From 675f7a378aa60cfbcf9aecc675db7bb721e8a265 Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Thu, 16 Dec 2021 23:57:29 +0000 Subject: [PATCH 01/10] Revert "Doc: Generate RPC and commands docs" This reverts commit 3a10722ad6fa4bd886a881b9abad740486d610e6. --- docs/Makefile | 13 ++----------- docs/doc_gen/dune | 1 - docs/doc_gen/rpc_doc.ml | 4 ---- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index f4b3af4d510d..ddb6a168a40f 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -10,13 +10,11 @@ DOCERRORDIR = $(DOCGENDIR)/errors DOCRPCDIR = $(DOCGENDIR)/rpcs ALPHA_LONG = ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK -ITHACA_LONG = PsithacaTTq3oumpKDw1pVvRrAtqiK4hKnP3Q4FNrXN9yc6KPhp HANGZHOU_LONG = PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx ACTIVE_LONG = $(HANGZHOU_LONG) ALPHA_SHORT = alpha HANGZHOU_SHORT = 011-PtHangz2 -ITHACA_SHORT = 012-Psithaca ACTIVE_SHORT = $(HANGZHOU_SHORT) SCRIPTSDIR = scripts @@ -32,11 +30,6 @@ manuals: main @../tezos-client -protocol $(ALPHA_LONG) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > alpha/tezos-client.html @../tezos-baker-$(ALPHA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > alpha/tezos-baker.html @../tezos-accuser-$(ALPHA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > alpha/tezos-accuser.html - # 012 (Ithaca) protocol - @../tezos-client -protocol $(ITHACA_LONG) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 012/tezos-client.html - @../tezos-baker-$(ITHACA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 012/tezos-baker.html - @../tezos-endorser-$(ITHACA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 012/tezos-endorser.html - @../tezos-accuser-$(ITHACA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 012/tezos-accuser.html # 011 (Hangzhou) protocol @../tezos-client -protocol $(HANGZHOU_LONG) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 011/tezos-client.html @../tezos-baker-$(HANGZHOU_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 011/tezos-baker.html @@ -72,7 +65,6 @@ redirectcheck: # - on each other protocol including alpha, also checking label defs (option -l) xrefscheck: $(CHECKXREFS) 011 - $(CHECKXREFS) -l 012 $(CHECKXREFS) -l alpha scriptsindoccheck: @@ -102,7 +94,6 @@ $(DOCGENDIR)/rpc_doc.exe: rpc: $(DOCGENDIR)/rpc_doc.exe @dune exec $(DOCGENDIR)/rpc_doc.exe index "" > active/rpc.rst - @dune exec $(DOCGENDIR)/rpc_doc.exe index "012" > 012/rpc.rst @dune exec $(DOCGENDIR)/rpc_doc.exe index alpha > alpha/rpc.rst @dune exec $(DOCGENDIR)/rpc_doc.exe index shell > shell/rpc.rst @dune exec $(DOCGENDIR)/rpc_doc.exe acl > user/default-acl.json @@ -167,5 +158,5 @@ lint: pylint pycodestyle lint_black clean: @-rm -Rf "$(BUILDDIR)" - @-rm -Rf api/errors.rst active/rpc.rst 011/rpc.rst 012/rpc.rst alpha/rpc.rst shell/rpc.rst shell/p2p_api.rst CHANGES.rst - @-rm -Rf api/tezos-*.html api/tezos-*.txt active/tezos-*.html 011/tezos-*.html 012/tezos-*.html alpha/tezos-*.html + @-rm -Rf api/errors.rst active/rpc.rst 011/rpc.rst alpha/rpc.rst shell/rpc.rst shell/p2p_api.rst CHANGES.rst + @-rm -Rf api/tezos-*.html api/tezos-*.txt active/tezos-*.html 011/tezos-*.html alpha/tezos-*.html diff --git a/docs/doc_gen/dune b/docs/doc_gen/dune index e94c340e943d..2ccda203a55f 100644 --- a/docs/doc_gen/dune +++ b/docs/doc_gen/dune @@ -8,7 +8,6 @@ tezos-protocol-updater ; TODO tezos/tezos#2170: adapt next line(s) tezos-embedded-protocol-011-PtHangz2 - tezos-embedded-protocol-012-Psithaca tezos-embedded-protocol-alpha data-encoding re) diff --git a/docs/doc_gen/rpc_doc.ml b/docs/doc_gen/rpc_doc.ml index 5a9b818b29d5..6fa6c13aa5f8 100644 --- a/docs/doc_gen/rpc_doc.ml +++ b/docs/doc_gen/rpc_doc.ml @@ -37,10 +37,6 @@ let protocols = "011 Hangzhou", Some "/include/rpc_introduction.rst.inc", "PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx" ); - ( "012", - "012 Ithaca", - Some "/include/rpc_introduction.rst.inc", - "PsithacaTTq3oumpKDw1pVvRrAtqiK4hKnP3Q4FNrXN9yc6KPhp" ); ] let pp_name ppf = function -- GitLab From b53c21597b809b833a8a107a2286c69be305c74f Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Thu, 16 Dec 2021 23:57:29 +0000 Subject: [PATCH 02/10] Revert "Doc: rename Alpha to Ithaca" This reverts commit 6380b9ff61ffc5c7f430ce69b3f9515a6d227edc. --- docs/protocols/012_ithaca.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/protocols/012_ithaca.rst b/docs/protocols/012_ithaca.rst index 2238246f8081..b247774caf9d 100644 --- a/docs/protocols/012_ithaca.rst +++ b/docs/protocols/012_ithaca.rst @@ -1,13 +1,13 @@ -Protocol Ithaca -=============== +Protocol Alpha +============== -This page contains all the relevant information for protocol Ithaca +This page contains all the relevant information for protocol Alpha (see :ref:`naming_convention`). The code can be found in the :src:`src/proto_012_Psithaca` directory of the ``master`` branch of Tezos. -This page documents the changes brought by protocol Ithaca with respect +This page documents the changes brought by protocol Alpha with respect to Hangzhou. .. contents:: -- GitLab From 6cc3394b2de458d0e3bc7c250dfb21b5a065da6b Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Thu, 16 Dec 2021 23:57:29 +0000 Subject: [PATCH 03/10] Revert "Test: test stitching from H for now" This reverts commit a07cbcc4da6c2d7c49d683891625c03fc91d067e. --- tests_python/tests_alpha/protocol.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests_python/tests_alpha/protocol.py b/tests_python/tests_alpha/protocol.py index 06e52dccd1cc..34166afbfda8 100644 --- a/tests_python/tests_alpha/protocol.py +++ b/tests_python/tests_alpha/protocol.py @@ -14,9 +14,9 @@ TENDERBAKE_PARAMETERS['consensus_committee_size'] = 67 FOLDER = constants.ALPHA_FOLDER -PREV_HASH = constants.HANGZHOU -PREV_DAEMON = constants.HANGZHOU_DAEMON -PREV_PARAMETERS = constants.HANGZHOU_PARAMETERS +PREV_HASH = constants.ITHACA +PREV_DAEMON = constants.ITHACA_DAEMON +PREV_PARAMETERS = constants.ITHACA_PARAMETERS def activate( -- GitLab From 785cf5739768ac2947659f2af092cd042d45191c Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Thu, 16 Dec 2021 23:57:29 +0000 Subject: [PATCH 04/10] Revert "Build: link Ithaca" This reverts commit 6ad5e43ab15207531c81807739eabfec729602b6. --- .gitlab/ci/unittest.yml | 14 +------------- active_protocol_versions | 1 - src/bin_client/dune | 12 ------------ src/bin_client/tezos-client.opam | 3 --- src/bin_codec/dune | 4 ---- src/bin_codec/tezos-codec.opam | 1 - src/bin_node/dune | 8 -------- src/bin_node/tezos-node.opam | 2 -- src/bin_proxy_server/dune | 8 -------- src/bin_proxy_server/tezos-proxy-server.opam | 2 -- 10 files changed, 1 insertion(+), 54 deletions(-) diff --git a/.gitlab/ci/unittest.yml b/.gitlab/ci/unittest.yml index e42a32e786ad..b32082ae4d84 100644 --- a/.gitlab/ci/unittest.yml +++ b/.gitlab/ci/unittest.yml @@ -75,19 +75,6 @@ unit:011_PtHangz2: src/proto_011_PtHangz2/lib_client.test_proto src/proto_011_PtHangz2/lib_protocol.test_proto -unit:012_Psithaca: - extends: - - .unit_test_template_x86_64 - - .template__coverage_files - variables: - MAKE_TARGETS: > - src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference.test_proto - src/proto_012_Psithaca/lib_benchmark.test_proto - src/proto_012_Psithaca/lib_client.test_proto - src/proto_012_Psithaca/lib_plugin.test_proto - src/proto_012_Psithaca/lib_protocol.test_proto - src/proto_012_Psithaca/lib_delegate.test_proto - unit:alpha: extends: - .unit_test_template_x86_64 @@ -100,6 +87,7 @@ unit:alpha: src/proto_alpha/lib_plugin.test_proto src/proto_alpha/lib_protocol.test_proto src/proto_alpha/lib_delegate.test_proto + unit:non-proto-x86_64: extends: - .unit_test_template_x86_64 diff --git a/active_protocol_versions b/active_protocol_versions index b0029662e1a8..ec3fe7cdd955 100644 --- a/active_protocol_versions +++ b/active_protocol_versions @@ -1,4 +1,3 @@ 010-PtGRANAD 011-PtHangz2 -012-Psithaca alpha diff --git a/src/bin_client/dune b/src/bin_client/dune index 2c1833da7e0d..d7541c171d4b 100644 --- a/src/bin_client/dune +++ b/src/bin_client/dune @@ -68,9 +68,6 @@ (select void_for_linking-tezos-client-011-PtHangz2-commands-registration from (tezos-client-011-PtHangz2-commands-registration -> void_for_linking-tezos-client-011-PtHangz2-commands-registration.empty) (-> void_for_linking-tezos-client-011-PtHangz2-commands-registration.empty)) - (select void_for_linking-tezos-client-012-Psithaca-commands-registration from - (tezos-client-012-Psithaca-commands-registration -> void_for_linking-tezos-client-012-Psithaca-commands-registration.empty) - (-> void_for_linking-tezos-client-012-Psithaca-commands-registration.empty)) (select void_for_linking-tezos-client-alpha-commands-registration from (tezos-client-alpha-commands-registration -> void_for_linking-tezos-client-alpha-commands-registration.empty) (-> void_for_linking-tezos-client-alpha-commands-registration.empty)) @@ -85,9 +82,6 @@ (select void_for_linking-tezos-baking-011-PtHangz2-commands-registration from (tezos-baking-011-PtHangz2-commands.registration -> void_for_linking-tezos-baking-011-PtHangz2-commands-registration.empty) (-> void_for_linking-tezos-baking-011-PtHangz2-commands-registration.empty)) - (select void_for_linking-tezos-baking-012-Psithaca-commands-registration from - (tezos-baking-012-Psithaca-commands.registration -> void_for_linking-tezos-baking-012-Psithaca-commands-registration.empty) - (-> void_for_linking-tezos-baking-012-Psithaca-commands-registration.empty)) (select void_for_linking-tezos-baking-alpha-commands-registration from (tezos-baking-alpha-commands.registration -> void_for_linking-tezos-baking-alpha-commands-registration.empty) (-> void_for_linking-tezos-baking-alpha-commands-registration.empty)) @@ -106,9 +100,6 @@ (select void_for_linking-tezos-protocol-plugin-011-PtHangz2 from (tezos-protocol-plugin-011-PtHangz2 -> void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty) (-> void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty)) - (select void_for_linking-tezos-protocol-plugin-012-Psithaca from - (tezos-protocol-plugin-012-Psithaca -> void_for_linking-tezos-protocol-plugin-012-Psithaca.empty) - (-> void_for_linking-tezos-protocol-plugin-012-Psithaca.empty)) (select void_for_linking-tezos-protocol-plugin-alpha from (tezos-protocol-plugin-alpha -> void_for_linking-tezos-protocol-plugin-alpha.empty) (-> void_for_linking-tezos-protocol-plugin-alpha.empty))) @@ -142,18 +133,15 @@ (write-file void_for_linking-tezos-client-009-PsFLoren-commands-registration.empty "") (write-file void_for_linking-tezos-client-010-PtGRANAD-commands-registration.empty "") (write-file void_for_linking-tezos-client-011-PtHangz2-commands-registration.empty "") - (write-file void_for_linking-tezos-client-012-Psithaca-commands-registration.empty "") (write-file void_for_linking-tezos-client-alpha-commands-registration.empty "") (write-file void_for_linking-tezos-baking-010-PtGRANAD-commands-registration.empty "") (write-file void_for_linking-tezos-baking-011-PtHangz2-commands-registration.empty "") - (write-file void_for_linking-tezos-baking-012-Psithaca-commands-registration.empty "") (write-file void_for_linking-tezos-baking-alpha-commands-registration.empty "") (write-file void_for_linking-tezos-protocol-plugin-007-PsDELPH1.empty "") (write-file void_for_linking-tezos-protocol-plugin-008-PtEdo2Zk.empty "") (write-file void_for_linking-tezos-protocol-plugin-009-PsFLoren.empty "") (write-file void_for_linking-tezos-protocol-plugin-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty "") - (write-file void_for_linking-tezos-protocol-plugin-012-Psithaca.empty "") (write-file void_for_linking-tezos-protocol-plugin-alpha.empty "")))) (install diff --git a/src/bin_client/tezos-client.opam b/src/bin_client/tezos-client.opam index bb26a8116d0d..8e71ec5f0a82 100644 --- a/src/bin_client/tezos-client.opam +++ b/src/bin_client/tezos-client.opam @@ -34,18 +34,15 @@ depopts: [ "tezos-client-009-PsFLoren-commands-registration" "tezos-client-010-PtGRANAD-commands-registration" "tezos-client-011-PtHangz2-commands-registration" - "tezos-client-012-Psithaca-commands-registration" "tezos-client-alpha-commands-registration" "tezos-baking-010-PtGRANAD-commands" "tezos-baking-011-PtHangz2-commands" - "tezos-baking-012-Psithaca-commands" "tezos-baking-alpha-commands" "tezos-protocol-plugin-007-PsDELPH1" "tezos-protocol-plugin-008-PtEdo2Zk" "tezos-protocol-plugin-009-PsFLoren" "tezos-protocol-plugin-010-PtGRANAD" "tezos-protocol-plugin-011-PtHangz2" - "tezos-protocol-plugin-012-Psithaca" "tezos-protocol-plugin-alpha" ] build: [ diff --git a/src/bin_codec/dune b/src/bin_codec/dune index c47ae2f7c129..aee18a1a369a 100644 --- a/src/bin_codec/dune +++ b/src/bin_codec/dune @@ -37,9 +37,6 @@ (select void_for_linking-tezos-client-011-PtHangz2 from (tezos-client-011-PtHangz2 -> void_for_linking-tezos-client-011-PtHangz2.empty) (-> void_for_linking-tezos-client-011-PtHangz2.empty)) - (select void_for_linking-tezos-client-012-Psithaca from - (tezos-client-012-Psithaca -> void_for_linking-tezos-client-012-Psithaca.empty) - (-> void_for_linking-tezos-client-012-Psithaca.empty)) (select void_for_linking-tezos-client-alpha from (tezos-client-alpha -> void_for_linking-tezos-client-alpha.empty) (-> void_for_linking-tezos-client-alpha.empty))) @@ -64,5 +61,4 @@ (write-file void_for_linking-tezos-client-009-PsFLoren.empty "") (write-file void_for_linking-tezos-client-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-client-011-PtHangz2.empty "") - (write-file void_for_linking-tezos-client-012-Psithaca.empty "") (write-file void_for_linking-tezos-client-alpha.empty "")))) diff --git a/src/bin_codec/tezos-codec.opam b/src/bin_codec/tezos-codec.opam index 8d2ddc4467c0..e85861cd6a40 100644 --- a/src/bin_codec/tezos-codec.opam +++ b/src/bin_codec/tezos-codec.opam @@ -24,7 +24,6 @@ depopts: [ "tezos-client-009-PsFLoren" "tezos-client-010-PtGRANAD" "tezos-client-011-PtHangz2" - "tezos-client-012-Psithaca" "tezos-client-alpha" ] build: [ diff --git a/src/bin_node/dune b/src/bin_node/dune index 008b2bb37000..dbeca49a8e80 100644 --- a/src/bin_node/dune +++ b/src/bin_node/dune @@ -89,9 +89,6 @@ (select void_for_linking-tezos-embedded-protocol-011-PtHangz2 from (tezos-embedded-protocol-011-PtHangz2 -> void_for_linking-tezos-embedded-protocol-011-PtHangz2.empty) (-> void_for_linking-tezos-embedded-protocol-011-PtHangz2.empty)) - (select void_for_linking-tezos-embedded-protocol-012-Psithaca from - (tezos-embedded-protocol-012-Psithaca -> void_for_linking-tezos-embedded-protocol-012-Psithaca.empty) - (-> void_for_linking-tezos-embedded-protocol-012-Psithaca.empty)) (select void_for_linking-tezos-embedded-protocol-alpha from (tezos-embedded-protocol-alpha -> void_for_linking-tezos-embedded-protocol-alpha.empty) (-> void_for_linking-tezos-embedded-protocol-alpha.empty)) @@ -110,9 +107,6 @@ (select void_for_linking-tezos-protocol-plugin-011-PtHangz2-registerer from (tezos-protocol-plugin-011-PtHangz2-registerer -> void_for_linking-tezos-protocol-plugin-011-PtHangz2-registerer.empty) (-> void_for_linking-tezos-protocol-plugin-011-PtHangz2-registerer.empty)) - (select void_for_linking-tezos-protocol-plugin-012-Psithaca-registerer from - (tezos-protocol-plugin-012-Psithaca-registerer -> void_for_linking-tezos-protocol-plugin-012-Psithaca-registerer.empty) - (-> void_for_linking-tezos-protocol-plugin-012-Psithaca-registerer.empty)) (select void_for_linking-tezos-protocol-plugin-alpha-registerer from (tezos-protocol-plugin-alpha-registerer -> void_for_linking-tezos-protocol-plugin-alpha-registerer.empty) (-> void_for_linking-tezos-protocol-plugin-alpha-registerer.empty))) @@ -155,14 +149,12 @@ (write-file void_for_linking-tezos-embedded-protocol-009-PsFLoren.empty "") (write-file void_for_linking-tezos-embedded-protocol-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-embedded-protocol-011-PtHangz2.empty "") - (write-file void_for_linking-tezos-embedded-protocol-012-Psithaca.empty "") (write-file void_for_linking-tezos-embedded-protocol-alpha.empty "") (write-file void_for_linking-tezos-protocol-plugin-007-PsDELPH1-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-008-PtEdo2Zk-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-009-PsFLoren-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-010-PtGRANAD-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-011-PtHangz2-registerer.empty "") - (write-file void_for_linking-tezos-protocol-plugin-012-Psithaca-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-alpha-registerer.empty "")))) (install diff --git a/src/bin_node/tezos-node.opam b/src/bin_node/tezos-node.opam index f5aa38f471d9..31e2fb5b2b2b 100644 --- a/src/bin_node/tezos-node.opam +++ b/src/bin_node/tezos-node.opam @@ -44,14 +44,12 @@ depopts: [ "tezos-embedded-protocol-009-PsFLoren" "tezos-embedded-protocol-010-PtGRANAD" "tezos-embedded-protocol-011-PtHangz2" - "tezos-embedded-protocol-012-Psithaca" "tezos-embedded-protocol-alpha" "tezos-protocol-plugin-007-PsDELPH1-registerer" "tezos-protocol-plugin-008-PtEdo2Zk-registerer" "tezos-protocol-plugin-009-PsFLoren-registerer" "tezos-protocol-plugin-010-PtGRANAD-registerer" "tezos-protocol-plugin-011-PtHangz2-registerer" - "tezos-protocol-plugin-012-Psithaca-registerer" "tezos-protocol-plugin-alpha-registerer" ] build: [ diff --git a/src/bin_proxy_server/dune b/src/bin_proxy_server/dune index d244276d93f2..21479e2f9f19 100644 --- a/src/bin_proxy_server/dune +++ b/src/bin_proxy_server/dune @@ -66,9 +66,6 @@ (select void_for_linking-tezos-client-011-PtHangz2 from (tezos-client-011-PtHangz2 -> void_for_linking-tezos-client-011-PtHangz2.empty) (-> void_for_linking-tezos-client-011-PtHangz2.empty)) - (select void_for_linking-tezos-client-012-Psithaca from - (tezos-client-012-Psithaca -> void_for_linking-tezos-client-012-Psithaca.empty) - (-> void_for_linking-tezos-client-012-Psithaca.empty)) (select void_for_linking-tezos-client-alpha from (tezos-client-alpha -> void_for_linking-tezos-client-alpha.empty) (-> void_for_linking-tezos-client-alpha.empty)) @@ -87,9 +84,6 @@ (select void_for_linking-tezos-protocol-plugin-011-PtHangz2 from (tezos-protocol-plugin-011-PtHangz2 -> void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty) (-> void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty)) - (select void_for_linking-tezos-protocol-plugin-012-Psithaca from - (tezos-protocol-plugin-012-Psithaca -> void_for_linking-tezos-protocol-plugin-012-Psithaca.empty) - (-> void_for_linking-tezos-protocol-plugin-012-Psithaca.empty)) (select void_for_linking-tezos-protocol-plugin-alpha from (tezos-protocol-plugin-alpha -> void_for_linking-tezos-protocol-plugin-alpha.empty) (-> void_for_linking-tezos-protocol-plugin-alpha.empty))) @@ -118,12 +112,10 @@ (write-file void_for_linking-tezos-client-009-PsFLoren.empty "") (write-file void_for_linking-tezos-client-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-client-011-PtHangz2.empty "") - (write-file void_for_linking-tezos-client-012-Psithaca.empty "") (write-file void_for_linking-tezos-client-alpha.empty "") (write-file void_for_linking-tezos-protocol-plugin-007-PsDELPH1.empty "") (write-file void_for_linking-tezos-protocol-plugin-008-PtEdo2Zk.empty "") (write-file void_for_linking-tezos-protocol-plugin-009-PsFLoren.empty "") (write-file void_for_linking-tezos-protocol-plugin-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty "") - (write-file void_for_linking-tezos-protocol-plugin-012-Psithaca.empty "") (write-file void_for_linking-tezos-protocol-plugin-alpha.empty "")))) diff --git a/src/bin_proxy_server/tezos-proxy-server.opam b/src/bin_proxy_server/tezos-proxy-server.opam index c404c334fabb..e77f4ab09118 100644 --- a/src/bin_proxy_server/tezos-proxy-server.opam +++ b/src/bin_proxy_server/tezos-proxy-server.opam @@ -33,14 +33,12 @@ depopts: [ "tezos-client-009-PsFLoren" "tezos-client-010-PtGRANAD" "tezos-client-011-PtHangz2" - "tezos-client-012-Psithaca" "tezos-client-alpha" "tezos-protocol-plugin-007-PsDELPH1" "tezos-protocol-plugin-008-PtEdo2Zk" "tezos-protocol-plugin-009-PsFLoren" "tezos-protocol-plugin-010-PtGRANAD" "tezos-protocol-plugin-011-PtHangz2" - "tezos-protocol-plugin-012-Psithaca" "tezos-protocol-plugin-alpha" ] build: [ -- GitLab From 616803118568662b7adf1a9f2b046ba7fde2c940 Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Thu, 16 Dec 2021 23:57:29 +0000 Subject: [PATCH 05/10] Revert "Protocol: Ithaca" This reverts commit d70a4bb20346aa85da1925fe1b216b9641e819e6. --- docs/012/cli-commands.rst | 41 - docs/012/consensus.rst | 453 -- docs/012/global_constants.rst | 141 - docs/012/glossary.rst | 179 - docs/012/liquidity_baking.rst | 51 - docs/012/michelson.rst | 3821 ---------- docs/012/plugins.rst | 53 - docs/012/proof_of_stake.rst | 171 - docs/012/protocol.rst | 62 - docs/012/protocol_overview.rst | 112 - docs/012/sapling.rst | 496 -- docs/012/timelock.rst | 129 - docs/012/voting.rst | 331 - docs/index.rst | 10 - docs/protocols/012_ithaca.rst | 160 - .../final_protocol_versions | 3 +- .../bin_accuser/.ocamlformat | 17 - src/proto_012_Psithaca/bin_accuser/dune | 20 - .../bin_accuser/dune-project | 3 - .../bin_accuser/main_accuser_012_Psithaca.ml | 38 - .../tezos-accuser-012-Psithaca.opam | 20 - src/proto_012_Psithaca/bin_baker/.ocamlformat | 17 - src/proto_012_Psithaca/bin_baker/dune | 20 - src/proto_012_Psithaca/bin_baker/dune-project | 3 - .../bin_baker/main_baker_012_Psithaca.ml | 38 - .../bin_baker/tezos-baker-012-Psithaca.opam | 20 - .../lib_benchmark/.ocamlformat | 17 - .../lib_benchmark/README.md | 42 - .../lib_benchmark/autocomp.ml | 382 - src/proto_012_Psithaca/lib_benchmark/dune | 27 - .../lib_benchmark/dune-project | 3 - .../lib_benchmark/execution_context.ml | 84 - .../lib_benchmark/kernel.ml | 39 - .../lib_benchmark_type_inference/.ocamlformat | 17 - .../lib_benchmark_type_inference/dune | 17 - .../lib_benchmark_type_inference/dune-project | 3 - .../lib_benchmark_type_inference/inference.ml | 1150 --- .../inference.mli | 145 - .../lib_benchmark_type_inference/int_map.ml | 26 - .../mikhailsky.ml | 422 - .../mikhailsky.mli | 330 - .../mikhailsky_prim.ml | 570 -- .../lib_benchmark_type_inference/monads.ml | 83 - .../lib_benchmark_type_inference/stores.ml | 85 - .../test/.ocamlformat | 17 - .../lib_benchmark_type_inference/test/dune | 10 - .../test/test_inference.ml | 615 -- .../test/test_uf.ml | 63 - ...benchmark-type-inference-012-Psithaca.opam | 24 - .../lib_benchmark_type_inference/type.ml | 201 - .../lib_benchmark_type_inference/type.mli | 111 - .../lib_benchmark_type_inference/uf.ml | 99 - .../lib_benchmark/micheline_sampler.ml | 110 - .../lib_benchmark/micheline_sampler.mli | 70 - .../lib_benchmark/michelson_mcmc_samplers.ml | 337 - .../lib_benchmark/michelson_mcmc_samplers.mli | 115 - .../lib_benchmark/michelson_samplers.ml | 727 -- .../lib_benchmark/michelson_samplers.mli | 131 - .../lib_benchmark/michelson_samplers_base.ml | 127 - .../lib_benchmark/michelson_samplers_base.mli | 67 - .../lib_benchmark/mikhailsky_to_michelson.ml | 229 - src/proto_012_Psithaca/lib_benchmark/rules.ml | 975 --- .../lib_benchmark/sampling_helpers.ml | 41 - .../lib_benchmark/state_space.ml | 78 - .../lib_benchmark/test/.ocamlformat | 17 - .../lib_benchmark/test/dune | 41 - .../lib_benchmark/test/test_autocompletion.ml | 120 - .../lib_benchmark/test/test_distribution.ml | 182 - .../lib_benchmark/test/test_helpers.ml | 83 - .../lib_benchmark/test/test_sampling_code.ml | 98 - .../lib_benchmark/test/test_sampling_data.ml | 87 - .../tezos-benchmark-012-Psithaca.opam | 32 - .../lib_benchmark/type_helpers.ml | 88 - .../lib_benchmark/type_helpers.mli | 58 - .../lib_benchmarks_proto/.ocamlformat | 17 - .../lib_benchmarks_proto/cache_benchmarks.ml | 195 - .../lib_benchmarks_proto/dune | 31 - .../lib_benchmarks_proto/dune-project | 3 - .../encodings_benchmarks.ml | 432 -- .../lib_benchmarks_proto/gas_helpers.ml | 36 - .../global_constants_storage_benchmarks.ml | 727 -- .../interpreter_benchmarks.ml | 3139 -------- .../lib_benchmarks_proto/interpreter_model.ml | 538 -- .../interpreter_workload.ml | 1562 ---- .../michelson_commands.ml | 202 - .../michelson_generation.ml | 113 - .../michelson_generation.mli | 61 - .../lib_benchmarks_proto/michelson_types.ml | 138 - .../registration_helpers.ml | 37 - .../sapling_benchmarks.ml | 152 - .../lib_benchmarks_proto/sapling_commands.ml | 134 - .../sapling_generation.ml | 560 -- .../script_repr_benchmarks.ml | 143 - .../script_typed_ir_size_benchmarks.ml | 338 - .../lib_benchmarks_proto/size.ml | 206 - .../lib_benchmarks_proto/tags.ml | 32 - .../tezos-benchmarks-proto-012-Psithaca.opam | 28 - .../translator_benchmarks.ml | 854 --- .../lib_benchmarks_proto/translator_model.ml | 68 - .../translator_workload.ml | 186 - .../lib_client/.ocamlformat | 17 - .../lib_client/annotated_manager_operation.ml | 123 - .../annotated_manager_operation.mli | 98 - .../lib_client/client_proto_args.ml | 573 -- .../lib_client/client_proto_args.mli | 141 - .../lib_client/client_proto_context.ml | 747 -- .../lib_client/client_proto_context.mli | 386 - .../lib_client/client_proto_contracts.ml | 156 - .../lib_client/client_proto_contracts.mli | 74 - .../lib_client/client_proto_fa12.ml | 975 --- .../lib_client/client_proto_fa12.mli | 161 - .../lib_client/client_proto_multisig.ml | 1210 --- .../lib_client/client_proto_multisig.mli | 150 - .../lib_client/client_proto_programs.ml | 344 - .../lib_client/client_proto_programs.mli | 204 - .../lib_client/client_proto_utils.ml | 55 - .../lib_client/client_proto_utils.mli | 40 - src/proto_012_Psithaca/lib_client/dune | 24 - .../lib_client/dune-project | 3 - .../lib_client/injection.ml | 1071 --- .../lib_client/injection.mli | 105 - src/proto_012_Psithaca/lib_client/light.ml | 37 - src/proto_012_Psithaca/lib_client/limit.ml | 64 - src/proto_012_Psithaca/lib_client/limit.mli | 49 - .../lib_client/managed_contract.ml | 321 - .../lib_client/managed_contract.mli | 125 - .../lib_client/michelson_v1_emacs.ml | 234 - .../lib_client/michelson_v1_emacs.mli | 39 - .../lib_client/michelson_v1_entrypoints.ml | 216 - .../lib_client/michelson_v1_entrypoints.mli | 108 - .../lib_client/michelson_v1_error_reporter.ml | 767 -- .../michelson_v1_error_reporter.mli | 32 - .../lib_client/michelson_v1_helpers.ml | 60 - .../lib_client/michelson_v1_macros.ml | 1519 ---- .../lib_client/michelson_v1_macros.mli | 86 - .../lib_client/michelson_v1_parser.ml | 103 - .../lib_client/michelson_v1_parser.mli | 55 - .../lib_client/michelson_v1_printer.ml | 241 - .../lib_client/michelson_v1_printer.mli | 65 - src/proto_012_Psithaca/lib_client/mockup.ml | 1158 --- .../lib_client/operation_result.ml | 666 -- .../lib_client/operation_result.mli | 35 - .../lib_client/protocol_client_context.ml | 272 - src/proto_012_Psithaca/lib_client/proxy.ml | 184 - .../lib_client/test/.ocamlformat | 17 - .../lib_client/test/assert.ml | 37 - src/proto_012_Psithaca/lib_client/test/dune | 17 - .../test/test_client_proto_context.ml | 71 - .../test/test_client_proto_contracts.ml | 94 - .../test/test_michelson_v1_macros.ml | 1345 ---- .../lib_client/test/test_proxy.ml | 89 - .../lib_client/tezos-client-012-Psithaca.opam | 31 - .../lib_client_commands/.ocamlformat | 17 - .../alpha_commands_registration.ml | 38 - .../client_proto_context_commands.ml | 1958 ----- .../client_proto_contracts_commands.ml | 87 - .../client_proto_fa12_commands.ml | 764 -- .../client_proto_mockup_commands.ml | 81 - .../client_proto_mockup_commands.mli | 26 - .../client_proto_multisig_commands.ml | 1136 --- .../client_proto_multisig_commands.mli | 26 - .../client_proto_programs_commands.ml | 966 --- .../client_proto_programs_commands.mli | 26 - .../client_proto_stresstest_commands.ml | 1004 --- .../client_proto_utils_commands.ml | 162 - .../client_proto_utils_commands.mli | 26 - .../lib_client_commands/dune | 57 - .../lib_client_commands/dune-project | 3 - ...nt-012-Psithaca-commands-registration.opam | 24 - .../tezos-client-012-Psithaca-commands.opam | 22 - .../lib_client_sapling/.ocamlformat | 17 - .../client_sapling_commands.ml | 796 -- .../client_sapling_commands.mli | 23 - .../lib_client_sapling/context.ml | 553 -- .../lib_client_sapling/context.mli | 157 - .../lib_client_sapling/dune | 19 - .../lib_client_sapling/dune-project | 3 - .../tezos-client-sapling-012-Psithaca.opam | 24 - .../lib_client_sapling/wallet.ml | 126 - .../lib_client_sapling/wallet.mli | 75 - .../lib_delegate/.ocamlformat | 17 - .../lib_delegate/abstract_context_index.ml | 35 - .../lib_delegate/abstract_context_index.mli | 31 - .../lib_delegate/baking_actions.ml | 531 -- .../lib_delegate/baking_actions.mli | 125 - .../lib_delegate/baking_cache.ml | 85 - .../lib_delegate/baking_commands.ml | 374 - .../lib_delegate/baking_commands.mli | 30 - .../baking_commands_registration.ml | 29 - .../lib_delegate/baking_configuration.ml | 310 - .../lib_delegate/baking_configuration.mli | 118 - .../lib_delegate/baking_errors.ml | 65 - .../lib_delegate/baking_events.ml | 789 -- .../lib_delegate/baking_files.ml | 37 - .../lib_delegate/baking_files.mli | 33 - .../lib_delegate/baking_highwatermarks.ml | 230 - .../lib_delegate/baking_highwatermarks.mli | 91 - .../lib_delegate/baking_lib.ml | 487 -- .../lib_delegate/baking_lib.mli | 65 - .../lib_delegate/baking_nonces.ml | 321 - .../lib_delegate/baking_nonces.mli | 114 - .../lib_delegate/baking_pow.ml | 85 - .../lib_delegate/baking_pow.mli | 40 - .../lib_delegate/baking_scheduling.ml | 787 -- .../lib_delegate/baking_scheduling.mli | 83 - .../lib_delegate/baking_simulator.ml | 120 - .../lib_delegate/baking_simulator.mli | 61 - .../lib_delegate/baking_state.ml | 847 -- .../lib_delegate/baking_state.mli | 226 - .../lib_delegate/block_forge.ml | 360 - .../lib_delegate/block_forge.mli | 63 - .../lib_delegate/client_baking_blocks.ml | 188 - .../lib_delegate/client_baking_blocks.mli | 68 - .../client_baking_denunciation.ml | 489 -- .../client_baking_denunciation.mli | 31 - .../lib_delegate/client_baking_scheduling.ml | 33 - .../lib_delegate/client_baking_scheduling.mli | 54 - .../lib_delegate/client_daemon.ml | 147 - .../lib_delegate/client_daemon.mli | 53 - .../lib_delegate/context_ops.ml | 108 - .../lib_delegate/delegate_events.ml | 788 -- src/proto_012_Psithaca/lib_delegate/dune | 89 - .../lib_delegate/dune-project | 3 - .../liquidity_baking_vote_file.ml | 162 - .../lib_delegate/logging.ml | 167 - .../lib_delegate/logging.mli | 83 - .../lib_delegate/node_rpc.ml | 200 - .../lib_delegate/node_rpc.mli | 76 - .../lib_delegate/operation_pool.ml | 327 - .../lib_delegate/operation_pool.mli | 123 - .../lib_delegate/operation_selection.ml | 316 - .../lib_delegate/operation_selection.mli | 48 - .../lib_delegate/operation_worker.ml | 658 -- .../lib_delegate/operation_worker.mli | 94 - .../lib_delegate/state_transitions.ml | 703 -- .../lib_delegate/state_transitions.mli | 90 - .../lib_delegate/test/.ocamlformat | 17 - .../lib_delegate/test/README.md | 116 - src/proto_012_Psithaca/lib_delegate/test/dune | 25 - .../lib_delegate/test/main.ml | 10 - .../test/mockup_simulator/.ocamlformat | 17 - .../mockup_simulator/broadcast_services.ml | 85 - .../lib_delegate/test/mockup_simulator/dune | 24 - .../mockup_simulator/faked_client_context.ml | 163 - .../test/mockup_simulator/faked_daemon.ml | 29 - .../test/mockup_simulator/faked_services.ml | 295 - .../test/mockup_simulator/mockup_simulator.ml | 1285 ---- .../mockup_simulator/mockup_simulator.mli | 244 - .../lib_delegate/test/test_scenario.ml | 1317 ---- .../tezos-accuser-012-Psithaca-commands.opam | 23 - .../tezos-baking-012-Psithaca-commands.opam | 24 - .../tezos-baking-012-Psithaca.opam | 33 - .../tezos-endorser-012-Psithaca-commands.opam | 23 - .../lib_parameters/.ocamlformat | 17 - .../lib_parameters/default_parameters.ml | 224 - .../lib_parameters/default_parameters.mli | 48 - src/proto_012_Psithaca/lib_parameters/dune | 47 - .../lib_parameters/dune-project | 3 - src/proto_012_Psithaca/lib_parameters/gen.ml | 62 - ...ezos-protocol-012-Psithaca-parameters.opam | 18 - .../lib_plugin/.ocamlformat | 17 - src/proto_012_Psithaca/lib_plugin/dune | 27 - .../lib_plugin/dune-project | 3 - src/proto_012_Psithaca/lib_plugin/plugin.ml | 3277 -------- .../lib_plugin/plugin_registerer.ml | 31 - .../lib_plugin/test/.ocamlformat | 17 - src/proto_012_Psithaca/lib_plugin/test/dune | 16 - .../lib_plugin/test/test_consensus_filter.ml | 499 -- ...otocol-plugin-012-Psithaca-registerer.opam | 18 - .../tezos-protocol-plugin-012-Psithaca.opam | 22 - .../lib_protocol/.ocamlformat | 17 - .../lib_protocol/TEZOS_PROTOCOL | 129 - .../lib_protocol/alpha_context.ml | 436 -- .../lib_protocol/alpha_context.mli | 2436 ------ .../lib_protocol/alpha_services.ml | 194 - .../lib_protocol/alpha_services.mli | 81 - .../lib_protocol/amendment.ml | 266 - .../lib_protocol/amendment.mli | 81 - src/proto_012_Psithaca/lib_protocol/apply.ml | 2658 ------- src/proto_012_Psithaca/lib_protocol/apply.mli | 282 - .../lib_protocol/apply_results.ml | 1478 ---- .../lib_protocol/apply_results.mli | 250 - src/proto_012_Psithaca/lib_protocol/baking.ml | 130 - .../lib_protocol/baking.mli | 60 - .../lib_protocol/blinded_public_key_hash.ml | 59 - .../lib_protocol/blinded_public_key_hash.mli | 45 - .../lib_protocol/block_header_repr.ml | 502 -- .../lib_protocol/block_header_repr.mli | 159 - .../lib_protocol/block_payload_hash.ml | 42 - .../lib_protocol/block_payload_hash.mli | 28 - .../lib_protocol/block_payload_repr.ml | 41 - .../lib_protocol/block_payload_repr.mli | 41 - .../lib_protocol/bootstrap_storage.ml | 120 - .../lib_protocol/bootstrap_storage.mli | 38 - .../lib_protocol/cache_memory_helpers.ml | 168 - .../lib_protocol/cache_repr.ml | 249 - .../lib_protocol/cache_repr.mli | 233 - .../lib_protocol/commitment_repr.ml | 36 - .../lib_protocol/commitment_repr.mli | 31 - .../lib_protocol/commitment_storage.ml | 44 - .../lib_protocol/commitment_storage.mli | 45 - .../lib_protocol/constants_repr.ml | 644 -- .../lib_protocol/constants_repr.mli | 197 - .../lib_protocol/constants_services.ml | 59 - .../lib_protocol/constants_services.mli | 34 - .../lib_protocol/constants_storage.ml | 150 - .../lib_protocol/constants_storage.mli | 91 - .../lib_protocol/contract_delegate_storage.ml | 83 - .../contract_delegate_storage.mli | 88 - .../lib_protocol/contract_hash.ml | 45 - .../lib_protocol/contract_hash.mli | 29 - .../lib_protocol/contract_manager_storage.ml | 130 - .../lib_protocol/contract_manager_storage.mli | 67 - .../lib_protocol/contract_repr.ml | 214 - .../lib_protocol/contract_repr.mli | 99 - .../lib_protocol/contract_services.ml | 527 -- .../lib_protocol/contract_services.mli | 126 - .../lib_protocol/contract_storage.ml | 629 -- .../lib_protocol/contract_storage.mli | 184 - .../lib_protocol/contracts/cpmm.bin | 1 - .../lib_protocol/contracts/cpmm.mligo | 388 - .../lib_protocol/contracts/cpmm.tz | 929 --- .../lib_protocol/contracts/lqt.bin | 1 - .../lib_protocol/contracts/lqt.mligo | 164 - .../lib_protocol/contracts/lqt.tz | 327 - .../lib_protocol/coq-of-ocaml/README.md | 11 - .../lib_protocol/coq-of-ocaml/config.json | 255 - .../lib_protocol/cycle_repr.ml | 85 - .../lib_protocol/cycle_repr.mli | 61 - .../delegate_activation_storage.ml | 87 - .../delegate_activation_storage.mli | 39 - .../lib_protocol/delegate_services.ml | 418 - .../lib_protocol/delegate_services.mli | 122 - .../lib_protocol/delegate_storage.ml | 908 --- .../lib_protocol/delegate_storage.mli | 242 - src/proto_012_Psithaca/lib_protocol/dune | 1 - .../lib_protocol/dune-project | 3 - src/proto_012_Psithaca/lib_protocol/dune.inc | 708 -- .../lib_protocol/fees_storage.ml | 111 - .../lib_protocol/fees_storage.mli | 77 - .../lib_protocol/fitness_repr.ml | 289 - .../lib_protocol/fitness_repr.mli | 96 - .../lib_protocol/fixed_point_repr.ml | 94 - .../lib_protocol/fixed_point_repr.mli | 105 - .../lib_protocol/frozen_deposits_storage.ml | 61 - .../lib_protocol/frozen_deposits_storage.mli | 52 - .../lib_protocol/gas_limit_repr.ml | 210 - .../lib_protocol/gas_limit_repr.mli | 110 - .../lib_protocol/gas_monad.ml | 53 - .../lib_protocol/gas_monad.mli | 71 - .../lib_protocol/global_constants_costs.ml | 47 - .../lib_protocol/global_constants_costs.mli | 34 - .../lib_protocol/global_constants_storage.ml | 270 - .../lib_protocol/global_constants_storage.mli | 150 - .../lib_protocol/init_storage.ml | 312 - .../lib_protocol/init_storage.mli | 55 - .../lib_protocol/lazy_storage_diff.ml | 439 -- .../lib_protocol/lazy_storage_diff.mli | 71 - .../lib_protocol/lazy_storage_kind.ml | 325 - .../lib_protocol/lazy_storage_kind.mli | 178 - .../lib_protocol/level_repr.ml | 336 - .../lib_protocol/level_repr.mli | 115 - .../lib_protocol/level_storage.ml | 122 - .../lib_protocol/level_storage.mli | 71 - .../lib_protocol/liquidity_baking_cpmm.ml | 13 - .../lib_protocol/liquidity_baking_lqt.ml | 13 - .../liquidity_baking_migration.ml | 242 - .../liquidity_baking_migration.mli | 33 - .../lib_protocol/liquidity_baking_repr.ml | 71 - .../lib_protocol/liquidity_baking_repr.mli | 36 - .../lib_protocol/local_gas_counter.ml | 99 - src/proto_012_Psithaca/lib_protocol/main.ml | 822 -- src/proto_012_Psithaca/lib_protocol/main.mli | 139 - .../lib_protocol/manager_repr.ml | 52 - .../lib_protocol/manager_repr.mli | 38 - .../lib_protocol/michelson_v1_gas.ml | 1809 ----- .../lib_protocol/michelson_v1_gas.mli | 506 -- .../lib_protocol/michelson_v1_primitives.ml | 799 -- .../lib_protocol/michelson_v1_primitives.mli | 230 - .../lib_protocol/migration_repr.ml | 62 - .../lib_protocol/migration_repr.mli | 39 - src/proto_012_Psithaca/lib_protocol/misc.ml | 92 - src/proto_012_Psithaca/lib_protocol/misc.mli | 51 - .../lib_protocol/non_empty_string.ml | 42 - .../lib_protocol/non_empty_string.mli | 45 - .../lib_protocol/nonce_hash.ml | 45 - .../lib_protocol/nonce_hash.mli | 31 - .../lib_protocol/nonce_storage.ml | 132 - .../lib_protocol/nonce_storage.mli | 60 - .../lib_protocol/operation_repr.ml | 1149 --- .../lib_protocol/operation_repr.mli | 377 - .../lib_protocol/parameters_repr.ml | 132 - .../lib_protocol/parameters_repr.mli | 57 - .../lib_protocol/path_encoding.ml | 54 - .../lib_protocol/path_encoding.mli | 48 - .../lib_protocol/period_repr.ml | 164 - .../lib_protocol/period_repr.mli | 73 - .../lib_protocol/raw_context.ml | 1295 ---- .../lib_protocol/raw_context.mli | 320 - .../lib_protocol/raw_context_intf.ml | 260 - .../lib_protocol/raw_level_repr.ml | 108 - .../lib_protocol/raw_level_repr.mli | 64 - .../lib_protocol/receipt_repr.ml | 410 - .../lib_protocol/receipt_repr.mli | 80 - .../lib_protocol/roll_repr_legacy.ml | 60 - .../lib_protocol/roll_repr_legacy.mli | 44 - .../lib_protocol/roll_storage_legacy.ml | 359 - .../lib_protocol/roll_storage_legacy.mli | 173 - .../lib_protocol/round_repr.ml | 429 -- .../lib_protocol/round_repr.mli | 245 - .../lib_protocol/sampler.ml | 209 - .../lib_protocol/sampler.mli | 98 - .../lib_protocol/sapling_repr.ml | 200 - .../lib_protocol/sapling_services.ml | 103 - .../lib_protocol/sapling_storage.ml | 489 -- .../lib_protocol/sapling_validator.ml | 108 - .../lib_protocol/saturation_repr.ml | 170 - .../lib_protocol/saturation_repr.mli | 204 - .../lib_protocol/script_cache.ml | 109 - .../lib_protocol/script_cache.mli | 81 - .../lib_protocol/script_comparable.ml | 89 - .../lib_protocol/script_comparable.mli | 29 - .../lib_protocol/script_expr_hash.ml | 44 - .../lib_protocol/script_expr_hash.mli | 31 - .../lib_protocol/script_int_repr.ml | 113 - .../lib_protocol/script_int_repr.mli | 161 - .../lib_protocol/script_interpreter.ml | 1798 ----- .../lib_protocol/script_interpreter.mli | 168 - .../lib_protocol/script_interpreter_defs.ml | 855 --- .../lib_protocol/script_ir_annot.ml | 528 -- .../lib_protocol/script_ir_annot.mli | 230 - .../lib_protocol/script_ir_translator.ml | 6787 ----------------- .../lib_protocol/script_ir_translator.mli | 502 -- .../lib_protocol/script_list.ml | 32 - .../lib_protocol/script_list.mli | 31 - .../lib_protocol/script_map.ml | 97 - .../lib_protocol/script_map.mli | 49 - .../lib_protocol/script_repr.ml | 353 - .../lib_protocol/script_repr.mli | 130 - .../lib_protocol/script_set.ml | 75 - .../lib_protocol/script_set.mli | 37 - .../lib_protocol/script_string_repr.ml | 77 - .../lib_protocol/script_string_repr.mli | 46 - .../lib_protocol/script_tc_errors.ml | 201 - .../script_tc_errors_registration.ml | 805 -- .../script_tc_errors_registration.mli | 34 - .../lib_protocol/script_timestamp_repr.ml | 55 - .../lib_protocol/script_timestamp_repr.mli | 68 - .../lib_protocol/script_typed_ir.ml | 2201 ------ .../lib_protocol/script_typed_ir.mli | 1594 ---- .../lib_protocol/script_typed_ir_size.ml | 769 -- .../lib_protocol/script_typed_ir_size.mli | 71 - .../script_typed_ir_size_costs.ml | 34 - .../script_typed_ir_size_costs.mli | 28 - .../lib_protocol/seed_repr.ml | 150 - .../lib_protocol/seed_repr.mli | 111 - .../lib_protocol/seed_storage.ml | 127 - .../lib_protocol/seed_storage.mli | 47 - .../lib_protocol/services_registration.ml | 122 - .../lib_protocol/services_registration.mli | 127 - .../lib_protocol/slot_repr.ml | 138 - .../lib_protocol/slot_repr.mli | 63 - .../lib_protocol/stake_storage.ml | 325 - .../lib_protocol/stake_storage.mli | 126 - .../lib_protocol/state_hash.ml | 44 - .../lib_protocol/state_hash.mli | 30 - .../lib_protocol/storage.ml | 1616 ---- .../lib_protocol/storage.mli | 693 -- .../lib_protocol/storage_costs.ml | 43 - .../lib_protocol/storage_costs.mli | 30 - .../lib_protocol/storage_description.ml | 388 - .../lib_protocol/storage_description.mli | 93 - .../lib_protocol/storage_functors.ml | 1123 --- .../lib_protocol/storage_functors.mli | 122 - .../lib_protocol/storage_sigs.ml | 418 - .../lib_protocol/test/.ocamlformat | 17 - .../test/contracts/big_interpreter_stack.tz | 5 - .../test/contracts/sapling_contract.tz | 69 - .../test/contracts/sapling_contract_double.tz | 33 - .../test/contracts/sapling_contract_drop.tz | 14 - .../test/contracts/sapling_contract_send.tz | 20 - .../sapling_contract_state_as_arg.tz | 18 - .../contracts/sapling_push_sapling_state.tz | 11 - .../contracts/sapling_use_existing_state.tz | 12 - .../test/contracts/temp_big_maps.tz | 81 - .../lib_protocol/test/contracts/timelock.tz | 31 - src/proto_012_Psithaca/lib_protocol/test/dune | 80 - .../lib_protocol/test/helpers/.ocamlformat | 17 - .../lib_protocol/test/helpers/README.md | 3 - .../lib_protocol/test/helpers/account.ml | 115 - .../lib_protocol/test/helpers/account.mli | 68 - .../lib_protocol/test/helpers/assert.ml | 178 - .../lib_protocol/test/helpers/block.ml | 759 -- .../lib_protocol/test/helpers/block.mli | 258 - .../test/helpers/consensus_helpers.ml | 108 - .../lib_protocol/test/helpers/context.ml | 368 - .../lib_protocol/test/helpers/context.mli | 188 - .../test/helpers/contract_helpers.ml | 101 - .../lib_protocol/test/helpers/cpmm_logic.ml | 102 - .../lib_protocol/test/helpers/cpmm_repr.ml | 384 - .../lib_protocol/test/helpers/dune | 24 - .../lib_protocol/test/helpers/dune-project | 3 - .../test/helpers/error_monad_operators.ml | 11 - .../lib_protocol/test/helpers/expr.ml | 50 - .../lib_protocol/test/helpers/expr_common.ml | 82 - .../lib_protocol/test/helpers/incremental.ml | 224 - .../lib_protocol/test/helpers/incremental.mli | 62 - .../helpers/liquidity_baking_generator.ml | 351 - .../helpers/liquidity_baking_generator.mli | 77 - .../test/helpers/liquidity_baking_machine.ml | 1364 ---- .../test/helpers/liquidity_baking_machine.mli | 387 - .../test/helpers/lqt_fa12_repr.ml | 252 - .../lib_protocol/test/helpers/nonce.ml | 35 - .../lib_protocol/test/helpers/nonce.mli | 33 - .../lib_protocol/test/helpers/op.ml | 476 -- .../lib_protocol/test/helpers/op.mli | 175 - .../lib_protocol/test/helpers/rewards.ml | 1641 ---- .../test/helpers/sapling_helpers.ml | 397 - .../test/helpers/script_big_map.ml | 30 - .../test/helpers/script_big_map.mli | 44 - .../lib_protocol/test/helpers/script_list.ml | 29 - .../lib_protocol/test/helpers/script_list.mli | 28 - .../lib_protocol/test/helpers/script_map.ml | 36 - .../lib_protocol/test/helpers/script_map.mli | 31 - .../lib_protocol/test/helpers/script_set.ml | 31 - .../lib_protocol/test/helpers/script_set.mli | 32 - .../test/helpers/test_global_constants.ml | 327 - .../lib_protocol/test/helpers/test_tez.ml | 70 - .../lib_protocol/test/helpers/testable.ml | 38 - .../tezos-012-Psithaca-test-helpers.opam | 25 - .../lib_protocol/test/liquidity_baking_pbt.ml | 299 - .../lib_protocol/test/main.ml | 82 - .../lib_protocol/test/saturation_fuzzing.ml | 183 - .../lib_protocol/test/test_activation.ml | 587 -- .../lib_protocol/test/test_baking.ml | 455 -- .../test/test_combined_operations.ml | 335 - .../lib_protocol/test/test_constants.ml | 87 - .../lib_protocol/test/test_deactivation.ml | 351 - .../lib_protocol/test/test_delegation.ml | 1580 ---- .../lib_protocol/test/test_double_baking.ml | 365 - .../test/test_double_endorsement.ml | 513 -- .../test/test_double_preendorsement.ml | 337 - .../lib_protocol/test/test_endorsement.ml | 594 -- .../lib_protocol/test/test_failing_noop.ml | 62 - .../lib_protocol/test/test_fitness.ml | 157 - .../lib_protocol/test/test_fixed_point.ml | 174 - .../lib_protocol/test/test_frozen_deposits.ml | 631 -- .../lib_protocol/test/test_gas_costs.ml | 289 - .../lib_protocol/test/test_gas_levels.ml | 481 -- .../lib_protocol/test/test_gas_properties.ml | 139 - .../test/test_global_constants_storage.ml | 138 - .../lib_protocol/test/test_helpers_rpcs.ml | 69 - .../lib_protocol/test/test_interpretation.ml | 304 - .../test/test_lazy_storage_diff.ml | 141 - .../lib_protocol/test/test_level_module.ml | 275 - .../test/test_liquidity_baking.ml | 562 -- .../lib_protocol/test/test_origination.ml | 240 - .../lib_protocol/test/test_participation.ml | 208 - .../lib_protocol/test/test_preendorsement.ml | 228 - .../test/test_preendorsement_functor.ml | 266 - .../lib_protocol/test/test_qty.ml | 159 - .../lib_protocol/test/test_receipt.ml | 93 - .../lib_protocol/test/test_reveal.ml | 109 - .../lib_protocol/test/test_round_repr.ml | 541 -- .../lib_protocol/test/test_sampler.ml | 270 - .../lib_protocol/test/test_sapling.ml | 1126 --- .../lib_protocol/test/test_saturation.ml | 218 - .../test/test_script_comparison.ml | 369 - .../test/test_script_typed_ir_size.ml | 400 - .../lib_protocol/test/test_seed.ml | 252 - .../lib_protocol/test/test_storage.ml | 224 - .../lib_protocol/test/test_temp_big_maps.ml | 100 - .../lib_protocol/test/test_tez_repr.ml | 140 - .../test/test_ticket_balance_key.ml | 497 -- .../lib_protocol/test/test_ticket_scanner.ml | 593 -- .../lib_protocol/test/test_ticket_storage.ml | 288 - .../lib_protocol/test/test_time_repr.ml | 44 - .../lib_protocol/test/test_timelock.ml | 168 - .../lib_protocol/test/test_token.ml | 732 -- .../lib_protocol/test/test_transfer.ml | 801 -- .../lib_protocol/test/test_typechecking.ml | 915 --- .../lib_protocol/test/test_voting.ml | 1167 --- .../lib_protocol/test/unit/.ocamlformat | 17 - .../lib_protocol/test/unit/dune | 20 - .../lib_protocol/test/unit/main.ml | 60 - .../test/unit/test_alpha_context.ml | 129 - .../test/unit/test_contract_repr.ml | 161 - .../unit/test_global_constants_storage.ml | 413 - .../test/unit/test_operation_repr.ml | 112 - .../test/unit/test_raw_level_repr.ml | 176 - .../lib_protocol/test/unit/test_tez_repr.ml | 202 - .../lib_protocol/tez_repr.ml | 245 - .../lib_protocol/tez_repr.mli | 75 - .../tezos-embedded-protocol-012-Psithaca.opam | 25 - .../tezos-protocol-012-Psithaca-tests.opam | 36 - .../tezos-protocol-012-Psithaca.opam | 23 - .../tezos-protocol-functor-012-Psithaca.opam | 24 - .../lib_protocol/ticket_balance_key.ml | 70 - .../lib_protocol/ticket_balance_key.mli | 40 - .../lib_protocol/ticket_costs.ml | 52 - .../lib_protocol/ticket_costs.mli | 53 - .../lib_protocol/ticket_scanner.ml | 515 -- .../lib_protocol/ticket_scanner.mli | 55 - .../lib_protocol/ticket_storage.ml | 119 - .../lib_protocol/ticket_storage.mli | 71 - .../lib_protocol/time_repr.ml | 73 - .../lib_protocol/time_repr.mli | 55 - src/proto_012_Psithaca/lib_protocol/token.ml | 266 - src/proto_012_Psithaca/lib_protocol/token.mli | 134 - .../lib_protocol/vote_repr.ml | 42 - .../lib_protocol/vote_repr.mli | 33 - .../lib_protocol/vote_storage.ml | 169 - .../lib_protocol/vote_storage.mli | 116 - .../lib_protocol/voting_period_repr.ml | 175 - .../lib_protocol/voting_period_repr.mli | 82 - .../lib_protocol/voting_period_storage.ml | 191 - .../lib_protocol/voting_period_storage.mli | 51 - .../lib_protocol/voting_services.ml | 152 - .../lib_protocol/voting_services.mli | 60 - src/proto_012_Psithaca/parameters/dune | 4 - tests_python/contracts_012/attic/accounts.tz | 54 - tests_python/contracts_012/attic/add1.tz | 7 - tests_python/contracts_012/attic/add1_list.tz | 6 - .../contracts_012/attic/after_strategy.tz | 3 - tests_python/contracts_012/attic/always.tz | 4 - tests_python/contracts_012/attic/append.tz | 8 - tests_python/contracts_012/attic/at_least.tz | 6 - tests_python/contracts_012/attic/auction.tz | 8 - .../contracts_012/attic/bad_lockup.tz | 6 - .../contracts_012/attic/big_map_union.tz | 8 - .../contracts_012/attic/cadr_annotation.tz | 3 - tests_python/contracts_012/attic/concat.tz | 7 - .../contracts_012/attic/conditionals.tz | 9 - .../contracts_012/attic/cons_twice.tz | 9 - tests_python/contracts_012/attic/cps_fact.tz | 16 - .../contracts_012/attic/create_add1_lists.tz | 14 - .../contracts_012/attic/data_publisher.tz | 8 - tests_python/contracts_012/attic/dispatch.tz | 9 - tests_python/contracts_012/attic/empty.tz | 3 - .../contracts_012/attic/fail_amount.tz | 6 - tests_python/contracts_012/attic/faucet.tz | 7 - tests_python/contracts_012/attic/forward.tz | 150 - tests_python/contracts_012/attic/id.tz | 3 - .../contracts_012/attic/infinite_loop.tz | 3 - .../contracts_012/attic/insertion_sort.tz | 16 - .../contracts_012/attic/int_publisher.tz | 17 - .../contracts_012/attic/king_of_tez.tz | 19 - .../attic/list_of_transactions.tz | 8 - tests_python/contracts_012/attic/queue.tz | 24 - .../contracts_012/attic/reduce_map.tz | 16 - .../contracts_012/attic/reentrancy.tz | 7 - tests_python/contracts_012/attic/reservoir.tz | 25 - .../attic/scrutable_reservoir.tz | 67 - .../contracts_012/attic/spawn_identities.tz | 20 - .../entrypoints/big_map_entrypoints.tz | 31 - .../entrypoints/delegatable_target.tz | 79 - .../contracts_012/entrypoints/manager.tz | 31 - .../entrypoints/no_default_target.tz | 11 - .../entrypoints/no_entrypoint_target.tz | 11 - .../entrypoints/rooted_target.tz | 11 - .../entrypoints/simple_entrypoints.tz | 4 - .../contracts_012/ill_typed/badly_indented.tz | 3 - .../contracts_012/ill_typed/big_dip.tz | 4 - .../contracts_012/ill_typed/big_drop.tz | 4 - .../contracts_012/ill_typed/big_map_arity.tz | 5 - .../contracts_012/ill_typed/chain_id_arity.tz | 3 - tests_python/contracts_012/ill_typed/comb0.tz | 3 - tests_python/contracts_012/ill_typed/comb1.tz | 3 - .../ill_typed/contract_annotation_default.tz | 11 - .../contracts_012/ill_typed/dip_failwith.tz | 4 - tests_python/contracts_012/ill_typed/dup0.tz | 3 - .../ill_typed/failwith_big_map.tz | 22 - .../ill_typed/invalid_self_entrypoint.tz | 10 - .../contracts_012/ill_typed/map_failwith.tz | 4 - .../ill_typed/missing_only_code_field.tz | 2 - .../ill_typed/missing_only_parameter_field.tz | 4 - .../ill_typed/missing_only_storage_field.tz | 4 - .../missing_parameter_and_storage_fields.tz | 3 - .../ill_typed/multiple_code_field.tz | 6 - .../ill_typed/multiple_parameter_field.tz | 6 - .../multiple_storage_and_code_fields.tz | 7 - .../ill_typed/multiple_storage_field.tz | 6 - .../contracts_012/ill_typed/never_literal.tz | 6 - .../contracts_012/ill_typed/pack_big_map.tz | 7 - .../contracts_012/ill_typed/pack_operation.tz | 20 - .../ill_typed/pack_sapling_state.tz | 13 - .../push_big_map_with_id_with_parens.tz | 10 - .../push_big_map_with_id_without_parens.tz | 11 - ...ng_build_empty_state_with_int_parameter.tz | 10 - .../ill_typed/set_update_non_comparable.tz | 9 - .../ill_typed/stack_bottom_undig2able.tz | 5 - .../ill_typed/stack_bottom_undigable.tz | 6 - .../ill_typed/stack_bottom_undip2able.tz | 6 - .../ill_typed/stack_bottom_undipable.tz | 5 - .../ill_typed/stack_bottom_undropable.tz | 5 - .../ill_typed/stack_bottom_undug2able.tz | 5 - .../ill_typed/stack_bottom_undugable.tz | 6 - .../ill_typed/stack_bottom_undup2able.tz | 5 - .../ill_typed/stack_bottom_unfailwithable.tz | 6 - .../ill_typed/stack_bottom_ungetable.tz | 6 - .../ill_typed/stack_bottom_unleftable.tz | 6 - .../ill_typed/stack_bottom_unpairable.tz | 6 - .../ill_typed/stack_bottom_unpopable.tz | 10 - .../stack_bottom_unpopable_in_lambda.tz | 10 - .../ill_typed/stack_bottom_unrightable.tz | 6 - .../contracts_012/ill_typed/ticket_apply.tz | 17 - .../contracts_012/ill_typed/ticket_dup.tz | 3 - .../ill_typed/ticket_in_ticket.tz | 16 - .../contracts_012/ill_typed/ticket_unpack.tz | 5 - .../contracts_012/ill_typed/uncomb0.tz | 3 - .../contracts_012/ill_typed/uncomb1.tz | 3 - .../ill_typed/unpack_sapling_state.tz | 12 - .../unpair_field_annotation_mismatch.tz | 10 - .../view_op_bad_name_invalid_char_set.tz | 3 - .../view_op_bad_name_invalid_type.tz | 3 - .../view_op_bad_name_non_printable_char.tz | 3 - .../ill_typed/view_op_bad_name_too_long.tz | 4 - .../ill_typed/view_op_bad_return_type.tz | 3 - .../ill_typed/view_op_dupable_type.tz | 3 - .../ill_typed/view_op_invalid_arity.tz | 3 - .../ill_typed/view_op_lazy_storage.tz | 8 - .../ill_typed/view_op_lazy_storage_type.tz | 8 - .../ill_typed/view_toplevel_bad_input_type.tz | 4 - ...view_toplevel_bad_name_invalid_char_set.tz | 5 - .../view_toplevel_bad_name_invalid_type.tz | 4 - ...ew_toplevel_bad_name_non_printable_char.tz | 4 - .../view_toplevel_bad_name_too_long.tz | 4 - .../view_toplevel_bad_return_type.tz | 4 - .../ill_typed/view_toplevel_bad_type.tz | 7 - .../view_toplevel_dupable_type_input.tz | 5 - .../view_toplevel_dupable_type_output.tz | 4 - .../view_toplevel_duplicated_name.tz | 5 - .../ill_typed/view_toplevel_invalid_arity.tz | 4 - .../view_toplevel_lazy_storage_input.tz | 4 - .../view_toplevel_lazy_storage_output.tz | 4 - .../contracts_012/legacy/create_account.tz | 29 - .../contracts_012/legacy/create_contract.tz | 18 - .../legacy/create_contract_flags.tz | 26 - .../legacy/create_contract_rootname.tz | 18 - .../contracts_012/legacy/originator.tz | 16 - .../contracts_012/legacy/steps_to_quota.tz | 12 - tests_python/contracts_012/macros/assert.tz | 3 - .../contracts_012/macros/assert_cmpeq.tz | 3 - .../contracts_012/macros/assert_cmpge.tz | 3 - .../contracts_012/macros/assert_cmpgt.tz | 3 - .../contracts_012/macros/assert_cmple.tz | 3 - .../contracts_012/macros/assert_cmplt.tz | 3 - .../contracts_012/macros/assert_cmpneq.tz | 3 - .../contracts_012/macros/assert_eq.tz | 3 - .../contracts_012/macros/assert_ge.tz | 3 - .../contracts_012/macros/assert_gt.tz | 3 - .../contracts_012/macros/assert_le.tz | 3 - .../contracts_012/macros/assert_lt.tz | 3 - .../contracts_012/macros/assert_neq.tz | 3 - .../contracts_012/macros/big_map_get_add.tz | 7 - .../contracts_012/macros/big_map_mem.tz | 5 - .../contracts_012/macros/build_list.tz | 6 - .../contracts_012/macros/carn_and_cdrn.tz | 26 - tests_python/contracts_012/macros/compare.tz | 9 - .../contracts_012/macros/compare_bytes.tz | 9 - tests_python/contracts_012/macros/fail.tz | 5 - .../contracts_012/macros/guestbook.tz | 10 - .../contracts_012/macros/macro_annotations.tz | 6 - .../contracts_012/macros/map_caddaadr.tz | 4 - .../contracts_012/macros/max_in_list.tz | 9 - tests_python/contracts_012/macros/min.tz | 11 - .../contracts_012/macros/pair_macro.tz | 6 - .../contracts_012/macros/set_caddaadr.tz | 5 - .../contracts_012/macros/take_my_money.tz | 9 - .../contracts_012/macros/unpair_macro.tz | 9 - .../mini_scenarios/authentication.tz | 30 - .../mini_scenarios/big_map_entrypoints.tz | 31 - .../mini_scenarios/big_map_magic.tz | 41 - .../mini_scenarios/big_map_read.tz | 9 - .../mini_scenarios/big_map_store.tz | 8 - .../mini_scenarios/big_map_write.tz | 10 - .../mini_scenarios/create_contract.tz | 33 - .../mini_scenarios/create_contract_simple.tz | 14 - .../mini_scenarios/default_account.tz | 9 - .../execution_order_appender.tz | 17 - .../mini_scenarios/execution_order_caller.tz | 17 - .../mini_scenarios/execution_order_storer.tz | 4 - .../mini_scenarios/fa12_reference.tz | 749 -- .../mini_scenarios/generic_multisig.tz | 92 - .../contracts_012/mini_scenarios/groth16.tz | 74 - .../contracts_012/mini_scenarios/hardlimit.tz | 5 - .../mini_scenarios/legacy_multisig.tz | 78 - .../contracts_012/mini_scenarios/lockup.tz | 19 - .../mini_scenarios/lqt_fa12.mligo.tz | 328 - .../mini_scenarios/multiple_en2.tz | 77 - .../multiple_entrypoints_counter.tz | 29 - .../mini_scenarios/parameterized_multisig.tz | 24 - .../contracts_012/mini_scenarios/replay.tz | 8 - .../mini_scenarios/reveal_signed_preimage.tz | 13 - .../mini_scenarios/self_address_receiver.tz | 12 - .../mini_scenarios/self_address_sender.tz | 17 - .../mini_scenarios/ticket_builder_fungible.tz | 40 - .../ticket_builder_non_fungible.tz | 47 - .../mini_scenarios/ticket_wallet_fungible.tz | 88 - .../ticket_wallet_non_fungible.tz | 61 - .../mini_scenarios/tzip4_view.tz | 7 - .../mini_scenarios/vote_for_delegate.tz | 30 - .../mini_scenarios/weather_insurance.tz | 19 - .../contracts_012/mini_scenarios/xcat.tz | 48 - .../contracts_012/mini_scenarios/xcat_dapp.tz | 79 - .../contracts_012/non_regression/bug_262.tz | 5 - .../non_regression/pairk_annot.tz | 7 - tests_python/contracts_012/opcodes/abs.tz | 5 - tests_python/contracts_012/opcodes/add.tz | 25 - .../contracts_012/opcodes/add_bls12_381_fr.tz | 3 - .../contracts_012/opcodes/add_bls12_381_g1.tz | 3 - .../contracts_012/opcodes/add_bls12_381_g2.tz | 3 - .../opcodes/add_delta_timestamp.tz | 3 - .../opcodes/add_timestamp_delta.tz | 3 - tests_python/contracts_012/opcodes/address.tz | 3 - .../opcodes/amount_after_fib_view.tz | 24 - .../opcodes/amount_after_nonexistent_view.tz | 23 - .../opcodes/amount_after_view.tz | 26 - tests_python/contracts_012/opcodes/and.tz | 3 - .../contracts_012/opcodes/and_binary.tz | 27 - .../contracts_012/opcodes/and_logical_1.tz | 3 - tests_python/contracts_012/opcodes/balance.tz | 3 - .../opcodes/balance_after_fib_view.tz | 25 - .../opcodes/balance_after_nonexistent_view.tz | 22 - .../opcodes/balance_after_view.tz | 25 - .../contracts_012/opcodes/big_map_mem_nat.tz | 7 - .../opcodes/big_map_mem_string.tz | 7 - .../contracts_012/opcodes/big_map_to_self.tz | 22 - .../bls12_381_fr_push_bytes_not_padded.tz | 9 - .../opcodes/bls12_381_fr_push_nat.tz | 9 - .../opcodes/bls12_381_fr_to_int.tz | 8 - .../opcodes/bls12_381_fr_to_mutez.tz | 12 - .../opcodes/bls12_381_fr_z_int.tz | 8 - .../opcodes/bls12_381_fr_z_nat.tz | 8 - .../opcodes/bls12_381_z_fr_int.tz | 9 - .../opcodes/bls12_381_z_fr_nat.tz | 9 - tests_python/contracts_012/opcodes/bytes.tz | 11 - tests_python/contracts_012/opcodes/car.tz | 3 - tests_python/contracts_012/opcodes/cdr.tz | 3 - .../contracts_012/opcodes/chain_id.tz | 3 - .../contracts_012/opcodes/chain_id_store.tz | 3 - .../contracts_012/opcodes/check_signature.tz | 10 - .../contracts_012/opcodes/comb-get.tz | 27 - .../contracts_012/opcodes/comb-literals.tz | 9 - .../contracts_012/opcodes/comb-set-2.tz | 10 - .../contracts_012/opcodes/comb-set.tz | 10 - tests_python/contracts_012/opcodes/comb.tz | 9 - tests_python/contracts_012/opcodes/compare.tz | 52 - .../contracts_012/opcodes/compare_big_type.tz | 20 - .../opcodes/compare_big_type2.tz | 22 - .../contracts_012/opcodes/comparisons.tz | 15 - .../contracts_012/opcodes/concat_hello.tz | 4 - .../opcodes/concat_hello_bytes.tz | 4 - .../contracts_012/opcodes/concat_list.tz | 5 - tests_python/contracts_012/opcodes/cons.tz | 3 - .../contracts_012/opcodes/contains_all.tz | 7 - .../contracts_012/opcodes/contract.tz | 11 - .../contracts_012/opcodes/create_contract.tz | 14 - .../opcodes/create_contract_rootname.tz | 15 - .../opcodes/create_contract_rootname_alt.tz | 14 - .../opcodes/create_contract_with_view.tz | 17 - .../contracts_012/opcodes/diff_timestamps.tz | 3 - tests_python/contracts_012/opcodes/dig_eq.tz | 14 - tests_python/contracts_012/opcodes/dign.tz | 3 - tests_python/contracts_012/opcodes/dip.tz | 8 - tests_python/contracts_012/opcodes/dipn.tz | 3 - tests_python/contracts_012/opcodes/dropn.tz | 3 - tests_python/contracts_012/opcodes/dugn.tz | 3 - tests_python/contracts_012/opcodes/dup-n.tz | 18 - tests_python/contracts_012/opcodes/ediv.tz | 13 - .../contracts_012/opcodes/ediv_mutez.tz | 12 - .../contracts_012/opcodes/empty_map.tz | 6 - .../contracts_012/opcodes/exec_concat.tz | 7 - tests_python/contracts_012/opcodes/first.tz | 3 - .../opcodes/get_and_update_big_map.tz | 9 - .../opcodes/get_and_update_map.tz | 9 - .../opcodes/get_big_map_value.tz | 6 - .../contracts_012/opcodes/get_map_value.tz | 3 - .../opcodes/hash_consistency_checker.tz | 3 - .../contracts_012/opcodes/hash_key.tz | 3 - .../contracts_012/opcodes/hash_string.tz | 3 - tests_python/contracts_012/opcodes/if.tz | 3 - tests_python/contracts_012/opcodes/if_some.tz | 3 - tests_python/contracts_012/opcodes/int.tz | 5 - .../contracts_012/opcodes/iter_fail.tz | 4 - tests_python/contracts_012/opcodes/keccak.tz | 8 - .../contracts_012/opcodes/left_right.tz | 3 - tests_python/contracts_012/opcodes/level.tz | 3 - .../contracts_012/opcodes/list_concat.tz | 3 - .../opcodes/list_concat_bytes.tz | 3 - tests_python/contracts_012/opcodes/list_id.tz | 3 - .../contracts_012/opcodes/list_id_map.tz | 3 - .../contracts_012/opcodes/list_iter.tz | 5 - .../contracts_012/opcodes/list_map_block.tz | 5 - .../contracts_012/opcodes/list_size.tz | 3 - .../contracts_012/opcodes/loop_failwith.tz | 4 - .../contracts_012/opcodes/loop_left.tz | 7 - .../opcodes/loop_left_failwith.tz | 4 - tests_python/contracts_012/opcodes/map_car.tz | 5 - tests_python/contracts_012/opcodes/map_id.tz | 3 - .../contracts_012/opcodes/map_iter.tz | 7 - tests_python/contracts_012/opcodes/map_map.tz | 8 - .../opcodes/map_map_sideeffect.tz | 12 - .../contracts_012/opcodes/map_mem_nat.tz | 7 - .../contracts_012/opcodes/map_mem_string.tz | 7 - .../contracts_012/opcodes/map_size.tz | 3 - .../opcodes/merge_comparable_pairs.tz | 14 - tests_python/contracts_012/opcodes/mul.tz | 48 - .../contracts_012/opcodes/mul_bls12_381_fr.tz | 3 - .../contracts_012/opcodes/mul_bls12_381_g1.tz | 3 - .../contracts_012/opcodes/mul_bls12_381_g2.tz | 3 - .../contracts_012/opcodes/mul_overflow.tz | 18 - tests_python/contracts_012/opcodes/munch.tz | 14 - .../opcodes/mutez_to_bls12_381_fr.tz | 14 - tests_python/contracts_012/opcodes/neg.tz | 8 - .../contracts_012/opcodes/neg_bls12_381_fr.tz | 3 - .../contracts_012/opcodes/neg_bls12_381_g1.tz | 3 - .../contracts_012/opcodes/neg_bls12_381_g2.tz | 3 - tests_python/contracts_012/opcodes/none.tz | 3 - tests_python/contracts_012/opcodes/noop.tz | 3 - tests_python/contracts_012/opcodes/not.tz | 3 - .../contracts_012/opcodes/not_binary.tz | 12 - tests_python/contracts_012/opcodes/or.tz | 3 - .../contracts_012/opcodes/or_binary.tz | 9 - .../opcodes/originate_big_map.tz | 3 - .../contracts_012/opcodes/packunpack.tz | 6 - .../contracts_012/opcodes/packunpack_rev.tz | 43 - .../opcodes/packunpack_rev_cty.tz | 31 - tests_python/contracts_012/opcodes/pair_id.tz | 3 - .../contracts_012/opcodes/pairing_check.tz | 3 - tests_python/contracts_012/opcodes/pexec.tz | 6 - tests_python/contracts_012/opcodes/pexec_2.tz | 11 - tests_python/contracts_012/opcodes/proxy.tz | 13 - tests_python/contracts_012/opcodes/ret_int.tz | 3 - tests_python/contracts_012/opcodes/reverse.tz | 5 - .../contracts_012/opcodes/reverse_loop.tz | 5 - .../opcodes/sapling_empty_state.tz | 3 - tests_python/contracts_012/opcodes/self.tz | 3 - .../contracts_012/opcodes/self_address.tz | 11 - .../opcodes/self_address_after_fib_view.tz | 25 - .../self_address_after_nonexistent_view.tz | 26 - .../opcodes/self_address_after_view.tz | 24 - .../opcodes/self_after_fib_view.tz | 27 - .../opcodes/self_after_nonexistent_view.tz | 28 - .../contracts_012/opcodes/self_after_view.tz | 26 - .../opcodes/self_with_default_entrypoint.tz | 19 - .../opcodes/self_with_entrypoint.tz | 26 - tests_python/contracts_012/opcodes/sender.tz | 8 - .../opcodes/sender_after_fib_view.tz | 26 - .../opcodes/sender_after_nonexistent_view.tz | 25 - .../opcodes/sender_after_view.tz | 25 - tests_python/contracts_012/opcodes/set_car.tz | 3 - tests_python/contracts_012/opcodes/set_cdr.tz | 3 - .../contracts_012/opcodes/set_delegate.tz | 9 - tests_python/contracts_012/opcodes/set_id.tz | 3 - .../contracts_012/opcodes/set_iter.tz | 3 - .../contracts_012/opcodes/set_member.tz | 3 - .../contracts_012/opcodes/set_size.tz | 3 - tests_python/contracts_012/opcodes/sets.tz | 40 - tests_python/contracts_012/opcodes/sha3.tz | 8 - tests_python/contracts_012/opcodes/shifts.tz | 18 - tests_python/contracts_012/opcodes/slice.tz | 5 - .../contracts_012/opcodes/slice_bytes.tz | 5 - tests_python/contracts_012/opcodes/slices.tz | 11 - tests_python/contracts_012/opcodes/source.tz | 10 - .../contracts_012/opcodes/split_bytes.tz | 16 - .../contracts_012/opcodes/split_string.tz | 16 - .../opcodes/store_bls12_381_fr.tz | 3 - .../opcodes/store_bls12_381_g1.tz | 3 - .../opcodes/store_bls12_381_g2.tz | 3 - .../contracts_012/opcodes/store_input.tz | 3 - .../contracts_012/opcodes/store_now.tz | 3 - tests_python/contracts_012/opcodes/str_id.tz | 3 - .../opcodes/sub_timestamp_delta.tz | 3 - tests_python/contracts_012/opcodes/subset.tz | 12 - .../contracts_012/opcodes/tez_add_sub.tz | 5 - .../contracts_012/opcodes/ticket_bad.tz | 5 - .../contracts_012/opcodes/ticket_big_store.tz | 3 - .../contracts_012/opcodes/ticket_join.tz | 7 - .../contracts_012/opcodes/ticket_read.tz | 8 - .../contracts_012/opcodes/ticket_split.tz | 11 - .../contracts_012/opcodes/ticket_store-2.tz | 3 - .../contracts_012/opcodes/ticket_store.tz | 3 - .../contracts_012/opcodes/ticketer-2.tz | 9 - .../contracts_012/opcodes/ticketer.tz | 10 - .../contracts_012/opcodes/transfer_amount.tz | 3 - .../contracts_012/opcodes/transfer_tokens.tz | 5 - tests_python/contracts_012/opcodes/uncomb.tz | 8 - tests_python/contracts_012/opcodes/unpair.tz | 71 - .../contracts_012/opcodes/update_big_map.tz | 6 - .../contracts_012/opcodes/utxo_read.tz | 9 - tests_python/contracts_012/opcodes/utxor.tz | 24 - .../contracts_012/opcodes/view_fib.tz | 9 - .../opcodes/view_mutual_recursion.tz | 11 - .../contracts_012/opcodes/view_op_add.tz | 3 - .../contracts_012/opcodes/view_op_constant.tz | 3 - .../contracts_012/opcodes/view_op_id.tz | 4 - .../opcodes/view_op_nonexistent_addr.tz | 5 - .../opcodes/view_op_nonexistent_func.tz | 3 - .../opcodes/view_op_test_step_contants.tz | 8 - ...iew_op_toplevel_inconsistent_input_type.tz | 3 - ...ew_op_toplevel_inconsistent_output_type.tz | 3 - .../contracts_012/opcodes/view_rec.tz | 12 - .../opcodes/view_toplevel_lib.tz | 67 - .../contracts_012/opcodes/voting_power.tz | 7 - tests_python/contracts_012/opcodes/xor.tz | 13 - tests_python/tests_012/__init__.py | 0 ...contract.TestNormalize::test_normalize.out | 8 - ...tNormalize::test_normalize_legacy_flag.out | 8 - ...Normalize::test_normalize_script[None].out | 10 - ...lize::test_normalize_script[Optimized].out | 10 - ...est_normalize_script[Optimized_legacy].out | 12 - ...alize::test_normalize_script[Readable].out | 10 - ...e_type[list (pair nat int bool bytes)].out | 3 - ...rmalize_type[list (pair nat int bool)].out | 3 - ...st_normalize_type[list (pair nat int)].out | 3 - ...rmalize::test_normalize_type[list nat].out | 3 - ...estNormalize::test_normalize_type[nat].out | 3 - ...ormalize_type[pair nat int bool bytes].out | 3 - ...test_normalize_type[pair nat int bool].out | 3 - ...ize::test_normalize_type[pair nat int].out | 3 - ...e::test_normalize_unparsing_mode[None].out | 3 - ...st_normalize_unparsing_mode[Optimized].out | 3 - ...alize_unparsing_mode[Optimized_legacy].out | 5 - ...est_normalize_unparsing_mode[Readable].out | 3 - ..._hash[client_regtest_custom_scrubber0].out | 301 - ...st_contract_hash[opcodes--view_fac.tz].out | 3 - ...st_contract_hash[opcodes--view_fib.tz].out | 3 - ...ash[opcodes--view_mutual_recursion.tz].out | 3 - ...contract_hash[opcodes--view_op_add.tz].out | 3 - ..._contract_hash[opcodes--view_op_id.tz].out | 3 - ...[opcodes--view_op_nonexistent_addr.tz].out | 3 - ...[opcodes--view_op_nonexistent_func.tz].out | 3 - ...pcodes--view_op_test_step_contants.tz].out | 3 - ...p_toplevel_inconsistent_input_type.tz].out | 3 - ..._toplevel_inconsistent_output_type.tz].out | 3 - ...st_contract_hash[opcodes--view_rec.tz].out | 3 - ...ct_hash[opcodes--view_toplevel_lib.tz].out | 3 - ...::test_self_address_originate_receiver.out | 53 - ...er::test_self_address_originate_sender.out | 52 - ...ddressTransfer::test_send_self_address.out | 42 - ...ck::test_typecheck[attic--accounts.tz].out | 379 - ...echeck::test_typecheck[attic--add1.tz].out | 16 - ...k::test_typecheck[attic--add1_list.tz].out | 14 - ...st_typecheck[attic--after_strategy.tz].out | 27 - ...heck::test_typecheck[attic--always.tz].out | 18 - ...heck::test_typecheck[attic--append.tz].out | 22 - ...ck::test_typecheck[attic--at_least.tz].out | 18 - ...eck::test_typecheck[attic--auction.tz].out | 87 - ...::test_typecheck[attic--bad_lockup.tz].out | 71 - ...est_typecheck[attic--big_map_union.tz].out | 34 - ...t_typecheck[attic--cadr_annotation.tz].out | 17 - ...heck::test_typecheck[attic--concat.tz].out | 28 - ...test_typecheck[attic--conditionals.tz].out | 20 - ...::test_typecheck[attic--cons_twice.tz].out | 23 - ...ck::test_typecheck[attic--cps_fact.tz].out | 71 - ...typecheck[attic--create_add1_lists.tz].out | 30 - ...st_typecheck[attic--data_publisher.tz].out | 80 - ...ck::test_typecheck[attic--dispatch.tz].out | 54 - ...check::test_typecheck[attic--empty.tz].out | 12 - ...:test_typecheck[attic--fail_amount.tz].out | 20 - ...heck::test_typecheck[attic--faucet.tz].out | 35 - ...eck::test_typecheck[attic--forward.tz].out | 1920 ----- ...ypecheck::test_typecheck[attic--id.tz].out | 12 - ...est_typecheck[attic--infinite_loop.tz].out | 18 - ...st_typecheck[attic--insertion_sort.tz].out | 63 - ...est_typecheck[attic--int_publisher.tz].out | 105 - ...:test_typecheck[attic--king_of_tez.tz].out | 79 - ...echeck[attic--list_of_transactions.tz].out | 49 - ...check::test_typecheck[attic--queue.tz].out | 111 - ...::test_typecheck[attic--reduce_map.tz].out | 58 - ...::test_typecheck[attic--reentrancy.tz].out | 49 - ...k::test_typecheck[attic--reservoir.tz].out | 100 - ...pecheck[attic--scrutable_reservoir.tz].out | 273 - ..._typecheck[attic--spawn_identities.tz].out | 71 - ...eck::test_typecheck[macros--assert.tz].out | 15 - ...est_typecheck[macros--assert_cmpeq.tz].out | 21 - ...est_typecheck[macros--assert_cmpge.tz].out | 21 - ...est_typecheck[macros--assert_cmpgt.tz].out | 21 - ...est_typecheck[macros--assert_cmple.tz].out | 21 - ...est_typecheck[macros--assert_cmplt.tz].out | 21 - ...st_typecheck[macros--assert_cmpneq.tz].out | 21 - ...::test_typecheck[macros--assert_eq.tz].out | 23 - ...::test_typecheck[macros--assert_ge.tz].out | 23 - ...::test_typecheck[macros--assert_gt.tz].out | 23 - ...::test_typecheck[macros--assert_le.tz].out | 23 - ...::test_typecheck[macros--assert_lt.tz].out | 23 - ...:test_typecheck[macros--assert_neq.tz].out | 23 - ..._typecheck[macros--big_map_get_add.tz].out | 71 - ...test_typecheck[macros--big_map_mem.tz].out | 31 - ...:test_typecheck[macros--build_list.tz].out | 45 - ...st_typecheck[macros--carn_and_cdrn.tz].out | 47 - ...ck::test_typecheck[macros--compare.tz].out | 97 - ...st_typecheck[macros--compare_bytes.tz].out | 97 - ...check::test_typecheck[macros--fail.tz].out | 5 - ...::test_typecheck[macros--guestbook.tz].out | 36 - ...ypecheck[macros--macro_annotations.tz].out | 24 - ...est_typecheck[macros--map_caddaadr.tz].out | 18 - ...test_typecheck[macros--max_in_list.tz].out | 29 - ...echeck::test_typecheck[macros--min.tz].out | 23 - ...:test_typecheck[macros--pair_macro.tz].out | 26 - ...est_typecheck[macros--set_caddaadr.tz].out | 52 - ...st_typecheck[macros--take_my_money.tz].out | 26 - ...est_typecheck[macros--unpair_macro.tz].out | 32 - ...eck[mini_scenarios--authentication.tz].out | 47 - ...ini_scenarios--big_map_entrypoints.tz].out | 132 - ...heck[mini_scenarios--big_map_magic.tz].out | 106 - ...check[mini_scenarios--big_map_read.tz].out | 17 - ...heck[mini_scenarios--big_map_store.tz].out | 14 - ...heck[mini_scenarios--big_map_write.tz].out | 21 - ...ck[mini_scenarios--create_contract.tz].out | 75 - ..._scenarios--create_contract_simple.tz].out | 29 - ...ck[mini_scenarios--default_account.tz].out | 26 - ...cenarios--execution_order_appender.tz].out | 34 - ..._scenarios--execution_order_caller.tz].out | 25 - ..._scenarios--execution_order_storer.tz].out | 16 - ...eck[mini_scenarios--fa12_reference.tz].out | 2761 ------- ...k[mini_scenarios--generic_multisig.tz].out | 438 -- ..._typecheck[mini_scenarios--groth16.tz].out | 233 - ...ypecheck[mini_scenarios--hardlimit.tz].out | 18 - ...ck[mini_scenarios--legacy_multisig.tz].out | 501 -- ...t_typecheck[mini_scenarios--lockup.tz].out | 48 - ...eck[mini_scenarios--lqt_fa12.mligo.tz].out | 2834 ------- ...check[mini_scenarios--multiple_en2.tz].out | 205 - ...rios--multiple_entrypoints_counter.tz].out | 180 - ..._scenarios--parameterized_multisig.tz].out | 173 - ...t_typecheck[mini_scenarios--replay.tz].out | 33 - ..._scenarios--reveal_signed_preimage.tz].out | 70 - ...i_scenarios--self_address_receiver.tz].out | 19 - ...ini_scenarios--self_address_sender.tz].out | 24 - ...scenarios--ticket_builder_fungible.tz].out | 71 - ...arios--ticket_builder_non_fungible.tz].out | 73 - ..._scenarios--ticket_wallet_fungible.tz].out | 224 - ...narios--ticket_wallet_non_fungible.tz].out | 132 - ...pecheck[mini_scenarios--tzip4_view.tz].out | 56 - ...[mini_scenarios--vote_for_delegate.tz].out | 168 - ...[mini_scenarios--weather_insurance.tz].out | 259 - ...est_typecheck[mini_scenarios--xcat.tz].out | 93 - ...ypecheck[mini_scenarios--xcat_dapp.tz].out | 612 -- ..._typecheck[non_regression--bug_262.tz].out | 18 - ...echeck[non_regression--pairk_annot.tz].out | 32 - ...check::test_typecheck[opcodes--abs.tz].out | 23 - ...check::test_typecheck[opcodes--add.tz].out | 84 - ...ypecheck[opcodes--add_bls12_381_fr.tz].out | 18 - ...ypecheck[opcodes--add_bls12_381_g1.tz].out | 18 - ...ypecheck[opcodes--add_bls12_381_g2.tz].out | 18 - ...check[opcodes--add_delta_timestamp.tz].out | 22 - ...check[opcodes--add_timestamp_delta.tz].out | 22 - ...k::test_typecheck[opcodes--address.tz].out | 16 - ...eck[opcodes--amount_after_fib_view.tz].out | 38 - ...des--amount_after_nonexistent_view.tz].out | 37 - ...pecheck[opcodes--amount_after_view.tz].out | 39 - ...check::test_typecheck[opcodes--and.tz].out | 22 - ...test_typecheck[opcodes--and_binary.tz].out | 50 - ...t_typecheck[opcodes--and_logical_1.tz].out | 16 - ...k::test_typecheck[opcodes--balance.tz].out | 14 - ...ck[opcodes--balance_after_fib_view.tz].out | 38 - ...es--balance_after_nonexistent_view.tz].out | 37 - ...echeck[opcodes--balance_after_view.tz].out | 39 - ...typecheck[opcodes--big_map_mem_nat.tz].out | 22 - ...echeck[opcodes--big_map_mem_string.tz].out | 25 - ...typecheck[opcodes--big_map_to_self.tz].out | 59 - ...bls12_381_fr_push_bytes_not_padded.tz].out | 16 - ...eck[opcodes--bls12_381_fr_push_nat.tz].out | 16 - ...check[opcodes--bls12_381_fr_to_int.tz].out | 14 - ...eck[opcodes--bls12_381_fr_to_mutez.tz].out | 21 - ...echeck[opcodes--bls12_381_fr_z_int.tz].out | 14 - ...echeck[opcodes--bls12_381_fr_z_nat.tz].out | 14 - ...echeck[opcodes--bls12_381_z_fr_int.tz].out | 16 - ...echeck[opcodes--bls12_381_z_fr_nat.tz].out | 16 - ...eck::test_typecheck[opcodes--bytes.tz].out | 12 - ...check::test_typecheck[opcodes--car.tz].out | 14 - ...check::test_typecheck[opcodes--cdr.tz].out | 14 - ...::test_typecheck[opcodes--chain_id.tz].out | 16 - ..._typecheck[opcodes--chain_id_store.tz].out | 16 - ...typecheck[opcodes--check_signature.tz].out | 42 - ...::test_typecheck[opcodes--comb-get.tz].out | 51 - ...t_typecheck[opcodes--comb-literals.tz].out | 17 - ...test_typecheck[opcodes--comb-set-2.tz].out | 26 - ...::test_typecheck[opcodes--comb-set.tz].out | 28 - ...heck::test_typecheck[opcodes--comb.tz].out | 18 - ...k::test_typecheck[opcodes--compare.tz].out | 217 - ...ypecheck[opcodes--compare_big_type.tz].out | 3737 --------- ...pecheck[opcodes--compare_big_type2.tz].out | 4302 ----------- ...est_typecheck[opcodes--comparisons.tz].out | 65 - ...st_typecheck[opcodes--concat_hello.tz].out | 17 - ...echeck[opcodes--concat_hello_bytes.tz].out | 14 - ...est_typecheck[opcodes--concat_list.tz].out | 30 - ...heck::test_typecheck[opcodes--cons.tz].out | 14 - ...st_typecheck[opcodes--contains_all.tz].out | 79 - ...::test_typecheck[opcodes--contract.tz].out | 19 - ...typecheck[opcodes--create_contract.tz].out | 27 - ...[opcodes--create_contract_rootname.tz].out | 29 - ...odes--create_contract_rootname_alt.tz].out | 29 - ...opcodes--create_contract_with_view.tz].out | 30 - ...typecheck[opcodes--diff_timestamps.tz].out | 20 - ...ck::test_typecheck[opcodes--dig_eq.tz].out | 157 - ...heck::test_typecheck[opcodes--dign.tz].out | 24 - ...check::test_typecheck[opcodes--dip.tz].out | 20 - ...heck::test_typecheck[opcodes--dipn.tz].out | 32 - ...eck::test_typecheck[opcodes--dropn.tz].out | 22 - ...heck::test_typecheck[opcodes--dugn.tz].out | 30 - ...eck::test_typecheck[opcodes--dup-n.tz].out | 51 - ...heck::test_typecheck[opcodes--ediv.tz].out | 70 - ...test_typecheck[opcodes--ediv_mutez.tz].out | 30 - ...:test_typecheck[opcodes--empty_map.tz].out | 22 - ...est_typecheck[opcodes--exec_concat.tz].out | 34 - ...eck::test_typecheck[opcodes--first.tz].out | 13 - ...ck[opcodes--get_and_update_big_map.tz].out | 15 - ...echeck[opcodes--get_and_update_map.tz].out | 15 - ...pecheck[opcodes--get_big_map_value.tz].out | 24 - ...t_typecheck[opcodes--get_map_value.tz].out | 22 - ...[opcodes--hash_consistency_checker.tz].out | 16 - ...::test_typecheck[opcodes--hash_key.tz].out | 16 - ...est_typecheck[opcodes--hash_string.tz].out | 16 - ...echeck::test_typecheck[opcodes--if.tz].out | 15 - ...k::test_typecheck[opcodes--if_some.tz].out | 13 - ...check::test_typecheck[opcodes--int.tz].out | 16 - ...:test_typecheck[opcodes--iter_fail.tz].out | 14 - ...ck::test_typecheck[opcodes--keccak.tz].out | 16 - ...test_typecheck[opcodes--left_right.tz].out | 15 - ...eck::test_typecheck[opcodes--level.tz].out | 14 - ...est_typecheck[opcodes--list_concat.tz].out | 18 - ...pecheck[opcodes--list_concat_bytes.tz].out | 18 - ...k::test_typecheck[opcodes--list_id.tz].out | 12 - ...est_typecheck[opcodes--list_id_map.tz].out | 14 - ...:test_typecheck[opcodes--list_iter.tz].out | 18 - ..._typecheck[opcodes--list_map_block.tz].out | 25 - ...:test_typecheck[opcodes--list_size.tz].out | 14 - ...t_typecheck[opcodes--loop_failwith.tz].out | 14 - ...:test_typecheck[opcodes--loop_left.tz].out | 41 - ...echeck[opcodes--loop_left_failwith.tz].out | 14 - ...k::test_typecheck[opcodes--map_car.tz].out | 21 - ...ck::test_typecheck[opcodes--map_id.tz].out | 12 - ...::test_typecheck[opcodes--map_iter.tz].out | 47 - ...k::test_typecheck[opcodes--map_map.tz].out | 23 - ...echeck[opcodes--map_map_sideeffect.tz].out | 36 - ...est_typecheck[opcodes--map_mem_nat.tz].out | 22 - ..._typecheck[opcodes--map_mem_string.tz].out | 22 - ...::test_typecheck[opcodes--map_size.tz].out | 14 - ...ck[opcodes--merge_comparable_pairs.tz].out | 31 - ...check::test_typecheck[opcodes--mul.tz].out | 82 - ...ypecheck[opcodes--mul_bls12_381_fr.tz].out | 18 - ...ypecheck[opcodes--mul_bls12_381_g1.tz].out | 18 - ...ypecheck[opcodes--mul_bls12_381_g2.tz].out | 18 - ...st_typecheck[opcodes--mul_overflow.tz].out | 29 - ...eck::test_typecheck[opcodes--munch.tz].out | 13 - ...eck[opcodes--mutez_to_bls12_381_fr.tz].out | 25 - ...check::test_typecheck[opcodes--neg.tz].out | 13 - ...ypecheck[opcodes--neg_bls12_381_fr.tz].out | 16 - ...ypecheck[opcodes--neg_bls12_381_g1.tz].out | 16 - ...ypecheck[opcodes--neg_bls12_381_g2.tz].out | 16 - ...heck::test_typecheck[opcodes--none.tz].out | 14 - ...heck::test_typecheck[opcodes--noop.tz].out | 12 - ...check::test_typecheck[opcodes--not.tz].out | 16 - ...test_typecheck[opcodes--not_binary.tz].out | 15 - ...echeck::test_typecheck[opcodes--or.tz].out | 24 - ...:test_typecheck[opcodes--or_binary.tz].out | 18 - ...pecheck[opcodes--originate_big_map.tz].out | 12 - ...test_typecheck[opcodes--packunpack.tz].out | 27 - ..._typecheck[opcodes--packunpack_rev.tz].out | 171 - ...echeck[opcodes--packunpack_rev_cty.tz].out | 614 -- ...k::test_typecheck[opcodes--pair_id.tz].out | 14 - ...t_typecheck[opcodes--pairing_check.tz].out | 16 - ...eck::test_typecheck[opcodes--pexec.tz].out | 23 - ...k::test_typecheck[opcodes--pexec_2.tz].out | 41 - ...eck::test_typecheck[opcodes--proxy.tz].out | 20 - ...k::test_typecheck[opcodes--ret_int.tz].out | 16 - ...k::test_typecheck[opcodes--reverse.tz].out | 18 - ...st_typecheck[opcodes--reverse_loop.tz].out | 32 - ...check[opcodes--sapling_empty_state.tz].out | 14 - ...heck::test_typecheck[opcodes--self.tz].out | 16 - ...st_typecheck[opcodes--self_address.tz].out | 28 - ...codes--self_address_after_fib_view.tz].out | 38 - ...elf_address_after_nonexistent_view.tz].out | 36 - ...k[opcodes--self_address_after_view.tz].out | 39 - ...check[opcodes--self_after_fib_view.tz].out | 40 - ...codes--self_after_nonexistent_view.tz].out | 39 - ...typecheck[opcodes--self_after_view.tz].out | 41 - ...odes--self_with_default_entrypoint.tz].out | 31 - ...heck[opcodes--self_with_entrypoint.tz].out | 70 - ...ck::test_typecheck[opcodes--sender.tz].out | 14 - ...eck[opcodes--sender_after_fib_view.tz].out | 38 - ...des--sender_after_nonexistent_view.tz].out | 36 - ...pecheck[opcodes--sender_after_view.tz].out | 39 - ...k::test_typecheck[opcodes--set_car.tz].out | 19 - ...k::test_typecheck[opcodes--set_cdr.tz].out | 19 - ...st_typecheck[opcodes--set_delegate.tz].out | 16 - ...ck::test_typecheck[opcodes--set_id.tz].out | 12 - ...::test_typecheck[opcodes--set_iter.tz].out | 18 - ...test_typecheck[opcodes--set_member.tz].out | 36 - ...::test_typecheck[opcodes--set_size.tz].out | 14 - ...heck::test_typecheck[opcodes--sets.tz].out | 68 - ...heck::test_typecheck[opcodes--sha3.tz].out | 16 - ...ck::test_typecheck[opcodes--shifts.tz].out | 17 - ...eck::test_typecheck[opcodes--slice.tz].out | 22 - ...est_typecheck[opcodes--slice_bytes.tz].out | 22 - ...ck::test_typecheck[opcodes--slices.tz].out | 156 - ...ck::test_typecheck[opcodes--source.tz].out | 14 - ...est_typecheck[opcodes--split_bytes.tz].out | 72 - ...st_typecheck[opcodes--split_string.tz].out | 72 - ...echeck[opcodes--store_bls12_381_fr.tz].out | 14 - ...echeck[opcodes--store_bls12_381_g1.tz].out | 14 - ...echeck[opcodes--store_bls12_381_g2.tz].out | 14 - ...est_typecheck[opcodes--store_input.tz].out | 12 - ...:test_typecheck[opcodes--store_now.tz].out | 14 - ...ck::test_typecheck[opcodes--str_id.tz].out | 14 - ...check[opcodes--sub_timestamp_delta.tz].out | 20 - ...ck::test_typecheck[opcodes--subset.tz].out | 46 - ...est_typecheck[opcodes--tez_add_sub.tz].out | 37 - ...test_typecheck[opcodes--ticket_bad.tz].out | 12 - ...ypecheck[opcodes--ticket_big_store.tz].out | 24 - ...est_typecheck[opcodes--ticket_join.tz].out | 23 - ...est_typecheck[opcodes--ticket_read.tz].out | 24 - ...st_typecheck[opcodes--ticket_split.tz].out | 39 - ..._typecheck[opcodes--ticket_store-2.tz].out | 12 - ...st_typecheck[opcodes--ticket_store.tz].out | 14 - ...test_typecheck[opcodes--ticketer-2.tz].out | 35 - ...::test_typecheck[opcodes--ticketer.tz].out | 37 - ...typecheck[opcodes--transfer_amount.tz].out | 14 - ...typecheck[opcodes--transfer_tokens.tz].out | 24 - ...ck::test_typecheck[opcodes--uncomb.tz].out | 28 - ...ck::test_typecheck[opcodes--unpair.tz].out | 322 - ..._typecheck[opcodes--update_big_map.tz].out | 18 - ...:test_typecheck[opcodes--utxo_read.tz].out | 26 - ...eck::test_typecheck[opcodes--utxor.tz].out | 109 - ...::test_typecheck[opcodes--view_fib.tz].out | 18 - ...eck[opcodes--view_mutual_recursion.tz].out | 22 - ...est_typecheck[opcodes--view_op_add.tz].out | 17 - ...ypecheck[opcodes--view_op_constant.tz].out | 17 - ...test_typecheck[opcodes--view_op_id.tz].out | 17 - ...[opcodes--view_op_nonexistent_addr.tz].out | 21 - ...[opcodes--view_op_nonexistent_func.tz].out | 19 - ...pcodes--view_op_test_step_contants.tz].out | 19 - ...p_toplevel_inconsistent_input_type.tz].out | 17 - ..._toplevel_inconsistent_output_type.tz].out | 19 - ...::test_typecheck[opcodes--view_rec.tz].out | 33 - ...pecheck[opcodes--view_toplevel_lib.tz].out | 148 - ...st_typecheck[opcodes--voting_power.tz].out | 20 - ...check::test_typecheck[opcodes--xor.tz].out | 17 - ...81.TestBls12_381::test_add_one_one[Fr].out | 9 - ...81.TestBls12_381::test_add_one_one[G1].out | 9 - ...81.TestBls12_381::test_add_one_one[G2].out | 9 - ...TestBls12_381::test_add_one_random[Fr].out | 72 - ...TestBls12_381::test_add_one_random[G1].out | 72 - ...TestBls12_381::test_add_one_random[G2].out | 72 - ...1.TestBls12_381::test_add_one_zero[Fr].out | 9 - ...1.TestBls12_381::test_add_one_zero[G1].out | 9 - ...1.TestBls12_381::test_add_one_zero[G2].out | 9 - ...TestBls12_381::test_add_random_one[Fr].out | 72 - ...TestBls12_381::test_add_random_one[G1].out | 72 - ...TestBls12_381::test_add_random_one[G2].out | 72 - ...tBls12_381::test_add_random_random[Fr].out | 72 - ...tBls12_381::test_add_random_random[G1].out | 72 - ...tBls12_381::test_add_random_random[G2].out | 72 - ...estBls12_381::test_add_random_zero[Fr].out | 72 - ...estBls12_381::test_add_random_zero[G1].out | 72 - ...estBls12_381::test_add_random_zero[G2].out | 72 - ...1.TestBls12_381::test_add_zero_one[Fr].out | 9 - ...1.TestBls12_381::test_add_zero_one[G1].out | 9 - ...1.TestBls12_381::test_add_zero_one[G2].out | 9 - ...estBls12_381::test_add_zero_random[Fr].out | 72 - ...estBls12_381::test_add_zero_random[G1].out | 72 - ...estBls12_381::test_add_zero_random[G2].out | 72 - ....TestBls12_381::test_add_zero_zero[Fr].out | 9 - ....TestBls12_381::test_add_zero_zero[G1].out | 9 - ....TestBls12_381::test_add_zero_zero[G2].out | 9 - ...fr_bytes_parameters_more_than_32_bytes.out | 8 - ..._bls12_381.TestBls12_381::test_groth16.out | 9 - ...81.TestBls12_381::test_mul_one_one[Fr].out | 9 - ...81.TestBls12_381::test_mul_one_one[G1].out | 9 - ...81.TestBls12_381::test_mul_one_one[G2].out | 9 - ...TestBls12_381::test_mul_one_random[Fr].out | 72 - ...TestBls12_381::test_mul_one_random[G1].out | 72 - ...TestBls12_381::test_mul_one_random[G2].out | 72 - ...1.TestBls12_381::test_mul_one_zero[Fr].out | 9 - ...1.TestBls12_381::test_mul_one_zero[G1].out | 9 - ...1.TestBls12_381::test_mul_one_zero[G2].out | 9 - ...TestBls12_381::test_mul_random_one[Fr].out | 72 - ...TestBls12_381::test_mul_random_one[G1].out | 72 - ...TestBls12_381::test_mul_random_one[G2].out | 72 - ...tBls12_381::test_mul_random_random[Fr].out | 72 - ...tBls12_381::test_mul_random_random[G1].out | 72 - ...tBls12_381::test_mul_random_random[G2].out | 72 - ...estBls12_381::test_mul_random_zero[Fr].out | 72 - ...estBls12_381::test_mul_random_zero[G1].out | 72 - ...estBls12_381::test_mul_random_zero[G2].out | 72 - ...1.TestBls12_381::test_mul_zero_one[Fr].out | 9 - ...1.TestBls12_381::test_mul_zero_one[G1].out | 9 - ...1.TestBls12_381::test_mul_zero_one[G2].out | 9 - ...estBls12_381::test_mul_zero_random[Fr].out | 72 - ...estBls12_381::test_mul_zero_random[G1].out | 72 - ...estBls12_381::test_mul_zero_random[G2].out | 72 - ....TestBls12_381::test_mul_zero_zero[Fr].out | 9 - ....TestBls12_381::test_mul_zero_zero[G1].out | 9 - ....TestBls12_381::test_mul_zero_zero[G2].out | 9 - ...12_381.TestBls12_381::test_neg_one[Fr].out | 9 - ...12_381.TestBls12_381::test_neg_one[G1].out | 9 - ...12_381.TestBls12_381::test_neg_one[G2].out | 9 - ...381.TestBls12_381::test_neg_random[Fr].out | 72 - ...381.TestBls12_381::test_neg_random[G1].out | 72 - ...381.TestBls12_381::test_neg_random[G2].out | 72 - ...2_381.TestBls12_381::test_neg_zero[Fr].out | 9 - ...2_381.TestBls12_381::test_neg_zero[G1].out | 9 - ...2_381.TestBls12_381::test_neg_zero[G2].out | 9 - ...381.TestBls12_381::test_pairing_neg_g1.out | 72 - ...381.TestBls12_381::test_pairing_neg_g2.out | 72 - ...12_381.TestBls12_381::test_pairing_nil.out | 9 - ...81.TestBls12_381::test_pairing_one_one.out | 9 - ...TestBls12_381::test_pairing_one_random.out | 72 - ...1.TestBls12_381::test_pairing_one_zero.out | 9 - ...TestBls12_381::test_pairing_random_one.out | 72 - ...tBls12_381::test_pairing_random_random.out | 72 - ...estBls12_381::test_pairing_random_zero.out | 72 - ...1.TestBls12_381::test_pairing_zero_one.out | 9 - ...estBls12_381::test_pairing_zero_random.out | 72 - ....TestBls12_381::test_pairing_zero_zero.out | 9 - ...tBls12_381::test_signature_aggregation.out | 142 - ..._381.TestBls12_381::test_store_one[Fr].out | 9 - ..._381.TestBls12_381::test_store_one[G1].out | 9 - ..._381.TestBls12_381::test_store_one[G2].out | 9 - ...1.TestBls12_381::test_store_random[Fr].out | 72 - ...1.TestBls12_381::test_store_random[G1].out | 72 - ...1.TestBls12_381::test_store_random[G2].out | 72 - ...381.TestBls12_381::test_store_zero[Fr].out | 9 - ...381.TestBls12_381::test_store_zero[G1].out | 9 - ...381.TestBls12_381::test_store_zero[G2].out | 9 - ...est_macro_expansion[macros--assert.tz].out | 9 - ...cro_expansion[macros--assert_cmpeq.tz].out | 12 - ...cro_expansion[macros--assert_cmpge.tz].out | 12 - ...cro_expansion[macros--assert_cmpgt.tz].out | 12 - ...cro_expansion[macros--assert_cmple.tz].out | 12 - ...cro_expansion[macros--assert_cmplt.tz].out | 12 - ...ro_expansion[macros--assert_cmpneq.tz].out | 12 - ..._macro_expansion[macros--assert_eq.tz].out | 13 - ..._macro_expansion[macros--assert_ge.tz].out | 13 - ..._macro_expansion[macros--assert_gt.tz].out | 13 - ..._macro_expansion[macros--assert_le.tz].out | 13 - ..._macro_expansion[macros--assert_lt.tz].out | 13 - ...macro_expansion[macros--assert_neq.tz].out | 13 - ..._expansion[macros--big_map_get_add.tz].out | 23 - ...acro_expansion[macros--big_map_mem.tz].out | 14 - ...macro_expansion[macros--build_list.tz].out | 24 - ...ro_expansion[macros--carn_and_cdrn.tz].out | 29 - ...st_macro_expansion[macros--compare.tz].out | 22 - ...ro_expansion[macros--compare_bytes.tz].out | 22 - ...:test_macro_expansion[macros--fail.tz].out | 3 - ..._macro_expansion[macros--guestbook.tz].out | 18 - ...xpansion[macros--macro_annotations.tz].out | 13 - ...cro_expansion[macros--map_caddaadr.tz].out | 40 - ...acro_expansion[macros--max_in_list.tz].out | 17 - ...::test_macro_expansion[macros--min.tz].out | 13 - ...macro_expansion[macros--pair_macro.tz].out | 18 - ...cro_expansion[macros--set_caddaadr.tz].out | 33 - ...ro_expansion[macros--take_my_money.tz].out | 14 - ...cro_expansion[macros--unpair_macro.tz].out | 20 - ...ination::test_big_map_origination_diff.out | 29 - ...igination::test_big_map_origination_id.out | 27 - ...tion::test_big_map_origination_literal.out | 50 - ...rigination::test_big_map_transfer_diff.out | 23 - ...pOrigination::test_big_map_transfer_id.out | 22 - ...s.TestContractOnchainLevel::test_level.out | 123 - ...actOnchainOpcodes::test_contract_fails.out | 2 - ...tContractOnchainOpcodes::test_gen_keys.out | 2 - ...ontractOnchainOpcodes::test_init_proxy.out | 53 - ...s.TestContractOnchainOpcodes::test_now.out | 2 - ....TestContractOnchainOpcodes::test_self.out | 2 - ...estContractOnchainOpcodes::test_sender.out | 2 - ...tractOnchainOpcodes::test_set_delegate.out | 123 - ...TestContractOnchainOpcodes::test_slice.out | 87 - ...\"spsig1PPUFZucuAQybs5wsqs.818025e860.out" | 66 - ...0e55c43a9a857214d8761e67b75.2d6806d54e.out | 66 - ...0e55c43a9a857214d8761e67b75.378d03ae2d.out | 66 - ...0e55c43a9a857214d8761e67b75.57fdc7ad1c.out | 66 - ...0e55c43a9a857214d8761e67b75.c583c796bf.out | 66 - ...ef0e55c43a9a857214d8761e67b.7da5c9014e.out | 46 - ...estContractOnchainOpcodes::test_source.out | 119 - ...ntractOnchainOpcodes::test_split_bytes.out | 139 - ...tractOnchainOpcodes::test_split_string.out | 139 - ...ntractOnchainOpcodes::test_store_input.out | 185 - ...trace_origination[compare_big_type.tz].out | 93 - ...race_origination[compare_big_type2.tz].out | 97 - ...ctOnchainOpcodes::test_transfer_amount.out | 83 - ...ctOnchainOpcodes::test_transfer_tokens.out | 238 - ...(Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" | 35 - ...(Some 5) { Elt \"hello\" 4.0427752f13.out" | 35 - ...(Some 5) { Elt \"hello\" 4.0793dc66d5.out" | 36 - ...None { Elt \"1\" 1 ; .df114499b8.out" | 36 - ...None { Elt \"1\" 1 ; .f9bea98de9.out" | 36 - ...None { Elt \"hello\" 4 })-.1db12cd837.out" | 35 - ...None {})-\"hello\"-(Pair N.6fc7d0acf2.out" | 35 - ..." \"one\" ; Elt \"2\" \"tw.524c5459f8.out" | 46 - ...ello\" \"hi\" } None)-\"\".33eba403e7.out" | 45 - ...hello\" \"hi\" } None)-\"h.a5cd1005c9.out" | 45 - ...one\" ; Elt \"2\" \"two\" .6f3d35b151.out" | 36 - ...one\" ; Elt \"2\" \"two\" .76aeaa0706.out" | 48 - ...one\" ; Elt \"2\" \"two\" .7e7197f248.out" | 48 - ...one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" | 49 - ...one\" ; Elt \"2\" \"two\" .b688cc94a7.out" | 49 - ...one\" ; Elt \"2\" \"two\" .c68db221ed.out" | 48 - ...erflow[mul_overflow.tz-Unit-Left Unit].out | 26 - ...rflow[mul_overflow.tz-Unit-Right Unit].out | 26 - ...ow[shifts.tz-None-(Left (Pair 1 257))].out | 26 - ...[shifts.tz-None-(Left (Pair 123 257))].out | 26 - ...w[shifts.tz-None-(Right (Pair 1 257))].out | 26 - ...shifts.tz-None-(Right (Pair 123 257))].out | 26 - ...TestContractOpcodes::test_balance[0.5].out | 21 - ...s.TestContractOpcodes::test_balance[0].out | 21 - ...estContractOpcodes::test_balance[1000].out | 21 - ...s.TestContractOpcodes::test_balance[1].out | 21 - ...stContractOpcodes::test_balance[1e-06].out | 21 - ...s.TestContractOpcodes::test_balance[5].out | 21 - ...Opcodes::test_balance[8000000000000.0].out | 21 - ... \"two\" }) )-(Right (Righ.7492e8cdea.out" | 90 - ... \"two\" }))-(Left Unit)-(.21b30dd90f.out" | 44 - ... \"two\" }))-(Right (Left .2873ef610c.out" | 39 - ... \"two\" }))-(Right (Left .8a6f480005.out" | 35 - ... \"two\" }))-(Right (Right.d336ca1903.out" | 83 - ...Pair \"foo\" \"bar\" } { P.7f2ee47600.out" | 135 - ...tContractOpcodes::test_check_signature.out | 241 - ...tract_input_output[abs.tz-Unit-0-Unit].out | 38 - ....tz-Unit-12039123919239192312931-Unit].out | 38 - ...act_input_output[abs.tz-Unit-948-Unit].out | 38 - ...ct_input_output[add.tz-Unit-Unit-Unit].out | 211 - ...r 0x00 0x00-(Some 0x0000000.3c2de60480.out | 30 - ...r 0x01 0x00-(Some 0x0100000.12b2c1172b.out | 30 - ...r 0x010000 0x00-(Some 0x010.0e44fc6f40.out | 30 - ...r 0x010000 0x010000-(Some 0.7e0ed229a3.out | 30 - ...air -100 100)-(Some \"1970.7c1b1e4e5b.out" | 36 - ...air 0 \"1970-01-01T00:00:0.528ed42c01.out" | 36 - ...air 100 100)-(Some \"1970-.6566111ad2.out" | 36 - ...air \"1970-01-01T00:00:00Z.72c424f3da.out" | 36 - ...air 100 -100)-(Some \"1970.7c4b12e9aa.out" | 36 - ...air 100 100)-(Some \"1970-.af32743640.out" | 36 - ...dhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" | 23 - ...-None-(Pair False False)-(Some False)].out | 31 - ...z-None-(Pair False True)-(Some False)].out | 31 - ...z-None-(Pair True False)-(Some False)].out | 31 - ....tz-None-(Pair True True)-(Some True)].out | 31 - ...t_output[and_binary.tz-Unit-Unit-Unit].out | 93 - ...l_1.tz-False-(Pair False False)-False].out | 24 - ...al_1.tz-False-(Pair False True)-False].out | 24 - ...al_1.tz-False-(Pair True False)-False].out | 24 - ...ical_1.tz-False-(Pair True True)-True].out | 24 - ...put[balance.tz-111-Unit-4000000000000].out | 21 - ...lt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out | 43 - ...lt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out | 43 - ...lt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out | 43 - ...lt 1 0 } None)-1-(Pair 4 (S.73700321f8.out | 43 - ...lt 1 4 ; Elt 2 11 } None)-1.1182eca937.out | 44 - ...lt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out | 44 - ...lt 1 4 ; Elt 2 11 } None)-2.1eead33885.out | 44 - ...lt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out | 44 - ...lt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out | 44 - ...lt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out | 44 - ...air {} None)-1-(Pair 4 (Some False))0].out | 42 - ...air {} None)-1-(Pair 4 (Some False))1].out | 42 - ... \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" | 44 - ... \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" | 44 - ... \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" | 44 - ... \"foo\" 0 } None)-\"foo\".968709d39d.out" | 43 - ... \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" | 43 - ... None)-\"bar\"-(Pair 4 (Some False))].out" | 42 - ...padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out | 24 - ...e-Unit-(Some 0x100000000000.d1219ca789.out | 24 - ...utput[bls12_381_fr_to_int.tz-0-0x00-0].out | 21 - ...utput[bls12_381_fr_to_int.tz-0-0x01-1].out | 21 - ...8db8e57af88d9576acd181b89f2.7a85c336ff.out | 22 - ...9e8abf8dc324a010007addde986.b821eb26b3.out | 22 - ...ut[bls12_381_fr_to_mutez.tz-0-0x10-16].out | 32 - ...000000000000000000000000000.0accef5bef.out | 22 - ...000000000000000000000000000.0ecc537252.out | 22 - ...000000000000000000000000000.2229b767cd.out | 22 - ...000000000000000000000000000.2ff549b46b.out | 22 - ...000000000000000000000000000.bf8a711be6.out | 23 - ...000000000000000000000000000.d41cbb044b.out | 22 - ...a5ad0a633e4880d2296f08ec5c1.a50412e458.out | 23 - ...cd0fa853810e356f1eb79721e80.f3a349c4a7.out | 23 - ...be1766f92cd82c5e5135c374a03.1b9676e4c2.out | 23 - ...be1766f92cd82c5e5135c374a03.e966dc6de5.out | 23 - ...000000000000000000000000000.964835cc43.out | 22 - ...000000000000000000000000000.b25ea709fb.out | 22 - ...000000000000000000000000000.eae36753ea.out | 23 - ...000000000000000000000000000.ee57dac8f7.out | 22 - ...a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out | 23 - ...cd0fa853810e356f1eb79721e80.bd5800f6b8.out | 23 - ...be1766f92cd82c5e5135c374a03.00e897789a.out | 23 - ...be1766f92cd82c5e5135c374a03.a4697eaa13.out | 23 - ...000000000000000000000000000.0177355bbf.out | 25 - ...000000000000000000000000000.744166c609.out | 25 - ...000000000000000000000000000.9f3c5cdc6a.out | 25 - ...000000000000000000000000000.a54cb341ba.out | 25 - ...000000000000000000000000000.b0dc584c94.out | 25 - ...000000000000000000000000000.bddcad090c.out | 26 - ...a5ad0a633e4880d2296f08ec5c1.92c153eb47.out | 26 - ...cd0fa853810e356f1eb79721e80.290ab49d11.out | 26 - ...be1766f92cd82c5e5135c374a03.69f3589a06.out | 26 - ...be1766f92cd82c5e5135c374a03.fee3c5cf43.out | 26 - ...000000000000000000000000000.1bccc033e8.out | 26 - ...000000000000000000000000000.40958700fe.out | 25 - ...000000000000000000000000000.6c62b03d78.out | 25 - ...000000000000000000000000000.d23f269341.out | 25 - ...a5ad0a633e4880d2296f08ec5c1.927f808504.out | 26 - ...cd0fa853810e356f1eb79721e80.0c114c956a.out | 26 - ...be1766f92cd82c5e5135c374a03.03c4f38e68.out | 26 - ...be1766f92cd82c5e5135c374a03.8ed19cfdd9.out | 26 - ...input_output[car.tz-0-(Pair 34 17)-34].out | 21 - ...input_output[cdr.tz-0-(Pair 34 17)-17].out | 21 - ...prcVkpaWU\")-Unit-(Some \".8420090f97.out" | 23 - ...770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" | 23 - ...None-Unit-(Some \"NetXdQprcVkpaWU\")].out" | 23 - ...mb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out | 123 - ... Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" | 36 - ...r 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out | 39 - ...omb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out | 30 - ...nput_output[compare.tz-Unit-Unit-Unit].out | 398 - ...; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out | 350 - ...-{ \"World!\" }-{ \"Hello World!\" }].out" | 28 - ..."test2\" }-{ \"Hello test1.c27e8c3ee6.out" | 35 - ...input_output[concat_hello.tz-{}-{}-{}].out | 21 - ...}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out | 35 - ...hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out | 28 - ...output[concat_hello_bytes.tz-{}-{}-{}].out | 21 - ...; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" | 119 - ...\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" | 96 - ...t_output[concat_list.tz-\"\"-{}-\"\"].out" | 27 - ...ns.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out | 22 - ..._output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out | 22 - ...act_input_output[cons.tz-{}-10-{ 10 }].out | 22 - ...ir { \"A\" } { \"B\" })-(Some False)].out" | 166 - ...\"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" | 410 - ...\"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" | 437 -- ...air { \"B\" } { \"B\" })-(Some True)].out" | 166 - ...ir { \"c\" } { \"B\" })-(Some False)].out" | 166 - ..._all.tz-None-(Pair {} {})-(Some True)].out | 63 - ...wnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" | 29 - ...Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" | 49 - ...970-01-01T00:03:20Z\" \"19.90e9215d17.out" | 34 - ...t[diff_timestamps.tz-111-(Pair 0 0)-0].out | 34 - ...[diff_timestamps.tz-111-(Pair 0 1)--1].out | 34 - ...t[diff_timestamps.tz-111-(Pair 1 0)-1].out | 34 - ...r 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out | 3431 --------- ... 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out | 3431 --------- ...air (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out | 61 - ...p.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out | 36 - ...z-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out | 36 - ...air (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out | 93 - ...air (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out | 39 - ...air (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out | 57 - ..._input_output[dup-n.tz-Unit-Unit-Unit].out | 248 - ... None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out | 142 - ... None)-(Pair 10 -3)-(Pair (.3caea50555.out | 142 - ... None)-(Pair 10 0)-(Pair No.f9448c04fb.out | 142 - ... None)-(Pair 10 (Left 0))-(Left None)].out | 37 - ...air 10 (Left 10))-(Left (So.f782cc1dec.out | 37 - ...air 10 (Left 3))-(Left (Som.016b4db96c.out | 37 - ...one)-(Pair 10 (Right 0))-(Right None)].out | 37 - ...air 10 (Right 10))-(Right (.e705a30e07.out | 37 - ...air 10 (Right 3))-(Right (S.44485eda6a.out | 37 - ...air 5 (Right 10))-(Right (S.8ab987af15.out | 37 - ...-{}-Unit-{ Elt \"hello\" \"world\" }].out" | 33 - ...t[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" | 48 - ...oncat.tz-\"?\"-\"test\"-\"test_abc\"].out" | 48 - ...tput[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out | 30 - ...act_input_output[first.tz-111-{ 4 }-4].out | 30 - ...me 4) {})-\"hello\"-(Pair .161d86cef6.out" | 34 - ...me 5) { Elt \"hello\" 4 }).684ab7e326.out" | 34 - ...me 5) { Elt \"hello\" 4 }).d49817fb83.out" | 34 - ...e { Elt \"1\" 1 ; .6900b1da14.out" | 34 - ...e { Elt \"1\" 1 ; .bca0ede8be.out" | 34 - ... { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" | 34 - ...ir None {})-\"hello\"-(Pair None {})].out" | 34 - ... \"1\" \"one\" ; .bc4127094e.out" | 41 - ..."hello\" \"hi\" })-\"\"-(P.0c03056487.out" | 41 - ...\"hello\" \"hi\" })-\"hell.cc45544c66.out" | 41 - ...nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" | 23 - ...2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" | 23 - ...xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" | 23 - ...-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" | 23 - ..._output[if.tz-None-False-(Some False)].out | 27 - ...ut_output[if.tz-None-True-(Some True)].out | 27 - ....tz-\"?\"-(Some \"hello\")-\"hello\"].out" | 23 - ...ut_output[if_some.tz-\"?\"-None-\"\"].out" | 25 - ...t_input_output[int.tz-None-0-(Some 0)].out | 23 - ...t_input_output[int.tz-None-1-(Some 1)].out | 23 - ...t_output[int.tz-None-9999-(Some 9999)].out | 23 - ...c20776f726c6421-(Some 0xb6e.34c02678c9.out | 24 - ...Left \"X\")-(Left True)-(Right True)].out" | 25 - ...ft \"X\")-(Right \"a\")-(Left \"a\")].out" | 25 - ...ract_input_output[level.tz-111-Unit-1].out | 21 - ...{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" | 27 - ...ut[list_concat.tz-\"abc\"-{}-\"abc\"].out" | 27 - ...tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out | 27 - ..._output[list_concat_bytes.tz-0x-{}-0x].out | 27 - ...b-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out | 27 - ...list_concat_bytes.tz-0xabcd-{}-0xabcd].out | 27 - ... ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" | 19 - ... ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 19 - ...input_output[list_id.tz-{\"\"}-{}-{}].out" | 19 - ... ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" | 27 - ... ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 27 - ...t_output[list_id_map.tz-{\"\"}-{}-{}].out" | 21 - ...tput[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out | 42 - ...tput[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out | 42 - ...}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out | 136 - ...}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out | 136 - ...ut_output[list_map_block.tz-{0}-{}-{}].out | 36 - ...ze.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out | 21 - ...tput[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out | 21 - ...input_output[list_size.tz-111-{ 1 }-1].out | 21 - ...ct_input_output[list_size.tz-111-{}-0].out | 21 - ... ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 163 - ...put_output[loop_left.tz-{\"\"}-{}-{}].out" | 52 - ...0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out | 19 - ...[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out | 19 - ...[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out | 19 - ... Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out | 152 - ...-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out | 152 - ...foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" | 68 - ...lt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" | 50 - ...ract_input_output[map_map.tz-{}-10-{}].out | 32 - ... 1 } None)-1-(Pair { Elt 0 .7396e5f090.out | 42 - ... 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out | 42 - ... 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out | 42 - ... 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out | 42 - ... 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out | 42 - ...air {} None)-1-(Pair {} (Some False))].out | 42 - ...ar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" | 42 - ...ar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" | 42 - ...ar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" | 42 - ...oo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" | 42 - ...oo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" | 42 - ...None)-\"bar\"-(Pair {} (Some False))].out" | 42 - ... \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" | 21 - ...\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" | 21 - ...ut[map_size.tz-111-{ Elt \"a\" 1 }-1].out" | 21 - ...act_input_output[map_size.tz-111-{}-0].out | 21 - ...ct_input_output[mul.tz-Unit-Unit-Unit].out | 131 - ...0-257-0x0101000000000000000.be11332c7f.out | 38 - ...2-16-0x10000000000000000000.8230fb4fac.out | 38 - ...act_input_output[neg.tz-0-(Left -2)-2].out | 25 - ...ract_input_output[neg.tz-0-(Left 0)-0].out | 25 - ...act_input_output[neg.tz-0-(Left 2)--2].out | 25 - ...act_input_output[neg.tz-0-(Right 0)-0].out | 25 - ...ct_input_output[neg.tz-0-(Right 2)--2].out | 25 - ...nput_output[none.tz-Some 10-Unit-None].out | 21 - ..._output[not.tz-None-False-(Some True)].out | 23 - ..._output[not.tz-None-True-(Some False)].out | 23 - ...not_binary.tz-None-(Left -8)-(Some 7)].out | 27 - ...not_binary.tz-None-(Left -9)-(Some 8)].out | 27 - ...not_binary.tz-None-(Left 0)-(Some -1)].out | 27 - ...not_binary.tz-None-(Left 7)-(Some -8)].out | 27 - ...not_binary.tz-None-(Left 8)-(Some -9)].out | 27 - ...ot_binary.tz-None-(Right 0)-(Some -1)].out | 27 - ...ot_binary.tz-None-(Right 7)-(Some -8)].out | 27 - ...ot_binary.tz-None-(Right 8)-(Some -9)].out | 27 - ...-None-(Pair False False)-(Some False)].out | 35 - ...tz-None-(Pair False True)-(Some True)].out | 35 - ...tz-None-(Pair True False)-(Some True)].out | 35 - ....tz-None-(Pair True True)-(Some True)].out | 35 - ...or_binary.tz-None-(Pair 0 8)-(Some 8)].out | 26 - ..._binary.tz-None-(Pair 14 1)-(Some 15)].out | 26 - ..._binary.tz-None-(Pair 15 4)-(Some 15)].out | 26 - ...r_binary.tz-None-(Pair 4 8)-(Some 12)].out | 26 - ...or_binary.tz-None-(Pair 7 7)-(Some 7)].out | 26 - ...or_binary.tz-None-(Pair 8 0)-(Some 8)].out | 26 - ... (Pair 1 (Pair \"foobar\".368bdfd73a.out" | 845 -- ... (Pair 1 (Pair \"foobar\".735d9ae802.out" | 845 -- ...ir \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" | 1194 --- ...ir \"edpkuBknW28nW72KG6RoH.4e20b52378.out" | 1032 --- ...alse False)-(Some (Pair False False))].out | 21 - ... False True)-(Some (Pair False True))].out | 21 - ... True False)-(Some (Pair True False))].out | 21 - ...ir True True)-(Some (Pair True True))].out | 21 - ...ntract_input_output[pexec.tz-14-38-52].out | 47 - ... 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out | 282 - ...utput[ret_int.tz-None-Unit-(Some 300)].out | 23 - ... ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 42 - ...input_output[reverse.tz-{\"\"}-{}-{}].out" | 27 - ... ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 131 - ..._output[reverse_loop.tz-{\"\"}-{}-{}].out" | 50 - ...tput[sapling_empty_state.tz-{}-Unit-0].out | 21 - ...output[self_address.tz-Unit-Unit-Unit].out | 46 - ..._default_entrypoint.tz-Unit-Unit-Unit].out | 47 - ...entrypoint.tz-Unit-Left (Left 0)-Unit].out | 93 - ...Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" | 49 - ..."hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" | 49 - ...lo\" 0)-\"world\"-(Pair \"world\" 0)].out" | 49 - ...ir \"hello\" 0)-1-(Pair \"hello\" 1)].out" | 46 - ... \"hello\" 500)-3-(Pair \"hello\" 3)].out" | 46 - ..."hello\" 7)-100-(Pair \"hello\" 100)].out" | 46 - ... ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 19 - ...; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" | 19 - ...tract_input_output[set_id.tz-{}-{}-{}].out | 19 - ..._iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out | 47 - ..._input_output[set_iter.tz-111-{ 1 }-1].out | 32 - ...act_input_output[set_iter.tz-111-{}-0].out | 27 - ..."World\" } None)-\"\"-(Pai.3d2044726e.out" | 61 - ...)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" | 61 - ... None)-\"Hi\"-(Pair {} (Some False))].out" | 61 - ...ze.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out | 21 - ...utput[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out | 21 - ..._input_output[set_size.tz-111-{ 1 }-1].out | 21 - ...act_input_output[set_size.tz-111-{}-0].out | 21 - ...0776f726c6421-(Some 0xf345a.a07ae9dddf.out | 24 - ...ts.tz-None-(Left (Pair 0 0))-(Some 0)].out | 30 - ...ts.tz-None-(Left (Pair 0 1))-(Some 0)].out | 30 - ...ts.tz-None-(Left (Pair 1 2))-(Some 4)].out | 30 - ....tz-None-(Left (Pair 15 2))-(Some 60)].out | 30 - ...s.tz-None-(Left (Pair 8 1))-(Some 16)].out | 30 - ...s.tz-None-(Right (Pair 0 0))-(Some 0)].out | 30 - ...s.tz-None-(Right (Pair 0 1))-(Some 0)].out | 30 - ...s.tz-None-(Right (Pair 1 2))-(Some 0)].out | 30 - ....tz-None-(Right (Pair 15 2))-(Some 3)].out | 30 - ...s.tz-None-(Right (Pair 8 1))-(Some 4)].out | 30 - ...ut_output[slice.tz-None-Pair 0 0-None].out | 31 - ...tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" | 37 - ...slice.tz-Some \"Foo\"-Pair 0 10-None].out" | 37 - ...-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" | 37 - ...z-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" | 37 - ...[slice.tz-Some \"Foo\"-Pair 1 3-None].out" | 37 - ...slice.tz-Some \"Foo\"-Pair 10 5-None].out" | 37 - ...FooFooFooFooFooFooFooFooFo.c508d67bb0.out" | 38 - ...put[slice_bytes.tz-None-Pair 0 1-None].out | 31 - ...s.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out | 37 - ...tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out | 37 - ...z-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out | 37 - ...z-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out | 37 - ...-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out | 37 - ..._bytes.tz-Some 0xaabbcc-Pair 1 3-None].out | 37 - ...aabbccaabbccaabbccaabbccaab.df5895de85.out | 38 - ...d.tz-None-\"Hello\"-(Some \"Hello\")].out" | 21 - ..._id.tz-None-\"abcd\"-(Some \"abcd\")].out" | 21 - ...r 100 -100)-\"1970-01-01T00:03:20Z\"].out" | 34 - ...ir 100 100)-\"1970-01-01T00:00:00Z\"].out" | 34 - ...Pair 100 200000000000000000.3db82d2c25.out | 34 - ...00000 1000000)-(Some (Pair .b461aa042b.out | 71 - ...10000 1010000)-(Some (Pair .1e8cf7679c.out | 71 - ...t_output[uncomb.tz-0-(Pair 1 4 2)-142].out | 50 - ...input_output[unpair.tz-Unit-Unit-Unit].out | 462 -- ...dpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" | 32 - ...Pair False False)-(Some (Left False))].out | 32 - ... (Pair False True)-(Some (Left True))].out | 32 - ... (Pair True False)-(Some (Left True))].out | 32 - ... (Pair True True)-(Some (Left False))].out | 32 - ...one-Right (Pair 0 0)-(Some (Right 0))].out | 32 - ...one-Right (Pair 0 1)-(Some (Right 1))].out | 32 - ...one-Right (Pair 1 0)-(Some (Right 1))].out | 32 - ...one-Right (Pair 1 1)-(Some (Right 0))].out | 32 - ...-Right (Pair 42 21)-(Some (Right 63))].out | 32 - ...-Right (Pair 42 63)-(Some (Right 21))].out | 32 - ...s::test_hash_consistency_michelson_cli.out | 23 - ...pcodes.TestContractOpcodes::test_level.out | 21 - ...bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" | 9 - ...\"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" | 9 - ...eeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out | 9 - ..._opcodes.TestContractOpcodes::test_now.out | 21 - ...s.TestContractOpcodes::test_packunpack.out | 106 - ...roveTransferRemove::test_add_liquidity.out | 83 - ...ddApproveTransferRemove::test_approval.out | 41 - ...TransferRemove::test_approved_transfer.out | 41 - ...roveTransferRemove::test_call_approve1.out | 41 - ...roveTransferRemove::test_call_approve2.out | 41 - ...roveTransferRemove::test_call_approve3.out | 41 - ...TransferRemove::test_call_mint_or_burn.out | 40 - ...pproveTransferRemove::test_dex_storage.out | 7 - ...pproveTransferRemove::test_lqt_storage.out | 3 - ...eTransferRemove::test_remove_liquidity.out | 80 - ...stAddApproveTransferRemove::test_setup.out | 8 - ...pproveTransferRemove::test_tok_storage.out | 3 - ..._baking.TestTrades::test_add_liquidity.out | 83 - ...uidity_baking.TestTrades::test_buy_tok.out | 75 - ..._baking.TestTrades::test_call_approve1.out | 41 - ..._baking.TestTrades::test_call_approve2.out | 41 - ..._baking.TestTrades::test_call_approve3.out | 41 - ...ing.TestTrades::test_call_mint_or_burn.out | 40 - ...ty_baking.TestTrades::test_dex_storage.out | 7 - ...ty_baking.TestTrades::test_lqt_storage.out | 3 - ...idity_baking.TestTrades::test_sell_tok.out | 74 - ...iquidity_baking.TestTrades::test_setup.out | 8 - ...ty_baking.TestTrades::test_tok_storage.out | 3 - ...idity_baking.TestTrades::test_transfer.out | 43 - tests_python/tests_012/conftest.py | 121 - tests_python/tests_012/contract_paths.py | 20 - .../tests_012/per_block_vote_files/false.json | 1 - .../per_block_vote_files/invalid.json | 1 - .../per_block_vote_files/non_boolean.json | 1 - .../tests_012/per_block_vote_files/true.json | 1 - .../per_block_vote_files/wrong_key.json | 1 - tests_python/tests_012/protocol.py | 69 - tests_python/tests_012/test_accuser.py | 126 - tests_python/tests_012/test_baker_endorser.py | 113 - tests_python/tests_012/test_basic.py | 503 -- tests_python/tests_012/test_binaries.py | 48 - tests_python/tests_012/test_bootstrap.py | 221 - tests_python/tests_012/test_client.py | 35 - .../tests_012/test_client_without_node.py | 450 -- tests_python/tests_012/test_codec.py | 23 - tests_python/tests_012/test_contract.py | 2296 ------ .../tests_012/test_contract_annotations.py | 88 - tests_python/tests_012/test_contract_baker.py | 55 - .../tests_012/test_contract_bls12_381.py | 317 - .../tests_012/test_contract_macros.py | 447 -- .../test_contract_onchain_opcodes.py | 1312 ---- .../tests_012/test_contract_opcodes.py | 1943 ----- tests_python/tests_012/test_cors.py | 47 - tests_python/tests_012/test_crypto.py | 47 - tests_python/tests_012/test_fa12.py | 352 - tests_python/tests_012/test_forge_block.py | 46 - tests_python/tests_012/test_fork.py | 88 - tests_python/tests_012/test_injection.py | 103 - .../tests_012/test_liquidity_baking.py | 279 - tests_python/tests_012/test_many_bakers.py | 42 - tests_python/tests_012/test_many_nodes.py | 66 - tests_python/tests_012/test_mempool.py | 66 - tests_python/tests_012/test_migration.py | 298 - tests_python/tests_012/test_mockup.py | 762 -- .../tests_012/test_multinode_snapshot.py | 753 -- .../test_multinode_storage_reconstruction.py | 180 - .../tests_012/test_multiple_transfers.py | 133 - tests_python/tests_012/test_multisig.py | 620 -- .../tests_012/test_nonce_seed_revelation.py | 133 - tests_python/tests_012/test_openapi.py | 73 - tests_python/tests_012/test_p2p.py | 147 - .../tests_012/test_per_block_votes.py | 131 - tests_python/tests_012/test_programs.py | 97 - .../tests_012/test_proto_demo_counter.py | 88 - .../test_proto_demo_noops_manual_bake.py | 97 - tests_python/tests_012/test_rpc.py | 639 -- tests_python/tests_012/test_sapling.py | 962 --- .../tests_012/test_slice_fails_params.txt | 5 - .../tests_012/test_slice_success_params.txt | 1 - tests_python/tests_012/test_tenderbake.py | 59 - .../test_tenderbake_bakers_restart.py | 80 - .../test_tenderbake_incremental_start.py | 82 - .../test_tenderbake_long_dynamic_bake.py | 237 - .../tests_012/test_tenderbake_manual_bake.py | 231 - tests_python/tests_012/test_tls.py | 23 - tests_python/tests_012/test_voting.py | 249 - tests_python/tests_012/test_voting_full.py | 217 - tests_python/tests_alpha/protocol.py | 6 +- tests_python/tools/constants.py | 5 - 1942 files changed, 4 insertions(+), 245918 deletions(-) delete mode 100644 docs/012/cli-commands.rst delete mode 100644 docs/012/consensus.rst delete mode 100644 docs/012/global_constants.rst delete mode 100644 docs/012/glossary.rst delete mode 100644 docs/012/liquidity_baking.rst delete mode 100644 docs/012/michelson.rst delete mode 100644 docs/012/plugins.rst delete mode 100644 docs/012/proof_of_stake.rst delete mode 100644 docs/012/protocol.rst delete mode 100644 docs/012/protocol_overview.rst delete mode 100644 docs/012/sapling.rst delete mode 100644 docs/012/timelock.rst delete mode 100644 docs/012/voting.rst delete mode 100644 docs/protocols/012_ithaca.rst delete mode 100644 src/proto_012_Psithaca/bin_accuser/.ocamlformat delete mode 100644 src/proto_012_Psithaca/bin_accuser/dune delete mode 100644 src/proto_012_Psithaca/bin_accuser/dune-project delete mode 100644 src/proto_012_Psithaca/bin_accuser/main_accuser_012_Psithaca.ml delete mode 100644 src/proto_012_Psithaca/bin_accuser/tezos-accuser-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/bin_baker/.ocamlformat delete mode 100644 src/proto_012_Psithaca/bin_baker/dune delete mode 100644 src/proto_012_Psithaca/bin_baker/dune-project delete mode 100644 src/proto_012_Psithaca/bin_baker/main_baker_012_Psithaca.ml delete mode 100644 src/proto_012_Psithaca/bin_baker/tezos-baker-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_benchmark/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_benchmark/README.md delete mode 100644 src/proto_012_Psithaca/lib_benchmark/autocomp.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/dune delete mode 100644 src/proto_012_Psithaca/lib_benchmark/dune-project delete mode 100644 src/proto_012_Psithaca/lib_benchmark/execution_context.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/kernel.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/dune delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/dune-project delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/inference.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/inference.mli delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/int_map.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky.mli delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky_prim.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/monads.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/stores.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/dune delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/test_inference.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/test_uf.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/tezos-benchmark-type-inference-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/type.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/type.mli delete mode 100644 src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/uf.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/micheline_sampler.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/micheline_sampler.mli delete mode 100644 src/proto_012_Psithaca/lib_benchmark/michelson_mcmc_samplers.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/michelson_mcmc_samplers.mli delete mode 100644 src/proto_012_Psithaca/lib_benchmark/michelson_samplers.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/michelson_samplers.mli delete mode 100644 src/proto_012_Psithaca/lib_benchmark/michelson_samplers_base.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/michelson_samplers_base.mli delete mode 100644 src/proto_012_Psithaca/lib_benchmark/mikhailsky_to_michelson.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/rules.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/sampling_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/state_space.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/test/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_benchmark/test/dune delete mode 100644 src/proto_012_Psithaca/lib_benchmark/test/test_autocompletion.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/test/test_distribution.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/test/test_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/test/test_sampling_code.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/test/test_sampling_data.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/tezos-benchmark-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_benchmark/type_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmark/type_helpers.mli delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/cache_benchmarks.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/dune delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/dune-project delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/encodings_benchmarks.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/gas_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/global_constants_storage_benchmarks.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_benchmarks.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_model.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_workload.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/michelson_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/michelson_generation.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/michelson_generation.mli delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/michelson_types.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/registration_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/sapling_benchmarks.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/sapling_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/sapling_generation.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/script_repr_benchmarks.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/script_typed_ir_size_benchmarks.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/size.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/tags.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/tezos-benchmarks-proto-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/translator_benchmarks.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/translator_model.ml delete mode 100644 src/proto_012_Psithaca/lib_benchmarks_proto/translator_workload.ml delete mode 100644 src/proto_012_Psithaca/lib_client/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_client/annotated_manager_operation.ml delete mode 100644 src/proto_012_Psithaca/lib_client/annotated_manager_operation.mli delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_args.ml delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_args.mli delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_context.ml delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_context.mli delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_contracts.ml delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_contracts.mli delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_fa12.ml delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_fa12.mli delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_multisig.ml delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_multisig.mli delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_programs.ml delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_programs.mli delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_utils.ml delete mode 100644 src/proto_012_Psithaca/lib_client/client_proto_utils.mli delete mode 100644 src/proto_012_Psithaca/lib_client/dune delete mode 100644 src/proto_012_Psithaca/lib_client/dune-project delete mode 100644 src/proto_012_Psithaca/lib_client/injection.ml delete mode 100644 src/proto_012_Psithaca/lib_client/injection.mli delete mode 100644 src/proto_012_Psithaca/lib_client/light.ml delete mode 100644 src/proto_012_Psithaca/lib_client/limit.ml delete mode 100644 src/proto_012_Psithaca/lib_client/limit.mli delete mode 100644 src/proto_012_Psithaca/lib_client/managed_contract.ml delete mode 100644 src/proto_012_Psithaca/lib_client/managed_contract.mli delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_emacs.ml delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_emacs.mli delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_entrypoints.ml delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_entrypoints.mli delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_error_reporter.ml delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_error_reporter.mli delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_macros.ml delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_macros.mli delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_parser.ml delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_parser.mli delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_printer.ml delete mode 100644 src/proto_012_Psithaca/lib_client/michelson_v1_printer.mli delete mode 100644 src/proto_012_Psithaca/lib_client/mockup.ml delete mode 100644 src/proto_012_Psithaca/lib_client/operation_result.ml delete mode 100644 src/proto_012_Psithaca/lib_client/operation_result.mli delete mode 100644 src/proto_012_Psithaca/lib_client/protocol_client_context.ml delete mode 100644 src/proto_012_Psithaca/lib_client/proxy.ml delete mode 100644 src/proto_012_Psithaca/lib_client/test/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_client/test/assert.ml delete mode 100644 src/proto_012_Psithaca/lib_client/test/dune delete mode 100644 src/proto_012_Psithaca/lib_client/test/test_client_proto_context.ml delete mode 100644 src/proto_012_Psithaca/lib_client/test/test_client_proto_contracts.ml delete mode 100644 src/proto_012_Psithaca/lib_client/test/test_michelson_v1_macros.ml delete mode 100644 src/proto_012_Psithaca/lib_client/test/test_proxy.ml delete mode 100644 src/proto_012_Psithaca/lib_client/tezos-client-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_client_commands/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_client_commands/alpha_commands_registration.ml delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_context_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_contracts_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_fa12_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_mockup_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_mockup_commands.mli delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_multisig_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_multisig_commands.mli delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_programs_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_programs_commands.mli delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_stresstest_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_utils_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_client_commands/client_proto_utils_commands.mli delete mode 100644 src/proto_012_Psithaca/lib_client_commands/dune delete mode 100644 src/proto_012_Psithaca/lib_client_commands/dune-project delete mode 100644 src/proto_012_Psithaca/lib_client_commands/tezos-client-012-Psithaca-commands-registration.opam delete mode 100644 src/proto_012_Psithaca/lib_client_commands/tezos-client-012-Psithaca-commands.opam delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/client_sapling_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/client_sapling_commands.mli delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/context.ml delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/context.mli delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/dune delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/dune-project delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/tezos-client-sapling-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/wallet.ml delete mode 100644 src/proto_012_Psithaca/lib_client_sapling/wallet.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_delegate/abstract_context_index.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/abstract_context_index.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_actions.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_actions.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_cache.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_commands.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_commands.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_commands_registration.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_configuration.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_configuration.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_errors.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_events.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_files.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_files.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_highwatermarks.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_highwatermarks.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_lib.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_lib.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_nonces.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_nonces.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_pow.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_pow.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_scheduling.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_scheduling.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_simulator.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_simulator.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_state.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/baking_state.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/block_forge.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/block_forge.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/client_baking_blocks.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/client_baking_blocks.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/client_baking_denunciation.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/client_baking_denunciation.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/client_baking_scheduling.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/client_baking_scheduling.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/client_daemon.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/client_daemon.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/context_ops.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/delegate_events.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/dune delete mode 100644 src/proto_012_Psithaca/lib_delegate/dune-project delete mode 100644 src/proto_012_Psithaca/lib_delegate/liquidity_baking_vote_file.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/logging.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/logging.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/node_rpc.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/node_rpc.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/operation_pool.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/operation_pool.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/operation_selection.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/operation_selection.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/operation_worker.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/operation_worker.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/state_transitions.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/state_transitions.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/README.md delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/dune delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/main.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/broadcast_services.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/dune delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_client_context.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_daemon.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_services.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/mockup_simulator.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/mockup_simulator.mli delete mode 100644 src/proto_012_Psithaca/lib_delegate/test/test_scenario.ml delete mode 100644 src/proto_012_Psithaca/lib_delegate/tezos-accuser-012-Psithaca-commands.opam delete mode 100644 src/proto_012_Psithaca/lib_delegate/tezos-baking-012-Psithaca-commands.opam delete mode 100644 src/proto_012_Psithaca/lib_delegate/tezos-baking-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_delegate/tezos-endorser-012-Psithaca-commands.opam delete mode 100644 src/proto_012_Psithaca/lib_parameters/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_parameters/default_parameters.ml delete mode 100644 src/proto_012_Psithaca/lib_parameters/default_parameters.mli delete mode 100644 src/proto_012_Psithaca/lib_parameters/dune delete mode 100644 src/proto_012_Psithaca/lib_parameters/dune-project delete mode 100644 src/proto_012_Psithaca/lib_parameters/gen.ml delete mode 100644 src/proto_012_Psithaca/lib_parameters/tezos-protocol-012-Psithaca-parameters.opam delete mode 100644 src/proto_012_Psithaca/lib_plugin/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_plugin/dune delete mode 100644 src/proto_012_Psithaca/lib_plugin/dune-project delete mode 100644 src/proto_012_Psithaca/lib_plugin/plugin.ml delete mode 100644 src/proto_012_Psithaca/lib_plugin/plugin_registerer.ml delete mode 100644 src/proto_012_Psithaca/lib_plugin/test/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_plugin/test/dune delete mode 100644 src/proto_012_Psithaca/lib_plugin/test/test_consensus_filter.ml delete mode 100644 src/proto_012_Psithaca/lib_plugin/tezos-protocol-plugin-012-Psithaca-registerer.opam delete mode 100644 src/proto_012_Psithaca/lib_plugin/tezos-protocol-plugin-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_protocol/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_protocol/TEZOS_PROTOCOL delete mode 100644 src/proto_012_Psithaca/lib_protocol/alpha_context.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/alpha_context.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/alpha_services.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/alpha_services.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/amendment.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/amendment.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/apply.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/apply.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/apply_results.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/apply_results.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/baking.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/baking.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/blinded_public_key_hash.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/blinded_public_key_hash.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/block_header_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/block_header_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/block_payload_hash.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/block_payload_hash.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/block_payload_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/block_payload_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/bootstrap_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/bootstrap_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/cache_memory_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/cache_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/cache_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/commitment_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/commitment_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/commitment_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/commitment_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/constants_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/constants_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/constants_services.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/constants_services.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/constants_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/constants_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_delegate_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_delegate_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_hash.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_hash.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_manager_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_manager_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_services.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_services.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/contract_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/contracts/cpmm.bin delete mode 100644 src/proto_012_Psithaca/lib_protocol/contracts/cpmm.mligo delete mode 100644 src/proto_012_Psithaca/lib_protocol/contracts/cpmm.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/contracts/lqt.bin delete mode 100644 src/proto_012_Psithaca/lib_protocol/contracts/lqt.mligo delete mode 100644 src/proto_012_Psithaca/lib_protocol/contracts/lqt.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/coq-of-ocaml/README.md delete mode 100644 src/proto_012_Psithaca/lib_protocol/coq-of-ocaml/config.json delete mode 100644 src/proto_012_Psithaca/lib_protocol/cycle_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/cycle_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/delegate_activation_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/delegate_activation_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/delegate_services.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/delegate_services.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/delegate_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/delegate_storage.mli delete mode 120000 src/proto_012_Psithaca/lib_protocol/dune delete mode 100644 src/proto_012_Psithaca/lib_protocol/dune-project delete mode 100644 src/proto_012_Psithaca/lib_protocol/dune.inc delete mode 100644 src/proto_012_Psithaca/lib_protocol/fees_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/fees_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/fitness_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/fitness_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/fixed_point_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/fixed_point_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/frozen_deposits_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/frozen_deposits_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/gas_limit_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/gas_limit_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/gas_monad.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/gas_monad.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/global_constants_costs.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/global_constants_costs.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/global_constants_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/global_constants_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/init_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/init_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/lazy_storage_diff.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/lazy_storage_diff.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/lazy_storage_kind.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/lazy_storage_kind.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/level_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/level_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/level_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/level_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/liquidity_baking_cpmm.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/liquidity_baking_lqt.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/liquidity_baking_migration.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/liquidity_baking_migration.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/liquidity_baking_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/liquidity_baking_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/local_gas_counter.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/main.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/main.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/manager_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/manager_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/michelson_v1_gas.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/michelson_v1_gas.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/michelson_v1_primitives.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/michelson_v1_primitives.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/migration_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/migration_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/misc.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/misc.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/non_empty_string.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/non_empty_string.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/nonce_hash.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/nonce_hash.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/nonce_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/nonce_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/operation_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/operation_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/parameters_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/parameters_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/path_encoding.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/path_encoding.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/period_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/period_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/raw_context.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/raw_context.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/raw_context_intf.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/raw_level_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/raw_level_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/receipt_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/receipt_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/roll_repr_legacy.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/roll_repr_legacy.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/roll_storage_legacy.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/roll_storage_legacy.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/round_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/round_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/sampler.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/sampler.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/sapling_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/sapling_services.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/sapling_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/sapling_validator.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/saturation_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/saturation_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_cache.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_cache.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_comparable.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_comparable.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_expr_hash.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_expr_hash.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_int_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_int_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_interpreter.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_interpreter.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_interpreter_defs.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_ir_annot.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_ir_annot.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_ir_translator.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_ir_translator.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_list.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_list.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_map.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_map.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_set.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_set.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_string_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_string_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_tc_errors.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_tc_errors_registration.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_tc_errors_registration.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_timestamp_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_timestamp_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_typed_ir.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_typed_ir.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_typed_ir_size.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_typed_ir_size.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_typed_ir_size_costs.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/script_typed_ir_size_costs.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/seed_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/seed_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/seed_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/seed_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/services_registration.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/services_registration.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/slot_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/slot_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/stake_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/stake_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/state_hash.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/state_hash.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/storage_costs.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/storage_costs.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/storage_description.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/storage_description.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/storage_functors.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/storage_functors.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/storage_sigs.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/big_interpreter_stack.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_double.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_drop.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_send.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_state_as_arg.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_push_sapling_state.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_use_existing_state.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/temp_big_maps.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/contracts/timelock.tz delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/dune delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/README.md delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/account.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/account.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/assert.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/block.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/block.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/consensus_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/context.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/context.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/contract_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/cpmm_logic.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/cpmm_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/dune delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/dune-project delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/error_monad_operators.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/expr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/expr_common.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/incremental.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/incremental.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_generator.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_generator.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/lqt_fa12_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/nonce.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/nonce.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/op.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/op.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/rewards.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/sapling_helpers.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/script_big_map.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/script_big_map.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/script_list.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/script_list.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/script_map.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/script_map.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/script_set.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/script_set.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/test_global_constants.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/test_tez.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/testable.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/helpers/tezos-012-Psithaca-test-helpers.opam delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/liquidity_baking_pbt.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/main.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/saturation_fuzzing.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_activation.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_baking.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_combined_operations.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_constants.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_deactivation.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_delegation.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_double_baking.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_double_endorsement.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_double_preendorsement.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_endorsement.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_failing_noop.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_fitness.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_fixed_point.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_frozen_deposits.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_gas_costs.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_gas_levels.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_gas_properties.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_global_constants_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_helpers_rpcs.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_interpretation.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_lazy_storage_diff.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_level_module.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_liquidity_baking.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_origination.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_participation.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_preendorsement.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_preendorsement_functor.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_qty.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_receipt.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_reveal.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_round_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_sampler.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_sapling.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_saturation.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_script_comparison.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_script_typed_ir_size.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_seed.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_temp_big_maps.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_tez_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_ticket_balance_key.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_ticket_scanner.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_ticket_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_time_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_timelock.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_token.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_transfer.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_typechecking.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/test_voting.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/unit/.ocamlformat delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/unit/dune delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/unit/main.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/unit/test_alpha_context.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/unit/test_contract_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/unit/test_global_constants_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/unit/test_operation_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/unit/test_raw_level_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/test/unit/test_tez_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/tez_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/tez_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/tezos-embedded-protocol-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_protocol/tezos-protocol-012-Psithaca-tests.opam delete mode 100644 src/proto_012_Psithaca/lib_protocol/tezos-protocol-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_protocol/tezos-protocol-functor-012-Psithaca.opam delete mode 100644 src/proto_012_Psithaca/lib_protocol/ticket_balance_key.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/ticket_balance_key.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/ticket_costs.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/ticket_costs.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/ticket_scanner.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/ticket_scanner.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/ticket_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/ticket_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/time_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/time_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/token.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/token.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/vote_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/vote_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/vote_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/vote_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/voting_period_repr.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/voting_period_repr.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/voting_period_storage.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/voting_period_storage.mli delete mode 100644 src/proto_012_Psithaca/lib_protocol/voting_services.ml delete mode 100644 src/proto_012_Psithaca/lib_protocol/voting_services.mli delete mode 100644 src/proto_012_Psithaca/parameters/dune delete mode 100644 tests_python/contracts_012/attic/accounts.tz delete mode 100644 tests_python/contracts_012/attic/add1.tz delete mode 100644 tests_python/contracts_012/attic/add1_list.tz delete mode 100644 tests_python/contracts_012/attic/after_strategy.tz delete mode 100644 tests_python/contracts_012/attic/always.tz delete mode 100644 tests_python/contracts_012/attic/append.tz delete mode 100644 tests_python/contracts_012/attic/at_least.tz delete mode 100644 tests_python/contracts_012/attic/auction.tz delete mode 100644 tests_python/contracts_012/attic/bad_lockup.tz delete mode 100644 tests_python/contracts_012/attic/big_map_union.tz delete mode 100644 tests_python/contracts_012/attic/cadr_annotation.tz delete mode 100644 tests_python/contracts_012/attic/concat.tz delete mode 100644 tests_python/contracts_012/attic/conditionals.tz delete mode 100644 tests_python/contracts_012/attic/cons_twice.tz delete mode 100644 tests_python/contracts_012/attic/cps_fact.tz delete mode 100644 tests_python/contracts_012/attic/create_add1_lists.tz delete mode 100644 tests_python/contracts_012/attic/data_publisher.tz delete mode 100644 tests_python/contracts_012/attic/dispatch.tz delete mode 100644 tests_python/contracts_012/attic/empty.tz delete mode 100644 tests_python/contracts_012/attic/fail_amount.tz delete mode 100644 tests_python/contracts_012/attic/faucet.tz delete mode 100644 tests_python/contracts_012/attic/forward.tz delete mode 100644 tests_python/contracts_012/attic/id.tz delete mode 100644 tests_python/contracts_012/attic/infinite_loop.tz delete mode 100644 tests_python/contracts_012/attic/insertion_sort.tz delete mode 100644 tests_python/contracts_012/attic/int_publisher.tz delete mode 100644 tests_python/contracts_012/attic/king_of_tez.tz delete mode 100644 tests_python/contracts_012/attic/list_of_transactions.tz delete mode 100644 tests_python/contracts_012/attic/queue.tz delete mode 100644 tests_python/contracts_012/attic/reduce_map.tz delete mode 100644 tests_python/contracts_012/attic/reentrancy.tz delete mode 100644 tests_python/contracts_012/attic/reservoir.tz delete mode 100644 tests_python/contracts_012/attic/scrutable_reservoir.tz delete mode 100644 tests_python/contracts_012/attic/spawn_identities.tz delete mode 100644 tests_python/contracts_012/entrypoints/big_map_entrypoints.tz delete mode 100644 tests_python/contracts_012/entrypoints/delegatable_target.tz delete mode 100644 tests_python/contracts_012/entrypoints/manager.tz delete mode 100644 tests_python/contracts_012/entrypoints/no_default_target.tz delete mode 100644 tests_python/contracts_012/entrypoints/no_entrypoint_target.tz delete mode 100644 tests_python/contracts_012/entrypoints/rooted_target.tz delete mode 100644 tests_python/contracts_012/entrypoints/simple_entrypoints.tz delete mode 100644 tests_python/contracts_012/ill_typed/badly_indented.tz delete mode 100644 tests_python/contracts_012/ill_typed/big_dip.tz delete mode 100644 tests_python/contracts_012/ill_typed/big_drop.tz delete mode 100644 tests_python/contracts_012/ill_typed/big_map_arity.tz delete mode 100644 tests_python/contracts_012/ill_typed/chain_id_arity.tz delete mode 100644 tests_python/contracts_012/ill_typed/comb0.tz delete mode 100644 tests_python/contracts_012/ill_typed/comb1.tz delete mode 100644 tests_python/contracts_012/ill_typed/contract_annotation_default.tz delete mode 100644 tests_python/contracts_012/ill_typed/dip_failwith.tz delete mode 100644 tests_python/contracts_012/ill_typed/dup0.tz delete mode 100644 tests_python/contracts_012/ill_typed/failwith_big_map.tz delete mode 100644 tests_python/contracts_012/ill_typed/invalid_self_entrypoint.tz delete mode 100644 tests_python/contracts_012/ill_typed/map_failwith.tz delete mode 100644 tests_python/contracts_012/ill_typed/missing_only_code_field.tz delete mode 100644 tests_python/contracts_012/ill_typed/missing_only_parameter_field.tz delete mode 100644 tests_python/contracts_012/ill_typed/missing_only_storage_field.tz delete mode 100644 tests_python/contracts_012/ill_typed/missing_parameter_and_storage_fields.tz delete mode 100644 tests_python/contracts_012/ill_typed/multiple_code_field.tz delete mode 100644 tests_python/contracts_012/ill_typed/multiple_parameter_field.tz delete mode 100644 tests_python/contracts_012/ill_typed/multiple_storage_and_code_fields.tz delete mode 100644 tests_python/contracts_012/ill_typed/multiple_storage_field.tz delete mode 100644 tests_python/contracts_012/ill_typed/never_literal.tz delete mode 100644 tests_python/contracts_012/ill_typed/pack_big_map.tz delete mode 100644 tests_python/contracts_012/ill_typed/pack_operation.tz delete mode 100644 tests_python/contracts_012/ill_typed/pack_sapling_state.tz delete mode 100644 tests_python/contracts_012/ill_typed/push_big_map_with_id_with_parens.tz delete mode 100644 tests_python/contracts_012/ill_typed/push_big_map_with_id_without_parens.tz delete mode 100644 tests_python/contracts_012/ill_typed/sapling_build_empty_state_with_int_parameter.tz delete mode 100644 tests_python/contracts_012/ill_typed/set_update_non_comparable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undig2able.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undigable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undip2able.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undipable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undropable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undug2able.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undugable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undup2able.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unfailwithable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_ungetable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unleftable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unpairable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unpopable.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unpopable_in_lambda.tz delete mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unrightable.tz delete mode 100644 tests_python/contracts_012/ill_typed/ticket_apply.tz delete mode 100644 tests_python/contracts_012/ill_typed/ticket_dup.tz delete mode 100644 tests_python/contracts_012/ill_typed/ticket_in_ticket.tz delete mode 100644 tests_python/contracts_012/ill_typed/ticket_unpack.tz delete mode 100644 tests_python/contracts_012/ill_typed/uncomb0.tz delete mode 100644 tests_python/contracts_012/ill_typed/uncomb1.tz delete mode 100644 tests_python/contracts_012/ill_typed/unpack_sapling_state.tz delete mode 100644 tests_python/contracts_012/ill_typed/unpair_field_annotation_mismatch.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_char_set.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_type.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_name_non_printable_char.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_name_too_long.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_return_type.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_op_dupable_type.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_op_invalid_arity.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_op_lazy_storage.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_op_lazy_storage_type.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_input_type.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_char_set.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_type.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_name_non_printable_char.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_name_too_long.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_return_type.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_type.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_input.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_output.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_duplicated_name.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_invalid_arity.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_input.tz delete mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_output.tz delete mode 100644 tests_python/contracts_012/legacy/create_account.tz delete mode 100644 tests_python/contracts_012/legacy/create_contract.tz delete mode 100644 tests_python/contracts_012/legacy/create_contract_flags.tz delete mode 100644 tests_python/contracts_012/legacy/create_contract_rootname.tz delete mode 100644 tests_python/contracts_012/legacy/originator.tz delete mode 100644 tests_python/contracts_012/legacy/steps_to_quota.tz delete mode 100644 tests_python/contracts_012/macros/assert.tz delete mode 100644 tests_python/contracts_012/macros/assert_cmpeq.tz delete mode 100644 tests_python/contracts_012/macros/assert_cmpge.tz delete mode 100644 tests_python/contracts_012/macros/assert_cmpgt.tz delete mode 100644 tests_python/contracts_012/macros/assert_cmple.tz delete mode 100644 tests_python/contracts_012/macros/assert_cmplt.tz delete mode 100644 tests_python/contracts_012/macros/assert_cmpneq.tz delete mode 100644 tests_python/contracts_012/macros/assert_eq.tz delete mode 100644 tests_python/contracts_012/macros/assert_ge.tz delete mode 100644 tests_python/contracts_012/macros/assert_gt.tz delete mode 100644 tests_python/contracts_012/macros/assert_le.tz delete mode 100644 tests_python/contracts_012/macros/assert_lt.tz delete mode 100644 tests_python/contracts_012/macros/assert_neq.tz delete mode 100644 tests_python/contracts_012/macros/big_map_get_add.tz delete mode 100644 tests_python/contracts_012/macros/big_map_mem.tz delete mode 100644 tests_python/contracts_012/macros/build_list.tz delete mode 100644 tests_python/contracts_012/macros/carn_and_cdrn.tz delete mode 100644 tests_python/contracts_012/macros/compare.tz delete mode 100644 tests_python/contracts_012/macros/compare_bytes.tz delete mode 100644 tests_python/contracts_012/macros/fail.tz delete mode 100644 tests_python/contracts_012/macros/guestbook.tz delete mode 100644 tests_python/contracts_012/macros/macro_annotations.tz delete mode 100644 tests_python/contracts_012/macros/map_caddaadr.tz delete mode 100644 tests_python/contracts_012/macros/max_in_list.tz delete mode 100644 tests_python/contracts_012/macros/min.tz delete mode 100644 tests_python/contracts_012/macros/pair_macro.tz delete mode 100644 tests_python/contracts_012/macros/set_caddaadr.tz delete mode 100644 tests_python/contracts_012/macros/take_my_money.tz delete mode 100644 tests_python/contracts_012/macros/unpair_macro.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/authentication.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/big_map_entrypoints.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/big_map_magic.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/big_map_read.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/big_map_store.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/big_map_write.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/create_contract.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/create_contract_simple.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/default_account.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/execution_order_appender.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/execution_order_caller.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/execution_order_storer.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/fa12_reference.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/generic_multisig.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/groth16.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/hardlimit.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/legacy_multisig.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/lockup.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/lqt_fa12.mligo.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/multiple_en2.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/multiple_entrypoints_counter.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/parameterized_multisig.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/replay.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/reveal_signed_preimage.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/self_address_receiver.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/self_address_sender.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/ticket_builder_fungible.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/ticket_builder_non_fungible.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/ticket_wallet_fungible.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/ticket_wallet_non_fungible.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/tzip4_view.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/vote_for_delegate.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/weather_insurance.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/xcat.tz delete mode 100644 tests_python/contracts_012/mini_scenarios/xcat_dapp.tz delete mode 100644 tests_python/contracts_012/non_regression/bug_262.tz delete mode 100644 tests_python/contracts_012/non_regression/pairk_annot.tz delete mode 100644 tests_python/contracts_012/opcodes/abs.tz delete mode 100644 tests_python/contracts_012/opcodes/add.tz delete mode 100644 tests_python/contracts_012/opcodes/add_bls12_381_fr.tz delete mode 100644 tests_python/contracts_012/opcodes/add_bls12_381_g1.tz delete mode 100644 tests_python/contracts_012/opcodes/add_bls12_381_g2.tz delete mode 100644 tests_python/contracts_012/opcodes/add_delta_timestamp.tz delete mode 100644 tests_python/contracts_012/opcodes/add_timestamp_delta.tz delete mode 100644 tests_python/contracts_012/opcodes/address.tz delete mode 100644 tests_python/contracts_012/opcodes/amount_after_fib_view.tz delete mode 100644 tests_python/contracts_012/opcodes/amount_after_nonexistent_view.tz delete mode 100644 tests_python/contracts_012/opcodes/amount_after_view.tz delete mode 100644 tests_python/contracts_012/opcodes/and.tz delete mode 100644 tests_python/contracts_012/opcodes/and_binary.tz delete mode 100644 tests_python/contracts_012/opcodes/and_logical_1.tz delete mode 100644 tests_python/contracts_012/opcodes/balance.tz delete mode 100644 tests_python/contracts_012/opcodes/balance_after_fib_view.tz delete mode 100644 tests_python/contracts_012/opcodes/balance_after_nonexistent_view.tz delete mode 100644 tests_python/contracts_012/opcodes/balance_after_view.tz delete mode 100644 tests_python/contracts_012/opcodes/big_map_mem_nat.tz delete mode 100644 tests_python/contracts_012/opcodes/big_map_mem_string.tz delete mode 100644 tests_python/contracts_012/opcodes/big_map_to_self.tz delete mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_push_bytes_not_padded.tz delete mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_push_nat.tz delete mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_to_int.tz delete mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_to_mutez.tz delete mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_z_int.tz delete mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_z_nat.tz delete mode 100644 tests_python/contracts_012/opcodes/bls12_381_z_fr_int.tz delete mode 100644 tests_python/contracts_012/opcodes/bls12_381_z_fr_nat.tz delete mode 100644 tests_python/contracts_012/opcodes/bytes.tz delete mode 100644 tests_python/contracts_012/opcodes/car.tz delete mode 100644 tests_python/contracts_012/opcodes/cdr.tz delete mode 100644 tests_python/contracts_012/opcodes/chain_id.tz delete mode 100644 tests_python/contracts_012/opcodes/chain_id_store.tz delete mode 100644 tests_python/contracts_012/opcodes/check_signature.tz delete mode 100644 tests_python/contracts_012/opcodes/comb-get.tz delete mode 100644 tests_python/contracts_012/opcodes/comb-literals.tz delete mode 100644 tests_python/contracts_012/opcodes/comb-set-2.tz delete mode 100644 tests_python/contracts_012/opcodes/comb-set.tz delete mode 100644 tests_python/contracts_012/opcodes/comb.tz delete mode 100644 tests_python/contracts_012/opcodes/compare.tz delete mode 100644 tests_python/contracts_012/opcodes/compare_big_type.tz delete mode 100644 tests_python/contracts_012/opcodes/compare_big_type2.tz delete mode 100644 tests_python/contracts_012/opcodes/comparisons.tz delete mode 100644 tests_python/contracts_012/opcodes/concat_hello.tz delete mode 100644 tests_python/contracts_012/opcodes/concat_hello_bytes.tz delete mode 100644 tests_python/contracts_012/opcodes/concat_list.tz delete mode 100644 tests_python/contracts_012/opcodes/cons.tz delete mode 100644 tests_python/contracts_012/opcodes/contains_all.tz delete mode 100644 tests_python/contracts_012/opcodes/contract.tz delete mode 100644 tests_python/contracts_012/opcodes/create_contract.tz delete mode 100644 tests_python/contracts_012/opcodes/create_contract_rootname.tz delete mode 100644 tests_python/contracts_012/opcodes/create_contract_rootname_alt.tz delete mode 100644 tests_python/contracts_012/opcodes/create_contract_with_view.tz delete mode 100644 tests_python/contracts_012/opcodes/diff_timestamps.tz delete mode 100644 tests_python/contracts_012/opcodes/dig_eq.tz delete mode 100644 tests_python/contracts_012/opcodes/dign.tz delete mode 100644 tests_python/contracts_012/opcodes/dip.tz delete mode 100644 tests_python/contracts_012/opcodes/dipn.tz delete mode 100644 tests_python/contracts_012/opcodes/dropn.tz delete mode 100644 tests_python/contracts_012/opcodes/dugn.tz delete mode 100644 tests_python/contracts_012/opcodes/dup-n.tz delete mode 100644 tests_python/contracts_012/opcodes/ediv.tz delete mode 100644 tests_python/contracts_012/opcodes/ediv_mutez.tz delete mode 100644 tests_python/contracts_012/opcodes/empty_map.tz delete mode 100644 tests_python/contracts_012/opcodes/exec_concat.tz delete mode 100644 tests_python/contracts_012/opcodes/first.tz delete mode 100644 tests_python/contracts_012/opcodes/get_and_update_big_map.tz delete mode 100644 tests_python/contracts_012/opcodes/get_and_update_map.tz delete mode 100644 tests_python/contracts_012/opcodes/get_big_map_value.tz delete mode 100644 tests_python/contracts_012/opcodes/get_map_value.tz delete mode 100644 tests_python/contracts_012/opcodes/hash_consistency_checker.tz delete mode 100644 tests_python/contracts_012/opcodes/hash_key.tz delete mode 100644 tests_python/contracts_012/opcodes/hash_string.tz delete mode 100644 tests_python/contracts_012/opcodes/if.tz delete mode 100644 tests_python/contracts_012/opcodes/if_some.tz delete mode 100644 tests_python/contracts_012/opcodes/int.tz delete mode 100644 tests_python/contracts_012/opcodes/iter_fail.tz delete mode 100644 tests_python/contracts_012/opcodes/keccak.tz delete mode 100644 tests_python/contracts_012/opcodes/left_right.tz delete mode 100644 tests_python/contracts_012/opcodes/level.tz delete mode 100644 tests_python/contracts_012/opcodes/list_concat.tz delete mode 100644 tests_python/contracts_012/opcodes/list_concat_bytes.tz delete mode 100644 tests_python/contracts_012/opcodes/list_id.tz delete mode 100644 tests_python/contracts_012/opcodes/list_id_map.tz delete mode 100644 tests_python/contracts_012/opcodes/list_iter.tz delete mode 100644 tests_python/contracts_012/opcodes/list_map_block.tz delete mode 100644 tests_python/contracts_012/opcodes/list_size.tz delete mode 100644 tests_python/contracts_012/opcodes/loop_failwith.tz delete mode 100644 tests_python/contracts_012/opcodes/loop_left.tz delete mode 100644 tests_python/contracts_012/opcodes/loop_left_failwith.tz delete mode 100644 tests_python/contracts_012/opcodes/map_car.tz delete mode 100644 tests_python/contracts_012/opcodes/map_id.tz delete mode 100644 tests_python/contracts_012/opcodes/map_iter.tz delete mode 100644 tests_python/contracts_012/opcodes/map_map.tz delete mode 100644 tests_python/contracts_012/opcodes/map_map_sideeffect.tz delete mode 100644 tests_python/contracts_012/opcodes/map_mem_nat.tz delete mode 100644 tests_python/contracts_012/opcodes/map_mem_string.tz delete mode 100644 tests_python/contracts_012/opcodes/map_size.tz delete mode 100644 tests_python/contracts_012/opcodes/merge_comparable_pairs.tz delete mode 100644 tests_python/contracts_012/opcodes/mul.tz delete mode 100644 tests_python/contracts_012/opcodes/mul_bls12_381_fr.tz delete mode 100644 tests_python/contracts_012/opcodes/mul_bls12_381_g1.tz delete mode 100644 tests_python/contracts_012/opcodes/mul_bls12_381_g2.tz delete mode 100644 tests_python/contracts_012/opcodes/mul_overflow.tz delete mode 100644 tests_python/contracts_012/opcodes/munch.tz delete mode 100644 tests_python/contracts_012/opcodes/mutez_to_bls12_381_fr.tz delete mode 100644 tests_python/contracts_012/opcodes/neg.tz delete mode 100644 tests_python/contracts_012/opcodes/neg_bls12_381_fr.tz delete mode 100644 tests_python/contracts_012/opcodes/neg_bls12_381_g1.tz delete mode 100644 tests_python/contracts_012/opcodes/neg_bls12_381_g2.tz delete mode 100644 tests_python/contracts_012/opcodes/none.tz delete mode 100644 tests_python/contracts_012/opcodes/noop.tz delete mode 100644 tests_python/contracts_012/opcodes/not.tz delete mode 100644 tests_python/contracts_012/opcodes/not_binary.tz delete mode 100644 tests_python/contracts_012/opcodes/or.tz delete mode 100644 tests_python/contracts_012/opcodes/or_binary.tz delete mode 100644 tests_python/contracts_012/opcodes/originate_big_map.tz delete mode 100644 tests_python/contracts_012/opcodes/packunpack.tz delete mode 100644 tests_python/contracts_012/opcodes/packunpack_rev.tz delete mode 100644 tests_python/contracts_012/opcodes/packunpack_rev_cty.tz delete mode 100644 tests_python/contracts_012/opcodes/pair_id.tz delete mode 100644 tests_python/contracts_012/opcodes/pairing_check.tz delete mode 100644 tests_python/contracts_012/opcodes/pexec.tz delete mode 100644 tests_python/contracts_012/opcodes/pexec_2.tz delete mode 100644 tests_python/contracts_012/opcodes/proxy.tz delete mode 100644 tests_python/contracts_012/opcodes/ret_int.tz delete mode 100644 tests_python/contracts_012/opcodes/reverse.tz delete mode 100644 tests_python/contracts_012/opcodes/reverse_loop.tz delete mode 100644 tests_python/contracts_012/opcodes/sapling_empty_state.tz delete mode 100644 tests_python/contracts_012/opcodes/self.tz delete mode 100644 tests_python/contracts_012/opcodes/self_address.tz delete mode 100644 tests_python/contracts_012/opcodes/self_address_after_fib_view.tz delete mode 100644 tests_python/contracts_012/opcodes/self_address_after_nonexistent_view.tz delete mode 100644 tests_python/contracts_012/opcodes/self_address_after_view.tz delete mode 100644 tests_python/contracts_012/opcodes/self_after_fib_view.tz delete mode 100644 tests_python/contracts_012/opcodes/self_after_nonexistent_view.tz delete mode 100644 tests_python/contracts_012/opcodes/self_after_view.tz delete mode 100644 tests_python/contracts_012/opcodes/self_with_default_entrypoint.tz delete mode 100644 tests_python/contracts_012/opcodes/self_with_entrypoint.tz delete mode 100644 tests_python/contracts_012/opcodes/sender.tz delete mode 100644 tests_python/contracts_012/opcodes/sender_after_fib_view.tz delete mode 100644 tests_python/contracts_012/opcodes/sender_after_nonexistent_view.tz delete mode 100644 tests_python/contracts_012/opcodes/sender_after_view.tz delete mode 100644 tests_python/contracts_012/opcodes/set_car.tz delete mode 100644 tests_python/contracts_012/opcodes/set_cdr.tz delete mode 100644 tests_python/contracts_012/opcodes/set_delegate.tz delete mode 100644 tests_python/contracts_012/opcodes/set_id.tz delete mode 100644 tests_python/contracts_012/opcodes/set_iter.tz delete mode 100644 tests_python/contracts_012/opcodes/set_member.tz delete mode 100644 tests_python/contracts_012/opcodes/set_size.tz delete mode 100644 tests_python/contracts_012/opcodes/sets.tz delete mode 100644 tests_python/contracts_012/opcodes/sha3.tz delete mode 100644 tests_python/contracts_012/opcodes/shifts.tz delete mode 100644 tests_python/contracts_012/opcodes/slice.tz delete mode 100644 tests_python/contracts_012/opcodes/slice_bytes.tz delete mode 100644 tests_python/contracts_012/opcodes/slices.tz delete mode 100644 tests_python/contracts_012/opcodes/source.tz delete mode 100644 tests_python/contracts_012/opcodes/split_bytes.tz delete mode 100644 tests_python/contracts_012/opcodes/split_string.tz delete mode 100644 tests_python/contracts_012/opcodes/store_bls12_381_fr.tz delete mode 100644 tests_python/contracts_012/opcodes/store_bls12_381_g1.tz delete mode 100644 tests_python/contracts_012/opcodes/store_bls12_381_g2.tz delete mode 100644 tests_python/contracts_012/opcodes/store_input.tz delete mode 100644 tests_python/contracts_012/opcodes/store_now.tz delete mode 100644 tests_python/contracts_012/opcodes/str_id.tz delete mode 100644 tests_python/contracts_012/opcodes/sub_timestamp_delta.tz delete mode 100644 tests_python/contracts_012/opcodes/subset.tz delete mode 100644 tests_python/contracts_012/opcodes/tez_add_sub.tz delete mode 100644 tests_python/contracts_012/opcodes/ticket_bad.tz delete mode 100644 tests_python/contracts_012/opcodes/ticket_big_store.tz delete mode 100644 tests_python/contracts_012/opcodes/ticket_join.tz delete mode 100644 tests_python/contracts_012/opcodes/ticket_read.tz delete mode 100644 tests_python/contracts_012/opcodes/ticket_split.tz delete mode 100644 tests_python/contracts_012/opcodes/ticket_store-2.tz delete mode 100644 tests_python/contracts_012/opcodes/ticket_store.tz delete mode 100644 tests_python/contracts_012/opcodes/ticketer-2.tz delete mode 100644 tests_python/contracts_012/opcodes/ticketer.tz delete mode 100644 tests_python/contracts_012/opcodes/transfer_amount.tz delete mode 100644 tests_python/contracts_012/opcodes/transfer_tokens.tz delete mode 100644 tests_python/contracts_012/opcodes/uncomb.tz delete mode 100644 tests_python/contracts_012/opcodes/unpair.tz delete mode 100644 tests_python/contracts_012/opcodes/update_big_map.tz delete mode 100644 tests_python/contracts_012/opcodes/utxo_read.tz delete mode 100644 tests_python/contracts_012/opcodes/utxor.tz delete mode 100644 tests_python/contracts_012/opcodes/view_fib.tz delete mode 100644 tests_python/contracts_012/opcodes/view_mutual_recursion.tz delete mode 100644 tests_python/contracts_012/opcodes/view_op_add.tz delete mode 100644 tests_python/contracts_012/opcodes/view_op_constant.tz delete mode 100644 tests_python/contracts_012/opcodes/view_op_id.tz delete mode 100644 tests_python/contracts_012/opcodes/view_op_nonexistent_addr.tz delete mode 100644 tests_python/contracts_012/opcodes/view_op_nonexistent_func.tz delete mode 100644 tests_python/contracts_012/opcodes/view_op_test_step_contants.tz delete mode 100644 tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_input_type.tz delete mode 100644 tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_output_type.tz delete mode 100644 tests_python/contracts_012/opcodes/view_rec.tz delete mode 100644 tests_python/contracts_012/opcodes/view_toplevel_lib.tz delete mode 100644 tests_python/contracts_012/opcodes/voting_power.tz delete mode 100644 tests_python/contracts_012/opcodes/xor.tz delete mode 100644 tests_python/tests_012/__init__.py delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_legacy_flag.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[None].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized_legacy].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Readable].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool bytes)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list nat].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[nat].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool bytes].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[None].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized_legacy].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Readable].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fac.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fib.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_mutual_recursion.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_add.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_id.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_addr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_func.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_test_step_contants.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_input_type.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_output_type.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_rec.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_toplevel_lib.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_receiver.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_sender.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_send_self_address.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--accounts.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1_list.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--after_strategy.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--always.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--append.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--at_least.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--auction.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--bad_lockup.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--big_map_union.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cadr_annotation.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--concat.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--conditionals.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cons_twice.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cps_fact.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--create_add1_lists.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--data_publisher.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--dispatch.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--empty.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--fail_amount.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--faucet.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--forward.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--id.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--infinite_loop.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--insertion_sort.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--int_publisher.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--king_of_tez.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--list_of_transactions.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--queue.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reduce_map.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reentrancy.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reservoir.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--scrutable_reservoir.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--spawn_identities.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpeq.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpge.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpgt.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmple.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmplt.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpneq.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_eq.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_ge.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_gt.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_le.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_lt.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_neq.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_get_add.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_mem.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--build_list.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--carn_and_cdrn.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare_bytes.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--fail.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--guestbook.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--macro_annotations.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--map_caddaadr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--max_in_list.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--min.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--pair_macro.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--set_caddaadr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--take_my_money.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--unpair_macro.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--authentication.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_entrypoints.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_magic.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_read.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_store.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_write.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract_simple.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--default_account.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_appender.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_caller.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_storer.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--fa12_reference.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--generic_multisig.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--groth16.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--hardlimit.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--legacy_multisig.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lockup.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lqt_fa12.mligo.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_en2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_entrypoints_counter.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--parameterized_multisig.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--replay.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--reveal_signed_preimage.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_receiver.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_sender.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_fungible.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_non_fungible.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_fungible.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_non_fungible.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--tzip4_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--vote_for_delegate.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--weather_insurance.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat_dapp.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--bug_262.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--pairk_annot.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--abs.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_fr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g1.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_delta_timestamp.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_timestamp_delta.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--address.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_fib_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_nonexistent_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_binary.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_logical_1.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_fib_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_nonexistent_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_nat.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_string.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_to_self.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_bytes_not_padded.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_nat.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_int.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_mutez.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_int.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_nat.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_int.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_nat.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bytes.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--car.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cdr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id_store.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--check_signature.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-get.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-literals.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set-2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comparisons.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello_bytes.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_list.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cons.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contains_all.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contract.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname_alt.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_with_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--diff_timestamps.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dig_eq.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dign.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dip.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dipn.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dropn.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dugn.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dup-n.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv_mutez.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--empty_map.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--exec_concat.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--first.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_big_map.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_map.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_big_map_value.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_map_value.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_consistency_checker.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_key.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_string.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if_some.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--int.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--iter_fail.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--keccak.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--left_right.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--level.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat_bytes.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id_map.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_iter.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_map_block.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_size.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_failwith.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left_failwith.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_car.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_id.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_iter.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map_sideeffect.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_nat.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_string.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_size.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--merge_comparable_pairs.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_fr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g1.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_overflow.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--munch.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mutez_to_bls12_381_fr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_fr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g1.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--none.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--noop.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not_binary.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or_binary.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--originate_big_map.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev_cty.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pair_id.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pairing_check.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec_2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--proxy.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ret_int.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse_loop.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sapling_empty_state.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_fib_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_nonexistent_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_fib_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_nonexistent_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_default_entrypoint.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_entrypoint.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_fib_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_nonexistent_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_view.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_car.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_cdr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_delegate.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_id.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_iter.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_member.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_size.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sets.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sha3.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--shifts.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice_bytes.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slices.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--source.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_bytes.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_string.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_fr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g1.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_input.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_now.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--str_id.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sub_timestamp_delta.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--subset.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--tez_add_sub.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_bad.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_big_store.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_join.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_read.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_split.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store-2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer-2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_amount.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_tokens.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--uncomb.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--unpair.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--update_big_map.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxo_read.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxor.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_fib.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_mutual_recursion.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_add.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_constant.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_id.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_addr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_func.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_test_step_contants.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_input_type.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_output_type.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_rec.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_toplevel_lib.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--voting_power.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--xor.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_groth16.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g1.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g2.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_nil.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_one.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_random.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_zero.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_one.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_random.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_zero.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_one.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_random.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_zero.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_signature_aggregation.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[Fr].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpeq.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpge.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpgt.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmple.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmplt.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpneq.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_eq.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_ge.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_gt.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_le.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_lt.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_neq.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_get_add.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_mem.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--build_list.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--carn_and_cdrn.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare_bytes.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--fail.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--guestbook.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--macro_annotations.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--map_caddaadr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--max_in_list.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--min.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--pair_macro.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--set_caddaadr.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--take_my_money.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--unpair_macro.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_diff.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_id.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_literal.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_diff.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_id.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainLevel::test_level.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_contract_fails.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_gen_keys.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_init_proxy.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_now.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_self.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_sender.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_set_delegate.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice.out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 \"spsig1PPUFZucuAQybs5wsqs.818025e860.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.2d6806d54e.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.378d03ae2d.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.57fdc7ad1c.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75.c583c796bf.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_source.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_bytes.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_string.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_amount.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_tokens.out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0427752f13.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0793dc66d5.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .df114499b8.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .f9bea98de9.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"hello\" 4 })-.1db12cd837.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-\"hello\"-(Pair N.6fc7d0acf2.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"tw.524c5459f8.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"\".33eba403e7.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"h.a5cd1005c9.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .6f3d35b151.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .76aeaa0706.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7e7197f248.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .b688cc94a7.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .c68db221ed.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0.5].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1000].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1e-06].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[5].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[8000000000000.0].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }) )-(Right (Righ.7492e8cdea.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Left Unit)-(.21b30dd90f.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .2873ef610c.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .8a6f480005.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Right.d336ca1903.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair \"foo\" \"bar\" } { P.7f2ee47600.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_check_signature.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000.3c2de60480.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000.12b2c1172b.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x010.0e44fc6f40.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0.7e0ed229a3.out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some \"1970.7c1b1e4e5b.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 \"1970-01-01T00:00:0.528ed42c01.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some \"1970-.6566111ad2.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair \"1970-01-01T00:00:00Z.72c424f3da.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some \"1970.7c4b12e9aa.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some \"1970-.af32743640.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[address.tz-None-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.73700321f8.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.1182eca937.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.1eead33885.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\".968709d39d.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair 4 (Some False))].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x100000000000.d1219ca789.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f2.7a85c336ff.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986.b821eb26b3.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0accef5bef.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0ecc537252.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2229b767cd.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2ff549b46b.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.bf8a711be6.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.d41cbb044b.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.a50412e458.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.f3a349c4a7.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.1b9676e4c2.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.e966dc6de5.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.964835cc43.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.b25ea709fb.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.eae36753ea.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.ee57dac8f7.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.bd5800f6b8.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.00e897789a.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.a4697eaa13.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.0177355bbf.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.744166c609.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.9f3c5cdc6a.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.a54cb341ba.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.b0dc584c94.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.bddcad090c.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.92c153eb47.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.290ab49d11.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.69f3589a06.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.fee3c5cf43.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.1bccc033e8.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.40958700fe.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.6c62b03d78.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.d23f269341.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.927f808504.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.0c114c956a.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.03c4f38e68.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.8ed19cfdd9.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some \"NetXdQprcVkpaWU\")-Unit-(Some \".8420090f97.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some \"NetXdQprcVkpaWU\")].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"World!\" }-{ \"Hello World!\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"test1\" ; \"test2\" }-{ \"Hello test1.c27e8c3ee6.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"Hello\" ; \" \" ; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{}-\"\"].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"A\" } { \"B\" })-(Some False)].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" } { \"B\" })-(Some True)].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"c\" } { \"B\" })-(Some False)].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contract.tz-Unit-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair \"1970-01-01T00:03:20Z\" \"19.90e9215d17.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (.3caea50555.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair No.f9448c04fb.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (So.f782cc1dec.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Som.016b4db96c.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (.e705a30e07.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (S.44485eda6a.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (S.8ab987af15.out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt \"hello\" \"world\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"test\"-\"test_abc\"].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-\"hello\"-(Pair .161d86cef6.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).684ab7e326.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).d49817fb83.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .6900b1da14.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .bca0ede8be.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-\"hello\"-(Pair None {})].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"1\" \"one\" ; .bc4127094e.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"\"-(P.0c03056487.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"hell.cc45544c66.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"12345\"-0xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"abcdefg\"-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-(Some \"hello\")-\"hello\"].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-None-\"\"].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e.34c02678c9.out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Left True)-(Right True)].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Right \"a\")-(Left \"a\")].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{}-\"abc\"].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{}-{}].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{}-{}].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{}-{}].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"bar\" 5 ; Elt \"foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 .7396e5f090.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair {} (Some False))].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 }-1].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000.be11332c7f.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x10000000000000000000.8230fb4fac.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".368bdfd73a.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".735d9ae802.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.4e20b52378.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{}-{}].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{}-{}].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"world\"-(Pair \"world\" 0)].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 0)-1-(Pair \"hello\" 1)].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 500)-3-(Pair \"hello\" 3)].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 7)-100-(Pair \"hello\" 100)].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"asdf\" ; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hello\" ; \"World\" } None)-\"\"-(Pai.3d2044726e.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hi\" } None)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-\"Hi\"-(Pair {} (Some False))].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a.a07ae9dddf.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 10-None].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 3-None].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 10 5-None].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some\"FooFooFooFooFooFooFooFooFooFooFooFooFooFo.c508d67bb0.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaab.df5895de85.out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"Hello\"-(Some \"Hello\")].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"abcd\"-(Some \"abcd\")].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-\"1970-01-01T00:03:20Z\"].out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-\"1970-01-01T00:00:00Z\"].out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 200000000000000000.3db82d2c25.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair .b461aa042b.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair .1e8cf7679c.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit].out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-\"edpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_hash_consistency_michelson_cli.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_level.out delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" delete mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_now.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_packunpack.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_add_liquidity.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approval.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approved_transfer.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve1.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve2.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve3.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_mint_or_burn.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_dex_storage.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_lqt_storage.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_setup.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_tok_storage.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_add_liquidity.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve1.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve2.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve3.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_mint_or_burn.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_dex_storage.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_lqt_storage.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_setup.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_tok_storage.out delete mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_transfer.out delete mode 100644 tests_python/tests_012/conftest.py delete mode 100644 tests_python/tests_012/contract_paths.py delete mode 100644 tests_python/tests_012/per_block_vote_files/false.json delete mode 100644 tests_python/tests_012/per_block_vote_files/invalid.json delete mode 100644 tests_python/tests_012/per_block_vote_files/non_boolean.json delete mode 100644 tests_python/tests_012/per_block_vote_files/true.json delete mode 100644 tests_python/tests_012/per_block_vote_files/wrong_key.json delete mode 100644 tests_python/tests_012/protocol.py delete mode 100644 tests_python/tests_012/test_accuser.py delete mode 100644 tests_python/tests_012/test_baker_endorser.py delete mode 100644 tests_python/tests_012/test_basic.py delete mode 100644 tests_python/tests_012/test_binaries.py delete mode 100644 tests_python/tests_012/test_bootstrap.py delete mode 100644 tests_python/tests_012/test_client.py delete mode 100644 tests_python/tests_012/test_client_without_node.py delete mode 100644 tests_python/tests_012/test_codec.py delete mode 100644 tests_python/tests_012/test_contract.py delete mode 100644 tests_python/tests_012/test_contract_annotations.py delete mode 100644 tests_python/tests_012/test_contract_baker.py delete mode 100644 tests_python/tests_012/test_contract_bls12_381.py delete mode 100644 tests_python/tests_012/test_contract_macros.py delete mode 100644 tests_python/tests_012/test_contract_onchain_opcodes.py delete mode 100644 tests_python/tests_012/test_contract_opcodes.py delete mode 100644 tests_python/tests_012/test_cors.py delete mode 100644 tests_python/tests_012/test_crypto.py delete mode 100644 tests_python/tests_012/test_fa12.py delete mode 100755 tests_python/tests_012/test_forge_block.py delete mode 100644 tests_python/tests_012/test_fork.py delete mode 100644 tests_python/tests_012/test_injection.py delete mode 100644 tests_python/tests_012/test_liquidity_baking.py delete mode 100644 tests_python/tests_012/test_many_bakers.py delete mode 100644 tests_python/tests_012/test_many_nodes.py delete mode 100644 tests_python/tests_012/test_mempool.py delete mode 100644 tests_python/tests_012/test_migration.py delete mode 100644 tests_python/tests_012/test_mockup.py delete mode 100644 tests_python/tests_012/test_multinode_snapshot.py delete mode 100644 tests_python/tests_012/test_multinode_storage_reconstruction.py delete mode 100644 tests_python/tests_012/test_multiple_transfers.py delete mode 100644 tests_python/tests_012/test_multisig.py delete mode 100644 tests_python/tests_012/test_nonce_seed_revelation.py delete mode 100644 tests_python/tests_012/test_openapi.py delete mode 100644 tests_python/tests_012/test_p2p.py delete mode 100644 tests_python/tests_012/test_per_block_votes.py delete mode 100644 tests_python/tests_012/test_programs.py delete mode 100644 tests_python/tests_012/test_proto_demo_counter.py delete mode 100644 tests_python/tests_012/test_proto_demo_noops_manual_bake.py delete mode 100644 tests_python/tests_012/test_rpc.py delete mode 100644 tests_python/tests_012/test_sapling.py delete mode 100644 tests_python/tests_012/test_slice_fails_params.txt delete mode 100644 tests_python/tests_012/test_slice_success_params.txt delete mode 100644 tests_python/tests_012/test_tenderbake.py delete mode 100644 tests_python/tests_012/test_tenderbake_bakers_restart.py delete mode 100644 tests_python/tests_012/test_tenderbake_incremental_start.py delete mode 100644 tests_python/tests_012/test_tenderbake_long_dynamic_bake.py delete mode 100644 tests_python/tests_012/test_tenderbake_manual_bake.py delete mode 100755 tests_python/tests_012/test_tls.py delete mode 100644 tests_python/tests_012/test_voting.py delete mode 100644 tests_python/tests_012/test_voting_full.py diff --git a/docs/012/cli-commands.rst b/docs/012/cli-commands.rst deleted file mode 100644 index 695a9d3f3d19..000000000000 --- a/docs/012/cli-commands.rst +++ /dev/null @@ -1,41 +0,0 @@ -********************** -Command Line Interface -********************** - -This document is a prettier output of the documentation produced by -the command ``man`` of the different Tezos binaries. You can obtain similar pages -using shell commands such as (:ref:`indicating the appropriate protocol `): - -:: - - tezos-client -protocol man -verbosity 3 - -The rest of this page documents the protocol-dependent tools. -The protocol-independent tools are documented :doc:`here <../shell/cli-commands>`. - - -.. _client_manual_012: - -Client manual -============= - -.. raw:: html - :file: tezos-client.html - - -.. _baker_manual_012: - -Baker manual -============ - -.. raw:: html - :file: tezos-baker.html - - -.. _accuser_manual_012: - -Accuser manual -============== - -.. raw:: html - :file: tezos-accuser.html diff --git a/docs/012/consensus.rst b/docs/012/consensus.rst deleted file mode 100644 index bbc3972283dd..000000000000 --- a/docs/012/consensus.rst +++ /dev/null @@ -1,453 +0,0 @@ -The consensus algorithm -======================= - -This document provides a high-level description of Tenderbake, the Tezos -:doc:`proof-of-stake` consensus algorithm, as implemented in the -I protocol. - -History -------- - -Before Tenderbake, there was -`Emmy* `_, -a Nakamoto-style consensus consisting of a series of improvements of the one in -the `Tezos whitepaper `_. - -Emmy*, like any Nakamoto-style consensus algorithm (such as `Bitcoin -`_ or `Ouroboros -`_), offers *probabilistic* -finality: forks of arbitrary length are possible but they collapse -with a probability that increases rapidly with fork length. - -`Tenderbake `_ instead, like any classic -BFT-style consensus algorithm (such as -`PBFT `_ or -`Tendermint `_), offers *deterministic* -finality: a block that has just been appended to the chain of some node is known -to be final once it has two additional blocks on top of it, regardless of -network latency. - - -Overview --------- - -The starting point for Tenderbake is -`Tendermint `_, the first classic-style algorithm -for blockchains. - -Tenderbake adapts Tendermint to the Tezos blockchain, but the adjustments -required are -`substantive `_: - -* Tenderbake is tailored to match the Tezos architecture by using only - communication primitives and network assumptions which Tezos supports. -* Tenderbake makes weaker network assumptions than Tendermint, at the price of - adding the extra assumption that participants have loosely synchronized clocks - — which is fine, because Tezos already uses them. - -The design of Tenderbake and its rationale are described at -length in the `technical report `_ and in a -`Nomadic Labs's blog -post `_. Here we -only provide a user/developer perspective. -Tenderbake is executed for each new block level by a "committee" whose members -are called *validators*, which are delegates selected at random based on their -stake, in the same way as endorsers are selected in Emmy*. We let -``CONSENSUS_COMMITTEE_SIZE`` be the number of validator slots per level. This -constant has the role of ``ENDORSERS_PER_BLOCK`` in Emmy*. - -For each level, Tenderbake proceeds in rounds. Each *round* represents an -attempt by the validators to agree on the content of the block for the current -level, that is, on the sequence of non-consensus operations the block contains. -We call this sequence the block's *payload*. - -Each round has an associated duration. Round durations are set to increase so -that for any possible message delay, there is a round that is sufficiently long -for all required messages to be exchanged. -Round durations depend on protocol parameters ``MINIMAL_BLOCK_DELAY`` and ``DELAY_INCREMENT_PER_ROUND``. -These parameters specify round durations as follows: - -.. math:: - - round\_duration(0) &= minimal\_block\_delay \\ - round\_duration(r+1) &= round\_duration(r) + delay\_increment\_per\_round \\ - & = minimal\_block\_delay + (r + 1) * delay\_increment\_per\_round - -Round durations thus increase linearly with ``DELAY_INCREMENT_PER_ROUND``. - -Schematically, a round consists in the following steps: - -* a validator designated for that round injects a *candidate block* (representing a proposal) and consensus operations (representing votes) into the node to which it is attached, which then -* diffuses those blocks and consensus operations to other nodes of the network, and thus -* communicates them to the validators attached to those nodes, to carry out voting on which block to accept. - -Unlike Emmy*, Tenderbake has `two types of -votes `_: -before endorsing a block ``b``, a validator preendorses ``b``. Furthermore, -to be able to endorse, a validator must have observed a preendorsement *quorum*, that is a -set of preendorsements from validators having at least :math:`\lceil CONSENSUS\_COMMITTEE\_SIZE \times \frac{2}{3} \rceil` validator slots. Similarly, to be able to decide, a validator must have observed an endorsement quorum, that is, a set of endorsements from validators having at least :math:`\lceil CONSENSUS\_COMMITTEE\_SIZE \times \frac{2}{3} \rceil` validator slots. The -endorsement quorum for a block ``b`` is included in a block ``b'`` on top of ``b``, -serving as a certification that ``b`` has been agreed upon. -We also say that block ``b'`` confirms block ``b``. - -The validator's whose turn is to inject a candidate block at a given round is -called the *proposer* at that round. Proposers in Tenderbake are selected -similarly to bakers in Emmy*: the proposer at round ``r`` is the -validator who has the validator slot ``r``. A proposer who has observed a -preendorsement quorum for a candidate block in a previous round, is required to propose a block with -the same *payload* as -the initial block. We talk about a *re-proposal* in this case. - - -.. _finality_012: - -Transaction and block finality -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A transaction is final as soon as the block including it has a confirmation (that is, a block on top of it). -Indeed, as hinted above, a block contains the certification (that is, the endorsement quorum) for the previous -payload. Thanks to the endorsement quorum, Tenderbake guarantees **transaction finality -after 1 confirmation**. - -It may be possible that different validators decide at different rounds, though on the same payload. The blocks at these different rounds differ precisely because they contain, in the header, as part of the block fitness, -the round at which they were proposed. -Among these "candidate" blocks, the block with the smallest round has the highest fitness and so it will be the one decided. -Consequently, to agree on a block, that is, on both the payload and the header, Tenderbake needs one more -confirmation, and thus guarantees -**block finality after 2 confirmations**. - -Time between blocks -~~~~~~~~~~~~~~~~~~~~~~~ - -The time between blocks represents the difference between the timestamps of the blocks. The timestamp of a block is given by the beginning of the round at which the block has been agreed upon. Thus, the time between blocks depends on the round at which decisions are taken. For -example, if the decision at the previous level was taken at round 4 and at the current level at round 2, then the current block's delay relative to -its predecessor, is :math:`round\_duration(4) + round\_duration(0) + round\_duration(1)`. -The general case is as follows, say that the decision at the previous -level is taken at round ``m`` and the decision at the current level is -taken at round ``n``, then the current block's delay relative to its -predecessor is :math:`round\_duration(m) + \sum_{i=0}^{n-1} round\_duration(i)`. -We note that, under -normal network conditions, and with active and compliant validators, decisions -should be taken at round 0, meaning that the time between blocks would be -:math:`round\_duration(0)` seconds i.e., parameter ``MINIMAL_BLOCK_DELAY``. - - -Validator selection: staking balance, active stake, and frozen deposits -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Validator selection is based on the stake, as in Emmy*, with the exception that -it is based on the delegate's *active stake* instead of its *staking -balance* (or rather the corresponding rolls. -**NB**: rolls do not play a -role anymore, except for establishing a minimum required staking -balance). Let us first (re)define these and related concepts. - -- The *(maximal) staking balance* of a delegate is its full balance (i.e. all the tokens owned by the delegate) plus the - balances of all accounts that have delegated to it. -- The *active stake* of a delegate is the amount of tez with which - it participates in consensus. It is at most its - staking balance. It must be at least ``TOKEN_PER_ROLL`` tez. We explain below how it is computed. -- The *frozen deposit* represents a percentage ``FROZEN_DEPOSIT_PERCENTAGE`` - of the maximum active stake during the last ``PRESERVED_CYCLES + MAX_SLASHING_PERIOD``. This amount - represents the delegate's skin in the game: in the case that the - delegate behaves badly, its frozen deposit is partly slashed (see - :ref:`slashing_012`). Taking the maximum over an - interval of cycles (instead of just considering the active stake at - the cycle where the bad action can occur) allows to avoid situations - where a malicious delegate empties its accounts between the time when - rights are attributed and the time when the deposit is frozen. The frozen deposits are updated at the end of each cycle. -- The *spendable balance* of a delegate is its full balance - minus the frozen deposits. - -We state next the RPCs which allow to retrieve these types of balances, and also some invariants about them -(Note that these are just invariants, not definitions; for -instance, the frozen deposits are computed in terms of the full balance, -not the other way around.): - -- ``delegated balance`` represents the total amount of tokens delegated by others to a - given delegate; it excludes the delegate's full balance; it is obtained - with ``../context/delegates//delegated_balance`` -- ``staking balance = full balance + delegated balance``; it is obtained with - ``../context/delegates//staking_balance`` -- ``full balance = spendable balance + frozen deposit``; it is obtained with - ``../context/delegates//full_balance`` -- ``frozen deposit`` is obtained with ``../context/delegates//frozen_deposits`` -- ``spendable balance`` is obtained with ``../context/contracts//balance`` - -Delegates can set an upper limit to their frozen deposits with the -commands ``tezos-client set deposit limit for to -``, and unset this limit with the command ``tezos-client -unset deposit limit for ``. These commands are implemented by -using a new manager operation ``Set_deposits_limit``. When emitting such a -command in cycle ``c``, it affects the active stake for cycles starting -with ``c + PRESERVED_CYCLES + 1``; the new active stake is -taken into account when computing the frozen deposit for cycle ``c+1`` -already, however the user may see an update to its frozen deposit at -cycle ``c + PRESERVED_CYCLES + MAX_SLASHING_PERIOD`` at the -latest (because up to that cycle the frozen deposit also depends on the -active stake at cycles before cycle ``c+1``). - -The active stake is computed ``PRESERVED_CYCLES`` in advance: at -the end of cycle ``c`` for cycle ``c + PRESERVED_CYCLES`` (as in Emmy*). Intuitively, -the active stake is set to 10 times the delegate's chosen frozen -deposit limit, without going beyond its available staking balance, -nor its maximum staking capacity (determined by its full balance). -More precisely, the active stake is the minimum between: - -- the delegate's staking balance, and -- 10 times the delegate's *deposit cap*, i.e. ``deposit_cap * 100 / deposit_percentage``. If the delegate has not set a frozen deposit limit, ``deposit_cap`` is its full balance. Otherwise ``deposit_cap`` is the minimum between its full balance and the frozen deposit limit set by the delegate. - -Let's take some examples. Say that the full balance of a delegate is ``1000`` tez. -Then its theoretical maximum staking balance is -``10000`` tez. The following table lists some scenarios (assuming for -simplicity no changes in the delegate's full and staking balances -during the last 8 cycles). - -.. list-table:: - :widths: 20 20 20 20 20 - :header-rows: 1 - - * - Staking balance - - Frozen deposit limit - - Active stake - - Frozen deposit - - Spendable balance - * - 9000 - - -- - - 9000 - - 900 - - 100 - * - 12000 - - -- - - 10000 - - 1000 - - 0 - * - 9000 - - 400 - - 4000 - - 400 - - 600 - * - 12000 - - 400 - - 4000 - - 400 - - 600 - -We note in passing that this new schema basically solves the main -problem of over-delegation: a delegate will not fail anymore to bake -and endorse because of an insufficient balance to pay the -deposit. However, a delegate can still be over-delegated, and it will be -rewarded based on its active stake, not on its staking balance. - -Economic Incentives -~~~~~~~~~~~~~~~~~~~ - -As Emmy*, Tenderbake rewards participation in consensus and punishes bad -behavior. Notable changes however are as follows: - -* Fees and baking rewards go to the payload producer, the one who selected the - transactions to be included in the block (and was the first to propose a - block with that payload). In case of re-proposal, the payload producer might - be different from the block proposer, the baker who injects the block. -* Including extra endorsements, that is, more than the minimal required to - obtain a quorum, is rewarded with a bonus. -* Endorsing rewards are shared equally among all validators. Participation above - a minimal threshold per cycle is however required. -* Deposits are no longer frozen and unfrozen, instead a percentage of the active stake is always locked. -* Validators are rewarded instantaneously for baking blocks and including extra endorsements, and not at the end of the cycle like in Emmy*. -* At the end of a cycle ``c``, the following actions happen: - - - the selection of the consensus committee cycle ``c + PRESERVED_CYCLES``, based on the current active stake distribution, - - the distribution of endorsing rewards, - - the adjustment of frozen deposits. - - -Fees -^^^^ - -The fees associated to the transactions included in a block go to the payload -producer. This is only natural given that this is the validator that selects the -transactions to be included; see `an in-depth blog -post `_ for further motivation. - -The payload producer is usually the same delegate as the block -proposer (that is, the one that signs and injects the block): that's -always true for blocks at round 0; however, in case of re-proposals -this is not necessarily the case (see the algorithm description above). - -Fees are given to the payload producer immediately, that is, they are -already reflected in the blockchain state obtained after applying the injected -block. - -Rewards -^^^^^^^ - -There are three kinds of rewards: baking rewards, endorsing rewards, and a bonus for including extra endorsements. - -The baking rewards are treated in the same way as fees: they go to the *payload* -producer and are distributed immediately. - -To encourage fairness and participation, the *block* proposer receives -a bonus for the extra endorsements it includes in the block. -The bonus is proportional to the number of -validator slots above the threshold of :math:`\lceil CONSENSUS\_COMMITTEE\_SIZE \times \frac{2}{3} \rceil` that -the included endorsements represent. The bonus is also distributed -immediately. - -The endorsing rewards are shared among all validators, proportionally -to their *expected* number of validator slots. The endorsing reward -may be received even if the validator's endorsement is not included in -a block. However, two conditions must be met: - - - the validator has revealed its nonce, and - - the validator has been present during the cycle. - -Not giving rewards in case of missing revelations is not new as it is :ref:`adapted` -from Emmy*. -The second condition is new. We say that a delegate is *present* during a cycle -if the endorsing power (that is, the number of validator slots at the -corresponding level) of all the endorsements included by the delegate during the -cycle represents at least ``MINIMAL_PARTICIPATION_RATIO`` of the delegate's expected number of -validator slots for the current cycle (which is ``BLOCKS_PER_CYCLE * -CONSENSUS_COMMITTEE_SIZE * active_stake / total_active_stake``). -The endorsing rewards are distributed at the end of the cycle. - -Regarding the concrete values for rewards, we first fix the total reward per -level, call it ``total_rewards``, to ``80 / blocks_per_minute`` tez. -Assuming ``blocks_per_minute = 2``, ``total_rewards`` is 40 tez. -We define: - -- ``BAKING_REWARD_FIXED_PORTION := baking_reward_ratio * total_rewards`` -- ``bonus := (1 - baking_reward_ratio) * bonus_ratio * total_rewards`` is the max bonus -- ``endorsing_reward := (1 - baking_reward_ratio) * (1 - bonus_ratio) * total_rewards`` - -where: - -- ``baking_reward_ratio`` to ``1 / 4``, -- ``bonus_ratio`` to ``1 / 3``. - -Thus, we obtain ``BAKING_REWARD_FIXED_PORTION = 10`` tez, -(maximum) ``bonus = 10`` tez, and ``endorsing_rewards = 20`` tez. -The bonus per additional endorsement slot is in turn ``bonus / -(CONSENSUS_COMMITTEE_SIZE / 3)`` (because there are at most -``CONSENSUS_COMMITTEE_SIZE / 3`` validator slots corresponding to the -additional endorsements included in a block). The rewards per -endorsement slot are ``endorsing_rewards / CONSENSUS_COMMITTEE_SIZE``. -Assuming ``CONSENSUS_COMMITTEE_SIZE = 8000``, we obtain a bonus per slot of -``10 / (8000 / 3) = 0.00375`` tez and an endorsing -rewards per slot of ``20 / 8000 = 0.0025`` tez. - -Let's take an example. Say a block has round 1, is proposed by -delegate B, and contains the payload from round 0 produced by delegate -A. Also, B includes endorsements with endorsing power ``6000``. Then A receives -the fees and 10 tez (the ``BAKING_REWARD_FIXED_PORTION``) as a reward for -producing the block's payload. For simpler calculations, let's assume -``CONSENSUS_COMMITTEE_SIZE = 8000``. Concerning the bonus, the minimum required validator slots is ``5334``, and there are ``2666 = 8000 - 5334`` additional validator slots. -Therefore B receives the bonus ``(6000 - 5334) * 0.00375 = 2.4975`` tez. (Note -that B only included endorsements corresponding to 666 additional validator slots, about a quarter of the -maximum 2666 extra endorsements it could have theoretically included.) Finally, consider some -delegate C, whose active stake at some cycle is 5% of the total stake. Note that -his expected number of validator slots for that cycle is ``5/100 * 8192 * 8000 = -3,276,800`` slots. Assume also that the endorsing power of C's endorsements -included during that cycle has been ``3,123,456`` slots. Given that this number is -bigger than the minimum required (``3,276,800 * 2 / 3``), it receives an endorsing -reward of ``3,276,800 * 0.0025 = 8192`` tez for that cycle. - -.. _slashing_012: - -Slashing -^^^^^^^^ - -Like in Emmy*, not revealing nonces and double signing are punishable. If a -validator does not reveal its nonce by the end of the cycle, it does not receive -its endorsing rewards. If a validator double signs, that is, it double bakes or -it double (pre)endorses (which means voting on two different proposals at the -same round), the frozen deposit is slashed. The slashed amount for double baking -is ``DOUBLE_BAKING_PUNISHMENT``. The slashed amount for double (pre)endorsing is -a fixed percentage ``RATIO_OF_FROZEN_DEPOSITS_SLASHED_PER_DOUBLE_ENDORSEMENT`` -of the frozen deposit. The payload producer that includes the misbehavior -evidence is rewarded half of the slashed amount. - -The evidence for double signing at a given level can be collected by any -:ref:`accuser` and included as an *accusation* operation in a block -for a period of ``MAX_SLASHING_PERIOD``. - -We note that selfish baking is not an issue in Tenderbake: say we are at round -``r`` and the validator which is proposer at round ``r+1`` does not (pre)endorse -at round ``r`` in the hope that the block at round ``r`` is not agreed upon and -its turn comes to propose at round ``r+1``. Under the assumption that the -correct validators have more than two thirds of the total stake, these correct -validators have sufficient power for agreement to be reached, thus the lack of -participation of a selfish baker does not have an impact. - -.. _cs_constants_012: - -Consensus related protocol parameters -------------------------------------- - -.. list-table:: - :widths: 55 25 - :header-rows: 1 - - * - Parameter name - - Parameter value - * - ``CONSENSUS_COMMITTEE_SIZE`` - - 7000 - * - ``CONSENSUS_THRESHOLD`` - - ``ceil(2 * CONSENSUS_COMMITTEE_SIZE / 3)`` - * - ``MINIMAL_BLOCK_DELAY`` - - 30s - * - ``DELAY_INCREMENT_PER_ROUND`` - - 15s - * - ``MINIMAL_PARTICIPATION_RATIO`` - - 2/3 - * - ``FROZEN_DEPOSITS_PERCENTAGE`` - - 10 - * - ``MAX_SLASHING_PERIOD`` - - 2 cycles - * - ``DOUBLE_BAKING_PUNISHMENT`` - - 640 tez - * - ``RATIO_OF_FROZEN_DEPOSITS_SLASHED_PER_DOUBLE_ENDORSEMENT`` - - 1/2 - * - ``BAKING_REWARD_FIXED_PORTION`` - - 10 tez - * - ``BAKING_REWARD_BONUS_PER_SLOT`` - - ``bonus / (CONSENSUS_COMMITTEE_SIZE / 3)`` = 0.004286 tez - * - ``ENDORSING_REWARD_PER_SLOT`` - - ``endorsing_reward / CONSENSUS_COMMITTEE_SIZE`` = 0.002857 tez - - -.. _shell_proto_revisit_012: - -Shell-protocol interaction revisited ------------------------------------- - -:ref:`Recall` that, for the shell to interact with the economic protocol, two notions are defined abstractly at the level of the shell and made concrete at the level of the consensus protocol. -Namely, these two notions are the protocol-specific header and the fitness. -As in Emmy*, the protocol-specific header contains the fields: - -- ``signature``: a digital signature of the shell and protocol headers (excluding the signature itself) -- ``seed_nonce_hash``: a commitment to :ref:`a random number`, used to generate entropy on the chain -- ``proof_of_work_nonce``: a nonce used to pass a low-difficulty proof-of-work for the block, as a spam prevention measure -- ``liquidity_baking_escape_vote``: :ref:`a flag` that requests ending the subsidy. - -There are two additional fields: ``payload_hash`` and ``payload_round`` which are needed for establishing if a block is :ref:`final`. - -.. _fitness_012: - -The fitness is given by the tuple ``(level, locked_round, predecessor_round, round)``. -The fitness encapsulates more information than in Emmy* because Tenderbake is more complex: recall that blocks at the last level only represent :ref:`candidate blocks`. -In Emmy*, only the level mattered. -But in Tenderbake, we need to, for instance, allow for new blocks at the same level to be accepted by nodes. -Therefore the fitness also includes the block's round. -Furthermore, we also allow to change the predecessor block when it has a :ref:`smaller round`. -Therefore the fitness also includes the predecessor block's round. - - - -Further External Resources --------------------------- - -* Tenderbake `report `_ -* Tenderbake `blog post `_. -* Tenderbake `tzip `_. diff --git a/docs/012/global_constants.rst b/docs/012/global_constants.rst deleted file mode 100644 index 9b8286f906b5..000000000000 --- a/docs/012/global_constants.rst +++ /dev/null @@ -1,141 +0,0 @@ -Global Constants -================ - -The size limit for :doc:`Michelson ` contracts is quite small, limited to 60 -kilobytes as of Granada protocol. Global constants are a feature added -in Hangzhou protocol that enables the re-use of user-defined Micheline chunks in Michelson scripts, allowing -for larger and more complex contracts on the chain. It works in the -following way: - -- Fragments of Michelson code (written in the :doc:`Micheline format <../shell/micheline>`) are - registered on the chain via a new operation - ``register_global_constant``. An example expression might be the - integer ``999`` or the lambda expression ``{ PUSH int 999; ADD }`` -- Included in the receipt of the operation is a hash of the expression - registered. For example the hash ``999`` is - ``expruQN5r2umbZVHy6WynYM8f71F8zS4AERz9bugF8UkPBEqrHLuU8``. -- Constants can be referenced inside a Michelson script with the new - primitive ``constant``. For example, we could write a lambda - equivalent to the one above like so: - ``{ PUSH int (constant "expruQN5r2umbZVHy6WynYM8f71F8zS4AERz9bugF8UkPBEqrHLuU8"); ADD }`` - -Global Constant Registration ----------------------------- - -The new ``register_global_constant`` operation includes an object with a -single key ``"value"``, the value of which is the Micheline expression -to be registered. - -You can submit this operation conveniently through a new :doc:`tezos-client ` command. -For example, the command: - -.. code:: sh - - tezos-client register global constant "999" from bootstrap1 --burn-cap 0.017 - -would result in the output: - -:: - - Node is bootstrapped. - Estimated gas: 1440 units (will add 100 for safety) - Estimated storage: 68 bytes added (will add 20 for safety) - Operation successfully injected in the node. - Operation hash is 'onsFknW5iWa6eiTYqAghY4peQZ7JYQUJg5fR8MwAQkMKjXfNqGf' - NOT waiting for the operation to be included. - Use command - tezos-client wait for onsFknW5iWa6eiTYqAghY4peQZ7JYQUJg5fR8MwAQkMKjXfNqGf to be included --confirmations 5 --branch BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU - and/or an external block explorer to make sure that it has been included. - This sequence of operations was run: - Manager signed operations: - From: tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx - Fee to the baker: ꜩ0.000385 - Expected counter: 1 - Gas limit: 1540 - Storage limit: 88 bytes - Balance updates: - tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ................ -ꜩ0.000385 - fees(the baker who will include this operation,0) ... +ꜩ0.000385 - Register Global: - Value: 999 - This global constant registration was successfully applied - Balance updates: - tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ... -ꜩ0.017 - Consumed gas: 1440 - Storage size: 68 bytes - Global address: expruQN5r2umbZVHy6WynYM8f71F8zS4AERz9bugF8UkPBEqrHLuU8 - -As you can see, the address of the constant is returned in the operation -receipt in the field ``Global address``. This address is the Base58-encode Blake2b -hash of the binary serialization of the registered Micheline expression. -This means constants are content-addressable - given a particular Micheline -expression, you can always calculate its on-chain address and check if it’s registered. - -A few points about registering global constants: - -- Global constants may contain references to other constants; however, - any referenced constants must already be registered on the chain. As a - corollary, you cannot have cyclic references. -- Global constants are not type-checked before registration - any - valid Micheline expression may be registered. That said, attempting - to originate a contract that uses a constant in an ill-typed way will - fail. -- The total depth of the expression registered as a constant (after - expanding all constant references) may not exceed 10,000. -- The total number of nodes in the Micheline expression being - registered (after expanding all constant references) may not exceed - the ``max_micheline_node_count`` protocol constant. As of Hangzhou - this is 50,000. -- The total number of bytes in the Micheline expression being - registered (after expanding all constant references) may not exceed - the ``max_micheline_bytes_limit`` protocol constant. As of Hangzhou - this is 50,000. - -Originating a Contract that uses Global Constants -------------------------------------------------- - -A global constant can be referenced in Michelson scripts via the -primitive ``constant``, which accepts a single string argument, being -the hash of the expression to be referenced at runtime. This primitive -can be used to replace any Micheline node in the bodies of the -``parameter``, ``storage``, ``code``, or ``view`` fields of a Michelson script. For -example, we replace every instance of the type ``lambda unit unit`` and -value 999 with their respective hashes: - -.. code-block:: michelson - - parameter (constant "exprtYirrFwYKm6yKLzJNtYRbq49zedYq16BonRvMzHiwSbUekB9YL"); - storage (big_map int (constant "exprtYirrFwYKm6yKLzJNtYRbq49zedYq16BonRvMzHiwSbUekB9YL")); - code { - PUSH int (constant "expruQN5r2umbZVHy6WynYM8f71F8zS4AERz9bugF8UkPBEqrHLuU8"); - # - }; - -The full expansion of this contract would be: - -.. code-block:: michelson - - parameter (lambda unit unit); - storage (big_map int (lambda unit unit)); - code { - PUSH int 999; - # - }; - -During origination, all constants are expanded recursively. The -operation will fail if the resulting contract is ill-typed. Global -constant expansion consumes gas; thus, the operation may also fail due -to gas exhaustion. - -Global Constants at Runtime ---------------------------- - -Contracts that use global constants are semantically equivalent to the -contract with all constants expanded. - -Note that using the `UNPACK `__ -operation to deserialize a lambda which contains a reference to a global -constant is not supported. Similarly, originating a contract which contains -a reference to a global constant using the -`CREATE_CONTRACT `__ -instruction will also fail. diff --git a/docs/012/glossary.rst b/docs/012/glossary.rst deleted file mode 100644 index 6c0bc44efb72..000000000000 --- a/docs/012/glossary.rst +++ /dev/null @@ -1,179 +0,0 @@ -Glossary -======== - -This glossary is divided in two sections, the first one concerns Tezos, and -the second one concerns the `economic protocol`_. The definitions in the latter -section may be different for other protocol versions. - -Tezos ------ - -.. include:: ../shell/glossary.rst.h - -Protocol --------- - -_`Accuser` - When a node_ attempts to inject several incompatible blocks (or when it tries - to abuse the network in another similar way), another node_ can make an - accusation: show evidence of attempted abuse. The node_ making the accusation - is the accuser. - - The accuser is awarded some funds from the baking_ deposit of the accused. - - When using :ref:`Octez `, accusations are handled by a - separate binary. - -_`Account` - An account is a unique identifier within the protocol. There are different - kinds of accounts (see `Originated account`_ and `Implicit account`_). - - In the Context_, each account is associated with a balance (an amount of - tez available). - -_`Baker` - When a node_ creates a new block_, it is the baker of this block_. - Baking_ rights are distributed to different accounts based on their - available balance. Only a node_ that handles an account_ with baking_ rights - is allowed to bake; blocks created by another node_ are invalid. - The baker selects transactions from the mempool_ to be included in the block_ it bakes. - - When using :ref:`Octez `, baking_ is handled by a separate - binary. - -_`Baking`/_`Endorsing rights` - A delegate_ is allowed to bake/endorse a block_ if he holds the - baking/endorsing right for that block_. At the start of a Cycle_, - baking and endorsing rights are computed for all the block_ heights in the - cycle_, based on the proportion of the stake owned by each account. - - For each block_ height, there are several accounts that are allowed to bake. - These different accounts are given different Priorities. - - For each block_ height, there are several accounts that are allowed to - endorse. There can be multiple endorsements per block_. - -_`Burn` - To ensure responsible use of the storage space on the public blockchain, - there are some costs charged to users for consuming storage. These - costs are burnt (i.e., the amount of tez is destroyed). For example, - a per-byte storage cost is burnt for increasing the storage space of a - smart contract; a fixed amount is burnt for allocating a new contract - (which consumes space by storing its address on the blockchain). - - See also `Fee`_. - -_`Constants` - Protocols are parameterized by several parameters called protocol constants, which may vary from one protocol to another or from one network to another. - -_`Contract` - See account_. - -_`Cycle` - A cycle is a set of consecutive blocks. E.g., cycle 12 started at block_ - height 49152 and ended at block_ height 53248. - - Cycles are used as a unit of “time” in the block_ chain. For example, the - different phases in the amendment voting procedures are defined based on - cycles. - -_`Delegate` - An `Implicit account`_ to which an account_ has delegated their baking_ and - `endorsing rights`_. The baking_ rights and `endorsing rights`_ are - calculated based on the total balance of tez that an account_ has been - delegated to. - -_`Delegation` - An operation_ in which an account_ balance is lent to a - delegate_. This increases the delegate_'s stake and consequently - its Baking_ rights. The delegate_ does not control the funds from - the account_. - -_`Double baking` - When a baker_ signs two different blocks at the same height, it is called - double baking. Double baking is detrimental to the network and might be - indicative of an attempt to double spend. As such, it is punished by the - network: an accuser_ can provide proof of the double baking to be awarded - part of the baker_'s deposit. - -_`Endorser` - When a block_ is created and propagated on the network, nodes that have - `endorsing rights`_ for the matching block_ height can emit an endorsement - operation_. The accounts that emit the block_ are the endorsers of the block_. - Endorsement operations_ are included in the next block_. - - When using :ref:`Octez `, endorsing is handled by a separate binary. - -_`Fee` - To ensure responsible use of computation resources of other nodes, and also to encourage active participation in the consensus protocol, there are some - fees that users pay to bakers for including their operations in blocks. - For example, fees are paid to a baker for operations such as a transaction_ or a revelation of a public key. - - See also `Burn`_. - -_`Gas` - A measure of the number of elementary operations_ performed during - the execution of a `smart contract`_. Gas is used to measure how - much computing power is used to execute a `smart contract`_. - -_`Implicit account` - An account_ that is linked to a public key. Contrary to a `smart - contract`_, an `Implicit account`_ cannot include a script and it - cannot reject incoming transactions. - - If registered, an `Implicit account`_ can act as a delegate_. - - The address of an `Implicit account`_ always starts with the - letters `tz` followed by `1`, `2` or `3` (depending on the - signature scheme) and finally the hash of the public key. - -.. _glossary_michelson_012: - -Michelson - The built-in language used by a `smart contract`_. - -_`Operations` - The main operations in the protocol are transactions (to transfer funds - or to execute smart contracts), accusations, activations, delegations, - endorsements and originations. - -_`Originated account` - See `smart contract`_. - -_`Origination` - An operation_ to create a `smart contract`_. - -_`Priority` - A rank of different baking_ rights. Each rank corresponds to a time span. A - baker_ with baking_ rights at a given priority is only allowed to bake during - the priority's corresponding time span. Baking_ outside of one's designated - priority, results in an invalid block_. - -_`Roll` - An amount of tez (e.g., 6000ꜩ) serving as a minimal amount to - determine delegates' baking_ rights in a cycle_. A delegate_ with - twice as much stake as another will be given twice as many rights - to bake. A roll also serves as a unit to determine delegates' - voting rights in a cycle_. - -_`Smart contract` - Account_ which is associated to a :ref:`Michelson ` script. They are - created with an explicit origination_ operation and are therefore - sometimes called originated accounts. The address of a smart - contract always starts with the letters ``KT1``. - -_`Transaction` - An operation_ to transfer tez between two accounts, or to run the code of a - `smart contract`_. - -_`Voting period` - Any of the ``proposal``, ``exploration``, ``cooldown``, - ``promotion`` or ``adoption`` stages in the voting procedure when - amending the `economic protocol`_. - -_`Voting listings` - The list calculated at the beginning of each `voting period`_ that contains - the staking balance (in number of rolls) of each delegate_ that owns more - than one roll_ at that moment. For each delegate_, The voting listings - reflects the weight of the vote emitted by the delegate_ when amending the - `economic protocol`_. diff --git a/docs/012/liquidity_baking.rst b/docs/012/liquidity_baking.rst deleted file mode 100644 index 88e4d2c58e5e..000000000000 --- a/docs/012/liquidity_baking.rst +++ /dev/null @@ -1,51 +0,0 @@ -Liquidity Baking -================ - -Liquidity baking incentivizes large amounts of decentralized liquidity provision between tez and tzBTC by minting a small amount of tez every block and depositing it inside of a constant product market making smart-contract. It includes an escape hatch mechanism as a contingency. - -Contracts -~~~~~~~~~ - -During activation of Granada protocol, a constant product market making (CPMM) Michelson contract has been deployed on the chain with address ``KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5`` as well as an associated liquidity token contract (LQT) with address ``KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo``. - -.. warning:: - - while the CPMM and LQT contract originations provide an ``Origination_result``, the LQT contract contains two big maps not included in a `lazy_storage_diff` field. Indexers and other tooling may need manual updates to include these. - -The CPMM maintains a balance of ``a`` tez and ``b`` `tzBTC `_, where tzBTC is the `FA1.2 token `_ found at address ``KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn``. The smart contract accepts deposits of ``da`` tez and returns ``db`` tzBTC (or vice versa) where the invariant ``(a + da * (1 - f - n)) * (b - db) = a b`` is preserved, and ``f`` and ``n`` are a fee and burn, set at 0.1% each. Calculations are done with precision of 1000, rounding down on division. - -To implement this contract, we use a fork of the open source code base used by `version two `_ of the "Dexter" project. The implementation of this contract has been `formally verified `_ against its functional specification. The contract code is modified in the following way: - -1. The fee is set to 0.1% only (the fee in Dexter v2 is set to 0.3%). Rationale: given the subsidy it is not necessary to charge a large fee and better to improve liquidity. -2. An additional 0.1% of every trade is burned by being transferred to the null implicit account. Rationale: this mechanism offsets inflation from the subsidy. The inflation is exactly balanced at a daily trade volume of 7.2 million tez. -3. The ability to set a delegate has been removed. Rationale: the subsidy means there is no need for a baker for that contract and having one would create an imbalance. -4. The ability to set a manager has been removed. Rationale: the only privilege of the Dexter manager is to set Dexter's delegate so this role is now unnecessary. - -The LIGO and Michelson code for these contracts, as well as detailed documentation, can be found on `the liquidity baking branch of the Dexter 2 repository `_. - -Subsidy -~~~~~~~ - -At every block in the chain, a small amount of tez is minted and credited to the CPMM contract, and the CPMM's ``%default`` entrypoint is called to update the ``xtz_pool`` balance in its storage. The amount that is minted and sent to the CPMM contract is 1/16th of the rewards for a block of priority 0 with all endorsements; currently these rewards are 40 tez per block so the amount that is sent to the CPMM contract is 2.5 tez per block. - -So the credits to the CPMM contract can be accounted for by indexers, they are included in block metadata as a balance update with a new constructor for ``update_origin``, ``Subsidy``. - -As a safety precaution, the subsidy expires automatically at a given -level called the liquidity baking sunset level. The sunset level can -be renewed periodically by protocol amendment. - -.. _esc_hatch_012: - -Escape hatch -~~~~~~~~~~~~ - -In addition to the sunset mechanism, an escape hatch is included. At every block, the baker producing the block can choose to include a flag that requests ending the subsidy. The context maintains an exponential moving average of that flag calculated as such with integer arithmetic: - -``e[0] = 0`` -``e[n+1] = (1999 * e[n] // 2000) + (1000 if flag[n] else 0)`` - -If at any block ``e[n] >= 666667`` then it means that an exponential moving average with a window size on the order of two thousand blocks has had roughly at least a third of blocks demanding the end of the subsidy. If that is the case, the subsidy is permanently halted (though it can be reactivated by a protocol upgrade). - -For indicative purposes, if a fraction ``f`` of blocks start signalling the flag, the threshold is reached after roughly ``2*(log(1-1/(3f)) / log(0.999))`` blocks, about 812 blocks if everyone signals, 1079 blocks if 80% do, 1624 blocks if 60% do, 3590 blocks if 40% do, etc. Recall for comparison that assuming two blocks per minute there are 2880 blocks per day. - -The escape hatch can be invoked through a JSON file containing a vote that is repeatedly submitted on each baked block, e.g. ``tezos-baker run with local node ~/.tezos-node alice --votefile "per_block_votes.json"`` where ``per_block_votes.json`` contains just ``{"liquidity_baking_escape_vote": true}``. See also the :ref:`baker man page`. diff --git a/docs/012/michelson.rst b/docs/012/michelson.rst deleted file mode 100644 index 5d7212e70edd..000000000000 --- a/docs/012/michelson.rst +++ /dev/null @@ -1,3821 +0,0 @@ -Michelson: the language of Smart Contracts in Tezos -=================================================== - -This specification gives a detailed formal semantics of the Michelson -language and a short explanation of how smart contracts are executed -and interact in the blockchain. - -The language is stack-based, with high level data types and primitives, -and strict static type checking. Its design cherry picks traits from -several language families. Vigilant readers will notice direct -references to Forth, Scheme, ML and Cat. - -A Michelson program is a series of instructions that are run in -sequence: each instruction receives as input the stack resulting from the -previous instruction, and rewrites it for the next one. The stack -contains both immediate values and heap allocated structures. All values -are immutable and garbage collected. - -The types of the input and output stack are fixed and monomorphic, -and the program is typechecked before being introduced into the system. -No smart contract execution can fail because an instruction has been -executed on a stack of unexpected length or contents. - -This specification gives the complete instruction set, type system and -semantics of the language. It is meant as a precise reference manual, -not an easy introduction. Even though, some examples are provided at -the end of the document and can be read first or at the same time as -the specification. The document also starts with a less formal -explanation of the context: how Michelson code interacts with the -blockchain. - -Semantics of smart contracts and transactions ---------------------------------------------- - -The Tezos ledger currently has two types of accounts that can hold -tokens (and be the destinations of transactions). - - - An implicit account is a non programmable account, whose tokens - are spendable and delegatable by a public key. Its address is - directly the public key hash, and starts with ``tz1``, ``tz2`` or - ``tz3``. - - A smart contract is a programmable account. A transaction to such - an address can provide data, and can fail for reasons decided by - its Michelson code. Its address is a unique hash that depends on - the operation that led to its creation, and starts with ``KT1``. - -From Michelson, they are indistinguishable. A safe way to think about -this is to consider that implicit accounts are smart contracts that -always succeed to receive tokens, and does nothing else. - -Intra-transaction semantics -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Alongside their tokens, smart contracts keep a piece of storage. Both -are ruled by a specific logic specified by a Michelson program. A -transaction to a smart contract will provide an input value and in -option some tokens, and in return, the smart contract can modify its -storage and transfer its tokens. - -The Michelson program receives as input a stack containing a single -pair whose first element is an input value and second element the -content of the storage space. It must return a stack containing a -single pair whose first element is the list of internal operations -that it wants to emit, and second element is the new contents of the -storage space. Alternatively, a Michelson program can fail, explicitly -using a specific opcode, or because something went wrong that could -not be caught by the type system (e.g. gas exhaustion). - -A bit of polymorphism can be used at contract level, with a -lightweight system of named entrypoints: instead of an input value, -the contract can be called with an entrypoint name and an argument, -and these two components are transformed automatically in a simple and -deterministic way to an input value. This feature is available both -for users and from Michelson code. See the dedicated section. - -Inter-transaction semantics -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -An operation included in the blockchain is a sequence of "external -operations" signed as a whole by a source address. These operations -are of three kinds: - - - Transactions to transfer tokens to implicit accounts or tokens and - parameters to a smart contract (or, optionally, to a specified - entrypoint of a smart contract). - - Originations to create new smart contracts from its Michelson - source code, an initial amount of tokens transferred from the - source, and an initial storage contents. - - Delegations to assign the tokens of the source to the stake of - another implicit account (without transferring any tokens). - -Smart contracts can also emit "internal operations". These are run -in sequence after the external transaction completes, as in the -following schema for a sequence of two external operations. - -:: - - +------+----------------+-------+----------------+ - | op 1 | internal ops 1 | op 2 | internal ops 2 | - +------+----------------+-------+----------------+ - -Smart contracts called by internal transactions can in turn also emit -internal operation. The interpretation of the internal operations -of a given external operation uses a stack, as in the following -example, also with two external operations. - -:: - - +-----------+---------------+--------------------------+ - | executing | emissions | resulting stack | - +-----------+---------------+--------------------------+ - | op 1 | 1a, 1b, 1c | 1a, 1b, 1c | - | op 1a | 1ai, 1aj | 1ai, 1aj, 1b, 1c | - | op 1ai | | 1aj, 1b, 1c | - | op 1aj | | 1b, 1c | - | op 1b | 1bi | 1bi, 1c | - | op 1bi | | 1c | - | op 1c | | | - | op 2 | 2a, 2b | 2a, 2b | - | op 2a | 2ai | 2ai, 2b | - | op 2ai | 2ai1 | 2ai1, 2b | - | op 2ai1 | | 2b | - | op 2b | 2bi | 2bi | - | op 2bi | 2bi1 | 2bi1 | - | op 2bi1 | 2bi2 | 2bi2 | - | op 2bi2 | | | - +-----------+---------------+--------------------------+ - -Failures -~~~~~~~~ - -All transactions can fail for a few reasons, mostly: - - - Not enough tokens in the source to spend the specified amount. - - The script took too many execution steps. - - The script failed programmatically using the ``FAILWITH`` instruction. - -External transactions can also fail for these additional reasons: - - - The signature of the external operations was wrong. - - The code or initial storage in an origination did not typecheck. - - The parameter in a transfer did not typecheck. - - The destination did not exist. - - The specified entrypoint did not exist. - -All these errors cannot happen in internal transactions, as the type -system catches them at operation creation time. In particular, -Michelson has two types to talk about other accounts: ``address`` and -``contract t``. The ``address`` type merely gives the guarantee that -the value has the form of a Tezos address. The ``contract t`` type, on -the other hand, guarantees that the value is indeed a valid, existing -account whose parameter type is ``t``. To make a transaction from -Michelson, a value of type ``contract t`` must be provided, and the -type system checks that the argument to the transaction is indeed of -type ``t``. Hence, all transactions made from Michelson are well -formed by construction. - -In any case, when a failure happens, either total success or total -failure is guaranteed. If a transaction (internal or external) fails, -then the whole sequence fails and all the effects up to the failure -are reverted. These transactions can still be included in blocks, and -the transaction fees are given to the implicit account who baked the -block. - -Language semantics ------------------- - -This specification explains in a symbolic way the computation performed by the -Michelson interpreter on a given program and initial stack to produce -the corresponding resulting stack. The Michelson interpreter is a pure -function: it only builds a result stack from the elements of an initial -one, without affecting its environment. This semantics is then naturally -given in what is called a big step form: a symbolic definition of a -recursive reference interpreter. This definition takes the form of a -list of rules that cover all the possible inputs of the interpreter -(program and stack), and describe the computation of the corresponding -resulting stacks. - -Rules form and selection -~~~~~~~~~~~~~~~~~~~~~~~~ - -The rules have the main following form. - -:: - - > (syntax pattern) / (initial stack pattern) => (result stack pattern) - iff (conditions) - where (recursions) - and (more recursions) - -The left hand side of the ``=>`` sign is used for selecting the rule. -Given a program and an initial stack, one (and only one) rule can be -selected using the following process. First, the toplevel structure of -the program must match the syntax pattern. This is quite simple since -there are only a few non-trivial patterns to deal with instruction -sequences, and the rest is made of trivial patterns that match one -specific instruction. Then, the initial stack must match the initial -stack pattern. Finally, some rules add extra conditions over the values -in the stack that follow the ``iff`` keyword. Sometimes, several rules -may apply in a given context. In this case, the one that appears first -in this specification is to be selected. If no rule applies, the result -is equivalent to the one for the explicit ``FAILWITH`` instruction. This -case does not happen on well-typed programs, as explained in the next -section. - -The right hand side describes the result of the interpreter if the rule -applies. It consists in a stack pattern, whose parts are either -constants, or elements of the context (program and initial stack) that -have been named on the left hand side of the ``=>`` sign. - -Recursive rules (big step form) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Sometimes, the result of interpreting a program is derived from the -result of interpreting another one (as in conditionals or function -calls). In these cases, the rule contains a clause of the following -form. - -:: - - where (intermediate program) / (intermediate stack) => (partial result) - -This means that this rule applies in case interpreting the intermediate -state on the left gives the pattern on the right. - -The left hand sign of the ``=>`` sign is constructed from elements of -the initial state or other partial results, and the right hand side -identify parts that can be used to build the result stack of the rule. - -If the partial result pattern does not actually match the result of the -interpretation, then the result of the whole rule is equivalent to the -one for the explicit ``FAILWITH`` instruction. Again, this case does not -happen on well-typed programs, as explained in the next section. - -Format of patterns -~~~~~~~~~~~~~~~~~~ - -Code patterns are of one of the following syntactical forms. - -- ``INSTR`` (an uppercase identifier) is a simple instruction (e.g. - ``DROP``). -- ``INSTR (arg) ...`` is a compound instruction, whose arguments can be - code, data or type patterns (e.g. ``PUSH nat 3``). -- ``{ (instr) ; ... }`` is a possibly empty sequence of instructions, - (e.g. ``IF { SWAP ; DROP } { DROP }``), nested sequences can drop the - braces. -- ``name`` is a pattern that matches any program and names a part of - the matched program that can be used to build the result. -- ``_`` is a pattern that matches any instruction. - -Stack patterns are of one of the following syntactical forms. - -- ``[FAILED]`` is the special failed state. -- ``[]`` is the empty stack. -- ``(top) : (rest)`` is a stack whose top element is matched by the - data pattern ``(top)`` on the left, and whose remaining elements are - matched by the stack pattern ``(rest)`` on the right (e.g. - ``x : y : rest``). -- ``name`` is a pattern that matches any stack and names it in order to - use it to build the result. -- ``_`` is a pattern that matches any stack. - -Data patterns are of one of the following syntactical forms. - -- integer/natural number literals, (e.g. ``3``). -- string literals, (e.g. ``"contents"``). -- raw byte sequence literals (e.g. ``0xABCDEF42``). -- ``Tag`` (capitalized) is a symbolic constant, (e.g. ``Unit``, - ``True``, ``False``). -- ``(Tag (arg) ...)`` tagged constructed data, (e.g. ``(Pair 3 4)``). -- a code pattern for first class code values. -- ``name`` to name a value in order to use it to build the result. -- ``_`` to match any value. - -The domain of instruction names, symbolic constants and data -constructors is fixed by this specification. Michelson does not let the -programmer introduce its own types. - -Be aware that the syntax used in the specification may differ from -the :ref:`concrete syntax `. In particular -some instructions are annotated with types that are not present in the -concrete language because they are synthesized by the typechecker. - -Shortcuts -~~~~~~~~~ - -Sometimes, it is easier to think (and shorter to write) in terms of -program rewriting than in terms of big step semantics. When it is the -case, and when both are equivalents, we write rules of the form: - -:: - - p / S => S'' - where p' / S' => S'' - -using the following shortcut: - -:: - - p / S => p' / S' - -The concrete language also has some syntax sugar to group some common -sequences of operations as one. This is described in this specification -using a simple regular expression style recursive instruction rewriting. - -.. _michelson_type_system_012: - -Introduction to the type system and notations ---------------------------------------------- - -This specification describes a type system for Michelson. To make things -clear, in particular to readers that are not accustomed to reading -formal programming language specifications, it does not give a -typechecking or inference algorithm. It only gives an intentional -definition of what we consider to be well-typed programs. For each -syntactical form, it describes the stacks that are considered well-typed -inputs, and the resulting outputs. - -The type system is sound, meaning that if a program can be given a type, -then if run on a well-typed input stack, the interpreter will never -apply an interpretation rule on a stack of unexpected length or -contents. Also, it will never reach a state where it cannot select an -appropriate rule to continue the execution. Well-typed programs do not -block, and do not go wrong. - -Type notations -~~~~~~~~~~~~~~ - -The specification introduces notations for the types of values, terms -and stacks. Apart from a subset of value types that appear in the form -of type annotations in some places throughout the language, it is -important to understand that this type language only exists in the -specification. - -A stack type can be written: - -- ``[]`` for the empty stack. -- ``(top) : (rest)`` for the stack whose first value has type ``(top)`` - and queue has stack type ``(rest)``. - -Instructions, programs and primitives of the language are also typed, -their types are written: - -:: - - (type of stack before) -> (type of stack after) - -The types of values in the stack are written: - -- ``identifier`` for a primitive data-type (e.g. ``bool``). -- ``identifier (arg)`` for a parametric data-type with one parameter - type ``(arg)`` (e.g. ``list nat``). -- ``identifier (arg) ...`` for a parametric data-type with several - parameters (e.g. ``map string int``). -- ``[ (type of stack before) -> (type of stack after) ]`` for a code - quotation, (e.g. ``[ int : int : [] -> int : [] ]``). -- ``lambda (arg) (ret)`` is a shortcut for - ``[ (arg) : [] -> (ret) : [] ]``. - -Meta type variables -~~~~~~~~~~~~~~~~~~~ - -The typing rules introduce meta type variables. To be clear, this has -nothing to do with polymorphism, which Michelson does not have. These -variables only live at the specification level, and are used to express -the consistency between the parts of the program. For instance, the -typing rule for the ``IF`` construct introduces meta variables to -express that both branches must have the same type. - -Here are the notations for meta type variables: - -- ``'a`` for a type variable. -- ``'A`` for a stack type variable. -- ``_`` for an anonymous type or stack type variable. - -Typing rules -~~~~~~~~~~~~ - -The system is syntax directed, meaning that it defines a single -typing rule for each syntax construct. A typing rule restricts the type -of input stacks that are authorized for this syntax construct, links the -output type to the input type, and links both of them to the -subexpressions when needed, using meta type variables. - -Typing rules are of the form: - -:: - - (syntax pattern) - :: (type of stack before) -> (type of stack after) [rule-name] - iff (premises) - -Where premises are typing requirements over subprograms or values in the -stack, both of the form ``(x) :: (type)``, meaning that value ``(x)`` -must have type ``(type)``. - -A program is shown well-typed if one can find an instance of a rule that -applies to the toplevel program expression, with all meta type variables -replaced by non variable type expressions, and of which all type -requirements in the premises can be proven well-typed in the same -manner. For the reader unfamiliar with formal type systems, this is -called building a typing derivation. - -Here is an example typing derivation on a small program that computes -``(x+5)*10`` for a given input ``x``, obtained by instantiating the -typing rules for instructions ``PUSH``, ``ADD`` and for the sequence, as -found in the next sections. When instantiating, we replace the ``iff`` -with ``by``. - -:: - - { PUSH nat 5 ; ADD ; PUSH nat 10 ; MUL } - :: [ nat : [] -> nat : [] ] - by { PUSH nat 5 ; ADD } - :: [ nat : [] -> nat : [] ] - by PUSH nat 5 - :: [ nat : [] -> nat : nat : [] ] - by 5 :: nat - and ADD - :: [ nat : nat : [] -> nat : [] ] - and { PUSH nat 10 ; MUL } - :: [ nat : [] -> nat : [] ] - by PUSH nat 10 - :: [ nat : [] -> nat : nat : [] ] - by 10 :: nat - and MUL - :: [ nat : nat : [] -> nat : [] ] - -Producing such a typing derivation can be done in a number of manners, -such as unification or abstract interpretation. In the implementation of -Michelson, this is done by performing a recursive symbolic evaluation of -the program on an abstract stack representing the input type provided by -the programmer, and checking that the resulting symbolic stack is -consistent with the expected result, also provided by the programmer. - -Side note -~~~~~~~~~ - -As with most type systems, it is incomplete. There are programs that -cannot be given a type in this type system, yet that would not go wrong -if executed. This is a necessary compromise to make the type system -usable. Also, it is important to remember that the implementation of -Michelson does not accept as many programs as the type system describes -as well-typed. This is because the implementation uses a simple single -pass typechecking algorithm, and does not handle any form of -polymorphism. - -Core data types and notations ------------------------------ - -- ``string``, ``nat``, ``int`` and ``bytes``: The core primitive - constant types. - -- ``bool``: The type for booleans whose values are ``True`` and - ``False``. - -- ``unit``: The type whose only value is ``Unit``, to use as a - placeholder when some result or parameter is not necessary. For - instance, when the only goal of a contract is to update its storage. - -- ``never``: The empty type. Since ``never`` has no inhabitant, no value of - this type is allowed to occur in a well-typed program. - -- ``list (t)``: A single, immutable, homogeneous linked list, whose - elements are of type ``(t)``, and that we write ``{}`` for the empty - list or ``{ first ; ... }``. In the semantics, we use chevrons to - denote a subsequence of elements. For instance: ``{ head ; }``. - -- ``pair (l) (r)``: A pair of values ``a`` and ``b`` of types ``(l)`` - and ``(r)``, that we write ``(Pair a b)``. - -- ``pair (t{1}) ... (t{n})`` with ``n > 2``: A shorthand for ``pair (t{1}) (pair (t{2}) ... (pair (t{n-1}) (t{n})) ...)``. - -- ``option (t)``: Optional value of type ``(t)`` that we write ``None`` - or ``(Some v)``. - -- ``or (l) (r)``: A union of two types: a value holding either a value - ``a`` of type ``(l)`` or a value ``b`` of type ``(r)``, that we write - ``(Left a)`` or ``(Right b)``. - -- ``set (t)``: Immutable sets of values of type ``(t)`` that we write as - lists ``{ item ; ... }``, of course with their elements unique, and - sorted. - -- ``map (k) (t)``: Immutable maps from keys of type ``(k)`` of values - of type ``(t)`` that we write ``{ Elt key value ; ... }``, with keys - sorted. - -- ``big_map (k) (t)``: Lazily deserialized maps from keys of type - ``(k)`` of values of type ``(t)``. - These maps should be used if you intend to store large amounts of data in a map. - Using ``big_map`` can reduce gas costs significantly compared to standard maps, as data is lazily deserialized. - Note however that individual operations on ``big_map`` have higher gas costs than those over standard maps. - A ``big_map`` also has a lower storage cost than a standard map of the same size, when large keys are used, since only the hash of each key is stored in a ``big_map``. - - A ``big_map`` cannot appear inside another ``big_map``. - See the section on :ref:`operations on big maps ` for a description of the syntax of values of type ``big_map (k) (t)`` and available operations. - -Core instructions ------------------ - -Control structures -~~~~~~~~~~~~~~~~~~ - -- ``FAILWITH``: Explicitly abort the current program. - -:: - - :: 'a : \_ -> \_ - -This special instruction aborts the current program exposing the top -element of the stack in its error message (first rule below). It makes -the output useless since all subsequent instructions will simply -ignore their usual semantics to propagate the failure up to the main -result (second rule below). Its type is thus completely generic. - -:: - - > FAILWITH / a : _ => [FAILED] - > _ / [FAILED] => [FAILED] - -- ``{}``: Empty sequence. - -:: - - :: 'A -> 'A - - > {} / SA => SA - -- ``{ I ; C }``: Sequence. - -:: - - :: 'A -> 'C - iff I :: [ 'A -> 'B ] - C :: [ 'B -> 'C ] - - > I ; C / SA => SC - where I / SA => SB - and C / SB => SC - -- ``IF bt bf``: Conditional branching. - -:: - - :: bool : 'A -> 'B - iff bt :: [ 'A -> 'B ] - bf :: [ 'A -> 'B ] - - > IF bt bf / True : S => bt / S - > IF bt bf / False : S => bf / S - -- ``LOOP body``: A generic loop. - -:: - - :: bool : 'A -> 'A - iff body :: [ 'A -> bool : 'A ] - - > LOOP body / True : S => body ; LOOP body / S - > LOOP body / False : S => S - -- ``LOOP_LEFT body``: A loop with an accumulator. - -:: - - :: (or 'a 'b) : 'A -> 'b : 'A - iff body :: [ 'a : 'A -> (or 'a 'b) : 'A ] - - > LOOP_LEFT body / (Left a) : S => body ; LOOP_LEFT body / a : S - > LOOP_LEFT body / (Right b) : S => b : S - -- ``DIP code``: Runs code protecting the top element of the stack. - -:: - - :: 'b : 'A -> 'b : 'C - iff code :: [ 'A -> 'C ] - - > DIP code / x : S => x : S' - where code / S => S' - -- ``DIP n code``: Runs code protecting the ``n`` topmost elements of - the stack. In particular, ``DIP 0 code`` is equivalent to ``code`` - and ``DIP 1 code`` is equivalent to ``DIP code``. - -:: - - :: 'a{1} : ... : 'a{n} : 'A -> 'a{1} : ... : 'a{n} : 'B - iff code :: [ 'A -> 'B ] - - > DIP n code / x{1} : ... : x{n} : S => x{1} : ... : x{n} : S' - where code / S => S' - -- ``EXEC``: Execute a function from the stack. - -:: - - :: 'a : lambda 'a 'b : 'C -> 'b : 'C - - > EXEC / a : f : S => r : S - where f / a : [] => r : [] - -- ``APPLY``: Partially apply a tuplified function from the stack. - Values that are not both pushable and storable - (values of type ``operation``, ``contract _`` and ``big map _ _``) - cannot be captured by ``APPLY`` (cannot appear in ``'a``). - -:: - - :: 'a : lambda (pair 'a 'b) 'c : 'C -> lambda 'b 'c : 'C - - > APPLY / a : f : S => { PUSH 'a a ; PAIR ; f } : S - -Stack operations -~~~~~~~~~~~~~~~~ - -- ``DROP``: Drop the top element of the stack. - -:: - - :: _ : 'A -> 'A - - > DROP / _ : S => S - -- ``DROP n``: Drop the `n` topmost elements of the stack. In - particular, ``DROP 0`` is a noop and ``DROP 1`` is equivalent to - ``DROP``. - -:: - - :: 'a{1} : ... : 'a{n} : 'A -> 'A - - > DROP n / x{1} : ... : x{n} : S => S - -- ``DUP``: Duplicate the top element of the stack. - -:: - - :: 'a : 'A -> 'a : 'a : 'A - - > DUP / x : S => x : x : S - -- ``DUP n``: Duplicate the N-th element of the stack. `DUP 1` is equivalent to `DUP`. `DUP 0` is rejected. - -:: - - DUP 1 :: 'a : 'A -> 'a : 'a : 'A - - DUP (n+1) :: 'a : 'A -> 'b : 'a : 'A - iff DUP n :: 'A -> 'b : 'A - - > DUP 1 / x : S => x : x : S - - > DUP (n+1) / x : S => y : x : S - iff DUP n / S => y : S - - -- ``SWAP``: Exchange the top two elements of the stack. - -:: - - :: 'a : 'b : 'A -> 'b : 'a : 'A - - > SWAP / x : y : S => y : x : S - -- ``DIG n``: Take the element at depth ``n`` of the stack and move it - on top. The element on top of the stack is at depth ``0`` so that - ``DIG 0`` is a no-op and ``DIG 1`` is equivalent to ``SWAP``. - -:: - - :: 'a{1} : ... : 'a{n} : 'b : 'A -> 'b : 'a{1} : ... : 'a{n} : 'A - - > DIG n / x{1} : ... : x{n} : y : S => y : x{1} : ... : x{n} : S - -- ``DUG n``: Place the element on top of the stack at depth ``n``. The - element on top of the stack is at depth ``0`` so that ``DUG 0`` is a - no-op and ``DUG 1`` is equivalent to ``SWAP``. - -:: - - :: 'b : 'a{1} : ... : 'a{n} : 'A -> 'a{1} : ... : 'a{n} : 'b : 'A - - > DUG n / y : x{1} : ... : x{n} : S => x{1} : ... : x{n} : y : S - -- ``PUSH 'a x``: Push a constant value of a given type onto the stack. - -:: - - :: 'A -> 'a : 'A - iff x :: 'a - - > PUSH 'a x / S => x : S - -- ``LAMBDA 'a 'b code``: Push a lambda with the given parameter type `'a` and return - type `'b` onto the stack. - -:: - - :: 'A -> (lambda 'a 'b) : 'A - - > LAMBDA _ _ code / S => code : S - -Generic comparison -~~~~~~~~~~~~~~~~~~ - -Comparison only works on a class of types that we call comparable. A -``COMPARE`` operation is defined in an ad hoc way for each comparable -type, but the result of compare is always an ``int``, which can in turn -be checked in a generic manner using the following combinators. The -result of ``COMPARE`` is ``0`` if the top two elements of the stack are -equal, negative if the first element in the stack is less than the -second, and positive otherwise. - -- ``EQ``: Checks that the top element of the stack is equal to zero. - -:: - - :: int : 'S -> bool : 'S - - > EQ / 0 : S => True : S - > EQ / v : S => False : S - iff v <> 0 - -- ``NEQ``: Checks that the top element of the stack is not equal to zero. - -:: - - :: int : 'S -> bool : 'S - - > NEQ / 0 : S => False : S - > NEQ / v : S => True : S - iff v <> 0 - -- ``LT``: Checks that the top element of the stack is less than zero. - -:: - - :: int : 'S -> bool : 'S - - > LT / v : S => True : S - iff v < 0 - > LT / v : S => False : S - iff v >= 0 - -- ``GT``: Checks that the top element of the stack is greater than zero. - -:: - - :: int : 'S -> bool : 'S - - > GT / v : S => C / True : S - iff v > 0 - > GT / v : S => C / False : S - iff v <= 0 - -- ``LE``: Checks that the top element of the stack is less than or equal to - zero. - -:: - - :: int : 'S -> bool : 'S - - > LE / v : S => True : S - iff v <= 0 - > LE / v : S => False : S - iff v > 0 - -- ``GE``: Checks that the top of the stack is greater than or equal to - zero. - -:: - - :: int : 'S -> bool : 'S - - > GE / v : S => True : S - iff v >= 0 - > GE / v : S => False : S - iff v < 0 - -Operations ----------- - -Operations on unit -~~~~~~~~~~~~~~~~~~ - -- ``UNIT``: Push a unit value onto the stack. - -:: - - :: 'A -> unit : 'A - - > UNIT / S => Unit : S - -- ``COMPARE``: Unit comparison - -:: - - :: unit : unit : 'S -> int : 'S - - > COMPARE / Unit : Unit : S => 0 : S - -Operations on type never -~~~~~~~~~~~~~~~~~~~~~~~~ - -The type ``never`` is the type of forbidden values. The most prominent -scenario in which ``never`` is used is when implementing a contract -template with no additional entrypoint. A contract template defines a set -of basic entrypoints, and its ``parameter`` declaration contains a type -variable for additional entrypoints in some branch of an union type, or -wrapped inside an option type. Letting this type variable be ``never`` in -a particular implementation indicates that the contract template has not -been extended, and turns the branch in the code that processes the -additional entrypoints into a forbidden branch. - -Values of type ``never`` cannot occur in a well-typed program. However, -they can be abstracted in the ``parameter`` declaration of a contract---or -by using the ``LAMBDA`` operation---thus indicating that the corresponding -branches in the code are forbidden. The type ``never`` also plays a role -when introducing values of union or option type with ``LEFT never``, -``RIGHT never``, or ``NONE never``. In such cases, the created values can -be inspected with the operations ``IF_LEFT``, ``IF_RIGHT``, or -``IF_NONE``, and the corresponding branches in the code are forbidden -branches. - -- ``NEVER``: Close a forbidden branch. - -:: - - :: never : 'A -> 'B - -- ``COMPARE``: Trivial comparison on type ``never`` - -:: - - :: never : never : 'S -> int : 'S - - -Operations on booleans -~~~~~~~~~~~~~~~~~~~~~~ - -- ``OR`` - -:: - - :: bool : bool : 'S -> bool : 'S - - > OR / x : y : S => (x | y) : S - -- ``AND`` - -:: - - :: bool : bool : 'S -> bool : 'S - - > AND / x : y : S => (x & y) : S - -- ``XOR`` - -:: - - :: bool : bool : 'S -> bool : 'S - - > XOR / x : y : S => (x ^ y) : S - -- ``NOT`` - -:: - - :: bool : 'S -> bool : 'S - - > NOT / x : S => ~x : S - -- ``COMPARE``: Boolean comparison - -:: - - :: bool : bool : 'S -> int : 'S - - > COMPARE / False : False : S => 0 : S - > COMPARE / False : True : S => -1 : S - > COMPARE / True : False : S => 1 : S - > COMPARE / True : True : S => 0 : S - -Operations on integers and natural numbers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Integers and naturals are arbitrary-precision, meaning that the only size -limit is gas. - -- ``NEG`` - -:: - - :: int : 'S -> int : 'S - :: nat : 'S -> int : 'S - - > NEG / x : S => -x : S - -- ``ABS`` - -:: - - :: int : 'S -> nat : 'S - - > ABS / x : S => abs (x) : S - -- ``ISNAT`` - -:: - - :: int : 'S -> option nat : 'S - - > ISNAT / x : S => Some (x) : S - iff x >= 0 - - > ISNAT / x : S => None : S - iff x < 0 - -- ``INT`` - -:: - - :: nat : 'S -> int : 'S - - > INT / x : S => x : S - -- ``ADD`` - -:: - - :: int : int : 'S -> int : 'S - :: int : nat : 'S -> int : 'S - :: nat : int : 'S -> int : 'S - :: nat : nat : 'S -> nat : 'S - - > ADD / x : y : S => (x + y) : S - -- ``SUB`` - -:: - - :: int : int : 'S -> int : 'S - :: int : nat : 'S -> int : 'S - :: nat : int : 'S -> int : 'S - :: nat : nat : 'S -> int : 'S - - > SUB / x : y : S => (x - y) : S - -- ``MUL`` - -:: - - :: int : int : 'S -> int : 'S - :: int : nat : 'S -> int : 'S - :: nat : int : 'S -> int : 'S - :: nat : nat : 'S -> nat : 'S - - > MUL / x : y : S => (x * y) : S - -- ``EDIV``: Perform Euclidean division - -:: - - :: int : int : 'S -> option (pair int nat) : 'S - :: int : nat : 'S -> option (pair int nat) : 'S - :: nat : int : 'S -> option (pair int nat) : 'S - :: nat : nat : 'S -> option (pair nat nat) : 'S - - > EDIV / x : 0 : S => None : S - > EDIV / x : y : S => Some (Pair (x / y) (x % y)) : S - iff y <> 0 - -Bitwise logical operators are also available on unsigned integers. - -- ``OR`` - -:: - - :: nat : nat : 'S -> nat : 'S - - > OR / x : y : S => (x | y) : S - -- ``AND``: (also available when the top operand is signed) - -:: - - :: nat : nat : 'S -> nat : 'S - :: int : nat : 'S -> nat : 'S - - > AND / x : y : S => (x & y) : S - -- ``XOR`` - -:: - - :: nat : nat : 'S -> nat : 'S - - > XOR / x : y : S => (x ^ y) : S - -- ``NOT``: Two's complement - -:: - - :: nat : 'S -> int : 'S - :: int : 'S -> int : 'S - - > NOT / x : S => ~x : S - - -The return type of ``NOT`` is an ``int`` and not a ``nat``. This is -because the sign is also negated. The resulting integer is computed -using two's complement. For instance, the boolean negation of ``0`` is -``-1``. To get a natural back, a possibility is to use ``AND`` with an -unsigned mask afterwards. - - -- ``LSL`` - -:: - - :: nat : nat : 'S -> nat : 'S - - > LSL / x : s : S => (x << s) : S - iff s <= 256 - > LSL / x : s : S => [FAILED] - iff s > 256 - -- ``LSR`` - -:: - - :: nat : nat : 'S -> nat : 'S - - > LSR / x : s : S => (x >> s) : S - iff s <= 256 - > LSR / x : s : S => [FAILED] - iff s > 256 - -- ``COMPARE``: Integer/natural comparison - -:: - - :: int : int : 'S -> int : 'S - :: nat : nat : 'S -> int : 'S - - > COMPARE / x : y : S => -1 : S - iff x < y - > COMPARE / x : y : S => 0 : S - iff x = y - > COMPARE / x : y : S => 1 : S - iff x > y - -Operations on strings -~~~~~~~~~~~~~~~~~~~~~ - -Strings are mostly used for naming things without having to rely on -external ID databases. They are restricted to the printable subset of -7-bit ASCII, plus some escaped characters (see section on -constants). So what can be done is basically use string constants as -is, concatenate or splice them, and use them as keys. - - -- ``CONCAT``: String concatenation. - -:: - - :: string : string : 'S -> string : 'S - - > CONCAT / s : t : S => (s ^ t) : S - - :: string list : 'S -> string : 'S - - > CONCAT / {} : S => "" : S - > CONCAT / { s ; } : S => (s ^ r) : S - where CONCAT / { } : S => r : S - -- ``SIZE``: number of characters in a string. - -:: - - :: string : 'S -> nat : 'S - -- ``SLICE``: String access. - -:: - - :: nat : nat : string : 'S -> option string : 'S - - > SLICE / offset : length : s : S => Some ss : S - where ss is the substring of s at the given offset and of the given length - iff offset and (offset + length) are in bounds - > SLICE / offset : length : s : S => None : S - iff offset or (offset + length) are out of bounds - -- ``COMPARE``: Lexicographic comparison. - -:: - - :: string : string : 'S -> int : 'S - - > COMPARE / s : t : S => -1 : S - iff s < t - > COMPARE / s : t : S => 0 : S - iff s = t - > COMPARE / s : t : S => 1 : S - iff s > t - -Operations on pairs and right combs -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The type ``pair l r`` is the type of binary pairs composed of a left -element of type ``l`` and a right element of type ``r``. A value of -type ``pair l r`` is written ``Pair x y`` where ``x`` is a value of -type ``l`` and ``y`` is a value of type ``r``. - -To build tuples of length greater than 2, right combs have specific -optimized operations. For any ``n > 2``, the compact notations ``pair -t{0} t{1} ... t{n-2} t{n-1}`` is provided for the type of right combs -``pair t{0} (pair t{1} ... (pair t{n-2} t{n-1}) ...)``. Similarly, the -compact notation ``Pair x{0} x{1} ... x{n-2} x{n-1}`` is provided for -the right-comb value ``Pair x{0} (Pair x{1} ... (Pair x{n-2} x{n-1}) -...)``. Right-comb values can also be written using sequences; ``Pair -x{0} x{1} ... x{n-2} x{n-1}`` can be written ``{x{0}; x{1}; ...; x{n-2}; x{n-1}}``. - -- ``PAIR``: Build a binary pair from the stack's top two elements. - -:: - - :: 'a : 'b : 'S -> pair 'a 'b : 'S - - > PAIR / x : y : S => Pair x y : S - -- ``PAIR n``: Fold ``n`` values on the top of the stack in a right comb. - ``PAIR 0`` and ``PAIR 1`` are rejected. ``PAIR 2`` is equivalent to ``PAIR``. - -:: - - PAIR 2 :: 'a : 'b : 'S -> pair 'a 'b : 'S - PAIR (k+1) :: 'x : 'S -> pair 'x 'y : 'T - iff PAIR k :: 'S -> 'y : 'T - - Or equivalently, for n >= 2, - PAIR n :: 'a{0} : ... : 'a{n-1} : 'A -> pair 'a{0} ... 'a{n-1} : 'A - - > PAIR 2 / x : y : S => Pair x y : S - > PAIR (k+1) / x : S => Pair x y : T - iff PAIR k / S => y : T - - Or equivalently, for n >= 2, - > PAIR n / x{0} : ... : x{n-1} : S => Pair x{0} ... x{n-1} : S - -- ``UNPAIR``: Split a pair into its components. - -:: - - :: pair 'a 'b : 'S -> 'a : 'b : 'S - - > UNPAIR / Pair a b : S => a : b : S - - -- ``UNPAIR n``: Unfold ``n`` values from a right comb on the top of the stack. ``UNPAIR 0`` and ``UNPAIR 1`` are rejected. ``UNPAIR 2`` is equivalent to ``UNPAIR``. - -:: - - UNPAIR 2 :: pair 'a 'b : 'A -> 'a : 'b : 'A - UNPAIR (k+1) :: pair 'a 'b : 'A -> 'a : 'B - iff UNPAIR k :: 'b : 'A -> 'B - - Or equivalently, for n >= 2, - UNPAIR n :: pair 'a{0} ... 'a{n-1} : S -> 'a{0} : ... : 'a{n-1} : S - - > UNPAIR 2 / Pair x y : S => x : y : S - > UNPAIR (k+1) / Pair x y : SA => x : SB - iff UNPAIR k / y : SA => SB - - Or equivalently, for n >= 2, - > UNPAIR n / Pair x{0} ... x{n-1} : S => x{0} : ... : x{n-1} : S - -- ``CAR``: Access the left part of a pair. - -:: - - :: pair 'a _ : 'S -> 'a : 'S - - > CAR / Pair x _ : S => x : S - -- ``CDR``: Access the right part of a pair. - -:: - - :: pair _ 'b : 'S -> 'b : 'S - - > CDR / Pair _ y : S => y : S - -- ``GET k``: Access an element or a sub comb in a right comb. - - The nodes of a right comb of size ``n`` are canonically numbered as follows: - -:: - - 0 - / \ - 1 2 - / \ - 3 4 - / \ - 5 ... - 2n-2 - / \ - 2n-1 2n - - -Or in plain English: - - - The root is numbered with 0, - - The left child of the node numbered by ``k`` is numbered by ``k+1``, and - - The right child of the node numbered by ``k`` is numbered by ``k+2``. - -The ``GET k`` instruction accesses the node numbered by ``k``. In -particular, for a comb of size ``n``, the ``n-1`` first elements are -accessed by ``GET 1``, ``GET 3``, ..., and ``GET (2n-1)`` and the last -element is accessed by ``GET (2n)``. - -:: - - GET 0 :: 'a : 'S -> 'a : 'S - GET 1 :: pair 'x _ : 'S -> 'x : 'S - GET (k+2) :: pair _ 'y : 'S -> 'z : 'S - iff GET k :: 'y : 'S -> 'z : 'S - - Or equivalently, - GET 0 :: 'a : 'S -> 'a : 'S - GET (2k) :: pair 'a{0} ... 'a{k-1} 'a{k} : 'S -> 'a{k} : 'S - GET (2k+1) :: pair 'a{0} ... 'a{k} 'a{k+1} : 'S -> 'a{k} : 'S - - > GET 0 / x : S => x : S - > GET 1 / Pair x _ : S => x : S - > GET (k+2) / Pair _ y : S => GET k / y : S - - Or equivalently, - > GET 0 / x : S => x : S - > GET (2k) / Pair x{0} ... x{k-1} x{k} : 'S -> x{k} : 'S - > GET (2k+1) / Pair x{0} ... x{k} x{k+1} : 'S -> x{k} : 'S - - -- ``UPDATE k``: Update an element or a sub comb in a right comb. The topmost stack element is the new value to insert in the comb, the second stack element is the right comb to update. The meaning of ``k`` is the same as for the ``GET k`` instruction. - -:: - - UPDATE 0 :: 'a : 'b : 'S -> 'a : 'S - UPDATE 1 :: 'a2 : pair 'a1 'b : 'S -> pair 'a2 'b : 'S - UPDATE (k+2) :: 'c : pair 'a 'b1 : 'S -> pair 'a 'b2 : 'S - iff UPDATE k :: 'c : 'b1 : 'S -> 'b2 : 'S - - Or equivalently, - UPDATE 0 :: 'a : 'b : 'S -> 'a : 'S - UPDATE (2k) :: 'c : pair 'a{0} ... 'a{k-1} 'a{k} : 'S -> pair 'a{0} ... 'a{k-1} 'c : 'S - UPDATE (2k+1) :: 'c : pair 'a{0} ... 'a{k} 'a{k+1} : 'S -> pair 'a{0} ... 'a{k-1} 'c 'a{k+1} : 'S - - > UPDATE 0 / x : _ : S => x : S - > UPDATE 1 / x2 : Pair x1 y : S => Pair x2 y : S - > UPDATE (k+2) / z : Pair x y1 : S => Pair x y2 : S - iff UPDATE k / z : y1 : S => y2 : S - - Or equivalently, - > UPDATE 0 / x : _ : S => x : S - > UPDATE (2k) / z : Pair x{0} ... x{k-1} x{k} : 'S => Pair x{0} ... x{k-1} z : 'S - > UPDATE (2k+1) / z : Pair x{0} ... x{k-1} x{k} x{k+1} : 'S => Pair x{0} ... x{k-1} z x{k+1} : 'S - -- ``COMPARE``: Lexicographic comparison. - -:: - - :: pair 'a 'b : pair 'a 'b : 'S -> int : 'S - - > COMPARE / (Pair sa sb) : (Pair ta tb) : S => -1 : S - iff COMPARE / sa : ta : S => -1 : S - > COMPARE / (Pair sa sb) : (Pair ta tb) : S => 1 : S - iff COMPARE / sa : ta : S => 1 : S - > COMPARE / (Pair sa sb) : (Pair ta tb) : S => r : S - iff COMPARE / sa : ta : S => 0 : S - COMPARE / sb : tb : S => r : S - -Operations on sets -~~~~~~~~~~~~~~~~~~ - -- ``EMPTY_SET 'elt``: Build a new, empty set for elements of a given - type. - - The ``'elt`` type must be comparable (the ``COMPARE`` - primitive must be defined over it). - -:: - - :: 'S -> set 'elt : 'S - - > EMPTY_SET _ / S => {} : S - -- ``MEM``: Check for the presence of an element in a set. - -:: - - :: 'elt : set 'elt : 'S -> bool : 'S - - > MEM / x : {} : S => false : S - > MEM / x : { hd ; } : S => r : S - iff COMPARE / x : hd : [] => 1 : [] - where MEM / x : { } : S => r : S - > MEM / x : { hd ; } : S => true : S - iff COMPARE / x : hd : [] => 0 : [] - > MEM / x : { hd ; } : S => false : S - iff COMPARE / x : hd : [] => -1 : [] - -- ``UPDATE``: Inserts or removes an element in a set, replacing a - previous value. - -:: - - :: 'elt : bool : set 'elt : 'S -> set 'elt : 'S - - > UPDATE / x : false : {} : S => {} : S - > UPDATE / x : true : {} : S => { x } : S - > UPDATE / x : v : { hd ; } : S => { hd ; } : S - iff COMPARE / x : hd : [] => 1 : [] - where UPDATE / x : v : { } : S => { } : S - > UPDATE / x : false : { hd ; } : S => { } : S - iff COMPARE / x : hd : [] => 0 : [] - > UPDATE / x : true : { hd ; } : S => { hd ; } : S - iff COMPARE / x : hd : [] => 0 : [] - > UPDATE / x : false : { hd ; } : S => { hd ; } : S - iff COMPARE / x : hd : [] => -1 : [] - > UPDATE / x : true : { hd ; } : S => { x ; hd ; } : S - iff COMPARE / x : hd : [] => -1 : [] - -- ``ITER body``: Apply the body expression to each element of a set. - The body sequence has access to the stack. - -:: - - :: (set 'elt) : 'A -> 'A - iff body :: [ 'elt : 'A -> 'A ] - - > ITER body / {} : S => S - > ITER body / { hd ; } : S => ITER body / { } : S' - iff body / hd : S => S' - - -- ``SIZE``: Get the cardinality of the set. - -:: - - :: set 'elt : 'S -> nat : 'S - - > SIZE / {} : S => 0 : S - > SIZE / { _ ; } : S => 1 + s : S - where SIZE / { } : S => s : S - -Operations on maps -~~~~~~~~~~~~~~~~~~ - -- ``EMPTY_MAP 'key 'val``: Build a new, empty map from keys of a - given type to values of another given type. - - The ``'key`` type must be comparable (the ``COMPARE`` primitive must - be defined over it). - -:: - - :: 'S -> map 'key 'val : 'S - - > EMPTY_MAP _ _ / S => {} : S - - -- ``GET``: Access an element in a map, returns an optional value to be - checked with ``IF_SOME``. - -:: - - :: 'key : map 'key 'val : 'S -> option 'val : 'S - - > GET / x : {} : S => None : S - > GET / x : { Elt k v ; } : S => opt_y : S - iff COMPARE / x : k : [] => 1 : [] - where GET / x : { } : S => opt_y : S - > GET / x : { Elt k v ; } : S => Some v : S - iff COMPARE / x : k : [] => 0 : [] - > GET / x : { Elt k v ; } : S => None : S - iff COMPARE / x : k : [] => -1 : [] - -- ``MEM``: Check for the presence of a binding for a key in a map. - -:: - - :: 'key : map 'key 'val : 'S -> bool : 'S - - > MEM / x : {} : S => false : S - > MEM / x : { Elt k v ; } : S => r : S - iff COMPARE / x : k : [] => 1 : [] - where MEM / x : { } : S => r : S - > MEM / x : { Elt k v ; } : S => true : S - iff COMPARE / x : k : [] => 0 : [] - > MEM / x : { Elt k v ; } : S => false : S - iff COMPARE / x : k : [] => -1 : [] - -- ``UPDATE``: Assign or remove an element in a map. - -:: - - :: 'key : option 'val : map 'key 'val : 'S -> map 'key 'val : 'S - - > UPDATE / x : None : {} : S => {} : S - > UPDATE / x : Some y : {} : S => { Elt x y } : S - > UPDATE / x : opt_y : { Elt k v ; } : S => { Elt k v ; } : S - iff COMPARE / x : k : [] => 1 : [] - where UPDATE / x : opt_y : { } : S => { } : S - > UPDATE / x : None : { Elt k v ; } : S => { } : S - iff COMPARE / x : k : [] => 0 : [] - > UPDATE / x : Some y : { Elt k v ; } : S => { Elt k y ; } : S - iff COMPARE / x : k : [] => 0 : [] - > UPDATE / x : None : { Elt k v ; } : S => { Elt k v ; } : S - iff COMPARE / x : k : [] => -1 : [] - > UPDATE / x : Some y : { Elt k v ; } : S => { Elt x y ; Elt k v ; } : S - iff COMPARE / x : k : [] => -1 : [] - -- ``GET_AND_UPDATE``: A combination of the ``GET`` and ``UPDATE`` instructions. - -:: - - :: 'key : option 'val : map 'key 'val : 'S -> option 'val : map 'key 'val : 'S - -This instruction is similar to ``UPDATE`` but it also returns the -value that was previously stored in the ``map`` at the same key as -``GET`` would. - -:: - - > GET_AND_UPDATE / x : None : {} : S => None : {} : S - > GET_AND_UPDATE / x : Some y : {} : S => None : { Elt x y } : S - > GET_AND_UPDATE / x : opt_y : { Elt k v ; } : S => opt_y' : { Elt k v ; } : S - iff COMPARE / x : k : [] => 1 : [] - where GET_AND_UPDATE / x : opt_y : { } : S => opt_y' : { } : S - > GET_AND_UPDATE / x : None : { Elt k v ; } : S => Some v : { } : S - iff COMPARE / x : k : [] => 0 : [] - > GET_AND_UPDATE / x : Some y : { Elt k v ; } : S => Some v : { Elt k y ; } : S - iff COMPARE / x : k : [] => 0 : [] - > GET_AND_UPDATE / x : None : { Elt k v ; } : S => None : { Elt k v ; } : S - iff COMPARE / x : k : [] => -1 : [] - > GET_AND_UPDATE / x : Some y : { Elt k v ; } : S => None : { Elt x y ; Elt k v ; } : S - iff COMPARE / x : k : [] => -1 : [] - -- ``MAP body``: Apply the body expression to each element of a map. The - body sequence has access to the stack. - -:: - - :: (map 'key 'val) : 'A -> (map 'key 'b) : 'A - iff body :: [ (pair 'key 'val) : 'A -> 'b : 'A ] - - > MAP body / {} : S => {} : S - > MAP body / { Elt k v ; } : S => { Elt k v' ; } : S'' - where body / Pair k v : S => v' : S' - and MAP body / { } : S' => { } : S'' - -- ``ITER body``: Apply the body expression to each element of a map. - The body sequence has access to the stack. - -:: - - :: (map 'elt 'val) : 'A -> 'A - iff body :: [ (pair 'elt 'val : 'A) -> 'A ] - - > ITER body / {} : S => S - > ITER body / { Elt k v ; } : S => ITER body / { } : S' - iff body / (Pair k v) : S => S' - -- ``SIZE``: Get the cardinality of the map. - -:: - - :: map 'key 'val : 'S -> nat : 'S - - > SIZE / {} : S => 0 : S - > SIZE / { _ ; } : S => 1 + s : S - where SIZE / { } : S => s : S - - -Operations on ``big_maps`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. _OperationsOnBigMaps_012: - -Big maps have three possible representations. A map literal is always -a valid representation for a big map. Big maps can also be represented -by integers called big-map identifiers. Finally, big maps can be -represented as pairs of a big-map identifier (an integer) and a -big-map diff (written in the same syntax as a map whose values are -options). - -So for example, ``{ Elt "bar" True ; Elt "foo" False }``, ``42``, and -``Pair 42 { Elt "foo" (Some False) }`` are all valid representations -of type ``big_map string bool``. - -The behavior of big-map operations is the same as if they were normal -maps, except that under the hood, the elements are loaded and -deserialized on demand. - -- ``EMPTY_BIG_MAP 'key 'val``: Build a new, empty big map from keys of a - given type to values of another given type. - - The ``'key`` type must be comparable (the ``COMPARE`` primitive must - be defined over it). - -:: - - :: 'S -> map 'key 'val : 'S - -- ``GET``: Access an element in a ``big_map``, returns an optional value to be - checked with ``IF_SOME``. - -:: - - :: 'key : big_map 'key 'val : 'S -> option 'val : 'S - -- ``MEM``: Check for the presence of an element in a ``big_map``. - -:: - - :: 'key : big_map 'key 'val : 'S -> bool : 'S - -- ``UPDATE``: Assign or remove an element in a ``big_map``. - -:: - - :: 'key : option 'val : big_map 'key 'val : 'S -> big_map 'key 'val : 'S - - -- ``GET_AND_UPDATE``: A combination of the ``GET`` and ``UPDATE`` instructions. - -:: - - :: 'key : option 'val : big_map 'key 'val : 'S -> option 'val : big_map 'key 'val : 'S - -This instruction is similar to ``UPDATE`` but it also returns the -value that was previously stored in the ``big_map`` at the same key as -``GET`` would. - - -Operations on optional values -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``SOME``: Pack a value as an optional value. - -:: - - :: 'a : 'S -> option 'a : 'S - - > SOME / v : S => (Some v) : S - -- ``NONE 'a``: The absent optional value. - -:: - - :: 'S -> option 'a : 'S - - > NONE / S => None : S - -- ``IF_NONE bt bf``: Inspect an optional value. - -:: - - :: option 'a : 'A -> 'B - iff bt :: [ 'A -> 'B] - bf :: [ 'a : 'A -> 'B] - - > IF_NONE bt bf / (None) : S => bt / S - > IF_NONE bt bf / (Some a) : S => bf / a : S - -- ``COMPARE``: Optional values comparison - -:: - - :: option 'a : option 'a : 'S -> int : 'S - - > COMPARE / None : None : S => 0 : S - > COMPARE / None : (Some _) : S => -1 : S - > COMPARE / (Some _) : None : S => 1 : S - > COMPARE / (Some a) : (Some b) : S => COMPARE / a : b : S - -- ``MAP body``: Apply the body expression to the value inside the option if there is one. - -:: - - :: option 'a : 'S -> option 'b : 'S - iff body :: [ 'a : 'S -> 'b : 'S ] - - > MAP body / None : S => None : S - > MAP body / (Some a) : S => (Some b) : S' - where body / a : S => b : S' - -Operations on unions -~~~~~~~~~~~~~~~~~~~~ - -- ``LEFT 'b``: Pack a value in a union (left case). - -:: - - :: 'a : 'S -> or 'a 'b : 'S - - > LEFT / v : S => (Left v) : S - -- ``RIGHT 'a``: Pack a value in a union (right case). - -:: - - :: 'b : 'S -> or 'a 'b : 'S - - > RIGHT / v : S => (Right v) : S - -- ``IF_LEFT bt bf``: Inspect a value of a union. - -:: - - :: or 'a 'b : 'A -> 'B - iff bt :: [ 'a : 'A -> 'B] - bf :: [ 'b : 'A -> 'B] - - > IF_LEFT bt bf / (Left a) : S => bt / a : S - > IF_LEFT bt bf / (Right b) : S => bf / b : S - -- ``COMPARE``: Unions comparison - -:: - - :: or 'a 'b : or 'a 'b : 'S -> int : 'S - - > COMPARE / (Left a) : (Left b) : S => COMPARE / a : b : S - > COMPARE / (Left _) : (Right _) : S => -1 : S - > COMPARE / (Right _) : (Left _) : S => 1 : S - > COMPARE / (Right a) : (Right b) : S => COMPARE / a : b : S - -Operations on lists -~~~~~~~~~~~~~~~~~~~ - -- ``CONS``: Prepend an element to a list. - -:: - - :: 'a : list 'a : 'S -> list 'a : 'S - - > CONS / a : { } : S => { a ; } : S - -- ``NIL 'a``: The empty list. - -:: - - :: 'S -> list 'a : 'S - - > NIL / S => {} : S - -- ``IF_CONS bt bf``: Inspect a list. - -:: - - :: list 'a : 'A -> 'B - iff bt :: [ 'a : list 'a : 'A -> 'B] - bf :: [ 'A -> 'B] - - > IF_CONS bt bf / { a ; } : S => bt / a : { } : S - > IF_CONS bt bf / {} : S => bf / S - -- ``MAP body``: Apply the body expression to each element of the list. - The body sequence has access to the stack. - -:: - - :: (list 'elt) : 'A -> (list 'b) : 'A - iff body :: [ 'elt : 'A -> 'b : 'A ] - - > MAP body / {} : S => {} : S - > MAP body / { a ; } : S => { b ; } : S'' - where body / a : S => b : S' - and MAP body / { } : S' => { } : S'' - -- ``SIZE``: Get the number of elements in the list. - -:: - - :: list 'elt : 'S -> nat : 'S - - > SIZE / { _ ; } : S => 1 + s : S - where SIZE / { } : S => s : S - > SIZE / {} : S => 0 : S - - -- ``ITER body``: Apply the body expression to each element of a list. - The body sequence has access to the stack. - -:: - - :: (list 'elt) : 'A -> 'A - iff body :: [ 'elt : 'A -> 'A ] - > ITER body / {} : S => S - > ITER body / { a ; } : S => ITER body / { } : S' - iff body / a : S => S' - - -Domain specific data types --------------------------- - -- ``timestamp``: Dates in the real world. - -- ``mutez``: A specific type for manipulating tokens. - -- ``address``: An untyped address (implicit account or smart contract). - -- ``contract 'param``: A contract, with the type of its code, - ``contract unit`` for implicit accounts. - -- ``operation``: An internal operation emitted by a contract. - -- ``key``: A public cryptographic key. - -- ``key_hash``: The hash of a public cryptographic key. - -- ``signature``: A cryptographic signature. - -- ``chain_id``: An identifier for a chain, used to distinguish the test and the main chains. - -- ``bls12_381_g1``, ``bls12_381_g2`` : Points on the BLS12-381 curves G\ :sub:`1`\ and G\ :sub:`2`\ , respectively. - -- ``bls12_381_fr`` : An element of the scalar field F\ :sub:`r`\ , used for scalar multiplication on the BLS12-381 curves G\ :sub:`1`\ and G\ :sub:`2`\ . - -- ``sapling_transaction ms``: A :doc:`Sapling ` transaction - -- ``sapling_state ms``: A :doc:`Sapling ` state - -- ``ticket (t)``: A ticket used to authenticate information of type ``(t)`` on-chain. - -- ``chest``: a timelocked chest containing bytes and information to open it. - see :doc:`Timelock ` . - -- ``chest_key``: used to open a chest, also contains a proof - to check the correctness of the opening. see :doc:`Timelock ` . - - -Domain specific operations --------------------------- - -Operations on timestamps -~~~~~~~~~~~~~~~~~~~~~~~~ - -Timestamps can be obtained by the ``NOW`` operation, or retrieved from -script parameters or globals. - -- ``ADD`` Increment / decrement a timestamp of the given number of - seconds. - -:: - - :: timestamp : int : 'S -> timestamp : 'S - :: int : timestamp : 'S -> timestamp : 'S - - > ADD / seconds : nat (t) : S => (seconds + t) : S - > ADD / nat (t) : seconds : S => (t + seconds) : S - -- ``SUB`` Subtract a number of seconds from a timestamp. - -:: - - :: timestamp : int : 'S -> timestamp : 'S - - > SUB / seconds : nat (t) : S => (seconds - t) : S - -- ``SUB`` Subtract two timestamps. - -:: - - :: timestamp : timestamp : 'S -> int : 'S - - > SUB / seconds(t1) : seconds(t2) : S => (t1 - t2) : S - -- ``COMPARE``: Timestamp comparison. - -:: - - :: timestamp : timestamp : 'S -> int : 'S - - > COMPARE / seconds(t1) : seconds(t2) : S => -1 : S - iff t1 < t2 - > COMPARE / seconds(t1) : seconds(t2) : S => 0 : S - iff t1 = t2 - > COMPARE / seconds(t1) : seconds(t2) : S => 1 : S - iff t1 > t2 - - -Operations on Mutez -~~~~~~~~~~~~~~~~~~~ - -Mutez (micro-Tez) are internally represented by a 64 bit signed -integers. There are restrictions to prevent creating a negative amount -of mutez. Operations are limited to prevent overflow and mixing them -with other numerical types by mistake. They are also mandatory checked -for under/overflows. - -- ``ADD`` - -:: - - :: mutez : mutez : 'S -> mutez : 'S - - > ADD / x : y : S => [FAILED] on overflow - > ADD / x : y : S => (x + y) : S - -- ``SUB_MUTEZ`` - -:: - - :: mutez : mutez : 'S -> option mutez : 'S - - > SUB_MUTEZ / x : y : S => None - iff x < y - > SUB_MUTEZ / x : y : S => Some (x - y) : S - -- ``MUL`` - -:: - - :: mutez : nat : 'S -> mutez : 'S - :: nat : mutez : 'S -> mutez : 'S - - > MUL / x : y : S => [FAILED] on overflow - > MUL / x : y : S => (x * y) : S - -- ``EDIV`` - -:: - - :: mutez : nat : 'S -> option (pair mutez mutez) : 'S - :: mutez : mutez : 'S -> option (pair nat mutez) : 'S - - > EDIV / x : 0 : S => None - > EDIV / x : y : S => Some (Pair (x / y) (x % y)) : S - iff y <> 0 - -- ``COMPARE``: Mutez comparison - -:: - - :: mutez : mutez : 'S -> int : 'S - - > COMPARE / x : y : S => -1 : S - iff x < y - > COMPARE / x : y : S => 0 : S - iff x = y - > COMPARE / x : y : S => 1 : S - iff x > y - -Operations on contracts -~~~~~~~~~~~~~~~~~~~~~~~ - -- ``CREATE_CONTRACT { storage 'g ; parameter 'p ; code ... }``: - Forge a new contract from a literal. - -:: - - :: option key_hash : mutez : 'g : 'S - -> operation : address : 'S - -Originate a contract based on a literal. The parameters are the -optional delegate, the initial amount taken from the current -contract, and the initial storage of the originated contract. -The contract is returned as a first class value (to be dropped, passed -as parameter or stored). The ``CONTRACT 'p`` instruction will fail -until it is actually originated. - -- ``TRANSFER_TOKENS``: Forge a transaction. - -:: - - :: 'p : mutez : contract 'p : 'S -> operation : 'S - -The parameter must be consistent with the one expected by the -contract, unit for an account. - -.. _MichelsonSetDelegate_012: - -- ``SET_DELEGATE``: Set or withdraw the contract's delegation. - -:: - - :: option key_hash : 'S -> operation : 'S - -Using this instruction is the only way to modify the delegation of a -smart contract. If the parameter is ``None`` then the delegation of the -current contract is withdrawn; if it is ``Some kh`` where ``kh`` is the -key hash of a registered delegate that is not the current delegate of -the contract, then this operation sets the delegate of the contract to -this registered delegate. The operation fails if ``kh`` is the current -delegate of the contract or if ``kh`` is not a registered delegate. - -- ``BALANCE``: Push the current amount of mutez held by the executing - contract, including any mutez added by the calling transaction. - -:: - - :: 'S -> mutez : 'S - -- ``ADDRESS``: Cast the contract to its address. - -:: - - :: contract _ : 'S -> address : 'S - - > ADDRESS / addr : S => addr : S - -- ``CONTRACT 'p``: Cast the address to the given contract type if possible. - -:: - - :: address : 'S -> option (contract 'p) : 'S - - > CONTRACT / addr : S => Some addr : S - iff addr exists and is a contract of parameter type 'p - > CONTRACT / addr : S => Some addr : S - iff 'p = unit and addr is an implicit contract - > CONTRACT / addr : S => None : S - otherwise - -- ``SOURCE``: Push the contract that initiated the current - transaction, i.e. the contract that paid the fees and - storage cost, and whose manager signed the operation - that was sent on the blockchain. Note that since - ``TRANSFER_TOKENS`` instructions can be chained, - ``SOURCE`` and ``SENDER`` are not necessarily the same. - -:: - - :: 'S -> address : 'S - -- ``SENDER``: Push the contract that initiated the current - internal transaction. It may be the ``SOURCE``, but may - also be different if the source sent an order to an intermediate - smart contract, which then called the current contract. - -:: - - :: 'S -> address : 'S - -- ``SELF``: Push the current contract. - -:: - - :: 'S -> contract 'p : 'S - where contract 'p is the type of the current contract - -Note that ``SELF`` is forbidden in lambdas because it cannot be -type-checked; the type of the contract executing the lambda cannot be -known at the point of type-checking the lambda's body. - -- ``SELF_ADDRESS``: Push the address of the current contract. This is - equivalent to ``SELF; ADDRESS`` except that it is allowed in - lambdas. - -:: - - :: 'S -> address : 'S - -Note that ``SELF_ADDRESS`` inside a lambda returns the address of the -contract executing the lambda, which can be different from the address -of the contract in which the ``SELF_ADDRESS`` instruction is written. - -- ``AMOUNT``: Push the amount of the current transaction. - -:: - - :: 'S -> mutez : 'S - -- ``IMPLICIT_ACCOUNT``: Return a default contract with the given - public/private key pair. Any funds deposited in this contract can - immediately be spent by the holder of the private key. This contract - cannot execute Michelson code and will always exist on the - blockchain. - -:: - - :: key_hash : 'S -> contract unit : 'S - -- ``VOTING_POWER``: Return the voting power of a given contract. This voting power - coincides with the weight of the contract in the voting listings (i.e., the rolls - count) which is calculated at the beginning of every voting period. - -:: - - :: key_hash : 'S -> nat : 'S - -Special operations -~~~~~~~~~~~~~~~~~~ - -- ``NOW``: Push the minimal injection time for the current block, - namely the block whose validation triggered this execution. The - minimal injection time is 60 seconds after the timestamp of the - predecessor block. This value does not change during the execution - of the contract. - -:: - - :: 'S -> timestamp : 'S - -- ``CHAIN_ID``: Push the chain identifier. - -:: - - :: 'S -> chain_id : 'S - -- ``COMPARE``: Chain identifier comparison - -:: - - :: chain_id : chain_id : 'S -> int : 'S - - > COMPARE / x : y : S => -1 : S - iff x < y - > COMPARE / x : y : S => 0 : S - iff x = y - > COMPARE / x : y : S => 1 : S - iff x > y - -- ``LEVEL``: Push the level of the current transaction's block. - -:: - - :: 'S -> nat : 'S - -- ``TOTAL_VOTING_POWER``: Return the total voting power of all contracts. The total - voting power coincides with the sum of the rolls count of every contract in the voting - listings. The voting listings is calculated at the beginning of every voting period. - -:: - - :: 'S -> nat : 'S - -Operations on bytes -~~~~~~~~~~~~~~~~~~~ - -Bytes are used for serializing data, in order to check signatures and -compute hashes on them. They can also be used to incorporate data from -the wild and untyped outside world. - -- ``PACK``: Serializes a piece of data to its optimized - binary representation. - -:: - - :: 'a : 'S -> bytes : 'S - -- ``UNPACK 'a``: Deserializes a piece of data, if valid. - -:: - - :: bytes : 'S -> option 'a : 'S - -- ``CONCAT``: Byte sequence concatenation. - -:: - - :: bytes : bytes : 'S -> bytes : 'S - - > CONCAT / s : t : S => (s ^ t) : S - - :: bytes list : 'S -> bytes : 'S - - > CONCAT / {} : S => 0x : S - > CONCAT / { s ; } : S => (s ^ r) : S - where CONCAT / { } : S => r : S - -- ``SIZE``: size of a sequence of bytes. - -:: - - :: bytes : 'S -> nat : 'S - -- ``SLICE``: Bytes access. - -:: - - :: nat : nat : bytes : 'S -> option bytes : 'S - - > SLICE / offset : length : s : S => Some ss : S - where ss is the substring of s at the given offset and of the given length - iff offset and (offset + length) are in bounds - > SLICE / offset : length : s : S => None : S - iff offset or (offset + length) are out of bounds - -- ``COMPARE``: Lexicographic comparison. - -:: - - :: bytes : bytes : 'S -> int : 'S - - > COMPARE / s : t : S => -1 : S - iff s < t - > COMPARE / s : t : S => 0 : S - iff s = t - > COMPARE / s : t : S => 1 : S - iff s > t - - -Cryptographic primitives -~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``HASH_KEY``: Compute the b58check of a public key. - -:: - - :: key : 'S -> key_hash : 'S - -- ``BLAKE2B``: Compute a cryptographic hash of the value contents using the - Blake2b-256 cryptographic hash function. - -:: - - :: bytes : 'S -> bytes : 'S - -- ``KECCAK``: Compute a cryptographic hash of the value contents using the - Keccak-256 cryptographic hash function. - -:: - - :: bytes : 'S -> bytes : 'S - -- ``SHA256``: Compute a cryptographic hash of the value contents using the - Sha256 cryptographic hash function. - -:: - - :: bytes : 'S -> bytes : 'S - -- ``SHA512``: Compute a cryptographic hash of the value contents using the - Sha512 cryptographic hash function. - -:: - - :: bytes : 'S -> bytes : 'S - -- ``SHA3``: Compute a cryptographic hash of the value contents using the - SHA3-256 cryptographic hash function. - -:: - - :: bytes : 'S -> bytes : 'S - -- ``CHECK_SIGNATURE``: Check that a sequence of bytes has been signed - with a given key. - -:: - - :: key : signature : bytes : 'S -> bool : 'S - -- ``COMPARE``: Key hash, key and signature comparison - -:: - - :: key_hash : key_hash : 'S -> int : 'S - :: key : key : 'S -> int : 'S - :: signature : signature : 'S -> int : 'S - - > COMPARE / x : y : S => -1 : S - iff x < y - > COMPARE / x : y : S => 0 : S - iff x = y - > COMPARE / x : y : S => 1 : S - iff x > y - -BLS12-381 primitives -~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``NEG``: Negate a curve point or field element. - -:: - - :: bls12_381_g1 : 'S -> bls12_381_g1 : 'S - :: bls12_381_g2 : 'S -> bls12_381_g2 : 'S - :: bls12_381_fr : 'S -> bls12_381_fr : 'S - -- ``ADD``: Add two curve points or field elements. - -:: - - :: bls12_381_g1 : bls12_381_g1 : 'S -> bls12_381_g1 : 'S - :: bls12_381_g2 : bls12_381_g2 : 'S -> bls12_381_g2 : 'S - :: bls12_381_fr : bls12_381_fr : 'S -> bls12_381_fr : 'S - -- ``MUL``: Multiply a curve point or field element by a scalar field element. Fr - elements can be built from naturals by multiplying by the unit of Fr using ``PUSH bls12_381_fr 1; MUL``. Note - that the multiplication will be computed using the natural modulo the order - of Fr. - -:: - - :: bls12_381_g1 : bls12_381_fr : 'S -> bls12_381_g1 : 'S - :: bls12_381_g2 : bls12_381_fr : 'S -> bls12_381_g2 : 'S - :: bls12_381_fr : bls12_381_fr : 'S -> bls12_381_fr : 'S - :: nat : bls12_381_fr : 'S -> bls12_381_fr : 'S - :: int : bls12_381_fr : 'S -> bls12_381_fr : 'S - :: bls12_381_fr : nat : 'S -> bls12_381_fr : 'S - :: bls12_381_fr : int : 'S -> bls12_381_fr : 'S - -- ``INT``: Convert a field element to type ``int``. The returned value is always between ``0`` (inclusive) and the order of Fr (exclusive). - -:: - - :: bls12_381_fr : 'S -> int : 'S - -- ``PAIRING_CHECK``: - Verify that the product of pairings of the given list of points is equal to 1 in Fq12. Returns ``true`` if the list is empty. - Can be used to verify if two pairings P1 and P2 are equal by verifying P1 * P2^(-1) = 1. - -:: - - :: list (pair bls12_381_g1 bls12_381_g2) : 'S -> bool : 'S - - -Sapling operations -~~~~~~~~~~~~~~~~~~ - -Please see the :doc:`Sapling integration` page for a more -comprehensive description of the Sapling protocol. - -- ``SAPLING_VERIFY_UPDATE``: verify and apply a transaction on a Sapling state. - -:: - - :: sapling_transaction ms : sapling_state ms : 'S -> option (pair int (sapling_state ms)): 'S - - > SAPLING_VERIFY_UPDATE / t : s : S => Some (Pair b s') : S - iff the transaction t successfully applied on state s resulting - in balance b and an updated state s' - > SAPLING_VERIFY_UPDATE / t : s : S => None : S - iff the transaction t is invalid with respect to the state - -- ``SAPLING_EMPTY_STATE ms``: Pushes an empty state on the stack. - - :: - - :: 'S -> sapling_state ms: 'S - - > SAPLING_EMPTY_STATE ms / S => sapling_state ms : S - with `sapling_state ms` being the empty state (ie. no one can spend tokens from it) - with memo_size `ms` - - -.. _MichelsonTickets_012: - -Operations on tickets -~~~~~~~~~~~~~~~~~~~~~ - -The following operations deal with tickets. Tickets are a way for smart-contracts -to authenticate data with respect to a Tezos address. This authentication can -then be used to build composable permission systems. - -A contract can create a ticket from a value and an amount. The ticket, when -inspected reveals the value, the amount, and the address of the ticketer (the contract that created the ticket). It is -impossible for a contract to “forge” a ticket that appears to have been created -by another ticketer. - -The amount is a meta-data that can be used to implement UTXOs. - -Tickets cannot be duplicated using the ``DUP`` instruction. - -For example, a ticket could represent a Non Fungible Token (NFT) or a Unspent -Transaction Output (UTXO) which can then be passed around and behave like a value. -This process can happen without the need to interact with a centralized NFT contract, -simplifying the code. - -- ``TICKET``: Create a ticket with the given content and amount. The ticketer is the address - of `SELF`. - -:: - - :: 'a : nat : 'S -> ticket 'a : 'S - -Type ``'a`` must be comparable (the ``COMPARE`` primitive must be defined over it). - -- ``READ_TICKET``: Retrieve the information stored in a ticket. Also return the ticket. - -:: - - :: ticket 'a : 'S -> pair address 'a nat : ticket 'a : 'S - -- ``SPLIT_TICKET``: Delete the given ticket and create two tickets with the - same content and ticketer as the original, but with the new provided amounts. - (This can be used to easily implement UTXOs.) - Return None iff the ticket's original amount is not equal to the sum of the - provided amounts. - -:: - - :: ticket 'a : (pair nat nat) : 'S -> - option (pair (ticket 'a) (ticket 'a)) : 'S - -- ``JOIN_TICKETS``: The inverse of ``SPLIT_TICKET``. Delete the given tickets and create a ticket with an amount equal to the - sum of the amounts of the input tickets. - (This can be used to consolidate UTXOs.) - Return None iff the input tickets have a different ticketer or content. - -:: - - :: (pair (ticket 'a) (ticket 'a)) : 'S -> - option (ticket 'a) : 'S - -Operations on timelock -~~~~~~~~~~~~~~~~~~~~~~ - -- ``OPEN_CHEST``: opens a timelocked chest given its key and the time. The results can be bytes - if the opening is correct, or a boolean indicating whether the chest was incorrect, - or its opening was. See :doc:`Timelock ` for more information. - -:: - - :: chest_key : chest : nat : 'S -> or bytes bool : 'S - - - -Removed instructions -~~~~~~~~~~~~~~~~~~~~ - -:doc:`../protocols/005_babylon` deprecated the following instructions. Because no smart -contract used these on Mainnet before they got deprecated, they have been -removed. The Michelson type-checker will reject any contract using them. - -- ``CREATE_CONTRACT { storage 'g ; parameter 'p ; code ... }``: - Forge a new contract from a literal. - -:: - - :: key_hash : option key_hash : bool : bool : mutez : 'g : 'S - -> operation : address : 'S - -See the documentation of the new ``CREATE_CONTRACT`` instruction. The -first, third, and fourth parameters are ignored. - -- ``CREATE_ACCOUNT``: Forge an account creation operation. - -:: - - :: key_hash : option key_hash : bool : mutez : 'S - -> operation : address : 'S - -Takes as argument the manager, optional delegate, the delegatable flag -and finally the initial amount taken from the currently executed -contract. This instruction originates a contract with two entrypoints; -``%default`` of type ``unit`` that does nothing and ``%do`` of type -``lambda unit (list operation)`` that executes and returns the -parameter if the sender is the contract's manager. - -- ``STEPS_TO_QUOTA``: Push the remaining steps before the contract - execution must terminate. - -:: - - :: 'S -> nat : 'S - -.. _MichelsonViews_012: - -Operations on views -~~~~~~~~~~~~~~~~~~~~ - -Views are a mechanism for contract calls that: - -- are read-only: they may depend on the storage of the contract declaring the view but cannot modify it nor emit operations (but they can call other views), -- take arguments as input in addition to the contract storage, -- return results as output, -- are synchronous: the result is immediately available on the stack of the caller contract. - -In other words, the execution of a view is included in the operation of caller's contract, but accesses the storage of the declarer's contract, in read-only mode. -Thus, in terms of execution, views are more like lambda functions rather than contract entrypoints, -Here is an example: - -:: - - code { - ...; - TRANSFER_TOKENS; - ...; - VIEW "view_ex" unit; - ...; - }; - -This contract calls a contract ``TRANSFER_TOKENS``, and, later on, a view called "view_ex". -No matter if the callee "view_ex" is defined in the same contract with this caller contract or not, -this view will be executed immediately in the current operation, -while the operations emitted by ``TRANSFER_TOKENS`` will be executed later on. -As a result, although it may seem that "view_ex" receives the storage modified by ``TRANSFER_TOKENS``, -this is not the case. -In other words, the storage of the view is the same as when the current contract was called. -In particular, in case of re-entrance, i.e., if a contract A calls a contract B that calls a view on A, the storage of the view will be the same as when B started, not when A started. - -Views are **declared** at the toplevel of the script of the contract on which they operate, -alongside the contract parameter type, storage type, and code. -To declare a view, the ``view`` keyword is used; its syntax is -``view name 'arg 'return { instr; ... }`` where: - -- ``name`` is a string of at most 31 characters matching the regular expression ``[a-zA-Z0-9_.%@]*``; it is used to identify the view, hence it must be different from the names of the other views declared in the same script; -- ``'arg`` is the type of the argument of the view; -- ``'return`` is the type of the result returned by the view; -- ``{ instr; ... }`` is a sequence of instructions of type ``lambda (pair 'arg 'storage_ty) 'return`` where ``'storage_ty`` is the type of the storage of the current contract. Certain specific instructions have different semantics in ``view``: ``BALANCE`` represents the current amount of mutez held by the contract where ``view`` is; ``SENDER`` represents the contract which is the caller of ``view``; ``SELF_ADDRESS`` represents the contract where ``view`` is; ``AMOUNT`` is always 0 mutez. - -Note that in both view input (type ``'arg``) and view output (type ``'return``), the following types are forbidden: ``ticket``, ``operation``, ``big_map`` and ``sapling_state``. - -Views are **called** using the following Michelson instruction: - -- ``VIEW name 'return``: Call the view named ``name`` from the contract whose address is the second element of the stack, sending it as input the top element of the stack. - -:: - - :: 'arg : address : 'S -> option 'return : 'S - - > VIEW name 'return / x : addr : S => Some y : S - iff addr is the address of a smart contract c with storage s - where c has a toplevel declaration of the form "view name 'arg 'return { code }" - and code / Pair x s : [] => y : [] - - > VIEW name 'return / _ : _ : S => None : S - otherwise - - - -If the given address is nonexistent or if the contract at that address does not have a view of the expected name and type, -``None`` will be returned. -Otherwise, ``Some a`` will be returned where ``a`` is the result of the view call. -Note that if a contract address containing an entrypoint ``address%entrypoint`` is provided, -only the ``address`` part will be taken. -``operation``, ``big_map`` and ``sapling_state`` and ``ticket`` types are forbidden for the ``'return`` type. - - -Here is an example using views, consisting of two contracts. -The first contract defines two views at toplevel that are named ``add_v`` and ``mul_v``. - -:: - - { parameter nat; - storage nat; - code { CAR; NIL operation ; PAIR }; - view "add_v" nat nat { UNPAIR; ADD }; - view "mul_v" nat nat { UNPAIR; MUL }; - } - - -The second contract calls the ``add_v`` view of the above contract and obtains a result immediately. - -:: - - { parameter (pair nat address) ; - storage nat ; - code { CAR ; UNPAIR; VIEW "add_v" nat ; - IF_SOME { } { FAIL }; NIL operation; PAIR }; } - -Macros ------- - -In addition to the operations above, several extensions have been added -to the language's concrete syntax. If you are interacting with the node -via RPC, bypassing the client, which expands away these macros, you will -need to desugar them yourself. - -These macros are designed to be unambiguous and reversible, meaning that -errors are reported in terms of desugared syntax. Below you'll see -these macros defined in terms of other syntactic forms. That is how -these macros are seen by the node. - -Compare -~~~~~~~ - -Syntactic sugar exists for merging ``COMPARE`` and comparison -combinators, and also for branching. - -- ``CMP{EQ|NEQ|LT|GT|LE|GE}`` - -:: - - > CMP(\op) / S => COMPARE ; (\op) / S - -- ``IF{EQ|NEQ|LT|GT|LE|GE} bt bf`` - -:: - - > IF(\op) bt bf / S => (\op) ; IF bt bf / S - -- ``IFCMP{EQ|NEQ|LT|GT|LE|GE} bt bf`` - -:: - - > IFCMP(\op) / S => COMPARE ; (\op) ; IF bt bf / S - -Fail -~~~~ - -The ``FAIL`` macros is equivalent to ``UNIT; FAILWITH`` and is callable -in any context since it does not use its input stack. - -- ``FAIL`` - -:: - - > FAIL / S => UNIT; FAILWITH / S - -Assertion macros -~~~~~~~~~~~~~~~~ - -All assertion operations are syntactic sugar for conditionals with a -``FAIL`` instruction in the appropriate branch. When possible, use them -to increase clarity about illegal states. - -- ``ASSERT`` - -:: - - > ASSERT => IF {} {FAIL} - -- ``ASSERT_{EQ|NEQ|LT|LE|GT|GE}`` - -:: - - > ASSERT_(\op) => IF(\op) {} {FAIL} - -- ``ASSERT_CMP{EQ|NEQ|LT|LE|GT|GE}`` - -:: - - > ASSERT_CMP(\op) => IFCMP(\op) {} {FAIL} - -- ``ASSERT_NONE`` - -:: - - > ASSERT_NONE => IF_NONE {} {FAIL} - -- ``ASSERT_SOME`` - -:: - - > ASSERT_SOME @x => IF_NONE {FAIL} {RENAME @x} - -- ``ASSERT_LEFT`` - -:: - - > ASSERT_LEFT @x => IF_LEFT {RENAME @x} {FAIL} - -- ``ASSERT_RIGHT`` - -:: - - > ASSERT_RIGHT @x => IF_LEFT {FAIL} {RENAME @x} - -Syntactic Conveniences -~~~~~~~~~~~~~~~~~~~~~~ - -These macros are simply more convenient syntax for various common -operations. - -- ``P(\left=A|P(\left)(\right))(\right=I|P(\left)(\right))R``: A syntactic sugar - for building nested pairs. In the case of right combs, `PAIR n` is more efficient. - -:: - - > PA(\right)R / S => DIP ((\right)R) ; PAIR / S - > P(\left)IR / S => (\left)R ; PAIR / S - > P(\left)(\right)R => (\left)R ; DIP ((\right)R) ; PAIR / S - -A good way to quickly figure which macro to use is to mentally parse the -macro as ``P`` for pair constructor, ``A`` for left leaf and ``I`` for -right leaf. The macro takes as many elements on the stack as there are -leaves and constructs a nested pair with the shape given by its name. - -Take the macro ``PAPPAIIR`` for instance: - -:: - - P A P P A I I R - ( l, ( ( l, r ), r )) - -A typing rule can be inferred: - -:: - - PAPPAIIR - :: 'a : 'b : 'c : 'd : 'S -> (pair 'a (pair (pair 'b 'c) 'd)) - -- ``UNP(\left=A|P(\left)(\right))(\right=I|P(\left)(\right))R``: A syntactic sugar - for destructing nested pairs. These macros follow the same convention - as the previous one. - -:: - - > UNPA(\right)R / S => UNPAIR ; DIP (UN(\right)R) / S - > UNP(\left)IR / S => UNPAIR ; UN(\left)R / S - > UNP(\left)(\right)R => UNPAIR ; DIP (UN(\right)R) ; UN(\left)R / S - -- ``C[AD]+R``: A syntactic sugar for accessing fields in nested pairs. In the case of right combs, ``CAR k`` and ``CDR k`` are more efficient. - -:: - - > CA(\rest=[AD]+)R / S => CAR ; C(\rest)R / S - > CD(\rest=[AD]+)R / S => CDR ; C(\rest)R / S - -- ``CAR k``: Access the ``k`` -th part of a right comb of size ``n > k + 1``. ``CAR 0`` is equivalent to ``CAR`` and in general ``CAR k`` is equivalent to ``k`` times the ``CDR`` instruction followed by once the ``CAR`` instruction. Note that this instruction cannot access the last element of a right comb; ``CDR k`` should be used for that. - -:: - - > CAR n / S => GET (2n+1) / S - -- ``CDR k``: Access the rightmost element of a right comb of size ``k``. ``CDR 0`` is a no-op, ``CDR 1`` is equivalent to ``CDR`` and in general ``CDR k`` is equivalent to ``k`` times the ``CDR`` instruction. Note that on a right comb of size ``n > k >= 2``, ``CDR k`` will return the right comb composed of the same elements but the ``k`` leftmost ones. - -:: - - > CDR n / S => GET (2n) / S - -- ``IF_SOME bt bf``: Inspect an optional value. - -:: - - > IF_SOME bt bf / S => IF_NONE bf bt / S - -- ``IF_RIGHT bt bf``: Inspect a value of a union. - -:: - - > IF_RIGHT bt bf / S => IF_LEFT bf bt / S - -- ``SET_CAR``: Set the left field of a pair. This is equivalent to ``SWAP; UPDATE 1``. - -:: - - > SET_CAR => CDR ; SWAP ; PAIR - -- ``SET_CDR``: Set the right field of a pair. This is equivalent to ``SWAP; UPDATE 2``. - -:: - - > SET_CDR => CAR ; PAIR - -- ``SET_C[AD]+R``: A syntactic sugar for setting fields in nested - pairs. In the case of right combs, `UPDATE n` is more efficient. - -:: - - > SET_CA(\rest=[AD]+)R / S => - { DUP ; DIP { CAR ; SET_C(\rest)R } ; CDR ; SWAP ; PAIR } / S - > SET_CD(\rest=[AD]+)R / S => - { DUP ; DIP { CDR ; SET_C(\rest)R } ; CAR ; PAIR } / S - -- ``MAP_CAR`` code: Transform the left field of a pair. - -:: - - > MAP_CAR code => DUP ; CDR ; DIP { CAR ; code } ; SWAP ; PAIR - -- ``MAP_CDR`` code: Transform the right field of a pair. - -:: - - > MAP_CDR code => DUP ; CDR ; code ; SWAP ; CAR ; PAIR - -- ``MAP_C[AD]+R`` code: A syntactic sugar for transforming fields in - nested pairs. - -:: - - > MAP_CA(\rest=[AD]+)R code / S => - { DUP ; DIP { CAR ; MAP_C(\rest)R code } ; CDR ; SWAP ; PAIR } / S - > MAP_CD(\rest=[AD]+)R code / S => - { DUP ; DIP { CDR ; MAP_C(\rest)R code } ; CAR ; PAIR } / S - -Concrete syntax ---------------- -.. _ConcreteSyntax_012: - -The concrete language is very close to the formal notation of the -specification. Its structure is extremely simple: an expression in the -language can only be one of the five following constructs. - -1. An integer in decimal notation. -2. A character string. -3. A byte sequence in hexadecimal notation prefixed by ``0x``. -4. The application of a primitive to a sequence of expressions. -5. A sequence of expressions. - -This simple five cases notation is called :doc:`../shell/micheline`. - -In the Tezos protocol, the primitive ``constant`` with a single -character string applied has special meaning. See -:doc:`global_constants`. - -Constants -~~~~~~~~~ - -There are three kinds of constants: - -1. Integers or naturals in decimal notation. -2. Strings, with some usual escape sequences: ``\n``, ``\\``, - ``\"``. Unescaped line-breaks (both ``\n`` and ``\r``) cannot - appear in a Michelson string. Moreover, the current version of - Michelson restricts strings to be the printable subset of 7-bit - ASCII, namely characters with codes from within `[32, 126]` range, - plus the escaped characters mentioned above. -3. Byte sequences in hexadecimal notation, prefixed with ``0x``. - -Differences with the formal notation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The concrete syntax follows the same lexical conventions as the -specification: instructions are represented by uppercase identifiers, -type constructors by lowercase identifiers, and constant constructors -are capitalized. - -All domain specific constants are Micheline constants with specific -formats. Some have two variants accepted by the data type checker: a -readable one in a string and an optimized. - -- ``mutez`` amounts are written as naturals. -- ``timestamp``\ s are written either using ``RFC3339`` notation - in a string (readable), or as the number of seconds since Epoch - in a natural (optimized). -- ``contract``\ s, ``address``\ es, ``key``\ s and ``signature``\ s - are written as strings, in their usual Base58 encoded versions - (readable), or as their raw bytes (optimized). -- ``bls12_381_g1``\ s and ``bls12_381_g2``\ s are written as their raw bytes, using a big-endian point encoding, `as specified here `__. -- ``bls12_381_fr``\ s are written as their raw bytes, using a little-endian encoding. - -The optimized versions should not reach the RPCs, the protocol code -will convert to optimized by itself when forging operations, storing -to the database, and before hashing to get a canonical representation -of a datum for a given type. - -To prevent errors, control flow primitives that take instructions as -parameters require sequences in the concrete syntax. - -:: - - IF { instr1_true ; instr2_true ; ... } - { instr1_false ; instr2_false ; ... } - -Main program structure -~~~~~~~~~~~~~~~~~~~~~~ - -The toplevel of a smart contract file must be an un-delimited sequence -of three primitive applications (in no particular order) that provide its -``code``, ``parameter`` and ``storage`` fields. - -See the next section for a concrete example. - -Annotations ------------ - -The annotation mechanism of Michelson provides ways to better track -data on the stack and to give additional type constraints. Except for -a single exception specified just after, annotations are only here to -add constraints, *i.e.* they cannot turn an otherwise rejected program -into an accepted one. The notable exception to this rule is for -entrypoints: the semantics of the `CONTRACT` and `SELF` instructions vary depending on -their constructor annotations, and some contract origination may fail due -to invalid entrypoint constructor annotations. - -Stack visualization tools like the Michelson's Emacs mode print -annotations associated with each type in the program, as propagated by -the typechecker as well as variable annotations on the types of elements -in the stack. This is useful as a debugging aid. - -We distinguish three kinds of annotations: - -- type annotations, written ``:type_annot``, -- variable annotations, written ``@var_annot``, -- and field or constructors annotations, written ``%field_annot``. - -Type annotations -~~~~~~~~~~~~~~~~ - -Each type can be annotated with at most one type annotation. They are -used to give names to types. For types to be equal, their unnamed -version must be equal and their names must be the same or at least one -type must be unnamed. - -For instance, the following Michelson program which put its integer -parameter in the storage is not well typed: - -.. code-block:: michelson - - parameter (int :p) ; - storage (int :s) ; - code { UNPAIR ; SWAP ; DROP ; NIL operation ; PAIR } - -Whereas this one is: - -.. code-block:: michelson - - parameter (int :p) ; - storage int ; - code { UNPAIR ; SWAP ; DROP ; NIL operation ; PAIR } - -Inner components of composed typed can also be named. - -:: - - (pair :point (int :x_pos) (int :y_pos)) - -Push-like instructions, that act as constructors, can also be given a -type annotation. The stack type will then have on top a type with a corresponding name. - -:: - - UNIT :t - :: 'A -> (unit :t) : 'A - - PAIR :t - :: 'a : 'b : 'S -> (pair :t 'a 'b) : 'S - - SOME :t - :: 'a : 'S -> (option :t 'a) : 'S - - NONE :t 'a - :: 'S -> (option :t 'a) : 'S - - LEFT :t 'b - :: 'a : 'S -> (or :t 'a 'b) : 'S - - RIGHT :t 'a - :: 'b : 'S -> (or :t 'a 'b) : 'S - - NIL :t 'a - :: 'S -> (list :t 'a) : 'S - - EMPTY_SET :t 'elt - :: 'S -> (set :t 'elt) : 'S - - EMPTY_MAP :t 'key 'val - :: 'S -> (map :t 'key 'val) : 'S - - EMPTY_BIG_MAP :t 'key 'val - :: 'S -> (big_map :t 'key 'val) : 'S - - -A no-op instruction ``CAST`` ensures the top of the stack has the -specified type, and change its type if it is compatible. In particular, -this allows to change or remove type names explicitly. - -:: - - CAST 'b - :: 'a : 'S -> 'b : 'S - iff 'a = 'b - - > CAST t / a : S => a : S - - -Variable annotations -~~~~~~~~~~~~~~~~~~~~ - -Variable annotations can only be used on instructions that produce -elements on the stack. An instruction that produces ``n`` elements on -the stack can be given at most ``n`` variable annotations. - -The stack type contains both the types of each element in the stack, as -well as an optional variable annotation for each element. In this -sub-section we note: - -- ``[]`` for the empty stack, -- ``@annot (top) : (rest)`` for the stack whose first value has type ``(top)`` and is annotated with variable annotation ``@annot`` and whose queue has stack type ``(rest)``. - -The instructions which do not accept any variable annotations are: - -:: - - DROP - SWAP - DIG - DUG - IF_NONE - IF_LEFT - IF_CONS - ITER - IF - LOOP - LOOP_LEFT - DIP - FAILWITH - -The instructions which accept at most one variable annotation are: - -:: - - DUP - PUSH - UNIT - SOME - NONE - PAIR - CAR - CDR - LEFT - RIGHT - NIL - CONS - SIZE - MAP - MEM - EMPTY_SET - EMPTY_MAP - EMPTY_BIG_MAP - UPDATE - GET - LAMBDA - EXEC - ADD - SUB - CONCAT - MUL - OR - AND - XOR - NOT - ABS - ISNAT - INT - NEG - EDIV - LSL - LSR - COMPARE - EQ - NEQ - LT - GT - LE - GE - ADDRESS - CONTRACT - SET_DELEGATE - IMPLICIT_ACCOUNT - NOW - LEVEL - AMOUNT - BALANCE - HASH_KEY - CHECK_SIGNATURE - BLAKE2B - SOURCE - SENDER - SELF - SELF_ADDRESS - CAST - RENAME - CHAIN_ID - -The instructions which accept at most two variable annotations are: - -:: - - UNPAIR - CREATE_CONTRACT - -Annotations on instructions that produce multiple elements on the stack -will be used in order, where the first variable annotation is given to -the top-most element on the resulting stack. Instructions that produce -``n`` elements on the stack but are given less than ``n`` variable -annotations will see only their top-most stack type elements annotated. - -:: - - UNPAIR @fist @second - :: pair 'a 'b : 'S - -> @first 'a : @second 'b : 'S - - UNPAIR @first - :: pair 'a 'b : 'S - -> @first 'a : 'b : 'S - -A no-op instruction ``RENAME`` allows to rename variables in the stack -or to erase variable annotations in the stack. - -:: - - RENAME @new - :: @old 'a ; 'S -> @new 'a : 'S - - RENAME - :: @old 'a ; 'S -> 'a : 'S - - -Field and constructor annotations -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Components of pair types, option types and or types can be annotated -with a field or constructor annotation. This feature is useful to encode -records fields and constructors of sum types. - -:: - - (pair :point - (int %x) - (int %y)) - -The previous Michelson type can be used as visual aid to represent the -record type (given in OCaml-like syntax): - -:: - - type point = { x : int ; y : int } - -Similarly, - -:: - - (or :t - (int %A) - (or - (bool %B) - (pair %C - (nat %n1) - (nat %n2)))) - -can be used to represent the algebraic data type (in OCaml-like syntax): - -:: - - type t = - | A of int - | B of bool - | C of { n1 : nat ; n2 : nat } - - -Field annotations are part of the type (at the same level as type name -annotations), and so types with differing field names (if present) are -not considered equal. - -Instructions that construct elements of composed types can also be -annotated with one or multiple field annotations (in addition to type -and variable annotations). - -:: - - PAIR %fst %snd - :: 'a : 'b : 'S -> (pair ('a %fst) ('b %snd)) : 'S - - LEFT %left %right 'b - :: 'a : 'S -> (or ('a %left) ('b %right)) : 'S - - RIGHT %left %right 'a - :: 'b : 'S -> (or ('a %left) ('b %right)) : 'S - -To improve readability and robustness, instructions ``CAR`` and ``CDR`` -accept one field annotation. For the contract to type check, the name of -the accessed field in the destructed pair must match the one given here. - -:: - - CAR %fst - :: (pair ('a %fst) 'b) : S -> 'a : 'S - - CDR %snd - :: (pair 'a ('b %snd)) : S -> 'b : 'S - - -Syntax -~~~~~~ - -Primitive applications can receive one or many annotations. - -An annotation is a sequence of characters that matches the regular -expression ``@%|@%%|%@|[@:%][_0-9a-zA-Z][_0-9a-zA-Z\.%@]*``. -Note however that ``@%``, ``@%%`` and ``%@`` are -:ref:`special annotations ` and are not allowed everywhere. - -Annotations come after the primitive name and before its potential arguments. - -:: - - (prim @v :t %x arg1 arg2 ...) - - -Ordering between different kinds of annotations is not significant, but -ordering among annotations of the same kind is. Annotations of the same -kind must be grouped together. - -For instance these two annotated instructions are equivalent: - -:: - - PAIR :t @my_pair %x %y - - PAIR %x %y :t @my_pair - -An annotation can be empty, in this case it will mean *no annotation* -and can be used as a wildcard. For instance, it is useful to annotate -only the right field of a pair instruction ``PAIR % %right`` or to -ignore field access constraints, *e.g.* in the macro ``UNPPAIPAIR %x1 % -%x3 %x4``. - -Annotations and macros -~~~~~~~~~~~~~~~~~~~~~~ - -Macros also support annotations, which are propagated on their expanded -forms. As with instructions, macros that produce ``n`` values on the -stack accept ``n`` variable annotations. - -:: - - DUU+P @annot - > DUU(\rest=U*)P @annot / S => DIP (DU(\rest)P @annot) ; SWAP / S - - C[AD]+R @annot %field_name - > CA(\rest=[AD]+)R @annot %field_name / S => CAR ; C(\rest)R @annot %field_name / S - > CD(\rest=[AD]+)R @annot %field_name / S => CDR ; C(\rest)R @annot %field_name / S - - CMP{EQ|NEQ|LT|GT|LE|GE} @annot - > CMP(\op) @annot / S => COMPARE ; (\op) @annot / S - -The variable annotation on ``SET_C[AD]+R`` and ``MAP_C[AD]+R`` annotates -the resulting toplevel pair while its field annotation is used to check -that the modified field is the expected one. - -:: - - SET_C[AD]+R @var %field - > SET_CAR @var %field => CDR %field ; SWAP ; PAIR @var - > SET_CDR @var %field => CAR %field ; PAIR @var - > SET_CA(\rest=[AD]+)R @var %field / S => - { DUP ; DIP { CAR ; SET_C(\rest)R %field } ; CDR ; SWAP ; PAIR @var } / S - > SET_CD(\rest=[AD]+)R @var %field/ S => - { DUP ; DIP { CDR ; SET_C(\rest)R %field } ; CAR ; PAIR @var } / S - - MAP_C[AD]+R @var %field code - > MAP_CAR code => DUP ; CDR ; DIP { CAR %field ; code } ; SWAP ; PAIR @var - > MAP_CDR code => DUP ; CDR %field ; code ; SWAP ; CAR ; PAIR @var - > MAP_CA(\rest=[AD]+)R @var %field code / S => - { DUP ; DIP { CAR ; MAP_C(\rest)R %field code } ; CDR ; SWAP ; PAIR @var} / S - > MAP_CD(\rest=[AD]+)R @var %field code / S => - { DUP ; DIP { CDR ; MAP_C(\rest)R %field code } ; CAR ; PAIR @var} / S - -Macros for nested ``PAIR`` accept multiple annotations. Field -annotations for ``PAIR`` give names to leaves of the constructed -nested pair, in order. This next snippet gives examples instead of -generic rewrite rules for readability purposes. - -:: - - PAPPAIIR @p %x1 %x2 %x3 %x4 - :: 'a : 'b : 'c : 'd : 'S - -> @p (pair ('a %x1) (pair (pair ('b %x) ('c %x3)) ('d %x4))) : 'S - - PAPAIR @p %x1 %x2 %x3 - :: 'a : 'b : 'c : 'S -> @p (pair ('a %x1) (pair ('b %x) ('c %x3))) : 'S - -Annotations for nested ``UNPAIR`` are deprecated. - -Automatic variable and field annotations inferring -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When no annotation is provided by the Michelson programmer, the -typechecker infers some annotations in specific cases. This greatly -helps users track information in the stack for bare contracts. - -For unannotated accesses with ``CAR`` and ``CDR`` to fields that are -named will be appended (with an additional ``.`` character) to the pair -variable annotation. - -:: - - CDAR - :: @p (pair ('a %foo) (pair %bar ('b %x) ('c %y))) : 'S -> @p.bar.x 'b : 'S - -If fields are not named but the pair is still named in the stack then -``.car`` or ``.cdr`` will be appended. - -:: - - CDAR - :: @p (pair 'a (pair 'b 'c)) : 'S -> @p.cdr.car 'b : 'S - -If the original pair is not named in the stack, but a field annotation -is present in the pair type the accessed value will be annotated with a -variable annotation corresponding to the field annotation alone. - -:: - - CDAR - :: (pair ('a %foo) (pair %bar ('b %x) ('c %y))) : 'S -> @bar.x 'b : 'S - -A similar mechanism is used for context dependent instructions: - -:: - - ADDRESS :: @c contract _ : 'S -> @c.address address : 'S - - CONTRACT 'p :: @a address : 'S -> @a.contract contract 'p : 'S - - BALANCE :: 'S -> @balance mutez : 'S - - SOURCE :: 'S -> @source address : 'S - - SENDER :: 'S -> @sender address : 'S - - SELF :: 'S -> @self contract 'p : 'S - - SELF_ADDRESS :: 'S -> @self address : 'S - - AMOUNT :: 'S -> @amount mutez : 'S - - NOW :: 'S -> @now timestamp : 'S - - LEVEL :: 'S -> @level nat : 'S - -Inside nested code blocks, bound items on the stack will be given a -default variable name annotation depending on the instruction and stack -type (which can be changed). For instance the annotated typing rule for -``ITER`` on lists is: - -:: - - ITER body - :: @l (list 'e) : 'A -> 'A - iff body :: [ @l.elt e' : 'A -> 'A ] - -Special annotations -~~~~~~~~~~~~~~~~~~~ -.. _SpecialAnnotations_012: - -The special variable annotations ``@%`` and ``@%%`` can be used on instructions -``CAR``, ``CDR``, and ``UNPAIR``. It means to use the accessed field name (if any) as -a name for the value on the stack. The following typing rule -demonstrates their use for instruction ``CAR``. - -:: - - CAR @% - :: @p (pair ('a %fst) ('b %snd)) : 'S -> @fst 'a : 'S - - CAR @%% - :: @p (pair ('a %fst) ('b %snd)) : 'S -> @p.fst 'a : 'S - -The special field annotation ``%@`` can be used on instructions -``PAIR``, ``LEFT`` and ``RIGHT``. It means to use the variable -name annotation in the stack as a field name for the constructed -element. Two examples with ``PAIR`` follows, notice the special -treatment of annotations with ``.``. - -:: - - PAIR %@ %@ - :: @x 'a : @y 'b : 'S -> (pair ('a %x) ('b %y)) : 'S - - PAIR %@ %@ - :: @p.x 'a : @p.y 'b : 'S -> @p (pair ('a %x) ('b %y)) : 'S - :: @p.x 'a : @q.y 'b : 'S -> (pair ('a %x) ('b %y)) : 'S - -Entrypoints ------------ - -The specification up to this point has been mostly ignoring existence -of entrypoints: a mechanism of contract level polymorphism. This -mechanism is optional, non intrusive, and transparent to smart -contracts that don't use them. This section is to be read as a patch -over the rest of the specification, introducing rules that apply only -in presence of contracts that make use of entrypoints. - -Defining and calling entrypoints -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Entrypoints piggyback on the constructor annotations. A contract with -entrypoints is basically a contract that takes a disjunctive type (a -nesting of ``or`` types) as the root of its input parameter, decorated -with constructor annotations. An extra check is performed on these -constructor annotations: a contract cannot define two entrypoints with -the same name. - -An external transaction can include an entrypoint name alongside the -parameter value. In that case, if there is a constructor annotation -with this name at any position in the nesting of ``or`` types, the -value is automatically wrapped into the according constructors. If the -transaction specifies an entrypoint, but there is no such constructor -annotation, the transaction fails. - -For instance, suppose the following input type. - -``parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))`` - -The input values will be wrapped as in the following examples. - -:: - - +------------+-----------+---------------------------------+ - | entrypoint | input | wrapped input | - +------------+-----------+---------------------------------+ - | %A | 3 | Left (Left 3) | - | %B | False | Left (Right False) | - | %C | "bob" | Right (Right "bob") | - | %Z | Unit | Right (Left Unit) | - | %maybe_C | Right "x" | Right (Right "x") | - | %maybe_C | Left Unit | Right (Left Unit) | - +------------+-----------+---------------------------------+ - | not given | value | value (untouched) | - | %BAD | _ | failure, contract not called | - +------------+-----------+---------------------------------+ - -The ``default`` entrypoint -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -A special semantics is assigned to the ``default`` entrypoint. If the -contract does not explicitly declare a ``default`` entrypoint, then it -is automatically assigned to the root of the parameter -type. Conversely, if the contract is called without specifying an -entrypoint, then it is assumed to be called with the ``default`` -entrypoint. This behaviour makes the entrypoint system completely -transparent to contracts that do not use it. - -This is the case for the previous example, for instance. If a value is -passed to such a contract specifying entrypoint ``default``, then the -value is fed to the contract untouched, exactly as if no entrypoint -was given. - -A non enforced convention is to make the entrypoint ``default`` of -type unit, and to implement the crediting operation (just receive the -transferred tokens). - -A consequence of this semantics is that if the contract uses the -entrypoint system and defines a ``default`` entrypoint somewhere else -than at the root of the parameter type, then it must provide an -entrypoint for all the paths in the toplevel disjunction. Otherwise, -some parts of the contracts would be dead code. - -Another consequence of setting the entrypoint somewhere else than at -the root is that it makes it impossible to send the raw values of the -full parameter type to a contract. A trivial solution for that is to -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))`` - -The input values will be wrapped as in the following examples. - -:: - - +------------+---------------------+-----------------------+ - | entrypoint | input | wrapped input | - +------------+---------------------+-----------------------+ - | %A | 3 | Left (Left 3) | - | %B | False | Left (Right False) | - | %default | Unit | Right (Left Unit) | - | %root | Right (Right "bob") | Right (Right "bob") | - +------------+---------------------+-----------------------+ - | not given | Unit | Right (Left Unit) | - | %BAD | _ | failure, contract not | - +------------+---------------------+-----------------------+ - -Calling entrypoints from Michelson -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Michelson code can also produce transactions to a specific entrypoint. - -For this, both types ``address`` and ``contract`` have the ability to -denote not just an address, but a pair of an address and an -entrypoint. The concrete notation is ``"address%entrypoint"``. -Note that ``"address"`` is strictly equivalent to ``"address%default"``, -and for clarity, the second variant is forbidden in the concrete syntax. - -When the ``TRANSFER_TOKENS`` instruction is called, it places the -entrypoint provided in the contract handle in the transaction. - -The ``CONTRACT t`` instruction has a variant ``CONTRACT %entrypoint -t``, that works as follows. Note that ``CONTRACT t`` is strictly -equivalent to ``CONTRACT %default t``, and for clarity, the second -variant is forbidden in the concrete syntax. - -:: - - +---------------+---------------------+------------------------------------------+ - | input address | instruction | output contract | - +---------------+---------------------+------------------------------------------+ - | "addr" | CONTRACT t | (Some "addr") if contract exists, has a | - | | | default entrypoint of type t, or has no | - | | | default entrypoint and parameter type t | - +---------------+---------------------+------------------------------------------+ - | "addr%name" | CONTRACT t | (Some "addr%name") if addr exists and | - +---------------+---------------------+ has an entrypoint %name of type t | - | "addr" | CONTRACT %name t | | - +---------------+---------------------+------------------------------------------+ - | "addr%_" | CONTRACT %_ t | None | - +---------------+---------------------+------------------------------------------+ - -Similarly, the ``SELF`` instruction has a variant ``SELF %entrypoint``, -that is only well-typed if the current contract has an entrypoint named ``%entrypoint``. - -- ``SELF %entrypoint`` - -:: - - :: 'S -> contract 'p : 'S - where contract 'p is the type of the entrypoint %entrypoint of the current contract - -Implicit accounts are considered to have a single ``default`` -entrypoint of type ``Unit``. - -JSON syntax ------------ - -Micheline expressions are encoded in JSON like this: - -- An integer ``N`` is an object with a single field ``"int"`` whose - value is the decimal representation as a string. - - ``{ "int": "N" }`` - -- A string ``"contents"`` is an object with a single field ``"string"`` - whose value is the decimal representation as a string. - - ``{ "string": "contents" }`` - -- A sequence is a JSON array. - - ``[ expr, ... ]`` - -- A primitive application is an object with two fields ``"prim"`` for - the primitive name and ``"args"`` for the arguments (that must - contain an array). A third optional field ``"annots"`` contains a - list of annotations, including their leading ``@``, ``%`` or ``:`` - sign. - - ``{ "prim": "pair", "args": [ { "prim": "nat", "args": [] }, { "prim": "nat", "args": [] } ], "annots": [":t"] }`` - -As in the concrete syntax, all domain specific constants are encoded as -strings. - -Examples ---------- - -Contracts in the system are stored as a piece of code and a global data -storage. The type of the global data of the storage is fixed for each -contract at origination time. This is ensured statically by checking on -origination that the code preserves the type of the global data. For -this, the code of the contract is checked to be of type -``lambda (pair 'arg 'global) -> (pair (list operation) 'global)`` where -``'global`` is the type of the original global store given on origination. -The contract also takes a parameter and returns a list of internal operations, -hence the complete calling convention above. The internal operations are -queued for execution when the contract returns. - -Empty contract -~~~~~~~~~~~~~~ - -The simplest contract is the contract for which the ``parameter`` and -``storage`` are all of type ``unit``. This contract is as follows: - -.. code-block:: michelson - - code { CDR ; # keep the storage - NIL operation ; # return no internal operation - PAIR }; # respect the calling convention - storage unit; - parameter unit; - - -Example contract with entrypoints -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The following contract maintains a number in its storage. It has two -entrypoints ``add`` and ``sub`` to modify it, and the default -entrypoint, of type ``unit`` will reset it to ``0``. - -:: - - { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; - storage int ; - code { AMOUNT ; PUSH mutez 0 ; ASSERT_CMPEQ ; UNPAIR ; - IF_LEFT - { IF_LEFT { ADD } { SWAP ; SUB } } - { DROP ; DROP ; PUSH int 0 } ; - NIL operation ; PAIR } } - -Multisig contract -~~~~~~~~~~~~~~~~~ - -The multisig is a typical access control contract. The ownership of -the multisig contract is shared between ``N`` participants represented -by their public keys in the contract's storage. Any action on the -multisig contract needs to be signed by ``K`` participants where the -threshold ``K`` is also stored in the storage. - -To avoid replay of the signatures sent to the contract, the signed -data include not only a description of the action to perform but also -the address of the multisig contract and a counter that gets -incremented at each successful call to the contract. - -The multisig commands of :ref:`Tezos command line client ` -use this -smart contract. Moreover, `functional correctness of this contract has -been verified -`__ -using the Coq proof assistant. - - -.. code-block:: michelson - - parameter (pair - (pair :payload - (nat %counter) # counter, used to prevent replay attacks - (or :action # payload to sign, represents the requested action - (pair :transfer # transfer tokens - (mutez %amount) # amount to transfer - (contract %dest unit)) # destination to transfer to - (or - (option %delegate key_hash) # change the delegate to this address - (pair %change_keys # change the keys controlling the multisig - (nat %threshold) # new threshold - (list %keys key))))) # new list of keys - (list %sigs (option signature))); # signatures - - storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; - - code - { - UNPAIR ; SWAP ; DUP ; DIP { SWAP } ; - DIP - { - UNPAIR ; - # pair the payload with the current contract address, to ensure signatures - # can't be replayed across different contracts if a key is reused. - DUP ; SELF ; ADDRESS ; CHAIN_ID ; PAIR ; PAIR ; - PACK ; # form the binary payload that we expect to be signed - DIP { UNPAIR @counter ; DIP { SWAP } } ; SWAP - } ; - - # Check that the counters match - UNPAIR @stored_counter; DIP { SWAP }; - ASSERT_CMPEQ ; - - # Compute the number of valid signatures - DIP { SWAP } ; UNPAIR @threshold @keys; - DIP - { - # Running count of valid signatures - PUSH @valid nat 0; SWAP ; - ITER - { - DIP { SWAP } ; SWAP ; - IF_CONS - { - IF_SOME - { SWAP ; - DIP - { - SWAP ; DIIP { DIP { DUP } ; SWAP } ; - # Checks signatures, fails if invalid - CHECK_SIGNATURE ; ASSERT ; - PUSH nat 1 ; ADD @valid } } - { SWAP ; DROP } - } - { - # There were fewer signatures in the list - # than keys. Not all signatures must be present, but - # they should be marked as absent using the option type. - FAIL - } ; - SWAP - } - } ; - # Assert that the threshold is less than or equal to the - # number of valid signatures. - ASSERT_CMPLE ; - DROP ; DROP ; - - # Increment counter and place in storage - DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR} ; - - # We have now handled the signature verification part, - # produce the operation requested by the signers. - NIL operation ; SWAP ; - IF_LEFT - { # Transfer tokens - UNPAIR ; UNIT ; TRANSFER_TOKENS ; CONS } - { IF_LEFT { - # Change delegate - SET_DELEGATE ; CONS } - { - # Change set of signatures - DIP { SWAP ; CAR } ; SWAP ; PAIR ; SWAP }} ; - PAIR } - - - -Full grammar ------------- - -:: - - ::= - | - | - | - | Unit - | True - | False - | Pair ... - | Left - | Right - | Some - | None - | { ; ... } - | { Elt ; ... } - | instruction - ::= - | [0-9]+ - ::= - | - | - - ::= - | "*" - ::= - | \" - | \r - | \n - | \t - | \b - | \\ - | [^"\] - ::= - | 0x[0-9a-fA-F]+ - ::= - | { ... } - | DROP - | DROP - | DUP - | DUP - | SWAP - | DIG - | DUG - | PUSH - | SOME - | NONE - | UNIT - | NEVER - | IF_NONE { ... } { ... } - | PAIR - | PAIR - | CAR - | CDR - | UNPAIR - | UNPAIR - | LEFT - | RIGHT - | IF_LEFT { ... } { ... } - | NIL - | CONS - | IF_CONS { ... } { ... } - | SIZE - | EMPTY_SET - | EMPTY_MAP - | EMPTY_BIG_MAP - | MAP { ... } - | ITER { ... } - | MEM - | GET - | GET - | UPDATE - | UPDATE - | IF { ... } { ... } - | LOOP { ... } - | LOOP_LEFT { ... } - | LAMBDA { ... } - | EXEC - | APPLY - | DIP { ... } - | DIP { ... } - | FAILWITH - | CAST - | RENAME - | CONCAT - | SLICE - | PACK - | UNPACK - | ADD - | SUB - | MUL - | EDIV - | ABS - | ISNAT - | INT - | NEG - | LSL - | LSR - | OR - | AND - | XOR - | NOT - | COMPARE - | EQ - | NEQ - | LT - | GT - | LE - | GE - | SELF - | SELF_ADDRESS - | CONTRACT - | TRANSFER_TOKENS - | SET_DELEGATE - | CREATE_CONTRACT { ... } - | IMPLICIT_ACCOUNT - | VOTING_POWER - | NOW - | LEVEL - | AMOUNT - | BALANCE - | CHECK_SIGNATURE - | BLAKE2B - | KECCAK - | SHA3 - | SHA256 - | SHA512 - | HASH_KEY - | SOURCE - | SENDER - | ADDRESS - | CHAIN_ID - | TOTAL_VOTING_POWER - | PAIRING_CHECK - | SAPLING_EMPTY_STATE - | SAPLING_VERIFY_UPDATE - | TICKET - | READ_TICKET - | SPLIT_TICKET - | JOIN_TICKETS - | OPEN_CHEST - ::= - | - | option - | list - | set - | operation - | contract - | ticket - | pair ... - | or - | lambda - | map - | big_map - | bls12_381_g1 - | bls12_381_g2 - | bls12_381_fr - | sapling_transaction - | sapling_state - | chest - | chest_key - ::= - | unit - | never - | bool - | int - | nat - | string - | chain_id - | bytes - | mutez - | key_hash - | key - | signature - | timestamp - | address - | option - | or - | pair ... - - -Reference implementation ------------------------- - -The language is implemented in OCaml as follows: - -- The lower internal representation is written as a GADT whose type - parameters encode exactly the typing rules given in this - specification. In other words, if a program written in this - representation is accepted by OCaml's typechecker, it is guaranteed - type-safe. This is of course also valid for programs not - handwritten but generated by OCaml code, so we are sure that any - manipulated code is type-safe. - - In the end, what remains to be checked is the encoding of the typing - rules as OCaml types, which boils down to half a line of code for - each instruction. Everything else is left to the venerable and well - trusted OCaml. - -- The interpreter is basically the direct transcription of the - rewriting rules presented above. It takes an instruction, a stack and - transforms it. OCaml's typechecker ensures that the transformation - respects the pre and post stack types declared by the GADT case for - each instruction. - - The only things that remain to be reviewed are value dependent - choices, such as we did not swap true and false when - interpreting the IF instruction. - -- The input, untyped internal representation is an OCaml ADT with - only 5 grammar constructions: ``String``, ``Int``, ``Bytes``, ``Seq`` and - ``Prim``. It is the target language for the parser, since not all - parsable programs are well typed, and thus could simply not be - constructed using the GADT. - -- The typechecker is a simple function that recognizes the abstract - grammar described in section X by pattern matching, producing the - well-typed, corresponding GADT expressions. It is mostly a checker, - not a full inferrer, and thus takes some annotations (basically the - input and output of the program, of lambdas and of uninitialized maps - and sets). It works by performing a symbolic evaluation of the - program, transforming a symbolic stack. It only needs one pass over - the whole program. - - Here again, OCaml does most of the checking, the structure of the - function is very simple, what we have to check is that we transform a - ``Prim ("If", ...)`` into an ``If``, a ``Prim ("Dup", ...)`` into a - ``Dup``, etc. diff --git a/docs/012/plugins.rst b/docs/012/plugins.rst deleted file mode 100644 index a0e36d5086d2..000000000000 --- a/docs/012/plugins.rst +++ /dev/null @@ -1,53 +0,0 @@ -Protocol plugins -================ - -Protocol plugins implement extra APIs needed by the shell in order to interact with the economic protocol, beyond the one provided by the protocol environment. -This code is not strictly speaking part of the protocol code base, so this is not subject to on-chain governance (see :doc:`voting procedure `), but it is still protocol-dependent, which means that it may vary with different protocols. -For instance, the plugin code for protocol Alpha is located in file :src:`src/proto_012_Psithaca/lib_plugin/plugin.ml`. -Thus, a specific version is included in the Octez node for each protocol version (recall that a new release of Octez is usually delivered for each new protocol proposal, see :doc:`../releases/releases`) - -So what kind of features may a protocol plugin provide? -For instance, protocol plugins do not define the context, or restrict the validity of operations. -In turn protocol plugins may, for example: - -- be adjacent enough to the protocol code that it needs to have access to the protocol's internal representations for certain structures: e.g., it has some RPCs that can introspect on the protocol dependent content for certain operations; -- implement some common operations that are customized for each protocol (e.g., :ref:`prevalidator_filters`). - -.. _prevalidator_filters_012: - -Prevalidator filters -~~~~~~~~~~~~~~~~~~~~ - -The :ref:`prevalidator component ` of the shell is responsible for disseminating operations over the peer-to-peer network, that may be included in next blocks. -To prevent spam, the prevalidator implements built-in filtering mechanisms that limit to some extent the risk of flooding the network with invalid operations. -However, these selection mechanisms remain rather laxist to protect from DOS attacks. -In particular, a very affordable technique for attackers is based on flooding the network with, valid but useless, zero-fees operations. -This is why an additional and more flexible selection mechanism is included in the Octez node: *prevalidator filters*. - -Prevalidator filters thus serve at further restricting the operations to propapate by the node to the network. -Filters are implemented as a node plugin and a specific filter is delivererd with each protocol version. -When the chain switches to a new protocol, the node installs its corresponding filter, *in lieu of* the filter of the previous protocol. - -The prevalidator filter is based on restricting operations based on their associated fees, to reject "too cheap" or "zero-fees" operations. -However, the filters could also be used to restrict the propagation of consensus operations (e.g. endorsements). - -The filter is tunable by several parameters, whose values can be retrieved and changed by users via the following RPC calls, respectively: - -- ``rpc get /chains//mempool/filter`` -- ``rpc post /chains//mempool/filter`` - -The following parameters can be thus inspected and modified: - -- ``minimal_fees``: type ``int``, default ``100`` -- ``minimal_nanotez_per_gas_unit``: type ``int``, default ``100`` -- ``minimal_nanotez_per_byte``: type ``int``, default ``1000`` -- ``allow_script_failure``: type ``bool``, default ``true`` - -For example, the following command modifies the ``minimal_fees`` parameter (and resets all the other parameters to their default values):: - - tezos-client rpc post /chains/main/mempool/filter with '{ "minimal_fees": "42" }' - -See also: - -- The `mempool plugin API `__ -- MR :gl:`!3118` show defaults in RPC get mempool/filter diff --git a/docs/012/proof_of_stake.rst b/docs/012/proof_of_stake.rst deleted file mode 100644 index 5366a3e28731..000000000000 --- a/docs/012/proof_of_stake.rst +++ /dev/null @@ -1,171 +0,0 @@ -Proof-of-stake -============== - -Overview --------- - -:doc:`The consensus algorithm ` in Tezos is based on the -*proof-of-stake* mechanism. Proof-of-stake means that participants -in the consensus algorithm are chosen in function of their stake (the -amount of tokens a participant has). The same mechanism is used in the -Tezos :doc:`governance `. - -If one does not have enough stake to participate on its own or does not want to -set up the needed infrastructure, (s)he can use :ref:`delegation -`. Therefore, in Tezos, it is the :ref:`delegates` -that may participate in consensus. Delegates' rights to participate are -determined by a `follow-the-coin strategy -`_. This -procedure is random, in that its result cannot be predicted too much in advance. -The :ref:`randomness` is obtained from information already found on the -blockchain. Thus, the procedure is also deterministic: delegates' rights are -uniquely determined from the random element. - -Delegation ----------- - -A *delegate* is any :ref:`implicit account ` registered as -such by emitting a delegate registration operation. - -Any :ref:`accounts ` (implicit or originated) can specify a delegate -through a delegation operation. - -Any account can change or revoke its delegate at any time. However, the change -only becomes effective after ``PRESERVED_CYCLES + 2`` :ref:`cycles `. -The value ``PRESERVED_CYCLES`` is a -:ref:`protocol constant `. - -A delegate participates in consensus and in governance with a weight -proportional with their delegated stake, which includes the balances -of all the accounts that delegate to it, and also the balance of the -delegate itself. To participate in consensus or in governance, a -delegate needs to have at least a minimal stake, which is given by the -``TOKENS_PER_ROLL`` :ref:`protocol constant -`. - -Delegates place security deposits that may be forfeited in case they do not -follow (some particular rules of) the protocol. Security deposits are deduced -from the delegates' own balance. - - -Active and passive delegates -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. _active_delegate_012: - -A delegate can be marked as either active or passive. A passive -delegate cannot participate in the consensus algorithm. - -A delegate is marked as active at its registration. - -A delegate becomes passive for cycle ``n`` when they -fail to participate in the consensus algorithm in -the past ``PRESERVED_CYCLES`` cycles, that is, in cycles ``n-1``, -``n-2``, ..., ``n - PRESERVED_CYCLES``. - -Delegates' rights selection ---------------------------- - -Tezos being proof-of-stake, the delegates' rights are selected at random based on their -stake. - -.. _random_seed_012: - -Random seed -^^^^^^^^^^^ - -Each cycle ``n`` is associated with a random seed. The random seed for cycle -``n`` is a 256-bit number generated at the very end of cycle ``n-1`` from -*nonces* to which delegates commit during cycle ``n-2``. One block out of every -``BLOCKS_PER_COMMITMENT`` can contain a commitment. A commitment is the hash of -a nonce. The commitment is generated by the block proposer and is included in -the block header. - -The committed nonce must be revealed by the original block proposer during cycle -``n-1`` under penalty of forfeiting the rewards and fees of the block that -included the commitment. The associated security deposit is not forfeited. - -A *nonce revelation* is an operation and multiple nonce revelations can thus be -included in a block. A reward ``SEED_NONCE_REVELATION_TIP`` is given for -including a revelation. Revelations are free operations which do not compete -with transactions for block space. Up to ``MAX_ANON_OPS_PER_BLOCK`` revelations, -wallet activations and denunciations can be contained in any given block. - -The seed for cycle ``n`` is obtained as follows: the seed of cycle ``n-1`` is -hashed with a constant and then with each nonce revealed in cycle ``n-1``. - -.. _rights_012: - -Slot selection -^^^^^^^^^^^^^^ - -To return to the rights selection mechanism, we first introduce a new -terminology, *stake snapshot*, to denote the stored (in the -:ref:`context `) stake distribution for a given block. Stake -snapshots are taken (and stored) every ``BLOCKS_PER_STAKE_SNAPSHOT`` -blocks. - -The delegates' rights at a given level and for a particular role in -the protocol are expressed in terms of *slots* that the delegate -receives for that role. The slot owner is obtained by running a PRNG -(pseudo-random number generator) with the following input: - -- the level -- the role (a string) -- the slot (a non-negative integer) - -Let `n` be the cycle the level belongs to. -The seed of the PRNG is the :ref:`random seed ` associated with cycle ``n-PRESERVED_CYCLES``. -The PRNG selects a snapshot from cycle ``n-PRESERVED_CYCLES-2`` and then it selects a stake in the selected snapshot. -The slot owner is then the stake owner. - -.. _protocol_constants_012: - -Protocol constants ------------------- - -Protocols are parameterized by several parameters called *protocol constants*, which may vary from one protocol to another or from one network to another (for instance, test networks move faster). - -The list of protocol constants can be found in the API of the `Constants module `__. - -The values of protocol constants can be found using a :ref:`specific RPC call `, as shown in :ref:`this example `. - -In particular, the protocol constants related to the proof-of-stake mechanism are detailed below. - -.. _ps_constants_012: - -Proof-of-stake parameters -^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. list-table:: - :widths: 55 25 - :header-rows: 1 - - * - Parameter name - - Parameter value - * - ``BLOCKS_PER_CYCLE`` - - 8192 blocks - * - ``PRESERVED_CYCLES`` - - 5 cycles - * - ``BLOCKS_PER_COMMITMENT`` - - 64 blocks - * - ``MAX_ANON_OPS_PER_BLOCK`` - - 132 revelations - * - ``SEED_NONCE_REVELATION_TIP`` - - 1/8 ꜩ - * - ``TOKENS_PER_ROLL`` - - 6,000 ꜩ - * - ``BLOCKS_PER_STAKE_SNAPSHOT`` - - 512 blocks - - -Further External Resources --------------------------- - -The original design of the proof-of-stake mechanism in Tezos can be -found in the `whitepaper -`_. - -Another presentation of the Tezos' proof-of-stake mechanism can be -found in the `Tezos agora wiki entry -`_. diff --git a/docs/012/protocol.rst b/docs/012/protocol.rst deleted file mode 100644 index a49f35ea036b..000000000000 --- a/docs/012/protocol.rst +++ /dev/null @@ -1,62 +0,0 @@ -The economic protocol -===================== - -The economic protocol provides the rules for checking the validity of the blocks and operations, and for updating the blockchain state accordingly, by applying new valid blocks and operations on the current blockchain state. These rules can be changed through voting. -Thus, the -economic protocol represents the amendable part of Tezos. - -This page groups the documentation helping developers and users in -understanding the basic concepts of the economic protocol -(proof-of-stake, consensus, voting, etc), its features (Michelson, -Sapling, etc), and some details about its implementation. - - -.. toctree:: - :maxdepth: 2 - - protocol_overview - -.. toctree:: - :maxdepth: 2 - - consensus - -.. toctree:: - :maxdepth: 2 - - proof_of_stake - -.. toctree:: - :maxdepth: 2 - - voting - -.. toctree:: - :maxdepth: 2 - - michelson - -.. toctree:: - :maxdepth: 2 - - timelock - -.. toctree:: - :maxdepth: 2 - - sapling - -.. toctree:: - :maxdepth: 2 - - liquidity_baking - -.. toctree:: - :maxdepth: 2 - - global_constants - -.. toctree:: - :maxdepth: 2 - - plugins diff --git a/docs/012/protocol_overview.rst b/docs/012/protocol_overview.rst deleted file mode 100644 index 405fcf93ed8f..000000000000 --- a/docs/012/protocol_overview.rst +++ /dev/null @@ -1,112 +0,0 @@ -Overview of the economic protocol -================================= - -Tezos overview -~~~~~~~~~~~~~~ - -Tezos is a distributed system in which nodes agree upon a chain of blocks of -operations. Tezos is also an account-based crypto-ledger, where an account is -associated to a public-private key pair, and has a balance, that is, a number of -tokens. Tezos is a :doc:`proof-of-stake` system in which any -account that has a minimal stake amount has the right to produce blocks, in -proportion to their balance. - -A Tezos node has mainly three roles: it validates blocks and operations, it -broadcasts them to (and retrieves them from) other nodes, and it maintains a -main chain and its associated state (i.e. the ledger), which includes accounts -and their balances, among other things. Note that, as blocks only specify a -predecessor block, exchanged blocks do not necessarily form a chain, but rather -a tree. Nodes communicate over :doc:`a gossip network<../shell/p2p>`. - -A Tezos node acts as a server, which responds to queries and requests from -clients. Such queries and requests are implemented via :doc:`RPC -calls<../developer/rpc>`. A client can query the chain’s state and can inject -blocks and operations into a node. One particular client is the :ref:`baker daemon `, -which is associated to an account. In particular the baker has access to the -account’s private key and thus can sign blocks and operations. - -The main reason for using such a client-server architecture is safety: to insulate -the component that has access to the client keys, i.e. the baker, from the -component which is exposed to the internet, i.e. the node. Indeed, the node and -the baker can sit on different computers and the baker does not need to be -exposed to the internet. So nodes manage communication and shield bakers from -network attacks, and bakers hold secrets and bake blocks into the blockchain. - -Another advantage of this architecture is that bakers can more easily have -different implementations, and this is important, for instance because different bakers may want -to implement different transaction selection strategies. - -Tezos is a self-amending blockchain, in that a large part of Tezos can be -changed through a so-called amendement procedure. To this end, as mentioned in -:doc:`the big picture<../shell/the_big_picture>`, a Tezos node consists of two -components: - -- the shell, which comprises the network and storage layer, and embeds -- the economic protocol component, which is the part that can be changed through amendment. - -The role of the protocol -~~~~~~~~~~~~~~~~~~~~~~~~ - -At a very high level, a protocol must: - -- implement protocol-specific types, such as the type of operations or protocol-specific block header data (in addition to the shell generic header), -- define under which conditions a block is a valid extension of the current blockchain, and define an ordering on blocks to arbitrate between concurrent extensions. - -Validity conditions are implemented in the ``apply`` function which is called -whenever the node processes a block. The ``apply`` function takes as arguments a -*context* and a block. The context represents the *protocol state* and is -therefore protocol specific. The context may contain, for instance, a list of -accounts and their balances. More generally, the context must provide enough -information to determine the validity of a block. Given a context and a block, -the ``apply`` function returns the updated context if the block is valid and has -a higher :ref:`fitness`. The fitness determines a total ordering between blocks. - -.. _shell_proto_interact_012: - -Shell-protocol interaction -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:doc:`Recall<../shell/the_big_picture>` that the economic protocol and the shell interact in order to ensure that the blocks being appended to the blockchain are valid. There are mainly two rules that the shell uses when receiving a new block: - -- The shell does not accept a branch whose fork point is in a cycle more than ``PRESERVED_CYCLES`` in the past. More precisely, if ``n`` is the current cycle, :ref:`the last allowed fork point` is the first level of cycle ``n-PRESERVED_CYCLES``. The parameter ``PRESERVED_CYCLES`` therefore plays a central role in Tezos: any block before the last allowed fork level is immutable. -- The shell changes the head of the chain to this new block only if the block is :doc:`valid<../shell/validation>` and has a higher fitness than the current head; a block is valid if the operations it includes are valid. - - -Blocks -~~~~~~ - -A block consists of a header and operations. A block's header is -composed of two parts: :ref:`the protocol-agnostic part` -and :ref:`the protocol-specific part`. -This separation enables the shell to interact with different -protocols. - -Operations -~~~~~~~~~~ - -The different kinds of operations are grouped in classes, such that operations belonging to different classes may be validated independently, and/or with different priorities. -Each class has an associated index, called a :ref:`validation pass`. -There are four classes of operations: :doc:`consensus ` operations, :doc:`voting ` operations, anonymous operations, manager operations. - -Consensus operations are endorsements, while `voting ` operations are ballot and proposal. - -Anonymous operations are operations which are not signed. There are three anonymous operations: seed nonce revelation, double baking evidence, and double endorsing evidence. The evidence for double baking and double endorsing is included in a block by the so-called accuser (see :ref:`slashing`). - -Manager operations are activation, origination (see :doc:`smart contracts`), transaction, reveal, and delegation (see :doc:`proof of stake `). Manager operations are the only fee-paying operations. - -Recall that users have associated :ref:`accounts ` which they activate before being able to participate. By means of the operation :ref:`origination`, accounts can be further associated with smart contracts in which they are called :ref:`originated accounts`. :ref:`Transactions` are used to either transfer tez between two accounts or run the code of a smart contract. Transactions are signed by an account's private key. Before making a transaction, a user must reveal her public key so that other users (not being aware of this public key) can effectively check the signature of the transaction. - -Manager operations can be grouped into batches forming a so-called group operation. A group operation satisfies: - -- atomicity: either all the operations in the batch succeed or none is applied -- efficiency: the whole batch is signed only once (by the same implicit account), thus it is much more efficient to check, and it requires much less gas -- usability: the batch only increments the counter of the signer account by one; for this reason it is easier for tools to provide sending several operations per block using operation batches than tracking counter changes. - -The list of operations can be obtained with :ref:`this rpc `. - -See also -~~~~~~~~ - -An in-depth description of the inners of a protocol can be found in the blog -post `How to write a Tezos protocol -`_. diff --git a/docs/012/sapling.rst b/docs/012/sapling.rst deleted file mode 100644 index 80a8b02b6574..000000000000 --- a/docs/012/sapling.rst +++ /dev/null @@ -1,496 +0,0 @@ -**The features described in this page are experimental and have not undergone any security review.** - -Sapling integration -=================== - -Sapling is a protocol enabling privacy-preserving transactions of fungible -tokens in a decentralised -environment. It was designed and implemented by the Electric Coin -Company as the last iteration over a series of previous protocols and -academic works starting with the `Zerocoin seminal -paper `_. - -The reference implementation of Sapling, -`librustzcash `_, was -integrated in the Tezos codebase during 2019. It will be proposed as -part of a protocol amendment during 2020. - -Librustzcash and the Tezos integration implement the protocol -described in this `specification -`_, version 2020.1.0. - - -Sapling -------- - -Keys -~~~~ - -Sapling offers a rich set of keys, each allowing different operations. -A `spending key` allows to spend tokens so if it is lost or -compromised the tokens could remain locked or be stolen. -From a spending key it is possible to derive a corresponding `viewing -key` which allows to view all incoming and outgoing transactions. -The viewing key allows the owner of the tokens to check their balance -and transaction history so if compromised there is a complete loss of -privacy. -On the other hand a viewing key can willingly be shared with a third -party, for example with an auditor for regulatory compliance purposes. - -A viewing key can also derive several diversified `addresses`. -An address can be used to receive funds, much like the address of an -implicit account. - -Additionally `proving keys` can be used to allow the creation of proofs, -thus revealing private information, without being able to spend funds. -They are useful for example in case the spending key is stored in a -hardware wallet but we'd like to use our laptop to craft the -transaction and produce the zero-knowledge proofs, which are -computationally too intensive for an embedded device. - -More details can be found in the `specification document -`_. - -Shielded transactions -~~~~~~~~~~~~~~~~~~~~~ - -Transactions use Bitcoin's UTXO model with the important difference that each -input and output, instead of containing an amount and an address, -are just cryptographic `commitments`. -In order to avoid double spends, it's important to be able to check -that a commitment has not already been spent. In Bitcoin we just need to -check if an output is also later used as an input to verify if it's -already spent. In Sapling however we can't know because inputs are not -linked to outputs. -For this reason for each input of a transaction, the owner must also -publish a `nullifier`, which invalidates it. The nullifier can only be -produced by the owner of a commitment and it's deterministic so that -everybody can check that it hasn't been already published. -Note however that it is not possible to infer which commitment has -been nullified. -Transactions of this form are privacy preserving and are referred to -as `shielded`, because they reveal neither the amount, the sender nor -the receiver. - -The existing set of transactions is referred to as the `shielded pool`. -Unlike Bitcoin, where everybody can compute the set of unspent -outputs of every user, in Sapling only the owner of a viewing key can -find their outputs and verify that they are not already spent. -For this reason, to an external -observer, the shielded pool is always increasing in size and the more -transactions are added the harder it is to pinpoint the commitments -belonging to a user. - -When we spend a commitment there is some additional information that -we need to transmit to the recipient in order for them to spend the -corresponding output. -This data is encrypted under a symmetric key resulting from a -Diffie-Hellman key exchange using the recipient address and an -ephemeral key. -In principle this `ciphertext` can be transmitted off-chain as it's -not needed to verify the integrity of the pool. For convenience, in -Tezos, it is stored together with the commitment and the nullifier on -chain. - -For reasons of efficiency the commitments are stored in an incremental -`Merkle tree `_ which -allows for compact proofs of membership. The root of the tree is all -that is needed to refer to a certain state of the shielded pool. - -In order to ensure the correctness of a transaction, given that there -is information that we wish to remain secret, the spender must also -generate proofs that various good properties are true. -Thanks to the use of `SNARKs `_ -these proofs are very succinct in size, fast to verify and they don't -reveal any private information. - -This model of transaction adapts elegantly to the case when we need to -mint or burn tokens, which is needed to shield or unshield from a -transparent token. -It suffices to add more values in the outputs than in the inputs -to mint and to have more in inputs than outputs to burn. - -Privacy guarantees -~~~~~~~~~~~~~~~~~~ - -We explained that the shielded pool contains one commitment for each -input (spent or not), and one nullifier for each spent input. -These cryptographic commitments hide the amount and the owner of the -tokens they represent. -Additionally commitments are unlinkable meaning that we can not deduce -which input is spent to create an output. - -It should be noted that the number of inputs and outputs of a -transaction is public, which could help link a class of -transactions. This problem can be mitigated by adding any number of -dummy inputs or outputs at the cost of wasting some space. - -The shielded pool communicates with the public ledger by minting and -burning shielded tokens in exchange for public coins. -Therefore going in and out of the shielded pool is public: we know -which address shielded or unshielded and how much. -We can among other things infer the total number of shielded coins. - -Timing and network information can also help to deduce some private -information. -For example by observing the gossip network we might learn the IP -address of somebody that is submitting a shielded transaction. -This can be mitigated by using `TOR -`_. - -Good practices -~~~~~~~~~~~~~~ - -When blending in a group of people, one should always pay attention to -the size and the variety of the group. - -We recommend two good practices. First, do not originate a second -contract if another one has the same functionalities, it will split -the anonymity set. - -Second, remember that shielding and unshielding are public operations. -A typical anti-pattern is to shield from tz1-alice 15.3 tez, and then -unshield 15.3 tez to tz1-bob. It's fairly clear from timing and -amounts that Alice transferred 15.3 tez to Bob. -To decorrelate the two transfers it is important to change the -amounts, let some time pass between the two and perform the -transactions when there is traffic in the pool. -Similar problems exist in Zcash and they are illustrated in this -introductory `blog post -`_. - -There are a number of more sophisticated techniques to deanonymise -users using timing of operations, network monitoring, side-channels on -clients and analysis of number of inputs/outputs just to mention a few -(`A fistful of Bitcoins -`_ is a good -first read). -We advice users to be familiar with the use of the TOR network and to -use clients developed specifically to protect their privacy. - - -Tezos integration ------------------ - -Michelson: verify update -~~~~~~~~~~~~~~~~~~~~~~~~ - -We introduce two new Michelson types `sapling_state` and -`sapling_transaction`, and two instructions called -`SAPLING_VERIFY_UPDATE` and `SAPLING_EMPTY_STATE` -(see the :doc:`Michelson reference` -for more details). -`SAPLING_EMPTY_STATE` pushes an empty `sapling_state` on the stack. -`SAPLING_VERIFY_UPDATE` takes a transaction and a state and returns an -option type which is Some (updated -state and a balance) if the transaction is correct, None otherwise. -A transaction has a list of inputs, outputs, a signature, a balance, -and the root of the Merkle tree containing its inputs. -The verification part checks the zero-knowledge proofs of all inputs -and outputs of the transaction, which guarantee several properties of -correctness. -It also checks a (randomised) signature associated with each input -(which guarantees that the owner forged the transaction), and the -signature that binds the whole transaction together and guarantees the -correctness of the balance. -All the signatures are over the hash of the data that we wish to sign -and the hash function used is Blake2-b, prefixed with the anti-replay string. -The anti-replay string is the the concatenation of the chain id and -the smart contract address. The same string has to be used by the client for -signing. - -Verify_update also checks that the root of the Merkle tree appears in -one of the past states and that the nullifiers are not already -present (i.e. no double spending is happening). -If one of the checks fails the instruction returns None. - -Otherwise the function adds to the new state the nullifiers given with each inputs -and adds the outputs to the Merkle tree, which will produce a new root. -It should be noted that it is possible to generate transactions -referring to an old root, as long as the inputs used were present in -the Merkle tree with that root and were not spent after. -In particular the protocol keeps 120 previous roots and guarantees -that roots are updated only once per block. -Considering 1 block per minute and that each block contains at least -one call to the same contract, a client has 2 hours to have its -transaction accepted before it is considered invalid. - -The nullifiers are stored in a set. The ciphertexts and other relevant -information linked to the commitment of the Merkle tree are -stored in a map indexed by the position of the commitment in the -Merkle tree. - -Lastly the instruction pushes the updated state and the balance as an option -on the stack. - -Example contracts -~~~~~~~~~~~~~~~~~ - -Shielded tez -^^^^^^^^^^^^ - -An example contract to have a shielded tez with a 1 to 1 conversion to -tez is available in the tests of `lib_sapling`. - -Simple Vote Contract -^^^^^^^^^^^^^^^^^^^^ - -One might think to use Sapling to do private voting. -It is possible to adapt shielded transactions to express preferences. -**Note that this is not what Sapling is designed for and it doesn't provide the same properties as an actual private voting protocol.** -A natural naive idea is the following. -Suppose we want a set of users to express a preference for option A or -B, we can generate two Sapling keys with two addresses that are -published and represent the two options. -The contract lets each user create a token which represents one vote -that can then be transferred to address A or B. -Using the published viewing keys everyone can check the outcome of the -vote. -**However note that a transaction can be replayed and we can see the balance of A or B going up. -This system does not offer ballot privacy. -Therefore one should ensure that the vote he is casting cannot be linked to him. -It is possible that the practical situation makes this usable but we recommend in general not to use -it for any important vote.** -Note that using a random elliptic curve element as incoming viewing key allows to generate a -dummy address that cannot be spent. This eases the counting of the votes. -To ensure that the ivk does not correspond to a normal address with spending key, one -can use the Fiat-Shamir heuristic. - - -Fees issue -~~~~~~~~~~ - -We have an additional privacy issue that Z-cash doesn't have. When -interacting with a shielded pool we interact with a smart contract -with a normal transaction and therefore have to pay fees from an -implicit account. -One could guess that private transactions whose fees are paid by the -same implicit account are from the same user. -This can be mitigated by making a service that act as a proxy by -forwarding the user transactions and paying it fees. The user would -then include in the transaction a shielded output for the service that -covers the fees plus a small bonus to pay the service. -This output can be open by the service before sending the transaction -to check that there is enough money to cover its fees. As for Z-cash, -users interacting with the proxy should use TOR or mitigate network -analysis as they wish. - -Gas, storage and costs -~~~~~~~~~~~~~~~~~~~~~~ - -Gas evaluation is not yet done. - -RPCs -~~~~ - -There are two Sapling RPCs under the prefix `context/sapling`. -`get_size` returns a pair with the size of the set of commitments -and the size of the set of nullifiers. -`get_diff` takes two optional starting offsets `cm_from` and `nf_from` -and returns the sapling state that was added from the offsets to the -current size. In particular it returns three lists, commitments, -ciphertexts from position `cm_from` up to the last one added and -nullifiers, from `nf_from` to the last one added. -Additionally it returns the last computed root of the merkle tree so -that a client updating its tree using the diff can verify the -correctness of the result. - -Client -~~~~~~ - -Wallet -^^^^^^ - -tezos-client supports Sapling keys and can send -shielded transactions to smart contracts. - -The client supports two ways to generate a new Sapling spending key. -It can be generated from a mnemonic using `BIP39 -`_, so -that it can be recovered in case of loss using the mnemonic. -Alternatively it is possible to derive new keys from existing ones -using `ZIP32 -`_, a Sapling -variant of `BIP32 -`_ for -hierarchical deterministic wallets. As usual, in this case it is -important to note the derivation path of the key to be able to recover -it in case of loss. -At the moment there is no hardware wallet support, keys are stored in -`~/.tezos-client/sapling_keys` by default encrypted with a password. -**Users should take care to backup this file.** - -The client can also derive addresses from viewing keys. -By default addresses are generated using an increasing counter called -the address index. Not all indexes correspond to valid addresses for -each key so it is normal to see an increasing counter that -occasionally skips a few positions. - -Because for now the only support for Sapling keys is to interact with -smart contracts, the client binds each newly generated key to a -specific smart contract address. - -Operations -^^^^^^^^^^ - -The client also facilitates the creation of shielded transactions and -their transfer as arguments of smart contracts. -For now there is seamless integration to send transactions to the -reference shielded-tez contract and we are planning to support a -larger class of contracts. - -For the shielded-tez smart contract, the client supports shielding, -unshielding and shielded transactions. -In the case of shielded transactions there are two commands, one to -forge a transaction and save it to file and one to submit it to the -smart contract. -The idea is that a user should not use their own transparent tz{1,2,3} -address to submit a shielded address but rather have a third party -inject it. - -Message argument -^^^^^^^^^^^^^^^^ -Sapling also allows to send an arbitrary encrypted message attached -to an output. -The message size has to be fixed by pool for privacy reasons. -For now it is fixed overall at eight bytes. An incorrect message length -will raise a failure in our client and the protocol will reject the -transaction. Our client adds a default zero's filled message of the -right length. If a message is provided with the --message option, -the client will pad it or truncate it if necessary. A warning message -is printed only if the user's message is truncated. - - -Code base -~~~~~~~~~ - -The current code-base is organized in three main components. -There is a core library called `lib_sapling` which binds `librustzcash`, -adds all the data structures necessary to run the sapling -protocol and includes a simple client and baker. -Under the protocol directory there is a `lib_client_sapling` library -which implements a full client capable of handling Sapling keys and -forging transactions. -Lastly in the protocol there is a efficient implementation of the -Sapling storage, in the spirit of `big_map`s, and the integration of -`SAPLING_VERIFY_UPDATE` in the Michelson interpreter. - -Protocol -^^^^^^^^ - -In order to export the Sapling library to the protocol we first need -to expose it through the environment that sandboxes the protocol. -The changes under `src/lib_protocol_environment` are simple but very -relevant as any change of the environment requires a manual update of the -Tezos node. These changes are part of version V1 of the environment -while protocols 000 to 006 depends on version V0. - -There are two main changes to Tezos' economic protocol, the storage -for Sapling and the addition of `SAPLING_VERIFY_UPDATE` to the Michelson -interpreter. - -Given that the storage of a Sapling contract can be substantially -large, it is important to provide an efficient implementation. -Similarly to what it's done for big_maps, the storage of Sapling can't -be entirely deserialized and modified in memory but only a diff of the -changes is kept by the interpreter and applied at the end of each -smart contract call. - -In the Michelson interpreter two new types are added, `sapling_state` and -`sapling_transaction`, and the instruction `SAPLING_VERIFY_UPDATE`. - -Client -^^^^^^ - -Under `lib_client_sapling` there is the client integration -with the support for Sapling keys and forging of transactions. -The main difference from the existing Tezos client is the need for the -Sapling client to keep an additional state, for each contract. -Because Sapling uses a UTXO model it is necessary for a client to -compute the set of unspent outputs in order to forge new transactions. -Computing this set requires scanning all the state of a contract which -can be expensive. -For this reason the client keeps a local state of the unspent outputs -after the last synchronization and updates it before performing any -Sapling command. -The update is done using the RPCs to recover the new updates since the -last known position. - -The state of all sapling contracts is stored in -`~/.tezos-client/sapling_states`. This file can be regenerated from -the chain in case of loss. However disclosure of this file will reveal -the balance and the unspent outputs of all viewing keys. - -Memo -^^^^^^ - -Sapling offers the possibility to add an arbitrary memo to any -created output. The memo is encrypted and available to anyone -owning the outgoing viewing key or the spending key. -For privacy reasons the size of the memo is fixed per contract -and it is chosen at origination time. -A transaction containing an output with a different memo-size -will be rejected. - -Sandbox tutorial -~~~~~~~~~~~~~~~~ - -As usual it's possible to test the system end-to-end using the -:doc:`../user/sandbox`. -After having set up the sandbox and originated the contract, a good -way to get familiar with the system is to generate keys and then -perform the full cycle of shielding, shielded transfer and -unshielding. - -:: - - # set up the sandbox - ./src/bin_node/tezos-sandboxed-node.sh 1 --connections 0 & - eval `./src/bin_client/tezos-init-sandboxed-client.sh 1` - tezos-activate-alpha - - # originate the contract with its initial empty sapling storage, - # bake a block to include it. - # { } represents an empty Sapling state. - tezos-client originate contract shielded-tez transferring 0 from bootstrap1 \ - running src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract.tz \ - --init '{ }' --burn-cap 3 & - tezos-client bake for bootstrap1 - - # as usual you can check the tezos-client manual - tezos-client sapling man - - # generate two shielded keys for Alice and Bob and use them for the shielded-tez contract - # the memo size has to be indicated - tezos-client sapling gen key alice - tezos-client sapling use key alice for contract shielded-tez --memo-size 8 - tezos-client sapling gen key bob - tezos-client sapling use key bob for contract shielded-tez --memo-size 8 - - # generate an address for Alice to receive shielded tokens. - tezos-client sapling gen address alice - zet1AliceXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Alice's address - - - # shield 10 tez from bootstrap1 to alice - tezos-client sapling shield 10 from bootstrap1 to zet1AliceXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX using shielded-tez --burn-cap 2 & - tezos-client bake for bootstrap1 - tezos-client sapling get balance for alice in contract shielded-tez - - # generate an address for Bob to receive shielded tokens. - tezos-client sapling gen address bob - zet1BobXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Bob's address - - # forge a shielded transaction from alice to bob that is saved to a file - tezos-client sapling forge transaction 10 from alice to zet1BobXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX using shielded-tez - - # submit the shielded transaction from any transparent account - tezos-client sapling submit sapling_transaction from bootstrap2 using shielded-tez --burn-cap 1 & - tezos-client bake for bootstrap1 - tezos-client sapling get balance for bob in contract shielded-tez - - # unshield from bob to any transparent account - tezos-client sapling unshield 10 from bob to bootstrap1 using shielded-tez --burn-cap 1 - ctrl+z # to put the process in background - tezos-client bake for bootstrap1 - fg # to put resume the transfer diff --git a/docs/012/timelock.rst b/docs/012/timelock.rst deleted file mode 100644 index 9083bfa1c44e..000000000000 --- a/docs/012/timelock.rst +++ /dev/null @@ -1,129 +0,0 @@ -Time locked Michelson against Block Producer Extractable Value -============================================================== - - -Block Producer Extractable Value --------------------------------- - -We aim at tackling the issue known through -the unfortunate misnomer of "generalized front running", described -for instance in `here `__. - -Observing a transaction before it is actually included in the chain -can give an advantage to a trader against another one. Ultimately, -this means block producers can extract a rent from the system -as they have the ability to choose and order transactions in a block. -This is sometimes referred to, in proof-of-work networks like Ethereum as -`Miner Extractable Value `_ or MEV for shorts. -We refer to it as BPEV, for "Block producer extractable value" -or "Baker pecuniary extractable value", at the reader's preference. -We also note that the term "front-running" is regrettable as it can mislead people -into thinking there is a fiduciary relationship between block producers -and transaction emitters where, in fact, none exists unless explicitly contracted into. - -For example, upon receiving a transaction, a baker could craft a block including -this transaction and one of his such that the sequential execution of these -two transactions guarantees a gain to the baker. - -Timelock --------- - -We propose a solution to alleviate this issue which is relatively easy to implement -and is based on time lock encryption -(see -`Timelock puzzles and timed release Crypto `_ -for more details). - -Time lock encryption allows to encrypt a message such that it can be -decrypted in two ways. -Either the author of the ciphertext produces a plaintext -(and a proof of correct decryption) -by providing a secret trapdoor (the factorization of an RSA modulus in our case). -Otherwise a sequential computation can decrypt the ciphertext after a computation -requiring ``T`` sequential operations (modular squaring in our case), -for some pre-determined constant ``T``. - -In addition, a proof of the correctness of the decryption can also be produced and checked in sub linear time (``log T`` in our case). - -By experimentally measuring the time the sequential operation takes -on available hardware using optimized implementation, we can estimate -a rough conversion (or a bound in our case) between the constant ``T`` and -wall clock time. -We also note that the `VDF alliance `_ has been working on producing an ASIC for squaring in an RSA group to -ensure a level playing field in terms of computational speed. - -An implementation of the timelock puzzle -and proof scheme is available in :src:`src/lib_crypto/timelock.mli` inspired from -a proof of concept available -`here `__. - -General principle ------------------ - -To limit BPEV, we introduce in Michelson an opcode (``OPEN_CHEST``) and two types (``chest`` and ``chest_key``) allowing -timelock-encrypted values to be used inside a Michelson contract. - -The typical usage pattern would be as follows: - -1. In a first period, a contract collects user-submitted and timelock encrypted Michelson values along with some valuable deposit, such as tez. -2. In a second period, after the values are collected, the contract collects from users a decryption of the value they submitted alongside with a proof that the decryption is correct. -3. In a third period, if any value remains undecrypted, anyone can claim part of the deposit by submitting a decryption of the value, with the other part of the deposit being burnt. Different penalties can be assessed depending on whether the user merely failed to submit a decryption for their value, or if they also intentionally encrypted invalid data. Different rewards can be distributed for submitting a correct decryption. The third period needs to be long enough so that people have enough time to perform the timelock decryption. -4. Finally, the contract can compute some function of all the decrypted data. - -There is generally no incentive for users not to provide -the decryption of their data and thus the third period generally does not need -to take place. However, the second period needs to be long enough so that bakers -cannot easily censor submission of the decryption in a bid to later claim the reward. -Burning a part of the deposit also limits grieving attacks where a user gets back -their whole deposit by providing the decryption, but in a way that delays everyone else. - -Cryptographic principles ------------------------- - -Users first generate a RSA modulus and a symmetric encryption key. -They use authenticated encryption to encrypt a packed Michelson value (an array of bytes computed with ``PACK``) -and encrypt that encryption key using a timelock puzzle. -They then combine the RSA modulus, the timelocked symmetric key, the constant ``T`` -and the encrypted value as a single value as well (called chest in our library in :src:`src/lib_crypto`). - -A proof of decryption can be the symmetric key itself. -However, a malicious user could propose an authenticated ciphertext that does yield a valid value -even when decrypted with the symmetric key that was indeed time locked. -To avoid this threat, an opening (called -the chest_key in our library) includes the symmetric key and -a proof that the symmetric key proposed is indeed the one hidden in the timelock puzzle. -In this way we can differentiate whether the chest or the chest key was proposed by a -malicious user. - -Finally, our library exposes an ``open_chest`` function taking a chest, a chest key and -produces either the underlying plaintext or indicates that the chest or the chest key is -malicious. - -Proposed opcode and types ---------------------------- - -To expose the features added by our library, we introduce the following Michelson types: - -- ``chest``, which represents timelocked arbitrary bytes with the - necessary public parameters to open it. -- ``chest_key``, which represents the decryption key, - alongside with a proof that the key is correct. - -and the following opcode: - -``unlock :: chest_key → chest → time →or (bytes, bool)`` - -If everything is correct it pushes -``Left bytes`` on top of the stack where bytes are -cryptographically guaranteed to be the bytes the chest provider timelocked. -If the ciphertext does not decrypt under the symmetric key that was timelocked, it pushes on the stack -``Right False`` -If the provided symmetric key was not the one timelocked -(which we detect thanks to the timelock proof), -it pushes on the stack ``Right True``. -Note that we are using an authenticated encryption scheme, -so we can detect if someone provides a wrong key while fooling the time lock proof. -This is doable only by someone knowing the factorisation of the RSA modulus. -However, this cannot prevent someone from encrypting a wrong key, or putting -a wrong message authentication code, -so this is why we still need the proof of correctness. diff --git a/docs/012/voting.rst b/docs/012/voting.rst deleted file mode 100644 index ff20806f5a3d..000000000000 --- a/docs/012/voting.rst +++ /dev/null @@ -1,331 +0,0 @@ -The Amendment (and Voting) Process -================================== - -In the Tezos blockchain, the *economic protocol* can be amended. Specifically, -there is an on-chain mechanism to propose changes to the economic protocol, to -vote for-or-against these proposed changes, and, depending on the result of the -vote, to activate these changes or not. - -Note that the proposal, voting and activation processes are part of the economic -protocol itself. Consequently the amendment rules themselves are subject to -amendments. - -The rest of this page gives more details about the amendment and voting process. - -Periods -------- - -The amendment process consists of five *periods*. Each period lasts for 40960 -blocks (5 cycles) (or approximately two weeks). The periods (listed below) -typically succeed one another for a total duration of approximately 2 months and -a half, after which the whole amendment process starts again. - -The five periods are as follows: - -- *Proposal period*: During this period, delegates can - - - submit *protocol amendment proposals* (or, simply, *proposals*) using the - ``Proposals`` operation (see below), - - support a proposal using the ``Ballot`` operation (see below). - - Each delegate can submit a maximum of 20 proposals. Duplicates count towards - this total. - - At the end of a **proposal period**, the proposal with most support is - selected and we move to an **exploration period**. Note that support is - measured in the cumulated number of :ref:`rolls ` that delegates supporting the - proposal have. E.g., a proposal supported by a single delegate with 100 rolls - has more support than a proposal supported by two delegates with 20 rolls - each. - - If there are no proposals, or a tie between two or more proposals, the process - moves back to a new **proposal period**. - -- *Exploration period*: During this period delegates can cast one - Yay, Nay, or Pass ballot on the selected proposal. They do so using the - ``Ballot`` operation. - - If the voting participation reaches *quorum* and there is a *super-majority* - of Yay, the process moves to the **cooldown period**. (See below for details - on participation, quorum, and super-majority.) - - Otherwise the process moves back to the **proposal period**. - -- *Cooldown period*: On-chain nothing specific happens during this period. - Off-chain the delegates can read the proposal with more scrutiny, the - community can discuss finer points of the proposal, the developers can - perform additional tests, etc. - - At the end of this period, the process moves to the **promotion period**. - -- *Promotion period*: During this period, delegates can cast a Yay, Nay, or Pass - ballots using the ``Ballot`` operation. - - If the voting participation reaches *quorum* and there is a super-majority of - Yay, the process moves to the **adoption period**. - - Otherwise the process moves back to the **proposal period**. - -- *Adoption period*: On-chain nothing specific happens during this period except - on the very last block (see below). - - Off-chain the developers release tools that include support for the - soon-to-be activated protocol, other actors (bakers, indexers, etc.) update - their infrastructure to support the newly released tools, smart-contract - developers start working with soon-to-be-available features, etc. - - At the very end of the period, the proposal is *activated*. This means that - the last block of the period is still interpreted by the current economic - protocol, but the first block after the period is interpreted by the new - economic protocol (the one that was voted in). - - And a new **proposal period** starts. - - -Activation ----------- - -After the activation step, the blocks added to the chain are interpreted in the -newly activated protocol. As a result gas costs may differ, new operations may -be available, contracts using new opcodes may be injected, etc. - -Because the amendment process is also part of the economic protocol, the -amendment process now unfolds according to the rules of the newly activated -protocol. As a result the periods may be lengthened or shortened, a new period -might be introduced, a different selection mechanism may be used, the quorum -requirement might differ, etc. - - -Voting Power ------------- - -When supporting a proposal or casting a Yay, Nay, or Pass ballot, each delegate -has voting power equal to its *stake*. The stake is always measured in -**number of rolls**. - -Note that the stake of each delegate is computed at the beginning of each -period. - - -Super-majority and Quorum -------------------------- - -As mentioned above, during either of the **proposal** or **promotion** periods, -delegates can cast ballots using the ``Ballot`` operation (see below). -In both cases, delegates can cast a single Yay, Nay, or Pass ballot. A ballot -has a weight equal to the delegate's stake as detailed above. - -For either of these two periods, the process continues to the next period if the -*vote participation* reaches *quorum* and there is a *super-majority* of -Yay. - -The *vote participation* is the ratio of all the cumulated stake of cast ballots -(including Pass ballots) to the total stake. - -For the first voting period, the *quorum* started at 80% of stake. The quorum is -adjusted after each vote as detailed below. This adjustment is necessary to -ensure that the amendment process can continue even if some delegates stop -participating. After each vote the new quorum is updated based on the old quorum -and the **vote participation** with the following coefficients:: - - new-quorum = 0.8 × old-quorum + 0.2 × participation - -The *super-majority* is reached if the cumulated stake of Yay ballots is -greater than 8/10 of the cumulated stake of Yay and Nay ballots. - -Note that Pass ballots do not count towards or against the super-majority; -they still counts towards participation and quorum. - -More details can be found in the file -:src:`src/proto_012_Psithaca/lib_protocol/amendment.ml`. - - -The Hash and the Protocol -------------------------- - -On the one hand, the voting part of the process revolves around the -**hash of a protocol**. Specifically, a delegate submits a hash of a -protocol, and all the delegates cast ballots on the proposed hash. -The *hash of a protocol* is the hash of the files that constitute the source -code of the protocol. - -On the other hand, the **protocol activation** (at the end of the -**adoption period**) revolves around the compiled sources of the protocol. - -Basically, the voting process works on an identifier of the protocol whilst the -activation step works on the protocol itself. Consequently, if a protocol hash -is voted in and the protocol it identifies is invalid, the activation step -fails. - -.. sidebar:: Checking a hash is of a valid protocol - - When a hash is proposed by a delegate, it is usually accompanied by some - blogposts and forum threads on :ref:`community websites `. - These should include directions for testing the proposed protocols. If you - cannot find such directions, do not hesitate to ask. - -.. sidebar:: Localised failures - - It is possible that the activation step fails on a single node or a few nodes - of the network, but succeed on the others. In this case the nodes with the - failure are stuck, but the network as a whole continues. - - The most likely cause for this is nodes that have not been updated and do not - include a new protocol environment version. - - If your node becomes stuck, you should start a fresh up-to-date node. - -A protocol is *invalid* if its code cannot be compiled (e.g., if the code is not -valid source code), if its code uses functions not present in the -:doc:`protocol environment <../developer/protocol_environment>`, or if it -downgrades the protocol environment version. - -If an invalid protocol is voted in, then the activation fails for all the nodes, -and then the chain becomes stuck. This is why it is important to vote for hashes -that designate valid protocols: ones with sources that are available and that -can be compiled. - -Operations ----------- - -There are two operations used by the delegates: **proposals** and **ballot**. - -A *proposals* operation can only be injected during a proposal period. - -:: - - Proposals : { - source: Signature.Public_key_hash.t ; - period: Voting_period_repr.t ; - proposals: Protocol_hash.t list ; } - -The ``source`` is the public key hash of the delegate, ``period`` is the unique -identifier of each voting period and ``proposals`` is a non-empty list of -maximum 20 protocol hashes. -The operation can be submitted more than once but only as long as the -cumulative length of the proposals lists is less than 20. -Duplicate proposals from the same delegate are accounted for in the -maximum number of proposals for that delegate. -However duplicates from the same delegate are not tallied at the end -of the proposal period. - -For example, a delegate submits a *proposals* operation for protocols A -and B early in the proposal period, later a new protocol C is revealed -and the delegate submits another *proposals* operation for protocols B -and C. -The list of submissions that will be tallied is [A,B,C]. - -A *ballot* operation can only be submitted during one of the voting -periods, and only once per period. - -:: - - Ballot : { - source: Signature.Public_key_hash.t ; - period: Voting_period_repr.t ; - proposal: Protocol_hash.t ; - ballot: Vote_repr.ballot ; } - -The fields ``source`` and ``period`` are the same as above, while ``proposal`` -is the currently selected proposal and ``ballot`` is one of ``Yay``, ``Nay`` or -``Pass``. -The ``Pass`` vote allows a delegate to contribute towards the quorum without -contributing towards the super-majority. This is important because, as detailed -above, the quorum is adaptive and that low participation would lower the -quorum of the next vote. - -More details on the operations can be found in -:src:`src/proto_012_Psithaca/lib_protocol/operation_repr.ml`. -The binary format is described by -``tezos-client describe unsigned operation``. - -Client Commands ---------------- - -The Octez client, ``tezos-client``, provides commands for basic exploration and -interaction with the amendment and voting process. - - -Show -~~~~ - -Tezos' client provides a command to show the status of a voting period. -It displays different information for different kind of periods, as -in the following samples:: - - $ tezos-client show voting period - Current period: "proposal" - Blocks remaining until end of period: 59 - Current proposals: - PsNa6jTtsRfbGaNSoYXNTNM5A7c3Lji22Yf2ZhpFUjQFC17iZVp 400 - - $ tezos-client show voting period - Current period: "exploration" - Blocks remaining until end of period: 63 - Current proposal: PsNa6jTtsRfbGaNSoYXNTNM5A7c3Lji22Yf2ZhpFUjQFC17iZVp - Ballots: { "yay": 400, "nay": 0, "pass": 0 } - Current participation 20.00%, necessary quorum 80.00% - Current in favor 400, needed supermajority 320 - - $ tezos-client show voting period - Current period: "cooldown" - Blocks remaining until end of period: 64 - Current proposal: PsNa6jTtsRfbGaNSoYXNTNM5A7c3Lji22Yf2ZhpFUjQFC17iZVp - -It should be noted that the ballot number 400 above is the stake counted in -number of rolls. -The proposal has a total stake of 400 rolls, which may come from a single ballot -from a delegate having 400 rolls, or it may come from multiple ballots from -delegates with a combined stake of 400 rolls. - - -Submit proposals -~~~~~~~~~~~~~~~~ - -During a proposal period, a list of proposals can be submitted with:: - - tezos-client submit proposals for ... - -Remember that each delegate can submit a maximum of 20 protocol -hashes and that duplicates count towards this total. -Moreover each proposal is accepted only if it meets one of the -following two conditions: - -- the protocol hash was already proposed on the network. In this case - we can submit an additional proposal that "upvotes" an existing one - and our rolls are added to the ones already supporting the proposal. -- the protocol is known by the node. In particular the first proposer - of a protocol should be able to successfully inject the protocol in - its node which performs some checks, compiles and loads the - protocol. - -These are protection measures that the Octez client takes to prevent the -accidental injection of invalid protocols. As mentioned above, it is still -important to check the validity of the protocols that you vote for as they may -have been injected via different means. - - -Submit ballots -~~~~~~~~~~~~~~ - -During either of the **exploration** or **promotion** periods, -ballots can be submitted once with:: - - tezos-client submit ballot for - -Further External Resources --------------------------- - -Further details and explanations on the voting procedure can be found at: - -- `Governance on-chain `_ on Open Tezos -- `Tezos Governance `_ on Tezos Agora. - -For more details on the client commands refer to the manual at -:ref:`client_manual_012`. - -For vote related RPCs check the :doc:`rpc` under the prefix -``votes/``. - -For Ledger support refer to Obsidian Systems' `documentation -`__. diff --git a/docs/index.rst b/docs/index.rst index b0d2a5d9c0a1..f46bdb6a9f33 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -160,15 +160,6 @@ in the :ref:`introduction `. active/cli-commands active/rpc -.. toctree:: - :maxdepth: 2 - :caption: 012 Ithaca Protocol doc: - - 012/protocol - 012/glossary - 012/cli-commands - 012/rpc - .. toctree:: :maxdepth: 2 :caption: Alpha Development Protocol doc: @@ -217,7 +208,6 @@ in the :ref:`introduction `. protocols/009_florence protocols/010_granada protocols/011_hangzhou - protocols/012_ithaca protocols/alpha .. toctree:: diff --git a/docs/protocols/012_ithaca.rst b/docs/protocols/012_ithaca.rst deleted file mode 100644 index b247774caf9d..000000000000 --- a/docs/protocols/012_ithaca.rst +++ /dev/null @@ -1,160 +0,0 @@ -Protocol Alpha -============== - -This page contains all the relevant information for protocol Alpha -(see :ref:`naming_convention`). - -The code can be found in the :src:`src/proto_012_Psithaca` directory of the -``master`` branch of Tezos. - -This page documents the changes brought by protocol Alpha with respect -to Hangzhou. - -.. contents:: - -New Environment Version (V4) ----------------------------- - -This protocol requires a different protocol environment than Hangzhou. -It requires protocol environment V4, compared to V3 for Hangzhou. -(MRs :gl:`!3379`, :gl:`!3468`) - -- Move BLS12-381 to blst backend. (MR :gl:`!3296`) - -- Expose BLS signature module. (MR :gl:`!3470`) - -- Remove Error-monad compat layer. (MR :gl:`!3575`) - -- Allow different type of error categories in the different error monads. - (MR :gl:`!3664`) - -- Fix interface of Hex. (MR :gl:`!3267`) - -- Fix use of Micheline canonical encoding. (MR :gl:`!3764`) - -- Add concat_map. (MR :gl:`!3801`) - -- Make Micheline.canonical_location abstract. (MR :gl:`!3744`) - -- Error_monad: better tracing primitives. (MR :gl:`!3589`) - -- Error-monad: simpler trace_eval. (MR :gl:`!3869`) - -- Add missing functions from Lwtreslib. (MR :gl:`!3905`) - -- Expose an order for folding over the context. (MR :gl:`!3910`) - -Tenderbake ----------- - -- Tenderbake is a new consensus algorithm replacing Emmy* in order to provide deterministic finality. (MR :gl:`!3738`) - -- The list of breaking changes related to Tenderbake are described in a separate :doc:`change log`. - -- Further, related changes after the main MR has been merged: - - - Export participation RPC. (MR :gl:`!3822`) - - - Rename Bonds to Deposits. (MR :gl:`!3832`) - - - Fix issues related to token management in Tenderbake. (MR :gl:`!3811`) - - - Inherit block times. (MR :gl:`!3850`) - - - Address comments on Tenderbake. (MR :gl:`!3906`) - - - Small updates to the ``../delegates//..`` RPCs. (MR :gl:`!3977`) - -- Fix issues with receipts (MR :gl:`!3987`) - -Tickets Hardening ------------------ - -- Add ticket-balance storage module. (MR :gl:`!3495`) - -- Add API for scanning values for tickets. (MR :gl:`!3591`) - -- Add API for generating ticket-balance key hashes. (MR :gl:`!3788`) - -Michelson ---------- - -- A new ``SUB_MUTEZ`` instruction has been added, it is similar to the - ``mutez`` case of the ``SUB`` instruction but its return type is - ``option mutez`` instead of ``mutez``. This allows subtracting - ``mutez`` values without failing in case of underflow. (MR :gl:`!3079`) - -- The ``SUB`` instruction on type ``mutez`` is deprecated. It can be - replaced by ``SUB_MUTEZ; ASSERT_SOME`` (and ``SUB; DROP`` can be - replaced by ``ASSERT_CMPGE``). (MR :gl:`!3079`) - -- The ``MAP`` instruction can now also be applied to values of type ``option - a``. In this case the block of code given is executed if and only if the value - at the top of the stack is ``Some a``. It should map the value at the top of - the stack into a value of any type ``b``. The block has access to the - remainder of the stack also, but its type should remain unchanged. The result - of the instruction is the stack returned by the applied block of code, where - the value at the top is wrapped in ``Some`` again. If the value at the top of - input stack is ``None``, the instruction does nothing. (MR :gl:`!3574`) - -Precheck of operations ----------------------- - -- Expose `precheck_manager` and `check_manager_signature` (MR :gl:`!3872`) - -- Remove the gas block limit for prevalidator mode. (MR :gl:`!3802`) - -Bug Fixes ---------- - -- Use Cache_costs.cache_find in cache find. (MR :gl:`!3752`) - -- Fix gas accounting for the deserialization of Michelson arguments in - operations. (MR :gl:`!3930`) - -Minor Changes -------------- - -- Update and simplify fixed constants. (MR :gl:`!3454`) - -- Simplify pack cost. (MR :gl:`!3620`) - -- Do not play with locations inside protocol. (MR :gl:`!3667`) - -- Remove the optional entrypoint in ticketer address. (MR :gl:`!3570`) - -- Make delegate optional for bootstrap contracts. (MR :gl:`!3584`) - -- Fix interface of Hex. (MR :gl:`!3267`) - -- Update migration for protocol "I". (MR :gl:`!3668`) - -- Make `max_operations_ttl` a parametric constant of the protocol, now called - `max_operations_time_to_live`. (MR :gl:`!3709`) - -- ``NOW`` and ``LEVEL`` are now passed to the Michelson interpreter as - step constants instead of being read from the context each time - these instructions are executed. (MR :gl:`!3524`) - -- The RPC ``../helpers/current_level`` does not support anymore a - negative ``offset`` argument. The level which used to be returned by - ``..//helpers/current_level?offset=-`` can still be obtained by - ``..//helpers/current_level``. (MR :gl:`!3808`) - -- Ensure annotations are non-empty. (MR :gl:`!3746`) - -- Only allow positive depth in context query RPC and other RPC. - (MR :gl:`!3564`) - -- Liquidity Baking: postpone the sunset level by 819,200 blocks and - decrease the escape hatch threshold from one half to one third. - (MR :gl:`!3911`) - -- Bump up bls12-381.1.1.0. (MRs :gl:`!3914`, :gl:`!3942`) - -- Other internal refactorings or documentation. (MRs :gl:`!3506`, :gl:`!3550`, - :gl:`!3593`, :gl:`!3552`, :gl:`!3588`, :gl:`!3612`, :gl:`!3575`, - :gl:`!3622`, :gl:`!3631`, :gl:`!3630`, :gl:`!3707`, :gl:`!3644`, - :gl:`!3529`, :gl:`!3739`, :gl:`!3741`, :gl:`!3695`, :gl:`!3763`, - :gl:`!3779`, :gl:`!3745`, :gl:`!3256`, :gl:`!3326`, :gl:`!3812`, - :gl:`!3920`, :gl:`!3929`) diff --git a/src/lib_protocol_compiler/final_protocol_versions b/src/lib_protocol_compiler/final_protocol_versions index 7839b0347248..102e0e09a1fa 100644 --- a/src/lib_protocol_compiler/final_protocol_versions +++ b/src/lib_protocol_compiler/final_protocol_versions @@ -11,5 +11,4 @@ PtEdoTezd3RHSC31mpxxo1npxFjoWWcFgQtxapi51Z8TLu6v6Uq PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i PtGRANADsDU8R9daYKAgWnQYAJ64omN1o3KMGVCykShA97vQbvV -PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx -PsithacaTTq3oumpKDw1pVvRrAtqiK4hKnP3Q4FNrXN9yc6KPhp \ No newline at end of file +PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx \ No newline at end of file diff --git a/src/proto_012_Psithaca/bin_accuser/.ocamlformat b/src/proto_012_Psithaca/bin_accuser/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/bin_accuser/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/bin_accuser/dune b/src/proto_012_Psithaca/bin_accuser/dune deleted file mode 100644 index 4da948f22e49..000000000000 --- a/src/proto_012_Psithaca/bin_accuser/dune +++ /dev/null @@ -1,20 +0,0 @@ -; build static executable with --profile static -(env - (static - (flags (:standard - -ccopt -static)))) - -(executable - (name main_accuser_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-accuser-012-Psithaca) - (libraries tezos-client-base-unix - tezos-client-commands - tezos-baking-012-Psithaca-commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_baking_012_Psithaca_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix))) diff --git a/src/proto_012_Psithaca/bin_accuser/dune-project b/src/proto_012_Psithaca/bin_accuser/dune-project deleted file mode 100644 index 97aa51842c2f..000000000000 --- a/src/proto_012_Psithaca/bin_accuser/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-accuser-alpha) diff --git a/src/proto_012_Psithaca/bin_accuser/main_accuser_012_Psithaca.ml b/src/proto_012_Psithaca/bin_accuser/main_accuser_012_Psithaca.ml deleted file mode 100644 index 2b995988014a..000000000000 --- a/src/proto_012_Psithaca/bin_accuser/main_accuser_012_Psithaca.ml +++ /dev/null @@ -1,38 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let () = - Client_commands.register Protocol.hash @@ fun _network -> - List.map (Clic.map_command (new Protocol_client_context.wrap_full)) - @@ Baking_commands.accuser_commands () - -let select_commands _ _ = - return - (List.map - (Clic.map_command (new Protocol_client_context.wrap_full)) - (Baking_commands.accuser_commands ())) - -let () = Client_main_run.run (module Daemon_config) ~select_commands diff --git a/src/proto_012_Psithaca/bin_accuser/tezos-accuser-012-Psithaca.opam b/src/proto_012_Psithaca/bin_accuser/tezos-accuser-012-Psithaca.opam deleted file mode 100644 index d1b3fe99ff3a..000000000000 --- a/src/proto_012_Psithaca/bin_accuser/tezos-accuser-012-Psithaca.opam +++ /dev/null @@ -1,20 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-client-012-Psithaca" - "tezos-client-commands" - "tezos-baking-012-Psithaca-commands" - "tezos-client-base-unix" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: accuser binary" diff --git a/src/proto_012_Psithaca/bin_baker/.ocamlformat b/src/proto_012_Psithaca/bin_baker/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/bin_baker/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/bin_baker/dune b/src/proto_012_Psithaca/bin_baker/dune deleted file mode 100644 index dd7b9eadd9bd..000000000000 --- a/src/proto_012_Psithaca/bin_baker/dune +++ /dev/null @@ -1,20 +0,0 @@ -; build static executable with --profile static -(env - (static - (flags (:standard - -ccopt -static)))) - -(executable - (name main_baker_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-baker-012-Psithaca) - (libraries tezos-client-base-unix - tezos-client-commands - tezos-baking-012-Psithaca-commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_baking_012_Psithaca_commands - -open Tezos_stdlib_unix - -open Tezos_client_base_unix))) diff --git a/src/proto_012_Psithaca/bin_baker/dune-project b/src/proto_012_Psithaca/bin_baker/dune-project deleted file mode 100644 index 5fab06455dee..000000000000 --- a/src/proto_012_Psithaca/bin_baker/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-baker-alpha) diff --git a/src/proto_012_Psithaca/bin_baker/main_baker_012_Psithaca.ml b/src/proto_012_Psithaca/bin_baker/main_baker_012_Psithaca.ml deleted file mode 100644 index 3115253b9427..000000000000 --- a/src/proto_012_Psithaca/bin_baker/main_baker_012_Psithaca.ml +++ /dev/null @@ -1,38 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let () = - Client_commands.register Protocol.hash @@ fun _network -> - List.map (Clic.map_command (new Protocol_client_context.wrap_full)) - @@ Baking_commands.baker_commands () - -let select_commands _ _ = - return - (List.map - (Clic.map_command (new Protocol_client_context.wrap_full)) - (Baking_commands.baker_commands ())) - -let () = Client_main_run.run (module Daemon_config) ~select_commands diff --git a/src/proto_012_Psithaca/bin_baker/tezos-baker-012-Psithaca.opam b/src/proto_012_Psithaca/bin_baker/tezos-baker-012-Psithaca.opam deleted file mode 100644 index 9613387a4af7..000000000000 --- a/src/proto_012_Psithaca/bin_baker/tezos-baker-012-Psithaca.opam +++ /dev/null @@ -1,20 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-client-012-Psithaca" - "tezos-client-commands" - "tezos-baking-012-Psithaca-commands" - "tezos-client-base-unix" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: baker binary" diff --git a/src/proto_012_Psithaca/lib_benchmark/.ocamlformat b/src/proto_012_Psithaca/lib_benchmark/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_benchmark/README.md b/src/proto_012_Psithaca/lib_benchmark/README.md deleted file mode 100644 index 8adba76cbf90..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# `Tezos_benchmark_alpha` - -This library is dedicated to sampling Michelson values and in particular -Michelson programs. - -## Architecture - -This library provides a sampling-based interface for well-typed -Michelson generation. Internally, this library is built on a sampler for an -intermediate language called Mikhailsky post-composed with a function to -map Mikhailsky terms to Michelson ones. - -### Layer 1: Mikhailsky - Mikhailsky corresponds to "Michelson with typed holes". Mikhailsky terms - are encoded inside Micheline. The library `lib_benchmark_type_inference` - provides the language definition as well as a type inference engine. - -### Layer 2: Sampling Mikhailsky terms - We sample Mikhailsky terms using a Markov chain where transitions correspond - to local rewriting rules. The state space of the Markov chain is defined - in `State_space` module. The rewriting infrastructure is provided in the - `Kernel` module by instantiating `lib_micheline_rewriting`. - Rewrites are checked to preserved well-typedness in the Mikhailsky sense - using the type inference engine provided with Mikhailsky. The `Rules` - module defines all rewriting rules, for both Mikhailsky _programs_ - (submodule `Rules.Instruction`) and _data_ - (submodule `Rules.Data_rewrite_leaves`). The function `Rules.rewriting` - performs the enumeration of possible rewritings. - - The Markov chain is biased to sample terms of a specified - size using the Metropolis-Hasting functors provided by `StaTz`. - The instantiation of this Markov chain is defined in the `Sampler` - module. - -### Layer 3: - Once we can sample Mikhaislky terms of a specified size, we need - to convert them to Michelson ones. This is performed in two steps. - - In the first step, we use the `Autocomplete` module to fill holes - in Mikhailsky terms (resp. data) with well-typed code (resp. data). - This is a relatively ad-hoc process. - - The last step is to convert Mikhaislky to Michelson using the - `Michelson` module. diff --git a/src/proto_012_Psithaca/lib_benchmark/autocomp.ml b/src/proto_012_Psithaca/lib_benchmark/autocomp.ml deleted file mode 100644 index 1a44dc9826f7..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/autocomp.ml +++ /dev/null @@ -1,382 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Autocompletion functions (removing holes from Mikhailsky terms). *) - -open Sampling_helpers - -(* ------------------------------------------------------------------------- *) -(* Helpers *) - -let rec stack_length (stack : Type.Stack.t) acc = - match stack.node with - | Empty_t -> acc - | Stack_var_t _ -> acc + 1 - | Item_t (_, tl) -> stack_length tl (acc + 1) - -(* We need to sort and remove duplicate elements - of sets and maps to make them Michelson-compatible. *) -let sort_set_elements elements = - List.sort_uniq - (Structural_compare.compare - ~prim_compare:Mikhailsky.Mikhailsky_signature.compare) - elements - -let sort_map_elements elements = - let open Micheline in - List.sort_uniq - (fun node1 node2 -> - match (node1, node2) with - | ( Prim (_, Mikhailsky_prim.D_Elt, [k1; _v1], _), - Prim (_, Mikhailsky_prim.D_Elt, [k2; _v2], _) ) -> - Structural_compare.compare - ~prim_compare:Mikhailsky.Mikhailsky_signature.compare - k1 - k2 - | _ -> Stdlib.failwith "Autocomp.sort_map_elements: invalid Michelson map") - elements - -(* ------------------------------------------------------------------------- *) -(* Error handling *) - -type error_case = - | Cannot_complete_data of Mikhailsky.node * Kernel.Path.t - | Cannot_complete_code of Mikhailsky.node * Kernel.Path.t - -exception Autocompletion_error of error_case - -let cannot_complete_data node path = - raise (Autocompletion_error (Cannot_complete_data (node, path))) - -let cannot_complete_code node path = - raise (Autocompletion_error (Cannot_complete_code (node, path))) - -(* ------------------------------------------------------------------------- *) -(* Code & data autocompletion *) - -(* By default, comparable values are unit. *) -let default_comparable_type = Type.unit - -let generate_comparable _sp = Mikhailsky.Data.unit - -(* Instantiates variables in a base type, remaining variables - are mapped to some consistent choice of ground type - (this is made complicated by comparability constraints) *) -let rec instantiate_and_set ty = - let open Inference.M in - Inference.instantiate_base ty >>= fun ty -> replace_vars ty - -and replace_vars (ty : Type.Base.t) = - let open Inference.M in - let node = ty.node in - match node with - | Type.Base.Unit_t | Type.Base.Int_t | Type.Base.Nat_t | Type.Base.Bool_t - | Type.Base.String_t | Type.Base.Bytes_t | Type.Base.Key_hash_t - | Type.Base.Timestamp_t | Type.Base.Mutez_t | Type.Base.Key_t -> - return ty - | Type.Base.Var_t v -> ( - get_repr_exn v >>= fun repr -> - match repr with - | Inference.Stack_type _ -> assert false - | Inference.Base_type {comparable = _; repr = Some _} -> assert false - | Inference.Base_type {comparable; repr = None} -> ( - match comparable with - | Inference.Comparable -> return default_comparable_type - | Inference.Unconstrained | Inference.Not_comparable -> - return Type.unit)) - | Type.Base.Option_t ty -> - replace_vars ty >>= fun ty -> return (Type.option ty) - | Type.Base.Pair_t (lt, rt) -> - replace_vars lt >>= fun lt -> - replace_vars rt >>= fun rt -> return (Type.pair lt rt) - | Type.Base.Union_t (lt, rt) -> - replace_vars lt >>= fun lt -> - replace_vars rt >>= fun rt -> return (Type.union lt rt) - | Type.Base.List_t ty -> replace_vars ty >>= fun ty -> return (Type.list ty) - | Type.Base.Set_t ty -> replace_vars ty >>= fun ty -> return (Type.set ty) - | Type.Base.Map_t (k, v) -> - replace_vars k >>= fun k -> - replace_vars v >>= fun v -> return (Type.map k v) - | Type.Base.Lambda_t (dom, range) -> - replace_vars dom >>= fun dom -> - replace_vars range >>= fun range -> return (Type.lambda dom range) - -let rec instantiate_and_set_stack (stack_ty : Type.Stack.t) = - let open Inference.M in - let node = stack_ty.node in - match node with - | Type.Stack.Empty_t -> return Type.empty - | Type.Stack.Stack_var_t _ -> return Type.empty - | Type.Stack.Item_t (hd, tl) -> - instantiate_and_set hd >>= fun hd -> - instantiate_and_set_stack tl >>= fun tl -> return (Type.item hd tl) - -(* In the following we perform computations in the composite monad - (sampler o Inference.M.t), it is convenient to define the bind and return - explicitly. *) -module SM = struct - type 'a t = 'a Inference.M.t sampler - - let ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t = - fun m f rng_state s -> - let (x, s) = m rng_state s in - f x rng_state s - [@@inline] - - let sample : 'a sampler -> 'a Inference.M.t sampler = - fun x rng_state st -> (x rng_state, st) - [@@inline] - - let deterministic : 'a Inference.M.t -> 'a t = fun x _rng_state -> x - - let return x _ s = (x, s) [@@inline] -end - -module Make - (Michelson_base : Michelson_samplers_base.S) - (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) = -struct - (* Generates minimally sized random data of specified type. - Used in autocompletion. *) - (* /!\ Always call [instantiate_and_set] on the type argument of - [generate_data]. /!\ *) - let rec generate_data : Type.Base.t -> Mikhailsky.node SM.t = - fun ty -> - let open SM in - let open Type.Base in - let desc = ty.node in - match desc with - | Var_t _v -> assert false - | Unit_t -> return Mikhailsky.Data.unit - | Int_t -> - sample @@ Michelson_base.int >>= fun i -> - let i = Protocol.Script_int_repr.to_zint i in - return (Mikhailsky.Data.big_integer i) - | Nat_t -> - sample @@ Michelson_base.nat >>= fun n -> - let n = Protocol.Script_int_repr.to_zint n in - return (Mikhailsky.Data.big_natural n) - | Bool_t -> - sample Base_samplers.uniform_bool >>= fun b -> - if b then return Mikhailsky.Data.true_ - else return Mikhailsky.Data.false_ - | String_t -> - sample Michelson_base.string >>= fun str -> - let str = Protocol.Script_string_repr.to_string str in - return (Mikhailsky.Data.string str) - | Bytes_t -> - sample Michelson_base.bytes >>= fun bytes -> - return (Mikhailsky.Data.bytes bytes) - | Key_hash_t -> - sample Crypto_samplers.pkh >>= fun pkh -> - return (Mikhailsky.Data.key_hash pkh) - | Timestamp_t -> - sample Michelson_base.timestamp >>= fun tstamp -> - return (Mikhailsky.Data.timestamp tstamp) - | Mutez_t -> - sample Michelson_base.tez >>= fun tz -> - return (Mikhailsky.Data.mutez tz) - | Key_t -> - sample Crypto_samplers.pk >>= fun pk -> return (Mikhailsky.Data.key pk) - | Option_t ty -> - sample Base_samplers.uniform_bool >>= fun b -> - if b then return Mikhailsky.Data.none - else generate_data ty >>= fun res -> return (Mikhailsky.Data.some res) - | Pair_t (lty, rty) -> - generate_data lty >>= fun lv -> - generate_data rty >>= fun rv -> return (Mikhailsky.Data.pair lv rv) - | Union_t (lty, rty) -> - sample Base_samplers.uniform_bool >>= fun b -> - if b then generate_data lty >>= fun v -> return (Mikhailsky.Data.left v) - else generate_data rty >>= fun v -> return (Mikhailsky.Data.right v) - | List_t _ty -> return (Mikhailsky.Data.list []) - | Set_t _ty -> return (Mikhailsky.Data.set []) - | Map_t (_kty, _vty) -> return (Mikhailsky.Data.map []) - | Lambda_t (dom, range) -> - invent_term Type.(item dom empty) Type.(item range empty) - >>= fun code -> return (Mikhailsky.Data.lambda code) - - and invent_term (bef : Type.Stack.t) (aft : Type.Stack.t) : - Mikhailsky.node list SM.t = - let open SM in - install_dummy_stack aft [] >>= fun code -> - let terms = drop_stack bef code in - return terms - - and drop_stack (stack : Type.Stack.t) code = - Mikhailsky.Instructions.dropn (stack_length stack 0) :: code - - and install_dummy_stack (stack : Type.Stack.t) (acc : Mikhailsky.node list) = - let open SM in - match stack.node with - | Empty_t -> return acc - | Stack_var_t _ -> - let acc = Mikhailsky.(Instructions.push unit_ty Data.unit) :: acc in - return acc - | Item_t (hd, tl) -> - deterministic @@ instantiate_and_set hd >>= fun hd -> - (match hd.node with - | Lambda_t (dom, range) -> - invent_term Type.(item dom empty) Type.(item range empty) - >>= fun code -> - let instr = Mikhailsky.(prim I_LAMBDA [seq code] []) in - return instr - | _ -> - generate_data hd >>= fun term -> - let ty = Mikhailsky.unparse_ty_exn hd in - return (Mikhailsky.Instructions.push ty term)) - >>= fun instr -> install_dummy_stack tl (instr :: acc) - - (* Autocomplete Mikhailsky data. - When encountering a hole, we lookup its type and instantiate - some random data of the specified type. *) - let rec complete_data : - Mikhailsky.node -> Kernel.Path.t -> Mikhailsky.node SM.t = - let open SM in - fun node path -> - match node with - | Micheline.Int (_, _) | Micheline.String (_, _) | Micheline.Bytes (_, _) - -> - return node - | Micheline.Prim (_, D_Hole, _, _) -> ( - deterministic @@ Inference.M.get_data_annot path >>= fun ty_opt -> - match ty_opt with - | None -> cannot_complete_data node path - | Some ty -> - deterministic @@ instantiate_and_set ty >>= fun ty -> - generate_data ty) - | Micheline.Prim (_, A_Set, [Micheline.Seq (_, elements)], _) -> - complete_data_list (Kernel.Path.at_index 0 path) 0 elements [] - >>= fun elements -> - let elements = sort_set_elements elements in - return (Mikhailsky.Data.set elements) - | Micheline.Prim (_, A_Map, [Micheline.Seq (_, elements)], _) -> - complete_data_list (Kernel.Path.at_index 0 path) 0 elements [] - >>= fun elements -> - let elements = sort_map_elements elements in - return (Mikhailsky.Data.map elements) - | Micheline.Prim (_, prim, subterms, _) -> - complete_data_list path 0 subterms [] >>= fun subterms -> - return (Mikhailsky.prim prim subterms []) - | Micheline.Seq (_, subterms) -> - complete_data_list path 0 subterms [] >>= fun subterms -> - return (Mikhailsky.seq subterms) - - and complete_data_list path i subterms acc = - let open SM in - match subterms with - | [] -> return (List.rev acc) - | subterm :: tl -> - let path' = Kernel.Path.at_index i path in - complete_data subterm path' >>= fun term -> - complete_data_list path (i + 1) tl (term :: acc) - - let complete_data typing node rng_state = - let (root_type_opt, _) = - Inference.M.get_data_annot Kernel.Path.root typing - in - match root_type_opt with - | None -> Stdlib.failwith "Autocomp.complete_data: cannot get type of expr" - | Some ty -> - let (_, typing) = Inference.instantiate_base ty typing in - let (result, _) = - try complete_data node Kernel.Path.root rng_state typing - with Autocompletion_error (Cannot_complete_data (subterm, path)) -> - Format.eprintf "Cannot complete data@." ; - Format.eprintf "at path %s@." (Kernel.Path.to_string path) ; - Format.eprintf "%a@." Mikhailsky.pp subterm ; - Stdlib.failwith "in autocomp.ml: unrecoverable failure" - in - let (typ, _typing) = - try Inference.infer_data_with_state result - with Inference.Ill_typed_script error -> - Format.eprintf "%a@." Inference.pp_inference_error error ; - Format.eprintf "%a@." Mikhailsky.pp result ; - assert false - in - (result, typ) - - (* Autocomplete Mikhailsky code. *) - - let rec complete_code : - Mikhailsky.node -> Kernel.Path.t -> Mikhailsky.node SM.t = - let open SM in - fun node path -> - match node with - | Micheline.Int (_, _) | Micheline.String (_, _) | Micheline.Bytes (_, _) - -> - return node - | Micheline.Prim (_, I_Hole, _, _) -> ( - deterministic @@ Inference.M.get_instr_annot path >>= function - | None -> cannot_complete_code node path - | Some {bef; aft} -> - deterministic @@ Inference.instantiate bef >>= fun bef -> - deterministic @@ Inference.instantiate aft >>= fun aft -> - invent_term bef aft >>= fun code -> return (Mikhailsky.seq code)) - | Micheline.Prim (_, prim, subterms, _) -> - complete_code_list path 0 subterms [] >>= fun subterms -> - return (Mikhailsky.prim prim subterms []) - | Micheline.Seq (_, subterms) -> - complete_code_list path 0 subterms [] >>= fun subterms -> - return (Mikhailsky.seq subterms) - - and complete_code_list path i subterms acc = - let open SM in - match subterms with - | [] -> return (List.rev acc) - | subterm :: tl -> - let path' = Kernel.Path.at_index i path in - complete_code subterm path' >>= fun term -> - complete_code_list path (i + 1) tl (term :: acc) - - let complete_code typing node rng_state = - let (root_type_opt, _) = - Inference.M.get_instr_annot Kernel.Path.root typing - in - match root_type_opt with - | None -> Stdlib.failwith "Autocomp.complete_code: cannot get type of expr" - | Some {bef; aft} -> - let (_, typing) = Inference.instantiate bef typing in - let (_, typing) = Inference.instantiate aft typing in - let (result, _) = - try complete_code node Kernel.Path.root rng_state typing with - | Autocompletion_error (Cannot_complete_code (subterm, path)) -> - Format.eprintf "Cannot complete code@." ; - Format.eprintf "at path %s@." (Kernel.Path.to_string path) ; - Format.eprintf "%a@." Mikhailsky.pp subterm ; - Stdlib.failwith "in autocomp.ml: unrecoverable failure" - | _ -> assert false - in - let ((bef, aft), typing) = - try Inference.infer_with_state result - with Inference.Ill_typed_script error -> - Format.eprintf "%a@." Inference.pp_inference_error error ; - Format.eprintf "%a@." Mikhailsky.pp result ; - assert false - in - let (bef, typing) = instantiate_and_set_stack bef typing in - let (aft, typing) = instantiate_and_set_stack aft typing in - (result, (bef, aft), typing) -end diff --git a/src/proto_012_Psithaca/lib_benchmark/dune b/src/proto_012_Psithaca/lib_benchmark/dune deleted file mode 100644 index b667f8872dfc..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/dune +++ /dev/null @@ -1,27 +0,0 @@ -(library - (name tezos_benchmark_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-benchmark-012-Psithaca) - (libraries - tezos-base - tezos-protocol-012-Psithaca - tezos-protocol-012-Psithaca-parameters - tezos-micheline-rewriting - tezos-benchmark - tezos-benchmark-type-inference-012-Psithaca - hashcons - benchmark-utils - tezos-012-Psithaca-test-helpers - prbnmcn-stats) - (library_flags (:standard -linkall)) - (private_modules kernel rules state_space) - (flags (:standard -open Tezos_stdlib - -open Tezos_base - -open Tezos_error_monad - -open Tezos_micheline - -open Tezos_micheline_rewriting - -open Tezos_benchmark - -open Tezos_benchmark_type_inference_012_Psithaca - -open Tezos_protocol_012_Psithaca - -open Tezos_crypto - -open Tezos_012_Psithaca_test_helpers))) diff --git a/src/proto_012_Psithaca/lib_benchmark/dune-project b/src/proto_012_Psithaca/lib_benchmark/dune-project deleted file mode 100644 index cb4adad038dd..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-benchmark-alpha) diff --git a/src/proto_012_Psithaca/lib_benchmark/execution_context.ml b/src/proto_012_Psithaca/lib_benchmark/execution_context.ml deleted file mode 100644 index 74a60d5bd405..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/execution_context.ml +++ /dev/null @@ -1,84 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Error_monad - -type context = Alpha_context.context * Script_interpreter.step_constants - -let context_init_memory ~rng_state = - Context.init - ~rng_state - ~initial_balances: - [ - 4_000_000_000_000L; - 4_000_000_000_000L; - 4_000_000_000_000L; - 4_000_000_000_000L; - 4_000_000_000_000L; - ] - 5 - >>=? fun (block, accounts) -> - match accounts with - | [bs1; bs2; bs3; bs4; bs5] -> - return (`Mem_block (block, (bs1, bs2, bs3, bs4, bs5))) - | _ -> assert false - -let context_init ~rng_state = context_init_memory ~rng_state - -let make ~rng_state = - context_init_memory ~rng_state >>=? fun context -> - let amount = Alpha_context.Tez.one in - let chain_id = Chain_id.zero in - let now = Alpha_context.Script_timestamp.of_zint Z.zero in - let level = Alpha_context.Script_int.zero_n in - let open Script_interpreter in - (match context with - | `Mem_block (block, (bs1, bs2, bs3, _, _)) -> - let source = bs1 in - let payer = bs2 in - let self = bs3 in - let step_constants = - {source; payer; self; amount; chain_id; now; level} - in - return (block, step_constants) - | `Disk_block (block, source) -> - let step_constants = - {source; payer = source; self = source; amount; chain_id; now; level} - in - return (block, step_constants)) - >>=? fun (block, step_constants) -> - Incremental.begin_construction - ~timestamp:(Time.Protocol.add block.header.shell.timestamp 30L) - block - >>=? fun vs -> - let ctxt = Incremental.alpha_ctxt vs in - let ctxt = - (* Required for eg Create_contract *) - Protocol.Alpha_context.Contract.init_origination_nonce - ctxt - Operation_hash.zero - in - return (ctxt, step_constants) diff --git a/src/proto_012_Psithaca/lib_benchmark/kernel.ml b/src/proto_012_Psithaca/lib_benchmark/kernel.ml deleted file mode 100644 index 0932302aa20b..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/kernel.ml +++ /dev/null @@ -1,39 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* ------------------------------------------------------------------------- *) -(* Instantiate rewriting subsystem *) - -module Lang = - Micheline_with_hash_consing.Make - (Mikhailsky.Mikhailsky_signature) - (struct - let initial_size = None - end) - -module Path = Mikhailsky.Path -module Patt = Pattern.Make (Mikhailsky.Mikhailsky_signature) (Lang) (Path) -module Rewriter = - Rewrite.Make (Mikhailsky.Mikhailsky_signature) (Lang) (Path) (Patt) diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/.ocamlformat b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/dune b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/dune deleted file mode 100644 index e35b280f4d82..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/dune +++ /dev/null @@ -1,17 +0,0 @@ -(library - (name tezos_benchmark_type_inference_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-benchmark-type-inference-012-Psithaca) - (libraries - tezos-stdlib - tezos-error-monad - tezos-crypto - tezos-micheline - tezos-protocol-012-Psithaca - tezos-micheline-rewriting - hashcons) - (flags (:standard -open Tezos_stdlib - -open Tezos_error_monad - -open Tezos_micheline - -open Tezos_micheline_rewriting - -open Tezos_protocol_012_Psithaca))) diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/dune-project b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/dune-project deleted file mode 100644 index c0b5d472accd..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(name tezos-benchmark-type-inference-alpha) -(formatting (enabled_for ocaml)) diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/inference.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/inference.ml deleted file mode 100644 index 72dc6c1ef4be..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/inference.ml +++ /dev/null @@ -1,1150 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Micheline -module UF = Uf.UF - -(* The domain of comparability: - * - * Comparable Not_comparable - * ^ ^ - * \ / - * \ / - * Unconstrained - * - * The higher we go, the more information we have. - * This domain admits all glbs but not all lubs. - *) - -type comparability = Comparable | Not_comparable | Unconstrained - -let pp_comparability fmtr (cmp : comparability) = - match cmp with - | Comparable -> Format.fprintf fmtr "Comparable" - | Not_comparable -> Format.fprintf fmtr "Not_comparable" - | Unconstrained -> Format.fprintf fmtr "Unconstrained" - -let sup_comparability (c1 : comparability) (c2 : comparability) = - match (c1, c2) with - | (Unconstrained, c) | (c, Unconstrained) -> Some c - | (Comparable, Comparable) -> Some Comparable - | (Not_comparable, Not_comparable) -> Some Not_comparable - | (Comparable, Not_comparable) | (Not_comparable, Comparable) -> None - -type michelson_type = - | Base_type of {repr : Type.Base.t option; comparable : comparability} - | Stack_type of Type.Stack.t option - -type transformer = {bef : Type.Stack.t; aft : Type.Stack.t} - -let michelson_type_to_string (x : michelson_type) = - match x with - | Base_type {repr = None; comparable} -> - Format.asprintf "?::[%a]" pp_comparability comparable - | Base_type {repr = Some ty; comparable} -> - Format.asprintf "%a::[%a]" Type.Base.pp ty pp_comparability comparable - | Stack_type None -> "" - | Stack_type (Some sty) -> Format.asprintf "%a" Type.Stack.pp sty - -(* ------------------------------------------------------------------------- *) -(* Typechecking errors *) - -type inference_error = - (* | Expected_data_with_ground_type of Mikhailsky.Path.t * Mikhailsky.node *) - | Unhandled_micheline of Mikhailsky.Path.t * Mikhailsky.node - | Expected_micheline_prim - | Unsatisfiable_comparability_constraint of comparability_error_witness - | Base_types_incompatible of Type.Base.t * Type.Base.t - | Stack_types_incompatible of Type.Stack.t * Type.Stack.t - | Badly_typed_arithmetic of Mikhailsky_prim.prim * Type.Base.t * Type.Base.t - | Ill_formed_arithmetic of Mikhailsky.Path.t * Mikhailsky.node - | Cyclic_stack_type - | Cyclic_base_type - | Invalid_ast of string option * Mikhailsky.Path.t * Mikhailsky.node - -and comparability_error_witness = - | Comparability_error_types of michelson_type * michelson_type - | Comparability_error_tags of Type.Base.t * comparability * comparability - -let pp_inference_error fmtr (err : inference_error) = - match err with - (* | Expected_data_with_ground_type (path, node) -> - * let path = Mikhailsky.Path.to_string path in - * let node = Mikhailsky.to_string node in - * Format.fprintf fmtr "Expected data with ground type: %s at path %s" node path *) - | Unhandled_micheline (path, node) -> - let path = Mikhailsky.Path.to_string path in - let node = Mikhailsky.to_string node in - Format.fprintf fmtr "Unhandled micheline: %s at path %s" node path - | Expected_micheline_prim -> - Format.fprintf fmtr "%s" "Expected_micheline_prim" - | Unsatisfiable_comparability_constraint - (Comparability_error_types (ty1, ty2)) -> - let ty1 = michelson_type_to_string ty1 in - let ty2 = michelson_type_to_string ty2 in - Format.fprintf - fmtr - "Unsatisfiable comparability constraint: %s # %s" - ty1 - ty2 - | Unsatisfiable_comparability_constraint - (Comparability_error_tags (ty, cmp1, cmp2)) -> - Format.fprintf - fmtr - "Unsatisfiable comparability constraint: %a :: %a # %a" - Type.Base.pp - ty - pp_comparability - cmp1 - pp_comparability - cmp2 - | Base_types_incompatible (ty1, ty2) -> - Format.fprintf - fmtr - "Base types incompatible: %a %a" - Type.Base.pp - ty1 - Type.Base.pp - ty2 - | Stack_types_incompatible (sty1, sty2) -> - Format.fprintf - fmtr - "Stack types incompatible: %a %a" - Type.Stack.pp - sty1 - Type.Stack.pp - sty2 - | Badly_typed_arithmetic (prim, ty1, ty2) -> - Format.fprintf - fmtr - "Badly typed arithmetic: %a(%a, %a)" - Mikhailsky_prim.pp - prim - Type.Base.pp - ty1 - Type.Base.pp - ty2 - | Ill_formed_arithmetic (path, node) -> - let path = Mikhailsky.Path.to_string path in - let node = Mikhailsky.to_string node in - Format.fprintf fmtr "Ill formed arithmetic: %s at path %s" node path - | Cyclic_stack_type -> Format.fprintf fmtr "Cyclic stack type" - | Cyclic_base_type -> Format.fprintf fmtr "Cyclic base type" - | Invalid_ast (msg_opt, path, node) -> ( - let path = Mikhailsky.Path.to_string path in - let node = Mikhailsky.to_string node in - match msg_opt with - | None -> Format.fprintf fmtr "Invalid ast: %s at path %s" node path - | Some msg -> - Format.fprintf fmtr "Invalid ast: %s at path %s (%s)" node path msg) - -exception Ill_typed_script of inference_error - -let unsatisfiable_comparability ty cmp1 cmp2 = - raise - (Ill_typed_script - (Unsatisfiable_comparability_constraint - (Comparability_error_tags (ty, cmp1, cmp2)))) - -let invalid_ast ?msg path node = - raise (Ill_typed_script (Invalid_ast (msg, path, node))) - -let () = - Printexc.register_printer (fun exn -> - match exn with - | Ill_typed_script error -> - Some (Format.asprintf "%a" pp_inference_error error) - | _ -> None) - -(* ------------------------------------------------------------------------- *) - -module Repr_store = - Stores.Map - (Int_map) - (struct - type key = int - - type value = michelson_type - - let key_to_string = string_of_int - - let value_to_string = michelson_type_to_string - end) - -module Repr_sm = Monads.Make_state_monad (Repr_store) -module Path_map = Map.Make (Mikhailsky.Path) - -module Annot_instr_store = - Stores.Map - (Path_map) - (struct - type key = Mikhailsky.Path.t - - type value = transformer - - let key_to_string = Mikhailsky.Path.to_string - - let value_to_string {bef; aft} = - Format.asprintf "%a => %a" Type.Stack.pp bef Type.Stack.pp aft - end) - -module Annot_instr_sm = Monads.Make_state_monad (Annot_instr_store) - -module Annot_data_store = - Stores.Map - (Path_map) - (struct - type key = Mikhailsky.Path.t - - type value = Type.Base.t - - let key_to_string = Mikhailsky.Path.to_string - - let value_to_string ty = Format.asprintf "%a" Type.Base.pp ty - end) - -module Annot_data_sm = Monads.Make_state_monad (Annot_data_store) - -type state = { - uf : UF.M.state; - repr : Repr_sm.state; - annot_instr : Annot_instr_sm.state; - annot_data : Annot_data_sm.state; -} - -module M = struct - type 'a t = state -> 'a * state - - let empty : unit -> state = - fun () -> - { - uf = UF.M.empty (); - repr = Repr_sm.empty (); - annot_instr = Annot_instr_sm.empty (); - annot_data = Annot_data_sm.empty (); - } - - let ( >>= ) m f s = - let (x, s) = m s in - f x s - [@@inline] - - let return x s = (x, s) - - (* let run m = fst (m (empty ())) *) - - let uf_lift : 'a UF.M.t -> 'a t = - fun computation state -> - let (res, uf) = computation state.uf in - (res, {state with uf}) - [@@inline] - - let repr_lift : 'a Repr_sm.t -> 'a t = - fun computation state -> - let (res, repr) = computation state.repr in - (res, {state with repr}) - [@@inline] - - let annot_instr_lift : 'a Annot_instr_sm.t -> 'a t = - fun computation state -> - let (res, annot_instr) = computation state.annot_instr in - (res, {state with annot_instr}) - [@@inline] - - let annot_data_lift : 'a Annot_data_sm.t -> 'a t = - fun computation state -> - let (res, annot_data) = computation state.annot_data in - (res, {state with annot_data}) - [@@inline] - - let set_repr k v = repr_lift (Repr_sm.set k v) [@@inline] - - let get_repr_exn k = - repr_lift (Repr_sm.get k) >>= function - | None -> Stdlib.failwith "get_repr_exn" - | Some res -> return res - [@@inline] - - let set_instr_annot k v = annot_instr_lift (Annot_instr_sm.set k v) [@@inline] - - let get_instr_annot k = annot_instr_lift (Annot_instr_sm.get k) [@@inline] - - let set_data_annot k v = annot_data_lift (Annot_data_sm.set k v) [@@inline] - - let get_data_annot k = annot_data_lift (Annot_data_sm.get k) [@@inline] - - let get_state state = (state, state) -end - -module S = Set.Make (Int) - -let rec instantiate (encountered : S.t) (stack_ty : Type.Stack.t) : - Type.Stack.t M.t = - let open Type.Stack in - let open M in - if S.mem stack_ty.tag encountered then - raise (Ill_typed_script Cyclic_stack_type) - else - let encountered = S.add stack_ty.tag encountered in - match stack_ty.node with - | Empty_t -> return stack_ty - | Stack_var_t x -> ( - uf_lift (UF.find x) >>= fun root -> - get_repr_exn root >>= function - | Stack_type None -> return (Type.stack_var root) - | Stack_type (Some ty) -> instantiate encountered ty - | _ -> assert false) - | Item_t (head, tail) -> - instantiate_base S.empty head >>= fun head -> - instantiate encountered tail >>= fun tail -> - return (Type.item head tail) - -and instantiate_base (encountered : S.t) (ty : Type.Base.t) : Type.Base.t M.t = - let open Type.Base in - let open M in - if S.mem ty.tag encountered then raise (Ill_typed_script Cyclic_base_type) - else - let encountered = S.add ty.tag encountered in - match ty.node with - | Unit_t | Int_t | Nat_t | Bool_t | String_t | Bytes_t | Key_hash_t | Key_t - | Timestamp_t | Mutez_t -> - return ty - | Option_t ty -> - instantiate_base encountered ty >>= fun ty -> return (Type.option ty) - | List_t ty -> - instantiate_base encountered ty >>= fun ty -> return (Type.list ty) - | Set_t ty -> - instantiate_base encountered ty >>= fun ty -> return (Type.set ty) - | Map_t (kty, vty) -> - instantiate_base encountered kty >>= fun kty -> - instantiate_base encountered vty >>= fun vty -> - return (Type.map kty vty) - | Pair_t (lty, rty) -> - instantiate_base encountered lty >>= fun lty -> - instantiate_base encountered rty >>= fun rty -> - return (Type.pair lty rty) - | Union_t (lty, rty) -> - instantiate_base encountered lty >>= fun lty -> - instantiate_base encountered rty >>= fun rty -> - return (Type.union lty rty) - | Lambda_t (dom, range) -> - instantiate_base encountered dom >>= fun dom -> - instantiate_base encountered range >>= fun range -> - return (Type.lambda dom range) - | Var_t x -> ( - uf_lift (UF.find x) >>= fun root -> - get_repr_exn root >>= function - | Base_type {repr = None; _} -> return (Type.var root) - | Base_type {repr = Some ty; _} -> instantiate_base encountered ty - | _ -> assert false) - -let instantiate_base base_ty = instantiate_base S.empty base_ty - -let instantiate stack_ty = instantiate S.empty stack_ty - -let rec unify (x : Type.Stack.t) (y : Type.Stack.t) : unit M.t = - let open Type.Stack in - let open M in - let unify_single_stack v x = - (match Type.Stack.vars x with - | None -> return () - | Some v' -> - if v = v' then raise (Ill_typed_script Cyclic_stack_type) else return ()) - >>= fun () -> - M.uf_lift (UF.find v) >>= fun root -> - get_repr_exn root >>= fun repr -> - merge_reprs (Stack_type (Some x)) repr >>= fun repr -> set_repr root repr - in - if x.tag = y.tag then return () - else - match (x.node, y.node) with - | (Empty_t, Empty_t) -> return () - | (Stack_var_t x, Stack_var_t y) -> - M.uf_lift (UF.find x) >>= fun root_x -> - M.uf_lift (UF.find y) >>= fun root_y -> - get_repr_exn root_x >>= fun repr_x -> - get_repr_exn root_y >>= fun repr_y -> - M.uf_lift (UF.union x y) >>= fun root -> - merge_reprs repr_x repr_y >>= fun repr -> set_repr root repr - | (Stack_var_t v, _) -> unify_single_stack v y - | (_, Stack_var_t v) -> unify_single_stack v x - | (Item_t (ty1, tail1), Item_t (ty2, tail2)) -> - unify_base ty1 ty2 >>= fun () -> - unify tail1 tail2 >>= fun () -> return () - | _ -> raise (Ill_typed_script (Stack_types_incompatible (x, y))) - -and unify_base (x : Type.Base.t) (y : Type.Base.t) : unit M.t = - let open Type.Base in - let open M in - let unify_single_var v x = - (if List.mem v (Type.Base.vars x) then - raise (Ill_typed_script Cyclic_base_type) - else return ()) - >>= fun () -> - M.uf_lift (UF.find v) >>= fun root -> - get_repr_exn root >>= fun repr -> - get_comparability x >>= fun comparable -> - merge_reprs (Base_type {repr = Some x; comparable}) repr >>= fun repr -> - set_repr root repr - in - if x.tag = y.tag then return () - else - match (x.node, y.node) with - | (Unit_t, Unit_t) - | (Int_t, Int_t) - | (Nat_t, Nat_t) - | (Bool_t, Bool_t) - | (String_t, String_t) - | (Bytes_t, Bytes_t) - | (Key_hash_t, Key_hash_t) - | (Timestamp_t, Timestamp_t) - | (Mutez_t, Mutez_t) - | (Key_t, Key_t) -> - return () - | (Option_t x, Option_t y) -> unify_base x y - | (List_t x, List_t y) -> unify_base x y - | (Set_t x, Set_t y) -> unify_base x y - | (Map_t (kx, vx), Map_t (ky, vy)) -> - unify_base kx ky >>= fun () -> unify_base vx vy - | (Pair_t (x, x'), Pair_t (y, y')) -> - unify_base x y >>= fun () -> unify_base x' y' - | (Union_t (x, x'), Union_t (y, y')) -> - unify_base x y >>= fun () -> unify_base x' y' - | (Lambda_t (x, x'), Lambda_t (y, y')) -> - unify_base x y >>= fun () -> unify_base x' y' - | (Var_t x, Var_t y) -> - M.uf_lift (UF.find x) >>= fun root_x -> - M.uf_lift (UF.find y) >>= fun root_y -> - get_repr_exn root_x >>= fun repr_x -> - get_repr_exn root_y >>= fun repr_y -> - M.uf_lift (UF.union x y) >>= fun root -> - merge_reprs repr_x repr_y >>= fun repr -> set_repr root repr - | (Var_t v, _) -> unify_single_var v y - | (_, Var_t v) -> unify_single_var v x - | _ -> - instantiate_base x >>= fun x -> - instantiate_base y >>= fun y -> - raise (Ill_typed_script (Base_types_incompatible (x, y))) - -and merge_reprs (repr1 : michelson_type) (repr2 : michelson_type) : - michelson_type M.t = - let open M in - match (repr1, repr2) with - | ((Stack_type None as repr), Stack_type None) - | ((Stack_type (Some _) as repr), Stack_type None) - | (Stack_type None, (Stack_type (Some _) as repr)) -> - return repr - | ((Stack_type (Some sty1) as repr), Stack_type (Some sty2)) -> - unify sty1 sty2 >>= fun () -> return repr - | ( Base_type {repr = opt1; comparable = cmp1}, - Base_type {repr = opt2; comparable = cmp2} ) -> ( - let comparable_opt = sup_comparability cmp1 cmp2 in - match comparable_opt with - | None -> - raise - (Ill_typed_script - (Unsatisfiable_comparability_constraint - (Comparability_error_types (repr1, repr2)))) - | Some comparable -> ( - match (opt1, opt2) with - | (None, None) -> return (Base_type {repr = None; comparable}) - | ((Some ty as repr), None) -> - assert_comparability comparable ty >>= fun () -> - return (Base_type {repr; comparable}) - | (None, (Some ty as repr)) -> - assert_comparability comparable ty >>= fun () -> - return (Base_type {repr; comparable}) - | (Some ty1, Some ty2) -> - unify_base ty1 ty2 >>= fun () -> - assert_comparability comparable ty1 >>= fun () -> - assert_comparability comparable ty2 >>= fun () -> - return (Base_type {repr = opt1; comparable}))) - | _ -> assert false - -and assert_comparability comparable ty = - assert_comparability_aux comparable ty [] - -and assert_comparability_aux lower_bound (ty : Type.Base.t) - (encountered : int list) : unit M.t = - let open M in - if List.mem ty.tag encountered then raise (Ill_typed_script Cyclic_base_type) - else - let encountered = ty.tag :: encountered in - match ty.node with - | Var_t v -> ( - uf_lift (UF.find v) >>= fun root -> - get_repr_exn root >>= fun repr -> - match repr with - | Base_type {repr = None; comparable} -> ( - match sup_comparability comparable lower_bound with - | None -> unsatisfiable_comparability ty comparable lower_bound - | Some comparable -> - set_repr root (Base_type {repr = None; comparable})) - | Base_type {repr = Some ty; comparable} -> ( - match sup_comparability comparable lower_bound with - | None -> unsatisfiable_comparability ty comparable lower_bound - | Some comparable -> - assert_comparability_aux lower_bound ty encountered - >>= fun () -> - set_repr root (Base_type {repr = Some ty; comparable})) - | Stack_type _ -> assert false) - | List_t _ | Set_t _ | Map_t _ | Lambda_t _ | Key_t -> ( - match lower_bound with - | Unconstrained | Not_comparable -> return () - | Comparable -> unsatisfiable_comparability ty Unconstrained lower_bound - ) - | Unit_t | Int_t | Nat_t | Bool_t | String_t | Bytes_t | Key_hash_t - | Timestamp_t | Mutez_t -> - (* if not (le_comparability lower_bound Comparable) then - * unsatisfiable_comparability ty Comparable lower_bound - * else *) - return () - | Option_t ty -> ( - match lower_bound with - | Comparable -> assert_comparability_aux Comparable ty encountered - | Not_comparable | Unconstrained -> return ()) - | Pair_t (l, r) -> ( - match lower_bound with - | Comparable -> - assert_comparability_aux Comparable l encountered >>= fun () -> - assert_comparability_aux Comparable r encountered - | Unconstrained | Not_comparable -> return ()) - | Union_t (l, r) -> ( - match lower_bound with - | Comparable -> - assert_comparability_aux Comparable l encountered >>= fun () -> - assert_comparability_aux Comparable r encountered - | Unconstrained | Not_comparable -> return ()) - -and get_comparability (ty : Type.Base.t) : comparability M.t = - let open M in - match ty.node with - | Var_t v -> ( - get_repr_exn v >>= fun repr -> - match repr with - | Stack_type _ -> assert false - | Base_type {comparable; _} -> return comparable) - | Unit_t | Int_t | Nat_t | Bool_t | String_t | Bytes_t | Key_hash_t - | Timestamp_t | Mutez_t -> - return Comparable - | List_t _ | Set_t _ | Map_t _ | Lambda_t _ | Key_t -> return Not_comparable - | Option_t ty -> get_comparability ty - | Union_t (lt, rt) | Pair_t (lt, rt) -> ( - get_comparability lt >>= fun lc -> - get_comparability rt >>= fun rc -> - match (lc, rc) with - | (Comparable, Comparable) -> return Comparable - | _ -> return Unconstrained) - -let fresh = - let x = ref ~-1 in - fun () -> - incr x ; - !x - -let exists_stack : unit -> Type.Stack.t M.t = - let open M in - fun () -> - let fresh = fresh () in - uf_lift (UF.add fresh) >>= fun () -> - set_repr fresh (Stack_type None) >>= fun () -> return (Type.stack_var fresh) - -let exists : unit -> Type.Base.t M.t = - let open M in - fun () -> - let fresh = fresh () in - uf_lift (UF.add fresh) >>= fun () -> - set_repr fresh (Base_type {repr = None; comparable = Unconstrained}) - >>= fun () -> return (Type.var fresh) - -let exists_cmp : unit -> Type.Base.t M.t = - let open M in - fun () -> - let fresh = fresh () in - uf_lift (UF.add fresh) >>= fun () -> - set_repr fresh (Base_type {repr = None; comparable = Comparable}) - >>= fun () -> return (Type.var fresh) - -(* Adapted from [script_ir_translator] *) -let parse_uint30 n : int = - let max_uint30 = 0x3fffffff in - match n with - | Micheline.Int (_, n') - when Compare.Z.(Z.zero <= n') && Compare.Z.(n' <= Z.of_int max_uint30) -> - Z.to_int n' - | _ -> assert false - -(* encodes the per-instruction relationship between input and output types - of binary arithmetic operations. *) -let arith_type (instr : Mikhailsky_prim.prim) (ty1 : Type.Base.t) - (ty2 : Type.Base.t) : Type.Base.t option = - match (instr, ty1.node, ty2.node) with - | ((I_ADD | I_MUL), Int_t, Int_t) - | ((I_ADD | I_MUL), Int_t, Nat_t) - | ((I_ADD | I_MUL), Nat_t, Int_t) -> - Some Type.int - | ((I_ADD | I_MUL), Nat_t, Nat_t) -> Some Type.nat - | (I_SUB, Int_t, Int_t) - | (I_SUB, Int_t, Nat_t) - | (I_SUB, Nat_t, Int_t) - | (I_SUB, Nat_t, Nat_t) - | (I_SUB, Timestamp_t, Timestamp_t) -> - Some Type.int - | (I_EDIV, Int_t, Int_t) - | (I_EDIV, Int_t, Nat_t) - | (I_EDIV, Nat_t, Int_t) - | (I_EDIV, Nat_t, Nat_t) -> - Some Type.(option (pair nat nat)) - (* Timestamp *) - | (I_ADD, Timestamp_t, Int_t) - | (I_ADD, Int_t, Timestamp_t) - | (I_SUB, Timestamp_t, Int_t) -> - Some Type.timestamp - (* Mutez *) - | (I_ADD, Mutez_t, Mutez_t) - | (I_SUB, Mutez_t, Mutez_t) - | (I_MUL, Mutez_t, Nat_t) - | (I_MUL, Nat_t, Mutez_t) -> - Some Type.mutez - | (I_EDIV, Mutez_t, Nat_t) -> Some Type.(option (pair mutez mutez)) - | (I_EDIV, Mutez_t, Mutez_t) -> Some Type.(option (pair nat mutez)) - | _ -> None - -let rec generate_constraints (path : Mikhailsky.Path.t) (node : Mikhailsky.node) - (bef : Type.Stack.t) (aft : Type.Stack.t) : unit M.t = - let open M in - set_instr_annot path {bef; aft} >>= fun () -> - match node with - | Int (_, _) -> - assert false (* Ints should always be guarded by annotations *) - | String (_, _) | Bytes (_, _) -> - raise (Ill_typed_script Expected_micheline_prim) - (* Hole *) - | Prim (_, I_Hole, [], _) -> return () - (* Stack ops - simple cases *) - | Prim (_loc, I_DROP, [], _annot) -> - exists () >>= fun top -> unify bef (Type.item top aft) - | Prim (_loc, I_DROP, [n], _annot) -> - let n = parse_uint30 n in - generate_constraints_dropn n bef aft - | Prim (_loc, I_DUP, [], _annot) -> - exists () >>= fun top -> - exists_stack () >>= fun rest -> - unify bef Type.(item top rest) >>= fun () -> - unify aft Type.(item top (item top rest)) - | Prim (_loc, I_SWAP, [], _annot) -> - exists () >>= fun a -> - exists () >>= fun b -> - exists_stack () >>= fun rest -> - unify bef Type.(item a (item b rest)) >>= fun () -> - unify aft Type.(item b (item a rest)) - | Prim (_loc, I_PUSH, [t; d], _annot) -> - let ty = - Mikhailsky.parse_ty - ~allow_big_map:false - ~allow_operation:false - ~allow_contract:false - t - in - generate_constraints_data (Mikhailsky.Path.at_index 1 path) d ty - >>= fun () -> - (* assert_data_has_ground_type (Mikhailsky.Path.at_index 1 path) d ty >>= fun () -> *) - unify aft Type.(item ty bef) - | Prim (_loc, I_UNIT, [], _annot) -> unify aft Type.(item unit bef) - | Prim (_loc, I_DIP, [code], _annot) -> - exists () >>= fun top -> - exists_stack () >>= fun bef_rest -> - exists_stack () >>= fun aft_rest -> - unify bef Type.(item top bef_rest) >>= fun () -> - unify aft Type.(item top aft_rest) >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 0 path) - code - bef_rest - aft_rest - (* TODO: DIGn, etc *) - (* Option-related instructions *) - | Prim (_, I_SOME, [], _) -> - exists () >>= fun top -> - exists_stack () >>= fun rest -> - unify bef Type.(item top rest) >>= fun () -> - unify aft Type.(item (option top) rest) - | Prim (_, I_NONE, [t], _) -> - let ty = - Mikhailsky.parse_ty - ~allow_big_map:true - ~allow_operation:true - ~allow_contract:true - t - in - unify aft Type.(item (option ty) bef) - | Prim (_, I_IF_NONE, [bt; bf], _) -> - exists () >>= fun a -> - exists_stack () >>= fun rest -> - unify bef Type.(item (option a) rest) >>= fun () -> - generate_constraints (Mikhailsky.Path.at_index 0 path) bt rest aft - >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 1 path) - bf - Type.(item a rest) - aft - (* bool-based control flow *) - | Prim (_, I_IF, [bt; bf], _) -> - exists_stack () >>= fun rest -> - unify bef Type.(item bool rest) >>= fun () -> - generate_constraints (Mikhailsky.Path.at_index 0 path) bt rest aft - >>= fun () -> - generate_constraints (Mikhailsky.Path.at_index 1 path) bf rest aft - | Prim (_, I_LOOP, [body], _) -> - unify bef Type.(item bool aft) >>= fun () -> - generate_constraints (Mikhailsky.Path.at_index 0 path) body aft bef - (* Boolean binops *) - | Prim (_, I_AND, [], _) | Prim (_, I_OR, [], _) | Prim (_, I_XOR, [], _) -> - exists_stack () >>= fun rest -> - unify bef Type.(item bool (item bool rest)) >>= fun () -> - unify aft Type.(item bool rest) - (* Arithmetic *) - | Prim (_, ((I_ADD | I_SUB | I_MUL | I_EDIV) as instr), [ty1; ty2], _) -> ( - let ty1 = - Mikhailsky.parse_ty - ~allow_big_map:false - ~allow_operation:false - ~allow_contract:false - ty1 - in - let ty2 = - Mikhailsky.parse_ty - ~allow_big_map:false - ~allow_operation:false - ~allow_contract:false - ty2 - in - match arith_type instr ty1 ty2 with - | None -> - raise (Ill_typed_script (Badly_typed_arithmetic (instr, ty1, ty2))) - | Some ret -> - exists_stack () >>= fun rest -> - unify bef Type.(item ty1 (item ty2 rest)) >>= fun () -> - unify aft Type.(item ret rest)) - | Prim (_, (I_ADD | I_SUB | I_MUL | I_EDIV), _, _) -> - raise (Ill_typed_script (Ill_formed_arithmetic (path, node))) - | Prim (_, I_COMPARE, [], _) -> - exists_cmp () >>= fun a -> - exists_stack () >>= fun rest -> - unify bef Type.(item a (item a rest)) >>= fun () -> - unify aft Type.(item int rest) - | Prim (_, I_ABS, [], _) -> - exists_stack () >>= fun rest -> - unify bef Type.(item int rest) >>= fun () -> - unify aft Type.(item nat rest) - | Prim (_, I_GT, [], _) -> - exists_stack () >>= fun rest -> - unify bef Type.(item int rest) >>= fun () -> - unify aft Type.(item bool rest) - (* Strings/bytes *) - | Prim (_, I_CONCAT, [], _) -> - exists_stack () >>= fun rest -> - unify bef Type.(item string (item string rest)) >>= fun () -> - unify aft Type.(item string rest) - | Prim (_, I_SIZE_STRING, [], _) -> - exists_stack () >>= fun rest -> - unify bef Type.(item string rest) >>= fun () -> - unify aft Type.(item nat rest) - | Prim (_, I_SIZE_BYTES, [], _) -> - exists_stack () >>= fun rest -> - unify bef Type.(item bytes rest) >>= fun () -> - unify aft Type.(item nat rest) - (* Crypto *) - | Prim (_, I_SHA256, [], _) - | Prim (_, I_SHA512, [], _) - | Prim (_, I_BLAKE2B, [], _) -> - exists_stack () >>= fun rest -> - unify bef Type.(item bytes rest) >>= fun () -> - unify aft Type.(item bytes rest) - | Prim (_, I_HASH_KEY, [], _) -> - exists_stack () >>= fun rest -> - unify bef Type.(item key rest) >>= fun () -> - unify aft Type.(item key_hash rest) - (* sets *) - | Prim (_, I_EMPTY_SET, [], _) -> - exists_cmp () >>= fun cmpty -> unify aft Type.(item (set cmpty) bef) - | Prim (_, I_UPDATE_SET, [], _) -> - exists_cmp () >>= fun cty -> - exists_stack () >>= fun rest -> - unify bef Type.(item cty (item bool (item (set cty) rest))) >>= fun () -> - unify aft Type.(item (set cty) rest) - | Prim (_, I_SIZE_SET, [], _) -> - exists_cmp () >>= fun cmpty -> - exists_stack () >>= fun rest -> - unify bef Type.(item (set cmpty) rest) >>= fun () -> - unify aft Type.(item nat rest) - | Prim (_, I_ITER_SET, [code], _) -> - exists_cmp () >>= fun cmpty -> - unify bef Type.(item (set cmpty) aft) >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 0 path) - code - Type.(item cmpty aft) - aft - | Prim (_, I_MEM_SET, [], _) -> - exists_cmp () >>= fun cmpty -> - exists_stack () >>= fun rest -> - unify bef Type.(item cmpty (item (set cmpty) rest)) >>= fun () -> - unify aft Type.(item bool rest) - (* maps *) - | Prim (_, I_EMPTY_MAP, [], _) -> - exists_cmp () >>= fun kty -> - exists () >>= fun vty -> unify aft Type.(item (map kty vty) bef) - | Prim (_, I_UPDATE_MAP, [], _) -> - exists_cmp () >>= fun kty -> - exists () >>= fun vty -> - exists_stack () >>= fun rest -> - unify bef Type.(item kty (item (option vty) (item (map kty vty) rest))) - >>= fun () -> unify aft Type.(item (map kty vty) rest) - | Prim (_, I_SIZE_MAP, [], _) -> - exists_cmp () >>= fun kty -> - exists () >>= fun vty -> - exists_stack () >>= fun rest -> - unify bef Type.(item (map kty vty) rest) >>= fun () -> - unify aft Type.(item nat rest) - | Prim (_, I_ITER_MAP, [code], _) -> - exists_cmp () >>= fun kty -> - exists () >>= fun vty -> - unify bef Type.(item (map kty vty) aft) >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 0 path) - code - Type.(item (pair kty vty) aft) - aft - | Prim (_, I_MAP_MAP, [code], _) -> - exists_cmp () >>= fun kty -> - exists () >>= fun vty1 -> - exists () >>= fun vty2 -> - exists_stack () >>= fun rest -> - unify bef Type.(item (map kty vty1) rest) >>= fun () -> - unify aft Type.(item (map kty vty2) rest) >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 0 path) - code - Type.(item (pair kty vty1) rest) - Type.(item vty2 rest) - | Prim (_, I_MEM_MAP, [], _) -> - exists_cmp () >>= fun kty -> - exists () >>= fun vty -> - exists_stack () >>= fun rest -> - unify bef Type.(item kty (item (map kty vty) rest)) >>= fun () -> - unify aft Type.(item bool rest) - | Prim (_, I_GET_MAP, [], _) -> - exists_cmp () >>= fun kty -> - exists () >>= fun vty -> - exists_stack () >>= fun rest -> - unify bef Type.(item kty (item (map kty vty) rest)) >>= fun () -> - unify aft Type.(item (option vty) rest) - (* Pairs *) - | Prim (_, I_PAIR, [], _) -> - exists () >>= fun a -> - exists () >>= fun b -> - exists_stack () >>= fun rest -> - unify bef Type.(item a (item b rest)) >>= fun () -> - unify aft Type.(item (pair a b) rest) - | Prim (_, I_CAR, [], _) -> - exists () >>= fun a -> - exists () >>= fun b -> - exists_stack () >>= fun rest -> - unify bef Type.(item (pair a b) rest) >>= fun () -> - unify aft Type.(item a rest) - | Prim (_, I_CDR, [], _) -> - exists () >>= fun a -> - exists () >>= fun b -> - exists_stack () >>= fun rest -> - unify bef Type.(item (pair a b) rest) >>= fun () -> - unify aft Type.(item b rest) - (* Unions *) - | Prim (_, I_LEFT, [], _) -> - exists () >>= fun lt -> - exists () >>= fun rt -> - exists_stack () >>= fun rest -> - unify bef (Type.item lt rest) >>= fun () -> - unify aft Type.(item (union lt rt) rest) >>= fun res -> return res - | Prim (_, I_RIGHT, [], _) -> - exists () >>= fun lt -> - exists () >>= fun rt -> - exists_stack () >>= fun rest -> - unify bef Type.(item rt rest) >>= fun () -> - unify aft Type.(item (union lt rt) rest) - | Prim (_, (I_LEFT | I_RIGHT), _ :: _, _) -> - invalid_ast ~msg:__LOC__ path node - | Prim (_, I_LOOP_LEFT, [body], _) -> - exists () >>= fun l -> - exists () >>= fun r -> - exists_stack () >>= fun rest -> - unify bef Type.(item (union l r) rest) >>= fun () -> - unify aft Type.(item r rest) >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 0 path) - body - Type.(item l rest) - bef - | Prim (_, I_IF_LEFT, [bt; bf], _) -> - exists () >>= fun a -> - exists () >>= fun b -> - exists_stack () >>= fun rest -> - unify bef Type.(item (union a b) rest) >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 0 path) - bt - (Type.item a rest) - aft - >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 1 path) - bf - (Type.item b rest) - aft - (* lambdas *) - | Prim (_, I_LAMBDA, [code], _) -> - exists () >>= fun dom -> - exists () >>= fun range -> - unify aft Type.(item (lambda dom range) bef) >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 0 path) - code - Type.(item dom empty) - Type.(item range empty) - | Prim (_, I_LAMBDA, _, _) -> invalid_ast ~msg:__LOC__ path node - | Prim (_, I_APPLY, [], _) -> - exists () >>= fun a -> - exists () >>= fun b -> - exists () >>= fun ret -> - exists_stack () >>= fun rest -> - unify bef Type.(item a (item (lambda (pair a b) ret) rest)) >>= fun () -> - unify aft Type.(item (lambda b ret) rest) - | Prim (_, I_EXEC, [], _) -> - exists () >>= fun a -> - exists () >>= fun ret -> - exists_stack () >>= fun rest -> - unify bef Type.(item a (item (lambda a ret) rest)) >>= fun () -> - unify aft Type.(item ret rest) - (* lists *) - | Prim (_, I_NIL, [], _) -> - exists () >>= fun a -> unify aft Type.(item (list a) bef) - | Prim (_, I_CONS, [], _) -> - exists () >>= fun a -> - exists_stack () >>= fun rest -> - unify bef Type.(item a (item (list a) rest)) >>= fun () -> - unify aft Type.(item (list a) rest) - | Prim (_, I_SIZE_LIST, [], _) -> - exists () >>= fun ty -> - exists_stack () >>= fun rest -> - unify bef Type.(item (list ty) rest) >>= fun () -> - unify aft Type.(item nat rest) - | Prim (_, I_ITER_LIST, [code], _) -> - exists () >>= fun ty -> - unify bef Type.(item (list ty) aft) >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 0 path) - code - Type.(item ty aft) - aft - | Prim (_, I_MAP_LIST, [code], _) -> - exists () >>= fun ty1 -> - exists () >>= fun ty2 -> - exists_stack () >>= fun rest -> - unify bef Type.(item (list ty1) rest) >>= fun () -> - unify aft Type.(item (list ty2) rest) >>= fun () -> - generate_constraints - (Mikhailsky.Path.at_index 0 path) - code - Type.(item ty1 rest) - Type.(item ty2 rest) - (* pack/unpack*) - | Prim (_, I_PACK, [], _) -> - exists () >>= fun ty -> - exists_stack () >>= fun rest -> - unify bef Type.(item ty rest) >>= fun () -> - unify aft Type.(item bytes rest) - | Prim (_, I_UNPACK, [], _) -> - exists () >>= fun ty -> - exists_stack () >>= fun rest -> - unify bef Type.(item bytes rest) >>= fun () -> - unify aft Type.(item (option ty) rest) - (* Others *) - | Seq (_, []) -> unify bef aft - | Seq (_, [single]) -> - generate_constraints (Mikhailsky.Path.at_index 0 path) single bef aft - | Seq (_, instrs) -> generate_constraints_seq path 0 instrs bef aft - | _ -> raise (Ill_typed_script (Unhandled_micheline (path, node))) - -and generate_constraints_seq path index instrs bef aft = - let open M in - match instrs with - | [] -> assert false - | [single] -> - generate_constraints (Mikhailsky.Path.at_index index path) single bef aft - | hd :: tl -> - exists_stack () >>= fun stack_ty -> - generate_constraints (Mikhailsky.Path.at_index index path) hd bef stack_ty - >>= fun () -> generate_constraints_seq path (index + 1) tl stack_ty aft - -and generate_constraints_data (path : Mikhailsky.Path.t) - (node : Mikhailsky.node) (ty : Type.Base.t) : unit M.t = - let open M in - set_data_annot path ty >>= fun () -> - match node with - | Prim (_, D_Hole, [], _) -> return () - | Prim (_, D_Unit, [], _) -> unify_base ty Type.unit - | Prim (_, D_True, [], _) | Prim (_, D_False, [], _) -> - unify_base ty Type.bool - | String _ -> unify_base ty Type.string - | Bytes _ -> unify_base ty Type.bytes - | Prim (_, D_Pair, [vl; vr], _) -> - exists () >>= fun lty -> - exists () >>= fun rty -> - generate_constraints_data (Mikhailsky.Path.at_index 0 path) vl lty - >>= fun () -> - generate_constraints_data (Mikhailsky.Path.at_index 1 path) vr rty - >>= fun () -> unify_base ty (Type.pair lty rty) - | Prim (_, D_Left, [term], _) -> - exists () >>= fun lty -> - exists () >>= fun rty -> - generate_constraints_data (Mikhailsky.Path.at_index 0 path) term lty - >>= fun () -> unify_base ty (Type.union lty rty) - | Prim (_, D_Right, [term], _) -> - exists () >>= fun lty -> - exists () >>= fun rty -> - generate_constraints_data (Mikhailsky.Path.at_index 0 path) term rty - >>= fun () -> unify_base ty (Type.union lty rty) - | Prim (_, D_None, [], _) -> - exists () >>= fun elt_ty -> unify_base ty (Type.option elt_ty) - | Prim (_, D_Some, [v], _) -> - exists () >>= fun elt_ty -> - generate_constraints_data (Mikhailsky.Path.at_index 0 path) v elt_ty - >>= fun () -> unify_base ty (Type.option elt_ty) - | Prim (_, A_Int, [Int (_, _)], _) -> unify_base ty Type.int - | Prim (_, A_Nat, [Int (_, _)], _) -> unify_base ty Type.nat - | Prim (_, A_Timestamp, [Int (_, _)], _) -> unify_base ty Type.timestamp - | Prim (_, A_Mutez, [Int (_, _)], _) -> unify_base ty Type.mutez - | Prim (_, A_Key_hash, [Bytes (_, _)], _) -> unify_base ty Type.key_hash - | Prim (_, A_Key, [Bytes (_, _)], _) -> unify_base ty Type.key - | Prim (_, A_List, [Seq (_, subterms)], _) -> - exists () >>= fun elt_ty -> - unify_base ty Type.(list elt_ty) >>= fun () -> - (* path' accounts for the fact that the Seq is hidden under an annot. *) - let path' = Mikhailsky.Path.at_index 0 path in - generate_constraints_data_list path' 0 subterms elt_ty - | Prim (_, A_Set, [Seq (_, subterms)], _) -> - exists_cmp () >>= fun elt_ty -> - unify_base ty Type.(set elt_ty) >>= fun () -> - (* path' accounts for the fact that the Seq is hidden under an annot. *) - let path' = Mikhailsky.Path.at_index 0 path in - generate_constraints_data_set path' 0 subterms elt_ty - | Prim (_, A_Map, [Seq (_, subterms)], _) -> - exists_cmp () >>= fun k_ty -> - exists () >>= fun v_ty -> - unify_base ty Type.(map k_ty v_ty) >>= fun () -> - (* path' accounts for the fact that the Seq is hidden under an annot. *) - let path' = Mikhailsky.Path.at_index 0 path in - generate_constraints_data_map path' 0 subterms k_ty v_ty - | Prim (_, A_Lambda, [(Seq (_, _) as node)], _) -> - exists () >>= fun dom -> - exists () >>= fun range -> - unify_base ty Type.(lambda dom range) >>= fun () -> - let path' = Mikhailsky.Path.at_index 0 path in - let bef = Type.(item dom empty) in - let aft = Type.(item range empty) in - generate_constraints path' node bef aft - | Prim (_, (A_Int | A_Nat | A_List), _, _) -> - invalid_ast ~msg:__LOC__ path node - | Int _ - (* Ints should always be guarded by annotations *) - | Seq (_, _) - (* Lists, sets, maps, lambdas, should always be guarded by annotations *) - | _ -> - invalid_ast ~msg:__LOC__ path node - -(* raise (Ill_typed_script (Invalid_ast (path, node))) *) -and generate_constraints_data_list path index data ty = - let open M in - match data with - | [] -> return () - | hd :: tl -> - let hd_path = Mikhailsky.Path.at_index index path in - generate_constraints_data hd_path hd ty >>= fun () -> - generate_constraints_data_list path (index + 1) tl ty - -and generate_constraints_data_set path index data ty = - let open M in - match data with - | [] -> return () - | hd :: tl -> - let hd_path = Mikhailsky.Path.at_index index path in - generate_constraints_data hd_path hd ty >>= fun () -> - generate_constraints_data_list path (index + 1) tl ty - -and generate_constraints_data_map path index data k_ty v_ty = - let open M in - match data with - | [] -> return () - | elt :: tl -> ( - let elt_path = Mikhailsky.Path.at_index index path in - match elt with - | Prim (_, D_Elt, [k; v], _) -> - let k_path = Mikhailsky.Path.at_index 0 elt_path in - generate_constraints_data k_path k k_ty >>= fun () -> - let v_path = Mikhailsky.Path.at_index 1 elt_path in - generate_constraints_data v_path v v_ty >>= fun () -> - generate_constraints_data_map path (index + 1) tl k_ty v_ty - | _ -> invalid_ast ~msg:__LOC__ elt_path elt) - -and generate_constraints_dropn n bef aft = - let open M in - if n = 0 then unify bef aft - else - exists () >>= fun top -> - generate_constraints_dropn (n - 1) bef (Type.item top aft) - -let infer_with_state (node : Mikhailsky.node) : - (Type.Stack.t * Type.Stack.t) * state = - let open M in - ( exists_stack () >>= fun bef -> - exists_stack () >>= fun aft -> - generate_constraints Mikhailsky.Path.root node bef aft >>= fun () -> - instantiate bef >>= fun bef -> - instantiate aft >>= fun aft -> return (bef, aft) ) - (M.empty ()) - -let infer (node : Mikhailsky.node) : Type.Stack.t * Type.Stack.t = - fst (infer_with_state node) - -let infer_data_with_state (node : Mikhailsky.node) : Type.Base.t * state = - let open M in - ( exists () >>= fun ty -> - generate_constraints_data Mikhailsky.Path.root node ty >>= fun () -> - instantiate_base ty >>= fun ty -> return ty ) - (M.empty ()) - -let infer_data (node : Mikhailsky.node) : Type.Base.t = - fst (infer_data_with_state node) diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/inference.mli b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/inference.mli deleted file mode 100644 index e44d83fab069..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/inference.mli +++ /dev/null @@ -1,145 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Errors and their pretty-printing function *) -type inference_error - -exception Ill_typed_script of inference_error - -val pp_inference_error : Format.formatter -> inference_error -> unit - -(** Comparability tag. *) -type comparability = Comparable | Not_comparable | Unconstrained - -(** Michelson types. *) -type michelson_type = - | Base_type of {repr : Type.Base.t option; comparable : comparability} - | Stack_type of Type.Stack.t option - -type transformer = {bef : Type.Stack.t; aft : Type.Stack.t} - -(** State of the type inference module *) - -(** Store implementation for type representatives *) -module Repr_store : Stores.S with type key = int and type value = michelson_type - -(** State monad built on [Repr_store] *) -module Repr_sm : - Monads.State_sig - with type state = Repr_store.state - and type key = int - and type value = michelson_type - -(** Store implementation for instruction type representatives *) -module Annot_instr_store : - Stores.S with type key = Mikhailsky.Path.t and type value = transformer - -(** State monad handling annotations on instructions *) -module Annot_instr_sm : - Monads.State_sig - with type state = Annot_instr_store.state - and type value = transformer - and type key = Mikhailsky.Path.t - -(** Store implementation for data type representatives *) -module Annot_data_store : - Stores.S with type key = Mikhailsky.Path.t and type value = Type.Base.t - -(** State monad handling annotations on data *) -module Annot_data_sm : - Monads.State_sig - with type state = Annot_data_store.state - and type value = Type.Base.t - and type key = Mikhailsky.Path.t - -(** State of the inference module *) -type state = { - uf : Uf.UF.M.state; - repr : Repr_sm.state; - annot_instr : Annot_instr_sm.state; - annot_data : Annot_data_sm.state; -} - -(** State monad of the inference module. *) -module M : sig - type 'a t = state -> 'a * state - - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - - val empty : unit -> state - - val return : 'a -> 'a t - - val set_repr : int -> michelson_type -> unit t - - val get_repr_exn : int -> michelson_type t - - val get_instr_annot : Annot_data_sm.key -> transformer option t - - val get_data_annot : Annot_data_sm.key -> Type.Base.t option t - - val uf_lift : 'a Uf.UF.M.t -> 'a t - - val repr_lift : 'a Repr_sm.t -> 'a t - - val annot_instr_lift : 'a Annot_instr_sm.t -> 'a t - - val annot_data_lift : 'a Annot_data_sm.t -> 'a t - - val get_state : state t -end - -(** Unifies two stack types. *) -val unify : Type.Stack.t -> Type.Stack.t -> unit M.t - -(** Unifies two base types. *) -val unify_base : Type.Base.t -> Type.Base.t -> unit M.t - -(** Instantiate type variables with the associated terms in a base type. *) -val instantiate_base : Type.Base.t -> Type.Base.t M.t - -(** Instantiate type variables with the associated terms in a stack type. *) -val instantiate : Type.Stack.t -> Type.Stack.t M.t - -(** Get comparability flag for a base type. *) -val get_comparability : Type.Base.t -> comparability M.t - -(** Performs inference on the given Mikhailsky term and returns - its type (as a pair of [before] and [after] stack) as well as the - inference engine state. *) -val infer_with_state : Mikhailsky.node -> (Type.Stack.t * Type.Stack.t) * state - -(** Performs inference on the given Mikhailsky term and throws - the inference engine state away. *) -val infer : Mikhailsky.node -> Type.Stack.t * Type.Stack.t - -(** Performs inference on a piece of Mikhailsky [data] and - returns the inference engine state along the inferred type. *) -val infer_data_with_state : Mikhailsky.node -> Type.Base.t * state - -(** Performs inference on a piece of Mikhailsky [data] and - returns the inferred type, throwing the inference engine - state away. *) -val infer_data : Mikhailsky.node -> Type.Base.t diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/int_map.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/int_map.ml deleted file mode 100644 index e9b05fe91caa..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/int_map.ml +++ /dev/null @@ -1,26 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -include Map.Make (Compare.Int) diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky.ml deleted file mode 100644 index a015381180a0..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky.ml +++ /dev/null @@ -1,422 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -exception Term_contains_holes - -module Mikhailsky_signature : Signature.S with type t = Mikhailsky_prim.prim = -struct - type t = Mikhailsky_prim.prim - - let compare (x : t) (y : t) = Stdlib.compare x y - - let hash (x : t) = Hashtbl.hash x - - let pp = Mikhailsky_prim.pp -end - -include - Micheline_with_hash_consing.Make - (Mikhailsky_signature) - (struct - let initial_size = None - end) - -module Path = Path.With_hash_consing (struct - let initial_size = None -end) - -(* Prints a Mikhailsky term. *) -let pp fmt node = - let canonical = Micheline.strip_locations node in - let printable = - Micheline_printer.printable Mikhailsky_prim.string_of_prim canonical - in - Micheline_printer.print_expr fmt printable - -let to_string node = - pp Format.str_formatter node ; - Format.flush_str_formatter () - -(* Adapted from Script_ir_translator.parse_ty *) -let rec parse_ty : - allow_big_map:bool -> - allow_operation:bool -> - allow_contract:bool -> - node -> - Type.Base.t = - fun ~allow_big_map ~allow_operation ~allow_contract node -> - match node with - | Prim (_loc, T_unit, [], _annot) -> Type.unit - | Prim (_loc, T_int, [], _annot) -> Type.int - | Prim (_loc, T_nat, [], _annot) -> Type.nat - | Prim (_loc, T_string, [], _annot) -> Type.string - | Prim (_loc, T_bytes, [], _annot) -> Type.bytes - | Prim (_loc, T_bool, [], _annot) -> Type.bool - | Prim (_loc, T_key_hash, [], _annot) -> Type.key_hash - | Prim (_loc, T_timestamp, [], _annot) -> Type.timestamp - | Prim (_loc, T_mutez, [], _annot) -> Type.mutez - | Prim (_loc, T_option, [ut], _annot) -> - let ty = parse_ty ~allow_big_map ~allow_operation ~allow_contract ut in - Type.option ty - | Prim (_loc, T_pair, [utl; utr], _annot) -> - let lty = parse_ty ~allow_big_map ~allow_operation ~allow_contract utl in - let rty = parse_ty ~allow_big_map ~allow_operation ~allow_contract utr in - Type.pair lty rty - | Prim (_loc, T_or, [utl; utr], _annot) -> - let lty = parse_ty ~allow_big_map ~allow_operation ~allow_contract utl in - let rty = parse_ty ~allow_big_map ~allow_operation ~allow_contract utr in - Type.union lty rty - | Prim (_loc, T_set, [ut], _annot) -> - let ut = parse_ty ~allow_big_map ~allow_operation ~allow_contract ut in - Type.set ut - | Prim (_loc, T_map, [uta; utb], _annot) -> - let uta = parse_ty ~allow_big_map ~allow_operation ~allow_contract uta in - let utb = parse_ty ~allow_big_map ~allow_operation ~allow_contract utb in - Type.map uta utb - | Prim (_loc, T_lambda, [dom; range], _annot) -> - let dom = parse_ty ~allow_big_map ~allow_operation ~allow_contract dom in - let range = - parse_ty ~allow_big_map ~allow_operation ~allow_contract range - in - Type.lambda dom range - | Prim (_loc, T_list, [elt], _annot) -> - let elt = parse_ty ~allow_big_map ~allow_operation ~allow_contract elt in - Type.list elt - | _ -> - let s = to_string node in - Stdlib.failwith ("Mikhailsky.parse_ty: could not parse " ^ s) - -exception Term_has_variables - -exception Ill_formed_mikhailsky - -let rec map_var f (x : Type.Base.t) = - match x.node with - | Unit_t -> prim T_unit [] [] - | Var_t v -> f v - | Int_t -> prim T_int [] [] - | Nat_t -> prim T_nat [] [] - | Bool_t -> prim T_bool [] [] - | String_t -> prim T_string [] [] - | Bytes_t -> prim T_bytes [] [] - | Key_hash_t -> prim T_key_hash [] [] - | Timestamp_t -> prim T_timestamp [] [] - | Mutez_t -> prim T_mutez [] [] - | Key_t -> prim T_key [] [] - | Option_t ty -> - let mty = map_var f ty in - prim T_option [mty] [] - | Pair_t (lty, rty) -> - let lty = map_var f lty in - let rty = map_var f rty in - prim T_pair [lty; rty] [] - | Union_t (lty, rty) -> - let lty = map_var f lty in - let rty = map_var f rty in - prim T_or [lty; rty] [] - | List_t ty -> - let mty = map_var f ty in - prim T_list [mty] [] - | Set_t ty -> - let mty = map_var f ty in - prim T_set [mty] [] - | Map_t (kty, vty) -> - let mkty = map_var f kty in - let mvty = map_var f vty in - prim T_map [mkty; mvty] [] - | Lambda_t (dom, range) -> - let dom = map_var f dom in - let range = map_var f range in - prim T_lambda [dom; range] [] - -let unparse_ty_exn (x : Type.Base.t) = - map_var (fun _ -> raise Term_has_variables) x - -let unparse_ty (x : Type.Base.t) = - try Some (unparse_ty_exn x) with Term_has_variables -> None - -(* Exports a Mikhailsky term to Michelson. Fails if term contains holes. - Erases annotations, introduces types where missing. *) -let rec to_michelson (n : node) = - match n with - | Micheline.Int (_, i) -> Micheline.Int (0, i) - | Micheline.Prim (_, head, [term], _) - when Mikhailsky_prim.kind head = Annot_kind && head <> A_Lambda -> - to_michelson term - | Micheline.Prim (_, I_Hole, _, _) -> raise Term_contains_holes - | Micheline.Prim (_, D_Hole, _, _) -> raise Term_contains_holes - | Micheline.Prim (_, head, subterms, annots) -> - let head = Mikhailsky_prim.to_michelson head in - Micheline.Prim (0, head, List.map to_michelson subterms, annots) - | Micheline.String (_, s) -> Micheline.String (0, s) - | Micheline.Bytes (_, b) -> Micheline.Bytes (0, b) - | Micheline.Seq (_, subterms) -> - Micheline.Seq (0, List.map to_michelson subterms) - -let to_michelson (n : node) : Script_repr.expr = - Micheline.strip_locations (to_michelson n) - -let rec size : node -> int = - fun node -> - match node with - | Micheline.Int (_, _) -> 1 - | Micheline.String (_, _) -> 1 - | Micheline.Bytes (_, _) -> 1 - | Micheline.Prim (_, _, subterms, _) -> - List.fold_left (fun acc n -> acc + size n) 1 subterms - | Micheline.Seq (_, subterms) -> - List.fold_left (fun acc n -> acc + size n) 1 subterms - -let instr_hole = prim I_Hole [] [] - -let data_hole = prim D_Hole [] [] - -(* types *) -let unit_ty = prim T_unit [] [] - -let bool_ty = prim T_bool [] [] - -let int_ty = prim T_int [] [] - -let nat_ty = prim T_nat [] [] - -let string_ty = prim T_string [] [] - -let bytes_ty = prim T_bytes [] [] - -let key_hash_ty = prim T_key_hash [] [] - -let option_ty x = prim T_option [x] [] - -let list_ty x = prim T_list [x] [] - -(* Unique identifier provided by hash-consing Micheline terms. *) -let tag node = - let l = label node in - l.tag - -(* hash of term *) -let hash node = - let l = label node in - l.hash - -module Instructions = struct - (* arithmetic *) - - let add ty1 ty2 = prim I_ADD [ty1; ty2] [] - - let sub ty1 ty2 = prim I_SUB [ty1; ty2] [] - - let mul ty1 ty2 = prim I_MUL [ty1; ty2] [] - - let ediv ty1 ty2 = prim I_EDIV [ty1; ty2] [] - - let abs = prim I_ABS [] [] - - let gt = prim I_GT [] [] - - (* stack ops *) - let push ty v = prim I_PUSH [ty; v] [] - - let dip code = prim I_DIP [seq [code]] [] - - let dup = prim I_DUP [] [] - - let drop = prim I_DROP [] [] - - let dropn n = prim I_DROP [int (Z.of_int n)] [] - - let swap = prim I_SWAP [] [] - - (* crypto *) - let blake2b = prim I_BLAKE2B [] [] - - let sha256 = prim I_SHA256 [] [] - - let sha512 = prim I_SHA512 [] [] - - let hash_key = prim I_HASH_KEY [] [] - - (* control *) - let if_ bt bf = prim I_IF [seq [bt]; seq [bf]] [] - - let if_left bt bf = prim I_IF_LEFT [seq [bt]; seq [bf]] [] - - let if_none bt bf = prim I_IF_NONE [seq [bt]; seq [bf]] [] - - let loop b = prim I_LOOP [seq [b]] [] - - let loop_left b = prim I_LOOP_LEFT [seq [b]] [] - - (* pairs *) - let car = prim I_CAR [] [] - - let cdr = prim I_CDR [] [] - - let pair = prim I_PAIR [] [] - - (* unions *) - - let left = prim I_LEFT [] [] - - let right = prim I_RIGHT [] [] - - (* boolean *) - let and_ = prim I_AND [] [] - - (* compare *) - let compare = prim I_COMPARE [] [] - - (* map/set *) - let empty_set = prim I_EMPTY_SET [] [] - - let update_set = prim I_UPDATE_SET [] [] - - let size_set = prim I_SIZE_SET [] [] - - let iter_set code = prim I_ITER_SET [seq code] [] - - let mem_set = prim I_MEM_SET [] [] - - let empty_map = prim I_EMPTY_MAP [] [] - - let update_map = prim I_UPDATE_MAP [] [] - - let size_map = prim I_SIZE_MAP [] [] - - let iter_map code = prim I_ITER_MAP [seq code] [] - - let map_map code = prim I_MAP_MAP [seq code] [] - - let get_map = prim I_GET_MAP [] [] - - let mem_map = prim I_MEM_MAP [] [] - - (* lists*) - let nil = prim I_NIL [] [] - - let cons = prim I_CONS [] [] - - let size_list = prim I_SIZE_LIST [] [] - - let iter_list code = prim I_ITER_LIST [seq code] [] - - let map_list code = prim I_MAP_LIST [seq code] [] - - (* strings *) - let concat = prim I_CONCAT [] [] - - let size_string = prim I_SIZE_STRING [] [] - - let size_bytes = prim I_SIZE_BYTES [] [] - - (* Lambdas *) - let lambda code = prim I_LAMBDA [seq code] [] - - let exec = prim I_EXEC [] [] - - let apply = prim I_APPLY [] [] - - (* pack/unpack *) - let pack = prim I_PACK [] [] - - let unpack = prim I_UNPACK [] [] - - (* hole *) - let hole = instr_hole -end - -(* value constructors *) -module Data = struct - let unit = prim D_Unit [] [] - - let false_ = prim D_False [] [] - - let true_ = prim D_True [] [] - - let none = prim D_None [] [] - - let some x = prim D_Some [x] [] - - let pair x y = prim D_Pair [x; y] [] - - let left x = prim D_Left [x] [] - - let right x = prim D_Right [x] [] - - let list elts = prim A_List [seq elts] [] - - let set elts = prim A_Set [seq elts] [] - - let map_elt k v = prim D_Elt [k; v] [] - - let map elts = prim A_Map [seq elts] [] - - let timestamp ts = - let z = Protocol.Alpha_context.Script_timestamp.to_zint ts in - prim A_Timestamp [int z] [] - - let mutez (tz : Protocol.Alpha_context.Tez.tez) = - let i = Protocol.Alpha_context.Tez.to_mutez tz in - prim A_Mutez [int (Z.of_int64 i)] [] - - let key_hash kh = - let b = - Data_encoding.Binary.to_bytes_exn - Tezos_crypto.Signature.Public_key_hash.encoding - kh - in - prim A_Key_hash [bytes b] [] - - let key k = - let b = - Data_encoding.Binary.to_bytes_exn - Tezos_crypto.Signature.Public_key.encoding - k - in - prim A_Key [bytes b] [] - - let integer (i : int) = prim A_Int [int (Z.of_int i)] [] - - let natural (i : int) = - assert (i >= 0) ; - prim A_Nat [int (Z.of_int i)] [] - - let big_integer (i : Z.t) = prim A_Int [int i] [] - - let big_natural (i : Z.t) = - assert (Z.geq i Z.zero) ; - prim A_Nat [int i] [] - - let string = string - - let bytes = bytes - - let lambda code = prim A_Lambda [seq code] [] - - let hole = data_hole -end diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky.mli b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky.mli deleted file mode 100644 index 6285f6a39555..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky.mli +++ /dev/null @@ -1,330 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** Mikhailsky: Michelson in Micheline form, with typed holes and annotations. - Mikhailsky terms are hash-consed. *) - -(** - Michelson code is a hard to type-check and generate incrementally due to - the presence of ambiguous constructs, such as literals - like [{ 1 ; 2 ; 3 }]. Is it a list of ints? of nats? of tez? Or a set? - - Thus, we will work with Mikhailsky, a better behaved version of Michelson - allowing local reconstruction of types. - - Differences wrt Michelson: - - 1. non string/byte literals are explicitly annotated with their head type constructor. - Here is an int i: Prim (_, D_int, [Int i], _) - Here is an nat n: Prim (_, D_nat, [Int i], _) - Here is an list of something: Prim (_, D_list, michelson_list, _) - Here is a set: Prim (_, D_set, michelson_set, _) - Here is a map: Prim (_, D_map, michelson_map, _) - etc. - Projecting back from this language to Michelson is trivial. - - 2. Instructions `LEFT/RIGHT` do not need to carry the type of the other - component of the disjunction. These has to be filled in back when - generating Michelson from Mikhailsky. - - 4. The same holds for the input/output type of a lambda as specified in the - `LAMBDA` instruction. - - 3. Some instructions are annotated with the type on which they operate. - Eg if Prim (_, I_ADD, [], []) is the (ad-hoc polymorphic) addition in Michelson, - we will have the following variants in Mikhailsky: - - Prim (_, I_ADD, [ Prim (_, T_mutez, [], []), - Prim (_, T_mutez, [], []) ], []) for mutez addition - - Prim (_, I_ADD, [ Prim (_, T_int, [], []), - Prim (_, T_nat, [], []) ], []) for int+nat addition - etc. -*) - -(** The signature of Mikhailsky terms. *) -module Mikhailsky_signature : Signature.S with type t = Mikhailsky_prim.prim - -(** Elements of type [Path.t] allow to index subterms of Mikhailsky terms. *) -module Path : Path.S - -(** The following types correspond to those provided when instantiating the - functor [Micheline_with_hash_consing.Make] on [Mikhailsky_signature]. *) -type label = Micheline_with_hash_consing.hcons_info - -type head = Mikhailsky_signature.t - -type node = (label, head) Micheline.node - -exception Term_contains_holes - -exception Ill_formed_mikhailsky - -(** [parse_ty] returns a type from a Mikhailsky term. *) -val parse_ty : - allow_big_map:bool -> - allow_operation:bool -> - allow_contract:bool -> - node -> - Type.Base.t - -(** [map_var f x] maps the function f on all variables contained - in the type [x]. *) -val map_var : (int -> node) -> Type.Base.t -> node - -(** [unparse_ty] returns a Mikhailsky term representing a type. *) -val unparse_ty_exn : Type.Base.t -> node - -val unparse_ty : Type.Base.t -> node option - -(** Extracts a Michelson term from a Mikhailsky one. Raises - [Term_contains_holes] if it cannot be done. *) -val to_michelson : node -> Script_repr.expr - -(** Pretty printer. *) -val pp : Format.formatter -> node -> unit - -val to_string : node -> string - -(** Returns the number of nodes of a Mikhailsky term. *) -val size : node -> int - -(** Micheline generic constructors *) -val prim : Mikhailsky_prim.prim -> node list -> string list -> node - -val seq : node list -> node - -val string : string -> node - -val bytes : Bytes.t -> node - -(** Mikhailsky smart constructors*) - -(** Holes *) -val instr_hole : node - -val data_hole : node - -(** Types *) -val unit_ty : node - -val int_ty : node - -val nat_ty : node - -val bool_ty : node - -val string_ty : node - -val bytes_ty : node - -val key_hash_ty : node - -val option_ty : node -> node - -val list_ty : node -> node - -(** Project unique tag out of Mikhailsky node *) -val tag : node -> int - -(** Project hash out of Mikhailsky node *) -val hash : node -> int - -(** Instructions *) -module Instructions : sig - (** Arithmetic. Binary operations take the input types as extra arguments. *) - val add : node -> node -> node - - val sub : node -> node -> node - - val mul : node -> node -> node - - val ediv : node -> node -> node - - val abs : node - - val gt : node - - (** Stack *) - val push : node -> node -> node - - val dip : node -> node - - val dup : node - - val drop : node - - val dropn : int -> node - - val swap : node - - (** Crypto *) - val blake2b : node - - val sha256 : node - - val sha512 : node - - val hash_key : node - - (** Control *) - val if_ : node -> node -> node - - val if_left : node -> node -> node - - val if_none : node -> node -> node - - val loop : node -> node - - val loop_left : node -> node - - (** Pairs *) - val car : node - - val cdr : node - - val pair : node - - (** Unions *) - val left : node - - val right : node - - (** Booleans *) - val and_ : node - - (** Compare *) - val compare : node - - (** Set/Map *) - val empty_set : node - - val update_set : node - - val size_set : node - - val iter_set : node list -> node - - val mem_set : node - - val empty_map : node - - val update_map : node - - val size_map : node - - val iter_map : node list -> node - - val map_map : node list -> node - - val get_map : node - - val mem_map : node - - (** Lists *) - val nil : node - - val cons : node - - val size_list : node - - val iter_list : node list -> node - - val map_list : node list -> node - - (** Strings/bytes *) - val concat : node - - val size_string : node - - val size_bytes : node - - (** Lambdas *) - val lambda : node list -> node - - val exec : node - - val apply : node - - (** pack/unpack *) - - val pack : node - - val unpack : node - - (** Hole *) - val hole : node -end - -(** data *) -module Data : sig - val unit : node - - val false_ : node - - val true_ : node - - val none : node - - val some : node -> node - - val pair : node -> node -> node - - val left : node -> node - - val right : node -> node - - val list : node list -> node - - val set : node list -> node - - val map_elt : node -> node -> node - - val map : node list -> node - - val timestamp : Alpha_context.Script_timestamp.t -> node - - val mutez : Alpha_context.Tez.t -> node - - val key_hash : Tezos_crypto.Signature.Public_key_hash.t -> node - - val key : Tezos_crypto.Signature.Public_key.t -> node - - val integer : int -> node - - val natural : int -> node - - val big_integer : Z.t -> node - - val big_natural : Z.t -> node - - val string : string -> node - - val bytes : Bytes.t -> node - - val lambda : node list -> node - - val hole : node -end diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky_prim.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky_prim.ml deleted file mode 100644 index b1b2fb140616..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/mikhailsky_prim.ml +++ /dev/null @@ -1,570 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** Mikhailsky primitives correspond to Michelson primitives plus special - "holes" for instructions and data. *) - -type prim = - | K_parameter - | K_storage - | K_code - | D_False - | D_Elt - | D_Left - | D_None - | D_Pair - | D_Right - | D_Some - | D_True - | D_Unit - | I_PACK - | I_UNPACK - | I_BLAKE2B - | I_SHA256 - | I_SHA512 - | I_ABS - | I_ADD - | I_AMOUNT - | I_AND - | I_BALANCE - | I_CAR - | I_CDR - | I_CHAIN_ID - | I_CHECK_SIGNATURE - | I_COMPARE - | I_CONCAT - | I_CONS - | I_CREATE_ACCOUNT - | I_CREATE_CONTRACT - | I_IMPLICIT_ACCOUNT - | I_DIP - | I_DROP - | I_DUP - | I_EDIV - | I_EMPTY_BIG_MAP - | I_EMPTY_MAP - | I_EMPTY_SET - | I_EQ - | I_EXEC - | I_APPLY - | I_FAILWITH - | I_GE - | I_GET_MAP - | I_GET_AND_UPDATE_MAP - | I_GT - | I_HASH_KEY - | I_IF - | I_IF_CONS - | I_IF_LEFT - | I_IF_NONE - | I_INT - | I_LAMBDA - | I_LE - | I_LEFT - | I_LOOP - | I_LSL - | I_LSR - | I_LT - | I_MAP_MAP - | I_MAP_LIST - | I_MEM_SET - | I_MEM_MAP - | I_MUL - | I_NEG - | I_NEQ - | I_NIL - | I_NONE - | I_NOT - | I_NOW - | I_OR - | I_PAIR - | I_UNPAIR - | I_PUSH - | I_RIGHT - | I_SIZE_SET - | I_SIZE_MAP - | I_SIZE_LIST - | I_SIZE_STRING - | I_SIZE_BYTES - | I_SOME - | I_SOURCE - | I_SENDER - | I_SELF - | I_SLICE - | I_STEPS_TO_QUOTA - | I_SUB - | I_SWAP - | I_TRANSFER_TOKENS - | I_SET_DELEGATE - | I_UNIT - | I_UPDATE_SET - | I_UPDATE_MAP - | I_XOR - | I_ITER_MAP - | I_ITER_LIST - | I_ITER_SET - | I_LOOP_LEFT - | I_ADDRESS - | I_CONTRACT - | I_ISNAT - | I_CAST - | I_RENAME - | I_DIG - | I_DUG - | I_LEVEL - | I_SELF_ADDRESS - | I_NEVER - | I_SAPLING_EMPTY_STATE - | I_SAPLING_VERIFY_UPDATE - | I_VOTING_POWER - | I_TOTAL_VOTING_POWER - | I_KECCAK - | I_SHA3 - | I_PAIRING_CHECK - | I_TICKET - | I_READ_TICKET - | I_SPLIT_TICKET - | I_JOIN_TICKETS - | T_bool - | T_contract - | T_int - | T_key - | T_key_hash - | T_lambda - | T_list - | T_map - | T_big_map - | T_nat - | T_option - | T_or - | T_pair - | T_set - | T_signature - | T_string - | T_bytes - | T_mutez - | T_timestamp - | T_unit - | T_operation - | T_address - | T_chain_id - | T_never - | T_sapling_state - | T_sapling_transaction - | T_bls12_381_g1 - | T_bls12_381_g2 - | T_bls12_381_fr - | T_ticket - (* Holes in programs and data. *) - | I_Hole - | D_Hole - (* Annotations. *) - | A_Int - | A_Nat - | A_Timestamp - | A_Mutez - | A_Key_hash - | A_Key - | A_List - | A_Set - | A_Map - | A_Lambda - -let relation = - [ - (K_parameter, Michelson_v1_primitives.K_parameter); - (K_storage, Michelson_v1_primitives.K_storage); - (K_code, Michelson_v1_primitives.K_code); - (D_False, Michelson_v1_primitives.D_False); - (D_Elt, Michelson_v1_primitives.D_Elt); - (D_Left, Michelson_v1_primitives.D_Left); - (D_None, Michelson_v1_primitives.D_None); - (D_Pair, Michelson_v1_primitives.D_Pair); - (D_Right, Michelson_v1_primitives.D_Right); - (D_Some, Michelson_v1_primitives.D_Some); - (D_True, Michelson_v1_primitives.D_True); - (D_Unit, Michelson_v1_primitives.D_Unit); - (I_PACK, Michelson_v1_primitives.I_PACK); - (I_UNPACK, Michelson_v1_primitives.I_UNPACK); - (I_BLAKE2B, Michelson_v1_primitives.I_BLAKE2B); - (I_SHA256, Michelson_v1_primitives.I_SHA256); - (I_SHA512, Michelson_v1_primitives.I_SHA512); - (I_ABS, Michelson_v1_primitives.I_ABS); - (I_ADD, Michelson_v1_primitives.I_ADD); - (I_AMOUNT, Michelson_v1_primitives.I_AMOUNT); - (I_AND, Michelson_v1_primitives.I_AND); - (I_BALANCE, Michelson_v1_primitives.I_BALANCE); - (I_CAR, Michelson_v1_primitives.I_CAR); - (I_CDR, Michelson_v1_primitives.I_CDR); - (I_CHAIN_ID, Michelson_v1_primitives.I_CHAIN_ID); - (I_CHECK_SIGNATURE, Michelson_v1_primitives.I_CHECK_SIGNATURE); - (I_COMPARE, Michelson_v1_primitives.I_COMPARE); - (I_CONCAT, Michelson_v1_primitives.I_CONCAT); - (I_CONS, Michelson_v1_primitives.I_CONS); - (I_CREATE_ACCOUNT, Michelson_v1_primitives.I_CREATE_ACCOUNT); - (I_CREATE_CONTRACT, Michelson_v1_primitives.I_CREATE_CONTRACT); - (I_IMPLICIT_ACCOUNT, Michelson_v1_primitives.I_IMPLICIT_ACCOUNT); - (I_DIP, Michelson_v1_primitives.I_DIP); - (I_DROP, Michelson_v1_primitives.I_DROP); - (I_DUP, Michelson_v1_primitives.I_DUP); - (I_EDIV, Michelson_v1_primitives.I_EDIV); - (I_EMPTY_BIG_MAP, Michelson_v1_primitives.I_EMPTY_BIG_MAP); - (I_EMPTY_MAP, Michelson_v1_primitives.I_EMPTY_MAP); - (I_EMPTY_SET, Michelson_v1_primitives.I_EMPTY_SET); - (I_EQ, Michelson_v1_primitives.I_EQ); - (I_EXEC, Michelson_v1_primitives.I_EXEC); - (I_APPLY, Michelson_v1_primitives.I_APPLY); - (I_FAILWITH, Michelson_v1_primitives.I_FAILWITH); - (I_GE, Michelson_v1_primitives.I_GE); - (I_GET_MAP, Michelson_v1_primitives.I_GET); - (I_GET_AND_UPDATE_MAP, Michelson_v1_primitives.I_GET_AND_UPDATE); - (I_GT, Michelson_v1_primitives.I_GT); - (I_HASH_KEY, Michelson_v1_primitives.I_HASH_KEY); - (I_IF, Michelson_v1_primitives.I_IF); - (I_IF_CONS, Michelson_v1_primitives.I_IF_CONS); - (I_IF_LEFT, Michelson_v1_primitives.I_IF_LEFT); - (I_IF_NONE, Michelson_v1_primitives.I_IF_NONE); - (I_INT, Michelson_v1_primitives.I_INT); - (I_LAMBDA, Michelson_v1_primitives.I_LAMBDA); - (I_LE, Michelson_v1_primitives.I_LE); - (I_LEFT, Michelson_v1_primitives.I_LEFT); - (I_LEVEL, Michelson_v1_primitives.I_LEVEL); - (I_LOOP, Michelson_v1_primitives.I_LOOP); - (I_LSL, Michelson_v1_primitives.I_LSL); - (I_LSR, Michelson_v1_primitives.I_LSR); - (I_LT, Michelson_v1_primitives.I_LT); - (I_MAP_MAP, Michelson_v1_primitives.I_MAP); - (I_MAP_LIST, Michelson_v1_primitives.I_MAP); - (I_MEM_SET, Michelson_v1_primitives.I_MEM); - (I_MEM_MAP, Michelson_v1_primitives.I_MEM); - (I_MUL, Michelson_v1_primitives.I_MUL); - (I_NEG, Michelson_v1_primitives.I_NEG); - (I_NEQ, Michelson_v1_primitives.I_NEQ); - (I_NIL, Michelson_v1_primitives.I_NIL); - (I_NONE, Michelson_v1_primitives.I_NONE); - (I_NOT, Michelson_v1_primitives.I_NOT); - (I_NOW, Michelson_v1_primitives.I_NOW); - (I_OR, Michelson_v1_primitives.I_OR); - (I_PAIR, Michelson_v1_primitives.I_PAIR); - (I_UNPAIR, Michelson_v1_primitives.I_UNPAIR); - (I_PUSH, Michelson_v1_primitives.I_PUSH); - (I_RIGHT, Michelson_v1_primitives.I_RIGHT); - (I_SIZE_SET, Michelson_v1_primitives.I_SIZE); - (I_SIZE_MAP, Michelson_v1_primitives.I_SIZE); - (I_SIZE_LIST, Michelson_v1_primitives.I_SIZE); - (I_SIZE_STRING, Michelson_v1_primitives.I_SIZE); - (I_SIZE_BYTES, Michelson_v1_primitives.I_SIZE); - (I_SOME, Michelson_v1_primitives.I_SOME); - (I_SOURCE, Michelson_v1_primitives.I_SOURCE); - (I_SENDER, Michelson_v1_primitives.I_SENDER); - (I_SELF, Michelson_v1_primitives.I_SELF); - (I_SELF_ADDRESS, Michelson_v1_primitives.I_SELF_ADDRESS); - (I_SLICE, Michelson_v1_primitives.I_SLICE); - (I_STEPS_TO_QUOTA, Michelson_v1_primitives.I_STEPS_TO_QUOTA); - (I_SUB, Michelson_v1_primitives.I_SUB); - (I_SWAP, Michelson_v1_primitives.I_SWAP); - (I_TRANSFER_TOKENS, Michelson_v1_primitives.I_TRANSFER_TOKENS); - (I_SET_DELEGATE, Michelson_v1_primitives.I_SET_DELEGATE); - (I_UNIT, Michelson_v1_primitives.I_UNIT); - (I_UPDATE_SET, Michelson_v1_primitives.I_UPDATE); - (I_UPDATE_MAP, Michelson_v1_primitives.I_UPDATE); - (I_XOR, Michelson_v1_primitives.I_XOR); - (I_ITER_MAP, Michelson_v1_primitives.I_ITER); - (I_ITER_LIST, Michelson_v1_primitives.I_ITER); - (I_ITER_SET, Michelson_v1_primitives.I_ITER); - (I_LOOP_LEFT, Michelson_v1_primitives.I_LOOP_LEFT); - (I_ADDRESS, Michelson_v1_primitives.I_ADDRESS); - (I_CONTRACT, Michelson_v1_primitives.I_CONTRACT); - (I_ISNAT, Michelson_v1_primitives.I_ISNAT); - (I_CAST, Michelson_v1_primitives.I_CAST); - (I_RENAME, Michelson_v1_primitives.I_RENAME); - (I_SAPLING_EMPTY_STATE, Michelson_v1_primitives.I_SAPLING_EMPTY_STATE); - (I_SAPLING_VERIFY_UPDATE, Michelson_v1_primitives.I_SAPLING_VERIFY_UPDATE); - (I_DIG, Michelson_v1_primitives.I_DIG); - (I_DUG, Michelson_v1_primitives.I_DUG); - (I_NEVER, Michelson_v1_primitives.I_NEVER); - (I_VOTING_POWER, Michelson_v1_primitives.I_VOTING_POWER); - (I_TOTAL_VOTING_POWER, Michelson_v1_primitives.I_TOTAL_VOTING_POWER); - (I_KECCAK, Michelson_v1_primitives.I_KECCAK); - (I_SHA3, Michelson_v1_primitives.I_SHA3); - (I_PAIRING_CHECK, Michelson_v1_primitives.I_PAIRING_CHECK); - (I_TICKET, Michelson_v1_primitives.I_TICKET); - (I_READ_TICKET, Michelson_v1_primitives.I_READ_TICKET); - (I_SPLIT_TICKET, Michelson_v1_primitives.I_SPLIT_TICKET); - (I_JOIN_TICKETS, Michelson_v1_primitives.I_JOIN_TICKETS); - (T_bool, Michelson_v1_primitives.T_bool); - (T_contract, Michelson_v1_primitives.T_contract); - (T_int, Michelson_v1_primitives.T_int); - (T_key, Michelson_v1_primitives.T_key); - (T_key_hash, Michelson_v1_primitives.T_key_hash); - (T_lambda, Michelson_v1_primitives.T_lambda); - (T_list, Michelson_v1_primitives.T_list); - (T_map, Michelson_v1_primitives.T_map); - (T_big_map, Michelson_v1_primitives.T_big_map); - (T_nat, Michelson_v1_primitives.T_nat); - (T_option, Michelson_v1_primitives.T_option); - (T_or, Michelson_v1_primitives.T_or); - (T_pair, Michelson_v1_primitives.T_pair); - (T_set, Michelson_v1_primitives.T_set); - (T_signature, Michelson_v1_primitives.T_signature); - (T_string, Michelson_v1_primitives.T_string); - (T_bytes, Michelson_v1_primitives.T_bytes); - (T_mutez, Michelson_v1_primitives.T_mutez); - (T_timestamp, Michelson_v1_primitives.T_timestamp); - (T_unit, Michelson_v1_primitives.T_unit); - (T_operation, Michelson_v1_primitives.T_operation); - (T_address, Michelson_v1_primitives.T_address); - (T_sapling_transaction, Michelson_v1_primitives.T_sapling_transaction); - (T_sapling_state, Michelson_v1_primitives.T_sapling_state); - (T_chain_id, Michelson_v1_primitives.T_chain_id); - (T_never, Michelson_v1_primitives.T_never); - (T_bls12_381_g1, Michelson_v1_primitives.T_bls12_381_g1); - (T_bls12_381_g2, Michelson_v1_primitives.T_bls12_381_g2); - (T_bls12_381_fr, Michelson_v1_primitives.T_bls12_381_fr); - (T_ticket, Michelson_v1_primitives.T_ticket); - ] - -let relation_table = - let table = Hashtbl.create 269 in - List.iter - (fun (mikhailsky, michelson) -> Hashtbl.add table mikhailsky michelson) - relation ; - table - -exception Primitive_cannot_be_cast_back_to_Michelson of prim - -let to_michelson prim = - match Hashtbl.find relation_table prim with - | exception Not_found -> - raise (Primitive_cannot_be_cast_back_to_Michelson prim) - | res -> res - -let string_of_prim prim = - match prim with - | K_parameter -> "K_parameter" - | K_storage -> "K_storage" - | K_code -> "K_code" - | D_False -> "D_False" - | D_Elt -> "D_Elt" - | D_Left -> "D_Left" - | D_None -> "D_None" - | D_Pair -> "D_Pair" - | D_Right -> "D_Right" - | D_Some -> "D_Some" - | D_True -> "D_True" - | D_Unit -> "D_Unit" - | I_PACK -> "I_PACK" - | I_UNPACK -> "I_UNPACK" - | I_BLAKE2B -> "I_BLAKE2B" - | I_SHA256 -> "I_SHA256" - | I_SHA512 -> "I_SHA512" - | I_ABS -> "I_ABS" - | I_ADD -> "I_ADD" - | I_AMOUNT -> "I_AMOUNT" - | I_AND -> "I_AND" - | I_BALANCE -> "I_BALANCE" - | I_CAR -> "I_CAR" - | I_CDR -> "I_CDR" - | I_CHAIN_ID -> "I_CHAIN_ID" - | I_CHECK_SIGNATURE -> "I_CHECK_SIGNATURE" - | I_COMPARE -> "I_COMPARE" - | I_CONCAT -> "I_CONCAT" - | I_CONS -> "I_CONS" - | I_CREATE_ACCOUNT -> "I_CREATE_ACCOUNT" - | I_CREATE_CONTRACT -> "I_CREATE_CONTRACT" - | I_IMPLICIT_ACCOUNT -> "I_IMPLICIT_ACCOUNT" - | I_DIP -> "I_DIP" - | I_DROP -> "I_DROP" - | I_DUP -> "I_DUP" - | I_EDIV -> "I_EDIV" - | I_EMPTY_BIG_MAP -> "I_EMPTY_BIG_MAP" - | I_EMPTY_MAP -> "I_EMPTY_MAP" - | I_EMPTY_SET -> "I_EMPTY_SET" - | I_EQ -> "I_EQ" - | I_EXEC -> "I_EXEC" - | I_APPLY -> "I_APPLY" - | I_FAILWITH -> "I_FAILWITH" - | I_GE -> "I_GE" - | I_GET_MAP -> "I_GET_MAP" - | I_GET_AND_UPDATE_MAP -> "I_GET_AND_UPDATE_MAP" - | I_GT -> "I_GT" - | I_HASH_KEY -> "I_HASH_KEY" - | I_IF -> "I_IF" - | I_IF_CONS -> "I_IF_CONS" - | I_IF_LEFT -> "I_IF_LEFT" - | I_IF_NONE -> "I_IF_NONE" - | I_INT -> "I_INT" - | I_LAMBDA -> "I_LAMBDA" - | I_LE -> "I_LE" - | I_LEFT -> "I_LEFT" - | I_LOOP -> "I_LOOP" - | I_LSL -> "I_LSL" - | I_LSR -> "I_LSR" - | I_LT -> "I_LT" - | I_MAP_MAP -> "I_MAP_MAP" - | I_MAP_LIST -> "I_MAP_LIST" - | I_MEM_SET -> "I_MEM_SET" - | I_MEM_MAP -> "I_MEM_MAP" - | I_MUL -> "I_MUL" - | I_NEG -> "I_NEG" - | I_NEQ -> "I_NEQ" - | I_NIL -> "I_NIL" - | I_NONE -> "I_NONE" - | I_NOT -> "I_NOT" - | I_NOW -> "I_NOW" - | I_OR -> "I_OR" - | I_PAIR -> "I_PAIR" - | I_UNPAIR -> "I_UNPAIR" - | I_PUSH -> "I_PUSH" - | I_RIGHT -> "I_RIGHT" - | I_SIZE_SET -> "I_SIZE_SET" - | I_SIZE_MAP -> "I_SIZE_MAP" - | I_SIZE_LIST -> "I_SIZE_LIST" - | I_SIZE_STRING -> "I_SIZE_STRING" - | I_SIZE_BYTES -> "I_SIZE_BYTES" - | I_SOME -> "I_SOME" - | I_SOURCE -> "I_SOURCE" - | I_SENDER -> "I_SENDER" - | I_SELF -> "I_SELF" - | I_SLICE -> "I_SLICE" - | I_STEPS_TO_QUOTA -> "I_STEPS_TO_QUOTA" - | I_SUB -> "I_SUB" - | I_SWAP -> "I_SWAP" - | I_TRANSFER_TOKENS -> "I_TRANSFER_TOKENS" - | I_SET_DELEGATE -> "I_SET_DELEGATE" - | I_UNIT -> "I_UNIT" - | I_UPDATE_SET -> "I_UPDATE_SET" - | I_UPDATE_MAP -> "I_UPDATE_MAP" - | I_XOR -> "I_XOR" - | I_ITER_MAP -> "I_ITER_MAP" - | I_ITER_LIST -> "I_ITER_LIST" - | I_ITER_SET -> "I_ITER_SET" - | I_LOOP_LEFT -> "I_LOOP_LEFT" - | I_ADDRESS -> "I_ADDRESS" - | I_CONTRACT -> "I_CONTRACT" - | I_ISNAT -> "I_ISNAT" - | I_CAST -> "I_CAST" - | I_RENAME -> "I_RENAME" - | I_DIG -> "I_DIG" - | I_DUG -> "I_DUG" - | I_LEVEL -> "I_LEVEL" - | I_SELF_ADDRESS -> "I_SELF_ADDRESS" - | I_NEVER -> "I_NEVER" - | I_SAPLING_EMPTY_STATE -> "I_SAPLING_EMPTY_STATE" - | I_SAPLING_VERIFY_UPDATE -> "I_SAPLING_VERIFY_UPDATE" - | I_VOTING_POWER -> "I_VOTING_POWER" - | I_TOTAL_VOTING_POWER -> "I_TOTAL_VOTING_POWER" - | I_KECCAK -> "I_KECCAK" - | I_SHA3 -> "I_SHA3" - | I_PAIRING_CHECK -> "I_PAIRING_CHECK" - | I_TICKET -> "I_TICKET" - | I_READ_TICKET -> "I_READ_TICKET" - | I_SPLIT_TICKET -> "I_SPLIT_TICKET" - | I_JOIN_TICKETS -> "I_JOIN_TICKETS" - | T_bool -> "T_bool" - | T_contract -> "T_contract" - | T_int -> "T_int" - | T_key -> "T_key" - | T_key_hash -> "T_key_hash" - | T_lambda -> "T_lambda" - | T_list -> "T_list" - | T_map -> "T_map" - | T_big_map -> "T_big_map" - | T_nat -> "T_nat" - | T_option -> "T_option" - | T_or -> "T_or" - | T_pair -> "T_pair" - | T_set -> "T_set" - | T_signature -> "T_signature" - | T_string -> "T_string" - | T_bytes -> "T_bytes" - | T_mutez -> "T_mutez" - | T_timestamp -> "T_timestamp" - | T_unit -> "T_unit" - | T_operation -> "T_operation" - | T_address -> "T_address" - | T_chain_id -> "T_chain_id" - | T_never -> "T_never" - | T_sapling_state -> "T_sapling_state" - | T_sapling_transaction -> "T_sapling_transaction" - | T_bls12_381_g1 -> "T_bls12_381_g1" - | T_bls12_381_g2 -> "T_bls12_381_g2" - | T_bls12_381_fr -> "T_bls12_381_fr" - | T_ticket -> "T_ticket" - | I_Hole -> "I_Hole" - | D_Hole -> "D_Hole" - | A_Int -> "A_Int" - | A_Nat -> "A_Nat" - | A_Timestamp -> "A_Timestamp" - | A_Mutez -> "A_Mutez" - | A_Key_hash -> "A_Key_hash" - | A_Key -> "A_Key" - | A_List -> "A_List" - | A_Set -> "A_Set" - | A_Map -> "A_Map" - | A_Lambda -> "A_Lambda" - -let pp fmtr prim = Format.fprintf fmtr "%s" (string_of_prim prim) - -type kind = Data_kind | Instr_kind | Type_kind | Keyword_kind | Annot_kind - -let kind (x : prim) = - match x with - | K_parameter | K_storage | K_code -> Keyword_kind - | D_Hole | D_False | D_Elt | D_Left | D_None | D_Pair | D_Right | D_Some - | D_True | D_Unit -> - Data_kind - | I_PACK | I_UNPACK | I_BLAKE2B | I_SHA256 | I_SHA512 | I_ABS | I_ADD - | I_AMOUNT | I_AND | I_BALANCE | I_CAR | I_CDR | I_CHAIN_ID - | I_CHECK_SIGNATURE | I_COMPARE | I_CONCAT | I_CONS | I_CREATE_ACCOUNT - | I_CREATE_CONTRACT | I_IMPLICIT_ACCOUNT | I_DIP | I_DROP | I_DUP | I_EDIV - | I_EMPTY_BIG_MAP | I_EMPTY_MAP | I_EMPTY_SET | I_EQ | I_EXEC | I_APPLY - | I_FAILWITH | I_GE | I_GET_MAP | I_GET_AND_UPDATE_MAP | I_GT | I_HASH_KEY - | I_IF | I_IF_CONS | I_IF_LEFT | I_IF_NONE | I_INT | I_LAMBDA | I_LE | I_LEFT - | I_LOOP | I_LSL | I_LSR | I_LT | I_MAP_MAP | I_MAP_LIST | I_MEM_SET - | I_MEM_MAP | I_MUL | I_NEG | I_NEQ | I_NIL | I_NONE | I_NOT | I_NOW | I_OR - | I_PAIR | I_UNPAIR | I_PUSH | I_RIGHT | I_SIZE_SET | I_SIZE_MAP | I_SIZE_LIST - | I_SIZE_STRING | I_SIZE_BYTES | I_SOME | I_SOURCE | I_SENDER | I_SELF - | I_SLICE | I_STEPS_TO_QUOTA | I_SUB | I_SWAP | I_TRANSFER_TOKENS - | I_SET_DELEGATE | I_UNIT | I_UPDATE_SET | I_UPDATE_MAP | I_XOR | I_ITER_MAP - | I_ITER_LIST | I_ITER_SET | I_LOOP_LEFT | I_ADDRESS | I_CONTRACT | I_ISNAT - | I_CAST | I_RENAME | I_DIG | I_DUG | I_LEVEL | I_SELF_ADDRESS | I_NEVER - | I_SAPLING_EMPTY_STATE | I_SAPLING_VERIFY_UPDATE | I_VOTING_POWER - | I_TOTAL_VOTING_POWER | I_KECCAK | I_SHA3 | I_PAIRING_CHECK | I_TICKET - | I_READ_TICKET | I_SPLIT_TICKET | I_JOIN_TICKETS | I_Hole -> - Instr_kind - | T_bool | T_contract | T_int | T_key | T_key_hash | T_lambda | T_list | T_map - | T_big_map | T_nat | T_option | T_or | T_pair | T_set | T_signature - | T_string | T_bytes | T_mutez | T_timestamp | T_unit | T_operation - | T_address | T_chain_id | T_never | T_sapling_state | T_sapling_transaction - | T_bls12_381_g1 | T_bls12_381_g2 | T_bls12_381_fr | T_ticket -> - Type_kind - (* Holes in programs and data. *) - (* Annotations. *) - | A_Int | A_Nat | A_Timestamp | A_Mutez | A_Key_hash | A_Key | A_List | A_Set - | A_Map | A_Lambda -> - Annot_kind diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/monads.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/monads.ml deleted file mode 100644 index d0939011cb5e..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/monads.ml +++ /dev/null @@ -1,83 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Widely used module types. *) - -module type S = sig - type 'a t - - val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t - - val return : 'a -> 'a t - - val run : 'a t -> 'a -end - -(* Signature of a state monad. *) -module type State_sig = sig - type state - - type key - - type value - - include S with type 'a t = state -> 'a * state - - val empty : unit -> state - - val set : key -> value -> unit t - - val get : key -> value option t - - val iter_list : ('a -> unit t) -> 'a list -> unit t -end - -module Make_state_monad (X : Stores.S) : - State_sig - with type state = X.state - and type key = X.key - and type value = X.value - and type 'a t = X.state -> 'a * X.state = struct - include X - - type 'a t = state -> 'a * state - - let ( >>= ) m f s = - let (x, s) = m s in - f x s - - let return x s = (x, s) - - let run m = fst (m (empty ())) - - let set k v s = ((), set k v s) - - let get k s = (get k s, s) - - let rec iter_list (f : 'a -> unit t) (l : 'a list) = - match l with - | [] -> return () - | elt :: tl -> f elt >>= fun () -> iter_list f tl -end diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/stores.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/stores.ml deleted file mode 100644 index dff87824d1b4..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/stores.ml +++ /dev/null @@ -1,85 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Various implementations of Monads.Store_sig *) - -(* Signature of a persistent store. *) -module type S = sig - type state - - type key - - type value - - val empty : unit -> state - - val set : key -> value -> state -> state - - val get : key -> state -> value option - - val map : (value -> value) -> state -> state - - val to_string : state -> string -end - -module type Map_store_param_sig = sig - type key - - type value - - val key_to_string : key -> string - - val value_to_string : value -> string -end - -(* An implemention of [S] using maps. *) -module Map (M : Map.S) (V : Map_store_param_sig with type key = M.key) : - S with type state = V.value M.t and type key = M.key and type value = V.value = -struct - type state = V.value M.t - - type key = M.key - - type value = V.value - - let empty () = M.empty - - let set = M.add - - let get = M.find_opt - - let map = M.map - - let to_string s = - M.fold - (fun key node acc -> - Printf.sprintf - "%s\n%s |-> %s" - acc - (V.key_to_string key) - (V.value_to_string node)) - s - "" -end diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/.ocamlformat b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/dune b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/dune deleted file mode 100644 index a8e7aed807e9..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/dune +++ /dev/null @@ -1,10 +0,0 @@ -(tests - (names test_uf - test_inference) - (package tezos-benchmark-type-inference-012-Psithaca) - (libraries tezos-micheline tezos-micheline-rewriting - tezos-benchmark-type-inference-012-Psithaca tezos-protocol-012-Psithaca - tezos-error-monad tezos-client-012-Psithaca) - (flags - (:standard -open Tezos_micheline - -open Tezos_benchmark_type_inference_012_Psithaca))) diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/test_inference.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/test_inference.ml deleted file mode 100644 index 93aa25022308..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/test_inference.ml +++ /dev/null @@ -1,615 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* open Tezos_rewriting *) -open Mikhailsky - -let unopt x = match x with Some x -> x | None -> assert false - -let time f = - let now = Unix.gettimeofday () in - let res = f () in - let later = Unix.gettimeofday () in - (later -. now, res) - -let add_ii = Instructions.(add Mikhailsky.int_ty Mikhailsky.int_ty) - -let add_in = Instructions.(add Mikhailsky.int_ty Mikhailsky.nat_ty) - -let mul_ii = Instructions.(mul Mikhailsky.int_ty Mikhailsky.int_ty) - -let push_int = Instructions.push int_ty (Data.big_integer (Z.of_int 100)) - -let push_nat = Instructions.push nat_ty (Data.big_natural (Z.of_int 100)) - -module Test1 = struct - open Data - open Instructions - - let program = seq [add_ii; push bool_ty false_; dip instr_hole; dip swap] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test2 = struct - open Instructions - - let program = seq [loop swap; and_] - - let () = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING FAILURE\n" ; - Format.printf "Program: %a\n" Mikhailsky.pp program ; - let exception Test_failed in - try - ignore - ( time @@ fun () -> - ignore @@ Inference.infer program ; - raise Test_failed ) - with - | Inference.Ill_typed_script error -> - Format.printf "Error:\n" ; - Format.printf "%a\n" Inference.pp_inference_error error - | Test_failed -> Format.printf "No type error: Test failed!" - - let _ = print_newline () -end - -module Test3 = struct - open Instructions - - let program = - seq - [ - dip (seq [swap; dup]); - swap; - dip cdr; - loop (seq [dip instr_hole; cdr; loop instr_hole]); - car; - car; - push int_ty (Data.integer 10); - compare; - ] - - let _ = - Format.printf "Testing rewriting and type inference\n" ; - Format.printf "Source program: %a\n" Mikhailsky.pp program - - open Tezos_micheline_rewriting - - module Lang = - Micheline_with_hash_consing.Make - (Mikhailsky.Mikhailsky_signature) - (struct - let initial_size = None - end) - - module Path = Mikhailsky.Path - module Patt = Pattern.Make (Mikhailsky.Mikhailsky_signature) (Lang) (Path) - module Rewriter = - Rewrite.Make (Mikhailsky.Mikhailsky_signature) (Lang) (Path) (Patt) - - let (timing, ((bef, aft), state)) = - try time @@ fun () -> Inference.infer_with_state program - with Inference.Ill_typed_script error -> - let s = Mikhailsky.to_string program in - Format.printf - "Ill-typed script:%a\n%s\n" - Inference.pp_inference_error - error - s ; - Format.printf "Test failed\n" ; - exit 1 - - let () = - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft - - let () = - try - ignore - ((let open Inference in - let open M in - M.uf_lift Uf.UF.show >>= fun uf_state -> - Inference.M.repr_lift (fun s -> (Inference.Repr_store.to_string s, s)) - >>= fun repr_state -> - Printf.printf "uf_state:\n%s\n" uf_state ; - Printf.printf "repr_state:\n%s\n" repr_state ; - let path = - Path.(at_index 2 (at_index 0 (at_index 0 (at_index 3 root)))) - in - let subterm = Rewriter.get_subterm ~term:program ~path in - Format.printf - "subterm at path %s:\n%a\n" - (Path.to_string path) - Mikhailsky.pp - subterm ; - Inference.M.annot_instr_lift (Inference.Annot_instr_sm.get path) - >>= fun typ -> - (match typ with - | None -> assert false - | Some {bef; aft} -> - Inference.instantiate bef >>= fun bef -> - Inference.instantiate aft >>= fun aft -> - Format.printf "Type of subterm:\n" ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - return ()) - >>= fun () -> return ()) - state) - with Inference.Ill_typed_script error -> - let s = Mikhailsky.to_string program in - Format.printf - "Ill-typed script:\n%a\n%s\n" - Inference.pp_inference_error - error - s - - let _ = print_newline () -end - -module Test4 = struct - open Instructions - - let program = - seq - [ - empty_set; - push Type.(unopt (unparse_ty bool)) Data.true_; - push - Type.(unopt (unparse_ty (pair int int))) - Data.(pair (integer 0) (integer 0)); - update_set; - ] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test5 = struct - open Instructions - - let unopt x = match x with Some x -> x | None -> assert false - - let program = - seq - [ - empty_map; - push Type.(unopt (unparse_ty (option (set int)))) Data.none; - push - Type.(unopt (unparse_ty (pair int int))) - Data.(pair (integer 0) (integer 0)); - update_map; - ] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () - - let program = - seq - [ - push - Type.(unopt (unparse_ty (map (pair int int) (set int)))) - Data.( - map - [ - map_elt - (pair (integer 0) (integer 1)) - (set [integer 42; integer 44]); - map_elt - (pair (integer 1) (integer 2)) - (set [integer 42; integer 48]); - ]); - ] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test6 = struct - open Instructions - - (* We remove a chunk from a well-typed program to make it ill-typed, and - expect the type inference to fail *) - let program = - seq - [ - push int_ty (Data.integer 0); - push int_ty (Data.integer 100); - swap; - drop; - drop; - drop; - push unit_ty Data.unit; - push bool_ty Data.false_; - push unit_ty Data.unit; - push int_ty (Data.integer 4073851221413541140); - push string_ty (string "n"); - push string_ty (string "k"); - push int_ty (Data.integer 1391989767887046289); - (* push int_ty (integer 100); - * abs; - * drop; *) - dip (prim I_CONCAT [] []); - compare; - ] - - let () = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING FAILURE\n" ; - Format.printf "Program: %a\n" Mikhailsky.pp program ; - let exception Test_failed in - try - ignore (Inference.infer program) ; - raise Test_failed - with - | Inference.Ill_typed_script error -> - Format.printf "Got error, as expected:\n" ; - Format.printf "%a@." Inference.pp_inference_error error - | Test_failed -> - Format.printf "No type error: Test failed!" ; - exit 1 -end - -module Test7 = struct - open Instructions - - let program = - seq - [ - push int_ty (Data.integer 42); - left; - push string_ty (Data.string "forty-two"); - right; - pair; - left; - ] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test8 = struct - open Instructions - - let program = - seq - [ - hole; - add_ii; - push int_ty (Data.big_integer (Z.of_int 100)); - abs; - right; - dup; - push int_ty (Data.big_integer (Z.of_int 100)); - dip (loop_left hole); - push_int; - hole; - mul_ii; - hole; - loop_left left; - sha512; - push_int; - dup; - add_ii; - right; - swap; - hole; - drop; - compare; - mul_ii; - push_int; - ] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test9 = struct - open Instructions - - let program = seq [car; if_none hole hole] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test10 = struct - open Instructions - - let program = seq [hash_key] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test11 = struct - open Instructions - - let program = - seq [lambda [dup; car; dip cdr; add_in]; push_int; apply; push_nat; exec] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test12 = struct - open Instructions - - let program = seq [dup; dup; if_none hole (seq [drop]); dup; compare] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test13 = struct - open Instructions - - let program = - seq [push Type.(unparse_ty_exn (lambda int int)) (Data.lambda [])] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test14 = struct - open Instructions - - let program = seq [nil; push_int; cons] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test15 = struct - open Instructions - - let program = seq [empty_set; size_set; empty_map; size_map; nil; size_list] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test16 = struct - open Instructions - - let program = - seq - [ - empty_set; - push bool_ty Data.true_; - push_int; - update_set; - iter_set [dup; add_ii; add_ii]; - ] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test17 = struct - open Instructions - - let program = - seq - [ - empty_map; - push (option_ty (list_ty bool_ty)) Data.(some (list [false_; true_])); - push_int; - update_map; - map_map - [ - cdr; - map_list - [ - if_ - (seq [push bool_ty Data.false_]) - (seq [push bool_ty Data.true_]); - ]; - ]; - ] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end - -module Test18 = struct - open Instructions - - let program = - seq - [ - empty_map; - push (option_ty (list_ty bool_ty)) Data.(some (list [false_; true_])); - push_int; - update_map; - map_map - [ - cdr; - map_list - [ - if_ - (seq [push bool_ty Data.false_]) - (seq [push bool_ty Data.true_]); - ]; - ]; - dup; - dip push_int; - push_int; - mem_map; - if_ - (seq [get_map]) - (seq [drop; drop; push (option_ty (list_ty bool_ty)) Data.none]); - ] - - let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program - - let _ = - Format.printf "Testing type inference\n" ; - Format.printf "EXPECTING SUCCESS\n" ; - Format.printf "Program\n" ; - Format.printf "%a\n" Mikhailsky.pp program ; - Format.printf "In %f seconds:\n" timing ; - Format.printf "bef: %a@." Type.Stack.pp bef ; - Format.printf "aft: %a@." Type.Stack.pp aft ; - print_newline () -end diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/test_uf.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/test_uf.ml deleted file mode 100644 index 84fdd856e9ba..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/test/test_uf.ml +++ /dev/null @@ -1,63 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let _ = - print_newline () ; - Printf.printf "Testing union-find algorithm\n" - -module UF = Uf.UF - -let test = - let open UF.M in - UF.add 0 >>= fun () -> - UF.add 1 >>= fun () -> - UF.add 2 >>= fun () -> - UF.add 3 >>= fun () -> - UF.add 4 >>= fun () -> - UF.find 0 >>= fun v0_repr -> - UF.find 1 >>= fun v1_repr -> - assert (v0_repr <> v1_repr) ; - UF.union 0 1 >>= fun _ -> - UF.find 0 >>= fun v0_repr -> - UF.find 1 >>= fun v1_repr -> - UF.find 2 >>= fun v2_repr -> - assert (v0_repr = v1_repr) ; - assert (v0_repr <> v2_repr) ; - UF.union 2 3 >>= fun _ -> - UF.union 0 3 >>= fun _ -> - UF.find 1 >>= fun v1_repr -> - UF.find 2 >>= fun v2_repr -> - UF.find 3 >>= fun v3_repr -> - UF.find 4 >>= fun v4_repr -> - assert (v1_repr = v2_repr) ; - UF.union 4 4 >>= fun _ -> - assert (v3_repr <> v4_repr) ; - UF.show >>= fun s -> - Printf.printf "UF state:%s\n" s ; - return () - -let () = UF.M.run test - -let _ = Printf.printf "Success.\n" diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/tezos-benchmark-type-inference-012-Psithaca.opam b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/tezos-benchmark-type-inference-012-Psithaca.opam deleted file mode 100644 index 9e280a7c7b4e..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/tezos-benchmark-type-inference-012-Psithaca.opam +++ /dev/null @@ -1,24 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "tezos-tooling" { with-test } - "tezos-client-012-Psithaca" { with-test } - "dune" { >= "1.11" } - "tezos-stdlib" - "tezos-error-monad" - "tezos-crypto" - "tezos-protocol-012-Psithaca" - "tezos-micheline" - "tezos-micheline-rewriting" - "hashcons" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos: type inference for partial Michelson expressions" diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/type.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/type.ml deleted file mode 100644 index dacd2ac7f8fd..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/type.ml +++ /dev/null @@ -1,201 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Michelson types. *) - -module Base = struct - type comparable_tag = Comparable | Maybe_not_comparable - - type t = t_node Hashcons.hash_consed - - and t_node = - | Unit_t - | Var_t of int - | Int_t - | Nat_t - | Bool_t - | String_t - | Bytes_t - | Key_hash_t - | Timestamp_t - | Mutez_t - | Key_t - | Option_t of t - | Pair_t of t * t - | Union_t of t * t - | List_t of t - | Set_t of t - | Map_t of t * t - | Lambda_t of t * t - - module Hashed = struct - type t = t_node - - let equal (t1 : t) (t2 : t) = - match (t1, t2) with - | (Var_t v1, Var_t v2) -> v1 = v2 - | (Unit_t, Unit_t) - | (Int_t, Int_t) - | (Nat_t, Nat_t) - | (Bool_t, Bool_t) - | (String_t, String_t) - | (Bytes_t, Bytes_t) - | (Key_hash_t, Key_hash_t) - | (Timestamp_t, Timestamp_t) - | (Mutez_t, Mutez_t) - | (Key_t, Key_t) -> - true - | (Option_t ty1, Option_t ty2) -> ty1.tag = ty2.tag - | (Pair_t (l1, r1), Pair_t (l2, r2)) -> l1.tag = l2.tag && r1.tag = r2.tag - | (Union_t (l1, r1), Union_t (l2, r2)) -> - l1.tag = l2.tag && r1.tag = r2.tag - | (List_t ty1, List_t ty2) -> ty1.tag = ty2.tag - | (Set_t ty1, Set_t ty2) -> ty1.tag = ty2.tag - | (Map_t (kty1, vty1), Map_t (kty2, vty2)) -> - kty1.tag = kty2.tag && vty1.tag = vty2.tag - | (Lambda_t (dom1, range1), Lambda_t (dom2, range2)) -> - dom1.tag = dom2.tag && range1.tag = range2.tag - | _ -> false - - let hash (t : t) = Hashtbl.hash t - end - - module Table = Hashcons.Make (Hashed) - - let table = Table.create 101 - - let rec pp fmtr x = - match x.Hashcons.node with - | Unit_t -> Format.pp_print_string fmtr "unit" - | Var_t v -> Format.fprintf fmtr "%d" v - | Int_t -> Format.pp_print_string fmtr "int" - | Nat_t -> Format.pp_print_string fmtr "nat" - | Bool_t -> Format.pp_print_string fmtr "bool" - | String_t -> Format.pp_print_string fmtr "string" - | Bytes_t -> Format.pp_print_string fmtr "bytes" - | Key_hash_t -> Format.pp_print_string fmtr "key_hash" - | Timestamp_t -> Format.pp_print_string fmtr "timestamp" - | Mutez_t -> Format.pp_print_string fmtr "mutez" - | Key_t -> Format.pp_print_string fmtr "key" - | Option_t ty -> Format.fprintf fmtr "(option %a)" pp ty - | List_t ty -> Format.fprintf fmtr "(list %a)" pp ty - | Pair_t (lty, rty) -> Format.fprintf fmtr "(pair %a %a)" pp lty pp rty - | Union_t (lty, rty) -> Format.fprintf fmtr "(union %a %a)" pp lty pp rty - | Set_t ty -> Format.fprintf fmtr "(set %a)" pp ty - | Map_t (kty, vty) -> Format.fprintf fmtr "(map %a %a)" pp kty pp vty - | Lambda_t (dom, range) -> - Format.fprintf fmtr "(lambda %a %a)" pp dom pp range - - let rec vars x acc = - match x.Hashcons.node with - | Unit_t | Int_t | Nat_t | Bool_t | String_t | Bytes_t | Key_hash_t - | Timestamp_t | Mutez_t | Key_t -> - acc - | Var_t v -> v :: acc - | Option_t ty | List_t ty | Set_t ty -> vars ty acc - | Pair_t (lty, rty) | Union_t (lty, rty) -> vars lty (vars rty acc) - | Map_t (kty, vty) -> vars kty (vars vty acc) - | Lambda_t (dom, range) -> vars dom (vars range acc) - - let vars x = vars x [] -end - -module Stack = struct - type t = t_node Hashcons.hash_consed - - and t_node = Empty_t | Stack_var_t of int | Item_t of Base.t * t - - module Hashed = struct - type t = t_node - - let equal (t1 : t) (t2 : t) = - match (t1, t2) with - | (Empty_t, Empty_t) -> true - | (Stack_var_t v1, Stack_var_t v2) -> v1 = v2 - | (Item_t (h1, tl1), Item_t (h2, tl2)) -> h1 == h2 && tl1 == tl2 - | _ -> false - - let hash (t : t) = Hashtbl.hash t - end - - module Table = Hashcons.Make (Hashed) - - let table = Table.create 101 - - let rec pp fmtr x = - match x.Hashcons.node with - | Empty_t -> Format.pp_print_string fmtr "[]" - | Stack_var_t v -> Format.fprintf fmtr "<%d>" v - | Item_t (head, tail) -> Format.fprintf fmtr "%a :: %a" Base.pp head pp tail - - let rec vars x = - match x.Hashcons.node with - | Empty_t -> None - | Stack_var_t v -> Some v - | Item_t (_head, tail) -> vars tail -end - -let unit = Base.Table.hashcons Base.table Unit_t - -let var x = Base.Table.hashcons Base.table (Var_t x) - -let int = Base.Table.hashcons Base.table Int_t - -let nat = Base.Table.hashcons Base.table Nat_t - -let bool = Base.Table.hashcons Base.table Bool_t - -let string = Base.Table.hashcons Base.table String_t - -let bytes = Base.Table.hashcons Base.table Bytes_t - -let key_hash = Base.Table.hashcons Base.table Key_hash_t - -let timestamp = Base.Table.hashcons Base.table Timestamp_t - -let mutez = Base.Table.hashcons Base.table Mutez_t - -let key = Base.Table.hashcons Base.table Key_t - -let option ty = Base.Table.hashcons Base.table (Option_t ty) - -let pair lty rty = Base.Table.hashcons Base.table (Pair_t (lty, rty)) - -let union lty rty = Base.Table.hashcons Base.table (Union_t (lty, rty)) - -let list ty = Base.Table.hashcons Base.table (List_t ty) - -let set ty = Base.Table.hashcons Base.table (Set_t ty) - -let map kty vty = Base.Table.hashcons Base.table (Map_t (kty, vty)) - -let lambda dom range = Base.Table.hashcons Base.table (Lambda_t (dom, range)) - -(* Stack smart constructors *) -let empty = Stack.Table.hashcons Stack.table Empty_t - -let stack_var x = Stack.Table.hashcons Stack.table (Stack_var_t x) - -let item head tail = Stack.Table.hashcons Stack.table (Item_t (head, tail)) diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/type.mli b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/type.mli deleted file mode 100644 index 168ba97e4d21..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/type.mli +++ /dev/null @@ -1,111 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Michelson types, hash-consed. *) - -(** Base types *) -module Base : sig - type comparable_tag = Comparable | Maybe_not_comparable - - type t = t_node Hashcons.hash_consed - - and t_node = private - | Unit_t - | Var_t of int - | Int_t - | Nat_t - | Bool_t - | String_t - | Bytes_t - | Key_hash_t - | Timestamp_t - | Mutez_t - | Key_t - | Option_t of t - | Pair_t of t * t - | Union_t of t * t - | List_t of t - | Set_t of t - | Map_t of t * t - | Lambda_t of t * t - - val pp : Format.formatter -> t -> unit - - val vars : t -> int list -end - -(** Stack types *) -module Stack : sig - type t = t_node Hashcons.hash_consed - - and t_node = private Empty_t | Stack_var_t of int | Item_t of Base.t * t - - val pp : Format.formatter -> t -> unit - - val vars : t -> int option -end - -(** Smart constructors *) -val unit : Base.t - -val var : int -> Base.t - -val int : Base.t - -val nat : Base.t - -val bool : Base.t - -val string : Base.t - -val bytes : Base.t - -val key_hash : Base.t - -val timestamp : Base.t - -val mutez : Base.t - -val key : Base.t - -val option : Base.t -> Base.t - -val pair : Base.t -> Base.t -> Base.t - -val union : Base.t -> Base.t -> Base.t - -val list : Base.t -> Base.t - -val set : Base.t -> Base.t - -val map : Base.t -> Base.t -> Base.t - -val lambda : Base.t -> Base.t -> Base.t - -val empty : Stack.t - -val stack_var : int -> Stack.t - -val item : Base.t -> Stack.t -> Stack.t diff --git a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/uf.ml b/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/uf.ml deleted file mode 100644 index f14a166939a7..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/lib_benchmark_type_inference/uf.ml +++ /dev/null @@ -1,99 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* ------------------------------------------------------------------------- *) -(* Union find parameterized over a persistent store. *) - -module type S = sig - module M : Monads.State_sig - - type key = int - - val add : key -> unit M.t - - val find : key -> key M.t - - val union : key -> key -> key M.t - - val show : string M.t -end - -module UF : S = struct - type node = T of {rank : int} | Ptr of key - - and key = int - - module S = - Stores.Map - (Int_map) - (struct - type key = int - - type value = node - - let key_to_string = string_of_int - - let value_to_string (x : value) = - match x with - | T {rank} -> Printf.sprintf "[%d]" rank - | Ptr k -> Printf.sprintf "ptr(%d)" k - end) - - module M = Monads.Make_state_monad (S) - - let add (k : key) = - let open M in - set k (T {rank = 1}) - - let rec get_root (k : key) (acc : key list) = - let open M in - get k >>= function - | None -> - let msg = Printf.sprintf "UF.get_root: invalid key %d" k in - Stdlib.failwith msg - | Some (T {rank}) -> - let ptr_to_root = Ptr k in - iter_list (fun key -> set key ptr_to_root) acc >>= fun () -> - return (k, rank) - | Some (Ptr k') -> get_root k' (k :: acc) - - let find (k : key) = - let open M in - get_root k [] >>= fun (res, _) -> return res - - let union k1 k2 = - let open M in - get_root k1 [] >>= fun (k1, rank1) -> - get_root k2 [] >>= fun (k2, rank2) -> - if k1 = k2 then return k1 - else if rank1 < rank2 then set k1 (Ptr k2) >>= fun () -> return k2 - else if rank1 > rank2 then set k2 (Ptr k1) >>= fun () -> return k1 - else - let new_root = T {rank = rank1 + 1} in - set k2 (Ptr k1) >>= fun () -> - set k1 new_root >>= fun () -> return k1 - - let show s = (S.to_string s, s) -end diff --git a/src/proto_012_Psithaca/lib_benchmark/micheline_sampler.ml b/src/proto_012_Psithaca/lib_benchmark/micheline_sampler.ml deleted file mode 100644 index 1e4778f856f0..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/micheline_sampler.ml +++ /dev/null @@ -1,110 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Micheline sampling. *) - -type width_function = depth:int -> int Base_samplers.sampler - -(** [Base_samplers] specifies samplers for leaves, primitives and annotations. *) -module type Base_samplers = sig - (** The type of primitives. *) - type prim - - val sample_prim : prim Base_samplers.sampler - - val sample_annots : string list Base_samplers.sampler - - val sample_string : string Base_samplers.sampler - - val sample_bytes : Bytes.t Base_samplers.sampler - - val sample_z : Z.t Base_samplers.sampler - - val width_function : width_function -end - -module type S = sig - type prim - - val sample : (int, prim) Micheline.node Base_samplers.sampler -end - -type node_kind = Int_node | String_node | Bytes_node | Seq_node | Prim_node - -(* The distribution can be skewed towards non-leaf nodes by repeating their - relevant kind in the array below. *) -let all_kinds = [|Int_node; String_node; Bytes_node; Seq_node; Prim_node|] - -let sample_kind : node_kind Base_samplers.sampler = - fun rng_state -> - let i = Random.State.int rng_state (Array.length all_kinds) in - all_kinds.(i) - -let reasonable_width_function ~depth rng_state = - (* Entirely ad-hoc *) - Base_samplers.( - sample_in_interval - ~range:{min = 0; max = 20 / (Bits.numbits depth + 1)} - rng_state) - -module Make (P : Base_samplers) : S with type prim = P.prim = struct - type prim = P.prim - - let sample (w : width_function) rng_state = - let rec sample depth rng_state k = - match sample_kind rng_state with - | Int_node -> k (Micheline.Int (0, P.sample_z rng_state)) - | String_node -> k (Micheline.String (0, P.sample_string rng_state)) - | Bytes_node -> k (Micheline.Bytes (0, P.sample_bytes rng_state)) - | Seq_node -> - let width = w ~depth rng_state in - sample_list - depth - width - [] - (fun terms -> k (Micheline.Seq (0, terms))) - rng_state - | Prim_node -> - let prim = P.sample_prim rng_state in - let annots = P.sample_annots rng_state in - let width = w ~depth rng_state in - sample_list - depth - width - [] - (fun terms -> k (Micheline.Prim (0, prim, terms, annots))) - rng_state - and sample_list depth width acc k rng_state = - if width < 0 then invalid_arg "sample_list: negative width" - else if width = 0 then k (List.rev acc) - else - sample (depth + 1) rng_state (fun x -> - sample_list depth (width - 1) (x :: acc) k rng_state) - in - sample 0 rng_state (fun x -> x) - - let sample rng_state = sample P.width_function rng_state -end diff --git a/src/proto_012_Psithaca/lib_benchmark/micheline_sampler.mli b/src/proto_012_Psithaca/lib_benchmark/micheline_sampler.mli deleted file mode 100644 index 97e3d4ec1e12..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/micheline_sampler.mli +++ /dev/null @@ -1,70 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Micheline sampling. *) - -(** A [width_function] specifies the distribution of node degree as a function - of [depth]. A [width_function] {e must} be supported by the nonnegative - integers. - - Note that picking a [width_function] which doesn't converge fast enough to - the singular distribution on 0 could yield very large terms. *) -type width_function = depth:int -> int Base_samplers.sampler - -(** [reasonable_width_function] is a width function which works well - empirically. *) -val reasonable_width_function : width_function - -(** [Base_samplers] specifies samplers for leaves, primitives and annotations. *) -module type Base_samplers = sig - (** The type of primitives. *) - type prim - - val sample_prim : prim Base_samplers.sampler - - val sample_annots : string list Base_samplers.sampler - - val sample_string : string Base_samplers.sampler - - val sample_bytes : Bytes.t Base_samplers.sampler - - val sample_z : Z.t Base_samplers.sampler - - val width_function : width_function -end - -(** Applying the [Make] functor below yields a module with the following - type. *) -module type S = sig - type prim - - (** [sample w] is a Micheline sampler for the prescribed primitive - type. The sampler uses the provided width function [w]. *) - val sample : (int, prim) Micheline.node Base_samplers.sampler -end - -(** [Make] instantiates a micheline sampler. *) -module Make (P : Base_samplers) : S with type prim = P.prim diff --git a/src/proto_012_Psithaca/lib_benchmark/michelson_mcmc_samplers.ml b/src/proto_012_Psithaca/lib_benchmark/michelson_mcmc_samplers.ml deleted file mode 100644 index d8064150cb34..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/michelson_mcmc_samplers.ml +++ /dev/null @@ -1,337 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** MCMC-based Michelson data and code samplers. *) - -open Protocol -open Stats - -type michelson_code = { - term : Script_repr.expr; - bef : Script_repr.expr list; - aft : Script_repr.expr list; -} - -type michelson_data = {term : Script_repr.expr; typ : Script_repr.expr} - -type michelson_sample = Code of michelson_code | Data of michelson_data - -let michelson_sample_list_encoding = - let open Data_encoding in - let e = Script_repr.expr_encoding in - list - @@ union - [ - case - ~title:"Code" - (Tag 0) - (tup3 e (list e) (list e)) - (function - | Code {term; bef; aft} -> Some (term, bef, aft) | _ -> None) - (fun (term, bef, aft) -> Code {term; bef; aft}); - case - ~title:"Data" - (Tag 1) - (tup2 e e) - (function Data {term; typ} -> Some (term, typ) | _ -> None) - (fun (term, typ) -> Data {term; typ}); - ] - -let save ~filename ~terms = - let str = - match - Data_encoding.Binary.to_string michelson_sample_list_encoding terms - with - | Error err -> - Format.eprintf - "Michelson_mcmc_samplers.save: encoding failed (%a); exiting" - Data_encoding.Binary.pp_write_error - err ; - exit 1 - | Ok res -> res - in - try Lwt_main.run @@ Tezos_stdlib_unix.Lwt_utils_unix.create_file filename str - with exn -> - Format.eprintf - "Michelson_mcmc_samplers.save: create_file failed (%s); exiting" - (Printexc.to_string exn) ; - exit 1 - -let load ~filename = - let open TzPervasives in - let string = - try Lwt_main.run @@ Tezos_stdlib_unix.Lwt_utils_unix.read_file filename - with exn -> - Format.eprintf - "Michelson_mcmc_samplers.load: read_file failed (%s); exiting" - (Printexc.to_string exn) ; - exit 1 - in - let bytes = Bytes.of_string string in - match Data_encoding.Binary.of_bytes michelson_sample_list_encoding bytes with - | Ok result -> result - | Error err -> - Format.eprintf - "Michelson_mcmc_samplers.load: decoding failed (%a); exiting" - Data_encoding.Binary.pp_read_error - err ; - exit 1 - -(* Helpers *) - -let base_type_to_michelson_type (typ : Type.Base.t) = - let typ = Mikhailsky.map_var (fun _ -> Mikhailsky.unit_ty) typ in - Mikhailsky.to_michelson typ - -module type Sampler_parameters_sig = sig - val initial : State_space.t - - val energy : State_space.t -> float - - val rules : Rules.rule_set list - - val infer : Mikhailsky.node -> Inference.state - - val verbosity : [`Silent | `Progress | `Trace] -end - -(* The Markov chain in state [state] *) -type mc_state = { - state : State_space.t; - jump : State_space.t Fin.Float.prb Lazy.t; -} - -module State_multiset = - Basic_structures.Basic_impl.Free_module.Float_valued.Make_with_map - (State_space) - -(** Generic MCMC michelson sampler (can be used for code and data) *) -module Make_generic (P : Sampler_parameters_sig) = struct - let uniform (l : State_space.t list) : State_space.t Fin.Float.prb = - match l with - | [] -> - (* This can only happen is the MCMC was driven to a coffin state, - which means that it's not reversible (this is a bug) *) - assert false - | _ -> - let arr = Array.of_list l in - let emp = Emp.of_raw_data arr in - Fin.Float.counts_of_empirical (module State_multiset) emp - |> Fin.Float.normalize - - let unrecoverable_failure err current result = - Format.eprintf "Error when typechecking term:@." ; - Format.eprintf "%a@." Inference.pp_inference_error err ; - Format.eprintf "Original state: @[%a@]@." State_space.pp current ; - Format.eprintf "Erroneous term: %a@." Mikhailsky.pp result ; - Stdlib.failwith "in sampler.ml: unrecoverable failure." - - let of_state : State_space.t -> mc_state = - fun state -> - { - state; - jump = - Lazy.from_fun (fun () -> - let current = state in - let rewriting_options = Rules.rewriting current P.rules in - let term = current.term in - let rewritings = - List.fold_left - (fun rewritings (path, replacement) -> - let result = Kernel.Rewriter.subst ~term ~path ~replacement in - let typing = - Lazy.from_fun (fun () -> - try P.infer result - with Inference.Ill_typed_script err -> - unrecoverable_failure err current result) - in - {State_space.typing; term = result} :: rewritings) - [] - rewriting_options - in - uniform rewritings); - } - - module MH_params : Mh.MH_parameters with type t = mc_state = struct - type t = mc_state - - let pp fmtr {state; jump = _} = State_space.pp fmtr state - - let trace state = - match P.verbosity with - | `Silent | `Progress -> () - | `Trace -> - Format.eprintf "@." ; - Format.eprintf "%a" State_space.pp state ; - Format.eprintf "energy:@." ; - Format.eprintf "%f:@." (P.energy state) - - let proposal_log_density s1 s2 = - let jump = Lazy.force s1.jump in - Log_space.of_float (Fin.Float.eval_prb jump s2.state) - - let proposal mcmc_state rng_state = - trace mcmc_state.state ; - let dist = Lazy.force mcmc_state.jump in - let next = Fin.Float.sample (Fin.as_measure dist) rng_state in - of_state next - - let log_weight state = Log_space.unsafe_cast (-.P.energy state.state) - end - - module Sampler = Mh.Make (MH_params) - - let generator ~burn_in = - P.(Sampler.mcmc ~verbosity ~initial:(of_state initial) ~burn_in) -end - -module Make_code_sampler - (Michelson_base : Michelson_samplers_base.S) - (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) (X : sig - val rng_state : Random.State.t - - val target_size : int - - val verbosity : [`Silent | `Progress | `Trace] - end) = -struct - module Autocomp = Autocomp.Make (Michelson_base) (Crypto_samplers) - - module MCMC = Make_generic (struct - let initial = - let term = Mikhailsky.Instructions.hole in - let typing = Lazy.from_val @@ snd (Inference.infer_with_state term) in - {State_space.term; typing} - - let energy state = - let stats = State_space.statistics state in - let size_deficit = - abs_float - (float_of_int X.target_size -. float_of_int stats.State_space.size) - in - let holes_proportion = float stats.holes /. float stats.size in - let holes_deficit = - (* we want at least 1% of holes, above is ok *) - if holes_proportion < 0.01 then - (0.01 -. holes_proportion) *. size_deficit - else 0.0 - in - size_deficit +. holes_deficit - - let rules = Rules.Instruction.rules - - let infer term = snd (Inference.infer_with_state term) - - let verbosity = X.verbosity - end) - - let to_michelson {state = ({typing; term} : State_space.t); jump = _} = - let typing = Lazy.force typing in - let (node, (bef, aft), state) = - Autocomp.complete_code typing term X.rng_state - in - let node = - Micheline.strip_locations @@ Mikhailsky_to_michelson.convert node state - in - { - term = node; - bef = Type_helpers.stack_type_to_michelson_type_list bef; - aft = Type_helpers.stack_type_to_michelson_type_list aft; - } - - let generator ~burn_in = - Gen.map (MCMC.generator ~burn_in) @@ fun after_burn_in -> - Gen.map after_burn_in to_michelson -end - -module Make_data_sampler - (Michelson_base : Michelson_samplers_base.S) - (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) (X : sig - val rng_state : Random.State.t - - val target_size : int - - val verbosity : [`Silent | `Progress | `Trace] - end) = -struct - module Autocomp = Autocomp.Make (Michelson_base) (Crypto_samplers) - module Rewrite_rules = - Rules.Data_rewrite_leaves (Michelson_base) (Crypto_samplers) - - module MCMC = Make_generic (struct - let initial = - let term = Mikhailsky.Data.hole in - let typing = - Lazy.from_val @@ snd (Inference.infer_data_with_state term) - in - {State_space.term; typing} - - let energy state = - let stats = State_space.statistics state in - let size_deficit = - abs_float - (float_of_int X.target_size -. float_of_int stats.State_space.size) - in - let holes_proportion = - float_of_int stats.holes /. float_of_int stats.size - in - let holes_deficit = - (* we want at least 10% of holes, above is ok *) - if holes_proportion < 0.5 then (0.5 -. holes_proportion) *. size_deficit - else 0.0 - in - let depth_deficit = - abs_float - ((0.1 *. float_of_int X.target_size) -. float_of_int stats.depth) - in - size_deficit +. holes_deficit +. depth_deficit - - let rules = Rewrite_rules.rules X.rng_state - - let infer term = snd (Inference.infer_data_with_state term) - - let verbosity = X.verbosity - end) - - let to_michelson {state = ({typing; term} : State_space.t); jump = _} = - let typing = Lazy.force typing in - let (node, _) = Autocomp.complete_data typing term X.rng_state in - let (typ, state) = - try Inference.infer_data_with_state node - with _ -> - Format.eprintf "Bug found!@." ; - Format.eprintf "Ill-typed autocompletion. Resulting term:@." ; - Format.eprintf "%a@." Mikhailsky.pp node ; - Stdlib.failwith "in generators.ml: unrecoverable failure" - in - let node = - Micheline.strip_locations @@ Mikhailsky_to_michelson.convert node state - in - {term = node; typ = base_type_to_michelson_type typ} - - let generator ~burn_in = - Gen.map (MCMC.generator ~burn_in) @@ fun after_burn_in -> - Gen.map after_burn_in to_michelson -end diff --git a/src/proto_012_Psithaca/lib_benchmark/michelson_mcmc_samplers.mli b/src/proto_012_Psithaca/lib_benchmark/michelson_mcmc_samplers.mli deleted file mode 100644 index bd67d13e3c16..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/michelson_mcmc_samplers.mli +++ /dev/null @@ -1,115 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** MCMC-based Michelson data and code samplers. *) - -open Protocol - -(** MCMC samplers can either produce data or code. Note that the samplers - natively produce data and code in Micheline (ie untyped) form. *) - -type michelson_code = { - term : Script_repr.expr; - (** [term] is a typeable Michelson program in Micheline form. *) - bef : Script_repr.expr list; - (** [bef] is an input stack type for which [term] is a well-typed script. *) - aft : Script_repr.expr list; - (** [aft] is the stack type corresponding to the execution of [term] - on a stack of type [bef]. *) -} - -type michelson_data = { - term : Script_repr.expr; - (** [term] is a typeable Michelson data in Micheline form. *) - typ : Script_repr.expr; (** [typ] is the type of [term]. *) -} - -(** A [michelson_sample] is either a code sample or a data sample. *) -type michelson_sample = Code of michelson_code | Data of michelson_data - -(** Encoding used for saving or loading data. *) -val michelson_sample_list_encoding : michelson_sample list Data_encoding.t - -(** Saving a list of samples to a file. - Exits with code 1 if an error arises during encoding or file manipulation. *) -val save : filename:string -> terms:michelson_sample list -> unit - -(** Loading a list of samples from a file. - Exits with code 1 if an error arises during decoding or file manipulation. *) -val load : filename:string -> michelson_sample list - -(** [Make_code_sampler] produces a sampler for well-typed Michelson code. - The parameters of the functor are: - - a module [Michelson_base] implementing samplers for basic values - - a module [Crypto_samplers] implementing samplers for pk/pkh/sk triplets - - a module [X] containing some parameters to the Markov chain sampler: - - [rng_state] is the mutable state that will be used during sampling - - [target_size] specifies the size, in terms of Micheline nodes, of the - terms that the sampler should try to produce - - [verbosity] specifies how much information should be written on stdout - during the sampling process. - - The outcome is a [michelson_code] [generator]. The [burn_in] parameter - specifies how much samples should be thrown away before starting to - produce sample (this is used to let the underlying Markov chain reach - its stationary distribution - the value should be commensurate with - the [target_size]. - *) -module Make_code_sampler : functor - (Michelson_base : Michelson_samplers_base.S) - (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) - (X : sig - val rng_state : Random.State.t - - val target_size : int - - val verbosity : [`Progress | `Silent | `Trace] - end) - -> sig - (** [generator ~burn_in rng_state] performs a burn-in phase consisting of sampling [burn_in] times, - throwing the results away and returns a michelson term sampler. The goal of burn-in is - to drive the underlying Markov chain to its stationary distribution, ie to sample - terms around the specified [X.target_size]. *) - val generator : burn_in:int -> Random.State.t -> michelson_code Stats.Gen.t -end - -(** See documentation for [Make_code_sampler] *) -module Make_data_sampler : functor - (Michelson_base : Michelson_samplers_base.S) - (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) - (X : sig - val rng_state : Random.State.t - - val target_size : int - - val verbosity : [`Progress | `Silent | `Trace] - end) - -> sig - (** [generator ~burn_in rng_state] performs a burn-in phase consisting of sampling [burn_in] times, - throwing the results away and returns a michelson term sampler. The goal of burn-in is - to drive the underlying Markov chain to its stationary distribution, ie to sample - terms around the specified [X.target_size]. *) - val generator : burn_in:int -> Random.State.t -> michelson_data Stats.Gen.t -end diff --git a/src/proto_012_Psithaca/lib_benchmark/michelson_samplers.ml b/src/proto_012_Psithaca/lib_benchmark/michelson_samplers.ml deleted file mode 100644 index 16014d6df65a..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/michelson_samplers.ml +++ /dev/null @@ -1,727 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Script_typed_ir - -type parameters = { - base_parameters : Michelson_samplers_base.parameters; - list_size : Base_samplers.range; - set_size : Base_samplers.range; - map_size : Base_samplers.range; -} - -let parameters_encoding = - let open Data_encoding in - let range_encoding = Base_samplers.range_encoding in - conv - (fun {base_parameters; list_size; set_size; map_size} -> - (base_parameters, (list_size, set_size, map_size))) - (fun (base_parameters, (list_size, set_size, map_size)) -> - {base_parameters; list_size; set_size; map_size}) - (merge_objs - Michelson_samplers_base.parameters_encoding - (obj3 - (req "list_size" range_encoding) - (req "set_size" range_encoding) - (req "map_size" range_encoding))) - -(* ------------------------------------------------------------------------- *) -(* Helpers. *) - -let comparable_downcast = Script_ir_translator.ty_of_comparable_ty - -(* ------------------------------------------------------------------------- *) -(* Type names. *) - -(* We only want to generated inhabited types, hence Never is not included. *) - -type type_name = - [ `TUnit - | `TInt - | `TNat - | `TSignature - | `TString - | `TBytes - | `TMutez - | `TKey_hash - | `TKey - | `TTimestamp - | `TAddress - | `TBool - | `TPair - | `TUnion - | `TLambda - | `TOption - | `TList - | `TSet - | `TMap - | `TBig_map - | `TContract - | `TSapling_transaction - | `TSapling_state - | `TOperation - | `TChain_id - | `TBls12_381_g1 - | `TBls12_381_g2 - | `TBls12_381_fr - | `TTicket ] - -type atomic_type_name = - [ `TUnit - | `TInt - | `TNat - | `TSignature - | `TString - | `TBytes - | `TMutez - | `TKey_hash - | `TKey - | `TTimestamp - | `TAddress - | `TBool - | `TSapling_transaction - | `TSapling_state - | `TChain_id - | `TBls12_381_g1 - | `TBls12_381_g2 - | `TBls12_381_fr ] - -type non_atomic_type_name = - [ `TPair - | `TUnion - | `TLambda - | `TOption - | `TList - | `TSet - | `TMap - | `TBig_map - | `TContract - | `TTicket ] - -(* Ensure inclusion of atomic_type_name in type_name *) -let (_ : atomic_type_name -> type_name) = fun x -> (x :> type_name) - -(* Ensure inclusion of non_atomic_type_name in type_name *) -let (_ : non_atomic_type_name -> type_name) = fun x -> (x :> type_name) - -let all_atomic_type_names : atomic_type_name array = - [| - `TUnit; - `TInt; - `TNat; - `TSignature; - `TString; - `TBytes; - `TMutez; - `TKey_hash; - `TKey; - `TTimestamp; - `TAddress; - `TBool; - `TSapling_transaction; - `TSapling_state; - `TChain_id; - `TBls12_381_g1; - `TBls12_381_g2; - `TBls12_381_fr; - |] - -let all_non_atomic_type_names : non_atomic_type_name array = - [| - `TPair; - `TUnion; - `TLambda; - `TOption; - `TList; - `TSet; - `TMap; - `TBig_map; - `TContract; - `TTicket; - |] - -type comparable_type_name = - [ `TUnit - | `TInt - | `TNat - | `TSignature - | `TString - | `TBytes - | `TMutez - | `TBool - | `TKey_hash - | `TKey - | `TTimestamp - | `TChain_id - | `TAddress - | `TPair - | `TUnion - | `TOption ] - -(* Ensure inclusion of comparable_type_name in type_name *) -let (_ : comparable_type_name -> type_name) = fun x -> (x :> type_name) - -type 'a comparable_and_atomic = 'a - constraint 'a = [< comparable_type_name] constraint 'a = [< atomic_type_name] - -let all_comparable_atomic_type_names : 'a comparable_and_atomic array = - [| - `TUnit; - `TInt; - `TNat; - `TSignature; - `TString; - `TBytes; - `TMutez; - `TBool; - `TKey_hash; - `TKey; - `TTimestamp; - `TChain_id; - `TAddress; - |] - -type 'a comparable_and_non_atomic = 'a - constraint 'a = [< comparable_type_name] - constraint 'a = [< non_atomic_type_name] - -let all_comparable_non_atomic_type_names : 'a comparable_and_non_atomic array = - [|`TPair; `TUnion; `TOption|] - -(* Ensure inclusion of comparable_and_atomic in type_name *) -let (_ : 'a comparable_and_atomic -> type_name) = fun x -> (x :> type_name) - -(* ------------------------------------------------------------------------- *) -(* Uniform type name generators *) - -open Sampling_helpers - -let uniform : 'a array -> 'a sampler = - fun arr rng_state -> - let i = Random.State.int rng_state (Array.length arr) in - arr.(i) - -let uniform_atomic_type_name : atomic_type_name sampler = - uniform all_atomic_type_names - -let uniform_comparable_atomic_type_name : 'a comparable_and_atomic sampler = - uniform all_comparable_atomic_type_names - -let uniform_comparable_non_atomic_type_name : - 'a comparable_and_non_atomic sampler = - uniform all_comparable_non_atomic_type_names - -(* ------------------------------------------------------------------------- *) -(* Random generation functor. *) - -module type S = sig - module Michelson_base : Michelson_samplers_base.S - - module Random_type : sig - val m_type : size:int -> Script_ir_translator.ex_ty sampler - - val m_comparable_type : - size:int -> Script_ir_translator.ex_comparable_ty sampler - end - - module rec Random_value : sig - val value : 'a Script_typed_ir.ty -> 'a sampler - - val comparable : 'a Script_typed_ir.comparable_ty -> 'a sampler - - val stack : ('a, 'b) Script_typed_ir.stack_ty -> ('a * 'b) sampler - end -end - -exception SamplingError of string - -let fail_sampling error = raise (SamplingError error) - -module Make (P : sig - val parameters : parameters -end) -(Crypto_samplers : Crypto_samplers.Finite_key_pool_S) : S = struct - module Michelson_base = Michelson_samplers_base.Make (struct - let parameters = P.parameters.base_parameters - end) - - let memo_size = - Alpha_context.Sapling.Memo_size.parse_z Z.zero |> Result.get_ok - - (* [pick_split x] randomly splits the integer [x] into two integers [left] - and [right] such that [1 <= left], [1 <= right], and [left + right = x]. - Expects [x >= 2]. *) - let pick_split : int -> (int * int) sampler = - fun x rng_state -> - if x < 2 then invalid_arg "pick_split" - else - (* x >= 2 *) - let left = 1 + Random.State.int rng_state (x - 1) in - let right = x - left in - assert (left + right = x) ; - (left, right) - - (* Random generation of Michelson types. *) - module Random_type = struct - let type_of_atomic_type_name (at_tn : atomic_type_name) : - Script_ir_translator.ex_ty = - match at_tn with - | `TString -> Ex_ty (string_t ~annot:None) - | `TNat -> Ex_ty (nat_t ~annot:None) - | `TKey -> Ex_ty (key_t ~annot:None) - | `TBytes -> Ex_ty (bytes_t ~annot:None) - | `TBool -> Ex_ty (bool_t ~annot:None) - | `TAddress -> Ex_ty (address_t ~annot:None) - | `TTimestamp -> Ex_ty (timestamp_t ~annot:None) - | `TKey_hash -> Ex_ty (key_hash_t ~annot:None) - | `TMutez -> Ex_ty (mutez_t ~annot:None) - | `TSignature -> Ex_ty (signature_t ~annot:None) - | `TUnit -> Ex_ty (unit_t ~annot:None) - | `TInt -> Ex_ty (int_t ~annot:None) - | `TSapling_state -> Ex_ty (sapling_state_t ~memo_size ~annot:None) - | `TSapling_transaction -> - Ex_ty (sapling_transaction_t ~memo_size ~annot:None) - | `TChain_id -> Ex_ty (chain_id_t ~annot:None) - | `TBls12_381_g1 -> Ex_ty (bls12_381_g1_t ~annot:None) - | `TBls12_381_g2 -> Ex_ty (bls12_381_g2_t ~annot:None) - | `TBls12_381_fr -> Ex_ty (bls12_381_fr_t ~annot:None) - - let comparable_type_of_comparable_atomic_type_name - (cmp_tn : 'a comparable_and_atomic) : - Script_ir_translator.ex_comparable_ty = - match cmp_tn with - | `TString -> Ex_comparable_ty (string_key ~annot:None) - | `TNat -> Ex_comparable_ty (nat_key ~annot:None) - | `TBytes -> Ex_comparable_ty (bytes_key ~annot:None) - | `TBool -> Ex_comparable_ty (bool_key ~annot:None) - | `TAddress -> Ex_comparable_ty (address_key ~annot:None) - | `TTimestamp -> Ex_comparable_ty (timestamp_key ~annot:None) - | `TKey_hash -> Ex_comparable_ty (key_hash_key ~annot:None) - | `TMutez -> Ex_comparable_ty (mutez_key ~annot:None) - | `TInt -> Ex_comparable_ty (int_key ~annot:None) - | `TUnit -> Ex_comparable_ty (unit_key ~annot:None) - | `TSignature -> Ex_comparable_ty (signature_key ~annot:None) - | `TKey -> Ex_comparable_ty (key_key ~annot:None) - | `TChain_id -> Ex_comparable_ty (chain_id_key ~annot:None) - - let rec m_type ~size : Script_ir_translator.ex_ty sampler = - let open Script_ir_translator in - let open M in - if size <= 0 then Stdlib.failwith "m_type: size <= 0" - else if size = 1 then - (* only atomic types can have size 1 *) - let* at_tn = uniform_atomic_type_name in - return (type_of_atomic_type_name at_tn) - else if size = 2 then - bind (uniform [|`TOption; `TList; `TSet; `TTicket; `TContract|]) - @@ function - | `TOption -> ( - let* (Ex_ty t) = m_type ~size:1 in - match option_t (-1) t ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TList -> ( - let* (Ex_ty t) = m_type ~size:1 in - match list_t (-1) t ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TSet -> ( - let* (Ex_comparable_ty t) = m_comparable_type ~size:1 in - match set_t (-1) t ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TTicket -> ( - let* (Ex_comparable_ty contents) = m_comparable_type ~size:1 in - match ticket_t (-1) contents ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TContract -> ( - let* (Ex_ty t) = m_type ~size:1 in - match contract_t (-1) t ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - else - bind (uniform all_non_atomic_type_names) @@ function - | `TPair -> ( - let* (lsize, rsize) = pick_split (size - 1) in - let* (Ex_ty left) = m_type ~size:lsize in - let* (Ex_ty right) = m_type ~size:rsize in - match - pair_t (-1) (left, None, None) (right, None, None) ~annot:None - with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TLambda -> ( - let* (lsize, rsize) = pick_split (size - 1) in - let* (Ex_ty domain) = m_type ~size:lsize in - let* (Ex_ty range) = m_type ~size:rsize in - match lambda_t (-1) domain range ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TUnion -> ( - let* (lsize, rsize) = pick_split (size - 1) in - let* (Ex_ty left) = m_type ~size:lsize in - let* (Ex_ty right) = m_type ~size:rsize in - match union_t (-1) (left, None) (right, None) ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TOption -> ( - let* (Ex_ty t) = m_type ~size:(size - 1) in - match option_t (-1) t ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TMap -> ( - let* (lsize, rsize) = pick_split (size - 1) in - let* (Ex_comparable_ty key) = m_comparable_type ~size:lsize in - let* (Ex_ty elt) = m_type ~size:rsize in - match map_t (-1) key elt ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TSet -> ( - let* (Ex_comparable_ty key_ty) = - m_comparable_type ~size:(size - 1) - in - match set_t (-1) key_ty ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TList -> ( - let* (Ex_ty elt) = m_type ~size:(size - 1) in - match list_t (-1) elt ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TTicket -> ( - let* (Ex_comparable_ty contents) = - m_comparable_type ~size:(size - 1) - in - match ticket_t (-1) contents ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TContract -> ( - let* (Ex_ty t) = m_type ~size:(size - 1) in - match contract_t (-1) t ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_ty res_ty) - | `TBig_map -> - (* Don't know what to do with theses. Redraw. *) - m_type ~size - - and m_comparable_type ~size : Script_ir_translator.ex_comparable_ty sampler - = - let open M in - let open Script_ir_translator in - let atomic_case () = - let* at_tn = uniform_comparable_atomic_type_name in - return (comparable_type_of_comparable_atomic_type_name at_tn) - in - let option_case size = - let size = size - 1 in - let* (Ex_comparable_ty t) = m_comparable_type ~size in - match option_key (-1) t ~annot:None with - | Error _ -> (* what should be done here? *) assert false - | Ok res_ty -> return @@ Ex_comparable_ty res_ty - in - let pair_case size = - let size = size - 1 in - let* size_left = - Base_samplers.sample_in_interval ~range:{min = 1; max = size - 1} - in - let size_right = size - size_left in - let* (Ex_comparable_ty l) = m_comparable_type ~size:size_left in - let* (Ex_comparable_ty r) = m_comparable_type ~size:size_right in - match pair_key (-1) (l, None) (r, None) ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_comparable_ty res_ty - in - let union_case size = - let size = size - 1 in - let* size_left = - Base_samplers.sample_in_interval ~range:{min = 1; max = size - 1} - in - let size_right = size - size_left in - let* (Ex_comparable_ty l) = m_comparable_type ~size:size_left in - let* (Ex_comparable_ty r) = m_comparable_type ~size:size_right in - match union_key (-1) (l, None) (r, None) ~annot:None with - | Error _ -> assert false - | Ok res_ty -> return @@ Ex_comparable_ty res_ty - in - - if size <= 1 then atomic_case () - else if size = 2 then option_case size - else - let* cmp_tn = uniform_comparable_non_atomic_type_name in - match cmp_tn with - | `TPair -> pair_case size - | `TUnion -> union_case size - | `TOption -> option_case size - end - - (* Type-directed generation of random values. *) - module rec Random_value : sig - val value : 'a Script_typed_ir.ty -> 'a sampler - - val comparable : 'a Script_typed_ir.comparable_ty -> 'a sampler - - val stack : ('a, 'b) Script_typed_ir.stack_ty -> ('a * 'b) sampler - end = struct - let address rng_state = - if Base_samplers.uniform_bool rng_state then - ( Alpha_context.Contract.implicit_contract - (Crypto_samplers.pkh rng_state), - "default" ) - else - (* For a description of the format, see - tezos-codec describe alpha.contract binary encoding *) - let string = - "\001" ^ Base_samplers.uniform_string ~nbytes:20 rng_state ^ "\000" - in - let contract = - Data_encoding.Binary.of_string_exn - Alpha_context.Contract.encoding - string - in - let ep = Base_samplers.string ~size:{min = 1; max = 31} rng_state in - (contract, ep) - - let chain_id rng_state = - let string = Base_samplers.uniform_string ~nbytes:4 rng_state in - Data_encoding.Binary.of_string_exn Chain_id.encoding string - - let rec value : type a. a Script_typed_ir.ty -> a sampler = - let open Script_typed_ir in - fun typ -> - match typ with - | Never_t _ -> assert false - | Unit_t _ -> M.return () - | Int_t _ -> Michelson_base.int - | Nat_t _ -> Michelson_base.nat - | Signature_t _ -> Michelson_base.signature - | String_t _ -> Michelson_base.string - | Bytes_t _ -> Michelson_base.bytes - | Mutez_t _ -> Michelson_base.tez - | Key_hash_t _ -> Crypto_samplers.pkh - | Key_t _ -> Crypto_samplers.pk - | Timestamp_t _ -> Michelson_base.timestamp - | Bool_t _ -> Base_samplers.uniform_bool - | Address_t _ -> address - | Pair_t ((left_t, _, _), (right_t, _, _), _) -> - M.( - let* left_v = value left_t in - let* right_v = value right_t in - return (left_v, right_v)) - | Union_t ((left_t, _), (right_t, _), _) -> - fun rng_state -> - if Base_samplers.uniform_bool rng_state then - L (value left_t rng_state) - else R (value right_t rng_state) - | Lambda_t (arg_ty, ret_ty, _) -> generate_lambda arg_ty ret_ty - | Option_t (ty, _) -> - fun rng_state -> - if Base_samplers.uniform_bool rng_state then None - else Some (value ty rng_state) - | List_t (elt_ty, _) -> generate_list elt_ty - | Set_t (elt_ty, _) -> generate_set elt_ty - | Map_t (key_ty, val_ty, _) -> generate_map key_ty val_ty - | Contract_t (arg_ty, _) -> generate_contract arg_ty - | Operation_t _ -> generate_operation - | Big_map_t (key_ty, val_ty, _) -> generate_big_map key_ty val_ty - | Chain_id_t _ -> chain_id - | Bls12_381_g1_t _ -> generate_bls12_381_g1 - | Bls12_381_g2_t _ -> generate_bls12_381_g2 - | Bls12_381_fr_t _ -> generate_bls12_381_fr - | Ticket_t (contents_ty, _) -> - let ty = comparable_downcast contents_ty in - generate_ticket ty - | Sapling_transaction_t _ -> - fail_sampling - "Michelson_samplers: sapling transactions not handled yet" - | Sapling_state_t _ -> - fail_sampling "Michelson_samplers: sapling state not handled yet" - | Chest_key_t _ -> - fail_sampling "Michelson_samplers: chest key not handled yet" - | Chest_t _ -> fail_sampling "Michelson_samplers: chest not handled yet" - - and generate_lambda : - type arg ret. - arg Script_typed_ir.ty -> - ret Script_typed_ir.ty -> - (arg, ret) Script_typed_ir.lambda sampler = - fun _arg_ty _ret_ty _rng_state -> - fail_sampling "Michelson_samplers: lambda not handled yet" - - and generate_list : - type elt. - elt Script_typed_ir.ty -> elt Script_typed_ir.boxed_list sampler = - fun elt_type -> - let open M in - let* (length, elements) = - Structure_samplers.list - ~range:P.parameters.list_size - ~sampler:(value elt_type) - in - return Script_typed_ir.{elements; length} - - (* Note that we might very well generate sets smaller than the specified range (consider the - case of a set of type [unit]). *) - and generate_set : - type elt. - elt Script_typed_ir.comparable_ty -> elt Script_typed_ir.set sampler = - fun elt_ty -> - let open M in - let ety = comparable_downcast elt_ty in - let* (_, elements) = - Structure_samplers.list - ~range:P.parameters.set_size - ~sampler:(value ety) - in - return - @@ List.fold_left - (fun set x -> Script_set.update x true set) - (Script_set.empty elt_ty) - elements - - and generate_map : - type key elt. - key Script_typed_ir.comparable_ty -> - elt Script_typed_ir.ty -> - (key, elt) Script_typed_ir.map sampler = - fun key_ty elt_ty rng_state -> - let size = - Base_samplers.sample_in_interval rng_state ~range:P.parameters.map_size - in - let kty = comparable_downcast key_ty in - let keys = List.init size (fun _ -> value kty rng_state) in - let elts = List.init size (fun _ -> value elt_ty rng_state) in - List.fold_left2 - (fun map key elt -> Script_map.update key (Some elt) map) - (Script_map.empty key_ty) - keys - elts - - and generate_big_map : - type key elt. - key Script_typed_ir.comparable_ty -> - elt Script_typed_ir.ty -> - (key, elt) Script_typed_ir.big_map sampler = - let open Script_typed_ir in - fun key_ty elt_ty rng_state -> - let open TzPervasives in - let result = - Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - let big_map = Script_ir_translator.empty_big_map key_ty elt_ty in - (* Cannot have big maps under big maps *) - option_t (-1) elt_ty ~annot:None |> Environment.wrap_tzresult - >>?= fun opt_elt_ty -> - let map = generate_map key_ty opt_elt_ty rng_state in - Script_map.fold - (fun k v acc -> - acc >>=? fun (bm, ctxt_acc) -> - Script_ir_translator.big_map_update ctxt_acc k v bm) - map - (return (big_map, ctxt)) - >|= Environment.wrap_tzresult - >>=? fun (big_map, _) -> return big_map ) - in - match result with - | Ok x -> x - | Error e -> - Format.eprintf - "%a@." - (Error_monad.TzTrace.pp_print Error_monad.pp) - e ; - fail_sampling "raise_if_error" - - and generate_contract : - type arg. - arg Script_typed_ir.ty -> arg Script_typed_ir.typed_contract sampler = - fun arg_ty -> - let open M in - let* addr = value (address_t ~annot:None) in - return (arg_ty, addr) - - and generate_operation : - (Alpha_context.packed_internal_operation - * Alpha_context.Lazy_storage.diffs option) - sampler = - fun rng_state -> - let transfer = generate_transfer_tokens rng_state in - (transfer, None) - - and generate_transfer_tokens : - Alpha_context.packed_internal_operation sampler = - fun _rng_state -> fail_sampling "generate_transfer_tokens: unimplemented" - - and generate_bls12_381_g1 : Environment.Bls12_381.G1.t sampler = - fun rng_state -> - let b = Bls12_381.G1.(to_bytes (random ~state:rng_state ())) in - match Environment.Bls12_381.G1.of_bytes_opt b with - | Some x -> x - | None -> assert false - - and generate_bls12_381_g2 : Environment.Bls12_381.G2.t sampler = - fun rng_state -> - let b = Bls12_381.G2.(to_bytes (random ~state:rng_state ())) in - match Environment.Bls12_381.G2.of_bytes_opt b with - | Some x -> x - | None -> assert false - - and generate_bls12_381_fr : Environment.Bls12_381.Fr.t sampler = - fun rng_state -> - let b = Bls12_381.Fr.(to_bytes (random ~state:rng_state ())) in - match Environment.Bls12_381.Fr.of_bytes_opt b with - | Some x -> x - | None -> assert false - - and generate_ticket : - type a. a Script_typed_ir.ty -> a Script_typed_ir.ticket sampler = - fun ty rng_state -> - let contents = value ty rng_state in - let ticketer = - Alpha_context.Contract.implicit_contract (Crypto_samplers.pkh rng_state) - in - let amount = Michelson_base.nat rng_state in - Script_typed_ir.{ticketer; contents; amount} - - let comparable ty = value (comparable_downcast ty) - - (* Random stack generation. *) - let rec stack : type a b. (a, b) Script_typed_ir.stack_ty -> (a * b) sampler - = - let open M in - let open Script_typed_ir in - fun stack_ty -> - match stack_ty with - | Item_t (ty, tl, _) -> - let* elt = value ty in - let* tl = stack tl in - return ((elt, tl) : a * b) - | Bot_t -> return (EmptyCell, EmptyCell) - end -end - -module Internal_for_tests = struct - type nonrec type_name = type_name -end diff --git a/src/proto_012_Psithaca/lib_benchmark/michelson_samplers.mli b/src/proto_012_Psithaca/lib_benchmark/michelson_samplers.mli deleted file mode 100644 index 813638f3cab2..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/michelson_samplers.mli +++ /dev/null @@ -1,131 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Sampling various Michelson values. *) - -open Protocol -open Base_samplers - -(** This module exposes a functor implementing various samplers for Michelson. - These allow to sample: - - types and comparable types (given a target size), - - values and comparable values of a given Michelson type (given some more - parameters fixed at functor instantiation time) - - stacks - - Note that some kind of values might not be supported. At the time of writing, - the value sampler doesn't handle the following types: - - Sapling transaction and states - - Timelock chests and chest keys - - Operations - - Lambdas (ie code) - - For the latter, consider using the samplers in {!Michelson_mcmc_samplers}. -*) - -(** Parameters for the Michelson samplers. *) -type parameters = { - base_parameters : Michelson_samplers_base.parameters; - list_size : Base_samplers.range; - (** The range of the size, measured in number of elements, in which lists must be sampled.*) - set_size : Base_samplers.range; - (** The range of the size, measured in number of elements, in which sets must be sampled.*) - map_size : Base_samplers.range; - (** The range of the size, measured in number of bindings, in which maps must be sampled.*) -} - -(** Encoding for sampler prameters. *) -val parameters_encoding : parameters Data_encoding.t - -(** The module type produced by the [Make] functor. *) -module type S = sig - (** Basic Michelson samplers, re-exported for convenience by the functor. *) - module Michelson_base : Michelson_samplers_base.S - - (** Samplers for random Michelson types. *) - module Random_type : sig - (** [m_type ~size] samples a type containing exactly [size] constructors. *) - val m_type : size:int -> Script_ir_translator.ex_ty sampler - - (** [m_comparable_type ~size] samples a comparable type containing - exactly [size] constructors. *) - val m_comparable_type : - size:int -> Script_ir_translator.ex_comparable_ty sampler - end - - (** Samplers for random Michelson values. Restrictions apply on the - supported types as listed at the beginning of this file. *) - module rec Random_value : sig - (** Sample a value given its type. *) - val value : 'a Script_typed_ir.ty -> 'a sampler - - (** Sample a comparable value given its type. *) - val comparable : 'a Script_typed_ir.comparable_ty -> 'a sampler - - (** Sample a stack given its type. *) - val stack : ('a, 'b) Script_typed_ir.stack_ty -> ('a * 'b) sampler - end -end - -(** Instantiate a module of type {!S}. *) -module Make : functor - (P : sig - val parameters : parameters - end) - (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) - -> S - -module Internal_for_tests : sig - type type_name = - [ `TAddress - | `TBig_map - | `TBls12_381_fr - | `TBls12_381_g1 - | `TBls12_381_g2 - | `TBool - | `TBytes - | `TChain_id - | `TContract - | `TInt - | `TKey - | `TKey_hash - | `TLambda - | `TList - | `TMap - | `TMutez - | `TNat - | `TOperation - | `TOption - | `TPair - | `TSapling_state - | `TSapling_transaction - | `TSet - | `TSignature - | `TString - | `TTicket - | `TTimestamp - | `TUnion - | `TUnit ] -end diff --git a/src/proto_012_Psithaca/lib_benchmark/michelson_samplers_base.ml b/src/proto_012_Psithaca/lib_benchmark/michelson_samplers_base.ml deleted file mode 100644 index c772d60f1008..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/michelson_samplers_base.ml +++ /dev/null @@ -1,127 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Sampling_helpers - -(** Parameters for basic samplers *) -type parameters = { - int_size : Base_samplers.range; - string_size : Base_samplers.range; - bytes_size : Base_samplers.range; -} - -(** Encoding for basic samplers parameters *) -let parameters_encoding = - let open Data_encoding in - let range = Base_samplers.range_encoding in - conv - (fun {int_size; string_size; bytes_size} -> - (int_size, string_size, bytes_size)) - (fun (int_size, string_size, bytes_size) -> - {int_size; string_size; bytes_size}) - (obj3 - (req "int_size" range) - (req "string_size" range) - (req "bytes_size" range)) - -(** A module of type [S] packs samplers used to construct basic Michelson values. *) -module type S = sig - val int : Alpha_context.Script_int.z Alpha_context.Script_int.num sampler - - val nat : Alpha_context.Script_int.n Alpha_context.Script_int.num sampler - - val signature : Tezos_crypto.Signature.t sampler - - val string : Alpha_context.Script_string.t sampler - - val bytes : bytes sampler - - val tez : Alpha_context.Tez.tez sampler - - val timestamp : Alpha_context.Script_timestamp.t sampler -end - -(* Samplers for basic Michelson types. *) - -module Make (P : sig - val parameters : parameters -end) : S = struct - let int rng_state = - let i = Base_samplers.int ~size:P.parameters.int_size rng_state in - Alpha_context.Script_int.of_zint i - - let nat rng_state = - let i = Base_samplers.nat ~size:P.parameters.int_size rng_state in - Alpha_context.Script_int.abs (Alpha_context.Script_int.of_zint i) - - let signature rng_state = - let i = Random.State.int rng_state 4 in - match i with - | 0 -> ( - let open Ed25519 in - let bytes = Base_samplers.uniform_bytes ~nbytes:size rng_state in - match of_bytes_opt bytes with - | None -> assert false - | Some s -> Signature.of_ed25519 s) - | 1 -> ( - let open Secp256k1 in - let bytes = Base_samplers.uniform_bytes ~nbytes:size rng_state in - match of_bytes_opt bytes with - | None -> assert false - | Some s -> Signature.of_secp256k1 s) - | 2 -> ( - let open P256 in - let bytes = Base_samplers.uniform_bytes ~nbytes:size rng_state in - match of_bytes_opt bytes with - | None -> assert false - | Some s -> Signature.of_p256 s) - | _ -> ( - let open Signature in - let bytes = Base_samplers.uniform_bytes ~nbytes:size rng_state in - match of_bytes_opt bytes with None -> assert false | Some s -> s) - - let string rng_state = - let s = - Base_samplers.readable_ascii_string - ~size:P.parameters.string_size - rng_state - in - match Protocol.Alpha_context.Script_string.of_string s with - | Ok s -> s - | Error _ -> assert false - - let bytes = Base_samplers.bytes ~size:P.parameters.bytes_size - - let tez rng_state = - let i = Random.State.int64 rng_state (Int64.of_int max_int) in - match Protocol.Alpha_context.Tez.of_mutez i with - | Some res -> res - | None -> assert false - - let timestamp rng_state = - let i = Base_samplers.int ~size:P.parameters.int_size rng_state in - Protocol.Alpha_context.Script_timestamp.of_zint i -end diff --git a/src/proto_012_Psithaca/lib_benchmark/michelson_samplers_base.mli b/src/proto_012_Psithaca/lib_benchmark/michelson_samplers_base.mli deleted file mode 100644 index 975dd002bc1f..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/michelson_samplers_base.mli +++ /dev/null @@ -1,67 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Samplers for basic Michelson values (not including pairs, unions, tickets, big maps, etc) *) - -open Protocol -open Base_samplers - -(** Parameters for basic samplers *) -type parameters = { - int_size : Base_samplers.range; - (** The range of the size, measured in bytes, in which big integers must be sampled.*) - string_size : Base_samplers.range; - (** The range of the size, measured in bytes, in which strings must be sampled.*) - bytes_size : Base_samplers.range; - (** The range of the size, measured in bytes, in which [bytes] must be sampled.*) -} - -(** Encoding for [parameters] *) -val parameters_encoding : parameters Data_encoding.t - -(** A module of type [S] packs samplers used to construct basic Michelson values. *) -module type S = sig - val int : Alpha_context.Script_int.z Alpha_context.Script_int.num sampler - - val nat : Alpha_context.Script_int.n Alpha_context.Script_int.num sampler - - val signature : Tezos_crypto.Signature.t sampler - - val string : Alpha_context.Script_string.t sampler - - val bytes : bytes sampler - - val tez : Alpha_context.Tez.tez sampler - - val timestamp : Alpha_context.Script_timestamp.t sampler -end - -(** The [Make] functor instantiates a module of type [S], where the - samplers satisfy the given parameters. *) -module Make : functor - (P : sig - val parameters : parameters - end) - -> S diff --git a/src/proto_012_Psithaca/lib_benchmark/mikhailsky_to_michelson.ml b/src/proto_012_Psithaca/lib_benchmark/mikhailsky_to_michelson.ml deleted file mode 100644 index dbe7dd24789f..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/mikhailsky_to_michelson.ml +++ /dev/null @@ -1,229 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -exception Cannot_get_type of Mikhailsky.node * Kernel.Path.t - -exception Unexpected_stack_type of string - -exception Unexpected_base_type - -let unparse_type = Mikhailsky.map_var (fun _ -> Mikhailsky.prim T_unit [] []) - -let project_top (aft : Type.Stack.t) = - match aft.node with - | Type.Stack.Empty_t -> raise (Unexpected_stack_type "empty") - | Type.Stack.Stack_var_t _ -> raise (Unexpected_stack_type "var") - | Type.Stack.Item_t (top, _) -> top - -let project_union (aft : Type.Stack.t) = - let top = project_top aft in - match top.node with - | Type.Base.Union_t (l, r) -> (l, r) - | _ -> raise Unexpected_base_type - -let project_lambda (aft : Type.Stack.t) = - let top = project_top aft in - match top.node with - | Type.Base.Lambda_t (dom, range) -> (dom, range) - | _ -> raise Unexpected_base_type - -let project_list (aft : Type.Stack.t) = - let top = project_top aft in - match top.node with - | Type.Base.List_t t -> t - | _ -> raise Unexpected_base_type - -let project_set (aft : Type.Stack.t) = - let top = project_top aft in - match top.node with Type.Base.Set_t t -> t | _ -> raise Unexpected_base_type - -let project_map (aft : Type.Stack.t) = - let top = project_top aft in - match top.node with - | Type.Base.Map_t (k, v) -> (k, v) - | _ -> raise Unexpected_base_type - -let project_option (aft : Type.Stack.t) = - let top = project_top aft in - match top.node with - | Type.Base.Option_t t -> t - | _ -> raise Unexpected_base_type - -let rec convert_raw : Mikhailsky.node -> (int, 'a) Micheline.node = - fun node -> - match node with - | Micheline.Int (_, i) -> Micheline.Int (0, i) - | Micheline.Prim (_, head, subterms, annots) -> - let head = Mikhailsky_prim.to_michelson head in - Micheline.Prim (0, head, List.map convert_raw subterms, annots) - | Micheline.String (_, s) -> Micheline.String (0, s) - | Micheline.Bytes (_, b) -> Micheline.Bytes (0, b) - | Micheline.Seq (_, subterms) -> - Micheline.Seq (0, List.map convert_raw subterms) - -(* We assume that the term has been completed. *) -let rec convert : - Mikhailsky.node -> Kernel.Path.t -> (int, 'a) Micheline.node Inference.M.t = - fun node path -> - let open Inference.M in - match node with - | Micheline.Int (_, i) -> return (Micheline.Int (0, i)) - | Micheline.String (_, s) -> return (Micheline.String (0, s)) - | Micheline.Bytes (_, b) -> return (Micheline.Bytes (0, b)) - (* Remove annotations *) - | Micheline.Prim (_, prim, [term], _) - when Mikhailsky_prim.kind prim = Annot_kind -> - let path = Kernel.Path.at_index 0 path in - convert term path - (* Fail on holes *) - | Micheline.Prim (_, I_Hole, _, _) | Micheline.Prim (_, D_Hole, _, _) -> - raise Mikhailsky.Term_contains_holes - (* Add type information to union injections *) - | Micheline.Prim (_, I_LEFT, [], annots) -> ( - get_instr_annot path >>= fun ty_opt -> - match ty_opt with - | None -> raise (Cannot_get_type (node, path)) - | Some {aft; _} -> - Inference.instantiate aft >>= fun aft -> - let (_, r) = project_union aft in - Inference.instantiate_base r >>= fun r -> - Autocomp.replace_vars r >>= fun r -> - let r = unparse_type r in - let head = Mikhailsky_prim.to_michelson I_LEFT in - return (Micheline.Prim (0, head, [convert_raw r], annots))) - | Micheline.Prim (_, I_RIGHT, [], annots) -> ( - get_instr_annot path >>= fun ty_opt -> - match ty_opt with - | None -> raise (Cannot_get_type (node, path)) - | Some {aft; _} -> - Inference.instantiate aft >>= fun aft -> - let (l, _) = project_union aft in - Inference.instantiate_base l >>= fun l -> - Autocomp.replace_vars l >>= fun l -> - let l = unparse_type l in - let head = Mikhailsky_prim.to_michelson I_RIGHT in - return (Micheline.Prim (0, head, [convert_raw l], annots))) - | Micheline.Prim (_, (I_LEFT | I_RIGHT), _, _) -> - raise Mikhailsky.Ill_formed_mikhailsky - (* Add type information for lambdas *) - | Micheline.Prim (_, I_LAMBDA, [code], annots) -> ( - convert code (Kernel.Path.at_index 0 path) >>= fun code -> - get_instr_annot path >>= fun ty_opt -> - match ty_opt with - | None -> raise (Cannot_get_type (node, path)) - | Some {aft; _} -> - Inference.instantiate aft >>= fun aft -> - let (dom, range) = project_lambda aft in - Inference.instantiate_base dom >>= fun dom -> - Autocomp.replace_vars dom >>= fun dom -> - Inference.instantiate_base range >>= fun range -> - Autocomp.replace_vars range >>= fun range -> - let dom = unparse_type dom in - let range = unparse_type range in - let head = Mikhailsky_prim.to_michelson I_LAMBDA in - return - (Micheline.Prim - (0, head, [convert_raw dom; convert_raw range; code], annots))) - (* Add type information for empty_set, empty_map *) - | Micheline.Prim (_, I_EMPTY_SET, [], annots) -> ( - get_instr_annot path >>= fun ty_opt -> - match ty_opt with - | None -> raise (Cannot_get_type (node, path)) - | Some {aft; _} -> - Inference.instantiate aft >>= fun aft -> - let elt = project_set aft in - Inference.instantiate_base elt >>= fun elt -> - Autocomp.replace_vars elt >>= fun elt -> - let elt = unparse_type elt in - let head = Mikhailsky_prim.to_michelson I_EMPTY_SET in - return (Micheline.Prim (0, head, [convert_raw elt], annots))) - | Micheline.Prim (_, I_EMPTY_MAP, [], annots) -> ( - get_instr_annot path >>= fun ty_opt -> - match ty_opt with - | None -> raise (Cannot_get_type (node, path)) - | Some {aft; _} -> - Inference.instantiate aft >>= fun aft -> - let (k, v) = project_map aft in - Inference.instantiate_base k >>= fun k -> - Autocomp.replace_vars k >>= fun k -> - Inference.instantiate_base v >>= fun v -> - Autocomp.replace_vars v >>= fun v -> - let k = convert_raw (unparse_type k) in - let v = convert_raw (unparse_type v) in - let head = Mikhailsky_prim.to_michelson I_EMPTY_MAP in - return (Micheline.Prim (0, head, [k; v], annots))) - (* Add type information for UNPACK *) - | Micheline.Prim (_, I_UNPACK, [], annots) -> ( - get_instr_annot path >>= fun ty_opt -> - match ty_opt with - | None -> raise (Cannot_get_type (node, path)) - | Some {aft; _} -> - Inference.instantiate aft >>= fun aft -> - let elt = project_option aft in - Inference.instantiate_base elt >>= fun elt -> - Autocomp.replace_vars elt >>= fun elt -> - let elt = unparse_type elt in - let head = Mikhailsky_prim.to_michelson I_UNPACK in - return (Micheline.Prim (0, head, [convert_raw elt], annots))) - (* Add type information for NIL *) - | Micheline.Prim (_, I_NIL, [], annots) -> ( - get_instr_annot path >>= fun ty_opt -> - match ty_opt with - | None -> raise (Cannot_get_type (node, path)) - | Some {aft; _} -> - Inference.instantiate aft >>= fun aft -> - let elt = project_list aft in - Inference.instantiate_base elt >>= fun elt -> - Autocomp.replace_vars elt >>= fun elt -> - let elt = unparse_type elt in - let head = Mikhailsky_prim.to_michelson I_NIL in - return (Micheline.Prim (0, head, [convert_raw elt], annots))) - | Micheline.Prim (_, I_NIL, _, _) -> raise Mikhailsky.Ill_formed_mikhailsky - (* Project out type information from arithmetic ops *) - | Prim (_, ((I_ADD | I_SUB | I_MUL | I_EDIV) as instr), [_ty1; _ty2], annots) - -> - let head = Mikhailsky_prim.to_michelson instr in - return (Micheline.Prim (0, head, [], annots)) - | Prim (_, (I_ADD | I_SUB | I_MUL | I_EDIV), _, _) -> - raise Mikhailsky.Ill_formed_mikhailsky - (* Base case *) - | Micheline.Prim (_, head, subterms, annots) -> - let head = Mikhailsky_prim.to_michelson head in - convert_list path 0 subterms [] >>= fun subterms -> - return (Micheline.Prim (0, head, subterms, annots)) - | Micheline.Seq (_, subterms) -> - convert_list path 0 subterms [] >>= fun subterms -> - return (Micheline.Seq (0, subterms)) - -and convert_list path i subterms acc = - let open Inference.M in - match subterms with - | [] -> return (List.rev acc) - | subterm :: tl -> - let path' = Kernel.Path.at_index i path in - convert subterm path' >>= fun term -> - convert_list path (i + 1) tl (term :: acc) - -let convert node state = fst (convert node Kernel.Path.root state) diff --git a/src/proto_012_Psithaca/lib_benchmark/rules.ml b/src/proto_012_Psithaca/lib_benchmark/rules.ml deleted file mode 100644 index ff66cf05c7c4..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/rules.ml +++ /dev/null @@ -1,975 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Kernel - -type rule_set = {rule_patt : pattern; replacements : guarded_replacement list} - -and guarded_replacement = { - type_constraint : type_constraint; - replacement : replacement list; -} - -and type_constraint = - | No_cnstrnt - | Data_cnstrnt of {cnstrnt : Type.Base.t; fresh : int list} - | Instr_cnstrnt of { - cnstrnt : Inference.transformer; - fresh : var list; - fresh_stack : int list; - } - -and replacement = - | Context_aware of (Mikhailsky.node -> Mikhailsky.node) - | Context_blind of (unit -> Mikhailsky.node) - -and pattern = Pattern of Patt.t | Root - -and var = Plain of int | Cmp of int - -let stack_repr = Inference.Stack_type None - -let base_repr = - Inference.Base_type {repr = None; comparable = Inference.Unconstrained} - -let cmp_repr = - Inference.Base_type {repr = None; comparable = Inference.Comparable} - -let rec add_fresh_stack_variables vars = - let open Inference.M in - match vars with - | [] -> return () - | fresh :: tl -> - uf_lift (Uf.UF.add fresh) >>= fun () -> - set_repr fresh stack_repr >>= fun () -> add_fresh_stack_variables tl - -let rec add_fresh_data_variables vars = - let open Inference.M in - match vars with - | [] -> return () - | fresh :: tl -> - uf_lift (Uf.UF.add fresh) >>= fun () -> - set_repr fresh base_repr >>= fun () -> add_fresh_data_variables tl - -let rec add_fresh_variables vars plain_repr cmp_repr = - let open Inference.M in - match vars with - | [] -> return () - | Plain fresh :: tl -> - uf_lift (Uf.UF.add fresh) >>= fun () -> - set_repr fresh plain_repr >>= fun () -> - add_fresh_variables tl plain_repr cmp_repr - | Cmp fresh :: tl -> - uf_lift (Uf.UF.add fresh) >>= fun () -> - set_repr fresh cmp_repr >>= fun () -> - add_fresh_variables tl plain_repr cmp_repr - -let evaluate_guard_monadic guard path = - let open Inference.M in - match guard with - | No_cnstrnt -> return () - | Data_cnstrnt {cnstrnt = base_type_constraint; fresh} -> ( - add_fresh_data_variables fresh >>= fun () -> - get_data_annot path >>= fun res_opt -> - match res_opt with - | None -> assert false - | Some type_of_expr -> - Inference.unify_base type_of_expr base_type_constraint >>= fun () -> - Inference.instantiate_base type_of_expr >>= fun _ -> return ()) - | Instr_cnstrnt {cnstrnt = {bef = pre; aft = post}; fresh; fresh_stack} -> ( - (* Add base fresh type variables *) - add_fresh_variables fresh base_repr cmp_repr - >>= fun () -> - add_fresh_stack_variables fresh_stack >>= fun () -> - get_instr_annot path >>= fun res_opt -> - match res_opt with - | None -> assert false - | Some {bef; aft} -> - Inference.unify pre bef >>= fun () -> - Inference.unify post aft >>= fun () -> - Inference.instantiate bef >>= fun _bef -> - Inference.instantiate aft >>= fun _aft -> return ()) - -let evaluate_guard typing guard path = - try - let _ = evaluate_guard_monadic guard path typing in - true - with Inference.Ill_typed_script _ -> false - -let filter_matches typing guard matches = - List.filter (evaluate_guard typing guard) matches - -(* Provides a speedup but should better be done in the - rewriting module (so that not only top matches are hash-consed). *) -let matches_with_hash_consing = - let match_table : (int * int, Kernel.Path.t list) Hashtbl.t = - Hashtbl.create 97 - in - fun pattern term -> - match pattern with - | Root -> [Path.root] - | Pattern patt -> ( - let key = (Kernel.Patt.uid patt, Mikhailsky.tag term) in - match Hashtbl.find_opt match_table key with - | None -> - let res = Rewriter.all_matches patt term in - Hashtbl.add match_table key res ; - res - | Some res -> res) - -let matches_without_consing pattern term = - match pattern with - | Root -> [Path.root] - | Pattern patt -> Rewriter.all_matches patt term - -let rewriting (state : State_space.t) (rules : rule_set list) = - List.fold_left - (fun acc rule -> - let matches = matches_without_consing rule.rule_patt state.term in - List.fold_left - (fun acc guarded_replacement -> - let matches = - filter_matches - (Lazy.force state.typing) - guarded_replacement.type_constraint - matches - in - List.fold_left - (fun acc replacement -> - match replacement with - | Context_blind term -> - List.fold_left - (fun acc path -> (path, term ()) :: acc) - acc - matches - | Context_aware f -> - List.fold_left - (fun acc path -> - let term = Rewriter.get_subterm ~term:state.term ~path in - (path, f term) :: acc) - acc - matches) - acc - guarded_replacement.replacement) - acc - rule.replacements) - [] - rules - -module Instruction = struct - (* ----------------------------------------------------------------------- *) - (* Rule: replace instruction by hole. *) - - (* Matches instructions *) - let match_any_instr = - let open Patt in - Pattern - (focus - (prim_pred - (fun prim -> Mikhailsky_prim.kind prim = Mikhailsky_prim.Instr_kind) - list_any)) - - let replace_any_instr_by_hole = - let replace_by_hole = - { - type_constraint = No_cnstrnt; - replacement = [Context_blind (fun () -> Mikhailsky.instr_hole)]; - } - in - {rule_patt = match_any_instr; replacements = [replace_by_hole]} - - (* ----------------------------------------------------------------------- *) - (* Rule: replace instruction hole by instruction satisfying typing - constraints. *) - - (* Matches instruction holes *) - let match_instr_hole = - let open Patt in - Pattern (focus (prim I_Hole list_any)) - - let replacement ?(fresh = []) ?(fresh_stack = []) ~bef ~aft ~replacement () : - guarded_replacement = - { - type_constraint = Instr_cnstrnt {cnstrnt = {bef; aft}; fresh; fresh_stack}; - replacement; - } - - let instructions = - let open Type in - let module M = Mikhailsky in - let module I = Inference in - let alpha = ~-1 in - let beta = ~-2 in - let gamma = ~-3 in - let delta = ~-4 in - [ - replacement - ~fresh_stack:[alpha] - ~bef:(item bytes (stack_var alpha)) - ~aft:(item bytes (stack_var alpha)) - ~replacement: - [ - Context_blind (fun () -> M.Instructions.blake2b); - Context_blind (fun () -> M.Instructions.sha256); - Context_blind (fun () -> M.Instructions.sha512); - ] - (); - replacement - ~fresh_stack:[alpha] - ~bef:(item int (stack_var alpha)) - ~aft:(item bool (stack_var alpha)) - ~replacement:[Context_blind (fun () -> M.Instructions.gt)] - (); - replacement - ~fresh_stack:[alpha] - ~bef:(item int (stack_var alpha)) - ~aft:(item nat (stack_var alpha)) - ~replacement:[Context_blind (fun () -> M.Instructions.abs)] - (); - replacement - ~fresh_stack:[alpha] - ~bef:(item int (item int (stack_var alpha))) - ~aft:(item int (stack_var alpha)) - ~replacement: - [ - Context_blind (fun () -> M.Instructions.add M.int_ty M.int_ty); - Context_blind (fun () -> M.Instructions.mul M.int_ty M.int_ty); - ] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(item (pair (var alpha) (var beta)) (stack_var gamma)) - ~aft:(item (var alpha) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.car)] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(item (pair (var alpha) (var beta)) (stack_var gamma)) - ~aft:(item (var beta) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.cdr)] - (); - replacement - ~fresh:[Cmp alpha] - ~fresh_stack:[gamma] - ~bef:(item (var alpha) (item (var alpha) (stack_var gamma))) - ~aft:(item int (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.compare)] - (); - replacement - ~fresh_stack:[gamma] - ~bef:(item string (item string (stack_var gamma))) - ~aft:(item string (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.concat)] - (); - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[beta; gamma] - ~bef:(item (var alpha) (stack_var beta)) - ~aft:(item (var alpha) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.(dip hole))] - (); - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[beta] - ~bef:(item (var alpha) (stack_var beta)) - ~aft:(stack_var beta) - ~replacement:[Context_blind (fun () -> M.Instructions.drop)] - (); - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[beta] - ~bef:(item (var alpha) (stack_var beta)) - ~aft:(item (var alpha) (item (var alpha) (stack_var beta))) - ~replacement:[Context_blind (fun () -> M.Instructions.dup)] - (); - replacement - ~fresh:[] - ~fresh_stack:[alpha] - ~bef:(stack_var alpha) - ~aft:(item int (stack_var alpha)) - ~replacement: - [ - (* TODO : push random integer? *) - Context_blind - (fun () -> M.Instructions.push M.int_ty (M.Data.integer 100)); - ] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(item (var alpha) (item (var beta) (stack_var gamma))) - ~aft:(item (var beta) (item (var alpha) (stack_var gamma))) - ~replacement:[Context_blind (fun () -> M.Instructions.swap)] - (); - (* control *) - replacement - ~fresh_stack:[alpha] - ~bef:(item bool (stack_var alpha)) - ~aft:(stack_var alpha) - ~replacement:[Context_blind (fun () -> M.Instructions.(loop hole))] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(item (union (var alpha) (var beta)) (stack_var gamma)) - ~aft:(item (var beta) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.(loop_left hole))] - (); - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[beta; gamma] - ~bef:(item (option (var alpha)) (stack_var beta)) - ~aft:(stack_var gamma) - ~replacement: - [Context_blind (fun () -> M.Instructions.(if_none hole hole))] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma; delta] - ~bef:(item (union (var alpha) (var beta)) (stack_var gamma)) - ~aft:(stack_var delta) - ~replacement: - [Context_blind (fun () -> M.Instructions.(if_left hole hole))] - (); - replacement - ~fresh:[] - ~fresh_stack:[alpha; beta] - ~bef:(item bool (stack_var alpha)) - ~aft:(stack_var beta) - ~replacement:[Context_blind (fun () -> M.Instructions.(if_ hole hole))] - (); - replacement - ~fresh_stack:[alpha; beta] - ~bef:(stack_var alpha) - ~aft:(stack_var beta) - ~replacement: - [ - Context_blind - (fun () -> M.seq [M.Instructions.hole; M.Instructions.hole]); - ] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(item (var alpha) (stack_var gamma)) - ~aft:(item (union (var alpha) (var beta)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.left)] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(item (var beta) (stack_var gamma)) - ~aft:(item (union (var alpha) (var beta)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.right)] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(stack_var gamma) - ~aft:(item (lambda (var alpha) (var beta)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.(lambda [hole]))] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(stack_var gamma) - ~aft:(item (lambda (var alpha) (var beta)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.(lambda [hole]))] - (); - (* set/map/list*) - replacement - ~fresh:[Cmp alpha] - ~fresh_stack:[gamma] - ~bef: - (item - (var alpha) - (item bool (item (set (var alpha)) (stack_var gamma)))) - ~aft:(item (set (var alpha)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.update_set)] - (); - replacement - ~fresh:[Cmp alpha] - ~fresh_stack:[gamma] - ~bef:(stack_var gamma) - ~aft:(item (set (var alpha)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.empty_set)] - (); - replacement - ~fresh:[Cmp alpha] - ~fresh_stack:[gamma] - ~bef:(item (set (var alpha)) (stack_var gamma)) - ~aft:(stack_var gamma) - ~replacement: - [Context_blind (fun () -> M.Instructions.(iter_set [hole]))] - (); - replacement - ~fresh:[Cmp alpha] - ~fresh_stack:[gamma] - ~bef:(item (var alpha) (item (set (var alpha)) (stack_var gamma))) - ~aft:(item bool (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.mem_set)] - (); - replacement - ~fresh:[Cmp alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef: - (item - (var alpha) - (item - (option (var beta)) - (item (map (var alpha) (var beta)) (stack_var gamma)))) - ~aft:(item (map (var alpha) (var beta)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.update_map)] - (); - replacement - ~fresh:[Cmp alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(stack_var gamma) - ~aft:(item (map (var alpha) (var beta)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.empty_map)] - (); - replacement - ~fresh:[Cmp alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(item (map (var alpha) (var beta)) (stack_var gamma)) - ~aft:(stack_var gamma) - ~replacement: - [Context_blind (fun () -> M.Instructions.(iter_map [hole]))] - (); - replacement - ~fresh:[Cmp alpha; Plain beta; Plain delta] - ~fresh_stack:[gamma] - ~bef:(item (map (var alpha) (var beta)) (stack_var gamma)) - ~aft:(item (map (var alpha) (var delta)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.(map_map [hole]))] - (); - replacement - ~fresh:[Cmp alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef: - (item - (var alpha) - (item (map (var alpha) (var beta)) (stack_var gamma))) - ~aft:(item bool (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.mem_map)] - (); - replacement - ~fresh:[Cmp alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef: - (item - (var alpha) - (item (map (var alpha) (var beta)) (stack_var gamma))) - ~aft:(item (option (var beta)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.get_map)] - (); - (* lists *) - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[gamma] - ~bef:(stack_var gamma) - ~aft:(item (list (var alpha)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.nil)] - (); - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[gamma] - ~bef:(item (var alpha) (item (list (var alpha)) (stack_var gamma))) - ~aft:(item (list (var alpha)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.cons)] - (); - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[gamma] - ~bef:(item (list (var alpha)) (stack_var gamma)) - ~aft:(stack_var gamma) - ~replacement: - [Context_blind (fun () -> M.Instructions.(iter_list [hole]))] - (); - replacement - ~fresh:[Plain alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(item (list (var alpha)) (stack_var gamma)) - ~aft:(item (list (var beta)) (stack_var gamma)) - ~replacement: - [Context_blind (fun () -> M.Instructions.(map_list [hole]))] - (); - (* sizes *) - replacement - ~fresh:[Cmp alpha] - ~fresh_stack:[gamma] - ~bef:(item (set (var alpha)) (stack_var gamma)) - ~aft:(item nat (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.size_set)] - (); - replacement - ~fresh:[Cmp alpha; Plain beta] - ~fresh_stack:[gamma] - ~bef:(item (map (var alpha) (var beta)) (stack_var gamma)) - ~aft:(item nat (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.size_map)] - (); - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[gamma] - ~bef:(item (list (var alpha)) (stack_var gamma)) - ~aft:(item nat (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.size_list)] - (); - replacement - ~fresh:[] - ~fresh_stack:[gamma] - ~bef:(item string (stack_var gamma)) - ~aft:(item nat (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.size_string)] - (); - replacement - ~fresh:[] - ~fresh_stack:[gamma] - ~bef:(item bytes (stack_var gamma)) - ~aft:(item nat (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.size_bytes)] - (); - (* pack/unpack *) - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[gamma] - ~bef:(item (var alpha) (stack_var gamma)) - ~aft:(item bytes (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.pack)] - (); - replacement - ~fresh:[Plain alpha] - ~fresh_stack:[gamma] - ~bef:(item bytes (stack_var gamma)) - ~aft:(item (option (var alpha)) (stack_var gamma)) - ~replacement:[Context_blind (fun () -> M.Instructions.unpack)] - (); - ] - - let rules = - [ - replace_any_instr_by_hole; - {rule_patt = match_instr_hole; replacements = instructions}; - ] -end - -module Data_rewrite_leaves - (Michelson_base : Michelson_samplers_base.S) - (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) = -struct - let hole_patt = - let open Patt in - prim_pred (fun prim -> prim = D_Hole) list_empty - - (* Matches a data hole *) - let match_hole = - let open Patt in - Pattern (focus hole_patt) - - (* Matches an integer literal *) - let match_int = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = A_Int) list_any)) - - (* Matches a list literal *) - let match_list = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = A_List) list_any)) - - (* Matches a set literal *) - let match_set = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = A_Set) list_any)) - - (* Matches a map literal *) - let match_map = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = A_Map) list_any)) - - (* Matches a timestamp literal *) - let match_timestamp = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = A_Timestamp) list_any)) - - (* Matches a mutez literal *) - let match_mutez = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = A_Mutez) list_any)) - - (* Matches a key_hash literal *) - let match_key_hash = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = A_Key_hash) list_any)) - - let match_int_mutez_timestamp_key_hash_key_or_none = - let open Patt in - Pattern - (focus - (prim_pred - (function - | A_Int | A_Nat | A_Mutez | A_Timestamp | A_Key_hash | A_Key - | D_None -> - true - | _ -> false) - list_any)) - - (* Matches an empty list, set or map literal *) - let match_empty_list_set_or_map = - let open Patt in - Pattern - (focus - (prim_pred - (function A_List | A_Set | A_Map -> true | _ -> false) - (list_cons (seq list_empty) list_empty))) - - (* Matches a pair containing two holes*) - let match_empty_pair = - let open Patt in - Pattern - (focus - (prim_pred - (fun prim -> prim = D_Pair) - (list_cons hole_patt (list_cons hole_patt list_empty)))) - - (* Match a Some, Left or Right containing a hole *) - let match_empty_some_left_or_right = - let open Patt in - Pattern - (focus - (prim_pred - (function D_Left | D_Right | D_Some -> true | _ -> false) - (list_cons hole_patt list_empty))) - - (* Match a None constructor *) - let match_none = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = D_None) list_empty)) - - (* rules *) - - (* fresh type variables *) - let (alpha, beta) = (-1, -2) - - let replacement ~fresh ~typ ~replacement = - { - type_constraint = Data_cnstrnt {cnstrnt = typ; fresh}; - replacement = [Context_blind (fun () -> replacement)]; - } - - let replacement_gen ~fresh ~typ ~replacement = - { - type_constraint = Data_cnstrnt {cnstrnt = typ; fresh}; - replacement = [Context_blind replacement]; - } - - let fill_in_hole rng_state = - let replace_by_singleton_list = - replacement - ~fresh:[alpha] - ~typ:Type.(list (var alpha)) - ~replacement:Mikhailsky.Data.(list [hole]) - in - let replace_by_empty_pair = - replacement - ~fresh:[alpha; beta] - ~typ:Type.(pair (var alpha) (var beta)) - ~replacement:Mikhailsky.Data.(pair hole hole) - in - let replace_by_singleton_set = - replacement - ~fresh:[alpha] - ~typ:Type.(set (var alpha)) - ~replacement:Mikhailsky.Data.(set [hole]) - in - let replace_by_singleton_map = - replacement - ~fresh:[alpha; beta] - ~typ:Type.(map (var alpha) (var beta)) - ~replacement:Mikhailsky.Data.(map [map_elt hole hole]) - in - let replace_by_random_int rng_state = - let type_constraint = Data_cnstrnt {cnstrnt = Type.int; fresh = []} in - let replacement = - Context_blind - (fun () -> - Mikhailsky.Data.big_integer - (Protocol.Script_int_repr.to_zint (Michelson_base.int rng_state))) - in - {type_constraint; replacement = [replacement]} - in - let replace_by_left = - replacement - ~fresh:[alpha; beta] - ~typ:Type.(union (var alpha) (var beta)) - ~replacement:Mikhailsky.Data.(left hole) - in - let replace_by_right = - replacement - ~fresh:[alpha; beta] - ~typ:Type.(union (var alpha) (var beta)) - ~replacement:Mikhailsky.Data.(right hole) - in - let replace_by_some = - replacement - ~fresh:[alpha] - ~typ:Type.(option (var alpha)) - ~replacement:Mikhailsky.Data.(some hole) - in - let replace_by_none = - replacement - ~fresh:[alpha] - ~typ:Type.(option (var alpha)) - ~replacement:Mikhailsky.Data.none - in - let replace_by_mutez rng_state = - replacement_gen ~fresh:[] ~typ:Type.mutez ~replacement:(fun () -> - Mikhailsky.Data.mutez (Michelson_base.tez rng_state)) - in - let replace_by_key_hash rng_state = - replacement_gen ~fresh:[] ~typ:Type.key_hash ~replacement:(fun () -> - Mikhailsky.Data.key_hash (Crypto_samplers.pkh rng_state)) - in - let replace_by_key rng_state = - replacement_gen ~fresh:[] ~typ:Type.key ~replacement:(fun () -> - Mikhailsky.Data.key (Crypto_samplers.pk rng_state)) - in - { - rule_patt = match_hole; - replacements = - [ - replace_by_singleton_list; - replace_by_empty_pair; - replace_by_singleton_set; - replace_by_singleton_map; - replace_by_random_int rng_state; - replace_by_left; - replace_by_right; - replace_by_some; - replace_by_none; - replace_by_mutez rng_state; - replace_by_key_hash rng_state; - replace_by_key rng_state; - ]; - } - - let kill_empty_pair = - { - rule_patt = match_empty_pair; - replacements = - [ - { - type_constraint = No_cnstrnt; - replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; - }; - ]; - } - - let kill_int_mutez_timestamp_key_hash_none = - { - rule_patt = match_int_mutez_timestamp_key_hash_key_or_none; - replacements = - [ - { - type_constraint = No_cnstrnt; - replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; - }; - ]; - } - - let kill_empty_list_set_or_map = - { - rule_patt = match_empty_list_set_or_map; - replacements = - [ - { - type_constraint = No_cnstrnt; - replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; - }; - ]; - } - - let kill_empty_some_left_or_right = - { - rule_patt = match_empty_some_left_or_right; - replacements = - [ - { - type_constraint = No_cnstrnt; - replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; - }; - ]; - } - - let modify_set = - let grow_ungrow_set = - { - type_constraint = No_cnstrnt; - replacement = - [ - Context_aware - (fun set -> - match set with - | Micheline.Prim (_, A_Set, [Micheline.Seq (_, elements)], _) -> - Mikhailsky.Data.(set (hole :: elements)) - | _ -> assert false); - Context_aware - (fun set -> - match set with - | Micheline.Prim (_, A_Set, [Micheline.Seq (_, elements)], _) - -> ( - match elements with - | [] -> Mikhailsky.Data.hole - | _ :: tl -> Mikhailsky.Data.set tl) - | _ -> assert false); - ]; - } - in - {rule_patt = match_set; replacements = [grow_ungrow_set]} - - let modify_map = - let grow_ungrow_map = - { - type_constraint = No_cnstrnt; - replacement = - [ - Context_aware - (fun set -> - match set with - | Micheline.Prim (_, A_Map, [Micheline.Seq (_, elements)], _) -> - Mikhailsky.Data.(map (map_elt hole hole :: elements)) - | _ -> assert false); - Context_aware - (fun set -> - match set with - | Micheline.Prim (_, A_Map, [Micheline.Seq (_, elements)], _) - -> ( - match elements with - | [] -> Mikhailsky.Data.hole - | _ :: tl -> Mikhailsky.Data.map tl) - | _ -> assert false); - ]; - } - in - {rule_patt = match_map; replacements = [grow_ungrow_map]} - - let modify_list = - let grow_ungrow_list = - { - type_constraint = No_cnstrnt; - replacement = - [ - Context_aware - (fun list -> - match list with - | Micheline.Prim (_, A_List, [Micheline.Seq (_, terms)], _) -> - Mikhailsky.Data.(list (hole :: terms)) - | _ -> assert false); - Context_aware - (fun list -> - match list with - | Micheline.Prim (_, A_List, [Micheline.Seq (_, terms)], _) -> ( - match terms with - | [] -> Mikhailsky.Data.hole - | _ :: tl -> Mikhailsky.Data.list tl) - | _ -> assert false); - ]; - } - in - {rule_patt = match_list; replacements = [grow_ungrow_list]} - - let rules rng_state = - [ - fill_in_hole rng_state; - kill_empty_pair; - kill_empty_list_set_or_map; - kill_empty_some_left_or_right; - kill_int_mutez_timestamp_key_hash_none; - modify_list; - modify_set; - modify_map; - ] -end - -module Data - (Michelson_base : Michelson_samplers_base.S) - (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) = -struct - let match_data_node = - let open Patt in - Pattern - (focus - (prim_pred - (function - | Mikhailsky_prim.D_Elt | D_Hole -> false - | D_False | D_Left | D_None | D_Pair | D_Right | D_Some | D_True - | D_Unit | A_Int | A_Nat | A_Set | A_List | A_Map | A_Key_hash - | A_Mutez | A_Timestamp | A_Key -> - true - | _ -> false) - list_any)) - - let match_list = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = A_List) list_any)) - - let match_data_hole = - let open Patt in - Pattern (focus (prim_pred (fun prim -> prim = D_Hole) list_any)) - - let replace_by_hole = - let replace_by_hole = - { - type_constraint = No_cnstrnt; - replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; - } - in - {rule_patt = match_data_node; replacements = [replace_by_hole]} - - let pack_root = - let replacement = - [ - Context_aware (fun node -> Mikhailsky.Data.list [node]); - Context_aware (fun node -> Mikhailsky.Data.(pair node hole)); - Context_aware (fun node -> Mikhailsky.Data.(pair hole node)); - ] - in - let guarded_replacements = [{type_constraint = No_cnstrnt; replacement}] in - {rule_patt = Root; replacements = guarded_replacements} - - module Data_rewrite_leaves_rules = - Data_rewrite_leaves (Michelson_base) (Crypto_samplers) - - let rules rng_state = - [ - Data_rewrite_leaves_rules.fill_in_hole rng_state; - replace_by_hole; - Data_rewrite_leaves_rules.modify_list; - Data_rewrite_leaves_rules.modify_map; - Data_rewrite_leaves_rules.modify_set; - ] -end diff --git a/src/proto_012_Psithaca/lib_benchmark/sampling_helpers.ml b/src/proto_012_Psithaca/lib_benchmark/sampling_helpers.ml deleted file mode 100644 index 8b36fc09e0bf..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/sampling_helpers.ml +++ /dev/null @@ -1,41 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* ------------------------------------------------------------------------- *) - -(* TODO: use Statz's def. of sampler once upstreamed. *) -type 'a sampler = Random.State.t -> 'a - -module M = struct - let ( let* ) : 'a sampler -> ('a -> 'b sampler) -> 'b sampler = - fun sampler f rng_state -> - let x = sampler rng_state in - f x rng_state - [@@inline] - - let bind = ( let* ) - - let return x _ = x -end diff --git a/src/proto_012_Psithaca/lib_benchmark/state_space.ml b/src/proto_012_Psithaca/lib_benchmark/state_space.ml deleted file mode 100644 index 60d14970e610..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/state_space.ml +++ /dev/null @@ -1,78 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* The state of rewriting is a typed term *) -type t = {typing : Inference.state lazy_t; term : Mikhailsky.node} - -let compare (term1 : t) (term2 : t) = - let tag1 = Mikhailsky.tag term1.term in - let tag2 = Mikhailsky.tag term2.term in - if tag1 < tag2 then -1 else if tag1 > tag2 then 1 else 0 - -let equal (term1 : t) (term2 : t) = - let tag1 = Mikhailsky.tag term1.term in - let tag2 = Mikhailsky.tag term2.term in - tag1 = tag2 - -let hash (t : t) = Mikhailsky.hash t.term - -type node_statistics = { - mutable size : int; - mutable bytes : int; - mutable holes : int; - mutable depth : int; -} - -let pp_statistics fmtr stats = - Format.fprintf - fmtr - "{ size = %d ; bytes = %d ; holes = %d }" - stats.size - stats.bytes - stats.holes - -let rec statistics stats depth (n : Mikhailsky.node) = - stats.size <- stats.size + 1 ; - stats.depth <- max depth stats.depth ; - match n with - | Micheline.Int (_, z) -> stats.bytes <- stats.bytes + (Z.numbits z / 8) - | Micheline.String (_, s) -> stats.bytes <- stats.bytes + String.length s - | Micheline.Bytes (_, b) -> stats.bytes <- stats.bytes + Bytes.length b - | Micheline.Prim (_, Mikhailsky_prim.I_Hole, _, _) - | Micheline.Prim (_, Mikhailsky_prim.D_Hole, _, _) -> - stats.holes <- stats.holes + 1 - | Micheline.Prim (_, _, subterms, _) | Micheline.Seq (_, subterms) -> - List.iter (statistics stats (depth + 1)) subterms - -let statistics {term; _} = - let stats = {size = 0; bytes = 0; holes = 0; depth = 0} in - statistics stats 0 term ; - stats - -let pp fmtr (state : t) = - Format.fprintf fmtr "current term:@." ; - Format.fprintf fmtr "%a@." Mikhailsky.pp state.term ; - Format.fprintf fmtr "stats:@." ; - Format.fprintf fmtr "%a:@." pp_statistics (statistics state) diff --git a/src/proto_012_Psithaca/lib_benchmark/test/.ocamlformat b/src/proto_012_Psithaca/lib_benchmark/test/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/test/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_benchmark/test/dune b/src/proto_012_Psithaca/lib_benchmark/test/dune deleted file mode 100644 index 55dbcd73f447..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/test/dune +++ /dev/null @@ -1,41 +0,0 @@ -(executables - (names test_sampling_data test_sampling_code test_autocompletion test_distribution) - (libraries tezos-micheline - tezos-micheline-rewriting - tezos-benchmark-type-inference-012-Psithaca - tezos-benchmark - tezos-benchmark-012-Psithaca - tezos-protocol-012-Psithaca - tezos-012-Psithaca-test-helpers - tezos-error-monad - alcotest-lwt - prbnmcn-stats) -;; uncomment to enable gprof profiling -;; (ocamlopt_flags (:standard -p -ccopt -no-pie)) - (flags (:standard - -open Tezos_micheline - -open Tezos_protocol_012_Psithaca - -open Tezos_benchmark - -open Tezos_benchmark_type_inference_012_Psithaca - -open Tezos_benchmark_012_Psithaca - -open Tezos_012_Psithaca_test_helpers))) - -(alias - (name buildtest) - (deps test_sampling_data.exe test_sampling_code.exe)) - -(rule - (alias runtest_micheline_rewriting_data) - (action (run %{exe:test_sampling_data.exe} 1234))) - -(rule - (alias runtest_micheline_rewriting_code) - (action (run %{exe:test_sampling_code.exe} 1234))) - - -(alias - (name runtest) - (package tezos-benchmark-012-Psithaca) - (deps (alias runtest_micheline_rewriting_data) - (alias runtest_micheline_rewriting_code) - )) diff --git a/src/proto_012_Psithaca/lib_benchmark/test/test_autocompletion.ml b/src/proto_012_Psithaca/lib_benchmark/test/test_autocompletion.ml deleted file mode 100644 index 5d5d65fdee01..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/test/test_autocompletion.ml +++ /dev/null @@ -1,120 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let rng_state = Random.State.make [|42; 987897; 54120|] - -module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct - let algo = `Default - - let size = 16 -end) - -module Michelson_base_samplers = Michelson_samplers_base.Make (struct - let parameters = - let size = {Base_samplers.min = 4; max = 32} in - { - Michelson_samplers_base.int_size = size; - string_size = size; - bytes_size = size; - } -end) - -module Autocomp = Autocomp.Make (Michelson_base_samplers) (Crypto_samplers) - -let () = Format.eprintf "===============================@.%!" - -let () = Format.eprintf "Testing dummy program generator@.%!" - -let run x = x rng_state (Inference.M.empty ()) - -let invent_term bef aft = - let (term, _state) = run (Autocomp.invent_term bef aft) in - Mikhailsky.seq term - -let invent_term bef aft = - Format.eprintf - "requested type: %a => %a@." - Type.Stack.pp - bef - Type.Stack.pp - aft ; - let term = invent_term bef aft in - let (bef', aft') = Inference.infer term in - Format.eprintf - "generated type: %a => %a@." - Type.Stack.pp - bef' - Type.Stack.pp - aft' ; - Format.eprintf "%a@." Mikhailsky.pp term - -module T = Type - -let bef = T.(item unit (item unit (item unit empty))) - -let aft = T.(item int (item unit (item (pair nat nat) empty))) - -let () = invent_term bef aft - -let () = Format.eprintf "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@.%!" - -let () = invent_term bef aft - -let () = Format.eprintf "===============================@.%!" - -let () = Format.eprintf "Testing completion@.%!" - -let complete term = - Format.eprintf "term: %a@." Mikhailsky.pp term ; - let ((bef, aft), state) = Inference.infer_with_state term in - Format.eprintf "Inferred type: %a => %a@." Type.Stack.pp bef Type.Stack.pp aft ; - let (term, (bef', aft'), _state) = - Autocomp.complete_code state term rng_state - in - Format.eprintf "completed: %a@." Mikhailsky.pp term ; - Format.eprintf - "Inferred type after generation: %a => %a@." - Type.Stack.pp - bef' - Type.Stack.pp - aft' ; - let node = - Micheline.strip_locations @@ Mikhailsky_to_michelson.convert term state - in - let bef' = Type_helpers.stack_type_to_michelson_type_list bef' in - Test_helpers.typecheck_by_tezos bef' node - -open Mikhailsky -open Instructions - -let push_int = Instructions.push int_ty (Data.big_integer (Z.of_int 100)) - -let add_ii = Instructions.(add Mikhailsky.int_ty Mikhailsky.int_ty) - -let () = complete (lambda [if_left right (dip (seq [push_int; hole]))]) - -let () = Format.eprintf "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@.%!" - -let () = complete (seq [push_int; add_ii; lambda [dip (seq [dup; dip hole])]]) diff --git a/src/proto_012_Psithaca/lib_benchmark/test/test_distribution.ml b/src/proto_012_Psithaca/lib_benchmark/test/test_distribution.ml deleted file mode 100644 index 42bbfbc0638c..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/test/test_distribution.ml +++ /dev/null @@ -1,182 +0,0 @@ -open Tezos_benchmark -open Michelson_samplers -open Protocol -open Internal_for_tests - -let pp_type_name fmtr (t : type_name) = - Format.pp_print_string fmtr - @@ - match t with - | `TString -> "string" - | `TNat -> "nat" - | `TPair -> "pair" - | `TKey -> "key" - | `TLambda -> "lambda" - | `TUnion -> "union" - | `TOperation -> "operation" - | `TOption -> "option" - | `TSapling_state -> "sapling_state" - | `TBytes -> "bytes" - | `TChain_id -> "chain_id" - | `TBool -> "bool" - | `TBls12_381_g2 -> "bls12_381_g2" - | `TTicket -> "ticket" - | `TMap -> "map" - | `TAddress -> "address" - | `TContract -> "contract" - | `TBls12_381_fr -> "bls12_381_fr" - | `TSapling_transaction -> "sapling_transaction" - | `TTimestamp -> "timestamp" - | `TKey_hash -> "key_hash" - | `TBig_map -> "big_map" - | `TSet -> "set" - | `TBls12_381_g1 -> "bls12_381_g1" - | `TList -> "list" - | `TMutez -> "mutez" - | `TSignature -> "signature" - | `TUnit -> "unit" - | `TInt -> "int" - -module Type_name = struct - type t = type_name - - let compare (x : t) (y : t) = Stdlib.compare x y - - let equal (x : t) (y : t) = x = y - - let pp = pp_type_name - - let hash = Stdlib.Hashtbl.hash -end - -module Type_name_multiset = - Basic_structures.Basic_impl.Free_module.Float_valued.Make_with_map (Type_name) - -let rec tnames_of_type : - type a. a Script_typed_ir.ty -> type_name list -> type_name list = - fun t acc -> - match t with - | Script_typed_ir.Unit_t _ -> `TUnit :: acc - | Script_typed_ir.Int_t _ -> `TInt :: acc - | Script_typed_ir.Nat_t _ -> `TNat :: acc - | Script_typed_ir.Signature_t _ -> `TSignature :: acc - | Script_typed_ir.String_t _ -> `TString :: acc - | Script_typed_ir.Bytes_t _ -> `TBytes :: acc - | Script_typed_ir.Mutez_t _ -> `TMutez :: acc - | Script_typed_ir.Key_hash_t _ -> `TKey_hash :: acc - | Script_typed_ir.Key_t _ -> `TKey :: acc - | Script_typed_ir.Timestamp_t _ -> `TTimestamp :: acc - | Script_typed_ir.Address_t _ -> `TAddress :: acc - | Script_typed_ir.Bool_t _ -> `TBool :: acc - | Script_typed_ir.Pair_t ((lty, _, _), (rty, _, _), _) -> - tnames_of_type lty (tnames_of_type rty (`TPair :: acc)) - | Script_typed_ir.Union_t ((lty, _), (rty, _), _) -> - tnames_of_type lty (tnames_of_type rty (`TUnion :: acc)) - | Script_typed_ir.Lambda_t (dom, range, _) -> - tnames_of_type dom (tnames_of_type range (`TLambda :: acc)) - | Script_typed_ir.Option_t (ty, _) -> tnames_of_type ty (`TOption :: acc) - | Script_typed_ir.List_t (ty, _) -> tnames_of_type ty (`TList :: acc) - | Script_typed_ir.Set_t (ty, _) -> tnames_of_comparable_type ty (`TSet :: acc) - | Script_typed_ir.Map_t (kty, vty, _) -> - tnames_of_comparable_type kty (tnames_of_type vty (`TMap :: acc)) - | Script_typed_ir.Big_map_t (kty, vty, _) -> - tnames_of_comparable_type kty (tnames_of_type vty (`TBig_map :: acc)) - | Script_typed_ir.Contract_t (ty, _) -> tnames_of_type ty (`TContract :: acc) - | Script_typed_ir.Sapling_transaction_t (_, _) -> `TSapling_transaction :: acc - | Script_typed_ir.Sapling_state_t (_, _) -> `TSapling_state :: acc - | Script_typed_ir.Operation_t _ -> `TOperation :: acc - | Script_typed_ir.Chain_id_t _ -> `TChain_id :: acc - | Script_typed_ir.Never_t _ -> assert false - | Script_typed_ir.Bls12_381_g1_t _ -> `TBls12_381_g1 :: acc - | Script_typed_ir.Bls12_381_g2_t _ -> `TBls12_381_g2 :: acc - | Script_typed_ir.Bls12_381_fr_t _ -> `TBls12_381_fr :: acc - | Script_typed_ir.Ticket_t (ty, _) -> - tnames_of_comparable_type ty (`TTicket :: acc) - | Script_typed_ir.Chest_key_t _ -> assert false - | Script_typed_ir.Chest_t _ -> assert false - -and tnames_of_comparable_type : - type a. a Script_typed_ir.comparable_ty -> type_name list -> type_name list - = - fun t acc -> - match t with - | Script_typed_ir.Unit_key _ -> `TUnit :: acc - | Script_typed_ir.Never_key _ -> assert false - | Script_typed_ir.Int_key _ -> `TInt :: acc - | Script_typed_ir.Nat_key _ -> `TNat :: acc - | Script_typed_ir.Signature_key _ -> `TSignature :: acc - | Script_typed_ir.String_key _ -> `TString :: acc - | Script_typed_ir.Bytes_key _ -> `TBytes :: acc - | Script_typed_ir.Mutez_key _ -> `TMutez :: acc - | Script_typed_ir.Bool_key _ -> `TBool :: acc - | Script_typed_ir.Key_hash_key _ -> `TKey_hash :: acc - | Script_typed_ir.Key_key _ -> `TKey :: acc - | Script_typed_ir.Timestamp_key _ -> `TTimestamp :: acc - | Script_typed_ir.Chain_id_key _ -> `TChain_id :: acc - | Script_typed_ir.Address_key _ -> `TAddress :: acc - | Script_typed_ir.Pair_key ((lty, _), (rty, _), _) -> - tnames_of_comparable_type - lty - (tnames_of_comparable_type rty (`TPair :: acc)) - | Script_typed_ir.Union_key ((lty, _), (rty, _), _) -> - tnames_of_comparable_type - lty - (tnames_of_comparable_type rty (`TUnion :: acc)) - | Script_typed_ir.Option_key (ty, _) -> - tnames_of_comparable_type ty (`TOption :: acc) - -module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct - let algo = `Default - - let size = 16 -end) - -module Sampler = - Michelson_samplers.Make - (struct - let parameters = - { - base_parameters = - { - Michelson_samplers_base.int_size = {min = 8; max = 32}; - string_size = {min = 8; max = 128}; - bytes_size = {min = 8; max = 128}; - }; - list_size = {min = 10; max = 1000}; - set_size = {min = 10; max = 1000}; - map_size = {min = 10; max = 1000}; - } - end) - (Crypto_samplers) - -open Stats - -let tnames_dist : type_name list -> type_name Fin.Float.prb = - fun tnames -> - Emp.of_raw_data (Array.of_list tnames) - |> Fin.Float.counts_of_empirical (module Type_name_multiset) - |> Fin.Float.normalize - -let rec sample nsamples acc = - let open Sampling_helpers.M in - if nsamples = 0 then return acc - else - let* size = - Base_samplers.(sample_in_interval ~range:{min = 1; max = 1000}) - in - let* (Ex_ty ty) = Sampler.Random_type.m_type ~size in - let* acc = sample (nsamples - 1) acc in - return (tnames_of_type ty acc) - -let sample nsamples = sample nsamples [] - -let dist nsamples = - let open Sampling_helpers.M in - let* samples = sample nsamples in - return (tnames_dist samples) - -let () = - Format.printf - "stats:@.%a@." - Fin.Float.pp_fin_mes - (Fin.as_measure (dist 500 (Random.State.make [|0x1337; 0x533D|]))) diff --git a/src/proto_012_Psithaca/lib_benchmark/test/test_helpers.ml b/src/proto_012_Psithaca/lib_benchmark/test/test_helpers.ml deleted file mode 100644 index a27aed6768b6..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/test/test_helpers.ml +++ /dev/null @@ -1,83 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Tezos_error_monad.Error_monad - -let rng_state = Random.State.make [|42; 987897; 54120|] - -let print_script_expr fmtr (expr : Protocol.Script_repr.expr) = - Micheline_printer.print_expr - fmtr - (Micheline_printer.printable - Protocol.Michelson_v1_primitives.string_of_prim - expr) - -let print_script_expr_list fmtr (exprs : Protocol.Script_repr.expr list) = - Format.pp_print_list - ~pp_sep:(fun fmtr () -> Format.fprintf fmtr " :: ") - print_script_expr - fmtr - exprs - -let typecheck_by_tezos = - let context_init_memory ~rng_state = - Context.init - ~rng_state - ~initial_balances: - [ - 4_000_000_000_000L; - 4_000_000_000_000L; - 4_000_000_000_000L; - 4_000_000_000_000L; - 4_000_000_000_000L; - ] - 5 - >>=? fun (block, _accounts) -> - Incremental.begin_construction - ~timestamp:(Tezos_base.Time.Protocol.add block.header.shell.timestamp 30L) - block - >>=? fun vs -> - let ctxt = Incremental.alpha_ctxt vs in - (* Required for eg Create_contract *) - return - @@ Protocol.Alpha_context.Contract.init_origination_nonce - ctxt - Tezos_crypto.Operation_hash.zero - in - fun bef node -> - Stdlib.Result.get_ok - (Lwt_main.run - ( context_init_memory ~rng_state >>=? fun ctxt -> - let (Protocol.Script_ir_translator.Ex_stack_ty bef) = - Type_helpers.michelson_type_list_to_ex_stack_ty bef ctxt - in - Protocol.Script_ir_translator.parse_instr - Protocol.Script_ir_translator.Lambda - ctxt - ~legacy:false - (Micheline.root node) - bef - >|= Protocol.Environment.wrap_tzresult - >>=? fun _ -> return_unit )) diff --git a/src/proto_012_Psithaca/lib_benchmark/test/test_sampling_code.ml b/src/proto_012_Psithaca/lib_benchmark/test/test_sampling_code.ml deleted file mode 100644 index c637d3944e1f..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/test/test_sampling_code.ml +++ /dev/null @@ -1,98 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Tezos_benchmark - -(* Input parameter parsing *) - -let verbose = - if Array.length Sys.argv < 2 then ( - Format.eprintf "Executable expects random seed on input\n%!" ; - exit 1) - else - (Random.init (int_of_string Sys.argv.(1)) ; - List.exists (( = ) "-v")) - (Array.to_list Sys.argv) - -(* ------------------------------------------------------------------------- *) -(* Base sampler parameters *) - -let state = Random.State.make [|42; 987897; 54120|] - -module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct - let algo = `Default - - let size = 16 -end) - -module Michelson_base_samplers = Michelson_samplers_base.Make (struct - let parameters = - let size = {Base_samplers.min = 4; max = 32} in - { - Michelson_samplers_base.int_size = size; - string_size = size; - bytes_size = size; - } -end) - -(* ------------------------------------------------------------------------- *) -(* MCMC instantiation *) - -module Code = - Michelson_mcmc_samplers.Make_code_sampler - (Michelson_base_samplers) - (Crypto_samplers) - (struct - let rng_state = state - - let target_size = 500 - - let verbosity = if verbose then `Trace else `Silent - end) - -let start = Unix.gettimeofday () - -let generator = Code.generator ~burn_in:(500 * 7) state - -let stop = Unix.gettimeofday () - -let () = Format.printf "Burn in time: %f seconds@." (stop -. start) - -let _ = - for i = 1 to 1000 do - let Michelson_mcmc_samplers.{term = michelson; bef; aft} = - generator state - in - Test_helpers.typecheck_by_tezos bef michelson ; - if verbose then ( - Format.eprintf "result %d/1000:@." i ; - Format.eprintf - "type: %a => %a@." - Test_helpers.print_script_expr_list - bef - Test_helpers.print_script_expr_list - aft ; - Format.eprintf "%a@." Test_helpers.print_script_expr michelson) - done diff --git a/src/proto_012_Psithaca/lib_benchmark/test/test_sampling_data.ml b/src/proto_012_Psithaca/lib_benchmark/test/test_sampling_data.ml deleted file mode 100644 index a93671d4e102..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/test/test_sampling_data.ml +++ /dev/null @@ -1,87 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Tezos_benchmark - -(* Input parameter parsing *) - -let verbose = - if Array.length Sys.argv < 2 then ( - Format.eprintf "Executable expects random seed on input\n%!" ; - exit 1) - else - (Random.init (int_of_string Sys.argv.(1)) ; - List.exists (( = ) "-v")) - (Array.to_list Sys.argv) - -(* ------------------------------------------------------------------------- *) -(* MCMC instantiation *) - -let state = Random.State.make [|42; 987897; 54120|] - -module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct - let algo = `Default - - let size = 16 -end) - -module Michelson_base_samplers = Michelson_samplers_base.Make (struct - let parameters = - let size = {Base_samplers.min = 4; max = 32} in - { - Michelson_samplers_base.int_size = size; - string_size = size; - bytes_size = size; - } -end) - -module Data = - Michelson_mcmc_samplers.Make_data_sampler - (Michelson_base_samplers) - (Crypto_samplers) - (struct - let rng_state = state - - let target_size = 500 - - let verbosity = if verbose then `Trace else `Silent - end) - -let start = Unix.gettimeofday () - -let generator = Data.generator ~burn_in:(200 * 7) state - -let stop = Unix.gettimeofday () - -let () = Format.printf "Burn in time: %f seconds@." (stop -. start) - -let _ = - for _i = 0 to 1000 do - let Michelson_mcmc_samplers.{term = michelson; typ} = generator state in - if verbose then ( - Format.eprintf "result:@." ; - Format.eprintf "type: %a@." Test_helpers.print_script_expr typ ; - Format.eprintf "%a@." Test_helpers.print_script_expr michelson) - done diff --git a/src/proto_012_Psithaca/lib_benchmark/tezos-benchmark-012-Psithaca.opam b/src/proto_012_Psithaca/lib_benchmark/tezos-benchmark-012-Psithaca.opam deleted file mode 100644 index 542bbb9023fa..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/tezos-benchmark-012-Psithaca.opam +++ /dev/null @@ -1,32 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "tezos-tooling" { with-test } - "dune" { >= "2.9" } - "tezos-base" - "tezos-benchmark" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-012-Psithaca-test-helpers" - "tezos-protocol-012-Psithaca-parameters" - "tezos-micheline-rewriting" - "tezos-benchmark-type-inference-012-Psithaca" - "hashcons" - "benchmark-utils" - "tezos-012-Psithaca-test-helpers" - "prbnmcn-stats" { = "0.0.2" } - "tezos-micheline" { with-test } - "tezos-error-monad" { with-test } - "alcotest-lwt" { with-test } - -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: library for writing benchmarks (protocol-specific part)" diff --git a/src/proto_012_Psithaca/lib_benchmark/type_helpers.ml b/src/proto_012_Psithaca/lib_benchmark/type_helpers.ml deleted file mode 100644 index eea9a26d70ef..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/type_helpers.ml +++ /dev/null @@ -1,88 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Type conversion helpers *) - -open Protocol - -exception Type_helpers_error of string - -let helpers_error msg = raise (Type_helpers_error msg) - -(* Convert a Micheline-encoded type to its internal GADT format. *) -let michelson_type_to_ex_ty (typ : Alpha_context.Script.expr) - (ctxt : Alpha_context.t) = - Script_ir_translator.parse_ty - ctxt - ~legacy:false - ~allow_lazy_storage:false - ~allow_operation:false - ~allow_contract:false - ~allow_ticket:false - (Micheline.root typ) - |> Environment.wrap_tzresult - |> function - | Ok (ex_ty, _ctxt) -> ex_ty - | Error errs -> - let msg = - Format.asprintf - "Michelson_generation.michelson_type_to_ex_ty (%a)" - Error_monad.pp_print_trace - errs - in - helpers_error msg - -(* Convert a list of Micheline-encoded Michelson types to the - internal GADT format. *) -let rec michelson_type_list_to_ex_stack_ty - (stack_ty : Alpha_context.Script.expr list) ctxt = - let open Script_ir_translator in - let open Script_typed_ir in - match stack_ty with - | [] -> Ex_stack_ty Bot_t - | hd :: tl -> ( - let ex_ty = michelson_type_to_ex_ty hd ctxt in - match ex_ty with - | Ex_ty ty -> ( - let ex_stack_ty = michelson_type_list_to_ex_stack_ty tl ctxt in - match ex_stack_ty with - | Ex_stack_ty tl -> Ex_stack_ty (Item_t (ty, tl, None)))) - -let base_type_to_michelson_type (typ : Type.Base.t) = - let typ = Mikhailsky.map_var (fun _ -> Mikhailsky.unit_ty) typ in - Mikhailsky.to_michelson typ - -(* Convert a Mikhailsky stack to a list of Micheline-encoded types *) -let rec stack_type_to_michelson_type_list (typ : Type.Stack.t) = - let node = typ.node in - match node with - | Type.Stack.Stack_var_t _ -> - helpers_error "stack_type_to_michelson_type_list: bug found" - | Type.Stack.Empty_t -> [] - | Type.Stack.Item_t (ty, tl) -> - base_type_to_michelson_type ty :: stack_type_to_michelson_type_list tl - -let base_type_to_ex_ty ty = - michelson_type_to_ex_ty (base_type_to_michelson_type ty) diff --git a/src/proto_012_Psithaca/lib_benchmark/type_helpers.mli b/src/proto_012_Psithaca/lib_benchmark/type_helpers.mli deleted file mode 100644 index 1a041e001459..000000000000 --- a/src/proto_012_Psithaca/lib_benchmark/type_helpers.mli +++ /dev/null @@ -1,58 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Type conversion helpers *) - -open Protocol - -(** Exception raised in case an error occurs in this module. *) -exception Type_helpers_error of string - -(** [michelson_type_list_to_ex_stack_ty] converts a list of types in - Micheline form to a stack type in IR form. - - @raise Type_helpers_error if parsing the Michelson type fails. - *) -val michelson_type_list_to_ex_stack_ty : - Alpha_context.Script.expr list -> - Alpha_context.t -> - Script_ir_translator.ex_stack_ty - -(** [michelson_type_to_ex_ty ty ctxt] parses the type [ty]. - - @raise Type_helpers_error if an error arises during parsing. *) -val michelson_type_to_ex_ty : - Alpha_context.Script.expr -> Alpha_context.t -> Script_ir_translator.ex_ty - -(** [stack_type_to_michelson_type_list] converts a Mikhailsky stack type - to a stack represented as a list of Micheline expressions, each - element denoting a type on the stack type. - - @raise Type_helpers_error if the stack type contains variables. *) -val stack_type_to_michelson_type_list : Type.Stack.t -> Script_repr.expr list - -(** [base_type_to_ex_ty] converts a Mikhailsky type to a Michelson one. *) -val base_type_to_ex_ty : - Type.Base.t -> Alpha_context.t -> Script_ir_translator.ex_ty diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/.ocamlformat b/src/proto_012_Psithaca/lib_benchmarks_proto/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/cache_benchmarks.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/cache_benchmarks.ml deleted file mode 100644 index 3d96c3976834..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/cache_benchmarks.ml +++ /dev/null @@ -1,195 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** {2 [Alpha_context.Cache]-related benchmarks} *) - -let assert_ok_lwt x = - match Lwt_main.run x with Ok x -> x | Error _ -> assert false - -let assert_ok = function Ok x -> x | Error _ -> assert false - -module Admin = Alpha_context.Cache.Admin - -(** We can't construct a dummy cache client from outside the protocol. - We'll have to benchmark the {!Environment_cache} through the interface - exposed by {!Script_cache}. *) -module Cache = Script_cache - -(** { 2 Constructing a dummy cached value. } *) - -let make_context ~rng_state = - Execution_context.make ~rng_state |> assert_ok_lwt |> fst - -let throwaway_context = - let rng_state = Random.State.make [|0x1337; 0x533D|] in - make_context ~rng_state - -let dummy_script : Cache.cached_contract = - let str = "{ parameter unit; storage unit; code FAILWITH }" in - let storage = - let (parsed, _) = Michelson_v1_parser.parse_expression "Unit" in - Alpha_context.Script.lazy_expr parsed.expanded - in - let code = - let (parsed, _) = Michelson_v1_parser.parse_expression ~check:false str in - Alpha_context.Script.lazy_expr parsed.expanded - in - let script = Alpha_context.Script.{code; storage} in - let (ex_script, _) = - Script_ir_translator.parse_script - throwaway_context - ~legacy:true - ~allow_forged_in_storage:false - script - |> assert_ok_lwt - in - (script, ex_script) - -(** {2 Creating dummy cache value identifiers.} *) - -(** Configuration shared among all cache benchmarks. *) -module Cache_shared_config = struct - type config = unit - - let config_encoding = Data_encoding.unit - - let default_config = () - - type workload = {cache_cardinal : int} - - let workload_encoding = - let open Data_encoding in - conv - (fun {cache_cardinal} -> cache_cardinal) - (fun cache_cardinal -> {cache_cardinal}) - (obj1 (req "cache_cardinal" int31)) - - let tags = [Tags.cache] - - let workload_to_vector {cache_cardinal} = - Sparse_vec.String.of_list [("cache_cardinal", float_of_int cache_cardinal)] -end - -(* We can't produce a Script_cache.identifier without calling [Script_cache.find]. *) -let identifier_of_contract (c : Alpha_context.Contract.t) : Cache.identifier = - let (_, id, _) = Cache.find throwaway_context c |> assert_ok_lwt in - id - -let contract_of_int i : Alpha_context.Contract.t = - Alpha_context.Contract.of_b58check - Contract_hash.(to_b58check (hash_string [string_of_int i])) - |> assert_ok - -let identifier_of_int i = identifier_of_contract @@ contract_of_int i - -(** Prepare a context with a cache of the prescribed cardinality. A key in the domain of - the cache is returned along the context: this key is used to benchmark - (successful) cache accesses. *) -let prepare_context rng_state cache_cardinal = - assert (cache_cardinal > 0) ; - let ctxt = make_context ~rng_state in - let some_key_in_domain = identifier_of_int 0 in - let rec loop i ctxt = - if Compare.Int.(i = cache_cardinal) then ctxt - else - let key = identifier_of_int i in - loop (i + 1) (Cache.update ctxt key dummy_script 1 |> assert_ok) - in - (loop 0 ctxt, some_key_in_domain) - -(** Benchmark {!Script_cache.update}. This almost directly calls {!Environment_cache.update}. - We also use the result of this benchmark to assign a cost to {!Environment_cache.find}, - which alas can't be directly benchmarked from the interface provided by {!Script_cache}. *) -module Cache_update_benchmark : Benchmark.S = struct - include Cache_shared_config - - let name = "CACHE_UPDATE" - - let info = "Benchmarking the time it takes to update a key in the cache" - - (** It is expected that cache keys are non-adversarial, - ie do not share a long common prefix. This is the case for [Script_cache], - for which the keys are B58-encoded contract hashes. - - To rephrase: with high probability, comparing two keys in the domain of the cache is - a constant-time operation (two keys will differ after the first few characters). - We therefore do not take into account the length of the key in the model. *) - let model = - let affine_logn ~intercept ~coeff = - let open Model in - let module M = struct - type arg_type = int * unit - - module Def (X : Costlang.S) = struct - open X - - type model_type = size -> size - - let arity = arity_1 - - let model = - lam ~name:"size" @@ fun size -> - free ~name:intercept + (free ~name:coeff * log2 (int 1 + size)) - end - end in - (module M : Model_impl with type arg_type = int * unit) - in - (* Looking at the plots, it looks like this benchmark underestimates the constant term. - In the interpreter, this would warrant a dedicated benchmark for the intercept. *) - let intercept_variable = - Free_variable.of_string (Format.asprintf "%s_const" name) - in - let coeff_variable = - Free_variable.of_string (Format.asprintf "%s_coeff" name) - in - Model.make - ~conv:(function {cache_cardinal} -> (cache_cardinal, ())) - ~model:(affine_logn ~intercept:intercept_variable ~coeff:coeff_variable) - - let models = [("cache_model", model)] - - let cache_update_benchmark ctxt some_key_in_domain cache_cardinal = - let workload = {cache_cardinal} in - let closure () = - ignore (Cache.update ctxt some_key_in_domain dummy_script 1) - in - Generator.Plain {workload; closure} - - (** At the time of writing (Protocol H) the worst case execution path for - [Cache.update] is to update a key which is already present. *) - let make_bench rng_state _cfg () = - let cache_cardinal = - Base_samplers.sample_in_interval ~range:{min = 1; max = 100_000} rng_state - in - let (ctxt, some_key_in_domain) = prepare_context rng_state cache_cardinal in - cache_update_benchmark ctxt some_key_in_domain cache_cardinal - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Cache_update_benchmark) diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/dune b/src/proto_012_Psithaca/lib_benchmarks_proto/dune deleted file mode 100644 index 3b2e17f1f714..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/dune +++ /dev/null @@ -1,31 +0,0 @@ -(library - (name tezos_benchmarks_proto_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-benchmarks-proto-012-Psithaca) - (libraries - tezos-base - tezos-protocol-012-Psithaca - tezos-protocol-012-Psithaca-parameters - tezos-benchmark - tezos-benchmark-012-Psithaca - tezos-shell-benchmarks - tezos-micheline - tezos-012-Psithaca-test-helpers - tezos-sapling - tezos-client-012-Psithaca -) - (library_flags (:standard -linkall)) - (flags (:standard -open Tezos_stdlib - -open Tezos_base - -open Tezos_base__TzPervasives - -open Tezos_error_monad - -open Tezos_benchmark - -open Tezos_benchmark_012_Psithaca - -open Tezos_benchmark_type_inference_012_Psithaca - -open Tezos_protocol_012_Psithaca - -open Tezos_raw_protocol_012_Psithaca - -open Tezos_client_012_Psithaca - -open Tezos_crypto - -open Tezos_micheline - -open Tezos_012_Psithaca_test_helpers - -open Tezos_client_012_Psithaca))) diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/dune-project b/src/proto_012_Psithaca/lib_benchmarks_proto/dune-project deleted file mode 100644 index b0ebb71b4a03..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(name tezos-benchmarks-proto-alpha) -(formatting (enabled_for ocaml)) diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/encodings_benchmarks.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/encodings_benchmarks.ml deleted file mode 100644 index 0dc9f3212bc4..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/encodings_benchmarks.ml +++ /dev/null @@ -1,432 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -module Micheline_common = struct - let make_printable node = - Micheline_printer.printable - Michelson_v1_primitives.string_of_prim - (Micheline.strip_locations node) - - type phase = Trace_production | In_protocol | Global - - type error = - | Bad_micheline of { - benchmark_name : string; - micheline : Alpha_context.Script.node; - phase : phase; - } - - exception Micheline_benchmark of error - - let pp_phase fmtr (phase : phase) = - match phase with - | Trace_production -> Format.fprintf fmtr "trace production" - | In_protocol -> Format.fprintf fmtr "in protocol" - | Global -> Format.fprintf fmtr "global" - - let pp_error fmtr = function - | Bad_micheline {benchmark_name; micheline; phase} -> - Format.open_vbox 1 ; - Format.fprintf fmtr "Bad micheline:@," ; - Format.fprintf fmtr "benchmark = %s@," benchmark_name ; - Format.fprintf - fmtr - "expression = @[%a@]@," - Micheline_printer.print_expr - (make_printable micheline) ; - Format.fprintf fmtr "phase = %a@," pp_phase phase ; - Format.close_box () - - let bad_micheline benchmark_name micheline phase = - raise - (Micheline_benchmark (Bad_micheline {benchmark_name; micheline; phase})) - - type workload = {size : Size.micheline_size; bytes : int} - - let workload_encoding = - let open Data_encoding in - def "encoding_micheline_trace" - @@ conv - (fun {size; bytes} -> (size, bytes)) - (fun (size, bytes) -> {size; bytes}) - (obj2 - (req "micheline_size" Size.micheline_size_encoding) - (req "micheline_bytes" Size.encoding)) - - let workload_to_vector (workload : workload) = - let keys = - [ - ("encoding_micheline_traversal", Size.to_float workload.size.traversal); - ("encoding_micheline_int_bytes", Size.to_float workload.size.int_bytes); - ( "encoding_micheline_string_bytes", - Size.to_float workload.size.string_bytes ); - ("encoding_micheline_bytes", Size.to_float workload.bytes); - ] - in - Sparse_vec.String.of_list keys - - let tags = [Tags.encoding] - - let model_size name = - Model.make - ~conv:(fun {size = {Size.traversal; int_bytes; string_bytes}; _} -> - (traversal, (int_bytes, (string_bytes, ())))) - ~model: - (Model.trilinear - ~coeff1: - (Free_variable.of_string - (Format.asprintf "%s_micheline_traversal" name)) - ~coeff2: - (Free_variable.of_string - (Format.asprintf "%s_micheline_int_bytes" name)) - ~coeff3: - (Free_variable.of_string - (Format.asprintf "%s_micheline_string_bytes" name))) - - let model_bytes name = - Model.make - ~conv:(fun {bytes; _} -> (bytes, ())) - ~model: - (Model.linear - ~coeff: - (Free_variable.of_string - (Format.asprintf "%s_micheline_bytes" name))) - - let models name = - [("micheline", model_size name); ("micheline_bytes", model_bytes name)] -end - -module Encoding_micheline : Benchmark.S = struct - include Translator_benchmarks.Config - include Micheline_common - - let name = "ENCODING_MICHELINE" - - let info = "Benchmarking strip_location + encoding of Micheline to bytes" - - let micheline_serialization_trace (micheline_node : Alpha_context.Script.node) - = - match - Data_encoding.Binary.to_string - Protocol.Script_repr.expr_encoding - (Micheline.strip_locations micheline_node) - with - | Error err -> - Format.eprintf - "micheline_serialization_trace: %a@." - Data_encoding.Binary.pp_write_error - err ; - None - | Ok str -> - let micheline_size = Size.of_micheline micheline_node in - Some {size = micheline_size; bytes = Size.string str} - - let encoding_micheline_benchmark (node : Protocol.Script_repr.expr) = - let node = Micheline.root node in - let workload = - match micheline_serialization_trace node with - | None -> Micheline_common.bad_micheline name node Trace_production - | Some trace -> trace - in - let closure () = - try - ignore - (Data_encoding.Binary.to_string_exn - Protocol.Script_repr.expr_encoding - (Micheline.strip_locations node)) - with _ -> Micheline_common.bad_micheline name node In_protocol - in - Generator.Plain {workload; closure} - - let make_bench rng_state cfg () = - let Michelson_mcmc_samplers.{term; typ = _} = - Michelson_generation.make_data_sampler rng_state cfg.generator_config - in - encoding_micheline_benchmark term - - let create_benchmarks ~rng_state ~bench_num config = - match config.michelson_terms_file with - | Some file -> - Format.eprintf "Loading terms from %s@." file ; - let terms = Michelson_mcmc_samplers.load ~filename:file in - List.map - (function - | Michelson_mcmc_samplers.Data {term; typ = _} - | Michelson_mcmc_samplers.Code {term; bef = _; aft = _} -> - fun () -> encoding_micheline_benchmark term) - terms - | None -> List.repeat bench_num (make_bench rng_state config) - - let models = models name -end - -let () = Registration_helpers.register (module Encoding_micheline) - -module Decoding_micheline : Benchmark.S = struct - include Translator_benchmarks.Config - include Micheline_common - - let name = "DECODING_MICHELINE" - - let info = "Decoding of bytes to Micheline" - - let micheline_deserialization_trace (micheline_str : string) = - match - Data_encoding.Binary.of_string - Protocol.Script_repr.expr_encoding - micheline_str - with - | Error err -> - Format.eprintf - "micheline_deserialization_trace: %a@." - Data_encoding.Binary.pp_read_error - err ; - None - | Ok micheline_node -> - let micheline_size = - Size.of_micheline (Micheline.root micheline_node) - in - Some {size = micheline_size; bytes = Size.string micheline_str} - - let decoding_micheline_benchmark (node : Protocol.Script_repr.expr) = - let encoded = - Data_encoding.Binary.to_string_exn Protocol.Script_repr.expr_encoding node - in - let node = Micheline.root node in - let workload = - match micheline_deserialization_trace encoded with - | None -> bad_micheline name node Trace_production - | Some trace -> trace - in - let closure () = - try - ignore - (Data_encoding.Binary.of_string_exn - Protocol.Script_repr.expr_encoding - encoded) - with _ -> bad_micheline name node In_protocol - in - Generator.Plain {workload; closure} - - let make_bench rng_state cfg () = - let Michelson_mcmc_samplers.{term; typ = _} = - Michelson_generation.make_data_sampler rng_state cfg.generator_config - in - decoding_micheline_benchmark term - - let create_benchmarks ~rng_state ~bench_num config = - match config.michelson_terms_file with - | Some file -> - Format.eprintf "Loading terms from %s@." file ; - let terms = Michelson_mcmc_samplers.load ~filename:file in - List.map - (function - | Michelson_mcmc_samplers.Data {term; typ = _} - | Michelson_mcmc_samplers.Code {term; bef = _; aft = _} -> - fun () -> decoding_micheline_benchmark term) - terms - | None -> List.repeat bench_num (make_bench rng_state config) - - let models = models name -end - -let () = Registration_helpers.register (module Decoding_micheline) - -(* TODO: benchmark timestamps with big values (>64 bits) *) -module Timestamp = struct - let () = - Registration_helpers.register - @@ - let open Tezos_shell_benchmarks.Encoding_benchmarks_helpers in - fixed_size_shared - ~name:"TIMESTAMP_READABLE_ENCODING" - ~generator:(fun rng_state -> - let seconds_in_year = 30_000_000 in - let offset = Random.State.int rng_state seconds_in_year in - Alpha_context.Script_timestamp.of_zint (Z.of_int (1597764116 + offset))) - ~make_bench:(fun generator () -> - let tstamp_string = generator () in - let closure () = - ignore (Alpha_context.Script_timestamp.to_string tstamp_string) - in - Generator.Plain {workload = (); closure}) - - let () = - Registration_helpers.register - @@ - let open Tezos_shell_benchmarks.Encoding_benchmarks_helpers in - fixed_size_shared - ~name:"TIMESTAMP_READABLE_DECODING" - ~generator:(fun rng_state -> - let seconds_in_year = 30_000_000 in - let offset = Random.State.int rng_state seconds_in_year in - let tstamp = - Alpha_context.Script_timestamp.of_zint - (Z.of_int (1597764116 + offset)) - in - Alpha_context.Script_timestamp.to_string tstamp) - ~make_bench:(fun generator () -> - let tstamp_string = generator () in - let closure () = - ignore (Alpha_context.Script_timestamp.of_string tstamp_string) - in - Generator.Plain {workload = (); closure}) -end - -(* when benchmarking, compile bls12-381-unix without ADX, see - https://gitlab.com/dannywillems/ocaml-bls12-381/-/blob/71d0b4d467fbfaa6452d702fcc408d7a70916a80/README.md#install -*) -module BLS = struct - open Tezos_shell_benchmarks.Encoding_benchmarks_helpers - - let () = - Registration_helpers.register - @@ make_encode_fixed_size_to_bytes - ~name:"ENCODING_BLS_FR" - ~to_bytes:Bls12_381.Fr.to_bytes - ~generator:(fun rng_state -> Bls12_381.Fr.random ~state:rng_state ()) - - let () = - Registration_helpers.register - @@ make_encode_fixed_size_to_bytes - ~name:"ENCODING_BLS_G1" - ~to_bytes:Bls12_381.G1.to_bytes - ~generator:(fun rng_state -> Bls12_381.G1.random ~state:rng_state ()) - - let () = - Registration_helpers.register - @@ make_encode_fixed_size_to_bytes - ~name:"ENCODING_BLS_G2" - ~to_bytes:Bls12_381.G2.to_bytes - ~generator:(fun rng_state -> Bls12_381.G2.random ~state:rng_state ()) - - let () = - Registration_helpers.register - @@ make_decode_fixed_size_from_bytes - ~name:"DECODING_BLS_FR" - ~to_bytes:Bls12_381.Fr.to_bytes - ~from_bytes:Bls12_381.Fr.of_bytes_exn - ~generator:(fun rng_state -> Bls12_381.Fr.random ~state:rng_state ()) - - let () = - Registration_helpers.register - @@ make_decode_fixed_size_from_bytes - ~name:"DECODING_BLS_G1" - ~to_bytes:Bls12_381.G1.to_bytes - ~from_bytes:Bls12_381.G1.of_bytes_exn - ~generator:(fun rng_state -> Bls12_381.G1.random ~state:rng_state ()) - - let () = - Registration_helpers.register - @@ make_decode_fixed_size_from_bytes - ~name:"DECODING_BLS_G2" - ~to_bytes:Bls12_381.G2.to_bytes - ~from_bytes:Bls12_381.G2.of_bytes_exn - ~generator:(fun rng_state -> Bls12_381.G2.random ~state:rng_state ()) - - let () = - Registration_helpers.register - @@ fixed_size_shared - ~name:"BLS_FR_FROM_Z" - ~generator:(fun rng_state -> Bls12_381.Fr.random ~state:rng_state ()) - ~make_bench:(fun generator () -> - let generated = generator () in - let z = Bls12_381.Fr.to_z generated in - let closure () = ignore (Bls12_381.Fr.of_z z) in - Generator.Plain {workload = (); closure}) - - let () = - Registration_helpers.register - @@ fixed_size_shared - ~name:"BLS_FR_TO_Z" - ~generator:(fun rng_state -> Bls12_381.Fr.random ~state:rng_state ()) - ~make_bench:(fun generator () -> - let generated = generator () in - let closure () = ignore (Bls12_381.Fr.to_z generated) in - Generator.Plain {workload = (); closure}) -end - -module Timelock = struct - open Tezos_shell_benchmarks.Encoding_benchmarks_helpers - - let generator rng_state = - let log_time = - Base_samplers.sample_in_interval ~range:{min = 0; max = 29} rng_state - in - let time = Random.State.int rng_state (Int.shift_left 1 log_time) in - let plaintext_size = - Base_samplers.sample_in_interval ~range:{min = 1; max = 10000} rng_state - in - let (chest, chest_key) = - Timelock.chest_sampler ~plaintext_size ~time ~rng_state - in - ((chest, chest_key), plaintext_size) - - let () = - Registration_helpers.register - @@ make_encode_variable_size_to_string - ~name:"ENCODING_Chest" - ~to_string:(Data_encoding.Binary.to_string_exn Timelock.chest_encoding) - ~generator:(fun rng_state -> - let ((chest, _), plaintext_size) = generator rng_state in - (chest, {bytes = plaintext_size})) - - let () = - Registration_helpers.register - @@ make_encode_fixed_size_to_string - ~name:"ENCODING_Chest_key" - ~to_string: - (Data_encoding.Binary.to_string_exn Timelock.chest_key_encoding) - ~generator:(fun rng_state -> - let ((_, chest_key), _w) = generator rng_state in - chest_key) - - let () = - Registration_helpers.register - @@ make_decode_variable_size_from_bytes - ~name:"DECODING_Chest" - ~to_bytes:(Data_encoding.Binary.to_bytes_exn Timelock.chest_encoding) - ~from_bytes:(Data_encoding.Binary.of_bytes_exn Timelock.chest_encoding) - ~generator:(fun rng_state -> - let ((chest, _), _) = generator rng_state in - let b = - Data_encoding.Binary.to_bytes_exn Timelock.chest_encoding chest - in - (chest, {bytes = Bytes.length b})) - - let () = - Registration_helpers.register - @@ make_decode_fixed_size_from_bytes - ~name:"DECODING_Chest_key" - ~to_bytes: - (Data_encoding.Binary.to_bytes_exn Timelock.chest_key_encoding) - ~from_bytes: - (Data_encoding.Binary.of_bytes_exn Timelock.chest_key_encoding) - ~generator:(fun rng_state -> - let ((_, chest_key), _w) = generator rng_state in - chest_key) -end diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/gas_helpers.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/gas_helpers.ml deleted file mode 100644 index bf8bcde60256..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/gas_helpers.ml +++ /dev/null @@ -1,36 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -let set_limit ctxt = - Alpha_context.Gas.set_limit - ctxt - (Alpha_context.Gas.Arith.integral_of_int_exn 999_999_999_999) - -let fp_to_z (fp : Alpha_context.Gas.Arith.fp) = - let open Data_encoding in - Binary.to_bytes_exn Alpha_context.Gas.Arith.z_fp_encoding fp - |> Binary.of_bytes_exn z diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/global_constants_storage_benchmarks.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/global_constants_storage_benchmarks.ml deleted file mode 100644 index bb8fc4e2c898..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/global_constants_storage_benchmarks.ml +++ /dev/null @@ -1,727 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* This module includes benchmarks for [Global_constants_storage.expand] - and [Global_constants_storage.Internal_for_tests.expr_to_address_in_context]. - The other main function exported by [Global_constants_storage] is [register]; - however, [register] calls [expand] and does little else, and thus does - not need to be further carbonated. - - In the process of creating these benchmarks, we benchmarked several OCaml - stdlib functions and [Script_expr_hash.of_b58check_opt]. While these cost - models are not used in the protocol, they are kept here to ensure the - assumptions underlying [register] and [expand] don't change out - from under us.*) - -open Tezos_benchmark -open Tezos_micheline -open Protocol - -let assert_ok_lwt x = - match Lwt_main.run x with - | Ok x -> x - | Error errs -> - Format.eprintf "%a" pp_print_trace errs ; - exit 1 - -let assert_ok = function - | Ok x -> x - | Error errs -> - Format.eprintf "%a" pp_print_trace errs ; - exit 1 - -(** [seq_of_n_constants n hash] generates a Seq filled - with [n] constant primitives containing [hash] *) -let seq_of_n_constants n hash = - let open Micheline in - Seq - ( -1, - Stdlib.List.init n (fun _ -> - Prim (-1, Michelson_v1_primitives.H_constant, [String (-1, hash)], [])) - ) - -(** Computes the b58check hash of a Micheline node as a string. *) -let node_to_hash node = - let expr_bytes = - Micheline.strip_locations node - |> Script_repr.lazy_expr |> Script_repr.force_bytes |> Stdlib.Result.get_ok - in - Script_expr_hash.hash_bytes [expr_bytes] |> Script_expr_hash.to_b58check - -(* An ad-hoc sampler for Micheline values. Boltzmann sampling would do well - here. - - Copied from lib_micheline and modified to use [Michelson_v1_primitives.prim]. *) -module Micheline_sampler = struct - type node = Alpha_context.Script.node - - let prims = - let open Protocol.Michelson_v1_primitives in - [| - K_parameter; - K_storage; - K_code; - D_False; - D_Elt; - D_Left; - D_None; - D_Pair; - D_Right; - D_Some; - D_True; - D_Unit; - I_PACK; - I_UNPACK; - I_BLAKE2B; - I_SHA256; - I_SHA512; - I_ABS; - I_ADD; - I_AMOUNT; - I_AND; - I_BALANCE; - I_CAR; - I_CDR; - I_CHAIN_ID; - I_CHECK_SIGNATURE; - I_COMPARE; - I_CONCAT; - I_CONS; - I_CREATE_ACCOUNT; - I_CREATE_CONTRACT; - I_IMPLICIT_ACCOUNT; - I_DIP; - I_DROP; - I_DUP; - I_EDIV; - I_EMPTY_BIG_MAP; - I_EMPTY_MAP; - I_EMPTY_SET; - I_EQ; - I_EXEC; - I_APPLY; - I_FAILWITH; - I_GE; - I_GET; - I_GET_AND_UPDATE; - I_GT; - I_HASH_KEY; - I_IF; - I_IF_CONS; - I_IF_LEFT; - I_IF_NONE; - I_INT; - I_LAMBDA; - I_LE; - I_LEFT; - I_LEVEL; - I_LOOP; - I_LSL; - I_LSR; - I_LT; - I_MAP; - I_MEM; - I_MUL; - I_NEG; - I_NEQ; - I_NIL; - I_NONE; - I_NOT; - I_NOW; - I_OR; - I_PAIR; - I_UNPAIR; - I_PUSH; - I_RIGHT; - I_SIZE; - I_SOME; - I_SOURCE; - I_SENDER; - I_SELF; - I_SELF_ADDRESS; - I_SLICE; - I_STEPS_TO_QUOTA; - I_SUB; - I_SWAP; - I_TRANSFER_TOKENS; - I_SET_DELEGATE; - I_UNIT; - I_UPDATE; - I_XOR; - I_ITER; - I_LOOP_LEFT; - I_ADDRESS; - I_CONTRACT; - I_ISNAT; - I_CAST; - I_RENAME; - I_SAPLING_EMPTY_STATE; - I_SAPLING_VERIFY_UPDATE; - I_DIG; - I_DUG; - I_NEVER; - I_VOTING_POWER; - I_TOTAL_VOTING_POWER; - I_KECCAK; - I_SHA3; - I_PAIRING_CHECK; - I_TICKET; - I_READ_TICKET; - I_SPLIT_TICKET; - I_JOIN_TICKETS; - T_bool; - T_contract; - T_int; - T_key; - T_key_hash; - T_lambda; - T_list; - T_map; - T_big_map; - T_nat; - T_option; - T_or; - T_pair; - T_set; - T_signature; - T_string; - T_bytes; - T_mutez; - T_timestamp; - T_unit; - T_operation; - T_address; - T_sapling_transaction; - T_sapling_state; - T_chain_id; - T_never; - T_bls12_381_g1; - T_bls12_381_g2; - T_bls12_381_fr; - T_ticket - (* We don't want constants in our generator, else the constants - functions might fail because it's ill-formed. *) - (* H_constant; *); - |] - - module Sampler = Micheline_sampler.Make (struct - type prim = Michelson_v1_primitives.prim - - let sample_prim : Michelson_v1_primitives.prim Base_samplers.sampler = - fun rng_state -> - let i = Random.State.int rng_state (Array.length prims) in - prims.(i) - - let sample_annots : string list Base_samplers.sampler = fun _rng_state -> [] - - let sample_string _ = "" - - let sample_bytes _ = Bytes.empty - - let sample_z _ = Z.zero - - let width_function = Micheline_sampler.reasonable_width_function - end) - - let sample = Sampler.sample - - type size = {nodes : int; bytes : int} - - let int z = {nodes = 1; bytes = (Z.numbits z + 7) / 8} - - let string s = {nodes = 1; bytes = String.length s} - - let bytes b = {nodes = 1; bytes = Bytes.length b} - - let node = {nodes = 1; bytes = 0} - - let ( @+ ) x y = {nodes = x.nodes + y.nodes; bytes = x.bytes + y.bytes} - - let micheline_size (n : node) = - let rec micheline_size n acc = - let open Micheline in - match n with - | Int (_, i) -> acc @+ int i - | String (_, s) -> acc @+ string s - | Bytes (_, b) -> acc @+ bytes b - | Seq (_, terms) -> - List.fold_left - (fun acc term -> micheline_size term acc) - (acc @+ node) - terms - | Prim (_, _, terms, _) -> - List.fold_left - (fun acc term -> micheline_size term acc) - (acc @+ node) - terms - in - micheline_size n {nodes = 0; bytes = 0} -end - -(** Cost model and benchmarks for set element addition from the - OCaml stdlib. - - The cost model is not currently used - in the protocol, but we include the benchmarks to validate our - assumptions about functions that use this. *) -module Set_add : Benchmark.S = struct - let name = "Set_add" - - let info = - "Benchmarks and cost model for set element addition from OCaml stdlib." - - let tags = ["global_constants"] - - type config = unit - - let config_encoding = Data_encoding.unit - - let default_config = () - - type workload = int - - let workload_encoding = Data_encoding.int31 - - let workload_to_vector : workload -> Sparse_vec.String.t = - fun size -> Sparse_vec.String.of_list [("size", float_of_int size)] - - (* As an OCaml set is a balanced binary tree, complexity is O(log n). *) - let models = - [ - ( "Set_add", - Model.( - make - ~conv:(fun size -> (size, ())) - ~model:(logn ~coeff:(Free_variable.of_string "size"))) ); - ] - - module Int_set = Set.Make (Int) - - let create_benchmark rng_state _config () = - let range : Base_samplers.range = {min = 0; max = 10_000} in - let size = Base_samplers.sample_in_interval ~range rng_state in - let set = Stdlib.List.init size Fun.id |> Int_set.of_list in - let closure () = ignore (Int_set.add (size + 1) set) in - Generator.Plain {workload = size; closure} - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (create_benchmark rng_state config) -end - -let () = - Registration_helpers.register (module Set_add) ; - Registration_helpers.register_for_codegen - "Set_add" - (Model.For_codegen - (WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc ~equal:String.equal "Set_add" Set_add.models)) - -(** Cost model and benchmarks for set elements from the - OCaml stdlib. - - The cost model is not currently used - in the protocol, but we include the benchmarks to validate our - assumptions about functions that use this. *) -module Set_elements : Benchmark.S = struct - let name = "Set_elements" - - let info = "Benchmarks and cost model for set elements from OCaml stdlib." - - let tags = ["global_constants"] - - type config = unit - - let config_encoding = Data_encoding.unit - - let default_config = () - - type workload = int - - let workload_encoding = Data_encoding.int31 - - let workload_to_vector : workload -> Sparse_vec.String.t = - fun size -> Sparse_vec.String.of_list [("size", float_of_int size)] - - (* Cost of retrieving all elements from the set is linear with the size - of the set.*) - let models = - [ - ( "Set_elements", - Model.( - make - ~conv:(fun size -> (size, ())) - ~model:(linear ~coeff:(Free_variable.of_string "size"))) ); - ] - - module Int_set = Set.Make (Int) - - let create_benchmark rng_state _config () = - let range : Base_samplers.range = {min = 0; max = 10_000} in - let size = Base_samplers.sample_in_interval ~range rng_state in - let set = Stdlib.List.init size (fun x -> x) |> Int_set.of_list in - let closure () = ignore (Int_set.elements set) in - Generator.Plain {workload = size; closure} - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (create_benchmark rng_state config) -end - -let () = - Registration_helpers.register (module Set_elements) ; - Registration_helpers.register_for_codegen - "Set_elements" - (Model.For_codegen - (WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc ~equal:String.equal "Set_elements" Set_elements.models)) - -(** Cost model and benchmarks for [Script_expr_hash.of_b58_check_opt]. - Under the hood this function uses the [Blake2b] functor, which uses - the HACL* crypto library. - - The cost model is not currently used - in the protocol, but we include the benchmarks to validate our - assumptions about functions that use this. *) -module Script_expr_hash_of_b58check_opt : Benchmark.S = struct - let name = "Script_expr_hash_of_b58check_opt" - - let info = "Benchmark for Script_expr_hash.of_b58check_opt" - - let tags = ["global_constants"] - - type config = unit - - let config_encoding = Data_encoding.unit - - let default_config = () - - type workload = Micheline_sampler.size - - let workload_encoding = - let open Data_encoding in - conv - (fun Micheline_sampler.{nodes; bytes} -> (nodes, bytes)) - (fun (nodes, bytes) -> {nodes; bytes}) - (obj2 (req "nodes" int31) (req "bytes" int31)) - - let workload_to_vector Micheline_sampler.{nodes; bytes} = - Sparse_vec.String.of_list - [("nodes", float_of_int nodes); ("bytes", float_of_int bytes)] - - (* On testing we found that this function is a constant - time operation. However, to test this, we use an affine model. If - our assumption holds, the coefficient should be near zero. *) - let models = - [ - ( "Script_expr_hash_of_b58check_opt", - Model.( - make - ~conv:(fun Micheline_sampler.{nodes; _} -> (nodes, ())) - ~model: - (Model.affine - ~intercept:(Free_variable.of_string "b58_check_cost") - ~coeff:(Free_variable.of_string "size"))) ); - ] - - (* To create realistic benchmarks, we generate a random Micheline expression, - hash it, then benchmark the cost of validating the hash. *) - let create_benchmark rng_state _config () = - let open Protocol in - let term = Micheline_sampler.sample rng_state in - let size = Micheline_sampler.micheline_size term in - let expr_encoding = Alpha_context.Script.expr_encoding in - let lazy_expr = - Data_encoding.make_lazy expr_encoding (Micheline.strip_locations term) - in - let expr_bytes = Data_encoding.force_bytes lazy_expr in - let hash = Script_expr_hash.hash_bytes [expr_bytes] in - let hash_str = Script_expr_hash.to_b58check hash in - let closure () = ignore (Script_expr_hash.of_b58check_opt hash_str) in - Generator.Plain {workload = size; closure} - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (create_benchmark rng_state config) -end - -let () = - Registration_helpers.register (module Script_expr_hash_of_b58check_opt) ; - Registration_helpers.register_for_codegen - "Script_expr_hash_of_b58check_opt" - (Model.For_codegen - (WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc - ~equal:String.equal - "Script_expr_hash_of_b58check_opt" - Script_expr_hash_of_b58check_opt.models)) - -module Global_constants_storage_expr_to_address_in_context : Benchmark.S = -struct - let name = "Global_constants_storage_expr_to_address_in_context" - - let info = - "Benchmark for the \ - Global_constants_storage.Internal_for_tests.expr_to_address_in_context \ - function" - - let tags = ["global_constants"] - - type config = unit - - let config_encoding = Data_encoding.unit - - let default_config = () - - type workload = int - - let workload_encoding = Data_encoding.int31 - - let workload_to_vector : workload -> Sparse_vec.String.t = - fun size -> Sparse_vec.String.of_list [("size", float_of_int size)] - - (** The cost of a Blake2b hashing function is linear with the size of the input *) - let models = - [ - ( "Global_constants_storage_expr_to_address_in_context", - Model.( - make - ~conv:(fun size -> (size, ())) - ~model:(linear ~coeff:(Free_variable.of_string "size"))) ); - ] - - let create_benchmark rng_state _config () = - let open Micheline in - let expr = Micheline_sampler.sample rng_state |> strip_locations in - let b = - Script_repr.lazy_expr expr |> Script_repr.force_bytes - |> Environment.wrap_tzresult |> assert_ok - in - let size = Bytes.length b in - - let closure () = ignore (Script_expr_hash.hash_bytes [b]) in - Generator.Plain {workload = size; closure} - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (create_benchmark rng_state config) -end - -let () = - Registration_helpers.register - (module Global_constants_storage_expr_to_address_in_context) ; - Registration_helpers.register_for_codegen - "Global_constants_storage_expr_to_address_in_context" - (Model.For_codegen - (WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc - ~equal:String.equal - "Global_constants_storage_expr_to_address_in_context" - Global_constants_storage_expr_to_address_in_context.models)) - -(** [Global_constants_storage.expand] traverses a Micheline node, - searching for constants and replacing them with their values - retrieved from storage. - - There are three branches in the iterations of [Global_constants_storage.expand] - can take, each with different costs: - - Branch 1: The first time a particular constant is found, the hash is parsed with - [Script_expr_hash.of_b58check_opt], and its value is retrieved - from storage. This storage call (implemented [Global_constants_storage.get]) - is already carbonated and dominates the cost in this case, so do not need to - benchmark Branch 1 - the benchmarks for storage access are sufficient. - - Branch 2: If the same constant is found a subsequent time, its value is looked up - in a map. On testing we determined that the cost of [Script_expr_hash.of_b58check_opt] - dominates the cost of this branch - the cost of an OCaml map lookup is O(log 2 n), and - n has to be unreasonably large to catch up to the constant time cost of validating the - hash. - - Branch 3: When no constant is found, the cost is merely that of pattern matching - and calling the continuation (similar to that of [Micheline.strip_locations]). - - Because we don't know the full size of node being traversed ahead of time (because they - are retrieved from storage), it is impossible to calculate the full gas cost upfront. - However, each time we find a new expression to traverse, we can calculate its size upfront - and charge the cost of all Branch 3 cases. We can then do an additional charge for Branch 2 - each time we find a constant, and let storage handle charging for Branch 1. - - Below are models for Branch 2 and 3 respectively. - *) -module Global_constants_storage_expand_models = struct - module Global_constants_storage_expand_constant_branch : Benchmark.S = struct - let name = "Global_constants_storage_expand_constant_branch" - - let info = - "Benchmark for the constant branch Global_constants_storage.expand \ - function" - - let tags = ["global_constants"] - - type config = unit - - let config_encoding = Data_encoding.unit - - let default_config = () - - type workload = int - - let workload_encoding = Data_encoding.int31 - - let workload_to_vector : workload -> Sparse_vec.String.t = - fun constants -> - Sparse_vec.String.of_list - [("number of constants", float_of_int constants)] - - (** The cost of Branch 2 is linear to the number of constants in the expression. As - discussed above, the constant time operation [Script_expr_hash.of_b58check_opt] - dominates the cost of each iteration. *) - let models = - [ - ( "Global_constants_storage_expand_constant_branch", - Model.( - make - ~conv:(fun size -> (size, ())) - ~model: - (linear ~coeff:(Free_variable.of_string "number of constants"))) - ); - ] - - (* To test Branch 2 as nearly as possible, we generate a Micheline Seq - consisting of the same constant repeated n times. As n increases, - the benchmark more closely approximates the true cost of Branch 2. *) - let create_benchmark rng_state _config () = - let open Micheline in - let node = Micheline_sampler.sample rng_state in - let size = (Micheline_sampler.micheline_size node).nodes in - let registered_constant = Int (-1, Z.of_int 1) in - let hash = registered_constant |> node_to_hash in - let (context, _) = Execution_context.make ~rng_state |> assert_ok_lwt in - let (context, _, _) = - Alpha_context.Global_constants_storage.register - context - (strip_locations registered_constant) - >|= Environment.wrap_tzresult |> assert_ok_lwt - in - let node = seq_of_n_constants size hash in - let closure () = - ignore - (Lwt_main.run - @@ Alpha_context.Global_constants_storage.expand - context - (strip_locations node)) - in - Generator.Plain {workload = size; closure} - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (create_benchmark rng_state config) - end - - let () = - Registration_helpers.register - (module Global_constants_storage_expand_constant_branch) ; - Registration_helpers.register_for_codegen - "Global_constants_storage_expand_constant_branch" - (Model.For_codegen - (WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc - ~equal:String.equal - "Global_constants_storage_expand_constant_branch" - Global_constants_storage_expand_constant_branch.models)) - - module Global_constants_storage_expand_no_constant_branch : Benchmark.S = - struct - let name = "Global_constants_storage_expand_no_constant_branch" - - let info = - "Benchmark for the Global_constants_storage.expand function on the case \ - without constants" - - let tags = ["global_constants"] - - type config = unit - - let config_encoding = Data_encoding.unit - - let default_config = () - - type workload = int - - let workload_encoding = Data_encoding.int31 - - let workload_to_vector : workload -> Sparse_vec.String.t = - fun size -> - Sparse_vec.String.of_list [("number of nodes", float_of_int size)] - - (* The cost of Branch 3 is the cost of traversing a single node. It - is therefore linear to the number of nodes being traversed. This is - very similar to [Micheline.strip_locations]. - - On testing I observed that while the linear model was accurate - for small numbers of nodes, after 1000 nodes the cost seems to increase more - than linearly. I think I would have to fine tune the sampler to better test - past this amount; however, I don't think it's necessary - to get large orders - of nodes, you need to use constants, in which case the cost of - [Script_expr_hash.of_b58check_opt] will dominate. A n*log(n) model seems - accurate enough for the range of values tested. - *) - let models = - [ - ( "Global_constants_storage_expand_no_constant_branch", - Model.( - make - ~conv:(fun size -> (size, ())) - ~model: - (nlogn - ~intercept:(Free_variable.of_string "cst") - ~coeff:(Free_variable.of_string "number of nodes"))) ); - ] - - (** We benchmark this by generating a random Micheline expression without constants - and calling [expand] on it. This causes the function to spend all its time in - Branch 3. *) - let create_benchmark rng_state _config () = - let open Micheline in - let node = Micheline_sampler.sample rng_state in - let size = (Micheline_sampler.micheline_size node).nodes in - let (context, _) = Execution_context.make ~rng_state |> assert_ok_lwt in - let expr = strip_locations node in - let closure () = - ignore - (Lwt_main.run - @@ Alpha_context.Global_constants_storage.expand context expr) - in - Generator.Plain {workload = size; closure} - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (create_benchmark rng_state config) - end - - let () = - Registration_helpers.register - (module Global_constants_storage_expand_no_constant_branch) ; - Registration_helpers.register_for_codegen - "Global_constants_storage_expand_no_constant_branch" - (Model.For_codegen - (WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc - ~equal:String.equal - "Global_constants_storage_expand_no_constant_branch" - Global_constants_storage_expand_no_constant_branch.models)) -end diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_benchmarks.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_benchmarks.ml deleted file mode 100644 index abb7b1e42e2b..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_benchmarks.ml +++ /dev/null @@ -1,3139 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(* ------------------------------------------------------------------------- *) - -type ex_stack_and_kinstr = - | Ex_stack_and_kinstr : { - stack : 'a * 'b; - kinstr : ('a, 'b, 'c, 'd) Script_typed_ir.kinstr; - } - -> ex_stack_and_kinstr - -type ex_stack_and_continuation = - | Ex_stack_and_cont : { - stack : 'a * 'b; - cont : ('a, 'b, 'c, 'd) Script_typed_ir.continuation; - } - -> ex_stack_and_continuation - -type ex_value = - | Ex_value : {value : 'a; ty : 'a Script_typed_ir.ty} -> ex_value - -(* ------------------------------------------------------------------------- *) - -let sf = Printf.sprintf - -(* End of Stack *) -let eos = Script_typed_ir.(EmptyCell, EmptyCell) - -let info_and_name ~intercept ?(salt = "") s = - let s = s ^ salt in - if intercept then (sf "Benchmark %s (intercept case)" s, s ^ "_intercept") - else (sf "Benchmark %s" s, s) - -module Default_boilerplate = struct - type workload = Interpreter_workload.t - - let workload_encoding = Interpreter_workload.encoding - - let workload_to_vector = Interpreter_workload.trace_to_sparse_vec - - let tags = [Tags.interpreter] -end - -module Default_config = struct - (* Configuration specific to sapling benchmarks *) - type sapling_config = {sapling_txs_file : string; seed : int option} - - (* Configuration specific to benchmarking Dign/Dipn/Dupn/Dropn/Combs *) - type comb_config = {max_depth : int} - - (* Configuration specific to benchmarking ICompare *) - type compare_config = {type_size : Base_samplers.range} - - type config = { - sampler : Michelson_samplers.parameters; - sapling : sapling_config; - comb : comb_config; - compare : compare_config; - } - - let default_config = - let open Michelson_samplers in - let open Michelson_samplers_base in - let sampler = - { - base_parameters = - { - int_size = {min = 8; max = 100_000}; - string_size = {min = 1 lsl 10; max = 1 lsl 17}; - bytes_size = {min = 1 lsl 10; max = 1 lsl 17}; - }; - list_size = {min = 10; max = 1000}; - set_size = {min = 10; max = 1000}; - map_size = {min = 10; max = 1000}; - } - in - { - sampler; - sapling = {sapling_txs_file = {|/no/such/file|}; seed = None}; - comb = {max_depth = 1000}; - compare = {type_size = {min = 1; max = 15}}; - } - - let sapling_config_encoding = - let open Data_encoding in - conv - (fun {sapling_txs_file; seed} -> (sapling_txs_file, seed)) - (fun (sapling_txs_file, seed) -> {sapling_txs_file; seed}) - (obj2 (req "sapling_txs_file" string) (req "seed" (option int31))) - - let comb_config_encoding = - let open Data_encoding in - conv - (fun {max_depth} -> max_depth) - (fun max_depth -> {max_depth}) - (obj1 (req "max_depth" int31)) - - let compare_config_encoding = - let open Data_encoding in - conv - (fun {type_size} -> type_size) - (fun type_size -> {type_size}) - (obj1 (req "type_size" Base_samplers.range_encoding)) - - let config_encoding = - let open Data_encoding in - conv - (fun {sampler; sapling; comb; compare} -> - (sampler, sapling, comb, compare)) - (fun (sampler, sapling, comb, compare) -> - {sampler; sapling; comb; compare}) - (obj4 - (req "sampler" Michelson_samplers.parameters_encoding) - (req "sapling" sapling_config_encoding) - (req "comb" comb_config_encoding) - (req "compare" compare_config_encoding)) -end - -let make_default_samplers ?(algo = `Default) cfg : - (module Crypto_samplers.Finite_key_pool_S) * (module Michelson_samplers.S) = - let module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct - let size = 16 - - let algo = algo - end) in - let module Michelson_samplers = - Michelson_samplers.Make - (struct - let parameters = cfg - end) - (Crypto_samplers) - in - ((module Crypto_samplers), (module Michelson_samplers)) - -(* ------------------------------------------------------------------------- *) -(* Helpers for creating benchmarks for the interpreter *) - -let benchmark_from_kinstr_and_stack : - ?amplification:int -> - Alpha_context.context -> - Protocol.Script_interpreter.step_constants -> - ex_stack_and_kinstr -> - Interpreter_workload.ir_sized_step list Generator.benchmark = - fun ?amplification ctxt step_constants stack_kinstr -> - let ctxt = Gas_helpers.set_limit ctxt in - match stack_kinstr with - | Ex_stack_and_kinstr {stack = (bef_top, bef); kinstr} -> - let (workload, closure) = - match amplification with - | None -> - let workload = - Interpreter_workload.extract_deps - ctxt - step_constants - kinstr - (bef_top, bef) - in - let outdated_ctxt = - Script_interpreter.Internals.OutDatedContext ctxt - in - let closure () = - ignore - (* Lwt_main.run *) - (Script_interpreter.Internals.step - (outdated_ctxt, step_constants) - 9_999_999_999 - kinstr - bef_top - bef) - in - (workload, closure) - | Some amplification_factor -> - assert (amplification_factor > 0) ; - let workload = - Interpreter_workload.extract_deps - ctxt - step_constants - kinstr - (bef_top, bef) - in - let workload = - List.repeat amplification_factor workload |> List.flatten - in - let outdated_ctxt = - Script_interpreter.Internals.OutDatedContext ctxt - in - let closure () = - for _i = 1 to amplification_factor do - ignore - (* Lwt_main.run *) - (Script_interpreter.Internals.step - (outdated_ctxt, step_constants) - 9_999_999_999 - kinstr - bef_top - bef) - done - in - (workload, closure) - in - Generator.Plain {workload; closure} - -let make_benchmark : - ?amplification:int -> - ?intercept:bool -> - ?salt:string -> - ?more_tags:string list -> - name:Interpreter_workload.instruction_name -> - kinstr_and_stack_sampler: - (Default_config.config -> Random.State.t -> unit -> ex_stack_and_kinstr) -> - unit -> - Benchmark.t = - fun ?amplification - ?(intercept = false) - ?salt - ?(more_tags = []) - ~name - ~kinstr_and_stack_sampler - () -> - let module B : Benchmark.S = struct - include Default_config - include Default_boilerplate - - let tags = tags @ more_tags - - let models = - (* [intercept = true] implies there's a benchmark with [intercept = false]. - No need to register the model twice. *) - Interpreter_model.make_model - ?amplification - (if intercept then None else Some (Instr_name name)) - - let (info, name) = - info_and_name - ~intercept - ?salt - (Interpreter_workload.string_of_instruction_name name) - - let benchmark kinstr_and_stack_sampler ctxt step_constants () = - let stack_instr = kinstr_and_stack_sampler () in - benchmark_from_kinstr_and_stack - ?amplification - ctxt - step_constants - stack_instr - - let create_benchmarks ~rng_state ~bench_num (config : config) = - match Lwt_main.run (Execution_context.make ~rng_state) with - | Error _errs -> assert false - | Ok (ctxt, step_constants) -> - let kinstr_and_stack_sampler = - kinstr_and_stack_sampler config rng_state - in - List.repeat - bench_num - (benchmark kinstr_and_stack_sampler ctxt step_constants) - end in - (module B : Benchmark.S) - -let make_simple_benchmark : - type bef_top bef res_top res. - ?amplification:int -> - ?intercept:bool -> - ?more_tags:string list -> - ?salt:string -> - name:Interpreter_workload.instruction_name -> - kinstr:(bef_top, bef, res_top, res) Script_typed_ir.kinstr -> - unit -> - Benchmark.t = - fun ?amplification ?intercept ?more_tags ?salt ~name ~kinstr () -> - let kinfo = Script_typed_ir.kinfo_of_kinstr kinstr in - let stack_ty = kinfo.kstack_ty in - let kinstr_and_stack_sampler config rng_state = - let (_, (module Samplers)) = - make_default_samplers config.Default_config.sampler - in - fun () -> - Ex_stack_and_kinstr - {stack = Samplers.Random_value.stack stack_ty rng_state; kinstr} - in - make_benchmark - ?amplification - ?intercept - ?more_tags - ?salt - ~name - ~kinstr_and_stack_sampler - () - -let benchmark ?amplification ?intercept ?more_tags ?salt ~name - ~kinstr_and_stack_sampler () = - let bench = - make_benchmark - ?amplification - ?intercept - ?more_tags - ?salt - ~name - ~kinstr_and_stack_sampler - () - in - Registration_helpers.register bench - -let benchmark_with_stack_sampler ?amplification ?intercept ?more_tags ?salt - ~name ~kinstr ~stack_sampler () = - let kinstr_and_stack_sampler config rng_state = - let stack_sampler = stack_sampler config rng_state in - fun () -> Ex_stack_and_kinstr {stack = stack_sampler (); kinstr} - in - let bench = - make_benchmark - ?amplification - ?intercept - ?more_tags - ?salt - ~name - ~kinstr_and_stack_sampler - () - in - Registration_helpers.register bench - -let benchmark_with_fixed_stack ?amplification ?intercept ?more_tags ?salt ~name - ~stack ~kinstr () = - benchmark_with_stack_sampler - ?amplification - ?intercept - ?more_tags - ?salt - ~name - ~kinstr - ~stack_sampler:(fun _cfg _rng_state () -> stack) - () - -let simple_benchmark_with_stack_sampler ?amplification ?intercept_stack ?salt - ?more_tags ~name ~kinstr ~stack_sampler () = - benchmark_with_stack_sampler - ?amplification - ~intercept:false - ?salt - ?more_tags - ~name - ~kinstr - ~stack_sampler - () ; - Option.iter - (fun stack -> - benchmark_with_fixed_stack - ?amplification - ~intercept:true - ?more_tags - ?salt - ~name - ~stack - ~kinstr - ()) - intercept_stack - -let simple_benchmark ?amplification ?intercept_stack ?more_tags ?salt ~name - ~kinstr () = - let bench = - make_simple_benchmark - ?amplification - ~intercept:false - ?more_tags - ?salt - ~name - ~kinstr - () - in - Registration_helpers.register bench ; - Option.iter - (fun stack -> - benchmark_with_fixed_stack - ?amplification - ~intercept:true - ?more_tags - ?salt - ~name - ~stack - ~kinstr - ()) - intercept_stack - -(* ------------------------------------------------------------------------- *) -(* Helpers for creating benchmarks for [Script_interpreter.next] *) - -let benchmark_from_continuation : - ?amplification:int -> - Alpha_context.context -> - Protocol.Script_interpreter.step_constants -> - ex_stack_and_continuation -> - Interpreter_workload.ir_sized_step list Generator.benchmark = - fun ?amplification ctxt step_constants stack_cont -> - let ctxt = Gas_helpers.set_limit ctxt in - match stack_cont with - | Ex_stack_and_cont {stack = (bef_top, bef); cont} -> - let (workload, closure) = - match amplification with - | None -> - let workload = - Interpreter_workload.extract_deps_continuation - ctxt - step_constants - cont - (bef_top, bef) - in - let outdated_ctxt = - Script_interpreter.Internals.OutDatedContext ctxt - in - let closure () = - ignore - (* Lwt_main.run *) - (Script_interpreter.Internals.next - None - (outdated_ctxt, step_constants) - 9_999_999_999 - cont - bef_top - bef) - in - (workload, closure) - | Some amplification_factor -> - assert (amplification_factor > 0) ; - let workload = - Interpreter_workload.extract_deps_continuation - ctxt - step_constants - cont - (bef_top, bef) - in - let workload = - List.repeat amplification_factor workload |> List.flatten - in - let outdated_ctxt = - Script_interpreter.Internals.OutDatedContext ctxt - in - let closure () = - for _i = 1 to amplification_factor do - ignore - (* Lwt_main.run *) - (Script_interpreter.Internals.next - None - (outdated_ctxt, step_constants) - 9_999_999_999 - cont - bef_top - bef) - done - in - (workload, closure) - in - Generator.Plain {workload; closure} - -let make_continuation_benchmark : - ?amplification:int -> - ?intercept:bool -> - ?salt:string -> - ?more_tags:string list -> - name:Interpreter_workload.continuation_name -> - cont_and_stack_sampler: - (Default_config.config -> - Random.State.t -> - unit -> - ex_stack_and_continuation) -> - unit -> - Benchmark.t = - fun ?amplification - ?(intercept = false) - ?salt - ?(more_tags = []) - ~name - ~cont_and_stack_sampler - () -> - let module B : Benchmark.S = struct - include Default_config - include Default_boilerplate - - let tags = tags @ more_tags - - let models = - Interpreter_model.make_model - ?amplification - (if intercept then None else Some (Cont_name name)) - - let (info, name) = - info_and_name - ~intercept - ?salt - (Interpreter_workload.string_of_continuation_name name) - - let benchmark cont_and_stack_sampler ctxt step_constants () = - let stack_instr = cont_and_stack_sampler () in - benchmark_from_continuation ?amplification ctxt step_constants stack_instr - - let create_benchmarks ~rng_state ~bench_num (config : config) = - match Lwt_main.run (Execution_context.make ~rng_state) with - | Error _errs -> assert false - | Ok (ctxt, step_constants) -> - let cont_and_stack_sampler = - cont_and_stack_sampler config rng_state - in - List.repeat - bench_num - (benchmark cont_and_stack_sampler ctxt step_constants) - end in - (module B : Benchmark.S) - -let continuation_benchmark ?amplification ?intercept ?salt ?more_tags ~name - ~cont_and_stack_sampler () = - let bench = - make_continuation_benchmark - ?amplification - ?intercept - ?salt - ?more_tags - ~name - ~cont_and_stack_sampler - () - in - Registration_helpers.register bench - -(* ------------------------------------------------------------------------- *) -(* Sampling helpers *) - -let nat_of_positive_int (i : int) = - let open Alpha_context.Script_int in - match is_nat (of_int i) with None -> assert false | Some x -> x - -let adversarial_ints rng_state (cfg : Default_config.config) n = - let (_common_prefix, ls) = - Base_samplers.Adversarial.integers - ~prefix_size:cfg.sampler.base_parameters.int_size - ~card:n - rng_state - in - List.map Script_int_repr.of_zint ls - -(* ------------------------------------------------------------------------- *) -(* Error helpers *) - -let raise_if_error = function - | Ok x -> x - | Error e -> - Format.eprintf "%a@." (Error_monad.TzTrace.pp_print Error_monad.pp) e ; - Stdlib.failwith "raise_if_error" - -(* ------------------------------------------------------------------------- *) - -(** [Registration_section] contains all interpreter benchmarks. The goal of - a benchmark is to gather enough data to reliably estimate the parameters - of the cost model associated to each instruction. In general, it can - take several distinct benchmarks to properly cover all the execution - paths. - - In particular, for affine cost model, it is often worth estimating the - intercept separately from the size-dependent coefficients. - *) - -module Registration_section = struct - open Script_typed_ir - open Michelson_types - - let sf = Printf.sprintf - - let kinfo kstack_ty = {iloc = 0; kstack_ty} - - let halt stack_ty = IHalt (kinfo stack_ty) - - let halt_unit = halt (unit @$ bot) - - let halt_unitunit = halt (unit @$ unit @$ bot) - - let kinfo_unit = kinfo (unit @$ bot) - - let kinfo_unitunit = kinfo (unit @$ unit @$ bot) - - let () = - (* KHalt *) - simple_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_IHalt - ~kinstr:halt_unit - () - - module Amplification = struct - module Loop : Benchmark.S = struct - let name = "amplification_loop" - - let info = "Benchmarking the cost of an empty loop" - - let tags = [Tags.interpreter] - - type config = {max_iterations : int} - - let config_encoding = - let open Data_encoding in - conv - (fun {max_iterations} -> max_iterations) - (fun max_iterations -> {max_iterations}) - (obj1 (req "max_iterations" int31)) - - let default_config = {max_iterations = 100000} - - type workload = int - - let workload_encoding = Data_encoding.int31 - - let workload_to_vector n = - Sparse_vec.String.of_list [("iterations", float_of_int n)] - - let models = [("interpreter", Interpreter_model.amplification_loop_model)] - - let benchmark rng_state config () = - let workload = Random.State.int rng_state config.max_iterations in - let closure () = - for _i = 1 to workload do - Sys.opaque_identity () - done - in - Generator.Plain {workload; closure} - - let create_benchmarks ~rng_state ~bench_num (config : config) = - List.repeat bench_num (benchmark rng_state config) - end - end - - let () = Registration_helpers.register (module Amplification.Loop) - - module Stack = struct - let () = - (* KDrop ; KHalt *) - simple_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_IDrop - ~kinstr:(IDrop (kinfo_unitunit, halt_unit)) - () - - let () = - (* IDup ; IHalt *) - simple_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_IDup - ~kinstr:(IDup (kinfo_unit, halt_unitunit)) - () - - let () = - simple_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_ISwap - ~kinstr:(ISwap (kinfo_unitunit, halt_unitunit)) - () - - let () = - simple_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_IConst - ~kinstr:(IConst (kinfo_unit, (), halt_unitunit)) - () - - (* deep stack manipulation *) - - (* Constructing these instructions is made especially painful by the - fact that they include "stack preservation witnesses", which are not - exposed in Script_ir_translator. - We must go through [Script_ir_translator.parse_instr] to construct - the corresponding terms. *) - type ex_stack = - | Ex_stack : ('a, 'b) Script_typed_ir.stack_ty * ('a * 'b) -> ex_stack - - let rec make_stack (depth : int) = - if depth = 0 then assert false - else if depth = 1 then Ex_stack (unit @$ Script_typed_ir.Bot_t, ((), eos)) - else - let stack = make_stack (depth - 1) in - match stack with - | Ex_stack (stack_ty, stack) -> Ex_stack (unit @$ stack_ty, ((), stack)) - - let parse_instr rng_state node stack = - match stack with - | Ex_stack (stack_ty, stack) -> - raise_if_error - (Lwt_main.run - ( Execution_context.make ~rng_state - >>=? fun (ctxt, _step_constants) -> - Script_ir_translator.parse_instr - Script_ir_translator.Lambda - ctxt - ~legacy:false - node - stack_ty - >|= Environment.wrap_tzresult - >>=? fun (judgement, _) -> - match judgement with - | Script_ir_translator.Typed descr -> - let kinfo = {iloc = 0; kstack_ty = descr.bef} in - let kinfo' = {iloc = 0; kstack_ty = descr.aft} in - let kinstr = descr.instr.apply kinfo (IHalt kinfo') in - return (Ex_stack_and_kinstr {stack; kinstr}) - | Script_ir_translator.Failed _ -> assert false )) - - open Protocol.Michelson_v1_primitives - - (* The size parameter of a deep stack instruction must fit on 10 bits. See - [Script_ir_translator.parse_uint10]. *) - let stack_size = 1023 - - let long_stack = make_stack stack_size - - let sample_depth rng_state = - Base_samplers.( - sample_in_interval rng_state ~range:{min = 0; max = stack_size - 2}) - - let () = - let dig = Micheline.(Prim (0, I_DIG, [Int (0, Z.of_int 0)], [])) in - benchmark - ~amplification:100 - ~intercept:true - ~name:Interpreter_workload.N_IDig - ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> - let node = dig in - parse_instr rng_state node long_stack) - () - - let () = - let dig n = Micheline.(Prim (0, I_DIG, [Int (0, Z.of_int n)], [])) in - benchmark - ~name:Interpreter_workload.N_IDig - ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> - let node = dig (sample_depth rng_state) in - parse_instr rng_state node long_stack) - () - - let () = - let dug = Micheline.(Prim (0, I_DUG, [Int (0, Z.of_int 0)], [])) in - benchmark - ~intercept:true - ~name:Interpreter_workload.N_IDug - ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> - let node = dug in - parse_instr rng_state node long_stack) - () - - let () = - let dug n = Micheline.(Prim (0, I_DUG, [Int (0, Z.of_int n)], [])) in - benchmark - ~name:Interpreter_workload.N_IDug - ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> - let node = dug (sample_depth rng_state) in - parse_instr rng_state node long_stack) - () - - let () = - let nop = Micheline.Seq (0, []) in - let dip = Micheline.(Prim (0, I_DIP, [Int (0, Z.of_int 0); nop], [])) in - benchmark - ~intercept:true - ~name:Interpreter_workload.N_IDipN - ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> - let node = dip in - parse_instr rng_state node long_stack) - () - - let () = - let nop = Micheline.Seq (0, []) in - let dip n = Micheline.(Prim (0, I_DIP, [Int (0, Z.of_int n); nop], [])) in - benchmark - ~name:Interpreter_workload.N_IDipN - ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> - let node = dip (sample_depth rng_state) in - parse_instr rng_state node long_stack) - () - - let () = - let drop = Micheline.(Prim (0, I_DROP, [Int (0, Z.of_int 0)], [])) in - benchmark - ~intercept:true - ~name:Interpreter_workload.N_IDropN - ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> - let node = drop in - parse_instr rng_state node long_stack) - () - - let () = - let drop n = Micheline.(Prim (0, I_DROP, [Int (0, Z.of_int n)], [])) in - benchmark - ~name:Interpreter_workload.N_IDropN - ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> - let node = drop (sample_depth rng_state) in - parse_instr rng_state node long_stack) - () - - let () = - let pair n = Micheline.(Prim (0, I_PAIR, [Int (0, Z.of_int n)], [])) in - benchmark - ~name:Interpreter_workload.N_IComb - ~kinstr_and_stack_sampler:(fun cfg rng_state () -> - let width = - Base_samplers.( - sample_in_interval - rng_state - ~range:{min = 2; max = cfg.comb.max_depth}) - in - let node = pair width in - parse_instr rng_state node long_stack) - () - - let rec make_comb_stack (comb_width : int) (depth : int) acc = - if depth = 0 then - match acc with - | Ex_stack (stack_ty, stack) -> ( - match make_comb comb_width (Ex_value {value = (); ty = unit}) with - | Ex_value {value; ty} -> Ex_stack (ty @$ stack_ty, (value, stack))) - else - match acc with - | Ex_stack (stack_ty, stack) -> - make_comb_stack - comb_width - (depth - 1) - (Ex_stack (unit @$ stack_ty, ((), stack))) - - and make_comb comb_width comb_acc = - if comb_width = 0 then assert false - else if comb_width = 1 then comb_acc - else - match comb_acc with - | Ex_value {value; ty} -> - make_comb - (comb_width - 1) - (Ex_value {value = ((), value); ty = pair unit ty}) - - let () = - let unpair n = - Micheline.(Prim (0, I_UNPAIR, [Int (0, Z.of_int n)], [])) - in - benchmark - ~name:Interpreter_workload.N_IUncomb - ~kinstr_and_stack_sampler:(fun cfg rng_state () -> - let width = - Base_samplers.( - sample_in_interval - rng_state - ~range:{min = 2; max = cfg.comb.max_depth - 2}) - in - let node = unpair width in - let stack = - make_comb_stack width 1 (Ex_stack (unit @$ bot, ((), eos))) - in - parse_instr rng_state node stack) - () - - let () = - let comb_get n = Micheline.(Prim (0, I_GET, [Int (0, Z.of_int n)], [])) in - benchmark - ~name:Interpreter_workload.N_IComb_get - ~kinstr_and_stack_sampler:(fun cfg rng_state () -> - let width = - Base_samplers.( - sample_in_interval - rng_state - ~range:{min = 2; max = cfg.comb.max_depth - 2}) - in - let index = - Base_samplers.( - sample_in_interval rng_state ~range:{min = 0; max = width}) - in - let node = comb_get index in - let stack = - make_comb_stack width 1 (Ex_stack (unit @$ bot, ((), eos))) - in - parse_instr rng_state node stack) - () - - let () = - let comb_set n = - Micheline.(Prim (0, I_UPDATE, [Int (0, Z.of_int n)], [])) - in - benchmark - ~name:Interpreter_workload.N_IComb_set - ~kinstr_and_stack_sampler:(fun cfg rng_state () -> - let width = - Base_samplers.( - sample_in_interval - rng_state - ~range:{min = 2; max = cfg.comb.max_depth - 2}) - in - let index = - Base_samplers.( - sample_in_interval rng_state ~range:{min = 0; max = width}) - in - let node = comb_set index in - let stack = - let (Ex_stack (stack_ty, stack)) = - make_comb_stack width 1 (Ex_stack (unit @$ bot, ((), eos))) - in - Ex_stack (unit @$ stack_ty, ((), stack)) - in - parse_instr rng_state node stack) - () - - let () = - let dup n = Micheline.(Prim (0, I_DUP, [Int (0, Z.of_int n)], [])) in - benchmark - ~name:Interpreter_workload.N_IDupN - ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> - let node = dup (1 + sample_depth rng_state) in - parse_instr rng_state node long_stack) - () - end - - module Pairs = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_ICons_pair - ~kinstr:(ICons_pair (kinfo_unitunit, halt (pair unit unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ICar - ~kinstr:(ICar (kinfo (pair unit unit @$ bot), halt_unit)) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ICdr - ~kinstr:(ICdr (kinfo (pair unit unit @$ bot), halt_unit)) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IUnpair - ~kinstr:(IUnpair (kinfo (pair unit unit @$ bot), halt_unitunit)) - () - end - - module Options = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_ICons_some - ~kinstr:(ICons_some (kinfo_unit, halt (option unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ICons_none - ~kinstr:(ICons_none (kinfo_unit, halt (option unit @$ unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IIf_none - ~kinstr: - (IIf_none - { - kinfo = kinfo (option unit @$ unit @$ bot); - branch_if_none = halt_unit; - branch_if_some = IDrop (kinfo_unitunit, halt_unit); - k = halt_unit; - }) - () - - let () = - benchmark_with_fixed_stack - ~name:Interpreter_workload.N_IOpt_map - ~salt:"none" - ~stack:(None, ((), eos)) - ~kinstr: - (IOpt_map - { - kinfo = kinfo (option unit @$ unit @$ bot); - body = halt_unitunit; - k = halt (option unit @$ unit @$ bot); - }) - () - - let () = - benchmark_with_fixed_stack - ~name:Interpreter_workload.N_IOpt_map - ~salt:"some" - ~stack:(Some (), ((), eos)) - ~kinstr: - (IOpt_map - { - kinfo = kinfo (option unit @$ unit @$ bot); - body = halt_unitunit; - k = halt (option unit @$ unit @$ bot); - }) - () - end - - module Unions = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_ILeft - ~kinstr:(ICons_left (kinfo_unit, halt (union unit unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IRight - ~kinstr:(ICons_right (kinfo_unit, halt (union unit unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IIf_left - ~kinstr: - (IIf_left - { - kinfo = kinfo (union unit unit @$ bot); - branch_if_left = halt_unit; - branch_if_right = halt_unit; - k = halt_unit; - }) - () - end - - module Lists = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_ICons_list - ~kinstr: - (ICons_list (kinfo (unit @$ list unit @$ bot), halt (list unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_INil - ~kinstr:(INil (kinfo_unit, halt (list unit @$ unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IIf_cons - ~kinstr: - (IIf_cons - { - kinfo = kinfo (list unit @$ unit @$ bot); - branch_if_cons = - IDrop - ( kinfo (unit @$ list unit @$ unit @$ bot), - IDrop (kinfo (list unit @$ unit @$ bot), halt_unit) ); - branch_if_nil = halt_unit; - k = halt_unit; - }) - () - - module Mapping = struct - let kinfo_enter_body = kinfo_unit - - let kinfo_exit_body = kinfo_unitunit - - let () = - (* - IList_map -> - IList_enter_body (empty case) -> - IHalt - *) - benchmark_with_fixed_stack - ~name:Interpreter_workload.N_IList_map - ~stack:(Script_list.empty, ((), eos)) - ~kinstr: - (IList_map - ( kinfo (list unit @$ unit @$ bot), - halt_unitunit, - halt (list unit @$ unit @$ bot) )) - () - end - - let () = - let kinfo = kinfo (list unit @$ bot) in - simple_benchmark - ~name:Interpreter_workload.N_IList_size - ~kinstr:(IList_size (kinfo, halt (nat @$ bot))) - () - - let () = - (* - IList_iter -> - IIter (empty case) -> - IHalt - *) - let kinfo1 = kinfo (list unit @$ unit @$ bot) in - benchmark_with_fixed_stack - ~name:Interpreter_workload.N_IList_iter - ~stack:(Script_list.empty, ((), eos)) - ~kinstr: - (IList_iter (kinfo1, IDrop (kinfo_unitunit, halt_unit), halt_unit)) - () - end - - module Sets = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_IEmpty_set - ~kinstr: - (IEmpty_set (kinfo_unit, unit_cmp, halt (set unit_cmp @$ unit @$ bot))) - () - - let set_iter_code = - ISet_iter - ( kinfo (set int_cmp @$ unit @$ bot), - IDrop (kinfo (int @$ unit @$ bot), halt_unit), - halt_unit ) - - let () = - (* - ISet_iter -> - (List.rev (set_fold)) -> - { - IIter -> - IDrop -> - ICons -> - ... - } - *) - simple_benchmark - ~name:Interpreter_workload.N_ISet_iter - ~intercept_stack:(Script_set.empty int_cmp, ((), eos)) - ~kinstr:set_iter_code - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_ISet_mem - ~kinstr: - (ISet_mem - ( kinfo (int @$ set int_cmp @$ unit @$ bot), - halt (bool @$ unit @$ bot) )) - ~intercept_stack: - (Alpha_context.Script_int.zero, (Script_set.empty int_cmp, ((), eos))) - ~stack_sampler:(fun cfg rng_state () -> - assert (cfg.sampler.set_size.min >= 1) ; - let n = - Base_samplers.sample_in_interval - rng_state - ~range:cfg.sampler.set_size - in - let elts = adversarial_ints rng_state cfg n in - let set = - List.fold_left - (fun set elt -> Script_set.update elt true set) - (Script_set.empty int_cmp) - elts - in - let elt = - List.nth_opt elts (Random.State.int rng_state n) - |> WithExceptions.Option.get ~loc:__LOC__ - in - (elt, (set, ((), eos)))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_ISet_update - ~kinstr: - (ISet_update - ( kinfo (int @$ bool @$ set int_cmp @$ bot), - halt (set int_cmp @$ bot) )) - ~intercept_stack: - ( Alpha_context.Script_int.zero, - (false, (Script_set.empty int_cmp, eos)) ) - ~stack_sampler:(fun cfg rng_state () -> - assert (cfg.sampler.set_size.min >= 2) ; - let n = - Base_samplers.sample_in_interval - rng_state - ~range:cfg.sampler.set_size - in - let elts = adversarial_ints rng_state cfg (n + 1) in - let (out_of_set, in_set) = - match elts with [] -> assert false | hd :: tl -> (hd, tl) - in - let set = - List.fold_left - (fun set elt -> Script_set.update elt true set) - (Script_set.empty int_cmp) - in_set - in - let stack = - let flip = Random.State.bool rng_state in - if flip then - (* add an element not in the set *) - (out_of_set, (true, (set, eos))) - else - (* remove an element in the set *) - let elt = out_of_set in - let set = Script_set.update elt true set in - (elt, (flip, (set, eos))) - in - stack) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISet_size - ~kinstr:(ISet_size (kinfo (set unit_cmp @$ bot), halt (nat @$ bot))) - () - end - - module Maps = struct - let generate_map_and_key_in_map (cfg : Default_config.config) rng_state = - let n = - Base_samplers.sample_in_interval rng_state ~range:cfg.sampler.set_size - in - let keys = adversarial_ints rng_state cfg n in - let map = - List.fold_left - (fun map i -> Script_map.update i (Some ()) map) - (Script_map.empty int_cmp) - keys - in - let (module M) = map in - let key = - M.OPS.fold (fun k _ -> function None -> Some k | x -> x) M.boxed None - |> WithExceptions.Option.get ~loc:__LOC__ - in - (key, map) - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IEmpty_map - ~kinstr: - (IEmpty_map - (kinfo_unit, unit_cmp, halt (map unit_cmp unit @$ unit @$ bot))) - () - - (* - let map_map_code = - IMap_map - ( kinfo (map int_cmp unit @$ unit @$ bot), - ICdr (kinfo (pair int unit @$ unit @$ bot), halt_unitunit), - halt (map int_cmp unit @$ unit @$ bot) ) - *) - - let map_map_code = - IMap_map - ( kinfo (map int_cmp unit @$ unit @$ bot), - IFailwith (kinfo (pair int unit @$ unit @$ bot), 0, pair int unit), - halt (map int_cmp unit @$ unit @$ bot) ) - - let () = - (* - Map_map (nonempty case) -> - (List.rev (map_fold nonempty_map)) -> - KMap_enter_body (nonempty case) -> - fail (early interruption) - *) - simple_benchmark - ~name:Interpreter_workload.N_IMap_map - ~intercept_stack: - (let map = Script_map.empty int_cmp in - (map, ((), eos))) - ~kinstr:map_map_code - () - - let kmap_iter_code = - IMap_iter - ( kinfo (map int_cmp unit @$ unit @$ bot), - IDrop (kinfo (pair int unit @$ unit @$ bot), halt_unit), - halt_unit ) - - let () = - (* - IMap_iter (nonempty case) -> - (List.rev (map_fold (nonempty))) -> - IIter (nonempty case) -> - ... - *) - simple_benchmark - ~name:Interpreter_workload.N_IMap_iter - ~intercept_stack: - (let map = Script_map.empty int_cmp in - (map, ((), eos))) - ~kinstr:kmap_iter_code - () - - let () = - (* - IMap_mem -> - (map_mem) -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IMap_mem - ~kinstr: - (IMap_mem - ( kinfo (int @$ map int_cmp unit @$ unit @$ bot), - halt (bool @$ unit @$ bot) )) - ~intercept_stack: - (let map = Script_map.empty int_cmp in - (Alpha_context.Script_int.zero, (map, ((), eos)))) - ~stack_sampler:(fun cfg rng_state () -> - let (key, map) = generate_map_and_key_in_map cfg rng_state in - (key, (map, ((), eos)))) - () - - let () = - (* - IMap_get -> - (map_get) -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IMap_get - ~kinstr: - (IMap_get - ( kinfo (int @$ map int_cmp unit @$ unit @$ bot), - halt (option unit @$ unit @$ bot) )) - ~intercept_stack: - (let map = Script_map.empty int_cmp in - (Alpha_context.Script_int.zero, (map, ((), eos)))) - ~stack_sampler:(fun cfg rng_state () -> - let (key, map) = generate_map_and_key_in_map cfg rng_state in - (key, (map, ((), eos)))) - () - - let () = - (* - IMap_update -> - (map_update) -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IMap_update - ~kinstr: - (IMap_update - ( kinfo (int @$ option unit @$ map int_cmp unit @$ bot), - halt (map int_cmp unit @$ bot) )) - ~intercept_stack: - (let map = Script_map.empty int_cmp in - (Alpha_context.Script_int.zero, (None, (map, eos)))) - ~stack_sampler:(fun cfg rng_state () -> - let (key, map) = generate_map_and_key_in_map cfg rng_state in - (key, (Some (), (map, eos)))) - () - - let () = - (* - IMap_get_and_update -> - (map_update) -> - (map_get) -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IMap_get_and_update - ~kinstr: - (IMap_get_and_update - ( kinfo (int @$ option unit @$ map int_cmp unit @$ bot), - halt (option unit @$ map int_cmp unit @$ bot) )) - ~intercept_stack: - (let map = Script_map.empty int_cmp in - (Alpha_context.Script_int.zero, (None, (map, eos)))) - ~stack_sampler:(fun cfg rng_state () -> - let (key, map) = generate_map_and_key_in_map cfg rng_state in - (key, (Some (), (map, eos)))) - () - - let () = - (* - IMap_size -> - (map_update) -> - (map_get) -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IMap_size - ~kinstr:(IMap_size (kinfo (map int_cmp unit @$ bot), halt (nat @$ bot))) - ~stack_sampler:(fun _cfg _rng_state -> - let map = Script_map.empty int_cmp in - fun () -> (map, eos)) - () - end - - module Big_maps = struct - let generate_big_map_and_key_in_map (cfg : Default_config.config) rng_state - = - let n = - Base_samplers.sample_in_interval rng_state ~range:cfg.sampler.set_size - in - let keys = adversarial_ints rng_state cfg n in - let map = - List.fold_left - (fun map i -> Script_map.update i (Some (Some ())) map) - (Script_map.empty int_cmp) - keys - in - let (module M) = map in - let key = - M.OPS.fold (fun k _ -> function None -> Some k | x -> x) M.boxed None - |> WithExceptions.Option.get ~loc:__LOC__ - in - let big_map = - raise_if_error - (Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - let big_map = - Script_ir_translator.empty_big_map int_cmp (unit_t ~annot:None) - in - Script_map.fold - (fun k v acc -> - acc >>=? fun (bm, ctxt_acc) -> - Script_ir_translator.big_map_update ctxt_acc k v bm) - map - (return (big_map, ctxt)) - >|= Environment.wrap_tzresult - >>=? fun (big_map, _) -> return big_map )) - in - (key, big_map) - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IEmpty_big_map - ~kinstr: - (IEmpty_big_map - ( kinfo_unit, - unit_cmp, - unit, - halt (big_map unit_cmp unit @$ unit @$ bot) )) - () - - let () = - (* - IBig_map_mem -> - (update context with gas) - (big_map_mem) -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IBig_map_mem - ~kinstr: - (IBig_map_mem - ( kinfo (int @$ big_map int_cmp unit @$ unit @$ bot), - halt (bool @$ unit @$ bot) )) - ~stack_sampler:(fun cfg rng_state () -> - let (key, map) = generate_big_map_and_key_in_map cfg rng_state in - (key, (map, ((), eos)))) - () - - let () = - (* - IBig_map_get -> - (big_map_get) -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IBig_map_get - ~kinstr: - (IBig_map_get - ( kinfo (int @$ big_map int_cmp unit @$ unit @$ bot), - halt (option unit @$ unit @$ bot) )) - ~intercept_stack: - (let map = Script_ir_translator.empty_big_map int_cmp unit in - (Alpha_context.Script_int.zero, (map, ((), eos)))) - ~stack_sampler:(fun cfg rng_state () -> - let (key, map) = generate_big_map_and_key_in_map cfg rng_state in - (key, (map, ((), eos)))) - () - - let () = - (* - IBig_map_update -> - (big_map_update) -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IBig_map_update - ~kinstr: - (IBig_map_update - ( kinfo (int @$ option unit @$ big_map int_cmp unit @$ bot), - halt (big_map int_cmp unit @$ bot) )) - ~intercept_stack: - (let map = Script_ir_translator.empty_big_map int_cmp unit in - (Alpha_context.Script_int.zero, (None, (map, eos)))) - ~stack_sampler:(fun cfg rng_state () -> - let (key, map) = generate_big_map_and_key_in_map cfg rng_state in - (key, (Some (), (map, eos)))) - () - - let () = - (* - IBig_map_get_and_update -> - (big_map_update) -> - (big_map_get) -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IBig_map_get_and_update - ~kinstr: - (IBig_map_get_and_update - ( kinfo (int @$ option unit @$ big_map int_cmp unit @$ bot), - halt (option unit @$ big_map int_cmp unit @$ bot) )) - ~intercept_stack: - (let map = Script_ir_translator.empty_big_map int_cmp unit in - (Alpha_context.Script_int.zero, (None, (map, eos)))) - ~stack_sampler:(fun cfg rng_state () -> - let (key, map) = generate_big_map_and_key_in_map cfg rng_state in - (key, (Some (), (map, eos)))) - () - end - - module Strings = struct - open Alpha_context.Script_string - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IConcat_string - ~intercept_stack:(Script_list.empty, eos) - ~kinstr: - (IConcat_string (kinfo (list string @$ bot), halt (string @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IConcat_string_pair - ~intercept_stack:(empty, (empty, eos)) - ~kinstr: - (IConcat_string_pair - (kinfo (string @$ string @$ bot), halt (string @$ bot))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_ISlice_string - ~kinstr: - (ISlice_string - (kinfo (nat @$ nat @$ string @$ bot), halt (option string @$ bot))) - ~intercept_stack: - (let z = Alpha_context.Script_int.zero_n in - (z, (z, (empty, eos)))) - ~stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = make_default_samplers cfg.sampler in - fun () -> - let string = - Samplers.Random_value.value - Script_typed_ir.(string_t ~annot:None) - rng_state - in - let len = nat_of_positive_int (length string) in - (* worst case: offset = 0 *) - (nat_of_positive_int 0, (len, (string, eos)))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IString_size - ~kinstr:(IString_size (kinfo (string @$ bot), halt (nat @$ bot))) - () - end - - module Bytes = struct - (* Copy of [String] modulo renaming string to bytes. *) - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IConcat_bytes - ~intercept_stack:(Script_list.empty, eos) - ~kinstr:(IConcat_bytes (kinfo (list bytes @$ bot), halt (bytes @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IConcat_bytes_pair - ~intercept_stack:(Bytes.empty, (Bytes.empty, eos)) - ~kinstr: - (IConcat_bytes_pair - (kinfo (bytes @$ bytes @$ bot), halt (bytes @$ bot))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_ISlice_bytes - ~kinstr: - (ISlice_bytes - (kinfo (nat @$ nat @$ bytes @$ bot), halt (option bytes @$ bot))) - ~intercept_stack: - (let z = Alpha_context.Script_int.zero_n in - (z, (z, (Bytes.empty, eos)))) - ~stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = make_default_samplers cfg.sampler in - fun () -> - let bytes = - Samplers.Random_value.value - Script_typed_ir.(bytes_t ~annot:None) - rng_state - in - let len = nat_of_positive_int (Bytes.length bytes) in - (* worst case: offset = 0 *) - (nat_of_positive_int 0, (len, (bytes, eos)))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IBytes_size - ~kinstr:(IBytes_size (kinfo (bytes @$ bot), halt (nat @$ bot))) - () - end - - module Timestamps = struct - let zero_timestamp = Alpha_context.Script_timestamp.of_zint Z.zero - - let zero_int = Alpha_context.Script_int.zero - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAdd_seconds_to_timestamp - ~intercept_stack:(zero_int, (zero_timestamp, eos)) - ~kinstr: - (IAdd_seconds_to_timestamp - (kinfo (int @$ timestamp @$ bot), halt (timestamp @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAdd_timestamp_to_seconds - ~intercept_stack:(zero_timestamp, (zero_int, eos)) - ~kinstr: - (IAdd_timestamp_to_seconds - (kinfo (timestamp @$ int @$ bot), halt (timestamp @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISub_timestamp_seconds - ~intercept_stack:(zero_timestamp, (zero_int, eos)) - ~kinstr: - (ISub_timestamp_seconds - (kinfo (timestamp @$ int @$ bot), halt (timestamp @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IDiff_timestamps - ~intercept_stack:(zero_timestamp, (zero_timestamp, eos)) - ~kinstr: - (IDiff_timestamps - (kinfo (timestamp @$ timestamp @$ bot), halt (int @$ bot))) - () - end - - module Tez = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAdd_tez - ~kinstr:(IAdd_tez (kinfo (mutez @$ mutez @$ bot), halt (mutez @$ bot))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_ISub_tez - ~kinstr: - (ISub_tez (kinfo (mutez @$ mutez @$ bot), halt (option mutez @$ bot))) - ~stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = - make_default_samplers cfg.Default_config.sampler - in - fun () -> - let a = Samplers.Random_value.value mutez rng_state in - let b = - match Alpha_context.Tez.(a /? 2L) with - | Error _ -> assert false - | Ok x -> x - in - (a, (b, eos))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_ISub_tez_legacy - ~kinstr: - (ISub_tez_legacy (kinfo (mutez @$ mutez @$ bot), halt (mutez @$ bot))) - ~stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = - make_default_samplers cfg.Default_config.sampler - in - fun () -> - let a = Samplers.Random_value.value mutez rng_state in - let b = - match Alpha_context.Tez.(a /? 2L) with - | Error _ -> assert false - | Ok x -> x - in - (a, (b, eos))) - () - - let sample_tez_nat (module Samplers : Michelson_samplers.S) rng_state = - let mutez = Samplers.Random_value.value mutez rng_state in - let mutez_int64 = Alpha_context.Tez.to_mutez mutez in - let int64 = Int64.(div max_int (mul mutez_int64 2L)) in - let nat = - match Alpha_context.Script_int.(is_nat (of_int64 int64)) with - | None -> assert false - | Some nat -> nat - in - (mutez, nat) - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IMul_teznat - ~kinstr:(IMul_teznat (kinfo (mutez @$ nat @$ bot), halt (mutez @$ bot))) - ~stack_sampler:(fun cfg rng_state -> - let (_, samplers) = make_default_samplers cfg.sampler in - fun () -> - let (mutez, nat) = sample_tez_nat samplers rng_state in - (mutez, (nat, eos))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IMul_nattez - ~kinstr:(IMul_nattez (kinfo (nat @$ mutez @$ bot), halt (mutez @$ bot))) - ~stack_sampler:(fun cfg rng_state -> - let (_, samplers) = make_default_samplers cfg.sampler in - fun () -> - let (mutez, nat) = sample_tez_nat samplers rng_state in - (nat, (mutez, eos))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IEdiv_teznat - ~intercept_stack: - (Alpha_context.Tez.zero, (Alpha_context.Script_int.zero_n, eos)) - ~kinstr: - (IEdiv_teznat - ( kinfo (mutez @$ nat @$ bot), - halt (option (pair mutez mutez) @$ bot) )) - ~stack_sampler:(fun cfg rng_state -> - let (_, samplers) = make_default_samplers cfg.sampler in - fun () -> - let (mutez, nat) = sample_tez_nat samplers rng_state in - (mutez, (nat, eos))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IEdiv_tez - ~intercept_stack:(Alpha_context.Tez.zero, (Alpha_context.Tez.zero, eos)) - ~kinstr: - (IEdiv_tez - ( kinfo (mutez @$ mutez @$ bot), - halt (option (pair nat mutez) @$ bot) )) - () - end - - module Booleans = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_IOr - ~kinstr:(IOr (kinfo (bool @$ bool @$ bot), halt (bool @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAnd - ~kinstr:(IAnd (kinfo (bool @$ bool @$ bot), halt (bool @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IXor - ~kinstr:(IXor (kinfo (bool @$ bool @$ bot), halt (bool @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_INot - ~kinstr:(INot (kinfo (bool @$ bot), halt (bool @$ bot))) - () - end - - module Integers = struct - let zero = Alpha_context.Script_int.zero - - let zero_n = Alpha_context.Script_int.zero_n - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IIs_nat - ~intercept_stack:(zero, eos) - ~kinstr:(IIs_nat (kinfo (int @$ bot), halt (option nat @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_INeg - ~intercept_stack:(zero, eos) - ~kinstr:(INeg (kinfo (int @$ bot), halt (int @$ bot))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IAbs_int - ~kinstr:(IAbs_int (kinfo (int @$ bot), halt (nat @$ bot))) - ~intercept_stack:(zero, eos) - ~stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = make_default_samplers cfg.sampler in - fun () -> - let x = Samplers.Michelson_base.nat rng_state in - let neg_x = Alpha_context.Script_int.neg x in - (neg_x, eos)) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IInt_nat - ~intercept_stack:(zero_n, eos) - ~kinstr:(IInt_nat (kinfo (nat @$ bot), halt (int @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAdd_int - ~intercept_stack:(zero, (zero, eos)) - ~kinstr:(IAdd_int (kinfo (int @$ int @$ bot), halt (int @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAdd_nat - ~intercept_stack:(zero_n, (zero_n, eos)) - ~kinstr:(IAdd_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISub_int - ~intercept_stack:(zero, (zero, eos)) - ~kinstr:(ISub_int (kinfo (int @$ int @$ bot), halt (int @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IMul_int - ~intercept_stack:(zero, (zero, eos)) - ~kinstr:(IMul_int (kinfo (int @$ int @$ bot), halt (int @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IMul_nat - ~intercept_stack:(zero_n, (zero, eos)) - ~kinstr:(IMul_nat (kinfo (nat @$ int @$ bot), halt (int @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IEdiv_int - ~intercept_stack:(zero, (zero, eos)) - ~kinstr: - (IEdiv_int - (kinfo (int @$ int @$ bot), halt (option (pair int nat) @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IEdiv_nat - ~intercept_stack:(zero_n, (zero, eos)) - ~kinstr: - (IEdiv_nat - (kinfo (nat @$ int @$ bot), halt (option (pair int nat) @$ bot))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_ILsl_nat - ~intercept_stack:(zero_n, (zero_n, eos)) - ~kinstr:(ILsl_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) - ~stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = make_default_samplers cfg.sampler in - fun () -> - let x = Samplers.Michelson_base.nat rng_state in - (* shift must be in [0;256]: 1 byte max *) - let shift = - Script_int_repr.(abs (of_int (Random.State.int rng_state 256))) - in - (x, (shift, eos))) - () - - let () = - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_ILsr_nat - ~intercept_stack:(zero_n, (zero_n, eos)) - ~kinstr:(ILsr_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) - ~stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = make_default_samplers cfg.sampler in - fun () -> - let x = Samplers.Michelson_base.nat rng_state in - (* shift must be in [0;256]: 1 byte max *) - let shift = - Script_int_repr.(abs (of_int (Random.State.int rng_state 256))) - in - (x, (shift, eos))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IOr_nat - ~intercept_stack:(zero_n, (zero_n, eos)) - ~kinstr:(IOr_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAnd_nat - ~intercept_stack:(zero_n, (zero_n, eos)) - ~kinstr:(IAnd_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAnd_int_nat - ~intercept_stack:(zero, (zero_n, eos)) - ~kinstr:(IAnd_int_nat (kinfo (int @$ nat @$ bot), halt (nat @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IXor_nat - ~intercept_stack:(zero_n, (zero_n, eos)) - ~kinstr:(IXor_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_INot_int - ~intercept_stack:(zero, eos) - ~kinstr:(INot_int (kinfo (int @$ bot), halt (int @$ bot))) - () - end - - module Control = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_IIf - ~kinstr: - (IIf - { - kinfo = kinfo (bool @$ unit @$ bot); - branch_if_true = halt_unit; - branch_if_false = halt_unit; - k = halt_unit; - }) - () - - let () = - (* - ILoop -> - either - - IHalt (false on top of stack) - - IConst false ; IHalt (true on top of stack) - *) - let push_false = IConst (kinfo_unit, false, halt (bool @$ unit @$ bot)) in - simple_benchmark - ~name:Interpreter_workload.N_ILoop - ~kinstr:(ILoop (kinfo (bool @$ unit @$ bot), push_false, halt_unit)) - () - - let () = - (* - ILoop_left -> - ICons_right -> - IHalt - *) - let cons_r = ICons_right (kinfo_unit, halt (union unit unit @$ bot)) in - simple_benchmark - ~name:Interpreter_workload.N_ILoop_left - ~kinstr:(ILoop_left (kinfo (union unit unit @$ bot), cons_r, halt_unit)) - () - - let () = - (* - IDip -> - IHalt -> - IConst -> - IHalt - *) - simple_benchmark - ~name:Interpreter_workload.N_IDip - ~kinstr:(IDip (kinfo (unit @$ unit @$ bot), halt_unit, halt_unitunit)) - () - - let dummy_lambda = - let open Script_typed_ir in - let descr = - {kloc = 0; kbef = unit @$ bot; kaft = unit @$ bot; kinstr = halt_unit} - in - Lam (descr, Micheline.Int (0, Z.zero)) - - let () = - (* - IExec -> - (switch to in-context gas-counting) -> - interp lambda code -> - IHalt - *) - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IExec - ~kinstr:(IExec (kinfo (unit @$ lambda unit unit @$ bot), halt_unit)) - ~stack_sampler:(fun _cfg _rng_state () -> ((), (dummy_lambda, eos))) - () - - let () = - (* - IApply -> - unparse unit -> - unparse unit_ty -> - construct term -> - IHalt - *) - let code = - let open Script_typed_ir in - let descr = - { - kloc = 0; - kbef = pair unit unit @$ bot; - kaft = unit @$ bot; - kinstr = ICdr (kinfo (pair unit unit @$ bot), halt_unit); - } - in - Lam (descr, Micheline.Int (0, Z.zero)) - in - simple_benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IApply - ~kinstr: - (IApply - ( kinfo (unit @$ lambda (pair unit unit) unit @$ bot), - unit, - halt (lambda unit unit @$ bot) )) - ~stack_sampler:(fun _cfg _rng_state () -> ((), (code, eos))) - () - - let () = - (* - ILambda -> - IHalt - *) - simple_benchmark - ~name:Interpreter_workload.N_ILambda - ~kinstr: - (ILambda - (kinfo_unit, dummy_lambda, halt (lambda unit unit @$ unit @$ bot))) - () - - let () = - (* - IFailwith -> - (unparse_data Unit) -> - (strip_locations) -> - fail - *) - simple_benchmark - ~name:Interpreter_workload.N_IFailwith - ~amplification:100 - ~kinstr:(IFailwith (kinfo_unit, 0, unit)) - () - end - - module Comparison = struct - let () = - benchmark - ~name:Interpreter_workload.N_ICompare - ~kinstr_and_stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = make_default_samplers cfg.sampler in - fun () -> - let size = - Base_samplers.sample_in_interval - rng_state - ~range:cfg.compare.type_size - in - let (Script_ir_translator.Ex_comparable_ty cmp_ty) = - Samplers.Random_type.m_comparable_type ~size rng_state - in - let ty = Script_ir_translator.ty_of_comparable_ty cmp_ty in - let value = Samplers.Random_value.comparable cmp_ty rng_state in - let kinstr = - ICompare (kinfo (ty @$ ty @$ bot), cmp_ty, halt (int @$ bot)) - in - Ex_stack_and_kinstr {stack = (value, (value, eos)); kinstr}) - () - end - - module Comparators = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_IEq - ~kinstr:(IEq (kinfo (int @$ bot), halt (bool @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_INeq - ~kinstr:(INeq (kinfo (int @$ bot), halt (bool @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ILt - ~kinstr:(ILt (kinfo (int @$ bot), halt (bool @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IGt - ~kinstr:(IGt (kinfo (int @$ bot), halt (bool @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ILe - ~kinstr:(ILe (kinfo (int @$ bot), halt (bool @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IGe - ~kinstr:(IGe (kinfo (int @$ bot), halt (bool @$ bot))) - () - end - - module Proto = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAddress - ~kinstr:(IAddress (kinfo (contract unit @$ bot), halt (address @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IContract - ~kinstr: - (IContract - ( kinfo (address @$ bot), - unit, - "default", - halt (option (contract unit) @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ITransfer_tokens - ~kinstr: - (ITransfer_tokens - ( kinfo (unit @$ mutez @$ contract unit @$ bot), - halt (operation @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IImplicit_account - ~kinstr: - (IImplicit_account - (kinfo (key_hash @$ bot), halt (contract unit @$ bot))) - () - - let () = - let lambda = - let open Script_typed_ir in - let descr = - { - kloc = 0; - kbef = pair unit unit @$ bot; - kaft = pair (list operation) unit @$ bot; - kinstr = - ICdr - ( kinfo (pair unit unit @$ bot), - INil - ( kinfo (unit @$ bot), - ICons_pair - ( kinfo (list operation @$ unit @$ bot), - IHalt (kinfo (pair (list operation) unit @$ bot)) ) ) - ); - } - in - Lam (descr, Micheline.Int (0, Z.zero)) - in - simple_benchmark - ~name:Interpreter_workload.N_ICreate_contract - ~kinstr: - (ICreate_contract - { - kinfo = kinfo (option key_hash @$ mutez @$ unit @$ bot); - storage_type = unit; - arg_type = unit; - lambda; - views = SMap.empty; - root_name = None; - k = halt (operation @$ address @$ bot); - }) - () - - let () = - let name = - match Protocol.Alpha_context.Script_string.of_string "view" with - | Ok s -> s - | Error _ -> assert false - in - simple_benchmark - ~name:Interpreter_workload.N_IView - ~kinstr: - (IView - ( kinfo (unit @$ address @$ bot), - View_signature {name; input_ty = unit; output_ty = unit}, - halt (option unit @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISet_delegate - ~kinstr: - (ISet_delegate - (kinfo (option key_hash @$ bot), halt (operation @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_INow - ~kinstr:(INow (kinfo (unit @$ bot), halt (timestamp @$ unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IBalance - ~kinstr:(IBalance (kinfo (unit @$ bot), halt (mutez @$ unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ILevel - ~kinstr:(ILevel (kinfo (unit @$ bot), halt (nat @$ unit @$ bot))) - () - - let check_signature (algo : Signature.algo) ~for_intercept = - let name = - match algo with - | Signature.Ed25519 -> Interpreter_workload.N_ICheck_signature_ed25519 - | Signature.Secp256k1 -> - Interpreter_workload.N_ICheck_signature_secp256k1 - | Signature.P256 -> Interpreter_workload.N_ICheck_signature_p256 - in - benchmark_with_stack_sampler - ~intercept:for_intercept - ~name - ~kinstr: - (ICheck_signature - ( kinfo (public_key @$ signature @$ bytes @$ bot), - halt (bool @$ bot) )) - ~stack_sampler:(fun cfg rng_state -> - let ((module Crypto_samplers), (module Samplers)) = - make_default_samplers ~algo:(`Algo algo) cfg.Default_config.sampler - in - fun () -> - let (_pkh, pk, sk) = Crypto_samplers.all rng_state in - let unsigned_message = - if for_intercept then Environment.Bytes.empty - else - Samplers.Random_value.value - Script_typed_ir.(bytes_t ~annot:None) - rng_state - in - let signed_message = Signature.sign sk unsigned_message in - (pk, (signed_message, (unsigned_message, eos)))) - () - - let check_signature algo = - check_signature algo ~for_intercept:true ; - check_signature algo ~for_intercept:false - - let () = check_signature Signature.Ed25519 - - let () = check_signature Signature.Secp256k1 - - let () = check_signature Signature.P256 - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IHash_key - ~kinstr:(IHash_key (kinfo (public_key @$ bot), halt (key_hash @$ bot))) - () - - let () = - benchmark - ~name:Interpreter_workload.N_IPack - ~kinstr_and_stack_sampler:(fun _cfg _rng_state -> - let kinstr = IPack (kinfo (unit @$ bot), unit, halt (bytes @$ bot)) in - fun () -> Ex_stack_and_kinstr {stack = ((), eos); kinstr}) - () - - let () = - benchmark - ~name:Interpreter_workload.N_IUnpack - ~kinstr_and_stack_sampler:(fun _cfg rng_state -> - let b = - raise_if_error - (Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - Script_ir_translator.pack_data ctxt unit () - >|= Environment.wrap_tzresult - >>=? fun (bytes, _) -> return bytes )) - in - let kinstr = - IUnpack (kinfo (bytes @$ bot), unit, halt (option unit @$ bot)) - in - fun () -> Ex_stack_and_kinstr {stack = (b, eos); kinstr}) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IBlake2b - ~intercept_stack:(Environment.Bytes.empty, eos) - ~kinstr:(IBlake2b (kinfo (bytes @$ bot), halt (bytes @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISha256 - ~intercept_stack:(Environment.Bytes.empty, eos) - ~kinstr:(ISha256 (kinfo (bytes @$ bot), halt (bytes @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISha512 - ~intercept_stack:(Environment.Bytes.empty, eos) - ~kinstr:(ISha512 (kinfo (bytes @$ bot), halt (bytes @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IKeccak - ~intercept_stack:(Environment.Bytes.empty, eos) - ~kinstr:(IKeccak (kinfo (bytes @$ bot), halt (bytes @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISha3 - ~intercept_stack:(Environment.Bytes.empty, eos) - ~kinstr:(ISha3 (kinfo (bytes @$ bot), halt (bytes @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISource - ~kinstr:(ISource (kinfo (unit @$ bot), halt (address @$ unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISender - ~kinstr:(ISender (kinfo (unit @$ bot), halt (address @$ unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISelf - ~kinstr: - (ISelf - ( kinfo (unit @$ bot), - unit, - "default", - halt (contract unit @$ unit @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ISelf_address - ~kinstr: - (ISelf_address (kinfo (unit @$ bot), halt (address @$ unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAmount - ~kinstr:(IAmount (kinfo (unit @$ bot), halt (mutez @$ unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IChainId - ~kinstr:(IChainId (kinfo (unit @$ bot), halt (chain_id @$ unit @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IVoting_power - ~kinstr:(IVoting_power (kinfo (key_hash @$ bot), halt (nat @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_ITotal_voting_power - ~kinstr: - (ITotal_voting_power (kinfo (unit @$ bot), halt (nat @$ unit @$ bot))) - () - end - - module Sapling = struct - let () = - let memo_size = - match Alpha_context.Sapling.Memo_size.parse_z Z.zero with - | Error _ -> assert false - | Ok sz -> sz - in - simple_benchmark - ~name:Interpreter_workload.N_ISapling_empty_state - ~kinstr: - (ISapling_empty_state - ( kinfo (unit @$ bot), - memo_size, - halt (sapling_state memo_size @$ unit @$ bot) )) - () - - let () = - (* Note that memo_size is hardcoded to 0 in module [Sapling_generation]. *) - let memo_size = - match Alpha_context.Sapling.Memo_size.parse_z Z.zero with - | Error _ -> assert false - | Ok sz -> sz - in - let (info, name) = - info_and_name ~intercept:false "ISapling_verify_update" - in - let module B : Benchmark.S = struct - let name = name - - let info = info - - include Default_config - include Default_boilerplate - - let models = - Interpreter_model.make_model - (Some (Instr_name Interpreter_workload.N_ISapling_verify_update)) - - let kinstr = - let spl_state = sapling_state memo_size in - let spl_tx = sapling_transaction memo_size in - ISapling_verify_update - ( kinfo (spl_tx @$ spl_state @$ bot), - halt (option (pair int spl_state) @$ bot) ) - - let prepare_sapling_execution_environment sapling_forge_rng_seed - sapling_transition = - let sapling_forge_rng_state = - Random.State.make - @@ Option.fold - ~none:Sapling_generation.shared_seed - ~some:(fun seed -> [|seed|]) - sapling_forge_rng_seed - in - (* Prepare context. We _must_ reuse the same seed as the one used for - the context when generating the transactions. This ensures that the - bootstrap account match and that the transactions can be replayed. *) - let result = - Lwt_main.run - ( Execution_context.make ~rng_state:sapling_forge_rng_state - >>=? fun (ctxt, step_constants) -> - (* Prepare a sapling state able to replay the transition. *) - Sapling_generation.prepare_seeded_state sapling_transition ctxt - >>=? fun (_, _, _, _, ctxt, state_id) -> - Alpha_context.Sapling.(state_from_id ctxt (Id.parse_z state_id)) - >|= Environment.wrap_tzresult - >>=? fun (state, ctxt) -> return (ctxt, state, step_constants) - ) - in - match result with - | Ok r -> r - | Error _ -> - Format.eprintf - "Error in prepare_sapling_execution_environment, aborting@." ; - Stdlib.failwith "prepare_sapling_execution_environment" - - let create_benchmarks ~rng_state ~bench_num (config : config) = - ignore rng_state ; - match config.sapling with - | {sapling_txs_file; seed} -> - let transitions = - Sapling_generation.load ~filename:sapling_txs_file - in - let length = List.length transitions in - if length < bench_num then - Format.eprintf - "ISapling_verify_update: warning, only %d available \ - transactions (requested %d)@." - length - bench_num ; - let transitions = - List.take_n (min bench_num length) transitions - in - List.map - (fun (_, transition) () -> - let (ctxt, state, step_constants) = - prepare_sapling_execution_environment seed transition - in - let stack_instr = - Ex_stack_and_kinstr - {stack = (transition.sapling_tx, (state, eos)); kinstr} - in - benchmark_from_kinstr_and_stack - ctxt - step_constants - stack_instr) - transitions - end in - Registration_helpers.register (module B) - end - - (* when benchmarking, compile bls12-381-unix without ADX, see - https://gitlab.com/dannywillems/ocaml-bls12-381/-/blob/71d0b4d467fbfaa6452d702fcc408d7a70916a80/README.md#install - *) - module Bls12_381 = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAdd_bls12_381_g1 - ~kinstr: - (IAdd_bls12_381_g1 - ( kinfo (bls12_381_g1 @$ bls12_381_g1 @$ bot), - halt (bls12_381_g1 @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAdd_bls12_381_g2 - ~kinstr: - (IAdd_bls12_381_g2 - ( kinfo (bls12_381_g2 @$ bls12_381_g2 @$ bot), - halt (bls12_381_g2 @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IAdd_bls12_381_fr - ~kinstr: - (IAdd_bls12_381_fr - ( kinfo (bls12_381_fr @$ bls12_381_fr @$ bot), - halt (bls12_381_fr @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IMul_bls12_381_g1 - ~kinstr: - (IMul_bls12_381_g1 - ( kinfo (bls12_381_g1 @$ bls12_381_fr @$ bot), - halt (bls12_381_g1 @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IMul_bls12_381_g2 - ~kinstr: - (IMul_bls12_381_g2 - ( kinfo (bls12_381_g2 @$ bls12_381_fr @$ bot), - halt (bls12_381_g2 @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IMul_bls12_381_fr - ~kinstr: - (IMul_bls12_381_fr - ( kinfo (bls12_381_fr @$ bls12_381_fr @$ bot), - halt (bls12_381_fr @$ bot) )) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IMul_bls12_381_z_fr - ~kinstr: - (IMul_bls12_381_z_fr - (kinfo (bls12_381_fr @$ int @$ bot), halt (bls12_381_fr @$ bot))) - () - - let () = - benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IMul_bls12_381_z_fr - ~intercept:true - ~kinstr: - (IMul_bls12_381_z_fr - (kinfo (bls12_381_fr @$ int @$ bot), halt (bls12_381_fr @$ bot))) - ~stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = make_default_samplers cfg.sampler in - let fr_sampler = Samplers.Random_value.value bls12_381_fr in - let zero = Alpha_context.Script_int.zero in - fun () -> (fr_sampler rng_state, (zero, eos))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IMul_bls12_381_fr_z - ~kinstr: - (IMul_bls12_381_fr_z - (kinfo (int @$ bls12_381_fr @$ bot), halt (bls12_381_fr @$ bot))) - () - - let () = - benchmark_with_stack_sampler - ~name:Interpreter_workload.N_IMul_bls12_381_fr_z - ~intercept:true - ~kinstr: - (IMul_bls12_381_fr_z - (kinfo (int @$ bls12_381_fr @$ bot), halt (bls12_381_fr @$ bot))) - ~stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = make_default_samplers cfg.sampler in - let fr_sampler = Samplers.Random_value.value bls12_381_fr in - let zero = Alpha_context.Script_int.zero in - fun () -> (zero, (fr_sampler rng_state, eos))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IInt_bls12_381_z_fr - ~kinstr: - (IInt_bls12_381_fr (kinfo (bls12_381_fr @$ bot), halt (int @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_INeg_bls12_381_g1 - ~kinstr: - (INeg_bls12_381_g1 - (kinfo (bls12_381_g1 @$ bot), halt (bls12_381_g1 @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_INeg_bls12_381_g2 - ~kinstr: - (INeg_bls12_381_g2 - (kinfo (bls12_381_g2 @$ bot), halt (bls12_381_g2 @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_INeg_bls12_381_fr - ~kinstr: - (INeg_bls12_381_fr - (kinfo (bls12_381_fr @$ bot), halt (bls12_381_fr @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IPairing_check_bls12_381 - ~kinstr: - (IPairing_check_bls12_381 - ( kinfo (list (pair bls12_381_g1 bls12_381_g2) @$ bot), - halt (bool @$ bot) )) - () - end - - module Tickets = struct - let () = - simple_benchmark - ~name:Interpreter_workload.N_ITicket - ~kinstr: - (ITicket (kinfo (unit @$ nat @$ bot), halt (ticket unit_cmp @$ bot))) - () - - let () = - simple_benchmark - ~name:Interpreter_workload.N_IRead_ticket - ~kinstr: - (IRead_ticket - ( kinfo (ticket unit_cmp @$ bot), - halt (pair address (pair unit nat) @$ ticket unit_cmp @$ bot) )) - () - - let split_ticket_instr = - ISplit_ticket - ( kinfo (ticket unit_cmp @$ pair nat nat @$ bot), - halt (option (pair (ticket unit_cmp) (ticket unit_cmp)) @$ bot) ) - - let () = - let zero = Alpha_context.Script_int.zero_n in - let ticket = - { - ticketer = - Alpha_context.Contract.implicit_contract - Environment.Signature.Public_key_hash.zero; - contents = (); - amount = zero; - } - in - benchmark_with_fixed_stack - ~intercept:true - ~name:Interpreter_workload.N_ISplit_ticket - ~stack:(ticket, ((zero, zero), eos)) - ~kinstr:split_ticket_instr - () - - let () = - benchmark - ~name:Interpreter_workload.N_ISplit_ticket - ~kinstr_and_stack_sampler:(fun config rng_state -> - let (_, (module Samplers)) = - make_default_samplers config.Default_config.sampler - in - fun () -> - let half_amount = Samplers.Random_value.value nat rng_state in - let amount = - Alpha_context.Script_int.add_n half_amount half_amount - in - let ticket = - Samplers.Random_value.value (ticket unit_cmp) rng_state - in - let ticket = {ticket with amount} in - Ex_stack_and_kinstr - { - stack = (ticket, ((half_amount, half_amount), eos)); - kinstr = split_ticket_instr; - }) - () - - let join_tickets_instr = - IJoin_tickets - ( kinfo (pair (ticket string_cmp) (ticket string_cmp) @$ bot), - string_cmp, - halt (option (ticket string_cmp) @$ bot) ) - - let () = - benchmark - ~intercept:true - ~name:Interpreter_workload.N_IJoin_tickets - ~kinstr_and_stack_sampler:(fun config rng_state -> - let (_, (module Samplers)) = - make_default_samplers config.Default_config.sampler - in - fun () -> - let ticket = - Samplers.Random_value.value (ticket string_cmp) rng_state - in - let ticket = - { - ticket with - contents = Alpha_context.Script_string.empty; - amount = Script_int_repr.zero_n; - } - in - Ex_stack_and_kinstr - {stack = ((ticket, ticket), eos); kinstr = join_tickets_instr}) - () - - let () = - benchmark - ~name:Interpreter_workload.N_IJoin_tickets - ~kinstr_and_stack_sampler:(fun config rng_state -> - let (_, (module Samplers)) = - make_default_samplers config.Default_config.sampler - in - fun () -> - let ticket = - Samplers.Random_value.value (ticket string_cmp) rng_state - in - let alt_amount = Samplers.Random_value.value nat rng_state in - let ticket' = {ticket with amount = alt_amount} in - Ex_stack_and_kinstr - {stack = ((ticket, ticket'), eos); kinstr = join_tickets_instr}) - () - end - - module Timelock = struct - let name = Interpreter_workload.N_IOpen_chest - - let kinstr = - IOpen_chest - ( kinfo - (Michelson_types.chest_key @$ Michelson_types.chest @$ nat @$ bot), - halt (union bytes bool @$ bot) ) - - let resulting_stack chest chest_key time = - ( chest_key, - ( chest, - ( Script_int_repr.is_nat (Script_int_repr.of_int time) - |> WithExceptions.Option.get ~loc:"Timelock:gas benchmarks", - eos ) ) ) - - let () = - benchmark_with_stack_sampler - ~intercept:true - ~name - ~kinstr - ~stack_sampler:(fun _ rng_state () -> - let (chest, chest_key) = - Timelock.chest_sampler ~plaintext_size:1 ~time:0 ~rng_state - in - resulting_stack chest chest_key 0) - () - - let () = - benchmark_with_stack_sampler - ~name - ~kinstr - ~stack_sampler:(fun _ rng_state () -> - let log_time = - Base_samplers.sample_in_interval - ~range:{min = 0; max = 29} - rng_state - in - let time = Random.State.int rng_state (Int.shift_left 1 log_time) in - let plaintext_size = - Base_samplers.sample_in_interval - ~range:{min = 1; max = 10000} - rng_state - in - - let (chest, chest_key) = - Timelock.chest_sampler ~plaintext_size ~time ~rng_state - in - resulting_stack chest chest_key time) - () - end - - module Continuations = struct - let () = - (* - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KNil - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let cont = KNil in - let stack = eos in - fun () -> Ex_stack_and_cont {stack; cont}) - () - - let () = - (* - KCons -> step - KHalt -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KCons - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let cont = KCons (halt_unit, KNil) in - let stack = ((), eos) in - fun () -> Ex_stack_and_cont {stack; cont}) - () - - let () = - (* - KReturn -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KReturn - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let cont = KReturn (halt_unit, KNil) in - let stack = ((), eos) in - fun () -> Ex_stack_and_cont {stack; cont}) - () - - let () = - (* - KView_exit -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KView_exit - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let open Script_typed_ir in - let open Alpha_context in - let zero = - Contract.implicit_contract Signature.Public_key_hash.zero - in - let step_constants = - { - source = zero; - payer = zero; - self = zero; - amount = Tez.zero; - chain_id = Chain_id.zero; - now = Script_timestamp.of_zint Z.zero; - level = Script_int.zero_n; - } - in - let cont = KView_exit (step_constants, KNil) in - let stack = ((), eos) in - fun () -> Ex_stack_and_cont {stack; cont}) - () - - let () = - (* - KLoop_in -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KLoop_in - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let cont = - KLoop_in - (IConst (kinfo_unit, false, halt (bool @$ unit @$ bot)), KNil) - in - let stack = (false, ((), eos)) in - fun () -> Ex_stack_and_cont {stack; cont}) - () - - let () = - (* - KLoop_in_left -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KLoop_in_left - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let cont = - KLoop_in_left - (ICons_right (kinfo_unit, halt (union unit unit @$ bot)), KNil) - in - let stack = (R (), eos) in - fun () -> Ex_stack_and_cont {stack; cont}) - () - - let () = - (* - KUndip -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KUndip - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let cont = KUndip ((), KNil) in - let stack = eos in - fun () -> Ex_stack_and_cont {stack; cont}) - () - - let () = - (* - KIter (empty case) -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KIter - ~salt:"_empty" - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let cont = KIter (IDrop (kinfo_unitunit, halt_unit), [], KNil) in - let stack = ((), eos) in - fun () -> Ex_stack_and_cont {stack; cont}) - () - - let () = - (* - KIter (nonempty case) -> step - KDrop -> step - KHalt -> next - KIter (empty case) -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KIter - ~salt:"_nonempty" - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let cont = KIter (IDrop (kinfo_unitunit, halt_unit), [()], KNil) in - let stack = ((), eos) in - fun () -> Ex_stack_and_cont {stack; cont}) - () - - let () = - (* - KList_enter_body ([()], bot accumulator case) -> step - KHalt -> next - KList_exit_body ([], []) -> - KList_enter_body ([], [()] -> - List.rev singleton - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KList_enter_body - ~salt:"_singleton_list" - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let kbody = halt_unitunit in - fun () -> - let cont = KList_enter_body (kbody, [()], [], 1, KNil) in - Ex_stack_and_cont {stack = ((), eos); cont}) - () - - let () = - (* - KList_enter_body (empty list, nonempty accumulator case) -> - {List.rev n elements} -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KList_enter_body - ~salt:"_terminal" - ~cont_and_stack_sampler:(fun cfg rng_state -> - let (_, (module Samplers)) = make_default_samplers cfg.sampler in - let kbody = halt_unitunit in - fun () -> - let ys = Samplers.Random_value.value (list unit) rng_state in - let cont = - KList_enter_body (kbody, [], ys.elements, ys.length, KNil) - in - Ex_stack_and_cont {stack = ((), eos); cont}) - () - - let () = - (* - KList_enter_body (empty list, bot accumulator case) -> - {List.rev singleton} -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~intercept:true - ~name:Interpreter_workload.N_KList_enter_body - ~salt:"_terminal" - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let kbody = halt_unitunit in - fun () -> - let cont = KList_enter_body (kbody, [], [], 1, KNil) in - Ex_stack_and_cont {stack = ((), eos); cont}) - () - - let () = - (* - KList_exit_body (empty list) -> next - KList_enter_body -> - {List.rev 1 element} -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~intercept:true - ~name:Interpreter_workload.N_KList_exit_body - ~salt:"_terminal" - ~cont_and_stack_sampler:(fun _cfg _rng_state -> - let kbody = halt_unitunit in - let cont = KList_exit_body (kbody, [], [], 1, KNil) in - fun () -> Ex_stack_and_cont {stack = ((), ((), eos)); cont}) - () - - let map_enter_body_code = - let kbody = ICdr (kinfo (pair int unit @$ unit @$ bot), halt_unitunit) in - fun accu -> KMap_enter_body (kbody, accu, Script_map.empty int_cmp, KNil) - - let () = - (* - KMap_enter_body (empty case) -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~salt:"_empty" - ~name:Interpreter_workload.N_KMap_enter_body - ~cont_and_stack_sampler:(fun _cfg _rng_state () -> - Ex_stack_and_cont {stack = ((), eos); cont = map_enter_body_code []}) - () - - let () = - (* - KMap_enter_body (singleton case) -> step - KCdr -> step - KHalt -> next - KMap_exit_body -> next - (map_update) - KMap_enter_body (empty case) -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~salt:"_singleton" - ~name:Interpreter_workload.N_KMap_enter_body - ~cont_and_stack_sampler:(fun _cfg _rng_state () -> - Ex_stack_and_cont - { - stack = ((), eos); - cont = map_enter_body_code [(Script_int_repr.zero, ())]; - }) - () - - let () = - (* - KMap_exit_body -> - (map_update) -> next - KMap_enter_body (empty case) -> next - KNil - *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KMap_exit_body - ~cont_and_stack_sampler:(fun cfg rng_state -> - let kbody = - ICdr (kinfo (pair int unit @$ unit @$ bot), halt_unitunit) - in - fun () -> - let (key, map) = Maps.generate_map_and_key_in_map cfg rng_state in - let cont = KMap_exit_body (kbody, [], map, key, KNil) in - Ex_stack_and_cont {stack = ((), ((), eos)); cont}) - () - - let () = - (* KMap_head -> KNil *) - continuation_benchmark - ~amplification:100 - ~name:Interpreter_workload.N_KMap_head - ~cont_and_stack_sampler:(fun _cfg _rng_state () -> - let cont = KMap_head (Option.some, KNil) in - Ex_stack_and_cont {stack = ((), ((), eos)); cont}) - () - end -end diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_model.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_model.ml deleted file mode 100644 index 9231a9156768..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_model.ml +++ /dev/null @@ -1,538 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* ------------------------------------------------------------------------- *) - -let trace_error expected given = - let open Interpreter_workload in - let exp = string_of_instr_or_cont expected in - let given = string_of_instr_or_cont given in - let msg = - Format.asprintf - "Interpreter_model: trace error, expected %s, given %s" - exp - given - in - Stdlib.failwith msg - -let arity_error instr expected given = - let open Interpreter_workload in - let s = string_of_instr_or_cont instr in - let msg = - Format.asprintf - "Interpreter_model: arity error (%s), expected %d, given %a" - s - expected - Interpreter_workload.pp_args - given - in - Stdlib.failwith msg - -(* ------------------------------------------------------------------------- *) - -let model_0 instr model = - let open Interpreter_workload in - Model.make - ~conv:(function - | {name; args = []} -> if name = instr then () else trace_error instr name - | {args; _} -> arity_error instr 0 args) - ~model - -let model_1 instr model = - let open Interpreter_workload in - Model.make - ~conv:(function - | {name; args = [{name = _; arg}]} -> - if name = instr then (arg, ()) else trace_error instr name - | {args; _} -> arity_error instr 1 args) - ~model - -let model_2 instr model = - let open Interpreter_workload in - Model.make - ~conv:(function - | {name; args = [{name = _; arg = x}; {name = _; arg = y}]} -> - if name = instr then (x, (y, ())) else trace_error instr name - | {args; _} -> arity_error instr 2 args) - ~model - -let model_3 instr model = - let open Interpreter_workload in - Model.make - ~conv:(function - | { - name; - args = [{name = _; arg = x}; {name = _; arg = y}; {name = _; arg = z}]; - } -> - if name = instr then (x, (y, (z, ()))) else trace_error instr name - | {args; _} -> arity_error instr 3 args) - ~model - -let model_4 instr model = - let open Interpreter_workload in - Model.make - ~conv:(function - | { - name; - args = - [ - {name = _; arg = w}; - {name = _; arg = x}; - {name = _; arg = y}; - {name = _; arg = z}; - ]; - } -> - if name = instr then (w, (x, (y, (z, ())))) - else trace_error instr name - | {args; _} -> arity_error instr 4 args) - ~model - -let fv = Free_variable.of_string - -let sf = Format.asprintf - -let division_cost name = - let const = fv (sf "%s_const" name) in - let coeff = fv (sf "%s_coeff" name) in - let module M = struct - type arg_type = int * (int * unit) - - module Def (X : Costlang.S) = struct - open X - - type model_type = size -> size -> size - - let arity = Model.arity_2 - - let model = - lam ~name:"size1" @@ fun size1 -> - lam ~name:"size2" @@ fun size2 -> - let_ ~name:"q" (size1 - size2) @@ fun q -> - (free ~name:coeff * if_ (lt size2 size1) (q * size2) (int 0)) - + free ~name:const - end - end in - (module M : Model.Model_impl with type arg_type = int * (int * unit)) - -let addlogadd name = - let const = fv (sf "%s_const" name) in - let coeff = fv (sf "%s_coeff" name) in - let module M = struct - type arg_type = int * (int * unit) - - module Def (X : Costlang.S) = struct - open X - - type model_type = size -> size -> size - - let arity = Model.arity_2 - - let model = - lam ~name:"size1" @@ fun size1 -> - lam ~name:"size2" @@ fun size2 -> - let_ ~name:"a" (size1 + size2) @@ fun a -> - (free ~name:coeff * (a * log2 (int 1 + a))) + free ~name:const - end - end in - (module M : Model.Model_impl with type arg_type = int * (int * unit)) - -(* Some instructions are oveloaded (eg COMPARE). In order to generate distinct - models at different types, we must specialize these models. The [specialization] - parameter acts as a mangling scheme to produce distinct models. *) -let name_of_instr_or_cont ?specialization instr_or_cont = - let spec = Option.fold ~none:"" ~some:(fun s -> "_" ^ s) specialization in - Interpreter_workload.string_of_instr_or_cont instr_or_cont ^ spec - -module Models = struct - let const1_model name = - (* For constant-time instructions *) - Model.unknown_const1 ~const:(fv (sf "%s_const" name)) - - let affine_model name = - (* For instructions with cost function - [\lambda size. const + coeff * size] *) - Model.affine - ~intercept:(fv (sf "%s_const" name)) - ~coeff:(fv (sf "%s_coeff" name)) - - let break_model name break = - Model.breakdown - ~coeff1:(fv (sf "%s_coeff1" name)) - ~coeff2:(fv (sf "%s_coeff2" name)) - ~break - - let break_model_2 name break1 break2 = - Model.breakdown2 - ~coeff1:(fv (sf "%s_coeff1" name)) - ~coeff2:(fv (sf "%s_coeff2" name)) - ~coeff3:(fv (sf "%s_coeff3" name)) - ~break1 - ~break2 - - let break_model_2_const name break1 break2 = - Model.breakdown2_const - ~coeff1:(fv (sf "%s_coeff1" name)) - ~coeff2:(fv (sf "%s_coeff2" name)) - ~coeff3:(fv (sf "%s_coeff3" name)) - ~const:(fv (sf "%s_const" name)) - ~break1 - ~break2 - - let nlogm_model name = - (* For instructions with cost function - [\lambda size1. \lambda size2. const + coeff * size1 log2(size2)] *) - Model.nlogm - ~intercept:(fv (sf "%s_const" name)) - ~coeff:(fv (sf "%s_coeff" name)) - - let concat_model name = - Model.bilinear_affine - ~intercept:(fv (sf "%s_const" name)) - ~coeff1:(fv (sf "%s_total_bytes" name)) - ~coeff2:(fv (sf "%s_list_length" name)) - - let concat_pair_model name = - Model.linear_sum - ~intercept:(fv (sf "%s_const" name)) - ~coeff:(fv (sf "%s_coeff" name)) - - let linear_max_model name = - (* For instructions with cost function - [\lambda size1. \lambda size2. const + coeff * max(size1,size2)] *) - Model.linear_max - ~intercept:(fv (sf "%s_const" name)) - ~coeff:(fv (sf "%s_coeff" name)) - - let linear_min_model name = - (* For instructions with cost function - [\lambda size1. \lambda size2. const + coeff * min(size1,size2)] *) - Model.linear_min - ~intercept:(fv (sf "%s_const" name)) - ~coeff:(fv (sf "%s_coeff" name)) - - let pack_model name = - Model.trilinear - ~coeff1:(fv (sf "%s_micheline_nodes" name)) - ~coeff2:(fv (sf "%s_micheline_int_bytes" name)) - ~coeff3:(fv (sf "%s_micheline_string_bytes" name)) - - let split_ticket_model name = - let module M = struct - type arg_type = int * (int * unit) - - module Def (X : Costlang.S) = struct - open X - - type model_type = size -> size -> size - - let arity = Model.arity_2 - - let model = - lam ~name:"size1" @@ fun size1 -> - lam ~name:"size2" @@ fun size2 -> - free ~name:(fv (sf "%s_const" name)) - + (free ~name:(fv (sf "%s_add_coeff" name)) * max size1 size2) - + (free ~name:(fv (sf "%s_cmp_coeff" name)) * min size1 size2) - end - end in - (module M : Model.Model_impl with type arg_type = int * (int * unit)) - - let open_chest_model name = - let module M = struct - type arg_type = int * (int * unit) - - module Def (X : Costlang.S) = struct - open X - - type model_type = size -> size -> size - - let arity = Model.arity_2 - - let model = - lam ~name:"size1" @@ fun size1 -> - lam ~name:"size2" @@ fun size2 -> - free ~name:(fv (sf "%s_const" name)) - + (free ~name:(fv (sf "%s_log_time_coeff" name)) * size1) - + (free ~name:(fv (sf "%s_plaintext_coeff" name)) * size2) - end - end in - (module M : Model.Model_impl with type arg_type = int * (int * unit)) - - let verify_update_model name = - Model.bilinear_affine - ~intercept:(fv (sf "%s_const" name)) - ~coeff1:(fv (sf "%s_inputs" name)) - ~coeff2:(fv (sf "%s_ouputs" name)) - - let list_enter_body_model name = - let module M = struct - type arg_type = int * (int * unit) - - module Def (X : Costlang.S) = struct - open X - - type model_type = size -> size -> size - - let arity = Model.arity_2 - - let model = - lam ~name:"size_xs" @@ fun size_xs -> - lam ~name:"size_ys" @@ fun size_ys -> - if_ - (eq size_xs (int 0)) - (free ~name:(fv (sf "%s_const" name)) - + (free ~name:(fv (sf "%s_coeff" name)) * size_ys)) - (free ~name:(fv (sf "%s_iter" name))) - end - end in - (module M : Model.Model_impl with type arg_type = int * (int * unit)) - - let branching_model name = - let module M = struct - type arg_type = int * unit - - module Def (X : Costlang.S) = struct - open X - - type model_type = size -> size - - let arity = Model.arity_1 - - let model = - lam ~name:"size" @@ fun size -> - if_ - (eq size (int 0)) - (free ~name:(fv (sf "%s_empty" name))) - (free ~name:(fv (sf "%s_nonempty" name))) - end - end in - (module M : Model.Model_impl with type arg_type = int * unit) - - let join_tickets_model name = - let module M = struct - type arg_type = int * (int * (int * (int * unit))) - - module Def (X : Costlang.S) = struct - open X - - type model_type = size -> size -> size -> size -> size - - let arity = Model.Succ_arity Model.arity_3 - - let model = - lam ~name:"content_size_x" @@ fun content_size_x -> - lam ~name:"content_size_y" @@ fun content_size_y -> - lam ~name:"amount_size_x" @@ fun amount_size_x -> - lam ~name:"amount_size_y" @@ fun amount_size_y -> - free ~name:(fv (sf "%s_const" name)) - + free ~name:(fv (sf "%s_compare_coeff" name)) - * min content_size_x content_size_y - + free ~name:(fv (sf "%s_add_coeff" name)) - * max amount_size_x amount_size_y - end - end in - (module M : Model.Model_impl - with type arg_type = int * (int * (int * (int * unit)))) -end - -let ir_model ?specialization instr_or_cont = - let open Interpreter_workload in - let open Models in - let name = name_of_instr_or_cont ?specialization instr_or_cont in - match instr_or_cont with - | Instr_name instr -> ( - match instr with - | N_IDrop | N_IDup | N_ISwap | N_IConst | N_ICons_pair | N_ICar | N_ICdr - | N_ICons_some | N_ICons_none | N_IIf_none | N_IOpt_map | N_ILeft - | N_IRight | N_IIf_left | N_ICons_list | N_INil | N_IIf_cons - | N_IEmpty_set | N_IEmpty_map | N_IEmpty_big_map | N_IOr | N_IAnd | N_IXor - | N_INot | N_IIf | N_ILoop | N_ILoop_left | N_IDip | N_IExec | N_IView - | N_ILambda | N_IFailwith | N_IAddress | N_ICreate_contract - | N_ISet_delegate | N_INow | N_IBalance | N_IHash_key | N_IUnpack - | N_ISource | N_ISender | N_ISelf | N_IAmount | N_IChainId | N_ILevel - | N_ISelf_address | N_INever | N_IUnpair | N_IVoting_power - | N_ITotal_voting_power | N_IList_size | N_ISet_size | N_IMap_size - | N_ISapling_empty_state -> - model_0 instr_or_cont (const1_model name) - | N_ISet_mem | N_ISet_update | N_IMap_mem | N_IMap_get | N_IMap_update - | N_IBig_map_mem | N_IBig_map_get | N_IBig_map_update - | N_IMap_get_and_update | N_IBig_map_get_and_update -> - model_2 instr_or_cont (nlogm_model name) - | N_IConcat_string -> model_2 instr_or_cont (concat_model name) - | N_IConcat_string_pair -> model_2 instr_or_cont (concat_pair_model name) - | N_ISlice_string -> model_1 instr_or_cont (affine_model name) - | N_IString_size -> model_0 instr_or_cont (const1_model name) - | N_IConcat_bytes -> model_2 instr_or_cont (concat_model name) - | N_IConcat_bytes_pair -> model_2 instr_or_cont (concat_pair_model name) - | N_ISlice_bytes -> model_1 instr_or_cont (affine_model name) - | N_IBytes_size -> model_0 instr_or_cont (const1_model name) - | N_IAdd_seconds_to_timestamp | N_IAdd_timestamp_to_seconds - | N_ISub_timestamp_seconds | N_IDiff_timestamps -> - model_2 instr_or_cont (linear_max_model name) - | N_IAdd_tez | N_ISub_tez | N_ISub_tez_legacy | N_IEdiv_tez -> - model_0 instr_or_cont (const1_model name) - | N_IMul_teznat | N_IMul_nattez -> - model_1 instr_or_cont (affine_model name) - | N_IEdiv_teznat -> model_2 instr_or_cont (division_cost name) - | N_IIs_nat -> model_0 instr_or_cont (const1_model name) - | N_INeg -> model_1 instr_or_cont (affine_model name) - | N_IAbs_int -> model_1 instr_or_cont (affine_model name) - | N_IInt_nat -> model_0 instr_or_cont (const1_model name) - | N_IAdd_int -> model_2 instr_or_cont (linear_max_model name) - | N_IAdd_nat -> model_2 instr_or_cont (linear_max_model name) - | N_ISub_int -> model_2 instr_or_cont (linear_max_model name) - | N_IMul_int -> model_2 instr_or_cont (addlogadd name) - | N_IMul_nat -> model_2 instr_or_cont (addlogadd name) - | N_IEdiv_int -> model_2 instr_or_cont (division_cost name) - | N_IEdiv_nat -> model_2 instr_or_cont (division_cost name) - | N_ILsl_nat -> model_1 instr_or_cont (affine_model name) - | N_ILsr_nat -> model_1 instr_or_cont (affine_model name) - | N_IOr_nat -> model_2 instr_or_cont (linear_max_model name) - | N_IAnd_nat -> model_2 instr_or_cont (linear_min_model name) - | N_IAnd_int_nat -> model_2 instr_or_cont (linear_min_model name) - | N_IXor_nat -> model_2 instr_or_cont (linear_max_model name) - | N_INot_int -> model_1 instr_or_cont (affine_model name) - | N_ICompare -> model_2 instr_or_cont (linear_min_model name) - | N_IEq | N_INeq | N_ILt | N_IGt | N_ILe | N_IGe -> - model_0 instr_or_cont (const1_model name) - | N_IPack -> model_3 instr_or_cont (pack_model name) - | N_IBlake2b | N_ISha256 | N_ISha512 | N_IKeccak | N_ISha3 -> - model_1 instr_or_cont (affine_model name) - | N_ICheck_signature_ed25519 | N_ICheck_signature_secp256k1 - | N_ICheck_signature_p256 -> - model_1 instr_or_cont (affine_model name) - | N_IContract | N_ITransfer_tokens | N_IImplicit_account -> - model_0 instr_or_cont (const1_model name) - (* The following two instructions are expected to have an affine model. However, - we observe 3 affine parts, on [0;300], [300;400] and [400;\inf[. *) - | N_IDupN -> model_1 instr_or_cont (break_model_2 name 300 400) - | N_IDropN -> model_1 instr_or_cont (break_model_2_const name 300 400) - | N_IDig | N_IDug | N_IDipN -> model_1 instr_or_cont (affine_model name) - | N_IAdd_bls12_381_g1 | N_IAdd_bls12_381_g2 | N_IAdd_bls12_381_fr - | N_IMul_bls12_381_g1 | N_IMul_bls12_381_g2 | N_IMul_bls12_381_fr - | N_INeg_bls12_381_g1 | N_INeg_bls12_381_g2 | N_INeg_bls12_381_fr - | N_IInt_bls12_381_z_fr -> - model_0 instr_or_cont (const1_model name) - | N_IMul_bls12_381_fr_z | N_IMul_bls12_381_z_fr - | N_IPairing_check_bls12_381 -> - model_1 instr_or_cont (affine_model name) - | N_IComb_get | N_IComb | N_IComb_set | N_IUncomb -> - model_1 instr_or_cont (affine_model name) - | N_ITicket | N_IRead_ticket -> model_0 instr_or_cont (const1_model name) - | N_ISplit_ticket -> model_2 instr_or_cont (split_ticket_model name) - | N_IJoin_tickets -> model_4 instr_or_cont (join_tickets_model name) - | N_ISapling_verify_update -> - model_2 instr_or_cont (verify_update_model name) - | N_IList_map -> model_0 instr_or_cont (const1_model name) - | N_IList_iter -> model_0 instr_or_cont (const1_model name) - | N_IIter -> model_0 instr_or_cont (const1_model name) - | N_IMap_map -> model_1 instr_or_cont (affine_model name) - | N_IMap_iter -> model_1 instr_or_cont (affine_model name) - | N_ISet_iter -> model_1 instr_or_cont (affine_model name) - | N_IHalt -> model_0 instr_or_cont (const1_model name) - | N_IApply -> model_0 instr_or_cont (const1_model name) - | N_ILog -> model_0 instr_or_cont (const1_model name) - | N_IOpen_chest -> model_2 instr_or_cont (open_chest_model name)) - | Cont_name cont -> ( - match cont with - | N_KNil -> model_0 instr_or_cont (const1_model name) - | N_KCons -> model_0 instr_or_cont (const1_model name) - | N_KReturn -> model_0 instr_or_cont (const1_model name) - | N_KView_exit -> model_0 instr_or_cont (const1_model name) - | N_KMap_head -> model_0 instr_or_cont (const1_model name) - | N_KUndip -> model_0 instr_or_cont (const1_model name) - | N_KLoop_in -> model_0 instr_or_cont (const1_model name) - | N_KLoop_in_left -> model_0 instr_or_cont (const1_model name) - | N_KIter -> model_1 instr_or_cont (branching_model name) - | N_KList_enter_body -> model_2 instr_or_cont (list_enter_body_model name) - | N_KList_exit_body -> model_0 instr_or_cont (const1_model name) - | N_KMap_enter_body -> model_1 instr_or_cont (branching_model name) - | N_KMap_exit_body -> model_2 instr_or_cont (nlogm_model name) - | N_KLog -> model_0 instr_or_cont (const1_model name)) - -let amplification_loop_iteration = fv "amplification_loop_iteration" - -let amplification_loop_model = - Model.make - ~conv:(fun iterations -> (iterations, ())) - ~model:(Model.linear ~coeff:amplification_loop_iteration) - -(* The following model stitches together the per-instruction models and - adds a term corresponding to the latency induced by the timer itself. *) -let interpreter_model ?amplification ?specialization () = - Model.make_preapplied ~model:(fun trace -> - let module Def (X : Costlang.S) = struct - let applied = - let (module Timer_applied) = - Model.apply Tezos_benchmark.Builtin_benchmarks.timer_model () - in - let module Timer_result = Timer_applied (X) in - let initial = - match amplification with - | None -> Timer_result.applied - | Some amplification_factor -> - let (module Amplification_applied) = - Model.apply amplification_loop_model amplification_factor - in - let module Amplification_result = Amplification_applied (X) in - X.(Timer_result.applied + Amplification_result.applied) - in - List.fold_left - (fun (acc : X.size X.repr) instr_trace -> - let (module Applied_instr) = - Model.apply - (ir_model - ?specialization - instr_trace.Interpreter_workload.name) - instr_trace - in - let module R = Applied_instr (X) in - X.(acc + R.applied)) - initial - trace - end in - ((module Def) : Model.applied)) - -let make_model ?amplification ?specialization instr_name_opt = - match instr_name_opt with - | None -> - [("interpreter", interpreter_model ?amplification ?specialization ())] - | Some name -> - (* When generating code, we don't want to consider the terms specific to - Lwt and to the timer latency. Also, we restrict to single instructions. *) - let ir_model = ir_model ?specialization name in - let name = name_of_instr_or_cont ?specialization name in - Registration_helpers.register_for_codegen - name - (Model.For_codegen ir_model) ; - let ir_model = - Model.precompose - (function [sized_step] -> sized_step | _ -> assert false) - ir_model - in - [ - ("interpreter", interpreter_model ?amplification ?specialization ()); - ("codegen", ir_model); - ] diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_workload.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_workload.ml deleted file mode 100644 index 7f48a5271d5b..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/interpreter_workload.ml +++ /dev/null @@ -1,1562 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(* ------------------------------------------------------------------------- *) - -type id = string - -let pp_id = Format.pp_print_string - -let equal_id = String.equal - -(* ------------------------------------------------------------------------- *) -(* Names of IR instructions together with sizes of their operands as - encountered during evaluation. *) - -type instruction_name = - (* stack ops *) - | N_IDrop - | N_IDup - | N_ISwap - | N_IConst - (* pairs *) - | N_ICons_pair - | N_ICar - | N_ICdr - | N_IUnpair - (* options *) - | N_ICons_some - | N_ICons_none - | N_IIf_none - | N_IOpt_map - (* unions *) - | N_ILeft - | N_IRight - | N_IIf_left - (* lists *) - | N_ICons_list - | N_INil - | N_IIf_cons - | N_IList_map - | N_IList_iter - | N_IIter - | N_IList_size - (* sets *) - | N_IEmpty_set - | N_ISet_iter - | N_ISet_mem - | N_ISet_update - | N_ISet_size - (* maps *) - | N_IEmpty_map - | N_IMap_map - | N_IMap_iter - | N_IMap_mem - | N_IMap_get - | N_IMap_update - | N_IMap_get_and_update - | N_IMap_size - (* big maps *) - | N_IEmpty_big_map - | N_IBig_map_mem - | N_IBig_map_get - | N_IBig_map_update - | N_IBig_map_get_and_update - (* string operations *) - | N_IConcat_string - | N_IConcat_string_pair - | N_ISlice_string - | N_IString_size - (* bytes operations *) - | N_IConcat_bytes - | N_IConcat_bytes_pair - | N_ISlice_bytes - | N_IBytes_size - (* timestamp operations *) - | N_IAdd_seconds_to_timestamp - | N_IAdd_timestamp_to_seconds - | N_ISub_timestamp_seconds - | N_IDiff_timestamps - (* currency operations *) - | N_IAdd_tez - | N_ISub_tez - | N_ISub_tez_legacy - | N_IMul_teznat - | N_IMul_nattez - | N_IEdiv_teznat - | N_IEdiv_tez - (* boolean operations - assumed O(1) *) - | N_IOr - | N_IAnd - | N_IXor - | N_INot - (* integer operations *) - | N_IIs_nat - | N_INeg - | N_IAbs_int - | N_IInt_nat - | N_IAdd_int - | N_IAdd_nat - | N_ISub_int - | N_IMul_int - | N_IMul_nat - | N_IEdiv_int - | N_IEdiv_nat - | N_ILsl_nat - | N_ILsr_nat - | N_IOr_nat - | N_IAnd_nat - | N_IAnd_int_nat - | N_IXor_nat - | N_INot_int - (* control *) - | N_IIf - | N_ILoop - | N_ILoop_left - | N_IDip - | N_IExec - | N_IApply - | N_ILambda - | N_IFailwith - (* comparison, warning: ad-hoc polymorphic instruction *) - | N_ICompare - (* comparators *) - | N_IEq - | N_INeq - | N_ILt - | N_IGt - | N_ILe - | N_IGe - (* protocol *) - | N_IAddress - | N_IContract - | N_ITransfer_tokens - | N_IImplicit_account - | N_ICreate_contract - | N_ISet_delegate - | N_INow - | N_IBalance - | N_ILevel - | N_IView - (* We specialize the check-signature instruction for each crypto scheme. *) - | N_ICheck_signature_ed25519 - | N_ICheck_signature_secp256k1 - | N_ICheck_signature_p256 - | N_IHash_key - | N_IPack - | N_IUnpack - | N_IBlake2b - | N_ISha256 - | N_ISha512 - | N_ISource - | N_ISender - | N_ISelf - | N_ISelf_address - | N_IAmount - | N_ISapling_empty_state - | N_ISapling_verify_update - | N_IDig - | N_IDug - | N_IDipN - | N_IDropN - | N_IChainId - | N_INever - | N_IVoting_power - | N_ITotal_voting_power - | N_IKeccak - | N_ISha3 - (* Elliptic curves *) - | N_IAdd_bls12_381_g1 - | N_IAdd_bls12_381_g2 - | N_IAdd_bls12_381_fr - | N_IMul_bls12_381_g1 - | N_IMul_bls12_381_g2 - | N_IMul_bls12_381_fr - | N_INeg_bls12_381_g1 - | N_INeg_bls12_381_g2 - | N_INeg_bls12_381_fr - | N_IMul_bls12_381_fr_z - | N_IMul_bls12_381_z_fr - | N_IInt_bls12_381_z_fr - | N_IPairing_check_bls12_381 - (* Combs *) - | N_IComb - | N_IUncomb - | N_IComb_get - | N_IComb_set - | N_IDupN - (* Tickets *) - | N_ITicket - | N_IRead_ticket - | N_ISplit_ticket - | N_IJoin_tickets - (* Misc *) - | N_IHalt - | N_ILog - (* Timelock*) - | N_IOpen_chest - -type continuation_name = - | N_KNil - | N_KCons - | N_KReturn - | N_KView_exit - | N_KMap_head - | N_KUndip - | N_KLoop_in - | N_KLoop_in_left - | N_KIter - | N_KList_enter_body - | N_KList_exit_body - | N_KMap_enter_body - | N_KMap_exit_body - | N_KLog - -and instr_or_cont_name = - | Instr_name of instruction_name - | Cont_name of continuation_name - -(* ------------------------------------------------------------------------- *) -(* Code that ought to be auto-generated *) - -let string_of_instruction_name : instruction_name -> string = - fun ir -> - match ir with - | N_IDrop -> "N_IDrop" - | N_IDup -> "N_IDup" - | N_ISwap -> "N_ISwap" - | N_IConst -> "N_IConst" - | N_ICons_pair -> "N_ICons_pair" - | N_ICar -> "N_ICar" - | N_ICdr -> "N_ICdr" - | N_ICons_some -> "N_ICons_some" - | N_ICons_none -> "N_ICons_none" - | N_IIf_none -> "N_IIf_none" - | N_IOpt_map -> "N_IOpt_map" - | N_ILeft -> "N_ILeft" - | N_IRight -> "N_IRight" - | N_IIf_left -> "N_IIf_left" - | N_ICons_list -> "N_ICons_list" - | N_INil -> "N_INil" - | N_IIf_cons -> "N_IIf_cons" - | N_IList_map -> "N_IList_map" - | N_IList_iter -> "N_IList_iter" - | N_IIter -> "N_IIter" - | N_IList_size -> "N_IList_size" - | N_IEmpty_set -> "N_IEmpty_set" - | N_ISet_iter -> "N_ISet_iter" - | N_ISet_mem -> "N_ISet_mem" - | N_ISet_update -> "N_ISet_update" - | N_ISet_size -> "N_ISet_size" - | N_IEmpty_map -> "N_IEmpty_map" - | N_IMap_map -> "N_IMap_map" - | N_IMap_iter -> "N_IMap_iter" - | N_IMap_mem -> "N_IMap_mem" - | N_IMap_get -> "N_IMap_get" - | N_IMap_update -> "N_IMap_update" - | N_IMap_size -> "N_IMap_size" - | N_IEmpty_big_map -> "N_IEmpty_big_map" - | N_IBig_map_mem -> "N_IBig_map_mem" - | N_IBig_map_get -> "N_IBig_map_get" - | N_IBig_map_update -> "N_IBig_map_update" - | N_IConcat_string -> "N_IConcat_string" - | N_IConcat_string_pair -> "N_IConcat_string_pair" - | N_ISlice_string -> "N_ISlice_string" - | N_IString_size -> "N_IString_size" - | N_IConcat_bytes -> "N_IConcat_bytes" - | N_IConcat_bytes_pair -> "N_IConcat_bytes_pair" - | N_ISlice_bytes -> "N_ISlice_bytes" - | N_IBytes_size -> "N_IBytes_size" - | N_IAdd_seconds_to_timestamp -> "N_IAdd_seconds_to_timestamp" - | N_IAdd_timestamp_to_seconds -> "N_IAdd_timestamp_to_seconds" - | N_ISub_timestamp_seconds -> "N_ISub_timestamp_seconds" - | N_IDiff_timestamps -> "N_IDiff_timestamps" - | N_IAdd_tez -> "N_IAdd_tez" - | N_ISub_tez -> "N_ISub_tez" - | N_ISub_tez_legacy -> "N_ISub_tez_legacy" - | N_IMul_teznat -> "N_IMul_teznat" - | N_IMul_nattez -> "N_IMul_nattez" - | N_IEdiv_teznat -> "N_IEdiv_teznat" - | N_IEdiv_tez -> "N_IEdiv_tez" - | N_IOr -> "N_IOr" - | N_IAnd -> "N_IAnd" - | N_IXor -> "N_IXor" - | N_INot -> "N_INot" - | N_IIs_nat -> "N_IIs_nat" - | N_INeg -> "N_INeg" - | N_IAbs_int -> "N_IAbs_int" - | N_IInt_nat -> "N_IInt_nat" - | N_IAdd_int -> "N_IAdd_int" - | N_IAdd_nat -> "N_IAdd_nat" - | N_ISub_int -> "N_ISub_int" - | N_IMul_int -> "N_IMul_int" - | N_IMul_nat -> "N_IMul_nat" - | N_IEdiv_int -> "N_IEdiv_int" - | N_IEdiv_nat -> "N_IEdiv_nat" - | N_ILsl_nat -> "N_ILsl_nat" - | N_ILsr_nat -> "N_ILsr_nat" - | N_IOr_nat -> "N_IOr_nat" - | N_IAnd_nat -> "N_IAnd_nat" - | N_IAnd_int_nat -> "N_IAnd_int_nat" - | N_IXor_nat -> "N_IXor_nat" - | N_INot_int -> "N_INot_int" - | N_IIf -> "N_IIf" - | N_ILoop -> "N_ILoop" - | N_ILoop_left -> "N_ILoop_left" - | N_IDip -> "N_IDip" - | N_IExec -> "N_IExec" - | N_IApply -> "N_IApply" - | N_ILambda -> "N_ILambda" - | N_IFailwith -> "N_IFailwith" - | N_ICompare -> "N_ICompare" - | N_IEq -> "N_IEq" - | N_INeq -> "N_INeq" - | N_ILt -> "N_ILt" - | N_IGt -> "N_IGt" - | N_ILe -> "N_ILe" - | N_IGe -> "N_IGe" - | N_IAddress -> "N_IAddress" - | N_IContract -> "N_IContract" - | N_ITransfer_tokens -> "N_ITransfer_tokens" - | N_IImplicit_account -> "N_IImplicit_account" - | N_ICreate_contract -> "N_ICreate_contract" - | N_ISet_delegate -> "N_ISet_delegate" - | N_INow -> "N_INow" - | N_IBalance -> "N_IBalance" - | N_ICheck_signature_ed25519 -> "N_ICheck_signature_ed25519" - | N_ICheck_signature_secp256k1 -> "N_ICheck_signature_secp256k1" - | N_ICheck_signature_p256 -> "N_ICheck_signature_p256" - | N_IHash_key -> "N_IHash_key" - | N_IPack -> "N_IPack" - | N_IUnpack -> "N_IUnpack" - | N_IBlake2b -> "N_IBlake2b" - | N_ISha256 -> "N_ISha256" - | N_ISha512 -> "N_ISha512" - | N_ISource -> "N_ISource" - | N_ISender -> "N_ISender" - | N_ISelf -> "N_ISelf" - | N_IAmount -> "N_IAmount" - | N_IDig -> "N_IDig" - | N_IDug -> "N_IDug" - | N_IDipN -> "N_IDipN" - | N_IDropN -> "N_IDropN" - | N_IDupN -> "N_IDupN" - | N_IChainId -> "N_IChainId" - | N_ILevel -> "N_ILevel" - | N_IView -> "N_IView" - | N_ISelf_address -> "N_ISelf_address" - | N_INever -> "N_INever" - | N_IUnpair -> "N_IUnpair" - | N_IVoting_power -> "N_IVoting_power" - | N_ITotal_voting_power -> "N_ITotal_voting_power" - | N_IKeccak -> "N_IKeccak" - | N_ISha3 -> "N_ISha3" - | N_IAdd_bls12_381_g1 -> "N_IAdd_bls12_381_g1" - | N_IAdd_bls12_381_g2 -> "N_IAdd_bls12_381_g2" - | N_IAdd_bls12_381_fr -> "N_IAdd_bls12_381_fr" - | N_IMul_bls12_381_g1 -> "N_IMul_bls12_381_g1" - | N_IMul_bls12_381_g2 -> "N_IMul_bls12_381_g2" - | N_IMul_bls12_381_fr -> "N_IMul_bls12_381_fr" - | N_INeg_bls12_381_g1 -> "N_INeg_bls12_381_g1" - | N_INeg_bls12_381_g2 -> "N_INeg_bls12_381_g2" - | N_INeg_bls12_381_fr -> "N_INeg_bls12_381_fr" - | N_IPairing_check_bls12_381 -> "N_IPairing_check_bls12_381" - | N_IMul_bls12_381_fr_z -> "N_IMul_bls12_381_fr_z" - | N_IMul_bls12_381_z_fr -> "N_IMul_bls12_381_z_fr" - | N_IInt_bls12_381_z_fr -> "N_IInt_bls12_381_z_fr" - | N_IComb -> "N_IComb" - | N_IUncomb -> "N_IUncomb" - | N_IComb_get -> "N_IComb_get" - | N_IComb_set -> "N_IComb_set" - | N_ITicket -> "N_ITicket" - | N_IRead_ticket -> "N_IRead_ticket" - | N_ISplit_ticket -> "N_ISplit_ticket" - | N_IJoin_tickets -> "N_IJoin_tickets" - | N_ISapling_empty_state -> "N_ISapling_empty_state" - | N_ISapling_verify_update -> "N_ISapling_verify_update" - | N_IMap_get_and_update -> "N_IMap_get_and_update" - | N_IBig_map_get_and_update -> "N_IBig_map_get_and_update" - | N_IHalt -> "N_IHalt" - | N_ILog -> "N_ILog" - | N_IOpen_chest -> "N_IOpen_chest" - -let string_of_continuation_name : continuation_name -> string = - fun c -> - match c with - | N_KNil -> "N_KNil" - | N_KCons -> "N_KCons" - | N_KReturn -> "N_KReturn" - | N_KView_exit -> "N_KView_exit" - | N_KMap_head -> "N_KMap_head" - | N_KUndip -> "N_KUndip" - | N_KLoop_in -> "N_KLoop_in" - | N_KLoop_in_left -> "N_KLoop_in_left" - | N_KIter -> "N_KIter" - | N_KList_enter_body -> "N_KList_enter_body" - | N_KList_exit_body -> "N_KList_exit_body" - | N_KMap_enter_body -> "N_KMap_enter_body" - | N_KMap_exit_body -> "N_KMap_exit_body" - | N_KLog -> "N_KLog" - -let string_of_instr_or_cont name = - match name with - | Instr_name instr_name -> string_of_instruction_name instr_name - | Cont_name cont_name -> string_of_continuation_name cont_name - -(* ------------------------------------------------------------------------- *) - -type args = arg list - -and arg = {name : id; arg : Size.t} - -let nullary : args = [] - -let unary xn x : args = [{name = xn; arg = x}] - -let binary xn x yn y : args = {name = xn; arg = x} :: unary yn y - -let ternary xn x yn y zn z : args = {name = xn; arg = x} :: binary yn y zn z - -let quaternary wn w xn x yn y zn z : args = - {name = wn; arg = w} :: ternary xn x yn y zn z - -let pp_arg fmtr {name; arg} = Format.fprintf fmtr "%s = %a" name Size.pp arg - -let pp_args fmtr args = - Format.pp_print_list - ~pp_sep:(fun fmtr () -> Format.fprintf fmtr ";") - pp_arg - fmtr - args - -type ir_sized_step = {name : instr_or_cont_name; args : args} - -type t = ir_sized_step list - -let ir_sized_step instr_name args = {name = Instr_name instr_name; args} - -let cont_sized_step cont_name args = {name = Cont_name cont_name; args} - -(* ------------------------------------------------------------------------- *) - -let all_instructions = - [ - N_IDrop; - N_IDup; - N_ISwap; - N_IConst; - N_ICons_pair; - N_ICar; - N_ICdr; - N_ICons_some; - N_ICons_none; - N_IIf_none; - N_IOpt_map; - N_ILeft; - N_IRight; - N_IIf_left; - N_ICons_list; - N_INil; - N_IIf_cons; - N_IList_map; - N_IList_iter; - N_IIter; - N_IList_size; - N_IEmpty_set; - N_ISet_iter; - N_ISet_mem; - N_ISet_update; - N_ISet_size; - N_IEmpty_map; - N_IMap_map; - N_IMap_iter; - N_IMap_mem; - N_IMap_get; - N_IMap_update; - N_IMap_size; - N_IEmpty_big_map; - N_IBig_map_mem; - N_IBig_map_get; - N_IBig_map_update; - N_IConcat_string; - N_IConcat_string_pair; - N_ISlice_string; - N_IString_size; - N_IConcat_bytes; - N_IConcat_bytes_pair; - N_ISlice_bytes; - N_IBytes_size; - N_IAdd_seconds_to_timestamp; - N_IAdd_timestamp_to_seconds; - N_ISub_timestamp_seconds; - N_IDiff_timestamps; - N_IAdd_tez; - N_ISub_tez; - N_ISub_tez_legacy; - N_IMul_teznat; - N_IMul_nattez; - N_IEdiv_teznat; - N_IEdiv_tez; - N_IOr; - N_IAnd; - N_IXor; - N_INot; - N_IIs_nat; - N_INeg; - N_IAbs_int; - N_IInt_nat; - N_IAdd_int; - N_IAdd_nat; - N_ISub_int; - N_IMul_int; - N_IMul_nat; - N_IEdiv_int; - N_IEdiv_nat; - N_ILsl_nat; - N_ILsr_nat; - N_IOr_nat; - N_IAnd_nat; - N_IAnd_int_nat; - N_IXor_nat; - N_INot_int; - N_IIf; - N_ILoop; - N_ILoop_left; - N_IDip; - N_IExec; - N_IApply; - N_ILambda; - N_IFailwith; - N_ICompare; - N_IEq; - N_INeq; - N_ILt; - N_IGt; - N_ILe; - N_IGe; - N_IAddress; - N_IContract; - N_ITransfer_tokens; - N_IImplicit_account; - N_ICreate_contract; - N_ISet_delegate; - N_INow; - N_IBalance; - N_ICheck_signature_ed25519; - N_ICheck_signature_secp256k1; - N_ICheck_signature_p256; - N_IHash_key; - N_IPack; - N_IUnpack; - N_IBlake2b; - N_ISha256; - N_ISha512; - N_ISource; - N_ISender; - N_ISelf; - N_IAmount; - N_IDig; - N_IDug; - N_IDipN; - N_IDropN; - N_IDupN; - N_IChainId; - N_ILevel; - N_IView; - N_ISelf_address; - N_INever; - N_IUnpair; - N_IVoting_power; - N_ITotal_voting_power; - N_IKeccak; - N_ISha3; - N_IAdd_bls12_381_g1; - N_IAdd_bls12_381_g2; - N_IAdd_bls12_381_fr; - N_IMul_bls12_381_g1; - N_IMul_bls12_381_g2; - N_IMul_bls12_381_fr; - N_INeg_bls12_381_g1; - N_INeg_bls12_381_g2; - N_INeg_bls12_381_fr; - N_IPairing_check_bls12_381; - N_IMul_bls12_381_fr_z; - N_IMul_bls12_381_z_fr; - N_IInt_bls12_381_z_fr; - N_IComb; - N_IUncomb; - N_IComb_get; - N_IComb_set; - N_ITicket; - N_IRead_ticket; - N_ISplit_ticket; - N_IJoin_tickets; - N_ISapling_empty_state; - N_ISapling_verify_update; - N_IMap_get_and_update; - N_IBig_map_get_and_update; - N_IHalt; - N_ILog; - N_IOpen_chest; - ] - -let all_continuations = - [ - N_KNil; - N_KCons; - N_KReturn; - N_KView_exit; - N_KMap_head; - N_KUndip; - N_KLoop_in; - N_KLoop_in_left; - N_KIter; - N_KList_enter_body; - N_KList_exit_body; - N_KMap_enter_body; - N_KMap_exit_body; - N_KLog; - ] - -let instruction_name_encoding = - let open Data_encoding in - def "instruction_name_encoding" - @@ string_enum - (List.map - (fun instr_name -> - (string_of_instruction_name instr_name, instr_name)) - all_instructions) - -let continuation_name_encoding = - let open Data_encoding in - def "continuation_name_encoding" - @@ string_enum - (List.map - (fun cont_name -> (string_of_continuation_name cont_name, cont_name)) - all_continuations) - -let args_encoding = - let open Data_encoding in - def "args_encoding" - @@ list - (conv - (fun {name; arg} -> (name, arg)) - (fun (name, arg) -> {name; arg}) - (tup2 string Size.encoding)) - -let instr_or_cont_name_encoding = - let open Data_encoding in - def "instr_or_cont_name" - @@ union - [ - case - ~title:"instr_name" - (Tag 0) - instruction_name_encoding - (function Instr_name name -> Some name | _ -> None) - (fun name -> Instr_name name); - case - ~title:"cont_name" - (Tag 1) - continuation_name_encoding - (function Cont_name name -> Some name | _ -> None) - (fun name -> Cont_name name); - ] - -let ir_sized_step_encoding = - let open Data_encoding in - def "ir_sized_step_encoding" - @@ conv - (fun {name; args} -> (name, args)) - (fun (name, args) -> {name; args}) - (tup2 instr_or_cont_name_encoding args_encoding) - -let encoding = - let open Data_encoding in - def "interpreter_trace_encoding" @@ list ir_sized_step_encoding - -(* ------------------------------------------------------------------------- *) - -module Instructions = struct - let drop = ir_sized_step N_IDrop nullary - - let dup = ir_sized_step N_IDup nullary - - let swap = ir_sized_step N_ISwap nullary - - let const = ir_sized_step N_IConst nullary - - let cons_pair = ir_sized_step N_ICons_pair nullary - - let car = ir_sized_step N_ICar nullary - - let cdr = ir_sized_step N_ICdr nullary - - let cons_some = ir_sized_step N_ICons_some nullary - - let cons_none = ir_sized_step N_ICons_none nullary - - let if_none = ir_sized_step N_IIf_none nullary - - let opt_map = ir_sized_step N_IOpt_map nullary - - let left = ir_sized_step N_ILeft nullary - - let right = ir_sized_step N_IRight nullary - - let if_left = ir_sized_step N_IIf_left nullary - - let cons_list = ir_sized_step N_ICons_list nullary - - let nil = ir_sized_step N_INil nullary - - let if_cons = ir_sized_step N_IIf_cons nullary - - let list_map = ir_sized_step N_IList_map nullary - - let list_iter = ir_sized_step N_IList_iter nullary - - let iter = ir_sized_step N_IIter nullary - - let list_size _list = ir_sized_step N_IList_size nullary - - let empty_set = ir_sized_step N_IEmpty_set nullary - - let set_iter set = ir_sized_step N_ISet_iter (unary "set" set) - - let set_mem elt set = ir_sized_step N_ISet_mem (binary "elt" elt "set" set) - - let set_update elt set = - ir_sized_step N_ISet_update (binary "elt" elt "set" set) - - let set_size _set = ir_sized_step N_ISet_size nullary - - let empty_map = ir_sized_step N_IEmpty_map nullary - - let map_map map = ir_sized_step N_IMap_map (unary "map" map) - - let map_iter map = ir_sized_step N_IMap_iter (unary "map" map) - - let map_mem key map = ir_sized_step N_IMap_mem (binary "key" key "map" map) - - let map_get key map = ir_sized_step N_IMap_get (binary "key" key "map" map) - - let map_update key map = - ir_sized_step N_IMap_update (binary "key" key "map" map) - - let map_size _map = ir_sized_step N_IMap_size nullary - - let empty_big_map = ir_sized_step N_IEmpty_big_map nullary - - let big_map_mem key big_map = - ir_sized_step N_IBig_map_mem (binary "key" key "big_map" big_map) - - let big_map_get key big_map = - ir_sized_step N_IBig_map_get (binary "key" key "big_map" big_map) - - let big_map_update key big_map = - ir_sized_step N_IBig_map_update (binary "key" key "big_map" big_map) - - let big_map_get_and_update key big_map = - ir_sized_step N_IBig_map_get_and_update (binary "key" key "big_map" big_map) - - let concat_string total_bytes list = - ir_sized_step - N_IConcat_string - (binary "total_bytes" total_bytes "list" list) - - let concat_string_pair str1 str2 = - ir_sized_step N_IConcat_string_pair (binary "str1" str1 "str2" str2) - - let slice_string string = - ir_sized_step N_ISlice_string (unary "string" string) - - let string_size _string = ir_sized_step N_IString_size nullary - - let concat_bytes total_bytes list = - ir_sized_step N_IConcat_bytes (binary "total_bytes" total_bytes "list" list) - - let concat_bytes_pair str1 str2 = - ir_sized_step N_IConcat_bytes_pair (binary "str1" str1 "str2" str2) - - let slice_bytes bytes = ir_sized_step N_ISlice_bytes (unary "bytes" bytes) - - let bytes_size = ir_sized_step N_IBytes_size nullary - - let add_seconds_to_timestamp seconds tstamp = - ir_sized_step - N_IAdd_seconds_to_timestamp - (binary "seconds" seconds "tstamp" tstamp) - - let add_timestamp_to_seconds tstamp seconds = - ir_sized_step - N_IAdd_timestamp_to_seconds - (binary "tstamp" tstamp "seconds" seconds) - - let sub_timestamp_seconds tstamp seconds = - ir_sized_step - N_ISub_timestamp_seconds - (binary "tstamp" tstamp "seconds" seconds) - - let diff_timestamps tstamp1 tstamp2 = - ir_sized_step - N_IDiff_timestamps - (binary "tstamp1" tstamp1 "tstamp2" tstamp2) - - let add_tez _tez1 _tez2 = ir_sized_step N_IAdd_tez nullary - - let sub_tez _tez1 _tez2 = ir_sized_step N_ISub_tez nullary - - let sub_tez_legacy _tez1 _tez2 = ir_sized_step N_ISub_tez_legacy nullary - - let mul_teznat _tez nat = ir_sized_step N_IMul_teznat (unary "nat" nat) - - let mul_nattez nat _tez = ir_sized_step N_IMul_nattez (unary "nat" nat) - - let ediv_teznat tez nat = - ir_sized_step N_IEdiv_teznat (binary "tez" tez "nat" nat) - - let ediv_tez _tez1 _tez2 = ir_sized_step N_IEdiv_tez nullary - - let or_ = ir_sized_step N_IOr nullary - - let and_ = ir_sized_step N_IAnd nullary - - let xor_ = ir_sized_step N_IXor nullary - - let not_ = ir_sized_step N_INot nullary - - let is_nat _int = ir_sized_step N_IIs_nat nullary - - let neg int = ir_sized_step N_INeg (unary "int" int) - - let abs_int int = ir_sized_step N_IAbs_int (unary "int" int) - - let int_nat _nat = ir_sized_step N_IInt_nat nullary - - let add_int int1 int2 = - ir_sized_step N_IAdd_int (binary "int1" int1 "int2" int2) - - let add_nat nat1 nat2 = - ir_sized_step N_IAdd_nat (binary "nat1" nat1 "nat2" nat2) - - let sub_int int1 int2 = - ir_sized_step N_ISub_int (binary "int1" int1 "int2" int2) - - let mul_int int1 int2 = - ir_sized_step N_IMul_int (binary "int1" int1 "int2" int2) - - let mul_nat nat int = ir_sized_step N_IMul_nat (binary "nat" nat "int" int) - - let ediv_int int1 int2 = - ir_sized_step N_IEdiv_int (binary "int1" int1 "int2" int2) - - let ediv_nat nat int = ir_sized_step N_IEdiv_nat (binary "nat" nat "int" int) - - let lsl_nat nat1 _shift = ir_sized_step N_ILsl_nat (unary "nat" nat1) - - let lsr_nat nat1 _shift = ir_sized_step N_ILsr_nat (unary "nat" nat1) - - let or_nat nat1 nat2 = - ir_sized_step N_IOr_nat (binary "nat1" nat1 "nat2" nat2) - - let and_nat nat1 nat2 = - ir_sized_step N_IAnd_nat (binary "nat1" nat1 "nat2" nat2) - - let and_int_nat int nat = - ir_sized_step N_IAnd_int_nat (binary "int" int "nat" nat) - - let xor_nat nat1 nat2 = - ir_sized_step N_IXor_nat (binary "nat1" nat1 "nat2" nat2) - - let not_int int = ir_sized_step N_INot_int (unary "int" int) - - let if_ = ir_sized_step N_IIf nullary - - let loop = ir_sized_step N_ILoop nullary - - let loop_left = ir_sized_step N_ILoop_left nullary - - let dip = ir_sized_step N_IDip nullary - - let exec = ir_sized_step N_IExec nullary - - let apply = ir_sized_step N_IApply nullary - - let lambda = ir_sized_step N_ILambda nullary - - let failwith_ = ir_sized_step N_IFailwith nullary - - let compare arg1 arg2 = - ir_sized_step N_ICompare (binary "arg1" arg1 "arg2" arg2) - - let eq = ir_sized_step N_IEq nullary - - let neq = ir_sized_step N_INeq nullary - - let lt = ir_sized_step N_ILt nullary - - let gt = ir_sized_step N_IGt nullary - - let le = ir_sized_step N_ILe nullary - - let ge = ir_sized_step N_IGe nullary - - let address = ir_sized_step N_IAddress nullary - - let contract = ir_sized_step N_IContract nullary - - let transfer_tokens = ir_sized_step N_ITransfer_tokens nullary - - let implicit_account = ir_sized_step N_IImplicit_account nullary - - let create_contract = ir_sized_step N_ICreate_contract nullary - - let set_delegate = ir_sized_step N_ISet_delegate nullary - - let now = ir_sized_step N_INow nullary - - let balance = ir_sized_step N_IBalance nullary - - let check_signature_ed25519 _pk _signature message = - ir_sized_step N_ICheck_signature_ed25519 (unary "message" message) - - let check_signature_secp256k1 _pk _signature message = - ir_sized_step N_ICheck_signature_secp256k1 (unary "message" message) - - let check_signature_p256 _pk _signature message = - ir_sized_step N_ICheck_signature_p256 (unary "message" message) - - let hash_key = ir_sized_step N_IHash_key nullary - - let pack (micheline_size : Size.micheline_size) = - ir_sized_step - N_IPack - (ternary - "micheline_nodes" - micheline_size.traversal - "micheline_int_bytes" - micheline_size.int_bytes - "micheline_string_bytes" - micheline_size.string_bytes) - - let unpack = ir_sized_step N_IUnpack nullary - - let blake2b bytes = ir_sized_step N_IBlake2b (unary "bytes" bytes) - - let sha256 bytes = ir_sized_step N_ISha256 (unary "bytes" bytes) - - let sha512 bytes = ir_sized_step N_ISha512 (unary "bytes" bytes) - - let source = ir_sized_step N_ISource nullary - - let sender = ir_sized_step N_ISender nullary - - let self = ir_sized_step N_ISelf nullary - - let amount = ir_sized_step N_IAmount nullary - - let dig depth = ir_sized_step N_IDig (unary "depth" depth) - - let dug depth = ir_sized_step N_IDug (unary "depth" depth) - - let dipn depth = ir_sized_step N_IDipN (unary "depth" depth) - - let dropn depth = ir_sized_step N_IDropN (unary "depth" depth) - - let dupn depth = ir_sized_step N_IDupN (unary "depth" depth) - - let chain_id = ir_sized_step N_IChainId nullary - - let level = ir_sized_step N_ILevel nullary - - let view = ir_sized_step N_IView nullary - - let self_address = ir_sized_step N_ISelf_address nullary - - let never = ir_sized_step N_INever nullary - - let unpair = ir_sized_step N_IUnpair nullary - - let voting_power = ir_sized_step N_IVoting_power nullary - - let total_voting_power = ir_sized_step N_ITotal_voting_power nullary - - let keccak bytes = ir_sized_step N_IKeccak (unary "bytes" bytes) - - let sha3 bytes = ir_sized_step N_ISha3 (unary "bytes" bytes) - - let add_bls12_381_g1 = ir_sized_step N_IAdd_bls12_381_g1 nullary - - let add_bls12_381_g2 = ir_sized_step N_IAdd_bls12_381_g2 nullary - - let add_bls12_381_fr = ir_sized_step N_IAdd_bls12_381_fr nullary - - let mul_bls12_381_g1 = ir_sized_step N_IMul_bls12_381_g1 nullary - - let mul_bls12_381_g2 = ir_sized_step N_IMul_bls12_381_g2 nullary - - let mul_bls12_381_fr = ir_sized_step N_IMul_bls12_381_fr nullary - - let neg_bls12_381_g1 = ir_sized_step N_INeg_bls12_381_g1 nullary - - let neg_bls12_381_g2 = ir_sized_step N_INeg_bls12_381_g2 nullary - - let neg_bls12_381_fr = ir_sized_step N_INeg_bls12_381_fr nullary - - let pairing_check_bls12_381 length = - ir_sized_step N_IPairing_check_bls12_381 (unary "length" length) - - let mul_bls12_381_fr_z nat = - ir_sized_step N_IMul_bls12_381_fr_z (unary "nat" nat) - - let mul_bls12_381_z_fr nat = - ir_sized_step N_IMul_bls12_381_z_fr (unary "nat" nat) - - let int_bls12_381_z_fr = ir_sized_step N_IInt_bls12_381_z_fr nullary - - let comb depth = ir_sized_step N_IComb (unary "depth" depth) - - let uncomb depth = ir_sized_step N_IUncomb (unary "depth" depth) - - let comb_get key = ir_sized_step N_IComb_get (unary "key" key) - - let comb_set key = ir_sized_step N_IComb_set (unary "key" key) - - let ticket = ir_sized_step N_ITicket nullary - - let read_ticket = ir_sized_step N_IRead_ticket nullary - - let split_ticket nat1 nat2 = - ir_sized_step N_ISplit_ticket (binary "nat1" nat1 "nat2" nat2) - - let join_tickets size1 size2 size3 size4 = - ir_sized_step - N_IJoin_tickets - (quaternary - "contents1" - size1 - "contents2" - size2 - "amount1" - size3 - "amount2" - size4) - - let sapling_empty_state = ir_sized_step N_ISapling_empty_state nullary - - let sapling_verify_update inputs outputs _state = - ir_sized_step - N_ISapling_verify_update - (binary "inputs" inputs "outputs" outputs) - - let map_get_and_update key_size map_size = - ir_sized_step - N_IMap_get_and_update - (binary "key_size" key_size "map_size" map_size) - - let halt = ir_sized_step N_IHalt nullary - - let log = ir_sized_step N_ILog nullary - - let open_chest log_time size = - ir_sized_step N_IOpen_chest (binary "log_time" log_time "size" size) -end - -module Control = struct - let nil = cont_sized_step N_KNil nullary - - let cons = cont_sized_step N_KCons nullary - - let return = cont_sized_step N_KReturn nullary - - let view_exit = cont_sized_step N_KView_exit nullary - - let map_head = cont_sized_step N_KMap_head nullary - - let undip = cont_sized_step N_KUndip nullary - - let loop_in = cont_sized_step N_KLoop_in nullary - - let loop_in_left = cont_sized_step N_KLoop_in_left nullary - - let iter size = cont_sized_step N_KIter (unary "size" size) - - let list_enter_body xs_size ys_size = - cont_sized_step - N_KList_enter_body - (binary "xs_size" xs_size "ys_size" ys_size) - - let list_exit_body = cont_sized_step N_KList_exit_body nullary - - let map_enter_body size = - cont_sized_step N_KMap_enter_body (unary "size" size) - - let map_exit_body key_size map_size = - cont_sized_step N_KMap_exit_body (binary "key" key_size "map" map_size) - - let log = cont_sized_step N_KLog nullary -end - -(* ------------------------------------------------------------------------- *) - -open Script_typed_ir - -let rec size_of_comparable_value : type a. a comparable_ty -> a -> Size.t = - fun (type a) (wit : a comparable_ty) (v : a) -> - match wit with - | Never_key _ -> Size.zero - | Unit_key _ -> Size.unit - | Int_key _ -> Size.integer v - | Nat_key _ -> Size.integer v - | String_key _ -> Size.script_string v - | Bytes_key _ -> Size.bytes v - | Mutez_key _ -> Size.mutez v - | Bool_key _ -> Size.bool v - | Key_hash_key _ -> Size.key_hash v - | Timestamp_key _ -> Size.timestamp v - | Address_key _ -> Size.address v - | Pair_key ((leaf, _), (node, _), _) -> - let (lv, rv) = v in - let size = - Size.add - (size_of_comparable_value leaf lv) - (size_of_comparable_value node rv) - in - Size.add size Size.one - | Union_key ((left, _), (right, _), _) -> - let size = - match v with - | L v -> size_of_comparable_value left v - | R v -> size_of_comparable_value right v - in - Size.add size Size.one - | Option_key (ty, _) -> ( - match v with - | None -> Size.one - | Some x -> Size.add (size_of_comparable_value ty x) Size.one) - | Signature_key _ -> Size.signature v - | Key_key _ -> Size.public_key v - | Chain_id_key _ -> Size.chain_id v - -let extract_compare_sized_step : - type a. a comparable_ty -> a -> a -> ir_sized_step = - fun comparable_ty x y -> - Instructions.compare - (size_of_comparable_value comparable_ty x) - (size_of_comparable_value comparable_ty y) - -let extract_ir_sized_step : - type bef_top bef res_top res. - Alpha_context.t -> - (bef_top, bef, res_top, res) Script_typed_ir.kinstr -> - bef_top * bef -> - ir_sized_step = - fun ctxt instr stack -> - let open Script_typed_ir in - match (instr, stack) with - | (IDrop (_, _), _) -> Instructions.drop - | (IDup (_, _), _) -> Instructions.dup - | (ISwap (_, _), _) -> Instructions.swap - | (IConst (_, _, _), _) -> Instructions.const - | (ICons_pair (_, _), _) -> Instructions.cons_pair - | (ICar (_, _), _) -> Instructions.car - | (ICdr (_, _), _) -> Instructions.cdr - | (IUnpair (_, _), _) -> Instructions.unpair - | (ICons_some (_, _), _) -> Instructions.cons_some - | (ICons_none (_, _), _) -> Instructions.cons_none - | (IIf_none _, _) -> Instructions.if_none - | (IOpt_map _, _) -> Instructions.opt_map - | (ICons_left (_, _), _) -> Instructions.left - | (ICons_right (_, _), _) -> Instructions.right - | (IIf_left _, _) -> Instructions.if_left - | (ICons_list (_, _), _) -> Instructions.cons_list - | (INil (_, _), _) -> Instructions.nil - | (IIf_cons _, _) -> Instructions.if_cons - | (IList_iter (_, _, _), _) -> Instructions.list_iter - | (IList_map (_, _, _), _) -> Instructions.list_map - | (IList_size (_, _), (list, _)) -> Instructions.list_size (Size.list list) - | (IEmpty_set (_, _, _), _) -> Instructions.empty_set - | (ISet_iter _, (set, _)) -> Instructions.set_iter (Size.set set) - | (ISet_mem (_, _), (v, (set, _))) -> - let (module S) = set in - let sz = size_of_comparable_value S.elt_ty v in - Instructions.set_mem sz (Size.set set) - | (ISet_update (_, _), (v, (_flag, (set, _)))) -> - let (module S) = set in - let sz = size_of_comparable_value S.elt_ty v in - Instructions.set_update sz (Size.set set) - | (ISet_size (_, _), (set, _)) -> Instructions.set_size (Size.set set) - | (IEmpty_map (_, _, _), _) -> Instructions.empty_map - | (IMap_map _, (map, _)) -> Instructions.map_map (Size.map map) - | (IMap_iter _, (map, _)) -> Instructions.map_iter (Size.map map) - | (IMap_mem (_, _), (v, (((module Map) as map), _))) -> - let key_size = size_of_comparable_value Map.key_ty v in - Instructions.map_mem key_size (Size.map map) - | (IMap_get (_, _), (v, (((module Map) as map), _))) -> - let key_size = size_of_comparable_value Map.key_ty v in - Instructions.map_get key_size (Size.map map) - | (IMap_update (_, _), (v, (_elt_opt, (((module Map) as map), _)))) -> - let key_size = size_of_comparable_value Map.key_ty v in - Instructions.map_update key_size (Size.map map) - | (IMap_get_and_update (_, _), (v, (_elt_opt, (((module Map) as map), _)))) -> - let key_size = size_of_comparable_value Map.key_ty v in - Instructions.map_get_and_update key_size (Size.map map) - | (IMap_size (_, _), (map, _)) -> Instructions.map_size (Size.map map) - | (IEmpty_big_map (_, _, _, _), _) -> Instructions.empty_big_map - | (IBig_map_mem (_, _), (v, ({diff = {size; _}; key_type; _}, _))) -> - let key_size = size_of_comparable_value key_type v in - Instructions.big_map_mem key_size size - | (IBig_map_get (_, _), (v, ({diff = {size; _}; key_type; _}, _))) -> - let key_size = size_of_comparable_value key_type v in - Instructions.big_map_get key_size size - | (IBig_map_update (_, _), (v, (_, ({diff = {size; _}; key_type; _}, _)))) -> - let key_size = size_of_comparable_value key_type v in - Instructions.big_map_update key_size size - | ( IBig_map_get_and_update (_, _), - (v, (_, ({diff = {size; _}; key_type; _}, _))) ) -> - let key_size = size_of_comparable_value key_type v in - Instructions.big_map_get_and_update key_size size - | (IConcat_string (_, _), (ss, _)) -> - let list_size = Size.list ss in - let total_bytes = - List.fold_left - (fun x s -> Size.(add x (script_string s))) - Size.zero - ss.elements - in - Instructions.concat_string list_size total_bytes - | (IConcat_string_pair (_, _), (s1, (s2, _))) -> - Instructions.concat_string_pair - (Size.script_string s1) - (Size.script_string s2) - | (ISlice_string (_, _), (_off, (_len, (s, _)))) -> - Instructions.slice_string (Size.script_string s) - | (IString_size (_, _), (s, _)) -> - Instructions.string_size (Size.script_string s) - | (IConcat_bytes (_, _), (ss, _)) -> - let list_size = Size.list ss in - let total_bytes = - List.fold_left (fun x s -> Size.(add x (bytes s))) Size.zero ss.elements - in - Instructions.concat_bytes list_size total_bytes - | (IConcat_bytes_pair (_, _), (s1, (s2, _))) -> - Instructions.concat_bytes_pair (Size.bytes s1) (Size.bytes s2) - | (ISlice_bytes (_, _), (_off, (_len, (s, _)))) -> - Instructions.slice_bytes (Size.bytes s) - | (IBytes_size (_, _), _) -> Instructions.bytes_size - | (IAdd_seconds_to_timestamp (_, _), (s, (t, _))) -> - Instructions.add_seconds_to_timestamp (Size.timestamp t) (Size.integer s) - | (IAdd_timestamp_to_seconds (_, _), (t, (s, _))) -> - Instructions.add_timestamp_to_seconds (Size.timestamp t) (Size.integer s) - | (ISub_timestamp_seconds (_, _), (t, (s, _))) -> - Instructions.sub_timestamp_seconds (Size.timestamp t) (Size.integer s) - | (IDiff_timestamps (_, _), (t1, (t2, _))) -> - Instructions.diff_timestamps (Size.timestamp t1) (Size.timestamp t2) - | (IAdd_tez (_, _), (x, (y, _))) -> - Instructions.add_tez (Size.mutez x) (Size.mutez y) - | (ISub_tez (_, _), (x, (y, _))) -> - Instructions.sub_tez (Size.mutez x) (Size.mutez y) - | (ISub_tez_legacy (_, _), (x, (y, _))) -> - Instructions.sub_tez_legacy (Size.mutez x) (Size.mutez y) - | (IMul_teznat (_, _), (x, (y, _))) -> - Instructions.mul_teznat (Size.mutez x) (Size.integer y) - | (IMul_nattez (_, _), (x, (y, _))) -> - Instructions.mul_nattez (Size.integer x) (Size.mutez y) - | (IEdiv_teznat (_, _), (x, (y, _))) -> - Instructions.ediv_teznat (Size.mutez x) (Size.integer y) - | (IEdiv_tez (_, _), (x, (y, _))) -> - Instructions.ediv_tez (Size.mutez x) (Size.mutez y) - | (IOr (_, _), _) -> Instructions.or_ - | (IAnd (_, _), _) -> Instructions.and_ - | (IXor (_, _), _) -> Instructions.xor_ - | (INot (_, _), _) -> Instructions.not_ - | (IIs_nat (_, _), (x, _)) -> Instructions.is_nat (Size.integer x) - | (INeg (_, _), (x, _)) -> Instructions.neg (Size.integer x) - | (IAbs_int (_, _), (x, _)) -> Instructions.abs_int (Size.integer x) - | (IInt_nat (_, _), (x, _)) -> Instructions.int_nat (Size.integer x) - | (IAdd_int (_, _), (x, (y, _))) -> - Instructions.add_int (Size.integer x) (Size.integer y) - | (IAdd_nat (_, _), (x, (y, _))) -> - Instructions.add_nat (Size.integer x) (Size.integer y) - | (ISub_int (_, _), (x, (y, _))) -> - Instructions.sub_int (Size.integer x) (Size.integer y) - | (IMul_int (_, _), (x, (y, _))) -> - Instructions.mul_int (Size.integer x) (Size.integer y) - | (IMul_nat (_, _), (x, (y, _))) -> - Instructions.mul_nat (Size.integer x) (Size.integer y) - | (IEdiv_int (_, _), (x, (y, _))) -> - Instructions.ediv_int (Size.integer x) (Size.integer y) - | (IEdiv_nat (_, _), (x, (y, _))) -> - Instructions.ediv_nat (Size.integer x) (Size.integer y) - | (ILsl_nat (_, _), (x, (y, _))) -> - Instructions.lsl_nat (Size.integer x) (Size.integer y) - | (ILsr_nat (_, _), (x, (y, _))) -> - Instructions.lsr_nat (Size.integer x) (Size.integer y) - | (IOr_nat (_, _), (x, (y, _))) -> - Instructions.or_nat (Size.integer x) (Size.integer y) - | (IAnd_nat (_, _), (x, (y, _))) -> - Instructions.and_nat (Size.integer x) (Size.integer y) - | (IAnd_int_nat (_, _), (x, (y, _))) -> - Instructions.and_int_nat (Size.integer x) (Size.integer y) - | (IXor_nat (_, _), (x, (y, _))) -> - Instructions.xor_nat (Size.integer x) (Size.integer y) - | (INot_int (_, _), (x, _)) -> Instructions.not_int (Size.integer x) - | (IIf _, _) -> Instructions.if_ - | (ILoop (_, _, _), _) -> Instructions.loop - | (ILoop_left (_, _, _), _) -> Instructions.loop_left - | (IDip (_, _, _), _) -> Instructions.dip - | (IExec (_, _), _) -> Instructions.exec - | (IApply (_, _, _), _) -> Instructions.apply - | (ILambda (_, _, _), _) -> Instructions.lambda - | (IFailwith (_, _, _), _) -> Instructions.failwith_ - | (ICompare (_, cmp_ty, _), (a, (b, _))) -> - extract_compare_sized_step cmp_ty a b - | (IEq (_, _), _) -> Instructions.eq - | (INeq (_, _), _) -> Instructions.neq - | (ILt (_, _), _) -> Instructions.lt - | (IGt (_, _), _) -> Instructions.gt - | (ILe (_, _), _) -> Instructions.le - | (IGe (_, _), _) -> Instructions.ge - | (IAddress (_, _), _) -> Instructions.address - | (IContract (_, _, _, _), _) -> Instructions.contract - | (ITransfer_tokens (_, _), _) -> Instructions.transfer_tokens - | (IView (_, _, _), _) -> Instructions.view - | (IImplicit_account (_, _), _) -> Instructions.implicit_account - | (ICreate_contract _, _) -> Instructions.create_contract - | (ISet_delegate (_, _), _) -> Instructions.set_delegate - | (INow (_, _), _) -> Instructions.now - | (IBalance (_, _), _) -> Instructions.balance - | (ILevel (_, _), _) -> Instructions.level - | (ICheck_signature (_, _), (public_key, (_signature, (message, _)))) -> ( - match public_key with - | Signature.Ed25519 _pk -> - let pk = Size.of_int Ed25519.size in - let signature = Size.of_int Signature.size in - let message = Size.bytes message in - Instructions.check_signature_ed25519 pk signature message - | Signature.Secp256k1 _pk -> - let pk = Size.of_int Secp256k1.size in - let signature = Size.of_int Signature.size in - let message = Size.bytes message in - Instructions.check_signature_secp256k1 pk signature message - | Signature.P256 _pk -> - let pk = Size.of_int P256.size in - let signature = Size.of_int Signature.size in - let message = Size.bytes message in - Instructions.check_signature_p256 pk signature message) - | (IHash_key (_, _), _) -> Instructions.hash_key - | (IPack (_, ty, _), (v, _)) -> - let encoding_size = Size.of_encoded_value ctxt ty v in - Instructions.pack encoding_size - | (IUnpack (_, _, _), _) -> Instructions.unpack - | (IBlake2b (_, _), (bytes, _)) -> Instructions.blake2b (Size.bytes bytes) - | (ISha256 (_, _), (bytes, _)) -> Instructions.sha256 (Size.bytes bytes) - | (ISha512 (_, _), (bytes, _)) -> Instructions.sha512 (Size.bytes bytes) - | (ISource (_, _), _) -> Instructions.source - | (ISender (_, _), _) -> Instructions.sender - | (ISelf (_, _, _, _), _) -> Instructions.self - | (ISelf_address (_, _), _) -> Instructions.self_address - | (IAmount (_, _), _) -> Instructions.amount - | (ISapling_empty_state (_, _, _), _) -> Instructions.sapling_empty_state - | (ISapling_verify_update (_, _), (transaction, (_state, _))) -> - let inputs = Size.sapling_transaction_inputs transaction in - let outputs = Size.sapling_transaction_outputs transaction in - let state = Size.zero in - Instructions.sapling_verify_update inputs outputs state - | (IDig (_, n, _, _), _) -> Instructions.dig n - | (IDug (_, n, _, _), _) -> Instructions.dug n - | (IDipn (_, n, _, _, _), _) -> Instructions.dipn n - | (IDropn (_, n, _, _), _) -> Instructions.dropn n - | (IChainId (_, _), _) -> Instructions.chain_id - | (INever _, _) -> . - | (IVoting_power (_, _), _) -> Instructions.voting_power - | (ITotal_voting_power (_, _), _) -> Instructions.total_voting_power - | (IKeccak (_, _), (bytes, _)) -> Instructions.keccak (Size.bytes bytes) - | (ISha3 (_, _), (bytes, _)) -> Instructions.sha3 (Size.bytes bytes) - | (IAdd_bls12_381_g1 (_, _), _) -> Instructions.add_bls12_381_g1 - | (IAdd_bls12_381_g2 (_, _), _) -> Instructions.add_bls12_381_g2 - | (IAdd_bls12_381_fr (_, _), _) -> Instructions.add_bls12_381_fr - | (IMul_bls12_381_g1 (_, _), _) -> Instructions.mul_bls12_381_g1 - | (IMul_bls12_381_g2 (_, _), _) -> Instructions.mul_bls12_381_g2 - | (IMul_bls12_381_fr (_, _), _) -> Instructions.mul_bls12_381_fr - | (IMul_bls12_381_z_fr (_, _), (_fr, (z, _))) -> - Instructions.mul_bls12_381_z_fr (Size.integer z) - | (IMul_bls12_381_fr_z (_, _), (z, _)) -> - Instructions.mul_bls12_381_fr_z (Size.integer z) - | (IInt_bls12_381_fr (_, _), _) -> Instructions.int_bls12_381_z_fr - | (INeg_bls12_381_g1 (_, _), _) -> Instructions.neg_bls12_381_g1 - | (INeg_bls12_381_g2 (_, _), _) -> Instructions.neg_bls12_381_g2 - | (INeg_bls12_381_fr (_, _), _) -> Instructions.neg_bls12_381_fr - | (IPairing_check_bls12_381 (_, _), (list, _)) -> - Instructions.pairing_check_bls12_381 (Size.list list) - | (IComb (_, n, _, _), _) -> Instructions.comb (Size.of_int n) - | (IUncomb (_, n, _, _), _) -> Instructions.uncomb (Size.of_int n) - | (IComb_get (_, n, _, _), _) -> Instructions.comb_get (Size.of_int n) - | (IComb_set (_, n, _, _), _) -> Instructions.comb_set (Size.of_int n) - | (IDup_n (_, n, _, _), _) -> Instructions.dupn (Size.of_int n) - | (ITicket (_, _), _) -> Instructions.ticket - | (IRead_ticket (_, _), _) -> Instructions.read_ticket - | (ISplit_ticket (_, _), (_ticket, ((amount_a, amount_b), _))) -> - Instructions.split_ticket (Size.integer amount_a) (Size.integer amount_b) - | (IJoin_tickets (_, cmp_ty, _), ((ticket1, ticket2), _)) -> - let size1 = size_of_comparable_value cmp_ty ticket1.contents in - let size2 = size_of_comparable_value cmp_ty ticket2.contents in - let tez1 = Size.integer ticket1.amount in - let tez2 = Size.integer ticket2.amount in - Instructions.join_tickets size1 size2 tez1 tez2 - | (IHalt _, _) -> Instructions.halt - | (ILog _, _) -> Instructions.log - | (IOpen_chest (_, _), (_, (chest, (time, _)))) -> - let plaintext_size = Timelock.get_plaintext_size chest - 1 in - let log_time = Z.log2 Z.(one + Script_int_repr.to_zint time) in - Instructions.open_chest log_time plaintext_size - -let extract_control_trace (type bef_top bef aft_top aft) - (cont : (bef_top, bef, aft_top, aft) Script_typed_ir.continuation) = - match cont with - | KNil -> Control.nil - | KCons _ -> Control.cons - | KReturn _ -> Control.return - | KMap_head (_, _) -> Control.map_head - | KUndip _ -> Control.undip - | KLoop_in _ -> Control.loop_in - | KLoop_in_left _ -> Control.loop_in_left - | KIter (_, xs, _) -> Control.iter (Size.of_int (List.length xs)) - | KList_enter_body (_, xs, ys, _, _) -> - Control.list_enter_body - (Size.of_int (List.length xs)) - (Size.of_int (List.length ys)) - | KList_exit_body (_, _, _, _, _) -> Control.list_exit_body - | KMap_enter_body (_, xs, _, _) -> - Control.map_enter_body (Size.of_int (List.length xs)) - | KMap_exit_body (_, _, ((module Map) as map), k, _) -> - let key_size = size_of_comparable_value Map.key_ty k in - Control.map_exit_body key_size (Size.map map) - | KView_exit _ -> Control.view_exit - | KLog _ -> Control.log - -(** [Stop_bench] gets raised when a [IFailwith] would be the next instruction. - This allows us to recover the full execution trace, including the trace of - the [IFailwith]. - - The actual benchmark will follow the same execution branch, but instead will - raise an [error] which will be ignored. Thus it is safe to end a benchmark - with [IFailwith], but timings are expected to be different from ending with - [IHalt]. This means that, if we choose to include this behavior in any - benchmark, [IFailwith] must be benched. *) -exception Stop_bench - -let extract_deps (type bef_top bef aft_top aft) ctxt step_constants - (kinstr : (bef_top, bef, aft_top, aft) Script_typed_ir.kinstr) - (stack : bef_top * bef) = - let trace = ref [] in - (* Logger definition *) - let log_interp _instr _ctxt _log _stack_ty _stack = () in - let log_entry : - type a s b f. (a, s, b, f, a, s) Script_typed_ir.logging_function = - fun kinstr ctxt _loc _stack_ty stack -> - trace := extract_ir_sized_step ctxt kinstr stack :: !trace ; - match kinstr with IFailwith _ -> raise Stop_bench | _ -> () - in - let log_control kont = trace := extract_control_trace kont :: !trace in - let log_exit _instr _ctxt _log _stack_ty _stack = () in - let get_log () = Environment.Error_monad.return_none in - let logger = {log_interp; log_entry; log_control; log_exit; get_log} in - try - let res = - Lwt_main.run - (Script_interpreter.kstep - (Some logger) - ctxt - step_constants - kinstr - (fst stack) - (snd stack)) - in - match Environment.wrap_tzresult res with - | Error errs -> - Format.eprintf "%a@." Error_monad.pp_print_trace errs ; - raise (Failure "Interpreter_workload.extract_deps: error in step") - | Ok (_aft_top, _aft, _ctxt) -> - (* ((aft_top, aft), List.rev !trace, ctxt) *) - List.rev !trace - with Stop_bench -> List.rev !trace - -let extract_deps_continuation (type bef_top bef aft_top aft) ctxt step_constants - (cont : (bef_top, bef, aft_top, aft) Script_typed_ir.continuation) - (stack : bef_top * bef) = - let trace = ref [] in - (* Logger definition *) - let log_interp _instr _ctxt _log _stack_ty _stack = () in - let log_entry : - type a s b f. (a, s, b, f, a, s) Script_typed_ir.logging_function = - fun kinstr ctxt _loc _stack_ty stack -> - trace := extract_ir_sized_step ctxt kinstr stack :: !trace ; - match kinstr with IFailwith _ -> raise Stop_bench | _ -> () - in - let log_control kont = trace := extract_control_trace kont :: !trace in - let log_exit _instr _ctxt _log _stack_ty _stack = () in - let get_log () = Environment.Error_monad.return_none in - let logger = {log_interp; log_entry; log_control; log_exit; get_log} in - try - let res = - Lwt_main.run - (Script_interpreter.Internals.next - (Some logger) - (Script_interpreter.Internals.OutDatedContext ctxt, step_constants) - 0xFF_FF_FF_FF - cont - (fst stack) - (snd stack)) - in - match Environment.wrap_tzresult res with - | Error errs -> - Format.eprintf "%a@." Error_monad.pp_print_trace errs ; - raise (Failure "Interpreter_workload.extract_deps: error in step") - | Ok (_aft_top, _aft, _outdated_ctxt, _gas) -> - (* ((aft_top, aft), List.rev !trace, outdated_ctxt, gas) *) - List.rev !trace - with Stop_bench -> List.rev !trace - -let sized_step_to_sparse_vec {name; args} = - let s = string_of_instr_or_cont name in - match args with - | [] -> Sparse_vec.String.of_list [(s, float_of_int 1)] - | _ -> - List.fold_left - (fun acc {name; arg} -> - Sparse_vec.String.( - add acc (of_list [(s ^ "_" ^ name, float_of_int arg)]))) - Sparse_vec.String.zero - args - -let trace_to_sparse_vec trace = - List.fold_left - (fun acc step -> Sparse_vec.String.add acc (sized_step_to_sparse_vec step)) - Sparse_vec.String.zero - trace diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_commands.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_commands.ml deleted file mode 100644 index 13cf634827ec..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_commands.ml +++ /dev/null @@ -1,202 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Michelson_generation - -let group = - { - Clic.name = "Michelson generation"; - title = "Command for generating random Michelson code and data"; - } - -module Michelson_concat_cmd = struct - let handler () file1 file2 file3 () = - let trace1 = Michelson_mcmc_samplers.load ~filename:file1 in - let trace2 = Michelson_mcmc_samplers.load ~filename:file2 in - let terms = trace1 @ trace2 in - let l1 = List.length trace1 in - let l2 = List.length trace2 in - Format.eprintf - "Loaded %d terms from %s, %d terms from %s, total %d@." - l1 - file1 - l2 - file2 - (l1 + l2) ; - Michelson_mcmc_samplers.save ~filename:file3 ~terms ; - return_unit - - let params = - Clic.( - prefixes [Protocol.name; "michelson"; "concat"; "files"] - @@ string ~name:"FILENAME" ~desc:"First file" - @@ prefixes ["and"] - @@ string ~name:"FILENAME" ~desc:"Second file" - @@ prefixes ["into"] - @@ string ~name:"FILENAME" ~desc:"Target file" - @@ stop) - - let command = - Clic.command - ~group - ~desc:"Michelson generation" - Clic.no_options - params - handler -end - -let () = Registration.add_command Michelson_concat_cmd.command - -module Michelson_gen_cmd = struct - let lift_opt f opt_arg state = - match opt_arg with None -> state | Some arg -> f arg state - - let handler (min_size, max_size, burn_in, seed) terms_count terms_kind - filename () = - let default = Michelson_generation.default_generator_config in - let min = Option.value ~default:default.target_size.min min_size in - let max = Option.value ~default:default.target_size.max max_size in - let burn_in_multiplier = - Option.value ~default:default.burn_in_multiplier burn_in - in - let rng_state = - match seed with - | None -> - Format.eprintf "Self-initialization of PRNG@." ; - let state = Random.State.make_self_init () in - Format.(eprintf "PRNG state hash: %d@." (Hashtbl.hash state)) ; - state - | Some seed -> - Format.eprintf "PRNG initialized with seed %d@." seed ; - Random.State.make [|seed|] - in - let cfg = - {Michelson_generation.target_size = {min; max}; burn_in_multiplier} - in - let terms_count = - match int_of_string terms_count with - | exception Failure _ -> - Format.eprintf "TERMS-COUNT must be an integer, exiting@." ; - exit 1 - | terms_count -> - if terms_count <= 0 then ( - Format.eprintf "TERMS-COUNT must be strictly positive, exiting@." ; - exit 1) - else terms_count - in - let progress = - Benchmark_helpers.make_progress_printer - Format.err_formatter - terms_count - "Generating term" - in - let terms = - match terms_kind with - | "data" -> - Stdlib.List.init terms_count (fun _i -> - progress () ; - Michelson_mcmc_samplers.Data - (Michelson_generation.make_data_sampler rng_state cfg)) - | "code" -> - Stdlib.List.init terms_count (fun _i -> - progress () ; - Michelson_mcmc_samplers.Code - (Michelson_generation.make_code_sampler rng_state cfg)) - | _ -> - Format.eprintf "Term kind must be either \"data\" or \"code\"@." ; - exit 1 - in - Michelson_mcmc_samplers.save ~filename ~terms ; - return_unit - - let min_size_arg = - let min_size = - Clic.parameter (fun (_ : unit) parsed -> - try return (int_of_string parsed) - with _ -> - Printf.eprintf "Error while parsing --min-size argument." ; - exit 1) - in - Clic.arg - ~doc:"Lower bound for target size of terms" - ~long:"min-size" - ~placeholder:"int" - min_size - - let max_size_arg = - let max_size = - Clic.parameter (fun (_ : unit) parsed -> - try return (int_of_string parsed) - with _ -> - Printf.eprintf "Error while parsing --max-size argument." ; - exit 1) - in - Clic.arg - ~doc:"Lower bound for target size of terms" - ~long:"max-size" - ~placeholder:"int" - max_size - - let burn_in_arg = - let target_size = - Clic.parameter (fun (_ : unit) parsed -> - try return (int_of_string parsed) - with _ -> - Printf.eprintf "Error while parsing --burn-in argument." ; - exit 1) - in - Clic.arg - ~doc:"Burn-in multiplier" - ~long:"burn-in" - ~placeholder:"int" - target_size - - let seed_arg = - let seed = - Clic.parameter (fun (_ : unit) parsed -> - try return (int_of_string parsed) - with _ -> - Printf.eprintf "Error while parsing --seed argument." ; - exit 1) - in - Clic.arg ~doc:"RNG seed" ~long:"seed" ~placeholder:"int" seed - - let options = Clic.args4 min_size_arg max_size_arg burn_in_arg seed_arg - - let params = - Clic.( - prefixes [Protocol.name; "michelson"; "generate"] - @@ string ~name:"TERMS-COUNT" ~desc:"Number of terms to generate" - @@ prefixes ["terms"; "of"; "kind"] - @@ string ~name:"{data|code}" ~desc:"Kind of term to generate" - @@ prefixes ["in"] - @@ string ~name:"FILENAME" ~desc:"File where to save Michelson terms" - @@ stop) - - let command = - Clic.command ~group ~desc:"Michelson generation" options params handler -end - -let () = Registration.add_command Michelson_gen_cmd.command diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_generation.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_generation.ml deleted file mode 100644 index d1422930010a..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_generation.ml +++ /dev/null @@ -1,113 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type generator_config = { - target_size : Base_samplers.range; - burn_in_multiplier : int; -} - -let default_generator_config = - {target_size = {Base_samplers.min = 100; max = 1000}; burn_in_multiplier = 5} - -let generator_config_encoding = - let open Data_encoding in - conv - (fun {target_size; burn_in_multiplier} -> (target_size, burn_in_multiplier)) - (fun (target_size, burn_in_multiplier) -> {target_size; burn_in_multiplier}) - (obj2 - (req "target_size" Base_samplers.range_encoding) - (req "burn_in_multiplier" int31)) - -(* ----------------------------------------------------------------------- *) - -(* ----------------------------------------------------------------------- *) - -module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct - let size = 16 - - let algo = `Default -end) - -module Samplers = - Michelson_samplers.Make - (struct - let parameters = - { - Michelson_samplers.base_parameters = - { - int_size = {min = 8; max = 32}; - string_size = {min = 8; max = 128}; - bytes_size = {min = 8; max = 128}; - }; - list_size = {min = 0; max = 1000}; - set_size = {min = 0; max = 1000}; - map_size = {min = 0; max = 1000}; - } - end) - (Crypto_samplers) - -module Michelson_base_samplers = Samplers.Michelson_base - -(* ----------------------------------------------------------------------- *) - -let make_data_sampler rng_state config = - let target_size = - Base_samplers.sample_in_interval rng_state ~range:config.target_size - in - let module Data = - Michelson_mcmc_samplers.Make_data_sampler - (Michelson_base_samplers) - (Crypto_samplers) - (struct - let rng_state = rng_state - - let target_size = target_size - - let verbosity = `Silent - end) - in - let burn_in = target_size * config.burn_in_multiplier in - let generator = Data.generator ~burn_in rng_state in - generator rng_state - -let make_code_sampler rng_state config = - let target_size = - Base_samplers.sample_in_interval rng_state ~range:config.target_size - in - let module Code = - Michelson_mcmc_samplers.Make_code_sampler - (Michelson_base_samplers) - (Crypto_samplers) - (struct - let rng_state = rng_state - - let target_size = target_size - - let verbosity = `Silent - end) - in - let burn_in = target_size * config.burn_in_multiplier in - let generator = Code.generator ~burn_in rng_state in - generator rng_state diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_generation.mli b/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_generation.mli deleted file mode 100644 index 89868e6f58b1..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_generation.mli +++ /dev/null @@ -1,61 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** {2 Wrappers around some Michelson generators and related helpers} *) - -(** [generator_config] specifies some parameters to the - {!Tezos_benchmark_alpha.Michelson_mcmc_samplers} Michelson code and data generators. *) -type generator_config = { - target_size : Base_samplers.range; - (** The target size of the terms, in number of nodes, is sampled uniformly - in [target_size]. *) - burn_in_multiplier : int; - (** The generators are based on a Markov chain, which must be - "heated-up" until it reaches its stationary state. A prefix of samples - are therefore thrown away: this is called the {e burn-in} phase. - The number of thrown away terms is proportional to [burn_in_multiplier] - and [target_size]. *) -} - -(** Default configuration for the generators. *) -val default_generator_config : generator_config - -val generator_config_encoding : generator_config Data_encoding.t - -(** Samplers *) - -(** [make_data_sampler] constructs a Michelson data sampler based on the - infrastructure available in {!Tezos_benchmark_alpha.Michelson_mcmc_samplers}. *) -val make_data_sampler : - Random.State.t -> generator_config -> Michelson_mcmc_samplers.michelson_data - -(** [make_code_sampler] constructs a Michelson code sampler based on the - infrastructure available in {!Tezos_benchmark_alpha.Michelson_mcmc_samplers}. *) -val make_code_sampler : - Random.State.t -> generator_config -> Michelson_mcmc_samplers.michelson_code - -(** [Samplers] is an instance of the direct-style (non-MCMC based) samplers - implemented in {!Tezos_benchmark_alpha.Michelson_samplers}. *) -module Samplers : Michelson_samplers.S diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_types.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_types.ml deleted file mode 100644 index 047097c932e2..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/michelson_types.ml +++ /dev/null @@ -1,138 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Script_typed_ir - -[@@@ocaml.warning "-32"] - -let ( @$ ) x y = Item_t (x, y, None) - -let bot = Bot_t - -let unit = unit_t ~annot:None - -let unit_cmp = unit_key ~annot:None - -let int_cmp = int_key ~annot:None - -let string_cmp = string_key ~annot:None - -(* the type of integers *) -let int = int_t ~annot:None - -(* the type of naturals *) -let nat = nat_t ~annot:None - -(* the type of strings *) -let string = string_t ~annot:None - -(* the type of bytes *) -let bytes = bytes_t ~annot:None - -(* the type of booleans *) -let bool = bool_t ~annot:None - -(* the type of mutez *) -let mutez = mutez_t ~annot:None - -(* the type of public key *) -let public_key = key_t ~annot:None - -(* the type of key hashes *) -let key_hash = key_hash_t ~annot:None - -(* the type of signatures *) -let signature = signature_t ~annot:None - -(* the type of addresses *) -let address = address_t ~annot:None - -(* the type of chain ids *) -let chain_id = chain_id_t ~annot:None - -(* the type of timestamps *) -let timestamp = timestamp_t ~annot:None - -(* list type constructor *) -let list x = - match list_t (-1) x ~annot:None with Error _ -> assert false | Ok t -> t - -(* option type constructor *) -let option x = - match option_t (-1) x ~annot:None with Error _ -> assert false | Ok t -> t - -(* map type constructor*) -let map k v = - match map_t (-1) k v ~annot:None with Error _ -> assert false | Ok t -> t - -(* map type constructor*) -let big_map k v = - match big_map_t (-1) k v ~annot:None with - | Error _ -> assert false - | Ok t -> t - -(* set type constructor*) -let set k = - match set_t (-1) k ~annot:None with Error _ -> assert false | Ok t -> t - -(* pair type constructor*) -let pair k1 k2 = - match pair_t (-1) (k1, None, None) (k2, None, None) ~annot:None with - | Error _ -> assert false - | Ok t -> t - -(* union type constructor*) -let union k1 k2 = - match union_t (-1) (k1, None) (k2, None) ~annot:None with - | Error _ -> assert false - | Ok t -> t - -let lambda x y = - match lambda_t (-1) x y ~annot:None with Error _ -> assert false | Ok t -> t - -let contract arg_ty = - match contract_t (-1) arg_ty ~annot:None with - | Error _ -> assert false - | Ok t -> t - -let operation = operation_t ~annot:None - -let sapling_state memo_size = sapling_state_t ~memo_size ~annot:None - -let sapling_transaction memo_size = sapling_transaction_t ~memo_size ~annot:None - -let bls12_381_g1 = bls12_381_g1_t ~annot:None - -let bls12_381_g2 = bls12_381_g2_t ~annot:None - -let bls12_381_fr = bls12_381_fr_t ~annot:None - -let ticket ty = - match ticket_t (-1) ty ~annot:None with Error _ -> assert false | Ok t -> t - -let chest_key = chest_key_t ~annot:None - -let chest = chest_t ~annot:None diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/registration_helpers.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/registration_helpers.ml deleted file mode 100644 index 81a84d090420..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/registration_helpers.ml +++ /dev/null @@ -1,37 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let register ((module Bench) : Benchmark.t) = - let module B : Benchmark.S = struct - include Bench - - let name = name ^ "_" ^ Protocol.name - - let tags = Protocol.name :: tags - end in - Registration.register (module B) - -let register_for_codegen name model = - Registration.register_for_codegen (name ^ "_" ^ Protocol.name) model diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/sapling_benchmarks.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/sapling_benchmarks.ml deleted file mode 100644 index 5ce5c4ff0693..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/sapling_benchmarks.ml +++ /dev/null @@ -1,152 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -module Apply_diff_bench : Benchmark.S = struct - include Interpreter_benchmarks.Default_config - include Interpreter_benchmarks.Default_boilerplate - - let name = "SAPLING_APPLY_DIFF" - - let info = "Benchmarking SAPLING_APPLY_DIFF" - - let tags = ["sapling"] - - let diff_from_tx (tx : Alpha_context.Sapling.transaction) = - let open Environment.Sapling.UTXO in - let commitments_and_ciphertexts = - List.map (fun x -> (x.cm, x.ciphertext)) tx.outputs - in - { - Protocol.Sapling_repr.commitments_and_ciphertexts; - nullifiers = List.map (fun (x : input) -> x.nf) tx.inputs; - } - - type workload = {nb_input : int; nb_output : int; nb_cm : int; nb_nf : int} - - let workload_encoding : workload Data_encoding.t = - let open Data_encoding in - def "diff_arg_encoding" - @@ conv - (fun {nb_input; nb_output; nb_cm; nb_nf} -> - (nb_input, nb_output, nb_cm, nb_nf)) - (fun (nb_input, nb_output, nb_cm, nb_nf) -> - {nb_input; nb_output; nb_cm; nb_nf}) - (tup4 Size.encoding Size.encoding Size.encoding Size.encoding) - - let workload_to_vector {nb_input; nb_output; nb_cm = _; nb_nf = _} = - let l = - [ - ("nb_input", float_of_int nb_input); - ("nb_output", float_of_int nb_output); - ] - in - Sparse_vec.String.of_list l - - let model = - Model.make - ~conv:(fun {nb_input; nb_output; _} -> (nb_input, (nb_output, ()))) - ~model: - (Model.bilinear_affine - ~intercept:(Free_variable.of_string "apply_diff_const") - ~coeff1:(Free_variable.of_string "apply_diff_inputs") - ~coeff2:(Free_variable.of_string "apply_diff_outputs")) - - let models = [("apply_diff", model)] - - let benchmark_apply_diff seed sapling_transition () = - let sapling_forge_rng_state = - Random.State.make - @@ Option.fold - ~none:Sapling_generation.shared_seed - ~some:(fun seed -> [|seed|]) - seed - in - Lwt_main.run - ( Execution_context.make ~rng_state:sapling_forge_rng_state - >>=? fun (ctxt, step_constants) -> - Sapling_generation.prepare_seeded_state sapling_transition ctxt - >>=? fun (_, _, _, _, ctxt, state_id) -> - let external_state_id = Alpha_context.Sapling.Id.parse_z state_id in - let internal_state_id = - Lazy_storage_kind.Sapling_state.Id.parse_z state_id - in - Alpha_context.Sapling.(state_from_id ctxt external_state_id) - >|= Protocol.Environment.wrap_tzresult - >>=? fun (state, ctxt) -> - Format.eprintf "state hash: %d@." (Hashtbl.hash state.diff) ; - Format.eprintf - "tx hash: %d@." - (Hashtbl.hash sapling_transition.sapling_tx) ; - let address = Alpha_context.Contract.to_b58check step_constants.self in - let chain_id = - Environment.Chain_id.to_b58check step_constants.chain_id - in - let anti_replay = address ^ chain_id in - Format.eprintf "anti-replay: %s@." anti_replay ; - let diff = diff_from_tx sapling_transition.sapling_tx in - let closure () = - ignore - (Lwt_main.run - (Sapling_generation.apply_diff ctxt internal_state_id diff)) - in - let workload = - { - nb_input = List.length sapling_transition.sapling_tx.inputs; - nb_output = List.length sapling_transition.sapling_tx.outputs; - nb_cm = Int64.to_int sapling_transition.commitment_count; - nb_nf = Int64.to_int sapling_transition.nullifier_count; - } - in - return (Generator.Plain {workload; closure}) ) - |> function - | Ok closure -> closure - | Error errs -> - Format.eprintf - "Runner.benchmarkable_from_instr_str:\n%a@." - (Format.pp_print_list Error_monad.pp) - errs ; - exit 1 - - let create_benchmarks ~rng_state ~bench_num config = - ignore rng_state ; - match config.sapling with - | {sapling_txs_file; seed} -> - let transitions = Sapling_generation.load ~filename:sapling_txs_file in - let length = List.length transitions in - if length < bench_num then - Format.eprintf - "KSapling_verify_update: warning, only %d available transactions \ - (requested %d)@." - length - bench_num ; - let transitions = List.take_n (min bench_num length) transitions in - List.map - (fun (_filename, tx) -> benchmark_apply_diff seed tx) - transitions -end - -let () = Registration_helpers.register (module Apply_diff_bench) diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/sapling_commands.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/sapling_commands.ml deleted file mode 100644 index 77b42a0b848b..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/sapling_commands.ml +++ /dev/null @@ -1,134 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Sapling_gen_cmd = struct - let lift_opt f opt_arg state = - match opt_arg with None -> state | Some arg -> f arg state - - (* ----------------------------------------------------------------------- *) - (* Handling options for the "generate sapling transactions" command *) - - (* Generic max-%s argument *) - let max name = - Clic.arg - ~doc:(Printf.sprintf "Maximum number of %s" name) - ~long:(Printf.sprintf "max-%s" name) - ~placeholder:"integer" - (Clic.parameter (fun (_ : unit) parsed -> - match int_of_string parsed with - | exception Failure _ -> - Format.eprintf - "Ill-formatted --max-%s option (expected integer), exiting" - name ; - exit 1 - | res when res <= 0 -> - Format.eprintf - "--max-%s should be a strictly positive integer, exiting" - name ; - exit 1 - | res -> return res)) - - (* Integer argument --seed *) - let seed_arg = - let seed = - Clic.parameter (fun (_ : unit) parsed -> - try return (int_of_string parsed) - with _ -> - Printf.eprintf "Error while parsing --seed argument." ; - exit 1) - in - Clic.arg ~doc:"RNG seed" ~long:"seed" ~placeholder:"int" seed - - let positive_param = - Clic.parameter (fun _ s -> - match int_of_string_opt s with - | Some i when i > 0 -> return i - | _ -> failwith "Parameter should be a positive integer literal") - - open Sapling_generation - - let set_max_inputs max_inputs options = {options with max_inputs} - - let set_max_outputs max_outputs options = {options with max_outputs} - - let set_max_nullifiers max_nullifiers options = {options with max_nullifiers} - - let set_max_additional_commitments max_additional_commitments options = - {options with max_additional_commitments} - - let set_seed seed (options : sapling_gen_options) = - {options with seed = Some seed} - - let sapling_handler - (max_inputs, max_outputs, max_nullifiers, max_additional_commitments, seed) - tx_count save_to () = - let sapling_gen_options = - default_sapling_gen_options - |> lift_opt set_max_inputs max_inputs - |> lift_opt set_max_outputs max_outputs - |> lift_opt set_max_nullifiers max_nullifiers - |> lift_opt set_max_additional_commitments max_additional_commitments - |> lift_opt set_seed seed - in - generate save_to tx_count sapling_gen_options ; - return () - - let options = - Clic.args5 - (max "inputs") - (max "outputs") - (max "nullifiers") - (max "additional-commitments") - seed_arg - - let params = - Clic.( - prefixes [Protocol.name; "sapling"; "generate"] - @@ param - ~name:"SAPLING-TX-COUNT" - ~desc:"Number of sapling transactions to generate" - positive_param - @@ prefixes ["transactions"; "in"] - @@ string - ~name:"SAPLING-TX-FILE" - ~desc:"File containing sapling transactions" - @@ stop) - - let group = - { - Clic.name = "Sapling tx generation"; - title = "Command for generating random sapling transactions"; - } - - let command = - Clic.command - ~group - ~desc:"Sapling transaction generation" - options - params - sapling_handler -end - -let () = Registration.add_command Sapling_gen_cmd.command diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/sapling_generation.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/sapling_generation.ml deleted file mode 100644 index 79059417911e..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/sapling_generation.ml +++ /dev/null @@ -1,560 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(* ------------------------------------------------------------------------- *) -type sapling_gen_options = { - max_inputs : int; - max_outputs : int; - max_nullifiers : int; - max_additional_commitments : int; - seed : int option; -} - -let default_sapling_gen_options = - { - max_inputs = 100; - max_outputs = 100; - max_nullifiers = 100; - max_additional_commitments = 50; - seed = None; - } - -(* ------------------------------------------------------------------------- *) -(* Evil incantations *) - -(* We have to break the protocol abstraction boundary quite often in this - module. Props to whoever finds a way to avoid these calls. *) - -let alpha_to_raw (x : Alpha_context.t) : Raw_context.t = Obj.magic x - -let raw_to_alpha (x : Raw_context.t) : Alpha_context.t = Obj.magic x - -(* ------------------------------------------------------------------------- *) -(* Helpers *) - -(* sample a random permutation of [0 ; ... ; n-1] *) -let fisher_yates n state = - let a = Array.init n (fun i -> i) in - for i = 0 to Array.length a - 1 do - let j = Random.State.int state (i + 1) in - let tmp = a.(j) in - a.(j) <- a.(i) ; - a.(i) <- tmp - done ; - a - -(* sample a random injection of [0 ; ... ; m-1 ] in [0 ; ... ; n - 1] *) -let random_injection m n state = - if m > n then invalid_arg "random_injection" - else - let a = fisher_yates n state in - Array.sub a 0 m - -(* ------------------------------------------------------------------------- *) -(* Sapling generation *) - -(* Sapling state spec + sapling transaction valid for that state. *) -type sapling_transition = { - state_seed : int64; - nullifier_count : int64; - commitment_count : int64; - sapling_tx : Alpha_context.Sapling.transaction; -} - -type forge_info = { - rcm : Tezos_sapling.Core.Client.Rcm.t; - position : int64; - amount : int64; - address : Tezos_sapling.Core.Client.Viewing_key.address; - nf : Tezos_sapling.Core.Client.Nullifier.t; -} - -let random_amount sum = - Random.int64 (Int64.sub Tezos_sapling.Core.Validator.UTXO.max_amount sum) - -let reverse diff = - Protocol.Sapling_repr. - { - diff with - commitments_and_ciphertexts = List.rev diff.commitments_and_ciphertexts; - } - -let pp_rpc_diff fmtr (diff : Protocol.Sapling_repr.diff) = - let json = - Data_encoding.Json.construct Protocol.Sapling_repr.diff_encoding diff - in - Format.fprintf fmtr "%a" Data_encoding.Json.pp json - -let random_bytes state size = - Bytes.init size (fun _ -> Char.chr (Random.State.int state 256)) - -let rec gen_rcm state = - let rcm = - Data_encoding.Binary.of_bytes_exn - Tezos_sapling.Core.Client.Rcm.encoding - (random_bytes state 32) - in - try - Tezos_sapling.Core.Client.Rcm.assert_valid rcm ; - rcm - with _ -> gen_rcm state - -(* Adds a commitment, ciphertext, cv to an rpc_diff *) -let add_input diff vk index position sum state = - let rcm = gen_rcm state in - let amount = random_amount sum in - let (new_idx, address) = - Tezos_sapling.Core.Client.Viewing_key.new_address vk index - in - let cv = - Tezos_sapling.Core.Client.CV.of_bytes (random_bytes state 32) - |> WithExceptions.Option.get ~loc:__LOC__ - in - let (ciphertext, cm) = - Tezos_sapling.Core.Client.Forge.Output.to_ciphertext - Tezos_sapling.Core.Client.Forge.Output. - {address; amount; memo = Bytes.empty} - cv - vk - rcm - (Tezos_sapling.Core.Client.DH.esk_random ()) - in - let nf = - Tezos_sapling.Core.Client.Nullifier.compute address vk ~amount rcm ~position - in - let diff = - Protocol.Sapling_repr. - { - diff with - commitments_and_ciphertexts = - (cm, ciphertext) :: diff.commitments_and_ciphertexts; - } - in - return (diff, {rcm; position; amount; address; nf}, new_idx) - -let generate_commitments ~vk ~nb_input ~nb_cm ~nb_nf ~diff ~index state = - let inj = random_injection nb_input nb_cm state in - let use_for_input i = Array.exists (fun k -> k = i) inj in - let rec loop i cm_index nb_nf diff to_forge sum = - if i = nb_cm then return (reverse diff, to_forge) - else if use_for_input i then - (* create commitment for input *) - add_input diff vk cm_index (Int64.of_int i) sum state - >>=? fun (diff, forge_info, next_index) -> - let sum = Int64.add sum forge_info.amount in - loop (i + 1) next_index nb_nf diff (forge_info :: to_forge) sum - else - (* create commitment (not for input) *) - add_input diff vk cm_index (Int64.of_int i) sum state - >>=? fun (diff, {nf; _}, next_index) -> - (* can we use a nullifier? *) - if nb_nf = 0 then (* No. *) - loop (i + 1) next_index nb_nf diff to_forge sum - else - (* Yes! Grab it. *) - let diff = - Protocol.Sapling_repr.{diff with nullifiers = nf :: diff.nullifiers} - in - loop (i + 1) next_index (nb_nf - 1) diff to_forge sum - in - loop 0 index nb_nf diff [] 0L - -(* Add roots to the storage. One cm has to be added for every root. *) -let rec add_root nb_root ctxt id vk index size diff state = - if nb_root > 0 then - add_input Protocol.Sapling_storage.empty_diff vk index size 0L state - >>=? fun (diff_to_add, {position = size; _}, new_idx) -> - Protocol.Sapling_storage.apply_diff ctxt id diff_to_add - >|= Protocol.Environment.wrap_tzresult - >>=? fun (ctxt, _) -> - (* We call it nb_root -1 because one root is already present*) - add_root - (nb_root - 1) - ctxt - id - vk - new_idx - (Int64.succ size) - Protocol.Sapling_repr. - { - diff with - commitments_and_ciphertexts = - diff.commitments_and_ciphertexts - @ diff_to_add.commitments_and_ciphertexts; - } - state - else return (ctxt, diff) - -(* Compute a state as an OCaml object to compute the witness *) -let state_from_rpc_diff rpc_diff = - Tezos_sapling.Storage.add - (Tezos_sapling.Storage.empty ~memo_size:0) - rpc_diff.Protocol.Sapling_repr.commitments_and_ciphertexts - -(* Create an (unspendable) output from a proving context and a vk *) -let output proving_ctx vk sum = - let address = Tezos_sapling.Core.Client.Viewing_key.dummy_address () in - let amount = random_amount sum in - let rcm = Tezos_sapling.Core.Client.Rcm.random () in - let esk = Tezos_sapling.Core.Client.DH.esk_random () in - let (cv_o, proof_o) = - Tezos_sapling.Core.Client.Proving.output_proof - proving_ctx - esk - address - rcm - ~amount - in - let (ciphertext, cm) = - Tezos_sapling.Core.Client.Forge.Output.to_ciphertext - Tezos_sapling.Core.Client.Forge.Output. - {address; amount; memo = Bytes.empty} - cv_o - vk - rcm - esk - in - (Tezos_sapling.Core.Validator.UTXO.{cm; proof_o; ciphertext}, amount) - -(* Returns a list of outputs and the sum of their amount *) -let outputs nb_output proving_ctx vk = - let rec aux output_amount list_outputs nb_output sum = - match nb_output with - | 0 -> (output_amount, list_outputs) - | nb_output -> - let (output, amount) = output proving_ctx vk sum in - assert ( - Int64.compare - amount - (Int64.sub - Int64.max_int - Tezos_sapling.Core.Validator.UTXO.max_amount) - < 0) ; - aux - (Int64.add output_amount amount) - (output :: list_outputs) - (nb_output - 1) - (Int64.add sum amount) - in - aux 0L [] nb_output 0L - -(* Create the list of inputs. To use once the merkle tree is completed. *) -let make_inputs to_forge local_state proving_ctx sk vk root anti_replay = - List.map_ep - (fun {rcm; position; amount; address; nf} -> - let witness = Tezos_sapling.Storage.get_witness local_state position in - let ar = Tezos_sapling.Core.Client.Proving.ar_random () in - let (cv, rk, proof) = - Tezos_sapling.Core.Client.Proving.spend_proof - proving_ctx - vk - sk - address - rcm - ar - ~amount - ~root - ~witness - in - let signature = - Tezos_sapling.Core.Client.Proving.spend_sig - sk - ar - cv - nf - rk - proof - anti_replay - in - return - Tezos_sapling.Core.Validator.UTXO. - {cv; nf; rk; proof_i = proof; signature}) - to_forge - -let init_fresh_sapling_state ctxt = - let open Protocol.Environment.Error_monad in - Protocol.Lazy_storage_diff.fresh - Protocol.Lazy_storage_kind.Sapling_state - ~temporary:false - ctxt - >>=? fun (ctxt, id) -> - Protocol.Sapling_storage.init ctxt id ~memo_size:0 - (* TODO CHECK *) - >>=? fun ctxt -> return (ctxt, id) - -let generate_spending_and_viewing_keys state = - let sk = - Tezos_sapling.Core.Client.Spending_key.of_seed (random_bytes state 32) - in - let vk = Tezos_sapling.Core.Client.Viewing_key.of_sk sk in - (sk, vk) - -let prepare_seeded_state_internal ~(nb_input : int) ~(nb_nf : int) - ~(nb_cm : int) (ctxt : Raw_context.t) (state : Random.State.t) : - (Sapling_repr.diff - * forge_info list - * Tezos_sapling.Core.Client.Spending_key.t - * Tezos_sapling.Core.Client.Viewing_key.t - * Raw_context.t - * Protocol.Lazy_storage_kind.Sapling_state.Id.t) - tzresult - Lwt.t = - init_fresh_sapling_state ctxt >|= Protocol.Environment.wrap_tzresult - >>=? fun (ctxt, id) -> - let index_start = Tezos_sapling.Core.Client.Viewing_key.default_index in - let (sk, vk) = generate_spending_and_viewing_keys state in - generate_commitments - ~vk - ~nb_input - ~nb_cm - ~nb_nf - ~diff:Protocol.Sapling_storage.empty_diff - ~index:index_start - state - >>=? fun (diff, to_forge) -> - Protocol.Sapling_storage.apply_diff ctxt id diff - >|= Protocol.Environment.wrap_tzresult - >>=? fun (ctxt, _size) -> return (diff, to_forge, sk, vk, ctxt, id) - -let prepare_seeded_state - {state_seed; nullifier_count; commitment_count; sapling_tx} ctxt = - let rng_state = Random.State.make [|Int64.to_int state_seed|] in - prepare_seeded_state_internal - ~nb_input:(List.length sapling_tx.inputs) - ~nb_nf:(Int64.to_int nullifier_count) - ~nb_cm:(Int64.to_int commitment_count) - (alpha_to_raw ctxt) - rng_state - >>=? fun (diff, forge_info, spending_key, viewing_key, raw_ctxt, raw_id) -> - let id = Protocol.Lazy_storage_kind.Sapling_state.Id.unparse_to_z raw_id in - return (diff, forge_info, spending_key, viewing_key, raw_to_alpha raw_ctxt, id) - -let generate ~(nb_input : int) ~(nb_output : int) ~(nb_nf : int) ~(nb_cm : int) - ~(anti_replay : string) ~ctxt state = - assert (nb_input <= nb_cm) ; - assert (nb_nf <= nb_cm - nb_input) ; - prepare_seeded_state_internal ~nb_input ~nb_nf ~nb_cm ctxt state - >>=? fun (diff, to_forge, sk, vk, ctxt, id) -> - let local_state = state_from_rpc_diff diff in - let root = Tezos_sapling.Storage.get_root local_state in - Tezos_sapling.Core.Client.Proving.with_proving_ctx (fun proving_ctx -> - make_inputs to_forge local_state proving_ctx sk vk root anti_replay - >>=? fun inputs -> - let (output_amount, outputs) = outputs nb_output proving_ctx vk in - let input_amount = - List.fold_left - (fun sum {amount; _} -> - assert ( - Int64.compare - sum - (Int64.sub - Int64.max_int - Tezos_sapling.Core.Validator.UTXO.max_amount) - < 0) ; - Int64.add sum amount) - 0L - to_forge - in - let balance = Int64.sub input_amount output_amount in - let binding_sig = - Tezos_sapling.Core.Client.Proving.make_binding_sig - proving_ctx - inputs - outputs - ~balance - anti_replay - in - let transaction = - Tezos_sapling.Core.Validator.UTXO. - {inputs; outputs; binding_sig; balance; root} - in - return transaction) - >>=? fun transaction -> - assert (Compare.List_length_with.(transaction.inputs = nb_input)) ; - assert (Compare.List_length_with.(transaction.outputs = nb_output)) ; - return (transaction, (ctxt, id)) - -(* ------------------------------------------------------------------------- *) -(* Nicely packaging sapling generation for snoop *) - -let sapling_transition_encoding = - let open Data_encoding in - conv - (fun {state_seed; nullifier_count; commitment_count; sapling_tx} -> - (state_seed, nullifier_count, commitment_count, sapling_tx)) - (fun (state_seed, nullifier_count, commitment_count, sapling_tx) -> - {state_seed; nullifier_count; commitment_count; sapling_tx}) - (obj4 - (req "state_seed" int64) - (req "nullifier_count" int64) - (req "commitment_count" int64) - (req "sapling_tx" Alpha_context.Sapling.transaction_encoding)) - -let sapling_dataset_encoding = Data_encoding.list sapling_transition_encoding - -let save ~filename ~txs = - let str = - match Data_encoding.Binary.to_string sapling_dataset_encoding txs with - | Error err -> - Format.eprintf - "Sapling_generation.save: encoding failed (%a); exiting" - Data_encoding.Binary.pp_write_error - err ; - exit 1 - | Ok res -> res - in - ignore (* TODO handle error *) - (Lwt_main.run @@ Tezos_stdlib_unix.Lwt_utils_unix.create_file filename str) - -let load_file filename = - Lwt_main.run - @@ ( Tezos_stdlib_unix.Lwt_utils_unix.read_file filename >>= fun str -> - Format.eprintf "Sapling_generation.load: loaded %s@." filename ; - match Data_encoding.Binary.of_string sapling_dataset_encoding str with - | Ok result -> - let result = List.map (fun tx -> (filename, tx)) result in - Lwt.return result - | Error err -> - Format.eprintf - "Sapling_generation.load: can't load file (%a); exiting" - Data_encoding.Binary.pp_read_error - err ; - exit 1 ) - -let get_all_sapling_data_files directory = - let is_sapling_data file = - let regexp = Str.regexp ".*\\.sapling" in - Str.string_match regexp file 0 - in - let lift file = directory ^ "/" ^ file in - let handle = Unix.opendir directory in - let rec loop acc = - match Unix.readdir handle with - | file -> if is_sapling_data file then loop (lift file :: acc) else loop acc - | exception End_of_file -> - Unix.closedir handle ; - acc - in - loop [] - -let load ~filename = - if not (Sys.file_exists filename) then ( - Format.eprintf "Sapling_generation.load: file does not exist@." ; - Stdlib.failwith "Sapling_generation.load") - else if Sys.is_directory filename then - let () = - Format.eprintf - "Sapling_generation.load: loading all .sapling files from directory \ - %s@." - filename - in - let files = get_all_sapling_data_files filename in - List.concat (List.map load_file files) - else load_file filename - -let shared_seed = [|9798798; 217861209; 876786|] - -let generate (save_to : string) (tx_count : int) - (sapling_gen_options : sapling_gen_options) = - let result = - Lwt_main.run - (let { - max_inputs; - max_outputs; - max_nullifiers; - max_additional_commitments; - seed; - } = - sapling_gen_options - in - let rng_state = - (* /!\ This must match the seed used at benchmark time, - defined in Runner.benchmark_sapling. /!\ *) - Random.State.make - @@ Option.fold ~none:shared_seed ~some:(fun seed -> [|seed|]) seed - in - Execution_context.make ~rng_state >>=? fun (ctxt, step_constants) -> - let address = Alpha_context.Contract.to_b58check step_constants.self in - let chain_id = - Environment.Chain_id.to_b58check step_constants.chain_id - in - let anti_replay = address ^ chain_id in - let ctxt = alpha_to_raw ctxt in - (match sapling_gen_options.seed with - | None -> Random.self_init () - | Some seed -> Random.init seed) ; - let seeds = - Stdlib.List.init tx_count (fun i -> (i, Random.int 0x3FFFFFFF)) - in - let rec loop seeds acc = - match seeds with - | [] -> return acc - | (i, seed) :: tl -> - let nb_input = 1 + Random.int max_inputs in - let nb_output = 1 + Random.int max_outputs in - let nb_nf = 1 + Random.int max_nullifiers in - let nb_cm = - nb_input + nb_nf + Random.int max_additional_commitments - in - let () = - Format.eprintf "@." ; - Format.eprintf "generating sapling tx %i/%d@." (i + 1) tx_count ; - Format.eprintf "saving to file %s@." save_to ; - Format.eprintf "nb_input = %d@." nb_input ; - Format.eprintf "nb_output = %d@." nb_output ; - Format.eprintf "nb_nf = %d@." nb_nf ; - Format.eprintf "nb_cm = %d@." nb_cm ; - Format.eprintf "anti_replay = %s@." anti_replay - in - let state = Random.State.make [|seed|] in - generate - ~nb_input - ~nb_output - ~nb_nf - ~nb_cm - ~anti_replay - ~ctxt - state - >>=? fun (tx, (_ctxt, _state_id)) -> - let result = - { - state_seed = Int64.of_int seed; - nullifier_count = Int64.of_int nb_nf; - commitment_count = Int64.of_int nb_cm; - sapling_tx = Obj.magic tx; - } - in - loop tl (result :: acc) - in - loop seeds []) - in - match result with Ok txs -> save ~filename:save_to ~txs | Error _ -> () - -let apply_diff ctxt id diff = - let open Protocol.Environment.Error_monad in - Sapling_storage.apply_diff (alpha_to_raw ctxt) id diff - >>=? fun (ctxt, size) -> return (raw_to_alpha ctxt, size) diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/script_repr_benchmarks.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/script_repr_benchmarks.ml deleted file mode 100644 index 8409dac0da8f..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/script_repr_benchmarks.ml +++ /dev/null @@ -1,143 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** {2 [Script_repr] benchmarks} *) - -module Script_repr_shared_config = struct - type config = unit - - let config_encoding = Data_encoding.unit - - let default_config = () - - type workload = {micheline_nodes : int} - - let workload_encoding = - let open Data_encoding in - conv - (fun {micheline_nodes} -> micheline_nodes) - (fun micheline_nodes -> {micheline_nodes}) - (obj1 (req "micheline_nodes" int31)) - - let tags = [Tags.translator] - - let workload_to_vector {micheline_nodes} = - Sparse_vec.String.of_list [("nodes", float_of_int micheline_nodes)] -end - -module Sampler = Micheline_sampler.Make (struct - type prim = Michelson_v1_primitives.prim - - (* The runtime of the functions in [Script_repr] do not depend on the primitives. *) - let sample_prim : Michelson_v1_primitives.prim Base_samplers.sampler = - fun _rng_state -> I_ADD - - let sample_annots : string list Base_samplers.sampler = fun _rng_state -> [] - - let sample_string = Base_samplers.uniform_string ~nbytes:4 - - let sample_bytes = Base_samplers.uniform_bytes ~nbytes:4 - - let sample_z = Base_samplers.int ~size:{min = 1; max = 8} - - let width_function = Micheline_sampler.reasonable_width_function -end) - -module Micheline_nodes_benchmark : Benchmark.S = struct - include Script_repr_shared_config - - let name = "MICHELINE_NODES" - - let info = - "Benchmarking the time it takes to compute the number of nodes of a \ - Micheline term" - - let size_based_model = - Model.make - ~conv:(function {micheline_nodes} -> (micheline_nodes, ())) - ~model: - (Model.affine - ~intercept: - (Free_variable.of_string (Format.asprintf "%s_const" name)) - ~coeff: - (Free_variable.of_string - (Format.asprintf "%s_ns_per_node_coeff" name))) - - let () = - Registration_helpers.register_for_codegen - name - (Model.For_codegen size_based_model) - - let models = [("size_translator_model", size_based_model)] - - let micheline_nodes_benchmark node = - let nodes = Script_repr.micheline_nodes node in - let workload = {micheline_nodes = nodes} in - let closure () = ignore (Script_repr.micheline_nodes node) in - Generator.Plain {workload; closure} - - let make_bench rng_state _cfg () = - let term = Sampler.sample rng_state in - micheline_nodes_benchmark term - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Micheline_nodes_benchmark) - -module Script_repr_strip_annotations : Benchmark.S = struct - include Script_repr_shared_config - - let name = "strip_annotations" - - let info = "Benchmarking Script_repr.strip_annotations" - - let strip_annotations_model = - Model.( - make - ~conv:(fun {micheline_nodes} -> (micheline_nodes, ())) - ~model:(linear ~coeff:(Free_variable.of_string "nodes"))) - - let () = - Registration_helpers.register_for_codegen - name - (Model.For_codegen strip_annotations_model) - - let models = [("strip_annotations_model", strip_annotations_model)] - - let create_benchmark rng_state () = - let node = Sampler.sample rng_state in - let closure () = ignore @@ Script_repr.strip_annotations node in - let micheline_nodes = Script_repr.micheline_nodes node in - Generator.Plain {workload = {micheline_nodes}; closure} - - let create_benchmarks ~rng_state ~bench_num _cfg = - List.repeat bench_num (create_benchmark rng_state) -end - -let () = Registration_helpers.register (module Script_repr_strip_annotations) diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/script_typed_ir_size_benchmarks.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/script_typed_ir_size_benchmarks.ml deleted file mode 100644 index 69995389360c..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/script_typed_ir_size_benchmarks.ml +++ /dev/null @@ -1,338 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** {2 {!Script_typed_ir_size}-related benchmarks} *) - -(** Benchmarking {!Script_typed_ir_size.value_size}. *) - -let model_name = "ir_size_model" - -module Size_benchmarks_shared_config = struct - include Translator_benchmarks.Config - - type workload = {size : int} - - let workload_encoding : workload Data_encoding.t = - let open Data_encoding in - def "size_encoding" - @@ conv (fun {size} -> size) (fun size -> {size}) (obj1 (req "size" int31)) - - let workload_to_vector {size} = - Sparse_vec.String.of_list [("size", float_of_int size)] - - let tags = [Tags.translator] - - let size_based_model name = - let intercept_variable = - Free_variable.of_string (Format.asprintf "%s_const" name) - in - let coeff_variable = - Free_variable.of_string (Format.asprintf "%s_size_coeff" name) - in - Model.make - ~conv:(function {size} -> (size, ())) - ~model:(Model.affine ~intercept:intercept_variable ~coeff:coeff_variable) -end - -module Value_size_benchmark : sig - include Tezos_benchmark.Benchmark.S - - val size_based_model : string -> workload Model.t -end = struct - include Size_benchmarks_shared_config - - let name = "VALUE_SIZE" - - let models = [(model_name, size_based_model name)] - - let info = "Benchmarking Script_typed_ir_size.value_size" - - let value_size_benchmark rng_state (node : Protocol.Script_repr.expr) - (michelson_type : Script_repr.expr) = - (* FIXME: cleanup and factorize this code between translator benches and these ones. *) - let open Translator_benchmarks in - Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - let ex_ty = Type_helpers.michelson_type_to_ex_ty michelson_type ctxt in - match ex_ty with - | Script_ir_translator.Ex_ty ty -> ( - match - Lwt_main.run - (Script_ir_translator.parse_data - ctxt - ~legacy:false - ~allow_forged:false - ty - (Micheline.root node)) - with - | Error _ | (exception _) -> - bad_data name node michelson_type In_protocol - | Ok (value, _) -> - let open Script_typed_ir_size in - let open Cache_memory_helpers in - let size = Nodes.(to_int (fst (value_size ty value))) in - let workload = {size} in - let closure () = ignore (value_size ty value) in - return (Generator.Plain {workload; closure})) ) - |> function - | Ok closure -> closure - | Error errs -> global_error name errs - - let make_bench rng_state cfg () = - let Michelson_mcmc_samplers.{term; typ} = - Michelson_generation.make_data_sampler rng_state cfg.generator_config - in - value_size_benchmark rng_state term typ - - let create_benchmarks ~rng_state ~bench_num config = - match config.michelson_terms_file with - | Some file -> - Format.eprintf "Loading terms from %s@." file ; - let terms = Michelson_mcmc_samplers.load ~filename:file in - List.filter_map - (function - | Michelson_mcmc_samplers.Data {term; typ} -> - Some (fun () -> value_size_benchmark rng_state term typ) - | _ -> None) - terms - | None -> - Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Value_size_benchmark) - -(** Benchmarking {!Script_typed_ir_size.ty_size}. *) - -module Type_size_benchmark : Tezos_benchmark.Benchmark.S = struct - include Size_benchmarks_shared_config - - type config = unit - - let config_encoding = Data_encoding.unit - - let default_config = () - - let name = "TYPE_SIZE" - - let info = - "Benchmarking the time it takes to compute Script_typed_ir_size.ty_size" - - let models = [(model_name, size_based_model name)] - - let type_size_benchmark (Script_ir_translator.Ex_ty ty) = - let open Script_typed_ir_size in - let open Cache_memory_helpers in - let size = Nodes.(to_int (fst (ty_size ty))) in - let workload = {size} in - let closure () = ignore (ty_size ty) in - Generator.Plain {workload; closure} - - let make_bench rng_state _cfg () = - (* The [size] here is a parameter to the random sampler and does not - match the [size] returned by [type_size]. *) - let size = - Base_samplers.sample_in_interval ~range:{min = 1; max = 1000} rng_state - in - let ex_ty = - Michelson_generation.Samplers.Random_type.m_type ~size rng_state - in - type_size_benchmark ex_ty - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Type_size_benchmark) - -(** Benchmarking {!Script_typed_ir_size.comparable_ty_size}. *) - -module Comparable_type_size_benchmark : Tezos_benchmark.Benchmark.S = struct - include Size_benchmarks_shared_config - - let name = "COMPARABLE_TYPE_SIZE" - - let info = - "Benchmarking the time it takes to compute \ - Script_typed_ir_size.comparable_ty_size" - - let models = [(model_name, size_based_model name)] - - let type_size_benchmark (Script_ir_translator.Ex_comparable_ty ty) = - let workload = - let open Script_typed_ir_size in - let open Cache_memory_helpers in - {size = Nodes.to_int @@ fst @@ comparable_ty_size ty} - in - let closure () = ignore (Script_typed_ir_size.comparable_ty_size ty) in - Generator.Plain {workload; closure} - - let make_bench rng_state _cfg () = - (* The [size] here is a parameter to the random sampler and does not - match the [size] returned by [type_size]. *) - let size = - Base_samplers.sample_in_interval ~range:{min = 1; max = 1000} rng_state - in - let ex_ty = - Michelson_generation.Samplers.Random_type.m_comparable_type - ~size - rng_state - in - type_size_benchmark ex_ty - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Comparable_type_size_benchmark) - -(** Benchmarking {!Script_typed_ir_size.kinstr_size}. *) - -module Kinstr_size_benchmark : sig - include Tezos_benchmark.Benchmark.S - - val size_based_model : string -> workload Model.t -end = struct - include Size_benchmarks_shared_config - - let name = "KINSTR_SIZE" - - let models = [(model_name, size_based_model name)] - - let info = "Benchmarking Script_typed_ir_size.kinstr_size" - - let kinstr_size_benchmark rng_state (expr : Protocol.Script_repr.expr) - (stack : Script_repr.expr list) = - (* FIXME: cleanup and factorize this code between translator benches and these ones. *) - let open Translator_benchmarks in - Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - let ex_stack_ty = - Type_helpers.michelson_type_list_to_ex_stack_ty stack ctxt - in - let (Script_ir_translator.Ex_stack_ty bef) = ex_stack_ty in - let node = Micheline.root expr in - match - Lwt_main.run - (Script_ir_translator.parse_instr - Script_ir_translator.Lambda - ctxt - ~legacy:false - node - bef) - with - | Error _ | (exception _) -> bad_code name expr stack In_protocol - | Ok (Failed {descr}, _) -> - let kdescr = Script_ir_translator.close_descr (descr Bot_t) in - let kinstr = kdescr.kinstr in - let workload = - let open Script_typed_ir_size in - let open Cache_memory_helpers in - {size = Nodes.to_int @@ fst @@ kinstr_size kinstr} - in - let closure () = ignore (Script_typed_ir_size.kinstr_size kinstr) in - return (Generator.Plain {workload; closure}) - | Ok (Typed descr, _) -> - let kdescr = Script_ir_translator.close_descr descr in - let kinstr = kdescr.kinstr in - let workload = - let open Script_typed_ir_size in - let open Cache_memory_helpers in - {size = Nodes.to_int @@ fst @@ kinstr_size kinstr} - in - let closure () = ignore (Script_typed_ir_size.kinstr_size kinstr) in - return (Generator.Plain {workload; closure}) ) - |> function - | Ok closure -> closure - | Error errs -> global_error name errs - - let make_bench rng_state cfg () = - let Michelson_mcmc_samplers.{term; bef; aft = _} = - Michelson_generation.make_code_sampler rng_state cfg.generator_config - in - kinstr_size_benchmark rng_state term bef - - let create_benchmarks ~rng_state ~bench_num config = - match config.michelson_terms_file with - | Some file -> - Format.eprintf "Loading terms from %s@." file ; - let terms = Michelson_mcmc_samplers.load ~filename:file in - List.filter_map - (function - | Michelson_mcmc_samplers.Code {term; bef; aft = _} -> - Some (fun () -> kinstr_size_benchmark rng_state term bef) - | _ -> None) - terms - | None -> - Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Kinstr_size_benchmark) - -module Node_size_benchmark : Benchmark.S = struct - include Script_repr_benchmarks.Script_repr_shared_config - - let name = "NODE_SIZE" - - let info = - "Benchmarking the time it takes to compute Script_typed_ir_size.node_size" - - let size_based_model = - Model.make - ~conv:(function {micheline_nodes} -> (micheline_nodes, ())) - ~model: - (Model.affine - ~intercept: - (Free_variable.of_string (Format.asprintf "%s_const" name)) - ~coeff: - (Free_variable.of_string - (Format.asprintf "%s_ns_per_node_coeff" name))) - - let () = - Registration_helpers.register_for_codegen - name - (Model.For_codegen size_based_model) - - let models = [(model_name, size_based_model)] - - let micheline_nodes_benchmark node = - let open Cache_memory_helpers in - let nodes = Nodes.to_int @@ fst @@ node_size node in - let workload = {micheline_nodes = nodes} in - let closure () = ignore (Script_typed_ir_size.node_size node) in - Generator.Plain {workload; closure} - - let make_bench rng_state _cfg () = - let term = Script_repr_benchmarks.Sampler.sample rng_state in - micheline_nodes_benchmark term - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Node_size_benchmark) diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/size.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/size.ml deleted file mode 100644 index 5549702e9aa9..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/size.ml +++ /dev/null @@ -1,206 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -type t = int - -type micheline_size = {traversal : t; int_bytes : t; string_bytes : t} - -(* ------------------------------------------------------------------------- *) -(* encoding *) - -let encoding : t Data_encoding.encoding = - let open Data_encoding in - conv (fun i -> Int64.of_int i) (fun l -> Int64.to_int l) int64 - -let micheline_size_encoding : micheline_size Data_encoding.encoding = - let open Data_encoding in - conv - (fun {traversal; int_bytes; string_bytes} -> - (traversal, int_bytes, string_bytes)) - (fun (traversal, int_bytes, string_bytes) -> - {traversal; int_bytes; string_bytes}) - (tup3 encoding encoding encoding) - -(* ------------------------------------------------------------------------- *) - -let zero = 0 - -let one = 1 - -let add = ( + ) - -let sub = ( - ) - -let mul = ( * ) - -let div = ( / ) - -let max x y = if x < y then y else x - -let min x y = if x < y then x else y - -(* can't be bothered to do it well *) -let rec pow x i = if i = 0 then 1 else x * pow x (i - 1) - -module Ops = struct - let ( * ) = mul - - let ( / ) = div - - let ( + ) = add - - let ( - ) = sub - - let ( ** ) = pow -end - -let compare = Stdlib.compare - -let equal = ( = ) - -let lt = ( < ) - -let leq = ( <= ) - -let pp = Format.pp_print_int - -let pp_micheline_size fmtr {traversal; int_bytes; string_bytes} = - Format.fprintf - fmtr - "@[{ traversal = %a;@; int_bytes = %a;@; string_bytes = %a;@,}@]" - pp - traversal - pp - int_bytes - pp - string_bytes - -let show = string_of_int - -let to_float = float_of_int - -let of_float = int_of_float - -let to_int x = x - -let of_int x = x - -let log2 x = Z.log2 (Z.of_int x) - -let unit : t = 1 - -let integer (i : 'a Alpha_context.Script_int.num) : t = - Z.numbits (Alpha_context.Script_int.to_zint i) / 8 - -let string = String.length - -let script_string = Alpha_context.Script_string.length - -let bytes (b : Bytes.t) : t = Bytes.length b - -let mutez (_tez : Alpha_context.Tez.tez) : t = - (* Up to now, mutez are stored on 8 bytes (int64). *) - 8 - -let bool (_ : bool) : t = 1 - -let signature (_signature : Signature.t) : t = Signature.size - -let key_hash (_keyhash : Signature.public_key_hash) : t = - Signature.Public_key_hash.size - -let public_key (public_key : Signature.public_key) : t = - Signature.Public_key.size public_key - -let chain_id (_chain_id : Chain_id.t) : t = Chain_id.size - -let address (addr : Script_typed_ir.address) : t = - let (_contract, entrypoint) = addr in - Signature.Public_key_hash.size + String.length entrypoint - -let list (list : 'a Script_typed_ir.boxed_list) : t = - list.Script_typed_ir.length - -let set (set : 'a Script_typed_ir.set) : t = - let res = Alpha_context.Script_int.to_int (Script_set.size set) in - match res with None -> assert false | Some x -> x - -let map (map : ('a, 'b) Script_typed_ir.map) : t = - let res = Alpha_context.Script_int.to_int (Script_map.size map) in - match res with None -> assert false | Some x -> x - -let timestamp (tstamp : Alpha_context.Script_timestamp.t) : t = - Z.numbits (Alpha_context.Script_timestamp.to_zint tstamp) / 8 - -(* ------------------------------------------------------------------------- *) -(* Micheline/Michelson-related *) - -let micheline_zero = {traversal = 0; int_bytes = 0; string_bytes = 0} - -let ( ++ ) x y = - { - traversal = Ops.(x.traversal + y.traversal); - int_bytes = Ops.(x.int_bytes + y.int_bytes); - string_bytes = Ops.(x.string_bytes + y.string_bytes); - } - -let node leaves = - let r = List.fold_left ( ++ ) micheline_zero leaves in - {r with traversal = Ops.(r.traversal + 1)} - -let rec of_micheline (x : ('a, 'b) Micheline.node) = - match x with - | Micheline.Int (_loc, z) -> - let int_bytes = integer (Alpha_context.Script_int.of_zint z) in - {traversal = 1; int_bytes; string_bytes = 0} - | Micheline.String (_loc, s) -> - let string_bytes = String.length s in - {traversal = 1; int_bytes = 0; string_bytes} - | Micheline.Bytes (_loc, b) -> - let string_bytes = bytes b in - {traversal = 1; int_bytes = 0; string_bytes} - | Micheline.Prim (_loc, _prim, subterms, _annot) -> - node (List.map of_micheline subterms) - | Micheline.Seq (_loc, subterms) -> node (List.map of_micheline subterms) - -let of_encoded_value : - type a. Alpha_context.t -> a Script_typed_ir.ty -> a -> micheline_size = - fun (type a) ctxt (ty : a Script_typed_ir.ty) (v : a) -> - let open Script_ir_translator in - let script_res = Lwt_main.run (unparse_data ctxt Optimized ty v) in - match script_res with - | Ok (node, _ctxt) -> of_micheline node - | Error _ -> Stdlib.failwith "sizeof: could not unparse" - -(* ------------------------------------------------------------------------- *) -(* Sapling-related *) - -let sapling_transaction_inputs : Alpha_context.Sapling.transaction -> t = - fun tx -> List.length tx.Tezos_sapling.Core.Client.UTXO.inputs - -let sapling_transaction_outputs : Alpha_context.Sapling.transaction -> t = - fun tx -> List.length tx.Tezos_sapling.Core.Client.UTXO.outputs diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/tags.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/tags.ml deleted file mode 100644 index 2748e3551ccd..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/tags.ml +++ /dev/null @@ -1,32 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let interpreter = "interpreter" - -let translator = "translator" - -let encoding = "encoding" - -let cache = "cache" diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/tezos-benchmarks-proto-012-Psithaca.opam b/src/proto_012_Psithaca/lib_benchmarks_proto/tezos-benchmarks-proto-012-Psithaca.opam deleted file mode 100644 index 214f6bb63358..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/tezos-benchmarks-proto-012-Psithaca.opam +++ /dev/null @@ -1,28 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "tezos-tooling" { with-test } - "dune" { >= "2.9" } - "tezos-base" - "tezos-benchmark" - "tezos-benchmark-012-Psithaca" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-protocol-012-Psithaca-parameters" - "tezos-shell-benchmarks" - "tezos-micheline" - "tezos-012-Psithaca-test-helpers" - "tezos-sapling" - "tezos-client-012-Psithaca" - -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol benchmarks" diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/translator_benchmarks.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/translator_benchmarks.ml deleted file mode 100644 index e4a3da4cc86a..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/translator_benchmarks.ml +++ /dev/null @@ -1,854 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** {2 [Script_ir_translator] benchmarks} *) - -module Config = struct - type config = { - generator_config : Michelson_generation.generator_config; - michelson_terms_file : string option; - } - - let default_config = - { - generator_config = Michelson_generation.default_generator_config; - michelson_terms_file = None; - } - - let config_encoding = - let open Data_encoding in - conv - (fun {generator_config; michelson_terms_file} -> - (generator_config, michelson_terms_file)) - (fun (generator_config, michelson_terms_file) -> - {generator_config; michelson_terms_file}) - (obj2 - (req "generator_config" Michelson_generation.generator_config_encoding) - (opt "michelson_terms_file" string)) -end - -module Default_boilerplate = struct - type workload = Translator_workload.t - - let workload_encoding = Translator_workload.encoding - - let workload_to_vector = Translator_workload.workload_to_sparse_vec - - let tags = [Tags.translator] - - let make_models t_kind code_or_data = - [ - ( "gas_translator_model", - Translator_model.gas_based_model t_kind code_or_data ); - ( "size_translator_model", - Translator_model.size_based_model t_kind code_or_data ); - ] -end - -(* ----------------------------------------------------------------------- *) -(* Error handling *) - -type phase = Workload_production | In_protocol | Global - -type error_kind = - | Global_error of { - benchmark_name : string; - workload : Tezos_base.TzPervasives.tztrace; - } - | Bad_data of { - benchmark_name : string; - micheline : Alpha_context.Script.expr; - expected_type : Alpha_context.Script.expr; - phase : phase; - } - | Bad_code of { - benchmark_name : string; - micheline : Alpha_context.Script.expr; - expected_stack_type : Alpha_context.Script.expr list; - phase : phase; - } - -let pp_phase fmtr (phase : phase) = - match phase with - | Workload_production -> Format.fprintf fmtr "workload production" - | In_protocol -> Format.fprintf fmtr "in protocol" - | Global -> Format.fprintf fmtr "global" - -let report_michelson_errors fmtr errs = - Michelson_v1_error_reporter.report_errors - ~details:true - ~show_source:true - fmtr - errs - -let make_printable node = - Micheline_printer.printable Michelson_v1_primitives.string_of_prim node - -let pp_error_kind fmtr (error_kind : error_kind) = - match error_kind with - | Global_error {benchmark_name; workload} -> - Format.open_vbox 1 ; - Format.fprintf fmtr "Global error:@," ; - Format.fprintf fmtr "benchmark = %s@," benchmark_name ; - Format.fprintf fmtr "workload:@," ; - report_michelson_errors fmtr workload ; - Format.close_box () - | Bad_data {benchmark_name; micheline; expected_type; phase} -> - Format.open_vbox 1 ; - Format.fprintf fmtr "Bad data:@," ; - Format.fprintf fmtr "benchmark = %s@," benchmark_name ; - Format.fprintf - fmtr - "expression = @[%a@]@," - Micheline_printer.print_expr - (make_printable micheline) ; - Format.fprintf - fmtr - "expected type = @[%a@]@," - Micheline_printer.print_expr - (make_printable expected_type) ; - Format.fprintf fmtr "phase = %a@," pp_phase phase ; - Format.close_box () - | Bad_code {benchmark_name; micheline; expected_stack_type; phase} -> - Format.open_vbox 1 ; - Format.fprintf fmtr "Bad code:@," ; - Format.fprintf fmtr "benchmark = %s@," benchmark_name ; - Format.fprintf - fmtr - "expression = @[%a@]@," - Micheline_printer.print_expr - (make_printable micheline) ; - Format.fprintf - fmtr - "expected stack = @[%a@]@," - (Format.pp_print_list - ~pp_sep:(fun fmtr () -> Format.fprintf fmtr "::") - (fun fmtr node -> - let printable = make_printable node in - Format.fprintf fmtr "%a" Micheline_printer.print_expr printable)) - expected_stack_type ; - Format.fprintf fmtr "phase = %a@," pp_phase phase ; - Format.close_box () - -exception Translator_benchmark_error of error_kind - -let () = - Printexc.register_printer (function - | Translator_benchmark_error err -> - Some (Format.asprintf "%a" pp_error_kind err) - | _ -> None) - -let global_error benchmark_name workload = - raise (Translator_benchmark_error (Global_error {benchmark_name; workload})) - -let bad_data benchmark_name micheline expected_type phase = - raise - (Translator_benchmark_error - (Bad_data {benchmark_name; micheline; expected_type; phase})) - -let bad_code benchmark_name micheline expected_stack_type phase = - raise - (Translator_benchmark_error - (Bad_code {benchmark_name; micheline; expected_stack_type; phase})) - -(* ----------------------------------------------------------------------- *) -(* Typechecking data (Micheline data -> typed data) *) - -module Typechecking_data : Benchmark.S = struct - include Config - include Default_boilerplate - - let models = make_models Translator_workload.Parsing Translator_workload.Data - - let name = "TYPECHECKING_DATA" - - let info = "Benchmarking typechecking of data" - - let typechecking_data_benchmark rng_state (node : Protocol.Script_repr.expr) - (michelson_type : Script_repr.expr) = - Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - let ex_ty = Type_helpers.michelson_type_to_ex_ty michelson_type ctxt in - let workload = - match - Translator_workload.data_typechecker_workload - ctxt - Translator_workload.Parsing - (Micheline.root node) - ex_ty - with - | None -> bad_data name node michelson_type Workload_production - | Some workload -> workload - in - match ex_ty with - | Script_ir_translator.Ex_ty ty -> - let closure () = - match - Lwt_main.run - (Script_ir_translator.parse_data - ctxt - ~legacy:false - ~allow_forged:false - ty - (Micheline.root node)) - with - | Error _ | (exception _) -> - bad_data name node michelson_type In_protocol - | Ok _ -> () - in - return (Generator.Plain {workload; closure}) ) - |> function - | Ok closure -> closure - | Error errs -> global_error name errs - - let make_bench rng_state cfg () = - let Michelson_mcmc_samplers.{term; typ} = - Michelson_generation.make_data_sampler rng_state cfg.generator_config - in - typechecking_data_benchmark rng_state term typ - - let create_benchmarks ~rng_state ~bench_num config = - match config.michelson_terms_file with - | Some file -> - Format.eprintf "Loading terms from %s@." file ; - let terms = Michelson_mcmc_samplers.load ~filename:file in - List.filter_map - (function - | Michelson_mcmc_samplers.Data {term; typ} -> - Some (fun () -> typechecking_data_benchmark rng_state term typ) - | _ -> None) - terms - | None -> - Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Typechecking_data) - -module Unparsing_data : Benchmark.S = struct - include Config - include Default_boilerplate - - let models = - make_models Translator_workload.Unparsing Translator_workload.Data - - let name = "UNPARSING_DATA" - - let info = "Benchmarking unparsing of data" - - let unparsing_data_benchmark rng_state (node : Protocol.Script_repr.expr) - (michelson_type : Protocol.Script_repr.expr) = - Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - let ex_ty = Type_helpers.michelson_type_to_ex_ty michelson_type ctxt in - let workload = - match - Translator_workload.data_typechecker_workload - ctxt - Translator_workload.Unparsing - (Micheline.root node) - ex_ty - with - | None -> bad_data name node michelson_type Workload_production - | Some workload -> workload - in - match ex_ty with - | Script_ir_translator.Ex_ty ty -> - Script_ir_translator.parse_data - ctxt - ~legacy:false - ~allow_forged:false - ty - (Micheline.root node) - >|= Environment.wrap_tzresult - >>=? fun (typed, ctxt) -> - let closure () = - match - Lwt_main.run - (Script_ir_translator.unparse_data - ctxt - Script_ir_translator.Optimized - ty - typed) - with - | Error _ | (exception _) -> - bad_data name node michelson_type In_protocol - | Ok _ -> () - in - return (Generator.Plain {workload; closure}) ) - |> function - | Ok closure -> closure - | Error errs -> global_error name errs - - let make_bench rng_state cfg () = - let Michelson_mcmc_samplers.{term; typ} = - Michelson_generation.make_data_sampler rng_state cfg.generator_config - in - unparsing_data_benchmark rng_state term typ - - let create_benchmarks ~rng_state ~bench_num config = - match config.michelson_terms_file with - | Some file -> - Format.eprintf "Loading terms from %s@." file ; - let terms = Michelson_mcmc_samplers.load ~filename:file in - List.filter_map - (function - | Michelson_mcmc_samplers.Data {term; typ} -> - Some (fun () -> unparsing_data_benchmark rng_state term typ) - | _ -> None) - terms - | None -> - Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Unparsing_data) - -module Typechecking_code : Benchmark.S = struct - include Config - include Default_boilerplate - - let models = make_models Translator_workload.Parsing Translator_workload.Code - - let name = "TYPECHECKING_CODE" - - let info = "Benchmarking typechecking of code" - - let typechecking_code_benchmark rng_state (node : Protocol.Script_repr.expr) - (stack : Script_repr.expr list) = - Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - let ex_stack_ty = - Type_helpers.michelson_type_list_to_ex_stack_ty stack ctxt - in - let workload = - match - Translator_workload.code_typechecker_workload - ctxt - Translator_workload.Parsing - (Micheline.root node) - ex_stack_ty - with - | None -> bad_code name node stack Workload_production - | Some workload -> workload - in - let (Script_ir_translator.Ex_stack_ty bef) = ex_stack_ty in - let closure () = - let result = - Lwt_main.run - (Script_ir_translator.parse_instr - Script_ir_translator.Lambda - ctxt - ~legacy:false - (Micheline.root node) - bef) - in - match Environment.wrap_tzresult result with - | Error errs -> - Format.eprintf "%a@." Error_monad.pp_print_trace errs ; - bad_code name node stack In_protocol - | Ok _ -> () - in - return (Generator.Plain {workload; closure}) ) - |> function - | Ok closure -> closure - | Error errs -> global_error name errs - - let make_bench rng_state (cfg : Config.config) () = - let open Michelson_generation in - let Michelson_mcmc_samplers.{term; bef; aft = _} = - make_code_sampler rng_state cfg.generator_config - in - typechecking_code_benchmark rng_state term bef - - let create_benchmarks ~rng_state ~bench_num config = - match config.michelson_terms_file with - | Some file -> - Format.eprintf "Loading terms from %s@." file ; - let terms = Michelson_mcmc_samplers.load ~filename:file in - List.filter_map - (function - | Michelson_mcmc_samplers.Code {term; bef; aft = _} -> - Some (fun () -> typechecking_code_benchmark rng_state term bef) - | _ -> None) - terms - | None -> - Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Typechecking_code) - -module Unparsing_code : Benchmark.S = struct - include Config - include Default_boilerplate - - let models = - make_models Translator_workload.Unparsing Translator_workload.Code - - let name = "UNPARSING_CODE" - - let info = "Benchmarking unparsing of code" - - let unparsing_code_benchmark rng_state (node : Protocol.Script_repr.expr) - (stack : Script_repr.expr list) = - Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - let ex_stack_ty = - Type_helpers.michelson_type_list_to_ex_stack_ty stack ctxt - in - let workload = - match - Translator_workload.code_typechecker_workload - ctxt - Translator_workload.Unparsing - (Micheline.root node) - ex_stack_ty - with - | None -> bad_code name node stack Workload_production - | Some workload -> workload - in - let (Script_ir_translator.Ex_stack_ty bef) = ex_stack_ty in - (* We parse the code just to check it is well-typed. *) - Script_ir_translator.parse_instr - Script_ir_translator.Lambda - ctxt - ~legacy:false - (Micheline.root node) - bef - >|= Environment.wrap_tzresult - >>=? fun (_typed, ctxt) -> - let closure () = - let result = - Lwt_main.run - (Script_ir_translator.unparse_code - ctxt - Optimized - (Micheline.root node)) - in - match Environment.wrap_tzresult result with - | Error errs -> - Format.eprintf "%a@." Error_monad.pp_print_trace errs ; - bad_code name node stack In_protocol - | Ok _ -> () - in - return (Generator.Plain {workload; closure}) ) - |> function - | Ok closure -> closure - | Error errs -> global_error name errs - - let make_bench rng_state (cfg : Config.config) () = - let open Michelson_generation in - let Michelson_mcmc_samplers.{term; bef; aft = _} = - make_code_sampler rng_state cfg.generator_config - in - unparsing_code_benchmark rng_state term bef - - let create_benchmarks ~rng_state ~bench_num config = - match config.michelson_terms_file with - | Some file -> - Format.eprintf "Loading terms from %s@." file ; - let terms = Michelson_mcmc_samplers.load ~filename:file in - List.filter_map - (function - | Michelson_mcmc_samplers.Code {term; bef; aft = _} -> - Some (fun () -> unparsing_code_benchmark rng_state term bef) - | _ -> None) - terms - | None -> List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Unparsing_code) - -let rec check_printable_ascii v i = - if Compare.Int.(i < 0) then true - else - match v.[i] with - | '\n' | '\x20' .. '\x7E' -> check_printable_ascii v (i - 1) - | _ -> false - -let check_printable_benchmark = - let open Tezos_shell_benchmarks.Encoding_benchmarks_helpers in - linear_shared - ~name:"CHECK_PRINTABLE" - ~generator:(fun rng_state -> - let open Base_samplers in - let string = - readable_ascii_string rng_state ~size:{min = 1; max = 1024} - in - (string, {Shared_linear.bytes = String.length string})) - ~make_bench:(fun generator () -> - let (generated, workload) = generator () in - let closure () = - ignore (check_printable_ascii generated (String.length generated - 1)) - in - Generator.Plain {workload; closure}) - -let () = Registration_helpers.register check_printable_benchmark - -module Merge_types : Benchmark.S = struct - type config = {max_size : int} - - let config_encoding = - let open Data_encoding in - conv - (fun {max_size} -> max_size) - (fun max_size -> {max_size}) - (obj1 (req "max_size" int31)) - - let default_config = {max_size = 64} - - type workload = Merge_types_workload of {nodes : int; consumed : Size.t} - - let workload_encoding = - let open Data_encoding in - conv - (function Merge_types_workload {nodes; consumed} -> (nodes, consumed)) - (fun (nodes, consumed) -> Merge_types_workload {nodes; consumed}) - (obj2 (req "nodes" int31) (req "consumed" int31)) - - let workload_to_vector = function - | Merge_types_workload {nodes; consumed} -> - Sparse_vec.String.of_list - [("nodes", float_of_int nodes); ("consumed", float_of_int consumed)] - - let name = "MERGE_TYPES" - - let info = "Benchmarking merging of types" - - let tags = [Tags.translator] - - let intercept_var = Free_variable.of_string (Format.asprintf "%s_const" name) - - let coeff_var = Free_variable.of_string (Format.asprintf "%s_coeff" name) - - let size_model = - Model.make - ~conv:(function Merge_types_workload {nodes; _} -> (nodes, ())) - ~model: - (Model.affine_split_const - ~intercept1:Builtin_benchmarks.timer_variable - ~intercept2:intercept_var - ~coeff:coeff_var) - - let codegen_model = - Model.make - ~conv:(function Merge_types_workload {nodes; _} -> (nodes, ())) - ~model:(Model.affine ~intercept:intercept_var ~coeff:coeff_var) - - let () = - Registration_helpers.register_for_codegen - name - (Model.For_codegen codegen_model) - - let models = - [("size_translator_model", size_model); ("codegen", codegen_model)] - - let merge_type_benchmark rng_state nodes (ty : Script_ir_translator.ex_ty) = - let open Error_monad in - Lwt_main.run - ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> - let ctxt = Gas_helpers.set_limit ctxt in - match ty with - | Ex_ty ty -> - let dummy_loc = 0 in - Lwt.return (Script_ir_translator.ty_eq ctxt dummy_loc ty ty) - >|= Environment.wrap_tzresult - >>=? fun (_, ctxt') -> - let consumed = - Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt' - in - let workload = - Merge_types_workload - {nodes; consumed = Z.to_int (Gas_helpers.fp_to_z consumed)} - in - let closure () = ignore (Script_ir_translator.ty_eq ctxt 0 ty ty) in - return (Generator.Plain {workload; closure}) ) - |> function - | Ok closure -> closure - | Error errs -> global_error name errs - - let make_bench rng_state (cfg : config) () = - let nodes = - Base_samplers.( - sample_in_interval ~range:{min = 1; max = cfg.max_size} rng_state) - in - let ty = - Michelson_generation.Samplers.Random_type.m_type ~size:nodes rng_state - in - merge_type_benchmark rng_state nodes ty - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Merge_types) - -(* A dummy type generator, sampling linear terms of a given size. - The generator always returns types of the shape: - - [pair unit (pair unit (pair unit ...))] - - This structure is the worse-case of the unparsing function for types because - an extra test is performed to determine if the comb type needs to be folded. - *) -let rec dummy_type_generator size = - let open Script_ir_translator in - let open Script_typed_ir in - if size <= 1 then Ex_ty (unit_t ~annot:None) - else - match dummy_type_generator (size - 2) with - | Ex_ty r -> - let l = unit_t ~annot:None in - Ex_ty - (match pair_t (-1) (l, None, None) (r, None, None) ~annot:None with - | Error _ -> assert false - | Ok t -> t) - -(* A dummy comparable type generator, sampling linear terms of a given size. *) -let rec dummy_comparable_type_generator size = - let open Script_ir_translator in - let open Script_typed_ir in - if size <= 0 then Ex_comparable_ty (unit_key ~annot:None) - else - match dummy_comparable_type_generator (size - 2) with - | Ex_comparable_ty r -> - let l = unit_key ~annot:None in - Ex_comparable_ty - (match pair_key (-1) (l, None) (r, None) ~annot:None with - | Error _ -> assert false - | Ok t -> t) - -module Parse_type_shared = struct - type config = {max_size : int} - - let default_config = {max_size = Constants_repr.michelson_maximum_type_size} - - let config_encoding = - let open Data_encoding in - conv - (fun {max_size} -> max_size) - (fun max_size -> {max_size}) - (obj1 (req "max_size" int31)) - - type workload = Type_workload of {nodes : int; consumed : Size.t} - - let workload_encoding = - let open Data_encoding in - conv - (function Type_workload {nodes; consumed} -> (nodes, consumed)) - (fun (nodes, consumed) -> Type_workload {nodes; consumed}) - (obj2 (req "nodes" int31) (req "consumed" int31)) - - let workload_to_vector = function - | Type_workload {nodes; consumed} -> - Sparse_vec.String.of_list - [("nodes", float_of_int nodes); ("consumed", float_of_int consumed)] - - let tags = [Tags.translator] -end - -let parse_ty ctxt node = - Script_ir_translator.parse_ty - ctxt - ~legacy:true - ~allow_lazy_storage:true - ~allow_operation:true - ~allow_contract:true - ~allow_ticket:true - node - -let unparse_ty ctxt ty = Script_ir_translator.unparse_ty ~loc:(-1) ctxt ty - -module Parse_type_benchmark : Benchmark.S = struct - include Parse_type_shared - - let name = "PARSE_TYPE" - - let info = "Benchmarking parse_ty" - - let make_bench rng_state config () = - let open Error_monad in - ( Lwt_main.run (Execution_context.make ~rng_state) >>? fun (ctxt, _) -> - let ctxt = Gas_helpers.set_limit ctxt in - let size = Random.State.int rng_state config.max_size in - let ty = dummy_type_generator size in - match ty with - | Ex_ty ty -> - Environment.wrap_tzresult @@ unparse_ty ctxt ty - >>? fun (unparsed, _) -> - Environment.wrap_tzresult @@ parse_ty ctxt unparsed - >>? fun (_, ctxt') -> - let consumed = - Z.to_int - (Gas_helpers.fp_to_z - (Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt')) - in - let nodes = - let x = Script_typed_ir.ty_size ty in - Saturation_repr.to_int @@ Script_typed_ir.Type_size.to_int x - in - let workload = Type_workload {nodes; consumed} in - let closure () = ignore (parse_ty ctxt unparsed) in - ok (Generator.Plain {workload; closure}) ) - |> function - | Ok closure -> closure - | Error errs -> global_error name errs - - let size_model = - Model.make - ~conv:(function Type_workload {nodes; consumed = _} -> (nodes, ())) - ~model: - (Model.affine - ~intercept: - (Free_variable.of_string (Format.asprintf "%s_const" name)) - ~coeff:(Free_variable.of_string (Format.asprintf "%s_coeff" name))) - - let models = [("size_translator_model", size_model)] - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (make_bench rng_state config) -end - -let () = Registration_helpers.register (module Parse_type_benchmark) - -module Unparse_type_benchmark : Benchmark.S = struct - include Parse_type_shared - - let name = "UNPARSE_TYPE" - - let info = "Benchmarking unparse_ty" - - let make_bench rng_state config () = - let open Error_monad in - ( Lwt_main.run (Execution_context.make ~rng_state) >>? fun (ctxt, _) -> - let ctxt = Gas_helpers.set_limit ctxt in - let size = Random.State.int rng_state config.max_size in - let ty = dummy_type_generator size in - match ty with - | Ex_ty ty -> - Environment.wrap_tzresult @@ unparse_ty ctxt ty >>? fun (_, ctxt') -> - let consumed = - Z.to_int - (Gas_helpers.fp_to_z - (Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt')) - in - let nodes = - let x = Script_typed_ir.ty_size ty in - Saturation_repr.to_int @@ Script_typed_ir.Type_size.to_int x - in - let workload = Type_workload {nodes; consumed} in - let closure () = ignore (unparse_ty ctxt ty) in - ok (Generator.Plain {workload; closure}) ) - |> function - | Ok closure -> closure - | Error errs -> global_error name errs - - let size_model = - Model.make - ~conv:(function Type_workload {nodes; consumed = _} -> (nodes, ())) - ~model: - (Model.affine - ~intercept: - (Free_variable.of_string (Format.asprintf "%s_const" name)) - ~coeff:(Free_variable.of_string (Format.asprintf "%s_coeff" name))) - - let models = [("size_translator_model", size_model)] - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (make_bench rng_state config) - - let () = - Registration_helpers.register_for_codegen - name - (Model.For_codegen size_model) -end - -let () = Registration_helpers.register (module Unparse_type_benchmark) - -module Unparse_comparable_type_benchmark : Benchmark.S = struct - include Parse_type_shared - - let name = "UNPARSE_COMPARABLE_TYPE" - - let info = "Benchmarking unparse_comparable_ty" - - let make_bench rng_state config () = - let open Error_monad in - let res = - Lwt_main.run (Execution_context.make ~rng_state) >>? fun (ctxt, _) -> - let ctxt = Gas_helpers.set_limit ctxt in - let size = Random.State.int rng_state config.max_size in - let ty = dummy_comparable_type_generator size in - let nodes = - let (Script_ir_translator.Ex_comparable_ty ty) = ty in - let x = Script_typed_ir.comparable_ty_size ty in - Saturation_repr.to_int @@ Script_typed_ir.Type_size.to_int x - in - match ty with - | Ex_comparable_ty comp_ty -> - Environment.wrap_tzresult - @@ Script_ir_translator.unparse_comparable_ty ~loc:() ctxt comp_ty - >>? fun (_, ctxt') -> - let consumed = - Z.to_int - (Gas_helpers.fp_to_z - (Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt')) - in - let workload = Type_workload {nodes; consumed} in - let closure () = - ignore - (Script_ir_translator.unparse_comparable_ty ~loc:() ctxt comp_ty) - in - ok (Generator.Plain {workload; closure}) - in - match res with - | Ok closure -> closure - | Error errs -> global_error name errs - - let size_model = - Model.make - ~conv:(function Type_workload {nodes; consumed = _} -> (nodes, ())) - ~model: - (Model.affine - ~intercept: - (Free_variable.of_string (Format.asprintf "%s_const" name)) - ~coeff:(Free_variable.of_string (Format.asprintf "%s_coeff" name))) - - let () = - Registration_helpers.register_for_codegen - name - (Model.For_codegen size_model) - - let models = [("size_translator_model", size_model)] - - let create_benchmarks ~rng_state ~bench_num config = - List.repeat bench_num (make_bench rng_state config) -end - -let () = - Registration_helpers.register (module Unparse_comparable_type_benchmark) diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/translator_model.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/translator_model.ml deleted file mode 100644 index 0bcf6c3b8a20..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/translator_model.ml +++ /dev/null @@ -1,68 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let gas_full t_kind code_or_data = - let name = - Format.asprintf - "%a_%a" - Translator_workload.pp_kind - t_kind - Translator_workload.pp_code_or_data - code_or_data - in - let intercept = Free_variable.of_string (Format.asprintf "%s_const" name) in - let coeff = Free_variable.of_string (Format.asprintf "%s_coeff" name) in - Model.affine ~intercept ~coeff - -let size_full t_kind code_or_data = - let name = - Format.asprintf - "%a_%a" - Translator_workload.pp_kind - t_kind - Translator_workload.pp_code_or_data - code_or_data - in - let coeff1 = Free_variable.of_string (Format.asprintf "%s_traversal" name) in - let coeff2 = Free_variable.of_string (Format.asprintf "%s_int_bytes" name) in - let coeff3 = - Free_variable.of_string (Format.asprintf "%s_string_bytes" name) - in - Model.trilinear ~coeff1 ~coeff2 ~coeff3 - -let gas_based_model t_kind code_or_data = - Model.make - ~conv:(function - | Translator_workload.Typechecker_workload {consumed; _} -> (consumed, ())) - ~model:(gas_full t_kind code_or_data) - -let size_based_model t_kind code_or_data = - Model.make - ~conv:(function - | Translator_workload.Typechecker_workload {micheline_size; _} -> ( - match micheline_size with - | {traversal; int_bytes; string_bytes} -> - (traversal, (int_bytes, (string_bytes, ()))))) - ~model:(size_full t_kind code_or_data) diff --git a/src/proto_012_Psithaca/lib_benchmarks_proto/translator_workload.ml b/src/proto_012_Psithaca/lib_benchmarks_proto/translator_workload.ml deleted file mode 100644 index 1ba338327374..000000000000 --- a/src/proto_012_Psithaca/lib_benchmarks_proto/translator_workload.ml +++ /dev/null @@ -1,186 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type kind = Parsing | Unparsing - -type code_or_data = Code | Data - -type t = - | Typechecker_workload of { - t_kind : kind; - code_or_data : code_or_data; - micheline_size : Size.micheline_size; - consumed : Size.t; - } - -let kind_encoding : kind Data_encoding.t = - let open Data_encoding in - def "kind_encoding" - @@ string_enum [("parsing", Parsing); ("unparsing", Unparsing)] - -let code_or_data_encoding : code_or_data Data_encoding.t = - let open Data_encoding in - def "code_or_data_encoding" @@ string_enum [("code", Code); ("data", Data)] - -let encoding : t Data_encoding.t = - let open Data_encoding in - def "translator_trace_encoding" - @@ conv - (function - | Typechecker_workload {t_kind; code_or_data; micheline_size; consumed} - -> - (t_kind, code_or_data, micheline_size, consumed)) - (fun (t_kind, code_or_data, micheline_size, consumed) -> - Typechecker_workload {t_kind; code_or_data; micheline_size; consumed}) - (tup4 - kind_encoding - code_or_data_encoding - Size.micheline_size_encoding - Size.encoding) - -let pp_kind fmtr (kind : kind) = - match kind with - | Parsing -> Format.pp_print_string fmtr "Parsing" - | Unparsing -> Format.pp_print_string fmtr "Unparsing" - -let pp_code_or_data fmtr (x : code_or_data) = - match x with - | Code -> Format.pp_print_string fmtr "Code" - | Data -> Format.pp_print_string fmtr "Data" - -let pp fmtr (trace : t) = - match trace with - | Typechecker_workload {t_kind; code_or_data; micheline_size; consumed} -> - Format.fprintf - fmtr - "typechecker_trace { %a; %a; %a; %a }" - pp_kind - t_kind - pp_code_or_data - code_or_data - Size.pp_micheline_size - micheline_size - Size.pp - consumed - -let workload_to_sparse_vec (trace : t) = - let (name, {Size.traversal; int_bytes; string_bytes}, consumed) = - match trace with - | Typechecker_workload {t_kind; code_or_data; micheline_size; consumed} -> - let name = - Format.asprintf "%a_%a" pp_kind t_kind pp_code_or_data code_or_data - in - (name, micheline_size, consumed) - in - let n s = name ^ "_" ^ s in - let vars = - [ - (n "traversal", Size.to_float traversal); - (n "int_bytes", Size.to_float int_bytes); - (n "string_bytes", Size.to_float string_bytes); - (n "gas", Size.to_float consumed); - ] - in - Sparse_vec.String.of_list vars - -let data_typechecker_workload ctxt t_kind micheline_node ex_ty = - let open Protocol in - match ex_ty with - | Script_ir_translator.Ex_ty ty -> - let ctxt = Gas_helpers.set_limit ctxt in - Lwt_main.run - ( Script_ir_translator.parse_data - ctxt - ~legacy:false - ~allow_forged:false - ty - micheline_node - |> Lwt.map Environment.wrap_tzresult - >>= fun res -> - match res with - | Ok (_res, ctxt_after) -> - let micheline_size = Size.of_micheline micheline_node in - let consumed = - Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt_after - in - let trace = - Typechecker_workload - { - t_kind; - code_or_data = Data; - micheline_size; - consumed = - Size.of_int (Z.to_int (Gas_helpers.fp_to_z consumed)); - } - in - Lwt.return (Some trace) - | Error errors -> - Michelson_v1_error_reporter.report_errors - ~details:true - ~show_source:true - Format.err_formatter - errors ; - Format.eprintf "@." ; - Lwt.return None ) - -let code_typechecker_workload (ctxt : Protocol.Alpha_context.context) - (t_kind : kind) (code : Protocol.Alpha_context.Script.node) - (bef : Protocol.Script_ir_translator.ex_stack_ty) = - let open Protocol in - let ctxt = Gas_helpers.set_limit ctxt in - let (Script_ir_translator.Ex_stack_ty stack_ty) = bef in - Lwt_main.run - ( Script_ir_translator.parse_instr - Script_ir_translator.Lambda - ctxt - ~legacy:false - code - stack_ty - |> Lwt.map Environment.wrap_tzresult - >>= fun res -> - match res with - | Ok (_res, ctxt_after) -> - let micheline_size = Size.of_micheline code in - let consumed = - Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt_after - in - let trace = - Typechecker_workload - { - t_kind; - code_or_data = Code; - micheline_size; - consumed = Size.of_int (Z.to_int (Gas_helpers.fp_to_z consumed)); - } - in - Lwt.return (Some trace) - | Error errs -> - Michelson_v1_error_reporter.report_errors - ~details:true - ~show_source:true - Format.err_formatter - errs ; - Format.eprintf "@." ; - Lwt.return None ) diff --git a/src/proto_012_Psithaca/lib_client/.ocamlformat b/src/proto_012_Psithaca/lib_client/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_client/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_client/annotated_manager_operation.ml b/src/proto_012_Psithaca/lib_client/annotated_manager_operation.ml deleted file mode 100644 index 96ce163f5295..000000000000 --- a/src/proto_012_Psithaca/lib_client/annotated_manager_operation.ml +++ /dev/null @@ -1,123 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2018-2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type _ t = - | Manager_info : { - source : Alpha_context.public_key_hash option; - fee : Tez.t Limit.t; - gas_limit : Gas.Arith.integral Limit.t; - storage_limit : Z.t Limit.t; - counter : Z.t option; - operation : 'kind manager_operation; - } - -> 'kind t - -type packed = Annotated_manager_operation : 'kind t -> packed - -type _ annotated_list = - | Single_manager : 'kind t -> 'kind annotated_list - | Cons_manager : - 'kind t * 'rest annotated_list - -> ('kind * 'rest) annotated_list - -type packed_annotated_list = - | Manager_list : 'kind annotated_list -> packed_annotated_list - -let rec manager_to_list = function - | Manager_list (Single_manager o) -> [Annotated_manager_operation o] - | Manager_list (Cons_manager (o, os)) -> - Annotated_manager_operation o :: manager_to_list (Manager_list os) - -let rec manager_of_list = function - | [] -> assert false - | [Annotated_manager_operation o] -> Manager_list (Single_manager o) - | Annotated_manager_operation o :: os -> - let (Manager_list os) = manager_of_list os in - Manager_list (Cons_manager (o, os)) - -let join_fee fee operation = - let (Manager_info c) = operation in - Limit.join ~where:__LOC__ Tez.equal fee c.fee >|? fun fee -> - Manager_info {c with fee} - -let set_fee fee (Manager_info c) = Manager_info {c with fee} - -let join_gas_limit gas_limit operation = - let (Manager_info c) = operation in - Limit.join ~where:__LOC__ Gas.Arith.equal gas_limit c.gas_limit - >|? fun gas_limit -> Manager_info {c with gas_limit} - -let set_gas_limit gas_limit (Manager_info c) = Manager_info {c with gas_limit} - -let join_storage_limit storage_limit (Manager_info c) = - Limit.join ~where:__LOC__ Z.equal storage_limit c.storage_limit - >|? fun storage_limit -> Manager_info {c with storage_limit} - -let set_storage_limit storage_limit (Manager_info c) = - Manager_info {c with storage_limit} - -let set_counter counter (Manager_info c) = - match c.counter with - | Some _ -> error_with "set_counter_annot: already set" - | None -> ok (Manager_info {c with counter = Some counter}) - -let set_source source (Manager_info c) = - match c.source with - | Some _ -> error_with "set_source_annot: already set" - | None -> ok (Manager_info {c with source = Some source}) - -let manager_from_annotated operation = - let (Manager_info {source; fee; gas_limit; storage_limit; counter; operation}) - = - operation - in - Limit.get ~when_unknown:"unknown fee" fee >>? fun fee -> - Limit.get ~when_unknown:"unknown gas limit" gas_limit >>? fun gas_limit -> - Limit.get ~when_unknown:"unknown storage limit" storage_limit - >>? fun storage_limit -> - Option.fold - ~some:ok - ~none:(error_with "manager_from_annotated: source not set") - source - >>? fun source -> - Option.fold - ~some:ok - ~none:(error_with "manager_from_annotated: counter not set") - counter - >|? fun counter -> - Manager_operation {source; fee; counter; gas_limit; storage_limit; operation} - -let rec manager_list_from_annotated : - type kind. kind annotated_list -> kind Kind.manager contents_list tzresult = - function - | Single_manager operation -> - manager_from_annotated operation >|? fun op -> Single op - | Cons_manager (operation, rest) -> - manager_list_from_annotated rest >>? fun rest -> - manager_from_annotated operation >|? fun op -> Cons (op, rest) diff --git a/src/proto_012_Psithaca/lib_client/annotated_manager_operation.mli b/src/proto_012_Psithaca/lib_client/annotated_manager_operation.mli deleted file mode 100644 index 4eebe07b7a59..000000000000 --- a/src/proto_012_Psithaca/lib_client/annotated_manager_operation.mli +++ /dev/null @@ -1,98 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2018 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Annotated manager operations are wrappers used to accumulate information - (especially about limits) on the operation prior to the injection. *) - -open Protocol -open Alpha_context - -type _ t = - | Manager_info : { - source : Alpha_context.public_key_hash option; - fee : Tez.t Limit.t; - gas_limit : Gas.Arith.integral Limit.t; - storage_limit : Z.t Limit.t; - counter : Z.t option; - operation : 'kind manager_operation; - } - -> 'kind t - -type packed = Annotated_manager_operation : 'kind t -> packed - -(** The [annotated_list] type helps making - [contents_list] from a list of [manager_operation]s. - Its construction mimics [contents_list] in order to keep - consistent types when calling [inject_manager_operation] - and [inject_operation].*) -type _ annotated_list = - | Single_manager : 'kind t -> 'kind annotated_list - | Cons_manager : - 'kind t * 'rest annotated_list - -> ('kind * 'rest) annotated_list - -type packed_annotated_list = - | Manager_list : 'kind annotated_list -> packed_annotated_list - -(** Convert a list of annotated operations to a list of packed annotated - operations *) -val manager_to_list : packed_annotated_list -> packed list - -(** Converse of [manager_to_list] *) -val manager_of_list : packed list -> packed_annotated_list - -(** [join_fee fee op] updates [op.fee] to [Limit.join op.fee fee] and - fails if the join fails *) -val join_fee : Tez.t Limit.t -> 'a t -> 'a t tzresult - -(** [set_fee fee op] updates [op.fee] to [fee] *) -val set_fee : Tez.t Limit.t -> 'a t -> 'a t - -(** See [join_fee] *) -val join_gas_limit : Gas.Arith.integral Limit.t -> 'a t -> 'a t tzresult - -(** See [set_fee] *) -val set_gas_limit : Gas.Arith.integral Limit.t -> 'a t -> 'a t - -(** See [join_fee] *) -val join_storage_limit : Z.t Limit.t -> 'a t -> 'a t tzresult - -(** See [set_fee] *) -val set_storage_limit : Z.t Limit.t -> 'a t -> 'a t - -(** Set the counter of the annotated operation. Fail if the counter - is already set. *) -val set_counter : counter -> 'a t -> 'a t tzresult - -(** Set the source of the operation. Fail if the source is already set. *) -val set_source : public_key_hash -> 'a t -> 'a t tzresult - -(** Convert an annotated manager operation to a proper manager operation. - Fail if some fields in the annotated operation are not set. *) -val manager_from_annotated : 'a t -> 'a Kind.manager contents tzresult - -val manager_list_from_annotated : - 'kind annotated_list -> 'kind Kind.manager contents_list tzresult diff --git a/src/proto_012_Psithaca/lib_client/client_proto_args.ml b/src/proto_012_Psithaca/lib_client/client_proto_args.ml deleted file mode 100644 index ef75fd573aa6..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_args.ml +++ /dev/null @@ -1,573 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol_client_context -open Protocol -open Alpha_context -open Clic - -type error += Bad_tez_arg of string * string (* Arg_name * value *) - -type error += Bad_max_priority of string - -type error += Bad_minimal_fees of string - -type error += Bad_max_waiting_time of string - -type error += Bad_endorsement_delay of string - -type error += Bad_preserved_levels of string - -let () = - register_error_kind - `Permanent - ~id:"badTezArg" - ~title:"Bad Tez Arg" - ~description:"Invalid \xEA\x9C\xA9 notation in parameter." - ~pp:(fun ppf (arg_name, literal) -> - Format.fprintf - ppf - "Invalid \xEA\x9C\xA9 notation in parameter %s: '%s'" - arg_name - literal) - Data_encoding.(obj2 (req "parameter" string) (req "literal" string)) - (function - | Bad_tez_arg (parameter, literal) -> Some (parameter, literal) - | _ -> None) - (fun (parameter, literal) -> Bad_tez_arg (parameter, literal)) ; - register_error_kind - `Permanent - ~id:"badMaxPriorityArg" - ~title:"Bad -max-priority arg" - ~description:"invalid priority in -max-priority" - ~pp:(fun ppf literal -> - Format.fprintf ppf "invalid priority '%s' in -max-priority" literal) - Data_encoding.(obj1 (req "parameter" string)) - (function Bad_max_priority parameter -> Some parameter | _ -> None) - (fun parameter -> Bad_max_priority parameter) ; - register_error_kind - `Permanent - ~id:"badMinimalFeesArg" - ~title:"Bad -minimal-fees arg" - ~description:"invalid fee threshold in -fee-threshold" - ~pp:(fun ppf literal -> - Format.fprintf ppf "invalid minimal fees '%s'" literal) - Data_encoding.(obj1 (req "parameter" string)) - (function Bad_minimal_fees parameter -> Some parameter | _ -> None) - (fun parameter -> Bad_minimal_fees parameter) ; - register_error_kind - `Permanent - ~id:"badMaxWaitingTimeArg" - ~title:"Bad -max-waiting-time arg" - ~description:"invalid duration in -max-waiting-time" - ~pp:(fun ppf literal -> - Format.fprintf - ppf - "Bad argument value for -max-waiting-time. Expected an integer, but \ - given '%s'" - literal) - Data_encoding.(obj1 (req "parameter" string)) - (function Bad_max_waiting_time parameter -> Some parameter | _ -> None) - (fun parameter -> Bad_max_waiting_time parameter) ; - register_error_kind - `Permanent - ~id:"badEndorsementDelayArg" - ~title:"Bad -endorsement-delay arg" - ~description:"invalid duration in -endorsement-delay" - ~pp:(fun ppf literal -> - Format.fprintf - ppf - "Bad argument value for -endorsement-delay. Expected an integer, but \ - given '%s'" - literal) - Data_encoding.(obj1 (req "parameter" string)) - (function Bad_endorsement_delay parameter -> Some parameter | _ -> None) - (fun parameter -> Bad_endorsement_delay parameter) ; - register_error_kind - `Permanent - ~id:"badPreservedLevelsArg" - ~title:"Bad -preserved-levels arg" - ~description:"invalid number of levels in -preserved-levels" - ~pp:(fun ppf literal -> - Format.fprintf - ppf - "Bad argument value for -preserved_levels. Expected a positive \ - integer, but given '%s'" - literal) - Data_encoding.(obj1 (req "parameter" string)) - (function Bad_preserved_levels parameter -> Some parameter | _ -> None) - (fun parameter -> Bad_preserved_levels parameter) - -let tez_sym = "\xEA\x9C\xA9" - -let string_parameter = parameter (fun _ x -> return x) - -let int_parameter = - parameter (fun _ p -> - try return (int_of_string p) with _ -> failwith "Cannot read int") - -let uri_parameter = parameter (fun _ x -> return (Uri.of_string x)) - -let bytes_of_prefixed_string s = - match - if String.length s < 2 || s.[0] <> '0' || s.[1] <> 'x' then None - else Hex.to_bytes (`Hex (String.sub s 2 (String.length s - 2))) - with - | Some s -> return s - | None -> - failwith "Invalid bytes, expecting hexadecimal notation (e.g. 0x1234abcd)" - -let bytes_parameter = parameter (fun _ s -> bytes_of_prefixed_string s) - -let data_parameter = - parameter (fun _ data -> - Lwt.return @@ Tezos_micheline.Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression data) - -let init_arg = - default_arg - ~long:"init" - ~placeholder:"data" - ~doc:"initial value of the contract's storage" - ~default:"Unit" - string_parameter - -let global_constant_param ~name ~desc next = - Clic.param ~name ~desc string_parameter next - -let arg_arg = - arg - ~long:"arg" - ~placeholder:"data" - ~doc:"argument passed to the contract's script, if needed" - string_parameter - -let default_arg_arg = - arg - ~long:"default-arg" - ~placeholder:"data" - ~doc:"default argument passed to each contract's script, if needed" - string_parameter - -let delegate_arg = - Client_keys.Public_key_hash.source_arg - ~long:"delegate" - ~placeholder:"address" - ~doc:"delegate of the contract\nMust be a known address." - () - -let source_arg = - arg - ~long:"source" - ~placeholder:"address" - ~doc:"source of the deposits to be paid\nMust be a known address." - string_parameter - -let entrypoint_arg = - arg - ~long:"entrypoint" - ~placeholder:"name" - ~doc:"entrypoint of the smart contract" - string_parameter - -let default_entrypoint_arg = - arg - ~long:"default-entrypoint" - ~placeholder:"name" - ~doc:"default entrypoint of the smart contracts" - string_parameter - -let force_switch = - switch - ~long:"force" - ~short:'f' - ~doc: - "disables the node's injection checks\n\ - Force the injection of branch-invalid operation or force the injection \ - of block without a fitness greater than the current head." - () - -let no_endorse_switch = - switch - ~long:"no-endorse" - ~doc:"Do not let the client automatically endorse a block that it baked." - () - -let minimal_timestamp_switch = - switch - ~long:"minimal-timestamp" - ~doc: - "Use the minimal timestamp instead of the current date as timestamp of \ - the baked block." - () - -let tez_format = - "Text format: `DDDDDDD.DDDDDD`.\n\ - Tez and mutez and separated by a period sign. Trailing and pending zeroes \ - are allowed." - -let tez_parameter param = - parameter (fun _ s -> - match Tez.of_string s with - | Some tez -> return tez - | None -> fail (Bad_tez_arg (param, s))) - -let tez_arg ~default ~parameter ~doc = - default_arg - ~long:parameter - ~placeholder:"amount" - ~doc - ~default - (tez_parameter ("--" ^ parameter)) - -let tez_param ~name ~desc next = - Clic.param - ~name - ~desc:(desc ^ " in \xEA\x9C\xA9\n" ^ tez_format) - (tez_parameter name) - next - -let fee_arg = - arg - ~long:"fee" - ~placeholder:"amount" - ~doc:"fee in \xEA\x9C\xA9 to pay to the baker" - (tez_parameter "--fee") - -let default_fee_arg = - arg - ~long:"default-fee" - ~placeholder:"amount" - ~doc:"default fee in \xEA\x9C\xA9 to pay to the baker for each transaction" - (tez_parameter "--default-fee") - -let level_kind = - parameter (fun _ s -> - match Option.bind (Script_int.of_string s) Script_int.is_nat with - | Some n -> return n - | None -> failwith "invalid level (must be a positive number)") - -let level_arg = - arg - ~long:"level" - ~placeholder:"level" - ~doc:"Set the level to be returned by the LEVEL instruction" - level_kind - -let timestamp_parameter = - parameter (fun _ s -> - match Script_timestamp.of_string s with - | Some time -> return time - | None -> - failwith - "invalid timestamp, must be either a RFC 3339 string or a number \ - of seconds since epoch.") - -let now_arg = - arg - ~long:"now" - ~placeholder:"timestamp" - ~doc: - "Set the timestamp to be returned by the NOW instruction. Allowed format \ - are RFC 3339 (YYYY-MM-DDTHH:MM:SSZ) or number of seconds since epoch." - timestamp_parameter - -let gas_limit_kind = - parameter (fun _ s -> - try - let v = Z.of_string s in - return (Gas.Arith.integral_exn v) - with _ -> failwith "invalid gas limit (must be a positive number)") - -let gas_limit_arg = - arg - ~long:"gas-limit" - ~short:'G' - ~placeholder:"amount" - ~doc: - "Set the gas limit of the transaction instead of letting the client \ - decide based on a simulation" - gas_limit_kind - -let default_gas_limit_arg = - arg - ~long:"default-gas-limit" - ~short:'G' - ~placeholder:"amount" - ~doc: - "Set the default gas limit for each transaction instead of letting the \ - client decide based on a simulation" - gas_limit_kind - -let run_gas_limit_arg = - arg - ~long:"gas" - ~short:'G' - ~doc:"Initial quantity of gas for typechecking and execution" - ~placeholder:"gas" - gas_limit_kind - -let storage_limit_kind = - parameter (fun _ s -> - try - let v = Z.of_string s in - assert (Compare.Z.(v >= Z.zero)) ; - return v - with _ -> - failwith "invalid storage limit (must be a positive number of bytes)") - -let storage_limit_arg = - arg - ~long:"storage-limit" - ~short:'S' - ~placeholder:"amount" - ~doc: - "Set the storage limit of the transaction instead of letting the client \ - decide based on a simulation" - storage_limit_kind - -let default_storage_limit_arg = - arg - ~long:"default-storage-limit" - ~short:'S' - ~placeholder:"amount" - ~doc: - "Set the default storage limit for each transaction instead of letting \ - the client decide based on a simulation" - storage_limit_kind - -let counter_arg = - arg - ~long:"counter" - ~short:'C' - ~placeholder:"counter" - ~doc:"Set the counter to be used by the transaction" - (parameter (fun _ s -> - try - let v = Z.of_string s in - assert (Compare.Z.(v >= Z.zero)) ; - return v - with _ -> - failwith "invalid counter (must be a positive number of bytes)")) - -let max_priority_arg = - arg - ~long:"max-priority" - ~placeholder:"slot" - ~doc:"maximum allowed baking slot" - (parameter (fun _ s -> - try return (int_of_string s) with _ -> fail (Bad_max_priority s))) - -let default_minimal_fees = - match Tez.of_mutez 100L with None -> assert false | Some t -> t - -let default_minimal_nanotez_per_gas_unit = Q.of_int 100 - -let default_minimal_nanotez_per_byte = Q.of_int 1000 - -let minimal_fees_arg = - default_arg - ~long:"minimal-fees" - ~placeholder:"amount" - ~doc:"exclude operations with fees lower than this threshold (in tez)" - ~default:(Tez.to_string default_minimal_fees) - (parameter (fun _ s -> - match Tez.of_string s with - | Some t -> return t - | None -> fail (Bad_minimal_fees s))) - -let minimal_nanotez_per_gas_unit_arg = - default_arg - ~long:"minimal-nanotez-per-gas-unit" - ~placeholder:"amount" - ~doc: - "exclude operations with fees per gas lower than this threshold (in \ - nanotez)" - ~default:(Q.to_string default_minimal_nanotez_per_gas_unit) - (parameter (fun _ s -> - try return (Q.of_string s) with _ -> fail (Bad_minimal_fees s))) - -let minimal_nanotez_per_byte_arg = - default_arg - ~long:"minimal-nanotez-per-byte" - ~placeholder:"amount" - ~default:(Q.to_string default_minimal_nanotez_per_byte) - ~doc: - "exclude operations with fees per byte lower than this threshold (in \ - nanotez)" - (parameter (fun _ s -> - try return (Q.of_string s) with _ -> fail (Bad_minimal_fees s))) - -let force_low_fee_arg = - switch - ~long:"force-low-fee" - ~doc:"Don't check that the fee is lower than the estimated default value" - () - -let fee_cap_arg = - default_arg - ~long:"fee-cap" - ~placeholder:"amount" - ~default:"1.0" - ~doc:"Set the fee cap" - (parameter (fun _ s -> - match Tez.of_string s with - | Some t -> return t - | None -> failwith "Bad fee cap")) - -let burn_cap_arg = - default_arg - ~long:"burn-cap" - ~placeholder:"amount" - ~default:"0" - ~doc:"Set the burn cap" - (parameter (fun _ s -> - match Tez.of_string s with - | Some t -> return t - | None -> failwith "Bad burn cap")) - -let no_waiting_for_endorsements_arg = - switch - ~long:"no-waiting-for-late-endorsements" - ~doc:"Disable waiting for late endorsements" - () - -let await_endorsements_arg = - switch - ~long:"await-late-endorsements" - ~doc:"Await late endorsements when baking a block" - () - -let endorsement_delay_arg = - default_arg - ~long:"endorsement-delay" - ~placeholder:"seconds" - ~doc: - "delay before endorsing blocks\n\ - Delay between notifications of new blocks from the node and production \ - of endorsements for these blocks." - ~default:"0" - (parameter (fun _ s -> - try - let i = int_of_string s in - fail_when (i < 0) (Bad_endorsement_delay s) >>=? fun () -> - return (int_of_string s) - with _ -> fail (Bad_endorsement_delay s))) - -let preserved_levels_arg = - arg - ~long:"preserved-levels" - ~placeholder:"threshold" - ~doc:"Number of effective levels kept in the accuser's memory" - (parameter (fun _ s -> - try - let preserved_cycles = int_of_string s in - if preserved_cycles < 0 then fail (Bad_preserved_levels s) - else return preserved_cycles - with _ -> fail (Bad_preserved_levels s))) - -let no_print_source_flag = - switch - ~long:"no-print-source" - ~short:'q' - ~doc: - "don't print the source code\n\ - If an error is encountered, the client will print the contract's source \ - code by default.\n\ - This option disables this behaviour." - () - -let no_confirmation = - switch - ~long:"no-confirmation" - ~doc:"don't print wait for the operation to be confirmed." - () - -let signature_parameter = - parameter (fun _cctxt s -> - match Signature.of_b58check_opt s with - | Some s -> return s - | None -> failwith "Not given a valid signature") - -let unparsing_mode_parameter = - parameter - ~autocomplete:(fun _cctxt -> - return ["Readable"; "Optimized"; "Optimized_legacy"]) - (fun _cctxt s -> - match s with - | "Readable" -> return Script_ir_translator.Readable - | "Optimized" -> return Script_ir_translator.Optimized - | "Optimized_legacy" -> return Script_ir_translator.Optimized_legacy - | _ -> failwith "Unknown unparsing mode %s" s) - -let unparsing_mode_arg ~default = - default_arg - ~long:"unparsing-mode" - ~placeholder:"mode" - ~doc: - "Unparsing mode to use\n\ - One of \"Readable\", \"Optimized\", or \"Optimized_legacy\".\n\ - This option affects the way the values of the following Michelson types \ - are represented:\n\ - - timestamp: the Readable representation is a RFC3339 string, the \ - Optimized and Optimized_legacy representations are the number of \ - seconds since Epoch\n\ - - key, signature, key_hash, address, contract, chain_id: the Readable \ - representation is a Base58Check string, the Optimized and \ - Optimized_legacy representations are byte sequences\n\ - - nested pairs: in Readable mode, the Pair constructor is used even \ - with arity bigger than 2 such as in Pair 0 1 2; in Optimized_legacy \ - mode, the Pair constructor is always use with arity 2 such as in Pair 0 \ - (Pair 1 2); in Optimized mode, a sequence is used if there are at least \ - 4 elements and the behavior is the same as in Optimized_legacy mode \ - otherwise.\n" - ~default - unparsing_mode_parameter - -let enforce_indentation_flag = - switch - ~long:"enforce-indentation" - ~doc: - "Check that the Micheline expression passed to this command is \ - well-indented." - () - -let display_names_flag = - switch - ~long:"display-names" - ~doc:"Print names of scripts passed to this command" - () - -module Daemon = struct - let baking_switch = - switch ~long:"baking" ~short:'B' ~doc:"run the baking daemon" () - - let endorsement_switch = - switch ~long:"endorsement" ~short:'E' ~doc:"run the endorsement daemon" () - - let denunciation_switch = - switch ~long:"denunciation" ~short:'D' ~doc:"run the denunciation daemon" () -end diff --git a/src/proto_012_Psithaca/lib_client/client_proto_args.mli b/src/proto_012_Psithaca/lib_client/client_proto_args.mli deleted file mode 100644 index 0a57c66874ac..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_args.mli +++ /dev/null @@ -1,141 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Protocol_client_context - -val tez_sym : string - -val init_arg : (string, full) Clic.arg - -val fee_arg : (Tez.t option, full) Clic.arg - -val default_fee_arg : (Tez.t option, full) Clic.arg - -val counter_arg : (Z.t option, full) Clic.arg - -val gas_limit_arg : (Gas.Arith.integral option, full) Clic.arg - -val default_gas_limit_arg : (Gas.Arith.integral option, full) Clic.arg - -val run_gas_limit_arg : (Gas.Arith.integral option, full) Clic.arg - -val storage_limit_arg : (Z.t option, full) Clic.arg - -val default_storage_limit_arg : (Z.t option, full) Clic.arg - -val arg_arg : (string option, full) Clic.arg - -val default_arg_arg : (string option, full) Clic.arg - -val source_arg : (string option, full) Clic.arg - -val entrypoint_arg : (string option, full) Clic.arg - -val default_entrypoint_arg : (string option, full) Clic.arg - -val delegate_arg : (Signature.Public_key_hash.t option, full) Clic.arg - -val max_priority_arg : (int option, full) Clic.arg - -val minimal_fees_arg : (Tez.tez, full) Clic.arg - -val minimal_nanotez_per_gas_unit_arg : (Q.t, full) Clic.arg - -val minimal_nanotez_per_byte_arg : (Q.t, full) Clic.arg - -val force_low_fee_arg : (bool, full) Clic.arg - -val fee_cap_arg : (Tez.t, full) Clic.arg - -val burn_cap_arg : (Tez.t, full) Clic.arg - -val no_waiting_for_endorsements_arg : (bool, full) Clic.arg - -val await_endorsements_arg : (bool, full) Clic.arg - -val force_switch : (bool, full) Clic.arg - -val no_endorse_switch : (bool, full) Clic.arg - -val minimal_timestamp_switch : (bool, full) Clic.arg - -val endorsement_delay_arg : (int, full) Clic.arg - -val preserved_levels_arg : (int option, full) Clic.arg - -val no_print_source_flag : (bool, full) Clic.arg - -val no_confirmation : (bool, full) Clic.arg - -val tez_arg : - default:string -> parameter:string -> doc:string -> (Tez.t, full) Clic.arg - -val tez_param : - name:string -> - desc:string -> - ('a, full) Clic.params -> - (Tez.t -> 'a, full) Clic.params - -val global_constant_param : - name:string -> - desc:string -> - ('a, full) Clic.params -> - (string -> 'a, full) Clic.params - -val signature_parameter : (Signature.t, full) Clic.parameter - -module Daemon : sig - val baking_switch : (bool, full) Clic.arg - - val endorsement_switch : (bool, full) Clic.arg - - val denunciation_switch : (bool, full) Clic.arg -end - -val int_parameter : (int, full) Clic.parameter - -val uri_parameter : (Uri.t, full) Clic.parameter - -val string_parameter : (string, full) Clic.parameter - -val bytes_of_prefixed_string : string -> Bytes.t tzresult Lwt.t - -val bytes_parameter : (Bytes.t, full) Clic.parameter - -val data_parameter : (Michelson_v1_parser.parsed, full) Clic.parameter - -val unparsing_mode_arg : - default:string -> (Script_ir_translator.unparsing_mode, full) Clic.arg - -val enforce_indentation_flag : (bool, full) Clic.arg - -val display_names_flag : (bool, full) Clic.arg - -val level_arg : (Script_int.n Script_int.num option, full) Clic.arg - -val now_arg : (Script_timestamp.t option, full) Clic.arg diff --git a/src/proto_012_Psithaca/lib_client/client_proto_context.ml b/src/proto_012_Psithaca/lib_client/client_proto_context.ml deleted file mode 100644 index d55e8eb9f321..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_context.ml +++ /dev/null @@ -1,747 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Protocol_client_context -open Tezos_micheline -open Client_proto_contracts -open Client_keys - -let get_balance (rpc : #rpc_context) ~chain ~block contract = - Alpha_services.Contract.balance rpc (chain, block) contract - -let get_storage (rpc : #rpc_context) ~chain ~block ~unparsing_mode contract = - Plugin.RPC.Contract.get_storage_normalized - rpc - (chain, block) - ~unparsing_mode - ~contract - -let get_big_map_value (rpc : #rpc_context) ~chain ~block ~unparsing_mode id key - = - Plugin.RPC.Big_map.big_map_get_normalized - rpc - (chain, block) - ~unparsing_mode - id - key - -let get_contract_big_map_value (rpc : #rpc_context) ~chain ~block contract key = - Alpha_services.Contract.contract_big_map_get_opt - rpc - (chain, block) - contract - key - -let get_script (rpc : #rpc_context) ~chain ~block ~unparsing_mode contract = - Plugin.RPC.Contract.get_script_normalized - rpc - (chain, block) - ~unparsing_mode - ~contract - -let get_script_hash (rpc : #rpc_context) ~chain ~block contract = - Alpha_services.Contract.script_opt rpc (chain, block) contract - >>=? fun script_opt -> - Lwt.return @@ Environment.wrap_tzresult - @@ Option.map_e - (fun {Script.code; storage = _} -> - Script_repr.force_decode code >>? fun code -> - let bytes = - Data_encoding.Binary.to_bytes_exn Script.expr_encoding code - in - let hash = Script_expr_hash.hash_bytes [bytes] in - ok hash) - script_opt - -let get_frozen_deposits_limit (rpc : #rpc_context) ~chain ~block delegate = - Alpha_services.Delegate.frozen_deposits_limit rpc (chain, block) delegate - -let parse_expression arg = - Lwt.return - (Micheline_parser.no_parsing_error - (Michelson_v1_parser.parse_expression arg)) - -let parse_arg_transfer arg = - (match arg with - | Some arg -> - parse_expression arg >>=? fun {expanded = arg; _} -> return_some arg - | None -> return_none) - >>=? fun parameters -> - return - (Option.fold ~some:Script.lazy_expr ~none:Script.unit_parameter parameters) - -let build_transaction_operation ~amount ~parameters ?(entrypoint = "default") - ?fee ?gas_limit ?storage_limit destination = - let operation = Transaction {amount; parameters; destination; entrypoint} in - Injection.prepare_manager_operation - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - operation - -let transfer (cctxt : #full) ~chain ~block ?confirmations ?dry_run - ?verbose_signing ?simulation ?branch ~source ~src_pk ~src_sk ~destination - ?(entrypoint = "default") ?arg ~amount ?fee ?gas_limit ?storage_limit - ?counter ~fee_parameter () = - parse_arg_transfer arg >>=? fun parameters -> - let contents = - build_transaction_operation - ~amount - ~parameters - ~entrypoint - ?fee - ?gas_limit - ?storage_limit - destination - in - let contents = Annotated_manager_operation.Single_manager contents in - Injection.inject_manager_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?simulation - ?branch - ~source - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - ?counter - ~src_pk - ~src_sk - ~fee_parameter - contents - >>=? fun (oph, op, result) -> - Lwt.return (Injection.originated_contracts result) >>=? fun contracts -> - match Apply_results.pack_contents_list op result with - | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> - return ((oph, op, result), contracts) - -let build_reveal_operation ?fee ?gas_limit ?storage_limit pk = - let operation = Reveal pk in - Injection.prepare_manager_operation - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - operation - -let reveal cctxt ~chain ~block ?confirmations ?dry_run ?verbose_signing ?branch - ~source ~src_pk ~src_sk ?fee ~fee_parameter () = - let contents = - Annotated_manager_operation.Single_manager - (build_reveal_operation ?fee ~storage_limit:Z.zero src_pk) - in - Injection.inject_manager_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?branch - ~source - ~fee:(Limit.of_option fee) - ~gas_limit:Limit.unknown - ~storage_limit:Limit.unknown - ~src_pk - ~src_sk - ~fee_parameter - contents - >>=? fun (oph, op, result) -> - match Apply_results.pack_contents_list op result with - | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> - return (oph, op, result) - -let build_delegate_operation ?fee ?gas_limit ?storage_limit delegate_opt = - let operation = Delegation delegate_opt in - Injection.prepare_manager_operation - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - operation - -let delegate_contract cctxt ~chain ~block ?branch ?confirmations ?dry_run - ?verbose_signing ?simulation ~source ~src_pk ~src_sk ?fee ~fee_parameter - delegate_opt = - let operation = - Annotated_manager_operation.Single_manager - (build_delegate_operation ?fee delegate_opt) - in - Injection.inject_manager_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?simulation - ?branch - ~source - ~fee:(Limit.of_option fee) - ~gas_limit:Limit.unknown - ~storage_limit:Limit.unknown - ~src_pk - ~src_sk - ~fee_parameter - operation - >>=? fun (oph, op, result) -> - match Apply_results.pack_contents_list op result with - | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> - return (oph, op, result) - -let list_contract_labels cctxt ~chain ~block = - Alpha_services.Contract.list cctxt (chain, block) >>=? fun contracts -> - List.rev_map_es - (fun h -> - (match Contract.is_implicit h with - | Some m -> ( - Public_key_hash.rev_find cctxt m >>=? function - | None -> return "" - | Some nm -> ( - RawContractAlias.find_opt cctxt nm >>=? function - | None -> return (" (known as " ^ nm ^ ")") - | Some _ -> return (" (known as key:" ^ nm ^ ")"))) - | None -> ( - RawContractAlias.rev_find cctxt h >>=? function - | None -> return "" - | Some nm -> return (" (known as " ^ nm ^ ")"))) - >>=? fun nm -> - let kind = - match Contract.is_implicit h with Some _ -> " (implicit)" | None -> "" - in - let h_b58 = Contract.to_b58check h in - return (nm, h_b58, kind)) - contracts - >|=? List.rev - -let message_added_contract (cctxt : #full) name = - cctxt#message "Contract memorized as %s." name - -let set_delegate cctxt ~chain ~block ?confirmations ?dry_run ?verbose_signing - ?simulation ?fee contract ~src_pk ~manager_sk ~fee_parameter opt_delegate = - delegate_contract - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?simulation - ~source:contract - ~src_pk - ~src_sk:manager_sk - ?fee - ~fee_parameter - opt_delegate - -let register_as_delegate cctxt ~chain ~block ?confirmations ?dry_run - ?verbose_signing ?fee ~manager_sk ~fee_parameter src_pk = - let source = Signature.Public_key.hash src_pk in - delegate_contract - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ~source - ~src_pk - ~src_sk:manager_sk - ?fee - ~fee_parameter - (Some source) - -let set_deposits_limit cctxt ~chain ~block ?confirmations ?dry_run - ?verbose_signing ?simulation ?fee contract ~src_pk ~manager_sk - ~fee_parameter limit_opt = - let operation = Set_deposits_limit limit_opt in - let operation = - Injection.prepare_manager_operation - ~fee:(Limit.of_option fee) - ~gas_limit:Limit.unknown - ~storage_limit:Limit.unknown - operation - in - let operation = Annotated_manager_operation.Single_manager operation in - Injection.inject_manager_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?simulation - ~source:contract - ~fee:(Limit.of_option fee) - ~gas_limit:Limit.unknown - ~storage_limit:Limit.unknown - ~src_pk - ~src_sk:manager_sk - ~fee_parameter - operation - >>=? fun (oph, op, result) -> - match Apply_results.pack_contents_list op result with - | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> - return (oph, op, result) - -let save_contract ~force cctxt alias_name contract = - RawContractAlias.add ~force cctxt alias_name contract >>=? fun () -> - message_added_contract cctxt alias_name >>= fun () -> return_unit - -let build_origination_operation ?fee ?gas_limit ?storage_limit ~initial_storage - ~code ~delegate ~balance () = - (* With the change of making implicit accounts delegatable, the following - 3 arguments are being defaulted before they can be safely removed. *) - Lwt.return (Michelson_v1_parser.parse_expression initial_storage) - >>= fun result -> - Lwt.return (Micheline_parser.no_parsing_error result) - >>=? fun {Michelson_v1_parser.expanded = storage; _} -> - let code = Script.lazy_expr code and storage = Script.lazy_expr storage in - let origination = - Origination - { - delegate; - script = {code; storage}; - credit = balance; - preorigination = None; - } - in - return - (Injection.prepare_manager_operation - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - origination) - -let originate_contract (cctxt : #full) ~chain ~block ?confirmations ?dry_run - ?verbose_signing ?branch ?fee ?gas_limit ?storage_limit ~delegate - ~initial_storage ~balance ~source ~src_pk ~src_sk ~code ~fee_parameter () = - build_origination_operation - ?fee - ?gas_limit - ?storage_limit - ~initial_storage - ~code - ~delegate - ~balance - () - >>=? fun origination -> - let origination = Annotated_manager_operation.Single_manager origination in - Injection.inject_manager_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?branch - ~source - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - ~src_pk - ~src_sk - ~fee_parameter - origination - >>=? fun (oph, op, result) -> - (match Apply_results.pack_contents_list op result with - | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> - return (oph, op, result)) - >>=? fun res -> - Lwt.return (Injection.originated_contracts result) >>=? function - | [contract] -> return (res, contract) - | contracts -> - failwith - "The origination introduced %d contracts instead of one." - (List.length contracts) - -let michelson_expression_of_string str = - Michelson_v1_parser.parse_expression str |> Micheline_parser.no_parsing_error - >>? fun {Michelson_v1_parser.expanded = v; _} -> ok @@ Script.lazy_expr v - -let build_register_global_constant ?fee ?gas_limit ?storage_limit value = - michelson_expression_of_string value >>? fun value -> - let op = Register_global_constant {value} in - ok - (Injection.prepare_manager_operation - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - op) - -let register_global_constant (cctxt : #full) ~chain ~block ?confirmations - ?dry_run ?verbose_signing ?simulation ?fee ?gas_limit ?storage_limit - ?counter ~source ~src_pk ~src_sk ~fee_parameter ~constant () = - build_register_global_constant ?fee ?storage_limit ?gas_limit constant - >>?= fun op -> - let op = Annotated_manager_operation.Single_manager op in - Injection.inject_manager_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?simulation - ?counter - ~source - ~fee:(Limit.of_option fee) - ~storage_limit:(Limit.of_option storage_limit) - ~gas_limit:(Limit.of_option gas_limit) - ~src_pk - ~src_sk - ~fee_parameter - op - >>=? fun (oph, op, result) -> - match Apply_results.pack_contents_list op result with - | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> - return (oph, op, result) - -type activation_key = { - pkh : Ed25519.Public_key_hash.t; - amount : Tez.t; - activation_code : Blinded_public_key_hash.activation_code; - mnemonic : string list; - password : string; - email : string; -} - -let raw_activation_key_encoding = - let open Data_encoding in - obj6 - (req "pkh" Ed25519.Public_key_hash.encoding) - (req "amount" Tez.encoding) - (req "activation_code" Blinded_public_key_hash.activation_code_encoding) - (req "mnemonic" (list string)) - (req "password" string) - (req "email" string) - -let activation_key_encoding = - (* Hack: allow compatibility with older encoding *) - let open Data_encoding in - conv - (fun {pkh; amount; activation_code; mnemonic; password; email} -> - (pkh, amount, activation_code, mnemonic, password, email)) - (fun (pkh, amount, activation_code, mnemonic, password, email) -> - {pkh; amount; activation_code; mnemonic; password; email}) - @@ splitted - ~binary:raw_activation_key_encoding - ~json: - (union - [ - case - ~title:"Activation" - Json_only - raw_activation_key_encoding - (fun x -> Some x) - (fun x -> x); - case - ~title:"Deprecated_activation" - Json_only - (obj6 - (req "pkh" Ed25519.Public_key_hash.encoding) - (req "amount" Tez.encoding) - (req - "secret" - Blinded_public_key_hash.activation_code_encoding) - (req "mnemonic" (list string)) - (req "password" string) - (req "email" string)) - (fun _ -> None) - (fun x -> x); - ]) - -type batch_transfer_operation = { - destination : string; - fee : string option; - gas_limit : Gas.Arith.integral option; - storage_limit : Z.t option; - amount : string; - arg : string option; - entrypoint : string option; -} - -let batch_transfer_operation_encoding = - let open Data_encoding in - conv - (fun {destination; fee; gas_limit; storage_limit; amount; arg; entrypoint} -> - (destination, fee, gas_limit, storage_limit, amount, arg, entrypoint)) - (fun (destination, fee, gas_limit, storage_limit, amount, arg, entrypoint) -> - {destination; fee; gas_limit; storage_limit; amount; arg; entrypoint}) - (obj7 - (req "destination" string) - (opt "fee" string) - (opt "gas-limit" Gas.Arith.n_integral_encoding) - (opt "storage-limit" z) - (req "amount" string) - (opt "arg" string) - (opt "entrypoint" string)) - -let read_key key = - match Bip39.of_words key.mnemonic with - | None -> failwith "" - | Some t -> - (* TODO: unicode normalization (NFKD)... *) - let passphrase = - Bytes.(cat (of_string key.email) (of_string key.password)) - in - let sk = Bip39.to_seed ~passphrase t in - let sk = Bytes.sub sk 0 32 in - let sk : Signature.Secret_key.t = - Ed25519 - (Data_encoding.Binary.of_bytes_exn Ed25519.Secret_key.encoding sk) - in - let pk = Signature.Secret_key.to_public_key sk in - let pkh = Signature.Public_key.hash pk in - return (pkh, pk, sk) - -let inject_activate_operation cctxt ~chain ~block ?confirmations ?dry_run alias - pkh activation_code = - let contents = Single (Activate_account {id = pkh; activation_code}) in - Injection.inject_operation - cctxt - ?confirmations - ?dry_run - ~chain - ~block - ~fee_parameter:Injection.dummy_fee_parameter - contents - >>=? fun (oph, op, result) -> - (match confirmations with - | None -> return_unit - | Some _confirmations -> - Alpha_services.Contract.balance - cctxt - (chain, block) - (Contract.implicit_contract (Ed25519 pkh)) - >>=? fun balance -> - cctxt#message - "Account %s (%a) activated with %s%a." - alias - Ed25519.Public_key_hash.pp - pkh - Client_proto_args.tez_sym - Tez.pp - balance - >>= fun () -> return_unit) - >>=? fun () -> - match Apply_results.pack_contents_list op result with - | Apply_results.Single_and_result ((Activate_account _ as op), result) -> - return (oph, op, result) - -let activate_account (cctxt : #full) ~chain ~block ?confirmations ?dry_run - ?(encrypted = false) ?force key name = - read_key key >>=? fun (pkh, pk, sk) -> - fail_unless - (Signature.Public_key_hash.equal pkh (Ed25519 key.pkh)) - (error_of_fmt - "@[Inconsistent activation key:@ Computed pkh: %a@ Embedded pkh: \ - %a @]" - Signature.Public_key_hash.pp - pkh - Ed25519.Public_key_hash.pp - key.pkh) - >>=? fun () -> - Tezos_signer_backends.Unencrypted.make_pk pk >>?= fun pk_uri -> - (if encrypted then - Tezos_signer_backends.Encrypted.prompt_twice_and_encrypt cctxt sk - else Tezos_signer_backends.Unencrypted.make_sk sk >>?= return) - >>=? fun sk_uri -> - Client_keys.register_key cctxt ?force (pkh, pk_uri, sk_uri) name - >>=? fun () -> - inject_activate_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - name - key.pkh - key.activation_code - -let activate_existing_account (cctxt : #full) ~chain ~block ?confirmations - ?dry_run alias activation_code = - Client_keys.alias_keys cctxt alias >>=? function - | Some (Ed25519 pkh, _, _) -> - inject_activate_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - alias - pkh - activation_code - | Some _ -> failwith "Only Ed25519 accounts can be activated" - | None -> failwith "Unknown account" - -type period_info = { - current_period_kind : Voting_period.kind; - position : Int32.t; - remaining : Int32.t; - current_proposal : Protocol_hash.t option; -} - -type ballots_info = { - current_quorum : Int32.t; - participation : Int32.t; - supermajority : Int32.t; - ballots : Vote.ballots; -} - -let get_ballots_info (cctxt : #full) ~chain ~block = - (* Get the next level, not the current *) - let cb = (chain, block) in - Alpha_services.Voting.ballots cctxt cb >>=? fun ballots -> - Alpha_services.Voting.current_quorum cctxt cb >>=? fun current_quorum -> - Alpha_services.Voting.listings cctxt cb >>=? fun listings -> - let max_participation = - List.fold_left (fun acc (_, w) -> Int32.add w acc) 0l listings - in - let all_votes = Int32.(add (add ballots.yay ballots.nay) ballots.pass) in - let participation = Int32.(div (mul all_votes 100_00l) max_participation) in - let supermajority = Int32.(div (mul 8l (add ballots.yay ballots.nay)) 10l) in - return {current_quorum; participation; supermajority; ballots} - -let get_period_info ?(successor = false) (cctxt : #full) ~chain ~block = - let cb = (chain, block) in - (if successor then Alpha_services.Voting.successor_period - else Alpha_services.Voting.current_period) - cctxt - cb - >>=? fun voting_period -> - Alpha_services.Voting.current_proposal cctxt cb >>=? fun current_proposal -> - return - { - current_period_kind = voting_period.voting_period.kind; - position = voting_period.position; - remaining = voting_period.remaining; - current_proposal; - } - -let get_proposals (cctxt : #full) ~chain ~block = - let cb = (chain, block) in - Alpha_services.Voting.proposals cctxt cb - -let submit_proposals ?dry_run ?verbose_signing (cctxt : #full) ~chain ~block - ?confirmations ~src_sk source proposals = - Alpha_services.Voting.successor_period cctxt (chain, block) - >>=? fun {voting_period = {index; _}; _} -> - let contents = Single (Proposals {source; period = index; proposals}) in - Injection.inject_operation - cctxt - ~chain - ~block - ?confirmations - ~fee_parameter:Injection.dummy_fee_parameter - ?dry_run - ~src_sk - contents - ?verbose_signing - -let submit_ballot ?dry_run ?verbose_signing (cctxt : #full) ~chain ~block - ?confirmations ~src_sk source proposal ballot = - (* The user must provide the proposal explicitly to make himself sure - for what he is voting. *) - Alpha_services.Voting.successor_period cctxt (chain, block) - >>=? fun {voting_period = {index; _}; _} -> - let contents = Single (Ballot {source; period = index; proposal; ballot}) in - Injection.inject_operation - cctxt - ~chain - ~block - ?confirmations - ~fee_parameter:Injection.dummy_fee_parameter - ?dry_run - ~src_sk - contents - ?verbose_signing - -let pp_operation formatter (a : Alpha_block_services.operation) = - match (a.receipt, a.protocol_data) with - | (Some (Apply_results.Operation_metadata omd), Operation_data od) -> ( - match Apply_results.kind_equal_list od.contents omd.contents with - | Some Apply_results.Eq -> - Operation_result.pp_operation_result - formatter - (od.contents, omd.contents) - | None -> Stdlib.failwith "Unexpected result.") - | (None, _) -> - Stdlib.failwith - "Pruned metadata: the operation receipt was removed accordingly to the \ - node's history mode." - | _ -> Stdlib.failwith "Unexpected result." - -let get_operation_from_block (cctxt : #full) ~chain predecessors operation_hash - = - Client_confirmations.lookup_operation_in_previous_blocks - cctxt - ~chain - ~predecessors - operation_hash - >>=? function - | None -> return_none - | Some (block, i, j) -> - cctxt#message - "Operation found in block: %a (pass: %d, offset: %d)" - Block_hash.pp - block - i - j - >>= fun () -> - Protocol_client_context.Alpha_block_services.Operations.operation - cctxt - ~chain - ~block:(`Hash (block, 0)) - i - j - >>=? fun op' -> return_some op' - -let display_receipt_for_operation (cctxt : #full) ~chain ?(predecessors = 10) - operation_hash = - get_operation_from_block cctxt ~chain predecessors operation_hash - >>=? function - | None -> failwith "Couldn't find operation" - | Some op -> cctxt#message "%a" pp_operation op >>= fun () -> return_unit - -let cached_contracts cctxt ~chain ~block = - let cb = (chain, block) in - Alpha_services.Cache.cached_contracts cctxt cb - -let contract_rank cctxt ~chain ~block contract = - let cb = (chain, block) in - Alpha_services.Cache.contract_rank cctxt cb contract - -let contract_cache_size cctxt ~chain ~block = - let cb = (chain, block) in - Alpha_services.Cache.contract_cache_size cctxt cb - -let contract_cache_size_limit cctxt ~chain ~block = - let cb = (chain, block) in - Alpha_services.Cache.contract_cache_size_limit cctxt cb diff --git a/src/proto_012_Psithaca/lib_client/client_proto_context.mli b/src/proto_012_Psithaca/lib_client/client_proto_context.mli deleted file mode 100644 index 05d01ac753ef..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_context.mli +++ /dev/null @@ -1,386 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -val list_contract_labels : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - (string * string * string) list tzresult Lwt.t - -val get_storage : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - unparsing_mode:Script_ir_translator.unparsing_mode -> - Contract.t -> - Script.expr option tzresult Lwt.t - -val get_contract_big_map_value : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Contract.t -> - Script.expr * Script.expr -> - Script.expr option tzresult Lwt.t - -val register_global_constant : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?simulation:bool -> - ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - ?counter:Z.t -> - source:Signature.public_key_hash -> - src_pk:Signature.public_key -> - src_sk:Client_keys.sk_uri -> - fee_parameter:Injection.fee_parameter -> - constant:string -> - unit -> - (Kind.register_global_constant Kind.manager Injection.result, tztrace) result - Lwt.t - -val get_big_map_value : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - unparsing_mode:Script_ir_translator.unparsing_mode -> - Big_map.Id.t -> - Script_expr_hash.t -> - Script.expr tzresult Lwt.t - -val get_script : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - unparsing_mode:Script_ir_translator.unparsing_mode -> - Contract.t -> - Script.t option tzresult Lwt.t - -val get_script_hash : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Contract.t -> - Script_expr_hash.t option tzresult Lwt.t - -val get_balance : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Contract.t -> - Tez.t tzresult Lwt.t - -val get_frozen_deposits_limit : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Signature.Public_key_hash.t -> - Tez.t option tzresult Lwt.t - -val build_delegate_operation : - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - public_key_hash option -> - Kind.delegation Annotated_manager_operation.t - -val set_delegate : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?simulation:bool -> - ?fee:Tez.tez -> - public_key_hash -> - src_pk:public_key -> - manager_sk:Client_keys.sk_uri -> - fee_parameter:Injection.fee_parameter -> - public_key_hash option -> - Kind.delegation Kind.manager Injection.result tzresult Lwt.t - -val set_deposits_limit : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?simulation:bool -> - ?fee:Tez.tez -> - public_key_hash -> - src_pk:public_key -> - manager_sk:Client_keys.sk_uri -> - fee_parameter:Injection.fee_parameter -> - Tez.t option -> - Kind.set_deposits_limit Kind.manager Injection.result tzresult Lwt.t - -val register_as_delegate : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?fee:Tez.tez -> - manager_sk:Client_keys.sk_uri -> - fee_parameter:Injection.fee_parameter -> - public_key -> - Kind.delegation Kind.manager Injection.result tzresult Lwt.t - -val save_contract : - force:bool -> - #Protocol_client_context.full -> - string -> - Contract.t -> - unit tzresult Lwt.t - -val originate_contract : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?branch:int -> - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - delegate:public_key_hash option -> - initial_storage:string -> - balance:Tez.t -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - code:Script.expr -> - fee_parameter:Injection.fee_parameter -> - unit -> - (Kind.origination Kind.manager Injection.result * Contract.t) tzresult Lwt.t - -val parse_arg_transfer : string option -> Script.lazy_expr tzresult Lwt.t - -val build_transaction_operation : - amount:Tez.t -> - parameters:Script.lazy_expr -> - ?entrypoint:string -> - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - Contract.t -> - Kind.transaction Annotated_manager_operation.t - -val transfer : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?simulation:bool -> - ?branch:int -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - destination:Contract.t -> - ?entrypoint:string -> - ?arg:string -> - amount:Tez.t -> - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - ?counter:Z.t -> - fee_parameter:Injection.fee_parameter -> - unit -> - (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult - Lwt.t - -val build_reveal_operation : - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - public_key -> - Kind.reveal Annotated_manager_operation.t - -val reveal : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?branch:int -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - ?fee:Tez.t -> - fee_parameter:Injection.fee_parameter -> - unit -> - Kind.reveal Kind.manager Injection.result tzresult Lwt.t - -type activation_key = { - pkh : Ed25519.Public_key_hash.t; - amount : Tez.t; - activation_code : Blinded_public_key_hash.activation_code; - mnemonic : string list; - password : string; - email : string; -} - -val activation_key_encoding : activation_key Data_encoding.t - -type batch_transfer_operation = { - destination : string; - fee : string option; - gas_limit : Gas.Arith.integral option; - storage_limit : Z.t option; - amount : string; - arg : string option; - entrypoint : string option; -} - -val batch_transfer_operation_encoding : batch_transfer_operation Data_encoding.t - -val activate_account : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?encrypted:bool -> - ?force:bool -> - activation_key -> - string -> - Kind.activate_account Injection.result tzresult Lwt.t - -val activate_existing_account : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - string -> - Blinded_public_key_hash.activation_code -> - Kind.activate_account Injection.result tzresult Lwt.t - -type period_info = { - current_period_kind : Voting_period.kind; - position : Int32.t; - remaining : Int32.t; - current_proposal : Protocol_hash.t option; -} - -type ballots_info = { - current_quorum : Int32.t; - participation : Int32.t; - supermajority : Int32.t; - ballots : Vote.ballots; -} - -val get_period_info : - ?successor:bool -> - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - period_info tzresult Lwt.t - -val get_ballots_info : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ballots_info tzresult Lwt.t - -val get_proposals : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Int32.t Environment.Protocol_hash.Map.t tzresult Lwt.t - -val submit_proposals : - ?dry_run:bool -> - ?verbose_signing:bool -> - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - src_sk:Client_keys.sk_uri -> - public_key_hash -> - Protocol_hash.t list -> - Kind.proposals Injection.result_list tzresult Lwt.t - -val submit_ballot : - ?dry_run:bool -> - ?verbose_signing:bool -> - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - src_sk:Client_keys.sk_uri -> - public_key_hash -> - Protocol_hash.t -> - Vote.ballot -> - Kind.ballot Injection.result_list tzresult Lwt.t - -(** lookup an operation in [predecessors] previous blocks, and print the - receipt if found *) -val display_receipt_for_operation : - #Protocol_client_context.full -> - chain:Block_services.chain -> - ?predecessors:int -> - Operation_list_hash.elt -> - unit tzresult Lwt.t - -val cached_contracts : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - (Contract.t * int) list tzresult Lwt.t - -val contract_rank : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Contract.t -> - int option tzresult Lwt.t - -val contract_cache_size : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - int tzresult Lwt.t - -val contract_cache_size_limit : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - int tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_client/client_proto_contracts.ml b/src/proto_012_Psithaca/lib_client/client_proto_contracts.ml deleted file mode 100644 index 903e0ddd0968..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_contracts.ml +++ /dev/null @@ -1,156 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -module ContractEntity = struct - include Contract (* t, Compare, encoding *) - - let of_source s = - Contract.of_b58check s |> Environment.wrap_tzresult - |> record_trace_eval (fun () -> error_of_fmt "bad contract notation") - |> Lwt.return - - let to_source s = return (Contract.to_b58check s) - - let name = "contract" -end - -module RawContractAlias = Client_aliases.Alias (ContractEntity) - -module ContractAlias = struct - let find cctxt s = - RawContractAlias.find_opt cctxt s >>=? function - | Some v -> return (s, v) - | None -> ( - Client_keys.Public_key_hash.find_opt cctxt s >>=? function - | Some v -> return (s, Contract.implicit_contract v) - | None -> failwith "no contract or key named %s" s) - - let find_key cctxt name = - Client_keys.Public_key_hash.find cctxt name >>=? fun v -> - return (name, Contract.implicit_contract v) - - let rev_find cctxt c = - match Contract.is_implicit c with - | Some hash -> ( - Client_keys.Public_key_hash.rev_find cctxt hash >>=? function - | Some name -> return_some ("key:" ^ name) - | None -> return_none) - | None -> RawContractAlias.rev_find cctxt c - - let get_contract cctxt s = - match String.split ~limit:1 ':' s with - | ["key"; key] -> find_key cctxt key - | _ -> find cctxt s - - let autocomplete cctxt = - Client_keys.Public_key_hash.autocomplete cctxt >>=? fun keys -> - RawContractAlias.autocomplete cctxt >>=? fun contracts -> - return (List.map (( ^ ) "key:") keys @ contracts) - - let alias_param ?(name = "name") ?(desc = "existing contract alias") next = - let desc = - desc ^ "\n" - ^ "Can be a contract alias or a key alias (autodetected in order).\n\ - Use 'key:name' to force the later." - in - Clic.( - param - ~name - ~desc - (parameter ~autocomplete (fun cctxt p -> get_contract cctxt p)) - next) - - let find_destination cctxt s = - match String.split ~limit:1 ':' s with - | ["alias"; alias] -> find cctxt alias - | ["key"; text] -> - Client_keys.Public_key_hash.find cctxt text >>=? fun v -> - return (s, Contract.implicit_contract v) - | _ -> ( - find cctxt s >>= function - | Ok v -> return v - | Error k_errs -> ( - ContractEntity.of_source s >>= function - | Ok v -> return (s, v) - | Error c_errs -> Lwt.return_error (k_errs @ c_errs))) - - let destination_parameter () = - Clic.parameter - ~autocomplete:(fun cctxt -> - autocomplete cctxt >>=? fun list1 -> - Client_keys.Public_key_hash.autocomplete cctxt >>=? fun list2 -> - return (list1 @ list2)) - find_destination - - let destination_param ?(name = "dst") ?(desc = "destination contract") next = - let desc = - String.concat - "\n" - [ - desc; - "Can be an alias, a key, or a literal (autodetected in order).\n\ - Use 'text:literal', 'alias:name', 'key:name' to force."; - ] - in - Clic.param ~name ~desc (destination_parameter ()) next - - let destination_arg ?(name = "dst") ?(doc = "destination contract") () = - let doc = - String.concat - "\n" - [ - doc; - "Can be an alias, a key, or a literal (autodetected in order).\n\ - Use 'text:literal', 'alias:name', 'key:name' to force."; - ] - in - Clic.arg ~long:name ~doc ~placeholder:name (destination_parameter ()) - - let name cctxt contract = - rev_find cctxt contract >>=? function - | None -> return (Contract.to_b58check contract) - | Some name -> return name -end - -let list_contracts cctxt = - RawContractAlias.load cctxt >>=? fun raw_contracts -> - List.map_s (fun (n, v) -> Lwt.return ("", n, v)) raw_contracts - >>= fun contracts -> - Client_keys.Public_key_hash.load cctxt >>=? fun keys -> - (* List accounts (implicit contracts of identities) *) - List.map_es - (fun (n, v) -> - RawContractAlias.mem cctxt n >>=? fun mem -> - let p = if mem then "key:" else "" in - let v' = Contract.implicit_contract v in - return (p, n, v')) - keys - >>=? fun accounts -> return (contracts @ accounts) - -let get_delegate cctxt ~chain ~block source = - Alpha_services.Contract.delegate_opt cctxt (chain, block) source diff --git a/src/proto_012_Psithaca/lib_client/client_proto_contracts.mli b/src/proto_012_Psithaca/lib_client/client_proto_contracts.mli deleted file mode 100644 index fcef44b21f11..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_contracts.mli +++ /dev/null @@ -1,74 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Clic - -module RawContractAlias : Client_aliases.Alias with type t = Contract.t - -module ContractAlias : sig - val get_contract : - #Client_context.wallet -> string -> (string * Contract.t) tzresult Lwt.t - - val alias_param : - ?name:string -> - ?desc:string -> - ('a, (#Client_context.wallet as 'wallet)) params -> - (string * Contract.t -> 'a, 'wallet) params - - val find_destination : - #Client_context.wallet -> string -> (string * Contract.t) tzresult Lwt.t - - val destination_param : - ?name:string -> - ?desc:string -> - ('a, (#Client_context.wallet as 'wallet)) params -> - (string * Contract.t -> 'a, 'wallet) params - - val destination_arg : - ?name:string -> - ?doc:string -> - unit -> - ((string * Contract.t) option, #Client_context.wallet) Clic.arg - - val rev_find : - #Client_context.wallet -> Contract.t -> string option tzresult Lwt.t - - val name : #Client_context.wallet -> Contract.t -> string tzresult Lwt.t - - val autocomplete : #Client_context.wallet -> string list tzresult Lwt.t -end - -val list_contracts : - #Client_context.wallet -> - (string * string * RawContractAlias.t) list tzresult Lwt.t - -val get_delegate : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Contract.t -> - public_key_hash option tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_client/client_proto_fa12.ml b/src/proto_012_Psithaca/lib_client/client_proto_fa12.ml deleted file mode 100644 index fb7e31dc856b..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_fa12.ml +++ /dev/null @@ -1,975 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol_client_context -open Protocol -open Alpha_context -open Tezos_micheline - -type error += Contract_has_no_script of Contract.t - -type error += Contract_has_no_storage of Contract.t - -type error += Entrypoint_mismatch of string * (Script.expr * Script.expr) option - -type error += Action_unwrapping_error of string * Script.expr - -type error += Not_a_viewable_entrypoint of string - -type error += Not_an_entrypoint of Script.expr - -type error += Not_enough_balance of Z.t * Z.t - -type error += Not_enough_allowance of Z.t * Z.t - -type error += Unsafe_allowance_change of Z.t - -type error += Unexpected_error of Script.location * Script.expr - -let entrypoint_mismatch_explanation ppf (name, ty) = - match ty with - | None -> Format.fprintf ppf "Entrypoint %s is missing" name - | Some (ty, expected) -> - Format.fprintf - ppf - "Entrypoint \"%s\" has type @[%a@], but should have type @[%a@]" - name - Michelson_v1_printer.print_expr - ty - Michelson_v1_printer.print_expr - expected - -let () = - register_error_kind - `Permanent - ~id:"fa12ContractHasNoScript" - ~title:"The given contract is not a smart contract" - ~description:"An FA1.2 command has referenced a scriptless contract." - ~pp:(fun ppf contract -> - Format.fprintf - ppf - "Contract %a is not a smart contract, it has no script." - Contract.pp - contract) - Data_encoding.(obj1 (req "contract" Contract.encoding)) - (function Contract_has_no_script c -> Some c | _ -> None) - (fun c -> Contract_has_no_script c) ; - register_error_kind - `Permanent - ~id:"fa12ContractHasNoStorage" - ~title:"The given contract has no storage" - ~description: - "An FA1.2 command made a call on a contract that has no storage." - ~pp:(fun ppf contract -> - Format.fprintf ppf "Contract %a has no storage." Contract.pp contract) - Data_encoding.(obj1 (req "contract" Contract.encoding)) - (function Contract_has_no_storage c -> Some c | _ -> None) - (fun c -> Contract_has_no_storage c) ; - register_error_kind - `Permanent - ~id:"entrypointMismatch" - ~title:"The given contract does not implement the FA1.2 interface" - ~description: - "An FA1.2 command has referenced a smart contract whose script does not \ - implement at least one FA1.2 entrypoint, or with an incompatible type. \ - See TZIP-7 \ - (https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-7/tzip-7.md) \ - for documentation on FA1.2." - ~pp:(fun ppf (name, ty) -> - Format.fprintf - ppf - "Not a supported FA1.2 contract.@\n%a." - entrypoint_mismatch_explanation - (name, ty)) - Data_encoding.( - obj2 - (req "name" string) - (req "type" (option (tup2 Script.expr_encoding Script.expr_encoding)))) - (function Entrypoint_mismatch (n, t) -> Some (n, t) | _ -> None) - (fun (n, t) -> Entrypoint_mismatch (n, t)) ; - register_error_kind - `Permanent - ~id:"actionUnwrappingError" - ~title:"The argument is not for an FA1.2 parameter" - ~description: - "The argument's type does not correspond to that of the corresponding \ - FA1.2 entrypoint." - ~pp:(fun ppf (entrypoint, expr) -> - Format.fprintf - ppf - "Not a supported FA1.2 entrypoint argument.@\nEntrypoint: %s@\n%a." - entrypoint - Michelson_v1_printer.print_expr - expr) - Data_encoding.( - obj2 (req "entrypoint" string) (req "expr" Script.expr_encoding)) - (function Action_unwrapping_error (s, e) -> Some (s, e) | _ -> None) - (fun (s, e) -> Action_unwrapping_error (s, e)) ; - register_error_kind - `Permanent - ~id:"notAViewableEntrypoint" - ~title:"The entrypoint is not viewable" - ~description: - "A transaction made a call on an entrypoint expecting it to implement \ - the 'view' type." - ~pp:(fun ppf entrypoint -> - Format.fprintf ppf "Entrypoint %s is not viewable." entrypoint) - Data_encoding.(obj1 (req "entrypoint" string)) - (function Not_a_viewable_entrypoint e -> Some e | _ -> None) - (fun e -> Not_a_viewable_entrypoint e) ; - register_error_kind - `Permanent - ~id:"notAnEntrypoint" - ~title:"The expression is not for an entrypoint" - ~description: - "The parameter value of the contract call refers to a non-existing \ - entrypoint." - ~pp:(fun ppf param -> - Format.fprintf - ppf - "Not a parameter for an entrypoint.@\n%a." - Michelson_v1_printer.print_expr - param) - Data_encoding.(obj1 (req "param" Script.expr_encoding)) - (function Not_an_entrypoint e -> Some e | _ -> None) - (fun e -> Not_an_entrypoint e) ; - register_error_kind - `Permanent - ~id:"notEnoughBalance" - ~title:"The sender does not have enough balance" - ~description: - "An FA1.2 transfer failed because the sender does not have enough \ - balance." - ~pp:(fun ppf (required, present) -> - Format.fprintf - ppf - "Not enough balance.@\nRequired: %a.@\nPresent: %a." - Z.pp_print - required - Z.pp_print - present) - Data_encoding.(obj2 (req "present" n) (req "required" n)) - (function Not_enough_balance (p, r) -> Some (p, r) | _ -> None) - (fun (p, r) -> Not_enough_balance (p, r)) ; - register_error_kind - `Permanent - ~id:"notEnoughAllowance" - ~title:"The sender does not have enough allowance" - ~description: - "An FA1.2 transfer failed because the receiver does not have enough \ - allowance to ask for a transfer from the sender." - ~pp:(fun ppf (required, present) -> - Format.fprintf - ppf - "Not enough allowance.@\nRequired: %a.@\nPresent: %a." - Z.pp_print - required - Z.pp_print - present) - Data_encoding.(obj2 (req "present" n) (req "required" n)) - (function Not_enough_allowance (p, r) -> Some (p, r) | _ -> None) - (fun (p, r) -> Not_enough_allowance (p, r)) ; - register_error_kind - `Permanent - ~id:"unsafeAllowanceChange" - ~title:"The allowance change is unsafe" - ~description: - "An FA1.2 non-zero allowance change failed because the current allowance \ - is non-zero. For more explanation on why such allowance change is \ - unsafe, please look at TZIP-7 \ - (https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-7/tzip-7.md#approve)." - ~pp:(fun ppf previous -> - Format.fprintf - ppf - "Unsafe allowance change@\nPrevious: %a." - Z.pp_print - previous) - Data_encoding.(obj1 (req "previous" n)) - (function Unsafe_allowance_change p -> Some p | _ -> None) - (fun p -> Unsafe_allowance_change p) ; - register_error_kind - `Permanent - ~id:"fa12UnexpectedError" - ~title:"Unexpected error during FA1.2 contract interpretation" - ~description: - "An unexpected Michelson error was reached during the interpretation of \ - an FA1.2 contract." - ~pp:(fun ppf (loc, expr) -> - Format.fprintf - ppf - "An unexpected error was reached at location %d with: %a." - loc - Michelson_v1_printer.print_expr - expr) - Data_encoding.( - obj2 - (req "location" Script.location_encoding) - (req "value" Script.expr_encoding)) - (function Unexpected_error (loc, expr) -> Some (loc, expr) | _ -> None) - (fun (loc, expr) -> Unexpected_error (loc, expr)) - -let callback_encoding = - Data_encoding.( - conv - (fun (c, e) -> (c, Option.value ~default:"" e)) - (fun (c, e) -> (c, if String.equal e "" then None else Some e)) - (tup2 Contract.encoding Variable.string)) - -(** Michelson combinators *) - -let pair ~loc a b = Micheline.Prim (loc, Script.D_Pair, [a; b], []) - -let nat ~loc i = Micheline.Int (loc, i) - -let unit ~loc = Micheline.Prim (loc, Script.D_Unit, [], []) - -let bytes ~loc b = Micheline.Bytes (loc, b) - -let address ~loc addr = - bytes ~loc (Data_encoding.Binary.to_bytes_exn Contract.encoding addr) - -let callback ~loc ?entrypoint addr = - bytes - ~loc - (Data_encoding.Binary.to_bytes_exn callback_encoding (addr, entrypoint)) - -(** Types *) - -(** Michelson type combinators: produce a Michelson node of the - expected type, and a function to check another node is - syntactically equivalent. *) -type type_eq_combinator = Script.node * (Script.node -> bool) - -(** [t_pair ~loc l] takes a list of types and respective equivalence - check functions, and returns a type of n-ary pair of such types and - a function checking syntactical equivalence with another node. *) -let t_pair ~loc l : type_eq_combinator = - let (values, are_ty) = List.split l in - let is_pair p = - match p with - | Micheline.Prim (_, Script.T_pair, l, _) -> ( - let res = - List.for_all2 - ~when_different_lengths:() - (fun is_ty v -> is_ty v) - are_ty - l - in - match res with Ok b -> b | Error () -> false) - | _ -> false - in - (Micheline.Prim (loc, Script.T_pair, values, []), is_pair) - -(** [t_unit ~loc] returns a Micheline node for the `unit` type, and - a function checking another node is syntactically equivalent. *) -let t_unit ~loc : type_eq_combinator = - let is_unit p = - match p with Micheline.Prim (_, Script.T_unit, [], _) -> true | _ -> false - in - (Micheline.Prim (loc, Script.T_unit, [], []), is_unit) - -(** [t_nat ~loc] returns a Micheline node for the `nat` type, and - a function checking another node is syntactically equivalent. *) -let t_nat ~loc : type_eq_combinator = - let is_nat p = - match p with Micheline.Prim (_, Script.T_nat, [], _) -> true | _ -> false - in - (Micheline.Prim (loc, Script.T_nat, [], []), is_nat) - -(** [t_address ~loc] returns a Micheline node for the `address` - type, and a function checking another node is syntactically - equivalent. *) -let t_address ~loc : type_eq_combinator = - let is_address p = - match p with - | Micheline.Prim (_, Script.T_address, [], _) -> true - | _ -> false - in - (Micheline.Prim (loc, Script.T_address, [], []), is_address) - -(** [t_contract ~loc (c, is_c)] takes a node representing a Michelson - type and its own syntactical equivalence checker, and returns a - Micheline node for the type `contract c`, and a function checking - another node is syntactically equivalent. *) -let t_contract ~loc (a, is_a) : type_eq_combinator = - let is_contract c = - match c with - | Micheline.Prim (_, Script.T_contract, [a], _) -> is_a a - | _ -> false - in - (Micheline.Prim (loc, Script.T_contract, [a], []), is_contract) - -(** [t_view ~loc a b] takes two node [a] and [b] and their syntactical - equivalence checking functions, and returns a Micheline node for - the `view a b` type, and a function checking another node is - syntactically equivalent. The view type is defined by - [TZIP4](https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-4/tzip-4.md). - *) -let t_view ~loc a b : type_eq_combinator = t_pair ~loc [a; t_contract ~loc b] - -(** * Actions *) - -(** Corresponds to - [TZIP7](https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-7/tzip-7.md) - entrypoints. *) - -(** A callback from a view can be on a specific entrypoint of the - contract, or the default one if not specified. *) -type callback_contract = Contract.t * string option - -type action = - | Transfer of Contract.t * Contract.t * Z.t - | Approve of Contract.t * Z.t - | Get_allowance of Contract.t * Contract.t * callback_contract - | Get_balance of Contract.t * callback_contract - | Get_total_supply of callback_contract - -let print_callback_contract ppf (c, etp) = - Format.fprintf - ppf - "%a%s" - Contract.pp - c - (match etp with None | Some "" -> "" | Some etp -> "%" ^ etp) - -let print_action ppf = function - | Transfer (src, dst, amount) -> - Format.fprintf - ppf - "Transfer (%a, %a, %a)" - Contract.pp - src - Contract.pp - dst - Z.pp_print - amount - | Approve (addr, amount) -> - Format.fprintf ppf "Approve (%a, %a)" Contract.pp addr Z.pp_print amount - | Get_allowance (src, dst, callback) -> - Format.fprintf - ppf - "Get_allowance (%a, %a, %a)" - Contract.pp - src - Contract.pp - dst - print_callback_contract - callback - | Get_balance (addr, callback) -> - Format.fprintf - ppf - "Get_balance (%a, %a)" - Contract.pp - addr - print_callback_contract - callback - | Get_total_supply callback -> - Format.fprintf - ppf - "Get_total_supply (%a)" - print_callback_contract - callback - -let transfer_encoding = - Data_encoding.( - case - ~title:"transfer" - (Tag 0) - (obj3 - (req "transfer_source" Contract.encoding) - (req "transfer_destination" Contract.encoding) - (req "transfer_amount" n)) - (function - | Transfer (src, dst, amount) -> Some (src, dst, amount) | _ -> None) - (fun (src, dst, amount) -> Transfer (src, dst, amount))) - -let approve_encoding = - Data_encoding.( - case - ~title:"approve" - (Tag 1) - (obj2 (req "approve_address" Contract.encoding) (req "approve_amount" n)) - (function Approve (addr, amount) -> Some (addr, amount) | _ -> None) - (fun (addr, amount) -> Approve (addr, amount))) - -let getBalance_encoding = - Data_encoding.( - case - ~title:"getBalance" - (Tag 2) - (obj2 - (req "getBalance_address" Contract.encoding) - (req "getBalance_callback" callback_encoding)) - (function - | Get_balance (addr, callback) -> Some (addr, callback) | _ -> None) - (fun (addr, callback) -> Get_balance (addr, callback))) - -let getAllowance_encoding = - Data_encoding.( - case - ~title:"getAllowance" - (Tag 3) - (obj3 - (req "getAllowance_source" Contract.encoding) - (req "getAllowance_destination" Contract.encoding) - (req "getAllowance_callback" callback_encoding)) - (function - | Get_allowance (src, dst, callback) -> Some (src, dst, callback) - | _ -> None) - (fun (src, dst, callback) -> Get_allowance (src, dst, callback))) - -let getTotalSupply_encoding = - Data_encoding.( - case - ~title:"getTotalSupply" - (Tag 4) - (obj1 (req "getTotalSupply_callback" callback_encoding)) - (function Get_total_supply callback -> Some callback | _ -> None) - (fun callback -> Get_total_supply callback)) - -let action_encoding = - Data_encoding.union - [ - transfer_encoding; - approve_encoding; - getBalance_encoding; - getAllowance_encoding; - getTotalSupply_encoding; - ] - -let transfer_type ~loc = - t_pair ~loc [t_address ~loc; t_address ~loc; t_nat ~loc] - -let approve_type ~loc = t_pair ~loc [t_address ~loc; t_nat ~loc] - -let getAllowance_type ~loc = - t_view ~loc (t_pair ~loc [t_address ~loc; t_address ~loc]) (t_nat ~loc) - -let getBalance_type ~loc = t_view ~loc (t_address ~loc) (t_nat ~loc) - -let getTotalSupply_type ~loc = t_view ~loc (t_unit ~loc) (t_nat ~loc) - -let standard_entrypoints = - let loc = -1 in - [ - ("transfer", transfer_type ~loc); - ("approve", approve_type ~loc); - ("getAllowance", getAllowance_type ~loc); - ("getBalance", getBalance_type ~loc); - ("getTotalSupply", getTotalSupply_type ~loc); - ] - -let view_input ~loc action = - match action with - | Get_allowance (source, destination, _) -> - pair ~loc (address ~loc source) (address ~loc destination) - | Get_balance (addr, _) -> address ~loc addr - | Get_total_supply _ -> unit ~loc - | _ -> unit ~loc - -let action_to_expr ~loc action = - match action with - | Transfer (source, destination, amount) -> - pair - ~loc - (address ~loc source) - (pair ~loc (address ~loc destination) (nat ~loc amount)) - | Approve (addr, amount) -> pair ~loc (address ~loc addr) (nat ~loc amount) - | Get_allowance (_, _, (cb, entrypoint)) -> - let input = view_input ~loc action in - pair ~loc input (callback ~loc ?entrypoint cb) - | Get_balance (_, (cb, entrypoint)) -> - let input = view_input ~loc action in - pair ~loc input (callback ~loc ?entrypoint cb) - | Get_total_supply (cb, entrypoint) -> - let input = view_input ~loc action in - pair ~loc input (callback ~loc ?entrypoint cb) - -let parse_address error = function - | Micheline.Bytes (_, b) -> - ok @@ Data_encoding.Binary.of_bytes_exn Contract.encoding b - | String (_, s) -> ( - match Contract.of_b58check s with Ok c -> ok c | Error _ -> error ()) - | _ -> error () - -let parse_callback error expr = - let of_b58_check (c, entrypoint) = - match Contract.of_b58check c with - | Ok c -> ok (c, entrypoint) - | Error _ -> error () - in - match expr with - | Micheline.Bytes (_, b) -> ( - match Data_encoding.Binary.of_bytes callback_encoding b with - | Ok (c, entrypoint) -> ok (c, entrypoint) - | Error _ -> error ()) - | String (_, s) -> ( - match String.index_opt s '%' with - | None -> of_b58_check (s, None) - | Some pos -> ( - let len = String.length s - pos - 1 in - let name = String.sub s (pos + 1) len in - match (String.sub s 0 pos, name) with - | (addr, "default") -> of_b58_check (addr, None) - | (addr, name) -> of_b58_check (addr, Some name))) - | _ -> error () - -let action_of_expr ~entrypoint expr = - let open Micheline in - let error () = - error (Action_unwrapping_error (entrypoint, Micheline.strip_locations expr)) - in - match (entrypoint, expr) with - (* Transfer operation before comb pairs. *) - | ( "transfer", - Prim - ( _, - Script.D_Pair, - [ - ((Bytes (_, _) | String (_, _)) as source); - Prim - ( _, - Script.D_Pair, - [ - ((Bytes (_, _) | String (_, _)) as destination); - Int (_, amount); - ], - _ ); - ], - _ ) ) - (* Transfer operation since Edo comb pairs are now directly interpreted as a - tuple of 3 elements instead of a pair inside a pair. *) - | ( "transfer", - Prim - ( _, - Script.D_Pair, - [ - ((Bytes (_, _) | String (_, _)) as source); - ((Bytes (_, _) | String (_, _)) as destination); - Int (_, amount); - ], - _ ) ) -> - parse_address error source >>? fun source -> - parse_address error destination >>? fun destination -> - ok (Transfer (source, destination, amount)) - | ( "approve", - Prim - ( _, - Script.D_Pair, - [((Bytes (_, _) | String (_, _)) as addr); Int (_, amount)], - _ ) ) -> - parse_address error addr >>? fun addr -> ok (Approve (addr, amount)) - | ( "getBalance", - Prim - ( _, - Script.D_Pair, - [ - ((Bytes (_, _) | String (_, _)) as addr); - ((Bytes (_, _) | String (_, _)) as cb); - ], - _ ) ) -> - parse_address error addr >>? fun addr -> - parse_callback error cb >>? fun callback -> - ok (Get_balance (addr, callback)) - | ( "getAllowance", - Prim - ( _, - Script.D_Pair, - [ - Prim - ( _, - Script.D_Pair, - [ - ((Bytes (_, _) | String (_, _)) as source); - ((Bytes (_, _) | String (_, _)) as destination); - ], - _ ); - ((Bytes (_, _) | String (_, _)) as contract); - ], - _ ) ) -> - parse_address error source >>? fun source -> - parse_address error destination >>? fun destination -> - parse_callback error contract >>? fun callback -> - ok (Get_allowance (source, destination, callback)) - | ( "getTotalSupply", - Prim - ( _, - Script.D_Pair, - [ - Prim (_, Script.D_Unit, [], _); - ((Bytes (_, _) | String (_, _)) as contract); - ], - _ ) ) -> - parse_callback error contract >>? fun callback -> - ok (Get_total_supply callback) - | _ -> error () - -let find_entrypoint_in_annot error annots expr = - match List.find_opt (fun annot -> annot.[0] = '%') annots with - | Some entrypoint -> - action_of_expr - ~entrypoint:(String.sub entrypoint 1 (String.length entrypoint - 1)) - expr - | None -> error () - -let derive_action expr t_param = - let error () = error (Not_an_entrypoint (Micheline.strip_locations expr)) in - let rec derive expr t_param = - match (expr, t_param) with - | ( Micheline.Prim (_, Script.D_Left, [left], _), - Micheline.Prim (_, Script.T_or, [t_left; _], _) ) -> - derive left t_left - | ( Micheline.Prim (_, Script.D_Right, [right], _), - Micheline.Prim (_, Script.T_or, [_; t_right], _) ) -> - derive right t_right - | (_, Micheline.Prim (_, _, _, annots)) -> - find_entrypoint_in_annot error annots expr - | _ -> error () - in - derive expr t_param - -let extract_parameter contract = function - | Micheline.Seq (_, l) -> ( - List.filter_map - (function - | Micheline.Prim (_, Script.K_parameter, [param], _) -> Some param - | _ -> None) - l - |> function - | param :: _ -> ok param - | _ -> error (Contract_has_no_script contract)) - | _ -> error (Contract_has_no_script contract) - -let get_contract_parameter cctxt ~chain ~block contract = - Client_proto_context.get_script - cctxt - ~chain - ~block - contract - ~unparsing_mode:Optimized - >>=? function - | None -> fail (Contract_has_no_script contract) - | Some {code; _} -> ( - match Script_repr.force_decode code with - | Error _ -> fail (Contract_has_no_script contract) - | Ok code -> Lwt.return (extract_parameter contract (Micheline.root code)) - ) - -let convert_wrapped_parameter_into_action cctxt ~chain ~block contract param = - get_contract_parameter cctxt ~chain ~block contract >>=? fun parameter -> - Lwt.return (derive_action param parameter) - -let check_entrypoint entrypoints (name, (expected_ty, check)) = - match List.assoc_opt ~equal:String.equal name entrypoints with - | None -> error (Entrypoint_mismatch (name, None)) - | Some ty -> - if not (check (Micheline.root ty)) then - error - (Entrypoint_mismatch - (name, Some (ty, Micheline.strip_locations expected_ty))) - else Ok () - -let action_to_entrypoint = function - | Transfer (_, _, _) -> "transfer" - | Approve (_, _) -> "approve" - | Get_allowance (_, _, _) -> "getAllowance" - | Get_balance (_, _) -> "getBalance" - | Get_total_supply _ -> "getTotalSupply" - -let contract_has_fa12_interface : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - contract:Alpha_context.Contract.t -> - unit -> - unit tzresult Lwt.t = - fun cctxt ~chain ~block ~contract () -> - match Contract.is_implicit contract with - | Some _ -> fail (Contract_has_no_script contract) - | None -> - Michelson_v1_entrypoints.list_contract_entrypoints - cctxt - ~chain - ~block - ~contract - >>=? fun entrypoints -> - List.iter_e (check_entrypoint entrypoints) standard_entrypoints - |> Lwt.return - -let translate_action_to_argument action = - let entrypoint = action_to_entrypoint action in - let expr = Micheline.strip_locations (action_to_expr ~loc:() action) in - (entrypoint, Format.asprintf "%a" Michelson_v1_printer.print_expr expr) - -let parse_error = - let open Micheline in - function - | ( "NotEnoughBalance", - Prim (_, Script.D_Pair, [Int (_, required); Int (_, present)], _) ) -> - Some (Not_enough_balance (required, present)) - | ( "NotEnoughAllowance", - Prim (_, Script.D_Pair, [Int (_, required); Int (_, present)], _) ) -> - Some (Not_enough_allowance (required, present)) - | ("UnsafeAllowanceChange", Int (_, previous)) -> - Some (Unsafe_allowance_change previous) - | _ -> None - -let extract_error trace = - let open Micheline in - TzTrace.fold - (fun _ error -> - match error with - | Environment.Ecoproto_error (Script_interpreter.Reject (loc, param, _)) - -> ( - match root param with - | Prim (_, Script.D_Pair, [String (_, error); res], _) -> - parse_error (error, res) - | _ -> Some (Unexpected_error (loc, param))) - | _ -> None) - None - trace - -let call_contract (cctxt : #Protocol_client_context.full) ~chain ~block - ?confirmations ?dry_run ?verbose_signing ?branch ~source ~src_pk ~src_sk - ~contract ~action ~tez_amount ?fee ?gas_limit ?storage_limit ?counter - ~fee_parameter () = - contract_has_fa12_interface cctxt ~chain ~block ~contract () >>=? fun () -> - let (entrypoint, arg) = translate_action_to_argument action in - Client_proto_context.transfer - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?branch - ~source - ~src_pk - ~src_sk - ~destination:contract - ~arg - ~amount:tez_amount - ~entrypoint - ?fee - ?gas_limit - ?storage_limit - ?counter - ~fee_parameter - ?verbose_signing - () - >>= function - | Ok res -> return res - | Error trace -> ( - match extract_error trace with - | None -> Lwt.return (Error trace) - | Some error -> fail error) - -type token_transfer = { - token_contract : string; - destination : string; - amount : Z.t; - tez_amount : string option; - fee : string option; - gas_limit : Gas.Arith.integral option; - storage_limit : Z.t option; -} - -let token_transfer_encoding = - let open Data_encoding in - conv - (fun { - token_contract; - destination; - amount; - tez_amount; - fee; - gas_limit; - storage_limit; - } -> - ( token_contract, - destination, - amount, - tez_amount, - fee, - gas_limit, - storage_limit )) - (fun ( token_contract, - destination, - amount, - tez_amount, - fee, - gas_limit, - storage_limit ) -> - { - token_contract; - destination; - amount; - tez_amount; - fee; - gas_limit; - storage_limit; - }) - (obj7 - (req "token_contract" string) - (req "destination" string) - (req "amount" z) - (opt "tez-amount" string) - (opt "fee" string) - (opt "gas-limit" Gas.Arith.n_integral_encoding) - (opt "storage-limit" z)) - -let tez_of_string_exn index field s = - match Tez.of_string s with - | Some t -> ok t - | None -> - error_with - "Invalid %s notation at entry %i, field \"%s\": %s" - Client_proto_args.tez_sym - index - field - s - -let tez_of_opt_string_exn index field s = - Option.map_e (tez_of_string_exn index field) s - -let build_transaction_operation ?(tez_amount = Tez.zero) ?fee ?gas_limit - ?storage_limit token action = - let entrypoint = action_to_entrypoint action in - let parameters = - Script.lazy_expr (Micheline.strip_locations (action_to_expr ~loc:() action)) - in - let operation = - Transaction - {amount = tez_amount; parameters; destination = token; entrypoint} - in - Injection.prepare_manager_operation - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - operation - -let prepare_single_token_transfer cctxt ?default_fee ?default_gas_limit - ?default_storage_limit ~chain ~block src index transfer = - Client_proto_contracts.ContractAlias.find_destination - cctxt - transfer.token_contract - >>=? fun (_, token) -> - contract_has_fa12_interface cctxt ~chain ~block ~contract:token () - >>=? fun () -> - Client_proto_contracts.ContractAlias.find_destination - cctxt - transfer.destination - >>=? fun (_, dest) -> - tez_of_opt_string_exn index "tez_amount" transfer.tez_amount - >>?= fun tez_amount -> - tez_of_opt_string_exn index "fee" transfer.fee >>?= fun transfer_fee -> - let fee = Option.either transfer_fee default_fee in - let gas_limit = Option.either transfer.gas_limit default_gas_limit in - let storage_limit = - Option.either transfer.storage_limit default_storage_limit - in - let action = Transfer (src, dest, transfer.amount) in - let operation = - build_transaction_operation - ?tez_amount - ?fee - ?gas_limit - ?storage_limit - token - action - in - return (Annotated_manager_operation.Annotated_manager_operation operation) - -let inject_token_transfer_batch (cctxt : #Protocol_client_context.full) ~chain - ~block ?confirmations ?dry_run ?verbose_signing ~sender ~source ~src_pk - ~src_sk ~token_transfers ~fee_parameter ?counter ?default_fee - ?default_gas_limit ?default_storage_limit () = - List.mapi_ep - (prepare_single_token_transfer - cctxt - ?default_fee - ?default_gas_limit - ?default_storage_limit - ~chain - ~block - sender) - token_transfers - >>=? fun contents -> - let (Manager_list contents) = - Annotated_manager_operation.manager_of_list contents - in - Injection.inject_manager_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ~source - ~fee:(Limit.of_option default_fee) - ~gas_limit:(Limit.of_option default_gas_limit) - ~storage_limit:(Limit.of_option default_storage_limit) - ?counter - ~src_pk - ~src_sk - ~fee_parameter - contents - >>= function - | Ok _ -> return () - | Error trace -> ( - match extract_error trace with - | None -> Lwt.return (Error trace) - | Some error -> fail error) - -let is_viewable_action action = - match action with - | Get_balance (_, _) | Get_allowance (_, _, _) | Get_total_supply _ -> - return () - | _ -> fail (Not_a_viewable_entrypoint (action_to_entrypoint action)) - -let run_view_action (cctxt : #Protocol_client_context.full) ~chain ~block - ?source ~contract ~action ?payer ?gas ~unparsing_mode () = - is_viewable_action action >>=? fun () -> - contract_has_fa12_interface cctxt ~chain ~block ~contract () >>=? fun () -> - let entrypoint = action_to_entrypoint action in - let input = Micheline.strip_locations (view_input ~loc:() action) in - Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> - Plugin.RPC.Scripts.run_view - cctxt - (chain, block) - ~contract - ~input - ~chain_id - ?source - ?payer - ?gas - ~entrypoint - ~unparsing_mode - ~now:None - ~level:None - -let () = - Data_encoding.( - Registration.register - @@ def (Protocol.name ^ ".fa1.2.token_transfer") token_transfer_encoding) diff --git a/src/proto_012_Psithaca/lib_client/client_proto_fa12.mli b/src/proto_012_Psithaca/lib_client/client_proto_fa12.mli deleted file mode 100644 index 8022bd2d7986..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_fa12.mli +++ /dev/null @@ -1,161 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** [Client_proto_fa12] implements built-in support for the - {{:https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-7/tzip-7.md} - FA1.2} standard. This module features functions to check whether a - contract implements the standard interface and to interact with - such contracts using high-level [actions] that model the entrypoint - calls. - - This module also provides functions to unwrap [Micheline] values - into [actions], which can be useful for indexers or applications - using this module to interpret transactions on FA1.2 contracts as - FA1.2 operations. *) - -open Protocol -open Alpha_context -open Protocol_client_context - -(** A callback contract is represented by an address and a possible - entrypoint on which the transaction is done. *) -type callback_contract = Contract.t * string option - -type action = - | Transfer of Contract.t * Contract.t * Z.t - | Approve of Contract.t * Z.t - | Get_allowance of Contract.t * Contract.t * callback_contract - | Get_balance of Contract.t * callback_contract - | Get_total_supply of callback_contract - -val print_action : Format.formatter -> action -> unit - -val action_encoding : action Data_encoding.encoding - -val action_to_expr : - loc:'loc -> action -> ('loc, Script.prim) Tezos_micheline.Micheline.node - -val action_of_expr : - entrypoint:string -> - (_, Script.prim) Tezos_micheline.Micheline.node -> - action tzresult - -(** [convert_wrapped_parameter_into_action ccctx ~chain ~block - ~contract parameter] converts a wrapped FA1.2 contract [parameter] - into the corresponding FA1.2 [action]. - - That is, it takes a contract parameter on the form [C_1 .. (C_n - ... ))] where [C_1 ... C_n] is a sequence of - [Left]/[Right] constructors. It finds the entrypoint corresponding - to that path in [contract]'s interface. The result of the function - is the [] applied to the [action] - corresponding to that entrypoint. *) -val convert_wrapped_parameter_into_action : - full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Contract.t -> - Script.node -> - action tzresult Lwt.t - -(** Check whether a contract has an FA1.2 interface. *) -val contract_has_fa12_interface : - full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - contract:Alpha_context.Contract.t -> - unit -> - unit tzresult Lwt.t - -val call_contract : - full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?branch:int -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - contract:Contract.t -> - action:action -> - tez_amount:Tez.t -> - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - ?counter:Z.t -> - fee_parameter:Injection.fee_parameter -> - unit -> - (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult - Lwt.t - -(** Single transfer operation. *) -type token_transfer = { - token_contract : string; - destination : string; - amount : Z.t; - tez_amount : string option; - fee : string option; - gas_limit : Gas.Arith.integral option; - storage_limit : Z.t option; -} - -val token_transfer_encoding : token_transfer Data_encoding.t - -(** Inject a batch of token transfers. *) -val inject_token_transfer_batch : - full -> - chain:Chain_services.chain -> - block:Block_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - sender:Contract.t -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - token_transfers:token_transfer list -> - fee_parameter:Injection.fee_parameter -> - ?counter:counter -> - ?default_fee:Tez.t -> - ?default_gas_limit:Gas.Arith.integral -> - ?default_storage_limit:counter -> - unit -> - unit tzresult Lwt.t - -(** Run the action without injecting it. Only for views. *) -val run_view_action : - full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?source:Contract.t -> - contract:Contract.t -> - action:action -> - ?payer:Contract.t -> - ?gas:Gas.Arith.integral -> - unparsing_mode:Script_ir_translator.unparsing_mode -> - unit -> - Script.expr tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_client/client_proto_multisig.ml b/src/proto_012_Psithaca/lib_client/client_proto_multisig.ml deleted file mode 100644 index 7ffb4f883006..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_multisig.ml +++ /dev/null @@ -1,1210 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol_client_context -open Protocol -open Alpha_context -open Michelson_v1_helpers - -type error += Contract_has_no_script of Contract.t - -type error += Not_a_supported_multisig_contract of Script_expr_hash.t - -type error += Contract_has_no_storage of Contract.t - -type error += Contract_has_unexpected_storage of Contract.t - -type error += Invalid_signature of signature - -type error += Not_enough_signatures of int * int - -type error += Action_deserialisation_error of Script.expr - -type error += Bytes_deserialisation_error of Bytes.t - -type error += Bad_deserialized_contract of (Contract.t * Contract.t) - -type error += Bad_deserialized_counter of (counter * counter) - -type error += Non_positive_threshold of int - -type error += Threshold_too_high of int * int - -type error += Unsupported_feature_generic_call of Script.expr - -type error += Unsupported_feature_generic_call_ty of Script.expr - -type error += Unsupported_feature_lambda of string - -type error += - | Ill_typed_argument of Contract.t * string * Script.expr * Script.expr - -type error += Ill_typed_lambda of Script.expr * Script.expr - -let () = - register_error_kind - `Permanent - ~id:"contractHasNoScript" - ~title: - "The given contract is not a multisig contract because it has no script" - ~description: - "A multisig command has referenced a scriptless smart contract instead \ - of a multisig smart contract." - ~pp:(fun ppf contract -> - Format.fprintf ppf "Contract has no script %a." Contract.pp contract) - Data_encoding.(obj1 (req "contract" Contract.encoding)) - (function Contract_has_no_script c -> Some c | _ -> None) - (fun c -> Contract_has_no_script c) ; - register_error_kind - `Permanent - ~id:"notASupportedMultisigContract" - ~title:"The given contract is not one of the supported contracts" - ~description: - "A multisig command has referenced a smart contract whose script is not \ - one of the known multisig contract scripts." - ~pp:(fun ppf hash -> - Format.fprintf - ppf - "Not a supported multisig contract.@\n\ - The hash of this script is %a, it was not found among in the list of \ - known multisig script hashes." - Script_expr_hash.pp - hash) - Data_encoding.(obj1 (req "hash" Script_expr_hash.encoding)) - (function Not_a_supported_multisig_contract h -> Some h | _ -> None) - (fun h -> Not_a_supported_multisig_contract h) ; - register_error_kind - `Permanent - ~id:"contractHasNoStorage" - ~title: - "The given contract is not a multisig contract because it has no storage" - ~description: - "A multisig command has referenced a smart contract without storage \ - instead of a multisig smart contract." - ~pp:(fun ppf contract -> - Format.fprintf ppf "Contract has no storage %a." Contract.pp contract) - Data_encoding.(obj1 (req "contract" Contract.encoding)) - (function Contract_has_no_storage c -> Some c | _ -> None) - (fun c -> Contract_has_no_storage c) ; - register_error_kind - `Permanent - ~id:"contractHasUnexpectedStorage" - ~title: - "The storage of the given contract is not of the shape expected for a \ - multisig contract" - ~description: - "A multisig command has referenced a smart contract whose storage is of \ - a different shape than the expected one." - ~pp:(fun ppf contract -> - Format.fprintf - ppf - "Contract has unexpected storage %a." - Contract.pp - contract) - Data_encoding.(obj1 (req "contract" Contract.encoding)) - (function Contract_has_unexpected_storage c -> Some c | _ -> None) - (fun c -> Contract_has_unexpected_storage c) ; - register_error_kind - `Permanent - ~id:"invalidSignature" - ~title: - "The following signature did not match a public key in the given \ - multisig contract" - ~description: - "A signature was given for a multisig contract that matched none of the \ - public keys of the contract signers" - ~pp:(fun ppf s -> - Format.fprintf ppf "Invalid signature %s." (Signature.to_b58check s)) - Data_encoding.(obj1 (req "invalid_signature" Signature.encoding)) - (function Invalid_signature s -> Some s | _ -> None) - (fun s -> Invalid_signature s) ; - register_error_kind - `Permanent - ~id:"notEnoughSignatures" - ~title:"Not enough signatures were provided for this multisig action" - ~description: - "To run an action on a multisig contract, you should provide at least as \ - many signatures as indicated by the threshold stored in the multisig \ - contract." - ~pp:(fun ppf (threshold, nsigs) -> - Format.fprintf - ppf - "Not enough signatures: only %d signatures were given but the \ - threshold is currently %d" - nsigs - threshold) - Data_encoding.(obj1 (req "threshold_nsigs" (tup2 int31 int31))) - (function - | Not_enough_signatures (threshold, nsigs) -> Some (threshold, nsigs) - | _ -> None) - (fun (threshold, nsigs) -> Not_enough_signatures (threshold, nsigs)) ; - register_error_kind - `Permanent - ~id:"actionDeserialisation" - ~title:"The expression is not a valid multisig action" - ~description: - "When trying to deserialise an action from a sequence of bytes, we got \ - an expression that does not correspond to a known multisig action" - ~pp:(fun ppf e -> - Format.fprintf - ppf - "Action deserialisation error %a." - Michelson_v1_printer.print_expr - e) - Data_encoding.(obj1 (req "expr" Script.expr_encoding)) - (function Action_deserialisation_error e -> Some e | _ -> None) - (fun e -> Action_deserialisation_error e) ; - register_error_kind - `Permanent - ~id:"bytesDeserialisation" - ~title:"The byte sequence is not a valid multisig action" - ~description: - "When trying to deserialise an action from a sequence of bytes, we got \ - an error" - ~pp:(fun ppf b -> - Format.fprintf ppf "Bytes deserialisation error %s." (Bytes.to_string b)) - Data_encoding.(obj1 (req "expr" bytes)) - (function Bytes_deserialisation_error b -> Some b | _ -> None) - (fun b -> Bytes_deserialisation_error b) ; - register_error_kind - `Permanent - ~id:"badDeserializedContract" - ~title:"The byte sequence is not for the given multisig contract" - ~description: - "When trying to deserialise an action from a sequence of bytes, we got \ - an action for another multisig contract" - ~pp:(fun ppf (received, expected) -> - Format.fprintf - ppf - "Bad deserialized contract, received %a expected %a." - Contract.pp - received - Contract.pp - expected) - Data_encoding.( - obj1 (req "received_expected" (tup2 Contract.encoding Contract.encoding))) - (function Bad_deserialized_contract b -> Some b | _ -> None) - (fun b -> Bad_deserialized_contract b) ; - register_error_kind - `Permanent - ~id:"Bad deserialized counter" - ~title:"Deserialized counter does not match the stored one" - ~description: - "The byte sequence references a multisig counter that does not match the \ - one currently stored in the given multisig contract" - ~pp:(fun ppf (received, expected) -> - Format.fprintf - ppf - "Bad deserialized counter, received %d expected %d." - received - expected) - Data_encoding.(obj1 (req "received_expected" (tup2 int31 int31))) - (function - | Bad_deserialized_counter (c1, c2) -> Some (Z.to_int c1, Z.to_int c2) - | _ -> None) - (fun (c1, c2) -> Bad_deserialized_counter (Z.of_int c1, Z.of_int c2)) ; - register_error_kind - `Permanent - ~id:"thresholdTooHigh" - ~title:"Given threshold is too high" - ~description: - "The given threshold is higher than the number of keys, this would lead \ - to a frozen multisig contract" - ~pp:(fun ppf (threshold, nkeys) -> - Format.fprintf - ppf - "Threshold too high: %d expected at most %d." - threshold - nkeys) - Data_encoding.(obj1 (req "received_expected" (tup2 int31 int31))) - (function Threshold_too_high (c1, c2) -> Some (c1, c2) | _ -> None) - (fun (c1, c2) -> Threshold_too_high (c1, c2)) ; - register_error_kind - `Permanent - ~id:"nonPositiveThreshold" - ~title:"Given threshold is not positive" - ~description:"A multisig threshold should be a positive number" - ~pp:(fun ppf threshold -> - Format.fprintf ppf "Multisig threshold %d should be positive." threshold) - Data_encoding.(obj1 (req "threshold" int31)) - (function Non_positive_threshold t -> Some t | _ -> None) - (fun t -> Non_positive_threshold t) ; - register_error_kind - `Permanent - ~id:"unsupportedGenericMultisigFeature" - ~title:"Unsupported multisig feature: generic call" - ~description: - "This multisig contract does not feature calling contracts with arguments" - ~pp:(fun ppf arg -> - Format.fprintf - ppf - "This multisig contract can only transfer tokens to contracts of type \ - unit; calling a contract with argument %a is not supported." - Michelson_v1_printer.print_expr - arg) - Data_encoding.(obj1 (req "arg" Script.expr_encoding)) - (function Unsupported_feature_generic_call arg -> Some arg | _ -> None) - (fun arg -> Unsupported_feature_generic_call arg) ; - register_error_kind - `Permanent - ~id:"unsupportedGenericMultisigFeatureTy" - ~title:"Unsupported multisig feature: generic call to non-unit entrypoint" - ~description: - "This multisig contract does not feature calling contracts with arguments" - ~pp:(fun ppf ty -> - Format.fprintf - ppf - "This multisig contract can only transfer tokens to contracts of type \ - unit; calling a contract of type %a is not supported." - Michelson_v1_printer.print_expr - ty) - Data_encoding.(obj1 (req "ty" Script.expr_encoding)) - (function Unsupported_feature_generic_call_ty ty -> Some ty | _ -> None) - (fun ty -> Unsupported_feature_generic_call_ty ty) ; - register_error_kind - `Permanent - ~id:"unsupportedGenericMultisigLambda" - ~title:"Unsupported multisig feature: running lambda" - ~description:"This multisig contract does not feature running lambdas" - ~pp:(fun ppf lam -> - Format.fprintf - ppf - "This multisig contract has a fixed set of actions, it cannot run the \ - following lambda: %s." - lam) - Data_encoding.(obj1 (req "lam" string)) - (function Unsupported_feature_lambda lam -> Some lam | _ -> None) - (fun lam -> Unsupported_feature_lambda lam) ; - register_error_kind - `Permanent - ~id:"illTypedArgumentForMultisig" - ~title:"Ill-typed argument in multi-signed transfer" - ~description: - "The provided argument for a transfer from a multisig contract is \ - ill-typed" - ~pp:(fun ppf (destination, entrypoint, parameter_ty, parameter) -> - Format.fprintf - ppf - "The entrypoint %s of contract %a called from a multisig contract is \ - of type %a; the provided parameter %a is ill-typed." - entrypoint - Contract.pp - destination - Michelson_v1_printer.print_expr - parameter_ty - Michelson_v1_printer.print_expr - parameter) - Data_encoding.( - obj4 - (req "destination" Contract.encoding) - (req "entrypoint" string) - (req "parameter_ty" Script.expr_encoding) - (req "parameter" Script.expr_encoding)) - (function - | Ill_typed_argument (destination, entrypoint, parameter_ty, parameter) -> - Some (destination, entrypoint, parameter_ty, parameter) - | _ -> None) - (fun (destination, entrypoint, parameter_ty, parameter) -> - Ill_typed_argument (destination, entrypoint, parameter_ty, parameter)) ; - register_error_kind - `Permanent - ~id:"illTypedLambdaForMultisig" - ~title:"Ill-typed lambda for multi-signed transfer" - ~description: - "The provided lambda for a transfer from a multisig contract is ill-typed" - ~pp:(fun ppf (lam, exp) -> - Format.fprintf - ppf - "The provided lambda %a for multisig contract is ill-typed; %a is \ - expected." - Michelson_v1_printer.print_expr - lam - Michelson_v1_printer.print_expr - exp) - Data_encoding.( - obj2 (req "lam" Script.expr_encoding) (req "exp" Script.expr_encoding)) - (function Ill_typed_lambda (lam, exp) -> Some (lam, exp) | _ -> None) - (fun (lam, exp) -> Ill_typed_lambda (lam, exp)) - -(* The multisig contract script written by Arthur Breitman - https://github.com/murbard/smart-contracts/blob/abdb582d8f1fe7ba7eb15975867d8862cb70acfe/multisig/michelson/generic.tz *) -let multisig_script_string = - {| -parameter (or (unit %default) - (pair %main - (pair :payload - (nat %counter) # counter, used to prevent replay attacks - (or :action # payload to sign, represents the requested action - (lambda %operation unit (list operation)) - (pair %change_keys # change the keys controlling the multisig - (nat %threshold) # new threshold - (list %keys key)))) # new list of keys - (list %sigs (option signature)))); # signatures - -storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; - -code - { - UNPAIR ; - IF_LEFT - { # Default entry point: do nothing - # This entry point can be used to send tokens to this contract - DROP ; NIL operation ; PAIR } - { # Main entry point - # Assert no token was sent: - # to send tokens, the default entry point should be used - PUSH mutez 0 ; AMOUNT ; ASSERT_CMPEQ ; - SWAP ; DUP ; DIP { SWAP } ; - DIP - { - UNPAIR ; - # pair the payload with the current contract address, to ensure signatures - # can't be replayed accross different contracts if a key is reused. - DUP ; SELF ; ADDRESS ; CHAIN_ID ; PAIR ; PAIR ; - PACK ; # form the binary payload that we expect to be signed - DIP { UNPAIR @counter ; DIP { SWAP } } ; SWAP - } ; - - # Check that the counters match - UNPAIR @stored_counter; DIP { SWAP }; - ASSERT_CMPEQ ; - - # Compute the number of valid signatures - DIP { SWAP } ; UNPAIR @threshold @keys; - DIP - { - # Running count of valid signatures - PUSH @valid nat 0; SWAP ; - ITER - { - DIP { SWAP } ; SWAP ; - IF_CONS - { - IF_SOME - { SWAP ; - DIP - { - SWAP ; DIIP { DUUP } ; - # Checks signatures, fails if invalid - { DUUUP; DIP {CHECK_SIGNATURE}; SWAP; IF {DROP} {FAILWITH} }; - PUSH nat 1 ; ADD @valid } } - { SWAP ; DROP } - } - { - # There were fewer signatures in the list - # than keys. Not all signatures must be present, but - # they should be marked as absent using the option type. - FAIL - } ; - SWAP - } - } ; - # Assert that the threshold is less than or equal to the - # number of valid signatures. - ASSERT_CMPLE ; - # Assert no unchecked signature remains - IF_CONS {FAIL} {} ; - DROP ; - - # Increment counter and place in storage - DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR} ; - - # We have now handled the signature verification part, - # produce the operation requested by the signers. - IF_LEFT - { # Get operation - UNIT ; EXEC - } - { - # Change set of signatures - DIP { CAR } ; SWAP ; PAIR ; NIL operation - }; - PAIR } - } -|} - -(* Client_proto_context.originate expects the contract script as a Script.expr *) -let multisig_script : Script.expr = - Michelson_v1_parser.parse_toplevel ?check:(Some true) multisig_script_string - |> Tezos_micheline.Micheline_parser.no_parsing_error - |> function - | Error _ -> - assert false - (* This is a top level assertion, it is asserted when the client's process runs. *) - | Ok parsing_result -> parsing_result.Michelson_v1_parser.expanded - -let multisig_script_hash = - let bytes = - Data_encoding.Binary.to_bytes_exn Script.expr_encoding multisig_script - in - Script_expr_hash.hash_bytes [bytes] - -(* The previous multisig script is the only one that the client can - originate but the client knows how to interact with several - versions of the multisig contract. For each version, the description - indicates which features are available and how to interact with - the contract. *) - -type multisig_contract_description = { - hash : Script_expr_hash.t; - (* The hash of the contract script *) - requires_chain_id : bool; - (* The signatures should contain the chain identifier *) - main_entrypoint : string option; - (* name of the main entrypoint of the multisig contract, None means use the default entrypoint *) - generic : bool; - (* False means that the contract uses a custom action type, true - means that the contract expects the action as a (lambda unit - (list operation)). *) -} - -(* List of known multisig contracts hashes with their kinds *) -let known_multisig_contracts : multisig_contract_description list = - [ - { - (* First supported version of the generic multisig contract. Supports incoming - transfers from unauthenticated senders and outgoing transfers of - arbitrary operation lists. - - See docs/user/multisig.rst for more details. *) - hash = multisig_script_hash; - requires_chain_id = true; - main_entrypoint = Some "main"; - generic = true; - }; - { - (* Fourth supported version of the legacy multisig contract. This script is - functionally equivalent to the third version but uses the [DUP 2] - instruction introduced in Edo instead of the macro for [DIG 2; DUP; DUG 3]. *) - hash = - Script_expr_hash.of_b58check_exn - "exprutz4BVGJ3Qms6qjmqvUF8sEk27H1cfqhRT17qpTdhEs5hEjbWm"; - requires_chain_id = true; - main_entrypoint = None; - generic = false; - }; - { - (* Third supported version of the legacy multisig contract. This script is - functionally equivalent to the second version but uses the [DIP 2] - instruction introduced in Babylon instead of the [DIIP] macro. *) - hash = - Script_expr_hash.of_b58check_exn - "exprumpS39YZd26Cn4kyKUK5ezTR3at838iGWg7i6uETv8enDeAnfb"; - requires_chain_id = true; - main_entrypoint = None; - generic = false; - }; - { - (* Second supported version of the legacy multisig contract. This script - is the one resulting from the stitching of the Babylon protocol, the - only difference with the first version is that the chain id is part of - the data to sign. *) - hash = - Script_expr_hash.of_b58check_exn - "exprtw1v4KvQN414oEXdGuA1U3eQizuCdS8cipx8QGK8TbNLRwc3qL"; - requires_chain_id = true; - main_entrypoint = None; - generic = false; - }; - { - (* First supported version of the legacy multisig contract. This script should not - be used anymore because it is subject to a small replay attack: when - the test chain is forked both instances have the same address and - counter so whatever happens on the test chain can be replayed on the - main chain. The script has been fixed during the activation of the - Babylon protocol. *) - hash = - Script_expr_hash.of_b58check_exn - "expru4Ju9kf6MQ216FxUEsb9P6j8UhkPtsFcYP8r9XhQSRb47FZGfM"; - requires_chain_id = false; - main_entrypoint = None; - generic = false; - }; - ] - -let known_multisig_hashes = - List.map (fun descr -> descr.hash) known_multisig_contracts - -let check_multisig_script_hash hash : - multisig_contract_description tzresult Lwt.t = - match - List.find_opt - (fun d -> Script_expr_hash.(d.hash = hash)) - known_multisig_contracts - with - | None -> fail (Not_a_supported_multisig_contract hash) - | Some d -> return d - -(* Returns [Ok ()] if [~contract] is an originated contract whose code - is [multisig_script] *) -let check_multisig_contract (cctxt : #Protocol_client_context.full) ~chain - ~block contract = - Client_proto_context.get_script_hash cctxt ~chain ~block contract - >>=? function - | None -> fail (Contract_has_no_script contract) - | Some hash -> check_multisig_script_hash hash - -(* Some Michelson building functions, specific to the needs of the multisig - interface.*) - -(* The type of the lambdas consumed by the generic script *) -let lambda_action_t ~loc = lambda_t ~loc (unit_t ~loc) (operations_t ~loc) - -(* Conversion functions from common types to Script_expr using the optimized representation *) -let mutez ~loc (amount : Tez.t) = int ~loc (Z.of_int64 (Tez.to_mutez amount)) - -let optimized_key_hash ~loc (key_hash : Signature.Public_key_hash.t) = - bytes - ~loc - (Data_encoding.Binary.to_bytes_exn - Signature.Public_key_hash.encoding - key_hash) - -let optimized_address ~loc ~(address : Contract.t) ~(entrypoint : string) = - let entrypoint = match entrypoint with "default" -> "" | name -> name in - bytes - ~loc - (Data_encoding.Binary.to_bytes_exn - Data_encoding.(tup2 Contract.encoding Variable.string) - (address, entrypoint)) - -let optimized_key ~loc (key : Signature.Public_key.t) = - bytes - ~loc - (Data_encoding.Binary.to_bytes_exn Signature.Public_key.encoding key) - -(** * Actions *) - -type multisig_action = - | Transfer of { - amount : Tez.t; - destination : Contract.t; - entrypoint : string; - parameter_type : Script.expr; - parameter : Script.expr; - } - | Change_delegate of public_key_hash option - | Lambda of Script.expr - | Change_keys of Z.t * public_key list - -let action_to_expr_generic ~loc = function - | Transfer {amount; destination; entrypoint; parameter_type; parameter} -> ( - match Contract.is_implicit destination with - | Some destination -> - lambda_from_string - @@ Managed_contract.build_lambda_for_transfer_to_implicit - ~destination - ~amount - >|? left ~loc - | None -> - lambda_from_string - @@ Managed_contract.build_lambda_for_transfer_to_originated - ~destination - ~entrypoint - ~parameter_type - ~parameter - ~amount - >|? left ~loc) - | Lambda code -> - Error_monad.ok Tezos_micheline.Micheline.(left ~loc (root code)) - | Change_delegate delegate -> - lambda_from_string - @@ Managed_contract.build_lambda_for_set_delegate ~delegate - >|? left ~loc - | Change_keys (threshold, keys) -> - let optimized_keys = seq ~loc (List.map (optimized_key ~loc) keys) in - let expr = right ~loc (pair ~loc (int ~loc threshold) optimized_keys) in - Error_monad.ok expr - -let action_to_expr_legacy ~loc = function - | Transfer {amount; destination; entrypoint; parameter_type; parameter} -> - if parameter <> Tezos_micheline.Micheline.strip_locations (unit ~loc:()) - then Error_monad.error @@ Unsupported_feature_generic_call parameter - else if - parameter_type - <> Tezos_micheline.Micheline.strip_locations (unit_t ~loc:()) - then - Error_monad.error @@ Unsupported_feature_generic_call_ty parameter_type - else - Error_monad.ok - @@ left - ~loc - (pair - ~loc - (mutez ~loc amount) - (optimized_address ~loc ~address:destination ~entrypoint)) - | Lambda _ -> Error_monad.error @@ Unsupported_feature_lambda "" - | Change_delegate delegate -> - let delegate_opt = - match delegate with - | None -> none ~loc () - | Some delegate -> some ~loc (optimized_key_hash ~loc delegate) - in - Error_monad.ok @@ right ~loc (left ~loc delegate_opt) - | Change_keys (threshold, keys) -> - let optimized_keys = seq ~loc (List.map (optimized_key ~loc) keys) in - let expr = right ~loc (pair ~loc (int ~loc threshold) optimized_keys) in - Error_monad.ok (right ~loc expr) - -let action_to_expr ~loc ~generic action = - if generic then action_to_expr_generic ~loc action - else action_to_expr_legacy ~loc action - -let action_of_expr_generic e = - let fail () = - Error_monad.fail - (Action_deserialisation_error - (Tezos_micheline.Micheline.strip_locations e)) - in - match e with - | Tezos_micheline.Micheline.Prim (_, Script.D_Left, [lam], []) -> - return @@ Lambda (Tezos_micheline.Micheline.strip_locations lam) - | Tezos_micheline.Micheline.Prim - ( _, - Script.D_Right, - [ - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [ - Tezos_micheline.Micheline.Int (_, threshold); - Tezos_micheline.Micheline.Seq (_, key_bytes); - ], - [] ); - ], - [] ) -> - List.map_es - (function - | Tezos_micheline.Micheline.Bytes (_, s) -> - return - @@ Data_encoding.Binary.of_bytes_exn - Signature.Public_key.encoding - s - | _ -> fail ()) - key_bytes - >>=? fun keys -> return @@ Change_keys (threshold, keys) - | _ -> fail () - -let action_of_expr_not_generic e = - let fail () = - Error_monad.fail - (Action_deserialisation_error - (Tezos_micheline.Micheline.strip_locations e)) - in - match e with - | Tezos_micheline.Micheline.Prim - ( _, - Script.D_Left, - [ - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [ - Tezos_micheline.Micheline.Int (_, i); - Tezos_micheline.Micheline.Bytes (_, s); - ], - [] ); - ], - [] ) -> ( - match Tez.of_mutez (Z.to_int64 i) with - | None -> fail () - | Some amount -> - return - @@ Transfer - { - amount; - destination = - Data_encoding.Binary.of_bytes_exn Contract.encoding s; - entrypoint = "default"; - parameter_type = - Tezos_micheline.Micheline.strip_locations @@ unit_t ~loc:(); - parameter = - Tezos_micheline.Micheline.strip_locations @@ unit ~loc:(); - }) - | Tezos_micheline.Micheline.Prim - ( _, - Script.D_Right, - [ - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Left, - [Tezos_micheline.Micheline.Prim (_, Script.D_None, [], [])], - [] ); - ], - [] ) -> - return @@ Change_delegate None - | Tezos_micheline.Micheline.Prim - ( _, - Script.D_Right, - [ - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Left, - [ - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Some, - [Tezos_micheline.Micheline.Bytes (_, s)], - [] ); - ], - [] ); - ], - [] ) -> - return - @@ Change_delegate - (Some - (Data_encoding.Binary.of_bytes_exn - Signature.Public_key_hash.encoding - s)) - | Tezos_micheline.Micheline.Prim - ( _, - Script.D_Right, - [ - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Right, - [ - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [ - Tezos_micheline.Micheline.Int (_, threshold); - Tezos_micheline.Micheline.Seq (_, key_bytes); - ], - [] ); - ], - [] ); - ], - [] ) -> - List.map_es - (function - | Tezos_micheline.Micheline.Bytes (_, s) -> - return - @@ Data_encoding.Binary.of_bytes_exn - Signature.Public_key.encoding - s - | _ -> fail ()) - key_bytes - >>=? fun keys -> return @@ Change_keys (threshold, keys) - | _ -> fail () - -let action_of_expr ~generic = - if generic then action_of_expr_generic else action_of_expr_not_generic - -type key_list = Signature.Public_key.t list - -(* The relevant information that we can get about a multisig smart contract *) -type multisig_contract_information = { - counter : Z.t; - threshold : Z.t; - keys : key_list; -} - -let multisig_get_information (cctxt : #Protocol_client_context.full) ~chain - ~block contract = - let open Client_proto_context in - let open Tezos_micheline.Micheline in - get_storage cctxt ~chain ~block ~unparsing_mode:Readable contract - >>=? fun storage_opt -> - match storage_opt with - | None -> fail (Contract_has_no_storage contract) - | Some storage -> ( - match root storage with - | Prim - ( _, - D_Pair, - [Int (_, counter); Int (_, threshold); Seq (_, key_nodes)], - _ ) -> - List.map_es - (function - | String (_, key_str) -> - return @@ Signature.Public_key.of_b58check_exn key_str - | _ -> fail (Contract_has_unexpected_storage contract)) - key_nodes - >>=? fun keys -> return {counter; threshold; keys} - | _ -> fail (Contract_has_unexpected_storage contract)) - -let multisig_create_storage ~counter ~threshold ~keys () : - Script.expr tzresult Lwt.t = - let loc = Tezos_micheline.Micheline_parser.location_zero in - let open Tezos_micheline.Micheline in - List.map_es - (fun key -> - let key_str = Signature.Public_key.to_b58check key in - return (String (loc, key_str))) - keys - >>=? fun l -> - return @@ strip_locations - @@ pair ~loc (int ~loc counter) (pair ~loc (int ~loc threshold) (seq ~loc l)) - -(* Client_proto_context.originate expects the initial storage as a string *) -let multisig_storage_string ~counter ~threshold ~keys () = - multisig_create_storage ~counter ~threshold ~keys () >>=? fun expr -> - return @@ Format.asprintf "%a" Michelson_v1_printer.print_expr expr - -let multisig_create_param ~counter ~generic ~action ~optional_signatures () : - Script.expr tzresult Lwt.t = - let loc = 0 in - let open Tezos_micheline.Micheline in - List.map_es - (fun sig_opt -> - match sig_opt with - | None -> return @@ none ~loc () - | Some signature -> - return @@ some ~loc (String (loc, Signature.to_b58check signature))) - optional_signatures - >>=? fun l -> - Lwt.return @@ action_to_expr ~loc ~generic action >>=? fun expr -> - return @@ strip_locations - @@ pair ~loc (pair ~loc (int ~loc counter) expr) (Seq (loc, l)) - -let multisig_param_string ~counter ~action ~optional_signatures ~generic () = - multisig_create_param ~counter ~action ~optional_signatures ~generic () - >>=? fun expr -> - return @@ Format.asprintf "%a" Michelson_v1_printer.print_expr expr - -let get_contract_address_maybe_chain_id ~descr ~loc ~chain_id contract = - let address = - bytes ~loc (Data_encoding.Binary.to_bytes_exn Contract.encoding contract) - in - if descr.requires_chain_id then - let chain_id_bytes = - bytes ~loc (Data_encoding.Binary.to_bytes_exn Chain_id.encoding chain_id) - in - pair ~loc chain_id_bytes address - else address - -let multisig_bytes ~counter ~action ~contract ~chain_id ~descr () = - let loc = 0 in - Lwt.return @@ action_to_expr ~loc ~generic:descr.generic action - >>=? fun expr -> - let triple = - pair - ~loc - (get_contract_address_maybe_chain_id ~descr ~loc ~chain_id contract) - (pair ~loc (int ~loc counter) expr) - in - let bytes = - Data_encoding.Binary.to_bytes_exn Script.expr_encoding - @@ Tezos_micheline.Micheline.strip_locations @@ triple - in - return @@ Bytes.cat (Bytes.of_string "\005") bytes - -let check_threshold ~threshold ~keys () = - let threshold = Z.to_int threshold in - if Compare.List_length_with.(keys < threshold) then - fail (Threshold_too_high (threshold, List.length keys)) - else if Compare.Int.(threshold <= 0) then - fail (Non_positive_threshold threshold) - else return_unit - -let originate_multisig (cctxt : #Protocol_client_context.full) ~chain ~block - ?confirmations ?dry_run ?branch ?fee ?gas_limit ?storage_limit - ?verbose_signing ~delegate ~threshold ~keys ~balance ~source ~src_pk ~src_sk - ~fee_parameter () = - multisig_storage_string ~counter:Z.zero ~threshold ~keys () - >>=? fun initial_storage -> - check_threshold ~threshold ~keys () >>=? fun () -> - Client_proto_context.originate_contract - cctxt - ~chain - ~block - ?branch - ?confirmations - ?dry_run - ?fee - ?gas_limit - ?storage_limit - ?verbose_signing - ~delegate - ~initial_storage - ~balance - ~source - ~src_pk - ~src_sk - ~code:multisig_script - ~fee_parameter - () - -type multisig_prepared_action = { - bytes : Bytes.t; - threshold : Z.t; - keys : public_key list; - counter : Z.t; - entrypoint : string option; - generic : bool; -} - -let check_parameter_type (cctxt : #Protocol_client_context.full) ?gas ?legacy - ~destination ~entrypoint ~parameter_type ~parameter () = - trace - (Ill_typed_argument (destination, entrypoint, parameter_type, parameter)) - @@ Plugin.RPC.Scripts.typecheck_data - cctxt - (cctxt#chain, cctxt#block) - ~data:parameter - ~ty:parameter_type - ?gas - ?legacy - >>=? fun _ -> return_unit - -let check_action (cctxt : #Protocol_client_context.full) ~action ~balance ?gas - ?legacy () = - match action with - | Change_keys (threshold, keys) -> - check_threshold ~threshold ~keys () >>=? fun () -> return_unit - | Transfer {amount; destination; entrypoint; parameter_type; parameter} -> - check_parameter_type - cctxt - ~destination - ~entrypoint - ~parameter_type - ~parameter - () - >>=? fun () -> - if Tez.(amount > balance) then - (* This is warning only because the contract can be filled - before sending the signatures or even in the same - transaction *) - Format.eprintf - "Transferred amount is bigger than current multisig balance" ; - return_unit - | Lambda code -> - let action_t = - Tezos_micheline.Micheline.strip_locations (lambda_action_t ~loc:()) - in - trace (Ill_typed_lambda (code, action_t)) - @@ Plugin.RPC.Scripts.typecheck_data - cctxt - (cctxt#chain, cctxt#block) - ~data:code - ~ty:action_t - ?gas - ?legacy - >>=? fun _remaining_gas -> return_unit - | _ -> return_unit - -let prepare_multisig_transaction (cctxt : #Protocol_client_context.full) ~chain - ~block ~multisig_contract ~action () = - let contract = multisig_contract in - check_multisig_contract cctxt ~chain ~block contract >>=? fun descr -> - multisig_get_information cctxt ~chain ~block contract - >>=? fun {counter; threshold; keys} -> - Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> - multisig_bytes ~counter ~action ~contract ~descr ~chain_id () - >>=? fun bytes -> - Client_proto_context.get_balance - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - contract - >>=? fun balance -> - check_action cctxt ~action ~balance () >>=? fun () -> - return - { - bytes; - threshold; - keys; - counter; - entrypoint = descr.main_entrypoint; - generic = descr.generic; - } - -let check_multisig_signatures ~bytes ~threshold ~keys signatures = - let key_array = Array.of_list keys in - let nkeys = Array.length key_array in - let opt_sigs_arr = Array.make nkeys None in - let matching_key_found = ref false in - let check_signature_against_key_number signature i key = - if Signature.check key signature bytes then ( - matching_key_found := true ; - opt_sigs_arr.(i) <- Some signature) - in - List.iter_ep - (fun signature -> - matching_key_found := false ; - List.iteri (check_signature_against_key_number signature) keys ; - fail_unless !matching_key_found (Invalid_signature signature)) - signatures - >>=? fun () -> - let opt_sigs = Array.to_list opt_sigs_arr in - let signature_count = - List.fold_left - (fun n sig_opt -> match sig_opt with Some _ -> n + 1 | None -> n) - 0 - opt_sigs - in - let threshold_int = Z.to_int threshold in - if signature_count >= threshold_int then return opt_sigs - else fail (Not_enough_signatures (threshold_int, signature_count)) - -let call_multisig (cctxt : #Protocol_client_context.full) ~chain ~block - ?confirmations ?dry_run ?verbose_signing ?branch ~source ~src_pk ~src_sk - ~multisig_contract ~action ~signatures ~amount ?fee ?gas_limit - ?storage_limit ?counter ~fee_parameter () = - prepare_multisig_transaction cctxt ~chain ~block ~multisig_contract ~action () - >>=? fun { - bytes; - threshold; - keys; - counter = stored_counter; - entrypoint; - generic; - } -> - check_multisig_signatures ~bytes ~threshold ~keys signatures - >>=? fun optional_signatures -> - multisig_param_string - ~counter:stored_counter - ~action - ~optional_signatures - ~generic - () - >>=? fun arg -> - Client_proto_context.transfer - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?branch - ~source - ~src_pk - ~src_sk - ~destination:multisig_contract - ?entrypoint - ~arg - ~amount - ?fee - ?gas_limit - ?storage_limit - ?counter - ~fee_parameter - ?verbose_signing - () - -let action_of_bytes ~multisig_contract ~stored_counter ~descr ~chain_id bytes = - if - Compare.Int.(Bytes.length bytes >= 1) - && Compare.Int.(TzEndian.get_uint8 bytes 0 = 0x05) - then - let nbytes = Bytes.sub bytes 1 (Bytes.length bytes - 1) in - match Data_encoding.Binary.of_bytes_opt Script.expr_encoding nbytes with - | None -> fail (Bytes_deserialisation_error bytes) - | Some e -> ( - match Tezos_micheline.Micheline.root e with - | Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [ - Tezos_micheline.Micheline.Bytes (_, contract_bytes); - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [Tezos_micheline.Micheline.Int (_, counter); e], - [] ); - ], - [] ) - when not descr.requires_chain_id -> - let contract = - Data_encoding.Binary.of_bytes_exn Contract.encoding contract_bytes - in - if counter = stored_counter then - if Contract.(multisig_contract = contract) then - action_of_expr ~generic:descr.generic e - else - fail (Bad_deserialized_contract (contract, multisig_contract)) - else fail (Bad_deserialized_counter (counter, stored_counter)) - | Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [ - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [ - Tezos_micheline.Micheline.Bytes (_, chain_id_bytes); - Tezos_micheline.Micheline.Bytes (_, contract_bytes); - ], - [] ); - Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [Tezos_micheline.Micheline.Int (_, counter); e], - [] ); - ], - [] ) - when descr.requires_chain_id -> - let contract = - Data_encoding.Binary.of_bytes_exn Contract.encoding contract_bytes - in - let cid = - Data_encoding.Binary.of_bytes_exn Chain_id.encoding chain_id_bytes - in - if counter = stored_counter then - if multisig_contract = contract && chain_id = cid then - action_of_expr ~generic:descr.generic e - else - fail (Bad_deserialized_contract (contract, multisig_contract)) - else fail (Bad_deserialized_counter (counter, stored_counter)) - | _ -> fail (Bytes_deserialisation_error bytes)) - else fail (Bytes_deserialisation_error bytes) - -let call_multisig_on_bytes (cctxt : #Protocol_client_context.full) ~chain ~block - ?confirmations ?dry_run ?verbose_signing ?branch ~source ~src_pk ~src_sk - ~multisig_contract ~bytes ~signatures ~amount ?fee ?gas_limit ?storage_limit - ?counter ~fee_parameter () = - multisig_get_information cctxt ~chain ~block multisig_contract - >>=? fun info -> - check_multisig_contract cctxt ~chain ~block multisig_contract - >>=? fun descr -> - Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> - action_of_bytes - ~multisig_contract - ~stored_counter:info.counter - ~chain_id - ~descr - bytes - >>=? fun action -> - call_multisig - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?branch - ~source - ~src_pk - ~src_sk - ~multisig_contract - ~action - ~signatures - ~amount - ?fee - ?gas_limit - ?storage_limit - ?counter - ~fee_parameter - ?verbose_signing - () diff --git a/src/proto_012_Psithaca/lib_client/client_proto_multisig.mli b/src/proto_012_Psithaca/lib_client/client_proto_multisig.mli deleted file mode 100644 index ad4a6306d60c..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_multisig.mli +++ /dev/null @@ -1,150 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Protocol_client_context - -(* The script of the recommended version of the multisig contract. - This is the script originated by [originate_multisig]. *) -val multisig_script : Script.expr - -(* A description of the possible actions that a multisig contract can run. *) -type multisig_action = - | Transfer of { - amount : Tez.t; - destination : Contract.t; - entrypoint : string; - parameter_type : Script.expr; - parameter : Script.expr; - } - | Change_delegate of public_key_hash option - | Lambda of Script.expr - | Change_keys of Z.t * public_key list - -(* A prepared action is the byte sequence that needs to be signed to run the - action together with some data that can be useful for the user and to call - the multisig contracts once enough signatures are provided. *) -type multisig_prepared_action = { - (* The sequence of bytes to be signed. *) - bytes : Bytes.t; - (* Information reported to the user so that she knows who can sign and how - many signatures are required. *) - threshold : Z.t; - keys : public_key list; - (* Information needed to execute the action ones enough signatures have been - gathered. *) - counter : Z.t; - entrypoint : string option; - generic : bool; -} - -(* The client will refuse to interact with a multisig contract if the hash of - its script is not in this list. *) -val known_multisig_hashes : Script_expr_hash.t list - -(* Originate a new multisig contract *) -val originate_multisig : - full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?branch:int -> - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - ?verbose_signing:bool -> - delegate:public_key_hash option -> - threshold:Z.t -> - keys:public_key list -> - balance:Tez.t -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - fee_parameter:Injection.fee_parameter -> - unit -> - (Kind.origination Kind.manager Injection.result * Contract.t) tzresult Lwt.t - -(* Prepare an action, see [multisig_prepared_action]. *) -val prepare_multisig_transaction : - full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - multisig_contract:Contract.t -> - action:multisig_action -> - unit -> - multisig_prepared_action tzresult Lwt.t - -(* Call a multisig contract, requesting it to run an action. *) -val call_multisig : - full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?branch:int -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - multisig_contract:Contract.t -> - action:multisig_action -> - signatures:Signature.t list -> - amount:Tez.t -> - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - ?counter:Z.t -> - fee_parameter:Injection.fee_parameter -> - unit -> - (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult - Lwt.t - -(* Same as [call_multisig] but the action to be performed is reconstructed from - the byte sequence that was signed. *) -val call_multisig_on_bytes : - full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?branch:int -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - multisig_contract:Contract.t -> - bytes:Bytes.t -> - signatures:Signature.t list -> - amount:Tez.t -> - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - ?counter:Z.t -> - fee_parameter:Injection.fee_parameter -> - unit -> - (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult - Lwt.t diff --git a/src/proto_012_Psithaca/lib_client/client_proto_programs.ml b/src/proto_012_Psithaca/lib_client/client_proto_programs.ml deleted file mode 100644 index b0b1b295e529..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_programs.ml +++ /dev/null @@ -1,344 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Tezos_micheline -open Michelson_v1_printer - -module Program = Client_aliases.Alias (struct - type t = Michelson_v1_parser.parsed Micheline_parser.parsing_result - - include Compare.Make (struct - type nonrec t = t - - let compare = Micheline_parser.compare Michelson_v1_parser.compare_parsed - end) - - let encoding = - Data_encoding.conv - (fun ({Michelson_v1_parser.source; _}, _) -> source) - (fun source -> Michelson_v1_parser.parse_toplevel source) - Data_encoding.string - - let of_source source = return (Michelson_v1_parser.parse_toplevel source) - - let to_source ({Michelson_v1_parser.source; _}, _) = return source - - let name = "script" -end) - -let print_errors ?parsed (cctxt : #Client_context.printer) errs ~show_source = - cctxt#warning - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:false - ?parsed - ~show_source) - errs - >>= fun () -> - cctxt#error "error running script" >>= fun () -> return_unit - -let print_view_result (cctxt : #Client_context.printer) = function - | Ok expr -> cctxt#message "%a" print_expr expr >>= fun () -> return_unit - | Error errs -> print_errors cctxt ~show_source:false errs - -let print_run_result (cctxt : #Client_context.printer) ~show_source ~parsed = - function - | Ok (storage, operations, maybe_lazy_storage_diff) -> - cctxt#message - "@[@[storage@,\ - %a@]@,\ - @[emitted operations@,\ - %a@]@,\ - @[big_map diff@,\ - %a@]@]@." - print_expr - storage - (Format.pp_print_list Operation_result.pp_internal_operation) - operations - (fun ppf -> function - | None -> () - | Some diff -> print_big_map_diff ppf diff) - maybe_lazy_storage_diff - >>= fun () -> return_unit - | Error errs -> print_errors cctxt errs ~show_source ~parsed - -let print_trace_result (cctxt : #Client_context.printer) ~show_source ~parsed = - function - | Ok (storage, operations, trace, maybe_lazy_storage_diff) -> - cctxt#message - "@[@[storage@,\ - %a@]@,\ - @[emitted operations@,\ - %a@]@,\ - @[big_map diff@,\ - %a@]@,\ - @[trace@,\ - %a@]@]@." - print_expr - storage - (Format.pp_print_list Operation_result.pp_internal_operation) - operations - (fun ppf -> function - | None -> () - | Some diff -> print_big_map_diff ppf diff) - maybe_lazy_storage_diff - print_execution_trace - trace - >>= fun () -> return_unit - | Error errs -> print_errors cctxt errs ~show_source ~parsed - -type simulation_params = { - input : Michelson_v1_parser.parsed; - unparsing_mode : Script_ir_translator.unparsing_mode; - now : Script_timestamp.t option; - level : Script_int.n Script_int.num option; - source : Contract.t option; - payer : Contract.t option; - gas : Gas.Arith.integral option; -} - -type run_view_params = { - shared_params : simulation_params; - contract : Contract.t; - entrypoint : string; -} - -type run_params = { - shared_params : simulation_params; - amount : Tez.t option; - balance : Tez.t; - program : Michelson_v1_parser.parsed; - storage : Michelson_v1_parser.parsed; - entrypoint : string option; -} - -let run_view (cctxt : #Protocol_client_context.rpc_context) - ~(chain : Chain_services.chain) ~block (params : run_view_params) = - let { - shared_params = {input; unparsing_mode; now; level; source; payer; gas}; - contract; - entrypoint; - } = - params - in - Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> - Plugin.RPC.Scripts.run_view - cctxt - (chain, block) - ?gas - ~contract - ~entrypoint - ~input:input.expanded - ~chain_id - ?source - ?payer - ~unparsing_mode - ~now - ~level - -let run (cctxt : #Protocol_client_context.rpc_context) - ~(chain : Chain_services.chain) ~block (params : run_params) = - Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> - let { - shared_params = {input; unparsing_mode; now; level; source; payer; gas}; - program; - amount; - balance; - storage; - entrypoint; - } = - params - in - let amount = Option.value ~default:Tez.fifty_cents amount in - Plugin.RPC.Scripts.run_code - cctxt - (chain, block) - ?gas - ?entrypoint - ~unparsing_mode - ~script:program.expanded - ~storage:storage.expanded - ~input:input.expanded - ~amount - ~balance - ~chain_id - ~source - ~payer - ~now - ~level - -let trace (cctxt : #Protocol_client_context.rpc_context) - ~(chain : Chain_services.chain) ~block (params : run_params) = - Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> - let { - shared_params = {input; unparsing_mode; now; level; source; payer; gas}; - program; - amount; - balance; - storage; - entrypoint; - } = - params - in - let amount = Option.value ~default:Tez.fifty_cents amount in - Plugin.RPC.Scripts.trace_code - cctxt - (chain, block) - ?gas - ?entrypoint - ~unparsing_mode - ~script:program.expanded - ~storage:storage.expanded - ~input:input.expanded - ~amount - ~balance - ~chain_id - ~source - ~payer - ~now - ~level - -let typecheck_data cctxt ~(chain : Chain_services.chain) ~block ?gas ?legacy - ~(data : Michelson_v1_parser.parsed) ~(ty : Michelson_v1_parser.parsed) () = - Plugin.RPC.Scripts.typecheck_data - cctxt - (chain, block) - ?gas - ?legacy - ~data:data.expanded - ~ty:ty.expanded - -let typecheck_program cctxt ~(chain : Chain_services.chain) ~block ?gas ?legacy - ~show_types (program : Michelson_v1_parser.parsed) = - Plugin.RPC.Scripts.typecheck_code - cctxt - (chain, block) - ?gas - ?legacy - ~script:program.expanded - ~show_types - -let script_size cctxt ~(chain : Chain_services.chain) ~block ?gas ?legacy - ~(program : Michelson_v1_parser.parsed) - ~(storage : Michelson_v1_parser.parsed) () = - Plugin.RPC.Scripts.script_size - cctxt - (chain, block) - ?gas - ?legacy - ~script:program.expanded - ~storage:storage.expanded - -let print_typecheck_result ~emacs ~show_types ~print_source_on_error program res - (cctxt : #Client_context.printer) = - if emacs then - let (type_map, errs, _gas) = - match res with - | Ok (type_map, gas) -> (type_map, [], Some gas) - | Error - (Environment.Ecoproto_error - (Script_tc_errors.Ill_typed_contract (_, type_map)) - :: _ as errs) -> - (type_map, errs, None) - | Error errs -> ([], errs, None) - in - cctxt#message - "(@[(types . %a)@ (errors . %a)@])" - Michelson_v1_emacs.print_type_map - (program, type_map) - Michelson_v1_emacs.report_errors - (program, errs) - >>= fun () -> return_unit - else - match res with - | Ok (type_map, gas) -> - let program = Michelson_v1_printer.inject_types type_map program in - cctxt#message "@[Well typed@,Gas remaining: %a@]" Gas.pp gas - >>= fun () -> - if show_types then - cctxt#message "%a" Micheline_printer.print_expr program >>= fun () -> - return_unit - else return_unit - | Error errs -> - cctxt#warning - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:show_types - ~show_source:print_source_on_error - ~parsed:program) - errs - >>= fun () -> cctxt#error "ill-typed script" - -let entrypoint_type cctxt ~(chain : Chain_services.chain) ~block - (program : Michelson_v1_parser.parsed) ~entrypoint = - Michelson_v1_entrypoints.script_entrypoint_type - cctxt - ~chain - ~block - program.expanded - ~entrypoint - -let print_entrypoint_type (cctxt : #Client_context.printer) ~emacs ?script_name - ~show_source ~parsed ~entrypoint ty = - Michelson_v1_entrypoints.print_entrypoint_type - cctxt - ~entrypoint - ~emacs - ?script_name - ~on_errors:(print_errors cctxt ~show_source ~parsed) - ty - -let list_entrypoints cctxt ~(chain : Chain_services.chain) ~block - (program : Michelson_v1_parser.parsed) = - Michelson_v1_entrypoints.list_entrypoints cctxt ~chain ~block program.expanded - -let print_entrypoints_list (cctxt : #Client_context.printer) ~emacs ?script_name - ~show_source ~parsed ty = - Michelson_v1_entrypoints.print_entrypoints_list - cctxt - ~emacs - ?script_name - ~on_errors:(print_errors cctxt ~show_source ~parsed) - ty - -let list_unreachables cctxt ~(chain : Chain_services.chain) ~block - (program : Michelson_v1_parser.parsed) = - Michelson_v1_entrypoints.list_unreachables - cctxt - ~chain - ~block - program.expanded - -let print_unreachables (cctxt : #Client_context.printer) ~emacs ?script_name - ~show_source ~parsed ty = - Michelson_v1_entrypoints.print_unreachables - cctxt - ~emacs - ?script_name - ~on_errors:(print_errors cctxt ~show_source ~parsed) - ty diff --git a/src/proto_012_Psithaca/lib_client/client_proto_programs.mli b/src/proto_012_Psithaca/lib_client/client_proto_programs.mli deleted file mode 100644 index 16c9a45acfff..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_programs.mli +++ /dev/null @@ -1,204 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Tezos_micheline - -module Program : - Client_aliases.Alias - with type t = Michelson_v1_parser.parsed Micheline_parser.parsing_result - -(* Parameters shared by both simulations (views, and contracts). *) -type simulation_params = { - input : Michelson_v1_parser.parsed; - unparsing_mode : Script_ir_translator.unparsing_mode; - now : Script_timestamp.t option; - level : Script_int.n Script_int.num option; - source : Contract.t option; - payer : Contract.t option; - gas : Gas.Arith.integral option; -} - -(* Parameters specific to simulations of views *) -type run_view_params = { - shared_params : simulation_params; - contract : Contract.t; - entrypoint : string; -} - -(* Parameters specific to simulations of contract calls *) -type run_params = { - shared_params : simulation_params; - amount : Tez.t option; - balance : Tez.t; - program : Michelson_v1_parser.parsed; - storage : Michelson_v1_parser.parsed; - entrypoint : string option; -} - -val run_view : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - run_view_params -> - Script.expr tzresult Lwt.t - -val run : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - run_params -> - (Script.expr * packed_internal_operation list * Lazy_storage.diffs option) - tzresult - Lwt.t - -val trace : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - run_params -> - (Script.expr - * packed_internal_operation list - * Script_typed_ir.execution_trace - * Lazy_storage.diffs option) - tzresult - Lwt.t - -val print_view_result : - #Client_context.printer -> Script_repr.expr tzresult -> unit tzresult Lwt.t - -val print_run_result : - #Client_context.printer -> - show_source:bool -> - parsed:Michelson_v1_parser.parsed -> - (Script_repr.expr - * packed_internal_operation list - * Lazy_storage.diffs option) - tzresult -> - unit tzresult Lwt.t - -val print_trace_result : - #Client_context.printer -> - show_source:bool -> - parsed:Michelson_v1_parser.parsed -> - (Script_repr.expr - * packed_internal_operation list - * Script_typed_ir.execution_trace - * Lazy_storage.diffs option) - tzresult -> - unit tzresult Lwt.t - -val typecheck_data : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?gas:Gas.Arith.integral -> - ?legacy:bool -> - data:Michelson_v1_parser.parsed -> - ty:Michelson_v1_parser.parsed -> - unit -> - Gas.t tzresult Lwt.t - -val typecheck_program : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?gas:Gas.Arith.integral -> - ?legacy:bool -> - show_types:bool -> - Michelson_v1_parser.parsed -> - (Script_tc_errors.type_map * Gas.t) tzresult Lwt.t - -val print_typecheck_result : - emacs:bool -> - show_types:bool -> - print_source_on_error:bool -> - Michelson_v1_parser.parsed -> - (Script_tc_errors.type_map * Gas.t) tzresult -> - #Client_context.printer -> - unit tzresult Lwt.t - -val script_size : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?gas:Gas.Arith.integral -> - ?legacy:bool -> - program:Michelson_v1_parser.parsed -> - storage:Michelson_v1_parser.parsed -> - unit -> - int tzresult Lwt.t - -val entrypoint_type : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Michelson_v1_parser.parsed -> - entrypoint:string -> - Script.expr option tzresult Lwt.t - -val print_entrypoint_type : - #Client_context.printer -> - emacs:bool -> - ?script_name:string -> - show_source:bool -> - parsed:Michelson_v1_parser.parsed -> - entrypoint:string -> - Script_repr.expr option tzresult -> - unit tzresult Lwt.t - -val list_entrypoints : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Michelson_v1_parser.parsed -> - (string * Script.expr) list tzresult Lwt.t - -val print_entrypoints_list : - #Client_context.printer -> - emacs:bool -> - ?script_name:string -> - show_source:bool -> - parsed:Michelson_v1_parser.parsed -> - (string * Script.expr) list tzresult -> - unit tzresult Lwt.t - -val list_unreachables : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - block:Shell_services.block -> - Michelson_v1_parser.parsed -> - Michelson_v1_primitives.prim list list tzresult Lwt.t - -val print_unreachables : - #Client_context.printer -> - emacs:bool -> - ?script_name:string -> - show_source:bool -> - parsed:Michelson_v1_parser.parsed -> - Michelson_v1_primitives.prim list list tzresult -> - unit tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_client/client_proto_utils.ml b/src/proto_012_Psithaca/lib_client/client_proto_utils.ml deleted file mode 100644 index 27fec54d342a..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_utils.ml +++ /dev/null @@ -1,55 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Protocol_client_context - -let to_json_and_bytes branch message = - let op = - ( Environment.Operation.{branch}, - Contents_list (Single (Failing_noop message)) ) - in - let encoding = Operation.unsigned_encoding in - ( Data_encoding.Json.construct encoding op, - Data_encoding.Binary.to_bytes_exn encoding op ) - -let sign_message (cctxt : #full) ~src_sk ~block ~message = - let (json, bytes) = to_json_and_bytes block message in - cctxt#message "signed content: @[%a@]" Data_encoding.Json.pp json - >>= fun () -> - Client_keys.sign cctxt ~watermark:Signature.Generic_operation src_sk bytes - -let check_message (cctxt : #full) ~block ~key_locator ~quiet ~message ~signature - = - let (json, bytes) = to_json_and_bytes block message in - (if quiet then Lwt.return_unit - else cctxt#message "checked content: @[%a@]" Data_encoding.Json.pp json) - >>= fun () -> - Client_keys.check - ~watermark:Signature.Generic_operation - key_locator - signature - bytes diff --git a/src/proto_012_Psithaca/lib_client/client_proto_utils.mli b/src/proto_012_Psithaca/lib_client/client_proto_utils.mli deleted file mode 100644 index c535e4b24ecb..000000000000 --- a/src/proto_012_Psithaca/lib_client/client_proto_utils.mli +++ /dev/null @@ -1,40 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val sign_message : - #Protocol_client_context.full -> - src_sk:Client_keys.sk_uri -> - block:Block_hash.t -> - message:string -> - Signature.t tzresult Lwt.t - -val check_message : - #Protocol_client_context.full -> - block:Block_hash.t -> - key_locator:Client_keys.pk_uri -> - quiet:bool -> - message:string -> - signature:Signature.t -> - bool tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_client/dune b/src/proto_012_Psithaca/lib_client/dune deleted file mode 100644 index bdc999eca4ed..000000000000 --- a/src/proto_012_Psithaca/lib_client/dune +++ /dev/null @@ -1,24 +0,0 @@ -(library - (name tezos_client_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-client-012-Psithaca) - (libraries tezos-base - tezos-protocol-012-Psithaca - tezos-shell-services - tezos-client-base - tezos-mockup-registration - tezos-proxy - tezos-rpc - tezos-signer-backends - tezos-protocol-012-Psithaca-parameters - tezos-protocol-plugin-012-Psithaca) - (inline_tests) - (preprocess (pps ppx_inline_test)) - (library_flags (:standard -linkall)) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_shell_services - -open Tezos_client_base - -open Tezos_protocol_012_Psithaca - -open Tezos_protocol_plugin_012_Psithaca - -open Tezos_protocol_012_Psithaca_parameters - -open Tezos_rpc))) diff --git a/src/proto_012_Psithaca/lib_client/dune-project b/src/proto_012_Psithaca/lib_client/dune-project deleted file mode 100644 index e8836f1257a0..000000000000 --- a/src/proto_012_Psithaca/lib_client/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-client-alpha) diff --git a/src/proto_012_Psithaca/lib_client/injection.ml b/src/proto_012_Psithaca/lib_client/injection.ml deleted file mode 100644 index fff28c8f3e2b..000000000000 --- a/src/proto_012_Psithaca/lib_client/injection.ml +++ /dev/null @@ -1,1071 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2018 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Apply_results -open Protocol_client_context - -let get_branch (rpc_config : #Protocol_client_context.full) ~chain - ~(block : Block_services.block) branch = - (* The default branch is set to HEAD~2, because with Tenderbake the - same transaction may be included again in another block candidate - at the same level, so the operation branch should not point to - the current head. It's not a good idea if it points to the head's - predecessor as well, as the predecessor hash may still change - because of potential reorgs (only the predecessor payload is - finalized, not the whole block). *) - let branch = Option.value ~default:0 branch in - (* TODO export parameter *) - (match block with - | `Head 0 -> - (* Default client's block value: we branch to head's grandfather *) - return (`Head (2 + branch)) - | `Head n -> return (`Head (n + branch)) - | `Hash (h, n) -> return (`Hash (h, n + branch)) - | `Alias (a, n) -> return (`Alias (a, n)) - | `Genesis -> return `Genesis - | `Level i -> return (`Level i)) - >>=? fun block -> - Shell_services.Blocks.hash rpc_config ~chain ~block () >>=? fun hash -> - Shell_services.Chain.chain_id rpc_config ~chain () >>=? fun chain_id -> - return (chain_id, hash) - -type 'kind preapply_result = - Operation_hash.t * 'kind operation * 'kind operation_metadata - -type 'kind result_list = - Operation_hash.t * 'kind contents_list * 'kind contents_result_list - -type 'kind result = Operation_hash.t * 'kind contents * 'kind contents_result - -let get_manager_operation_gas_and_fee contents = - let open Operation in - let l = to_list (Contents_list contents) in - List.fold_left - (fun acc -> function - | Contents (Manager_operation {fee; gas_limit; _}) -> ( - match acc with - | Error _ as e -> e - | Ok (total_fee, total_gas) -> ( - match Tez.(total_fee +? fee) with - | Ok total_fee -> Ok (total_fee, Gas.Arith.add total_gas gas_limit) - | Error _ as e -> e)) - | _ -> acc) - (Ok (Tez.zero, Gas.Arith.zero)) - l - -type fee_parameter = { - minimal_fees : Tez.t; - minimal_nanotez_per_byte : Q.t; - minimal_nanotez_per_gas_unit : Q.t; - force_low_fee : bool; - fee_cap : Tez.t; - burn_cap : Tez.t; -} - -let dummy_fee_parameter = - { - minimal_fees = Tez.zero; - minimal_nanotez_per_byte = Q.zero; - minimal_nanotez_per_gas_unit = Q.zero; - force_low_fee = false; - fee_cap = Tez.one; - burn_cap = Tez.zero; - } - -(* Rounding up (see Z.cdiv) *) -let z_mutez_of_q_nanotez (ntz : Q.t) = - let q_mutez = Q.div ntz (Q.of_int 1000) in - Z.cdiv q_mutez.Q.num q_mutez.Q.den - -let check_fees : - type t. - #Protocol_client_context.full -> - fee_parameter -> - t contents_list -> - int -> - unit Lwt.t = - fun cctxt config op size -> - match get_manager_operation_gas_and_fee op with - | Error _ -> assert false (* FIXME *) - | Ok (fee, gas) -> - if Tez.compare fee config.fee_cap > 0 then - cctxt#error - "The proposed fee (%s%a) are higher than the configured fee cap \ - (%s%a).@\n\ - \ Use `--fee-cap %a` to emit this operation anyway." - Client_proto_args.tez_sym - Tez.pp - fee - Client_proto_args.tez_sym - Tez.pp - config.fee_cap - Tez.pp - fee - >>= fun () -> exit 1 - else - let fees_in_nanotez = - Q.mul (Q.of_int64 (Tez.to_mutez fee)) (Q.of_int 1000) - in - let minimal_fees_in_nanotez = - Q.mul (Q.of_int64 (Tez.to_mutez config.minimal_fees)) (Q.of_int 1000) - in - let minimal_fees_for_gas_in_nanotez = - Q.mul - config.minimal_nanotez_per_gas_unit - (Q.of_bigint (Gas.Arith.integral_to_z gas)) - in - let minimal_fees_for_size_in_nanotez = - Q.mul config.minimal_nanotez_per_byte (Q.of_int size) - in - let estimated_fees_in_nanotez = - Q.add - minimal_fees_in_nanotez - (Q.add - minimal_fees_for_gas_in_nanotez - minimal_fees_for_size_in_nanotez) - in - let estimated_fees_in_mutez = - z_mutez_of_q_nanotez estimated_fees_in_nanotez - in - let estimated_fees = - match Tez.of_mutez (Z.to_int64 estimated_fees_in_mutez) with - | None -> assert false - | Some fee -> fee - in - if - (not config.force_low_fee) - && Q.compare fees_in_nanotez estimated_fees_in_nanotez < 0 - then - cctxt#error - "The proposed fee (%s%a) are lower than the fee that baker expect \ - by default (%s%a).@\n\ - \ Use `--force-low-fee` to emit this operation anyway." - Client_proto_args.tez_sym - Tez.pp - fee - Client_proto_args.tez_sym - Tez.pp - estimated_fees - >>= fun () -> exit 1 - else Lwt.return_unit - -let print_for_verbose_signing ppf ~watermark ~bytes ~branch ~contents = - let open Format in - pp_open_vbox ppf 0 ; - let item f = - pp_open_hovbox ppf 4 ; - pp_print_string ppf " * " ; - f ppf () ; - pp_close_box ppf () ; - pp_print_cut ppf () - in - let hash_pp l = - fprintf ppf "%s" (Base58.raw_encode Blake2B.(hash_bytes l |> to_string)) - in - item (fun ppf () -> - pp_print_text ppf "Branch: " ; - Block_hash.pp ppf branch) ; - item (fun ppf () -> - fprintf - ppf - "Watermark: `%a` (0x%s)" - Signature.pp_watermark - watermark - (Hex.of_bytes (Signature.bytes_of_watermark watermark) |> Hex.show)) ; - item (fun ppf () -> - pp_print_text ppf "Operation bytes: " ; - TzString.fold_left (* We split the bytes into lines for display: *) - (fun n c -> - pp_print_char ppf c ; - if - n < 72 - (* is the email-body standard width, ideal for copy-pasting. *) - then n + 1 - else ( - pp_print_space ppf () ; - 0)) - 0 - (Hex.of_bytes bytes |> Hex.show) - |> ignore) ; - item (fun ppf () -> - pp_print_text ppf "Blake 2B Hash (raw): " ; - hash_pp [bytes]) ; - item (fun ppf () -> - pp_print_text - ppf - "Blake 2B Hash (ledger-style, with operation watermark): " ; - hash_pp [Signature.bytes_of_watermark watermark; bytes]) ; - let json = - Data_encoding.Json.construct - Operation.unsigned_encoding - ({branch}, Contents_list contents) - in - item (fun ppf () -> - pp_print_text ppf "JSON encoding: " ; - Data_encoding.Json.pp ppf json) ; - pp_close_box ppf () - -let preapply (type t) (cctxt : #Protocol_client_context.full) ~chain ~block - ?(verbose_signing = false) ?fee_parameter ?branch ?src_sk - (contents : t contents_list) = - get_branch cctxt ~chain ~block branch >>=? fun (_chain_id, branch) -> - let bytes = - Data_encoding.Binary.to_bytes_exn - Operation.unsigned_encoding - ({branch}, Contents_list contents) - in - (match src_sk with - | None -> return_none - | Some src_sk -> - let watermark = - match contents with - (* TODO-TB sign endosrement? *) - | _ -> Signature.Generic_operation - in - (if verbose_signing then - cctxt#message - "Pre-signature information (verbose signing):@.%t%!" - (print_for_verbose_signing ~watermark ~bytes ~branch ~contents) - else Lwt.return_unit) - >>= fun () -> - Client_keys.sign cctxt ~watermark src_sk bytes >>=? fun signature -> - return_some signature) - >>=? fun signature -> - let op : _ Operation.t = - {shell = {branch}; protocol_data = {contents; signature}} - in - let oph = Operation.hash op in - let size = Bytes.length bytes + Signature.size in - (match fee_parameter with - | Some fee_parameter -> check_fees cctxt fee_parameter contents size - | None -> Lwt.return_unit) - >>= fun () -> - Protocol_client_context.Alpha_block_services.Helpers.Preapply.operations - cctxt - ~chain - ~block - [Operation.pack op] - >>=? function - | [(Operation_data op', Operation_metadata result)] -> ( - match - ( Operation.equal op {shell = {branch}; protocol_data = op'}, - Apply_results.kind_equal_list contents result.contents ) - with - | (Some Operation.Eq, Some Apply_results.Eq) -> - return ((oph, op, result) : t preapply_result) - | _ -> failwith "Unexpected result") - | _ -> failwith "Unexpected result" - -let simulate (type t) (cctxt : #Protocol_client_context.full) ~chain ~block - ?branch ?(latency = Plugin.default_operation_inclusion_latency) - (contents : t contents_list) = - get_branch cctxt ~chain ~block branch >>=? fun (_chain_id, branch) -> - let op : _ Operation.t = - {shell = {branch}; protocol_data = {contents; signature = None}} - in - let oph = Operation.hash op in - Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> - Plugin.RPC.Scripts.simulate_operation - cctxt - (chain, block) - ~op:(Operation.pack op) - ~chain_id - ~latency - >>=? function - | (Operation_data op', Operation_metadata result) -> ( - match - ( Operation.equal op {shell = {branch}; protocol_data = op'}, - Apply_results.kind_equal_list contents result.contents ) - with - | (Some Operation.Eq, Some Apply_results.Eq) -> - return ((oph, op, result) : t preapply_result) - | _ -> failwith "Unexpected result") - | _ -> failwith "Unexpected result" - -let estimated_gas_single (type kind) - (Manager_operation_result {operation_result; internal_operation_results; _} : - kind Kind.manager contents_result) = - let consumed_gas (type kind) (result : kind manager_operation_result) = - match result with - | Applied (Transaction_result {consumed_gas; _}) -> Ok consumed_gas - | Applied (Origination_result {consumed_gas; _}) -> Ok consumed_gas - | Applied (Reveal_result {consumed_gas}) -> Ok consumed_gas - | Applied (Delegation_result {consumed_gas}) -> Ok consumed_gas - | Applied (Register_global_constant_result {consumed_gas; _}) -> - Ok consumed_gas - | Applied (Set_deposits_limit_result {consumed_gas}) -> Ok consumed_gas - | Skipped _ -> assert false - | Backtracked (_, None) -> - Ok Gas.Arith.zero (* there must be another error for this to happen *) - | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) - | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) - in - List.fold_left - (fun acc (Internal_operation_result (_, r)) -> - acc >>? fun acc -> - consumed_gas r >>? fun gas -> Ok (Gas.Arith.add acc gas)) - (consumed_gas operation_result) - internal_operation_results - -let estimated_storage_single (type kind) origination_size - (Manager_operation_result {operation_result; internal_operation_results; _} : - kind Kind.manager contents_result) = - let storage_size_diff (type kind) (result : kind manager_operation_result) = - match result with - | Applied - (Transaction_result - {paid_storage_size_diff; allocated_destination_contract; _}) -> - if allocated_destination_contract then - Ok (Z.add paid_storage_size_diff origination_size) - else Ok paid_storage_size_diff - | Applied (Origination_result {paid_storage_size_diff; _}) -> - Ok (Z.add paid_storage_size_diff origination_size) - | Applied (Reveal_result _) -> Ok Z.zero - | Applied (Delegation_result _) -> Ok Z.zero - | Applied (Register_global_constant_result {size_of_constant; _}) -> - Ok size_of_constant - | Applied (Set_deposits_limit_result _) -> Ok Z.zero - | Skipped _ -> assert false - | Backtracked (_, None) -> - Ok Z.zero (* there must be another error for this to happen *) - | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) - | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) - in - List.fold_left - (fun acc (Internal_operation_result (_, r)) -> - acc >>? fun acc -> - storage_size_diff r >>? fun storage -> Ok (Z.add acc storage)) - (storage_size_diff operation_result) - internal_operation_results - -let estimated_storage origination_size res = - let rec estimated_storage : type kind. kind contents_result_list -> _ = - function - | Single_result (Manager_operation_result _ as res) -> - estimated_storage_single origination_size res - | Single_result _ -> Ok Z.zero - | Cons_result (res, rest) -> - estimated_storage_single origination_size res >>? fun storage1 -> - estimated_storage rest >>? fun storage2 -> Ok (Z.add storage1 storage2) - in - estimated_storage res >>? fun diff -> Ok (Z.max Z.zero diff) - -let originated_contracts_single (type kind) - (Manager_operation_result {operation_result; internal_operation_results; _} : - kind Kind.manager contents_result) = - let originated_contracts (type kind) (result : kind manager_operation_result) - = - match result with - | Applied (Transaction_result {originated_contracts; _}) -> - Ok originated_contracts - | Applied (Origination_result {originated_contracts; _}) -> - Ok originated_contracts - | Applied (Register_global_constant_result _) -> Ok [] - | Applied (Reveal_result _) -> Ok [] - | Applied (Delegation_result _) -> Ok [] - | Applied (Set_deposits_limit_result _) -> Ok [] - | Skipped _ -> assert false - | Backtracked (_, None) -> - Ok [] (* there must be another error for this to happen *) - | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) - | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) - in - List.fold_left - (fun acc (Internal_operation_result (_, r)) -> - acc >>? fun acc -> - originated_contracts r >>? fun contracts -> - Ok (List.rev_append contracts acc)) - (originated_contracts operation_result >|? List.rev) - internal_operation_results - -let rec originated_contracts : type kind. kind contents_result_list -> _ = - function - | Single_result (Manager_operation_result _ as res) -> - originated_contracts_single res >|? List.rev - | Single_result _ -> Ok [] - | Cons_result (res, rest) -> - originated_contracts_single res >>? fun contracts1 -> - originated_contracts rest >>? fun contracts2 -> - Ok (List.rev_append contracts1 contracts2) - -let detect_script_failure : type kind. kind operation_metadata -> _ = - let rec detect_script_failure : type kind. kind contents_result_list -> _ = - let detect_script_failure_single (type kind) - (Manager_operation_result - {operation_result; internal_operation_results; _} : - kind Kind.manager contents_result) = - let detect_script_failure (type kind) - (result : kind manager_operation_result) = - match result with - | Applied _ -> Ok () - | Skipped _ -> assert false - | Backtracked (_, None) -> - (* there must be another error for this to happen *) - Ok () - | Backtracked (_, Some errs) -> - record_trace - (error_of_fmt "The transfer simulation failed.") - (Error (Environment.wrap_tztrace errs)) - | Failed (_, errs) -> - record_trace - (error_of_fmt "The transfer simulation failed.") - (Error (Environment.wrap_tztrace errs)) - in - List.fold_left - (fun acc (Internal_operation_result (_, r)) -> - acc >>? fun () -> detect_script_failure r) - (detect_script_failure operation_result) - internal_operation_results - in - function - | Single_result (Manager_operation_result _ as res) -> - detect_script_failure_single res - | Single_result _ -> Ok () - | Cons_result (res, rest) -> - detect_script_failure_single res >>? fun () -> - detect_script_failure rest - in - fun {contents} -> detect_script_failure contents - -(* This value is used as a safety guard for gas limit. *) -let safety_guard = Gas.Arith.(integral_of_int_exn 100) - -(* - - {2 High-level description of the automatic gas patching algorithm} - - When the user wants to inject a list of operations, some of which - might have unspecified gas, fees or storage limit, the client - performs a {e simulation} to estimate those limits and assign - sensible values to them. - - The simulation works as follows: - 1. limits are assigned to dummy, high values to ensure that the operations - can be simulated - - 1.a) when a list of operations is partially specified, the algorithm - allocates to each unspecified operation an equal portion of the - maximum gas per block minus the gas consumed by the operations that - do specify their limit - 2. the algorithm retrieves the effectively consumed gas and storage from the - receipt - 3. the algorithm assigns slight overapproximations to the operation - 4. a default fee is computed and set - -*) - -let may_patch_limits (type kind) (cctxt : #Protocol_client_context.full) - ~fee_parameter ~chain ~block ?branch - (annotated_contents : kind Annotated_manager_operation.annotated_list) : - kind Kind.manager contents_list tzresult Lwt.t = - Tezos_client_base.Client_confirmations.wait_for_bootstrapped cctxt - >>=? fun () -> - Alpha_services.Constants.all cctxt (chain, block) - >>=? fun { - parametric = - { - hard_gas_limit_per_operation; - hard_gas_limit_per_block; - hard_storage_limit_per_operation; - origination_size; - cost_per_byte; - _; - }; - _; - } -> - let user_gas_limit_needs_patching user_gas_limit = - Limit.fold user_gas_limit ~unknown:true ~known:(fun user_gas_limit -> - Gas.Arith.( - user_gas_limit < zero || hard_gas_limit_per_operation < user_gas_limit)) - in - let user_storage_limit_needs_patching user_storage_limit = - Limit.fold - user_storage_limit - ~unknown:true - ~known:(fun user_storage_limit -> - Z.Compare.( - user_storage_limit < Z.zero - || hard_storage_limit_per_operation < user_storage_limit)) - in - let gas_patching_stats (Annotated_manager_operation.Manager_info c) - need_patching gas_consumed = - if user_gas_limit_needs_patching c.gas_limit then - (need_patching + 1, gas_consumed) - else - ( need_patching, - Gas.Arith.add - gas_consumed - (Limit.value ~when_unknown:Gas.Arith.zero c.gas_limit) ) - in - let rec gas_patching_stats_list : - type kind. - kind Annotated_manager_operation.annotated_list -> - int -> - Saturation_repr.may_saturate Saturation_repr.t -> - int * Saturation_repr.may_saturate Saturation_repr.t = - fun op need_patching gas_consumed -> - match op with - | Single_manager minfo -> - gas_patching_stats minfo need_patching gas_consumed - | Cons_manager (minfo, rest) -> - let (need_patching, gas_consumed) = - gas_patching_stats minfo need_patching gas_consumed - in - gas_patching_stats_list rest need_patching gas_consumed - in - let may_need_patching_single : - type kind. - Gas.Arith.integral -> - kind Annotated_manager_operation.t -> - kind Annotated_manager_operation.t option = - fun gas_limit_per_patched_op op -> - match op with - | Manager_info c -> - let needs_patching = - Limit.is_unknown c.fee - || user_gas_limit_needs_patching c.gas_limit - || user_storage_limit_needs_patching c.storage_limit - in - if not needs_patching then None - else - (* Set limits for simulation purposes *) - let gas_limit = - if user_gas_limit_needs_patching c.gas_limit then - Limit.known gas_limit_per_patched_op - else c.gas_limit - in - let storage_limit = - if user_storage_limit_needs_patching c.storage_limit then - Limit.known hard_storage_limit_per_operation - else c.storage_limit - in - let fee = Limit.value ~when_unknown:Tez.zero c.fee in - Some - (Manager_info - {c with gas_limit; storage_limit; fee = Limit.known fee}) - in - let may_need_patching gas_limit_per_patched_op ops = - let rec loop : - type kind. - kind Annotated_manager_operation.annotated_list -> - kind Annotated_manager_operation.annotated_list option = function - | Single_manager annotated_op -> - Option.map (fun op -> Annotated_manager_operation.Single_manager op) - @@ may_need_patching_single gas_limit_per_patched_op annotated_op - | Cons_manager (annotated_op, rest) -> ( - let annotated_op_opt = - may_need_patching_single gas_limit_per_patched_op annotated_op - in - let rest_opt = loop rest in - match (annotated_op_opt, rest_opt) with - | (None, None) -> None - | _ -> - let op = Option.value ~default:annotated_op annotated_op_opt in - let rest = Option.value ~default:rest rest_opt in - Some (Cons_manager (op, rest))) - in - loop ops - in - (* - The recursion here handles the case where an increased fee might increase the - size of the operation, and so require a recalculation of the gas costs. - Rationale for termination: - - the fee for size increases linearly with the size of the operation. - - however, when the size of the operation increase to make space for an - increased fee, the amount of new fee that can be added without increasing - the size of the block again increases exponentially. - - hence, there will eventually be a increase of size that will fit any new - fee without having to increase the size of the operation again. - *) - let rec patch_fee : type kind. first:bool -> kind contents -> kind contents = - fun ~first -> function - | Manager_operation c as op -> ( - let size = - if first then - (WithExceptions.Option.get ~loc:__LOC__ - @@ Data_encoding.Binary.fixed_length - Tezos_base.Operation.shell_header_encoding) - + Data_encoding.Binary.length - Operation.contents_encoding - (Contents op) - + Signature.size - else - Data_encoding.Binary.length - Operation.contents_encoding - (Contents op) - in - let minimal_fees_in_nanotez = - Q.mul - (Q.of_int64 (Tez.to_mutez fee_parameter.minimal_fees)) - (Q.of_int 1000) - in - let minimal_fees_for_gas_in_nanotez = - Q.mul - fee_parameter.minimal_nanotez_per_gas_unit - (Q.of_bigint @@ Gas.Arith.integral_to_z c.gas_limit) - in - let minimal_fees_for_size_in_nanotez = - Q.mul fee_parameter.minimal_nanotez_per_byte (Q.of_int size) - in - let fees_in_nanotez = - Q.add minimal_fees_in_nanotez - @@ Q.add - minimal_fees_for_gas_in_nanotez - minimal_fees_for_size_in_nanotez - in - let fees_in_mutez = z_mutez_of_q_nanotez fees_in_nanotez in - match Tez.of_mutez (Z.to_int64 fees_in_mutez) with - | None -> assert false - | Some fee -> - if Tez.(fee <= c.fee) then op - else patch_fee ~first (Manager_operation {c with fee})) - | c -> c - in - let patch : - type kind. - first:bool -> - kind Annotated_manager_operation.t * kind Kind.manager contents_result -> - kind Kind.manager contents tzresult Lwt.t = - fun ~first -> function - | ((Manager_info c as op), (Manager_operation_result _ as result)) -> - (if user_gas_limit_needs_patching c.gas_limit then - Lwt.return (estimated_gas_single result) >>=? fun gas -> - if Gas.Arith.(gas = zero) then - cctxt#message "Estimated gas: none" >>= fun () -> - return - (Annotated_manager_operation.set_gas_limit - (Limit.known Gas.Arith.zero) - op) - else - cctxt#message - "Estimated gas: %a units (will add 100 for safety)" - Gas.Arith.pp - gas - >>= fun () -> - let safe_gas = Gas.Arith.(add (ceil gas) safety_guard) in - let patched_gas = - Gas.Arith.min safe_gas hard_gas_limit_per_operation - in - return - (Annotated_manager_operation.set_gas_limit - (Limit.known patched_gas) - op) - else return op) - >>=? fun op -> - (if user_storage_limit_needs_patching c.storage_limit then - Lwt.return - (estimated_storage_single (Z.of_int origination_size) result) - >>=? fun storage -> - if Z.equal storage Z.zero then - cctxt#message "Estimated storage: no bytes added" >>= fun () -> - return - (Annotated_manager_operation.set_storage_limit - (Limit.known Z.zero) - op) - else - cctxt#message - "Estimated storage: %s bytes added (will add 20 for safety)" - (Z.to_string storage) - >>= fun () -> - let storage_limit = - Z.min - (Z.add storage (Z.of_int 20)) - hard_storage_limit_per_operation - in - return - (Annotated_manager_operation.set_storage_limit - (Limit.known storage_limit) - op) - else return op) - >>=? fun op -> - if Limit.is_unknown c.fee then - (* Setting a dummy fee is required for converting to manager op *) - let op = - Annotated_manager_operation.set_fee (Limit.known Tez.zero) op - in - Annotated_manager_operation.manager_from_annotated op >>?= fun cm -> - return (patch_fee ~first cm) - else Lwt.return (Annotated_manager_operation.manager_from_annotated op) - in - let rec patch_list : - type kind. - bool -> - kind Annotated_manager_operation.annotated_list -> - kind Kind.manager contents_result_list -> - kind Kind.manager contents_list tzresult Lwt.t = - fun first annotated_list result_list -> - match (annotated_list, result_list) with - | (Single_manager annotated, Single_result res) -> - patch ~first (annotated, res) >>=? fun op -> return (Single op) - | (Cons_manager (annotated, annotated_rest), Cons_result (res, res_rest)) -> - patch ~first (annotated, res) >>=? fun op -> - patch_list false annotated_rest res_rest >>=? fun rest -> - return (Cons (op, rest)) - | _ -> assert false - in - let gas_limit_per_patched_op = - let (need_gas_patching, gas_consumed) = - gas_patching_stats_list annotated_contents 0 Gas.Arith.zero - in - if need_gas_patching = 0 then hard_gas_limit_per_operation - else - let remaining_gas = Gas.Arith.sub hard_gas_limit_per_block gas_consumed in - let average_per_operation_gas = - Gas.Arith.integral_exn - @@ Z.div - (Gas.Arith.integral_to_z remaining_gas) - (Z.of_int need_gas_patching) - in - Gas.Arith.min hard_gas_limit_per_operation average_per_operation_gas - in - match may_need_patching gas_limit_per_patched_op annotated_contents with - | Some annotated_for_simulation -> - Lwt.return - (Annotated_manager_operation.manager_list_from_annotated - annotated_for_simulation) - >>=? fun contents_for_simulation -> - simulate cctxt ~chain ~block ?branch contents_for_simulation - >>=? fun (_, _, result) -> - (match detect_script_failure result with - | Ok () -> return_unit - | Error _ -> - cctxt#message - "@[This simulation failed:@,%a@]" - Operation_result.pp_operation_result - (contents_for_simulation, result.contents) - >>= fun () -> return_unit) - >>=? fun () -> - ( Lwt.return - (estimated_storage (Z.of_int origination_size) result.contents) - >>=? fun storage -> - Lwt.return - (Environment.wrap_tzresult Tez.(cost_per_byte *? Z.to_int64 storage)) - >>=? fun burn -> - if Tez.(burn > fee_parameter.burn_cap) then - cctxt#error - "The operation will burn %s%a which is higher than the configured \ - burn cap (%s%a).@\n\ - \ Use `--burn-cap %a` to emit this operation." - Client_proto_args.tez_sym - Tez.pp - burn - Client_proto_args.tez_sym - Tez.pp - fee_parameter.burn_cap - Tez.pp - burn - >>= fun () -> exit 1 - else return_unit ) - >>=? fun () -> patch_list true annotated_contents result.contents - | None -> - Lwt.return - (Annotated_manager_operation.manager_list_from_annotated - annotated_contents) - -let tenderbake_finality_confirmations = 1 - -let tenderbake_adjust_confirmations (cctxt : #Client_context.full) = function - | None -> Lwt.return_none - | Some cli_confirmations -> - if cli_confirmations > tenderbake_finality_confirmations then - cctxt#message - "Tenderbake needs at most %d confirmations for finality (%d given). \ - Using %d confirmations." - tenderbake_finality_confirmations - cli_confirmations - tenderbake_finality_confirmations - >>= fun () -> Lwt.return_some tenderbake_finality_confirmations - else Lwt.return_some cli_confirmations - -(* For Tenderbake we restrain the interval of confirmations to be [0, - tenderbake_finality_confirmations] - - Any value greater than the tenderbake_finality_confirmations is treated as if it - were tenderbake_finality_confirmations. - *) -let inject_operation_internal (type kind) cctxt ~chain ~block ?confirmations - ?(dry_run = false) ?(simulation = false) ?branch ?src_sk ?verbose_signing - ~fee_parameter (contents : kind contents_list) = - (if simulation then simulate cctxt ~chain ~block ?branch contents - else - preapply - cctxt - ~chain - ~block - ~fee_parameter - ?verbose_signing - ?branch - ?src_sk - contents) - >>=? fun (_oph, op, result) -> - (match detect_script_failure result with - | Ok () -> return_unit - | Error _ as res -> - cctxt#message - "@[This simulation failed:@,%a@]" - Operation_result.pp_operation_result - (op.protocol_data.contents, result.contents) - >>= fun () -> Lwt.return res) - >>=? fun () -> - let bytes = - Data_encoding.Binary.to_bytes_exn Operation.encoding (Operation.pack op) - in - if dry_run || simulation then - let oph = Operation_hash.hash_bytes [bytes] in - cctxt#message - "@[Operation: 0x%a@,Operation hash is '%a'@]" - Hex.pp - (Hex.of_bytes bytes) - Operation_hash.pp - oph - >>= fun () -> - cctxt#message - "@[Simulation result:@,%a@]" - Operation_result.pp_operation_result - (op.protocol_data.contents, result.contents) - >>= fun () -> return (oph, op.protocol_data.contents, result.contents) - else - Shell_services.Injection.operation cctxt ~chain bytes >>=? fun oph -> - cctxt#message "Operation successfully injected in the node." >>= fun () -> - cctxt#message "Operation hash is '%a'" Operation_hash.pp oph >>= fun () -> - (* Adjust user-provided confirmations with respect to Alpha protocol finality properties *) - tenderbake_adjust_confirmations cctxt confirmations >>= fun confirmations -> - (match confirmations with - | None -> - cctxt#message - "@[NOT waiting for the operation to be included.@,\ - Use command@,\ - \ tezos-client wait for %a to be included --confirmations %d \ - --branch %a@,\ - and/or an external block explorer to make sure that it has been \ - included.@]" - Operation_hash.pp - oph - tenderbake_finality_confirmations - Block_hash.pp - op.shell.branch - >>= fun () -> return result - | Some confirmations -> ( - cctxt#message "Waiting for the operation to be included..." - >>= fun () -> - Client_confirmations.wait_for_operation_inclusion - ~branch:op.shell.branch - ~confirmations - cctxt - ~chain - oph - >>=? fun (h, i, j) -> - Alpha_block_services.Operations.operation - cctxt - ~chain - ~block:(`Hash (h, 0)) - i - j - >>=? fun op' -> - match op'.receipt with - | None -> failwith "Internal error: pruned metadata." - | Some No_operation_metadata -> - failwith "Internal error: unexpected receipt." - | Some (Operation_metadata receipt) -> ( - match Apply_results.kind_equal_list contents receipt.contents with - | Some Apply_results.Eq -> - return (receipt : kind operation_metadata) - | None -> failwith "Internal error: unexpected receipt."))) - >>=? fun result -> - cctxt#message - "@[This sequence of operations was run:@,%a@]" - Operation_result.pp_operation_result - (op.protocol_data.contents, result.contents) - >>= fun () -> - Lwt.return (originated_contracts result.contents) >>=? fun contracts -> - List.iter_s - (fun c -> cctxt#message "New contract %a originated." Contract.pp c) - contracts - >>= fun () -> - (match confirmations with - | None -> Lwt.return_unit - | Some number -> - if number >= tenderbake_finality_confirmations then - cctxt#message - "The operation was included in a block %d blocks ago." - number - else - cctxt#message - "@[The operation has only been included %d blocks ago.@,\ - We recommend to wait more.@,\ - Use command@,\ - \ tezos-client wait for %a to be included --confirmations %d \ - --branch %a@,\ - and/or an external block explorer.@]" - number - Operation_hash.pp - oph - tenderbake_finality_confirmations - Block_hash.pp - op.shell.branch) - >>= fun () -> return (oph, op.protocol_data.contents, result.contents) - -let inject_operation (type kind) cctxt ~chain ~block ?confirmations - ?(dry_run = false) ?(simulation = false) ?branch ?src_sk ?verbose_signing - ~fee_parameter (contents : kind contents_list) = - Tezos_client_base.Client_confirmations.wait_for_bootstrapped cctxt - >>=? fun () -> - inject_operation_internal - cctxt - ~chain - ~block - ?confirmations - ~dry_run - ~simulation - ?branch - ?src_sk - ?verbose_signing - ~fee_parameter - (contents : kind contents_list) - -let prepare_manager_operation ~fee ~gas_limit ~storage_limit operation = - Annotated_manager_operation.Manager_info - {source = None; fee; gas_limit; storage_limit; counter = None; operation} - -(* [gas_limit] must correspond to - [Michelson_v1_gas.Cost_of.manager_operation] *) -let cost_of_manager_operation = Gas.Arith.integral_of_int_exn 1_000 - -let reveal_error_message = - "Requested operation requires to perform a public key revelation beforehand.\n\ - This cannot be done automatically when a custom fee or storage limit is \ - given.\n\ - If you wish to use a custom fee or storage limit, please first perform the \ - reveal operation separately using the dedicated command.\n\ - Otherwise, please do not specify custom fee or storage parameters." - -let reveal_error (cctxt : #Protocol_client_context.full) = - cctxt#error "%s" reveal_error_message - -let inject_manager_operation cctxt ~chain ~block ?branch ?confirmations ?dry_run - ?verbose_signing ?simulation ~source ~src_pk ~src_sk ~fee ~gas_limit - ~storage_limit ?counter ~fee_parameter (type kind) - (operations : kind Annotated_manager_operation.annotated_list) : - (Operation_hash.t - * kind Kind.manager contents_list - * kind Kind.manager contents_result_list) - tzresult - Lwt.t = - (match counter with - | None -> - Alpha_services.Contract.counter cctxt (chain, block) source - >>=? fun pcounter -> - let counter = Z.succ pcounter in - return counter - | Some counter -> return counter) - >>=? fun counter -> - Alpha_services.Contract.manager_key cctxt (chain, block) source - >>=? fun key -> - (* [has_reveal] assumes that a Reveal operation only appears as the first of a batch *) - let has_reveal : - type kind. kind Annotated_manager_operation.annotated_list -> bool = - function - | Single_manager (Manager_info {operation = Reveal _; _}) -> true - | Cons_manager (Manager_info {operation = Reveal _; _}, _) -> true - | _ -> false - in - let apply_specified_options counter op = - Annotated_manager_operation.set_source source op >>? fun op -> - Annotated_manager_operation.set_counter counter op >>? fun op -> - Annotated_manager_operation.join_fee fee op >>? fun op -> - Annotated_manager_operation.join_gas_limit gas_limit op >>? fun op -> - Annotated_manager_operation.join_storage_limit storage_limit op - in - let rec build_contents : - type kind. - Z.t -> - kind Annotated_manager_operation.annotated_list -> - kind Annotated_manager_operation.annotated_list tzresult = - fun counter -> function - | Single_manager op -> - apply_specified_options counter op >|? fun op -> - Annotated_manager_operation.Single_manager op - | Cons_manager (op, rest) -> - apply_specified_options counter op >>? fun op -> - build_contents (Z.succ counter) rest >|? fun rest -> - Annotated_manager_operation.Cons_manager (op, rest) - in - match key with - | None when not (has_reveal operations) -> ( - (if not (Limit.is_unknown fee && Limit.is_unknown storage_limit) then - reveal_error cctxt - else return_unit) - >>=? fun () -> - let reveal = - prepare_manager_operation - ~fee:Limit.unknown - ~gas_limit:(Limit.known cost_of_manager_operation) - ~storage_limit:Limit.unknown - (Reveal src_pk) - in - Annotated_manager_operation.set_source source reveal >>?= fun reveal -> - Annotated_manager_operation.set_counter counter reveal >>?= fun reveal -> - build_contents (Z.succ counter) operations >>?= fun rest -> - let contents = Annotated_manager_operation.Cons_manager (reveal, rest) in - may_patch_limits cctxt ~fee_parameter ~chain ~block ?branch contents - >>=? fun contents -> - inject_operation_internal - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?simulation - ~fee_parameter - ?verbose_signing - ?branch - ~src_sk - contents - >>=? fun (oph, op, result) -> - match pack_contents_list op result with - | Cons_and_result (_, _, rest) -> - let (op, result) = unpack_contents_list rest in - return (oph, op, result) - | _ -> assert false) - | Some _ when has_reveal operations -> - failwith "The manager key was previously revealed." - | _ -> - build_contents counter operations >>?= fun contents -> - may_patch_limits cctxt ~fee_parameter ~chain ~block ?branch contents - >>=? fun contents -> - inject_operation_internal - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?simulation - ~fee_parameter - ?branch - ~src_sk - contents diff --git a/src/proto_012_Psithaca/lib_client/injection.mli b/src/proto_012_Psithaca/lib_client/injection.mli deleted file mode 100644 index d8f99d620510..000000000000 --- a/src/proto_012_Psithaca/lib_client/injection.mli +++ /dev/null @@ -1,105 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Apply_results - -type 'kind preapply_result = - Operation_hash.t * 'kind operation * 'kind operation_metadata - -type fee_parameter = { - minimal_fees : Tez.t; - minimal_nanotez_per_byte : Q.t; - minimal_nanotez_per_gas_unit : Q.t; - force_low_fee : bool; - fee_cap : Tez.t; - burn_cap : Tez.t; -} - -val dummy_fee_parameter : fee_parameter - -val preapply : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?verbose_signing:bool -> - ?fee_parameter:fee_parameter -> - ?branch:int -> - ?src_sk:Client_keys.sk_uri -> - 'kind contents_list -> - 'kind preapply_result tzresult Lwt.t - -type 'kind result_list = - Operation_hash.t * 'kind contents_list * 'kind contents_result_list - -(** /!\ [inject_operation] does not perform automatic patching of - gas, storage and fees; use [inject_manager_operation] to inject - manager operations. *) -val inject_operation : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?simulation:bool -> - ?branch:int -> - ?src_sk:Client_keys.sk_uri -> - ?verbose_signing:bool -> - fee_parameter:fee_parameter -> - 'kind contents_list -> - 'kind result_list tzresult Lwt.t - -type 'kind result = Operation_hash.t * 'kind contents * 'kind contents_result - -val prepare_manager_operation : - fee:Tez.t Limit.t -> - gas_limit:Gas.Arith.integral Limit.t -> - storage_limit:Z.t Limit.t -> - 'kind manager_operation -> - 'kind Annotated_manager_operation.t - -val inject_manager_operation : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - block:Shell_services.block -> - ?branch:int -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?simulation:bool -> - source:Signature.Public_key_hash.t -> - src_pk:Signature.public_key -> - src_sk:Client_keys.sk_uri -> - fee:Tez.t Limit.t -> - gas_limit:Gas.Arith.integral Limit.t -> - storage_limit:Z.t Limit.t -> - ?counter:Z.t -> - fee_parameter:fee_parameter -> - 'kind Annotated_manager_operation.annotated_list -> - 'kind Kind.manager result_list tzresult Lwt.t - -val originated_contracts : - 'kind contents_result_list -> Contract.t list tzresult diff --git a/src/proto_012_Psithaca/lib_client/light.ml b/src/proto_012_Psithaca/lib_client/light.ml deleted file mode 100644 index 038624664ec0..000000000000 --- a/src/proto_012_Psithaca/lib_client/light.ml +++ /dev/null @@ -1,37 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module M : Tezos_proxy.Light_proto.PROTO_RPCS = struct - let merkle_tree (pgi : Tezos_proxy.Proxy.proxy_getter_input) key leaf_kind = - Protocol_client_context.Alpha_block_services.Context.merkle_tree - pgi.rpc_context - ~chain:pgi.chain - ~block:pgi.block - ~holey: - (match leaf_kind with - | Tezos_shell_services.Block_services.Hole -> true - | Tezos_shell_services.Block_services.Raw_context -> false) - key -end diff --git a/src/proto_012_Psithaca/lib_client/limit.ml b/src/proto_012_Psithaca/lib_client/limit.ml deleted file mode 100644 index 3f3c798c02b6..000000000000 --- a/src/proto_012_Psithaca/lib_client/limit.ml +++ /dev/null @@ -1,64 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type 'a t = 'a option - -let unknown = None - -let known x = Some x - -let of_option = Fun.id - -let is_unknown = Option.is_none - -let join (type a) ~where eq (l1 : a t) (l2 : a t) = - match (l1, l2) with - | (None, None) -> Result.return_none - | (Some x, None) | (None, Some x) -> Result.return_some x - | (Some x, Some y) -> - if eq x y then Result.return_some x - else error_with "Limit.join: error (%s)" where - -let%test "join" = - let check res y = - match res with Ok x -> Option.equal Bool.equal x y | Error _ -> false - in - check (join ~where:__LOC__ Bool.equal (Some true) (Some true)) (Some true) - && check (join ~where:__LOC__ Bool.equal None None) None - && check (join ~where:__LOC__ Bool.equal None (Some true)) (Some true) - && check (join ~where:__LOC__ Bool.equal (Some true) None) (Some true) - && not - (Result.is_ok (join ~where:__LOC__ Bool.equal (Some true) (Some false))) - -let get ~when_unknown = function - | None -> error_with "Limit.get: %s" when_unknown - | Some x -> ok x - -let%test "get" = - match get ~when_unknown:"" (Some true) with Ok true -> true | _ -> false - -let fold ~unknown ~known x = match x with None -> unknown | Some x -> known x - -let value ~when_unknown = function None -> when_unknown | Some x -> x diff --git a/src/proto_012_Psithaca/lib_client/limit.mli b/src/proto_012_Psithaca/lib_client/limit.mli deleted file mode 100644 index 3ce610e3450c..000000000000 --- a/src/proto_012_Psithaca/lib_client/limit.mli +++ /dev/null @@ -1,49 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This helper module allows to handle partially specified limits during the - injection process. *) - -(** A value of type ['a t] is either [unknown] of [known]. *) -type 'a t - -val unknown : 'a t - -val known : 'a -> 'a t - -val of_option : 'a option -> 'a t - -val is_unknown : 'a t -> bool - -(** [join ~where eq x y] computes the order-theoretic union of [x] and [y]. - If both [x] and [y] are not [Unknown], the function fails iff their - contents are not equal according to [eq]. *) -val join : where:string -> ('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t tzresult - -val fold : unknown:'a -> known:('b -> 'a) -> 'b t -> 'a - -val get : when_unknown:string -> 'a t -> 'a tzresult - -val value : when_unknown:'a -> 'a t -> 'a diff --git a/src/proto_012_Psithaca/lib_client/managed_contract.ml b/src/proto_012_Psithaca/lib_client/managed_contract.ml deleted file mode 100644 index 29bb3d976b63..000000000000 --- a/src/proto_012_Psithaca/lib_client/managed_contract.ml +++ /dev/null @@ -1,321 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) -open Protocol -open Alpha_context -open Protocol_client_context -open Tezos_micheline - -let return_single_manager_result (oph, op, result) = - match Apply_results.pack_contents_list op result with - | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> - return (oph, op, result) - | _ -> assert false - -let get_contract_manager (cctxt : #full) contract = - let open Micheline in - let open Michelson_v1_primitives in - Client_proto_context.get_storage - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~unparsing_mode:Optimized - contract - >>=? function - | None -> cctxt#error "This is not a smart contract." - | Some storage -> ( - match root storage with - | Prim (_, D_Pair, Bytes (_, bytes) :: _, _) | Bytes (_, bytes) -> ( - match - Data_encoding.Binary.of_bytes_opt - Signature.Public_key_hash.encoding - bytes - with - | Some k -> return k - | None -> - cctxt#error - "Cannot find a manager key in contracts storage (decoding \ - bytes failed).\n\ - Transfer from scripted contract are currently only supported \ - for \"manager\" contract.") - | Prim (_, D_Pair, String (_, value) :: _, _) | String (_, value) -> ( - match Signature.Public_key_hash.of_b58check_opt value with - | Some k -> return k - | None -> - cctxt#error - "Cannot find a manager key in contracts storage (\"%s\" is not \ - a valid key).\n\ - Transfer from scripted contract are currently only supported \ - for \"manager\" contract." - value) - | _raw_storage -> - cctxt#error - "Cannot find a manager key in contracts storage (wrong storage \ - format : @[%a@]).\n\ - Transfer from scripted contract are currently only supported for \ - \"manager\" contract." - Michelson_v1_printer.print_expr - storage) - -let parse code = - Lwt.return - ( Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression code - >>? fun exp -> - Error_monad.ok @@ Script.lazy_expr Michelson_v1_parser.(exp.expanded) ) - -let build_lambda_for_set_delegate ~delegate = - match delegate with - | Some delegate -> - let (`Hex delegate) = Signature.Public_key_hash.to_hex delegate in - Format.asprintf - "{ DROP ; NIL operation ; PUSH key_hash 0x%s ; SOME ; SET_DELEGATE ; \ - CONS }" - delegate - | None -> "{ DROP ; NIL operation ; NONE key_hash ; SET_DELEGATE ; CONS }" - -let build_delegate_operation (cctxt : #full) ~chain ~block ?fee - contract (* the KT1 to delegate *) - (delegate : Signature.public_key_hash option) = - let entrypoint = "do" in - (Michelson_v1_entrypoints.contract_entrypoint_type - cctxt - ~chain - ~block - ~contract - ~entrypoint - >>=? function - | Some _ -> - (* their is a "do" entrypoint (we could check its type here)*) - parse @@ build_lambda_for_set_delegate ~delegate >>=? fun param -> - return (param, entrypoint) - | None -> ( - (* their is no "do" entrypoint trying "set/remove_delegate" *) - let entrypoint = - match delegate with - | Some _ -> "set_delegate" - | None -> "remove_delegate" - in - Michelson_v1_entrypoints.contract_entrypoint_type - cctxt - ~chain - ~block - ~contract - ~entrypoint - >>=? function - | Some _ -> - (* their is a "set/remove_delegate" entrypoint *) - let delegate_data = - match delegate with - | Some delegate -> - let (`Hex delegate) = - Signature.Public_key_hash.to_hex delegate - in - "0x" ^ delegate - | None -> "Unit" - in - parse delegate_data >>=? fun param -> return (param, entrypoint) - | None -> - cctxt#error - "Cannot find a %%do or %%set_delegate entrypoint in contract@.")) - >>=? fun (parameters, entrypoint) -> - return - (Client_proto_context.build_transaction_operation - ~amount:Tez.zero - ~parameters - ~entrypoint - ?fee - contract) - -let set_delegate (cctxt : #full) ~chain ~block ?confirmations ?dry_run - ?verbose_signing ?simulation ?branch ~fee_parameter ?fee ~source ~src_pk - ~src_sk contract (* the KT1 to delegate *) - (delegate : Signature.public_key_hash option) = - build_delegate_operation cctxt ~chain ~block ?fee contract delegate - >>=? fun operation -> - let operation = Annotated_manager_operation.Single_manager operation in - Injection.inject_manager_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?simulation - ?branch - ~source - ~fee:(Limit.of_option fee) - ~gas_limit:Limit.unknown - ~storage_limit:(Limit.known Z.zero) - ~src_pk - ~src_sk - ~fee_parameter - operation - >>=? return_single_manager_result - -let d_unit = - Micheline.strip_locations (Prim (0, Michelson_v1_primitives.D_Unit, [], [])) - -let t_unit = - Micheline.strip_locations (Prim (0, Michelson_v1_primitives.T_unit, [], [])) - -let build_lambda_for_transfer_to_implicit ~destination ~amount = - let (`Hex destination) = Signature.Public_key_hash.to_hex destination in - Format.asprintf - "{ DROP ; NIL operation ;PUSH key_hash 0x%s; IMPLICIT_ACCOUNT;PUSH mutez \ - %Ld ;UNIT;TRANSFER_TOKENS ; CONS }" - destination - (Tez.to_mutez amount) - -let build_lambda_for_transfer_to_originated ~destination ~entrypoint ~amount - ~parameter_type ~parameter = - let destination = - Data_encoding.Binary.to_bytes_exn Contract.encoding destination - in - let amount = Tez.to_mutez amount in - let (`Hex destination) = Hex.of_bytes destination in - let entrypoint = match entrypoint with "default" -> "" | s -> "%" ^ s in - if parameter_type = t_unit then - Format.asprintf - "{ DROP ; NIL operation ;PUSH address 0x%s; CONTRACT %s %a; \ - ASSERT_SOME;PUSH mutez %Ld ;UNIT;TRANSFER_TOKENS ; CONS }" - destination - entrypoint - Michelson_v1_printer.print_expr - parameter_type - amount - else - Format.asprintf - "{ DROP ; NIL operation ;PUSH address 0x%s; CONTRACT %s %a; \ - ASSERT_SOME;PUSH mutez %Ld ;PUSH %a %a;TRANSFER_TOKENS ; CONS }" - destination - entrypoint - Michelson_v1_printer.print_expr - parameter_type - amount - Michelson_v1_printer.print_expr - parameter_type - Michelson_v1_printer.print_expr - parameter - -let build_transaction_operation (cctxt : #full) ~chain ~block ~contract - ~destination ?(entrypoint = "default") ?arg ~amount ?fee ?gas_limit - ?storage_limit () = - (match Alpha_context.Contract.is_implicit destination with - | Some destination when entrypoint = "default" -> - return @@ build_lambda_for_transfer_to_implicit ~destination ~amount - | Some _ -> - cctxt#error - "Implicit accounts have no entrypoints. (targeted entrypoint %%%s on \ - contract %a)" - entrypoint - Contract.pp - destination - | None -> - (Michelson_v1_entrypoints.contract_entrypoint_type - cctxt - ~chain - ~block - ~contract:destination - ~entrypoint - >>=? function - | None -> - cctxt#error - "Contract %a has no entrypoint named %s" - Contract.pp - destination - entrypoint - | Some parameter_type -> return parameter_type) - >>=? fun parameter_type -> - (match arg with - | Some arg -> - Lwt.return @@ Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression arg - >>=? fun {expanded = arg; _} -> return_some arg - | None -> return_none) - >>=? fun parameter -> - let parameter = Option.value ~default:d_unit parameter in - return - @@ build_lambda_for_transfer_to_originated - ~destination - ~entrypoint - ~amount - ~parameter_type - ~parameter) - >>=? fun lambda -> - parse lambda >>=? fun parameters -> - let entrypoint = "do" in - return - (Client_proto_context.build_transaction_operation - ~amount:Tez.zero - ~parameters - ~entrypoint - ?fee - ?gas_limit - ?storage_limit - contract) - -let transfer (cctxt : #full) ~chain ~block ?confirmations ?dry_run - ?verbose_signing ?simulation ?branch ~source ~src_pk ~src_sk ~contract - ~destination ?(entrypoint = "default") ?arg ~amount ?fee ?gas_limit - ?storage_limit ?counter ~fee_parameter () : - (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult - Lwt.t = - build_transaction_operation - cctxt - ~chain - ~block - ~contract - ~destination - ~entrypoint - ?arg - ~amount - ?fee - ?gas_limit - ?storage_limit - () - >>=? fun operation -> - let operation = Annotated_manager_operation.Single_manager operation in - Injection.inject_manager_operation - cctxt - ~chain - ~block - ?confirmations - ?dry_run - ?verbose_signing - ?simulation - ?branch - ~source - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - ?counter - ~src_pk - ~src_sk - ~fee_parameter - operation - >>=? fun (oph, op, result) -> - Lwt.return (Injection.originated_contracts result) >>=? fun contracts -> - return_single_manager_result (oph, op, result) >>=? fun res -> - return (res, contracts) diff --git a/src/proto_012_Psithaca/lib_client/managed_contract.mli b/src/proto_012_Psithaca/lib_client/managed_contract.mli deleted file mode 100644 index ae532c986987..000000000000 --- a/src/proto_012_Psithaca/lib_client/managed_contract.mli +++ /dev/null @@ -1,125 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) -open Protocol -open Alpha_context -open Protocol_client_context - -(** Retrieve the manager key in a contract storage. - The storage has to be of type `pair key_hash 'a`. -*) -val get_contract_manager : #full -> Contract.t -> public_key_hash tzresult Lwt.t - -(** Builds a delegation operation ready for injection *) -val build_delegate_operation : - #Protocol_client_context.full -> - chain:Chain_services.chain -> - block:Block_services.block -> - ?fee:Tez.t -> - Contract.t -> - public_key_hash option -> - Kind.transaction Annotated_manager_operation.t tzresult Lwt.t - -(** Set the delegate of a manageable contract. - For a contract with a `do`entrypoint, it builds the lambda that set - the provided delegate. - `~source` has to be the registered manager of the contract. -*) -val set_delegate : - #Protocol_client_context.full -> - chain:Chain_services.chain -> - block:Block_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?simulation:bool -> - ?branch:int -> - fee_parameter:Injection.fee_parameter -> - ?fee:Tez.t -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - Contract.t -> - public_key_hash option -> - Kind.transaction Kind.manager Injection.result tzresult Lwt.t - -(** Builds a transaction operation ready for injection *) -val build_transaction_operation : - #Protocol_client_context.full -> - chain:Chain_services.chain -> - block:Block_services.block -> - contract:Contract.t -> - destination:Contract.t -> - ?entrypoint:string -> - ?arg:string -> - amount:Tez.t -> - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:counter -> - unit -> - Kind.transaction Annotated_manager_operation.t tzresult Lwt.t - -(** Perform a transfer on behalf of a managed contract . - For a contract with a `do`entrypoint, it builds the lambda that - does the requested operation. - `~source` has to be the registered manager of the contract. -*) -val transfer : - #Protocol_client_context.full -> - chain:Chain_services.chain -> - block:Block_services.block -> - ?confirmations:int -> - ?dry_run:bool -> - ?verbose_signing:bool -> - ?simulation:bool -> - ?branch:int -> - source:public_key_hash -> - src_pk:public_key -> - src_sk:Client_keys.sk_uri -> - contract:Contract.t -> - destination:Contract.t -> - ?entrypoint:string -> - ?arg:string -> - amount:Tez.t -> - ?fee:Tez.t -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:counter -> - ?counter:counter -> - fee_parameter:Injection.fee_parameter -> - unit -> - (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult - Lwt.t - -val build_lambda_for_set_delegate : delegate:public_key_hash option -> string - -val build_lambda_for_transfer_to_implicit : - destination:public_key_hash -> amount:Tez.t -> string - -val build_lambda_for_transfer_to_originated : - destination:Contract.t -> - entrypoint:string -> - amount:Tez.t -> - parameter_type:Script.expr -> - parameter:Script.expr -> - string diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_emacs.ml b/src/proto_012_Psithaca/lib_client/michelson_v1_emacs.ml deleted file mode 100644 index 2721fa702d46..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_emacs.ml +++ /dev/null @@ -1,234 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Tezos_micheline -open Micheline - -let print_expr ppf expr = - let print_annot ppf = function - | [] -> () - | annots -> Format.fprintf ppf " %s" (String.concat " " annots) - in - let rec print_expr ppf = function - | Int (_, value) -> Format.fprintf ppf "%s" (Z.to_string value) - | String (_, value) -> Micheline_printer.print_string ppf value - | Bytes (_, value) -> Format.fprintf ppf "0x%a" Hex.pp (Hex.of_bytes value) - | Seq (_, items) -> - Format.fprintf - ppf - "(seq %a)" - (Format.pp_print_list ~pp_sep:Format.pp_print_space print_expr) - items - | Prim (_, name, [], []) -> Format.fprintf ppf "%s" name - | Prim (_, name, items, annot) -> - Format.fprintf - ppf - "(%s%a%s%a)" - name - print_annot - annot - (if items = [] then "" else " ") - (Format.pp_print_list ~pp_sep:Format.pp_print_space print_expr) - items - in - let root = root (Michelson_v1_primitives.strings_of_prims expr) in - Format.fprintf ppf "@[%a@]" print_expr root - -let print_var_annots ppf = List.iter (Format.fprintf ppf "%s ") - -let print_annot_expr ppf (expr, annot) = - Format.fprintf ppf "(%a%a)" print_var_annots annot print_expr expr - -open Micheline_parser -open Script_tc_errors - -let print_type_map ppf (parsed, type_map) = - let rec print_expr_types ppf = function - | Seq (loc, []) - | Prim (loc, _, [], _) - | Int (loc, _) - | Bytes (loc, _) - | String (loc, _) -> - print_item ppf loc - | Seq (loc, items) | Prim (loc, _, items, _) -> - print_item ppf loc ; - List.iter (print_expr_types ppf) items - and print_stack ppf items = - Format.fprintf - ppf - "(%a)" - (Format.pp_print_list ~pp_sep:Format.pp_print_space print_annot_expr) - items - and print_item ppf loc = - (let ( >?? ) = Option.bind in - List.assoc ~equal:Int.equal loc parsed.Michelson_v1_parser.expansion_table - >?? fun ({start = {point = s; _}; stop = {point = e; _}}, locs) -> - let locs = List.sort Stdlib.compare locs in - List.hd locs >?? fun hd_loc -> - List.assoc ~equal:Int.equal hd_loc type_map >?? fun (bef, aft) -> - Some (s, e, bef, aft)) - |> Option.iter (fun (s, e, bef, aft) -> - Format.fprintf - ppf - "(@[%d %d %a %a@])@," - s - e - print_stack - bef - print_stack - aft) - in - Format.fprintf ppf "(@[%a@])" print_expr_types (root parsed.unexpanded) - -let first_error_location errs = - let rec find = function - | [] -> 0 - | ( Inconsistent_type_annotations (loc, _, _) - | Unexpected_annotation loc - | Ill_formed_type (_, _, loc) - | Invalid_arity (loc, _, _, _) - | Invalid_seq_arity (loc, _, _) - | Invalid_namespace (loc, _, _, _) - | Invalid_primitive (loc, _, _) - | Invalid_kind (loc, _, _) - | Invalid_never_expr loc - | Fail_not_in_tail_position loc - | Undefined_binop (loc, _, _, _) - | Undefined_unop (loc, _, _) - | Bad_return (loc, _, _) - | Bad_stack (loc, _, _, _) - | Unmatched_branches (loc, _, _) - | Invalid_constant (loc, _, _) - | Invalid_syntactic_constant (loc, _, _) - | Invalid_contract (loc, _) - | Comparable_type_expected (loc, _) - | Michelson_v1_primitives.Invalid_primitive_name (_, loc) ) - :: _ -> - loc - | _ :: rest -> find rest - in - find errs - -let report_errors ppf (parsed, errs) = - let (eco, out) = - List.fold_left - (fun (eco, out) -> function - | Environment.Ecoproto_error err -> (err :: eco, out) - | err -> (eco, err :: out)) - ([], []) - errs - in - let (eco, out) = (List.rev eco, List.rev out) in - Format.fprintf - ppf - "(@[%a@,%a@])" - (fun ppf errs -> - let find_location loc = - let oloc = - WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc - ~equal:Int.equal - loc - parsed.Michelson_v1_parser.unexpansion_table - in - fst - (WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc ~equal:Int.equal oloc parsed.expansion_table) - in - match errs with - | top :: errs -> - let (errs, loc) = - ( List.map (fun e -> Environment.Ecoproto_error e) (top :: errs), - match top with - | Ill_typed_contract (expr, _) | Ill_typed_data (_, expr, _) -> - if expr = parsed.expanded then - find_location (first_error_location (top :: errs)) - else find_location 0 - | Michelson_v1_primitives.Invalid_primitive_name (expr, loc) -> - if - Micheline.strip_locations - (Michelson_v1_macros.unexpand_rec (Micheline.root expr)) - = parsed.Michelson_v1_parser.unexpanded - then find_location loc - else find_location 0 - | _ -> find_location 0 ) - in - let message = - Format.asprintf - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:false - ~show_source:false - ~parsed) - errs - in - let {start = {point = s; _}; stop = {point = e; _}} = loc in - Format.fprintf ppf "(%d %d %S)" (s + 1) (e + 1) message - | [] -> ()) - eco - (Format.pp_print_list (fun ppf err -> - let find_location loc = - let oloc = - WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc - ~equal:Int.equal - loc - parsed.Michelson_v1_parser.unexpansion_table - in - fst - (WithExceptions.Option.get ~loc:__LOC__ - @@ List.assoc ~equal:Int.equal oloc parsed.expansion_table) - in - let loc = - match err with - | Invalid_utf8_sequence (point, _) - | Unexpected_character (point, _) - | Undefined_escape_sequence (point, _) - | Missing_break_after_number point -> - {start = point; stop = point} - | Unterminated_string loc - | Unterminated_integer loc - | Unterminated_comment loc - | Invalid_hex_bytes loc - | Unclosed {loc; _} - | Unexpected {loc; _} - | Extra {loc; _} -> - loc - | Misaligned node -> location node - | _ -> find_location 0 - in - let message = - Format.asprintf - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:false - ~show_source:false - ~parsed) - [err] - in - let {start = {point = s; _}; stop = {point = e; _}} = loc in - Format.fprintf ppf "(%d %d %S)" (s + 1) (e + 1) message)) - out diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_emacs.mli b/src/proto_012_Psithaca/lib_client/michelson_v1_emacs.mli deleted file mode 100644 index 6694308d4b02..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_emacs.mli +++ /dev/null @@ -1,39 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -val print_expr : Format.formatter -> Script.expr -> unit - -val print_type_map : - Format.formatter -> - Michelson_v1_parser.parsed * Script_tc_errors.type_map -> - unit - -val report_errors : - Format.formatter -> - Michelson_v1_parser.parsed * Error_monad.error list -> - unit diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_entrypoints.ml b/src/proto_012_Psithaca/lib_client/michelson_v1_entrypoints.ml deleted file mode 100644 index 9d6f08221e8b..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_entrypoints.ml +++ /dev/null @@ -1,216 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Protocol_client_context -open Alpha_context - -type error += Contract_without_code of Contract.t - -let () = - register_error_kind - `Permanent - ~id:"contractWithoutCode" - ~title:"The given contract has no code" - ~description: - "Attempt to get the code of a contract failed because it has nocode. No \ - scriptless contract should remain." - ~pp:(fun ppf contract -> - Format.fprintf ppf "Contract has no code %a." Contract.pp contract) - Data_encoding.(obj1 (req "contract" Contract.encoding)) - (function Contract_without_code c -> Some c | _ -> None) - (fun c -> Contract_without_code c) - -let print_errors (cctxt : #Client_context.printer) errs = - cctxt#error "%a" Error_monad.pp_print_trace errs >>= fun () -> return_unit - -let script_entrypoint_type cctxt ~(chain : Chain_services.chain) ~block - (program : Script.expr) ~entrypoint = - Plugin.RPC.Scripts.entrypoint_type - cctxt - (chain, block) - ~script:program - ~entrypoint - >>= function - | Ok ty -> return_some ty - | Error - (Environment.Ecoproto_error (Script_tc_errors.No_such_entrypoint _) :: _) - -> - return None - | Error _ as err -> Lwt.return err - -let contract_entrypoint_type cctxt ~(chain : Chain_services.chain) ~block - ~contract ~entrypoint = - Alpha_services.Contract.entrypoint_type - cctxt - (chain, block) - contract - entrypoint - >>= function - | Ok ty -> return_some ty - | Error (RPC_context.Not_found _ :: _) -> return None - | Error _ as err -> Lwt.return err - -let print_entrypoint_type (cctxt : #Client_context.printer) - ?(on_errors = print_errors cctxt) ~emacs ?contract ?script_name ~entrypoint - = function - | Ok (Some ty) -> - (if emacs then - cctxt#message - "@[((entrypoint . %s) (type . %a))@]@." - entrypoint - Michelson_v1_emacs.print_expr - ty - else - cctxt#message - "@[Entrypoint %s: %a@]@." - entrypoint - Michelson_v1_printer.print_expr - ty) - >>= fun () -> return_unit - | Ok None -> - cctxt#message - "@[No entrypoint named %s%a%a@]@." - entrypoint - (Format.pp_print_option (fun ppf -> - Format.fprintf ppf " for contract %a" Contract.pp)) - contract - (Format.pp_print_option (fun ppf -> Format.fprintf ppf " for script %s")) - script_name - >>= fun () -> return_unit - | Error errs -> on_errors errs - -let list_contract_unreachables_and_entrypoints cctxt ~chain ~block ~contract = - Alpha_services.Contract.list_entrypoints cctxt (chain, block) contract - -let list_contract_unreachables cctxt ~chain ~block ~contract = - list_contract_unreachables_and_entrypoints cctxt ~chain ~block ~contract - >>=? fun (unreachables, _) -> return unreachables - -let list_contract_entrypoints cctxt ~chain ~block ~contract = - list_contract_unreachables_and_entrypoints cctxt ~chain ~block ~contract - >>=? fun (_, entrypoints) -> - if not @@ List.mem_assoc ~equal:String.equal "default" entrypoints then - contract_entrypoint_type cctxt ~chain ~block ~contract ~entrypoint:"default" - >>= function - | Ok (Some ty) -> return (("default", ty) :: entrypoints) - | Ok None -> return entrypoints - | Error _ as err -> Lwt.return err - else return entrypoints - -let list_unreachables cctxt ~chain ~block (program : Script.expr) = - Plugin.RPC.Scripts.list_entrypoints cctxt (chain, block) ~script:program - >>=? fun (unreachables, _) -> return unreachables - -let list_entrypoints cctxt ~chain ~block (program : Script.expr) = - Plugin.RPC.Scripts.list_entrypoints cctxt (chain, block) ~script:program - >>=? fun (_, entrypoints) -> - if not @@ List.mem_assoc ~equal:String.equal "default" entrypoints then - script_entrypoint_type cctxt ~chain ~block program ~entrypoint:"default" - >>= function - | Ok (Some ty) -> return (("default", ty) :: entrypoints) - | Ok None -> return entrypoints - | Error _ as err -> Lwt.return err - else return entrypoints - -let print_entrypoints_list (cctxt : #Client_context.printer) - ?(on_errors = print_errors cctxt) ~emacs ?contract ?script_name = function - | Ok entrypoint_list -> - (if emacs then - cctxt#message - "@[(@[%a@])@." - (Format.pp_print_list - ~pp_sep:Format.pp_print_cut - (fun ppf (entrypoint, ty) -> - Format.fprintf - ppf - "@[( ( entrypoint . %s ) ( type . @[%a@]))@]" - entrypoint - Michelson_v1_emacs.print_expr - ty)) - entrypoint_list - else - cctxt#message - "@[Entrypoints%a%a: @,%a@]@." - (Format.pp_print_option (fun ppf -> - Format.fprintf ppf " for contract %a" Contract.pp)) - contract - (Format.pp_print_option (fun ppf -> - Format.fprintf ppf " for script %s")) - script_name - (Format.pp_print_list - ~pp_sep:Format.pp_print_cut - (fun ppf (entrypoint, ty) -> - Format.fprintf - ppf - "@[%s: @[%a@]@]" - entrypoint - Michelson_v1_printer.print_expr - ty)) - entrypoint_list) - >>= fun () -> return_unit - | Error errs -> on_errors errs - -let print_unreachables (cctxt : #Client_context.printer) - ?(on_errors = print_errors cctxt) ~emacs ?contract ?script_name = function - | Ok unreachable -> - (if emacs then - cctxt#message - "@[(@[%a@])@." - (Format.pp_print_list ~pp_sep:Format.pp_print_cut (fun ppf path -> - Format.fprintf - ppf - "@[( unreachable-path . %a )@]" - (Format.pp_print_list - ~pp_sep:Format.pp_print_space - (fun ppf prim -> - Format.pp_print_string ppf - @@ Michelson_v1_primitives.string_of_prim prim)) - path)) - unreachable - else - match unreachable with - | [] -> cctxt#message "@[None.@]@." - | _ -> - cctxt#message - "@[Unreachable paths in the argument%a%a: @[%a@]@." - (Format.pp_print_option (fun ppf -> - Format.fprintf ppf " of contract %a" Contract.pp)) - contract - (Format.pp_print_option (fun ppf -> - Format.fprintf ppf " of script %s")) - script_name - (Format.pp_print_list ~pp_sep:Format.pp_print_cut (fun ppf -> - Format.fprintf - ppf - "@[ %a @]" - (Format.pp_print_list - ~pp_sep:(fun ppf _ -> Format.pp_print_string ppf "/") - (fun ppf prim -> - Format.pp_print_string ppf - @@ Michelson_v1_primitives.string_of_prim prim)))) - unreachable) - >>= fun () -> return_unit - | Error errs -> on_errors errs diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_entrypoints.mli b/src/proto_012_Psithaca/lib_client/michelson_v1_entrypoints.mli deleted file mode 100644 index 96d3ad82c2f0..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_entrypoints.mli +++ /dev/null @@ -1,108 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** Returns [Some type] if the contract has an entrypoint of type [type]. None if it does not exists. *) -val script_entrypoint_type : - #Protocol_client_context.rpc_context -> - chain:Chain_services.chain -> - block:Block_services.block -> - Alpha_context.Script.expr -> - entrypoint:string -> - Alpha_context.Script.expr option tzresult Lwt.t - -(** Returns [Some type] if the script has an entrypoint of type [type]. None if it does not exists. *) -val contract_entrypoint_type : - #Protocol_client_context.rpc_context -> - chain:Chain_services.chain -> - block:Block_services.block -> - contract:Alpha_context.Contract.t -> - entrypoint:string -> - Alpha_context.Script.expr option tzresult Lwt.t - -val print_entrypoint_type : - #Client_context.printer -> - ?on_errors:(error list -> unit tzresult Lwt.t) -> - emacs:bool -> - ?contract:Alpha_context.Contract.t -> - ?script_name:string -> - entrypoint:string -> - Alpha_context.Script.expr option tzresult -> - unit tzresult Lwt.t - -(** List paths of unreachable parameters. - Only useful to test the stitching, as no such parameter should be - allowed in originated contracts. *) -val list_contract_unreachables : - #Protocol_client_context.rpc_context -> - chain:Chain_services.chain -> - block:Block_services.block -> - contract:Alpha_context.Contract.t -> - Michelson_v1_primitives.prim list list tzresult Lwt.t - -val list_unreachables : - #Protocol_client_context.rpc_context -> - chain:Chain_services.chain -> - block:Block_services.block -> - Alpha_context.Script.expr -> - Michelson_v1_primitives.prim list list tzresult Lwt.t - -val print_unreachables : - #Client_context.printer -> - ?on_errors:(error list -> unit tzresult Lwt.t) -> - emacs:bool -> - ?contract:Alpha_context.Contract.t -> - ?script_name:string -> - Michelson_v1_primitives.prim list list tzresult -> - unit tzresult Lwt.t - -(** List the contract entrypoints with their types. - If their is no explicit default, th type of default entrypoint will still be given. -*) -val list_contract_entrypoints : - #Protocol_client_context.rpc_context -> - chain:Chain_services.chain -> - block:Block_services.block -> - contract:Alpha_context.Contract.t -> - (string * Alpha_context.Script.expr) list tzresult Lwt.t - -(** List the script entrypoints with their types. *) -val list_entrypoints : - #Protocol_client_context.rpc_context -> - chain:Chain_services.chain -> - block:Block_services.block -> - Alpha_context.Script.expr -> - (string * Alpha_context.Script.expr) list tzresult Lwt.t - -(** Print the contract entrypoints with their types. *) -val print_entrypoints_list : - #Client_context.printer -> - ?on_errors:(error list -> unit tzresult Lwt.t) -> - emacs:bool -> - ?contract:Alpha_context.Contract.t -> - ?script_name:string -> - (string * Alpha_context.Script.expr) list tzresult -> - unit tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_error_reporter.ml b/src/proto_012_Psithaca/lib_client/michelson_v1_error_reporter.ml deleted file mode 100644 index fcbfb443c7a2..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_error_reporter.ml +++ /dev/null @@ -1,767 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Tezos_micheline -open Script_tc_errors -open Script_interpreter -open Michelson_v1_printer - -let print_ty ppf ty = Michelson_v1_printer.print_expr_unwrapped ppf ty - -let print_var_annot ppf annot = List.iter (Format.fprintf ppf "@ %s") annot - -let print_stack_ty ?(depth = max_int) ppf s = - let rec loop depth ppf = function - | [] -> () - | _ when depth <= 0 -> Format.fprintf ppf "..." - | [(last, annot)] -> - Format.fprintf ppf "%a%a" print_ty last print_var_annot annot - | (last, annot) :: rest -> - Format.fprintf - ppf - "%a%a@ :@ %a" - print_ty - last - print_var_annot - annot - (loop (depth - 1)) - rest - in - match s with - | [] -> Format.fprintf ppf "[]" - | sty -> Format.fprintf ppf "@[[ %a ]@]" (loop depth) sty - -let rec print_enumeration ppf = function - | [single] -> Format.fprintf ppf "%a" Format.pp_print_text single - | [prev; last] -> - Format.fprintf - ppf - "%a@ or@ %a" - Format.pp_print_text - prev - Format.pp_print_text - last - | first :: rest -> - Format.fprintf - ppf - "%a,@ %a" - Format.pp_print_text - first - print_enumeration - rest - | [] -> assert false - -let collect_error_locations errs = - let rec collect acc = function - | Environment.Ecoproto_error - ( Ill_formed_type (_, _, _) - | No_such_entrypoint _ | Duplicate_entrypoint _ - | Unreachable_entrypoint _ - | Runtime_contract_error (_, _) - | Michelson_v1_primitives.Invalid_primitive_name (_, _) - | Ill_typed_data (_, _, _) - | Ill_typed_contract (_, _) ) - :: _ - | [] -> - acc - | Environment.Ecoproto_error - ( Invalid_arity (loc, _, _, _) - | Invalid_seq_arity (loc, _, _) - | Inconsistent_type_annotations (loc, _, _) - | Unexpected_annotation loc - | Ungrouped_annotations loc - | Type_too_large (loc, _) - | Invalid_namespace (loc, _, _, _) - | Invalid_primitive (loc, _, _) - | Invalid_kind (loc, _, _) - | Invalid_never_expr loc - | Duplicate_field (loc, _) - | Unexpected_lazy_storage loc - | Unexpected_operation loc - | Fail_not_in_tail_position loc - | Undefined_binop (loc, _, _, _) - | Undefined_unop (loc, _, _) - | Bad_return (loc, _, _) - | Bad_stack (loc, _, _, _) - | Unmatched_branches (loc, _, _) - | Self_in_lambda loc - | Invalid_constant (loc, _, _) - | Invalid_syntactic_constant (loc, _, _) - | Invalid_contract (loc, _) - | Comparable_type_expected (loc, _) - | Overflow (loc, _) - | Reject (loc, _, _) - | Pair_bad_argument loc - | Unpair_bad_argument loc - | Dup_n_bad_argument loc ) - :: rest -> - collect (loc :: acc) rest - | _ :: rest -> collect acc rest - in - collect [] errs - -let report_errors ~details ~show_source ?parsed ppf errs = - let rec print_trace locations errs = - let print_loc ppf loc = - match locations loc with - | None -> Format.fprintf ppf "At (unshown) location %d, " loc - | Some loc -> - Format.fprintf - ppf - "%s,@ " - (String.capitalize_ascii - (Format.asprintf "%a" Micheline_parser.print_location loc)) - in - let parsed_locations parsed loc = - let ( >?? ) = Option.bind in - List.assoc - ~equal:Int.equal - loc - parsed.Michelson_v1_parser.unexpansion_table - >?? fun oloc -> - List.assoc ~equal:Int.equal oloc parsed.expansion_table - >?? fun (ploc, _) -> Some ploc - in - let print_source ppf (parsed, _hilights) (* TODO *) = - let lines = String.split_on_char '\n' parsed.Michelson_v1_parser.source in - let cols = String.length (string_of_int (List.length lines)) in - Format.fprintf - ppf - "@[%a@]" - (Format.pp_print_list (fun ppf (i, l) -> - Format.fprintf ppf "%0*d: %s" cols i l)) - (List.rev_mapi (fun i x -> (i + 1, x)) lines |> List.rev) - in - match errs with - | [] -> () - | Environment.Ecoproto_error - (Michelson_v1_primitives.Invalid_primitive_name (expr, loc)) - :: rest -> - let parsed = - match parsed with - | Some parsed -> - if - Micheline.strip_locations - (Michelson_v1_macros.unexpand_rec (Micheline.root expr)) - = parsed.Michelson_v1_parser.unexpanded - then parsed - else Michelson_v1_printer.unparse_invalid expr - | None -> Michelson_v1_printer.unparse_invalid expr - in - let hilights = loc :: collect_error_locations rest in - if show_source then - Format.fprintf - ppf - "@[@[Invalid primitive:@ %a@]@]" - print_source - (parsed, hilights) - else Format.fprintf ppf "Invalid primitive." ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace (parsed_locations parsed) rest - | Environment.Ecoproto_error (Ill_typed_data (name, expr, ty)) :: rest -> - let parsed = - match parsed with - | Some parsed when expr = parsed.Michelson_v1_parser.expanded -> - parsed - | Some _ | None -> Michelson_v1_printer.unparse_expression expr - in - let hilights = collect_error_locations rest in - Format.fprintf - ppf - "@[@[Ill typed %adata:@ %a@]@ @[is not an \ - expression of type@ %a@]@]" - (fun ppf -> function - | None -> () - | Some s -> Format.fprintf ppf "%s " s) - name - print_source - (parsed, hilights) - print_ty - ty ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace (parsed_locations parsed) rest - | Environment.Ecoproto_error (No_such_entrypoint entrypoint) :: rest -> - Format.fprintf ppf "Contract has no entrypoint named %s" entrypoint ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Duplicate_entrypoint entrypoint) :: rest -> - Format.fprintf ppf "Contract has two entrypoints named %s" entrypoint ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Unreachable_entrypoint path) :: rest -> - let path = - String.concat - "/" - (List.map Michelson_v1_primitives.string_of_prim path) - in - Format.fprintf ppf "Entrypoint at path %s is not reachable" path ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Ill_formed_type (_, expr, loc)) :: rest -> - let parsed = - match parsed with - | Some parsed when expr = parsed.Michelson_v1_parser.expanded -> - parsed - | Some _ | None -> Michelson_v1_printer.unparse_expression expr - in - let hilights = loc :: collect_error_locations errs in - if show_source then - Format.fprintf - ppf - "@[%aill formed type:@ %a@]" - print_loc - loc - print_source - (parsed, hilights) - else Format.fprintf ppf "Ill formed type." ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace (parsed_locations parsed) rest - | Environment.Ecoproto_error (Ill_typed_contract (expr, type_map)) :: rest - -> - let parsed = - match parsed with - | Some parsed - when (not details) && expr = parsed.Michelson_v1_parser.expanded -> - parsed - | Some _ | None -> - Michelson_v1_printer.unparse_toplevel ~type_map expr - in - let hilights = collect_error_locations rest in - if show_source then - Format.fprintf - ppf - "@[Ill typed contract:@, %a@]" - print_source - (parsed, hilights) - else Format.fprintf ppf "Ill typed contract." ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace (parsed_locations parsed) rest - | Environment.Ecoproto_error Apply.Gas_quota_exceeded_init_deserialize - :: rest -> - Format.fprintf - ppf - "@[Not enough gas to deserialize the operation.@,\ - Injecting such a transaction could have you banned from mempools.@]" ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Deprecated_instruction prim) :: rest -> - Format.fprintf - ppf - "@[Use of deprecated instruction: %s@]" - (Michelson_v1_primitives.string_of_prim prim) ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error Cannot_serialize_storage :: rest -> - Format.fprintf - ppf - "Cannot serialize the resulting storage value within the provided \ - gas bounds." ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Missing_field prim) :: rest -> - Format.fprintf - ppf - "@[Missing contract field: %s@]" - (Michelson_v1_primitives.string_of_prim prim) ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Duplicate_field (loc, prim)) :: rest -> - Format.fprintf - ppf - "@[%aduplicate contract field: %s@]" - print_loc - loc - (Michelson_v1_primitives.string_of_prim prim) ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Unexpected_lazy_storage loc) :: rest -> - Format.fprintf - ppf - "%abig_map or sapling_state type not expected here" - print_loc - loc ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Unexpected_operation loc) :: rest -> - Format.fprintf - ppf - "%aoperation type forbidden in parameter, storage and constants" - print_loc - loc ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Unexpected_contract loc) :: rest -> - Format.fprintf - ppf - "%acontract type forbidden in storage and constants" - print_loc - loc ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error (Runtime_contract_error (contract, expr)) - :: rest -> - let parsed = - match parsed with - | Some parsed when expr = parsed.Michelson_v1_parser.expanded -> - parsed - | Some _ | None -> Michelson_v1_printer.unparse_toplevel expr - in - let hilights = collect_error_locations rest in - Format.fprintf - ppf - "@[Runtime error in contract %a:@ %a@]" - Contract.pp - contract - print_source - (parsed, hilights) ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace (parsed_locations parsed) rest - | Environment.Ecoproto_error (Apply.Internal_operation_replay op) :: rest -> - Format.fprintf - ppf - "@[Internal operation replay attempt:@,%a@]" - Operation_result.pp_internal_operation - op ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error Gas.Gas_limit_too_high :: rest -> - Format.fprintf - ppf - "Gas limit for the operation is out of the protocol hard bounds." ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error Gas.Block_quota_exceeded :: rest -> - Format.fprintf - ppf - "Gas limit for the block exceeded during typechecking or execution." ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error Gas.Operation_quota_exceeded :: rest -> - Format.fprintf - ppf - "@[Gas limit exceeded during typechecking or execution.@,\ - Try again with a higher gas limit.@]" ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | Environment.Ecoproto_error Fees.Operation_quota_exceeded :: rest -> - Format.fprintf - ppf - "@[Storage limit exceeded during typechecking or execution.@,\ - Try again with a higher storage limit.@]" ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | [Environment.Ecoproto_error (Script_interpreter.Bad_contract_parameter c)] - -> - Format.fprintf - ppf - "@[Account %a is not a smart contract, it does not take \ - arguments.@,\ - The `-arg' flag should not be used when transferring to an \ - account.@]" - Contract.pp - c - | Environment.Ecoproto_error err :: rest -> - (match err with - | Bad_contract_parameter c -> - Format.fprintf - ppf - "Invalid argument passed to contract %a." - Contract.pp - c - | Invalid_arity (loc, name, exp, got) -> - Format.fprintf - ppf - "%aprimitive %s expects %d arguments but is given %d." - print_loc - loc - (Michelson_v1_primitives.string_of_prim name) - exp - got - | Invalid_seq_arity (loc, exp, got) -> - Format.fprintf - ppf - "%asequence expects at least %d elements but is given %d." - print_loc - loc - exp - got - | Invalid_namespace (loc, name, exp, got) -> - let human_namespace = function - | Michelson_v1_primitives.Instr_namespace -> ("an", "instruction") - | Type_namespace -> ("a", "type name") - | Constant_namespace -> ("a", "constant constructor") - | Keyword_namespace -> ("a", "keyword") - | Constant_hash_namespace -> ("a", "constant hash") - in - Format.fprintf - ppf - "@[%aunexpected %s %s, only %s %s can be used here." - print_loc - loc - (snd (human_namespace got)) - (Michelson_v1_primitives.string_of_prim name) - (fst (human_namespace exp)) - (snd (human_namespace exp)) - | Invalid_primitive (loc, exp, got) -> - Format.fprintf - ppf - "@[%ainvalid primitive %s, only %a can be used here." - print_loc - loc - (Michelson_v1_primitives.string_of_prim got) - print_enumeration - (List.map Michelson_v1_primitives.string_of_prim exp) - | Invalid_kind (loc, exp, got) -> - let human_kind = function - | Seq_kind -> ("a", "sequence") - | Prim_kind -> ("a", "primitive") - | Int_kind -> ("an", "int") - | String_kind -> ("a", "string") - | Bytes_kind -> ("a", "byte sequence") - in - Format.fprintf - ppf - "@[%aunexpected %s, only@ %a@ can be used here." - print_loc - loc - (snd (human_kind got)) - print_enumeration - (List.map - (fun k -> - let (a, n) = human_kind k in - a ^ " " ^ n) - exp) - | Invalid_never_expr loc -> - Format.fprintf - ppf - "@[%athis expression should have type never but type never has \ - no inhabitant." - print_loc - loc - | Duplicate_map_keys (_, expr) -> - Format.fprintf - ppf - "@[Map literals cannot contain duplicate keys, however a \ - duplicate key was found:@ @[%a@]" - print_expr - expr - | Unordered_map_keys (_, expr) -> - Format.fprintf - ppf - "@[Keys in a map literal must be in strictly ascending \ - order, but they were unordered in literal:@ @[%a@]" - print_expr - expr - | Duplicate_set_values (_, expr) -> - Format.fprintf - ppf - "@[Set literals cannot contain duplicate values, however a \ - duplicate value was found:@ @[%a@]" - print_expr - expr - | Unordered_set_values (_, expr) -> - Format.fprintf - ppf - "@[Values in a set literal must be in strictly ascending \ - order, but they were unordered in literal:@ @[%a@]" - print_expr - expr - | Fail_not_in_tail_position loc -> - Format.fprintf - ppf - "%aThe FAIL instruction must appear in a tail position." - print_loc - loc - | Undefined_binop (loc, name, tya, tyb) -> - Format.fprintf - ppf - "@[@[%aoperator %s is undefined between@ %a@]@ \ - @[and@ %a.@]@]" - print_loc - loc - (Michelson_v1_primitives.string_of_prim name) - print_ty - tya - print_ty - tyb - | Undefined_unop (loc, name, ty) -> - Format.fprintf - ppf - "@[@[%aoperator %s is undefined on@ %a@]@]" - print_loc - loc - (Michelson_v1_primitives.string_of_prim name) - print_ty - ty - | Bad_return (loc, got, exp) -> - Format.fprintf - ppf - "@[%awrong stack type at end of body:@,\ - - @[expected return stack type:@ %a,@]@,\ - - @[actual stack type:@ %a.@]@]" - print_loc - loc - (fun ppf -> print_stack_ty ppf) - [(exp, [])] - (fun ppf -> print_stack_ty ppf) - got - | Bad_stack (loc, name, depth, sty) -> - Format.fprintf - ppf - "@[%awrong stack type for instruction %s:@ %a.@]" - print_loc - loc - (Michelson_v1_primitives.string_of_prim name) - (print_stack_ty ~depth) - sty - | Unmatched_branches (loc, sta, stb) -> - Format.fprintf - ppf - "@[%atwo branches don't end with the same stack type:@,\ - - @[first stack type:@ %a,@]@,\ - - @[other stack type:@ %a.@]@]" - print_loc - loc - (fun ppf -> print_stack_ty ppf) - sta - (fun ppf -> print_stack_ty ppf) - stb - | Bad_view_name loc -> - Format.fprintf - ppf - "@[%athe name of view should be of type string @]" - print_loc - loc - | Duplicated_view_name loc -> - Format.fprintf - ppf - "@[%athe name of view in toplevel should be unique @]" - print_loc - loc - | Ill_typed_view {loc; actual; expected} -> - Format.fprintf - ppf - "@[%athe return of a view block did not match the expected \ - type.@,\ - - @[resulted view stack type:@ %a,@]@,\ - - @[expected view stack type:@ %a.@]@]" - print_loc - loc - (fun ppf -> print_stack_ty ppf) - actual - (fun ppf -> print_stack_ty ppf) - expected - | View_name_too_long name -> - Format.fprintf - ppf - "@[ A view name, \"%s\", exceeds the maximum length of 31 \ - characters." - name - | Inconsistent_annotations (annot1, annot2) -> - Format.fprintf - ppf - "@[The two annotations do not match:@,\ - - @[%s@]@,\ - - @[%s@]@]" - annot1 - annot2 - | Inconsistent_field_annotations (annot1, annot2) -> - Format.fprintf - ppf - "@[The field access annotation does not match:@,\ - - @[%s@]@,\ - - @[%s@]@]" - annot1 - annot2 - | Inconsistent_type_annotations (loc, ty1, ty2) -> - Format.fprintf - ppf - "@[%athe two types contain incompatible annotations:@,\ - - @[%a@]@,\ - - @[%a@]@]" - print_loc - loc - print_ty - ty1 - print_ty - ty2 - | Inconsistent_type_sizes (size1, size2) -> - Format.fprintf - ppf - "@[The two types have different sizes, the first one is of \ - size %d while the other one is of size %d@]" - size1 - size2 - | Unexpected_annotation loc -> - Format.fprintf ppf "@[%aunexpected annotation." print_loc loc - | Ungrouped_annotations loc -> - Format.fprintf - ppf - "@[%aAnnotations of the same kind must be grouped." - print_loc - loc - | Type_too_large (loc, maximum_size) -> - Format.fprintf - ppf - "@[%atype exceeded maximum type size (%d)." - print_loc - loc - maximum_size - | Pair_bad_argument loc -> - Format.fprintf - ppf - "%aPAIR expects an argument of at least 2." - print_loc - loc - | Unpair_bad_argument loc -> - Format.fprintf - ppf - "%aUNPAIR expects an argument of at least 2." - print_loc - loc - | Dup_n_bad_argument loc -> - Format.fprintf - ppf - "%aDUP n expects an argument of at least 1 (passed 0)." - print_loc - loc - | Self_in_lambda loc -> - Format.fprintf - ppf - "%aThe SELF instruction cannot appear in a lambda." - print_loc - loc - | Non_dupable_type (loc, ty) -> - Format.fprintf - ppf - "%atype %a cannot be used here because it is not duplicable. \ - Only duplicable types can be used with the DUP instruction and \ - as view inputs and outputs." - print_loc - loc - print_ty - ty - | Unexpected_ticket loc -> - Format.fprintf - ppf - "%aTicket in unauthorized position (type error)." - print_loc - loc - | Bad_stack_length -> Format.fprintf ppf "Bad stack length." - | Bad_stack_item lvl -> Format.fprintf ppf "Bad stack item %d." lvl - | Unexpected_forged_value loc -> - Format.fprintf ppf "%aUnexpected forged value." print_loc loc - | Invalid_constant (loc, got, exp) -> - Format.fprintf - ppf - "@[@[%avalue@ %a@]@ @[is invalid for type@ \ - %a.@]@]" - print_loc - loc - print_expr - got - print_ty - exp - | Invalid_syntactic_constant (loc, got, exp) -> - Format.fprintf - ppf - "@[@[%avalue@ %a@]@ @[is invalid, expected@ \ - %s@]@]" - print_loc - loc - print_expr - got - exp - | Invalid_contract (loc, contract) -> - Format.fprintf - ppf - "%ainvalid contract %a." - print_loc - loc - Contract.pp - contract - | Comparable_type_expected (loc, ty) -> - Format.fprintf ppf "%acomparable type expected." print_loc loc ; - Format.fprintf - ppf - "@[@[Type@ %a@]@ is not comparable.@]" - print_ty - ty - | Inconsistent_types (opt_loc, tya, tyb) -> - Format.fprintf - ppf - "@[@[%aType@ %a@]@ @[is not compatible with \ - type@ %a.@]@]" - (fun fmt -> function None -> () | Some loc -> print_loc fmt loc) - opt_loc - print_ty - tya - print_ty - tyb - | Reject (loc, v, trace) -> - Format.fprintf - ppf - "%ascript reached FAILWITH instruction@ @[with@ %a@]%a" - print_loc - loc - print_expr - v - (fun ppf -> function - | None -> () - | Some trace -> - Format.fprintf - ppf - "@,@[trace@,%a@]" - print_execution_trace - trace) - trace - | Overflow (loc, trace) -> - Format.fprintf - ppf - "%aunexpected arithmetic overflow%a" - print_loc - loc - (fun ppf -> function - | None -> () - | Some trace -> - Format.fprintf - ppf - "@,@[trace@,%a@]" - print_execution_trace - trace) - trace - | err -> Format.fprintf ppf "%a" Environment.Error_monad.pp err) ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - | err :: rest -> - Format.fprintf ppf "%a" Error_monad.pp err ; - if rest <> [] then Format.fprintf ppf "@," ; - print_trace locations rest - in - Format.fprintf ppf "@[" ; - print_trace (fun _ -> None) errs ; - Format.fprintf ppf "@]" diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_error_reporter.mli b/src/proto_012_Psithaca/lib_client/michelson_v1_error_reporter.mli deleted file mode 100644 index e1bbea6eb12c..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_error_reporter.mli +++ /dev/null @@ -1,32 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val report_errors : - details:bool -> - show_source:bool -> - ?parsed:Michelson_v1_parser.parsed -> - Format.formatter -> - Error_monad.error list -> - unit diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_helpers.ml b/src/proto_012_Psithaca/lib_client/michelson_v1_helpers.ml deleted file mode 100644 index 40d1698fff37..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_helpers.ml +++ /dev/null @@ -1,60 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Generic Michelson building functions *) - -open Tezos_micheline.Micheline -open Protocol.Alpha_context.Script - -let seq ~loc l = Seq (loc, l) - -let pair ~loc a b = Prim (loc, D_Pair, [a; b], []) - -let none ~loc () = Prim (loc, D_None, [], []) - -let some ~loc a = Prim (loc, D_Some, [a], []) - -let left ~loc a = Prim (loc, D_Left, [a], []) - -let right ~loc b = Prim (loc, D_Right, [b], []) - -let int ~loc i = Int (loc, i) - -let bytes ~loc s = Bytes (loc, s) - -let unit_t ~loc = Prim (loc, T_unit, [], []) - -let unit ~loc = Prim (loc, D_Unit, [], []) - -let lambda_from_string code = - Tezos_micheline.Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression code - >|? fun parsed -> root Michelson_v1_parser.(parsed.expanded) - -let lambda_t ~loc param res = Prim (loc, T_lambda, [param; res], []) - -let operation_t ~loc = Prim (loc, T_operation, [], []) - -let operations_t ~loc = Prim (loc, T_list, [operation_t ~loc], []) diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_macros.ml b/src/proto_012_Psithaca/lib_client/michelson_v1_macros.ml deleted file mode 100644 index 448bd000108e..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_macros.ml +++ /dev/null @@ -1,1519 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol_client_context -open Tezos_micheline -open Micheline -module IntMap = Map.Make (Compare.Int) - -type 'l node = ('l, string) Micheline.node - -type error += Unexpected_macro_annotation of string - -type error += Sequence_expected of string - -type error += Invalid_arity of string * int * int - -let rec check_letters str i j f = - i > j || (f str.[i] && check_letters str (i + 1) j f) - -let expand_caddadr original = - match original with - | Prim (loc, str, args, annot) -> - let len = String.length str in - if - len > 3 - && str.[0] = 'C' - && str.[len - 1] = 'R' - && check_letters str 1 (len - 2) (function - | 'A' | 'D' -> true - | _ -> false) - then - (match args with - | [] -> ok () - | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) - >>? fun () -> - let path_annot = - List.filter (function "@%" | "@%%" -> true | _ -> false) annot - in - let rec parse i acc = - if i = 0 then Seq (loc, acc) - else - let annot = if i = len - 2 then annot else path_annot in - match str.[i] with - | 'A' -> parse (i - 1) (Prim (loc, "CAR", [], annot) :: acc) - | 'D' -> parse (i - 1) (Prim (loc, "CDR", [], annot) :: acc) - | _ -> assert false - in - ok (Some (parse (len - 2) [])) - else ok None - | _ -> ok None - -let expand_carn original = - match original with - | Prim (loc, "CAR", [Int (loc2, n)], annot) -> - ok - (Some - (Seq - ( loc, - [ - Prim - ( loc, - "GET", - [Int (loc2, Z.(of_int 1 + (n * of_int 2)))], - annot ); - ] ))) - | _ -> ok None - -let expand_cdrn original = - match original with - | Prim (loc, "CDR", [Int (loc2, n)], annot) -> - ok - (Some - (Seq (loc, [Prim (loc, "GET", [Int (loc2, Z.(n * of_int 2))], annot)]))) - | _ -> ok None - -let extract_field_annots annot = - List.partition - (fun a -> - match a.[0] with - | '%' -> true - | _ -> false - | exception Invalid_argument _ -> false) - annot - -let expand_set_caddadr original = - match original with - | Prim (loc, str, args, annot) -> - let len = String.length str in - if - len >= 7 - && String.sub str 0 5 = "SET_C" - && str.[len - 1] = 'R' - && check_letters str 5 (len - 2) (function - | 'A' | 'D' -> true - | _ -> false) - then - (match args with - | [] -> ok () - | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) - >>? fun () -> - (match extract_field_annots annot with - | ([], annot) -> ok (None, annot) - | ([f], annot) -> ok (Some f, annot) - | (_, _) -> error (Unexpected_macro_annotation str)) - >>? fun (field_annot, annot) -> - let rec parse i acc = - if i = 4 then acc - else - let annot = if i = 5 then annot else [] in - match str.[i] with - | 'A' -> - let acc = - Seq - ( loc, - [ - Prim (loc, "DUP", [], []); - Prim - ( loc, - "DIP", - [Seq (loc, [Prim (loc, "CAR", [], ["@%%"]); acc])], - [] ); - Prim (loc, "CDR", [], ["@%%"]); - Prim (loc, "SWAP", [], []); - Prim (loc, "PAIR", [], "%@" :: "%@" :: annot); - ] ) - in - parse (i - 1) acc - | 'D' -> - let acc = - Seq - ( loc, - [ - Prim (loc, "DUP", [], []); - Prim - ( loc, - "DIP", - [Seq (loc, [Prim (loc, "CDR", [], ["@%%"]); acc])], - [] ); - Prim (loc, "CAR", [], ["@%%"]); - Prim (loc, "PAIR", [], "%@" :: "%@" :: annot); - ] ) - in - parse (i - 1) acc - | _ -> assert false - in - match str.[len - 2] with - | 'A' -> - let access_check = - match field_annot with - | None -> [] - | Some f -> - [ - Prim (loc, "DUP", [], []); - Prim (loc, "CAR", [], [f]); - Prim (loc, "DROP", [], []); - ] - in - let encoding = - [Prim (loc, "CDR", [], ["@%%"]); Prim (loc, "SWAP", [], [])] - in - let pair = - [ - Prim - ( loc, - "PAIR", - [], - [Option.value field_annot ~default:"%"; "%@"] ); - ] - in - let init = Seq (loc, access_check @ encoding @ pair) in - ok (Some (parse (len - 3) init)) - | 'D' -> - let access_check = - match field_annot with - | None -> [] - | Some f -> - [ - Prim (loc, "DUP", [], []); - Prim (loc, "CDR", [], [f]); - Prim (loc, "DROP", [], []); - ] - in - let encoding = [Prim (loc, "CAR", [], ["@%%"])] in - let pair = - [ - Prim - ( loc, - "PAIR", - [], - ["%@"; Option.value field_annot ~default:"%"] ); - ] - in - let init = Seq (loc, access_check @ encoding @ pair) in - ok (Some (parse (len - 3) init)) - | _ -> assert false - else ok None - | _ -> ok None - -let expand_map_caddadr original = - match original with - | Prim (loc, str, args, annot) -> - let len = String.length str in - if - len >= 7 - && String.sub str 0 5 = "MAP_C" - && str.[len - 1] = 'R' - && check_letters str 5 (len - 2) (function - | 'A' | 'D' -> true - | _ -> false) - then - (match args with - | [(Seq _ as code)] -> ok code - | [_] -> error (Sequence_expected str) - | [] | _ :: _ :: _ -> error (Invalid_arity (str, List.length args, 1))) - >>? fun code -> - (match extract_field_annots annot with - | ([], annot) -> ok (None, annot) - | ([f], annot) -> ok (Some f, annot) - | (_, _) -> error (Unexpected_macro_annotation str)) - >>? fun (field_annot, annot) -> - let rec parse i acc = - if i = 4 then acc - else - let annot = if i = 5 then annot else [] in - match str.[i] with - | 'A' -> - let acc = - Seq - ( loc, - [ - Prim (loc, "DUP", [], []); - Prim - ( loc, - "DIP", - [Seq (loc, [Prim (loc, "CAR", [], ["@%%"]); acc])], - [] ); - Prim (loc, "CDR", [], ["@%%"]); - Prim (loc, "SWAP", [], []); - Prim (loc, "PAIR", [], "%@" :: "%@" :: annot); - ] ) - in - parse (i - 1) acc - | 'D' -> - let acc = - Seq - ( loc, - [ - Prim (loc, "DUP", [], []); - Prim - ( loc, - "DIP", - [Seq (loc, [Prim (loc, "CDR", [], ["@%%"]); acc])], - [] ); - Prim (loc, "CAR", [], ["@%%"]); - Prim (loc, "PAIR", [], "%@" :: "%@" :: annot); - ] ) - in - parse (i - 1) acc - | _ -> assert false - in - let cr_annot = - match field_annot with - | None -> [] - | Some f -> ["@" ^ String.sub f 1 (String.length f - 1)] - in - match str.[len - 2] with - | 'A' -> - let init = - Seq - ( loc, - [ - Prim (loc, "DUP", [], []); - Prim (loc, "CDR", [], ["@%%"]); - Prim - ( loc, - "DIP", - [Seq (loc, [Prim (loc, "CAR", [], cr_annot); code])], - [] ); - Prim (loc, "SWAP", [], []); - Prim - ( loc, - "PAIR", - [], - [Option.value field_annot ~default:"%"; "%@"] ); - ] ) - in - ok (Some (parse (len - 3) init)) - | 'D' -> - let init = - Seq - ( loc, - [ - Prim (loc, "DUP", [], []); - Prim (loc, "CDR", [], cr_annot); - code; - Prim (loc, "SWAP", [], []); - Prim (loc, "CAR", [], ["@%%"]); - Prim - ( loc, - "PAIR", - [], - ["%@"; Option.value field_annot ~default:"%"] ); - ] ) - in - ok (Some (parse (len - 3) init)) - | _ -> assert false - else ok None - | _ -> ok None - -exception Not_a_roman - -let decimal_of_roman roman = - (* http://rosettacode.org/wiki/Roman_numerals/Decode#OCaml *) - let arabic = ref 0 in - let lastval = ref 0 in - for i = String.length roman - 1 downto 0 do - let n = - match roman.[i] with - | 'M' -> 1000 - | 'D' -> 500 - | 'C' -> 100 - | 'L' -> 50 - | 'X' -> 10 - | 'V' -> 5 - | 'I' -> 1 - | _ -> raise_notrace Not_a_roman - in - if Compare.Int.(n < !lastval) then arabic := !arabic - n - else arabic := !arabic + n ; - lastval := n - done ; - !arabic - -let dip ~loc ?(annot = []) depth instr = - assert (depth >= 0) ; - if depth = 1 then Prim (loc, "DIP", [instr], annot) - else Prim (loc, "DIP", [Int (loc, Z.of_int depth); instr], annot) - -let expand_deprecated_dxiiivp original = - (* transparently expands deprecated macro [DI...IP] to instruction [DIP n] *) - match original with - | Prim (loc, str, args, annot) -> - let len = String.length str in - if len > 3 && str.[0] = 'D' && str.[len - 1] = 'P' then - try - let depth = decimal_of_roman (String.sub str 1 (len - 2)) in - match args with - | [(Seq (_, _) as arg)] -> ok @@ Some (dip ~loc ~annot depth arg) - | [_] -> error (Sequence_expected str) - | [] | _ :: _ :: _ -> error (Invalid_arity (str, List.length args, 1)) - with Not_a_roman -> ok None - else ok None - | _ -> ok None - -exception Not_a_pair - -type pair_item = A | I | P of int * pair_item * pair_item - -let parse_pair_substr str ~len start = - let rec parse ?left i = - if i = len - 1 then raise_notrace Not_a_pair - else if str.[i] = 'P' then - let (next_i, l) = parse ~left:true (i + 1) in - let (next_i, r) = parse ~left:false next_i in - (next_i, P (i, l, r)) - else if str.[i] = 'A' && left = Some true then (i + 1, A) - else if str.[i] = 'I' && left <> Some true then (i + 1, I) - else raise_notrace Not_a_pair - in - let (last, ast) = parse start in - if last <> len - 1 then raise_notrace Not_a_pair else ast - -let unparse_pair_item ast = - let rec unparse ast acc = - match ast with - | P (_, l, r) -> unparse r (unparse l ("P" :: acc)) - | A -> "A" :: acc - | I -> "I" :: acc - in - List.rev ("R" :: unparse ast []) |> String.concat "" - -let pappaiir_annots_pos ast annot = - let rec find_annots_pos p_pos ast annots acc = - match (ast, annots) with - | (_, []) -> (annots, acc) - | (P (i, left, right), _) -> - let (annots, acc) = find_annots_pos i left annots acc in - find_annots_pos i right annots acc - | (A, a :: annots) -> - let pos = - match IntMap.find p_pos acc with - | None -> ([a], []) - | Some (_, cdr) -> ([a], cdr) - in - (annots, IntMap.add p_pos pos acc) - | (I, a :: annots) -> - let pos = - match IntMap.find p_pos acc with - | None -> ([], [a]) - | Some (car, _) -> (car, [a]) - in - (annots, IntMap.add p_pos pos acc) - in - snd (find_annots_pos 0 ast annot IntMap.empty) - -let expand_pappaiir original = - match original with - | Prim (loc, str, args, annot) -> - let len = String.length str in - if - len > 4 - && str.[0] = 'P' - && str.[len - 1] = 'R' - && check_letters str 1 (len - 2) (function - | 'P' | 'A' | 'I' -> true - | _ -> false) - then - try - let (field_annots, annot) = extract_field_annots annot in - let ast = parse_pair_substr str ~len 0 in - let field_annots_pos = pappaiir_annots_pos ast field_annots in - let rec parse p (depth, acc) = - match p with - | P (i, left, right) -> - let annot = - match (i, IntMap.find i field_annots_pos) with - | (0, None) -> annot - | (_, None) -> [] - | (0, Some ([], cdr_annot)) -> "%" :: cdr_annot @ annot - | (_, Some ([], cdr_annot)) -> "%" :: cdr_annot - | (0, Some (car_annot, cdr_annot)) -> - car_annot @ cdr_annot @ annot - | (_, Some (car_annot, cdr_annot)) -> car_annot @ cdr_annot - in - let acc = - if depth = 0 then Prim (loc, "PAIR", [], annot) :: acc - else - dip ~loc depth (Seq (loc, [Prim (loc, "PAIR", [], annot)])) - :: acc - in - (depth, acc) |> parse left |> parse right - | A | I -> (depth + 1, acc) - in - let (_, expanded) = parse ast (0, []) in - (match args with - | [] -> ok () - | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) - >>? fun () -> ok (Some (Seq (loc, expanded))) - with Not_a_pair -> ok None - else ok None - | _ -> ok None - -let expand_unpappaiir original = - match original with - | Prim (loc, str, args, _annot) -> - let len = String.length str in - if - len > 6 - && String.sub str 0 3 = "UNP" - && str.[len - 1] = 'R' - && check_letters str 3 (len - 2) (function - | 'P' | 'A' | 'I' -> true - | _ -> false) - then - try - let unpair = Prim (loc, "UNPAIR", [], []) in - let ast = parse_pair_substr str ~len 2 in - let rec parse p (depth, acc) = - match p with - | P (_i, left, right) -> - let acc = - if depth = 0 then unpair :: acc - else dip ~loc depth (Seq (loc, [unpair])) :: acc - in - (depth, acc) |> parse left |> parse right - | A | I -> (depth + 1, acc) - in - let (_, rev_expanded) = parse ast (0, []) in - let expanded = Seq (loc, List.rev rev_expanded) in - (match args with - | [] -> ok () - | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) - >>? fun () -> ok (Some expanded) - with Not_a_pair -> ok None - else ok None - | _ -> ok None - -exception Not_a_dup - -let expand_deprecated_duuuuup original = - (* transparently expands deprecated macro [DU...UP] to [{ DUP n }] *) - match original with - | Prim (loc, str, args, annot) -> - let len = String.length str in - if - len > 3 - && str.[0] = 'D' - && str.[len - 1] = 'P' - && check_letters str 1 (len - 2) (( = ) 'U') - then - (match args with - | [] -> ok () - | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) - >>? fun () -> - try - let rec parse i = - if i = 1 then - Prim (loc, "DUP", [Int (loc, Z.of_int (len - 2))], annot) - else if str.[i] = 'U' then parse (i - 1) - else raise_notrace Not_a_dup - in - ok (Some (parse (len - 2))) - with Not_a_dup -> ok None - else ok None - | _ -> ok None - -let expand_compare original = - let cmp loc is annot = - let is = - match List.rev_map (fun i -> Prim (loc, i, [], [])) is with - | Prim (loc, i, args, _) :: r -> - List.rev (Prim (loc, i, args, annot) :: r) - | is -> List.rev is - in - ok (Some (Seq (loc, is))) - in - let ifcmp loc is l r annot = - let is = - List.map (fun i -> Prim (loc, i, [], [])) is - @ [Prim (loc, "IF", [l; r], annot)] - in - ok (Some (Seq (loc, is))) - in - match original with - | Prim (loc, "CMPEQ", [], annot) -> cmp loc ["COMPARE"; "EQ"] annot - | Prim (loc, "CMPNEQ", [], annot) -> cmp loc ["COMPARE"; "NEQ"] annot - | Prim (loc, "CMPLT", [], annot) -> cmp loc ["COMPARE"; "LT"] annot - | Prim (loc, "CMPGT", [], annot) -> cmp loc ["COMPARE"; "GT"] annot - | Prim (loc, "CMPLE", [], annot) -> cmp loc ["COMPARE"; "LE"] annot - | Prim (loc, "CMPGE", [], annot) -> cmp loc ["COMPARE"; "GE"] annot - | Prim - ( _, - (("CMPEQ" | "CMPNEQ" | "CMPLT" | "CMPGT" | "CMPLE" | "CMPGE") as str), - args, - [] ) -> - error (Invalid_arity (str, List.length args, 0)) - | Prim (loc, "IFCMPEQ", [l; r], annot) -> - ifcmp loc ["COMPARE"; "EQ"] l r annot - | Prim (loc, "IFCMPNEQ", [l; r], annot) -> - ifcmp loc ["COMPARE"; "NEQ"] l r annot - | Prim (loc, "IFCMPLT", [l; r], annot) -> - ifcmp loc ["COMPARE"; "LT"] l r annot - | Prim (loc, "IFCMPGT", [l; r], annot) -> - ifcmp loc ["COMPARE"; "GT"] l r annot - | Prim (loc, "IFCMPLE", [l; r], annot) -> - ifcmp loc ["COMPARE"; "LE"] l r annot - | Prim (loc, "IFCMPGE", [l; r], annot) -> - ifcmp loc ["COMPARE"; "GE"] l r annot - | Prim (loc, "IFEQ", [l; r], annot) -> ifcmp loc ["EQ"] l r annot - | Prim (loc, "IFNEQ", [l; r], annot) -> ifcmp loc ["NEQ"] l r annot - | Prim (loc, "IFLT", [l; r], annot) -> ifcmp loc ["LT"] l r annot - | Prim (loc, "IFGT", [l; r], annot) -> ifcmp loc ["GT"] l r annot - | Prim (loc, "IFLE", [l; r], annot) -> ifcmp loc ["LE"] l r annot - | Prim (loc, "IFGE", [l; r], annot) -> ifcmp loc ["GE"] l r annot - | Prim - ( _, - (( "IFCMPEQ" | "IFCMPNEQ" | "IFCMPLT" | "IFCMPGT" | "IFCMPLE" - | "IFCMPGE" | "IFEQ" | "IFNEQ" | "IFLT" | "IFGT" | "IFLE" | "IFGE" ) as - str), - args, - [] ) -> - error (Invalid_arity (str, List.length args, 2)) - | Prim - ( _, - (( "IFCMPEQ" | "IFCMPNEQ" | "IFCMPLT" | "IFCMPGT" | "IFCMPLE" - | "IFCMPGE" | "IFEQ" | "IFNEQ" | "IFLT" | "IFGT" | "IFLE" | "IFGE" ) as - str), - [], - _ :: _ ) -> - error (Unexpected_macro_annotation str) - | _ -> ok None - -let expand_asserts original = - let may_rename loc = function - | [] -> Seq (loc, []) - | annot -> Seq (loc, [Prim (loc, "RENAME", [], annot)]) - in - let fail_false ?(annot = []) loc = - [may_rename loc annot; Seq (loc, [Prim (loc, "FAIL", [], [])])] - in - let fail_true ?(annot = []) loc = - [Seq (loc, [Prim (loc, "FAIL", [], [])]); may_rename loc annot] - in - match original with - | Prim (loc, "ASSERT", [], []) -> - ok @@ Some (Seq (loc, [Prim (loc, "IF", fail_false loc, [])])) - | Prim (loc, "ASSERT_NONE", [], []) -> - ok @@ Some (Seq (loc, [Prim (loc, "IF_NONE", fail_false loc, [])])) - | Prim (loc, "ASSERT_SOME", [], annot) -> - ok @@ Some (Seq (loc, [Prim (loc, "IF_NONE", fail_true ~annot loc, [])])) - | Prim (loc, "ASSERT_LEFT", [], annot) -> - ok @@ Some (Seq (loc, [Prim (loc, "IF_LEFT", fail_false ~annot loc, [])])) - | Prim (loc, "ASSERT_RIGHT", [], annot) -> - ok @@ Some (Seq (loc, [Prim (loc, "IF_LEFT", fail_true ~annot loc, [])])) - | Prim - ( _, - (( "ASSERT" | "ASSERT_NONE" | "ASSERT_SOME" | "ASSERT_LEFT" - | "ASSERT_RIGHT" ) as str), - args, - [] ) -> - error (Invalid_arity (str, List.length args, 0)) - | Prim (_, (("ASSERT" | "ASSERT_NONE") as str), [], _ :: _) -> - error (Unexpected_macro_annotation str) - | Prim (loc, s, args, annot) - when String.(length s > 7 && equal (sub s 0 7) "ASSERT_") -> ( - (match args with - | [] -> ok () - | _ :: _ -> error (Invalid_arity (s, List.length args, 0))) - >>? fun () -> - (match annot with - | _ :: _ -> error (Unexpected_macro_annotation s) - | [] -> ok ()) - >>? fun () -> - let remaining = String.(sub s 7 (length s - 7)) in - let remaining_prim = Prim (loc, remaining, [], []) in - match remaining with - | "EQ" | "NEQ" | "LT" | "LE" | "GE" | "GT" -> - ok - @@ Some - (Seq (loc, [remaining_prim; Prim (loc, "IF", fail_false loc, [])])) - | _ -> ( - expand_compare remaining_prim >|? function - | None -> None - | Some seq -> - Some (Seq (loc, [seq; Prim (loc, "IF", fail_false loc, [])])))) - | _ -> ok None - -let expand_if_some = function - | Prim (loc, "IF_SOME", [right; left], annot) -> - ok @@ Some (Seq (loc, [Prim (loc, "IF_NONE", [left; right], annot)])) - | Prim (_, "IF_SOME", args, _annot) -> - error (Invalid_arity ("IF_SOME", List.length args, 2)) - | _ -> ok @@ None - -let expand_if_right = function - | Prim (loc, "IF_RIGHT", [right; left], annot) -> - ok @@ Some (Seq (loc, [Prim (loc, "IF_LEFT", [left; right], annot)])) - | Prim (_, "IF_RIGHT", args, _annot) -> - error (Invalid_arity ("IF_RIGHT", List.length args, 2)) - | _ -> ok @@ None - -let expand_fail = function - | Prim (loc, "FAIL", [], []) -> - ok - @@ Some - (Seq - (loc, [Prim (loc, "UNIT", [], []); Prim (loc, "FAILWITH", [], [])])) - | _ -> ok @@ None - -let expand original = - let rec try_expansions = function - | [] -> ok @@ original - | expander :: expanders -> ( - expander original >>? function - | None -> try_expansions expanders - | Some rewritten -> ok rewritten) - in - try_expansions - [ - expand_carn; - expand_cdrn; - expand_caddadr; - expand_set_caddadr; - expand_map_caddadr; - expand_deprecated_dxiiivp; - (* expand_paaiair ; *) - expand_pappaiir; - (* expand_unpaaiair ; *) - expand_unpappaiir; - expand_deprecated_duuuuup; - expand_compare; - expand_asserts; - expand_if_some; - expand_if_right; - expand_fail; - ] - -let expand_rec expr = - let rec error_map (expanded, errors) f = function - | [] -> (List.rev expanded, List.rev errors) - | hd :: tl -> - let (new_expanded, new_errors) = f hd in - error_map - (new_expanded :: expanded, List.rev_append new_errors errors) - f - tl - in - let error_map = error_map ([], []) in - let rec expand_rec expr = - match expand expr with - | Ok expanded -> ( - match expanded with - | Seq (loc, items) -> - let (items, errors) = error_map expand_rec items in - (Seq (loc, items), errors) - | Prim (loc, name, args, annot) -> - let (args, errors) = error_map expand_rec args in - (Prim (loc, name, args, annot), errors) - | (Int _ | String _ | Bytes _) as atom -> (atom, [])) - | Error errors -> (expr, errors) - in - expand_rec expr - -let unexpand_carn_and_cdrn expanded = - match expanded with - | Seq (loc, [Prim (_, "GET", [Int (locn, n)], annot)]) -> - let (half, parity) = Z.ediv_rem n (Z.of_int 2) in - if Z.(parity = zero) then - Some (Prim (loc, "CDR", [Int (locn, half)], annot)) - else Some (Prim (loc, "CAR", [Int (locn, half)], annot)) - | _ -> None - -let unexpand_caddadr expanded = - let rec rsteps acc = function - | [] -> Some acc - | Prim (_, "CAR", [], []) :: rest -> rsteps ("A" :: acc) rest - | Prim (_, "CDR", [], []) :: rest -> rsteps ("D" :: acc) rest - | _ -> None - in - match expanded with - | Seq (loc, (Prim (_, "CAR", [], []) :: _ as nodes)) - | Seq (loc, (Prim (_, "CDR", [], []) :: _ as nodes)) -> ( - match rsteps [] nodes with - | Some steps -> - let name = String.concat "" ("C" :: List.rev ("R" :: steps)) in - Some (Prim (loc, name, [], [])) - | None -> None) - | _ -> None - -let unexpand_set_caddadr expanded = - let rec steps acc annots = function - | Seq - ( loc, - [ - Prim (_, "CDR", [], _); - Prim (_, "SWAP", [], _); - Prim (_, "PAIR", [], _); - ] ) -> - Some (loc, "A" :: acc, annots) - | Seq - ( loc, - [ - Prim (_, "DUP", [], []); - Prim (_, "CAR", [], [field_annot]); - Prim (_, "DROP", [], []); - Prim (_, "CDR", [], _); - Prim (_, "SWAP", [], []); - Prim (_, "PAIR", [], _); - ] ) -> - Some (loc, "A" :: acc, field_annot :: annots) - | Seq (loc, [Prim (_, "CAR", [], _); Prim (_, "PAIR", [], _)]) -> - Some (loc, "D" :: acc, annots) - | Seq - ( loc, - [ - Prim (_, "DUP", [], []); - Prim (_, "CDR", [], [field_annot]); - Prim (_, "DROP", [], []); - Prim (_, "CAR", [], _); - Prim (_, "PAIR", [], _); - ] ) -> - Some (loc, "D" :: acc, field_annot :: annots) - | Seq - ( _, - [ - Prim (_, "DUP", [], []); - Prim (_, "DIP", [Seq (_, [Prim (_, "CAR", [], _); sub])], []); - Prim (_, "CDR", [], _); - Prim (_, "SWAP", [], []); - Prim (_, "PAIR", [], pair_annots); - ] ) -> - let (_, pair_annots) = extract_field_annots pair_annots in - steps ("A" :: acc) (List.rev_append pair_annots annots) sub - | Seq - ( _, - [ - Prim (_, "DUP", [], []); - Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], _); sub])], []); - Prim (_, "CAR", [], _); - Prim (_, "PAIR", [], pair_annots); - ] ) -> - let (_, pair_annots) = extract_field_annots pair_annots in - steps ("D" :: acc) (List.rev_append pair_annots annots) sub - | _ -> None - in - match steps [] [] expanded with - | Some (loc, steps, annots) -> - let name = String.concat "" ("SET_C" :: List.rev ("R" :: steps)) in - Some (Prim (loc, name, [], List.rev annots)) - | None -> None - -let unexpand_map_caddadr expanded = - let rec steps acc annots = function - | Seq - ( loc, - [ - Prim (_, "DUP", [], []); - Prim (_, "CDR", [], _); - Prim (_, "SWAP", [], []); - Prim (_, "DIP", [Seq (_, [Prim (_, "CAR", [], []); code])], []); - Prim (_, "PAIR", [], _); - ] ) -> - Some (loc, "A" :: acc, annots, code) - | Seq - ( loc, - [ - Prim (_, "DUP", [], []); - Prim (_, "CDR", [], _); - Prim (_, "SWAP", [], []); - Prim - ( _, - "DIP", - [Seq (_, [Prim (_, "CAR", [], [field_annot]); code])], - [] ); - Prim (_, "PAIR", [], _); - ] ) -> - Some (loc, "A" :: acc, field_annot :: annots, code) - | Seq - ( loc, - [ - Prim (_, "DUP", [], []); - Prim (_, "CDR", [], []); - code; - Prim (_, "SWAP", [], []); - Prim (_, "CAR", [], _); - Prim (_, "PAIR", [], _); - ] ) -> - Some (loc, "D" :: acc, annots, code) - | Seq - ( loc, - [ - Prim (_, "DUP", [], []); - Prim (_, "CDR", [], [field_annot]); - code; - Prim (_, "SWAP", [], []); - Prim (_, "CAR", [], _); - Prim (_, "PAIR", [], _); - ] ) -> - Some (loc, "D" :: acc, field_annot :: annots, code) - | Seq - ( _, - [ - Prim (_, "DUP", [], []); - Prim (_, "DIP", [Seq (_, [Prim (_, "CAR", [], _); sub])], []); - Prim (_, "CDR", [], _); - Prim (_, "SWAP", [], []); - Prim (_, "PAIR", [], pair_annots); - ] ) -> - let (_, pair_annots) = extract_field_annots pair_annots in - steps ("A" :: acc) (List.rev_append pair_annots annots) sub - | Seq - ( _, - [ - Prim (_, "DUP", [], []); - Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], []); sub])], []); - Prim (_, "CAR", [], []); - Prim (_, "PAIR", [], pair_annots); - ] ) -> - let (_, pair_annots) = extract_field_annots pair_annots in - steps ("D" :: acc) (List.rev_append pair_annots annots) sub - | _ -> None - in - match steps [] [] expanded with - | Some (loc, steps, annots, code) -> - let name = String.concat "" ("MAP_C" :: List.rev ("R" :: steps)) in - Some (Prim (loc, name, [code], List.rev annots)) - | None -> None - -let unexpand_deprecated_dxiiivp expanded = - (* transparently turn the old expansion of deprecated [DI...IP] to [DIP n] *) - match expanded with - | Seq - ( loc, - [Prim (_, "DIP", [(Seq (_, [Prim (_, "DIP", [_], [])]) as sub)], [])] ) - -> - let rec count acc = function - | Seq (_, [Prim (_, "DIP", [sub], [])]) -> count (acc + 1) sub - | sub -> (acc, sub) - in - let (depth, sub) = count 1 sub in - Some (Prim (loc, "DIP", [Int (loc, Z.of_int depth); sub], [])) - | _ -> None - -let unexpand_dupn expanded = - match expanded with - | Seq - ( loc, - [ - Prim - (_, "DIP", [Int (_, np); Seq (_, [Prim (_, "DUP", [], annot)])], []); - Prim (_, "DIG", [Int (nloc, ng)], []); - ] ) - when Z.equal np (Z.pred ng) -> - Some (Prim (loc, "DUP", [Int (nloc, ng)], annot)) - | _ -> None - -let unexpand_deprecated_duuuuup expanded = - (* transparently turn the old expansion of deprecated [DU...UP] to [DUP n] *) - let rec expand n = function - | Seq (loc, [Prim (nloc, "DUP", [], annot)]) -> - if n = 1 then None - else Some (Prim (loc, "DUP", [Int (nloc, Z.of_int n)], annot)) - | Seq (_, [Prim (_, "DIP", [expanded'], []); Prim (_, "SWAP", [], [])]) -> - expand (n + 1) expanded' - | _ -> None - in - expand 1 expanded - -let rec normalize_pair_item ?(right = false) = function - | P (i, a, b) -> - P (i, normalize_pair_item a, normalize_pair_item ~right:true b) - | A when right -> I - | A -> A - | I -> I - -let unexpand_pappaiir expanded = - match expanded with - | Seq (_, [Prim (_, "PAIR", [], [])]) -> Some expanded - | Seq (loc, (_ :: _ as nodes)) -> ( - let rec exec stack nodes = - match (nodes, stack) with - | ([], _) -> stack - (* support new expansion using [DIP n] *) - | ( Prim (ploc, "DIP", [Int (loc, n); Seq (sloc, sub)], []) :: rest, - a :: rstack ) - when Z.to_int n > 1 -> - exec - (a - :: - exec - rstack - [ - Prim (ploc, "DIP", [Int (loc, Z.pred n); Seq (sloc, sub)], []); - ]) - rest - | (Prim (_, "DIP", [Int (_, n); Seq (_, sub)], []) :: rest, a :: rstack) - when Z.to_int n = 1 -> - exec (a :: exec rstack sub) rest - | (Prim (ploc, "DIP", [Int (loc, n); Seq (sloc, sub)], []) :: rest, []) - when Z.to_int n > 1 -> - exec - (A - :: - exec - [] - [ - Prim (ploc, "DIP", [Int (loc, Z.pred n); Seq (sloc, sub)], []); - ]) - rest - | (Prim (_, "DIP", [Int (_, n); Seq (_, sub)], []) :: rest, []) - when Z.to_int n = 1 -> - exec (A :: exec [] sub) rest - (* support old expansion using [DIP] *) - | (Prim (_, "DIP", [Seq (_, sub)], []) :: rest, a :: rstack) -> - exec (a :: exec rstack sub) rest - | (Prim (_, "DIP", [Seq (_, sub)], []) :: rest, []) -> - exec (A :: exec [] sub) rest - | (Prim (_, "PAIR", [], []) :: rest, a :: b :: rstack) -> - exec (P (0, a, b) :: rstack) rest - | (Prim (_, "PAIR", [], []) :: rest, [a]) -> exec [P (0, a, I)] rest - | (Prim (_, "PAIR", [], []) :: rest, []) -> exec [P (0, A, I)] rest - | _ -> raise_notrace Not_a_pair - in - match exec [] nodes with - | [] -> None - | res :: _ -> - let res = normalize_pair_item res in - let name = unparse_pair_item res in - Some (Prim (loc, name, [], [])) - | exception Not_a_pair -> None) - | _ -> None - -let unexpand_unpappaiir expanded = - match expanded with - | Seq (loc, (_ :: _ as nodes)) -> ( - let rec exec stack nodes = - match (nodes, stack) with - | ([], _) -> stack - (* support new expansion using [DIP n] *) - | ( Prim (ploc, "DIP", [Int (loc, n); Seq (sloc, sub)], []) :: rest, - a :: rstack ) - when Z.to_int n > 1 -> - exec - (a - :: - exec - rstack - [ - Prim (ploc, "DIP", [Int (loc, Z.pred n); Seq (sloc, sub)], []); - ]) - rest - | (Prim (_, "DIP", [Int (_, n); Seq (_, sub)], []) :: rest, a :: rstack) - when Z.to_int n = 1 -> - exec (a :: exec rstack sub) rest - | (Prim (ploc, "DIP", [Int (loc, n); Seq (sloc, sub)], []) :: rest, []) - when Z.to_int n > 1 -> - exec - (A - :: - exec - [] - [ - Prim (ploc, "DIP", [Int (loc, Z.pred n); Seq (sloc, sub)], []); - ]) - rest - | (Prim (_, "DIP", [Int (_, n); Seq (_, sub)], []) :: rest, []) - when Z.to_int n = 1 -> - exec (A :: exec [] sub) rest - (* support old expansion using [DIP] *) - | (Prim (_, "DIP", [Seq (_, sub)], []) :: rest, a :: rstack) -> - exec (a :: exec rstack sub) rest - | (Prim (_, "DIP", [Seq (_, sub)], []) :: rest, []) -> - exec (A :: exec [] sub) rest - | ( Seq - ( _, - [ - Prim (_, "DUP", [], []); - Prim (_, "CAR", [], []); - Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], [])])], []); - ] ) - :: rest, - a :: b :: rstack ) -> - exec (P (0, a, b) :: rstack) rest - | ( Seq - ( _, - [ - Prim (_, "DUP", [], []); - Prim (_, "CAR", [], []); - Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], [])])], []); - ] ) - :: rest, - [a] ) -> - exec [P (0, a, I)] rest - | ( Seq - ( _, - [ - Prim (_, "DUP", [], []); - Prim (_, "CAR", [], []); - Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], [])])], []); - ] ) - :: rest, - [] ) -> - exec [P (0, A, I)] rest - | _ -> raise_notrace Not_a_pair - in - match exec [] (List.rev nodes) with - | [] -> None - | res :: _ -> - let res = normalize_pair_item res in - let name = "UN" ^ unparse_pair_item res in - Some (Prim (loc, name, [], [])) - | exception Not_a_pair -> None) - | _ -> None - -let unexpand_compare expanded = - match expanded with - | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "EQ", [], annot)]) -> - Some (Prim (loc, "CMPEQ", [], annot)) - | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "NEQ", [], annot)]) -> - Some (Prim (loc, "CMPNEQ", [], annot)) - | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "LT", [], annot)]) -> - Some (Prim (loc, "CMPLT", [], annot)) - | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "GT", [], annot)]) -> - Some (Prim (loc, "CMPGT", [], annot)) - | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "LE", [], annot)]) -> - Some (Prim (loc, "CMPLE", [], annot)) - | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "GE", [], annot)]) -> - Some (Prim (loc, "CMPGE", [], annot)) - | Seq - ( loc, - [ - Prim (_, "COMPARE", [], _); - Prim (_, "EQ", [], _); - Prim (_, "IF", args, annot); - ] ) -> - Some (Prim (loc, "IFCMPEQ", args, annot)) - | Seq - ( loc, - [ - Prim (_, "COMPARE", [], _); - Prim (_, "NEQ", [], _); - Prim (_, "IF", args, annot); - ] ) -> - Some (Prim (loc, "IFCMPNEQ", args, annot)) - | Seq - ( loc, - [ - Prim (_, "COMPARE", [], _); - Prim (_, "LT", [], _); - Prim (_, "IF", args, annot); - ] ) -> - Some (Prim (loc, "IFCMPLT", args, annot)) - | Seq - ( loc, - [ - Prim (_, "COMPARE", [], _); - Prim (_, "GT", [], _); - Prim (_, "IF", args, annot); - ] ) -> - Some (Prim (loc, "IFCMPGT", args, annot)) - | Seq - ( loc, - [ - Prim (_, "COMPARE", [], _); - Prim (_, "LE", [], _); - Prim (_, "IF", args, annot); - ] ) -> - Some (Prim (loc, "IFCMPLE", args, annot)) - | Seq - ( loc, - [ - Prim (_, "COMPARE", [], _); - Prim (_, "GE", [], _); - Prim (_, "IF", args, annot); - ] ) -> - Some (Prim (loc, "IFCMPGE", args, annot)) - | Seq (loc, [Prim (_, "EQ", [], _); Prim (_, "IF", args, annot)]) -> - Some (Prim (loc, "IFEQ", args, annot)) - | Seq (loc, [Prim (_, "NEQ", [], _); Prim (_, "IF", args, annot)]) -> - Some (Prim (loc, "IFNEQ", args, annot)) - | Seq (loc, [Prim (_, "LT", [], _); Prim (_, "IF", args, annot)]) -> - Some (Prim (loc, "IFLT", args, annot)) - | Seq (loc, [Prim (_, "GT", [], _); Prim (_, "IF", args, annot)]) -> - Some (Prim (loc, "IFGT", args, annot)) - | Seq (loc, [Prim (_, "LE", [], _); Prim (_, "IF", args, annot)]) -> - Some (Prim (loc, "IFLE", args, annot)) - | Seq (loc, [Prim (_, "GE", [], _); Prim (_, "IF", args, annot)]) -> - Some (Prim (loc, "IFGE", args, annot)) - | _ -> None - -let unexpand_asserts expanded = - match expanded with - | Seq - ( loc, - [ - Prim - ( _, - "IF", - [ - Seq (_, []); - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT", [], [])) - | Seq - ( loc, - [ - Seq (_, [Prim (_, "COMPARE", [], []); Prim (_, comparison, [], [])]); - Prim - ( _, - "IF", - [ - Seq (_, []); - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_CMP" ^ comparison, [], [])) - | Seq - ( loc, - [ - Prim (_, comparison, [], []); - Prim - ( _, - "IF", - [ - Seq (_, []); - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_" ^ comparison, [], [])) - | Seq - ( loc, - [ - Prim - ( _, - "IF_NONE", - [ - Seq (_, [Prim (_, "RENAME", [], annot)]); - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_NONE", [], annot)) - | Seq - ( loc, - [ - Prim - ( _, - "IF_NONE", - [ - Seq (_, []); - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_NONE", [], [])) - | Seq - ( loc, - [ - Prim - ( _, - "IF_NONE", - [ - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - Seq (_, []); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_SOME", [], [])) - | Seq - ( loc, - [ - Prim - ( _, - "IF_NONE", - [ - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - Seq (_, [Prim (_, "RENAME", [], annot)]); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_SOME", [], annot)) - | Seq - ( loc, - [ - Prim - ( _, - "IF_LEFT", - [ - Seq (_, []); - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_LEFT", [], [])) - | Seq - ( loc, - [ - Prim - ( _, - "IF_LEFT", - [ - Seq (_, [Prim (_, "RENAME", [], annot)]); - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_LEFT", [], annot)) - | Seq - ( loc, - [ - Prim - ( _, - "IF_LEFT", - [ - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - Seq (_, []); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_RIGHT", [], [])) - | Seq - ( loc, - [ - Prim - ( _, - "IF_LEFT", - [ - Seq - ( _, - [ - Seq - ( _, - [ - Prim (_, "UNIT", [], []); - Prim (_, "FAILWITH", [], []); - ] ); - ] ); - Seq (_, [Prim (_, "RENAME", [], annot)]); - ], - [] ); - ] ) -> - Some (Prim (loc, "ASSERT_RIGHT", [], annot)) - | _ -> None - -let unexpand_if_some = function - | Seq (loc, [Prim (_, "IF_NONE", [left; right], annot)]) -> - Some (Prim (loc, "IF_SOME", [right; left], annot)) - | _ -> None - -let unexpand_if_right = function - | Seq (loc, [Prim (_, "IF_LEFT", [left; right], annot)]) -> - Some (Prim (loc, "IF_RIGHT", [right; left], annot)) - | _ -> None - -let unexpand_fail = function - | Seq (loc, [Prim (_, "UNIT", [], []); Prim (_, "FAILWITH", [], [])]) -> - Some (Prim (loc, "FAIL", [], [])) - | _ -> None - -let unexpand original = - let try_unexpansions unexpanders = - Option.value - ~default:original - (List.fold_left - (fun acc f -> Option.either_f acc (fun () -> f original)) - None - unexpanders) - in - try_unexpansions - [ - unexpand_asserts; - unexpand_carn_and_cdrn; - unexpand_caddadr; - unexpand_set_caddadr; - unexpand_map_caddadr; - unexpand_deprecated_dxiiivp; - unexpand_pappaiir; - unexpand_unpappaiir; - unexpand_deprecated_duuuuup; - unexpand_dupn; - unexpand_compare; - unexpand_if_some; - unexpand_if_right; - unexpand_fail; - ] - -(* - If an argument of Prim is a sequence, we do not want to unexpand - its root in case the source already contains an expanded macro. In - which case unexpansion would remove surrounding braces and generate - ill-formed code. - - For example, DIIP { DIP { DUP }; SWAP } is not unexpandable but - DIIP {{ DIP { DUP }; SWAP }} (note the double braces) is unexpanded - to DIIP { DUUP }. - - unexpand_rec_but_root is the same as unexpand_rec but does not try - to unexpand at root *) - -let rec unexpand_rec expr = unexpand_rec_but_root (unexpand expr) - -and unexpand_rec_but_root = function - | Seq (loc, items) -> Seq (loc, List.map unexpand_rec items) - | Prim (loc, name, args, annot) -> - Prim (loc, name, List.map unexpand_rec_but_root args, annot) - | (Int _ | String _ | Bytes _) as atom -> atom - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"michelson.macros.unexpected_annotation" - ~title:"Unexpected annotation" - ~description: - "A macro had an annotation, but no annotation was permitted on this \ - macro." - ~pp:(fun ppf -> Format.fprintf ppf "Unexpected annotation on macro %s.") - (obj1 (req "macro_name" string)) - (function Unexpected_macro_annotation str -> Some str | _ -> None) - (fun s -> Unexpected_macro_annotation s) ; - register_error_kind - `Permanent - ~id:"michelson.macros.sequence_expected" - ~title:"Macro expects a sequence" - ~description:"An macro expects a sequence, but a sequence was not provided" - ~pp:(fun ppf name -> - Format.fprintf - ppf - "Macro %s expects a sequence, but did not receive one." - name) - (obj1 (req "macro_name" string)) - (function Sequence_expected name -> Some name | _ -> None) - (fun name -> Sequence_expected name) ; - register_error_kind - `Permanent - ~id:"michelson.macros.bas_arity" - ~title:"Wrong number of arguments to macro" - ~description:"A wrong number of arguments was provided to a macro" - ~pp:(fun ppf (name, got, exp) -> - Format.fprintf - ppf - "Macro %s expects %d arguments, was given %d." - name - exp - got) - (obj3 - (req "macro_name" string) - (req "given_number_of_arguments" uint16) - (req "expected_number_of_arguments" uint16)) - (function - | Invalid_arity (name, got, exp) -> Some (name, got, exp) | _ -> None) - (fun (name, got, exp) -> Invalid_arity (name, got, exp)) diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_macros.mli b/src/proto_012_Psithaca/lib_client/michelson_v1_macros.mli deleted file mode 100644 index 352a59b00a9e..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_macros.mli +++ /dev/null @@ -1,86 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Tezos_micheline - -type 'l node = ('l, string) Micheline.node - -type error += Unexpected_macro_annotation of string - -type error += Sequence_expected of string - -type error += Invalid_arity of string * int * int - -val expand : 'l node -> 'l node tzresult - -val expand_rec : 'l node -> 'l node * error list - -val expand_caddadr : 'l node -> 'l node option tzresult - -val expand_set_caddadr : 'l node -> 'l node option tzresult - -val expand_map_caddadr : 'l node -> 'l node option tzresult - -val expand_deprecated_dxiiivp : 'l node -> 'l node option tzresult - -val expand_pappaiir : 'l node -> 'l node option tzresult - -val expand_deprecated_duuuuup : 'l node -> 'l node option tzresult - -val expand_compare : 'l node -> 'l node option tzresult - -val expand_asserts : 'l node -> 'l node option tzresult - -val expand_unpappaiir : 'l node -> 'l node option tzresult - -val expand_if_some : 'l node -> 'l node option tzresult - -val expand_if_right : 'l node -> 'l node option tzresult - -val unexpand : 'l node -> 'l node - -val unexpand_rec : 'l node -> 'l node - -val unexpand_caddadr : 'l node -> 'l node option - -val unexpand_set_caddadr : 'l node -> 'l node option - -val unexpand_map_caddadr : 'l node -> 'l node option - -val unexpand_deprecated_dxiiivp : 'l node -> 'l node option - -val unexpand_pappaiir : 'l node -> 'l node option - -val unexpand_deprecated_duuuuup : 'l node -> 'l node option - -val unexpand_compare : 'l node -> 'l node option - -val unexpand_asserts : 'l node -> 'l node option - -val unexpand_unpappaiir : 'l node -> 'l node option - -val unexpand_if_some : 'l node -> 'l node option - -val unexpand_if_right : 'l node -> 'l node option diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_parser.ml b/src/proto_012_Psithaca/lib_client/michelson_v1_parser.ml deleted file mode 100644 index 2f44d22c1fca..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_parser.ml +++ /dev/null @@ -1,103 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Tezos_micheline -open Micheline_parser -open Micheline - -type parsed = { - source : string; - unexpanded : string canonical; - expanded : Michelson_v1_primitives.prim canonical; - expansion_table : (int * (Micheline_parser.location * int list)) list; - unexpansion_table : (int * int) list; -} - -let compare_parsed = Stdlib.compare - -(* Unexpanded toplevel expression should be a sequence *) -let expand_all source ast errors = - let (unexpanded, loc_table) = extract_locations ast in - let (expanded, expansion_errors) = - Michelson_v1_macros.expand_rec (root unexpanded) - in - let (expanded, unexpansion_table) = extract_locations expanded in - let expansion_table = - let sorted = - List.sort (fun (_, a) (_, b) -> Stdlib.compare a b) unexpansion_table - in - let grouped = - let rec group = function - | (acc, []) -> acc - | ([], (u, e) :: r) -> group ([(e, [u])], r) - | (((pe, us) :: racc as acc), (u, e) :: r) -> - if e = pe then group ((e, u :: us) :: racc, r) - else group ((e, [u]) :: acc, r) - in - group ([], sorted) - in - match - List.map2 - ~when_different_lengths:() - (fun (l, ploc) (l', elocs) -> - assert (l = l') ; - (l, (ploc, elocs))) - (List.sort Stdlib.compare loc_table) - (List.sort Stdlib.compare grouped) - with - | Ok v -> v - | Error () -> invalid_arg "Michelson_v1_parser.expand_all" - in - match Michelson_v1_primitives.prims_of_strings expanded with - | Ok expanded -> - ( {source; unexpanded; expanded; expansion_table; unexpansion_table}, - errors @ expansion_errors ) - | Error errs -> - let errs = Environment.wrap_tztrace errs in - ( { - source; - unexpanded; - expanded = Micheline.strip_locations (Seq ((), [])); - expansion_table; - unexpansion_table; - }, - errors @ expansion_errors @ errs ) - -let parse_toplevel ?check source = - let (tokens, lexing_errors) = Micheline_parser.tokenize source in - let (asts, parsing_errors) = Micheline_parser.parse_toplevel ?check tokens in - let ast = - let start = min_point asts and stop = max_point asts in - Seq ({start; stop}, asts) - in - expand_all source ast (lexing_errors @ parsing_errors) - -let parse_expression ?check source = - let (tokens, lexing_errors) = Micheline_parser.tokenize source in - let (ast, parsing_errors) = Micheline_parser.parse_expression ?check tokens in - expand_all source ast (lexing_errors @ parsing_errors) - -let expand_all ~source ~original = expand_all source original [] diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_parser.mli b/src/proto_012_Psithaca/lib_client/michelson_v1_parser.mli deleted file mode 100644 index 6aa29676741a..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_parser.mli +++ /dev/null @@ -1,55 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Tezos_micheline - -(** The result of parsing and expanding a Michelson V1 script or data. *) -type parsed = { - source : string; (** The original source code. *) - unexpanded : string Micheline.canonical; - (** Original expression with macros. *) - expanded : Script.expr; (** Expression with macros fully expanded. *) - expansion_table : (int * (Micheline_parser.location * int list)) list; - (** Associates unexpanded nodes to their parsing locations and - the nodes expanded from it in the expanded expression. *) - unexpansion_table : (int * int) list; - (** Associates an expanded node to its source in the unexpanded - expression. *) -} - -val compare_parsed : parsed -> parsed -> int - -val parse_toplevel : - ?check:bool -> string -> parsed Micheline_parser.parsing_result - -val parse_expression : - ?check:bool -> string -> parsed Micheline_parser.parsing_result - -val expand_all : - source:string -> - original:Micheline_parser.node -> - parsed Micheline_parser.parsing_result diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_printer.ml b/src/proto_012_Psithaca/lib_client/michelson_v1_printer.ml deleted file mode 100644 index 5eeb4e1fd88c..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_printer.ml +++ /dev/null @@ -1,241 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Tezos_micheline -open Micheline -open Micheline_printer - -let anon = {comment = None} - -let print_expr ppf expr = - expr |> Michelson_v1_primitives.strings_of_prims - |> Micheline.inject_locations (fun _ -> anon) - |> print_expr ppf - -let print_expr_unwrapped ppf expr = - expr |> Michelson_v1_primitives.strings_of_prims - |> Micheline.inject_locations (fun _ -> anon) - |> print_expr_unwrapped ppf - -let print_var_annots ppf = List.iter (Format.fprintf ppf "%s ") - -let print_annot_expr_unwrapped ppf (expr, annot) = - Format.fprintf ppf "%a%a" print_var_annots annot print_expr_unwrapped expr - -let print_stack ppf = function - | [] -> Format.fprintf ppf "[]" - | more -> - Format.fprintf - ppf - "@[[ %a ]@]" - (Format.pp_print_list - ~pp_sep:(fun ppf () -> Format.fprintf ppf "@ : ") - print_annot_expr_unwrapped) - more - -let print_execution_trace ppf trace = - Format.pp_print_list - (fun ppf (loc, gas, stack) -> - Format.fprintf - ppf - "- @[location: %d (remaining gas: %a)@,[ @[%a ]@]@]" - loc - Gas.pp - gas - (Format.pp_print_list (fun ppf (e, annot) -> - Format.fprintf - ppf - "@[%a \t%s@]" - print_expr - e - (match annot with None -> "" | Some a -> a))) - stack) - ppf - trace - -let print_big_map_diff ppf lazy_storage_diff = - let diff = - Contract.Legacy_big_map_diff.of_lazy_storage_diff lazy_storage_diff - in - let pp_map ppf id = - if Compare.Z.(id < Z.zero) then - Format.fprintf ppf "temp(%s)" (Z.to_string (Z.neg id)) - else Format.fprintf ppf "map(%s)" (Z.to_string id) - in - Format.fprintf - ppf - "@[%a@]" - (Format.pp_print_list ~pp_sep:Format.pp_print_space (fun ppf -> function - | Contract.Legacy_big_map_diff.Clear id -> - Format.fprintf ppf "Clear %a" pp_map id - | Contract.Legacy_big_map_diff.Alloc {big_map; key_type; value_type} -> - Format.fprintf - ppf - "New %a of type (big_map %a %a)" - pp_map - big_map - print_expr - key_type - print_expr - value_type - | Contract.Legacy_big_map_diff.Copy {src; dst} -> - Format.fprintf ppf "Copy %a to %a" pp_map src pp_map dst - | Contract.Legacy_big_map_diff.Update {big_map; diff_key; diff_value; _} - -> - Format.fprintf - ppf - "%s %a[%a]%a" - (match diff_value with None -> "Unset" | Some _ -> "Set") - pp_map - big_map - print_expr - diff_key - (fun ppf -> function - | None -> () - | Some x -> Format.fprintf ppf " to %a" print_expr x) - diff_value)) - (diff :> Contract.Legacy_big_map_diff.item list) - -let inject_types type_map parsed = - let rec inject_expr = function - | Seq (loc, items) -> - Seq (inject_loc `before loc, List.map inject_expr items) - | Prim (loc, name, items, annot) -> - Prim (inject_loc `after loc, name, List.map inject_expr items, annot) - | Int (loc, value) -> Int (inject_loc `after loc, value) - | String (loc, value) -> String (inject_loc `after loc, value) - | Bytes (loc, value) -> Bytes (inject_loc `after loc, value) - and inject_loc which loc = - let comment = - let ( >?? ) = Option.bind in - List.assoc ~equal:Int.equal loc parsed.Michelson_v1_parser.expansion_table - >?? fun (_, locs) -> - let locs = List.sort compare locs in - List.hd locs >?? fun head_loc -> - List.assoc ~equal:Int.equal head_loc type_map >?? fun (bef, aft) -> - let stack = match which with `before -> bef | `after -> aft in - Some (Format.asprintf "%a" print_stack stack) - in - {comment} - in - inject_expr (root parsed.unexpanded) - -let unparse ?type_map parse expanded = - let source = - match type_map with - | Some type_map -> - let (unexpanded, unexpansion_table) = - expanded |> Michelson_v1_primitives.strings_of_prims |> root - |> Michelson_v1_macros.unexpand_rec |> Micheline.extract_locations - in - let rec inject_expr = function - | Seq (loc, items) -> - Seq (inject_loc `before loc, List.map inject_expr items) - | Prim (loc, name, items, annot) -> - Prim - (inject_loc `after loc, name, List.map inject_expr items, annot) - | Int (loc, value) -> Int (inject_loc `after loc, value) - | String (loc, value) -> String (inject_loc `after loc, value) - | Bytes (loc, value) -> Bytes (inject_loc `after loc, value) - and inject_loc which loc = - let comment = - let ( >?? ) = Option.bind in - List.assoc ~equal:Int.equal loc unexpansion_table >?? fun loc -> - List.assoc ~equal:Int.equal loc type_map >?? fun (bef, aft) -> - let stack = match which with `before -> bef | `after -> aft in - Some (Format.asprintf "%a" print_stack stack) - in - {comment} - in - unexpanded |> root |> inject_expr - |> Format.asprintf "%a" Micheline_printer.print_expr - | None -> - expanded |> Michelson_v1_primitives.strings_of_prims |> root - |> Michelson_v1_macros.unexpand_rec |> Micheline.strip_locations - |> Micheline_printer.printable (fun n -> n) - |> Format.asprintf "%a" Micheline_printer.print_expr - in - match parse source with - | (res, []) -> res - | (_, _ :: _) -> Stdlib.failwith "Michelson_v1_printer.unparse" - -let unparse_toplevel ?type_map = - unparse ?type_map Michelson_v1_parser.parse_toplevel - -let unparse_expression = unparse Michelson_v1_parser.parse_expression - -let unparse_invalid expanded = - let source = - expanded |> root |> Michelson_v1_macros.unexpand_rec - |> Micheline.strip_locations - |> Micheline_printer.printable (fun n -> n) - |> Format.asprintf "%a" Micheline_printer.print_expr_unwrapped - in - fst (Michelson_v1_parser.parse_toplevel source) - -let ocaml_constructor_of_prim prim = - (* Assuming all the prim constructor prefixes match the - [[Michelson_v1_primitives.namespace]]. *) - let prefix = - Michelson_v1_primitives.(namespace prim |> string_of_namespace) - in - Format.asprintf "%s_%s" prefix @@ Michelson_v1_primitives.string_of_prim prim - -let micheline_string_of_expression ~zero_loc expression = - let string_of_list : string list -> string = - fun xs -> String.concat "; " xs |> Format.asprintf "[%s]" - in - let show_loc loc = if zero_loc then 0 else loc in - let rec string_of_node = function - | Int (loc, i) -> - let z = - match Z.to_int i with - | 0 -> "Z.zero" - | 1 -> "Z.one" - | i -> Format.asprintf "Z.of_int %d" i - in - Format.asprintf "Int (%d, %s)" (show_loc loc) z - | String (loc, s) -> Format.asprintf "String (%d, \"%s\")" (show_loc loc) s - | Bytes (loc, b) -> - Format.asprintf - "Bytes (%d, Bytes.of_string \"%s\")" - (show_loc loc) - Bytes.(escaped b |> to_string) - | Prim (loc, prim, nodes, annot) -> - Format.asprintf - "Prim (%d, %s, %s, %s)" - (show_loc loc) - (ocaml_constructor_of_prim prim) - (string_of_list @@ List.map string_of_node nodes) - (string_of_list @@ List.map (Format.asprintf "\"%s\"") annot) - | Seq (loc, nodes) -> - Format.asprintf - "Seq (%d, %s)" - (show_loc loc) - (string_of_list @@ List.map string_of_node nodes) - in - string_of_node (root expression) diff --git a/src/proto_012_Psithaca/lib_client/michelson_v1_printer.mli b/src/proto_012_Psithaca/lib_client/michelson_v1_printer.mli deleted file mode 100644 index 07cb29ae8556..000000000000 --- a/src/proto_012_Psithaca/lib_client/michelson_v1_printer.mli +++ /dev/null @@ -1,65 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Tezos_micheline - -val print_expr : Format.formatter -> Script_repr.expr -> unit - -val print_expr_unwrapped : Format.formatter -> Script_repr.expr -> unit - -val print_execution_trace : - Format.formatter -> - (Script.location * Gas.t * (Script.expr * string option) list) list -> - unit - -val print_big_map_diff : Format.formatter -> Lazy_storage.diffs -> unit - -(** Insert the type map returned by the typechecker as comments in a - printable Micheline AST. *) -val inject_types : - Script_tc_errors.type_map -> - Michelson_v1_parser.parsed -> - Micheline_printer.node - -(** Unexpand the macros and produce the result of parsing an - intermediate pretty printed source. Useful when working with - contracts extracted from the blockchain and not local files. *) -val unparse_toplevel : - ?type_map:Script_tc_errors.type_map -> - Script.expr -> - Michelson_v1_parser.parsed - -val unparse_expression : Script.expr -> Michelson_v1_parser.parsed - -(** Unexpand the macros and produce the result of parsing an - intermediate pretty printed source. Works on generic trees,for - programs that fail to be converted to a specific script version. *) -val unparse_invalid : string Micheline.canonical -> Michelson_v1_parser.parsed - -val ocaml_constructor_of_prim : Michelson_v1_primitives.prim -> string - -val micheline_string_of_expression : zero_loc:bool -> Script.expr -> string diff --git a/src/proto_012_Psithaca/lib_client/mockup.ml b/src/proto_012_Psithaca/lib_client/mockup.ml deleted file mode 100644 index f6abdf46bd2c..000000000000 --- a/src/proto_012_Psithaca/lib_client/mockup.ml +++ /dev/null @@ -1,1158 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol.Alpha_context - -(* ------------------------------------------------------------------------- *) -(* Mockup protocol parameters *) - -(** Protocol constants overriding logic. *) -module Protocol_constants_overrides = struct - (** Equivalent of [Constants.parametric] with additionally [chain_id] and [timestamp] but each field is wrapped in an [option]. - [Some] is an override, [None] means "Use the default value". - *) - type t = { - preserved_cycles : int option; - blocks_per_cycle : int32 option; - blocks_per_commitment : int32 option; - blocks_per_stake_snapshot : int32 option; - blocks_per_voting_period : int32 option; - hard_gas_limit_per_operation : Gas.Arith.integral option; - hard_gas_limit_per_block : Gas.Arith.integral option; - proof_of_work_threshold : int64 option; - tokens_per_roll : Tez.t option; - seed_nonce_revelation_tip : Tez.t option; - origination_size : int option; - baking_reward_fixed_portion : Tez.t option; - baking_reward_bonus_per_slot : Tez.t option; - endorsing_reward_per_slot : Tez.t option; - cost_per_byte : Tez.t option; - hard_storage_limit_per_operation : Z.t option; - quorum_min : int32 option; - quorum_max : int32 option; - min_proposal_quorum : int32 option; - liquidity_baking_subsidy : Tez.t option; - liquidity_baking_sunset_level : int32 option; - liquidity_baking_escape_ema_threshold : int32 option; - max_operations_time_to_live : int option; - minimal_block_delay : Period.t option; - delay_increment_per_round : Period.t option; - minimal_participation_ratio : Constants.ratio option; - consensus_committee_size : int option; - consensus_threshold : int option; - delegate_selection : Constants.delegate_selection option; - max_slashing_period : int option; - frozen_deposits_percentage : int option; - double_baking_punishment : Tez.t option; - ratio_of_frozen_deposits_slashed_per_double_endorsement : - Constants.ratio option; - (* Additional, "bastard" parameters (they are not protocol constants but partially treated the same way). *) - chain_id : Chain_id.t option; - timestamp : Time.Protocol.t option; - } - - (** Shamefully copied from [Constants_repr.parametric_encoding] and adapted ([opt] instead of [req]). *) - let encoding = - let open Data_encoding in - conv - (fun c -> - ( ( c.preserved_cycles, - c.blocks_per_cycle, - c.blocks_per_commitment, - c.blocks_per_stake_snapshot, - c.blocks_per_voting_period, - c.hard_gas_limit_per_operation, - c.hard_gas_limit_per_block, - c.proof_of_work_threshold, - c.tokens_per_roll ), - ( ( c.seed_nonce_revelation_tip, - c.origination_size, - c.baking_reward_fixed_portion, - c.baking_reward_bonus_per_slot, - c.endorsing_reward_per_slot, - c.cost_per_byte, - c.hard_storage_limit_per_operation, - c.quorum_min ), - ( ( c.quorum_max, - c.min_proposal_quorum, - c.liquidity_baking_subsidy, - c.liquidity_baking_sunset_level, - c.liquidity_baking_escape_ema_threshold, - c.max_operations_time_to_live, - c.minimal_block_delay, - c.delay_increment_per_round, - c.consensus_committee_size, - c.consensus_threshold ), - ( c.delegate_selection, - c.minimal_participation_ratio, - c.max_slashing_period, - c.frozen_deposits_percentage, - c.double_baking_punishment, - c.ratio_of_frozen_deposits_slashed_per_double_endorsement, - c.chain_id, - c.timestamp ) ) ) )) - (fun ( ( preserved_cycles, - blocks_per_cycle, - blocks_per_commitment, - blocks_per_stake_snapshot, - blocks_per_voting_period, - hard_gas_limit_per_operation, - hard_gas_limit_per_block, - proof_of_work_threshold, - tokens_per_roll ), - ( ( seed_nonce_revelation_tip, - origination_size, - baking_reward_fixed_portion, - baking_reward_bonus_per_slot, - endorsing_reward_per_slot, - cost_per_byte, - hard_storage_limit_per_operation, - quorum_min ), - ( ( quorum_max, - min_proposal_quorum, - liquidity_baking_subsidy, - liquidity_baking_sunset_level, - liquidity_baking_escape_ema_threshold, - max_operations_time_to_live, - minimal_block_delay, - delay_increment_per_round, - consensus_committee_size, - consensus_threshold ), - ( delegate_selection, - minimal_participation_ratio, - max_slashing_period, - frozen_deposits_percentage, - double_baking_punishment, - ratio_of_frozen_deposits_slashed_per_double_endorsement, - chain_id, - timestamp ) ) ) ) -> - { - preserved_cycles; - blocks_per_cycle; - blocks_per_commitment; - blocks_per_stake_snapshot; - blocks_per_voting_period; - hard_gas_limit_per_operation; - hard_gas_limit_per_block; - proof_of_work_threshold; - tokens_per_roll; - seed_nonce_revelation_tip; - origination_size; - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - cost_per_byte; - hard_storage_limit_per_operation; - quorum_min; - quorum_max; - min_proposal_quorum; - liquidity_baking_subsidy; - liquidity_baking_sunset_level; - liquidity_baking_escape_ema_threshold; - max_operations_time_to_live; - minimal_block_delay; - delay_increment_per_round; - minimal_participation_ratio; - max_slashing_period; - frozen_deposits_percentage; - consensus_committee_size; - consensus_threshold; - delegate_selection; - double_baking_punishment; - ratio_of_frozen_deposits_slashed_per_double_endorsement; - chain_id; - timestamp; - }) - (merge_objs - (obj9 - (opt "preserved_cycles" uint8) - (opt "blocks_per_cycle" int32) - (opt "blocks_per_commitment" int32) - (opt "blocks_per_stake_snapshot" int32) - (opt "blocks_per_voting_period" int32) - (opt "hard_gas_limit_per_operation" Gas.Arith.z_integral_encoding) - (opt "hard_gas_limit_per_block" Gas.Arith.z_integral_encoding) - (opt "proof_of_work_threshold" int64) - (opt "tokens_per_roll" Tez.encoding)) - (merge_objs - (obj8 - (opt "seed_nonce_revelation_tip" Tez.encoding) - (opt "origination_size" int31) - (opt "baking_reward_fixed_portion" Tez.encoding) - (opt "baking_reward_bonus_per_slot" Tez.encoding) - (opt "endorsing_reward_per_slot" Tez.encoding) - (opt "cost_per_byte" Tez.encoding) - (opt "hard_storage_limit_per_operation" z) - (opt "quorum_min" int32)) - (merge_objs - (obj10 - (opt "quorum_max" int32) - (opt "min_proposal_quorum" int32) - (opt "liquidity_baking_subsidy" Tez.encoding) - (opt "liquidity_baking_sunset_level" int32) - (opt "liquidity_baking_escape_ema_threshold" int32) - (opt "max_operations_time_to_live" int16) - (opt "minimal_block_delay" Period.encoding) - (opt "delay_increment_per_round" Period.encoding) - (opt "consensus_committee_size" int31) - (opt "consensus_threshold" int31)) - (obj8 - (opt - "delegate_selection" - Constants.delegate_selection_encoding) - (opt "minimal_participation_ratio" Constants.ratio_encoding) - (opt "max_slashing_period" int31) - (opt "frozen_deposits_percentage" int31) - (opt "double_baking_punishment" Tez.encoding) - (opt - "ratio_of_frozen_deposits_slashed_per_double_endorsement" - Constants.ratio_encoding) - (opt "chain_id" Chain_id.encoding) - (opt "initial_timestamp" Time.Protocol.encoding))))) - - let default_value (cctxt : Tezos_client_base.Client_context.full) : - t tzresult Lwt.t = - let cpctxt = new Protocol_client_context.wrap_full cctxt in - Protocol.Constants_services.all cpctxt (cpctxt#chain, cpctxt#block) - >>=? fun {parametric; _} -> - let to_chain_id_opt = function `Hash c -> Some c | _ -> None in - Shell_services.Blocks.Header.shell_header - cpctxt - ~chain:cpctxt#chain - ~block:cpctxt#block - () - >>=? fun header -> - return - { - preserved_cycles = Some parametric.preserved_cycles; - blocks_per_cycle = Some parametric.blocks_per_cycle; - blocks_per_commitment = Some parametric.blocks_per_commitment; - blocks_per_stake_snapshot = Some parametric.blocks_per_stake_snapshot; - blocks_per_voting_period = Some parametric.blocks_per_voting_period; - hard_gas_limit_per_operation = - Some parametric.hard_gas_limit_per_operation; - hard_gas_limit_per_block = Some parametric.hard_gas_limit_per_block; - proof_of_work_threshold = Some parametric.proof_of_work_threshold; - tokens_per_roll = Some parametric.tokens_per_roll; - seed_nonce_revelation_tip = Some parametric.seed_nonce_revelation_tip; - origination_size = Some parametric.origination_size; - baking_reward_fixed_portion = - Some parametric.baking_reward_fixed_portion; - baking_reward_bonus_per_slot = - Some parametric.baking_reward_bonus_per_slot; - endorsing_reward_per_slot = Some parametric.endorsing_reward_per_slot; - cost_per_byte = Some parametric.cost_per_byte; - hard_storage_limit_per_operation = - Some parametric.hard_storage_limit_per_operation; - quorum_min = Some parametric.quorum_min; - quorum_max = Some parametric.quorum_max; - min_proposal_quorum = Some parametric.min_proposal_quorum; - liquidity_baking_subsidy = Some parametric.liquidity_baking_subsidy; - liquidity_baking_sunset_level = - Some parametric.liquidity_baking_sunset_level; - liquidity_baking_escape_ema_threshold = - Some parametric.liquidity_baking_escape_ema_threshold; - max_operations_time_to_live = - Some parametric.max_operations_time_to_live; - minimal_block_delay = Some parametric.minimal_block_delay; - delay_increment_per_round = Some parametric.delay_increment_per_round; - minimal_participation_ratio = - Some parametric.minimal_participation_ratio; - consensus_committee_size = Some parametric.consensus_committee_size; - (* mockup mode does not support endorsing commands *) - consensus_threshold = Some 0; - delegate_selection = Some Random; - max_slashing_period = Some parametric.max_slashing_period; - frozen_deposits_percentage = Some parametric.frozen_deposits_percentage; - double_baking_punishment = Some parametric.double_baking_punishment; - ratio_of_frozen_deposits_slashed_per_double_endorsement = - Some - parametric.ratio_of_frozen_deposits_slashed_per_double_endorsement; - (* Bastard additional parameters. *) - chain_id = to_chain_id_opt cpctxt#chain; - timestamp = Some header.timestamp; - } - - let no_overrides : t = - { - preserved_cycles = None; - blocks_per_cycle = None; - blocks_per_commitment = None; - blocks_per_stake_snapshot = None; - blocks_per_voting_period = None; - hard_gas_limit_per_operation = None; - hard_gas_limit_per_block = None; - proof_of_work_threshold = None; - tokens_per_roll = None; - seed_nonce_revelation_tip = None; - origination_size = None; - baking_reward_fixed_portion = None; - baking_reward_bonus_per_slot = None; - endorsing_reward_per_slot = None; - cost_per_byte = None; - hard_storage_limit_per_operation = None; - quorum_min = None; - quorum_max = None; - min_proposal_quorum = None; - liquidity_baking_subsidy = None; - liquidity_baking_sunset_level = None; - liquidity_baking_escape_ema_threshold = None; - max_operations_time_to_live = None; - minimal_block_delay = None; - delay_increment_per_round = None; - minimal_participation_ratio = None; - consensus_committee_size = None; - (* Let consensus threshold be overridable for Tenderbake mockup - simulator tests. *) - consensus_threshold = None; - delegate_selection = None; - max_slashing_period = None; - frozen_deposits_percentage = None; - double_baking_punishment = None; - ratio_of_frozen_deposits_slashed_per_double_endorsement = None; - chain_id = None; - timestamp = None; - } - - (** Existential wrapper to support heterogeneous lists/maps. *) - type field = - | O : { - name : string; - override_value : 'a option; - pp : Format.formatter -> 'a -> unit; - } - -> field - - let field_pp ppf (O {name; override_value; pp; _}) = - match override_value with - | None -> () - | Some value -> Format.fprintf ppf "@[%s: %a@]" name pp value - - let apply_overrides (cctxt : Tezos_client_base.Client_context.printer) (o : t) - (c : Constants.parametric) : Constants.parametric tzresult Lwt.t = - let open Format in - let pp_print_int32 ppf i = fprintf ppf "%li" i in - let pp_print_int64 ppf i = fprintf ppf "%Li" i in - let fields : field list = - [ - O - { - name = "preserved_cycles"; - override_value = o.preserved_cycles; - pp = pp_print_int; - }; - O - { - name = "blocks_per_cycle"; - override_value = o.blocks_per_cycle; - pp = pp_print_int32; - }; - O - { - name = "blocks_per_commitment"; - override_value = o.blocks_per_commitment; - pp = pp_print_int32; - }; - O - { - name = "blocks_per_stake_snapshot"; - override_value = o.blocks_per_stake_snapshot; - pp = pp_print_int32; - }; - O - { - name = "blocks_per_voting_period"; - override_value = o.blocks_per_voting_period; - pp = pp_print_int32; - }; - O - { - name = "hard_gas_limit_per_operation"; - override_value = o.hard_gas_limit_per_operation; - pp = Gas.Arith.pp_integral; - }; - O - { - name = "hard_gas_limit_per_block"; - override_value = o.hard_gas_limit_per_block; - pp = Gas.Arith.pp_integral; - }; - O - { - name = "proof_of_work_threshold"; - override_value = o.proof_of_work_threshold; - pp = pp_print_int64; - }; - O - { - name = "tokens_per_roll"; - override_value = o.tokens_per_roll; - pp = Tez.pp; - }; - O - { - name = "seed_nonce_revelation_tip"; - override_value = o.seed_nonce_revelation_tip; - pp = Tez.pp; - }; - O - { - name = "origination_size"; - override_value = o.origination_size; - pp = pp_print_int; - }; - O - { - name = "baking_reward_fixed_portion"; - override_value = o.baking_reward_fixed_portion; - pp = Tez.pp; - }; - O - { - name = "baking_reward_bonus_per_slot"; - override_value = o.baking_reward_bonus_per_slot; - pp = Tez.pp; - }; - O - { - name = "endorsing_reward_per_slot"; - override_value = o.endorsing_reward_per_slot; - pp = Tez.pp; - }; - O - { - name = "cost_per_byte"; - override_value = o.cost_per_byte; - pp = Tez.pp; - }; - O - { - name = "hard_storage_limit_per_operation"; - override_value = o.hard_storage_limit_per_operation; - pp = Z.pp_print; - }; - O - { - name = "quorum_min"; - override_value = o.quorum_min; - pp = pp_print_int32; - }; - O - { - name = "quorum_max"; - override_value = o.quorum_max; - pp = pp_print_int32; - }; - O - { - name = "min_proposal_quorum"; - override_value = o.min_proposal_quorum; - pp = pp_print_int32; - }; - O - { - name = "liquidity_baking_subsidy"; - override_value = o.liquidity_baking_subsidy; - pp = Tez.pp; - }; - O - { - name = "liquidity_baking_sunset_level"; - override_value = o.liquidity_baking_sunset_level; - pp = pp_print_int32; - }; - O - { - name = "liquidity_baking_escape_ema_threshold"; - override_value = o.liquidity_baking_escape_ema_threshold; - pp = pp_print_int32; - }; - O - { - name = "minimal_block_delay"; - override_value = o.minimal_block_delay; - pp = Period.pp; - }; - O - { - name = "delay_increment_per_round"; - override_value = o.delay_increment_per_round; - pp = Period.pp; - }; - O - { - name = "minimal_participation_ratio"; - override_value = o.minimal_participation_ratio; - pp = Constants.pp_ratio; - }; - O - { - name = "consensus_committee_size"; - override_value = o.consensus_committee_size; - pp = pp_print_int; - }; - O - { - name = "consensus_threshold"; - override_value = o.consensus_threshold; - pp = pp_print_int; - }; - O - { - name = "max_slashing_period"; - override_value = o.max_slashing_period; - pp = pp_print_int; - }; - O - { - name = "frozen_deposits_percentage"; - override_value = o.frozen_deposits_percentage; - pp = pp_print_int; - }; - O - { - name = "double_baking_punishment"; - override_value = o.double_baking_punishment; - pp = Tez.pp; - }; - O - { - name = "ratio_of_frozen_deposits_slashed_per_double_endorsement"; - override_value = - o.ratio_of_frozen_deposits_slashed_per_double_endorsement; - pp = Constants.pp_ratio; - }; - O {name = "chain_id"; override_value = o.chain_id; pp = Chain_id.pp}; - O - { - name = "timestamp"; - override_value = o.timestamp; - pp = Time.Protocol.pp_hum; - }; - ] - in - let fields_with_override = - fields - |> List.filter (fun (O {override_value; _}) -> - Option.is_some override_value) - in - (if fields_with_override <> [] then - cctxt#message - "@[mockup client uses protocol overrides:@,%a@]@?" - (pp_print_list field_pp) - fields_with_override - else Lwt.return_unit) - >>= fun () -> - return - ({ - minimal_block_delay = - Option.value ~default:c.minimal_block_delay o.minimal_block_delay; - delay_increment_per_round = - Option.value - ~default:c.delay_increment_per_round - o.delay_increment_per_round; - consensus_committee_size = - Option.value - ~default:c.consensus_committee_size - o.consensus_committee_size; - consensus_threshold = - Option.value ~default:c.consensus_threshold o.consensus_threshold; - delegate_selection = - Option.value ~default:c.delegate_selection o.delegate_selection; - preserved_cycles = - Option.value ~default:c.preserved_cycles o.preserved_cycles; - blocks_per_cycle = - Option.value ~default:c.blocks_per_cycle o.blocks_per_cycle; - blocks_per_commitment = - Option.value ~default:c.blocks_per_commitment o.blocks_per_commitment; - blocks_per_stake_snapshot = - Option.value - ~default:c.blocks_per_stake_snapshot - o.blocks_per_stake_snapshot; - blocks_per_voting_period = - Option.value - ~default:c.blocks_per_voting_period - o.blocks_per_voting_period; - hard_gas_limit_per_operation = - Option.value - ~default:c.hard_gas_limit_per_operation - o.hard_gas_limit_per_operation; - hard_gas_limit_per_block = - Option.value - ~default:c.hard_gas_limit_per_block - o.hard_gas_limit_per_block; - proof_of_work_threshold = - Option.value - ~default:c.proof_of_work_threshold - o.proof_of_work_threshold; - tokens_per_roll = - Option.value ~default:c.tokens_per_roll o.tokens_per_roll; - seed_nonce_revelation_tip = - Option.value - ~default:c.seed_nonce_revelation_tip - o.seed_nonce_revelation_tip; - origination_size = - Option.value ~default:c.origination_size o.origination_size; - baking_reward_fixed_portion = - Option.value - ~default:c.baking_reward_fixed_portion - o.baking_reward_fixed_portion; - baking_reward_bonus_per_slot = - Option.value - ~default:c.baking_reward_bonus_per_slot - o.baking_reward_bonus_per_slot; - endorsing_reward_per_slot = - Option.value - ~default:c.endorsing_reward_per_slot - o.endorsing_reward_per_slot; - cost_per_byte = Option.value ~default:c.cost_per_byte o.cost_per_byte; - hard_storage_limit_per_operation = - Option.value - ~default:c.hard_storage_limit_per_operation - o.hard_storage_limit_per_operation; - quorum_min = Option.value ~default:c.quorum_min o.quorum_min; - quorum_max = Option.value ~default:c.quorum_max o.quorum_max; - min_proposal_quorum = - Option.value ~default:c.min_proposal_quorum o.min_proposal_quorum; - liquidity_baking_subsidy = - Option.value - ~default:c.liquidity_baking_subsidy - o.liquidity_baking_subsidy; - liquidity_baking_sunset_level = - Option.value - ~default:c.liquidity_baking_sunset_level - o.liquidity_baking_sunset_level; - liquidity_baking_escape_ema_threshold = - Option.value - ~default:c.liquidity_baking_escape_ema_threshold - o.liquidity_baking_escape_ema_threshold; - max_operations_time_to_live = - Option.value - ~default:c.max_operations_time_to_live - o.max_operations_time_to_live; - minimal_participation_ratio = - Option.value - ~default:c.minimal_participation_ratio - o.minimal_participation_ratio; - max_slashing_period = - Option.value ~default:c.max_slashing_period o.max_slashing_period; - frozen_deposits_percentage = - Option.value - ~default:c.frozen_deposits_percentage - o.frozen_deposits_percentage; - double_baking_punishment = - Option.value - ~default:c.double_baking_punishment - o.double_baking_punishment; - ratio_of_frozen_deposits_slashed_per_double_endorsement = - Option.value - ~default:c.ratio_of_frozen_deposits_slashed_per_double_endorsement - o.ratio_of_frozen_deposits_slashed_per_double_endorsement - (* Notice that the chain_id and the timestamp are not used here - as they are not protocol constants... *); - } - : Constants.parametric) -end - -module Parsed_account = struct - type t = {name : string; sk_uri : Client_keys.sk_uri; amount : Tez.t} - - let pp ppf account = - let open Format in - let format_amount ppf value = fprintf ppf "amount:%a" Tez.pp value in - fprintf - ppf - "@[name:%s@,sk_uri:%s@,%a@]" - account.name - (Uri.to_string (account.sk_uri :> Uri.t)) - format_amount - account.amount - - let encoding = - let open Data_encoding in - conv - (fun p -> (p.name, p.sk_uri, p.amount)) - (fun (name, sk_uri, amount) -> {name; sk_uri; amount}) - (obj3 - (req "name" string) - (req "sk_uri" Client_keys.Secret_key.encoding) - (req "amount" Tez.encoding)) - - let to_bootstrap_account repr = - Tezos_client_base.Client_keys.neuterize repr.sk_uri >>=? fun pk_uri -> - Tezos_client_base.Client_keys.public_key pk_uri >>=? fun public_key -> - let public_key_hash = Signature.Public_key.hash public_key in - return - Parameters. - {public_key_hash; public_key = Some public_key; amount = repr.amount} - - let default_to_json (cctxt : Tezos_client_base.Client_context.full) : - string tzresult Lwt.t = - let rpc_context = new Protocol_client_context.wrap_full cctxt in - let wallet = (cctxt :> Client_context.wallet) in - let parsed_account_reprs = ref [] in - let errors = ref [] in - Client_keys.list_keys wallet >>=? fun all_keys -> - List.iter_s - (function - | (name, pkh, _pk_opt, Some sk_uri) -> ( - let contract = Contract.implicit_contract pkh in - Client_proto_context.get_balance - rpc_context - ~chain:cctxt#chain - ~block:cctxt#block - contract - >>= fun tz_balance -> - match tz_balance with - | Ok balance -> ( - let tez_repr = Tez.of_mutez @@ Tez.to_mutez balance in - match tez_repr with - | None -> - (* we're reading the wallet, it's content MUST be valid *) - assert false - | Some amount -> - parsed_account_reprs := - {name; sk_uri; amount} :: !parsed_account_reprs ; - Lwt.return_unit) - | Error err -> - errors := err :: !errors ; - Lwt.return_unit) - | _ -> Lwt.return_unit) - all_keys - >>= fun () -> - match !errors with - | [] -> - let json = - Data_encoding.Json.construct - (Data_encoding.list encoding) - !parsed_account_reprs - in - return @@ Data_encoding.Json.to_string json - | errs -> Lwt.return_error @@ List.concat errs -end - -module Bootstrap_account = struct - let encoding : Parameters.bootstrap_account Data_encoding.t = - let open Data_encoding in - let open Parameters in - conv - (fun {public_key_hash; public_key; amount} -> - (public_key_hash, public_key, amount)) - (fun (public_key_hash, public_key, amount) -> - {public_key_hash; public_key; amount}) - (obj3 - (req "public_key_hash" Signature.Public_key_hash.encoding) - (opt "public_key" Signature.Public_key.encoding) - (req "amount" Tez.encoding)) -end - -module Bootstrap_contract = struct - let encoding : Parameters.bootstrap_contract Data_encoding.t = - let open Data_encoding in - let open Parameters in - conv - (fun {delegate; amount; script} -> (delegate, amount, script)) - (fun (delegate, amount, script) -> {delegate; amount; script}) - (obj3 - (opt "delegate" Signature.Public_key_hash.encoding) - (req "amount" Tez.encoding) - (req "script" Script.encoding)) -end - -module Protocol_parameters = struct - type t = { - initial_timestamp : Time.Protocol.t; - bootstrap_accounts : Parameters.bootstrap_account list; - bootstrap_contracts : Parameters.bootstrap_contract list; - constants : Constants.parametric; - } - - let encoding : t Data_encoding.t = - let open Data_encoding in - conv - (fun p -> - ( p.initial_timestamp, - p.bootstrap_accounts, - p.bootstrap_contracts, - p.constants )) - (fun ( initial_timestamp, - bootstrap_accounts, - bootstrap_contracts, - constants ) -> - {initial_timestamp; bootstrap_accounts; bootstrap_contracts; constants}) - (obj4 - (req "initial_timestamp" Time.Protocol.encoding) - (req "bootstrap_accounts" (list Bootstrap_account.encoding)) - (req "bootstrap_contracts" (list Bootstrap_contract.encoding)) - (req "constants" Constants.parametric_encoding)) - - let default_value : t = - let parameters = - Default_parameters.parameters_of_constants - Default_parameters.constants_sandbox - in - { - initial_timestamp = Time.Protocol.epoch; - bootstrap_accounts = parameters.bootstrap_accounts; - bootstrap_contracts = parameters.bootstrap_contracts; - constants = parameters.constants; - } -end - -(* This encoding extends [Protocol_constants_overrides.encoding] to allow - reading json files as produced by lib_parameters. Sadly, this require - copying partially [bootstrap_account_encoding], which is not exposed - in parameters_repr.ml. *) -let lib_parameters_json_encoding = - let bootstrap_account_encoding = - let open Data_encoding in - conv - (function - | {Parameters.public_key; amount; _} -> ( - match public_key with - | None -> assert false - | Some pk -> (pk, amount))) - (fun (pk, amount) -> - { - Parameters.public_key = Some pk; - public_key_hash = Signature.Public_key.hash pk; - amount; - }) - (tup2 Signature.Public_key.encoding Tez.encoding) - in - Data_encoding.( - merge_objs - (obj2 - (opt "bootstrap_accounts" (list bootstrap_account_encoding)) - (opt "commitments" (list Commitment.encoding))) - Protocol_constants_overrides.encoding) - -(* ------------------------------------------------------------------------- *) -(* Blocks *) - -type block = { - hash : Block_hash.t; - header : Block_header.t; - operations : Operation.packed list; - context : Protocol.Environment.Context.t; -} - -module Forge = struct - let default_proof_of_work_nonce = - Bytes.create Constants.proof_of_work_nonce_size - - let make_shell ~level ~predecessor ~timestamp ~fitness ~operations_hash = - Tezos_base.Block_header. - { - level; - predecessor; - timestamp; - fitness; - operations_hash; - proto_level = 0; - validation_passes = 0; - context = Context_hash.zero; - } -end - -(* ------------------------------------------------------------------------- *) -(* RPC context *) -let genesis_block_hash = - Block_hash.of_b58check_exn - "BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU" - -let endorsement_branch_data_encoding = - let open Data_encoding in - conv - (fun (block_hash, block_payload_hash) -> (block_hash, block_payload_hash)) - (fun (block_hash, block_payload_hash) -> (block_hash, block_payload_hash)) - (obj2 - (req "block_hash" Block_hash.encoding) - (req "block_payload_hash" Protocol.Block_payload_hash.encoding)) - -let initial_context chain_id (header : Block_header.shell_header) - ({bootstrap_accounts; bootstrap_contracts; constants; _} : - Protocol_parameters.t) = - let parameters = - Default_parameters.parameters_of_constants - ~bootstrap_accounts - ~bootstrap_contracts - ~commitments:[] - constants - in - let json = Default_parameters.json_of_parameters parameters in - let proto_params = - Data_encoding.Binary.to_bytes_exn Data_encoding.json json - in - Tezos_protocol_environment.Context.( - let empty = Memory_context.empty in - add empty ["version"] (Bytes.of_string "genesis") >>= fun ctxt -> - add ctxt ["protocol_parameters"] proto_params) - >>= fun ctxt -> - Protocol.Main.init ctxt header >|= Protocol.Environment.wrap_tzresult - >>=? fun {context; _} -> - let ({ - timestamp = predecessor_timestamp; - level = predecessor_level; - fitness = predecessor_fitness; - _; - } - : Block_header.shell_header) = - header - in - let timestamp = - Time.System.to_protocol (Tezos_stdlib_unix.Systime_os.now ()) - in - (* - - We need to forge a predecessor hash to pass it to [value_of_key]. - This initial context is used for RPC, hence this piece of - information is not important and does not have to be meaningful - - *) - let predecessor = - Tezos_base.Block_header.hash {shell = header; protocol_data = Bytes.empty} - in - Protocol.Main.value_of_key - ~chain_id - ~predecessor_context:context - ~predecessor_timestamp - ~predecessor_level - ~predecessor_fitness - ~predecessor - ~timestamp - >|= Protocol.Environment.wrap_tzresult - >>=? fun value_of_key -> - (* - In the mockup mode, reactivity is important and there are - no constraints to be consistent with other nodes. For this - reason, the mockup mode loads the cache lazily. - See {!Environment_context.source_of_cache}. - *) - Tezos_protocol_environment.Context.load_cache - predecessor - context - `Lazy - (fun key -> value_of_key key >|= Protocol.Environment.wrap_tzresult) - >>=? fun context -> return context - -let mem_init : - cctxt:Tezos_client_base.Client_context.printer -> - parameters:Protocol_parameters.t -> - constants_overrides_json:Data_encoding.json option -> - bootstrap_accounts_json:Data_encoding.json option -> - Tezos_mockup_registration.Registration.mockup_context tzresult Lwt.t = - fun ~cctxt ~parameters ~constants_overrides_json ~bootstrap_accounts_json -> - let hash = genesis_block_hash in - (* Need to read this Json file before since timestamp modification may be in - there *) - (match constants_overrides_json with - | None -> return Protocol_constants_overrides.no_overrides - | Some json -> ( - match Data_encoding.Json.destruct lib_parameters_json_encoding json with - | (_, x) -> return x - | exception error -> - failwith - "cannot read protocol constants overrides: %a" - (Data_encoding.Json.print_error ?print_unknown:None) - error)) - >>=? fun protocol_overrides -> - let default = parameters.initial_timestamp in - let timestamp = Option.value ~default protocol_overrides.timestamp in - (if not @@ Time.Protocol.equal default timestamp then - cctxt#message "@[initial_timestamp: %a@]" Time.Protocol.pp_hum timestamp - else Lwt.return_unit) - >>= fun () -> - let fitness = - Protocol.Alpha_context.( - Fitness.create_without_locked_round - ~level:Raw_level.root - ~predecessor_round:Round.zero - ~round:Round.zero - |> Fitness.to_raw) - in - let shell_header = - Forge.make_shell - ~level:0l - ~predecessor:hash - ~timestamp - ~fitness - ~operations_hash:Operation_list_list_hash.zero - in - Protocol_constants_overrides.apply_overrides - (cctxt :> Tezos_client_base.Client_context.printer) - protocol_overrides - parameters.constants - >>=? fun protocol_custom -> - (match bootstrap_accounts_json with - | None -> return None - | Some json -> ( - match - Data_encoding.Json.destruct - (Data_encoding.list Parsed_account.encoding) - json - with - | accounts -> - cctxt#message "@[mockup client uses custom bootstrap accounts:@]" - >>= fun () -> - let open Format in - cctxt#message - "@[%a@]" - (pp_print_list - ~pp_sep:(fun ppf () -> fprintf ppf ";@ ") - Parsed_account.pp) - accounts - >>= fun () -> - List.map_es Parsed_account.to_bootstrap_account accounts - >>=? fun bootstrap_accounts -> return (Some bootstrap_accounts) - | exception error -> - failwith - "cannot read definitions of bootstrap accounts: %a" - (Data_encoding.Json.print_error ?print_unknown:None) - error)) - >>=? fun bootstrap_accounts_custom -> - let chain_id = - Tezos_mockup_registration.Mockup_args.Chain_id.choose - ~from_config_file:protocol_overrides.chain_id - in - initial_context - chain_id - shell_header - { - parameters with - bootstrap_accounts = - Option.value - ~default:parameters.bootstrap_accounts - bootstrap_accounts_custom; - constants = protocol_custom; - } - >>=? fun context -> - let chain_id = - Tezos_mockup_registration.Mockup_args.Chain_id.choose - ~from_config_file:protocol_overrides.chain_id - in - let protocol_data = - let payload_hash = - Protocol.Block_payload_hash.hash_bytes - [Block_hash.to_bytes hash; Operation_list_hash.(to_bytes @@ compute [])] - in - let open Protocol.Alpha_context.Block_header in - let (_, _, sk) = Signature.generate_key () in - let proof_of_work_nonce = - Bytes.create Protocol.Alpha_context.Constants.proof_of_work_nonce_size - in - let contents = - { - payload_round = Round.zero; - payload_hash; - seed_nonce_hash = None; - proof_of_work_nonce; - (* following Baking_configuration.escape_votes in lib_delegate *) - liquidity_baking_escape_vote = false; - } - in - let unsigned_bytes = - Data_encoding.Binary.to_bytes_exn - Block_header.unsigned_encoding - (shell_header, contents) - in - let signature = - Signature.sign - ~watermark: - Protocol.Alpha_context.Block_header.( - to_watermark (Block_header chain_id)) - sk - unsigned_bytes - in - Data_encoding.Binary.to_bytes_exn - Protocol.block_header_data_encoding - {contents; signature} - in - return - Tezos_mockup_registration.Registration_intf. - { - chain = chain_id; - rpc_context = - Tezos_protocol_environment. - {block_hash = hash; block_header = shell_header; context}; - protocol_data; - } - -let migrate : - Tezos_mockup_registration.Registration.mockup_context -> - Tezos_mockup_registration.Registration.mockup_context tzresult Lwt.t = - fun {chain; rpc_context; protocol_data} -> - let Tezos_protocol_environment.{block_hash; context; block_header} = - rpc_context - in - Protocol.Main.init context block_header >|= Protocol.Environment.wrap_tzresult - >>=? fun {context; _} -> - let rpc_context = - Tezos_protocol_environment.{block_hash; block_header; context} - in - return - Tezos_mockup_registration.Registration_intf. - {chain; rpc_context; protocol_data} - -(* ------------------------------------------------------------------------- *) -(* Register mockup *) - -module M : - Tezos_mockup_registration.Registration_intf.MOCKUP - with module Protocol = Protocol_client_context.Lifted_protocol = struct - type parameters = Protocol_parameters.t - - type protocol_constants = Protocol_constants_overrides.t - - let parameters_encoding = Protocol_parameters.encoding - - let default_parameters = Protocol_parameters.default_value - - let protocol_constants_encoding = Protocol_constants_overrides.encoding - - let default_protocol_constants = Protocol_constants_overrides.default_value - - let default_bootstrap_accounts = Parsed_account.default_to_json - - let protocol_hash = Protocol.hash - - module Protocol = Protocol_client_context.Lifted_protocol - module Block_services = Protocol_client_context.Alpha_block_services - - let directory = Plugin.RPC.rpc_services - - let init ~cctxt ~parameters ~constants_overrides_json ~bootstrap_accounts_json - = - mem_init - ~cctxt:(cctxt :> Tezos_client_base.Client_context.printer) - ~parameters - ~constants_overrides_json - ~bootstrap_accounts_json - - let migrate = migrate -end - -let () = - Tezos_mockup_registration.Registration.register_mockup_environment (module M) diff --git a/src/proto_012_Psithaca/lib_client/operation_result.ml b/src/proto_012_Psithaca/lib_client/operation_result.ml deleted file mode 100644 index af99cf5b7e9b..000000000000 --- a/src/proto_012_Psithaca/lib_client/operation_result.ml +++ /dev/null @@ -1,666 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Apply_results - -let pp_manager_operation_content (type kind) source internal pp_result ppf - ((operation, result) : kind manager_operation * _) = - Format.fprintf ppf "@[" ; - (match operation with - | Transaction {destination; amount; parameters; entrypoint} -> - Format.fprintf - ppf - "@[%s:@,Amount: %s%a@,From: %a@,To: %a" - (if internal then "Internal transaction" else "Transaction") - Client_proto_args.tez_sym - Tez.pp - amount - Contract.pp - source - Contract.pp - destination ; - (match entrypoint with - | "default" -> () - | _ -> Format.fprintf ppf "@,Entrypoint: %s" entrypoint) ; - (if not (Script_repr.is_unit_parameter parameters) then - let expr = - WithExceptions.Option.to_exn - ~none:(Failure "ill-serialized argument") - (Data_encoding.force_decode parameters) - in - Format.fprintf - ppf - "@,Parameter: @[%a@]" - Michelson_v1_printer.print_expr - expr) ; - pp_result ppf result ; - Format.fprintf ppf "@]" - | Origination {delegate; credit; script = {code; storage}; preorigination = _} - -> - Format.fprintf - ppf - "@[%s:@,From: %a@,Credit: %s%a" - (if internal then "Internal origination" else "Origination") - Contract.pp - source - Client_proto_args.tez_sym - Tez.pp - credit ; - let code = - WithExceptions.Option.to_exn - ~none:(Failure "ill-serialized code") - (Data_encoding.force_decode code) - and storage = - WithExceptions.Option.to_exn - ~none:(Failure "ill-serialized storage") - (Data_encoding.force_decode storage) - in - let {Michelson_v1_parser.source; _} = - Michelson_v1_printer.unparse_toplevel code - in - Format.fprintf - ppf - "@,@[Script:@ @[%a@]@,@[Initial storage:@ %a@]" - Format.pp_print_text - source - Michelson_v1_printer.print_expr - storage ; - (match delegate with - | None -> Format.fprintf ppf "@,No delegate for this contract" - | Some delegate -> - Format.fprintf - ppf - "@,Delegate: %a" - Signature.Public_key_hash.pp - delegate) ; - pp_result ppf result ; - Format.fprintf ppf "@]" - | Reveal key -> - Format.fprintf - ppf - "@[%s of manager public key:@,Contract: %a@,Key: %a%a@]" - (if internal then "Internal revelation" else "Revelation") - Contract.pp - source - Signature.Public_key.pp - key - pp_result - result - | Delegation None -> - Format.fprintf - ppf - "@[%s:@,Contract: %a@,To: nobody%a@]" - (if internal then "Internal Delegation" else "Delegation") - Contract.pp - source - pp_result - result - | Delegation (Some delegate) -> - Format.fprintf - ppf - "@[%s:@,Contract: %a@,To: %a%a@]" - (if internal then "Internal Delegation" else "Delegation") - Contract.pp - source - Signature.Public_key_hash.pp - delegate - pp_result - result - | Register_global_constant {value = lazy_value} -> - let value = - WithExceptions.Option.to_exn - ~none:(Failure "ill-serialized value") - (Data_encoding.force_decode lazy_value) - in - Format.fprintf - ppf - "Register Global:@,@[ Value: %a%a@]" - Michelson_v1_printer.print_expr - value - pp_result - result - | Set_deposits_limit None -> - Format.fprintf - ppf - "@[%s:@,Delegate: %a@,Unlimited deposits%a@]" - (if internal then "Internal set deposits limit" - else "Set deposits limit") - Contract.pp - source - pp_result - result - | Set_deposits_limit (Some limit) -> - Format.fprintf - ppf - "@[%s:@,Delegate: %a@,Limit: %a%a@]" - (if internal then "Internal set deposits limit" - else "Set deposits limit") - Contract.pp - source - Tez.pp - limit - pp_result - result) ; - Format.fprintf ppf "@]" - -let pp_balance_updates ppf = function - | [] -> () - | balance_updates -> - let open Receipt in - (* For dry runs, the baker's key is zero - (tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU). Instead of printing this - key hash, we want to make the result more informative. *) - let pp_baker ppf baker = - if Signature.Public_key_hash.equal baker Signature.Public_key_hash.zero - then Format.fprintf ppf "the baker who will include this operation" - else Signature.Public_key_hash.pp ppf baker - in - let balance_updates = - List.map - (fun (balance, update, origin) -> - let balance = - match balance with - | Contract c -> Format.asprintf "%a" Contract.pp c - | Legacy_rewards (pkh, l) -> - Format.asprintf - "legacy_rewards(%a,%a)" - pp_baker - pkh - Cycle.pp - l - | Block_fees -> "payload fees(the block proposer)" - | Legacy_deposits (pkh, l) -> - Format.asprintf - "legacy_deposits(%a,%a)" - pp_baker - pkh - Cycle.pp - l - | Deposits pkh -> Format.asprintf "deposits(%a)" pp_baker pkh - | Nonce_revelation_rewards -> "nonce revelation rewards" - | Double_signing_evidence_rewards -> - "double signing evidence rewards" - | Endorsing_rewards -> "endorsing rewards" - | Baking_rewards -> "baking rewards" - | Baking_bonuses -> "baking bonuses" - | Legacy_fees (pkh, c) -> - Format.asprintf "legacy_fees(%a,%a)" pp_baker pkh Cycle.pp c - | Storage_fees -> "storage fees" - | Double_signing_punishments -> "double signing punishments" - | Lost_endorsing_rewards (pkh, p, r) -> - let reason = - match (p, r) with - | (false, false) -> "" - | (false, true) -> ",revelation" - | (true, false) -> ",participation" - | (true, true) -> ",participation,revelation" - in - Format.asprintf - "lost endorsing rewards(%a%s)" - pp_baker - pkh - reason - | Liquidity_baking_subsidies -> "liquidity baking subsidies" - | Burned -> "burned" - | Commitments bpkh -> - Format.asprintf - "commitment(%a)" - Blinded_public_key_hash.pp - bpkh - | Bootstrap -> "bootstrap" - | Invoice -> "invoices" - | Initial_commitments -> "initial commitments" - | Minted -> "minted" - in - let balance = - match origin with - | Block_application -> balance - | Protocol_migration -> Format.asprintf "migration %s" balance - | Subsidy -> Format.asprintf "subsidy %s" balance - | Simulation -> Format.asprintf "simulation %s" balance - in - (balance, update)) - balance_updates - in - let column_size = - List.fold_left - (fun acc (balance, _) -> Compare.Int.max acc (String.length balance)) - 0 - balance_updates - in - let pp_update ppf = function - | Credited amount -> - Format.fprintf ppf "+%s%a" Client_proto_args.tez_sym Tez.pp amount - | Debited amount -> - Format.fprintf ppf "-%s%a" Client_proto_args.tez_sym Tez.pp amount - in - let pp_one ppf (balance, update) = - let to_fill = column_size + 3 - String.length balance in - let filler = String.make to_fill '.' in - Format.fprintf ppf "%s %s %a" balance filler pp_update update - in - Format.fprintf - ppf - "@[%a@]" - (Format.pp_print_list pp_one) - balance_updates - -let pp_manager_operation_contents_and_result ppf - ( Manager_operation - {source; fee; operation; counter; gas_limit; storage_limit}, - Manager_operation_result - {balance_updates; operation_result; internal_operation_results} ) = - let pp_lazy_storage_diff = function - | None -> () - | Some lazy_storage_diff -> ( - let big_map_diff = - Contract.Legacy_big_map_diff.of_lazy_storage_diff lazy_storage_diff - in - match (big_map_diff :> Contract.Legacy_big_map_diff.item list) with - | [] -> () - | _ :: _ -> - (* TODO: print all lazy storage diff *) - Format.fprintf - ppf - "@,@[Updated big_maps:@ %a@]" - Michelson_v1_printer.print_big_map_diff - lazy_storage_diff) - in - let pp_transaction_result - (Transaction_result - { - balance_updates; - consumed_gas; - storage; - originated_contracts; - storage_size; - paid_storage_size_diff; - lazy_storage_diff; - allocated_destination_contract = _; - }) = - (match originated_contracts with - | [] -> () - | contracts -> - Format.fprintf - ppf - "@,@[Originated contracts:@,%a@]" - (Format.pp_print_list Contract.pp) - contracts) ; - (match storage with - | None -> () - | Some expr -> - Format.fprintf - ppf - "@,@[Updated storage:@ %a@]" - Michelson_v1_printer.print_expr - expr) ; - pp_lazy_storage_diff lazy_storage_diff ; - if storage_size <> Z.zero then - Format.fprintf ppf "@,Storage size: %s bytes" (Z.to_string storage_size) ; - if paid_storage_size_diff <> Z.zero then - Format.fprintf - ppf - "@,Paid storage size diff: %s bytes" - (Z.to_string paid_storage_size_diff) ; - Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas ; - match balance_updates with - | [] -> () - | balance_updates -> - Format.fprintf - ppf - "@,Balance updates:@, %a" - pp_balance_updates - balance_updates - in - let pp_origination_result - (Origination_result - { - lazy_storage_diff; - balance_updates; - consumed_gas; - originated_contracts; - storage_size; - paid_storage_size_diff; - }) = - (match originated_contracts with - | [] -> () - | contracts -> - Format.fprintf - ppf - "@,@[Originated contracts:@,%a@]" - (Format.pp_print_list Contract.pp) - contracts) ; - if storage_size <> Z.zero then - Format.fprintf ppf "@,Storage size: %s bytes" (Z.to_string storage_size) ; - pp_lazy_storage_diff lazy_storage_diff ; - if paid_storage_size_diff <> Z.zero then - Format.fprintf - ppf - "@,Paid storage size diff: %s bytes" - (Z.to_string paid_storage_size_diff) ; - Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas ; - match balance_updates with - | [] -> () - | balance_updates -> - Format.fprintf - ppf - "@,Balance updates:@, %a" - pp_balance_updates - balance_updates - in - let pp_register_global_constant_result - (Register_global_constant_result - {balance_updates; consumed_gas; size_of_constant; global_address}) = - (match balance_updates with - | [] -> - (* Not possible - register global constant operation always returns - balance updates. *) - assert false - | balance_updates -> - Format.fprintf - ppf - "@,Balance updates:@, %a" - pp_balance_updates - balance_updates) ; - Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas ; - Format.fprintf ppf "@,Storage size: %s bytes" (Z.to_string size_of_constant) ; - Format.fprintf ppf "@,Global address: %a" Script_expr_hash.pp global_address - in - let pp_result (type kind) ppf (result : kind manager_operation_result) = - Format.fprintf ppf "@," ; - match result with - | Skipped _ -> Format.fprintf ppf "This operation was skipped" - | Failed (_, _errs) -> Format.fprintf ppf "This operation FAILED." - | Applied (Reveal_result {consumed_gas}) -> - Format.fprintf ppf "This revelation was successfully applied" ; - Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas - | Backtracked (Reveal_result _, _) -> - Format.fprintf - ppf - "@[This revelation was BACKTRACKED, its expected effects were \ - NOT applied.@]" - | Applied (Delegation_result {consumed_gas}) -> - Format.fprintf ppf "This delegation was successfully applied" ; - Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas - | Backtracked (Delegation_result _, _) -> - Format.fprintf - ppf - "@[This delegation was BACKTRACKED, its expected effects were \ - NOT applied.@]" - | Applied (Set_deposits_limit_result {consumed_gas}) -> - Format.fprintf ppf "The deposits limit was successfully set" ; - Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas - | Backtracked (Set_deposits_limit_result _, _) -> - Format.fprintf - ppf - "@[This deposits limit modification was BACKTRACKED, its \ - expected effects were NOT applied.@]" - | Applied (Transaction_result _ as tx) -> - Format.fprintf ppf "This transaction was successfully applied" ; - pp_transaction_result tx - | Backtracked ((Transaction_result _ as tx), _errs) -> - Format.fprintf - ppf - "@[This transaction was BACKTRACKED, its expected effects (as \ - follow) were NOT applied.@]" ; - pp_transaction_result tx - | Applied (Origination_result _ as op) -> - Format.fprintf ppf "This origination was successfully applied" ; - pp_origination_result op - | Backtracked ((Origination_result _ as op), _errs) -> - Format.fprintf - ppf - "@[This origination was BACKTRACKED, its expected effects (as \ - follow) were NOT applied.@]" ; - pp_origination_result op - | Applied (Register_global_constant_result _ as op) -> - Format.fprintf - ppf - "This global constant registration was successfully applied" ; - pp_register_global_constant_result op - | Backtracked ((Register_global_constant_result _ as op), _errs) -> - Format.fprintf - ppf - "@[This registration of a global constant was BACKTRACKED, its \ - expected effects (as follow) were NOT applied.@]" ; - pp_register_global_constant_result op - in - Format.fprintf - ppf - "@[@[Manager signed operations:@,\ - From: %a@,\ - Fee to the baker: %s%a@,\ - Expected counter: %s@,\ - Gas limit: %a@,\ - Storage limit: %s bytes" - Signature.Public_key_hash.pp - source - Client_proto_args.tez_sym - Tez.pp - fee - (Z.to_string counter) - Gas.Arith.pp_integral - gas_limit - (Z.to_string storage_limit) ; - (match balance_updates with - | [] -> () - | balance_updates -> - Format.fprintf - ppf - "@,Balance updates:@, %a" - pp_balance_updates - balance_updates) ; - Format.fprintf - ppf - "@,%a" - (pp_manager_operation_content - (Contract.implicit_contract source) - false - pp_result) - (operation, operation_result) ; - (match internal_operation_results with - | [] -> () - | _ :: _ -> - Format.fprintf - ppf - "@,@[Internal operations:@ %a@]" - (Format.pp_print_list (fun ppf (Internal_operation_result (op, res)) -> - pp_manager_operation_content - op.source - false - pp_result - ppf - (op.operation, res))) - internal_operation_results) ; - Format.fprintf ppf "@]" - -let rec pp_contents_and_result_list : - type kind. Format.formatter -> kind contents_and_result_list -> unit = - fun ppf -> function - | Single_and_result - (Seed_nonce_revelation {level; nonce}, Seed_nonce_revelation_result bus) - -> - Format.fprintf - ppf - "@[Seed nonce revelation:@,\ - Level: %a@,\ - Nonce (hash): %a@,\ - Balance updates:@,\ - %a@]" - Raw_level.pp - level - Nonce_hash.pp - (Nonce.hash nonce) - pp_balance_updates - bus - | Single_and_result - (Double_baking_evidence {bh1; bh2}, Double_baking_evidence_result bus) -> - Format.fprintf - ppf - "@[Double baking evidence:@,\ - Exhibit A: %a@,\ - Exhibit B: %a@,\ - Balance updates:@,\ - %a@]" - Block_hash.pp - (Block_header.hash bh1) - Block_hash.pp - (Block_header.hash bh2) - pp_balance_updates - bus - | Single_and_result - ( Preendorsement {level; _}, - Preendorsement_result {balance_updates; delegate; preendorsement_power} - ) -> - Format.fprintf - ppf - "@[Preendorsement:@,\ - Level: %a@,\ - Balance updates:%a@,\ - Delegate: %a@,\ - Preendorsement Power: %d@]" - Raw_level.pp - level - pp_balance_updates - balance_updates - Signature.Public_key_hash.pp - delegate - preendorsement_power - | Single_and_result - ( Endorsement {level; _}, - Endorsement_result {balance_updates; delegate; endorsement_power} ) -> - Format.fprintf - ppf - "@[Endorsement:@,\ - Level: %a@,\ - Balance updates:%a@,\ - Delegate: %a@,\ - Endorsement power: %d@]" - Raw_level.pp - level - pp_balance_updates - balance_updates - Signature.Public_key_hash.pp - delegate - endorsement_power - | Single_and_result - ( Double_endorsement_evidence {op1; op2}, - Double_endorsement_evidence_result bus ) -> - Format.fprintf - ppf - "@[Double endorsement evidence:@,\ - Exhibit A: %a@,\ - Exhibit B: %a@,\ - Balance updates:@,\ - \ %a@]" - Operation_hash.pp - (Operation.hash op1) - Operation_hash.pp - (Operation.hash op2) - pp_balance_updates - bus - | Single_and_result - ( Double_preendorsement_evidence {op1; op2}, - Double_preendorsement_evidence_result bus ) -> - Format.fprintf - ppf - "@[Double preendorsement evidence:@,\ - Exhibit A: %a@,\ - Exhibit B: %a@,\ - Balance updates:@,\ - \ %a@]" - Operation_hash.pp - (Operation.hash op1) - Operation_hash.pp - (Operation.hash op2) - pp_balance_updates - bus - | Single_and_result (Activate_account {id; _}, Activate_account_result bus) -> - Format.fprintf - ppf - "@[Genesis account activation:@,\ - Account: %a@,\ - Balance updates:@,\ - \ %a@]" - Ed25519.Public_key_hash.pp - id - pp_balance_updates - bus - | Single_and_result (Proposals {source; period; proposals}, Proposals_result) - -> - Format.fprintf - ppf - "@[Proposals:@,From: %a@,Period: %ld@,Protocols:@, @[%a@]@]" - Signature.Public_key_hash.pp - source - period - (Format.pp_print_list Protocol_hash.pp) - proposals - | Single_and_result (Ballot {source; period; proposal; ballot}, Ballot_result) - -> - Format.fprintf - ppf - "@[Ballot:@,From: %a@,Period: %ld@,Protocol: %a@,Vote: %a@]" - Signature.Public_key_hash.pp - source - period - Protocol_hash.pp - proposal - Data_encoding.Json.pp - (Data_encoding.Json.construct Vote.ballot_encoding ballot) - | Single_and_result (Failing_noop _arbitrary, _) -> - (* the Failing_noop operation always fails and can't have result *) - . - | Single_and_result - ((Manager_operation _ as op), (Manager_operation_result _ as res)) -> - Format.fprintf ppf "%a" pp_manager_operation_contents_and_result (op, res) - | Cons_and_result - ((Manager_operation _ as op), (Manager_operation_result _ as res), rest) - -> - Format.fprintf - ppf - "%a@\n%a" - pp_manager_operation_contents_and_result - (op, res) - pp_contents_and_result_list - rest - -let pp_operation_result ppf - ((op, res) : 'kind contents_list * 'kind contents_result_list) = - Format.fprintf ppf "@[" ; - let contents_and_result_list = Apply_results.pack_contents_list op res in - pp_contents_and_result_list ppf contents_and_result_list ; - Format.fprintf ppf "@]@." - -let pp_internal_operation ppf - (Internal_operation {source; operation; nonce = _}) = - pp_manager_operation_content - source - true - (fun _ppf () -> ()) - ppf - (operation, ()) diff --git a/src/proto_012_Psithaca/lib_client/operation_result.mli b/src/proto_012_Psithaca/lib_client/operation_result.mli deleted file mode 100644 index cc03abfcd36b..000000000000 --- a/src/proto_012_Psithaca/lib_client/operation_result.mli +++ /dev/null @@ -1,35 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -val pp_internal_operation : - Format.formatter -> packed_internal_operation -> unit - -val pp_operation_result : - Format.formatter -> - 'kind contents_list * 'kind Apply_results.contents_result_list -> - unit diff --git a/src/proto_012_Psithaca/lib_client/protocol_client_context.ml b/src/proto_012_Psithaca/lib_client/protocol_client_context.ml deleted file mode 100644 index 1d2fc145eeb6..000000000000 --- a/src/proto_012_Psithaca/lib_client/protocol_client_context.ml +++ /dev/null @@ -1,272 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Lifted_protocol = struct - include Protocol.Environment.Lift (Protocol) - - let hash = Protocol.hash -end - -module Alpha_block_services = - Block_services.Make (Lifted_protocol) (Lifted_protocol) - -(** Client RPC context *) -class type rpc_context = - object - inherit RPC_context.json - - inherit - [Shell_services.chain * Shell_services.block] Protocol.Environment - .RPC_context - .simple - end - -(** The class [wrap_rpc_context] is a wrapper class used by the proxy - mode clients. From a general-purpose RPC_context.json [t], the - class is augmented with shell services to provide RPC calls that - are protocol-dependent. *) -class wrap_rpc_context (t : RPC_context.json) : rpc_context = - object - method base : Uri.t = t#base - - method generic_json_call = t#generic_json_call - - method generic_media_type_call = t#generic_media_type_call - - method call_service - : 'm 'p 'q 'i 'o. - (([< Resto.meth] as 'm), unit, 'p, 'q, 'i, 'o) RPC_service.t -> - 'p -> - 'q -> - 'i -> - 'o tzresult Lwt.t = - t#call_service - - method call_streamed_service - : 'm 'p 'q 'i 'o. - (([< Resto.meth] as 'm), unit, 'p, 'q, 'i, 'o) RPC_service.t -> - on_chunk:('o -> unit) -> - on_close:(unit -> unit) -> - 'p -> - 'q -> - 'i -> - (unit -> unit) tzresult Lwt.t = - t#call_streamed_service - - (** Abstracts variables and in protocol RPCs - prefixed by "/chains//blocks//...". *) - inherit - [Shell_services.chain, Shell_services.block] Protocol.Environment - .proto_rpc_context - (t :> RPC_context.t) - Shell_services.Blocks.path - end - -(** The class type [full] allows to create contexts that are - explicitly used by low-level shell functions, while containing - various information (I/O services, RPCs...). Then, depending on the - usage, the type may be coerced into one of its following ascendants - to serve for explicit operations on blocks, chain or daemon for - instance. *) -class type full = - object - (** The class Client_context.full provides I/O services for the - client, the wallet, etc. *) - inherit Client_context.full - - (** Base interface provided to call RPCs, i.e., communication - with the node. A client context is defined by mapping all - RPCs protocol-generic to a specific procotol. *) - inherit - [Shell_services.chain * Shell_services.block] Protocol.Environment - .RPC_context - .simple - - (** Protocol RPCs exposed through the environment (using - an additional chainpath). *) - inherit - [Shell_services.chain, Shell_services.block] Protocol.Environment - .proto_rpc_context - end - -(** From a [Client_context.full], the class allows to call RPCs from - the node and those defined by the protocol. *) -class wrap_full (t : Client_context.full) : full = - object - inherit Client_context.proxy_context t - - inherit - [Shell_services.chain, Shell_services.block] Protocol.Environment - .proto_rpc_context - (t :> RPC_context.t) - Shell_services.Blocks.path - end - -let register_error_kind category ~id ~title ~description ?pp encoding from_error - to_error = - let id = "client." ^ Protocol.name ^ "." ^ id in - register_error_kind - category - ~id - ~title - ~description - ?pp - encoding - from_error - to_error - -(** Initialization calls that run on start-up. Register the various - protocol encodings. *) -let () = - let open Data_encoding.Registration in - register Protocol.Alpha_context.Lazy_storage.encoding ; - register ~pp:Protocol.Alpha_context.Fitness.pp - @@ Protocol.Alpha_context.Fitness.encoding ; - (* These encodings are missing a def field which we add before registering them. - These defs should be moved inside their encodings in the protocol code. *) - let def id ids ?title ?description encoding = - Data_encoding.def - (String.concat "." (Protocol.name :: id :: ids)) - ?title - ?description - encoding - in - register @@ def "parameters" [] Protocol.Parameters_repr.encoding ; - register ~pp:Protocol.Alpha_context.Tez.pp - @@ def "tez" [] Protocol.Alpha_context.Tez.encoding ; - register ~pp:Protocol.Alpha_context.Timestamp.pp - @@ def "timestamp" [] Protocol.Alpha_context.Timestamp.encoding ; - register ~pp:Protocol.Alpha_context.Raw_level.pp - @@ def "raw_level" [] Protocol.Alpha_context.Raw_level.encoding ; - register @@ def "vote" ["ballot"] Protocol.Alpha_context.Vote.ballot_encoding ; - register - @@ def "vote" ["ballots"] Protocol.Alpha_context.Vote.ballots_encoding ; - register - @@ def "vote" ["listings"] Protocol.Alpha_context.Vote.listings_encoding ; - register @@ def "seed" [] Protocol.Alpha_context.Seed.seed_encoding ; - register ~pp:Protocol.Alpha_context.Gas.pp - @@ def "gas" [] Protocol.Alpha_context.Gas.encoding ; - register ~pp:Protocol.Alpha_context.Gas.pp_cost - @@ def "gas" ["cost"] Protocol.Alpha_context.Gas.cost_encoding ; - register @@ def "script" [] Protocol.Alpha_context.Script.encoding ; - register @@ def "script" ["expr"] Protocol.Alpha_context.Script.expr_encoding ; - register @@ def "script" ["prim"] Protocol.Alpha_context.Script.prim_encoding ; - register - @@ def "script" ["lazy_expr"] Protocol.Alpha_context.Script.lazy_expr_encoding ; - register - @@ def "script" ["loc"] Protocol.Alpha_context.Script.location_encoding ; - register ~pp:Protocol.Alpha_context.Contract.pp - @@ def "contract" [] Protocol.Alpha_context.Contract.encoding ; - register - @@ def - "contract" - ["big_map_diff"] - Protocol.Alpha_context.Lazy_storage.legacy_big_map_diff_encoding ; - register - @@ def - "receipt" - ["balance_updates"] - Protocol.Alpha_context.Receipt.balance_updates_encoding ; - register ~pp:Protocol.Alpha_context.Level.pp_full - @@ def "level" [] Protocol.Alpha_context.Level.encoding ; - register @@ def "operation" [] Protocol.Alpha_context.Operation.encoding ; - register - @@ def - "operation" - ["contents"] - Protocol.Alpha_context.Operation.contents_encoding ; - register - @@ def - "operation" - ["contents_list"] - Protocol.Alpha_context.Operation.contents_list_encoding ; - register - @@ def - "operation" - ["protocol_data"] - Protocol.Alpha_context.Operation.protocol_data_encoding ; - register - @@ def "operation" ["raw"] Protocol.Alpha_context.Operation.raw_encoding ; - register - @@ def - "operation" - ["internal"] - Protocol.Alpha_context.Operation.internal_operation_encoding ; - register - @@ def - "operation" - ["unsigned"] - Protocol.Alpha_context.Operation.unsigned_encoding ; - register ~pp:Protocol.Alpha_context.Period.pp - @@ def "period" [] Protocol.Alpha_context.Period.encoding ; - register ~pp:Protocol.Alpha_context.Cycle.pp - @@ def "cycle" [] Protocol.Alpha_context.Cycle.encoding ; - register @@ def "constants" [] Protocol.Alpha_context.Constants.encoding ; - register - @@ def "constants" ["fixed"] Protocol.Alpha_context.Constants.fixed_encoding ; - register - @@ def - "constants" - ["parametric"] - Protocol.Alpha_context.Constants.parametric_encoding ; - register @@ def "nonce" [] Protocol.Alpha_context.Nonce.encoding ; - register @@ def "block_header" [] Protocol.Alpha_context.Block_header.encoding ; - register - @@ def - "block_header" - ["unsigned"] - Protocol.Alpha_context.Block_header.unsigned_encoding ; - register - @@ def "block_header" ["raw"] Protocol.Alpha_context.Block_header.raw_encoding ; - register - @@ def - "block_header" - ["contents"] - Protocol.Alpha_context.Block_header.contents_encoding ; - register - @@ def - "block_header" - ["shell_header"] - Protocol.Alpha_context.Block_header.shell_header_encoding ; - register - @@ def - "block_header" - ["protocol_data"] - Protocol.Alpha_context.Block_header.protocol_data_encoding ; - register ~pp:Protocol.Alpha_context.Voting_period.pp - @@ def "voting_period" [] Protocol.Alpha_context.Voting_period.encoding ; - register - @@ def - "voting_period" - ["kind"] - Protocol.Alpha_context.Voting_period.kind_encoding ; - register - @@ def - "errors" - [] - ~description: - "The full list of RPC errors would be too long to include.It is\n\ - available through the RPC `/errors` (GET)." - error_encoding diff --git a/src/proto_012_Psithaca/lib_client/proxy.ml b/src/proto_012_Psithaca/lib_client/proxy.ml deleted file mode 100644 index 460985950e1f..000000000000 --- a/src/proto_012_Psithaca/lib_client/proxy.ml +++ /dev/null @@ -1,184 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module L = (val Tezos_proxy.Logger.logger ~protocol_name:Protocol.name - : Tezos_proxy.Logger.S) - -let proxy_block_header (rpc_context : RPC_context.json) - (chain : Tezos_shell_services.Block_services.chain) - (block : Tezos_shell_services.Block_services.block) = - let rpc_context = new Protocol_client_context.wrap_rpc_context rpc_context in - L.emit - L.proxy_block_header - ( Tezos_shell_services.Block_services.chain_to_string chain, - Tezos_shell_services.Block_services.to_string block ) - >>= fun () -> - Protocol_client_context.Alpha_block_services.header - rpc_context - ~chain - ~block - () - -module ProtoRpc : Tezos_proxy.Proxy_proto.PROTO_RPC = struct - (** Split done only when the mode is [Tezos_proxy.Proxy.server]. Getting - an entire big map at once is useful for dapp developers that - iterate a lot on big maps and that use proxy servers in their - internal infra. *) - let split_server key = - match key with - (* matches paths like: - big_maps/index/i/contents/tail *) - | "big_maps" :: "index" :: i :: "contents" :: tail -> - Some (["big_maps"; "index"; i; "contents"], tail) - | _ -> None - - (** Split that is always done, no matter the mode *) - let split_always key = - match key with - (* matches paths like: - contracts/index/000002298c03ed7d454a101eb7022bc95f7e5f41ac78/tail *) - | "contracts" :: "index" :: i :: tail -> - Some (["contracts"; "index"; i], tail) - | "cycle" :: i :: tail -> Some (["cycle"; i], tail) - (* matches paths like: - rolls/owner/snapshot/19/1/tail *) - | "rolls" :: "owner" :: "snapshot" :: i :: j :: tail -> - Some (["rolls"; "owner"; "snapshot"; i; j], tail) - | "v1" :: tail -> Some (["v1"], tail) - | _ -> None - - let split_key (mode : Tezos_proxy.Proxy.mode) (key : Proxy_context.M.key) : - (Proxy_context.M.key * Proxy_context.M.key) option = - match split_always key with - | Some _ as res -> - res (* No need to inspect the mode, this split is always done *) - | None -> ( - match mode with - | Client -> - (* There are strictly less splits in Client mode: return immediately *) - None - | Server -> split_server key) - - let failure_is_permanent = function - | ["pending_migration_balance_updates"] - | ["pending_migration_operation_results"] -> - true - | _ -> false - - let do_rpc (pgi : Tezos_proxy.Proxy.proxy_getter_input) - (key : Proxy_context.M.key) = - let chain = pgi.chain in - let block = pgi.block in - L.emit - L.proxy_block_rpc - ( Tezos_shell_services.Block_services.chain_to_string chain, - Tezos_shell_services.Block_services.to_string block, - key ) - >>= fun () -> - Protocol_client_context.Alpha_block_services.Context.read - pgi.rpc_context - ~chain - ~block - key - >>=? fun (raw_context : Block_services.raw_context) -> - L.emit L.tree_received - @@ Int64.of_int (Tezos_proxy.Proxy_getter.raw_context_size raw_context) - >>= fun () -> return raw_context -end - -let initial_context - (proxy_builder : - Tezos_proxy.Proxy_proto.proto_rpc -> - Tezos_proxy.Proxy_getter.proxy_m Lwt.t) (rpc_context : RPC_context.json) - (mode : Tezos_proxy.Proxy.mode) - (chain : Tezos_shell_services.Block_services.chain) - (block : Tezos_shell_services.Block_services.block) : - Environment_context.Context.t Lwt.t = - let p_rpc = (module ProtoRpc : Tezos_proxy.Proxy_proto.PROTO_RPC) in - proxy_builder p_rpc >>= fun (module M) -> - L.emit - L.proxy_getter_created - ( Tezos_shell_services.Block_services.chain_to_string chain, - Tezos_shell_services.Block_services.to_string block ) - >>= fun () -> - let pgi : Tezos_proxy.Proxy.proxy_getter_input = - {rpc_context = (rpc_context :> RPC_context.simple); mode; chain; block} - in - let module N : Proxy_context.M.ProxyDelegate = struct - let proxy_dir_mem = M.proxy_dir_mem pgi - - let proxy_get = M.proxy_get pgi - - let proxy_mem = M.proxy_mem pgi - end in - let empty = Proxy_context.empty @@ Some (module N) in - let version_value = "ithaca_012" in - Tezos_protocol_environment.Context.add - empty - ["version"] - (Bytes.of_string version_value) - >>= fun ctxt -> Protocol.Main.init_cache ctxt - -let round_durations (rpc_context : RPC_context.json) - (chain : Tezos_shell_services.Block_services.chain) - (block : Tezos_shell_services.Block_services.block) = - let open Protocol in - let rpc_context = new Protocol_client_context.wrap_rpc_context rpc_context in - Constants_services.all rpc_context (chain, block) >>=? fun constants -> - (* Return the duration of block 0 *) - return_some - (Alpha_context.Period.to_seconds constants.parametric.minimal_block_delay) - -let init_env_rpc_context (_printer : Tezos_client_base.Client_context.printer) - (proxy_builder : - Tezos_proxy.Proxy_proto.proto_rpc -> - Tezos_proxy.Proxy_getter.proxy_m Lwt.t) (rpc_context : RPC_context.json) - (mode : Tezos_proxy.Proxy.mode) - (chain : Tezos_shell_services.Block_services.chain) - (block : Tezos_shell_services.Block_services.block) : - Tezos_protocol_environment.rpc_context tzresult Lwt.t = - proxy_block_header rpc_context chain block >>=? fun {shell; hash; _} -> - let block_hash = hash in - initial_context proxy_builder rpc_context mode chain block >>= fun context -> - return {Tezos_protocol_environment.block_hash; block_header = shell; context} - -let () = - let open Tezos_proxy.Registration in - let module M : Proxy_sig = struct - module Protocol = Protocol_client_context.Lifted_protocol - - let protocol_hash = Protocol.hash - - let directory = Plugin.RPC.rpc_services - - let hash = Protocol_client_context.Alpha_block_services.hash - - let init_env_rpc_context = init_env_rpc_context - - let time_between_blocks = round_durations - - include Light.M - end in - register_proxy_context (module M) diff --git a/src/proto_012_Psithaca/lib_client/test/.ocamlformat b/src/proto_012_Psithaca/lib_client/test/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_client/test/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_client/test/assert.ml b/src/proto_012_Psithaca/lib_client/test/assert.ml deleted file mode 100644 index 3d414c2eafa9..000000000000 --- a/src/proto_012_Psithaca/lib_client/test/assert.ml +++ /dev/null @@ -1,37 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let fail expected given msg = - Format.kasprintf - Stdlib.failwith - "@[%s@ expected: %s@ got: %s@]" - msg - expected - given - -let default_printer _ = "" - -let equal ?(eq = ( = )) ?(print = default_printer) ?(msg = "") x y = - if not (eq x y) then fail (print x) (print y) msg diff --git a/src/proto_012_Psithaca/lib_client/test/dune b/src/proto_012_Psithaca/lib_client/test/dune deleted file mode 100644 index 8279641d2fa9..000000000000 --- a/src/proto_012_Psithaca/lib_client/test/dune +++ /dev/null @@ -1,17 +0,0 @@ -(tests - (names test_michelson_v1_macros test_client_proto_contracts test_client_proto_context test_proxy) - (libraries tezos-base - tezos-micheline - tezos-protocol-012-Psithaca - tezos-client-012-Psithaca - tezos-base-test-helpers - tezos-test-helpers - alcotest-lwt - qcheck-alcotest) - (package tezos-client-012-Psithaca) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_micheline - -open Tezos_client_012_Psithaca - -open Tezos_protocol_012_Psithaca - -open Tezos_base_test_helpers - -open Lib_test))) diff --git a/src/proto_012_Psithaca/lib_client/test/test_client_proto_context.ml b/src/proto_012_Psithaca/lib_client/test/test_client_proto_context.ml deleted file mode 100644 index ee5786be4739..000000000000 --- a/src/proto_012_Psithaca/lib_client/test/test_client_proto_context.ml +++ /dev/null @@ -1,71 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Testing - ------- - Component: Client - Invocation: dune exec src/proto_alpha/lib_client/test/test_client_proto_context.exe - Subject: Tests roundtrips of batch_transfer_operation_encoding -*) - -open Protocol -open Alpha_context -open Qcheck_helpers - -let binary_roundtrip ?pp encoding t = - let b = Data_encoding.Binary.to_bytes_exn encoding t in - let actual = Data_encoding.Binary.of_bytes_exn encoding b in - qcheck_eq' ?pp ~expected:t ~actual () - -let arb_batch_transfer_operation_encoding : - Client_proto_context.batch_transfer_operation QCheck.arbitrary = - let open QCheck.Gen in - let gen_z = sized @@ fun n -> map Z.of_bits (string_size (return n)) in - let gen_gas_arith_integral = - map Gas.Arith.integral_of_int_exn (int_range 0 (Int.div Int.max_int 1000)) - in - let gen_batch_transfer_operation_encoding = - let* destination = string ?gen:None in - let* fee = opt string in - let* gas_limit = opt gen_gas_arith_integral in - let* storage_limit = opt gen_z in - let* amount = string ?gen:None in - let* arg = opt string in - let* entrypoint = opt string in - return - Client_proto_context. - {destination; fee; gas_limit; storage_limit; amount; arg; entrypoint} - in - QCheck.make gen_batch_transfer_operation_encoding - -let tests = - [ - QCheck.Test.make - ~name:"test_batch_transfer_operation_encoding_roundtrip" - arb_batch_transfer_operation_encoding - (binary_roundtrip Client_proto_context.batch_transfer_operation_encoding); - ] - -let () = Alcotest.run "Client proto context" [("Encodings", qcheck_wrap tests)] diff --git a/src/proto_012_Psithaca/lib_client/test/test_client_proto_contracts.ml b/src/proto_012_Psithaca/lib_client/test/test_client_proto_contracts.ml deleted file mode 100644 index a89e6d5694ae..000000000000 --- a/src/proto_012_Psithaca/lib_client/test/test_client_proto_contracts.ml +++ /dev/null @@ -1,94 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Client - Invocation: dune exec src/proto_alpha/lib_client/test/test_client_proto_contracts.exe - Subject: Unit tests for Client_proto_contracts -*) - -(** [mock_wallet entities] is a mock of the - [Tezos_client_base.Client_context.wallet] class that only - implements the [load] method. This methods returns a key-value - association as given by the json string [entities] that should have - the form: ["[{"name": "alias", "value": "key" }, <...>]"]. *) -class mock_wallet (entities : string) : Tezos_client_base.Client_context.wallet - = - object - method load_passwords = None - - method read_file _path = failwith "mock_wallet:read_file" - - method get_base_dir = assert false - - method with_lock : type a. (unit -> a Lwt.t) -> a Lwt.t = fun _f -> _f () - - method load : type a. - string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t = - fun _alias_name ~default:_default _encoding -> - let json = (Ezjsonm.from_string entities :> Data_encoding.json) in - return @@ Data_encoding.Json.destruct _encoding json - - method write : type a. - string -> a -> a Data_encoding.encoding -> unit tzresult Lwt.t = - fun _alias_name _list _encoding -> failwith "mock_wallet:write" - end - -(** - Test. - Tests different lookups of - [Client_proto_contracts.ContractAlias.find_destination]. -*) -let test_find_destination _ = - let bootstrap1 = "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" in - let wallet_json = - Format.asprintf {| [{"name": "test_alias", "value": "%s" }] |} bootstrap1 - in - let w = new mock_wallet wallet_json in - let test msg key exp_source = - Client_proto_contracts.ContractAlias.find_destination w key - >>=? fun (_, contract) -> - Client_proto_contracts.RawContractAlias.to_source contract - >>=? fun source -> - (* Alcotest equality assertion *) - Alcotest.(check string msg source exp_source) ; - return_unit - in - test "Expected alias:test_alias = bootstrap1" "alias:test_alias" bootstrap1 - >>=? fun () -> - test "Expected key:test_alias = bootstrap1" "key:test_alias" bootstrap1 - >>=? fun () -> - test "Expected bootstrap1 = bootstrap1" bootstrap1 bootstrap1 >>=? fun () -> - test "Expected test_alias bootstrap1" "test_alias" bootstrap1 - -let () = - Alcotest_lwt.run - "tezos-lib-client-proto-contracts" - [ - ( "client_proto_contracts", - [Tztest.tztest "test_find_destination" `Quick test_find_destination] ); - ] - |> Lwt_main.run diff --git a/src/proto_012_Psithaca/lib_client/test/test_michelson_v1_macros.ml b/src/proto_012_Psithaca/lib_client/test/test_michelson_v1_macros.ml deleted file mode 100644 index 75316f163dfa..000000000000 --- a/src/proto_012_Psithaca/lib_client/test/test_michelson_v1_macros.ml +++ /dev/null @@ -1,1345 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Client - Invocation: dune build @src/proto_alpha/lib_client/runtest - Dependencies: src/proto_alpha/lib_client/test/assert.ml - Subject: Expansion and unexpansion of Micheline terms. -*) - -open Protocol - -let print expr : string = - expr - |> Micheline_printer.printable (fun s -> s) - |> Format.asprintf "%a" Micheline_printer.print_expr - -(* expands : expression with macros fully expanded *) - -let assert_expands - (original : (Micheline_parser.location, string) Micheline.node) - (expanded : (Micheline_parser.location, string) Micheline.node) = - let ({Michelson_v1_parser.expanded = expansion; _}, errors) = - let source = print (Micheline.strip_locations original) in - Michelson_v1_parser.expand_all ~source ~original - in - match errors with - | [] -> - Assert.equal - ~print - (Michelson_v1_primitives.strings_of_prims expansion) - (Micheline.strip_locations expanded) ; - ok () - | errors -> Error errors - -(****************************************************************************) - -open Micheline - -let zero_loc = Micheline_parser.location_zero - -let left_branch = Seq (zero_loc, [Prim (zero_loc, "SWAP", [], [])]) - -let right_branch = Seq (zero_loc, []) - -(***************************************************************************) -(* Test expands *) -(***************************************************************************) - -(** [prim_name] is the syntactic sugar to be expanded, while [compare_name] - is syntactic atom. *) -let assert_compare_macro prim_name compare_name = - assert_expands - (Prim (zero_loc, prim_name, [], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "COMPARE", [], []); - Prim (zero_loc, compare_name, [], []); - ] )) - -(** Expand "COMP{EQ|NEQ|LT|GT|LE|GE}" - into "COMPARE ; {EQ|NEQ|LT|GT|LE|GE}". -*) -let test_compare_marco_expansion () = - assert_compare_macro "CMPEQ" "EQ" >>? fun () -> - assert_compare_macro "CMPNEQ" "NEQ" >>? fun () -> - assert_compare_macro "CMPLT" "LT" >>? fun () -> - assert_compare_macro "CMPGT" "GT" >>? fun () -> - assert_compare_macro "CMPLE" "LE" >>? fun () -> - assert_compare_macro "CMPGE" "GE" - -let assert_if_macro prim_name compare_name = - assert_expands - (Prim (zero_loc, prim_name, [left_branch; right_branch], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, compare_name, [], []); - Prim (zero_loc, "IF", [left_branch; right_branch], []); - ] )) - -(** Expand "IF{EQ|NEQ|LT|GT|LE|GE}" - into "{EQ|NEQ|LT|GT|LE|GE} ; IF" -*) -let test_if_compare_macros_expansion () = - assert_if_macro "IFEQ" "EQ" >>? fun () -> - assert_if_macro "IFNEQ" "NEQ" >>? fun () -> - assert_if_macro "IFLT" "LT" >>? fun () -> - assert_if_macro "IFGT" "GT" >>? fun () -> - assert_if_macro "IFLE" "LE" >>? fun () -> assert_if_macro "IFGE" "GE" - -let assert_if_cmp_macros prim_name compare_name = - assert_expands - (Prim (zero_loc, prim_name, [left_branch; right_branch], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "COMPARE", [], []); - Prim (zero_loc, compare_name, [], []); - Prim (zero_loc, "IF", [left_branch; right_branch], []); - ] )) - -(** Expand "IF{EQ|NEQ|LT|GT|LE|GE}" - into "{EQ|NEQ|LT|GT|LE|GE} ; IF" -*) -let test_if_cmp_macros_expansion () = - assert_if_cmp_macros "IFCMPEQ" "EQ" >>? fun () -> - assert_if_cmp_macros "IFCMPNEQ" "NEQ" >>? fun () -> - assert_if_cmp_macros "IFCMPLT" "LT" >>? fun () -> - assert_if_cmp_macros "IFCMPGT" "GT" >>? fun () -> - assert_if_cmp_macros "IFCMPLE" "LE" >>? fun () -> - assert_if_cmp_macros "IFCMPGE" "GE" - -(****************************************************************************) -(* Fail *) - -(** Expand "FAIL" - into "UNIT ; FAILWITH" -*) -let test_fail_expansion () = - assert_expands - (Prim (zero_loc, "FAIL", [], [])) - (Seq - ( zero_loc, - [Prim (zero_loc, "UNIT", [], []); Prim (zero_loc, "FAILWITH", [], [])] - )) - -(**********************************************************************) -(* assertion *) - -let seq_unit_failwith = - Seq - ( zero_loc, - [Prim (zero_loc, "UNIT", [], []); Prim (zero_loc, "FAILWITH", [], [])] ) - -(* {} {FAIL} *) -let fail_false = [Seq (zero_loc, []); Seq (zero_loc, [seq_unit_failwith])] - -(* {FAIL} {} *) -let fail_true = [Seq (zero_loc, [seq_unit_failwith]); Seq (zero_loc, [])] - -(** Expand "ASSERT" - into "IF {} {FAIL}" -*) -let test_assert_expansion () = - assert_expands - (Prim (zero_loc, "ASSERT", [], [])) - (Seq (zero_loc, [Prim (zero_loc, "IF", fail_false, [])])) - -let assert_assert_if_compare prim_name compare_name = - assert_expands - (Prim (zero_loc, prim_name, [], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, compare_name, [], []); - Prim (zero_loc, "IF", fail_false, []); - ] )) - -(** Expand "ASSERT_{EQ|NEQ|LT|GT|LE|GE}" - into "{EQ|NEQ|LT|GT|LE|GE} ; IF {} {FAIL}" -*) -let test_assert_if () = - assert_assert_if_compare "ASSERT_EQ" "EQ" >>? fun () -> - assert_assert_if_compare "ASSERT_NEQ" "NEQ" >>? fun () -> - assert_assert_if_compare "ASSERT_LT" "LT" >>? fun () -> - assert_assert_if_compare "ASSERT_LE" "LE" >>? fun () -> - assert_assert_if_compare "ASSERT_GT" "GT" >>? fun () -> - assert_assert_if_compare "ASSERT_GE" "GE" - -let assert_cmp_if prim_name compare_name = - assert_expands - (Prim (zero_loc, prim_name, [], [])) - (Seq - ( zero_loc, - [ - Seq - ( zero_loc, - [ - Prim (zero_loc, "COMPARE", [], []); - Prim (zero_loc, compare_name, [], []); - ] ); - Prim (zero_loc, "IF", fail_false, []); - ] )) - -(** Expand "ASSERT_CMP{EQ|NEQ|LT|GT|LE|GE}" - into "COMPARE ; {EQ|NEQ|LT|GT|LE|GE} ; IF {} {FAIL}" -*) -let test_assert_cmp_if () = - assert_cmp_if "ASSERT_CMPEQ" "EQ" >>? fun () -> - assert_cmp_if "ASSERT_CMPNEQ" "NEQ" >>? fun () -> - assert_cmp_if "ASSERT_CMPLT" "LT" >>? fun () -> - assert_cmp_if "ASSERT_CMPLE" "LE" >>? fun () -> - assert_cmp_if "ASSERT_CMPGT" "GT" >>? fun () -> - assert_cmp_if "ASSERT_CMPGE" "GE" - -(* The work of merge request !628 - > ASSERT_LEFT @x => IF_LEFT {RENAME @x} {FAIL} - > ASSERT_RIGHT @x => IF_LEFT {FAIL} {RENAME @x} - > ASSERT_SOME @x => IF_NONE {FAIL} {RENAME @x} -*) - -let may_rename annot = Seq (zero_loc, [Prim (zero_loc, "RENAME", [], annot)]) - -let fail_false_may_rename = - [ - may_rename ["@annot"]; - Seq - ( zero_loc, - [ - Seq - ( zero_loc, - [ - Prim (zero_loc, "UNIT", [], []); - Prim (zero_loc, "FAILWITH", [], []); - ] ); - ] ); - ] - -let fail_true_may_rename = - [ - Seq - ( zero_loc, - [ - Seq - ( zero_loc, - [ - Prim (zero_loc, "UNIT", [], []); - Prim (zero_loc, "FAILWITH", [], []); - ] ); - ] ); - may_rename ["@annot"]; - ] - -(** Expand "ASSERT_SOME @annot" - into "IF_NONE { } {UNIT;FAILWITH}" - using variable annotation "@annot" -*) -let test_assert_some_annot () = - assert_expands - (Prim (zero_loc, "ASSERT_SOME", [], ["@annot"])) - (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_true_may_rename, [])])) - -(** Expand "ASSERT_SOME" - into "IF_NONE { UNIT;FAILWITH } { }" -*) -let test_assert_some () = - assert_expands - (Prim (zero_loc, "ASSERT_SOME", [], [])) - (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_true, [])])) - -(** Expand "ASSERT_LEFT @annot" - into "IF_LEFT { } {UNIT;FAILWITH}" - using variable annotation "@annot" -*) -let test_assert_left_annot () = - assert_expands - (Prim (zero_loc, "ASSERT_LEFT", [], ["@annot"])) - (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_false_may_rename, [])])) - -(** Expand "ASSERT_LEFT" - into "IF_LEFT { } {UNIT;FAILWITH}" -*) -let test_assert_left () = - assert_expands - (Prim (zero_loc, "ASSERT_LEFT", [], [])) - (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_false, [])])) - -(** Expand "ASSERT_RIGHT @annot" - into "IF_LEFT {UNIT;FAILWITH} { }" - using variable annotation "@annot" -*) -let test_assert_right_annot () = - assert_expands - (Prim (zero_loc, "ASSERT_RIGHT", [], ["@annot"])) - (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_true_may_rename, [])])) - -(** Expand "ASSERT_RIGHT" - into "IF_LEFT {UNIT;FAILWITH} { }" -*) -let test_assert_right () = - assert_expands - (Prim (zero_loc, "ASSERT_RIGHT", [], [])) - (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_true, [])])) - -(** Expand "ASSERT_NONE" - into "IF_NONE { } { UNIT;FAILWITH }" -*) -let test_assert_none () = - assert_expands - (Prim (zero_loc, "ASSERT_NONE", [], [])) - (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_false, [])])) - -(***********************************************************************) -(*Syntactic Conveniences*) - -(* diip *) - -(** Expand "DIP" into "DIP". - Expand "DIIIIIIIIP" into "DIP 8". - Expand "DIIP" into "DIP 2". -*) -let test_diip () = - let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in - assert_expands - (Prim (zero_loc, "DIP", [code], [])) - (Prim (zero_loc, "DIP", [code], [])) - >>? fun () -> - assert_expands - (Prim (zero_loc, "DIIIIIIIIP", [code], [])) - (Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 8); code], [])) - >>? fun () -> - assert_expands - (Prim (zero_loc, "DIIP", [code], [])) - (Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 2); code], [])) - -(* pair *) - -(** Expand "PAIR" - into "PAIR" -*) -let test_pair () = - assert_expands - (Prim (zero_loc, "PAIR", [], [])) - (Prim (zero_loc, "PAIR", [], [])) - -(** Expand "PAPPAIIR" - into "DIP {PAIR}; DIP {PAIR}; PAIR" -*) -let test_pappaiir () = - let pair = Prim (zero_loc, "PAIR", [], []) in - assert_expands - (Prim (zero_loc, "PAPPAIIR", [], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DIP", [Seq (zero_loc, [pair])], []); - Prim (zero_loc, "DIP", [Seq (zero_loc, [pair])], []); - pair; - ] )) - -(* unpair *) - -(** Expand "UNPAIR" - into "DUP ; CAR ; DIP {CDR}" -*) -let test_unpair () = - assert_expands - (Prim (zero_loc, "UNPAIR", [], [])) - (Prim (zero_loc, "UNPAIR", [], [])) - -(* duup *) - -(** Expand "DUUP" - into "DIP {DUP} ; SWAP" -*) -let test_duup () = - assert_expands - (Prim (zero_loc, "DUUP", [], [])) - (Prim (zero_loc, "DUP", [Int (zero_loc, Z.of_int 2)], [])) - -(* car/cdr *) - -(** Expand "CAR" into "CAR" - Expand "CDR" into "CDR" - Expand "CADR" into "CAR ; CDR" - Expand "CDAR" into "CDR ; CAR" -*) -let test_caddadr_expansion () = - let car = Prim (zero_loc, "CAR", [], []) in - assert_expands (Prim (zero_loc, "CAR", [], [])) car >>? fun () -> - let cdr = Prim (zero_loc, "CDR", [], []) in - assert_expands (Prim (zero_loc, "CDR", [], [])) cdr >>? fun () -> - assert_expands (Prim (zero_loc, "CADR", [], [])) (Seq (zero_loc, [car; cdr])) - >>? fun () -> - assert_expands (Prim (zero_loc, "CDAR", [], [])) (Seq (zero_loc, [cdr; car])) - -let test_carn_cdrn_expansion () = - let car n = Prim (zero_loc, "CAR", [Int (zero_loc, Z.of_int n)], []) in - let cdr n = Prim (zero_loc, "CDR", [Int (zero_loc, Z.of_int n)], []) in - let get n = - Seq (zero_loc, [Prim (zero_loc, "GET", [Int (zero_loc, Z.of_int n)], [])]) - in - assert_expands (cdr 0) (get 0) >>? fun () -> - assert_expands (car 0) (get 1) >>? fun () -> - assert_expands (cdr 1) (get 2) >>? fun () -> - assert_expands (car 1) (get 3) >>? fun () -> assert_expands (cdr 2) (get 4) - -(* if_some *) - -(** Expand "IF_SOME { 1 } { 2 }" - into "IF_NONE { 2 } { 1 }" -*) -let test_if_some () = - assert_expands - (Prim (zero_loc, "IF_SOME", [right_branch; left_branch], [])) - (Seq - (zero_loc, [Prim (zero_loc, "IF_NONE", [left_branch; right_branch], [])])) - -(*set_caddadr*) - -(** Expand "SET_CAR" - into "CDR; SWAP; PAIR" -*) -let test_set_car_expansion () = - assert_expands - (Prim (zero_loc, "SET_CAR", [], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%"; "%@"]); - ] )) - -(** Expand "SET_CDR" - into "CAR; PAIR" -*) -let test_set_cdr_expansion () = - assert_expands - (Prim (zero_loc, "SET_CDR", [], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%"]); - ] )) - -(** Expand "SET_CADR" - into "DUP; DIP {CAR; { CAR; PAIR }}; CDR; SWAP; PAIR" -*) -let test_set_cadr_expansion () = - let set_car = - Seq - ( zero_loc, - [ - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%"]); - ] ) - in - assert_expands - (Prim (zero_loc, "SET_CADR", [], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); set_car])], - [] ); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] )) - -(** Expand "SET_CDAR" - into "DUP; DIP {CDR; { CDR; SWAP; PAIR }}; CAR; PAIR" -*) -let test_set_cdar_expansion () = - let set_cdr = - Seq - ( zero_loc, - [ - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%"; "%@"]); - ] ) - in - assert_expands - (Prim (zero_loc, "SET_CDAR", [], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CDR", [], ["@%%"]); set_cdr])], - [] ); - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] )) - -(* TO BE CHANGE IN THE DOCUMENTATION: @MR!791 - FROM: - > MAP_CAR code => DUP ; CDR ; DIP { CAR ; code } ; SWAP ; PAIR - TO: - > MAP_CAR code => DUP ; CDR ; DIP { CAR ; {code} } ; SWAP ; PAIR -*) - -(** Expand "MAP_CAR {CAR}" - into "DUP; CDR; DIP {CAR; CAR}; SWAP; PAIR" -*) -let test_map_car () = - (* code is a sequence *) - let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in - assert_expands - (Prim (zero_loc, "MAP_CAR", [code], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CAR", [], []); code])], - [] ); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%"; "%@"]); - ] )) - -(** Expand "MAP_CDR {CAR}" - into "DUP; CDR; CAR; SWAP; CAR; PAIR" -*) -let test_map_cdr () = - let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in - assert_expands - (Prim (zero_loc, "MAP_CDR", [code], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CDR", [], []); - code; - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%"]); - ] )) - -(** Expand "MAP_CAADR {CAR}" - into "DUP; - DIP { CAR; - DUP; - DIP { CAR; - DUP; - CDR; - CAR; - SWAP; - CAR; - PAIR - } - CDR; - SWAP; - PAIR - }; - CDR; - SWAP; - PAIR" -*) -let test_map_caadr () = - let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in - let map_cdr = - Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CDR", [], []); - code; - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%"]); - ] ) - in - let map_cadr = - Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); map_cdr])], - [] ); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] ) - in - assert_expands - (Prim (zero_loc, "MAP_CAADR", [code], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); map_cadr])], - [] ); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] )) - -(** Expand "MAP_CDADR" - into "DUP; - DIP { CDR; - DUP; - DIP { CAR; - DUP; - CDR; - CAR; - SWAP; - CAR; - PAIR - }; - CDR; - CAR; - PAIR - }; - CAR; - PAIR" -*) -let test_map_cdadr () = - let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in - let map_cdr = - Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CDR", [], []); - code; - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%"]); - ] ) - in - let map_cadr = - Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); map_cdr])], - [] ); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] ) - in - assert_expands - (Prim (zero_loc, "MAP_CDADR", [code], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CDR", [], ["@%%"]); map_cadr])], - [] ); - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] )) - -(****************************************************************************) -(* Unexpand tests *) -(****************************************************************************) - -(** Asserts that unexpanding the expression [original] conforms with - the canonical form of [ex]. - [unparse.Michelson_v1_parser.unexpanded] contains the original - expression with macros *) -let assert_unexpansion original ex = - let ({Michelson_v1_parser.expanded; _}, errors) = - let source = print (Micheline.strip_locations original) in - Michelson_v1_parser.expand_all ~source ~original - in - let unparse = Michelson_v1_printer.unparse_expression expanded in - match errors with - | [] -> - Assert.equal - ~print - unparse.Michelson_v1_parser.unexpanded - (Micheline.strip_locations ex) ; - ok () - | _ :: _ -> Error errors - -(** Unexpanding "UNIT; FAILWITH" - yields "FAIL" -*) -let test_unexpand_fail () = - assert_unexpansion - (Seq - ( zero_loc, - [Prim (zero_loc, "UNIT", [], []); Prim (zero_loc, "FAILWITH", [], [])] - )) - (Prim (zero_loc, "FAIL", [], [])) - -(** Unexpanding "IF_LEFT { 1 } { 2 }" - yields "IF_RIGHT { 2 } { 1 }" -*) -let test_unexpand_if_right () = - assert_unexpansion - (Seq - (zero_loc, [Prim (zero_loc, "IF_LEFT", [left_branch; right_branch], [])])) - (Prim (zero_loc, "IF_RIGHT", [right_branch; left_branch], [])) - -(** IF_NONE - Unexpanding "IF_NONE { 1 } { 2 }" - yields "IF_SOME { 2 } { 1 }" -*) -let test_unexpand_if_some () = - assert_unexpansion - (Seq - (zero_loc, [Prim (zero_loc, "IF_NONE", [left_branch; right_branch], [])])) - (Prim (zero_loc, "IF_SOME", [right_branch; left_branch], [])) - -(** Unexpanding "IF {} { UNIT; FAILWITH }" - yields "ASSERT" -*) -let test_unexpand_assert () = - assert_unexpansion - (Seq (zero_loc, [Prim (zero_loc, "IF", fail_false, [])])) - (Prim (zero_loc, "ASSERT", [], [])) - -let assert_unexpansion_assert_if_compare compare_name prim_name = - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim (zero_loc, compare_name, [], []); - Prim (zero_loc, "IF", fail_false, []); - ] )) - (Prim (zero_loc, prim_name, [], [])) - -(** Unexpanding "{EQ|NEQ|LT|LE|GT|GE} ; IF {} {FAIL}" - yields "ASSERT_{EQ|NEQ|LT|LE|GT|GE}" -*) -let test_unexpand_assert_if () = - assert_unexpansion_assert_if_compare "EQ" "ASSERT_EQ" >>? fun () -> - assert_unexpansion_assert_if_compare "NEQ" "ASSERT_NEQ" >>? fun () -> - assert_unexpansion_assert_if_compare "LT" "ASSERT_LT" >>? fun () -> - assert_unexpansion_assert_if_compare "LE" "ASSERT_LE" >>? fun () -> - assert_unexpansion_assert_if_compare "GT" "ASSERT_GT" >>? fun () -> - assert_unexpansion_assert_if_compare "GE" "ASSERT_GE" - -let assert_unexpansion_assert_cmp_if_compare compare_name prim_name = - assert_unexpansion - (Seq - ( zero_loc, - [ - Seq - ( zero_loc, - [ - Prim (zero_loc, "COMPARE", [], []); - Prim (zero_loc, compare_name, [], []); - ] ); - Prim (zero_loc, "IF", fail_false, []); - ] )) - (Prim (zero_loc, prim_name, [], [])) - -(** Unexpanding "COMPARE; {EQ|NEQ|LT|LE|GT|GE}; IF {} {FAIL}" - yields "ASSERT_CMP{EQ|NEQ|LT|LE|GT|GE}" -*) -let test_unexpansion_assert_cmp_if () = - assert_unexpansion_assert_cmp_if_compare "EQ" "ASSERT_CMPEQ" >>? fun () -> - assert_unexpansion_assert_cmp_if_compare "NEQ" "ASSERT_CMPNEQ" >>? fun () -> - assert_unexpansion_assert_cmp_if_compare "LT" "ASSERT_CMPLT" >>? fun () -> - assert_unexpansion_assert_cmp_if_compare "LE" "ASSERT_CMPLE" >>? fun () -> - assert_unexpansion_assert_cmp_if_compare "GT" "ASSERT_CMPGT" >>? fun () -> - assert_unexpansion_assert_cmp_if_compare "GE" "ASSERT_CMPGE" - -(** Unexpanding "IF_NONE { FAIL } { RENAME @annot }" - yields "ASSERT_SOME @annot" -*) -let test_unexpand_assert_some_annot () = - assert_unexpansion - (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_true_may_rename, [])])) - (Prim (zero_loc, "ASSERT_SOME", [], ["@annot"])) - -(** Unexpanding "IF_LEFT { RENAME @annot } { FAIL }" - yields "ASSERT_LEFT @annot" -*) -let test_unexpand_assert_left_annot () = - assert_unexpansion - (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_false_may_rename, [])])) - (Prim (zero_loc, "ASSERT_LEFT", [], ["@annot"])) - -(** Unexpanding "IF_LEFT { FAIL } { RENAME @annot }" - yields "ASSERT_RIGHT @annot" -*) -let test_unexpand_assert_right_annot () = - assert_unexpansion - (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_true_may_rename, [])])) - (Prim (zero_loc, "ASSERT_RIGHT", [], ["@annot"])) - -(** Unexpanding "IF_NONE {} { FAIL }" - yields "ASSERT_NONE" -*) -let test_unexpand_assert_none () = - assert_unexpansion - (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_false, [])])) - (Prim (zero_loc, "ASSERT_NONE", [], [])) - -(** Unexpanding "IF_NONE { FAIL } {}" - yields "ASSERT_SOME" -*) -let test_unexpand_assert_some () = - assert_unexpansion - (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_true, [])])) - (Prim (zero_loc, "ASSERT_SOME", [], [])) - -(** Unexpanding "IF_LEFT {} { FAIL }" - yields "ASSERT_LEFT" -*) -let test_unexpand_assert_left () = - assert_unexpansion - (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_false, [])])) - (Prim (zero_loc, "ASSERT_LEFT", [], [])) - -(** Unexpanding "IF_LEFT { FAIL } {}" - yields "ASSERT_RIGHT" -*) -let test_unexpand_assert_right () = - assert_unexpansion - (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_true, [])])) - (Prim (zero_loc, "ASSERT_RIGHT", [], [])) - -(** Unexpanding "DUP; CAR; DIP { CDR }" - yields "UNPAIR" -*) -let test_unexpand_unpair () = - assert_unexpansion - (Prim (zero_loc, "UNPAIR", [], [])) - (Prim (zero_loc, "UNPAIR", [], [])) - -(** Unexpanding "PAIR" - yields "PAIR" -*) -let test_unexpand_pair () = - assert_unexpansion - (Prim (zero_loc, "PAIR", [], [])) - (Prim (zero_loc, "PAIR", [], [])) - -(** Unexpanding "DIP { PAIR }; DIP { PAIR }; PAIR" - yields "PAPPAIIR" -*) -let test_unexpand_pappaiir () = - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "PAIR", [], [])])], - [] ); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "PAIR", [], [])])], - [] ); - Prim (zero_loc, "PAIR", [], []); - ] )) - (Prim (zero_loc, "PAPPAIIR", [], [])) - -(** Unexpanding "DIP { DUP }; SWAP" - yields "DUP 2" -*) -let test_unexpand_duup () = - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "DUP", [], [])])], - [] ); - Prim (zero_loc, "SWAP", [], []); - ] )) - (Prim (zero_loc, "DUP", [Int (zero_loc, Z.of_int 2)], [])) - -(** Unexpanding "CAR" yields "CAR" - Unexpanding "CDR" yields "CDR" - Unexpanding "CAR; CDR" yields "CADR" - Unexpanding "CDR; CAR" yields "CDAR" -*) -let test_unexpand_caddadr () = - let car = Prim (zero_loc, "CAR", [], []) in - let cdr = Prim (zero_loc, "CDR", [], []) in - assert_unexpansion (Seq (zero_loc, [car])) car >>? fun () -> - assert_unexpansion (Seq (zero_loc, [cdr])) cdr >>? fun () -> - assert_unexpansion - (Seq (zero_loc, [car; cdr])) - (Prim (zero_loc, "CADR", [], [])) - >>? fun () -> - assert_unexpansion - (Seq (zero_loc, [cdr; car])) - (Prim (zero_loc, "CDAR", [], [])) - -let test_unexpand_carn_cdrn () = - let car n = Prim (zero_loc, "CAR", [Int (zero_loc, Z.of_int n)], []) in - let cdr n = Prim (zero_loc, "CDR", [Int (zero_loc, Z.of_int n)], []) in - let get n = - Seq (zero_loc, [Prim (zero_loc, "GET", [Int (zero_loc, Z.of_int n)], [])]) - in - assert_unexpansion (get 0) (cdr 0) >>? fun () -> - assert_unexpansion (get 1) (car 0) >>? fun () -> - assert_unexpansion (get 2) (cdr 1) >>? fun () -> - assert_unexpansion (get 3) (car 1) >>? fun () -> - assert_unexpansion (get 4) (cdr 2) - -(** Unexpanding "CDR; SWAP; PAIR" - yields "SET_CAR" -*) -let test_unexpand_set_car () = - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%"; "%@"]); - ] )) - (Prim (zero_loc, "SET_CAR", [], [])) - -(** Unexpanding "CAR; PAIR" - yields "SET_CDR" -*) -let test_unexpand_set_cdr () = - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%"]); - ] )) - (Prim (zero_loc, "SET_CDR", [], [])) - -(** Unexpanding "DUP; CAR; DROP; CDR; SWAP; PAIR" - yields "SET_CAR" -*) -let test_unexpand_set_car_annot () = - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CAR", [], ["%@"]); - Prim (zero_loc, "DROP", [], []); - Prim (zero_loc, "CDR", [], []); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], []); - ] )) - (Prim (zero_loc, "SET_CAR", [], ["%@"])) - -(** Unexpanding "DUP; CDR; DROP; CAR; PAIR" - yields "SET_CDR" -*) -let test_unexpand_set_cdr_annot () = - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CDR", [], ["%@"]); - Prim (zero_loc, "DROP", [], []); - Prim (zero_loc, "CAR", [], []); - Prim (zero_loc, "PAIR", [], []); - ] )) - (Prim (zero_loc, "SET_CDR", [], ["%@"])) - -(** Unexpanding "DUP; DIP { CAR; CAR; PAIR }; CDR; SWAP; PAIR" - yields "SET_CADR" -*) -let test_unexpand_set_cadr () = - let set_car = - Seq - ( zero_loc, - [ - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%"]); - ] ) - in - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); set_car])], - [] ); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] )) - (Prim (zero_loc, "SET_CADR", [], [])) - -let test_unexpand_set_cdar () = - let set_cdr = - Seq - ( zero_loc, - [ - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%"; "%@"]); - ] ) - in - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CDR", [], ["@%%"]); set_cdr])], - [] ); - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] )) - (Prim (zero_loc, "SET_CDAR", [], [])) - -(* FIXME: Seq()(Prim): does not parse, raise an error unparse *) -let test_unexpand_map_car () = - let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in - assert_unexpansion - (Prim (zero_loc, "MAP_CAR", [code], [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim - ( zero_loc, - "DIP", - [ - Seq - ( zero_loc, - [ - Prim (zero_loc, "CAR", [], []); - Prim (zero_loc, "CAR", [], []); - ] ); - ], - [] ); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%"; "%@"]); - ] )) - -(***********************************************************************) -(*BUG: the test with MAP_CDR or any map with "D" inside fail *) - -let _test_unexpand_map_cdr () = - let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CDR", [], []); - code; - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "CAR", [], []); - Prim (zero_loc, "PAIR", [], []); - ] )) - (Prim (zero_loc, "MAP_CDR", [code], [])) - -let _test_unexpand_map_caadr () = - let code = [Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])])] in - let map_cdr = - Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [ - Seq - ( zero_loc, - [ - Prim (zero_loc, "CAR", [], ["@%%"]); - Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CDR", [], []); - Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%"]); - ] ); - ] ); - ], - [] ); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] ) - in - assert_unexpansion - (Prim (zero_loc, "MAP_CAAR", code, [])) - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); map_cdr])], - [] ); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] )) - -let _test_unexpand_map_cdadr () = - let code = [Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])])] in - let map_cdr = - Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [ - Seq - ( zero_loc, - [ - Prim (zero_loc, "CAR", [], ["@%%"]); - Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim (zero_loc, "CDR", [], []); - Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%"]); - ] ); - ] ); - ], - [] ); - Prim (zero_loc, "CDR", [], ["@%%"]); - Prim (zero_loc, "SWAP", [], []); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] ) - in - assert_unexpansion - (Seq - ( zero_loc, - [ - Prim (zero_loc, "DUP", [], []); - Prim - ( zero_loc, - "DIP", - [Seq (zero_loc, [Prim (zero_loc, "CDR", [], ["@%%"]); map_cdr])], - [] ); - Prim (zero_loc, "CAR", [], ["@%%"]); - Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); - ] )) - (Prim (zero_loc, "MAP_CDADR", code, [])) - -let test_unexpand_diip () = - let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in - assert_unexpansion - (Prim (zero_loc, "DIIP", [code], [])) - (Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 2); code], [])) - -(** Unexpanding "DIP { DIP { DIP { DUP }; SWAP" - yields "DIIP { DIP { DUP }; SWAP }" -*) -let test_unexpand_diip_duup1 () = - let single code = Seq (zero_loc, [code]) in - let cst str = Prim (zero_loc, str, [], []) in - let app str code = Prim (zero_loc, str, [code], []) in - let dip = app "DIP" in - let diip code = - Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 2); code], []) - in - let dup = cst "DUP" in - let swap = cst "SWAP" in - let dip_dup_swap = Seq (zero_loc, [dip (single dup); swap]) in - assert_unexpansion - (* { DIP { DIP { DIP { DUP }; SWAP }}} *) - (single (dip (single (dip dip_dup_swap)))) - (* DIIP { DIP { DUP }; SWAP } *) - (diip dip_dup_swap) - -(** Unexpanding "DIP { DIP {{ DIP { DUP }; SWAP" - yields "DIIP { DUUP }" -*) -let test_unexpand_diip_duup2 () = - let single code = Seq (zero_loc, [code]) in - let cst str = Prim (zero_loc, str, [], []) in - let app str code = Prim (zero_loc, str, [code], []) in - let dip = app "DIP" in - let diip code = - Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 2); code], []) - in - let dup = cst "DUP" in - let duup = Prim (zero_loc, "DUP", [Int (zero_loc, Z.of_int 2)], []) in - let swap = cst "SWAP" in - let dip_dup_swap = Seq (zero_loc, [dip (single dup); swap]) in - assert_unexpansion - (* { DIP { DIP {{ DIP { DUP }; SWAP }}}} *) - (single (dip (single (dip (single dip_dup_swap))))) - (* DIIP { DUUP } *) - (diip (single duup)) - -(*****************************************************************************) -(* Test *) -(*****************************************************************************) - -let tests = - [ - (*compare*) - ("compare expansion", fun _ -> Lwt.return (test_compare_marco_expansion ())); - ( "if compare expansion", - fun _ -> Lwt.return (test_if_compare_macros_expansion ()) ); - ( "if compare expansion: IFCMP", - fun _ -> Lwt.return (test_if_cmp_macros_expansion ()) ); - (*fail*) - ("fail expansion", fun _ -> Lwt.return (test_fail_expansion ())); - (*assertion*) - ("assert expansion", fun _ -> Lwt.return (test_assert_expansion ())); - ("assert if expansion", fun _ -> Lwt.return (test_assert_if ())); - ("assert cmpif expansion", fun _ -> Lwt.return (test_assert_cmp_if ())); - ("assert none expansion", fun _ -> Lwt.return (test_assert_none ())); - ("assert some expansion", fun _ -> Lwt.return (test_assert_some ())); - ("assert left expansion", fun _ -> Lwt.return (test_assert_left ())); - ("assert right expansion", fun _ -> Lwt.return (test_assert_right ())); - ( "assert some annot expansion", - fun _ -> Lwt.return (test_assert_some_annot ()) ); - ( "assert left annot expansion", - fun _ -> Lwt.return (test_assert_left_annot ()) ); - ( "assert right annot expansion", - fun _ -> Lwt.return (test_assert_right_annot ()) ); - (*syntactic conveniences*) - ("diip expansion", fun _ -> Lwt.return (test_diip ())); - ("duup expansion", fun _ -> Lwt.return (test_duup ())); - ("pair expansion", fun _ -> Lwt.return (test_pair ())); - ("pappaiir expansion", fun _ -> Lwt.return (test_pappaiir ())); - ("unpair expansion", fun _ -> Lwt.return (test_unpair ())); - ("caddadr expansion", fun _ -> Lwt.return (test_caddadr_expansion ())); - ( "carn and cdrn expansion", - fun _ -> Lwt.return (test_carn_cdrn_expansion ()) ); - ("if_some expansion", fun _ -> Lwt.return (test_if_some ())); - ("set_car expansion", fun _ -> Lwt.return (test_set_car_expansion ())); - ("set_cdr expansion", fun _ -> Lwt.return (test_set_cdr_expansion ())); - ("set_cadr expansion", fun _ -> Lwt.return (test_set_cadr_expansion ())); - ("set_cdar expansion", fun _ -> Lwt.return (test_set_cdar_expansion ())); - ("map_car expansion", fun _ -> Lwt.return (test_map_car ())); - ("map_cdr expansion", fun _ -> Lwt.return (test_map_cdr ())); - ("map_caadr expansion", fun _ -> Lwt.return (test_map_caadr ())); - ("map_cdadr expansion", fun _ -> Lwt.return (test_map_cdadr ())); - (*Unexpand*) - ("fail unexpansion", fun _ -> Lwt.return (test_unexpand_fail ())); - ("if_right unexpansion", fun _ -> Lwt.return (test_unexpand_if_right ())); - ("if_some unexpansion", fun _ -> Lwt.return (test_unexpand_if_some ())); - ("assert unexpansion", fun _ -> Lwt.return (test_unexpand_assert ())); - ("assert_if unexpansion", fun _ -> Lwt.return (test_unexpand_assert_if ())); - ( "assert_cmp_if unexpansion", - fun _ -> Lwt.return (test_unexpansion_assert_cmp_if ()) ); - ( "assert_none unexpansion", - fun _ -> Lwt.return (test_unexpand_assert_none ()) ); - ( "assert_some unexpansion", - fun _ -> Lwt.return (test_unexpand_assert_some ()) ); - ( "assert_left unexpansion", - fun _ -> Lwt.return (test_unexpand_assert_left ()) ); - ( "assert_right unexpansion", - fun _ -> Lwt.return (test_unexpand_assert_right ()) ); - ( "assert_some annot unexpansion", - fun _ -> Lwt.return (test_unexpand_assert_some_annot ()) ); - ( "assert_left annot unexpansion", - fun _ -> Lwt.return (test_unexpand_assert_left_annot ()) ); - ( "assert_right annot unexpansion", - fun _ -> Lwt.return (test_unexpand_assert_right_annot ()) ); - ("unpair unexpansion", fun _ -> Lwt.return (test_unexpand_unpair ())); - ("pair unexpansion", fun _ -> Lwt.return (test_unexpand_pair ())); - ("pappaiir unexpansion", fun _ -> Lwt.return (test_unexpand_pappaiir ())); - ("duup unexpansion", fun _ -> Lwt.return (test_unexpand_duup ())); - ("caddadr unexpansion", fun _ -> Lwt.return (test_unexpand_caddadr ())); - ( "carn and cdrn unexpansion", - fun _ -> Lwt.return (test_unexpand_carn_cdrn ()) ); - ("set_car unexpansion", fun _ -> Lwt.return (test_unexpand_set_car ())); - ("set_cdr unexpansion", fun _ -> Lwt.return (test_unexpand_set_cdr ())); - ("set_cdar unexpansion", fun _ -> Lwt.return (test_unexpand_set_cdar ())); - ("set_cadr unexpansion", fun _ -> Lwt.return (test_unexpand_set_cadr ())); - ( "set_car annot unexpansion", - fun _ -> Lwt.return (test_unexpand_set_car_annot ()) ); - ( "set_cdr annot unexpansion", - fun _ -> Lwt.return (test_unexpand_set_cdr_annot ()) ); - ("map_car unexpansion", fun _ -> Lwt.return (test_unexpand_map_car ())); - ("diip unexpansion", fun _ -> Lwt.return (test_unexpand_diip ())); - ("diip_duup1 unexpansion", fun _ -> Lwt.return (test_unexpand_diip_duup1 ())); - ("diip_duup2 unexpansion", fun _ -> Lwt.return (test_unexpand_diip_duup2 ())); - (***********************************************************************) - (*BUG - the function in Michelson_v1_macros.unexpand_map_caddadr - failed to test the case with the character "D". - It returns an empty {} for the expand *) - (*"diip unexpansion", (fun _ -> Lwt.return (test_unexpand_diip ())) ;*) - (*"map_cdr unexpansion", (fun _ -> Lwt.return (test_unexpand_map_cdr ())) ;*) - (*"map_caadr unexpansion", (fun _ -> Lwt.return (test_unexpand_map_caadr ())) ;*) - (*"map_cdadr unexpansion", (fun _ -> Lwt.return (test_unexpand_map_cdadr ())) ;*) - ] - -let wrap (n, f) = - Alcotest_lwt.test_case n `Quick (fun _ () -> - f () >>= function - | Ok () -> Lwt.return_unit - | Error error -> - Format.kasprintf Stdlib.failwith "%a" pp_print_trace error) - -let () = - Alcotest_lwt.run - ~argv:[|""|] - "tezos-lib-client" - [("micheline v1 macros", List.map wrap tests)] - |> Lwt_main.run diff --git a/src/proto_012_Psithaca/lib_client/test/test_proxy.ml b/src/proto_012_Psithaca/lib_client/test/test_proxy.ml deleted file mode 100644 index d6973017918b..000000000000 --- a/src/proto_012_Psithaca/lib_client/test/test_proxy.ml +++ /dev/null @@ -1,89 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Client - Invocation: dune build @src/proto_alpha/lib_client/runtest - Subject: Test of --mode proxy and tezos-proxy-server heuristic -*) - -let proxy_mode_arb = - QCheck.make (QCheck.Gen.oneofl Tezos_proxy.Proxy.[Client; Server]) - -let key_gen : string list QCheck.Gen.t = - (* Segments taken from the implementation of split_key in src/proto_alpha/lib_client/proxy.ml *) - let keys = - QCheck.Gen.oneofl - [ - "big_maps"; - "index"; - "contents"; - "contracts"; - "cycle"; - "cycle"; - "rolls"; - "owner"; - "snapshot"; - "v1"; - ] - |> QCheck.Gen.list - in - QCheck.Gen.frequency QCheck.Gen.[(9, keys); (1, list string)] - -(** Whether [t1] is a prefix of [t2] *) -let rec is_prefix t1 t2 = - match (t1, t2) with - | ([], _) -> true - | (_, []) -> false - | (x1 :: rest1, x2 :: rest2) when x1 = x2 -> is_prefix rest1 rest2 - | _ -> false - -let test_split_key = - let fmt = - let pp_sep fmt () = Format.fprintf fmt "/" in - Format.pp_print_list ~pp_sep Format.pp_print_string - in - QCheck.Test.make - ~name:"[fst (split_key s)] is a prefix of [s]" - QCheck.(pair proxy_mode_arb (QCheck.make key_gen)) - @@ fun (mode, key) -> - match Proxy.ProtoRpc.split_key mode key with - | None -> true - | Some (shorter, _) -> - if is_prefix shorter key then true - else - QCheck.Test.fail_reportf - "Expected result of split_key to be a prefix of the input key. But \ - %a is not a prefix of %a." - fmt - shorter - fmt - key - -let () = - Alcotest.run - "tezos-lib-client-proxy" - [("proxy", Lib_test.Qcheck_helpers.qcheck_wrap [test_split_key])] diff --git a/src/proto_012_Psithaca/lib_client/tezos-client-012-Psithaca.opam b/src/proto_012_Psithaca/lib_client/tezos-client-012-Psithaca.opam deleted file mode 100644 index 3c3691b1606b..000000000000 --- a/src/proto_012_Psithaca/lib_client/tezos-client-012-Psithaca.opam +++ /dev/null @@ -1,31 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-shell-services" - "tezos-client-base-unix" - "tezos-mockup-registration" - "tezos-proxy" - "tezos-signer-backends" - "tezos-protocol-012-Psithaca-parameters" - "tezos-protocol-plugin-012-Psithaca" - "alcotest-lwt" { with-test & >= "1.1.0" } - "tezos-test-helpers" { with-test } - "tezos-base-test-helpers" { with-test } - "ppx_inline_test" - "qcheck-alcotest" { with-test } - "tezos-test-helpers" { with-test } -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol specific library for `tezos-client`" diff --git a/src/proto_012_Psithaca/lib_client_commands/.ocamlformat b/src/proto_012_Psithaca/lib_client_commands/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_client_commands/alpha_commands_registration.ml b/src/proto_012_Psithaca/lib_client_commands/alpha_commands_registration.ml deleted file mode 100644 index 9d4231dc9a12..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/alpha_commands_registration.ml +++ /dev/null @@ -1,38 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let () = - Client_commands.register Protocol.hash @@ fun network -> - List.map (Clic.map_command (new Protocol_client_context.wrap_full)) - @@ Client_proto_programs_commands.commands () - @ Client_proto_contracts_commands.commands () - @ Client_proto_context_commands.commands network () - @ Client_proto_multisig_commands.commands () - @ Client_proto_mockup_commands.commands () - @ Client_sapling_commands.commands () - @ Client_proto_utils_commands.commands () - @ Client_proto_stresstest_commands.commands network () - @ Client_proto_fa12_commands.commands () diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_context_commands.ml b/src/proto_012_Psithaca/lib_client_commands/client_proto_context_commands.ml deleted file mode 100644 index 077fadc50d62..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_context_commands.ml +++ /dev/null @@ -1,1958 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Client_proto_context -open Client_proto_contracts -open Client_keys -open Client_proto_args - -let encrypted_switch = - Clic.switch ~long:"encrypted" ~doc:"encrypt the key on-disk" () - -let report_michelson_errors ?(no_print_source = false) ~msg - (cctxt : #Client_context.printer) = function - | Error errs -> - cctxt#warning - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:(not no_print_source) - ~show_source:(not no_print_source) - ?parsed:None) - errs - >>= fun () -> - cctxt#error "%s" msg >>= fun () -> Lwt.return_none - | Ok data -> Lwt.return_some data - -let json_file_or_text_parameter = - Clic.parameter (fun _ p -> - match String.split ~limit:1 ':' p with - | ["text"; text] -> return (Ezjsonm.from_string text) - | ["file"; path] -> Lwt_utils_unix.Json.read_file path - | _ -> ( - if Sys.file_exists p then Lwt_utils_unix.Json.read_file p - else - try return (Ezjsonm.from_string p) - with Ezjsonm.Parse_error _ -> - failwith "Neither an existing file nor valid JSON: '%s'" p)) - -let non_negative_param = - Clic.parameter (fun _ s -> - match int_of_string_opt s with - | Some i when i >= 0 -> return i - | _ -> failwith "Parameter should be a non-negative integer literal") - -let block_hash_param = - Clic.parameter (fun _ s -> - try return (Block_hash.of_b58check_exn s) - with _ -> failwith "Parameter '%s' is an invalid block hash" s) - -let group = - { - Clic.name = "context"; - title = "Block contextual commands (see option -block)"; - } - -let alphanet = {Clic.name = "alphanet"; title = "Alphanet only commands"} - -let binary_description = - {Clic.name = "description"; title = "Binary Description"} - -let tez_of_string_exn index field s = - match Tez.of_string s with - | Some t -> return t - | None -> - failwith - "Invalid \xEA\x9C\xA9 notation at entry %i, field \"%s\": %s" - index - field - s - -let tez_of_opt_string_exn index field s = - match s with - | None -> return None - | Some s -> tez_of_string_exn index field s >>=? fun s -> return (Some s) - -let commands_ro () = - let open Clic in - [ - command - ~group - ~desc:"Access the timestamp of the block." - (args1 - (switch ~doc:"output time in seconds" ~short:'s' ~long:"seconds" ())) - (fixed ["get"; "timestamp"]) - (fun seconds (cctxt : Protocol_client_context.full) -> - Shell_services.Blocks.Header.shell_header - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - () - >>=? fun {timestamp = v; _} -> - (if seconds then cctxt#message "%Ld" (Time.Protocol.to_seconds v) - else cctxt#message "%s" (Time.Protocol.to_notation v)) - >>= fun () -> return_unit); - command - ~group - ~desc:"Lists all non empty contracts of the block." - no_options - (fixed ["list"; "contracts"]) - (fun () (cctxt : Protocol_client_context.full) -> - list_contract_labels cctxt ~chain:cctxt#chain ~block:cctxt#block - >>=? fun contracts -> - List.iter_s - (fun (alias, hash, kind) -> cctxt#message "%s%s%s" hash kind alias) - contracts - >>= fun () -> return_unit); - command - ~group - ~desc:"Lists cached contracts and their age in LRU ordering." - no_options - (prefixes ["list"; "cached"; "contracts"] @@ stop) - (fun () (cctxt : Protocol_client_context.full) -> - cached_contracts cctxt ~chain:cctxt#chain ~block:cctxt#block - >>=? fun keys -> - List.iter_s - (fun (key, size) -> - cctxt#message "%a %d" Alpha_context.Contract.pp key size) - keys - >>= fun () -> return_unit); - command - ~group - ~desc:"Get the key rank of a cache key." - no_options - (prefixes ["get"; "cached"; "contract"; "rank"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"contract" - @@ stop) - (fun () (_, contract) (cctxt : Protocol_client_context.full) -> - contract_rank cctxt ~chain:cctxt#chain ~block:cctxt#block contract - >>=? fun rank -> - match rank with - | None -> - cctxt#error - "Invalid contract: %a" - Alpha_context.Contract.pp - contract - >>= fun () -> return_unit - | Some rank -> cctxt#message "%d" rank >>= fun () -> return_unit); - command - ~group - ~desc:"Get cache contract size." - no_options - (prefixes ["get"; "cache"; "contract"; "size"] @@ stop) - (fun () (cctxt : Protocol_client_context.full) -> - contract_cache_size cctxt ~chain:cctxt#chain ~block:cctxt#block - >>=? fun t -> - cctxt#message "%d" t >>= fun () -> return_unit); - command - ~group - ~desc:"Get cache contract size limit." - no_options - (prefixes ["get"; "cache"; "contract"; "size"; "limit"] @@ stop) - (fun () (cctxt : Protocol_client_context.full) -> - contract_cache_size_limit cctxt ~chain:cctxt#chain ~block:cctxt#block - >>=? fun t -> - cctxt#message "%d" t >>= fun () -> return_unit); - command - ~group - ~desc:"Get the balance of a contract." - no_options - (prefixes ["get"; "balance"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun () (_, contract) (cctxt : Protocol_client_context.full) -> - get_balance cctxt ~chain:cctxt#chain ~block:cctxt#block contract - >>=? fun amount -> - cctxt#answer "%a %s" Tez.pp amount Client_proto_args.tez_sym - >>= fun () -> return_unit); - command - ~group - ~desc:"Get the storage of a contract." - (args1 (unparsing_mode_arg ~default:"Readable")) - (prefixes ["get"; "contract"; "storage"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun unparsing_mode (_, contract) (cctxt : Protocol_client_context.full) -> - get_storage - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~unparsing_mode - contract - >>=? function - | None -> cctxt#error "This is not a smart contract." - | Some storage -> - cctxt#answer "%a" Michelson_v1_printer.print_expr_unwrapped storage - >>= fun () -> return_unit); - command - ~group - ~desc: - "Get the value associated to a key in the big map storage of a \ - contract (deprecated)." - no_options - (prefixes ["get"; "big"; "map"; "value"; "for"] - @@ Clic.param ~name:"key" ~desc:"the key to look for" data_parameter - @@ prefixes ["of"; "type"] - @@ Clic.param ~name:"type" ~desc:"type of the key" data_parameter - @@ prefix "in" - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun () key key_type (_, contract) (cctxt : Protocol_client_context.full) -> - get_contract_big_map_value - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - contract - (key.expanded, key_type.expanded) - >>=? function - | None -> cctxt#error "No value associated to this key." - | Some value -> - cctxt#answer "%a" Michelson_v1_printer.print_expr_unwrapped value - >>= fun () -> return_unit); - command - ~group - ~desc:"Get a value in a big map." - (args1 (unparsing_mode_arg ~default:"Readable")) - (prefixes ["get"; "element"] - @@ Clic.param - ~name:"key" - ~desc:"the key to look for" - (Clic.parameter (fun _ s -> - return (Script_expr_hash.of_b58check_exn s))) - @@ prefixes ["of"; "big"; "map"] - @@ Clic.param - ~name:"big_map" - ~desc:"identifier of the big_map" - int_parameter - @@ stop) - (fun unparsing_mode key id (cctxt : Protocol_client_context.full) -> - get_big_map_value - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~unparsing_mode - (Big_map.Id.parse_z (Z.of_int id)) - key - >>=? fun value -> - cctxt#answer "%a" Michelson_v1_printer.print_expr_unwrapped value - >>= fun () -> return_unit); - command - ~group - ~desc:"Get the code of a contract." - (args1 (unparsing_mode_arg ~default:"Readable")) - (prefixes ["get"; "contract"; "code"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun unparsing_mode (_, contract) (cctxt : Protocol_client_context.full) -> - get_script - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~unparsing_mode - contract - >>=? function - | None -> cctxt#error "This is not a smart contract." - | Some {code; storage = _} -> ( - match Script_repr.force_decode code with - | Error errs -> - cctxt#error "%a" Environment.Error_monad.pp_trace errs - | Ok code -> - let {Michelson_v1_parser.source; _} = - Michelson_v1_printer.unparse_toplevel code - in - cctxt#answer "%s" source >>= return)); - command - ~group - ~desc:"Get the `BLAKE2B` script hash of a contract." - no_options - (prefixes ["get"; "contract"; "script"; "hash"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun () (_, contract) (cctxt : Protocol_client_context.full) -> - get_script_hash cctxt ~chain:cctxt#chain ~block:cctxt#block contract - >>= function - | Error errs -> cctxt#error "%a" pp_print_trace errs - | Ok None -> cctxt#error "This is not a smart contract." - | Ok (Some hash) -> cctxt#answer "%a" Script_expr_hash.pp hash >|= ok); - command - ~group - ~desc:"Get the type of an entrypoint of a contract." - no_options - (prefixes ["get"; "contract"; "entrypoint"; "type"; "of"] - @@ Clic.string ~name:"entrypoint" ~desc:"the entrypoint to describe" - @@ prefixes ["for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun () entrypoint (_, contract) (cctxt : Protocol_client_context.full) -> - Michelson_v1_entrypoints.contract_entrypoint_type - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - ~entrypoint - >>= Michelson_v1_entrypoints.print_entrypoint_type - cctxt - ~emacs:false - ~contract - ~entrypoint); - command - ~group - ~desc:"Get the entrypoint list of a contract." - no_options - (prefixes ["get"; "contract"; "entrypoints"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun () (_, contract) (cctxt : Protocol_client_context.full) -> - Michelson_v1_entrypoints.list_contract_entrypoints - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - >>= Michelson_v1_entrypoints.print_entrypoints_list - cctxt - ~emacs:false - ~contract); - command - ~group - ~desc:"Get the list of unreachable paths in a contract's parameter type." - no_options - (prefixes ["get"; "contract"; "unreachable"; "paths"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun () (_, contract) (cctxt : Protocol_client_context.full) -> - Michelson_v1_entrypoints.list_contract_unreachables - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - >>= Michelson_v1_entrypoints.print_unreachables - cctxt - ~emacs:false - ~contract); - command - ~group - ~desc:"Get the delegate of a contract." - no_options - (prefixes ["get"; "delegate"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun () (_, contract) (cctxt : Protocol_client_context.full) -> - Client_proto_contracts.get_delegate - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - contract - >>=? function - | None -> cctxt#message "none" >>= fun () -> return_unit - | Some delegate -> - Public_key_hash.rev_find cctxt delegate >>=? fun mn -> - Public_key_hash.to_source delegate >>=? fun m -> - cctxt#message - "%s (%s)" - m - (match mn with None -> "unknown" | Some n -> "known as " ^ n) - >>= fun () -> return_unit); - command - ~desc:"Get receipt for past operation" - (args1 - (default_arg - ~long:"check-previous" - ~placeholder:"num_blocks" - ~doc:"number of previous blocks to check" - ~default:"10" - non_negative_param)) - (prefixes ["get"; "receipt"; "for"] - @@ param - ~name:"operation" - ~desc:"Operation to be looked up" - (parameter (fun _ x -> - match Operation_hash.of_b58check_opt x with - | None -> Error_monad.failwith "Invalid operation hash: '%s'" x - | Some hash -> return hash)) - @@ stop) - (fun predecessors operation_hash (ctxt : Protocol_client_context.full) -> - display_receipt_for_operation - ctxt - ~chain:ctxt#chain - ~predecessors - operation_hash - >>=? fun _ -> return_unit); - command - ~group - ~desc:"Summarize the current voting period" - no_options - (fixed ["show"; "voting"; "period"]) - (fun () (cctxt : Protocol_client_context.full) -> - get_period_info ~chain:cctxt#chain ~block:cctxt#block cctxt - >>=? fun info -> - cctxt#message - "Current period: %a\nBlocks remaining until end of period: %ld" - Data_encoding.Json.pp - (Data_encoding.Json.construct - Alpha_context.Voting_period.kind_encoding - info.current_period_kind) - info.remaining - >>= fun () -> - Shell_services.Protocol.list cctxt >>=? fun known_protos -> - get_proposals ~chain:cctxt#chain ~block:cctxt#block cctxt - >>=? fun props -> - let ranks = - Environment.Protocol_hash.Map.bindings props - |> List.sort (fun (_, v1) (_, v2) -> Int32.(compare v2 v1)) - in - let print_proposal = function - | None -> - cctxt#message "The current proposal has already been cleared." - (* The proposal is cleared on the last block of adoption period, and - also on the last block of the exploration and promotion - periods when the proposal is not approved *) - | Some proposal -> - cctxt#message "Current proposal: %a" Protocol_hash.pp proposal - in - match info.current_period_kind with - | Proposal -> - (* the current proposals are cleared on the last block of the - proposal period *) - if info.remaining <> 0l then - cctxt#answer - "Current proposals:%t" - Format.( - fun ppf -> - pp_print_cut ppf () ; - pp_open_vbox ppf 0 ; - List.iter - (fun (p, w) -> - fprintf - ppf - "* %a %ld (%sknown by the node)@." - Protocol_hash.pp - p - w - (if List.mem ~equal:Protocol_hash.equal p known_protos - then "" - else "not ")) - ranks ; - pp_close_box ppf ()) - >>= fun () -> return_unit - else - cctxt#message "The proposals have already been cleared." - >>= fun () -> return_unit - | Exploration | Promotion -> - print_proposal info.current_proposal >>= fun () -> - (* the ballots are cleared on the last block of these periods *) - if info.remaining <> 0l then - get_ballots_info ~chain:cctxt#chain ~block:cctxt#block cctxt - >>=? fun ballots_info -> - cctxt#answer - "Ballots: %a@,\ - Current participation %.2f%%, necessary quorum %.2f%%@,\ - Current in favor %ld, needed supermajority %ld" - Data_encoding.Json.pp - (Data_encoding.Json.construct - Vote.ballots_encoding - ballots_info.ballots) - (Int32.to_float ballots_info.participation /. 100.) - (Int32.to_float ballots_info.current_quorum /. 100.) - ballots_info.ballots.yay - ballots_info.supermajority - >>= fun () -> return_unit - else - cctxt#message "The ballots have already been cleared." - >>= fun () -> return_unit - | Cooldown -> - print_proposal info.current_proposal >>= fun () -> return_unit - | Adoption -> - print_proposal info.current_proposal >>= fun () -> return_unit); - command - ~group:binary_description - ~desc:"Describe unsigned block header" - no_options - (fixed ["describe"; "unsigned"; "block"; "header"]) - (fun () (cctxt : Protocol_client_context.full) -> - cctxt#message - "%a" - Data_encoding.Binary_schema.pp - (Data_encoding.Binary.describe - Alpha_context.Block_header.unsigned_encoding) - >>= fun () -> return_unit); - command - ~group:binary_description - ~desc:"Describe unsigned operation" - no_options - (fixed ["describe"; "unsigned"; "operation"]) - (fun () (cctxt : Protocol_client_context.full) -> - cctxt#message - "%a" - Data_encoding.Binary_schema.pp - (Data_encoding.Binary.describe - Alpha_context.Operation.unsigned_encoding) - >>= fun () -> return_unit); - command - ~group - ~desc:"Get the frozen deposits limit of a delegate." - no_options - (prefixes ["get"; "deposits"; "limit"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source delegate" - @@ stop) - (fun () (_, contract) (cctxt : Protocol_client_context.full) -> - match Contract.is_implicit contract with - | None -> - cctxt#error - "Cannot change deposits limit on contract %a. This operation is \ - invalid on originated contracts." - Contract.pp - contract - | Some delegate -> ( - get_frozen_deposits_limit - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - delegate - >>=? function - | None -> cctxt#answer "unlimited" >>= return - | Some limit -> - cctxt#answer "%a %s" Tez.pp limit Client_proto_args.tez_sym - >>= return)); - ] - -(* ----------------------------------------------------------------------------*) -(* After the activation of a new version of the protocol, the older protocols - are only kept in the code base to replay the history of the chain and to query - old states. - - The commands that are not useful anymore in the old protocols are removed, - this is called protocol freezing. The commands below are those that can be - removed during protocol freezing. - - The rule of thumb to know if a command should be kept at freezing is that all - commands that modify the state of the chain should be removed and conversely - all commands that are used to query the context should be kept. For this - reason, we call read-only (or RO for short) the commands that are kept and - read-write (or RW for short) the commands that are removed. - - There are some exceptions to this rule however, for example the command - "tezos-client wait for to be included" is classified as RW despite having - no effect on the context because it has no use case once all RW commands are - removed. - - Keeping this in mind, the developer should decide where to add a new command. - At the end of the file, RO and RW commands are concatenated into one list that - is then exported in the mli file. *) -(* ----------------------------------------------------------------------------*) - -let dry_run_switch = - Clic.switch - ~long:"dry-run" - ~short:'D' - ~doc:"don't inject the operation, just display it" - () - -let verbose_signing_switch = - Clic.switch - ~long:"verbose-signing" - ~doc:"display extra information before signing the operation" - () - -let simulate_switch = - Clic.switch - ~long:"simulation" - ~doc: - "Simulate the execution of the command, without needing any signatures." - () - -let transfer_command amount source destination cctxt - ( fee, - dry_run, - verbose_signing, - simulation, - gas_limit, - storage_limit, - counter, - arg, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap, - entrypoint ) = - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - (match Contract.is_implicit source with - | None -> - let contract = source in - Managed_contract.get_contract_manager cctxt source >>=? fun source -> - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - Managed_contract.transfer - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~simulation - ~fee_parameter - ?fee - ~contract - ~source - ~src_pk - ~src_sk - ~destination - ?entrypoint - ?arg - ~amount - ?gas_limit - ?storage_limit - ?counter - () - | Some source -> - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - transfer - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~simulation - ~verbose_signing - ~fee_parameter - ~source - ?fee - ~src_pk - ~src_sk - ~destination - ?entrypoint - ?arg - ~amount - ?gas_limit - ?storage_limit - ?counter - ()) - >>= report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit - -let prepare_batch_operation cctxt ?arg ?fee ?gas_limit ?storage_limit - ?entrypoint source index batch = - Client_proto_contracts.ContractAlias.find_destination cctxt batch.destination - >>=? fun (_, destination) -> - tez_of_string_exn index "amount" batch.amount >>=? fun amount -> - tez_of_opt_string_exn index "fee" batch.fee >>=? fun batch_fee -> - let fee = Option.either batch_fee fee in - let arg = Option.either batch.arg arg in - let gas_limit = Option.either batch.gas_limit gas_limit in - let storage_limit = Option.either batch.storage_limit storage_limit in - let entrypoint = Option.either batch.entrypoint entrypoint in - parse_arg_transfer arg >>=? fun parameters -> - (match Contract.is_implicit source with - | None -> - Managed_contract.build_transaction_operation - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract:source - ~destination - ?entrypoint - ?arg - ~amount - ?fee - ?gas_limit - ?storage_limit - () - | Some _ -> - return - (build_transaction_operation - ~amount - ~parameters - ?entrypoint - ?fee - ?gas_limit - ?storage_limit - destination)) - >>=? fun operation -> - return (Annotated_manager_operation.Annotated_manager_operation operation) - -let commands_network network () = - let open Clic in - match network with - | Some `Testnet | None -> - [ - command - ~group - ~desc:"Register and activate an Alphanet/Zeronet faucet account." - (args2 (Secret_key.force_switch ()) encrypted_switch) - (prefixes ["activate"; "account"] - @@ Secret_key.fresh_alias_param - @@ prefixes ["with"] - @@ param - ~name:"activation_key" - ~desc: - "Activate an Alphanet/Zeronet faucet account from the JSON \ - (file or directly inlined)." - json_file_or_text_parameter - @@ stop) - (fun (force, encrypted) name activation_json cctxt -> - Secret_key.of_fresh cctxt force name >>=? fun name -> - match - Data_encoding.Json.destruct - Client_proto_context.activation_key_encoding - activation_json - with - | exception (Data_encoding.Json.Cannot_destruct _ as exn) -> - Format.kasprintf - (fun s -> failwith "%s" s) - "Invalid activation file: %a %a" - (fun ppf -> Data_encoding.Json.print_error ppf) - exn - Data_encoding.Json.pp - activation_json - | key -> - activate_account - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~encrypted - ~force - key - name - >>=? fun _res -> return_unit); - ] - | Some `Mainnet -> - [ - command - ~group - ~desc:"Activate a fundraiser account." - (args1 dry_run_switch) - (prefixes ["activate"; "fundraiser"; "account"] - @@ Public_key_hash.alias_param - @@ prefixes ["with"] - @@ param - ~name:"code" - (Clic.parameter (fun _ctx code -> - match - Blinded_public_key_hash.activation_code_of_hex code - with - | Some c -> return c - | None -> failwith "Hexadecimal parsing failure")) - ~desc:"Activation code obtained from the Tezos foundation." - @@ stop) - (fun dry_run (name, _pkh) code cctxt -> - activate_existing_account - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - name - code - >>=? fun _res -> return_unit); - ] - -let commands_rw () = - let open Client_proto_programs in - let open Tezos_micheline in - let open Clic in - [ - command - ~group - ~desc:"Set the delegate of a contract." - (args10 - fee_arg - dry_run_switch - verbose_signing_switch - simulate_switch - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["set"; "delegate"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ prefix "to" - @@ Public_key_hash.source_param - ~name:"dlgt" - ~desc:"new delegate of the contract" - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - simulation, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, contract) - delegate - (cctxt : Protocol_client_context.full) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - match Contract.is_implicit contract with - | None -> - Managed_contract.get_contract_manager cctxt contract - >>=? fun source -> - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - Managed_contract.set_delegate - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~simulation - ~fee_parameter - ?fee - ~source - ~src_pk - ~src_sk - contract - (Some delegate) - >>= fun errors -> - report_michelson_errors - ~no_print_source:true - ~msg:"Setting delegate through entrypoints failed." - cctxt - errors - >>= fun _ -> return_unit - | Some mgr -> - Client_keys.get_key cctxt mgr >>=? fun (_, src_pk, manager_sk) -> - set_delegate - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~simulation - ~fee_parameter - ?fee - mgr - (Some delegate) - ~src_pk - ~manager_sk - >>=? fun _ -> return_unit); - command - ~group - ~desc:"Withdraw the delegate from a contract." - (args9 - fee_arg - dry_run_switch - verbose_signing_switch - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["withdraw"; "delegate"; "from"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, contract) - (cctxt : Protocol_client_context.full) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - match Contract.is_implicit contract with - | None -> - Managed_contract.get_contract_manager cctxt contract - >>=? fun source -> - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - Managed_contract.set_delegate - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~fee_parameter - ?fee - ~source - ~src_pk - ~src_sk - contract - None - >>= fun errors -> - report_michelson_errors - ~no_print_source:true - ~msg:"Withdrawing delegate through entrypoints failed." - cctxt - errors - >>= fun _ -> return_unit - | Some mgr -> - Client_keys.get_key cctxt mgr >>=? fun (_, src_pk, manager_sk) -> - set_delegate - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~fee_parameter - mgr - None - ?fee - ~src_pk - ~manager_sk - >>= fun _ -> return_unit); - command - ~group - ~desc:"Launch a smart contract on the blockchain." - (args15 - fee_arg - dry_run_switch - verbose_signing_switch - gas_limit_arg - storage_limit_arg - delegate_arg - (Client_keys.force_switch ()) - init_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["originate"; "contract"] - @@ RawContractAlias.fresh_alias_param - ~name:"new" - ~desc:"name of the new contract" - @@ prefix "transferring" - @@ tez_param ~name:"qty" ~desc:"amount taken from source" - @@ prefix "from" - @@ ContractAlias.destination_param - ~name:"src" - ~desc:"name of the source contract" - @@ prefix "running" - @@ Program.source_param - ~name:"prg" - ~desc: - "script of the account\n\ - Combine with -init if the storage type is not unit." - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - delegate, - force, - initial_storage, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - alias_name - balance - (_, source) - program - (cctxt : Protocol_client_context.full) -> - RawContractAlias.of_fresh cctxt force alias_name >>=? fun alias_name -> - Lwt.return (Micheline_parser.no_parsing_error program) - >>=? fun {expanded = code; _} -> - match Contract.is_implicit source with - | None -> - failwith - "only implicit accounts can be the source of an origination" - | Some source -> ( - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - originate_contract - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ?fee - ?gas_limit - ?storage_limit - ~delegate - ~initial_storage - ~balance - ~source - ~src_pk - ~src_sk - ~code - ~fee_parameter - () - >>= fun errors -> - report_michelson_errors - ~no_print_source - ~msg:"origination simulation failed" - cctxt - errors - >>= function - | None -> return_unit - | Some (_res, contract) -> - if dry_run then return_unit - else - save_contract ~force cctxt alias_name contract >>=? fun () -> - return_unit)); - command - ~group - ~desc: - "Execute multiple transfers from a single source account.\n\ - If one of the transfers fails, none of them get executed." - (args16 - default_fee_arg - dry_run_switch - verbose_signing_switch - simulate_switch - default_gas_limit_arg - default_storage_limit_arg - counter_arg - default_arg_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg - default_entrypoint_arg) - (prefixes ["multiple"; "transfers"; "from"] - @@ ContractAlias.destination_param - ~name:"src" - ~desc:"name of the source contract" - @@ prefix "using" - @@ param - ~name:"transfers.json" - ~desc: - "List of operations originating from the source contract in JSON \ - format (from a file or directly inlined). The input JSON must be \ - an array of objects of the form: '[ {\"destination\": dst, \ - \"amount\": qty (, : ...) } (, ...) ]', where an \ - optional can either be \"fee\", \"gas-limit\", \ - \"storage-limit\", \"arg\", or \"entrypoint\"." - json_file_or_text_parameter - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - simulation, - gas_limit, - storage_limit, - counter, - arg, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap, - entrypoint ) - (_, source) - operations_json - cctxt -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - let prepare i = - prepare_batch_operation - cctxt - ?arg - ?fee - ?gas_limit - ?storage_limit - ?entrypoint - source - i - in - match - Data_encoding.Json.destruct - (Data_encoding.list - Client_proto_context.batch_transfer_operation_encoding) - operations_json - with - | [] -> failwith "Empty operation list" - | operations -> - (match Contract.is_implicit source with - | None -> - Managed_contract.get_contract_manager cctxt source - >>=? fun source -> - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - return (source, src_pk, src_sk) - | Some source -> - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - return (source, src_pk, src_sk)) - >>=? fun (source, src_pk, src_sk) -> - List.mapi_ep prepare operations >>=? fun contents -> - let (Manager_list contents) = - Annotated_manager_operation.manager_of_list contents - in - Injection.inject_manager_operation - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~simulation - ~source - ~fee:(Limit.of_option fee) - ~gas_limit:(Limit.of_option gas_limit) - ~storage_limit:(Limit.of_option storage_limit) - ?counter - ~src_pk - ~src_sk - ~fee_parameter - contents - >>= report_michelson_errors - ~no_print_source - ~msg:"multiple transfers simulation failed" - cctxt - >>= fun _ -> return_unit - | exception (Data_encoding.Json.Cannot_destruct (path, exn2) as exn) - -> ( - match (path, operations_json) with - | ([`Index n], `A lj) -> ( - match List.nth_opt lj n with - | Some j -> - failwith - "Invalid transfer at index %i: %a %a" - n - (fun ppf -> Data_encoding.Json.print_error ppf) - exn2 - Data_encoding.Json.pp - j - | _ -> - failwith - "Invalid transfer at index %i: %a" - n - (fun ppf -> Data_encoding.Json.print_error ppf) - exn2) - | _ -> - failwith - "Invalid transfer file: %a %a" - (fun ppf -> Data_encoding.Json.print_error ppf) - exn - Data_encoding.Json.pp - operations_json)); - command - ~group - ~desc:"Transfer tokens / call a smart contract." - (args16 - fee_arg - dry_run_switch - verbose_signing_switch - simulate_switch - gas_limit_arg - storage_limit_arg - counter_arg - arg_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg - entrypoint_arg) - (prefixes ["transfer"] - @@ tez_param ~name:"qty" ~desc:"amount taken from source" - @@ prefix "from" - @@ ContractAlias.destination_param - ~name:"src" - ~desc:"name of the source contract" - @@ prefix "to" - @@ ContractAlias.destination_param - ~name:"dst" - ~desc:"name/literal of the destination contract" - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - simulation, - gas_limit, - storage_limit, - counter, - arg, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap, - entrypoint ) - amount - (_, source) - (_, destination) - cctxt -> - transfer_command - amount - source - destination - cctxt - ( fee, - dry_run, - verbose_signing, - simulation, - gas_limit, - storage_limit, - counter, - arg, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap, - entrypoint )); - command - ~group - ~desc:"Register a global constant" - (args12 - fee_arg - dry_run_switch - verbose_signing_switch - simulate_switch - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - storage_limit_arg - counter_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["register"; "global"; "constant"] - @@ global_constant_param - ~name:"expression" - ~desc: - "Michelson expression to register. Note the value is not \ - typechecked before registration." - @@ prefix "from" - @@ ContractAlias.destination_param - ~name:"src" - ~desc:"name of the account registering the global constant" - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - simulation, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - storage_limit, - counter, - force_low_fee, - fee_cap, - burn_cap ) - global_constant_str - (_, source) - cctxt -> - match Contract.is_implicit source with - | None -> - failwith "Only implicit accounts can register global constants" - | Some source -> - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - register_global_constant - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?dry_run:(Some dry_run) - ?verbose_signing:(Some verbose_signing) - ?fee - ?storage_limit - ?counter - ?confirmations:cctxt#confirmations - ~simulation - ~source - ~src_pk - ~src_sk - ~fee_parameter - ~constant:global_constant_str - () - >>= fun errors -> - report_michelson_errors - ~no_print_source:false - ~msg:"register global constant simulation failed" - cctxt - errors - >>= fun _ -> return_unit); - command - ~group - ~desc:"Call a smart contract (same as 'transfer 0')." - (args16 - fee_arg - dry_run_switch - verbose_signing_switch - simulate_switch - gas_limit_arg - storage_limit_arg - counter_arg - arg_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg - entrypoint_arg) - (prefixes ["call"] - @@ ContractAlias.destination_param - ~name:"dst" - ~desc:"name/literal of the destination contract" - @@ prefix "from" - @@ ContractAlias.destination_param - ~name:"src" - ~desc:"name of the source contract" - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - simulation, - gas_limit, - storage_limit, - counter, - arg, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap, - entrypoint ) - (_, destination) - (_, source) - cctxt -> - let amount = Tez.zero in - transfer_command - amount - source - destination - cctxt - ( fee, - dry_run, - verbose_signing, - simulation, - gas_limit, - storage_limit, - counter, - arg, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap, - entrypoint )); - command - ~group - ~desc:"Reveal the public key of the contract manager." - (args9 - fee_arg - dry_run_switch - verbose_signing_switch - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["reveal"; "key"; "for"] - @@ ContractAlias.alias_param - ~name:"src" - ~desc:"name of the source contract" - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, source) - cctxt -> - match Contract.is_implicit source with - | None -> failwith "only implicit accounts can be revealed" - | Some source -> - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - reveal - cctxt - ~dry_run - ~verbose_signing - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~source - ?fee - ~src_pk - ~src_sk - ~fee_parameter - () - >>=? fun _res -> return_unit); - command - ~group - ~desc:"Register the public key hash as a delegate." - (args9 - fee_arg - dry_run_switch - verbose_signing_switch - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["register"; "key"] - @@ Public_key_hash.source_param ~name:"mgr" ~desc:"the delegate key" - @@ prefixes ["as"; "delegate"] - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - src_pkh - cctxt -> - Client_keys.get_key cctxt src_pkh >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - register_as_delegate - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~fee_parameter - ~verbose_signing - ?fee - ~manager_sk:src_sk - src_pk - >>= function - | Ok _ -> return_unit - | Error [Environment.Ecoproto_error Delegate_storage.Active_delegate] -> - cctxt#message "Delegate already activated." >>= fun () -> - return_unit - | Error el -> Lwt.return_error el); - command - ~desc:"Wait until an operation is included in a block" - (args3 - (default_arg - ~long:"confirmations" - ~placeholder:"num_blocks" - ~doc: - "wait until 'N' additional blocks after the operation appears in \ - the considered chain" - ~default:"0" - non_negative_param) - (default_arg - ~long:"check-previous" - ~placeholder:"num_blocks" - ~doc:"number of previous blocks to check" - ~default:"10" - non_negative_param) - (arg - ~long:"branch" - ~placeholder:"block_hash" - ~doc: - "hash of the oldest block where we should look for the operation" - block_hash_param)) - (prefixes ["wait"; "for"] - @@ param - ~name:"operation" - ~desc:"Operation to be included" - (parameter (fun _ x -> - match Operation_hash.of_b58check_opt x with - | None -> Error_monad.failwith "Invalid operation hash: '%s'" x - | Some hash -> return hash)) - @@ prefixes ["to"; "be"; "included"] - @@ stop) - (fun (confirmations, predecessors, branch) - operation_hash - (ctxt : Protocol_client_context.full) -> - Client_confirmations.wait_for_operation_inclusion - ctxt - ~chain:ctxt#chain - ~confirmations - ~predecessors - ?branch - operation_hash - >>=? fun _ -> return_unit); - command - ~group - ~desc:"Submit protocol proposals" - (args3 - dry_run_switch - verbose_signing_switch - (switch - ~doc: - "Do not fail when the checks that try to prevent the user from \ - shooting themselves in the foot do." - ~long:"force" - ())) - (prefixes ["submit"; "proposals"; "for"] - @@ ContractAlias.destination_param - ~name:"delegate" - ~desc:"the delegate who makes the proposal" - @@ seq_of_param - (param - ~name:"proposal" - ~desc:"the protocol hash proposal to be submitted" - (parameter (fun _ x -> - match Protocol_hash.of_b58check_opt x with - | None -> - Error_monad.failwith "Invalid proposal hash: '%s'" x - | Some hash -> return hash)))) - (fun (dry_run, verbose_signing, force) - (_name, source) - proposals - (cctxt : Protocol_client_context.full) -> - match Contract.is_implicit source with - | None -> failwith "only implicit accounts can submit proposals" - | Some src_pkh -> ( - Client_keys.get_key cctxt src_pkh - >>=? fun (src_name, _src_pk, src_sk) -> - get_period_info - (* Find period info of the successor, because the operation will - be injected on the next block at the earliest *) - ~successor:true - ~chain:cctxt#chain - ~block:cctxt#block - cctxt - >>=? fun info -> - (match info.current_period_kind with - | Proposal -> return_unit - | _ -> cctxt#error "Not in a proposal period") - >>=? fun () -> - Shell_services.Protocol.list cctxt >>=? fun known_protos -> - get_proposals ~chain:cctxt#chain ~block:cctxt#block cctxt - >>=? fun known_proposals -> - Alpha_services.Voting.listings cctxt (cctxt#chain, cctxt#block) - >>=? fun listings -> - (* for a proposal to be valid it must either a protocol that was already - proposed by somebody else or a protocol known by the node, because - the user is the first proposer and just injected it with - tezos-admin-client *) - let check_proposals proposals : bool tzresult Lwt.t = - let errors = ref [] in - let error ppf = - Format.kasprintf (fun s -> errors := s :: !errors) ppf - in - if proposals = [] then error "Empty proposal list." ; - if - Compare.List_length_with.( - proposals > Constants.max_proposals_per_delegate) - then - error - "Too many proposals: %d > %d." - (List.length proposals) - Constants.max_proposals_per_delegate ; - (match - Base.List.find_all_dups - ~compare:Protocol_hash.compare - proposals - with - | [] -> () - | dups -> - error - "There %s: %a." - (if Compare.List_length_with.(dups = 1) then - "is a duplicate proposal" - else "are duplicate proposals") - Format.( - pp_print_list - ~pp_sep:(fun ppf () -> pp_print_string ppf ", ") - Protocol_hash.pp) - dups) ; - List.iter - (fun (p : Protocol_hash.t) -> - if - List.mem ~equal:Protocol_hash.equal p known_protos - || Environment.Protocol_hash.Map.mem p known_proposals - then () - else - error - "Protocol %a is not a known proposal." - Protocol_hash.pp - p) - proposals ; - if - not - (List.exists - (fun (pkh, _) -> - Signature.Public_key_hash.equal pkh src_pkh) - listings) - then - error - "Public-key-hash `%a` from account `%s` does not appear to \ - have voting rights." - Signature.Public_key_hash.pp - src_pkh - src_name ; - if !errors <> [] then - cctxt#message - "There %s with the submission:%t" - (if Compare.List_length_with.(!errors = 1) then "is an issue" - else "are issues") - Format.( - fun ppf -> - pp_print_cut ppf () ; - pp_open_vbox ppf 0 ; - List.iter - (fun msg -> - pp_open_hovbox ppf 2 ; - pp_print_string ppf "* " ; - pp_print_text ppf msg ; - pp_close_box ppf () ; - pp_print_cut ppf ()) - !errors ; - pp_close_box ppf ()) - >>= fun () -> return_false - else return_true - in - check_proposals proposals >>=? fun all_valid -> - (if all_valid then cctxt#message "All proposals are valid." - else if force then - cctxt#message - "Some proposals are not valid, but `--force` was used." - else cctxt#error "Submission failed because of invalid proposals.") - >>= fun () -> - submit_proposals - ~dry_run - ~verbose_signing - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~src_sk - src_pkh - proposals - >>= function - | Ok _res -> return_unit - | Error errs -> - (match errs with - | [ - Unregistered_error - (`O [("kind", `String "generic"); ("error", `String msg)]); - ] -> - cctxt#message - "Error:@[@.%a@]" - Format.pp_print_text - (String.split_on_char ' ' msg - |> List.filter (function "" | "\n" -> false | _ -> true) - |> String.concat " " - |> String.map (function '\n' | '\t' -> ' ' | c -> c)) - | el -> cctxt#message "Error:@ %a" pp_print_trace el) - >>= fun () -> failwith "Failed to submit proposals")); - command - ~group - ~desc:"Submit a ballot" - (args2 verbose_signing_switch dry_run_switch) - (prefixes ["submit"; "ballot"; "for"] - @@ ContractAlias.destination_param - ~name:"delegate" - ~desc:"the delegate who votes" - @@ param - ~name:"proposal" - ~desc:"the protocol hash proposal to vote for" - (parameter (fun _ x -> - match Protocol_hash.of_b58check_opt x with - | None -> failwith "Invalid proposal hash: '%s'" x - | Some hash -> return hash)) - @@ param - ~name:"ballot" - ~desc:"the ballot value (yea/yay, nay, or pass)" - (parameter - ~autocomplete:(fun _ -> return ["yea"; "nay"; "pass"]) - (fun _ s -> - (* We should have [Vote.of_string]. *) - match String.lowercase_ascii s with - | "yay" | "yea" -> return Vote.Yay - | "nay" -> return Vote.Nay - | "pass" -> return Vote.Pass - | s -> failwith "Invalid ballot: '%s'" s)) - @@ stop) - (fun (verbose_signing, dry_run) - (_name, source) - proposal - ballot - (cctxt : Protocol_client_context.full) -> - match Contract.is_implicit source with - | None -> failwith "only implicit accounts can submit ballot" - | Some src_pkh -> - Client_keys.get_key cctxt src_pkh - >>=? fun (_src_name, _src_pk, src_sk) -> - get_period_info - (* Find period info of the successor, because the operation will - be injected on the next block at the earliest *) - ~successor:true - ~chain:cctxt#chain - ~block:cctxt#block - cctxt - >>=? fun info -> - (match info.current_period_kind with - | Exploration | Promotion -> return_unit - | _ -> cctxt#error "Not in Exploration or Promotion period") - >>=? fun () -> - submit_ballot - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~src_sk - src_pkh - ~verbose_signing - ~dry_run - proposal - ballot - >>=? fun _res -> return_unit); - command - ~group - ~desc:"Set the deposits limit of a registered delegate." - (args10 - fee_arg - dry_run_switch - verbose_signing_switch - simulate_switch - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["set"; "deposits"; "limit"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ prefix "to" - @@ tez_param - ~name:"deposits limit" - ~desc:"the maximum amount of frozen deposits" - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - simulation, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, contract) - limit - (cctxt : Protocol_client_context.full) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - match Contract.is_implicit contract with - | None -> - cctxt#error - "Cannot change deposits limit on contract %a. This operation is \ - invalid on originated contracts or unregistered delegate \ - contracts." - Contract.pp - contract - | Some mgr -> - Client_keys.get_key cctxt mgr >>=? fun (_, src_pk, manager_sk) -> - set_deposits_limit - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~simulation - ~fee_parameter - ?fee - mgr - ~src_pk - ~manager_sk - (Some limit) - >>=? fun _ -> return_unit); - command - ~group - ~desc:"Remove the deposits limit of a registered delegate." - (args10 - fee_arg - dry_run_switch - verbose_signing_switch - simulate_switch - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["unset"; "deposits"; "limit"; "for"] - @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - simulation, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, contract) - (cctxt : Protocol_client_context.full) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - match Contract.is_implicit contract with - | None -> - cctxt#error - "Cannot change deposits limit on contract %a. This operation is \ - invalid on originated contracts or unregistered delegate \ - contracts." - Contract.pp - contract - | Some mgr -> - Client_keys.get_key cctxt mgr >>=? fun (_, src_pk, manager_sk) -> - set_deposits_limit - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~simulation - ~fee_parameter - ?fee - mgr - ~src_pk - ~manager_sk - None - >>=? fun _ -> return_unit); - ] - -let commands network () = - commands_rw () @ commands_network network () @ commands_ro () diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_contracts_commands.ml b/src/proto_012_Psithaca/lib_client_commands/client_proto_contracts_commands.ml deleted file mode 100644 index e23e8ad821e2..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_contracts_commands.ml +++ /dev/null @@ -1,87 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Client_proto_contracts - -let group = - { - Clic.name = "contracts"; - title = "Commands for managing the record of known contracts"; - } - -let commands () = - let open Clic in - [ - command - ~group - ~desc:"Add a contract to the wallet." - (args1 (RawContractAlias.force_switch ())) - (prefixes ["remember"; "contract"] - @@ RawContractAlias.fresh_alias_param @@ RawContractAlias.source_param - @@ stop) - (fun force name hash cctxt -> - RawContractAlias.of_fresh cctxt force name >>=? fun name -> - RawContractAlias.add ~force cctxt name hash); - command - ~group - ~desc:"Remove a contract from the wallet." - no_options - (prefixes ["forget"; "contract"] @@ RawContractAlias.alias_param @@ stop) - (fun () (name, _) cctxt -> RawContractAlias.del cctxt name); - command - ~group - ~desc:"Lists all known contracts in the wallet." - no_options - (fixed ["list"; "known"; "contracts"]) - (fun () (cctxt : Protocol_client_context.full) -> - list_contracts cctxt >>=? fun contracts -> - List.iter_es - (fun (prefix, alias, contract) -> - cctxt#message - "%s%s: %s" - prefix - alias - (Contract.to_b58check contract) - >>= return) - contracts); - command - ~group - ~desc:"Forget the entire wallet of known contracts." - (args1 (RawContractAlias.force_switch ())) - (fixed ["forget"; "all"; "contracts"]) - (fun force cctxt -> - fail_unless force (error_of_fmt "this can only used with option -force") - >>=? fun () -> RawContractAlias.set cctxt []); - command - ~group - ~desc:"Display a contract from the wallet." - no_options - (prefixes ["show"; "known"; "contract"] - @@ RawContractAlias.alias_param @@ stop) - (fun () (_, contract) (cctxt : Protocol_client_context.full) -> - cctxt#message "%a\n%!" Contract.pp contract >>= fun () -> return_unit); - ] diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_fa12_commands.ml b/src/proto_012_Psithaca/lib_client_commands/client_proto_fa12_commands.ml deleted file mode 100644 index fe6703bbb7fa..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_fa12_commands.ml +++ /dev/null @@ -1,764 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Client_proto_args - -let group = - { - Clic.name = "tokens"; - title = "Commands for managing FA1.2-compatible smart contracts"; - } - -let alias_param = Client_proto_contracts.ContractAlias.destination_param - -let token_contract_param () = - alias_param - ~name:"contract" - ~desc:"name or address of the FA1.2-compatible contract" - -let from_param () = - alias_param ~name:"from" ~desc:"name or address of the sender" - -let to_param () = alias_param ~name:"to" ~desc:"name or address of the receiver" - -let amount_param () = - Clic.param - ~name:"amount" - ~desc:"number of tokens" - (Clic.parameter (fun _ s -> - try - let v = Z.of_string s in - assert (Compare.Z.(v >= Z.zero)) ; - return v - with _ -> failwith "invalid amount (must be a non-negative number)")) - -let tez_amount_arg = - tez_arg ~default:"0" ~parameter:"tez-amount" ~doc:"amount in \xEA\x9C\xA9" - -let as_arg = - Client_proto_contracts.ContractAlias.destination_arg - ~name:"as" - ~doc:"name or address of the caller of the contract" - () - -let payer_arg = - Client_proto_contracts.ContractAlias.destination_arg - ~name:"payer" - ~doc:"name of the payer (i.e. SOURCE) contract for the transaction" - () - -let callback_entrypoint_arg = - Clic.arg - ~doc:"Entrypoint the view should use to callback to" - ~long:"callback-entrypoint" - ~placeholder:"name" - string_parameter - -let contract_call_options = - Clic.args14 - tez_amount_arg - fee_arg - Client_proto_context_commands.dry_run_switch - Client_proto_context_commands.verbose_signing_switch - gas_limit_arg - storage_limit_arg - counter_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg - -let contract_view_options = - Clic.args15 - callback_entrypoint_arg - tez_amount_arg - fee_arg - Client_proto_context_commands.dry_run_switch - Client_proto_context_commands.verbose_signing_switch - gas_limit_arg - storage_limit_arg - counter_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg - -let view_options = - Clic.args3 - run_gas_limit_arg - payer_arg - (unparsing_mode_arg ~default:"Readable") - -let dummy_callback = Contract.implicit_contract Signature.Public_key_hash.zero - -let get_contract_caller_keys cctxt caller = - match Contract.is_implicit caller with - | None -> - failwith "only implicit accounts can be the source of a contract call" - | Some source -> - Client_keys.get_key cctxt source >>=? fun (_, caller_pk, caller_sk) -> - return (source, caller_pk, caller_sk) - -let commands_ro () : #Protocol_client_context.full Clic.command list = - Clic. - [ - command - ~group - ~desc:"Check that a contract is FA1.2-compatible." - no_options - (prefixes ["check"; "contract"] - @@ token_contract_param () - @@ prefixes ["implements"; "fa1.2"] - @@ stop) - (fun () (_, contract) (cctxt : #Protocol_client_context.full) -> - Client_proto_fa12.contract_has_fa12_interface - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - () - >>=? fun _ -> - Format.printf - "Contract %a has an FA1.2 interface.\n%!" - Contract.pp - contract ; - return_unit); - command - ~group - ~desc:"Ask for an address's balance offchain" - view_options - (prefixes ["from"; "fa1.2"; "contract"] - @@ token_contract_param () - @@ prefixes ["get"; "balance"; "for"] - @@ alias_param - ~name:"from" - ~desc: - "name or address of the account to lookup (also the source \ - contract)" - @@ stop) - (fun (gas, payer, unparsing_mode) - (_, contract) - (_, addr) - (cctxt : #Protocol_client_context.full) -> - let action = - Client_proto_fa12.Get_balance (addr, (dummy_callback, None)) - in - let payer = Option.map snd payer in - Client_proto_fa12.run_view_action - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - ~action - ~source:addr - ?gas - ?payer - ~unparsing_mode - () - >>= fun res -> Client_proto_programs.print_view_result cctxt res); - command - ~group - ~desc:"Ask for an address's allowance offchain" - view_options - (prefixes ["from"; "fa1.2"; "contract"] - @@ token_contract_param () - @@ prefixes ["get"; "allowance"; "on"] - @@ alias_param - ~name:"owner" - ~desc:"name or address of the account giving the allowance" - @@ prefix "as" - @@ alias_param - ~name:"operator" - ~desc:"name or address of the account receiving the allowance" - @@ stop) - (fun (gas, payer, unparsing_mode) - (_, contract) - (_, source) - (_, destination) - (cctxt : #Protocol_client_context.full) -> - let action = - Client_proto_fa12.Get_allowance - (source, destination, (dummy_callback, None)) - in - let payer = Option.map snd payer in - Client_proto_fa12.run_view_action - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - ~action - ~source - ?gas - ?payer - ~unparsing_mode - () - >>= fun res -> Client_proto_programs.print_view_result cctxt res); - command - ~group - ~desc:"Ask for the contract's total token supply offchain" - view_options - (prefixes ["from"; "fa1.2"; "contract"] - @@ token_contract_param () - @@ prefixes ["get"; "total"; "supply"] - @@ stop) - (fun (gas, payer, unparsing_mode) - (_, contract) - (cctxt : #Protocol_client_context.full) -> - let action = - Client_proto_fa12.Get_total_supply (dummy_callback, None) - in - let payer = Option.map snd payer in - Client_proto_fa12.run_view_action - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - ~action - ?gas - ?payer - ~unparsing_mode - () - >>= fun res -> Client_proto_programs.print_view_result cctxt res); - command - ~group - ~desc:"Ask for an address's balance using a callback contract" - contract_view_options - (prefixes ["from"; "fa1.2"; "contract"] - @@ token_contract_param () - @@ prefixes ["get"; "balance"; "for"] - @@ alias_param - ~name:"from" - ~desc: - "name or address of the account to lookup (also the source \ - contract)" - @@ prefixes ["callback"; "on"] - @@ alias_param - ~name:"callback" - ~desc:"name or address of the callback contract" - @@ stop) - (fun ( callback_entrypoint, - tez_amount, - fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, contract) - (_, addr) - (_, callback) - (cctxt : #Protocol_client_context.full) -> - get_contract_caller_keys cctxt addr - >>=? fun (source, src_pk, src_sk) -> - let action = - Client_proto_fa12.Get_balance (addr, (callback, callback_entrypoint)) - in - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_fa12.call_contract - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - ~action - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ?fee - ~source - ~src_pk - ~src_sk - ~tez_amount - ?gas_limit - ?storage_limit - ?counter - ~fee_parameter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= fun _ -> return_unit); - command - ~group - ~desc:"Ask for an address's allowance using a callback contract" - contract_view_options - (prefixes ["from"; "fa1.2"; "contract"] - @@ token_contract_param () - @@ prefixes ["get"; "allowance"; "on"] - @@ alias_param - ~name:"from" - ~desc:"name or address of the account giving the allowance" - @@ prefix "as" - @@ alias_param - ~name:"to" - ~desc:"name or address of the account receiving the allowance" - @@ prefixes ["callback"; "on"] - @@ alias_param - ~name:"callback" - ~desc:"name or address of the callback contract" - @@ stop) - (fun ( callback_entrypoint, - tez_amount, - fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, contract) - (_, src) - (_, dst) - (_, callback) - (cctxt : #Protocol_client_context.full) -> - get_contract_caller_keys cctxt src - >>=? fun (source, src_pk, src_sk) -> - let action = - Client_proto_fa12.Get_allowance - (src, dst, (callback, callback_entrypoint)) - in - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_fa12.call_contract - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - ~action - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ?fee - ~source - ~src_pk - ~src_sk - ~tez_amount - ?gas_limit - ?storage_limit - ?counter - ~fee_parameter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= fun _ -> return_unit); - command - ~group - ~desc: - "Ask for a contract's total token supply using a callback contract" - contract_view_options - (prefixes ["from"; "fa1.2"; "contract"] - @@ token_contract_param () - @@ prefixes ["get"; "total"; "supply"; "as"] - @@ alias_param - ~name:"from" - ~desc:"name or address of the source account" - @@ prefixes ["callback"; "on"] - @@ alias_param - ~name:"callback" - ~desc:"name or address of the callback contract" - @@ stop) - (fun ( callback_entrypoint, - tez_amount, - fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, contract) - (_, addr) - (_, callback) - (cctxt : #Protocol_client_context.full) -> - get_contract_caller_keys cctxt addr - >>=? fun (source, src_pk, src_sk) -> - let action = - Client_proto_fa12.Get_total_supply (callback, callback_entrypoint) - in - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_fa12.call_contract - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - ~action - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ?fee - ~source - ~src_pk - ~src_sk - ~tez_amount - ?gas_limit - ?storage_limit - ?counter - ~fee_parameter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= fun _ -> return_unit); - ] - -let commands_rw () : #Protocol_client_context.full Clic.command list = - let open Client_proto_args in - Clic. - [ - command - ~group - ~desc:"Transfer tokens between two given accounts" - (Clic.args15 - as_arg - tez_amount_arg - fee_arg - Client_proto_context_commands.dry_run_switch - Client_proto_context_commands.verbose_signing_switch - gas_limit_arg - storage_limit_arg - counter_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["from"; "fa1.2"; "contract"] - @@ token_contract_param () @@ prefix "transfer" @@ amount_param () - @@ prefix "from" @@ from_param () @@ prefix "to" @@ to_param () @@ stop - ) - (fun ( as_address, - tez_amount, - fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, contract) - amount - src - (_, dst) - (cctxt : #Protocol_client_context.full) -> - let (_, caller) = Option.value ~default:src as_address in - get_contract_caller_keys cctxt caller - >>=? fun (source, caller_pk, caller_sk) -> - let action = Client_proto_fa12.Transfer (snd src, dst, amount) in - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_fa12.call_contract - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - ~action - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ?fee - ~source - ~src_pk:caller_pk - ~src_sk:caller_sk - ~tez_amount - ?gas_limit - ?storage_limit - ?counter - ~fee_parameter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= fun _ -> return_unit); - command - ~group - ~desc:"Allow account to transfer an amount of token" - contract_call_options - (prefixes ["from"; "fa1.2"; "contract"] - @@ token_contract_param () @@ prefix "as" - @@ alias_param ~name:"as" ~desc:"name or address of the sender" - @@ prefix "approve" @@ amount_param () @@ prefix "from" - @@ alias_param - ~name:"from" - ~desc:"name or address to approve withdrawal" - @@ stop) - (fun ( tez_amount, - fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, contract) - (_, source) - amount - (_, dst) - (cctxt : #Protocol_client_context.full) -> - get_contract_caller_keys cctxt source - >>=? fun (source, src_pk, src_sk) -> - let action = Client_proto_fa12.Approve (dst, amount) in - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_fa12.call_contract - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract - ~action - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ?fee - ~source - ~src_pk - ~src_sk - ~tez_amount - ?gas_limit - ?storage_limit - ?counter - ~fee_parameter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= fun _ -> return_unit); - command - ~group - ~desc: - "Execute multiple token transfers from a single source account. If \ - one of the token transfers fails, none of them are executed." - (args14 - default_fee_arg - as_arg - Client_proto_context_commands.dry_run_switch - Client_proto_context_commands.verbose_signing_switch - default_gas_limit_arg - default_storage_limit_arg - counter_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["multiple"; "fa1.2"; "transfers"; "from"] - @@ alias_param - ~name:"src" - ~desc:"name or address of the source of the transfers" - @@ prefix "using" - @@ param - ~name:"transfers.json" - ~desc: - (Format.sprintf - "List of token transfers to inject from the source contract \ - in JSON format (as a file or string). The JSON must be an \ - array of objects of the form: '[ {\"token_contract\": \ - address or alias, \"destination\": address or alias, \ - \"amount\": non-negative integer (, : ...) } \ - (, ...) ]', where an optional can either be \ - \"tez-amount\", \"fee\", \"gas-limit\" or \ - \"storage-limit\". The complete schema can be inspected via \ - `tezos-codec describe %s.fa1.2.token_transfer json schema`." - Protocol.name) - Client_proto_context_commands.json_file_or_text_parameter - @@ stop) - (fun ( fee, - as_address, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - src - operations_json - cctxt -> - let (_, caller) = Option.value ~default:src as_address in - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - match - Data_encoding.Json.destruct - (Data_encoding.list Client_proto_fa12.token_transfer_encoding) - operations_json - with - | [] -> failwith "Empty operation list" - | operations -> - get_contract_caller_keys cctxt caller - >>=? fun (source, src_pk, src_sk) -> - Client_proto_fa12.inject_token_transfer_batch - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~sender:(snd src) - ~source - ~src_pk - ~src_sk - ~token_transfers:operations - ~fee_parameter - ?counter - ?default_fee:fee - ?default_gas_limit:gas_limit - ?default_storage_limit:storage_limit - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"multiple transfers simulation failed" - cctxt - >>= fun _ -> return_unit - | exception (Data_encoding.Json.Cannot_destruct (path, exn2) as exn) - -> ( - match (path, operations_json) with - | ([`Index n], `A lj) -> ( - match List.nth_opt lj n with - | Some j -> - failwith - "Invalid transfer at index %i: %a %a" - n - (fun ppf -> Data_encoding.Json.print_error ppf) - exn2 - Data_encoding.Json.pp - j - | _ -> - failwith - "Invalid transfer at index %i: %a" - n - (fun ppf -> Data_encoding.Json.print_error ppf) - exn2) - | _ -> - failwith - "Invalid transfer file: %a %a" - (fun ppf -> Data_encoding.Json.print_error ppf) - exn - Data_encoding.Json.pp - operations_json)); - ] - -let commands () = commands_ro () @ commands_rw () diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_mockup_commands.ml b/src/proto_012_Psithaca/lib_client_commands/client_proto_mockup_commands.ml deleted file mode 100644 index 47c00a38eebf..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_mockup_commands.ml +++ /dev/null @@ -1,81 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Tezos_clic - -let protocol_constants_arg = - Clic.arg - ~doc:"a JSON file that contains protocol constants to set." - ~long:"protocol-constants" - ~placeholder:"path" - (Clic.parameter (fun _ x -> return x)) - -let bootstrap_accounts_arg = - Clic.arg - ~doc: - "a JSON file that contains definitions of bootstrap accounts to create." - ~long:"bootstrap-accounts" - ~placeholder:"path" - (Clic.parameter (fun _ x -> return x)) - -let asynchronous_flag = - Clic.switch - ~long:"asynchronous" - ~doc:"put operations in mempool and require baking to include in the chain" - () - -let load_json_file (cctxt : Protocol_client_context.full) json_file = - match json_file with - | None -> return None - | Some filename -> - cctxt#read_file filename >>=? fun json_string -> - return (Some (Ezjsonm.from_string json_string :> Data_encoding.json)) - -let create_mockup_command_handler - (constants_overrides_file, bootstrap_accounts_file, asynchronous) - (cctxt : Protocol_client_context.full) = - load_json_file cctxt constants_overrides_file - >>=? fun constants_overrides_json -> - load_json_file cctxt bootstrap_accounts_file - >>=? fun bootstrap_accounts_json -> - Tezos_mockup.Persistence.create_mockup - ~cctxt:(cctxt :> Tezos_client_base.Client_context.full) - ~protocol_hash:Protocol.hash - ~constants_overrides_json - ~bootstrap_accounts_json - ~asynchronous - >>=? fun () -> - Tezos_mockup_commands.Mockup_wallet.populate cctxt bootstrap_accounts_file - -let create_mockup_command : Protocol_client_context.full Clic.command = - let open Clic in - command - ~group:Tezos_mockup_commands.Mockup_commands.group - ~desc:"Create a mockup environment." - (args3 protocol_constants_arg bootstrap_accounts_arg asynchronous_flag) - (prefixes ["create"; "mockup"] @@ stop) - create_mockup_command_handler - -let commands () = [create_mockup_command] diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_mockup_commands.mli b/src/proto_012_Psithaca/lib_client_commands/client_proto_mockup_commands.mli deleted file mode 100644 index 765437d4365e..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_mockup_commands.mli +++ /dev/null @@ -1,26 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_multisig_commands.ml b/src/proto_012_Psithaca/lib_client_commands/client_proto_multisig_commands.ml deleted file mode 100644 index db58555539ee..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_multisig_commands.ml +++ /dev/null @@ -1,1136 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Client_proto_args -open Tezos_micheline - -let group = - { - Clic.name = "multisig"; - title = "Commands for managing a multisig smart contract"; - } - -let threshold_param () = - Clic.param - ~name:"threshold" - ~desc:"Number of required signatures" - Client_proto_args.int_parameter - -let public_key_param () = - Client_keys.Public_key.source_param - ~name:"key" - ~desc:"Each signer of the multisig contract" - -let secret_key_param () = - Client_keys.Secret_key.source_param - ~name:"key" - ~desc: - "Secret key corresponding to one of the public keys stored on the \ - multisig contract" - -let signature_param () = - Clic.param - ~name:"signature" - ~desc:"Each signer of the multisig contract" - Client_proto_args.signature_parameter - -let lambda_param () = - Clic.param - ~name:"lambda" - ~desc:"the lambda to execute, of type lambda unit (list operation)" - string_parameter - -let bytes_only_switch = - Clic.switch - ~long:"bytes-only" - ~doc:"return only the byte sequence to be signed" - () - -let bytes_param ~name ~desc = - Clic.param ~name ~desc Client_proto_args.bytes_parameter - -let transfer_options = - Clic.args15 - Client_proto_args.fee_arg - Client_proto_context_commands.dry_run_switch - Client_proto_context_commands.verbose_signing_switch - Client_proto_args.gas_limit_arg - Client_proto_args.storage_limit_arg - Client_proto_args.counter_arg - Client_proto_args.arg_arg - Client_proto_args.no_print_source_flag - Client_proto_args.minimal_fees_arg - Client_proto_args.minimal_nanotez_per_byte_arg - Client_proto_args.minimal_nanotez_per_gas_unit_arg - Client_proto_args.force_low_fee_arg - Client_proto_args.fee_cap_arg - Client_proto_args.burn_cap_arg - Client_proto_args.entrypoint_arg - -let non_transfer_options = - Clic.args13 - Client_proto_args.fee_arg - Client_proto_context_commands.dry_run_switch - Client_proto_context_commands.verbose_signing_switch - Client_proto_args.gas_limit_arg - Client_proto_args.storage_limit_arg - Client_proto_args.counter_arg - Client_proto_args.no_print_source_flag - Client_proto_args.minimal_fees_arg - Client_proto_args.minimal_nanotez_per_byte_arg - Client_proto_args.minimal_nanotez_per_gas_unit_arg - Client_proto_args.force_low_fee_arg - Client_proto_args.fee_cap_arg - Client_proto_args.burn_cap_arg - -let prepare_command_display prepared_command bytes_only = - if bytes_only then - Format.printf - "0x%a@." - Hex.pp - (Hex.of_bytes prepared_command.Client_proto_multisig.bytes) - else - Format.printf - "%a@.%a@.%a@.%a@." - (fun ppf x -> - Format.fprintf ppf "Bytes to sign: '0x%a'" Hex.pp (Hex.of_bytes x)) - prepared_command.Client_proto_multisig.bytes - (fun ppf x -> - Format.fprintf - ppf - "Blake 2B Hash: '%s'" - (Base58.raw_encode Blake2B.(hash_bytes [x] |> to_string))) - prepared_command.Client_proto_multisig.bytes - (fun ppf z -> - Format.fprintf - ppf - "Threshold (number of signatures required): %s" - (Z.to_string z)) - prepared_command.Client_proto_multisig.threshold - (fun ppf -> - Format.fprintf - ppf - "@[<2>Public keys of the signers:@ %a@]" - (Format.pp_print_list - ~pp_sep:(fun ppf () -> Format.fprintf ppf "@ ") - Signature.Public_key.pp)) - prepared_command.Client_proto_multisig.keys - -let get_parameter_type (cctxt : #Protocol_client_context.full) ~destination - ~entrypoint = - match Contract.is_implicit destination with - | Some _ -> - let open Micheline in - return @@ strip_locations @@ Prim (0, Script.T_unit, [], []) - | None -> ( - Michelson_v1_entrypoints.contract_entrypoint_type - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~contract:destination - ~entrypoint - >>=? function - | None -> - cctxt#error - "Contract %a has no entrypoint named %s" - Contract.pp - destination - entrypoint - | Some parameter_type -> return parameter_type) - -let commands_ro () : #Protocol_client_context.full Clic.command list = - Clic. - [ - command - ~group - ~desc:"Show the hashes of the supported multisig contracts." - no_options - (fixed ["show"; "supported"; "multisig"; "hashes"]) - (fun () _cctxt -> - Format.printf "Hashes of supported multisig contracts:@." ; - List.iter - (fun h -> Format.printf "%a@." Script_expr_hash.pp h) - Client_proto_multisig.known_multisig_hashes ; - return_unit); - command - ~group - ~desc:"Show the script of the recommended multisig contract." - no_options - (fixed ["show"; "multisig"; "script"]) - (fun () _cctxt -> - let {Michelson_v1_parser.source; _} = - Michelson_v1_printer.unparse_toplevel - Client_proto_multisig.multisig_script - in - Format.printf "%s@." source ; - return_unit); - ] - -let commands_rw () : #Protocol_client_context.full Clic.command list = - Clic. - [ - command - ~group - ~desc:"Originate a new multisig contract." - (args14 - Client_proto_args.fee_arg - Client_proto_context_commands.dry_run_switch - Client_proto_args.gas_limit_arg - Client_proto_args.storage_limit_arg - Client_proto_args.delegate_arg - (Client_keys.force_switch ()) - Client_proto_args.no_print_source_flag - Client_proto_args.minimal_fees_arg - Client_proto_args.minimal_nanotez_per_byte_arg - Client_proto_args.minimal_nanotez_per_gas_unit_arg - Client_proto_args.force_low_fee_arg - Client_proto_args.fee_cap_arg - Client_proto_context_commands.verbose_signing_switch - Client_proto_args.burn_cap_arg) - (prefixes ["deploy"; "multisig"] - @@ Client_proto_contracts.RawContractAlias.fresh_alias_param - ~name:"new_multisig" - ~desc:"name of the new multisig contract" - @@ prefix "transferring" - @@ Client_proto_args.tez_param - ~name:"qty" - ~desc:"amount taken from source" - @@ prefix "from" - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"src" - ~desc:"name of the source contract" - @@ prefixes ["with"; "threshold"] - @@ threshold_param () - @@ prefixes ["on"; "public"; "keys"] - @@ seq_of_param (public_key_param ())) - (fun ( fee, - dry_run, - gas_limit, - storage_limit, - delegate, - force, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - verbose_signing, - burn_cap ) - alias_name - balance - (_, source) - threshold - keys - (cctxt : #Protocol_client_context.full) -> - Client_proto_contracts.RawContractAlias.of_fresh - cctxt - force - alias_name - >>=? fun alias_name -> - match Contract.is_implicit source with - | None -> - failwith - "only implicit accounts can be the source of an origination" - | Some source -> ( - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - List.map_es - (fun (pk_uri, _) -> Client_keys.public_key pk_uri) - keys - >>=? fun keys -> - Client_proto_multisig.originate_multisig - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ?fee - ?gas_limit - ?storage_limit - ~verbose_signing - ~delegate - ~threshold:(Z.of_int threshold) - ~keys - ~balance - ~source - ~src_pk - ~src_sk - ~fee_parameter - () - >>= fun errors -> - Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"multisig origination simulation failed" - cctxt - errors - >>= function - | None -> return_unit - | Some (_res, contract) -> - if dry_run then return_unit - else - Client_proto_context.save_contract - ~force - cctxt - alias_name - contract - >>=? fun () -> return_unit)); - command - ~group - ~desc:"Sign a transaction for a multisig contract." - (args2 arg_arg entrypoint_arg) - (prefixes ["sign"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefix "transferring" - @@ Client_proto_args.tez_param - ~name:"qty" - ~desc:"amount taken from source" - @@ prefix "to" - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"dst" - ~desc:"name/literal of the destination contract" - @@ prefixes ["using"; "secret"; "key"] - @@ secret_key_param () @@ stop) - (fun (parameter, entrypoint) - (_, multisig_contract) - amount - (_, destination) - sk - (cctxt : #Protocol_client_context.full) -> - let entrypoint = Option.value ~default:"default" entrypoint in - let parameter = Option.value ~default:"Unit" parameter in - Lwt.return @@ Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression parameter - >>=? fun {expanded = parameter; _} -> - get_parameter_type cctxt ~destination ~entrypoint - >>=? fun parameter_type -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action: - (Client_proto_multisig.Transfer - {amount; destination; entrypoint; parameter_type; parameter}) - () - >>=? fun prepared_command -> - Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> - return @@ Format.printf "%a@." Signature.pp signature); - command - ~group - ~desc:"Sign a lambda for a generic multisig contract." - no_options - (prefixes ["sign"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["running"; "lambda"] - @@ lambda_param () - @@ prefixes ["using"; "secret"; "key"] - @@ secret_key_param () @@ stop) - (fun () - (_, multisig_contract) - lambda - sk - (cctxt : #Protocol_client_context.full) -> - Lwt.return @@ Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression lambda - >>=? fun {expanded = lambda; _} -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action:(Lambda lambda) - () - >>=? fun prepared_command -> - Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> - return @@ Format.printf "%a@." Signature.pp signature); - command - ~group - ~desc:"Sign a delegate change for a multisig contract." - no_options - (prefixes ["sign"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["setting"; "delegate"; "to"] - @@ Client_keys.Public_key_hash.source_param - ~name:"dlgt" - ~desc:"new delegate of the new multisig contract" - @@ prefixes ["using"; "secret"; "key"] - @@ secret_key_param () @@ stop) - (fun () - (_, multisig_contract) - delegate - sk - (cctxt : #Protocol_client_context.full) -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action:(Client_proto_multisig.Change_delegate (Some delegate)) - () - >>=? fun prepared_command -> - Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> - return @@ Format.printf "%a@." Signature.pp signature); - command - ~group - ~desc:"Sign a delegate withdraw for a multisig contract." - no_options - (prefixes ["sign"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["withdrawing"; "delegate"] - @@ prefixes ["using"; "secret"; "key"] - @@ secret_key_param () @@ stop) - (fun () - (_, multisig_contract) - sk - (cctxt : #Protocol_client_context.full) -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action:(Client_proto_multisig.Change_delegate None) - () - >>=? fun prepared_command -> - Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> - return @@ Format.printf "%a@." Signature.pp signature); - command - ~group - ~desc: - "Sign a change of public keys and threshold for a multisig contract." - no_options - (prefixes ["sign"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["using"; "secret"; "key"] - @@ secret_key_param () - @@ prefixes ["setting"; "threshold"; "to"] - @@ threshold_param () - @@ prefixes ["and"; "public"; "keys"; "to"] - @@ seq_of_param (public_key_param ())) - (fun () - (_, multisig_contract) - sk - new_threshold - new_keys - (cctxt : #Protocol_client_context.full) -> - List.map_es - (fun (pk_uri, _) -> Client_keys.public_key pk_uri) - new_keys - >>=? fun keys -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action: - (Client_proto_multisig.Change_keys (Z.of_int new_threshold, keys)) - () - >>=? fun prepared_command -> - Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> - return @@ Format.printf "%a@." Signature.pp signature); - command - ~group - ~desc:"Transfer tokens using a multisig contract." - transfer_options - (prefixes ["from"; "multisig"; "contract"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name/literal of the multisig contract" - @@ prefix "transfer" - @@ Client_proto_args.tez_param - ~name:"qty" - ~desc:"amount taken from the multisig contract" - @@ prefix "to" - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"dst" - ~desc:"name/literal of the destination contract" - @@ prefixes ["on"; "behalf"; "of"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"src" - ~desc:"source calling the multisig contract" - @@ prefixes ["with"; "signatures"] - @@ seq_of_param (signature_param ())) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - parameter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap, - entrypoint ) - (_, multisig_contract) - amount - (_, destination) - (_, source) - signatures - (cctxt : #Protocol_client_context.full) -> - let entrypoint = Option.value ~default:"default" entrypoint in - let parameter = Option.value ~default:"Unit" parameter in - Lwt.return @@ Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression parameter - >>=? fun {expanded = parameter; _} -> - get_parameter_type cctxt ~destination ~entrypoint - >>=? fun parameter_type -> - match Contract.is_implicit source with - | None -> - failwith - "only implicit accounts can be the source of a contract call" - | Some source -> ( - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_multisig.call_multisig - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~fee_parameter - ~source - ?fee - ~src_pk - ~src_sk - ~multisig_contract - ~action: - (Client_proto_multisig.Transfer - { - amount; - destination; - entrypoint; - parameter_type; - parameter; - }) - ~signatures - ~amount:Tez.zero - ?gas_limit - ?storage_limit - ?counter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit)); - command - ~group - ~desc:"Run a lambda on a generic multisig contract." - non_transfer_options - (prefixes ["from"; "multisig"; "contract"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name/literal of the multisig contract" - @@ prefixes ["run"; "lambda"] - @@ lambda_param () - @@ prefixes ["on"; "behalf"; "of"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"src" - ~desc:"source calling the multisig contract" - @@ prefixes ["with"; "signatures"] - @@ seq_of_param (signature_param ())) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, multisig_contract) - lambda - (_, source) - signatures - (cctxt : #Protocol_client_context.full) -> - match Contract.is_implicit source with - | None -> - failwith - "only implicit accounts can be the source of a contract call" - | Some source -> ( - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Lwt.return @@ Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression lambda - >>=? fun {expanded = lambda; _} -> - Client_proto_multisig.call_multisig - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~fee_parameter - ~source - ?fee - ~src_pk - ~src_sk - ~multisig_contract - ~action:(Client_proto_multisig.Lambda lambda) - ~signatures - ~amount:Tez.zero - ?gas_limit - ?storage_limit - ?counter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit)); - command - ~group - ~desc:"Change the delegate of a multisig contract." - non_transfer_options - (prefixes ["set"; "delegate"; "of"; "multisig"; "contract"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefix "to" - @@ Client_keys.Public_key_hash.source_param - ~name:"dlgt" - ~desc:"new delegate of the new multisig contract" - @@ prefixes ["on"; "behalf"; "of"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"src" - ~desc:"source calling the multisig contract" - @@ prefixes ["with"; "signatures"] - @@ seq_of_param (signature_param ())) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, multisig_contract) - delegate - (_, source) - signatures - (cctxt : #Protocol_client_context.full) -> - match Contract.is_implicit source with - | None -> - failwith - "only implicit accounts can be the source of a contract call" - | Some source -> ( - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_multisig.call_multisig - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~fee_parameter - ~source - ?fee - ~src_pk - ~src_sk - ~multisig_contract - ~action:(Client_proto_multisig.Change_delegate (Some delegate)) - ~signatures - ~amount:Tez.zero - ?gas_limit - ?storage_limit - ?counter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit)); - command - ~group - ~desc:"Withdraw the delegate of a multisig contract." - non_transfer_options - (prefixes ["withdraw"; "delegate"; "of"; "multisig"; "contract"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["on"; "behalf"; "of"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"src" - ~desc:"source calling the multisig contract" - @@ prefixes ["with"; "signatures"] - @@ seq_of_param (signature_param ())) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, multisig_contract) - (_, source) - signatures - (cctxt : #Protocol_client_context.full) -> - match Contract.is_implicit source with - | None -> - failwith - "only implicit accounts can be the source of a contract call" - | Some source -> ( - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_multisig.call_multisig - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~fee_parameter - ~source - ?fee - ~src_pk - ~src_sk - ~multisig_contract - ~action:(Client_proto_multisig.Change_delegate None) - ~signatures - ~amount:Tez.zero - ?gas_limit - ?storage_limit - ?counter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit)); - command - ~group - ~desc:"Change public keys and threshold for a multisig contract." - non_transfer_options - (prefixes ["set"; "threshold"; "of"; "multisig"; "contract"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["to"] - @@ threshold_param () - @@ prefixes ["and"; "public"; "keys"; "to"] - @@ non_terminal_seq (public_key_param ()) ~suffix:["on"; "behalf"; "of"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"src" - ~desc:"source calling the multisig contract" - @@ prefixes ["with"; "signatures"] - @@ seq_of_param (signature_param ())) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - (_, multisig_contract) - new_threshold - new_keys - (_, source) - signatures - (cctxt : #Protocol_client_context.full) -> - match Contract.is_implicit source with - | None -> - failwith - "only implicit accounts can be the source of a contract call" - | Some source -> ( - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - List.map_es - (fun (pk_uri, _) -> Client_keys.public_key pk_uri) - new_keys - >>=? fun keys -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_multisig.call_multisig - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~fee_parameter - ~source - ?fee - ~src_pk - ~src_sk - ~multisig_contract - ~action: - (Client_proto_multisig.Change_keys - (Z.of_int new_threshold, keys)) - ~signatures - ~amount:Tez.zero - ?gas_limit - ?storage_limit - ?counter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit)); - (* This command is no longer necessary as Clic now supports non terminal - lists of parameters, however, it is kept for compatibility. *) - command - ~group - ~desc: - "Run a transaction described by a sequence of bytes on a multisig \ - contract." - non_transfer_options - (prefixes ["run"; "transaction"] - @@ bytes_param - ~name:"bytes" - ~desc: - "the sequence of bytes to deserialize as a multisig action, can \ - be obtained by one of the \"prepare multisig transaction\" \ - commands" - @@ prefixes ["on"; "multisig"; "contract"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["on"; "behalf"; "of"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"src" - ~desc:"source calling the multisig contract" - @@ prefixes ["with"; "signatures"] - @@ seq_of_param (signature_param ())) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - bytes - (_, multisig_contract) - (_, source) - signatures - (cctxt : #Protocol_client_context.full) -> - match Contract.is_implicit source with - | None -> - failwith - "only implicit accounts can be the source of a contract call" - | Some source -> ( - Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_multisig.call_multisig_on_bytes - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ?confirmations:cctxt#confirmations - ~dry_run - ~verbose_signing - ~fee_parameter - ~source - ?fee - ~src_pk - ~src_sk - ~multisig_contract - ~bytes - ~signatures - ~amount:Tez.zero - ?gas_limit - ?storage_limit - ?counter - () - >>= Client_proto_context_commands.report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit)); - command - ~group - ~desc: - "Display the threshold, public keys, and byte sequence to sign for a \ - multisigned transfer." - (args3 bytes_only_switch arg_arg entrypoint_arg) - (prefixes ["prepare"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefix "transferring" - @@ Client_proto_args.tez_param - ~name:"qty" - ~desc:"amount taken from source" - @@ prefix "to" - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"dst" - ~desc:"name/literal of the destination contract" - @@ stop) - (fun (bytes_only, parameter, entrypoint) - (_, multisig_contract) - amount - (_, destination) - (cctxt : #Protocol_client_context.full) -> - let entrypoint = Option.value ~default:"default" entrypoint in - let parameter = Option.value ~default:"Unit" parameter in - Lwt.return @@ Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression parameter - >>=? fun {expanded = parameter; _} -> - get_parameter_type cctxt ~destination ~entrypoint - >>=? fun parameter_type -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action: - (Client_proto_multisig.Transfer - {amount; destination; entrypoint; parameter_type; parameter}) - () - >>=? fun prepared_command -> - return @@ prepare_command_display prepared_command bytes_only); - command - ~group - ~desc: - "Display the threshold, public keys, and byte sequence to sign for a \ - multisigned lambda execution in a generic multisig contract." - (args1 bytes_only_switch) - (prefixes ["prepare"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["running"; "lambda"] - @@ lambda_param () @@ stop) - (fun bytes_only - (_, multisig_contract) - lambda - (cctxt : #Protocol_client_context.full) -> - Lwt.return @@ Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression lambda - >>=? fun {expanded = lambda; _} -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action:(Client_proto_multisig.Lambda lambda) - () - >>=? fun prepared_command -> - return @@ prepare_command_display prepared_command bytes_only); - command - ~group - ~desc: - "Display the threshold, public keys, and byte sequence to sign for a \ - multisigned delegate change." - (args1 bytes_only_switch) - (prefixes ["prepare"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["setting"; "delegate"; "to"] - @@ Client_keys.Public_key_hash.source_param - ~name:"dlgt" - ~desc:"new delegate of the new multisig contract" - @@ stop) - (fun bytes_only - (_, multisig_contract) - new_delegate - (cctxt : #Protocol_client_context.full) -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action:(Client_proto_multisig.Change_delegate (Some new_delegate)) - () - >>=? fun prepared_command -> - return @@ prepare_command_display prepared_command bytes_only); - command - ~group - ~desc: - "Display the threshold, public keys, and byte sequence to sign for a \ - multisigned delegate withdraw." - (args1 bytes_only_switch) - (prefixes ["prepare"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["withdrawing"; "delegate"] - @@ stop) - (fun bytes_only - (_, multisig_contract) - (cctxt : #Protocol_client_context.full) -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action:(Client_proto_multisig.Change_delegate None) - () - >>=? fun prepared_command -> - return @@ prepare_command_display prepared_command bytes_only); - command - ~group - ~desc: - "Display the threshold, public keys, and byte sequence to sign for a \ - multisigned change of keys and threshold." - (args1 bytes_only_switch) - (prefixes ["prepare"; "multisig"; "transaction"; "on"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"multisig" - ~desc:"name or address of the originated multisig contract" - @@ prefixes ["setting"; "threshold"; "to"] - @@ threshold_param () - @@ prefixes ["and"; "public"; "keys"; "to"] - @@ seq_of_param (public_key_param ())) - (fun bytes_only - (_, multisig_contract) - new_threshold - new_keys - (cctxt : #Protocol_client_context.full) -> - List.map_es - (fun (pk_uri, _) -> Client_keys.public_key pk_uri) - new_keys - >>=? fun keys -> - Client_proto_multisig.prepare_multisig_transaction - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~multisig_contract - ~action: - (Client_proto_multisig.Change_keys (Z.of_int new_threshold, keys)) - () - >>=? fun prepared_command -> - return @@ prepare_command_display prepared_command bytes_only); - ] - -let commands () = commands_ro () @ commands_rw () diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_multisig_commands.mli b/src/proto_012_Psithaca/lib_client_commands/client_proto_multisig_commands.mli deleted file mode 100644 index c328ace47c3f..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_multisig_commands.mli +++ /dev/null @@ -1,26 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_programs_commands.ml b/src/proto_012_Psithaca/lib_client_commands/client_proto_programs_commands.ml deleted file mode 100644 index e0bc75fb83ab..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_programs_commands.ml +++ /dev/null @@ -1,966 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -let group = - { - Clic.name = "scripts"; - title = "Commands for managing the library of known scripts"; - } - -open Tezos_micheline -open Client_proto_programs -open Client_proto_args -open Client_proto_contracts - -let safe_decode_json (cctxt : Protocol_client_context.full) encoding json = - match Data_encoding.Json.destruct encoding json with - | exception Data_encoding.Json.Cannot_destruct (_, exc) -> - cctxt#error - "could not decode json (%a)" - (Data_encoding.Json.print_error ~print_unknown:(fun fmt exc -> - Format.fprintf fmt "%s" (Printexc.to_string exc))) - exc - | exception ((Stack_overflow | Out_of_memory) as exc) -> raise exc - | exception exc -> - cctxt#error "could not decode json (%s)" (Printexc.to_string exc) - | expr -> return expr - -let commands () = - let open Clic in - let show_types_switch = - switch - ~long:"details" - ~short:'v' - ~doc:"show the types of each instruction" - () - in - let emacs_mode_switch = - switch - ~long:"emacs" - ?short:None - ~doc:"output in `michelson-mode.el` compatible format" - () - in - let trace_stack_switch = - switch ~long:"trace-stack" ~doc:"show the stack after each step" () - in - let zero_loc_switch = - switch ~short:'z' ~long:"zero-loc" ~doc:"replace location with \"0\"" () - in - let legacy_switch = - switch - ~long:"legacy" - ~doc:"typecheck in legacy mode as if the data was taken from the chain" - () - in - let amount_arg = - Client_proto_args.tez_arg - ~parameter:"amount" - ~doc:"amount of the transfer in \xEA\x9C\xA9" - ~default:"0.05" - in - let source_arg = - ContractAlias.destination_arg - ~name:"source" - ~doc:"name of the source (i.e. SENDER) contract for the transaction" - () - in - let payer_arg = - ContractAlias.destination_arg - ~name:"payer" - ~doc:"name of the payer (i.e. SOURCE) contract for the transaction" - () - in - let balance_arg = - Client_proto_args.tez_arg - ~parameter:"balance" - ~doc:"balance of run contract in \xEA\x9C\xA9" - ~default:"4_000_000" - in - let now_arg = Client_proto_args.now_arg in - let level_arg = Client_proto_args.level_arg in - let resolve_max_gas cctxt block = function - | None -> - Alpha_services.Constants.all cctxt (cctxt#chain, block) - >>=? fun {parametric = {hard_gas_limit_per_operation; _}; _} -> - return hard_gas_limit_per_operation - | Some gas -> return gas - in - let parse_expr expr = - Lwt.return @@ Micheline_parser.no_parsing_error - @@ Michelson_v1_parser.parse_expression expr - in - let data_type_arg = - arg - ~doc:"the given data will be type-checked against this type" - ~short:'t' - ~long:"type" - ~placeholder:"unit" - data_parameter - in - let bytes_parameter ~name ~desc = - param ~name ~desc Client_proto_args.bytes_parameter - in - let signature_parameter = - parameter (fun _cctxt s -> - match Signature.of_b58check_opt s with - | Some s -> return s - | None -> failwith "Not given a valid signature") - in - let convert_input_format_param = - param - ~name:"input_format" - ~desc:"format of the input for conversion" - (parameter - ~autocomplete:(fun _ -> return ["michelson"; "json"; "binary"]) - (fun _ s -> - match String.lowercase_ascii s with - | "michelson" -> return `Michelson - | "json" -> return `JSON - | "binary" -> return `Binary - | _ -> - failwith - "invalid input format, expecting one of \"michelson\", \ - \"json\" or \"binary\".")) - in - let convert_output_format_param = - param - ~name:"output_format" - ~desc:"format of the conversion output" - (parameter - ~autocomplete:(fun _ -> - return ["michelson"; "json"; "binary"; "ocaml"]) - (fun _ s -> - match String.lowercase_ascii s with - | "michelson" -> return `Michelson - | "json" -> return `JSON - | "binary" -> return `Binary - | "ocaml" -> return `OCaml - | _ -> - failwith - "invalid output format, expecting one of \"michelson\", \ - \"json\", \"binary\" or \"ocaml\".")) - in - let file_or_literal_param () = - param - ~name:"source" - ~desc:"literal or a path to a file" - (parameter (fun cctxt s -> - cctxt#read_file s >>= function - | Ok v -> return (Some s, v) - | Error _ -> return (None, s))) - in - let handle_parsing_error label (cctxt : Protocol_client_context.full) - (emacs_mode, no_print_source) program body = - match program with - | (program, []) -> body program - | res_with_errors when emacs_mode -> - cctxt#message - "(@[(%s . ())@ (errors . %a)@])" - label - Michelson_v1_emacs.report_errors - res_with_errors - >>= fun () -> return_unit - | (parsed, errors) -> - cctxt#message - "%a" - (fun ppf () -> - Michelson_v1_error_reporter.report_errors - ~details:(not no_print_source) - ~parsed - ~show_source:(not no_print_source) - ppf - errors) - () - >>= fun () -> cctxt#error "syntax error in program" - in - [ - command - ~group - ~desc:"Lists all scripts in the library." - no_options - (fixed ["list"; "known"; "scripts"]) - (fun () (cctxt : Protocol_client_context.full) -> - Program.load cctxt >>=? fun list -> - List.iter_s (fun (n, _) -> cctxt#message "%s" n) list >>= fun () -> - return_unit); - command - ~group - ~desc:"Add a script to the library." - (args1 (Program.force_switch ())) - (prefixes ["remember"; "script"] - @@ Program.fresh_alias_param @@ Program.source_param @@ stop) - (fun force name hash cctxt -> - Program.of_fresh cctxt force name >>=? fun name -> - Program.add ~force cctxt name hash); - command - ~group - ~desc:"Remove a script from the library." - no_options - (prefixes ["forget"; "script"] @@ Program.alias_param @@ stop) - (fun () (name, _) cctxt -> Program.del cctxt name); - command - ~group - ~desc:"Display a script from the library." - no_options - (prefixes ["show"; "known"; "script"] @@ Program.alias_param @@ stop) - (fun () (_, program) (cctxt : Protocol_client_context.full) -> - Program.to_source program >>=? fun source -> - cctxt#message "%s\n" source >>= fun () -> return_unit); - command - ~group - ~desc:"Ask the node to run a script." - (args11 - trace_stack_switch - amount_arg - balance_arg - source_arg - payer_arg - no_print_source_flag - run_gas_limit_arg - entrypoint_arg - (unparsing_mode_arg ~default:"Readable") - now_arg - level_arg) - (prefixes ["run"; "script"] - @@ Program.source_param - @@ prefixes ["on"; "storage"] - @@ param ~name:"storage" ~desc:"the storage data" data_parameter - @@ prefixes ["and"; "input"] - @@ param ~name:"input" ~desc:"the input data" data_parameter - @@ stop) - (fun ( trace_exec, - amount, - balance, - source, - payer, - no_print_source, - gas, - entrypoint, - unparsing_mode, - now, - level ) - program - storage - input - cctxt -> - let source = Option.map snd source in - let payer = Option.map snd payer in - Lwt.return @@ Micheline_parser.no_parsing_error program - >>=? fun program -> - let show_source = not no_print_source in - if trace_exec then - trace - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - { - amount = Some amount; - balance; - program; - storage; - shared_params = - {input; unparsing_mode; now; level; source; payer; gas}; - entrypoint; - } - >>= fun res -> - print_trace_result cctxt ~show_source ~parsed:program res - else - run - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - { - amount = Some amount; - balance; - program; - storage; - shared_params = - {input; unparsing_mode; now; level; source; payer; gas}; - entrypoint; - } - >>= fun res -> print_run_result cctxt ~show_source ~parsed:program res); - command - ~group - ~desc:"Ask the node to compute the size of a script." - (args4 - emacs_mode_switch - no_print_source_flag - run_gas_limit_arg - legacy_switch) - (prefixes ["compute"; "size"; "for"; "script"] - @@ Program.source_param - @@ prefixes ["on"; "storage"] - @@ param ~name:"storage" ~desc:"the storage data" data_parameter - @@ stop) - (fun (emacs_mode, no_print_source, original_gas, legacy) - program - storage - cctxt -> - let setup = (emacs_mode, no_print_source) in - resolve_max_gas cctxt cctxt#block original_gas >>=? fun original_gas -> - handle_parsing_error "size" cctxt setup program @@ fun program -> - script_size - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~gas:original_gas - ~legacy - ~program - ~storage - () - >>=? fun code_size -> - cctxt#message "%d" code_size >>= fun _ -> return ()); - command - ~group - ~desc:"Ask the node to typecheck a script." - (args5 - show_types_switch - emacs_mode_switch - no_print_source_flag - run_gas_limit_arg - legacy_switch) - (prefixes ["typecheck"; "script"] @@ Program.source_param @@ stop) - (fun (show_types, emacs_mode, no_print_source, original_gas, legacy) - program - cctxt -> - let setup = (emacs_mode, no_print_source) in - handle_parsing_error "types" cctxt setup program @@ fun program -> - resolve_max_gas cctxt cctxt#block original_gas >>=? fun original_gas -> - typecheck_program - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~gas:original_gas - ~legacy - ~show_types - program - >>= fun res -> - print_typecheck_result - ~emacs:emacs_mode - ~show_types - ~print_source_on_error:(not no_print_source) - program - res - cctxt); - command - ~group - ~desc:"Ask the node to typecheck a data expression." - (args3 no_print_source_flag run_gas_limit_arg legacy_switch) - (prefixes ["typecheck"; "data"] - @@ param ~name:"data" ~desc:"the data to typecheck" data_parameter - @@ prefixes ["against"; "type"] - @@ param ~name:"type" ~desc:"the expected type" data_parameter - @@ stop) - (fun (no_print_source, custom_gas, legacy) data ty cctxt -> - resolve_max_gas cctxt cctxt#block custom_gas >>=? fun original_gas -> - Client_proto_programs.typecheck_data - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~gas:original_gas - ~legacy - ~data - ~ty - () - >>= function - | Ok gas -> - cctxt#message - "@[Well typed@,Gas remaining: %a@]" - Alpha_context.Gas.pp - gas - >>= fun () -> return_unit - | Error errs -> - cctxt#warning - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:false - ~show_source:(not no_print_source) - ?parsed:None) - errs - >>= fun () -> cctxt#error "ill-typed data"); - command - ~group - ~desc: - "Ask the node to pack a data expression.\n\ - The returned hash is the same as what Michelson instruction `PACK` \ - would have produced.\n\ - Also displays the result of hashing this packed data with `BLAKE2B`, \ - `SHA256` or `SHA512` instruction." - (args2 run_gas_limit_arg (Tezos_clic_unix.Scriptable.clic_arg ())) - (prefixes ["hash"; "data"] - @@ param ~name:"data" ~desc:"the data to hash" data_parameter - @@ prefixes ["of"; "type"] - @@ param ~name:"type" ~desc:"type of the data" data_parameter - @@ stop) - (fun (custom_gas, scriptable) data typ cctxt -> - resolve_max_gas cctxt cctxt#block custom_gas >>=? fun original_gas -> - Plugin.RPC.Scripts.pack_data - cctxt - (cctxt#chain, cctxt#block) - ~gas:original_gas - ~data:data.expanded - ~ty:typ.expanded - >>= function - | Ok (bytes, remaining_gas) -> - let hash = Script_expr_hash.hash_bytes [bytes] in - let name_value_rows = - Format. - [ - ( "Raw packed data", - asprintf "0x%a" Hex.pp (Hex.of_bytes bytes) ); - ( "Script-expression-ID-Hash", - asprintf "%a" Script_expr_hash.pp hash ); - ( "Raw Script-expression-ID-Hash", - asprintf - "0x%a" - Hex.pp - (Hex.of_bytes (Script_expr_hash.to_bytes hash)) ); - ( "Ledger Blake2b hash", - Base58.raw_encode Blake2B.(hash_bytes [bytes] |> to_string) - ); - ( "Raw Sha256 hash", - asprintf - "0x%a" - Hex.pp - (Hex.of_bytes (Environment.Raw_hashes.sha256 bytes)) ); - ( "Raw Sha512 hash", - asprintf - "0x%a" - Hex.pp - (Hex.of_bytes (Environment.Raw_hashes.sha512 bytes)) ); - ( "Gas remaining", - asprintf "%a" Alpha_context.Gas.pp remaining_gas ); - ] - in - Tezos_clic_unix.Scriptable.output - scriptable - ~for_human:(fun () -> - List.iter_s - (fun (name, value) -> cctxt#message "%s: %s" name value) - name_value_rows - >|= ok) - ~for_script:(fun () -> - name_value_rows |> List.map (fun (name, value) -> [name; value])) - | Error errs -> - cctxt#warning - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:false - ~show_source:false - ?parsed:None) - errs - >>= fun () -> cctxt#error "ill-formed data"); - command - ~group - ~desc:"Ask the node to hash a Michelson script with `BLAKE2B`." - (args3 - enforce_indentation_flag - display_names_flag - (Tezos_clic_unix.Scriptable.clic_arg ())) - (prefixes ["hash"; "script"] @@ seq_of_param @@ file_or_literal_param ()) - (fun (check, display_names, scriptable) - expr_strings - (cctxt : Protocol_client_context.full) -> - if List.length expr_strings == 0 then - cctxt#warning "No scripts were specified on the command line" >|= ok - else - List.mapi_ep - (fun i (src, expr_string) -> - let program = - Michelson_v1_parser.parse_toplevel ~check expr_string - in - Micheline_parser.no_parsing_error program >>?= fun program -> - let code = program.expanded in - let bytes = - Data_encoding.Binary.to_bytes_exn - Alpha_context.Script.expr_encoding - code - in - let hash = - Format.asprintf - "%a" - Script_expr_hash.pp - (Script_expr_hash.hash_bytes [bytes]) - in - let name = - Option.value - src - ~default:("Literal script " ^ string_of_int (i + 1)) - in - return (hash, name)) - expr_strings - >>=? fun hash_name_rows -> - Tezos_clic_unix.Scriptable.output - scriptable - ~for_human:(fun () -> - List.iter_s - (fun (hash, name) -> - if display_names then cctxt#answer "%s\t%s" hash name - else cctxt#answer "%s" hash) - hash_name_rows - >|= ok) - ~for_script:(fun () -> - List.map - (fun (hash, name) -> - if display_names then [hash; name] else [hash]) - hash_name_rows)); - command - ~group - ~desc: - "Parse a byte sequence (in hexadecimal notation) as a data expression, \ - as per Michelson instruction `UNPACK`." - no_options - (prefixes ["unpack"; "michelson"; "data"] - @@ bytes_parameter ~name:"bytes" ~desc:"the packed data to parse" - @@ stop) - (fun () bytes cctxt -> - (if Bytes.get bytes 0 != '\005' then - failwith - "Not a piece of packed Michelson data (must start with `0x05`)" - else return_unit) - >>=? fun () -> - (* Remove first byte *) - let bytes = Bytes.sub bytes 1 (Bytes.length bytes - 1) in - match - Data_encoding.Binary.of_bytes_opt - Alpha_context.Script.expr_encoding - bytes - with - | None -> failwith "Could not decode bytes" - | Some expr -> - cctxt#message "%a" Michelson_v1_printer.print_expr_unwrapped expr - >>= fun () -> return_unit); - command - ~group - ~desc:"Ask the node to normalize a script." - (args1 (unparsing_mode_arg ~default:"Readable")) - (prefixes ["normalize"; "script"] @@ Program.source_param @@ stop) - (fun unparsing_mode program cctxt -> - Lwt.return @@ Micheline_parser.no_parsing_error program - >>=? fun program -> - Plugin.RPC.Scripts.normalize_script - cctxt - (cctxt#chain, cctxt#block) - ~script:program.expanded - ~unparsing_mode - >>= function - | Ok program -> - cctxt#message - "%a" - (fun ppf () : unit -> - Michelson_v1_printer.print_expr_unwrapped ppf program) - () - >>= fun () -> return_unit - | Error errs -> - cctxt#warning - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:false - ~show_source:false - ?parsed:None) - errs - >>= fun () -> cctxt#error "ill-typed script"); - command - ~group - ~desc:"Ask the node to normalize a data expression." - (args2 (unparsing_mode_arg ~default:"Readable") legacy_switch) - (prefixes ["normalize"; "data"] - @@ param - ~name:"data" - ~desc:"the data expression to normalize" - data_parameter - @@ prefixes ["of"; "type"] - @@ param ~name:"type" ~desc:"type of the data expression" data_parameter - @@ stop) - (fun (unparsing_mode, legacy) data typ cctxt -> - Plugin.RPC.Scripts.normalize_data - cctxt - (cctxt#chain, cctxt#block) - ~legacy - ~data:data.expanded - ~ty:typ.expanded - ~unparsing_mode - >>= function - | Ok expr -> - cctxt#message "%a" Michelson_v1_printer.print_expr_unwrapped expr - >>= fun () -> return_unit - | Error errs -> - cctxt#warning - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:false - ~show_source:false - ?parsed:None) - errs - >>= fun () -> cctxt#error "ill-typed data expression"); - command - ~group - ~desc:"Ask the node to normalize a type." - no_options - (prefixes ["normalize"; "type"] - @@ param - ~name:"typ" - ~desc:"the Michelson type to normalize" - data_parameter - @@ stop) - (fun () typ cctxt -> - Plugin.RPC.Scripts.normalize_type - cctxt - (cctxt#chain, cctxt#block) - ~ty:typ.expanded - >>= function - | Ok expr -> - cctxt#message "%a" Michelson_v1_printer.print_expr_unwrapped expr - >>= fun () -> return_unit - | Error errs -> - cctxt#warning - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:false - ~show_source:false - ?parsed:None) - errs - >>= fun () -> cctxt#error "ill-formed type"); - command - ~group - ~desc: - "Sign a raw sequence of bytes and display it using the format expected \ - by Michelson instruction `CHECK_SIGNATURE`." - no_options - (prefixes ["sign"; "bytes"] - @@ bytes_parameter ~name:"data" ~desc:"the raw data to sign" - @@ prefixes ["for"] - @@ Client_keys.Secret_key.source_param @@ stop) - (fun () bytes sk cctxt -> - Client_keys.sign cctxt sk bytes >>=? fun signature -> - cctxt#message "Signature: %a" Signature.pp signature >>= fun () -> - return_unit); - command - ~group - ~desc: - "Check the signature of a byte sequence as per Michelson instruction \ - `CHECK_SIGNATURE`." - (args1 (switch ~doc:"Use only exit codes" ~short:'q' ~long:"quiet" ())) - (prefixes ["check"; "that"; "bytes"] - @@ bytes_parameter ~name:"bytes" ~desc:"the signed data" - @@ prefixes ["were"; "signed"; "by"] - @@ Client_keys.Public_key.alias_param ~name:"key" - @@ prefixes ["to"; "produce"] - @@ param - ~name:"signature" - ~desc:"the signature to check" - signature_parameter - @@ stop) - (fun quiet - bytes - (_, (key_locator, _)) - signature - (cctxt : #Protocol_client_context.full) -> - Client_keys.check key_locator signature bytes >>=? function - | false -> cctxt#error "invalid signature" - | true -> - if quiet then return_unit - else - cctxt#message "Signature check successful." >>= fun () -> - return_unit); - command - ~group - ~desc:"Ask the type of an entrypoint of a script." - (args2 emacs_mode_switch no_print_source_flag) - (prefixes ["get"; "script"; "entrypoint"; "type"; "of"] - @@ string ~name:"entrypoint" ~desc:"the entrypoint to describe" - @@ prefixes ["for"] - @@ Program.source_param @@ stop) - (fun ((emacs_mode, no_print_source) as setup) entrypoint program cctxt -> - handle_parsing_error "entrypoint" cctxt setup program @@ fun program -> - entrypoint_type - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - program - ~entrypoint - >>= fun entrypoint_type -> - print_entrypoint_type - ~emacs:emacs_mode - ~show_source:(not no_print_source) - ~parsed:program - ~entrypoint - cctxt - entrypoint_type); - command - ~group - ~desc:"Ask the node to list the entrypoints of a script." - (args2 emacs_mode_switch no_print_source_flag) - (prefixes ["get"; "script"; "entrypoints"; "for"] - @@ Program.source_param @@ stop) - (fun ((emacs_mode, no_print_source) as setup) program cctxt -> - handle_parsing_error "entrypoints" cctxt setup program @@ fun program -> - list_entrypoints cctxt ~chain:cctxt#chain ~block:cctxt#block program - >>= fun entrypoints -> - print_entrypoints_list - ~emacs:emacs_mode - ~show_source:(not no_print_source) - ~parsed:program - cctxt - entrypoints); - command - ~group - ~desc: - "Ask the node to list the unreachable paths in a script's parameter \ - type." - (args2 emacs_mode_switch no_print_source_flag) - (prefixes ["get"; "script"; "unreachable"; "paths"; "for"] - @@ Program.source_param @@ stop) - (fun ((emacs_mode, no_print_source) as setup) program cctxt -> - handle_parsing_error "entrypoints" cctxt setup program @@ fun program -> - list_unreachables cctxt ~chain:cctxt#chain ~block:cctxt#block program - >>= fun entrypoints -> - print_unreachables - ~emacs:emacs_mode - ~show_source:(not no_print_source) - ~parsed:program - cctxt - entrypoints); - command - ~group - ~desc:"Ask the node to expand the Michelson macros in a script." - no_options - (prefixes ["expand"; "macros"; "in"] @@ Program.source_param @@ stop) - (fun () program (cctxt : Protocol_client_context.full) -> - Lwt.return @@ Micheline_parser.no_parsing_error program - >>=? fun program -> - cctxt#message - "%a" - (fun ppf () : unit -> - Michelson_v1_printer.print_expr_unwrapped ppf program.expanded) - () - >>= fun () -> return_unit); - command - ~desc: - "Conversion of Michelson script from Micheline, JSON or binary to \ - Micheline, JSON, binary or OCaml" - (args3 zero_loc_switch legacy_switch enforce_indentation_flag) - (prefixes ["convert"; "script"] - @@ file_or_literal_param () @@ prefix "from" @@ convert_input_format_param - @@ prefix "to" @@ convert_output_format_param @@ stop) - (fun (zero_loc, legacy, check) - (_, expr_string) - from_format - to_format - (cctxt : Protocol_client_context.full) -> - (match from_format with - | `Michelson -> - let program = - Michelson_v1_parser.parse_toplevel ~check expr_string - in - Lwt.return @@ Micheline_parser.no_parsing_error program - >>=? fun program -> - (typecheck_program - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~legacy - ~show_types:true - program - >>= function - | Error _ as res -> - print_typecheck_result - ~emacs:false - ~show_types:true - ~print_source_on_error:true - program - res - cctxt - | Ok _ -> return_unit) - >>=? fun () -> return program.expanded - | `JSON -> ( - match Data_encoding.Json.from_string expr_string with - | Error err -> cctxt#error "%s" err - | Ok json -> - safe_decode_json cctxt Alpha_context.Script.expr_encoding json) - | `Binary -> ( - bytes_of_prefixed_string expr_string >>=? fun bytes -> - match - Data_encoding.Binary.of_bytes_opt - Alpha_context.Script.expr_encoding - bytes - with - | None -> failwith "Could not decode bytes" - | Some expr -> return expr)) - >>=? fun (expression : Alpha_context.Script.expr) -> - let output = - match to_format with - | `Michelson -> - Micheline_printer.printable - Michelson_v1_primitives.string_of_prim - expression - |> Format.asprintf "%a" Micheline_printer.print_expr - | `JSON -> - Data_encoding.Json.( - construct Alpha_context.Script.expr_encoding expression - |> to_string) - | `Binary -> - Format.asprintf - "0x%s" - (Data_encoding.Binary.( - to_bytes_exn Alpha_context.Script.expr_encoding expression) - |> Hex.of_bytes |> Hex.show) - | `OCaml -> - Michelson_v1_printer.micheline_string_of_expression - ~zero_loc - expression - in - cctxt#message "%s" output >>= fun () -> return_unit); - command - ~desc: - "Conversion of Micheline expression from Micheline, JSON or binary to \ - Micheline, JSON, binary or OCaml" - (args2 zero_loc_switch data_type_arg) - (prefixes ["convert"; "data"] - @@ file_or_literal_param () @@ prefix "from" @@ convert_input_format_param - @@ prefix "to" @@ convert_output_format_param @@ stop) - (fun (zero_loc, data_ty) - (_, data_string) - from_format - to_format - (cctxt : Protocol_client_context.full) -> - let micheline_of_expr expr = - Micheline_printer.printable - Michelson_v1_primitives.string_of_prim - expr - |> Format.asprintf "%a" Micheline_printer.print_expr - in - let typecheck_parsed ~data ~ty = - Client_proto_programs.typecheck_data - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~data - ~ty - () - >>= function - | Error errs -> - failwith - "%a" - (Michelson_v1_error_reporter.report_errors - ~details:false - ~show_source:false - ?parsed:None) - errs - | Ok _gas -> return data.expanded - in - let typecheck_expr ~expr ~ty = - let data_string = micheline_of_expr expr in - parse_expr data_string >>=? fun data -> typecheck_parsed ~data ~ty - in - (match from_format with - | `Michelson -> ( - parse_expr data_string >>=? fun data -> - match data_ty with - | Some ty -> typecheck_parsed ~data ~ty - | None -> return data.expanded) - | `JSON -> ( - match Data_encoding.Json.from_string data_string with - | Error err -> cctxt#error "%s" err - | Ok json -> ( - safe_decode_json cctxt Alpha_context.Script.expr_encoding json - >>=? fun expr -> - match data_ty with - | None -> return expr - | Some ty -> typecheck_expr ~expr ~ty)) - | `Binary -> ( - bytes_of_prefixed_string data_string >>=? fun bytes -> - match - Data_encoding.Binary.of_bytes_opt - Alpha_context.Script.expr_encoding - bytes - with - | None -> failwith "Could not decode bytes" - | Some expr -> ( - match data_ty with - | None -> return expr - | Some ty -> typecheck_expr ~expr ~ty))) - >>=? fun (expression : Alpha_context.Script.expr) -> - let output = - match to_format with - | `Michelson -> micheline_of_expr expression - | `JSON -> - Data_encoding.Json.( - construct Alpha_context.Script.expr_encoding expression - |> to_string) - | `Binary -> - Format.asprintf - "0x%s" - (Data_encoding.Binary.( - to_bytes_exn Alpha_context.Script.expr_encoding expression) - |> Hex.of_bytes |> Hex.show) - | `OCaml -> - Michelson_v1_printer.micheline_string_of_expression - ~zero_loc - expression - in - cctxt#message "%s" output >>= fun () -> return_unit); - command - ~group - ~desc:"Ask the node to run a TZIP-4 view." - (args6 - source_arg - payer_arg - run_gas_limit_arg - (unparsing_mode_arg ~default:"Readable") - now_arg - level_arg) - (prefixes ["run"; "tzip4"; "view"] - @@ param ~name:"entrypoint" ~desc:"the name of the view" string_parameter - @@ prefixes ["on"; "contract"] - @@ ContractAlias.destination_param - ~name:"contract" - ~desc:"viewed contract" - @@ prefixes ["with"; "input"] - @@ param ~name:"input" ~desc:"the input data" data_parameter - @@ stop) - (fun (source, payer, gas, unparsing_mode, now, level) - entrypoint - (_, contract) - input - cctxt -> - let source = Option.map snd source in - let payer = Option.map snd payer in - Client_proto_programs.run_view - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - { - shared_params = - {input; unparsing_mode; now; level; source; payer; gas}; - contract; - entrypoint; - } - >>= fun res -> print_view_result cctxt res); - ] diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_programs_commands.mli b/src/proto_012_Psithaca/lib_client_commands/client_proto_programs_commands.mli deleted file mode 100644 index 6e352b98be7f..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_programs_commands.mli +++ /dev/null @@ -1,26 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_stresstest_commands.ml b/src/proto_012_Psithaca/lib_client_commands/client_proto_stresstest_commands.ml deleted file mode 100644 index d302206a9834..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_stresstest_commands.ml +++ /dev/null @@ -1,1004 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type transfer_strategy = - | Fixed_amount of {mutez : Tez.t} (** Amount to transfer *) - | Evaporation of {fraction : float} - (** Maximum fraction of current wealth to transfer. - Minimum amount is 1 mutez regardless of total wealth. *) - -type parameters = { - seed : int; - fresh_probability : float; - (** Per-transfer probability that the destination will be fresh *) - tps : float; (** Transaction per seconds target *) - strategy : transfer_strategy; - fee_mutez : Tez.t; (** fees for each transfer, in mutez *) - gas_limit : Gas.Arith.integral; (** gas limit per operation *) - storage_limit : Z.t; (** storage limit per operation *) - account_creation_storage : Z.t; - (** upper bound on bytes consumed when creating a tz1 account *) - total_transfers : int option; - (** total number of transfers to perform; unbounded if None *) - single_op_per_pkh_per_block : bool; - (** if true, a single operation will be injected by pkh by block to - improve the chance for the injected operations to be included in the - next block *) -} - -type origin = Explicit | Wallet_pkh | Wallet_alias of string - -type source = { - pkh : public_key_hash; - pk : public_key; - sk : Signature.secret_key; -} - -type input_source = - | Explicit of source - | Wallet_alias of string - | Wallet_pkh of public_key_hash - -type source_origin = {source : source; origin : origin} - -type transfer = { - src : source; - dst : public_key_hash; - fee : Tez.t; - amount : Tez.t; - counter : Z.t option; - fresh_dst : bool; -} - -type state = { - current_head_on_start : Block_hash.t; - counters : (Block_hash.t * Z.t) Signature.Public_key_hash.Table.t; - mutable pool : source_origin list; - mutable pool_size : int; - (** [Some l] if [single_op_per_pkh_per_block] is true *) - mutable shuffled_pool : source list option; - mutable revealed : Signature.Public_key_hash.Set.t; - mutable last_block : Block_hash.t; - new_block_condition : unit Lwt_condition.t; - injected_operations : Operation_hash.t list Block_hash.Table.t; -} - -let verbose = ref false - -let debug = ref false - -let debug_msg msg = if !debug then msg () else Lwt.return_unit - -let default_parameters = - { - seed = 0x533D; - fresh_probability = 0.001; - tps = 5.0; - strategy = Fixed_amount {mutez = Tez.one}; - fee_mutez = Tez.of_mutez_exn 2_000L; - gas_limit = Gas.Arith.integral_of_int_exn 1_600; - (* [gas_limit] corresponds to a slight overapproximation of the - gas needed to inject an operation. It was obtained by simulating - the operation using the client. *) - storage_limit = Z.zero; - account_creation_storage = Z.of_int 300; - (* [account_creation_storage] corresponds to a slight overapproximation - of the storage consumed when allocating a new implicit account. - It was obtained by simulating the operation using the client. *) - total_transfers = None; - single_op_per_pkh_per_block = false; - } - -let input_source_encoding = - let open Data_encoding in - union - [ - case - ~title:"explicit" - (Tag 0) - (obj3 - (req "pkh" Signature.Public_key_hash.encoding) - (req "pk" Signature.Public_key.encoding) - (req "sk" Signature.Secret_key.encoding)) - (function Explicit {pkh; pk; sk} -> Some (pkh, pk, sk) | _ -> None) - (fun (pkh, pk, sk) -> Explicit {pkh; pk; sk}); - case - ~title:"alias" - (Tag 1) - (obj1 (req "alias" Data_encoding.string)) - (function Wallet_alias alias -> Some alias | _ -> None) - (fun alias -> Wallet_alias alias); - case - ~title:"pkh" - (Tag 2) - (obj1 (req "pkh" Signature.Public_key_hash.encoding)) - (function Wallet_pkh pkh -> Some pkh | _ -> None) - (fun pkh -> Wallet_pkh pkh); - ] - -let input_source_list_encoding = Data_encoding.list input_source_encoding - -let injected_operations_encoding = - let open Data_encoding in - list - (obj2 - (req "block_hash_when_injected" Block_hash.encoding) - (req "operation_hashes" (list Operation_hash.encoding))) - -let parse_strategy s = - match String.split ~limit:1 ':' s with - | ["fixed"; parameter] -> ( - match int_of_string parameter with - | exception _ -> Error "invalid integer literal" - | mutez when mutez <= 0 -> Error "negative amount" - | mutez -> ( - match Tez.of_mutez (Int64.of_int mutez) with - | None -> Error "invalid mutez" - | Some mutez -> Ok (Fixed_amount {mutez}))) - | ["evaporation"; parameter] -> ( - match float_of_string parameter with - | exception _ -> Error "invalid float literal" - | fraction when fraction < 0.0 || fraction > 1.0 -> - Error "invalid evaporation rate" - | fraction -> Ok (Evaporation {fraction})) - | _ -> Error "invalid argument" - -(** This command uses two different data structures for sources: - - The in-output files one, - - The normalized one. - - The data structure used for in-output files does not directly contain the - data required to forge operations. For efficiency purposes, the sources are - converted into a normalized data structure that contains all the required - data to forge operations and the format originally used to be able to - revert this conversion. *) - -(** [normalize_source cctxt src] converts [src] from in-output data structure - to normalized one. If the conversion fails, [None] is returned and a - warning message is printed in [cctxt]. - - Only unencrypted and encrypted sources from the wallet of [cctxt] are - supported. *) -let normalize_source cctxt = - let sk_of_sk_uri sk_uri = - match - Signature.Secret_key.of_b58check - (Uri.path (sk_uri : Client_keys.sk_uri :> Uri.t)) - with - | Ok sk -> Lwt.return_some sk - | Error _ -> ( - Tezos_signer_backends.Encrypted.decrypt cctxt sk_uri >>= function - | Error _ -> Lwt.return_none - | Ok sk -> Lwt.return_some sk) - in - let key_from_alias alias = - let warning msg alias = - cctxt#warning msg alias >>= fun () -> Lwt.return_none - in - (Client_keys.alias_keys cctxt alias >>= function - | Error _ | Ok None -> warning "Alias \"%s\" not found in the wallet" alias - | Ok (Some (_, None, _)) | Ok (Some (_, _, None)) -> - warning - "Alias \"%s\" does not contain public or secret key and could not \ - be used for stresstest" - alias - | Ok (Some (pkh, Some pk, Some sk_uri)) -> ( - sk_of_sk_uri sk_uri >>= function - | None -> - warning - "Cannot extract the secret key form the alias \"%s\" of the \ - wallet" - alias - | Some sk -> - Lwt.return_some - {source = {pkh; pk; sk}; origin = Wallet_alias alias})) - >>= function - | None -> warning "Source given as alias \"%s\" ignored" alias - | key -> Lwt.return key - in - let key_from_wallet pkh = - let warning msg pkh = - cctxt#warning msg Signature.Public_key_hash.pp pkh >>= fun () -> - Lwt.return_none - in - (Client_keys.get_key cctxt pkh >>= function - | Error _ -> warning "Pkh \"%a\" not found in the wallet" pkh - | Ok (alias, pk, sk_uri) -> ( - sk_of_sk_uri sk_uri >>= function - | None -> - cctxt#warning - "Cannot extract the secret key form the pkh \"%a\" (alias: \ - \"%s\") of the wallet" - Signature.Public_key_hash.pp - pkh - alias - >>= fun () -> Lwt.return_none - | Some sk -> - Lwt.return_some {source = {pkh; pk; sk}; origin = Wallet_pkh})) - >>= function - | None -> warning "Source given as pkh \"%a\" ignored" pkh - | key -> Lwt.return key - in - function - | Explicit source -> Lwt.return_some {source; origin = Explicit} - | Wallet_alias alias -> key_from_alias alias - | Wallet_pkh pkh -> key_from_wallet pkh - -(** [unnormalize_source src_org] converts [src_org] from normalized data - structure to in-output one. *) -let unnormalize_source src_org = - match src_org.origin with - | Explicit -> Explicit src_org.source - | Wallet_pkh -> Wallet_pkh src_org.source.pkh - | Wallet_alias alias -> Wallet_alias alias - -(** Samples from [state.pool]. Used to generate the destination of a - transfer, and its source only when [state.shuffled_pool] is [None] - meaning that [--single-op-per-pkh-per-block] is not set. *) -let sample_any_source_from_pool state rng_state = - let idx = Random.State.int rng_state state.pool_size in - match List.nth state.pool idx with - | None -> assert false - | Some src_org -> Lwt.return src_org.source - -(** Generates the source of a transfer. If [state.shuffled_pool] has a - value (meaning that [--single-op-per-pkh-per-block] is active) then - it is sampled from there, otherwise from [state.pool]. *) -let rec sample_source_from_pool state rng_state - (cctxt : Protocol_client_context.full) = - match state.shuffled_pool with - | None -> sample_any_source_from_pool state rng_state - | Some (source :: l) -> - state.shuffled_pool <- Some l ; - debug_msg (fun () -> - cctxt#message - "sample_transfer: %d unused sources for the block next to %a" - (List.length l) - Block_hash.pp - state.last_block) - >>= fun () -> Lwt.return source - | Some [] -> - cctxt#message - "all available sources have been used for block next to %a" - Block_hash.pp - state.last_block - >>= fun () -> - Lwt_condition.wait state.new_block_condition >>= fun () -> - sample_source_from_pool state rng_state cctxt - -let random_seed rng_state = - Bytes.init 32 (fun _ -> Char.chr (Random.State.int rng_state 256)) - -let generate_fresh_source pool rng_state = - let seed = random_seed rng_state in - let (pkh, pk, sk) = Signature.generate_key ~seed () in - let fresh = {source = {pkh; pk; sk}; origin = Explicit} in - pool.pool <- fresh :: pool.pool ; - pool.pool_size <- pool.pool_size + 1 ; - fresh.source - -(* [on_new_head cctxt f] calls [f head] each time there is a new head - received by the streamed RPC /monitor/heads/main *) -let on_new_head (cctxt : Protocol_client_context.full) f = - Shell_services.Monitor.heads cctxt `Main >>=? fun (heads_stream, stopper) -> - Lwt_stream.iter_s f heads_stream >>= fun () -> - stopper () ; - return_unit - -(* We perform rejection sampling of valid sources. - We could maintain a local cache of existing contracts with sufficient balance. *) -let rec sample_transfer (cctxt : Protocol_client_context.full) chain block - (parameters : parameters) (state : state) rng_state = - sample_source_from_pool state rng_state cctxt >>= fun src -> - Alpha_services.Contract.balance - cctxt - (chain, block) - (Contract.implicit_contract src.pkh) - >>=? fun tez -> - if Tez.(tez = zero) then - debug_msg (fun () -> - cctxt#message - "sample_transfer: invalid balance %a" - Signature.Public_key_hash.pp - src.pkh) - >>= fun () -> - (* Sampled source has zero balance: the transfer that created that - address was not included yet. Retry *) - sample_transfer cctxt chain block parameters state rng_state - else - let fresh = - Random.State.float rng_state 1.0 < parameters.fresh_probability - in - (if fresh then Lwt.return (generate_fresh_source state rng_state) - else sample_any_source_from_pool state rng_state) - >>= fun dest -> - let amount = - match parameters.strategy with - | Fixed_amount {mutez} -> mutez - | Evaporation {fraction} -> - let mutez = Int64.to_float (Tez.to_mutez tez) in - let max_fraction = Int64.of_float (mutez *. fraction) in - let amount = - if max_fraction = 0L then 1L - else max 1L (Random.State.int64 rng_state max_fraction) - in - Tez.of_mutez_exn amount - in - let fee = parameters.fee_mutez in - return {src; dst = dest.pkh; fee; amount; counter = None; fresh_dst = fresh} - -let inject_contents (cctxt : Protocol_client_context.full) chain branch sk - contents = - let bytes = - Data_encoding.Binary.to_bytes_exn - Operation.unsigned_encoding - ({branch}, Contents_list contents) - in - let signature = - Some (Signature.sign ~watermark:Signature.Generic_operation sk bytes) - in - let op : _ Operation.t = - {shell = {branch}; protocol_data = {contents; signature}} - in - let bytes = - Data_encoding.Binary.to_bytes_exn Operation.encoding (Operation.pack op) - in - Shell_services.Injection.operation cctxt ~chain bytes - -(* counter _must_ be set before calling this function *) -let manager_op_of_transfer parameters - {src; dst; fee; amount; counter; fresh_dst} = - let source = src.pkh in - let gas_limit = parameters.gas_limit in - let storage_limit = - if fresh_dst then - Z.add parameters.account_creation_storage parameters.storage_limit - else parameters.storage_limit - in - let operation = - let parameters = - let open Tezos_micheline in - Script.lazy_expr - @@ Micheline.strip_locations - (Prim (0, Michelson_v1_primitives.D_Unit, [], [])) - in - let entrypoint = "default" in - let destination = Contract.implicit_contract dst in - Transaction {amount; parameters; entrypoint; destination} - in - match counter with - | None -> assert false - | Some counter -> - Manager_operation - {source; fee; counter; operation; gas_limit; storage_limit} - -let cost_of_manager_operation = Gas.Arith.integral_of_int_exn 1_000 - -let inject_transfer (cctxt : Protocol_client_context.full) parameters state - rng_state chain block transfer = - Alpha_services.Contract.counter cctxt (chain, block) transfer.src.pkh - >>=? fun pcounter -> - Shell_services.Blocks.hash cctxt ~chain ~block () >>=? fun branch -> - (* If there is a new block refresh the fresh_pool *) - if not (Block_hash.equal branch state.last_block) then ( - state.last_block <- branch ; - if Option.is_some state.shuffled_pool then - state.shuffled_pool <- - Some - (List.shuffle - ~rng_state - (List.map (fun src_org -> src_org.source) state.pool))) ; - let freshest_counter = - match - Signature.Public_key_hash.Table.find state.counters transfer.src.pkh - with - | None -> - (* This is the first operation we inject for this pkh: the counter given - by the RPC _must_ be the freshest one. *) - pcounter - | Some (previous_branch, previous_counter) -> - if Block_hash.equal branch previous_branch then - (* We already injected an operation on top of this block: the one stored - locally is the freshest one. *) - previous_counter - else - (* It seems the block changed since we last injected an operation: - this invalidates the previously stored counter. We return the counter - given by the RPC. *) - pcounter - in - (if Signature.Public_key_hash.Set.mem transfer.src.pkh state.revealed then - return true - else ( - (* Either the [manager_key] RPC tells us the key is already - revealed, or we immediately inject a reveal operation: in any - case the key is revealed in the end. *) - state.revealed <- - Signature.Public_key_hash.Set.add transfer.src.pkh state.revealed ; - Alpha_services.Contract.manager_key cctxt (chain, block) transfer.src.pkh - >>=? fun pk_opt -> return (Option.is_some pk_opt))) - >>=? fun already_revealed -> - (if not already_revealed then ( - let reveal_counter = Z.succ freshest_counter in - let transf_counter = Z.succ reveal_counter in - let reveal = - Manager_operation - { - source = transfer.src.pkh; - fee = Tez.zero; - counter = reveal_counter; - gas_limit = cost_of_manager_operation; - storage_limit = Z.zero; - operation = Reveal transfer.src.pk; - } - in - let manager_op = - manager_op_of_transfer - parameters - {transfer with counter = Some transf_counter} - in - let list = Cons (reveal, Single manager_op) in - Signature.Public_key_hash.Table.remove state.counters transfer.src.pkh ; - Signature.Public_key_hash.Table.add - state.counters - transfer.src.pkh - (branch, transf_counter) ; - (if !verbose then - cctxt#message - "injecting reveal+transfer from %a (counters=%a,%a) to %a" - Signature.Public_key_hash.pp - transfer.src.pkh - Z.pp_print - reveal_counter - Z.pp_print - transf_counter - Signature.Public_key_hash.pp - transfer.dst - else Lwt.return_unit) - >>= fun () -> - (* NB: regardless of our best efforts to keep track of counters, injection can fail with - "counter in the future" if a block switch happens in between the moment we - get the branch and the moment we inject, and the new block does not include - all the operations we injected. *) - inject_contents cctxt chain branch transfer.src.sk list) - else - let transf_counter = Z.succ freshest_counter in - let manager_op = - manager_op_of_transfer - parameters - {transfer with counter = Some transf_counter} - in - let list = Single manager_op in - Signature.Public_key_hash.Table.remove state.counters transfer.src.pkh ; - Signature.Public_key_hash.Table.add - state.counters - transfer.src.pkh - (branch, transf_counter) ; - (if !verbose then - cctxt#message - "injecting transfer from %a (counter=%a) to %a" - Signature.Public_key_hash.pp - transfer.src.pkh - Z.pp_print - transf_counter - Signature.Public_key_hash.pp - transfer.dst - else Lwt.return_unit) - >>= fun () -> - (* See comment above. *) - inject_contents cctxt chain branch transfer.src.sk list) - >>= function - | Ok op_hash -> - debug_msg (fun () -> - cctxt#message - "inject_transfer: op injected %a" - Operation_hash.pp - op_hash) - >>= fun () -> - let ops = - Option.value - ~default:[] - (Block_hash.Table.find state.injected_operations branch) - in - Block_hash.Table.replace state.injected_operations branch (op_hash :: ops) ; - return_unit - | Error e -> - debug_msg (fun () -> - cctxt#message - "inject_transfer: error, op not injected: %a" - Error_monad.pp_print_trace - e) - >>= fun () -> return_unit - -let save_injected_operations (cctxt : Protocol_client_context.full) state = - let json = - Data_encoding.Json.construct - injected_operations_encoding - (Block_hash.Table.fold - (fun k v acc -> (k, v) :: acc) - state.injected_operations - []) - in - let path = - Filename.temp_file "client-stresstest-injected_operations-" ".json" - in - cctxt#message "writing injected operations in file %s" path >>= fun () -> - Lwt_utils_unix.Json.write_file path json >>= function - | Error e -> - cctxt#message - "could not write injected operations json file: %a" - Error_monad.pp_print_trace - e - | Ok _ -> Lwt.return_unit - -let stat_on_exit (cctxt : Protocol_client_context.full) state = - let ratio_injected_included_op () = - Shell_services.Blocks.hash cctxt () >>=? fun current_head_on_exit -> - let inter_cardinal s1 s2 = - Operation_hash.Set.cardinal - (Operation_hash.Set.inter - (Operation_hash.Set.of_list s1) - (Operation_hash.Set.of_list s2)) - in - let get_included_ops older_block = - let rec get_included_ops block acc_included_ops = - if block = older_block then return acc_included_ops - else - Shell_services.Chain.Blocks.Operation_hashes.operation_hashes_in_pass - cctxt - ~chain:`Main - ~block:(`Hash (block, 0)) - 3 - >>=? fun included_ops -> - Shell_services.Blocks.list - cctxt - ~chain:`Main - ~heads:[block] - ~length:2 - () - >>=? function - | [[current; predecessor]] when current = block -> - get_included_ops - predecessor - (List.append acc_included_ops included_ops) - | _ -> cctxt#error "Error while computing stats: invalid block list" - in - get_included_ops current_head_on_exit [] - in - let injected_ops = - Block_hash.Table.fold - (fun k l acc -> - (* The operations injected during the last block are ignored because - they should not be currently included. *) - if current_head_on_exit <> k then List.append acc l else acc) - state.injected_operations - [] - in - get_included_ops state.current_head_on_start >>=? fun included_ops -> - let included_ops_count = inter_cardinal injected_ops included_ops in - debug_msg (fun () -> - cctxt#message - "injected : %a\nincluded: %a" - (Format.pp_print_list Operation_hash.pp) - injected_ops - (Format.pp_print_list Operation_hash.pp) - included_ops) - >>= fun () -> - let injected_ops_count = List.length injected_ops in - cctxt#message - "%s of the injected operations have been included (%d injected, %d \ - included). Note that the operations injected during the last block are \ - ignored because they should not be currently included." - (if Int.equal injected_ops_count 0 then "N/A" - else Format.sprintf "%d%%" (included_ops_count * 100 / injected_ops_count)) - injected_ops_count - included_ops_count - >>= fun () -> return_unit - in - ratio_injected_included_op () - -let launch (cctxt : Protocol_client_context.full) (parameters : parameters) - state rng_state save_pool_callback = - let injected = ref 0 in - let dt = 1. /. parameters.tps in - let terminated () = - match parameters.total_transfers with - | None -> false - | Some bound -> bound <= !injected - in - let rec loop () = - if terminated () then - save_pool_callback () >>= fun () -> - save_injected_operations cctxt state >>= fun () -> - stat_on_exit cctxt state - else - let start = Mtime_clock.elapsed () in - debug_msg (fun () -> cctxt#message "launch.loop: invoke sample_transfer") - >>= fun () -> - sample_transfer cctxt cctxt#chain cctxt#block parameters state rng_state - >>=? fun transfer -> - debug_msg (fun () -> cctxt#message "launch.loop: invoke inject_transfer") - >>= fun () -> - inject_transfer - cctxt - parameters - state - rng_state - cctxt#chain - cctxt#block - transfer - >>=? fun () -> - incr injected ; - let stop = Mtime_clock.elapsed () in - let elapsed = Mtime.Span.(to_s stop -. to_s start) in - let remaining = dt -. elapsed in - (if remaining <= 0.0 then - cctxt#warning - "warning: tps target could not be reached, consider using a lower \ - value for --tps" - else Lwt_unix.sleep remaining) - >>= loop - in - (* True, if and only if [single_op_per_pkh_per_block] is true. *) - if Option.is_some state.shuffled_pool then - dont_wait - (fun () -> - on_new_head cctxt (fun (block, _) -> - if not (Block_hash.equal block state.last_block) then ( - state.last_block <- block ; - state.shuffled_pool <- - Some - (List.shuffle - ~rng_state - (List.map (fun src_org -> src_org.source) state.pool))) ; - Lwt_condition.broadcast state.new_block_condition () ; - Lwt.return_unit)) - (fun trace -> - ignore - (cctxt#error - "an error while getting the new head has been returned: %a" - Error_monad.pp_print_trace - trace)) - (fun exn -> - ignore - (cctxt#error - "an exception while getting the new head has been raised: %s" - (Printexc.to_string exn))) ; - loop () - -let group = - Clic.{name = "stresstest"; title = "Commands for stress-testing the network"} - -type pool_source = - | From_string of {json : Ezjsonm.value} - | From_file of {path : string; json : Ezjsonm.value} - -let json_of_pool_source = function - | From_string {json} | From_file {json; _} -> json - -let json_file_or_text_parameter = - Clic.parameter (fun _ p -> - match String.split ~limit:1 ':' p with - | ["text"; text] -> return (From_string {json = Ezjsonm.from_string text}) - | ["file"; path] -> - Lwt_utils_unix.Json.read_file path >|=? fun json -> - From_file {path; json} - | _ -> ( - if Sys.file_exists p then - Lwt_utils_unix.Json.read_file p >|=? fun json -> - From_file {path = p; json} - else - try return (From_string {json = Ezjsonm.from_string p}) - with Ezjsonm.Parse_error _ -> - failwith "Neither an existing file nor valid JSON: '%s'" p)) - -let seed_arg = - let open Clic in - arg - ~long:"seed" - ~placeholder:"int" - ~doc:"random seed" - (parameter (fun (cctxt : Protocol_client_context.full) s -> - match int_of_string s with - | exception _ -> - cctxt#error - "While parsing --seed: could not convert argument to int" - | i -> return i)) - -let tps_arg = - let open Clic in - arg - ~long:"tps" - ~placeholder:"float" - ~doc:"transactions per seconds target" - (parameter (fun (cctxt : Protocol_client_context.full) s -> - match float_of_string s with - | exception _ -> - cctxt#error - "While parsing --tps: could not convert argument to float" - | f when f < 0.0 -> - cctxt#error "While parsing --tps: negative argument" - | f -> return f)) - -let fresh_probability_arg = - let open Clic in - arg - ~long:"fresh-probability" - ~placeholder:"float in [0;1]" - ~doc: - (Format.sprintf - "Probability for each transaction's destination to be a fresh \ - account. The default value is %g. This new account may then be used \ - as source or destination of subsequent transactions, just like the \ - accounts that were initially provided to the command. Note that when \ - [--single-op-per-pkh-per-block] is set, the new account will not be \ - used as source until the head changes." - default_parameters.fresh_probability) - (parameter (fun (cctxt : Protocol_client_context.full) s -> - match float_of_string s with - | exception _ -> - cctxt#error - "While parsing --fresh-probability: could not convert argument \ - to float" - | f when f < 0.0 || f > 1.0 -> - cctxt#error "While parsing --fresh-probability: invalid argument" - | f -> return f)) - -let strategy_arg = - let open Clic in - arg - ~long:"strategy" - ~placeholder:"fixed:mutez | evaporation:[0;1]" - ~doc:"wealth redistribution strategy" - (parameter (fun (cctxt : Protocol_client_context.full) s -> - match parse_strategy s with - | Error msg -> cctxt#error "While parsing --strategy: %s" msg - | Ok strategy -> return strategy)) - -let gas_limit_arg = - let open Clic in - let gas_limit_kind = - parameter (fun _ s -> - try - let v = Z.of_string s in - return (Gas.Arith.integral_exn v) - with _ -> failwith "invalid gas limit (must be a positive number)") - in - arg - ~long:"gas-limit" - ~short:'G' - ~placeholder:"amount" - ~doc: - (Format.asprintf - "Set the gas limit of the transaction instead of using the default \ - value of %a" - Gas.Arith.pp_integral - default_parameters.gas_limit) - gas_limit_kind - -let storage_limit_arg = - let open Clic in - let storage_limit_kind = - parameter (fun _ s -> - try - let v = Z.of_string s in - assert (Compare.Z.(v >= Z.zero)) ; - return v - with _ -> - failwith "invalid storage limit (must be a positive number of bytes)") - in - arg - ~long:"storage-limit" - ~short:'S' - ~placeholder:"amount" - ~doc: - (Format.asprintf - "Set the storage limit of the transaction instead of using the \ - default value of %a" - Z.pp_print - default_parameters.storage_limit) - storage_limit_kind - -let transfers_arg = - let open Clic in - arg - ~long:"transfers" - ~placeholder:"integer" - ~doc:"total number of transfers to perform, unbounded if not specified" - (parameter (fun (cctxt : Protocol_client_context.full) s -> - match int_of_string s with - | exception _ -> - cctxt#error "While parsing --transfers: invalid integer literal" - | i when i <= 0 -> - cctxt#error "While parsing --transfers: negative integer" - | i -> return i)) - -let single_op_per_pkh_per_block_arg = - Clic.switch - ~long:"single-op-per-pkh-per-block" - ~doc: - "ensure that the operations are not rejected by limiting the injection \ - to 1 operation per public_key_hash per block." - () - -let verbose_arg = - Clic.switch - ~long:"verbose" - ~doc:"Display detailed logs of the injected operations" - () - -let debug_arg = Clic.switch ~long:"debug" ~doc:"Display debug logs" () - -let set_option opt f x = Option.fold ~none:x ~some:(f x) opt - -let save_pool_callback (cctxt : Protocol_client_context.full) pool_source state - = - let json = - Data_encoding.Json.construct - input_source_list_encoding - (List.map unnormalize_source state.pool) - in - let catch_write_error = function - | Error e -> - cctxt#message - "could not write back json file: %a" - Error_monad.pp_print_trace - e - | Ok () -> Lwt.return_unit - in - match pool_source with - | From_string _ -> - (* If the initial pool was given directly as json, save pool to - a temp file. *) - let path = Filename.temp_file "client-stresstest-pool-" ".json" in - cctxt#message "writing back address pool in file %s" path >>= fun () -> - Lwt_utils_unix.Json.write_file path json >>= catch_write_error - | From_file {path; _} -> - (* If the pool specification was a json file, save pool to - the same file. *) - cctxt#message "writing back address pool in file %s" path >>= fun () -> - Lwt_utils_unix.Json.write_file path json >>= catch_write_error - -let generate_random_transactions = - let open Clic in - command - ~group - ~desc:"Generate random transactions" - (args11 - seed_arg - tps_arg - fresh_probability_arg - strategy_arg - Client_proto_args.fee_arg - gas_limit_arg - storage_limit_arg - transfers_arg - single_op_per_pkh_per_block_arg - verbose_arg - debug_arg) - (prefixes ["stresstest"; "transfer"; "using"] - @@ param - ~name:"sources.json" - ~desc: - {|List of accounts from which to perform transfers in JSON format. The input JSON must be an array of objects of the form {"pkh":"","pk":"","sk":""} or {"alias":""} or {"pkh":""} with the pkh, pk and sk encoded in B58 form."|} - json_file_or_text_parameter - @@ stop) - (fun ( seed, - tps, - freshp, - strat, - fee, - gas_limit, - storage_limit, - transfers, - single_op_per_pkh_per_block, - verbose_flag, - debug_flag ) - sources_json - (cctxt : Protocol_client_context.full) -> - verbose := verbose_flag ; - debug := debug_flag ; - let parameters = - default_parameters - |> set_option seed (fun parameter seed -> {parameter with seed}) - |> set_option tps (fun parameter tps -> {parameter with tps}) - |> set_option freshp (fun parameter fresh_probability -> - {parameter with fresh_probability}) - |> set_option strat (fun parameter strategy -> - {parameter with strategy}) - |> set_option fee (fun parameter fee_mutez -> - {parameter with fee_mutez}) - |> set_option gas_limit (fun parameter gas_limit -> - {parameter with gas_limit}) - |> set_option storage_limit (fun parameter storage_limit -> - {parameter with storage_limit}) - |> set_option transfers (fun parameter transfers -> - {parameter with total_transfers = Some transfers}) - |> fun parameter -> {parameter with single_op_per_pkh_per_block} - in - match - Data_encoding.Json.destruct - input_source_list_encoding - (json_of_pool_source sources_json) - with - | exception _ -> cctxt#error "Could not decode list of sources" - | [] -> cctxt#error "It is required to provide sources" - | sources -> - List.filter_map_p (normalize_source cctxt) sources >>= fun sources -> - let counters = Signature.Public_key_hash.Table.create 1023 in - let rng_state = Random.State.make [|parameters.seed|] in - Shell_services.Blocks.hash cctxt () >>=? fun current_head_on_start -> - let state = - { - current_head_on_start; - counters; - pool = sources; - pool_size = List.length sources; - shuffled_pool = - (if parameters.single_op_per_pkh_per_block then - Some - (List.shuffle - ~rng_state - (List.map (fun src_org -> src_org.source) sources)) - else None); - revealed = Signature.Public_key_hash.Set.empty; - last_block = current_head_on_start; - new_block_condition = Lwt_condition.create (); - injected_operations = Block_hash.Table.create 1023; - } - in - let exit_callback_id = - Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _retcode -> - stat_on_exit cctxt state >>= function - | Ok () -> Lwt.return_unit - | Error e -> - cctxt#message "Error: %a" Error_monad.pp_print_trace e) - in - let save_pool () = save_pool_callback cctxt sources_json state in - (* Register a callback for saving the pool when the tool is interrupted - through ctrl-c *) - let exit_callback_id = - Lwt_exit.register_clean_up_callback - ~loc:__LOC__ - ~after:[exit_callback_id] - (fun _retcode -> save_pool ()) - in - let save_injected_operations () = - save_injected_operations cctxt state - in - ignore - (Lwt_exit.register_clean_up_callback - ~loc:__LOC__ - ~after:[exit_callback_id] - (fun _retcode -> save_injected_operations ())) ; - launch cctxt parameters state rng_state save_pool) - -let commands network () = - match network with - | Some `Mainnet -> [] - | Some `Testnet | None -> [generate_random_transactions] diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_utils_commands.ml b/src/proto_012_Psithaca/lib_client_commands/client_proto_utils_commands.ml deleted file mode 100644 index 7f57941fb389..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_utils_commands.ml +++ /dev/null @@ -1,162 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Client_proto_utils - -let group = {Clic.name = "utilities"; title = "Utility Commands"} - -let unsigned_block_header_param = - let open Clic in - param - ~name:"unsigned block header" - ~desc:"A hex or JSON encoded unsigned block header" - @@ parameter (fun _ s -> - let bytes_opt = `Hex s |> Hex.to_bytes in - let enc = Protocol.Alpha_context.Block_header.unsigned_encoding in - Option.bind bytes_opt (Data_encoding.Binary.of_bytes_opt enc) - |> function - | Some s -> return s - | None -> ( - let error = - Exn - (Failure - "Cannot decode unsigned block header: is it valid JSON or \ - hexadecimal?") - in - let open Data_encoding.Json in - from_string s |> function - | Error _ -> fail error - | Ok json -> ( - try destruct enc json |> return with _ -> fail error))) - -let commands () = - let open Clic in - let string_param ~name ~desc = - param ~name ~desc Client_proto_args.string_parameter - in - let block_arg = - default_arg - ~long:"branch" - ~short:'b' - ~placeholder:"hash|tag" - ~doc: - "Block hash used to create the no-op operation to sign (possible tags \ - are 'head' and 'genesis'). Defaults to 'genesis'. Note that the the \ - genesis block hash is network-dependent." - ~default:(Block_services.to_string `Genesis) - (Client_config.block_parameter ()) - in - [ - command - ~group - ~desc: - "Sign a message and display it using the failing_noop operation. This \ - operation is not executable in the protocol. Please note that \ - signing/checking an arbitrary message in itself is not sufficient to \ - verify a key ownership" - (args1 block_arg) - (prefixes ["sign"; "message"] - @@ string_param ~name:"message" ~desc:"message to sign" - @@ prefixes ["for"] - @@ Client_keys.Secret_key.source_param - ~name:"src" - ~desc:"name of the signer contract" - @@ stop) - (fun block_head message src_sk cctxt -> - Shell_services.Blocks.hash cctxt ~chain:cctxt#chain ~block:block_head () - >>=? fun block -> - sign_message cctxt ~src_sk ~block ~message >>=? fun signature -> - cctxt#message "Signature: %a" Signature.pp signature >>= fun () -> - return_unit); - command - ~group - ~desc: - "Check the signature of an arbitrary message using the failing_noop \ - operation. Please note that signing/checking an arbitrary message in \ - itself is not sufficient to verify a key ownership." - (args2 - block_arg - (switch ~doc:"Use only exit codes" ~short:'q' ~long:"quiet" ())) - (prefixes ["check"; "that"; "message"] - @@ string_param ~name:"message" ~desc:"signed message" - @@ prefixes ["was"; "signed"; "by"] - @@ Client_keys.Public_key.alias_param - ~name:"signer" - ~desc:"name of the signer contract" - @@ prefixes ["to"; "produce"] - @@ param - ~name:"signature" - ~desc:"the signature to check" - Client_proto_args.signature_parameter - @@ stop) - (fun (block_head, quiet) - message - (_, (key_locator, _)) - signature - (cctxt : #Protocol_client_context.full) -> - Shell_services.Blocks.hash cctxt ~chain:cctxt#chain ~block:block_head () - >>=? fun block -> - check_message cctxt ~key_locator ~block ~quiet ~message ~signature - >>=? function - | false -> cctxt#error "invalid signature" - | true -> - if quiet then return_unit - else - cctxt#message "Signature check successful" >>= fun () -> - return_unit); - command - ~group - ~desc: - "Sign an arbitrary unsigned block header for a given delegate and \ - return the signed block." - no_options - (prefixes ["sign"; "block"] - @@ unsigned_block_header_param - @@ prefixes ["for"] - @@ Client_keys.Public_key_hash.source_param - ~name:"delegate" - ~desc:"signing delegate" - @@ stop) - (fun () - unsigned_block_header - delegate - (cctxt : #Protocol_client_context.full) -> - let unsigned_header = - Data_encoding.Binary.to_bytes_exn - Protocol.Alpha_context.Block_header.unsigned_encoding - unsigned_block_header - in - Shell_services.Chain.chain_id cctxt ~chain:cctxt#chain () - >>=? fun chain_id -> - Client_keys.get_key cctxt delegate >>=? fun (_, _, sk) -> - Client_keys.sign - cctxt - ~watermark: - (Protocol.Alpha_context.Block_header.to_watermark - (Block_header chain_id)) - sk - unsigned_header - >>=? fun s -> cctxt#message "%a" Hex.pp (Signature.to_hex s) >>= return); - ] diff --git a/src/proto_012_Psithaca/lib_client_commands/client_proto_utils_commands.mli b/src/proto_012_Psithaca/lib_client_commands/client_proto_utils_commands.mli deleted file mode 100644 index 0d38cde9a251..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/client_proto_utils_commands.mli +++ /dev/null @@ -1,26 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_Psithaca/lib_client_commands/dune b/src/proto_012_Psithaca/lib_client_commands/dune deleted file mode 100644 index 3e77fdb21967..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/dune +++ /dev/null @@ -1,57 +0,0 @@ -(library - (name tezos_client_012_Psithaca_commands) - (instrumentation (backend bisect_ppx)) - (public_name tezos-client-012-Psithaca-commands) - (libraries tezos-base - tezos-stdlib-unix - tezos-protocol-012-Psithaca - tezos-protocol-environment - tezos-shell-services - tezos-mockup - tezos-mockup-registration - tezos-mockup-commands - tezos-client-base-unix - tezos-client-012-Psithaca - tezos-client-commands - tezos-rpc - tezos-protocol-plugin-012-Psithaca) - (library_flags (:standard -linkall)) - (modules (:standard \ alpha_commands_registration)) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_stdlib_unix - -open Tezos_shell_services - -open Tezos_client_base - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_rpc - -open Tezos_client_base_unix - -open Tezos_protocol_plugin_012_Psithaca))) - -(library - (name tezos_client_012_Psithaca_commands_registration) - (instrumentation (backend bisect_ppx)) - (public_name tezos-client-012-Psithaca-commands-registration) - (libraries tezos-base - tezos-protocol-012-Psithaca - tezos-protocol-environment - tezos-shell-services - tezos-client-base - tezos-client-012-Psithaca - tezos-client-commands - tezos-client-012-Psithaca-commands - tezos-client-sapling-012-Psithaca - tezos-rpc - tezos-protocol-plugin-012-Psithaca) - (library_flags (:standard -linkall)) - (modules alpha_commands_registration) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_shell_services - -open Tezos_client_base - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_client_012_Psithaca_commands - -open Tezos_client_sapling_012_Psithaca - -open Tezos_rpc - -open Tezos_protocol_plugin_012_Psithaca))) diff --git a/src/proto_012_Psithaca/lib_client_commands/dune-project b/src/proto_012_Psithaca/lib_client_commands/dune-project deleted file mode 100644 index 7a9ba6f96d2b..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-client-alpha-commands) diff --git a/src/proto_012_Psithaca/lib_client_commands/tezos-client-012-Psithaca-commands-registration.opam b/src/proto_012_Psithaca/lib_client_commands/tezos-client-012-Psithaca-commands-registration.opam deleted file mode 100644 index 8e3fc05d6a6a..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/tezos-client-012-Psithaca-commands-registration.opam +++ /dev/null @@ -1,24 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-shell-services" - "tezos-client-base" - "tezos-client-012-Psithaca" - "tezos-client-012-Psithaca-commands" - "tezos-client-sapling-012-Psithaca" - "tezos-client-commands" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol-specific commands for `tezos-client`" diff --git a/src/proto_012_Psithaca/lib_client_commands/tezos-client-012-Psithaca-commands.opam b/src/proto_012_Psithaca/lib_client_commands/tezos-client-012-Psithaca-commands.opam deleted file mode 100644 index 5ebf12cdbf2a..000000000000 --- a/src/proto_012_Psithaca/lib_client_commands/tezos-client-012-Psithaca-commands.opam +++ /dev/null @@ -1,22 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-shell-services" - "tezos-client-base-unix" - "tezos-client-012-Psithaca" - "tezos-client-commands" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol-specific commands for `tezos-client`" diff --git a/src/proto_012_Psithaca/lib_client_sapling/.ocamlformat b/src/proto_012_Psithaca/lib_client_sapling/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_client_sapling/client_sapling_commands.ml b/src/proto_012_Psithaca/lib_client_sapling/client_sapling_commands.ml deleted file mode 100644 index 3a268e4a37a3..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/client_sapling_commands.ml +++ /dev/null @@ -1,796 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Clic -open Client_keys -open Tezos_sapling.Core.Client - -let json_switch = switch ~long:"json" ~doc:"Use JSON format" () - -let save_json_to_file json file = - let output_channel = open_out_bin file in - let ppf = Format.formatter_of_out_channel output_channel in - Data_encoding.Json.pp ppf json ; - Format.pp_print_flush ppf () ; - close_out output_channel - -let group = - { - Clic.name = "sapling"; - title = "Commands for working with Sapling transactions"; - } - -let keys_of_implicit_account cctxt source = - match Protocol.Alpha_context.Contract.is_implicit source with - | None -> assert false - | Some src -> - Client_keys.get_key cctxt src >>=? fun (_, pk, sk) -> return (src, pk, sk) - -let viewing_key_of_string s = - let exception Unknown_sapling_address in - let encoding = Viewing_key.address_b58check_encoding in - WithExceptions.Option.to_exn - ~none:Unknown_sapling_address - (Base58.simple_decode encoding s) - -(** All signatures are done with an anti-replay string. - In Tezos' protocol this string is set to be chain_id + KT1. **) -let anti_replay cctxt contract = - Tezos_shell_services.Chain_services.chain_id cctxt ~chain:cctxt#chain () - >>=? fun chain_id -> - let address = Protocol.Alpha_context.Contract.to_b58check contract in - let chain_id = Chain_id.to_b58check chain_id in - return (address ^ chain_id) - -let do_unshield cctxt contract src_name stez dst = - anti_replay cctxt contract >>=? fun anti_replay -> - Wallet.new_address cctxt src_name None >>=? fun (src, _, backdst) -> - Context.Client_state.sync_and_scan cctxt contract >>=? fun contract_state -> - Lwt.return - @@ Context.unshield ~src ~dst ~backdst stez contract_state anti_replay - -let do_shield cctxt ?message contract utez dst = - anti_replay cctxt contract >>=? fun anti_replay -> - Context.Client_state.sync_and_scan cctxt contract >>=? fun contract_state -> - let dst = viewing_key_of_string dst in - Context.shield cctxt ~dst ?message utez contract_state anti_replay - -let do_sapling_transfer cctxt ?message contract src_name amount dst = - anti_replay cctxt contract >>=? fun anti_replay -> - Wallet.new_address cctxt src_name None >>=? fun (src, _, backdst) -> - Context.Client_state.sync_and_scan cctxt contract >>=? fun contract_state -> - let dst = viewing_key_of_string dst in - Context.transfer - cctxt - ~src - ~dst - ~backdst - ?message - amount - contract_state - anti_replay - -let message_arg = - let open Clic in - arg - ~long:"message" - ~placeholder:"" - ~doc:"Message for Sapling transaction" - (parameter (fun _ x -> return @@ Bytes.of_string x)) - -let memo_size_arg = - let open Clic in - arg - ~long:"memo-size" - ~placeholder:"memo-size" - ~doc:"Expected length for message of Sapling transaction" - (parameter (fun _ s -> - match - let i = int_of_string s in - assert (i >= 0 && i <= 65535) ; - i - with - | i -> return i - | exception _ -> - failwith "invalid memo-size (must be between 0 and 65535)")) - -let shield_cmd = - let open Client_proto_args in - let open Client_proto_context_commands in - let open Protocol.Alpha_context in - let open Client_proto_contracts in - command - ~group - ~desc:"Shield tokens from an implicit account to a Sapling address." - (args14 - fee_arg - dry_run_switch - verbose_signing_switch - gas_limit_arg - storage_limit_arg - counter_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg - message_arg) - (prefixes ["sapling"; "shield"] - @@ tez_param - ~name:"qty" - ~desc:"Amount taken from transparent wallet of source." - @@ prefix "from" - @@ ContractAlias.destination_param - ~name:"src-tz" - ~desc:"Transparent source account." - @@ prefix "to" - @@ Clic.string ~name:"dst-sap" ~desc:"Sapling address of destination." - @@ prefix "using" - @@ ContractAlias.destination_param - ~name:"sapling contract" - ~desc:"Smart contract to submit this transaction to." - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap, - message ) - amount - (_, source) - sapling_dst - (_contract_name, contract_dst) - cctxt -> - keys_of_implicit_account cctxt source >>=? fun (pkh, src_pk, src_sk) -> - let open Context in - cctxt#warning - "Shielding %a from %a to %s@ entails a loss of privacy@." - Tez.pp - amount - Contract.pp - source - sapling_dst - >>= fun () -> - do_shield cctxt ?message contract_dst amount sapling_dst - >>=? fun sapling_input -> - let arg = Shielded_tez_contract_input.as_arg sapling_input in - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_context.transfer - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~fee_parameter - ~amount - ~src_pk - ~src_sk - ~destination:contract_dst - ~source:pkh - ~arg - ?confirmations:cctxt#confirmations - ?fee - ~dry_run - ~verbose_signing - ?gas_limit - ?storage_limit - ?counter - () - >>= fun errors -> - report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - errors - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit) - -let unshield_cmd = - let open Client_proto_args in - let open Client_proto_context_commands in - let open Protocol.Alpha_context in - let open Client_proto_contracts in - command - ~group - ~desc:"Unshield tokens from a Sapling address to an implicit account." - (args13 - fee_arg - dry_run_switch - verbose_signing_switch - gas_limit_arg - storage_limit_arg - counter_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg) - (prefixes ["sapling"; "unshield"] - @@ tez_param - ~name:"qty" - ~desc:"Amount taken from shielded wallet of source." - @@ prefix "from" - @@ Sapling_key.alias_param - ~name:"src-sap" - ~desc:"Sapling account of source." - @@ prefix "to" - @@ ContractAlias.destination_param - ~name:"dst-tz" - ~desc:"Transparent destination account." - @@ prefix "using" - @@ ContractAlias.destination_param - ~name:"sapling contract" - ~desc:"Smart contract to submit this transaction to." - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap ) - amount - (name, _sapling_uri) - (_, tz_dst) - (_contract_name, contract_dst) - cctxt -> - let open Context in - let stez = Shielded_tez.of_tez amount in - cctxt#warning - "Unshielding %a from %s to %a@ entails a loss of privacy@." - Shielded_tez.pp - stez - name - Contract.pp - tz_dst - >>= fun () -> - keys_of_implicit_account cctxt tz_dst >>=? fun (source, src_pk, src_sk) -> - do_unshield cctxt contract_dst name stez source >>=? fun sapling_input -> - let arg = Shielded_tez_contract_input.as_arg sapling_input in - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_context.transfer - cctxt - ~chain:cctxt#chain - ~block:cctxt#block - ~fee_parameter - ~amount:Tez.zero - ~src_pk - ~src_sk - ~destination:contract_dst - ~source - ~arg - ?confirmations:cctxt#confirmations - ?fee - ~dry_run - ~verbose_signing - ?gas_limit - ?storage_limit - ?counter - () - >>= fun errors -> - report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - errors - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit) - -(* Default name for Sapling transaction file *) -let sapling_transaction_file = "sapling_transaction" - -let file_arg default_filename = - let open Clic in - arg - ~long:"file" - ~placeholder:default_filename - ~doc:"file name" - (parameter (fun _ x -> return x)) - -(** Shielded transaction are first forged and printed in a file. - Then they are submitted with the next command. **) -let forge_shielded_cmd = - let open Client_proto_args in - let open Client_proto_context_commands in - let open Client_proto_contracts in - command - ~group - ~desc:"Forge a sapling transaction and save it to a file." - (args16 - fee_arg - dry_run_switch - verbose_signing_switch - gas_limit_arg - storage_limit_arg - counter_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg - message_arg - (file_arg sapling_transaction_file) - json_switch) - (prefixes ["sapling"; "forge"; "transaction"] - @@ tez_param - ~name:"qty" - ~desc:"Amount taken from shielded wallet of source." - @@ prefix "from" - @@ Sapling_key.alias_param - ~name:"src-sap" - ~desc:"Sapling account of source." - @@ prefix "to" - @@ Clic.string ~name:"dst-sap" ~desc:"Sapling address of destination." - @@ prefix "using" - @@ ContractAlias.destination_param - ~name:"sapling contract" - ~desc:"Smart contract to submit this transaction to." - @@ stop) - (fun ( _fee, - _dry_run, - _verbose_signing, - _gas_limit, - _storage_limit, - _counter, - _no_print_source, - _minimal_fees, - _minimal_nanotez_per_byte, - _minimal_nanotez_per_gas_unit, - _force_low_fee, - _fee_cap, - _burn_cap, - message, - file, - use_json_format ) - amount - (name, _sapling_uri) - destination - (_contract_name, contract_dst) - cctxt -> - let open Context in - let stez = Shielded_tez.of_tez amount in - do_sapling_transfer cctxt ?message contract_dst name stez destination - >>=? fun transaction -> - let file = Option.value ~default:sapling_transaction_file file in - cctxt#message "Writing transaction to %s@." file >>= fun () -> - (if use_json_format then - save_json_to_file - (Data_encoding.Json.construct UTXO.transaction_encoding transaction) - file - else - let bytes = - Hex.of_bytes - (Data_encoding.Binary.to_bytes_exn - UTXO.transaction_encoding - transaction) - in - let file = open_out_bin file in - Printf.fprintf file "0x%s" (Hex.show bytes) ; - close_out file) ; - return_unit) - -let submit_shielded_cmd = - let open Client_proto_context_commands in - let open Client_proto_args in - let open Client_proto_contracts in - command - ~group - ~desc:"Submit a forged sapling transaction." - (args14 - fee_arg - dry_run_switch - verbose_signing_switch - gas_limit_arg - storage_limit_arg - counter_arg - no_print_source_flag - minimal_fees_arg - minimal_nanotez_per_byte_arg - minimal_nanotez_per_gas_unit_arg - force_low_fee_arg - fee_cap_arg - burn_cap_arg - json_switch) - (prefixes ["sapling"; "submit"] - (* TODO: Add a dedicated abstracted Clic element to parse filenames, - potentially using Sys.file_exists *) - @@ Clic.string ~name:"file" ~desc:"Filename of the forged transaction." - @@ prefix "from" - @@ ContractAlias.destination_param - ~name:"alias-tz" - ~desc:"Transparent account paying the fees." - @@ prefix "using" - @@ ContractAlias.destination_param - ~name:"sapling contract" - ~desc:"Smart contract to submit this transaction to." - @@ stop) - (fun ( fee, - dry_run, - verbose_signing, - gas_limit, - storage_limit, - counter, - no_print_source, - minimal_fees, - minimal_nanotez_per_byte, - minimal_nanotez_per_gas_unit, - force_low_fee, - fee_cap, - burn_cap, - use_json_format ) - filename - (_, source) - (contract_name, destination) - (cctxt : Protocol_client_context.full) -> - cctxt#message - "Reading forge transaction from file %s -- sending it to %s@." - filename - contract_name - >>= fun () -> - let open Context in - (if use_json_format then - Lwt_utils_unix.Json.read_file filename >>=? fun json -> - return @@ Data_encoding.Json.destruct UTXO.transaction_encoding json - else - Lwt_utils_unix.read_file filename >>= fun hex -> - let hex = - (* remove 0x *) - String.sub hex 2 (String.length hex - 2) - in - return - @@ Data_encoding.Binary.of_bytes_exn - UTXO.transaction_encoding - Hex.(to_bytes_exn (`Hex hex))) - >>=? fun transaction -> - return Shielded_tez_contract_input.(as_arg (create transaction)) - >>=? fun contract_input -> - let chain = cctxt#chain and block = cctxt#block in - keys_of_implicit_account cctxt source >>=? fun (source, src_pk, src_sk) -> - let open Protocol.Alpha_context in - let fee_parameter = - { - Injection.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee; - fee_cap; - burn_cap; - } - in - Client_proto_context.transfer - cctxt - ~chain - ~block - ~fee_parameter - ~amount:Tez.zero - ~src_pk - ~src_sk - ~destination - ~source - ~arg:contract_input - ?confirmations:cctxt#confirmations - ?fee - ~dry_run - ~verbose_signing - ?gas_limit - ?storage_limit - ?counter - () - >>= fun errors -> - report_michelson_errors - ~no_print_source - ~msg:"transfer simulation failed" - cctxt - errors - >>= function - | None -> return_unit - | Some (_res, _contracts) -> return_unit) - -let for_contract_arg = - Client_proto_contracts.ContractAlias.destination_arg - ~name:"for-contract" - ~doc:"name of the contract to associate new key with" - () - -let unencrypted_switch () = - Clic.switch - ~long:"unencrypted" - ~doc:"Do not encrypt the key on-disk (for testing and debugging)." - () - -let generate_key_cmd = - command - ~group - ~desc:"Generate a new sapling key." - (args2 (Sapling_key.force_switch ()) (unencrypted_switch ())) - (prefixes ["sapling"; "gen"; "key"] @@ Sapling_key.fresh_alias_param @@ stop) - (fun (force, unencrypted) name (cctxt : Protocol_client_context.full) -> - Sapling_key.of_fresh cctxt force name >>=? fun name -> - let mnemonic = Wallet.Mnemonic.new_random in - cctxt#message - "It is important to save this mnemonic in a secure place:@\n\ - @\n\ - %a@\n\ - @\n\ - The mnemonic can be used to recover your spending key.@." - Wallet.Mnemonic.words_pp - (Bip39.to_words mnemonic) - >>= fun () -> - Wallet.register cctxt ~force ~unencrypted mnemonic name >>=? fun _vk -> - return_unit) - -let use_key_for_contract_cmd = - command - ~group - ~desc:"Use a sapling key for a contract." - (args1 memo_size_arg) - (prefixes ["sapling"; "use"; "key"] - @@ Sapling_key.alias_param - ~name:"sapling-key" - ~desc:"Sapling key to use for the contract." - @@ prefixes ["for"; "contract"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"contract" - ~desc:"Contract the key will be used on." - @@ stop) - (fun default_memo_size - (name, _sapling_uri) - (_contract_name, contract) - (cctxt : Protocol_client_context.full) -> - Wallet.find_vk cctxt name >>=? fun vk -> - Context.Client_state.register - cctxt - ~default_memo_size - ~force:false - contract - vk) - -let import_key_cmd = - command - ~group - ~desc:"Restore a sapling key from mnemonic." - (args3 - (Sapling_key.force_switch ()) - (unencrypted_switch ()) - (Clic.arg - ~long:"mnemonic" - ~placeholder:"mnemonic" - ~doc:"Mnemonic as an option, only used for testing and debugging." - Client_proto_args.string_parameter)) - (prefixes ["sapling"; "import"; "key"] - @@ Sapling_key.fresh_alias_param @@ stop) - (fun (force, unencrypted, mnemonic_opt) - fresh_name - (cctxt : Protocol_client_context.full) -> - (match mnemonic_opt with - | None -> - let rec loop_words (acc : string list) i = - if i > 23 then return (List.rev acc) - else - cctxt#prompt_password "Enter word %d: " i >>=? fun word_raw -> - let word = Bytes.to_string word_raw in - match Bip39.index_of_word word with - | None -> loop_words acc i - | Some _ -> loop_words (word :: acc) (succ i) - in - loop_words [] 0 - | Some mnemonic -> return (String.split_on_char ' ' mnemonic)) - >>=? fun words -> - match Bip39.of_words words with - | None -> failwith "Not a valid mnemonic" - | Some mnemonic -> - Sapling_key.of_fresh cctxt force fresh_name >>=? fun name -> - Wallet.register cctxt ~force ~unencrypted mnemonic name >>=? fun _ -> - return_unit) - -let commands () = - let child_index_param = - Clic.param - ~name:"child-index" - ~desc:"Index of the child to derive." - Client_proto_args.int_parameter - in - let index_arg = - Clic.arg - ~doc:"index of the address to generate" - ~long:"address-index" - ~placeholder:"idx" - Client_proto_args.int_parameter - in - [ - generate_key_cmd; - use_key_for_contract_cmd; - import_key_cmd; - command - ~group - ~desc:"Derive a key from an existing one using zip32." - (args4 - (Sapling_key.force_switch ()) - for_contract_arg - (unencrypted_switch ()) - memo_size_arg) - (prefixes ["sapling"; "derive"; "key"] - @@ Sapling_key.fresh_alias_param @@ prefix "from" - @@ Sapling_key.alias_param - @@ prefixes ["at"; "index"] - @@ child_index_param @@ stop) - (fun (force, contract_opt, unencrypted, default_memo_size) - fresh_name - (existing_name, _existing_uri) - child_index - (cctxt : Protocol_client_context.full) -> - Sapling_key.of_fresh cctxt force fresh_name >>=? fun new_name -> - Wallet.derive - cctxt - ~force - ~unencrypted - existing_name - new_name - child_index - >>=? fun (path, vk) -> - cctxt#message - "Derived new key %s from %s with path %s@." - new_name - existing_name - path - >>= fun () -> - (* TODO must pass contract address for now *) - let (_, contract) = - WithExceptions.Option.get ~loc:__LOC__ contract_opt - in - Context.Client_state.register - cctxt - ~default_memo_size - ~force - contract - vk); - command - ~group - ~desc:"Generate an address for a key referenced by alias." - (args1 index_arg) - (prefixes ["sapling"; "gen"; "address"] @@ Sapling_key.alias_param @@ stop) - (fun index_opt (name, _sapling_uri) (cctxt : Protocol_client_context.full) -> - Wallet.new_address cctxt name index_opt - >>=? fun (_, corrected_index, address) -> - let address_b58 = - Base58.simple_encode Viewing_key.address_b58check_encoding address - in - cctxt#message - "Generated address:@.%s@.at index %Ld" - address_b58 - (Viewing_key.index_to_int64 corrected_index) - >>= fun () -> return_unit); - command - ~group - ~desc:"Save a sapling viewing key in a JSON file." - no_options - (prefixes ["sapling"; "export"; "key"] - @@ Sapling_key.alias_param @@ prefix "in" - @@ Clic.param - ~name:"file" - ~desc:"Filename." - Client_proto_args.string_parameter - @@ stop) - (fun () (name, _sapling_uri) file (cctxt : Protocol_client_context.full) -> - Wallet.export_vk cctxt name >>=? fun vk_json -> - return (save_json_to_file vk_json file)); - command - ~group - ~desc:"Get balance associated with given sapling key and contract" - (args1 - (Clic.switch - ~doc:"Print the collection of non-spent inputs." - ~short:'v' - ~long:"verbose" - ())) - (prefixes ["sapling"; "get"; "balance"; "for"] - @@ Sapling_key.alias_param - ~name:"sapling-key" - ~desc:"Sapling key we get balance for." - @@ prefixes ["in"; "contract"] - @@ Client_proto_contracts.ContractAlias.destination_param - ~name:"contract" - ~desc:"Contract we get balance from." - @@ stop) - (fun verbose - (name, _sapling_uri) - (_contract_name, contract) - (cctxt : Protocol_client_context.full) -> - Wallet.find_vk cctxt name >>= function - | Error _ -> cctxt#error "Account %s not found" name - | Ok vk -> ( - Context.Client_state.sync_and_scan cctxt contract - >>=? fun contract_state -> - Context.Contract_state.find_account vk contract_state |> function - | None -> cctxt#error "Account %s not found" name - | Some account -> - (if verbose then - cctxt#answer - "@[Received Sapling transactions for %s@,@[%a@]@]" - name - Context.Account.pp_unspent - account - else Lwt.return_unit) - >>= fun () -> - cctxt#answer - "Total Sapling funds %a%s" - Context.Shielded_tez.pp - (Context.Account.balance account) - Client_proto_args.tez_sym - >>= fun () -> return_unit)); - command - ~group - ~desc:"List sapling keys." - no_options - (fixed ["sapling"; "list"; "keys"]) - (fun () (cctxt : Protocol_client_context.full) -> - Sapling_key.load cctxt >>=? fun l -> - List.iter_s - (fun (s, _) -> cctxt#message "%s" s) - (List.sort (fun (s1, _) (s2, _) -> String.compare s1 s2) l) - >>= fun () -> return_unit); - shield_cmd; - unshield_cmd; - forge_shielded_cmd; - submit_shielded_cmd; - ] diff --git a/src/proto_012_Psithaca/lib_client_sapling/client_sapling_commands.mli b/src/proto_012_Psithaca/lib_client_sapling/client_sapling_commands.mli deleted file mode 100644 index 769a4eac58e9..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/client_sapling_commands.mli +++ /dev/null @@ -1,23 +0,0 @@ -(* The MIT License (MIT) - * - * Copyright (c) 2019-2020 Nomadic Labs - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. *) - -val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_Psithaca/lib_client_sapling/context.ml b/src/proto_012_Psithaca/lib_client_sapling/context.ml deleted file mode 100644 index e12003adde36..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/context.ml +++ /dev/null @@ -1,553 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Tezos_sapling.Core.Client - -let _ = Random.self_init () - -module Tez = Protocol.Alpha_context.Tez - -module Shielded_tez : sig - type t - - val encoding : t Data_encoding.t - - val pp : Format.formatter -> t -> unit - - val zero : t - - val of_mutez : int64 -> t option - - val to_mutez : t -> int64 - - val of_tez : Tez.t -> t - - val ( +? ) : t -> t -> t tzresult - - val ( -? ) : t -> t -> t tzresult -end = struct - include Tez - - let ( +? ) a b = a +? b |> Environment.wrap_tzresult - - let ( -? ) a b = a -? b |> Environment.wrap_tzresult - - let of_tez t = - let i = Tez.to_mutez t in - assert (UTXO.valid_amount i) ; - WithExceptions.Option.get ~loc:__LOC__ @@ of_mutez i -end - -module Shielded_tez_contract_input = struct - type t = UTXO.transaction * Signature.public_key_hash option - - let create ?pkh tr = (tr, pkh) - - let encoding = - let open Data_encoding in - obj2 - (req "transaction" UTXO.transaction_encoding) - (opt "pkh" Signature.Public_key_hash.encoding) - - let pp ppf t = - let open Data_encoding in - let json = Json.construct encoding t in - Json.pp ppf json - - let michelson (tr, pkopt) = - let open Tezos_micheline in - let open Protocol.Alpha_context in - let a = - Micheline.Bytes - (0, Data_encoding.Binary.to_bytes_exn UTXO.transaction_encoding tr) - in - let b = - match pkopt with - | None -> Micheline.Prim (0, Script.D_None, [], []) - | Some v -> - let value = - Micheline.Bytes - ( 0, - Data_encoding.Binary.to_bytes_exn - Signature.Public_key_hash.encoding - v ) - in - Micheline.Prim (0, Script.D_Some, [value], []) - in - Micheline.strip_locations - @@ Micheline.Seq (0, [Micheline.Prim (0, Script.D_Pair, [a; b], [])]) - - let pp_michelson ppf t = - let value = michelson t in - Michelson_v1_printer.print_expr ppf value - - let as_arg t = Format.asprintf "%a" pp_michelson t -end - -(** The inputs and outputs are shuffled to prevent meta-data analysis. **) -module Shuffle = struct - let list l = - let a = Array.of_list l in - let len = Array.length a in - for i = len downto 2 do - let idx = Random.int i in - let swp_idx = i - 1 in - let tmp = a.(swp_idx) in - a.(swp_idx) <- a.(idx) ; - a.(idx) <- tmp - done ; - Array.to_list a - - let pair x y = if Random.bool () then [y; x] else [x; y] -end - -type error += Balance_too_low of Shielded_tez.t * Shielded_tez.t - -let register_error_kind category ~id ~title ~description ?pp encoding from_error - to_error = - let id = "client_sapling." ^ Protocol.name ^ "." ^ id in - register_error_kind - category - ~id - ~title - ~description - ?pp - encoding - from_error - to_error - -let () = - register_error_kind - `Temporary - ~id:"balance_too_low" - ~title:"Balance too low" - ~description:"The sender contract does not have enough tokens." - ~pp:(fun ppf (balance, amount) -> - Format.fprintf - ppf - "@[Balance too low (%a) to spend %a@]" - Shielded_tez.pp - balance - Shielded_tez.pp - amount) - Data_encoding.( - obj2 - (req "actual_balance" Shielded_tez.encoding) - (req "amount" Shielded_tez.encoding)) - (function - | Balance_too_low (balance, amount) -> Some (balance, amount) | _ -> None) - (fun (balance, amount) -> Balance_too_low (balance, amount)) - -module Storage = Tezos_sapling.Storage -module F = Tezos_sapling.Forge - -module Input_set = struct - include Set.Make (F.Input) - - let to_list = elements - - let pp_f pp i = - Format.fprintf - pp - "@[%s %Ld@]" - (Base58.simple_encode - Viewing_key.address_b58check_encoding - (F.Input.address i)) - (F.Input.amount i) -end - -module Account = struct - type t = { - vk : Viewing_key.t; - unspents : Input_set.t; - balance : Shielded_tez.t; - } - - let encoding = - let open Data_encoding in - conv - (fun cs -> (cs.vk, Input_set.to_list cs.unspents, cs.balance)) - (fun (vk, unspents, balance) -> - {vk; unspents = Input_set.of_list unspents; balance}) - (obj3 - (req "vk" Viewing_key.encoding) - (req "unspents" (list F.Input.encoding)) - (req "balance" Shielded_tez.encoding)) - - let create vk = {vk; unspents = Input_set.empty; balance = Shielded_tez.zero} - - let balance c = c.balance - - let add_unspent c input = - let amount = - WithExceptions.Option.get ~loc:__LOC__ - @@ Shielded_tez.of_mutez (F.Input.amount input) - in - match Shielded_tez.(c.balance +? amount) with - | Error _ -> assert false (* overflow *) - | Ok balance -> - let unspents = Input_set.add input c.unspents in - {c with balance; unspents} - - let remove_unspent c input = - let amount = - WithExceptions.Option.get ~loc:__LOC__ - @@ Shielded_tez.of_mutez (F.Input.amount input) - in - match Shielded_tez.(c.balance -? amount) with - | Error _ -> assert false (* negative balance *) - | Ok balance -> - let unspents = Input_set.remove input c.unspents in - {c with balance; unspents} - - let filter_spent account storage = - Input_set.fold - (fun input acc -> - if F.Input.is_spent input storage account.vk then - remove_unspent acc input - else acc) - account.unspents - account - - let pick_input c = - let ( >?| ) x f = Option.map f x in - Input_set.choose c.unspents >?| fun unspent -> - let c = remove_unspent c unspent in - (unspent, c) - - let pp_unspent : Format.formatter -> t -> unit = - fun ppf a -> - (Format.pp_print_list ~pp_sep:Format.pp_print_cut Input_set.pp_f ppf) - (Input_set.elements a.unspents) -end - -module Contract_state = struct - module Accounts = struct - include Set.Make (struct - type t = Account.t - - let compare a b = - let open Account in - Bytes.compare (Viewing_key.to_bytes a.vk) (Viewing_key.to_bytes b.vk) - end) - - let replace a set = add a (remove a set) - - let find vk accounts = find (Account.create vk) accounts - end - - let accounts_encoding = - let open Data_encoding in - conv - Accounts.elements - (List.fold_left (fun m e -> Accounts.add e m) Accounts.empty) - (list Account.encoding) - - type t = {accounts : Accounts.t; storage : Storage.state} - - let encoding = - let open Data_encoding in - conv - (fun t -> (t.accounts, t.storage)) - (fun (accounts, storage) -> {accounts; storage}) - (obj2 - (req "accounts" accounts_encoding) - (req "storage" Storage.state_encoding)) - - let empty ~memo_size = - {accounts = Accounts.empty; storage = Storage.empty ~memo_size} - - let find_account vk contract_state = Accounts.find vk contract_state.accounts - - let init ~force vk state = - Accounts.find vk state.accounts |> function - | None -> - let accounts = Accounts.add (Account.create vk) state.accounts in - return {state with accounts} - | Some _ -> - if force then - let accounts = Accounts.add (Account.create vk) state.accounts in - return {state with accounts} - else failwith "vk already present" - - let add_unspent vk input accounts = - let account = - Accounts.find vk accounts |> WithExceptions.Option.get ~loc:__LOC__ - in - let account = Account.add_unspent account input in - Accounts.replace account accounts - - (** Scan the Sapling storage of a smart contract and update the accounts of - all known viewing keys for that contract *) - let scan state storage = - (* remove newly spent inputs *) - let accounts = - Accounts.map - (fun account -> Account.filter_spent account storage) - state.accounts - in - (* get all the vks that need to be scanned for *) - let vks = - Accounts.fold (fun account acc -> Account.(account.vk) :: acc) accounts [] - in - let (size, _) = Storage.size storage in - let rec aux pos accounts = - if pos < size then - (* try to decrypt each inputs with all vks *) - List.fold_left - (fun acc vk -> - match F.Input.get storage pos vk with - | None -> acc - | Some input -> (vk, input) :: acc) - [] - vks - |> function - | [] -> aux (Int64.succ pos) accounts - | [(vk, (_message, forge_input))] -> - let is_spent = F.Input.is_spent forge_input storage vk in - if is_spent then aux (Int64.succ pos) accounts - else aux (Int64.succ pos) (add_unspent vk forge_input accounts) - | _ -> assert false (* got more than one decrypting key *) - else accounts - in - let (current_size, _) = Storage.size state.storage in - let accounts = aux current_size accounts in - {accounts; storage} - - (** Update the Sapling storage of a smart contract using a diff, checking that - the resulting Merkle tree has a root equal to the one in the diff. *) - let update_storage contract_state (root, diff) = - let open Protocol.Alpha_context.Sapling in - let storage = - Tezos_sapling.Storage.add - contract_state.storage - diff.commitments_and_ciphertexts - in - let computed_root = Storage.get_root storage in - if computed_root <> root then - Stdlib.failwith "Commitment tree inconsistent wrt to node." - else - let storage = - List.fold_left - (fun s nf -> Storage.add_nullifier s nf) - storage - diff.nullifiers - in - scan contract_state storage -end - -module Client_state = struct - module Map = Map.Make (Protocol.Alpha_context.Contract) - - type t = Contract_state.t Map.t - - let encoding = - let open Data_encoding in - conv - Map.bindings - (List.fold_left (fun m (k, v) -> Map.add k v m) Map.empty) - (list - (obj2 - (req "contract" Protocol.Alpha_context.Contract.encoding) - (req "state" Contract_state.encoding))) - - let filename = "sapling_state" - - let load (cctxt : #Client_context.wallet) = - cctxt#load filename ~default:Map.empty encoding - - let write (cctxt : #Client_context.wallet) t = cctxt#write filename t encoding - - let get_or_init ~default_memo_size contract client_state = - Map.find contract client_state |> function - | None -> ( - match default_memo_size with - | None -> - failwith - "Unknown memo size for contract %s and none was provided in \ - options" - @@ Protocol.Alpha_context.Contract.to_b58check contract - | Some memo_size -> - let contract_state = Contract_state.empty ~memo_size in - let client_state = Map.add contract contract_state client_state in - return (contract_state, client_state)) - | Some contract_state -> return (contract_state, client_state) - - let register cctxt ~force ~default_memo_size contract vk = - load cctxt >>=? fun client_state -> - get_or_init ~default_memo_size contract client_state - >>=? fun (contract_state, client_state) -> - Contract_state.init ~force vk contract_state >>=? fun contract_state -> - let client_state = Map.add contract contract_state client_state in - write cctxt client_state - - let find (cctxt : #Client_context.full) contract state = - Map.find contract state |> function - | None -> - cctxt#error - "Contract %s not found" - (Protocol.Alpha_context.Contract.to_b58check contract) - | Some v -> return v - - (** Call the node RPC to obtain the storage diff of a contract *) - let get_diff cctxt contract offset_commitment offset_nullifier = - Protocol.Alpha_services.Contract.single_sapling_get_diff - cctxt - (cctxt#chain, cctxt#block) - contract - ~offset_commitment - ~offset_nullifier - () - - let sync_and_scan cctxt contract = - load cctxt >>=? fun state -> - find cctxt contract state >>=? fun contract_state -> - let (cm_pos, nf_pos) = Storage.size contract_state.storage in - get_diff cctxt contract cm_pos nf_pos >>=? fun diff -> - let contract_state = Contract_state.update_storage contract_state diff in - let state = Map.add contract contract_state state in - write cctxt state >>=? fun () -> return contract_state -end - -(** Truncate or pad the message to fit the memo_size *) -let adjust_message_length (cctxt : #Client_context.full) ?message memo_size = - match message with - | None -> - cctxt#warning - "no message provided, adding a zeroes filled message of the required \ - length: %d " - memo_size - >|= fun () -> Bytes.make memo_size '\000' - | Some message -> - let message_length = Bytes.length message in - if message_length = memo_size then Lwt.return message - else if message_length > memo_size then - cctxt#warning - "Your message is too long (%d bytes) and will therefore be truncated \ - to %d bytes" - message_length - memo_size - >|= fun () -> Bytes.sub message 0 memo_size - else - cctxt#warning - "Your message is too short (%d bytes) and will therefore be \ - right-padded with zero bytes to reach a %d-byte length" - message_length - memo_size - >|= fun () -> - Bytes.cat message (Bytes.make (memo_size - message_length) '\000') - -let create_payment ~message dst amount = - let amount = Shielded_tez.to_mutez amount in - F.make_output dst amount message - -(** Return a list of inputs belonging to an account sufficient to cover an - amount, together with the change remaining. *) -let get_shielded_amount amount account = - let balance = Account.balance account in - error_unless (balance >= amount) (Balance_too_low (balance, amount)) - >|? fun () -> - let to_pay = Shielded_tez.to_mutez amount in - let inputs_to_spend = [] in - let rec loop to_pay chosen_inputs account = - if Int64.(compare to_pay zero) > 0 then - Account.pick_input account |> function - | None -> - Stdlib.failwith "Not enough inputs" (* TODO raise a proper error *) - | Some (next_in, account) -> - let next_val = F.Input.amount next_in in - let rest_to_pay = Int64.sub to_pay next_val in - loop rest_to_pay (next_in :: chosen_inputs) account - else - let change = - WithExceptions.Option.get ~loc:__LOC__ - @@ Shielded_tez.of_mutez @@ Int64.abs to_pay - in - (chosen_inputs, change) - in - loop to_pay inputs_to_spend account - -let create_payback ~memo_size address amount = - let plaintext_message = Bytes.make memo_size '\000' in - let amount = Shielded_tez.to_mutez amount in - F.make_output address amount plaintext_message - -(* The caller should check that the account exists already *) -let unshield ~src ~dst ~backdst amount (state : Contract_state.t) anti_replay = - let vk = Viewing_key.of_sk src in - let account = - Contract_state.find_account vk state - |> WithExceptions.Option.get ~loc:__LOC__ - in - get_shielded_amount amount account >|? fun (inputs, change) -> - let memo_size = Storage.get_memo_size state.storage in - let payback = create_payback ~memo_size backdst change in - let sapling_transaction = - F.forge_transaction - (Shuffle.list inputs) - [payback] - src - anti_replay - state.storage - in - Shielded_tez_contract_input.create ~pkh:dst sapling_transaction - -let shield cctxt ~dst ?message amount (state : Contract_state.t) anti_replay = - let shielded_amount = Shielded_tez.of_tez amount in - let memo_size = Storage.get_memo_size Contract_state.(state.storage) in - adjust_message_length cctxt ?message memo_size >>= fun message -> - let payment = create_payment ~message dst shielded_amount in - let negative_amount = Int64.neg (Tez.to_mutez amount) in - let sapling_transaction = - F.forge_shield_transaction - [payment] - negative_amount - anti_replay - Contract_state.(state.storage) - in - return (Shielded_tez_contract_input.create sapling_transaction) - -(* The caller should check that the account exists already *) -let transfer cctxt ~src ~dst ~backdst ?message amount (state : Contract_state.t) - anti_replay = - let vk = Viewing_key.of_sk src in - let account = - Contract_state.find_account vk state - |> WithExceptions.Option.get ~loc:__LOC__ - in - let memo_size = Storage.get_memo_size state.storage in - adjust_message_length cctxt ?message memo_size >|= fun message -> - get_shielded_amount amount account >|? fun (inputs, change) -> - let payment = create_payment ~message dst amount in - let payback = create_payback ~memo_size backdst change in - let sapling_transaction = - F.forge_transaction - (Shuffle.list inputs) - (Shuffle.pair payback payment) - src - anti_replay - state.storage - in - sapling_transaction diff --git a/src/proto_012_Psithaca/lib_client_sapling/context.mli b/src/proto_012_Psithaca/lib_client_sapling/context.mli deleted file mode 100644 index 72963733eb7c..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/context.mli +++ /dev/null @@ -1,157 +0,0 @@ -(* The MIT License (MIT) - * - * Copyright (c) 2019-2020 Nomadic Labs - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. *) - -(** - This module allows the creation Sapling transactions: shield, unshield and - transfer. - Because Sapling uses an UTXO model, it is necessary for the client to - maintain locally the set of unspent outputs for each viewing key, for each - smart contract. This operation is called scanning. - This local cache is updated downloading from the node only the difference - from the last scanned state. -*) - -open Tezos_sapling.Core.Client - -module Tez : module type of Protocol.Alpha_context.Tez - -(** This module is used to represent any shielded token to avoid confusing it - with Tez. *) -module Shielded_tez : sig - type t - - val encoding : t Data_encoding.t - - val pp : Format.formatter -> t -> unit - - val zero : t - - val of_mutez : int64 -> t option - - val to_mutez : t -> int64 - - val of_tez : Tez.t -> t - - val ( +? ) : t -> t -> t tzresult -end - -(** Actual input to a smart contract handling Sapling transactions *) -module Shielded_tez_contract_input : sig - type t - - val create : ?pkh:Signature.Public_key_hash.t -> UTXO.transaction -> t - - val encoding : t Data_encoding.t - - val pp : Format.formatter -> t -> unit - - val as_arg : t -> string -end - -(** Account corresponding to a contract and a viewing key *) -module Account : sig - type t - - val balance : t -> Shielded_tez.t - - val pp_unspent : Format.formatter -> t -> unit -end - -(** State of a contract, potentially involving several viewing keys *) -module Contract_state : sig - type t - - val find_account : Viewing_key.t -> t -> Account.t option -end - -module Client_state : sig - type t - - val find : - Protocol_client_context.full -> - Protocol.Alpha_context.Contract.t -> - t -> - Contract_state.t tzresult Lwt.t - - val register : - Protocol_client_context.full -> - force:bool -> - default_memo_size:int option -> - Protocol.Alpha_context.Contract.t -> - Viewing_key.t -> - unit tzresult Lwt.t - - (** Synchronise our local state with the blockchain's. - The state must be recent enough to craft correct transactions. - The limit enforced by the protocol if 120 blocks. - Also scans, ie. checks for incoming payments and add - them to our balance. - **) - val sync_and_scan : - Protocol_client_context.full -> - Protocol.Alpha_context.Contract.t -> - Contract_state.t tzresult Lwt.t -end - -(** [shield ~message ~dst tez cstate anti-replay] returns a transaction - shielding [tez] tez to a sapling address [dst] using a sapling - storage [cstate] and the anti-replay string. *) -val shield : - #Client_context.full -> - dst:Viewing_key.address -> - ?message:bytes -> - Tez.t -> - Contract_state.t -> - string -> - Shielded_tez_contract_input.t tzresult Lwt.t - -(** [unshield ~src_name ~src ~dst ~backdst stez cstate storage] returns - a transaction unshielding [stez] shielded tokens from a sapling wallet - [src] to a transparent tezos address [dst], sending the change back to - [backdst] and using a Sapling storage [cstate] and a anti-replay string. - The transaction is refused if there is an insufficient amount of shielded - tez in the wallet [src], the error is raised with [src_name]. - *) -val unshield : - src:Spending_key.t -> - dst:Signature.public_key_hash -> - backdst:Viewing_key.address -> - Shielded_tez.t -> - Contract_state.t -> - string -> - Shielded_tez_contract_input.t tzresult - -(** [transfer ~message ~src ~dst ~backdst amount cstate anti-replay] creates a - Sapling transaction of [amount] shielded tez from Sapling wallet [src] to - Sapling address [dst], sending the change to [backdst], using a Sapling - storage [cstate] and a anti-replay string. - [~message] is a message that will be uploaded encrypted on chain. *) -val transfer : - #Client_context.full -> - src:Spending_key.t -> - dst:Viewing_key.address -> - backdst:Viewing_key.address -> - ?message:bytes -> - Shielded_tez.t -> - Contract_state.t -> - string -> - UTXO.transaction tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_client_sapling/dune b/src/proto_012_Psithaca/lib_client_sapling/dune deleted file mode 100644 index 5167b00e1390..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/dune +++ /dev/null @@ -1,19 +0,0 @@ -(library - (name tezos_client_sapling_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-client-sapling-012-Psithaca) - (libraries tezos-base - tezos-crypto - tezos-client-base - tezos-signer-backends - tezos-client-012-Psithaca - tezos-client-012-Psithaca-commands - tezos-protocol-012-Psithaca) - (library_flags (:standard -linkall)) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_stdlib_unix - -open Tezos_client_base - -open Tezos_client_012_Psithaca - -open Tezos_client_012_Psithaca_commands - -open Tezos_protocol_012_Psithaca - -open Tezos_protocol_environment_012_Psithaca))) diff --git a/src/proto_012_Psithaca/lib_client_sapling/dune-project b/src/proto_012_Psithaca/lib_client_sapling/dune-project deleted file mode 100644 index f0a33c2f223d..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(name tezos-client-sapling) -(formatting (enabled_for ocaml)) diff --git a/src/proto_012_Psithaca/lib_client_sapling/tezos-client-sapling-012-Psithaca.opam b/src/proto_012_Psithaca/lib_client_sapling/tezos-client-sapling-012-Psithaca.opam deleted file mode 100644 index c676182a6981..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/tezos-client-sapling-012-Psithaca.opam +++ /dev/null @@ -1,24 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "ocamlfind" { build } - "dune" { >= "2.9" } - "tezos-base" - "tezos-clic" - "tezos-crypto" - "tezos-client-base" - "tezos-signer-backends" - "tezos-client-012-Psithaca" - "tezos-client-012-Psithaca-commands" - "tezos-protocol-012-Psithaca" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos: sapling support for `tezos-client`" diff --git a/src/proto_012_Psithaca/lib_client_sapling/wallet.ml b/src/proto_012_Psithaca/lib_client_sapling/wallet.ml deleted file mode 100644 index e970fd0b2a8a..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/wallet.ml +++ /dev/null @@ -1,126 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Client_keys -open Tezos_sapling.Core.Client - -module Mnemonic = struct - let new_random = Bip39.of_entropy (Hacl.Rand.gen 32) - - let to_sapling_key mnemonic = - (* Z-cash needs 32 bytes and BIP-39 gives 64 bytes of entropy. - We xor the two halves in case the entropy is not well distributed. *) - let seed_64_to_seed_32 (seed_64 : bytes) : bytes = - assert (Bytes.length seed_64 = 64) ; - let first_32 = Bytes.sub seed_64 0 32 in - let second_32 = Bytes.sub seed_64 32 32 in - let seed_32 = Bytes.create 32 in - for i = 0 to 31 do - Bytes.set - seed_32 - i - (Char.chr - (Char.code (Bytes.get first_32 i) - lxor Char.code (Bytes.get second_32 i))) - done ; - seed_32 - in - Spending_key.of_seed (seed_64_to_seed_32 (Bip39.to_seed mnemonic)) - - let words_pp = Format.(pp_print_list ~pp_sep:pp_print_space pp_print_string) -end - -(* Transform a spending key to an uri, encrypted or not. *) -let to_uri unencrypted cctxt sapling_key = - if unencrypted then - Tezos_signer_backends.Unencrypted.make_sapling_key sapling_key >>?= return - else Tezos_signer_backends.Encrypted.encrypt_sapling_key cctxt sapling_key - -(** Transform an uri into a spending key, asking for a password if the uri was - encrypted. *) -let from_uri (cctxt : #Client_context.full) uri = - Tezos_signer_backends.Encrypted.decrypt_sapling_key cctxt uri - -let register (cctxt : #Client_context.full) ?(force = false) - ?(unencrypted = false) mnemonic name = - let sk = Mnemonic.to_sapling_key mnemonic in - to_uri unencrypted cctxt sk >>=? fun sk_uri -> - let key = - { - sk = sk_uri; - path = [Spending_key.child_index sk]; - address_index = Viewing_key.default_index; - } - in - Sapling_key.add ~force cctxt name key >>=? fun () -> - return @@ Viewing_key.of_sk sk - -let derive (cctxt : #Client_context.full) ?(force = false) - ?(unencrypted = false) src_name dst_name child_index = - Sapling_key.find cctxt src_name >>=? fun k -> - from_uri cctxt k.sk >>=? fun src_sk -> - let child_index = Int32.of_int child_index in - let dst_sk = Spending_key.derive_key src_sk child_index in - to_uri unencrypted cctxt dst_sk >>=? fun dst_sk_uri -> - let dst_key = - { - sk = dst_sk_uri; - path = child_index :: k.path; - address_index = Viewing_key.default_index; - } - in - (* TODO check this force *) - let _ = force in - Sapling_key.add ~force:true cctxt dst_name dst_key >>=? fun () -> - let path = - String.concat "/" (List.map Int32.to_string (List.rev dst_key.path)) - in - return (path, Viewing_key.of_sk dst_sk) - -let find_vk cctxt name = - Sapling_key.find cctxt name >>=? fun k -> - from_uri cctxt k.sk >>=? fun sk -> return (Viewing_key.of_sk sk) - -let new_address (cctxt : #Client_context.full) name index_opt = - Sapling_key.find cctxt name >>=? fun k -> - let index = - match index_opt with - | None -> k.address_index - | Some i -> Viewing_key.index_of_int64 (Int64.of_int i) - in - from_uri cctxt k.sk >>=? fun sk -> - return (Viewing_key.of_sk sk) >>=? fun vk -> - (* Viewing_key.new_address finds the smallest index greater or equal to - [index] that generates a correct address. *) - let (corrected_index, address) = Viewing_key.new_address vk index in - Sapling_key.update - cctxt - name - {k with address_index = Viewing_key.index_succ corrected_index} - >>=? fun () -> return (sk, corrected_index, address) - -let export_vk cctxt name = - find_vk cctxt name >>=? fun vk -> - return (Data_encoding.Json.construct Viewing_key.encoding vk) diff --git a/src/proto_012_Psithaca/lib_client_sapling/wallet.mli b/src/proto_012_Psithaca/lib_client_sapling/wallet.mli deleted file mode 100644 index 17e0e59d0af4..000000000000 --- a/src/proto_012_Psithaca/lib_client_sapling/wallet.mli +++ /dev/null @@ -1,75 +0,0 @@ -(* The MIT License (MIT) - * - * Copyright (c) 2019-2020 Nomadic Labs - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. *) - -open Tezos_sapling.Core.Client - -(** Mnemonic of 24 common english words from which a key can be derived. - The mnemonic follows the BIP-39 spec. *) -module Mnemonic : sig - val new_random : Bip39.t - - (** Pretty printer for printing a list of words of a mnemonic. *) - val words_pp : Format.formatter -> string list -> unit -end - -(** Add to the wallet a new spending key derived from a mnemonic and identified - by an alias. The wallet is updated and the corresponding viewing key is - returned. - If [force] it will overwrite an existing alias. *) -val register : - #Client_context.full -> - ?force:bool -> - ?unencrypted:bool -> - Bip39.t -> - string -> - Viewing_key.t tzresult Lwt.t - -(** [derive parent child index] derives a key with alias [child] from an - existing key with alias [parent] at [index] using ZIP32. - If a new index is required the state of the wallet is updated. - The path and viewing key corresponding to the generated key are returned. *) -val derive : - #Client_context.full -> - ?force:bool -> - ?unencrypted:bool -> - string -> - string -> - int -> - (string * Viewing_key.t) tzresult Lwt.t - -val find_vk : #Client_context.full -> string -> Viewing_key.t tzresult Lwt.t - -(** Generate a new address. - If an optional index is provided, try to derive the address at this index, - otherwise use the first viable one. - Not all indexes correspond to a valid address so successive ones are tried. - Once a valid index is found it is recorded in the wallet. - Return also the corresponding sk and vk to avoid asking the user multiple - times for the description password. *) -val new_address : - #Client_context.full -> - string -> - int option -> - (Spending_key.t * Viewing_key.index * Viewing_key.address) tzresult Lwt.t - -val export_vk : - #Client_context.full -> string -> Data_encoding.Json.json tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/.ocamlformat b/src/proto_012_Psithaca/lib_delegate/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_delegate/abstract_context_index.ml b/src/proto_012_Psithaca/lib_delegate/abstract_context_index.ml deleted file mode 100644 index c714c2515946..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/abstract_context_index.ml +++ /dev/null @@ -1,35 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = { - checkout_fun : Context_hash.t -> Environment_context.Context.t option Lwt.t; - finalize_fun : unit -> unit Lwt.t; -} - -let abstract index = - { - checkout_fun = Shell_context.checkout index; - finalize_fun = (fun () -> Context.close index); - } diff --git a/src/proto_012_Psithaca/lib_delegate/abstract_context_index.mli b/src/proto_012_Psithaca/lib_delegate/abstract_context_index.mli deleted file mode 100644 index 617739bd9124..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/abstract_context_index.mli +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = { - checkout_fun : Context_hash.t -> Environment_context.Context.t option Lwt.t; - finalize_fun : unit -> unit Lwt.t; -} - -val abstract : Context.index -> t diff --git a/src/proto_012_Psithaca/lib_delegate/baking_actions.ml b/src/proto_012_Psithaca/lib_delegate/baking_actions.ml deleted file mode 100644 index 83ed9d5d920d..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_actions.ml +++ /dev/null @@ -1,531 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Baking_state -module Events = Baking_events.Actions - -type block_kind = - | Fresh of Operation_pool.pool - | Reproposal of { - consensus_operations : packed_operation list; - payload_hash : Block_payload_hash.t; - payload_round : Round.t; - payload : Operation_pool.payload; - } - -type block_to_bake = { - predecessor : block_info; - round : Round.t; - delegate : Baking_state.delegate; - kind : block_kind; -} - -type action = - | Do_nothing - | Inject_block of {block_to_bake : block_to_bake; updated_state : state} - | Inject_preendorsements of { - preendorsements : (delegate * consensus_content) list; - updated_state : state; - } - | Inject_endorsements of { - endorsements : (delegate * consensus_content) list; - updated_state : state; - } - | Update_to_level of level_update - | Synchronize_round of round_update - -and level_update = { - new_level_proposal : proposal; - compute_new_state : - current_round:Round.t -> - delegate_slots:delegate_slots -> - next_level_delegate_slots:delegate_slots -> - (state * action) Lwt.t; -} - -and round_update = { - new_round_proposal : proposal; - handle_proposal : state -> (state * action) Lwt.t; -} - -type t = action - -let pp_action fmt = function - | Do_nothing -> Format.fprintf fmt "do nothing" - | Inject_block _ -> Format.fprintf fmt "inject block" - | Inject_preendorsements _ -> Format.fprintf fmt "inject preendorsements" - | Inject_endorsements _ -> Format.fprintf fmt "inject endorsements" - | Update_to_level _ -> Format.fprintf fmt "update to level" - | Synchronize_round _ -> Format.fprintf fmt "synchronize round" - -let generate_seed_nonce_hash config delegate level = - if level.Level.expected_commitment then - Baking_nonces.generate_seed_nonce config delegate level.level - >>=? fun seed_nonce -> return_some seed_nonce - else return_none - -let sign_block_header state proposer unsigned_block_header = - let cctxt = state.global_state.cctxt in - let chain_id = state.global_state.chain_id in - let force = state.global_state.config.force in - let {Block_header.shell; protocol_data = {contents; _}} = - unsigned_block_header - in - let unsigned_header = - Data_encoding.Binary.to_bytes_exn - Alpha_context.Block_header.unsigned_encoding - (shell, contents) - in - let level = shell.level in - Baking_state.round_of_shell_header shell >>?= fun round -> - let open Baking_highwatermarks in - cctxt#with_lock (fun () -> - let block_location = - Baking_files.resolve_location ~chain_id `Highwatermarks - in - may_sign_block - cctxt - block_location - ~delegate:proposer.public_key_hash - ~level - ~round - >>=? function - | true -> - record_block - cctxt - block_location - ~delegate:proposer.public_key_hash - ~level - ~round - >>=? fun () -> return_true - | false -> - Events.(emit potential_double_baking (level, round)) >>= fun () -> - return force) - >>=? function - | false -> fail (Block_previously_baked {level; round}) - | true -> - Client_keys.sign - cctxt - proposer.secret_key_uri - ~watermark:Block_header.(to_watermark (Block_header chain_id)) - unsigned_header - >>=? fun signature -> - return {Block_header.shell; protocol_data = {contents; signature}} - -let inject_block ~state_recorder state block_to_bake ~updated_state = - let {predecessor; round; delegate; kind} = block_to_bake in - let cctxt = state.global_state.cctxt in - let chain_id = state.global_state.chain_id in - let simulation_mode = state.global_state.validation_mode in - let round_durations = state.global_state.round_durations in - Environment.wrap_tzresult - (Round.timestamp_of_round - round_durations - ~predecessor_timestamp:predecessor.shell.timestamp - ~predecessor_round:predecessor.round - ~round) - >>?= fun timestamp -> - let (simulation_kind, payload_round) = - match kind with - | Fresh pool -> (Block_forge.Filter pool, round) - | Reproposal {consensus_operations; payload_hash; payload_round; payload} -> - ( Block_forge.Apply - { - ordered_pool = - Operation_pool.ordered_pool_of_payload - ~consensus_operations - payload; - payload_hash; - }, - payload_round ) - in - Events.( - emit forging_block (Int32.succ predecessor.shell.level, round, delegate)) - >>= fun () -> - Plugin.RPC.current_level - cctxt - ~offset:1l - (`Hash state.global_state.chain_id, `Hash (predecessor.hash, 0)) - >>=? fun injection_level -> - generate_seed_nonce_hash - state.global_state.config.Baking_configuration.nonce - delegate - injection_level - >>=? fun seed_nonce_opt -> - let seed_nonce_hash = Option.map fst seed_nonce_opt in - (* Set liquidity_baking_escape_vote for this block *) - let default = state.global_state.config.liquidity_baking_escape_vote in - (match state.global_state.config.per_block_vote_file with - | None -> Lwt.return default - | Some per_block_vote_file -> - Liquidity_baking_vote_file.read_liquidity_baking_escape_vote_no_fail - ~default - ~per_block_vote_file) - >>= fun liquidity_baking_escape_vote -> - Block_forge.forge - cctxt - ~chain_id - ~pred_info:predecessor - ~timestamp - ~seed_nonce_hash - ~payload_round - ~liquidity_baking_escape_vote - state.global_state.config.fees - simulation_mode - simulation_kind - state.global_state.constants.parametric - >>=? fun {unsigned_block_header; operations} -> - sign_block_header state delegate unsigned_block_header - >>=? fun signed_block_header -> - (match seed_nonce_opt with - | None -> - (* Nothing to do *) - return_unit - | Some (_, nonce) -> - let block_hash = Block_header.hash signed_block_header in - Baking_nonces.register_nonce cctxt ~chain_id block_hash nonce) - >>=? fun () -> - state_recorder ~new_state:updated_state >>=? fun () -> - Events.( - emit injecting_block (signed_block_header.shell.level, round, delegate)) - >>= fun () -> - Node_rpc.inject_block - cctxt - ~force:state.global_state.config.force - ~chain:(`Hash state.global_state.chain_id) - signed_block_header - operations - >>=? fun bh -> - Events.(emit block_injected (bh, delegate)) >>= fun () -> return updated_state - -let inject_preendorsements ~state_recorder state ~preendorsements ~updated_state - = - let cctxt = state.global_state.cctxt in - let chain_id = state.global_state.chain_id in - (* N.b. signing a lot of operations may take some time *) - (* Don't parallelize signatures: the signer might not be able to - handle concurrent requests *) - List.filter_map_es - (fun (delegate, consensus_content) -> - Events.(emit signing_preendorsement delegate) >>= fun () -> - let shell = - { - Tezos_base.Operation.branch = - state.level_state.latest_proposal.predecessor.hash; - } - in - let contents = Single (Preendorsement consensus_content) in - let level = Raw_level.to_int32 consensus_content.level in - let round = consensus_content.round in - cctxt#with_lock (fun () -> - let block_location = - Baking_files.resolve_location ~chain_id `Highwatermarks - in - Baking_highwatermarks.may_sign_preendorsement - cctxt - block_location - ~delegate:delegate.public_key_hash - ~level - ~round - >>=? function - | true -> - Baking_highwatermarks.record_preendorsement - cctxt - block_location - ~delegate:delegate.public_key_hash - ~level - ~round - >>=? fun () -> return_true - | false -> return state.global_state.config.force) - >>=? fun may_sign -> - (if may_sign then - let unsigned_operation = (shell, Contents_list contents) in - let watermark = Operation.(to_watermark (Preendorsement chain_id)) in - let unsigned_operation_bytes = - Data_encoding.Binary.to_bytes_exn - Operation.unsigned_encoding - unsigned_operation - in - (* TODO: do we want to reload the sk uri or not ? *) - Client_keys.get_key cctxt delegate.public_key_hash >>=? fun (_, _, sk) -> - Client_keys.sign cctxt ~watermark sk unsigned_operation_bytes - else - fail (Baking_highwatermarks.Block_previously_preendorsed {round; level})) - >>= function - | Error err -> - Events.(emit skipping_preendorsement (delegate, err)) >>= fun () -> - return_none - | Ok signature -> - let protocol_data = - Operation_data {contents; signature = Some signature} - in - let operation : Operation.packed = {shell; protocol_data} in - return_some (delegate, operation)) - preendorsements - >>=? fun signed_operations -> - state_recorder ~new_state:updated_state >>=? fun () -> - (* TODO: add a RPC to inject multiple operations *) - List.iter_ep - (fun (delegate, operation) -> - let encoded_op = - Data_encoding.Binary.to_bytes_exn Operation.encoding operation - in - protect - ~on_error:(fun err -> - Events.(emit failed_to_inject_preendorsement (delegate, err)) - >>= fun () -> return_unit) - (fun () -> - Shell_services.Injection.operation - cctxt - ~chain:(`Hash chain_id) - encoded_op - >>=? fun oph -> - Events.(emit preendorsement_injected (oph, delegate)) >>= fun () -> - return_unit)) - signed_operations - >>=? fun () -> return updated_state - -let sign_endorsements state endorsements = - let cctxt = state.global_state.cctxt in - let chain_id = state.global_state.chain_id in - (* N.b. signing a lot of operations may take some time *) - (* Don't parallelize signatures: the signer might not be able to - handle concurrent requests *) - List.filter_map_es - (fun (delegate, consensus_content) -> - Events.(emit signing_endorsement delegate) >>= fun () -> - let shell = - { - Tezos_base.Operation.branch = - state.level_state.latest_proposal.predecessor.hash; - } - in - let contents = - (* No preendorsements are included *) - Single (Endorsement consensus_content) - in - let level = Raw_level.to_int32 consensus_content.level in - let round = consensus_content.round in - cctxt#with_lock (fun () -> - let block_location = - Baking_files.resolve_location ~chain_id `Highwatermarks - in - Baking_highwatermarks.may_sign_endorsement - cctxt - block_location - ~delegate:delegate.public_key_hash - ~level - ~round - >>=? function - | true -> - Baking_highwatermarks.record_endorsement - cctxt - block_location - ~delegate:delegate.public_key_hash - ~level - ~round - >>=? fun () -> return_true - | false -> return state.global_state.config.force) - >>=? fun may_sign -> - (if may_sign then - let watermark = Operation.(to_watermark (Endorsement chain_id)) in - let unsigned_operation = (shell, Contents_list contents) in - let unsigned_operation_bytes = - Data_encoding.Binary.to_bytes_exn - Operation.unsigned_encoding - unsigned_operation - in - (* TODO: do we want to reload the sk uri or not ? *) - Client_keys.get_key cctxt delegate.public_key_hash >>=? fun (_, _, sk) -> - Client_keys.sign cctxt ~watermark sk unsigned_operation_bytes - else - fail (Baking_highwatermarks.Block_previously_preendorsed {round; level})) - >>= function - | Error err -> - Events.(emit skipping_endorsement (delegate, err)) >>= fun () -> - return_none - | Ok signature -> - let protocol_data = - Operation_data {contents; signature = Some signature} - in - let operation : Operation.packed = {shell; protocol_data} in - return_some (delegate, operation)) - endorsements - -let inject_endorsements ~state_recorder state ~endorsements ~updated_state = - let cctxt = state.global_state.cctxt in - let chain_id = state.global_state.chain_id in - sign_endorsements state endorsements >>=? fun signed_operations -> - state_recorder ~new_state:updated_state >>=? fun () -> - (* TODO: add a RPC to inject multiple operations *) - List.iter_ep - (fun (delegate, signed_operation) -> - let encoded_op = - Data_encoding.Binary.to_bytes_exn Operation.encoding signed_operation - in - Shell_services.Injection.operation - cctxt - ~chain:(`Hash chain_id) - encoded_op - >>=? fun oph -> - Events.(emit endorsement_injected (oph, delegate)) >>= fun () -> - return_unit) - signed_operations - >>=? fun () -> return updated_state - -let prepare_waiting_for_quorum state = - let consensus_threshold = - state.global_state.constants.parametric.consensus_threshold - in - let get_consensus_operation_voting_power ~slot = - match - SlotMap.find slot state.level_state.delegate_slots.all_delegate_slots - with - | None -> - (* cannot happen if the map is correctly populated *) - 0 - | Some {endorsing_power; _} -> endorsing_power - in - let latest_proposal = state.level_state.latest_proposal.block in - (* assert (latest_proposal.block.round = state.round_state.current_round) ; *) - let candidate = - { - Operation_worker.hash = latest_proposal.hash; - round_watched = latest_proposal.round; - payload_hash_watched = latest_proposal.payload_hash; - } - in - (consensus_threshold, get_consensus_operation_voting_power, candidate) - -let start_waiting_for_preendorsement_quorum state = - let (consensus_threshold, get_preendorsement_voting_power, candidate) = - prepare_waiting_for_quorum state - in - let operation_worker = state.global_state.operation_worker in - Operation_worker.monitor_preendorsement_quorum - operation_worker - ~consensus_threshold - ~get_preendorsement_voting_power - candidate - -let start_waiting_for_endorsement_quorum state = - let (consensus_threshold, get_endorsement_voting_power, candidate) = - prepare_waiting_for_quorum state - in - let operation_worker = state.global_state.operation_worker in - Operation_worker.monitor_endorsement_quorum - operation_worker - ~consensus_threshold - ~get_endorsement_voting_power - candidate - -let compute_round proposal round_durations = - let open Protocol in - let open Baking_state in - (* If our current proposal is the transition block, we suppose a - never ending round 0 *) - if Protocol_hash.(proposal.block.protocol <> proposal.block.next_protocol) - then ok Round.zero - else - let timestamp = Systime_os.now () |> Time.System.to_protocol in - let predecessor_block = proposal.predecessor in - Environment.wrap_tzresult - @@ Alpha_context.Round.round_of_timestamp - round_durations - ~predecessor_timestamp:predecessor_block.shell.timestamp - ~predecessor_round:predecessor_block.round - ~timestamp - -let update_to_level state level_update = - let {new_level_proposal; compute_new_state} = level_update in - let cctxt = state.global_state.cctxt in - let delegates = state.global_state.delegates in - let new_level = new_level_proposal.block.shell.level in - let chain = `Hash state.global_state.chain_id in - (if Int32.(new_level = succ state.level_state.current_level) then - return state.level_state.next_level_delegate_slots - else - Baking_state.compute_delegate_slots cctxt delegates ~level:new_level ~chain) - >>=? fun delegate_slots -> - Baking_state.compute_delegate_slots - cctxt - delegates - ~level:(Int32.succ new_level) - ~chain - >>=? fun next_level_delegate_slots -> - let round_durations = state.global_state.round_durations in - compute_round new_level_proposal round_durations >>?= fun current_round -> - compute_new_state ~current_round ~delegate_slots ~next_level_delegate_slots - >>= return - -let synchronize_round state {new_round_proposal; handle_proposal} = - Events.(emit synchronizing_round new_round_proposal.predecessor.hash) - >>= fun () -> - let round_durations = state.global_state.round_durations in - compute_round new_round_proposal round_durations >>?= fun current_round -> - if Round.(current_round < new_round_proposal.block.round) then - (* impossible *) - failwith - "synchronize_round: current round (%a) is behind the new proposal's \ - round (%a)" - Round.pp - current_round - Round.pp - new_round_proposal.block.round - else - let new_round_state = {current_round; current_phase = Idle} in - let new_state = {state with round_state = new_round_state} in - handle_proposal new_state >>= return - -let rec perform_action ~state_recorder state (action : action) = - match action with - | Do_nothing -> state_recorder ~new_state:state >>=? fun () -> return state - | Inject_block {block_to_bake; updated_state} -> - inject_block state ~state_recorder block_to_bake ~updated_state - | Inject_preendorsements {preendorsements; updated_state} -> - inject_preendorsements - ~state_recorder - state - ~preendorsements - ~updated_state - >>=? fun new_state -> - (* We wait for preendorsements to trigger the - [Prequorum_reached] event *) - start_waiting_for_preendorsement_quorum state >>= fun () -> - return new_state - | Inject_endorsements {endorsements; updated_state} -> - inject_endorsements ~state_recorder state ~endorsements ~updated_state - >>=? fun new_state -> - (* We wait for endorsements to trigger the [Quorum_reached] - event *) - start_waiting_for_endorsement_quorum state >>= fun () -> return new_state - | Update_to_level level_update -> - update_to_level state level_update >>=? fun (new_state, new_action) -> - perform_action ~state_recorder new_state new_action - | Synchronize_round round_update -> - synchronize_round state round_update >>=? fun (new_state, new_action) -> - perform_action ~state_recorder new_state new_action diff --git a/src/proto_012_Psithaca/lib_delegate/baking_actions.mli b/src/proto_012_Psithaca/lib_delegate/baking_actions.mli deleted file mode 100644 index 83789e84892f..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_actions.mli +++ /dev/null @@ -1,125 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Baking_state - -type block_kind = - | Fresh of Operation_pool.pool - | Reproposal of { - consensus_operations : packed_operation list; - payload_hash : Block_payload_hash.t; - payload_round : Round.t; - payload : Operation_pool.payload; - } - -type block_to_bake = { - predecessor : block_info; - round : Round.t; - delegate : delegate; - kind : block_kind; -} - -type action = - | Do_nothing - | Inject_block of {block_to_bake : block_to_bake; updated_state : state} - | Inject_preendorsements of { - preendorsements : (delegate * consensus_content) list; - updated_state : state; - } - | Inject_endorsements of { - endorsements : (delegate * consensus_content) list; - updated_state : state; - } - | Update_to_level of level_update - | Synchronize_round of round_update - -and level_update = { - new_level_proposal : proposal; - compute_new_state : - current_round:Round.t -> - delegate_slots:delegate_slots -> - next_level_delegate_slots:delegate_slots -> - (state * action) Lwt.t; -} - -and round_update = { - new_round_proposal : proposal; - handle_proposal : state -> (state * action) Lwt.t; -} - -type t = action - -val generate_seed_nonce_hash : - Baking_configuration.nonce_config -> - delegate -> - Level.t -> - (Nonce_hash.t * Nonce.t) option tzresult Lwt.t - -val inject_block : - state_recorder:(new_state:state -> unit tzresult Lwt.t) -> - state -> - block_to_bake -> - updated_state:state -> - state tzresult Lwt.t - -val inject_preendorsements : - state_recorder:(new_state:state -> unit tzresult Lwt.t) -> - state -> - preendorsements:(delegate * consensus_content) list -> - updated_state:state -> - state tzresult Lwt.t - -val sign_endorsements : - state -> - (delegate * consensus_content) list -> - (delegate * packed_operation) list tzresult Lwt.t - -val inject_endorsements : - state_recorder:(new_state:state -> unit tzresult Lwt.t) -> - state -> - endorsements:(delegate * consensus_content) list -> - updated_state:state -> - state tzresult Lwt.t - -val prepare_waiting_for_quorum : - state -> int * (slot:Slot.t -> int) * Operation_worker.candidate - -val start_waiting_for_preendorsement_quorum : state -> unit Lwt.t - -val start_waiting_for_endorsement_quorum : state -> unit Lwt.t - -val update_to_level : state -> level_update -> (state * t) tzresult Lwt.t - -val pp_action : Format.formatter -> t -> unit - -val compute_round : proposal -> Round.round_durations -> Round.t tzresult - -val perform_action : - state_recorder:(new_state:state -> unit tzresult Lwt.t) -> - state -> - t -> - state tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/baking_cache.ml b/src/proto_012_Psithaca/lib_delegate/baking_cache.ml deleted file mode 100644 index 4ce45c7b7a9d..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_cache.ml +++ /dev/null @@ -1,85 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Cache structures used to memoize costly RPCs/computations. *) - -open Protocol.Alpha_context - -type round = Round.t - -module Block_cache = - (val Ringo.(map_maker ~replacement:LRU ~overflow:Strong ~accounting:Precise)) - (Block_hash) - -(** The [Timestamp_of_round_tbl] module allows to create memoization tables - to store function calls of [Round.timestamp_of_round]. *) -module Timestamp_of_round_cache = - (val Ringo.(map_maker ~replacement:LRU ~overflow:Strong ~accounting:Precise)) - (struct - (* The type of keys is a tuple that corresponds to the arguments - of [Round.timestamp_of_round]. *) - type t = Timestamp.time * round * round - - let hash k = Hashtbl.hash k - - let equal (ts, r1, r2) (ts', r1', r2') = - Timestamp.(ts = ts') && Round.(r1 = r1') && Round.(r2 = r2') - end) - -module Round_cache_key = struct - type ts_interval = Timestamp.time * Timestamp.time - - (** The values that are intended to be used here are the - arguments are: predecessor_timestamp * predecessor_round * - timestamp_interval *) - type t = { - predecessor_timestamp : Timestamp.time; - predecessor_round : round; - time_interval : ts_interval; - } - - let hash {predecessor_timestamp; predecessor_round; _} = - Stdlib.Hashtbl.hash (predecessor_timestamp, predecessor_round) - - let equal - { - predecessor_timestamp = pred_t; - predecessor_round = pred_r; - time_interval = (t_beg, t_end); - } - { - predecessor_timestamp = pred_t'; - predecessor_round = pred_r'; - time_interval = (t_beg', t_end'); - } = - Timestamp.(pred_t = pred_t') - && Round.(pred_r = pred_r') - && Timestamp.(t_beg' <= t_beg) - && Timestamp.(t_end < t_end') -end - -module Round_timestamp_interval_cache = - (val Ringo.(map_maker ~replacement:LRU ~overflow:Strong ~accounting:Precise)) - (Round_cache_key) diff --git a/src/proto_012_Psithaca/lib_delegate/baking_commands.ml b/src/proto_012_Psithaca/lib_delegate/baking_commands.ml deleted file mode 100644 index c452ac7dbafd..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_commands.ml +++ /dev/null @@ -1,374 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Client_proto_args - -let pidfile_arg = - Clic.arg - ~doc:"write process id in file" - ~short:'P' - ~long:"pidfile" - ~placeholder:"filename" - (Clic.parameter (fun _ s -> return s)) - -let may_lock_pidfile pidfile_opt f = - match pidfile_opt with - | None -> f () - | Some pidfile -> - Lwt_lock_file.try_with_lock - ~when_locked:(fun () -> - failwith "Failed to create the pidfile: %s" pidfile) - ~filename:pidfile - f - -let http_headers = - match Sys.getenv_opt "TEZOS_REMOTE_MEMPOOL_HTTP_HEADERS" with - | None -> None - | Some contents -> - let lines = String.split_on_char '\n' contents in - Some - (List.fold_left - (fun acc line -> - match String.index_opt line ':' with - | None -> - Stdlib.failwith - "Http headers: invalid TEZOS_REMOTE_MEMPOOL_HTTP_HEADERS \ - environment variable, missing colon" - | Some pos -> - let header = String.trim (String.sub line 0 pos) in - let header = String.lowercase_ascii header in - if - header <> "host" - && (String.length header < 2 || String.sub header 0 2 <> "x-") - then - Stdlib.failwith - "Http headers: invalid TEZOS_REMOTE_MEMPOOL_HTTP_HEADERS \ - environment variable, only 'host' or 'x-' headers are \ - supported" ; - let value = - String.trim - (String.sub line (pos + 1) (String.length line - pos - 1)) - in - (header, value) :: acc) - [] - lines) - -let check_endpoint_validity uri = - match Uri.scheme uri with - | Some "http" | Some "https" -> () - | None -> - Stdlib.failwith "no scheme detected, http and https scheme are required" - | Some x -> - Printf.ksprintf - Stdlib.failwith - "invalid scheme '%s' only http and https endpoints are supported" - x - -let mempool_arg = - Clic.arg - ~long:"mempool" - ~placeholder:"file" - ~doc: - "When specified, the baker will try to fetch a mempool from this file \ - (or uri) and will try to include the retrieved operations in the block. \ - The expected format of the content is of the form of the \ - '/chains//mempool/pending_operations' RPC. Environment \ - variable 'TEZOS_REMOTE_MEMPOOL_HTTP_HEADERS' may also be specified to \ - add headers to the requests (only 'host' and custom 'x-...' headers are \ - supported)." - (Clic.map_parameter - ~f:(fun uri -> - let open Baking_configuration in - let path = Uri.to_string uri in - if Sys.file_exists path then Mempool.(Local {filename = path}) - else ( - check_endpoint_validity uri ; - Mempool.(Remote {uri; http_headers}))) - uri_parameter) - -let context_path_arg = - Clic.arg - ~long:"context" - ~placeholder:"path" - ~doc: - "When specified, the client will read in the local context at the \ - provided path in order to build the block, instead of relying on the \ - 'preapply' RPC." - string_parameter - -let endorsement_force_switch_arg = - Clic.switch - ~long:"force" - ~short:'f' - ~doc: - "Disable consistency, injection and double signature checks for \ - (pre)endorsements." - () - -let do_not_monitor_node_mempool_arg = - Clic.switch - ~long:"ignore-node-mempool" - ~doc: - "Ignore mempool operations from the node and do not subsequently monitor \ - them. Use in conjunction with --mempool option to restrict the observed \ - operations to those of the mempool file." - () - -let keep_alive_arg = - Clic.switch - ~doc: - "Keep the daemon process alive: when the connection with the node is \ - lost, the daemon periodically tries to reach it." - ~short:'K' - ~long:"keep-alive" - () - -let liquidity_baking_escape_vote_switch = - Clic.switch - ~doc:"Vote to end the liquidity baking subsidy." - ~long:"liquidity-baking-escape-vote" - () - -let get_delegates (cctxt : Protocol_client_context.full) - (pkhs : Signature.public_key_hash list) = - let proj_delegate (alias, public_key_hash, public_key, secret_key_uri) = - { - Baking_state.alias = Some alias; - public_key_hash; - public_key; - secret_key_uri; - } - in - (if pkhs = [] then - Client_keys.get_keys cctxt >>=? fun keys -> - List.map proj_delegate keys |> return - else - List.map_es - (fun pkh -> - Client_keys.get_key cctxt pkh >>=? function - | (alias, pk, sk_uri) -> return (proj_delegate (alias, pkh, pk, sk_uri))) - pkhs) - >>=? fun delegates -> - Tezos_signer_backends.Encrypted.decrypt_list - cctxt - (List.filter_map - (function - | {Baking_state.alias = Some alias; _} -> Some alias | _ -> None) - delegates) - >>=? fun () -> - let delegates_no_duplicates = List.sort_uniq compare delegates in - (if Compare.List_lengths.(delegates <> delegates_no_duplicates) then - cctxt#warning - "Warning: the list of public key hash aliases contains duplicate hashes, \ - which are ignored" - else Lwt.return ()) - >>= fun () -> return delegates_no_duplicates - -let sources_param = - Clic.seq_of_param - (Client_keys.Public_key_hash.source_param - ~name:"baker" - ~desc:"name of the delegate owning the endorsement right") - -let delegate_commands () : Protocol_client_context.full Clic.command list = - let open Clic in - let group = - {name = "delegate.client"; title = "Tenderbake client commands"} - in - [ - command - ~group - ~desc:"Forge and inject block using the delegates' rights." - (args8 - minimal_fees_arg - minimal_nanotez_per_gas_unit_arg - minimal_nanotez_per_byte_arg - minimal_timestamp_switch - force_switch - mempool_arg - context_path_arg - do_not_monitor_node_mempool_arg) - (prefixes ["bake"; "for"] @@ sources_param) - (fun ( minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - minimal_timestamp, - force, - mempool, - context_path, - do_not_monitor_node_mempool ) - pkhs - cctxt -> - get_delegates cctxt pkhs >>=? fun delegates -> - Baking_lib.bake - cctxt - ~minimal_nanotez_per_gas_unit - ~minimal_timestamp - ~minimal_nanotez_per_byte - ~minimal_fees - ~force - ~monitor_node_mempool:(not do_not_monitor_node_mempool) - ?mempool - ?context_path - delegates); - command - ~group - ~desc:"Forge and inject an endorsement operation." - (args1 endorsement_force_switch_arg) - (prefixes ["endorse"; "for"] @@ sources_param) - (fun force pkhs cctxt -> - get_delegates cctxt pkhs >>=? fun delegates -> - Baking_lib.endorse ~force cctxt delegates); - command - ~group - ~desc:"Forge and inject a preendorsement operation." - (args1 endorsement_force_switch_arg) - (prefixes ["preendorse"; "for"] @@ sources_param) - (fun force pkhs cctxt -> - get_delegates cctxt pkhs >>=? fun delegates -> - Baking_lib.preendorse ~force cctxt delegates); - command - ~group - ~desc:"Send a Tenderbake proposal" - (args7 - minimal_fees_arg - minimal_nanotez_per_gas_unit_arg - minimal_nanotez_per_byte_arg - minimal_timestamp_switch - force_switch - mempool_arg - context_path_arg) - (prefixes ["propose"; "for"] @@ sources_param) - (fun ( minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - minimal_timestamp, - force, - mempool, - context_path ) - sources - cctxt -> - get_delegates cctxt sources >>=? fun delegates -> - Baking_lib.propose - cctxt - ~minimal_nanotez_per_gas_unit - ~minimal_timestamp - ~minimal_nanotez_per_byte - ~minimal_fees - ~force - ?mempool - ?context_path - delegates); - ] - -let directory_parameter = - Clic.parameter (fun _ p -> - if not (Sys.file_exists p && Sys.is_directory p) then - failwith "Directory doesn't exist: '%s'" p - else return p) - -let per_block_vote_file_arg = - Clic.arg - ~doc:"read per block votes as json file" - ~short:'V' - ~long:"votefile" - ~placeholder:"filename" - (Clic.parameter (fun _ s -> return s)) - -let baker_commands () : Protocol_client_context.full Clic.command list = - let open Clic in - let group = - { - Clic.name = "delegate.baker"; - title = "Commands related to the baker daemon."; - } - in - [ - command - ~group - ~desc:"Launch the baker daemon." - (args7 - pidfile_arg - minimal_fees_arg - minimal_nanotez_per_gas_unit_arg - minimal_nanotez_per_byte_arg - keep_alive_arg - liquidity_baking_escape_vote_switch - per_block_vote_file_arg) - (prefixes ["run"; "with"; "local"; "node"] - @@ param - ~name:"node_data_path" - ~desc:"Path to the node data directory (e.g. $HOME/.tezos-node)" - directory_parameter - @@ sources_param) - (fun ( pidfile, - minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - keep_alive, - liquidity_baking_escape_vote, - per_block_vote_file ) - node_data_path - sources - cctxt -> - may_lock_pidfile pidfile @@ fun () -> - get_delegates cctxt sources >>=? fun delegates -> - let context_path = Filename.Infix.(node_data_path // "context") in - Client_daemon.Baker.run - cctxt - ~minimal_fees - ~minimal_nanotez_per_gas_unit - ~minimal_nanotez_per_byte - ~liquidity_baking_escape_vote - ?per_block_vote_file - ~chain:cctxt#chain - ~context_path - ~keep_alive - delegates); - ] - -let accuser_commands () = - let open Clic in - let group = - { - Clic.name = "delegate.accuser"; - title = "Commands related to the accuser daemon."; - } - in - [ - command - ~group - ~desc:"Launch the accuser daemon" - (args3 pidfile_arg Client_proto_args.preserved_levels_arg keep_alive_arg) - (prefixes ["run"] @@ stop) - (fun (pidfile, preserved_levels, keep_alive) cctxt -> - let preserved_levels = Option.value ~default:200 preserved_levels in - may_lock_pidfile pidfile @@ fun () -> - Client_daemon.Accuser.run - cctxt - ~chain:cctxt#chain - ~preserved_levels - ~keep_alive); - ] diff --git a/src/proto_012_Psithaca/lib_delegate/baking_commands.mli b/src/proto_012_Psithaca/lib_delegate/baking_commands.mli deleted file mode 100644 index 8c9f9ea45d06..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_commands.mli +++ /dev/null @@ -1,30 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val delegate_commands : unit -> Protocol_client_context.full Clic.command list - -val baker_commands : unit -> Protocol_client_context.full Clic.command list - -val accuser_commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_Psithaca/lib_delegate/baking_commands_registration.ml b/src/proto_012_Psithaca/lib_delegate/baking_commands_registration.ml deleted file mode 100644 index 1050a6901021..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_commands_registration.ml +++ /dev/null @@ -1,29 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let () = - Client_commands.register Protocol.hash @@ fun _network -> - List.map (Clic.map_command (new Protocol_client_context.wrap_full)) - @@ Baking_commands.delegate_commands () diff --git a/src/proto_012_Psithaca/lib_delegate/baking_configuration.ml b/src/proto_012_Psithaca/lib_delegate/baking_configuration.ml deleted file mode 100644 index bec18c12dcd2..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_configuration.ml +++ /dev/null @@ -1,310 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Mempool = struct - type t = - | Local of {filename : string} - | Remote of {uri : Uri.t; http_headers : (string * string) list option} - - let encoding = - let open Data_encoding in - union - ~tag_size:`Uint8 - [ - case - (Tag 1) - ~title:"Local" - (obj2 (req "filename" string) (req "kind" (constant "Local"))) - (function Local {filename} -> Some (filename, ()) | _ -> None) - (fun (filename, ()) -> Local {filename}); - case - (Tag 2) - ~title:"Remote" - (obj3 - (req "uri" string) - (opt "http_headers" (list (tup2 string string))) - (req "kind" (constant "Remote"))) - (function - | Remote {uri; http_headers} -> - Some (Uri.to_string uri, http_headers, ()) - | _ -> None) - (fun (uri_str, http_headers, ()) -> - Remote {uri = Uri.of_string uri_str; http_headers}); - ] -end - -open Protocol.Alpha_context - -type fees_config = { - minimal_fees : Tez.t; - minimal_nanotez_per_gas_unit : Q.t; - minimal_nanotez_per_byte : Q.t; -} - -type validation_config = - | Local of {context_path : string} - | Node - | ContextIndex of Abstract_context_index.t - -type nonce_config = Deterministic | Random - -type state_recorder_config = Filesystem | Disabled - -type t = { - fees : fees_config; - nonce : nonce_config; - validation : validation_config; - retries_on_failure : int; - user_activated_upgrades : (int32 * Protocol_hash.t) list; - liquidity_baking_escape_vote : bool; - per_block_vote_file : string option; - force : bool; - state_recorder : state_recorder_config; - initial_mempool : Mempool.t option; -} - -let default_fees_config = - { - minimal_fees = - (match Tez.of_mutez 100L with None -> assert false | Some t -> t); - minimal_nanotez_per_gas_unit = Q.of_int 100; - minimal_nanotez_per_byte = Q.of_int 1000; - } - -let default_validation_config = Node - -(* Unclear if determinist nonces, and more importantly, if - [supports_deterministic_nonces] is supported. *) -let default_nonce_config = Random - -let default_retries_on_failure_config = 5 - -let default_user_activated_upgrades = [] - -let default_liquidity_baking_escape_vote = false - -let default_force = false - -let default_state_recorder_config = Filesystem - -let default_initial_mempool = None - -let default_per_block_vote_file = None - -let default_config = - { - fees = default_fees_config; - nonce = default_nonce_config; - validation = default_validation_config; - retries_on_failure = default_retries_on_failure_config; - user_activated_upgrades = default_user_activated_upgrades; - liquidity_baking_escape_vote = default_liquidity_baking_escape_vote; - force = default_force; - state_recorder = default_state_recorder_config; - initial_mempool = default_initial_mempool; - per_block_vote_file = default_per_block_vote_file; - } - -let make ?(minimal_fees = default_fees_config.minimal_fees) - ?(minimal_nanotez_per_gas_unit = - default_fees_config.minimal_nanotez_per_gas_unit) - ?(minimal_nanotez_per_byte = default_fees_config.minimal_nanotez_per_byte) - ?(nonce = default_nonce_config) ?context_path - ?(retries_on_failure = default_retries_on_failure_config) - ?(user_activated_upgrades = default_user_activated_upgrades) - ?(liquidity_baking_escape_vote = default_liquidity_baking_escape_vote) - ?per_block_vote_file ?(force = default_force) - ?(state_recorder = default_state_recorder_config) ?initial_mempool () = - let fees = - {minimal_fees; minimal_nanotez_per_gas_unit; minimal_nanotez_per_byte} - in - let validation = - match context_path with - | None -> Node - | Some context_path -> Local {context_path} - in - { - fees; - validation; - nonce; - retries_on_failure; - user_activated_upgrades; - liquidity_baking_escape_vote; - per_block_vote_file; - force; - state_recorder; - initial_mempool; - } - -let fees_config_encoding : fees_config Data_encoding.t = - let open Data_encoding in - let q_encoding = - conv (fun q -> Q.to_string q) (fun s -> Q.of_string s) string - in - conv - (fun {minimal_fees; minimal_nanotez_per_gas_unit; minimal_nanotez_per_byte} -> - (minimal_fees, minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte)) - (fun (minimal_fees, minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte) -> - {minimal_fees; minimal_nanotez_per_gas_unit; minimal_nanotez_per_byte}) - (obj3 - (req "minimal_fees" Tez.encoding) - (req "minimal_nanotez_per_gas_unit" q_encoding) - (req "minimal_nanotez_per_byte" q_encoding)) - -let validation_config_encoding = - let open Data_encoding in - union - ~tag_size:`Uint8 - [ - case - ~title:"Local" - (Tag 0) - (obj1 (req "local" string)) - (function Local {context_path} -> Some context_path | _ -> None) - (fun context_path -> Local {context_path}); - case - ~title:"Node" - (Tag 1) - (constant "node") - (function Node -> Some () | _ -> None) - (fun () -> Node); - ] - -let nonce_config_encoding = - let open Data_encoding in - union - ~tag_size:`Uint8 - [ - case - ~title:"Deterministic" - (Tag 0) - (constant "deterministic") - (function Deterministic -> Some () | _ -> None) - (fun () -> Deterministic); - case - ~title:"Random" - (Tag 1) - (constant "Random") - (function Random -> Some () | _ -> None) - (fun () -> Random); - ] - -let retries_on_failure_config_encoding = Data_encoding.int31 - -let user_activate_upgrades_config_encoding = - let open Data_encoding in - list (tup2 int32 Protocol_hash.encoding) - -let liquidity_baking_escape_vote_config_encoding = Data_encoding.bool - -let force_config_encoding = Data_encoding.bool - -let state_recorder_config_encoding = - let open Data_encoding in - union - ~tag_size:`Uint8 - [ - case - ~title:"Filesystem" - (Tag 0) - (constant "filesystem") - (function Filesystem -> Some () | _ -> None) - (fun () -> Filesystem); - case - ~title:"Disabled" - (Tag 1) - (constant "disabled") - (function Disabled -> Some () | _ -> None) - (fun () -> Disabled); - ] - -let encoding : t Data_encoding.t = - let open Data_encoding in - def - (String.concat "." [Protocol.name; "baking_configuration"]) - ~title:"Baking configuration" - ~description:"Baking configuration" - @@ conv - (fun { - fees; - validation; - nonce; - retries_on_failure; - user_activated_upgrades; - liquidity_baking_escape_vote; - per_block_vote_file; - force; - state_recorder; - initial_mempool; - } -> - ( fees, - validation, - nonce, - retries_on_failure, - user_activated_upgrades, - liquidity_baking_escape_vote, - per_block_vote_file, - force, - state_recorder, - initial_mempool )) - (fun ( fees, - validation, - nonce, - retries_on_failure, - user_activated_upgrades, - liquidity_baking_escape_vote, - per_block_vote_file, - force, - state_recorder, - initial_mempool ) -> - { - fees; - validation; - nonce; - retries_on_failure; - user_activated_upgrades; - liquidity_baking_escape_vote; - per_block_vote_file; - force; - state_recorder; - initial_mempool; - }) - (obj10 - (req "fees" fees_config_encoding) - (req "validation" validation_config_encoding) - (req "nonce" nonce_config_encoding) - (req "retries_on_failure" retries_on_failure_config_encoding) - (req "user_activated_upgrades" user_activate_upgrades_config_encoding) - (req - "liquidity_baking_escape_vote" - liquidity_baking_escape_vote_config_encoding) - (opt "per_block_vote_file" Data_encoding.string) - (req "force" force_config_encoding) - (req "state_recorder" state_recorder_config_encoding) - (opt "initial_mempool" Mempool.encoding)) - -let pp fmt t = - let json = Data_encoding.Json.construct encoding t in - Format.fprintf fmt "%a" Data_encoding.Json.pp json diff --git a/src/proto_012_Psithaca/lib_delegate/baking_configuration.mli b/src/proto_012_Psithaca/lib_delegate/baking_configuration.mli deleted file mode 100644 index 3b8e98235331..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_configuration.mli +++ /dev/null @@ -1,118 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) -(** {1 Mempool abstraction} *) -module Mempool : sig - type t = - | Local of {filename : string} - (** local mempool resource located in [filename] *) - | Remote of {uri : Uri.t; http_headers : (string * string) list option} - (** remote resource located a [uri], with additional [http_headers] - parameters *) - - val encoding : t Data_encoding.t -end - -type fees_config = { - minimal_fees : Protocol.Alpha_context.Tez.t; - minimal_nanotez_per_gas_unit : Q.t; - minimal_nanotez_per_byte : Q.t; -} - -type validation_config = - | Local of {context_path : string} - | Node - | ContextIndex of Abstract_context_index.t - -type nonce_config = Deterministic | Random - -type state_recorder_config = Filesystem | Disabled - -type t = { - fees : fees_config; - nonce : nonce_config; - validation : validation_config; - retries_on_failure : int; - user_activated_upgrades : (int32 * Protocol_hash.t) list; - liquidity_baking_escape_vote : bool; - per_block_vote_file : string option; - force : bool; - state_recorder : state_recorder_config; - initial_mempool : Mempool.t option; -} - -val default_fees_config : fees_config - -val default_validation_config : validation_config - -val default_nonce_config : nonce_config - -val default_retries_on_failure_config : int - -val default_user_activated_upgrades : (int32 * Protocol_hash.t) list - -val default_liquidity_baking_escape_vote : bool - -val default_force : bool - -val default_state_recorder_config : state_recorder_config - -val default_initial_mempool : Mempool.t option - -val default_per_block_vote_file : string option - -val default_config : t - -val make : - ?minimal_fees:Protocol.Alpha_context.Tez.t -> - ?minimal_nanotez_per_gas_unit:Q.t -> - ?minimal_nanotez_per_byte:Q.t -> - ?nonce:nonce_config -> - ?context_path:string -> - ?retries_on_failure:int -> - ?user_activated_upgrades:(int32 * Protocol_hash.t) list -> - ?liquidity_baking_escape_vote:bool -> - ?per_block_vote_file:string -> - ?force:bool -> - ?state_recorder:state_recorder_config -> - ?initial_mempool:Mempool.t -> - unit -> - t - -val fees_config_encoding : fees_config Data_encoding.t - -val validation_config_encoding : validation_config Data_encoding.t - -val nonce_config_encoding : nonce_config Data_encoding.t - -val retries_on_failure_config_encoding : int Data_encoding.t - -val user_activate_upgrades_config_encoding : - (int32 * Protocol_hash.t) list Data_encoding.t - -val liquidity_baking_escape_vote_config_encoding : bool Data_encoding.t - -val encoding : t Data_encoding.t - -val pp : Format.formatter -> t -> unit diff --git a/src/proto_012_Psithaca/lib_delegate/baking_errors.ml b/src/proto_012_Psithaca/lib_delegate/baking_errors.ml deleted file mode 100644 index 0332e0b7e510..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_errors.ml +++ /dev/null @@ -1,65 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += Cannot_open_context_index of {context_path : string} - -type error += Node_connection_lost - -type error += Cannot_load_local_file of string - -let make_id id = String.concat "." [Protocol.name; id] - -let () = - Error_monad.register_error_kind - `Temporary - ~id:(make_id "cannot_open_context_index") - ~title:"Cannot open context index" - ~description:"Failed to open the context index at the given location" - ~pp:(fun fmt path -> - Format.fprintf fmt "Cannot open context index at %s" path) - Data_encoding.(obj1 (req "cannot_open_context_index" Data_encoding.string)) - (function - | Cannot_open_context_index {context_path} -> Some context_path - | _ -> None) - (fun context_path -> Cannot_open_context_index {context_path}) ; - register_error_kind - `Temporary - ~id:(make_id "baking_scheduling.node_connection_lost") - ~title:"Node connection lost" - ~description:"The connection with the node was lost." - ~pp:(fun fmt () -> Format.fprintf fmt "Lost connection with the node") - Data_encoding.empty - (function Node_connection_lost -> Some () | _ -> None) - (fun () -> Node_connection_lost) ; - register_error_kind - `Temporary - ~id:(make_id "baking_scheduling.cannot_load_local_file") - ~title:"Cannot load local file" - ~description:"Cannot load local file." - ~pp:(fun fmt filename -> - Format.fprintf fmt "Cannot load the local file %s" filename) - Data_encoding.(obj1 (req "file" string)) - (function Cannot_load_local_file s -> Some s | _ -> None) - (fun s -> Cannot_load_local_file s) diff --git a/src/proto_012_Psithaca/lib_delegate/baking_events.ml b/src/proto_012_Psithaca/lib_delegate/baking_events.ml deleted file mode 100644 index d36324e3adb8..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_events.ml +++ /dev/null @@ -1,789 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -let section = [Protocol.name; "baker"] - -let pp_int32 fmt n = Format.fprintf fmt "%ld" n - -let pp_int64 fmt n = Format.fprintf fmt "%Ld" n - -module State_transitions = struct - include Internal_event.Simple - - let section = section @ ["transitions"] - - let new_head_with_increasing_level = - declare_0 - ~section - ~name:"new_head_with_increasing_level" - ~level:Info - ~msg:"received new head with level increasing" - () - - let no_proposal_slot = - declare_1 - ~section - ~name:"no_proposal_slot" - ~level:Notice - ~msg:"no proposal slot at round {round}" - ~pp1:Round.pp - ("round", Round.encoding) - - let proposal_slot = - declare_2 - ~section - ~name:"proposal_slot" - ~level:Notice - ~msg:"proposal slot at round {round} for {delegate}" - ~pp1:Round.pp - ("round", Round.encoding) - ~pp2:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) - - let new_head_while_waiting_for_qc = - declare_0 - ~section - ~name:"new_head_while_waiting_for_qc" - ~level:Info - ~msg:"received new head while waiting for a quorum" - () - - let unexpected_proposal_round = - declare_2 - ~section - ~name:"unexpected_proposal_round" - ~level:Info - ~msg: - "unexpected proposal round, expected: {expected_round}, got: \ - {proposal_round}" - ~pp1:Round.pp - ("expected_round", Round.encoding) - ~pp2:Round.pp - ("proposal_round", Round.encoding) - - let proposal_for_round_already_seen = - declare_3 - ~section - ~name:"proposal_for_round_already_seen" - ~level:Warning - ~msg: - "proposal {new_proposal} for current round ({current_round}) has \ - already been seen {previous_proposal}" - ~pp1:Block_hash.pp - ("new_proposal", Block_hash.encoding) - ~pp2:Round.pp - ("current_round", Round.encoding) - ~pp3:Block_hash.pp - ("previous_proposal", Block_hash.encoding) - - let updating_latest_proposal = - declare_1 - ~section - ~name:"updating_latest_proposal" - ~msg:"updating latest proposal to {block_hash}" - ~level:Info - ~pp1:Block_hash.pp - ("block_hash", Block_hash.encoding) - - let baker_is_ahead_of_node = - declare_2 - ~section - ~name:"baker_is_ahead" - ~level:Info - ~msg: - "baker (level: {baker_level}) is ahead of the node (level: \ - {node_level})" - ~pp1:pp_int32 - ("baker_level", Data_encoding.int32) - ~pp2:pp_int32 - ("node_level", Data_encoding.int32) - - let new_proposal_is_on_another_branch = - declare_2 - ~section - ~name:"new_proposal_is_on_another_branch" - ~level:Info - ~msg: - "received a proposal on another branch - current: current \ - pred{current_branch}, new pred {new_branch}" - ~pp1:Block_hash.pp - ("current_branch", Block_hash.encoding) - ~pp2:Block_hash.pp - ("new_branch", Block_hash.encoding) - - let switching_branch = - declare_0 - ~section - ~name:"switching_branch" - ~level:Info - ~msg:"switching branch" - () - - let branch_proposal_has_better_fitness = - declare_0 - ~section - ~name:"branch_proposal_has_better_fitness" - ~level:Info - ~msg:"different branch proposal has a better fitness than us" - () - - let branch_proposal_has_no_prequorum = - declare_0 - ~section - ~name:"branch_proposal_has_no_prequorum" - ~level:Info - ~msg:"different branch proposal has no prequorum but we do" - () - - let branch_proposal_has_lower_prequorum = - declare_0 - ~section - ~name:"branch_proposal_has_lower_prequorum" - ~level:Info - ~msg:"different branch proposal has a lower prequorum than us" - () - - let branch_proposal_has_better_prequorum = - declare_0 - ~section - ~name:"branch_proposal_has_better_prequorum" - ~level:Info - ~msg:"different branch proposal has a better prequorum" - () - - let branch_proposal_has_same_prequorum = - declare_0 - ~section - ~name:"branch_proposal_has_same_prequorum" - ~level:Error - ~msg:"different branch proposal has the same prequorum" - () - - let preendorsing_proposal = - declare_1 - ~section - ~name:"preendorsing_proposal" - ~level:Info - ~msg:"preendorsing proposal {block_hash}" - ~pp1:Block_hash.pp - ("block_hash", Block_hash.encoding) - - let skipping_invalid_proposal = - declare_0 - ~section - ~name:"skipping_invalid_proposal" - ~level:Info - ~msg:"invalid proposal, skipping" - () - - let outdated_proposal = - declare_1 - ~section - ~name:"outdated_proposal" - ~level:Debug - ~msg:"outdated proposal {block_hash}" - ~pp1:Block_hash.pp - ("block_hash", Block_hash.encoding) - - let proposing_fresh_block = - declare_2 - ~section - ~name:"proposing_fresh_block" - ~level:Info - ~msg:"proposing fresh block for {delegate} at round {round}" - ~pp1:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) - ~pp2:Round.pp - ("round", Round.encoding) - - let no_endorsable_payload_fresh_block = - declare_0 - ~section - ~name:"no_endorsable_payload_fresh_block" - ~level:Info - ~msg:"no endorsable payload, proposing fresh block" - () - - let repropose_block = - declare_1 - ~section - ~name:"repropose_block" - ~level:Info - ~msg:"repropose block with payload {payload}" - ~pp1:Block_payload_hash.pp - ("payload", Block_payload_hash.encoding) - - let unexpected_prequorum_received = - declare_2 - ~section - ~name:"unexpected_prequorum_received" - ~level:Info - ~msg: - "unexpected prequorum received for {received_hash} instead of \ - {expected_hash}" - ~pp1:Block_hash.pp - ("received_hash", Block_hash.encoding) - ~pp2:Block_hash.pp - ("expected_hash", Block_hash.encoding) - - let unexpected_quorum_received = - declare_2 - ~section - ~name:"unexpected_quorum_received" - ~level:Info - ~msg: - "unexpected quorum received for {received_hash} instead of \ - {expected_hash}" - ~pp1:Block_hash.pp - ("received_hash", Block_hash.encoding) - ~pp2:Block_hash.pp - ("expected_hash", Block_hash.encoding) - - let step_current_phase = - declare_2 - ~section - ~name:"step_current_phase" - ~level:Debug - ~msg:"automaton step: current phase {phase}, event {event}" - ~pp1:Baking_state.pp_phase - ("phase", Baking_state.phase_encoding) - ~pp2:Baking_state.pp_event - ("event", Baking_state.event_encoding) -end - -module Node_rpc = struct - include Internal_event.Simple - - let section = section @ ["rpc"] - - let error_while_monitoring_heads = - declare_1 - ~section - ~name:"error_while_monitoring_heads" - ~level:Error - ~msg:"error while monitoring heads {trace}" - ~pp1:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let raw_info = - declare_2 - ~section - ~name:"raw_info" - ~level:Debug - ~msg:"raw info for {block_hash} at level {level}" - ~pp1:Block_hash.pp - ("block_hash", Block_hash.encoding) - ~pp2:pp_int32 - ("level", Data_encoding.int32) -end - -module Scheduling = struct - include Internal_event.Simple - - let section = section @ ["scheduling"] - - let error_while_baking = - declare_1 - ~section - ~name:"error_while_baking" - ~level:Warning - ~msg:"error while baking {trace}" - ~pp1:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let waiting_for_new_head = - declare_0 - ~section - ~name:"waiting_for_new_head" - ~level:Info - ~msg:"no possible timeout, waiting for a new head to arrive..." - () - - let compute_next_timeout_elected_block = - declare_2 - ~section - ~name:"compute_next_timeout_elected_block" - ~level:Debug - ~msg: - "found an elected block at level {level}, round {round}... checking \ - baking rights" - ~pp1:pp_int32 - ("level", Data_encoding.int32) - ~pp2:Round.pp - ("round", Round.encoding) - - let proposal_already_injected = - declare_0 - ~section - ~name:"proposal_already_injected" - ~level:Debug - ~msg:"proposal already injected for next level round, skipping..." - () - - let next_potential_slot = - declare_4 - ~section - ~name:"next_potential_slot" - ~level:Info - ~msg: - "next potential slot for level {level} is at round {round} at \ - {timestamp} for {delegate}" - ~pp1:pp_int32 - ("level", Data_encoding.int32) - ~pp2:Round.pp - ("round", Round.encoding) - ~pp3:Timestamp.pp - ("timestamp", Timestamp.encoding) - ~pp4:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) - - let waiting_end_of_round = - declare_3 - ~section - ~name:"waiting_end_of_round" - ~level:Info - ~msg:"waiting {timespan} until end of round {round} at {timestamp}" - ~pp1:Ptime.Span.pp - ("timespan", Time.System.Span.encoding) - ~pp2:pp_int32 - ("round", Data_encoding.int32) - ~pp3:Timestamp.pp - ("timestamp", Timestamp.encoding) - - let waiting_delayed_end_of_round = - declare_4 - ~section - ~name:"waiting_delayed_end_of_round" - ~level:Info - ~msg: - "waiting {timespan} until {timestamp} (end of round {round} plus \ - {delay}s delay)" - ~pp1:Ptime.Span.pp - ("timespan", Time.System.Span.encoding) - ~pp2:pp_int32 - ("round", Data_encoding.int32) - ~pp3:Timestamp.pp - ("timestamp", Timestamp.encoding) - ~pp4:pp_int64 - ("delay", Data_encoding.int64) - - let waiting_time_to_bake = - declare_2 - ~section - ~name:"waiting_time_to_bake" - ~level:Info - ~msg:"waiting {timespan} until it's time to bake at {timestamp}" - ~pp1:Ptime.Span.pp - ("timespan", Time.System.Span.encoding) - ~pp2:Timestamp.pp - ("timestamp", Timestamp.encoding) - - let no_need_to_wait_for_proposal = - declare_0 - ~section - ~name:"no_need_to_wait_for_proposal" - ~level:Info - ~msg:"no need to wait to propose a block" - () - - let state_synchronized_to_round = - declare_1 - ~section - ~name:"state_synchronized_to_round" - ~level:Debug - ~msg:"state synchronized to round {round}" - ~pp1:Round.pp - ("round", Round.encoding) - - let proposal_in_the_future = - declare_1 - ~section - ~name:"proposal_in_the_future" - ~level:Debug - ~msg:"received proposal in the future {block_hash}" - ~pp1:Block_hash.pp - ("block_hash", Block_hash.encoding) - - let process_proposal_in_the_future = - declare_1 - ~section - ~name:"process_proposal_in_the_future" - ~level:Debug - ~msg:"process proposal received in the future with hash {block_hash}" - ~pp1:Block_hash.pp - ("block_hash", Block_hash.encoding) -end - -module Lib = struct - include Internal_event.Simple - - let section = section @ ["lib"] - - let preendorsing_proposal = - declare_1 - ~section - ~name:"preendorsing_proposal" - ~level:Debug - ~msg:"preendorsing proposal {proposal}" - ~pp1:Baking_state.pp_proposal - ("proposal", Baking_state.proposal_encoding) - - let endorsing_proposal = - declare_1 - ~section - ~name:"endorsing_proposal" - ~level:Debug - ~msg:"endorsing proposal {proposal}" - ~pp1:Baking_state.pp_proposal - ("proposal", Baking_state.proposal_encoding) -end - -module Actions = struct - include Internal_event.Simple - - let section = section @ ["actions"] - - let skipping_preendorsement = - declare_2 - ~section - ~name:"skipping_preendorsement" - ~level:Error - ~msg:"skipping preendorsement for {delegate} -- {trace}" - ~pp1:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) - ~pp2:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let skipping_endorsement = - declare_2 - ~section - ~name:"skipping_endorsement" - ~level:Error - ~msg:"skipping endorsement for {delegate} -- {trace}" - ~pp1:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) - ~pp2:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let failed_to_inject_preendorsement = - declare_2 - ~section - ~name:"failed_to_inject_preendorsement" - ~level:Error - ~msg:"failed to inject preendorsement for {delegate} -- {trace}" - ~pp1:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) - ~pp2:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let potential_double_baking = - declare_2 - ~section - ~name:"potential_double_baking" - ~level:Warning - ~msg:"potential double baking detected at level {level}, round {round}" - ~pp1:pp_int32 - ~pp2:Round.pp - ("level", Data_encoding.int32) - ("round", Round.encoding) - - let preendorsement_injected = - declare_2 - ~section - ~name:"preendorsement_injected" - ~level:Info - ~msg:"injected preendorsement {ophash} for {delegate}" - ~pp1:Operation_hash.pp - ("ophash", Operation_hash.encoding) - ~pp2:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) - - let endorsement_injected = - declare_2 - ~section - ~name:"endorsement_injected" - ~level:Info - ~msg:"injected endorsement {ophash} for {delegate}" - ~pp1:Operation_hash.pp - ("ophash", Operation_hash.encoding) - ~pp2:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) - - let synchronizing_round = - declare_1 - ~section - ~name:"synchronizing_round" - ~level:Info - ~msg:"synchronizing round after block {block}" - ~pp1:Block_hash.pp - ("block", Block_hash.encoding) - - let forging_block = - declare_3 - ~section - ~name:"forging_block" - ~level:Info - ~msg: - "forging block at level {level}, round {round} for delegate {delegate}" - ~pp1:pp_int32 - ~pp2:Round.pp - ~pp3:Baking_state.pp_delegate - ("level", Data_encoding.int32) - ("round", Round.encoding) - ("delegate", Baking_state.delegate_encoding) - - let injecting_block = - declare_3 - ~section - ~name:"injecting_block" - ~level:Debug - ~msg: - "injecting block at level {level}, round {round} for delegate \ - {delegate}" - ~pp1:pp_int32 - ~pp2:Round.pp - ~pp3:Baking_state.pp_delegate - ("level", Data_encoding.int32) - ("round", Round.encoding) - ("delegate", Baking_state.delegate_encoding) - - let block_injected = - declare_2 - ~section - ~name:"block_injected" - ~level:Notice - ~msg:"block {block} injected for delegate {delegate}" - ~pp1:Block_hash.pp - ~pp2:Baking_state.pp_delegate - ("block", Block_hash.encoding) - ("delegate", Baking_state.delegate_encoding) - - let signing_preendorsement = - declare_1 - ~section - ~name:"signing_preendorsement" - ~level:Info - ~msg:"signing preendorsement for {delegate}" - ~pp1:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) - - let signing_endorsement = - declare_1 - ~section - ~name:"signing_endorsement" - ~level:Info - ~msg:"signing endorsement for {delegate}" - ~pp1:Baking_state.pp_delegate - ("delegate", Baking_state.delegate_encoding) -end - -module Nonces = struct - include Internal_event.Simple - - let section = section @ ["nonces"] - - let found_nonce_to_reveal = - declare_2 - ~section - ~name:"found_nonce_to_reveal" - ~level:Notice - ~msg:"found nonce to reveal for block {block}, level {level}" - ~pp1:Block_hash.pp - ("block", Block_hash.encoding) - ~pp2:pp_int32 - ("level", Data_encoding.int32) - - let revealing_nonce = - declare_3 - ~section - ~name:"revealing_nonce" - ~level:Notice - ~msg: - "revaling nonce of level {level} (chain {chain} with operation \ - {ophash})" - ~pp1:pp_int32 - ("level", Data_encoding.int32) - ~pp2:Format.pp_print_string - ("chain", Data_encoding.string) - ~pp3:Operation_hash.pp - ("ophash", Operation_hash.encoding) - - let cannot_fetch_chain_head_level = - declare_0 - ~section - ~name:"cannot_fetch_chain_head_level" - ~level:Error - ~msg:"cannot fetch chain head level, aborting nonces filtering" - () - - let incoherent_nonce = - declare_1 - ~section - ~name:"incoherent_nonce" - ~level:Error - ~msg:"incoherent nonce for level {level}" - ~pp1:pp_int32 - ("level", Data_encoding.int32) - - let cannot_read_nonces = - declare_1 - ~section - ~name:"cannot_read_nonces" - ~level:Error - ~msg:"cannot read nonces {trace}" - ~pp1:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let cannot_retrieve_unrevealed_nonces = - declare_1 - ~section - ~name:"cannot_retrieve_unrevealed_nonces" - ~level:Error - ~msg:"cannot retrieve unrevealed nonces {trace}" - ~pp1:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let cannot_inject_nonces = - declare_1 - ~section - ~name:"cannot_inject_nonces" - ~level:Error - ~msg:"cannot inject nonces {trace}" - ~pp1:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let cant_retrieve_block_header_for_nonce = - declare_2 - ~section - ~name:"cant_retrieve_block_header_for_nonce" - ~level:Warning - ~msg: - "cannot retrieved block header {header} associated with nonce {trace}" - ("header", Data_encoding.string) - ~pp2:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let too_many_nonces = - declare_1 - ~section - ~name:"too_many_nonces" - ~level:Warning - ~msg: - "too many nonces associated with blocks unknown by node in \ - '$TEZOS_CLIENT/{filename}'. After checking that these blocks were \ - never included in the chain (e.g., via a block explorer), consider \ - using `tezos-client filter orphan nonces` to clear them." - ("filename", Data_encoding.string) - - let registering_nonce = - declare_1 - ~section - ~name:"registering_nonce" - ~level:Info - ~msg:"registering nonce for block {block}" - ~pp1:Block_hash.pp - ("block", Block_hash.encoding) - - let nothing_to_reveal = - declare_1 - ~section - ~name:"nothing_to_reveal" - ~level:Info - ~msg:"nothing to reveal for block {block}" - ~pp1:Block_hash.pp - ("block", Block_hash.encoding) - - let revelation_worker_started = - declare_0 - ~section - ~name:"revelation_worker_started" - ~level:Info - ~msg:"revelation worker started" - () -end - -module Liquidity_baking = struct - include Internal_event.Simple - - let reading_per_block = - declare_1 - ~section - ~name:"reading_per_block" - ~level:Notice - ~msg:"reading per block vote file path: {path}" - ("path", Data_encoding.string) - - let per_block_vote_file_notice = - declare_1 - ~section - ~name:"per_block_vote_file_notice" - ~level:Notice - ~msg:"per block vote file {event}" - ("event", Data_encoding.string) - - let reading_liquidity_baking = - declare_0 - ~section - ~name:"reading_liquidity_baking" - ~level:Notice - ~msg:"reading liquidity baking escape vote" - () - - let liquidity_baking_escape_vote = - declare_1 - ~section - ~name:"liquidity_baking_escape_vote" - ~level:Notice - ~msg:"liquidity baking escape vote = {value}" - ("value", Data_encoding.bool) - - let per_block_vote_file_fail = - declare_1 - ~section - ~name:"per_block_vote_file_error" - ~level:Notice - ~msg:"Error reading the block vote file: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let liquidity_baking_escape = - declare_0 - ~section - ~name:"liquidity_baking_continue" - ~level:Notice - ~msg:"Will vote to escape Liquidity Baking" - () - - let liquidity_baking_continue = - declare_0 - ~section - ~name:"liquidity_baking_escape" - ~level:Notice - ~msg:"Will vote to continue Liquidity Baking" - () -end diff --git a/src/proto_012_Psithaca/lib_delegate/baking_files.ml b/src/proto_012_Psithaca/lib_delegate/baking_files.ml deleted file mode 100644 index 38339e2fe555..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_files.ml +++ /dev/null @@ -1,37 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type _ location = string - -let resolve_location ~chain_id (kind : 'a) : 'a location = - let basename = - match kind with - | `Highwatermarks -> "highwatermark" - | `State -> "baker_state" - | `Nonce -> "nonce" - in - Format.asprintf "%a_%s" Chain_id.pp_short chain_id basename - -let filename x = x diff --git a/src/proto_012_Psithaca/lib_delegate/baking_files.mli b/src/proto_012_Psithaca/lib_delegate/baking_files.mli deleted file mode 100644 index 01146f7d0744..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_files.mli +++ /dev/null @@ -1,33 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type _ location - -val resolve_location : - chain_id:Chain_id.t -> - ([< `Highwatermarks | `Nonce | `State] as 'kind) -> - 'kind location - -val filename : [< `Highwatermarks | `Nonce | `State] location -> string diff --git a/src/proto_012_Psithaca/lib_delegate/baking_highwatermarks.ml b/src/proto_012_Psithaca/lib_delegate/baking_highwatermarks.ml deleted file mode 100644 index 5a0b12d57345..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_highwatermarks.ml +++ /dev/null @@ -1,230 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol_client_context -open Protocol.Alpha_context - -type highwatermark = {round : Round.t; level : int32} - -let highwatermark_encoding : highwatermark Data_encoding.t = - let open Data_encoding in - conv - (fun {round; level} -> (round, level)) - (fun (round, level) -> {round; level}) - (obj2 - (req "round" Protocol.Alpha_context.Round.encoding) - (req "level" int32)) - -let pp_highwatermark fmt {round; level} = - Format.fprintf fmt "round: %a, level: %ld" Round.pp round level - -type error += Block_previously_baked of highwatermark - -type error += Block_previously_preendorsed of highwatermark - -type error += Block_previously_endorsed of highwatermark - -let () = - register_error_kind - `Permanent - ~id:"highwatermarks.block_previously_baked" - ~title:"Block previously baked" - ~description:"Trying to bake a block at a level previously baked" - ~pp:(fun ppf highwatermark -> - Format.fprintf - ppf - "Block (%a) was previously baked" - pp_highwatermark - highwatermark) - highwatermark_encoding - (function - | Block_previously_baked highwatermark -> Some highwatermark | _ -> None) - (fun highwatermark -> Block_previously_baked highwatermark) ; - register_error_kind - `Permanent - ~id:"highwatermarks.block_previously_preendorsed" - ~title:"Block previously preendorsed" - ~description: - "Trying to preendorse a block at a level previously preendorsed" - ~pp:(fun ppf highwatermark -> - Format.fprintf - ppf - "Block %a was already preendorsed" - pp_highwatermark - highwatermark) - highwatermark_encoding - (function - | Block_previously_preendorsed highwatermark -> Some highwatermark - | _ -> None) - (fun highwatermark -> Block_previously_preendorsed highwatermark) ; - register_error_kind - `Permanent - ~id:"highwatermarks.block_previously_endorsed" - ~title:"Block previously endorsed" - ~description:"Trying to endorse a block at a level previously endorsed" - ~pp:(fun ppf highwatermark -> - Format.fprintf - ppf - "Block %a was previously endorsed" - pp_highwatermark - highwatermark) - highwatermark_encoding - (function - | Block_previously_endorsed highwatermark -> Some highwatermark - | _ -> None) - (fun highwatermark -> Block_previously_endorsed highwatermark) - -module DelegateMap = Map.Make (struct - type t = Signature.Public_key_hash.t - - let compare = Signature.Public_key_hash.compare -end) - -let highwatermark_delegate_map_encoding = - let open Data_encoding in - conv - DelegateMap.bindings - DelegateMap.( - fun l -> List.fold_left (fun map (k, v) -> add k v map) empty l) - (list - (obj2 - (req "delegate" Signature.Public_key_hash.encoding) - (req "highwatermark" highwatermark_encoding))) - -type highwatermarks = { - blocks : highwatermark DelegateMap.t; - preendorsements : highwatermark DelegateMap.t; - endorsements : highwatermark DelegateMap.t; -} - -type t = highwatermarks - -let encoding = - let open Data_encoding in - conv - (fun {blocks; preendorsements; endorsements} -> - (blocks, preendorsements, endorsements)) - (fun (blocks, preendorsements, endorsements) -> - {blocks; preendorsements; endorsements}) - (obj3 - (req "blocks" highwatermark_delegate_map_encoding) - (req "preendorsements" highwatermark_delegate_map_encoding) - (req "endorsements" highwatermark_delegate_map_encoding)) - -let empty = - { - blocks = DelegateMap.empty; - preendorsements = DelegateMap.empty; - endorsements = DelegateMap.empty; - } - -(* We do not lock these functions. The caller will be already locked. *) -let load (cctxt : #Protocol_client_context.full) location : t tzresult Lwt.t = - protect (fun () -> - cctxt#load (Baking_files.filename location) encoding ~default:empty) - -let save_highwatermarks (cctxt : #Protocol_client_context.full) filename - highwatermarks : unit tzresult Lwt.t = - protect (fun () -> - (* TODO: improve the backend so we don't write partial informations *) - cctxt#write filename highwatermarks encoding) - -let may_sign highwatermarks ~delegate ~level ~round = - match DelegateMap.find delegate highwatermarks with - | None -> true - | Some highwatermark -> - if Compare.Int32.(highwatermark.level < level) then true - else if Compare.Int32.(highwatermark.level = level) then - Round.(highwatermark.round < round) - else false - -let may_sign_block cctxt (location : [`Highwatermarks] Baking_files.location) - ~delegate ~level ~round = - load cctxt location >>=? fun all_highwatermarks -> - return @@ may_sign all_highwatermarks.blocks ~delegate ~level ~round - -let may_sign_preendorsement cctxt location ~delegate ~level ~round = - load cctxt location >>=? fun all_highwatermarks -> - return @@ may_sign all_highwatermarks.preendorsements ~delegate ~level ~round - -let may_sign_endorsement cctxt location ~delegate ~level ~round = - load cctxt location >>=? fun all_highwatermarks -> - return @@ may_sign all_highwatermarks.endorsements ~delegate ~level ~round - -let record map ~delegate ~new_level ~new_round = - DelegateMap.update - delegate - (function - | None -> Some {level = new_level; round = new_round} - | Some ({level; round} as prev) -> - if Compare.Int32.(new_level > level) then - Some {level = new_level; round = new_round} - else if Compare.Int32.(new_level = level) then - if Round.(new_round > round) then - Some {level = new_level; round = new_round} - else Some prev - else Some prev) - map - -let record_block (cctxt : #Protocol_client_context.full) location ~delegate - ~level ~round = - let filename = Baking_files.filename location in - load cctxt location >>=? fun highwatermarks -> - let new_blocks = - record highwatermarks.blocks ~delegate ~new_level:level ~new_round:round - in - save_highwatermarks cctxt filename {highwatermarks with blocks = new_blocks} - -let record_preendorsement (cctxt : #Protocol_client_context.full) location - ~delegate ~level ~round = - let filename = Baking_files.filename location in - load cctxt location >>=? fun highwatermarks -> - let new_preendorsements = - record - highwatermarks.preendorsements - ~delegate - ~new_level:level - ~new_round:round - in - save_highwatermarks - cctxt - filename - {highwatermarks with preendorsements = new_preendorsements} - -let record_endorsement (cctxt : #Protocol_client_context.full) location - ~delegate ~level ~round = - let filename = Baking_files.filename location in - load cctxt location >>=? fun highwatermarks -> - let new_endorsements = - record - highwatermarks.endorsements - ~delegate - ~new_level:level - ~new_round:round - in - save_highwatermarks - cctxt - filename - {highwatermarks with endorsements = new_endorsements} diff --git a/src/proto_012_Psithaca/lib_delegate/baking_highwatermarks.mli b/src/proto_012_Psithaca/lib_delegate/baking_highwatermarks.mli deleted file mode 100644 index 757b667c58bb..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_highwatermarks.mli +++ /dev/null @@ -1,91 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol.Alpha_context - -type highwatermark = {round : Round.t; level : int32} - -type error += Block_previously_baked of highwatermark - -type error += Block_previously_preendorsed of highwatermark - -type error += Block_previously_endorsed of highwatermark - -type t - -val encoding : t Data_encoding.t - -val load : - #Protocol_client_context.full -> - [`Highwatermarks] Baking_files.location -> - t tzresult Lwt.t - -val may_sign_block : - #Protocol_client_context.full -> - [`Highwatermarks] Baking_files.location -> - delegate:Signature.public_key_hash -> - level:int32 -> - round:Round.t -> - bool tzresult Lwt.t - -val may_sign_preendorsement : - #Protocol_client_context.full -> - [`Highwatermarks] Baking_files.location -> - delegate:Signature.public_key_hash -> - level:int32 -> - round:Round.t -> - bool tzresult Lwt.t - -val may_sign_endorsement : - #Protocol_client_context.full -> - [`Highwatermarks] Baking_files.location -> - delegate:Signature.public_key_hash -> - level:int32 -> - round:Round.t -> - bool tzresult Lwt.t - -val record_block : - #Protocol_client_context.full -> - [`Highwatermarks] Baking_files.location -> - delegate:Signature.public_key_hash -> - level:int32 -> - round:Round.t -> - unit tzresult Lwt.t - -val record_preendorsement : - #Protocol_client_context.full -> - [`Highwatermarks] Baking_files.location -> - delegate:Signature.public_key_hash -> - level:int32 -> - round:Round.t -> - unit tzresult Lwt.t - -val record_endorsement : - #Protocol_client_context.full -> - [`Highwatermarks] Baking_files.location -> - delegate:Signature.public_key_hash -> - level:int32 -> - round:Round.t -> - unit tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/baking_lib.ml b/src/proto_012_Psithaca/lib_delegate/baking_lib.ml deleted file mode 100644 index 7528e873e6dd..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_lib.ml +++ /dev/null @@ -1,487 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Baking_state - -let create_state cctxt ?synchronize ?monitor_node_mempool ~config - ~current_proposal delegates = - let chain = cctxt#chain in - let monitor_node_operations = monitor_node_mempool in - let initial_mempool = config.Baking_configuration.initial_mempool in - Operation_worker.create ?initial_mempool ?monitor_node_operations cctxt - >>= fun operation_worker -> - Baking_scheduling.create_initial_state - cctxt - ?synchronize - ~chain - config - operation_worker - ~current_proposal - delegates - -let get_current_proposal cctxt = - Node_rpc.monitor_proposals cctxt ~chain:cctxt#chain () - >>=? fun (block_stream, _block_stream_stopper) -> - Lwt_stream.peek block_stream >>= function - | Some current_head -> return (block_stream, current_head) - | None -> failwith "head stream unexpectedly ended" - -module Events = Baking_events.Lib - -let preendorse (cctxt : Protocol_client_context.full) ?(force = false) delegates - = - let open State_transitions in - get_current_proposal cctxt >>=? fun (_, current_proposal) -> - let config = Baking_configuration.make ~force () in - create_state cctxt ~config ~current_proposal delegates >>=? fun state -> - let proposal = state.level_state.latest_proposal in - Events.(emit preendorsing_proposal state.level_state.latest_proposal) - >>= fun () -> - (if force then return_unit - else - is_acceptable_proposal_for_current_level state proposal >>= function - | Invalid -> cctxt#error "Cannot preendorse an invalid proposal" - | Outdated_proposal -> cctxt#error "Cannot preendorse an outdated proposal" - | Valid_proposal -> return_unit) - >>=? fun () -> - let consensus_list = make_consensus_list state proposal in - cctxt#message - "@[Preendorsing for:@ %a@]" - Format.(pp_print_list ~pp_sep:pp_print_space Baking_state.pp_delegate) - (List.map fst consensus_list) - >>= fun () -> - let state_recorder ~new_state = - Baking_state.may_record_new_state ~previous_state:state ~new_state - in - Baking_actions.inject_preendorsements - ~state_recorder - state - ~preendorsements:consensus_list - ~updated_state:state - >>=? fun _ -> return_unit - -let endorse (cctxt : Protocol_client_context.full) ?(force = false) delegates = - let open State_transitions in - get_current_proposal cctxt >>=? fun (_, current_proposal) -> - let config = Baking_configuration.make ~force () in - create_state cctxt ~config ~current_proposal delegates >>=? fun state -> - let proposal = state.level_state.latest_proposal in - Events.(emit endorsing_proposal state.level_state.latest_proposal) - >>= fun () -> - (if force then return_unit - else - is_acceptable_proposal_for_current_level state proposal >>= function - | Invalid -> cctxt#error "Cannot endorse an invalid proposal" - | Outdated_proposal -> cctxt#error "Cannot endorse an outdated proposal" - | Valid_proposal -> return_unit) - >>=? fun () -> - let consensus_list = make_consensus_list state proposal in - cctxt#message - "@[Endorsing for:@ %a@]" - Format.(pp_print_list ~pp_sep:pp_print_space Baking_state.pp_delegate) - (List.map fst consensus_list) - >>= fun () -> - let state_recorder ~new_state = - Baking_state.may_record_new_state ~previous_state:state ~new_state - in - Baking_actions.inject_endorsements - ~state_recorder - state - ~endorsements:consensus_list - ~updated_state:state - >>=? fun _ -> return_unit - -let bake_at_next_level state = - let cctxt = state.global_state.cctxt in - Baking_scheduling.compute_next_potential_baking_time_at_next_level state - >>= function - | None -> cctxt#error "No baking slot found for the delegates" - | Some (timestamp, round) -> - cctxt#message - "Waiting until %a for round %a" - Timestamp.pp - timestamp - Round.pp - round - >>= fun () -> - Option.value - ~default:Lwt.return_unit - (Baking_scheduling.sleep_until timestamp) - >>= fun () -> - return (Baking_state.Timeout (Time_to_bake_next_level {at_round = round})) - -(* Simulate the end of the current round to bootstrap the automaton - or endorse the block if necessary *) -let first_automaton_event state = - match state.level_state.elected_block with - | None -> Lwt.return (Baking_scheduling.compute_bootstrap_event state) - | Some _elected_block -> - (* If there is an elected block we can directly bake at next - level after waiting its date *) - bake_at_next_level state - -let endorsements_endorsing_power state endorsements = - let get_endorsement_voting_power {slot; _} = - match - SlotMap.find slot state.level_state.delegate_slots.all_delegate_slots - with - | None -> assert false - | Some {endorsing_power; _} -> endorsing_power - in - List.sort_uniq compare endorsements - |> List.fold_left - (fun power endorsement -> - power + get_endorsement_voting_power endorsement) - 0 - -let generic_endorsing_power (filter : packed_operation list -> 'a list) - (extract : 'a -> consensus_content) state = - let current_mempool = - Operation_worker.get_current_operations state.global_state.operation_worker - in - let latest_proposal = state.level_state.latest_proposal in - let block_round = latest_proposal.block.round in - let shell_level = latest_proposal.block.shell.level in - let endorsements = - filter (Operation_pool.OpSet.elements current_mempool.consensus) - in - let endorsements_in_mempool = - List.filter_map - (fun v -> - let consensus_content = extract v in - if - Round.(consensus_content.round = block_round) - && Compare.Int32.( - Raw_level.to_int32 consensus_content.level = shell_level) - then Some consensus_content - else None) - endorsements - in - let power = endorsements_endorsing_power state endorsements_in_mempool in - (power, endorsements) - -let state_endorsing_power = - generic_endorsing_power - Operation_pool.filter_endorsements - (fun - ({ - protocol_data = {contents = Single (Endorsement consensus_content); _}; - _; - } : - Kind.endorsement operation) - -> consensus_content) - -let do_action (state, action) = - let state_recorder ~new_state = - Baking_state.may_record_new_state ~previous_state:state ~new_state - in - Baking_actions.perform_action ~state_recorder state action - -let propose_at_next_level ~minimal_timestamp state = - let cctxt = state.global_state.cctxt in - assert (Option.is_some state.level_state.elected_block) ; - if minimal_timestamp then - (match - Baking_scheduling.first_potential_round_at_next_level - state - ~earliest_round:Round.zero - with - | None -> cctxt#error "No potential baking slot for the given delegates." - | Some first_potential_round -> return first_potential_round) - >>=? fun (minimal_round, delegate) -> - let pool = - Operation_worker.get_current_operations - state.global_state.operation_worker - in - let kind = Baking_actions.Fresh pool in - let block_to_bake : Baking_actions.block_to_bake = - { - Baking_actions.predecessor = state.level_state.latest_proposal.block; - round = minimal_round; - delegate; - kind; - } - in - let state_recorder ~new_state = - Baking_state.may_record_new_state ~previous_state:state ~new_state - in - Baking_actions.perform_action - ~state_recorder - state - (Inject_block {block_to_bake; updated_state = state}) - >>=? fun state -> - cctxt#message - "Proposed block at round %a on top of %a " - Round.pp - block_to_bake.round - Block_hash.pp - block_to_bake.predecessor.hash - >>= fun () -> return state - else - bake_at_next_level state >>=? fun event -> - State_transitions.step state event >>= do_action >>=? fun state -> - cctxt#message "Proposal injected" >>= fun () -> return state - -let endorsement_quorum state = - let (power, endorsements) = state_endorsing_power state in - if - Compare.Int.( - power >= state.global_state.constants.parametric.consensus_threshold) - then Some (power, endorsements) - else None - -(* Here's the sketch of the algorithm: - Do I have an endorsement quorum for the current block or an elected block? - - Yes :: wait and propose at next level - - No :: - Is the current proposal at the right round? - - Yes :: fail propose - - No :: - Is there a preendorsement quorum or does the last proposal contain a prequorum? - - Yes :: repropose block with right payload and preendorsements for current round - - No :: repropose fresh block for current round *) -let propose (cctxt : Protocol_client_context.full) ?minimal_fees - ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?force - ?(minimal_timestamp = false) ?mempool ?context_path delegates = - get_current_proposal cctxt >>=? fun (_block_stream, current_proposal) -> - let config = - let initial_mempool = mempool in - Baking_configuration.make - ?minimal_fees - ?minimal_nanotez_per_gas_unit - ?minimal_nanotez_per_byte - ?context_path - ?force - ?initial_mempool - () - in - create_state cctxt ~config ~current_proposal delegates >>=? fun state -> - (match state.level_state.elected_block with - | Some _ -> propose_at_next_level ~minimal_timestamp state - | None -> ( - match endorsement_quorum state with - | Some (voting_power, endorsement_qc) -> - let state = - { - state with - round_state = - { - state.round_state with - current_phase = Baking_state.Awaiting_endorsements; - }; - } - in - let latest_proposal = state.level_state.latest_proposal.block in - let candidate = - { - Operation_worker.hash = latest_proposal.hash; - round_watched = latest_proposal.round; - payload_hash_watched = latest_proposal.payload_hash; - } - in - State_transitions.step - state - (Baking_state.Quorum_reached - (candidate, voting_power, endorsement_qc)) - >>= do_action - (* this will register the elected block *) - >>=? fun state -> propose_at_next_level ~minimal_timestamp state - | None -> ( - Baking_scheduling.compute_bootstrap_event state >>?= fun event -> - State_transitions.step state event >>= fun (state, _action) -> - let latest_proposal = state.level_state.latest_proposal in - let open State_transitions in - let round = state.round_state.current_round in - is_acceptable_proposal_for_current_level state latest_proposal - >>= function - | Invalid | Outdated_proposal -> ( - let slotmap = - state.level_state.delegate_slots.own_delegate_slots - in - match State_transitions.round_proposer state slotmap round with - | Some (delegate, _) -> - State_transitions.repropose_block_action - state - delegate - round - state.level_state.latest_proposal - >>= fun action -> - do_action (state, action) >>=? fun state -> - cctxt#message - "Reproposed block at level %ld on round %a" - state.level_state.current_level - Round.pp - state.round_state.current_round - >>= fun () -> return state - | None -> cctxt#error "No slots for current round") - | Valid_proposal -> - cctxt#error - "Cannot propose: there's already a valid proposal for the \ - current round %a" - Round.pp - round))) - >>=? fun _ -> return_unit - -let bake_using_automaton config state block_stream = - let cctxt = state.global_state.cctxt in - first_automaton_event state >>=? fun initial_event -> - let current_level = state.level_state.latest_proposal.block.shell.level in - let loop_state = - Baking_scheduling.create_loop_state - block_stream - state.global_state.operation_worker - in - let stop_on_next_level_block = function - | New_proposal proposal -> - Compare.Int32.(proposal.block.shell.level >= Int32.succ current_level) - | _ -> false - in - Baking_scheduling.automaton_loop - ~stop_on_event:stop_on_next_level_block - ~config - ~on_error:(fun err -> Lwt.return (Error err)) - loop_state - state - initial_event - >>=? function - | Some (New_proposal proposal) -> - cctxt#message - "Block %a (%ld) injected" - Block_hash.pp - proposal.block.hash - proposal.block.shell.level - >>= fun () -> return_unit - | _ -> cctxt#error "Baking loop unexpectedly ended" - -(* endorse the latest proposal and bake with it *) -let baking_minimal_timestamp state = - let cctxt = state.global_state.cctxt in - let latest_proposal = state.level_state.latest_proposal in - let own_endorsements = - State_transitions.make_consensus_list state latest_proposal - in - let current_mempool = - Operation_worker.get_current_operations state.global_state.operation_worker - in - let endorsements_in_mempool = - Operation_pool.( - filter_endorsements (OpSet.elements current_mempool.consensus)) - |> List.filter_map - (fun - ({ - protocol_data = - {contents = Single (Endorsement consensus_content); _}; - _; - } : - Kind.endorsement operation) - -> - if - Round.(consensus_content.round = latest_proposal.block.round) - && Compare.Int32.( - Raw_level.to_int32 consensus_content.level - = latest_proposal.block.shell.level) - then Some consensus_content - else None) - in - let total_voting_power = - List.fold_left - (fun endorsements own -> snd own :: endorsements) - endorsements_in_mempool - own_endorsements - |> endorsements_endorsing_power state - in - let consensus_threshold = - state.global_state.constants.parametric.consensus_threshold - in - (if Compare.Int.(total_voting_power < consensus_threshold) then - cctxt#error - "Delegates do not have enough voting power. Only %d is available while %d \ - is required." - total_voting_power - consensus_threshold - else return_unit) - >>=? fun () -> - (match - Baking_scheduling.first_potential_round_at_next_level - state - ~earliest_round:Round.zero - with - | None -> cctxt#error "No potential baking slot for the given delegates." - | Some first_potential_round -> return first_potential_round) - >>=? fun (minimal_round, delegate) -> - Baking_actions.sign_endorsements state own_endorsements - >>=? fun signed_endorsements -> - let pool = - Operation_pool.add_operations - current_mempool - (List.map snd signed_endorsements) - in - let kind = Baking_actions.Fresh pool in - let block_to_bake : Baking_actions.block_to_bake = - { - Baking_actions.predecessor = latest_proposal.block; - round = minimal_round; - delegate; - kind; - } - in - let state_recorder ~new_state = - Baking_state.may_record_new_state ~previous_state:state ~new_state - in - Baking_actions.perform_action - ~state_recorder - state - (Inject_block {block_to_bake; updated_state = state}) - >>=? fun _ -> - cctxt#message "Injected block at minimal timestamp" >>= fun () -> return_unit - -let bake (cctxt : Protocol_client_context.full) ?minimal_fees - ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?force - ?(minimal_timestamp = false) ?mempool ?monitor_node_mempool ?context_path - delegates = - let config = - let initial_mempool = mempool in - Baking_configuration.make - ?minimal_fees - ?minimal_nanotez_per_gas_unit - ?minimal_nanotez_per_byte - ?context_path - ?force - ?initial_mempool - () - in - get_current_proposal cctxt >>=? fun (block_stream, current_proposal) -> - create_state - cctxt - ?monitor_node_mempool - ~synchronize:(not minimal_timestamp) - ~config - ~current_proposal - delegates - >>=? fun state -> - if not minimal_timestamp then bake_using_automaton config state block_stream - else baking_minimal_timestamp state diff --git a/src/proto_012_Psithaca/lib_delegate/baking_lib.mli b/src/proto_012_Psithaca/lib_delegate/baking_lib.mli deleted file mode 100644 index d027ec19109e..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_lib.mli +++ /dev/null @@ -1,65 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol.Alpha_context - -(** {1 API} *) - -val bake : - Protocol_client_context.full -> - ?minimal_fees:Tez.t -> - ?minimal_nanotez_per_gas_unit:Q.t -> - ?minimal_nanotez_per_byte:Q.t -> - ?force:bool -> - ?minimal_timestamp:bool -> - ?mempool:Baking_configuration.Mempool.t -> - ?monitor_node_mempool:bool -> - ?context_path:string -> - Baking_state.delegate list -> - unit tzresult Lwt.t - -val preendorse : - Protocol_client_context.full -> - ?force:bool -> - Baking_state.delegate list -> - unit tzresult Lwt.t - -val endorse : - Protocol_client_context.full -> - ?force:bool -> - Baking_state.delegate list -> - unit tzresult Lwt.t - -val propose : - Protocol_client_context.full -> - ?minimal_fees:Tez.t -> - ?minimal_nanotez_per_gas_unit:Q.t -> - ?minimal_nanotez_per_byte:Q.t -> - ?force:bool -> - ?minimal_timestamp:bool -> - ?mempool:Baking_configuration.Mempool.t -> - ?context_path:string -> - Baking_state.delegate list -> - unit tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/baking_nonces.ml b/src/proto_012_Psithaca/lib_delegate/baking_nonces.ml deleted file mode 100644 index 136c12ae2592..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_nonces.ml +++ /dev/null @@ -1,321 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -module Events = Baking_events.Nonces - -type state = { - cctxt : Protocol_client_context.full; - chain : Chain_services.chain; - constants : Constants.t; - config : Baking_configuration.nonce_config; - nonces_location : [`Nonce] Baking_files.location; - mutable last_predecessor : Block_hash.t; -} - -type t = state - -type nonces = Nonce.t Block_hash.Map.t - -let empty = Block_hash.Map.empty - -let encoding = - let open Data_encoding in - def "seed_nonce" - @@ conv - (fun m -> - Block_hash.Map.fold (fun hash nonce acc -> (hash, nonce) :: acc) m []) - (fun l -> - List.fold_left - (fun map (hash, nonce) -> Block_hash.Map.add hash nonce map) - Block_hash.Map.empty - l) - @@ list (obj2 (req "block" Block_hash.encoding) (req "nonce" Nonce.encoding)) - -let may_migrate (wallet : Protocol_client_context.full) location = - let base_dir = wallet#get_base_dir in - let current_file = - Filename.Infix.((base_dir // Baking_files.filename location) ^ "s") - in - Lwt_unix.file_exists current_file >>= function - | true -> - (* Migration already occured *) - Lwt.return_unit - | false -> ( - let legacy_file = Filename.Infix.(base_dir // "nonces") in - Lwt_unix.file_exists legacy_file >>= function - | false -> - (* Do nothing *) - Lwt.return_unit - | true -> Lwt_utils_unix.copy_file ~src:legacy_file ~dst:current_file) - -let load (wallet : #Client_context.wallet) location = - wallet#load (Baking_files.filename location) ~default:empty encoding - -let save (wallet : #Client_context.wallet) location nonces = - wallet#write (Baking_files.filename location) nonces encoding - -let mem nonces hash = Block_hash.Map.mem hash nonces - -let find_opt nonces hash = Block_hash.Map.find hash nonces - -let add nonces hash nonce = Block_hash.Map.add hash nonce nonces - -let remove nonces hash = Block_hash.Map.remove hash nonces - -let remove_all nonces nonces_to_remove = - Block_hash.Map.fold - (fun hash _ acc -> remove acc hash) - nonces_to_remove - nonces - -let get_block_level_opt cctxt ~chain ~block = - Shell_services.Blocks.Header.shell_header cctxt ~chain ~block () >>= function - | Ok {level; _} -> Lwt.return_some level - | Error errs -> - Events.( - emit - cant_retrieve_block_header_for_nonce - (Block_services.to_string block, errs)) - >>= fun () -> Lwt.return_none - -let get_outdated_nonces {cctxt; constants; chain; _} nonces = - let {Constants.parametric = {blocks_per_cycle; preserved_cycles; _}; _} = - constants - in - get_block_level_opt cctxt ~chain ~block:(`Head 0) >>= function - | None -> - Events.(emit cannot_fetch_chain_head_level ()) >>= fun () -> - return (empty, empty) - | Some current_level -> - let current_cycle = Int32.(div current_level blocks_per_cycle) in - let is_older_than_preserved_cycles block_level = - let block_cycle = Int32.(div block_level blocks_per_cycle) in - Int32.sub current_cycle block_cycle > Int32.of_int preserved_cycles - in - Block_hash.Map.fold - (fun hash nonce acc -> - acc >>=? fun (orphans, outdated) -> - get_block_level_opt cctxt ~chain ~block:(`Hash (hash, 0)) >>= function - | Some level -> - if is_older_than_preserved_cycles level then - return (orphans, add outdated hash nonce) - else acc - | None -> return (add orphans hash nonce, outdated)) - nonces - (return (empty, empty)) - -let filter_outdated_nonces state nonces = - get_outdated_nonces state nonces >>=? fun (orphans, outdated_nonces) -> - when_ - (Block_hash.Map.cardinal orphans >= 50) - (fun () -> - Events.( - emit too_many_nonces (Baking_files.filename state.nonces_location ^ "s")) - >>= fun () -> return_unit) - >>=? fun () -> return (remove_all nonces outdated_nonces) - -let blocks_from_current_cycle {cctxt; chain; _} block ?(offset = 0l) () = - Shell_services.Blocks.hash cctxt ~chain ~block () >>=? fun hash -> - Shell_services.Blocks.Header.shell_header cctxt ~chain ~block () - >>=? fun {level; _} -> - Plugin.RPC.levels_in_current_cycle cctxt ~offset (chain, block) >>= function - | Error (RPC_context.Not_found _ :: _) -> return_nil - | Error _ as err -> Lwt.return err - | Ok (first, last) -> - (* FIXME: crappy algorithm, change this *) - let length = Int32.to_int (Int32.sub level (Raw_level.to_int32 first)) in - Shell_services.Blocks.list cctxt ~chain ~heads:[hash] ~length () - >>=? fun blocks -> - let head = Stdlib.List.hd blocks in - let blocks = - List.remove (length - Int32.to_int (Raw_level.diff last first)) head - in - if Int32.equal level (Raw_level.to_int32 last) then - return (hash :: blocks) - else return blocks - -let get_unrevealed_nonces ({cctxt; chain; _} as state) nonces = - blocks_from_current_cycle state (`Head 0) ~offset:(-1l) () >>=? fun blocks -> - List.filter_map_es - (fun hash -> - match find_opt nonces hash with - | None -> return_none - | Some nonce -> ( - get_block_level_opt cctxt ~chain ~block:(`Hash (hash, 0)) >>= function - | Some level -> ( - Lwt.return (Environment.wrap_tzresult (Raw_level.of_int32 level)) - >>=? fun level -> - Alpha_services.Nonce.get cctxt (chain, `Head 0) level - >>=? function - | Missing nonce_hash when Nonce.check_hash nonce nonce_hash -> - Events.( - emit found_nonce_to_reveal (hash, Raw_level.to_int32 level)) - >>= fun () -> return_some (level, nonce) - | Missing _nonce_hash -> - Events.(emit incoherent_nonce (Raw_level.to_int32 level)) - >>= fun () -> return_none - | Forgotten -> return_none - | Revealed _ -> return_none) - | None -> return_none)) - blocks - -(* Nonce creation *) - -let generate_seed_nonce (nonce_config : Baking_configuration.nonce_config) - (delegate : Baking_state.delegate) level = - (match nonce_config with - | Deterministic -> - let data = Data_encoding.Binary.to_bytes_exn Raw_level.encoding level in - Client_keys.deterministic_nonce delegate.secret_key_uri data - >>=? fun nonce -> - return (Data_encoding.Binary.of_bytes_exn Nonce.encoding nonce) - | Random -> ( - match Nonce.of_bytes (Rand.generate Constants.nonce_length) with - | Error _errs -> assert false - | Ok nonce -> return nonce)) - >>=? fun nonce -> return (Nonce.hash nonce, nonce) - -let register_nonce (cctxt : #Protocol_client_context.full) ~chain_id block_hash - nonce = - Events.(emit registering_nonce block_hash) >>= fun () -> - (* Register the nonce *) - let nonces_location = Baking_files.resolve_location ~chain_id `Nonce in - cctxt#with_lock @@ fun () -> - load cctxt nonces_location >>=? fun nonces -> - let nonces = add nonces block_hash nonce in - save cctxt nonces_location nonces >>=? fun () -> return_unit - -let inject_seed_nonce_revelation (cctxt : #Protocol_client_context.full) ~chain - ~block ~branch nonces = - match nonces with - | [] -> Events.(emit nothing_to_reveal branch) >>= fun () -> return_unit - | _ -> - List.iter_es - (fun (level, nonce) -> - Plugin.RPC.Forge.seed_nonce_revelation - cctxt - (chain, block) - ~branch - ~level - ~nonce - () - >>=? fun bytes -> - let bytes = Signature.concat bytes Signature.zero in - Shell_services.Injection.operation ~async:true cctxt ~chain bytes - >>=? fun oph -> - Events.( - emit - revealing_nonce - (Raw_level.to_int32 level, Chain_services.to_string chain, oph)) - >>= fun () -> return_unit) - nonces - -(** [reveal_potential_nonces] reveal registered nonces *) -let reveal_potential_nonces - ({cctxt; chain; nonces_location; last_predecessor; _} as state) new_proposal - = - let new_predecessor_hash = new_proposal.Baking_state.predecessor.hash in - if - Block_hash.(last_predecessor <> new_predecessor_hash) - && Protocol_hash.(new_proposal.predecessor.protocol = Protocol.hash) - then ( - (* only try revealing nonces when the proposal's predecessor is a new one *) - state.last_predecessor <- new_predecessor_hash ; - let block = `Head 0 in - let branch = new_predecessor_hash in - (* improve concurrency *) - cctxt#with_lock @@ fun () -> - load cctxt nonces_location >>= function - | Error err -> - Events.(emit cannot_read_nonces err) >>= fun () -> return_unit - | Ok nonces -> ( - get_unrevealed_nonces state nonces >>= function - | Error err -> - Events.(emit cannot_retrieve_unrevealed_nonces err) >>= fun () -> - return_unit - | Ok [] -> return_unit - | Ok nonces_to_reveal -> ( - inject_seed_nonce_revelation - cctxt - ~chain - ~block - ~branch - nonces_to_reveal - >>= function - | Error err -> - Events.(emit cannot_inject_nonces err) >>= fun () -> return_unit - | Ok () -> - (* If some nonces are to be revealed it means: - - We entered a new cycle and we can clear old nonces ; - - A revelation was not included yet in the cycle beginning. - So, it is safe to only filter outdated_nonces there *) - filter_outdated_nonces state nonces >>=? fun live_nonces -> - save cctxt nonces_location live_nonces >>=? fun () -> - return_unit))) - else return_unit - -(* We suppose that the block stream is cloned by the caller *) -let start_revelation_worker cctxt config chain_id constants block_stream = - let nonces_location = Baking_files.resolve_location ~chain_id `Nonce in - may_migrate cctxt nonces_location >>= fun () -> - let chain = `Hash chain_id in - let canceler = Lwt_canceler.create () in - let should_shutdown = ref false in - let state = - { - cctxt; - chain; - constants; - config; - nonces_location; - last_predecessor = Block_hash.zero; - } - in - let rec worker_loop () = - Lwt_canceler.on_cancel canceler (fun () -> - should_shutdown := true ; - Lwt.return_unit) ; - Lwt_stream.get block_stream >>= function - | None -> - (* The head stream closed meaning that the connection - with the node was interrupted: exit *) - return_unit - | Some new_proposal -> - if !should_shutdown then return_unit - else - reveal_potential_nonces state new_proposal >>=? fun () -> - worker_loop () - in - Lwt.dont_wait - (fun () -> - Lwt.finalize - (fun () -> - Events.(emit revelation_worker_started ()) >>= fun () -> - worker_loop () >>= fun _ -> (* never ending loop *) Lwt.return_unit) - (fun () -> (* TODO *) Lwt.return_unit)) - (fun _exn -> ()) ; - Lwt.return canceler diff --git a/src/proto_012_Psithaca/lib_delegate/baking_nonces.mli b/src/proto_012_Psithaca/lib_delegate/baking_nonces.mli deleted file mode 100644 index baa6ebf23f18..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_nonces.mli +++ /dev/null @@ -1,114 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type state = { - cctxt : Protocol_client_context.full; - chain : Chain_services.chain; - constants : Constants.t; - config : Baking_configuration.nonce_config; - nonces_location : [`Nonce] Baking_files.location; - mutable last_predecessor : Block_hash.t; -} - -type t = state - -type nonces = Nonce.t Block_hash.Map.t - -val empty : Nonce.t Block_hash.Map.t - -val encoding : Nonce.t Block_hash.Map.t Data_encoding.t - -val load : - #Client_context.wallet -> - [< `Highwatermarks | `Nonce | `State] Baking_files.location -> - Nonce.t Block_hash.Map.t tzresult Lwt.t - -val save : - #Client_context.wallet -> - [< `Highwatermarks | `Nonce | `State] Baking_files.location -> - Nonce.t Block_hash.Map.t -> - unit tzresult Lwt.t - -val mem : Nonce.t Block_hash.Map.t -> Block_hash.t -> bool - -val find_opt : Nonce.t Block_hash.Map.t -> Block_hash.t -> Nonce.t option - -val get_block_level_opt : - #RPC_context.simple -> - chain:Block_services.chain -> - block:Block_services.block -> - int32 option Lwt.t - -val get_outdated_nonces : - t -> - Nonce.t Block_hash.Map.t -> - (Nonce.t Block_hash.Map.t * Nonce.t Block_hash.Map.t) tzresult Lwt.t - -val filter_outdated_nonces : - t -> Nonce.t Block_hash.Map.t -> Nonce.t Block_hash.Map.t tzresult Lwt.t - -val blocks_from_current_cycle : - t -> - Block_services.block -> - ?offset:int32 -> - unit -> - Block_hash.t list tzresult Lwt.t - -val get_unrevealed_nonces : - t -> Nonce.t Block_hash.Map.t -> (Raw_level.t * Nonce.t) list tzresult Lwt.t - -val generate_seed_nonce : - Baking_configuration.nonce_config -> - Baking_state.delegate -> - Raw_level.t -> - (Nonce_hash.t * Nonce.t) tzresult Lwt.t - -val register_nonce : - #Protocol_client_context.full -> - chain_id:Chain_id.t -> - Block_hash.t -> - Nonce.t -> - unit tzresult Lwt.t - -val inject_seed_nonce_revelation : - #Protocol_client_context.full -> - chain:Chain_services.chain -> - block:Block_services.block -> - branch:Block_hash.t -> - (Raw_level.t * Nonce.t) list -> - unit tzresult Lwt.t - -val reveal_potential_nonces : t -> Baking_state.proposal -> unit tzresult Lwt.t - -val start_revelation_worker : - Protocol_client_context.full -> - Baking_configuration.nonce_config -> - Chain_id.t -> - Constants.t -> - Baking_state.proposal Lwt_stream.t -> - Lwt_canceler.t Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/baking_pow.ml b/src/proto_012_Psithaca/lib_delegate/baking_pow.ml deleted file mode 100644 index 5637988fb52b..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_pow.ml +++ /dev/null @@ -1,85 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -let default_constant = "\x00\x00\x00\x05" - -let is_updated_constant = - let commit_hash = - match Hex.to_string (`Hex Tezos_version.Current_git_info.commit_hash) with - | None -> Tezos_version.Current_git_info.commit_hash - | Some s -> s - in - if String.length commit_hash >= 4 then String.sub commit_hash 0 4 - else default_constant - -let is_updated_constant_len = String.length is_updated_constant - -(* add a version to the pow *) -let init_proof_of_work_nonce () = - let buf = - Bytes.make Alpha_context.Constants.proof_of_work_nonce_size '\000' - in - Bytes.blit_string is_updated_constant 0 buf 0 is_updated_constant_len ; - let max_z_len = - Alpha_context.Constants.proof_of_work_nonce_size - is_updated_constant_len - in - let rec aux z = - let z_len = (Z.numbits z + 7) / 8 in - if z_len > max_z_len then Seq.Nil - else ( - Bytes.blit_string (Z.to_bits z) 0 buf is_updated_constant_len z_len ; - Seq.Cons (buf, fun () -> aux (Z.succ z))) - in - aux Z.zero - -(* This was used before November 2018 *) -(* (\* Random proof of work *\) - * let generate_proof_of_work_nonce () = - * Rand.generate Alpha_context.Constants.proof_of_work_nonce_size *) - -let empty_proof_of_work_nonce = - Bytes.make Constants_repr.proof_of_work_nonce_size '\000' - -let mine ~proof_of_work_threshold shell builder = - let rec loop nonce_seq = - match nonce_seq with - | Seq.Nil -> - failwith - "Client_baking_pow.mine: couldn't find nonce for required proof of \ - work" - | Seq.Cons (nonce, seq) -> - let block = builder nonce in - if - Alpha_context.Block_header.Proof_of_work - .check_header_proof_of_work_stamp - shell - block - proof_of_work_threshold - then return block - else loop (seq ()) - in - loop (init_proof_of_work_nonce ()) diff --git a/src/proto_012_Psithaca/lib_delegate/baking_pow.mli b/src/proto_012_Psithaca/lib_delegate/baking_pow.mli deleted file mode 100644 index ad5975c9190c..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_pow.mli +++ /dev/null @@ -1,40 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** A null proof-of-work nonce. This should only be used to nonsensical blocks - of the correct size and shape. *) -val empty_proof_of_work_nonce : Bytes.t - -(** [mine ~proof_of_work_threshold chain block header builder] returns a block with a valid - proof-of-work nonce. The function [builder], provided by the caller, is used - to make the block. All the internal logic of generating nonces and checking - for the proof-of-work threshold is handled by [mine]. *) -val mine : - proof_of_work_threshold:int64 -> - Block_header.shell_header -> - (Bytes.t -> Alpha_context.Block_header.contents) -> - Alpha_context.Block_header.contents tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/baking_scheduling.ml b/src/proto_012_Psithaca/lib_delegate/baking_scheduling.ml deleted file mode 100644 index 07efc9042412..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_scheduling.ml +++ /dev/null @@ -1,787 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol.Alpha_context -module Events = Baking_events.Scheduling -open Baking_state - -type loop_state = { - block_stream : Baking_state.proposal Lwt_stream.t; - qc_stream : Operation_worker.event Lwt_stream.t; - future_block_stream : proposal Lwt_stream.t; - push_future_block : proposal -> unit; - mutable last_get_head_event : Baking_state.proposal option Lwt.t option; - mutable last_future_block_event : Baking_state.proposal Lwt.t option; - mutable last_get_qc_event : Operation_worker.event option Lwt.t option; -} - -let create_loop_state block_stream operation_worker = - let (future_block_stream, push_future_block) = Lwt_stream.create () in - { - block_stream; - qc_stream = Operation_worker.get_quorum_event_stream operation_worker; - future_block_stream; - push_future_block = (fun x -> push_future_block (Some x)); - last_get_head_event = None; - last_future_block_event = None; - last_get_qc_event = None; - } - -let find_in_known_round_intervals known_round_intervals ~predecessor_timestamp - ~predecessor_round ~now = - let open Baking_cache in - Round_timestamp_interval_cache.( - find_opt - known_round_intervals - {predecessor_timestamp; predecessor_round; time_interval = (now, now)}) - -(** Memoization wrapper for [Round.timestamp_of_round]. *) -let timestamp_of_round known_timestamps round_durations ~predecessor_timestamp - ~predecessor_round ~round = - let open Baking_cache in - match - Timestamp_of_round_cache.find_opt - known_timestamps - (predecessor_timestamp, predecessor_round, round) - with - (* Compute and register the timestamp if not already existing. *) - | None -> - Protocol.Alpha_context.Round.timestamp_of_round - round_durations - ~predecessor_timestamp - ~predecessor_round - ~round - >>? fun ts -> - Timestamp_of_round_cache.replace - known_timestamps - (predecessor_timestamp, predecessor_round, round) - ts ; - ok ts - (* If it already exists, just fetch from the memoization table. *) - | Some ts -> ok ts - -(** The function is blocking until it is [time]. *) -let sleep_until time = - (* Sleeping is a system op, baking is a protocol op, this is where we convert *) - let time = Time.System.of_protocol_exn time in - let delay = Ptime.diff time (Tezos_stdlib_unix.Systime_os.now ()) in - if Ptime.Span.compare delay Ptime.Span.zero < 0 then None - else Some (Lwt_unix.sleep (Ptime.Span.to_float_s delay)) - -let rec wait_next_event ~timeout loop_state = - (* TODO? should we prioritize head events/timeouts to resynchronize if needs be ? *) - let get_head_event () = - (* n.b. we should also consume the available elements in the - block_stream before starting baking. *) - match loop_state.last_get_head_event with - | None -> - let t = Lwt_stream.get loop_state.block_stream in - loop_state.last_get_head_event <- Some t ; - t - | Some t -> t - in - let get_future_block_event () = - (* n.b. we should also consume the available elements in the - block_stream before starting baking. *) - match loop_state.last_future_block_event with - | None -> - let t = - Lwt_stream.get loop_state.future_block_stream >>= function - | None -> - (* unreachable, we never close the stream *) - assert false - | Some proposal -> Lwt.return proposal - in - loop_state.last_future_block_event <- Some t ; - t - | Some t -> t - in - let get_qc_event () = - match loop_state.last_get_qc_event with - | None -> - let t = Lwt_stream.get loop_state.qc_stream in - loop_state.last_get_qc_event <- Some t ; - t - | Some t -> t - in - (* event construction *) - let open Baking_state in - Lwt.choose - [ - (Lwt_exit.clean_up_starts >|= fun _ -> `Termination); - (get_head_event () >|= fun e -> `New_proposal e); - (get_future_block_event () >|= fun e -> `New_future_block e); - (get_qc_event () >|= fun e -> `QC_reached e); - (timeout >|= fun e -> `Timeout e); - ] - >>= function - (* event matching *) - | `Termination -> - (* Exit the loop *) - return_none - | `New_proposal None -> - (* Node connection lost *) - loop_state.last_get_head_event <- None ; - fail Baking_errors.Node_connection_lost - | `QC_reached None -> - (* Not supposed to happen: exit the loop *) - loop_state.last_get_qc_event <- None ; - return_none - | `New_proposal (Some proposal) -> ( - loop_state.last_get_head_event <- None ; - (* Is the block in the future? *) - match sleep_until proposal.block.shell.timestamp with - | Some waiter -> - (* If so, wait until its timestamp is reached before advertising it *) - Events.(emit proposal_in_the_future proposal.block.hash) >>= fun () -> - Lwt.dont_wait - (fun () -> - waiter >>= fun () -> - loop_state.push_future_block proposal ; - Lwt.return_unit) - (fun _exn -> ()) ; - wait_next_event ~timeout loop_state - | None -> return_some (New_proposal proposal)) - | `New_future_block proposal -> - Events.(emit process_proposal_in_the_future proposal.block.hash) - >>= fun () -> - loop_state.last_future_block_event <- None ; - return_some (New_proposal proposal) - | `QC_reached - (Some - (Operation_worker.Prequorum_reached - (candidate, voting_power, preendorsement_qc))) -> - loop_state.last_get_qc_event <- None ; - (* TODO: pass the candidate to add a consistency check *) - return_some - (Prequorum_reached (candidate, voting_power, preendorsement_qc)) - | `QC_reached - (Some - (Operation_worker.Quorum_reached - (candidate, voting_power, endorsement_qc))) -> - loop_state.last_get_qc_event <- None ; - (* TODO: pass the candidate to add a consistency check *) - return_some (Quorum_reached (candidate, voting_power, endorsement_qc)) - | `Timeout e -> return_some (Timeout e) - -(** From the current [state], the function returns an optional - association pair, which consists of the next round timestamp and its - round. *) -let compute_next_round_time state = - let open Baking_state in - let proposal = - match state.level_state.endorsable_payload with - | None -> state.level_state.latest_proposal - | Some {proposal; _} -> proposal - in - if Protocol_hash.(proposal.predecessor.next_protocol <> Protocol.hash) then - None - else - match state.level_state.next_level_proposed_round with - | Some _proposed_round -> - (* TODO? do something, if we don't, we won't be able to - repropose a block at next level. *) - None - | None -> ( - let first_round_duration = - state.global_state.constants.parametric.minimal_block_delay - in - let delay_increment_per_round = - state.global_state.constants.parametric.delay_increment_per_round - in - match - Round.Durations.create_opt - ~first_round_duration - ~delay_increment_per_round - with - | Some round_durations -> ( - let predecessor_timestamp = proposal.predecessor.shell.timestamp in - let predecessor_round = proposal.predecessor.round in - let next_round = Round.succ state.round_state.current_round in - match - timestamp_of_round - state.global_state.cache.known_timestamps - round_durations - ~predecessor_timestamp - ~predecessor_round - ~round:next_round - with - | Ok timestamp -> Some (timestamp, next_round) - | _ -> assert false) - | None -> assert false) - -(** [first_potential_round_at_next_level state ~earliest_round] yields - an optional pair of the earliest possible round (at or after - [earliest_round]), along with the delegate having the slot to - propose. - - In particular when the required round value is higher than the - consensus committee size, an Euclidean division allows to - recycle. Then, the earliest round when it exists is extracted. This - is meant to be multiplied back again to find the round value. *) -let first_potential_round_at_next_level state ~earliest_round = - let open Baking_state in - let slots = state.level_state.next_level_delegate_slots.own_delegate_slots in - let rounds = - state.level_state.next_level_delegate_slots.all_slots_by_round - |> Array.to_seqi - |> Seq.fold_left - (fun acc (round, slot) -> - if SlotMap.mem slot slots then (round, slot) :: acc else acc) - [] - |> List.rev - in - match Round.to_int earliest_round with - | Error _ -> None - | Ok earliest_round -> ( - let consensus_committee_size = - state.global_state.constants.parametric.consensus_committee_size - in - let q = earliest_round / consensus_committee_size in - let r = earliest_round mod consensus_committee_size in - let first_round = List.find (fun (round, _) -> round >= r) rounds in - match first_round with - | None -> None - | Some (round, slot) -> ( - SlotMap.find slot slots |> function - | None -> None - | Some (delegate, _) -> ( - (* TODO? check with [Node_rpc.first_proposer_round] if we also need the q+1 *) - match Round.of_int ((q * consensus_committee_size) + round) with - | Error _ -> None - | Ok first_potential_round -> - Some (first_potential_round, delegate)))) - -(** From the current [state], the function returns an optional - association pair, which consists of the next baking timestamp and - its baking round. In that case, an elected block must exist. *) -let compute_next_potential_baking_time_at_next_level state = - let open Protocol.Alpha_context in - let open Baking_state in - match state.level_state.elected_block with - | None -> Lwt.return_none - | Some elected_block -> ( - Events.( - emit - compute_next_timeout_elected_block - ( elected_block.proposal.block.shell.level, - elected_block.proposal.block.round )) - >>= fun () -> - (* Do we have baking rights for the next level ? *) - (* Determine the round for the next level *) - let predecessor_timestamp = - elected_block.proposal.block.shell.timestamp - in - let predecessor_round = elected_block.proposal.block.round in - let now = Systime_os.now () |> Time.System.to_protocol in - (* Lookup the next slot information if already stored in the - memoization table [Round_timestamp_interval_tbl]. *) - match - find_in_known_round_intervals - state.global_state.cache.round_timestamps - ~predecessor_timestamp - ~predecessor_round - ~now - with - | Some (first_potential_baking_time, first_potential_round, delegate) -> ( - (* Check if we already have proposed something at next - level *) - match state.level_state.next_level_proposed_round with - | Some proposed_round - when Round.(proposed_round >= first_potential_round) -> - Events.(emit proposal_already_injected ()) >>= fun () -> - Lwt.return_none - | None | Some _ -> - Events.( - emit - next_potential_slot - ( Int32.succ state.level_state.current_level, - first_potential_round, - first_potential_baking_time, - delegate )) - >>= fun () -> - Lwt.return_some - (first_potential_baking_time, first_potential_round)) - | None -> ( - let round_durations = state.global_state.round_durations in - (* Compute the timestamp at which the new level will start at - round 0.*) - Round.timestamp_of_round - round_durations - ~predecessor_timestamp - ~predecessor_round - ~round:Round.zero - |> function - | Error _ -> Lwt.return_none - | Ok min_possible_time -> ( - (* If this timestamp exists and is not yet outdated, the - earliest round to bake is thereby 0. Otherwise, we - compute the round from the current timestamp. This - possibly means the baker has been late. *) - (if Time.Protocol.(now < min_possible_time) then ok Round.zero - else - Protocol.Environment.wrap_tzresult - @@ Round.round_of_timestamp - round_durations - ~predecessor_timestamp - ~predecessor_round - ~timestamp:now) - |> function - | Error _ -> Lwt.return_none - | Ok earliest_round -> ( - (* There does not necessarily exists a slot that is - equal to [earliest_round]. We must find the earliest - slot after this value for which a validator is - designated to propose. *) - match - first_potential_round_at_next_level state ~earliest_round - with - | None -> Lwt.return_none - | Some (first_potential_round, delegate) -> ( - (* Check if we already have proposed something at next - level. If so, we can skip. Otherwise, we recompute - the timestamp for the - [first_potential_round]. Finally, from this - [first_potential_baking_time], we can return. *) - match state.level_state.next_level_proposed_round with - | Some proposed_round - when Round.(proposed_round >= first_potential_round) -> - Events.(emit proposal_already_injected ()) - >>= fun () -> Lwt.return_none - | None | Some _ -> ( - timestamp_of_round - state.global_state.cache.known_timestamps - round_durations - ~predecessor_timestamp - ~predecessor_round - ~round:first_potential_round - |> function - | Error _ -> Lwt.return_none - | Ok first_potential_baking_time -> - Events.( - emit - next_potential_slot - ( Int32.succ state.level_state.current_level, - first_potential_round, - first_potential_baking_time, - delegate )) - >>= fun () -> - (* memoize this *) - let () = - let this_round_duration = - Round.round_duration - round_durations - first_potential_round - in - let end_first_potential_baking_time = - Timestamp.( - first_potential_baking_time - +? this_round_duration) - |> function - | Ok x -> x - | Error _ -> assert false - in - Baking_cache.( - Round_timestamp_interval_cache.replace - state.global_state.cache.round_timestamps - { - predecessor_timestamp; - predecessor_round; - time_interval = - ( first_potential_baking_time, - end_first_potential_baking_time ); - } - ( first_potential_baking_time, - first_potential_round, - delegate )) - in - Lwt.return_some - ( first_potential_baking_time, - first_potential_round ))))))) - -(** From the current [state], the function returns an Lwt promise that - fulfills once the nearest timeout is expired and at which the state - machine will react. - - Both subfunctions [wait_baking_time] and [wait_end_of_round] are - using the blocking function - [Baking_scheduling.sleep_until]. However, this call is binded into - a Lwt promise. Hence, it just won't get fulfilled until sleep time - has elapsed. Once the promise is fulfilled, - [Baking_scheduling.wait_next_event] handles with [Lwt.choose] to - react and trigger event [Timeout]. *) -let compute_next_timeout state : Baking_state.timeout_kind Lwt.t tzresult Lwt.t - = - (* FIXME: this function (may) try to instantly repropose a block *) - let open Baking_state in - let wait_end_of_round ?(delta = 0L) (next_round_time, next_round) = - let next_time = Time.Protocol.add next_round_time delta in - let now = Systime_os.now () in - let delay = Ptime.diff (Time.System.of_protocol_exn next_time) now in - let current_round = Int32.pred @@ Round.to_int32 next_round in - (if delta = 0L then - Events.(emit waiting_end_of_round (delay, current_round, next_time)) - else - Events.( - emit - waiting_delayed_end_of_round - (delay, current_round, next_time, delta))) - >>= fun () -> - let end_of_round = - Lwt.return - @@ End_of_round {ending_round = state.round_state.current_round} - in - match sleep_until next_time with - | None -> return end_of_round - | Some t -> return (t >>= fun () -> end_of_round) - in - let wait_baking_time_next_level (next_baking_time, next_baking_round) = - let now = Systime_os.now () in - let delay = Ptime.diff (Time.System.of_protocol_exn next_baking_time) now in - Events.(emit waiting_time_to_bake (delay, next_baking_time)) >>= fun () -> - match sleep_until next_baking_time with - | None -> - Events.(emit no_need_to_wait_for_proposal ()) >>= fun () -> - return - (Lwt.return (Time_to_bake_next_level {at_round = next_baking_round})) - | Some t -> - return - ( t >>= fun () -> - Lwt.return (Time_to_bake_next_level {at_round = next_baking_round}) - ) - in - let delay_next_round_timeout next_round = - (* we only delay if it's our turn to bake *) - match - State_transitions.round_proposer - state - state.level_state.delegate_slots.own_delegate_slots - (snd next_round) - with - | Some _ -> - let delta = - state.global_state.constants.parametric.minimal_block_delay - |> Period.to_seconds - |> fun d -> Int64.div d 5L - in - (* NB: this means 6 seconds delay, if the first round duration is - 30. *) - wait_end_of_round ~delta next_round - | None -> wait_end_of_round next_round - in - (* TODO: re-use what has been done in round_synchronizer.ml *) - (* Compute the timestamp of the next possible round. *) - let next_round = compute_next_round_time state in - compute_next_potential_baking_time_at_next_level state >>= fun next_baking -> - match (next_round, next_baking) with - | (None, None) -> - Events.(emit waiting_for_new_head ()) >>= fun () -> - return (Lwt_utils.never_ending () >>= fun () -> assert false) - (* We have no slot at the next level in the near future, we will - patiently wait for the next round. *) - | (Some next_round, None) -> ( - (* If there is an elected block, then we make the assumption - that the bakers at the next level have also received an - endorsement quorum, and we delay a bit injecting at the next - round, so that there are not two blocks injected at the same - time. *) - match state.level_state.elected_block with - | None -> wait_end_of_round next_round - | Some _elected_block -> delay_next_round_timeout next_round) - (* There is no timestamp for a successor round but there is for a - future baking slot, we will wait to bake. *) - | (None, Some next_baking) -> wait_baking_time_next_level next_baking - (* We choose the earliest timestamp between waiting to bake and - waiting for the next round. *) - | ( Some ((next_round_time, next_round) as next_round_info), - Some ((next_baking_time, _) as next_baking) ) -> - (* If we can bake at the next level before the end of the next - round, then do so. This is because the proposed block will have - a smaller timestamp than the earliest block at next level built - on top of the proposal made at the next round (at the current - level). *) - let round_durations = state.global_state.round_durations in - let next_round_duration = - Round.round_duration round_durations next_round |> Period.to_seconds - in - if - Time.Protocol.( - next_baking_time < add next_round_time next_round_duration) - then wait_baking_time_next_level next_baking - else - (* same observation is in the [(Some next_round, None)] case *) - delay_next_round_timeout next_round_info - -(* initialises endorsable_payload with the PQC included in the latest block - if there is one and if it's more recent than the one loaded from disk - if any *) -let may_initialise_with_latest_proposal_pqc state = - let p = state.level_state.latest_proposal in - match p.block.prequorum with - | None -> return state - | Some pqc -> ( - match state.level_state.endorsable_payload with - | Some ep when ep.prequorum.round >= pqc.round -> - (*do not change the endorsable_payload loaded from disk if it's - more recent *) - return state - | Some _ | None -> - return - { - state with - level_state = - { - state.level_state with - endorsable_payload = Some {prequorum = pqc; proposal = p}; - }; - }) - -let create_round_durations constants = - let first_round_duration = - constants.Constants.parametric.minimal_block_delay - in - let delay_increment_per_round = - constants.parametric.delay_increment_per_round - in - Protocol.Environment.wrap_tzresult - (Round.Durations.create ~first_round_duration ~delay_increment_per_round) - -let create_initial_state cctxt ?(synchronize = true) ~chain config - operation_worker ~(current_proposal : Baking_state.proposal) delegates = - (* FIXME? consider saved endorsable value *) - let open Protocol in - let open Baking_state in - Shell_services.Chain.chain_id cctxt ~chain () >>=? fun chain_id -> - Alpha_services.Constants.all cctxt (`Hash chain_id, `Head 0) - >>=? fun constants -> - create_round_durations constants >>?= fun round_durations -> - Baking_state.( - match config.Baking_configuration.validation with - | Node -> return Node - | Local {context_path} -> - Baking_simulator.load_context ~context_path >>=? fun index -> - return (Local index) - | ContextIndex index -> return (Local index)) - >>=? fun validation_mode -> - let cache = Baking_state.create_cache () in - let global_state = - { - cctxt; - chain_id; - config; - constants; - round_durations; - operation_worker; - validation_mode; - delegates; - cache; - } - in - let chain = `Hash chain_id in - let current_level = current_proposal.block.shell.level in - Baking_state.compute_delegate_slots - cctxt - delegates - ~level:current_level - ~chain - >>=? fun delegate_slots -> - Baking_state.compute_delegate_slots - cctxt - delegates - ~level:(Int32.succ current_level) - ~chain - >>=? fun next_level_delegate_slots -> - let elected_block = - if - Protocol_hash.( - current_proposal.block.protocol <> Protocol.hash - && current_proposal.block.next_protocol = Protocol.hash) - then - (* If the last block is a protocol transition, we admit it as a - final block *) - Some {proposal = current_proposal; endorsement_qc = []} - else None - in - let level_state = - { - current_level = current_proposal.block.shell.level; - latest_proposal = current_proposal; - locked_round = None; - endorsable_payload = None; - elected_block; - delegate_slots; - next_level_delegate_slots; - next_level_proposed_round = None; - } - in - (if synchronize then - let round_durations = - Stdlib.Option.get - @@ Round.Durations.create_opt - ~first_round_duration:constants.parametric.minimal_block_delay - ~delay_increment_per_round: - constants.parametric.delay_increment_per_round - in - Baking_actions.compute_round current_proposal round_durations - >>? fun current_round -> ok {current_round; current_phase = Idle} - else ok {Baking_state.current_round = Round.zero; current_phase = Idle}) - >>?= fun round_state -> - let state = {global_state; level_state; round_state} in - (* Try loading locked round and endorsable round from disk *) - Baking_state.may_load_endorsable_data state >>=? fun state -> - may_initialise_with_latest_proposal_pqc state - -let compute_bootstrap_event state = - let open Baking_state in - (* Check if we are in the current round *) - if - Round.( - state.level_state.latest_proposal.block.round - = state.round_state.current_round) - then - (* If so, then trigger the new proposal event to possibly preendorse *) - ok @@ Baking_state.New_proposal state.level_state.latest_proposal - else - (* Otherwise, trigger the end of round to check whether we - need to propose at this level or not *) - Protocol.Environment.wrap_tzresult - @@ Round.pred state.round_state.current_round - >>? fun ending_round -> - ok @@ Baking_state.Timeout (End_of_round {ending_round}) - -let rec automaton_loop ?(stop_on_event = fun _ -> false) ~config ~on_error - loop_state state event = - let state_recorder ~new_state = - match config.Baking_configuration.state_recorder with - | Baking_configuration.Filesystem -> - Baking_state.may_record_new_state ~previous_state:state ~new_state - | Baking_configuration.Disabled -> return_unit - in - State_transitions.step state event >>= fun (state', action) -> - (Baking_actions.perform_action ~state_recorder state' action >>= function - | Ok state'' -> return state'' - | Error error -> - on_error error >>=? fun () -> - (* Still try to record the intermediate state; ignore potential - errors. *) - state_recorder ~new_state:state' >>= fun _ -> return state') - >>=? fun state'' -> - compute_next_timeout state'' >>=? fun next_timeout -> - wait_next_event ~timeout:next_timeout loop_state >>=? function - | None -> - (* Termination *) - return_none - | Some event -> - if stop_on_event event then return_some event - else - automaton_loop ~stop_on_event ~config ~on_error loop_state state'' event - -let perform_sanity_check cctxt ~chain_id = - let open Baking_errors in - let prefix_base_dir f = Filename.Infix.(cctxt#get_base_dir // f) in - let nonces_location = Baking_files.resolve_location ~chain_id `Nonce in - Baking_nonces.load cctxt nonces_location - |> trace - (Cannot_load_local_file - (prefix_base_dir (Baking_files.filename nonces_location) ^ "s")) - >>=? fun _ -> - let highwatermarks_location = - Baking_files.resolve_location ~chain_id `Highwatermarks - in - Baking_highwatermarks.load cctxt highwatermarks_location - |> trace - (Cannot_load_local_file - (prefix_base_dir (Baking_files.filename highwatermarks_location) ^ "s")) - >>=? fun _ -> - let state_location = Baking_files.resolve_location ~chain_id `State in - Baking_state.load_endorsable_data cctxt state_location - |> trace - (Cannot_load_local_file - (prefix_base_dir (Baking_files.filename state_location))) - >>=? fun _ -> return_unit - -let run cctxt ?canceler ?(stop_on_event = fun _ -> false) - ?(on_error = fun _ -> return_unit) ~chain config delegates = - Shell_services.Chain.chain_id cctxt ~chain () >>=? fun chain_id -> - perform_sanity_check cctxt ~chain_id >>=? fun () -> - Node_rpc.monitor_proposals cctxt ~chain () - >>=? fun (block_stream, _block_stream_stopper) -> - (Lwt_stream.get block_stream >>= function - | Some current_head -> return current_head - | None -> failwith "head stream unexpectedly ended") - >>=? fun current_proposal -> - Operation_worker.create cctxt >>= fun operation_worker -> - Option.iter - (fun canceler -> - Lwt_canceler.on_cancel canceler (fun () -> - Operation_worker.shutdown_worker operation_worker >>= fun _ -> - Lwt.return_unit)) - canceler ; - create_initial_state - cctxt - ~chain - config - operation_worker - ~current_proposal - delegates - >>=? fun initial_state -> - let cloned_block_stream = Lwt_stream.clone block_stream in - Baking_nonces.start_revelation_worker - cctxt - initial_state.global_state.config.nonce - initial_state.global_state.chain_id - initial_state.global_state.constants - cloned_block_stream - >>= fun revelation_worker_canceler -> - Option.iter - (fun canceler -> - Lwt_canceler.on_cancel canceler (fun () -> - Lwt_canceler.cancel revelation_worker_canceler >>= fun _ -> - Lwt.return_unit)) - canceler ; - - let loop_state = - create_loop_state block_stream initial_state.global_state.operation_worker - in - let on_error err = - Events.(emit error_while_baking err) >>= fun () -> - (* TODO? retry a bounded number of time *) - (* let retries = config.Baking_configuration.retries_on_failure in *) - on_error err - in - compute_bootstrap_event initial_state >>?= fun initial_event -> - protect - ~on_error:(fun err -> - Option.iter_es Lwt_canceler.cancel canceler >>= fun _ -> - Lwt.return_error err) - (fun () -> - automaton_loop - ~stop_on_event - ~config - ~on_error - loop_state - initial_state - initial_event - >>=? fun _ignored_event -> return_unit) diff --git a/src/proto_012_Psithaca/lib_delegate/baking_scheduling.mli b/src/proto_012_Psithaca/lib_delegate/baking_scheduling.mli deleted file mode 100644 index b42fbda8b20c..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_scheduling.mli +++ /dev/null @@ -1,83 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Baking_state -open Protocol.Alpha_context - -type loop_state - -val create_loop_state : - proposal Lwt_stream.t -> Operation_worker.t -> loop_state - -val sleep_until : Time.Protocol.t -> unit Lwt.t option - -(** An event monitor using the streams in [loop_state] (to create - promises) and a timeout promise [timeout]. The function reacts to a - promise being fulfilled by firing an event [Baking_state.event]. *) -val wait_next_event : - timeout:timeout_kind Lwt.t -> - loop_state -> - (event option, error trace) result Lwt.t - -val compute_next_round_time : state -> (Time.Protocol.t * Round.t) option - -val first_potential_round_at_next_level : - state -> earliest_round:Round.t -> (Round.t * delegate) option - -val compute_next_potential_baking_time_at_next_level : - state -> (Time.Protocol.t * Round.t) option Lwt.t - -val compute_next_timeout : state -> timeout_kind Lwt.t tzresult Lwt.t - -val create_initial_state : - Protocol_client_context.full -> - ?synchronize:bool -> - chain:Chain_services.chain -> - Baking_configuration.t -> - Operation_worker.t -> - current_proposal:proposal -> - delegate trace -> - state tzresult Lwt.t - -val compute_bootstrap_event : state -> event tzresult - -val automaton_loop : - ?stop_on_event:(event -> bool) -> - config:Baking_configuration.t -> - on_error:(tztrace -> (unit, tztrace) result Lwt.t) -> - loop_state -> - state -> - event -> - event option tzresult Lwt.t - -val run : - Protocol_client_context.full -> - ?canceler:Lwt_canceler.t -> - ?stop_on_event:(event -> bool) -> - ?on_error:(tztrace -> unit tzresult Lwt.t) -> - chain:Chain_services.chain -> - Baking_configuration.t -> - delegate trace -> - unit tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/baking_simulator.ml b/src/proto_012_Psithaca/lib_delegate/baking_simulator.ml deleted file mode 100644 index 8188f673c123..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_simulator.ml +++ /dev/null @@ -1,120 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol_client_context -open Protocol -open Alpha_context - -type error += Failed_to_checkout_context - -type error += Invalid_context - -let wrap_error_lwt x = x >>= fun x -> Lwt.return @@ Environment.wrap_tzresult x - -let ( >>=?? ) x k = wrap_error_lwt x >>=? k - -let () = - register_error_kind - `Permanent - ~id:"Client_baking_simulator.failed_to_checkout_context" - ~title:"Failed to checkout context" - ~description:"The given context hash does not exists in the context." - ~pp:(fun ppf () -> Format.fprintf ppf "Failed to checkout the context") - Data_encoding.unit - (function Failed_to_checkout_context -> Some () | _ -> None) - (fun () -> Failed_to_checkout_context) ; - register_error_kind - `Permanent - ~id:"Client_baking_simulator.invalid_context" - ~title:"Invalid context" - ~description:"Occurs when the context is inconsistent." - ~pp:(fun ppf () -> Format.fprintf ppf "The given context is invalid.") - Data_encoding.unit - (function Invalid_context -> Some () | _ -> None) - (fun () -> Invalid_context) - -type incremental = { - predecessor : Baking_state.block_info; - context : Tezos_protocol_environment.Context.t; - state : Protocol.validation_state; - rev_operations : Operation.packed list; - header : Tezos_base.Block_header.shell_header; -} - -let load_context ~context_path = - protect (fun () -> - Context.init ~readonly:true context_path >>= fun index -> - return (Abstract_context_index.abstract index)) - -let check_context_consistency (abstract_index : Abstract_context_index.t) - context_hash = - (* Hypothesis : the version key exists *) - let version_key = ["version"] in - abstract_index.checkout_fun context_hash >>= function - | None -> fail Failed_to_checkout_context - | Some context -> ( - Context_ops.mem context version_key >>= function - | true -> return_unit - | false -> fail Invalid_context) - -let begin_construction ~timestamp ?protocol_data - (abstract_index : Abstract_context_index.t) predecessor chain_id = - let {Baking_state.shell = pred_shell; hash = pred_hash; _} = predecessor in - abstract_index.checkout_fun pred_shell.context >>= function - | None -> fail Failed_to_checkout_context - | Some context -> - let header : Tezos_base.Block_header.shell_header = - Tezos_base.Block_header. - { - predecessor = pred_hash; - proto_level = pred_shell.proto_level; - validation_passes = 0; - fitness = pred_shell.fitness; - timestamp; - level = pred_shell.level; - context = Context_hash.zero (* fake context hash *); - operations_hash = Operation_list_list_hash.zero (* fake op hash *); - } - in - Lifted_protocol.begin_construction - ~chain_id - ~predecessor_context:context - ~predecessor_timestamp:pred_shell.timestamp - ~predecessor_fitness:pred_shell.fitness - ~predecessor_level:pred_shell.level - ~predecessor:pred_hash - ?protocol_data - ~timestamp - ~cache:`Lazy - () - >>=? fun state -> - return {predecessor; context; state; rev_operations = []; header} - -let add_operation st (op : Operation.packed) = - Protocol.apply_operation st.state op >>=?? fun (state, receipt) -> - return ({st with state; rev_operations = op :: st.rev_operations}, receipt) - -let finalize_construction inc = - Protocol.finalize_block inc.state (Some inc.header) >>=?? return diff --git a/src/proto_012_Psithaca/lib_delegate/baking_simulator.mli b/src/proto_012_Psithaca/lib_delegate/baking_simulator.mli deleted file mode 100644 index 582fbd3e2922..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_simulator.mli +++ /dev/null @@ -1,61 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type incremental = { - predecessor : Baking_state.block_info; - context : Tezos_protocol_environment.Context.t; - state : validation_state; - rev_operations : Operation.packed list; - header : Tezos_base.Block_header.shell_header; -} - -val load_context : - context_path:string -> Abstract_context_index.t tzresult Lwt.t - -(** Make sure that the given context is consistent by trying to read in it *) -val check_context_consistency : - Abstract_context_index.t -> Context_hash.t -> unit tzresult Lwt.t - -val begin_construction : - timestamp:Time.Protocol.t -> - ?protocol_data:block_header_data -> - Abstract_context_index.t -> - Baking_state.block_info -> - Chain_id.t -> - incremental tzresult Lwt.t - -val add_operation : - incremental -> - Operation.packed -> - (incremental * operation_receipt) tzresult Lwt.t - -val finalize_construction : - incremental -> - (Tezos_protocol_environment.validation_result * block_header_metadata) - tzresult - Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/baking_state.ml b/src/proto_012_Psithaca/lib_delegate/baking_state.ml deleted file mode 100644 index 88a7f80e5b0b..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_state.ml +++ /dev/null @@ -1,847 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -(** A delegate (aka, a validator) is identified by its alias name, its - public key, its public key hash, and its secret key. *) -type delegate = { - alias : string option; - public_key : Signature.Public_key.t; - public_key_hash : Signature.Public_key_hash.t; - secret_key_uri : Client_keys.sk_uri; -} - -let delegate_encoding = - let open Data_encoding in - conv - (fun {alias; public_key; public_key_hash; secret_key_uri} -> - ( alias, - public_key, - public_key_hash, - Uri.to_string (secret_key_uri :> Uri.t) )) - (fun (alias, public_key, public_key_hash, secret_key_uri) -> - { - alias; - public_key; - public_key_hash; - secret_key_uri = - (match Client_keys.make_sk_uri (Uri.of_string secret_key_uri) with - | Ok sk -> sk - | Error e -> Format.kasprintf Stdlib.failwith "%a" pp_print_trace e); - }) - (obj4 - (req "alias" (option string)) - (req "public_key" Signature.Public_key.encoding) - (req "public_key_hash" Signature.Public_key_hash.encoding) - (req "secret_key_uri" string)) - -let pp_delegate fmt {alias; public_key_hash; _} = - match alias with - | None -> Format.fprintf fmt "%a" Signature.Public_key_hash.pp public_key_hash - | Some alias -> - Format.fprintf - fmt - "%s (%a)" - alias - Signature.Public_key_hash.pp - public_key_hash - -type validation_mode = Node | Local of Abstract_context_index.t - -type prequorum = { - level : int32; - round : Round.t; - block_payload_hash : Block_payload_hash.t; - preendorsements : Kind.preendorsement operation list; -} - -type block_info = { - hash : Block_hash.t; - shell : Block_header.shell_header; - payload_hash : Block_payload_hash.t; - payload_round : Round.t; - round : Round.t; - protocol : Protocol_hash.t; - next_protocol : Protocol_hash.t; - prequorum : prequorum option; - quorum : Kind.endorsement operation list; - payload : Operation_pool.payload; - live_blocks : Block_hash.Set.t; -} - -type cache = { - known_timestamps : Timestamp.time Baking_cache.Timestamp_of_round_cache.t; - round_timestamps : - (Timestamp.time * Round.t * delegate) - Baking_cache.Round_timestamp_interval_cache.t; -} - -type global_state = { - (* client context *) - cctxt : Protocol_client_context.full; - (* chain id *) - chain_id : Chain_id.t; - (* baker configuration *) - config : Baking_configuration.t; - (* protocol constants *) - constants : Constants.t; - (* round durations *) - round_durations : Round.round_durations; - (* worker that monitor and aggregates new operations *) - operation_worker : Operation_worker.t; - (* the validation mode used by the baker*) - validation_mode : validation_mode; - (* the delegates on behalf of which the baker is running *) - delegates : delegate list; - cache : cache; -} - -let prequorum_encoding = - let open Data_encoding in - conv - (fun {level; round; block_payload_hash; preendorsements} -> - (level, round, block_payload_hash, List.map Operation.pack preendorsements)) - (fun (level, round, block_payload_hash, preendorsements) -> - { - level; - round; - block_payload_hash; - preendorsements = - List.filter_map Operation_pool.unpack_preendorsement preendorsements; - }) - (obj4 - (req "level" int32) - (req "round" Round.encoding) - (req "block_payload_hash" Block_payload_hash.encoding) - (req "preendorsements" (list (dynamic_size Operation.encoding)))) - -let block_info_encoding = - let open Data_encoding in - conv - (fun { - hash; - shell; - payload_hash; - payload_round; - round; - protocol; - next_protocol; - prequorum; - quorum; - payload; - live_blocks; - } -> - ( ( hash, - shell, - payload_hash, - payload_round, - round, - protocol, - next_protocol, - prequorum, - List.map Operation.pack quorum, - payload ), - live_blocks )) - (fun ( ( hash, - shell, - payload_hash, - payload_round, - round, - protocol, - next_protocol, - prequorum, - quorum, - payload ), - live_blocks ) -> - { - hash; - shell; - payload_hash; - payload_round; - round; - protocol; - next_protocol; - prequorum; - quorum = List.filter_map Operation_pool.unpack_endorsement quorum; - payload; - live_blocks; - }) - (merge_objs - (obj10 - (req "hash" Block_hash.encoding) - (req "shell" Block_header.shell_header_encoding) - (req "payload_hash" Block_payload_hash.encoding) - (req "payload_round" Round.encoding) - (req "round" Round.encoding) - (req "protocol" Protocol_hash.encoding) - (req "next_protocol" Protocol_hash.encoding) - (req "prequorum" (option prequorum_encoding)) - (req "quorum" (list (dynamic_size Operation.encoding))) - (req "payload" Operation_pool.payload_encoding)) - (obj1 (req "live_blocks" Block_hash.Set.encoding))) - -let round_of_shell_header shell_header = - Environment.wrap_tzresult - @@ Fitness.from_raw shell_header.Tezos_base.Block_header.fitness - >>? fun fitness -> ok (Fitness.round fitness) - -module SlotMap : Map.S with type key = Slot.t = Map.Make (Slot) - -(** An endorsing slot consists of the public key hash of a delegate, a - list of slots (i.e., a list of position indexes in the slot map, in - other words the list of rounds when it will be the proposer), and - its endorsing power. *) -type endorsing_slot = { - delegate : Signature.Public_key_hash.t; - slots : Slot.t list; - endorsing_power : int; -} - -(* FIXME: determine if the slot map should contain all slots or just - the first one *) -(* We also use the delegate slots as proposal slots *) -(* TODO: make sure that this is correct *) -type delegate_slots = { - (* be careful not to duplicate endorsing slots with different slots - keys: always use the first slot in the slots list *) - own_delegate_slots : (delegate * endorsing_slot) SlotMap.t; - all_delegate_slots : endorsing_slot SlotMap.t; - all_slots_by_round : Slot.t array; -} - -type proposal = {block : block_info; predecessor : block_info} - -let proposal_encoding = - let open Data_encoding in - conv - (fun {block; predecessor} -> (block, predecessor)) - (fun (block, predecessor) -> {block; predecessor}) - (obj2 - (req "block" block_info_encoding) - (req "predecessor" block_info_encoding)) - -type locked_round = {payload_hash : Block_payload_hash.t; round : Round.t} - -let locked_round_encoding = - let open Data_encoding in - conv - (fun {payload_hash; round} -> (payload_hash, round)) - (fun (payload_hash, round) -> {payload_hash; round}) - (obj2 - (req "payload_hash" Block_payload_hash.encoding) - (req "round" Round.encoding)) - -type endorsable_payload = {proposal : proposal; prequorum : prequorum} - -let endorsable_payload_encoding = - let open Data_encoding in - conv - (fun {proposal; prequorum} -> (proposal, prequorum)) - (fun (proposal, prequorum) -> {proposal; prequorum}) - (obj2 - (req "proposal" proposal_encoding) - (req "prequorum" prequorum_encoding)) - -type elected_block = { - proposal : proposal; - endorsement_qc : Kind.endorsement Operation.t list; -} - -(* Updated only when we receive a block at a different level. - - N.B. it may be our own: implying that we should not update unless - we already baked a block *) -type level_state = { - current_level : int32; - latest_proposal : proposal; - (* Last proposal received where we injected an endorsement (thus we - have seen 2f+1 preendorsements) *) - locked_round : locked_round option; - (* Latest payload where we've seen a proposal reach 2f+1 preendorsements *) - endorsable_payload : endorsable_payload option; - (* Block for which we've seen 2f+1 endorsements and that we may bake onto *) - elected_block : elected_block option; - delegate_slots : delegate_slots; - next_level_delegate_slots : delegate_slots; - next_level_proposed_round : Round.t option; -} - -type phase = Idle | Awaiting_preendorsements | Awaiting_endorsements - -let phase_encoding = - let open Data_encoding in - union - ~tag_size:`Uint8 - [ - case - ~title:"Idle" - (Tag 0) - unit - (function Idle -> Some () | _ -> None) - (fun () -> Idle); - case - ~title:"Awaiting_preendorsements" - (Tag 1) - unit - (function Awaiting_preendorsements -> Some () | _ -> None) - (fun () -> Awaiting_preendorsements); - case - ~title:"Awaiting_endorsements" - (Tag 2) - unit - (function Awaiting_endorsements -> Some () | _ -> None) - (fun () -> Awaiting_endorsements); - ] - -type round_state = {current_round : Round.t; current_phase : phase} - -type state = { - global_state : global_state; - level_state : level_state; - round_state : round_state; -} - -type t = state - -type timeout_kind = - | End_of_round of {ending_round : Round.t} - | Time_to_bake_next_level of {at_round : Round.t} - -let timeout_kind_encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"End_of_round" - Round.encoding - (function - | End_of_round {ending_round} -> Some ending_round | _ -> None) - (fun ending_round -> End_of_round {ending_round}); - case - (Tag 1) - ~title:"Time_to_bake_next_level" - Round.encoding - (function - | Time_to_bake_next_level {at_round} -> Some at_round | _ -> None) - (fun at_round -> Time_to_bake_next_level {at_round}); - ] - -type voting_power = int - -type event = - | New_proposal of proposal - | Prequorum_reached of - Operation_worker.candidate - * voting_power - * Kind.preendorsement operation list - | Quorum_reached of - Operation_worker.candidate - * voting_power - * Kind.endorsement operation list - | Timeout of timeout_kind - -let event_encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"New_proposal" - proposal_encoding - (function New_proposal p -> Some p | _ -> None) - (fun p -> New_proposal p); - case - (Tag 1) - ~title:"Prequorum_reached" - (tup3 - Operation_worker.candidate_encoding - Data_encoding.int31 - (Data_encoding.list (dynamic_size Operation.encoding))) - (function - | Prequorum_reached (candidate, voting_power, ops) -> - Some (candidate, voting_power, List.map Operation.pack ops) - | _ -> None) - (fun (candidate, voting_power, ops) -> - Prequorum_reached - (candidate, voting_power, Operation_pool.filter_preendorsements ops)); - case - (Tag 2) - ~title:"Quorum_reached" - (tup3 - Operation_worker.candidate_encoding - Data_encoding.int31 - (Data_encoding.list (dynamic_size Operation.encoding))) - (function - | Quorum_reached (candidate, voting_power, ops) -> - Some (candidate, voting_power, List.map Operation.pack ops) - | _ -> None) - (fun (candidate, voting_power, ops) -> - Quorum_reached - (candidate, voting_power, Operation_pool.filter_endorsements ops)); - case - (Tag 3) - ~title:"Timeout" - timeout_kind_encoding - (function Timeout tk -> Some tk | _ -> None) - (fun tk -> Timeout tk); - ] - -(* Disk state *) - -type state_data = { - level_data : int32; - locked_round_data : locked_round option; - endorsable_payload_data : endorsable_payload option; -} - -let state_data_encoding = - let open Data_encoding in - conv - (fun {level_data; locked_round_data; endorsable_payload_data} -> - (level_data, locked_round_data, endorsable_payload_data)) - (fun (level_data, locked_round_data, endorsable_payload_data) -> - {level_data; locked_round_data; endorsable_payload_data}) - (obj3 - (req "level" int32) - (req "locked_round" (option locked_round_encoding)) - (req "endorsable_payload" (option endorsable_payload_encoding))) - -let record_state (state : state) = - let cctxt = state.global_state.cctxt in - let location = - Baking_files.resolve_location ~chain_id:state.global_state.chain_id `State - in - let filename = - Filename.Infix.(cctxt#get_base_dir // Baking_files.filename location) - in - protect @@ fun () -> - cctxt#with_lock @@ fun () -> - let level_data = state.level_state.current_level in - let locked_round_data = state.level_state.locked_round in - let endorsable_payload_data = state.level_state.endorsable_payload in - let bytes = - Data_encoding.Binary.to_bytes_exn - state_data_encoding - {level_data; locked_round_data; endorsable_payload_data} - in - let filename_tmp = filename ^ "_tmp" in - Lwt_io.with_file - ~flags:[Unix.O_CREAT; O_WRONLY; O_TRUNC; O_CLOEXEC; O_SYNC] - ~mode:Output - filename_tmp - (fun channel -> - Lwt_io.write_from_exactly channel bytes 0 (Bytes.length bytes)) - >>= fun () -> - Lwt_unix.rename filename_tmp filename >>= fun () -> return_unit - -let may_record_new_state ~previous_state ~new_state = - let { - current_level = previous_current_level; - locked_round = previous_locked_round; - endorsable_payload = previous_endorsable_payload; - _; - } = - previous_state.level_state - in - let { - current_level = new_current_level; - locked_round = new_locked_round; - endorsable_payload = new_endorsable_payload; - _; - } = - new_state.level_state - in - let is_new_state_consistent = - Compare.Int32.(new_current_level > previous_current_level) - || new_current_level = previous_current_level - && - if Compare.Int32.(new_current_level = previous_current_level) then - let is_new_locked_round_consistent = - match (new_locked_round, previous_locked_round) with - | (None, None) -> true - | (Some _, None) -> true - | (None, Some _) -> false - | (Some new_locked_round, Some previous_locked_round) -> - Round.(new_locked_round.round >= previous_locked_round.round) - in - let is_new_endorsable_payload_consistent = - match (new_endorsable_payload, previous_endorsable_payload) with - | (None, None) -> true - | (Some _, None) -> true - | (None, Some _) -> false - | (Some new_endorsable_payload, Some previous_endorsable_payload) -> - Round.( - new_endorsable_payload.proposal.block.round - >= previous_endorsable_payload.proposal.block.round) - in - is_new_locked_round_consistent && is_new_endorsable_payload_consistent - else true - in - (* TODO: proper error *) - fail_unless - is_new_state_consistent - (Exn (Failure "locked values invariant does not hold")) - >>=? fun () -> - let has_not_changed = - previous_state.level_state.current_level - == new_state.level_state.current_level - && previous_state.level_state.locked_round - == new_state.level_state.locked_round - && previous_state.level_state.endorsable_payload - == new_state.level_state.endorsable_payload - in - if has_not_changed then return_unit else record_state new_state - -let load_endorsable_data cctxt location = - protect (fun () -> - let filename = - Filename.Infix.(cctxt#get_base_dir // Baking_files.filename location) - in - Lwt_unix.file_exists filename >>= function - | false -> return_none - | true -> - Lwt_io.with_file - ~flags:[Unix.O_EXCL; O_RDONLY; O_CLOEXEC] - ~mode:Input - filename - (fun channel -> - Lwt_io.read channel >>= fun bytes -> - Lwt.return - (Data_encoding.Binary.of_bytes_exn - state_data_encoding - (Bytes.unsafe_of_string bytes))) - >>= return_some) - -let may_load_endorsable_data state = - let cctxt = state.global_state.cctxt in - let chain_id = state.global_state.chain_id in - let location = Baking_files.resolve_location ~chain_id `State in - protect ~on_error:(fun _ -> return state) @@ fun () -> - cctxt#with_lock @@ fun () -> - load_endorsable_data cctxt location >>=? function - | None -> return state - | Some {level_data; locked_round_data; endorsable_payload_data} -> - if Compare.Int32.(state.level_state.current_level = level_data) then - let loaded_level_state = - { - state.level_state with - locked_round = locked_round_data; - endorsable_payload = endorsable_payload_data; - } - in - return {state with level_state = loaded_level_state} - else return state - -(* Helpers *) - -module DelegateSet = struct - include Set.Make (struct - type t = delegate - - let compare {public_key_hash = pkh; _} {public_key_hash = pkh'; _} = - Signature.Public_key_hash.compare pkh pkh' - end) - - let find_pkh pkh s = - let exception Found of elt in - try - iter - (fun ({public_key_hash; _} as delegate) -> - if Signature.Public_key_hash.equal pkh public_key_hash then - raise (Found delegate) - else ()) - s ; - None - with Found d -> Some d -end - -let cache_size_limit = 100 - -let compute_delegate_slots (cctxt : Protocol_client_context.full) delegates - ~level ~chain = - let own_delegates = DelegateSet.of_list delegates in - Environment.wrap_tzresult (Raw_level.of_int32 level) >>?= fun level -> - (* FIXME? should we not take `Head 0 ? *) - Plugin.RPC.Validators.get cctxt (chain, `Head 0) ~levels:[level] - >>=? fun endorsing_rights -> - let (own_delegate_slots, all_delegate_slots) = - List.fold_left - (fun (own_map, all_map) slot -> - let {Plugin.RPC.Validators.delegate; slots; _} = slot in - let endorsing_slot = - {endorsing_power = List.length slots; delegate; slots} - in - let all_map = - List.fold_left - (fun all_map slot -> SlotMap.add slot endorsing_slot all_map) - all_map - slots - in - let own_map = - match DelegateSet.find_pkh delegate own_delegates with - | Some delegate -> - List.fold_left - (fun own_map slot -> - SlotMap.add slot (delegate, endorsing_slot) own_map) - own_map - slots - | None -> own_map - in - (own_map, all_map)) - (SlotMap.empty, SlotMap.empty) - endorsing_rights - in - let all_slots_by_round = - all_delegate_slots |> SlotMap.bindings |> List.split |> fst |> Array.of_list - in - return {own_delegate_slots; all_delegate_slots; all_slots_by_round} - -let create_cache () = - let open Baking_cache in - { - known_timestamps = Timestamp_of_round_cache.create cache_size_limit; - round_timestamps = Round_timestamp_interval_cache.create cache_size_limit; - } - -(* Pretty-printers *) - -let pp_validation_mode fmt = function - | Node -> Format.fprintf fmt "node" - | Local _ -> Format.fprintf fmt "local" - -let pp_global_state fmt {chain_id; config; validation_mode; delegates; _} = - Format.fprintf - fmt - "@[Global state:@ chain_id: %a@ @[config:@ %a@]@ \ - validation_mode: %a@ @[delegates:@ %a@]@]" - Chain_id.pp - chain_id - Baking_configuration.pp - config - pp_validation_mode - validation_mode - Format.(pp_print_list pp_delegate) - delegates - -let pp_option pp fmt = function - | None -> Format.fprintf fmt "none" - | Some v -> Format.fprintf fmt "%a" pp v - -let pp_prequorum fmt {level; round; block_payload_hash; preendorsements} = - Format.fprintf - fmt - "level: %ld, round: %a, payload_hash: %a, preendorsements: %d" - level - Round.pp - round - Block_payload_hash.pp_short - block_payload_hash - (List.length preendorsements) - -let pp_block_info fmt - { - hash; - shell; - payload_hash; - round; - protocol; - next_protocol; - prequorum; - quorum; - payload; - _; - } = - Format.fprintf - fmt - "@[Block:@ hash: %a@ payload_hash: %a@ level: %ld@ round: %a@ \ - protocol: %a@ next protocol: %a@ prequorum: %a@ quorum: %d endorsements@ \ - payload: %a@]" - Block_hash.pp - hash - Block_payload_hash.pp_short - payload_hash - shell.level - Round.pp - round - Protocol_hash.pp_short - protocol - Protocol_hash.pp_short - next_protocol - (pp_option pp_prequorum) - prequorum - (List.length quorum) - Operation_pool.pp_payload - payload - -let pp_proposal fmt {block; _} = pp_block_info fmt block - -let pp_locked_round fmt ({payload_hash; round} : locked_round) = - Format.fprintf - fmt - "payload hash: %a, round: %a" - Block_payload_hash.pp_short - payload_hash - Round.pp - round - -let pp_endorsable_payload fmt {proposal; prequorum} = - Format.fprintf - fmt - "proposal: %a, prequorum: %a" - Block_hash.pp - proposal.block.hash - pp_prequorum - prequorum - -let pp_elected_block fmt {proposal; endorsement_qc} = - Format.fprintf - fmt - "@[%a@ nb quorum endorsements: %d@]" - pp_block_info - proposal.block - (List.length endorsement_qc) - -let pp_endorsing_slot fmt (delegate, {delegate = _; slots; endorsing_power}) = - Format.fprintf - fmt - "slots: @[[%a]@],@ delegate: %a,@ endorsing_power: %d" - Format.(pp_print_list ~pp_sep:pp_print_space Slot.pp) - slots - pp_delegate - delegate - endorsing_power - -let pp_delegate_slots fmt {own_delegate_slots; _} = - Format.fprintf - fmt - "@[%a@]" - Format.( - pp_print_list ~pp_sep:pp_print_cut (fun fmt (slot, endorsing_slot) -> - Format.fprintf - fmt - "slot: %a, %a" - Slot.pp - slot - pp_endorsing_slot - endorsing_slot)) - (SlotMap.bindings own_delegate_slots) - -let pp_level_state fmt - { - current_level; - latest_proposal; - locked_round; - endorsable_payload; - elected_block; - delegate_slots; - next_level_delegate_slots; - next_level_proposed_round; - } = - Format.fprintf - fmt - "@[Level state:@ current level: %ld@ @[proposal:@ %a@]@ locked \ - round: %a@ endorsable payload: %a@ elected block: %a@ @[own delegate \ - slots:@ %a@]@ @[next level own delegate slots:@ %a@]@ next level \ - proposed round: %a@]" - current_level - pp_proposal - latest_proposal - (pp_option pp_locked_round) - locked_round - (pp_option pp_endorsable_payload) - endorsable_payload - (pp_option pp_elected_block) - elected_block - pp_delegate_slots - delegate_slots - pp_delegate_slots - next_level_delegate_slots - (pp_option Round.pp) - next_level_proposed_round - -let pp_phase fmt = function - | Idle -> Format.fprintf fmt "idle" - | Awaiting_preendorsements -> Format.fprintf fmt "awaiting preendorsements" - | Awaiting_endorsements -> Format.fprintf fmt "awaiting endorsements" - -let pp_round_state fmt {current_round; current_phase} = - Format.fprintf - fmt - "@[Round state:@ round: %a@ phase: %a@]" - Round.pp - current_round - pp_phase - current_phase - -let pp fmt {global_state; level_state; round_state} = - Format.fprintf - fmt - "@[State:@ %a@ %a@ %a@]" - pp_global_state - global_state - pp_level_state - level_state - pp_round_state - round_state - -let pp_timeout_kind fmt = function - | End_of_round {ending_round} -> - Format.fprintf fmt "end of round %a" Round.pp ending_round - | Time_to_bake_next_level {at_round} -> - Format.fprintf fmt "time to bake next level at round %a" Round.pp at_round - -let pp_event fmt = function - | New_proposal proposal -> - Format.fprintf - fmt - "new proposal received: %a" - pp_block_info - proposal.block - | Prequorum_reached (candidate, voting_power, preendos) -> - Format.fprintf - fmt - "pre-quorum reached with %d preendorsements (power: %d) for %a at \ - round %a" - (List.length preendos) - voting_power - Block_hash.pp - candidate.Operation_worker.hash - Round.pp - candidate.round_watched - | Quorum_reached (candidate, voting_power, endos) -> - Format.fprintf - fmt - "quorum reached with %d endorsements (power: %d) for %a at round %a" - (List.length endos) - voting_power - Block_hash.pp - candidate.Operation_worker.hash - Round.pp - candidate.round_watched - | Timeout kind -> - Format.fprintf fmt "timeout reached: %a" pp_timeout_kind kind diff --git a/src/proto_012_Psithaca/lib_delegate/baking_state.mli b/src/proto_012_Psithaca/lib_delegate/baking_state.mli deleted file mode 100644 index d745b67eabcc..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/baking_state.mli +++ /dev/null @@ -1,226 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type delegate = { - alias : string option; - public_key : Signature.public_key; - public_key_hash : Signature.public_key_hash; - secret_key_uri : Client_keys.sk_uri; -} - -val delegate_encoding : delegate Data_encoding.t - -val pp_delegate : Format.formatter -> delegate -> unit - -type validation_mode = Node | Local of Abstract_context_index.t - -type prequorum = { - level : int32; - round : Round.t; - block_payload_hash : Block_payload_hash.t; - preendorsements : Kind.preendorsement operation list; -} - -type block_info = { - hash : Block_hash.t; - shell : Block_header.shell_header; - payload_hash : Block_payload_hash.t; - payload_round : Round.t; - round : Round.t; - protocol : Protocol_hash.t; - next_protocol : Protocol_hash.t; - prequorum : prequorum option; - quorum : Kind.endorsement operation list; - payload : Operation_pool.payload; - live_blocks : Block_hash.Set.t; - (** Set of live blocks for this block that is used to filter - old or too recent operations. *) -} - -type cache = { - known_timestamps : Timestamp.time Baking_cache.Timestamp_of_round_cache.t; - round_timestamps : - (Timestamp.time * Round.t * delegate) - Baking_cache.Round_timestamp_interval_cache.t; -} - -type global_state = { - cctxt : Protocol_client_context.full; - chain_id : Chain_id.t; - config : Baking_configuration.t; - constants : Constants.t; - round_durations : Round.round_durations; - operation_worker : Operation_worker.t; - validation_mode : validation_mode; - delegates : delegate list; - cache : cache; -} - -val block_info_encoding : block_info Data_encoding.t - -val round_of_shell_header : Block_header.shell_header -> Round.t tzresult - -module SlotMap : Map.S with type key = Slot.t - -type endorsing_slot = { - delegate : Signature.public_key_hash; - slots : Slot.t trace; - endorsing_power : int; -} - -type delegate_slots = { - own_delegate_slots : (delegate * endorsing_slot) SlotMap.t; - all_delegate_slots : endorsing_slot SlotMap.t; - all_slots_by_round : Slot.t array; -} - -type proposal = {block : block_info; predecessor : block_info} - -val proposal_encoding : proposal Data_encoding.t - -type locked_round = {payload_hash : Block_payload_hash.t; round : Round.t} - -val locked_round_encoding : locked_round Data_encoding.t - -type endorsable_payload = {proposal : proposal; prequorum : prequorum} - -val endorsable_payload_encoding : endorsable_payload Data_encoding.t - -type elected_block = { - proposal : proposal; - endorsement_qc : Kind.endorsement operation list; -} - -type level_state = { - current_level : int32; - latest_proposal : proposal; - locked_round : locked_round option; - endorsable_payload : endorsable_payload option; - elected_block : elected_block option; - delegate_slots : delegate_slots; - next_level_delegate_slots : delegate_slots; - next_level_proposed_round : Round.t option; -} - -type phase = Idle | Awaiting_preendorsements | Awaiting_endorsements - -val phase_encoding : phase Data_encoding.t - -type round_state = {current_round : Round.t; current_phase : phase} - -type state = { - global_state : global_state; - level_state : level_state; - round_state : round_state; -} - -type t = state - -type timeout_kind = - | End_of_round of {ending_round : Round.t} - | Time_to_bake_next_level of {at_round : Round.t} - -val timeout_kind_encoding : timeout_kind Data_encoding.t - -type voting_power = int - -type event = - | New_proposal of proposal - | Prequorum_reached of - Operation_worker.candidate - * voting_power - * Kind.preendorsement operation list - | Quorum_reached of - Operation_worker.candidate - * voting_power - * Kind.endorsement operation list - | Timeout of timeout_kind - -val event_encoding : event Data_encoding.t - -type state_data = { - level_data : int32; - locked_round_data : locked_round option; - endorsable_payload_data : endorsable_payload option; -} - -val state_data_encoding : state_data Data_encoding.t - -val record_state : t -> unit tzresult Lwt.t - -val may_record_new_state : - previous_state:t -> new_state:t -> unit tzresult Lwt.t - -val load_endorsable_data : - Protocol_client_context.full -> - [`State] Baking_files.location -> - state_data option tzresult Lwt.t - -val may_load_endorsable_data : t -> t tzresult Lwt.t - -val compute_delegate_slots : - Protocol_client_context.full -> - delegate trace -> - level:int32 -> - chain:Shell_services.chain -> - delegate_slots tzresult Lwt.t - -val create_cache : unit -> cache - -val pp_validation_mode : Format.formatter -> validation_mode -> unit - -val pp_global_state : Format.formatter -> global_state -> unit - -val pp_option : - (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a option -> unit - -val pp_block_info : Format.formatter -> block_info -> unit - -val pp_proposal : Format.formatter -> proposal -> unit - -val pp_locked_round : Format.formatter -> locked_round -> unit - -val pp_endorsable_payload : Format.formatter -> endorsable_payload -> unit - -val pp_elected_block : Format.formatter -> elected_block -> unit - -val pp_endorsing_slot : Format.formatter -> delegate * endorsing_slot -> unit - -val pp_delegate_slots : Format.formatter -> delegate_slots -> unit - -val pp_level_state : Format.formatter -> level_state -> unit - -val pp_phase : Format.formatter -> phase -> unit - -val pp_round_state : Format.formatter -> round_state -> unit - -val pp : Format.formatter -> t -> unit - -val pp_timeout_kind : Format.formatter -> timeout_kind -> unit - -val pp_event : Format.formatter -> event -> unit diff --git a/src/proto_012_Psithaca/lib_delegate/block_forge.ml b/src/proto_012_Psithaca/lib_delegate/block_forge.ml deleted file mode 100644 index 35776a82ce7e..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/block_forge.ml +++ /dev/null @@ -1,360 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type unsigned_block = { - unsigned_block_header : Block_header.t; - operations : Tezos_base.Operation.t list list; -} - -type simulation_kind = - | Filter of Operation_pool.pool - | Apply of { - ordered_pool : Operation_pool.ordered_pool; - payload_hash : Block_payload_hash.t; - } - -type simulation_mode = Local of Context.index | Node - -let forge_faked_protocol_data ?(payload_hash = Block_payload_hash.zero) - ~payload_round ~seed_nonce_hash ~liquidity_baking_escape_vote () = - Block_header. - { - contents = - { - payload_hash; - payload_round; - seed_nonce_hash; - proof_of_work_nonce = Baking_pow.empty_proof_of_work_nonce; - liquidity_baking_escape_vote; - }; - signature = Signature.zero; - } - -let convert_operation (op : packed_operation) : Tezos_base.Operation.t = - { - shell = op.shell; - proto = - Data_encoding.Binary.to_bytes_exn - Alpha_context.Operation.protocol_data_encoding - op.protocol_data; - } - -(* Build the block header : mimics node prevalidation *) -let finalize_block_header shell_header timestamp validation_result - operations_hash predecessor_block_metadata_hash - predecessor_ops_metadata_hash = - let {Tezos_protocol_environment.context; fitness; message; _} = - validation_result - in - let validation_passes = List.length Main.validation_passes in - (Context_ops.get_test_chain context >>= function - | Not_running -> return context - | Running {expiration; _} -> - if Time.Protocol.(expiration <= timestamp) then - Context_ops.add_test_chain context Not_running >>= fun context -> - return context - else return context - | Forking _ -> assert false) - >>=? fun context -> - (match predecessor_block_metadata_hash with - | Some predecessor_block_metadata_hash -> - Context_ops.add_predecessor_block_metadata_hash - context - predecessor_block_metadata_hash - | None -> Lwt.return context) - >>= fun context -> - (match predecessor_ops_metadata_hash with - | Some predecessor_ops_metadata_hash -> - Context_ops.add_predecessor_ops_metadata_hash - context - predecessor_ops_metadata_hash - | None -> Lwt.return context) - >>= fun context -> - let context = Context_ops.hash ~time:timestamp ?message context in - let header = - Tezos_base.Block_header. - { - shell_header with - level = Int32.succ shell_header.level; - validation_passes; - operations_hash; - fitness; - context; - } - in - return header - -let retain_live_operations_only ~live_blocks operation_pool = - Operation_pool.filter_pool - (fun ({shell; _} : packed_operation) -> - Block_hash.Set.mem shell.branch live_blocks) - operation_pool - -let forge (cctxt : #Protocol_client_context.full) ~chain_id ~pred_info - ~timestamp ~liquidity_baking_escape_vote fees_config ~seed_nonce_hash - ~payload_round simulation_mode simulation_kind constants = - let predecessor_block = (pred_info : Baking_state.block_info) in - let hard_gas_limit_per_block = constants.Constants.hard_gas_limit_per_block in - let chain = `Hash chain_id in - let simulation_kind = - match simulation_kind with - | Filter operation_pool -> - (* We cannot include operations that are not live with respect - to our predecessor otherwise the node would reject the block. *) - let filtered_pool = - retain_live_operations_only - ~live_blocks:pred_info.live_blocks - operation_pool - in - Filter filtered_pool - | Apply _ as x -> x - in - (match (simulation_mode, simulation_kind) with - | (Baking_state.Node, Filter operation_pool) -> - let filtered_operations = - Operation_selection.filter_operations_without_simulation - fees_config - ~hard_gas_limit_per_block - operation_pool - in - let faked_protocol_data = - forge_faked_protocol_data - ~payload_round - ~seed_nonce_hash - ~liquidity_baking_escape_vote - () - in - Node_rpc.preapply_block - cctxt - ~chain - ~head:predecessor_block.hash - ~timestamp - ~protocol_data:faked_protocol_data - filtered_operations - >>=? fun (shell_header, preapply_result) -> - (* only retain valid operations *) - let operations = - List.map - (fun l -> List.map snd l.Preapply_result.applied) - preapply_result - in - let payload_hash = - let operation_list_hash = - Stdlib.List.tl operations |> List.flatten - |> List.map Tezos_base.Operation.hash - |> Operation_list_hash.compute - in - Block_payload.hash - ~predecessor:shell_header.predecessor - payload_round - operation_list_hash - in - return (shell_header, operations, payload_hash) - | (Node, Apply {ordered_pool; payload_hash}) -> - let operations = Operation_pool.ordered_to_list_list ordered_pool in - let faked_protocol_data = - forge_faked_protocol_data - ~seed_nonce_hash - ~liquidity_baking_escape_vote - ~payload_hash - ~payload_round - () - in - Node_rpc.preapply_block - cctxt - ~chain - ~head:predecessor_block.hash - ~timestamp - ~protocol_data:faked_protocol_data - operations - >>=? fun (shell_header, _preapply_result) -> - let operations = List.map (List.map convert_operation) operations in - return (shell_header, operations, payload_hash) - | (Local context_index, Filter operation_pool) -> - let faked_protocol_data = - forge_faked_protocol_data - ~payload_round - ~seed_nonce_hash - ~liquidity_baking_escape_vote - () - in - Baking_simulator.begin_construction - ~timestamp - ~protocol_data:faked_protocol_data - context_index - predecessor_block - chain_id - >>=? fun incremental -> - Operation_selection.filter_operations_with_simulation - incremental - fees_config - ~hard_gas_limit_per_block - operation_pool - >>=? fun { - Operation_selection.operations; - validation_result; - operations_hash; - _; - } -> - let _op_pool' = - Operation_pool.(add_operations empty (List.concat operations)) - in - protect - ~on_error:(fun _ -> return_none) - (fun () -> - Shell_services.Blocks.metadata_hash - cctxt - ~block:(`Hash (predecessor_block.hash, 0)) - ~chain - () - >>=? fun pred_block_metadata_hash -> - return (Some pred_block_metadata_hash)) - >>=? fun pred_block_metadata_hash -> - protect - ~on_error:(fun _ -> return_none) - (fun () -> - Shell_services.Blocks.Operation_metadata_hashes.root - cctxt - ~block:(`Hash (predecessor_block.hash, 0)) - ~chain - () - >>=? fun pred_op_metadata_hash -> return (Some pred_op_metadata_hash)) - >>=? fun pred_op_metadata_hash -> - finalize_block_header - incremental.header - timestamp - validation_result - operations_hash - pred_block_metadata_hash - pred_op_metadata_hash - >>=? fun shell_header -> - let operations = List.map (List.map convert_operation) operations in - let payload_hash = - let operation_list_hash = - Stdlib.List.tl operations |> List.flatten - |> List.map Tezos_base.Operation.hash - |> Operation_list_hash.compute - in - Block_payload.hash - ~predecessor:shell_header.predecessor - payload_round - operation_list_hash - in - return (shell_header, operations, payload_hash) - | (Local context_index, Apply {ordered_pool; payload_hash}) -> - let faked_protocol_data = - forge_faked_protocol_data - ~seed_nonce_hash - ~liquidity_baking_escape_vote - ~payload_hash - ~payload_round - () - in - Shell_services.Chain.chain_id cctxt ~chain () >>=? fun chain_id -> - Baking_simulator.begin_construction - ~timestamp - ~protocol_data:faked_protocol_data - context_index - predecessor_block - chain_id - >>=? fun incremental -> - let operations = Operation_pool.ordered_to_list_list ordered_pool in - (* We must make sure that the given consensus operations are - pre-checked/pre-filtered before calling this function, - otherwise, these will fail *) - List.fold_left_es - (fun inc op -> - Baking_simulator.add_operation inc op >>=? fun (inc, _) -> return inc) - incremental - (List.flatten operations) - >>=? fun incremental -> - let operations_hash = - Operation_list_list_hash.compute - (List.map - (fun sl -> - Operation_list_hash.compute (List.map Operation.hash_packed sl)) - operations) - in - (* We need to compute the final [operations_hash] before - finalizing the block because it will be used in the cache's nonce. *) - let incremental = - {incremental with header = {incremental.header with operations_hash}} - in - Baking_simulator.finalize_construction incremental - >>=? fun (validation_result, _) -> - protect - ~on_error:(fun _ -> return_none) - (fun () -> - Shell_services.Blocks.metadata_hash - cctxt - ~block:(`Hash (predecessor_block.hash, 0)) - ~chain - () - >>=? fun pred_block_metadata_hash -> - return (Some pred_block_metadata_hash)) - >>=? fun pred_block_metadata_hash -> - protect - ~on_error:(fun _ -> return_none) - (fun () -> - Shell_services.Blocks.Operation_metadata_hashes.root - cctxt - ~block:(`Hash (predecessor_block.hash, 0)) - ~chain - () - >>=? fun pred_op_metadata_hash -> return (Some pred_op_metadata_hash)) - >>=? fun pred_op_metadata_hash -> - finalize_block_header - incremental.header - timestamp - validation_result - operations_hash - pred_block_metadata_hash - pred_op_metadata_hash - >>=? fun shell_header -> - let operations = List.map (List.map convert_operation) operations in - return (shell_header, operations, payload_hash)) - >>=? fun (shell_header, operations, payload_hash) -> - Baking_pow.mine - ~proof_of_work_threshold:constants.proof_of_work_threshold - shell_header - (fun proof_of_work_nonce -> - { - Block_header.payload_hash; - payload_round; - seed_nonce_hash; - proof_of_work_nonce; - liquidity_baking_escape_vote; - }) - >>=? fun contents -> - let unsigned_block_header = - { - Block_header.shell = shell_header; - protocol_data = {contents; signature = Signature.zero}; - } - in - return {unsigned_block_header; operations} diff --git a/src/proto_012_Psithaca/lib_delegate/block_forge.mli b/src/proto_012_Psithaca/lib_delegate/block_forge.mli deleted file mode 100644 index 5549a3f19881..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/block_forge.mli +++ /dev/null @@ -1,63 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type unsigned_block = { - unsigned_block_header : Block_header.t; - operations : Tezos_base.Operation.t list list; -} - -type simulation_kind = - | Filter of Operation_pool.pool - | Apply of { - ordered_pool : Operation_pool.ordered_pool; - payload_hash : Block_payload_hash.t; - } - -type simulation_mode = Local of Context.index | Node - -val forge_faked_protocol_data : - ?payload_hash:Block_payload_hash.t -> - payload_round:Round.t -> - seed_nonce_hash:Nonce_hash.t option -> - liquidity_baking_escape_vote:bool -> - unit -> - block_header_data - -val forge : - #Protocol_client_context.full -> - chain_id:Chain_id.t -> - pred_info:Baking_state.block_info -> - timestamp:Time.Protocol.t -> - liquidity_baking_escape_vote:bool -> - Baking_configuration.fees_config -> - seed_nonce_hash:Nonce_hash.t option -> - payload_round:Round.t -> - Baking_state.validation_mode -> - simulation_kind -> - Constants.parametric -> - unsigned_block tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/client_baking_blocks.ml b/src/proto_012_Psithaca/lib_delegate/client_baking_blocks.ml deleted file mode 100644 index b678e02824c8..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/client_baking_blocks.ml +++ /dev/null @@ -1,188 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type block_info = { - hash : Block_hash.t; - chain_id : Chain_id.t; - predecessor : Block_hash.t; - fitness : Bytes.t list; - timestamp : Time.Protocol.t; - protocol : Protocol_hash.t; - next_protocol : Protocol_hash.t; - proto_level : int; - level : Raw_level.t; - context : Context_hash.t; -} - -let raw_info cctxt ?(chain = `Main) hash shell_header = - let block = `Hash (hash, 0) in - Shell_services.Chain.chain_id cctxt ~chain () >>=? fun chain_id -> - Shell_services.Blocks.protocols cctxt ~chain ~block () - >>=? fun {current_protocol = protocol; next_protocol} -> - let { - Tezos_base.Block_header.predecessor; - fitness; - timestamp; - level; - context; - proto_level; - _; - } = - shell_header - in - match Raw_level.of_int32 level with - | Ok level -> - return - { - hash; - chain_id; - predecessor; - fitness; - timestamp; - protocol; - next_protocol; - proto_level; - level; - context; - } - | Error _ -> failwith "Cannot convert level into int32" - -let info cctxt ?(chain = `Main) block = - Shell_services.Blocks.hash cctxt ~chain ~block () >>=? fun hash -> - Shell_services.Blocks.Header.shell_header cctxt ~chain ~block () - >>=? fun shell_header -> raw_info cctxt ~chain hash shell_header - -module Block_seen_event = struct - type t = { - hash : Block_hash.t; - header : Tezos_base.Block_header.t; - occurrence : [`Valid_blocks of Chain_id.t | `Heads]; - } - - let make hash header occurrence () = {hash; header; occurrence} - - module Definition = struct - let section = None - - let name = "block-seen-" ^ Protocol.name - - type nonrec t = t - - let encoding = - let open Data_encoding in - let v0_encoding = - conv - (function {hash; header; occurrence} -> (hash, occurrence, header)) - (fun (b, o, h) -> make b h o ()) - (obj3 - (req "hash" Block_hash.encoding) - (* Occurrence has to come before header, because: - (Invalid_argument - "Cannot merge two objects when the left element is of - variable length and the right one of dynamic - length. You should use the reverse order, or wrap the - second one with Data_encoding.dynamic_size.") *) - (req - "occurrence" - (union - [ - case - ~title:"heads" - (Tag 0) - (obj1 (req "occurrence-kind" (constant "heads"))) - (function `Heads -> Some () | _ -> None) - (fun () -> `Heads); - case - ~title:"valid-blocks" - (Tag 1) - (obj2 - (req "occurrence-kind" (constant "valid-blocks")) - (req "chain-id" Chain_id.encoding)) - (function - | `Valid_blocks ch -> Some ((), ch) | _ -> None) - (fun ((), ch) -> `Valid_blocks ch); - ])) - (req "header" Tezos_base.Block_header.encoding)) - in - With_version.(encoding ~name (first_version v0_encoding)) - - let pp ~short:_ ppf {hash; _} = - Format.fprintf ppf "Saw block %a" Block_hash.pp_short hash - - let doc = "Block observed while monitoring a blockchain." - - let level _ = Internal_event.Info - end - - module Event = Internal_event.Make (Definition) -end - -let monitor_valid_blocks cctxt ?chains ?protocols ~next_protocols () = - Monitor_services.valid_blocks cctxt ?chains ?protocols ?next_protocols () - >>=? fun (block_stream, _stop) -> - return - (Lwt_stream.map_s - (fun ((chain, block), header) -> - Block_seen_event.(Event.emit (make block header (`Valid_blocks chain))) - >>=? fun () -> - raw_info - cctxt - ~chain:(`Hash chain) - block - header.Tezos_base.Block_header.shell) - block_stream) - -let monitor_heads cctxt ~next_protocols chain = - Monitor_services.heads cctxt ?next_protocols chain - >>=? fun (block_stream, _stop) -> - return - (Lwt_stream.map_s - (fun (block, ({Tezos_base.Block_header.shell; _} as header)) -> - Block_seen_event.(Event.emit (make block header `Heads)) >>=? fun () -> - raw_info cctxt ~chain block shell) - block_stream) - -let blocks_from_current_cycle cctxt ?(chain = `Main) block ?(offset = 0l) () = - Shell_services.Blocks.hash cctxt ~chain ~block () >>=? fun hash -> - Shell_services.Blocks.Header.shell_header cctxt ~chain ~block () - >>=? fun {level; _} -> - Plugin.RPC.levels_in_current_cycle cctxt ~offset (chain, block) >>= function - | Error (RPC_context.Not_found _ :: _) -> return_nil - | Error _ as err -> Lwt.return err - | Ok (first, last) -> - let length = Int32.to_int (Int32.sub level (Raw_level.to_int32 first)) in - Shell_services.Blocks.list cctxt ~chain ~heads:[hash] ~length () - >>=? fun blocks -> - (* TODO-TB change this *) - let head = match blocks with hd :: _ -> hd | _ -> assert false in - let blocks = - List.remove (length - Int32.to_int (Raw_level.diff last first)) head - in - if Int32.equal level (Raw_level.to_int32 last) then - return (hash :: blocks) - else return blocks diff --git a/src/proto_012_Psithaca/lib_delegate/client_baking_blocks.mli b/src/proto_012_Psithaca/lib_delegate/client_baking_blocks.mli deleted file mode 100644 index fdf29d613ddb..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/client_baking_blocks.mli +++ /dev/null @@ -1,68 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type block_info = { - hash : Block_hash.t; - chain_id : Chain_id.t; - predecessor : Block_hash.t; - fitness : Bytes.t list; - timestamp : Time.Protocol.t; - protocol : Protocol_hash.t; - next_protocol : Protocol_hash.t; - proto_level : int; - level : Raw_level.t; - context : Context_hash.t; -} - -val info : - #Protocol_client_context.rpc_context -> - ?chain:Chain_services.chain -> - Block_services.block -> - block_info tzresult Lwt.t - -val monitor_valid_blocks : - #Protocol_client_context.rpc_context -> - ?chains:Chain_services.chain list -> - ?protocols:Protocol_hash.t list -> - next_protocols:Protocol_hash.t list option -> - unit -> - block_info tzresult Lwt_stream.t tzresult Lwt.t - -val monitor_heads : - #Protocol_client_context.rpc_context -> - next_protocols:Protocol_hash.t list option -> - Chain_services.chain -> - block_info tzresult Lwt_stream.t tzresult Lwt.t - -val blocks_from_current_cycle : - #Protocol_client_context.rpc_context -> - ?chain:Chain_services.chain -> - Block_services.block -> - ?offset:int32 -> - unit -> - Block_hash.t list tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/client_baking_denunciation.ml b/src/proto_012_Psithaca/lib_delegate/client_baking_denunciation.ml deleted file mode 100644 index 09f35229368b..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/client_baking_denunciation.ml +++ /dev/null @@ -1,489 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Protocol_client_context -open Client_baking_blocks -module Events = Delegate_events.Denunciator - -module HLevel = Hashtbl.Make (struct - type t = Chain_id.t * Raw_level.t * Round.t - - let equal (c, l, r) (c', l', r') = - Chain_id.equal c c' && Raw_level.equal l l' && Round.equal r r' - - let hash (c, lvl, r) = Hashtbl.hash (c, lvl, r) -end) - -(* Blocks are associated to the delegates who baked them *) -module Delegate_Map = Map.Make (Signature.Public_key_hash) - -(* (pre)endorsements are associated to the slot they are injected - with; we rely on the fact that there is a unique canonical slot - identifying a (pre)endorser. *) -module Slot_Map = Slot.Map - -(* type of operations stream, as returned by monitor_operations RPC *) -type ops_stream = - ((Operation_hash.t * packed_operation) * error list) list Lwt_stream.t - -type 'a state = { - (* Endorsements seen so far *) - endorsements_table : Kind.endorsement operation Slot_Map.t HLevel.t; - (* Preendorsements seen so far *) - preendorsements_table : Kind.preendorsement operation Slot_Map.t HLevel.t; - (* Blocks received so far *) - blocks_table : Block_hash.t Delegate_Map.t HLevel.t; - (* Maximum delta of level to register *) - preserved_levels : int; - (* Highest level seen in a block *) - mutable highest_level_encountered : Raw_level.t; - (* This constant allows to set at which frequency (expressed in blocks levels) - the tables above are cleaned. Cleaning the table means removing information - stored about old levels up to - 'highest_level_encountered - preserved_levels'. - *) - clean_frequency : int; - (* the decreasing cleaning countdown for the next cleaning *) - mutable cleaning_countdown : int; - (* stream of all valid blocks *) - blocks_stream : (block_info, 'a) result Lwt_stream.t; - (* operations stream. Reset on new heads flush *) - mutable ops_stream : ops_stream; - (* operatons stream stopper. Used when a q new *) - mutable ops_stream_stopper : unit -> unit; -} - -let create_state ~preserved_levels blocks_stream ops_stream ops_stream_stopper = - let clean_frequency = max 1 (preserved_levels / 10) in - Lwt.return - { - endorsements_table = HLevel.create preserved_levels; - preendorsements_table = HLevel.create preserved_levels; - blocks_table = HLevel.create preserved_levels; - preserved_levels; - highest_level_encountered = Raw_level.root (* 0l *); - clean_frequency; - cleaning_countdown = clean_frequency; - blocks_stream; - ops_stream; - ops_stream_stopper; - } - -(* We choose a previous offset (5 blocks from head) to ensure that the - injected operation is branched from a valid - predecessor. Denunciation operations can be emitted when the - consensus is under attack and may occur so you want to inject the - operation from a block which is considered "final". *) -let get_block_offset level = - match Raw_level.of_int32 5l with - | Ok min_level -> - let offset = Raw_level.diff level min_level in - if Compare.Int32.(offset >= 0l) then Lwt.return (`Head 5) - else - (* offset < 0l *) - let negative_offset = Int32.to_int offset in - (* We cannot inject at at level 0 : this is the genesis - level. We inject starting from level 1 thus the '- 1'. *) - Lwt.return (`Head (5 + negative_offset - 1)) - | Error errs -> - Events.(emit invalid_level_conversion) (Environment.wrap_tztrace errs) - >>= fun () -> Lwt.return (`Head 0) - -let get_payload_hash (type kind) (op_kind : kind consensus_operation_type) - (op : kind Operation.t) = - match (op_kind, op.protocol_data.contents) with - | (Preendorsement, Single (Preendorsement consensus_content)) - | (Endorsement, Single (Endorsement consensus_content)) -> - consensus_content.block_payload_hash - | _ -> . - -let double_consensus_op_evidence (type kind) : - kind consensus_operation_type -> - #Protocol_client_context.full -> - 'a -> - branch:Block_hash.t -> - op1:kind Alpha_context.operation -> - op2:kind Alpha_context.operation -> - unit -> - bytes Environment.Error_monad.shell_tzresult Lwt.t = function - | Endorsement -> Plugin.RPC.Forge.double_endorsement_evidence - | Preendorsement -> Plugin.RPC.Forge.double_preendorsement_evidence - -let process_consensus_op (type kind) cctxt - (op_kind : kind consensus_operation_type) (new_op : kind Operation.t) - chain_id level round slot ops_table = - let map = - Option.value ~default:Slot_Map.empty - @@ HLevel.find ops_table (chain_id, level, round) - in - (* If a previous endorsement made by this pkh (the slot determines the pkh) - is found for the same level we inject a double_(pre)endorsement *) - match Slot_Map.find slot map with - | None -> - return - @@ HLevel.add - ops_table - (chain_id, level, round) - (Slot_Map.add slot new_op map) - | Some existing_op - when Block_payload_hash.( - get_payload_hash op_kind existing_op - <> get_payload_hash op_kind new_op) -> - (* same level and round, and different payload hash for this slot *) - let (new_op_hash, existing_op_hash) = - (Operation.hash new_op, Operation.hash existing_op) - in - let (op1, op2) = - if Operation_hash.(new_op_hash < existing_op_hash) then - (new_op, existing_op) - else (existing_op, new_op) - in - get_block_offset level >>= fun block -> - let chain = `Hash chain_id in - Alpha_block_services.hash cctxt ~chain ~block () >>=? fun block_hash -> - double_consensus_op_evidence - op_kind - cctxt - (`Hash chain_id, block) - ~branch:block_hash - ~op1 - ~op2 - () - >>=? fun bytes -> - let bytes = Signature.concat bytes Signature.zero in - let (double_op_detected, double_op_denounced) = - Events.( - match op_kind with - | Endorsement -> - (double_endorsement_detected, double_endorsement_denounced) - | Preendorsement -> - (double_preendorsement_detected, double_preendorsement_denounced)) - in - Events.(emit double_op_detected) (new_op_hash, existing_op_hash) - >>= fun () -> - HLevel.replace - ops_table - (chain_id, level, round) - (Slot_Map.add slot new_op map) ; - Shell_services.Injection.operation cctxt ~chain bytes >>=? fun op_hash -> - Events.(emit double_op_denounced) (op_hash, bytes) >>= fun () -> - return_unit - | _ -> return_unit - -let process_operations (cctxt : #Protocol_client_context.full) state - (endorsements : 'a list) ~packed_op chain_id = - List.iter_es - (fun op -> - let {shell; protocol_data; _} = packed_op op in - match protocol_data with - | Operation_data - ({contents = Single (Preendorsement {round; slot; level; _}); _} as - protocol_data) -> - let new_preendorsement : Kind.preendorsement Alpha_context.operation = - {shell; protocol_data} - in - process_consensus_op - cctxt - Preendorsement - new_preendorsement - chain_id - level - round - slot - state.preendorsements_table - | Operation_data - ({contents = Single (Endorsement {round; slot; level; _}); _} as - protocol_data) -> - let new_endorsement : Kind.endorsement Alpha_context.operation = - {shell; protocol_data} - in - process_consensus_op - cctxt - Endorsement - new_endorsement - chain_id - level - round - slot - state.endorsements_table - | _ -> - (* not a consensus operation *) - return_unit) - endorsements - -let context_block_header cctxt ~chain b_hash = - Alpha_block_services.header cctxt ~chain ~block:(`Hash (b_hash, 0)) () - >>=? fun ({shell; protocol_data; _} : Alpha_block_services.block_header) -> - return {Alpha_context.Block_header.shell; protocol_data} - -let process_block (cctxt : #Protocol_client_context.full) state - (header : Alpha_block_services.block_info) = - match header with - | {hash; metadata = None; _} -> - Events.(emit unexpected_pruned_block) hash >>= fun () -> return_unit - | { - Alpha_block_services.chain_id; - hash = new_hash; - metadata = Some {protocol_data = {baker; level_info = {level; _}; _}; _}; - header = {shell = {fitness; _}; _}; - _; - } -> ( - let fitness = Fitness.from_raw fitness in - Lwt.return - (match fitness with - | Ok fitness -> Ok (Fitness.round fitness) - | Error errs -> Error (Environment.wrap_tztrace errs)) - >>=? fun round -> - let chain = `Hash chain_id in - let map = - Option.value ~default:Delegate_Map.empty - @@ HLevel.find state.blocks_table (chain_id, level, round) - in - match Delegate_Map.find baker map with - | None -> - return - @@ HLevel.add - state.blocks_table - (chain_id, level, round) - (Delegate_Map.add baker new_hash map) - | Some existing_hash when Block_hash.(existing_hash = new_hash) -> - (* This case should never happen *) - Events.(emit double_baking_but_not) () >>= fun () -> - return - @@ HLevel.replace - state.blocks_table - (chain_id, level, round) - (Delegate_Map.add baker new_hash map) - | Some existing_hash -> - (* If a previous block made by this pkh is found for - the same (level, round) we inject a double_baking_evidence *) - context_block_header cctxt ~chain existing_hash >>=? fun bh1 -> - context_block_header cctxt ~chain new_hash >>=? fun bh2 -> - let hash1 = Block_header.hash bh1 in - let hash2 = Block_header.hash bh2 in - let (bh1, bh2) = - if Block_hash.(hash1 < hash2) then (bh1, bh2) else (bh2, bh1) - in - (* If the blocks are on different chains then skip it *) - get_block_offset level >>= fun block -> - Alpha_block_services.hash cctxt ~chain ~block () - >>=? fun block_hash -> - Plugin.RPC.Forge.double_baking_evidence - cctxt - (chain, block) - ~branch:block_hash - ~bh1 - ~bh2 - () - >>=? fun bytes -> - let bytes = Signature.concat bytes Signature.zero in - Events.(emit double_baking_detected) () >>= fun () -> - Shell_services.Injection.operation cctxt ~chain bytes - >>=? fun op_hash -> - Events.(emit double_baking_denounced) (op_hash, bytes) >>= fun () -> - return - @@ HLevel.replace - state.blocks_table - (chain_id, level, round) - (Delegate_Map.add baker new_hash map)) - -(* Remove levels that are lower than the - [highest_level_encountered] minus [preserved_levels] *) -let cleanup_old_operations state = - state.cleaning_countdown <- state.cleaning_countdown - 1 ; - if state.cleaning_countdown < 0 then ( - (* It's time to remove old levels *) - state.cleaning_countdown <- state.clean_frequency ; - let highest_level_encountered = - Int32.to_int (Raw_level.to_int32 state.highest_level_encountered) - in - let diff = highest_level_encountered - state.preserved_levels in - let threshold = - if diff < 0 then Raw_level.root - else - Raw_level.of_int32 (Int32.of_int diff) |> function - | Ok threshold -> threshold - | Error _ -> Raw_level.root - in - let filter hmap = - HLevel.filter_map_inplace - (fun (_, level, _) x -> - if Raw_level.(level < threshold) then None else Some x) - hmap - in - filter state.preendorsements_table ; - filter state.endorsements_table ; - filter state.blocks_table) - -(* Each new block is processed : - - Checking that every baker injected only once at this level - - Checking that every (pre)endorser operated only once at this level -*) -let process_new_block (cctxt : #Protocol_client_context.full) state - {hash; chain_id; level; protocol; next_protocol; _} = - if Protocol_hash.(protocol <> next_protocol) then - Events.(emit protocol_change_detected) () >>= fun () -> return_unit - else - Events.(emit accuser_saw_block) (level, hash) >>= fun () -> - let chain = `Hash chain_id in - let block = `Hash (hash, 0) in - state.highest_level_encountered <- - Raw_level.max level state.highest_level_encountered ; - (* Processing blocks *) - (Alpha_block_services.info cctxt ~chain ~block () >>= function - | Ok block_info -> process_block cctxt state block_info - | Error errs -> - Events.(emit fetch_operations_error) (hash, errs) >>= fun () -> - return_unit) - >>=? fun () -> - (* Processing (pre)endorsements in the block *) - (Alpha_block_services.Operations.operations cctxt ~chain ~block () - >>= function - | Ok (consensus_ops :: _) -> - let packed_op {Alpha_block_services.shell; protocol_data; _} = - {shell; protocol_data} - in - process_operations cctxt state consensus_ops ~packed_op chain_id - | Ok [] -> - (* should not happen, unless the semantics of - Alpha_block_services.Operations.operations (which is supposed to - return a list of 4 elements changes. In which case, this code - should be adapted). *) - assert false - | Error errs -> - Events.(emit fetch_operations_error) (hash, errs) >>= fun () -> - return_unit) - >>=? fun () -> - cleanup_old_operations state ; - return_unit - -let process_new_block cctxt state bi = - process_new_block cctxt state bi >>= function - | Ok () -> Events.(emit accuser_processed_block) bi.hash >>= return - | Error errs -> Events.(emit accuser_block_error) (bi.hash, errs) >>= return - -module B_Events = Delegate_events.Baking_scheduling - -let rec wait_for_first_block ~name stream = - Lwt_stream.get stream >>= function - | None | Some (Error _) -> - B_Events.(emit cannot_fetch_event) name >>= fun () -> - (* NOTE: this is not a tight loop because of Lwt_stream.get *) - wait_for_first_block ~name stream - | Some (Ok bi) -> Lwt.return bi - -let log_errors_and_continue ~name p = - p >>= function - | Ok () -> Lwt.return_unit - | Error errs -> B_Events.(emit daemon_error) (name, errs) - -let start_ops_monitor cctxt = - Alpha_block_services.Mempool.monitor_operations - cctxt - ~chain:cctxt#chain - ~applied:true - ~branch_delayed:true - ~branch_refused:true - ~refused:true - () - -let create (cctxt : #Protocol_client_context.full) ?canceler ~preserved_levels - valid_blocks_stream = - B_Events.(emit daemon_setup) name >>= fun () -> - start_ops_monitor cctxt >>=? fun (ops_stream, ops_stream_stopper) -> - create_state - ~preserved_levels - valid_blocks_stream - ops_stream - ops_stream_stopper - >>= fun state -> - Option.iter - (fun canceler -> - Lwt_canceler.on_cancel canceler (fun () -> - state.ops_stream_stopper () ; - Lwt.return_unit)) - canceler ; - wait_for_first_block ~name state.blocks_stream >>= fun _first_event -> - let last_get_block = ref None in - let get_block () = - match !last_get_block with - | None -> - let t = Lwt_stream.get state.blocks_stream in - last_get_block := Some t ; - t - | Some t -> t - in - let last_get_ops = ref None in - let get_ops () = - match !last_get_ops with - | None -> - let t = Lwt_stream.get state.ops_stream in - last_get_ops := Some t ; - t - | Some t -> t - in - Chain_services.chain_id cctxt () >>=? fun chain_id -> - (* main loop *) - let rec worker_loop () = - Lwt.choose - [ - (Lwt_exit.clean_up_starts >|= fun _ -> `Termination); - (get_block () >|= fun e -> `Block e); - (get_ops () >|= fun e -> `Operations e); - ] - >>= function - (* event matching *) - | `Termination -> return_unit - | `Block (None | Some (Error _)) -> - (* exit when the node is unavailable *) - last_get_block := None ; - B_Events.(emit daemon_connection_lost) name >>= fun () -> - fail Baking_errors.Node_connection_lost - | `Block (Some (Ok bi)) -> - last_get_block := None ; - log_errors_and_continue ~name @@ process_new_block cctxt state bi - >>= fun () -> worker_loop () - | `Operations None -> - (* restart a new operations monitor stream *) - last_get_ops := None ; - state.ops_stream_stopper () ; - start_ops_monitor cctxt >>=? fun (ops_stream, ops_stream_stopper) -> - state.ops_stream <- ops_stream ; - state.ops_stream_stopper <- ops_stream_stopper ; - worker_loop () - | `Operations (Some ops) -> - last_get_ops := None ; - log_errors_and_continue ~name - @@ process_operations - cctxt - state - ops - ~packed_op:(fun ((_h, op), _errl) -> op) - chain_id - >>= fun () -> worker_loop () - in - B_Events.(emit daemon_start) name >>= fun () -> worker_loop () diff --git a/src/proto_012_Psithaca/lib_delegate/client_baking_denunciation.mli b/src/proto_012_Psithaca/lib_delegate/client_baking_denunciation.mli deleted file mode 100644 index 46e784d132b4..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/client_baking_denunciation.mli +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val create : - #Protocol_client_context.full -> - ?canceler:Lwt_canceler.t -> - preserved_levels:int -> - Client_baking_blocks.block_info tzresult Lwt_stream.t -> - unit tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/client_baking_scheduling.ml b/src/proto_012_Psithaca/lib_delegate/client_baking_scheduling.ml deleted file mode 100644 index 0c61aabfa353..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/client_baking_scheduling.ml +++ /dev/null @@ -1,33 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Events = Delegate_events.Baking_scheduling - -let sleep_until time = - (* Sleeping is a system op, baking is a protocol op, this is where we convert *) - let time = Time.System.of_protocol_exn time in - let delay = Ptime.diff time (Tezos_stdlib_unix.Systime_os.now ()) in - if Ptime.Span.compare delay Ptime.Span.zero < 0 then None - else Some (Lwt_unix.sleep (Ptime.Span.to_float_s delay)) diff --git a/src/proto_012_Psithaca/lib_delegate/client_baking_scheduling.mli b/src/proto_012_Psithaca/lib_delegate/client_baking_scheduling.mli deleted file mode 100644 index ae4a323ca1cc..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/client_baking_scheduling.mli +++ /dev/null @@ -1,54 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val sleep_until : Time.Protocol.t -> unit Lwt.t option - -(* val wait_for_first_event : - * name:string -> 'event tzresult Lwt_stream.t -> 'event Lwt.t - * - * val main : - * name:string -> - * cctxt:(#Protocol_client_context.full as 'a) -> - * stream:'event tzresult Lwt_stream.t -> - * state_maker:('event -> 'state tzresult Lwt.t) -> - * pre_loop:('a -> 'state -> 'event -> unit tzresult Lwt.t) -> - * compute_timeout:('state -> 'timesup Lwt.t) -> - * timeout_k:('a -> 'state -> 'timesup -> unit tzresult Lwt.t) -> - * event_k:('a -> 'state -> 'event -> unit tzresult Lwt.t) -> - * finalizer:('state -> unit Lwt.t) -> - * unit tzresult Lwt.t *) - -(** [main ~name ~cctxt ~stream ~state_maker ~pre_loop ~timeout_maker ~timeout_k - ~event_k] is an infinitely running loop that - monitors new events arriving on [stream]. The loop exits when the - [stream] gives an error. - - The function [pre_loop] is called before the loop starts. - - The loop maintains a state (of type ['state]) initialized by [state_maker] - and passed to the callbacks [timeout_maker] (used to set up waking-up - timeouts), [timeout_k] (when a computed timeout happens), and [event_k] - (when a new event arrives on the stream). -*) diff --git a/src/proto_012_Psithaca/lib_delegate/client_daemon.ml b/src/proto_012_Psithaca/lib_delegate/client_daemon.ml deleted file mode 100644 index a21ec55610d2..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/client_daemon.ml +++ /dev/null @@ -1,147 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let rec retry (cctxt : #Protocol_client_context.full) ?max_delay ~delay ~factor - ~tries f x = - f x >>= function - | Ok _ as r -> Lwt.return r - | Error - (RPC_client_errors.Request_failed {error = Connection_failed _; _} :: _) - as err - when tries > 0 -> ( - cctxt#message "Connection refused, retrying in %.2f seconds..." delay - >>= fun () -> - Lwt.pick - [ - (Lwt_unix.sleep delay >|= fun () -> `Continue); - (Lwt_exit.clean_up_starts >|= fun _ -> `Killed); - ] - >>= function - | `Killed -> Lwt.return err - | `Continue -> - let next_delay = delay *. factor in - let delay = - Option.fold - ~none:next_delay - ~some:(fun max_delay -> Float.min next_delay max_delay) - max_delay - in - retry cctxt ?max_delay ~delay ~factor ~tries:(tries - 1) f x) - | Error _ as err -> Lwt.return err - -let rec retry_on_disconnection (cctxt : #Protocol_client_context.full) f = - f () >>= function - | Ok () -> return_unit - | Error (Baking_errors.Node_connection_lost :: _) -> - cctxt#warning - "Lost connection with the node. Retrying to establish connection..." - >>= fun () -> - (* Wait forever when the node stops responding... *) - Client_confirmations.wait_for_bootstrapped - ~retry:(retry cctxt ~max_delay:10. ~delay:1. ~factor:1.5 ~tries:max_int) - cctxt - >>=? fun () -> retry_on_disconnection cctxt f - | Error err -> - cctxt#error "Unexpected error: %a. Exiting..." pp_print_trace err - -module Baker = struct - let run (cctxt : Protocol_client_context.full) ?minimal_fees - ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte - ?liquidity_baking_escape_vote ?per_block_vote_file ~chain ~context_path - ~keep_alive delegates = - let process () = - Config_services.user_activated_upgrades cctxt - >>=? fun user_activated_upgrades -> - let config = - Baking_configuration.make - ?minimal_fees - ?minimal_nanotez_per_gas_unit - ?minimal_nanotez_per_byte - ?liquidity_baking_escape_vote - ?per_block_vote_file - ~context_path - ~user_activated_upgrades - () - in - cctxt#message - "Baker v%s (%s) for %a started." - Tezos_version.Version.current_string - Tezos_version.Current_git_info.abbreviated_commit_hash - Protocol_hash.pp_short - Protocol.hash - >>= fun () -> - let canceler = Lwt_canceler.create () in - let _ = - Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _ -> - cctxt#message "Shutting down the baker..." >>= fun () -> - Lwt_canceler.cancel canceler >>= fun _ -> Lwt.return_unit) - in - Baking_scheduling.run cctxt ~canceler ~chain config delegates - in - Client_confirmations.wait_for_bootstrapped - ~retry:(retry cctxt ~delay:1. ~factor:1.5 ~tries:5) - cctxt - >>=? fun () -> - cctxt#message "Waiting for protocol %s to start..." Protocol.name - >>= fun () -> - Node_rpc.await_protocol_activation cctxt ~chain () >>=? fun () -> - if keep_alive then retry_on_disconnection cctxt process else process () -end - -module Accuser = struct - let run (cctxt : #Protocol_client_context.full) ~chain ~preserved_levels - ~keep_alive = - let process () = - Client_baking_blocks.monitor_valid_blocks - ~next_protocols:(Some [Protocol.hash]) - cctxt - ~chains:[chain] - () - >>=? fun valid_blocks_stream -> - cctxt#message - "Accuser v%s (%s) for %a started." - Tezos_version.Version.current_string - Tezos_version.Current_git_info.abbreviated_commit_hash - Protocol_hash.pp_short - Protocol.hash - >>= fun () -> - let canceler = Lwt_canceler.create () in - let _ = - Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _ -> - cctxt#message "Shutting down the accuser..." >>= fun () -> - Lwt_canceler.cancel canceler >>= fun _ -> Lwt.return_unit) - in - Client_baking_denunciation.create - cctxt - ~canceler - ~preserved_levels - valid_blocks_stream - in - Client_confirmations.wait_for_bootstrapped - ~retry:(retry cctxt ~delay:1. ~factor:1.5 ~tries:5) - cctxt - >>=? fun () -> - if keep_alive then retry_on_disconnection cctxt process else process () -end diff --git a/src/proto_012_Psithaca/lib_delegate/client_daemon.mli b/src/proto_012_Psithaca/lib_delegate/client_daemon.mli deleted file mode 100644 index d7e1c5a01e55..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/client_daemon.mli +++ /dev/null @@ -1,53 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Daemons directly supported by lib_delegate *) - -(** {1 Baker daemon} *) -module Baker : sig - val run : - Protocol_client_context.full -> - ?minimal_fees:Protocol.Alpha_context.Tez.t -> - ?minimal_nanotez_per_gas_unit:Q.t -> - ?minimal_nanotez_per_byte:Q.t -> - ?liquidity_baking_escape_vote:bool -> - ?per_block_vote_file:string -> - chain:Shell_services.chain -> - context_path:string -> - keep_alive:bool -> - Baking_state.delegate list -> - unit tzresult Lwt.t -end - -(** {1 Accuser daemon} *) - -module Accuser : sig - val run : - #Protocol_client_context.full -> - chain:Chain_services.chain -> - preserved_levels:int -> - keep_alive:bool -> - unit tzresult Lwt.t -end diff --git a/src/proto_012_Psithaca/lib_delegate/context_ops.ml b/src/proto_012_Psithaca/lib_delegate/context_ops.ml deleted file mode 100644 index 8762bc9ddd3b..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/context_ops.ml +++ /dev/null @@ -1,108 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Backend-agnostic operations on the context *) - -let mem (context : Environment_context.Context.t) key = - match context with - | Context {kind = Shell_context.Context; ctxt; _} -> Context.mem ctxt key - | Context {kind = Memory_context.Context; ctxt; _} -> - Tezos_context_memory.Context.mem ctxt key - | Context t -> - Environment_context.err_implementation_mismatch - ~expected:"shell or memory" - ~got:t.impl_name - -let get_protocol (context : Environment_context.Context.t) = - match context with - | Context {kind = Shell_context.Context; ctxt; _} -> Context.get_protocol ctxt - | Context {kind = Memory_context.Context; ctxt; _} -> - Tezos_context_memory.Context.get_protocol ctxt - | Context t -> - Environment_context.err_implementation_mismatch - ~expected:"shell or memory" - ~got:t.impl_name - -let add_predecessor_block_metadata_hash - (context : Environment_context.Context.t) hash = - match context with - | Context {kind = Shell_context.Context; ctxt; _} -> - Context.add_predecessor_block_metadata_hash ctxt hash - >|= Shell_context.wrap_disk_context - | Context {kind = Memory_context.Context; ctxt; _} -> - Tezos_context_memory.Context.add_predecessor_block_metadata_hash ctxt hash - >|= Memory_context.wrap_memory_context - | Context t -> - Environment_context.err_implementation_mismatch - ~expected:"shell or memory" - ~got:t.impl_name - -let add_predecessor_ops_metadata_hash (context : Environment_context.Context.t) - hash = - match context with - | Context {kind = Shell_context.Context; ctxt; _} -> - Context.add_predecessor_ops_metadata_hash ctxt hash - >|= Shell_context.wrap_disk_context - | Context {kind = Memory_context.Context; ctxt; _} -> - Tezos_context_memory.Context.add_predecessor_ops_metadata_hash ctxt hash - >|= Memory_context.wrap_memory_context - | Context t -> - Environment_context.err_implementation_mismatch - ~expected:"shell or memory" - ~got:t.impl_name - -let hash ~time ?message (context : Environment_context.Context.t) = - match context with - | Context {kind = Shell_context.Context; ctxt; _} -> - Context.hash ~time ?message ctxt - | Context {kind = Memory_context.Context; ctxt; _} -> - Tezos_context_memory.Context.hash ~time ?message ctxt - | Context t -> - Environment_context.err_implementation_mismatch - ~expected:"shell or memory" - ~got:t.impl_name - -let get_test_chain (context : Environment_context.Context.t) = - match context with - | Context {kind = Shell_context.Context; ctxt; _} -> - Context.get_test_chain ctxt - | Context {kind = Memory_context.Context; _} -> - Lwt.return Test_chain_status.Not_running - | Context t -> - Environment_context.err_implementation_mismatch - ~expected:"shell or memory" - ~got:t.impl_name - -let add_test_chain (context : Environment_context.Context.t) status = - match context with - | Context {kind = Shell_context.Context; ctxt; _} -> - Context.add_test_chain ctxt status >|= Shell_context.wrap_disk_context - | Context {kind = Memory_context.Context; ctxt; _} -> - Tezos_context_memory.Context.add_test_chain ctxt status - >|= Memory_context.wrap_memory_context - | Context t -> - Environment_context.err_implementation_mismatch - ~expected:"shell or memory" - ~got:t.impl_name diff --git a/src/proto_012_Psithaca/lib_delegate/delegate_events.ml b/src/proto_012_Psithaca/lib_delegate/delegate_events.ml deleted file mode 100644 index ec06b2a6442c..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/delegate_events.ml +++ /dev/null @@ -1,788 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Tocqueville Group, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -let level = Internal_event.Notice - -(* Ignore the value in the output. *) -let pp_ignore fmt _ = Format.pp_print_string fmt "" - -module Revelation = struct - include Internal_event.Simple - - let section = [Protocol.name; "delegate"; "reveal"] - - let no_nonce_reveal = - declare_1 - ~section - ~level - ~name:"no_nonce_reveal" - ~msg:"nothing to reveal for block {block}" - ("block", Block_hash.encoding) - - let reveal_nonce = - declare_5 - ~section - ~level - ~name:"reveal_nonce" - ~msg: - "revealing nonce {nonce} from level {level} for chain {chain}, block \ - {block} with operation {operation}" - ("nonce", Alpha_context.Nonce.encoding) - ("level", Alpha_context.Raw_level.encoding) - ("chain", Data_encoding.string) - ("block", Data_encoding.string) - ("operation", Operation_hash.encoding) -end - -module Nonces = struct - include Internal_event.Simple - - let section = [Protocol.name; "delegate"; "nonces"] - - let cannot_retrieve_block_header = - declare_2 - ~section - ~level:Warning - ~name:"cannot_retrieve_block_header" - ~msg:"cannot retrieve block {block} header associated to nonce: {errors}" - ~pp2:pp_print_top_error_of_trace - ("block", Data_encoding.string) - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let cannot_retrieve_head_level = - declare_0 - ~section - ~level:Error - ~name:"cannot_retrieve_head_level" - ~msg:"cannot fetch chain's head level; aborting nonce filtering" - () - - let too_many_orphans = - declare_1 - ~section - ~level:Warning - ~name:"too_many_orphans" - ~msg: - "found too many nonces associated to blocks unknown by the node in \ - '$TEZOS_CLIENT/{filename}'; after checking that these blocks were \ - never included in the chain (e.g. via a block explorer), consider \ - using `tezos-client filter orphan nonces` to clear them" - ("filename", Data_encoding.string) - - let found_nonce = - declare_2 - ~section - ~level - ~name:"found_nonce" - ~msg:"found nonce to reveal for {hash} (level: {level})" - ("hash", Block_hash.encoding) - ("level", Alpha_context.Raw_level.encoding) - - let bad_nonce = - declare_1 - ~section - ~level:Error - ~name:"bad_nonce" - ~msg:"incoherent nonce for level {level}" - ("level", Alpha_context.Raw_level.encoding) -end - -module Denunciator = struct - include Internal_event.Simple - - let section = [Protocol.name; "delegate"; "denunciation"] - - let invalid_level_conversion = - declare_1 - ~section - ~level:Error - ~name:"invalid_level_conversion" - ~msg:"invalid level conversion: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let double_endorsement_detected = - declare_2 - ~section - ~level - ~name:"double_endorsement_detected" - ~msg:"double endorsement detected" - ("existing_endorsement", Operation_hash.encoding) - ("new_endorsement", Operation_hash.encoding) - - let double_endorsement_denounced = - declare_2 - ~section - ~level - ~name:"double_endorsement_denounced" - ~msg:"double endorsement evidence injected: {hash}" - ("hash", Operation_hash.encoding) - ~pp2:pp_ignore - ("bytes", Data_encoding.bytes) - - let double_preendorsement_detected = - declare_2 - ~section - ~level - ~name:"double_preendorsement_detected" - ~msg:"double preendorsement detected" - ("existing_preendorsement", Operation_hash.encoding) - ("new_preendorsement", Operation_hash.encoding) - - let double_preendorsement_denounced = - declare_2 - ~section - ~level - ~name:"double_preendorsement_denounced" - ~msg:"double preendorsement evidence injected: {hash}" - ("hash", Operation_hash.encoding) - ~pp2:pp_ignore - ("bytes", Data_encoding.bytes) - - let inconsistent_endorsement = - declare_1 - ~section - ~level:Error - ~name:"inconsistent_endorsement" - ~msg:"inconsistent endorsement found {hash}" - ("hash", Operation_hash.encoding) - - let unexpected_pruned_block = - declare_1 - ~section - ~level:Error - ~name:"unexpected_pruned_block" - ~msg:"unexpected pruned block: {hash}" - ("hash", Block_hash.encoding) - - let double_baking_but_not = - declare_0 - ~section - ~level:Debug - ~name:"double_baking_but_not" - ~msg:"double baking detected but block hashes are equivalent; skipping" - () - - let double_baking_detected = - declare_0 - ~section - ~level - ~name:"double_baking_detected" - ~msg:"double baking detected" - () - - let double_baking_denounced = - declare_2 - ~section - ~level - ~name:"double_baking_denounced" - ~msg:"double baking evidence injected {hash}" - ("hash", Operation_hash.encoding) - ~pp2:pp_ignore - ("bytes", Data_encoding.bytes) - - let protocol_change_detected = - declare_0 - ~section - ~level:Error - ~name:"protocol_change_detected" - ~msg:"protocol changing detected; skipping the block" - () - - let accuser_saw_block = - declare_2 - ~section - ~level:Debug - ~name:"accuser_saw_block" - ~msg:"block level: {level}" - ("level", Alpha_context.Raw_level.encoding) - ("hash", Block_hash.encoding) - - let fetch_operations_error = - declare_2 - ~section - ~level:Error - ~name:"fetch_operations_error" - ~msg:"error while fetching operations in block {hash} {errors}" - ~pp2:pp_print_top_error_of_trace - ("hash", Block_hash.encoding) - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let accuser_processed_block = - declare_1 - ~section - ~level - ~name:"accuser_processed_block" - ~msg:"block {hash} registered" - ("hash", Block_hash.encoding) - - let accuser_block_error = - declare_2 - ~section - ~level:Error - ~name:"accuser_block_error" - ~msg:"error while processing block {hash} {errors}" - ~pp2:pp_print_top_error_of_trace - ("hash", Block_hash.encoding) - ("errors", Error_monad.(TzTrace.encoding error_encoding)) -end - -module Baking_scheduling = struct - include Internal_event.Simple - - let section = [Protocol.name; "delegate"; "baking-scheduling"] - - let cannot_fetch_event = - declare_1 - ~section - ~level:Info - ~name:"cannot_fetch_event" - ~msg:"{worker}: can't fetch the current event; waiting for new event" - ("worker", Data_encoding.string) - - let daemon_error = - declare_2 - ~section - ~level:Error - ~name:"daemon_error" - ~msg:"{worker}: error while baking: {errors}" - ~pp2:pp_print_top_error_of_trace - ("worker", Data_encoding.string) - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let daemon_setup = - declare_1 - ~section - ~level:Info - ~name:"daemon_setup" - ~msg:"setting up before the {worker} can start" - ("worker", Data_encoding.string) - - let daemon_connection_lost = - declare_1 - ~section - ~level:Error - ~name:"daemon_connection_lost" - ~msg:"connection to node lost, {worker} exiting" - ("worker", Data_encoding.string) - - let daemon_wakeup = - declare_1 - ~section - ~level:Debug - ~name:"daemon_wakeup" - ~msg:"waking up for {worker}" - ("worker", Data_encoding.string) - - let daemon_start = - declare_1 - ~section - ~level:Info - ~name:"daemon_start" - ~msg:"starting {worker} daemon" - ("worker", Data_encoding.string) -end - -module Baking_forge = struct - include Internal_event.Simple - - let section = [Protocol.name; "delegate"; "baking_forge"] - - let double_bake_near_miss = - declare_1 - ~section - ~level:Error - ~name:"double_bake_near_miss" - ~msg:"level {level}: previously baked" - ("level", Alpha_context.Raw_level.encoding) - - let inject_baked_block = - declare_3 - ~section - ~level:Info - ~name:"inject_baked_block" - ~msg:"Client_baking_forge.inject_block: inject {hash}" - ("hash", Block_hash.encoding) - ~pp2:pp_ignore - ("header", Data_encoding.bytes) - ~pp3:Format.(pp_print_list @@ pp_print_list @@ Operation.pp) - ( "operations", - Data_encoding.(list @@ list @@ dynamic_size Operation.encoding) ) - - let baking_local_validation_start = - declare_1 - ~section - ~level:Debug - ~name:"baking_local_validation_start" - ~msg:"starting client-side validation after {hash}" - ("hash", Block_hash.encoding) - - let context_fetch_error = - declare_1 - ~section - ~level:Error - ~name:"context_fetch_error" - ~msg:"error while fetching current context: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let reopen_context = - declare_0 - ~section - ~level - ~name:"reopen_context" - ~msg:"retrying to open the context" - () - - let baking_rejected_invalid_operation = - declare_2 - ~section - ~level:Debug - ~name:"baking_rejected_invalid_operation" - ~msg:"client-side validation: filtered invalid operation {hash} {errors}" - ~pp2:pp_print_top_error_of_trace - ("hash", Operation_hash.encoding) - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let shell_prevalidation_notice = - declare_0 - ~section - ~level - ~name:"shell_prevalidation_notice" - ~msg:"building a block using shell validation" - () - - let shell_prevalidation_new_protocol = - declare_0 - ~section - ~level - ~name:"shell_prevalidation_new_protocol" - ~msg:"new protocol detected: using shell validation" - () - - let found_valid_operations = - declare_4 - ~section - ~level - ~name:"found_valid_operations" - ~msg: - "found {valid_count} valid operations ({refused_count} refused) for \ - timestamp {timestamp} (fitness {fitness})" - ~pp4:Fitness.pp - ("valid_count", Data_encoding.int31) - ("refused_count", Data_encoding.int31) - ("timestamp", Time.System.encoding) - ("fitness", Fitness.encoding) - - let block_conversion_failed = - declare_1 - ~section - ~level:Error - ~name:"block_conversion_failed" - ~msg:"error on raw_level conversion: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let block_injection_failed = - declare_2 - ~section - ~level:Error - ~name:"block_injection_failed" - ~msg: - "error while injecting block; included operations: {operations}; \ - errors: {errors}" - ~pp1:(Format.pp_print_list Operation.pp) - ~pp2:pp_print_top_error_of_trace - ("operations", Data_encoding.(list @@ dynamic_size Operation.encoding)) - ("errors", Error_monad.trace_encoding) - - let built_invalid_block_error = - declare_1 - ~section - ~level:Error - ~name:"built_invalid_block_error" - ~msg: - "shell-side validation: error while prevalidating operations: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let try_baking = - declare_4 - ~section - ~level:Debug - ~name:"try_baking" - ~msg: - "try baking after {hash} (slot {priority}) for {client} ({timestamp})" - ("hash", Block_hash.encoding) - ("priority", Data_encoding.int31) - ("client", Data_encoding.string) - ("timestamp", Time.System.encoding) - - let new_head_received = - declare_0 - ~section - ~level - ~name:"new_head_received" - ~msg: - "received a new head while waiting for operations; aborting this block" - () - - let client_side_validation_error = - declare_1 - ~section - ~level:Error - ~name:"client_side_validation_error" - ~msg: - "client-side validation: error while filtering invalid operations: \ - {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let waiting_before_injection = - declare_2 - ~section - ~level - ~name:"waiting_before_injection" - ~msg: - "[{current_timestamp}] not ready to inject yet, waiting until \ - {valid_timestamp}" - ("current_timestamp", Time.System.encoding) - ("valid_timestamp", Time.System.encoding) - - let try_forging = - declare_4 - ~section - ~level:Debug - ~name:"try_forging" - ~msg: - "try forging locally the block header for {hash} (slot {priority}) for \ - {client} ({timestamp})" - ("hash", Block_hash.encoding) - ("priority", Data_encoding.int31) - ("client", Data_encoding.string) - ("timestamp", Time.System.encoding) - - let start_injecting_block = - declare_5 - ~section - ~level:Info - ~name:"start_injecting_block" - ~msg: - "injecting block (priority {priority}, fitness {fitness}) for {client} \ - after {predecessor}" - ~pp2:Fitness.pp - ("priority", Data_encoding.int31) - ("fitness", Fitness.encoding) - ("client", Data_encoding.string) - ("predecessor", Block_hash.encoding) - ("baker", Client_keys.Public_key_hash.encoding) - - let injected_block = - declare_7 - ~section - ~level - ~name:"injected_block" - ~msg: - "injected block {block_hash} for {client} after {predecessor} (level \ - {level}, priority {priority}, fitness {fitness}, operations \ - {operations})" - ~pp6:Fitness.pp - ~pp7:Format.(pp_print_list Operation.pp) - ("block_hash", Block_hash.encoding) - ("client", Data_encoding.string) - ("predecessor", Block_hash.encoding) - ("level", Alpha_context.Raw_level.encoding) - ("priority", Data_encoding.int31) - ("fitness", Fitness.encoding) - ("operations", Data_encoding.(list @@ dynamic_size Operation.encoding)) - - let baking_slot_fetch_errors = - declare_1 - ~section - ~level:Error - ~name:"baking_slot_fetch_errors" - ~msg:"error while fetching baking possibilities: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let no_slot_found = - declare_2 - ~section - ~level - ~name:"no_slot_found" - ~msg:"no slot found at level {level} (max_priority = {priority})" - ("level", Alpha_context.Raw_level.encoding) - ("priority", Data_encoding.int31) - - let have_baking_slot = - declare_6 - ~section - ~level - ~name:"have_baking_slot" - ~msg: - "new baking slot found (level {level}, priority {priority}) at \ - {timestamp} for {client} after {predecessor}" - ("level", Alpha_context.Raw_level.encoding) - ("priority", Data_encoding.int31) - ("timestamp", Time.System.encoding) - ("client", Data_encoding.string) - ("predecessor", Block_hash.encoding) - ("baker", Client_keys.Public_key_hash.encoding) - - let read_nonce_fail = - declare_1 - ~section - ~level:Error - ~name:"read_nonce_fail" - ~msg:"cannot read nonces: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let nonce_retrieval_fail = - declare_1 - ~section - ~level:Error - ~name:"nonce_retrieval_fail" - ~msg:"cannot retrieve unrevealed nonces: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let nonce_injection_fail = - declare_1 - ~section - ~level:Error - ~name:"nonce_injection_fail" - ~msg:"cannot inject nonces: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let retrying_on_error = - declare_1 - ~section - ~level:Error - ~name:"retrying_on_error" - ~msg:"retrying after baking error {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let endorsement_received = - declare_2 - ~section - ~level:Info - ~name:"endorsement_received" - ~msg:"received endorsement for slot {slot} (power: {power})" - ~pp1:Format.pp_print_int - ("slot", Data_encoding.int31) - ~pp2:Format.pp_print_int - ("power", Data_encoding.int31) - - let expected_validity_time = - declare_2 - ~section - ~name:"expected_validity_time" - ~level:Info - ~msg:"expected validity time: {time} (endorsing power: {power})" - ~pp1:Alpha_context.Timestamp.pp - ("time", Alpha_context.Timestamp.encoding) - ~pp2:Format.pp_print_int - ("power", Data_encoding.int31) - - let reading_per_block = - declare_1 - ~section - ~name:"reading_per_block" - ~level:Notice - ~msg:"reading per block vote file path: {path}" - ("path", Data_encoding.string) - - let per_block_vote_file_notice = - declare_1 - ~section - ~name:"per_block_vote_file_notice" - ~level:Notice - ~msg:"per block vote file {event}" - ("event", Data_encoding.string) - - let reading_liquidity_baking = - declare_0 - ~section - ~name:"reading_liquidity_baking" - ~level:Notice - ~msg:"reading liquidity baking escape vote" - () - - let liquidity_baking_escape_vote = - declare_1 - ~section - ~name:"liquidity_baking_escape_vote" - ~level:Notice - ~msg:"liquidity baking escape vote = {value}" - ("value", Data_encoding.bool) - - let per_block_vote_file_fail = - declare_1 - ~section - ~name:"per_block_vote_file_error" - ~level:Notice - ~msg:"Error reading the block vote file: {errors}" - ~pp1:pp_print_top_error_of_trace - ("errors", Error_monad.(TzTrace.encoding error_encoding)) - - let liquidity_baking_escape = - declare_0 - ~section - ~name:"liquidity_baking_continue" - ~level:Notice - ~msg:"Will vote to escape Liquidity Baking" - () - - let liquidity_baking_continue = - declare_0 - ~section - ~name:"liquidity_baking_escape" - ~level:Notice - ~msg:"Will vote to continue Liquidity Baking" - () -end - -module Endorsement = struct - include Internal_event.Simple - - let section = [Protocol.name; "delegate"; "endorsement"] - - let double_endorsement_near_miss = - declare_1 - ~section - ~level:Error - ~name:"double_endorsement_near_miss" - ~msg:"level {level}: previously endorsed" - ("level", Alpha_context.Raw_level.encoding) - - let injected_endorsement = - declare_5 - ~section - ~level - ~name:"injected_endorsement" - ~msg: - "injected endorsement for block '{block_hash}' (level {level}, \ - contract {client}) '{op_hash}'" - ("block_hash", Block_hash.encoding) - ("level", Alpha_context.Raw_level.encoding) - ("client", Data_encoding.string) - ("op_hash", Operation_hash.encoding) - ("baker", Client_keys.Public_key_hash.encoding) - - let endorsing = - declare_3 - ~section - ~level:Debug - ~name:"endorsing" - ~msg:"endorsing {block} for {client} (level {level})!" - ("block", Block_hash.encoding) - ("client", Data_encoding.string) - ("level", Alpha_context.Raw_level.encoding) - - let check_endorsement_ok = - declare_2 - ~section - ~level:Debug - ~name:"check_endorsement_ok" - ~msg:"checking if allowed to endorse block {block} for {client}" - ("block", Block_hash.encoding) - ("client", Data_encoding.string) - - let endorsement_no_slots_found = - declare_2 - ~section - ~level:Debug - ~name:"endorsement_no_slots_found" - ~msg:"no slot found for {block}/{client}" - ("block", Block_hash.encoding) - ("client", Data_encoding.string) - - let endorsement_slots_found = - declare_3 - ~section - ~level:Debug - ~name:"endorsement_slots_found" - ~msg:"found slots for {block}/{client} ({slots})" - ~pp3: - Format.( - fun fmt -> - fprintf - fmt - "[%a]" - (pp_print_list - ~pp_sep:(fun f () -> pp_print_string f "; ") - Format.pp_print_int)) - ("block", Block_hash.encoding) - ("client", Data_encoding.string) - ("slots", Data_encoding.list Data_encoding.int31) - - let previously_endorsed = - declare_1 - ~section - ~level:Debug - ~name:"previously_endorsed" - ~msg:"level {level} (or higher) previously endorsed: do not endorse" - ("level", Alpha_context.Raw_level.encoding) - - let endorsement_stale_block = - declare_1 - ~section - ~level:Info - ~name:"endorsement_stale_block" - ~msg:"ignore block {block}: forged too far the past" - ("block", Block_hash.encoding) - - let endorsement_got_block = - declare_1 - ~section - ~level:Info - ~name:"endorsement_got_block" - ~msg:"received new block {block}" - ("block", Block_hash.encoding) - - let wait_before_injecting = - declare_2 - ~section - ~level:Info - ~name:"wait_before_injecting" - ~msg:"waiting until {timestamp} ({timespan}) to inject endorsements" - ("timestamp", Time.System.encoding) - ("timespan", Time.System.Span.encoding) - - let error_while_endorsing = - declare_2 - ~section - ~level:Error - ~name:"error_while_endorsing" - ~msg:"error while injecting endorsement for baker {baker}: {errors}" - ~pp2:pp_print_top_error_of_trace - ("baker", Client_keys.Public_key_hash.encoding) - ("errors", Error_monad.(TzTrace.encoding error_encoding)) -end diff --git a/src/proto_012_Psithaca/lib_delegate/dune b/src/proto_012_Psithaca/lib_delegate/dune deleted file mode 100644 index 45399c741f9e..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/dune +++ /dev/null @@ -1,89 +0,0 @@ -(library - (name tezos_baking_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-baking-012-Psithaca) - (libraries tezos-base - tezos-version - tezos-protocol-012-Psithaca - tezos-protocol-environment - tezos-shell-context - tezos-shell-services - tezos-client-base - tezos-client-012-Psithaca - tezos-client-commands - tezos-stdlib - tezos-stdlib-unix - tezos-context - tezos-context.memory - tezos-rpc-http - tezos-rpc-http-client-unix - tezos-rpc - lwt-canceler - lwt-exit) - (library_flags (:standard -linkall)) - (modules (:standard \ - baking_commands - baking_commands_registration)) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_protocol_plugin_012_Psithaca - -open Tezos_shell_services - -open Tezos_client_base - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_stdlib - -open Tezos_stdlib_unix - -open Tezos_shell_context - -open Tezos_context - -open Tezos_rpc - -open Tezos_rpc_http))) - -(library - (name tezos_baking_012_Psithaca_commands) - (instrumentation (backend bisect_ppx)) - (public_name tezos-baking-012-Psithaca-commands) - (libraries tezos-base - tezos-protocol-012-Psithaca - tezos-protocol-environment - tezos-shell-services - tezos-client-base - tezos-client-012-Psithaca - tezos-client-commands - tezos-baking-012-Psithaca) - (library_flags (:standard -linkall)) - (modules baking_commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_stdlib_unix - -open Tezos_shell_services - -open Tezos_client_base - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_baking_012_Psithaca - -open Tezos_rpc))) - -(library - (name tezos_baking_012_Psithaca_commands_registration) - (instrumentation (backend bisect_ppx)) - (public_name tezos-baking-012-Psithaca-commands.registration) - (libraries tezos-base - tezos-protocol-012-Psithaca - tezos-protocol-environment - tezos-shell-services - tezos-client-base - tezos-client-012-Psithaca - tezos-client-commands - tezos-baking-012-Psithaca - tezos-baking-012-Psithaca-commands - tezos-rpc) - (library_flags (:standard -linkall)) - (modules baking_commands_registration) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_shell_services - -open Tezos_client_base - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_baking_012_Psithaca - -open Tezos_baking_012_Psithaca_commands - -open Tezos_rpc))) diff --git a/src/proto_012_Psithaca/lib_delegate/dune-project b/src/proto_012_Psithaca/lib_delegate/dune-project deleted file mode 100644 index d6286ff1f0d3..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-accuser-alpha-commands) diff --git a/src/proto_012_Psithaca/lib_delegate/liquidity_baking_vote_file.ml b/src/proto_012_Psithaca/lib_delegate/liquidity_baking_vote_file.ml deleted file mode 100644 index 57bc0ce5a187..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/liquidity_baking_vote_file.ml +++ /dev/null @@ -1,162 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol_client_context -module Events = Baking_events.Liquidity_baking - -type per_block_votes = {liquidity_baking_escape_vote : bool option} - -let per_block_votes_encoding = - let open Data_encoding in - def "per_block_votes.alpha" - @@ conv - (fun {liquidity_baking_escape_vote} -> liquidity_baking_escape_vote) - (fun liquidity_baking_escape_vote -> {liquidity_baking_escape_vote}) - (obj1 (opt "liquidity_baking_escape_vote" Data_encoding.bool)) - -type error += Block_vote_file_not_found of string - -type error += Block_vote_file_invalid of string - -type error += Block_vote_file_wrong_content of string - -type error += Block_vote_file_missing_liquidity_baking_escape_vote of string - -let () = - register_error_kind - `Permanent - ~id:"Client_baking_forge.block_vote_file_not_found" - ~title: - "The provided block vote file path does not point to an existing file." - ~description: - "A block vote file path was provided on the command line but the path \ - does not point to an existing file." - ~pp:(fun ppf file_path -> - Format.fprintf - ppf - "@[The provided block vote file path \"%s\" does not point to an \ - existing file.@]" - file_path) - Data_encoding.(obj1 (req "file_path" string)) - (function - | Block_vote_file_not_found file_path -> Some file_path | _ -> None) - (fun file_path -> Block_vote_file_not_found file_path) ; - register_error_kind - `Permanent - ~id:"Client_baking_forge.block_vote_file_invalid" - ~title: - "The provided block vote file path does not point to a valid JSON file." - ~description: - "A block vote file path was provided on the command line but the path \ - does not point to a valid JSON file." - ~pp:(fun ppf file_path -> - Format.fprintf - ppf - "@[The provided block vote file path \"%s\" does not point to a valid \ - JSON file. The file exists but its content is not valid JSON.@]" - file_path) - Data_encoding.(obj1 (req "file_path" string)) - (function Block_vote_file_invalid file_path -> Some file_path | _ -> None) - (fun file_path -> Block_vote_file_invalid file_path) ; - register_error_kind - `Permanent - ~id:"Client_baking_forge.block_vote_file_wrong_content" - ~title:"The content of the provided block vote file is unexpected." - ~description: - "The block vote file is valid JSON but its content is not the expected \ - one." - ~pp:(fun ppf file_path -> - Format.fprintf - ppf - "@[The provided block vote file \"%s\" is a valid JSON file but its \ - content is unexpected. Expecting a JSON file containing either \ - '{\"liquidity_baking_escape_vote\": true}' or \ - '{\"liquidity_baking_escape_vote\": false}'.@]" - file_path) - Data_encoding.(obj1 (req "file_path" string)) - (function - | Block_vote_file_wrong_content file_path -> Some file_path | _ -> None) - (fun file_path -> Block_vote_file_wrong_content file_path) ; - register_error_kind - `Permanent - ~id: - "Client_baking_forge.block_vote_file_missing_liquidity_baking_escape_vote" - ~title: - "In the provided block vote file, no entry for liquidity baking escape \ - vote was found" - ~description: - "In the provided block vote file, no entry for liquidity baking escape \ - vote was found." - ~pp:(fun ppf file_path -> - Format.fprintf - ppf - "@[In the provided block vote file \"%s\", the \ - \"liquidity_baking_escape_vote\" boolean field is missing. Expecting \ - a JSON file containing either '{\"liquidity_baking_escape_vote\": \ - true}' or '{\"liquidity_baking_escape_vote\": false}'.@]" - file_path) - Data_encoding.(obj1 (req "file_path" string)) - (function - | Block_vote_file_missing_liquidity_baking_escape_vote file_path -> - Some file_path - | _ -> None) - (fun file_path -> - Block_vote_file_missing_liquidity_baking_escape_vote file_path) - -let traced_option_to_result ~error = - Option.fold ~some:ok ~none:(Error_monad.error error) - -let check_file_exists file = - if Sys.file_exists file then Result.return_unit - else error (Block_vote_file_not_found file) - -let read_liquidity_baking_escape_vote ~per_block_vote_file = - Events.(emit reading_per_block) per_block_vote_file >>= fun () -> - check_file_exists per_block_vote_file >>?= fun () -> - trace (Block_vote_file_invalid per_block_vote_file) - @@ Lwt_utils_unix.Json.read_file per_block_vote_file - >>=? fun votes_json -> - Events.(emit per_block_vote_file_notice) "found" >>= fun () -> - trace (Block_vote_file_wrong_content per_block_vote_file) - @@ Error_monad.protect (fun () -> - return - @@ Data_encoding.Json.destruct per_block_votes_encoding votes_json) - >>=? fun votes -> - Events.(emit per_block_vote_file_notice) "JSON decoded" >>= fun () -> - traced_option_to_result - ~error: - (Block_vote_file_missing_liquidity_baking_escape_vote per_block_vote_file) - votes.liquidity_baking_escape_vote - >>?= fun liquidity_baking_escape_vote -> - Events.(emit reading_liquidity_baking) () >>= fun () -> - Events.(emit liquidity_baking_escape_vote) liquidity_baking_escape_vote - >>= fun () -> return liquidity_baking_escape_vote - -let read_liquidity_baking_escape_vote_no_fail ~default ~per_block_vote_file = - read_liquidity_baking_escape_vote ~per_block_vote_file >>= function - | Ok vote -> Lwt.return vote - | Error errs -> - Events.(emit per_block_vote_file_fail) errs >>= fun () -> - Lwt.return default diff --git a/src/proto_012_Psithaca/lib_delegate/logging.ml b/src/proto_012_Psithaca/lib_delegate/logging.ml deleted file mode 100644 index ed9cb18c9db3..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/logging.ml +++ /dev/null @@ -1,167 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -let timestamp_tag = - Tag.def ~doc:"Timestamp when event occurred" "timestamp" Time.System.pp_hum - -let valid_ops = Tag.def ~doc:"Valid Operations" "valid_ops" Format.pp_print_int - -let op_count = - Tag.def ~doc:"Number of operations" "op_count" Format.pp_print_int - -let refused_ops = - Tag.def ~doc:"Refused Operations" "refused_ops" Format.pp_print_int - -let bake_priority_tag = - Tag.def ~doc:"Baking priority" "bake_priority" Format.pp_print_int - -let fitness_tag = Tag.def ~doc:"Fitness" "fitness" Fitness.pp - -let current_slots_tag = - Tag.def - ~doc:"Number of baking slots that can be baked at this time" - "current_slots" - Format.pp_print_int - -let future_slots_tag = - Tag.def - ~doc:"Number of baking slots in the foreseeable future but not yet bakeable" - "future_slots" - Format.pp_print_int - -let timespan_tag = Tag.def ~doc:"Timespan in seconds" "timespan" Ptime.Span.pp - -let filename_tag = Tag.def ~doc:"Filename" "filename" Format.pp_print_text - -let signed_header_tag = - Tag.def ~doc:"Signed header" "signed_header" (fun fmt x -> - Hex.pp fmt (Hex.of_bytes x)) - -let signed_operation_tag = - Tag.def ~doc:"Signed operation" "signed_operation" (fun fmt x -> - Hex.pp fmt (Hex.of_bytes x)) - -let operations_tag = - Tag.def - ~doc:"Block Operations" - "operations" - (Format.pp_print_list - ~pp_sep:(fun ppf () -> Format.fprintf ppf "+") - (fun ppf operations -> Format.fprintf ppf "%d" (List.length operations))) - -let raw_operations_tag = - Tag.def ~doc:"Raw operations" "raw_operations" (fun fmt raw_ops -> - let pp_op fmt op = - let json = Data_encoding.Json.construct Operation.raw_encoding op in - Format.fprintf fmt "%a" Data_encoding.Json.pp json - in - Format.fprintf - fmt - "@[%a@]" - (Format.pp_print_list ~pp_sep:Format.pp_print_cut pp_op) - raw_ops) - -let bake_op_count_tag = - Tag.def ~doc:"Bake Operation Count" "operation_count" Format.pp_print_int - -let endorsement_slot_tag = - Tag.def ~doc:"Endorsement Slot" "endorsement_slot" Format.pp_print_int - -let endorsement_slots_tag = - Tag.def - ~doc:"Endorsement Slots" - "endorsement_slots" - Format.(fun ppf v -> pp_print_int ppf (List.length v)) - -let denounced_endorsements_slots_tag = - Tag.def - ~doc:"Endorsement Slots" - "denounced_endorsement_slots" - Format.(pp_print_list pp_print_int) - -let denouncement_source_tag = - Tag.def ~doc:"Denounce Source" "source" Format.pp_print_text - -let level_tag = Tag.def ~doc:"Level" "level" Raw_level.pp - -let nonce_tag = - Tag.def - ~doc:"Nonce" - "nonce" - Data_encoding.Json.( - fun ppf nonce -> pp ppf (construct Nonce.encoding nonce)) - -let chain_tag = - Tag.def - ~doc:"Chain selector" - "chain" - Format.( - fun ppf chain -> - pp_print_string ppf @@ Block_services.chain_to_string chain) - -let block_tag = - Tag.def - ~doc:"Block selector" - "block" - Format.( - fun ppf block -> pp_print_string ppf @@ Block_services.to_string block) - -let worker_tag = - Tag.def ~doc:"Worker in which event occurred" "worker" Format.pp_print_text - -let block_header_tag = - Tag.def ~doc:"Raw block header" "block_header" (fun ppf _ -> - Format.fprintf ppf "[raw block header]") - -let conflicting_endorsements_tag = - Tag.def - ~doc:"Two conflicting endorsements signed by the same key" - "conflicting_endorsements" - Format.( - fun ppf (a, b) -> - fprintf - ppf - "%a / %a" - Operation_hash.pp - (Operation.hash a) - Operation_hash.pp - (Operation.hash b)) - -let conflicting_preendorsements_tag = - Tag.def - ~doc:"Two conflicting preendorsements signed by the same key" - "conflicting_preendorsements" - Format.( - fun ppf (a, b) -> - fprintf - ppf - "%a / %a" - Operation_hash.pp - (Operation.hash a) - Operation_hash.pp - (Operation.hash b)) diff --git a/src/proto_012_Psithaca/lib_delegate/logging.mli b/src/proto_012_Psithaca/lib_delegate/logging.mli deleted file mode 100644 index 5e10680ae612..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/logging.mli +++ /dev/null @@ -1,83 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -val timestamp_tag : Time.System.t Tag.def - -val valid_ops : int Tag.def - -val op_count : int Tag.def - -val refused_ops : int Tag.def - -val bake_priority_tag : int Tag.def - -val fitness_tag : Fitness.t Tag.def - -val current_slots_tag : int Tag.def - -val future_slots_tag : int Tag.def - -val timespan_tag : Time.System.Span.t Tag.def - -val filename_tag : string Tag.def - -val signed_header_tag : Bytes.t Tag.def - -val signed_operation_tag : Bytes.t Tag.def - -val operations_tag : Tezos_base.Operation.t list list Tag.def - -val raw_operations_tag : Operation.raw list Tag.def - -val bake_op_count_tag : int Tag.def - -val endorsement_slot_tag : int Tag.def - -val endorsement_slots_tag : int list Tag.def - -val denounced_endorsements_slots_tag : int list Tag.def - -val denouncement_source_tag : string Tag.def - -val level_tag : Raw_level.t Tag.def - -val nonce_tag : Nonce.t Tag.def - -val chain_tag : Block_services.chain Tag.def - -val block_tag : Block_services.block Tag.def - -val worker_tag : string Tag.def - -val block_header_tag : Block_header.t Tag.def - -val conflicting_endorsements_tag : - (Kind.endorsement operation * Kind.endorsement operation) Tag.def - -val conflicting_preendorsements_tag : - (Kind.preendorsement operation * Kind.preendorsement operation) Tag.def diff --git a/src/proto_012_Psithaca/lib_delegate/node_rpc.ml b/src/proto_012_Psithaca/lib_delegate/node_rpc.ml deleted file mode 100644 index cc250824a6ec..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/node_rpc.ml +++ /dev/null @@ -1,200 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -module Block_services = Block_services.Make (Protocol) (Protocol) -module Events = Baking_events.Node_rpc - -let inject_block cctxt ?(force = false) ~chain signed_block_header operations = - let signed_shell_header_bytes = - Data_encoding.Binary.to_bytes_exn Block_header.encoding signed_block_header - in - Shell_services.Injection.block - cctxt - ~chain - ~force - signed_shell_header_bytes - operations - -let preapply_block cctxt ~chain ~head ~timestamp ~protocol_data operations = - Block_services.Helpers.Preapply.block - cctxt - ~chain - ~timestamp - ~block:(`Hash (head, 0)) - operations - ~protocol_data - -let extract_prequorum preendorsements = - match preendorsements with - | h :: _ as l -> - let ({protocol_data = {contents = Single (Preendorsement content); _}; _}) - = - (h : Kind.preendorsement Operation.t) - in - Some - { - Baking_state.level = Raw_level.to_int32 content.level; - round = content.round; - block_payload_hash = content.block_payload_hash; - preendorsements = l; - } - | _ -> None - -let raw_info cctxt ~chain ~block_hash shell payload_hash payload_round - current_protocol next_protocol live_blocks = - Events.(emit raw_info (block_hash, shell.Tezos_base.Block_header.level)) - >>= fun () -> - let open Protocol_client_context in - let block = `Hash (block_hash, 0) in - let is_in_protocol = Protocol_hash.(current_protocol = Protocol.hash) in - (if is_in_protocol then - Alpha_block_services.Operations.operations cctxt ~chain ~block () - >>=? fun operations -> - let operations = - List.map - (fun l -> - List.map - (fun {Alpha_block_services.shell; protocol_data; _} -> - {Alpha_context.shell; protocol_data}) - l) - operations - in - match Operation_pool.extract_operations_of_list_list operations with - | None -> failwith "Unexpected operation list size" - | Some operations -> return operations - else - (* If we are not in the current protocol, do no consider operations *) - return (None, [], Operation_pool.empty_payload)) - >>=? fun (preendorsements, quorum, payload) -> - (if is_in_protocol then Baking_state.round_of_shell_header shell - else (* If we are not in the current protocol, the round is 0 *) - ok Round.zero) - >>?= fun round -> - let prequorum = - Option.fold ~none:None ~some:extract_prequorum preendorsements - in - return - { - Baking_state.hash = block_hash; - shell; - payload_hash; - payload_round; - round; - protocol = current_protocol; - next_protocol; - prequorum; - quorum; - payload; - live_blocks; - } - -let dummy_payload_hash = Block_payload_hash.zero - -let info cctxt ~chain ~block () = - let open Protocol_client_context in - (* Fails if the block's protocol is not the current one *) - Shell_services.Blocks.protocols cctxt ~chain ~block () - >>=? fun {current_protocol; next_protocol} -> - (if Protocol_hash.(current_protocol <> Protocol.hash) then - Block_services.Header.shell_header cctxt ~chain ~block () >>=? fun shell -> - Chain_services.Blocks.Header.raw_protocol_data cctxt ~chain ~block () - >>=? fun protocol_data -> - let hash = - Tezos_base.Block_header.hash {Tezos_base.Block_header.shell; protocol_data} - in - let payload_hash = - (* If the protocol is not the same, then we won't need to use - the payload_hash *) - dummy_payload_hash - in - return (hash, shell, payload_hash, Round.zero) - else - Alpha_block_services.header cctxt ~chain ~block () - >>=? fun {hash; shell; protocol_data; _} -> - return - ( hash, - shell, - protocol_data.contents.payload_hash, - protocol_data.contents.payload_round )) - >>=? fun (hash, shell, payload_hash, payload_round) -> - (Chain_services.Blocks.live_blocks cctxt ~chain ~block () >>= function - | Error _ -> - (* The RPC might fail when a block's metadata is not available *) - Lwt.return Block_hash.Set.empty - | Ok live_blocks -> Lwt.return live_blocks) - >>= fun live_blocks -> - raw_info - cctxt - ~chain - ~block_hash:hash - shell - payload_hash - payload_round - current_protocol - next_protocol - live_blocks - -let find_in_cache_or_fetch cctxt ?cache ~chain block_hash = - let open Baking_cache in - let fetch () = info cctxt ~chain ~block:(`Hash (block_hash, 0)) () in - match cache with - | None -> fetch () - | Some block_cache -> ( - match Block_cache.find_opt block_cache block_hash with - | Some block_info -> return block_info - | None -> - fetch () >>=? fun block_info -> - Block_cache.replace block_cache block_hash block_info ; - return block_info) - -let proposal cctxt ?cache ~chain block_hash = - find_in_cache_or_fetch cctxt ~chain ?cache block_hash >>=? fun block -> - let predecessor_hash = block.shell.predecessor in - find_in_cache_or_fetch cctxt ~chain ?cache predecessor_hash - >>=? fun predecessor -> return {Baking_state.block; predecessor} - -let monitor_proposals cctxt ~chain () = - let cache = Baking_cache.Block_cache.create 100 in - Monitor_services.heads cctxt ~next_protocols:[Protocol.hash] chain - >>=? fun (block_stream, stopper) -> - return - ( Lwt_stream.filter_map_s - (fun (block_hash, _) -> - protect (fun () -> proposal cctxt ~cache ~chain block_hash) - >>= function - | Ok proposal -> Lwt.return_some proposal - | Error err -> - Events.(emit error_while_monitoring_heads err) >>= fun () -> - Lwt.return_none) - block_stream, - stopper ) - -let await_protocol_activation cctxt ~chain () = - Monitor_services.heads cctxt ~next_protocols:[Protocol.hash] chain - >>=? fun (_block_stream, stop) -> - stop () ; - return_unit diff --git a/src/proto_012_Psithaca/lib_delegate/node_rpc.mli b/src/proto_012_Psithaca/lib_delegate/node_rpc.mli deleted file mode 100644 index 1c4b0f493a82..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/node_rpc.mli +++ /dev/null @@ -1,76 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -(** Inject a block. - - @param force defaults to [false] - @return block hash of the newly injected block -*) -val inject_block : - #Protocol_client_context.full -> - ?force:bool -> - chain:Shell_services.chain -> - Block_header.t -> - Tezos_base.Operation.t list list -> - Block_hash.t tzresult Lwt.t - -(** Preapply a block using the node validation mechanism.*) -val preapply_block : - #Protocol_client_context.full -> - chain:Shell_services.chain -> - head:Block_hash.t -> - timestamp:Time.Protocol.t -> - protocol_data:Protocol.block_header_data -> - packed_operation list list -> - (Tezos_base.Block_header.shell_header * error Preapply_result.t list) tzresult - Lwt.t - -(** Fetch a proposal from the node. - - @param cache is unset by default -*) -val proposal : - #RPC_context.simple -> - ?cache:Baking_state.block_info Baking_cache.Block_cache.t -> - chain:Shell_services.chain -> - Block_hash.t -> - Baking_state.proposal tzresult Lwt.t - -(** Monitor proposals from the node.*) -val monitor_proposals : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - unit -> - (Baking_state.proposal Lwt_stream.t * (unit -> unit)) tzresult Lwt.t - -(** Await the current protocol to be activated. *) -val await_protocol_activation : - #Protocol_client_context.rpc_context -> - chain:Shell_services.chain -> - unit -> - unit tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/operation_pool.ml b/src/proto_012_Psithaca/lib_delegate/operation_pool.ml deleted file mode 100644 index e680d7328aa6..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/operation_pool.ml +++ /dev/null @@ -1,327 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -(* Should we use a better ordering ? *) - -module OpSet = Set.Make (struct - type t = packed_operation - - let compare = compare -end) - -(* TODO refine this: unpack operations *) -type pool = { - consensus : OpSet.t; - votes : OpSet.t; - anonymous : OpSet.t; - managers : OpSet.t; -} - -(* TODO refine this: unpack operations *) -type ordered_pool = { - ordered_consensus : packed_operation list; - ordered_votes : packed_operation list; - ordered_anonymous : packed_operation list; - ordered_managers : packed_operation list; -} - -let ordered_pool_encoding = - let open Data_encoding in - conv - (fun {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers} -> - (ordered_consensus, ordered_votes, ordered_anonymous, ordered_managers)) - (fun (ordered_consensus, ordered_votes, ordered_anonymous, ordered_managers) -> - {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers}) - (obj4 - (req "ordered_consensus" (list (dynamic_size Operation.encoding))) - (req "ordered_votes" (list (dynamic_size Operation.encoding))) - (req "ordered_payload" (list (dynamic_size Operation.encoding))) - (req "ordered_payload" (list (dynamic_size Operation.encoding)))) - -type payload = { - votes_payload : packed_operation list; - anonymous_payload : packed_operation list; - managers_payload : packed_operation list; -} - -let empty_payload = - {votes_payload = []; anonymous_payload = []; managers_payload = []} - -let payload_encoding = - let open Data_encoding in - conv - (fun {votes_payload; anonymous_payload; managers_payload} -> - (votes_payload, anonymous_payload, managers_payload)) - (fun (votes_payload, anonymous_payload, managers_payload) -> - {votes_payload; anonymous_payload; managers_payload}) - (obj3 - (req "votes_payload" (list (dynamic_size Operation.encoding))) - (req "anonymous_payload" (list (dynamic_size Operation.encoding))) - (req "managers_payload" (list (dynamic_size Operation.encoding)))) - -let pp_payload fmt {votes_payload; anonymous_payload; managers_payload} = - Format.fprintf - fmt - "[votes: %d, anonymous: %d, managers: %d]" - (List.length votes_payload) - (List.length anonymous_payload) - (List.length managers_payload) - -let empty = - { - consensus = OpSet.empty; - votes = OpSet.empty; - anonymous = OpSet.empty; - managers = OpSet.empty; - } - -let empty_ordered = - { - ordered_consensus = []; - ordered_votes = []; - ordered_anonymous = []; - ordered_managers = []; - } - -let pp_pool fmt {consensus; votes; anonymous; managers} = - Format.fprintf - fmt - "[consensus: %d, votes: %d, anonymous: %d, managers: %d]" - (OpSet.cardinal consensus) - (OpSet.cardinal votes) - (OpSet.cardinal anonymous) - (OpSet.cardinal managers) - -let pp_ordered_pool fmt - {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers} = - Format.fprintf - fmt - "[consensus: %d, votes: %d, anonymous: %d, managers: %d]" - (List.length ordered_consensus) - (List.length ordered_votes) - (List.length ordered_anonymous) - (List.length ordered_managers) - -(* Hypothesis : we suppose [List.length Protocol.Main.validation_passes = 4] *) -let consensus_index = 0 - -let votes_index = 1 - -let anonymous_index = 2 - -let managers_index = 3 - -let classify op = - (* Hypothesis: acceptable passes returns a size at most 1 list *) - match Main.acceptable_passes op with - | [pass] -> - if pass = consensus_index then `Consensus - (* TODO filter outdated consensus ops ? *) - else if pass = votes_index then `Votes - else if pass = anonymous_index then `Anonymous - else if pass = managers_index then `Managers - else `Bad - | _ -> `Bad - -let add_operation pool op = - match classify op with - | `Consensus -> - let consensus = OpSet.add op pool.consensus in - {pool with consensus} - | `Votes -> - let votes = OpSet.add op pool.votes in - {pool with votes} - | `Anonymous -> - let anonymous = OpSet.add op pool.anonymous in - {pool with anonymous} - | `Managers -> - let managers = OpSet.add op pool.managers in - {pool with managers} - | `Bad -> pool - -let add_operations pool new_ops = List.fold_left add_operation pool new_ops - -type consensus_filter = { - level : int32; - round : Round.t; - payload_hash : Block_payload_hash.t; -} - -(** From a pool of operations [operation_pool], the function filters - out the endorsements that are different from the [current_level], - the [current_round] or the optional [current_block_payload_hash], - as well as preendorsements. *) -let filter_with_relevant_consensus_ops ~(endorsement_filter : consensus_filter) - ~(preendorsement_filter : consensus_filter option) operation_set = - OpSet.filter - (fun {protocol_data; _} -> - match (protocol_data, preendorsement_filter) with - (* 1a. Remove preendorsements. *) - | (Operation_data {contents = Single (Preendorsement _); _}, None) -> - false - (* 1b. Filter preendorsements. *) - | ( Operation_data - { - contents = - Single (Preendorsement {level; round; block_payload_hash; _}); - _; - }, - Some - {level = level'; round = round'; payload_hash = block_payload_hash'} - ) -> - Compare.Int32.(Raw_level.to_int32 level = level') - && Round.(round = round') - && Block_payload_hash.(block_payload_hash = block_payload_hash') - (* 2. Filter endorsements. *) - | ( Operation_data - { - contents = - Single (Endorsement {level; round; block_payload_hash; _}); - _; - }, - _ ) -> - Compare.Int32.(Raw_level.to_int32 level = endorsement_filter.level) - && Round.(round = endorsement_filter.round) - && Block_payload_hash.( - block_payload_hash = endorsement_filter.payload_hash) - (* 3. Preserve all non-consensus operations. *) - | _ -> true) - operation_set - -let unpack_preendorsement packed_preendorsement = - let {shell; protocol_data = Operation_data data} = packed_preendorsement in - match data with - | {contents = Single (Preendorsement _); _} -> - Some ({shell; protocol_data = data} : Kind.preendorsement Operation.t) - | _ -> None - -let unpack_endorsement packed_endorsement = - let {shell; protocol_data = Operation_data data} = packed_endorsement in - match data with - | {contents = Single (Endorsement _); _} -> - Some ({shell; protocol_data = data} : Kind.endorsement Operation.t) - | _ -> None - -let filter_preendorsements ops = - List.filter_map - (function - | { - shell = {branch}; - protocol_data = - Operation_data - ({contents = Single (Preendorsement _); _} as content); - _; - } -> - Some - ({shell = {branch}; protocol_data = content} - : Kind.preendorsement operation) - | _ -> None) - ops - -let filter_endorsements ops = - List.filter_map - (function - | { - shell = {branch}; - protocol_data = - Operation_data ({contents = Single (Endorsement _); _} as content); - _; - } -> - Some - ({shell = {branch}; protocol_data = content} - : Kind.endorsement operation) - | _ -> None) - ops - -let pool_to_list_list {consensus; votes; anonymous; managers} = - List.map OpSet.elements [consensus; votes; anonymous; managers] - -let pool_of_list_list (ll : packed_operation list list) = - List.fold_left add_operations empty ll - -let ordered_to_list_list - {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers} = - [ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers] - -let ordered_of_list_list = function - | [ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers] -> - Some - {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers} - | _ -> None - -let payload_of_ordered_pool - {ordered_votes; ordered_anonymous; ordered_managers; _} = - { - votes_payload = ordered_votes; - anonymous_payload = ordered_anonymous; - managers_payload = ordered_managers; - } - -let ordered_pool_of_payload ~consensus_operations - {votes_payload; anonymous_payload; managers_payload} = - { - ordered_consensus = consensus_operations; - ordered_votes = votes_payload; - ordered_anonymous = anonymous_payload; - ordered_managers = managers_payload; - } - -let extract_operations_of_list_list = function - | [consensus; votes_payload; anonymous_payload; managers_payload] -> - let (preendorsements, endorsements) = - List.fold_left - (fun ( (preendorsements : Kind.preendorsement Operation.t list), - (endorsements : Kind.endorsement Operation.t list) ) - packed_op -> - let {shell; protocol_data = Operation_data data} = packed_op in - match data with - | {contents = Single (Preendorsement _); _} -> - ({shell; protocol_data = data} :: preendorsements, endorsements) - | {contents = Single (Endorsement _); _} -> - (preendorsements, {shell; protocol_data = data} :: endorsements) - | _ -> - (* unreachable *) - (preendorsements, endorsements)) - ([], []) - consensus - (* N.b. the order doesn't matter *) - in - let preendorsements = - if preendorsements = [] then None else Some preendorsements - in - let payload = {votes_payload; anonymous_payload; managers_payload} in - Some (preendorsements, endorsements, payload) - | _ -> None - -let filter_pool p {consensus; votes; anonymous; managers} = - { - consensus = OpSet.filter p consensus; - votes = OpSet.filter p votes; - anonymous = OpSet.filter p anonymous; - managers = OpSet.filter p managers; - } diff --git a/src/proto_012_Psithaca/lib_delegate/operation_pool.mli b/src/proto_012_Psithaca/lib_delegate/operation_pool.mli deleted file mode 100644 index 54d8501cd6e9..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/operation_pool.mli +++ /dev/null @@ -1,123 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -val consensus_index : int - -val votes_index : int - -val anonymous_index : int - -val managers_index : int - -module OpSet : Set.S with type elt = packed_operation - -type pool = { - consensus : OpSet.t; - votes : OpSet.t; - anonymous : OpSet.t; - managers : OpSet.t; -} - -val empty : pool - -val pp_pool : Format.formatter -> pool -> unit - -val pool_to_list_list : pool -> packed_operation list list - -val pool_of_list_list : packed_operation list list -> pool - -val filter_pool : (packed_operation -> bool) -> pool -> pool - -type ordered_pool = { - ordered_consensus : packed_operation list; - ordered_votes : packed_operation list; - ordered_anonymous : packed_operation list; - ordered_managers : packed_operation list; -} - -val ordered_pool_encoding : ordered_pool Data_encoding.t - -val empty_ordered : ordered_pool - -val pp_ordered_pool : Format.formatter -> ordered_pool -> unit - -type payload = { - votes_payload : packed_operation list; - anonymous_payload : packed_operation list; - managers_payload : packed_operation list; -} - -val empty_payload : payload - -val payload_encoding : payload Data_encoding.t - -val pp_payload : Format.formatter -> payload -> unit - -val payload_of_ordered_pool : ordered_pool -> payload - -val ordered_pool_of_payload : - consensus_operations:packed_operation list -> payload -> ordered_pool - -val add_operation : pool -> packed_operation -> pool - -val add_operations : pool -> packed_operation list -> pool - -type consensus_filter = { - level : int32; - round : Round.t; - payload_hash : Block_payload_hash.t; -} - -val filter_with_relevant_consensus_ops : - endorsement_filter:consensus_filter -> - preendorsement_filter:consensus_filter option -> - OpSet.t -> - OpSet.t - -val unpack_preendorsement : - packed_operation -> Kind.preendorsement operation option - -val unpack_endorsement : packed_operation -> Kind.endorsement operation option - -val filter_preendorsements : - packed_operation list -> Kind.preendorsement operation list - -val filter_endorsements : - packed_operation list -> Kind.endorsement operation list - -val ordered_to_list_list : ordered_pool -> packed_operation list list - -val ordered_of_list_list : packed_operation list list -> ordered_pool option - -(** [preendorsements] <> None => (List.length preendorsements > 0) *) -val extract_operations_of_list_list : - packed_operation list list -> - (Kind.preendorsement operation list option - * Kind.endorsement operation list - * payload) - option diff --git a/src/proto_012_Psithaca/lib_delegate/operation_selection.ml b/src/proto_012_Psithaca/lib_delegate/operation_selection.ml deleted file mode 100644 index 103165683567..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/operation_selection.ml +++ /dev/null @@ -1,316 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Operation_pool - -let quota = Main.validation_passes - -let consensus_quota = Stdlib.List.nth quota Operation_pool.consensus_index - -let votes_quota = Stdlib.List.nth quota Operation_pool.votes_index - -let anonymous_quota = Stdlib.List.nth quota Operation_pool.anonymous_index - -let managers_quota = Stdlib.List.nth quota Operation_pool.managers_index - -type weighted_manager = { - op : packed_operation; - size : int; - fee : Tez.t; - gas : Fixed_point_repr.integral_tag Gas.Arith.t; - weight : Q.t; - source : public_key_hash; - counter : counter; -} - -module WeightedManagerSet = Set.Make (struct - type t = weighted_manager - - (* We order the operations by their weights except if they belong - to the same manager, if they do, we order them by their - counter. *) - let compare {source; counter; weight; _} - {source = source'; counter = counter'; weight = weight'; _} = - (* Be careful with the [compare] *) - let cmp_src = Signature.Public_key_hash.compare source source' in - if cmp_src = 0 then - (* we want the smallest counter first *) - let c = Z.compare counter counter' in - if c <> 0 then c else Q.compare weight' weight - (* if same counter, biggest weight first *) - else - (* We want the biggest weight first *) - let c = Q.compare weight' weight in - if c <> 0 then c else cmp_src -end) - -let weight_manager ~max_size ~hard_gas_limit_per_block ~minimal_fees - ~minimal_nanotez_per_gas_unit ~minimal_nanotez_per_byte op = - let {protocol_data = Operation_data {contents; _}; _} = op in - let open Operation in - let l = to_list (Contents_list contents) in - List.fold_left_e - (fun ((first_source, first_counter, total_fee, total_gas) as acc) -> - function - | Contents (Manager_operation {source; counter; fee; gas_limit; _}) -> - (Environment.wrap_tzresult @@ Tez.(total_fee +? fee)) - >>? fun total_fee -> - (* There is only one unique source per packed transaction *) - let first_source = Option.value ~default:source first_source in - (* We only care about the first counter *) - let first_counter = Option.value ~default:counter first_counter in - ok - ( Some first_source, - Some first_counter, - total_fee, - Gas.Arith.add total_gas gas_limit ) - | _ -> ok acc) - (None, None, Tez.zero, Gas.Arith.zero) - l - |> function - | Ok (Some source, Some counter, fee, gas) -> - if Tez.(fee < minimal_fees) then None - else - let size = Data_encoding.Binary.length Operation.encoding op in - let size_f = Q.of_int size in - let gas_f = Q.of_bigint (Gas.Arith.integral_to_z gas) in - let fee_f = Q.of_int64 (Tez.to_mutez fee) in - let size_ratio = Q.(size_f / Q.of_int max_size) in - let gas_ratio = - Q.( - gas_f - / Q.of_bigint (Gas.Arith.integral_to_z hard_gas_limit_per_block)) - in - let weight = Q.(fee_f / max size_ratio gas_ratio) in - let fees_in_nanotez = - Q.mul (Q.of_int64 (Tez.to_mutez fee)) (Q.of_int 1000) - in - let enough_fees_for_gas = - let minimal_fees_in_nanotez = - Q.mul - minimal_nanotez_per_gas_unit - (Q.of_bigint @@ Gas.Arith.integral_to_z gas) - in - Q.compare minimal_fees_in_nanotez fees_in_nanotez <= 0 - in - let enough_fees_for_size = - let minimal_fees_in_nanotez = - Q.mul minimal_nanotez_per_byte (Q.of_int size) - in - Q.compare minimal_fees_in_nanotez fees_in_nanotez <= 0 - in - if enough_fees_for_size && enough_fees_for_gas then - Some {op; size; weight; fee; gas; source; counter} - else None - | _ -> None - -let weight_managers ~hard_gas_limit_per_block ~minimal_fees - ~minimal_nanotez_per_gas_unit ~minimal_nanotez_per_byte managers = - OpSet.fold - (fun op acc -> - match - weight_manager - ~max_size:managers_quota.max_size - ~hard_gas_limit_per_block - ~minimal_fees - ~minimal_nanotez_per_gas_unit - ~minimal_nanotez_per_byte - op - with - | None -> acc - | Some w_op -> WeightedManagerSet.add w_op acc) - managers - WeightedManagerSet.empty - -(** Simulation *) - -type simulation_result = { - validation_result : Tezos_protocol_environment.validation_result; - block_header_metadata : block_header_metadata; - operations : packed_operation list list; - operations_hash : Operation_list_list_hash.t; -} - -let validate_operation inc op = - Baking_simulator.add_operation inc op >>= function - | Error _errs -> - (* TODO: log debug *) - (* "@[Client-side validation: filtered invalid operation %a@\n\ - * %a@]" - *) - Lwt.return_none - | Ok (resulting_state, receipt) -> ( - try - (* Check that the metadata are serializable/deserializable *) - let _ = - Data_encoding.Binary.( - of_bytes_exn - Protocol.operation_receipt_encoding - (to_bytes_exn Protocol.operation_receipt_encoding receipt)) - in - Lwt.return_some resulting_state - with _exn -> - (* TODO: log debug *) - (* f "Client-side validation: filtered invalid operation %a" - * -% t event "baking_rejected_invalid_operation" - * -% a - * errs_tag - * [ Validation_errors.Cannot_serialize_operation_metadata; - * Exn exn ]) - * >>= fun () -> *) - Lwt.return_none) - -let filter_valid_operations_up_to_quota inc (ops, quota) = - let {Environment_context.max_size; max_op} = quota in - let exception Full of (Baking_simulator.incremental * packed_operation list) - in - try - List.fold_left_s - (fun (inc, curr_size, nb_ops, acc) op -> - let op_size = - Data_encoding.Binary.length Alpha_context.Operation.encoding op - in - let new_size = curr_size + op_size in - if new_size > max_size then Lwt.return (inc, curr_size, nb_ops, acc) - else ( - Option.iter - (fun max_op -> if max_op = nb_ops + 1 then raise (Full (inc, acc))) - max_op ; - validate_operation inc op >>= function - | None -> Lwt.return (inc, curr_size, nb_ops, acc) - | Some inc' -> Lwt.return (inc', new_size, nb_ops + 1, op :: acc))) - (inc, 0, 0, []) - ops - >>= fun (inc, _, _, l) -> Lwt.return (inc, List.rev l) - with Full (inc, l) -> Lwt.return (inc, List.rev l) - -let filter_operations_with_simulation initial_inc fees_config - ~hard_gas_limit_per_block {consensus; votes; anonymous; managers} = - let { - Baking_configuration.minimal_fees; - minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte; - } = - fees_config - in - filter_valid_operations_up_to_quota - initial_inc - (OpSet.elements consensus, consensus_quota) - >>= fun (inc, consensus) -> - filter_valid_operations_up_to_quota inc (OpSet.elements votes, votes_quota) - >>= fun (inc, votes) -> - filter_valid_operations_up_to_quota - inc - (OpSet.elements anonymous, anonymous_quota) - >>= fun (inc, anonymous) -> - (* Sort the managers *) - let weighted_managers = - weight_managers - ~hard_gas_limit_per_block - ~minimal_fees - ~minimal_nanotez_per_gas_unit - ~minimal_nanotez_per_byte - managers - in - filter_valid_operations_up_to_quota - inc - ( WeightedManagerSet.elements weighted_managers - |> List.map (fun {op; _} -> op), - managers_quota ) - >>= fun (inc, managers) -> - let operations = [consensus; votes; anonymous; managers] in - let operations_hash = - Operation_list_list_hash.compute - (List.map - (fun sl -> - Operation_list_hash.compute (List.map Operation.hash_packed sl)) - operations) - in - let inc = {inc with header = {inc.header with operations_hash}} in - Baking_simulator.finalize_construction inc - >>=? fun (validation_result, block_header_metadata) -> - return {validation_result; block_header_metadata; operations; operations_hash} - -let filter_valid_operations_up_to_quota_without_simulation (ops, quota) = - let {Environment_context.max_size; max_op} = quota in - let exception Full of packed_operation list in - try - List.fold_left - (fun (curr_size, nb_ops, acc) op -> - let op_size = - Data_encoding.Binary.length Alpha_context.Operation.encoding op - in - let new_size = curr_size + op_size in - if new_size > max_size then (curr_size, nb_ops, acc) - else ( - Option.iter - (fun max_op -> if max_op = nb_ops + 1 then raise (Full acc)) - max_op ; - (new_size, nb_ops + 1, op :: acc))) - (0, 0, []) - ops - |> fun (_, _, l) -> List.rev l - with Full l -> List.rev l - -let filter_operations_without_simulation fees_config ~hard_gas_limit_per_block - {consensus; votes; anonymous; managers} = - let consensus = - filter_valid_operations_up_to_quota_without_simulation - (OpSet.elements consensus, consensus_quota) - in - let votes = - filter_valid_operations_up_to_quota_without_simulation - (OpSet.elements votes, votes_quota) - in - let anonymous = - filter_valid_operations_up_to_quota_without_simulation - (OpSet.elements anonymous, anonymous_quota) - in - let { - Baking_configuration.minimal_fees; - minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte; - } = - fees_config - in - (* Sort the managers *) - let weighted_managers = - weight_managers - ~hard_gas_limit_per_block - ~minimal_fees - ~minimal_nanotez_per_gas_unit - ~minimal_nanotez_per_byte - managers - in - let managers = - filter_valid_operations_up_to_quota_without_simulation - ( WeightedManagerSet.elements weighted_managers - |> List.map (fun {op; _} -> op), - managers_quota ) - in - let operations = [consensus; votes; anonymous; managers] in - operations diff --git a/src/proto_012_Psithaca/lib_delegate/operation_selection.mli b/src/proto_012_Psithaca/lib_delegate/operation_selection.mli deleted file mode 100644 index 1159a6cba704..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/operation_selection.mli +++ /dev/null @@ -1,48 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Environment_context - -type simulation_result = { - validation_result : validation_result; - block_header_metadata : Apply_results.block_metadata; - operations : packed_operation list list; - operations_hash : Operation_list_list_hash.t; -} - -val filter_operations_with_simulation : - Baking_simulator.incremental -> - Baking_configuration.fees_config -> - hard_gas_limit_per_block:Gas.Arith.integral -> - Operation_pool.pool -> - simulation_result tzresult Lwt.t - -val filter_operations_without_simulation : - Baking_configuration.fees_config -> - hard_gas_limit_per_block:Gas.Arith.integral -> - Operation_pool.pool -> - packed_operation list list diff --git a/src/proto_012_Psithaca/lib_delegate/operation_worker.ml b/src/proto_012_Psithaca/lib_delegate/operation_worker.ml deleted file mode 100644 index da6b8444748d..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/operation_worker.ml +++ /dev/null @@ -1,658 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* TODO: - add events + - running state introspection to recover/restart on failure - - Do we need a mutex ? -*) - -open Protocol_client_context -open Protocol -open Alpha_context - -module Events = struct - include Internal_event.Simple - - let section = [Protocol.name; "baker"; "operation_worker"] - - let pp_int = Format.pp_print_int - - let loop_failed = - declare_1 - ~section - ~name:"loop_failed" - ~level:Error - ~msg:"loop failed with {trace}" - ~pp1:Error_monad.pp_print_trace - ("trace", Error_monad.trace_encoding) - - let ended = - declare_1 - ~section - ~name:"ended" - ~level:Error - ~msg:"ended with error {stacktrace}" - ("stacktrace", Data_encoding.string) - - let pqc_reached = - declare_2 - ~section - ~name:"pqc_reached" - ~level:Debug - ~msg: - "pre-quorum reached (voting power: {voting_power}, {preendorsements} \ - preendorsements)" - ~pp1:pp_int - ("voting_power", Data_encoding.int31) - ~pp2:pp_int - ("preendorsements", Data_encoding.int31) - - let preendorsements_received = - declare_4 - ~section - ~name:"preendorsements_received" - ~level:Debug - ~msg: - "received {count} preendorsements (power: {delta_power}) (total voting \ - power: {voting_power}, {preendorsements} preendorsements)" - ~pp1:pp_int - ("count", Data_encoding.int31) - ~pp2:pp_int - ("delta_power", Data_encoding.int31) - ~pp3:pp_int - ("voting_power", Data_encoding.int31) - ~pp4:pp_int - ("preendorsements", Data_encoding.int31) - - let qc_reached = - declare_2 - ~section - ~name:"qc_reached" - ~level:Debug - ~msg: - "quorum reached (voting power: {voting_power}, {endorsements} \ - endorsements)" - ~pp1:pp_int - ("voting_power", Data_encoding.int31) - ~pp2:pp_int - ("endorsements", Data_encoding.int31) - - let endorsements_received = - declare_4 - ~section - ~name:"endorsements_received" - ~level:Debug - ~msg: - "received {count} endorsements (power: {delta_power}) (total voting \ - power: {voting_power}, {endorsements} endorsements)" - ~pp1:pp_int - ("count", Data_encoding.int31) - ~pp2:pp_int - ("delta_power", Data_encoding.int31) - ~pp3:pp_int - ("voting_power", Data_encoding.int31) - ~pp4:pp_int - ("endorsements", Data_encoding.int31) - - let starting_new_monitoring = - declare_0 - ~section - ~name:"starting_new_monitoring" - ~level:Debug - ~msg:"starting new monitoring" - () - - let end_of_stream = - declare_0 - ~section - ~name:"end_of_stream" - ~level:Debug - ~msg:"end of stream" - () - - let received_new_operations = - declare_0 - ~section - ~name:"received_new_operations" - ~level:Debug - ~msg:"received new operations" - () - - (* info messages *) - let shutting_down = - declare_0 - ~section - ~name:"shutting_down" - ~level:Info - ~msg:"shutting down operation worker" - () - - let mempool_initial_additions = - declare_1 - ~section - ~name:"mempool_initial_additions" - ~level:Info - ~msg:"added {count} initial operations in baker mempool" - ("count", Data_encoding.int31) - - let invalid_json_file = - declare_1 - ~section - ~name:"invalid_json_file" - ~level:Warning - ~msg:"{filename} is not a valid JSON file" - ("filename", Data_encoding.string) - - let no_mempool_found_in_file = - declare_1 - ~section - ~name:"no_mempool_found_in_file" - ~level:Warning - ~msg:"no mempool found in file {filename}" - ("filename", Data_encoding.string) - - let cannot_fetch_mempool = - declare_1 - ~section - ~name:"cannot_fetch_mempool" - ~level:Error - ~msg:"cannot fetch mempool: {errs}" - ("errs", Error_monad.(TzTrace.encoding error_encoding)) -end - -module Mempool = struct - type error += - | Failed_mempool_fetch of { - path : string; - reason : string; - details : Data_encoding.json option; - } - - let ops_of_mempool - (ops : Protocol_client_context.Alpha_block_services.Mempool.t) = - (* We only retain the applied, unprocessed and delayed operations *) - List.rev - (Operation_hash.Map.fold (fun _ op acc -> op :: acc) ops.unprocessed - @@ Operation_hash.Map.fold - (fun _ (op, _) acc -> op :: acc) - ops.branch_delayed - @@ List.rev_map (fun (_, op) -> op) ops.applied) - - let retrieve mempool = - match mempool with - | None -> Lwt.return_none - | Some mempool -> ( - let fail reason details = - let path = - match mempool with - | Baking_configuration.Mempool.Local {filename} -> filename - | Baking_configuration.Mempool.Remote {uri; _} -> Uri.to_string uri - in - fail (Failed_mempool_fetch {path; reason; details}) - in - let decode_mempool json = - protect - ~on_error:(fun _ -> - fail "cannot decode the received JSON into mempool" (Some json)) - (fun () -> - let mempool = - Data_encoding.Json.destruct - Protocol_client_context.Alpha_block_services.S.Mempool - .encoding - json - in - return (ops_of_mempool mempool)) - in - match mempool with - | Baking_configuration.Mempool.Local {filename} -> - if Sys.file_exists filename then - Tezos_stdlib_unix.Lwt_utils_unix.Json.read_file filename - >>= function - | Error _ -> - Events.(emit invalid_json_file filename) >>= fun () -> - Lwt.return_none - | Ok json -> ( - decode_mempool json >>= function - | Ok mempool -> Lwt.return_some mempool - | Error errs -> - Events.(emit cannot_fetch_mempool errs) >>= fun () -> - Lwt.return_none) - else - Events.(emit no_mempool_found_in_file filename) >>= fun () -> - Lwt.return_none - | Baking_configuration.Mempool.Remote {uri; http_headers} -> ( - ( (with_timeout - (Systime_os.sleep (Time.System.Span.of_seconds_exn 5.)) - (fun _ -> - Tezos_rpc_http_client_unix.RPC_client_unix.generic_json_call - ?headers:http_headers - `GET - uri) - >>=? function - | `Ok json -> return json - | `Unauthorized json -> fail "unauthorized request" json - | `Gone json -> fail "gone" json - | `Error json -> fail "error" json - | `Not_found json -> fail "not found" json - | `Forbidden json -> fail "forbidden" json - | `Conflict json -> fail "conflict" json) - >>=? fun json -> decode_mempool json ) - >>= function - | Ok mempool -> Lwt.return_some mempool - | Error errs -> - Events.(emit cannot_fetch_mempool errs) >>= fun () -> - Lwt.return_none)) -end - -type candidate = { - hash : Block_hash.t; - round_watched : Round.t; - payload_hash_watched : Block_payload_hash.t; -} - -let candidate_encoding = - let open Data_encoding in - conv - (fun {hash; round_watched; payload_hash_watched} -> - (hash, round_watched, payload_hash_watched)) - (fun (hash, round_watched, payload_hash_watched) -> - {hash; round_watched; payload_hash_watched}) - (obj3 - (req "hash" Block_hash.encoding) - (req "round_watched" Round.encoding) - (req "payload_hash_watched" Block_payload_hash.encoding)) - -type voting_power = int - -type event = - | Prequorum_reached of - candidate * voting_power * Kind.preendorsement operation list - | Quorum_reached of candidate * voting_power * Kind.endorsement operation list - -type pqc_watched = { - candidate_watched : candidate; - get_preendorsement_voting_power : slot:Slot.t -> int; - consensus_threshold : int; - mutable current_voting_power : int; - mutable preendorsements_received : Kind.preendorsement operation list; - mutable preendorsements_count : int; -} - -type qc_watched = { - candidate_watched : candidate; - get_endorsement_voting_power : slot:Slot.t -> int; - consensus_threshold : int; - mutable current_voting_power : int; - mutable endorsements_received : Kind.endorsement operation list; - mutable endorsements_count : int; -} - -type watch_kind = Pqc_watch of pqc_watched | Qc_watch of qc_watched - -type quorum_event_stream = { - stream : event Lwt_stream.t; - push : event option -> unit; -} - -type t = { - mutable operation_pool : Operation_pool.pool; - mutable canceler : Lwt_canceler.t; - mutable proposal_watched : watch_kind option; - qc_event_stream : quorum_event_stream; - lock : Lwt_mutex.t; - monitor_node_operations : bool; (* Keep on monitoring node operations *) -} - -let monitor_operations (cctxt : #Protocol_client_context.full) = - Alpha_block_services.Mempool.monitor_operations - cctxt - ~chain:cctxt#chain - ~applied:true - ~branch_delayed:true - ~branch_refused:false - ~refused:false - () - >>=? fun (operation_stream, stream_stopper) -> - let operation_stream = - Lwt_stream.map - (fun ops -> List.map (fun ((_, op), _) -> op) ops) - operation_stream - in - Shell_services.Blocks.Header.shell_header - cctxt - ~chain:cctxt#chain - ~block:(`Head 0) - () - >>=? fun shell_header -> - let round = - match Fitness.(round_from_raw shell_header.fitness) with - | Ok r -> r - | Error _ -> Round.zero - in - return ((shell_header.level, round), operation_stream, stream_stopper) - -let make_initial_state ?initial_mempool ?(monitor_node_operations = true) () = - let qc_event_stream = - let (stream, push) = Lwt_stream.create () in - {stream; push} - in - let canceler = Lwt_canceler.create () in - let operation_pool = - Option.fold - ~none:Operation_pool.empty - ~some:(Operation_pool.add_operations Operation_pool.empty) - initial_mempool - in - let lock = Lwt_mutex.create () in - { - operation_pool; - canceler; - proposal_watched = None; - qc_event_stream; - lock; - monitor_node_operations; - } - -let is_valid_consensus_content (candidate : candidate) consensus_content = - let {hash = _; round_watched; payload_hash_watched} = candidate in - Round.equal consensus_content.round round_watched - && Block_payload_hash.equal - consensus_content.block_payload_hash - payload_hash_watched - -let cancel_monitoring state = state.proposal_watched <- None - -let update_monitoring ?(should_lock = true) state ops = - (if should_lock then Lwt_mutex.with_lock state.lock else fun f -> f ()) - @@ fun () -> - (* If no block is watched, don't do anything *) - match state.proposal_watched with - | None -> Lwt.return_unit - | Some - (Pqc_watch - ({ - candidate_watched; - get_preendorsement_voting_power; - consensus_threshold; - _; - } as proposal_watched)) -> - let preendorsements = Operation_pool.filter_preendorsements ops in - let (preendorsements_count, voting_power) = - List.fold_left - (fun (count, power) (op : Kind.preendorsement Operation.t) -> - let { - shell = _; - protocol_data = - {contents = Single (Preendorsement consensus_content); _}; - _; - } = - op - in - if is_valid_consensus_content candidate_watched consensus_content - then ( - let op_power = - get_preendorsement_voting_power ~slot:consensus_content.slot - in - proposal_watched.current_voting_power <- - proposal_watched.current_voting_power + op_power ; - proposal_watched.preendorsements_received <- - op :: proposal_watched.preendorsements_received ; - proposal_watched.preendorsements_count <- - proposal_watched.preendorsements_count + 1 ; - (count + 1, power + op_power)) - else (count, power)) - (0, 0) - preendorsements - in - if proposal_watched.current_voting_power >= consensus_threshold then ( - Events.( - emit - pqc_reached - ( proposal_watched.current_voting_power, - proposal_watched.preendorsements_count )) - >>= fun () -> - state.qc_event_stream.push - (Some - (Prequorum_reached - ( candidate_watched, - proposal_watched.current_voting_power, - List.rev proposal_watched.preendorsements_received ))) ; - (* Once the event has been emitted, we cancel the monitoring *) - cancel_monitoring state ; - Lwt.return_unit) - else - Events.( - emit - preendorsements_received - ( preendorsements_count, - voting_power, - proposal_watched.current_voting_power, - proposal_watched.preendorsements_count )) - | Some - (Qc_watch - ({ - candidate_watched; - get_endorsement_voting_power; - consensus_threshold; - _; - } as proposal_watched)) -> - let endorsements = Operation_pool.filter_endorsements ops in - let (endorsements_count, voting_power) = - List.fold_left - (fun (count, power) (op : Kind.endorsement Operation.t) -> - let { - shell = _; - protocol_data = - {contents = Single (Endorsement consensus_content); _}; - _; - } = - op - in - if is_valid_consensus_content candidate_watched consensus_content - then ( - let op_power = - get_endorsement_voting_power ~slot:consensus_content.slot - in - proposal_watched.current_voting_power <- - proposal_watched.current_voting_power + op_power ; - proposal_watched.endorsements_received <- - op :: proposal_watched.endorsements_received ; - proposal_watched.endorsements_count <- - proposal_watched.endorsements_count + 1 ; - (count + 1, power + op_power)) - else (count, power)) - (0, 0) - endorsements - in - if proposal_watched.current_voting_power >= consensus_threshold then ( - Events.( - emit - qc_reached - ( proposal_watched.current_voting_power, - proposal_watched.endorsements_count )) - >>= fun () -> - state.qc_event_stream.push - (Some - (Quorum_reached - ( candidate_watched, - proposal_watched.current_voting_power, - List.rev proposal_watched.endorsements_received ))) ; - (* Once the event has been emitted, we cancel the monitoring *) - cancel_monitoring state ; - Lwt.return_unit) - else - Events.( - emit - endorsements_received - ( endorsements_count, - voting_power, - proposal_watched.current_voting_power, - proposal_watched.endorsements_count )) - -let monitor_quorum state new_proposal_watched = - Lwt_mutex.with_lock state.lock @@ fun () -> - (* if a previous monitoring was registered, we cancel it *) - if state.proposal_watched <> None then cancel_monitoring state ; - state.proposal_watched <- new_proposal_watched ; - let current_consensus_operations = - Operation_pool.OpSet.elements state.operation_pool.consensus - in - (* initialize with the currently present consensus operations *) - update_monitoring ~should_lock:false state current_consensus_operations - -let monitor_preendorsement_quorum state ~consensus_threshold - ~get_preendorsement_voting_power candidate_watched = - let new_proposal = - Some - (Pqc_watch - { - candidate_watched; - get_preendorsement_voting_power; - consensus_threshold; - current_voting_power = 0; - preendorsements_received = []; - preendorsements_count = 0; - }) - in - monitor_quorum state new_proposal - -let monitor_endorsement_quorum state ~consensus_threshold - ~get_endorsement_voting_power candidate_watched = - let new_proposal = - Some - (Qc_watch - { - candidate_watched; - get_endorsement_voting_power; - consensus_threshold; - current_voting_power = 0; - endorsements_received = []; - endorsements_count = 0; - }) - in - monitor_quorum state new_proposal - -let shutdown_worker state = - Events.(emit shutting_down ()) >>= fun () -> - Lwt_canceler.cancel state.canceler - -(* Each time a new head is received, the operation_pool field of the state is - cleaned/reset by this function. Instead of emptying it completely, we keep - the endorsements of at most 5 rounds and 1 level in the past, to be able to - include as much endorsements as possible in the next block if this baker is - the proposer. This allows to handle the following situations: - - - The baker observes an EQC for (L, R), but a proposal arrived for (L, R+1). - After the flush, extra endorsements on top of (L, R) are 'Branch_refused', - and are not re-sent by the node. If the baker proposes at (L+1, 1), he should - be able to include these extra endorsements. Hence the cache for old rounds. - - - The baker receives a head at (L+1, 0) on top of (L, 0), but this head - didn't reach consensus. If the baker who proposes at (L+1, 1) observed some - extra endorsements for (L, 0) that are not included in (L+1, 0), he may want - to add them. But these endorsements become 'Outdated' in the mempool once - (L+1, 0) is received. Hence the cache for previous level. -*) -let may_update_operations_pool state (head_level, head_round) = - let endorsements = - let head_round_i32 = Round.to_int32 head_round in - let head_level_i32 = head_level in - Operation_pool.OpSet.filter - (function - | { - protocol_data = - Operation_data - {contents = Single (Endorsement {round; level; _}); _}; - _; - } -> - let round_i32 = Round.to_int32 round in - let level_i32 = Raw_level.to_int32 level in - let delta_round = Int32.sub head_round_i32 round_i32 in - let delta_level = Int32.sub head_level_i32 level_i32 in - (* Only retain endorsements that are maximum 5 rounds old and - 1 level in the last *) - Compare.Int32.(delta_round <= 5l && delta_level <= 1l) - | _ -> false) - state.operation_pool.consensus - in - let operation_pool = - {Operation_pool.empty with Operation_pool.consensus = endorsements} - in - state.operation_pool <- operation_pool - -let create ?initial_mempool ?(monitor_node_operations = true) - (cctxt : #Protocol_client_context.full) = - Mempool.retrieve initial_mempool >>= fun initial_mempool -> - let state = make_initial_state ?initial_mempool ~monitor_node_operations () in - (* TODO should we continue forever ? *) - let rec worker_loop () = - monitor_operations cctxt >>= function - | Error err -> Events.(emit loop_failed err) - | Ok (head, operation_stream, op_stream_stopper) -> - Events.(emit starting_new_monitoring ()) >>= fun () -> - state.canceler <- Lwt_canceler.create () ; - Lwt_canceler.on_cancel state.canceler (fun () -> - op_stream_stopper () ; - cancel_monitoring state ; - Lwt.return_unit) ; - may_update_operations_pool state head ; - let rec loop () = - Lwt_stream.get operation_stream >>= function - | None -> - (* When the stream closes, it means a new head has been set, - we cancel the monitoring and flush current operations *) - Events.(emit end_of_stream ()) >>= fun () -> - op_stream_stopper () ; - cancel_monitoring state ; - worker_loop () - | Some ops -> - Events.(emit received_new_operations ()) >>= fun () -> - state.operation_pool <- - Operation_pool.add_operations state.operation_pool ops ; - update_monitoring state ops >>= fun () -> loop () - in - loop () - in - let worker_loop () = - (match initial_mempool with - | None -> Lwt.return_unit - | Some ops -> Events.(emit mempool_initial_additions (List.length ops))) - >>= fun () -> - if state.monitor_node_operations then worker_loop () else Lwt.return_unit - in - Lwt.dont_wait - (fun () -> - Lwt.finalize - (fun () -> worker_loop ()) - (fun () -> shutdown_worker state >>= fun _ -> Lwt.return_unit)) - (fun exn -> - Events.(emit__dont_wait__use_with_care ended (Printexc.to_string exn))) ; - Lwt.return state - -let get_current_operations state = state.operation_pool - -let get_quorum_event_stream state = state.qc_event_stream.stream diff --git a/src/proto_012_Psithaca/lib_delegate/operation_worker.mli b/src/proto_012_Psithaca/lib_delegate/operation_worker.mli deleted file mode 100644 index b7fb0559b29c..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/operation_worker.mli +++ /dev/null @@ -1,94 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Launch processes to gather operations from the mempool and make them - available for the baker. *) - -open Protocol -open Alpha_context - -(** {1 Datatypes}*) - -type t - -type candidate = { - hash : Block_hash.t; - round_watched : Round.t; - payload_hash_watched : Block_payload_hash.t; -} - -val candidate_encoding : candidate Data_encoding.t - -type voting_power = int - -type event = - | Prequorum_reached of - candidate * voting_power * Kind.preendorsement operation list - | Quorum_reached of candidate * voting_power * Kind.endorsement operation list - -(** {1 Constructors}*) - -(** [create ?initial_mempool ?monitor_node cctxt] create a monitoring process to - fetch operations for the baker to process. - - - @param initial_mempool initial operations to put in the worker's queue - (default: [None]) - - @param monitor_node_operations monitor operations on the node (defaults: [true]). Set - [monitor_node] to [false] to only consider the [initial_mempool] operations. - -*) -val create : - ?initial_mempool:Baking_configuration.Mempool.t -> - ?monitor_node_operations:bool -> - #Protocol_client_context.full -> - t Lwt.t - -(** {2 Accessors}*) - -val get_current_operations : t -> Operation_pool.pool - -val get_quorum_event_stream : t -> event Lwt_stream.t - -(** {3 Observers} *) - -val monitor_preendorsement_quorum : - t -> - consensus_threshold:int -> - get_preendorsement_voting_power:(slot:Slot.t -> int) -> - candidate -> - unit Lwt.t - -val monitor_endorsement_quorum : - t -> - consensus_threshold:int -> - get_endorsement_voting_power:(slot:Slot.t -> int) -> - candidate -> - unit Lwt.t - -val cancel_monitoring : t -> unit - -val shutdown_worker : t -> (unit, exn list) result Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/state_transitions.ml b/src/proto_012_Psithaca/lib_delegate/state_transitions.ml deleted file mode 100644 index 2e76497495e5..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/state_transitions.ml +++ /dev/null @@ -1,703 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Baking_state -open Baking_actions -module Events = Baking_events.State_transitions - -let do_nothing state = Lwt.return (state, Do_nothing) - -type proposal_acceptance = Invalid | Outdated_proposal | Valid_proposal - -let is_acceptable_proposal_for_current_level state - (proposal : Baking_state.proposal) = - let current_round = state.round_state.current_round in - if Round.(current_round < proposal.block.round) then - Events.( - emit unexpected_proposal_round (current_round, proposal.block.round)) - >>= fun () -> Lwt.return Invalid - else if Round.(current_round > proposal.block.round) then - Lwt.return Outdated_proposal - else - (* current_round = proposal.round *) - let previous_proposal = state.level_state.latest_proposal in - if - Round.(proposal.block.round = previous_proposal.block.round) - && Block_hash.(proposal.block.hash <> previous_proposal.block.hash) - && Block_hash.( - proposal.predecessor.hash = previous_proposal.predecessor.hash) - then - (* An existing proposal was found at the same round: the - proposal is bad and should be punished by the accuser *) - Events.( - emit - proposal_for_round_already_seen - (proposal.block.hash, current_round, previous_proposal.block.hash)) - >>= fun () -> Lwt.return Invalid - else - (* current_round = proposal.block.round ∧ - proposal.block.round <> previous_proposal.block.round - => - proposal.block.round > previous_proposal.block.round - - The proposal has the expected round and the previous proposal - is a predecessor therefore the proposal is valid *) - Lwt.return Valid_proposal - -let make_consensus_list state proposal = - (* TODO efficiently iterate on the slot map instead of removing - duplicate endorsements *) - let level = - Raw_level.of_int32 state.level_state.current_level |> function - | Ok l -> l - | _ -> assert false - in - let round = proposal.block.round in - let block_payload_hash = proposal.block.payload_hash in - SlotMap.fold - (fun _slot (delegate, slots) acc -> - ( delegate, - {slot = Stdlib.List.hd slots.slots; level; round; block_payload_hash} ) - :: acc) - state.level_state.delegate_slots.own_delegate_slots - [] - |> List.sort_uniq compare - -(* If we do not have any slots, we won't inject any operation but we - will still participate to determine an elected block *) -let make_preendorse_action state proposal = - let updated_state = - let round_state = - {state.round_state with current_phase = Awaiting_preendorsements} - in - {state with round_state} - in - let preendorsements : (delegate * consensus_content) list = - make_consensus_list state proposal - in - Inject_preendorsements {preendorsements; updated_state} - -let update_proposal state proposal = - Events.(emit updating_latest_proposal proposal.block.hash) >>= fun () -> - let new_level_state = {state.level_state with latest_proposal = proposal} in - Lwt.return {state with level_state = new_level_state} - -let may_update_proposal state (proposal : proposal) = - assert ( - Compare.Int32.( - state.level_state.latest_proposal.block.shell.level - = proposal.block.shell.level)) ; - if - Round.(state.level_state.latest_proposal.block.round < proposal.block.round) - then update_proposal state proposal - else Lwt.return state - -let preendorse state proposal = - Events.(emit preendorsing_proposal proposal.block.hash) >>= fun () -> - if Protocol_hash.(proposal.block.protocol <> proposal.block.next_protocol) - then - (* We do not endorse the first transition block *) - let new_round_state = {state.round_state with current_phase = Idle} in - let new_state = {state with round_state = new_round_state} in - Lwt.return (new_state, Do_nothing) - else Lwt.return (state, make_preendorse_action state proposal) - -let extract_pqc state (new_proposal : proposal) = - match new_proposal.block.prequorum with - | None -> None - | Some pqc -> - let add_voting_power acc (op : Kind.preendorsement Operation.t) = - let open Protocol.Alpha_context.Operation in - let { - shell = _; - protocol_data = {contents = Single (Preendorsement {slot; _}); _}; - _; - } = - op - in - match - SlotMap.find slot state.level_state.delegate_slots.all_delegate_slots - with - | None -> - (* cannot happen if the map is correctly populated *) - acc - | Some {endorsing_power; _} -> acc + endorsing_power - in - let voting_power = - List.fold_left add_voting_power 0 pqc.preendorsements - in - let consensus_threshold = - state.global_state.constants.parametric.consensus_threshold - in - if Compare.Int.(voting_power >= consensus_threshold) then - Some (pqc.preendorsements, pqc.round) - else None - -let may_update_endorsable_payload_with_internal_pqc state - (new_proposal : proposal) = - match - (new_proposal.block.prequorum, state.level_state.endorsable_payload) - with - | (None, _) -> - (* The proposal does not contain a PQC: no need to update *) - state - | (Some {round = new_round; _}, Some {prequorum = {round = old_round; _}; _}) - when Round.(new_round < old_round) -> - (* The proposal pqc is outdated, do not update *) - state - | (Some better_prequorum, _) -> - assert ( - Block_payload_hash.( - better_prequorum.block_payload_hash = new_proposal.block.payload_hash)) ; - assert ( - Compare.Int32.(better_prequorum.level = new_proposal.block.shell.level)) ; - let new_endorsable_payload = - Some {proposal = new_proposal; prequorum = better_prequorum} - in - let new_level_state = - {state.level_state with endorsable_payload = new_endorsable_payload} - in - {state with level_state = new_level_state} - -let rec handle_new_proposal state (new_proposal : proposal) = - let current_level = state.level_state.current_level in - let new_proposal_level = new_proposal.block.shell.level in - if Compare.Int32.(current_level > new_proposal_level) then - (* The baker is ahead, a reorg may have happened. Do nothing: - wait for the node to send us the branch's head. This new head - should have a fitness that is greater than our current - proposal and thus, its level should be at least the same as - our current proposal's level. *) - Events.(emit baker_is_ahead_of_node (current_level, new_proposal_level)) - >>= fun () -> Lwt.return (state, Do_nothing) - else if Compare.Int32.(current_level = new_proposal_level) then - (* The received head is a new proposal for the current level: - let's check if it's a valid one for us. *) - let current_proposal = state.level_state.latest_proposal in - if - Block_hash.( - current_proposal.predecessor.hash <> new_proposal.predecessor.hash) - then - Events.( - emit - new_proposal_is_on_another_branch - (current_proposal.predecessor.hash, new_proposal.predecessor.hash)) - >>= fun () -> may_switch_branch state new_proposal - else - is_acceptable_proposal_for_current_level state new_proposal >>= function - | Invalid -> - (* The proposal is invalid: we ignore it *) - Events.(emit skipping_invalid_proposal ()) >>= fun () -> - do_nothing state - | Outdated_proposal -> - (* Check whether we need to update our endorsable payload *) - let state = - may_update_endorsable_payload_with_internal_pqc state new_proposal - in - (* The proposal is outdated: we update to be able to extract - its included endorsements but we do not endorse it *) - Events.(emit outdated_proposal new_proposal.block.hash) >>= fun () -> - may_update_proposal state new_proposal >>= fun state -> - do_nothing state - | Valid_proposal -> ( - (* Valid_proposal => proposal.round = current_round *) - (* Check whether we need to update our endorsable payload *) - let new_state = - may_update_endorsable_payload_with_internal_pqc state new_proposal - in - may_update_proposal new_state new_proposal >>= fun new_state -> - (* The proposal is valid but maybe we already locked on a payload *) - match new_state.level_state.locked_round with - | Some locked_round -> ( - if - Block_payload_hash.( - locked_round.payload_hash = new_proposal.block.payload_hash) - then - (* when the new head has the same payload as our - [locked_round], we accept it and preendorse *) - preendorse new_state new_proposal - else - (* The payload is different *) - match new_proposal.block.prequorum with - | Some {round; _} when Round.(locked_round.round < round) -> - (* This PQC is above our locked_round, we can preendorse it *) - preendorse new_state new_proposal - | _ -> Lwt.return (new_state, Do_nothing)) - | None -> - (* Otherwise, we did not lock on any payload, thus we can - preendorse it *) - preendorse new_state new_proposal) - else - (* new_proposal.level > current_level *) - (* Possible scenarios: - - we received a block for a next level - - we received our own block - This is where we update our [level_state] (and our [round_state]) *) - Events.(emit new_head_with_increasing_level ()) >>= fun () -> - let new_level = new_proposal.block.shell.level in - let compute_new_state ~current_round ~delegate_slots - ~next_level_delegate_slots = - let round_state = {current_round; current_phase = Idle} in - let level_state = - { - current_level = new_level; - latest_proposal = new_proposal; - (* Unlock values *) - locked_round = None; - endorsable_payload = None; - elected_block = None; - delegate_slots; - next_level_delegate_slots; - next_level_proposed_round = None; - } - in - (* recursive call with the up-to-date state to handle the new - level proposals *) - handle_new_proposal {state with level_state; round_state} new_proposal - in - let action = - Update_to_level {new_level_proposal = new_proposal; compute_new_state} - in - Lwt.return (state, action) - -and may_switch_branch state new_proposal = - let switch_branch state = - Events.(emit switching_branch ()) >>= fun () -> - (* If we are on a different branch, we also need to update our - [round_state] accordingly. - The recursive call to [handle_new_proposal] cannot end up - with an invalid proposal as it's on a different branch, thus - there is no need to backtrack to the former state as the new - proposal must end up being the new [latest_proposal]. That's - why we update it here. *) - let round_update = - { - Baking_actions.new_round_proposal = new_proposal; - handle_proposal = (fun state -> handle_new_proposal state new_proposal); - } - in - update_proposal state new_proposal >>= fun new_state -> - (* TODO if the branch proposal is outdated, we should - trigger an [End_of_round] to participate *) - Lwt.return (new_state, Synchronize_round round_update) - in - let current_endorsable_payload = state.level_state.endorsable_payload in - match (current_endorsable_payload, new_proposal.block.prequorum) with - | (None, Some _) | (None, None) -> - Events.(emit branch_proposal_has_better_fitness ()) >>= fun () -> - (* The new branch contains a PQC (and we do not) or a better - fitness, we switch. *) - switch_branch state - | (Some _, None) -> - (* We have a better PQC, we don't switch as we are able to - propose a better chain if we stay on our current one. *) - Events.(emit branch_proposal_has_no_prequorum ()) >>= fun () -> - do_nothing state - | (Some {prequorum = current_pqc; _}, Some new_pqc) -> - if Round.(current_pqc.round > new_pqc.round) then - Events.(emit branch_proposal_has_lower_prequorum ()) >>= fun () -> - (* The other's branch PQC is lower than ours, do not - switch *) - do_nothing state - else if Round.(current_pqc.round < new_pqc.round) then - Events.(emit branch_proposal_has_better_prequorum ()) >>= fun () -> - (* Their PQC is better than ours: we switch *) - switch_branch state - else - (* current_pqc.round = new_pqc *) - (* There is a PQC on two branches with the same round and - the same level but not the same predecessor : it's - impossible unless if there was some double-baking. This - shouldn't happen but do nothing anyway. *) - Events.(emit branch_proposal_has_same_prequorum ()) >>= fun () -> - do_nothing state - -(** In the association map [delegate_slots], the function returns an - optional pair ([delegate], [endorsing_slot]) if for the current - [round], the validator [delegate] has a endorsing slot. *) -let round_proposer state delegate_slots round = - (* TODO: make sure that for each slots all rounds in the map are filled *) - (* !FIXME! Endorsers and proposer are differents sets *) - (* !FIXME! the slotmap may be inconsistent & may sure to document - the invariants *) - let round_mod = - Int32.to_int (Round.to_int32 round) - mod state.global_state.constants.parametric.consensus_committee_size - in - SlotMap.find - state.level_state.delegate_slots.all_slots_by_round.(round_mod) - delegate_slots - -(** Inject a fresh block proposal containing the current operations of - the mempool in [state] and the additional [endorsements] for - [delegate] at round [round]. *) -let propose_fresh_block_action ~endorsements ?last_proposal - ~(predecessor : block_info) state delegate round = - (* TODO check if there is a trace where we could not have updated the level *) - (* The block to bake embeds the operations gathered by the - worker. However, consensus operations that are not relevant for - this block are filtered out. In the case of proposing a new fresh - block, the block is supposed to carry only endorsements for the - previous level. *) - let operation_pool = - (* 1. Fetch operations from the mempool. *) - let current_mempool = - let pool = - Operation_worker.get_current_operations - state.global_state.operation_worker - in - (* Considered the operations in the previous proposal as well *) - match last_proposal with - | Some proposal -> - let { - Operation_pool.votes_payload; - anonymous_payload; - managers_payload; - } = - proposal.payload - in - List.fold_left - Operation_pool.add_operations - pool - [votes_payload; anonymous_payload; managers_payload] - | None -> pool - in - (* 2. Filter and only retain relevant endorsements. *) - let relevant_consensus_operations = - let endorsement_filter = - { - Operation_pool.level = predecessor.shell.level; - round = predecessor.round; - payload_hash = predecessor.payload_hash; - } - in - Operation_pool.filter_with_relevant_consensus_ops - ~endorsement_filter - ~preendorsement_filter:None - current_mempool.consensus - in - let filtered_mempool = - {current_mempool with consensus = relevant_consensus_operations} - in - (* 3. Add the additional given [endorsements]. - N.b. this is a set: there won't be duplicates *) - Operation_pool.add_operations - filtered_mempool - (List.map Operation.pack endorsements) - in - let kind = Fresh operation_pool in - Events.(emit proposing_fresh_block (delegate, round)) >>= fun () -> - let block_to_bake = {predecessor; round; delegate; kind} in - let updated_state = - let new_round_state = {state.round_state with current_phase = Idle} in - {state with round_state = new_round_state} - in - Lwt.return @@ Inject_block {block_to_bake; updated_state} - -let repropose_block_action state delegate round (proposal : proposal) = - (* Possible cases: 1. There was a proposal but the PQC was not - reached 2. There was a proposal and the PQC and/or QC was - reached *) - (* We repropose the [endorsable_payload] if it exists, not the - [locked_round] as it may be older. *) - match state.level_state.endorsable_payload with - | None -> - Events.(emit no_endorsable_payload_fresh_block ()) >>= fun () -> - (* For case 1, we may re-inject with the same payload or a fresh - one. We make the choice of baking a fresh one: the previous - proposal may have been rejected because the block may have been - valid but may be considered "bad" (censored operations, empty - block, etc.) by the other validators. *) - (* Invariant: there is no locked round if there is no endorsable - payload *) - assert (state.level_state.locked_round = None) ; - let last_proposal_consensus_ops = proposal.block.quorum in - propose_fresh_block_action - ~endorsements:last_proposal_consensus_ops - state - ~last_proposal:proposal.block - ~predecessor:proposal.predecessor - delegate - round - | Some {proposal; prequorum} -> - Events.(emit repropose_block proposal.block.payload_hash) >>= fun () -> - (* For case 2, we re-inject the same block as [endorsable_round] - but we may add some left-overs endorsements. Therefore, the - operations we need to include are: - - the proposal's included endorsements - - the potential missing new endorsements for the - previous block - - the PQC of the endorsable payload *) - let consensus_operations = - (* Fetch preendorsements and endorsements from the mempool - (that could be missing from the proposal), filter, then add - consensus operations of the proposal itself, and convert - into [packed_operation trace]. *) - let mempool_consensus_operations = - (Operation_worker.get_current_operations - state.global_state.operation_worker) - .consensus - in - let all_consensus_operations = - (* Add the proposal and pqc consensus operations to the - mempool *) - List.fold_left - (fun set op -> Operation_pool.OpSet.add op set) - mempool_consensus_operations - (List.map Operation.pack proposal.block.quorum - @ List.map Operation.pack prequorum.preendorsements) - in - let endorsement_filter = - { - Operation_pool.level = proposal.predecessor.shell.level; - round = proposal.predecessor.round; - payload_hash = proposal.predecessor.payload_hash; - } - in - let preendorsement_filter = - Some - { - Operation_pool.level = prequorum.level; - round = prequorum.round; - payload_hash = prequorum.block_payload_hash; - } - in - Operation_pool.( - filter_with_relevant_consensus_ops - ~endorsement_filter - ~preendorsement_filter - all_consensus_operations - |> OpSet.elements) - in - let payload_hash = proposal.block.payload_hash in - let payload_round = proposal.block.payload_round in - let payload = proposal.block.payload in - let kind = - Reproposal {consensus_operations; payload_hash; payload_round; payload} - in - let block_to_bake = - {predecessor = proposal.predecessor; round; delegate; kind} - in - let updated_state = - let new_round_state = {state.round_state with current_phase = Idle} in - {state with round_state = new_round_state} - in - Lwt.return @@ Inject_block {block_to_bake; updated_state} - -let end_of_round state current_round = - let new_round = Round.succ current_round in - let new_round_state = {state.round_state with current_round = new_round} in - let new_state = {state with round_state = new_round_state} in - (* we need to check if we need to bake for this round or not *) - match - round_proposer - new_state - new_state.level_state.delegate_slots.own_delegate_slots - new_state.round_state.current_round - with - | None -> - Events.(emit no_proposal_slot new_round) >>= fun () -> - (* We don't have any delegate that may propose a new block for - this round -- We will wait for preendorsements when the next - level block arrive. Meanwhile, we are idle *) - let new_round_state = {new_state.round_state with current_phase = Idle} in - let new_state = {state with round_state = new_round_state} in - do_nothing new_state - | Some (delegate, _) -> - Events.(emit proposal_slot (new_round, delegate)) >>= fun () -> - (* We have a delegate, we need to determine what to inject *) - repropose_block_action - new_state - delegate - new_round - state.level_state.latest_proposal - >>= fun action -> Lwt.return (new_state, action) - -let time_to_bake state at_round = - (* It is now time to update the state level *) - (* We need to keep track for which block we have 2f+1 *endorsements*, that is, - which will become the new predecessor_block *) - (* Invariant: endorsable_round >= round(elected block) >= locked_round *) - let round_proposer_opt = - round_proposer - state - state.level_state.next_level_delegate_slots.own_delegate_slots - at_round - in - match (state.level_state.elected_block, round_proposer_opt) with - | (None, _) | (_, None) -> - (* Unreachable: the [Time_to_bake_next_level] event can only be - triggered when we have a slot and an elected block *) - assert false - | (Some elected_block, Some (delegate, _)) -> - let endorsements = elected_block.endorsement_qc in - let new_level_state = - {state.level_state with next_level_proposed_round = Some at_round} - in - let new_state = {state with level_state = new_level_state} in - propose_fresh_block_action - ~endorsements - ~predecessor:elected_block.proposal.block - new_state - delegate - at_round - >>= fun action -> Lwt.return (new_state, action) - -let update_locked_round state round payload_hash = - let locked_round = Some {payload_hash; round} in - let new_level_state = {state.level_state with locked_round} in - {state with level_state = new_level_state} - -let make_endorse_action state proposal = - let updated_state = - let new_round_state = - {state.round_state with current_phase = Awaiting_endorsements} - in - let new_state = {state with round_state = new_round_state} in - update_locked_round - new_state - proposal.block.round - proposal.block.payload_hash - in - let endorsements : (delegate * consensus_content) list = - make_consensus_list state proposal - in - Inject_endorsements {endorsements; updated_state} - -let prequorum_reached_when_awaiting_preendorsements state candidate - preendorsements = - let latest_proposal = state.level_state.latest_proposal in - if Block_hash.(candidate.Operation_worker.hash <> latest_proposal.block.hash) - then - Events.( - emit - unexpected_prequorum_received - (candidate.hash, latest_proposal.block.hash)) - >>= fun () -> do_nothing state - else - let prequorum = - { - level = latest_proposal.block.shell.level; - round = latest_proposal.block.round; - block_payload_hash = latest_proposal.block.payload_hash; - preendorsements - (* preendorsements may be nil when [consensus_threshold] is 0 *); - } - in - let new_endorsable_payload = {proposal = latest_proposal; prequorum} in - let new_level_state = - let level_state_with_new_payload = - { - state.level_state with - endorsable_payload = Some new_endorsable_payload; - } - in - match state.level_state.endorsable_payload with - | None -> level_state_with_new_payload - | Some endorsable_payload -> - if - Round.( - endorsable_payload.prequorum.round - < new_endorsable_payload.prequorum.round) - then level_state_with_new_payload - else state.level_state - in - let new_state = {state with level_state = new_level_state} in - Lwt.return (new_state, make_endorse_action new_state latest_proposal) - -let quorum_reached_when_waiting_endorsements state candidate endorsement_qc = - let latest_proposal = state.level_state.latest_proposal in - if Block_hash.(candidate.Operation_worker.hash <> latest_proposal.block.hash) - then - Events.( - emit - unexpected_quorum_received - (candidate.hash, latest_proposal.block.hash)) - >>= fun () -> do_nothing state - else - let new_level_state = - match state.level_state.elected_block with - | None -> - let elected_block = - Some {proposal = latest_proposal; endorsement_qc} - in - {state.level_state with elected_block} - | Some _ -> - (* If we already have an elected block, do not update it: the - earliest, the better. *) - state.level_state - in - let new_round_state = {state.round_state with current_phase = Idle} in - let new_state = - {state with round_state = new_round_state; level_state = new_level_state} - in - do_nothing new_state - -(* Hypothesis: - - The state is not to be modified outside this module - - - new_proposal's received blocks are expected to belong to our current - round - - - [Prequorum_reached] can only be received when we've seen a new head - - - [Quorum_reached] can only be received when we've seen a - [Prequorum_reached] *) -let step (state : Baking_state.t) (event : Baking_state.event) : - (Baking_state.t * Baking_actions.t) Lwt.t = - let phase = state.round_state.current_phase in - Events.(emit step_current_phase (phase, event)) >>= fun () -> - match (phase, event) with - (* Handle timeouts *) - | (_, Timeout (End_of_round {ending_round})) -> - (* If the round is ending, stop everything currently going on and - increment the round. *) - end_of_round state ending_round - | (_, Timeout (Time_to_bake_next_level {at_round})) -> - (* If it is time to bake the next level, stop everything currently - going on and propose the next level block *) - time_to_bake state at_round - | (Idle, New_proposal block_info) -> handle_new_proposal state block_info - | (Awaiting_endorsements, New_proposal block_info) - | (Awaiting_preendorsements, New_proposal block_info) -> - Events.(emit new_head_while_waiting_for_qc ()) >>= fun () -> - handle_new_proposal state block_info - | ( Awaiting_preendorsements, - Prequorum_reached (candidate, _voting_power, preendorsement_qc) ) -> - prequorum_reached_when_awaiting_preendorsements - state - candidate - preendorsement_qc - | ( Awaiting_endorsements, - Quorum_reached (candidate, _voting_power, endorsement_qc) ) -> - quorum_reached_when_waiting_endorsements state candidate endorsement_qc - (* Unreachable cases *) - | (Idle, (Prequorum_reached _ | Quorum_reached _)) - | (Awaiting_preendorsements, Quorum_reached _) - | (Awaiting_endorsements, Prequorum_reached _) -> - (* This cannot/should not happen *) - do_nothing state diff --git a/src/proto_012_Psithaca/lib_delegate/state_transitions.mli b/src/proto_012_Psithaca/lib_delegate/state_transitions.mli deleted file mode 100644 index bd449b20929c..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/state_transitions.mli +++ /dev/null @@ -1,90 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Baking_state -open Baking_actions - -val do_nothing : state -> (state * action) Lwt.t - -type proposal_acceptance = Invalid | Outdated_proposal | Valid_proposal - -val is_acceptable_proposal_for_current_level : - state -> proposal -> proposal_acceptance Lwt.t - -val make_consensus_list : - state -> proposal -> (delegate * consensus_content) list - -val make_preendorse_action : state -> proposal -> action - -val may_update_proposal : state -> proposal -> state Lwt.t - -val preendorse : state -> proposal -> (state * action) Lwt.t - -val extract_pqc : - state -> proposal -> (Kind.preendorsement operation list * Round.t) option - -val handle_new_proposal : state -> proposal -> (state * action) Lwt.t - -val round_proposer : - state -> - (delegate * endorsing_slot) SlotMap.t -> - Round.t -> - (delegate * endorsing_slot) option - -val propose_fresh_block_action : - endorsements:Kind.endorsement Operation.t list -> - ?last_proposal:block_info -> - predecessor:block_info -> - state -> - delegate -> - Round.t -> - action Lwt.t - -val repropose_block_action : - state -> delegate -> Round.t -> proposal -> action Lwt.t - -val end_of_round : state -> Round.t -> (state * action) Lwt.t - -val time_to_bake : state -> Round.t -> (state * action) Lwt.t - -val update_locked_round : state -> Round.t -> Block_payload_hash.t -> state - -val make_endorse_action : state -> proposal -> action - -val prequorum_reached_when_awaiting_preendorsements : - state -> - Operation_worker.candidate -> - Kind.preendorsement operation list -> - (state * action) Lwt.t - -val quorum_reached_when_waiting_endorsements : - state -> - Operation_worker.candidate -> - Kind.endorsement operation list -> - (state * action) Lwt.t - -val step : state -> event -> (state * action) Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/test/.ocamlformat b/src/proto_012_Psithaca/lib_delegate/test/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_delegate/test/README.md b/src/proto_012_Psithaca/lib_delegate/test/README.md deleted file mode 100644 index 73f3e79bac88..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/README.md +++ /dev/null @@ -1,116 +0,0 @@ -# Testing Tenderbake via mockup-based simulations - -This test suite contains tests that check the baker. A notable feature that -distinguishes these tests from simple unit tests is that the baker is -examined as a whole with all its components working together. We do not run -a node, instead, we run a mockup node that allows us to create an illusion -for the baker that it talks to a real node. Thus, we have full control of -how the mockup node behaves, how the proposals and operations propagate, and -what the baker sees when it calls RPCs. - -Pros: - -* Integrates naturally with the existing testing setup and CI. No external - binaries or setup needed. -* Fast. The round time is currently constant and equal to 3 seconds. 2 - second was also tried, but that resulted in deviations from expected - behavior in about 10% of cases. Upon closer inspection it was found out - that round timeouts happen before a key event in the scenario. Supposedly, - this depends on the time the test is started as all other parameters are - set and deterministic. Switching 3 seconds solved the issue. -* Uses the same code as the baker, so people who are familiar with the - existing Tezos will benefit from their knowledge. -* Various assertions and checks can be expressed to ensure that the scenario - in question progresses exactly as it supposed to. -* Many details of how the baker sees the world can be tightly controlled. - -Cons: - -* Hard to see the logic of the scenario because it has to be written as a - collection of hooks. - -## Running the tests - -The tests can be run like this from the `src/proto_alpha/lib_delegate/test`: - -``` -$ dune exec ./main.exe -- -v -``` - -## Writing a test - -See the examples in `test_scenario.ml` for inspiration. Start writing a -scenario by deciding how many bakers you need and how many delegates each of -them will have (see the docs for `Mockup_simulator.run`): - -```ocaml - let open Mockup_simulator in - run [(3, (module Default_hooks)); (2, (module Default_hooks))] -``` - -* Set `debug` to `true` in `Mockup_simulator.default_config` and pass it to - `Mockup_simulator.run`. When `debug` is enabled baker logs will be printed. - This is the main instrument for observing what happens in the scenario. -* Consider setting `timeout` to an appropriate value. By default it is 10 - seconds, which should be fine for short scenarios, but may be insufficient - for longer ones. Timeout is a safety mechanism that prevents scenarios - from hanging and non-termination. -* It is also possible to control round durations, but it recommended to - use at least 3 seconds (the default). -* Finally, proposal slots can be controlled with the `delegate_selection` - field. Its value can either be `Random` for random selection of slots or - `Round_robin_over` with `Signature.public_key list list` inside. The - nested lists specify slot owners per level and round. - -```ocaml - let open Mockup_simulator in - let config = - { - default_config with - debug = true; - delegate_selection = - Round_robin_over - [ - (* round 0 round 1 round 2 round 3 *) - [bootstrap3; bootstrap4; bootstrap1; bootstrap2]; (* level 1 *) - [bootstrap1; bootstrap4; bootstrap2; bootstrap3]; (* level 2 *) - ]; - timeout = 15; - } - in - run ~config [(3, (module Default_hooks)); (2, (module Default_hooks))] -``` - -Note that delegate selection affects both (pre-)endorsing and voting power. -Delegates that do not have proposer slots will not be able to (pre-)endorse. -Voting power of delegates who have proposer slots will be proportional to -the number of slots they have. - -Next step is writing hook modules per baker that control its mockup mode and -execute assertions. In most cases there is no need to implement all hooks, -so the `Default_hooks` module can be reused, e.g.: - -```ocaml - let module Hooks : Mockup_simulator.Hooks = struct - include Mockup_simulator.Default_hooks - - let stop_on_event = function - | Baking_state.New_proposal {block; _} -> - (* Stop the node as soon as we receive a proposal with a level - higher than 5. *) - block.shell.level > 5l - | _ -> false - end in -``` - -Other hooks can be used to implement assertions using `failwith` and to set -mutable variable to track progress of a scenario. - -### Termination - -A scenario runs till all bakers terminate or till the scenario times out. A -baker can terminate successfully or unsuccessfully. Successful termination -happens when `stop_on_event` returns `true`. Unsuccessful termination occurs -when any of the hooks executes `failwith`. If at least one baker fails its -error message propagates and is displayed by the testing framework -(Alcotest). diff --git a/src/proto_012_Psithaca/lib_delegate/test/dune b/src/proto_012_Psithaca/lib_delegate/test/dune deleted file mode 100644 index 5ebd6390cecc..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/dune +++ /dev/null @@ -1,25 +0,0 @@ -(test - (name main) - (package tezos-baking-012-Psithaca) - (libraries - tezos-client-012-Psithaca - tezos_baking_012_Psithaca - tezos-baking-012-Psithaca.mockup-simulator - tezos-base-test-helpers - tezos-protocol-012-Psithaca-parameters - tezos-crypto - alcotest-lwt) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_micheline - -open Tezos_client_012_Psithaca - -open Tezos_protocol_012_Psithaca - -open Tezos_protocol_environment_012_Psithaca - -open Tezos_base_test_helpers - -open Tezos_012_Psithaca_mockup_simulator - -open Tezos_baking_012_Psithaca)) - (action (run %{exe:main.exe} -q -e))) - -(rule - (alias runtest_lint) - (deps (glob_files *.ml{,i})) - (action (run %{lib:tezos-tooling:lint.sh} %{deps}))) diff --git a/src/proto_012_Psithaca/lib_delegate/test/main.ml b/src/proto_012_Psithaca/lib_delegate/test/main.ml deleted file mode 100644 index f05f721ebebb..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/main.ml +++ /dev/null @@ -1,10 +0,0 @@ -(** Testing - ------- - Component: Baking - Invocation: dune build @src/proto_alpha/lib_delegate/runtest - Subject: Entrypoint - *) - -let () = - Lwt_main.run - (Alcotest_lwt.run "protocol_alpha" [("scenario", Test_scenario.tests)]) diff --git a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/.ocamlformat b/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/broadcast_services.ml b/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/broadcast_services.ml deleted file mode 100644 index deeffbf9f12e..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/broadcast_services.ml +++ /dev/null @@ -1,85 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module S = struct - open Data_encoding - - let path = RPC_path.(root / "broadcast") - - let dests_query = - let open RPC_query in - query (fun dests -> - object - method dests = dests - end) - |+ multi_field "dests" RPC_arg.int (fun t -> t#dests) - |> seal - - (* copied from lib_shell_services/injection_services.ml *) - let block_param = - obj2 - (req "block" (dynamic_size Block_header.encoding)) - (req - "operations" - (list (dynamic_size (list (dynamic_size Operation.encoding))))) - - let block = - RPC_service.post_service - ~description:"Broadcast a block." - ~query:dests_query - ~input:block_param - ~output:unit - RPC_path.(path / "block") - - let operation = - RPC_service.post_service - ~description:"Broadcast an operation." - ~query:dests_query - ~input:Alpha_context.Operation.encoding - ~output:unit - RPC_path.(path / "operation") -end - -open RPC_context - -let block ctxt ?(dests = []) raw operations = - make_call - S.block - ctxt - () - (object - method dests = dests - end) - (raw, operations) - -let operation ctxt ?(dests = []) operation = - make_call - S.operation - ctxt - () - (object - method dests = dests - end) - operation diff --git a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/dune b/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/dune deleted file mode 100644 index 303585d0ec88..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/dune +++ /dev/null @@ -1,24 +0,0 @@ -(library - (name tezos_012_Psithaca_mockup_simulator) - (public_name tezos-baking-012-Psithaca.mockup-simulator) - (libraries tezos-client-base-unix - tezos-client-commands - tezos-protocol-012-Psithaca - tezos-baking-012-Psithaca - tezos-mockup - tezos-mockup-proxy - tezos-mockup-commands) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_client_012_Psithaca - -open Tezos_client_commands - -open Tezos_baking_012_Psithaca - -open Tezos_stdlib_unix - -open Tezos_client_base_unix - -open Tezos_protocol_012_Psithaca_parameters - -open Tezos_protocol_012_Psithaca.Protocol))) - -(rule - (alias runtest_lint) - (deps (glob_files *.ml{,i})) - (action (run %{lib:tezos-tooling:lint.sh} %{deps}))) diff --git a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_client_context.ml b/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_client_context.ml deleted file mode 100644 index d5e58d187999..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_client_context.ml +++ /dev/null @@ -1,163 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Tezos_client_base - -let logger = - let log _channel msg = Lwt_fmt.printf "%s@." msg in - new Client_context.simple_printer log - -class dummy_prompter : Client_context.prompter = - object - method prompt : type a. (a, string tzresult) Client_context.lwt_format -> a - = - fun _msg -> assert false - - method prompt_password : type a. - (a, Bytes.t tzresult) Client_context.lwt_format -> a = - fun _msg -> assert false - - method multiple_password_retries = false - end - -let log _channel msg = - print_endline msg ; - Lwt.return_unit - -class faked_ctxt (hooks : Faked_services.hooks) (chain_id : Chain_id.t) : - RPC_context.json = - let local_ctxt = - let module Services = Faked_services.Make ((val hooks)) in - Tezos_mockup_proxy.RPC_client.local_ctxt (Services.directory chain_id) - in - object - method base = local_ctxt#base - - method generic_json_call meth ?body uri = - local_ctxt#generic_json_call meth ?body uri - - method generic_media_type_call meth ?body uri = - local_ctxt#generic_media_type_call meth ?body uri - - method call_service - : 'm 'p 'q 'i 'o. - (([< Resto.meth] as 'm), unit, 'p, 'q, 'i, 'o) RPC_service.t -> - 'p -> - 'q -> - 'i -> - 'o tzresult Lwt.t = - fun service params query body -> - local_ctxt#call_service service params query body - - method call_streamed_service - : 'm 'p 'q 'i 'o. - (([< Resto.meth] as 'm), unit, 'p, 'q, 'i, 'o) RPC_service.t -> - on_chunk:('o -> unit) -> - on_close:(unit -> unit) -> - 'p -> - 'q -> - 'i -> - (unit -> unit) tzresult Lwt.t = - fun service ~on_chunk ~on_close params query body -> - local_ctxt#call_streamed_service - service - ~on_chunk - ~on_close - params - query - body - end - -class faked_wallet ~base_dir ~filesystem : Client_context.wallet = - object (self) - method load_passwords = None - - method read_file fname = - match String.Hashtbl.find filesystem fname with - | None -> failwith "faked_wallet: cannot ead file (%s)" fname - | Some content -> return content - - method private filename alias_name = - Filename.concat - base_dir - (String.map (function ' ' -> '_' | c -> c) alias_name ^ "s") - - val lock_mutex = Lwt_mutex.create () - - method with_lock : type a. (unit -> a Lwt.t) -> a Lwt.t = - fun f -> Lwt_mutex.with_lock lock_mutex f - - method get_base_dir = base_dir - - method load : type a. - string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t = - fun alias_name ~default encoding -> - let filename = self#filename alias_name in - if not (String.Hashtbl.mem filesystem filename) then return default - else - self#read_file filename >>=? fun content -> - let json = (Ezjsonm.from_string content :> Data_encoding.json) in - match Data_encoding.Json.destruct encoding json with - | exception e -> - failwith - "did not understand the %s alias file %s : %s" - alias_name - filename - (Printexc.to_string e) - | data -> return data - - method write : type a. - string -> a -> a Data_encoding.encoding -> unit tzresult Lwt.t = - fun alias_name list encoding -> - let filename = self#filename alias_name in - let json = Data_encoding.Json.construct encoding list in - let str = Ezjsonm.value_to_string (json :> Ezjsonm.value) in - String.Hashtbl.replace filesystem filename str ; - return_unit - end - -class faked_io_wallet ~base_dir ~filesystem : Client_context.io_wallet = - object - inherit Client_context.simple_printer log - - inherit dummy_prompter - - inherit faked_wallet ~base_dir ~filesystem - end - -class unix_faked ~base_dir ~filesystem ~chain_id ~hooks : Client_context.full = - object - inherit faked_io_wallet ~base_dir ~filesystem - - inherit faked_ctxt hooks chain_id - - inherit Client_context_unix.unix_ui - - method chain = `Hash chain_id - - method block = `Head 0 - - method confirmations = None - end diff --git a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_daemon.ml b/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_daemon.ml deleted file mode 100644 index 1319d3df51d9..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_daemon.ml +++ /dev/null @@ -1,29 +0,0 @@ -module Baker = struct - let run ~(cctxt : #Protocol_client_context.full) ~stop_on_event ~chain_id - ~(context_index : Abstract_context_index.t) ~delegates = - let chain = `Hash chain_id in - let baking_configuration = - let open Baking_configuration in - { - default_config with - validation = ContextIndex context_index; - state_recorder = Disabled; - } - in - (* By default errors are simply printed but the baker won't stop - because of them. This is not what we want for testing. Here we force - the baker to terminate unsuccessfully if an error occurs. *) - let canceler = Lwt_canceler.create () in - let on_error (err : error trace) = - Lwt_canceler.cancel canceler >>= fun _ -> - failwith "%a" Error_monad.pp_print_trace err - in - Baking_scheduling.run - cctxt - ~canceler - ~stop_on_event - ~on_error - ~chain - baking_configuration - delegates -end diff --git a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_services.ml b/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_services.ml deleted file mode 100644 index 392600503c55..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/faked_services.ml +++ /dev/null @@ -1,295 +0,0 @@ -open Tezos_shell_services -module Directory = Tezos_rpc.RPC_directory -module Chain_services = Tezos_shell_services.Chain_services -module Block_services = Tezos_shell_services.Block_services -module Block_services_alpha = Protocol_client_context.Alpha_block_services - -module type Mocked_services_hooks = sig - type mempool = Mockup.M.Block_services.Mempool.t - - (** The baker and endorser rely on this stream to be notified of new - blocks. *) - val monitor_heads : unit -> (Block_hash.t * Block_header.t) RPC_answer.stream - - (** Returns current and next protocol for a block. *) - val protocols : - Block_services.block -> Block_services.protocols tzresult Lwt.t - - (** [header] returns the block header of the block associated to the given - block specification. *) - val header : - Block_services.block -> Mockup.M.Block_services.block_header tzresult Lwt.t - - (** [operations] returns all operations included in the block. *) - val operations : - Block_services.block -> - Mockup.M.Block_services.operation list list tzresult Lwt.t - - (** [inject_block_callback] is called when an RPC is performed on - [Tezos_shell_services.Injection_services.S.block], after checking that - the block header can be deserialized. *) - val inject_block : - Block_hash.t -> - Block_header.t -> - Operation.t trace trace -> - unit tzresult Lwt.t - - (** [inject_operation] is used by the endorser (or the client) to inject - operations, including endorsements. *) - val inject_operation : Operation.t -> Operation_hash.t tzresult Lwt.t - - (** [pending_operations] returns the current contents of the mempool. It - is used by the baker to fetch operations to potentially include in the - block being baked. These operations might include endorsements. If - there aren't enough endorsements, the baker waits on - [monitor_operations]. *) - val pending_operations : unit -> mempool Lwt.t - - (** Return a stream of list of operations. Used by the baker to wait on - endorsements. Invariant: the stream becomes empty when the node changes - head. *) - val monitor_operations : - applied:bool -> - branch_delayed:bool -> - branch_refused:bool -> - refused:bool -> - ((Operation_hash.t * Mockup.M.Protocol.operation) * error list) list - RPC_answer.stream - - (** Lists block hashes from the chain, up to the last checkpoint, sorted - with decreasing fitness. Without arguments it returns the head of the - chain. Optional arguments allow to return the list of predecessors of a - given block or of a set of blocks. *) - val list_blocks : - heads:Block_hash.t list -> - length:int option -> - min_date:Time.Protocol.t option -> - Block_hash.t list list tzresult Lwt.t - - (** List the ancestors of the given block which, if referred to as - the branch in an operation header, are recent enough for that - operation to be included in the current block. *) - val live_blocks : Block_services.block -> Block_hash.Set.t tzresult Lwt.t - - (** [rpc_context_callback] is used in the implementations of several - RPCs (see local_services.ml). It should correspond to the - rpc_context constructed from the context at the requested block. *) - val rpc_context_callback : - Block_services.block -> Environment_context.rpc_context tzresult Lwt.t - - (** Return raw protocol data as a block. *) - val raw_protocol_data : Block_services.block -> Bytes.t tzresult Lwt.t - - (** Broadcast block manually to nodes [dests] (given by their - number, starting from 0). If [dests] is not provided, broadcast - to all nodes. *) - val broadcast_block : - ?dests:int list -> - Block_hash.t -> - Block_header.t -> - Operation.t trace trace -> - unit tzresult Lwt.t - - (** Broadcast operation manually to nodes [dests] (given by their - number, starting from 0). If [dests] is not provided, broadcast - to all nodes. *) - val broadcast_operation : - ?dests:int list -> Alpha_context.packed_operation -> unit tzresult Lwt.t - - (** Simulate waiting for the node to be bootstrapped. Because the - simulated node is already bootstrapped, returns the current head - immediately. *) - val monitor_bootstrapped : - unit -> (Block_hash.t * Time.Protocol.t) RPC_answer.stream -end - -type hooks = (module Mocked_services_hooks) - -module Make (Hooks : Mocked_services_hooks) = struct - let monitor_heads = - Directory.gen_register1 - Directory.empty - Monitor_services.S.heads - (fun _chain _next_protocol () -> - RPC_answer.return_stream (Hooks.monitor_heads ())) - - let monitor_bootstrapped = - Directory.gen_register0 - Directory.empty - Monitor_services.S.bootstrapped - (fun () () -> RPC_answer.return_stream (Hooks.monitor_bootstrapped ())) - - let protocols = - let path = - let open Tezos_rpc.RPC_path in - prefix Block_services.chain_path Block_services.path - in - let service = - Tezos_rpc.RPC_service.prefix path Block_services.Empty.S.protocols - in - Directory.register Directory.empty service (fun (_, block) () () -> - Hooks.protocols block) - - let header = - Directory.prefix - (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) - @@ Directory.register - Directory.empty - Mockup.M.Block_services.S.header - (fun (((), _chain), block) _ _ -> Hooks.header block) - - let operations = - Directory.prefix - (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) - @@ Directory.register - Directory.empty - Mockup.M.Block_services.S.Operations.operations - (fun (((), _chain), block) () () -> Hooks.operations block) - - let hash = - Directory.prefix - (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) - @@ Directory.register - Directory.empty - Block_services.Empty.S.hash - (fun (((), _chain), block) () () -> - Hooks.header block >>=? fun x -> return x.hash) - - let shell_header = - Directory.prefix - (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) - @@ Directory.register - Directory.empty - Mockup.M.Block_services.S.Header.shell_header - (fun (((), _chain), block) _ _ -> - Hooks.header block >>=? fun x -> return x.shell) - - let chain chain_id = - Directory.prefix - Chain_services.path - (Directory.register - Directory.empty - Chain_services.S.chain_id - (fun _chain () () -> return chain_id)) - - let inject_block = - Directory.register - Directory.empty - Injection_services.S.block - (fun () _chain (bytes, operations) -> - match Block_header.of_bytes bytes with - | None -> failwith "faked_services.inject_block: can't deserialize" - | Some block_header -> - let block_hash = Block_hash.hash_bytes [bytes] in - Hooks.inject_block block_hash block_header operations >>=? fun () -> - return block_hash) - - let inject_operation = - Directory.register - Directory.empty - Injection_services.S.operation - (fun () _chain bytes -> - match Data_encoding.Binary.of_bytes_opt Operation.encoding bytes with - | None -> failwith "faked_services.inject_operation: can't deserialize" - | Some operation -> Hooks.inject_operation operation) - - let broadcast_block = - Directory.register - Directory.empty - Broadcast_services.S.block - (fun () dests (block_header, operations) -> - let bytes = Block_header.to_bytes block_header in - let block_hash = Block_hash.hash_bytes [bytes] in - let dests = match dests#dests with [] -> None | dests -> Some dests in - Hooks.broadcast_block ?dests block_hash block_header operations) - - let broadcast_operation = - Directory.register - Directory.empty - Broadcast_services.S.operation - (fun () dests operation -> - let dests = match dests#dests with [] -> None | dests -> Some dests in - Hooks.broadcast_operation ?dests operation) - - let pending_operations = - Directory.gen_register - Directory.empty - (Mockup.M.Block_services.S.Mempool.pending_operations - @@ Block_services.mempool_path Block_services.chain_path) - (fun ((), _chain) _params () -> - Hooks.pending_operations () >>= fun mempool -> - Mockup.M.Block_services.Mempool.pending_operations_version_dispatcher - ~version:1 - mempool) - - let monitor_operations = - Directory.gen_register - Directory.empty - (Block_services_alpha.S.Mempool.monitor_operations - @@ Block_services.mempool_path Block_services.chain_path) - (fun ((), _chain) flags () -> - let stream = - Hooks.monitor_operations - ~applied:flags#applied - ~branch_delayed:flags#branch_delayed - ~branch_refused:flags#branch_refused - ~refused:flags#refused - in - RPC_answer.return_stream stream) - - let list_blocks = - Directory.prefix - Chain_services.path - (Directory.register - Directory.empty - Chain_services.S.Blocks.list - (fun ((), _chain) flags () -> - Hooks.list_blocks - ~heads:flags#heads - ~length:flags#length - ~min_date:flags#min_date)) - - let live_blocks = - Directory.prefix - (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) - @@ Directory.register - Directory.empty - Block_services.Empty.S.live_blocks - (fun (_, block) _ () -> Hooks.live_blocks block) - - let raw_protocol_data = - Directory.prefix - (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) - @@ Directory.register - Directory.empty - Block_services.Empty.S.Header.raw_protocol_data - (fun (_, block) () () -> Hooks.raw_protocol_data block) - - let shell_directory chain_id = - let merge = Directory.merge in - Directory.empty |> merge monitor_heads |> merge protocols |> merge header - |> merge operations |> merge hash |> merge shell_header - |> merge (chain chain_id) - |> merge inject_block |> merge inject_operation |> merge monitor_operations - |> merge list_blocks |> merge live_blocks |> merge raw_protocol_data - |> merge broadcast_block |> merge broadcast_operation - |> merge monitor_bootstrapped - - let directory chain_id = - let proto_directory = - Directory.prefix - Chain_services.path - (Directory.prefix - Block_services.path - (Directory.map - (fun (((), _chain), block) -> - Hooks.rpc_context_callback block >>= function - | Error _ -> assert false - | Ok rpc_context -> Lwt.return rpc_context) - Mockup.M.directory)) - in - let base = Directory.merge (shell_directory chain_id) proto_directory in - RPC_directory.register_describe_directory_service - base - RPC_service.description_service -end diff --git a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/mockup_simulator.ml b/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/mockup_simulator.ml deleted file mode 100644 index 38467f3ebc82..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/mockup_simulator.ml +++ /dev/null @@ -1,1285 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type block = { - rpc_context : Environment_context.rpc_context; - protocol_data : Protocol.Alpha_context.Block_header.protocol_data; - raw_protocol_data : Bytes.t; - operations : Mockup.M.Block_services.operation list list; -} - -type chain = block list - -(** As new blocks and operations are received they are pushed to an Lwt_pipe - wrapped into this type. *) -type broadcast = - | Broadcast_block of Block_hash.t * Block_header.t * Operation.t list list - | Broadcast_op of Operation_hash.t * Alpha_context.packed_operation - -(** The state of a mockup node. *) -type state = { - instance_index : int; - (** Index of this node. Indices go from 0 to N-1 where N is the total - number of bakers in the simulation. *) - live_depth : int; - (** How many blocks (counting from the head into the past) are considered live? *) - mutable chain : chain; (** The chain as seen by this fake "node". *) - mutable mempool : (Operation_hash.t * Mockup.M.Protocol.operation) list; - (** Mempool of this fake "node". *) - chain_table : chain Block_hash.Table.t; - (** The chain table of this fake "node". It maps from block hashes to - blocks. *) - global_chain_table : block Block_hash.Table.t; - (** The global chain table that allows us to look up blocks that may be - missing in [chain_table], i.e. not known to this particular node. This - is used to find unknown predecessors. The real node can ask about an - unknown block and receive it on request, this is supposed to emulate - that functionality. *) - ctxt_table : Environment_context.rpc_context Context_hash.Table.t; - (** The context table allows us to look up rpc_context by its hash. *) - heads_pipe : (Block_hash.t * Block_header.t) Lwt_pipe.Unbounded.t; - (** [heads_pipe] is used to implement the [monitor_heads] RPC. *) - operations_pipe : - (Operation_hash.t * Mockup.M.Protocol.operation) option Lwt_pipe.Unbounded.t; - (** [operations_pipe] is used to implement the [operations_pipe] RPC. *) - mutable streaming_operations : bool; - (** A helper flag used to implement the monitor operations RPC. *) - broadcast_pipes : broadcast Lwt_pipe.Unbounded.t list; - (** Broadcast pipes per node. *) - genesis_block_true_hash : Block_hash.t; - (** True hash of the genesis - block as calculated by the - [Block_header.hash] function. *) -} - -let accounts = Mockup.Protocol_parameters.default_value.bootstrap_accounts - -let chain_id = Chain_id.of_string_exn "main" - -let genesis_block_hash = - Block_hash.of_b58check_exn - "BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU" - -let genesis_predecessor_block_hash = Block_hash.zero - -type propagation = Block | Pass | Delay of float - -type propagation_vector = propagation list - -module type Hooks = sig - val on_inject_block : - level:int32 -> - round:int32 -> - block_hash:Block_hash.t -> - block_header:Block_header.t -> - operations:Operation.t list list -> - protocol_data:Alpha_context.Block_header.protocol_data -> - (Block_hash.t * Block_header.t * Operation.t list list * propagation_vector) - tzresult - Lwt.t - - val on_inject_operation : - op_hash:Operation_hash.t -> - op:Alpha_context.packed_operation -> - (Operation_hash.t * Alpha_context.packed_operation * propagation_vector) - tzresult - Lwt.t - - val on_new_head : - block_hash:Block_hash.t -> - block_header:Block_header.t -> - (Block_hash.t * Block_header.t) option Lwt.t - - val on_new_operation : - Operation_hash.t * Alpha_context.packed_operation -> - (Operation_hash.t * Alpha_context.packed_operation) option Lwt.t - - val check_block_before_processing : - level:int32 -> - round:int32 -> - block_hash:Block_hash.t -> - block_header:Block_header.t -> - protocol_data:Alpha_context.Block_header.protocol_data -> - unit tzresult Lwt.t - - val check_chain_after_processing : - level:int32 -> round:int32 -> chain:chain -> unit tzresult Lwt.t - - val check_mempool_after_processing : - mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> - unit tzresult Lwt.t - - val stop_on_event : Baking_state.event -> bool - - val on_start_baker : - baker_position:int -> - delegates:Baking_state.delegate list -> - cctxt:Protocol_client_context.full -> - unit Lwt.t - - val check_chain_on_success : chain:chain -> unit tzresult Lwt.t -end - -(** Return a series of blocks starting from the block with the given - identifier. *) -let locate_blocks (state : state) - (block : Tezos_shell_services.Block_services.block) : - block list tzresult Lwt.t = - match block with - | `Hash (hash, rel) -> ( - match Block_hash.Table.find state.chain_table hash with - | None -> - failwith "locate_blocks: can't find the block %a" Block_hash.pp hash - | Some chain0 -> - let (_, chain) = List.split_n rel chain0 in - return chain) - | `Head rel -> - let (_, chain) = List.split_n rel state.chain in - return chain - | `Level _ -> failwith "locate_blocks: `Level block spec not handled" - | `Genesis -> failwith "locate_blocks: `Genesis block spec net handled" - | `Alias _ -> failwith "locate_blocks: `Alias block spec not handled" - -(** Similar to [locate_blocks], but only returns the first block. *) -let locate_block (state : state) - (block : Tezos_shell_services.Block_services.block) : block tzresult Lwt.t = - locate_blocks state block >>=? function - | [] -> failwith "locate_block: can't find the block" - | x :: _ -> return x - -(** Return the collection of live blocks for a given block identifier. *) -let live_blocks (state : state) block = - locate_blocks state block >>=? fun chain -> - let (segment, _) = List.split_n state.live_depth chain in - return - (List.fold_left - (fun set ({rpc_context; _} : block) -> - let hash = rpc_context.Environment_context.block_hash in - Block_hash.Set.add hash set) - (Block_hash.Set.singleton state.genesis_block_true_hash) - segment) - -(** Extract the round number from raw fitness. *) -let round_from_raw_fitness raw_fitness = - match Protocol.Alpha_context.Fitness.from_raw raw_fitness with - | Ok fitness -> - return - (Alpha_context.Round.to_int32 - (Protocol.Alpha_context.Fitness.round fitness)) - | Error _ -> failwith "round_from_raw_fitness: cannot parse fitness" - -(** Extract level from a block header. *) -let get_block_level (block_header : Block_header.t) = - return block_header.shell.level - -(** Extract round from a block header. *) -let get_block_round (block_header : Block_header.t) = - round_from_raw_fitness block_header.shell.fitness - -(** Parse protocol data. *) -let parse_protocol_data (protocol_data : Bytes.t) = - match - Data_encoding.Binary.of_bytes_opt - Protocol.Alpha_context.Block_header.protocol_data_encoding - protocol_data - with - | None -> failwith "can't parse protocol data of a block" - | Some parsed_protocol_data -> return parsed_protocol_data - -(** Broadcast an operation or block according to the given propagation - vector. *) -let handle_propagation msg propagation_vector broadcast_pipes = - List.iter_s - (fun (propagation, pipe) -> - match propagation with - | Block -> Lwt.return () - | Pass -> - Lwt_pipe.Unbounded.push pipe msg ; - Lwt.return_unit - | Delay s -> - Lwt.dont_wait - (fun () -> - Lwt_unix.sleep s >>= fun () -> - Lwt_pipe.Unbounded.push pipe msg ; - Lwt.return_unit) - (fun _exn -> ()) ; - Lwt.return ()) - (List.combine_drop propagation_vector broadcast_pipes) - >>= fun () -> return () - -(** Use the [user_hooks] to produce a module of functions that will perform - the heavy lifting for the RPC implementations. *) -let make_mocked_services_hooks (state : state) (user_hooks : (module Hooks)) : - Faked_services.hooks = - let module User_hooks = (val user_hooks : Hooks) in - let module Impl : Faked_services.Mocked_services_hooks = struct - type mempool = Mockup.M.Block_services.Mempool.t - - let monitor_heads () = - let next () = - let rec pop_until_ok () = - Lwt_pipe.Unbounded.pop state.heads_pipe - >>= fun (block_hash, block_header) -> - User_hooks.on_new_head ~block_hash ~block_header >>= function - | None -> pop_until_ok () - | Some head -> Lwt.return_some head - in - pop_until_ok () - in - let shutdown () = () in - RPC_answer.{next; shutdown} - - let monitor_bootstrapped () = - let first_run = ref true in - let next () = - if !first_run then ( - first_run := false ; - let b = match state.chain with [] -> assert false | b :: _ -> b in - let head_hash = b.rpc_context.block_hash in - let timestamp = b.rpc_context.block_header.timestamp in - Lwt.return_some (head_hash, timestamp)) - else Lwt.return_none - in - let shutdown () = () in - RPC_answer.{next; shutdown} - - let protocols (block : Tezos_shell_services.Block_services.block) = - locate_block state block >>=? fun x -> - let hash = x.rpc_context.block_hash in - let is_predecessor_of_genesis = - match block with - | `Hash (requested_hash, rel) -> - Int.equal rel 0 - && Block_hash.equal requested_hash genesis_predecessor_block_hash - | _ -> false - in - (* It is important to tell the baker that the genesis block is not in - the alpha protocol (we use Protocol_hash.zero). This will make the - baker not try to propose alternatives to that block and just accept - it as final in that Protocol_hash.zero protocol. The same for - predecessor of genesis, it should be in Protocol_hash.zero. *) - return - Tezos_shell_services.Block_services. - { - current_protocol = - (if - Block_hash.equal hash genesis_block_hash - || is_predecessor_of_genesis - then Protocol_hash.zero - else Protocol.hash); - next_protocol = - (if is_predecessor_of_genesis then Protocol_hash.zero - else Protocol.hash); - } - - let header (block : Tezos_shell_services.Block_services.block) : - Mockup.M.Block_services.block_header tzresult Lwt.t = - locate_block state block >>=? fun x -> - return - { - Mockup.M.Block_services.hash = x.rpc_context.block_hash; - chain_id; - shell = x.rpc_context.block_header; - protocol_data = x.protocol_data; - } - - let operations block = - locate_block state block >>=? fun x -> return x.operations - - let inject_block block_hash (block_header : Block_header.t) operations = - parse_protocol_data block_header.protocol_data >>=? fun protocol_data -> - get_block_level block_header >>=? fun level -> - get_block_round block_header >>=? fun round -> - User_hooks.on_inject_block - ~level - ~round - ~block_hash - ~block_header - ~operations - ~protocol_data - >>=? fun (block_hash1, block_header1, operations1, propagation_vector) -> - handle_propagation - (Broadcast_block (block_hash1, block_header1, operations1)) - propagation_vector - state.broadcast_pipes - - let all_pipes_or_select = function - | None -> return state.broadcast_pipes - | Some l -> - List.map_es - (fun n -> - match List.nth_opt state.broadcast_pipes n with - | None -> - failwith - "Node number %d is out of range (max is %d)" - n - (List.length state.broadcast_pipes - 1) - | Some pipe -> return pipe) - l - - let broadcast_block ?dests block_hash (block_header : Block_header.t) - operations = - all_pipes_or_select dests >>=? fun pipes -> - List.iter_s - (fun pipe -> - Lwt_pipe.Unbounded.push - pipe - (Broadcast_block (block_hash, block_header, operations)) ; - Lwt.return ()) - pipes - >>= return - - let inject_operation (Operation.{shell; proto} as op) = - let op_hash = Operation.hash op in - let proto_op_opt = - Data_encoding.Binary.of_bytes Protocol.operation_data_encoding proto - in - match proto_op_opt with - | Error _ -> failwith "inject_operation: cannot parse operation" - | Ok protocol_data -> - let op : Protocol.Alpha_context.packed_operation = - {shell; protocol_data} - in - User_hooks.on_inject_operation ~op_hash ~op - >>=? fun (op_hash1, op1, propagation_vector) -> - handle_propagation - (Broadcast_op (op_hash1, op1)) - propagation_vector - state.broadcast_pipes - >>=? fun () -> return op_hash1 - - let broadcast_operation ?dests - (op : Protocol.Alpha_context.packed_operation) = - all_pipes_or_select dests >>=? fun pipes -> - let op_hash = Alpha_context.Operation.hash_packed op in - List.iter_s - (fun pipe -> - Lwt_pipe.Unbounded.push pipe (Broadcast_op (op_hash, op)) ; - Lwt.return ()) - pipes - >>= return - - let pending_operations () = - let ops = state.mempool in - Lwt.return - Mockup.M.Block_services.Mempool. - { - applied = ops; - refused = Operation_hash.Map.empty; - outdated = Operation_hash.Map.empty; - branch_refused = Operation_hash.Map.empty; - branch_delayed = Operation_hash.Map.empty; - unprocessed = Operation_hash.Map.empty; - } - - let monitor_operations ~applied ~branch_delayed ~branch_refused ~refused = - ignore applied ; - ignore branch_delayed ; - ignore branch_refused ; - ignore refused ; - let streamed = ref false in - state.streaming_operations <- true ; - let next () = - let rec pop_until_ok () = - Lwt_pipe.Unbounded.pop state.operations_pipe >>= function - | None when !streamed -> Lwt.return None - | None -> - streamed := true ; - Lwt.return (Some []) - | Some op -> ( - User_hooks.on_new_operation op >>= function - | None when !streamed -> pop_until_ok () - | None -> - streamed := true ; - Lwt.return (Some []) - | Some (oph, op) -> - streamed := true ; - Lwt.return (Some [((oph, op), [])])) - in - pop_until_ok () - in - let shutdown () = () in - RPC_answer.{next; shutdown} - - let rpc_context_callback block = - locate_block state block >>=? fun x -> return x.rpc_context - - let list_blocks ~heads ~length ~min_date:_ = - let compare_block_fitnesses block0 block1 = - Fitness.compare - block0.rpc_context.block_header.fitness - block1.rpc_context.block_header.fitness - in - let hash_of_block block = block.rpc_context.block_hash in - let lookup_head head = - locate_blocks state (`Hash (head, 0)) >>=? fun xs -> - let segment = - match length with None -> xs | Some n -> List.take_n n xs - in - return - (List.map hash_of_block (List.sort compare_block_fitnesses segment)) - in - List.map_es lookup_head heads - - let live_blocks block = live_blocks state block - - let raw_protocol_data block = - locate_block state block >>=? fun x -> return x.raw_protocol_data - end in - (module Impl) - -(** Return the current head. *) -let head {chain; _} = - match List.hd chain with - | None -> failwith "mockup_simulator.ml: empty chain" - | Some hd -> return hd - -(** Clear from the mempool operations whose branch does not point to - a live block with respect to the current head. *) -let clear_mempool state = - head state >>=? fun head -> - let included_ops_hashes = - List.map - (fun (op : Mockup.M.Block_services.operation) -> op.hash) - (List.flatten head.operations) - in - live_blocks state (`Head 0) >>=? fun live_set -> - let mempool = - List.filter - (fun (_oph, (op : Mockup.M.Protocol.operation)) -> - let included_in_head = - List.mem - ~equal:Operation_hash.equal - (Alpha_context.Operation.hash_packed op) - included_ops_hashes - in - Block_hash.Set.mem op.shell.branch live_set && not included_in_head) - state.mempool - in - state.mempool <- mempool ; - return_unit - -(** Apply a block to the given [rpc_context]. *) -let reconstruct_context (rpc_context : Tezos_protocol_environment.rpc_context) - (operations : Operation.t list list) (block_header : Block_header.t) = - let header = rpc_context.block_header in - let predecessor_context = rpc_context.context in - parse_protocol_data block_header.protocol_data >>=? fun protocol_data -> - Mockup.M.Protocol.begin_application - ~chain_id - ~predecessor_context - ~predecessor_timestamp:header.timestamp - ~predecessor_fitness:header.fitness - ~cache:`Lazy - {shell = block_header.shell; protocol_data} - >>=? fun validation_state -> - let i = ref 0 in - List.fold_left_es - (List.fold_left_es (fun (validation_state, results) op -> - incr i ; - let operation_data = - Data_encoding.Binary.of_bytes_exn - Mockup.M.Protocol.operation_data_encoding - op.Operation.proto - in - let op = - {Mockup.M.Protocol.shell = op.shell; protocol_data = operation_data} - in - Mockup.M.Protocol.apply_operation validation_state op - >>=? fun (validation_state, receipt) -> - return (validation_state, receipt :: results))) - (validation_state, []) - operations - >>=? fun (validation_state, _) -> - Mockup.M.Protocol.finalize_block validation_state None - -(** Process an incoming block. If validation succeeds: - - update the current head to this new block - - cleanup outdated operations - - cleanup listener table - Note that this implementation does not handle concurrent branches. *) -let rec process_block state block_hash (block_header : Block_header.t) - operations = - let get_predecessor () = - let predecessor_hash = block_header.Block_header.shell.predecessor in - head state >>=? fun head -> - match Block_hash.Table.find state.chain_table predecessor_hash with - | None | Some [] -> ( - (* Even if the predecessor is not known locally, it might be known by - some node in the network. The code below "requests" information - about the block by its hash. *) - match - Block_hash.Table.find state.global_chain_table predecessor_hash - with - | None -> failwith "get_predecessor: unknown predecessor block" - | Some predecessor -> - let predecessor_block_header = - Block_header. - { - shell = predecessor.rpc_context.block_header; - protocol_data = predecessor.raw_protocol_data; - } - in - let predecessor_ops = - List.map - (fun xs -> - List.map - (fun (op : Mockup.M.Block_services.operation) -> - Operation. - { - shell = op.shell; - proto = - Data_encoding.Binary.to_bytes_exn - Protocol.operation_data_encoding - op.protocol_data; - }) - xs) - predecessor.operations - in - (* If the block is found, apply it before proceeding. *) - process_block - state - predecessor.rpc_context.block_hash - predecessor_block_header - predecessor_ops - >>=? fun () -> return predecessor) - | Some (predecessor :: _) -> - if - Int32.sub - head.rpc_context.block_header.level - predecessor.rpc_context.block_header.level - <= 2l - then return predecessor - else failwith "get_predecessor: the predecessor block is too old" - in - match Block_hash.Table.find state.chain_table block_hash with - | Some _ -> - (* The block is already known. *) - return_unit - | None -> - get_predecessor () >>=? fun predecessor -> - head state >>=? fun head -> - reconstruct_context predecessor.rpc_context operations block_header - >>=? fun ({context; _}, _) -> - let rpc_context = - Tezos_protocol_environment. - {context; block_hash; block_header = block_header.shell} - in - let operations = - List.map - (fun pass -> - List.map - (fun (Operation.{shell; proto} as op) -> - let hash : Operation_hash.t = Operation.hash op in - let protocol_data : Alpha_context.packed_protocol_data = - Data_encoding.Binary.of_bytes_exn - Protocol.operation_data_encoding - proto - in - let receipt = None in - { - Mockup.M.Block_services.chain_id; - hash; - shell; - protocol_data; - receipt; - }) - pass) - operations - in - parse_protocol_data block_header.protocol_data >>=? fun protocol_data -> - let new_block = - { - rpc_context; - protocol_data; - raw_protocol_data = block_header.protocol_data; - operations; - } - in - let predecessor_hash = block_header.Block_header.shell.predecessor in - let tail = - Block_hash.Table.find state.chain_table predecessor_hash - |> WithExceptions.Option.get ~loc:__LOC__ - in - let new_chain = new_block :: tail in - Block_hash.Table.replace state.chain_table block_hash new_chain ; - Block_hash.Table.replace state.global_chain_table block_hash new_block ; - Context_hash.Table.replace - state.ctxt_table - rpc_context.Environment_context.block_header.context - rpc_context ; - if - Fitness.( - block_header.shell.fitness > head.rpc_context.block_header.fitness) - then ( - state.chain <- new_chain ; - clear_mempool state >>=? fun () -> - (* The head has changed, the messages in the operations pipe are no - good anymore. *) - ignore (Lwt_pipe.Unbounded.pop_all_now state.operations_pipe) ; - (if state.streaming_operations then ( - state.streaming_operations <- false ; - Lwt_pipe.Unbounded.push state.operations_pipe None ; - Lwt.return ()) - else Lwt.return ()) - >>= fun () -> - (* Put back in the pipe operations that are still alive. *) - List.iter_s - (fun op -> - Lwt_pipe.Unbounded.push state.operations_pipe (Some op) ; - Lwt.return ()) - state.mempool - >>= fun () -> return_unit) - else return_unit - -(** This process listens to broadcast block and operations and incorporates - them in the context of the fake node. *) -let rec listener ~(user_hooks : (module Hooks)) ~state ~broadcast_pipe = - let module User_hooks = (val user_hooks : Hooks) in - Lwt_pipe.Unbounded.pop broadcast_pipe >>= function - | Broadcast_op (operation_hash, packed_operation) -> - state.mempool <- (operation_hash, packed_operation) :: state.mempool ; - Lwt_pipe.Unbounded.push - state.operations_pipe - (Some (operation_hash, packed_operation)) ; - User_hooks.check_mempool_after_processing ~mempool:state.mempool - >>=? fun () -> listener ~user_hooks ~state ~broadcast_pipe - | Broadcast_block (block_hash, block_header, operations) -> - get_block_level block_header >>=? fun level -> - get_block_round block_header >>=? fun round -> - parse_protocol_data block_header.protocol_data >>=? fun protocol_data -> - User_hooks.check_block_before_processing - ~level - ~round - ~block_hash - ~block_header - ~protocol_data - >>=? fun () -> - process_block state block_hash block_header operations >>=? fun () -> - User_hooks.check_chain_after_processing ~level ~round ~chain:state.chain - >>=? fun () -> - Lwt_pipe.Unbounded.push state.heads_pipe (block_hash, block_header) ; - listener ~user_hooks ~state ~broadcast_pipe - -(** Create a fake node state. *) -let create_fake_node_state ~i ~live_depth - ~(genesis_block : Block_header.t * Environment_context.rpc_context) - ~global_chain_table ~broadcast_pipes = - let (block_header0, rpc_context0) = genesis_block in - parse_protocol_data block_header0.protocol_data >>=? fun protocol_data -> - let genesis0 = - { - rpc_context = rpc_context0; - protocol_data; - raw_protocol_data = block_header0.protocol_data; - operations = [[]; []; []; []]; - } - in - let chain0 = [genesis0] in - let heads_pipe = Lwt_pipe.Unbounded.create () in - let operations_pipe = Lwt_pipe.Unbounded.create () in - let genesis_block_true_hash = - Block_header.hash - { - shell = rpc_context0.block_header; - protocol_data = block_header0.protocol_data; - } - in - Lwt_pipe.Unbounded.push heads_pipe (rpc_context0.block_hash, block_header0) ; - return - { - instance_index = i; - live_depth; - mempool = []; - chain = chain0; - chain_table = - Block_hash.Table.of_seq - (List.to_seq - [ - (rpc_context0.block_hash, chain0); - (genesis_block_true_hash, chain0); - (genesis_predecessor_block_hash, chain0); - ]); - global_chain_table; - ctxt_table = - Context_hash.Table.of_seq - (List.to_seq - [ - ( rpc_context0.Environment_context.block_header - .Block_header.context, - rpc_context0 ); - ]); - heads_pipe; - operations_pipe; - streaming_operations = false; - broadcast_pipes; - genesis_block_true_hash; - } - -(** Start baker process. *) -let baker_process ~(delegates : Baking_state.delegate list) ~base_dir - ~(genesis_block : Block_header.t * Environment_context.rpc_context) ~i - ~global_chain_table ~broadcast_pipes ~(user_hooks : (module Hooks)) = - let broadcast_pipe = - List.nth broadcast_pipes i |> WithExceptions.Option.get ~loc:__LOC__ - in - create_fake_node_state - ~i - ~live_depth:60 - ~genesis_block - ~global_chain_table - ~broadcast_pipes - >>=? fun state -> - let filesystem = String.Hashtbl.create 10 in - let wallet = new Faked_client_context.faked_io_wallet ~base_dir ~filesystem in - let cctxt = - let hooks = make_mocked_services_hooks state user_hooks in - new Protocol_client_context.wrap_full - (new Faked_client_context.unix_faked - ~base_dir - ~filesystem - ~chain_id - ~hooks) - in - let module User_hooks = (val user_hooks : Hooks) in - User_hooks.on_start_baker ~baker_position:i ~delegates ~cctxt >>= fun () -> - List.iter_es - (fun ({alias; public_key; public_key_hash; secret_key_uri} : - Baking_state.delegate) -> - let open Tezos_client_base in - let name = alias |> WithExceptions.Option.get ~loc:__LOC__ in - Client_keys.neuterize secret_key_uri >>=? fun public_key_uri -> - Client_keys.register_key - wallet - ~force:false - (public_key_hash, public_key_uri, secret_key_uri) - ~public_key - name) - delegates - >>=? fun () -> - let context_index = - let open Abstract_context_index in - { - checkout_fun = - (fun hash -> - Context_hash.Table.find state.ctxt_table hash - |> Option.map (fun Environment_context.{context; _} -> context) - |> Lwt.return); - finalize_fun = Lwt.return; - } - in - let module User_hooks = (val user_hooks : Hooks) in - let listener_process () = listener ~user_hooks ~state ~broadcast_pipe in - let stop_on_event event = User_hooks.stop_on_event event in - let baker_process () = - Faked_daemon.Baker.run - ~cctxt - ~stop_on_event - ~chain_id - ~context_index - ~delegates - in - Lwt.pick [listener_process (); baker_process ()] >>=? fun () -> - User_hooks.check_chain_on_success ~chain:state.chain - -let genesis_protocol_data (baker_sk : Signature.secret_key) - (predecessor_block_hash : Block_hash.t) - (block_header : Block_header.shell_header) : Bytes.t = - let proof_of_work_nonce = - Bytes.create Protocol.Alpha_context.Constants.proof_of_work_nonce_size - in - let operation_list_hash = Operation_list_hash.compute [] in - let payload_hash = - Protocol.Alpha_context.Block_payload.hash - ~predecessor:predecessor_block_hash - Alpha_context.Round.zero - operation_list_hash - in - let contents = - Protocol.Alpha_context.Block_header. - { - payload_hash; - payload_round = Alpha_context.Round.zero; - proof_of_work_nonce; - seed_nonce_hash = None; - liquidity_baking_escape_vote = - Baking_configuration.default_liquidity_baking_escape_vote; - } - in - let unsigned_header = - Data_encoding.Binary.to_bytes_exn - Protocol.Alpha_context.Block_header.unsigned_encoding - (block_header, contents) - in - let signature = - Signature.sign - ~watermark: - Alpha_context.Block_header.(to_watermark (Block_header chain_id)) - baker_sk - unsigned_header - in - Data_encoding.Binary.to_bytes_exn - Protocol.Alpha_context.Block_header.protocol_data_encoding - {contents; signature} - -(** Figure out who should be the signer for the genesis block. *) -let deduce_baker_sk - (accounts_with_secrets : - (Protocol.Alpha_context.Parameters.bootstrap_account - * Tezos_mockup_commands.Mockup_wallet.bootstrap_secret) - list) (total_accounts : int) (level : int) : - Signature.secret_key tzresult Lwt.t = - (match (total_accounts, level) with - | (_, 0) -> return 0 (* apparently this doesn't really matter *) - | _ -> - failwith - "cannot deduce baker for a genesis block, total accounts = %d, level = \ - %d" - total_accounts - level) - >>=? fun baker_index -> - let (_, secret) = - List.nth accounts_with_secrets baker_index - |> WithExceptions.Option.get ~loc:__LOC__ - in - let secret_key = - Signature.Secret_key.of_b58check_exn (Uri.path (secret.sk_uri :> Uri.t)) - in - return secret_key - -(** Generate the two initial genesis blocks. *) -let make_genesis_context ~delegate_selection ~round0 ~round1 - ~consensus_committee_size ~consensus_threshold accounts_with_secrets - (total_accounts : int) = - let default_constants = Mockup.Protocol_parameters.default_value.constants in - let round_durations = - let open Alpha_context in - Stdlib.Option.get - (Round.Durations.create_opt - ~first_round_duration:(Period.of_seconds_exn round0) - ~delay_increment_per_round: - (Period.of_seconds_exn (Int64.sub round1 round0))) - in - let constants = - { - default_constants with - delegate_selection; - consensus_committee_size; - consensus_threshold; - minimal_block_delay = Alpha_context.Period.of_seconds_exn (max 1L round0); - delay_increment_per_round = - Alpha_context.Period.of_seconds_exn Int64.(max 1L (sub round1 round0)); - } - in - let common_parameters = - Mockup.Protocol_parameters.{default_value with constants} - in - let make_block0 initial_timestamp = - let parameters = {common_parameters with initial_timestamp} in - let reencoded_parameters = - Data_encoding.Binary.of_bytes_exn Mockup.M.parameters_encoding - @@ Data_encoding.Binary.to_bytes_exn - Mockup.Protocol_parameters.encoding - parameters - in - let from_bootstrap_account i - ( (account : Protocol.Alpha_context.Parameters.bootstrap_account), - (secret : Tezos_mockup_commands.Mockup_wallet.bootstrap_secret) ) : - Mockup.Parsed_account.t = - { - name = Format.sprintf "bootstrap%d" (i + 1); - sk_uri = secret.sk_uri; - amount = account.amount; - } - in - let bootstrap_accounts = - Data_encoding.Json.construct - (Data_encoding.list Mockup.Parsed_account.encoding) - (List.mapi from_bootstrap_account accounts_with_secrets) - in - Mockup.M.init - ~cctxt:Faked_client_context.logger - ~parameters:reencoded_parameters - ~constants_overrides_json:None - ~bootstrap_accounts_json:(Some bootstrap_accounts) - >>=? fun {chain = _; rpc_context = rpc_context0; protocol_data = _} -> - let block_header0 = - { - rpc_context0.block_header with - predecessor = genesis_predecessor_block_hash; - } - in - let rpc_context = {rpc_context0 with block_header = block_header0} in - deduce_baker_sk accounts_with_secrets total_accounts 0 >>=? fun baker_sk -> - let protocol_data = - genesis_protocol_data - baker_sk - genesis_predecessor_block_hash - rpc_context.block_header - in - let block_header = - Block_header.{shell = rpc_context.block_header; protocol_data} - in - return (block_header, rpc_context) - in - - let level0_round0_duration = - Protocol.Alpha_context.Round.round_duration - round_durations - Alpha_context.Round.zero - in - let timestamp0 = - Time.Protocol.of_seconds - Int64.( - sub - (of_float (Unix.time ())) - (Alpha_context.Period.to_seconds level0_round0_duration)) - in - make_block0 timestamp0 - -(** By default, propagate every message everywhere. *) -let default_propagation_vector = List.repeat 5 Pass - -module Default_hooks : Hooks = struct - let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations - ~protocol_data:_ = - return (block_hash, block_header, operations, default_propagation_vector) - - let on_inject_operation ~op_hash ~op = - return (op_hash, op, default_propagation_vector) - - let on_new_head ~block_hash ~block_header = - Lwt.return (Some (block_hash, block_header)) - - let on_new_operation x = Lwt.return_some x - - let check_block_before_processing ~level:_ ~round:_ ~block_hash:_ - ~block_header:_ ~protocol_data:_ = - return_unit - - let check_chain_after_processing ~level:_ ~round:_ ~chain:_ = return_unit - - let check_mempool_after_processing ~mempool:_ = return_unit - - let stop_on_event _ = false - - let on_start_baker ~baker_position:_ ~delegates:_ ~cctxt:_ = Lwt.return_unit - - let check_chain_on_success ~chain:_ = return_unit -end - -type config = { - debug : bool; - round0 : int64; - round1 : int64; - timeout : int; - delegate_selection : Alpha_context.Constants.delegate_selection; - consensus_committee_size : int; - consensus_threshold : int; -} - -let default_config = - { - debug = false; - round0 = 2L; - (* Rounds should be long enough for the bakers to - exchange all the necessary messages. *) - round1 = 3L (* No real need to increase round durations. *); - timeout = 10; - delegate_selection = Random; - consensus_committee_size = - Default_parameters.constants_mainnet.consensus_committee_size; - consensus_threshold = - Default_parameters.constants_mainnet.consensus_threshold; - } - -let make_baking_delegate - ( (account : Alpha_context.Parameters.bootstrap_account), - (secret : Tezos_mockup_commands.Mockup_wallet.bootstrap_secret) ) : - Baking_state.delegate = - Baking_state. - { - alias = Some secret.name; - public_key = account.public_key |> WithExceptions.Option.get ~loc:__LOC__; - public_key_hash = account.public_key_hash; - secret_key_uri = secret.sk_uri; - } - -let run ?(config = default_config) bakers_spec = - Tezos_client_base.Client_keys.register_signer - (module Tezos_signer_backends.Unencrypted) ; - let total_accounts = - List.fold_left (fun acc (n, _) -> acc + n) 0 bakers_spec - in - if total_accounts = 0 then - failwith "the simulation should use at least one delegate" - else if total_accounts > 5 then - failwith "only up to 5 bootstrap accounts are available" - else - (* When logging is enabled it may cause non-termination: - - https://gitlab.com/nomadic-labs/tezos/-/issues/546 - - In particular, it seems that when logging is enabled the baker - process can get cancelled without executing its Lwt finalizer. *) - (if config.debug then Internal_event_unix.init () else Lwt.return_unit) - >>= fun () -> - let total_bakers = List.length bakers_spec in - (List.init ~when_negative_length:() total_bakers (fun _ -> - Lwt_pipe.Unbounded.create ()) - |> function - | Error () -> failwith "impossible: negative length of the baker spec" - | Ok xs -> return xs) - >>=? fun broadcast_pipes -> - let global_chain_table = Block_hash.Table.create 10 in - Tezos_mockup_commands.Mockup_wallet.default_bootstrap_accounts - >>=? fun bootstrap_secrets -> - let accounts_with_secrets = - List.combine_drop (List.take_n total_accounts accounts) bootstrap_secrets - in - let all_delegates = List.map make_baking_delegate accounts_with_secrets in - make_genesis_context - ~delegate_selection:config.delegate_selection - ~round0:config.round0 - ~round1:config.round1 - ~consensus_committee_size:config.consensus_committee_size - ~consensus_threshold:config.consensus_threshold - accounts_with_secrets - total_accounts - >>=? fun genesis_block -> - let take_third (_, _, x) = x in - let timeout_process () = - Lwt_unix.sleep (Float.of_int config.timeout) >>= fun () -> - failwith "the test is taking longer than %d seconds@." config.timeout - in - Lwt.pick - [ - timeout_process (); - Lwt_tzresult_syntax.join - (take_third - (List.fold_left - (fun (i, delegates_acc, ms) (n, user_hooks) -> - let (delegates, leftover_delegates) = - List.split_n n delegates_acc - in - let m = - baker_process - ~delegates - ~base_dir:"dummy" - ~genesis_block - ~i - ~global_chain_table - ~broadcast_pipes - ~user_hooks - in - (i + 1, leftover_delegates, m :: ms)) - (0, all_delegates, []) - bakers_spec)); - ] - -let get_account_pk i = - match List.nth accounts i with - | None -> assert false - | Some acc -> acc.public_key |> WithExceptions.Option.get ~loc:__LOC__ - -let bootstrap1 = get_account_pk 0 - -let bootstrap2 = get_account_pk 1 - -let bootstrap3 = get_account_pk 2 - -let bootstrap4 = get_account_pk 3 - -let bootstrap5 = get_account_pk 4 - -let check_block_signature ~block_hash ~(block_header : Block_header.t) - ~public_key = - let (protocol_data : Protocol.Alpha_context.Block_header.protocol_data) = - Data_encoding.Binary.of_bytes_exn - Protocol.Alpha_context.Block_header.protocol_data_encoding - block_header.protocol_data - in - let unsigned_header = - Data_encoding.Binary.to_bytes_exn - Protocol.Alpha_context.Block_header.unsigned_encoding - (block_header.shell, protocol_data.contents) - in - if - Signature.check - ~watermark: - Alpha_context.Block_header.(to_watermark (Block_header chain_id)) - public_key - protocol_data.signature - unsigned_header - then return_unit - else - failwith - "unexpected signature for %a; tried with %a@." - Block_hash.pp - block_hash - Signature.Public_key.pp - public_key - -type op_predicate = - Operation_hash.t -> Alpha_context.packed_operation -> bool tzresult Lwt.t - -let mempool_count_ops ~mempool ~predicate = - List.map_es (fun (op_hash, op) -> predicate op_hash op) mempool - >>=? fun results -> - return - (List.fold_left - (fun acc result -> if result then acc + 1 else acc) - 0 - results) - -let mempool_has_op ~mempool ~predicate = - mempool_count_ops ~mempool ~predicate >>=? fun n -> return (n > 0) - -let mempool_has_op_ref ~mempool ~predicate ~var = - mempool_has_op ~mempool ~predicate >>=? fun result -> - if result then var := true ; - return_unit - -let op_is_signed_by ~public_key (op_hash : Operation_hash.t) - (op : Alpha_context.packed_operation) = - match op.protocol_data with - | Operation_data d -> ( - (match d.contents with - | Single op_contents -> - return - (match op_contents with - | Endorsement _ -> - Alpha_context.Operation.to_watermark (Endorsement chain_id) - | Preendorsement _ -> - Alpha_context.Operation.to_watermark (Preendorsement chain_id) - | _ -> Signature.Generic_operation) - | _ -> failwith "unexpected contents in %a@." Operation_hash.pp op_hash) - >>=? fun watermark -> - match d.signature with - | None -> - failwith - "did not find a signature for op %a@." - Operation_hash.pp - op_hash - | Some signature -> - let unsigned_operation_bytes = - Data_encoding.Binary.to_bytes_exn - Protocol.Alpha_context.Operation.unsigned_encoding - (op.shell, Contents_list d.contents) - in - return - (Signature.check - ~watermark - public_key - signature - unsigned_operation_bytes)) - -let op_is_preendorsement ?level ?round (op_hash : Operation_hash.t) - (op : Alpha_context.packed_operation) = - match op.protocol_data with - | Operation_data d -> ( - match d.contents with - | Single op_contents -> ( - match op_contents with - | Preendorsement consensus_content -> - let right_level = - match level with - | None -> true - | Some expected_level -> - Int32.equal - (Alpha_context.Raw_level.to_int32 consensus_content.level) - expected_level - in - let right_round = - match round with - | None -> true - | Some expected_round -> - Int32.equal - (Alpha_context.Round.to_int32 consensus_content.round) - expected_round - in - return (right_level && right_round) - | _ -> return false) - | _ -> failwith "unexpected contents in %a@." Operation_hash.pp op_hash) - -let op_is_endorsement ?level ?round (op_hash : Operation_hash.t) - (op : Alpha_context.packed_operation) = - match op.protocol_data with - | Operation_data d -> ( - match d.contents with - | Single op_contents -> ( - match op_contents with - | Endorsement consensus_content -> - let right_level = - match level with - | None -> true - | Some expected_level -> - Int32.equal - (Alpha_context.Raw_level.to_int32 consensus_content.level) - expected_level - in - let right_round = - match round with - | None -> true - | Some expected_round -> - Int32.equal - (Alpha_context.Round.to_int32 consensus_content.round) - expected_round - in - return (right_level && right_round) - | _ -> return false) - | _ -> failwith "unexpected contents in %a@." Operation_hash.pp op_hash) - -let op_is_both f g op_hash op = - f op_hash op >>=? fun f_result -> - if f_result then g op_hash op else return false - -let save_proposal_payload - ~(protocol_data : Alpha_context.Block_header.protocol_data) ~var = - var := - Some - (protocol_data.contents.payload_hash, protocol_data.contents.payload_round) ; - return_unit - -let verify_payload_hash - ~(protocol_data : Alpha_context.Block_header.protocol_data) - ~original_proposal ~message = - match !original_proposal with - | None -> - failwith - "verify_payload_hash: expected to have observed a proposal by now" - | Some (original_hash, original_round) -> - if - Protocol.Block_payload_hash.equal - original_hash - protocol_data.contents.payload_hash - && Protocol.Alpha_context.Round.equal - original_round - protocol_data.contents.payload_round - then return_unit - else failwith "verify_payload_hash: %s" message - -let get_block_round block = - round_from_raw_fitness block.rpc_context.block_header.fitness diff --git a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/mockup_simulator.mli b/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/mockup_simulator.mli deleted file mode 100644 index c538ab3a01b7..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/mockup_simulator/mockup_simulator.mli +++ /dev/null @@ -1,244 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Representation of a block in the simulator. *) -type block = { - rpc_context : Environment_context.rpc_context; - protocol_data : Protocol.Alpha_context.Block_header.protocol_data; - raw_protocol_data : Bytes.t; - operations : Mockup.M.Block_services.operation list list; -} - -(** Chain is a list of blocks. *) -type chain = block list - -(** How an operation or block should propagate through the network. *) -type propagation = - | Block (** Block the operation/block, it'll never be delivered. *) - | Pass (** Pass the operation/block as is. *) - | Delay of float - (** Delay the operation/block for the given number of seconds. *) - -(** Values of this type specify to which bakers a block or operation should - be delivered. *) -type propagation_vector = propagation list - -(** The way to control behavior of a mockup node. *) -module type Hooks = sig - (** This function is called on injection of a block by a particular baker. - It allows us to inspect, change, or discard the block. Calling the - injection RPC and actually updating the state of the mockup node are - two different operations. Normally the first entails the latter, but - not always. In particular, the [propagation_vector] controls what - bakers will see and incorporate the block. *) - val on_inject_block : - level:int32 -> - round:int32 -> - block_hash:Block_hash.t -> - block_header:Block_header.t -> - operations:Operation.t list list -> - protocol_data:Alpha_context.Block_header.protocol_data -> - (Block_hash.t * Block_header.t * Operation.t list list * propagation_vector) - tzresult - Lwt.t - - (** This function is called on injection of an operation. It is similar - to [on_inject_block], which see. *) - val on_inject_operation : - op_hash:Operation_hash.t -> - op:Alpha_context.packed_operation -> - (Operation_hash.t * Alpha_context.packed_operation * propagation_vector) - tzresult - Lwt.t - - (** This is called when a new head is going to be sent as the response to - a "monitor heads" RPC call. Returning [None] here terminates the - process for the baker. *) - val on_new_head : - block_hash:Block_hash.t -> - block_header:Block_header.t -> - (Block_hash.t * Block_header.t) option Lwt.t - - (** This is called when a new operation is going to be sent as the - response to a "monitor operations" RPC call. Returning [None] here - indicates that the node has advanced to the next level. *) - val on_new_operation : - Operation_hash.t * Alpha_context.packed_operation -> - (Operation_hash.t * Alpha_context.packed_operation) option Lwt.t - - (** Check a block before processing it in the mockup. *) - val check_block_before_processing : - level:int32 -> - round:int32 -> - block_hash:Block_hash.t -> - block_header:Block_header.t -> - protocol_data:Alpha_context.Block_header.protocol_data -> - unit tzresult Lwt.t - - (** Check the chain after processing a proposal. *) - val check_chain_after_processing : - level:int32 -> round:int32 -> chain:chain -> unit tzresult Lwt.t - - (** Check operations in the mempool after injecting an operation. *) - val check_mempool_after_processing : - mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> - unit tzresult Lwt.t - - (** This hook is used to decide when the baker is supposed to shut down. - It is triggered by receiving an event. *) - val stop_on_event : Baking_state.event -> bool - - (** This hook is used to gather information on the baker when it is - started (usually recording for later use). The first argument - [baker_position], is the position of the baker in the list of - bakers that were started for this run. *) - val on_start_baker : - baker_position:int -> - delegates:Baking_state.delegate list -> - cctxt:Protocol_client_context.full -> - unit Lwt.t - - (** Check to run on the chain upon successful termination. *) - val check_chain_on_success : chain:chain -> unit tzresult Lwt.t -end - -(** The default hook implementation. *) -module Default_hooks : Hooks - -(** Simulation configuration. *) -type config = { - debug : bool; - (** Whether to initialize the event system in order to display - information about the progress of the simulation. *) - round0 : int64; (** Duration of the round 0 in seconds. *) - round1 : int64; (** Duration of the round 1 in seconds. *) - timeout : int; - (** Maximal duration of the test. If the test takes - longer to terminate it'll be aborted with an - error. *) - delegate_selection : Alpha_context.Constants.delegate_selection; - (** Selection strategy for delegates per level *) - consensus_committee_size : int; - (** Size of the committee for tenderbake in number of slots *) - consensus_threshold : int; - (** Threshold, in number of slots, for the quorum to be considered - reached. Should be [2 * consensus_committee_size / 3 + 1] in - usual setting for tenderbake. *) -} - -(** Default configuration. *) -val default_config : config - -(** [run spec] runs a simulation according to the [spec]. Elements of [spec] - describe bakers: how many delegate each baker has and how it behaves. The - total number of delegates cannot exceed 5 for now (it is easy to increase - this limit). The delegates are assigned in order, gradually exhausting - the standard bootstrap accounts. For example, if the first baker has 3 - delegates and the second one has 2 delegates, we have the following - distribution of bootstrap accounts: - - Baker no. 1: bootstrap1, bootstrap2, bootstrap3 - - Baker no. 2: bootstrap4, bootstrap5 - - A simulation continues till all nodes finish either with an error or - successfully. If at least one node finishes with an error, it propagates - to the final result. *) -val run : ?config:config -> (int * (module Hooks)) list -> unit tzresult Lwt.t - -val bootstrap1 : Signature.public_key - -val bootstrap2 : Signature.public_key - -val bootstrap3 : Signature.public_key - -val bootstrap4 : Signature.public_key - -val bootstrap5 : Signature.public_key - -(** Check if a block header is signed by a given delegate. *) -val check_block_signature : - block_hash:Block_hash.t -> - block_header:Block_header.t -> - public_key:Signature.public_key -> - unit tzresult Lwt.t - -(** A shortcut type for predicates on operations. *) -type op_predicate = - Operation_hash.t -> Alpha_context.packed_operation -> bool tzresult Lwt.t - -(** Count the number of operations in the mempool that satisfy the given - predicate. *) -val mempool_count_ops : - mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> - predicate:op_predicate -> - int tzresult Lwt.t - -(** Check if the mempool has at least one operation that satisfies the given - predicate. *) -val mempool_has_op : - mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> - predicate:op_predicate -> - bool tzresult Lwt.t - -(** Similar to [mempool_has_op] but instead of returning a [bool] it sets - the given [bool ref]. *) -val mempool_has_op_ref : - mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> - predicate:op_predicate -> - var:bool ref -> - unit tzresult Lwt.t - -(** Check if an operation is signed by the given delegate. *) -val op_is_signed_by : public_key:Signature.public_key -> op_predicate - -(** Check that an operation is a preendorsement. *) -val op_is_preendorsement : ?level:int32 -> ?round:int32 -> op_predicate - -(** Check that an operation is an endorsement. *) -val op_is_endorsement : ?level:int32 -> ?round:int32 -> op_predicate - -(** Combine two predicates. *) -val op_is_both : op_predicate -> op_predicate -> op_predicate - -(** Set the given variable to save payload hash and payload round. *) -val save_proposal_payload : - protocol_data:Alpha_context.Block_header.protocol_data -> - var:(Block_payload_hash.t * Alpha_context.Round.t) option ref -> - unit tzresult Lwt.t - -(** Check that payload hashes match, fail if it is not the case. *) -val verify_payload_hash : - protocol_data:Alpha_context.Block_header.protocol_data -> - original_proposal:(Block_payload_hash.t * Alpha_context.Round.t) option ref -> - message:string -> - unit tzresult Lwt.t - -(** Parse protocol data. *) -val parse_protocol_data : - Bytes.t -> Alpha_context.Block_header.protocol_data tzresult Lwt.t - -(** Get round of a block. *) -val get_block_round : block -> int32 tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_delegate/test/test_scenario.ml b/src/proto_012_Psithaca/lib_delegate/test/test_scenario.ml deleted file mode 100644 index b88fa46c0b75..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/test/test_scenario.ml +++ /dev/null @@ -1,1317 +0,0 @@ -open Mockup_simulator - -(* - -Test that the chain reaches the 5th level. - -*) - -let test_level_5 () = - let level_to_reach = 5l in - let module Hooks : Hooks = struct - include Default_hooks - - let stop_on_event = function - | Baking_state.New_proposal {block; _} -> - (* Stop the node as soon as we receive a proposal with a level - higher than [level_to_reach]. *) - block.shell.level > level_to_reach - | _ -> false - - let check_chain_on_success ~chain = - (* Make sure that all decided blocks have been decided at round 0. *) - let round_is_zero block = - let level = block.rpc_context.block_header.level in - get_block_round block >>=? fun round -> - if Int32.equal round 0l then return () - else failwith "block at level %ld was selected at round %ld" level round - in - List.iter_es round_is_zero chain - end in - (* Here we start two bakers, one with 3 delegates (bootstrap1, bootstrap2, - bootstrap3) and the other with 2 delegates (bootstrap4, bootstrap5). - The simulation continues till both nodes stop, see [stop_on_event] - above. *) - let config = - { - default_config with - timeout = Int32.to_int level_to_reach * 3; - round0 = 2L; - round1 = 3L; - } - in - run ~config [(3, (module Hooks)); (2, (module Hooks))] - -(* - -Scenario T1 - -1. Node A proposes at the round 0. -2. Both node A and node B preendorse. -3. Node A stops. -4. Node B endorses in the round 0 and locks. No decision is taken at the - round 0 because A did not endorse. -5. We check that in round 1 (the next slot for B), B proposes the same - value as A proposed in the round 0, not a new proposal. -*) - -let test_scenario_t1 () = - let original_proposal = ref None in - let a_preendorsed = ref false in - let b_preendorsed = ref false in - let b_endorsed = ref false in - let b_reproposed = ref false in - (* Here we use custom hooks to make each node/baker behave according to - its role in the scenario. *) - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let check_mempool_after_processing ~mempool = - mempool_has_op_ref - ~mempool - ~predicate: - (op_is_both - (op_is_signed_by ~public_key:bootstrap1) - (op_is_preendorsement ~level:1l ~round:0l)) - ~var:a_preendorsed - - let stop_on_event _ = !a_preendorsed - end in - let module Node_b_hooks : Hooks = struct - include Default_hooks - - let check_block_before_processing ~level ~round ~block_hash ~block_header - ~(protocol_data : Protocol.Alpha_context.Block_header.protocol_data) = - (match (!b_endorsed, level, round) with - | (false, 1l, 0l) -> - (* If any of the checks fails the whole scenario will fail. *) - check_block_signature ~block_hash ~block_header ~public_key:bootstrap1 - >>=? fun () -> - save_proposal_payload ~protocol_data ~var:original_proposal - | (true, 1l, 1l) -> - check_block_signature ~block_hash ~block_header ~public_key:bootstrap2 - >>=? fun () -> - verify_payload_hash - ~protocol_data - ~original_proposal - ~message:"a new block proposed instead of reproposal" - >>=? fun () -> - b_reproposed := true ; - return_unit - | _ -> failwith "unexpected level = %ld / round = %ld" level round) - >>=? fun () -> return_unit - - let check_mempool_after_processing ~mempool = - mempool_has_op_ref - ~mempool - ~predicate: - (op_is_both - (op_is_signed_by ~public_key:bootstrap2) - (op_is_preendorsement ~level:1l ~round:0l)) - ~var:b_preendorsed - >>=? fun () -> - mempool_has_op_ref - ~mempool - ~predicate: - (op_is_both - (op_is_signed_by ~public_key:bootstrap2) - (op_is_preendorsement ~level:1l ~round:0l)) - ~var:b_endorsed - - let stop_on_event _ = !b_reproposed - end in - let config = - { - default_config with - delegate_selection = Round_robin_over [[bootstrap1; bootstrap2]]; - } - in - run ~config [(1, (module Node_a_hooks)); (1, (module Node_b_hooks))] - -(* - -Scenario T2 - -1. Node A should propose at the round 0, but it is dead. -2. Node B waits til it has its proposal slot at round 1 and proposes then. - -*) - -let test_scenario_t2 () = - let b_proposed = ref false in - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let stop_on_event _ = true (* Node A stops immediately. *) - end in - let module Node_b_hooks : Hooks = struct - include Default_hooks - - let check_block_before_processing ~level ~round ~block_hash ~block_header - ~protocol_data:_ = - (* Here we test that the only block that B observes is its own - proposal for level 1 at round 1. *) - match (level, round) with - | (1l, 1l) -> - check_block_signature ~block_hash ~block_header ~public_key:bootstrap2 - >>=? fun () -> - b_proposed := true ; - return_unit - | _ -> failwith "unexpected level = %ld / round = %ld" level round - - let stop_on_event _ = - (* Stop as soon as B has proposed. This ends the test. *) - !b_proposed - end in - let config = - { - default_config with - delegate_selection = Round_robin_over [[bootstrap1; bootstrap2]]; - } - in - run ~config [(1, (module Node_a_hooks)); (1, (module Node_b_hooks))] - -(* - -Scenario T3 - -1. There are four nodes: A, B, C, and D. -2. C is the proposer at the round 0. It sends the proposal, which is - received by all bakers except for D. -3. Due to how the messages propagate, only B sees 3 preendorsements. It - endorses and locks. Other nodes all see fewer than 3 preendorsements. - - A -> A and B - B -> B - C -> C and B - -4. D proposes at the round 1. Its message reaches 3 nodes, including B. - - D -> D, B, C - -5. B does not preendorse because it is locked. -6. No decision is taken at the round 1. -7. B proposes at the round 2. There are no more problems with propagation of - messages, so a decision is reached. - -*) - -let test_scenario_t3 () = - let b_observed_pqc = ref false in - let original_proposal = ref None in - let we_are_done = ref false in - let stop_on_event0 _ = !we_are_done in - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let on_inject_operation ~op_hash ~op = - if !b_observed_pqc then return (op_hash, op, [Pass; Pass; Pass; Pass]) - else - op_is_preendorsement ~level:1l ~round:0l op_hash op - >>=? fun is_preendorsement -> - if is_preendorsement then - return (op_hash, op, [Pass; Pass; Block; Block]) - else failwith "unexpected operation from the node D" - - let stop_on_event = stop_on_event0 - end in - let module Node_b_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~(protocol_data : Protocol.Alpha_context.Block_header.protocol_data) = - match (level, round) with - | (1l, 2l) -> - check_block_signature ~block_hash ~block_header ~public_key:bootstrap2 - >>=? fun () -> - we_are_done := true ; - verify_payload_hash - ~protocol_data - ~original_proposal - ~message:"a new block proposed instead of reproposal" - >>=? fun () -> - return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) - | _ -> - failwith - "unexpected injection on the node B, level = %ld / round = %ld" - level - round - - let on_inject_operation ~op_hash ~op = - if !b_observed_pqc then return (op_hash, op, [Pass; Pass; Pass; Pass]) - else - op_is_preendorsement ~level:1l ~round:0l op_hash op - >>=? fun is_preendorsement -> - if is_preendorsement then - return (op_hash, op, [Block; Pass; Block; Block]) - else failwith "unexpected operation from the node B" - - let check_mempool_after_processing ~mempool = - let predicate op_hash op = - op_is_preendorsement ~level:1l ~round:0l op_hash op - in - mempool_count_ops ~mempool ~predicate >>=? fun n -> - if n > 3 then - failwith "B received too many preendorsements, expected to see only 3" - else if n = 3 then ( - b_observed_pqc := true ; - return_unit) - else return_unit - - let stop_on_event = stop_on_event0 - end in - let module Node_c_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~(protocol_data : Protocol.Alpha_context.Block_header.protocol_data) = - match (level, round) with - | (1l, 0l) -> - check_block_signature ~block_hash ~block_header ~public_key:bootstrap3 - >>=? fun () -> - save_proposal_payload ~protocol_data ~var:original_proposal - >>=? fun () -> - return - (block_hash, block_header, operations, [Pass; Pass; Pass; Block]) - | _ -> - failwith - "unexpected injection on the node C, level = %ld / round = %ld" - level - round - - let on_inject_operation ~op_hash ~op = - if !b_observed_pqc then return (op_hash, op, [Pass; Pass; Pass; Pass]) - else - op_is_preendorsement ~level:1l ~round:0l op_hash op - >>=? fun is_preendorsement -> - if is_preendorsement then - return (op_hash, op, [Block; Pass; Pass; Block]) - else failwith "unexpected operation from the node C" - - let stop_on_event = stop_on_event0 - end in - let module Node_d_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - match (level, round) with - | (1l, 1l) -> - return - (block_hash, block_header, operations, [Block; Pass; Pass; Pass]) - | _ -> - failwith - "unexpected injection on the node D, level = %ld / round = %ld" - level - round - - let on_inject_operation ~op_hash ~op = - if !b_observed_pqc then return (op_hash, op, [Pass; Pass; Pass; Pass]) - else return (op_hash, op, [Block; Block; Block; Block]) - - let stop_on_event = stop_on_event0 - end in - let config = - { - default_config with - delegate_selection = - Round_robin_over - [ - [bootstrap3; bootstrap4; bootstrap2; bootstrap1]; - [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; - ]; - } - in - run - ~config - [ - (1, (module Node_a_hooks)); - (1, (module Node_b_hooks)); - (1, (module Node_c_hooks)); - (1, (module Node_d_hooks)); - ] - -(* - -Scenario F1 - -1. Node C (bootstrap3) proposes at level 1 round 0, its proposal reaches all - nodes. -2. Propagation of preendorsements happens in such a way that only Node A - (bootstrap1) observes PQC: - - A -> A - B -> B and A - C -> C and A - D -> D and A - - Node A locks. - -3. At the level 1 round 1 node D (bootstrap4) proposes. Propagation of - messages is normal. - -4. Node A (bootstrap1) should propose at level 2 round 0. - -*) - -let test_scenario_f1 () = - let c_proposed_l1_r0 = ref false in - let d_proposed_l1_r1 = ref false in - let a_proposed_l2_r0 = ref false in - let stop_on_event0 _ = !a_proposed_l2_r0 in - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - match (!c_proposed_l1_r0, !d_proposed_l1_r1, level, round) with - | (true, true, 2l, 0l) -> - check_block_signature ~block_hash ~block_header ~public_key:bootstrap1 - >>=? fun () -> - (a_proposed_l2_r0 := true ; - return_unit) - >>=? fun () -> - return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) - | _ -> - failwith - "unexpected injection on the node A, level = %ld / round = %ld" - level - round - - let on_inject_operation ~op_hash ~op = - match (!c_proposed_l1_r0, !d_proposed_l1_r1) with - | (true, false) -> return (op_hash, op, [Pass; Block; Block; Block]) - | _ -> return (op_hash, op, [Pass; Pass; Pass; Pass]) - - let stop_on_event = stop_on_event0 - end in - let module Node_b_hooks : Hooks = struct - include Default_hooks - - let on_inject_operation ~op_hash ~op = - match (!c_proposed_l1_r0, !d_proposed_l1_r1) with - | (true, false) -> return (op_hash, op, [Pass; Pass; Block; Block]) - | _ -> return (op_hash, op, [Pass; Pass; Pass; Pass]) - - let stop_on_event = stop_on_event0 - end in - let module Node_c_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - match (!c_proposed_l1_r0, !d_proposed_l1_r1, level, round) with - | (false, false, 1l, 0l) -> - check_block_signature ~block_hash ~block_header ~public_key:bootstrap3 - >>=? fun () -> - (c_proposed_l1_r0 := true ; - return_unit) - >>=? fun () -> - return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) - | _ -> - failwith - "unexpected injection on the node C, level = %ld / round = %ld" - level - round - - let on_inject_operation ~op_hash ~op = - match (!c_proposed_l1_r0, !d_proposed_l1_r1) with - | (true, false) -> return (op_hash, op, [Pass; Block; Pass; Block]) - | _ -> return (op_hash, op, [Pass; Pass; Pass; Pass]) - - let stop_on_event = stop_on_event0 - end in - let module Node_d_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - match (!d_proposed_l1_r1, level, round) with - | (false, 1l, 1l) -> - check_block_signature ~block_hash ~block_header ~public_key:bootstrap4 - >>=? fun () -> - (d_proposed_l1_r1 := true ; - return_unit) - >>=? fun () -> - return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) - | _ -> - failwith - "unexpected injection on the node D, level = %ld / round = %ld" - level - round - - let on_inject_operation ~op_hash ~op = - match (!c_proposed_l1_r0, !d_proposed_l1_r1) with - | (true, false) -> return (op_hash, op, [Pass; Block; Block; Pass]) - | _ -> return (op_hash, op, [Pass; Pass; Pass; Pass]) - - let stop_on_event = stop_on_event0 - end in - let config = - { - default_config with - delegate_selection = - Round_robin_over - [ - [bootstrap3; bootstrap4; bootstrap1; bootstrap2]; - [bootstrap1; bootstrap4; bootstrap2; bootstrap3]; - ]; - timeout = 15; - } - in - run - ~config - [ - (1, (module Node_a_hooks)); - (1, (module Node_b_hooks)); - (1, (module Node_c_hooks)); - (1, (module Node_d_hooks)); - ] - -(* - -Scenario F2 - -1. There are four nodes: A, B, C, and D. -2. A proposes at 1.0 and observes EQC. -3. A has the slot at 2.0 but somehow it doesn't propose or its proposal is lost. -4. B, C, and D have the rounds 1, 2, and 3 respectively, but they also do not propose. -5. A should still propose at 2.4. - -*) - -let test_scenario_f2 () = - let proposal_2_4_observed = ref false in - let module Hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - let propagation_vector = - match (level, round) with - | (1l, 0l) -> [Pass; Pass; Pass; Pass] - | (2l, 0l) -> [Pass; Block; Block; Block] - | (2l, 4l) -> - proposal_2_4_observed := true ; - [Pass; Pass; Pass; Pass] - | _ -> [Block; Block; Block; Block] - in - return (block_hash, block_header, operations, propagation_vector) - - let stop_on_event _ = !proposal_2_4_observed - end in - let config = - { - default_config with - delegate_selection = - Round_robin_over - [ - [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; - [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; - ]; - timeout = 25; - round0 = 2L; - round1 = 3L; - } - in - run - ~config - [ - (1, (module Hooks)); - (1, (module Hooks)); - (1, (module Hooks)); - (1, (module Hooks)); - ] - -(* - -Scenario M1 - -1. Four nodes start, each with 1 delegate. -2. As soon as 2nd level is proposed all communication between nodes becomes - impossible. -3. The situation continues for 5 seconds. -4. After communication is resumed the bakers must continue making progress. - -*) - -let test_scenario_m1 () = - let observed_level2_timestamp = ref None in - let network_down_sec = 5. in - let module Hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round:_ ~block_hash ~block_header ~operations - ~protocol_data:_ = - let propagation_vector = - match !observed_level2_timestamp with - | None -> - if Compare.Int32.(level >= 2l) then ( - observed_level2_timestamp := Some (Unix.time ()) ; - [Pass; Pass; Pass; Pass]) - else [Pass; Pass; Pass; Pass] - | Some level2_observed -> - if Unix.time () -. level2_observed < network_down_sec then - [Block; Block; Block; Block] - else [Pass; Pass; Pass; Pass] - in - return (block_hash, block_header, operations, propagation_vector) - - let on_inject_operation ~op_hash ~op = - let propagation_vector = - match !observed_level2_timestamp with - | None -> [Pass; Pass; Pass; Pass] - | Some level2_observed -> - if Unix.time () -. level2_observed < network_down_sec then - [Block; Block; Block; Block] - else [Pass; Pass; Pass; Pass] - in - return (op_hash, op, propagation_vector) - - let stop_on_event = function - | Baking_state.New_proposal {block; _} -> block.shell.level > 4l - | _ -> false - end in - let config = {default_config with timeout = 25} in - run - ~config - [ - (1, (module Hooks)); - (1, (module Hooks)); - (1, (module Hooks)); - (1, (module Hooks)); - ] - -(* - -Scenario M2 - -1. Five nodes start (single delegate per node). -2. They decide level 1. -3. However, the node that has the slot for level 2 round 0 is not there - to participate. -4. We check that the chain continues advancing despite that. - -*) - -let test_scenario_m2 () = - let module Normal_node : Hooks = struct - include Default_hooks - - let stop_on_event = function - | Baking_state.New_proposal {block; _} -> block.shell.level > 5l - | _ -> false - end in - let module Missing_node : Hooks = struct - include Default_hooks - - let stop_on_event _ = true (* stop immediately *) - end in - let config = - { - default_config with - delegate_selection = - Round_robin_over - [ - [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; - [bootstrap5; bootstrap1; bootstrap2; bootstrap3; bootstrap4]; - ]; - round0 = 2L; - round1 = 3L; - timeout = 20; - } - in - run - ~config - [ - (1, (module Normal_node)); - (1, (module Normal_node)); - (1, (module Normal_node)); - (1, (module Normal_node)); - (1, (module Missing_node)); - ] - -(* - -Scenario M3 - -1. There are four nodes: A, B, C, and D. -2. A and B propose in turns. Messages from A reach every node, but messages - from other nodes only go to A. -3. The chain should not make progress. Since we have both bootstrap1 and - bootstrap2 in delegate selection they have equal voting power. Therefore - it is necessary to have 2 votes for pre-quorums (which is achieved when A - is proposing) and 2 votes for quorums (impossible because B has no way to - obtain PQC and thus cannot send endorsements). - -*) - -let test_scenario_m3 () = - let stop_on_event0 = function - | Baking_state.New_proposal {block; _} -> - block.shell.level = 1l - && Protocol.Alpha_context.Round.to_int32 block.round = 6l - | _ -> false - in - - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let stop_on_event = stop_on_event0 - end in - let module Other_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations - ~protocol_data:_ = - return (block_hash, block_header, operations, [Pass; Block; Block; Block]) - - let on_inject_operation ~op_hash ~op = - return (op_hash, op, [Pass; Block; Block; Block]) - - let stop_on_event = stop_on_event0 - end in - let config = - { - default_config with - delegate_selection = Round_robin_over [[bootstrap1; bootstrap2]]; - round0 = 2L; - round1 = 3L; - timeout = 30; - } - in - run - ~config - [ - (1, (module Node_a_hooks)); - (1, (module Other_hooks)); - (1, (module Other_hooks)); - (1, (module Other_hooks)); - ] - -(* - -Scenario M4 - -1. There are four bakers: A, B, C, and D. -2. A proposes at level 1 round 0. Its proposal reaches A, B, C, and D, but - with a delay of 0.5 seconds. -3. 3 votes are enough for consensus, because voting powers of all delegates - are equal. Preendorsements propagate freely, however endorsements from C - are blocked. -4. Check that at level 1 round 0 quorum is reached (from the point of view - of A). This means that D sends an endorsement despite receiving - preendorsements before the proposal. - -*) - -let test_scenario_m4 () = - let a_observed_qc = ref false in - let stop_on_event0 _ = !a_observed_qc in - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - match (level, round) with - | (1l, 0l) -> - check_block_signature ~block_hash ~block_header ~public_key:bootstrap1 - >>=? fun () -> - return - (block_hash, block_header, operations, [Pass; Pass; Pass; Delay 0.5]) - | _ -> - failwith - "unexpected injection on the node A, level = %ld / round = %ld" - level - round - - let check_mempool_after_processing ~mempool = - let predicate op_hash op = - op_is_endorsement ~level:1l ~round:0l op_hash op - in - mempool_count_ops ~mempool ~predicate >>=? fun n -> - if n > 3 then - failwith "A received too many endorsements, expected to see only 3" - else if n = 3 then ( - a_observed_qc := true ; - return_unit) - else return_unit - - let stop_on_event = stop_on_event0 - end in - let module Node_b_hooks : Hooks = struct - include Default_hooks - - let stop_on_event = stop_on_event0 - end in - let module Node_c_hooks : Hooks = struct - include Default_hooks - - let on_inject_operation ~op_hash ~op = - op_is_endorsement ~level:1l ~round:0l op_hash op - >>=? fun is_endorsement -> - return - ( op_hash, - op, - if is_endorsement then [Block; Block; Block; Block] - else [Pass; Pass; Pass; Pass] ) - - let stop_on_event = stop_on_event0 - end in - let module Node_d_hooks : Hooks = struct - include Default_hooks - - let stop_on_event = stop_on_event0 - end in - let config = - { - default_config with - delegate_selection = - Round_robin_over [[bootstrap1; bootstrap2; bootstrap3; bootstrap4]]; - } - in - run - ~config - [ - (1, (module Node_a_hooks)); - (1, (module Node_b_hooks)); - (1, (module Node_c_hooks)); - (1, (module Node_d_hooks)); - ] - -(* - -Scenario M5 - -1. There are four bakers: A, B, C, and D. -2. A proposes at level 1 round 0. Its proposal reaches A, B, C, and D, but with - a delay of 1 second. There are no problems with propagation of - preendorsements and endorsements. -3. At the level 1 all four bakers have proposer slots, however we block possible - proposals from B and C at higher rounds. -4. Check that D proposes at the level 2 round 0, which means that it has - observed QC. - -*) - -let test_scenario_m5 () = - let stop_on_event0 = function - | Baking_state.New_proposal {block; _} -> block.shell.level >= 2l - | _ -> false - in - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - match (level, round) with - | (1l, 0l) -> - check_block_signature ~block_hash ~block_header ~public_key:bootstrap1 - >>=? fun () -> - return - (block_hash, block_header, operations, [Pass; Pass; Pass; Delay 1.0]) - | _ -> - failwith - "unexpected injection on the node A, level = %ld / round = %ld" - level - round - - let stop_on_event = stop_on_event0 - end in - let module Other_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations - ~protocol_data:_ = - return (block_hash, block_header, operations, [Block; Block; Block; Block]) - - let stop_on_event = stop_on_event0 - end in - let module Node_d_hooks : Hooks = struct - include Default_hooks - - let stop_on_event = stop_on_event0 - end in - let config = - { - default_config with - delegate_selection = - Round_robin_over - [[bootstrap1; bootstrap2; bootstrap3; bootstrap4]; [bootstrap4]]; - round0 = 3L; - round1 = 4L; - } - in - run - ~config - [ - (1, (module Node_a_hooks)); - (1, (module Other_hooks)); - (1, (module Other_hooks)); - (1, (module Node_d_hooks)); - ] - -(* - -Scenario M6 - -1. There are four bakers: A, B, C, and D. -2. A proposes at level 1 round 0. Its proposal reaches all nodes, and they - observe PQC. Only A observes a QC. -3. At level 1 round 1 it is B's turn to propose. Since it has observed the - PQC, it reproposes A's proposal. A does not see it. -4. B observes PQC and QC for its proposal. -5. A proposes at level 2 round 0. No one sees the proposal. -6. B proposes at level 2 round 1. A sees B's proposal and switches its branch. -7. We wait 2 more levels before checking A's chain to verify that it has - adopted B's proposal. - -*) - -let test_scenario_m6 () = - let b_proposal_2_1 = ref None in - let stop_on_event0 = function - | Baking_state.New_proposal {block; _} -> block.shell.level > 4l - | _ -> false - in - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - let propagation_vector = - match (level, round) with - | (2l, 0l) -> [Pass; Block; Block; Block] - | _ -> [Pass; Pass; Pass; Pass] - in - return (block_hash, block_header, operations, propagation_vector) - - let on_inject_operation ~op_hash ~op = - op_is_endorsement ~level:1l ~round:0l op_hash op - >>=? fun is_a10_endorsement -> - return - ( op_hash, - op, - if is_a10_endorsement then [Pass; Block; Block; Block] - else [Pass; Pass; Pass; Pass] ) - - let stop_on_event = stop_on_event0 - - let check_chain_on_success ~chain = - match List.nth (List.rev chain) 2 with - | None -> failwith "Node A has empty chain" - | Some (block : block) -> - verify_payload_hash - ~protocol_data:block.protocol_data - ~original_proposal:b_proposal_2_1 - ~message:"A did not switch to B's proposal (level 2, round 1)" - end in - let module Node_b_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data = - (match (level, round) with - | (1l, 1l) -> return [Block; Delay 0.1; Delay 0.1; Delay 0.1] - | (2l, 1l) -> - save_proposal_payload ~protocol_data ~var:b_proposal_2_1 - >>=? fun () -> return [Pass; Pass; Pass; Pass] - | _ -> return [Pass; Pass; Pass; Pass]) - >>=? fun propagation_vector -> - return (block_hash, block_header, operations, propagation_vector) - - let on_inject_operation ~op_hash ~op = - op_is_endorsement ~level:1l ~round:0l op_hash op - >>=? fun is_a10_endorsement -> - return - ( op_hash, - op, - if is_a10_endorsement then [Pass; Block; Block; Block] - else [Pass; Pass; Pass; Pass] ) - - let stop_on_event = stop_on_event0 - end in - let module Other_node : Hooks = struct - include Default_hooks - - let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations - ~protocol_data:_ = - return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) - - let on_inject_operation ~op_hash ~op = - op_is_endorsement ~level:1l ~round:0l op_hash op - >>=? fun is_a10_endorsement -> - return - ( op_hash, - op, - if is_a10_endorsement then [Pass; Block; Block; Block] - else [Pass; Pass; Pass; Pass] ) - - let stop_on_event = stop_on_event0 - end in - let config = - { - default_config with - delegate_selection = - Round_robin_over - [ - [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; - [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; - ]; - timeout = 20; - } - in - run - ~config - [ - (1, (module Node_a_hooks)); - (1, (module Node_b_hooks)); - (1, (module Other_node)); - (1, (module Other_node)); - ] - -(* - -Scenario M7 - -The same as M6, but: - -5. B proposes at level 2 round 0 (A does not see the proposal). -6. A proposes at 2.1. B switches to A's branch when it receives 2.1. -7. We wait 2 more levels before checking everyone's chain to verify that - A's proposal has been selected. - -*) - -let test_scenario_m7 () = - let a_proposal_2_1 = ref None in - let c_received_2_1 = ref false in - let d_received_2_1 = ref false in - let stop_on_event0 = function - | Baking_state.New_proposal {block; _} -> block.shell.level > 4l - | _ -> false - in - let check_chain_on_success0 node_label ~chain = - match List.nth (List.rev chain) 2 with - | None -> failwith "Node %s has empty chain" node_label - | Some (block : block) -> - verify_payload_hash - ~protocol_data:block.protocol_data - ~original_proposal:a_proposal_2_1 - ~message: - (Format.sprintf - "%s did not switch to A's proposal (level 2, round 1)" - node_label) - in - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data = - (match (level, round) with - | (2l, 1l) -> save_proposal_payload ~protocol_data ~var:a_proposal_2_1 - | _ -> return_unit) - >>=? fun () -> - return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) - - let on_inject_operation ~op_hash ~op = - op_is_endorsement ~level:1l ~round:0l op_hash op - >>=? fun is_a10_endorsement -> - return - ( op_hash, - op, - if is_a10_endorsement then [Pass; Block; Block; Block] - else [Pass; Pass; Pass; Pass] ) - - let stop_on_event = stop_on_event0 - - let check_chain_on_success = check_chain_on_success0 "A" - end in - let module Node_b_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - (match (level, round) with - | (1l, 1l) -> return [Block; Delay 0.1; Delay 0.1; Delay 0.1] - | (2l, 0l) -> return [Block; Pass; Pass; Pass] - | _ -> return [Pass; Pass; Pass; Pass]) - >>=? fun propagation_vector -> - return (block_hash, block_header, operations, propagation_vector) - - let on_inject_operation ~op_hash ~op = - op_is_endorsement ~level:1l ~round:0l op_hash op - >>=? fun is_a10_endorsement -> - op_is_preendorsement ~level:2l op_hash op - >>=? fun level2_preendorsement -> - op_is_endorsement ~level:2l op_hash op >>=? fun level2_endorsement -> - let propagation_vector = - match - (is_a10_endorsement, level2_preendorsement, level2_endorsement) - with - | (true, _, _) -> [Pass; Block; Block; Block] - | (_, true, _) | (_, _, true) -> [Block; Block; Block; Block] - | (_, _, _) -> [Pass; Pass; Pass; Pass] - in - return (op_hash, op, propagation_vector) - - let stop_on_event = stop_on_event0 - - let check_chain_on_success = check_chain_on_success0 "B" - end in - let module Node_c_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations - ~protocol_data:_ = - let propagation_vector = - if !c_received_2_1 then [Pass; Pass; Pass; Pass] - else [Block; Block; Block; Block] - in - return (block_hash, block_header, operations, propagation_vector) - - let check_chain_after_processing ~level ~round ~chain:_ = - match (level, round) with - | (2l, 1l) -> - c_received_2_1 := true ; - return_unit - | _ -> return_unit - - let on_inject_operation ~op_hash ~op = - op_is_endorsement ~level:1l ~round:0l op_hash op - >>=? fun is_a10_endorsement -> - op_is_preendorsement ~level:2l op_hash op - >>=? fun level2_preendorsement -> - op_is_endorsement ~level:2l op_hash op >>=? fun level2_endorsement -> - let propagation_vector = - match - ( is_a10_endorsement, - !c_received_2_1, - level2_preendorsement, - level2_endorsement ) - with - | (true, _, _, _) -> [Pass; Block; Block; Block] - | (_, false, true, _) | (_, false, _, true) -> - [Block; Block; Block; Block] - | (_, _, _, _) -> [Pass; Pass; Pass; Pass] - in - return (op_hash, op, propagation_vector) - - let stop_on_event = stop_on_event0 - - let check_chain_on_success = check_chain_on_success0 "C" - end in - let module Node_d_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations - ~protocol_data:_ = - let propagation_vector = - if !d_received_2_1 then [Pass; Pass; Pass; Pass] - else [Block; Block; Block; Block] - in - return (block_hash, block_header, operations, propagation_vector) - - let check_chain_after_processing ~level ~round ~chain:_ = - match (level, round) with - | (2l, 1l) -> - d_received_2_1 := true ; - return_unit - | _ -> return_unit - - let on_inject_operation ~op_hash ~op = - op_is_endorsement ~level:1l ~round:0l op_hash op - >>=? fun is_a10_endorsement -> - op_is_preendorsement ~level:2l op_hash op - >>=? fun level2_preendorsement -> - op_is_endorsement ~level:2l op_hash op >>=? fun level2_endorsement -> - let propagation_vector = - match - ( is_a10_endorsement, - !d_received_2_1, - level2_preendorsement, - level2_endorsement ) - with - | (true, _, _, _) -> [Pass; Block; Block; Block] - | (_, false, true, _) | (_, false, _, true) -> - [Block; Block; Block; Block] - | (_, _, _, _) -> [Pass; Pass; Pass; Pass] - in - return (op_hash, op, propagation_vector) - - let stop_on_event = stop_on_event0 - - let check_chain_on_success = check_chain_on_success0 "D" - end in - let config = - { - default_config with - delegate_selection = - Round_robin_over - [ - [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; - [bootstrap2; bootstrap1; bootstrap3; bootstrap4]; - ]; - timeout = 20; - } - in - run - ~config - [ - (1, (module Node_a_hooks)); - (1, (module Node_b_hooks)); - (1, (module Node_c_hooks)); - (1, (module Node_d_hooks)); - ] - -(* - -Scenario M8 - -5. B proposes at 2.0 and observes PQC but not QC. -6. C re-proposes at 2.1 and similarly observes PQC but not QC. -7. A proposes at 2.2. B, C, and D do not switch to A's branch; moreover A - switches to their branch when it receives the next proposal (2.3). This - happens because B, C, and D have PQC despite A having a higher round (2 > 1). -8. We wait 2 more levels before checking everyone's chain to verify that - B's proposal has been selected. - -*) - -let test_scenario_m8 () = - let b_proposal_2_0 = ref None in - let stop_on_event0 = function - | Baking_state.New_proposal {block; _} -> block.shell.level > 4l - | _ -> false - in - let on_inject_operation0 ~op_hash ~op = - op_is_endorsement ~level:1l ~round:0l op_hash op - >>=? fun is_a10_endorsement -> - op_is_endorsement ~level:2l ~round:0l op_hash op - >>=? fun is_b20_endorsement -> - op_is_endorsement ~level:2l ~round:1l op_hash op - >>=? fun is_c21_endorsement -> - let propagation_vector = - if is_a10_endorsement then [Pass; Block; Block; Block] - else if is_b20_endorsement || is_c21_endorsement then - [Block; Block; Block; Block] - else [Pass; Pass; Pass; Pass] - in - return (op_hash, op, propagation_vector) - in - let check_chain_on_success0 node_label ~chain = - match List.nth (List.rev chain) 2 with - | None -> failwith "Node %s has empty chain" node_label - | Some (block : block) -> - verify_payload_hash - ~protocol_data:block.protocol_data - ~original_proposal:b_proposal_2_0 - ~message: - (Format.sprintf - "%s did not switch to B's proposal (level 2, round 0)" - node_label) - in - let module Node_a_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations - ~protocol_data:_ = - return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) - - let on_inject_operation = on_inject_operation0 - - let stop_on_event = stop_on_event0 - - let check_chain_on_success = check_chain_on_success0 "A" - end in - let module Node_b_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data = - (match (level, round) with - | (1l, 1l) -> return [Block; Delay 0.1; Delay 0.1; Delay 0.1] - | (2l, 0l) -> - save_proposal_payload ~protocol_data ~var:b_proposal_2_0 - >>=? fun () -> return [Block; Pass; Pass; Pass] - | _ -> return [Pass; Pass; Pass; Pass]) - >>=? fun propagation_vector -> - return (block_hash, block_header, operations, propagation_vector) - - let on_inject_operation = on_inject_operation0 - - let stop_on_event = stop_on_event0 - - let check_chain_on_success = check_chain_on_success0 "B" - end in - let module Node_c_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level ~round ~block_hash ~block_header ~operations - ~protocol_data:_ = - let propagation_vector = - match (level, round) with - | (2l, 1l) -> [Block; Pass; Pass; Pass] - | _ -> [Pass; Pass; Pass; Pass] - in - return (block_hash, block_header, operations, propagation_vector) - - let on_inject_operation = on_inject_operation0 - - let stop_on_event = stop_on_event0 - - let check_chain_on_success = check_chain_on_success0 "C" - end in - let module Node_d_hooks : Hooks = struct - include Default_hooks - - let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations - ~protocol_data:_ = - return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) - - let on_inject_operation = on_inject_operation0 - - let stop_on_event = stop_on_event0 - - let check_chain_on_success = check_chain_on_success0 "D" - end in - let config = - { - default_config with - delegate_selection = - Round_robin_over - [ - [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; - [bootstrap2; bootstrap3; bootstrap1; bootstrap4]; - ]; - timeout = 30; - } - in - run - ~config - [ - (1, (module Node_a_hooks)); - (1, (module Node_b_hooks)); - (1, (module Node_c_hooks)); - (1, (module Node_d_hooks)); - ] - -let tests = - let open Tezos_base_test_helpers.Tztest in - [ - tztest "reaches level 5" `Quick test_level_5; - tztest "scenario t1" `Quick test_scenario_t1; - tztest "scenario t2" `Quick test_scenario_t2; - tztest "scenario t3" `Quick test_scenario_t3; - (* See issue https://gitlab.com/nomadic-labs/tezos/-/issues/518 *) - (* tztest "scenario f1" `Quick test_scenario_f1; *) - tztest "scenario f2" `Quick test_scenario_f2; - tztest "scenario m1" `Quick test_scenario_m1; - tztest "scenario m2" `Quick test_scenario_m2; - tztest "scenario m3" `Quick test_scenario_m3; - tztest "scenario m4" `Quick test_scenario_m4; - tztest "scenario m5" `Quick test_scenario_m5; - tztest "scenario m6" `Quick test_scenario_m6; - tztest "scenario m7" `Quick test_scenario_m7; - tztest "scenario m8" `Quick test_scenario_m8; - ] diff --git a/src/proto_012_Psithaca/lib_delegate/tezos-accuser-012-Psithaca-commands.opam b/src/proto_012_Psithaca/lib_delegate/tezos-accuser-012-Psithaca-commands.opam deleted file mode 100644 index 13b45e6cace9..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/tezos-accuser-012-Psithaca-commands.opam +++ /dev/null @@ -1,23 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-shell-services" - "tezos-client-base" - "tezos-client-commands" - "tezos-client-012-Psithaca" - "tezos-baking-012-Psithaca" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol-specific commands for `tezos-accuser`" diff --git a/src/proto_012_Psithaca/lib_delegate/tezos-baking-012-Psithaca-commands.opam b/src/proto_012_Psithaca/lib_delegate/tezos-baking-012-Psithaca-commands.opam deleted file mode 100644 index 60d43fb96f69..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/tezos-baking-012-Psithaca-commands.opam +++ /dev/null @@ -1,24 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-shell-services" - "tezos-shell-context" - "tezos-client-base" - "tezos-client-commands" - "tezos-client-012-Psithaca" - "tezos-baking-012-Psithaca" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol-specific commands for baking" diff --git a/src/proto_012_Psithaca/lib_delegate/tezos-baking-012-Psithaca.opam b/src/proto_012_Psithaca/lib_delegate/tezos-baking-012-Psithaca.opam deleted file mode 100644 index bdf3049797cc..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/tezos-baking-012-Psithaca.opam +++ /dev/null @@ -1,33 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "tezos-tooling" { with-test } - "tezos-012-Psithaca-test-helpers" { with-test } - "dune" { >= "2.9" } - "tezos-base" - "tezos-version" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-shell-context" - "tezos-shell-services" - "tezos-context" - "tezos-client-base" - "tezos-client-commands" - "tezos-client-012-Psithaca" - "tezos-rpc-http-client-unix" - "lwt-canceler" { >= "0.3" & < "0.4" } - "lwt-exit" - "tezos-base-test-helpers" {with-test} - "tezos-protocol-012-Psithaca-parameters" {with-test} - "alcotest-lwt" {with-test} -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: base library for `tezos-baker/accuser`" diff --git a/src/proto_012_Psithaca/lib_delegate/tezos-endorser-012-Psithaca-commands.opam b/src/proto_012_Psithaca/lib_delegate/tezos-endorser-012-Psithaca-commands.opam deleted file mode 100644 index 4e84befc4d39..000000000000 --- a/src/proto_012_Psithaca/lib_delegate/tezos-endorser-012-Psithaca-commands.opam +++ /dev/null @@ -1,23 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-shell-services" - "tezos-client-base" - "tezos-client-commands" - "tezos-client-012-Psithaca" - "tezos-baking-012-Psithaca" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol-specific commands for `tezos-endorser`" diff --git a/src/proto_012_Psithaca/lib_parameters/.ocamlformat b/src/proto_012_Psithaca/lib_parameters/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_parameters/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_parameters/default_parameters.ml b/src/proto_012_Psithaca/lib_parameters/default_parameters.ml deleted file mode 100644 index c2f8a1c05d00..000000000000 --- a/src/proto_012_Psithaca/lib_parameters/default_parameters.ml +++ /dev/null @@ -1,224 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol.Alpha_context - -let constants_mainnet = - let consensus_committee_size = 7000 in - let block_time = 30 in - let Constants.Generated. - { - consensus_threshold; - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - } = - Constants.Generated.generate - ~consensus_committee_size - ~blocks_per_minute:{numerator = 60; denominator = block_time} - in - { - Constants.preserved_cycles = 5; - blocks_per_cycle = 8192l; - blocks_per_commitment = 64l; - blocks_per_stake_snapshot = 512l; - blocks_per_voting_period = 40960l (* 5 cycles *); - hard_gas_limit_per_operation = Gas.Arith.(integral_of_int_exn 1_040_000); - hard_gas_limit_per_block = Gas.Arith.(integral_of_int_exn 5_200_000); - proof_of_work_threshold = Int64.(sub (shift_left 1L 46) 1L); - tokens_per_roll = Tez.(mul_exn one 6_000); - seed_nonce_revelation_tip = - (match Tez.(one /? 8L) with Ok c -> c | Error _ -> assert false); - origination_size = 257; - baking_reward_fixed_portion (* 10_000_000 mutez *); - baking_reward_bonus_per_slot (* 4_286 mutez *); - endorsing_reward_per_slot (* 2_857 mutez *); - hard_storage_limit_per_operation = Z.of_int 60_000; - cost_per_byte = Tez.of_mutez_exn 250L; - quorum_min = 20_00l; - quorum_max = 70_00l; - min_proposal_quorum = 5_00l; - (* liquidity_baking_subsidy is 1/16th of maximum total rewards for a block *) - liquidity_baking_subsidy = Tez.of_mutez_exn 2_500_000L; - (* level after protocol activation when liquidity baking shuts off: - about 6 months after first activation on mainnet *) - liquidity_baking_sunset_level = 3_063_809l; - (* 1/3 window size of 2000 blocks with precision of 1000 for integer computation *) - liquidity_baking_escape_ema_threshold = 666_667l; - (* The rationale behind the value of this constant is that an - operation should be considered alive for about one hour: - - minimal_block_delay context * max_operations_ttl = 3600 - - The unit for this value is a block. - *) - max_operations_time_to_live = 120; - minimal_block_delay = Period.of_seconds_exn (Int64.of_int block_time); - delay_increment_per_round = Period.of_seconds_exn 15L; - consensus_committee_size; - consensus_threshold; - (* 4667 slots *) - minimal_participation_ratio = {numerator = 2; denominator = 3}; - max_slashing_period = 2; - frozen_deposits_percentage = 10; - double_baking_punishment = Tez.(mul_exn one 640); - ratio_of_frozen_deposits_slashed_per_double_endorsement = - {numerator = 1; denominator = 2}; - delegate_selection = Constants.Random; - } - -let constants_sandbox = - let consensus_committee_size = 256 in - let block_time = 1 in - let Constants.Generated. - { - consensus_threshold = _; - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - } = - Constants.Generated.generate - ~consensus_committee_size - ~blocks_per_minute:{numerator = 60; denominator = block_time} - in - { - constants_mainnet with - Constants.preserved_cycles = 2; - blocks_per_cycle = 8l; - blocks_per_commitment = 4l; - blocks_per_stake_snapshot = 4l; - blocks_per_voting_period = 64l; - proof_of_work_threshold = Int64.of_int (-1); - liquidity_baking_sunset_level = 128l; - minimal_block_delay = Period.of_seconds_exn (Int64.of_int block_time); - delay_increment_per_round = Period.one_second; - consensus_committee_size = 256; - consensus_threshold = 0; - baking_reward_fixed_portion (* 333_333 mutez *); - baking_reward_bonus_per_slot (* 3_921 mutez *); - endorsing_reward_per_slot (* 2_604 mutez *); - max_slashing_period = 2; - frozen_deposits_percentage = 5; - } - -let constants_test = - let consensus_committee_size = 25 in - let Constants.Generated. - { - consensus_threshold; - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - } = - Constants.Generated.generate - ~consensus_committee_size - ~blocks_per_minute:{numerator = 2; denominator = 1} - in - { - constants_mainnet with - Constants.preserved_cycles = 3; - blocks_per_cycle = 12l; - blocks_per_commitment = 4l; - blocks_per_stake_snapshot = 4l; - blocks_per_voting_period = 24l; - proof_of_work_threshold = Int64.of_int (-1); - liquidity_baking_sunset_level = 4096l; - consensus_committee_size; - consensus_threshold (* 17 slots *); - max_slashing_period = 2; - baking_reward_fixed_portion (* 10 tez *); - baking_reward_bonus_per_slot (* 1.25 tez *); - endorsing_reward_per_slot (* 0.8 tez *); - frozen_deposits_percentage = - 5 - (* not 10 so that multiplication and - divisions do not easily get - intermingled *); - } - -let test_commitments = - lazy - (List.map - (fun (bpkh, amount) -> - let blinded_public_key_hash = - Protocol.Blinded_public_key_hash.of_b58check_exn bpkh - in - let amount = Protocol.Alpha_context.Tez.of_mutez_exn amount in - {Protocol.Alpha_context.Commitment.blinded_public_key_hash; amount}) - [ - ("btz1bRL4X5BWo2Fj4EsBdUwexXqgTf75uf1qa", 23932454669343L); - ("btz1SxjV1syBgftgKy721czKi3arVkVwYUFSv", 72954577464032L); - ("btz1LtoNCjiW23txBTenALaf5H6NKF1L3c1gw", 217487035428348L); - ("btz1SUd3mMhEBcWudrn8u361MVAec4WYCcFoy", 4092742372031L); - ("btz1MvBXf4orko1tsGmzkjLbpYSgnwUjEe81r", 17590039016550L); - ("btz1LoDZ3zsjgG3k3cqTpUMc9bsXbchu9qMXT", 26322312350555L); - ("btz1RMfq456hFV5AeDiZcQuZhoMv2dMpb9hpP", 244951387881443L); - ("btz1Y9roTh4A7PsMBkp8AgdVFrqUDNaBE59y1", 80065050465525L); - ("btz1Q1N2ePwhVw5ED3aaRVek6EBzYs1GDkSVD", 3569618927693L); - ("btz1VFFVsVMYHd5WfaDTAt92BeQYGK8Ri4eLy", 9034781424478L); - ]) - -let bootstrap_accounts_strings = - [ - "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"; - "edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9"; - "edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV"; - "edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU"; - "edpkv8EUUH68jmo3f7Um5PezmfGrRF24gnfLpH3sVNwJnV5bVCxL2n"; - ] - -let bootstrap_balance = Tez.of_mutez_exn 4_000_000_000_000L - -let compute_accounts = - List.map (fun s -> - let public_key = Signature.Public_key.of_b58check_exn s in - let public_key_hash = Signature.Public_key.hash public_key in - Parameters. - { - public_key_hash; - public_key = Some public_key; - amount = bootstrap_balance; - }) - -let bootstrap_accounts = compute_accounts bootstrap_accounts_strings - -let make_bootstrap_account (pkh, pk, amount) = - Parameters.{public_key_hash = pkh; public_key = Some pk; amount} - -let parameters_of_constants ?(bootstrap_accounts = bootstrap_accounts) - ?(bootstrap_contracts = []) ?(commitments = []) constants = - Parameters. - { - bootstrap_accounts; - bootstrap_contracts; - commitments; - constants; - security_deposit_ramp_up_cycles = None; - no_reward_cycles = None; - } - -let json_of_parameters parameters = - Data_encoding.Json.construct Parameters.encoding parameters diff --git a/src/proto_012_Psithaca/lib_parameters/default_parameters.mli b/src/proto_012_Psithaca/lib_parameters/default_parameters.mli deleted file mode 100644 index 3551ac5d3117..000000000000 --- a/src/proto_012_Psithaca/lib_parameters/default_parameters.mli +++ /dev/null @@ -1,48 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol.Alpha_context - -val constants_mainnet : Constants.parametric - -val constants_sandbox : Constants.parametric - -val constants_test : Constants.parametric - -val test_commitments : Commitment.t list lazy_t - -val make_bootstrap_account : - Signature.public_key_hash * Signature.public_key * Tez.t -> - Parameters.bootstrap_account - -val parameters_of_constants : - ?bootstrap_accounts:Parameters.bootstrap_account list -> - ?bootstrap_contracts:Parameters.bootstrap_contract list -> - ?commitments:Commitment.t list -> - Constants.parametric -> - Parameters.t - -val json_of_parameters : Parameters.t -> Data_encoding.json diff --git a/src/proto_012_Psithaca/lib_parameters/dune b/src/proto_012_Psithaca/lib_parameters/dune deleted file mode 100644 index a9daaead55a0..000000000000 --- a/src/proto_012_Psithaca/lib_parameters/dune +++ /dev/null @@ -1,47 +0,0 @@ -(library - (name tezos_protocol_012_Psithaca_parameters) - (instrumentation (backend bisect_ppx)) - (public_name tezos-protocol-012-Psithaca-parameters) - (modules :standard \ gen) - (libraries tezos-base - tezos-base.unix - tezos-protocol-environment - tezos-protocol-012-Psithaca) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -linkall)) -) - -(executable - (name gen) - (libraries tezos-base - tezos-protocol-012-Psithaca-parameters) - (modules gen) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca_parameters - -open Tezos_protocol_012_Psithaca - -linkall))) - -(rule - (targets sandbox-parameters.json) - (deps gen.exe) - (action (run %{deps} --sandbox))) - -(rule - (targets test-parameters.json) - (deps gen.exe) - (action (run %{deps} --test))) - -(rule - (targets mainnet-parameters.json) - (deps gen.exe) - (action (run %{deps} --mainnet))) - -(install - (section lib) - (files sandbox-parameters.json test-parameters.json mainnet-parameters.json)) - -(rule - (alias runtest_lint) - (deps (glob_files *.ml{,i})) - (action (run %{lib:tezos-tooling:lint.sh} %{deps}))) diff --git a/src/proto_012_Psithaca/lib_parameters/dune-project b/src/proto_012_Psithaca/lib_parameters/dune-project deleted file mode 100644 index c6a0caba245e..000000000000 --- a/src/proto_012_Psithaca/lib_parameters/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-protocol-alpha-parameters) diff --git a/src/proto_012_Psithaca/lib_parameters/gen.ml b/src/proto_012_Psithaca/lib_parameters/gen.ml deleted file mode 100644 index 8fcc504044e5..000000000000 --- a/src/proto_012_Psithaca/lib_parameters/gen.ml +++ /dev/null @@ -1,62 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Prints the json encoding of the parametric constants of protocol alpha. - $ dune utop src/proto_alpha/lib_protocol/test/helpers/ constants.ml -*) - -let () = - let print_usage_and_fail s = - Printf.eprintf "Usage: %s [ --sandbox | --test | --mainnet ]" Sys.argv.(0) ; - raise (Invalid_argument s) - in - let dump parameters file = - let str = - Data_encoding.Json.to_string - (Default_parameters.json_of_parameters parameters) - in - let fd = open_out file in - output_string fd str ; - close_out fd - in - if Array.length Sys.argv < 2 then print_usage_and_fail "" - else - match Sys.argv.(1) with - | "--sandbox" -> - dump - Default_parameters.(parameters_of_constants constants_sandbox) - "sandbox-parameters.json" - | "--test" -> - dump - Default_parameters.( - parameters_of_constants - ~commitments:(Lazy.force test_commitments) - constants_sandbox) - "test-parameters.json" - | "--mainnet" -> - dump - Default_parameters.(parameters_of_constants constants_mainnet) - "mainnet-parameters.json" - | s -> print_usage_and_fail s diff --git a/src/proto_012_Psithaca/lib_parameters/tezos-protocol-012-Psithaca-parameters.opam b/src/proto_012_Psithaca/lib_parameters/tezos-protocol-012-Psithaca-parameters.opam deleted file mode 100644 index b5b347cbf120..000000000000 --- a/src/proto_012_Psithaca/lib_parameters/tezos-protocol-012-Psithaca-parameters.opam +++ /dev/null @@ -1,18 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: parameters" diff --git a/src/proto_012_Psithaca/lib_plugin/.ocamlformat b/src/proto_012_Psithaca/lib_plugin/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_plugin/dune b/src/proto_012_Psithaca/lib_plugin/dune deleted file mode 100644 index b54e9d401917..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/dune +++ /dev/null @@ -1,27 +0,0 @@ -(library - (name tezos_protocol_plugin_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-protocol-plugin-012-Psithaca) - (libraries tezos-base - tezos-protocol-012-Psithaca - tezos-stdlib-unix - ) - (modules (:standard) \ Plugin_registerer) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_protocol_012_Psithaca - -open Tezos_stdlib_unix - ))) - -(library - (name tezos_protocol_plugin_012_Psithaca_registerer) - (instrumentation (backend bisect_ppx)) - (public_name tezos-protocol-plugin-012-Psithaca-registerer) - (libraries tezos-base - tezos-embedded-protocol-012-Psithaca - tezos-protocol-plugin-012-Psithaca - tezos-shell) - (modules Plugin_registerer) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_embedded_protocol_012_Psithaca - -open Tezos_protocol_plugin_012_Psithaca - -open Tezos_shell))) diff --git a/src/proto_012_Psithaca/lib_plugin/dune-project b/src/proto_012_Psithaca/lib_plugin/dune-project deleted file mode 100644 index 9a66059d4b1d..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-filters-alpha) diff --git a/src/proto_012_Psithaca/lib_plugin/plugin.ml b/src/proto_012_Psithaca/lib_plugin/plugin.ml deleted file mode 100644 index 794a88b6a704..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/plugin.ml +++ /dev/null @@ -1,3277 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Nomadic Development. *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -(** The assumed number of blocks between operation-creation time and - the actual time when the operation is included in a block. *) -let default_operation_inclusion_latency = 3 - -type Environment.Error_monad.error += Cannot_parse_operation (* `Branch *) - -type Environment.Error_monad.error += Cannot_serialize_log - -type Environment.Error_monad.error += Cannot_retrieve_predecessor_level - -let () = - Environment.Error_monad.register_error_kind - `Branch - ~id:"operation.cannot_parse" - ~title:"Cannot parse operation" - ~description:"The operation is ill-formed or for another protocol version" - ~pp:(fun ppf () -> Format.fprintf ppf "The operation cannot be parsed") - Data_encoding.unit - (function Cannot_parse_operation -> Some () | _ -> None) - (fun () -> Cannot_parse_operation) ; - (* Cannot serialize log *) - Environment.Error_monad.register_error_kind - `Temporary - ~id:"michelson_v1.cannot_serialize_log" - ~title:"Not enough gas to serialize execution trace" - ~description: - "Execution trace with stacks was to big to be serialized with the \ - provided gas" - Data_encoding.empty - (function Cannot_serialize_log -> Some () | _ -> None) - (fun () -> Cannot_serialize_log) ; - Environment.Error_monad.register_error_kind - `Temporary - ~id:"cannot_retrieve_predecessor_level" - ~title:"Cannot retrieve predecessor level" - ~description:"Cannot retrieve predecessor level." - Data_encoding.empty - (function Cannot_retrieve_predecessor_level -> Some () | _ -> None) - (fun () -> Cannot_retrieve_predecessor_level) - -module Mempool = struct - type nanotez = Q.t - - let nanotez_enc : nanotez Data_encoding.t = - let open Data_encoding in - def - "nanotez" - ~title:"A thousandth of a mutez" - ~description:"One thousand nanotez make a mutez (1 tez = 1e9 nanotez)" - (conv - (fun q -> (q.Q.num, q.Q.den)) - (fun (num, den) -> {Q.num; den}) - (tup2 z z)) - - let manager_op_replacement_factor_enc : Q.t Data_encoding.t = - let open Data_encoding in - def - "manager operation replacement factor" - ~title:"A manager operation's replacement factor" - ~description: - "The fee and fee/gas ratio of an operation to replace another" - (conv - (fun q -> (q.Q.num, q.Q.den)) - (fun (num, den) -> {Q.num; den}) - (tup2 z z)) - - type config = { - minimal_fees : Tez.t; - minimal_nanotez_per_gas_unit : nanotez; - minimal_nanotez_per_byte : nanotez; - allow_script_failure : bool; - (** If [true], this makes [post_filter_manager] unconditionally return - [`Passed_postfilter filter_state], no matter the operation's - success. *) - clock_drift : Period.t option; - replace_by_fee_factor : Q.t; - (** This field determines the amount of additional fees (given as a - factor of the declared fees) a manager should add to an operation - in order to (eventually) replace an existing (prechecked) one - in the mempool. Note that other criteria, such as the gas ratio, - are also taken into account to decide whether to accept the - replacement or not. *) - } - - let default_minimal_fees = - match Tez.of_mutez 100L with None -> assert false | Some t -> t - - let default_minimal_nanotez_per_gas_unit = Q.of_int 100 - - let default_minimal_nanotez_per_byte = Q.of_int 1000 - - (* If the drift is not specified, it will be the duration of round zero. - It allows only to spam with one future round. - - /!\ Warning /!\ : current plugin implementation implies that this drift - cumulates with the accepted drift regarding the current head's timestamp. - *) - - let config_encoding : config Data_encoding.t = - let open Data_encoding in - (* 105/100 = 1.05%: This is the minumum fee increase ratio required between - an operation and another one it'd replace in the prevalidator. *) - let replace_factor = Q.make (Z.of_int 105) (Z.of_int 100) in - conv - (fun { - minimal_fees; - minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte; - allow_script_failure; - clock_drift; - replace_by_fee_factor; - } -> - ( minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - allow_script_failure, - clock_drift, - replace_by_fee_factor )) - (fun ( minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - allow_script_failure, - clock_drift, - replace_by_fee_factor ) -> - { - minimal_fees; - minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte; - allow_script_failure; - clock_drift; - replace_by_fee_factor; - }) - (obj6 - (dft "minimal_fees" Tez.encoding default_minimal_fees) - (dft - "minimal_nanotez_per_gas_unit" - nanotez_enc - default_minimal_nanotez_per_gas_unit) - (dft - "minimal_nanotez_per_byte" - nanotez_enc - default_minimal_nanotez_per_byte) - (dft "allow_script_failure" bool true) - (opt "clock_drift" Period.encoding) - (dft - "replace_by_fee_factor" - manager_op_replacement_factor_enc - replace_factor)) - - let default_config = - { - minimal_fees = default_minimal_fees; - minimal_nanotez_per_gas_unit = default_minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte = default_minimal_nanotez_per_byte; - allow_script_failure = true; - clock_drift = None; - replace_by_fee_factor = - Q.make (Z.of_int 105) (Z.of_int 100) - (* Default value of [replace_by_fee_factor] is set to 5% *); - } - - type manager_gas_witness - - (* For each Prechecked manager operation (batched or not), we associate the - following information to its source: - - the operation's hash, needed in case the operation is replaced - afterwards, - - the total fee and gas_limit, needed to compare operations of the same - manager to decide which one has more fees w.r.t. announced gas limit - (modulo replace_by_fee_factor) - *) - type manager_op_info = { - operation_hash : Operation_hash.t; - gas_limit : manager_gas_witness Gas.Arith.t; - fee : Tez.t; - } - - type state = { - grandparent_level_start : Alpha_context.Timestamp.t option; - round_zero_duration : Period.t option; - op_prechecked_managers : manager_op_info Signature.Public_key_hash.Map.t; - (** All managers that are the source of manager operations - prechecked in the mempool. Each manager in the map is associated to - a record of type [manager_op_info] (See for record details above). - Each manager in the map should be accessible - with an operation hash in [operation_hash_to_manager]. *) - operation_hash_to_manager : Signature.Public_key_hash.t Operation_hash.Map.t; - (** Map of operation hash to manager used to remove a manager from - [op_prechecked_managers] with an operation hash. Each manager in the - map should also be in [op_prechecked_managers]. *) - } - - let empty : state = - { - grandparent_level_start = None; - round_zero_duration = None; - op_prechecked_managers = Signature.Public_key_hash.Map.empty; - operation_hash_to_manager = Operation_hash.Map.empty; - } - - let init config ?(validation_state : validation_state option) ~predecessor () - = - ignore config ; - (match validation_state with - | None -> return empty - | Some {ctxt; _} -> - let { - Tezos_base.Block_header.fitness = predecessor_fitness; - timestamp = predecessor_timestamp; - _; - } = - predecessor.Tezos_base.Block_header.shell - in - Alpha_context.Fitness.predecessor_round_from_raw predecessor_fitness - >>?= fun grandparent_round -> - Alpha_context.Fitness.round_from_raw predecessor_fitness - >>?= fun predecessor_round -> - Alpha_context.( - let round_durations = Constants.round_durations ctxt in - let round_zero_duration = - Round.round_duration round_durations Round.zero - in - Round.level_offset_of_round - round_durations - ~round:Round.(succ grandparent_round) - >>?= fun proposal_level_offset -> - Round.level_offset_of_round round_durations ~round:predecessor_round - >>?= fun proposal_round_offset -> - Period.(add proposal_level_offset proposal_round_offset) - >>?= fun proposal_offset -> - return - { - empty with - grandparent_level_start = - Some Timestamp.(predecessor_timestamp - proposal_offset); - round_zero_duration = Some round_zero_duration; - })) - >|= Environment.wrap_tzresult - - let on_flush config filter_state ?(validation_state : validation_state option) - ~predecessor () = - ignore filter_state ; - init config ?validation_state ~predecessor () - - let remove ~(filter_state : state) oph = - match - Operation_hash.Map.find oph filter_state.operation_hash_to_manager - with - | None -> filter_state - | Some source -> - { - filter_state with - op_prechecked_managers = - Signature.Public_key_hash.Map.remove - source - filter_state.op_prechecked_managers; - operation_hash_to_manager = - Operation_hash.Map.remove oph filter_state.operation_hash_to_manager; - } - - let get_manager_operation_gas_and_fee contents = - let open Operation in - let l = to_list (Contents_list contents) in - List.fold_left - (fun acc -> function - | Contents (Manager_operation {fee; gas_limit; _}) -> ( - match acc with - | Error _ as e -> e - | Ok (total_fee, total_gas) -> ( - match Tez.(total_fee +? fee) with - | Ok total_fee -> - Ok (total_fee, Gas.Arith.add total_gas gas_limit) - | Error _ as e -> e)) - | _ -> acc) - (Ok (Tez.zero, Gas.Arith.zero)) - l - - type Environment.Error_monad.error += Fees_too_low - - let () = - Environment.Error_monad.register_error_kind - `Permanent - ~id:"prefilter.fees_too_low" - ~title:"Operation fees are too low" - ~description:"Operation fees are too low" - ~pp:(fun ppf () -> Format.fprintf ppf "Operation fees are too low") - Data_encoding.unit - (function Fees_too_low -> Some () | _ -> None) - (fun () -> Fees_too_low) - - type Environment.Error_monad.error += Manager_restriction - - let () = - Environment.Error_monad.register_error_kind - `Temporary - ~id:"plugin_filter.manager_restriction" - ~title:"Only one manager operation per manager per block allowed" - ~description:"Only one manager operation per manager per block allowed" - ~pp:(fun ppf () -> - Format.fprintf - ppf - "Only one manager operation per manager per block allowed") - Data_encoding.unit - (function Manager_restriction -> Some () | _ -> None) - (fun () -> Manager_restriction) - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2238 - Write unit tests for the feature 'replace-by-fee' and for other changes - introduced by other MRs in the plugin. *) - (* In order to decide if the new operation can replace an old one from the - same manager, we check if its fees (resp. fees/gas ratio) are greater than - (or equal to) the old operations's fees (resp. fees/gas ratio), bumped by - the factor [config.replace_by_fee_factor]. - *) - let better_fees_and_ratio = - let bump config q = Q.mul q config.replace_by_fee_factor in - fun config old_gas old_fee new_gas new_fee -> - let old_fee = Tez.to_mutez old_fee |> Z.of_int64 |> Q.of_bigint in - let old_gas = Gas.Arith.integral_to_z old_gas |> Q.of_bigint in - let new_fee = Tez.to_mutez new_fee |> Z.of_int64 |> Q.of_bigint in - let new_gas = Gas.Arith.integral_to_z new_gas |> Q.of_bigint in - let old_ratio = Q.div old_fee old_gas in - let new_ratio = Q.div new_fee new_gas in - Q.compare new_ratio (bump config old_ratio) >= 0 - && Q.compare new_fee (bump config old_fee) >= 0 - - let check_manager_restriction config filter_state source ~fee ~gas_limit = - match - Signature.Public_key_hash.Map.find - source - filter_state.op_prechecked_managers - with - | None -> `Fresh - | Some {operation_hash = old_hash; gas_limit = old_gas; fee = old_fee} -> - (* Manager already seen: one manager per block limitation triggered. - Can replace old operation if new operation's fees are better *) - if better_fees_and_ratio config old_gas old_fee gas_limit fee then - `Replace old_hash - else - `Fail (`Branch_delayed [Environment.wrap_tzerror Manager_restriction]) - - let pre_filter_manager : - type t. - config -> - state -> - public_key_hash -> - int -> - t Kind.manager contents_list -> - [ `Passed_prefilter - | `Branch_refused of tztrace - | `Branch_delayed of tztrace - | `Refused of tztrace - | `Outdated of tztrace ] = - fun config filter_state source size op -> - let check_gas_and_fee fee gas_limit = - let fees_in_nanotez = - Q.mul (Q.of_int64 (Tez.to_mutez fee)) (Q.of_int 1000) - in - let minimal_fees_in_nanotez = - Q.mul (Q.of_int64 (Tez.to_mutez config.minimal_fees)) (Q.of_int 1000) - in - let minimal_fees_for_gas_in_nanotez = - Q.mul - config.minimal_nanotez_per_gas_unit - (Q.of_bigint @@ Gas.Arith.integral_to_z gas_limit) - in - let minimal_fees_for_size_in_nanotez = - Q.mul config.minimal_nanotez_per_byte (Q.of_int size) - in - if - Q.compare - fees_in_nanotez - (Q.add - minimal_fees_in_nanotez - (Q.add - minimal_fees_for_gas_in_nanotez - minimal_fees_for_size_in_nanotez)) - >= 0 - then `Passed_prefilter - else `Refused [Environment.wrap_tzerror Fees_too_low] - in - match get_manager_operation_gas_and_fee op with - | Error err -> `Refused (Environment.wrap_tztrace err) - | Ok (fee, gas_limit) -> ( - match - check_manager_restriction config filter_state source ~fee ~gas_limit - with - | `Fail errs -> errs - | `Fresh | `Replace _ -> check_gas_and_fee fee gas_limit) - - type Environment.Error_monad.error += Outdated_endorsement - - let () = - Environment.Error_monad.register_error_kind - `Temporary - ~id:"prefilter.outdated_endorsement" - ~title:"Endorsement is outdated" - ~description:"Endorsement is outdated" - ~pp:(fun ppf () -> Format.fprintf ppf "Endorsement is outdated") - Data_encoding.unit - (function Outdated_endorsement -> Some () | _ -> None) - (fun () -> Outdated_endorsement) - - type Environment.Error_monad.error += Wrong_operation - - let () = - Environment.Error_monad.register_error_kind - `Temporary - ~id:"prefilter.wrong_operation" - ~title:"Wrong operation" - ~description:"Failing_noop and old endorsement format are not accepted." - ~pp:(fun ppf () -> - Format.fprintf - ppf - "Failing_noop and old endorsement format are not accepted") - Data_encoding.unit - (function Wrong_operation -> Some () | _ -> None) - (fun () -> Wrong_operation) - - type Environment.Error_monad.error += Consensus_operation_in_far_future - - let () = - Environment.Error_monad.register_error_kind - `Branch - ~id:"prefilter.Consensus_operation_in_far_future" - ~title:"Consensus operation in far future" - ~description:"Consensus operation too far in the future are not accepted." - ~pp:(fun ppf () -> - Format.fprintf - ppf - "Consensus operation too far in the future are not accepted.") - Data_encoding.unit - (function Consensus_operation_in_far_future -> Some () | _ -> None) - (fun () -> Consensus_operation_in_far_future) - - (** {2} consensus operation filtering. - - In Tenderbake, we increased a lot the number of consensus - operations, therefore it seems necessary to be able to filter consensus - operations that could be produced by a Byzantine baker mis-using - its right to produce operations in future rounds or levels. - - We consider the situation where the head is at level [h_l], - round [h_r], and with timestamp [h_ts], with the predecessor of the head - being at round [hp_r]. - We receive at a time [now] a consensus operation for level [op_l] and - round [op_r]. - - A consensus operation is considered too far in the future, and therefore filtered, - if the earliest possible starting time of its round is greater than the - current time plus a safety margin of [config.clock_drift]. - - To consider potential level 2 reorgs, we first compute the expected - timestamp of round zero at previous level [hp0_ts], - - All ops at level p_l and round r' such that time(r') is greater than (now + drift) are - deemed too far in the future: - - h_r op_ts now+drift (h_l,r') - hp0_ts h_0 h_l | | | - +----+-----+---------+-------------------+--+-----+--------------+----------- - | | | | | | | - | h_ts h_r end time | now | earliest expected - | | | | time of round r' - |<----op_r rounds duration -------->| | - | - |<--------------- operations kept ---->|<-rejected----------... - | - |<-----------operations considered by the filter -----------... - - For an operation on a proposal at the next level, we consider the minimum - starting time of the operation's round, obtained by assuming that the proposal - at the next level was built on top of a proposal at round 0 for the current - level, itself based on a proposal at round 0 of previous level. - Operations on proposal with higher levels are treated similarly. - - All ops at the next level and round r' such that timestamp(r') > now+drift - are deemed too far in the future. - - r=0 r=1 h_r now now+drift (h_l+1,r') - hp0_ts h_0 h_l h_l | | | - +----+---- |-------+----+---------+----------+----------+---------- - | | | | | - | t0 | h_ts earliest expected - | | | | time of round r' - |<--- | earliest| | - | next level| | - | |<---------------------------------->| - round_offset(r') - - *) - - (** At a given level a consensus operation is acceptable if its earliest - expected timestamp, [op_earliest_ts] is below the current clock with an - accepted drift for the clock given by a configuration. *) - let acceptable ~drift ~op_earliest_ts ~now_timestamp = - Timestamp.( - now_timestamp +? drift >|? fun now_drifted -> - op_earliest_ts <= now_drifted) - - (** Check that an operation with the given [op_round], at level [op_level] - is likely to be correct, meaning it could have been produced before - now (+ the safety margin from configuration). - - Given an operation at level greater or equal than/to the current level, we - compute the expected timestamp of the operation's round. If the operation - is at a greater level, we assume that it is based on the proposal at round - zero of the current level. - - All operations whose (level, round) is lower than or equal to the current - head are deemed valid. - Note that in case where their is a high drift in the computer clock, they - might not have been considered valid by comparing their expected timestamp - to the clock. - - This is a stricter than necessary filter as it will reject operations that - could be valid in the current timeframe if the proposal they endorse is - built over a predecessor of the current proposal that would be of lower - round than the current one. - - What can we do that would be smarter: get current head's predecessor round - and timestamp to compute the timestamp t0 of a predecessor that would have - been proposed at round 0. - - Timestamp of round at current level for an alternative head that would be - based on such proposal would be computed based on t0. - For level higher than current head, compute the round's earliest timestamp - if all proposal passed at round 0 starting from t0. - *) - let acceptable_op ~config ~round_durations ~round_zero_duration - ~proposal_level ~proposal_round ~proposal_timestamp - ~(proposal_predecessor_level_start : Timestamp.t) ~op_level ~op_round - ~now_timestamp = - if - Raw_level.(succ op_level < proposal_level) - || (op_level = proposal_level && op_round <= proposal_round) - then - (* Past and current round operations are not in the future *) - (* This case could be handled directly in `pre_filter_far_future_consensus_ops` - for a (slightly) better performance. *) - Ok true - else - (* If, by some tolerance on local clock drift, the timestamp of the - current head is itself in the future, we use this time instead of - now_timestamp *) - let now_timestamp = Timestamp.(max now_timestamp proposal_timestamp) in - (* Computing when the current level started. *) - let drift = - Option.value ~default:round_zero_duration config.clock_drift - in - (* We compute the earliest timestamp possible [op_earliest_ts] for the - operation's (level,round), as if all proposals were accepted at round 0 - since the previous level. *) - (* Invariant: [op_level + 1 >= proposal_level] *) - let level_offset = Raw_level.(diff (succ op_level) proposal_level) in - Period.mult level_offset round_zero_duration >>? fun time_shift -> - Timestamp.(proposal_predecessor_level_start +? time_shift) - >>? fun earliest_op_level_start -> - (* computing the operations's round start from it's earliest - possible level start *) - Round.timestamp_of_another_round_same_level - round_durations - ~current_round:Round.zero - ~current_timestamp:earliest_op_level_start - ~considered_round:op_round - >>? fun op_earliest_ts -> - (* We finally check that the expected time of the operation is - acceptable *) - acceptable ~drift ~op_earliest_ts ~now_timestamp - - let pre_filter_far_future_consensus_ops config - ~filter_state:({grandparent_level_start; round_zero_duration; _} : state) - ?validation_state_before - ({level = op_level; round = op_round; _} : consensus_content) : bool Lwt.t - = - match - (grandparent_level_start, validation_state_before, round_zero_duration) - with - | (None, _, _) | (_, None, _) | (_, _, None) -> Lwt.return_true - | ( Some grandparent_level_start, - Some validation_state_before, - Some round_zero_duration ) -> ( - let ctxt : t = validation_state_before.ctxt in - match validation_state_before.mode with - | Application _ | Partial_application _ | Full_construction _ -> - assert false - (* Prefilter is always applied in mempool mode aka Partial_construction *) - | Partial_construction {predecessor_round = proposal_round; _} -> ( - (let proposal_timestamp = - Alpha_context.Timestamp.predecessor ctxt - in - let now_timestamp = Systime_os.now () |> Time.System.to_protocol in - let Level.{level; _} = Alpha_context.Level.current ctxt in - let proposal_level = - match Raw_level.pred level with - | None -> - (* mempool level is set to the successor of the - current head *) - assert false - | Some proposal_level -> proposal_level - in - let round_durations = - Alpha_context.Constants.round_durations ctxt - in - Lwt.return - @@ acceptable_op - ~config - ~round_durations - ~round_zero_duration - ~proposal_level - ~proposal_round - ~proposal_timestamp - ~proposal_predecessor_level_start:grandparent_level_start - ~op_level - ~op_round - ~now_timestamp) - >>= function - | Ok b -> Lwt.return b - | _ -> Lwt.return_false)) - - (** A quasi infinite amount of "valid" (pre)endorsements could be - sent by a committee member, one for each possible round number. - - This filter rejects (pre)endorsements that refer to a round - that could not have been reached within the time span between - the last head's timestamp and the current local clock. - - We add [config.clock_drift] time as a safety margin. - *) - let pre_filter config ~(filter_state : state) ?validation_state_before - (Operation_data {contents; _} as op : Operation.packed_protocol_data) = - let bytes = - (WithExceptions.Option.get ~loc:__LOC__ - @@ Data_encoding.Binary.fixed_length - Tezos_base.Operation.shell_header_encoding) - + Data_encoding.Binary.length Operation.protocol_data_encoding op - in - match contents with - | Single (Failing_noop _) -> - Lwt.return (`Refused [Environment.wrap_tzerror Wrong_operation]) - | Single (Preendorsement consensus_content) - | Single (Endorsement consensus_content) -> - pre_filter_far_future_consensus_ops - ~filter_state - config - ?validation_state_before - consensus_content - >>= fun keep -> - if keep then Lwt.return `Passed_prefilter - else - Lwt.return - (`Branch_refused - [Environment.wrap_tzerror Consensus_operation_in_far_future]) - | Single (Seed_nonce_revelation _) - | Single (Double_preendorsement_evidence _) - | Single (Double_endorsement_evidence _) - | Single (Double_baking_evidence _) - | Single (Activate_account _) - | Single (Proposals _) - | Single (Ballot _) -> - Lwt.return @@ `Passed_prefilter - | Single (Manager_operation {source; _}) as op -> - Lwt.return @@ pre_filter_manager config filter_state source bytes op - | Cons (Manager_operation {source; _}, _) as op -> - Lwt.return @@ pre_filter_manager config filter_state source bytes op - - let precheck_manager : - type t. - config -> - state -> - validation_state -> - Tezos_base.Operation.shell_header -> - t Kind.manager protocol_data -> - fee:Tez.t -> - gas_limit:manager_gas_witness Gas.Arith.t -> - public_key_hash -> - [> `Prechecked_manager - | `Prechecked_manager_with_replace of Operation_hash.t - | `Branch_delayed of tztrace - | `Branch_refused of tztrace - | `Refused of tztrace - | `Outdated of tztrace ] - Lwt.t = - fun config - filter_state - validation_state - shell - ({contents; _} as protocol_data : t Kind.manager protocol_data) - ~fee - ~gas_limit - source -> - let precheck_manager_and_check_signature ~on_success = - ( Main.precheck_manager validation_state contents >>=? fun () -> - let (raw_operation : t Kind.manager operation) = - Alpha_context.{shell; protocol_data} - in - Main.check_manager_signature validation_state contents raw_operation ) - >|= function - | Ok () -> on_success - | Error err -> ( - let err = Environment.wrap_tztrace err in - match classify_trace err with - | Branch -> `Branch_refused err - | Permanent -> `Refused err - | Temporary -> `Branch_delayed err - | Outdated -> `Outdated err) - in - match - check_manager_restriction config filter_state source ~fee ~gas_limit - with - | `Fail err -> Lwt.return err - | `Fresh -> - precheck_manager_and_check_signature ~on_success:`Prechecked_manager - | `Replace old_oph -> - precheck_manager_and_check_signature - ~on_success:(`Prechecked_manager_with_replace old_oph) - - let add_manager_restriction filter_state oph info source = - { - filter_state with - op_prechecked_managers = - (* Manager not seen yet, record it for next ops *) - Signature.Public_key_hash.Map.add - source - info - filter_state.op_prechecked_managers; - operation_hash_to_manager = - Operation_hash.Map.add oph source filter_state.operation_hash_to_manager - (* Record which manager is used for the operation hash. *); - } - - let precheck : - config -> - filter_state:state -> - validation_state:validation_state -> - Tezos_base.Operation.shell_header -> - Operation_hash.t -> - Main.operation_data -> - [ `Passed_precheck of state - | `Passed_precheck_with_replace of Operation_hash.t * state - | `Branch_delayed of tztrace - | `Branch_refused of tztrace - | `Refused of tztrace - | `Outdated of tztrace - | `Undecided ] - Lwt.t = - fun config - ~filter_state - ~validation_state - shell_header - oph - (Operation_data protocol_data) -> - let precheck_manager protocol_data source op = - match get_manager_operation_gas_and_fee op with - | Error err -> Lwt.return (`Refused (Environment.wrap_tztrace err)) - | Ok (fee, gas_limit) -> ( - let info = {operation_hash = oph; gas_limit; fee} in - precheck_manager - config - filter_state - validation_state - shell_header - protocol_data - source - ~fee - ~gas_limit - >|= function - | `Prechecked_manager -> - `Passed_precheck - (add_manager_restriction filter_state oph info source) - | `Prechecked_manager_with_replace old_oph -> - `Passed_precheck_with_replace - (old_oph, add_manager_restriction filter_state oph info source) - | (`Refused _ | `Branch_delayed _ | `Branch_refused _ | `Outdated _) - as errs -> - errs) - in - match protocol_data.contents with - | Single (Manager_operation {source; _}) as op -> - precheck_manager protocol_data source op - | Cons (Manager_operation {source; _}, _) as op -> - precheck_manager protocol_data source op - | Single _ -> Lwt.return `Undecided - - open Apply_results - - type Environment.Error_monad.error += Skipped_operation - - let () = - Environment.Error_monad.register_error_kind - `Temporary - ~id:"postfilter.skipped_operation" - ~title:"The operation has been skipped by the protocol" - ~description:"The operation has been skipped by the protocol" - ~pp:(fun ppf () -> - Format.fprintf ppf "The operation has been skipped by the protocol") - Data_encoding.unit - (function Skipped_operation -> Some () | _ -> None) - (fun () -> Skipped_operation) - - type Environment.Error_monad.error += Backtracked_operation - - let () = - Environment.Error_monad.register_error_kind - `Temporary - ~id:"postfilter.backtracked_operation" - ~title:"The operation has been backtracked by the protocol" - ~description:"The operation has been backtracked by the protocol" - ~pp:(fun ppf () -> - Format.fprintf ppf "The operation has been backtracked by the protocol") - Data_encoding.unit - (function Backtracked_operation -> Some () | _ -> None) - (fun () -> Backtracked_operation) - - let rec post_filter_manager : - type t. - Alpha_context.t -> - state -> - t Kind.manager contents_result_list -> - config -> - [`Passed_postfilter of state | `Refused of tztrace] = - fun ctxt filter_state result config -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2181 - This function should be unit tested. - The errors that can be raised if allow_script_failure is enable should - be tested. *) - match result with - | Single_result (Manager_operation_result {operation_result; _}) -> ( - let check_allow_script_failure errs = - if config.allow_script_failure then `Passed_postfilter filter_state - else `Refused errs - in - match operation_result with - | Applied _ -> `Passed_postfilter filter_state - | Skipped _ -> - check_allow_script_failure - [Environment.wrap_tzerror Skipped_operation] - | Failed (_, errors) -> - check_allow_script_failure (Environment.wrap_tztrace errors) - | Backtracked (_, errors) -> - check_allow_script_failure - (match errors with - | Some e -> Environment.wrap_tztrace e - | None -> [Environment.wrap_tzerror Backtracked_operation])) - | Cons_result (Manager_operation_result res, rest) -> ( - post_filter_manager - ctxt - filter_state - (Single_result (Manager_operation_result res)) - config - |> function - | `Passed_postfilter filter_state -> - post_filter_manager ctxt filter_state rest config - | `Refused _ as errs -> errs) - - let post_filter config ~(filter_state : state) ~validation_state_before:_ - ~validation_state_after:({ctxt; _} : validation_state) (_op, receipt) = - match receipt with - | No_operation_metadata -> assert false (* only for multipass validator *) - | Operation_metadata {contents} -> ( - match contents with - | Single_result (Preendorsement_result _) - | Single_result (Endorsement_result _) - | Single_result (Seed_nonce_revelation_result _) - | Single_result (Double_preendorsement_evidence_result _) - | Single_result (Double_endorsement_evidence_result _) - | Single_result (Double_baking_evidence_result _) - | Single_result (Activate_account_result _) - | Single_result Proposals_result - | Single_result Ballot_result -> - Lwt.return (`Passed_postfilter filter_state) - | Single_result (Manager_operation_result _) as result -> - Lwt.return (post_filter_manager ctxt filter_state result config) - | Cons_result (Manager_operation_result _, _) as result -> - Lwt.return (post_filter_manager ctxt filter_state result config)) -end - -module View_helpers = struct - open Tezos_micheline - - type Environment.Error_monad.error += Viewed_contract_has_no_script - - type Environment.Error_monad.error += View_callback_origination_failed - - type Environment.Error_monad.error += - | Illformed_view_type of string * Script.expr - - type Environment.Error_monad.error += - | View_never_returns of string * Contract.t - - type Environment.Error_monad.error += - | View_unexpected_return of string * Contract.t - - let () = - Environment.Error_monad.register_error_kind - `Permanent - ~id:"viewedContractHasNoScript" - ~title:"Viewed contract has no script" - ~description:"A view was called on a contract with no script." - ~pp:(fun ppf () -> - Format.fprintf ppf "A view was called on a contract with no script.") - Data_encoding.(unit) - (function Viewed_contract_has_no_script -> Some () | _ -> None) - (fun () -> Viewed_contract_has_no_script) ; - Environment.Error_monad.register_error_kind - `Permanent - ~id:"viewCallbackOriginationFailed" - ~title:"View callback origination failed" - ~description:"View callback origination failed" - ~pp:(fun ppf () -> - Format.fprintf ppf "Error during origination of view callback contract.") - Data_encoding.(unit) - (function View_callback_origination_failed -> Some () | _ -> None) - (fun () -> View_callback_origination_failed) ; - Environment.Error_monad.register_error_kind - `Permanent - ~id:"illformedViewType" - ~title:"An entrypoint type is incompatible with TZIP-4 view type." - ~description:"An entrypoint type is incompatible with TZIP-4 view type." - ~pp:(fun ppf (entrypoint, typ) -> - Format.fprintf - ppf - "The view %s has type %a, it is not compatible with a TZIP-4 view \ - type." - entrypoint - Micheline_printer.print_expr - (Micheline_printer.printable - (fun x -> x) - (Michelson_v1_primitives.strings_of_prims typ))) - Data_encoding.( - obj2 (req "entrypoint" string) (req "type" Script.expr_encoding)) - (function Illformed_view_type (etp, exp) -> Some (etp, exp) | _ -> None) - (fun (etp, exp) -> Illformed_view_type (etp, exp)) ; - Environment.Error_monad.register_error_kind - `Permanent - ~id:"viewNeverReturns" - ~title: - "A view never returned a transaction to the given callback contract" - ~description: - "A view never initiated a transaction to the given callback contract." - ~pp:(fun ppf (entrypoint, callback) -> - Format.fprintf - ppf - "The view %s never initiated a transaction to the given callback \ - contract %a." - entrypoint - Contract.pp - callback) - Data_encoding.( - obj2 (req "entrypoint" string) (req "callback" Contract.encoding)) - (function View_never_returns (e, c) -> Some (e, c) | _ -> None) - (fun (e, c) -> View_never_returns (e, c)) ; - Environment.Error_monad.register_error_kind - `Permanent - ~id:"viewUnexpectedReturn" - ~title:"A view returned an unexpected list of operations" - ~description: - "A view initiated a list of operations while the TZIP-4 standard \ - expects only a transaction to the given callback contract." - ~pp:(fun ppf (entrypoint, callback) -> - Format.fprintf - ppf - "The view %s initiated a list of operations while the TZIP-4 \ - standard expects only a transaction to the given callback contract \ - %a." - entrypoint - Contract.pp - callback) - Data_encoding.( - obj2 (req "entrypoint" string) (req "callback" Contract.encoding)) - (function View_never_returns (e, c) -> Some (e, c) | _ -> None) - (fun (e, c) -> View_never_returns (e, c)) - - (* This script is actually never run, its usage is to ensure a - contract that has the type `contract ` is originated, which - will be required as callback of the view. *) - let make_viewer_script ty : Script.t = - let loc = 0 in - let ty = Micheline.root ty in - let code = - Micheline.strip_locations - @@ Micheline.Seq - ( loc, - [ - Micheline.Prim (loc, Script.K_parameter, [ty], []); - Micheline.Prim - ( loc, - Script.K_storage, - [Micheline.Prim (loc, Script.T_unit, [], [])], - [] ); - Micheline.Prim - ( loc, - Script.K_code, - [Micheline.Prim (loc, Script.I_FAILWITH, [], [])], - [] ); - ] ) - in - let storage = - Micheline.strip_locations (Micheline.Prim (loc, Script.D_Unit, [], [])) - in - {code = Script.lazy_expr code; storage = Script.lazy_expr storage} - - let make_view_parameter input callback = - let loc = 0 in - Micheline.strip_locations - (Micheline.Prim - ( loc, - Script.D_Pair, - [ - input; - Micheline.Bytes - ( loc, - Data_encoding.Binary.to_bytes_exn Contract.encoding callback ); - ], - [] )) - - let extract_view_output_type entrypoint ty = - match Micheline.root ty with - | Micheline.Prim - ( _, - Script.T_pair, - [_; Micheline.Prim (_, Script.T_contract, [ty], _)], - _ ) -> - ok (Micheline.strip_locations ty) - | _ -> Environment.Error_monad.error (Illformed_view_type (entrypoint, ty)) - - (* 'view' entrypoints returns their value by calling a callback contract, thus - the expected result is a unique internal transaction to this callback. *) - let extract_parameter_from_operations entrypoint operations callback = - let unexpected_return = - Environment.Error_monad.error - @@ View_unexpected_return (entrypoint, callback) - in - match operations with - | [ - Internal_operation - {operation = Transaction {destination; parameters; _}; _}; - ] - when Contract.equal destination callback -> - ok parameters - | [] -> - Environment.Error_monad.error - (View_never_returns (entrypoint, callback)) - | _ -> unexpected_return -end - -module RPC = struct - open Environment - open Alpha_context - open Environment.Error_monad - - let parse_operation (op : Operation.raw) = - match - Data_encoding.Binary.of_bytes_opt - Operation.protocol_data_encoding - op.proto - with - | Some protocol_data -> ok {shell = op.shell; protocol_data} - | None -> error Cannot_parse_operation - - let path = RPC_path.(open_root / "helpers") - - module Registration = struct - let patched_services = - ref (RPC_directory.empty : Updater.rpc_context RPC_directory.t) - - let register0_fullctxt ~chunked s f = - patched_services := - RPC_directory.register ~chunked !patched_services s (fun ctxt q i -> - Services_registration.rpc_init ctxt >>=? fun ctxt -> f ctxt q i) - - let register0 ~chunked s f = - register0_fullctxt ~chunked s (fun {context; _} -> f context) - - let register0_noctxt ~chunked s f = - patched_services := - RPC_directory.register ~chunked !patched_services s (fun _ q i -> f q i) - - let opt_register0_fullctxt ~chunked s f = - patched_services := - RPC_directory.opt_register ~chunked !patched_services s (fun ctxt q i -> - Services_registration.rpc_init ctxt >>=? fun ctxt -> f ctxt q i) - - let opt_register0 ~chunked s f = - opt_register0_fullctxt ~chunked s (fun {context; _} -> f context) - - let register1_fullctxt ~chunked s f = - patched_services := - RPC_directory.register - ~chunked - !patched_services - s - (fun (ctxt, arg) q i -> - Services_registration.rpc_init ctxt >>=? fun ctxt -> f ctxt arg q i) - - let register1 ~chunked s f = - register1_fullctxt ~chunked s (fun {context; _} x -> f context x) - - let register2_fullctxt ~chunked s f = - patched_services := - RPC_directory.register - ~chunked - !patched_services - s - (fun ((ctxt, arg1), arg2) q i -> - Services_registration.rpc_init ctxt >>=? fun ctxt -> - f ctxt arg1 arg2 q i) - - let register2 ~chunked s f = - register2_fullctxt ~chunked s (fun {context; _} a1 a2 q i -> - f context a1 a2 q i) - end - - let unparsing_mode_encoding = - let open Script_ir_translator in - let open Data_encoding in - union - ~tag_size:`Uint8 - [ - case - (Tag 0) - ~title:"Readable" - (constant "Readable") - (function - | Readable -> Some () | Optimized | Optimized_legacy -> None) - (fun () -> Readable); - case - (Tag 1) - ~title:"Optimized" - (constant "Optimized") - (function - | Optimized -> Some () | Readable | Optimized_legacy -> None) - (fun () -> Optimized); - case - (Tag 2) - ~title:"Optimized_legacy" - (constant "Optimized_legacy") - (function - | Optimized_legacy -> Some () | Readable | Optimized -> None) - (fun () -> Optimized_legacy); - ] - - module Scripts = struct - module S = struct - open Data_encoding - - let path = RPC_path.(path / "scripts") - - let run_code_input_encoding = - merge_objs - (obj10 - (req "script" Script.expr_encoding) - (req "storage" Script.expr_encoding) - (req "input" Script.expr_encoding) - (req "amount" Tez.encoding) - (req "balance" Tez.encoding) - (req "chain_id" Chain_id.encoding) - (opt "source" Contract.encoding) - (opt "payer" Contract.encoding) - (opt "gas" Gas.Arith.z_integral_encoding) - (dft "entrypoint" string "default")) - (obj3 - (opt "unparsing_mode" unparsing_mode_encoding) - (opt "now" Script_timestamp.encoding) - (opt "level" Script_int.n_encoding)) - - let run_code_output_encoding = - conv - (fun (storage, operations, lazy_storage_diff) -> - (storage, operations, lazy_storage_diff, lazy_storage_diff)) - (fun (storage, operations, legacy_lazy_storage_diff, lazy_storage_diff) - -> - let lazy_storage_diff = - Option.either lazy_storage_diff legacy_lazy_storage_diff - in - (storage, operations, lazy_storage_diff)) - (obj4 - (req "storage" Script.expr_encoding) - (req "operations" (list Operation.internal_operation_encoding)) - (opt "big_map_diff" Lazy_storage.legacy_big_map_diff_encoding) - (opt "lazy_storage_diff" Lazy_storage.encoding)) - - let trace_code_input_encoding = run_code_input_encoding - - let trace_encoding = - def "scripted.trace" @@ list - @@ obj3 - (req "location" Script.location_encoding) - (req "gas" Gas.encoding) - (req - "stack" - (list - (obj2 (req "item" Script.expr_encoding) (opt "annot" string)))) - - let trace_code_output_encoding = - conv - (fun (storage, operations, trace, lazy_storage_diff) -> - (storage, operations, trace, lazy_storage_diff, lazy_storage_diff)) - (fun ( storage, - operations, - trace, - legacy_lazy_storage_diff, - lazy_storage_diff ) -> - let lazy_storage_diff = - Option.either lazy_storage_diff legacy_lazy_storage_diff - in - (storage, operations, trace, lazy_storage_diff)) - (obj5 - (req "storage" Script.expr_encoding) - (req "operations" (list Operation.internal_operation_encoding)) - (req "trace" trace_encoding) - (opt "big_map_diff" Lazy_storage.legacy_big_map_diff_encoding) - (opt "lazy_storage_diff" Lazy_storage.encoding)) - - let run_view_encoding = - let open Data_encoding in - obj10 - (req "contract" Contract.encoding) - (req "entrypoint" string) - (req "input" Script.expr_encoding) - (req "chain_id" Chain_id.encoding) - (opt "source" Contract.encoding) - (opt "payer" Contract.encoding) - (opt "gas" Gas.Arith.z_integral_encoding) - (req "unparsing_mode" unparsing_mode_encoding) - (opt "now" Script_timestamp.encoding) - (opt "level" Script_int.n_encoding) - - let run_code = - RPC_service.post_service - ~description:"Run a piece of code in the current context" - ~query:RPC_query.empty - ~input:run_code_input_encoding - ~output:run_code_output_encoding - RPC_path.(path / "run_code") - - let trace_code = - RPC_service.post_service - ~description: - "Run a piece of code in the current context, keeping a trace" - ~query:RPC_query.empty - ~input:trace_code_input_encoding - ~output:trace_code_output_encoding - RPC_path.(path / "trace_code") - - let run_view = - RPC_service.post_service - ~description: - "Simulate a call to a view following the TZIP-4 standard. See \ - https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-4/tzip-4.md#view-entrypoints." - ~input:run_view_encoding - ~output:(obj1 (req "data" Script.expr_encoding)) - ~query:RPC_query.empty - RPC_path.(path / "run_view") - - let typecheck_code = - RPC_service.post_service - ~description:"Typecheck a piece of code in the current context" - ~query:RPC_query.empty - ~input: - (obj4 - (req "program" Script.expr_encoding) - (opt "gas" Gas.Arith.z_integral_encoding) - (opt "legacy" bool) - (opt "show_types" bool)) - ~output: - (obj2 - (req "type_map" Script_tc_errors_registration.type_map_enc) - (req "gas" Gas.encoding)) - RPC_path.(path / "typecheck_code") - - let script_size = - RPC_service.post_service - ~description:"Compute the size of a script in the current context" - ~query:RPC_query.empty - ~input: - (obj4 - (req "program" Script.expr_encoding) - (req "storage" Script.expr_encoding) - (opt "gas" Gas.Arith.z_integral_encoding) - (opt "legacy" bool)) - ~output:(obj1 (req "script_size" int31)) - RPC_path.(path / "script_size") - - let typecheck_data = - RPC_service.post_service - ~description: - "Check that some data expression is well formed and of a given \ - type in the current context" - ~query:RPC_query.empty - ~input: - (obj4 - (req "data" Script.expr_encoding) - (req "type" Script.expr_encoding) - (opt "gas" Gas.Arith.z_integral_encoding) - (opt "legacy" bool)) - ~output:(obj1 (req "gas" Gas.encoding)) - RPC_path.(path / "typecheck_data") - - let pack_data = - RPC_service.post_service - ~description: - "Computes the serialized version of some data expression using the \ - same algorithm as script instruction PACK" - ~input: - (obj3 - (req "data" Script.expr_encoding) - (req "type" Script.expr_encoding) - (opt "gas" Gas.Arith.z_integral_encoding)) - ~output:(obj2 (req "packed" bytes) (req "gas" Gas.encoding)) - ~query:RPC_query.empty - RPC_path.(path / "pack_data") - - let normalize_data = - RPC_service.post_service - ~description: - "Normalizes some data expression using the requested unparsing mode" - ~input: - (obj4 - (req "data" Script.expr_encoding) - (req "type" Script.expr_encoding) - (req "unparsing_mode" unparsing_mode_encoding) - (opt "legacy" bool)) - ~output:(obj1 (req "normalized" Script.expr_encoding)) - ~query:RPC_query.empty - RPC_path.(path / "normalize_data") - - let normalize_script = - RPC_service.post_service - ~description: - "Normalizes a Michelson script using the requested unparsing mode" - ~input: - (obj2 - (req "script" Script.expr_encoding) - (req "unparsing_mode" unparsing_mode_encoding)) - ~output:(obj1 (req "normalized" Script.expr_encoding)) - ~query:RPC_query.empty - RPC_path.(path / "normalize_script") - - let normalize_type = - RPC_service.post_service - ~description: - "Normalizes some Michelson type by expanding `pair a b c` as `pair \ - a (pair b c)" - ~input:(obj1 (req "type" Script.expr_encoding)) - ~output:(obj1 (req "normalized" Script.expr_encoding)) - ~query:RPC_query.empty - RPC_path.(path / "normalize_type") - - let run_operation = - RPC_service.post_service - ~description:"Run an operation without signature checks" - ~query:RPC_query.empty - ~input: - (obj2 - (req "operation" Operation.encoding) - (req "chain_id" Chain_id.encoding)) - ~output:Apply_results.operation_data_and_metadata_encoding - RPC_path.(path / "run_operation") - - let simulate_operation = - RPC_service.post_service - ~description:"Simulate an operation" - ~query:RPC_query.empty - ~input: - (obj3 - (req "operation" Operation.encoding) - (req "chain_id" Chain_id.encoding) - (dft "latency" int16 default_operation_inclusion_latency)) - ~output:Apply_results.operation_data_and_metadata_encoding - RPC_path.(path / "simulate_operation") - - let entrypoint_type = - RPC_service.post_service - ~description:"Return the type of the given entrypoint" - ~query:RPC_query.empty - ~input: - (obj2 - (req "script" Script.expr_encoding) - (dft "entrypoint" string "default")) - ~output:(obj1 (req "entrypoint_type" Script.expr_encoding)) - RPC_path.(path / "entrypoint") - - let list_entrypoints = - RPC_service.post_service - ~description:"Return the list of entrypoints of the given script" - ~query:RPC_query.empty - ~input:(obj1 (req "script" Script.expr_encoding)) - ~output: - (obj2 - (dft - "unreachable" - (Data_encoding.list - (obj1 - (req - "path" - (Data_encoding.list - Michelson_v1_primitives.prim_encoding)))) - []) - (req "entrypoints" (assoc Script.expr_encoding))) - RPC_path.(path / "entrypoints") - end - - module type UNPARSING_MODE = sig - val unparsing_mode : Script_ir_translator.unparsing_mode - end - - module Traced_interpreter (Unparsing_mode : UNPARSING_MODE) = struct - type log_element = - | Log : - context - * Script.location - * ('a * 's) - * ('a, 's) Script_typed_ir.stack_ty - -> log_element - - let unparse_stack ctxt (stack, stack_ty) = - (* We drop the gas limit as this function is only used for debugging/errors. *) - let ctxt = Gas.set_unlimited ctxt in - let rec unparse_stack : - type a s. - (a, s) Script_typed_ir.stack_ty * (a * s) -> - (Script.expr * string option) list tzresult Lwt.t = function - | (Bot_t, (EmptyCell, EmptyCell)) -> return_nil - | (Item_t (ty, rest_ty, annot), (v, rest)) -> - Script_ir_translator.unparse_data - ctxt - Unparsing_mode.unparsing_mode - ty - v - >>=? fun (data, _ctxt) -> - unparse_stack (rest_ty, rest) >|=? fun rest -> - let annot = - match Script_ir_annot.unparse_var_annot annot with - | [] -> None - | [a] -> Some a - | _ -> assert false - in - let data = Micheline.strip_locations data in - (data, annot) :: rest - in - unparse_stack (stack_ty, stack) - - let trace_logger () : Script_typed_ir.logger = - let log : log_element list ref = ref [] in - let log_interp _ ctxt loc sty stack = - log := Log (ctxt, loc, stack, sty) :: !log - in - let log_entry _ _ctxt _loc _sty _stack = () in - let log_exit _ ctxt loc sty stack = - log := Log (ctxt, loc, stack, sty) :: !log - in - let log_control _ = () in - let get_log () = - List.map_es - (fun (Log (ctxt, loc, stack, stack_ty)) -> - trace Cannot_serialize_log (unparse_stack ctxt (stack, stack_ty)) - >>=? fun stack -> return (loc, Gas.level ctxt, stack)) - !log - >>=? fun res -> return (Some (List.rev res)) - in - {log_exit; log_entry; log_interp; get_log; log_control} - - let execute ctxt step_constants ~script ~entrypoint ~parameter = - let open Script_interpreter in - let logger = trace_logger () in - execute - ~logger - ~cached_script:None - ctxt - Unparsing_mode.unparsing_mode - step_constants - ~script - ~entrypoint - ~parameter - ~internal:true - >>=? fun ({ctxt; storage; lazy_storage_diff; operations}, _) -> - logger.get_log () >|=? fun trace -> - let trace = Option.value ~default:[] trace in - ({ctxt; storage; lazy_storage_diff; operations}, trace) - end - - let typecheck_data : - legacy:bool -> - context -> - Script.expr * Script.expr -> - context tzresult Lwt.t = - fun ~legacy ctxt (data, exp_ty) -> - record_trace - (Script_tc_errors.Ill_formed_type (None, exp_ty, 0)) - (Script_ir_translator.parse_parameter_ty - ctxt - ~legacy - (Micheline.root exp_ty)) - >>?= fun (Ex_ty exp_ty, ctxt) -> - trace_eval - (fun () -> - let exp_ty = Script_ir_translator.serialize_ty_for_error exp_ty in - Script_tc_errors.Ill_typed_data (None, data, exp_ty)) - (let allow_forged = - true - (* Safe since we ignore the value afterwards. *) - in - Script_ir_translator.parse_data - ctxt - ~legacy - ~allow_forged - exp_ty - (Micheline.root data)) - >|=? fun (_, ctxt) -> ctxt - - module Unparse_types = struct - (* Same as the unparsing functions for types in Script_ir_translator but - does not consume gas and never folds (pair a (pair b c)) *) - - open Script_ir_translator - open Micheline - open Michelson_v1_primitives - open Script_ir_annot - open Script_typed_ir - - let rec unparse_comparable_ty : - type a loc. - loc:loc -> a comparable_ty -> (loc, Script.prim) Micheline.node = - fun ~loc -> function - | Unit_key meta -> Prim (loc, T_unit, [], unparse_type_annot meta.annot) - | Never_key meta -> - Prim (loc, T_never, [], unparse_type_annot meta.annot) - | Int_key meta -> Prim (loc, T_int, [], unparse_type_annot meta.annot) - | Nat_key meta -> Prim (loc, T_nat, [], unparse_type_annot meta.annot) - | Signature_key meta -> - Prim (loc, T_signature, [], unparse_type_annot meta.annot) - | String_key meta -> - Prim (loc, T_string, [], unparse_type_annot meta.annot) - | Bytes_key meta -> - Prim (loc, T_bytes, [], unparse_type_annot meta.annot) - | Mutez_key meta -> - Prim (loc, T_mutez, [], unparse_type_annot meta.annot) - | Bool_key meta -> Prim (loc, T_bool, [], unparse_type_annot meta.annot) - | Key_hash_key meta -> - Prim (loc, T_key_hash, [], unparse_type_annot meta.annot) - | Key_key meta -> Prim (loc, T_key, [], unparse_type_annot meta.annot) - | Timestamp_key meta -> - Prim (loc, T_timestamp, [], unparse_type_annot meta.annot) - | Address_key meta -> - Prim (loc, T_address, [], unparse_type_annot meta.annot) - | Chain_id_key meta -> - Prim (loc, T_chain_id, [], unparse_type_annot meta.annot) - | Pair_key ((l, al), (r, ar), meta) -> - let tl = add_field_annot al None (unparse_comparable_ty ~loc l) in - let tr = add_field_annot ar None (unparse_comparable_ty ~loc r) in - Prim (loc, T_pair, [tl; tr], unparse_type_annot meta.annot) - | Union_key ((l, al), (r, ar), meta) -> - let tl = add_field_annot al None (unparse_comparable_ty ~loc l) in - let tr = add_field_annot ar None (unparse_comparable_ty ~loc r) in - Prim (loc, T_or, [tl; tr], unparse_type_annot meta.annot) - | Option_key (t, meta) -> - Prim - ( loc, - T_option, - [unparse_comparable_ty ~loc t], - unparse_type_annot meta.annot ) - - let unparse_memo_size ~loc memo_size = - let z = Alpha_context.Sapling.Memo_size.unparse_to_z memo_size in - Int (loc, z) - - let rec unparse_ty : - type a loc. loc:loc -> a ty -> (loc, Script.prim) Micheline.node = - fun ~loc ty -> - let return (name, args, annot) = Prim (loc, name, args, annot) in - match ty with - | Unit_t meta -> return (T_unit, [], unparse_type_annot meta.annot) - | Int_t meta -> return (T_int, [], unparse_type_annot meta.annot) - | Nat_t meta -> return (T_nat, [], unparse_type_annot meta.annot) - | Signature_t meta -> - return (T_signature, [], unparse_type_annot meta.annot) - | String_t meta -> return (T_string, [], unparse_type_annot meta.annot) - | Bytes_t meta -> return (T_bytes, [], unparse_type_annot meta.annot) - | Mutez_t meta -> return (T_mutez, [], unparse_type_annot meta.annot) - | Bool_t meta -> return (T_bool, [], unparse_type_annot meta.annot) - | Key_hash_t meta -> - return (T_key_hash, [], unparse_type_annot meta.annot) - | Key_t meta -> return (T_key, [], unparse_type_annot meta.annot) - | Timestamp_t meta -> - return (T_timestamp, [], unparse_type_annot meta.annot) - | Address_t meta -> return (T_address, [], unparse_type_annot meta.annot) - | Operation_t meta -> - return (T_operation, [], unparse_type_annot meta.annot) - | Chain_id_t meta -> - return (T_chain_id, [], unparse_type_annot meta.annot) - | Never_t meta -> return (T_never, [], unparse_type_annot meta.annot) - | Bls12_381_g1_t meta -> - return (T_bls12_381_g1, [], unparse_type_annot meta.annot) - | Bls12_381_g2_t meta -> - return (T_bls12_381_g2, [], unparse_type_annot meta.annot) - | Bls12_381_fr_t meta -> - return (T_bls12_381_fr, [], unparse_type_annot meta.annot) - | Contract_t (ut, meta) -> - let t = unparse_ty ~loc ut in - return (T_contract, [t], unparse_type_annot meta.annot) - | Pair_t ((utl, l_field, l_var), (utr, r_field, r_var), meta) -> - let annot = unparse_type_annot meta.annot in - let utl = unparse_ty ~loc utl in - let tl = add_field_annot l_field l_var utl in - let utr = unparse_ty ~loc utr in - let tr = add_field_annot r_field r_var utr in - return (T_pair, [tl; tr], annot) - | Union_t ((utl, l_field), (utr, r_field), meta) -> - let annot = unparse_type_annot meta.annot in - let utl = unparse_ty ~loc utl in - let tl = add_field_annot l_field None utl in - let utr = unparse_ty ~loc utr in - let tr = add_field_annot r_field None utr in - return (T_or, [tl; tr], annot) - | Lambda_t (uta, utr, meta) -> - let ta = unparse_ty ~loc uta in - let tr = unparse_ty ~loc utr in - return (T_lambda, [ta; tr], unparse_type_annot meta.annot) - | Option_t (ut, meta) -> - let annot = unparse_type_annot meta.annot in - let ut = unparse_ty ~loc ut in - return (T_option, [ut], annot) - | List_t (ut, meta) -> - let t = unparse_ty ~loc ut in - return (T_list, [t], unparse_type_annot meta.annot) - | Ticket_t (ut, meta) -> - let t = unparse_comparable_ty ~loc ut in - return (T_ticket, [t], unparse_type_annot meta.annot) - | Set_t (ut, meta) -> - let t = unparse_comparable_ty ~loc ut in - return (T_set, [t], unparse_type_annot meta.annot) - | Map_t (uta, utr, meta) -> - let ta = unparse_comparable_ty ~loc uta in - let tr = unparse_ty ~loc utr in - return (T_map, [ta; tr], unparse_type_annot meta.annot) - | Big_map_t (uta, utr, meta) -> - let ta = unparse_comparable_ty ~loc uta in - let tr = unparse_ty ~loc utr in - return (T_big_map, [ta; tr], unparse_type_annot meta.annot) - | Sapling_transaction_t (memo_size, meta) -> - return - ( T_sapling_transaction, - [unparse_memo_size ~loc memo_size], - unparse_type_annot meta.annot ) - | Sapling_state_t (memo_size, meta) -> - return - ( T_sapling_state, - [unparse_memo_size ~loc memo_size], - unparse_type_annot meta.annot ) - | Chest_t meta -> return (T_chest, [], unparse_type_annot meta.annot) - | Chest_key_t meta -> - return (T_chest_key, [], unparse_type_annot meta.annot) - end - - let run_operation_service ctxt () - ({shell; protocol_data = Operation_data protocol_data}, chain_id) = - (* this code is a duplicate of Apply without signature check *) - let ret contents = - ( Operation_data protocol_data, - Apply_results.Operation_metadata {contents} ) - in - let operation : _ operation = {shell; protocol_data} in - let hash = Operation.hash {shell; protocol_data} in - let ctxt = Contract.init_origination_nonce ctxt hash in - let payload_producer = Signature.Public_key_hash.zero in - match protocol_data.contents with - | Single (Manager_operation _) as op -> - Apply.precheck_manager_contents_list ctxt op ~mempool_mode:true - >>=? fun (ctxt, prechecked_contents_list) -> - (* removed signature check here *) - Apply.apply_manager_contents_list - ctxt - Optimized - ~payload_producer - chain_id - prechecked_contents_list - >|= fun (_ctxt, result) -> ok @@ ret result - | Cons (Manager_operation _, _) as op -> - Apply.precheck_manager_contents_list ctxt op ~mempool_mode:true - >>=? fun (ctxt, prechecked_contents_list) -> - (* removed signature check here *) - Apply.apply_manager_contents_list - ctxt - Optimized - ~payload_producer - chain_id - prechecked_contents_list - >|= fun (_ctxt, result) -> ok @@ ret result - | _ -> - let predecessor_level = - match - Alpha_context.Level.pred ctxt (Alpha_context.Level.current ctxt) - with - | Some level -> level - | None -> assert false - in - Alpha_context.Round.get ctxt >>=? fun predecessor_round -> - Apply.apply_contents_list - ctxt - chain_id - (Partial_construction - { - predecessor_level; - predecessor_round; - grand_parent_round = Round.zero; - }) - Optimized - ~payload_producer - operation - operation.protocol_data.contents - >|=? fun (_ctxt, result) -> ret result - - (* - - The execution of an operation depends on the state of the - cache. In particular, gas consumption is usually impacted by - cache hits and misses. - - Unfortunately, the state of the cache is different between the - context at operation-creation time and the context when is - included in a block. - - Therefore, the simulation tries to predict the state of the - cache in a [time_in_blocks] assumed to be close to the inclusion - time of the operation. - - *) - let simulate_operation_service ctxt () (op, chain_id, time_in_blocks) = - let ctxt = Cache.Admin.future_cache_expectation ctxt ~time_in_blocks in - run_operation_service ctxt () (op, chain_id) - - let register () = - let originate_dummy_contract ctxt script balance = - let ctxt = Contract.init_origination_nonce ctxt Operation_hash.zero in - Lwt.return (Contract.fresh_contract_from_current_nonce ctxt) - >>=? fun (ctxt, dummy_contract) -> - Contract.raw_originate - ctxt - ~prepaid_bootstrap_storage:false - dummy_contract - ~script:(script, None) - >>=? fun ctxt -> - Token.transfer - ~origin:Simulation - ctxt - `Minted - (`Contract dummy_contract) - balance - >>=? fun (ctxt, _) -> return (ctxt, dummy_contract) - in - let script_entrypoint_type ctxt expr entrypoint = - let ctxt = Gas.set_unlimited ctxt in - let legacy = false in - let open Script_ir_translator in - parse_toplevel ctxt ~legacy expr - >>=? fun ({arg_type; root_name; _}, ctxt) -> - Lwt.return - ( ( parse_parameter_ty ctxt ~legacy arg_type - >>? fun (Ex_ty arg_type, _) -> - Script_ir_translator.find_entrypoint - ~root_name - arg_type - entrypoint ) - >>? fun (_f, Ex_ty ty) -> - unparse_ty ~loc:() ctxt ty >|? fun (ty_node, _) -> - Micheline.strip_locations ty_node ) - in - Registration.register0 - ~chunked:true - S.run_code - (fun - ctxt - () - ( ( code, - storage, - parameter, - amount, - balance, - chain_id, - source, - payer, - gas, - entrypoint ), - (unparsing_mode, now, level) ) - -> - let unparsing_mode = Option.value ~default:Readable unparsing_mode in - let storage = Script.lazy_expr storage in - let code = Script.lazy_expr code in - originate_dummy_contract ctxt {storage; code} balance - >>=? fun (ctxt, dummy_contract) -> - let (source, payer) = - match (source, payer) with - | (Some source, Some payer) -> (source, payer) - | (Some source, None) -> (source, source) - | (None, Some payer) -> (payer, payer) - | (None, None) -> (dummy_contract, dummy_contract) - in - let gas = - match gas with - | Some gas -> gas - | None -> Constants.hard_gas_limit_per_operation ctxt - in - let ctxt = Gas.set_limit ctxt gas in - let now = - match now with None -> Script_timestamp.now ctxt | Some t -> t - in - let level = - match level with - | None -> - (Level.current ctxt).level |> Raw_level.to_int32 - |> Script_int.of_int32 |> Script_int.abs - | Some z -> z - in - let step_constants = - let open Script_interpreter in - {source; payer; self = dummy_contract; amount; chain_id; now; level} - in - Script_interpreter.execute - ctxt - unparsing_mode - step_constants - ~cached_script:None - ~script:{storage; code} - ~entrypoint - ~parameter - ~internal:true - >|=? fun ( { - Script_interpreter.storage; - operations; - lazy_storage_diff; - _; - }, - _ ) -> (storage, operations, lazy_storage_diff)) ; - Registration.register0 - ~chunked:true - S.trace_code - (fun - ctxt - () - ( ( code, - storage, - parameter, - amount, - balance, - chain_id, - source, - payer, - gas, - entrypoint ), - (unparsing_mode, now, level) ) - -> - let unparsing_mode = Option.value ~default:Readable unparsing_mode in - let storage = Script.lazy_expr storage in - let code = Script.lazy_expr code in - originate_dummy_contract ctxt {storage; code} balance - >>=? fun (ctxt, dummy_contract) -> - let (source, payer) = - match (source, payer) with - | (Some source, Some payer) -> (source, payer) - | (Some source, None) -> (source, source) - | (None, Some payer) -> (payer, payer) - | (None, None) -> (dummy_contract, dummy_contract) - in - let gas = - match gas with - | Some gas -> gas - | None -> Constants.hard_gas_limit_per_operation ctxt - in - let ctxt = Gas.set_limit ctxt gas in - let now = - match now with None -> Script_timestamp.now ctxt | Some t -> t - in - let level = - match level with - | None -> - (Level.current ctxt).level |> Raw_level.to_int32 - |> Script_int.of_int32 |> Script_int.abs - | Some z -> z - in - let step_constants = - let open Script_interpreter in - {source; payer; self = dummy_contract; amount; chain_id; now; level} - in - let module Unparsing_mode = struct - let unparsing_mode = unparsing_mode - end in - let module Interp = Traced_interpreter (Unparsing_mode) in - Interp.execute - ctxt - step_constants - ~script:{storage; code} - ~entrypoint - ~parameter - >|=? fun ( { - Script_interpreter.storage; - operations; - lazy_storage_diff; - _; - }, - trace ) -> (storage, operations, trace, lazy_storage_diff)) ; - Registration.register0 - ~chunked:true - S.run_view - (fun - ctxt - () - ( contract, - entrypoint, - input, - chain_id, - source, - payer, - gas, - unparsing_mode, - now, - level ) - -> - Contract.get_script ctxt contract >>=? fun (ctxt, script_opt) -> - Option.fold - ~some:ok - ~none:(Error_monad.error View_helpers.Viewed_contract_has_no_script) - script_opt - >>?= fun script -> - Script_repr.(force_decode script.code) >>?= fun decoded_script -> - script_entrypoint_type ctxt decoded_script entrypoint - >>=? fun view_ty -> - View_helpers.extract_view_output_type entrypoint view_ty - >>?= fun ty -> - Error_monad.trace View_helpers.View_callback_origination_failed - @@ originate_dummy_contract - ctxt - (View_helpers.make_viewer_script ty) - Tez.zero - >>=? fun (ctxt, viewer_contract) -> - let (source, payer) = - match (source, payer) with - | (Some source, Some payer) -> (source, payer) - | (Some source, None) -> (source, source) - | (None, Some payer) -> (payer, payer) - | (None, None) -> (contract, contract) - in - let gas = - Option.value - ~default:(Constants.hard_gas_limit_per_operation ctxt) - gas - in - let ctxt = Gas.set_limit ctxt gas in - let now = - match now with None -> Script_timestamp.now ctxt | Some t -> t - in - let level = - match level with - | None -> - (Level.current ctxt).level |> Raw_level.to_int32 - |> Script_int.of_int32 |> Script_int.abs - | Some z -> z - in - let step_constants = - let open Script_interpreter in - { - source; - payer; - self = contract; - amount = Tez.zero; - chain_id; - now; - level; - } - in - let parameter = - View_helpers.make_view_parameter - (Micheline.root input) - viewer_contract - in - Script_interpreter.execute - ctxt - unparsing_mode - step_constants - ~script - ~cached_script:None - ~entrypoint - ~parameter - ~internal:true - >>=? fun ({Script_interpreter.operations; _}, (_, _)) -> - View_helpers.extract_parameter_from_operations - entrypoint - operations - viewer_contract - >>?= fun parameter -> Lwt.return (Script_repr.force_decode parameter)) ; - Registration.register0 - ~chunked:false - S.typecheck_code - (fun ctxt () (expr, maybe_gas, legacy, show_types) -> - let legacy = Option.value ~default:false legacy in - let show_types = Option.value ~default:true show_types in - let ctxt = - match maybe_gas with - | None -> Gas.set_unlimited ctxt - | Some gas -> Gas.set_limit ctxt gas - in - Script_ir_translator.typecheck_code ~legacy ~show_types ctxt expr - >|=? fun (res, ctxt) -> (res, Gas.level ctxt)) ; - Registration.register0 - ~chunked:false - S.script_size - (fun ctxt () (expr, storage, maybe_gas, legacy) -> - let legacy = Option.value ~default:false legacy in - let ctxt = - match maybe_gas with - | None -> Gas.set_unlimited ctxt - | Some gas -> Gas.set_limit ctxt gas - in - let code = Script.lazy_expr expr in - Script_ir_translator.parse_code ~legacy ctxt ~code - >>=? fun ( Ex_code - { - code; - arg_type; - storage_type; - views; - root_name; - code_size; - }, - ctxt ) -> - Script_ir_translator.parse_data - ~legacy - ~allow_forged:true - ctxt - storage_type - (Micheline.root storage) - >>=? fun (storage, _) -> - let script = - Script_ir_translator.Ex_script - { - code; - arg_type; - storage_type; - views; - root_name; - code_size; - storage; - } - in - let (size, cost) = Script_ir_translator.script_size script in - Gas.consume ctxt cost >>?= fun _ctxt -> return @@ size) ; - - Registration.register0 - ~chunked:false - S.typecheck_data - (fun ctxt () (data, ty, maybe_gas, legacy) -> - let legacy = Option.value ~default:false legacy in - let ctxt = - match maybe_gas with - | None -> Gas.set_unlimited ctxt - | Some gas -> Gas.set_limit ctxt gas - in - typecheck_data ~legacy ctxt (data, ty) >|=? fun ctxt -> Gas.level ctxt) ; - Registration.register0 - ~chunked:true - S.pack_data - (fun ctxt () (expr, typ, maybe_gas) -> - let open Script_ir_translator in - let ctxt = - match maybe_gas with - | None -> Gas.set_unlimited ctxt - | Some gas -> Gas.set_limit ctxt gas - in - parse_packable_ty ctxt ~legacy:true (Micheline.root typ) - >>?= fun (Ex_ty typ, ctxt) -> - parse_data - ctxt - ~legacy:true - ~allow_forged:true - typ - (Micheline.root expr) - >>=? fun (data, ctxt) -> - Script_ir_translator.pack_data ctxt typ data >|=? fun (bytes, ctxt) -> - (bytes, Gas.level ctxt)) ; - Registration.register0 - ~chunked:true - S.normalize_data - (fun ctxt () (expr, typ, unparsing_mode, legacy) -> - let open Script_ir_translator in - let legacy = Option.value ~default:false legacy in - let ctxt = Gas.set_unlimited ctxt in - Script_ir_translator.parse_any_ty ctxt ~legacy (Micheline.root typ) - >>?= fun (Ex_ty typ, ctxt) -> - parse_data ctxt ~legacy ~allow_forged:true typ (Micheline.root expr) - >>=? fun (data, ctxt) -> - Script_ir_translator.unparse_data ctxt unparsing_mode typ data - >|=? fun (normalized, _ctxt) -> Micheline.strip_locations normalized) ; - Registration.register0 - ~chunked:true - S.normalize_script - (fun ctxt () (script, unparsing_mode) -> - let ctxt = Gas.set_unlimited ctxt in - Script_ir_translator.unparse_code - ctxt - unparsing_mode - (Micheline.root script) - >|=? fun (normalized, _ctxt) -> Micheline.strip_locations normalized) ; - Registration.register0 ~chunked:true S.normalize_type (fun ctxt () typ -> - let open Script_ir_translator in - let ctxt = Gas.set_unlimited ctxt in - (* Unfortunately, Script_ir_translator.parse_any_ty is not exported *) - Script_ir_translator.parse_ty - ctxt - ~legacy:true - ~allow_lazy_storage:true - ~allow_operation:true - ~allow_contract:true - ~allow_ticket:true - (Micheline.root typ) - >>?= fun (Ex_ty typ, _ctxt) -> - let normalized = Unparse_types.unparse_ty ~loc:() typ in - return @@ Micheline.strip_locations normalized) ; - Registration.register0 ~chunked:true S.run_operation run_operation_service ; - Registration.register0 - ~chunked:true - S.simulate_operation - simulate_operation_service ; - Registration.register0 - ~chunked:true - S.entrypoint_type - (fun ctxt () (expr, entrypoint) -> - script_entrypoint_type ctxt expr entrypoint) ; - Registration.register0 - ~chunked:true - S.list_entrypoints - (fun ctxt () expr -> - let ctxt = Gas.set_unlimited ctxt in - let legacy = false in - let open Script_ir_translator in - parse_toplevel ~legacy ctxt expr - >>=? fun ({arg_type; root_name; _}, ctxt) -> - Lwt.return - ( parse_parameter_ty ctxt ~legacy arg_type - >>? fun (Ex_ty arg_type, _) -> - Script_ir_translator.list_entrypoints ~root_name arg_type ctxt - >|? fun (unreachable_entrypoint, map) -> - ( unreachable_entrypoint, - Entrypoints_map.fold - (fun entry (_, ty) acc -> - (entry, Micheline.strip_locations ty) :: acc) - map - [] ) )) - - let run_code ?unparsing_mode ?gas ?(entrypoint = "default") ~script ~storage - ~input ~amount ~balance ~chain_id ~source ~payer ~now ~level ctxt block - = - RPC_context.make_call0 - S.run_code - ctxt - block - () - ( ( script, - storage, - input, - amount, - balance, - chain_id, - source, - payer, - gas, - entrypoint ), - (unparsing_mode, now, level) ) - - let trace_code ?unparsing_mode ?gas ?(entrypoint = "default") ~script - ~storage ~input ~amount ~balance ~chain_id ~source ~payer ~now ~level - ctxt block = - RPC_context.make_call0 - S.trace_code - ctxt - block - () - ( ( script, - storage, - input, - amount, - balance, - chain_id, - source, - payer, - gas, - entrypoint ), - (unparsing_mode, now, level) ) - - let run_view ?gas ~contract ~entrypoint ~input ~chain_id ~now ~level ?source - ?payer ~unparsing_mode ctxt block = - RPC_context.make_call0 - S.run_view - ctxt - block - () - ( contract, - entrypoint, - input, - chain_id, - source, - payer, - gas, - unparsing_mode, - now, - level ) - - let typecheck_code ?gas ?legacy ~script ?show_types ctxt block = - RPC_context.make_call0 - S.typecheck_code - ctxt - block - () - (script, gas, legacy, show_types) - - let script_size ?gas ?legacy ~script ~storage ctxt block = - RPC_context.make_call0 - S.script_size - ctxt - block - () - (script, storage, gas, legacy) - - let typecheck_data ?gas ?legacy ~data ~ty ctxt block = - RPC_context.make_call0 - S.typecheck_data - ctxt - block - () - (data, ty, gas, legacy) - - let pack_data ?gas ~data ~ty ctxt block = - RPC_context.make_call0 S.pack_data ctxt block () (data, ty, gas) - - let normalize_data ?legacy ~data ~ty ~unparsing_mode ctxt block = - RPC_context.make_call0 - S.normalize_data - ctxt - block - () - (data, ty, unparsing_mode, legacy) - - let normalize_script ~script ~unparsing_mode ctxt block = - RPC_context.make_call0 - S.normalize_script - ctxt - block - () - (script, unparsing_mode) - - let normalize_type ~ty ctxt block = - RPC_context.make_call0 S.normalize_type ctxt block () ty - - let run_operation ~op ~chain_id ctxt block = - RPC_context.make_call0 S.run_operation ctxt block () (op, chain_id) - - let simulate_operation ~op ~chain_id ~latency ctxt block = - RPC_context.make_call0 - S.simulate_operation - ctxt - block - () - (op, chain_id, latency) - - let entrypoint_type ~script ~entrypoint ctxt block = - RPC_context.make_call0 S.entrypoint_type ctxt block () (script, entrypoint) - - let list_entrypoints ctxt block ~script = - RPC_context.make_call0 S.list_entrypoints ctxt block () script - end - - module Contract = struct - module S = struct - let path = - (RPC_path.(open_root / "context" / "contracts") - : RPC_context.t RPC_path.context) - - let get_storage_normalized = - let open Data_encoding in - RPC_service.post_service - ~description: - "Access the data of the contract and normalize it using the \ - requested unparsing mode." - ~input:(obj1 (req "unparsing_mode" unparsing_mode_encoding)) - ~query:RPC_query.empty - ~output:(option Script.expr_encoding) - RPC_path.(path /: Contract.rpc_arg / "storage" / "normalized") - - let get_script_normalized = - let open Data_encoding in - RPC_service.post_service - ~description: - "Access the script of the contract and normalize it using the \ - requested unparsing mode." - ~input:(obj1 (req "unparsing_mode" unparsing_mode_encoding)) - ~query:RPC_query.empty - ~output:(option Script.encoding) - RPC_path.(path /: Contract.rpc_arg / "script" / "normalized") - end - - let register () = - (* Patched RPC: get_storage *) - Registration.register1 - ~chunked:true - S.get_storage_normalized - (fun ctxt contract () unparsing_mode -> - Contract.get_script ctxt contract >>=? fun (ctxt, script) -> - match script with - | None -> return_none - | Some script -> - let ctxt = Gas.set_unlimited ctxt in - let open Script_ir_translator in - parse_script - ctxt - ~legacy:true - ~allow_forged_in_storage:true - script - >>=? fun (Ex_script script, ctxt) -> - unparse_script ctxt unparsing_mode script - >>=? fun (script, ctxt) -> - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - script.storage - >>?= fun (storage, _ctxt) -> return_some storage) ; - (* Patched RPC: get_script *) - Registration.register1 - ~chunked:true - S.get_script_normalized - (fun ctxt contract () unparsing_mode -> - Contract.get_script ctxt contract >>=? fun (ctxt, script) -> - match script with - | None -> return_none - | Some script -> - let ctxt = Gas.set_unlimited ctxt in - let open Script_ir_translator in - parse_script - ctxt - ~legacy:true - ~allow_forged_in_storage:true - script - >>=? fun (Ex_script script, ctxt) -> - unparse_script ctxt unparsing_mode script - >>=? fun (script, _ctxt) -> return_some script) - - let get_storage_normalized ctxt block ~contract ~unparsing_mode = - RPC_context.make_call1 - S.get_storage_normalized - ctxt - block - contract - () - unparsing_mode - - let get_script_normalized ctxt block ~contract ~unparsing_mode = - RPC_context.make_call1 - S.get_script_normalized - ctxt - block - contract - () - unparsing_mode - end - - module Big_map = struct - module S = struct - let path = - (RPC_path.(open_root / "context" / "big_maps") - : RPC_context.t RPC_path.context) - - let big_map_get_normalized = - let open Data_encoding in - RPC_service.post_service - ~description: - "Access the value associated with a key in a big map, normalize \ - the output using the requested unparsing mode." - ~query:RPC_query.empty - ~input:(obj1 (req "unparsing_mode" unparsing_mode_encoding)) - ~output:Script.expr_encoding - RPC_path.( - path /: Big_map.Id.rpc_arg /: Script_expr_hash.rpc_arg - / "normalized") - end - - let register () = - Registration.register2 - ~chunked:true - S.big_map_get_normalized - (fun ctxt id key () unparsing_mode -> - let open Script_ir_translator in - let ctxt = Gas.set_unlimited ctxt in - Big_map.exists ctxt id >>=? fun (ctxt, types) -> - match types with - | None -> raise Not_found - | Some (_, value_type) -> ( - parse_big_map_value_ty - ctxt - ~legacy:true - (Micheline.root value_type) - >>?= fun (Ex_ty value_type, ctxt) -> - Big_map.get_opt ctxt id key >>=? fun (_ctxt, value) -> - match value with - | None -> raise Not_found - | Some value -> - parse_data - ctxt - ~legacy:true - ~allow_forged:true - value_type - (Micheline.root value) - >>=? fun (value, ctxt) -> - unparse_data ctxt unparsing_mode value_type value - >|=? fun (value, _ctxt) -> Micheline.strip_locations value)) - - let big_map_get_normalized ctxt block id key ~unparsing_mode = - RPC_context.make_call2 - S.big_map_get_normalized - ctxt - block - id - key - () - unparsing_mode - end - - module Forge = struct - module S = struct - open Data_encoding - - let path = RPC_path.(path / "forge") - - let operations = - RPC_service.post_service - ~description:"Forge an operation" - ~query:RPC_query.empty - ~input:Operation.unsigned_encoding - ~output:bytes - RPC_path.(path / "operations") - - let empty_proof_of_work_nonce = - Bytes.make Constants_repr.proof_of_work_nonce_size '\000' - - let protocol_data = - RPC_service.post_service - ~description:"Forge the protocol-specific part of a block header" - ~query:RPC_query.empty - ~input: - (obj5 - (req "payload_hash" Block_payload_hash.encoding) - (req "payload_round" Round.encoding) - (opt "nonce_hash" Nonce_hash.encoding) - (dft - "proof_of_work_nonce" - (Fixed.bytes Alpha_context.Constants.proof_of_work_nonce_size) - empty_proof_of_work_nonce) - (dft "liquidity_baking_escape_vote" bool false)) - ~output:(obj1 (req "protocol_data" bytes)) - RPC_path.(path / "protocol_data") - end - - let register () = - Registration.register0_noctxt - ~chunked:true - S.operations - (fun () (shell, proto) -> - return - (Data_encoding.Binary.to_bytes_exn - Operation.unsigned_encoding - (shell, proto))) ; - Registration.register0_noctxt - ~chunked:true - S.protocol_data - (fun - () - ( payload_hash, - payload_round, - seed_nonce_hash, - proof_of_work_nonce, - liquidity_baking_escape_vote ) - -> - return - (Data_encoding.Binary.to_bytes_exn - Block_header.contents_encoding - { - payload_hash; - payload_round; - seed_nonce_hash; - proof_of_work_nonce; - liquidity_baking_escape_vote; - })) - - module Manager = struct - let[@coq_axiom_with_reason "cast on e"] operations ctxt block ~branch - ~source ?sourcePubKey ~counter ~fee ~gas_limit ~storage_limit - operations = - Contract_services.manager_key ctxt block source >>= function - | Error _ as e -> Lwt.return e - | Ok revealed -> - let ops = - List.map - (fun (Manager operation) -> - Contents - (Manager_operation - { - source; - counter; - operation; - fee; - gas_limit; - storage_limit; - })) - operations - in - let ops = - match (sourcePubKey, revealed) with - | (None, _) | (_, Some _) -> ops - | (Some pk, None) -> - let operation = Reveal pk in - Contents - (Manager_operation - { - source; - counter; - operation; - fee; - gas_limit; - storage_limit; - }) - :: ops - in - Environment.wrap_tzresult @@ Operation.of_list ops >>?= fun ops -> - RPC_context.make_call0 S.operations ctxt block () ({branch}, ops) - - let reveal ctxt block ~branch ~source ~sourcePubKey ~counter ~fee () = - operations - ctxt - block - ~branch - ~source - ~sourcePubKey - ~counter - ~fee - ~gas_limit:Gas.Arith.zero - ~storage_limit:Z.zero - [] - - let transaction ctxt block ~branch ~source ?sourcePubKey ~counter ~amount - ~destination ?(entrypoint = "default") ?parameters ~gas_limit - ~storage_limit ~fee () = - let parameters = - Option.fold - ~some:Script.lazy_expr - ~none:Script.unit_parameter - parameters - in - operations - ctxt - block - ~branch - ~source - ?sourcePubKey - ~counter - ~fee - ~gas_limit - ~storage_limit - [Manager (Transaction {amount; parameters; destination; entrypoint})] - - let origination ctxt block ~branch ~source ?sourcePubKey ~counter ~balance - ?delegatePubKey ~script ~gas_limit ~storage_limit ~fee () = - operations - ctxt - block - ~branch - ~source - ?sourcePubKey - ~counter - ~fee - ~gas_limit - ~storage_limit - [ - Manager - (Origination - { - delegate = delegatePubKey; - script; - credit = balance; - preorigination = None; - }); - ] - - let delegation ctxt block ~branch ~source ?sourcePubKey ~counter ~fee - delegate = - operations - ctxt - block - ~branch - ~source - ?sourcePubKey - ~counter - ~fee - ~gas_limit:Gas.Arith.zero - ~storage_limit:Z.zero - [Manager (Delegation delegate)] - end - - let operation ctxt block ~branch operation = - RPC_context.make_call0 - S.operations - ctxt - block - () - ({branch}, Contents_list (Single operation)) - - let endorsement ctxt b ~branch ~consensus_content () = - operation ctxt b ~branch (Endorsement consensus_content) - - let proposals ctxt b ~branch ~source ~period ~proposals () = - operation ctxt b ~branch (Proposals {source; period; proposals}) - - let ballot ctxt b ~branch ~source ~period ~proposal ~ballot () = - operation ctxt b ~branch (Ballot {source; period; proposal; ballot}) - - let failing_noop ctxt b ~branch ~message () = - operation ctxt b ~branch (Failing_noop message) - - let seed_nonce_revelation ctxt block ~branch ~level ~nonce () = - operation ctxt block ~branch (Seed_nonce_revelation {level; nonce}) - - let double_baking_evidence ctxt block ~branch ~bh1 ~bh2 () = - operation ctxt block ~branch (Double_baking_evidence {bh1; bh2}) - - let double_endorsement_evidence ctxt block ~branch ~op1 ~op2 () = - operation ctxt block ~branch (Double_endorsement_evidence {op1; op2}) - - let double_preendorsement_evidence ctxt block ~branch ~op1 ~op2 () = - operation ctxt block ~branch (Double_preendorsement_evidence {op1; op2}) - - let empty_proof_of_work_nonce = - Bytes.make Constants_repr.proof_of_work_nonce_size '\000' - - let protocol_data ctxt block ?(payload_hash = Block_payload_hash.zero) - ?(payload_round = Round.zero) ?seed_nonce_hash - ?(proof_of_work_nonce = empty_proof_of_work_nonce) - ~liquidity_baking_escape_vote () = - RPC_context.make_call0 - S.protocol_data - ctxt - block - () - ( payload_hash, - payload_round, - seed_nonce_hash, - proof_of_work_nonce, - liquidity_baking_escape_vote ) - end - - module Parse = struct - module S = struct - open Data_encoding - - let path = RPC_path.(path / "parse") - - let operations = - RPC_service.post_service - ~description:"Parse operations" - ~query:RPC_query.empty - ~input: - (obj2 - (req "operations" (list (dynamic_size Operation.raw_encoding))) - (opt "check_signature" bool)) - ~output:(list (dynamic_size Operation.encoding)) - RPC_path.(path / "operations") - - let block = - RPC_service.post_service - ~description:"Parse a block" - ~query:RPC_query.empty - ~input:Block_header.raw_encoding - ~output:Block_header.protocol_data_encoding - RPC_path.(path / "block") - end - - let parse_protocol_data protocol_data = - match - Data_encoding.Binary.of_bytes_opt - Block_header.protocol_data_encoding - protocol_data - with - | None -> Stdlib.failwith "Cant_parse_protocol_data" - | Some protocol_data -> protocol_data - - let register () = - Registration.register0 - ~chunked:true - S.operations - (fun _ctxt () (operations, check) -> - List.map_es - (fun raw -> - parse_operation raw >>?= fun op -> - (match check with - | Some true -> return_unit (* FIXME *) - (* I.check_signature ctxt *) - (* op.protocol_data.signature op.shell op.protocol_data.contents *) - | Some false | None -> return_unit) - >|=? fun () -> op) - operations) ; - Registration.register0_noctxt ~chunked:false S.block (fun () raw_block -> - return @@ parse_protocol_data raw_block.protocol_data) - - let operations ctxt block ?check operations = - RPC_context.make_call0 S.operations ctxt block () (operations, check) - - let block ctxt block shell protocol_data = - RPC_context.make_call0 - S.block - ctxt - block - () - ({shell; protocol_data} : Block_header.raw) - end - - (* Compute the estimated starting time of a [round] at a future - [level], given the head's level [current_level], timestamp - [current_timestamp], and round [current_round]. Assumes blocks at - intermediate levels are produced at round 0. *) - let estimated_time round_durations ~current_level ~current_round - ~current_timestamp ~level ~round = - if Level.(level <= current_level) then Result.return_none - else - Round.of_int round >>? fun round -> - Round.timestamp_of_round - round_durations - ~round - ~predecessor_timestamp:current_timestamp - ~predecessor_round:current_round - >>? fun round_start_at_next_level -> - let step = Round.round_duration round_durations Round.zero in - let diff = Level.diff level current_level in - Period.mult (Int32.pred diff) step >>? fun delay -> - Timestamp.(round_start_at_next_level +? delay) >>? fun timestamp -> - Result.return_some timestamp - - let requested_levels ~default_level ctxt cycles levels = - match (levels, cycles) with - | ([], []) -> [default_level] - | (levels, cycles) -> - (* explicitly fail when requested levels or cycle are in the past... - or too far in the future... - TODO-TB: this old comment (from version Alpha) conflicts with - the specification of the RPCs that use this code. - *) - List.sort_uniq - Level.compare - (List.concat - (List.map (Level.from_raw ctxt) levels - :: List.map (Level.levels_in_cycle ctxt) cycles)) - - module Baking_rights = struct - type t = { - level : Raw_level.t; - delegate : Signature.Public_key_hash.t; - round : int; - timestamp : Timestamp.t option; - } - - let encoding = - let open Data_encoding in - conv - (fun {level; delegate; round; timestamp} -> - (level, delegate, round, timestamp)) - (fun (level, delegate, round, timestamp) -> - {level; delegate; round; timestamp}) - (obj4 - (req "level" Raw_level.encoding) - (req "delegate" Signature.Public_key_hash.encoding) - (req "round" uint16) - (opt "estimated_time" Timestamp.encoding)) - - let default_max_round = 64 - - module S = struct - open Data_encoding - - let path = RPC_path.(open_root / "helpers" / "baking_rights") - - type baking_rights_query = { - levels : Raw_level.t list; - cycle : Cycle.t option; - delegates : Signature.Public_key_hash.t list; - max_round : int option; - all : bool; - } - - let baking_rights_query = - let open RPC_query in - query (fun levels cycle delegates max_round all -> - {levels; cycle; delegates; max_round; all}) - |+ multi_field "level" Raw_level.rpc_arg (fun t -> t.levels) - |+ opt_field "cycle" Cycle.rpc_arg (fun t -> t.cycle) - |+ multi_field "delegate" Signature.Public_key_hash.rpc_arg (fun t -> - t.delegates) - |+ opt_field "max_round" RPC_arg.uint (fun t -> t.max_round) - |+ flag "all" (fun t -> t.all) - |> seal - - let baking_rights = - RPC_service.get_service - ~description: - (Format.sprintf - "Retrieves the list of delegates allowed to bake a block.\n\ - By default, it gives the best baking opportunities (in terms \ - of rounds) for bakers that have at least one opportunity below \ - the %dth round for the next block.\n\ - Parameters `level` and `cycle` can be used to specify the \ - (valid) level(s) in the past or future at which the baking \ - rights have to be returned.\n\ - Parameter `delegate` can be used to restrict the results to \ - the given delegates. If parameter `all` is set, all the baking \ - opportunities for each baker at each level are returned, \ - instead of just the first one.\n\ - Returns the list of baking opportunities up to round %d. Also \ - returns the minimal timestamps that correspond to these \ - opportunities. The timestamps are omitted for levels in the \ - past, and are only estimates for levels higher that the next \ - block's, based on the hypothesis that all predecessor blocks \ - were baked at the first round." - default_max_round - default_max_round) - ~query:baking_rights_query - ~output:(list encoding) - path - end - - let baking_rights_at_level ctxt max_round level = - Baking.baking_rights ctxt level >>=? fun delegates -> - Round.get ctxt >>=? fun current_round -> - let current_level = Level.current ctxt in - let current_timestamp = Timestamp.current ctxt in - let round_durations = Alpha_context.Constants.round_durations ctxt in - let rec loop l acc round = - if Compare.Int.(round > max_round) then return (List.rev acc) - else - let (Misc.LCons (pk, next)) = l in - let delegate = Signature.Public_key.hash pk in - estimated_time - round_durations - ~current_level - ~current_round - ~current_timestamp - ~level - ~round - >>?= fun timestamp -> - let acc = {level = level.level; delegate; round; timestamp} :: acc in - next () >>=? fun l -> loop l acc (round + 1) - in - loop delegates [] 0 - - let remove_duplicated_delegates rights = - List.rev @@ fst - @@ List.fold_left - (fun (acc, previous) r -> - if - Signature.Public_key_hash.Set.exists - (Signature.Public_key_hash.equal r.delegate) - previous - then (acc, previous) - else - (r :: acc, Signature.Public_key_hash.Set.add r.delegate previous)) - ([], Signature.Public_key_hash.Set.empty) - rights - - let register () = - Registration.register0 ~chunked:true S.baking_rights (fun ctxt q () -> - let cycles = - match q.cycle with None -> [] | Some cycle -> [cycle] - in - let levels = - requested_levels - ~default_level:(Level.succ ctxt (Level.current ctxt)) - ctxt - cycles - q.levels - in - let max_round = - match q.max_round with - | None -> default_max_round - | Some max_round -> - Compare.Int.min - max_round - (Constants.consensus_committee_size ctxt) - in - List.map_es (baking_rights_at_level ctxt max_round) levels - >|=? fun rights -> - let rights = - if q.all then rights - else List.map remove_duplicated_delegates rights - in - let rights = List.concat rights in - match q.delegates with - | [] -> rights - | _ :: _ as delegates -> - let is_requested p = - List.exists - (Signature.Public_key_hash.equal p.delegate) - delegates - in - List.filter is_requested rights) - - let get ctxt ?(levels = []) ?cycle ?(delegates = []) ?(all = false) - ?max_round block = - RPC_context.make_call0 - S.baking_rights - ctxt - block - {levels; cycle; delegates; max_round; all} - () - end - - module Endorsing_rights = struct - type delegate_rights = { - delegate : Signature.Public_key_hash.t; - first_slot : Slot.t; - endorsing_power : int; - } - - type t = { - level : Raw_level.t; - delegates_rights : delegate_rights list; - estimated_time : Time.t option; - } - - let delegate_rights_encoding = - let open Data_encoding in - conv - (fun {delegate; first_slot; endorsing_power} -> - (delegate, first_slot, endorsing_power)) - (fun (delegate, first_slot, endorsing_power) -> - {delegate; first_slot; endorsing_power}) - (obj3 - (req "delegate" Signature.Public_key_hash.encoding) - (req "first_slot" Slot.encoding) - (req "endorsing_power" uint16)) - - let encoding = - let open Data_encoding in - conv - (fun {level; delegates_rights; estimated_time} -> - (level, delegates_rights, estimated_time)) - (fun (level, delegates_rights, estimated_time) -> - {level; delegates_rights; estimated_time}) - (obj3 - (req "level" Raw_level.encoding) - (req "delegates" (list delegate_rights_encoding)) - (opt "estimated_time" Timestamp.encoding)) - - module S = struct - open Data_encoding - - let path = RPC_path.(path / "endorsing_rights") - - type endorsing_rights_query = { - levels : Raw_level.t list; - cycle : Cycle.t option; - delegates : Signature.Public_key_hash.t list; - } - - let endorsing_rights_query = - let open RPC_query in - query (fun levels cycle delegates -> {levels; cycle; delegates}) - |+ multi_field "level" Raw_level.rpc_arg (fun t -> t.levels) - |+ opt_field "cycle" Cycle.rpc_arg (fun t -> t.cycle) - |+ multi_field "delegate" Signature.Public_key_hash.rpc_arg (fun t -> - t.delegates) - |> seal - - let endorsing_rights = - RPC_service.get_service - ~description: - "Retrieves the delegates allowed to endorse a block.\n\ - By default, it gives the endorsing power for delegates that have \ - at least one endorsing slot for the next block.\n\ - Parameters `level` and `cycle` can be used to specify the (valid) \ - level(s) in the past or future at which the endorsing rights have \ - to be returned. Parameter `delegate` can be used to restrict the \ - results to the given delegates.\n\ - Returns the smallest endorsing slots and the endorsing power. \ - Also returns the minimal timestamp that corresponds to endorsing \ - at the given level. The timestamps are omitted for levels in the \ - past, and are only estimates for levels higher that the next \ - block's, based on the hypothesis that all predecessor blocks were \ - baked at the first round." - ~query:endorsing_rights_query - ~output:(list encoding) - path - end - - let endorsing_rights_at_level ctxt level = - Baking.endorsing_rights_by_first_slot ctxt level - >>=? fun (ctxt, rights) -> - Round.get ctxt >>=? fun current_round -> - let current_level = Level.current ctxt in - let current_timestamp = Timestamp.current ctxt in - let round_durations = Alpha_context.Constants.round_durations ctxt in - estimated_time - round_durations - ~current_level - ~current_round - ~current_timestamp - ~level - ~round:0 - >>?= fun estimated_time -> - let rights = - Slot.Map.fold - (fun first_slot (_pk, delegate, endorsing_power) acc -> - {delegate; first_slot; endorsing_power} :: acc) - rights - [] - in - return {level = level.level; delegates_rights = rights; estimated_time} - - let register () = - Registration.register0 ~chunked:true S.endorsing_rights (fun ctxt q () -> - let cycles = - match q.cycle with None -> [] | Some cycle -> [cycle] - in - let levels = - requested_levels - ~default_level:(Level.current ctxt) - ctxt - cycles - q.levels - in - List.map_es (endorsing_rights_at_level ctxt) levels - >|=? fun rights_per_level -> - match q.delegates with - | [] -> rights_per_level - | _ :: _ as delegates -> - List.filter_map - (fun rights_at_level -> - let is_requested p = - List.exists - (Signature.Public_key_hash.equal p.delegate) - delegates - in - match - List.filter is_requested rights_at_level.delegates_rights - with - | [] -> None - | delegates_rights -> - Some {rights_at_level with delegates_rights}) - rights_per_level) - - let get ctxt ?(levels = []) ?cycle ?(delegates = []) block = - RPC_context.make_call0 - S.endorsing_rights - ctxt - block - {levels; cycle; delegates} - () - end - - module Validators = struct - type t = { - level : Raw_level.t; - delegate : Signature.Public_key_hash.t; - slots : Slot.t list; - } - - let encoding = - let open Data_encoding in - conv - (fun {level; delegate; slots} -> (level, delegate, slots)) - (fun (level, delegate, slots) -> {level; delegate; slots}) - (obj3 - (req "level" Raw_level.encoding) - (req "delegate" Signature.Public_key_hash.encoding) - (req "slots" (list Slot.encoding))) - - module S = struct - open Data_encoding - - let path = RPC_path.(path / "validators") - - type validators_query = { - levels : Raw_level.t list; - delegates : Signature.Public_key_hash.t list; - } - - let validators_query = - let open RPC_query in - query (fun levels delegates -> {levels; delegates}) - |+ multi_field "level" Raw_level.rpc_arg (fun t -> t.levels) - |+ multi_field "delegate" Signature.Public_key_hash.rpc_arg (fun t -> - t.delegates) - |> seal - - let validators = - RPC_service.get_service - ~description: - "Retrieves the delegates allowed to endorse a block.\n\ - By default, it gives the endorsing slots for delegates that have \ - at least one in the next block.\n\ - Parameter `level` can be used to specify the (valid) level(s) in \ - the past or future at which the endorsement rights have to be \ - returned. Parameter `delegate` can be used to restrict the \ - results to the given delegates.\n\ - Returns the list of endorsing slots. Also returns the minimal \ - timestamps that correspond to these slots. The timestamps are \ - omitted for levels in the past, and are only estimates for levels \ - later that the next block, based on the hypothesis that all \ - predecessor blocks were baked at the first round." - ~query:validators_query - ~output:(list encoding) - path - end - - let endorsing_slots_at_level ctxt level = - Baking.endorsing_rights ctxt level >|=? fun (_, rights) -> - Signature.Public_key_hash.Map.fold - (fun delegate slots acc -> - {level = level.level; delegate; slots} :: acc) - rights - [] - - let register () = - Registration.register0 ~chunked:true S.validators (fun ctxt q () -> - let levels = - requested_levels - ~default_level:(Level.current ctxt) - ctxt - [] - q.levels - in - List.map_es (endorsing_slots_at_level ctxt) levels >|=? fun rights -> - let rights = List.concat rights in - match q.delegates with - | [] -> rights - | _ :: _ as delegates -> - let is_requested p = - List.exists - (Signature.Public_key_hash.equal p.delegate) - delegates - in - List.filter is_requested rights) - - let get ctxt ?(levels = []) ?(delegates = []) block = - RPC_context.make_call0 S.validators ctxt block {levels; delegates} () - end - - module S = struct - open Data_encoding - - type level_query = {offset : int32} - - let level_query : level_query RPC_query.t = - let open RPC_query in - query (fun offset -> {offset}) - |+ field "offset" RPC_arg.int32 0l (fun t -> t.offset) - |> seal - - let current_level = - RPC_service.get_service - ~description: - "Returns the level of the interrogated block, or the one of a block \ - located `offset` blocks after it in the chain. For instance, the \ - next block if `offset` is 1. The offset cannot be negative." - ~query:level_query - ~output:Level.encoding - RPC_path.(path / "current_level") - - let levels_in_current_cycle = - RPC_service.get_service - ~description:"Levels of a cycle" - ~query:level_query - ~output: - (obj2 - (req "first" Raw_level.encoding) - (req "last" Raw_level.encoding)) - RPC_path.(path / "levels_in_current_cycle") - - let round = - RPC_service.get_service - ~description: - "Returns the round of the interrogated block, or the one of a block \ - located `offset` blocks after in the chain (or before when \ - negative). For instance, the next block if `offset` is 1." - ~query:RPC_query.empty - ~output:Round.encoding - RPC_path.(path / "round") - end - - type Environment.Error_monad.error += Negative_level_offset - - let () = - Environment.Error_monad.register_error_kind - `Permanent - ~id:"negative_level_offset" - ~title:"The specified level offset is negative" - ~description:"The specified level offset is negative" - ~pp:(fun ppf () -> - Format.fprintf ppf "The specified level offset should be positive.") - Data_encoding.unit - (function Negative_level_offset -> Some () | _ -> None) - (fun () -> Negative_level_offset) - - let register () = - Scripts.register () ; - Forge.register () ; - Parse.register () ; - Contract.register () ; - Big_map.register () ; - Baking_rights.register () ; - Endorsing_rights.register () ; - Validators.register () ; - Registration.register0 ~chunked:false S.current_level (fun ctxt q () -> - if q.offset < 0l then fail Negative_level_offset - else - Lwt.return - (Level.from_raw_with_offset - ctxt - ~offset:q.offset - (Level.current ctxt).level)) ; - Registration.opt_register0 - ~chunked:true - S.levels_in_current_cycle - (fun ctxt q () -> - let rev_levels = - Level.levels_in_current_cycle ctxt ~offset:q.offset () - in - match rev_levels with - | [] -> return_none - | [level] -> return (Some (level.level, level.level)) - | last :: default_first :: rest -> - (* The [rev_levels] list is reversed, the last level is the head *) - let first = List.last default_first rest in - return (Some (first.level, last.level))) ; - Registration.register0 ~chunked:false S.round (fun ctxt () () -> - Round.get ctxt) - - let current_level ctxt ?(offset = 0l) block = - RPC_context.make_call0 S.current_level ctxt block {offset} () - - let levels_in_current_cycle ctxt ?(offset = 0l) block = - RPC_context.make_call0 S.levels_in_current_cycle ctxt block {offset} () - - let rpc_services = - register () ; - RPC_directory.merge rpc_services !Registration.patched_services -end diff --git a/src/proto_012_Psithaca/lib_plugin/plugin_registerer.ml b/src/proto_012_Psithaca/lib_plugin/plugin_registerer.ml deleted file mode 100644 index 03b4f9dccbac..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/plugin_registerer.ml +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Development. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Plugin = struct - module Proto = Registerer.Registered - include Plugin -end - -let () = Prevalidator_filters.register (module Plugin) diff --git a/src/proto_012_Psithaca/lib_plugin/test/.ocamlformat b/src/proto_012_Psithaca/lib_plugin/test/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/test/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_plugin/test/dune b/src/proto_012_Psithaca/lib_plugin/test/dune deleted file mode 100644 index 6692423622b9..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/test/dune +++ /dev/null @@ -1,16 +0,0 @@ -(test - (name test_consensus_filter) - (package tezos-protocol-plugin-012-Psithaca) - (libraries tezos-base - alcotest-lwt - tezos-test-helpers - qcheck-alcotest - tezos-stdlib-unix - tezos-protocol-012-Psithaca-parameters - tezos-protocol-plugin-012-Psithaca) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_micheline - -open Tezos_protocol_012_Psithaca - -open Tezos_protocol_plugin_012_Psithaca - -open Tezos_protocol_environment_012_Psithaca - -open Tezos_protocol_012_Psithaca.Protocol))) diff --git a/src/proto_012_Psithaca/lib_plugin/test/test_consensus_filter.ml b/src/proto_012_Psithaca/lib_plugin/test/test_consensus_filter.ml deleted file mode 100644 index 8e359c8ebf0b..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/test/test_consensus_filter.ml +++ /dev/null @@ -1,499 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Lib_test.Qcheck_helpers -open Plugin.Mempool -open Alpha_context - -let config drift_opt = - { - minimal_fees = default_minimal_fees; - minimal_nanotez_per_gas_unit = default_minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte = default_minimal_nanotez_per_byte; - allow_script_failure = true; - clock_drift = - Option.map - (fun drift -> Period.of_seconds_exn (Int64.of_int drift)) - drift_opt; - replace_by_fee_factor = Q.make (Z.of_int 105) (Z.of_int 100); - } - -type Environment.Error_monad.error += Generation_failure - -(** Conversion helpers *) - -let int32_of_timestamp ts = - let i64 = Timestamp.to_seconds ts in - let i32 = Int64.to_int32 i64 in - if Int64.(equal (of_int32 i32) i64) then Ok i32 - else Environment.Error_monad.error Generation_failure - -let int32_of_timestamp_exn ts = - match int32_of_timestamp ts with - | Ok i32 -> i32 - | Error _err -> Stdlib.failwith "int32_of_timestamp_exn: number too big" - -let timestamp_of_int32 ts = Timestamp.of_seconds (Int64.of_int32 ts) - -(** Data Generators *) -module Generator = struct - open QCheck - - let decorate ?(prefix = "") ?(suffix = "") printer gen = - set_print (fun d -> prefix ^ printer d ^ suffix) gen - - let config = - decorate ~prefix:"clock_drift " (fun config -> - Option.fold - ~none:"round_0 duration" - ~some:(fun drift -> Int64.to_string @@ Period.to_seconds drift) - config.clock_drift) - @@ map - ~rev:(fun {clock_drift; _} -> - Option.map - (fun drift -> Int64.to_int @@ Period.to_seconds drift) - clock_drift) - config - (option small_nat) - - let of_error_arb gen = - of_option_arb - @@ map - ~rev:(function - | Some x -> Ok x - | None -> Environment.Error_monad.error Generation_failure) - (function Ok x -> Some x | Error _err -> None) - gen - - let small_nat_32 ?prefix ?suffix () = - decorate ?prefix ?suffix Int32.to_string - @@ map ~rev:Int32.to_int Int32.of_int small_nat - - let small_signed_32 ?prefix ?suffix () = - decorate ?prefix ?suffix Int32.to_string - @@ map ~rev:Int32.to_int Int32.of_int small_signed_int - - let decorated_small_nat ?prefix ?suffix () = - decorate ?prefix ?suffix string_of_int small_nat - - let dup gen = map ~rev:fst (fun x -> (x, x)) gen - - let round = - of_error_arb - @@ map - ~rev:(function Ok l -> Round.to_int32 l | Error _ -> -1l) - (fun i32 -> Round.of_int32 i32) - (small_nat_32 ~prefix:"rnd " ()) - - let same_rounds = dup round - - let level = - of_error_arb - @@ map - ~rev:(function Ok l -> Raw_level.to_int32 l | Error _ -> -1l) - Raw_level.of_int32 - (small_nat_32 ~prefix:"lev " ()) - - let same_levels = dup level - - let timestamp = - set_print Timestamp.to_notation - @@ map ~rev:int32_of_timestamp_exn (fun f -> timestamp_of_int32 f) int32 - - let near_timestamps = - map - ~rev:(fun (ts1, ts2) -> - let its1 = int32_of_timestamp_exn ts1 in - let its2 = int32_of_timestamp_exn ts2 in - Int32.(its1, sub its2 its1)) - (fun (i, diff) -> - timestamp_of_int32 i |> fun ts1 -> - timestamp_of_int32 Int32.(add i diff) |> fun ts2 -> (ts1, ts2)) - (pair int32 (small_signed_32 ~prefix:"+" ~suffix:"sec." ())) - - let dummy_timestamp = - match Timestamp.of_seconds_string "0" with - | Some ts -> ts - | _ -> assert false - - let unsafe_sub ts1 ts2 = - Int64.to_int @@ Period.to_seconds - @@ - match Timestamp.(ts1 -? ts2) with - | Ok diff -> diff - | Error _ -> assert false - - let successive_timestamp = - of_error_arb - @@ map - ~rev:(function - | Ok (ts1, ts2) -> (ts1, unsafe_sub ts2 ts1) - | Error _ -> (dummy_timestamp, -1)) - (fun (ts, (diff : int)) -> - Period.of_seconds (Int64.of_int diff) >>? fun diff -> - Timestamp.(ts +? diff) >>? fun ts2 -> Ok (ts, ts2)) - (pair timestamp (decorated_small_nat ~prefix:"+" ~suffix:"sec." ())) - - let param_acceptable ?(rounds = pair round round) ?(levels = pair level level) - ?(timestamps = near_timestamps) () = - pair config (pair (pair rounds levels) timestamps) -end - -let assert_no_error d = match d with Error _ -> assert false | Ok d -> d - -(** Constants : - This could be generated but it would largely increase the search space. *) -let round_durations : Round.round_durations = - assert_no_error - @@ Round.Durations.create - ~first_round_duration:Period.(of_seconds_exn 4L) - ~delay_increment_per_round:Period.(of_seconds_exn 10L) - -let round_zero_duration = Round.round_duration round_durations Round.zero - -(** Don't allow test to fail *) -let no_error = function - | Ok b -> b - | Error errs -> - Format.printf - "test fail due to error : %a@." - Error_monad.pp_print_trace - (Environment.wrap_tztrace errs) ; - false - -(** Helper to compute *) -let durations round_durations start stop = - List.map_e - (fun round -> - Round.of_int round >|? fun round -> - Round.round_duration round_durations round |> Period.to_seconds) - Tezos_stdlib.Utils.Infix.(start -- stop) - -(** Expected timestamp for the begining of a round at same level that - the proposal. - - It has been developped before the Round.timestamp_of_round_same_level and has a - different implementation. - -*) -let timestamp_of_round round_durations ~proposal_timestamp ~proposal_round - ~round = - (let iproposal_round = Int32.to_int @@ Round.to_int32 proposal_round in - let iround = Int32.to_int @@ Round.to_int32 round in - if Round.(proposal_round = round) then ok (Period.zero, proposal_timestamp) - else if Round.(proposal_round < round) then - durations round_durations iproposal_round (iround - 1) >>? fun durations -> - Period.of_seconds @@ List.fold_left Int64.add Int64.zero durations - >>? fun rounds_duration -> - Timestamp.(proposal_timestamp +? rounds_duration) >|? fun ts -> - (rounds_duration, ts) - else - durations round_durations iround (iproposal_round - 1) >>? fun durations -> - List.fold_left Int64.add Int64.zero durations |> fun rounds_duration -> - Timestamp.of_seconds - @@ Int64.sub (Timestamp.to_seconds proposal_timestamp) rounds_duration - |> fun ts -> - Period.of_seconds rounds_duration >|? fun rounds_duration -> - (rounds_duration, ts)) - >>? fun (_rnd_dur, exp_ts) -> ok exp_ts - -let drift_of = - let r0_dur = Round.round_duration round_durations Round.zero in - fun clock_drift -> Option.value ~default:r0_dur clock_drift - -(** [max_ts] computes the upper bound on future timestamps given the - accepted round drift. -*) -let max_ts clock_drift prop_ts now = - Timestamp.(max prop_ts now +? drift_of clock_drift) - -let count = None - -let predecessor_start proposal_timestamp proposal_round grandparent_round = - assert_no_error - @@ ( Round.level_offset_of_round - round_durations - ~round:Round.(succ grandparent_round) - >>? fun proposal_level_offset -> - Round.level_offset_of_round round_durations ~round:proposal_round - >>? fun proposal_round_offset -> - Period.(add proposal_level_offset proposal_round_offset) - >>? fun proposal_offset -> - Ok Timestamp.(proposal_timestamp - proposal_offset) ) - -(** TESTS *) - -(** Test past operations that are accepted whatever the current timestamp is: - strictly before the predecessor level or at the current level and with a - strictly lower round than the head. *) - -let test_acceptable_past_level = - QCheck.Test.make - ~name:"acceptable past op " - (Generator.param_acceptable ()) - (fun - ( config, - ( ((proposal_round, op_round), (proposal_level, op_level)), - (proposal_timestamp, now_timestamp) ) ) - -> - QCheck.( - Raw_level.( - proposal_level > succ op_level - || (proposal_level = op_level && Round.(proposal_round > op_round))) - ==> no_error - @@ acceptable_op - ~config - ~round_durations - ~round_zero_duration - ~proposal_level - ~proposal_round - ~proposal_timestamp - ~proposal_predecessor_level_start: - (predecessor_start - proposal_timestamp - proposal_round - Round.zero) - ~op_level - ~op_round - ~now_timestamp)) - -(** Test acceptable operations at current level, current round, i.e. on the - currently considered proposal *) -let test_acceptable_current_level_current_round = - let open QCheck in - Test.make - ?count - ~name:"same round, same level " - Generator.(param_acceptable ~rounds:same_rounds ~levels:same_levels ()) - (fun ( config, - (((op_round, _), (_, op_level)), (proposal_timestamp, now_timestamp)) - ) -> - let proposal_level = op_level in - let proposal_round = op_round in - no_error - @@ acceptable_op - ~config - ~round_durations - ~round_zero_duration - ~proposal_level - ~proposal_round - ~proposal_timestamp - ~proposal_predecessor_level_start: - (predecessor_start proposal_timestamp proposal_round Round.zero) - ~op_level - ~op_round - ~now_timestamp) - -(** Test operations at same level, different round, with an acceptable expected - timestamp for the operation. *) -let test_acceptable_current_level = - let open QCheck in - Test.make - ?count - ~name:"same level, different round, acceptable op" - Generator.(param_acceptable ~levels:same_levels ()) - (fun ( config, - ( ((proposal_round, op_round), (_, op_level)), - (proposal_timestamp, now_timestamp) ) ) -> - let proposal_level = op_level in - no_error - ( timestamp_of_round - round_durations - ~proposal_timestamp - ~proposal_round - ~round:op_round - >>? fun expected_time -> - max_ts config.clock_drift proposal_timestamp now_timestamp - >>? fun max_timestamp -> ok Timestamp.(expected_time <= max_timestamp) - ) - ==> no_error - @@ acceptable_op - ~config - ~round_durations - ~round_zero_duration - ~proposal_level - ~proposal_round - ~proposal_timestamp - ~proposal_predecessor_level_start: - (predecessor_start - proposal_timestamp - proposal_round - Round.zero) - ~op_level - ~op_round - ~now_timestamp) - -(** Test operations at same level, different round, with a too high expected - timestamp for the operation, and not at current round (which is always accepted). *) -let test_not_acceptable_current_level = - let open QCheck in - Test.make - ?count - ~name:"same level, different round, too far" - Generator.(param_acceptable ~levels:same_levels ()) - (fun ( config, - ( ((proposal_round, op_round), (_, op_level)), - (proposal_timestamp, now_timestamp) ) ) -> - let proposal_level = op_level in - no_error - ( timestamp_of_round - round_durations - ~proposal_timestamp - ~proposal_round - ~round:op_round - >>? fun expected_time -> - max_ts config.clock_drift proposal_timestamp now_timestamp - >>? fun max_timestamp -> - ok - Timestamp.( - expected_time > max_timestamp - && Round.(proposal_round <> op_round)) ) - ==> no_error - (acceptable_op - ~config - ~round_durations - ~round_zero_duration - ~proposal_level - ~proposal_round - ~proposal_timestamp - ~proposal_predecessor_level_start: - (predecessor_start - proposal_timestamp - proposal_round - Round.zero) - ~op_level - ~op_round - ~now_timestamp - >|? not)) - -(** Test operations at next level, different round, with an acceptable timestamp for - the operation. *) -let test_acceptable_next_level = - let open QCheck in - Test.make - ?count - ~name:"next level, acceptable op" - Generator.(param_acceptable ~levels:same_levels ()) - (fun ( config, - ( ((proposal_round, op_round), (proposal_level, _)), - (proposal_timestamp, now_timestamp) ) ) -> - let op_level = Raw_level.succ proposal_level in - no_error - ( timestamp_of_round - round_durations - ~proposal_timestamp - ~proposal_round - ~round:Round.zero - >>? fun current_level_start -> - Round.timestamp_of_round - round_durations - ~predecessor_timestamp:current_level_start - ~predecessor_round:Round.zero - ~round:op_round - >>? fun expected_time -> - max_ts config.clock_drift proposal_timestamp now_timestamp - >>? fun max_timestamp -> ok Timestamp.(expected_time <= max_timestamp) - ) - ==> no_error - @@ acceptable_op - ~config - ~round_durations - ~round_zero_duration - ~proposal_level - ~proposal_round - ~proposal_timestamp - ~proposal_predecessor_level_start: - (predecessor_start - proposal_timestamp - proposal_round - Round.zero) - ~op_level - ~op_round - ~now_timestamp) - -(** Test operations at next level, different round, with a too high timestamp - for the operation. *) -let test_not_acceptable_next_level = - let open QCheck in - Test.make - ?count - ~name:"next level, too far" - Generator.( - param_acceptable ~levels:same_levels ~timestamps:successive_timestamp ()) - (fun ( config, - ( ((proposal_round, op_round), (proposal_level, _)), - (proposal_timestamp, now_timestamp) ) ) -> - let op_level = Raw_level.succ proposal_level in - QCheck.assume - @@ no_error - ( timestamp_of_round - round_durations - ~proposal_timestamp - ~proposal_round - ~round:Round.zero - >>? fun current_level_start -> - Round.timestamp_of_round - round_durations - ~predecessor_timestamp:current_level_start - ~predecessor_round:Round.zero - ~round:op_round - >>? fun expected_time -> - Timestamp.( - proposal_timestamp - +? Round.round_duration round_durations proposal_round) - >>? fun next_level_ts -> - max_ts config.clock_drift next_level_ts now_timestamp - >>? fun max_timestamp -> - ok Timestamp.(expected_time > max_timestamp) ) ; - no_error - @@ (acceptable_op - ~config - ~round_durations - ~round_zero_duration - ~proposal_level - ~proposal_round - ~proposal_timestamp - ~proposal_predecessor_level_start: - (predecessor_start proposal_timestamp proposal_round Round.zero) - ~op_level - ~op_round - ~now_timestamp - >|? not)) - -let () = - Alcotest.run - "Filter" - [ - ( "pre_filter", - qcheck_wrap - [ - test_acceptable_past_level; - test_acceptable_current_level_current_round; - test_acceptable_current_level; - test_not_acceptable_current_level; - test_acceptable_next_level; - test_not_acceptable_next_level; - ] ); - ] diff --git a/src/proto_012_Psithaca/lib_plugin/tezos-protocol-plugin-012-Psithaca-registerer.opam b/src/proto_012_Psithaca/lib_plugin/tezos-protocol-plugin-012-Psithaca-registerer.opam deleted file mode 100644 index e2b3e5fcb442..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/tezos-protocol-plugin-012-Psithaca-registerer.opam +++ /dev/null @@ -1,18 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-embedded-protocol-012-Psithaca" - "tezos-protocol-plugin-012-Psithaca" - "tezos-shell" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol plugin registerer" diff --git a/src/proto_012_Psithaca/lib_plugin/tezos-protocol-plugin-012-Psithaca.opam b/src/proto_012_Psithaca/lib_plugin/tezos-protocol-plugin-012-Psithaca.opam deleted file mode 100644 index c237ac98e651..000000000000 --- a/src/proto_012_Psithaca/lib_plugin/tezos-protocol-plugin-012-Psithaca.opam +++ /dev/null @@ -1,22 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-stdlib-unix" - "tezos-protocol-012-Psithaca" - "tezos-protocol-012-Psithaca-parameters" {with-test} - "tezos-test-helpers" {with-test} - "alcotest-lwt" {with-test} - "qcheck-alcotest" {with-test} -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol plugin" diff --git a/src/proto_012_Psithaca/lib_protocol/.ocamlformat b/src/proto_012_Psithaca/lib_protocol/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_protocol/TEZOS_PROTOCOL b/src/proto_012_Psithaca/lib_protocol/TEZOS_PROTOCOL deleted file mode 100644 index 812840dc4f8d..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/TEZOS_PROTOCOL +++ /dev/null @@ -1,129 +0,0 @@ -{ - "expected_env_version": 4, - "hash": "PsithacaTTq3oumpKDw1pVvRrAtqiK4hKnP3Q4FNrXN9yc6KPhp", - "modules": [ - "Misc", - "Non_empty_string", - "Path_encoding", - "Storage_description", - "State_hash", - "Nonce_hash", - "Script_expr_hash", - "Contract_hash", - "Blinded_public_key_hash", - "Block_payload_hash", - - "Slot_repr", - "Tez_repr", - "Period_repr", - "Time_repr", - "Round_repr", - "Block_payload_repr", - "Fixed_point_repr", - "Saturation_repr", - "Gas_limit_repr", - "Constants_repr", - "Raw_level_repr", - "Fitness_repr", - "Cycle_repr", - "Level_repr", - "Seed_repr", - "Sampler", - "Voting_period_repr", - "Script_string_repr", - "Script_int_repr", - "Script_timestamp_repr", - "Michelson_v1_primitives", - "Script_repr", - "Cache_memory_helpers", - "Contract_repr", - "Roll_repr_legacy", - "Vote_repr", - "Block_header_repr", - "Operation_repr", - "Manager_repr", - "Commitment_repr", - "Parameters_repr", - "Sapling_repr", - "Lazy_storage_kind", - "Receipt_repr", - "Migration_repr", - - "Raw_context_intf", - "Raw_context", - "Storage_costs", - "Storage_sigs", - "Storage_functors", - "Storage", - "Cache_repr", - - "Constants_storage", - "Level_storage", - "Nonce_storage", - "Seed_storage", - "Roll_storage_legacy", - "Contract_manager_storage", - "Delegate_activation_storage", - "Frozen_deposits_storage", - "Stake_storage", - "Contract_delegate_storage", - "Sapling_storage", - "Lazy_storage_diff", - "Contract_storage", - "Commitment_storage", - "Token", - "Delegate_storage", - "Bootstrap_storage", - "Voting_period_storage", - "Vote_storage", - "Fees_storage", - "Ticket_storage", - "Liquidity_baking_repr", - "Liquidity_baking_cpmm", - "Liquidity_baking_lqt", - "Liquidity_baking_migration", - "Init_storage", - "Sapling_validator", - - "Global_constants_costs", - "Global_constants_storage", - - "Alpha_context", - - "Local_gas_counter", - "Gas_monad", - "Script_tc_errors", - "Script_ir_annot", - "Script_typed_ir", - "Script_typed_ir_size", - "Script_typed_ir_size_costs", - "Michelson_v1_gas", - "Script_list", - "Script_comparable", - "Script_set", - "Script_map", - "Script_ir_translator", - "Script_cache", - "Script_tc_errors_registration", - "Ticket_costs", - "Ticket_scanner", - "Ticket_balance_key", - "Script_interpreter_defs", - "Script_interpreter", - - "Baking", - "Amendment", - "Apply_results", - "Apply", - - "Services_registration", - "Constants_services", - "Sapling_services", - "Contract_services", - "Delegate_services", - "Voting_services", - "Alpha_services", - - "Main" - ] -} diff --git a/src/proto_012_Psithaca/lib_protocol/alpha_context.ml b/src/proto_012_Psithaca/lib_protocol/alpha_context.ml deleted file mode 100644 index 83321a218c37..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/alpha_context.ml +++ /dev/null @@ -1,436 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = Raw_context.t - -type context = t - -module type BASIC_DATA = sig - type t - - include Compare.S with type t := t - - val encoding : t Data_encoding.t - - val pp : Format.formatter -> t -> unit -end - -module Tez = Tez_repr -module Period = Period_repr - -module Timestamp = struct - include Time_repr - - let current = Raw_context.current_timestamp - - let predecessor = Raw_context.predecessor_timestamp -end - -module Slot = struct - include Slot_repr - - let slot_range = List.slot_range -end - -include Operation_repr - -module Operation = struct - type 'kind t = 'kind operation = { - shell : Operation.shell_header; - protocol_data : 'kind protocol_data; - } - - type packed = packed_operation - - let unsigned_encoding = unsigned_operation_encoding - - include Operation_repr -end - -module Block_header = Block_header_repr - -module Vote = struct - include Vote_repr - include Vote_storage -end - -module Block_payload = struct - include Block_payload_repr -end - -module First_level_of_tenderbake = struct - let get = Storage.Tenderbake.First_level.get -end - -module Raw_level = Raw_level_repr -module Cycle = Cycle_repr -module Script_string = Script_string_repr -module Script_int = Script_int_repr - -module Script_timestamp = struct - include Script_timestamp_repr - - let now ctxt = - let {Constants_repr.minimal_block_delay; _} = Raw_context.constants ctxt in - let first_delay = Period_repr.to_seconds minimal_block_delay in - let current_timestamp = Raw_context.predecessor_timestamp ctxt in - Time.add current_timestamp first_delay |> Timestamp.to_seconds |> of_int64 -end - -module Script = struct - include Michelson_v1_primitives - include Script_repr - - type consume_deserialization_gas = Always | When_needed - - let force_decode_in_context ~consume_deserialization_gas ctxt lexpr = - let gas_cost = - match consume_deserialization_gas with - | Always -> Script_repr.stable_force_decode_cost lexpr - | When_needed -> Script_repr.force_decode_cost lexpr - in - Raw_context.consume_gas ctxt gas_cost >>? fun ctxt -> - Script_repr.force_decode lexpr >|? fun v -> (v, ctxt) - - let force_bytes_in_context ctxt lexpr = - Raw_context.consume_gas ctxt (Script_repr.force_bytes_cost lexpr) - >>? fun ctxt -> - Script_repr.force_bytes lexpr >|? fun v -> (v, ctxt) -end - -module Fees = Fees_storage - -type public_key = Signature.Public_key.t - -type public_key_hash = Signature.Public_key_hash.t - -type signature = Signature.t - -module Constants = struct - include Constants_repr - include Constants_storage - - let round_durations ctxt = Raw_context.round_durations ctxt - - let all ctxt = all (parametric ctxt) -end - -module Voting_period = struct - include Voting_period_repr - include Voting_period_storage -end - -module Round = struct - include Round_repr - module Durations = Durations - - type round_durations = Durations.t - - let pp_round_durations = Durations.pp - - let round_durations_encoding = Durations.encoding - - let round_duration = Round_repr.Durations.round_duration - - let update ctxt round = Storage.Block_round.update ctxt round - - let get ctxt = Storage.Block_round.get ctxt -end - -module Gas = struct - include Gas_limit_repr - - type error += Gas_limit_too_high = Raw_context.Gas_limit_too_high - - type error += Block_quota_exceeded = Raw_context.Block_quota_exceeded - - type error += Operation_quota_exceeded = Raw_context.Operation_quota_exceeded - - let check_limit_is_valid = Raw_context.check_gas_limit_is_valid - - let set_limit = Raw_context.set_gas_limit - - let consume_limit_in_block = Raw_context.consume_gas_limit_in_block - - let set_unlimited = Raw_context.set_gas_unlimited - - let consume = Raw_context.consume_gas - - let remaining_operation_gas = Raw_context.remaining_operation_gas - - let update_remaining_operation_gas = - Raw_context.update_remaining_operation_gas - - let reset_block_gas ctxt = - let gas = Constants.hard_gas_limit_per_block ctxt in - Raw_context.update_remaining_block_gas ctxt gas - - let level = Raw_context.gas_level - - let consumed = Raw_context.gas_consumed - - let block_level = Raw_context.block_gas_level - - (* Necessary to inject costs for Storage_costs into Gas.cost *) - let cost_of_repr cost = cost -end - -module Level = struct - include Level_repr - include Level_storage -end - -module Lazy_storage = struct - module Kind = Lazy_storage_kind - module IdSet = Kind.IdSet - include Lazy_storage_diff - - let legacy_big_map_diff_encoding = - Data_encoding.conv - Contract_storage.Legacy_big_map_diff.of_lazy_storage_diff - Contract_storage.Legacy_big_map_diff.to_lazy_storage_diff - Contract_storage.Legacy_big_map_diff.encoding -end - -module Contract = struct - include Contract_repr - include Contract_storage - - let init_origination_nonce = Raw_context.init_origination_nonce - - let unset_origination_nonce = Raw_context.unset_origination_nonce - - let is_manager_key_revealed = Contract_manager_storage.is_manager_key_revealed - - let reveal_manager_key = Contract_manager_storage.reveal_manager_key - - let get_manager_key = Contract_manager_storage.get_manager_key -end - -module Global_constants_storage = Global_constants_storage - -module Big_map = struct - module Big_map = Lazy_storage_kind.Big_map - - module Id = struct - type t = Big_map.Id.t - - let encoding = Big_map.Id.encoding - - let rpc_arg = Big_map.Id.rpc_arg - - let parse_z = Big_map.Id.parse_z - - let unparse_to_z = Big_map.Id.unparse_to_z - end - - let fresh ~temporary c = Lazy_storage.fresh Big_map ~temporary c - - let mem c m k = Storage.Big_map.Contents.mem (c, m) k - - let get_opt c m k = Storage.Big_map.Contents.find (c, m) k - - let list_values ?offset ?length c m = - Storage.Big_map.Contents.list_values ?offset ?length (c, m) - - let exists c id = - Raw_context.consume_gas c (Gas_limit_repr.read_bytes_cost 0) >>?= fun c -> - Storage.Big_map.Key_type.find c id >>=? fun kt -> - match kt with - | None -> return (c, None) - | Some kt -> - Storage.Big_map.Value_type.get c id >|=? fun kv -> (c, Some (kt, kv)) - - type update = Big_map.update = { - key : Script_repr.expr; - key_hash : Script_expr_hash.t; - value : Script_repr.expr option; - } - - type updates = Big_map.updates - - type alloc = Big_map.alloc = { - key_type : Script_repr.expr; - value_type : Script_repr.expr; - } -end - -module Sapling = struct - module Sapling_state = Lazy_storage_kind.Sapling_state - - module Id = struct - type t = Sapling_state.Id.t - - let encoding = Sapling_state.Id.encoding - - let rpc_arg = Sapling_state.Id.rpc_arg - - let parse_z = Sapling_state.Id.parse_z - - let unparse_to_z = Sapling_state.Id.unparse_to_z - end - - include Sapling_repr - include Sapling_storage - include Sapling_validator - - let fresh ~temporary c = Lazy_storage.fresh Sapling_state ~temporary c - - type updates = Sapling_state.updates - - type alloc = Sapling_state.alloc = {memo_size : Sapling_repr.Memo_size.t} -end - -module Receipt = Receipt_repr - -module Delegate = struct - include Delegate_storage - - type deposits = Storage.deposits = { - initial_amount : Tez.t; - current_amount : Tez.t; - } - - let grace_period = Delegate_activation_storage.grace_period - - let prepare_stake_distribution = Stake_storage.prepare_stake_distribution - - let registered = Contract_delegate_storage.registered - - let find = Contract_delegate_storage.find - - let delegated_contracts = Contract_delegate_storage.delegated_contracts -end - -module Stake_distribution = struct - let snapshot = Stake_storage.snapshot - - let baking_rights_owner = Delegate.baking_rights_owner - - let slot_owner = Delegate.slot_owner - - let delegate_pubkey = Delegate.pubkey - - let get_staking_balance = Delegate.staking_balance -end - -module Nonce = Nonce_storage - -module Seed = struct - include Seed_repr - include Seed_storage -end - -module Fitness = struct - type raw = Fitness.t - - include Fitness_repr -end - -module Bootstrap = Bootstrap_storage - -module Commitment = struct - include Commitment_repr - include Commitment_storage -end - -module Migration = Migration_repr - -module Consensus = struct - include Raw_context.Consensus - - let load_endorsement_branch ctxt = - Storage.Tenderbake.Endorsement_branch.find ctxt >>=? function - | Some endorsement_branch -> - Raw_context.Consensus.set_endorsement_branch ctxt endorsement_branch - |> return - | None -> return ctxt - - let store_endorsement_branch ctxt branch = - let ctxt = set_endorsement_branch ctxt branch in - Storage.Tenderbake.Endorsement_branch.add ctxt branch - - let load_grand_parent_branch ctxt = - Storage.Tenderbake.Grand_parent_branch.find ctxt >>=? function - | Some grand_parent_branch -> - Raw_context.Consensus.set_grand_parent_branch ctxt grand_parent_branch - |> return - | None -> return ctxt - - let store_grand_parent_branch ctxt branch = - let ctxt = set_grand_parent_branch ctxt branch in - Storage.Tenderbake.Grand_parent_branch.add ctxt branch -end - -let prepare_first_block = Init_storage.prepare_first_block - -let prepare ctxt ~level ~predecessor_timestamp ~timestamp = - Init_storage.prepare ctxt ~level ~predecessor_timestamp ~timestamp - >>=? fun (ctxt, balance_updates, origination_results) -> - Consensus.load_endorsement_branch ctxt >>=? fun ctxt -> - Consensus.load_grand_parent_branch ctxt >>=? fun ctxt -> - return (ctxt, balance_updates, origination_results) - -let finalize ?commit_message:message c fitness = - let context = Raw_context.recover c in - { - Updater.context; - fitness; - message; - max_operations_ttl = (Raw_context.constants c).max_operations_time_to_live; - last_allowed_fork_level = - Raw_level.to_int32 @@ Level.last_allowed_fork_level c; - } - -let current_context c = Raw_context.recover c - -let record_non_consensus_operation_hash = - Raw_context.record_non_consensus_operation_hash - -let non_consensus_operations = Raw_context.non_consensus_operations - -let activate = Raw_context.activate - -let reset_internal_nonce = Raw_context.reset_internal_nonce - -let fresh_internal_nonce = Raw_context.fresh_internal_nonce - -let record_internal_nonce = Raw_context.record_internal_nonce - -let internal_nonce_already_recorded = - Raw_context.internal_nonce_already_recorded - -let description = Raw_context.description - -module Parameters = Parameters_repr -module Liquidity_baking = Liquidity_baking_repr - -module Ticket_balance = struct - include Ticket_storage -end - -module Token = Token -module Cache = Cache_repr diff --git a/src/proto_012_Psithaca/lib_protocol/alpha_context.mli b/src/proto_012_Psithaca/lib_protocol/alpha_context.mli deleted file mode 100644 index 90bfdec63267..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/alpha_context.mli +++ /dev/null @@ -1,2436 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2021 Nomadic Labs *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** An [Alpha_context.t] is an immutable snapshot of the ledger state at some block - height, preserving - {{:https://tezos.gitlab.io/developer/entering_alpha.html#the-big-abstraction-barrier-alpha-context} - type-safety and invariants} of the ledger state. - - {2 Implementation} - - [Alpha_context.t] is a wrapper over [Raw_context.t], which in turn is a - wrapper around [Context.t] from the Protocol Environment. - - {2 Lifetime of an Alpha_context} - - - Creation, using [prepare] or [prepare_first_block] - - - Modification, using the operations defined in this signature - - - Finalization, using [finalize] - *) - -module type BASIC_DATA = sig - type t - - include Compare.S with type t := t - - val encoding : t Data_encoding.t - - val pp : Format.formatter -> t -> unit -end - -type t - -type context = t - -type public_key = Signature.Public_key.t - -type public_key_hash = Signature.Public_key_hash.t - -type signature = Signature.t - -module Slot : sig - type t - - include Compare.S with type t := t - - val pp : Format.formatter -> t -> unit - - val zero : t - - val succ : t -> t - - val of_int_do_not_use_except_for_parameters : int -> t - - val encoding : t Data_encoding.encoding - - val slot_range : min:int -> count:int -> t list tzresult - - module Map : Map.S with type key = t - - module Set : Set.S with type elt = t -end - -module Tez : sig - include BASIC_DATA - - type tez = t - - val zero : tez - - val one_mutez : tez - - val one_cent : tez - - val fifty_cents : tez - - val one : tez - - val ( -? ) : tez -> tez -> tez tzresult - - val sub_opt : tez -> tez -> tez option - - val ( +? ) : tez -> tez -> tez tzresult - - val ( *? ) : tez -> int64 -> tez tzresult - - val ( /? ) : tez -> int64 -> tez tzresult - - val of_string : string -> tez option - - val to_string : tez -> string - - val of_mutez : int64 -> tez option - - val to_mutez : tez -> int64 - - val of_mutez_exn : int64 -> t - - val mul_exn : t -> int -> t - - val div_exn : t -> int -> t -end - -module Period : sig - include BASIC_DATA - - type period = t - - val rpc_arg : period RPC_arg.arg - - val of_seconds : int64 -> period tzresult - - val of_seconds_exn : int64 -> period - - val to_seconds : period -> int64 - - val add : period -> period -> period tzresult - - val mult : int32 -> period -> period tzresult - - val zero : period - - val one_second : period - - val one_minute : period - - val one_hour : period - - val compare : period -> period -> int -end - -module Timestamp : sig - include BASIC_DATA with type t = Time.t - - type time = t - - val ( +? ) : time -> Period.t -> time tzresult - - val ( -? ) : time -> time -> Period.t tzresult - - val ( - ) : time -> Period.t -> time - - val of_notation : string -> time option - - val to_notation : time -> string - - val of_seconds : int64 -> time - - val to_seconds : time -> int64 - - val of_seconds_string : string -> time option - - val to_seconds_string : time -> string - - val current : context -> time - - val predecessor : context -> time -end - -module Raw_level : sig - include BASIC_DATA - - type raw_level = t - - val rpc_arg : raw_level RPC_arg.arg - - val diff : raw_level -> raw_level -> int32 - - val root : raw_level - - val succ : raw_level -> raw_level - - val pred : raw_level -> raw_level option - - val to_int32 : raw_level -> int32 - - val of_int32 : int32 -> raw_level tzresult -end - -module Cycle : sig - include BASIC_DATA - - type cycle = t - - val rpc_arg : cycle RPC_arg.arg - - val root : cycle - - val succ : cycle -> cycle - - val pred : cycle -> cycle option - - val add : cycle -> int -> cycle - - val sub : cycle -> int -> cycle option - - val to_int32 : cycle -> int32 - - module Map : Map.S with type key = cycle -end - -module Round : sig - (* A round represents an iteration of the single-shot consensus algorithm. - This mostly simply re-exports [Round_repr]. See [Round_repr] for - additional documentation of this module *) - - type t - - val zero : t - - val succ : t -> t - - val pred : t -> t tzresult - - val to_int32 : t -> int32 - - val of_int32 : int32 -> t tzresult - - val of_int : int -> t tzresult - - val to_int : t -> int tzresult - - val to_slot : t -> committee_size:int -> Slot.t tzresult - - val pp : Format.formatter -> t -> unit - - val encoding : t Data_encoding.t - - include Compare.S with type t := t - - module Map : Map.S with type key = t - - type round_durations - - val pp_round_durations : Format.formatter -> round_durations -> unit - - val round_durations_encoding : round_durations Data_encoding.t - - val round_duration : round_durations -> t -> Period.t - - module Durations : sig - val create : - first_round_duration:Period.t -> - delay_increment_per_round:Period.t -> - round_durations tzresult - - val create_opt : - first_round_duration:Period.t -> - delay_increment_per_round:Period.t -> - round_durations option - end - - val level_offset_of_round : round_durations -> round:t -> Period.t tzresult - - val timestamp_of_round : - round_durations -> - predecessor_timestamp:Time.t -> - predecessor_round:t -> - round:t -> - Time.t tzresult - - val timestamp_of_another_round_same_level : - round_durations -> - current_timestamp:Time.t -> - current_round:t -> - considered_round:t -> - Time.t tzresult - - val round_of_timestamp : - round_durations -> - predecessor_timestamp:Time.t -> - predecessor_round:t -> - timestamp:Time.t -> - t tzresult - - (* retrieve a round from the context *) - val get : context -> t tzresult Lwt.t - - (* store a round in context *) - val update : context -> t -> context tzresult Lwt.t -end - -module Gas : sig - (** This module implements the gas subsystem of the context. - - Gas reflects the computational cost of each operation to limit - the cost of operations and, by extension, the cost of blocks. - - There are two gas quotas: one for operation and one for - block. For this reason, we maintain two gas levels -- one for - operations and another one for blocks -- that correspond to the - remaining amounts of gas, initialized with the quota - limits and decreased each time gas is consumed. - - *) - - module Arith : - Fixed_point_repr.Safe - with type 'a t = Saturation_repr.may_saturate Saturation_repr.t - [@@coq_plain_module] - - (** For maintenance operations or for testing, gas can be - [Unaccounted]. Otherwise, the computation is [Limited] by the - [remaining] gas in the context. *) - type t = private Unaccounted | Limited of {remaining : Arith.fp} - - val encoding : t Data_encoding.encoding - - val pp : Format.formatter -> t -> unit - - (** [check_limit_is_valid ctxt limit] checks that the given gas - [limit] is well-formed, i.e., it does not exceed the hard gas - limit per operation as defined in [ctxt] and it is positive. *) - val check_limit_is_valid : context -> 'a Arith.t -> unit tzresult - - (** [set_limit ctxt limit] returns a context with a given - [limit] level of gas allocated for an operation. *) - val set_limit : context -> 'a Arith.t -> context - - (** [set_unlimited] allows unlimited gas consumption. *) - val set_unlimited : context -> context - - (** [remaining_operation_gas ctxt] returns the current gas level in - the context [ctxt] for the current operation. If gas is - [Unaccounted], an arbitrary value will be returned. *) - val remaining_operation_gas : context -> Arith.fp - - (** [reset_block_gas ctxt] returns a context where the remaining gas - in the block is reset to the constant [hard_gas_limit_per_block], - i.e., as if no operations have been included in the block. - - /!\ Do not call this function unless you want to validate - operations on their own (like in the mempool). *) - val reset_block_gas : context -> context - - (** [level ctxt] is the current gas level in [ctxt] for the current - operation. *) - val level : context -> t - - (** [update_remaining_operation_gas ctxt remaining] sets the current - gas level for operations to [remaining]. *) - val update_remaining_operation_gas : context -> Arith.fp -> context - - (** [consumed since until] is the operation gas level difference - between context [since] and context [until]. This function - returns [Arith.zero] if any of the two contexts allows for an - unlimited gas consumption. This function also returns - [Arith.zero] if [since] has less gas than [until]. *) - val consumed : since:context -> until:context -> Arith.fp - - (** [block_level ctxt] returns the block gas level in context [ctxt]. *) - val block_level : context -> Arith.fp - - (** Costs are computed using a saturating arithmetic. See - {!Saturation_repr}. *) - type cost = Saturation_repr.may_saturate Saturation_repr.t - - val cost_encoding : cost Data_encoding.encoding - - val pp_cost : Format.formatter -> cost -> unit - - (** [consume ctxt cost] subtracts [cost] to the current operation - gas level in [ctxt]. This operation may fail with - [Operation_quota_exceeded] if the operation gas level would - go below zero. *) - val consume : context -> cost -> context tzresult - - type error += Operation_quota_exceeded (* `Temporary *) - - (** [consume_limit_in_block ctxt limit] consumes [limit] in - the current block gas level of the context. This operation may - fail with error [Block_quota_exceeded] if not enough gas remains - in the block. This operation may also fail with - [Gas_limit_too_high] if [limit] is greater than the allowed - limit for operation gas level. *) - val consume_limit_in_block : context -> 'a Arith.t -> context tzresult - - type error += Block_quota_exceeded (* `Temporary *) - - type error += Gas_limit_too_high (* `Permanent *) - - (** The cost of free operation is [0]. *) - val free : cost - - (** [atomic_step_cost x] corresponds to [x] milliunit of gas. *) - val atomic_step_cost : _ Saturation_repr.t -> cost - - (** [step_cost x] corresponds to [x] units of gas. *) - val step_cost : _ Saturation_repr.t -> cost - - (** Cost of allocating qwords of storage. - [alloc_cost n] estimates the cost of allocating [n] qwords of storage. *) - val alloc_cost : _ Saturation_repr.t -> cost - - (** Cost of allocating bytes in the storage. - [alloc_bytes_cost b] estimates the cost of allocating [b] bytes of - storage. *) - val alloc_bytes_cost : int -> cost - - (** Cost of allocating bytes in the storage. - - [alloc_mbytes_cost b] estimates the cost of allocating [b] bytes of - storage and the cost of an header to describe these bytes. *) - val alloc_mbytes_cost : int -> cost - - (** Cost of reading the storage. - [read_bytes_cost n] estimates the cost of reading [n] bytes of storage. *) - val read_bytes_cost : int -> cost - - (** Cost of writing to storage. - [write_bytes_const n] estimates the cost of writing [n] bytes to the - storage. *) - val write_bytes_cost : int -> cost - - (** Multiply a cost by a factor. Both arguments are saturated arithmetic values, - so no negative numbers are involved. *) - val ( *@ ) : _ Saturation_repr.t -> cost -> cost - - (** Add two costs together. *) - val ( +@ ) : cost -> cost -> cost - - (** [cost_of_repr] is an internal operation needed to inject costs - for Storage_costs into Gas.cost. *) - val cost_of_repr : Gas_limit_repr.cost -> cost -end - -module Script_string : module type of Script_string_repr - -module Script_int : module type of Script_int_repr - -module Script_timestamp : sig - open Script_int - - type t - - val compare : t -> t -> int - - val to_string : t -> string - - val to_notation : t -> string option - - val to_num_str : t -> string - - val of_string : string -> t option - - val diff : t -> t -> z num - - val add_delta : t -> z num -> t - - val sub_delta : t -> z num -> t - - val now : context -> t - - val to_zint : t -> Z.t - - val of_zint : Z.t -> t - - val encoding : t Data_encoding.encoding -end - -module Script : sig - type prim = Michelson_v1_primitives.prim = - | K_parameter - | K_storage - | K_code - | K_view - | D_False - | D_Elt - | D_Left - | D_None - | D_Pair - | D_Right - | D_Some - | D_True - | D_Unit - | I_PACK - | I_UNPACK - | I_BLAKE2B - | I_SHA256 - | I_SHA512 - | I_ABS - | I_ADD - | I_AMOUNT - | I_AND - | I_BALANCE - | I_CAR - | I_CDR - | I_CHAIN_ID - | I_CHECK_SIGNATURE - | I_COMPARE - | I_CONCAT - | I_CONS - | I_CREATE_ACCOUNT - | I_CREATE_CONTRACT - | I_IMPLICIT_ACCOUNT - | I_DIP - | I_DROP - | I_DUP - | I_VIEW - | I_EDIV - | I_EMPTY_BIG_MAP - | I_EMPTY_MAP - | I_EMPTY_SET - | I_EQ - | I_EXEC - | I_APPLY - | I_FAILWITH - | I_GE - | I_GET - | I_GET_AND_UPDATE - | I_GT - | I_HASH_KEY - | I_IF - | I_IF_CONS - | I_IF_LEFT - | I_IF_NONE - | I_INT - | I_LAMBDA - | I_LE - | I_LEFT - | I_LEVEL - | I_LOOP - | I_LSL - | I_LSR - | I_LT - | I_MAP - | I_MEM - | I_MUL - | I_NEG - | I_NEQ - | I_NIL - | I_NONE - | I_NOT - | I_NOW - | I_OR - | I_PAIR - | I_UNPAIR - | I_PUSH - | I_RIGHT - | I_SIZE - | I_SOME - | I_SOURCE - | I_SENDER - | I_SELF - | I_SELF_ADDRESS - | I_SLICE - | I_STEPS_TO_QUOTA - | I_SUB - | I_SUB_MUTEZ - | I_SWAP - | I_TRANSFER_TOKENS - | I_SET_DELEGATE - | I_UNIT - | I_UPDATE - | I_XOR - | I_ITER - | I_LOOP_LEFT - | I_ADDRESS - | I_CONTRACT - | I_ISNAT - | I_CAST - | I_RENAME - | I_SAPLING_EMPTY_STATE - | I_SAPLING_VERIFY_UPDATE - | I_DIG - | I_DUG - | I_NEVER - | I_VOTING_POWER - | I_TOTAL_VOTING_POWER - | I_KECCAK - | I_SHA3 - | I_PAIRING_CHECK - | I_TICKET - | I_READ_TICKET - | I_SPLIT_TICKET - | I_JOIN_TICKETS - | I_OPEN_CHEST - | T_bool - | T_contract - | T_int - | T_key - | T_key_hash - | T_lambda - | T_list - | T_map - | T_big_map - | T_nat - | T_option - | T_or - | T_pair - | T_set - | T_signature - | T_string - | T_bytes - | T_mutez - | T_timestamp - | T_unit - | T_operation - | T_address - | T_sapling_transaction - | T_sapling_state - | T_chain_id - | T_never - | T_bls12_381_g1 - | T_bls12_381_g2 - | T_bls12_381_fr - | T_ticket - | T_chest_key - | T_chest - | H_constant - - type location = Micheline.canonical_location - - type annot = Micheline.annot - - type expr = prim Micheline.canonical - - type lazy_expr = expr Data_encoding.lazy_t - - val lazy_expr : expr -> lazy_expr - - type 'location michelson_node = ('location, prim) Micheline.node - - type unlocated_michelson_node = unit michelson_node - - type node = location michelson_node - - type t = {code : lazy_expr; storage : lazy_expr} - - val location_encoding : location Data_encoding.t - - val expr_encoding : expr Data_encoding.t - - val prim_encoding : prim Data_encoding.t - - val encoding : t Data_encoding.t - - val lazy_expr_encoding : lazy_expr Data_encoding.t - - val deserialization_cost_estimated_from_bytes : int -> Gas.cost - - val deserialized_cost : expr -> Gas.cost - - val serialized_cost : bytes -> Gas.cost - - val bytes_node_cost : bytes -> Gas.cost - - (** Mode of deserialization gas consumption in {!force_decode}: - - - {!Always}: the gas is taken independently of the internal state of the - [lazy_expr] - - {!When_needed}: the gas is consumed only if the [lazy_expr] has never - been deserialized before. *) - type consume_deserialization_gas = Always | When_needed - - (** Decode an expression in the context after consuming the deserialization - gas cost (see {!consume_deserialization_gas}). *) - val force_decode_in_context : - consume_deserialization_gas:consume_deserialization_gas -> - context -> - lazy_expr -> - (expr * context) tzresult - - val force_bytes_in_context : - context -> lazy_expr -> (bytes * context) tzresult - - val unit_parameter : lazy_expr - - val strip_locations_cost : _ michelson_node -> Gas.cost - - val strip_annotations_cost : node -> Gas.cost - - val strip_annotations : node -> node -end - -module Constants : sig - (** Fixed constants *) - type fixed - - type delegate_selection = - | Random - | Round_robin_over of Signature.Public_key.t list list - - val fixed_encoding : fixed Data_encoding.t - - val proof_of_work_nonce_size : int - - val nonce_length : int - - val max_anon_ops_per_block : int - - val max_operation_data_length : int - - val max_proposals_per_delegate : int - - val michelson_maximum_type_size : int - - type ratio = {numerator : int; denominator : int} - - val ratio_encoding : ratio Data_encoding.t - - val pp_ratio : Format.formatter -> ratio -> unit - - (** Constants parameterized by context *) - type parametric = { - preserved_cycles : int; - blocks_per_cycle : int32; - blocks_per_commitment : int32; - blocks_per_stake_snapshot : int32; - blocks_per_voting_period : int32; - hard_gas_limit_per_operation : Gas.Arith.integral; - hard_gas_limit_per_block : Gas.Arith.integral; - proof_of_work_threshold : int64; - tokens_per_roll : Tez.t; - seed_nonce_revelation_tip : Tez.t; - origination_size : int; - baking_reward_fixed_portion : Tez.t; - baking_reward_bonus_per_slot : Tez.t; - endorsing_reward_per_slot : Tez.t; - cost_per_byte : Tez.t; - hard_storage_limit_per_operation : Z.t; - quorum_min : int32; - quorum_max : int32; - min_proposal_quorum : int32; - liquidity_baking_subsidy : Tez.t; - liquidity_baking_sunset_level : int32; - liquidity_baking_escape_ema_threshold : int32; - max_operations_time_to_live : int; - minimal_block_delay : Period.t; - delay_increment_per_round : Period.t; - minimal_participation_ratio : ratio; - consensus_committee_size : int; - consensus_threshold : int; - max_slashing_period : int; - frozen_deposits_percentage : int; - double_baking_punishment : Tez.t; - ratio_of_frozen_deposits_slashed_per_double_endorsement : ratio; - delegate_selection : delegate_selection; - } - - module Generated : sig - type t = { - consensus_threshold : int; - baking_reward_fixed_portion : Tez.t; - baking_reward_bonus_per_slot : Tez.t; - endorsing_reward_per_slot : Tez.t; - } - - val generate : consensus_committee_size:int -> blocks_per_minute:ratio -> t - end - - val parametric_encoding : parametric Data_encoding.t - - val parametric : context -> parametric - - val preserved_cycles : context -> int - - val blocks_per_cycle : context -> int32 - - val blocks_per_commitment : context -> int32 - - val blocks_per_stake_snapshot : context -> int32 - - val blocks_per_voting_period : context -> int32 - - val hard_gas_limit_per_operation : context -> Gas.Arith.integral - - val hard_gas_limit_per_block : context -> Gas.Arith.integral - - val cost_per_byte : context -> Tez.t - - val hard_storage_limit_per_operation : context -> Z.t - - val proof_of_work_threshold : context -> int64 - - val tokens_per_roll : context -> Tez.t - - val seed_nonce_revelation_tip : context -> Tez.t - - val origination_size : context -> int - - val baking_reward_fixed_portion : context -> Tez.t - - val baking_reward_bonus_per_slot : context -> Tez.t - - val endorsing_reward_per_slot : context -> Tez.t - - val quorum_min : context -> int32 - - val quorum_max : context -> int32 - - val min_proposal_quorum : context -> int32 - - val liquidity_baking_subsidy : context -> Tez.t - - val liquidity_baking_sunset_level : context -> int32 - - val liquidity_baking_escape_ema_threshold : context -> int32 - - val minimal_block_delay : context -> Period.t - - val delay_increment_per_round : context -> Period.t - - val round_durations : context -> Round.round_durations - - val consensus_committee_size : context -> int - - val consensus_threshold : context -> int - - val minimal_participation_ratio : context -> ratio - - val max_slashing_period : context -> int - - val frozen_deposits_percentage : context -> int - - val double_baking_punishment : context -> Tez.t - - val ratio_of_frozen_deposits_slashed_per_double_endorsement : context -> ratio - - val delegate_selection_encoding : delegate_selection Data_encoding.t - - (** All constants: fixed and parametric *) - type t = private {fixed : fixed; parametric : parametric} - - val all : context -> t - - val encoding : t Data_encoding.t -end - -module Global_constants_storage : sig - type error += Expression_too_deep - - type error += Expression_already_registered - - (** A constant is the prim of the literal characters "constant". - A constant must have a single argument, being a string with a - well formed hash of a Micheline expression (i.e generated by - [Script_expr_hash.to_b58check]). *) - type error += Badly_formed_constant_expression - - type error += Nonexistent_global - - (** [get context hash] retrieves the Micheline value with the given hash. - - Fails with [Nonexistent_global] if no value is found at the given hash. - - Fails with [Storage_error Corrupted_data] if the deserialisation fails. - - Consumes [Gas_repr.read_bytes_cost ]. *) - val get : t -> Script_expr_hash.t -> (t * Script.expr) tzresult Lwt.t - - (** [register context value] Register a constant in the global table of constants, - returning the hash and storage bytes consumed. - - Does not type-check the Micheline code being registered, allow potentially - ill-typed Michelson values (see note at top of module in global_constants_storage.mli). - - The constant is stored unexpanded, but it is temporarily expanded at registration - time only to check the expanded version respects the following limits. - - Fails with [Expression_too_deep] if, after fully, expanding all constants, - the expression would contain too many nested levels, that is more than - [Constants_repr.max_allowed_global_constant_depth]. - - Fails with [Badly_formed_constant_expression] if constants are not - well-formed (see declaration of [Badly_formed_constant_expression]) or with - [Nonexistent_global] if a referenced constant does not exist in the table. - - Consumes serialization cost. - Consumes [Gas_repr.write_bytes_cost ] where size is the number - of bytes in the binary serialization provided by [Script.expr_encoding].*) - val register : - t -> Script.expr -> (t * Script_expr_hash.t * Z.t) tzresult Lwt.t - - (** [expand context expr] Replaces every constant in the - given Michelson expression with its value stored in the global table. - - The expansion is applied recursively so that the returned expression - contains no constant. - - Fails with [Badly_formed_constant_expression] if constants are not - well-formed (see declaration of [Badly_formed_constant_expression]) or - with [Nonexistent_global] if a referenced constant does not exist in - the table. *) - val expand : t -> Script.expr -> (t * Script.expr) tzresult Lwt.t - - module Internal_for_tests : sig - (** [node_too_large node] returns true if: - - The number of sub-nodes in the [node] - exceeds [Global_constants_storage.node_size_limit]. - - The sum of the bytes in String, Int, - and Bytes sub-nodes of [node] exceeds - [Global_constants_storage.bytes_size_limit]. - - Otherwise returns false. *) - val node_too_large : Script.node -> bool - - (** [bottom_up_fold_cps initial_accumulator node initial_k f] - folds [node] and all its sub-nodes if any, starting from - [initial_accumulator], using an initial continuation [initial_k]. - At each node, [f] is called to transform the continuation [k] into - the next one. This explicit manipulation of the continuation - is typically useful to short-circuit. - - Notice that a common source of bug is to forget to properly call the - continuation in `f`. *) - val bottom_up_fold_cps : - 'accumulator -> - 'loc Script.michelson_node -> - ('accumulator -> 'loc Script.michelson_node -> 'return) -> - ('accumulator -> - 'loc Script.michelson_node -> - ('accumulator -> 'loc Script.michelson_node -> 'return) -> - 'return) -> - 'return - - (** [expr_to_address_in_context context expr] converts [expr] - into a unique hash represented by a [Script_expr_hash.t]. - - Consumes gas corresponding to the cost of converting [expr] - to bytes and hashing the bytes. *) - val expr_to_address_in_context : - t -> Script.expr -> (t * Script_expr_hash.t) tzresult - end -end - -module Cache : sig - type size = int - - type index = int - - module Admin : sig - type key - - type value - - val pp : Format.formatter -> context -> unit - - val set_cache_layout : context -> size list -> context Lwt.t - - val sync : context -> cache_nonce:Bytes.t -> context Lwt.t - - val clear : context -> context - - val future_cache_expectation : context -> time_in_blocks:int -> context - - val cache_size : context -> cache_index:int -> size option - - val cache_size_limit : context -> cache_index:int -> size option - - val value_of_key : - context -> Context.Cache.key -> Context.Cache.value tzresult Lwt.t - end - - type namespace = private string - - val create_namespace : string -> namespace - - type identifier = string - - module type CLIENT = sig - type cached_value - - val cache_index : index - - val namespace : namespace - - val value_of_identifier : - context -> identifier -> cached_value tzresult Lwt.t - end - - module type INTERFACE = sig - type cached_value - - val update : - context -> identifier -> (cached_value * size) option -> context tzresult - - val find : context -> identifier -> cached_value option tzresult Lwt.t - - val list_identifiers : context -> (string * int) list - - val identifier_rank : context -> string -> int option - - val size : context -> int - - val size_limit : context -> int - end - - val register_exn : - (module CLIENT with type cached_value = 'a) -> - (module INTERFACE with type cached_value = 'a) -end - -module Level : sig - type t = private { - level : Raw_level.t; - level_position : int32; - cycle : Cycle.t; - cycle_position : int32; - expected_commitment : bool; - } - - include BASIC_DATA with type t := t - - val pp_full : Format.formatter -> t -> unit - - type level = t - - val root : context -> level - - val succ : context -> level -> level - - val pred : context -> level -> level option - - val from_raw : context -> Raw_level.t -> level - - (** Fails with [Negative_level_and_offset_sum] if the sum of the raw_level and the offset is negative. *) - val from_raw_with_offset : - context -> offset:int32 -> Raw_level.t -> level tzresult - - (** [add c level i] i must be positive *) - val add : context -> level -> int -> level - - (** [sub c level i] i must be positive *) - val sub : context -> level -> int -> level option - - val diff : level -> level -> int32 - - val current : context -> level - - val last_level_in_cycle : context -> Cycle.t -> level - - val levels_in_cycle : context -> Cycle.t -> level list - - val levels_in_current_cycle : context -> ?offset:int32 -> unit -> level list - - val last_allowed_fork_level : context -> Raw_level.t - - val dawn_of_a_new_cycle : context -> Cycle.t option - - val may_snapshot_rolls : context -> bool -end - -module Fitness : sig - type error += Invalid_fitness | Wrong_fitness | Outdated_fitness - - type raw = Fitness.t - - type t - - val encoding : t Data_encoding.t - - val pp : Format.formatter -> t -> unit - - val create : - level:Raw_level.t -> - locked_round:Round.t option -> - predecessor_round:Round.t -> - round:Round.t -> - t tzresult - - val create_without_locked_round : - level:Raw_level.t -> predecessor_round:Round.t -> round:Round.t -> t - - val to_raw : t -> raw - - val from_raw : raw -> t tzresult - - val round_from_raw : raw -> Round.t tzresult - - val predecessor_round_from_raw : raw -> Round.t tzresult - - val level : t -> Raw_level.t - - val round : t -> Round.t - - val locked_round : t -> Round.t option - - val predecessor_round : t -> Round.t -end - -module Nonce : sig - type t - - type nonce = t - - val encoding : nonce Data_encoding.t - - type unrevealed = {nonce_hash : Nonce_hash.t; delegate : public_key_hash} - - val record_hash : context -> unrevealed -> context tzresult Lwt.t - - val reveal : context -> Level.t -> nonce -> context tzresult Lwt.t - - type status = Unrevealed of unrevealed | Revealed of nonce - - val get : context -> Level.t -> status tzresult Lwt.t - - val of_bytes : bytes -> nonce tzresult - - val hash : nonce -> Nonce_hash.t - - val check_hash : nonce -> Nonce_hash.t -> bool -end - -module Seed : sig - type seed - - type error += Unknown of {oldest : Cycle.t; cycle : Cycle.t; latest : Cycle.t} - - val for_cycle : context -> Cycle.t -> seed tzresult Lwt.t - - val cycle_end : - context -> Cycle.t -> (context * Nonce.unrevealed list) tzresult Lwt.t - - val seed_encoding : seed Data_encoding.t -end - -module Big_map : sig - module Id : sig - type t - - val encoding : t Data_encoding.t - - val rpc_arg : t RPC_arg.arg - - (** In the protocol, to be used in parse_data only *) - val parse_z : Z.t -> t - - (** In the protocol, to be used in unparse_data only *) - val unparse_to_z : t -> Z.t - end - - val fresh : temporary:bool -> context -> (context * Id.t) tzresult Lwt.t - - val mem : - context -> Id.t -> Script_expr_hash.t -> (context * bool) tzresult Lwt.t - - val get_opt : - context -> - Id.t -> - Script_expr_hash.t -> - (context * Script.expr option) tzresult Lwt.t - - val exists : - context -> - Id.t -> - (context * (Script.expr * Script.expr) option) tzresult Lwt.t - - (** [list_values ?offset ?length ctxt id] lists all values stored in big map [id]. - - The first [offset] values are ignored (if passed). Negative offsets are treated as [0]. - - There will be no more than [length] values in the result list (if passed). - Negative values are treated as [0]. - - The returned {!context} takes into account gas consumption of loading values. - *) - val list_values : - ?offset:int -> - ?length:int -> - context -> - Id.t -> - (context * Script.expr list) tzresult Lwt.t - - type update = { - key : Script_repr.expr; - key_hash : Script_expr_hash.t; - value : Script_repr.expr option; - } - - type updates = update list - - type alloc = {key_type : Script_repr.expr; value_type : Script_repr.expr} -end - -module Sapling : sig - module Id : sig - type t - - val encoding : t Data_encoding.t - - val rpc_arg : t RPC_arg.arg - - val parse_z : Z.t -> t (* To be used in parse_data only *) - - val unparse_to_z : t -> Z.t (* To be used in unparse_data only *) - end - - val fresh : temporary:bool -> context -> (context * Id.t) tzresult Lwt.t - - type diff = private { - commitments_and_ciphertexts : - (Sapling.Commitment.t * Sapling.Ciphertext.t) list; - nullifiers : Sapling.Nullifier.t list; - } - - val diff_encoding : diff Data_encoding.t - - module Memo_size : sig - type t - - val encoding : t Data_encoding.t - - val equal : t -> t -> bool - - val parse_z : Z.t -> (t, string) result - - val unparse_to_z : t -> Z.t - end - - type state = private {id : Id.t option; diff : diff; memo_size : Memo_size.t} - - (** - Returns a [state] with fields filled accordingly. - [id] should only be used by [extract_lazy_storage_updates]. - *) - val empty_state : ?id:Id.t -> memo_size:Memo_size.t -> unit -> state - - type transaction = Sapling.UTXO.transaction - - val transaction_encoding : transaction Data_encoding.t - - val transaction_get_memo_size : transaction -> Memo_size.t option - - (** - Tries to fetch a state from the storage. - *) - val state_from_id : context -> Id.t -> (state * context) tzresult Lwt.t - - val rpc_arg : Id.t RPC_arg.t - - type root = Sapling.Hash.t - - val root_encoding : root Data_encoding.t - - (* Function exposed as RPC. Returns the root and a diff of a state starting - from an optional offset which is zero by default. *) - val get_diff : - context -> - Id.t -> - ?offset_commitment:Int64.t -> - ?offset_nullifier:Int64.t -> - unit -> - (root * diff) tzresult Lwt.t - - val verify_update : - context -> - state -> - transaction -> - string -> - (context * (Int64.t * state) option) tzresult Lwt.t - - type alloc = {memo_size : Memo_size.t} - - type updates = diff - - val transaction_in_memory_size : transaction -> Cache_memory_helpers.sint - - val diff_in_memory_size : diff -> Cache_memory_helpers.sint -end - -module Lazy_storage : sig - module Kind : sig - type ('id, 'alloc, 'updates) t = - | Big_map : (Big_map.Id.t, Big_map.alloc, Big_map.updates) t - | Sapling_state : (Sapling.Id.t, Sapling.alloc, Sapling.updates) t - end - - module IdSet : sig - type t - - type 'acc fold_f = {f : 'i 'a 'u. ('i, 'a, 'u) Kind.t -> 'i -> 'acc -> 'acc} - - val empty : t - - val mem : ('i, 'a, 'u) Kind.t -> 'i -> t -> bool - - val add : ('i, 'a, 'u) Kind.t -> 'i -> t -> t - - val diff : t -> t -> t - - val fold : ('i, 'a, 'u) Kind.t -> ('i -> 'acc -> 'acc) -> t -> 'acc -> 'acc - - val fold_all : 'acc fold_f -> t -> 'acc -> 'acc - end - - type ('id, 'alloc) init = Existing | Copy of {src : 'id} | Alloc of 'alloc - - type ('id, 'alloc, 'updates) diff = - | Remove - | Update of {init : ('id, 'alloc) init; updates : 'updates} - - type diffs_item - - val make : ('i, 'a, 'u) Kind.t -> 'i -> ('i, 'a, 'u) diff -> diffs_item - - type diffs = diffs_item list - - val encoding : diffs Data_encoding.t - - val diffs_in_memory_size : diffs -> Cache_memory_helpers.nodes_and_size - - val legacy_big_map_diff_encoding : diffs Data_encoding.t - - val cleanup_temporaries : context -> context Lwt.t - - val apply : t -> diffs -> (t * Z.t) tzresult Lwt.t -end - -module Contract : sig - include BASIC_DATA - - type contract = t - - val in_memory_size : t -> Cache_memory_helpers.sint - - val rpc_arg : contract RPC_arg.arg - - val to_b58check : contract -> string - - val of_b58check : string -> contract tzresult - - val implicit_contract : public_key_hash -> contract - - val is_implicit : contract -> public_key_hash option - - val exists : context -> contract -> bool tzresult Lwt.t - - val must_exist : context -> contract -> unit tzresult Lwt.t - - val allocated : context -> contract -> bool tzresult Lwt.t - - val must_be_allocated : context -> contract -> unit tzresult Lwt.t - - val list : context -> contract list Lwt.t - - val get_manager_key : - ?error:error -> context -> public_key_hash -> public_key tzresult Lwt.t - - val is_manager_key_revealed : - context -> public_key_hash -> bool tzresult Lwt.t - - val reveal_manager_key : - context -> public_key_hash -> public_key -> context tzresult Lwt.t - - val get_script_code : - context -> contract -> (context * Script.lazy_expr option) tzresult Lwt.t - - val get_script : - context -> contract -> (context * Script.t option) tzresult Lwt.t - - val get_storage : - context -> contract -> (context * Script.expr option) tzresult Lwt.t - - val get_counter : context -> public_key_hash -> Z.t tzresult Lwt.t - - val get_balance : context -> contract -> Tez.t tzresult Lwt.t - - val get_balance_carbonated : - context -> contract -> (context * Tez.t) tzresult Lwt.t - - val init_origination_nonce : context -> Operation_hash.t -> context - - val unset_origination_nonce : context -> context - - val fresh_contract_from_current_nonce : context -> (context * t) tzresult - - val originated_from_current_nonce : - since:context -> until:context -> contract list tzresult Lwt.t - - module Legacy_big_map_diff : sig - type item = private - | Update of { - big_map : Z.t; - diff_key : Script.expr; - diff_key_hash : Script_expr_hash.t; - diff_value : Script.expr option; - } - | Clear of Z.t - | Copy of {src : Z.t; dst : Z.t} - | Alloc of { - big_map : Z.t; - key_type : Script.expr; - value_type : Script.expr; - } - - type t = private item list - - val of_lazy_storage_diff : Lazy_storage.diffs -> t - end - - type error += Balance_too_low of contract * Tez.t * Tez.t - - val update_script_storage : - context -> - contract -> - Script.expr -> - Lazy_storage.diffs option -> - context tzresult Lwt.t - - val used_storage_space : context -> t -> Z.t tzresult Lwt.t - - val increment_counter : context -> public_key_hash -> context tzresult Lwt.t - - val check_counter_increment : - context -> public_key_hash -> Z.t -> unit tzresult Lwt.t - - (**/**) - - (* Only for testing *) - type origination_nonce - - val initial_origination_nonce : Operation_hash.t -> origination_nonce - - val originated_contract : origination_nonce -> contract - - val raw_originate : - context -> - prepaid_bootstrap_storage:bool -> - t -> - script:Script.t * Lazy_storage.diffs option -> - context tzresult Lwt.t -end - -module Receipt : sig - type balance = - | Contract of Contract.t - | Legacy_rewards of Signature.Public_key_hash.t * Cycle.t - | Block_fees - | Legacy_deposits of Signature.Public_key_hash.t * Cycle.t - | Deposits of public_key_hash - | Nonce_revelation_rewards - | Double_signing_evidence_rewards - | Endorsing_rewards - | Baking_rewards - | Baking_bonuses - | Legacy_fees of Signature.Public_key_hash.t * Cycle.t - | Storage_fees - | Double_signing_punishments - | Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool - | Liquidity_baking_subsidies - | Burned - | Commitments of Blinded_public_key_hash.t - | Bootstrap - | Invoice - | Initial_commitments - | Minted - - val compare_balance : balance -> balance -> int - - type balance_update = Debited of Tez.t | Credited of Tez.t - - type update_origin = - | Block_application - | Protocol_migration - | Subsidy - | Simulation - - val compare_update_origin : update_origin -> update_origin -> int - - type balance_updates = (balance * balance_update * update_origin) list - - val balance_updates_encoding : balance_updates Data_encoding.t - - val group_balance_updates : balance_updates -> balance_updates tzresult -end - -module Delegate : sig - val init : - context -> - Contract.t -> - Signature.Public_key_hash.t -> - context tzresult Lwt.t - - val find : context -> Contract.t -> public_key_hash option tzresult Lwt.t - - val set : - context -> Contract.t -> public_key_hash option -> context tzresult Lwt.t - - val frozen_deposits_limit : - context -> Signature.Public_key_hash.t -> Tez.t option tzresult Lwt.t - - val set_frozen_deposits_limit : - context -> Signature.Public_key_hash.t -> Tez.t option -> context Lwt.t - - val fold : - context -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(public_key_hash -> 'a -> 'a Lwt.t) -> - 'a Lwt.t - - val list : context -> public_key_hash list Lwt.t - - val check_delegate : context -> public_key_hash -> unit tzresult Lwt.t - - type participation_info = { - expected_cycle_activity : int; - minimal_cycle_activity : int; - missed_slots : int; - missed_levels : int; - remaining_allowed_missed_slots : int; - expected_endorsing_rewards : Tez.t; - } - - val delegate_participation_info : - context -> public_key_hash -> participation_info tzresult Lwt.t - - val cycle_end : - context -> - Cycle.t -> - Nonce.unrevealed list -> - (context * Receipt.balance_updates * Signature.Public_key_hash.t list) - tzresult - Lwt.t - - val already_slashed_for_double_endorsing : - context -> public_key_hash -> Level.t -> bool tzresult Lwt.t - - val already_slashed_for_double_baking : - context -> public_key_hash -> Level.t -> bool tzresult Lwt.t - - val punish_double_endorsing : - context -> - public_key_hash -> - Level.t -> - (context * Tez.t * Receipt.balance_updates) tzresult Lwt.t - - val punish_double_baking : - context -> - public_key_hash -> - Level.t -> - (context * Tez.t * Receipt.balance_updates) tzresult Lwt.t - - val full_balance : context -> public_key_hash -> Tez.t tzresult Lwt.t - - type level_participation = Participated | Didn't_participate - - val record_baking_activity_and_pay_rewards_and_fees : - context -> - payload_producer:Signature.Public_key_hash.t -> - block_producer:Signature.Public_key_hash.t -> - baking_reward:Tez.t -> - reward_bonus:Tez.t option -> - (context * Receipt.balance_updates) tzresult Lwt.t - - val record_endorsing_participation : - context -> - delegate:Signature.Public_key_hash.t -> - participation:level_participation -> - endorsing_power:int -> - context tzresult Lwt.t - - type deposits = {initial_amount : Tez.t; current_amount : Tez.t} - - val frozen_deposits : context -> public_key_hash -> deposits tzresult Lwt.t - - val staking_balance : - context -> Signature.Public_key_hash.t -> Tez.t tzresult Lwt.t - - val delegated_contracts : - context -> Signature.Public_key_hash.t -> Contract.t list Lwt.t - - val delegated_balance : - context -> Signature.Public_key_hash.t -> Tez.t tzresult Lwt.t - - val registered : context -> Signature.Public_key_hash.t -> bool tzresult Lwt.t - - val deactivated : - context -> Signature.Public_key_hash.t -> bool tzresult Lwt.t - - val grace_period : - context -> Signature.Public_key_hash.t -> Cycle.t tzresult Lwt.t - - val pubkey : context -> public_key_hash -> public_key tzresult Lwt.t - - val prepare_stake_distribution : context -> context tzresult Lwt.t -end - -module Voting_period : sig - type kind = Proposal | Exploration | Cooldown | Promotion | Adoption - - val kind_encoding : kind Data_encoding.encoding - - val pp_kind : Format.formatter -> kind -> unit - - (* This type should be abstract *) - type voting_period = private { - index : int32; - kind : kind; - start_position : int32; - } - - type t = voting_period - - include BASIC_DATA with type t := t - - val encoding : voting_period Data_encoding.t - - val pp : Format.formatter -> voting_period -> unit - - val reset : context -> context tzresult Lwt.t - - val succ : context -> context tzresult Lwt.t - - val get_current : context -> voting_period tzresult Lwt.t - - val get_current_kind : context -> kind tzresult Lwt.t - - val is_last_block : context -> bool tzresult Lwt.t - - type info = {voting_period : t; position : int32; remaining : int32} - - val info_encoding : info Data_encoding.t - - val pp_info : Format.formatter -> info -> unit - - val get_rpc_current_info : context -> info tzresult Lwt.t - - val get_rpc_succ_info : context -> info tzresult Lwt.t -end - -module Vote : sig - type proposal = Protocol_hash.t - - val record_proposal : - context -> Protocol_hash.t -> public_key_hash -> context tzresult Lwt.t - - val get_proposals : context -> int32 Protocol_hash.Map.t tzresult Lwt.t - - val clear_proposals : context -> context Lwt.t - - val recorded_proposal_count_for_delegate : - context -> public_key_hash -> int tzresult Lwt.t - - val listings_encoding : - (Signature.Public_key_hash.t * int32) list Data_encoding.t - - val update_listings : context -> context tzresult Lwt.t - - val listing_size : context -> int32 tzresult Lwt.t - - val in_listings : context -> public_key_hash -> bool Lwt.t - - val get_listings : context -> (public_key_hash * int32) list Lwt.t - - type ballot = Yay | Nay | Pass - - val get_voting_power_free : - context -> Signature.Public_key_hash.t -> int32 tzresult Lwt.t - - val get_voting_power : - context -> Signature.Public_key_hash.t -> (context * int32) tzresult Lwt.t - - val get_total_voting_power_free : context -> int32 tzresult Lwt.t - - val get_total_voting_power : context -> (context * int32) tzresult Lwt.t - - val ballot_encoding : ballot Data_encoding.t - - type ballots = {yay : int32; nay : int32; pass : int32} - - val ballots_encoding : ballots Data_encoding.t - - val has_recorded_ballot : context -> public_key_hash -> bool Lwt.t - - val record_ballot : - context -> public_key_hash -> ballot -> context tzresult Lwt.t - - val get_ballots : context -> ballots tzresult Lwt.t - - val get_ballot_list : - context -> (Signature.Public_key_hash.t * ballot) list Lwt.t - - val clear_ballots : context -> context Lwt.t - - val get_current_quorum : context -> int32 tzresult Lwt.t - - val get_participation_ema : context -> int32 tzresult Lwt.t - - val set_participation_ema : context -> int32 -> context tzresult Lwt.t - - val get_current_proposal : context -> proposal tzresult Lwt.t - - val find_current_proposal : context -> proposal option tzresult Lwt.t - - val init_current_proposal : context -> proposal -> context tzresult Lwt.t - - val clear_current_proposal : context -> context tzresult Lwt.t -end - -module Block_payload : sig - val hash : - predecessor:Block_hash.t -> - Round.t -> - Operation_list_hash.t -> - Block_payload_hash.t -end - -module Block_header : sig - type contents = { - payload_hash : Block_payload_hash.t; - payload_round : Round.t; - seed_nonce_hash : Nonce_hash.t option; - proof_of_work_nonce : bytes; - liquidity_baking_escape_vote : bool; - } - - type protocol_data = {contents : contents; signature : Signature.t} - - type t = {shell : Block_header.shell_header; protocol_data : protocol_data} - - type block_header = t - - type raw = Block_header.t - - type shell_header = Block_header.shell_header - - type block_watermark = Block_header of Chain_id.t - - val to_watermark : block_watermark -> Signature.watermark - - val of_watermark : Signature.watermark -> block_watermark option - - module Proof_of_work : sig - val check_hash : Block_hash.t -> int64 -> bool - - val check_header_proof_of_work_stamp : - shell_header -> contents -> int64 -> bool - - val check_proof_of_work_stamp : - proof_of_work_threshold:int64 -> block_header -> unit tzresult - end - - val raw : block_header -> raw - - val hash : block_header -> Block_hash.t - - val hash_raw : raw -> Block_hash.t - - val encoding : block_header Data_encoding.encoding - - val raw_encoding : raw Data_encoding.t - - val contents_encoding : contents Data_encoding.t - - val unsigned_encoding : (shell_header * contents) Data_encoding.t - - val protocol_data_encoding : protocol_data Data_encoding.encoding - - val shell_header_encoding : shell_header Data_encoding.encoding - - (** The maximum size of block headers in bytes *) - val max_header_length : int - - type error += - | Invalid_block_signature of Block_hash.t * Signature.Public_key_hash.t - | Invalid_stamp - | Invalid_payload_hash of { - expected : Block_payload_hash.t; - provided : Block_payload_hash.t; - } - | Locked_round_after_block_round of { - locked_round : Round_repr.t; - round : Round_repr.t; - } - | Invalid_payload_round of { - payload_round : Round_repr.t; - round : Round_repr.t; - } - | Insufficient_locked_round_evidence of { - voting_power : int; - consensus_threshold : int; - } - | Invalid_commitment of {expected : bool} - - val check_timestamp : - Round.round_durations -> - timestamp:Time.t -> - round:Round.t -> - predecessor_timestamp:Time.t -> - predecessor_round:Round.t -> - unit tzresult - - val check_signature : - t -> Chain_id.t -> Signature.Public_key.t -> unit tzresult - - val begin_validate_block_header : - block_header:t -> - chain_id:Chain_id.t -> - predecessor_timestamp:Time.t -> - predecessor_round:Round.t -> - fitness:Fitness.t -> - timestamp:Time.t -> - delegate_pk:Signature.public_key -> - round_durations:Round.round_durations -> - proof_of_work_threshold:int64 -> - expected_commitment:bool -> - unit tzresult - - type locked_round_evidence = { - preendorsement_round : Round.t; - preendorsement_count : int; - } - - type checkable_payload_hash = - | No_check - | Expected_payload_hash of Block_payload_hash.t - - val finalize_validate_block_header : - block_header_contents:contents -> - round:Round.t -> - fitness:Fitness.t -> - checkable_payload_hash:checkable_payload_hash -> - locked_round_evidence:locked_round_evidence option -> - consensus_threshold:int -> - unit tzresult -end - -module Kind : sig - type preendorsement_consensus_kind = Preendorsement_consensus_kind - - type endorsement_consensus_kind = Endorsement_consensus_kind - - type 'a consensus = - | Preendorsement_kind : preendorsement_consensus_kind consensus - | Endorsement_kind : endorsement_consensus_kind consensus - - type preendorsement = preendorsement_consensus_kind consensus - - type endorsement = endorsement_consensus_kind consensus - - type seed_nonce_revelation = Seed_nonce_revelation_kind - - type 'a double_consensus_operation_evidence = - | Double_consensus_operation_evidence - - type double_endorsement_evidence = - endorsement_consensus_kind double_consensus_operation_evidence - - type double_preendorsement_evidence = - preendorsement_consensus_kind double_consensus_operation_evidence - - type double_baking_evidence = Double_baking_evidence_kind - - type activate_account = Activate_account_kind - - type proposals = Proposals_kind - - type ballot = Ballot_kind - - type reveal = Reveal_kind - - type transaction = Transaction_kind - - type origination = Origination_kind - - type delegation = Delegation_kind - - type set_deposits_limit = Set_deposits_limit_kind - - type failing_noop = Failing_noop_kind - - type register_global_constant = Register_global_constant_kind - - type 'a manager = - | Reveal_manager_kind : reveal manager - | Transaction_manager_kind : transaction manager - | Origination_manager_kind : origination manager - | Delegation_manager_kind : delegation manager - | Register_global_constant_manager_kind : register_global_constant manager - | Set_deposits_limit_manager_kind : set_deposits_limit manager -end - -type 'a consensus_operation_type = - | Endorsement : Kind.endorsement consensus_operation_type - | Preendorsement : Kind.preendorsement consensus_operation_type - -val pp_operation_kind : - Format.formatter -> 'kind consensus_operation_type -> unit - -type consensus_content = { - slot : Slot.t; - level : Raw_level.t; - (* The level is not required to validate an endorsement when it corresponds - to the current payload, but if we want to filter endorsements, we need - the level. *) - round : Round.t; - block_payload_hash : Block_payload_hash.t; -} - -val consensus_content_encoding : consensus_content Data_encoding.t - -val pp_consensus_content : Format.formatter -> consensus_content -> unit - -type 'kind operation = { - shell : Operation.shell_header; - protocol_data : 'kind protocol_data; -} - -and 'kind protocol_data = { - contents : 'kind contents_list; - signature : Signature.t option; -} - -and _ contents_list = - | Single : 'kind contents -> 'kind contents_list - | Cons : - 'kind Kind.manager contents * 'rest Kind.manager contents_list - -> ('kind * 'rest) Kind.manager contents_list - -and _ contents = - | Preendorsement : consensus_content -> Kind.preendorsement contents - | Endorsement : consensus_content -> Kind.endorsement contents - | Seed_nonce_revelation : { - level : Raw_level.t; - nonce : Nonce.t; - } - -> Kind.seed_nonce_revelation contents - | Double_preendorsement_evidence : { - op1 : Kind.preendorsement operation; - op2 : Kind.preendorsement operation; - } - -> Kind.double_preendorsement_evidence contents - | Double_endorsement_evidence : { - op1 : Kind.endorsement operation; - op2 : Kind.endorsement operation; - } - -> Kind.double_endorsement_evidence contents - | Double_baking_evidence : { - bh1 : Block_header.t; - bh2 : Block_header.t; - } - -> Kind.double_baking_evidence contents - | Activate_account : { - id : Ed25519.Public_key_hash.t; - activation_code : Blinded_public_key_hash.activation_code; - } - -> Kind.activate_account contents - | Proposals : { - source : Signature.Public_key_hash.t; - period : int32; - proposals : Protocol_hash.t list; - } - -> Kind.proposals contents - | Ballot : { - source : Signature.Public_key_hash.t; - period : int32; - proposal : Protocol_hash.t; - ballot : Vote.ballot; - } - -> Kind.ballot contents - | Failing_noop : string -> Kind.failing_noop contents - | Manager_operation : { - source : Signature.Public_key_hash.t; - fee : Tez.tez; - counter : counter; - operation : 'kind manager_operation; - gas_limit : Gas.Arith.integral; - storage_limit : Z.t; - } - -> 'kind Kind.manager contents - -and _ manager_operation = - | Reveal : Signature.Public_key.t -> Kind.reveal manager_operation - | Transaction : { - amount : Tez.tez; - parameters : Script.lazy_expr; - entrypoint : string; - destination : Contract.contract; - } - -> Kind.transaction manager_operation - | Origination : { - delegate : Signature.Public_key_hash.t option; - script : Script.t; - credit : Tez.tez; - preorigination : Contract.t option; - } - -> Kind.origination manager_operation - | Delegation : - Signature.Public_key_hash.t option - -> Kind.delegation manager_operation - | Register_global_constant : { - value : Script.lazy_expr; - } - -> Kind.register_global_constant manager_operation - | Set_deposits_limit : - Tez.t option - -> Kind.set_deposits_limit manager_operation - -and counter = Z.t - -type 'kind internal_operation = { - source : Contract.contract; - operation : 'kind manager_operation; - nonce : int; -} - -type packed_manager_operation = - | Manager : 'kind manager_operation -> packed_manager_operation - -type packed_contents = Contents : 'kind contents -> packed_contents - -type packed_contents_list = - | Contents_list : 'kind contents_list -> packed_contents_list - -type packed_protocol_data = - | Operation_data : 'kind protocol_data -> packed_protocol_data - -type packed_operation = { - shell : Operation.shell_header; - protocol_data : packed_protocol_data; -} - -type packed_internal_operation = - | Internal_operation : 'kind internal_operation -> packed_internal_operation - -val manager_kind : 'kind manager_operation -> 'kind Kind.manager - -module Operation : sig - type nonrec 'kind contents = 'kind contents - - type nonrec packed_contents = packed_contents - - val contents_encoding : packed_contents Data_encoding.t - - type nonrec 'kind protocol_data = 'kind protocol_data - - type nonrec packed_protocol_data = packed_protocol_data - - type consensus_watermark = - | Endorsement of Chain_id.t - | Preendorsement of Chain_id.t - - val to_watermark : consensus_watermark -> Signature.watermark - - val of_watermark : Signature.watermark -> consensus_watermark option - - val protocol_data_encoding : packed_protocol_data Data_encoding.t - - val unsigned_encoding : - (Operation.shell_header * packed_contents_list) Data_encoding.t - - type raw = Operation.t = {shell : Operation.shell_header; proto : bytes} - - val raw_encoding : raw Data_encoding.t - - val contents_list_encoding : packed_contents_list Data_encoding.t - - type 'kind t = 'kind operation = { - shell : Operation.shell_header; - protocol_data : 'kind protocol_data; - } - - type nonrec packed = packed_operation - - val encoding : packed Data_encoding.t - - val raw : _ operation -> raw - - val hash : _ operation -> Operation_hash.t - - val hash_raw : raw -> Operation_hash.t - - val hash_packed : packed_operation -> Operation_hash.t - - val acceptable_passes : packed_operation -> int list - - type error += Missing_signature (* `Permanent *) - - type error += Invalid_signature (* `Permanent *) - - val check_signature : public_key -> Chain_id.t -> _ operation -> unit tzresult - - val internal_operation_encoding : packed_internal_operation Data_encoding.t - - val packed_internal_operation_in_memory_size : - packed_internal_operation -> Cache_memory_helpers.nodes_and_size - - val pack : 'kind operation -> packed_operation - - type ('a, 'b) eq = Eq : ('a, 'a) eq - - val equal : 'a operation -> 'b operation -> ('a, 'b) eq option - - module Encoding : sig - type 'b case = - | Case : { - tag : int; - name : string; - encoding : 'a Data_encoding.t; - select : packed_contents -> 'b contents option; - proj : 'b contents -> 'a; - inj : 'a -> 'b contents; - } - -> 'b case - - val preendorsement_case : Kind.preendorsement case - - val endorsement_case : Kind.endorsement case - - val seed_nonce_revelation_case : Kind.seed_nonce_revelation case - - val double_preendorsement_evidence_case : - Kind.double_preendorsement_evidence case - - val double_endorsement_evidence_case : Kind.double_endorsement_evidence case - - val double_baking_evidence_case : Kind.double_baking_evidence case - - val activate_account_case : Kind.activate_account case - - val proposals_case : Kind.proposals case - - val ballot_case : Kind.ballot case - - val failing_noop_case : Kind.failing_noop case - - val reveal_case : Kind.reveal Kind.manager case - - val transaction_case : Kind.transaction Kind.manager case - - val origination_case : Kind.origination Kind.manager case - - val delegation_case : Kind.delegation Kind.manager case - - val register_global_constant_case : - Kind.register_global_constant Kind.manager case - - val set_deposits_limit_case : Kind.set_deposits_limit Kind.manager case - - module Manager_operations : sig - type 'b case = - | MCase : { - tag : int; - name : string; - encoding : 'a Data_encoding.t; - select : packed_manager_operation -> 'kind manager_operation option; - proj : 'kind manager_operation -> 'a; - inj : 'a -> 'kind manager_operation; - } - -> 'kind case - - val reveal_case : Kind.reveal case - - val transaction_case : Kind.transaction case - - val origination_case : Kind.origination case - - val delegation_case : Kind.delegation case - - val register_global_constant_case : Kind.register_global_constant case - - val set_deposits_limit_case : Kind.set_deposits_limit case - end - end - - val of_list : packed_contents list -> packed_contents_list tzresult - - val to_list : packed_contents_list -> packed_contents list -end - -module Stake_distribution : sig - val snapshot : context -> context tzresult Lwt.t - - val baking_rights_owner : - context -> - Level.t -> - round:Round.t -> - (context * Slot.t * (public_key * public_key_hash)) tzresult Lwt.t - - val slot_owner : - context -> - Level.t -> - Slot.t -> - (context * (public_key * public_key_hash)) tzresult Lwt.t - - val delegate_pubkey : context -> public_key_hash -> public_key tzresult Lwt.t - - val get_staking_balance : - context -> Signature.Public_key_hash.t -> Tez.t tzresult Lwt.t -end - -module Commitment : sig - type t = { - blinded_public_key_hash : Blinded_public_key_hash.t; - amount : Tez.tez; - } - - val encoding : t Data_encoding.t -end - -module Bootstrap : sig - val cycle_end : context -> Cycle.t -> context tzresult Lwt.t -end - -module Migration : sig - type origination_result = { - balance_updates : Receipt.balance_updates; - originated_contracts : Contract.t list; - storage_size : Z.t; - paid_storage_size_diff : Z.t; - } -end - -(** Create an [Alpha_context.t] from an untyped context (first block in the chain only). *) -val prepare_first_block : - Context.t -> - typecheck: - (context -> - Script.t -> - ((Script.t * Lazy_storage.diffs option) * context) tzresult Lwt.t) -> - level:Int32.t -> - timestamp:Time.t -> - context tzresult Lwt.t - -(** Create an [Alpha_context.t] from an untyped context. *) -val prepare : - Context.t -> - level:Int32.t -> - predecessor_timestamp:Time.t -> - timestamp:Time.t -> - (context * Receipt.balance_updates * Migration.origination_result list) - tzresult - Lwt.t - -val activate : context -> Protocol_hash.t -> context Lwt.t - -val reset_internal_nonce : context -> context - -val fresh_internal_nonce : context -> (context * int) tzresult - -val record_internal_nonce : context -> int -> context - -val internal_nonce_already_recorded : context -> int -> bool - -val description : context Storage_description.t - -(** Finalize an {{!t} [Alpha_context.t]}, producing a [validation_result]. - *) -val finalize : - ?commit_message:string -> context -> Fitness.raw -> Updater.validation_result - -(** Should only be used by [Main.current_context] to return a context usable for RPCs *) -val current_context : context -> Context.t - -val record_non_consensus_operation_hash : context -> Operation_hash.t -> context - -val non_consensus_operations : context -> Operation_hash.t list - -module Parameters : sig - type bootstrap_account = { - public_key_hash : public_key_hash; - public_key : public_key option; - amount : Tez.t; - } - - type bootstrap_contract = { - delegate : public_key_hash option; - amount : Tez.t; - script : Script.t; - } - - type t = { - bootstrap_accounts : bootstrap_account list; - bootstrap_contracts : bootstrap_contract list; - commitments : Commitment.t list; - constants : Constants.parametric; - security_deposit_ramp_up_cycles : int option; - no_reward_cycles : int option; - } - - val encoding : t Data_encoding.t -end - -module Liquidity_baking : sig - val get_cpmm_address : context -> Contract.t tzresult Lwt.t - - type escape_ema = Int32.t - - val on_subsidy_allowed : - context -> - escape_vote:bool -> - (context -> Contract.t -> (context * 'a list) tzresult Lwt.t) -> - (context * 'a list * escape_ema) tzresult Lwt.t -end - -(** This module re-exports functions from [Ticket_storage]. See - documentation of the functions there. - *) -module Ticket_balance : sig - type key_hash - - val script_expr_hash_of_key_hash : key_hash -> Script_expr_hash.t - - val make_key_hash : - context -> - ticketer:Script.node -> - typ:Script.node -> - contents:Script.node -> - owner:Script.node -> - (key_hash * context) tzresult - - val adjust_balance : - context -> key_hash -> delta:Z.t -> (Z.t * context) tzresult Lwt.t - - val get_balance : context -> key_hash -> (Z.t option * context) tzresult Lwt.t -end - -module First_level_of_tenderbake : sig - val get : context -> Raw_level.t tzresult Lwt.t -end - -module Consensus : sig - include - Raw_context.CONSENSUS - with type t := t - and type slot := Slot.t - and type 'a slot_map := 'a Slot.Map.t - and type slot_set := Slot.Set.t - and type round := Round.t - - val store_endorsement_branch : - context -> Block_hash.t * Block_payload_hash.t -> context Lwt.t - - val store_grand_parent_branch : - context -> Block_hash.t * Block_payload_hash.t -> context Lwt.t -end - -(** See 'token.mli' for more explanation. *) -module Token : sig - type container = - [ `Contract of Contract.t - | `Collected_commitments of Blinded_public_key_hash.t - | `Delegate_balance of Signature.Public_key_hash.t - | `Frozen_deposits of Signature.Public_key_hash.t - | `Block_fees - | `Legacy_deposits of Signature.Public_key_hash.t * Cycle.t - | `Legacy_fees of Signature.Public_key_hash.t * Cycle.t - | `Legacy_rewards of Signature.Public_key_hash.t * Cycle.t ] - - type source = - [ `Invoice - | `Bootstrap - | `Initial_commitments - | `Revelation_rewards - | `Double_signing_evidence_rewards - | `Endorsing_rewards - | `Baking_rewards - | `Baking_bonuses - | `Minted - | `Liquidity_baking_subsidies - | container ] - - type sink = - [ `Storage_fees - | `Double_signing_punishments - | `Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool - | `Burned - | container ] - - val allocated : context -> container -> bool tzresult Lwt.t - - val balance : context -> container -> Tez.t tzresult Lwt.t - - val transfer_n : - ?origin:Receipt.update_origin -> - context -> - ([< source] * Tez.t) list -> - [< sink] -> - (context * Receipt.balance_updates) tzresult Lwt.t - - val transfer : - ?origin:Receipt.update_origin -> - context -> - [< source] -> - [< sink] -> - Tez.t -> - (context * Receipt.balance_updates) tzresult Lwt.t -end - -module Fees : sig - val record_paid_storage_space : - context -> Contract.t -> (context * Z.t * Z.t) tzresult Lwt.t - - val record_global_constant_storage_space : context -> Z.t -> context * Z.t - - val burn_storage_fees : - ?origin:Receipt.update_origin -> - context -> - storage_limit:Z.t -> - payer:Token.source -> - Z.t -> - (context * Z.t * Receipt.balance_updates) tzresult Lwt.t - - val burn_origination_fees : - ?origin:Receipt.update_origin -> - context -> - storage_limit:Z.t -> - payer:Token.source -> - (context * Z.t * Receipt.balance_updates) tzresult Lwt.t - - type error += Cannot_pay_storage_fee (* `Temporary *) - - type error += Operation_quota_exceeded (* `Temporary *) - - type error += Storage_limit_too_high (* `Permanent *) - - val check_storage_limit : context -> storage_limit:Z.t -> unit tzresult -end diff --git a/src/proto_012_Psithaca/lib_protocol/alpha_services.ml b/src/proto_012_Psithaca/lib_protocol/alpha_services.ml deleted file mode 100644 index 29832657ac27..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/alpha_services.ml +++ /dev/null @@ -1,194 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -let custom_root = RPC_path.open_root - -module Seed = struct - module S = struct - open Data_encoding - - let seed = - RPC_service.post_service - ~description:"Seed of the cycle to which the block belongs." - ~query:RPC_query.empty - ~input:empty - ~output:Seed.seed_encoding - RPC_path.(custom_root / "context" / "seed") - end - - let () = - let open Services_registration in - register0 ~chunked:false S.seed (fun ctxt () () -> - let l = Level.current ctxt in - Seed.for_cycle ctxt l.cycle) - - let get ctxt block = RPC_context.make_call0 S.seed ctxt block () () -end - -module Nonce = struct - type info = Revealed of Nonce.t | Missing of Nonce_hash.t | Forgotten - - let info_encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Revealed" - (obj1 (req "nonce" Nonce.encoding)) - (function Revealed nonce -> Some nonce | _ -> None) - (fun nonce -> Revealed nonce); - case - (Tag 1) - ~title:"Missing" - (obj1 (req "hash" Nonce_hash.encoding)) - (function Missing nonce -> Some nonce | _ -> None) - (fun nonce -> Missing nonce); - case - (Tag 2) - ~title:"Forgotten" - empty - (function Forgotten -> Some () | _ -> None) - (fun () -> Forgotten); - ] - - module S = struct - let get = - RPC_service.get_service - ~description:"Info about the nonce of a previous block." - ~query:RPC_query.empty - ~output:info_encoding - RPC_path.(custom_root / "context" / "nonces" /: Raw_level.rpc_arg) - end - - let register () = - let open Services_registration in - register1 ~chunked:false S.get (fun ctxt raw_level () () -> - let level = Level.from_raw ctxt raw_level in - Nonce.get ctxt level >|= function - | Ok (Revealed nonce) -> ok (Revealed nonce) - | Ok (Unrevealed {nonce_hash; _}) -> ok (Missing nonce_hash) - | Error _ -> ok Forgotten) - - let get ctxt block level = RPC_context.make_call1 S.get ctxt block level () () -end - -module Contract = Contract_services -module Constants = Constants_services -module Delegate = Delegate_services -module Voting = Voting_services -module Sapling = Sapling_services - -module Liquidity_baking = struct - module S = struct - let get_cpmm_address = - RPC_service.get_service - ~description:"Liquidity baking CPMM address" - ~query:RPC_query.empty - ~output:Alpha_context.Contract.encoding - RPC_path.(custom_root / "context" / "liquidity_baking" / "cpmm_address") - end - - let register () = - let open Services_registration in - register0 ~chunked:false S.get_cpmm_address (fun ctxt () () -> - Alpha_context.Liquidity_baking.get_cpmm_address ctxt) - - let get_cpmm_address ctxt block = - RPC_context.make_call0 S.get_cpmm_address ctxt block () () -end - -module Cache = struct - module S = struct - let cached_contracts = - RPC_service.get_service - ~description:"Return the list of cached contracts" - ~query:RPC_query.empty - ~output: - Data_encoding.(list @@ tup2 Alpha_context.Contract.encoding int31) - RPC_path.(custom_root / "context" / "cache" / "contracts" / "all") - - let contract_cache_size = - RPC_service.get_service - ~description:"Return the size of the contract cache" - ~query:RPC_query.empty - ~output:Data_encoding.int31 - RPC_path.(custom_root / "context" / "cache" / "contracts" / "size") - - let contract_cache_size_limit = - RPC_service.get_service - ~description:"Return the size limit of the contract cache" - ~query:RPC_query.empty - ~output:Data_encoding.int31 - RPC_path.( - custom_root / "context" / "cache" / "contracts" / "size_limit") - - let contract_rank = - RPC_service.post_service - ~description: - "Return the number of cached contracts older than the provided \ - contract" - ~query:RPC_query.empty - ~input:Alpha_context.Contract.encoding - ~output:Data_encoding.(option int31) - RPC_path.(custom_root / "context" / "cache" / "contracts" / "rank") - end - - let register () = - let open Services_registration in - register0 ~chunked:true S.cached_contracts (fun ctxt () () -> - Script_cache.entries ctxt |> Lwt.return) ; - register0 ~chunked:false S.contract_cache_size (fun ctxt () () -> - Script_cache.size ctxt |> return) ; - register0 ~chunked:false S.contract_cache_size_limit (fun ctxt () () -> - Script_cache.size_limit ctxt |> return) ; - register0 ~chunked:false S.contract_rank (fun ctxt () contract -> - Script_cache.contract_rank ctxt contract |> return) - - let cached_contracts ctxt block = - RPC_context.make_call0 S.cached_contracts ctxt block () () - - let contract_cache_size ctxt block = - RPC_context.make_call0 S.contract_cache_size ctxt block () () - - let contract_cache_size_limit ctxt block = - RPC_context.make_call0 S.contract_cache_size_limit ctxt block () () - - let contract_rank ctxt block contract = - RPC_context.make_call0 S.contract_rank ctxt block () contract -end - -let register () = - Contract.register () ; - Constants.register () ; - Delegate.register () ; - Nonce.register () ; - Voting.register () ; - Sapling.register () ; - Liquidity_baking.register () ; - Cache.register () diff --git a/src/proto_012_Psithaca/lib_protocol/alpha_services.mli b/src/proto_012_Psithaca/lib_protocol/alpha_services.mli deleted file mode 100644 index b32cb71dfe0a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/alpha_services.mli +++ /dev/null @@ -1,81 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This declares Protocol RPC services. - - Protocol RPC services are read-only, and support querying the state of the - ledger (including information such as existing contracts, delegation, - voting, and so on), at a given block height. - - This is a mostly internal module used from [rpc_services] in [Main]. - *) - -open Alpha_context - -module Seed : sig - val get : 'a #RPC_context.simple -> 'a -> Seed.seed shell_tzresult Lwt.t -end - -module Nonce : sig - type info = Revealed of Nonce.t | Missing of Nonce_hash.t | Forgotten - - val get : - 'a #RPC_context.simple -> 'a -> Raw_level.t -> info shell_tzresult Lwt.t -end - -module Contract = Contract_services -module Constants = Constants_services -module Delegate = Delegate_services -module Voting = Voting_services -module Sapling = Sapling_services - -module Liquidity_baking : sig - val get_cpmm_address : - 'a #RPC_context.simple -> - 'a -> - Alpha_context.Contract.t shell_tzresult Lwt.t -end - -module Cache : sig - val cached_contracts : - 'a #RPC_context.simple -> - 'a -> - (Alpha_context.Contract.t * int) list shell_tzresult Lwt.t - - val contract_cache_size : - 'a #RPC_context.simple -> 'a -> int shell_tzresult Lwt.t - - val contract_cache_size_limit : - 'a #RPC_context.simple -> 'a -> int shell_tzresult Lwt.t - - val contract_rank : - 'a #RPC_context.simple -> - 'a -> - Alpha_context.Contract.t -> - int option shell_tzresult Lwt.t -end - -val register : unit -> unit diff --git a/src/proto_012_Psithaca/lib_protocol/amendment.ml b/src/proto_012_Psithaca/lib_protocol/amendment.ml deleted file mode 100644 index ae8b50212a46..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/amendment.ml +++ /dev/null @@ -1,266 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -(** Returns the proposal submitted by the most delegates. - Returns None in case of a tie, if proposal quorum is below required - minimum or if there are no proposals. *) -let select_winning_proposal ctxt = - Vote.get_proposals ctxt >>=? fun proposals -> - let merge proposal vote winners = - match winners with - | None -> Some ([proposal], vote) - | Some (winners, winners_vote) as previous -> - if Compare.Int32.(vote = winners_vote) then - Some (proposal :: winners, winners_vote) - else if Compare.Int32.(vote > winners_vote) then Some ([proposal], vote) - else previous - in - match Protocol_hash.Map.fold merge proposals None with - | Some ([proposal], vote) -> - Vote.listing_size ctxt >>=? fun max_vote -> - let min_proposal_quorum = Constants.min_proposal_quorum ctxt in - let min_vote_to_pass = - Int32.div (Int32.mul min_proposal_quorum max_vote) 100_00l - in - if Compare.Int32.(vote >= min_vote_to_pass) then return_some proposal - else return_none - | _ -> return_none - -(* in case of a tie, let's do nothing. *) - -(** A proposal is approved if it has supermajority and the participation reaches - the current quorum. - Supermajority means the yays are more 8/10 of casted votes. - The participation is the ratio of all received votes, including passes, with - respect to the number of possible votes. - The participation EMA (exponential moving average) uses the last - participation EMA and the current participation./ - The expected quorum is calculated using the last participation EMA, capped - by the min/max quorum protocol constants. *) -let approval_and_participation_ema (ballots : Vote.ballots) ~maximum_vote - ~participation_ema ~expected_quorum = - (* Note overflows: considering a maximum of 8e8 tokens, with roll size as - small as 1e3, there is a maximum of 8e5 rolls and thus votes. - In 'participation' an Int64 is used because in the worst case 'all_votes is - 8e5 and after the multiplication is 8e9, making it potentially overflow a - signed Int32 which is 2e9. *) - let casted_votes = Int32.add ballots.yay ballots.nay in - let all_votes = Int32.add casted_votes ballots.pass in - let supermajority = Int32.div (Int32.mul 8l casted_votes) 10l in - let participation = - (* in centile of percentage *) - Int64.( - to_int32 (div (mul (of_int32 all_votes) 100_00L) (of_int32 maximum_vote))) - in - let approval = - Compare.Int32.( - participation >= expected_quorum && ballots.yay >= supermajority) - in - let new_participation_ema = - Int32.(div (add (mul 8l participation_ema) (mul 2l participation)) 10l) - in - (approval, new_participation_ema) - -let get_approval_and_update_participation_ema ctxt = - Vote.get_ballots ctxt >>=? fun ballots -> - Vote.listing_size ctxt >>=? fun maximum_vote -> - Vote.get_participation_ema ctxt >>=? fun participation_ema -> - Vote.get_current_quorum ctxt >>=? fun expected_quorum -> - Vote.clear_ballots ctxt >>= fun ctxt -> - let (approval, new_participation_ema) = - approval_and_participation_ema - ballots - ~maximum_vote - ~participation_ema - ~expected_quorum - in - Vote.set_participation_ema ctxt new_participation_ema >|=? fun ctxt -> - (ctxt, approval) - -(** Implements the state machine of the amendment procedure. Note that - [update_listings], that computes the vote weight of each delegate, is run at - the end of each voting period. This state-machine prepare the voting_period - for the next block. *) -let start_new_voting_period ctxt = - Voting_period.get_current_kind ctxt >>=? fun kind -> - (match kind with - | Proposal -> ( - select_winning_proposal ctxt >>=? fun proposal -> - Vote.clear_proposals ctxt >>= fun ctxt -> - match proposal with - | None -> Voting_period.reset ctxt - | Some proposal -> - Vote.init_current_proposal ctxt proposal >>=? Voting_period.succ) - | Exploration -> - get_approval_and_update_participation_ema ctxt - >>=? fun (ctxt, approved) -> - if approved then Voting_period.succ ctxt - else - Vote.clear_current_proposal ctxt >>=? fun ctxt -> - Voting_period.reset ctxt - | Cooldown -> Voting_period.succ ctxt - | Promotion -> - get_approval_and_update_participation_ema ctxt - >>=? fun (ctxt, approved) -> - if approved then Voting_period.succ ctxt - else Vote.clear_current_proposal ctxt >>=? Voting_period.reset - | Adoption -> - Vote.get_current_proposal ctxt >>=? fun proposal -> - activate ctxt proposal >>= fun ctxt -> - Vote.clear_current_proposal ctxt >>=? Voting_period.reset) - >>=? fun ctxt -> Vote.update_listings ctxt - -type error += - | (* `Branch *) - Invalid_proposal - | Unexpected_proposal - | Unauthorized_proposal - | Too_many_proposals - | Empty_proposal - | Unexpected_ballot - | Unauthorized_ballot - -let () = - let open Data_encoding in - (* Invalid proposal *) - register_error_kind - `Branch - ~id:"invalid_proposal" - ~title:"Invalid proposal" - ~description:"Ballot provided for a proposal that is not the current one." - ~pp:(fun ppf () -> Format.fprintf ppf "Invalid proposal") - empty - (function Invalid_proposal -> Some () | _ -> None) - (fun () -> Invalid_proposal) ; - (* Unexpected proposal *) - register_error_kind - `Branch - ~id:"unexpected_proposal" - ~title:"Unexpected proposal" - ~description:"Proposal recorded outside of a proposal period." - ~pp:(fun ppf () -> Format.fprintf ppf "Unexpected proposal") - empty - (function Unexpected_proposal -> Some () | _ -> None) - (fun () -> Unexpected_proposal) ; - (* Unauthorized proposal *) - register_error_kind - `Branch - ~id:"unauthorized_proposal" - ~title:"Unauthorized proposal" - ~description: - "The delegate provided for the proposal is not in the voting listings." - ~pp:(fun ppf () -> Format.fprintf ppf "Unauthorized proposal") - empty - (function Unauthorized_proposal -> Some () | _ -> None) - (fun () -> Unauthorized_proposal) ; - (* Unexpected ballot *) - register_error_kind - `Branch - ~id:"unexpected_ballot" - ~title:"Unexpected ballot" - ~description:"Ballot recorded outside of a voting period." - ~pp:(fun ppf () -> Format.fprintf ppf "Unexpected ballot") - empty - (function Unexpected_ballot -> Some () | _ -> None) - (fun () -> Unexpected_ballot) ; - (* Unauthorized ballot *) - register_error_kind - `Branch - ~id:"unauthorized_ballot" - ~title:"Unauthorized ballot" - ~description: - "The delegate provided for the ballot is not in the voting listings." - ~pp:(fun ppf () -> Format.fprintf ppf "Unauthorized ballot") - empty - (function Unauthorized_ballot -> Some () | _ -> None) - (fun () -> Unauthorized_ballot) ; - (* Too many proposals *) - register_error_kind - `Branch - ~id:"too_many_proposals" - ~title:"Too many proposals" - ~description:"The delegate reached the maximum number of allowed proposals." - ~pp:(fun ppf () -> Format.fprintf ppf "Too many proposals") - empty - (function Too_many_proposals -> Some () | _ -> None) - (fun () -> Too_many_proposals) ; - (* Empty proposal *) - register_error_kind - `Branch - ~id:"empty_proposal" - ~title:"Empty proposal" - ~description:"Proposal lists cannot be empty." - ~pp:(fun ppf () -> Format.fprintf ppf "Empty proposal") - empty - (function Empty_proposal -> Some () | _ -> None) - (fun () -> Empty_proposal) - -let record_proposals ctxt delegate proposals = - (match proposals with - | [] -> error Empty_proposal - | _ :: _ -> Result.return_unit) - >>?= fun () -> - Voting_period.get_current_kind ctxt >>=? function - | Proposal -> - Vote.in_listings ctxt delegate >>= fun in_listings -> - if in_listings then ( - Vote.recorded_proposal_count_for_delegate ctxt delegate - >>=? fun count -> - assert (Compare.Int.(Constants.max_proposals_per_delegate >= count)) ; - error_when - Compare.Int.( - List.compare_length_with - proposals - (Constants.max_proposals_per_delegate - count) - > 0) - Too_many_proposals - >>?= fun () -> - List.fold_left_es - (fun ctxt proposal -> Vote.record_proposal ctxt proposal delegate) - ctxt - proposals) - else fail Unauthorized_proposal - | Exploration | Cooldown | Promotion | Adoption -> fail Unexpected_proposal - -let record_ballot ctxt delegate proposal ballot = - Voting_period.get_current_kind ctxt >>=? function - | Exploration | Promotion -> - Vote.get_current_proposal ctxt >>=? fun current_proposal -> - error_unless - (Protocol_hash.equal proposal current_proposal) - Invalid_proposal - >>?= fun () -> - Vote.has_recorded_ballot ctxt delegate >>= fun has_ballot -> - error_when has_ballot Unauthorized_ballot >>?= fun () -> - Vote.in_listings ctxt delegate >>= fun in_listings -> - if in_listings then Vote.record_ballot ctxt delegate ballot - else fail Unauthorized_ballot - | Cooldown | Proposal | Adoption -> fail Unexpected_ballot - -let may_start_new_voting_period ctxt = - Voting_period.is_last_block ctxt >>=? fun is_last -> - if is_last then start_new_voting_period ctxt else return ctxt diff --git a/src/proto_012_Psithaca/lib_protocol/amendment.mli b/src/proto_012_Psithaca/lib_protocol/amendment.mli deleted file mode 100644 index 200019bd03ea..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/amendment.mli +++ /dev/null @@ -1,81 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Only delegates with at least one roll take part in the amendment - procedure. It works as follows: - - - Proposal period: delegates can submit protocol amendment - proposals using the proposal operation. At the end of a proposal - period, the proposal with most supporters is selected and we move - to an exploration period. If there are no proposals, or a tie - between proposals, a new proposal period starts. - - - Exploration period: delegates can cast votes to test or not the - winning proposal using the ballot operation. At the end of an - exploration period if participation reaches the quorum and the - proposal has a supermajority in favor, we proceed to a cooldown - period. Otherwise we go back to a proposal period. In any case, if - there is enough participation the quorum is updated. - - - Cooldown period: Nothing happens, this period is only a time gap - between exploration and promotion periods. At the end of a cooldown - period we move to a promotion period. - - - Promotion period: delegates can cast votes to promote or not the - proposal using the ballot operation. At the end of a promotion - period if participation reaches the quorum and the proposal has a - supermajority in favor, we move to an adoption period. Otherwise we - go back to a proposal period. In any case, if there is enough - participation the quorum is updated. - - - Adoption period: At the end of an adoption period, the proposal - is activated as the new protocol. *) - -open Alpha_context - -(** If at the end of a voting period, moves to the next one following - the state machine of the amendment procedure. *) -val may_start_new_voting_period : context -> context tzresult Lwt.t - -type error += - | Unexpected_proposal - | Unauthorized_proposal - | Too_many_proposals - | Empty_proposal - -(** Records a list of proposals for a delegate. - @raise Unexpected_proposal if [ctxt] is not in a proposal period. - @raise Unauthorized_proposal if [delegate] is not in the listing. *) -val record_proposals : - context -> public_key_hash -> Protocol_hash.t list -> context tzresult Lwt.t - -type error += Invalid_proposal | Unexpected_ballot | Unauthorized_ballot - -val record_ballot : - context -> - public_key_hash -> - Protocol_hash.t -> - Vote.ballot -> - context tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/apply.ml b/src/proto_012_Psithaca/lib_protocol/apply.ml deleted file mode 100644 index 4b20f9e2fb24..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/apply.ml +++ /dev/null @@ -1,2658 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Tezos Protocol Implementation - Main Entry Points *) - -open Alpha_context - -type error += - | (* `Permanent *) - Not_enough_endorsements of { - required : int; - endorsements : int; - } - | (* `Temporary *) - Wrong_consensus_operation_branch of - Block_hash.t * Block_hash.t - | (* `Permanent *) - Invalid_double_baking_evidence of { - hash1 : Block_hash.t; - level1 : Raw_level.t; - round1 : Round.t; - hash2 : Block_hash.t; - level2 : Raw_level.t; - round2 : Round.t; - } - | (* `Permanent *) - Wrong_level_for_consensus_operation of { - expected : Raw_level.t; - provided : Raw_level.t; - } - | (* `Permanent *) - Wrong_round_for_consensus_operation of { - expected : Round.t; - provided : Round.t; - } - | (* `Permanent *) - Preendorsement_round_too_high of { - block_round : Round.t; - provided : Round.t; - } - | (* `Permanent *) - Unexpected_endorsement_in_block - | (* `Permanent *) - Unexpected_preendorsement_in_block - | (* `Permanent *) - Wrong_payload_hash_for_consensus_operation of { - expected : Block_payload_hash.t; - provided : Block_payload_hash.t; - } - | (* `Permanent *) Wrong_slot_used_for_consensus_operation - | (* `Temporary *) - Consensus_operation_for_future_level of { - expected : Raw_level.t; - provided : Raw_level.t; - } - | (* `Temporary *) - Consensus_operation_for_future_round of { - expected : Round.t; - provided : Round.t; - } - | (* `Outdated *) - Consensus_operation_for_old_level of { - expected : Raw_level.t; - provided : Raw_level.t; - } - | (* `Branch *) - Consensus_operation_for_old_round of { - expected : Round.t; - provided : Round.t; - } - | (* `Branch *) - Consensus_operation_on_competing_proposal of { - expected : Block_payload_hash.t; - provided : Block_payload_hash.t; - } - | (* `Permanent *) - Set_deposits_limit_on_originated_contract - | (* `Temporary *) - Set_deposits_limit_on_unregistered_delegate of - Signature.Public_key_hash.t - | (* `Permanent *) - Set_deposits_limit_too_high of { - limit : Tez.t; - max_limit : Tez.t; - } - | (* `Branch *) Empty_transaction of Contract.t - -let () = - register_error_kind - `Permanent - ~id:"operations.wrong_slot" - ~title:"wrong slot" - ~description:"wrong slot" - ~pp:(fun ppf () -> Format.fprintf ppf "wrong slot") - Data_encoding.empty - (function Wrong_slot_used_for_consensus_operation -> Some () | _ -> None) - (fun () -> Wrong_slot_used_for_consensus_operation) ; - register_error_kind - `Permanent - ~id:"operation.not_enough_endorsements" - ~title:"Not enough endorsements" - ~description: - "The block being validated does not include the required minimum number \ - of endorsements." - ~pp:(fun ppf (required, endorsements) -> - Format.fprintf - ppf - "Wrong number of endorsements (%i), at least %i are expected" - endorsements - required) - Data_encoding.(obj2 (req "required" int31) (req "endorsements" int31)) - (function - | Not_enough_endorsements {required; endorsements} -> - Some (required, endorsements) - | _ -> None) - (fun (required, endorsements) -> - Not_enough_endorsements {required; endorsements}) ; - register_error_kind - `Temporary - ~id:"operation.wrong_consensus_operation_branch" - ~title:"Wrong consensus operation branch" - ~description: - "Trying to include an endorsement or preendorsement which points to the \ - wrong block.\n\ - \ It should be the predecessor for preendorsements and the \ - grandfather for endorsements." - ~pp:(fun ppf (e, p) -> - Format.fprintf - ppf - "Wrong branch %a, expected %a" - Block_hash.pp - p - Block_hash.pp - e) - Data_encoding.( - obj2 - (req "expected" Block_hash.encoding) - (req "provided" Block_hash.encoding)) - (function - | Wrong_consensus_operation_branch (e, p) -> Some (e, p) | _ -> None) - (fun (e, p) -> Wrong_consensus_operation_branch (e, p)) ; - register_error_kind - `Permanent - ~id:"block.invalid_double_baking_evidence" - ~title:"Invalid double baking evidence" - ~description: - "A double-baking evidence is inconsistent (two distinct level)" - ~pp:(fun ppf (hash1, level1, round1, hash2, level2, round2) -> - Format.fprintf - ppf - "Invalid double-baking evidence (hash: %a and %a, levels/rounds: \ - (%ld,%ld) and (%ld,%ld))" - Block_hash.pp - hash1 - Block_hash.pp - hash2 - (Raw_level.to_int32 level1) - (Round.to_int32 round1) - (Raw_level.to_int32 level2) - (Round.to_int32 round2)) - Data_encoding.( - obj6 - (req "hash1" Block_hash.encoding) - (req "level1" Raw_level.encoding) - (req "round1" Round.encoding) - (req "hash2" Block_hash.encoding) - (req "level2" Raw_level.encoding) - (req "round2" Round.encoding)) - (function - | Invalid_double_baking_evidence - {hash1; level1; round1; hash2; level2; round2} -> - Some (hash1, level1, round1, hash2, level2, round2) - | _ -> None) - (fun (hash1, level1, round1, hash2, level2, round2) -> - Invalid_double_baking_evidence - {hash1; level1; round1; hash2; level2; round2}) ; - register_error_kind - `Permanent - ~id:"wrong_level_for_consensus_operation" - ~title:"wrong level for consensus operation" - ~description:"Wrong level for consensus operation." - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Wrong level for consensus operation (expected: %a, provided: %a)." - Raw_level.pp - expected - Raw_level.pp - provided) - Data_encoding.( - obj2 - (req "expected" Raw_level.encoding) - (req "provided" Raw_level.encoding)) - (function - | Wrong_level_for_consensus_operation {expected; provided} -> - Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> - Wrong_level_for_consensus_operation {expected; provided}) ; - register_error_kind - `Permanent - ~id:"wrong_round_for_consensus_operation" - ~title:"wrong round for consensus operation" - ~description:"Wrong round for consensus operation." - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Wrong round for consensus operation (expected: %a, provided: %a)." - Round.pp - expected - Round.pp - provided) - Data_encoding.( - obj2 (req "expected" Round.encoding) (req "provided" Round.encoding)) - (function - | Wrong_round_for_consensus_operation {expected; provided} -> - Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> - Wrong_round_for_consensus_operation {expected; provided}) ; - register_error_kind - `Permanent - ~id:"preendorsement_round_too_high" - ~title:"preendorsement round too high" - ~description:"Preendorsement round too high." - ~pp:(fun ppf (block_round, provided) -> - Format.fprintf - ppf - "Preendorsement round too high (block_round: %a, provided: %a)." - Round.pp - block_round - Round.pp - provided) - Data_encoding.( - obj2 (req "block_round" Round.encoding) (req "provided" Round.encoding)) - (function - | Preendorsement_round_too_high {block_round; provided} -> - Some (block_round, provided) - | _ -> None) - (fun (block_round, provided) -> - Preendorsement_round_too_high {block_round; provided}) ; - register_error_kind - `Permanent - ~id:"wrong_payload_hash_for_consensus_operation" - ~title:"wrong payload hash for consensus operation" - ~description:"Wrong payload hash for consensus operation." - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Wrong payload hash for consensus operation (expected: %a, provided: \ - %a)." - Block_payload_hash.pp_short - expected - Block_payload_hash.pp_short - provided) - Data_encoding.( - obj2 - (req "expected" Block_payload_hash.encoding) - (req "provided" Block_payload_hash.encoding)) - (function - | Wrong_payload_hash_for_consensus_operation {expected; provided} -> - Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> - Wrong_payload_hash_for_consensus_operation {expected; provided}) ; - register_error_kind - `Permanent - ~id:"unexpected_endorsement_in_block" - ~title:"unexpected endorsement in block" - ~description:"Unexpected endorsement in block." - ~pp:(fun ppf () -> Format.fprintf ppf "Unexpected endorsement in block.") - Data_encoding.empty - (function Unexpected_endorsement_in_block -> Some () | _ -> None) - (fun () -> Unexpected_endorsement_in_block) ; - register_error_kind - `Permanent - ~id:"unexpected_preendorsement_in_block" - ~title:"unexpected preendorsement in block" - ~description:"Unexpected preendorsement in block." - ~pp:(fun ppf () -> Format.fprintf ppf "Unexpected preendorsement in block.") - Data_encoding.empty - (function Unexpected_preendorsement_in_block -> Some () | _ -> None) - (fun () -> Unexpected_preendorsement_in_block) ; - register_error_kind - `Temporary - ~id:"consensus_operation_for_future_level" - ~title:"Consensus operation for future level" - ~description:"Consensus operation for future level." - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Consensus operation for future level\n\ - \ (expected: %a, provided: %a)." - Raw_level.pp - expected - Raw_level.pp - provided) - Data_encoding.( - obj2 - (req "expected" Raw_level.encoding) - (req "provided" Raw_level.encoding)) - (function - | Consensus_operation_for_future_level {expected; provided} -> - Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> - Consensus_operation_for_future_level {expected; provided}) ; - register_error_kind - `Temporary - ~id:"consensus_operation_for_future_round" - ~title:"Consensus operation for future round" - ~description:"Consensus operation for future round." - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Consensus operation for future round (expected: %a, provided: %a)." - Round.pp - expected - Round.pp - provided) - Data_encoding.( - obj2 (req "expected_max" Round.encoding) (req "provided" Round.encoding)) - (function - | Consensus_operation_for_future_round {expected; provided} -> - Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> - Consensus_operation_for_future_round {expected; provided}) ; - register_error_kind - `Outdated - ~id:"consensus_operation_for_old_level" - ~title:"Consensus operation for old level" - ~description:"Consensus operation for old level." - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Consensus operation for old level (expected: %a, provided: %a)." - Raw_level.pp - expected - Raw_level.pp - provided) - Data_encoding.( - obj2 - (req "expected" Raw_level.encoding) - (req "provided" Raw_level.encoding)) - (function - | Consensus_operation_for_old_level {expected; provided} -> - Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> - Consensus_operation_for_old_level {expected; provided}) ; - register_error_kind - `Branch - ~id:"consensus_operation_for_old_round" - ~title:"Consensus operation for old round" - ~description:"Consensus operation for old round." - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Consensus operation for old round (expected_min: %a, provided: %a)." - Round.pp - expected - Round.pp - provided) - Data_encoding.( - obj2 (req "expected_min" Round.encoding) (req "provided" Round.encoding)) - (function - | Consensus_operation_for_old_round {expected; provided} -> - Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> - Consensus_operation_for_old_round {expected; provided}) ; - register_error_kind - `Branch - ~id:"consensus_operation_on_competing_proposal" - ~title:"Consensus operation on competing proposal" - ~description:"Consensus operation on competing proposal." - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Consensus operation on competing proposal (expected: %a, provided: \ - %a)." - Block_payload_hash.pp_short - expected - Block_payload_hash.pp_short - provided) - Data_encoding.( - obj2 - (req "expected" Block_payload_hash.encoding) - (req "provided" Block_payload_hash.encoding)) - (function - | Consensus_operation_on_competing_proposal {expected; provided} -> - Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> - Consensus_operation_on_competing_proposal {expected; provided}) ; - register_error_kind - `Permanent - ~id:"operation.set_deposits_limit_on_originated_contract" - ~title:"Set deposits limit on an originated contract" - ~description:"Cannot set deposits limit on an originated contract." - ~pp:(fun ppf () -> - Format.fprintf ppf "Cannot set deposits limit on an originated contract.") - Data_encoding.empty - (function - | Set_deposits_limit_on_originated_contract -> Some () | _ -> None) - (fun () -> Set_deposits_limit_on_originated_contract) ; - register_error_kind - `Temporary - ~id:"operation.set_deposits_limit_on_unregistered_delegate" - ~title:"Set deposits limit on an unregistered delegate" - ~description:"Cannot set deposits limit on an unregistered delegate." - ~pp:(fun ppf c -> - Format.fprintf - ppf - "Cannot set a deposits limit on the unregistered delegate %a." - Signature.Public_key_hash.pp - c) - Data_encoding.(obj1 (req "delegate" Signature.Public_key_hash.encoding)) - (function - | Set_deposits_limit_on_unregistered_delegate c -> Some c | _ -> None) - (fun c -> Set_deposits_limit_on_unregistered_delegate c) ; - register_error_kind - `Permanent - ~id:"operation.set_deposits_limit_too_high" - ~title:"Set deposits limit to a too high value" - ~description: - "Cannot set deposits limit such that the active stake overflows." - ~pp:(fun ppf (limit, max_limit) -> - Format.fprintf - ppf - "Cannot set deposits limit to %a as it is higher the allowed maximum \ - %a." - Tez.pp - limit - Tez.pp - max_limit) - Data_encoding.( - obj2 (req "limit" Tez.encoding) (req "max_limit" Tez.encoding)) - (function - | Set_deposits_limit_too_high {limit; max_limit} -> Some (limit, max_limit) - | _ -> None) - (fun (limit, max_limit) -> Set_deposits_limit_too_high {limit; max_limit}) ; - register_error_kind - `Branch - ~id:"contract.empty_transaction" - ~title:"Empty transaction" - ~description:"Forbidden to credit 0ꜩ to a contract without code." - ~pp:(fun ppf contract -> - Format.fprintf - ppf - "Transactions of 0ꜩ towards a contract without code are forbidden \ - (%a)." - Contract.pp - contract) - Data_encoding.(obj1 (req "contract" Contract.encoding)) - (function Empty_transaction c -> Some c | _ -> None) - (fun c -> Empty_transaction c) - -type error += (* `Temporary *) Wrong_voting_period of int32 * int32 - -type error += - | (* `Permanent *) Internal_operation_replay of packed_internal_operation - -type denunciation_kind = Preendorsement | Endorsement | Block - -let denunciation_kind_encoding = - let open Data_encoding in - string_enum - [ - ("preendorsement", Preendorsement); - ("endorsement", Endorsement); - ("block", Block); - ] - -let pp_denunciation_kind fmt : denunciation_kind -> unit = function - | Preendorsement -> Format.fprintf fmt "preendorsement" - | Endorsement -> Format.fprintf fmt "endorsement" - | Block -> Format.fprintf fmt "baking" - -type error += (* `Permanent *) - Invalid_denunciation of denunciation_kind - -type error += - | (* `Permanent *) - Inconsistent_denunciation of { - kind : denunciation_kind; - delegate1 : Signature.Public_key_hash.t; - delegate2 : Signature.Public_key_hash.t; - } - -type error += (* `Branch *) Unrequired_denunciation - -type error += - | (* `Temporary *) - Too_early_denunciation of { - kind : denunciation_kind; - level : Raw_level.t; - current : Raw_level.t; - } - -type error += - | (* `Permanent *) - Outdated_denunciation of { - kind : denunciation_kind; - level : Raw_level.t; - last_cycle : Cycle.t; - } - -type error += - | (* Permanent *) Invalid_activation of {pkh : Ed25519.Public_key_hash.t} - -type error += (* Permanent *) Multiple_revelation - -type error += (* Permanent *) Gas_quota_exceeded_init_deserialize - -type error += (* `Permanent *) Inconsistent_sources - -type error += (* `Permanent *) Failing_noop_error - -type error += - | (* `Permanent *) - Zero_frozen_deposits of Signature.Public_key_hash.t - -let () = - register_error_kind - `Temporary - ~id:"operation.wrong_voting_period" - ~title:"Wrong voting period" - ~description: - "Trying to include a proposal or ballot meant for another voting period" - ~pp:(fun ppf (e, p) -> - Format.fprintf ppf "Wrong voting period %ld, current is %ld" p e) - Data_encoding.( - obj2 (req "current_index" int32) (req "provided_index" int32)) - (function Wrong_voting_period (e, p) -> Some (e, p) | _ -> None) - (fun (e, p) -> Wrong_voting_period (e, p)) ; - register_error_kind - `Permanent - ~id:"internal_operation_replay" - ~title:"Internal operation replay" - ~description:"An internal operation was emitted twice by a script" - ~pp:(fun ppf (Internal_operation {nonce; _}) -> - Format.fprintf - ppf - "Internal operation %d was emitted twice by a script" - nonce) - Operation.internal_operation_encoding - (function Internal_operation_replay op -> Some op | _ -> None) - (fun op -> Internal_operation_replay op) ; - register_error_kind - `Permanent - ~id:"block.invalid_denunciation" - ~title:"Invalid denunciation" - ~description:"A denunciation is malformed" - ~pp:(fun ppf kind -> - Format.fprintf - ppf - "Malformed double-%a evidence" - pp_denunciation_kind - kind) - Data_encoding.(obj1 (req "kind" denunciation_kind_encoding)) - (function Invalid_denunciation kind -> Some kind | _ -> None) - (fun kind -> Invalid_denunciation kind) ; - register_error_kind - `Permanent - ~id:"block.inconsistent_denunciation" - ~title:"Inconsistent denunciation" - ~description: - "A denunciation operation is inconsistent (two distinct delegates)" - ~pp:(fun ppf (kind, delegate1, delegate2) -> - Format.fprintf - ppf - "Inconsistent double-%a evidence (distinct delegate: %a and %a)" - pp_denunciation_kind - kind - Signature.Public_key_hash.pp_short - delegate1 - Signature.Public_key_hash.pp_short - delegate2) - Data_encoding.( - obj3 - (req "kind" denunciation_kind_encoding) - (req "delegate1" Signature.Public_key_hash.encoding) - (req "delegate2" Signature.Public_key_hash.encoding)) - (function - | Inconsistent_denunciation {kind; delegate1; delegate2} -> - Some (kind, delegate1, delegate2) - | _ -> None) - (fun (kind, delegate1, delegate2) -> - Inconsistent_denunciation {kind; delegate1; delegate2}) ; - register_error_kind - `Branch - ~id:"block.unrequired_denunciation" - ~title:"Unrequired denunciation" - ~description:"A denunciation is unrequired" - ~pp:(fun ppf _ -> - Format.fprintf - ppf - "A valid denunciation cannot be applied: the associated delegate has \ - already been denounced for this level.") - Data_encoding.unit - (function Unrequired_denunciation -> Some () | _ -> None) - (fun () -> Unrequired_denunciation) ; - register_error_kind - `Temporary - ~id:"block.too_early_denunciation" - ~title:"Too early denunciation" - ~description:"A denunciation is too far in the future" - ~pp:(fun ppf (kind, level, current) -> - Format.fprintf - ppf - "A double-%a denunciation is too far in the future (current level: %a, \ - given level: %a)" - pp_denunciation_kind - kind - Raw_level.pp - current - Raw_level.pp - level) - Data_encoding.( - obj3 - (req "kind" denunciation_kind_encoding) - (req "level" Raw_level.encoding) - (req "current" Raw_level.encoding)) - (function - | Too_early_denunciation {kind; level; current} -> - Some (kind, level, current) - | _ -> None) - (fun (kind, level, current) -> - Too_early_denunciation {kind; level; current}) ; - register_error_kind - `Permanent - ~id:"block.outdated_denunciation" - ~title:"Outdated denunciation" - ~description:"A denunciation is outdated." - ~pp:(fun ppf (kind, level, last_cycle) -> - Format.fprintf - ppf - "A double-%a is outdated (last acceptable cycle: %a, given level: %a)" - pp_denunciation_kind - kind - Cycle.pp - last_cycle - Raw_level.pp - level) - Data_encoding.( - obj3 - (req "kind" denunciation_kind_encoding) - (req "level" Raw_level.encoding) - (req "last" Cycle.encoding)) - (function - | Outdated_denunciation {kind; level; last_cycle} -> - Some (kind, level, last_cycle) - | _ -> None) - (fun (kind, level, last_cycle) -> - Outdated_denunciation {kind; level; last_cycle}) ; - register_error_kind - `Permanent - ~id:"operation.invalid_activation" - ~title:"Invalid activation" - ~description: - "The given key and secret do not correspond to any existing preallocated \ - contract" - ~pp:(fun ppf pkh -> - Format.fprintf - ppf - "Invalid activation. The public key %a does not match any commitment." - Ed25519.Public_key_hash.pp - pkh) - Data_encoding.(obj1 (req "pkh" Ed25519.Public_key_hash.encoding)) - (function Invalid_activation {pkh} -> Some pkh | _ -> None) - (fun pkh -> Invalid_activation {pkh}) ; - register_error_kind - `Permanent - ~id:"block.multiple_revelation" - ~title:"Multiple revelations were included in a manager operation" - ~description: - "A manager operation should not contain more than one revelation" - ~pp:(fun ppf () -> - Format.fprintf - ppf - "Multiple revelations were included in a manager operation") - Data_encoding.empty - (function Multiple_revelation -> Some () | _ -> None) - (fun () -> Multiple_revelation) ; - register_error_kind - `Permanent - ~id:"gas_exhausted.init_deserialize" - ~title:"Not enough gas for initial deserialization of script expressions" - ~description: - "Gas limit was not high enough to deserialize the transaction parameters \ - or origination script code or initial storage, making the operation \ - impossible to parse within the provided gas bounds." - Data_encoding.empty - (function Gas_quota_exceeded_init_deserialize -> Some () | _ -> None) - (fun () -> Gas_quota_exceeded_init_deserialize) ; - register_error_kind - `Permanent - ~id:"operation.inconsistent_sources" - ~title:"Inconsistent sources in operation pack" - ~description: - "The operation pack includes operations from different sources." - ~pp:(fun ppf () -> - Format.pp_print_string - ppf - "The operation pack includes operations from different sources.") - Data_encoding.empty - (function Inconsistent_sources -> Some () | _ -> None) - (fun () -> Inconsistent_sources) ; - register_error_kind - `Permanent - ~id:"operation.failing_noop" - ~title:"Failing_noop operation are not executed by the protocol" - ~description: - "The failing_noop operation is an operation that is not and never will \ - be executed by the protocol." - ~pp:(fun ppf () -> - Format.fprintf - ppf - "The failing_noop operation cannot be executed by the protocol") - Data_encoding.empty - (function Failing_noop_error -> Some () | _ -> None) - (fun () -> Failing_noop_error) ; - register_error_kind - `Permanent - ~id:"delegate.zero_frozen_deposits" - ~title:"Zero frozen deposits" - ~description:"The delegate has zero frozen deposits." - ~pp:(fun ppf delegate -> - Format.fprintf - ppf - "Delegate %a has zero frozen deposits; it is not allowed to \ - bake/preendorse/endorse." - Signature.Public_key_hash.pp - delegate) - Data_encoding.(obj1 (req "delegate" Signature.Public_key_hash.encoding)) - (function Zero_frozen_deposits delegate -> Some delegate | _ -> None) - (fun delegate -> Zero_frozen_deposits delegate) - -open Apply_results - -let cache_layout = Constants_repr.cache_layout - -(** - - Retrieving the source code of a contract from its address is costly - because it requires I/Os. For this reason, we put the corresponding - Micheline expression in the cache. - - Elaborating a Micheline node into the well-typed script abstract - syntax tree is also a costly operation. The result of this operation - is cached as well. - -*) - -let apply_manager_operation_content : - type kind. - Alpha_context.t -> - Script_ir_translator.unparsing_mode -> - payer:Contract.t -> - source:Contract.t -> - chain_id:Chain_id.t -> - internal:bool -> - gas_consumed_in_precheck:Gas.cost option -> - kind manager_operation -> - (context - * kind successful_manager_operation_result - * packed_internal_operation list) - tzresult - Lwt.t = - fun ctxt - mode - ~payer - ~source - ~chain_id - ~internal - ~gas_consumed_in_precheck - operation -> - let before_operation = - (* This context is not used for backtracking. Only to compute - gas consumption and originations for the operation result. *) - ctxt - in - Contract.must_exist ctxt source >>=? fun () -> - Gas.consume ctxt Michelson_v1_gas.Cost_of.manager_operation >>?= fun ctxt -> - (match gas_consumed_in_precheck with - | None -> Ok ctxt - | Some gas -> Gas.consume ctxt gas) - >>?= fun ctxt -> - let consume_deserialization_gas = Script.When_needed in - (* [note]: deserialization gas has already been accounted for in the gas - consumed by the precheck and the lazy_exprs have been forced. *) - match operation with - | Reveal _ -> - return - (* No-op: action already performed by `precheck_manager_contents`. *) - ( ctxt, - (Reveal_result - {consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt} - : kind successful_manager_operation_result), - [] ) - | Transaction {amount; parameters; destination; entrypoint} -> ( - Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - parameters - >>?= fun (parameter, ctxt) -> - (match Contract.is_implicit destination with - | None -> - (if Tez.(amount = zero) then - (* Detect potential call to non existent contract. *) - Contract.must_exist ctxt destination - else return_unit) - >>=? fun () -> - (* Since the contract is originated, nothing will be allocated - or the next transfer of tokens will fail. *) - return_false - | Some _ -> - (* Transfers of zero to implicit accounts are forbidden. *) - error_when Tez.(amount = zero) (Empty_transaction destination) - >>?= fun () -> - (* If the implicit contract is not yet allocated at this point then - the next transfer of tokens will allocate it. *) - Contract.allocated ctxt destination >|=? not) - >>=? fun allocated_destination_contract -> - Token.transfer ctxt (`Contract source) (`Contract destination) amount - >>=? fun (ctxt, balance_updates) -> - Script_cache.find ctxt destination >>=? fun (ctxt, cache_key, script) -> - match script with - | None -> - Lwt.return - ( ( (match entrypoint with - | "default" -> Result.return_unit - | entrypoint -> - error (Script_tc_errors.No_such_entrypoint entrypoint)) - >>? fun () -> - match Micheline.root parameter with - | Prim (_, D_Unit, [], _) -> - (* Allow [Unit] parameter to non-scripted contracts. *) - ok ctxt - | _ -> - error - (Script_interpreter.Bad_contract_parameter destination) ) - >|? fun ctxt -> - let result = - Transaction_result - { - storage = None; - lazy_storage_diff = None; - balance_updates; - originated_contracts = []; - consumed_gas = - Gas.consumed ~since:before_operation ~until:ctxt; - storage_size = Z.zero; - paid_storage_size_diff = Z.zero; - allocated_destination_contract; - } - in - (ctxt, result, []) ) - | Some (script, script_ir) -> - let now = Script_timestamp.now ctxt in - let level = - (Level.current ctxt).level |> Raw_level.to_int32 - |> Script_int.of_int32 |> Script_int.abs - in - let step_constants = - let open Script_interpreter in - {source; payer; self = destination; amount; chain_id; now; level} - in - Script_interpreter.execute - ctxt - ~cached_script:(Some script_ir) - mode - step_constants - ~script - ~parameter - ~entrypoint - ~internal - >>=? fun ( {ctxt; storage; lazy_storage_diff; operations}, - (updated_cached_script, updated_size) ) -> - Contract.update_script_storage - ctxt - destination - storage - lazy_storage_diff - >>=? fun ctxt -> - Fees.record_paid_storage_space ctxt destination - >>=? fun (ctxt, new_size, paid_storage_size_diff) -> - Contract.originated_from_current_nonce - ~since:before_operation - ~until:ctxt - >>=? fun originated_contracts -> - Lwt.return - ( Script_cache.update - ctxt - cache_key - ( {script with storage = Script.lazy_expr storage}, - updated_cached_script ) - updated_size - >|? fun ctxt -> - let result = - Transaction_result - { - storage = Some storage; - lazy_storage_diff; - balance_updates; - originated_contracts; - consumed_gas = - Gas.consumed ~since:before_operation ~until:ctxt; - storage_size = new_size; - paid_storage_size_diff; - allocated_destination_contract; - } - in - (ctxt, result, operations) )) - | Origination {delegate; script; preorigination; credit} -> - Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - script.storage - >>?= fun (_unparsed_storage, ctxt) -> - Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - script.code - >>?= fun (unparsed_code, ctxt) -> - Script_ir_translator.parse_script - ctxt - ~legacy:false - ~allow_forged_in_storage:internal - script - >>=? fun (Ex_script parsed_script, ctxt) -> - let views_result = - Script_ir_translator.typecheck_views - ctxt - ~legacy:false - parsed_script.storage_type - parsed_script.views - in - trace - (Script_tc_errors.Ill_typed_contract (unparsed_code, [])) - views_result - >>=? fun ctxt -> - Script_ir_translator.collect_lazy_storage - ctxt - parsed_script.storage_type - parsed_script.storage - >>?= fun (to_duplicate, ctxt) -> - let to_update = Script_ir_translator.no_lazy_storage_id in - Script_ir_translator.extract_lazy_storage_diff - ctxt - Optimized - parsed_script.storage_type - parsed_script.storage - ~to_duplicate - ~to_update - ~temporary:false - >>=? fun (storage, lazy_storage_diff, ctxt) -> - Script_ir_translator.unparse_data - ctxt - Optimized - parsed_script.storage_type - storage - >>=? fun (storage, ctxt) -> - let storage = Script.lazy_expr (Micheline.strip_locations storage) in - let script = {script with storage} in - (match preorigination with - | Some contract -> - assert internal ; - (* The preorigination field is only used to early return - the address of an originated contract in Michelson. - It cannot come from the outside. *) - ok (ctxt, contract) - | None -> Contract.fresh_contract_from_current_nonce ctxt) - >>?= fun (ctxt, contract) -> - Contract.raw_originate - ctxt - ~prepaid_bootstrap_storage:false - contract - ~script:(script, lazy_storage_diff) - >>=? fun ctxt -> - (match delegate with - | None -> return ctxt - | Some delegate -> Delegate.init ctxt contract delegate) - >>=? fun ctxt -> - Token.transfer ctxt (`Contract source) (`Contract contract) credit - >>=? fun (ctxt, balance_updates) -> - Fees.record_paid_storage_space ctxt contract - >|=? fun (ctxt, size, paid_storage_size_diff) -> - let result = - Origination_result - { - lazy_storage_diff; - balance_updates; - originated_contracts = [contract]; - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; - storage_size = size; - paid_storage_size_diff; - } - in - (ctxt, result, []) - | Delegation delegate -> - Delegate.set ctxt source delegate >|=? fun ctxt -> - ( ctxt, - Delegation_result - {consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt}, - [] ) - | Register_global_constant {value} -> - (* Decode the value and consume gas appropriately *) - Script.force_decode_in_context ~consume_deserialization_gas ctxt value - >>?= fun (expr, ctxt) -> - (* Set the key to the value in storage. *) - Global_constants_storage.register ctxt expr - >>=? fun (ctxt, address, size) -> - (* The burn and the reporting of the burn are calculated differently. - - [Fees.record_global_constant_storage_space] does the actual burn - based on the size of the constant registered, and this causes a - change in account balance. - - On the other hand, the receipt is calculated - with the help of [Fees.cost_of_bytes], and is included in block metadata - and the client output. The receipt is also used during simulation, - letting the client automatically set an appropriate storage limit. - TODO : is this concern still honored by the token management - refactoring ? *) - let (ctxt, paid_size) = - Fees.record_global_constant_storage_space ctxt size - in - let result = - Register_global_constant_result - { - balance_updates = []; - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; - size_of_constant = paid_size; - global_address = address; - } - in - return (ctxt, result, []) - | Set_deposits_limit limit -> ( - (match limit with - | None -> return_unit - | Some limit -> - let frozen_deposits_percentage = - Constants.frozen_deposits_percentage ctxt - in - let max_limit = - Tez.of_mutez_exn - Int64.( - mul (of_int frozen_deposits_percentage) Int64.(div max_int 100L)) - in - fail_when - Tez.(limit > max_limit) - (Set_deposits_limit_too_high {limit; max_limit})) - >>=? fun () -> - Contract.is_implicit source |> function - | None -> fail Set_deposits_limit_on_originated_contract - | Some delegate -> - Delegate.registered ctxt delegate >>=? fun is_registered -> - fail_unless - is_registered - (Set_deposits_limit_on_unregistered_delegate delegate) - >>=? fun () -> - Delegate.set_frozen_deposits_limit ctxt delegate limit >>= fun ctxt -> - return - ( ctxt, - Set_deposits_limit_result - { - consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; - }, - [] )) - -type success_or_failure = Success of context | Failure - -let apply_internal_manager_operations ctxt mode ~payer ~chain_id ops = - let[@coq_struct "ctxt"] rec apply ctxt applied worklist = - match worklist with - | [] -> Lwt.return (Success ctxt, List.rev applied) - | Internal_operation ({source; operation; nonce} as op) :: rest -> ( - (if internal_nonce_already_recorded ctxt nonce then - fail (Internal_operation_replay (Internal_operation op)) - else - let ctxt = record_internal_nonce ctxt nonce in - apply_manager_operation_content - ctxt - mode - ~source - ~payer - ~chain_id - ~internal:true - ~gas_consumed_in_precheck:None - operation) - >>= function - | Error errors -> - let result = - Internal_operation_result - (op, Failed (manager_kind op.operation, errors)) - in - let skipped = - List.rev_map - (fun (Internal_operation op) -> - Internal_operation_result - (op, Skipped (manager_kind op.operation))) - rest - in - Lwt.return (Failure, List.rev (skipped @ result :: applied)) - | Ok (ctxt, result, emitted) -> - apply - ctxt - (Internal_operation_result (op, Applied result) :: applied) - (emitted @ rest)) - in - apply ctxt [] ops - -let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) - ~(only_batch : bool) : (context * precheck_result) tzresult Lwt.t = - let[@coq_match_with_default] (Manager_operation - { - source; - fee; - counter; - operation; - gas_limit; - storage_limit; - }) = - op - in - (if only_batch then - (* Gas.consume_limit_in_block will only raise a "temporary" error, however - when the precheck is called on a batch in isolation (like e.g. in the - mempool) it must "refuse" operations whose total gas_limit (the sum of - the gas_limits of each operation) is already above the block limit. We - add the "permanent" error Gas.Gas_limit_too_high on top of the trace to - this effect. *) - record_trace Gas.Gas_limit_too_high - else fun errs -> errs) - @@ Gas.consume_limit_in_block ctxt gas_limit - >>?= fun ctxt -> - let ctxt = Gas.set_limit ctxt gas_limit in - let ctxt_before = ctxt in - Fees.check_storage_limit ctxt ~storage_limit >>?= fun () -> - let source_contract = Contract.implicit_contract source in - Contract.must_be_allocated ctxt source_contract >>=? fun () -> - Contract.check_counter_increment ctxt source counter >>=? fun () -> - let consume_deserialization_gas = Script.Always in - (* We want to always consume the deserialization gas here, independently of - the internal state of the lazy_exprs in the arguments. Otherwise we might - risk getting different results if the operation has already been - deserialized before (e.g. when retrieve in JSON format). *) - (match operation with - | Reveal pk -> Contract.reveal_manager_key ctxt source pk - | Transaction {parameters; _} -> - Lwt.return - @@ record_trace Gas_quota_exceeded_init_deserialize - @@ (* Fail early if not enough gas for complete deserialization - cost or if deserialization fails. The gas consumed here is - "replayed" in [apply_manager_contents]. *) - ( Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - parameters - >|? fun (_arg, ctxt) -> ctxt ) - | Origination {script; _} -> - Lwt.return - @@ record_trace Gas_quota_exceeded_init_deserialize - @@ (* See comment in the Transaction branch *) - ( Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - script.code - >>? fun (_code, ctxt) -> - Script.force_decode_in_context - ~consume_deserialization_gas - ctxt - script.storage - >|? fun (_storage, ctxt) -> ctxt ) - | Register_global_constant {value} -> - Lwt.return - @@ record_trace Gas_quota_exceeded_init_deserialize - @@ (* See comment in the Transaction branch *) - ( Script.force_decode_in_context ~consume_deserialization_gas ctxt value - >|? fun (_value, ctxt) -> ctxt ) - | _ -> return ctxt) - >>=? fun ctxt -> - Contract.increment_counter ctxt source >>=? fun ctxt -> - Token.transfer ctxt (`Contract source_contract) `Block_fees fee - >|=? fun (ctxt, balance_updates) -> - let consumed_gas = Gas.consumed ~since:ctxt_before ~until:ctxt in - (ctxt, {balance_updates; consumed_gas}) - -(** [burn_storage_fees ctxt smopr storage_limit payer] burns the storage fees - associated to the transaction or origination result [smopr]. - Returns an updated context, an updated storage limit with the space consumed - by the operation subtracted, and [smopr] with the relevant balance updates - included. *) -let burn_storage_fees : - type kind. - context -> - kind successful_manager_operation_result -> - storage_limit:Z.t -> - payer:Contract.t -> - (context * Z.t * kind successful_manager_operation_result) tzresult Lwt.t = - fun ctxt smopr ~storage_limit ~payer -> - match smopr with - | Transaction_result payload -> - let consumed = payload.paid_storage_size_diff in - let payer = `Contract payer in - Fees.burn_storage_fees ctxt ~storage_limit ~payer consumed - >>=? fun (ctxt, storage_limit, storage_bus) -> - (if payload.allocated_destination_contract then - Fees.burn_origination_fees ctxt ~storage_limit ~payer - else return (ctxt, storage_limit, [])) - >>=? fun (ctxt, storage_limit, origination_bus) -> - let balance_updates = - storage_bus @ payload.balance_updates @ origination_bus - in - return - ( ctxt, - storage_limit, - Transaction_result - { - storage = payload.storage; - lazy_storage_diff = payload.lazy_storage_diff; - balance_updates; - originated_contracts = payload.originated_contracts; - consumed_gas = payload.consumed_gas; - storage_size = payload.storage_size; - paid_storage_size_diff = payload.paid_storage_size_diff; - allocated_destination_contract = - payload.allocated_destination_contract; - } ) - | Origination_result payload -> - let consumed = payload.paid_storage_size_diff in - let payer = `Contract payer in - Fees.burn_storage_fees ctxt ~storage_limit ~payer consumed - >>=? fun (ctxt, storage_limit, storage_bus) -> - Fees.burn_origination_fees ctxt ~storage_limit ~payer - >>=? fun (ctxt, storage_limit, origination_bus) -> - let balance_updates = - storage_bus @ origination_bus @ payload.balance_updates - in - return - ( ctxt, - storage_limit, - Origination_result - { - lazy_storage_diff = payload.lazy_storage_diff; - balance_updates; - originated_contracts = payload.originated_contracts; - consumed_gas = payload.consumed_gas; - storage_size = payload.storage_size; - paid_storage_size_diff = payload.paid_storage_size_diff; - } ) - | Reveal_result _ | Delegation_result _ -> return (ctxt, storage_limit, smopr) - | Register_global_constant_result payload -> - let consumed = payload.size_of_constant in - let payer = `Contract payer in - Fees.burn_storage_fees ctxt ~storage_limit ~payer consumed - >>=? fun (ctxt, storage_limit, storage_bus) -> - let balance_updates = storage_bus @ payload.balance_updates in - return - ( ctxt, - storage_limit, - Register_global_constant_result - { - balance_updates; - consumed_gas = payload.consumed_gas; - size_of_constant = payload.size_of_constant; - global_address = payload.global_address; - } ) - | Set_deposits_limit_result _ -> return (ctxt, storage_limit, smopr) - -let apply_manager_contents (type kind) ctxt mode chain_id - ~gas_consumed_in_precheck (op : kind Kind.manager contents) : - (success_or_failure - * kind manager_operation_result - * packed_internal_operation_result list) - Lwt.t = - let[@coq_match_with_default] (Manager_operation - { - source; - operation; - gas_limit; - storage_limit; - _; - }) = - op - in - (* We do not expose the internal scaling to the users. Instead, we multiply - the specified gas limit by the internal scaling. *) - let ctxt = Gas.set_limit ctxt gas_limit in - let source = Contract.implicit_contract source in - apply_manager_operation_content - ctxt - mode - ~source - ~payer:source - ~internal:false - ~gas_consumed_in_precheck - ~chain_id - operation - >>= function - | Ok (ctxt, operation_results, internal_operations) -> ( - apply_internal_manager_operations - ctxt - mode - ~payer:source - ~chain_id - internal_operations - >>= function - | (Success ctxt, internal_operations_results) -> ( - burn_storage_fees ctxt operation_results ~storage_limit ~payer:source - >>= function - | Ok (ctxt, storage_limit, operation_results) -> ( - List.fold_left_es - (fun (ctxt, storage_limit, res) iopr -> - let (Internal_operation_result (op, mopr)) = iopr in - match mopr with - | Applied smopr -> - burn_storage_fees ctxt smopr ~storage_limit ~payer:source - >>=? fun (ctxt, storage_limit, smopr) -> - let iopr = - Internal_operation_result (op, Applied smopr) - in - return (ctxt, storage_limit, iopr :: res) - | _ -> return (ctxt, storage_limit, iopr :: res)) - (ctxt, storage_limit, []) - internal_operations_results - >|= function - | Ok (ctxt, _, internal_operations_results) -> - ( Success ctxt, - Applied operation_results, - List.rev internal_operations_results ) - | Error errors -> - ( Failure, - Backtracked (operation_results, Some errors), - internal_operations_results )) - | Error errors -> - Lwt.return - ( Failure, - Backtracked (operation_results, Some errors), - internal_operations_results )) - | (Failure, internal_operations_results) -> - Lwt.return - (Failure, Applied operation_results, internal_operations_results)) - | Error errors -> - Lwt.return (Failure, Failed (manager_kind operation, errors), []) - -let skipped_operation_result : - type kind. kind manager_operation -> kind manager_operation_result = - function - | operation -> ( - match operation with - | Reveal _ -> - Applied - (Reveal_result {consumed_gas = Gas.Arith.zero} - : kind successful_manager_operation_result) - | _ -> Skipped (manager_kind operation)) - -let rec mark_skipped : - type kind. - payload_producer:Signature.Public_key_hash.t -> - Level.t -> - kind Kind.manager prechecked_contents_list -> - kind Kind.manager contents_result_list = - fun ~payload_producer level prechecked_contents_list -> - match[@coq_match_with_default] prechecked_contents_list with - | PrecheckedSingle - { - contents = Manager_operation {operation; _}; - result = {balance_updates; _}; - } -> - Single_result - (Manager_operation_result - { - balance_updates; - operation_result = skipped_operation_result operation; - internal_operation_results = []; - }) - | PrecheckedCons - ( { - contents = Manager_operation {operation; _}; - result = {balance_updates; _}; - }, - rest ) -> - Cons_result - ( Manager_operation_result - { - balance_updates; - operation_result = skipped_operation_result operation; - internal_operation_results = []; - }, - mark_skipped ~payload_producer level rest ) - -(** Returns an updated context, and a list of prechecked contents containing - balance updates for fees related to each manager operation in - [contents_list]. *) -let precheck_manager_contents_list ctxt contents_list ~mempool_mode = - let rec rec_precheck_manager_contents_list : - type kind. - Alpha_context.t -> - kind Kind.manager contents_list -> - (context * kind Kind.manager prechecked_contents_list) tzresult Lwt.t = - fun ctxt contents_list -> - match[@coq_match_with_default] contents_list with - | Single contents -> - precheck_manager_contents ctxt contents ~only_batch:mempool_mode - >>=? fun (ctxt, result) -> - return (ctxt, PrecheckedSingle {contents; result}) - | Cons (contents, rest) -> - precheck_manager_contents ctxt contents ~only_batch:mempool_mode - >>=? fun (ctxt, result) -> - rec_precheck_manager_contents_list ctxt rest - >>=? fun (ctxt, results_rest) -> - return (ctxt, PrecheckedCons ({contents; result}, results_rest)) - in - let ctxt = if mempool_mode then Gas.reset_block_gas ctxt else ctxt in - rec_precheck_manager_contents_list ctxt contents_list - -let check_manager_signature ctxt chain_id (op : _ Kind.manager contents_list) - raw_operation = - (* Currently, the [op] only contains one signature, so - all operations are required to be from the same manager. This may - change in the future, allowing several managers to group-sign a - sequence of transactions. *) - let check_same_manager (source, source_key) manager = - match manager with - | None -> - (* Consistency already checked by - [reveal_manager_key] in [precheck_manager_contents]. *) - ok (source, source_key) - | Some (manager, manager_key) -> - if Signature.Public_key_hash.equal source manager then - ok (source, Option.either manager_key source_key) - else error Inconsistent_sources - in - let rec find_source : - type kind. - kind Kind.manager contents_list -> - (Signature.public_key_hash * Signature.public_key option) option -> - (Signature.public_key_hash * Signature.public_key option) tzresult = - fun contents_list manager -> - let source (type kind) = function[@coq_match_with_default] - | (Manager_operation {source; operation = Reveal key; _} : - kind Kind.manager contents) -> - (source, Some key) - | Manager_operation {source; _} -> (source, None) - in - match contents_list with - | Single op -> check_same_manager (source op) manager - | Cons (op, rest) -> - check_same_manager (source op) manager >>? fun manager -> - find_source rest (Some manager) - in - find_source op None >>?= fun (source, source_key) -> - (match source_key with - | Some key -> return key - | None -> Contract.get_manager_key ctxt source) - >>=? fun public_key -> - Lwt.return (Operation.check_signature public_key chain_id raw_operation) - -let rec apply_manager_contents_list_rec : - type kind. - Alpha_context.t -> - Script_ir_translator.unparsing_mode -> - payload_producer:public_key_hash -> - Chain_id.t -> - kind Kind.manager prechecked_contents_list -> - (success_or_failure * kind Kind.manager contents_result_list) Lwt.t = - fun ctxt mode ~payload_producer chain_id prechecked_contents_list -> - let level = Level.current ctxt in - match[@coq_match_with_default] prechecked_contents_list with - | PrecheckedSingle - { - contents = Manager_operation _ as op; - result = {consumed_gas; balance_updates}; - } -> - apply_manager_contents - ctxt - mode - chain_id - ~gas_consumed_in_precheck:(Some consumed_gas) - op - >|= fun (ctxt_result, operation_result, internal_operation_results) -> - let result = - Manager_operation_result - {balance_updates; operation_result; internal_operation_results} - in - (ctxt_result, Single_result result) - | PrecheckedCons - ( { - contents = Manager_operation _ as op; - result = {consumed_gas; balance_updates}; - }, - rest ) -> ( - apply_manager_contents - ctxt - mode - chain_id - ~gas_consumed_in_precheck:(Some consumed_gas) - op - >>= function - | (Failure, operation_result, internal_operation_results) -> - let result = - Manager_operation_result - {balance_updates; operation_result; internal_operation_results} - in - Lwt.return - ( Failure, - Cons_result (result, mark_skipped ~payload_producer level rest) ) - | (Success ctxt, operation_result, internal_operation_results) -> - let result = - Manager_operation_result - {balance_updates; operation_result; internal_operation_results} - in - apply_manager_contents_list_rec - ctxt - mode - ~payload_producer - chain_id - rest - >|= fun (ctxt_result, results) -> - (ctxt_result, Cons_result (result, results))) - -let mark_backtracked results = - let rec mark_contents_list : - type kind. - kind Kind.manager contents_result_list -> - kind Kind.manager contents_result_list = function - | Single_result (Manager_operation_result op) -> - Single_result - (Manager_operation_result - { - balance_updates = op.balance_updates; - operation_result = - mark_manager_operation_result op.operation_result; - internal_operation_results = - List.map - mark_internal_operation_results - op.internal_operation_results; - }) - | Cons_result (Manager_operation_result op, rest) -> - Cons_result - ( Manager_operation_result - { - balance_updates = op.balance_updates; - operation_result = - mark_manager_operation_result op.operation_result; - internal_operation_results = - List.map - mark_internal_operation_results - op.internal_operation_results; - }, - mark_contents_list rest ) - and mark_internal_operation_results (Internal_operation_result (kind, result)) - = - Internal_operation_result (kind, mark_manager_operation_result result) - and mark_manager_operation_result : - type kind. kind manager_operation_result -> kind manager_operation_result - = function - | (Failed _ | Skipped _ | Backtracked _) as result -> result - | Applied (Reveal_result _) as result -> result - | Applied result -> Backtracked (result, None) - in - mark_contents_list results - [@@coq_axiom_with_reason "non-top-level mutual recursion"] - -type apply_mode = - | Application of { - predecessor_block : Block_hash.t; - payload_hash : Block_payload_hash.t; - locked_round : Round.t option; - predecessor_level : Level.t; - predecessor_round : Round.t; - round : Round.t; - } (* Both partial and normal *) - | Full_construction of { - predecessor_block : Block_hash.t; - payload_hash : Block_payload_hash.t; - predecessor_level : Level.t; - predecessor_round : Round.t; - round : Round.t; - } - | Partial_construction of { - predecessor_level : Level.t; - predecessor_round : Round.t; - grand_parent_round : Round.t; - } - -let get_predecessor_level = function - | Application {predecessor_level; _} - | Full_construction {predecessor_level; _} - | Partial_construction {predecessor_level; _} -> - predecessor_level - -let record_operation (type kind) ctxt (operation : kind operation) : context = - match operation.protocol_data.contents with - | Single (Preendorsement _) -> ctxt - | Single (Endorsement _) -> ctxt - | Single - ( Failing_noop _ | Proposals _ | Ballot _ | Seed_nonce_revelation _ - | Double_endorsement_evidence _ | Double_preendorsement_evidence _ - | Double_baking_evidence _ | Activate_account _ | Manager_operation _ ) - | Cons (Manager_operation _, _) -> - let hash = Operation.hash operation in - record_non_consensus_operation_hash ctxt hash - -type 'consensus_op_kind expected_consensus_content = { - payload_hash : Block_payload_hash.t; - branch : Block_hash.t; - level : Level.t; - round : Round.t; -} - -(* The [Alpha_context] is modified only in [Full_construction] mode - when we check a preendorsement if the [preendorsement_quorum_round] - was not set. *) -let compute_expected_consensus_content (type consensus_op_kind) - ~(current_level : Level.t) ~(proposal_level : Level.t) - (ctxt : Alpha_context.t) (application_mode : apply_mode) - (operation_kind : consensus_op_kind consensus_operation_type) - (operation_round : Round.t) (operation_level : Raw_level.t) : - (Alpha_context.t * consensus_op_kind expected_consensus_content) tzresult - Lwt.t = - match operation_kind with - | Endorsement -> ( - match Consensus.endorsement_branch ctxt with - | None -> ( - match application_mode with - | Application _ | Full_construction _ -> - fail Unexpected_endorsement_in_block - | Partial_construction _ -> - fail - (Consensus_operation_for_future_level - {expected = proposal_level.level; provided = operation_level}) - ) - | Some (branch, payload_hash) -> ( - match application_mode with - | Application {predecessor_round; _} - | Full_construction {predecessor_round; _} - | Partial_construction {predecessor_round; _} -> - return - ( ctxt, - { - payload_hash; - branch; - level = proposal_level; - round = predecessor_round; - } ))) - | Preendorsement -> ( - match application_mode with - | Application {locked_round = None; _} -> - fail Unexpected_preendorsement_in_block - | Application - { - payload_hash; - predecessor_block = branch; - locked_round = Some locked_round; - _; - } -> - return - ( ctxt, - { - payload_hash; - branch; - level = current_level; - round = locked_round; - } ) - | Partial_construction {predecessor_round; _} -> ( - match Consensus.endorsement_branch ctxt with - | None -> - fail - (Consensus_operation_for_future_level - {expected = proposal_level.level; provided = operation_level}) - | Some (branch, payload_hash) -> - return - ( ctxt, - { - payload_hash; - branch; - level = proposal_level; - round = predecessor_round; - } )) - | Full_construction {payload_hash; predecessor_block = branch; _} -> - let (ctxt', round) = - match Consensus.get_preendorsements_quorum_round ctxt with - | None -> - ( Consensus.set_preendorsements_quorum_round ctxt operation_round, - operation_round ) - | Some round -> (ctxt, round) - in - return (ctxt', {payload_hash; branch; level = current_level; round})) - -let check_level (apply_mode : apply_mode) ~expected ~provided = - match apply_mode with - | Application _ | Full_construction _ -> - error_unless - (Raw_level.equal expected provided) - (Wrong_level_for_consensus_operation {expected; provided}) - | Partial_construction _ -> - (* Valid grand parent's endorsements were treated by - [validate_grand_parent_endorsement]. *) - error_when - Raw_level.(expected > provided) - (Consensus_operation_for_old_level {expected; provided}) - >>? fun () -> - error_when - Raw_level.(expected < provided) - (Consensus_operation_for_future_level {expected; provided}) - -let check_payload_hash (apply_mode : apply_mode) ~expected ~provided = - match apply_mode with - | Application _ | Full_construction _ -> - error_unless - (Block_payload_hash.equal expected provided) - (Wrong_payload_hash_for_consensus_operation {expected; provided}) - | Partial_construction _ -> - error_unless - (Block_payload_hash.equal expected provided) - (Consensus_operation_on_competing_proposal {expected; provided}) - -let check_operation_branch ~expected ~provided = - error_unless - (Block_hash.equal expected provided) - (Wrong_consensus_operation_branch (expected, provided)) - -let check_round (type kind) (operation_kind : kind consensus_operation_type) - (apply_mode : apply_mode) ~(expected : Round.t) ~(provided : Round.t) : - unit tzresult = - match apply_mode with - | Partial_construction _ -> - error_when - Round.(expected > provided) - (Consensus_operation_for_old_round {expected; provided}) - >>? fun () -> - error_when - Round.(expected < provided) - (Consensus_operation_for_future_round {expected; provided}) - | Full_construction {round; _} | Application {round; _} -> - (match operation_kind with - | Preendorsement -> - error_when - Round.(round <= provided) - (Preendorsement_round_too_high {block_round = round; provided}) - | Endorsement -> Result.return_unit) - >>? fun () -> - error_unless - (Round.equal expected provided) - (Wrong_round_for_consensus_operation {expected; provided}) - -let check_consensus_content (type kind) (apply_mode : apply_mode) - (content : consensus_content) (operation_branch : Block_hash.t) - (operation_kind : kind consensus_operation_type) - (expected_content : kind expected_consensus_content) : unit tzresult = - let expected_level = expected_content.level.level in - let provided_level = content.level in - let expected_round = expected_content.round in - let provided_round = content.round in - check_level apply_mode ~expected:expected_level ~provided:provided_level - >>? fun () -> - check_round - operation_kind - apply_mode - ~expected:expected_round - ~provided:provided_round - >>? fun () -> - check_operation_branch - ~expected:expected_content.branch - ~provided:operation_branch - >>? fun () -> - check_payload_hash - apply_mode - ~expected:expected_content.payload_hash - ~provided:content.block_payload_hash - -(* Validate the 'operation.shell.branch' field of the operation. It MUST point - to the grandfather: the block hash used in the payload_hash. Otherwise we could produce - a preendorsement pointing to the direct proposal. This preendorsement wouldn't be able to - propagate for a subsequent proposal using it as a locked_round evidence. *) -let validate_consensus_contents (type kind) ctxt chain_id - (operation_kind : kind consensus_operation_type) - (operation : kind operation) (apply_mode : apply_mode) - (content : consensus_content) : - (context * public_key_hash * int) tzresult Lwt.t = - let current_level = Level.current ctxt in - let proposal_level = get_predecessor_level apply_mode in - let slot_map = - match operation_kind with - | Preendorsement -> Consensus.allowed_preendorsements ctxt - | Endorsement -> Consensus.allowed_endorsements ctxt - in - compute_expected_consensus_content - ~current_level - ~proposal_level - ctxt - apply_mode - operation_kind - content.round - content.level - >>=? fun (ctxt, expected_content) -> - check_consensus_content - apply_mode - content - operation.shell.branch - operation_kind - expected_content - >>?= fun () -> - match Slot.Map.find content.slot slot_map with - | None -> fail Wrong_slot_used_for_consensus_operation - | Some (delegate_pk, delegate_pkh, voting_power) -> - Delegate.frozen_deposits ctxt delegate_pkh >>=? fun frozen_deposits -> - fail_unless - Tez.(frozen_deposits.current_amount > zero) - (Zero_frozen_deposits delegate_pkh) - >>=? fun () -> - Operation.check_signature delegate_pk chain_id operation >>?= fun () -> - return (ctxt, delegate_pkh, voting_power) - -let apply_manager_contents_list ctxt mode ~payload_producer chain_id - prechecked_contents_list = - apply_manager_contents_list_rec - ctxt - mode - ~payload_producer - chain_id - prechecked_contents_list - >>= fun (ctxt_result, results) -> - match ctxt_result with - | Failure -> Lwt.return (ctxt (* backtracked *), mark_backtracked results) - | Success ctxt -> - Lazy_storage.cleanup_temporaries ctxt >|= fun ctxt -> (ctxt, results) - -let check_denunciation_age ctxt kind given_level = - let max_slashing_period = Constants.max_slashing_period ctxt in - let current_cycle = (Level.current ctxt).cycle in - let given_cycle = (Level.from_raw ctxt given_level).cycle in - let last_slashable_cycle = Cycle.add given_cycle max_slashing_period in - fail_when - Cycle.(given_cycle > current_cycle) - (Too_early_denunciation - {kind; level = given_level; current = (Level.current ctxt).level}) - >>=? fun () -> - fail_unless - Cycle.(last_slashable_cycle > current_cycle) - (Outdated_denunciation - {kind; level = given_level; last_cycle = last_slashable_cycle}) - -let punish_delegate ctxt delegate level mistake mk_result ~payload_producer = - let (already_slashed, punish) = - match mistake with - | `Double_baking -> - ( Delegate.already_slashed_for_double_baking, - Delegate.punish_double_baking ) - | `Double_endorsing -> - ( Delegate.already_slashed_for_double_endorsing, - Delegate.punish_double_endorsing ) - in - already_slashed ctxt delegate level >>=? fun slashed -> - fail_when slashed Unrequired_denunciation >>=? fun () -> - punish ctxt delegate level >>=? fun (ctxt, burned, punish_balance_updates) -> - (match Tez.(burned /? 2L) with - | Ok reward -> - Token.transfer - ctxt - `Double_signing_evidence_rewards - (`Contract (Contract.implicit_contract payload_producer)) - reward - | Error _ -> (* reward is Tez.zero *) return (ctxt, [])) - >|=? fun (ctxt, reward_balance_updates) -> - let balance_updates = reward_balance_updates @ punish_balance_updates in - (ctxt, Single_result (mk_result balance_updates)) - -let punish_double_endorsement_or_preendorsement (type kind) ctxt ~chain_id - ~preendorsement ~(op1 : kind Kind.consensus Operation.t) - ~(op2 : kind Kind.consensus Operation.t) ~payload_producer : - (t * kind Kind.double_consensus_operation_evidence contents_result_list) - tzresult - Lwt.t = - let mk_result (balance_updates : Receipt.balance_updates) : - kind Kind.double_consensus_operation_evidence contents_result = - match op1.protocol_data.contents with - | Single (Preendorsement _) -> - Double_preendorsement_evidence_result balance_updates - | Single (Endorsement _) -> - Double_endorsement_evidence_result balance_updates - in - match (op1.protocol_data.contents, op2.protocol_data.contents) with - | (Single (Preendorsement e1), Single (Preendorsement e2)) - | (Single (Endorsement e1), Single (Endorsement e2)) -> - let kind = if preendorsement then Preendorsement else Endorsement in - let op1_hash = Operation.hash op1 in - let op2_hash = Operation.hash op2 in - fail_unless - (Raw_level.(e1.level = e2.level) - && Round.(e1.round = e2.round) - && (not - (Block_payload_hash.equal - e1.block_payload_hash - e2.block_payload_hash)) - && (* we require an order on hashes to avoid the existence of - equivalent evidences *) - Operation_hash.(op1_hash < op2_hash)) - (Invalid_denunciation kind) - >>=? fun () -> - (* Disambiguate: levels are equal *) - let level = Level.from_raw ctxt e1.level in - check_denunciation_age ctxt kind level.level >>=? fun () -> - Stake_distribution.slot_owner ctxt level e1.slot - >>=? fun (ctxt, (delegate1_pk, delegate1)) -> - Stake_distribution.slot_owner ctxt level e2.slot - >>=? fun (ctxt, (_delegate2_pk, delegate2)) -> - fail_unless - (Signature.Public_key_hash.equal delegate1 delegate2) - (Inconsistent_denunciation {kind; delegate1; delegate2}) - >>=? fun () -> - let (delegate_pk, delegate) = (delegate1_pk, delegate1) in - Operation.check_signature delegate_pk chain_id op1 >>?= fun () -> - Operation.check_signature delegate_pk chain_id op2 >>?= fun () -> - punish_delegate - ctxt - delegate - level - `Double_endorsing - mk_result - ~payload_producer - -let punish_double_baking ctxt chain_id bh1 bh2 ~payload_producer = - let hash1 = Block_header.hash bh1 in - let hash2 = Block_header.hash bh2 in - Fitness.from_raw bh1.shell.fitness >>?= fun bh1_fitness -> - let round1 = Fitness.round bh1_fitness in - Fitness.from_raw bh2.shell.fitness >>?= fun bh2_fitness -> - let round2 = Fitness.round bh2_fitness in - ( Raw_level.of_int32 bh1.shell.level >>?= fun level1 -> - Raw_level.of_int32 bh2.shell.level >>?= fun level2 -> - fail_unless - (Compare.Int32.(bh1.shell.level = bh2.shell.level) - && Round.(round1 = round2) - && (* we require an order on hashes to avoid the existence of - equivalent evidences *) - Block_hash.(hash1 < hash2)) - (Invalid_double_baking_evidence - {hash1; level1; round1; hash2; level2; round2}) ) - >>=? fun () -> - Raw_level.of_int32 bh1.shell.level >>?= fun raw_level -> - check_denunciation_age ctxt Block raw_level >>=? fun () -> - let level = Level.from_raw ctxt raw_level in - let committee_size = Constants.consensus_committee_size ctxt in - Round.to_slot round1 ~committee_size >>?= fun slot1 -> - Stake_distribution.slot_owner ctxt level slot1 - >>=? fun (ctxt, (delegate1_pk, delegate1)) -> - Round.to_slot round2 ~committee_size >>?= fun slot2 -> - Stake_distribution.slot_owner ctxt level slot2 - >>=? fun (ctxt, (_delegate2_pk, delegate2)) -> - fail_unless - Signature.Public_key_hash.(delegate1 = delegate2) - (Inconsistent_denunciation {kind = Block; delegate1; delegate2}) - >>=? fun () -> - let (delegate_pk, delegate) = (delegate1_pk, delegate1) in - Block_header.check_signature bh1 chain_id delegate_pk >>?= fun () -> - Block_header.check_signature bh2 chain_id delegate_pk >>?= fun () -> - punish_delegate - ctxt - delegate - level - `Double_baking - ~payload_producer - (fun balance_updates -> Double_baking_evidence_result balance_updates) - -let is_parent_endorsement ctxt ~proposal_level ~grand_parent_round - (operation : 'a operation) (operation_content : consensus_content) = - match Consensus.grand_parent_branch ctxt with - | None -> false - | Some (great_grand_parent_hash, grand_parent_payload_hash) -> - (* Check level *) - Raw_level.(proposal_level.Level.level = succ operation_content.level) - (* Check round *) - && Round.(grand_parent_round = operation_content.round) - (* Check payload *) - && Block_payload_hash.( - grand_parent_payload_hash = operation_content.block_payload_hash) - && (* Check branch *) - Block_hash.(great_grand_parent_hash = operation.shell.branch) - -let validate_grand_parent_endorsement ctxt chain_id - (op : Kind.endorsement operation) = - match op.protocol_data.contents with - | Single (Endorsement e) -> - let level = Level.from_raw ctxt e.level in - Stake_distribution.slot_owner ctxt level e.slot - >>=? fun (ctxt, (delegate_pk, pkh)) -> - Operation.check_signature delegate_pk chain_id op >>?= fun () -> - Consensus.record_grand_parent_endorsement ctxt pkh >>?= fun ctxt -> - return - ( ctxt, - Single_result - (Endorsement_result - { - balance_updates = []; - delegate = pkh; - endorsement_power = - 0 (* dummy endorsement power: this will never be used *); - }) ) - -let apply_contents_list (type kind) ctxt chain_id (apply_mode : apply_mode) mode - ~payload_producer (operation : kind operation) - (contents_list : kind contents_list) : - (context * kind contents_result_list) tzresult Lwt.t = - let mempool_mode = - match apply_mode with - | Partial_construction _ -> true - | Full_construction _ | Application _ -> false - in - match[@coq_match_with_default] contents_list with - | Single (Preendorsement consensus_content) -> - validate_consensus_contents - ctxt - chain_id - Preendorsement - operation - apply_mode - consensus_content - >>=? fun (ctxt, delegate, voting_power) -> - Consensus.record_preendorsement - ctxt - ~initial_slot:consensus_content.slot - ~power:voting_power - consensus_content.round - >>?= fun ctxt -> - return - ( ctxt, - Single_result - (Preendorsement_result - { - balance_updates = []; - delegate; - preendorsement_power = voting_power; - }) ) - | Single (Endorsement consensus_content) -> ( - let proposal_level = get_predecessor_level apply_mode in - match apply_mode with - | Partial_construction {grand_parent_round; _} - when is_parent_endorsement - ctxt - ~proposal_level - ~grand_parent_round - operation - consensus_content -> - validate_grand_parent_endorsement ctxt chain_id operation - | _ -> - validate_consensus_contents - ctxt - chain_id - Endorsement - operation - apply_mode - consensus_content - >>=? fun (ctxt, delegate, voting_power) -> - Consensus.record_endorsement - ctxt - ~initial_slot:consensus_content.slot - ~power:voting_power - >>?= fun ctxt -> - return - ( ctxt, - Single_result - (Endorsement_result - { - balance_updates = []; - delegate; - endorsement_power = voting_power; - }) )) - | Single (Seed_nonce_revelation {level; nonce}) -> - let level = Level.from_raw ctxt level in - Nonce.reveal ctxt level nonce >>=? fun ctxt -> - let tip = Constants.seed_nonce_revelation_tip ctxt in - let contract = Contract.implicit_contract payload_producer in - Token.transfer ctxt `Revelation_rewards (`Contract contract) tip - >|=? fun (ctxt, balance_updates) -> - (ctxt, Single_result (Seed_nonce_revelation_result balance_updates)) - | Single (Double_preendorsement_evidence {op1; op2}) -> - punish_double_endorsement_or_preendorsement - ctxt - ~preendorsement:true - ~chain_id - ~op1 - ~op2 - ~payload_producer - | Single (Double_endorsement_evidence {op1; op2}) -> - punish_double_endorsement_or_preendorsement - ctxt - ~preendorsement:false - ~chain_id - ~op1 - ~op2 - ~payload_producer - | Single (Double_baking_evidence {bh1; bh2}) -> - punish_double_baking ctxt chain_id bh1 bh2 ~payload_producer - | Single (Activate_account {id = pkh; activation_code}) -> - let blinded_pkh = - Blinded_public_key_hash.of_ed25519_pkh activation_code pkh - in - let src = `Collected_commitments blinded_pkh in - Token.allocated ctxt src >>=? fun src_exists -> - fail_unless src_exists (Invalid_activation {pkh}) >>=? fun _ -> - let contract = Contract.implicit_contract (Signature.Ed25519 pkh) in - Token.balance ctxt src >>=? fun amount -> - Token.transfer ctxt src (`Contract contract) amount - >>=? fun (ctxt, bupds) -> - return (ctxt, Single_result (Activate_account_result bupds)) - | Single (Proposals {source; period; proposals}) -> - Delegate.pubkey ctxt source >>=? fun delegate -> - Operation.check_signature delegate chain_id operation >>?= fun () -> - Voting_period.get_current ctxt >>=? fun {index = current_period; _} -> - error_unless - Compare.Int32.(current_period = period) - (Wrong_voting_period (current_period, period)) - >>?= fun () -> - Amendment.record_proposals ctxt source proposals >|=? fun ctxt -> - (ctxt, Single_result Proposals_result) - | Single (Ballot {source; period; proposal; ballot}) -> - Delegate.pubkey ctxt source >>=? fun delegate -> - Operation.check_signature delegate chain_id operation >>?= fun () -> - Voting_period.get_current ctxt >>=? fun {index = current_period; _} -> - error_unless - Compare.Int32.(current_period = period) - (Wrong_voting_period (current_period, period)) - >>?= fun () -> - Amendment.record_ballot ctxt source proposal ballot >|=? fun ctxt -> - (ctxt, Single_result Ballot_result) - | Single (Failing_noop _) -> - (* Failing_noop _ always fails *) - fail Failing_noop_error - | Single (Manager_operation _) as op -> - precheck_manager_contents_list ctxt op ~mempool_mode - >>=? fun (ctxt, prechecked_contents_list) -> - check_manager_signature ctxt chain_id op operation >>=? fun () -> - apply_manager_contents_list - ctxt - mode - ~payload_producer - chain_id - prechecked_contents_list - >|= ok - | Cons (Manager_operation _, _) as op -> - precheck_manager_contents_list ctxt op ~mempool_mode - >>=? fun (ctxt, prechecked_contents_list) -> - check_manager_signature ctxt chain_id op operation >>=? fun () -> - apply_manager_contents_list - ctxt - mode - ~payload_producer - chain_id - prechecked_contents_list - >|= ok - -let apply_operation ctxt chain_id (apply_mode : apply_mode) mode - ~payload_producer hash operation = - let ctxt = Contract.init_origination_nonce ctxt hash in - let ctxt = record_operation ctxt operation in - apply_contents_list - ctxt - chain_id - apply_mode - mode - ~payload_producer - operation - operation.protocol_data.contents - >|=? fun (ctxt, result) -> - let ctxt = Gas.set_unlimited ctxt in - let ctxt = Contract.unset_origination_nonce ctxt in - (ctxt, {contents = result}) - -let may_start_new_cycle ctxt = - match Level.dawn_of_a_new_cycle ctxt with - | None -> return (ctxt, [], []) - | Some last_cycle -> - Seed.cycle_end ctxt last_cycle >>=? fun (ctxt, unrevealed) -> - Delegate.cycle_end ctxt last_cycle unrevealed - >>=? fun (ctxt, balance_updates, deactivated) -> - Bootstrap.cycle_end ctxt last_cycle >|=? fun ctxt -> - (ctxt, balance_updates, deactivated) - -let init_allowed_consensus_operations ctxt ~endorsement_level - ~preendorsement_level = - Delegate.prepare_stake_distribution ctxt >>=? fun ctxt -> - (if Level.(endorsement_level = preendorsement_level) then - Baking.endorsing_rights_by_first_slot ctxt endorsement_level - >>=? fun (ctxt, slots) -> - let consensus_operations = slots in - return (ctxt, consensus_operations, consensus_operations) - else - Baking.endorsing_rights_by_first_slot ctxt endorsement_level - >>=? fun (ctxt, endorsements_slots) -> - let endorsements = endorsements_slots in - Baking.endorsing_rights_by_first_slot ctxt preendorsement_level - >>=? fun (ctxt, preendorsements_slots) -> - let preendorsements = preendorsements_slots in - return (ctxt, endorsements, preendorsements)) - >>=? fun (ctxt, allowed_endorsements, allowed_preendorsements) -> - return - (Consensus.initialize_consensus_operation - ctxt - ~allowed_endorsements - ~allowed_preendorsements) - -let apply_liquidity_baking_subsidy ctxt ~escape_vote = - Liquidity_baking.on_subsidy_allowed - ctxt - ~escape_vote - (fun ctxt liquidity_baking_cpmm_contract -> - let ctxt = - (* We set a gas limit of 1/20th the block limit, which is ~10x - actual usage here in Granada. Gas consumed is reported in - the Transaction receipt, but not counted towards the block - limit. The gas limit is reset to unlimited at the end of - this function.*) - Gas.set_limit - ctxt - (Gas.Arith.integral_exn - (Z.div - (Gas.Arith.integral_to_z - (Constants.hard_gas_limit_per_block ctxt)) - (Z.of_int 20))) - in - let backtracking_ctxt = ctxt in - (let liquidity_baking_subsidy = Constants.liquidity_baking_subsidy ctxt in - (* credit liquidity baking subsidy to CPMM contract *) - Token.transfer - ~origin:Subsidy - ctxt - `Liquidity_baking_subsidies - (`Contract liquidity_baking_cpmm_contract) - liquidity_baking_subsidy - >>=? fun (ctxt, balance_updates) -> - Script_cache.find ctxt liquidity_baking_cpmm_contract - >>=? fun (ctxt, cache_key, script) -> - match script with - | None -> fail (Script_tc_errors.No_such_entrypoint "default") - | Some (script, script_ir) -> ( - let now = Script_timestamp.now ctxt in - let level = - (Level.current ctxt).level |> Raw_level.to_int32 - |> Script_int.of_int32 |> Script_int.abs - in - let step_constants = - let open Script_interpreter in - (* Using dummy values for source, payer, and chain_id - since they are not used within the CPMM default - entrypoint. *) - { - source = liquidity_baking_cpmm_contract; - payer = liquidity_baking_cpmm_contract; - self = liquidity_baking_cpmm_contract; - amount = liquidity_baking_subsidy; - chain_id = Chain_id.zero; - now; - level; - } - in - let parameter = - Micheline.strip_locations - Michelson_v1_primitives.(Prim (0, D_Unit, [], [])) - in - (* - Call CPPM default entrypoint with parameter Unit. - This is necessary for the CPMM's xtz_pool in storage to - increase since it cannot use BALANCE due to a transfer attack. - - Mimicks a transaction. - - There is no: - - storage burn (extra storage is free) - - fees (the operation is mandatory) - *) - Script_interpreter.execute - ctxt - Optimized - step_constants - ~script - ~parameter - ~cached_script:(Some script_ir) - ~entrypoint:"default" - ~internal:false - >>=? fun ( {ctxt; storage; lazy_storage_diff; operations}, - (updated_cached_script, updated_size) ) -> - match operations with - | _ :: _ -> - (* No internal operations are expected here. Something bad may be happening. *) - return (backtracking_ctxt, []) - | [] -> - (* update CPMM storage *) - Contract.update_script_storage - ctxt - liquidity_baking_cpmm_contract - storage - lazy_storage_diff - >>=? fun ctxt -> - Fees.record_paid_storage_space - ctxt - liquidity_baking_cpmm_contract - >>=? fun (ctxt, new_size, paid_storage_size_diff) -> - let consumed_gas = - Gas.consumed ~since:backtracking_ctxt ~until:ctxt - in - Script_cache.update - ctxt - cache_key - ( {script with storage = Script.lazy_expr storage}, - updated_cached_script ) - updated_size - >>?= fun ctxt -> - let result = - Transaction_result - { - storage = Some storage; - lazy_storage_diff; - balance_updates; - (* At this point in application the origination nonce has not been initialized so it's not possible to originate new contracts. We've checked above that none were originated. *) - originated_contracts = []; - consumed_gas; - storage_size = new_size; - paid_storage_size_diff; - allocated_destination_contract = false; - } - in - let ctxt = Gas.set_unlimited ctxt in - return (ctxt, [Successful_manager_result result]))) - >|= function - | Ok (ctxt, results) -> Ok (ctxt, results) - | Error _ -> - (* Do not fail if something bad happens during CPMM contract call. *) - let ctxt = Gas.set_unlimited backtracking_ctxt in - Ok (ctxt, [])) - -type 'a full_construction = { - ctxt : t; - protocol_data : 'a; - payload_producer : Signature.public_key_hash; - block_producer : Signature.public_key_hash; - round : Round.t; - implicit_operations_results : packed_successful_manager_operation_result list; - liquidity_baking_escape_ema : Liquidity_baking.escape_ema; -} - -let begin_full_construction ctxt ~predecessor_timestamp ~predecessor_level - ~predecessor_round ~round protocol_data = - let round_durations = Constants.round_durations ctxt in - let timestamp = Timestamp.current ctxt in - Block_header.check_timestamp - round_durations - ~timestamp - ~round - ~predecessor_timestamp - ~predecessor_round - >>?= fun () -> - let current_level = Level.current ctxt in - Stake_distribution.baking_rights_owner ctxt current_level ~round - >>=? fun (ctxt, _slot, (_block_producer_pk, block_producer)) -> - Delegate.frozen_deposits ctxt block_producer >>=? fun frozen_deposits -> - fail_unless - Tez.(frozen_deposits.current_amount > zero) - (Zero_frozen_deposits block_producer) - >>=? fun () -> - Stake_distribution.baking_rights_owner - ctxt - current_level - ~round:protocol_data.Block_header.payload_round - >>=? fun (ctxt, _slot, (_payload_producer_pk, payload_producer)) -> - init_allowed_consensus_operations - ctxt - ~endorsement_level:predecessor_level - ~preendorsement_level:current_level - >>=? fun ctxt -> - let escape_vote = protocol_data.liquidity_baking_escape_vote in - apply_liquidity_baking_subsidy ctxt ~escape_vote - >|=? fun ( ctxt, - liquidity_baking_operations_results, - liquidity_baking_escape_ema ) -> - { - ctxt; - protocol_data; - payload_producer; - block_producer; - round; - implicit_operations_results = liquidity_baking_operations_results; - liquidity_baking_escape_ema; - } - -let begin_partial_construction ctxt ~predecessor_level ~escape_vote = - (* In the mempool, only consensus operations for [predecessor_level] - (that is, head's level) are allowed, contrary to block validation - where endorsements are for the previous level and - preendorsements, if any, for the block's level. *) - init_allowed_consensus_operations - ctxt - ~endorsement_level:predecessor_level - ~preendorsement_level:predecessor_level - >>=? fun ctxt -> apply_liquidity_baking_subsidy ctxt ~escape_vote - -let begin_application ctxt chain_id (block_header : Block_header.t) fitness - ~predecessor_timestamp ~predecessor_level ~predecessor_round = - let round = Fitness.round fitness in - let current_level = Level.current ctxt in - Stake_distribution.baking_rights_owner ctxt current_level ~round - >>=? fun (ctxt, _slot, (block_producer_pk, block_producer)) -> - let round_durations = Constants.round_durations ctxt in - let timestamp = block_header.shell.timestamp in - Block_header.begin_validate_block_header - ~block_header - ~chain_id - ~predecessor_timestamp - ~predecessor_round - ~fitness - ~timestamp - ~delegate_pk:block_producer_pk - ~round_durations - ~proof_of_work_threshold:(Constants.proof_of_work_threshold ctxt) - ~expected_commitment:current_level.expected_commitment - >>?= fun () -> - Delegate.frozen_deposits ctxt block_producer >>=? fun frozen_deposits -> - fail_unless - Tez.(frozen_deposits.current_amount > zero) - (Zero_frozen_deposits block_producer) - >>=? fun () -> - Stake_distribution.baking_rights_owner - ctxt - current_level - ~round:block_header.protocol_data.contents.payload_round - >>=? fun (ctxt, _slot, (payload_producer_pk, _payload_producer)) -> - init_allowed_consensus_operations - ctxt - ~endorsement_level:predecessor_level - ~preendorsement_level:current_level - >>=? fun ctxt -> - let escape_vote = - block_header.Block_header.protocol_data.contents - .liquidity_baking_escape_vote - in - apply_liquidity_baking_subsidy ctxt ~escape_vote - >|=? fun ( ctxt, - liquidity_baking_operations_results, - liquidity_baking_escape_ema ) -> - ( ctxt, - payload_producer_pk, - block_producer, - liquidity_baking_operations_results, - liquidity_baking_escape_ema ) - -type finalize_application_mode = - | Finalize_full_construction of { - level : Raw_level.t; - predecessor_round : Round.t; - } - | Finalize_application of Fitness.t - -let compute_payload_hash (ctxt : Alpha_context.t) ~(predecessor : Block_hash.t) - ~(payload_round : Round.t) : Block_payload_hash.t = - let non_consensus_operations = non_consensus_operations ctxt in - let operations_hash = Operation_list_hash.compute non_consensus_operations in - Block_payload.hash ~predecessor payload_round operations_hash - -let are_endorsements_required ctxt ~level = - Alpha_context.First_level_of_tenderbake.get ctxt - >|=? fun first_Tenderbake_level -> - (* NB: the first level is the level of the migration block. This - block was proposed by an Emmy* baker. There are no - endorsements for this block. Therefore the block at the next - level cannot contain endorsements. *) - let tenderbake_level_position = Raw_level.diff level first_Tenderbake_level in - Compare.Int32.(tenderbake_level_position > 1l) - -let check_minimum_endorsements ~endorsing_power ~minimum = - fail_when - Compare.Int.(endorsing_power < minimum) - (Not_enough_endorsements - {required = minimum; endorsements = endorsing_power}) - -let finalize_application_check_validity ctxt (mode : finalize_application_mode) - protocol_data ~round ~predecessor ~endorsing_power ~consensus_threshold - ~required_endorsements = - (if required_endorsements then - check_minimum_endorsements ~endorsing_power ~minimum:consensus_threshold - else return_unit) - >>=? fun () -> - let block_payload_hash = - compute_payload_hash - ctxt - ~predecessor - ~payload_round:protocol_data.Block_header.payload_round - in - let locked_round_evidence = - Option.map - (fun (preendorsement_round, preendorsement_count) -> - Block_header.{preendorsement_round; preendorsement_count}) - (Consensus.locked_round_evidence ctxt) - in - (match mode with - | Finalize_application fitness -> ok fitness - | Finalize_full_construction {level; predecessor_round} -> - let locked_round = - match locked_round_evidence with - | None -> None - | Some {preendorsement_round; _} -> Some preendorsement_round - in - Fitness.create ~level ~round ~predecessor_round ~locked_round) - >>?= fun fitness -> - let checkable_payload_hash : Block_header.checkable_payload_hash = - match mode with - | Finalize_application _ -> Expected_payload_hash block_payload_hash - | Finalize_full_construction _ -> ( - match locked_round_evidence with - | Some _ -> Expected_payload_hash block_payload_hash - | None -> - (* In full construction, when there is no locked round - evidence (and thus no preendorsements), the baker cannot - know the payload hash before selecting the operations. We - may dismiss checking the initially given - payload_hash. However, to be valid, the baker must patch - the resulting block header with the actual payload - hash. *) - No_check) - in - Block_header.finalize_validate_block_header - ~block_header_contents:protocol_data - ~round - ~fitness - ~checkable_payload_hash - ~locked_round_evidence - ~consensus_threshold - >>?= fun () -> return (fitness, block_payload_hash) - -let record_endorsing_participation ctxt = - let validators = Consensus.allowed_endorsements ctxt in - Slot.Map.fold_es - (fun initial_slot (_delegate_pk, delegate, power) ctxt -> - let participation = - if Slot.Set.mem initial_slot (Consensus.endorsements_seen ctxt) then - Delegate.Participated - else Delegate.Didn't_participate - in - Delegate.record_endorsing_participation - ctxt - ~delegate - ~participation - ~endorsing_power:power) - validators - ctxt - -let finalize_application ctxt (mode : finalize_application_mode) protocol_data - ~payload_producer ~block_producer liquidity_baking_escape_ema - implicit_operations_results ~round ~predecessor ~migration_balance_updates = - let level = Alpha_context.Level.current ctxt in - let block_endorsing_power = Consensus.current_endorsement_power ctxt in - let consensus_threshold = Constants.consensus_threshold ctxt in - are_endorsements_required ctxt ~level:level.level - >>=? fun required_endorsements -> - finalize_application_check_validity - ctxt - mode - protocol_data - ~round - ~predecessor - ~endorsing_power:block_endorsing_power - ~consensus_threshold - ~required_endorsements - >>=? fun (fitness, block_payload_hash) -> - (* from this point nothing should fail *) - (* We mark the endorsement branch as the grand parent branch when - accessible. This will not be present before the first two blocks - of tenderbake. *) - (match Consensus.endorsement_branch ctxt with - | Some predecessor_branch -> - Consensus.store_grand_parent_branch ctxt predecessor_branch >>= return - | None -> return ctxt) - >>=? fun ctxt -> - (* We mark the current payload hash as the predecessor one => this - will only be accessed by the successor block now. *) - Consensus.store_endorsement_branch ctxt (predecessor, block_payload_hash) - >>= fun ctxt -> - Round.update ctxt round >>=? fun ctxt -> - (* end of level *) - (match protocol_data.Block_header.seed_nonce_hash with - | None -> return ctxt - | Some nonce_hash -> - Nonce.record_hash ctxt {nonce_hash; delegate = block_producer}) - >>=? fun ctxt -> - (if required_endorsements then - record_endorsing_participation ctxt >>=? fun ctxt -> - Baking.bonus_baking_reward ctxt ~endorsing_power:block_endorsing_power - >>?= fun rewards_bonus -> return (ctxt, Some rewards_bonus) - else return (ctxt, None)) - >>=? fun (ctxt, reward_bonus) -> - let baking_reward = Constants.baking_reward_fixed_portion ctxt in - Delegate.record_baking_activity_and_pay_rewards_and_fees - ctxt - ~payload_producer - ~block_producer - ~baking_reward - ~reward_bonus - >>=? fun (ctxt, baking_receipts) -> - (* end of cycle *) - (if Level.may_snapshot_rolls ctxt then Stake_distribution.snapshot ctxt - else return ctxt) - >>=? fun ctxt -> - may_start_new_cycle ctxt - >>=? fun (ctxt, cycle_end_balance_updates, deactivated) -> - Amendment.may_start_new_voting_period ctxt >>=? fun ctxt -> - let balance_updates = - migration_balance_updates @ baking_receipts @ cycle_end_balance_updates - in - let consumed_gas = - Gas.Arith.sub - (Gas.Arith.fp @@ Constants.hard_gas_limit_per_block ctxt) - (Gas.block_level ctxt) - in - Voting_period.get_rpc_current_info ctxt >|=? fun voting_period_info -> - let receipt = - Apply_results. - { - proposer = payload_producer; - baker = block_producer; - level_info = level; - voting_period_info; - nonce_hash = protocol_data.seed_nonce_hash; - consumed_gas; - deactivated; - balance_updates; - liquidity_baking_escape_ema; - implicit_operations_results; - } - in - (ctxt, fitness, receipt) - -let value_of_key ctxt k = Cache.Admin.value_of_key ctxt k diff --git a/src/proto_012_Psithaca/lib_protocol/apply.mli b/src/proto_012_Psithaca/lib_protocol/apply.mli deleted file mode 100644 index 1282375017e1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/apply.mli +++ /dev/null @@ -1,282 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module supports advancing the ledger state by applying [operation]s. - - Each operation application takes and returns an [Alpha_context.t], representing - the old and new state, respectively. - - The [Main] module provides wrappers for the functionality in this module, - satisfying the Protocol signature. - *) - -open Alpha_context -open Apply_results - -type error += - | (* `Temporary *) - Wrong_consensus_operation_branch of - Block_hash.t * Block_hash.t - -type error += - | (* `Permanent *) - Wrong_level_for_consensus_operation of { - expected : Raw_level.t; - provided : Raw_level.t; - } - | (* `Permanent *) - Wrong_round_for_consensus_operation of { - expected : Round.t; - provided : Round.t; - } - | (* `Permanent *) - Preendorsement_round_too_high of { - block_round : Round.t; - provided : Round.t; - } - -type error += - | (* `Permanent *) Internal_operation_replay of packed_internal_operation - -type denunciation_kind = Preendorsement | Endorsement | Block - -type error += (* `Permanent *) Invalid_denunciation of denunciation_kind - -type error += - | (* `Permanent *) - Inconsistent_denunciation of { - kind : denunciation_kind; - delegate1 : Signature.Public_key_hash.t; - delegate2 : Signature.Public_key_hash.t; - } - -type error += - | (* `Temporary *) - Too_early_denunciation of { - kind : denunciation_kind; - level : Raw_level.t; - current : Raw_level.t; - } - -type error += - | (* `Permanent *) - Outdated_denunciation of { - kind : denunciation_kind; - level : Raw_level.t; - last_cycle : Cycle.t; - } - -type error += - | (* `Permanent *) - Invalid_double_baking_evidence of { - hash1 : Block_hash.t; - level1 : Raw_level.t; - round1 : Round.t; - hash2 : Block_hash.t; - level2 : Raw_level.t; - round2 : Round.t; - } - -type error += - | (* Permanent *) Invalid_activation of {pkh : Ed25519.Public_key_hash.t} - -type error += (* Permanent *) Gas_quota_exceeded_init_deserialize - -type error += (* `Permanent *) Inconsistent_sources - -type error += (* `Permanent *) Failing_noop_error - -type error += (* `Branch *) Empty_transaction of Contract.t - -val begin_partial_construction : - t -> - predecessor_level:Level.t -> - escape_vote:bool -> - ( t - * packed_successful_manager_operation_result list - * Liquidity_baking.escape_ema, - error trace ) - result - Lwt.t - -type 'a full_construction = { - ctxt : t; - protocol_data : 'a; - payload_producer : Signature.public_key_hash; - block_producer : Signature.public_key_hash; - round : Round.t; - implicit_operations_results : packed_successful_manager_operation_result list; - liquidity_baking_escape_ema : Liquidity_baking.escape_ema; -} - -val begin_full_construction : - t -> - predecessor_timestamp:Time.t -> - predecessor_level:Level.t -> - predecessor_round:Round.t -> - round:Round.t -> - Block_header.contents -> - Block_header.contents full_construction tzresult Lwt.t - -val begin_application : - t -> - Chain_id.t -> - Block_header.t -> - Fitness.t -> - predecessor_timestamp:Time.t -> - predecessor_level:Level.t -> - predecessor_round:Round.t -> - (t - * Signature.public_key - * Signature.public_key_hash - * packed_successful_manager_operation_result list - * Liquidity_baking.escape_ema) - tzresult - Lwt.t - -type apply_mode = - | Application of { - predecessor_block : Block_hash.t; - payload_hash : Block_payload_hash.t; - locked_round : Round.t option; - predecessor_level : Level.t; - predecessor_round : Round.t; - round : Round.t; - } (* Both partial and normal *) - | Full_construction of { - predecessor_block : Block_hash.t; - payload_hash : Block_payload_hash.t; - predecessor_level : Level.t; - predecessor_round : Round.t; - round : Round.t; - } - | Partial_construction of { - predecessor_level : Level.t; - predecessor_round : Round.t; - grand_parent_round : Round.t; - } - -val apply_operation : - t -> - Chain_id.t -> - apply_mode -> - Script_ir_translator.unparsing_mode -> - payload_producer:public_key_hash -> - Operation_list_hash.elt -> - 'a operation -> - (t * 'a operation_metadata, error trace) result Lwt.t - -type finalize_application_mode = - | Finalize_full_construction of { - level : Raw_level.t; - predecessor_round : Round.t; - } - | Finalize_application of Fitness.t - -val finalize_application : - t -> - finalize_application_mode -> - Alpha_context.Block_header.contents -> - payload_producer:public_key_hash -> - block_producer:public_key_hash -> - Liquidity_baking.escape_ema -> - packed_successful_manager_operation_result list -> - round:Round.t -> - predecessor:Block_hash.t -> - migration_balance_updates:Receipt.balance_updates -> - (t * Fitness.t * block_metadata, error trace) result Lwt.t - -val apply_manager_contents_list : - t -> - Script_ir_translator.unparsing_mode -> - payload_producer:public_key_hash -> - Chain_id.t -> - 'a Kind.manager prechecked_contents_list -> - (t * 'a Kind.manager contents_result_list) Lwt.t - -val apply_contents_list : - t -> - Chain_id.t -> - apply_mode -> - Script_ir_translator.unparsing_mode -> - payload_producer:public_key_hash -> - 'kind operation -> - 'kind contents_list -> - (t * 'kind contents_result_list) tzresult Lwt.t - -(** [precheck_manager_contents_list validation_state contents_list] - Returns an updated context, and a list of prechecked contents - containing balance updates for fees related to each manager - operation in [contents_list] - - If [mempool_mode], the function checks whether the total gas limit - of this batch of operation is below the [gas_limit] of a block and - fails with a permanent error when above. Otherwise, the gas limit - of the batch is removed from the one of the block (when possible) - before moving on. *) -val precheck_manager_contents_list : - t -> - 'kind Kind.manager contents_list -> - mempool_mode:bool -> - (context * 'kind Kind.manager prechecked_contents_list) tzresult Lwt.t - -(** [value_of_key ctxt k] builds a value identified by key [k] - so that it can be put into the cache. *) -val value_of_key : t -> Context.Cache.key -> Context.Cache.value tzresult Lwt.t - -(** [cache_layout] describes how the caches needed by the protocol. - The length of the list defines the number of caches while each - element of this list corresponds to the size limit of each cache. *) -val cache_layout : int list - -(** Check if endorsements are required for a given level. *) -val are_endorsements_required : t -> level:Raw_level.t -> bool tzresult Lwt.t - -(** Check if a block's endorsing power is at least the minim required. *) -val check_minimum_endorsements : - endorsing_power:int -> minimum:int -> unit tzresult Lwt.t - -(** [check_manager_signature validation_state op raw_operation] - The function starts by retrieving the public key hash [pkh] of the manager - operation. In case the operation is batched, the function also checks that - the sources are all the same. - Once the [pkh] is retrieved, the function looks for its associated public - key. For that, the manager operation is inspected to check if it contains - a public key revelation. If not, the public key is searched in the context. - - @return [Error Invalid_signature] if the signature check fails - @return [Error Unrevealed_manager_key] if the manager has not yet been - revealed - @return [Error Failure "get_manager_key"] if the key is not found in the - context - @return [Error Inconsistent_sources] if the operations in a batch are not - from the same manager *) -val check_manager_signature : - t -> - Chain_id.t -> - 'a Kind.manager contents_list -> - 'b operation -> - (unit, error trace) result Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/apply_results.ml b/src/proto_012_Psithaca/lib_protocol/apply_results.ml deleted file mode 100644 index db84ac9e89c4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/apply_results.ml +++ /dev/null @@ -1,1478 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Data_encoding - -let error_encoding = - def - "error" - ~description: - "The full list of RPC errors would be too long to include.\n\ - It is available at RPC `/errors` (GET).\n\ - Errors specific to protocol Alpha have an id that starts with \ - `proto.alpha`." - @@ splitted - ~json: - (conv - (fun err -> - Data_encoding.Json.construct Error_monad.error_encoding err) - (fun json -> - Data_encoding.Json.destruct Error_monad.error_encoding json) - json) - ~binary:Error_monad.error_encoding - -let trace_encoding = make_trace_encoding error_encoding - -type _ successful_manager_operation_result = - | Reveal_result : { - consumed_gas : Gas.Arith.fp; - } - -> Kind.reveal successful_manager_operation_result - | Transaction_result : { - storage : Script.expr option; - lazy_storage_diff : Lazy_storage.diffs option; - balance_updates : Receipt.balance_updates; - originated_contracts : Contract.t list; - consumed_gas : Gas.Arith.fp; - storage_size : Z.t; - paid_storage_size_diff : Z.t; - allocated_destination_contract : bool; - } - -> Kind.transaction successful_manager_operation_result - | Origination_result : { - lazy_storage_diff : Lazy_storage.diffs option; - balance_updates : Receipt.balance_updates; - originated_contracts : Contract.t list; - consumed_gas : Gas.Arith.fp; - storage_size : Z.t; - paid_storage_size_diff : Z.t; - } - -> Kind.origination successful_manager_operation_result - | Delegation_result : { - consumed_gas : Gas.Arith.fp; - } - -> Kind.delegation successful_manager_operation_result - | Register_global_constant_result : { - balance_updates : Receipt.balance_updates; - consumed_gas : Gas.Arith.fp; - size_of_constant : Z.t; - global_address : Script_expr_hash.t; - } - -> Kind.register_global_constant successful_manager_operation_result - | Set_deposits_limit_result : { - consumed_gas : Gas.Arith.fp; - } - -> Kind.set_deposits_limit successful_manager_operation_result - -let migration_origination_result_to_successful_manager_operation_result - ({ - balance_updates; - originated_contracts; - storage_size; - paid_storage_size_diff; - } : - Migration.origination_result) = - Origination_result - { - lazy_storage_diff = None; - balance_updates; - originated_contracts; - consumed_gas = Gas.Arith.zero; - storage_size; - paid_storage_size_diff; - } - -type packed_successful_manager_operation_result = - | Successful_manager_result : - 'kind successful_manager_operation_result - -> packed_successful_manager_operation_result - -let pack_migration_operation_results results = - List.map - (fun el -> - Successful_manager_result - (migration_origination_result_to_successful_manager_operation_result el)) - results - -type 'kind manager_operation_result = - | Applied of 'kind successful_manager_operation_result - | Backtracked of - 'kind successful_manager_operation_result * error trace option - | Failed : 'kind Kind.manager * error trace -> 'kind manager_operation_result - | Skipped : 'kind Kind.manager -> 'kind manager_operation_result -[@@coq_force_gadt] - -type packed_internal_operation_result = - | Internal_operation_result : - 'kind internal_operation * 'kind manager_operation_result - -> packed_internal_operation_result - -module Manager_result = struct - type 'kind case = - | MCase : { - op_case : 'kind Operation.Encoding.Manager_operations.case; - encoding : 'a Data_encoding.t; - kind : 'kind Kind.manager; - iselect : - packed_internal_operation_result -> - ('kind internal_operation * 'kind manager_operation_result) option; - select : - packed_successful_manager_operation_result -> - 'kind successful_manager_operation_result option; - proj : 'kind successful_manager_operation_result -> 'a; - inj : 'a -> 'kind successful_manager_operation_result; - t : 'kind manager_operation_result Data_encoding.t; - } - -> 'kind case - - let make ~op_case ~encoding ~kind ~iselect ~select ~proj ~inj = - let (Operation.Encoding.Manager_operations.MCase {name; _}) = op_case in - let t = - def (Format.asprintf "operation.alpha.operation_result.%s" name) - @@ union - ~tag_size:`Uint8 - [ - case - (Tag 0) - ~title:"Applied" - (merge_objs (obj1 (req "status" (constant "applied"))) encoding) - (fun o -> - match o with - | Skipped _ | Failed _ | Backtracked _ -> None - | Applied o -> ( - match select (Successful_manager_result o) with - | None -> None - | Some o -> Some ((), proj o))) - (fun ((), x) -> Applied (inj x)); - case - (Tag 1) - ~title:"Failed" - (obj2 - (req "status" (constant "failed")) - (req "errors" trace_encoding)) - (function Failed (_, errs) -> Some ((), errs) | _ -> None) - (fun ((), errs) -> Failed (kind, errs)); - case - (Tag 2) - ~title:"Skipped" - (obj1 (req "status" (constant "skipped"))) - (function Skipped _ -> Some () | _ -> None) - (fun () -> Skipped kind); - case - (Tag 3) - ~title:"Backtracked" - (merge_objs - (obj2 - (req "status" (constant "backtracked")) - (opt "errors" trace_encoding)) - encoding) - (fun o -> - match o with - | Skipped _ | Failed _ | Applied _ -> None - | Backtracked (o, errs) -> ( - match select (Successful_manager_result o) with - | None -> None - | Some o -> Some (((), errs), proj o))) - (fun (((), errs), x) -> Backtracked (inj x, errs)); - ] - in - MCase {op_case; encoding; kind; iselect; select; proj; inj; t} - - let[@coq_axiom_with_reason "gadt"] reveal_case = - make - ~op_case:Operation.Encoding.Manager_operations.reveal_case - ~encoding: - Data_encoding.( - obj2 - (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) - (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero)) - ~iselect:(function - | Internal_operation_result (({operation = Reveal _; _} as op), res) -> - Some (op, res) - | _ -> None) - ~select:(function - | Successful_manager_result (Reveal_result _ as op) -> Some op - | _ -> None) - ~kind:Kind.Reveal_manager_kind - ~proj:(function - | Reveal_result {consumed_gas} -> - (Gas.Arith.ceil consumed_gas, consumed_gas)) - ~inj:(fun (consumed_gas, consumed_milligas) -> - assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; - Reveal_result {consumed_gas = consumed_milligas}) - - let[@coq_axiom_with_reason "gadt"] transaction_case = - make - ~op_case:Operation.Encoding.Manager_operations.transaction_case - ~encoding: - (obj10 - (opt "storage" Script.expr_encoding) - (opt - (* The field [big_map_diff] is deprecated since 008, use [lazy_storage_diff] instead. - It is kept here for a transitional period, for tools like indexers to update. *) - (* TODO: https://gitlab.com/tezos/tezos/-/issues/1948 - Remove it in 009 or later. *) - "big_map_diff" - Lazy_storage.legacy_big_map_diff_encoding) - (dft "balance_updates" Receipt.balance_updates_encoding []) - (dft "originated_contracts" (list Contract.encoding) []) - (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) - (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) - (dft "storage_size" z Z.zero) - (dft "paid_storage_size_diff" z Z.zero) - (dft "allocated_destination_contract" bool false) - (opt "lazy_storage_diff" Lazy_storage.encoding)) - ~iselect:(function - | Internal_operation_result (({operation = Transaction _; _} as op), res) - -> - Some (op, res) - | _ -> None) - ~select:(function - | Successful_manager_result (Transaction_result _ as op) -> Some op - | _ -> None) - ~kind:Kind.Transaction_manager_kind - ~proj:(function - | Transaction_result - { - storage; - lazy_storage_diff; - balance_updates; - originated_contracts; - consumed_gas; - storage_size; - paid_storage_size_diff; - allocated_destination_contract; - } -> - ( storage, - lazy_storage_diff, - balance_updates, - originated_contracts, - Gas.Arith.ceil consumed_gas, - consumed_gas, - storage_size, - paid_storage_size_diff, - allocated_destination_contract, - lazy_storage_diff )) - ~inj: - (fun ( storage, - legacy_lazy_storage_diff, - balance_updates, - originated_contracts, - consumed_gas, - consumed_milligas, - storage_size, - paid_storage_size_diff, - allocated_destination_contract, - lazy_storage_diff ) -> - assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; - let lazy_storage_diff = - Option.either lazy_storage_diff legacy_lazy_storage_diff - in - Transaction_result - { - storage; - lazy_storage_diff; - balance_updates; - originated_contracts; - consumed_gas = consumed_milligas; - storage_size; - paid_storage_size_diff; - allocated_destination_contract; - }) - - let[@coq_axiom_with_reason "gadt"] origination_case = - make - ~op_case:Operation.Encoding.Manager_operations.origination_case - ~encoding: - (obj8 - (opt - (* The field [big_map_diff] is deprecated since 008, use [lazy_storage_diff] instead. - It is kept here for a transitional period, for tools like indexers to update. *) - (* TODO: https://gitlab.com/tezos/tezos/-/issues/1948 - Remove it in 009 or later. *) - "big_map_diff" - Lazy_storage.legacy_big_map_diff_encoding) - (dft "balance_updates" Receipt.balance_updates_encoding []) - (dft "originated_contracts" (list Contract.encoding) []) - (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) - (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) - (dft "storage_size" z Z.zero) - (dft "paid_storage_size_diff" z Z.zero) - (opt "lazy_storage_diff" Lazy_storage.encoding)) - ~iselect:(function - | Internal_operation_result (({operation = Origination _; _} as op), res) - -> - Some (op, res) - | _ -> None) - ~select:(function - | Successful_manager_result (Origination_result _ as op) -> Some op - | _ -> None) - ~proj:(function - | Origination_result - { - lazy_storage_diff; - balance_updates; - originated_contracts; - consumed_gas; - storage_size; - paid_storage_size_diff; - } -> - ( lazy_storage_diff, - balance_updates, - originated_contracts, - Gas.Arith.ceil consumed_gas, - consumed_gas, - storage_size, - paid_storage_size_diff, - lazy_storage_diff )) - ~kind:Kind.Origination_manager_kind - ~inj: - (fun ( legacy_lazy_storage_diff, - balance_updates, - originated_contracts, - consumed_gas, - consumed_milligas, - storage_size, - paid_storage_size_diff, - lazy_storage_diff ) -> - assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; - let lazy_storage_diff = - Option.either lazy_storage_diff legacy_lazy_storage_diff - in - Origination_result - { - lazy_storage_diff; - balance_updates; - originated_contracts; - consumed_gas = consumed_milligas; - storage_size; - paid_storage_size_diff; - }) - - let[@coq_axiom_with_reason "gadt"] register_global_constant_case = - make - ~op_case: - Operation.Encoding.Manager_operations.register_global_constant_case - ~encoding: - (obj4 - (req "balance_updates" Receipt.balance_updates_encoding) - (req "consumed_gas" Gas.Arith.n_integral_encoding) - (req "storage_size" z) - (req "global_address" Script_expr_hash.encoding)) - ~iselect:(function - | Internal_operation_result - (({operation = Register_global_constant _; _} as op), res) -> - Some (op, res) - | _ -> None) - ~select:(function - | Successful_manager_result (Register_global_constant_result _ as op) -> - Some op - | _ -> None) - ~proj:(function - | Register_global_constant_result - {balance_updates; consumed_gas; size_of_constant; global_address} -> - (balance_updates, consumed_gas, size_of_constant, global_address)) - ~kind:Kind.Register_global_constant_manager_kind - ~inj: - (fun (balance_updates, consumed_gas, size_of_constant, global_address) -> - Register_global_constant_result - {balance_updates; consumed_gas; size_of_constant; global_address}) - - let delegation_case = - make - ~op_case:Operation.Encoding.Manager_operations.delegation_case - ~encoding: - Data_encoding.( - obj2 - (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) - (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero)) - ~iselect:(function - | Internal_operation_result (({operation = Delegation _; _} as op), res) - -> - Some (op, res) - | _ -> None) - ~select:(function - | Successful_manager_result (Delegation_result _ as op) -> Some op - | _ -> None) - ~kind:Kind.Delegation_manager_kind - ~proj:(function[@coq_match_with_default] - | Delegation_result {consumed_gas} -> - (Gas.Arith.ceil consumed_gas, consumed_gas)) - ~inj:(fun (consumed_gas, consumed_milligas) -> - assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; - Delegation_result {consumed_gas = consumed_milligas}) - - let set_deposits_limit_case = - make - ~op_case:Operation.Encoding.Manager_operations.set_deposits_limit_case - ~encoding: - Data_encoding.( - obj2 - (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) - (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero)) - ~iselect:(function - | Internal_operation_result - (({operation = Set_deposits_limit _; _} as op), res) -> - Some (op, res) - | _ -> None) - ~select:(function - | Successful_manager_result (Set_deposits_limit_result _ as op) -> - Some op - | _ -> None) - ~kind:Kind.Set_deposits_limit_manager_kind - ~proj:(function - | Set_deposits_limit_result {consumed_gas} -> - (Gas.Arith.ceil consumed_gas, consumed_gas)) - ~inj:(fun (consumed_gas, consumed_milligas) -> - assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; - Set_deposits_limit_result {consumed_gas = consumed_milligas}) -end - -let internal_operation_result_encoding : - packed_internal_operation_result Data_encoding.t = - let make (type kind) - (Manager_result.MCase res_case : kind Manager_result.case) = - let (Operation.Encoding.Manager_operations.MCase op_case) = - res_case.op_case - in - case - (Tag op_case.tag) - ~title:op_case.name - (merge_objs - (obj3 - (req "kind" (constant op_case.name)) - (req "source" Contract.encoding) - (req "nonce" uint16)) - (merge_objs op_case.encoding (obj1 (req "result" res_case.t)))) - (fun op -> - match res_case.iselect op with - | Some (op, res) -> - Some (((), op.source, op.nonce), (op_case.proj op.operation, res)) - | None -> None) - (fun (((), source, nonce), (op, res)) -> - let op = {source; operation = op_case.inj op; nonce} in - Internal_operation_result (op, res)) - in - def "operation.alpha.internal_operation_result" - @@ union - [ - make Manager_result.reveal_case; - make Manager_result.transaction_case; - make Manager_result.origination_case; - make Manager_result.delegation_case; - make Manager_result.register_global_constant_case; - make Manager_result.set_deposits_limit_case; - ] - -let successful_manager_operation_result_encoding : - packed_successful_manager_operation_result Data_encoding.t = - let make (type kind) - (Manager_result.MCase res_case : kind Manager_result.case) = - let (Operation.Encoding.Manager_operations.MCase op_case) = - res_case.op_case - in - case - (Tag op_case.tag) - ~title:op_case.name - (merge_objs (obj1 (req "kind" (constant op_case.name))) res_case.encoding) - (fun res -> - match res_case.select res with - | Some res -> Some ((), res_case.proj res) - | None -> None) - (fun ((), res) -> Successful_manager_result (res_case.inj res)) - in - def "operation.alpha.successful_manager_operation_result" - @@ union - [ - make Manager_result.reveal_case; - make Manager_result.transaction_case; - make Manager_result.origination_case; - make Manager_result.delegation_case; - make Manager_result.set_deposits_limit_case; - ] - -type 'kind contents_result = - | Preendorsement_result : { - balance_updates : Receipt.balance_updates; - delegate : Signature.Public_key_hash.t; - preendorsement_power : int; - } - -> Kind.preendorsement contents_result - | Endorsement_result : { - balance_updates : Receipt.balance_updates; - delegate : Signature.Public_key_hash.t; - endorsement_power : int; - } - -> Kind.endorsement contents_result - | Seed_nonce_revelation_result : - Receipt.balance_updates - -> Kind.seed_nonce_revelation contents_result - | Double_endorsement_evidence_result : - Receipt.balance_updates - -> Kind.double_endorsement_evidence contents_result - | Double_preendorsement_evidence_result : - Receipt.balance_updates - -> Kind.double_preendorsement_evidence contents_result - | Double_baking_evidence_result : - Receipt.balance_updates - -> Kind.double_baking_evidence contents_result - | Activate_account_result : - Receipt.balance_updates - -> Kind.activate_account contents_result - | Proposals_result : Kind.proposals contents_result - | Ballot_result : Kind.ballot contents_result - | Manager_operation_result : { - balance_updates : Receipt.balance_updates; - operation_result : 'kind manager_operation_result; - internal_operation_results : packed_internal_operation_result list; - } - -> 'kind Kind.manager contents_result - -type packed_contents_result = - | Contents_result : 'kind contents_result -> packed_contents_result - -type packed_contents_and_result = - | Contents_and_result : - 'kind Operation.contents * 'kind contents_result - -> packed_contents_and_result - -type ('a, 'b) eq = Eq : ('a, 'a) eq [@@coq_force_gadt] - -let equal_manager_kind : - type a b. a Kind.manager -> b Kind.manager -> (a, b) eq option = - fun ka kb -> - match (ka, kb) with - | (Kind.Reveal_manager_kind, Kind.Reveal_manager_kind) -> Some Eq - | (Kind.Reveal_manager_kind, _) -> None - | (Kind.Transaction_manager_kind, Kind.Transaction_manager_kind) -> Some Eq - | (Kind.Transaction_manager_kind, _) -> None - | (Kind.Origination_manager_kind, Kind.Origination_manager_kind) -> Some Eq - | (Kind.Origination_manager_kind, _) -> None - | (Kind.Delegation_manager_kind, Kind.Delegation_manager_kind) -> Some Eq - | (Kind.Delegation_manager_kind, _) -> None - | ( Kind.Register_global_constant_manager_kind, - Kind.Register_global_constant_manager_kind ) -> - Some Eq - | (Kind.Register_global_constant_manager_kind, _) -> None - | (Kind.Set_deposits_limit_manager_kind, Kind.Set_deposits_limit_manager_kind) - -> - Some Eq - | (Kind.Set_deposits_limit_manager_kind, _) -> None - -module Encoding = struct - type 'kind case = - | Case : { - op_case : 'kind Operation.Encoding.case; - encoding : 'a Data_encoding.t; - select : packed_contents_result -> 'kind contents_result option; - mselect : - packed_contents_and_result -> - ('kind contents * 'kind contents_result) option; - proj : 'kind contents_result -> 'a; - inj : 'a -> 'kind contents_result; - } - -> 'kind case - - let tagged_case tag name args proj inj = - let open Data_encoding in - case - tag - ~title:(String.capitalize_ascii name) - (merge_objs (obj1 (req "kind" (constant name))) args) - (fun x -> match proj x with None -> None | Some x -> Some ((), x)) - (fun ((), x) -> inj x) - - let[@coq_axiom_with_reason "gadt"] preendorsement_case = - Case - { - op_case = Operation.Encoding.preendorsement_case; - encoding = - obj3 - (req "balance_updates" Receipt.balance_updates_encoding) - (req "delegate" Signature.Public_key_hash.encoding) - (req "preendorsement_power" int31); - select = - (function - | Contents_result (Preendorsement_result _ as op) -> Some op - | _ -> None); - mselect = - (function - | Contents_and_result ((Preendorsement _ as op), res) -> Some (op, res) - | _ -> None); - proj = - (function - | Preendorsement_result - {balance_updates; delegate; preendorsement_power} -> - (balance_updates, delegate, preendorsement_power)); - inj = - (fun (balance_updates, delegate, preendorsement_power) -> - Preendorsement_result - {balance_updates; delegate; preendorsement_power}); - } - - let[@coq_axiom_with_reason "gadt"] endorsement_case = - Case - { - op_case = Operation.Encoding.endorsement_case; - encoding = - obj3 - (req "balance_updates" Receipt.balance_updates_encoding) - (req "delegate" Signature.Public_key_hash.encoding) - (req "endorsement_power" int31); - select = - (function - | Contents_result (Endorsement_result _ as op) -> Some op | _ -> None); - mselect = - (function - | Contents_and_result ((Endorsement _ as op), res) -> Some (op, res) - | _ -> None); - proj = - (function - | Endorsement_result {balance_updates; delegate; endorsement_power} -> - (balance_updates, delegate, endorsement_power)); - inj = - (fun (balance_updates, delegate, endorsement_power) -> - Endorsement_result {balance_updates; delegate; endorsement_power}); - } - - let[@coq_axiom_with_reason "gadt"] seed_nonce_revelation_case = - Case - { - op_case = Operation.Encoding.seed_nonce_revelation_case; - encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); - select = - (function - | Contents_result (Seed_nonce_revelation_result _ as op) -> Some op - | _ -> None); - mselect = - (function - | Contents_and_result ((Seed_nonce_revelation _ as op), res) -> - Some (op, res) - | _ -> None); - proj = (fun (Seed_nonce_revelation_result bus) -> bus); - inj = (fun bus -> Seed_nonce_revelation_result bus); - } - - let[@coq_axiom_with_reason "gadt"] double_endorsement_evidence_case = - Case - { - op_case = Operation.Encoding.double_endorsement_evidence_case; - encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); - select = - (function - | Contents_result (Double_endorsement_evidence_result _ as op) -> - Some op - | _ -> None); - mselect = - (function - | Contents_and_result ((Double_endorsement_evidence _ as op), res) -> - Some (op, res) - | _ -> None); - proj = (fun (Double_endorsement_evidence_result bus) -> bus); - inj = (fun bus -> Double_endorsement_evidence_result bus); - } - - let[@coq_axiom_with_reason "gadt"] double_preendorsement_evidence_case = - Case - { - op_case = Operation.Encoding.double_preendorsement_evidence_case; - encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); - select = - (function - | Contents_result (Double_preendorsement_evidence_result _ as op) -> - Some op - | _ -> None); - mselect = - (function - | Contents_and_result ((Double_preendorsement_evidence _ as op), res) - -> - Some (op, res) - | _ -> None); - proj = (fun (Double_preendorsement_evidence_result bus) -> bus); - inj = (fun bus -> Double_preendorsement_evidence_result bus); - } - - let[@coq_axiom_with_reason "gadt"] double_baking_evidence_case = - Case - { - op_case = Operation.Encoding.double_baking_evidence_case; - encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); - select = - (function - | Contents_result (Double_baking_evidence_result _ as op) -> Some op - | _ -> None); - mselect = - (function - | Contents_and_result ((Double_baking_evidence _ as op), res) -> - Some (op, res) - | _ -> None); - proj = (fun (Double_baking_evidence_result bus) -> bus); - inj = (fun bus -> Double_baking_evidence_result bus); - } - - let[@coq_axiom_with_reason "gadt"] activate_account_case = - Case - { - op_case = Operation.Encoding.activate_account_case; - encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); - select = - (function - | Contents_result (Activate_account_result _ as op) -> Some op - | _ -> None); - mselect = - (function - | Contents_and_result ((Activate_account _ as op), res) -> - Some (op, res) - | _ -> None); - proj = (fun (Activate_account_result bus) -> bus); - inj = (fun bus -> Activate_account_result bus); - } - - let[@coq_axiom_with_reason "gadt"] proposals_case = - Case - { - op_case = Operation.Encoding.proposals_case; - encoding = Data_encoding.empty; - select = - (function - | Contents_result (Proposals_result as op) -> Some op | _ -> None); - mselect = - (function - | Contents_and_result ((Proposals _ as op), res) -> Some (op, res) - | _ -> None); - proj = (fun Proposals_result -> ()); - inj = (fun () -> Proposals_result); - } - - let[@coq_axiom_with_reason "gadt"] ballot_case = - Case - { - op_case = Operation.Encoding.ballot_case; - encoding = Data_encoding.empty; - select = - (function - | Contents_result (Ballot_result as op) -> Some op | _ -> None); - mselect = - (function - | Contents_and_result ((Ballot _ as op), res) -> Some (op, res) - | _ -> None); - proj = (fun Ballot_result -> ()); - inj = (fun () -> Ballot_result); - } - - let[@coq_axiom_with_reason "gadt"] make_manager_case (type kind) - (Operation.Encoding.Case op_case : - kind Kind.manager Operation.Encoding.case) - (Manager_result.MCase res_case : kind Manager_result.case) mselect = - Case - { - op_case = Operation.Encoding.Case op_case; - encoding = - obj3 - (req "balance_updates" Receipt.balance_updates_encoding) - (req "operation_result" res_case.t) - (dft - "internal_operation_results" - (list internal_operation_result_encoding) - []); - select = - (function - | Contents_result - (Manager_operation_result - ({operation_result = Applied res; _} as op)) -> ( - match res_case.select (Successful_manager_result res) with - | Some res -> - Some - (Manager_operation_result - {op with operation_result = Applied res}) - | None -> None) - | Contents_result - (Manager_operation_result - ({operation_result = Backtracked (res, errs); _} as op)) -> ( - match res_case.select (Successful_manager_result res) with - | Some res -> - Some - (Manager_operation_result - {op with operation_result = Backtracked (res, errs)}) - | None -> None) - | Contents_result - (Manager_operation_result - ({operation_result = Skipped kind; _} as op)) -> ( - match equal_manager_kind kind res_case.kind with - | None -> None - | Some Eq -> - Some - (Manager_operation_result - {op with operation_result = Skipped kind})) - | Contents_result - (Manager_operation_result - ({operation_result = Failed (kind, errs); _} as op)) -> ( - match equal_manager_kind kind res_case.kind with - | None -> None - | Some Eq -> - Some - (Manager_operation_result - {op with operation_result = Failed (kind, errs)})) - | Contents_result (Preendorsement_result _) -> None - | Contents_result (Endorsement_result _) -> None - | Contents_result Ballot_result -> None - | Contents_result (Seed_nonce_revelation_result _) -> None - | Contents_result (Double_endorsement_evidence_result _) -> None - | Contents_result (Double_preendorsement_evidence_result _) -> None - | Contents_result (Double_baking_evidence_result _) -> None - | Contents_result (Activate_account_result _) -> None - | Contents_result Proposals_result -> None); - mselect; - proj = - (fun (Manager_operation_result - { - balance_updates = bus; - operation_result = r; - internal_operation_results = rs; - }) -> - (bus, r, rs)); - inj = - (fun (bus, r, rs) -> - Manager_operation_result - { - balance_updates = bus; - operation_result = r; - internal_operation_results = rs; - }); - } - - let[@coq_axiom_with_reason "gadt"] reveal_case = - make_manager_case - Operation.Encoding.reveal_case - Manager_result.reveal_case - (function - | Contents_and_result - ((Manager_operation {operation = Reveal _; _} as op), res) -> - Some (op, res) - | _ -> None) - - let[@coq_axiom_with_reason "gadt"] transaction_case = - make_manager_case - Operation.Encoding.transaction_case - Manager_result.transaction_case - (function - | Contents_and_result - ((Manager_operation {operation = Transaction _; _} as op), res) -> - Some (op, res) - | _ -> None) - - let[@coq_axiom_with_reason "gadt"] origination_case = - make_manager_case - Operation.Encoding.origination_case - Manager_result.origination_case - (function - | Contents_and_result - ((Manager_operation {operation = Origination _; _} as op), res) -> - Some (op, res) - | _ -> None) - - let[@coq_axiom_with_reason "gadt"] delegation_case = - make_manager_case - Operation.Encoding.delegation_case - Manager_result.delegation_case - (function - | Contents_and_result - ((Manager_operation {operation = Delegation _; _} as op), res) -> - Some (op, res) - | _ -> None) - - let[@coq_axiom_with_reason "gadt"] register_global_constant_case = - make_manager_case - Operation.Encoding.register_global_constant_case - Manager_result.register_global_constant_case - (function - | Contents_and_result - ( (Manager_operation {operation = Register_global_constant _; _} as - op), - res ) -> - Some (op, res) - | _ -> None) - - let[@coq_axiom_with_reason "gadt"] set_deposits_limit_case = - make_manager_case - Operation.Encoding.set_deposits_limit_case - Manager_result.set_deposits_limit_case - (function - | Contents_and_result - ( (Manager_operation {operation = Set_deposits_limit _; _} as op), - res ) -> - Some (op, res) - | _ -> None) -end - -let contents_result_encoding = - let open Encoding in - let make - (Case - { - op_case = Operation.Encoding.Case {tag; name; _}; - encoding; - mselect = _; - select; - proj; - inj; - }) = - let proj x = match select x with None -> None | Some x -> Some (proj x) in - let inj x = Contents_result (inj x) in - tagged_case (Tag tag) name encoding proj inj - in - def "operation.alpha.contents_result" - @@ union - [ - make seed_nonce_revelation_case; - make endorsement_case; - make preendorsement_case; - make double_preendorsement_evidence_case; - make double_endorsement_evidence_case; - make double_baking_evidence_case; - make activate_account_case; - make proposals_case; - make ballot_case; - make reveal_case; - make transaction_case; - make origination_case; - make delegation_case; - make register_global_constant_case; - make set_deposits_limit_case; - ] - -let contents_and_result_encoding = - let open Encoding in - let make - (Case - { - op_case = Operation.Encoding.Case {tag; name; encoding; proj; inj; _}; - mselect; - encoding = meta_encoding; - proj = meta_proj; - inj = meta_inj; - _; - }) = - let proj c = - match mselect c with - | Some (op, res) -> Some (proj op, meta_proj res) - | _ -> None - in - let inj (op, res) = Contents_and_result (inj op, meta_inj res) in - let encoding = merge_objs encoding (obj1 (req "metadata" meta_encoding)) in - tagged_case (Tag tag) name encoding proj inj - in - def "operation.alpha.operation_contents_and_result" - @@ union - [ - make seed_nonce_revelation_case; - make endorsement_case; - make preendorsement_case; - make double_preendorsement_evidence_case; - make double_endorsement_evidence_case; - make double_baking_evidence_case; - make activate_account_case; - make proposals_case; - make ballot_case; - make reveal_case; - make transaction_case; - make origination_case; - make delegation_case; - make register_global_constant_case; - make set_deposits_limit_case; - ] - -type 'kind contents_result_list = - | Single_result : 'kind contents_result -> 'kind contents_result_list - | Cons_result : - 'kind Kind.manager contents_result - * 'rest Kind.manager contents_result_list - -> ('kind * 'rest) Kind.manager contents_result_list - -type packed_contents_result_list = - | Contents_result_list : - 'kind contents_result_list - -> packed_contents_result_list - -let contents_result_list_encoding = - let rec to_list = function - | Contents_result_list (Single_result o) -> [Contents_result o] - | Contents_result_list (Cons_result (o, os)) -> - Contents_result o :: to_list (Contents_result_list os) - in - let rec of_list = function - | [] -> Error "cannot decode empty operation result" - | [Contents_result o] -> Ok (Contents_result_list (Single_result o)) - | Contents_result o :: os -> ( - of_list os >>? fun (Contents_result_list os) -> - match (o, os) with - | ( Manager_operation_result _, - Single_result (Manager_operation_result _) ) -> - Ok (Contents_result_list (Cons_result (o, os))) - | (Manager_operation_result _, Cons_result _) -> - Ok (Contents_result_list (Cons_result (o, os))) - | _ -> Error "cannot decode ill-formed operation result") - in - def "operation.alpha.contents_list_result" - @@ conv_with_guard to_list of_list (list contents_result_encoding) - -type 'kind contents_and_result_list = - | Single_and_result : - 'kind Alpha_context.contents * 'kind contents_result - -> 'kind contents_and_result_list - | Cons_and_result : - 'kind Kind.manager Alpha_context.contents - * 'kind Kind.manager contents_result - * 'rest Kind.manager contents_and_result_list - -> ('kind * 'rest) Kind.manager contents_and_result_list - -type packed_contents_and_result_list = - | Contents_and_result_list : - 'kind contents_and_result_list - -> packed_contents_and_result_list - -let contents_and_result_list_encoding = - let rec to_list = function - | Contents_and_result_list (Single_and_result (op, res)) -> - [Contents_and_result (op, res)] - | Contents_and_result_list (Cons_and_result (op, res, rest)) -> - Contents_and_result (op, res) :: to_list (Contents_and_result_list rest) - in - let rec of_list = function - | [] -> Error "cannot decode empty combined operation result" - | [Contents_and_result (op, res)] -> - Ok (Contents_and_result_list (Single_and_result (op, res))) - | Contents_and_result (op, res) :: rest -> ( - of_list rest >>? fun (Contents_and_result_list rest) -> - match (op, rest) with - | (Manager_operation _, Single_and_result (Manager_operation _, _)) -> - Ok (Contents_and_result_list (Cons_and_result (op, res, rest))) - | (Manager_operation _, Cons_and_result (_, _, _)) -> - Ok (Contents_and_result_list (Cons_and_result (op, res, rest))) - | _ -> Error "cannot decode ill-formed combined operation result") - in - conv_with_guard to_list of_list (Variable.list contents_and_result_encoding) - -type 'kind operation_metadata = {contents : 'kind contents_result_list} - -type packed_operation_metadata = - | Operation_metadata : 'kind operation_metadata -> packed_operation_metadata - | No_operation_metadata : packed_operation_metadata - -let operation_metadata_encoding = - def "operation.alpha.result" - @@ union - [ - case - (Tag 0) - ~title:"Operation_metadata" - contents_result_list_encoding - (function - | Operation_metadata {contents} -> - Some (Contents_result_list contents) - | _ -> None) - (fun (Contents_result_list contents) -> - Operation_metadata {contents}); - case - (Tag 1) - ~title:"No_operation_metadata" - empty - (function No_operation_metadata -> Some () | _ -> None) - (fun () -> No_operation_metadata); - ] - -let kind_equal : - type kind kind2. - kind contents -> kind2 contents_result -> (kind, kind2) eq option = - fun op res -> - match (op, res) with - | (Endorsement _, Endorsement_result _) -> Some Eq - | (Endorsement _, _) -> None - | (Preendorsement _, Preendorsement_result _) -> Some Eq - | (Preendorsement _, _) -> None - | (Seed_nonce_revelation _, Seed_nonce_revelation_result _) -> Some Eq - | (Seed_nonce_revelation _, _) -> None - | (Double_preendorsement_evidence _, Double_preendorsement_evidence_result _) - -> - Some Eq - | (Double_preendorsement_evidence _, _) -> None - | (Double_endorsement_evidence _, Double_endorsement_evidence_result _) -> - Some Eq - | (Double_endorsement_evidence _, _) -> None - | (Double_baking_evidence _, Double_baking_evidence_result _) -> Some Eq - | (Double_baking_evidence _, _) -> None - | (Activate_account _, Activate_account_result _) -> Some Eq - | (Activate_account _, _) -> None - | (Proposals _, Proposals_result) -> Some Eq - | (Proposals _, _) -> None - | (Ballot _, Ballot_result) -> Some Eq - | (Ballot _, _) -> None - | (Failing_noop _, _) -> - (* the Failing_noop operation always fails and can't have result *) - None - | ( Manager_operation {operation = Reveal _; _}, - Manager_operation_result {operation_result = Applied (Reveal_result _); _} - ) -> - Some Eq - | ( Manager_operation {operation = Reveal _; _}, - Manager_operation_result - {operation_result = Backtracked (Reveal_result _, _); _} ) -> - Some Eq - | ( Manager_operation {operation = Reveal _; _}, - Manager_operation_result - { - operation_result = Failed (Alpha_context.Kind.Reveal_manager_kind, _); - _; - } ) -> - Some Eq - | ( Manager_operation {operation = Reveal _; _}, - Manager_operation_result - {operation_result = Skipped Alpha_context.Kind.Reveal_manager_kind; _} - ) -> - Some Eq - | (Manager_operation {operation = Reveal _; _}, _) -> None - | ( Manager_operation {operation = Transaction _; _}, - Manager_operation_result - {operation_result = Applied (Transaction_result _); _} ) -> - Some Eq - | ( Manager_operation {operation = Transaction _; _}, - Manager_operation_result - {operation_result = Backtracked (Transaction_result _, _); _} ) -> - Some Eq - | ( Manager_operation {operation = Transaction _; _}, - Manager_operation_result - { - operation_result = - Failed (Alpha_context.Kind.Transaction_manager_kind, _); - _; - } ) -> - Some Eq - | ( Manager_operation {operation = Transaction _; _}, - Manager_operation_result - { - operation_result = Skipped Alpha_context.Kind.Transaction_manager_kind; - _; - } ) -> - Some Eq - | (Manager_operation {operation = Transaction _; _}, _) -> None - | ( Manager_operation {operation = Origination _; _}, - Manager_operation_result - {operation_result = Applied (Origination_result _); _} ) -> - Some Eq - | ( Manager_operation {operation = Origination _; _}, - Manager_operation_result - {operation_result = Backtracked (Origination_result _, _); _} ) -> - Some Eq - | ( Manager_operation {operation = Origination _; _}, - Manager_operation_result - { - operation_result = - Failed (Alpha_context.Kind.Origination_manager_kind, _); - _; - } ) -> - Some Eq - | ( Manager_operation {operation = Origination _; _}, - Manager_operation_result - { - operation_result = Skipped Alpha_context.Kind.Origination_manager_kind; - _; - } ) -> - Some Eq - | (Manager_operation {operation = Origination _; _}, _) -> None - | ( Manager_operation {operation = Delegation _; _}, - Manager_operation_result - {operation_result = Applied (Delegation_result _); _} ) -> - Some Eq - | ( Manager_operation {operation = Delegation _; _}, - Manager_operation_result - {operation_result = Backtracked (Delegation_result _, _); _} ) -> - Some Eq - | ( Manager_operation {operation = Delegation _; _}, - Manager_operation_result - { - operation_result = - Failed (Alpha_context.Kind.Delegation_manager_kind, _); - _; - } ) -> - Some Eq - | ( Manager_operation {operation = Delegation _; _}, - Manager_operation_result - { - operation_result = Skipped Alpha_context.Kind.Delegation_manager_kind; - _; - } ) -> - Some Eq - | (Manager_operation {operation = Delegation _; _}, _) -> None - | ( Manager_operation {operation = Register_global_constant _; _}, - Manager_operation_result - {operation_result = Applied (Register_global_constant_result _); _} ) -> - Some Eq - | ( Manager_operation {operation = Register_global_constant _; _}, - Manager_operation_result - { - operation_result = Backtracked (Register_global_constant_result _, _); - _; - } ) -> - Some Eq - | ( Manager_operation {operation = Register_global_constant _; _}, - Manager_operation_result - { - operation_result = - Failed (Alpha_context.Kind.Register_global_constant_manager_kind, _); - _; - } ) -> - Some Eq - | ( Manager_operation {operation = Register_global_constant _; _}, - Manager_operation_result - { - operation_result = - Skipped Alpha_context.Kind.Register_global_constant_manager_kind; - _; - } ) -> - Some Eq - | (Manager_operation {operation = Register_global_constant _; _}, _) -> None - | ( Manager_operation {operation = Set_deposits_limit _; _}, - Manager_operation_result - {operation_result = Applied (Set_deposits_limit_result _); _} ) -> - Some Eq - | ( Manager_operation {operation = Set_deposits_limit _; _}, - Manager_operation_result - {operation_result = Backtracked (Set_deposits_limit_result _, _); _} ) - -> - Some Eq - | ( Manager_operation {operation = Set_deposits_limit _; _}, - Manager_operation_result - { - operation_result = - Failed (Alpha_context.Kind.Set_deposits_limit_manager_kind, _); - _; - } ) -> - Some Eq - | ( Manager_operation {operation = Set_deposits_limit _; _}, - Manager_operation_result - { - operation_result = - Skipped Alpha_context.Kind.Set_deposits_limit_manager_kind; - _; - } ) -> - Some Eq - | (Manager_operation {operation = Set_deposits_limit _; _}, _) -> None - -let rec kind_equal_list : - type kind kind2. - kind contents_list -> kind2 contents_result_list -> (kind, kind2) eq option - = - fun contents res -> - match (contents, res) with - | (Single op, Single_result res) -> ( - match kind_equal op res with None -> None | Some Eq -> Some Eq) - | (Cons (op, ops), Cons_result (res, ress)) -> ( - match kind_equal op res with - | None -> None - | Some Eq -> ( - match kind_equal_list ops ress with - | None -> None - | Some Eq -> Some Eq)) - | _ -> None - -let[@coq_axiom_with_reason "gadt"] rec pack_contents_list : - type kind. - kind contents_list -> - kind contents_result_list -> - kind contents_and_result_list = - fun contents res -> - match (contents, res) with - | (Single op, Single_result res) -> Single_and_result (op, res) - | (Cons (op, ops), Cons_result (res, ress)) -> - Cons_and_result (op, res, pack_contents_list ops ress) - | ( Single (Manager_operation _), - Cons_result (Manager_operation_result _, Single_result _) ) -> - . - | ( Cons (_, _), - Single_result (Manager_operation_result {operation_result = Failed _; _}) - ) -> - . - | ( Cons (_, _), - Single_result (Manager_operation_result {operation_result = Skipped _; _}) - ) -> - . - | ( Cons (_, _), - Single_result (Manager_operation_result {operation_result = Applied _; _}) - ) -> - . - | ( Cons (_, _), - Single_result - (Manager_operation_result {operation_result = Backtracked _; _}) ) -> - . - | (Single _, Cons_result _) -> . - -let rec unpack_contents_list : - type kind. - kind contents_and_result_list -> - kind contents_list * kind contents_result_list = function - | Single_and_result (op, res) -> (Single op, Single_result res) - | Cons_and_result (op, res, rest) -> - let (ops, ress) = unpack_contents_list rest in - (Cons (op, ops), Cons_result (res, ress)) - -let rec to_list = function - | Contents_result_list (Single_result o) -> [Contents_result o] - | Contents_result_list (Cons_result (o, os)) -> - Contents_result o :: to_list (Contents_result_list os) - -let operation_data_and_metadata_encoding = - def "operation.alpha.operation_with_metadata" - @@ union - [ - case - (Tag 0) - ~title:"Operation_with_metadata" - (obj2 - (req "contents" (dynamic_size contents_and_result_list_encoding)) - (opt "signature" Signature.encoding)) - (function - | (Operation_data _, No_operation_metadata) -> None - | (Operation_data op, Operation_metadata res) -> ( - match kind_equal_list op.contents res.contents with - | None -> - Pervasives.failwith - "cannot decode inconsistent combined operation result" - | Some Eq -> - Some - ( Contents_and_result_list - (pack_contents_list op.contents res.contents), - op.signature ))) - (fun (Contents_and_result_list contents, signature) -> - let (op_contents, res_contents) = unpack_contents_list contents in - ( Operation_data {contents = op_contents; signature}, - Operation_metadata {contents = res_contents} )); - case - (Tag 1) - ~title:"Operation_without_metadata" - (obj2 - (req "contents" (dynamic_size Operation.contents_list_encoding)) - (opt "signature" Signature.encoding)) - (function - | (Operation_data op, No_operation_metadata) -> - Some (Contents_list op.contents, op.signature) - | (Operation_data _, Operation_metadata _) -> None) - (fun (Contents_list contents, signature) -> - (Operation_data {contents; signature}, No_operation_metadata)); - ] - -type block_metadata = { - proposer : Signature.Public_key_hash.t; - baker : Signature.Public_key_hash.t; - level_info : Level.t; - voting_period_info : Voting_period.info; - nonce_hash : Nonce_hash.t option; - consumed_gas : Gas.Arith.fp; - deactivated : Signature.Public_key_hash.t list; - balance_updates : Receipt.balance_updates; - liquidity_baking_escape_ema : Liquidity_baking.escape_ema; - implicit_operations_results : packed_successful_manager_operation_result list; -} - -let block_metadata_encoding = - let open Data_encoding in - def "block_header.alpha.metadata" - @@ conv - (fun { - proposer; - baker; - level_info; - voting_period_info; - nonce_hash; - consumed_gas; - deactivated; - balance_updates; - liquidity_baking_escape_ema; - implicit_operations_results; - } -> - ( proposer, - baker, - level_info, - voting_period_info, - nonce_hash, - consumed_gas, - deactivated, - balance_updates, - liquidity_baking_escape_ema, - implicit_operations_results )) - (fun ( proposer, - baker, - level_info, - voting_period_info, - nonce_hash, - consumed_gas, - deactivated, - balance_updates, - liquidity_baking_escape_ema, - implicit_operations_results ) -> - { - proposer; - baker; - level_info; - voting_period_info; - nonce_hash; - consumed_gas; - deactivated; - balance_updates; - liquidity_baking_escape_ema; - implicit_operations_results; - }) - (obj10 - (req "proposer" Signature.Public_key_hash.encoding) - (req "baker" Signature.Public_key_hash.encoding) - (req "level_info" Level.encoding) - (req "voting_period_info" Voting_period.info_encoding) - (req "nonce_hash" (option Nonce_hash.encoding)) - (req "consumed_gas" Gas.Arith.n_fp_encoding) - (req "deactivated" (list Signature.Public_key_hash.encoding)) - (req "balance_updates" Receipt.balance_updates_encoding) - (req "liquidity_baking_escape_ema" int32) - (req - "implicit_operations_results" - (list successful_manager_operation_result_encoding))) - -type precheck_result = { - consumed_gas : Gas.Arith.fp; - balance_updates : Receipt.balance_updates; -} - -type 'kind prechecked_contents = { - contents : 'kind contents; - result : precheck_result; -} - -type _ prechecked_contents_list = - | PrecheckedSingle : - 'kind prechecked_contents - -> 'kind prechecked_contents_list - | PrecheckedCons : - 'kind Kind.manager prechecked_contents - * 'rest Kind.manager prechecked_contents_list - -> ('kind * 'rest) Kind.manager prechecked_contents_list diff --git a/src/proto_012_Psithaca/lib_protocol/apply_results.mli b/src/proto_012_Psithaca/lib_protocol/apply_results.mli deleted file mode 100644 index 8093333ada79..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/apply_results.mli +++ /dev/null @@ -1,250 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Types representing results of applying an operation. - - These are used internally by [Apply], and can be used for experimenting - with protocol updates, by clients to print out a summary of the - operation at pre-injection simulation and at confirmation time, - and by block explorers. - *) - -open Alpha_context - -(** Result of applying a {!Operation.t}. Follows the same structure. *) -type 'kind operation_metadata = {contents : 'kind contents_result_list} - -and packed_operation_metadata = - | Operation_metadata : 'kind operation_metadata -> packed_operation_metadata - | No_operation_metadata : packed_operation_metadata - -(** Result of applying a {!Operation.contents_list}. Follows the same structure. *) -and 'kind contents_result_list = - | Single_result : 'kind contents_result -> 'kind contents_result_list - | Cons_result : - 'kind Kind.manager contents_result - * 'rest Kind.manager contents_result_list - -> ('kind * 'rest) Kind.manager contents_result_list - -and packed_contents_result_list = - | Contents_result_list : - 'kind contents_result_list - -> packed_contents_result_list - -(** Result of applying an {!Operation.contents}. Follows the same structure. *) -and 'kind contents_result = - | Preendorsement_result : { - balance_updates : Receipt.balance_updates; - delegate : Signature.Public_key_hash.t; - preendorsement_power : int; - } - -> Kind.preendorsement contents_result - | Endorsement_result : { - balance_updates : Receipt.balance_updates; - delegate : Signature.Public_key_hash.t; - endorsement_power : int; - } - -> Kind.endorsement contents_result - | Seed_nonce_revelation_result : - Receipt.balance_updates - -> Kind.seed_nonce_revelation contents_result - | Double_endorsement_evidence_result : - Receipt.balance_updates - -> Kind.double_endorsement_evidence contents_result - | Double_preendorsement_evidence_result : - Receipt.balance_updates - -> Kind.double_preendorsement_evidence contents_result - | Double_baking_evidence_result : - Receipt.balance_updates - -> Kind.double_baking_evidence contents_result - | Activate_account_result : - Receipt.balance_updates - -> Kind.activate_account contents_result - | Proposals_result : Kind.proposals contents_result - | Ballot_result : Kind.ballot contents_result - | Manager_operation_result : { - balance_updates : Receipt.balance_updates; - operation_result : 'kind manager_operation_result; - internal_operation_results : packed_internal_operation_result list; - } - -> 'kind Kind.manager contents_result - -and packed_contents_result = - | Contents_result : 'kind contents_result -> packed_contents_result - -(** The result of an operation in the queue. [Skipped] ones should - always be at the tail, and after a single [Failed]. *) -and 'kind manager_operation_result = - | Applied of 'kind successful_manager_operation_result - | Backtracked of - 'kind successful_manager_operation_result * error trace option - | Failed : 'kind Kind.manager * error trace -> 'kind manager_operation_result - | Skipped : 'kind Kind.manager -> 'kind manager_operation_result -[@@coq_force_gadt] - -(** Result of applying a {!manager_operation_content}, either internal - or external. *) -and _ successful_manager_operation_result = - | Reveal_result : { - consumed_gas : Gas.Arith.fp; - } - -> Kind.reveal successful_manager_operation_result - | Transaction_result : { - storage : Script.expr option; - lazy_storage_diff : Lazy_storage.diffs option; - balance_updates : Receipt.balance_updates; - originated_contracts : Contract.t list; - consumed_gas : Gas.Arith.fp; - storage_size : Z.t; - paid_storage_size_diff : Z.t; - allocated_destination_contract : bool; - } - -> Kind.transaction successful_manager_operation_result - | Origination_result : { - lazy_storage_diff : Lazy_storage.diffs option; - balance_updates : Receipt.balance_updates; - originated_contracts : Contract.t list; - consumed_gas : Gas.Arith.fp; - storage_size : Z.t; - paid_storage_size_diff : Z.t; - } - -> Kind.origination successful_manager_operation_result - | Delegation_result : { - consumed_gas : Gas.Arith.fp; - } - -> Kind.delegation successful_manager_operation_result - | Register_global_constant_result : { - (* The manager submitting the operation must pay - the cost of storage for the registered value. - We include the balance update here. *) - balance_updates : Receipt.balance_updates; - (* Gas consumed while validating and storing the registered - value. *) - consumed_gas : Gas.Arith.fp; - (* The size of the registered value in bytes. - Currently, this is simply the number of bytes in the binary - serialization of the Micheline value. *) - size_of_constant : Z.t; - (* The address of the newly registered value, being - the hash of its binary serialization. This could be - calulated on demand but we include it here in the - receipt for flexibility in the future. *) - global_address : Script_expr_hash.t; - } - -> Kind.register_global_constant successful_manager_operation_result - | Set_deposits_limit_result : { - consumed_gas : Gas.Arith.fp; - } - -> Kind.set_deposits_limit successful_manager_operation_result - -and packed_successful_manager_operation_result = - | Successful_manager_result : - 'kind successful_manager_operation_result - -> packed_successful_manager_operation_result - -and packed_internal_operation_result = - | Internal_operation_result : - 'kind internal_operation * 'kind manager_operation_result - -> packed_internal_operation_result - -val pack_migration_operation_results : - Migration.origination_result list -> - packed_successful_manager_operation_result list - -(** Serializer for {!packed_operation_result}. *) -val operation_metadata_encoding : packed_operation_metadata Data_encoding.t - -val operation_data_and_metadata_encoding : - (Operation.packed_protocol_data * packed_operation_metadata) Data_encoding.t - -type 'kind contents_and_result_list = - | Single_and_result : - 'kind Alpha_context.contents * 'kind contents_result - -> 'kind contents_and_result_list - | Cons_and_result : - 'kind Kind.manager Alpha_context.contents - * 'kind Kind.manager contents_result - * 'rest Kind.manager contents_and_result_list - -> ('kind * 'rest) Kind.manager contents_and_result_list - -type packed_contents_and_result_list = - | Contents_and_result_list : - 'kind contents_and_result_list - -> packed_contents_and_result_list - -val contents_and_result_list_encoding : - packed_contents_and_result_list Data_encoding.t - -val pack_contents_list : - 'kind contents_list -> - 'kind contents_result_list -> - 'kind contents_and_result_list - -val unpack_contents_list : - 'kind contents_and_result_list -> - 'kind contents_list * 'kind contents_result_list - -val to_list : packed_contents_result_list -> packed_contents_result list - -type ('a, 'b) eq = Eq : ('a, 'a) eq - -val kind_equal_list : - 'kind contents_list -> - 'kind2 contents_result_list -> - ('kind, 'kind2) eq option - -type block_metadata = { - proposer : Signature.Public_key_hash.t; - baker : Signature.Public_key_hash.t; - level_info : Level.t; - voting_period_info : Voting_period.info; - nonce_hash : Nonce_hash.t option; - consumed_gas : Gas.Arith.fp; - deactivated : Signature.Public_key_hash.t list; - balance_updates : Receipt.balance_updates; - liquidity_baking_escape_ema : Liquidity_baking.escape_ema; - implicit_operations_results : packed_successful_manager_operation_result list; -} - -val block_metadata_encoding : block_metadata Data_encoding.encoding - -type precheck_result = { - consumed_gas : Gas.Arith.fp; - balance_updates : Receipt.balance_updates; -} - -type 'kind prechecked_contents = { - contents : 'kind contents; - result : precheck_result; -} - -type _ prechecked_contents_list = - | PrecheckedSingle : - 'kind prechecked_contents - -> 'kind prechecked_contents_list - | PrecheckedCons : - 'kind Kind.manager prechecked_contents - * 'rest Kind.manager prechecked_contents_list - -> ('kind * 'rest) Kind.manager prechecked_contents_list diff --git a/src/proto_012_Psithaca/lib_protocol/baking.ml b/src/proto_012_Psithaca/lib_protocol/baking.ml deleted file mode 100644 index 72140a035f19..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/baking.ml +++ /dev/null @@ -1,130 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Misc - -type error += - | (* `Permanent *) - Insufficient_endorsing_power of { - endorsing_power : int; - consensus_threshold : int; - } - -let () = - register_error_kind - `Permanent - ~id:"baking.insufficient_endorsing_power" - ~title:"Insufficient endorsing power" - ~description: - "The endorsing power is insufficient to satisfy the consensus threshold." - ~pp:(fun ppf (endorsing_power, consensus_threshold) -> - Format.fprintf - ppf - "The endorsing power (%d) is insufficient to satisfy the consensus \ - threshold (%d)." - endorsing_power - consensus_threshold) - Data_encoding.( - obj2 (req "endorsing_power" int31) (req "consensus_threshold" int31)) - (function - | Insufficient_endorsing_power {endorsing_power; consensus_threshold} -> - Some (endorsing_power, consensus_threshold) - | _ -> None) - (fun (endorsing_power, consensus_threshold) -> - Insufficient_endorsing_power {endorsing_power; consensus_threshold}) - -let bonus_baking_reward ctxt ~endorsing_power = - let consensus_threshold = Constants.consensus_threshold ctxt in - let baking_reward_bonus_per_slot = - Constants.baking_reward_bonus_per_slot ctxt - in - let extra_endorsing_power = endorsing_power - consensus_threshold in - error_when - Compare.Int.(extra_endorsing_power < 0) - (Insufficient_endorsing_power {endorsing_power; consensus_threshold}) - >>? fun () -> - Tez.(baking_reward_bonus_per_slot *? Int64.of_int extra_endorsing_power) - -let baking_rights c level = - let rec f c round = - Stake_distribution.baking_rights_owner c level ~round - >>=? fun (c, _slot, (delegate, _)) -> - return (LCons (delegate, fun () -> f c (Round.succ round))) - in - f c Round.zero - -let endorsing_rights (ctxt : t) level = - let consensus_committee_size = Constants.consensus_committee_size ctxt in - Slot.slot_range ~min:0 ~count:consensus_committee_size >>?= fun slots -> - List.fold_left_es - (fun (ctxt, acc) slot -> - Stake_distribution.slot_owner ctxt level slot >>=? fun (ctxt, (_, pkh)) -> - return (ctxt, (slot, pkh) :: acc)) - (ctxt, []) - slots - >>=? fun (ctxt, right_owners) -> - let rights = - List.fold_left - (fun acc (slot, pkh) -> - let slots = - match Signature.Public_key_hash.Map.find pkh acc with - | None -> [slot] - | Some slots -> slot :: slots - in - Signature.Public_key_hash.Map.add pkh slots acc) - Signature.Public_key_hash.Map.empty - right_owners - in - return (ctxt, rights) - -let endorsing_rights_by_first_slot ctxt level = - Slot.slot_range ~min:0 ~count:(Constants.consensus_committee_size ctxt) - >>?= fun slots -> - List.fold_left_es - (fun (ctxt, (delegates_map, slots_map)) slot -> - Stake_distribution.slot_owner ctxt level slot - >|=? fun (ctxt, (pk, pkh)) -> - let (initial_slot, delegates_map) = - match Signature.Public_key_hash.Map.find pkh delegates_map with - | None -> - (slot, Signature.Public_key_hash.Map.add pkh slot delegates_map) - | Some initial_slot -> (initial_slot, delegates_map) - in - (* [slots_map]'keys are the minimal slots of delegates because - we fold on slots in increasing order *) - let slots_map = - Slot.Map.update - initial_slot - (function - | None -> Some (pk, pkh, 1) - | Some (pk, pkh, count) -> Some (pk, pkh, count + 1)) - slots_map - in - (ctxt, (delegates_map, slots_map))) - (ctxt, (Signature.Public_key_hash.Map.empty, Slot.Map.empty)) - slots - >>=? fun (ctxt, (_, slots_map)) -> return (ctxt, slots_map) diff --git a/src/proto_012_Psithaca/lib_protocol/baking.mli b/src/proto_012_Psithaca/lib_protocol/baking.mli deleted file mode 100644 index 6504712552ed..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/baking.mli +++ /dev/null @@ -1,60 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Misc - -type error += - | (* `Permanent *) - Insufficient_endorsing_power of { - endorsing_power : int; - consensus_threshold : int; - } - -(** For a given level computes who has the right to include an - endorsement in the next block. It returns a mapping from the - delegates with such rights to their endorsing slots. This function - is only used by the 'validators' RPC. *) -val endorsing_rights : - context -> - Level.t -> - (context * Slot.t list Signature.Public_key_hash.Map.t) tzresult Lwt.t - -(** Computes the endorsing rights for a given level. Returns a map - from allocated first slots to their owner's public key, public key - hash, and endorsing power. *) -val endorsing_rights_by_first_slot : - context -> - Level.t -> - (context * (public_key * public_key_hash * int) Slot.Map.t) tzresult Lwt.t - -(** Computes the bonus baking reward depending on the endorsing power. *) -val bonus_baking_reward : context -> endorsing_power:int -> Tez.t tzresult - -(** [baking_rights ctxt level] is the lazy list of contract's - public key hashes that are allowed to propose for [level] - at each round. *) -val baking_rights : context -> Level.t -> public_key lazy_list diff --git a/src/proto_012_Psithaca/lib_protocol/blinded_public_key_hash.ml b/src/proto_012_Psithaca/lib_protocol/blinded_public_key_hash.ml deleted file mode 100644 index 4cabfdae0688..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/blinded_public_key_hash.ml +++ /dev/null @@ -1,59 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module H = - Blake2B.Make - (Base58) - (struct - let name = "Blinded public key hash" - - let title = "A blinded public key hash" - - let b58check_prefix = "\001\002\049\223" - - let size = Some Ed25519.Public_key_hash.size - end) - -module Index = struct - include H - include Path_encoding.Make_hex (H) -end - -include H - -let () = Base58.check_encoded_prefix b58check_encoding "btz1" 37 - -let of_ed25519_pkh activation_code pkh = - hash_bytes ~key:activation_code [Ed25519.Public_key_hash.to_bytes pkh] - -type activation_code = bytes - -let activation_code_size = Ed25519.Public_key_hash.size - -let activation_code_encoding = Data_encoding.Fixed.bytes activation_code_size - -let activation_code_of_hex h = - if Compare.Int.(String.length h <> activation_code_size * 2) then None - else Hex.to_bytes (`Hex h) diff --git a/src/proto_012_Psithaca/lib_protocol/blinded_public_key_hash.mli b/src/proto_012_Psithaca/lib_protocol/blinded_public_key_hash.mli deleted file mode 100644 index 9be85a79d08d..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/blinded_public_key_hash.mli +++ /dev/null @@ -1,45 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module handles hashes of implicit contract addresses used for - commitments in the origin block. - - This module is needed because for legal reasons, when the blockchain is - activated, the btz1 addresses of participants to the fundraising are not - listed directly but instead their hashes are listed, together with their - balances. Thus, the listed accounts can be activated and credited in the - activation block. *) - -include S.HASH - -type activation_code - -val activation_code_encoding : activation_code Data_encoding.t - -val of_ed25519_pkh : activation_code -> Ed25519.Public_key_hash.t -> t - -val activation_code_of_hex : string -> activation_code option - -module Index : Storage_description.INDEX with type t = t diff --git a/src/proto_012_Psithaca/lib_protocol/block_header_repr.ml b/src/proto_012_Psithaca/lib_protocol/block_header_repr.ml deleted file mode 100644 index b753e6a9383b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/block_header_repr.ml +++ /dev/null @@ -1,502 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Block header *) - -type contents = { - payload_hash : Block_payload_hash.t; - payload_round : Round_repr.t; - seed_nonce_hash : Nonce_hash.t option; - proof_of_work_nonce : bytes; - liquidity_baking_escape_vote : bool; -} - -type protocol_data = {contents : contents; signature : Signature.t} - -type t = {shell : Block_header.shell_header; protocol_data : protocol_data} - -type block_header = t - -type raw = Block_header.t - -type shell_header = Block_header.shell_header - -let raw_encoding = Block_header.encoding - -let shell_header_encoding = Block_header.shell_header_encoding - -type block_watermark = Block_header of Chain_id.t - -let bytes_of_block_watermark = function - | Block_header chain_id -> - Bytes.cat (Bytes.of_string "\x11") (Chain_id.to_bytes chain_id) - -let to_watermark b = Signature.Custom (bytes_of_block_watermark b) - -let of_watermark = function - | Signature.Custom b -> - if Compare.Int.(Bytes.length b > 0) then - match Bytes.get b 0 with - | '\x11' -> - Option.map - (fun chain_id -> Block_header chain_id) - (Chain_id.of_bytes_opt (Bytes.sub b 1 (Bytes.length b - 1))) - | _ -> None - else None - | _ -> None - -let contents_encoding = - let open Data_encoding in - def "block_header.alpha.unsigned_contents" - @@ conv - (fun { - payload_hash; - payload_round; - seed_nonce_hash; - proof_of_work_nonce; - liquidity_baking_escape_vote; - } -> - ( payload_hash, - payload_round, - proof_of_work_nonce, - seed_nonce_hash, - liquidity_baking_escape_vote )) - (fun ( payload_hash, - payload_round, - proof_of_work_nonce, - seed_nonce_hash, - liquidity_baking_escape_vote ) -> - { - payload_hash; - payload_round; - seed_nonce_hash; - proof_of_work_nonce; - liquidity_baking_escape_vote; - }) - (obj5 - (req "payload_hash" Block_payload_hash.encoding) - (req "payload_round" Round_repr.encoding) - (req - "proof_of_work_nonce" - (Fixed.bytes Constants_repr.proof_of_work_nonce_size)) - (opt "seed_nonce_hash" Nonce_hash.encoding) - (req "liquidity_baking_escape_vote" Data_encoding.bool)) - -let protocol_data_encoding = - let open Data_encoding in - def "block_header.alpha.signed_contents" - @@ conv - (fun {contents; signature} -> (contents, signature)) - (fun (contents, signature) -> {contents; signature}) - (merge_objs - contents_encoding - (obj1 (req "signature" Signature.encoding))) - -let raw {shell; protocol_data} = - let protocol_data = - Data_encoding.Binary.to_bytes_exn protocol_data_encoding protocol_data - in - {Block_header.shell; protocol_data} - -let unsigned_encoding = - let open Data_encoding in - merge_objs Block_header.shell_header_encoding contents_encoding - -let encoding = - let open Data_encoding in - def "block_header.alpha.full_header" - @@ conv - (fun {shell; protocol_data} -> (shell, protocol_data)) - (fun (shell, protocol_data) -> {shell; protocol_data}) - (merge_objs Block_header.shell_header_encoding protocol_data_encoding) - -(** Constants *) - -let max_header_length = - let fake_level = Raw_level_repr.root in - let fake_round = Round_repr.zero in - let fake_fitness = - Fitness_repr.create_without_locked_round - ~level:fake_level - ~predecessor_round:fake_round - ~round:fake_round - in - let fake_shell = - { - Block_header.level = 0l; - proto_level = 0; - predecessor = Block_hash.zero; - timestamp = Time.of_seconds 0L; - validation_passes = 0; - operations_hash = Operation_list_list_hash.zero; - fitness = Fitness_repr.to_raw fake_fitness; - context = Context_hash.zero; - } - and fake_contents = - { - payload_hash = Block_payload_hash.zero; - payload_round = Round_repr.zero; - proof_of_work_nonce = - Bytes.make Constants_repr.proof_of_work_nonce_size '0'; - seed_nonce_hash = Some Nonce_hash.zero; - liquidity_baking_escape_vote = false; - } - in - Data_encoding.Binary.length - encoding - { - shell = fake_shell; - protocol_data = {contents = fake_contents; signature = Signature.zero}; - } - -(** Header parsing entry point *) - -let hash_raw = Block_header.hash - -let hash {shell; protocol_data} = - Block_header.hash - { - shell; - protocol_data = - Data_encoding.Binary.to_bytes_exn protocol_data_encoding protocol_data; - } - -type locked_round_evidence = { - preendorsement_round : Round_repr.t; - preendorsement_count : int; -} - -type error += - | (* Permanent *) - Invalid_block_signature of - Block_hash.t * Signature.Public_key_hash.t - | (* Permanent *) Invalid_stamp - | (* Permanent *) - Invalid_payload_hash of { - expected : Block_payload_hash.t; - provided : Block_payload_hash.t; - } - | (* Permanent *) - Locked_round_after_block_round of { - locked_round : Round_repr.t; - round : Round_repr.t; - } - | (* Permanent *) - Invalid_payload_round of { - payload_round : Round_repr.t; - round : Round_repr.t; - } - | (* Permanent *) - Insufficient_locked_round_evidence of { - voting_power : int; - consensus_threshold : int; - } - | (* Permanent *) Invalid_commitment of {expected : bool} - | (* Permanent *) Wrong_timestamp of Time.t * Time.t - -let () = - register_error_kind - `Permanent - ~id:"block_header.invalid_block_signature" - ~title:"Invalid block signature" - ~description:"A block was not signed with the expected private key." - ~pp:(fun ppf (block, pkh) -> - Format.fprintf - ppf - "Invalid signature for block %a. Expected: %a." - Block_hash.pp_short - block - Signature.Public_key_hash.pp_short - pkh) - Data_encoding.( - obj2 - (req "block" Block_hash.encoding) - (req "expected" Signature.Public_key_hash.encoding)) - (function - | Invalid_block_signature (block, pkh) -> Some (block, pkh) | _ -> None) - (fun (block, pkh) -> Invalid_block_signature (block, pkh)) ; - register_error_kind - `Permanent - ~id:"block_header.invalid_stamp" - ~title:"Insufficient block proof-of-work stamp" - ~description:"The block's proof-of-work stamp is insufficient" - ~pp:(fun ppf () -> Format.fprintf ppf "Insufficient proof-of-work stamp") - Data_encoding.empty - (function Invalid_stamp -> Some () | _ -> None) - (fun () -> Invalid_stamp) ; - register_error_kind - `Permanent - ~id:"block_header.invalid_payload_hash" - ~title:"Invalid payload hash" - ~description:"Invalid payload hash." - ~pp:(fun ppf (expected, provided) -> - Format.fprintf - ppf - "Invalid payload hash (expected: %a, provided: %a)." - Block_payload_hash.pp_short - expected - Block_payload_hash.pp_short - provided) - Data_encoding.( - obj2 - (req "expected" Block_payload_hash.encoding) - (req "provided" Block_payload_hash.encoding)) - (function - | Invalid_payload_hash {expected; provided} -> Some (expected, provided) - | _ -> None) - (fun (expected, provided) -> Invalid_payload_hash {expected; provided}) ; - () ; - register_error_kind - `Permanent - ~id:"block_header.locked_round_after_block_round" - ~title:"Locked round after block round" - ~description:"Locked round after block round." - ~pp:(fun ppf (locked_round, round) -> - Format.fprintf - ppf - "Locked round (%a) is after the block round (%a)." - Round_repr.pp - locked_round - Round_repr.pp - round) - Data_encoding.( - obj2 - (req "locked_round" Round_repr.encoding) - (req "round" Round_repr.encoding)) - (function - | Locked_round_after_block_round {locked_round; round} -> - Some (locked_round, round) - | _ -> None) - (fun (locked_round, round) -> - Locked_round_after_block_round {locked_round; round}) ; - () ; - register_error_kind - `Permanent - ~id:"block_header.invalid_payload_round" - ~title:"Invalid payload round" - ~description:"The given payload round is invalid." - ~pp:(fun ppf (payload_round, round) -> - Format.fprintf - ppf - "The provided payload round (%a) is after the block round (%a)." - Round_repr.pp - payload_round - Round_repr.pp - round) - Data_encoding.( - obj2 - (req "payload_round" Round_repr.encoding) - (req "round" Round_repr.encoding)) - (function - | Invalid_payload_round {payload_round; round} -> - Some (payload_round, round) - | _ -> None) - (fun (payload_round, round) -> Invalid_payload_round {payload_round; round}) ; - register_error_kind - `Permanent - ~id:"block_header.insufficient_locked_round_evidence" - ~title:"Insufficient locked round evidence" - ~description:"Insufficient locked round evidence." - ~pp:(fun ppf (voting_power, consensus_threshold) -> - Format.fprintf - ppf - "The provided locked round evidence is not sufficient: provided %d \ - voting power but was expecting at least %d." - voting_power - consensus_threshold) - Data_encoding.( - obj2 (req "voting_power" int31) (req "consensus_threshold" int31)) - (function - | Insufficient_locked_round_evidence {voting_power; consensus_threshold} - -> - Some (voting_power, consensus_threshold) - | _ -> None) - (fun (voting_power, consensus_threshold) -> - Insufficient_locked_round_evidence {voting_power; consensus_threshold}) ; - register_error_kind - `Permanent - ~id:"block_header.invalid_commitment" - ~title:"Invalid commitment in block header" - ~description:"The block header has invalid commitment." - ~pp:(fun ppf expected -> - if expected then - Format.fprintf ppf "Missing seed's nonce commitment in block header." - else - Format.fprintf ppf "Unexpected seed's nonce commitment in block header.") - Data_encoding.(obj1 (req "expected" bool)) - (function Invalid_commitment {expected} -> Some expected | _ -> None) - (fun expected -> Invalid_commitment {expected}) ; - register_error_kind - `Permanent - ~id:"block_header.wrong_timestamp" - ~title:"Wrong timestamp" - ~description:"Block timestamp not the expected one." - ~pp:(fun ppf (block_ts, expected_ts) -> - Format.fprintf - ppf - "Wrong timestamp: block timestamp (%a) not the expected one (%a)" - Time.pp_hum - block_ts - Time.pp_hum - expected_ts) - Data_encoding.( - obj2 - (req "block_timestamp" Time.encoding) - (req "expected_timestamp" Time.encoding)) - (function Wrong_timestamp (t1, t2) -> Some (t1, t2) | _ -> None) - (fun (t1, t2) -> Wrong_timestamp (t1, t2)) - -let check_signature (block : t) (chain_id : Chain_id.t) - (key : Signature.Public_key.t) = - let check_signature key ({shell; protocol_data = {contents; signature}} : t) = - let unsigned_header = - Data_encoding.Binary.to_bytes_exn unsigned_encoding (shell, contents) - in - Signature.check - ~watermark:(to_watermark (Block_header chain_id)) - key - signature - unsigned_header - in - if check_signature key block then ok () - else - error (Invalid_block_signature (hash block, Signature.Public_key.hash key)) - -let check_payload_round ~round ~payload_round = - error_when - Round_repr.(payload_round > round) - (Invalid_payload_round {payload_round; round}) - -let check_timestamp round_durations ~timestamp ~round ~predecessor_timestamp - ~predecessor_round = - Round_repr.timestamp_of_round - round_durations - ~predecessor_timestamp - ~predecessor_round - ~round - >>? fun expected_timestamp -> - if Time_repr.(expected_timestamp = timestamp) then Error_monad.ok () - else error (Wrong_timestamp (timestamp, expected_timestamp)) - -module Proof_of_work = struct - let check_hash hash stamp_threshold = - let bytes = Block_hash.to_bytes hash in - let word = TzEndian.get_int64 bytes 0 in - Compare.Uint64.(word <= stamp_threshold) - - let check_header_proof_of_work_stamp shell contents stamp_threshold = - let hash = - hash {shell; protocol_data = {contents; signature = Signature.zero}} - in - check_hash hash stamp_threshold - - let check_proof_of_work_stamp ~proof_of_work_threshold block = - if - check_header_proof_of_work_stamp - block.shell - block.protocol_data.contents - proof_of_work_threshold - then ok () - else error Invalid_stamp -end - -let begin_validate_block_header ~(block_header : t) ~(chain_id : Chain_id.t) - ~(predecessor_timestamp : Time.t) ~(predecessor_round : Round_repr.t) - ~(fitness : Fitness_repr.t) ~(timestamp : Time.t) - ~(delegate_pk : Signature.Public_key.t) - ~(round_durations : Round_repr.Durations.t) - ~(proof_of_work_threshold : int64) ~(expected_commitment : bool) = - (* Level relationship between current node and the predecessor is - done by the shell. We know that level is predecessor level + 1. - The predecessor block hash is guaranteed by the shell to be the - one in the shell header. The operations are guaranteed to - correspond to the shell_header.operations_hash by the shell *) - let {payload_round; seed_nonce_hash; _} = - block_header.protocol_data.contents - in - let raw_level = block_header.shell.level in - Proof_of_work.check_proof_of_work_stamp ~proof_of_work_threshold block_header - >>? fun () -> - Raw_level_repr.of_int32 raw_level >>? fun level -> - check_signature block_header chain_id delegate_pk >>? fun () -> - let round = Fitness_repr.round fitness in - check_payload_round ~round ~payload_round >>? fun () -> - check_timestamp - round_durations - ~predecessor_timestamp - ~predecessor_round - ~timestamp - ~round - >>? fun () -> - Fitness_repr.check_except_locked_round fitness ~level ~predecessor_round - >>? fun () -> - let has_commitment = - match seed_nonce_hash with None -> false | Some _ -> true - in - error_unless - Compare.Bool.(has_commitment = expected_commitment) - (Invalid_commitment {expected = expected_commitment}) - -type checkable_payload_hash = - | No_check - | Expected_payload_hash of Block_payload_hash.t - -let finalize_validate_block_header ~(block_header_contents : contents) - ~(round : Round_repr.t) - ~(* We have to check the round because in the construction case it was - deduced from the time *) - (fitness : Fitness_repr.t) - ~(checkable_payload_hash : checkable_payload_hash) - ~(locked_round_evidence : locked_round_evidence option) - ~(consensus_threshold : int) = - let { - payload_hash = actual_payload_hash; - seed_nonce_hash = _; - proof_of_work_nonce = _; - _; - } = - block_header_contents - in - (match checkable_payload_hash with - | No_check -> Result.return_unit - | Expected_payload_hash bph -> - error_unless - (Block_payload_hash.equal actual_payload_hash bph) - (Invalid_payload_hash {expected = bph; provided = actual_payload_hash})) - >>? fun () -> - (match locked_round_evidence with - | None -> ok None - | Some {preendorsement_count; preendorsement_round} -> - error_when - Round_repr.(preendorsement_round >= round) - (Locked_round_after_block_round - {locked_round = preendorsement_round; round}) - >>? fun () -> - error_when - Compare.Int.(preendorsement_count < consensus_threshold) - (Insufficient_locked_round_evidence - {voting_power = preendorsement_count; consensus_threshold}) - >>? fun () -> ok (Some preendorsement_round)) - >>? fun locked_round -> Fitness_repr.check_locked_round fitness ~locked_round diff --git a/src/proto_012_Psithaca/lib_protocol/block_header_repr.mli b/src/proto_012_Psithaca/lib_protocol/block_header_repr.mli deleted file mode 100644 index e4b3d09086e4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/block_header_repr.mli +++ /dev/null @@ -1,159 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Representation of block headers. *) - -type contents = { - payload_hash : Block_payload_hash.t; - payload_round : Round_repr.t; - seed_nonce_hash : Nonce_hash.t option; - proof_of_work_nonce : bytes; - liquidity_baking_escape_vote : bool; - (* set by baker to vote in favor of permanently disabling liquidity baking *) -} - -type protocol_data = {contents : contents; signature : Signature.t} - -type t = {shell : Block_header.shell_header; protocol_data : protocol_data} - -type block_header = t - -type raw = Block_header.t - -type shell_header = Block_header.shell_header - -val raw : block_header -> raw - -val encoding : block_header Data_encoding.encoding - -val raw_encoding : raw Data_encoding.t - -val contents_encoding : contents Data_encoding.t - -val unsigned_encoding : (Block_header.shell_header * contents) Data_encoding.t - -val protocol_data_encoding : protocol_data Data_encoding.encoding - -val shell_header_encoding : shell_header Data_encoding.encoding - -type block_watermark = Block_header of Chain_id.t - -val to_watermark : block_watermark -> Signature.watermark - -val of_watermark : Signature.watermark -> block_watermark option - -(** The maximum size of block headers in bytes *) -val max_header_length : int - -val hash : block_header -> Block_hash.t - -val hash_raw : raw -> Block_hash.t - -type error += - | (* Permanent *) - Invalid_block_signature of - Block_hash.t * Signature.Public_key_hash.t - | (* Permanent *) Invalid_stamp - | (* Permanent *) - Invalid_payload_hash of { - expected : Block_payload_hash.t; - provided : Block_payload_hash.t; - } - | (* Permanent *) - Locked_round_after_block_round of { - locked_round : Round_repr.t; - round : Round_repr.t; - } - | (* Permanent *) - Invalid_payload_round of { - payload_round : Round_repr.t; - round : Round_repr.t; - } - | (* Permanent *) - Insufficient_locked_round_evidence of { - voting_power : int; - consensus_threshold : int; - } - | (* Permanent *) Invalid_commitment of {expected : bool} - -(** Checks if the header that would be built from the given components - is valid for the given difficulty. The signature is not passed as - it is does not impact the proof-of-work stamp. The stamp is checked - on the hash of a block header whose signature has been - zeroed-out. *) -module Proof_of_work : sig - val check_hash : Block_hash.t -> int64 -> bool - - val check_header_proof_of_work_stamp : - shell_header -> contents -> int64 -> bool - - val check_proof_of_work_stamp : - proof_of_work_threshold:int64 -> block_header -> unit tzresult -end - -(** [check_timestamp ctxt timestamp round predecessor_timestamp - predecessor_round] verifies that the block's timestamp and round - are coherent with the predecessor block's timestamp and - round. Fails with an error if that is not the case. *) -val check_timestamp : - Round_repr.Durations.t -> - timestamp:Time.t -> - round:Round_repr.t -> - predecessor_timestamp:Time.t -> - predecessor_round:Round_repr.t -> - unit tzresult - -val check_signature : t -> Chain_id.t -> Signature.Public_key.t -> unit tzresult - -val begin_validate_block_header : - block_header:t -> - chain_id:Chain_id.t -> - predecessor_timestamp:Time.t -> - predecessor_round:Round_repr.t -> - fitness:Fitness_repr.t -> - timestamp:Time.t -> - delegate_pk:Signature.public_key -> - round_durations:Round_repr.Durations.t -> - proof_of_work_threshold:int64 -> - expected_commitment:bool -> - unit tzresult - -type locked_round_evidence = { - preendorsement_round : Round_repr.t; - preendorsement_count : int; -} - -type checkable_payload_hash = - | No_check - | Expected_payload_hash of Block_payload_hash.t - -val finalize_validate_block_header : - block_header_contents:contents -> - round:Round_repr.t -> - fitness:Fitness_repr.t -> - checkable_payload_hash:checkable_payload_hash -> - locked_round_evidence:locked_round_evidence option -> - consensus_threshold:int -> - unit tzresult diff --git a/src/proto_012_Psithaca/lib_protocol/block_payload_hash.ml b/src/proto_012_Psithaca/lib_protocol/block_payload_hash.ml deleted file mode 100644 index 724dec25f8b1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/block_payload_hash.ml +++ /dev/null @@ -1,42 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* 32 *) -let prefix = "\001\106\242" (* vh(52) *) - -include - Blake2B.Make - (Base58) - (struct - let name = "value_hash" - - let title = "Hash of a consensus value" - - let b58check_prefix = prefix - - let size = None - end) - -let () = Base58.check_encoded_prefix b58check_encoding "vh" 52 diff --git a/src/proto_012_Psithaca/lib_protocol/block_payload_hash.mli b/src/proto_012_Psithaca/lib_protocol/block_payload_hash.mli deleted file mode 100644 index 90280546e53c..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/block_payload_hash.mli +++ /dev/null @@ -1,28 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** A specialized Blake2B implementation for hashing block's payloads. *) - -include S.HASH diff --git a/src/proto_012_Psithaca/lib_protocol/block_payload_repr.ml b/src/proto_012_Psithaca/lib_protocol/block_payload_repr.ml deleted file mode 100644 index ad46807466a5..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/block_payload_repr.ml +++ /dev/null @@ -1,41 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Value on which validators try to reach a consensus. - - Consensus at a given level is reached on a sequence of operations. However, - to differentiate between two blocks having the same sequence of operations, - assuming that could ever happen (for instance, two empty blocks), we also - include the hash of the block that precedes the block where these operations - should be included. *) - -let hash ~predecessor round operations_hash = - let open Data_encoding in - let predecessor = Binary.to_bytes_exn Block_hash.encoding predecessor in - let round = Binary.to_bytes_exn Round_repr.encoding round in - let operations_hash = - Binary.to_bytes_exn Operation_list_hash.encoding operations_hash - in - Block_payload_hash.hash_bytes [predecessor; round; operations_hash] diff --git a/src/proto_012_Psithaca/lib_protocol/block_payload_repr.mli b/src/proto_012_Psithaca/lib_protocol/block_payload_repr.mli deleted file mode 100644 index 82c672e280cb..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/block_payload_repr.mli +++ /dev/null @@ -1,41 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Value on which validators try to reach a consensus. - - Consensus at a given level is reached on a sequence of operations. However, - to differentiate between two blocks having the same sequence of operations, - assuming that could ever happen (for instance, two empty blocks), we also - include the hash of the block that precedes the block where these operations - should be included. *) - -(** [hash ~predecessor:block_hash round oplh] creates a payload hash given a - [block_hash], the first [round] at which the payload was proposed - and the hash [oplh] of the non-consensus operations. *) -val hash : - predecessor:Block_hash.t -> - Round_repr.t -> - Operation_list_hash.t -> - Block_payload_hash.t diff --git a/src/proto_012_Psithaca/lib_protocol/bootstrap_storage.ml b/src/proto_012_Psithaca/lib_protocol/bootstrap_storage.ml deleted file mode 100644 index 3636d5f1793e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/bootstrap_storage.ml +++ /dev/null @@ -1,120 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let init_account (ctxt, balance_updates) - ({public_key_hash; public_key; amount} : Parameters_repr.bootstrap_account) - = - let contract = Contract_repr.implicit_contract public_key_hash in - Token.transfer - ~origin:Protocol_migration - ctxt - `Bootstrap - (`Contract contract) - amount - >>=? fun (ctxt, new_balance_updates) -> - (match public_key with - | Some public_key -> - Contract_manager_storage.reveal_manager_key - ctxt - public_key_hash - public_key - >>=? fun ctxt -> Delegate_storage.set ctxt contract (Some public_key_hash) - | None -> return ctxt) - >|=? fun ctxt -> (ctxt, new_balance_updates @ balance_updates) - -let init_contract ~typecheck (ctxt, balance_updates) - ({delegate; amount; script} : Parameters_repr.bootstrap_contract) = - Contract_storage.fresh_contract_from_current_nonce ctxt - >>?= fun (ctxt, contract) -> - typecheck ctxt script >>=? fun (script, ctxt) -> - Contract_storage.raw_originate - ctxt - ~prepaid_bootstrap_storage:true - contract - ~script - >>=? fun ctxt -> - (match delegate with - | None -> return ctxt - | Some delegate -> Delegate_storage.init ctxt contract delegate) - >>=? fun ctxt -> - let origin = Receipt_repr.Protocol_migration in - Token.transfer ~origin ctxt `Bootstrap (`Contract contract) amount - >|=? fun (ctxt, new_balance_updates) -> - (ctxt, new_balance_updates @ balance_updates) - -let init ctxt ~typecheck ?no_reward_cycles accounts contracts = - let nonce = Operation_hash.hash_string ["Un festival de GADT."] in - let ctxt = Raw_context.init_origination_nonce ctxt nonce in - List.fold_left_es init_account (ctxt, []) accounts - >>=? fun (ctxt, balance_updates) -> - List.fold_left_es (init_contract ~typecheck) (ctxt, balance_updates) contracts - >>=? fun (ctxt, balance_updates) -> - (match no_reward_cycles with - | None -> return ctxt - | Some cycles -> - (* Store pending ramp ups. *) - let constants = Raw_context.constants ctxt in - (* Start without rewards *) - Raw_context.patch_constants ctxt (fun c -> - { - c with - baking_reward_fixed_portion = Tez_repr.zero; - baking_reward_bonus_per_slot = Tez_repr.zero; - endorsing_reward_per_slot = Tez_repr.zero; - }) - >>= fun ctxt -> - (* Store the final reward. *) - Storage.Ramp_up.( - Rewards.init - ctxt - (Cycle_repr.of_int32_exn (Int32.of_int cycles)) - { - baking_reward_fixed_portion = constants.baking_reward_fixed_portion; - baking_reward_bonus_per_slot = - constants.baking_reward_bonus_per_slot; - endorsing_reward_per_slot = constants.endorsing_reward_per_slot; - })) - >|=? fun ctxt -> (ctxt, balance_updates) - -let cycle_end ctxt last_cycle = - let next_cycle = Cycle_repr.succ last_cycle in - Storage.Ramp_up.Rewards.find ctxt next_cycle >>=? function - | None -> return ctxt - | Some - Storage.Ramp_up. - { - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - } -> - Storage.Ramp_up.Rewards.remove_existing ctxt next_cycle >>=? fun ctxt -> - Raw_context.patch_constants ctxt (fun c -> - { - c with - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - }) - >|= ok diff --git a/src/proto_012_Psithaca/lib_protocol/bootstrap_storage.mli b/src/proto_012_Psithaca/lib_protocol/bootstrap_storage.mli deleted file mode 100644 index 3b72ec8ca940..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/bootstrap_storage.mli +++ /dev/null @@ -1,38 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val init : - Raw_context.t -> - typecheck: - (Raw_context.t -> - Script_repr.t -> - ((Script_repr.t * Lazy_storage_diff.diffs option) * Raw_context.t) tzresult - Lwt.t) -> - ?no_reward_cycles:int -> - Parameters_repr.bootstrap_account list -> - Parameters_repr.bootstrap_contract list -> - (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t - -val cycle_end : Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/cache_memory_helpers.ml b/src/proto_012_Psithaca/lib_protocol/cache_memory_helpers.ml deleted file mode 100644 index 83bdeb348494..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/cache_memory_helpers.ml +++ /dev/null @@ -1,168 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** The [Nodes] module is used to count the number of computation steps - performed when evaluating the size of the in-memory graph corresponding - to an OCaml value. - - In first approximation, the value of type [Nodes.t] threaded through - {!expr_size} below and through the module {!Script_typed_ir_size} - is meant to match the number of recursive calls in the [traverse] - functions of {!Script_typed_ir} and in that of {!node_size}. - - The assumption is that there's a bounded amount of work performed between - two such recursive calls, hence that the total work is bounded above - by something proportional to the [Nodes.t] accumulator. - - Computations on values of type [Nodes.t] do not overflow, as they - are bounded above by the number of nodes traversed when computing - an OCaml value. - *) -module Nodes : sig - type t = private int - - val zero : t - - val one : t [@@ocaml.warning "-32"] - - val succ : t -> t - - val add : t -> t -> t - - val to_int : t -> int -end = struct - type t = int - - let zero = 0 - - let one = 1 - - let succ x = x + 1 - - let add x y = x + y - - let to_int x = x -end - -(** {2 Helpers to deal with computing the in-memory size of values} *) - -type sint = Saturation_repr.may_saturate Saturation_repr.t - -type nodes_and_size = Nodes.t * sint - -let ( !! ) = Saturation_repr.safe_int - -let ( +! ) = Saturation_repr.add - -let ( +? ) s x = Saturation_repr.add s !!x - -let ( *? ) s x = Saturation_repr.mul s !!x - -let ( /? ) s x = Saturation_repr.ediv s !!x - -let ( ++ ) (n1, s1) (n2, s2) = (Nodes.add n1 n2, s1 +! s2) - -let zero = (Nodes.zero, !!0) - -let word_size = !!8 - -let header_size = word_size - -let int64_size = header_size +! (word_size *? 2) - -let h1w = header_size +! word_size - -let h2w = header_size +! (word_size *? 2) - -let h3w = header_size +! (word_size *? 3) - -let h4w = header_size +! (word_size *? 4) - -let h5w = header_size +! (word_size *? 5) - -let hh3w = (word_size *? 3) +! (header_size *? 2) - -let hh6w = (word_size *? 6) +! (header_size *? 2) - -let hh8w = (word_size *? 8) +! (header_size *? 2) - -let z_size z = - let numbits = Z.numbits z in - if Compare.Int.(numbits <= 62) then !!0 else (word_size *? Z.size z) +? 32 - -let string_size_gen len = header_size +? (len + (8 - (len mod 8))) - -let bytes_size b = string_size_gen (Bytes.length b) - -let string_size s = string_size_gen (String.length s) - -let ret_adding (nodes, size) added = (nodes, size +! added) - -let ret_succ_adding (nodes, size) added = (Nodes.succ nodes, size +! added) - -let ret_succ (nodes, size) = (Nodes.succ nodes, size) - -let option_size some x = - let some x = h1w +! some x in - Option.fold ~none:!!0 ~some x - -let option_size_vec some x = - let some x = ret_adding (some x) h1w in - Option.fold ~none:zero ~some x - -let list_cell_size elt_size = - header_size +! word_size +! word_size +! elt_size - [@@ocaml.inline always] - -let list_fold_size elt_size list = - List.fold_left - (fun accu elt -> ret_succ_adding (accu ++ elt_size elt) h2w) - zero - list - -let boxed_tup2 x y = - header_size +! word_size +! word_size +! x +! y - [@@ocaml.inline always] - -let node_size = - let open Micheline in - let annotation_size a = - List.fold_left - (fun accu s -> ret_succ_adding accu (h2w +! string_size s)) - zero - a - in - let internal_node_size = function - | Int (_, z) -> (Nodes.one, h2w +! z_size z) - | String (_, s) -> (Nodes.one, h2w +! string_size s) - | Bytes (_, s) -> (Nodes.one, h2w +! bytes_size s) - | Prim (_, _, _, a) -> ret_succ_adding (annotation_size a) h4w - | Seq (_, _) -> (Nodes.one, h2w) - in - fun node -> - Script_repr.fold node zero @@ fun accu node -> - accu ++ internal_node_size node - -let expr_size expr = node_size (Micheline.root expr) diff --git a/src/proto_012_Psithaca/lib_protocol/cache_repr.ml b/src/proto_012_Psithaca/lib_protocol/cache_repr.ml deleted file mode 100644 index 6aeada3338db..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/cache_repr.ml +++ /dev/null @@ -1,249 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Cache_costs = struct - module S = Saturation_repr - - (* Computed by typing the contract - "{parameter unit; storage unit; code FAILWITH}" - and evaluating - [(8 * Obj.reachable_words (Obj.repr typed_script))] - where [typed_script] is of type [ex_script] *) - let minimal_size_of_typed_contract_in_bytes = 688 - - let approximate_cardinal bytes = - S.safe_int (bytes / minimal_size_of_typed_contract_in_bytes) - - let log2 x = S.safe_int (1 + S.numbits x) - - let cache_update_constant = S.safe_int 600 - - let cache_update_coeff = S.safe_int 57 - - (* Cost of calling [Environment_cache.update]. *) - let cache_update ~cache_size_in_bytes = - let approx_card = approximate_cardinal cache_size_in_bytes in - Gas_limit_repr.atomic_step_cost - S.(add cache_update_constant (mul cache_update_coeff (log2 approx_card))) - - (* Cost of calling [Environment_cache.find]. - This overapproximates [cache_find] slightly. *) - let cache_find = cache_update -end - -type index = int - -type size = int - -type identifier = string - -type namespace = string - -let compare_namespace = Compare.String.compare - -type internal_identifier = {namespace : namespace; id : identifier} - -let separator = '@' - -let sanitize namespace = - if String.contains namespace separator then - invalid_arg - (Format.asprintf - "Invalid cache namespace: '%s'. Character %c is forbidden." - namespace - separator) - else namespace - -let create_namespace = sanitize - -let string_of_internal_identifier {namespace; id} = - namespace ^ String.make 1 separator ^ id - -let internal_identifier_of_string raw = - match String.index_opt raw separator with - | None -> assert false - | Some index -> - { - (* We do not need to call sanitize here since we stop at the first '@' - from index 0. It is a guarantee that there is no '@' between 0 and - (index - 1 ). *) - namespace = String.sub raw 0 index; - id = - (let delim_idx = index + 1 in - String.sub raw delim_idx (String.length raw - delim_idx)); - } - -let internal_identifier_of_key key = - let raw = Raw_context.Cache.identifier_of_key key in - internal_identifier_of_string raw - -let key_of_internal_identifier ~cache_index identifier = - let raw = string_of_internal_identifier identifier in - Raw_context.Cache.key_of_identifier ~cache_index raw - -let make_key = - let namespaces = ref [] in - fun ~cache_index ~namespace -> - if List.mem ~equal:String.equal namespace !namespaces then - invalid_arg - (Format.sprintf "Cache key namespace %s already exist." namespace) - else ( - namespaces := namespace :: !namespaces ; - fun ~id -> - let identifier = {namespace; id} in - key_of_internal_identifier ~cache_index identifier) - -module NamespaceMap = Map.Make (struct - type t = namespace - - let compare = compare_namespace -end) - -type partial_key_handler = - Raw_context.t -> string -> Context.Cache.value tzresult Lwt.t - -let value_of_key_handlers : partial_key_handler NamespaceMap.t ref = - ref NamespaceMap.empty - -module Admin = struct - include Raw_context.Cache - - let list_keys context ~cache_index = - Raw_context.Cache.list_keys context ~cache_index - - let key_rank context key = Raw_context.Cache.key_rank context key - - let value_of_key ctxt key = - (* [value_of_key] is a maintenance operation: it is typically run - when a node reboots. For this reason, this operation is not - carbonated. *) - let ctxt = Raw_context.set_gas_unlimited ctxt in - let {namespace; id} = internal_identifier_of_key key in - match NamespaceMap.find namespace !value_of_key_handlers with - | Some value_of_key -> value_of_key ctxt id - | None -> - failwith - (Format.sprintf "No handler for key `%s%c%s'" namespace separator id) -end - -module type CLIENT = sig - val cache_index : int - - val namespace : namespace - - type cached_value - - val value_of_identifier : - Raw_context.t -> identifier -> cached_value tzresult Lwt.t -end - -module type INTERFACE = sig - type cached_value - - val update : - Raw_context.t -> - identifier -> - (cached_value * int) option -> - Raw_context.t tzresult - - val find : Raw_context.t -> identifier -> cached_value option tzresult Lwt.t - - val list_identifiers : Raw_context.t -> (identifier * int) list - - val identifier_rank : Raw_context.t -> identifier -> int option - - val size : Raw_context.t -> size - - val size_limit : Raw_context.t -> size -end - -let register_exn (type cvalue) - (module C : CLIENT with type cached_value = cvalue) : - (module INTERFACE with type cached_value = cvalue) = - if - Compare.Int.(C.cache_index < 0) - || Compare.List_length_with.(Constants_repr.cache_layout <= C.cache_index) - then invalid_arg "Cache index is invalid" ; - let mk = make_key ~cache_index:C.cache_index ~namespace:C.namespace in - (module struct - type cached_value = C.cached_value - - type Admin.value += K of cached_value - - let () = - let voi ctxt i = - C.value_of_identifier ctxt i >>=? fun v -> return (K v) - in - value_of_key_handlers := - NamespaceMap.add C.namespace voi !value_of_key_handlers - - let size ctxt = - Option.value ~default:max_int - @@ Admin.cache_size ctxt ~cache_index:C.cache_index - - let size_limit ctxt = - Option.value ~default:max_int - @@ Admin.cache_size_limit ctxt ~cache_index:C.cache_index - - let update ctxt id v = - let cache_size_in_bytes = size ctxt in - Raw_context.consume_gas - ctxt - (Cache_costs.cache_update ~cache_size_in_bytes) - >|? fun ctxt -> - let v = Option.map (fun (v, size) -> (K v, size)) v in - Admin.update ctxt (mk ~id) v - - let find ctxt id = - let cache_size_in_bytes = size ctxt in - Raw_context.consume_gas ctxt (Cache_costs.cache_find ~cache_size_in_bytes) - >>?= fun ctxt -> - Admin.find ctxt (mk ~id) >>= function - | None -> return None - | Some (K v) -> return (Some v) - | _ -> - (* This execution path is impossible because all the keys of - C's namespace (which is unique to C) are constructed with - [K]. This [assert false] could have been pushed into the - environment in exchange for extra complexity. The - argument that justifies this [assert false] seems - simple enough to keep the current design though. *) - assert false - - let list_identifiers ctxt = - Admin.list_keys ctxt ~cache_index:C.cache_index |> function - | None -> - (* `cache_index` is valid. *) - assert false - | Some list -> - List.filter_map - (fun (key, age) -> - let {namespace; id} = internal_identifier_of_key key in - if String.equal namespace C.namespace then Some (id, age) - else None) - list - - let identifier_rank ctxt id = Admin.key_rank ctxt (mk ~id) - end) diff --git a/src/proto_012_Psithaca/lib_protocol/cache_repr.mli b/src/proto_012_Psithaca/lib_protocol/cache_repr.mli deleted file mode 100644 index feefb25ec55b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/cache_repr.mli +++ /dev/null @@ -1,233 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** - - Frequently used data should be kept in memory and persisted along a - chain of blocks. The caching mechanism allows the economic protocol - to declare such data and to rely on a Least Recently Used strategy - to keep the cache size under a fixed limit. - - Take a look at {!Environment_cache} and {!Environment_context} - for additional implementation details about the protocol cache. - - The protocol has two main kinds of interaction with the cache: - - 1. It is responsible for setting up the cache with appropriate - parameter values and callbacks. It must also compute cache nonces - to give the shell enough information to properly synchronize the - in-memory cache with the block contexts and protocol upgrades. - A typical place where this happens is {!Apply}. - This aspect must be implemented using {!Cache.Admin}. - - 2. It can exploit the cache to retrieve, to insert, and to update - cached values from the in-memory cache. The basic idea is to - avoid recomputing values from scratch at each block when they are - frequently used. {!Script_cache} is an example of such usage. - This aspect must be implemented using {!Cache.Interface}. - - *) - -(** Size for subcaches and values of the cache. *) -type size = int - -(** Index type to index caches. *) -type index = int - -(** - - The following module acts on the whole cache, not on a specific - sub-cache, unlike {!Interface}. It is used to administrate the - protocol cache, e.g., to maintain the cache in a consistent state - with respect to the chain. This module is typically used by - low-level layers of the protocol and by the shell. - - *) -module Admin : sig - (** A key uniquely identifies a cached [value] in some subcache. *) - type key - - (** Cached values. *) - type value - - (** [pp fmt ctxt] is a pretty printter for the [cache] of [ctxt]. *) - val pp : Format.formatter -> Raw_context.t -> unit - - (** [set_cache_layout ctxt layout] sets the caches of [ctxt] to - comply with given [layout]. If there was already a cache in - [ctxt], it is erased by the new layout. - - In that case, a fresh collection of empty caches is reconstructed - from the new [layout]. Notice that cache [key]s are invalidated - in that case, i.e. [find t k] will return [None]. *) - val set_cache_layout : Raw_context.t -> size list -> Raw_context.t Lwt.t - - (** [sync ctxt ~cache_nonce] updates the context with the domain of - the cache computed so far. Such function is expected to be called - at the end of the validation of a block, when there is no more - accesses to the cache. - - [cache_nonce] identifies the block that introduced new cache - entries. The nonce should identify uniquely the block which - modifies this value. It cannot be the block hash for circularity - reasons: The value of the nonce is stored onto the context and - consequently influences the context hash of the very same - block. Such nonce cannot be determined by the shell and its - computation is delegated to the economic protocol. *) - val sync : Raw_context.t -> cache_nonce:Bytes.t -> Raw_context.t Lwt.t - - (** [clear ctxt] removes all cache entries. *) - val clear : Raw_context.t -> Raw_context.t - - (** {3 Cache helpers for RPCs} *) - - (** [future_cache_expectation ctxt ~time_in_blocks] returns [ctxt] except - that the entries of the caches that are presumably too old to - still be in the caches in [n_blocks] are removed. - - This function is based on a heuristic. The context maintains - the median of the number of removed entries: this number is - multipled by `n_blocks` to determine the entries that are - likely to be removed in `n_blocks`. *) - val future_cache_expectation : - Raw_context.t -> time_in_blocks:int -> Raw_context.t - - (** [cache_size ctxt ~cache_index] returns an overapproximation of - the size of the cache. Returns [None] if [cache_index] is - greater than the number of subcaches declared by the cache - layout. *) - val cache_size : Raw_context.t -> cache_index:int -> size option - - (** [cache_size_limit ctxt ~cache_index] returns the maximal size of - the cache indexed by [cache_index]. Returns [None] if - [cache_index] is greater than the number of subcaches declared - by the cache layout. *) - val cache_size_limit : Raw_context.t -> cache_index:int -> size option - - (** [value_of_key ctxt k] interprets the functions introduced by - [register] to construct a cacheable value for a key [k]. *) - val value_of_key : - Raw_context.t -> Context.Cache.key -> Context.Cache.value tzresult Lwt.t -end - -(** A client uses a unique namespace (represented as a string - without '@') to avoid collision with the keys of other - clients. *) -type namespace = private string - -(** [create_namespace str] creates a valid namespace from [str] - - @raise Invalid_argument if [str] contains '@' - *) -val create_namespace : string -> namespace - -(** A key is fully determined by a namespace and an identifier. *) -type identifier = string - -(** - To use the cache, a client must implement the [CLIENT] - interface. - - *) -module type CLIENT = sig - (** The type of value to be stored in the cache. *) - type cached_value - - (** The client must declare the index of the subcache where its - values shall live. [cache_index] must be between [0] and - [List.length Constants_repr.cache_layout - 1]. *) - val cache_index : index - - (** The client must declare a namespace. This namespace must - be unique. Otherwise, the program stops. - A namespace cannot contain '@'. *) - val namespace : namespace - - (** [value_of_identifier id] builds the cached value identified by - [id]. This function is called when the subcache is loaded into - memory from the on-disk representation of its domain. - - An error during the execution of this function is fatal as - witnessed by its type: an error embedded in a [tzresult] is not - supposed to be caught by the protocol. *) - val value_of_identifier : - Raw_context.t -> identifier -> cached_value tzresult Lwt.t -end - -(** - - An [INTERFACE] to the subcache where keys live in a given [namespace]. - - *) -module type INTERFACE = sig - (** The type of value to be stored in the cache. *) - type cached_value - - (** [update ctxt i (Some (e, size))] returns a context where the - value [e] of given [size] is associated to identifier [i] in - the subcache. If [i] is already in the subcache, the cache - entry is updated. - - [update ctxt i None] removes [i] from the subcache. *) - val update : - Raw_context.t -> - identifier -> - (cached_value * size) option -> - Raw_context.t tzresult - - (** [find ctxt i = Some v] if [v] is the value associated to [i] - in the subcache. Returns [None] if there is no such value in - the subcache. This function is in the Lwt monad because if the - value may have not been constructed (see the lazy loading - mode in {!Environment_context}), it is constructed on the fly. *) - val find : Raw_context.t -> identifier -> cached_value option tzresult Lwt.t - - (** [list_identifiers ctxt] returns the list of the - identifiers of the cached values along with their respective - size. The returned list is sorted in terms of their age in the - cache, the oldest coming first. *) - val list_identifiers : Raw_context.t -> (string * int) list - - (** [identifier_rank ctxt identifier] returns the number of cached values - older than the one of [identifier]; or, [None] if the [identifier] has - no associated value in the subcache. *) - val identifier_rank : Raw_context.t -> string -> int option - - (** [size ctxt] returns an overapproximation of the subcache size - (in bytes). *) - val size : Raw_context.t -> int - - (** [size_limit ctxt] returns the maximal size of the subcache - (in bytes). *) - val size_limit : Raw_context.t -> int -end - -(** [register_exn client] produces an [Interface] specific to a - given [client]. This function can fail if [client] does not - respect the invariant declared in the documentation of - {!CLIENT}. *) -val register_exn : - (module CLIENT with type cached_value = 'a) -> - (module INTERFACE with type cached_value = 'a) diff --git a/src/proto_012_Psithaca/lib_protocol/commitment_repr.ml b/src/proto_012_Psithaca/lib_protocol/commitment_repr.ml deleted file mode 100644 index 38f114120c35..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/commitment_repr.ml +++ /dev/null @@ -1,36 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = { - blinded_public_key_hash : Blinded_public_key_hash.t; - amount : Tez_repr.t; -} - -let encoding = - let open Data_encoding in - conv - (fun {blinded_public_key_hash; amount} -> (blinded_public_key_hash, amount)) - (fun (blinded_public_key_hash, amount) -> {blinded_public_key_hash; amount}) - (tup2 Blinded_public_key_hash.encoding Tez_repr.encoding) diff --git a/src/proto_012_Psithaca/lib_protocol/commitment_repr.mli b/src/proto_012_Psithaca/lib_protocol/commitment_repr.mli deleted file mode 100644 index edca4134d844..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/commitment_repr.mli +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = { - blinded_public_key_hash : Blinded_public_key_hash.t; - amount : Tez_repr.t; -} - -val encoding : t Data_encoding.t diff --git a/src/proto_012_Psithaca/lib_protocol/commitment_storage.ml b/src/proto_012_Psithaca/lib_protocol/commitment_storage.ml deleted file mode 100644 index 272702a4ae67..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/commitment_storage.ml +++ /dev/null @@ -1,44 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let exists = Storage.Commitments.mem - -let committed_amount ctxt bpkh = - Storage.Commitments.find ctxt bpkh >>=? fun balance -> - return (Option.value ~default:Tez_repr.zero balance) - -let increase_commitment_only_call_from_token ctxt bpkh amount = - if Tez_repr.(amount = zero) then return ctxt - else - committed_amount ctxt bpkh >>=? fun balance -> - Tez_repr.(amount +? balance) >>?= fun new_balance -> - Storage.Commitments.add ctxt bpkh new_balance >|= ok - -let decrease_commitment_only_call_from_token ctxt bpkh amount = - committed_amount ctxt bpkh >>=? fun balance -> - Tez_repr.(balance -? amount) >>?= fun new_balance -> - if Tez_repr.(new_balance = Tez_repr.zero) then - Storage.Commitments.remove ctxt bpkh >|= ok - else Storage.Commitments.add ctxt bpkh new_balance >|= ok diff --git a/src/proto_012_Psithaca/lib_protocol/commitment_storage.mli b/src/proto_012_Psithaca/lib_protocol/commitment_storage.mli deleted file mode 100644 index 6c74e56a076a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/commitment_storage.mli +++ /dev/null @@ -1,45 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** [exists ctxt bpkh] returns true iff [bpkh] is associated to a non null - commitment. *) -val exists : Raw_context.t -> Blinded_public_key_hash.t -> bool Lwt.t - -(** [committed_amount ctxt bpkh] return the commitment associated to [bpkh], or - [Tez_repr.zero] if [bpkh] has no associated commitment. *) -val committed_amount : - Raw_context.t -> Blinded_public_key_hash.t -> Tez_repr.t tzresult Lwt.t - -val increase_commitment_only_call_from_token : - Raw_context.t -> - Blinded_public_key_hash.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t - -val decrease_commitment_only_call_from_token : - Raw_context.t -> - Blinded_public_key_hash.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/constants_repr.ml b/src/proto_012_Psithaca/lib_protocol/constants_repr.ml deleted file mode 100644 index 4acea2a75df2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/constants_repr.ml +++ /dev/null @@ -1,644 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* The fitness version number was: - - "\000" until and including proto 004 - - "\001" until and including proto 010 -*) -let fitness_version_number = "\002" - -let proof_of_work_nonce_size = 8 - -let nonce_length = 32 - -let max_anon_ops_per_block = 132 - -let max_proposals_per_delegate = 20 - -let max_operation_data_length = 32 * 1024 (* 32kB *) - -let max_micheline_node_count = 50_000 - -let max_micheline_bytes_limit = 50_000 - -let max_allowed_global_constant_depth = 10_000 - -(* In this version of the protocol, there are the following subcaches: - - * One for contract source code and storage. Its size has been - chosen not too exceed 100 000 000 bytes. - - * One for the stake distribution for all cycles stored at any - moment (* preserved_cycles + max_slashing_period + 1 *) - - * One for the sampler state for all cycles stored at any moment. *) - -let stake_distribution_size = 500 (* delegates*) * 15 (* words *) * 4 -(* bytes *) - -let sampler_state_size = 80 (* words *) * 4 (* bytes *) - -let cache_layout = - [ - 100_000_000; - 8 (* cycles *) * stake_distribution_size; - 8 (* cycles *) * sampler_state_size; - ] - -(* In previous versions of the protocol, this - [michelson_maximum_type_size] limit was set to 1000 but - the contract input types (pair ) - were not checked. Both components, and - where however checked hence it was possible to build - types as big as 2001. *) -let michelson_maximum_type_size = 2001 - -type fixed = unit - -type ratio = {numerator : int; denominator : int} - -let ratio_encoding = - let open Data_encoding in - conv_with_guard - (fun r -> (r.numerator, r.denominator)) - (fun (numerator, denominator) -> - if Compare.Int.(denominator > 0) then ok {numerator; denominator} - else Error "The denominator must be greater than 0.") - (obj2 (req "numerator" uint16) (req "denominator" uint16)) - -let pp_ratio fmt {numerator; denominator} = - Format.fprintf fmt "%d/%d" numerator denominator - -let fixed_encoding = - let open Data_encoding in - let uint62 = - let max_int_int64 = Int64.of_int max_int in - conv_with_guard - (fun int -> Int64.of_int int) - (fun int64 -> - if Compare.Int64.(int64 < 0L) then Error "Negative integer" - else if Compare.Int64.(int64 > max_int_int64) then - Error "Integer does not fit in 62 bits" - else ok @@ Int64.to_int int64) - int64 - in - conv - (fun () -> - ( proof_of_work_nonce_size, - nonce_length, - max_anon_ops_per_block, - max_operation_data_length, - max_proposals_per_delegate, - max_micheline_node_count, - max_micheline_bytes_limit, - max_allowed_global_constant_depth, - cache_layout, - michelson_maximum_type_size )) - (fun ( _proof_of_work_nonce_size, - _nonce_length, - _max_anon_ops_per_block, - _max_operation_data_length, - _max_proposals_per_delegate, - _max_micheline_node_count, - _max_micheline_bytes_limit, - _max_allowed_global_constant_depth, - _cache_layout, - _michelson_maximum_type_size ) -> ()) - (obj10 - (req "proof_of_work_nonce_size" uint8) - (req "nonce_length" uint8) - (req "max_anon_ops_per_block" uint8) - (req "max_operation_data_length" int31) - (req "max_proposals_per_delegate" uint8) - (req "max_micheline_node_count" int31) - (req "max_micheline_bytes_limit" int31) - (req "max_allowed_global_constants_depth" int31) - (req "cache_layout" (list uint62)) - (req "michelson_maximum_type_size" uint16)) - -let fixed = () - -type delegate_selection = - | Random - | Round_robin_over of Signature.Public_key.t list list - -let delegate_selection_encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Random_delegate_selection" - (constant "random") - (function Random -> Some () | _ -> None) - (fun () -> Random); - case - (Tag 1) - ~title:"Round_robin_over_delegates" - (list (list Signature.Public_key.encoding)) - (function Round_robin_over l -> Some l | _ -> None) - (fun l -> Round_robin_over l); - ] - -(* The encoded representation of this type is stored in the context as - bytes. Changing the encoding, or the value of these constants from - the previous protocol may break the context migration, or (even - worse) yield an incorrect context after migration. - - If you change this encoding, you should ensure that there is a - proper migration of the constants during context migration. *) -type parametric = { - preserved_cycles : int; - blocks_per_cycle : int32; - blocks_per_commitment : int32; - blocks_per_stake_snapshot : int32; - blocks_per_voting_period : int32; - hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; - hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; - proof_of_work_threshold : int64; - tokens_per_roll : Tez_repr.t; - seed_nonce_revelation_tip : Tez_repr.t; - origination_size : int; - baking_reward_fixed_portion : Tez_repr.t; - baking_reward_bonus_per_slot : Tez_repr.t; - endorsing_reward_per_slot : Tez_repr.t; - cost_per_byte : Tez_repr.t; - hard_storage_limit_per_operation : Z.t; - quorum_min : int32; - quorum_max : int32; - min_proposal_quorum : int32; - liquidity_baking_subsidy : Tez_repr.t; - liquidity_baking_sunset_level : int32; - liquidity_baking_escape_ema_threshold : int32; - max_operations_time_to_live : int; - minimal_block_delay : Period_repr.t; - delay_increment_per_round : Period_repr.t; - minimal_participation_ratio : ratio; - consensus_committee_size : int; - consensus_threshold : int; - max_slashing_period : int; - frozen_deposits_percentage : int; - double_baking_punishment : Tez_repr.t; - ratio_of_frozen_deposits_slashed_per_double_endorsement : ratio; - delegate_selection : delegate_selection; -} - -let parametric_encoding = - let open Data_encoding in - conv - (fun c -> - ( ( c.preserved_cycles, - c.blocks_per_cycle, - c.blocks_per_commitment, - c.blocks_per_stake_snapshot, - c.blocks_per_voting_period, - c.hard_gas_limit_per_operation, - c.hard_gas_limit_per_block, - c.proof_of_work_threshold, - c.tokens_per_roll ), - ( ( c.seed_nonce_revelation_tip, - c.origination_size, - c.baking_reward_fixed_portion, - c.baking_reward_bonus_per_slot, - c.endorsing_reward_per_slot, - c.cost_per_byte, - c.hard_storage_limit_per_operation, - c.quorum_min ), - ( ( c.quorum_max, - c.min_proposal_quorum, - c.liquidity_baking_subsidy, - c.liquidity_baking_sunset_level, - c.liquidity_baking_escape_ema_threshold, - c.max_operations_time_to_live, - c.minimal_block_delay, - c.delay_increment_per_round, - c.consensus_committee_size, - c.consensus_threshold ), - ( c.minimal_participation_ratio, - c.max_slashing_period, - c.frozen_deposits_percentage, - c.double_baking_punishment, - c.ratio_of_frozen_deposits_slashed_per_double_endorsement, - c.delegate_selection ) ) ) )) - (fun ( ( preserved_cycles, - blocks_per_cycle, - blocks_per_commitment, - blocks_per_stake_snapshot, - blocks_per_voting_period, - hard_gas_limit_per_operation, - hard_gas_limit_per_block, - proof_of_work_threshold, - tokens_per_roll ), - ( ( seed_nonce_revelation_tip, - origination_size, - baking_reward_fixed_portion, - baking_reward_bonus_per_slot, - endorsing_reward_per_slot, - cost_per_byte, - hard_storage_limit_per_operation, - quorum_min ), - ( ( quorum_max, - min_proposal_quorum, - liquidity_baking_subsidy, - liquidity_baking_sunset_level, - liquidity_baking_escape_ema_threshold, - max_operations_time_to_live, - minimal_block_delay, - delay_increment_per_round, - consensus_committee_size, - consensus_threshold ), - ( minimal_participation_ratio, - max_slashing_period, - frozen_deposits_percentage, - double_baking_punishment, - ratio_of_frozen_deposits_slashed_per_double_endorsement, - delegate_selection ) ) ) ) -> - { - preserved_cycles; - blocks_per_cycle; - blocks_per_commitment; - blocks_per_stake_snapshot; - blocks_per_voting_period; - hard_gas_limit_per_operation; - hard_gas_limit_per_block; - proof_of_work_threshold; - tokens_per_roll; - seed_nonce_revelation_tip; - origination_size; - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - cost_per_byte; - hard_storage_limit_per_operation; - quorum_min; - quorum_max; - min_proposal_quorum; - liquidity_baking_subsidy; - liquidity_baking_sunset_level; - liquidity_baking_escape_ema_threshold; - max_operations_time_to_live; - minimal_block_delay; - delay_increment_per_round; - minimal_participation_ratio; - max_slashing_period; - consensus_committee_size; - consensus_threshold; - frozen_deposits_percentage; - double_baking_punishment; - ratio_of_frozen_deposits_slashed_per_double_endorsement; - delegate_selection; - }) - (merge_objs - (obj9 - (req "preserved_cycles" uint8) - (req "blocks_per_cycle" int32) - (req "blocks_per_commitment" int32) - (req "blocks_per_stake_snapshot" int32) - (req "blocks_per_voting_period" int32) - (req - "hard_gas_limit_per_operation" - Gas_limit_repr.Arith.z_integral_encoding) - (req - "hard_gas_limit_per_block" - Gas_limit_repr.Arith.z_integral_encoding) - (req "proof_of_work_threshold" int64) - (req "tokens_per_roll" Tez_repr.encoding)) - (merge_objs - (obj8 - (req "seed_nonce_revelation_tip" Tez_repr.encoding) - (req "origination_size" int31) - (req "baking_reward_fixed_portion" Tez_repr.encoding) - (req "baking_reward_bonus_per_slot" Tez_repr.encoding) - (req "endorsing_reward_per_slot" Tez_repr.encoding) - (req "cost_per_byte" Tez_repr.encoding) - (req "hard_storage_limit_per_operation" z) - (req "quorum_min" int32)) - (merge_objs - (obj10 - (req "quorum_max" int32) - (req "min_proposal_quorum" int32) - (req "liquidity_baking_subsidy" Tez_repr.encoding) - (req "liquidity_baking_sunset_level" int32) - (req "liquidity_baking_escape_ema_threshold" int32) - (req "max_operations_time_to_live" int16) - (req "minimal_block_delay" Period_repr.encoding) - (req "delay_increment_per_round" Period_repr.encoding) - (req "consensus_committee_size" int31) - (req "consensus_threshold" int31)) - (obj6 - (req "minimal_participation_ratio" ratio_encoding) - (req "max_slashing_period" int31) - (req "frozen_deposits_percentage" int31) - (req "double_baking_punishment" Tez_repr.encoding) - (req - "ratio_of_frozen_deposits_slashed_per_double_endorsement" - ratio_encoding) - (dft "delegate_selection" delegate_selection_encoding Random))))) - -type t = {fixed : fixed; parametric : parametric} - -let all parametric = {fixed; parametric} - -let encoding = - let open Data_encoding in - conv - (fun {fixed; parametric} -> (fixed, parametric)) - (fun (fixed, parametric) -> {fixed; parametric}) - (merge_objs fixed_encoding parametric_encoding) - -type error += Invalid_protocol_constants of string (* `Permanent *) - -let () = - register_error_kind - `Permanent - ~id:"constants.invalid_protocol_constants" - ~title:"Invalid protocol constants" - ~description:"The provided protocol constants are not coherent." - ~pp:(fun ppf reason -> - Format.fprintf ppf "Invalid protocol constants: %s" reason) - Data_encoding.(obj1 (req "reason" string)) - (function Invalid_protocol_constants reason -> Some reason | _ -> None) - (fun reason -> Invalid_protocol_constants reason) - -let check_constants constants = - error_unless - Period_repr.(constants.minimal_block_delay > zero) - (Invalid_protocol_constants - "The minimal block delay must be greater than zero") - >>? fun () -> - error_unless - Period_repr.(constants.delay_increment_per_round > zero) - (Invalid_protocol_constants - "The delay increment per round must be greater than zero") - >>? fun () -> - error_unless - Compare.Int.(constants.consensus_committee_size > 3) - (Invalid_protocol_constants - "The consensus committee size must be strictly greater than 3.") - >>? fun () -> - error_unless - Compare.Int.( - constants.consensus_threshold >= 0 - && constants.consensus_threshold <= constants.consensus_committee_size) - (Invalid_protocol_constants - "The consensus threshold must be greater than or equal to 0 and less \ - than or equal to the consensus commitee size.") - >>? fun () -> - error_unless - (let {numerator; denominator} = constants.minimal_participation_ratio in - Compare.Int.(numerator >= 0 && denominator > 0)) - (Invalid_protocol_constants - "The minimal participation ratio must be a non-negative valid ratio.") - >>? fun () -> - error_unless - Compare.Int.( - constants.minimal_participation_ratio.numerator - <= constants.minimal_participation_ratio.denominator) - (Invalid_protocol_constants - "The minimal participation ratio must be less than or equal to 100%.") - >>? fun () -> - error_unless - Compare.Int.(constants.max_slashing_period > 0) - (Invalid_protocol_constants - "The unfreeze delay must be strictly greater than 0.") - >>? fun () -> - (* The [frozen_deposits_percentage] should be a percentage *) - error_unless - Compare.Int.( - constants.frozen_deposits_percentage > 0 - && constants.frozen_deposits_percentage <= 100) - (Invalid_protocol_constants - "The frozen percentage ratio must be strictly greater than 0 and less \ - or equal than 100.") - >>? fun () -> - error_unless - Tez_repr.(constants.double_baking_punishment >= zero) - (Invalid_protocol_constants - "The double baking punishment must be non-negative.") - >>? fun () -> - error_unless - (let {numerator; denominator} = - constants.ratio_of_frozen_deposits_slashed_per_double_endorsement - in - Compare.Int.(numerator >= 0 && denominator > 0)) - (Invalid_protocol_constants - "The ratio of frozen deposits ratio slashed per double endorsement must \ - be a non-negative valid ratio.") - >>? fun () -> Result.return_unit - -module Generated = struct - type t = { - consensus_threshold : int; - baking_reward_fixed_portion : Tez_repr.t; - baking_reward_bonus_per_slot : Tez_repr.t; - endorsing_reward_per_slot : Tez_repr.t; - } - - let generate ~consensus_committee_size ~blocks_per_minute = - let consensus_threshold = (consensus_committee_size * 2 / 3) + 1 in - (* As in previous protocols, we set the maximum total rewards per minute to - be 80 tez. *) - let rewards_per_minute = Tez_repr.(mul_exn one 80) in - let rewards_per_block = - Tez_repr.( - div_exn - (mul_exn rewards_per_minute blocks_per_minute.denominator) - blocks_per_minute.numerator) - in - let rewards_half = Tez_repr.(div_exn rewards_per_block 2) in - let rewards_quarter = Tez_repr.(div_exn rewards_per_block 4) in - { - consensus_threshold; - baking_reward_fixed_portion = rewards_quarter; - baking_reward_bonus_per_slot = - Tez_repr.div_exn - rewards_quarter - (consensus_committee_size - consensus_threshold); - endorsing_reward_per_slot = - Tez_repr.div_exn rewards_half consensus_committee_size; - } -end - -module Proto_previous = struct - type parametric = { - preserved_cycles : int; - blocks_per_cycle : int32; - blocks_per_commitment : int32; - blocks_per_roll_snapshot : int32; - blocks_per_voting_period : int32; - time_between_blocks : Period_repr.t list; - minimal_block_delay : Period_repr.t; - endorsers_per_block : int; - hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; - hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; - proof_of_work_threshold : int64; - tokens_per_roll : Tez_repr.t; - seed_nonce_revelation_tip : Tez_repr.t; - origination_size : int; - block_security_deposit : Tez_repr.t; - endorsement_security_deposit : Tez_repr.t; - baking_reward_per_endorsement : Tez_repr.t list; - endorsement_reward : Tez_repr.t list; - cost_per_byte : Tez_repr.t; - hard_storage_limit_per_operation : Z.t; - quorum_min : int32; - quorum_max : int32; - min_proposal_quorum : int32; - initial_endorsers : int; - delay_per_missing_endorsement : Period_repr.t; - liquidity_baking_subsidy : Tez_repr.t; - liquidity_baking_sunset_level : int32; - liquidity_baking_escape_ema_threshold : int32; - } - - let parametric_encoding = - let open Data_encoding in - conv - (fun c -> - ( ( c.preserved_cycles, - c.blocks_per_cycle, - c.blocks_per_commitment, - c.blocks_per_roll_snapshot, - c.blocks_per_voting_period, - c.time_between_blocks, - c.endorsers_per_block, - c.hard_gas_limit_per_operation, - c.hard_gas_limit_per_block, - c.proof_of_work_threshold ), - ( ( c.tokens_per_roll, - c.seed_nonce_revelation_tip, - c.origination_size, - c.block_security_deposit, - c.endorsement_security_deposit, - c.baking_reward_per_endorsement, - c.endorsement_reward, - c.cost_per_byte, - c.hard_storage_limit_per_operation ), - ( c.quorum_min, - c.quorum_max, - c.min_proposal_quorum, - c.initial_endorsers, - c.delay_per_missing_endorsement, - c.minimal_block_delay, - c.liquidity_baking_subsidy, - c.liquidity_baking_sunset_level, - c.liquidity_baking_escape_ema_threshold ) ) )) - (fun ( ( preserved_cycles, - blocks_per_cycle, - blocks_per_commitment, - blocks_per_roll_snapshot, - blocks_per_voting_period, - time_between_blocks, - endorsers_per_block, - hard_gas_limit_per_operation, - hard_gas_limit_per_block, - proof_of_work_threshold ), - ( ( tokens_per_roll, - seed_nonce_revelation_tip, - origination_size, - block_security_deposit, - endorsement_security_deposit, - baking_reward_per_endorsement, - endorsement_reward, - cost_per_byte, - hard_storage_limit_per_operation ), - ( quorum_min, - quorum_max, - min_proposal_quorum, - initial_endorsers, - delay_per_missing_endorsement, - minimal_block_delay, - liquidity_baking_subsidy, - liquidity_baking_sunset_level, - liquidity_baking_escape_ema_threshold ) ) ) -> - { - preserved_cycles; - blocks_per_cycle; - blocks_per_commitment; - blocks_per_roll_snapshot; - blocks_per_voting_period; - time_between_blocks; - endorsers_per_block; - hard_gas_limit_per_operation; - hard_gas_limit_per_block; - proof_of_work_threshold; - tokens_per_roll; - seed_nonce_revelation_tip; - origination_size; - block_security_deposit; - endorsement_security_deposit; - baking_reward_per_endorsement; - endorsement_reward; - cost_per_byte; - hard_storage_limit_per_operation; - quorum_min; - quorum_max; - min_proposal_quorum; - initial_endorsers; - delay_per_missing_endorsement; - minimal_block_delay; - liquidity_baking_subsidy; - liquidity_baking_sunset_level; - liquidity_baking_escape_ema_threshold; - }) - (merge_objs - (obj10 - (req "preserved_cycles" uint8) - (req "blocks_per_cycle" int32) - (req "blocks_per_commitment" int32) - (req "blocks_per_roll_snapshot" int32) - (req "blocks_per_voting_period" int32) - (req "time_between_blocks" (list Period_repr.encoding)) - (req "endorsers_per_block" uint16) - (req - "hard_gas_limit_per_operation" - Gas_limit_repr.Arith.z_integral_encoding) - (req - "hard_gas_limit_per_block" - Gas_limit_repr.Arith.z_integral_encoding) - (req "proof_of_work_threshold" int64)) - (merge_objs - (obj9 - (req "tokens_per_roll" Tez_repr.encoding) - (req "seed_nonce_revelation_tip" Tez_repr.encoding) - (req "origination_size" int31) - (req "block_security_deposit" Tez_repr.encoding) - (req "endorsement_security_deposit" Tez_repr.encoding) - (req "baking_reward_per_endorsement" (list Tez_repr.encoding)) - (req "endorsement_reward" (list Tez_repr.encoding)) - (req "cost_per_byte" Tez_repr.encoding) - (req "hard_storage_limit_per_operation" z)) - (obj9 - (req "quorum_min" int32) - (req "quorum_max" int32) - (req "min_proposal_quorum" int32) - (req "initial_endorsers" uint16) - (req "delay_per_missing_endorsement" Period_repr.encoding) - (req "minimal_block_delay" Period_repr.encoding) - (req "liquidity_baking_subsidy" Tez_repr.encoding) - (req "liquidity_baking_sunset_level" int32) - (req "liquidity_baking_escape_ema_threshold" int32)))) -end diff --git a/src/proto_012_Psithaca/lib_protocol/constants_repr.mli b/src/proto_012_Psithaca/lib_protocol/constants_repr.mli deleted file mode 100644 index eace934c36bd..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/constants_repr.mli +++ /dev/null @@ -1,197 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val fitness_version_number : string - -val proof_of_work_nonce_size : int - -val nonce_length : int - -val max_anon_ops_per_block : int - -val max_proposals_per_delegate : int - -val max_operation_data_length : int - -(** A global size limit on the size of Micheline expressions - after expansion. - - We want to prevent constants from being - used to create huge values that could potentially do damage - if ever printed or sent over the network. We arrived at this - number by finding the largest possible contract in terms of - number of nodes. The number of nodes is constrained by the - current "max_operation_data_length" (32768) to be ~10,000 ( - see "largest_flat_contract.tz" in the tezt suite for the largest - contract with constants that can be originated). As a first - approximation, we set the node size limit to 5 times this amount. *) -val max_micheline_node_count : int - -(** Same as [max_micheline_node_count] but for limiting the combined - bytes of the strings, ints and bytes in a expanded Micheline - expression. *) -val max_micheline_bytes_limit : int - -(** Represents the maximum depth of an expression stored - in the table after all references to other constants have - (recursively) been expanded, where depth refers to the - nesting of [Prim] and/or [Seq] nodes. - - The size was chosen arbitrarily to match the typechecker - in [Script_ir_translator]. *) -val max_allowed_global_constant_depth : int - -(* an over-approximation of the size (in bytes) of an entry in the cache - storing the stake distribution for a given cycle *) -val stake_distribution_size : int - -(* an over-approximation of the size (in bytes) of an entry in the - cache storing the sampler state for a given cycle *) -val sampler_state_size : int - -(** Each protocol defines the number of subcaches and their respective - limit size using [cache_layout]. *) -val cache_layout : int list - -val michelson_maximum_type_size : int - -type fixed - -val fixed_encoding : fixed Data_encoding.encoding - -type ratio = {numerator : int; denominator : int} - -val ratio_encoding : ratio Data_encoding.t - -val pp_ratio : Format.formatter -> ratio -> unit - -type delegate_selection = - | Random - | Round_robin_over of Signature.Public_key.t list list - -val delegate_selection_encoding : delegate_selection Data_encoding.encoding - -type parametric = { - preserved_cycles : int; - blocks_per_cycle : int32; - blocks_per_commitment : int32; - blocks_per_stake_snapshot : int32; - blocks_per_voting_period : int32; - hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; - hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; - proof_of_work_threshold : int64; - tokens_per_roll : Tez_repr.t; - seed_nonce_revelation_tip : Tez_repr.t; - origination_size : int; - baking_reward_fixed_portion : Tez_repr.t; - baking_reward_bonus_per_slot : Tez_repr.t; - endorsing_reward_per_slot : Tez_repr.t; - cost_per_byte : Tez_repr.t; - hard_storage_limit_per_operation : Z.t; - quorum_min : int32; - (* in centile of a percentage *) - quorum_max : int32; - min_proposal_quorum : int32; - liquidity_baking_subsidy : Tez_repr.t; - liquidity_baking_sunset_level : int32; - liquidity_baking_escape_ema_threshold : int32; - max_operations_time_to_live : int; - minimal_block_delay : Period_repr.t; - delay_increment_per_round : Period_repr.t; - minimal_participation_ratio : ratio; - consensus_committee_size : int; - (* in slots *) - consensus_threshold : int; - (* in slots *) - max_slashing_period : int; - (* in cycles *) - frozen_deposits_percentage : int; - (* that is, (100 * delegated tz / own tz) *) - double_baking_punishment : Tez_repr.t; - ratio_of_frozen_deposits_slashed_per_double_endorsement : ratio; - delegate_selection : delegate_selection; -} - -val parametric_encoding : parametric Data_encoding.encoding - -type t = private {fixed : fixed; parametric : parametric} - -val all : parametric -> t - -val encoding : t Data_encoding.encoding - -type error += (* `Permanent *) Invalid_protocol_constants of string - -(** performs some consistency checks on the protocol parameters *) -val check_constants : parametric -> unit tzresult - -module Generated : sig - type t = { - consensus_threshold : int; - baking_reward_fixed_portion : Tez_repr.t; - baking_reward_bonus_per_slot : Tez_repr.t; - endorsing_reward_per_slot : Tez_repr.t; - } - - (* This function is meant to be used just in lib_parameters and in the - migration code to be sure that the parameters are consistent. *) - val generate : consensus_committee_size:int -> blocks_per_minute:ratio -> t -end - -module Proto_previous : sig - type parametric = { - preserved_cycles : int; - blocks_per_cycle : int32; - blocks_per_commitment : int32; - blocks_per_roll_snapshot : int32; - blocks_per_voting_period : int32; - time_between_blocks : Period_repr.t list; - minimal_block_delay : Period_repr.t; - endorsers_per_block : int; - hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; - hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; - proof_of_work_threshold : int64; - tokens_per_roll : Tez_repr.t; - seed_nonce_revelation_tip : Tez_repr.t; - origination_size : int; - block_security_deposit : Tez_repr.t; - endorsement_security_deposit : Tez_repr.t; - baking_reward_per_endorsement : Tez_repr.t list; - endorsement_reward : Tez_repr.t list; - cost_per_byte : Tez_repr.t; - hard_storage_limit_per_operation : Z.t; - quorum_min : int32; - quorum_max : int32; - min_proposal_quorum : int32; - initial_endorsers : int; - delay_per_missing_endorsement : Period_repr.t; - liquidity_baking_subsidy : Tez_repr.t; - liquidity_baking_sunset_level : int32; - liquidity_baking_escape_ema_threshold : int32; - } - - val parametric_encoding : parametric Data_encoding.encoding -end diff --git a/src/proto_012_Psithaca/lib_protocol/constants_services.ml b/src/proto_012_Psithaca/lib_protocol/constants_services.ml deleted file mode 100644 index bc7e8ae3bb0e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/constants_services.ml +++ /dev/null @@ -1,59 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -let custom_root = - (RPC_path.(open_root / "context" / "constants") - : RPC_context.t RPC_path.context) - -module S = struct - open Data_encoding - - let errors = - RPC_service.get_service - ~description:"Schema for all the RPC errors from this protocol version" - ~query:RPC_query.empty - ~output:json_schema - RPC_path.(custom_root / "errors") - - let all = - RPC_service.get_service - ~description:"All constants" - ~query:RPC_query.empty - ~output:Alpha_context.Constants.encoding - custom_root -end - -let register () = - let open Services_registration in - register0_noctxt ~chunked:true S.errors (fun () () -> - return Data_encoding.Json.(schema error_encoding)) ; - register0 ~chunked:false S.all (fun ctxt () () -> - return @@ Constants.all ctxt) - -let errors ctxt block = RPC_context.make_call0 S.errors ctxt block () () - -let all ctxt block = RPC_context.make_call0 S.all ctxt block () () diff --git a/src/proto_012_Psithaca/lib_protocol/constants_services.mli b/src/proto_012_Psithaca/lib_protocol/constants_services.mli deleted file mode 100644 index 4ebdfc3557d2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/constants_services.mli +++ /dev/null @@ -1,34 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -val errors : - 'a #RPC_context.simple -> 'a -> Data_encoding.json_schema shell_tzresult Lwt.t - -(** Returns all the constants of the protocol *) -val all : 'a #RPC_context.simple -> 'a -> Constants.t shell_tzresult Lwt.t - -val register : unit -> unit diff --git a/src/proto_012_Psithaca/lib_protocol/constants_storage.ml b/src/proto_012_Psithaca/lib_protocol/constants_storage.ml deleted file mode 100644 index e4f4241c338f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/constants_storage.ml +++ /dev/null @@ -1,150 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let preserved_cycles c = - let constants = Raw_context.constants c in - constants.preserved_cycles - -let blocks_per_cycle c = - let constants = Raw_context.constants c in - constants.blocks_per_cycle - -let blocks_per_commitment c = - let constants = Raw_context.constants c in - constants.blocks_per_commitment - -let blocks_per_stake_snapshot c = - let constants = Raw_context.constants c in - constants.blocks_per_stake_snapshot - -let blocks_per_voting_period c = - let constants = Raw_context.constants c in - constants.blocks_per_voting_period - -let hard_gas_limit_per_operation c = - let constants = Raw_context.constants c in - constants.hard_gas_limit_per_operation - -let hard_gas_limit_per_block c = - let constants = Raw_context.constants c in - constants.hard_gas_limit_per_block - -let cost_per_byte c = - let constants = Raw_context.constants c in - constants.cost_per_byte - -let hard_storage_limit_per_operation c = - let constants = Raw_context.constants c in - constants.hard_storage_limit_per_operation - -let proof_of_work_threshold c = - let constants = Raw_context.constants c in - constants.proof_of_work_threshold - -let tokens_per_roll c = - let constants = Raw_context.constants c in - constants.tokens_per_roll - -let seed_nonce_revelation_tip c = - let constants = Raw_context.constants c in - constants.seed_nonce_revelation_tip - -let origination_size c = - let constants = Raw_context.constants c in - constants.origination_size - -let baking_reward_fixed_portion c = - let constants = Raw_context.constants c in - constants.baking_reward_fixed_portion - -let baking_reward_bonus_per_slot c = - let constants = Raw_context.constants c in - constants.baking_reward_bonus_per_slot - -let endorsing_reward_per_slot c = - let constants = Raw_context.constants c in - constants.endorsing_reward_per_slot - -let quorum_min c = - let constants = Raw_context.constants c in - constants.quorum_min - -let quorum_max c = - let constants = Raw_context.constants c in - constants.quorum_max - -let min_proposal_quorum c = - let constants = Raw_context.constants c in - constants.min_proposal_quorum - -let liquidity_baking_subsidy c = - let constants = Raw_context.constants c in - constants.liquidity_baking_subsidy - -let liquidity_baking_sunset_level c = - let constants = Raw_context.constants c in - constants.liquidity_baking_sunset_level - -let liquidity_baking_escape_ema_threshold c = - let constants = Raw_context.constants c in - constants.liquidity_baking_escape_ema_threshold - -let parametric c = Raw_context.constants c - -let minimal_block_delay c = - let constants = Raw_context.constants c in - constants.minimal_block_delay - -let delay_increment_per_round c = - let constants = Raw_context.constants c in - constants.delay_increment_per_round - -let consensus_committee_size c = - let constants = Raw_context.constants c in - constants.consensus_committee_size - -let consensus_threshold c = - let constants = Raw_context.constants c in - constants.consensus_threshold - -let minimal_participation_ratio c = - let constants = Raw_context.constants c in - constants.minimal_participation_ratio - -let max_slashing_period c = - let constants = Raw_context.constants c in - constants.max_slashing_period - -let frozen_deposits_percentage c = - let constants = Raw_context.constants c in - constants.frozen_deposits_percentage - -let double_baking_punishment c = - let constants = Raw_context.constants c in - constants.double_baking_punishment - -let ratio_of_frozen_deposits_slashed_per_double_endorsement c = - let constants = Raw_context.constants c in - constants.ratio_of_frozen_deposits_slashed_per_double_endorsement diff --git a/src/proto_012_Psithaca/lib_protocol/constants_storage.mli b/src/proto_012_Psithaca/lib_protocol/constants_storage.mli deleted file mode 100644 index 0af74a51a528..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/constants_storage.mli +++ /dev/null @@ -1,91 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val preserved_cycles : Raw_context.t -> int - -val blocks_per_cycle : Raw_context.t -> int32 - -val blocks_per_commitment : Raw_context.t -> int32 - -val blocks_per_stake_snapshot : Raw_context.t -> int32 - -val blocks_per_voting_period : Raw_context.t -> int32 - -val hard_gas_limit_per_operation : - Raw_context.t -> Gas_limit_repr.Arith.integral - -val hard_gas_limit_per_block : Raw_context.t -> Gas_limit_repr.Arith.integral - -val cost_per_byte : Raw_context.t -> Tez_repr.t - -val hard_storage_limit_per_operation : Raw_context.t -> Z.t - -val proof_of_work_threshold : Raw_context.t -> int64 - -val tokens_per_roll : Raw_context.t -> Tez_repr.t - -val seed_nonce_revelation_tip : Raw_context.t -> Tez_repr.t - -val origination_size : Raw_context.t -> int - -val baking_reward_fixed_portion : Raw_context.t -> Tez_repr.t - -val baking_reward_bonus_per_slot : Raw_context.t -> Tez_repr.t - -val endorsing_reward_per_slot : Raw_context.t -> Tez_repr.t - -val quorum_min : Raw_context.t -> int32 - -val quorum_max : Raw_context.t -> int32 - -val min_proposal_quorum : Raw_context.t -> int32 - -val liquidity_baking_subsidy : Raw_context.t -> Tez_repr.t - -val liquidity_baking_sunset_level : Raw_context.t -> int32 - -val liquidity_baking_escape_ema_threshold : Raw_context.t -> int32 - -val parametric : Raw_context.t -> Constants_repr.parametric - -val consensus_committee_size : Raw_context.t -> int - -val consensus_threshold : Raw_context.t -> int - -val minimal_participation_ratio : Raw_context.t -> Constants_repr.ratio - -val max_slashing_period : Raw_context.t -> int - -val frozen_deposits_percentage : Raw_context.t -> int - -val double_baking_punishment : Raw_context.t -> Tez_repr.t - -val ratio_of_frozen_deposits_slashed_per_double_endorsement : - Raw_context.t -> Constants_repr.ratio - -val minimal_block_delay : Raw_context.t -> Period_repr.t - -val delay_increment_per_round : Raw_context.t -> Period_repr.t diff --git a/src/proto_012_Psithaca/lib_protocol/contract_delegate_storage.ml b/src/proto_012_Psithaca/lib_protocol/contract_delegate_storage.ml deleted file mode 100644 index ca295af19167..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_delegate_storage.ml +++ /dev/null @@ -1,83 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let find = Storage.Contract.Delegate.find - -let remove_contract_stake ctxt contract amount = - find ctxt contract >>=? function - | None -> return ctxt - | Some delegate -> Stake_storage.remove_stake ctxt delegate amount - -let add_contract_stake ctxt contract amount = - find ctxt contract >>=? function - | None -> return ctxt - | Some delegate -> Stake_storage.add_stake ctxt delegate amount - -(* A delegate is registered if its "implicit account" delegates to itself. *) -let registered c delegate = - Storage.Contract.Delegate.find c (Contract_repr.implicit_contract delegate) - >|=? function - | Some current_delegate -> - Signature.Public_key_hash.equal delegate current_delegate - | None -> false - -let link c contract delegate = - Storage.Contract.Balance.get c contract >>=? fun balance -> - Stake_storage.add_stake c delegate balance >>=? fun c -> - Storage.Contract.Delegated.add - (c, Contract_repr.implicit_contract delegate) - contract - >|= ok - -let unlink c contract = - Storage.Contract.Delegate.find c contract >>=? function - | None -> return c - | Some delegate -> - Storage.Contract.Balance.get c contract >>=? fun balance -> - (* Removes the balance of the contract from the delegate *) - Stake_storage.remove_stake c delegate balance >>=? fun c -> - Storage.Contract.Delegated.remove - (c, Contract_repr.implicit_contract delegate) - contract - >|= ok - -let init ctxt contract delegate = - Storage.Contract.Delegate.init ctxt contract delegate >>=? fun ctxt -> - link ctxt contract delegate - -let delete ctxt contract = - unlink ctxt contract >>=? fun ctxt -> - Storage.Contract.Delegate.remove ctxt contract >|= ok - -let remove ctxt contract = unlink ctxt contract - -let set ctxt contract delegate = - unlink ctxt contract >>=? fun ctxt -> - Storage.Contract.Delegate.add ctxt contract delegate >>= fun ctxt -> - link ctxt contract delegate - -let delegated_contracts ctxt delegate = - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Delegated.elements (ctxt, contract) diff --git a/src/proto_012_Psithaca/lib_protocol/contract_delegate_storage.mli b/src/proto_012_Psithaca/lib_protocol/contract_delegate_storage.mli deleted file mode 100644 index 1a62d96b6ade..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_delegate_storage.mli +++ /dev/null @@ -1,88 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** [find ctxt contract] returns the delegate associated to [contract], or [None] - if [contract] has no delegate]. *) -val find : - Raw_context.t -> - Contract_repr.t -> - Signature.Public_key_hash.t option tzresult Lwt.t - -(** [registered ctxt delegate] returns true iff delegate is an implicit contract - that delegates to itself. *) -val registered : - Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t - -(** [init ctxt contract delegate] sets the [delegate] associated to [contract]. - - This function is undefined if [contract] is not allocated, or if [contract] - has already a delegate. *) -val init : - Raw_context.t -> - Contract_repr.t -> - Signature.Public_key_hash.t -> - Raw_context.t tzresult Lwt.t - -(** [remove ctxt contract] removes contract from the list of contracts that - delegated to [find ctxt contract], i.e. the output of [delegated_contracts]. - This function does not affect the value of the expression - [find ctxt contract]. - - This function is undefined if [contract] is not allocated. *) -val remove : Raw_context.t -> Contract_repr.t -> Raw_context.t tzresult Lwt.t - -(** [delete ctxt contract] behaves as [remove ctxt contract], but in addition - removes the association of the [contract] to its current delegate, leaving - the former with no delegate. - - This function is undefined if [contract] is not allocated. *) -val delete : Raw_context.t -> Contract_repr.t -> Raw_context.t tzresult Lwt.t - -(** [set ctxt contract delegate] updates the [delegate] associated to [contract]. - - This function is undefined if [contract] is not allocated, or if [contract] - does not have a delegate. *) -val set : - Raw_context.t -> - Contract_repr.t -> - Signature.Public_key_hash.t -> - Raw_context.t tzresult Lwt.t - -(** [delegated_contracts ctxt delegate] returns the list of contracts (implicit - or originated) that delegated to [delegate]. *) -val delegated_contracts : - Raw_context.t -> Signature.Public_key_hash.t -> Contract_repr.t list Lwt.t - -(** [add_contract_stake ctxt contract amount] calls - [Stake_storage.add_stake ctxt delegate amount] if [contract] has a - [delegate]. Otherwise this function does nothing. *) -val add_contract_stake : - Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t - -(** [remove_contract_stake ctxt contract amount] calls - [Stake_storage.remove_stake ctxt delegate amount] if [contract] has a - [delegate]. Otherwise this function does nothing. *) -val remove_contract_stake : - Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/contract_hash.ml b/src/proto_012_Psithaca/lib_protocol/contract_hash.ml deleted file mode 100644 index c232a80278df..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_hash.ml +++ /dev/null @@ -1,45 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* 20 *) -let contract_hash = "\002\090\121" (* KT1(36) *) - -module H = - Blake2B.Make - (Base58) - (struct - let name = "Contract_hash" - - let title = "A contract ID" - - let b58check_prefix = contract_hash - - let size = Some 20 - end) - -include H -include Path_encoding.Make_hex (H) - -let () = Base58.check_encoded_prefix b58check_encoding "KT1" 36 diff --git a/src/proto_012_Psithaca/lib_protocol/contract_hash.mli b/src/proto_012_Psithaca/lib_protocol/contract_hash.mli deleted file mode 100644 index 1cbc424150af..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_hash.mli +++ /dev/null @@ -1,29 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** A specialized Blake2B implementation for hashing contract identifiers. *) - -include S.HASH diff --git a/src/proto_012_Psithaca/lib_protocol/contract_manager_storage.ml b/src/proto_012_Psithaca/lib_protocol/contract_manager_storage.ml deleted file mode 100644 index 43464734c5aa..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_manager_storage.ml +++ /dev/null @@ -1,130 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | (* `Branch *) Unrevealed_manager_key of Contract_repr.t - | (* `Permanent *) - Inconsistent_hash of { - public_key : Signature.Public_key.t; - expected_hash : Signature.Public_key_hash.t; - provided_hash : Signature.Public_key_hash.t; - } - | (* `Branch *) Previously_revealed_key of Contract_repr.t - -let () = - register_error_kind - `Branch - ~id:"contract.unrevealed_key" - ~title:"Manager operation precedes key revelation" - ~description: - "One tried to apply a manager operation without revealing the manager \ - public key" - ~pp:(fun ppf s -> - Format.fprintf - ppf - "Unrevealed manager key for contract %a." - Contract_repr.pp - s) - Data_encoding.(obj1 (req "contract" Contract_repr.encoding)) - (function Unrevealed_manager_key s -> Some s | _ -> None) - (fun s -> Unrevealed_manager_key s) ; - register_error_kind - `Permanent - ~id:"contract.manager.inconsistent_hash" - ~title:"Inconsistent public key hash" - ~description: - "A revealed manager public key is inconsistent with the announced hash" - ~pp:(fun ppf (k, eh, ph) -> - Format.fprintf - ppf - "The hash of the manager public key %s is not %a as announced but %a" - (Signature.Public_key.to_b58check k) - Signature.Public_key_hash.pp - ph - Signature.Public_key_hash.pp - eh) - Data_encoding.( - obj3 - (req "public_key" Signature.Public_key.encoding) - (req "expected_hash" Signature.Public_key_hash.encoding) - (req "provided_hash" Signature.Public_key_hash.encoding)) - (function - | Inconsistent_hash {public_key; expected_hash; provided_hash} -> - Some (public_key, expected_hash, provided_hash) - | _ -> None) - (fun (public_key, expected_hash, provided_hash) -> - Inconsistent_hash {public_key; expected_hash; provided_hash}) ; - register_error_kind - `Branch - ~id:"contract.previously_revealed_key" - ~title:"Manager operation already revealed" - ~description:"One tried to reveal twice a manager public key" - ~pp:(fun ppf s -> - Format.fprintf - ppf - "Previously revealed manager key for contract %a." - Contract_repr.pp - s) - Data_encoding.(obj1 (req "contract" Contract_repr.encoding)) - (function Previously_revealed_key s -> Some s | _ -> None) - (fun s -> Previously_revealed_key s) - -let init = Storage.Contract.Manager.init - -let is_manager_key_revealed c manager = - let contract = Contract_repr.implicit_contract manager in - Storage.Contract.Manager.find c contract >>=? function - | None -> return_false - | Some (Manager_repr.Hash _) -> return_false - | Some (Manager_repr.Public_key _) -> return_true - -let reveal_manager_key c manager public_key = - let contract = Contract_repr.implicit_contract manager in - Storage.Contract.Manager.get c contract >>=? function - | Public_key _ -> fail (Previously_revealed_key contract) - | Hash v -> - let actual_hash = Signature.Public_key.hash public_key in - if Signature.Public_key_hash.equal actual_hash v then - let v = Manager_repr.Public_key public_key in - Storage.Contract.Manager.update c contract v - else - fail - (Inconsistent_hash - {public_key; expected_hash = v; provided_hash = actual_hash}) - -let get_manager_key ?error ctxt pkh = - let contract = Contract_repr.implicit_contract pkh in - Storage.Contract.Manager.find ctxt contract >>=? function - | None -> ( - match error with - | None -> failwith "get_manager_key" - | Some error -> fail error) - | Some (Manager_repr.Hash _) -> ( - match error with - | None -> fail (Unrevealed_manager_key contract) - | Some error -> fail error) - | Some (Manager_repr.Public_key pk) -> return pk - -let remove_existing = Storage.Contract.Manager.remove_existing diff --git a/src/proto_012_Psithaca/lib_protocol/contract_manager_storage.mli b/src/proto_012_Psithaca/lib_protocol/contract_manager_storage.mli deleted file mode 100644 index 8982e89a7699..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_manager_storage.mli +++ /dev/null @@ -1,67 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | (* `Branch *) Unrevealed_manager_key of Contract_repr.t - | (* `Permanent *) - Inconsistent_hash of { - public_key : Signature.Public_key.t; - expected_hash : Signature.Public_key_hash.t; - provided_hash : Signature.Public_key_hash.t; - } - | (* `Branch *) Previously_revealed_key of Contract_repr.t - -(** [init ctxt contract manager] associates [manager] to [contract]. This - function is undefined if [contract] has already a manager associated to it. -*) -val init : - Raw_context.t -> - Contract_repr.t -> - Manager_repr.manager_key -> - Raw_context.t tzresult Lwt.t - -val is_manager_key_revealed : - Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t - -val reveal_manager_key : - Raw_context.t -> - Signature.Public_key_hash.t -> - Signature.Public_key.t -> - Raw_context.t tzresult Lwt.t - -(** [get_manager_key ?error ctxt pkh] returns the revealed manager key of the - contract represented by [pkh]. When [error] is not provided this function - fails with "get_manager_key" error if [pkh] does not have a manager, and - with [Unrevealed_manager_key] error if the manager has not revealed its key. - When [error] is provided, the function fails with the provided [error] in - both cases. *) -val get_manager_key : - ?error:error -> - Raw_context.t -> - Signature.Public_key_hash.t -> - Signature.Public_key.t tzresult Lwt.t - -val remove_existing : - Raw_context.t -> Contract_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/contract_repr.ml b/src/proto_012_Psithaca/lib_protocol/contract_repr.ml deleted file mode 100644 index 84c4251b5c6a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_repr.ml +++ /dev/null @@ -1,214 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = - | Implicit of Signature.Public_key_hash.t - | Originated of Contract_hash.t - -include Compare.Make (struct - type nonrec t = t - - let compare l1 l2 = - match (l1, l2) with - | (Implicit pkh1, Implicit pkh2) -> - Signature.Public_key_hash.compare pkh1 pkh2 - | (Originated h1, Originated h2) -> Contract_hash.compare h1 h2 - | (Implicit _, Originated _) -> -1 - | (Originated _, Implicit _) -> 1 -end) - -type contract = t - -let blake2b_hash_size = - let open Cache_memory_helpers in - header_size +! word_size +! string_size_gen 20 - -let public_key_hash_in_memory_size = - let open Cache_memory_helpers in - header_size +! word_size +! blake2b_hash_size - -let in_memory_size = - let open Cache_memory_helpers in - function - | Implicit _ -> header_size +! word_size +! public_key_hash_in_memory_size - | Originated _ -> header_size +! word_size +! blake2b_hash_size - -type error += Invalid_contract_notation of string (* `Permanent *) - -let to_b58check = function - | Implicit pbk -> Signature.Public_key_hash.to_b58check pbk - | Originated h -> Contract_hash.to_b58check h - -let of_b58check s = - match Base58.decode s with - | Some data -> ( - match data with - | Ed25519.Public_key_hash.Data h -> ok (Implicit (Signature.Ed25519 h)) - | Secp256k1.Public_key_hash.Data h -> - ok (Implicit (Signature.Secp256k1 h)) - | P256.Public_key_hash.Data h -> ok (Implicit (Signature.P256 h)) - | Contract_hash.Data h -> ok (Originated h) - | _ -> error (Invalid_contract_notation s)) - | None -> error (Invalid_contract_notation s) - -let pp ppf = function - | Implicit pbk -> Signature.Public_key_hash.pp ppf pbk - | Originated h -> Contract_hash.pp ppf h - -let pp_short ppf = function - | Implicit pbk -> Signature.Public_key_hash.pp_short ppf pbk - | Originated h -> Contract_hash.pp_short ppf h - -let encoding = - let open Data_encoding in - def - "contract_id" - ~title:"A contract handle" - ~description: - "A contract notation as given to an RPC or inside scripts. Can be a \ - base58 implicit contract hash or a base58 originated contract hash." - @@ splitted - ~binary: - (union - ~tag_size:`Uint8 - [ - case - (Tag 0) - ~title:"Implicit" - Signature.Public_key_hash.encoding - (function Implicit k -> Some k | _ -> None) - (fun k -> Implicit k); - case - (Tag 1) - (Fixed.add_padding Contract_hash.encoding 1) - ~title:"Originated" - (function Originated k -> Some k | _ -> None) - (fun k -> Originated k); - ]) - ~json: - (conv - to_b58check - (fun s -> - match of_b58check s with - | Ok s -> s - | Error _ -> Json.cannot_destruct "Invalid contract notation.") - string) - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"contract.invalid_contract_notation" - ~title:"Invalid contract notation" - ~pp:(fun ppf x -> Format.fprintf ppf "Invalid contract notation %S" x) - ~description: - "A malformed contract notation was given to an RPC or in a script." - (obj1 (req "notation" string)) - (function Invalid_contract_notation loc -> Some loc | _ -> None) - (fun loc -> Invalid_contract_notation loc) - -let implicit_contract id = Implicit id - -let is_implicit = function Implicit m -> Some m | Originated _ -> None - -let is_originated = function Implicit _ -> None | Originated h -> Some h - -type origination_nonce = { - operation_hash : Operation_hash.t; - origination_index : int32; -} - -let origination_nonce_encoding = - let open Data_encoding in - conv - (fun {operation_hash; origination_index} -> - (operation_hash, origination_index)) - (fun (operation_hash, origination_index) -> - {operation_hash; origination_index}) - @@ obj2 (req "operation" Operation_hash.encoding) (dft "index" int32 0l) - -let originated_contract nonce = - let data = - Data_encoding.Binary.to_bytes_exn origination_nonce_encoding nonce - in - Originated (Contract_hash.hash_bytes [data]) - -let originated_contracts - ~since:{origination_index = first; operation_hash = first_hash} - ~until: - ({origination_index = last; operation_hash = last_hash} as - origination_nonce) = - assert (Operation_hash.equal first_hash last_hash) ; - let[@coq_struct "origination_index"] rec contracts acc origination_index = - if Compare.Int32.(origination_index < first) then acc - else - let origination_nonce = {origination_nonce with origination_index} in - let acc = originated_contract origination_nonce :: acc in - contracts acc (Int32.pred origination_index) - in - contracts [] (Int32.pred last) - -let initial_origination_nonce operation_hash = - {operation_hash; origination_index = 0l} - -let incr_origination_nonce nonce = - let origination_index = Int32.succ nonce.origination_index in - {nonce with origination_index} - -let rpc_arg = - let construct = to_b58check in - let destruct hash = - Result.map_error (fun _ -> "Cannot parse contract id") (of_b58check hash) - in - RPC_arg.make - ~descr:"A contract identifier encoded in b58check." - ~name:"contract_id" - ~construct - ~destruct - () - -module Index = struct - type t = contract - - let path_length = 1 - - let to_path c l = - let raw_key = Data_encoding.Binary.to_bytes_exn encoding c in - let (`Hex key) = Hex.of_bytes raw_key in - key :: l - - let of_path = function - | [key] -> - Option.bind - (Hex.to_bytes (`Hex key)) - (Data_encoding.Binary.of_bytes_opt encoding) - | _ -> None - - let rpc_arg = rpc_arg - - let encoding = encoding - - let compare = compare -end diff --git a/src/proto_012_Psithaca/lib_protocol/contract_repr.mli b/src/proto_012_Psithaca/lib_protocol/contract_repr.mli deleted file mode 100644 index 803275062627..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_repr.mli +++ /dev/null @@ -1,99 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module defines identifiers for two basic types of contracts. It also - specifies how to compute originated contract's hash from origination - nonce. *) - -(** A contract is simply an account on the blockchain ledger. There are two - types of contracts: - - implicit contracts represent accounts of users of the blockchain; - - originated are special accounts with a Michelson script attached to - them. Every time a transaction is sent to an originated account, its - associated script is run in order to trigger some action in response. - - An implicit account is identified by the hash of the public key which was - used to create it. The owner of the corresponding private key is the - holder of the account. An originated contract's hash is derived from its - origination nonce (see below). *) -type t = private - | Implicit of Signature.Public_key_hash.t - | Originated of Contract_hash.t - -type contract = t - -include Compare.S with type t := contract - -val public_key_hash_in_memory_size : Cache_memory_helpers.sint - -val in_memory_size : t -> Cache_memory_helpers.sint - -(** {2 Implicit contracts} *) - -val implicit_contract : Signature.Public_key_hash.t -> contract - -val is_implicit : contract -> Signature.Public_key_hash.t option - -(** {2 Originated contracts} *) - -(** Originated contracts handles are crafted from the hash of the - operation that triggered their origination (and nothing else). - As a single operation can trigger several originations, the - corresponding handles are forged from a deterministic sequence of - nonces, initialized with the hash of the operation. *) -type origination_nonce - -val originated_contract : origination_nonce -> contract - -val originated_contracts : - since:origination_nonce -> until:origination_nonce -> contract list - -val initial_origination_nonce : Operation_hash.t -> origination_nonce - -val incr_origination_nonce : origination_nonce -> origination_nonce - -val is_originated : contract -> Contract_hash.t option - -(** {2 Human readable notation} *) - -type error += Invalid_contract_notation of string (* `Permanent *) - -val to_b58check : contract -> string - -val of_b58check : string -> contract tzresult - -val pp : Format.formatter -> contract -> unit - -val pp_short : Format.formatter -> contract -> unit - -(** {2 Serializers} *) - -val encoding : contract Data_encoding.t - -val origination_nonce_encoding : origination_nonce Data_encoding.t - -val rpc_arg : contract RPC_arg.arg - -module Index : Storage_description.INDEX with type t = t diff --git a/src/proto_012_Psithaca/lib_protocol/contract_services.ml b/src/proto_012_Psithaca/lib_protocol/contract_services.ml deleted file mode 100644 index 799d8c5ae62b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_services.ml +++ /dev/null @@ -1,527 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -let custom_root = - (RPC_path.(open_root / "context" / "contracts") - : RPC_context.t RPC_path.context) - -let big_map_root = - (RPC_path.(open_root / "context" / "big_maps") - : RPC_context.t RPC_path.context) - -type info = { - balance : Tez.t; - delegate : public_key_hash option; - counter : counter option; - script : Script.t option; -} - -let info_encoding = - let open Data_encoding in - conv - (fun {balance; delegate; script; counter} -> - (balance, delegate, script, counter)) - (fun (balance, delegate, script, counter) -> - {balance; delegate; script; counter}) - @@ obj4 - (req "balance" Tez.encoding) - (opt "delegate" Signature.Public_key_hash.encoding) - (opt "script" Script.encoding) - (opt "counter" n) - -module S = struct - open Data_encoding - - let balance = - RPC_service.get_service - ~description:"Access the balance of a contract." - ~query:RPC_query.empty - ~output:Tez.encoding - RPC_path.(custom_root /: Contract.rpc_arg / "balance") - - let manager_key = - RPC_service.get_service - ~description:"Access the manager of a contract." - ~query:RPC_query.empty - ~output:(option Signature.Public_key.encoding) - RPC_path.(custom_root /: Contract.rpc_arg / "manager_key") - - let delegate = - RPC_service.get_service - ~description:"Access the delegate of a contract, if any." - ~query:RPC_query.empty - ~output:Signature.Public_key_hash.encoding - RPC_path.(custom_root /: Contract.rpc_arg / "delegate") - - let counter = - RPC_service.get_service - ~description:"Access the counter of a contract, if any." - ~query:RPC_query.empty - ~output:z - RPC_path.(custom_root /: Contract.rpc_arg / "counter") - - let script = - RPC_service.get_service - ~description:"Access the code and data of the contract." - ~query:RPC_query.empty - ~output:Script.encoding - RPC_path.(custom_root /: Contract.rpc_arg / "script") - - let storage = - RPC_service.get_service - ~description:"Access the data of the contract." - ~query:RPC_query.empty - ~output:Script.expr_encoding - RPC_path.(custom_root /: Contract.rpc_arg / "storage") - - let entrypoint_type = - RPC_service.get_service - ~description:"Return the type of the given entrypoint of the contract" - ~query:RPC_query.empty - ~output:Script.expr_encoding - RPC_path.( - custom_root /: Contract.rpc_arg / "entrypoints" /: RPC_arg.string) - - let list_entrypoints = - RPC_service.get_service - ~description:"Return the list of entrypoints of the contract" - ~query:RPC_query.empty - ~output: - (obj2 - (dft - "unreachable" - (Data_encoding.list - (obj1 - (req - "path" - (Data_encoding.list - Michelson_v1_primitives.prim_encoding)))) - []) - (req "entrypoints" (assoc Script.expr_encoding))) - RPC_path.(custom_root /: Contract.rpc_arg / "entrypoints") - - let contract_big_map_get_opt = - RPC_service.post_service - ~description: - "Access the value associated with a key in a big map of the contract \ - (deprecated)." - ~query:RPC_query.empty - ~input: - (obj2 - (req "key" Script.expr_encoding) - (req "type" Script.expr_encoding)) - ~output:(option Script.expr_encoding) - RPC_path.(custom_root /: Contract.rpc_arg / "big_map_get") - - let big_map_get = - RPC_service.get_service - ~description:"Access the value associated with a key in a big map." - ~query:RPC_query.empty - ~output:Script.expr_encoding - RPC_path.(big_map_root /: Big_map.Id.rpc_arg /: Script_expr_hash.rpc_arg) - - type big_map_get_all_query = {offset : int option; length : int option} - - let rpc_arg_uint : int RPC_arg.t = - let int_of_string s = - int_of_string_opt s - |> Option.to_result - ~none:(Format.sprintf "Cannot parse integer value %s" s) - >>? fun i -> - if Compare.Int.(i < 0) then - Error (Format.sprintf "Negative integer: %d" i) - else Ok i - in - RPC_arg.make - ~name:"uint" - ~descr:"A non-negative integer (greater than or equal to 0)." - ~destruct:int_of_string - ~construct:string_of_int - () - - let big_map_get_all_query : big_map_get_all_query RPC_query.t = - let open RPC_query in - query (fun offset length -> {offset; length}) - |+ opt_field - ~descr: - "Skip the first [offset] values. Useful in combination with \ - [length] for pagination." - "offset" - rpc_arg_uint - (fun t -> t.offset) - |+ opt_field - ~descr: - "Only retrieve [length] values. Useful in combination with [offset] \ - for pagination." - "length" - rpc_arg_uint - (fun t -> t.length) - |> seal - - let big_map_get_all = - RPC_service.get_service - ~description: - "Get the (optionally paginated) list of values in a big map. Order of \ - values is unspecified, but is guaranteed to be consistent." - ~query:big_map_get_all_query - ~output:(list Script.expr_encoding) - RPC_path.(big_map_root /: Big_map.Id.rpc_arg) - - let info = - RPC_service.get_service - ~description:"Access the complete status of a contract." - ~query:RPC_query.empty - ~output:info_encoding - RPC_path.(custom_root /: Contract.rpc_arg) - - let list = - RPC_service.get_service - ~description: - "All existing contracts (including non-empty default contracts)." - ~query:RPC_query.empty - ~output:(list Contract.encoding) - custom_root - - module Sapling = struct - (* - Sapling: these RPCs are like Sapling RPCs (sapling_services.ml) - specialized for contracts containing a single sapling state. - *) - - let single_sapling_get_id ctxt contract_id = - Contract.get_script ctxt contract_id >>=? fun (ctxt, script) -> - match script with - | None -> return (None, ctxt) - | Some script -> - let ctxt = Gas.set_unlimited ctxt in - Script_ir_translator.parse_script - ctxt - ~legacy:true - ~allow_forged_in_storage:true - script - >|= fun tzresult -> - tzresult >>? fun (Ex_script script, ctxt) -> - Script_ir_translator.get_single_sapling_state - ctxt - script.storage_type - script.storage - - let make_service - Sapling_services.S.Args.{name; description; query; output; f} = - let name = "single_sapling_" ^ name in - let path = RPC_path.(custom_root /: Contract.rpc_arg / name) in - let service = RPC_service.get_service ~description ~query ~output path in - ( service, - fun ctxt contract_id q () -> - single_sapling_get_id ctxt contract_id >>=? fun (sapling_id, ctxt) -> - Option.map_es (fun sapling_id -> f ctxt sapling_id q) sapling_id ) - - let get_diff = make_service Sapling_services.S.Args.get_diff - - let register () = - let reg chunked (service, f) = - Services_registration.opt_register1 ~chunked service f - in - reg false get_diff - - let mk_call1 (service, _f) ctxt block id q = - RPC_context.make_call1 service ctxt block id q () - end -end - -let[@coq_axiom_with_reason "gadt"] register () = - let open Services_registration in - register0 ~chunked:true S.list (fun ctxt () () -> Contract.list ctxt >|= ok) ; - let register_field ~chunked s f = - opt_register1 ~chunked s (fun ctxt contract () () -> - Contract.exists ctxt contract >>=? function - | true -> f ctxt contract >|=? Option.some - | false -> return_none) - in - let register_opt_field ~chunked s f = - opt_register1 ~chunked s (fun ctxt contract () () -> - Contract.exists ctxt contract >>=? function - | true -> f ctxt contract - | false -> return_none) - in - let do_big_map_get ctxt id key = - let open Script_ir_translator in - let ctxt = Gas.set_unlimited ctxt in - Big_map.exists ctxt id >>=? fun (ctxt, types) -> - match types with - | None -> return_none - | Some (_, value_type) -> ( - parse_big_map_value_ty ctxt ~legacy:true (Micheline.root value_type) - >>?= fun (Ex_ty value_type, ctxt) -> - Big_map.get_opt ctxt id key >>=? fun (_ctxt, value) -> - match value with - | None -> return_none - | Some value -> - parse_data - ctxt - ~legacy:true - ~allow_forged:true - value_type - (Micheline.root value) - >>=? fun (value, ctxt) -> - unparse_data ctxt Readable value_type value - >|=? fun (value, _ctxt) -> Some (Micheline.strip_locations value)) - in - let do_big_map_get_all ?offset ?length ctxt id = - let open Script_ir_translator in - let ctxt = Gas.set_unlimited ctxt in - Big_map.exists ctxt id >>=? fun (ctxt, types) -> - match types with - | None -> raise Not_found - | Some (_, value_type) -> - parse_big_map_value_ty ctxt ~legacy:true (Micheline.root value_type) - >>?= fun (Ex_ty value_type, ctxt) -> - Big_map.list_values ?offset ?length ctxt id >>=? fun (ctxt, values) -> - List.fold_left_s - (fun acc value -> - acc >>?= fun (ctxt, rev_values) -> - parse_data - ctxt - ~legacy:true - ~allow_forged:true - value_type - (Micheline.root value) - >>=? fun (value, ctxt) -> - unparse_data ctxt Readable value_type value - >|=? fun (value, ctxt) -> - (ctxt, Micheline.strip_locations value :: rev_values)) - (Ok (ctxt, [])) - values - >|=? fun (_ctxt, rev_values) -> List.rev rev_values - in - register_field ~chunked:false S.balance Contract.get_balance ; - opt_register1 ~chunked:false S.manager_key (fun ctxt contract () () -> - match Contract.is_implicit contract with - | None -> return_none - | Some mgr -> ( - Contract.is_manager_key_revealed ctxt mgr >>=? function - | false -> return_some None - | true -> - Contract.get_manager_key ctxt mgr >|=? fun key -> Some (Some key))) ; - register_opt_field ~chunked:false S.delegate Delegate.find ; - opt_register1 ~chunked:false S.counter (fun ctxt contract () () -> - match Contract.is_implicit contract with - | None -> return_none - | Some mgr -> - Contract.get_counter ctxt mgr >|=? fun counter -> Some counter) ; - register_opt_field ~chunked:true S.script (fun c v -> - Contract.get_script c v >|=? fun (_, v) -> v) ; - register_opt_field ~chunked:true S.storage (fun ctxt contract -> - Contract.get_script ctxt contract >>=? fun (ctxt, script) -> - match script with - | None -> return_none - | Some script -> - let ctxt = Gas.set_unlimited ctxt in - let open Script_ir_translator in - parse_script ctxt ~legacy:true ~allow_forged_in_storage:true script - >>=? fun (Ex_script script, ctxt) -> - unparse_script ctxt Readable script >>=? fun (script, ctxt) -> - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - script.storage - >>?= fun (storage, _ctxt) -> return_some storage) ; - opt_register2 ~chunked:true S.entrypoint_type (fun ctxt v entrypoint () () -> - Contract.get_script_code ctxt v >>=? fun (_, expr) -> - match expr with - | None -> return_none - | Some expr -> - let ctxt = Gas.set_unlimited ctxt in - let legacy = true in - let open Script_ir_translator in - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - expr - >>?= fun (expr, _) -> - parse_toplevel ctxt ~legacy expr - >>=? fun ({arg_type; root_name; _}, ctxt) -> - Lwt.return - (( parse_parameter_ty ctxt ~legacy arg_type - >>? fun (Ex_ty arg_type, _) -> - Script_ir_translator.find_entrypoint - ~root_name - arg_type - entrypoint ) - |> function - | Ok (_f, Ex_ty ty) -> - unparse_ty ~loc:() ctxt ty >|? fun (ty_node, _) -> - Some (Micheline.strip_locations ty_node) - | Error _ -> Result.return_none)) ; - opt_register1 ~chunked:true S.list_entrypoints (fun ctxt v () () -> - Contract.get_script_code ctxt v >>=? fun (_, expr) -> - match expr with - | None -> return_none - | Some expr -> - let ctxt = Gas.set_unlimited ctxt in - let legacy = true in - let open Script_ir_translator in - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - expr - >>?= fun (expr, _) -> - parse_toplevel ctxt ~legacy expr - >>=? fun ({arg_type; root_name; _}, ctxt) -> - Lwt.return - ( ( parse_parameter_ty ctxt ~legacy arg_type - >>? fun (Ex_ty arg_type, _) -> - Script_ir_translator.list_entrypoints ~root_name arg_type ctxt - ) - >|? fun (unreachable_entrypoint, map) -> - Some - ( unreachable_entrypoint, - Entrypoints_map.fold - (fun entry (_, ty) acc -> - (entry, Micheline.strip_locations ty) :: acc) - map - [] ) )) ; - opt_register1 - ~chunked:true - S.contract_big_map_get_opt - (fun ctxt contract () (key, key_type) -> - Contract.get_script ctxt contract >>=? fun (ctxt, script) -> - let key_type_node = Micheline.root key_type in - Script_ir_translator.parse_comparable_ty ctxt key_type_node - >>?= fun (Ex_comparable_ty key_type, ctxt) -> - Script_ir_translator.parse_comparable_data - ctxt - key_type - (Micheline.root key) - >>=? fun (key, ctxt) -> - Script_ir_translator.hash_comparable_data ctxt key_type key - >>=? fun (key, ctxt) -> - match script with - | None -> return_none - | Some script -> ( - let ctxt = Gas.set_unlimited ctxt in - let open Script_ir_translator in - parse_script ctxt ~legacy:true ~allow_forged_in_storage:true script - >>=? fun (Ex_script script, ctxt) -> - Script_ir_translator.collect_lazy_storage - ctxt - script.storage_type - script.storage - >>?= fun (ids, _ctxt) -> - match Script_ir_translator.list_of_big_map_ids ids with - | [] | _ :: _ :: _ -> return_some None - | [id] -> do_big_map_get ctxt id key >|=? Option.some)) ; - opt_register2 ~chunked:true S.big_map_get (fun ctxt id key () () -> - do_big_map_get ctxt id key) ; - register1 ~chunked:true S.big_map_get_all (fun ctxt id {offset; length} () -> - do_big_map_get_all ?offset ?length ctxt id) ; - register_field ~chunked:false S.info (fun ctxt contract -> - Contract.get_balance ctxt contract >>=? fun balance -> - Delegate.find ctxt contract >>=? fun delegate -> - (match Contract.is_implicit contract with - | Some manager -> - Contract.get_counter ctxt manager >>=? fun counter -> - return_some counter - | None -> return_none) - >>=? fun counter -> - Contract.get_script ctxt contract >>=? fun (ctxt, script) -> - (match script with - | None -> return (None, ctxt) - | Some script -> - let ctxt = Gas.set_unlimited ctxt in - let open Script_ir_translator in - parse_script ctxt ~legacy:true ~allow_forged_in_storage:true script - >>=? fun (Ex_script script, ctxt) -> - unparse_script ctxt Readable script >|=? fun (script, ctxt) -> - (Some script, ctxt)) - >|=? fun (script, _ctxt) -> {balance; delegate; script; counter}) ; - S.Sapling.register () - -let list ctxt block = RPC_context.make_call0 S.list ctxt block () () - -let info ctxt block contract = - RPC_context.make_call1 S.info ctxt block contract () () - -let balance ctxt block contract = - RPC_context.make_call1 S.balance ctxt block contract () () - -let manager_key ctxt block mgr = - RPC_context.make_call1 - S.manager_key - ctxt - block - (Contract.implicit_contract mgr) - () - () - -let delegate ctxt block contract = - RPC_context.make_call1 S.delegate ctxt block contract () () - -let delegate_opt ctxt block contract = - RPC_context.make_opt_call1 S.delegate ctxt block contract () () - -let counter ctxt block mgr = - RPC_context.make_call1 - S.counter - ctxt - block - (Contract.implicit_contract mgr) - () - () - -let script ctxt block contract = - RPC_context.make_call1 S.script ctxt block contract () () - -let script_opt ctxt block contract = - RPC_context.make_opt_call1 S.script ctxt block contract () () - -let storage ctxt block contract = - RPC_context.make_call1 S.storage ctxt block contract () () - -let entrypoint_type ctxt block contract entrypoint = - RPC_context.make_call2 S.entrypoint_type ctxt block contract entrypoint () () - -let list_entrypoints ctxt block contract = - RPC_context.make_call1 S.list_entrypoints ctxt block contract () () - -let storage_opt ctxt block contract = - RPC_context.make_opt_call1 S.storage ctxt block contract () () - -let big_map_get ctxt block id key = - RPC_context.make_call2 S.big_map_get ctxt block id key () () - -let contract_big_map_get_opt ctxt block contract key = - RPC_context.make_call1 S.contract_big_map_get_opt ctxt block contract () key - -let single_sapling_get_diff ctxt block id ?offset_commitment ?offset_nullifier - () = - S.Sapling.(mk_call1 get_diff) - ctxt - block - id - Sapling_services.{offset_commitment; offset_nullifier} diff --git a/src/proto_012_Psithaca/lib_protocol/contract_services.mli b/src/proto_012_Psithaca/lib_protocol/contract_services.mli deleted file mode 100644 index 458dfbe4d617..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_services.mli +++ /dev/null @@ -1,126 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -val list : 'a #RPC_context.simple -> 'a -> Contract.t list shell_tzresult Lwt.t - -type info = { - balance : Tez.t; - delegate : public_key_hash option; - counter : counter option; - script : Script.t option; -} - -val info_encoding : info Data_encoding.t - -val info : - 'a #RPC_context.simple -> 'a -> Contract.t -> info shell_tzresult Lwt.t - -val balance : - 'a #RPC_context.simple -> 'a -> Contract.t -> Tez.t shell_tzresult Lwt.t - -val manager_key : - 'a #RPC_context.simple -> - 'a -> - public_key_hash -> - public_key option shell_tzresult Lwt.t - -val delegate : - 'a #RPC_context.simple -> - 'a -> - Contract.t -> - public_key_hash shell_tzresult Lwt.t - -val delegate_opt : - 'a #RPC_context.simple -> - 'a -> - Contract.t -> - public_key_hash option shell_tzresult Lwt.t - -val counter : - 'a #RPC_context.simple -> - 'a -> - public_key_hash -> - counter shell_tzresult Lwt.t - -val script : - 'a #RPC_context.simple -> 'a -> Contract.t -> Script.t shell_tzresult Lwt.t - -val script_opt : - 'a #RPC_context.simple -> - 'a -> - Contract.t -> - Script.t option shell_tzresult Lwt.t - -val storage : - 'a #RPC_context.simple -> 'a -> Contract.t -> Script.expr shell_tzresult Lwt.t - -val entrypoint_type : - 'a #RPC_context.simple -> - 'a -> - Contract.t -> - string -> - Script.expr shell_tzresult Lwt.t - -val list_entrypoints : - 'a #RPC_context.simple -> - 'a -> - Contract.t -> - (Michelson_v1_primitives.prim list list * (string * Script.expr) list) - shell_tzresult - Lwt.t - -val storage_opt : - 'a #RPC_context.simple -> - 'a -> - Contract.t -> - Script.expr option shell_tzresult Lwt.t - -val big_map_get : - 'a #RPC_context.simple -> - 'a -> - Big_map.Id.t -> - Script_expr_hash.t -> - Script.expr shell_tzresult Lwt.t - -val contract_big_map_get_opt : - 'a #RPC_context.simple -> - 'a -> - Contract.t -> - Script.expr * Script.expr -> - Script.expr option shell_tzresult Lwt.t - -val single_sapling_get_diff : - 'a #RPC_context.simple -> - 'a -> - Contract.t -> - ?offset_commitment:int64 -> - ?offset_nullifier:int64 -> - unit -> - (Sapling.root * Sapling.diff) shell_tzresult Lwt.t - -val register : unit -> unit diff --git a/src/proto_012_Psithaca/lib_protocol/contract_storage.ml b/src/proto_012_Psithaca/lib_protocol/contract_storage.ml deleted file mode 100644 index 5bce09cebc50..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_storage.ml +++ /dev/null @@ -1,629 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | (* `Temporary *) - Balance_too_low of - Contract_repr.contract * Tez_repr.t * Tez_repr.t - | (* `Temporary *) - Counter_in_the_past of Contract_repr.contract * Z.t * Z.t - | (* `Branch *) - Counter_in_the_future of Contract_repr.contract * Z.t * Z.t - | (* `Temporary *) - Non_existing_contract of Contract_repr.contract - | (* `Branch *) - Empty_implicit_contract of Signature.Public_key_hash.t - | (* `Branch *) - Empty_implicit_delegated_contract of - Signature.Public_key_hash.t - | (* `Permanent *) - Inconsistent_public_key of - Signature.Public_key.t * Signature.Public_key.t - | (* `Permanent *) Failure of string - -let () = - register_error_kind - `Temporary - ~id:"contract.balance_too_low" - ~title:"Balance too low" - ~description:"An operation tried to spend more tokens than the contract has" - ~pp:(fun ppf (c, b, a) -> - Format.fprintf - ppf - "Balance of contract %a too low (%a) to spend %a" - Contract_repr.pp - c - Tez_repr.pp - b - Tez_repr.pp - a) - Data_encoding.( - obj3 - (req "contract" Contract_repr.encoding) - (req "balance" Tez_repr.encoding) - (req "amount" Tez_repr.encoding)) - (function Balance_too_low (c, b, a) -> Some (c, b, a) | _ -> None) - (fun (c, b, a) -> Balance_too_low (c, b, a)) ; - register_error_kind - `Temporary - ~id:"contract.counter_in_the_future" - ~title:"Invalid counter (not yet reached) in a manager operation" - ~description:"An operation assumed a contract counter in the future" - ~pp:(fun ppf (contract, exp, found) -> - Format.fprintf - ppf - "Counter %a not yet reached for contract %a (expected %a)" - Z.pp_print - found - Contract_repr.pp - contract - Z.pp_print - exp) - Data_encoding.( - obj3 - (req "contract" Contract_repr.encoding) - (req "expected" z) - (req "found" z)) - (function Counter_in_the_future (c, x, y) -> Some (c, x, y) | _ -> None) - (fun (c, x, y) -> Counter_in_the_future (c, x, y)) ; - register_error_kind - `Branch - ~id:"contract.counter_in_the_past" - ~title:"Invalid counter (already used) in a manager operation" - ~description:"An operation assumed a contract counter in the past" - ~pp:(fun ppf (contract, exp, found) -> - Format.fprintf - ppf - "Counter %a already used for contract %a (expected %a)" - Z.pp_print - found - Contract_repr.pp - contract - Z.pp_print - exp) - Data_encoding.( - obj3 - (req "contract" Contract_repr.encoding) - (req "expected" z) - (req "found" z)) - (function Counter_in_the_past (c, x, y) -> Some (c, x, y) | _ -> None) - (fun (c, x, y) -> Counter_in_the_past (c, x, y)) ; - register_error_kind - `Temporary - ~id:"contract.non_existing_contract" - ~title:"Non existing contract" - ~description: - "A contract handle is not present in the context (either it never was or \ - it has been destroyed)" - ~pp:(fun ppf contract -> - Format.fprintf ppf "Contract %a does not exist" Contract_repr.pp contract) - Data_encoding.(obj1 (req "contract" Contract_repr.encoding)) - (function Non_existing_contract c -> Some c | _ -> None) - (fun c -> Non_existing_contract c) ; - register_error_kind - `Permanent - ~id:"contract.manager.inconsistent_public_key" - ~title:"Inconsistent public key" - ~description: - "A provided manager public key is different with the public key stored \ - in the contract" - ~pp:(fun ppf (eh, ph) -> - Format.fprintf - ppf - "Expected manager public key %s but %s was provided" - (Signature.Public_key.to_b58check ph) - (Signature.Public_key.to_b58check eh)) - Data_encoding.( - obj2 - (req "public_key" Signature.Public_key.encoding) - (req "expected_public_key" Signature.Public_key.encoding)) - (function Inconsistent_public_key (eh, ph) -> Some (eh, ph) | _ -> None) - (fun (eh, ph) -> Inconsistent_public_key (eh, ph)) ; - register_error_kind - `Permanent - ~id:"contract.failure" - ~title:"Contract storage failure" - ~description:"Unexpected contract storage error" - ~pp:(fun ppf s -> Format.fprintf ppf "Contract_storage.Failure %S" s) - Data_encoding.(obj1 (req "message" string)) - (function Failure s -> Some s | _ -> None) - (fun s -> Failure s) ; - register_error_kind - `Branch - ~id:"implicit.empty_implicit_contract" - ~title:"Empty implicit contract" - ~description: - "No manager operations are allowed on an empty implicit contract." - ~pp:(fun ppf implicit -> - Format.fprintf - ppf - "Empty implicit contract (%a)" - Signature.Public_key_hash.pp - implicit) - Data_encoding.(obj1 (req "implicit" Signature.Public_key_hash.encoding)) - (function Empty_implicit_contract c -> Some c | _ -> None) - (fun c -> Empty_implicit_contract c) ; - register_error_kind - `Branch - ~id:"implicit.empty_implicit_delegated_contract" - ~title:"Empty implicit delegated contract" - ~description:"Emptying an implicit delegated account is not allowed." - ~pp:(fun ppf implicit -> - Format.fprintf - ppf - "Emptying implicit delegated contract (%a)" - Signature.Public_key_hash.pp - implicit) - Data_encoding.(obj1 (req "implicit" Signature.Public_key_hash.encoding)) - (function Empty_implicit_delegated_contract c -> Some c | _ -> None) - (fun c -> Empty_implicit_delegated_contract c) - -let failwith msg = fail (Failure msg) - -module Legacy_big_map_diff = struct - (* - Big_map_diff receipt as it was represented in 006 and earlier. - It is kept here for now for backward compatibility of tools. *) - - type item = - | Update of { - big_map : Z.t; - diff_key : Script_repr.expr; - diff_key_hash : Script_expr_hash.t; - diff_value : Script_repr.expr option; - } - | Clear of Z.t - | Copy of {src : Z.t; dst : Z.t} - | Alloc of { - big_map : Z.t; - key_type : Script_repr.expr; - value_type : Script_repr.expr; - } - - type t = item list - - let item_encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"update" - (obj5 - (req "action" (constant "update")) - (req "big_map" z) - (req "key_hash" Script_expr_hash.encoding) - (req "key" Script_repr.expr_encoding) - (opt "value" Script_repr.expr_encoding)) - (function - | Update {big_map; diff_key_hash; diff_key; diff_value} -> - Some ((), big_map, diff_key_hash, diff_key, diff_value) - | _ -> None) - (fun ((), big_map, diff_key_hash, diff_key, diff_value) -> - Update {big_map; diff_key_hash; diff_key; diff_value}); - case - (Tag 1) - ~title:"remove" - (obj2 (req "action" (constant "remove")) (req "big_map" z)) - (function Clear big_map -> Some ((), big_map) | _ -> None) - (fun ((), big_map) -> Clear big_map); - case - (Tag 2) - ~title:"copy" - (obj3 - (req "action" (constant "copy")) - (req "source_big_map" z) - (req "destination_big_map" z)) - (function Copy {src; dst} -> Some ((), src, dst) | _ -> None) - (fun ((), src, dst) -> Copy {src; dst}); - case - (Tag 3) - ~title:"alloc" - (obj4 - (req "action" (constant "alloc")) - (req "big_map" z) - (req "key_type" Script_repr.expr_encoding) - (req "value_type" Script_repr.expr_encoding)) - (function - | Alloc {big_map; key_type; value_type} -> - Some ((), big_map, key_type, value_type) - | _ -> None) - (fun ((), big_map, key_type, value_type) -> - Alloc {big_map; key_type; value_type}); - ] - - let encoding = Data_encoding.list item_encoding - - let to_lazy_storage_diff legacy_diffs = - let rev_head (diffs : (_ * (_, _, _) Lazy_storage_diff.diff) list) = - match diffs with - | [] -> [] - | (_, Remove) :: _ -> diffs - | (id, Update {init; updates}) :: rest -> - (id, Update {init; updates = List.rev updates}) :: rest - in - (* Invariant: - Updates are collected one by one, in reverse order, on the head diff - item. So only and exactly the head diff item has its updates reversed. - *) - List.fold_left - (fun (new_diff : (_ * (_, _, _) Lazy_storage_diff.diff) list) item -> - match item with - | Clear id -> (id, Lazy_storage_diff.Remove) :: rev_head new_diff - | Copy {src; dst} -> - let src = - Lazy_storage_kind.Big_map.Id - .of_legacy_USE_ONLY_IN_Legacy_big_map_diff - src - in - (dst, Lazy_storage_diff.Update {init = Copy {src}; updates = []}) - :: rev_head new_diff - | Alloc {big_map; key_type; value_type} -> - ( big_map, - Lazy_storage_diff.( - Update - { - init = Alloc Lazy_storage_kind.Big_map.{key_type; value_type}; - updates = []; - }) ) - :: rev_head new_diff - | Update - { - big_map; - diff_key = key; - diff_key_hash = key_hash; - diff_value = value; - } -> ( - match new_diff with - | (id, diff) :: rest when Compare.Z.(id = big_map) -> - let diff = - match diff with - | Remove -> assert false - | Update {init; updates} -> - let updates = - Lazy_storage_kind.Big_map.{key; key_hash; value} - :: updates - in - Lazy_storage_diff.Update {init; updates} - in - (id, diff) :: rest - | new_diff -> - let updates = - [Lazy_storage_kind.Big_map.{key; key_hash; value}] - in - (big_map, Update {init = Existing; updates}) - :: rev_head new_diff)) - [] - legacy_diffs - |> rev_head - |> List.rev_map (fun (id, diff) -> - let id = - Lazy_storage_kind.Big_map.Id - .of_legacy_USE_ONLY_IN_Legacy_big_map_diff - id - in - Lazy_storage_diff.make Lazy_storage_kind.Big_map id diff) - - let of_lazy_storage_diff diffs = - List.fold_left - (fun legacy_diffs (Lazy_storage_diff.Item (kind, id, diff)) -> - let diffs = - match kind with - | Lazy_storage_kind.Big_map -> ( - let id = - Lazy_storage_kind.Big_map.Id - .to_legacy_USE_ONLY_IN_Legacy_big_map_diff - id - in - match diff with - | Remove -> [Clear id] - | Update {init; updates} -> ( - let updates = - List.rev_map - (fun {Lazy_storage_kind.Big_map.key; key_hash; value} -> - Update - { - big_map = id; - diff_key = key; - diff_key_hash = key_hash; - diff_value = value; - }) - updates - in - match init with - | Existing -> updates - | Copy {src} -> - let src = - Lazy_storage_kind.Big_map.Id - .to_legacy_USE_ONLY_IN_Legacy_big_map_diff - src - in - Copy {src; dst = id} :: updates - | Alloc {key_type; value_type} -> - Alloc {big_map = id; key_type; value_type} :: updates)) - | _ -> (* Not a Big_map *) [] - in - diffs :: legacy_diffs) - [] - diffs - |> List.rev |> List.flatten - [@@coq_axiom_with_reason "gadt"] -end - -let update_script_lazy_storage c = function - | None -> return (c, Z.zero) - | Some diffs -> Lazy_storage_diff.apply c diffs - -let create_base c ~prepaid_bootstrap_storage - (* Free space for bootstrap contracts *) - contract ~balance ~manager ?script () = - (match Contract_repr.is_implicit contract with - | None -> return c - | Some _ -> - Storage.Contract.Global_counter.get c >>=? fun counter -> - Storage.Contract.Counter.init c contract counter) - >>=? fun c -> - Storage.Contract.Balance.init c contract balance >>=? fun c -> - (match manager with - | Some manager -> - Contract_manager_storage.init c contract (Manager_repr.Hash manager) - | None -> return c) - >>=? fun c -> - match script with - | Some ({Script_repr.code; storage}, lazy_storage_diff) -> - Storage.Contract.Code.init c contract code >>=? fun (c, code_size) -> - Storage.Contract.Storage.init c contract storage - >>=? fun (c, storage_size) -> - update_script_lazy_storage c lazy_storage_diff - >>=? fun (c, lazy_storage_size) -> - let total_size = - Z.add - (Z.add (Z.of_int code_size) (Z.of_int storage_size)) - lazy_storage_size - in - assert (Compare.Z.(total_size >= Z.zero)) ; - let prepaid_bootstrap_storage = - if prepaid_bootstrap_storage then total_size else Z.zero - in - Storage.Contract.Paid_storage_space.init - c - contract - prepaid_bootstrap_storage - >>=? fun c -> - Storage.Contract.Used_storage_space.init c contract total_size - | None -> return c - -let raw_originate c ~prepaid_bootstrap_storage contract ~script = - create_base - c - ~prepaid_bootstrap_storage - contract - ~balance:Tez_repr.zero - ~manager:None - ~script - () - -let create_implicit c manager ~balance = - create_base - c - ~prepaid_bootstrap_storage:false - (Contract_repr.implicit_contract manager) - ~balance - ~manager:(Some manager) - ?script:None - () - -let delete c contract = - match Contract_repr.is_implicit contract with - | None -> - (* For non implicit contract Big_map should be cleared *) - failwith "Non implicit contracts cannot be removed" - | Some _ -> - Contract_delegate_storage.remove c contract >>=? fun c -> - Storage.Contract.Balance.remove_existing c contract >>=? fun c -> - Contract_manager_storage.remove_existing c contract >>=? fun c -> - Storage.Contract.Counter.remove_existing c contract >>=? fun c -> - Storage.Contract.Code.remove c contract >>=? fun (c, _, _) -> - Storage.Contract.Storage.remove c contract >>=? fun (c, _, _) -> - Storage.Contract.Paid_storage_space.remove c contract >>= fun c -> - Storage.Contract.Used_storage_space.remove c contract >|= ok - -let allocated c contract = - Storage.Contract.Balance.find c contract >>=? function - | None -> return_false - | Some _ -> return_true - -let exists c contract = - match Contract_repr.is_implicit contract with - | Some _ -> return_true - | None -> allocated c contract - -let must_exist c contract = - exists c contract >>=? function - | true -> return_unit - | false -> fail (Non_existing_contract contract) - -let must_be_allocated c contract = - allocated c contract >>=? function - | true -> return_unit - | false -> ( - match Contract_repr.is_implicit contract with - | Some pkh -> fail (Empty_implicit_contract pkh) - | None -> fail (Non_existing_contract contract)) - -let list c = Storage.Contract.list c - -let fresh_contract_from_current_nonce c = - Raw_context.increment_origination_nonce c >|? fun (c, nonce) -> - (c, Contract_repr.originated_contract nonce) - -let originated_from_current_nonce ~since:ctxt_since ~until:ctxt_until = - Raw_context.get_origination_nonce ctxt_since >>?= fun since -> - Raw_context.get_origination_nonce ctxt_until >>?= fun until -> - List.filter_es - (fun contract -> exists ctxt_until contract) - (Contract_repr.originated_contracts ~since ~until) - -let check_counter_increment c manager counter = - let contract = Contract_repr.implicit_contract manager in - Storage.Contract.Counter.get c contract >>=? fun contract_counter -> - let expected = Z.succ contract_counter in - if Compare.Z.(expected = counter) then return_unit - else if Compare.Z.(expected > counter) then - fail (Counter_in_the_past (contract, expected, counter)) - else fail (Counter_in_the_future (contract, expected, counter)) - -let increment_counter c manager = - let contract = Contract_repr.implicit_contract manager in - Storage.Contract.Global_counter.get c >>=? fun global_counter -> - Storage.Contract.Global_counter.update c (Z.succ global_counter) >>=? fun c -> - Storage.Contract.Counter.get c contract >>=? fun contract_counter -> - Storage.Contract.Counter.update c contract (Z.succ contract_counter) - -let get_script_code c contract = Storage.Contract.Code.find c contract - -let get_script c contract = - Storage.Contract.Code.find c contract >>=? fun (c, code) -> - Storage.Contract.Storage.find c contract >>=? fun (c, storage) -> - match (code, storage) with - | (None, None) -> return (c, None) - | (Some code, Some storage) -> return (c, Some {Script_repr.code; storage}) - | (None, Some _) | (Some _, None) -> failwith "get_script" - -let get_storage ctxt contract = - Storage.Contract.Storage.find ctxt contract >>=? function - | (ctxt, None) -> return (ctxt, None) - | (ctxt, Some storage) -> - Raw_context.consume_gas ctxt (Script_repr.force_decode_cost storage) - >>?= fun ctxt -> - Script_repr.force_decode storage >>?= fun storage -> - return (ctxt, Some storage) - -let get_counter c manager = - let contract = Contract_repr.implicit_contract manager in - Storage.Contract.Counter.find c contract >>=? function - | None -> ( - match Contract_repr.is_implicit contract with - | Some _ -> Storage.Contract.Global_counter.get c - | None -> failwith "get_counter") - | Some v -> return v - -let get_balance c contract = - Storage.Contract.Balance.find c contract >>=? function - | None -> ( - match Contract_repr.is_implicit contract with - | Some _ -> return Tez_repr.zero - | None -> failwith "get_balance") - | Some v -> return v - -let get_balance_carbonated c contract = - (* Reading an int64 from /contracts/index//balance *) - Raw_context.consume_gas - c - (Storage_costs.read_access ~path_length:4 ~read_bytes:8) - >>?= fun c -> - get_balance c contract >>=? fun balance -> return (c, balance) - -let update_script_storage c contract storage lazy_storage_diff = - let storage = Script_repr.lazy_expr storage in - update_script_lazy_storage c lazy_storage_diff - >>=? fun (c, lazy_storage_size_diff) -> - Storage.Contract.Storage.update c contract storage >>=? fun (c, size_diff) -> - Storage.Contract.Used_storage_space.get c contract >>=? fun previous_size -> - let new_size = - Z.add previous_size (Z.add lazy_storage_size_diff (Z.of_int size_diff)) - in - Storage.Contract.Used_storage_space.update c contract new_size - -let spend_only_call_from_token c contract amount = - Storage.Contract.Balance.find c contract >>=? fun balance -> - let balance = Option.value balance ~default:Tez_repr.zero in - match Tez_repr.(balance -? amount) with - | Error _ -> fail (Balance_too_low (contract, balance, amount)) - | Ok new_balance -> ( - Storage.Contract.Balance.update c contract new_balance >>=? fun c -> - Contract_delegate_storage.remove_contract_stake c contract amount - >>=? fun c -> - if Tez_repr.(new_balance > Tez_repr.zero) then return c - else - match Contract_repr.is_implicit contract with - | None -> return c (* Never delete originated contracts *) - | Some pkh -> ( - Contract_delegate_storage.find c contract >>=? function - | Some pkh' -> - if Signature.Public_key_hash.equal pkh pkh' then return c - else - (* Delegated implicit accounts cannot be emptied *) - fail (Empty_implicit_delegated_contract pkh) - | None -> - (* Delete empty implicit contract *) - delete c contract)) - -(* [Tez_repr.(amount <> zero)] is a precondition of this function. It ensures that - no entry associating a null balance to an implicit contract exists in the map - [Storage.Contract.Balance]. *) -let credit_only_call_from_token c contract amount = - Storage.Contract.Balance.find c contract >>=? function - | None -> ( - match Contract_repr.is_implicit contract with - | None -> fail (Non_existing_contract contract) - | Some manager -> create_implicit c manager ~balance:amount) - | Some balance -> - Tez_repr.(amount +? balance) >>?= fun balance -> - Storage.Contract.Balance.update c contract balance >>=? fun c -> - Contract_delegate_storage.add_contract_stake c contract amount - -let init c = - Storage.Contract.Global_counter.init c Z.zero >>=? fun c -> - Lazy_storage_diff.init c - -let used_storage_space c contract = - Storage.Contract.Used_storage_space.find c contract - >|=? Option.value ~default:Z.zero - -let paid_storage_space c contract = - Storage.Contract.Paid_storage_space.find c contract - >|=? Option.value ~default:Z.zero - -let set_paid_storage_space_and_return_fees_to_pay c contract new_storage_space = - Storage.Contract.Paid_storage_space.get c contract - >>=? fun already_paid_space -> - if Compare.Z.(already_paid_space >= new_storage_space) then return (Z.zero, c) - else - let to_pay = Z.sub new_storage_space already_paid_space in - Storage.Contract.Paid_storage_space.update c contract new_storage_space - >|=? fun c -> (to_pay, c) - -let update_balance ctxt contract f amount = - Storage.Contract.Balance.get ctxt contract >>=? fun balance -> - f balance amount >>?= fun new_balance -> - Storage.Contract.Balance.update ctxt contract new_balance - -let increase_balance_only_call_from_token ctxt contract amount = - update_balance ctxt contract Tez_repr.( +? ) amount - -let decrease_balance_only_call_from_token ctxt contract amount = - update_balance ctxt contract Tez_repr.( -? ) amount diff --git a/src/proto_012_Psithaca/lib_protocol/contract_storage.mli b/src/proto_012_Psithaca/lib_protocol/contract_storage.mli deleted file mode 100644 index a08917d33c32..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contract_storage.mli +++ /dev/null @@ -1,184 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | (* `Temporary *) - Balance_too_low of - Contract_repr.contract * Tez_repr.t * Tez_repr.t - | (* `Temporary *) - Counter_in_the_past of Contract_repr.contract * Z.t * Z.t - | (* `Branch *) - Counter_in_the_future of Contract_repr.contract * Z.t * Z.t - | (* `Temporary *) - Non_existing_contract of Contract_repr.contract - | (* `Branch *) - Empty_implicit_contract of Signature.Public_key_hash.t - | (* `Branch *) - Empty_implicit_delegated_contract of - Signature.Public_key_hash.t - | (* `Permanent *) - Inconsistent_public_key of - Signature.Public_key.t * Signature.Public_key.t - | (* `Permanent *) Failure of string - -(** [allocated ctxt contract] returns [true] if and only if the - contract is stored in [Storage.Contract.Balance]. *) -val allocated : Raw_context.t -> Contract_repr.t -> bool tzresult Lwt.t - -(** [exists ctxt contract] returns [true] if and only if either the - contract is originated or it is (implicit and) "allocated". *) -val exists : Raw_context.t -> Contract_repr.t -> bool tzresult Lwt.t - -(** [must_exist ctxt contract] fails with the [Non_existing_contract] error if - [exists ctxt contract] returns [false]. Even though this function is - gas-free, it is always called in a context where some gas consumption is - guaranteed whenever necessary. The first context is that of a transfer - operation, and in that case the base cost of a manager operation - ([Micheclson_v1_gas.Cost_of.manager_operation]) is consumed. The second - context is that of an activation operation, and in that case no gas needs to - be consumed since that operation is not a manager operation. *) -val must_exist : Raw_context.t -> Contract_repr.t -> unit tzresult Lwt.t - -(** [must_be_allocated ctxt contract] fails when the contract is not - allocated. It fails with [Non_existing_contract] if the contract is - originated, and it fails with [Empty_implicit_contract] if the - contract is implicit. *) -val must_be_allocated : Raw_context.t -> Contract_repr.t -> unit tzresult Lwt.t - -val list : Raw_context.t -> Contract_repr.t list Lwt.t - -val check_counter_increment : - Raw_context.t -> Signature.Public_key_hash.t -> Z.t -> unit tzresult Lwt.t - -val increment_counter : - Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t - -val get_balance : Raw_context.t -> Contract_repr.t -> Tez_repr.t tzresult Lwt.t - -val get_balance_carbonated : - Raw_context.t -> - Contract_repr.t -> - (Raw_context.t * Tez_repr.t) tzresult Lwt.t - -val get_counter : - Raw_context.t -> Signature.Public_key_hash.t -> Z.t tzresult Lwt.t - -val get_script_code : - Raw_context.t -> - Contract_repr.t -> - (Raw_context.t * Script_repr.lazy_expr option) tzresult Lwt.t - -val get_script : - Raw_context.t -> - Contract_repr.t -> - (Raw_context.t * Script_repr.t option) tzresult Lwt.t - -val get_storage : - Raw_context.t -> - Contract_repr.t -> - (Raw_context.t * Script_repr.expr option) tzresult Lwt.t - -module Legacy_big_map_diff : sig - type item = private - | Update of { - big_map : Z.t; - diff_key : Script_repr.expr; - diff_key_hash : Script_expr_hash.t; - diff_value : Script_repr.expr option; - } - | Clear of Z.t - | Copy of {src : Z.t; dst : Z.t} - | Alloc of { - big_map : Z.t; - key_type : Script_repr.expr; - value_type : Script_repr.expr; - } - - type t = item list - - val encoding : t Data_encoding.t - - val to_lazy_storage_diff : t -> Lazy_storage_diff.diffs - - val of_lazy_storage_diff : Lazy_storage_diff.diffs -> t -end - -val update_script_storage : - Raw_context.t -> - Contract_repr.t -> - Script_repr.expr -> - Lazy_storage_diff.diffs option -> - Raw_context.t tzresult Lwt.t - -val credit_only_call_from_token : - Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t - -val spend_only_call_from_token : - Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t - -(** [raw_originate ctxt ~prepaid_bootstrap_storage contract ~script] - originates the [contract] parameter. The [storage] space allocated by this - origination is considered to be free of charge or to have been already paid - for by the user, if and only if [prepaid_bootstrap_storage] is [true]. In - particular, the amount of space allocated by this origination will be part - of the consumed space to pay for returned by the next call to - [Fees_storage.record_paid_storage_space ctxt contract], if and only if - [prepaid_bootstrap_storage] is [false]. *) -val raw_originate : - Raw_context.t -> - prepaid_bootstrap_storage:bool -> - Contract_repr.t -> - script:Script_repr.t * Lazy_storage_diff.diffs option -> - Raw_context.t tzresult Lwt.t - -val fresh_contract_from_current_nonce : - Raw_context.t -> (Raw_context.t * Contract_repr.t) tzresult - -val originated_from_current_nonce : - since:Raw_context.t -> - until:Raw_context.t -> - Contract_repr.t list tzresult Lwt.t - -val init : Raw_context.t -> Raw_context.t tzresult Lwt.t - -val used_storage_space : Raw_context.t -> Contract_repr.t -> Z.t tzresult Lwt.t - -val paid_storage_space : Raw_context.t -> Contract_repr.t -> Z.t tzresult Lwt.t - -val set_paid_storage_space_and_return_fees_to_pay : - Raw_context.t -> - Contract_repr.t -> - Z.t -> - (Z.t * Raw_context.t) tzresult Lwt.t - -(** Increases the balance of a contract. Calling this function directly may - break important invariants. Consider calling [credit] instead. *) -val increase_balance_only_call_from_token : - Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t - -(** Decreases the balance of a contract. Calling this function directly may - break important invariants. Consider calling [spend] instead. *) -val decrease_balance_only_call_from_token : - Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/contracts/cpmm.bin b/src/proto_012_Psithaca/lib_protocol/contracts/cpmm.bin deleted file mode 100644 index c4e455868ecb..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contracts/cpmm.bin +++ /dev/null @@ -1 +0,0 @@ -0x02000011c405000764076407640865046e00000006256f776e6572076504620000000d256d696e4c71744d696e7465640765046200000013256d6178546f6b656e734465706f7369746564046b0000000925646561646c696e650000000d256164644c6971756964697479046c000000082564656661756c7407640865046e0000000325746f076504620000000a256c71744275726e65640765046a00000010256d696e58747a57697468647261776e0765046200000013256d696e546f6b656e7357697468647261776e046b0000000925646561646c696e65000000102572656d6f76654c69717569646974790865046e00000015256f7574707574446578746572436f6e74726163740765046200000010256d696e546f6b656e73426f756768740765046e0000000325746f076504620000000b25746f6b656e73536f6c64046b0000000925646561646c696e650000000d25746f6b656e546f546f6b656e07640865046e0000000325746f076504620000000b25746f6b656e73536f6c640765046a0000000d256d696e58747a426f75676874046b0000000925646561646c696e650000000b25746f6b656e546f58747a0865046e0000000325746f0765046200000010256d696e546f6b656e73426f75676874046b0000000925646561646c696e650000000b2578747a546f546f6b656e0501076504620000000a25746f6b656e506f6f6c0765046a000000082578747a506f6f6c0765046200000009256c7174546f74616c0765046e0000000d25746f6b656e41646472657373046e0000000b256c71744164647265737305020200000f7203210317034c0316072e02000009d1072e020000035a072e020000032603210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200004074303620003032702000002ea0743036a000105700004032105710005031703160322072f0200000013074303680100000008444956206279203003270200000000031603130743036a0001034c0322072f02000000130743036801000000084449562062792030032702000000000316034c0321057100020570000603210571000703170317031605700002032105710003033a0322072f020000001307430368010000000844495620627920300327020000000003160570000205700006032105710007031605700003033a0322072f020000001307430368010000000844495620627920300327020000002a03210317034c03160743036200000570000203190325072c02000000000200000008074303620001031205700002034c0321057100020319032a072c020000000c05200005074303620004032702000001b60571000203210571000303190337072c020000000c0520000407430362000503270200000190057000030321057100040317031703170570000203210571000305700005032105710006031703170316031203420570000403210571000503170316034205700004032105710005031603420317034c032105710002057000050321057100060316031203420321031703170313057000060317031603120342034c03160342034c03490354034203480342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d05700002033005700003034205700002032105710003034c03210317034c031605700002031703170317031706550765045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e072f020000000807430362000c032702000000000743036a000005700002057000030342034d05700002053d036d05700002031b05700002031b0342020000002803200321031703170313057000020321057100030317031603120342034c03160342053d036d0342020000066b072e020000038d03210317034c0316034c03210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200005074303620003032702000003470743036a000003130319032a072c020000000c0520000507430362000a03270200000323057000040321057100050317031703160743036a000105700006032105710007031703160322072f0200000013074303680100000008444956206279203003270200000000031605700004032105710005033a0322072f020000001307430368010000000844495620627920300327020000000003160743036a0001034c033a0570000503210571000603170317031605700006032105710007031605700005032105710006033a0322072f02000000130743036801000000084449562062792030032702000000000316057000030570000203210571000303190337072c020000000c0520000607430362000b0327020000022e05700002034c03210571000203190337072c020000000c0520000507430362000d032702000002060570000203210571000305700005032105710006031703170316034b0356072f020000000807430362000e03270200000000034c032105710002057000060321057100070316034b0356072f020000000807430362000f03270200000000057000040743035b0000034b0348034205700006032105710007034c03210317034c031605700002031703170317031706550765045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e072f020000000807430362000c032702000000000743036a000005700002057000030342034d0570000305700005032105710006034203490354034205700006032105710007034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d05700004032105710005057000060555036c072f020000000807430362000903270200000000034c0743036c030b034d0570000603210571000703170317057000060570000703210571000803170316034b034205700006031603420321031703170317057000060342034c032105710002031703160342034c031603420317057000040342053d036d05700002031b05700002031b05700002031b034202000002d203210317034c0316034c03210317034c0316034c03210317034c0316034c03210317034c03160570000406550765046e0000000325746f0765046200000010256d696e546f6b656e73426f75676874046b0000000925646561646c696e650000000b2578747a546f546f6b656e072f020000000807430362001f032702000000000743036a000003130319032a072c020000000c0520000607430362000a0327020000022d05700002032105710003034003190328072c020000000c05200006074303620003032702000002050743036200a70f05700002032105710003033a0743036200a80f057000070321057100080316033a031205700006032105710007031703160743036200a70f05700004032105710005033a033a0322072f020000001307430368010000000844495620627920300327020000000003160743036200a80f0743036200a70f05700002032105710003033a0322072f02000000130743036801000000084449562062792030032702000000000316057000070321057100080317057000040321057100050570000903210571000a031603120342032103170317057000030321057100040570000a03170316034b0342034c031603420570000403490354034203480342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d057000040570000303210571000405700006057000080342057000070342034d0570000305700004034b0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d05700003053d036d05700002031b05700002031b05700002031b0342020000058d072e02000002cc03210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200004074303620003032702000002900743036a000003130319032a072c020000000c0520000407430362000a0327020000026c0743036200a70f05700002032105710003033a0743036200a80f057000050321057100060316033a03120743036a000105700005032105710006031703160322072f020000001307430368010000000844495620627920300327020000000003160743036200a70f05700004032105710005033a033a0322072f020000001307430368010000000844495620627920300327020000000003160743036a0001034c033a0743036200a80f0743036200a70f05700002032105710003033a0322072f0200000013074303680100000008444956206279203003270200000000031605700002034c03210571000203190337072c020000000a032007430362000803270200000000057000020321057100030349035403420348034205700005032105710006034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d034c032105710002057000050555036c072f020000000807430362000903270200000000034c0743036c030b034d0570000503210571000603170570000505700006032105710007031603120342032103170317057000050321057100060570000703170316034b0342034c031603420570000305700004034b0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d034c053d036d05700002031b05700002031b05700002031b034202000002b503210317034c0316034c03210317034c0316034c034003190328072c020000000c05200003074303620003032702000002830743036a000105700003032105710004031703160322072f0200000013074303680100000008444956206279203003270200000000031603130743036a0001034c0322072f020000001307430368010000000844495620627920300327020000000003160743036200a80f0743036200a70f05700002032105710003033a0322072f02000000130743036801000000084449562062792030032702000000000316032105700002034b03110743036200a70f05700002032105710003033a0743036200a80f05700004033a03120570000503210571000603160743036200a70f05700004032105710005033a033a0322072f0200000013074303680100000008444956206279203003270200000000031605700003034c03210571000203190337072c020000000a0320074303620012032702000000000321057000050321057100060316034b0356072f02000000080743036200130327020000000005700005032105710006031703170743036a000105700005033a05700006032105710007031703160312034205700005031603420317034c0342034c057000030342034903540342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d0743036a000105700003033a0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d05700002053d036d05700002031b05700002031b0342 diff --git a/src/proto_012_Psithaca/lib_protocol/contracts/cpmm.mligo b/src/proto_012_Psithaca/lib_protocol/contracts/cpmm.mligo deleted file mode 100644 index 37213e25a216..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contracts/cpmm.mligo +++ /dev/null @@ -1,388 +0,0 @@ -// ============================================================================= -// Entrypoints -// ============================================================================= - -type add_liquidity = - [@layout:comb] - { owner : address ; - minLqtMinted : nat ; - maxTokensDeposited : nat ; - deadline : timestamp ; - } - -type remove_liquidity = - [@layout:comb] - { [@annot:to] to_ : address ; // recipient of the liquidity redemption - lqtBurned : nat ; // amount of lqt owned by sender to burn - minXtzWithdrawn : tez ; // minimum amount of tez to withdraw - minTokensWithdrawn : nat ; // minimum amount of tokens to whitdw - deadline : timestamp ; // the time before which the request must be completed - } - -type xtz_to_token = - [@layout:comb] - { [@annot:to] to_ : address ; - minTokensBought : nat ; - deadline : timestamp ; - } - -type token_to_xtz = - [@layout:comb] - { [@annot:to] to_ : address ; - tokensSold : nat ; - minXtzBought : tez ; - deadline : timestamp ; - } - -type token_to_token = - [@layout:comb] - { outputDexterContract : address ; - minTokensBought : nat ; - [@annot:to] to_ : address ; - tokensSold : nat ; - deadline : timestamp ; - } - -type entrypoint = -| AddLiquidity of add_liquidity -| RemoveLiquidity of remove_liquidity -| XtzToToken of xtz_to_token -| TokenToXtz of token_to_xtz -| Default of unit -| TokenToToken of token_to_token - - -// ============================================================================= -// Storage -// ============================================================================= - -type storage = - [@layout:comb] - { tokenPool : nat ; - xtzPool : tez ; - lqtTotal : nat ; - tokenAddress : address ; - lqtAddress : address ; - } - -// ============================================================================= -// Type Synonyms -// ============================================================================= - -type result = operation list * storage - -// FA1.2 -type token_contract_transfer = address * (address * nat) -type get_balance = address * (nat contract) - -// custom entrypoint for LQT FA1.2 -type mintOrBurn = - [@layout:comb] - { quantity : int ; - target : address } - -// ============================================================================= -// Error codes -// ============================================================================= - -[@inline] let error_TOKEN_CONTRACT_MUST_HAVE_A_TRANSFER_ENTRYPOINT = 0n -(* 1n *) -[@inline] let error_SELF_IS_UPDATING_TOKEN_POOL_MUST_BE_FALSE = 2n -[@inline] let error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE = 3n -[@inline] let error_MAX_TOKENS_DEPOSITED_MUST_BE_GREATER_THAN_OR_EQUAL_TO_TOKENS_DEPOSITED = 4n -[@inline] let error_LQT_MINTED_MUST_BE_GREATER_THAN_MIN_LQT_MINTED = 5n -(* 6n *) -(* 7n *) -[@inline] let error_XTZ_BOUGHT_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_XTZ_BOUGHT = 8n -[@inline] let error_INVALID_TO_ADDRESS = 9n -[@inline] let error_AMOUNT_MUST_BE_ZERO = 10n -[@inline] let error_THE_AMOUNT_OF_XTZ_WITHDRAWN_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_XTZ_WITHDRAWN = 11n -[@inline] let error_LQT_CONTRACT_MUST_HAVE_A_MINT_OR_BURN_ENTRYPOINT = 12n -[@inline] let error_THE_AMOUNT_OF_TOKENS_WITHDRAWN_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_TOKENS_WITHDRAWN = 13n -[@inline] let error_CANNOT_BURN_MORE_THAN_THE_TOTAL_AMOUNT_OF_LQT = 14n -[@inline] let error_TOKEN_POOL_MINUS_TOKENS_WITHDRAWN_IS_NEGATIVE = 15n -(* 16n *) -(* 17n *) -[@inline] let error_TOKENS_BOUGHT_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_TOKENS_BOUGHT = 18n -[@inline] let error_TOKEN_POOL_MINUS_TOKENS_BOUGHT_IS_NEGATIVE = 19n -[@inline] let error_ONLY_MANAGER_CAN_SET_BAKER = 20n -[@inline] let error_ONLY_MANAGER_CAN_SET_MANAGER = 21n -[@inline] let error_BAKER_PERMANENTLY_FROZEN = 22n -[@inline] let error_ONLY_MANAGER_CAN_SET_LQT_ADRESS = 23n -[@inline] let error_LQT_ADDRESS_ALREADY_SET = 24n -[@inline] let error_CALL_NOT_FROM_AN_IMPLICIT_ACCOUNT = 25n -(* 26n *) -(* 27n *) -#if FA2 -[@inline] let error_INVALID_FA2_TOKEN_CONTRACT_MISSING_BALANCE_OF = 28n -#else -[@inline] let error_INVALID_FA12_TOKEN_CONTRACT_MISSING_GETBALANCE = 28n -#endif -[@inline] let error_THIS_ENTRYPOINT_MAY_ONLY_BE_CALLED_BY_GETBALANCE_OF_TOKENADDRESS = 29n -(* 30n *) -[@inline] let error_INVALID_INTERMEDIATE_CONTRACT = 31n -[@inline] let error_INVALID_FA2_BALANCE_RESPONSE = 32n -[@inline] let error_UNEXPECTED_REENTRANCE_IN_UPDATE_TOKEN_POOL = 33n - - -// ============================================================================= -// Functions -// ============================================================================= - -[@inline] -let fee = 999n - -[@inline] let null_address = ("tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU" : address) - -(* this is slightly inefficient to inline, but, nice to have a clean stack for - the entrypoints for the Coq verification *) -[@inline] -let mutez_to_natural (a: tez) : nat = a / 1mutez - -[@inline] -let natural_to_mutez (a: nat): tez = a * 1mutez - -[@inline] -let is_a_nat (i : int) : nat option = Michelson.is_nat i - -let ceildiv (numerator : nat) (denominator : nat) : nat = - match (ediv numerator denominator) with - | None -> (failwith("DIV by 0") : nat) - | Some v -> let (q, r) = v in if r = 0n then q else q + 1n - -[@inline] -let mint_or_burn (storage : storage) (target : address) (quantity : int) : operation = - let lqt_admin : mintOrBurn contract = - match (Tezos.get_entrypoint_opt "%mintOrBurn" storage.lqtAddress : mintOrBurn contract option) with - | None -> (failwith error_LQT_CONTRACT_MUST_HAVE_A_MINT_OR_BURN_ENTRYPOINT : mintOrBurn contract) - | Some contract -> contract in - Tezos.transaction {quantity = quantity ; target = target} 0mutez lqt_admin - -[@inline] -let token_transfer (storage : storage) (from : address) (to_ : address) (token_amount : nat) : operation = - let token_contract: token_contract_transfer contract = - match (Tezos.get_entrypoint_opt "%transfer" storage.tokenAddress : token_contract_transfer contract option) with - | None -> (failwith error_TOKEN_CONTRACT_MUST_HAVE_A_TRANSFER_ENTRYPOINT : token_contract_transfer contract) - | Some contract -> contract in - Tezos.transaction (from, (to_, token_amount)) 0mutez token_contract - -[@inline] -let xtz_transfer (to_ : address) (amount_ : tez) : operation = - let to_contract : unit contract = - match (Tezos.get_contract_opt to_ : unit contract option) with - | None -> (failwith error_INVALID_TO_ADDRESS : unit contract) - | Some c -> c in - Tezos.transaction () amount_ to_contract - -// ============================================================================= -// Entrypoint Functions -// ============================================================================= - -// We assume the contract is originated with at least one liquidity -// provider set up already, so lqtTotal, xtzPool and tokenPool will -// always be positive after the initial setup, unless all liquidity is -// removed, at which point the contract is considered dead and stops working -// properly. (To prevent this, at least one address should keep at least a -// small amount of liquidity in the contract forever.) - -let add_liquidity (param : add_liquidity) (storage: storage) : result = - let { owner = owner ; - minLqtMinted = minLqtMinted ; - maxTokensDeposited = maxTokensDeposited ; - deadline = deadline } = param in - - if Tezos.now >= deadline then - (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) - else - // the contract is initialized, use the existing exchange rate - // mints nothing if the contract has been emptied, but that's OK - let xtzPool : nat = mutez_to_natural storage.xtzPool in - let nat_amount : nat = mutez_to_natural Tezos.amount in - let lqt_minted : nat = nat_amount * storage.lqtTotal / xtzPool in - let tokens_deposited : nat = ceildiv (nat_amount * storage.tokenPool) xtzPool in - - if tokens_deposited > maxTokensDeposited then - (failwith error_MAX_TOKENS_DEPOSITED_MUST_BE_GREATER_THAN_OR_EQUAL_TO_TOKENS_DEPOSITED : result) - else if lqt_minted < minLqtMinted then - (failwith error_LQT_MINTED_MUST_BE_GREATER_THAN_MIN_LQT_MINTED : result) - else - let storage = {storage with - lqtTotal = storage.lqtTotal + lqt_minted ; - tokenPool = storage.tokenPool + tokens_deposited ; - xtzPool = storage.xtzPool + Tezos.amount} in - - // send tokens from sender to exchange - let op_token = token_transfer storage Tezos.sender Tezos.self_address tokens_deposited in - // mint lqt tokens for them - let op_lqt = mint_or_burn storage owner (int lqt_minted) in - ([op_token; op_lqt], storage) - -let remove_liquidity (param : remove_liquidity) (storage : storage) : result = - let { to_ = to_ ; - lqtBurned = lqtBurned ; - minXtzWithdrawn = minXtzWithdrawn ; - minTokensWithdrawn = minTokensWithdrawn ; - deadline = deadline } = param in - - if Tezos.now >= deadline then - (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) - else if Tezos.amount > 0mutez then - (failwith error_AMOUNT_MUST_BE_ZERO : result) - else begin - let xtz_withdrawn : tez = natural_to_mutez ((lqtBurned * (mutez_to_natural storage.xtzPool)) / storage.lqtTotal) in - let tokens_withdrawn : nat = lqtBurned * storage.tokenPool / storage.lqtTotal in - - // Check that minimum withdrawal conditions are met - if xtz_withdrawn < minXtzWithdrawn then - (failwith error_THE_AMOUNT_OF_XTZ_WITHDRAWN_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_XTZ_WITHDRAWN : result) - else if tokens_withdrawn < minTokensWithdrawn then - (failwith error_THE_AMOUNT_OF_TOKENS_WITHDRAWN_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_TOKENS_WITHDRAWN : result) - // Proceed to form the operations and update the storage - else begin - // calculate lqtTotal, convert int to nat - let new_lqtTotal = match (is_a_nat ( storage.lqtTotal - lqtBurned)) with - // This check should be unecessary, the fa12 logic normally takes care of it - | None -> (failwith error_CANNOT_BURN_MORE_THAN_THE_TOTAL_AMOUNT_OF_LQT : nat) - | Some n -> n in - // Calculate tokenPool, convert int to nat - let new_tokenPool = match is_a_nat (storage.tokenPool - tokens_withdrawn) with - | None -> (failwith error_TOKEN_POOL_MINUS_TOKENS_WITHDRAWN_IS_NEGATIVE : nat) - | Some n -> n in - - let op_lqt = mint_or_burn storage Tezos.sender (0 - lqtBurned) in - let op_token = token_transfer storage Tezos.self_address to_ tokens_withdrawn in - let op_xtz = xtz_transfer to_ xtz_withdrawn in - let storage = {storage with xtzPool = storage.xtzPool - xtz_withdrawn ; lqtTotal = new_lqtTotal ; tokenPool = new_tokenPool} in - ([op_lqt; op_token; op_xtz], storage) - end - end - - -let xtz_to_token (param : xtz_to_token) (storage : storage) = - let { to_ = to_ ; - minTokensBought = minTokensBought ; - deadline = deadline } = param in - - if Tezos.now >= deadline then - (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) - else begin - // we don't check that xtzPool > 0, because that is impossible - // unless all liquidity has been removed - let xtzPool = mutez_to_natural storage.xtzPool in - let nat_amount = mutez_to_natural Tezos.amount in - - let amount_net_burn = (nat_amount * 999n) / 1000n in - let burn_amount = abs (nat_amount - amount_net_burn) in - - let tokens_bought = - (let bought = (amount_net_burn * fee * storage.tokenPool) / (xtzPool * 1000n + (amount_net_burn * fee)) in - if bought < minTokensBought then - (failwith error_TOKENS_BOUGHT_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_TOKENS_BOUGHT : nat) - else - bought) - in - let new_tokenPool = (match is_nat (storage.tokenPool - tokens_bought) with - | None -> (failwith error_TOKEN_POOL_MINUS_TOKENS_BOUGHT_IS_NEGATIVE : nat) - | Some difference -> difference) in - - // update xtzPool - let storage = {storage with - xtzPool = storage.xtzPool + (natural_to_mutez amount_net_burn); - tokenPool = new_tokenPool } in - // send tokens_withdrawn to to address - // if tokens_bought is greater than storage.tokenPool, this will fail - let op = token_transfer storage Tezos.self_address to_ tokens_bought in - let op_burn = xtz_transfer null_address (natural_to_mutez burn_amount) in - ([ op ; op_burn], storage) - end - - -let token_to_xtz (param : token_to_xtz) (storage : storage) = - let { to_ = to_ ; - tokensSold = tokensSold ; - minXtzBought = minXtzBought ; - deadline = deadline } = param in - - if Tezos.now >= deadline then - (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) - else if Tezos.amount > 0mutez then - (failwith error_AMOUNT_MUST_BE_ZERO : result) - else - // we don't check that tokenPool > 0, because that is impossible - // unless all liquidity has been removed - let xtz_bought = natural_to_mutez (((tokensSold * fee * (mutez_to_natural storage.xtzPool)) / (storage.tokenPool * 1000n + (tokensSold * fee)))) in - - let xtz_bought_net_burn = - let bought = (xtz_bought * 999n) / 1000n in - if bought < minXtzBought then (failwith error_XTZ_BOUGHT_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_XTZ_BOUGHT : tez) else bought in - - let op_token = token_transfer storage Tezos.sender Tezos.self_address tokensSold in - let op_tez = xtz_transfer to_ xtz_bought_net_burn in - let storage = {storage with tokenPool = storage.tokenPool + tokensSold ; - xtzPool = storage.xtzPool - xtz_bought } in - - let burn_amount = xtz_bought - xtz_bought_net_burn in - let op_burn = xtz_transfer null_address burn_amount in - ([op_token ; op_tez; op_burn], storage) - -// entrypoint to allow depositing funds -let default_ (storage : storage) : result = - // update xtzPool - let storage = {storage with xtzPool = storage.xtzPool + Tezos.amount } in - (([] : operation list), storage) - -let token_to_token (param : token_to_token) (storage : storage) : result = - let { outputDexterContract = outputDexterContract ; - minTokensBought = minTokensBought ; - to_ = to_ ; - tokensSold = tokensSold ; - deadline = deadline } = param in - - let outputDexterContract_contract: xtz_to_token contract = - (match (Tezos.get_entrypoint_opt "%xtzToToken" outputDexterContract : xtz_to_token contract option) with - | None -> (failwith error_INVALID_INTERMEDIATE_CONTRACT : xtz_to_token contract) - | Some c -> c) in - - if Tezos.amount > 0mutez then - (failwith error_AMOUNT_MUST_BE_ZERO : result) - else if Tezos.now >= deadline then - (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) - else - // we don't check that tokenPool > 0, because that is impossible unless all liquidity has been removed - let xtz_bought = (tokensSold * fee * storage.xtzPool) / (storage.tokenPool * 1000n + (tokensSold * fee)) in - - let xtz_bought_net_burn = (xtz_bought * 999n) / 1000n in - - let storage = {storage with - tokenPool = storage.tokenPool + tokensSold ; - xtzPool = storage.xtzPool - xtz_bought } in - - let op1 = token_transfer storage Tezos.sender Tezos.self_address tokensSold in - let op2 = - Tezos.transaction - {to_ = to_; minTokensBought = minTokensBought; deadline = deadline} - xtz_bought_net_burn - outputDexterContract_contract in - - let burn_amount = xtz_bought - xtz_bought_net_burn in - let op_burn = xtz_transfer null_address burn_amount in - ([op1 ; op2; op_burn], storage) - -// ============================================================================= -// Main -// ============================================================================= - -let main ((entrypoint, storage) : entrypoint * storage) : result = - match entrypoint with - | AddLiquidity param -> - add_liquidity param storage - | RemoveLiquidity param -> - remove_liquidity param storage - | Default -> - default_ storage - | XtzToToken param -> - xtz_to_token param storage - | TokenToXtz param -> - token_to_xtz param storage - | TokenToToken param -> - token_to_token param storage \ No newline at end of file diff --git a/src/proto_012_Psithaca/lib_protocol/contracts/cpmm.tz b/src/proto_012_Psithaca/lib_protocol/contracts/cpmm.tz deleted file mode 100644 index 15a0819c52e8..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contracts/cpmm.tz +++ /dev/null @@ -1,929 +0,0 @@ -{ parameter - (or (or (or (pair %addLiquidity - (address %owner) - (pair (nat %minLqtMinted) (pair (nat %maxTokensDeposited) (timestamp %deadline)))) - (unit %default)) - (or (pair %removeLiquidity - (address %to) - (pair (nat %lqtBurned) - (pair (mutez %minXtzWithdrawn) (pair (nat %minTokensWithdrawn) (timestamp %deadline))))) - (pair %tokenToToken - (address %outputDexterContract) - (pair (nat %minTokensBought) - (pair (address %to) (pair (nat %tokensSold) (timestamp %deadline))))))) - (or (pair %tokenToXtz - (address %to) - (pair (nat %tokensSold) (pair (mutez %minXtzBought) (timestamp %deadline)))) - (pair %xtzToToken (address %to) (pair (nat %minTokensBought) (timestamp %deadline))))) ; - storage - (pair (nat %tokenPool) - (pair (mutez %xtzPool) - (pair (nat %lqtTotal) (pair (address %tokenAddress) (address %lqtAddress))))) ; - code { DUP ; - CDR ; - SWAP ; - CAR ; - IF_LEFT - { IF_LEFT - { IF_LEFT - { DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - NOW ; - COMPARE ; - GE ; - IF { DROP 4 ; PUSH nat 3 ; FAILWITH } - { PUSH mutez 1 ; - DIG 4 ; - DUP ; - DUG 5 ; - CDR ; - CAR ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - AMOUNT ; - PUSH mutez 1 ; - SWAP ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - SWAP ; - DUP ; - DUG 2 ; - DIG 6 ; - DUP ; - DUG 7 ; - CDR ; - CDR ; - CAR ; - DIG 2 ; - DUP ; - DUG 3 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DIG 2 ; - DIG 6 ; - DUP ; - DUG 7 ; - CAR ; - DIG 3 ; - MUL ; - EDIV ; - IF_NONE - { PUSH string "DIV by 0" ; FAILWITH } - { DUP ; - CDR ; - SWAP ; - CAR ; - PUSH nat 0 ; - DIG 2 ; - COMPARE ; - EQ ; - IF {} { PUSH nat 1 ; ADD } } ; - DIG 2 ; - SWAP ; - DUP ; - DUG 2 ; - COMPARE ; - GT ; - IF { DROP 5 ; PUSH nat 4 ; FAILWITH } - { DUG 2 ; - DUP ; - DUG 3 ; - COMPARE ; - LT ; - IF { DROP 4 ; PUSH nat 5 ; FAILWITH } - { DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - CDR ; - CDR ; - DIG 2 ; - DUP ; - DUG 3 ; - DIG 5 ; - DUP ; - DUG 6 ; - CDR ; - CDR ; - CAR ; - ADD ; - PAIR ; - DIG 4 ; - DUP ; - DUG 5 ; - CDR ; - CAR ; - PAIR ; - DIG 4 ; - DUP ; - DUG 5 ; - CAR ; - PAIR ; - CDR ; - SWAP ; - DUP ; - DUG 2 ; - DIG 5 ; - DUP ; - DUG 6 ; - CAR ; - ADD ; - PAIR ; - DUP ; - CDR ; - CDR ; - AMOUNT ; - DIG 6 ; - CDR ; - CAR ; - ADD ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - SWAP ; - SELF ; - ADDRESS ; - PAIR ; - SENDER ; - PAIR ; - SWAP ; - DUP ; - DUG 2 ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - DIG 3 ; - CDR ; - CDR ; - CDR ; - CAR ; - CONTRACT %transfer (pair address (pair address nat)) ; - IF_NONE { PUSH nat 0 ; FAILWITH } {} ; - PUSH mutez 0 ; - DIG 3 ; - DIG 3 ; - PAIR ; - DIG 3 ; - PAIR ; - TRANSFER_TOKENS ; - DIG 2 ; - INT ; - DIG 3 ; - PAIR ; - DIG 2 ; - DUP ; - DUG 3 ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - DIG 2 ; - CDR ; - CDR ; - CDR ; - CDR ; - CONTRACT %mintOrBurn (pair (int %quantity) (address %target)) ; - IF_NONE { PUSH nat 12 ; FAILWITH } {} ; - PUSH mutez 0 ; - DIG 2 ; - DIG 3 ; - PAIR ; - TRANSFER_TOKENS ; - DIG 2 ; - NIL operation ; - DIG 2 ; - CONS ; - DIG 2 ; - CONS ; - PAIR } } } } - { DROP ; - DUP ; - CDR ; - CDR ; - AMOUNT ; - DIG 2 ; - DUP ; - DUG 3 ; - CDR ; - CAR ; - ADD ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - NIL operation ; - PAIR } } - { IF_LEFT - { DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - NOW ; - COMPARE ; - GE ; - IF { DROP 5 ; PUSH nat 3 ; FAILWITH } - { PUSH mutez 0 ; - AMOUNT ; - COMPARE ; - GT ; - IF { DROP 5 ; PUSH nat 10 ; FAILWITH } - { DIG 4 ; - DUP ; - DUG 5 ; - CDR ; - CDR ; - CAR ; - PUSH mutez 1 ; - DIG 6 ; - DUP ; - DUG 7 ; - CDR ; - CAR ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DIG 4 ; - DUP ; - DUG 5 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - PUSH mutez 1 ; - SWAP ; - MUL ; - DIG 5 ; - DUP ; - DUG 6 ; - CDR ; - CDR ; - CAR ; - DIG 6 ; - DUP ; - DUG 7 ; - CAR ; - DIG 5 ; - DUP ; - DUG 6 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DIG 3 ; - DIG 2 ; - DUP ; - DUG 3 ; - COMPARE ; - LT ; - IF { DROP 6 ; PUSH nat 11 ; FAILWITH } - { DIG 2 ; - SWAP ; - DUP ; - DUG 2 ; - COMPARE ; - LT ; - IF { DROP 5 ; PUSH nat 13 ; FAILWITH } - { DIG 2 ; - DUP ; - DUG 3 ; - DIG 5 ; - DUP ; - DUG 6 ; - CDR ; - CDR ; - CAR ; - SUB ; - ISNAT ; - IF_NONE { PUSH nat 14 ; FAILWITH } {} ; - SWAP ; - DUP ; - DUG 2 ; - DIG 6 ; - DUP ; - DUG 7 ; - CAR ; - SUB ; - ISNAT ; - IF_NONE { PUSH nat 15 ; FAILWITH } {} ; - DIG 4 ; - PUSH int 0 ; - SUB ; - SENDER ; - PAIR ; - DIG 6 ; - DUP ; - DUG 7 ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - DIG 2 ; - CDR ; - CDR ; - CDR ; - CDR ; - CONTRACT %mintOrBurn (pair (int %quantity) (address %target)) ; - IF_NONE { PUSH nat 12 ; FAILWITH } {} ; - PUSH mutez 0 ; - DIG 2 ; - DIG 3 ; - PAIR ; - TRANSFER_TOKENS ; - DIG 3 ; - DIG 5 ; - DUP ; - DUG 6 ; - PAIR ; - SELF ; - ADDRESS ; - PAIR ; - DIG 6 ; - DUP ; - DUG 7 ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - DIG 3 ; - CDR ; - CDR ; - CDR ; - CAR ; - CONTRACT %transfer (pair address (pair address nat)) ; - IF_NONE { PUSH nat 0 ; FAILWITH } {} ; - PUSH mutez 0 ; - DIG 3 ; - DIG 3 ; - PAIR ; - DIG 3 ; - PAIR ; - TRANSFER_TOKENS ; - DIG 4 ; - DUP ; - DUG 5 ; - DIG 6 ; - CONTRACT unit ; - IF_NONE { PUSH nat 9 ; FAILWITH } {} ; - SWAP ; - PUSH unit Unit ; - TRANSFER_TOKENS ; - DIG 6 ; - DUP ; - DUG 7 ; - CDR ; - CDR ; - DIG 6 ; - DIG 7 ; - DUP ; - DUG 8 ; - CDR ; - CAR ; - SUB ; - PAIR ; - DIG 6 ; - CAR ; - PAIR ; - DUP ; - CDR ; - CDR ; - CDR ; - DIG 6 ; - PAIR ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - CAR ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - CDR ; - DIG 4 ; - PAIR ; - NIL operation ; - DIG 2 ; - CONS ; - DIG 2 ; - CONS ; - DIG 2 ; - CONS ; - PAIR } } } } } - { DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - DIG 4 ; - CONTRACT %xtzToToken - (pair (address %to) (pair (nat %minTokensBought) (timestamp %deadline))) ; - IF_NONE { PUSH nat 31 ; FAILWITH } {} ; - PUSH mutez 0 ; - AMOUNT ; - COMPARE ; - GT ; - IF { DROP 6 ; PUSH nat 10 ; FAILWITH } - { DIG 2 ; - DUP ; - DUG 3 ; - NOW ; - COMPARE ; - GE ; - IF { DROP 6 ; PUSH nat 3 ; FAILWITH } - { PUSH nat 999 ; - DIG 2 ; - DUP ; - DUG 3 ; - MUL ; - PUSH nat 1000 ; - DIG 7 ; - DUP ; - DUG 8 ; - CAR ; - MUL ; - ADD ; - DIG 6 ; - DUP ; - DUG 7 ; - CDR ; - CAR ; - PUSH nat 999 ; - DIG 4 ; - DUP ; - DUG 5 ; - MUL ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - PUSH nat 1000 ; - PUSH nat 999 ; - DIG 2 ; - DUP ; - DUG 3 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DIG 7 ; - DUP ; - DUG 8 ; - CDR ; - DIG 4 ; - DUP ; - DUG 5 ; - DIG 9 ; - DUP ; - DUG 10 ; - CAR ; - ADD ; - PAIR ; - DUP ; - CDR ; - CDR ; - DIG 3 ; - DUP ; - DUG 4 ; - DIG 10 ; - CDR ; - CAR ; - SUB ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - DIG 4 ; - SELF ; - ADDRESS ; - PAIR ; - SENDER ; - PAIR ; - SWAP ; - DUP ; - DUG 2 ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - DIG 3 ; - CDR ; - CDR ; - CDR ; - CAR ; - CONTRACT %transfer (pair address (pair address nat)) ; - IF_NONE { PUSH nat 0 ; FAILWITH } {} ; - PUSH mutez 0 ; - DIG 3 ; - DIG 3 ; - PAIR ; - DIG 3 ; - PAIR ; - TRANSFER_TOKENS ; - DIG 4 ; - DIG 3 ; - DUP ; - DUG 4 ; - DIG 6 ; - DIG 8 ; - PAIR ; - DIG 7 ; - PAIR ; - TRANSFER_TOKENS ; - DIG 3 ; - DIG 4 ; - SUB ; - PUSH address "tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU" ; - CONTRACT unit ; - IF_NONE { PUSH nat 9 ; FAILWITH } {} ; - SWAP ; - PUSH unit Unit ; - TRANSFER_TOKENS ; - DIG 3 ; - NIL operation ; - DIG 2 ; - CONS ; - DIG 2 ; - CONS ; - DIG 2 ; - CONS ; - PAIR } } } } } - { IF_LEFT - { DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - NOW ; - COMPARE ; - GE ; - IF { DROP 4 ; PUSH nat 3 ; FAILWITH } - { PUSH mutez 0 ; - AMOUNT ; - COMPARE ; - GT ; - IF { DROP 4 ; PUSH nat 10 ; FAILWITH } - { PUSH nat 999 ; - DIG 2 ; - DUP ; - DUG 3 ; - MUL ; - PUSH nat 1000 ; - DIG 5 ; - DUP ; - DUG 6 ; - CAR ; - MUL ; - ADD ; - PUSH mutez 1 ; - DIG 5 ; - DUP ; - DUG 6 ; - CDR ; - CAR ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - PUSH nat 999 ; - DIG 4 ; - DUP ; - DUG 5 ; - MUL ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - PUSH mutez 1 ; - SWAP ; - MUL ; - PUSH nat 1000 ; - PUSH nat 999 ; - DIG 2 ; - DUP ; - DUG 3 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DIG 2 ; - SWAP ; - DUP ; - DUG 2 ; - COMPARE ; - LT ; - IF { DROP ; PUSH nat 8 ; FAILWITH } {} ; - DIG 2 ; - DUP ; - DUG 3 ; - SELF ; - ADDRESS ; - PAIR ; - SENDER ; - PAIR ; - DIG 5 ; - DUP ; - DUG 6 ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - DIG 3 ; - CDR ; - CDR ; - CDR ; - CAR ; - CONTRACT %transfer (pair address (pair address nat)) ; - IF_NONE { PUSH nat 0 ; FAILWITH } {} ; - PUSH mutez 0 ; - DIG 3 ; - DIG 3 ; - PAIR ; - DIG 3 ; - PAIR ; - TRANSFER_TOKENS ; - SWAP ; - DUP ; - DUG 2 ; - DIG 5 ; - CONTRACT unit ; - IF_NONE { PUSH nat 9 ; FAILWITH } {} ; - SWAP ; - PUSH unit Unit ; - TRANSFER_TOKENS ; - DIG 5 ; - DUP ; - DUG 6 ; - CDR ; - DIG 5 ; - DIG 6 ; - DUP ; - DUG 7 ; - CAR ; - ADD ; - PAIR ; - DUP ; - CDR ; - CDR ; - DIG 5 ; - DUP ; - DUG 6 ; - DIG 7 ; - CDR ; - CAR ; - SUB ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - DIG 3 ; - DIG 4 ; - SUB ; - PUSH address "tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU" ; - CONTRACT unit ; - IF_NONE { PUSH nat 9 ; FAILWITH } {} ; - SWAP ; - PUSH unit Unit ; - TRANSFER_TOKENS ; - SWAP ; - NIL operation ; - DIG 2 ; - CONS ; - DIG 2 ; - CONS ; - DIG 2 ; - CONS ; - PAIR } } } - { DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - NOW ; - COMPARE ; - GE ; - IF { DROP 3 ; PUSH nat 3 ; FAILWITH } - { PUSH mutez 1 ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - CAR ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - AMOUNT ; - PUSH mutez 1 ; - SWAP ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - PUSH nat 1000 ; - PUSH nat 999 ; - DIG 2 ; - DUP ; - DUG 3 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DUP ; - DIG 2 ; - SUB ; - ABS ; - PUSH nat 999 ; - DIG 2 ; - DUP ; - DUG 3 ; - MUL ; - PUSH nat 1000 ; - DIG 4 ; - MUL ; - ADD ; - DIG 5 ; - DUP ; - DUG 6 ; - CAR ; - PUSH nat 999 ; - DIG 4 ; - DUP ; - DUG 5 ; - MUL ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DIG 3 ; - SWAP ; - DUP ; - DUG 2 ; - COMPARE ; - LT ; - IF { DROP ; PUSH nat 18 ; FAILWITH } {} ; - DUP ; - DIG 5 ; - DUP ; - DUG 6 ; - CAR ; - SUB ; - ISNAT ; - IF_NONE { PUSH nat 19 ; FAILWITH } {} ; - DIG 5 ; - DUP ; - DUG 6 ; - CDR ; - CDR ; - PUSH mutez 1 ; - DIG 5 ; - MUL ; - DIG 6 ; - DUP ; - DUG 7 ; - CDR ; - CAR ; - ADD ; - PAIR ; - DIG 5 ; - CAR ; - PAIR ; - CDR ; - SWAP ; - PAIR ; - SWAP ; - DIG 3 ; - PAIR ; - SELF ; - ADDRESS ; - PAIR ; - SWAP ; - DUP ; - DUG 2 ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - SWAP ; - DUP ; - CDR ; - SWAP ; - CAR ; - DIG 3 ; - CDR ; - CDR ; - CDR ; - CAR ; - CONTRACT %transfer (pair address (pair address nat)) ; - IF_NONE { PUSH nat 0 ; FAILWITH } {} ; - PUSH mutez 0 ; - DIG 3 ; - DIG 3 ; - PAIR ; - DIG 3 ; - PAIR ; - TRANSFER_TOKENS ; - PUSH mutez 1 ; - DIG 3 ; - MUL ; - PUSH address "tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU" ; - CONTRACT unit ; - IF_NONE { PUSH nat 9 ; FAILWITH } {} ; - SWAP ; - PUSH unit Unit ; - TRANSFER_TOKENS ; - DIG 2 ; - NIL operation ; - DIG 2 ; - CONS ; - DIG 2 ; - CONS ; - PAIR } } } } } - diff --git a/src/proto_012_Psithaca/lib_protocol/contracts/lqt.bin b/src/proto_012_Psithaca/lib_protocol/contracts/lqt.bin deleted file mode 100644 index 4fa01f58526f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contracts/lqt.bin +++ /dev/null @@ -1 +0,0 @@ -0x020000070005000764076407640865046e00000008257370656e6465720462000000062576616c75650000000825617070726f766508650865046e00000006256f776e6572046e00000008257370656e646572000000082572657175657374065a0362000000092563616c6c6261636b0000000d25676574416c6c6f77616e636507640865046e00000006256f776e6572065a0362000000092563616c6c6261636b0000000b2567657442616c616e63650865046c000000082572657175657374065a0362000000092563616c6c6261636b0000000f25676574546f74616c537570706c7907640865045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e0865046e000000052566726f6d0765046e0000000325746f0462000000062576616c756500000009257472616e73666572050107650861036e03620000000725746f6b656e73076508610765046e00000006256f776e6572046e00000008257370656e64657203620000000b25616c6c6f77616e6365730765046e000000062561646d696e04620000000d25746f74616c5f737570706c7905020200000552032103170743036a000003130319033c072c020000001607430368010000000b446f6e7453656e6454657a03270200000000034c0316072e02000001b2072e0200000132072e02000000e2034c03210571000203170316034c0321057100020316034803420743036200000570000303210571000403170319032a07430362000005700003032105710004057000030321057100040329072f020000000607430362000002000000000319032a0314072c0200000020074303680100000015556e73616665416c6c6f77616e63654368616e676503270200000000057000030321057100040317031705700002057000030317074303620000034c03210571000203190325072c02000000060320053e0362020000000203460570000303500342034c03160342053d036d03420200000044034c032105700002053d036d034c03210571000203170743036a000005700004031703160570000403160329072f02000000060743036200000200000000034d031b03420200000074072e0200000042034c032105700002053d036d034c03210571000203170743036a00000570000403160570000403160329072f02000000060743036200000200000000034d031b03420200000026034c032105700002053d036d034c03170743036a000005700003031703170317034d031b0342020000035e072e020000013c034c03210571000203170317031603480319033c072c02000000140743036801000000094f6e6c7941646d696e03270200000000032103160570000203210571000303160570000203210571000303170329072f0200000006074303620000020000000003120356072f020000003607430368010000002b43616e6e6f74206275726e206d6f7265207468616e207468652074617267657427732062616c616e63652e03270200000000034c032105710002031605700003032105710004031703170317031203110570000303210571000403170570000403160743036200000570000403210571000503190325072c020000000a057000030320053e03620200000006057000030346057000040317035003420321057100020317031703160342034c032105710002031703160342034c03160342053d036d03420200000216034c03210571000203170316057000020321057100030316057000020321057100030316034803190325072c0200000002034c02000000a903480570000303210571000403160342057000030321057100040317031705700003032105710004057000020321057100030329072f02000000060743036200000200000000034b0356072f020000001d0743036801000000124e6f74456e6f756768416c6c6f77616e636503270200000000057000030743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c03460570000203500570000203210571000303170317057000020321057100030570000403210571000503160329072f02000000060743036200000200000000034b0356072f020000001b0743036801000000104e6f74456e6f75676842616c616e636503270200000000057000020743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c034605700003032105710004031603500570000203210571000303170317034c03210571000205700004032105710005031703160329072f020000000607430362000002000000000312034c0743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c034605700003031703160350057000020317034c0342032103170317057000020342034c03160342053d036d0342 diff --git a/src/proto_012_Psithaca/lib_protocol/contracts/lqt.mligo b/src/proto_012_Psithaca/lib_protocol/contracts/lqt.mligo deleted file mode 100644 index 7c2fa5012d1e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contracts/lqt.mligo +++ /dev/null @@ -1,164 +0,0 @@ -type transfer = - [@layout:comb] - { [@annot:from] address_from : address; - [@annot:to] address_to : address; - value : nat } - -type approve = - [@layout:comb] - { spender : address; - value : nat } - -type mintOrBurn = - [@layout:comb] - { quantity : int ; - target : address } - -type allowance_key = - [@layout:comb] - { owner : address; - spender : address } - -type getAllowance = - [@layout:comb] - { request : allowance_key; - callback : nat contract } - -type getBalance = - [@layout:comb] - { owner : address; - callback : nat contract } - -type getTotalSupply = - [@layout:comb] - { request : unit ; - callback : nat contract } - -type tokens = (address, nat) big_map -type allowances = (allowance_key, nat) big_map - -type storage = - [@layout:comb] - { tokens : tokens; - allowances : allowances; - admin : address; - total_supply : nat; - } - -type parameter = - | Transfer of transfer - | Approve of approve - | MintOrBurn of mintOrBurn - | GetAllowance of getAllowance - | GetBalance of getBalance - | GetTotalSupply of getTotalSupply - -type result = operation list * storage - -[@inline] -let maybe (n : nat) : nat option = - if n = 0n - then (None : nat option) - else Some n - -let transfer (param : transfer) (storage : storage) : result = - let allowances = storage.allowances in - let tokens = storage.tokens in - let allowances = - if Tezos.sender = param.address_from - then allowances - else - let allowance_key = { owner = param.address_from ; spender = Tezos.sender } in - let authorized_value = - match Big_map.find_opt allowance_key allowances with - | Some value -> value - | None -> 0n in - let authorized_value = - match is_nat (authorized_value - param.value) with - | None -> (failwith "NotEnoughAllowance" : nat) - | Some authorized_value -> authorized_value in - Big_map.update allowance_key (maybe authorized_value) allowances in - let tokens = - let from_balance = - match Big_map.find_opt param.address_from tokens with - | Some value -> value - | None -> 0n in - let from_balance = - match is_nat (from_balance - param.value) with - | None -> (failwith "NotEnoughBalance" : nat) - | Some from_balance -> from_balance in - Big_map.update param.address_from (maybe from_balance) tokens in - let tokens = - let to_balance = - match Big_map.find_opt param.address_to tokens with - | Some value -> value - | None -> 0n in - let to_balance = to_balance + param.value in - Big_map.update param.address_to (maybe to_balance) tokens in - (([] : operation list), { storage with tokens = tokens; allowances = allowances }) - -let approve (param : approve) (storage : storage) : result = - let allowances = storage.allowances in - let allowance_key = { owner = Tezos.sender ; spender = param.spender } in - let previous_value = - match Big_map.find_opt allowance_key allowances with - | Some value -> value - | None -> 0n in - begin - if previous_value > 0n && param.value > 0n - then (failwith "UnsafeAllowanceChange") - else (); - let allowances = Big_map.update allowance_key (maybe param.value) allowances in - (([] : operation list), { storage with allowances = allowances }) - end - -let mintOrBurn (param : mintOrBurn) (storage : storage) : result = - begin - if Tezos.sender <> storage.admin - then failwith "OnlyAdmin" - else (); - let tokens = storage.tokens in - let old_balance = - match Big_map.find_opt param.target tokens with - | None -> 0n - | Some bal -> bal in - let new_balance = - match is_nat (old_balance + param.quantity) with - | None -> (failwith "Cannot burn more than the target's balance." : nat) - | Some bal -> bal in - let tokens = Big_map.update param.target (maybe new_balance) storage.tokens in - let total_supply = abs (storage.total_supply + param.quantity) in - (([] : operation list), { storage with tokens = tokens ; total_supply = total_supply }) - end - -let getAllowance (param : getAllowance) (storage : storage) : operation list = - let value = - match Big_map.find_opt param.request storage.allowances with - | Some value -> value - | None -> 0n in - [Tezos.transaction value 0mutez param.callback] - -let getBalance (param : getBalance) (storage : storage) : operation list = - let value = - match Big_map.find_opt param.owner storage.tokens with - | Some value -> value - | None -> 0n in - [Tezos.transaction value 0mutez param.callback] - -let getTotalSupply (param : getTotalSupply) (storage : storage) : operation list = - let total = storage.total_supply in - [Tezos.transaction total 0mutez param.callback] - -let main (param, storage : parameter * storage) : result = - begin - if Tezos.amount <> 0mutez - then failwith "DontSendTez" - else (); - match param with - | Transfer param -> transfer param storage - | Approve param -> approve param storage - | MintOrBurn param -> mintOrBurn param storage - | GetAllowance param -> (getAllowance param storage, storage) - | GetBalance param -> (getBalance param storage, storage) - | GetTotalSupply param -> (getTotalSupply param storage, storage) - end diff --git a/src/proto_012_Psithaca/lib_protocol/contracts/lqt.tz b/src/proto_012_Psithaca/lib_protocol/contracts/lqt.tz deleted file mode 100644 index d0f5f45fd05f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/contracts/lqt.tz +++ /dev/null @@ -1,327 +0,0 @@ -{ parameter - (or (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (pair (address %to) (nat %value))))) ; - storage - (pair (big_map %tokens address nat) - (pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (pair (address %admin) (nat %total_supply)))) ; - code { DUP ; - CDR ; - PUSH mutez 0 ; - AMOUNT ; - COMPARE ; - NEQ ; - IF { PUSH string "DontSendTez" ; FAILWITH } {} ; - SWAP ; - CAR ; - IF_LEFT - { IF_LEFT - { IF_LEFT - { SWAP ; - DUP ; - DUG 2 ; - CDR ; - CAR ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - SENDER ; - PAIR ; - PUSH nat 0 ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - COMPARE ; - GT ; - PUSH nat 0 ; - DIG 3 ; - DUP ; - DUG 4 ; - DIG 3 ; - DUP ; - DUG 4 ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - COMPARE ; - GT ; - AND ; - IF { PUSH string "UnsafeAllowanceChange" ; FAILWITH } {} ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - CDR ; - DIG 2 ; - DIG 3 ; - CDR ; - PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; - COMPARE ; - EQ ; - IF { DROP ; NONE nat } { SOME } ; - DIG 3 ; - UPDATE ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - NIL operation ; - PAIR } - { SWAP ; - DUP ; - DIG 2 ; - NIL operation ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - PUSH mutez 0 ; - DIG 4 ; - CDR ; - CAR ; - DIG 4 ; - CAR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - TRANSFER_TOKENS ; - CONS ; - PAIR } } - { IF_LEFT - { SWAP ; - DUP ; - DIG 2 ; - NIL operation ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - PUSH mutez 0 ; - DIG 4 ; - CAR ; - DIG 4 ; - CAR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - TRANSFER_TOKENS ; - CONS ; - PAIR } - { SWAP ; - DUP ; - DIG 2 ; - NIL operation ; - SWAP ; - CDR ; - PUSH mutez 0 ; - DIG 3 ; - CDR ; - CDR ; - CDR ; - TRANSFER_TOKENS ; - CONS ; - PAIR } } } - { IF_LEFT - { SWAP ; - DUP ; - DUG 2 ; - CDR ; - CDR ; - CAR ; - SENDER ; - COMPARE ; - NEQ ; - IF { PUSH string "OnlyAdmin" ; FAILWITH } {} ; - DUP ; - CAR ; - DIG 2 ; - DUP ; - DUG 3 ; - CAR ; - DIG 2 ; - DUP ; - DUG 3 ; - CDR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - ADD ; - ISNAT ; - IF_NONE - { PUSH string "Cannot burn more than the target's balance." ; FAILWITH } - {} ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - CDR ; - CDR ; - ADD ; - ABS ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - DIG 4 ; - CAR ; - PUSH nat 0 ; - DIG 4 ; - DUP ; - DUG 5 ; - COMPARE ; - EQ ; - IF { DIG 3 ; DROP ; NONE nat } { DIG 3 ; SOME } ; - DIG 4 ; - CDR ; - UPDATE ; - PAIR ; - DUP ; - DUG 2 ; - CDR ; - CDR ; - CAR ; - PAIR ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - CAR ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - NIL operation ; - PAIR } - { SWAP ; - DUP ; - DUG 2 ; - CDR ; - CAR ; - DIG 2 ; - DUP ; - DUG 3 ; - CAR ; - DIG 2 ; - DUP ; - DUG 3 ; - CAR ; - SENDER ; - COMPARE ; - EQ ; - IF { SWAP } - { SENDER ; - DIG 3 ; - DUP ; - DUG 4 ; - CAR ; - PAIR ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - CDR ; - DIG 3 ; - DUP ; - DUG 4 ; - DIG 2 ; - DUP ; - DUG 3 ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - SUB ; - ISNAT ; - IF_NONE { PUSH string "NotEnoughAllowance" ; FAILWITH } {} ; - DIG 3 ; - PUSH nat 0 ; - DIG 2 ; - DUP ; - DUG 3 ; - COMPARE ; - EQ ; - IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; - DIG 2 ; - UPDATE } ; - DIG 2 ; - DUP ; - DUG 3 ; - CDR ; - CDR ; - DIG 2 ; - DUP ; - DUG 3 ; - DIG 4 ; - DUP ; - DUG 5 ; - CAR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - SUB ; - ISNAT ; - IF_NONE { PUSH string "NotEnoughBalance" ; FAILWITH } {} ; - DIG 2 ; - PUSH nat 0 ; - DIG 2 ; - DUP ; - DUG 3 ; - COMPARE ; - EQ ; - IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; - DIG 3 ; - DUP ; - DUG 4 ; - CAR ; - UPDATE ; - DIG 2 ; - DUP ; - DUG 3 ; - CDR ; - CDR ; - SWAP ; - DUP ; - DUG 2 ; - DIG 4 ; - DUP ; - DUG 5 ; - CDR ; - CAR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - ADD ; - SWAP ; - PUSH nat 0 ; - DIG 2 ; - DUP ; - DUG 3 ; - COMPARE ; - EQ ; - IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; - DIG 3 ; - CDR ; - CAR ; - UPDATE ; - DIG 2 ; - CDR ; - SWAP ; - PAIR ; - DUP ; - CDR ; - CDR ; - DIG 2 ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - NIL operation ; - PAIR } } } } - diff --git a/src/proto_012_Psithaca/lib_protocol/coq-of-ocaml/README.md b/src/proto_012_Psithaca/lib_protocol/coq-of-ocaml/README.md deleted file mode 100644 index dc8bbda5de5e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/coq-of-ocaml/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# coq-of-ocaml - -In this folder we put the files relevant to the compilation of the protocol to -Coq using [coq-of-ocaml](https://clarus.github.io/coq-of-ocaml/). The code of -the protocol is annotated with `[@coq_...]` OCaml attributes. These attributes -are here to help the compilation to Coq. We document them on: -https://clarus.github.io/coq-of-ocaml/docs/attributes - -* `config.json` This file describes the configuration parameters for - coq-of-ocaml in the CI. For more information, see the - [documentation](https://clarus.github.io/coq-of-ocaml/docs/configuration). diff --git a/src/proto_012_Psithaca/lib_protocol/coq-of-ocaml/config.json b/src/proto_012_Psithaca/lib_protocol/coq-of-ocaml/config.json deleted file mode 100644 index 4a89eaa686dd..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/coq-of-ocaml/config.json +++ /dev/null @@ -1,255 +0,0 @@ -{ - "alias_barrier_modules": [ - "Tezos_protocol_environment_alpha__Environment" - ], - "constant_warning": false, - "constructor_map": [ - ["public_key_hash", "Ed25519", "Ed25519Hash"], - ["public_key_hash", "P256", "P256Hash"], - ["public_key_hash", "Secp256k1", "Secp256k1Hash"] - ], - "error_category_blacklist": [ - "side_effect" - ], - "error_filename_blacklist": [ - ], - "error_message_blacklist": [ - "Unbound module Tezos_protocol_012_Psithaca_functor", - "The placeholders `_` in types are not handled", - "No type known for the following variants: `Ge, `Lt, `Eq, `Le, `Gt", - "No type known for the following variants: `Eq, `Ge, `Gt, `Le, `Lt", - "No type known for the following variants: `Eq", - "Constructor of the variant `Eq unknown", - "No type known for the following variants: `Tree, `Value", - "Constructor of the variant `Tree unknown", - "Constructor of the variant `Value unknown", - "Anonymous definition of signatures is not handled", - "A variable name instead of a pattern was expected", - "We only support extensible types in patterns at the head", - "This kind of signature is not handled", - "Tezos_raw_protocol_012_Psithaca.Raw_context_intf.T", - "No type known for the following variants:", - "Constructor of the variant", - "Polymorphic variant types are defined as standard algebraic types" - ], - "escape_value": [ - "a", - "acc", - "alloc", - "b", - "baking_rights_query", - "case", - "cons", - "context", - "descr", - "diff", - "elt", - "endorsing_rights_query", - "eq", - "error", - "field", - "fixed", - "fp", - "frozen_balance", - "gas_counter_status", - "handler", - "has_big_map", - "has_lazy_storage", - "hash", - "info", - "init", - "integral", - "internal_gas", - "json", - "json_schema", - "judgement", - "key", - "kind", - "l", - "lazy_expr", - "level_query", - "list_query", - "may_saturate", - "mul_safe", - "namespace", - "nonce", - "query", - "p", - "parametric", - "r", - "raw", - "seed", - "sequence", - "snapshot", - "stack", - "storage", - "storage_error", - "t", - "tc_context", - "toplevel", - "trace", - "type_logger" - ], - "first_class_module_path_blacklist": [ - "Tezos_raw_protocol_012_Psithaca", - "Tezos_protocol_environment_alpha.Environment", - "Tezos_protocol_environment_alpha.Environment.Sapling" - ], - "first_class_module_signature_blacklist": [ - "Environment_context.TREE", - "Tezos_protocol_environment_alpha__Environment.Map.OrderedType", - "Tezos_protocol_environment_alpha__Environment.Set.OrderedType", - "Tezos_raw_protocol_012_Psithaca__Raw_context.T", - "Tezos_raw_protocol_012_Psithaca.Alpha_context.Cache.CLIENT", - "Tezos_raw_protocol_012_Psithaca.Alpha_context.Cache.INTERFACE", - "Tezos_sapling__Core_sig.T_encoding" - ], - "merge_returns": [ - ["return=", "return?", "return=?"] - ], - "merge_types": [ - ["M=", "M?", "M=?"] - ], - "monadic_lets": [ - ["Error_monad.op_gtgteq", "let="], - ["Error_monad.op_gtgteqquestion", "let=?"], - ["Error_monad.op_gtgtquestion", "let?"] - ], - "monadic_let_returns": [ - ["Error_monad.op_gtpipeeq", "let=", "return="], - ["Error_monad.op_gtpipeeqquestion", "let=?", "return=?"], - ["Error_monad.op_gtpipequestion", "let?", "return?"] - ], - "monadic_returns": [ - ["Lwt.__return", "return="], - ["Error_monad.__return", "return=?"], - ["Error_monad.ok", "return?"] - ], - "monadic_return_lets": [ - ["Error_monad.op_gtgtquestioneq", "return=", "let=?"] - ], - "operator_infix": [ - ["Compare.Int.(Compare.S.op_eq)", "=i"], - ["Compare.Int.(Compare.S.op_ltgt)", "<>i"], - ["Compare.Int.(Compare.S.op_lteq)", "<=i"], - ["Compare.Int.(Compare.S.op_lt)", "=i"], - ["Compare.Int.(Compare.S.op_gt)", ">i"], - - ["Compare.Int32.(Compare.S.op_eq)", "=i32"], - ["Compare.Int32.(Compare.S.op_ltgt)", "<>i32"], - ["Compare.Int32.(Compare.S.op_lteq)", "<=i32"], - ["Compare.Int32.(Compare.S.op_lt)", "=i32"], - ["Compare.Int32.(Compare.S.op_gt)", ">i32"], - - ["Compare.Int64.(Compare.S.op_eq)", "=i64"], - ["Compare.Int64.(Compare.S.op_ltgt)", "<>i64"], - ["Compare.Int64.(Compare.S.op_lteq)", "<=i64"], - ["Compare.Int64.(Compare.S.op_lt)", "=i64"], - ["Compare.Int64.(Compare.S.op_gt)", ">i64"], - - ["Compare.Z.(Compare.S.op_eq)", "=Z"], - ["Compare.Z.(Compare.S.op_ltgt)", "<>Z"], - ["Compare.Z.(Compare.S.op_lteq)", "<=Z"], - ["Compare.Z.(Compare.S.op_lt)", "=Z"], - ["Compare.Z.(Compare.S.op_gt)", ">Z"], - - ["Int32.add", "+i32"], - ["Int32.sub", "-i32"], - ["Int32.mul", "*i32"], - ["Int32.div", "/i32"], - - ["Int64.add", "+i64"], - ["Int64.sub", "-i64"], - ["Int64.mul", "*i64"], - ["Int64.div", "/i64"], - - ["Pervasives.op_andand", "&&"], - ["Pervasives.op_pipepipe", "||"], - - ["Pervasives.op_plus", "+i"], - ["Pervasives.op_minus", "-i"], - ["Pervasives.op_star", "*i"], - ["Pervasives.op_div", "/i"], - - ["Z.add", "+Z"], - ["Z.sub", "-Z"], - ["Z.mul", "*Z"], - ["Z.div", "/Z"], - - ["Z_syntax.op_plus", "+Z"], - ["Z_syntax.op_star", "*Z"] - ], - "renaming_rules": [ - ["Error_monad.tzresult", "M?"], - ["Lwt.t", "M="], - ["Failure", "Failure"] - ], - "renaming_type_constructor": [ - ["Compare.Char.(Compare.S.t)", "ascii"], - ["Compare.Int.(Compare.S.t)", "int"], - ["Compare.Int32.(Compare.S.t)", "int32"], - ["Compare.Int64.(Compare.S.t)", "int64"], - ["Compare.String.(Compare.S.t)", "string"], - ["Compare.Z.(Compare.S.t)", "Z.t"] - ], - "require": [ - ["Tezos_raw_protocol_012_Psithaca", "TezosOfOCaml.Proto_alpha"] - ], - "require_import": [ - ["Tezos_protocol_environment_alpha", "TezosOfOCaml.Proto_alpha"] - ], - "require_long_ident": [ - ["Storage_description", "TezosOfOCaml.Proto_alpha"] - ], - "require_mli": [ - ], - "variant_constructors": [ - ["Dir", "Context.Dir"], - ["Key", "Context.Key"], - ["Uint16", "Data_encoding.Uint16"], - ["Uint8", "Data_encoding.Uint8"], - ["Hex", "Hex.Hex"], - ["Branch", "Error_monad.Branch"], - ["Permanent", "Error_monad.Permanent"], - ["Temporary", "Error_monad.Temporary"] - ], - "variant_types": [ - ["Dir", "Context.key_or_dir"], - ["Key", "Context.key_or_dir"] - ], - "without_guard_checking": [ - "apply.ml", - "apply_results.ml", - "baking.ml", - "contract_repr.ml", - "delegate_services.ml", - "fixed_point_repr.ml", - "helpers_services.ml", - "lazy_storage_kind.ml", - "legacy_script_support_repr.ml", - "level_storage.ml", - "michelson_v1_gas.ml", - "michelson_v1_primitives.ml", - "misc.ml", - "operation_repr.ml", - "raw_context.ml", - "roll_storage.ml", - "sapling_storage.ml", - "script_interpreter.ml", - "script_ir_annot.ml", - "script_ir_translator.ml", - "script_repr.ml", - "seed_repr.ml", - "storage_description.ml", - "storage_functors.ml", - "tez_repr.ml" - ], - "without_positivity_checking": [ - "misc.ml", - "storage_description.ml" - ] -} diff --git a/src/proto_012_Psithaca/lib_protocol/cycle_repr.ml b/src/proto_012_Psithaca/lib_protocol/cycle_repr.ml deleted file mode 100644 index b1a4b8bc6e0b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/cycle_repr.ml +++ /dev/null @@ -1,85 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = int32 - -type cycle = t - -let encoding = Data_encoding.int32 - -let rpc_arg = RPC_arg.like RPC_arg.uint31 ~descr:"A cycle integer" "block_cycle" - -let pp ppf cycle = Format.fprintf ppf "%ld" cycle - -include (Compare.Int32 : Compare.S with type t := t) - -module Map = Map.Make (Compare.Int32) - -let root = 0l - -let succ = Int32.succ - -let pred = function 0l -> None | i -> Some (Int32.pred i) - -let add c i = - assert (Compare.Int.(i >= 0)) ; - Int32.add c (Int32.of_int i) - -let sub c i = - assert (Compare.Int.(i >= 0)) ; - let r = Int32.sub c (Int32.of_int i) in - if Compare.Int32.(r < 0l) then None else Some r - -let diff = Int32.sub - -let to_int32 i = i - -let of_int32_exn l = - if Compare.Int32.(l >= 0l) then l else invalid_arg "Cycle_repr.of_int32_exn" - -let of_string_exn s = - let int32_opt = Int32.of_string_opt s in - match int32_opt with - | None -> invalid_arg "Cycle_repr.of_string_exn" - | Some int32 -> of_int32_exn int32 - -let ( ---> ) = Misc.( ---> ) - -module Index = struct - type t = cycle - - let path_length = 1 - - let to_path c l = Int32.to_string (to_int32 c) :: l - - let of_path = function [s] -> Int32.of_string_opt s | _ -> None - - let rpc_arg = rpc_arg - - let encoding = encoding - - let compare = compare -end diff --git a/src/proto_012_Psithaca/lib_protocol/cycle_repr.mli b/src/proto_012_Psithaca/lib_protocol/cycle_repr.mli deleted file mode 100644 index bfd7a7b66db3..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/cycle_repr.mli +++ /dev/null @@ -1,61 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t - -type cycle = t - -include Compare.S with type t := t - -val encoding : cycle Data_encoding.t - -val rpc_arg : cycle RPC_arg.arg - -val pp : Format.formatter -> cycle -> unit - -val root : cycle - -val pred : cycle -> cycle option - -val add : cycle -> int -> cycle - -val sub : cycle -> int -> cycle option - -val succ : cycle -> cycle - -val diff : cycle -> cycle -> int32 - -(** a ---> b = [a; ...; b] *) -val ( ---> ) : cycle -> cycle -> cycle list - -val to_int32 : cycle -> int32 - -val of_int32_exn : int32 -> cycle - -val of_string_exn : string -> cycle - -module Map : Map.S with type key = cycle - -module Index : Storage_description.INDEX with type t = cycle diff --git a/src/proto_012_Psithaca/lib_protocol/delegate_activation_storage.ml b/src/proto_012_Psithaca/lib_protocol/delegate_activation_storage.ml deleted file mode 100644 index 2d090108f20b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/delegate_activation_storage.ml +++ /dev/null @@ -1,87 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let is_inactive ctxt delegate = - Storage.Contract.Inactive_delegate.mem - ctxt - (Contract_repr.implicit_contract delegate) - >>= fun inactive -> - if inactive then return inactive - else - Storage.Contract.Delegate_desactivation.find - ctxt - (Contract_repr.implicit_contract delegate) - >|=? function - | Some last_active_cycle -> - let ({Level_repr.cycle = current_cycle; _} : Level_repr.t) = - Raw_context.current_level ctxt - in - Cycle_repr.(last_active_cycle < current_cycle) - | None -> - (* This case is only when called from `set_active`, when creating - a contract. *) - false - -let grace_period ctxt delegate = - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Delegate_desactivation.get ctxt contract - -let set_inactive = Storage.Contract.Inactive_delegate.add - -let set_active ctxt delegate = - is_inactive ctxt delegate >>=? fun inactive -> - let current_cycle = (Raw_context.current_level ctxt).cycle in - let preserved_cycles = Constants_storage.preserved_cycles ctxt in - (* We allow a number of cycles before a delegate is deactivated as follows: - - if the delegate is active, we give it at least `1 + preserved_cycles` - after the current cycle before to be deactivated. - - if the delegate is new or inactive, we give it additionally - `preserved_cycles` because the delegate needs this number of cycles to - receive rights, so `1 + 2 * preserved_cycles` in total. *) - Storage.Contract.Delegate_desactivation.find - ctxt - (Contract_repr.implicit_contract delegate) - >>=? fun current_last_active_cycle -> - let last_active_cycle = - match current_last_active_cycle with - | None -> Cycle_repr.add current_cycle (1 + (2 * preserved_cycles)) - | Some current_last_active_cycle -> - let delay = - if inactive then 1 + (2 * preserved_cycles) else 1 + preserved_cycles - in - let updated = Cycle_repr.add current_cycle delay in - Cycle_repr.max current_last_active_cycle updated - in - Storage.Contract.Delegate_desactivation.add - ctxt - (Contract_repr.implicit_contract delegate) - last_active_cycle - >>= fun ctxt -> - if not inactive then return (ctxt, inactive) - else - Storage.Contract.Inactive_delegate.remove - ctxt - (Contract_repr.implicit_contract delegate) - >>= fun ctxt -> return (ctxt, inactive) diff --git a/src/proto_012_Psithaca/lib_protocol/delegate_activation_storage.mli b/src/proto_012_Psithaca/lib_protocol/delegate_activation_storage.mli deleted file mode 100644 index e18ca676079e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/delegate_activation_storage.mli +++ /dev/null @@ -1,39 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val is_inactive : - Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t - -(** [grace_period ctxt delegate] is the cycle at which the delegate is - scheduled to become inactive. *) -val grace_period : - Raw_context.t -> Signature.Public_key_hash.t -> Cycle_repr.t tzresult Lwt.t - -val set_inactive : Raw_context.t -> Contract_repr.t -> Raw_context.t Lwt.t - -val set_active : - Raw_context.t -> - Signature.Public_key_hash.t -> - (Raw_context.t * bool) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/delegate_services.ml b/src/proto_012_Psithaca/lib_protocol/delegate_services.ml deleted file mode 100644 index 1595f62f5802..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/delegate_services.ml +++ /dev/null @@ -1,418 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -type error += Balance_rpc_non_delegate of public_key_hash - -let () = - register_error_kind - `Temporary - ~id:"delegate_service.balance_rpc_on_non_delegate" - ~title:"Balance request for an unregistered delegate" - ~description:"The account whose balance was requested is not a delegate." - ~pp:(fun ppf pkh -> - Format.fprintf - ppf - "The implicit account (%a) whose balance was requested is not a \ - registered delegate. To get the balance of this account you can use \ - the ../context/contracts/%a/balance RPC." - Signature.Public_key_hash.pp - pkh - Signature.Public_key_hash.pp - pkh) - Data_encoding.(obj1 (req "pkh" Signature.Public_key_hash.encoding)) - (function Balance_rpc_non_delegate pkh -> Some pkh | _ -> None) - (fun pkh -> Balance_rpc_non_delegate pkh) - -type info = { - full_balance : Tez.t; - current_frozen_deposits : Tez.t; - frozen_deposits : Tez.t; - staking_balance : Tez.t; - frozen_deposits_limit : Tez.t option; - delegated_contracts : Contract.t list; - delegated_balance : Tez.t; - deactivated : bool; - grace_period : Cycle.t; - voting_power : int32; -} - -let info_encoding = - let open Data_encoding in - conv - (fun { - full_balance; - current_frozen_deposits; - frozen_deposits; - staking_balance; - frozen_deposits_limit; - delegated_contracts; - delegated_balance; - deactivated; - grace_period; - voting_power; - } -> - ( full_balance, - current_frozen_deposits, - frozen_deposits, - staking_balance, - frozen_deposits_limit, - delegated_contracts, - delegated_balance, - deactivated, - grace_period, - voting_power )) - (fun ( full_balance, - current_frozen_deposits, - frozen_deposits, - staking_balance, - frozen_deposits_limit, - delegated_contracts, - delegated_balance, - deactivated, - grace_period, - voting_power ) -> - { - full_balance; - current_frozen_deposits; - frozen_deposits; - staking_balance; - frozen_deposits_limit; - delegated_contracts; - delegated_balance; - deactivated; - grace_period; - voting_power; - }) - (obj10 - (req "full_balance" Tez.encoding) - (req "current_frozen_deposits" Tez.encoding) - (req "frozen_deposits" Tez.encoding) - (req "staking_balance" Tez.encoding) - (opt "frozen_deposits_limit" Tez.encoding) - (req "delegated_contracts" (list Contract.encoding)) - (req "delegated_balance" Tez.encoding) - (req "deactivated" bool) - (req "grace_period" Cycle.encoding) - (req "voting_power" int32)) - -let participation_info_encoding = - let open Data_encoding in - conv - (fun { - Delegate.expected_cycle_activity; - minimal_cycle_activity; - missed_slots; - missed_levels; - remaining_allowed_missed_slots; - expected_endorsing_rewards; - } -> - ( expected_cycle_activity, - minimal_cycle_activity, - missed_slots, - missed_levels, - remaining_allowed_missed_slots, - expected_endorsing_rewards )) - (fun ( expected_cycle_activity, - minimal_cycle_activity, - missed_slots, - missed_levels, - remaining_allowed_missed_slots, - expected_endorsing_rewards ) -> - { - expected_cycle_activity; - minimal_cycle_activity; - missed_slots; - missed_levels; - remaining_allowed_missed_slots; - expected_endorsing_rewards; - }) - (obj6 - (req "expected_cycle_activity" int31) - (req "minimal_cycle_activity" int31) - (req "missed_slots" int31) - (req "missed_levels" int31) - (req "remaining_allowed_missed_slots" int31) - (req "expected_endorsing_rewards" Tez.encoding)) - -module S = struct - let raw_path = RPC_path.(open_root / "context" / "delegates") - - open Data_encoding - - type list_query = {active : bool; inactive : bool} - - let list_query : list_query RPC_query.t = - let open RPC_query in - query (fun active inactive -> {active; inactive}) - |+ flag "active" (fun t -> t.active) - |+ flag "inactive" (fun t -> t.inactive) - |> seal - - let list_delegate = - RPC_service.get_service - ~description:"Lists all registered delegates." - ~query:list_query - ~output:(list Signature.Public_key_hash.encoding) - raw_path - - let path = RPC_path.(raw_path /: Signature.Public_key_hash.rpc_arg) - - let info = - RPC_service.get_service - ~description:"Everything about a delegate." - ~query:RPC_query.empty - ~output:info_encoding - path - - let full_balance = - RPC_service.get_service - ~description: - "Returns the full balance (in mutez) of a given delegate, including \ - the frozen deposits. It does not include its delegated balance." - ~query:RPC_query.empty - ~output:Tez.encoding - RPC_path.(path / "full_balance") - - let current_frozen_deposits = - RPC_service.get_service - ~description: - "Returns the current amount of the frozen deposits (in mutez)." - ~query:RPC_query.empty - ~output:Tez.encoding - RPC_path.(path / "current_frozen_deposits") - - let frozen_deposits = - RPC_service.get_service - ~description: - "Returns the initial amount (that is, at the beginning of a cycle) of \ - the frozen deposits (in mutez). This amount is the same as the \ - current amount of the frozen deposits, unless the delegate has been \ - punished." - ~query:RPC_query.empty - ~output:Tez.encoding - RPC_path.(path / "frozen_deposits") - - let staking_balance = - RPC_service.get_service - ~description: - "Returns the total amount of tokens (in mutez) delegated to a given \ - delegate. This includes the balances of all the contracts that \ - delegate to it, but also the balance of the delegate itself and its \ - frozen deposits." - ~query:RPC_query.empty - ~output:Tez.encoding - RPC_path.(path / "staking_balance") - - let frozen_deposits_limit = - RPC_service.get_service - ~description: - "Returns the frozen deposits limit for the given delegate or none if \ - no limit is set." - ~query:RPC_query.empty - ~output:(Data_encoding.option Tez.encoding) - RPC_path.(path / "frozen_deposits_limit") - - let delegated_contracts = - RPC_service.get_service - ~description: - "Returns the list of contracts that delegate to a given delegate." - ~query:RPC_query.empty - ~output:(list Contract.encoding) - RPC_path.(path / "delegated_contracts") - - let delegated_balance = - RPC_service.get_service - ~description: - "Returns the sum (in mutez) of all balances of all the contracts that \ - delegate to a given delegate. This excludes the delegate's own \ - balance and its frozen deposits." - ~query:RPC_query.empty - ~output:Tez.encoding - RPC_path.(path / "delegated_balance") - - let deactivated = - RPC_service.get_service - ~description: - "Tells whether the delegate is currently tagged as deactivated or not." - ~query:RPC_query.empty - ~output:bool - RPC_path.(path / "deactivated") - - let grace_period = - RPC_service.get_service - ~description: - "Returns the cycle by the end of which the delegate might be \ - deactivated if she fails to execute any delegate action. A \ - deactivated delegate might be reactivated (without loosing any stake) \ - by simply re-registering as a delegate. For deactivated delegates, \ - this value contains the cycle at which they were deactivated." - ~query:RPC_query.empty - ~output:Cycle.encoding - RPC_path.(path / "grace_period") - - let voting_power = - RPC_service.get_service - ~description: - "The number of rolls in the vote listings for a given delegate" - ~query:RPC_query.empty - ~output:Data_encoding.int32 - RPC_path.(path / "voting_power") - - let participation = - RPC_service.get_service - ~description: - "Returns cycle and level participation information. In particular this \ - indicates, in the field 'expected_cycle_activity', the number of \ - slots the delegate is expected to have in the cycle based on its \ - active stake. The field 'minimal_cycle_activity' indicates the \ - minimal endorsing slots in the cycle required to get endorsing \ - rewards. It is computed based on 'expected_cycle_activity. The fields \ - 'missed_slots' and 'missed_levels' indicate the number of missed \ - endorsing slots and missed levels (for endorsing) in the cycle so \ - far. 'missed_slots' indicates the number of missed endorsing slots in \ - the cycle so far. The field 'remaining_allowed_missed_slots' \ - indicates the remaining amount of endorsing slots that can be missed \ - in the cycle before forfeiting the rewards. Finally, \ - 'expected_endorsing_rewards' indicates the endorsing rewards that \ - will be distributed at the end of the cycle if activity at that point \ - will be greater than the minimal required; if the activity is already \ - known to be below the required minimum, then the rewards are zero." - ~query:RPC_query.empty - ~output:participation_info_encoding - RPC_path.(path / "participation") -end - -let register () = - let open Services_registration in - register0 ~chunked:true S.list_delegate (fun ctxt q () -> - Delegate.list ctxt >>= fun delegates -> - match q with - | {active = true; inactive = false} -> - List.filter_es - (fun pkh -> Delegate.deactivated ctxt pkh >|=? not) - delegates - | {active = false; inactive = true} -> - List.filter_es (fun pkh -> Delegate.deactivated ctxt pkh) delegates - | _ -> return delegates) ; - register1 ~chunked:false S.info (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.full_balance ctxt pkh >>=? fun full_balance -> - Delegate.frozen_deposits ctxt pkh >>=? fun frozen_deposits -> - Delegate.staking_balance ctxt pkh >>=? fun staking_balance -> - Delegate.frozen_deposits_limit ctxt pkh >>=? fun frozen_deposits_limit -> - Delegate.delegated_contracts ctxt pkh >>= fun delegated_contracts -> - Delegate.delegated_balance ctxt pkh >>=? fun delegated_balance -> - Delegate.deactivated ctxt pkh >>=? fun deactivated -> - Delegate.grace_period ctxt pkh >>=? fun grace_period -> - Vote.get_voting_power_free ctxt pkh >|=? fun voting_power -> - { - full_balance; - current_frozen_deposits = frozen_deposits.current_amount; - frozen_deposits = frozen_deposits.initial_amount; - staking_balance; - frozen_deposits_limit; - delegated_contracts; - delegated_balance; - deactivated; - grace_period; - voting_power; - }) ; - register1 ~chunked:false S.full_balance (fun ctxt pkh () () -> - trace (Balance_rpc_non_delegate pkh) (Delegate.check_delegate ctxt pkh) - >>=? fun () -> Delegate.full_balance ctxt pkh) ; - register1 ~chunked:false S.current_frozen_deposits (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.frozen_deposits ctxt pkh >>=? fun deposits -> - return deposits.current_amount) ; - register1 ~chunked:false S.frozen_deposits (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.frozen_deposits ctxt pkh >>=? fun deposits -> - return deposits.initial_amount) ; - register1 ~chunked:false S.staking_balance (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.staking_balance ctxt pkh) ; - register1 ~chunked:false S.frozen_deposits_limit (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.frozen_deposits_limit ctxt pkh) ; - register1 ~chunked:true S.delegated_contracts (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.delegated_contracts ctxt pkh >|= ok) ; - register1 ~chunked:false S.delegated_balance (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.delegated_balance ctxt pkh) ; - register1 ~chunked:false S.deactivated (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.deactivated ctxt pkh) ; - register1 ~chunked:false S.grace_period (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.grace_period ctxt pkh) ; - register1 ~chunked:false S.voting_power (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Vote.get_voting_power_free ctxt pkh) ; - register1 ~chunked:false S.participation (fun ctxt pkh () () -> - Delegate.check_delegate ctxt pkh >>=? fun () -> - Delegate.delegate_participation_info ctxt pkh) - -let list ctxt block ?(active = true) ?(inactive = false) () = - RPC_context.make_call0 S.list_delegate ctxt block {active; inactive} () - -let info ctxt block pkh = RPC_context.make_call1 S.info ctxt block pkh () () - -let full_balance ctxt block pkh = - RPC_context.make_call1 S.full_balance ctxt block pkh () () - -let current_frozen_deposits ctxt block pkh = - RPC_context.make_call1 S.current_frozen_deposits ctxt block pkh () () - -let frozen_deposits ctxt block pkh = - RPC_context.make_call1 S.frozen_deposits ctxt block pkh () () - -let staking_balance ctxt block pkh = - RPC_context.make_call1 S.staking_balance ctxt block pkh () () - -let frozen_deposits_limit ctxt block pkh = - RPC_context.make_call1 S.frozen_deposits_limit ctxt block pkh () () - -let delegated_contracts ctxt block pkh = - RPC_context.make_call1 S.delegated_contracts ctxt block pkh () () - -let delegated_balance ctxt block pkh = - RPC_context.make_call1 S.delegated_balance ctxt block pkh () () - -let deactivated ctxt block pkh = - RPC_context.make_call1 S.deactivated ctxt block pkh () () - -let grace_period ctxt block pkh = - RPC_context.make_call1 S.grace_period ctxt block pkh () () - -let voting_power ctxt block pkh = - RPC_context.make_call1 S.voting_power ctxt block pkh () () - -let participation ctxt block pkh = - RPC_context.make_call1 S.participation ctxt block pkh () () diff --git a/src/proto_012_Psithaca/lib_protocol/delegate_services.mli b/src/proto_012_Psithaca/lib_protocol/delegate_services.mli deleted file mode 100644 index ac9e3db4280d..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/delegate_services.mli +++ /dev/null @@ -1,122 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -val list : - 'a #RPC_context.simple -> - 'a -> - ?active:bool -> - ?inactive:bool -> - unit -> - Signature.Public_key_hash.t list shell_tzresult Lwt.t - -type info = { - full_balance : Tez.t; (** Balance + Frozen balance *) - current_frozen_deposits : Tez.t; - frozen_deposits : Tez.t; - staking_balance : Tez.t; - frozen_deposits_limit : Tez.t option; - delegated_contracts : Contract.t list; - delegated_balance : Tez.t; - deactivated : bool; - grace_period : Cycle.t; - voting_power : int32; -} - -val info_encoding : info Data_encoding.t - -val info : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - info shell_tzresult Lwt.t - -val full_balance : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - Tez.t shell_tzresult Lwt.t - -val current_frozen_deposits : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - Tez.t shell_tzresult Lwt.t - -val frozen_deposits : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - Tez.t shell_tzresult Lwt.t - -val staking_balance : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - Tez.t shell_tzresult Lwt.t - -val frozen_deposits_limit : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - Tez.t option shell_tzresult Lwt.t - -val delegated_contracts : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - Contract.t list shell_tzresult Lwt.t - -val delegated_balance : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - Tez.t shell_tzresult Lwt.t - -val deactivated : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - bool shell_tzresult Lwt.t - -val grace_period : - 'a #RPC_context.simple -> - 'a -> - Signature.Public_key_hash.t -> - Cycle.t shell_tzresult Lwt.t - -val voting_power : - 'a #RPC_context.simple -> 'a -> public_key_hash -> int32 shell_tzresult Lwt.t - -val participation : - 'a #RPC_context.simple -> - 'a -> - public_key_hash -> - Delegate.participation_info shell_tzresult Lwt.t - -val register : unit -> unit diff --git a/src/proto_012_Psithaca/lib_protocol/delegate_storage.ml b/src/proto_012_Psithaca/lib_protocol/delegate_storage.ml deleted file mode 100644 index 2816916d4767..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/delegate_storage.ml +++ /dev/null @@ -1,908 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | (* `Permanent *) No_deletion of Signature.Public_key_hash.t - | (* `Temporary *) Active_delegate - | (* `Temporary *) Current_delegate - | (* `Permanent *) Empty_delegate_account of Signature.Public_key_hash.t - | (* `Permanent *) Unregistered_delegate of Signature.Public_key_hash.t - | (* `Permanent *) Unassigned_validation_slot_for_level of Level_repr.t * int - | (* `Permanent *) - Cannot_find_active_stake of { - cycle : Cycle_repr.t; - delegate : Signature.Public_key_hash.t; - } - | (* `Temporary *) Not_registered of Signature.Public_key_hash.t - -let () = - register_error_kind - `Permanent - ~id:"delegate.no_deletion" - ~title:"Forbidden delegate deletion" - ~description:"Tried to unregister a delegate" - ~pp:(fun ppf delegate -> - Format.fprintf - ppf - "Delegate deletion is forbidden (%a)" - Signature.Public_key_hash.pp - delegate) - Data_encoding.(obj1 (req "delegate" Signature.Public_key_hash.encoding)) - (function No_deletion c -> Some c | _ -> None) - (fun c -> No_deletion c) ; - register_error_kind - `Temporary - ~id:"delegate.already_active" - ~title:"Delegate already active" - ~description:"Useless delegate reactivation" - ~pp:(fun ppf () -> - Format.fprintf ppf "The delegate is still active, no need to refresh it") - Data_encoding.empty - (function Active_delegate -> Some () | _ -> None) - (fun () -> Active_delegate) ; - register_error_kind - `Temporary - ~id:"delegate.unchanged" - ~title:"Unchanged delegated" - ~description:"Contract already delegated to the given delegate" - ~pp:(fun ppf () -> - Format.fprintf - ppf - "The contract is already delegated to the same delegate") - Data_encoding.empty - (function Current_delegate -> Some () | _ -> None) - (fun () -> Current_delegate) ; - register_error_kind - `Permanent - ~id:"delegate.empty_delegate_account" - ~title:"Empty delegate account" - ~description:"Cannot register a delegate when its implicit account is empty" - ~pp:(fun ppf delegate -> - Format.fprintf - ppf - "Delegate registration is forbidden when the delegate\n\ - \ implicit account is empty (%a)" - Signature.Public_key_hash.pp - delegate) - Data_encoding.(obj1 (req "delegate" Signature.Public_key_hash.encoding)) - (function Empty_delegate_account c -> Some c | _ -> None) - (fun c -> Empty_delegate_account c) ; - (* Unregistered delegate *) - register_error_kind - `Permanent - ~id:"contract.manager.unregistered_delegate" - ~title:"Unregistered delegate" - ~description:"A contract cannot be delegated to an unregistered delegate" - ~pp:(fun ppf k -> - Format.fprintf - ppf - "The provided public key (with hash %a) is not registered as valid \ - delegate key." - Signature.Public_key_hash.pp - k) - Data_encoding.(obj1 (req "hash" Signature.Public_key_hash.encoding)) - (function Unregistered_delegate k -> Some k | _ -> None) - (fun k -> Unregistered_delegate k) ; - (* Unassigned_validation_slot_for_level *) - register_error_kind - `Permanent - ~id:"delegate.unassigned_validation_slot_for_level" - ~title:"Unassigned validation slot for level" - ~description: - "The validation slot for the given level is not assigned. Nobody payed \ - for that slot, or the level is either in the past or too far in the \ - future (further than the validatiors_selection_offset constant)" - ~pp:(fun ppf (l, slot) -> - Format.fprintf - ppf - "The validation slot %i for the level %a is not assigned. Nobody payed \ - for that slot, or the level is either in the past or too far in the \ - future (further than the validatiors_selection_offset constant)" - slot - Level_repr.pp - l) - Data_encoding.(obj2 (req "level" Level_repr.encoding) (req "slot" int31)) - (function - | Unassigned_validation_slot_for_level (l, s) -> Some (l, s) | _ -> None) - (fun (l, s) -> Unassigned_validation_slot_for_level (l, s)) ; - register_error_kind - `Permanent - ~id:"delegate.cannot_find_active_stake" - ~title:"Cannot find active stake" - ~description: - "The active stake of a delegate cannot be found for the given cycle." - ~pp:(fun ppf (cycle, delegate) -> - Format.fprintf - ppf - "The active stake of the delegate %a cannot be found for the cycle %a." - Cycle_repr.pp - cycle - Signature.Public_key_hash.pp - delegate) - Data_encoding.( - obj2 - (req "cycle" Cycle_repr.encoding) - (req "delegate" Signature.Public_key_hash.encoding)) - (function - | Cannot_find_active_stake {cycle; delegate} -> Some (cycle, delegate) - | _ -> None) - (fun (cycle, delegate) -> Cannot_find_active_stake {cycle; delegate}) ; - register_error_kind - `Temporary - ~id:"delegate.not_registered" - ~title:"Not a registered delegate" - ~description: - "The provided public key hash is not the address of a registered \ - delegate." - ~pp:(fun ppf pkh -> - Format.fprintf - ppf - "The provided public key hash (%a) is not the address of a registered \ - delegate. If you own this account and want to register it as a \ - delegate, use a delegation operation to delegate the account to \ - itself." - Signature.Public_key_hash.pp - pkh) - Data_encoding.(obj1 (req "pkh" Signature.Public_key_hash.encoding)) - (function Not_registered pkh -> Some pkh | _ -> None) - (fun pkh -> Not_registered pkh) - -let set_inactive ctxt delegate = - let delegate_contract = Contract_repr.implicit_contract delegate in - Delegate_activation_storage.set_inactive ctxt delegate_contract - >>= fun ctxt -> - Stake_storage.deactivate_only_call_from_delegate_storage ctxt delegate >|= ok - -let set_active ctxt delegate = - Delegate_activation_storage.set_active ctxt delegate - >>=? fun (ctxt, inactive) -> - if not inactive then return ctxt - else Stake_storage.activate_only_call_from_delegate_storage ctxt delegate - -let staking_balance ctxt delegate = - Contract_delegate_storage.registered ctxt delegate >>=? fun is_registered -> - if is_registered then Stake_storage.get_staking_balance ctxt delegate - else return Tez_repr.zero - -let pubkey ctxt delegate = - Contract_manager_storage.get_manager_key - ctxt - delegate - ~error:(Unregistered_delegate delegate) - -let init ctxt contract delegate = - Contract_manager_storage.is_manager_key_revealed ctxt delegate - >>=? fun known_delegate -> - error_unless known_delegate (Unregistered_delegate delegate) >>?= fun () -> - Contract_delegate_storage.registered ctxt delegate >>=? fun is_registered -> - error_unless is_registered (Unregistered_delegate delegate) >>?= fun () -> - Contract_delegate_storage.init ctxt contract delegate - -let set c contract delegate = - match delegate with - | None -> ( - match Contract_repr.is_implicit contract with - | Some pkh -> - (* check if contract is a registered delegate *) - Contract_delegate_storage.registered c pkh >>=? fun is_registered -> - if is_registered then fail (No_deletion pkh) - else Contract_delegate_storage.delete c contract - | None -> Contract_delegate_storage.delete c contract) - | Some delegate -> - Contract_manager_storage.is_manager_key_revealed c delegate - >>=? fun known_delegate -> - Contract_delegate_storage.registered c delegate - >>=? fun registered_delegate -> - let self_delegation = - match Contract_repr.is_implicit contract with - | Some pkh -> Signature.Public_key_hash.equal pkh delegate - | None -> false - in - if (not known_delegate) || not (registered_delegate || self_delegation) - then fail (Unregistered_delegate delegate) - else - (Contract_delegate_storage.find c contract >>=? function - | Some current_delegate - when Signature.Public_key_hash.equal delegate current_delegate -> - if self_delegation then - Delegate_activation_storage.is_inactive c delegate >>=? function - | true -> return_unit - | false -> fail Active_delegate - else fail Current_delegate - | None | Some _ -> return_unit) - >>=? fun () -> - (* check if contract is a registered delegate *) - (match Contract_repr.is_implicit contract with - | Some pkh -> - Contract_delegate_storage.registered c pkh >>=? fun is_registered -> - (* allow self-delegation to re-activate *) - if (not self_delegation) && is_registered then - fail (No_deletion pkh) - else return_unit - | None -> return_unit) - >>=? fun () -> - Storage.Contract.Balance.mem c contract >>= fun exists -> - error_when - (self_delegation && not exists) - (Empty_delegate_account delegate) - >>?= fun () -> - Contract_delegate_storage.set c contract delegate >>=? fun c -> - if self_delegation then - Storage.Delegates.add c delegate >>= fun c -> set_active c delegate - else return c - -let frozen_deposits_limit ctxt delegate = - Storage.Contract.Frozen_deposits_limit.find - ctxt - (Contract_repr.implicit_contract delegate) - -let set_frozen_deposits_limit ctxt delegate limit = - Storage.Contract.Frozen_deposits_limit.add_or_remove - ctxt - (Contract_repr.implicit_contract delegate) - limit - -let update_activity ctxt last_cycle = - let preserved = Constants_storage.preserved_cycles ctxt in - match Cycle_repr.sub last_cycle preserved with - | None -> return (ctxt, []) - | Some _unfrozen_cycle -> - Stake_storage.fold_on_active_delegates_with_rolls - ctxt - ~order:`Sorted - ~init:(Ok (ctxt, [])) - ~f:(fun delegate () acc -> - acc >>?= fun (ctxt, deactivated) -> - Delegate_activation_storage.grace_period ctxt delegate - >>=? fun cycle -> - if Cycle_repr.(cycle <= last_cycle) then - set_inactive ctxt delegate >|=? fun ctxt -> - (ctxt, delegate :: deactivated) - else return (ctxt, deactivated)) - >|=? fun (ctxt, deactivated) -> (ctxt, deactivated) - -let expected_slots_for_given_active_stake ctxt ~total_active_stake ~active_stake - = - let blocks_per_cycle = - Int32.to_int (Constants_storage.blocks_per_cycle ctxt) - in - let consensus_committee_size = - Constants_storage.consensus_committee_size ctxt - in - let number_of_endorsements_per_cycle = - blocks_per_cycle * consensus_committee_size - in - return - (Z.to_int - (Z.div - (Z.mul - (Z.of_int64 (Tez_repr.to_mutez active_stake)) - (Z.of_int number_of_endorsements_per_cycle)) - (Z.of_int64 (Tez_repr.to_mutez total_active_stake)))) - -let delegate_participated_enough ctxt delegate = - Storage.Contract.Missed_endorsements.find ctxt delegate >>=? function - | None -> return_true - | Some missed_endorsements -> - return Compare.Int.(missed_endorsements.remaining_slots >= 0) - -let delegate_has_revealed_nonces delegate unrevelead_nonces_set = - not (Signature.Public_key_hash.Set.mem delegate unrevelead_nonces_set) - -let distribute_endorsing_rewards ctxt last_cycle unrevealed_nonces = - let endorsing_reward_per_slot = - Constants_storage.endorsing_reward_per_slot ctxt - in - let unrevealed_nonces_set = - List.fold_left - (fun set {Storage.Seed.nonce_hash = _; delegate} -> - Signature.Public_key_hash.Set.add delegate set) - Signature.Public_key_hash.Set.empty - unrevealed_nonces - in - Stake_storage.get_total_active_stake ctxt last_cycle - >>=? fun total_active_stake -> - Stake_storage.get_selected_distribution ctxt last_cycle >>=? fun delegates -> - List.fold_left_es - (fun (ctxt, balance_updates) (delegate, active_stake) -> - let delegate_contract = Contract_repr.implicit_contract delegate in - delegate_participated_enough ctxt delegate_contract - >>=? fun sufficient_participation -> - let has_revealed_nonces = - delegate_has_revealed_nonces delegate unrevealed_nonces_set - in - expected_slots_for_given_active_stake - ctxt - ~total_active_stake - ~active_stake - >>=? fun expected_slots -> - let rewards = Tez_repr.mul_exn endorsing_reward_per_slot expected_slots in - (if sufficient_participation && has_revealed_nonces then - (* Sufficient participation: we pay the rewards *) - Token.transfer - ctxt - `Endorsing_rewards - (`Contract delegate_contract) - rewards - >|=? fun (ctxt, payed_rewards_receipts) -> - (ctxt, payed_rewards_receipts @ balance_updates) - else - (* Insufficient participation or unrevealed nonce: no rewards *) - Token.transfer - ctxt - `Endorsing_rewards - (`Lost_endorsing_rewards - (delegate, not sufficient_participation, not has_revealed_nonces)) - rewards - >|=? fun (ctxt, payed_rewards_receipts) -> - (ctxt, payed_rewards_receipts @ balance_updates)) - >>=? fun (ctxt, balance_updates) -> - Storage.Contract.Missed_endorsements.remove ctxt delegate_contract - >>= fun ctxt -> return (ctxt, balance_updates)) - (ctxt, []) - delegates - -let clear_outdated_slashed_deposits ctxt ~new_cycle = - let max_slashable_period = Constants_storage.max_slashing_period ctxt in - match Cycle_repr.(sub new_cycle max_slashable_period) with - | None -> Lwt.return ctxt - | Some outdated_cycle -> Storage.Slashed_deposits.clear (ctxt, outdated_cycle) - -(* Return a map from delegates (with active stake at some cycle - in the cycle window [from_cycle, to_cycle]) to the maximum - of the stake to be deposited for each such cycle (which is just the - [frozen_deposits_percentage] of the active stake at that cycle). Also - return the delegates that have fallen out of the sliding window. *) -let max_frozen_deposits_and_delegates_to_remove ctxt ~from_cycle ~to_cycle = - let frozen_deposits_percentage = - Constants_storage.frozen_deposits_percentage ctxt - in - let cycles = Cycle_repr.(from_cycle ---> to_cycle) in - (match Cycle_repr.pred from_cycle with - | None -> return Signature.Public_key_hash.Set.empty - | Some cleared_cycle -> ( - Stake_storage.find_selected_distribution ctxt cleared_cycle - >|=? fun cleared_cycle_delegates -> - match cleared_cycle_delegates with - | None -> Signature.Public_key_hash.Set.empty - | Some delegates -> - List.fold_left - (fun set (d, _) -> Signature.Public_key_hash.Set.add d set) - Signature.Public_key_hash.Set.empty - delegates)) - >>=? fun cleared_cycle_delegates -> - List.fold_left_es - (fun (maxima, delegates_to_remove) (cycle : Cycle_repr.t) -> - Stake_storage.get_selected_distribution ctxt cycle - >|=? fun active_stakes -> - List.fold_left - (fun (maxima, delegates_to_remove) (delegate, stake) -> - let stake_to_be_deposited = - Tez_repr.(div_exn (mul_exn stake frozen_deposits_percentage) 100) - in - let maxima = - Signature.Public_key_hash.Map.update - delegate - (function - | None -> Some stake_to_be_deposited - | Some maximum -> - Some (Tez_repr.max maximum stake_to_be_deposited)) - maxima - in - let delegates_to_remove = - Signature.Public_key_hash.Set.remove delegate delegates_to_remove - in - (maxima, delegates_to_remove)) - (maxima, delegates_to_remove) - active_stakes) - (Signature.Public_key_hash.Map.empty, cleared_cycle_delegates) - cycles - -let freeze_deposits ?(origin = Receipt_repr.Block_application) ctxt ~new_cycle - ~balance_updates = - let max_slashable_period = Constants_storage.max_slashing_period ctxt in - (* We want to be able to slash for at most [max_slashable_period] *) - (match Cycle_repr.(sub new_cycle (max_slashable_period - 1)) with - | None -> - Storage.Tenderbake.First_level.get ctxt - >>=? fun first_level_of_tenderbake -> - let cycle_eras = Raw_context.cycle_eras ctxt in - let level = Level_repr.from_raw ~cycle_eras first_level_of_tenderbake in - return level.cycle - | Some cycle -> return cycle) - >>=? fun from_cycle -> - let preserved_cycles = Constants_storage.preserved_cycles ctxt in - let to_cycle = Cycle_repr.(add new_cycle preserved_cycles) in - max_frozen_deposits_and_delegates_to_remove ctxt ~from_cycle ~to_cycle - >>=? fun (maxima, delegates_to_remove) -> - Signature.Public_key_hash.Map.fold_es - (fun delegate maximum_stake_to_be_deposited (ctxt, balance_updates) -> - (* Here we make sure to preserve the following invariant : - maximum_stake_to_be_deposited <= frozen_deposits + balance - See select_distribution_for_cycle *) - let delegate_contract = Contract_repr.implicit_contract delegate in - Frozen_deposits_storage.update_deposits_cap - ctxt - delegate_contract - maximum_stake_to_be_deposited - >>=? fun (ctxt, current_amount) -> - if Tez_repr.(current_amount > maximum_stake_to_be_deposited) then - Tez_repr.(current_amount -? maximum_stake_to_be_deposited) - >>?= fun to_reimburse -> - Token.transfer - ~origin - ctxt - (`Frozen_deposits delegate) - (`Delegate_balance delegate) - to_reimburse - >|=? fun (ctxt, bupds) -> (ctxt, bupds @ balance_updates) - else if Tez_repr.(current_amount < maximum_stake_to_be_deposited) then - Tez_repr.(maximum_stake_to_be_deposited -? current_amount) - >>?= fun desired_to_freeze -> - Storage.Contract.Balance.get ctxt delegate_contract >>=? fun balance -> - (* In case the delegate hasn't been slashed in this cycle, - the following invariant holds: - maximum_stake_to_be_deposited <= frozen_deposits + balance - See select_distribution_for_cycle - - If the delegate has been slashed during the cycle, the invariant - above doesn't necessarily hold. In this case, we freeze the max - we can for the delegate. *) - let to_freeze = Tez_repr.(min balance desired_to_freeze) in - Token.transfer - ~origin - ctxt - (`Delegate_balance delegate) - (`Frozen_deposits delegate) - to_freeze - >|=? fun (ctxt, bupds) -> (ctxt, bupds @ balance_updates) - else return (ctxt, balance_updates)) - maxima - (ctxt, balance_updates) - >>=? fun (ctxt, balance_updates) -> - (* Unfreeze deposits (that is, set them to zero) for delegates that - were previously in the relevant window (and therefore had some - frozen deposits) but are not in the new window; because that means - that such a delegate had no active stake in the relevant cycles, - and therefore it should have no frozen deposits. *) - Signature.Public_key_hash.Set.fold_es - (fun delegate (ctxt, balance_updates) -> - let delegate_contract = Contract_repr.implicit_contract delegate in - Frozen_deposits_storage.get ctxt delegate_contract - >>=? fun frozen_deposits -> - if Tez_repr.(frozen_deposits.current_amount > zero) then - Frozen_deposits_storage.update_deposits_cap - ctxt - delegate_contract - Tez_repr.zero - >>=? fun (ctxt, (_current_amount : Tez_repr.t)) -> - Token.transfer - ~origin - ctxt - (`Frozen_deposits delegate) - (`Delegate_balance delegate) - frozen_deposits.current_amount - >|=? fun (ctxt, bupds) -> (ctxt, bupds @ balance_updates) - else return (ctxt, balance_updates)) - delegates_to_remove - (ctxt, balance_updates) - -let freeze_deposits_do_not_call_except_for_migration = - freeze_deposits ~origin:Protocol_migration - -let cycle_end ctxt last_cycle unrevealed_nonces = - let new_cycle = Cycle_repr.add last_cycle 1 in - Stake_storage.select_new_distribution_at_cycle_end ctxt ~new_cycle pubkey - >>=? fun ctxt -> - clear_outdated_slashed_deposits ctxt ~new_cycle >>= fun ctxt -> - distribute_endorsing_rewards ctxt last_cycle unrevealed_nonces - >>=? fun (ctxt, balance_updates) -> - freeze_deposits ctxt ~new_cycle ~balance_updates - >>=? fun (ctxt, balance_updates) -> - Stake_storage.clear_at_cycle_end ctxt ~new_cycle >>=? fun ctxt -> - update_activity ctxt last_cycle >>=? fun (ctxt, deactivated_delagates) -> - return (ctxt, balance_updates, deactivated_delagates) - -let balance ctxt delegate = - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Balance.get ctxt contract - -let frozen_deposits ctxt delegate = - Frozen_deposits_storage.get ctxt (Contract_repr.implicit_contract delegate) - -let full_balance ctxt delegate = - frozen_deposits ctxt delegate >>=? fun frozen_deposits -> - balance ctxt delegate >>=? fun balance -> - Lwt.return Tez_repr.(frozen_deposits.current_amount +? balance) - -let deactivated = Delegate_activation_storage.is_inactive - -let delegated_balance ctxt delegate = - staking_balance ctxt delegate >>=? fun staking_balance -> - balance ctxt delegate >>=? fun balance -> - frozen_deposits ctxt delegate >>=? fun frozen_deposits -> - Tez_repr.(balance +? frozen_deposits.current_amount) - >>?= fun self_staking_balance -> - Lwt.return Tez_repr.(staking_balance -? self_staking_balance) - -let fold = Storage.Delegates.fold - -let list = Storage.Delegates.elements - -(* The fact that this succeeds iff [registered ctxt pkh] returns true is an - invariant of the [set] function. *) -let check_delegate ctxt pkh = - Storage.Delegates.mem ctxt pkh >>= function - | true -> return_unit - | false -> fail (Not_registered pkh) - -module Random = struct - (* [init_random_state] initialize a random sequence drawing state - that's unique for a given (seed, level, index) triple. Elements - from this sequence are drawn using [take_int64], updating the - state for the next draw. The initial state is the Blake2b hash of - the three randomness sources, and an offset set to zero - (indicating that zero bits of randomness have been - consumed). When drawing random elements, bits are extracted from - the state until exhaustion (256 bits), at which point the state - is rehashed and the offset reset to 0. *) - - let init_random_state seed level index = - ( Raw_hashes.blake2b - (Data_encoding.Binary.to_bytes_exn - Data_encoding.(tup3 Seed_repr.seed_encoding int32 int32) - (seed, level.Level_repr.cycle_position, Int32.of_int index)), - 0 ) - - let take_int64 bound state = - let drop_if_over = - (* This function draws random values in [0-(bound-1)] by drawing - in [0-(2^63-1)] (64-bit) and computing the value modulo - [bound]. For the application of [mod bound] to preserve - uniformity, the input space must be of the form - [0-(n*bound-1)]. We enforce this by rejecting 64-bit samples - above this limit (in which case, we draw a new 64-sample from - the sequence and try again). *) - Int64.sub Int64.max_int (Int64.rem Int64.max_int bound) - in - let rec loop (bytes, n) = - let consumed_bytes = 8 in - let state_size = Bytes.length bytes in - if Compare.Int.(n > state_size - consumed_bytes) then - loop (Raw_hashes.blake2b bytes, 0) - else - let r = Int64.abs (TzEndian.get_int64 bytes n) in - if Compare.Int64.(r >= drop_if_over) then - loop (bytes, n + consumed_bytes) - else - let v = Int64.rem r bound in - (v, (bytes, n + consumed_bytes)) - in - loop state - - let owner c (level : Level_repr.t) offset = - (* TODO: https://gitlab.com/tezos/tezos/-/issues/2084 - compute sampler at stake distribution snapshot instead of lazily. *) - let cycle = level.Level_repr.cycle in - (match Raw_context.sampler_for_cycle c cycle with - | Error `Sampler_not_set -> - Seed_storage.for_cycle c cycle >>=? fun seed -> - Stake_storage.Delegate_sampler_state.get c cycle >>=? fun state -> - let (c, seed, state) = - match Raw_context.set_sampler_for_cycle c cycle (seed, state) with - | Error `Sampler_already_set -> assert false - | Ok c -> (c, seed, state) - in - return (c, seed, state) - | Ok (seed, state) -> return (c, seed, state)) - >>=? fun (c, seed, state) -> - let sample ~int_bound ~mass_bound = - let state = init_random_state seed level offset in - let (i, state) = take_int64 (Int64.of_int int_bound) state in - let (elt, _) = take_int64 mass_bound state in - (Int64.to_int i, elt) - in - let (pk, pkh) = Sampler.sample state sample in - return (c, (pk, pkh)) -end - -(* Round robin delegate selection. This is only used for testing purposes. *) -module Round_robin = struct - let over level slot delegates = - let nth_mod n l = - match List.nth_opt l (n mod List.length l) with - | None -> assert false - | Some x -> x - in - let level_int = Int32.to_int level.Level_repr.level_position in - if Compare.Int.(level_int = 0) then - (* dummy case for level 0 *) - nth_mod 0 delegates |> nth_mod 0 |> return - else - let adjusted_level = level_int - 1 in - let n_defined_levels = List.length delegates in - if Compare.Int.(adjusted_level < n_defined_levels) then - nth_mod adjusted_level delegates |> nth_mod slot |> return - else - let delegates = - match List.rev delegates with [] -> assert false | last :: _ -> last - in - nth_mod (level_int - n_defined_levels + slot) delegates |> return -end - -let slot_owner c level slot = - match (Constants_storage.parametric c).delegate_selection with - | Random -> Random.owner c level (Slot_repr.to_int slot) - | Round_robin_over delegates -> - Round_robin.over level (Slot_repr.to_int slot) delegates >|=? fun pk -> - (c, (pk, Signature.Public_key.hash pk)) - -let baking_rights_owner c (level : Level_repr.t) ~round = - Round_repr.to_int round >>?= fun round -> - let consensus_committee_size = Constants_storage.consensus_committee_size c in - let pos = round mod consensus_committee_size in - slot_owner c level pos >>=? fun (ctxt, pk) -> - return (ctxt, Slot_repr.of_int_do_not_use_except_for_parameters pos, pk) - -let already_slashed_for_double_endorsing ctxt delegate (level : Level_repr.t) = - Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate) - >>=? function - | None -> return_false - | Some slashed -> return slashed.for_double_endorsing - -let already_slashed_for_double_baking ctxt delegate (level : Level_repr.t) = - Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate) - >>=? function - | None -> return_false - | Some slashed -> return slashed.for_double_baking - -let punish_double_endorsing ctxt delegate (level : Level_repr.t) = - let delegate_contract = Contract_repr.implicit_contract delegate in - Frozen_deposits_storage.get ctxt delegate_contract >>=? fun frozen_deposits -> - let slashing_ratio : Constants_repr.ratio = - Constants_storage.ratio_of_frozen_deposits_slashed_per_double_endorsement - ctxt - in - let punish_value = - Tez_repr.( - div_exn - (mul_exn frozen_deposits.initial_amount slashing_ratio.numerator) - slashing_ratio.denominator) - in - let amount_to_burn = - Tez_repr.(min frozen_deposits.current_amount punish_value) - in - Token.transfer - ctxt - (`Frozen_deposits delegate) - `Double_signing_punishments - amount_to_burn - >>=? fun (ctxt, balance_updates) -> - Stake_storage.remove_stake ctxt delegate amount_to_burn >>=? fun ctxt -> - Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate) - >>=? fun slashed -> - let slashed : Storage.slashed_level = - match slashed with - | None -> {for_double_endorsing = true; for_double_baking = false} - | Some slashed -> - assert (Compare.Bool.(slashed.for_double_endorsing = false)) ; - {slashed with for_double_endorsing = true} - in - Storage.Slashed_deposits.add - (ctxt, level.cycle) - (level.level, delegate) - slashed - >>= fun ctxt -> return (ctxt, amount_to_burn, balance_updates) - -let punish_double_baking ctxt delegate (level : Level_repr.t) = - let delegate_contract = Contract_repr.implicit_contract delegate in - Frozen_deposits_storage.get ctxt delegate_contract >>=? fun frozen_deposits -> - let slashing_for_one_block = - Constants_storage.double_baking_punishment ctxt - in - let amount_to_burn = - Tez_repr.(min frozen_deposits.current_amount slashing_for_one_block) - in - Token.transfer - ctxt - (`Frozen_deposits delegate) - `Double_signing_punishments - amount_to_burn - >>=? fun (ctxt, balance_updates) -> - Stake_storage.remove_stake ctxt delegate amount_to_burn >>=? fun ctxt -> - Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate) - >>=? fun slashed -> - let slashed : Storage.slashed_level = - match slashed with - | None -> {for_double_endorsing = false; for_double_baking = true} - | Some slashed -> - assert (Compare.Bool.(slashed.for_double_baking = false)) ; - {slashed with for_double_baking = true} - in - Storage.Slashed_deposits.add - (ctxt, level.cycle) - (level.level, delegate) - slashed - >>= fun ctxt -> return (ctxt, amount_to_burn, balance_updates) - -type level_participation = Participated | Didn't_participate - -(* Note that the participation for the last block of a cycle is - recorded in the next cycle. *) -let record_endorsing_participation ctxt ~delegate ~participation - ~endorsing_power = - match participation with - | Participated -> set_active ctxt delegate - | Didn't_participate -> ( - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Missed_endorsements.find ctxt contract >>=? function - | Some {remaining_slots; missed_levels} -> - let remaining_slots = remaining_slots - endorsing_power in - Storage.Contract.Missed_endorsements.update - ctxt - contract - {remaining_slots; missed_levels = missed_levels + 1} - | None -> ( - let level = Level_storage.current ctxt in - Raw_context.stake_distribution_for_current_cycle ctxt - >>?= fun stake_distribution -> - match - Signature.Public_key_hash.Map.find delegate stake_distribution - with - | None -> - (* This happens when the block is the first one in a - cycle, and therefore the endorsements are for the last - block of the previous cycle, and when the delegate does - not have an active stake at the current cycle; in this - case its participation is simply ignored. *) - assert (Compare.Int32.(level.cycle_position = 0l)) ; - return ctxt - | Some active_stake -> - Stake_storage.get_total_active_stake ctxt level.cycle - >>=? fun total_active_stake -> - expected_slots_for_given_active_stake - ctxt - ~total_active_stake - ~active_stake - >>=? fun expected_slots -> - let Constants_repr.{numerator; denominator} = - Constants_storage.minimal_participation_ratio ctxt - in - let minimal_activity = expected_slots * numerator / denominator in - let maximal_inactivity = expected_slots - minimal_activity in - let remaining_slots = maximal_inactivity - endorsing_power in - Storage.Contract.Missed_endorsements.init - ctxt - contract - {remaining_slots; missed_levels = 1})) - -let record_baking_activity_and_pay_rewards_and_fees ctxt ~payload_producer - ~block_producer ~baking_reward ~reward_bonus = - set_active ctxt payload_producer >>=? fun ctxt -> - (if not (Signature.Public_key_hash.equal payload_producer block_producer) then - set_active ctxt block_producer - else return ctxt) - >>=? fun ctxt -> - let pay_payload_producer ctxt delegate = - let contract = Contract_repr.implicit_contract delegate in - Token.balance ctxt `Block_fees >>=? fun block_fees -> - Token.transfer_n - ctxt - [(`Block_fees, block_fees); (`Baking_rewards, baking_reward)] - (`Contract contract) - in - let pay_block_producer ctxt delegate bonus = - let contract = Contract_repr.implicit_contract delegate in - Token.transfer ctxt `Baking_bonuses (`Contract contract) bonus - in - pay_payload_producer ctxt payload_producer - >>=? fun (ctxt, balance_updates_payload_producer) -> - (match reward_bonus with - | Some bonus -> pay_block_producer ctxt block_producer bonus - | None -> return (ctxt, [])) - >>=? fun (ctxt, balance_updates_block_producer) -> - return - (ctxt, balance_updates_payload_producer @ balance_updates_block_producer) - -type participation_info = { - expected_cycle_activity : int; - minimal_cycle_activity : int; - missed_slots : int; - missed_levels : int; - remaining_allowed_missed_slots : int; - expected_endorsing_rewards : Tez_repr.t; -} - -(* Inefficient, only for RPC *) -let delegate_participation_info ctxt delegate = - let level = Level_storage.current ctxt in - Stake_storage.get_selected_distribution ctxt level.cycle - >>=? fun stake_distribution -> - match - List.assoc_opt - ~equal:Signature.Public_key_hash.equal - delegate - stake_distribution - with - | None -> - (* delegate does not have an active stake at the current cycle *) - return - { - expected_cycle_activity = 0; - minimal_cycle_activity = 0; - missed_slots = 0; - missed_levels = 0; - remaining_allowed_missed_slots = 0; - expected_endorsing_rewards = Tez_repr.zero; - } - | Some active_stake -> - Stake_storage.get_total_active_stake ctxt level.cycle - >>=? fun total_active_stake -> - expected_slots_for_given_active_stake - ctxt - ~total_active_stake - ~active_stake - >>=? fun expected_cycle_activity -> - let Constants_repr.{numerator; denominator} = - Constants_storage.minimal_participation_ratio ctxt - in - let endorsing_reward_per_slot = - Constants_storage.endorsing_reward_per_slot ctxt - in - let minimal_cycle_activity = - expected_cycle_activity * numerator / denominator - in - let maximal_cycle_inactivity = - expected_cycle_activity - minimal_cycle_activity - in - let expected_endorsing_rewards = - Tez_repr.mul_exn endorsing_reward_per_slot expected_cycle_activity - in - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Missed_endorsements.find ctxt contract - >>=? fun missed_endorsements -> - let (missed_slots, missed_levels, remaining_allowed_missed_slots) = - match missed_endorsements with - | None -> (0, 0, maximal_cycle_inactivity) - | Some {remaining_slots; missed_levels} -> - ( maximal_cycle_inactivity - remaining_slots, - missed_levels, - Compare.Int.max 0 remaining_slots ) - in - let expected_endorsing_rewards = - match missed_endorsements with - | Some r when Compare.Int.(r.remaining_slots < 0) -> Tez_repr.zero - | _ -> expected_endorsing_rewards - in - return - { - expected_cycle_activity; - minimal_cycle_activity; - missed_slots; - missed_levels; - remaining_allowed_missed_slots; - expected_endorsing_rewards; - } diff --git a/src/proto_012_Psithaca/lib_protocol/delegate_storage.mli b/src/proto_012_Psithaca/lib_protocol/delegate_storage.mli deleted file mode 100644 index c5c41bfbe13c..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/delegate_storage.mli +++ /dev/null @@ -1,242 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Allow to register a delegate when creating an account. *) -val init : - Raw_context.t -> - Contract_repr.t -> - Signature.Public_key_hash.t -> - Raw_context.t tzresult Lwt.t - -val pubkey : - Raw_context.t -> - Signature.Public_key_hash.t -> - Signature.Public_key.t tzresult Lwt.t - -(** Updating the delegate of a contract. - - When calling this function on an "implicit contract" and setting - the delegate to the contract manager registers it as a delegate. One - cannot unregister a delegate for now. The associate contract is now - 'undeletable'. *) -val set : - Raw_context.t -> - Contract_repr.t -> - Signature.Public_key_hash.t option -> - Raw_context.t tzresult Lwt.t - -val frozen_deposits_limit : - Raw_context.t -> - Signature.Public_key_hash.t -> - Tez_repr.t option tzresult Lwt.t - -val set_frozen_deposits_limit : - Raw_context.t -> - Signature.Public_key_hash.t -> - Tez_repr.t option -> - Raw_context.t Lwt.t - -type error += - | (* `Permanent *) No_deletion of Signature.Public_key_hash.t - | (* `Temporary *) Active_delegate - | (* `Temporary *) Current_delegate - | (* `Permanent *) Empty_delegate_account of Signature.Public_key_hash.t - | (* `Permanent *) Unregistered_delegate of Signature.Public_key_hash.t - | (* `Permanent *) Unassigned_validation_slot_for_level of Level_repr.t * int - | (* `Permanent *) - Cannot_find_active_stake of { - cycle : Cycle_repr.t; - delegate : Signature.Public_key_hash.t; - } - | (* `Temporary *) Not_registered of Signature.Public_key_hash.t - -(** Check that a given implicit account is a registered delegate. *) -val check_delegate : - Raw_context.t -> Signature.Public_key_hash.t -> unit tzresult Lwt.t - -(** Participation information. We denote by: - - "static" information that does not change during the cycle - - "dynamic" information that may change during the cycle *) -type participation_info = { - expected_cycle_activity : int; - (** The total expected slots to be endorsed in the cycle. (static) *) - minimal_cycle_activity : int; - (** The minimal endorsing slots in the cycle to get endorsing - rewards. (static) *) - missed_slots : int; - (** The number of missed endorsing slots in the cycle. (dynamic) *) - missed_levels : int; - (** The number of missed endorsing levels in the cycle. (dynamic) *) - remaining_allowed_missed_slots : int; - (** Remaining amount of endorsing slots that can be missed in the - cycle before forfeiting the rewards. (dynamic) *) - expected_endorsing_rewards : Tez_repr.t; - (** Endorsing rewards that will be distributed at the end of the - cycle if activity at that point will be greater than the minimal - required. If the activity is already known to be below the - required minimum, then the rewards are zero. (dynamic) *) -} - -val delegate_participation_info : - Raw_context.t -> - Signature.Public_key_hash.t -> - participation_info tzresult Lwt.t - -(** Iterate on all registered delegates. *) -val fold : - Raw_context.t -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(Signature.Public_key_hash.t -> 'a -> 'a Lwt.t) -> - 'a Lwt.t - -(** List all registered delegates. *) -val list : Raw_context.t -> Signature.Public_key_hash.t list Lwt.t - -val balance : - Raw_context.t -> Signature.public_key_hash -> Tez_repr.tez tzresult Lwt.t - -type level_participation = Participated | Didn't_participate - -(** Record the participation of a delegate as a validator. *) -val record_endorsing_participation : - Raw_context.t -> - delegate:Signature.Public_key_hash.t -> - participation:level_participation -> - endorsing_power:int -> - Raw_context.t tzresult Lwt.t - -(** Sets the payload and block producer as active. Pays the baking - reward and the fees to the payload producer and the reward bonus to - the payload producer (if the reward_bonus is not None).*) -val record_baking_activity_and_pay_rewards_and_fees : - Raw_context.t -> - payload_producer:Signature.Public_key_hash.t -> - block_producer:Signature.Public_key_hash.t -> - baking_reward:Tez_repr.t -> - reward_bonus:Tez_repr.t option -> - (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t - -(** Trigger the context maintenance at the end of cycle 'n', i.e.: - unfreeze the endorsing rewards, potentially deactivate delegates. - Return the corresponding balances updates and the list of - deactivated delegates. *) -val cycle_end : - Raw_context.t -> - Cycle_repr.t -> - Storage.Seed.unrevealed_nonce list -> - (Raw_context.t - * Receipt_repr.balance_updates - * Signature.Public_key_hash.t list) - tzresult - Lwt.t - -(** Returns true if the given delegate has already been slashed - for double baking for the given level. *) -val already_slashed_for_double_baking : - Raw_context.t -> - Signature.Public_key_hash.t -> - Level_repr.t -> - bool tzresult Lwt.t - -(** Returns true if the given delegate has already been slashed - for double preendorsing or double endorsing for the given level. *) -val already_slashed_for_double_endorsing : - Raw_context.t -> - Signature.Public_key_hash.t -> - Level_repr.t -> - bool tzresult Lwt.t - -(** Burn some frozen deposit for a delegate at a given level. Returns - the burned amount. *) -val punish_double_endorsing : - Raw_context.t -> - Signature.Public_key_hash.t -> - Level_repr.t -> - (Raw_context.t * Tez_repr.t * Receipt_repr.balance_updates) tzresult Lwt.t - -val punish_double_baking : - Raw_context.t -> - Signature.Public_key_hash.t -> - Level_repr.t -> - (Raw_context.t * Tez_repr.t * Receipt_repr.balance_updates) tzresult Lwt.t - -(** Returns a delegate's frozen deposits, both the current amount and - the initial freezed amount. - - A delegate's frozen balance is only composed of frozen deposits; - rewards and fees are not frozen, but simply credited at the right - moment. *) -val frozen_deposits : - Raw_context.t -> - Signature.Public_key_hash.t -> - Storage.deposits tzresult Lwt.t - -(** Returns the full 'balance' of the implicit contract associated to - a given key, i.e. the sum of the spendable balance and of the - frozen balance. - - Only use this function for RPCs: this is expensive. *) -val full_balance : - Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t - -val staking_balance : - Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t - -(** Only use this function for RPCs: this is expensive. *) -val delegated_balance : - Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t - -val deactivated : - Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t - -(** Participation slots potentially associated to accounts. The - accounts that didn't place a deposit will be excluded from this - list. This function should only be used to compute the deposits to - freeze or initialize the protocol while stitching. RPCs can use this - function to predict an approximation of long term future slot - allocations. It shouldn't be used in the baker. *) -val slot_owner : - Raw_context.t -> - Level_repr.t -> - Slot_repr.t -> - (Raw_context.t * (Signature.Public_key.t * Signature.Public_key_hash.t)) - tzresult - Lwt.t - -val baking_rights_owner : - Raw_context.t -> - Level_repr.t -> - round:Round_repr.round -> - (Raw_context.t * int * (Signature.public_key * Signature.public_key_hash)) - tzresult - Lwt.t - -val freeze_deposits_do_not_call_except_for_migration : - Raw_context.t -> - new_cycle:Cycle_repr.t -> - balance_updates:Receipt_repr.balance_updates -> - (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/dune b/src/proto_012_Psithaca/lib_protocol/dune deleted file mode 120000 index 8b081aeedbd3..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/dune +++ /dev/null @@ -1 +0,0 @@ -../../lib_protocol_compiler/dune_protocol.v1 \ No newline at end of file diff --git a/src/proto_012_Psithaca/lib_protocol/dune-project b/src/proto_012_Psithaca/lib_protocol/dune-project deleted file mode 100644 index d162b6795888..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-embedded-protocol-012-Psithaca) diff --git a/src/proto_012_Psithaca/lib_protocol/dune.inc b/src/proto_012_Psithaca/lib_protocol/dune.inc deleted file mode 100644 index 183148230ee5..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/dune.inc +++ /dev/null @@ -1,708 +0,0 @@ - - -; -; /!\ /!\ Do not modify this file /!\ /!\ -; -; but the original template in `tezos-protocol-compiler` -; - -; generated from src/lib_protocol_compiler/dune_protocol.template.v1 - -; This template is intended for protocols written after the Tezos -; project start using OCaml 4.12. -; -; template.v1 was introduced when we bumped the version of our OCaml -; dependency to 4.12. This change to a newer OCaml version introduced -; new warnings that need to be ignored in the protocols written before -; the update (see dune_protocol.template.v0). - -(rule - (targets environment.ml) - (action - (write-file %{targets} - "module Name = struct let name = \"012-Psithaca\" end -include Tezos_protocol_environment.MakeV4(Name)() -module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end -"))) - -(rule - (targets registerer.ml) - (deps - misc.mli misc.ml - non_empty_string.mli non_empty_string.ml - path_encoding.mli path_encoding.ml - storage_description.mli storage_description.ml - state_hash.mli state_hash.ml - nonce_hash.mli nonce_hash.ml - script_expr_hash.mli script_expr_hash.ml - contract_hash.mli contract_hash.ml - blinded_public_key_hash.mli blinded_public_key_hash.ml - block_payload_hash.mli block_payload_hash.ml - slot_repr.mli slot_repr.ml - tez_repr.mli tez_repr.ml - period_repr.mli period_repr.ml - time_repr.mli time_repr.ml - round_repr.mli round_repr.ml - block_payload_repr.mli block_payload_repr.ml - fixed_point_repr.mli fixed_point_repr.ml - saturation_repr.mli saturation_repr.ml - gas_limit_repr.mli gas_limit_repr.ml - constants_repr.mli constants_repr.ml - raw_level_repr.mli raw_level_repr.ml - fitness_repr.mli fitness_repr.ml - cycle_repr.mli cycle_repr.ml - level_repr.mli level_repr.ml - seed_repr.mli seed_repr.ml - sampler.mli sampler.ml - voting_period_repr.mli voting_period_repr.ml - script_string_repr.mli script_string_repr.ml - script_int_repr.mli script_int_repr.ml - script_timestamp_repr.mli script_timestamp_repr.ml - michelson_v1_primitives.mli michelson_v1_primitives.ml - script_repr.mli script_repr.ml - cache_memory_helpers.ml - contract_repr.mli contract_repr.ml - roll_repr_legacy.mli roll_repr_legacy.ml - vote_repr.mli vote_repr.ml - block_header_repr.mli block_header_repr.ml - operation_repr.mli operation_repr.ml - manager_repr.mli manager_repr.ml - commitment_repr.mli commitment_repr.ml - parameters_repr.mli parameters_repr.ml - sapling_repr.ml - lazy_storage_kind.mli lazy_storage_kind.ml - receipt_repr.mli receipt_repr.ml - migration_repr.mli migration_repr.ml - raw_context_intf.ml - raw_context.mli raw_context.ml - storage_costs.mli storage_costs.ml - storage_sigs.ml - storage_functors.mli storage_functors.ml - storage.mli storage.ml - cache_repr.mli cache_repr.ml - constants_storage.mli constants_storage.ml - level_storage.mli level_storage.ml - nonce_storage.mli nonce_storage.ml - seed_storage.mli seed_storage.ml - roll_storage_legacy.mli roll_storage_legacy.ml - contract_manager_storage.mli contract_manager_storage.ml - delegate_activation_storage.mli delegate_activation_storage.ml - frozen_deposits_storage.mli frozen_deposits_storage.ml - stake_storage.mli stake_storage.ml - contract_delegate_storage.mli contract_delegate_storage.ml - sapling_storage.ml - lazy_storage_diff.mli lazy_storage_diff.ml - contract_storage.mli contract_storage.ml - commitment_storage.mli commitment_storage.ml - token.mli token.ml - delegate_storage.mli delegate_storage.ml - bootstrap_storage.mli bootstrap_storage.ml - voting_period_storage.mli voting_period_storage.ml - vote_storage.mli vote_storage.ml - fees_storage.mli fees_storage.ml - ticket_storage.mli ticket_storage.ml - liquidity_baking_repr.mli liquidity_baking_repr.ml - liquidity_baking_cpmm.ml - liquidity_baking_lqt.ml - liquidity_baking_migration.mli liquidity_baking_migration.ml - init_storage.mli init_storage.ml - sapling_validator.ml - global_constants_costs.mli global_constants_costs.ml - global_constants_storage.mli global_constants_storage.ml - alpha_context.mli alpha_context.ml - local_gas_counter.ml - gas_monad.mli gas_monad.ml - script_tc_errors.ml - script_ir_annot.mli script_ir_annot.ml - script_typed_ir.mli script_typed_ir.ml - script_typed_ir_size.mli script_typed_ir_size.ml - script_typed_ir_size_costs.mli script_typed_ir_size_costs.ml - michelson_v1_gas.mli michelson_v1_gas.ml - script_list.mli script_list.ml - script_comparable.mli script_comparable.ml - script_set.mli script_set.ml - script_map.mli script_map.ml - script_ir_translator.mli script_ir_translator.ml - script_cache.mli script_cache.ml - script_tc_errors_registration.mli script_tc_errors_registration.ml - ticket_costs.mli ticket_costs.ml - ticket_scanner.mli ticket_scanner.ml - ticket_balance_key.mli ticket_balance_key.ml - script_interpreter_defs.ml - script_interpreter.mli script_interpreter.ml - baking.mli baking.ml - amendment.mli amendment.ml - apply_results.mli apply_results.ml - apply.mli apply.ml - services_registration.mli services_registration.ml - constants_services.mli constants_services.ml - sapling_services.ml - contract_services.mli contract_services.ml - delegate_services.mli delegate_services.ml - voting_services.mli voting_services.ml - alpha_services.mli alpha_services.ml - main.mli main.ml - (:src_dir TEZOS_PROTOCOL)) - (action - (with-stdout-to %{targets} - (chdir %{workspace_root} (run %{bin:tezos-embedded-protocol-packer} "%{src_dir}" "012_Psithaca"))))) - -(rule - (targets functor.ml) - (deps - misc.mli misc.ml - non_empty_string.mli non_empty_string.ml - path_encoding.mli path_encoding.ml - storage_description.mli storage_description.ml - state_hash.mli state_hash.ml - nonce_hash.mli nonce_hash.ml - script_expr_hash.mli script_expr_hash.ml - contract_hash.mli contract_hash.ml - blinded_public_key_hash.mli blinded_public_key_hash.ml - block_payload_hash.mli block_payload_hash.ml - slot_repr.mli slot_repr.ml - tez_repr.mli tez_repr.ml - period_repr.mli period_repr.ml - time_repr.mli time_repr.ml - round_repr.mli round_repr.ml - block_payload_repr.mli block_payload_repr.ml - fixed_point_repr.mli fixed_point_repr.ml - saturation_repr.mli saturation_repr.ml - gas_limit_repr.mli gas_limit_repr.ml - constants_repr.mli constants_repr.ml - raw_level_repr.mli raw_level_repr.ml - fitness_repr.mli fitness_repr.ml - cycle_repr.mli cycle_repr.ml - level_repr.mli level_repr.ml - seed_repr.mli seed_repr.ml - sampler.mli sampler.ml - voting_period_repr.mli voting_period_repr.ml - script_string_repr.mli script_string_repr.ml - script_int_repr.mli script_int_repr.ml - script_timestamp_repr.mli script_timestamp_repr.ml - michelson_v1_primitives.mli michelson_v1_primitives.ml - script_repr.mli script_repr.ml - cache_memory_helpers.ml - contract_repr.mli contract_repr.ml - roll_repr_legacy.mli roll_repr_legacy.ml - vote_repr.mli vote_repr.ml - block_header_repr.mli block_header_repr.ml - operation_repr.mli operation_repr.ml - manager_repr.mli manager_repr.ml - commitment_repr.mli commitment_repr.ml - parameters_repr.mli parameters_repr.ml - sapling_repr.ml - lazy_storage_kind.mli lazy_storage_kind.ml - receipt_repr.mli receipt_repr.ml - migration_repr.mli migration_repr.ml - raw_context_intf.ml - raw_context.mli raw_context.ml - storage_costs.mli storage_costs.ml - storage_sigs.ml - storage_functors.mli storage_functors.ml - storage.mli storage.ml - cache_repr.mli cache_repr.ml - constants_storage.mli constants_storage.ml - level_storage.mli level_storage.ml - nonce_storage.mli nonce_storage.ml - seed_storage.mli seed_storage.ml - roll_storage_legacy.mli roll_storage_legacy.ml - contract_manager_storage.mli contract_manager_storage.ml - delegate_activation_storage.mli delegate_activation_storage.ml - frozen_deposits_storage.mli frozen_deposits_storage.ml - stake_storage.mli stake_storage.ml - contract_delegate_storage.mli contract_delegate_storage.ml - sapling_storage.ml - lazy_storage_diff.mli lazy_storage_diff.ml - contract_storage.mli contract_storage.ml - commitment_storage.mli commitment_storage.ml - token.mli token.ml - delegate_storage.mli delegate_storage.ml - bootstrap_storage.mli bootstrap_storage.ml - voting_period_storage.mli voting_period_storage.ml - vote_storage.mli vote_storage.ml - fees_storage.mli fees_storage.ml - ticket_storage.mli ticket_storage.ml - liquidity_baking_repr.mli liquidity_baking_repr.ml - liquidity_baking_cpmm.ml - liquidity_baking_lqt.ml - liquidity_baking_migration.mli liquidity_baking_migration.ml - init_storage.mli init_storage.ml - sapling_validator.ml - global_constants_costs.mli global_constants_costs.ml - global_constants_storage.mli global_constants_storage.ml - alpha_context.mli alpha_context.ml - local_gas_counter.ml - gas_monad.mli gas_monad.ml - script_tc_errors.ml - script_ir_annot.mli script_ir_annot.ml - script_typed_ir.mli script_typed_ir.ml - script_typed_ir_size.mli script_typed_ir_size.ml - script_typed_ir_size_costs.mli script_typed_ir_size_costs.ml - michelson_v1_gas.mli michelson_v1_gas.ml - script_list.mli script_list.ml - script_comparable.mli script_comparable.ml - script_set.mli script_set.ml - script_map.mli script_map.ml - script_ir_translator.mli script_ir_translator.ml - script_cache.mli script_cache.ml - script_tc_errors_registration.mli script_tc_errors_registration.ml - ticket_costs.mli ticket_costs.ml - ticket_scanner.mli ticket_scanner.ml - ticket_balance_key.mli ticket_balance_key.ml - script_interpreter_defs.ml - script_interpreter.mli script_interpreter.ml - baking.mli baking.ml - amendment.mli amendment.ml - apply_results.mli apply_results.ml - apply.mli apply.ml - services_registration.mli services_registration.ml - constants_services.mli constants_services.ml - sapling_services.ml - contract_services.mli contract_services.ml - delegate_services.mli delegate_services.ml - voting_services.mli voting_services.ml - alpha_services.mli alpha_services.ml - main.mli main.ml - (:src_dir TEZOS_PROTOCOL)) - (action (with-stdout-to %{targets} - (chdir %{workspace_root} - (run %{bin:tezos-protocol-compiler.tezos-protocol-packer} %{src_dir}))))) - -(rule - (targets protocol.ml) - (deps - misc.mli misc.ml - non_empty_string.mli non_empty_string.ml - path_encoding.mli path_encoding.ml - storage_description.mli storage_description.ml - state_hash.mli state_hash.ml - nonce_hash.mli nonce_hash.ml - script_expr_hash.mli script_expr_hash.ml - contract_hash.mli contract_hash.ml - blinded_public_key_hash.mli blinded_public_key_hash.ml - block_payload_hash.mli block_payload_hash.ml - slot_repr.mli slot_repr.ml - tez_repr.mli tez_repr.ml - period_repr.mli period_repr.ml - time_repr.mli time_repr.ml - round_repr.mli round_repr.ml - block_payload_repr.mli block_payload_repr.ml - fixed_point_repr.mli fixed_point_repr.ml - saturation_repr.mli saturation_repr.ml - gas_limit_repr.mli gas_limit_repr.ml - constants_repr.mli constants_repr.ml - raw_level_repr.mli raw_level_repr.ml - fitness_repr.mli fitness_repr.ml - cycle_repr.mli cycle_repr.ml - level_repr.mli level_repr.ml - seed_repr.mli seed_repr.ml - sampler.mli sampler.ml - voting_period_repr.mli voting_period_repr.ml - script_string_repr.mli script_string_repr.ml - script_int_repr.mli script_int_repr.ml - script_timestamp_repr.mli script_timestamp_repr.ml - michelson_v1_primitives.mli michelson_v1_primitives.ml - script_repr.mli script_repr.ml - cache_memory_helpers.ml - contract_repr.mli contract_repr.ml - roll_repr_legacy.mli roll_repr_legacy.ml - vote_repr.mli vote_repr.ml - block_header_repr.mli block_header_repr.ml - operation_repr.mli operation_repr.ml - manager_repr.mli manager_repr.ml - commitment_repr.mli commitment_repr.ml - parameters_repr.mli parameters_repr.ml - sapling_repr.ml - lazy_storage_kind.mli lazy_storage_kind.ml - receipt_repr.mli receipt_repr.ml - migration_repr.mli migration_repr.ml - raw_context_intf.ml - raw_context.mli raw_context.ml - storage_costs.mli storage_costs.ml - storage_sigs.ml - storage_functors.mli storage_functors.ml - storage.mli storage.ml - cache_repr.mli cache_repr.ml - constants_storage.mli constants_storage.ml - level_storage.mli level_storage.ml - nonce_storage.mli nonce_storage.ml - seed_storage.mli seed_storage.ml - roll_storage_legacy.mli roll_storage_legacy.ml - contract_manager_storage.mli contract_manager_storage.ml - delegate_activation_storage.mli delegate_activation_storage.ml - frozen_deposits_storage.mli frozen_deposits_storage.ml - stake_storage.mli stake_storage.ml - contract_delegate_storage.mli contract_delegate_storage.ml - sapling_storage.ml - lazy_storage_diff.mli lazy_storage_diff.ml - contract_storage.mli contract_storage.ml - commitment_storage.mli commitment_storage.ml - token.mli token.ml - delegate_storage.mli delegate_storage.ml - bootstrap_storage.mli bootstrap_storage.ml - voting_period_storage.mli voting_period_storage.ml - vote_storage.mli vote_storage.ml - fees_storage.mli fees_storage.ml - ticket_storage.mli ticket_storage.ml - liquidity_baking_repr.mli liquidity_baking_repr.ml - liquidity_baking_cpmm.ml - liquidity_baking_lqt.ml - liquidity_baking_migration.mli liquidity_baking_migration.ml - init_storage.mli init_storage.ml - sapling_validator.ml - global_constants_costs.mli global_constants_costs.ml - global_constants_storage.mli global_constants_storage.ml - alpha_context.mli alpha_context.ml - local_gas_counter.ml - gas_monad.mli gas_monad.ml - script_tc_errors.ml - script_ir_annot.mli script_ir_annot.ml - script_typed_ir.mli script_typed_ir.ml - script_typed_ir_size.mli script_typed_ir_size.ml - script_typed_ir_size_costs.mli script_typed_ir_size_costs.ml - michelson_v1_gas.mli michelson_v1_gas.ml - script_list.mli script_list.ml - script_comparable.mli script_comparable.ml - script_set.mli script_set.ml - script_map.mli script_map.ml - script_ir_translator.mli script_ir_translator.ml - script_cache.mli script_cache.ml - script_tc_errors_registration.mli script_tc_errors_registration.ml - ticket_costs.mli ticket_costs.ml - ticket_scanner.mli ticket_scanner.ml - ticket_balance_key.mli ticket_balance_key.ml - script_interpreter_defs.ml - script_interpreter.mli script_interpreter.ml - baking.mli baking.ml - amendment.mli amendment.ml - apply_results.mli apply_results.ml - apply.mli apply.ml - services_registration.mli services_registration.ml - constants_services.mli constants_services.ml - sapling_services.ml - contract_services.mli contract_services.ml - delegate_services.mli delegate_services.ml - voting_services.mli voting_services.ml - alpha_services.mli alpha_services.ml - main.mli main.ml) - (action - (write-file %{targets} - "module Environment = Tezos_protocol_environment_012_Psithaca.Environment -let hash = Tezos_crypto.Protocol_hash.of_b58check_exn \"PsithacaTTq3oumpKDw1pVvRrAtqiK4hKnP3Q4FNrXN9yc6KPhp\" -let name = Environment.Name.name -include Tezos_raw_protocol_012_Psithaca -include Tezos_raw_protocol_012_Psithaca.Main -"))) - -(library - (name tezos_protocol_environment_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-protocol-012-Psithaca.environment) - (library_flags (:standard -linkall)) - (libraries tezos-protocol-environment) - (modules Environment)) - -(library - (name tezos_raw_protocol_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-protocol-012-Psithaca.raw) - (libraries tezos_protocol_environment_012_Psithaca) - (library_flags (:standard -linkall)) - (flags (:standard -nopervasives -nostdlib - -w +a-4-40..42-44-45-48 - -warn-error +a - -open Tezos_protocol_environment_012_Psithaca__Environment - -open Pervasives - -open Error_monad)) - (modules - Misc - Non_empty_string - Path_encoding - Storage_description - State_hash - Nonce_hash - Script_expr_hash - Contract_hash - Blinded_public_key_hash - Block_payload_hash - Slot_repr - Tez_repr - Period_repr - Time_repr - Round_repr - Block_payload_repr - Fixed_point_repr - Saturation_repr - Gas_limit_repr - Constants_repr - Raw_level_repr - Fitness_repr - Cycle_repr - Level_repr - Seed_repr - Sampler - Voting_period_repr - Script_string_repr - Script_int_repr - Script_timestamp_repr - Michelson_v1_primitives - Script_repr - Cache_memory_helpers - Contract_repr - Roll_repr_legacy - Vote_repr - Block_header_repr - Operation_repr - Manager_repr - Commitment_repr - Parameters_repr - Sapling_repr - Lazy_storage_kind - Receipt_repr - Migration_repr - Raw_context_intf - Raw_context - Storage_costs - Storage_sigs - Storage_functors - Storage - Cache_repr - Constants_storage - Level_storage - Nonce_storage - Seed_storage - Roll_storage_legacy - Contract_manager_storage - Delegate_activation_storage - Frozen_deposits_storage - Stake_storage - Contract_delegate_storage - Sapling_storage - Lazy_storage_diff - Contract_storage - Commitment_storage - Token - Delegate_storage - Bootstrap_storage - Voting_period_storage - Vote_storage - Fees_storage - Ticket_storage - Liquidity_baking_repr - Liquidity_baking_cpmm - Liquidity_baking_lqt - Liquidity_baking_migration - Init_storage - Sapling_validator - Global_constants_costs - Global_constants_storage - Alpha_context - Local_gas_counter - Gas_monad - Script_tc_errors - Script_ir_annot - Script_typed_ir - Script_typed_ir_size - Script_typed_ir_size_costs - Michelson_v1_gas - Script_list - Script_comparable - Script_set - Script_map - Script_ir_translator - Script_cache - Script_tc_errors_registration - Ticket_costs - Ticket_scanner - Ticket_balance_key - Script_interpreter_defs - Script_interpreter - Baking - Amendment - Apply_results - Apply - Services_registration - Constants_services - Sapling_services - Contract_services - Delegate_services - Voting_services - Alpha_services - Main)) - -(install - (section lib) - (package tezos-protocol-012-Psithaca) - (files (TEZOS_PROTOCOL as raw/TEZOS_PROTOCOL))) - -(library - (name tezos_protocol_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-protocol-012-Psithaca) - (libraries - tezos-protocol-environment - tezos-protocol-environment-sigs - tezos_raw_protocol_012_Psithaca) - (flags -w "+a-4-40..42-44-45-48" - -warn-error "+a" - -nopervasives) - (modules Protocol)) - -(library - (name tezos_protocol_012_Psithaca_functor) - ; The instrumentation is removed as it can lead to a stack overflow - ; https://gitlab.com/tezos/tezos/-/issues/1927 - ; (instrumentation (backend bisect_ppx)) - (public_name tezos-protocol-functor-012-Psithaca) - (libraries - tezos-protocol-environment - tezos-protocol-environment-sigs - tezos-protocol-012-Psithaca.raw) - (flags -w "+a-4-40..42-44-45-48" - -warn-error "+a" - -nopervasives) - (modules Functor)) - -(library - (name tezos_embedded_protocol_012_Psithaca) - (instrumentation (backend bisect_ppx)) - (public_name tezos-embedded-protocol-012-Psithaca) - (library_flags (:standard -linkall)) - (libraries tezos-protocol-012-Psithaca - tezos-protocol-updater - tezos-protocol-environment) - (flags (:standard -w +a-4-40..42-44-45-48 - -warn-error +a)) - (modules Registerer)) - -(rule - (alias runtest_compile_protocol) - (deps - misc.mli misc.ml - non_empty_string.mli non_empty_string.ml - path_encoding.mli path_encoding.ml - storage_description.mli storage_description.ml - state_hash.mli state_hash.ml - nonce_hash.mli nonce_hash.ml - script_expr_hash.mli script_expr_hash.ml - contract_hash.mli contract_hash.ml - blinded_public_key_hash.mli blinded_public_key_hash.ml - block_payload_hash.mli block_payload_hash.ml - slot_repr.mli slot_repr.ml - tez_repr.mli tez_repr.ml - period_repr.mli period_repr.ml - time_repr.mli time_repr.ml - round_repr.mli round_repr.ml - block_payload_repr.mli block_payload_repr.ml - fixed_point_repr.mli fixed_point_repr.ml - saturation_repr.mli saturation_repr.ml - gas_limit_repr.mli gas_limit_repr.ml - constants_repr.mli constants_repr.ml - raw_level_repr.mli raw_level_repr.ml - fitness_repr.mli fitness_repr.ml - cycle_repr.mli cycle_repr.ml - level_repr.mli level_repr.ml - seed_repr.mli seed_repr.ml - sampler.mli sampler.ml - voting_period_repr.mli voting_period_repr.ml - script_string_repr.mli script_string_repr.ml - script_int_repr.mli script_int_repr.ml - script_timestamp_repr.mli script_timestamp_repr.ml - michelson_v1_primitives.mli michelson_v1_primitives.ml - script_repr.mli script_repr.ml - cache_memory_helpers.ml - contract_repr.mli contract_repr.ml - roll_repr_legacy.mli roll_repr_legacy.ml - vote_repr.mli vote_repr.ml - block_header_repr.mli block_header_repr.ml - operation_repr.mli operation_repr.ml - manager_repr.mli manager_repr.ml - commitment_repr.mli commitment_repr.ml - parameters_repr.mli parameters_repr.ml - sapling_repr.ml - lazy_storage_kind.mli lazy_storage_kind.ml - receipt_repr.mli receipt_repr.ml - migration_repr.mli migration_repr.ml - raw_context_intf.ml - raw_context.mli raw_context.ml - storage_costs.mli storage_costs.ml - storage_sigs.ml - storage_functors.mli storage_functors.ml - storage.mli storage.ml - cache_repr.mli cache_repr.ml - constants_storage.mli constants_storage.ml - level_storage.mli level_storage.ml - nonce_storage.mli nonce_storage.ml - seed_storage.mli seed_storage.ml - roll_storage_legacy.mli roll_storage_legacy.ml - contract_manager_storage.mli contract_manager_storage.ml - delegate_activation_storage.mli delegate_activation_storage.ml - frozen_deposits_storage.mli frozen_deposits_storage.ml - stake_storage.mli stake_storage.ml - contract_delegate_storage.mli contract_delegate_storage.ml - sapling_storage.ml - lazy_storage_diff.mli lazy_storage_diff.ml - contract_storage.mli contract_storage.ml - commitment_storage.mli commitment_storage.ml - token.mli token.ml - delegate_storage.mli delegate_storage.ml - bootstrap_storage.mli bootstrap_storage.ml - voting_period_storage.mli voting_period_storage.ml - vote_storage.mli vote_storage.ml - fees_storage.mli fees_storage.ml - ticket_storage.mli ticket_storage.ml - liquidity_baking_repr.mli liquidity_baking_repr.ml - liquidity_baking_cpmm.ml - liquidity_baking_lqt.ml - liquidity_baking_migration.mli liquidity_baking_migration.ml - init_storage.mli init_storage.ml - sapling_validator.ml - global_constants_costs.mli global_constants_costs.ml - global_constants_storage.mli global_constants_storage.ml - alpha_context.mli alpha_context.ml - local_gas_counter.ml - gas_monad.mli gas_monad.ml - script_tc_errors.ml - script_ir_annot.mli script_ir_annot.ml - script_typed_ir.mli script_typed_ir.ml - script_typed_ir_size.mli script_typed_ir_size.ml - script_typed_ir_size_costs.mli script_typed_ir_size_costs.ml - michelson_v1_gas.mli michelson_v1_gas.ml - script_list.mli script_list.ml - script_comparable.mli script_comparable.ml - script_set.mli script_set.ml - script_map.mli script_map.ml - script_ir_translator.mli script_ir_translator.ml - script_cache.mli script_cache.ml - script_tc_errors_registration.mli script_tc_errors_registration.ml - ticket_costs.mli ticket_costs.ml - ticket_scanner.mli ticket_scanner.ml - ticket_balance_key.mli ticket_balance_key.ml - script_interpreter_defs.ml - script_interpreter.mli script_interpreter.ml - baking.mli baking.ml - amendment.mli amendment.ml - apply_results.mli apply_results.ml - apply.mli apply.ml - services_registration.mli services_registration.ml - constants_services.mli constants_services.ml - sapling_services.ml - contract_services.mli contract_services.ml - delegate_services.mli delegate_services.ml - voting_services.mli voting_services.ml - alpha_services.mli alpha_services.ml - main.mli main.ml - (:src_dir TEZOS_PROTOCOL)) - (action (run %{bin:tezos-protocol-compiler} .))) - -(rule - (alias runtest_sandbox) - (deps .tezos_protocol_012_Psithaca.objs/native/tezos_protocol_012_Psithaca.cmx) - (action (progn))) - -(rule - (alias runtest) - (package tezos-protocol-012-Psithaca) - (deps (alias runtest_sandbox)) - (action (progn))) diff --git a/src/proto_012_Psithaca/lib_protocol/fees_storage.ml b/src/proto_012_Psithaca/lib_protocol/fees_storage.ml deleted file mode 100644 index b156a09a3d1a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/fees_storage.ml +++ /dev/null @@ -1,111 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += Cannot_pay_storage_fee (* `Temporary *) - -type error += Operation_quota_exceeded (* `Temporary *) - -type error += Storage_limit_too_high (* `Permanent *) - -let () = - let open Data_encoding in - register_error_kind - `Temporary - ~id:"contract.cannot_pay_storage_fee" - ~title:"Cannot pay storage fee" - ~description:"The storage fee is higher than the contract balance" - ~pp:(fun ppf () -> Format.fprintf ppf "Cannot pay storage storage fee") - Data_encoding.empty - (function Cannot_pay_storage_fee -> Some () | _ -> None) - (fun () -> Cannot_pay_storage_fee) ; - register_error_kind - `Temporary - ~id:"storage_exhausted.operation" - ~title:"Storage quota exceeded for the operation" - ~description: - "A script or one of its callee wrote more bytes than the operation said \ - it would" - Data_encoding.empty - (function Operation_quota_exceeded -> Some () | _ -> None) - (fun () -> Operation_quota_exceeded) ; - register_error_kind - `Permanent - ~id:"storage_limit_too_high" - ~title:"Storage limit out of protocol hard bounds" - ~description:"A transaction tried to exceed the hard limit on storage" - empty - (function Storage_limit_too_high -> Some () | _ -> None) - (fun () -> Storage_limit_too_high) - -let record_global_constant_storage_space context size = - (* Following the precedent of big_map, a key in the - global table of constants costs 65 bytes (see - [Lazy_storage_diff.Big_map.bytes_size_for_big_map_key])*) - let cost_of_key = Z.of_int 65 in - let to_be_paid = Z.add size cost_of_key in - (context, to_be_paid) - -let record_paid_storage_space c contract = - Contract_storage.used_storage_space c contract >>=? fun size -> - Contract_storage.set_paid_storage_space_and_return_fees_to_pay c contract size - >>=? fun (to_be_paid, c) -> return (c, size, to_be_paid) - -let source_must_exist c src = - match src with - | `Contract src -> Contract_storage.must_exist c src - | _ -> return_unit - -let burn_storage_fees ?(origin = Receipt_repr.Block_application) c - ~storage_limit ~payer consumed = - let remaining = Z.sub storage_limit consumed in - if Compare.Z.(remaining < Z.zero) then fail Operation_quota_exceeded - else - let cost_per_byte = Constants_storage.cost_per_byte c in - Tez_repr.(cost_per_byte *? Z.to_int64 consumed) >>?= fun to_burn -> - (* Burning the fees... *) - if Tez_repr.(to_burn = Tez_repr.zero) then - (* If the payer was deleted by transferring all its balance, and no space - was used, burning zero would fail *) - return (c, remaining, []) - else - trace - Cannot_pay_storage_fee - ( source_must_exist c payer >>=? fun () -> - Token.transfer ~origin c payer `Storage_fees to_burn - >>=? fun (ctxt, balance_updates) -> - return (ctxt, remaining, balance_updates) ) - -let burn_origination_fees ?(origin = Receipt_repr.Block_application) c - ~storage_limit ~payer = - let origination_size = Constants_storage.origination_size c in - burn_storage_fees ~origin c ~storage_limit ~payer (Z.of_int origination_size) - -let check_storage_limit c ~storage_limit = - if - Compare.Z.( - storage_limit > (Raw_context.constants c).hard_storage_limit_per_operation) - || Compare.Z.(storage_limit < Z.zero) - then error Storage_limit_too_high - else Result.return_unit diff --git a/src/proto_012_Psithaca/lib_protocol/fees_storage.mli b/src/proto_012_Psithaca/lib_protocol/fees_storage.mli deleted file mode 100644 index fcb5ae412492..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/fees_storage.mli +++ /dev/null @@ -1,77 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += Cannot_pay_storage_fee (* `Temporary *) - -type error += Operation_quota_exceeded (* `Temporary *) - -type error += Storage_limit_too_high (* `Permanent *) - -(** [record_global_constant_storage_space ctxt size] records - paid storage space for registering a new global constant. - Cost is in bytes + 65 additional bytes for the key - hash of the expression. Returns new context and the cost. -*) -val record_global_constant_storage_space : - Raw_context.t -> Z.t -> Raw_context.t * Z.t - -(** [record_paid_storage_space ctxt contract] updates the amount of storage - consumed by the [contract] and considered as accounted for as far as - future payment is concerned. Returns a new context, the total space - consumed by the [contract], and the additional (and unpaid) space consumed - since the last call of this function on this [contract]. *) -val record_paid_storage_space : - Raw_context.t -> Contract_repr.t -> (Raw_context.t * Z.t * Z.t) tzresult Lwt.t - -(** [check_storage_limit ctxt ~storage_limit] raises the [Storage_limit_too_high] - error iff [storage_limit] is negative or greater the constant - [hard_storage_limit_per_operation]. *) -val check_storage_limit : Raw_context.t -> storage_limit:Z.t -> unit tzresult - -(** [burn_storage_fees ctxt ~storage_limit ~payer consumed] takes funds from the - [payer] to pay the cost of the [consumed] storage. This function has an - optional parameter [~origin] that allows to set the origin of returned - balance updates (by default the parameter is set to [Block_application]). - Returns an updated context, an updated storage limit equal to - [storage_limit - consumed], and the relevant balance updates. - Raises the [Operation_quota_exceeded] error if [storage_limit < consumed]. - Raises the [Cannot_pay_storage_fee] error if the funds from the [payer] are - not sufficient to pay the storage fees. *) -val burn_storage_fees : - ?origin:Receipt_repr.update_origin -> - Raw_context.t -> - storage_limit:Z.t -> - payer:Token.source -> - Z.t -> - (Raw_context.t * Z.t * Receipt_repr.balance_updates) tzresult Lwt.t - -(** Calls [burn_storage_fees] with the parameter [consumed] mapped to the - constant [origination_size]. *) -val burn_origination_fees : - ?origin:Receipt_repr.update_origin -> - Raw_context.t -> - storage_limit:Z.t -> - payer:Token.source -> - (Raw_context.t * Z.t * Receipt_repr.balance_updates) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/fitness_repr.ml b/src/proto_012_Psithaca/lib_protocol/fitness_repr.ml deleted file mode 100644 index 0a1c3bd7fa8a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/fitness_repr.ml +++ /dev/null @@ -1,289 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = { - level : Raw_level_repr.t; - locked_round : Round_repr.t option; - predecessor_round : Round_repr.t; - (* by convention, predecessor_round is 0 in case of protocol migration *) - round : Round_repr.t; -} - -let encoding = - let open Data_encoding in - def - "fitness" - (conv_with_guard - (fun {level; locked_round; predecessor_round; round} -> - (level, locked_round, predecessor_round, round)) - (fun (level, locked_round, predecessor_round, round) -> - match locked_round with - | None -> ok {level; locked_round; predecessor_round; round} - | Some locked_round_val -> - if Round_repr.(round <= locked_round_val) then - Error "Locked round must be smaller than round." - else ok {level; locked_round; predecessor_round; round}) - (obj4 - (req "level" Raw_level_repr.encoding) - (req "locked_round" (option Round_repr.encoding)) - (req "predecessor_round" Round_repr.encoding) - (req "round" Round_repr.encoding))) - -let pp ppf f = - let minus_sign = - if Round_repr.(f.predecessor_round = Round_repr.zero) then "" else "-" - in - let locked_round ppf locked_round = - match locked_round with - | None -> Format.pp_print_string ppf "unlocked" - | Some round -> Format.fprintf ppf "locked: %a" Round_repr.pp round - in - Format.fprintf - ppf - "(%a, %a, %s%a, %a)" - Raw_level_repr.pp - f.level - locked_round - f.locked_round - minus_sign - Round_repr.pp - f.predecessor_round - Round_repr.pp - f.round - -type error += - | (* `Permanent *) Invalid_fitness - | (* `Permanent *) Wrong_fitness - | (* `Permanent *) Outdated_fitness - | (* `Permanent *) - Locked_round_not_less_than_round of { - round : Round_repr.t; - locked_round : Round_repr.t; - } - -let () = - register_error_kind - `Permanent - ~id:"invalid_fitness" - ~title:"Invalid fitness" - ~description: - "Fitness representation should be exactly 4 times 4 bytes long." - ~pp:(fun ppf () -> Format.fprintf ppf "Invalid fitness") - Data_encoding.empty - (function Invalid_fitness -> Some () | _ -> None) - (fun () -> Invalid_fitness) ; - register_error_kind - `Permanent - ~id:"wrong_fitness" - ~title:"Wrong fitness" - ~description:"Wrong fitness." - ~pp:(fun ppf () -> Format.fprintf ppf "Wrong fitness.") - Data_encoding.empty - (function Wrong_fitness -> Some () | _ -> None) - (fun () -> Wrong_fitness) ; - register_error_kind - `Permanent - ~id:"outdated_fitness" - ~title:"Outdated fitness" - ~description:"Outdated fitness: referring to a previous version" - ~pp:(fun ppf () -> - Format.fprintf ppf "Outdated fitness: referring to a previous version.") - Data_encoding.empty - (function Outdated_fitness -> Some () | _ -> None) - (fun () -> Outdated_fitness) ; - register_error_kind - `Permanent - ~id:"locked_round_not_less_than_round" - ~title:"Locked round not smaller than round" - ~description:"The round is smaller than or equal to the locked round." - ~pp:(fun ppf (round, locked_round) -> - Format.fprintf - ppf - "Incorrect fitness: round %a is less than or equal to locked round %a." - Round_repr.pp - round - Round_repr.pp - locked_round) - Data_encoding.( - obj2 - (req "round" Round_repr.encoding) - (req "locked_round" Round_repr.encoding)) - (function - | Locked_round_not_less_than_round {round; locked_round} -> - Some (round, locked_round) - | _ -> None) - (fun (round, locked_round) -> - Locked_round_not_less_than_round {round; locked_round}) - -let create_without_locked_round ~level ~predecessor_round ~round = - {level; locked_round = None; predecessor_round; round} - -let create ~level ~locked_round ~predecessor_round ~round = - match locked_round with - | None -> ok {level; locked_round; predecessor_round; round} - | Some locked_round_val -> - error_when - Round_repr.(round <= locked_round_val) - (Locked_round_not_less_than_round - {round; locked_round = locked_round_val}) - >>? fun () -> ok {level; locked_round; predecessor_round; round} - -let int32_to_bytes i = - let b = Bytes.make 4 '\000' in - TzEndian.set_int32 b 0 i ; - b - -let int32_of_bytes b = - if Compare.Int.(Bytes.length b <> 4) then error Invalid_fitness - else ok (TzEndian.get_int32 b 0) - -(* Locked round is an option. And we want None to be smaller than any other - value. The way the shell handles the order makes the empty Bytes smaller - than any other *) -let locked_round_to_bytes = function - | None -> Bytes.empty - | Some locked_round -> int32_to_bytes (Round_repr.to_int32 locked_round) - -let locked_round_of_bytes b = - match Bytes.length b with - | 0 -> ok None - | 4 -> Round_repr.of_int32 (TzEndian.get_int32 b 0) >>? fun r -> ok (Some r) - | _ -> error Invalid_fitness - -let predecessor_round_of_bytes neg_predecessor_round = - int32_of_bytes neg_predecessor_round >>? fun neg_predecessor_round -> - Round_repr.of_int32 @@ Int32.pred (Int32.neg neg_predecessor_round) - -let round_of_bytes round = int32_of_bytes round >>? Round_repr.of_int32 - -let to_raw {level; locked_round; predecessor_round; round} = - [ - Bytes.of_string Constants_repr.fitness_version_number; - int32_to_bytes (Raw_level_repr.to_int32 level); - locked_round_to_bytes locked_round; - int32_to_bytes - (Int32.pred (Int32.neg (Round_repr.to_int32 predecessor_round))); - int32_to_bytes (Round_repr.to_int32 round); - ] - -let from_raw = function - | [version; level; locked_round; neg_predecessor_round; round] - when Compare.String.( - Bytes.to_string version = Constants_repr.fitness_version_number) -> - int32_of_bytes level >>? Raw_level_repr.of_int32 >>? fun level -> - locked_round_of_bytes locked_round >>? fun locked_round -> - predecessor_round_of_bytes neg_predecessor_round - >>? fun predecessor_round -> - round_of_bytes round >>? fun round -> - create ~level ~locked_round ~predecessor_round ~round - | [version; _] - when Compare.String.( - Bytes.to_string version < Constants_repr.fitness_version_number) -> - error Outdated_fitness - | [] (* genesis fitness *) -> error Outdated_fitness - | _ -> error Invalid_fitness - -let round_from_raw = function - | [version; _level; _locked_round; _neg_predecessor_round; round] - when Compare.String.( - Bytes.to_string version = Constants_repr.fitness_version_number) -> - round_of_bytes round - | [version; _] - when Compare.String.( - Bytes.to_string version < Constants_repr.fitness_version_number) -> - ok Round_repr.zero - | [] (* genesis fitness *) -> ok Round_repr.zero - | _ -> error Invalid_fitness - -let predecessor_round_from_raw = function - | [version; _level; _locked_round; neg_predecessor_round; _round] - when Compare.String.( - Bytes.to_string version = Constants_repr.fitness_version_number) -> - predecessor_round_of_bytes neg_predecessor_round - | [version; _] - when Compare.String.( - Bytes.to_string version < Constants_repr.fitness_version_number) -> - ok Round_repr.zero - | [] (* genesis fitness *) -> ok Round_repr.zero - | _ -> error Invalid_fitness - -let check_except_locked_round fitness ~level ~predecessor_round = - let { - level = expected_level; - locked_round = _; - predecessor_round = expected_predecessor_round; - round = _; - } = - fitness - in - let correct = - Raw_level_repr.(level = expected_level) - && Round_repr.(predecessor_round = expected_predecessor_round) - in - error_unless correct Wrong_fitness - -let check_locked_round fitness ~locked_round = - let { - level = _; - locked_round = expected_locked_round; - predecessor_round = _; - round = _; - } = - fitness - in - let correct = - match (locked_round, expected_locked_round) with - | (None, None) -> true - | (Some _, None) | (None, Some _) -> false - | (Some v, Some v') -> Round_repr.(v = v') - in - error_unless correct Wrong_fitness - -let level fitness = fitness.level - -let round fitness = fitness.round - -let locked_round fitness = fitness.locked_round - -let predecessor_round fitness = fitness.predecessor_round - -module Internal_for_tests = struct - module ListInt32Compare = Compare.List (Compare.Int32) - - let compare f ff = - let unopt l = - match l with Some l -> Round_repr.to_int32 l | None -> -1l - in - let to_list {level; locked_round; predecessor_round; round} = - Int32. - [ - Raw_level_repr.to_int32 level; - unopt locked_round; - neg (Round_repr.to_int32 predecessor_round); - Round_repr.to_int32 round; - ] - in - ListInt32Compare.compare (to_list f) (to_list ff) -end diff --git a/src/proto_012_Psithaca/lib_protocol/fitness_repr.mli b/src/proto_012_Psithaca/lib_protocol/fitness_repr.mli deleted file mode 100644 index 7a3ebaa8afe4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/fitness_repr.mli +++ /dev/null @@ -1,96 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | (* `Permanent *) Invalid_fitness - | (* `Permanent *) Wrong_fitness - | (* `Permanent *) Outdated_fitness - | (* `Permanent *) - Locked_round_not_less_than_round of { - round : Round_repr.t; - locked_round : Round_repr.t; - } - -type t - -val encoding : t Data_encoding.t - -val pp : Format.formatter -> t -> unit - -val create : - level:Raw_level_repr.t -> - locked_round:Round_repr.t option -> - predecessor_round:Round_repr.t -> - round:Round_repr.t -> - t tzresult - -val create_without_locked_round : - level:Raw_level_repr.t -> - predecessor_round:Round_repr.t -> - round:Round_repr.t -> - t - -val to_raw : t -> Fitness.t - -(** Returns the corresponding protocol fitness if the shell fitness has - the expected version, given by - Constants_repr.fitness_version_number. If the fitness' version is - from a previous protocol version, then it raises an "outdated - fitness" error. If the fitness version is higher then - it raises an "invalid fitness" error. *) -val from_raw : Fitness.t -> t tzresult - -(** Returns the round from a raw fitness. If the fitness is from a - previous protocol, the returned value will be Round.zero. *) -val round_from_raw : Fitness.t -> Round_repr.t tzresult - -(** Returns the predecessor round from a raw fitness. If the fitness - is from a previous protocol, the returned value will be Round.zero. *) -val predecessor_round_from_raw : Fitness.t -> Round_repr.t tzresult - -(** Validate only the part of the fitness for which information are - available during begin_application *) -val check_except_locked_round : - t -> level:Raw_level_repr.t -> predecessor_round:Round_repr.t -> unit tzresult - -(** Validate the locked_round component of the fitness, which could - not be validated during begin_application. *) -val check_locked_round : t -> locked_round:Round_repr.t option -> unit tzresult - -val level : t -> Raw_level_repr.t - -val round : t -> Round_repr.t - -val locked_round : t -> Round_repr.t option - -val predecessor_round : t -> Round_repr.t - -(**/**) - -module Internal_for_tests : sig - (** uses a lexicographic order relation for [level, locked_round, - -predecessor_round, round] *) - val compare : t -> t -> int -end diff --git a/src/proto_012_Psithaca/lib_protocol/fixed_point_repr.ml b/src/proto_012_Psithaca/lib_protocol/fixed_point_repr.ml deleted file mode 100644 index 531fd045f453..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/fixed_point_repr.ml +++ /dev/null @@ -1,94 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type fp_tag (* Tag for fixed point computations *) - -type integral_tag (* Tag for integral computations *) - -module type Safe = sig - type 'a t [@@coq_phantom] - - type fp = fp_tag t - - type integral = integral_tag t - - val integral_exn : Z.t -> integral - - val integral_of_int_exn : int -> integral - - val integral_to_z : integral -> Z.t - - val zero : 'a t - - val add : 'a t -> 'a t -> 'a t - - val sub : 'a t -> 'a t -> 'a t - - val ceil : fp -> integral - - val floor : fp -> integral - - val fp : 'a t -> fp - - val ( = ) : 'a t -> 'b t -> bool - - val ( <> ) : 'a t -> 'b t -> bool - - val ( < ) : 'a t -> 'b t -> bool - - val ( <= ) : 'a t -> 'b t -> bool - - val ( >= ) : 'a t -> 'b t -> bool - - val ( > ) : 'a t -> 'b t -> bool - - val compare : 'a t -> 'b t -> int - - val equal : 'a t -> 'b t -> bool - - val max : 'a t -> 'a t -> 'a t - - val min : 'a t -> 'a t -> 'a t - - val pp : Format.formatter -> 'a t -> unit - - val pp_integral : Format.formatter -> integral -> unit - - val n_fp_encoding : fp Data_encoding.t - - val n_integral_encoding : integral Data_encoding.t - - val z_fp_encoding : fp Data_encoding.t - - val z_integral_encoding : integral Data_encoding.t -end - -module type Full = sig - type 'a t [@@coq_phantom] - - include Safe with type 'a t := 'a t - - val unsafe_fp : Z.t -> fp -end diff --git a/src/proto_012_Psithaca/lib_protocol/fixed_point_repr.mli b/src/proto_012_Psithaca/lib_protocol/fixed_point_repr.mli deleted file mode 100644 index a9dee73a6f6e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/fixed_point_repr.mli +++ /dev/null @@ -1,105 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module defines a standard signature for modules providing fixed-point - arithmetic. *) - -type fp_tag (* Tag for fixed point computations *) - -type integral_tag (* Tag for integral computations *) - -(** A signature for modules implementing a fixed-point arithmetic. - - Fixed-point types come in two flavours: - - integral (marked with [integral_tag]), behaving like integers; - - fp (marked with [fp_tag]), allowing for fractions. - - Such numbers represent standard arithmetic, rounding (converting fp - flavour to integral one) and comparisons (which can work across flavours). *) -module type Safe = sig - type 'a t [@@coq_phantom] - - type fp = fp_tag t - - type integral = integral_tag t - - val integral_exn : Z.t -> integral - - val integral_of_int_exn : int -> integral - - val integral_to_z : integral -> Z.t - - val zero : 'a t - - val add : 'a t -> 'a t -> 'a t - - val sub : 'a t -> 'a t -> 'a t - - val ceil : fp -> integral - - val floor : fp -> integral - - val fp : 'a t -> fp - - val ( = ) : 'a t -> 'b t -> bool - - val ( <> ) : 'a t -> 'b t -> bool - - val ( < ) : 'a t -> 'b t -> bool - - val ( <= ) : 'a t -> 'b t -> bool - - val ( >= ) : 'a t -> 'b t -> bool - - val ( > ) : 'a t -> 'b t -> bool - - val compare : 'a t -> 'b t -> int - - val equal : 'a t -> 'b t -> bool - - val max : 'a t -> 'a t -> 'a t - - val min : 'a t -> 'a t -> 'a t - - val pp : Format.formatter -> 'a t -> unit - - val pp_integral : Format.formatter -> integral -> unit - - val n_fp_encoding : fp Data_encoding.t - - val n_integral_encoding : integral Data_encoding.t - - val z_fp_encoding : fp Data_encoding.t - - val z_integral_encoding : integral Data_encoding.t -end - -module type Full = sig - type 'a t [@@coq_phantom] - - include Safe with type 'a t := 'a t - - val unsafe_fp : Z.t -> fp -end diff --git a/src/proto_012_Psithaca/lib_protocol/frozen_deposits_storage.ml b/src/proto_012_Psithaca/lib_protocol/frozen_deposits_storage.ml deleted file mode 100644 index 26a3141df6bd..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/frozen_deposits_storage.ml +++ /dev/null @@ -1,61 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let init ctxt delegate = - Storage.Contract.Frozen_deposits.init - ctxt - (Contract_repr.implicit_contract delegate) - {initial_amount = Tez_repr.zero; current_amount = Tez_repr.zero} - -let allocated = Storage.Contract.Frozen_deposits.mem - -let get = Storage.Contract.Frozen_deposits.get - -let find = Storage.Contract.Frozen_deposits.find - -let update_balance ctxt delegate f amount = - let delegate_contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Frozen_deposits.get ctxt delegate_contract - >>=? fun frozen_deposits -> - f frozen_deposits.current_amount amount >>?= fun new_amount -> - Storage.Contract.Frozen_deposits.update - ctxt - delegate_contract - {frozen_deposits with current_amount = new_amount} - -let credit_only_call_from_token ctxt delegate amount = - update_balance ctxt delegate Tez_repr.( +? ) amount - -let spend_only_call_from_token ctxt delegate amount = - update_balance ctxt delegate Tez_repr.( -? ) amount - -let update_deposits_cap ctxt delegate_contract deposits_cap = - Storage.Contract.Frozen_deposits.get ctxt delegate_contract - >>=? fun frozen_deposits -> - Storage.Contract.Frozen_deposits.update - ctxt - delegate_contract - {frozen_deposits with initial_amount = deposits_cap} - >|=? fun ctxt -> (ctxt, frozen_deposits.current_amount) diff --git a/src/proto_012_Psithaca/lib_protocol/frozen_deposits_storage.mli b/src/proto_012_Psithaca/lib_protocol/frozen_deposits_storage.mli deleted file mode 100644 index a990dbcf99d8..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/frozen_deposits_storage.mli +++ /dev/null @@ -1,52 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val init : - Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t - -val allocated : Raw_context.t -> Contract_repr.t -> bool Lwt.t - -val get : Raw_context.t -> Contract_repr.t -> Storage.deposits tzresult Lwt.t - -val find : - Raw_context.t -> Contract_repr.t -> Storage.deposits option tzresult Lwt.t - -val credit_only_call_from_token : - Raw_context.t -> - Signature.Public_key_hash.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t - -val spend_only_call_from_token : - Raw_context.t -> - Signature.Public_key_hash.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t - -val update_deposits_cap : - Raw_context.t -> - Contract_repr.t -> - Tez_repr.t -> - (Raw_context.t * Tez_repr.t) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/gas_limit_repr.ml b/src/proto_012_Psithaca/lib_protocol/gas_limit_repr.ml deleted file mode 100644 index b613533863e7..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/gas_limit_repr.ml +++ /dev/null @@ -1,210 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let decimals = 3 - -type fp_tag - -type integral_tag - -module S = Saturation_repr - -(* 1 gas unit *) -let scaling_factor = S.mul_safe_of_int_exn 1000 - -module Arith = struct - type 'a t = S.may_saturate S.t - - type fp = fp_tag t - - type integral = integral_tag t - - let scaling_factor = scaling_factor - - let sub = S.sub - - let add = S.add - - let zero = S.zero - - let min = S.min - - let max = S.max - - let compare = S.compare - - let ( < ) = S.( < ) - - let ( <> ) = S.( <> ) - - let ( > ) = S.( > ) - - let ( <= ) = S.( <= ) - - let ( >= ) = S.( >= ) - - let ( = ) = S.( = ) - - let equal = S.equal - - let of_int_opt = S.of_int_opt - - let fatally_saturated_int i = - failwith (string_of_int i ^ " should not be saturated.") - - let fatally_saturated_z z = - failwith (Z.to_string z ^ " should not be saturated.") - - let integral_of_int_exn i = - S.( - match of_int_opt i with - | None -> fatally_saturated_int i - | Some i' -> - let r = scale_fast scaling_factor i' in - if r = saturated then fatally_saturated_int i else r) - - let integral_exn z = - match Z.to_int z with - | i -> integral_of_int_exn i - | exception Z.Overflow -> fatally_saturated_z z - - let integral_to_z (i : integral) : Z.t = S.(to_z (ediv i scaling_factor)) - - let ceil x = - let r = S.erem x scaling_factor in - if r = zero then x else add x (sub scaling_factor r) - - let floor x = sub x (S.erem x scaling_factor) - - let fp x = x - - let pp fmtr fp = - let q = S.(ediv fp scaling_factor |> to_int) in - let r = S.(erem fp scaling_factor |> to_int) in - if Compare.Int.(r = 0) then Format.fprintf fmtr "%d" q - else Format.fprintf fmtr "%d.%0*d" q decimals r - - let pp_integral = pp - - let n_fp_encoding : fp Data_encoding.t = S.n_encoding - - let z_fp_encoding : fp Data_encoding.t = S.z_encoding - - let n_integral_encoding : integral Data_encoding.t = - Data_encoding.conv integral_to_z integral_exn Data_encoding.n - - let z_integral_encoding : integral Data_encoding.t = - Data_encoding.conv integral_to_z integral_exn Data_encoding.z - - let unsafe_fp x = - match of_int_opt (Z.to_int x) with - | Some int -> int - | None -> fatally_saturated_z x - - let sub_opt = S.sub_opt -end - -type t = Unaccounted | Limited of {remaining : Arith.fp} - -type cost = S.may_saturate S.t - -let encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Limited" - Arith.z_fp_encoding - (function Limited {remaining} -> Some remaining | _ -> None) - (fun remaining -> Limited {remaining}); - case - (Tag 1) - ~title:"Unaccounted" - (constant "unaccounted") - (function Unaccounted -> Some () | _ -> None) - (fun () -> Unaccounted); - ] - -let pp ppf = function - | Unaccounted -> Format.fprintf ppf "unaccounted" - | Limited {remaining} -> - Format.fprintf ppf "%a units remaining" Arith.pp remaining - -let cost_encoding = S.z_encoding - -let pp_cost fmt z = S.pp fmt z - -(* 2 units of gas *) -let allocation_weight = - S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 2)) |> S.mul_safe_exn - -let step_weight = scaling_factor - -(* 100 units of gas *) -let read_base_weight = - S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 100)) |> S.mul_safe_exn - -(* 160 units of gas *) -let write_base_weight = - S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 160)) |> S.mul_safe_exn - -(* 10 units of gas *) -let byte_read_weight = - S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 10)) |> S.mul_safe_exn - -(* 15 units of gas *) -let byte_written_weight = - S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 15)) |> S.mul_safe_exn - -let cost_to_milligas (cost : cost) : Arith.fp = cost - -let raw_consume gas_counter cost = - let gas = cost_to_milligas cost in - Arith.sub_opt gas_counter gas - -let alloc_cost n = - S.scale_fast allocation_weight S.(add n (S.mul_safe_of_int_exn 1)) - -let alloc_bytes_cost n = alloc_cost (S.safe_int ((n + 7) / 8)) - -let atomic_step_cost : 'a S.t -> cost = S.may_saturate - -let step_cost n = S.scale_fast step_weight n - -let free = S.zero - -let read_bytes_cost n = - S.add read_base_weight (S.scale_fast byte_read_weight (S.safe_int n)) - -let write_bytes_cost n = - S.add write_base_weight (S.scale_fast byte_written_weight (S.safe_int n)) - -let ( +@ ) x y = S.add x y - -let ( *@ ) x y = S.mul x y - -let alloc_mbytes_cost n = - alloc_cost (S.mul_safe_of_int_exn 12) +@ alloc_bytes_cost n diff --git a/src/proto_012_Psithaca/lib_protocol/gas_limit_repr.mli b/src/proto_012_Psithaca/lib_protocol/gas_limit_repr.mli deleted file mode 100644 index 3b87007d6ee7..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/gas_limit_repr.mli +++ /dev/null @@ -1,110 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Internal representation of the gas limit available to the node baking a new - block. It should be proportional to the time and energy required to perform a - computation. - - This protects the bakers from performing exceedingly costly computations - while baking and also allows them to select cheaper-to-compute operations to - include in their blocks, as their reward for baking a block is not directly - related to the resources consumed by the machine performing the operation. - - It can be [Unaccounted] (unlimited) or [Limited] to some fixed-point value - (see [Fixed_point_repr] for the details). The value is represented with 3 - decimal places of precision. - - All computations on gas are performed in saturation arithmetic (see - [Saturation_repr]) bounded between [0] and [2 ^ 62 - 1]*) - -module Arith : - Fixed_point_repr.Full - with type 'a t = Saturation_repr.may_saturate Saturation_repr.t -[@@coq_plain_module] - -type t = Unaccounted | Limited of {remaining : Arith.fp} - -val encoding : t Data_encoding.encoding - -val pp : Format.formatter -> t -> unit - -(** Represents a gas cost of an operation. The gas model is constructed such - that the cost of each operation is roughly proportional to the time required - to perform the operation. If the gas cost of an operation exceeds the - available limit, such an operation is rejected. This is especially meant to - protect bakers against DoS attacks. *) -type cost = Saturation_repr.may_saturate Saturation_repr.t - -val cost_encoding : cost Data_encoding.encoding - -val pp_cost : Format.formatter -> cost -> unit - -(** Subtracts the cost from the current limit. Returns [None] if the limit - would fall below [0]. *) -val raw_consume : Arith.fp -> cost -> Arith.fp option - -(** The cost of free operation is [0]. *) -val free : cost - -(** [atomic_step_cost x] corresponds to [x] milliunit of gas. *) -val atomic_step_cost : _ Saturation_repr.t -> cost - -(** [step_cost x] corresponds to [x] units of gas. *) -val step_cost : _ Saturation_repr.t -> cost - -(** Cost of allocating qwords of storage. - - [alloc_cost n] estimates the cost of allocating [n] qwords of storage. *) -val alloc_cost : _ Saturation_repr.t -> cost - -(** Cost of allocating bytes in the storage. - - [alloc_bytes_cost b] estimates the cost of allocating [b] bytes of - storage. *) -val alloc_bytes_cost : int -> cost - -(** Cost of allocating bytes in the storage. - - [alloc_mbytes_cost b] estimates the cost of allocating [b] bytes of - storage and the cost of a header to describe these bytes. *) -val alloc_mbytes_cost : int -> cost - -(** Cost of reading the storage. - - [read_bytes_const n] estimates the cost of reading [n] bytes of storage. *) -val read_bytes_cost : int -> cost - -(** Cost of writing to storage. - - [write_bytes_const n] estimates the cost of writing [n] bytes to the - storage. *) -val write_bytes_cost : int -> cost - -(** Multiply a cost by a factor. Both arguments are saturated arithmetic values, - so no negative numbers are involved. *) -val ( *@ ) : _ Saturation_repr.t -> cost -> cost - -(** Add two costs together. *) -val ( +@ ) : cost -> cost -> cost diff --git a/src/proto_012_Psithaca/lib_protocol/gas_monad.ml b/src/proto_012_Psithaca/lib_protocol/gas_monad.ml deleted file mode 100644 index b0dd6b506d2b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/gas_monad.ml +++ /dev/null @@ -1,53 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -(* The outer [tzresult] is for gas exhaustion only. The inner [result] is for all - other (non-gas) errors. *) -type ('a, 'trace) t = context -> (('a, 'trace) result * context) tzresult - -type ('a, 'trace) gas_monad = ('a, 'trace) t - -let of_result x ctxt = ok (x, ctxt) - -let return x = of_result (ok x) - -let ( >>$ ) m f ctxt = - m ctxt >>? fun (x, ctxt) -> - match x with Ok y -> f y ctxt | Error _ as err -> of_result err ctxt - -let ( >|$ ) m f ctxt = m ctxt >>? fun (x, ctxt) -> of_result (x >|? f) ctxt - -let ( >?$ ) m f = m >>$ fun x -> of_result (f x) - -let ( >??$ ) m f ctxt = m ctxt >>? fun (x, ctxt) -> f x ctxt - -let consume_gas cost ctxt = Gas.consume ctxt cost >>? return () - -let run ctxt x = x ctxt - -let record_trace_eval f m ctxt = - m ctxt >>? fun (x, ctxt) -> of_result (record_trace_eval f x) ctxt diff --git a/src/proto_012_Psithaca/lib_protocol/gas_monad.mli b/src/proto_012_Psithaca/lib_protocol/gas_monad.mli deleted file mode 100644 index ad329151f442..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/gas_monad.mli +++ /dev/null @@ -1,71 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -(** This monad combines: - - a state monad where the state is the context - - two levels of error monad to distinguish gas exhaustion from other errors - - It is useful for backtracking on type checking errors without backtracking - the consumed gas. -*) -type ('a, 'trace) t - -(** Alias of [('a, 'trace) t] to avoid confusion when the module is open *) -type ('a, 'trace) gas_monad = ('a, 'trace) t - -(** monadic return operator of the gas monad *) -val return : 'a -> ('a, 'trace) t - -(** Binding operator for the gas monad *) -val ( >>$ ) : ('a, 'trace) t -> ('a -> ('b, 'trace) t) -> ('b, 'trace) t - -(** Mapping operator for the gas monad, [m >|$ f] is equivalent to - [m >>$ fun x -> return (f x)] *) -val ( >|$ ) : ('a, 'trace) t -> ('a -> 'b) -> ('b, 'trace) t - -(** Variant of [( >>$ )] to bind uncarbonated functions *) -val ( >?$ ) : ('a, 'trace) t -> ('a -> ('b, 'trace) result) -> ('b, 'trace) t - -(** Another variant of [( >>$ )] that lets recover from inner errors *) -val ( >??$ ) : - ('a, 'trace) t -> (('a, 'trace) result -> ('b, 'trace) t) -> ('b, 'trace) t - -(** gas-free embedding of tzresult values. [of_result x] is equivalent to [return () >?$ fun () -> x] *) -val of_result : ('a, 'trace) result -> ('a, 'trace) t - -(** A wrapper around Gas.consume. If that fails, the whole computation - within the Gas_monad returns an error. See the Alpha_context.Gas module - for details.*) -val consume_gas : Gas.cost -> (unit, 'trace) t - -(** Escaping the gas monad *) -val run : context -> ('a, 'trace) t -> (('a, 'trace) result * context) tzresult - -(** re-export of [Error_monad.record_trace_eval]. This function has no - effect in the case of a gas-exhaustion error. *) -val record_trace_eval : - (unit -> 'err) -> ('a, 'err trace) t -> ('a, 'err trace) t diff --git a/src/proto_012_Psithaca/lib_protocol/global_constants_costs.ml b/src/proto_012_Psithaca/lib_protocol/global_constants_costs.ml deleted file mode 100644 index 61bbab15e6b3..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/global_constants_costs.ml +++ /dev/null @@ -1,47 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module S = Saturation_repr - -let log2 x = S.safe_int (1 + S.numbits x) - -let ( + ) = S.add - -let ( lsr ) = S.shift_right - -(* Approximating 200 + 1.266960 * number of bytes *) -let expr_to_address_in_context_cost bytes = - let v0 = Bytes.length bytes |> S.safe_int in - S.safe_int 200 + (v0 + (v0 lsr 2)) |> Gas_limit_repr.atomic_step_cost - -let expand_constants_branch_cost = - Gas_limit_repr.atomic_step_cost @@ S.safe_int 4095 - -(* Approximating 100 + 4.639474 * n*log(n) *) -let expand_no_constants_branch_cost node = - let v0 = Script_repr.micheline_nodes node |> S.safe_int in - let v0 = S.mul v0 (log2 v0) in - S.safe_int 100 + S.mul (S.safe_int 4) v0 + (v0 lsr 1) + (v0 lsr 3) - |> Gas_limit_repr.atomic_step_cost diff --git a/src/proto_012_Psithaca/lib_protocol/global_constants_costs.mli b/src/proto_012_Psithaca/lib_protocol/global_constants_costs.mli deleted file mode 100644 index 9f24e8b34d39..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/global_constants_costs.mli +++ /dev/null @@ -1,34 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Costs function for the global table of constants. *) - -(** Cost of calling [Global_constats_storage.expr_to_address_in_context]. *) -val expr_to_address_in_context_cost : bytes -> Gas_limit_repr.cost - -(** Step costs for [Global_constats_storage.expand_node]. *) -val expand_constants_branch_cost : Gas_limit_repr.cost - -val expand_no_constants_branch_cost : Script_repr.node -> Gas_limit_repr.cost diff --git a/src/proto_012_Psithaca/lib_protocol/global_constants_storage.ml b/src/proto_012_Psithaca/lib_protocol/global_constants_storage.ml deleted file mode 100644 index 429b454d44f1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/global_constants_storage.ml +++ /dev/null @@ -1,270 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) -open Micheline -open Michelson_v1_primitives - -(* - - See [expand] for an example. - - TODO: https://gitlab.com/tezos/tezos/-/issues/1609 - Move function to lib_micheline. - - On our next opportunity to update the environment, we - should move this function to lib_micheline. - -*) -let bottom_up_fold_cps initial_accumulator node initial_k f = - let rec traverse_node accu node k = - f accu node @@ fun accu node -> - match node with - | String _ | Int _ | Bytes _ -> k accu node - | Prim (loc, prim, args, annot) -> - (traverse_nodes [@ocaml.tailcall]) accu args @@ fun accu args -> - f accu (Prim (loc, prim, args, annot)) k - | Seq (loc, elts) -> - (traverse_nodes [@ocaml.tailcall]) accu elts @@ fun accu elts -> - f accu (Seq (loc, elts)) k - and traverse_nodes accu nodes k = - match nodes with - | [] -> k accu [] - | node :: nodes -> - (traverse_node [@ocaml.tailcall]) accu node @@ fun accu node -> - (traverse_nodes [@ocaml.tailcall]) accu nodes @@ fun accu nodes -> - k accu (node :: nodes) - in - traverse_node initial_accumulator node initial_k - [@@coq_axiom_with_reason "local mutually recursive definition not handled"] - -module Gas_costs = Global_constants_costs -module Expr_hash_map = Map.Make (Script_expr_hash) - -type error += Expression_too_deep - -type error += Expression_already_registered - -type error += Badly_formed_constant_expression - -type error += Nonexistent_global - -type error += Expression_too_large - -let () = - let description = - "Attempted to register an expression that, after fully expanding all \ - referenced global constants, would result in too many levels of nesting." - in - register_error_kind - `Branch - ~id:"Expression_too_deep" - ~title:"Expression too deep" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Expression_too_deep -> Some () | _ -> None) - (fun () -> Expression_too_deep) ; - let description = - "Attempted to register an expression as global constant that has already \ - been registered." - in - register_error_kind - `Branch - ~id:"Expression_already_registered" - ~title:"Expression already registered" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Expression_already_registered -> Some () | _ -> None) - (fun () -> Expression_already_registered) ; - let description = - "Found a badly formed constant expression. The 'constant' primitive must \ - always be followed by a string of the hash of the expression it points \ - to." - in - register_error_kind - `Branch - ~id:"Badly_formed_constant_expression" - ~title:"Badly formed constant expression" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Badly_formed_constant_expression -> Some () | _ -> None) - (fun () -> Badly_formed_constant_expression) ; - let description = - "No registered global was found at the given hash in storage." - in - register_error_kind - `Branch - ~id:"Nonexistent_global" - ~title:"Tried to look up nonexistent global" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Nonexistent_global -> Some () | _ -> None) - (fun () -> Nonexistent_global) ; - let description = - "Encountered an expression that, after expanding all constants, is larger \ - than the expression size limit." - in - register_error_kind - `Branch - ~id:"Expression_too_large" - ~title:"Expression too large" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) - Data_encoding.empty - (function Expression_too_large -> Some () | _ -> None) - (fun () -> Expression_too_large) - -let get context hash = - Storage.Global_constants.Map.find context hash >>=? fun (context, value) -> - match value with - | None -> fail Nonexistent_global - | Some value -> return (context, value) - -let expr_to_address_in_context context expr = - let lexpr = Script_repr.lazy_expr expr in - Raw_context.consume_gas context @@ Script_repr.force_bytes_cost lexpr - >>? fun context -> - Script_repr.force_bytes lexpr >>? fun b -> - Raw_context.consume_gas context @@ Gas_costs.expr_to_address_in_context_cost b - >|? fun context -> (context, Script_expr_hash.hash_bytes [b]) - -let node_too_large node = - let node_size = Script_repr.Micheline_size.of_node node in - let nodes = Saturation_repr.to_int node_size.nodes in - let string_bytes = Saturation_repr.to_int node_size.string_bytes in - let z_bytes = Saturation_repr.to_int node_size.z_bytes in - Compare.Int.( - nodes > Constants_repr.max_micheline_node_count - || string_bytes + z_bytes > Constants_repr.max_micheline_bytes_limit) - -let expand_node context node = - (* We charge for traversing the top-level node at the beginning. - Inside the loop, we charge for traversing each new constant - that gets expanded. *) - Raw_context.consume_gas - context - (Gas_costs.expand_no_constants_branch_cost node) - >>?= fun context -> - bottom_up_fold_cps - (* We carry a Boolean representing whether we - had to do any expansions or not. *) - (context, Expr_hash_map.empty, false) - node - (fun (context, _, did_expansion) node -> - return (context, node, did_expansion)) - (fun (context, map, did_expansion) node k -> - match node with - | Prim (_, H_constant, args, annot) -> ( - (* Charge for validating the b58check hash. *) - Raw_context.consume_gas context Gas_costs.expand_constants_branch_cost - >>?= fun context -> - match (args, annot) with - (* A constant Prim should always have a single String argument, - being a properly formatted hash. *) - | ([String (_, address)], []) -> ( - match Script_expr_hash.of_b58check_opt address with - | None -> fail Badly_formed_constant_expression - | Some hash -> ( - match Expr_hash_map.find hash map with - | Some node -> - (* Charge traversing the newly retrieved node *) - Raw_context.consume_gas - context - (Gas_costs.expand_no_constants_branch_cost node) - >>?= fun context -> k (context, map, true) node - | None -> - get context hash >>=? fun (context, expr) -> - (* Charge traversing the newly retrieved node *) - let node = root expr in - Raw_context.consume_gas - context - (Gas_costs.expand_no_constants_branch_cost node) - >>?= fun context -> - k (context, Expr_hash_map.add hash node map, true) node)) - | _ -> fail Badly_formed_constant_expression) - | Int _ | String _ | Bytes _ | Prim _ | Seq _ -> - k (context, map, did_expansion) node) - >>=? fun (context, node, did_expansion) -> - if did_expansion then - (* Gas charged during expansion is at least proportional to the size of the - resulting node so the execution time of [node_too_large] is already - covered. *) - if node_too_large node then fail Expression_too_large - else return (context, node) - else return (context, node) - -let expand context expr = - expand_node context (root expr) >|=? fun (context, node) -> - (context, strip_locations node) - -(** Computes the maximum depth of a Micheline node. Fails - with [Expression_too_deep] if greater than - [max_allowed_global_constant_depth].*) -let check_depth node = - let rec advance node depth k = - if Compare.Int.(depth > Constants_repr.max_allowed_global_constant_depth) - then error Expression_too_deep - else - match node with - | Int _ | String _ | Bytes _ | Prim (_, _, [], _) | Seq (_, []) -> - (k [@tailcall]) (depth + 1) - | Prim (loc, _, hd :: tl, _) | Seq (loc, hd :: tl) -> - (advance [@tailcall]) hd (depth + 1) (fun dhd -> - (advance [@tailcall]) - (* Because [depth] doesn't care about the content - of the expression, we can safely throw away information - about primitives and replace them with the [Seq] constructor.*) - (Seq (loc, tl)) - depth - (fun dtl -> (k [@tailcall]) (Compare.Int.max dhd dtl))) - in - advance node 0 (fun x -> Ok x) - -let register context value = - (* To calculate the total depth, we first expand all constants - in the expression. This may fail with [Expression_too_large]. - - Though the stored expression is the unexpanded version. - *) - expand_node context (root value) >>=? fun (context, node) -> - (* We do not need to carbonate [check_depth]. [expand_node] and - [Storage.Global_constants.Map.init] are already carbonated - with gas at least proportional to the size of the expanded node - and the computation cost of [check_depth] is of the same order. *) - check_depth node >>?= fun (_depth : int) -> - expr_to_address_in_context context value >>?= fun (context, key) -> - trace Expression_already_registered - @@ Storage.Global_constants.Map.init context key value - >|=? fun (context, size) -> (context, key, Z.of_int size) - -module Internal_for_tests = struct - let node_too_large = node_too_large - - let bottom_up_fold_cps = bottom_up_fold_cps - - let expr_to_address_in_context = expr_to_address_in_context -end diff --git a/src/proto_012_Psithaca/lib_protocol/global_constants_storage.mli b/src/proto_012_Psithaca/lib_protocol/global_constants_storage.mli deleted file mode 100644 index 096143c3c2af..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/global_constants_storage.mli +++ /dev/null @@ -1,150 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module represents access to a global table of constant - Micheline values. Users may register a Micheline value in the - table, paying the cost of storage. Once stored, contracts source code may - reference this value by its hash. - - Note: the table does not typecheck the values stored in it. - Instead, any place that uses constants must first call [expand] - before typechecking the code. This decision was made to make it as - easy as possible for users to register values to the table, and also - to allow maximum flexibility in the use of constants for different - parts of a Michelson script (code, types, data, etc.). *) - -type error += Expression_too_deep - -type error += Expression_already_registered - -(** A constant is the prim of the literal characters "constant". - A constant must have a single argument, being a string with a - well formed hash of a Micheline expression (i.e generated by - [Script_expr_hash.to_b58check]). *) -type error += Badly_formed_constant_expression - -type error += Nonexistent_global - -(** [get context hash] retrieves the Micheline value with the given hash. - - Fails with [Nonexistent_global] if no value is found at the given hash. - - Fails with [Storage_error Corrupted_data] if the deserialisation fails. - - Consumes [Gas_repr.read_bytes_cost ]. *) -val get : - Raw_context.t -> - Script_expr_hash.t -> - (Raw_context.t * Script_repr.expr) tzresult Lwt.t - -(** [register context value] registers a constant in the global table of constants, - returning the hash and storage bytes consumed. - - Does not type-check the Micheline code being registered, allow potentially - ill-typed Michelson values to be stored in the table (see note at top of module). - - The constant is stored unexpanded, but it is temporarily expanded at registration - time only to check the expanded version respects the following limits. - This also ensures there are no cyclic dependencies between constants. - - Fails with [Expression_too_deep] if, after fully expanding all constants, - the expression would have a depth greater than [Constant_repr.max_allowed_global_constant_depth]. - - Fails with [Badly_formed_constant_expression] if constants are not - well-formed (see declaration of [Badly_formed_constant_expression]) or with - [Nonexistent_global] if a referenced constant does not exist in the table. - - Consumes serialization cost. - Consumes [Gas_repr.write_bytes_cost ] where size is the number - of bytes in the binary serialization provided by [Script_repr.expr_encoding]. *) -val register : - Raw_context.t -> - Script_repr.expr -> - (Raw_context.t * Script_expr_hash.t * Z.t) tzresult Lwt.t - -(** [expand context expr] replaces every constant in the - given Michelson expression with its value stored in the global table. - - The expansion is applied recursively so that the returned expression - contains no constant. - - Fails with [Badly_formed_constant_expression] if constants are not - well-formed (see declaration of [Badly_formed_constant_expression]) or - with [Nonexistent_global] if a referenced constant does not exist in - the table. *) -val expand : - Raw_context.t -> - Script_repr.expr -> - (Raw_context.t * Script_repr.expr) tzresult Lwt.t - -module Internal_for_tests : sig - (** [node_too_large node] returns true if: - - The number of sub-nodes in the [node] - exceeds [Global_constants_storage.node_size_limit]. - - The sum of the bytes in String, Int, - and Bytes sub-nodes of [node] exceeds - [Global_constants_storage.bytes_size_limit]. - - Otherwise returns false. *) - val node_too_large : Script_repr.node -> bool - - (** [bottom_up_fold_cps initial_accumulator node initial_k f] - folds [node] and all its sub-nodes if any, starting from - [initial_accumulator], using an initial continuation [initial_k]. - At each node, [f] is called to transform the continuation [k] into - the next one. This explicit manipulation of the continuation - is typically useful to short-circuit. - - Notice that a common source of bug is to forget to properly call the - continuation in `f`. - - See [Global_constants_storage.expand] for an example. - - TODO: https://gitlab.com/tezos/tezos/-/issues/1609 - Move function to lib_micheline. - - On our next opportunity to update the environment, we - should move this function to lib_micheline. - *) - val bottom_up_fold_cps : - 'accumulator -> - 'loc Script_repr.michelson_node -> - ('accumulator -> 'loc Script_repr.michelson_node -> 'return) -> - ('accumulator -> - 'loc Script_repr.michelson_node -> - ('accumulator -> 'loc Script_repr.michelson_node -> 'return) -> - 'return) -> - 'return - - (* [expr_to_address_in_context context expr] converts [expr] - into a unique hash represented by a [Script_expr_hash.t]. - - Consumes gas corresponding to the cost of converting [expr] - to bytes and hashing the bytes. *) - val expr_to_address_in_context : - Raw_context.t -> - Script_repr.expr -> - (Raw_context.t * Script_expr_hash.t) tzresult -end diff --git a/src/proto_012_Psithaca/lib_protocol/init_storage.ml b/src/proto_012_Psithaca/lib_protocol/init_storage.ml deleted file mode 100644 index ac570744fb1c..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/init_storage.ml +++ /dev/null @@ -1,312 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* Copyright (c) 2021 DaiLambda, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* - To add invoices, you can use a helper function like this one: - - (** Invoice a contract at a given address with a given amount. Returns the - updated context and a balance update receipt (singleton list). The address - must be a valid base58 hash, otherwise this is no-op and returns an empty - receipts list. - - Do not fail if something goes wrong. - *) - let invoice_contract ctxt ~address ~amount_mutez = - match Tez_repr.of_mutez amount_mutez with - | None -> Lwt.return (ctxt, []) - | Some amount -> ( - ( Contract_repr.of_b58check address >>?= fun recipient -> - Token.transfer - ~origin:Protocol_migration - ctxt - `Invoice - (`Contract recipient) - amount ) - >|= function - | Ok res -> res - | Error _ -> (ctxt, [])) -*) - -let unfreeze_deposits_rewards_and_fees ctxt delegate cycle = - Token.balance ctxt (`Legacy_deposits (delegate, cycle)) >>=? fun deposits -> - Token.balance ctxt (`Legacy_fees (delegate, cycle)) >>=? fun fees -> - Token.balance ctxt (`Legacy_rewards (delegate, cycle)) >>=? fun rewards -> - let contract = Contract_repr.implicit_contract delegate in - Token.transfer_n - ~origin:Protocol_migration - ctxt - [ - (`Legacy_deposits (delegate, cycle), deposits); - (`Legacy_fees (delegate, cycle), fees); - (`Legacy_rewards (delegate, cycle), rewards); - ] - (`Delegate_balance delegate) - >>=? fun (ctxt, balance_updates) -> - Contract_delegate_storage.add_contract_stake ctxt contract rewards - >|=? fun ctxt -> (ctxt, balance_updates) - -(* Note that Legacy_frozen_* tables do not need to be cleared because - they become empty, given that when the amount in such a table - becomes 0 the contract is automatically removed from the table (see - the [Transfer] module). *) -let unfreeze_all_remaining_deposits_rewards_and_fees ctxt migration_cycle = - let preserved = Constants_storage.preserved_cycles ctxt in - List.fold_left_es - (fun (ctxt, balance_updates) cycle_offset -> - match Cycle_repr.sub migration_cycle cycle_offset with - | None -> return (ctxt, balance_updates) - | Some unfrozen_cycle -> - Storage.Legacy_delegates_with_frozen_balance.fold - (ctxt, unfrozen_cycle) - ~order:`Sorted - ~init:(Ok (ctxt, balance_updates)) - ~f:(fun delegate acc -> - acc >>?= fun (ctxt, bus) -> - unfreeze_deposits_rewards_and_fees ctxt delegate unfrozen_cycle - >|=? fun (ctxt, balance_updates) -> (ctxt, balance_updates @ bus)) - >>=? fun (ctxt, balance_updates) -> - Storage.Legacy_delegates_with_frozen_balance.clear - (ctxt, unfrozen_cycle) - >>= fun ctxt -> return (ctxt, balance_updates)) - (ctxt, []) - Misc.(0 --> preserved) - -let migrate_nonces ctxt migration_cycle = - let migrate_cycle ctxt cycle = - let levels = Level_storage.levels_with_commitments_in_cycle ctxt cycle in - let migrate ctxt level = - Storage.Seed.Nonce_legacy.mem ctxt level >>= function - | false -> return ctxt - | true -> - Storage.Seed.Nonce_legacy.get ctxt level >>=? fun nonce -> - Storage.Seed.Nonce.add ctxt level nonce >>= return - in - List.fold_left_es migrate ctxt levels - in - List.fold_left_es - migrate_cycle - ctxt - (match Cycle_repr.pred migration_cycle with - | None -> [migration_cycle] - | Some previous_cycle -> [previous_cycle; migration_cycle]) - -let prepare_first_block ctxt ~typecheck ~level ~timestamp = - Raw_context.prepare_first_block ~level ~timestamp ctxt - >>=? fun (previous_protocol, ctxt) -> - let cycle = (Raw_context.current_level ctxt).cycle in - (match previous_protocol with - | Genesis param -> - (* This is the genesis protocol: initialise the state *) - let init_commitment (ctxt, balance_updates) - Commitment_repr.{blinded_public_key_hash; amount} = - Token.transfer - ctxt - `Initial_commitments - (`Collected_commitments blinded_public_key_hash) - amount - >>=? fun (ctxt, new_balance_updates) -> - return (ctxt, new_balance_updates @ balance_updates) - in - List.fold_left_es init_commitment (ctxt, []) param.commitments - >>=? fun (ctxt, commitments_balance_updates) -> - Storage.Stake.Last_snapshot.init ctxt 0 >>=? fun ctxt -> - Seed_storage.init ctxt >>=? fun ctxt -> - Contract_storage.init ctxt >>=? fun ctxt -> - Bootstrap_storage.init - ctxt - ~typecheck - ?no_reward_cycles:param.no_reward_cycles - param.bootstrap_accounts - param.bootstrap_contracts - >>=? fun (ctxt, bootstrap_balance_updates) -> - Stake_storage.init_first_cycles ctxt Delegate_storage.pubkey - >>=? fun ctxt -> - Vote_storage.init - ctxt - ~start_position:(Level_storage.current ctxt).level_position - >>=? fun ctxt -> - Storage.Block_round.init ctxt Round_repr.zero >>=? fun ctxt -> - Vote_storage.update_listings ctxt >>=? fun ctxt -> - (* Must be called after other originations since it unsets the origination nonce.*) - Liquidity_baking_migration.init ctxt ~typecheck - >>=? fun (ctxt, operation_results) -> - Storage.Pending_migration.Operation_results.init ctxt operation_results - >>=? fun ctxt -> - Raw_level_repr.of_int32 level >>?= fun first_level -> - Storage.Tenderbake.First_level.init ctxt first_level >>=? fun ctxt -> - return (ctxt, commitments_balance_updates @ bootstrap_balance_updates) - | Hangzhou_011 -> - Raw_level_repr.of_int32 level >>?= fun first_level -> - Storage.Tenderbake.First_level.init ctxt first_level >>=? fun ctxt -> - Storage.Block_round.init ctxt Round_repr.zero >>=? fun ctxt -> - Raw_context.remove_existing_tree ctxt ["block_priority"] >>=? fun ctxt -> - Storage.Legacy_active_delegates_with_rolls.fold - ctxt - ~order:`Sorted - ~init:(Ok ctxt) - ~f:(fun pkh ctxt -> - ctxt >>?= fun ctxt -> - Storage.Roll_legacy.Delegate_roll_list.remove_existing ctxt pkh) - >>=? fun ctxt -> - Storage.Legacy_active_delegates_with_rolls.clear ctxt >>= fun ctxt -> - let old_tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - let new_tokens_per_roll = Tez_repr.(mul_exn one 6_000) in - assert (Tez_repr.(new_tokens_per_roll < old_tokens_per_roll)) ; - Roll_storage_legacy.fold - ctxt - ~f:(fun _roll pk (stakes, pk_map) -> - let (pkh, pk_map) = - match Misc.Public_key_map.find pk pk_map with - | None -> - let pkh = Signature.Public_key.hash pk in - (pkh, Misc.Public_key_map.add pk pkh pk_map) - | Some pkh -> (pkh, pk_map) - in - let stake = - Signature.Public_key_hash.Map.update - pkh - (function None -> Some 1l | Some n -> Some (Int32.succ n)) - stakes - in - return (stake, pk_map)) - (Signature.Public_key_hash.Map.empty, Misc.Public_key_map.empty) - >>=? fun (stakes, _pk_map) -> - Storage.Delegates.fold - ctxt - ~order:`Sorted - ~init:(Ok ctxt) - ~f:(fun pkh ctxt -> - ctxt >>?= fun ctxt -> - Roll_storage_legacy.get_change ctxt pkh >>=? fun change -> - Storage.Roll_legacy.Delegate_change.remove ctxt pkh >>= fun ctxt -> - Frozen_deposits_storage.init ctxt pkh >>=? fun ctxt -> - Delegate_activation_storage.is_inactive ctxt pkh >>=? fun inactive -> - match Signature.Public_key_hash.Map.find pkh stakes with - | None -> - Storage.Stake.Staking_balance.init ctxt pkh change - >>=? fun ctxt -> - if (not inactive) && Tez_repr.(change >= new_tokens_per_roll) then - Storage.Stake.Active_delegate_with_one_roll.add ctxt pkh () - >>= fun ctxt -> return ctxt - else return ctxt - | Some n -> - Lwt.return - ( Tez_repr.(old_tokens_per_roll *? Int64.of_int32 n) - >>? fun rolls -> Tez_repr.(rolls +? change) ) - >>=? fun staking_balance -> - Storage.Stake.Staking_balance.init ctxt pkh staking_balance - >>=? fun ctxt -> - (if not inactive then - Storage.Stake.Active_delegate_with_one_roll.add ctxt pkh () - else Lwt.return ctxt) - >>= fun ctxt -> return ctxt) - >>=? fun ctxt -> - Raw_context.patch_constants ctxt (fun constants -> - { - constants with - Constants_repr.tokens_per_roll = Tez_repr.(mul_exn one 6_000); - }) - >>= fun ctxt -> - (* NOTE: the code below fails when the migration happens during - the first cycle after Genesis, probably because of a bug in - the initialization of the previous protocol from Genesis. *) - let preserved = Constants_storage.preserved_cycles ctxt in - let max_slashing_period = Constants_storage.max_slashing_period ctxt in - List.fold_left_s - (fun ctxt cycle -> - Storage.Roll_legacy.Last_for_snapshot.clear (ctxt, cycle) - >>= fun ctxt -> - Storage.Roll_legacy.Snapshot_for_cycle.remove ctxt cycle) - ctxt - Cycle_repr.( - (match Cycle_repr.sub cycle preserved with - | None -> cycle - | Some cycle -> cycle) - ---> Cycle_repr.add cycle (preserved + 3)) - >>= fun ctxt -> - Raw_context.remove_existing_tree ctxt ["rolls"] >>=? fun ctxt -> - migrate_nonces ctxt cycle >>=? fun ctxt -> - unfreeze_all_remaining_deposits_rewards_and_fees ctxt cycle - >>=? fun (ctxt, balance_updates) -> - Storage.Stake.Last_snapshot.init ctxt 0 >>=? fun ctxt -> - List.fold_left_es - (fun ctxt cycle -> - Storage.Seed.For_cycle.mem ctxt cycle >>= function - | false -> return ctxt - | true -> - Stake_storage.snapshot ctxt >>=? fun ctxt -> - Stake_storage - .select_distribution_for_cycle_do_not_call_except_for_migration - ctxt - cycle - Delegate_storage.pubkey) - ctxt - Cycle_repr.( - (match Cycle_repr.sub cycle (max_slashing_period - 1) with - | None -> cycle - | Some cycle -> cycle) - ---> Cycle_repr.add cycle (preserved + 1)) - >>=? fun ctxt -> - (* Remove seeds that will not be useful any longer: those from - [cycle - preserved_cycles - 1] to [cycle - max_slashable_period]. - NB: The seed at [cycle - preserved] is already removed by - H.cycle_end. The seed at [cycle - max_slashable_period + 1] - is removed a bit later below by [Stake_storage.clear_at_cycle_end]. *) - (match - ( Cycle_repr.sub cycle (preserved - 1), - Cycle_repr.sub cycle max_slashing_period ) - with - | (Some from_cycle, Some to_cycle) -> - List.fold_left_es - (fun ctxt cycle -> - Storage.Seed.For_cycle.mem ctxt cycle >>= function - | false -> return ctxt - | true -> Storage.Seed.For_cycle.remove_existing ctxt cycle) - ctxt - Cycle_repr.(from_cycle ---> to_cycle) - | _ -> return ctxt) - >>=? fun ctxt -> return (ctxt, balance_updates)) - >>=? fun (ctxt, balance_updates) -> - Stake_storage.snapshot ctxt >>=? fun ctxt -> - Delegate_storage.freeze_deposits_do_not_call_except_for_migration - ~new_cycle:cycle - ~balance_updates - ctxt - >>=? fun (ctxt, balance_updates) -> - (match Level_storage.dawn_of_a_new_cycle ctxt with - | None -> return ctxt - | Some last_cycle -> - assert (Cycle_repr.(last_cycle = cycle)) ; - Stake_storage.clear_at_cycle_end ctxt ~new_cycle:(Cycle_repr.succ cycle)) - >>=? fun ctxt -> - Receipt_repr.group_balance_updates balance_updates >>?= fun balance_updates -> - Storage.Pending_migration.Balance_updates.add ctxt balance_updates - >>= fun ctxt -> return ctxt - -let prepare ctxt ~level ~predecessor_timestamp ~timestamp = - Raw_context.prepare ~level ~predecessor_timestamp ~timestamp ctxt - >>=? fun ctxt -> Storage.Pending_migration.remove ctxt diff --git a/src/proto_012_Psithaca/lib_protocol/init_storage.mli b/src/proto_012_Psithaca/lib_protocol/init_storage.mli deleted file mode 100644 index 0b71d116c541..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/init_storage.mli +++ /dev/null @@ -1,55 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Functions to setup storage. Used by [Alpha_context.prepare]. - - If you have defined a new type of storage, you should add relevant - setups here. - *) - -(* This is the genesis protocol: initialise the state *) -val prepare_first_block : - Context.t -> - typecheck: - (Raw_context.t -> - Script_repr.t -> - ((Script_repr.t * Lazy_storage_diff.diffs option) * Raw_context.t) - Error_monad.tzresult - Lwt.t) -> - level:int32 -> - timestamp:Time.t -> - (Raw_context.t, Error_monad.error Error_monad.trace) Pervasives.result Lwt.t - -val prepare : - Context.t -> - level:Int32.t -> - predecessor_timestamp:Time.t -> - timestamp:Time.t -> - (Raw_context.t - * Receipt_repr.balance_updates - * Migration_repr.origination_result list) - Error_monad.tzresult - Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/lazy_storage_diff.ml b/src/proto_012_Psithaca/lib_protocol/lazy_storage_diff.ml deleted file mode 100644 index 9a7030c35741..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/lazy_storage_diff.ml +++ /dev/null @@ -1,439 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module type Next = sig - type id - - val init : Raw_context.t -> Raw_context.t tzresult Lwt.t - - val incr : Raw_context.t -> (Raw_context.t * id) tzresult Lwt.t -end - -module type Total_bytes = sig - type id - - val init : Raw_context.t -> id -> Z.t -> Raw_context.t tzresult Lwt.t - - val get : Raw_context.t -> id -> Z.t tzresult Lwt.t - - val update : Raw_context.t -> id -> Z.t -> Raw_context.t tzresult Lwt.t -end - -(** Operations to be defined on a lazy storage type. *) -module type OPS = sig - module Id : Lazy_storage_kind.ID - - type alloc - - type updates - - val title : string - - val alloc_encoding : alloc Data_encoding.t - - val updates_encoding : updates Data_encoding.t - - val alloc_in_memory_size : alloc -> Cache_memory_helpers.nodes_and_size - - val updates_in_memory_size : updates -> Cache_memory_helpers.nodes_and_size - - val bytes_size_for_empty : Z.t - - val alloc : Raw_context.t -> id:Id.t -> alloc -> Raw_context.t tzresult Lwt.t - - val apply_updates : - Raw_context.t -> id:Id.t -> updates -> (Raw_context.t * Z.t) tzresult Lwt.t - - module Next : Next with type id := Id.t - - module Total_bytes : Total_bytes with type id := Id.t - - (** Deep copy. *) - val copy : - Raw_context.t -> from:Id.t -> to_:Id.t -> Raw_context.t tzresult Lwt.t - - (** Deep deletion. *) - val remove : Raw_context.t -> Id.t -> Raw_context.t Lwt.t -end - -module Big_map = struct - include Lazy_storage_kind.Big_map - - let alloc_in_memory_size {key_type; value_type} = - let open Cache_memory_helpers in - ret_adding - (expr_size key_type ++ expr_size value_type) - (header_size +! (word_size *? 2)) - - let updates_in_memory_size updates = - let open Cache_memory_helpers in - let update_size {key; key_hash = _; value} = - ret_adding - (expr_size key ++ option_size_vec expr_size value) - (header_size +! (word_size *? 3) +? Script_expr_hash.size) - in - list_fold_size update_size updates - - let bytes_size_for_big_map_key = 65 - - let bytes_size_for_empty = - let bytes_size_for_big_map = 33 in - Z.of_int bytes_size_for_big_map - - let alloc ctxt ~id {key_type; value_type} = - (* Annotations are erased to allow sharing on [Copy]. The types from the - contract code are used, these ones are only used to make sure they are - compatible during transmissions between contracts, and only need to be - compatible, annotations notwithstanding. *) - let key_type = - Micheline.strip_locations - (Script_repr.strip_annotations (Micheline.root key_type)) - in - let value_type = - Micheline.strip_locations - (Script_repr.strip_annotations (Micheline.root value_type)) - in - Storage.Big_map.Key_type.init ctxt id key_type >>=? fun ctxt -> - Storage.Big_map.Value_type.init ctxt id value_type - - let apply_update ctxt ~id - { - key = _key_is_shown_only_on_the_receipt_in_print_big_map_diff; - key_hash; - value; - } = - match value with - | None -> - Storage.Big_map.Contents.remove (ctxt, id) key_hash - >|=? fun (ctxt, freed, existed) -> - let freed = - if existed then freed + bytes_size_for_big_map_key else freed - in - (ctxt, Z.of_int ~-freed) - | Some v -> - Storage.Big_map.Contents.add (ctxt, id) key_hash v - >|=? fun (ctxt, size_diff, existed) -> - let size_diff = - if existed then size_diff else size_diff + bytes_size_for_big_map_key - in - (ctxt, Z.of_int size_diff) - - let apply_updates ctxt ~id updates = - List.fold_left_es - (fun (ctxt, size) update -> - apply_update ctxt ~id update >|=? fun (ctxt, added_size) -> - (ctxt, Z.add size added_size)) - (ctxt, Z.zero) - updates - - include Storage.Big_map -end - -type ('id, 'alloc, 'updates) ops = - (module OPS - with type Id.t = 'id - and type alloc = 'alloc - and type updates = 'updates) - -module Sapling_state = struct - include Lazy_storage_kind.Sapling_state - - let alloc_in_memory_size {memo_size = (_ : int)} = - let open Cache_memory_helpers in - (Nodes.zero, header_size +! word_size) - - let updates_in_memory_size update = - (Cache_memory_helpers.Nodes.zero, Sapling_repr.diff_in_memory_size update) - - let bytes_size_for_empty = Z.of_int 33 - - let alloc ctxt ~id {memo_size} = Sapling_storage.init ctxt id ~memo_size - - let apply_updates ctxt ~id updates = - Sapling_storage.apply_diff ctxt id updates - - include Storage.Sapling -end - -(* - To add a new lazy storage kind here, you only need to create a module similar - to [Big_map] above and add a case to [get_ops] below. -*) - -let get_ops : type i a u. (i, a, u) Lazy_storage_kind.t -> (i, a, u) ops = - function - | Big_map -> (module Big_map) - | Sapling_state -> (module Sapling_state) - [@@coq_axiom_with_reason "gadt"] - -type ('id, 'alloc) init = Existing | Copy of {src : 'id} | Alloc of 'alloc - -type ('id, 'alloc, 'updates) diff = - | Remove - | Update of {init : ('id, 'alloc) init; updates : 'updates} - -let diff_encoding : type i a u. (i, a, u) ops -> (i, a, u) diff Data_encoding.t - = - fun (module OPS) -> - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"update" - (obj2 - (req "action" (constant "update")) - (req "updates" OPS.updates_encoding)) - (function - | Update {init = Existing; updates} -> Some ((), updates) | _ -> None) - (fun ((), updates) -> Update {init = Existing; updates}); - case - (Tag 1) - ~title:"remove" - (obj1 (req "action" (constant "remove"))) - (function Remove -> Some () | _ -> None) - (fun () -> Remove); - case - (Tag 2) - ~title:"copy" - (obj3 - (req "action" (constant "copy")) - (req "source" OPS.Id.encoding) - (req "updates" OPS.updates_encoding)) - (function - | Update {init = Copy {src}; updates} -> Some ((), src, updates) - | _ -> None) - (fun ((), src, updates) -> Update {init = Copy {src}; updates}); - case - (Tag 3) - ~title:"alloc" - (merge_objs - (obj2 - (req "action" (constant "alloc")) - (req "updates" OPS.updates_encoding)) - OPS.alloc_encoding) - (function - | Update {init = Alloc alloc; updates} -> Some (((), updates), alloc) - | _ -> None) - (fun (((), updates), alloc) -> Update {init = Alloc alloc; updates}); - ] - -let init_size : - type i a u. - (i, a, u) ops -> (i, a) init -> Cache_memory_helpers.nodes_and_size = - fun (module OPS) init -> - let open Cache_memory_helpers in - match init with - | Existing -> zero - | Copy {src = _id_is_a_Z_fitting_in_an_int_for_a_long_time} -> - (Nodes.zero, header_size +! word_size) - | Alloc alloc -> - ret_adding (OPS.alloc_in_memory_size alloc) (header_size +! word_size) - -let updates_size : - type i a u. (i, a, u) ops -> u -> Cache_memory_helpers.nodes_and_size = - fun (module OPS) updates -> OPS.updates_in_memory_size updates - -let diff_in_memory_size kind diff = - let open Cache_memory_helpers in - match diff with - | Remove -> zero - | Update {init; updates} -> - let ops = get_ops kind in - ret_adding (init_size ops init ++ updates_size ops updates) h2w - -(** - [apply_updates ctxt ops ~id init] applies the updates [updates] on lazy - storage [id] on storage context [ctxt] using operations [ops] and returns the - updated storage context and the added size in bytes (may be negative). -*) -let apply_updates : - type i a u. - Raw_context.t -> - (i, a, u) ops -> - id:i -> - u -> - (Raw_context.t * Z.t) tzresult Lwt.t = - fun ctxt (module OPS) ~id updates -> - OPS.apply_updates ctxt ~id updates >>=? fun (ctxt, updates_size) -> - if Z.(equal updates_size zero) then return (ctxt, updates_size) - else - OPS.Total_bytes.get ctxt id >>=? fun size -> - OPS.Total_bytes.update ctxt id (Z.add size updates_size) >|=? fun ctxt -> - (ctxt, updates_size) - -(** - [apply_init ctxt ops ~id init] applies the initialization [init] on lazy - storage [id] on storage context [ctxt] using operations [ops] and returns the - updated storage context and the added size in bytes (may be negative). - - If [id] represents a temporary lazy storage, the added size may be wrong. -*) -let apply_init : - type i a u. - Raw_context.t -> - (i, a, u) ops -> - id:i -> - (i, a) init -> - (Raw_context.t * Z.t) tzresult Lwt.t = - fun ctxt (module OPS) ~id init -> - match init with - | Existing -> return (ctxt, Z.zero) - | Copy {src} -> - OPS.copy ctxt ~from:src ~to_:id >>=? fun ctxt -> - if OPS.Id.is_temp id then return (ctxt, Z.zero) - else - OPS.Total_bytes.get ctxt src >>=? fun copy_size -> - return (ctxt, Z.add copy_size OPS.bytes_size_for_empty) - | Alloc alloc -> - OPS.Total_bytes.init ctxt id Z.zero >>=? fun ctxt -> - OPS.alloc ctxt ~id alloc >>=? fun ctxt -> - return (ctxt, OPS.bytes_size_for_empty) - -(** - [apply_diff ctxt ops ~id diff] applies the diff [diff] on lazy storage [id] - on storage context [ctxt] using operations [ops] and returns the updated - storage context and the added size in bytes (may be negative). - - If [id] represents a temporary lazy storage, the added size may be wrong. -*) -let apply_diff : - type i a u. - Raw_context.t -> - (i, a, u) ops -> - id:i -> - (i, a, u) diff -> - (Raw_context.t * Z.t) tzresult Lwt.t = - fun ctxt ((module OPS) as ops) ~id diff -> - match diff with - | Remove -> - if OPS.Id.is_temp id then - OPS.remove ctxt id >|= fun ctxt -> ok (ctxt, Z.zero) - else - OPS.Total_bytes.get ctxt id >>=? fun size -> - OPS.remove ctxt id >>= fun ctxt -> - return (ctxt, Z.neg (Z.add size OPS.bytes_size_for_empty)) - | Update {init; updates} -> - apply_init ctxt ops ~id init >>=? fun (ctxt, init_size) -> - apply_updates ctxt ops ~id updates >>=? fun (ctxt, updates_size) -> - return (ctxt, Z.add init_size updates_size) - -type diffs_item = - | Item : - ('i, 'a, 'u) Lazy_storage_kind.t * 'i * ('i, 'a, 'u) diff - -> diffs_item - -let make : - type i a u. - (i, a, u) Lazy_storage_kind.t -> i -> (i, a, u) diff -> diffs_item = - fun k id diff -> Item (k, id, diff) - -let item_encoding = - let open Data_encoding in - union - @@ List.map - (fun (tag, Lazy_storage_kind.Ex_Kind k) -> - let ops = get_ops k in - let (module OPS) = ops in - let title = OPS.title in - case - (Tag tag) - ~title - (obj3 - (req "kind" (constant title)) - (req "id" OPS.Id.encoding) - (req "diff" (diff_encoding ops))) - (fun (Item (kind, id, diff)) -> - match Lazy_storage_kind.equal k kind with - | Eq -> Some ((), id, diff) - | Neq -> None) - (fun ((), id, diff) -> Item (k, id, diff))) - Lazy_storage_kind.all - [@@coq_axiom_with_reason "gadt"] - -let item_in_memory_size - (Item - ( kind - (* kinds are constant tags *), - _id_is_a_Z_fitting_in_an_int_for_a_long_time, - diff )) = - let open Cache_memory_helpers in - ret_adding (diff_in_memory_size kind diff) h3w - -type diffs = diffs_item list - -let diffs_in_memory_size diffs = - Cache_memory_helpers.list_fold_size item_in_memory_size diffs - -let encoding = - let open Data_encoding in - def "lazy_storage_diff" @@ list item_encoding - -let apply ctxt diffs = - List.fold_left_es - (fun (ctxt, total_size) (Item (k, id, diff)) -> - let ops = get_ops k in - apply_diff ctxt ops ~id diff >|=? fun (ctxt, added_size) -> - let (module OPS) = ops in - ( ctxt, - if OPS.Id.is_temp id then total_size else Z.add total_size added_size )) - (ctxt, Z.zero) - diffs - -let fresh : - type i a u. - (i, a, u) Lazy_storage_kind.t -> - temporary:bool -> - Raw_context.t -> - (Raw_context.t * i) tzresult Lwt.t = - fun kind ~temporary ctxt -> - if temporary then - return - (Raw_context.fold_map_temporary_lazy_storage_ids ctxt (fun temp_ids -> - Lazy_storage_kind.Temp_ids.fresh kind temp_ids)) - else - let (module OPS) = get_ops kind in - OPS.Next.incr ctxt - [@@coq_axiom_with_reason "gadt"] - -let init ctxt = - List.fold_left_es - (fun ctxt (_tag, Lazy_storage_kind.Ex_Kind k) -> - let (module OPS) = get_ops k in - OPS.Next.init ctxt) - ctxt - Lazy_storage_kind.all - [@@coq_axiom_with_reason "gadt"] - -let cleanup_temporaries ctxt = - Raw_context.map_temporary_lazy_storage_ids_s ctxt (fun temp_ids -> - List.fold_left_s - (fun ctxt (_tag, Lazy_storage_kind.Ex_Kind k) -> - let (module OPS) = get_ops k in - Lazy_storage_kind.Temp_ids.fold_s k OPS.remove temp_ids ctxt) - ctxt - Lazy_storage_kind.all - >|= fun ctxt -> (ctxt, Lazy_storage_kind.Temp_ids.init)) - [@@coq_axiom_with_reason "gadt"] diff --git a/src/proto_012_Psithaca/lib_protocol/lazy_storage_diff.mli b/src/proto_012_Psithaca/lib_protocol/lazy_storage_diff.mli deleted file mode 100644 index 17637213d75b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/lazy_storage_diff.mli +++ /dev/null @@ -1,71 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining 'a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** - See [Lazy_storage_kind] for an introduction on lazy storage. - - This module defines operations on lazy storage types and diffs. -*) - -type ('id, 'alloc) init = Existing | Copy of {src : 'id} | Alloc of 'alloc - -type ('id, 'alloc, 'updates) diff = - | Remove - | Update of {init : ('id, 'alloc) init; updates : 'updates} - -(* Exposing this type is needed only for legacy big map diff. *) -type diffs_item = private - | Item : - ('i, 'a, 'u) Lazy_storage_kind.t * 'i * ('i, 'a, 'u) diff - -> diffs_item - -val make : - ('i, 'a, 'u) Lazy_storage_kind.t -> 'i -> ('i, 'a, 'u) diff -> diffs_item - -type diffs = diffs_item list - -val diffs_in_memory_size : diffs -> Cache_memory_helpers.nodes_and_size - -val encoding : diffs Data_encoding.t - -(** - The returned [Z.t] is the size added by the application of the diffs. -*) -val apply : Raw_context.t -> diffs -> (Raw_context.t * Z.t) tzresult Lwt.t - -val fresh : - ('id, _, _) Lazy_storage_kind.t -> - temporary:bool -> - Raw_context.t -> - (Raw_context.t * 'id) tzresult Lwt.t - -(** - Initializes the storage for all lazy storage kind. - This is useful for genesis only. - Protocol updates need to initialize new lazy storage kinds. -*) -val init : Raw_context.t -> Raw_context.t tzresult Lwt.t - -val cleanup_temporaries : Raw_context.t -> Raw_context.t Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/lazy_storage_kind.ml b/src/proto_012_Psithaca/lib_protocol/lazy_storage_kind.ml deleted file mode 100644 index 799e55e047f7..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/lazy_storage_kind.ml +++ /dev/null @@ -1,325 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module type TEMP_ID = sig - type t - - val equal : t -> t -> bool - - val init : t - - val next : t -> t -end - -module type ID = sig - type t - - val compare : t -> t -> int - - val encoding : t Data_encoding.t - - val rpc_arg : t RPC_arg.arg - - val init : t - - (** In the protocol, to be used in parse_data only *) - val parse_z : Z.t -> t - - (** In the protocol, to be used in unparse_data only *) - val unparse_to_z : t -> Z.t - - val next : t -> t - - val is_temp : t -> bool - - val of_legacy_USE_ONLY_IN_Legacy_big_map_diff : Z.t -> t - - val to_legacy_USE_ONLY_IN_Legacy_big_map_diff : t -> Z.t - - include Path_encoding.S with type t := t -end - -module type Title = sig - val title : string -end - -module type TitleWithId = sig - val title : string - - module Id : ID - - module Temp_id : TEMP_ID with type t = private Id.t - - module IdSet : Set.S with type elt = Id.t -end - -module MakeId (Title : Title) : TitleWithId = struct - let title = Title.title - - let title_words = String.map (function '_' -> ' ' | c -> c) title - - let rpc_arg_error = Format.sprintf "Cannot parse %s id" title_words - - let description = Format.sprintf "A %s identifier" title_words - - let name = title ^ "_id" - - let encoding_title = String.capitalize_ascii title_words ^ " identifier" - - module Id = struct - type t = Z.t - - let compare = Z.compare - - let encoding = - Data_encoding.def name ~title:encoding_title ~description Data_encoding.z - - let rpc_arg = - let construct = Z.to_string in - let destruct hash = - Result.catch_f (fun () -> Z.of_string hash) (fun _ -> rpc_arg_error) - in - RPC_arg.make ~descr:description ~name ~construct ~destruct () - - let init = Z.zero - - let parse_z (z : Z.t) : t = z - - let unparse_to_z (z : t) : Z.t = z - - let next = Z.succ - - let of_legacy_USE_ONLY_IN_Legacy_big_map_diff (z : Z.t) : t = z - - let to_legacy_USE_ONLY_IN_Legacy_big_map_diff (z : t) : Z.t = z - - let is_temp z = Compare.Z.(z < Z.zero) - - let path_length = 1 - - let to_path z l = Z.to_string z :: l - - let of_path = function - | [] | _ :: _ :: _ -> None - | [z] -> Some (Z.of_string z) - end - - module Temp_id = struct - type t = Id.t - - let equal = Z.equal - - let init = Z.of_int ~-1 - - let next z = Z.sub z Z.one - end - - module IdSet = Set.Make (Id) -end - -module Big_map = struct - include MakeId (struct - let title = "big_map" - end) - - type alloc = {key_type : Script_repr.expr; value_type : Script_repr.expr} - - type update = { - key : Script_repr.expr; - (** The key is ignored by [apply_update] but is shown in the receipt, - as specified in [print_big_map_diff]. *) - key_hash : Script_expr_hash.t; - value : Script_repr.expr option; - } - - type updates = update list - - let alloc_encoding = - let open Data_encoding in - conv - (fun {key_type; value_type} -> (key_type, value_type)) - (fun (key_type, value_type) -> {key_type; value_type}) - (obj2 - (req "key_type" Script_repr.expr_encoding) - (req "value_type" Script_repr.expr_encoding)) - - let update_encoding = - let open Data_encoding in - conv - (fun {key_hash; key; value} -> (key_hash, key, value)) - (fun (key_hash, key, value) -> {key_hash; key; value}) - (obj3 - (req "key_hash" Script_expr_hash.encoding) - (req "key" Script_repr.expr_encoding) - (opt "value" Script_repr.expr_encoding)) - - let updates_encoding = Data_encoding.list update_encoding -end - -module Sapling_state = struct - include MakeId (struct - let title = "sapling_state" - end) - - type alloc = {memo_size : Sapling_repr.Memo_size.t} - - type updates = Sapling_repr.diff - - let alloc_encoding = - let open Data_encoding in - conv - (fun {memo_size} -> memo_size) - (fun memo_size -> {memo_size}) - (obj1 (req "memo_size" Sapling_repr.Memo_size.encoding)) - - let updates_encoding = Sapling_repr.diff_encoding -end - -(* - When adding cases to this type, grep for [new lazy storage kind] in the code - for locations to update. - It must be: - - the value [all] right below, - - modules [Temp_ids], [IdSet] below, - - the rest should be guided by type errors. -*) -type ('id, 'alloc, 'updates) t = - | Big_map : (Big_map.Id.t, Big_map.alloc, Big_map.updates) t - | Sapling_state - : (Sapling_state.Id.t, Sapling_state.alloc, Sapling_state.updates) t - -type ex = Ex_Kind : (_, _, _) t -> ex - -(* /!\ Don't forget to add new lazy storage kinds here. /!\ *) -let all = [(0, Ex_Kind Big_map); (1, Ex_Kind Sapling_state)] - -type (_, _) cmp = Eq : ('a, 'a) cmp | Neq - -let equal : - type i1 a1 u1 i2 a2 u2. - (i1, a1, u1) t -> (i2, a2, u2) t -> (i1 * a1 * u1, i2 * a2 * u2) cmp = - fun k1 k2 -> - match (k1, k2) with - | (Big_map, Big_map) -> Eq - | (Sapling_state, Sapling_state) -> Eq - | (Big_map, _) -> Neq - | (_, Big_map) -> Neq - -type ('i, 'a, 'u) kind = ('i, 'a, 'u) t - -module Temp_ids = struct - type t = { - big_map : Big_map.Temp_id.t; - sapling_state : Sapling_state.Temp_id.t; - } - - let init = - {big_map = Big_map.Temp_id.init; sapling_state = Sapling_state.Temp_id.init} - - let fresh : type i a u. (i, a, u) kind -> t -> t * i = - fun kind temp_ids -> - match kind with - | Big_map -> - let big_map = Big_map.Temp_id.next temp_ids.big_map in - ({temp_ids with big_map}, (temp_ids.big_map :> Big_map.Id.t)) - | Sapling_state -> - let sapling_state = Sapling_state.Temp_id.next temp_ids.sapling_state in - ( {temp_ids with sapling_state}, - (temp_ids.sapling_state :> Sapling_state.Id.t) ) - [@@coq_axiom_with_reason "gadt"] - - let fold_s : - type i a u. - (i, a, u) kind -> ('acc -> i -> 'acc Lwt.t) -> t -> 'acc -> 'acc Lwt.t = - fun kind f temp_ids acc -> - let helper (type j) (module Temp_id : TEMP_ID with type t = j) ~last f = - let rec aux acc id = - if Temp_id.equal id last then Lwt.return acc - else f acc id >>= fun acc -> aux acc (Temp_id.next id) - in - aux acc Temp_id.init - in - match kind with - | Big_map -> - helper - (module Big_map.Temp_id) - ~last:temp_ids.big_map - (fun acc temp_id -> f acc (temp_id :> i)) - | Sapling_state -> - helper - (module Sapling_state.Temp_id) - ~last:temp_ids.sapling_state - (fun acc temp_id -> f acc (temp_id :> i)) - [@@coq_axiom_with_reason "gadt"] -end - -module IdSet = struct - type t = {big_map : Big_map.IdSet.t; sapling_state : Sapling_state.IdSet.t} - - type 'acc fold_f = {f : 'i 'a 'u. ('i, 'a, 'u) kind -> 'i -> 'acc -> 'acc} - - let empty = - {big_map = Big_map.IdSet.empty; sapling_state = Sapling_state.IdSet.empty} - - let mem (type i a u) (kind : (i, a, u) kind) (id : i) set = - match (kind, set) with - | (Big_map, {big_map; _}) -> Big_map.IdSet.mem id big_map - | (Sapling_state, {sapling_state; _}) -> - Sapling_state.IdSet.mem id sapling_state - [@@coq_axiom_with_reason "gadt"] - - let add (type i a u) (kind : (i, a, u) kind) (id : i) set = - match (kind, set) with - | (Big_map, {big_map; _}) -> - let big_map = Big_map.IdSet.add id big_map in - {set with big_map} - | (Sapling_state, {sapling_state; _}) -> - let sapling_state = Sapling_state.IdSet.add id sapling_state in - {set with sapling_state} - [@@coq_axiom_with_reason "gadt"] - - let diff set1 set2 = - let big_map = Big_map.IdSet.diff set1.big_map set2.big_map in - let sapling_state = - Sapling_state.IdSet.diff set1.sapling_state set2.sapling_state - in - {big_map; sapling_state} - [@@coq_axiom_with_reason "gadt"] - - let fold (type i a u) (kind : (i, a, u) kind) (f : i -> 'acc -> 'acc) set - (acc : 'acc) = - match (kind, set) with - | (Big_map, {big_map; _}) -> Big_map.IdSet.fold f big_map acc - | (Sapling_state, {sapling_state; _}) -> - Sapling_state.IdSet.fold f sapling_state acc - [@@coq_axiom_with_reason "gadt"] - - let fold_all f set acc = - List.fold_left - (fun acc (_, Ex_Kind kind) -> fold kind (f.f kind) set acc) - acc - all - [@@coq_axiom_with_reason "gadt"] -end diff --git a/src/proto_012_Psithaca/lib_protocol/lazy_storage_kind.mli b/src/proto_012_Psithaca/lib_protocol/lazy_storage_kind.mli deleted file mode 100644 index eb23fb9545ad..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/lazy_storage_kind.mli +++ /dev/null @@ -1,178 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** - Lazy_storage offers a unified interface for specific Michelson datatype that - behave somewhat lazily, because they are intended to be quite big. - Instead of serializing/deserializing the whole value to/from the storage, - only an identifier is used. The identifier acts like a pointer. - When using the value in a Michelson script, some part of it may be read from - the storage, and a lightweight diff is computed. - The diff is effectively applied to the storage at the end of the execution. - - This module defines the different kinds of lazy storages and their basic - properties. See also [Lazy_storage_diff]. - - Lazy storage types are: - - Big_map -*) - -(** - Lazy storage ids are kept as abstract as possible to avoid mixing them up. - - Behind the scene they are [Z.t]s but, within the protocol, only [parse_data]/ - [unparse_data] are allowed convert from/to it. - - Temporary ids may be used to pass values between contracts that won't be kept - longer than the lifetime of the operation. - Behind the scene, temporary ids are negative [Z.t]s. -*) -module type ID = sig - type t - - val compare : t -> t -> int - - val encoding : t Data_encoding.t - - val rpc_arg : t RPC_arg.arg - - (** Initial value for ids: zero. *) - val init : t - - (** In the protocol, to be used in parse_data only *) - val parse_z : Z.t -> t - - (** In the protocol, to be used in unparse_data only *) - val unparse_to_z : t -> Z.t - - val next : t -> t - - val is_temp : t -> bool - - (* To be removed once legacy big map diff is removed: *) - - val of_legacy_USE_ONLY_IN_Legacy_big_map_diff : Z.t -> t - - val to_legacy_USE_ONLY_IN_Legacy_big_map_diff : t -> Z.t - - (* To be used in storage: *) - - include Path_encoding.S with type t := t -end - -module Big_map : sig - val title : string - - module Id : ID - - type alloc = {key_type : Script_repr.expr; value_type : Script_repr.expr} - - type update = { - key : Script_repr.expr; - (** The key is ignored by [apply_update] but is shown in the receipt, - as specified in [print_big_map_diff]. *) - key_hash : Script_expr_hash.t; - value : Script_repr.expr option; - } - - type updates = update list - - val alloc_encoding : alloc Data_encoding.t - - val updates_encoding : updates Data_encoding.t -end - -module Sapling_state : sig - val title : string - - module Id : ID - - type alloc = {memo_size : Sapling_repr.Memo_size.t} - - type updates = Sapling_repr.diff - - val alloc_encoding : alloc Data_encoding.t - - val updates_encoding : updates Data_encoding.t -end - -(** - Kinds of lazy storage. - The GADT ensures operations are properly applied to the correct kind. - - ['id] the abstract type for the identifier of the kind. - ['alloc] is the type used to construct a new value. - ['updates] is the type used to update a value. -*) -type ('id, 'alloc, 'updates) t = - | Big_map : (Big_map.Id.t, Big_map.alloc, Big_map.updates) t - | Sapling_state - : (Sapling_state.Id.t, Sapling_state.alloc, Sapling_state.updates) t - -type ex = Ex_Kind : (_, _, _) t -> ex - -val all : (int * ex) list - -type (_, _) cmp = Eq : ('a, 'a) cmp | Neq - -val equal : - ('i1, 'a1, 'u1) t -> - ('i2, 'a2, 'u2) t -> - ('i1 * 'a1 * 'u1, 'i2 * 'a2 * 'u2) cmp - -type ('i, 'a, 'u) kind = ('i, 'a, 'u) t - -(** - Type to manage temporary ids. - Used only in the context. -*) -module Temp_ids : sig - type t - - val init : t - - val fresh : ('i, 'a, 'u) kind -> t -> t * 'i - - val fold_s : - ('i, 'a, 'u) kind -> ('acc -> 'i -> 'acc Lwt.t) -> t -> 'acc -> 'acc Lwt.t -end - -module IdSet : sig - type t - - type 'acc fold_f = {f : 'i 'a 'u. ('i, 'a, 'u) kind -> 'i -> 'acc -> 'acc} - - val empty : t - - val mem : ('i, 'a, 'u) kind -> 'i -> t -> bool - - val add : ('i, 'a, 'u) kind -> 'i -> t -> t - - val diff : t -> t -> t - - val fold : ('i, 'a, 'u) kind -> ('i -> 'acc -> 'acc) -> t -> 'acc -> 'acc - - val fold_all : 'acc fold_f -> t -> 'acc -> 'acc -end diff --git a/src/proto_012_Psithaca/lib_protocol/level_repr.ml b/src/proto_012_Psithaca/lib_protocol/level_repr.ml deleted file mode 100644 index 3ad6794c55ff..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/level_repr.ml +++ /dev/null @@ -1,336 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = { - level : Raw_level_repr.t; - level_position : int32; - cycle : Cycle_repr.t; - cycle_position : int32; - expected_commitment : bool; -} - -include Compare.Make (struct - type nonrec t = t - - let compare {level = l1; _} {level = l2; _} = Raw_level_repr.compare l1 l2 -end) - -type level = t - -let pp ppf {level; _} = Raw_level_repr.pp ppf level - -let pp_full ppf l = - Format.fprintf - ppf - "%a.%ld (cycle %a.%ld)" - Raw_level_repr.pp - l.level - l.level_position - Cycle_repr.pp - l.cycle - l.cycle_position - -let encoding = - let open Data_encoding in - conv - (fun {level; level_position; cycle; cycle_position; expected_commitment} -> - (level, level_position, cycle, cycle_position, expected_commitment)) - (fun (level, level_position, cycle, cycle_position, expected_commitment) -> - {level; level_position; cycle; cycle_position; expected_commitment}) - (obj5 - (req - "level" - ~description: - "The level of the block relative to genesis. This is also the \ - Shell's notion of level." - Raw_level_repr.encoding) - (req - "level_position" - ~description: - "The level of the block relative to the successor of the genesis \ - block. More precisely, it is the position of the block relative \ - to the block that starts the \"Alpha family\" of protocols, which \ - includes all protocols except Genesis (that is, from 001 \ - onwards)." - int32) - (req - "cycle" - ~description: - "The current cycle's number. Note that cycles are a \ - protocol-specific notion. As a result, the cycle number starts at \ - 0 with the first block of the Alpha family of protocols." - Cycle_repr.encoding) - (req - "cycle_position" - ~description: - "The current level of the block relative to the first block of the \ - current cycle." - int32) - (req - "expected_commitment" - ~description: - "Tells whether the baker of this block has to commit a seed nonce \ - hash." - bool)) - -let diff {level = l1; _} {level = l2; _} = - Int32.sub (Raw_level_repr.to_int32 l1) (Raw_level_repr.to_int32 l2) - -type cycle_era = { - first_level : Raw_level_repr.t; - first_cycle : Cycle_repr.t; - blocks_per_cycle : int32; - blocks_per_commitment : int32; -} - -type cycle_eras = cycle_era list - -type error += Invalid_cycle_eras - -let () = - register_error_kind - `Temporary - ~id:"level_repr.invalid_cycle_eras" - ~title:"Invalid cycle eras" - ~description: - "The cycles eras are not valid: empty list or non-decreasing first \ - levels or first cycles." - ~pp:(fun ppf () -> - Format.fprintf - ppf - "The cycles eras are not valid: empty list or non-decreasing first \ - levels or first cycles.") - Data_encoding.empty - (function Invalid_cycle_eras -> Some () | _ -> None) - (fun () -> Invalid_cycle_eras) - -let create_cycle_eras cycle_eras = - match cycle_eras with - | [] -> error Invalid_cycle_eras - | newest_era :: older_eras -> - let rec aux {first_level; first_cycle; _} older_eras = - match older_eras with - | ({ - first_level = first_level_of_previous_era; - first_cycle = first_cycle_of_previous_era; - _; - } as previous_era) - :: even_older_eras -> - if - Raw_level_repr.(first_level > first_level_of_previous_era) - && Cycle_repr.(first_cycle > first_cycle_of_previous_era) - then aux previous_era even_older_eras - else error Invalid_cycle_eras - | [] -> ok () - in - aux newest_era older_eras >>? fun () -> ok cycle_eras - -let cycle_era_encoding = - let open Data_encoding in - conv - (fun {first_level; first_cycle; blocks_per_cycle; blocks_per_commitment} -> - (first_level, first_cycle, blocks_per_cycle, blocks_per_commitment)) - (fun (first_level, first_cycle, blocks_per_cycle, blocks_per_commitment) -> - {first_level; first_cycle; blocks_per_cycle; blocks_per_commitment}) - (obj4 - (req - "first_level" - ~description:"The first level of a new cycle era." - Raw_level_repr.encoding) - (req - "first_cycle" - ~description:"The first cycle of a new cycle era." - Cycle_repr.encoding) - (req - "blocks_per_cycle" - ~description: - "The value of the blocks_per_cycle constant used during the cycle \ - era starting with first_level." - int32) - (req - "blocks_per_commitment" - ~description: - "The value of the blocks_per_commitment constant used during the \ - cycle era starting with first_level." - int32)) - -let cycle_eras_encoding = - Data_encoding.conv_with_guard - (fun eras -> eras) - (fun eras -> - match create_cycle_eras eras with - | Ok eras -> Ok eras - | Error _ -> Error "Invalid cycle eras") - (Data_encoding.list cycle_era_encoding) - -let current_era = function [] -> assert false | cycle_era :: _ -> cycle_era - -let root_level cycle_eras = - let first_era = List.last_opt cycle_eras in - let first_era = - match first_era with - | Some first_era -> first_era - | None -> - (* {!create_cycle_eras} fails if the list is empty. - {!cycle_eras_encoding} uses {!create_cycle_eras} and so fails on empty - lists too. *) - assert false - in - { - level = first_era.first_level; - level_position = 0l; - cycle = Cycle_repr.root; - cycle_position = 0l; - expected_commitment = false; - } - -(* This function returns the cycle era to which [level] belongs. *) -let era_of_level ~cycle_eras level = - let rec aux = function - | ({first_level; _} as era) :: previous_eras -> - if Raw_level_repr.(level >= first_level) then era else aux previous_eras - | [] -> assert false - in - aux cycle_eras - -(* This function returns the cycle era to which [cycle] belongs. *) -let era_of_cycle ~cycle_eras cycle = - let rec aux = function - | ({first_cycle; _} as era) :: previous_eras -> - if Cycle_repr.(cycle >= first_cycle) then era else aux previous_eras - | [] -> assert false - in - aux cycle_eras - -(* precondition: [level] belongs to [era] *) -let level_from_raw_with_era era ~first_level_in_alpha_family level = - let {first_level; first_cycle; blocks_per_cycle; blocks_per_commitment} = - era - in - let level_position_in_era = Raw_level_repr.diff level first_level in - assert (Compare.Int32.(level_position_in_era >= 0l)) ; - let cycles_since_era_start = - Int32.div level_position_in_era blocks_per_cycle - in - let cycle = - Cycle_repr.add first_cycle (Int32.to_int cycles_since_era_start) - in - let cycle_position = Int32.rem level_position_in_era blocks_per_cycle in - let level_position = Raw_level_repr.diff level first_level_in_alpha_family in - let expected_commitment = - Compare.Int32.( - Int32.rem cycle_position blocks_per_commitment - = Int32.pred blocks_per_commitment) - in - {level; level_position; cycle; cycle_position; expected_commitment} - -let level_from_raw_aux_exn ~cycle_eras level = - let first_level_in_alpha_family = - match List.rev cycle_eras with - | [] -> assert false - | {first_level; _} :: _ -> first_level - in - let era = era_of_level ~cycle_eras level in - level_from_raw_with_era era ~first_level_in_alpha_family level - -let from_raw ~cycle_eras l = level_from_raw_aux_exn ~cycle_eras l - -type error += Level_not_in_alpha of Raw_level_repr.t - -let () = - register_error_kind - `Permanent - ~id:"level_not_in_alpha" - ~title:"Level not in Alpha family" - ~description:"Level not in Alpha family" - ~pp:(fun ppf level -> - Format.fprintf - ppf - "Level %a is not in the Alpha family of protocols." - Raw_level_repr.pp - level) - Data_encoding.(obj1 (req "level" Raw_level_repr.encoding)) - (function Level_not_in_alpha level -> Some level | _ -> None) - (fun level -> Level_not_in_alpha level) - -let level_from_raw_aux ~cycle_eras level = - let first_level_in_alpha_family = - match List.rev cycle_eras with - | [] -> assert false - | {first_level; _} :: _ -> first_level - in - error_when - Raw_level_repr.(level < first_level_in_alpha_family) - (Level_not_in_alpha level) - >|? fun () -> - let era = era_of_level ~cycle_eras level in - level_from_raw_with_era era ~first_level_in_alpha_family level - -type error += Negative_level_and_offset_sum of int32 * int32 - -let () = - register_error_kind - `Permanent - ~id:"negative_level_and_offset_sum" - ~title:"Negative sum of level and offset" - ~description:"Negative sum of level and offset" - ~pp:(fun ppf (level, offset) -> - Format.fprintf - ppf - "Sum of level (%ld) and offset (%ld) is negative." - level - offset) - Data_encoding.(obj2 (req "level" int32) (req "offset" int32)) - (function - | Negative_level_and_offset_sum (level, offset) -> Some (level, offset) - | _ -> None) - (fun (level, offset) -> Negative_level_and_offset_sum (level, offset)) - -let from_raw_with_offset ~cycle_eras ~offset raw_level = - let res = Raw_level_repr.(of_int32 (Int32.add (to_int32 raw_level) offset)) in - match res with - | Ok level -> level_from_raw_aux ~cycle_eras level - | Error _ -> - error - (Negative_level_and_offset_sum - (Raw_level_repr.to_int32 raw_level, offset)) - -let first_level_in_cycle_from_eras ~cycle_eras cycle = - let first_level_in_alpha_family = - match List.rev cycle_eras with - | [] -> assert false - | {first_level; _} :: _ -> first_level - in - let era = era_of_cycle ~cycle_eras cycle in - let cycle_position = Cycle_repr.diff cycle era.first_cycle in - let offset = Int32.mul era.blocks_per_cycle cycle_position in - let first_level_in_cycle = - Raw_level_repr.(of_int32_exn (Int32.add (to_int32 era.first_level) offset)) - in - level_from_raw_with_era era ~first_level_in_alpha_family first_level_in_cycle - -let last_of_cycle ~cycle_eras level = - let era = era_of_level ~cycle_eras level.level in - Compare.Int32.(Int32.succ level.cycle_position = era.blocks_per_cycle) diff --git a/src/proto_012_Psithaca/lib_protocol/level_repr.mli b/src/proto_012_Psithaca/lib_protocol/level_repr.mli deleted file mode 100644 index 16e335b8f168..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/level_repr.mli +++ /dev/null @@ -1,115 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module defines the protocol representation of a level. Besides the "raw - level", which is the shell's notion of the level, this representation also - contains additional information, like the cycle the level belongs to. *) - -type t = private { - level : Raw_level_repr.t; - (** The level of the block relative to genesis. This - is also the Shell's notion of level. *) - level_position : int32; - (** The level of the block relative to the block that starts the - alpha family of protocols. *) - cycle : Cycle_repr.t; - (** The current cycle's number. Note that cycles are a protocol-specific - notion. As a result, the cycle number starts at 0 with the first block of - the first version of protocol alpha. *) - cycle_position : int32; - (** The current level of the block relative to the first block of the current - cycle. *) - expected_commitment : bool; -} - -type level = t - -include Compare.S with type t := level - -val encoding : level Data_encoding.t - -val pp : Format.formatter -> level -> unit - -val pp_full : Format.formatter -> level -> unit - -val diff : level -> level -> int32 - -(** A cycle era is a chunk of cycles having the same number of levels - per cycle and the same number of blocks per commitment. *) -type cycle_era = { - first_level : Raw_level_repr.t; (** The first level of a cycle era. *) - first_cycle : Cycle_repr.t; (** The first cycle of a cycle era. *) - blocks_per_cycle : int32; - (** The value of the blocks_per_cycle constant used during the cycle - era starting with first_level. *) - blocks_per_commitment : int32; - (** The value of the blocks_per_commitment constant used during the - cycle era starting with first_level. *) -} - -(** Stores the cycles eras of the Alpha family of protocols *) -type cycle_eras - -val cycle_eras_encoding : cycle_eras Data_encoding.t - -(** Preconditions on the input list of cycle eras: - - the list is not empty - - the first levels and the first cycles are decreasing, meaning that the - first era in the list is the current era, and the last era in the list - is the oldest era - Invariants: - - the first era therefore contains the same constants as in Constants - - the first level of an era is the first level of a cycle -*) -val create_cycle_eras : cycle_era list -> cycle_eras tzresult - -(** Returns the current era *) -val current_era : cycle_eras -> cycle_era - -(** Returns the first level of the oldest era *) -val root_level : cycle_eras -> level - -(** Returns the annotated level corresponding to a raw level *) -val from_raw : cycle_eras:cycle_eras -> Raw_level_repr.t -> level - -(** Returns the annotated level corresponding to a raw level and an - offset. A positive offset corresponds to a higher level. - Fails with [Negative_level_and_offset_sum] if the sum of the raw_level and the offset is negative. - Fails with [Level_not_in_alpha] if the sum of the raw_level and the offset - is a level before the first level in the Alpha family of protocols. *) -val from_raw_with_offset : - cycle_eras:cycle_eras -> offset:int32 -> Raw_level_repr.t -> level tzresult - -(** Returns the first level of the given cycle. *) -val first_level_in_cycle_from_eras : - cycle_eras:cycle_eras -> Cycle_repr.t -> level - -(** Returns true if the given level is the last of a cycle. *) -val last_of_cycle : cycle_eras:cycle_eras -> level -> bool - -(**/**) - -(* exported for unit testing only *) -type error += Invalid_cycle_eras diff --git a/src/proto_012_Psithaca/lib_protocol/level_storage.ml b/src/proto_012_Psithaca/lib_protocol/level_storage.ml deleted file mode 100644 index cf4fa87d12c4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/level_storage.ml +++ /dev/null @@ -1,122 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Level_repr - -let from_raw c l = - let cycle_eras = Raw_context.cycle_eras c in - Level_repr.from_raw ~cycle_eras l - -let from_raw_with_offset c ~offset l : Level_repr.t tzresult = - let cycle_eras = Raw_context.cycle_eras c in - Level_repr.from_raw_with_offset ~cycle_eras ~offset l - -let root c = Raw_context.cycle_eras c |> Level_repr.root_level - -let succ c (l : Level_repr.t) = from_raw c (Raw_level_repr.succ l.level) - -let pred c (l : Level_repr.t) = - match Raw_level_repr.pred l.Level_repr.level with - | None -> None - | Some l -> Some (from_raw c l) - -let add c (l : Level_repr.t) n = from_raw c (Raw_level_repr.add l.level n) - -let sub c (l : Level_repr.t) n = - match Raw_level_repr.sub l.level n with - | None -> None - | Some raw_level -> - let cycle_eras = Raw_context.cycle_eras c in - let root_level = Level_repr.root_level cycle_eras in - if Raw_level_repr.(raw_level >= root_level.level) then - Some (from_raw c raw_level) - else None - -let current ctxt = Raw_context.current_level ctxt - -let previous ctxt = - let l = current ctxt in - match pred ctxt l with - | None -> assert false (* We never validate the Genesis... *) - | Some p -> p - -let first_level_in_cycle ctxt cycle = - let cycle_eras = Raw_context.cycle_eras ctxt in - Level_repr.first_level_in_cycle_from_eras ~cycle_eras cycle - -let last_level_in_cycle ctxt c = - match pred ctxt (first_level_in_cycle ctxt (Cycle_repr.succ c)) with - | None -> assert false - | Some x -> x - -let levels_in_cycle ctxt cycle = - let first = first_level_in_cycle ctxt cycle in - let[@coq_struct "n"] rec loop (n : Level_repr.t) acc = - if Cycle_repr.(n.cycle = first.cycle) then loop (succ ctxt n) (n :: acc) - else acc - in - loop first [] - -let levels_in_current_cycle ctxt ?(offset = 0l) () = - let current_cycle = Cycle_repr.to_int32 (current ctxt).cycle in - let cycle = Int32.add current_cycle offset in - if Compare.Int32.(cycle < 0l) then [] - else - let cycle = Cycle_repr.of_int32_exn cycle in - levels_in_cycle ctxt cycle - -let levels_with_commitments_in_cycle ctxt c = - let first = first_level_in_cycle ctxt c in - let[@coq_struct "n"] rec loop (n : Level_repr.t) acc = - if Cycle_repr.(n.cycle = first.cycle) then - if n.expected_commitment then loop (succ ctxt n) (n :: acc) - else loop (succ ctxt n) acc - else acc - in - loop first [] - -let last_allowed_fork_level c = - let level = Raw_context.current_level c in - let preserved_cycles = Constants_storage.preserved_cycles c in - match Cycle_repr.sub level.cycle preserved_cycles with - | None -> Raw_level_repr.root - | Some cycle -> (first_level_in_cycle c cycle).level - -let last_of_a_cycle ctxt level = - let cycle_eras = Raw_context.cycle_eras ctxt in - Level_repr.last_of_cycle ~cycle_eras level - -let dawn_of_a_new_cycle ctxt = - let level = current ctxt in - if last_of_a_cycle ctxt level then Some level.cycle else None - -let may_snapshot_rolls ctxt = - let level = current ctxt in - let blocks_per_stake_snapshot = - Constants_storage.blocks_per_stake_snapshot ctxt - in - Compare.Int32.equal - (Int32.rem level.cycle_position blocks_per_stake_snapshot) - (Int32.pred blocks_per_stake_snapshot) diff --git a/src/proto_012_Psithaca/lib_protocol/level_storage.mli b/src/proto_012_Psithaca/lib_protocol/level_storage.mli deleted file mode 100644 index aeebe659b64f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/level_storage.mli +++ /dev/null @@ -1,71 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val current : Raw_context.t -> Level_repr.t - -val previous : Raw_context.t -> Level_repr.t - -val root : Raw_context.t -> Level_repr.t - -val from_raw : Raw_context.t -> Raw_level_repr.t -> Level_repr.t - -(** Fails with [Negative_level_and_offset_sum] if the sum of the raw_level and the offset is negative. *) -val from_raw_with_offset : - Raw_context.t -> offset:int32 -> Raw_level_repr.t -> Level_repr.t tzresult - -val pred : Raw_context.t -> Level_repr.t -> Level_repr.t option - -val succ : Raw_context.t -> Level_repr.t -> Level_repr.t - -(** [i] must be positive *) -val add : Raw_context.t -> Level_repr.t -> int -> Level_repr.t - -(** [sub c level i] returns None if the level is before the first - level of the Alpha family of protocol, otherwise it returns the - expected level. [i] must be positive. *) -val sub : Raw_context.t -> Level_repr.t -> int -> Level_repr.t option - -val first_level_in_cycle : Raw_context.t -> Cycle_repr.t -> Level_repr.t - -val last_level_in_cycle : Raw_context.t -> Cycle_repr.t -> Level_repr.t - -val levels_in_cycle : Raw_context.t -> Cycle_repr.t -> Level_repr.t list - -val levels_in_current_cycle : - Raw_context.t -> ?offset:int32 -> unit -> Level_repr.t list - -val levels_with_commitments_in_cycle : - Raw_context.t -> Cycle_repr.t -> Level_repr.t list - -val last_allowed_fork_level : Raw_context.t -> Raw_level_repr.t - -(** Returns [Some cycle] if the current level represents the last - level of [cycle] and [None] if the level is not the last level of a - cycle. *) -val dawn_of_a_new_cycle : Raw_context.t -> Cycle_repr.t option - -(** Returns [true] if the rolls should be snapshot at the current - level. *) -val may_snapshot_rolls : Raw_context.t -> bool diff --git a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_cpmm.ml b/src/proto_012_Psithaca/lib_protocol/liquidity_baking_cpmm.ml deleted file mode 100644 index be63503aa883..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_cpmm.ml +++ /dev/null @@ -1,13 +0,0 @@ -let script_hex : Hex.t = - `Hex - "02000011c405000764076407640865046e00000006256f776e6572076504620000000d256d696e4c71744d696e7465640765046200000013256d6178546f6b656e734465706f7369746564046b0000000925646561646c696e650000000d256164644c6971756964697479046c000000082564656661756c7407640865046e0000000325746f076504620000000a256c71744275726e65640765046a00000010256d696e58747a57697468647261776e0765046200000013256d696e546f6b656e7357697468647261776e046b0000000925646561646c696e65000000102572656d6f76654c69717569646974790865046e00000015256f7574707574446578746572436f6e74726163740765046200000010256d696e546f6b656e73426f756768740765046e0000000325746f076504620000000b25746f6b656e73536f6c64046b0000000925646561646c696e650000000d25746f6b656e546f546f6b656e07640865046e0000000325746f076504620000000b25746f6b656e73536f6c640765046a0000000d256d696e58747a426f75676874046b0000000925646561646c696e650000000b25746f6b656e546f58747a0865046e0000000325746f0765046200000010256d696e546f6b656e73426f75676874046b0000000925646561646c696e650000000b2578747a546f546f6b656e0501076504620000000a25746f6b656e506f6f6c0765046a000000082578747a506f6f6c0765046200000009256c7174546f74616c0765046e0000000d25746f6b656e41646472657373046e0000000b256c71744164647265737305020200000f7203210317034c0316072e02000009d1072e020000035a072e020000032603210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200004074303620003032702000002ea0743036a000105700004032105710005031703160322072f0200000013074303680100000008444956206279203003270200000000031603130743036a0001034c0322072f02000000130743036801000000084449562062792030032702000000000316034c0321057100020570000603210571000703170317031605700002032105710003033a0322072f020000001307430368010000000844495620627920300327020000000003160570000205700006032105710007031605700003033a0322072f020000001307430368010000000844495620627920300327020000002a03210317034c03160743036200000570000203190325072c02000000000200000008074303620001031205700002034c0321057100020319032a072c020000000c05200005074303620004032702000001b60571000203210571000303190337072c020000000c0520000407430362000503270200000190057000030321057100040317031703170570000203210571000305700005032105710006031703170316031203420570000403210571000503170316034205700004032105710005031603420317034c032105710002057000050321057100060316031203420321031703170313057000060317031603120342034c03160342034c03490354034203480342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d05700002033005700003034205700002032105710003034c03210317034c031605700002031703170317031706550765045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e072f020000000807430362000c032702000000000743036a000005700002057000030342034d05700002053d036d05700002031b05700002031b0342020000002803200321031703170313057000020321057100030317031603120342034c03160342053d036d0342020000066b072e020000038d03210317034c0316034c03210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200005074303620003032702000003470743036a000003130319032a072c020000000c0520000507430362000a03270200000323057000040321057100050317031703160743036a000105700006032105710007031703160322072f0200000013074303680100000008444956206279203003270200000000031605700004032105710005033a0322072f020000001307430368010000000844495620627920300327020000000003160743036a0001034c033a0570000503210571000603170317031605700006032105710007031605700005032105710006033a0322072f02000000130743036801000000084449562062792030032702000000000316057000030570000203210571000303190337072c020000000c0520000607430362000b0327020000022e05700002034c03210571000203190337072c020000000c0520000507430362000d032702000002060570000203210571000305700005032105710006031703170316034b0356072f020000000807430362000e03270200000000034c032105710002057000060321057100070316034b0356072f020000000807430362000f03270200000000057000040743035b0000034b0348034205700006032105710007034c03210317034c031605700002031703170317031706550765045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e072f020000000807430362000c032702000000000743036a000005700002057000030342034d0570000305700005032105710006034203490354034205700006032105710007034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d05700004032105710005057000060555036c072f020000000807430362000903270200000000034c0743036c030b034d0570000603210571000703170317057000060570000703210571000803170316034b034205700006031603420321031703170317057000060342034c032105710002031703160342034c031603420317057000040342053d036d05700002031b05700002031b05700002031b034202000002d203210317034c0316034c03210317034c0316034c03210317034c0316034c03210317034c03160570000406550765046e0000000325746f0765046200000010256d696e546f6b656e73426f75676874046b0000000925646561646c696e650000000b2578747a546f546f6b656e072f020000000807430362001f032702000000000743036a000003130319032a072c020000000c0520000607430362000a0327020000022d05700002032105710003034003190328072c020000000c05200006074303620003032702000002050743036200a70f05700002032105710003033a0743036200a80f057000070321057100080316033a031205700006032105710007031703160743036200a70f05700004032105710005033a033a0322072f020000001307430368010000000844495620627920300327020000000003160743036200a80f0743036200a70f05700002032105710003033a0322072f02000000130743036801000000084449562062792030032702000000000316057000070321057100080317057000040321057100050570000903210571000a031603120342032103170317057000030321057100040570000a03170316034b0342034c031603420570000403490354034203480342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d057000040570000303210571000405700006057000080342057000070342034d0570000305700004034b0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d05700003053d036d05700002031b05700002031b05700002031b0342020000058d072e02000002cc03210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200004074303620003032702000002900743036a000003130319032a072c020000000c0520000407430362000a0327020000026c0743036200a70f05700002032105710003033a0743036200a80f057000050321057100060316033a03120743036a000105700005032105710006031703160322072f020000001307430368010000000844495620627920300327020000000003160743036200a70f05700004032105710005033a033a0322072f020000001307430368010000000844495620627920300327020000000003160743036a0001034c033a0743036200a80f0743036200a70f05700002032105710003033a0322072f0200000013074303680100000008444956206279203003270200000000031605700002034c03210571000203190337072c020000000a032007430362000803270200000000057000020321057100030349035403420348034205700005032105710006034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d034c032105710002057000050555036c072f020000000807430362000903270200000000034c0743036c030b034d0570000503210571000603170570000505700006032105710007031603120342032103170317057000050321057100060570000703170316034b0342034c031603420570000305700004034b0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d034c053d036d05700002031b05700002031b05700002031b034202000002b503210317034c0316034c03210317034c0316034c034003190328072c020000000c05200003074303620003032702000002830743036a000105700003032105710004031703160322072f0200000013074303680100000008444956206279203003270200000000031603130743036a0001034c0322072f020000001307430368010000000844495620627920300327020000000003160743036200a80f0743036200a70f05700002032105710003033a0322072f02000000130743036801000000084449562062792030032702000000000316032105700002034b03110743036200a70f05700002032105710003033a0743036200a80f05700004033a03120570000503210571000603160743036200a70f05700004032105710005033a033a0322072f0200000013074303680100000008444956206279203003270200000000031605700003034c03210571000203190337072c020000000a0320074303620012032702000000000321057000050321057100060316034b0356072f02000000080743036200130327020000000005700005032105710006031703170743036a000105700005033a05700006032105710007031703160312034205700005031603420317034c0342034c057000030342034903540342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d0743036a000105700003033a0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d05700002053d036d05700002031b05700002031b0342" - -let script_bytes : Bytes.t option = Hex.to_bytes script_hex - -let script_opt : Script_repr.expr option = - Option.bind - script_bytes - (Data_encoding.Binary.of_bytes_opt Script_repr.expr_encoding) - -let script : Script_repr.expr = - Option.value_f ~default:(fun () -> assert false) script_opt diff --git a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_lqt.ml b/src/proto_012_Psithaca/lib_protocol/liquidity_baking_lqt.ml deleted file mode 100644 index 80c92e523d0f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_lqt.ml +++ /dev/null @@ -1,13 +0,0 @@ -let script_hex : Hex.t = - `Hex - "020000070005000764076407640865046e00000008257370656e6465720462000000062576616c75650000000825617070726f766508650865046e00000006256f776e6572046e00000008257370656e646572000000082572657175657374065a0362000000092563616c6c6261636b0000000d25676574416c6c6f77616e636507640865046e00000006256f776e6572065a0362000000092563616c6c6261636b0000000b2567657442616c616e63650865046c000000082572657175657374065a0362000000092563616c6c6261636b0000000f25676574546f74616c537570706c7907640865045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e0865046e000000052566726f6d0765046e0000000325746f0462000000062576616c756500000009257472616e73666572050107650861036e03620000000725746f6b656e73076508610765046e00000006256f776e6572046e00000008257370656e64657203620000000b25616c6c6f77616e6365730765046e000000062561646d696e04620000000d25746f74616c5f737570706c7905020200000552032103170743036a000003130319033c072c020000001607430368010000000b446f6e7453656e6454657a03270200000000034c0316072e02000001b2072e0200000132072e02000000e2034c03210571000203170316034c0321057100020316034803420743036200000570000303210571000403170319032a07430362000005700003032105710004057000030321057100040329072f020000000607430362000002000000000319032a0314072c0200000020074303680100000015556e73616665416c6c6f77616e63654368616e676503270200000000057000030321057100040317031705700002057000030317074303620000034c03210571000203190325072c02000000060320053e0362020000000203460570000303500342034c03160342053d036d03420200000044034c032105700002053d036d034c03210571000203170743036a000005700004031703160570000403160329072f02000000060743036200000200000000034d031b03420200000074072e0200000042034c032105700002053d036d034c03210571000203170743036a00000570000403160570000403160329072f02000000060743036200000200000000034d031b03420200000026034c032105700002053d036d034c03170743036a000005700003031703170317034d031b0342020000035e072e020000013c034c03210571000203170317031603480319033c072c02000000140743036801000000094f6e6c7941646d696e03270200000000032103160570000203210571000303160570000203210571000303170329072f0200000006074303620000020000000003120356072f020000003607430368010000002b43616e6e6f74206275726e206d6f7265207468616e207468652074617267657427732062616c616e63652e03270200000000034c032105710002031605700003032105710004031703170317031203110570000303210571000403170570000403160743036200000570000403210571000503190325072c020000000a057000030320053e03620200000006057000030346057000040317035003420321057100020317031703160342034c032105710002031703160342034c03160342053d036d03420200000216034c03210571000203170316057000020321057100030316057000020321057100030316034803190325072c0200000002034c02000000a903480570000303210571000403160342057000030321057100040317031705700003032105710004057000020321057100030329072f02000000060743036200000200000000034b0356072f020000001d0743036801000000124e6f74456e6f756768416c6c6f77616e636503270200000000057000030743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c03460570000203500570000203210571000303170317057000020321057100030570000403210571000503160329072f02000000060743036200000200000000034b0356072f020000001b0743036801000000104e6f74456e6f75676842616c616e636503270200000000057000020743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c034605700003032105710004031603500570000203210571000303170317034c03210571000205700004032105710005031703160329072f020000000607430362000002000000000312034c0743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c034605700003031703160350057000020317034c0342032103170317057000020342034c03160342053d036d0342" - -let script_bytes : Bytes.t option = Hex.to_bytes script_hex - -let script_opt : Script_repr.expr option = - Option.bind - script_bytes - (Data_encoding.Binary.of_bytes_opt Script_repr.expr_encoding) - -let script : Script_repr.expr = - Option.value_f ~default:(fun () -> assert false) script_opt diff --git a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_migration.ml b/src/proto_012_Psithaca/lib_protocol/liquidity_baking_migration.ml deleted file mode 100644 index 89985c3ff7e7..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_migration.ml +++ /dev/null @@ -1,242 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Tocqueville Group, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module is used to originate contracts for liquidity baking during - protocol stitching: a CPMM (constant product market making) contract and a - liquidity token FA1.2 contract, with the storage of each containing the - other's address. - - The CPMM's storage contains a token address, which corresponds to tzBTC when - originated on mainnet and a reference FA1.2 contract when originated for - testing. - - The test FA1.2 contract uses the same script as the liquidity token. Its - manager is initialized to the first bootstrap account. Before originating it, - we make sure we are not on mainnet by both checking for the existence of the - tzBTC contract and that the level is sufficiently low. - - The Michelson and Ligo code, as well as Coq proofs, for the CPMM and - liquidity token contracts are available here: - https://gitlab.com/dexter2tz/dexter2tz/-/tree/liquidity_baking - - All contracts were generated from Ligo at revision - 4d10d07ca05abe0f8a5fb97d15267bf5d339d9f4 and converted to OCaml using - `tezos-client convert`. -*) - -open Michelson_v1_primitives -open Micheline - -let null_address = - Bytes.of_string - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" - -let mainnet_tzBTC_address = "KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn" - -(** If token_pool, xtz_pool, or lqt_total are ever zero the CPMM will be - permanently broken. Therefore, we initialize it with the null address - registered as a liquidity provider with 1 satoshi tzBTC and 100 mutez - (roughly the current exchange rate). *) -let cpmm_init_storage ~token_address ~lqt_address = - Script_repr.lazy_expr - (Micheline.strip_locations - (Prim - ( 0, - D_Pair, - [ - Int (1, Z.one); - Int (2, Z.of_int 100); - Int (3, Z.of_int 100); - String (4, token_address); - String (5, lqt_address); - ], - [] ))) - -let lqt_init_storage cpmm_address = - Script_repr.lazy_expr - (Micheline.strip_locations - (Prim - ( 0, - D_Pair, - [ - Seq - ( 1, - [ - Prim - ( 2, - D_Elt, - [Bytes (3, null_address); Int (4, Z.of_int 100)], - [] ); - ] ); - Seq (5, []); - String (6, cpmm_address); - Int (7, Z.of_int 100); - ], - [] ))) - -let test_fa12_init_storage manager = - Script_repr.lazy_expr - (Micheline.strip_locations - (Prim - ( 0, - D_Pair, - [ - Seq (1, []); - Seq (2, []); - String (3, manager); - Int (4, Z.of_int 10_000); - ], - [] ))) - -let originate ctxt address ~balance script = - Contract_storage.raw_originate - ctxt - ~prepaid_bootstrap_storage:true - address - ~script - >>=? fun ctxt -> - Contract_storage.used_storage_space ctxt address >>=? fun size -> - Fees_storage.burn_origination_fees - ~origin:Protocol_migration - ctxt - ~storage_limit:(Z.of_int64 Int64.max_int) - ~payer:`Liquidity_baking_subsidies - >>=? fun (ctxt, _, origination_updates) -> - Fees_storage.burn_storage_fees - ~origin:Protocol_migration - ctxt - ~storage_limit:(Z.of_int64 Int64.max_int) - ~payer:`Liquidity_baking_subsidies - size - >>=? fun (ctxt, _, storage_updates) -> - Token.transfer - ~origin:Protocol_migration - ctxt - `Liquidity_baking_subsidies - (`Contract address) - balance - >>=? fun (ctxt, transfer_updates) -> - let balance_updates = - origination_updates @ storage_updates @ transfer_updates - in - let result : Migration_repr.origination_result = - { - balance_updates; - originated_contracts = [address]; - storage_size = size; - paid_storage_size_diff = size; - } - in - return (ctxt, result) - -let originate_test_fa12 ~typecheck ctxt admin = - Contract_storage.fresh_contract_from_current_nonce ctxt - >>?= fun (ctxt, fa12_address) -> - let script = - Script_repr. - { - code = Script_repr.lazy_expr Liquidity_baking_lqt.script; - storage = - test_fa12_init_storage (Signature.Public_key_hash.to_b58check admin); - } - in - typecheck ctxt script >>=? fun (script, ctxt) -> - originate ctxt fa12_address ~balance:(Tez_repr.of_mutez_exn 1_000_000L) script - >|=? fun (ctxt, origination_result) -> - (ctxt, fa12_address, [origination_result]) - -(* hardcoded from lib_parameters *) -let first_bootstrap_account = - Signature.Public_key.hash - (Signature.Public_key.of_b58check_exn - "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav") - -let check_tzBTC ~typecheck current_level ctxt f = - Contract_repr.of_b58check mainnet_tzBTC_address >>?= fun tzBTC -> - Contract_storage.exists ctxt tzBTC >>=? function - | true -> - (* If tzBTC exists, we're on mainnet and we use it as the token address in the CPMM. *) - f ctxt tzBTC [] - | false -> - (* If the tzBTC contract does not exist, we originate a test FA1.2 contract using the same script as the LQT. This is so that we can test the contracts after performing the same protocol migration that will be done on mainnet. - - First, we check current level is below mainnet level roughly around 010 injection so we do not accidentally originate the test token contract on mainnet. *) - if Compare.Int32.(current_level < 1_437_862l) then - originate_test_fa12 ~typecheck ctxt first_bootstrap_account - (* Token contract admin *) - >>=? fun (ctxt, token_address, token_result) -> - f ctxt token_address token_result - else - (* If we accidentally entered the tzBTC address incorrectly, but current level indicates this could be mainnet, we do not originate any contracts *) - return (ctxt, []) - -let init ctxt ~typecheck = - (* We use a custom origination nonce because it is unset when stitching from 009 *) - let nonce = Operation_hash.hash_string ["Drip, drip, drip."] in - let ctxt = Raw_context.init_origination_nonce ctxt nonce in - Storage.Liquidity_baking.Escape_ema.init ctxt 0l >>=? fun ctxt -> - let current_level = - Raw_level_repr.to_int32 (Level_storage.current ctxt).level - in - Contract_storage.fresh_contract_from_current_nonce ctxt - >>?= fun (ctxt, cpmm_address) -> - Contract_storage.fresh_contract_from_current_nonce ctxt - >>?= fun (ctxt, lqt_address) -> - Storage.Liquidity_baking.Cpmm_address.init ctxt cpmm_address >>=? fun ctxt -> - check_tzBTC - ~typecheck - current_level - ctxt - (fun ctxt token_address token_result -> - let cpmm_script = - Script_repr. - { - code = Script_repr.lazy_expr Liquidity_baking_cpmm.script; - storage = - cpmm_init_storage - ~token_address:(Contract_repr.to_b58check token_address) - ~lqt_address:(Contract_repr.to_b58check lqt_address); - } - in - typecheck ctxt cpmm_script >>=? fun (cpmm_script, ctxt) -> - let lqt_script = - Script_repr. - { - code = Script_repr.lazy_expr Liquidity_baking_lqt.script; - storage = lqt_init_storage (Contract_repr.to_b58check cpmm_address); - } - in - typecheck ctxt lqt_script >>=? fun (lqt_script, ctxt) -> - originate - ctxt - cpmm_address - ~balance:(Tez_repr.of_mutez_exn 100L) - cpmm_script - >>=? fun (ctxt, cpmm_result) -> - originate ctxt lqt_address ~balance:Tez_repr.zero lqt_script - >|=? fun (ctxt, lqt_result) -> - (* Unsets the origination nonce, which is okay because this is called after other originations in stitching. *) - let ctxt = Raw_context.unset_origination_nonce ctxt in - (ctxt, [cpmm_result; lqt_result] @ token_result)) diff --git a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_migration.mli b/src/proto_012_Psithaca/lib_protocol/liquidity_baking_migration.mli deleted file mode 100644 index 27059e493d50..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_migration.mli +++ /dev/null @@ -1,33 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Tocqueville Group, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val init : - Raw_context.t -> - typecheck: - (Raw_context.t -> - Script_repr.t -> - ((Script_repr.t * Lazy_storage_diff.diffs option) * Raw_context.t) tzresult - Lwt.t) -> - (Raw_context.t * Migration_repr.origination_result list) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_repr.ml b/src/proto_012_Psithaca/lib_protocol/liquidity_baking_repr.ml deleted file mode 100644 index 2dc35196d273..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_repr.ml +++ /dev/null @@ -1,71 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Tocqueville Group, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let get_cpmm_address = Storage.Liquidity_baking.Cpmm_address.get - -let get_escape_ema = Storage.Liquidity_baking.Escape_ema.get - -type escape_ema = Int32.t - -let on_cpmm_exists ctxt f = - get_cpmm_address ctxt >>=? fun cpmm_contract -> - Contract_storage.exists ctxt cpmm_contract >>=? function - | false -> - (* do nothing if the cpmm is not found *) - return (ctxt, []) - | true -> f ctxt cpmm_contract - -let on_below_sunset ctxt f = - let sunset_level = Constants_storage.liquidity_baking_sunset_level ctxt in - let level = Raw_level_repr.to_int32 (Level_storage.current ctxt).level in - if Compare.Int32.(level >= sunset_level) then return (ctxt, []) - else on_cpmm_exists ctxt f - -(* ema starts at zero - ema[n+1] = (1999 * ema[n] // 2000) + (1000 if escape_vote[n] else 0) - where escape_vote is protocol_data.contents.liquidity_baking_escape_vote *) -let update_escape_ema ctxt ~escape_vote = - get_escape_ema ctxt >>=? fun old_ema -> - (* if ema is over threshold, we don't update it because liquidity baking is permanently off *) - if - Compare.Int32.( - old_ema < Constants_storage.liquidity_baking_escape_ema_threshold ctxt) - then - let new_ema = - Int32.( - add (div (mul 1999l old_ema) 2000l) (if escape_vote then 1000l else 0l)) - in - Storage.Liquidity_baking.Escape_ema.update ctxt new_ema >|=? fun ctxt -> - (ctxt, new_ema, false) - else return (ctxt, old_ema, true) - -let on_subsidy_allowed ctxt ~escape_vote f = - update_escape_ema ctxt ~escape_vote - >>=? fun (ctxt, escape_ema, threshold_reached) -> - (* liquidity baking permanently shuts off if threshold is reached once *) - if threshold_reached then return (ctxt, [], escape_ema) - else - on_below_sunset ctxt f >|=? fun (ctxt, operation_results) -> - (ctxt, operation_results, escape_ema) diff --git a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_repr.mli b/src/proto_012_Psithaca/lib_protocol/liquidity_baking_repr.mli deleted file mode 100644 index f631ec4ddf4a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/liquidity_baking_repr.mli +++ /dev/null @@ -1,36 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Tocqueville Group, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val get_cpmm_address : Raw_context.t -> Contract_repr.t tzresult Lwt.t - -type escape_ema = Int32.t - -(** Checks if below EMA threshold (after updating), sunset level, and if CPMM - contract exists. *) -val on_subsidy_allowed : - Raw_context.t -> - escape_vote:bool -> - (Raw_context.t -> Contract_repr.t -> (Raw_context.t * 'a list) tzresult Lwt.t) -> - (Raw_context.t * 'a list * escape_ema) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/local_gas_counter.ml b/src/proto_012_Psithaca/lib_protocol/local_gas_counter.ml deleted file mode 100644 index 7ae70ae9f593..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/local_gas_counter.ml +++ /dev/null @@ -1,99 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -(* - - Gas update and check for gas exhaustion - ======================================= - - Costs of various computations are subtracted from an amount of gas made - available for the script execution. - - Updating the gas counter is a critical aspect to operation validation - because it is done at many places. - - For this reason, the gas counter must be read and updated as quickly as - possible. Hence, the gas counter should be stored in a machine register. To - motivate the OCaml compiler to make that choice, we represent the gas counter - as a local parameter of the execution [step] function. - -*) - -type local_gas_counter = int - -(* - - The gas counter stored in the context is desynchronized with the - [local_gas_counter] used locally. When we have to call a gas-consuming - function working on context with no local gas counter, we must update the - context so that it carries an up-to-date gas counter. Similarly, when we - return from such a function, the [local_gas_counter] must be updated as well. - - To statically track these points where the context's gas counter - must be updated, we introduce a type for outdated contexts. The - [step] function carries an [outdated_context]. When an external - function needs a [context], the typechecker points out the need for - a conversion: this forces us to either call [update_context], or - better, when this is possible, the function - [use_gas_counter_in_ctxt]. - -*) -type outdated_context = OutDatedContext of context [@@unboxed] - -let update_context local_gas_counter = function - | OutDatedContext ctxt -> - Gas.update_remaining_operation_gas - ctxt - (Saturation_repr.safe_int local_gas_counter) - [@@ocaml.inline always] - -let update_local_gas_counter ctxt = - (Gas.remaining_operation_gas ctxt :> int) - [@@ocaml.inline always] - -let outdated ctxt = OutDatedContext ctxt [@@ocaml.inline always] - -let context_from_outdated_context (OutDatedContext ctxt) = - ctxt - [@@ocaml.inline always] - -let use_gas_counter_in_ctxt ctxt local_gas_counter f = - let ctxt = update_context local_gas_counter ctxt in - f ctxt >>=? fun (y, ctxt) -> - return (y, outdated ctxt, update_local_gas_counter ctxt) - [@@ocaml.inline always] - -let update_and_check gas_counter (cost : Gas.cost) = - let gas_counter = gas_counter - (cost :> int) in - if Compare.Int.(gas_counter < 0) then None else Some gas_counter - [@@ocaml.inline always] - -let consume local_gas_counter cost = - match update_and_check local_gas_counter cost with - | None -> error Gas.Operation_quota_exceeded - | Some local_gas_counter -> Ok local_gas_counter - [@@ocaml.inline always] diff --git a/src/proto_012_Psithaca/lib_protocol/main.ml b/src/proto_012_Psithaca/lib_protocol/main.ml deleted file mode 100644 index a0f295c2c940..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/main.ml +++ /dev/null @@ -1,822 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Tezos Protocol Implementation - Protocol Signature Instance *) - -type block_header_data = Alpha_context.Block_header.protocol_data - -type block_header = Alpha_context.Block_header.t = { - shell : Block_header.shell_header; - protocol_data : block_header_data; -} - -let block_header_data_encoding = - Alpha_context.Block_header.protocol_data_encoding - -type block_header_metadata = Apply_results.block_metadata - -let block_header_metadata_encoding = Apply_results.block_metadata_encoding - -type operation_data = Alpha_context.packed_protocol_data = - | Operation_data : - 'kind Alpha_context.Operation.protocol_data - -> operation_data - -let operation_data_encoding = Alpha_context.Operation.protocol_data_encoding - -type operation_receipt = Apply_results.packed_operation_metadata = - | Operation_metadata : - 'kind Apply_results.operation_metadata - -> operation_receipt - | No_operation_metadata : operation_receipt - -let operation_receipt_encoding = Apply_results.operation_metadata_encoding - -let operation_data_and_receipt_encoding = - Apply_results.operation_data_and_metadata_encoding - -type operation = Alpha_context.packed_operation = { - shell : Operation.shell_header; - protocol_data : operation_data; -} - -let acceptable_passes = Alpha_context.Operation.acceptable_passes - -let max_block_length = Alpha_context.Block_header.max_header_length - -let max_operation_data_length = - Alpha_context.Constants.max_operation_data_length - -let validation_passes = - let open Alpha_context.Constants in - Updater. - [ - (* 2048 endorsements *) - {max_size = 2048 * 2048; max_op = Some 2048}; - (* 32k of voting operations *) - {max_size = 32 * 1024; max_op = None}; - (* revelations, wallet activations and denunciations *) - { - max_size = max_anon_ops_per_block * 1024; - max_op = Some max_anon_ops_per_block; - }; - (* 512kB *) - {max_size = 512 * 1024; max_op = None}; - ] - -let rpc_services = - Alpha_services.register () ; - Services_registration.get_rpc_services () - -type validation_mode = - | Application of { - block_header : Alpha_context.Block_header.t; - fitness : Alpha_context.Fitness.t; - payload_producer : Alpha_context.public_key_hash; - block_producer : Alpha_context.public_key_hash; - predecessor_round : Alpha_context.Round.t; - predecessor_level : Alpha_context.Level.t; - } - | Partial_application of { - block_header : Alpha_context.Block_header.t; - fitness : Alpha_context.Fitness.t; - payload_producer : Alpha_context.public_key_hash; - block_producer : Alpha_context.public_key_hash; - predecessor_level : Alpha_context.Level.t; - predecessor_round : Alpha_context.Round.t; - } - (* Mempool only *) - | Partial_construction of { - predecessor : Block_hash.t; - predecessor_fitness : Fitness.t; - predecessor_level : Alpha_context.Level.t; - predecessor_round : Alpha_context.Round.t; - } - (* Baker only *) - | Full_construction of { - predecessor : Block_hash.t; - payload_producer : Alpha_context.public_key_hash; - block_producer : Alpha_context.public_key_hash; - protocol_data_contents : Alpha_context.Block_header.contents; - level : Int32.t; - round : Alpha_context.Round.t; - predecessor_level : Alpha_context.Level.t; - predecessor_round : Alpha_context.Round.t; - } - -type validation_state = { - mode : validation_mode; - chain_id : Chain_id.t; - ctxt : Alpha_context.t; - op_count : int; - migration_balance_updates : Alpha_context.Receipt.balance_updates; - liquidity_baking_escape_ema : Int32.t; - implicit_operations_results : - Apply_results.packed_successful_manager_operation_result list; -} - -let cache_layout = Apply.cache_layout - -let begin_partial_application ~chain_id ~ancestor_context:ctxt - ~predecessor_timestamp ~(predecessor_fitness : Fitness.t) - (block_header : Alpha_context.Block_header.t) = - (* Note: we don't have access to the predecessor context. *) - let level = block_header.shell.level in - let timestamp = block_header.shell.timestamp in - Alpha_context.Fitness.from_raw block_header.shell.fitness >>?= fun fitness -> - Alpha_context.Fitness.round_from_raw predecessor_fitness - >>?= fun predecessor_round -> - Alpha_context.prepare ~level ~predecessor_timestamp ~timestamp ctxt - >>=? fun (ctxt, migration_balance_updates, migration_operation_results) -> - Alpha_context.Raw_level.of_int32 (Int32.pred level) - >>?= fun predecessor_level -> - let predecessor_level = - Alpha_context.Level.(from_raw ctxt predecessor_level) - in - Apply.begin_application - ctxt - chain_id - block_header - fitness - ~predecessor_timestamp - ~predecessor_level - ~predecessor_round - >>=? fun ( ctxt, - payload_producer_pk, - block_producer, - liquidity_baking_operations_results, - liquidity_baking_escape_ema ) -> - let mode = - Partial_application - { - block_header; - fitness; - predecessor_level; - predecessor_round; - payload_producer = Signature.Public_key.hash payload_producer_pk; - block_producer; - } - in - return - { - mode; - chain_id; - ctxt; - op_count = 0; - migration_balance_updates; - liquidity_baking_escape_ema; - implicit_operations_results = - Apply_results.pack_migration_operation_results - migration_operation_results - @ liquidity_baking_operations_results; - } - -(* During applications the valid consensus operations are: - * Endorsements on previous block with the right round, level, payload_hash (of the predecessor block) - * Preendorsements on current level, previous round, and the payload_hash of the current block - Those endorsements justify that the previous block was finalized. - Those preendorsements justify the locked_round part of the fitness of the current block - *) -let begin_application ~chain_id ~predecessor_context:ctxt ~predecessor_timestamp - ~predecessor_fitness (block_header : Alpha_context.Block_header.t) = - let level = block_header.shell.level in - let timestamp = block_header.shell.timestamp in - Alpha_context.Fitness.from_raw block_header.shell.fitness >>?= fun fitness -> - Alpha_context.Fitness.round_from_raw predecessor_fitness - >>?= fun predecessor_round -> - Alpha_context.Raw_level.of_int32 (Int32.pred level) - >>?= fun predecessor_level -> - Alpha_context.prepare ~level ~predecessor_timestamp ~timestamp ctxt - >>=? fun (ctxt, migration_balance_updates, migration_operation_results) -> - let predecessor_level = Alpha_context.Level.from_raw ctxt predecessor_level in - Apply.begin_application - ctxt - chain_id - block_header - fitness - ~predecessor_timestamp - ~predecessor_level - ~predecessor_round - >>=? fun ( ctxt, - payload_producer, - block_producer, - liquidity_baking_operations_results, - liquidity_baking_escape_ema ) -> - let mode = - Application - { - block_header; - fitness; - predecessor_round; - predecessor_level; - payload_producer = Signature.Public_key.hash payload_producer; - block_producer; - } - in - return - { - mode; - chain_id; - ctxt; - op_count = 0; - migration_balance_updates; - liquidity_baking_escape_ema; - implicit_operations_results = - Apply_results.pack_migration_operation_results - migration_operation_results - @ liquidity_baking_operations_results; - } - -let begin_construction ~chain_id ~predecessor_context:ctxt - ~predecessor_timestamp ~predecessor_level ~predecessor_fitness ~predecessor - ~timestamp ?(protocol_data : block_header_data option) () = - let level = Int32.succ predecessor_level in - Alpha_context.prepare ~level ~predecessor_timestamp ~timestamp ctxt - >>=? fun (ctxt, migration_balance_updates, migration_operation_results) -> - Alpha_context.Raw_level.of_int32 predecessor_level - >>?= fun predecessor_level -> - let predecessor_level = - Alpha_context.Level.(from_raw ctxt predecessor_level) - in - (match protocol_data with - | None -> - Alpha_context.Fitness.round_from_raw predecessor_fitness - >>?= fun predecessor_round -> - let escape_vote = false in - Apply.begin_partial_construction ctxt ~predecessor_level ~escape_vote - >>=? fun ( ctxt, - liquidity_baking_operations_results, - liquidity_baking_escape_ema ) -> - let mode = - Partial_construction - { - predecessor; - predecessor_fitness; - predecessor_level; - predecessor_round; - } - in - return - ( mode, - ctxt, - liquidity_baking_operations_results, - liquidity_baking_escape_ema ) - | Some proto_header -> - Alpha_context.Fitness.round_from_raw predecessor_fitness - >>?= fun predecessor_round -> - let round_durations = Alpha_context.Constants.round_durations ctxt in - Alpha_context.Round.round_of_timestamp - round_durations - ~predecessor_timestamp - ~predecessor_round - ~timestamp - >>?= fun round -> - (* The endorsement/preendorsement validation rules for construction are the - same as for application. *) - Apply.begin_full_construction - ctxt - ~predecessor_timestamp - ~predecessor_round - ~predecessor_level - ~round - proto_header.contents - >>=? fun { - ctxt; - protocol_data = protocol_data_contents; - payload_producer; - block_producer; - round; - liquidity_baking_escape_ema; - implicit_operations_results = - liquidity_baking_operations_results; - } -> - let mode = - Full_construction - { - predecessor; - payload_producer; - block_producer; - level; - round; - protocol_data_contents; - predecessor_round; - predecessor_level; - } - in - return - ( mode, - ctxt, - liquidity_baking_operations_results, - liquidity_baking_escape_ema )) - >|=? fun ( mode, - ctxt, - liquidity_baking_operations_results, - liquidity_baking_escape_ema ) -> - { - mode; - chain_id; - ctxt; - op_count = 0; - migration_balance_updates; - liquidity_baking_escape_ema; - implicit_operations_results = - Apply_results.pack_migration_operation_results migration_operation_results - @ liquidity_baking_operations_results; - } - -let apply_operation_with_mode mode ctxt chain_id data op_count operation - ~payload_producer = - let {shell; protocol_data = Operation_data protocol_data} = operation in - let operation : _ Alpha_context.operation = {shell; protocol_data} in - Apply.apply_operation - ctxt - chain_id - mode - Optimized - ~payload_producer - (Alpha_context.Operation.hash operation) - operation - >|=? fun (ctxt, result) -> - let op_count = op_count + 1 in - ({data with ctxt; op_count}, Operation_metadata result) - -let apply_operation ({mode; chain_id; ctxt; op_count; _} as data) - (operation : Alpha_context.packed_operation) = - match mode with - | Partial_application _ - when not - (List.exists - (Compare.Int.equal 0) - (Alpha_context.Operation.acceptable_passes operation)) -> - (* Multipass validation only considers operations in pass 0. *) - let op_count = op_count + 1 in - return ({data with ctxt; op_count}, No_operation_metadata) - | Partial_application - { - block_header = - { - shell = {predecessor; _}; - protocol_data = {contents = {payload_hash; _}; _}; - }; - fitness; - payload_producer; - predecessor_round; - predecessor_level; - _; - } -> - let locked_round = Alpha_context.Fitness.locked_round fitness in - apply_operation_with_mode - (Apply.Application - { - payload_hash; - predecessor_block = predecessor; - predecessor_round; - predecessor_level; - locked_round; - round = Alpha_context.Fitness.round fitness; - }) - ctxt - chain_id - data - op_count - operation - ~payload_producer - | Application - { - block_header = - { - shell = {predecessor; _}; - protocol_data = {contents = {payload_hash; _}; _}; - }; - fitness; - payload_producer; - predecessor_round; - predecessor_level; - _; - } -> - let locked_round = Alpha_context.Fitness.locked_round fitness in - apply_operation_with_mode - (Apply.Application - { - payload_hash; - predecessor_block = predecessor; - predecessor_round; - predecessor_level; - locked_round; - round = Alpha_context.Fitness.round fitness; - }) - ctxt - chain_id - data - op_count - operation - ~payload_producer - | Partial_construction - {predecessor_level; predecessor_round; predecessor_fitness; _} -> - Alpha_context.Fitness.predecessor_round_from_raw predecessor_fitness - >>?= fun grand_parent_round -> - apply_operation_with_mode - (Apply.Partial_construction - {predecessor_round; predecessor_level; grand_parent_round}) - ctxt - chain_id - data - op_count - operation - ~payload_producer:Signature.Public_key_hash.zero - | Full_construction - { - payload_producer; - predecessor; - predecessor_round; - predecessor_level; - protocol_data_contents = {payload_hash; _}; - round; - _; - } -> - apply_operation_with_mode - (Apply.Full_construction - { - payload_hash; - predecessor_block = predecessor; - predecessor_level; - predecessor_round; - round; - }) - ctxt - chain_id - data - op_count - operation - ~payload_producer - -let cache_nonce_from_block_header shell contents = - let open Alpha_context.Block_header in - let shell = - Block_header. - { - level = 0l; - proto_level = 0; - predecessor = shell.predecessor; - timestamp = Time.of_seconds 0L; - validation_passes = 0; - operations_hash = shell.operations_hash; - fitness = []; - context = Context_hash.zero; - } - in - let contents = - { - contents with - payload_hash = Block_payload_hash.zero; - proof_of_work_nonce = - Bytes.make Constants_repr.proof_of_work_nonce_size '0'; - } - in - let protocol_data = {signature = Signature.zero; contents} in - let x = {shell; protocol_data} in - Block_hash.to_bytes (hash x) - -let finalize_block_application ctxt round ~cache_nonce finalize_application_mode - protocol_data payload_producer block_producer liquidity_baking_escape_ema - implicit_operations_results predecessor migration_balance_updates op_count = - Apply.finalize_application - ctxt - finalize_application_mode - protocol_data - ~payload_producer - ~block_producer - liquidity_baking_escape_ema - implicit_operations_results - ~round - ~predecessor - ~migration_balance_updates - >>=? fun (ctxt, fitness, receipt) -> - Alpha_context.Cache.Admin.sync ctxt ~cache_nonce >>= fun ctxt -> - let level = Alpha_context.Level.current ctxt in - let raw_level = Alpha_context.Raw_level.to_int32 level.level in - let commit_message = - Format.asprintf - "lvl %ld, fit:%a, round %a, %d ops" - raw_level - Alpha_context.Fitness.pp - fitness - Alpha_context.Round.pp - round - op_count - in - let validation_result = - Alpha_context.finalize - ~commit_message - ctxt - (Alpha_context.Fitness.to_raw fitness) - in - return (validation_result, receipt) - -type error += Missing_shell_header - -let () = - register_error_kind - `Permanent - ~id:"main.missing_shell_header" - ~title:"Missing shell_header during finalisation of a block" - ~description: - "During finalisation of a block header in Application mode or Full \ - construction mode, a shell header should be provided so that a cache \ - nonce can be computed." - ~pp:(fun ppf () -> - Format.fprintf - ppf - "No shell header provided during the finalisation of a block.") - Data_encoding.unit - (function Missing_shell_header -> Some () | _ -> None) - (fun () -> Missing_shell_header) - -let finalize_block - { - mode; - ctxt; - op_count; - migration_balance_updates; - liquidity_baking_escape_ema; - implicit_operations_results; - _; - } shell_header = - match mode with - | Partial_construction {predecessor_fitness; _} -> - Alpha_context.Voting_period.get_rpc_current_info ctxt - >>=? fun voting_period_info -> - let level_info = Alpha_context.Level.current ctxt in - let fitness = predecessor_fitness in - let ctxt = Alpha_context.finalize ctxt fitness in - return - ( ctxt, - Apply_results. - { - proposer = Signature.Public_key_hash.zero; - baker = Signature.Public_key_hash.zero; - level_info; - voting_period_info; - nonce_hash = None; - consumed_gas = Alpha_context.Gas.Arith.zero; - deactivated = []; - balance_updates = migration_balance_updates; - liquidity_baking_escape_ema; - implicit_operations_results; - } ) - | Partial_application {fitness; block_producer; _} -> - (* For partial application we do not completely check the block validity. - Validating the endorsements is sufficient for a good precheck *) - let level = Alpha_context.Level.current ctxt in - let included_endorsements = - Alpha_context.Consensus.current_endorsement_power ctxt - in - let minimum = Alpha_context.Constants.consensus_threshold ctxt in - Apply.are_endorsements_required ctxt ~level:level.level - >>=? fun endorsements_required -> - (if endorsements_required then - Apply.check_minimum_endorsements - ~endorsing_power:included_endorsements - ~minimum - else return_unit) - >>=? fun () -> - Alpha_context.Voting_period.get_rpc_current_info ctxt - >|=? fun voting_period_info -> - let level_info = Alpha_context.Level.current ctxt in - let ctxt = - Alpha_context.finalize ctxt (Alpha_context.Fitness.to_raw fitness) - in - ( ctxt, - Apply_results. - { - proposer = Signature.Public_key_hash.zero; - (* We cannot retrieve the proposer as it requires the - frozen deposit that might not be available depending on - the context given to the partial application. *) - baker = block_producer; - level_info; - voting_period_info; - nonce_hash = None; - consumed_gas = Alpha_context.Gas.Arith.zero; - deactivated = []; - balance_updates = migration_balance_updates; - liquidity_baking_escape_ema; - implicit_operations_results; - } ) - | Application - { - payload_producer; - fitness; - block_producer; - block_header = {protocol_data = {contents = protocol_data; _}; shell}; - _; - } -> - let round = Alpha_context.Fitness.round fitness in - let cache_nonce = cache_nonce_from_block_header shell protocol_data in - finalize_block_application - ctxt - ~cache_nonce - round - (Finalize_application fitness) - protocol_data - payload_producer - block_producer - liquidity_baking_escape_ema - implicit_operations_results - shell.predecessor - migration_balance_updates - op_count - | Full_construction - { - predecessor; - predecessor_round; - protocol_data_contents; - round; - level; - payload_producer; - block_producer; - _; - } -> - Option.value_e - shell_header - ~error:(Error_monad.trace_of_error Missing_shell_header) - >>?= fun shell_header -> - let cache_nonce = - cache_nonce_from_block_header shell_header protocol_data_contents - in - Alpha_context.Raw_level.of_int32 level >>?= fun level -> - finalize_block_application - ctxt - round - ~cache_nonce - (Finalize_full_construction {level; predecessor_round}) - protocol_data_contents - payload_producer - block_producer - liquidity_baking_escape_ema - implicit_operations_results - predecessor - migration_balance_updates - op_count - -let relative_position_within_block op1 op2 = - let open Alpha_context in - let (Operation_data op1) = op1.protocol_data in - let (Operation_data op2) = op2.protocol_data in - match[@coq_match_with_default] (op1.contents, op2.contents) with - | (Single (Preendorsement _), Single (Preendorsement _)) -> 0 - | (Single (Preendorsement _), _) -> -1 - | (_, Single (Preendorsement _)) -> 1 - | (Single (Endorsement _), Single (Endorsement _)) -> 0 - | (Single (Endorsement _), _) -> -1 - | (_, Single (Endorsement _)) -> 1 - | (Single (Seed_nonce_revelation _), Single (Seed_nonce_revelation _)) -> 0 - | (_, Single (Seed_nonce_revelation _)) -> 1 - | (Single (Seed_nonce_revelation _), _) -> -1 - | ( Single (Double_preendorsement_evidence _), - Single (Double_preendorsement_evidence _) ) -> - 0 - | (_, Single (Double_preendorsement_evidence _)) -> 1 - | (Single (Double_preendorsement_evidence _), _) -> -1 - | ( Single (Double_endorsement_evidence _), - Single (Double_endorsement_evidence _) ) -> - 0 - | (_, Single (Double_endorsement_evidence _)) -> 1 - | (Single (Double_endorsement_evidence _), _) -> -1 - | (Single (Double_baking_evidence _), Single (Double_baking_evidence _)) -> 0 - | (_, Single (Double_baking_evidence _)) -> 1 - | (Single (Double_baking_evidence _), _) -> -1 - | (Single (Activate_account _), Single (Activate_account _)) -> 0 - | (_, Single (Activate_account _)) -> 1 - | (Single (Activate_account _), _) -> -1 - | (Single (Proposals _), Single (Proposals _)) -> 0 - | (_, Single (Proposals _)) -> 1 - | (Single (Proposals _), _) -> -1 - | (Single (Ballot _), Single (Ballot _)) -> 0 - | (_, Single (Ballot _)) -> 1 - | (Single (Ballot _), _) -> -1 - | (Single (Failing_noop _), Single (Failing_noop _)) -> 0 - | (_, Single (Failing_noop _)) -> 1 - | (Single (Failing_noop _), _) -> -1 - (* Manager operations with smaller counter are pre-validated first. *) - | (Single (Manager_operation op1), Single (Manager_operation op2)) -> - Z.compare op1.counter op2.counter - | (Cons (Manager_operation op1, _), Single (Manager_operation op2)) -> - Z.compare op1.counter op2.counter - | (Single (Manager_operation op1), Cons (Manager_operation op2, _)) -> - Z.compare op1.counter op2.counter - | (Cons (Manager_operation op1, _), Cons (Manager_operation op2, _)) -> - Z.compare op1.counter op2.counter - -let init_cache ctxt = - Context.Cache.set_cache_layout ctxt cache_layout >>= fun ctxt -> - Lwt.return (Context.Cache.clear ctxt) - -let init ctxt block_header = - let level = block_header.Block_header.level in - let timestamp = block_header.timestamp in - let typecheck (ctxt : Alpha_context.context) (script : Alpha_context.Script.t) - = - let allow_forged_in_storage = - false - (* There should be no forged value in bootstrap contracts. *) - in - Script_ir_translator.parse_script - ctxt - ~legacy:true - ~allow_forged_in_storage - script - >>=? fun (Ex_script parsed_script, ctxt) -> - Script_ir_translator.extract_lazy_storage_diff - ctxt - Optimized - parsed_script.storage_type - parsed_script.storage - ~to_duplicate:Script_ir_translator.no_lazy_storage_id - ~to_update:Script_ir_translator.no_lazy_storage_id - ~temporary:false - >>=? fun (storage, lazy_storage_diff, ctxt) -> - Script_ir_translator.unparse_data - ctxt - Optimized - parsed_script.storage_type - storage - >|=? fun (storage, ctxt) -> - let storage = - Alpha_context.Script.lazy_expr (Micheline.strip_locations storage) - in - (({script with storage}, lazy_storage_diff), ctxt) - in - (* The cache must be synced at the end of block validation, so we do - so here for the first block in a protocol where `finalize_block` - is not called. *) - Alpha_context.Raw_level.of_int32 level >>?= fun raw_level -> - let init_fitness = - Alpha_context.Fitness.create_without_locked_round - ~level:raw_level - ~round:Alpha_context.Round.zero - ~predecessor_round:Alpha_context.Round.zero - in - init_cache ctxt >>= fun ctxt -> - Alpha_context.prepare_first_block ~typecheck ~level ~timestamp ctxt - >>=? fun ctxt -> - let cache_nonce = - cache_nonce_from_block_header - block_header - { - payload_hash = Block_payload_hash.zero; - payload_round = Alpha_context.Round.zero; - liquidity_baking_escape_vote = false; - seed_nonce_hash = None; - proof_of_work_nonce = - Bytes.make Constants_repr.proof_of_work_nonce_size '0'; - } - in - Alpha_context.Cache.Admin.sync ctxt ~cache_nonce >>= fun ctxt -> - return - (Alpha_context.finalize ctxt (Alpha_context.Fitness.to_raw init_fitness)) - -let value_of_key ~chain_id:_ ~predecessor_context:ctxt ~predecessor_timestamp - ~predecessor_level:pred_level ~predecessor_fitness:_ ~predecessor:_ - ~timestamp = - let level = Int32.succ pred_level in - Alpha_context.prepare ctxt ~level ~predecessor_timestamp ~timestamp - >>=? fun (ctxt, _, _) -> return (Apply.value_of_key ctxt) - -let check_manager_signature {chain_id; ctxt; _} op raw_op = - Apply.check_manager_signature ctxt chain_id op raw_op - -let precheck_manager {ctxt; _} op = - (* We do not account for the gas limit of the batch in the block - since this function does not return a context, but we check that - this limit is within bounds (and fail otherwise with a - permanenent error). *) - Apply.precheck_manager_contents_list ctxt op ~mempool_mode:true - >|=? fun (_ : - Alpha_context.t - * 'kind Alpha_context.Kind.manager - Apply_results.prechecked_contents_list) -> () - -(* Vanity nonce: 0075005294242116 *) diff --git a/src/proto_012_Psithaca/lib_protocol/main.mli b/src/proto_012_Psithaca/lib_protocol/main.mli deleted file mode 100644 index ee6fb2dd6638..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/main.mli +++ /dev/null @@ -1,139 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Tezos Protocol Implementation - Protocol Signature Instance - - This module is the entrypoint to the protocol for shells and other - embedders. This signature is an instance of - {{!Tezos_protocol_environment_sigs.V3.T.Updater.PROTOCOL} the - [Updater.PROTOCOL] signature} from the - {{:https://tezos.gitlab.io/shell/the_big_picture.html#the-economic-protocol-environment-and-compiler} - Protocol Environment}. - - Each Protocol depends on a version of the Protocol Environment. For the - currently developed protocol, this is normally the latest version. You can - see {{!Tezos_protocol_environment_sigs} the full list of versions here}. - - For details on how Protocol and Environment interact, see - {{:https://tezos.gitlab.io/shell/the_big_picture.html} this overview}. - *) - -type validation_mode = - | Application of { - block_header : Alpha_context.Block_header.t; - fitness : Alpha_context.Fitness.t; - payload_producer : Alpha_context.public_key_hash; - block_producer : Alpha_context.public_key_hash; - predecessor_round : Alpha_context.Round.t; - predecessor_level : Alpha_context.Level.t; - } - | Partial_application of { - block_header : Alpha_context.Block_header.t; - fitness : Alpha_context.Fitness.t; - payload_producer : Alpha_context.public_key_hash; - block_producer : Alpha_context.public_key_hash; - predecessor_level : Alpha_context.Level.t; - predecessor_round : Alpha_context.Round.t; - } - (* Mempool only *) - | Partial_construction of { - predecessor : Block_hash.t; - predecessor_fitness : Fitness.t; - predecessor_level : Alpha_context.Level.t; - predecessor_round : Alpha_context.Round.t; - } - (* Baker only *) - | Full_construction of { - predecessor : Block_hash.t; - payload_producer : Alpha_context.public_key_hash; - block_producer : Alpha_context.public_key_hash; - protocol_data_contents : Alpha_context.Block_header.contents; - level : Int32.t; - round : Alpha_context.Round.t; - predecessor_level : Alpha_context.Level.t; - predecessor_round : Alpha_context.Round.t; - } - -type validation_state = { - mode : validation_mode; - chain_id : Chain_id.t; - ctxt : Alpha_context.t; - op_count : int; - migration_balance_updates : Alpha_context.Receipt.balance_updates; - liquidity_baking_escape_ema : Int32.t; - implicit_operations_results : - Apply_results.packed_successful_manager_operation_result list; -} - -type operation_data = Alpha_context.packed_protocol_data - -type operation = Alpha_context.packed_operation = { - shell : Operation.shell_header; - protocol_data : operation_data; -} - -val init_cache : Context.t -> Context.t Lwt.t - -(** [check_manager_signature validation_state op raw_operation] - The function starts by retrieving the public key hash [pkh] of the manager - operation. In case the operation is batched, the function also checks that - the sources are all the same. - Once the [pkh] is retrieved, the function looks for its associated public - key. For that, the manager operation is inspected to check if it contains - a public key revelation. If not, the public key is searched in the context. - - @return [Error Invalid_signature] if the signature check fails - @return [Error Unrevealed_manager_key] if the manager has not yet been - revealed - @return [Error Failure "get_manager_key"] if the key is not found in the - context - @return [Error Inconsistent_sources] if the operations in a batch are not - from the same manager *) -val check_manager_signature : - validation_state -> - 'b Alpha_context.Kind.manager Alpha_context.contents_list -> - 'a Alpha_context.operation -> - unit tzresult Lwt.t - -(** [precheck_manager validation_state op] returns [()] if the manager operation - [op] is solveable, returns an error otherwise. An operation is solveable if - it is well-formed and can pay the fees to be included in a block with either - a success or a failure status. - This function uses [Apply.precheck_manager_contents_list] but discard the - context and balance update *) -val precheck_manager : - validation_state -> - 'a Alpha_context.Kind.manager Alpha_context.contents_list -> - unit tzresult Lwt.t - -include - Updater.PROTOCOL - with type block_header_data = Alpha_context.Block_header.protocol_data - and type block_header_metadata = Apply_results.block_metadata - and type block_header = Alpha_context.Block_header.t - and type operation_data := operation_data - and type operation_receipt = Apply_results.packed_operation_metadata - and type operation := operation - and type validation_state := validation_state diff --git a/src/proto_012_Psithaca/lib_protocol/manager_repr.ml b/src/proto_012_Psithaca/lib_protocol/manager_repr.ml deleted file mode 100644 index b96a51401289..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/manager_repr.ml +++ /dev/null @@ -1,52 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Tezos Protocol Implementation - Low level Repr. of Managers' keys *) - -type manager_key = - | Hash of Signature.Public_key_hash.t - | Public_key of Signature.Public_key.t - -type t = manager_key - -open Data_encoding - -let hash_case tag = - case - tag - ~title:"Public_key_hash" - Signature.Public_key_hash.encoding - (function Hash hash -> Some hash | _ -> None) - (fun hash -> Hash hash) - -let pubkey_case tag = - case - tag - ~title:"Public_key" - Signature.Public_key.encoding - (function Public_key hash -> Some hash | _ -> None) - (fun hash -> Public_key hash) - -let encoding = union [hash_case (Tag 0); pubkey_case (Tag 1)] diff --git a/src/proto_012_Psithaca/lib_protocol/manager_repr.mli b/src/proto_012_Psithaca/lib_protocol/manager_repr.mli deleted file mode 100644 index 18ca236d71b1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/manager_repr.mli +++ /dev/null @@ -1,38 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Tezos Protocol Implementation - Low level Repr. of Managers' keys *) - -(** The public key of the manager of a contract is reveled only after the - first operation. At Origination time, the manager provides only the hash - of its public key that is stored in the contract. When the public key - is actually revealed, the public key instead of the hash of the key *) -type manager_key = - | Hash of Signature.Public_key_hash.t - | Public_key of Signature.Public_key.t - -type t = manager_key - -val encoding : t Data_encoding.encoding diff --git a/src/proto_012_Psithaca/lib_protocol/michelson_v1_gas.ml b/src/proto_012_Psithaca/lib_protocol/michelson_v1_gas.ml deleted file mode 100644 index b3175d63a615..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/michelson_v1_gas.ml +++ /dev/null @@ -1,1809 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Gas -module S = Saturation_repr - -module Cost_of = struct - module S_syntax = struct - (* This is a good enough approximation. S.numbits 0 = 0 *) - let log2 x = S.safe_int (1 + S.numbits x) - - let ( + ) = S.add - - let ( * ) = S.mul - - let ( lsr ) = S.shift_right - end - - let z_bytes (z : Z.t) = - let bits = Z.numbits z in - (7 + bits) / 8 - - let int_bytes (z : 'a Script_int.num) = z_bytes (Script_int.to_zint z) - - let manager_operation = step_cost @@ S.safe_int 1_000 - - module Generated_costs = struct - (* Automatically generated costs functions. *) - - (* model N_IAbs_int *) - (* Approximating 0.065045 x term *) - let cost_N_IAbs_int size = S.safe_int (25 + (size lsr 4)) - - (* model N_IAdd_bls12_381_fr *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IAdd_bls12_381_fr = S.safe_int 45 - - (* model N_IAdd_bls12_381_g1 *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IAdd_bls12_381_g1 = S.safe_int 925 - - (* model N_IAdd_bls12_381_g2 *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IAdd_bls12_381_g2 = S.safe_int 2_520 - - let cost_linear_op_int size1 size2 = - let open S_syntax in - let v0 = S.safe_int (Compare.Int.max size1 size2) in - S.safe_int 55 + ((v0 lsr 4) + (v0 lsr 7)) - - (* model N_IAdd_int *) - (* Approximating 0.078154 x term *) - let cost_N_IAdd_int = cost_linear_op_int - - (* model N_IAdd_nat *) - (* Approximating 0.077807 x term *) - let cost_N_IAdd_nat = cost_linear_op_int - - (* model N_IAdd_seconds_to_timestamp *) - (* Approximating 0.078056 x term *) - let cost_N_IAdd_seconds_to_timestamp = cost_linear_op_int - - (* model N_IAdd_tez *) - let cost_N_IAdd_tez = S.safe_int 20 - - (* model N_IAdd_timestamp_to_seconds *) - (* Approximating 0.077771 x term *) - let cost_N_IAdd_timestamp_to_seconds = cost_linear_op_int - - (* model N_IAddress *) - let cost_N_IAddress = S.safe_int 10 - - (* model N_IAmount *) - let cost_N_IAmount = S.safe_int 15 - - (* model N_IAnd *) - let cost_N_IAnd = S.safe_int 20 - - (* model N_IAnd_int_nat *) - (* Approximating 0.076804 x 2 x term *) - let cost_N_IAnd_int_nat size1 size2 = - let open S_syntax in - let v0 = S.safe_int (Compare.Int.min size1 size2) in - S.safe_int 50 + ((v0 lsr 3) + (v0 lsr 6)) - - (* model N_IAnd_nat *) - (* Approximating 0.076804 x term *) - (* The difference with `cost_N_IAnd_int_nat` comes from Zarith, where the - complexity of `Z.logand` depends on the sign of the argument. *) - let cost_N_IAnd_nat size1 size2 = - let open S_syntax in - let v0 = S.safe_int (Compare.Int.min size1 size2) in - S.safe_int 50 + ((v0 lsr 4) + (v0 lsr 7)) - - (* model N_IApply *) - let cost_N_IApply = S.safe_int 160 - - (* model N_IBlake2b *) - (* Approximating 1.120804 x term *) - let cost_N_IBlake2b size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 430 + v0 + (v0 lsr 3) - - (* model N_IBytes_size *) - let cost_N_IBytes_size = S.safe_int 15 - - (* model N_ICar *) - let cost_N_ICar = S.safe_int 10 - - (* model N_ICdr *) - let cost_N_ICdr = S.safe_int 10 - - (* model N_IChainId *) - let cost_N_IChainId = S.safe_int 15 - - (* model N_ICheck_signature_ed25519 *) - (* Approximating 1.123507 x term *) - let cost_N_ICheck_signature_ed25519 size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 65_800 + (v0 + (v0 lsr 3)) - - (* model N_ICheck_signature_p256 *) - (* Approximating 1.111539 x term *) - let cost_N_ICheck_signature_p256 size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 990_000 + (v0 + (v0 lsr 3)) - - (* model N_ICheck_signature_secp256k1 *) - (* Approximating 1.125404 x term *) - let cost_N_ICheck_signature_secp256k1 size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 51_600 + (v0 + (v0 lsr 3)) - - (* model N_IComb *) - (* Approximating 3.531001 x term *) - (* Note: size >= 2, so the cost is never 0 *) - let cost_N_IComb size = - let open S_syntax in - let v0 = S.safe_int size in - (S.safe_int 3 * v0) + (v0 lsr 1) + (v0 lsr 5) - - (* model N_IComb_get *) - (* Approximating 0.573180 x term *) - let cost_N_IComb_get size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 30 + (v0 lsr 1) + (v0 lsr 4) - - (* model N_IComb_set *) - (* Approximating 1.287531 x term *) - let cost_N_IComb_set size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 40 + (v0 + (v0 lsr 2) + (v0 lsr 5)) - - (* Model N_ICompare *) - (* Approximating 0.024413 x term *) - let cost_N_ICompare size1 size2 = - let open S_syntax in - let v0 = S.safe_int (Compare.Int.min size1 size2) in - S.safe_int 35 + ((v0 lsr 6) + (v0 lsr 7)) - - (* model N_IConcat_bytes_pair *) - (* Approximating 0.065017 x term *) - let cost_N_IConcat_bytes_pair size1 size2 = - let open S_syntax in - let v0 = S.safe_int size1 + S.safe_int size2 in - S.safe_int 65 + (v0 lsr 4) - - (* model N_IConcat_string_pair *) - (* Approximating 0.061402 x term *) - let cost_N_IConcat_string_pair size1 size2 = - let open S_syntax in - let v0 = S.safe_int size1 + S.safe_int size2 in - S.safe_int 65 + (v0 lsr 4) - - (* model N_ICons_list *) - let cost_N_ICons_list = S.safe_int 15 - - (* model N_ICons_none *) - let cost_N_ICons_none = S.safe_int 15 - - (* model N_ICons_pair *) - let cost_N_ICons_pair = S.safe_int 15 - - (* model N_ICons_some *) - let cost_N_ICons_some = S.safe_int 15 - - (* model N_IConst *) - let cost_N_IConst = S.safe_int 10 - - (* model N_IContract *) - let cost_N_IContract = S.safe_int 30 - - (* model N_ICreate_contract *) - let cost_N_ICreate_contract = S.safe_int 30 - - (* model N_IDiff_timestamps *) - (* Approximating 0.077922 x term *) - let cost_N_IDiff_timestamps = cost_linear_op_int - - (* model N_IDig *) - (* Approximating 6.750442 x term *) - let cost_N_IDig size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 60 + ((S.safe_int 6 * v0) + (v0 lsr 1) + (v0 lsr 2)) - - (* model N_IDip *) - let cost_N_IDip = S.safe_int 15 - - (* model N_IDipN *) - (* Approximating 1.708122 x term *) - let cost_N_IDipN size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 45 + (v0 + (v0 lsr 1) + (v0 lsr 3)) - - (* model N_IView *) - let cost_N_IView = S.safe_int 1460 - - (* model N_IDrop *) - let cost_N_IDrop = S.safe_int 10 - - (* model N_IDropN *) - (* Approximating 2.713108 x term *) - let cost_N_IDropN size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 60 + (S.safe_int 2 * v0) + (v0 lsr 1) + (v0 lsr 3) - - (* model N_IDug *) - (* Approximating 6.718396 x term *) - let cost_N_IDug size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 60 + ((S.safe_int 6 * v0) + (v0 lsr 1) + (v0 lsr 2)) - - (* model N_IDup *) - let cost_N_IDup = S.safe_int 10 - - (* model N_IDupN *) - (* Approximating 1.129785 x term *) - let cost_N_IDupN size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 20 + v0 + (v0 lsr 3) - - let cost_div_int size1 size2 = - let q = size1 - size2 in - if Compare.Int.(q < 0) then S.safe_int 140 - else - let open S_syntax in - let v0 = S.safe_int q * S.safe_int size2 in - S.safe_int 140 + (v0 lsr 10) + (v0 lsr 11) + (v0 lsr 13) - - (* model N_IEdiv_int *) - (* Approximating 0.001591 x term *) - let cost_N_IEdiv_int = cost_div_int - - (* model N_IEdiv_nat *) - (* Approximating 0.001605 x term *) - let cost_N_IEdiv_nat = cost_div_int - - (* model N_IEdiv_tez *) - let cost_N_IEdiv_tez = S.safe_int 140 - - (* model N_IEdiv_teznat *) - let cost_N_IEdiv_teznat = S.safe_int 140 - - (* model N_IEmpty_big_map *) - let cost_N_IEmpty_big_map = S.safe_int 15 - - (* model N_IEmpty_map *) - let cost_N_IEmpty_map = S.safe_int 220 - - (* model N_IEmpty_set *) - let cost_N_IEmpty_set = S.safe_int 220 - - (* model N_IEq *) - let cost_N_IEq = S.safe_int 15 - - (* model N_IExec *) - let cost_N_IExec = S.safe_int 15 - - (* model N_IFailwith *) - (* let cost_N_IFailwith = S.safe_int 105 *) - - (* model N_IGe *) - let cost_N_IGe = S.safe_int 15 - - (* model N_IGt *) - let cost_N_IGt = S.safe_int 15 - - (* model N_IHalt *) - let cost_N_IHalt = S.safe_int 15 - - (* model N_IHash_key *) - let cost_N_IHash_key = S.safe_int 655 - - (* model N_IIf *) - let cost_N_IIf = S.safe_int 10 - - (* model N_IIf_cons *) - let cost_N_IIf_cons = S.safe_int 10 - - (* model N_IIf_left *) - let cost_N_IIf_left = S.safe_int 10 - - (* model N_IIf_none *) - let cost_N_IIf_none = S.safe_int 10 - - (* model N_IOpt_map *) - let cost_opt_map = S.safe_int 15 - - (* model N_IImplicit_account *) - let cost_N_IImplicit_account = S.safe_int 10 - - (* model N_IInt_bls12_381_z_fr *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IInt_bls12_381_z_fr = S.safe_int 125 - - (* model N_IInt_nat *) - let cost_N_IInt_nat = S.safe_int 15 - - (* model N_IIs_nat *) - let cost_N_IIs_nat = S.safe_int 15 - - (* model N_IKeccak *) - (* Approximating 8.276352 x term *) - let cost_N_IKeccak size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 1350 + ((S.safe_int 8 * v0) + (v0 lsr 2)) - - (* model N_ILambda *) - let cost_N_ILambda = S.safe_int 10 - - (* model N_ILe *) - let cost_N_ILe = S.safe_int 15 - - (* model N_ILeft *) - let cost_N_ILeft = S.safe_int 15 - - (* model N_ILevel *) - let cost_N_ILevel = S.safe_int 15 - - (* model N_IList_iter *) - let cost_N_IList_iter _ = S.safe_int 25 - - (* model N_IList_map *) - let cost_N_IList_map _ = S.safe_int 25 - - (* model N_IList_size *) - let cost_N_IList_size = S.safe_int 15 - - (* model N_ILoop *) - let cost_N_ILoop = S.safe_int 10 - - (* model N_ILoop_left *) - let cost_N_ILoop_left = S.safe_int 10 - - (* model N_ILsl_nat *) - (* Approximating 0.115642 x term *) - let cost_N_ILsl_nat size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 60 + ((v0 lsr 4) + (v0 lsr 5) + (v0 lsr 6)) - - (* model N_ILsr_nat *) - (* Approximating 0.115565 x term *) - let cost_N_ILsr_nat size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 60 + ((v0 lsr 4) + (v0 lsr 5) + (v0 lsr 6)) - - (* model N_ILt *) - let cost_N_ILt = S.safe_int 15 - - (* model N_IMap_get *) - (* Approximating 0.048359 x term *) - let cost_N_IMap_get size1 size2 = - let open S_syntax in - let v0 = size1 * log2 size2 in - S.safe_int 110 + (v0 lsr 5) + (v0 lsr 6) - - (* model N_IMap_get_and_update *) - (* Approximating 0.145661 x term *) - let cost_N_IMap_get_and_update size1 size2 = - let open S_syntax in - let v0 = size1 * log2 size2 in - S.safe_int 135 + (v0 lsr 3) + (v0 lsr 6) - - (* model N_IMap_iter *) - (* Approximating 7.621331 x term *) - let cost_N_IMap_iter size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 70 + (S.safe_int 7 * v0) + (v0 lsr 1) + (v0 lsr 3) - - (* model N_IMap_map *) - (* Approximating 7.46280485884 x term *) - let cost_N_IMap_map size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 265 + ((S.safe_int 7 * v0) + (v0 lsr 1)) - - (* model N_IMap_mem *) - (* Approximating 0.048446 x term *) - let cost_N_IMap_mem size1 size2 = - let open S_syntax in - let v0 = size1 * log2 size2 in - S.safe_int 110 + (v0 lsr 5) + (v0 lsr 6) - - (* model N_IMap_size *) - let cost_N_IMap_size = S.safe_int 15 - - (* model N_IMap_update *) - (* Approximating 0.097072 x term *) - let cost_N_IMap_update size1 size2 = - let open S_syntax in - let v0 = size1 * log2 size2 in - S.safe_int 130 + (v0 lsr 4) + (v0 lsr 5) - - (* model N_IMul_bls12_381_fr *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IMul_bls12_381_fr = S.safe_int 65 - - (* model N_IMul_bls12_381_fr_z *) - (* Approximating 1.059386 x term *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IMul_bls12_381_fr_z size1 = - let open S_syntax in - let v0 = S.safe_int size1 in - S.safe_int 330 + v0 + (v0 lsr 4) - - (* model N_IMul_bls12_381_g1 *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IMul_bls12_381_g1 = S.safe_int 103_000 - - (* model N_IMul_bls12_381_g2 *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IMul_bls12_381_g2 = S.safe_int 220_000 - - (* model N_IMul_bls12_381_z_fr *) - (* Approximating 1.068674 x term *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IMul_bls12_381_z_fr size1 = - let open S_syntax in - let v0 = S.safe_int size1 in - S.safe_int 330 + v0 + (v0 lsr 4) - - let cost_mul size1 size2 = - let open S_syntax in - let a = S.add (S.safe_int size1) (S.safe_int size2) in - let v0 = a * log2 a in - S.safe_int 100 + (v0 lsr 1) + (v0 lsr 2) + (v0 lsr 4) - - (* model N_IMul_int *) - (* Approximating 0.857931 x term *) - let cost_N_IMul_int = cost_mul - - (* model N_IMul_nat *) - (* Approximating 0.861823 x term *) - let cost_N_IMul_nat = cost_mul - - (* model N_IMul_nattez *) - let cost_N_IMul_nattez = S.safe_int 50 - - (* model N_IMul_teznat *) - let cost_N_IMul_teznat = S.safe_int 50 - - (* model N_INeg_bls12_381_fr *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_INeg_bls12_381_fr = S.safe_int 45 - - (* model N_INeg_bls12_381_g1 *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_INeg_bls12_381_g1 = S.safe_int 60 - - (* model N_INeg_bls12_381_g2 *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_INeg_bls12_381_g2 = S.safe_int 85 - - (* model N_INeg *) - (* Approximating 0.066076 x term *) - let cost_N_INeg size = - let open S_syntax in - S.safe_int 40 + (S.safe_int size lsr 4) - - (* model N_INeq *) - let cost_N_INeq = S.safe_int 15 - - (* model N_INil *) - let cost_N_INil = S.safe_int 15 - - (* model N_INot *) - let cost_N_INot = S.safe_int 10 - - (* model N_INot_int *) - (* Approximating 0.075541 x term *) - let cost_N_INot_int size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 50 + ((v0 lsr 4) + (v0 lsr 7)) - - (* model N_INow *) - let cost_N_INow = S.safe_int 15 - - (* model N_IOpen_chest *) - (* 612000 + chest * 19 + time * 19050 *) - let cost_N_IOpen_chest ~chest ~time = - let open S_syntax in - let v0 = S.safe_int chest in - let v1 = S.safe_int time in - S.safe_int 612_000 + (S.safe_int 19 * v0) + (S.safe_int 19050 * v1) - - (* model N_IOr *) - let cost_N_IOr = S.safe_int 15 - - (* model N_IOr_nat *) - (* Approximating 0.075758 x term *) - let cost_N_IOr_nat = cost_linear_op_int - - (* model N_IPairing_check_bls12_381 *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_N_IPairing_check_bls12_381 size = - S.add (S.safe_int 450_000) (S.mul (S.safe_int 342_500) (S.safe_int size)) - - (* model N_IRead_ticket *) - let cost_N_IRead_ticket = S.safe_int 15 - - (* model N_IRight *) - let cost_N_IRight = S.safe_int 15 - - (* model N_ISapling_empty_state *) - let cost_N_ISapling_empty_state = S.safe_int 15 - - (* model N_ISapling_verify_update *) - (* Approximating 1.27167 x term *) - (* Approximating 38.72115 x term *) - let cost_N_ISapling_verify_update size1 size2 = - let open S_syntax in - let v1 = S.safe_int size1 in - let v0 = S.safe_int size2 in - S.safe_int 84_050 + (v1 + (v1 lsr 2)) + (S.safe_int 39 * v0) - - (* model N_ISelf_address *) - let cost_N_ISelf_address = S.safe_int 15 - - (* model N_ISelf *) - let cost_N_ISelf = S.safe_int 15 - - (* model N_ISender *) - let cost_N_ISender = S.safe_int 15 - - (* model N_ISet_delegate *) - let cost_N_ISet_delegate = S.safe_int 40 - - (* model N_ISet_iter *) - (* Approximating 7.633555 x term *) - let cost_N_ISet_iter size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 70 + (S.safe_int 7 * v0) + (v0 lsr 1) + (v0 lsr 3) - - (* model N_ISet_size *) - let cost_N_ISet_size = S.safe_int 15 - - (* model N_ISha256 *) - (* Approximating 4.763264 x term *) - let cost_N_ISha256 size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 600 + ((S.safe_int 4 * v0) + (v0 lsr 1) + (v0 lsr 2)) - - (* model N_ISha3 *) - (* Approximating 8.362339 x term *) - let cost_N_ISha3 = cost_N_IKeccak - - (* model N_ISha512 *) - (* Approximating 3.074641 x term *) - let cost_N_ISha512 size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 680 + (S.safe_int 3 * v0) - - (* model N_ISlice_bytes *) - (* Approximating 0.065752 x term *) - let cost_N_ISlice_bytes size = - let open S_syntax in - S.safe_int 40 + (S.safe_int size lsr 4) - - (* model N_ISlice_string *) - (* Approximating 0.065688 x term *) - let cost_N_ISlice_string size = - let open S_syntax in - S.safe_int 40 + (S.safe_int size lsr 4) - - (* model N_ISource *) - let cost_N_ISource = S.safe_int 15 - - (* model N_ISplit_ticket *) - (* Approximating 0.132362 x term *) - let cost_N_ISplit_ticket size1 size2 = - let open S_syntax in - let v1 = S.safe_int (Compare.Int.max size1 size2) in - S.safe_int 55 + (v1 lsr 3) - - (* model N_IString_size *) - let cost_N_IString_size = S.safe_int 15 - - (* model N_ISub_int *) - (* Approximating 0.077849 x term *) - let cost_N_ISub_int = cost_linear_op_int - - (* model N_ISub_tez *) - let cost_N_ISub_tez = S.safe_int 20 - - (* model N_ISub_tez_legacy *) - let cost_N_ISub_tez_legacy = S.safe_int 20 - - (* model N_ISub_timestamp_seconds *) - (* Approximating 0.077794 x term *) - let cost_N_ISub_timestamp_seconds = cost_linear_op_int - - (* model N_ISwap *) - let cost_N_ISwap = S.safe_int 10 - - (* model N_ITicket *) - let cost_N_ITicket = S.safe_int 15 - - (* model N_ITotal_voting_power *) - let cost_N_ITotal_voting_power = S.safe_int 370 - - (* model N_ITransfer_tokens *) - let cost_N_ITransfer_tokens = S.safe_int 30 - - (* model N_IUncomb *) - (* Approximating 3.944710 x term *) - let cost_N_IUncomb size = - let open S_syntax in - let v0 = S.safe_int size in - S.safe_int 25 + (S.safe_int 4 * v0) - - (* model N_IUnpair *) - let cost_N_IUnpair = S.safe_int 10 - - (* model N_IVoting_power *) - let cost_N_IVoting_power = S.safe_int 530 - - (* model N_IXor *) - let cost_N_IXor = S.safe_int 20 - - (* model N_IXor_nat *) - (* Approximating 0.075601 x term *) - let cost_N_IXor_nat = cost_linear_op_int - - (* model N_KCons *) - let cost_N_KCons = S.safe_int 15 - - (* model N_KIter *) - let cost_N_KIter = S.safe_int 20 - - (* model N_KList_enter_body *) - (* Approximating 1.672196 x term *) - let cost_N_KList_enter_body xs size_ys = - match xs with - | [] -> - let open S_syntax in - let v0 = S.safe_int size_ys in - S.safe_int 40 + (v0 + (v0 lsr 1) + (v0 lsr 3)) - | _ :: _ -> S.safe_int 70 - - (* model N_KList_exit_body *) - let cost_N_KList_exit_body = S.safe_int 30 - - (* model N_KLoop_in *) - let cost_N_KLoop_in = S.safe_int 15 - - (* model N_KLoop_in_left *) - let cost_N_KLoop_in_left = S.safe_int 15 - - (* model N_KMap_enter_body *) - let cost_N_KMap_enter_body = S.safe_int 165 - - (* model N_KNil *) - let cost_N_KNil = S.safe_int 20 - - (* model N_KReturn *) - let cost_N_KReturn = S.safe_int 15 - - (* model N_KView_exit *) - let cost_N_KView_exit = S.safe_int 20 - - (* model N_KMap_head *) - let const_N_KMap_head = S.safe_int 20 - - (* model N_KUndip *) - let cost_N_KUndip = S.safe_int 15 - - (* model DECODING_BLS_FR *) - (* when benchmarking, compile bls12-381-unix without ADX, see - https://gitlab.com/dannywillems/ocaml-bls12-381/-/blob/71d0b4d467fbfaa6452d702fcc408d7a70916a80/README.md#install - *) - let cost_DECODING_BLS_FR = S.safe_int 150 - - (* model DECODING_BLS_G1 *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_DECODING_BLS_G1 = S.safe_int 65_300 - - (* model DECODING_BLS_G2 *) - (* when benchmarking, compile bls12-381-unix without ADX *) - let cost_DECODING_BLS_G2 = S.safe_int 73_300 - - (* model B58CHECK_DECODING_CHAIN_ID *) - let cost_B58CHECK_DECODING_CHAIN_ID = S.safe_int 1_600 - - (* model B58CHECK_DECODING_PUBLIC_KEY_HASH_ed25519 *) - let cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 3_300 - - (* model B58CHECK_DECODING_PUBLIC_KEY_HASH_p256 *) - let cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_p256 = S.safe_int 3_300 - - (* model B58CHECK_DECODING_PUBLIC_KEY_HASH_secp256k1 *) - let cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 3_300 - - (* model B58CHECK_DECODING_PUBLIC_KEY_ed25519 *) - let cost_B58CHECK_DECODING_PUBLIC_KEY_ed25519 = S.safe_int 4_200 - - (* model B58CHECK_DECODING_PUBLIC_KEY_p256 *) - let cost_B58CHECK_DECODING_PUBLIC_KEY_p256 = S.safe_int 325_000 - - (* model B58CHECK_DECODING_PUBLIC_KEY_secp256k1 *) - let cost_B58CHECK_DECODING_PUBLIC_KEY_secp256k1 = S.safe_int 9_000 - - (* model B58CHECK_DECODING_SIGNATURE_ed25519 *) - let cost_B58CHECK_DECODING_SIGNATURE_ed25519 = S.safe_int 6_400 - - (* model B58CHECK_DECODING_SIGNATURE_p256 *) - let cost_B58CHECK_DECODING_SIGNATURE_p256 = S.safe_int 6_400 - - (* model B58CHECK_DECODING_SIGNATURE_secp256k1 *) - let cost_B58CHECK_DECODING_SIGNATURE_secp256k1 = S.safe_int 6_400 - - (* model ENCODING_BLS_FR *) - let cost_ENCODING_BLS_FR = S.safe_int 80 - - (* model ENCODING_BLS_G1 *) - let cost_ENCODING_BLS_G1 = S.safe_int 3200 - - (* model ENCODING_BLS_G2 *) - let cost_ENCODING_BLS_G2 = S.safe_int 3900 - - (* model B58CHECK_ENCODING_CHAIN_ID *) - let cost_B58CHECK_ENCODING_CHAIN_ID = S.safe_int 1_800 - - (* model B58CHECK_ENCODING_PUBLIC_KEY_HASH_ed25519 *) - let cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 3_200 - - (* model B58CHECK_ENCODING_PUBLIC_KEY_HASH_p256 *) - let cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_p256 = S.safe_int 3_200 - - (* model B58CHECK_ENCODING_PUBLIC_KEY_HASH_secp256k1 *) - let cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 3_200 - - (* model B58CHECK_ENCODING_PUBLIC_KEY_ed25519 *) - let cost_B58CHECK_ENCODING_PUBLIC_KEY_ed25519 = S.safe_int 4_500 - - (* model B58CHECK_ENCODING_PUBLIC_KEY_p256 *) - let cost_B58CHECK_ENCODING_PUBLIC_KEY_p256 = S.safe_int 4_550 - - (* model B58CHECK_ENCODING_PUBLIC_KEY_secp256k1 *) - let cost_B58CHECK_ENCODING_PUBLIC_KEY_secp256k1 = S.safe_int 4_950 - - (* model B58CHECK_ENCODING_SIGNATURE_ed25519 *) - let cost_B58CHECK_ENCODING_SIGNATURE_ed25519 = S.safe_int 8_300 - - (* model B58CHECK_ENCODING_SIGNATURE_p256 *) - let cost_B58CHECK_ENCODING_SIGNATURE_p256 = S.safe_int 8_300 - - (* model B58CHECK_ENCODING_SIGNATURE_secp256k1 *) - let cost_B58CHECK_ENCODING_SIGNATURE_secp256k1 = S.safe_int 8_300 - - (* model DECODING_CHAIN_ID *) - let cost_DECODING_CHAIN_ID = S.safe_int 50 - - (* model DECODING_PUBLIC_KEY_HASH_ed25519 *) - let cost_DECODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 50 - - (* model DECODING_PUBLIC_KEY_HASH_p256 *) - let cost_DECODING_PUBLIC_KEY_HASH_p256 = S.safe_int 50 - - (* model DECODING_PUBLIC_KEY_HASH_secp256k1 *) - let cost_DECODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 50 - - (* model DECODING_PUBLIC_KEY_ed25519 *) - let cost_DECODING_PUBLIC_KEY_ed25519 = S.safe_int 60 - - (* model DECODING_PUBLIC_KEY_p256 *) - let cost_DECODING_PUBLIC_KEY_p256 = S.safe_int 320_000 - - (* model DECODING_PUBLIC_KEY_secp256k1 *) - let cost_DECODING_PUBLIC_KEY_secp256k1 = S.safe_int 4_900 - - (* model DECODING_SIGNATURE_ed25519 *) - let cost_DECODING_SIGNATURE_ed25519 = S.safe_int 35 - - (* model DECODING_SIGNATURE_p256 *) - let cost_DECODING_SIGNATURE_p256 = S.safe_int 35 - - (* model DECODING_SIGNATURE_secp256k1 *) - let cost_DECODING_SIGNATURE_secp256k1 = S.safe_int 35 - - (* model DECODING_Chest_key *) - let cost_DECODING_Chest_key = S.safe_int 5900 - - (* model DECODING_Chest *) - (* Approximating 0.039349 x term *) - let cost_DECODING_Chest ~bytes = - let open S_syntax in - let v0 = S.safe_int bytes in - S.safe_int 7400 + (v0 lsr 5) + (v0 lsr 7) - - (* model ENCODING_CHAIN_ID *) - let cost_ENCODING_CHAIN_ID = S.safe_int 50 - - (* model ENCODING_PUBLIC_KEY_HASH_ed25519 *) - let cost_ENCODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 70 - - (* model ENCODING_PUBLIC_KEY_HASH_p256 *) - let cost_ENCODING_PUBLIC_KEY_HASH_p256 = S.safe_int 70 - - (* model ENCODING_PUBLIC_KEY_HASH_secp256k1 *) - let cost_ENCODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 70 - - (* model ENCODING_PUBLIC_KEY_ed25519 *) - let cost_ENCODING_PUBLIC_KEY_ed25519 = S.safe_int 80 - - (* model ENCODING_PUBLIC_KEY_p256 *) - let cost_ENCODING_PUBLIC_KEY_p256 = S.safe_int 90 - - (* model ENCODING_PUBLIC_KEY_secp256k1 *) - let cost_ENCODING_PUBLIC_KEY_secp256k1 = S.safe_int 455 - - (* model ENCODING_SIGNATURE_ed25519 *) - let cost_ENCODING_SIGNATURE_ed25519 = S.safe_int 45 - - (* model ENCODING_SIGNATURE_p256 *) - let cost_ENCODING_SIGNATURE_p256 = S.safe_int 45 - - (* model ENCODING_SIGNATURE_secp256k1 *) - let cost_ENCODING_SIGNATURE_secp256k1 = S.safe_int 45 - - (* model ENCODING_Chest_key *) - let cost_ENCODING_Chest_key = S.safe_int 13500 - - (* model ENCODING_Chest *) - (* Approximating 0.120086 x term *) - let cost_ENCODING_Chest ~plaintext_size = - let open S_syntax in - let v0 = S.safe_int plaintext_size in - S.safe_int 16630 + (v0 lsr 3) - - (* model TIMESTAMP_READABLE_DECODING *) - let cost_TIMESTAMP_READABLE_DECODING = S.safe_int 100 - - (* model TIMESTAMP_READABLE_ENCODING *) - let cost_TIMESTAMP_READABLE_ENCODING = S.safe_int 820 - - (* model CHECK_PRINTABLE *) - let cost_CHECK_PRINTABLE size = - let open S_syntax in - S.safe_int 14 + (S.safe_int 10 * S.safe_int size) - - (* model MERGE_TYPES - This is the estimated cost of one iteration of merge_types, extracted - and copied manually from the parameter fit for the MERGE_TYPES benchmark - (the model is parametric on the size of the type, which we don't have - access to in O(1)). *) - let cost_MERGE_TYPES = S.safe_int 220 - - (* model TYPECHECKING_CODE - This is the cost of one iteration of parse_instr, extracted by hand from the - parameter fit for the TYPECHECKING_CODE benchmark. *) - let cost_TYPECHECKING_CODE = S.safe_int 220 - - (* model UNPARSING_CODE - This is the cost of one iteration of unparse_instr, extracted by hand from the - parameter fit for the UNPARSING_CODE benchmark. *) - let cost_UNPARSING_CODE = S.safe_int 115 - - (* model TYPECHECKING_DATA - This is the cost of one iteration of parse_data, extracted by hand from the - parameter fit for the TYPECHECKING_DATA benchmark. *) - let cost_TYPECHECKING_DATA = S.safe_int 100 - - (* model UNPARSING_DATA - This is the cost of one iteration of unparse_data, extracted by hand from the - parameter fit for the UNPARSING_DATA benchmark. *) - let cost_UNPARSING_DATA = S.safe_int 45 - - (* model PARSE_TYPE - This is the cost of one iteration of parse_ty, extracted by hand from the - parameter fit for the PARSE_TYPE benchmark. *) - let cost_PARSE_TYPE = S.safe_int 60 - - (* model UNPARSE_TYPE - This is the cost of one iteration of unparse_ty, extracted by hand from the - parameter fit for the UNPARSE_TYPE benchmark. *) - let cost_UNPARSE_TYPE type_size = S.mul (S.safe_int 20) type_size - - (* TODO: Add benchmarked value from [Unparse_comparable_type_benchmark]. *) - let cost_UNPARSE_COMPARABLE_TYPE type_size = S.mul (S.safe_int 20) type_size - - (* TODO: benchmark *) - let cost_COMPARABLE_TY_OF_TY = S.safe_int 120 - - (* model SAPLING_TRANSACTION_ENCODING *) - let cost_SAPLING_TRANSACTION_ENCODING ~inputs ~outputs = - S.safe_int (1500 + (inputs * 160) + (outputs * 320)) - - (* model SAPLING_DIFF_ENCODING *) - let cost_SAPLING_DIFF_ENCODING ~nfs ~cms = - S.safe_int ((nfs * 22) + (cms * 215)) - end - - module Interpreter = struct - open Generated_costs - - let drop = atomic_step_cost cost_N_IDrop - - let dup = atomic_step_cost cost_N_IDup - - let swap = atomic_step_cost cost_N_ISwap - - let cons_some = atomic_step_cost cost_N_ICons_some - - let cons_none = atomic_step_cost cost_N_ICons_none - - let if_none = atomic_step_cost cost_N_IIf_none - - let opt_map = atomic_step_cost cost_opt_map - - let cons_pair = atomic_step_cost cost_N_ICons_pair - - let unpair = atomic_step_cost cost_N_IUnpair - - let car = atomic_step_cost cost_N_ICar - - let cdr = atomic_step_cost cost_N_ICdr - - let cons_left = atomic_step_cost cost_N_ILeft - - let cons_right = atomic_step_cost cost_N_IRight - - let if_left = atomic_step_cost cost_N_IIf_left - - let cons_list = atomic_step_cost cost_N_ICons_list - - let nil = atomic_step_cost cost_N_INil - - let if_cons = atomic_step_cost cost_N_IIf_cons - - let list_map : 'a Script_typed_ir.boxed_list -> Gas.cost = - fun {length; _} -> atomic_step_cost (cost_N_IList_map length) - - let list_size = atomic_step_cost cost_N_IList_size - - let list_iter : 'a Script_typed_ir.boxed_list -> Gas.cost = - fun {length; _} -> atomic_step_cost (cost_N_IList_iter length) - - let empty_set = atomic_step_cost cost_N_IEmpty_set - - let set_iter (type a) ((module Box) : a Script_typed_ir.set) = - atomic_step_cost (cost_N_ISet_iter Box.size) - - let set_size = atomic_step_cost cost_N_ISet_size - - let empty_map = atomic_step_cost cost_N_IEmpty_map - - let map_map (type k v) ((module Box) : (k, v) Script_typed_ir.map) = - atomic_step_cost (cost_N_IMap_map Box.size) - - let map_iter (type k v) ((module Box) : (k, v) Script_typed_ir.map) = - atomic_step_cost (cost_N_IMap_iter Box.size) - - let map_size = atomic_step_cost cost_N_IMap_size - - let big_map_elt_size = S.safe_int Script_expr_hash.size - - let big_map_mem ({size; _} : _ Script_typed_ir.big_map_overlay) = - atomic_step_cost (cost_N_IMap_mem big_map_elt_size (S.safe_int size)) - - let big_map_get ({size; _} : _ Script_typed_ir.big_map_overlay) = - atomic_step_cost (cost_N_IMap_get big_map_elt_size (S.safe_int size)) - - let big_map_update ({size; _} : _ Script_typed_ir.big_map_overlay) = - atomic_step_cost (cost_N_IMap_update big_map_elt_size (S.safe_int size)) - - let big_map_get_and_update ({size; _} : _ Script_typed_ir.big_map_overlay) = - atomic_step_cost - (cost_N_IMap_get_and_update big_map_elt_size (S.safe_int size)) - - let add_seconds_timestamp : - 'a Script_int.num -> Script_timestamp.t -> Gas.cost = - fun seconds timestamp -> - let seconds_bytes = int_bytes seconds in - let timestamp_bytes = z_bytes (Script_timestamp.to_zint timestamp) in - atomic_step_cost - (cost_N_IAdd_seconds_to_timestamp seconds_bytes timestamp_bytes) - - let add_timestamp_seconds : - Script_timestamp.t -> 'a Script_int.num -> Gas.cost = - fun timestamp seconds -> - let seconds_bytes = int_bytes seconds in - let timestamp_bytes = z_bytes (Script_timestamp.to_zint timestamp) in - atomic_step_cost - (cost_N_IAdd_timestamp_to_seconds timestamp_bytes seconds_bytes) - - let sub_timestamp_seconds : - Script_timestamp.t -> 'a Script_int.num -> Gas.cost = - fun timestamp seconds -> - let seconds_bytes = int_bytes seconds in - let timestamp_bytes = z_bytes (Script_timestamp.to_zint timestamp) in - atomic_step_cost - (cost_N_ISub_timestamp_seconds timestamp_bytes seconds_bytes) - - let diff_timestamps t1 t2 = - let t1_bytes = z_bytes (Script_timestamp.to_zint t1) in - let t2_bytes = z_bytes (Script_timestamp.to_zint t2) in - atomic_step_cost (cost_N_IDiff_timestamps t1_bytes t2_bytes) - - let concat_string_pair s1 s2 = - atomic_step_cost - (cost_N_IConcat_string_pair - (Script_string.length s1) - (Script_string.length s2)) - - let slice_string s = - atomic_step_cost (cost_N_ISlice_string (Script_string.length s)) - - let string_size = atomic_step_cost cost_N_IString_size - - let concat_bytes_pair b1 b2 = - atomic_step_cost - (cost_N_IConcat_bytes_pair (Bytes.length b1) (Bytes.length b2)) - - let slice_bytes b = atomic_step_cost (cost_N_ISlice_bytes (Bytes.length b)) - - let bytes_size = atomic_step_cost cost_N_IBytes_size - - let add_tez = atomic_step_cost cost_N_IAdd_tez - - let sub_tez = atomic_step_cost cost_N_ISub_tez - - let sub_tez_legacy = atomic_step_cost cost_N_ISub_tez_legacy - - let mul_teznat = atomic_step_cost cost_N_IMul_teznat - - let mul_nattez = atomic_step_cost cost_N_IMul_nattez - - let bool_or = atomic_step_cost cost_N_IOr - - let bool_and = atomic_step_cost cost_N_IAnd - - let bool_xor = atomic_step_cost cost_N_IXor - - let bool_not = atomic_step_cost cost_N_INot - - let is_nat = atomic_step_cost cost_N_IIs_nat - - let abs_int i = atomic_step_cost (cost_N_IAbs_int (int_bytes i)) - - let int_nat = atomic_step_cost cost_N_IInt_nat - - let neg i = atomic_step_cost (cost_N_INeg (int_bytes i)) - - let add_int i1 i2 = - atomic_step_cost (cost_N_IAdd_int (int_bytes i1) (int_bytes i2)) - - let add_nat i1 i2 = - atomic_step_cost (cost_N_IAdd_nat (int_bytes i1) (int_bytes i2)) - - let sub_int i1 i2 = - atomic_step_cost (cost_N_ISub_int (int_bytes i1) (int_bytes i2)) - - let mul_int i1 i2 = - atomic_step_cost (cost_N_IMul_int (int_bytes i1) (int_bytes i2)) - - let mul_nat i1 i2 = - atomic_step_cost (cost_N_IMul_nat (int_bytes i1) (int_bytes i2)) - - let ediv_teznat _tez _n = atomic_step_cost cost_N_IEdiv_teznat - - let ediv_tez = atomic_step_cost cost_N_IEdiv_tez - - let ediv_int i1 i2 = - atomic_step_cost (cost_N_IEdiv_int (int_bytes i1) (int_bytes i2)) - - let ediv_nat i1 i2 = - atomic_step_cost (cost_N_IEdiv_nat (int_bytes i1) (int_bytes i2)) - - let eq = atomic_step_cost cost_N_IEq - - let lsl_nat shifted = atomic_step_cost (cost_N_ILsl_nat (int_bytes shifted)) - - let lsr_nat shifted = atomic_step_cost (cost_N_ILsr_nat (int_bytes shifted)) - - let or_nat n1 n2 = - atomic_step_cost (cost_N_IOr_nat (int_bytes n1) (int_bytes n2)) - - let and_nat n1 n2 = - atomic_step_cost (cost_N_IAnd_nat (int_bytes n1) (int_bytes n2)) - - let and_int_nat n1 n2 = - atomic_step_cost (cost_N_IAnd_int_nat (int_bytes n1) (int_bytes n2)) - - let xor_nat n1 n2 = - atomic_step_cost (cost_N_IXor_nat (int_bytes n1) (int_bytes n2)) - - let not_int i = atomic_step_cost (cost_N_INot_int (int_bytes i)) - - let if_ = atomic_step_cost cost_N_IIf - - let loop = atomic_step_cost cost_N_ILoop - - let loop_left = atomic_step_cost cost_N_ILoop_left - - let dip = atomic_step_cost cost_N_IDip - - let view = atomic_step_cost cost_N_IView - - let check_signature (pkey : Signature.public_key) b = - let cost = - match pkey with - | Ed25519 _ -> cost_N_ICheck_signature_ed25519 (Bytes.length b) - | Secp256k1 _ -> cost_N_ICheck_signature_secp256k1 (Bytes.length b) - | P256 _ -> cost_N_ICheck_signature_p256 (Bytes.length b) - in - atomic_step_cost cost - - let blake2b b = atomic_step_cost (cost_N_IBlake2b (Bytes.length b)) - - let sha256 b = atomic_step_cost (cost_N_ISha256 (Bytes.length b)) - - let sha512 b = atomic_step_cost (cost_N_ISha512 (Bytes.length b)) - - let dign n = atomic_step_cost (cost_N_IDig n) - - let dugn n = atomic_step_cost (cost_N_IDug n) - - let dipn n = atomic_step_cost (cost_N_IDipN n) - - let dropn n = atomic_step_cost (cost_N_IDropN n) - - let voting_power = atomic_step_cost cost_N_IVoting_power - - let total_voting_power = atomic_step_cost cost_N_ITotal_voting_power - - let keccak b = atomic_step_cost (cost_N_IKeccak (Bytes.length b)) - - let sha3 b = atomic_step_cost (cost_N_ISha3 (Bytes.length b)) - - let add_bls12_381_g1 = atomic_step_cost cost_N_IAdd_bls12_381_g1 - - let add_bls12_381_g2 = atomic_step_cost cost_N_IAdd_bls12_381_g2 - - let add_bls12_381_fr = atomic_step_cost cost_N_IAdd_bls12_381_fr - - let mul_bls12_381_g1 = atomic_step_cost cost_N_IMul_bls12_381_g1 - - let mul_bls12_381_g2 = atomic_step_cost cost_N_IMul_bls12_381_g2 - - let mul_bls12_381_fr = atomic_step_cost cost_N_IMul_bls12_381_fr - - let mul_bls12_381_fr_z z = - atomic_step_cost (cost_N_IMul_bls12_381_fr_z (int_bytes z)) - - let mul_bls12_381_z_fr z = - atomic_step_cost (cost_N_IMul_bls12_381_z_fr (int_bytes z)) - - let int_bls12_381_fr = atomic_step_cost cost_N_IInt_bls12_381_z_fr - - let neg_bls12_381_g1 = atomic_step_cost cost_N_INeg_bls12_381_g1 - - let neg_bls12_381_g2 = atomic_step_cost cost_N_INeg_bls12_381_g2 - - let neg_bls12_381_fr = atomic_step_cost cost_N_INeg_bls12_381_fr - - let neq = atomic_step_cost cost_N_INeq - - let pairing_check_bls12_381 (l : 'a Script_typed_ir.boxed_list) = - atomic_step_cost (cost_N_IPairing_check_bls12_381 l.length) - - let comb n = atomic_step_cost (cost_N_IComb n) - - let uncomb n = atomic_step_cost (cost_N_IUncomb n) - - let comb_get n = atomic_step_cost (cost_N_IComb_get n) - - let comb_set n = atomic_step_cost (cost_N_IComb_set n) - - let dupn n = atomic_step_cost (cost_N_IDupN n) - - let sapling_verify_update ~inputs ~outputs = - atomic_step_cost (cost_N_ISapling_verify_update inputs outputs) - - let sapling_empty_state = atomic_step_cost cost_N_ISapling_empty_state - - let halt = atomic_step_cost cost_N_IHalt - - let const = atomic_step_cost cost_N_IConst - - let empty_big_map = atomic_step_cost cost_N_IEmpty_big_map - - let lt = atomic_step_cost cost_N_ILt - - let le = atomic_step_cost cost_N_ILe - - let gt = atomic_step_cost cost_N_IGt - - let ge = atomic_step_cost cost_N_IGe - - let exec = atomic_step_cost cost_N_IExec - - let apply = atomic_step_cost cost_N_IApply - - let lambda = atomic_step_cost cost_N_ILambda - - let address = atomic_step_cost cost_N_IAddress - - let contract = atomic_step_cost cost_N_IContract - - let transfer_tokens = atomic_step_cost cost_N_ITransfer_tokens - - let implicit_account = atomic_step_cost cost_N_IImplicit_account - - let create_contract = atomic_step_cost cost_N_ICreate_contract - - let set_delegate = atomic_step_cost cost_N_ISet_delegate - - let level = atomic_step_cost cost_N_ILevel - - let now = atomic_step_cost cost_N_INow - - let source = atomic_step_cost cost_N_ISource - - let sender = atomic_step_cost cost_N_ISender - - let self = atomic_step_cost cost_N_ISelf - - let self_address = atomic_step_cost cost_N_ISelf_address - - let amount = atomic_step_cost cost_N_IAmount - - let chain_id = atomic_step_cost cost_N_IChainId - - let ticket = atomic_step_cost cost_N_ITicket - - let read_ticket = atomic_step_cost cost_N_IRead_ticket - - let hash_key _ = atomic_step_cost cost_N_IHash_key - - let split_ticket _ amount_a amount_b = - atomic_step_cost - (cost_N_ISplit_ticket (int_bytes amount_a) (int_bytes amount_b)) - - let open_chest ~chest ~time = - let plaintext = Timelock.get_plaintext_size chest in - let log_time = Z.log2 Z.(add one time) in - atomic_step_cost (cost_N_IOpen_chest ~chest:plaintext ~time:log_time) - - (* --------------------------------------------------------------------- *) - (* Semi-hand-crafted models *) - - let compare_unit = atomic_step_cost (S.safe_int 10) - - let compare_pair_tag = atomic_step_cost (S.safe_int 10) - - let compare_union_tag = atomic_step_cost (S.safe_int 10) - - let compare_option_tag = atomic_step_cost (S.safe_int 10) - - let compare_bool = atomic_step_cost (cost_N_ICompare 1 1) - - let compare_signature = atomic_step_cost (S.safe_int 92) - - let compare_string s1 s2 = - atomic_step_cost - (cost_N_ICompare (Script_string.length s1) (Script_string.length s2)) - - let compare_bytes b1 b2 = - atomic_step_cost (cost_N_ICompare (Bytes.length b1) (Bytes.length b2)) - - let compare_mutez = atomic_step_cost (cost_N_ICompare 8 8) - - let compare_int i1 i2 = - atomic_step_cost (cost_N_ICompare (int_bytes i1) (int_bytes i2)) - - let compare_nat n1 n2 = - atomic_step_cost (cost_N_ICompare (int_bytes n1) (int_bytes n2)) - - let compare_key_hash = - let sz = Signature.Public_key_hash.size in - atomic_step_cost (cost_N_ICompare sz sz) - - let compare_key = atomic_step_cost (S.safe_int 92) - - let compare_timestamp t1 t2 = - atomic_step_cost - (cost_N_ICompare - (z_bytes (Script_timestamp.to_zint t1)) - (z_bytes (Script_timestamp.to_zint t2))) - - (* Maximum size of an entrypoint in bytes *) - let entrypoint_size = 31 - - let compare_address = - let sz = Signature.Public_key_hash.size + entrypoint_size in - atomic_step_cost (cost_N_ICompare sz sz) - - let compare_chain_id = atomic_step_cost (S.safe_int 30) - - (* Defunctionalized CPS *) - type cont = - | Compare : 'a Script_typed_ir.comparable_ty * 'a * 'a * cont -> cont - | Return : cont - - let compare : type a. a Script_typed_ir.comparable_ty -> a -> a -> cost = - fun ty x y -> - let rec compare : - type a. - a Script_typed_ir.comparable_ty -> a -> a -> cost -> cont -> cost = - fun ty x y acc k -> - match ty with - | Unit_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_unit) k - | Never_key _ -> ( match x with _ -> .) - | Bool_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_bool) k - | String_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_string x y) k - | Signature_key _ -> - (apply [@tailcall]) Gas.(acc +@ compare_signature) k - | Bytes_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_bytes x y) k - | Mutez_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_mutez) k - | Int_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_int x y) k - | Nat_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_nat x y) k - | Key_hash_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_key_hash) k - | Key_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_key) k - | Timestamp_key _ -> - (apply [@tailcall]) Gas.(acc +@ compare_timestamp x y) k - | Address_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_address) k - | Chain_id_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_chain_id) k - | Pair_key ((tl, _), (tr, _), _) -> - (* Reasonable over-approximation of the cost of lexicographic comparison. *) - let (xl, xr) = x in - let (yl, yr) = y in - (compare [@tailcall]) - tl - xl - yl - Gas.(acc +@ compare_pair_tag) - (Compare (tr, xr, yr, k)) - | Union_key ((tl, _), (tr, _), _) -> ( - match (x, y) with - | (L x, L y) -> - (compare [@tailcall]) tl x y Gas.(acc +@ compare_union_tag) k - | (L _, R _) -> (apply [@tailcall]) Gas.(acc +@ compare_union_tag) k - | (R _, L _) -> (apply [@tailcall]) Gas.(acc +@ compare_union_tag) k - | (R x, R y) -> - (compare [@tailcall]) tr x y Gas.(acc +@ compare_union_tag) k) - | Option_key (t, _) -> ( - match (x, y) with - | (None, None) -> - (apply [@tailcall]) Gas.(acc +@ compare_option_tag) k - | (None, Some _) -> - (apply [@tailcall]) Gas.(acc +@ compare_option_tag) k - | (Some _, None) -> - (apply [@tailcall]) Gas.(acc +@ compare_option_tag) k - | (Some x, Some y) -> - (compare [@tailcall]) t x y Gas.(acc +@ compare_option_tag) k) - and apply cost k = - match k with - | Compare (ty, x, y, k) -> (compare [@tailcall]) ty x y cost k - | Return -> cost - in - compare ty x y Gas.free Return - [@@coq_axiom_with_reason "non top-level mutually recursive function"] - - let view_mem (elt : Script_string.t) - (m : Script_typed_ir.view Script_typed_ir.SMap.t) = - let open S_syntax in - let per_elt_cost = - compare (Script_typed_ir.string_key ~annot:None) elt elt - in - let size = S.safe_int (Script_typed_ir.SMap.cardinal m) in - let intercept = atomic_step_cost (S.safe_int 80) in - Gas.(intercept +@ (log2 size *@ per_elt_cost)) - - let view_get = view_mem - - let view_update (elt : Script_string.t) - (m : Script_typed_ir.view Script_typed_ir.SMap.t) = - let open S_syntax in - let per_elt_cost = - compare (Script_typed_ir.string_key ~annot:None) elt elt - in - let size = S.safe_int (Script_typed_ir.SMap.cardinal m) in - let intercept = atomic_step_cost (S.safe_int 80) in - Gas.(intercept +@ (S.safe_int 2 * log2 size *@ per_elt_cost)) - - let set_mem (type a) (elt : a) ((module Box) : a Script_typed_ir.set) = - let open S_syntax in - let per_elt_cost = compare Box.elt_ty elt elt in - let size = S.safe_int Box.size in - let intercept = atomic_step_cost (S.safe_int 115) in - Gas.(intercept +@ (log2 size *@ per_elt_cost)) - - let set_update (type a) (elt : a) ((module Box) : a Script_typed_ir.set) = - let open S_syntax in - let per_elt_cost = compare Box.elt_ty elt elt in - let size = S.safe_int Box.size in - let intercept = atomic_step_cost (S.safe_int 130) in - (* The 2 factor reflects the update vs mem overhead as benchmarked - on non-structured data *) - Gas.(intercept +@ (S.safe_int 2 * log2 size *@ per_elt_cost)) - - let map_mem (type k v) (elt : k) ((module Box) : (k, v) Script_typed_ir.map) - = - let open S_syntax in - let per_elt_cost = compare Box.key_ty elt elt in - let size = S.safe_int Box.size in - let intercept = atomic_step_cost (S.safe_int 80) in - Gas.(intercept +@ (log2 size *@ per_elt_cost)) - - let map_get = map_mem - - let map_update (type k v) (elt : k) - ((module Box) : (k, v) Script_typed_ir.map) = - let open S_syntax in - let per_elt_cost = compare Box.key_ty elt elt in - let size = S.safe_int Box.size in - let intercept = atomic_step_cost (S.safe_int 80) in - (* The 2 factor reflects the update vs mem overhead as benchmarked - on non-structured data *) - Gas.(intercept +@ (S.safe_int 2 * log2 size *@ per_elt_cost)) - - let map_get_and_update (type k v) (elt : k) - ((module Box) : (k, v) Script_typed_ir.map) = - let open S_syntax in - let per_elt_cost = compare Box.key_ty elt elt in - let size = S.safe_int Box.size in - let intercept = atomic_step_cost (S.safe_int 80) in - (* The 3 factor reflects the update vs mem overhead as benchmarked - on non-structured data *) - Gas.(intercept +@ (S.safe_int 3 * log2 size *@ per_elt_cost)) - - let join_tickets : - 'a Script_typed_ir.comparable_ty -> - 'a Script_typed_ir.ticket -> - 'a Script_typed_ir.ticket -> - Gas.cost = - fun ty ticket_a ticket_b -> - let contents_comparison = - compare ty ticket_a.contents ticket_b.contents - in - Gas.( - contents_comparison +@ compare_address - +@ add_nat ticket_a.amount ticket_b.amount) - - (* Continuations *) - module Control = struct - let nil = atomic_step_cost cost_N_KNil - - let cons = atomic_step_cost cost_N_KCons - - let return = atomic_step_cost cost_N_KReturn - - let view_exit = atomic_step_cost cost_N_KView_exit - - let map_head = atomic_step_cost const_N_KMap_head - - let undip = atomic_step_cost cost_N_KUndip - - let loop_in = atomic_step_cost cost_N_KLoop_in - - let loop_in_left = atomic_step_cost cost_N_KLoop_in_left - - let iter = atomic_step_cost cost_N_KIter - - let list_enter_body xs ys_len = - atomic_step_cost (cost_N_KList_enter_body xs ys_len) - - let list_exit_body = atomic_step_cost cost_N_KList_exit_body - - let map_enter_body = atomic_step_cost cost_N_KMap_enter_body - - let map_exit_body (type k v) (key : k) (map : (k, v) Script_typed_ir.map) - = - map_update key map - end - - (* --------------------------------------------------------------------- *) - (* Hand-crafted models *) - - (* The cost functions below where not benchmarked, a cost model was derived - from looking at similar instructions. *) - - (* Cost for Concat_string is paid in two steps: when entering the interpreter, - the user pays for the cost of computing the information necessary to compute - the actual gas (so it's meta-gas): indeed, one needs to run through the - list of strings to compute the total allocated cost. - [concat_string_precheck] corresponds to the meta-gas cost of this computation. - *) - let concat_string_precheck (l : 'a Script_typed_ir.boxed_list) = - (* we set the precheck to be slightly more expensive than cost_N_IList_iter *) - atomic_step_cost (S.mul (S.safe_int l.length) (S.safe_int 10)) - - (* This is the cost of allocating a string and blitting existing ones into it. *) - let concat_string total_bytes = - atomic_step_cost - S.(add (S.safe_int 100) (S.ediv total_bytes (S.safe_int 10))) - - (* Same story as Concat_string. *) - let concat_bytes total_bytes = - atomic_step_cost - S.(add (S.safe_int 100) (S.ediv total_bytes (S.safe_int 10))) - - (* Cost of access taken care of in Contract_storage.get_balance_carbonated *) - let balance = Gas.free - - (* Cost of Unpack pays two integer comparisons, and a Bytes slice *) - let unpack bytes = - let blen = Bytes.length bytes in - let open S_syntax in - atomic_step_cost (S.safe_int 260 + (S.safe_int blen lsr 3)) - - (* TODO benchmark *) - (* FIXME: imported from 006, needs proper benchmarks *) - let unpack_failed bytes = - (* We cannot instrument failed deserialization, - so we take worst case fees: a set of size 1 bytes values. *) - let blen = String.length bytes in - let len = S.safe_int blen in - let d = Z.numbits (Z.of_int blen) in - (len *@ alloc_mbytes_cost 1) - +@ len - *@ (S.safe_int d *@ (alloc_cost (S.safe_int 3) +@ step_cost S.one)) - end - - module Typechecking = struct - open Generated_costs - - let public_key_optimized = - atomic_step_cost - @@ S.( - max - cost_DECODING_PUBLIC_KEY_ed25519 - (max - cost_DECODING_PUBLIC_KEY_secp256k1 - cost_DECODING_PUBLIC_KEY_p256)) - - let public_key_readable = - atomic_step_cost - @@ S.( - max - cost_B58CHECK_DECODING_PUBLIC_KEY_ed25519 - (max - cost_B58CHECK_DECODING_PUBLIC_KEY_secp256k1 - cost_B58CHECK_DECODING_PUBLIC_KEY_p256)) - - let key_hash_optimized = - atomic_step_cost - @@ S.( - max - cost_DECODING_PUBLIC_KEY_HASH_ed25519 - (max - cost_DECODING_PUBLIC_KEY_HASH_secp256k1 - cost_DECODING_PUBLIC_KEY_HASH_p256)) - - let key_hash_readable = - atomic_step_cost - @@ S.( - max - cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_ed25519 - (max - cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_secp256k1 - cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_p256)) - - let signature_optimized = - atomic_step_cost - @@ S.( - max - cost_DECODING_SIGNATURE_ed25519 - (max - cost_DECODING_SIGNATURE_secp256k1 - cost_DECODING_SIGNATURE_p256)) - - let signature_readable = - atomic_step_cost - @@ S.( - max - cost_B58CHECK_DECODING_SIGNATURE_ed25519 - (max - cost_B58CHECK_DECODING_SIGNATURE_secp256k1 - cost_B58CHECK_DECODING_SIGNATURE_p256)) - - let chain_id_optimized = atomic_step_cost cost_DECODING_CHAIN_ID - - let chain_id_readable = atomic_step_cost cost_B58CHECK_DECODING_CHAIN_ID - - (* Reasonable approximation *) - let address_optimized = key_hash_optimized - - (* Reasonable approximation *) - let contract_optimized = key_hash_optimized - - (* Reasonable approximation *) - let contract_readable = key_hash_readable - - let bls12_381_g1 = atomic_step_cost cost_DECODING_BLS_G1 - - let bls12_381_g2 = atomic_step_cost cost_DECODING_BLS_G2 - - let bls12_381_fr = atomic_step_cost cost_DECODING_BLS_FR - - let check_printable s = - atomic_step_cost (cost_CHECK_PRINTABLE (String.length s)) - - let merge_cycle = atomic_step_cost cost_MERGE_TYPES - - let parse_type_cycle = atomic_step_cost cost_PARSE_TYPE - - let parse_instr_cycle = atomic_step_cost cost_TYPECHECKING_CODE - - let parse_data_cycle = atomic_step_cost cost_TYPECHECKING_DATA - - let comparable_ty_of_ty_cycle = atomic_step_cost cost_COMPARABLE_TY_OF_TY - - (* Cost of a cycle of checking that a type is dupable *) - (* TODO: bench *) - let check_dupable_cycle = atomic_step_cost cost_TYPECHECKING_DATA - - let bool = free - - let unit = free - - let timestamp_readable = atomic_step_cost cost_TIMESTAMP_READABLE_DECODING - - (* Reasonable estimate. *) - let contract = Gas.(S.safe_int 2 *@ public_key_readable) - - (* Balance stored at /contracts/index/hash/balance, on 64 bits *) - let contract_exists = - Gas.cost_of_repr @@ Storage_costs.read_access ~path_length:4 ~read_bytes:8 - - (* Constructing proof arguments consists in a decreasing loop in the result - monad, allocating at each step. We charge a reasonable overapproximation. *) - let proof_argument n = - atomic_step_cost (S.mul (S.safe_int n) (S.safe_int 50)) - - let chest_key = atomic_step_cost cost_DECODING_Chest_key - - let chest ~bytes = atomic_step_cost (cost_DECODING_Chest ~bytes) - end - - module Unparsing = struct - open Generated_costs - - let public_key_optimized = - atomic_step_cost - @@ S.( - max - cost_ENCODING_PUBLIC_KEY_ed25519 - (max - cost_ENCODING_PUBLIC_KEY_secp256k1 - cost_ENCODING_PUBLIC_KEY_p256)) - - let public_key_readable = - atomic_step_cost - @@ S.( - max - cost_B58CHECK_ENCODING_PUBLIC_KEY_ed25519 - (max - cost_B58CHECK_ENCODING_PUBLIC_KEY_secp256k1 - cost_B58CHECK_ENCODING_PUBLIC_KEY_p256)) - - let key_hash_optimized = - atomic_step_cost - @@ S.( - max - cost_ENCODING_PUBLIC_KEY_HASH_ed25519 - (max - cost_ENCODING_PUBLIC_KEY_HASH_secp256k1 - cost_ENCODING_PUBLIC_KEY_HASH_p256)) - - let key_hash_readable = - atomic_step_cost - @@ S.( - max - cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_ed25519 - (max - cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_secp256k1 - cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_p256)) - - let signature_optimized = - atomic_step_cost - @@ S.( - max - cost_ENCODING_SIGNATURE_ed25519 - (max - cost_ENCODING_SIGNATURE_secp256k1 - cost_ENCODING_SIGNATURE_p256)) - - let signature_readable = - atomic_step_cost - @@ S.( - max - cost_B58CHECK_ENCODING_SIGNATURE_ed25519 - (max - cost_B58CHECK_ENCODING_SIGNATURE_secp256k1 - cost_B58CHECK_ENCODING_SIGNATURE_p256)) - - let chain_id_optimized = atomic_step_cost cost_ENCODING_CHAIN_ID - - let chain_id_readable = atomic_step_cost cost_B58CHECK_ENCODING_CHAIN_ID - - let timestamp_readable = atomic_step_cost cost_TIMESTAMP_READABLE_ENCODING - - (* Reasonable approximation *) - let address_optimized = key_hash_optimized - - (* Reasonable approximation *) - let contract_optimized = key_hash_optimized - - (* Reasonable approximation *) - let contract_readable = key_hash_readable - - let bls12_381_g1 = atomic_step_cost cost_ENCODING_BLS_G1 - - let bls12_381_g2 = atomic_step_cost cost_ENCODING_BLS_G2 - - let bls12_381_fr = atomic_step_cost cost_ENCODING_BLS_FR - - let unparse_type ty = - atomic_step_cost - @@ cost_UNPARSE_TYPE Script_typed_ir.(ty_size ty |> Type_size.to_int) - - let unparse_comparable_type comp_ty = - atomic_step_cost - @@ cost_UNPARSE_COMPARABLE_TYPE - Script_typed_ir.(comparable_ty_size comp_ty |> Type_size.to_int) - - let unparse_instr_cycle = atomic_step_cost cost_UNPARSING_CODE - - let unparse_data_cycle = atomic_step_cost cost_UNPARSING_DATA - - let unit = Gas.free - - (* Reasonable estimate. *) - let contract = Gas.(S.safe_int 2 *@ public_key_readable) - - (* Reuse 006 costs. *) - let operation bytes = Script.bytes_node_cost bytes - - let sapling_transaction (t : Sapling.transaction) = - let inputs = List.length t.inputs in - let outputs = List.length t.outputs in - atomic_step_cost (cost_SAPLING_TRANSACTION_ENCODING ~inputs ~outputs) - - let sapling_diff (d : Sapling.diff) = - let nfs = List.length d.nullifiers in - let cms = List.length d.commitments_and_ciphertexts in - atomic_step_cost (cost_SAPLING_DIFF_ENCODING ~nfs ~cms) - - let chest_key = atomic_step_cost cost_ENCODING_Chest_key - - let chest ~plaintext_size = - atomic_step_cost (cost_ENCODING_Chest ~plaintext_size) - end -end diff --git a/src/proto_012_Psithaca/lib_protocol/michelson_v1_gas.mli b/src/proto_012_Psithaca/lib_protocol/michelson_v1_gas.mli deleted file mode 100644 index 2b4674cbcca1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/michelson_v1_gas.mli +++ /dev/null @@ -1,506 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -module Cost_of : sig - val manager_operation : Gas.cost - - module Interpreter : sig - val drop : Gas.cost - - val dup : Gas.cost - - val swap : Gas.cost - - val cons_some : Gas.cost - - val cons_none : Gas.cost - - val if_none : Gas.cost - - val opt_map : Gas.cost - - val cons_pair : Gas.cost - - val unpair : Gas.cost - - val car : Gas.cost - - val cdr : Gas.cost - - val cons_left : Gas.cost - - val cons_right : Gas.cost - - val if_left : Gas.cost - - val cons_list : Gas.cost - - val nil : Gas.cost - - val if_cons : Gas.cost - - val list_map : 'a Script_typed_ir.boxed_list -> Gas.cost - - val list_size : Gas.cost - - val list_iter : 'a Script_typed_ir.boxed_list -> Gas.cost - - val empty_set : Gas.cost - - val set_iter : 'a Script_typed_ir.set -> Gas.cost - - val set_mem : 'a -> 'a Script_typed_ir.set -> Gas.cost - - val set_update : 'a -> 'a Script_typed_ir.set -> Gas.cost - - val set_size : Gas.cost - - val empty_map : Gas.cost - - val map_map : ('k, 'v) Script_typed_ir.map -> Gas.cost - - val map_iter : ('k, 'v) Script_typed_ir.map -> Gas.cost - - val map_mem : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost - - val map_get : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost - - val map_update : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost - - val map_get_and_update : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost - - val big_map_mem : (_, _) Script_typed_ir.big_map_overlay -> Gas.cost - - val big_map_get : (_, _) Script_typed_ir.big_map_overlay -> Gas.cost - - val big_map_update : (_, _) Script_typed_ir.big_map_overlay -> Gas.cost - - val big_map_get_and_update : - (_, _) Script_typed_ir.big_map_overlay -> Gas.cost - - val map_size : Gas.cost - - val add_seconds_timestamp : - 'a Script_int.num -> Script_timestamp.t -> Gas.cost - - val add_timestamp_seconds : - Script_timestamp.t -> 'a Script_int.num -> Gas.cost - - val sub_timestamp_seconds : - Script_timestamp.t -> 'a Script_int.num -> Gas.cost - - val diff_timestamps : Script_timestamp.t -> Script_timestamp.t -> Gas.cost - - val concat_string_pair : Script_string.t -> Script_string.t -> Gas.cost - - val slice_string : Script_string.t -> Gas.cost - - val string_size : Gas.cost - - val concat_bytes_pair : bytes -> bytes -> Gas.cost - - val slice_bytes : bytes -> Gas.cost - - val bytes_size : Gas.cost - - val add_tez : Gas.cost - - val sub_tez : Gas.cost - - val sub_tez_legacy : Gas.cost - - val mul_teznat : Gas.cost - - val mul_nattez : Gas.cost - - val bool_or : Gas.cost - - val bool_and : Gas.cost - - val bool_xor : Gas.cost - - val bool_not : Gas.cost - - val is_nat : Gas.cost - - val abs_int : Alpha_context.Script_int.z Script_int.num -> Gas.cost - - val int_nat : Gas.cost - - val neg : 'a Script_int.num -> Gas.cost - - val add_int : 'a Script_int.num -> 'b Script_int.num -> Gas.cost - - val add_nat : - Alpha_context.Script_int.n Script_int.num -> - Alpha_context.Script_int.n Script_int.num -> - Gas.cost - - val sub_int : 'a Script_int.num -> 'b Script_int.num -> Gas.cost - - val mul_int : 'a Script_int.num -> 'b Script_int.num -> Gas.cost - - val mul_nat : - Alpha_context.Script_int.n Script_int.num -> 'a Script_int.num -> Gas.cost - - val ediv_teznat : 'a -> 'b Script_int.num -> Gas.cost - - val ediv_tez : Gas.cost - - val ediv_int : 'a Script_int.num -> 'b Script_int.num -> Gas.cost - - val ediv_nat : - Alpha_context.Script_int.n Script_int.num -> 'a Script_int.num -> Gas.cost - - val eq : Gas.cost - - val lsl_nat : 'a Script_int.num -> Gas.cost - - val lsr_nat : 'a Script_int.num -> Gas.cost - - val or_nat : 'a Script_int.num -> 'b Script_int.num -> Gas.cost - - val and_nat : 'a Script_int.num -> 'b Script_int.num -> Gas.cost - - val and_int_nat : - Alpha_context.Script_int.z Script_int.num -> - Alpha_context.Script_int.n Script_int.num -> - Gas.cost - - val xor_nat : 'a Script_int.num -> 'b Script_int.num -> Gas.cost - - val not_int : 'a Script_int.num -> Gas.cost - - val if_ : Gas.cost - - val loop : Gas.cost - - val loop_left : Gas.cost - - val dip : Gas.cost - - val check_signature : Signature.public_key -> bytes -> Gas.cost - - val blake2b : bytes -> Gas.cost - - val sha256 : bytes -> Gas.cost - - val sha512 : bytes -> Gas.cost - - val dign : int -> Gas.cost - - val dugn : int -> Gas.cost - - val dipn : int -> Gas.cost - - val dropn : int -> Gas.cost - - val voting_power : Gas.cost - - val total_voting_power : Gas.cost - - val keccak : bytes -> Gas.cost - - val sha3 : bytes -> Gas.cost - - val add_bls12_381_g1 : Gas.cost - - val add_bls12_381_g2 : Gas.cost - - val add_bls12_381_fr : Gas.cost - - val mul_bls12_381_g1 : Gas.cost - - val mul_bls12_381_g2 : Gas.cost - - val mul_bls12_381_fr : Gas.cost - - val mul_bls12_381_fr_z : 'a Script_int.num -> Gas.cost - - val mul_bls12_381_z_fr : 'a Script_int.num -> Gas.cost - - val int_bls12_381_fr : Gas.cost - - val neg_bls12_381_g1 : Gas.cost - - val neg_bls12_381_g2 : Gas.cost - - val neg_bls12_381_fr : Gas.cost - - val neq : Gas.cost - - val pairing_check_bls12_381 : 'a Script_typed_ir.boxed_list -> Gas.cost - - val comb : int -> Gas.cost - - val uncomb : int -> Gas.cost - - val comb_get : int -> Gas.cost - - val comb_set : int -> Gas.cost - - val dupn : int -> Gas.cost - - val compare : 'a Script_typed_ir.comparable_ty -> 'a -> 'a -> Gas.cost - - val concat_string_precheck : 'a Script_typed_ir.boxed_list -> Gas.cost - - val concat_string : - Saturation_repr.may_saturate Saturation_repr.t -> Gas.cost - - val concat_bytes : - Saturation_repr.may_saturate Saturation_repr.t -> Gas.cost - - val halt : Gas.cost - - val const : Gas.cost - - val empty_big_map : Gas.cost - - val lt : Gas.cost - - val le : Gas.cost - - val gt : Gas.cost - - val ge : Gas.cost - - val exec : Gas.cost - - val apply : Gas.cost - - val lambda : Gas.cost - - val address : Gas.cost - - val contract : Gas.cost - - val view : Gas.cost - - val view_mem : - Script_string.t -> Script_typed_ir.view Script_typed_ir.SMap.t -> Gas.cost - - val view_get : - Script_string.t -> Script_typed_ir.view Script_typed_ir.SMap.t -> Gas.cost - - val view_update : - Script_string.t -> Script_typed_ir.view Script_typed_ir.SMap.t -> Gas.cost - - val transfer_tokens : Gas.cost - - val implicit_account : Gas.cost - - val create_contract : Gas.cost - - val set_delegate : Gas.cost - - val balance : Gas.cost - - val level : Gas.cost - - val now : Gas.cost - - val hash_key : Signature.Public_key.t -> Gas.cost - - val source : Gas.cost - - val sender : Gas.cost - - val self : Gas.cost - - val self_address : Gas.cost - - val amount : Gas.cost - - val chain_id : Gas.cost - - val unpack : bytes -> Gas.cost - - val unpack_failed : string -> Gas.cost - - val sapling_empty_state : Gas.cost - - val sapling_verify_update : inputs:int -> outputs:int -> Gas.cost - - val ticket : Gas.cost - - val read_ticket : Gas.cost - - val split_ticket : - 'a Script_int.num -> 'a Script_int.num -> 'a Script_int.num -> Gas.cost - - val join_tickets : - 'a Script_typed_ir.comparable_ty -> - 'a Script_typed_ir.ticket -> - 'a Script_typed_ir.ticket -> - Gas.cost - - val open_chest : chest:Timelock.chest -> time:Z.t -> Gas.cost - - module Control : sig - val nil : Gas.cost - - val cons : Gas.cost - - val return : Gas.cost - - val view_exit : Gas.cost - - val map_head : Gas.cost - - val undip : Gas.cost - - val loop_in : Gas.cost - - val loop_in_left : Gas.cost - - val iter : Gas.cost - - val list_enter_body : 'a list -> int -> Gas.cost - - val list_exit_body : Gas.cost - - val map_enter_body : Gas.cost - - val map_exit_body : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost - end - end - - module Typechecking : sig - val public_key_optimized : Gas.cost - - val public_key_readable : Gas.cost - - val key_hash_optimized : Gas.cost - - val key_hash_readable : Gas.cost - - val signature_optimized : Gas.cost - - val signature_readable : Gas.cost - - val chain_id_optimized : Gas.cost - - val chain_id_readable : Gas.cost - - val address_optimized : Gas.cost - - val contract_optimized : Gas.cost - - val contract_readable : Gas.cost - - val bls12_381_g1 : Gas.cost - - val bls12_381_g2 : Gas.cost - - val bls12_381_fr : Gas.cost - - val check_printable : string -> Gas.cost - - val merge_cycle : Gas.cost - - val parse_type_cycle : Gas.cost - - val parse_instr_cycle : Gas.cost - - val parse_data_cycle : Gas.cost - - val comparable_ty_of_ty_cycle : Gas.cost - - val check_dupable_cycle : Gas.cost - - val bool : Gas.cost - - val unit : Gas.cost - - val timestamp_readable : Gas.cost - - val contract : Gas.cost - - val contract_exists : Gas.cost - - val proof_argument : int -> Gas.cost - - val chest_key : Gas.cost - - val chest : bytes:int -> Gas.cost - end - - module Unparsing : sig - val public_key_optimized : Gas.cost - - val public_key_readable : Gas.cost - - val key_hash_optimized : Gas.cost - - val key_hash_readable : Gas.cost - - val signature_optimized : Gas.cost - - val signature_readable : Gas.cost - - val chain_id_optimized : Gas.cost - - val chain_id_readable : Gas.cost - - val timestamp_readable : Gas.cost - - val address_optimized : Gas.cost - - val contract_optimized : Gas.cost - - val contract_readable : Gas.cost - - val bls12_381_g1 : Gas.cost - - val bls12_381_g2 : Gas.cost - - val bls12_381_fr : Gas.cost - - val unparse_type : 'a Script_typed_ir.ty -> Gas.cost - - val unparse_comparable_type : 'a Script_typed_ir.comparable_ty -> Gas.cost - - val unparse_instr_cycle : Gas.cost - - val unparse_data_cycle : Gas.cost - - val unit : Gas.cost - - val contract : Gas.cost - - val operation : bytes -> Gas.cost - - val sapling_transaction : Sapling.transaction -> Gas.cost - - val sapling_diff : Sapling.diff -> Gas.cost - - val chest_key : Gas.cost - - val chest : plaintext_size:int -> Gas.cost - end -end diff --git a/src/proto_012_Psithaca/lib_protocol/michelson_v1_primitives.ml b/src/proto_012_Psithaca/lib_protocol/michelson_v1_primitives.ml deleted file mode 100644 index c1434b14ec14..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/michelson_v1_primitives.ml +++ /dev/null @@ -1,799 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Micheline - -type error += Unknown_primitive_name of string - -type error += Invalid_case of string - -type error += - | Invalid_primitive_name of - string Micheline.canonical * Micheline.canonical_location - -type prim = - | K_parameter - | K_storage - | K_code - | K_view - | D_False - | D_Elt - | D_Left - | D_None - | D_Pair - | D_Right - | D_Some - | D_True - | D_Unit - | I_PACK - | I_UNPACK - | I_BLAKE2B - | I_SHA256 - | I_SHA512 - | I_ABS - | I_ADD - | I_AMOUNT - | I_AND - | I_BALANCE - | I_CAR - | I_CDR - | I_CHAIN_ID - | I_CHECK_SIGNATURE - | I_COMPARE - | I_CONCAT - | I_CONS - | I_CREATE_ACCOUNT - | I_CREATE_CONTRACT - | I_IMPLICIT_ACCOUNT - | I_DIP - | I_DROP - | I_DUP - | I_VIEW - | I_EDIV - | I_EMPTY_BIG_MAP - | I_EMPTY_MAP - | I_EMPTY_SET - | I_EQ - | I_EXEC - | I_APPLY - | I_FAILWITH - | I_GE - | I_GET - | I_GET_AND_UPDATE - | I_GT - | I_HASH_KEY - | I_IF - | I_IF_CONS - | I_IF_LEFT - | I_IF_NONE - | I_INT - | I_LAMBDA - | I_LE - | I_LEFT - | I_LEVEL - | I_LOOP - | I_LSL - | I_LSR - | I_LT - | I_MAP - | I_MEM - | I_MUL - | I_NEG - | I_NEQ - | I_NIL - | I_NONE - | I_NOT - | I_NOW - | I_OR - | I_PAIR - | I_UNPAIR - | I_PUSH - | I_RIGHT - | I_SIZE - | I_SOME - | I_SOURCE - | I_SENDER - | I_SELF - | I_SELF_ADDRESS - | I_SLICE - | I_STEPS_TO_QUOTA - | I_SUB - | I_SUB_MUTEZ - | I_SWAP - | I_TRANSFER_TOKENS - | I_SET_DELEGATE - | I_UNIT - | I_UPDATE - | I_XOR - | I_ITER - | I_LOOP_LEFT - | I_ADDRESS - | I_CONTRACT - | I_ISNAT - | I_CAST - | I_RENAME - | I_SAPLING_EMPTY_STATE - | I_SAPLING_VERIFY_UPDATE - | I_DIG - | I_DUG - | I_NEVER - | I_VOTING_POWER - | I_TOTAL_VOTING_POWER - | I_KECCAK - | I_SHA3 - | I_PAIRING_CHECK - | I_TICKET - | I_READ_TICKET - | I_SPLIT_TICKET - | I_JOIN_TICKETS - | I_OPEN_CHEST - | T_bool - | T_contract - | T_int - | T_key - | T_key_hash - | T_lambda - | T_list - | T_map - | T_big_map - | T_nat - | T_option - | T_or - | T_pair - | T_set - | T_signature - | T_string - | T_bytes - | T_mutez - | T_timestamp - | T_unit - | T_operation - | T_address - | T_sapling_transaction - | T_sapling_state - | T_chain_id - | T_never - | T_bls12_381_g1 - | T_bls12_381_g2 - | T_bls12_381_fr - | T_ticket - | T_chest_key - | T_chest - | H_constant - -(* Auxiliary types for error documentation. - All the prim constructor prefixes must match their namespace. *) -type namespace = - | (* prefix "T" *) Type_namespace - | (* prefix "D" *) Constant_namespace - | (* prefix "I" *) Instr_namespace - | (* prefix "K" *) Keyword_namespace - | (* prefix "H" *) Constant_hash_namespace - -let namespace = function - | K_code | K_view | K_parameter | K_storage -> Keyword_namespace - | D_Elt | D_False | D_Left | D_None | D_Pair | D_Right | D_Some | D_True - | D_Unit -> - Constant_namespace - | I_ABS | I_ADD | I_ADDRESS | I_AMOUNT | I_AND | I_APPLY | I_BALANCE - | I_BLAKE2B | I_CAR | I_CAST | I_CDR | I_CHAIN_ID | I_CHECK_SIGNATURE - | I_COMPARE | I_CONCAT | I_CONS | I_CONTRACT | I_CREATE_ACCOUNT - | I_CREATE_CONTRACT | I_DIG | I_DIP | I_DROP | I_DUG | I_DUP | I_VIEW | I_EDIV - | I_EMPTY_BIG_MAP | I_EMPTY_MAP | I_EMPTY_SET | I_EQ | I_EXEC | I_FAILWITH - | I_GE | I_GET | I_GET_AND_UPDATE | I_GT | I_HASH_KEY | I_IF | I_IF_CONS - | I_IF_LEFT | I_IF_NONE | I_IMPLICIT_ACCOUNT | I_INT | I_ISNAT | I_ITER - | I_JOIN_TICKETS | I_KECCAK | I_LAMBDA | I_LE | I_LEFT | I_LEVEL | I_LOOP - | I_LOOP_LEFT | I_LSL | I_LSR | I_LT | I_MAP | I_MEM | I_MUL | I_NEG | I_NEQ - | I_NEVER | I_NIL | I_NONE | I_NOT | I_NOW | I_OR | I_PACK | I_PAIR - | I_PAIRING_CHECK | I_PUSH | I_READ_TICKET | I_RENAME | I_RIGHT - | I_SAPLING_EMPTY_STATE | I_SAPLING_VERIFY_UPDATE | I_SELF | I_SELF_ADDRESS - | I_SENDER | I_SET_DELEGATE | I_SHA256 | I_SHA512 | I_SHA3 | I_SIZE | I_SLICE - | I_SOME | I_SOURCE | I_SPLIT_TICKET | I_STEPS_TO_QUOTA | I_SUB | I_SUB_MUTEZ - | I_SWAP | I_TICKET | I_TOTAL_VOTING_POWER | I_TRANSFER_TOKENS | I_UNIT - | I_UNPACK | I_UNPAIR | I_UPDATE | I_VOTING_POWER | I_XOR | I_OPEN_CHEST -> - Instr_namespace - | T_address | T_big_map | T_bool | T_bytes | T_chain_id | T_contract | T_int - | T_key | T_key_hash | T_lambda | T_list | T_map | T_mutez | T_nat | T_never - | T_operation | T_option | T_or | T_pair | T_sapling_state - | T_sapling_transaction | T_set | T_signature | T_string | T_timestamp - | T_unit | T_bls12_381_fr | T_bls12_381_g1 | T_bls12_381_g2 | T_ticket - | T_chest_key | T_chest -> - Type_namespace - | H_constant -> Constant_hash_namespace - -let valid_case name = - let is_lower = function '_' | 'a' .. 'z' -> true | _ -> false in - let is_upper = function '_' | 'A' .. 'Z' -> true | _ -> false in - let[@coq_struct "a_value"] rec for_all a b f = - Compare.Int.(a > b) || (f a && for_all (a + 1) b f) - in - let len = String.length name in - Compare.Int.(len <> 0) - && Compare.Char.(name.[0] <> '_') - && ((is_upper name.[0] && for_all 1 (len - 1) (fun i -> is_upper name.[i])) - || (is_upper name.[0] && for_all 1 (len - 1) (fun i -> is_lower name.[i])) - || (is_lower name.[0] && for_all 1 (len - 1) (fun i -> is_lower name.[i])) - ) - -let string_of_prim = function - | K_parameter -> "parameter" - | K_storage -> "storage" - | K_code -> "code" - | K_view -> "view" - | D_False -> "False" - | D_Elt -> "Elt" - | D_Left -> "Left" - | D_None -> "None" - | D_Pair -> "Pair" - | D_Right -> "Right" - | D_Some -> "Some" - | D_True -> "True" - | D_Unit -> "Unit" - | I_PACK -> "PACK" - | I_UNPACK -> "UNPACK" - | I_BLAKE2B -> "BLAKE2B" - | I_SHA256 -> "SHA256" - | I_SHA512 -> "SHA512" - | I_ABS -> "ABS" - | I_ADD -> "ADD" - | I_AMOUNT -> "AMOUNT" - | I_AND -> "AND" - | I_BALANCE -> "BALANCE" - | I_CAR -> "CAR" - | I_CDR -> "CDR" - | I_CHAIN_ID -> "CHAIN_ID" - | I_CHECK_SIGNATURE -> "CHECK_SIGNATURE" - | I_COMPARE -> "COMPARE" - | I_CONCAT -> "CONCAT" - | I_CONS -> "CONS" - | I_CREATE_ACCOUNT -> "CREATE_ACCOUNT" - | I_CREATE_CONTRACT -> "CREATE_CONTRACT" - | I_IMPLICIT_ACCOUNT -> "IMPLICIT_ACCOUNT" - | I_DIP -> "DIP" - | I_DROP -> "DROP" - | I_DUP -> "DUP" - | I_EDIV -> "EDIV" - | I_EMPTY_BIG_MAP -> "EMPTY_BIG_MAP" - | I_EMPTY_MAP -> "EMPTY_MAP" - | I_EMPTY_SET -> "EMPTY_SET" - | I_EQ -> "EQ" - | I_EXEC -> "EXEC" - | I_APPLY -> "APPLY" - | I_FAILWITH -> "FAILWITH" - | I_GE -> "GE" - | I_GET -> "GET" - | I_GET_AND_UPDATE -> "GET_AND_UPDATE" - | I_GT -> "GT" - | I_HASH_KEY -> "HASH_KEY" - | I_IF -> "IF" - | I_IF_CONS -> "IF_CONS" - | I_IF_LEFT -> "IF_LEFT" - | I_IF_NONE -> "IF_NONE" - | I_INT -> "INT" - | I_LAMBDA -> "LAMBDA" - | I_LE -> "LE" - | I_LEFT -> "LEFT" - | I_LEVEL -> "LEVEL" - | I_LOOP -> "LOOP" - | I_LSL -> "LSL" - | I_LSR -> "LSR" - | I_LT -> "LT" - | I_MAP -> "MAP" - | I_MEM -> "MEM" - | I_MUL -> "MUL" - | I_NEG -> "NEG" - | I_NEQ -> "NEQ" - | I_NIL -> "NIL" - | I_NONE -> "NONE" - | I_NOT -> "NOT" - | I_NOW -> "NOW" - | I_OR -> "OR" - | I_PAIR -> "PAIR" - | I_PUSH -> "PUSH" - | I_RIGHT -> "RIGHT" - | I_SIZE -> "SIZE" - | I_SOME -> "SOME" - | I_SOURCE -> "SOURCE" - | I_SENDER -> "SENDER" - | I_SELF -> "SELF" - | I_SELF_ADDRESS -> "SELF_ADDRESS" - | I_SLICE -> "SLICE" - | I_STEPS_TO_QUOTA -> "STEPS_TO_QUOTA" - | I_SUB -> "SUB" - | I_SUB_MUTEZ -> "SUB_MUTEZ" - | I_SWAP -> "SWAP" - | I_TRANSFER_TOKENS -> "TRANSFER_TOKENS" - | I_SET_DELEGATE -> "SET_DELEGATE" - | I_UNIT -> "UNIT" - | I_UNPAIR -> "UNPAIR" - | I_UPDATE -> "UPDATE" - | I_XOR -> "XOR" - | I_ITER -> "ITER" - | I_LOOP_LEFT -> "LOOP_LEFT" - | I_ADDRESS -> "ADDRESS" - | I_CONTRACT -> "CONTRACT" - | I_ISNAT -> "ISNAT" - | I_CAST -> "CAST" - | I_RENAME -> "RENAME" - | I_SAPLING_EMPTY_STATE -> "SAPLING_EMPTY_STATE" - | I_SAPLING_VERIFY_UPDATE -> "SAPLING_VERIFY_UPDATE" - | I_DIG -> "DIG" - | I_DUG -> "DUG" - | I_NEVER -> "NEVER" - | I_VOTING_POWER -> "VOTING_POWER" - | I_TOTAL_VOTING_POWER -> "TOTAL_VOTING_POWER" - | I_KECCAK -> "KECCAK" - | I_SHA3 -> "SHA3" - | I_PAIRING_CHECK -> "PAIRING_CHECK" - | I_TICKET -> "TICKET" - | I_READ_TICKET -> "READ_TICKET" - | I_SPLIT_TICKET -> "SPLIT_TICKET" - | I_JOIN_TICKETS -> "JOIN_TICKETS" - | I_OPEN_CHEST -> "OPEN_CHEST" - | I_VIEW -> "VIEW" - | T_bool -> "bool" - | T_contract -> "contract" - | T_int -> "int" - | T_key -> "key" - | T_key_hash -> "key_hash" - | T_lambda -> "lambda" - | T_list -> "list" - | T_map -> "map" - | T_big_map -> "big_map" - | T_nat -> "nat" - | T_option -> "option" - | T_or -> "or" - | T_pair -> "pair" - | T_set -> "set" - | T_signature -> "signature" - | T_string -> "string" - | T_bytes -> "bytes" - | T_mutez -> "mutez" - | T_timestamp -> "timestamp" - | T_unit -> "unit" - | T_operation -> "operation" - | T_address -> "address" - | T_sapling_state -> "sapling_state" - | T_sapling_transaction -> "sapling_transaction" - | T_chain_id -> "chain_id" - | T_never -> "never" - | T_bls12_381_g1 -> "bls12_381_g1" - | T_bls12_381_g2 -> "bls12_381_g2" - | T_bls12_381_fr -> "bls12_381_fr" - | T_ticket -> "ticket" - | T_chest_key -> "chest_key" - | T_chest -> "chest" - | H_constant -> "constant" - -let prim_of_string = function - | "parameter" -> ok K_parameter - | "storage" -> ok K_storage - | "code" -> ok K_code - | "view" -> ok K_view - | "False" -> ok D_False - | "Elt" -> ok D_Elt - | "Left" -> ok D_Left - | "None" -> ok D_None - | "Pair" -> ok D_Pair - | "Right" -> ok D_Right - | "Some" -> ok D_Some - | "True" -> ok D_True - | "Unit" -> ok D_Unit - | "PACK" -> ok I_PACK - | "UNPACK" -> ok I_UNPACK - | "BLAKE2B" -> ok I_BLAKE2B - | "SHA256" -> ok I_SHA256 - | "SHA512" -> ok I_SHA512 - | "ABS" -> ok I_ABS - | "ADD" -> ok I_ADD - | "AMOUNT" -> ok I_AMOUNT - | "AND" -> ok I_AND - | "BALANCE" -> ok I_BALANCE - | "CAR" -> ok I_CAR - | "CDR" -> ok I_CDR - | "CHAIN_ID" -> ok I_CHAIN_ID - | "CHECK_SIGNATURE" -> ok I_CHECK_SIGNATURE - | "COMPARE" -> ok I_COMPARE - | "CONCAT" -> ok I_CONCAT - | "CONS" -> ok I_CONS - | "CREATE_ACCOUNT" -> ok I_CREATE_ACCOUNT - | "CREATE_CONTRACT" -> ok I_CREATE_CONTRACT - | "IMPLICIT_ACCOUNT" -> ok I_IMPLICIT_ACCOUNT - | "DIP" -> ok I_DIP - | "DROP" -> ok I_DROP - | "DUP" -> ok I_DUP - | "VIEW" -> ok I_VIEW - | "EDIV" -> ok I_EDIV - | "EMPTY_BIG_MAP" -> ok I_EMPTY_BIG_MAP - | "EMPTY_MAP" -> ok I_EMPTY_MAP - | "EMPTY_SET" -> ok I_EMPTY_SET - | "EQ" -> ok I_EQ - | "EXEC" -> ok I_EXEC - | "APPLY" -> ok I_APPLY - | "FAILWITH" -> ok I_FAILWITH - | "GE" -> ok I_GE - | "GET" -> ok I_GET - | "GET_AND_UPDATE" -> ok I_GET_AND_UPDATE - | "GT" -> ok I_GT - | "HASH_KEY" -> ok I_HASH_KEY - | "IF" -> ok I_IF - | "IF_CONS" -> ok I_IF_CONS - | "IF_LEFT" -> ok I_IF_LEFT - | "IF_NONE" -> ok I_IF_NONE - | "INT" -> ok I_INT - | "KECCAK" -> ok I_KECCAK - | "LAMBDA" -> ok I_LAMBDA - | "LE" -> ok I_LE - | "LEFT" -> ok I_LEFT - | "LEVEL" -> ok I_LEVEL - | "LOOP" -> ok I_LOOP - | "LSL" -> ok I_LSL - | "LSR" -> ok I_LSR - | "LT" -> ok I_LT - | "MAP" -> ok I_MAP - | "MEM" -> ok I_MEM - | "MUL" -> ok I_MUL - | "NEG" -> ok I_NEG - | "NEQ" -> ok I_NEQ - | "NIL" -> ok I_NIL - | "NONE" -> ok I_NONE - | "NOT" -> ok I_NOT - | "NOW" -> ok I_NOW - | "OR" -> ok I_OR - | "PAIR" -> ok I_PAIR - | "UNPAIR" -> ok I_UNPAIR - | "PAIRING_CHECK" -> ok I_PAIRING_CHECK - | "PUSH" -> ok I_PUSH - | "RIGHT" -> ok I_RIGHT - | "SHA3" -> ok I_SHA3 - | "SIZE" -> ok I_SIZE - | "SOME" -> ok I_SOME - | "SOURCE" -> ok I_SOURCE - | "SENDER" -> ok I_SENDER - | "SELF" -> ok I_SELF - | "SELF_ADDRESS" -> ok I_SELF_ADDRESS - | "SLICE" -> ok I_SLICE - | "STEPS_TO_QUOTA" -> ok I_STEPS_TO_QUOTA - | "SUB" -> ok I_SUB - | "SUB_MUTEZ" -> ok I_SUB_MUTEZ - | "SWAP" -> ok I_SWAP - | "TRANSFER_TOKENS" -> ok I_TRANSFER_TOKENS - | "SET_DELEGATE" -> ok I_SET_DELEGATE - | "UNIT" -> ok I_UNIT - | "UPDATE" -> ok I_UPDATE - | "XOR" -> ok I_XOR - | "ITER" -> ok I_ITER - | "LOOP_LEFT" -> ok I_LOOP_LEFT - | "ADDRESS" -> ok I_ADDRESS - | "CONTRACT" -> ok I_CONTRACT - | "ISNAT" -> ok I_ISNAT - | "CAST" -> ok I_CAST - | "RENAME" -> ok I_RENAME - | "SAPLING_EMPTY_STATE" -> ok I_SAPLING_EMPTY_STATE - | "SAPLING_VERIFY_UPDATE" -> ok I_SAPLING_VERIFY_UPDATE - | "DIG" -> ok I_DIG - | "DUG" -> ok I_DUG - | "NEVER" -> ok I_NEVER - | "VOTING_POWER" -> ok I_VOTING_POWER - | "TOTAL_VOTING_POWER" -> ok I_TOTAL_VOTING_POWER - | "TICKET" -> ok I_TICKET - | "READ_TICKET" -> ok I_READ_TICKET - | "SPLIT_TICKET" -> ok I_SPLIT_TICKET - | "JOIN_TICKETS" -> ok I_JOIN_TICKETS - | "OPEN_CHEST" -> ok I_OPEN_CHEST - | "bool" -> ok T_bool - | "contract" -> ok T_contract - | "int" -> ok T_int - | "key" -> ok T_key - | "key_hash" -> ok T_key_hash - | "lambda" -> ok T_lambda - | "list" -> ok T_list - | "map" -> ok T_map - | "big_map" -> ok T_big_map - | "nat" -> ok T_nat - | "option" -> ok T_option - | "or" -> ok T_or - | "pair" -> ok T_pair - | "set" -> ok T_set - | "signature" -> ok T_signature - | "string" -> ok T_string - | "bytes" -> ok T_bytes - | "mutez" -> ok T_mutez - | "timestamp" -> ok T_timestamp - | "unit" -> ok T_unit - | "operation" -> ok T_operation - | "address" -> ok T_address - | "sapling_state" -> ok T_sapling_state - | "sapling_transaction" -> ok T_sapling_transaction - | "chain_id" -> ok T_chain_id - | "never" -> ok T_never - | "bls12_381_g1" -> ok T_bls12_381_g1 - | "bls12_381_g2" -> ok T_bls12_381_g2 - | "bls12_381_fr" -> ok T_bls12_381_fr - | "ticket" -> ok T_ticket - | "chest_key" -> ok T_chest_key - | "chest" -> ok T_chest - | "constant" -> ok H_constant - | n -> - if valid_case n then error (Unknown_primitive_name n) - else error (Invalid_case n) - -let prims_of_strings expr = - let rec convert = function - | (Int _ | String _ | Bytes _) as expr -> ok expr - | Prim (loc, prim, args, annot) -> - Error_monad.record_trace - (Invalid_primitive_name (expr, loc)) - (prim_of_string prim) - >>? fun prim -> - List.map_e convert args >|? fun args -> Prim (loc, prim, args, annot) - | Seq (loc, args) -> List.map_e convert args >|? fun args -> Seq (loc, args) - in - convert (root expr) >|? fun expr -> strip_locations expr - [@@coq_axiom_with_reason - "implicit type conversion for expr in the constant cases"] - -let strings_of_prims expr = - let rec convert = function - | (Int _ | String _ | Bytes _) as expr -> expr - | Prim (loc, prim, args, annot) -> - let prim = string_of_prim prim in - let args = List.map convert args in - Prim (loc, prim, args, annot) - | Seq (loc, args) -> - let args = List.map convert args in - Seq (loc, args) - in - strip_locations (convert (root expr)) - [@@coq_axiom_with_reason - "implicit type conversion for expr in the constant cases"] - -let prim_encoding = - let open Data_encoding in - def "michelson.v1.primitives" - @@ string_enum - (* Add the comment below every 10 lines *) - [ - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("parameter", K_parameter); - ("storage", K_storage); - ("code", K_code); - ("False", D_False); - ("Elt", D_Elt); - ("Left", D_Left); - ("None", D_None); - ("Pair", D_Pair); - ("Right", D_Right); - ("Some", D_Some); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("True", D_True); - ("Unit", D_Unit); - ("PACK", I_PACK); - ("UNPACK", I_UNPACK); - ("BLAKE2B", I_BLAKE2B); - ("SHA256", I_SHA256); - ("SHA512", I_SHA512); - ("ABS", I_ABS); - ("ADD", I_ADD); - ("AMOUNT", I_AMOUNT); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("AND", I_AND); - ("BALANCE", I_BALANCE); - ("CAR", I_CAR); - ("CDR", I_CDR); - ("CHECK_SIGNATURE", I_CHECK_SIGNATURE); - ("COMPARE", I_COMPARE); - ("CONCAT", I_CONCAT); - ("CONS", I_CONS); - ("CREATE_ACCOUNT", I_CREATE_ACCOUNT); - ("CREATE_CONTRACT", I_CREATE_CONTRACT); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("IMPLICIT_ACCOUNT", I_IMPLICIT_ACCOUNT); - ("DIP", I_DIP); - ("DROP", I_DROP); - ("DUP", I_DUP); - ("EDIV", I_EDIV); - ("EMPTY_MAP", I_EMPTY_MAP); - ("EMPTY_SET", I_EMPTY_SET); - ("EQ", I_EQ); - ("EXEC", I_EXEC); - ("FAILWITH", I_FAILWITH); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("GE", I_GE); - ("GET", I_GET); - ("GT", I_GT); - ("HASH_KEY", I_HASH_KEY); - ("IF", I_IF); - ("IF_CONS", I_IF_CONS); - ("IF_LEFT", I_IF_LEFT); - ("IF_NONE", I_IF_NONE); - ("INT", I_INT); - ("LAMBDA", I_LAMBDA); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("LE", I_LE); - ("LEFT", I_LEFT); - ("LOOP", I_LOOP); - ("LSL", I_LSL); - ("LSR", I_LSR); - ("LT", I_LT); - ("MAP", I_MAP); - ("MEM", I_MEM); - ("MUL", I_MUL); - ("NEG", I_NEG); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("NEQ", I_NEQ); - ("NIL", I_NIL); - ("NONE", I_NONE); - ("NOT", I_NOT); - ("NOW", I_NOW); - ("OR", I_OR); - ("PAIR", I_PAIR); - ("PUSH", I_PUSH); - ("RIGHT", I_RIGHT); - ("SIZE", I_SIZE); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("SOME", I_SOME); - ("SOURCE", I_SOURCE); - ("SENDER", I_SENDER); - ("SELF", I_SELF); - ("STEPS_TO_QUOTA", I_STEPS_TO_QUOTA); - ("SUB", I_SUB); - ("SWAP", I_SWAP); - ("TRANSFER_TOKENS", I_TRANSFER_TOKENS); - ("SET_DELEGATE", I_SET_DELEGATE); - ("UNIT", I_UNIT); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("UPDATE", I_UPDATE); - ("XOR", I_XOR); - ("ITER", I_ITER); - ("LOOP_LEFT", I_LOOP_LEFT); - ("ADDRESS", I_ADDRESS); - ("CONTRACT", I_CONTRACT); - ("ISNAT", I_ISNAT); - ("CAST", I_CAST); - ("RENAME", I_RENAME); - ("bool", T_bool); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("contract", T_contract); - ("int", T_int); - ("key", T_key); - ("key_hash", T_key_hash); - ("lambda", T_lambda); - ("list", T_list); - ("map", T_map); - ("big_map", T_big_map); - ("nat", T_nat); - ("option", T_option); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("or", T_or); - ("pair", T_pair); - ("set", T_set); - ("signature", T_signature); - ("string", T_string); - ("bytes", T_bytes); - ("mutez", T_mutez); - ("timestamp", T_timestamp); - ("unit", T_unit); - ("operation", T_operation); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("address", T_address); - (* Alpha_002 addition *) - ("SLICE", I_SLICE); - (* Alpha_005 addition *) - ("DIG", I_DIG); - ("DUG", I_DUG); - ("EMPTY_BIG_MAP", I_EMPTY_BIG_MAP); - ("APPLY", I_APPLY); - ("chain_id", T_chain_id); - ("CHAIN_ID", I_CHAIN_ID); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - (* Alpha_008 addition *) - ("LEVEL", I_LEVEL); - ("SELF_ADDRESS", I_SELF_ADDRESS); - ("never", T_never); - ("NEVER", I_NEVER); - ("UNPAIR", I_UNPAIR); - ("VOTING_POWER", I_VOTING_POWER); - ("TOTAL_VOTING_POWER", I_TOTAL_VOTING_POWER); - ("KECCAK", I_KECCAK); - ("SHA3", I_SHA3); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - (* Alpha_008 addition *) - ("PAIRING_CHECK", I_PAIRING_CHECK); - ("bls12_381_g1", T_bls12_381_g1); - ("bls12_381_g2", T_bls12_381_g2); - ("bls12_381_fr", T_bls12_381_fr); - ("sapling_state", T_sapling_state); - ("sapling_transaction", T_sapling_transaction); - ("SAPLING_EMPTY_STATE", I_SAPLING_EMPTY_STATE); - ("SAPLING_VERIFY_UPDATE", I_SAPLING_VERIFY_UPDATE); - ("ticket", T_ticket); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - (* Alpha_008 addition *) - ("TICKET", I_TICKET); - ("READ_TICKET", I_READ_TICKET); - ("SPLIT_TICKET", I_SPLIT_TICKET); - ("JOIN_TICKETS", I_JOIN_TICKETS); - ("GET_AND_UPDATE", I_GET_AND_UPDATE); - (* Alpha_011 addition *) - ("chest", T_chest); - ("chest_key", T_chest_key); - ("OPEN_CHEST", I_OPEN_CHEST); - (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) - ("VIEW", I_VIEW); - ("view", K_view); - ("constant", H_constant); - (* Alpha_012 addition *) - ("SUB_MUTEZ", I_SUB_MUTEZ); - (* New instructions must be added here, for backward compatibility of the encoding. *) - (* Keep the comment above at the end of the list *) - ] - -let () = - register_error_kind - `Permanent - ~id:"michelson_v1.unknown_primitive_name" - ~title:"Unknown primitive name" - ~description:"In a script or data expression, a primitive was unknown." - ~pp:(fun ppf n -> Format.fprintf ppf "Unknown primitive %s." n) - Data_encoding.(obj1 (req "wrong_primitive_name" string)) - (function Unknown_primitive_name got -> Some got | _ -> None) - (fun got -> Unknown_primitive_name got) ; - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_primitive_name_case" - ~title:"Invalid primitive name case" - ~description: - "In a script or data expression, a primitive name is neither uppercase, \ - lowercase or capitalized." - ~pp:(fun ppf n -> Format.fprintf ppf "Primitive %s has invalid case." n) - Data_encoding.(obj1 (req "wrong_primitive_name" string)) - (function Invalid_case name -> Some name | _ -> None) - (fun name -> Invalid_case name) ; - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_primitive_name" - ~title:"Invalid primitive name" - ~description: - "In a script or data expression, a primitive name is unknown or has a \ - wrong case." - ~pp:(fun ppf _ -> Format.fprintf ppf "Invalid primitive.") - Data_encoding.( - obj2 - (req - "expression" - (Micheline.canonical_encoding ~variant:"generic" string)) - (req "location" Micheline.canonical_location_encoding)) - (function - | Invalid_primitive_name (expr, loc) -> Some (expr, loc) | _ -> None) - (fun (expr, loc) -> Invalid_primitive_name (expr, loc)) - -let string_of_namespace = function - | Type_namespace -> "T" - | Constant_namespace -> "D" - | Instr_namespace -> "I" - | Keyword_namespace -> "K" - | Constant_hash_namespace -> "H" diff --git a/src/proto_012_Psithaca/lib_protocol/michelson_v1_primitives.mli b/src/proto_012_Psithaca/lib_protocol/michelson_v1_primitives.mli deleted file mode 100644 index 3c2a65db73dd..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/michelson_v1_primitives.mli +++ /dev/null @@ -1,230 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += (* `Permanent *) Unknown_primitive_name of string - -type error += (* `Permanent *) Invalid_case of string - -type error += - | (* `Permanent *) - Invalid_primitive_name of - string Micheline.canonical * Micheline.canonical_location - -(** Types of nodes in Michelson's AST. They fall into 4 categories: - - types (prefixed with [T_]); - - constants (prefixed with [D_]); - - instructions (prefixed with [I_]); - - keywords (prefixed with [K_]). - - Recall that Micheline is essentially just S-expressions with - a few extra atom types for strings and numbers. This variant - represents the values the [Prim] atoms in the Michelson subset - of Micheline. Other types (such as ['a Micheline.canonical]) are - frequently parameterized by this type. This gives us a strongly-typed - subset of Micheline while keeping the set of primitives independent - from the definition of Micheline for easier changes. -*) -type prim = - | K_parameter - | K_storage - | K_code - | K_view - | D_False - | D_Elt - | D_Left - | D_None - | D_Pair - | D_Right - | D_Some - | D_True - | D_Unit - | I_PACK - | I_UNPACK - | I_BLAKE2B - | I_SHA256 - | I_SHA512 - | I_ABS - | I_ADD - | I_AMOUNT - | I_AND - | I_BALANCE - | I_CAR - | I_CDR - | I_CHAIN_ID - | I_CHECK_SIGNATURE - | I_COMPARE - | I_CONCAT - | I_CONS - | I_CREATE_ACCOUNT - | I_CREATE_CONTRACT - | I_IMPLICIT_ACCOUNT - | I_DIP - | I_DROP - | I_DUP - | I_VIEW - | I_EDIV - | I_EMPTY_BIG_MAP - | I_EMPTY_MAP - | I_EMPTY_SET - | I_EQ - | I_EXEC - | I_APPLY - | I_FAILWITH - | I_GE - | I_GET - | I_GET_AND_UPDATE - | I_GT - | I_HASH_KEY - | I_IF - | I_IF_CONS - | I_IF_LEFT - | I_IF_NONE - | I_INT - | I_LAMBDA - | I_LE - | I_LEFT - | I_LEVEL - | I_LOOP - | I_LSL - | I_LSR - | I_LT - | I_MAP - | I_MEM - | I_MUL - | I_NEG - | I_NEQ - | I_NIL - | I_NONE - | I_NOT - | I_NOW - | I_OR - | I_PAIR - | I_UNPAIR - | I_PUSH - | I_RIGHT - | I_SIZE - | I_SOME - | I_SOURCE - | I_SENDER - | I_SELF - | I_SELF_ADDRESS - | I_SLICE - | I_STEPS_TO_QUOTA - | I_SUB - | I_SUB_MUTEZ - | I_SWAP - | I_TRANSFER_TOKENS - | I_SET_DELEGATE - | I_UNIT - | I_UPDATE - | I_XOR - | I_ITER - | I_LOOP_LEFT - | I_ADDRESS - | I_CONTRACT - | I_ISNAT - | I_CAST - | I_RENAME - | I_SAPLING_EMPTY_STATE - | I_SAPLING_VERIFY_UPDATE - | I_DIG - | I_DUG - | I_NEVER - | I_VOTING_POWER - | I_TOTAL_VOTING_POWER - | I_KECCAK - | I_SHA3 - | I_PAIRING_CHECK - | I_TICKET - | I_READ_TICKET - | I_SPLIT_TICKET - | I_JOIN_TICKETS - | I_OPEN_CHEST - | T_bool - | T_contract - | T_int - | T_key - | T_key_hash - | T_lambda - | T_list - | T_map - | T_big_map - | T_nat - | T_option - | T_or - | T_pair - | T_set - | T_signature - | T_string - | T_bytes - | T_mutez - | T_timestamp - | T_unit - | T_operation - | T_address - | T_sapling_transaction - | T_sapling_state - | T_chain_id - | T_never - | T_bls12_381_g1 - | T_bls12_381_g2 - | T_bls12_381_fr - | T_ticket - | T_chest_key - | T_chest - (* See the interface of [Global_constants_storage]. *) - | H_constant - -(** Auxiliary types for error documentation. - All the prim constructor prefixes must match their namespace. *) - -type namespace = - | (* prefix "T" *) Type_namespace - | (* prefix "D" *) Constant_namespace - | (* prefix "I" *) Instr_namespace - | (* prefix "K" *) Keyword_namespace - (* The Constant Hash namespace is a singleton reserved - for the constant keyword. Unlike other primitives, - constants have no representation in the typed IR, - being fully expanded away before typechecking. *) - | (* prefix "H" *) Constant_hash_namespace - -val namespace : prim -> namespace - -val prim_encoding : prim Data_encoding.encoding - -val string_of_prim : prim -> string - -val prim_of_string : string -> prim tzresult - -val prims_of_strings : - string Micheline.canonical -> prim Micheline.canonical tzresult - -val strings_of_prims : prim Micheline.canonical -> string Micheline.canonical - -(** The string corresponds to the constructor prefix from the given namespace - (i.e. "T", "D", "I" or "K") *) -val string_of_namespace : namespace -> string diff --git a/src/proto_012_Psithaca/lib_protocol/migration_repr.ml b/src/proto_012_Psithaca/lib_protocol/migration_repr.ml deleted file mode 100644 index 5d4d513caff1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/migration_repr.ml +++ /dev/null @@ -1,62 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Tocqueville Group, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type origination_result = { - balance_updates : Receipt_repr.balance_updates; - originated_contracts : Contract_repr.t list; - storage_size : Z.t; - paid_storage_size_diff : Z.t; -} - -let origination_result_list_encoding = - let open Data_encoding in - def "operation.alpha.origination_result" - @@ list - (conv - (fun { - balance_updates; - originated_contracts; - storage_size; - paid_storage_size_diff; - } -> - ( balance_updates, - originated_contracts, - storage_size, - paid_storage_size_diff )) - (fun ( balance_updates, - originated_contracts, - storage_size, - paid_storage_size_diff ) -> - { - balance_updates; - originated_contracts; - storage_size; - paid_storage_size_diff; - }) - (obj4 - (dft "balance_updates" Receipt_repr.balance_updates_encoding []) - (dft "originated_contracts" (list Contract_repr.encoding) []) - (dft "storage_size" z Z.zero) - (dft "paid_storage_size_diff" z Z.zero))) diff --git a/src/proto_012_Psithaca/lib_protocol/migration_repr.mli b/src/proto_012_Psithaca/lib_protocol/migration_repr.mli deleted file mode 100644 index ea34cb1b7ee6..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/migration_repr.mli +++ /dev/null @@ -1,39 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Tocqueville Group, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Dupe of `Kind.origination successful_manager_operation_result` for use - inside Alpha_context. Converted in Apply_results. - - Doesn't consume gas and omits lazy_storage_diff field since it would - require copying Script_ir_translator functions to work on Raw_context. - *) -type origination_result = { - balance_updates : Receipt_repr.balance_updates; - originated_contracts : Contract_repr.t list; - storage_size : Z.t; - paid_storage_size_diff : Z.t; -} - -val origination_result_list_encoding : origination_result list Data_encoding.t diff --git a/src/proto_012_Psithaca/lib_protocol/misc.ml b/src/proto_012_Psithaca/lib_protocol/misc.ml deleted file mode 100644 index bd350a5ef85b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/misc.ml +++ /dev/null @@ -1,92 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Public_key_map = Map.Make (Signature.Public_key) - -type 'a lazyt = unit -> 'a - -type 'a lazy_list_t = LCons of 'a * 'a lazy_list_t tzresult Lwt.t lazyt - -type 'a lazy_list = 'a lazy_list_t tzresult Lwt.t - -let[@coq_struct "i"] rec ( --> ) i j = - (* [i; i+1; ...; j] *) - if Compare.Int.(i > j) then [] else i :: (succ i --> j) - -let[@coq_struct "j"] rec ( <-- ) i j = - (* [j; j-1; ...; i] *) - if Compare.Int.(i > j) then [] else j :: (i <-- pred j) - -let[@coq_struct "i"] rec ( ---> ) i j = - (* [i; i+1; ...; j] *) - if Compare.Int32.(i > j) then [] else i :: (Int32.succ i ---> j) - -let split delim ?(limit = max_int) path = - let l = String.length path in - let rec do_slashes acc limit i = - if Compare.Int.(i >= l) then List.rev acc - else if Compare.Char.(path.[i] = delim) then do_slashes acc limit (i + 1) - else do_split acc limit i - and do_split acc limit i = - if Compare.Int.(limit <= 0) then - if Compare.Int.(i = l) then List.rev acc - else List.rev (String.sub path i (l - i) :: acc) - else do_component acc (pred limit) i i - and do_component acc limit i j = - if Compare.Int.(j >= l) then - if Compare.Int.(i = j) then List.rev acc - else List.rev (String.sub path i (j - i) :: acc) - else if Compare.Char.(path.[j] = delim) then - do_slashes (String.sub path i (j - i) :: acc) limit j - else do_component acc limit i (j + 1) - in - if Compare.Int.(limit > 0) then do_slashes [] limit 0 else [path] - [@@coq_axiom_with_reason "non-top-level mutual recursion"] - -let pp_print_paragraph ppf description = - Format.fprintf - ppf - "@[%a@]" - Format.(pp_print_list ~pp_sep:pp_print_space pp_print_string) - (split ' ' description) - -let take n l = - let rec loop acc n xs = - if Compare.Int.(n <= 0) then Some (List.rev acc, xs) - else match xs with [] -> None | x :: xs -> loop (x :: acc) (n - 1) xs - in - loop [] n l - -let remove_prefix ~prefix s = - let x = String.length prefix in - let n = String.length s in - if Compare.Int.(n >= x) && Compare.String.(String.sub s 0 x = prefix) then - Some (String.sub s x (n - x)) - else None - -let rec remove_elem_from_list nb = function - | [] -> [] - | _ :: _ as l when Compare.Int.(nb <= 0) -> l - | _ :: tl -> remove_elem_from_list (nb - 1) tl diff --git a/src/proto_012_Psithaca/lib_protocol/misc.mli b/src/proto_012_Psithaca/lib_protocol/misc.mli deleted file mode 100644 index 734ca29f9bcf..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/misc.mli +++ /dev/null @@ -1,51 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** {2 Helper functions} *) - -module Public_key_map : Map.S with type key = Signature.Public_key.t - -type 'a lazyt = unit -> 'a - -type 'a lazy_list_t = LCons of 'a * 'a lazy_list_t tzresult Lwt.t lazyt - -type 'a lazy_list = 'a lazy_list_t tzresult Lwt.t - -(** Include bounds *) -val ( --> ) : int -> int -> int list - -val ( <-- ) : int -> int -> int list - -val ( ---> ) : Int32.t -> Int32.t -> Int32.t list - -val pp_print_paragraph : Format.formatter -> string -> unit - -val take : int -> 'a list -> ('a list * 'a list) option - -(** Some (input with [prefix] removed), if string has [prefix], else [None] *) -val remove_prefix : prefix:string -> string -> string option - -(** [remove nb list] remove the first [nb] elements from the list [list]. *) -val remove_elem_from_list : int -> 'a list -> 'a list diff --git a/src/proto_012_Psithaca/lib_protocol/non_empty_string.ml b/src/proto_012_Psithaca/lib_protocol/non_empty_string.ml deleted file mode 100644 index 9ce9b11d27e8..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/non_empty_string.ml +++ /dev/null @@ -1,42 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -include Compare.String - -let of_string = function "" -> None | s -> Some s - -let of_string_exn = function - | "" -> invalid_arg "Unexpected empty string" - | s -> s - -let cat2 a ?(sep = "") b = String.concat sep [a; b] - -let split_on_last sep s = - match String.rindex_opt s sep with - | Some i when Compare.Int.(i > 0 && i < String.length s - 1) -> - let s1 = String.sub s 0 i in - let s2 = String.sub s (i + 1) (String.length s - 1 - i) in - Some (s1, s2) - | _ -> None diff --git a/src/proto_012_Psithaca/lib_protocol/non_empty_string.mli b/src/proto_012_Psithaca/lib_protocol/non_empty_string.mli deleted file mode 100644 index a9973efd775f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/non_empty_string.mli +++ /dev/null @@ -1,45 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** A string that is guaranteed to be non-empty *) -type t = private string - -include Compare.S with type t := t - -(** Returns [None] if the original string is empty. *) -val of_string : string -> t option - -(** Fails with [Invalid_argument] if the original string is empty. *) -val of_string_exn : string -> t - -(** [cat2 a b] concatenates [a] and [b]. - [cat2 a ~sep b] concatenates [a], [sep], and [b]. *) -val cat2 : t -> ?sep:string -> t -> t - -(** [split_on_last c s] finds the last occurrence of [c] in [s] and returns - the substring before and the substring after. - Returns [None] if [c] is not present in [s] or if one or both substrings - would end up being empty. *) -val split_on_last : char -> t -> (t * t) option diff --git a/src/proto_012_Psithaca/lib_protocol/nonce_hash.ml b/src/proto_012_Psithaca/lib_protocol/nonce_hash.ml deleted file mode 100644 index 10a3f7efe42b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/nonce_hash.ml +++ /dev/null @@ -1,45 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* 32 *) -let nonce_hash = "\069\220\169" (* nce(53) *) - -module H = - Blake2B.Make - (Base58) - (struct - let name = "cycle_nonce" - - let title = "A nonce hash" - - let b58check_prefix = nonce_hash - - let size = None - end) - -include H -include Path_encoding.Make_hex (H) - -let () = Base58.check_encoded_prefix b58check_encoding "nce" 53 diff --git a/src/proto_012_Psithaca/lib_protocol/nonce_hash.mli b/src/proto_012_Psithaca/lib_protocol/nonce_hash.mli deleted file mode 100644 index aeeef12905bd..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/nonce_hash.mli +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** A specialized Blake2B implementation for hashing nonces. *) - -include S.HASH - -include Path_encoding.S with type t := t diff --git a/src/proto_012_Psithaca/lib_protocol/nonce_storage.ml b/src/proto_012_Psithaca/lib_protocol/nonce_storage.ml deleted file mode 100644 index 60e8d8f0dff6..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/nonce_storage.ml +++ /dev/null @@ -1,132 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = Seed_repr.nonce - -type nonce = t - -let encoding = Seed_repr.nonce_encoding - -type error += - | Too_late_revelation - | Too_early_revelation - | Previously_revealed_nonce - | Inconsistent_nonce - -let () = - register_error_kind - `Branch - ~id:"nonce.too_late_revelation" - ~title:"Too late nonce revelation" - ~description:"Nonce revelation happens too late" - ~pp:(fun ppf () -> - Format.fprintf ppf "This nonce cannot be revealed anymore.") - Data_encoding.unit - (function Too_late_revelation -> Some () | _ -> None) - (fun () -> Too_late_revelation) ; - register_error_kind - `Temporary - ~id:"nonce.too_early_revelation" - ~title:"Too early nonce revelation" - ~description:"Nonce revelation happens before cycle end" - ~pp:(fun ppf () -> - Format.fprintf ppf "This nonce should not yet be revealed") - Data_encoding.unit - (function Too_early_revelation -> Some () | _ -> None) - (fun () -> Too_early_revelation) ; - register_error_kind - `Branch - ~id:"nonce.previously_revealed" - ~title:"Previously revealed nonce" - ~description:"Duplicated revelation for a nonce." - ~pp:(fun ppf () -> Format.fprintf ppf "This nonce was previously revealed") - Data_encoding.unit - (function Previously_revealed_nonce -> Some () | _ -> None) - (fun () -> Previously_revealed_nonce) ; - register_error_kind - `Branch - ~id:"nonce.inconsistent" - ~title:"Inconsistent nonce" - ~description: - "The provided nonce is inconsistent with the committed nonce hash." - ~pp:(fun ppf () -> - Format.fprintf - ppf - "This nonce revelation is invalid (inconsistent with the committed \ - hash)") - Data_encoding.unit - (function Inconsistent_nonce -> Some () | _ -> None) - (fun () -> Inconsistent_nonce) - -(* checks that the level of a revelation is not too early or too late wrt to the - current context and that a nonce has not been already revealed for that level *) -let get_unrevealed ctxt (level : Level_repr.t) = - let cur_level = Level_storage.current ctxt in - match Cycle_repr.pred cur_level.cycle with - | None -> fail Too_early_revelation (* no revelations during cycle 0 *) - | Some revealed_cycle -> ( - if Cycle_repr.(revealed_cycle < level.Level_repr.cycle) then - fail Too_early_revelation - else if Cycle_repr.(level.Level_repr.cycle < revealed_cycle) then - fail Too_late_revelation - else - Storage.Seed.Nonce.get ctxt level >>=? function - | Revealed _ -> fail Previously_revealed_nonce - | Unrevealed status -> return status) - -let record_hash ctxt unrevealed = - let level = Level_storage.current ctxt in - Storage.Seed.Nonce.init ctxt level (Unrevealed unrevealed) - -let reveal ctxt level nonce = - get_unrevealed ctxt level >>=? fun unrevealed -> - error_unless - (Seed_repr.check_hash nonce unrevealed.nonce_hash) - Inconsistent_nonce - >>?= fun () -> Storage.Seed.Nonce.update ctxt level (Revealed nonce) - -type unrevealed = Storage.Seed.unrevealed_nonce = { - nonce_hash : Nonce_hash.t; - delegate : Signature.Public_key_hash.t; -} - -type status = Storage.Seed.nonce_status = - | Unrevealed of unrevealed - | Revealed of Seed_repr.nonce - -let get = Storage.Seed.Nonce.get - -type nonce_presence = No_nonce_expected | Nonce_expected of status - -let check ctxt level = - Storage.Seed.Nonce.find ctxt level >>=? function - | None -> return No_nonce_expected - | Some status -> return (Nonce_expected status) - -let of_bytes = Seed_repr.make_nonce - -let hash = Seed_repr.hash - -let check_hash = Seed_repr.check_hash diff --git a/src/proto_012_Psithaca/lib_protocol/nonce_storage.mli b/src/proto_012_Psithaca/lib_protocol/nonce_storage.mli deleted file mode 100644 index 16147031052e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/nonce_storage.mli +++ /dev/null @@ -1,60 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | Too_late_revelation - | Too_early_revelation - | Previously_revealed_nonce - | Inconsistent_nonce - -type t = Seed_repr.nonce - -type nonce = t - -val encoding : nonce Data_encoding.t - -type unrevealed = Storage.Seed.unrevealed_nonce = { - nonce_hash : Nonce_hash.t; - delegate : Signature.Public_key_hash.t; -} - -type status = Unrevealed of unrevealed | Revealed of Seed_repr.nonce - -val get : Raw_context.t -> Level_repr.t -> status tzresult Lwt.t - -type nonce_presence = No_nonce_expected | Nonce_expected of status - -val check : Raw_context.t -> Level_repr.t -> nonce_presence tzresult Lwt.t - -val record_hash : Raw_context.t -> unrevealed -> Raw_context.t tzresult Lwt.t - -val reveal : - Raw_context.t -> Level_repr.t -> nonce -> Raw_context.t tzresult Lwt.t - -val of_bytes : bytes -> nonce tzresult - -val hash : nonce -> Nonce_hash.t - -val check_hash : nonce -> Nonce_hash.t -> bool diff --git a/src/proto_012_Psithaca/lib_protocol/operation_repr.ml b/src/proto_012_Psithaca/lib_protocol/operation_repr.ml deleted file mode 100644 index 5db0a3162834..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/operation_repr.ml +++ /dev/null @@ -1,1149 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Tezos Protocol Implementation - Low level Repr. of Operations *) - -module Kind = struct - type preendorsement_consensus_kind = Preendorsement_consensus_kind - - type endorsement_consensus_kind = Endorsement_consensus_kind - - type 'a consensus = - | Preendorsement_kind : preendorsement_consensus_kind consensus - | Endorsement_kind : endorsement_consensus_kind consensus - - type preendorsement = preendorsement_consensus_kind consensus - - type endorsement = endorsement_consensus_kind consensus - - type seed_nonce_revelation = Seed_nonce_revelation_kind - - type 'a double_consensus_operation_evidence = - | Double_consensus_operation_evidence - - type double_endorsement_evidence = - endorsement_consensus_kind double_consensus_operation_evidence - - type double_preendorsement_evidence = - preendorsement_consensus_kind double_consensus_operation_evidence - - type double_baking_evidence = Double_baking_evidence_kind - - type activate_account = Activate_account_kind - - type proposals = Proposals_kind - - type ballot = Ballot_kind - - type reveal = Reveal_kind - - type transaction = Transaction_kind - - type origination = Origination_kind - - type delegation = Delegation_kind - - type set_deposits_limit = Set_deposits_limit_kind - - type failing_noop = Failing_noop_kind - - type register_global_constant = Register_global_constant_kind - - type 'a manager = - | Reveal_manager_kind : reveal manager - | Transaction_manager_kind : transaction manager - | Origination_manager_kind : origination manager - | Delegation_manager_kind : delegation manager - | Register_global_constant_manager_kind : register_global_constant manager - | Set_deposits_limit_manager_kind : set_deposits_limit manager -end - -type 'a consensus_operation_type = - | Endorsement : Kind.endorsement consensus_operation_type - | Preendorsement : Kind.preendorsement consensus_operation_type - -let pp_operation_kind (type kind) ppf - (operation_kind : kind consensus_operation_type) = - match operation_kind with - | Endorsement -> Format.fprintf ppf "Endorsement" - | Preendorsement -> Format.fprintf ppf "Preendorsement" - -type consensus_content = { - slot : Slot_repr.t; - level : Raw_level_repr.t; - (* The level is not required to validate an endorsement when it corresponds - to the current payload, but if we want to filter endorsements, we need - the level. *) - round : Round_repr.t; - block_payload_hash : Block_payload_hash.t; - (* NOTE: This could be just the hash of the set of operations (the - actual payload). The grandfather block hash should already be - fixed by the operation.shell.branch field. This is not really - important but could make things easier for debugging *) -} - -let consensus_content_encoding = - let open Data_encoding in - conv - (fun {slot; level; round; block_payload_hash} -> - (slot, level, round, block_payload_hash)) - (fun (slot, level, round, block_payload_hash) -> - {slot; level; round; block_payload_hash}) - (obj4 - (req "slot" Slot_repr.encoding) - (req "level" Raw_level_repr.encoding) - (req "round" Round_repr.encoding) - (req "block_payload_hash" Block_payload_hash.encoding)) - -let pp_consensus_content ppf content = - Format.fprintf - ppf - "(%ld, %a, %a, %a)" - (Raw_level_repr.to_int32 content.level) - Round_repr.pp - content.round - Slot_repr.pp - content.slot - Block_payload_hash.pp_short - content.block_payload_hash - -type consensus_watermark = - | Endorsement of Chain_id.t - | Preendorsement of Chain_id.t - -let bytes_of_consensus_watermark = function - | Preendorsement chain_id -> - Bytes.cat (Bytes.of_string "\x12") (Chain_id.to_bytes chain_id) - | Endorsement chain_id -> - Bytes.cat (Bytes.of_string "\x13") (Chain_id.to_bytes chain_id) - -let to_watermark w = Signature.Custom (bytes_of_consensus_watermark w) - -let of_watermark = function - | Signature.Custom b -> - if Compare.Int.(Bytes.length b > 0) then - match Bytes.get b 0 with - | '\x12' -> - Option.map - (fun chain_id -> Endorsement chain_id) - (Chain_id.of_bytes_opt (Bytes.sub b 1 (Bytes.length b - 1))) - | '\x13' -> - Option.map - (fun chain_id -> Preendorsement chain_id) - (Chain_id.of_bytes_opt (Bytes.sub b 1 (Bytes.length b - 1))) - | _ -> None - else None - | _ -> None - -type raw = Operation.t = {shell : Operation.shell_header; proto : bytes} - -let raw_encoding = Operation.encoding - -type 'kind operation = { - shell : Operation.shell_header; - protocol_data : 'kind protocol_data; -} - -and 'kind protocol_data = { - contents : 'kind contents_list; - signature : Signature.t option; -} - -and _ contents_list = - | Single : 'kind contents -> 'kind contents_list - | Cons : - 'kind Kind.manager contents * 'rest Kind.manager contents_list - -> ('kind * 'rest) Kind.manager contents_list - -and _ contents = - | Preendorsement : consensus_content -> Kind.preendorsement contents - | Endorsement : consensus_content -> Kind.endorsement contents - | Seed_nonce_revelation : { - level : Raw_level_repr.t; - nonce : Seed_repr.nonce; - } - -> Kind.seed_nonce_revelation contents - | Double_preendorsement_evidence : { - op1 : Kind.preendorsement operation; - op2 : Kind.preendorsement operation; - } - -> Kind.double_preendorsement_evidence contents - | Double_endorsement_evidence : { - op1 : Kind.endorsement operation; - op2 : Kind.endorsement operation; - } - -> Kind.double_endorsement_evidence contents - | Double_baking_evidence : { - bh1 : Block_header_repr.t; - bh2 : Block_header_repr.t; - } - -> Kind.double_baking_evidence contents - | Activate_account : { - id : Ed25519.Public_key_hash.t; - activation_code : Blinded_public_key_hash.activation_code; - } - -> Kind.activate_account contents - | Proposals : { - source : Signature.Public_key_hash.t; - period : int32; - proposals : Protocol_hash.t list; - } - -> Kind.proposals contents - | Ballot : { - source : Signature.Public_key_hash.t; - period : int32; - proposal : Protocol_hash.t; - ballot : Vote_repr.ballot; - } - -> Kind.ballot contents - | Failing_noop : string -> Kind.failing_noop contents - | Manager_operation : { - source : Signature.public_key_hash; - fee : Tez_repr.tez; - counter : counter; - operation : 'kind manager_operation; - gas_limit : Gas_limit_repr.Arith.integral; - storage_limit : Z.t; - } - -> 'kind Kind.manager contents - -and _ manager_operation = - | Reveal : Signature.Public_key.t -> Kind.reveal manager_operation - | Transaction : { - amount : Tez_repr.tez; - parameters : Script_repr.lazy_expr; - entrypoint : string; - destination : Contract_repr.contract; - } - -> Kind.transaction manager_operation - | Origination : { - delegate : Signature.Public_key_hash.t option; - script : Script_repr.t; - credit : Tez_repr.tez; - preorigination : Contract_repr.t option; - } - -> Kind.origination manager_operation - | Delegation : - Signature.Public_key_hash.t option - -> Kind.delegation manager_operation - | Register_global_constant : { - value : Script_repr.lazy_expr; - } - -> Kind.register_global_constant manager_operation - | Set_deposits_limit : - Tez_repr.t option - -> Kind.set_deposits_limit manager_operation - -and counter = Z.t - -let manager_kind : type kind. kind manager_operation -> kind Kind.manager = - function - | Reveal _ -> Kind.Reveal_manager_kind - | Transaction _ -> Kind.Transaction_manager_kind - | Origination _ -> Kind.Origination_manager_kind - | Delegation _ -> Kind.Delegation_manager_kind - | Register_global_constant _ -> Kind.Register_global_constant_manager_kind - | Set_deposits_limit _ -> Kind.Set_deposits_limit_manager_kind - -type 'kind internal_operation = { - source : Contract_repr.contract; - operation : 'kind manager_operation; - nonce : int; -} - -type packed_manager_operation = - | Manager : 'kind manager_operation -> packed_manager_operation - -type packed_contents = Contents : 'kind contents -> packed_contents - -type packed_contents_list = - | Contents_list : 'kind contents_list -> packed_contents_list - -type packed_protocol_data = - | Operation_data : 'kind protocol_data -> packed_protocol_data - -type packed_operation = { - shell : Operation.shell_header; - protocol_data : packed_protocol_data; -} - -let pack ({shell; protocol_data} : _ operation) : packed_operation = - {shell; protocol_data = Operation_data protocol_data} - -type packed_internal_operation = - | Internal_operation : 'kind internal_operation -> packed_internal_operation - -let rec to_list = function - | Contents_list (Single o) -> [Contents o] - | Contents_list (Cons (o, os)) -> Contents o :: to_list (Contents_list os) - -(* This first version of of_list has the type (_, string) result expected by - the conv_with_guard combinator of Data_encoding. For a more conventional - return type see [of_list] below. *) -let rec of_list_internal = function - | [] -> Error "Operation lists should not be empty." - | [Contents o] -> Ok (Contents_list (Single o)) - | Contents o :: os -> ( - of_list_internal os >>? fun (Contents_list os) -> - match (o, os) with - | (Manager_operation _, Single (Manager_operation _)) -> - Ok (Contents_list (Cons (o, os))) - | (Manager_operation _, Cons _) -> Ok (Contents_list (Cons (o, os))) - | _ -> - Error - "Operation list of length > 1 should only contains manager \ - operations.") - -type error += Contents_list_error of string (* `Permanent *) - -let of_list l = - match of_list_internal l with - | Ok contents -> Ok contents - | Error s -> error @@ Contents_list_error s - -module Encoding = struct - open Data_encoding - - let case tag name args proj inj = - case - tag - ~title:(String.capitalize_ascii name) - (merge_objs (obj1 (req "kind" (constant name))) args) - (fun x -> match proj x with None -> None | Some x -> Some ((), x)) - (fun ((), x) -> inj x) - - module Manager_operations = struct - type 'kind case = - | MCase : { - tag : int; - name : string; - encoding : 'a Data_encoding.t; - select : packed_manager_operation -> 'kind manager_operation option; - proj : 'kind manager_operation -> 'a; - inj : 'a -> 'kind manager_operation; - } - -> 'kind case - [@@coq_force_gadt] - - let[@coq_axiom_with_reason "gadt"] reveal_case = - MCase - { - tag = 0; - name = "reveal"; - encoding = obj1 (req "public_key" Signature.Public_key.encoding); - select = (function Manager (Reveal _ as op) -> Some op | _ -> None); - proj = (function Reveal pkh -> pkh); - inj = (fun pkh -> Reveal pkh); - } - - let entrypoint_encoding = - def - ~title:"entrypoint" - ~description:"Named entrypoint to a Michelson smart contract" - "entrypoint" - @@ - let builtin_case tag name = - Data_encoding.case - (Tag tag) - ~title:name - (constant name) - (fun n -> if Compare.String.(n = name) then Some () else None) - (fun () -> name) - in - union - [ - builtin_case 0 "default"; - builtin_case 1 "root"; - builtin_case 2 "do"; - builtin_case 3 "set_delegate"; - builtin_case 4 "remove_delegate"; - Data_encoding.case - (Tag 255) - ~title:"named" - (Bounded.string 31) - (fun s -> Some s) - (fun s -> s); - ] - - let[@coq_axiom_with_reason "gadt"] transaction_case = - MCase - { - tag = 1; - name = "transaction"; - encoding = - obj3 - (req "amount" Tez_repr.encoding) - (req "destination" Contract_repr.encoding) - (opt - "parameters" - (obj2 - (req "entrypoint" entrypoint_encoding) - (req "value" Script_repr.lazy_expr_encoding))); - select = - (function Manager (Transaction _ as op) -> Some op | _ -> None); - proj = - (function - | Transaction {amount; destination; parameters; entrypoint} -> - let parameters = - if - Script_repr.is_unit_parameter parameters - && Compare.String.(entrypoint = "default") - then None - else Some (entrypoint, parameters) - in - (amount, destination, parameters)); - inj = - (fun (amount, destination, parameters) -> - let (entrypoint, parameters) = - match parameters with - | None -> ("default", Script_repr.unit_parameter) - | Some (entrypoint, value) -> (entrypoint, value) - in - Transaction {amount; destination; parameters; entrypoint}); - } - - let[@coq_axiom_with_reason "gadt"] origination_case = - MCase - { - tag = 2; - name = "origination"; - encoding = - obj3 - (req "balance" Tez_repr.encoding) - (opt "delegate" Signature.Public_key_hash.encoding) - (req "script" Script_repr.encoding); - select = - (function Manager (Origination _ as op) -> Some op | _ -> None); - proj = - (function - | Origination - { - credit; - delegate; - script; - preorigination = - _ - (* the hash is only used internally - when originating from smart - contracts, don't serialize it *); - } -> - (credit, delegate, script)); - inj = - (fun (credit, delegate, script) -> - Origination {credit; delegate; script; preorigination = None}); - } - - let[@coq_axiom_with_reason "gadt"] delegation_case = - MCase - { - tag = 3; - name = "delegation"; - encoding = obj1 (opt "delegate" Signature.Public_key_hash.encoding); - select = - (function Manager (Delegation _ as op) -> Some op | _ -> None); - proj = (function Delegation key -> key); - inj = (fun key -> Delegation key); - } - - let[@coq_axiom_with_reason "gadt"] register_global_constant_case = - MCase - { - tag = 4; - name = "register_global_constant"; - encoding = obj1 (req "value" Script_repr.lazy_expr_encoding); - select = - (function - | Manager (Register_global_constant _ as op) -> Some op | _ -> None); - proj = (function Register_global_constant {value} -> value); - inj = (fun value -> Register_global_constant {value}); - } - - let[@coq_axiom_with_reason "gadt"] set_deposits_limit_case = - MCase - { - tag = 5; - name = "set_deposits_limit"; - encoding = obj1 (opt "limit" Tez_repr.encoding); - select = - (function - | Manager (Set_deposits_limit _ as op) -> Some op | _ -> None); - proj = (function Set_deposits_limit key -> key); - inj = (fun key -> Set_deposits_limit key); - } - - let encoding = - let make (MCase {tag; name; encoding; select; proj; inj}) = - case - (Tag tag) - name - encoding - (fun o -> - match select o with None -> None | Some o -> Some (proj o)) - (fun x -> Manager (inj x)) - in - union - ~tag_size:`Uint8 - [ - make reveal_case; - make transaction_case; - make origination_case; - make delegation_case; - make register_global_constant_case; - make set_deposits_limit_case; - ] - end - - type 'b case = - | Case : { - tag : int; - name : string; - encoding : 'a Data_encoding.t; - select : packed_contents -> 'b contents option; - proj : 'b contents -> 'a; - inj : 'a -> 'b contents; - } - -> 'b case - - let preendorsement_case = - Case - { - tag = 20; - (* Preendorsement where added after *) - name = "preendorsement"; - encoding = consensus_content_encoding; - select = - (function Contents (Preendorsement _ as op) -> Some op | _ -> None); - proj = (fun (Preendorsement preendorsement) -> preendorsement); - inj = (fun preendorsement -> Preendorsement preendorsement); - } - - (* Defined before endorsement encoding because this is used there *) - let preendorsement_encoding = - let make (Case {tag; name; encoding; select = _; proj; inj}) = - case (Tag tag) name encoding (fun o -> Some (proj o)) (fun x -> inj x) - in - let to_list : Kind.preendorsement contents_list -> _ = function - | Single o -> o - in - let of_list : Kind.preendorsement contents -> _ = function - | o -> Single o - in - def "inlined.preendorsement" - @@ conv - (fun ({shell; protocol_data = {contents; signature}} : _ operation) -> - (shell, (contents, signature))) - (fun (shell, (contents, signature)) : _ operation -> - {shell; protocol_data = {contents; signature}}) - (merge_objs - Operation.shell_header_encoding - (obj2 - (req - "operations" - (conv to_list of_list - @@ def "inlined.preendorsement.contents" - @@ union [make preendorsement_case])) - (varopt "signature" Signature.encoding))) - - let endorsement_encoding = - obj4 - (req "slot" Slot_repr.encoding) - (req "level" Raw_level_repr.encoding) - (req "round" Round_repr.encoding) - (req "block_payload_hash" Block_payload_hash.encoding) - - let endorsement_case = - Case - { - tag = 21; - name = "endorsement"; - encoding = endorsement_encoding; - select = - (function Contents (Endorsement _ as op) -> Some op | _ -> None); - proj = - (fun [@coq_match_with_default] (Endorsement consensus_content) -> - ( consensus_content.slot, - consensus_content.level, - consensus_content.round, - consensus_content.block_payload_hash )); - inj = - (fun (slot, level, round, block_payload_hash) -> - Endorsement {slot; level; round; block_payload_hash}); - } - - let[@coq_axiom_with_reason "gadt"] endorsement_encoding = - let make (Case {tag; name; encoding; select = _; proj; inj}) = - case (Tag tag) name encoding (fun o -> Some (proj o)) (fun x -> inj x) - in - let to_list : Kind.endorsement contents_list -> _ = fun (Single o) -> o in - let of_list : Kind.endorsement contents -> _ = fun o -> Single o in - def "inlined.endorsement" - @@ conv - (fun ({shell; protocol_data = {contents; signature}} : _ operation) -> - (shell, (contents, signature))) - (fun (shell, (contents, signature)) : _ operation -> - {shell; protocol_data = {contents; signature}}) - (merge_objs - Operation.shell_header_encoding - (obj2 - (req - "operations" - (conv to_list of_list - @@ def "inlined.endorsement_mempool.contents" - @@ union [make endorsement_case])) - (varopt "signature" Signature.encoding))) - - let[@coq_axiom_with_reason "gadt"] seed_nonce_revelation_case = - Case - { - tag = 1; - name = "seed_nonce_revelation"; - encoding = - obj2 - (req "level" Raw_level_repr.encoding) - (req "nonce" Seed_repr.nonce_encoding); - select = - (function - | Contents (Seed_nonce_revelation _ as op) -> Some op | _ -> None); - proj = (fun (Seed_nonce_revelation {level; nonce}) -> (level, nonce)); - inj = (fun (level, nonce) -> Seed_nonce_revelation {level; nonce}); - } - - let[@coq_axiom_with_reason "gadt"] double_preendorsement_evidence_case : - Kind.double_preendorsement_evidence case = - Case - { - tag = 7; - name = "double_preendorsement_evidence"; - encoding = - obj2 - (req "op1" (dynamic_size preendorsement_encoding)) - (req "op2" (dynamic_size preendorsement_encoding)); - select = - (function - | Contents (Double_preendorsement_evidence _ as op) -> Some op - | _ -> None); - proj = (fun (Double_preendorsement_evidence {op1; op2}) -> (op1, op2)); - inj = (fun (op1, op2) -> Double_preendorsement_evidence {op1; op2}); - } - - let[@coq_axiom_with_reason "gadt"] double_endorsement_evidence_case : - Kind.double_endorsement_evidence case = - Case - { - tag = 2; - name = "double_endorsement_evidence"; - encoding = - obj2 - (req "op1" (dynamic_size endorsement_encoding)) - (req "op2" (dynamic_size endorsement_encoding)); - select = - (function - | Contents (Double_endorsement_evidence _ as op) -> Some op - | _ -> None); - proj = (fun (Double_endorsement_evidence {op1; op2}) -> (op1, op2)); - inj = (fun (op1, op2) -> Double_endorsement_evidence {op1; op2}); - } - - let[@coq_axiom_with_reason "gadt"] double_baking_evidence_case = - Case - { - tag = 3; - name = "double_baking_evidence"; - encoding = - obj2 - (req "bh1" (dynamic_size Block_header_repr.encoding)) - (req "bh2" (dynamic_size Block_header_repr.encoding)); - select = - (function - | Contents (Double_baking_evidence _ as op) -> Some op | _ -> None); - proj = (fun (Double_baking_evidence {bh1; bh2}) -> (bh1, bh2)); - inj = (fun (bh1, bh2) -> Double_baking_evidence {bh1; bh2}); - } - - let[@coq_axiom_with_reason "gadt"] activate_account_case = - Case - { - tag = 4; - name = "activate_account"; - encoding = - obj2 - (req "pkh" Ed25519.Public_key_hash.encoding) - (req "secret" Blinded_public_key_hash.activation_code_encoding); - select = - (function - | Contents (Activate_account _ as op) -> Some op | _ -> None); - proj = - (fun (Activate_account {id; activation_code}) -> - (id, activation_code)); - inj = - (fun (id, activation_code) -> Activate_account {id; activation_code}); - } - - let[@coq_axiom_with_reason "gadt"] proposals_case = - Case - { - tag = 5; - name = "proposals"; - encoding = - obj3 - (req "source" Signature.Public_key_hash.encoding) - (req "period" int32) - (req "proposals" (list Protocol_hash.encoding)); - select = - (function Contents (Proposals _ as op) -> Some op | _ -> None); - proj = - (fun (Proposals {source; period; proposals}) -> - (source, period, proposals)); - inj = - (fun (source, period, proposals) -> - Proposals {source; period; proposals}); - } - - let[@coq_axiom_with_reason "gadt"] ballot_case = - Case - { - tag = 6; - name = "ballot"; - encoding = - obj4 - (req "source" Signature.Public_key_hash.encoding) - (req "period" int32) - (req "proposal" Protocol_hash.encoding) - (req "ballot" Vote_repr.ballot_encoding); - select = (function Contents (Ballot _ as op) -> Some op | _ -> None); - proj = - (function - | Ballot {source; period; proposal; ballot} -> - (source, period, proposal, ballot)); - inj = - (fun (source, period, proposal, ballot) -> - Ballot {source; period; proposal; ballot}); - } - - let failing_noop_case = - Case - { - tag = 17; - name = "failing_noop"; - encoding = obj1 (req "arbitrary" Data_encoding.string); - select = - (function Contents (Failing_noop _ as op) -> Some op | _ -> None); - proj = - (function[@coq_match_with_default] Failing_noop message -> message); - inj = (function message -> Failing_noop message); - } - - let manager_encoding = - obj5 - (req "source" Signature.Public_key_hash.encoding) - (req "fee" Tez_repr.encoding) - (req "counter" (check_size 10 n)) - (req "gas_limit" (check_size 10 Gas_limit_repr.Arith.n_integral_encoding)) - (req "storage_limit" (check_size 10 n)) - - let extract : type kind. kind Kind.manager contents -> _ = - function[@coq_match_with_default] - | Manager_operation - {source; fee; counter; gas_limit; storage_limit; operation = _} -> - (source, fee, counter, gas_limit, storage_limit) - - let rebuild (source, fee, counter, gas_limit, storage_limit) operation = - Manager_operation - {source; fee; counter; gas_limit; storage_limit; operation} - - let[@coq_axiom_with_reason "gadt"] make_manager_case tag (type kind) - (Manager_operations.MCase mcase : kind Manager_operations.case) = - Case - { - tag; - name = mcase.name; - encoding = merge_objs manager_encoding mcase.encoding; - select = - (function - | Contents (Manager_operation ({operation; _} as op)) -> ( - match mcase.select (Manager operation) with - | None -> None - | Some operation -> Some (Manager_operation {op with operation})) - | _ -> None); - proj = - (function - | Manager_operation {operation; _} as op -> - (extract op, mcase.proj operation)); - inj = (fun (op, contents) -> rebuild op (mcase.inj contents)); - } - - let reveal_case = make_manager_case 107 Manager_operations.reveal_case - - let transaction_case = - make_manager_case 108 Manager_operations.transaction_case - - let origination_case = - make_manager_case 109 Manager_operations.origination_case - - let delegation_case = make_manager_case 110 Manager_operations.delegation_case - - let register_global_constant_case = - make_manager_case 111 Manager_operations.register_global_constant_case - - let set_deposits_limit_case = - make_manager_case 112 Manager_operations.set_deposits_limit_case - - let contents_encoding = - let make (Case {tag; name; encoding; select; proj; inj}) = - case - (Tag tag) - name - encoding - (fun o -> match select o with None -> None | Some o -> Some (proj o)) - (fun x -> Contents (inj x)) - in - def "operation.alpha.contents" - @@ union - [ - make endorsement_case; - make preendorsement_case; - make seed_nonce_revelation_case; - make double_endorsement_evidence_case; - make double_preendorsement_evidence_case; - make double_baking_evidence_case; - make activate_account_case; - make proposals_case; - make ballot_case; - make reveal_case; - make transaction_case; - make origination_case; - make delegation_case; - make set_deposits_limit_case; - make failing_noop_case; - make register_global_constant_case; - ] - - let contents_list_encoding = - conv_with_guard to_list of_list_internal (Variable.list contents_encoding) - - let optional_signature_encoding = - conv - (function Some s -> s | None -> Signature.zero) - (fun s -> if Signature.equal s Signature.zero then None else Some s) - Signature.encoding - - let protocol_data_encoding = - def "operation.alpha.contents_and_signature" - @@ conv - (fun (Operation_data {contents; signature}) -> - (Contents_list contents, signature)) - (fun (Contents_list contents, signature) -> - Operation_data {contents; signature}) - (obj2 - (req "contents" contents_list_encoding) - (req "signature" optional_signature_encoding)) - - let operation_encoding = - conv - (fun {shell; protocol_data} -> (shell, protocol_data)) - (fun (shell, protocol_data) -> {shell; protocol_data}) - (merge_objs Operation.shell_header_encoding protocol_data_encoding) - - let unsigned_operation_encoding = - def "operation.alpha.unsigned_operation" - @@ merge_objs - Operation.shell_header_encoding - (obj1 (req "contents" contents_list_encoding)) - - let internal_operation_encoding = - def "operation.alpha.internal_operation" - @@ conv - (fun (Internal_operation {source; operation; nonce}) -> - ((source, nonce), Manager operation)) - (fun ((source, nonce), Manager operation) -> - Internal_operation {source; operation; nonce}) - (merge_objs - (obj2 (req "source" Contract_repr.encoding) (req "nonce" uint16)) - Manager_operations.encoding) -end - -let encoding = Encoding.operation_encoding - -let contents_encoding = Encoding.contents_encoding - -let contents_list_encoding = Encoding.contents_list_encoding - -let protocol_data_encoding = Encoding.protocol_data_encoding - -let unsigned_operation_encoding = Encoding.unsigned_operation_encoding - -let internal_operation_encoding = Encoding.internal_operation_encoding - -let raw ({shell; protocol_data} : _ operation) = - let proto = - Data_encoding.Binary.to_bytes_exn - protocol_data_encoding - (Operation_data protocol_data) - in - {Operation.shell; proto} - -let acceptable_passes (op : packed_operation) = - let (Operation_data protocol_data) = op.protocol_data in - match protocol_data.contents with - | Single (Failing_noop _) -> [] - | Single (Preendorsement _) -> [0] - | Single (Endorsement _) -> [0] - | Single (Proposals _) -> [1] - | Single (Ballot _) -> [1] - | Single (Seed_nonce_revelation _) -> [2] - | Single (Double_endorsement_evidence _) -> [2] - | Single (Double_preendorsement_evidence _) -> [2] - | Single (Double_baking_evidence _) -> [2] - | Single (Activate_account _) -> [2] - | Single (Manager_operation _) -> [3] - | Cons (Manager_operation _, _ops) -> [3] - -type error += Invalid_signature (* `Permanent *) - -type error += Missing_signature (* `Permanent *) - -let () = - register_error_kind - `Permanent - ~id:"operation.invalid_signature" - ~title:"Invalid operation signature" - ~description: - "The operation signature is ill-formed or has been made with the wrong \ - public key" - ~pp:(fun ppf () -> Format.fprintf ppf "The operation signature is invalid") - Data_encoding.unit - (function Invalid_signature -> Some () | _ -> None) - (fun () -> Invalid_signature) ; - register_error_kind - `Permanent - ~id:"operation.missing_signature" - ~title:"Missing operation signature" - ~description: - "The operation is of a kind that must be signed, but the signature is \ - missing" - ~pp:(fun ppf () -> Format.fprintf ppf "The operation requires a signature") - Data_encoding.unit - (function Missing_signature -> Some () | _ -> None) - (fun () -> Missing_signature) ; - register_error_kind - `Permanent - ~id:"operation.contents_list_error" - ~title:"Invalid list of operation contents." - ~description: - "An operation contents list has an unexpected shape; it should be either \ - a single operation or a non-empty list of manager operations" - ~pp:(fun ppf s -> - Format.fprintf - ppf - "An operation contents list has an unexpected shape: %s" - s) - Data_encoding.(obj1 (req "message" string)) - (function Contents_list_error s -> Some s | _ -> None) - (fun s -> Contents_list_error s) - -let check_signature (type kind) key chain_id - ({shell; protocol_data} : kind operation) = - let check ~watermark contents signature = - let unsigned_operation = - Data_encoding.Binary.to_bytes_exn - unsigned_operation_encoding - (shell, contents) - in - if Signature.check ~watermark key signature unsigned_operation then Ok () - else error Invalid_signature - in - match protocol_data.signature with - | None -> error Missing_signature - | Some signature -> ( - match protocol_data.contents with - | Single (Preendorsement _) as contents -> - check - ~watermark:(to_watermark (Preendorsement chain_id)) - (Contents_list contents) - signature - | Single (Endorsement _) as contents -> - check - ~watermark:(to_watermark (Endorsement chain_id)) - (Contents_list contents) - signature - | Single - ( Failing_noop _ | Proposals _ | Ballot _ | Seed_nonce_revelation _ - | Double_endorsement_evidence _ | Double_preendorsement_evidence _ - | Double_baking_evidence _ | Activate_account _ | Manager_operation _ - ) -> - check - ~watermark:Generic_operation - (Contents_list protocol_data.contents) - signature - | Cons (Manager_operation _, _ops) -> - check - ~watermark:Generic_operation - (Contents_list protocol_data.contents) - signature) - -let hash_raw = Operation.hash - -let hash (o : _ operation) = - let proto = - Data_encoding.Binary.to_bytes_exn - protocol_data_encoding - (Operation_data o.protocol_data) - in - Operation.hash {shell = o.shell; proto} - -let hash_packed (o : packed_operation) = - let proto = - Data_encoding.Binary.to_bytes_exn protocol_data_encoding o.protocol_data - in - Operation.hash {shell = o.shell; proto} - -type ('a, 'b) eq = Eq : ('a, 'a) eq [@@coq_force_gadt] - -let equal_manager_operation_kind : - type a b. a manager_operation -> b manager_operation -> (a, b) eq option = - fun op1 op2 -> - match (op1, op2) with - | (Reveal _, Reveal _) -> Some Eq - | (Reveal _, _) -> None - | (Transaction _, Transaction _) -> Some Eq - | (Transaction _, _) -> None - | (Origination _, Origination _) -> Some Eq - | (Origination _, _) -> None - | (Delegation _, Delegation _) -> Some Eq - | (Delegation _, _) -> None - | (Register_global_constant _, Register_global_constant _) -> Some Eq - | (Register_global_constant _, _) -> None - | (Set_deposits_limit _, Set_deposits_limit _) -> Some Eq - | (Set_deposits_limit _, _) -> None - -let equal_contents_kind : type a b. a contents -> b contents -> (a, b) eq option - = - fun op1 op2 -> - match (op1, op2) with - | (Preendorsement _, Preendorsement _) -> Some Eq - | (Preendorsement _, _) -> None - | (Endorsement _, Endorsement _) -> Some Eq - | (Endorsement _, _) -> None - | (Seed_nonce_revelation _, Seed_nonce_revelation _) -> Some Eq - | (Seed_nonce_revelation _, _) -> None - | (Double_endorsement_evidence _, Double_endorsement_evidence _) -> Some Eq - | (Double_endorsement_evidence _, _) -> None - | (Double_preendorsement_evidence _, Double_preendorsement_evidence _) -> - Some Eq - | (Double_preendorsement_evidence _, _) -> None - | (Double_baking_evidence _, Double_baking_evidence _) -> Some Eq - | (Double_baking_evidence _, _) -> None - | (Activate_account _, Activate_account _) -> Some Eq - | (Activate_account _, _) -> None - | (Proposals _, Proposals _) -> Some Eq - | (Proposals _, _) -> None - | (Ballot _, Ballot _) -> Some Eq - | (Ballot _, _) -> None - | (Failing_noop _, Failing_noop _) -> Some Eq - | (Failing_noop _, _) -> None - | (Manager_operation op1, Manager_operation op2) -> ( - match equal_manager_operation_kind op1.operation op2.operation with - | None -> None - | Some Eq -> Some Eq) - | (Manager_operation _, _) -> None - -let rec equal_contents_kind_list : - type a b. a contents_list -> b contents_list -> (a, b) eq option = - fun op1 op2 -> - match (op1, op2) with - | (Single op1, Single op2) -> equal_contents_kind op1 op2 - | (Single _, Cons _) -> None - | (Cons _, Single _) -> None - | (Cons (op1, ops1), Cons (op2, ops2)) -> ( - match equal_contents_kind op1 op2 with - | None -> None - | Some Eq -> ( - match equal_contents_kind_list ops1 ops2 with - | None -> None - | Some Eq -> Some Eq)) - -let equal : type a b. a operation -> b operation -> (a, b) eq option = - fun op1 op2 -> - if not (Operation_hash.equal (hash op1) (hash op2)) then None - else - equal_contents_kind_list - op1.protocol_data.contents - op2.protocol_data.contents - -open Cache_memory_helpers - -let script_lazy_expr_size (expr : Script_repr.lazy_expr) = - let fun_value expr = ret_adding (expr_size expr) word_size in - let fun_bytes bytes = (Nodes.zero, word_size +! bytes_size bytes) in - let fun_combine expr_size bytes_size = expr_size ++ bytes_size in - ret_adding - (Data_encoding.apply_lazy ~fun_value ~fun_bytes ~fun_combine expr) - header_size - -let script_repr_size ({code; storage} : Script_repr.t) = - ret_adding (script_lazy_expr_size code ++ script_lazy_expr_size storage) h2w - -let internal_manager_operation_size (type a) (op : a manager_operation) = - match op with - | Transaction {amount = _; parameters; entrypoint; destination} -> - ret_adding - (script_lazy_expr_size parameters) - (h4w +! int64_size - +! string_size_gen (String.length entrypoint) - +! Contract_repr.in_memory_size destination) - | Origination {delegate; script; credit = _; preorigination} -> - ret_adding - (script_repr_size script) - (h4w - +! option_size - (fun _ -> Contract_repr.public_key_hash_in_memory_size) - delegate - +! int64_size - +! option_size Contract_repr.in_memory_size preorigination) - | Delegation pkh_opt -> - ( Nodes.zero, - h1w - +! option_size - (fun _ -> Contract_repr.public_key_hash_in_memory_size) - pkh_opt ) - | Reveal _ -> - (* Reveals can't occur as internal operations *) - assert false - | Register_global_constant _ -> - (* Global constant registrations can't occur as internal operations *) - assert false - | Set_deposits_limit _ -> - (* Set_deposits_limit can't occur as internal operations *) - assert false - -let packed_internal_operation_in_memory_size : - packed_internal_operation -> nodes_and_size = function - | Internal_operation iop -> - let {source; operation; nonce = _} = iop in - let source_size = Contract_repr.in_memory_size source in - let nonce_size = word_size in - ret_adding - (internal_manager_operation_size operation) - (h2w +! source_size +! nonce_size) diff --git a/src/proto_012_Psithaca/lib_protocol/operation_repr.mli b/src/proto_012_Psithaca/lib_protocol/operation_repr.mli deleted file mode 100644 index 730ac686d0ad..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/operation_repr.mli +++ /dev/null @@ -1,377 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Tezos Protocol Implementation - Low level Repr. of Operations - - Defines kinds of operations that can be performed on chain: - - preendorsement - - endorsement - - double baking evidence - - double preendorsing evidence - - double endorsing evidence - - seed nonce revelation - - account activation - - proposal (see: [Voting_repr]) - - ballot (see: [Voting_repr]) - - failing noop - - manager operation (which in turn has several types): - - revelation - - transaction - - origination - - delegation - - set deposits limitation - - Each of them can be encoded as raw bytes. Operations are distinguished at - type level using phantom type parameters. [packed_operation] type allows - for unifying them when required, for instance to put them on a single - list. *) - -module Kind : sig - type preendorsement_consensus_kind = Preendorsement_consensus_kind - - type endorsement_consensus_kind = Endorsement_consensus_kind - - type 'a consensus = - | Preendorsement_kind : preendorsement_consensus_kind consensus - | Endorsement_kind : endorsement_consensus_kind consensus - - type preendorsement = preendorsement_consensus_kind consensus - - type endorsement = endorsement_consensus_kind consensus - - type seed_nonce_revelation = Seed_nonce_revelation_kind - - type 'a double_consensus_operation_evidence = - | Double_consensus_operation_evidence - - type double_endorsement_evidence = - endorsement_consensus_kind double_consensus_operation_evidence - - type double_preendorsement_evidence = - preendorsement_consensus_kind double_consensus_operation_evidence - - type double_baking_evidence = Double_baking_evidence_kind - - type activate_account = Activate_account_kind - - type proposals = Proposals_kind - - type ballot = Ballot_kind - - type reveal = Reveal_kind - - type transaction = Transaction_kind - - type origination = Origination_kind - - type delegation = Delegation_kind - - type set_deposits_limit = Set_deposits_limit_kind - - type failing_noop = Failing_noop_kind - - type register_global_constant = Register_global_constant_kind - - type 'a manager = - | Reveal_manager_kind : reveal manager - | Transaction_manager_kind : transaction manager - | Origination_manager_kind : origination manager - | Delegation_manager_kind : delegation manager - | Register_global_constant_manager_kind : register_global_constant manager - | Set_deposits_limit_manager_kind : set_deposits_limit manager -end - -type 'a consensus_operation_type = - | Endorsement : Kind.endorsement consensus_operation_type - | Preendorsement : Kind.preendorsement consensus_operation_type - -val pp_operation_kind : - Format.formatter -> 'kind consensus_operation_type -> unit - -type consensus_content = { - slot : Slot_repr.t; - (* By convention, this is the validator's first slot. *) - level : Raw_level_repr.t; - (* The level of (pre)endorsed block. *) - round : Round_repr.t; - (* The round of (pre)endorsed block. *) - block_payload_hash : Block_payload_hash.t; - (* The payload hash of (pre)endorsed block. *) -} - -val consensus_content_encoding : consensus_content Data_encoding.t - -val pp_consensus_content : Format.formatter -> consensus_content -> unit - -type consensus_watermark = - | Endorsement of Chain_id.t - | Preendorsement of Chain_id.t - -val to_watermark : consensus_watermark -> Signature.watermark - -val of_watermark : Signature.watermark -> consensus_watermark option - -type raw = Operation.t = {shell : Operation.shell_header; proto : bytes} - -val raw_encoding : raw Data_encoding.t - -type 'kind operation = { - shell : Operation.shell_header; - protocol_data : 'kind protocol_data; -} - -and 'kind protocol_data = { - contents : 'kind contents_list; - signature : Signature.t option; -} - -and _ contents_list = - | Single : 'kind contents -> 'kind contents_list - | Cons : - 'kind Kind.manager contents * 'rest Kind.manager contents_list - -> ('kind * 'rest) Kind.manager contents_list - -and _ contents = - | Preendorsement : consensus_content -> Kind.preendorsement contents - | Endorsement : consensus_content -> Kind.endorsement contents - | Seed_nonce_revelation : { - level : Raw_level_repr.t; - nonce : Seed_repr.nonce; - } - -> Kind.seed_nonce_revelation contents - | Double_preendorsement_evidence : { - op1 : Kind.preendorsement operation; - op2 : Kind.preendorsement operation; - } - -> Kind.double_preendorsement_evidence contents - | Double_endorsement_evidence : { - op1 : Kind.endorsement operation; - op2 : Kind.endorsement operation; - } - -> Kind.double_endorsement_evidence contents - | Double_baking_evidence : { - bh1 : Block_header_repr.t; - bh2 : Block_header_repr.t; - } - -> Kind.double_baking_evidence contents - | Activate_account : { - id : Ed25519.Public_key_hash.t; - activation_code : Blinded_public_key_hash.activation_code; - } - -> Kind.activate_account contents - | Proposals : { - source : Signature.Public_key_hash.t; - period : int32; - proposals : Protocol_hash.t list; - } - -> Kind.proposals contents - | Ballot : { - source : Signature.Public_key_hash.t; - period : int32; - proposal : Protocol_hash.t; - ballot : Vote_repr.ballot; - } - -> Kind.ballot contents - | Failing_noop : string -> Kind.failing_noop contents - | Manager_operation : { - source : Signature.Public_key_hash.t; - fee : Tez_repr.tez; - counter : counter; - operation : 'kind manager_operation; - gas_limit : Gas_limit_repr.Arith.integral; - storage_limit : Z.t; - } - -> 'kind Kind.manager contents - -and _ manager_operation = - | Reveal : Signature.Public_key.t -> Kind.reveal manager_operation - | Transaction : { - amount : Tez_repr.tez; - parameters : Script_repr.lazy_expr; - entrypoint : string; - destination : Contract_repr.contract; - } - -> Kind.transaction manager_operation - | Origination : { - delegate : Signature.Public_key_hash.t option; - script : Script_repr.t; - credit : Tez_repr.tez; - preorigination : Contract_repr.t option; - } - -> Kind.origination manager_operation - | Delegation : - Signature.Public_key_hash.t option - -> Kind.delegation manager_operation - | Register_global_constant : { - value : Script_repr.lazy_expr; - } - -> Kind.register_global_constant manager_operation - | Set_deposits_limit : - Tez_repr.t option - -> Kind.set_deposits_limit manager_operation - -and counter = Z.t - -type 'kind internal_operation = { - source : Contract_repr.contract; - operation : 'kind manager_operation; - nonce : int; -} - -type packed_manager_operation = - | Manager : 'kind manager_operation -> packed_manager_operation - -type packed_contents = Contents : 'kind contents -> packed_contents - -type packed_contents_list = - | Contents_list : 'kind contents_list -> packed_contents_list - -val of_list : packed_contents list -> packed_contents_list tzresult - -val to_list : packed_contents_list -> packed_contents list - -type packed_protocol_data = - | Operation_data : 'kind protocol_data -> packed_protocol_data - -type packed_operation = { - shell : Operation.shell_header; - protocol_data : packed_protocol_data; -} - -val pack : 'kind operation -> packed_operation - -type packed_internal_operation = - | Internal_operation : 'kind internal_operation -> packed_internal_operation - -val manager_kind : 'kind manager_operation -> 'kind Kind.manager - -val encoding : packed_operation Data_encoding.t - -val contents_encoding : packed_contents Data_encoding.t - -val contents_list_encoding : packed_contents_list Data_encoding.t - -val protocol_data_encoding : packed_protocol_data Data_encoding.t - -val unsigned_operation_encoding : - (Operation.shell_header * packed_contents_list) Data_encoding.t - -val raw : _ operation -> raw - -val hash_raw : raw -> Operation_hash.t - -val hash : _ operation -> Operation_hash.t - -val hash_packed : packed_operation -> Operation_hash.t - -val acceptable_passes : packed_operation -> int list - -type error += Missing_signature (* `Permanent *) - -type error += Invalid_signature (* `Permanent *) - -val check_signature : - Signature.Public_key.t -> Chain_id.t -> _ operation -> unit tzresult - -val internal_operation_encoding : packed_internal_operation Data_encoding.t - -type ('a, 'b) eq = Eq : ('a, 'a) eq - -val equal : 'a operation -> 'b operation -> ('a, 'b) eq option - -val packed_internal_operation_in_memory_size : - packed_internal_operation -> Cache_memory_helpers.nodes_and_size - -module Encoding : sig - type 'b case = - | Case : { - tag : int; - name : string; - encoding : 'a Data_encoding.t; - select : packed_contents -> 'b contents option; - proj : 'b contents -> 'a; - inj : 'a -> 'b contents; - } - -> 'b case - - val preendorsement_case : Kind.preendorsement case - - val endorsement_case : Kind.endorsement case - - val seed_nonce_revelation_case : Kind.seed_nonce_revelation case - - val double_preendorsement_evidence_case : - Kind.double_preendorsement_evidence case - - val double_endorsement_evidence_case : Kind.double_endorsement_evidence case - - val double_baking_evidence_case : Kind.double_baking_evidence case - - val activate_account_case : Kind.activate_account case - - val proposals_case : Kind.proposals case - - val ballot_case : Kind.ballot case - - val failing_noop_case : Kind.failing_noop case - - val reveal_case : Kind.reveal Kind.manager case - - val transaction_case : Kind.transaction Kind.manager case - - val origination_case : Kind.origination Kind.manager case - - val delegation_case : Kind.delegation Kind.manager case - - val register_global_constant_case : - Kind.register_global_constant Kind.manager case - - val set_deposits_limit_case : Kind.set_deposits_limit Kind.manager case - - module Manager_operations : sig - type 'b case = - | MCase : { - tag : int; - name : string; - encoding : 'a Data_encoding.t; - select : packed_manager_operation -> 'kind manager_operation option; - proj : 'kind manager_operation -> 'a; - inj : 'a -> 'kind manager_operation; - } - -> 'kind case - - val reveal_case : Kind.reveal case - - val transaction_case : Kind.transaction case - - val origination_case : Kind.origination case - - val delegation_case : Kind.delegation case - - val register_global_constant_case : Kind.register_global_constant case - - val set_deposits_limit_case : Kind.set_deposits_limit case - end -end diff --git a/src/proto_012_Psithaca/lib_protocol/parameters_repr.ml b/src/proto_012_Psithaca/lib_protocol/parameters_repr.ml deleted file mode 100644 index 5f21e6c3d453..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/parameters_repr.ml +++ /dev/null @@ -1,132 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type bootstrap_account = { - public_key_hash : Signature.Public_key_hash.t; - public_key : Signature.Public_key.t option; - amount : Tez_repr.t; -} - -type bootstrap_contract = { - delegate : Signature.Public_key_hash.t option; - amount : Tez_repr.t; - script : Script_repr.t; -} - -type t = { - bootstrap_accounts : bootstrap_account list; - bootstrap_contracts : bootstrap_contract list; - commitments : Commitment_repr.t list; - constants : Constants_repr.parametric; - security_deposit_ramp_up_cycles : int option; - no_reward_cycles : int option; -} - -let bootstrap_account_encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Public_key_known" - (tup2 Signature.Public_key.encoding Tez_repr.encoding) - (function - | {public_key_hash; public_key = Some public_key; amount} -> - assert ( - Signature.Public_key_hash.equal - (Signature.Public_key.hash public_key) - public_key_hash) ; - Some (public_key, amount) - | {public_key = None; _} -> None) - (fun (public_key, amount) -> - { - public_key = Some public_key; - public_key_hash = Signature.Public_key.hash public_key; - amount; - }); - case - (Tag 1) - ~title:"Public_key_unknown" - (tup2 Signature.Public_key_hash.encoding Tez_repr.encoding) - (function - | {public_key_hash; public_key = None; amount} -> - Some (public_key_hash, amount) - | {public_key = Some _; _} -> None) - (fun (public_key_hash, amount) -> - {public_key = None; public_key_hash; amount}); - ] - -let bootstrap_contract_encoding = - let open Data_encoding in - conv - (fun {delegate; amount; script} -> (delegate, amount, script)) - (fun (delegate, amount, script) -> {delegate; amount; script}) - (obj3 - (opt "delegate" Signature.Public_key_hash.encoding) - (req "amount" Tez_repr.encoding) - (req "script" Script_repr.encoding)) - -let encoding = - let open Data_encoding in - conv - (fun { - bootstrap_accounts; - bootstrap_contracts; - commitments; - constants; - security_deposit_ramp_up_cycles; - no_reward_cycles; - } -> - ( ( bootstrap_accounts, - bootstrap_contracts, - commitments, - security_deposit_ramp_up_cycles, - no_reward_cycles ), - constants )) - (fun ( ( bootstrap_accounts, - bootstrap_contracts, - commitments, - security_deposit_ramp_up_cycles, - no_reward_cycles ), - constants ) -> - { - bootstrap_accounts; - bootstrap_contracts; - commitments; - constants; - security_deposit_ramp_up_cycles; - no_reward_cycles; - }) - (merge_objs - (obj5 - (req "bootstrap_accounts" (list bootstrap_account_encoding)) - (dft "bootstrap_contracts" (list bootstrap_contract_encoding) []) - (dft "commitments" (list Commitment_repr.encoding) []) - (opt "security_deposit_ramp_up_cycles" int31) - (opt "no_reward_cycles" int31)) - Constants_repr.parametric_encoding) - -let check_params params = Constants_repr.check_constants params.constants diff --git a/src/proto_012_Psithaca/lib_protocol/parameters_repr.mli b/src/proto_012_Psithaca/lib_protocol/parameters_repr.mli deleted file mode 100644 index 0b9e3af8ed3d..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/parameters_repr.mli +++ /dev/null @@ -1,57 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module defines protocol parameters, i.e. constants regulating the - behaviour of the blockchain under the protocol. *) - -(** An implict contract (account) initially existing on a chain since genesis. *) -type bootstrap_account = { - public_key_hash : Signature.Public_key_hash.t; - public_key : Signature.Public_key.t option; - amount : Tez_repr.t; -} - -(** An originated contract initially existing on a chain since genesis. *) -type bootstrap_contract = { - delegate : Signature.Public_key_hash.t option; - amount : Tez_repr.t; - script : Script_repr.t; -} - -(** Protocol parameters define some constants regulating behaviour of the - chain. *) -type t = { - bootstrap_accounts : bootstrap_account list; - bootstrap_contracts : bootstrap_contract list; - commitments : Commitment_repr.t list; - constants : Constants_repr.parametric; - security_deposit_ramp_up_cycles : int option; - no_reward_cycles : int option; -} - -val encoding : t Data_encoding.t - -val check_params : t -> unit tzresult diff --git a/src/proto_012_Psithaca/lib_protocol/path_encoding.ml b/src/proto_012_Psithaca/lib_protocol/path_encoding.ml deleted file mode 100644 index e2657785be11..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/path_encoding.ml +++ /dev/null @@ -1,54 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 DaiLambda, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module type S = sig - type t - - val to_path : t -> string list -> string list - - val of_path : string list -> t option - - val path_length : int -end - -module Make_hex (H : sig - type t - - val to_bytes : t -> bytes - - val of_bytes_opt : bytes -> t option -end) = -struct - let path_length = 1 - - let to_path t l = - let (`Hex key) = Hex.of_bytes (H.to_bytes t) in - key :: l - - let of_path = function - | [path] -> Option.bind (Hex.to_bytes (`Hex path)) H.of_bytes_opt - | _ -> None -end diff --git a/src/proto_012_Psithaca/lib_protocol/path_encoding.mli b/src/proto_012_Psithaca/lib_protocol/path_encoding.mli deleted file mode 100644 index 7388fb52f6d2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/path_encoding.mli +++ /dev/null @@ -1,48 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 DaiLambda, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module type S = sig - type t - - (** [to_path t postfix] returns the context path name for [t] - postfixed with [postfix] *) - val to_path : t -> string list -> string list - - (** [of_path path] parses [path] as a context path name for [t] *) - val of_path : string list -> t option - - (** Directory levels of the path encoding of [t] *) - val path_length : int -end - -(** Path encoding in hex: /[0-9a-f]{2}+/ *) -module Make_hex (H : sig - type t - - val to_bytes : t -> bytes - - val of_bytes_opt : bytes -> t option -end) : S with type t := H.t diff --git a/src/proto_012_Psithaca/lib_protocol/period_repr.ml b/src/proto_012_Psithaca/lib_protocol/period_repr.ml deleted file mode 100644 index 1f2de5752be8..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/period_repr.ml +++ /dev/null @@ -1,164 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* `Permanent *) -type error += Malformed_period of int64 | Invalid_arg | Period_overflow - -let () = - let open Data_encoding in - (* Malformed period *) - register_error_kind - `Permanent - ~id:"malformed_period" - ~title:"Malformed period" - ~description:"Period is negative." - ~pp:(fun ppf period -> - Format.fprintf ppf "The given period '%Ld' is negative " period) - (obj1 (req "malformed_period" int64)) - (function Malformed_period n -> Some n | _ -> None) - (fun n -> Malformed_period n) ; - (* Invalid arg *) - register_error_kind - `Permanent - ~id:"invalid_arg" - ~title:"Invalid arg" - ~description:"Negative multiple of periods are not allowed." - ~pp:(fun ppf () -> Format.fprintf ppf "Invalid arg") - empty - (function Invalid_arg -> Some () | _ -> None) - (fun () -> Invalid_arg) ; - let title = "Period overflow" in - register_error_kind - `Permanent - ~id:"period_overflow" - ~title - ~description:"Last operation generated an integer overflow." - ~pp:(fun ppf () -> Format.fprintf ppf "%s" title) - empty - (function Period_overflow -> Some () | _ -> None) - (fun () -> Period_overflow) - -module type INTERNAL = sig - type t = private int64 - - val create : int64 -> t option - - val zero : t - - val one : t - - val mult_ : t -> t -> t option - - val add_ : t -> t -> t option - - val encoding : t Data_encoding.t - - val rpc_arg : t RPC_arg.arg - - val pp : Format.formatter -> t -> unit - - include Compare.S with type t := t -end - -(* Internal module implementing natural numbers using int64. These are different - from usual (wrapping up) unsigned integers in that if one overflows the - representation bounds for int64 through [add] or [mul], a [None] value is - returned *) -module Internal : INTERNAL = struct - type t = Int64.t - - let encoding = - Data_encoding.( - with_decoding_guard - (fun t -> - if Compare.Int64.(t >= 0L) then Ok () - else Error "Positive int64 required") - int64) - - let rpc_arg = RPC_arg.uint63 - - let pp ppf v = Format.fprintf ppf "%Ld" v - - include (Compare.Int64 : Compare.S with type t := t) - - let zero = 0L - - let one = 1L - - let create t = if t >= zero then Some t else None - - (* The create function is not used in the [mul_] and [add_] below to not add - extra Some | None pattern matching to handle since the overflow checks are - generic and apply as well to negative as positive integers . - - To handle overflows, both [add_] and [mult_] return option types. [None] is - returned on detected overflow, [Some value] when everything went well. *) - let mult_ a b = - if a <> zero then - let res = Int64.mul a b in - if Int64.div res a <> b then None else Some res - else Some zero - - let add_ a b = - let res = Int64.add a b in - if res < a || res < b then None else Some res -end - -include Internal - -type period = Internal.t - -let to_seconds (t : Internal.t) = (t :> int64) - -let of_seconds secs = - match Internal.create secs with - | Some v -> ok v - | None -> error (Malformed_period secs) - -let of_seconds_exn t = - match Internal.create t with - | Some t -> t - | None -> invalid_arg "Period.of_seconds_exn" - -let mult i p = - match Internal.create (Int64.of_int32 i) with - | None -> error Invalid_arg - | Some iper -> ( - match Internal.mult_ iper p with - | None -> error Period_overflow - | Some res -> ok res) - -let add p1 p2 = - match Internal.add_ p1 p2 with - | None -> error Period_overflow - | Some res -> ok res - -let ( +? ) = add - -let one_second = Internal.one - -let one_minute = of_seconds_exn 60L - -let one_hour = of_seconds_exn 3600L diff --git a/src/proto_012_Psithaca/lib_protocol/period_repr.mli b/src/proto_012_Psithaca/lib_protocol/period_repr.mli deleted file mode 100644 index 92f60493a57d..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/period_repr.mli +++ /dev/null @@ -1,73 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t - -(** Represents a period of time as a non-negative integer. *) -type period = t - -include Compare.S with type t := t - -val encoding : period Data_encoding.t - -val rpc_arg : period RPC_arg.t - -val pp : Format.formatter -> period -> unit - -(** Returns the number of seconds contained in the period. *) -val to_seconds : period -> int64 - -(** Converts a number of seconds to a [period]. - - [of_second s] fails if [s] is not positive. *) -val of_seconds : int64 -> period tzresult - -(** Converts a number of seconds to [period]. - - [of_second s] fails if [s] is not positive. - It should only be used at toplevel for constants. *) -val of_seconds_exn : int64 -> period - -(** Safe addition of periods, guarded against overflow. *) -val add : period -> period -> period tzresult - -(** Alias for [add]. *) -val ( +? ) : period -> period -> period tzresult - -(** Safe multiplication by a positive integer. Guarded against overflow. *) -val mult : int32 -> period -> period tzresult - -val zero : period - -val one_second : period - -val one_minute : period - -val one_hour : period - -(** [compare x y] returns [0] if [x] is equal to [y], a negative - integer if [x] is shorter than [y], and a positive integer if [x] - is longer than [y]. *) -val compare : period -> period -> int diff --git a/src/proto_012_Psithaca/lib_protocol/raw_context.ml b/src/proto_012_Psithaca/lib_protocol/raw_context.ml deleted file mode 100644 index 23b2bbaf2374..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/raw_context.ml +++ /dev/null @@ -1,1295 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Int_set = Set.Make (Compare.Int) - -(* - - Gas levels maintenance - ======================= - - The context maintains two levels of gas, one corresponds to the gas - available for the current operation while the other is the gas - available for the current block. Both levels are maintained - independently: [consume_gas] only decreases the operation level, - and block level should be updated with [consume_gas_limit_in_block]. - - A layered context - ================= - - Updating the context [remaining_operation_gas] is a critical routine - called very frequently by the operations performed by the protocol. - On the contrary, other fields are less frequently updated. - - In a previous version of the context datatype definition, all - the fields were represented at the toplevel. To update the remaining - gas, we had to copy ~25 fields (that is 200 bytes). - - With the following layered representation, we only have to - copy 2 fields (16 bytes) during [remaining_operation_gas] update. - This has a significant impact on the Michelson runtime efficiency. - - Here are the fields on the [back] of the context: - - *) - -module Raw_consensus = struct - (** Consensus operations are indexed by their [initial slots]. Given - a delegate, the [initial slot] is the lowest slot assigned to - this delegate. *) - - type t = { - current_endorsement_power : int; - (** Number of endorsement slots recorded for the current block. *) - allowed_endorsements : - (Signature.Public_key.t * Signature.Public_key_hash.t * int) - Slot_repr.Map.t; - (** Endorsements rights for the current block. Only an endorsement - for the lowest slot in the block can be recorded. The map - associates to each initial slot the [pkh] associated to this - slot with its power. *) - allowed_preendorsements : - (Signature.Public_key.t * Signature.Public_key_hash.t * int) - Slot_repr.Map.t; - (** Preendorsements rights for the current block. Only a preendorsement - for the lowest slot in the block can be recorded. The map - associates to each initial slot the [pkh] associated to this - slot with its power. *) - grand_parent_endorsements_seen : Signature.Public_key_hash.Set.t; - (** Record the endorsements already seen for the grand - parent. This only useful for the partial construction mode. *) - endorsements_seen : Slot_repr.Set.t; - (** Record the endorsements already seen. Only initial slots are indexed. *) - preendorsements_seen : Slot_repr.Set.t; - (** Record the preendorsements already seen. Only initial slots - are indexed. *) - locked_round_evidence : (Round_repr.t * int) option; - (** Record the preendorsement power for a locked round. *) - preendorsements_quorum_round : Round_repr.t option; - (** in block construction mode, record the round of preendorsements - included in a block. *) - endorsement_branch : (Block_hash.t * Block_payload_hash.t) option; - grand_parent_branch : (Block_hash.t * Block_payload_hash.t) option; - } - - (** Invariant: - - - [slot \in endorsements_seen => Int_map.mem slot allowed_endorsements] - - - [slot \in preendorsements_seen => Int_map.mem slot allowed_preendorsements] - - - [ |endorsements_seen| > 0 => |included endorsements| > 0] - - *) - - let empty : t = - { - current_endorsement_power = 0; - allowed_endorsements = Slot_repr.Map.empty; - allowed_preendorsements = Slot_repr.Map.empty; - grand_parent_endorsements_seen = Signature.Public_key_hash.Set.empty; - endorsements_seen = Slot_repr.Set.empty; - preendorsements_seen = Slot_repr.Set.empty; - locked_round_evidence = None; - preendorsements_quorum_round = None; - endorsement_branch = None; - grand_parent_branch = None; - } - - type error += Double_inclusion_of_consensus_operation - - let () = - register_error_kind - `Branch - ~id:"operation.double_inclusion_of_consensus_operation" - ~title:"double inclusion of consensus operation" - ~description:"double inclusion of consensus operation" - ~pp:(fun ppf () -> - Format.fprintf ppf "Double inclusion of consensus operation") - Data_encoding.empty - (function - | Double_inclusion_of_consensus_operation -> Some () | _ -> None) - (fun () -> Double_inclusion_of_consensus_operation) - - let record_grand_parent_endorsement t pkh = - error_when - (Signature.Public_key_hash.Set.mem pkh t.grand_parent_endorsements_seen) - Double_inclusion_of_consensus_operation - >|? fun () -> - { - t with - grand_parent_endorsements_seen = - Signature.Public_key_hash.Set.add pkh t.grand_parent_endorsements_seen; - } - - let record_endorsement t ~initial_slot ~power = - error_when - (Slot_repr.Set.mem initial_slot t.endorsements_seen) - Double_inclusion_of_consensus_operation - >|? fun () -> - { - t with - current_endorsement_power = t.current_endorsement_power + power; - endorsements_seen = Slot_repr.Set.add initial_slot t.endorsements_seen; - } - - let record_preendorsement ~initial_slot ~power round t = - error_when - (Slot_repr.Set.mem initial_slot t.preendorsements_seen) - Double_inclusion_of_consensus_operation - >|? fun () -> - let locked_round_evidence = - match t.locked_round_evidence with - | None -> Some (round, power) - | Some (_stored_round, evidences) -> - (* In mempool mode, round and stored_round can be different. - It doesn't matter in that case since quorum certificates - are not used in mempool. - For other cases [Apply.check_round] verifies it. *) - Some (round, evidences + power) - in - { - t with - locked_round_evidence; - preendorsements_seen = - Slot_repr.Set.add initial_slot t.preendorsements_seen; - } - - let set_preendorsements_quorum_round round t = - match t.preendorsements_quorum_round with - | Some round' -> - (* If the rounds are different, an error should have already - been raised. *) - assert (Round_repr.equal round round') ; - t - | None -> {t with preendorsements_quorum_round = Some round} - - let initialize_with_endorsements_and_preendorsements ~allowed_endorsements - ~allowed_preendorsements t = - {t with allowed_endorsements; allowed_preendorsements} - - let locked_round_evidence t = t.locked_round_evidence - - let endorsement_branch t = t.endorsement_branch - - let grand_parent_branch t = t.grand_parent_branch - - let set_endorsement_branch t endorsement_branch = - {t with endorsement_branch = Some endorsement_branch} - - let set_grand_parent_branch t grand_parent_branch = - {t with grand_parent_branch = Some grand_parent_branch} -end - -type back = { - context : Context.t; - constants : Constants_repr.parametric; - round_durations : Round_repr.Durations.t; - cycle_eras : Level_repr.cycle_eras; - level : Level_repr.t; - predecessor_timestamp : Time.t; - timestamp : Time.t; - fees : Tez_repr.t; - origination_nonce : Contract_repr.origination_nonce option; - temporary_lazy_storage_ids : Lazy_storage_kind.Temp_ids.t; - internal_nonce : int; - internal_nonces_used : Int_set.t; - remaining_block_gas : Gas_limit_repr.Arith.fp; - unlimited_operation_gas : bool; - consensus : Raw_consensus.t; - non_consensus_operations : Operation_hash.t list; - sampler_state : - (Seed_repr.seed - * (Signature.Public_key.t * Signature.Public_key_hash.t) Sampler.t) - Cycle_repr.Map.t; - stake_distribution_for_current_cycle : - Tez_repr.t Signature.Public_key_hash.Map.t option; -} - -(* - - The context is simply a record with two fields which - limits the cost of updating the [remaining_operation_gas]. - -*) -type t = {remaining_operation_gas : Gas_limit_repr.Arith.fp; back : back} - -type root = t - -(* - - Context fields accessors - ======================== - - To have the context related code more robust to evolutions, - we introduce accessors to get and to update the context - components. - -*) -let[@inline] context ctxt = ctxt.back.context - -let[@inline] current_level ctxt = ctxt.back.level - -let[@inline] predecessor_timestamp ctxt = ctxt.back.predecessor_timestamp - -let[@inline] current_timestamp ctxt = ctxt.back.timestamp - -let[@inline] round_durations ctxt = ctxt.back.round_durations - -let[@inline] cycle_eras ctxt = ctxt.back.cycle_eras - -let[@inline] constants ctxt = ctxt.back.constants - -let[@inline] recover ctxt = ctxt.back.context - -let[@inline] fees ctxt = ctxt.back.fees - -let[@inline] origination_nonce ctxt = ctxt.back.origination_nonce - -let[@inline] internal_nonce ctxt = ctxt.back.internal_nonce - -let[@inline] internal_nonces_used ctxt = ctxt.back.internal_nonces_used - -let[@inline] remaining_block_gas ctxt = ctxt.back.remaining_block_gas - -let[@inline] unlimited_operation_gas ctxt = ctxt.back.unlimited_operation_gas - -let[@inline] temporary_lazy_storage_ids ctxt = - ctxt.back.temporary_lazy_storage_ids - -let[@inline] remaining_operation_gas ctxt = ctxt.remaining_operation_gas - -let[@inline] non_consensus_operations ctxt = ctxt.back.non_consensus_operations - -let[@inline] sampler_state ctxt = ctxt.back.sampler_state - -let[@inline] update_back ctxt back = {ctxt with back} - -let[@inline] update_remaining_block_gas ctxt remaining_block_gas = - update_back ctxt {ctxt.back with remaining_block_gas} - -let[@inline] update_remaining_operation_gas ctxt remaining_operation_gas = - {ctxt with remaining_operation_gas} - -let[@inline] update_unlimited_operation_gas ctxt unlimited_operation_gas = - update_back ctxt {ctxt.back with unlimited_operation_gas} - -let[@inline] update_context ctxt context = - update_back ctxt {ctxt.back with context} - -let[@inline] update_constants ctxt constants = - update_back ctxt {ctxt.back with constants} - -let[@inline] update_origination_nonce ctxt origination_nonce = - update_back ctxt {ctxt.back with origination_nonce} - -let[@inline] update_internal_nonce ctxt internal_nonce = - update_back ctxt {ctxt.back with internal_nonce} - -let[@inline] update_internal_nonces_used ctxt internal_nonces_used = - update_back ctxt {ctxt.back with internal_nonces_used} - -let[@inline] update_fees ctxt fees = update_back ctxt {ctxt.back with fees} - -let[@inline] update_temporary_lazy_storage_ids ctxt temporary_lazy_storage_ids = - update_back ctxt {ctxt.back with temporary_lazy_storage_ids} - -let[@inline] update_non_consensus_operations ctxt non_consensus_operations = - update_back ctxt {ctxt.back with non_consensus_operations} - -let[@inline] update_sampler_state ctxt sampler_state = - update_back ctxt {ctxt.back with sampler_state} - -type error += Too_many_internal_operations (* `Permanent *) - -type error += Block_quota_exceeded (* `Temporary *) - -type error += Operation_quota_exceeded (* `Temporary *) - -type error += Stake_distribution_not_set (* `Branch *) - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"too_many_internal_operations" - ~title:"Too many internal operations" - ~description: - "A transaction exceeded the hard limit of internal operations it can emit" - empty - (function Too_many_internal_operations -> Some () | _ -> None) - (fun () -> Too_many_internal_operations) ; - register_error_kind - `Temporary - ~id:"gas_exhausted.operation" - ~title:"Gas quota exceeded for the operation" - ~description: - "A script or one of its callee took more time than the operation said it \ - would" - empty - (function Operation_quota_exceeded -> Some () | _ -> None) - (fun () -> Operation_quota_exceeded) ; - register_error_kind - `Temporary - ~id:"gas_exhausted.block" - ~title:"Gas quota exceeded for the block" - ~description: - "The sum of gas consumed by all the operations in the block exceeds the \ - hard gas limit per block" - empty - (function Block_quota_exceeded -> Some () | _ -> None) - (fun () -> Block_quota_exceeded) ; - register_error_kind - `Permanent - ~id:"delegate.stake_distribution_not_set" - ~title:"Stake distribution not set" - ~description:"The stake distribution for the current cycle is not set." - ~pp:(fun ppf () -> - Format.fprintf - ppf - "The stake distribution for the current cycle is not set.") - Data_encoding.(empty) - (function Stake_distribution_not_set -> Some () | _ -> None) - (fun () -> Stake_distribution_not_set) - -let fresh_internal_nonce ctxt = - if Compare.Int.(internal_nonce ctxt >= 65_535) then - error Too_many_internal_operations - else - ok - (update_internal_nonce ctxt (internal_nonce ctxt + 1), internal_nonce ctxt) - -let reset_internal_nonce ctxt = - let ctxt = update_internal_nonce ctxt 0 in - update_internal_nonces_used ctxt Int_set.empty - -let record_internal_nonce ctxt k = - update_internal_nonces_used ctxt (Int_set.add k (internal_nonces_used ctxt)) - -let internal_nonce_already_recorded ctxt k = - Int_set.mem k (internal_nonces_used ctxt) - -let get_collected_fees ctxt = fees ctxt - -let credit_collected_fees_only_call_from_token ctxt fees' = - let previous = get_collected_fees ctxt in - Tez_repr.(previous +? fees') >|? fun fees -> update_fees ctxt fees - -let spend_collected_fees_only_call_from_token ctxt fees' = - let previous = get_collected_fees ctxt in - Tez_repr.(previous -? fees') >|? fun fees -> update_fees ctxt fees - -type error += Undefined_operation_nonce (* `Permanent *) - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"undefined_operation_nonce" - ~title:"Ill timed access to the origination nonce" - ~description: - "An origination was attempted out of the scope of a manager operation" - empty - (function Undefined_operation_nonce -> Some () | _ -> None) - (fun () -> Undefined_operation_nonce) - -let init_origination_nonce ctxt operation_hash = - let origination_nonce = - Some (Contract_repr.initial_origination_nonce operation_hash) - in - update_origination_nonce ctxt origination_nonce - -let increment_origination_nonce ctxt = - match origination_nonce ctxt with - | None -> error Undefined_operation_nonce - | Some cur_origination_nonce -> - let origination_nonce = - Some (Contract_repr.incr_origination_nonce cur_origination_nonce) - in - let ctxt = update_origination_nonce ctxt origination_nonce in - ok (ctxt, cur_origination_nonce) - -let get_origination_nonce ctxt = - match origination_nonce ctxt with - | None -> error Undefined_operation_nonce - | Some origination_nonce -> ok origination_nonce - -let unset_origination_nonce ctxt = update_origination_nonce ctxt None - -type error += Gas_limit_too_high (* `Permanent *) - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"gas_limit_too_high" - ~title:"Gas limit out of protocol hard bounds" - ~description:"A transaction tried to exceed the hard limit on gas" - empty - (function Gas_limit_too_high -> Some () | _ -> None) - (fun () -> Gas_limit_too_high) - -let gas_level ctxt = - let open Gas_limit_repr in - if unlimited_operation_gas ctxt then Unaccounted - else Limited {remaining = remaining_operation_gas ctxt} - -let block_gas_level = remaining_block_gas - -let check_gas_limit_is_valid ctxt (remaining : 'a Gas_limit_repr.Arith.t) = - if - Gas_limit_repr.Arith.( - remaining > (constants ctxt).hard_gas_limit_per_operation - || remaining < zero) - then error Gas_limit_too_high - else Result.return_unit - -let consume_gas_limit_in_block ctxt (limit : 'a Gas_limit_repr.Arith.t) = - let open Gas_limit_repr in - check_gas_limit_is_valid ctxt limit >>? fun () -> - let block_gas = block_gas_level ctxt in - let limit = Arith.fp limit in - if Arith.(limit > block_gas) then error Block_quota_exceeded - else - let level = Arith.sub (block_gas_level ctxt) limit in - let ctxt = update_remaining_block_gas ctxt level in - Ok ctxt - -let set_gas_limit ctxt (remaining : 'a Gas_limit_repr.Arith.t) = - let open Gas_limit_repr in - let remaining_operation_gas = Arith.fp remaining in - let ctxt = update_unlimited_operation_gas ctxt false in - {ctxt with remaining_operation_gas} - -let set_gas_unlimited ctxt = update_unlimited_operation_gas ctxt true - -let consume_gas ctxt cost = - match Gas_limit_repr.raw_consume (remaining_operation_gas ctxt) cost with - | Some gas_counter -> Ok (update_remaining_operation_gas ctxt gas_counter) - | None -> - if unlimited_operation_gas ctxt then ok ctxt - else error Operation_quota_exceeded - -let check_enough_gas ctxt cost = - consume_gas ctxt cost >>? fun _ -> Result.return_unit - -let gas_consumed ~since ~until = - match (gas_level since, gas_level until) with - | (Limited {remaining = before}, Limited {remaining = after}) -> - Gas_limit_repr.Arith.sub before after - | (_, _) -> Gas_limit_repr.Arith.zero - -type missing_key_kind = Get | Set | Del | Copy - -type storage_error = - | Incompatible_protocol_version of string - | Missing_key of string list * missing_key_kind - | Existing_key of string list - | Corrupted_data of string list - -let storage_error_encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Incompatible_protocol_version" - (obj1 (req "incompatible_protocol_version" string)) - (function Incompatible_protocol_version arg -> Some arg | _ -> None) - (fun arg -> Incompatible_protocol_version arg); - case - (Tag 1) - ~title:"Missing_key" - (obj2 - (req "missing_key" (list string)) - (req - "function" - (string_enum - [("get", Get); ("set", Set); ("del", Del); ("copy", Copy)]))) - (function Missing_key (key, f) -> Some (key, f) | _ -> None) - (fun (key, f) -> Missing_key (key, f)); - case - (Tag 2) - ~title:"Existing_key" - (obj1 (req "existing_key" (list string))) - (function Existing_key key -> Some key | _ -> None) - (fun key -> Existing_key key); - case - (Tag 3) - ~title:"Corrupted_data" - (obj1 (req "corrupted_data" (list string))) - (function Corrupted_data key -> Some key | _ -> None) - (fun key -> Corrupted_data key); - ] - -let pp_storage_error ppf = function - | Incompatible_protocol_version version -> - Format.fprintf - ppf - "Found a context with an unexpected version '%s'." - version - | Missing_key (key, Get) -> - Format.fprintf ppf "Missing key '%s'." (String.concat "/" key) - | Missing_key (key, Set) -> - Format.fprintf - ppf - "Cannot set undefined key '%s'." - (String.concat "/" key) - | Missing_key (key, Del) -> - Format.fprintf - ppf - "Cannot delete undefined key '%s'." - (String.concat "/" key) - | Missing_key (key, Copy) -> - Format.fprintf - ppf - "Cannot copy undefined key '%s'." - (String.concat "/" key) - | Existing_key key -> - Format.fprintf - ppf - "Cannot initialize defined key '%s'." - (String.concat "/" key) - | Corrupted_data key -> - Format.fprintf - ppf - "Failed to parse the data at '%s'." - (String.concat "/" key) - -type error += Storage_error of storage_error - -let () = - register_error_kind - `Permanent - ~id:"context.storage_error" - ~title:"Storage error (fatal internal error)" - ~description: - "An error that should never happen unless something has been deleted or \ - corrupted in the database." - ~pp:(fun ppf err -> - Format.fprintf ppf "@[Storage error:@ %a@]" pp_storage_error err) - storage_error_encoding - (function Storage_error err -> Some err | _ -> None) - (fun err -> Storage_error err) - -let storage_error err = error (Storage_error err) - -(* Initialization *********************************************************) - -(* This key should always be populated for every version of the - protocol. It's absence meaning that the context is empty. *) -let version_key = ["version"] - -(* This value is set by the snapshot_alpha.sh script, don't change it. *) -let version_value = "ithaca_012" - -let version = "v1" - -let cycle_eras_key = [version; "cycle_eras"] - -let constants_key = [version; "constants"] - -let protocol_param_key = ["protocol_parameters"] - -let get_cycle_eras ctxt = - Context.find ctxt cycle_eras_key >|= function - | None -> storage_error (Missing_key (cycle_eras_key, Get)) - | Some bytes -> ( - match - Data_encoding.Binary.of_bytes_opt Level_repr.cycle_eras_encoding bytes - with - | None -> storage_error (Corrupted_data cycle_eras_key) - | Some cycle_eras -> ok cycle_eras) - -let set_cycle_eras ctxt cycle_eras = - let bytes = - Data_encoding.Binary.to_bytes_exn Level_repr.cycle_eras_encoding cycle_eras - in - Context.add ctxt cycle_eras_key bytes >|= ok - -type error += Failed_to_parse_parameter of bytes - -type error += Failed_to_decode_parameter of Data_encoding.json * string - -let () = - register_error_kind - `Temporary - ~id:"context.failed_to_parse_parameter" - ~title:"Failed to parse parameter" - ~description:"The protocol parameters are not valid JSON." - ~pp:(fun ppf bytes -> - Format.fprintf - ppf - "@[Cannot parse the protocol parameter:@ %s@]" - (Bytes.to_string bytes)) - Data_encoding.(obj1 (req "contents" bytes)) - (function Failed_to_parse_parameter data -> Some data | _ -> None) - (fun data -> Failed_to_parse_parameter data) ; - register_error_kind - `Temporary - ~id:"context.failed_to_decode_parameter" - ~title:"Failed to decode parameter" - ~description:"Unexpected JSON object." - ~pp:(fun ppf (json, msg) -> - Format.fprintf - ppf - "@[Cannot decode the protocol parameter:@ %s@ %a@]" - msg - Data_encoding.Json.pp - json) - Data_encoding.(obj2 (req "contents" json) (req "error" string)) - (function - | Failed_to_decode_parameter (json, msg) -> Some (json, msg) | _ -> None) - (fun (json, msg) -> Failed_to_decode_parameter (json, msg)) - -let get_proto_param ctxt = - Context.find ctxt protocol_param_key >>= function - | None -> failwith "Missing protocol parameters." - | Some bytes -> ( - match Data_encoding.Binary.of_bytes_opt Data_encoding.json bytes with - | None -> fail (Failed_to_parse_parameter bytes) - | Some json -> ( - Context.remove ctxt protocol_param_key >|= fun ctxt -> - match Data_encoding.Json.destruct Parameters_repr.encoding json with - | exception (Data_encoding.Json.Cannot_destruct _ as exn) -> - Format.kasprintf - failwith - "Invalid protocol_parameters: %a %a" - (fun ppf -> Data_encoding.Json.print_error ppf) - exn - Data_encoding.Json.pp - json - | param -> - Parameters_repr.check_params param >>? fun () -> ok (param, ctxt)) - ) - -let add_constants ctxt constants = - let bytes = - Data_encoding.Binary.to_bytes_exn - Constants_repr.parametric_encoding - constants - in - Context.add ctxt constants_key bytes - -let get_constants ctxt = - Context.find ctxt constants_key >|= function - | None -> failwith "Internal error: cannot read constants in context." - | Some bytes -> ( - match - Data_encoding.Binary.of_bytes_opt - Constants_repr.parametric_encoding - bytes - with - | None -> failwith "Internal error: cannot parse constants in context." - | Some constants -> ok constants) - -let patch_constants ctxt f = - let constants = f (constants ctxt) in - add_constants (context ctxt) constants >|= fun context -> - let ctxt = update_context ctxt context in - update_constants ctxt constants - -let check_inited ctxt = - Context.find ctxt version_key >|= function - | None -> failwith "Internal error: un-initialized context." - | Some bytes -> - let s = Bytes.to_string bytes in - if Compare.String.(s = version_value) then Result.return_unit - else storage_error (Incompatible_protocol_version s) - -let check_cycle_eras (cycle_eras : Level_repr.cycle_eras) - (constants : Constants_repr.parametric) = - let current_era = Level_repr.current_era cycle_eras in - assert ( - Compare.Int32.(current_era.blocks_per_cycle = constants.blocks_per_cycle)) ; - assert ( - Compare.Int32.( - current_era.blocks_per_commitment = constants.blocks_per_commitment)) - -let prepare ~level ~predecessor_timestamp ~timestamp ctxt = - Raw_level_repr.of_int32 level >>?= fun level -> - check_inited ctxt >>=? fun () -> - get_constants ctxt >>=? fun constants -> - Round_repr.Durations.create - ~first_round_duration:constants.minimal_block_delay - ~delay_increment_per_round:constants.delay_increment_per_round - >>?= fun round_durations -> - get_cycle_eras ctxt >|=? fun cycle_eras -> - check_cycle_eras cycle_eras constants ; - let level = Level_repr.from_raw ~cycle_eras level in - { - remaining_operation_gas = Gas_limit_repr.Arith.zero; - back = - { - context = ctxt; - constants; - level; - predecessor_timestamp; - timestamp; - round_durations; - cycle_eras; - fees = Tez_repr.zero; - origination_nonce = None; - temporary_lazy_storage_ids = Lazy_storage_kind.Temp_ids.init; - internal_nonce = 0; - internal_nonces_used = Int_set.empty; - remaining_block_gas = - Gas_limit_repr.Arith.fp - constants.Constants_repr.hard_gas_limit_per_block; - unlimited_operation_gas = true; - consensus = Raw_consensus.empty; - non_consensus_operations = []; - sampler_state = Cycle_repr.Map.empty; - stake_distribution_for_current_cycle = None; - }; - } - -type previous_protocol = Genesis of Parameters_repr.t | Hangzhou_011 - -let check_and_update_protocol_version ctxt = - (Context.find ctxt version_key >>= function - | None -> - failwith "Internal error: un-initialized context in check_first_block." - | Some bytes -> - let s = Bytes.to_string bytes in - if Compare.String.(s = version_value) then - failwith "Internal error: previously initialized context." - else if Compare.String.(s = "genesis") then - get_proto_param ctxt >|=? fun (param, ctxt) -> (Genesis param, ctxt) - else if Compare.String.(s = "hangzhou_011") then - return (Hangzhou_011, ctxt) - else Lwt.return @@ storage_error (Incompatible_protocol_version s)) - >>=? fun (previous_proto, ctxt) -> - Context.add ctxt version_key (Bytes.of_string version_value) >|= fun ctxt -> - ok (previous_proto, ctxt) - -(* only for the migration *) -let[@warning "-32"] get_previous_protocol_constants ctxt = - Context.find ctxt constants_key >>= function - | None -> - failwith - "Internal error: cannot read previous protocol constants in context." - | Some bytes -> ( - match - Data_encoding.Binary.of_bytes_opt - Constants_repr.Proto_previous.parametric_encoding - bytes - with - | None -> - failwith - "Internal error: cannot parse previous protocol constants in \ - context." - | Some constants -> Lwt.return constants) - -(* You should ensure that if the type `Constant_repr.parametric` is - different from the previous protocol or the value of these - constants is modified, is changed from the previous protocol, then - you `propagate` these constants to the new protocol by writing them - onto the context via the function `add_constants` or - `patch_constants`. - - This migration can be achieved also implicitly by modifying the - encoding directly in a way which is compatible with the previous - protocol. However, by doing so, you do not change the value of - these constants inside the context. *) -let prepare_first_block ~level ~timestamp ctxt = - check_and_update_protocol_version ctxt >>=? fun (previous_proto, ctxt) -> - (match previous_proto with - | Genesis param -> - Raw_level_repr.of_int32 level >>?= fun first_level -> - let cycle_era = - { - Level_repr.first_level; - first_cycle = Cycle_repr.root; - blocks_per_cycle = param.constants.blocks_per_cycle; - blocks_per_commitment = param.constants.blocks_per_commitment; - } - in - Level_repr.create_cycle_eras [cycle_era] >>?= fun cycle_eras -> - set_cycle_eras ctxt cycle_eras >>=? fun ctxt -> - add_constants ctxt param.constants >|= ok - | Hangzhou_011 -> - get_previous_protocol_constants ctxt >>= fun c -> - let minimal_block_delay = c.minimal_block_delay in - let minimal_block_delay_s = Period_repr.to_seconds minimal_block_delay in - (if Compare.Int64.(minimal_block_delay_s = 30L) then - (* that's the mainnet value of the constant; so we're - probably on the mainnet: do no inherit this constant's - value (as done in the else case below) *) - Period_repr.of_seconds 15L - else - match c.time_between_blocks with - | first_time_between_blocks :: _ -> - let delay_increment_per_round_s = - let m = - Int64.sub - (Period_repr.to_seconds first_time_between_blocks) - minimal_block_delay_s - in - if Compare.Int64.(m < 1L) then 1L else m - in - Period_repr.of_seconds delay_increment_per_round_s - | [] -> ok minimal_block_delay) - >>?= fun delay_increment_per_round -> - let constants = - let consensus_committee_size = 7000 in - let Constants_repr.Generated. - { - consensus_threshold; - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - } = - Constants_repr.Generated.generate - ~consensus_committee_size - ~blocks_per_minute: - {numerator = 60; denominator = Int64.to_int minimal_block_delay_s} - in - Constants_repr. - { - preserved_cycles = c.preserved_cycles; - blocks_per_cycle = c.blocks_per_cycle; - blocks_per_commitment = c.blocks_per_commitment; - blocks_per_stake_snapshot = c.blocks_per_roll_snapshot; - blocks_per_voting_period = c.blocks_per_voting_period; - hard_gas_limit_per_operation = c.hard_gas_limit_per_operation; - hard_gas_limit_per_block = c.hard_gas_limit_per_block; - proof_of_work_threshold = c.proof_of_work_threshold; - tokens_per_roll = - (* NB: the old value is used during the migration, and - changed to a new value there *) - c.tokens_per_roll; - seed_nonce_revelation_tip = c.seed_nonce_revelation_tip; - origination_size = c.origination_size; - (* Same value as in the previous protocol. *) - max_operations_time_to_live = 120; - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - cost_per_byte = c.cost_per_byte; - hard_storage_limit_per_operation = - c.hard_storage_limit_per_operation; - quorum_min = c.quorum_min; - quorum_max = c.quorum_max; - min_proposal_quorum = c.min_proposal_quorum; - liquidity_baking_subsidy = c.liquidity_baking_subsidy; - liquidity_baking_sunset_level = - (* preserve a lower level for testnets *) - (if Compare.Int32.(c.liquidity_baking_sunset_level = 2_244_609l) - then 3_063_809l - else c.liquidity_baking_sunset_level); - liquidity_baking_escape_ema_threshold = 666_667l; - minimal_block_delay; - delay_increment_per_round; - consensus_committee_size; - consensus_threshold; - minimal_participation_ratio = {numerator = 2; denominator = 3}; - max_slashing_period = 2; - frozen_deposits_percentage = 10; - double_baking_punishment = Tez_repr.(mul_exn one 640); - ratio_of_frozen_deposits_slashed_per_double_endorsement = - {numerator = 1; denominator = 2}; - delegate_selection = Random; - } - in - add_constants ctxt constants >>= fun ctxt -> return ctxt) - >>=? fun ctxt -> - prepare ctxt ~level ~predecessor_timestamp:timestamp ~timestamp - >|=? fun ctxt -> (previous_proto, ctxt) - -let activate ctxt h = Updater.activate (context ctxt) h >|= update_context ctxt - -(* Generic context ********************************************************) - -type key = string list - -type value = bytes - -type tree = Context.tree - -module type T = - Raw_context_intf.T - with type root := root - and type key := key - and type value := value - and type tree := tree - -let mem ctxt k = Context.mem (context ctxt) k - -let mem_tree ctxt k = Context.mem_tree (context ctxt) k - -let get ctxt k = - Context.find (context ctxt) k >|= function - | None -> storage_error (Missing_key (k, Get)) - | Some v -> ok v - -let get_tree ctxt k = - Context.find_tree (context ctxt) k >|= function - | None -> storage_error (Missing_key (k, Get)) - | Some v -> ok v - -let find ctxt k = Context.find (context ctxt) k - -let find_tree ctxt k = Context.find_tree (context ctxt) k - -let add ctxt k v = Context.add (context ctxt) k v >|= update_context ctxt - -let add_tree ctxt k v = - Context.add_tree (context ctxt) k v >|= update_context ctxt - -let init ctxt k v = - Context.mem (context ctxt) k >>= function - | true -> Lwt.return @@ storage_error (Existing_key k) - | _ -> - Context.add (context ctxt) k v >|= fun context -> - ok (update_context ctxt context) - -let init_tree ctxt k v : _ tzresult Lwt.t = - Context.mem_tree (context ctxt) k >>= function - | true -> Lwt.return @@ storage_error (Existing_key k) - | _ -> - Context.add_tree (context ctxt) k v >|= fun context -> - ok (update_context ctxt context) - -let update ctxt k v = - Context.mem (context ctxt) k >>= function - | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) - | _ -> - Context.add (context ctxt) k v >|= fun context -> - ok (update_context ctxt context) - -let update_tree ctxt k v = - Context.mem_tree (context ctxt) k >>= function - | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) - | _ -> - Context.add_tree (context ctxt) k v >|= fun context -> - ok (update_context ctxt context) - -(* Verify that the key is present before deleting *) -let remove_existing ctxt k = - Context.mem (context ctxt) k >>= function - | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) - | _ -> - Context.remove (context ctxt) k >|= fun context -> - ok (update_context ctxt context) - -(* Verify that the key is present before deleting *) -let remove_existing_tree ctxt k = - Context.mem_tree (context ctxt) k >>= function - | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) - | _ -> - Context.remove (context ctxt) k >|= fun context -> - ok (update_context ctxt context) - -(* Do not verify before deleting *) -let remove ctxt k = Context.remove (context ctxt) k >|= update_context ctxt - -let add_or_remove ctxt k = function - | None -> remove ctxt k - | Some v -> add ctxt k v - -let add_or_remove_tree ctxt k = function - | None -> remove ctxt k - | Some v -> add_tree ctxt k v - -let list ctxt ?offset ?length k = Context.list (context ctxt) ?offset ?length k - -let fold ?depth ctxt k ~order ~init ~f = - Context.fold ?depth (context ctxt) k ~order ~init ~f - -module Tree : - Raw_context_intf.TREE - with type t := t - and type key := key - and type value := value - and type tree := tree = struct - include Context.Tree - - let empty ctxt = Context.Tree.empty (context ctxt) - - let get t k = - find t k >|= function - | None -> storage_error (Missing_key (k, Get)) - | Some v -> ok v - - let get_tree t k = - find_tree t k >|= function - | None -> storage_error (Missing_key (k, Get)) - | Some v -> ok v - - let init t k v = - mem t k >>= function - | true -> Lwt.return @@ storage_error (Existing_key k) - | _ -> add t k v >|= ok - - let init_tree t k v = - mem_tree t k >>= function - | true -> Lwt.return @@ storage_error (Existing_key k) - | _ -> add_tree t k v >|= ok - - let update t k v = - mem t k >>= function - | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) - | _ -> add t k v >|= ok - - let update_tree t k v = - mem_tree t k >>= function - | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) - | _ -> add_tree t k v >|= ok - - (* Verify that the key is present before deleting *) - let remove_existing t k = - mem t k >>= function - | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) - | _ -> remove t k >|= ok - - (* Verify that the key is present before deleting *) - let remove_existing_tree t k = - mem_tree t k >>= function - | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) - | _ -> remove t k >|= ok - - let add_or_remove t k = function None -> remove t k | Some v -> add t k v - - let add_or_remove_tree t k = function - | None -> remove t k - | Some v -> add_tree t k v -end - -let project x = x - -let absolute_key _ k = k - -let description = Storage_description.create () - -let fold_map_temporary_lazy_storage_ids ctxt f = - f (temporary_lazy_storage_ids ctxt) |> fun (temporary_lazy_storage_ids, x) -> - (update_temporary_lazy_storage_ids ctxt temporary_lazy_storage_ids, x) - -let map_temporary_lazy_storage_ids_s ctxt f = - f (temporary_lazy_storage_ids ctxt) - >|= fun (ctxt, temporary_lazy_storage_ids) -> - update_temporary_lazy_storage_ids ctxt temporary_lazy_storage_ids - -module Cache = struct - type key = Context.Cache.key - - type value = Context.Cache.value = .. - - let key_of_identifier = Context.Cache.key_of_identifier - - let identifier_of_key = Context.Cache.identifier_of_key - - let pp fmt ctxt = Context.Cache.pp fmt (context ctxt) - - let find c k = Context.Cache.find (context c) k - - let set_cache_layout c layout = - Context.Cache.set_cache_layout (context c) layout >>= fun ctxt -> - Lwt.return (update_context c ctxt) - - let update c k v = Context.Cache.update (context c) k v |> update_context c - - let sync c ~cache_nonce = - Context.Cache.sync (context c) ~cache_nonce >>= fun ctxt -> - Lwt.return (update_context c ctxt) - - let clear c = Context.Cache.clear (context c) |> update_context c - - let list_keys c ~cache_index = - Context.Cache.list_keys (context c) ~cache_index - - let key_rank c key = Context.Cache.key_rank (context c) key - - let cache_size_limit c ~cache_index = - Context.Cache.cache_size_limit (context c) ~cache_index - - let cache_size c ~cache_index = - Context.Cache.cache_size (context c) ~cache_index - - let future_cache_expectation c ~time_in_blocks = - Context.Cache.future_cache_expectation (context c) ~time_in_blocks - |> update_context c -end - -let record_non_consensus_operation_hash ctxt operation_hash = - update_non_consensus_operations - ctxt - (operation_hash :: non_consensus_operations ctxt) - -let non_consensus_operations ctxt = List.rev (non_consensus_operations ctxt) - -let set_sampler_for_cycle ctxt cycle sampler_with_seed = - let map = sampler_state ctxt in - if Cycle_repr.Map.mem cycle map then Error `Sampler_already_set - else - let map = Cycle_repr.Map.add cycle sampler_with_seed map in - Ok (update_sampler_state ctxt map) - -let sampler_for_cycle ctxt cycle = - let map = sampler_state ctxt in - match Cycle_repr.Map.find cycle map with - | None -> Error `Sampler_not_set - | Some sampler -> Ok sampler - -let stake_distribution_for_current_cycle ctxt = - match ctxt.back.stake_distribution_for_current_cycle with - | None -> error Stake_distribution_not_set - | Some s -> ok s - -let init_stake_distribution_for_current_cycle ctxt - stake_distribution_for_current_cycle = - update_back - ctxt - { - ctxt.back with - stake_distribution_for_current_cycle = - Some stake_distribution_for_current_cycle; - } - -module type CONSENSUS = sig - type t - - type 'value slot_map - - type slot_set - - type slot - - type round - - val allowed_endorsements : - t -> (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map - - val allowed_preendorsements : - t -> (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map - - val current_endorsement_power : t -> int - - val initialize_consensus_operation : - t -> - allowed_endorsements: - (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map -> - allowed_preendorsements: - (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map -> - t - - val record_grand_parent_endorsement : - t -> Signature.Public_key_hash.t -> t tzresult - - val record_endorsement : t -> initial_slot:slot -> power:int -> t tzresult - - val record_preendorsement : - t -> initial_slot:slot -> power:int -> round -> t tzresult - - val endorsements_seen : t -> slot_set - - val get_preendorsements_quorum_round : t -> round option - - val set_preendorsements_quorum_round : t -> round -> t - - val locked_round_evidence : t -> (round * int) option - - val set_endorsement_branch : t -> Block_hash.t * Block_payload_hash.t -> t - - val endorsement_branch : t -> (Block_hash.t * Block_payload_hash.t) option - - val set_grand_parent_branch : t -> Block_hash.t * Block_payload_hash.t -> t - - val grand_parent_branch : t -> (Block_hash.t * Block_payload_hash.t) option -end - -module Consensus : - CONSENSUS - with type t := t - and type slot := Slot_repr.t - and type 'a slot_map := 'a Slot_repr.Map.t - and type slot_set := Slot_repr.Set.t - and type round := Round_repr.t = struct - let[@inline] allowed_endorsements ctxt = - ctxt.back.consensus.allowed_endorsements - - let[@inline] allowed_preendorsements ctxt = - ctxt.back.consensus.allowed_preendorsements - - let[@inline] current_endorsement_power ctxt = - ctxt.back.consensus.current_endorsement_power - - let[@inline] get_preendorsements_quorum_round ctxt = - ctxt.back.consensus.preendorsements_quorum_round - - let[@inline] locked_round_evidence ctxt = - Raw_consensus.locked_round_evidence ctxt.back.consensus - - let[@inline] update_consensus_with ctxt f = - {ctxt with back = {ctxt.back with consensus = f ctxt.back.consensus}} - - let[@inline] update_consensus_with_tzresult ctxt f = - f ctxt.back.consensus >|? fun consensus -> - {ctxt with back = {ctxt.back with consensus}} - - let[@inline] initialize_consensus_operation ctxt ~allowed_endorsements - ~allowed_preendorsements = - update_consensus_with - ctxt - (Raw_consensus.initialize_with_endorsements_and_preendorsements - ~allowed_endorsements - ~allowed_preendorsements) - - let[@inline] record_grand_parent_endorsement ctxt pkh = - update_consensus_with_tzresult ctxt (fun ctxt -> - Raw_consensus.record_grand_parent_endorsement ctxt pkh) - - let[@inline] record_preendorsement ctxt ~initial_slot ~power round = - update_consensus_with_tzresult - ctxt - (Raw_consensus.record_preendorsement ~initial_slot ~power round) - - let[@inline] record_endorsement ctxt ~initial_slot ~power = - update_consensus_with_tzresult - ctxt - (Raw_consensus.record_endorsement ~initial_slot ~power) - - let[@inline] endorsements_seen ctxt = ctxt.back.consensus.endorsements_seen - - let[@inline] set_preendorsements_quorum_round ctxt round = - update_consensus_with - ctxt - (Raw_consensus.set_preendorsements_quorum_round round) - - let[@inline] endorsement_branch ctxt = - Raw_consensus.endorsement_branch ctxt.back.consensus - - let[@inline] set_endorsement_branch ctxt branch = - update_consensus_with ctxt (fun ctxt -> - Raw_consensus.set_endorsement_branch ctxt branch) - - let[@inline] grand_parent_branch ctxt = - Raw_consensus.grand_parent_branch ctxt.back.consensus - - let[@inline] set_grand_parent_branch ctxt branch = - update_consensus_with ctxt (fun ctxt -> - Raw_consensus.set_grand_parent_branch ctxt branch) -end diff --git a/src/proto_012_Psithaca/lib_protocol/raw_context.mli b/src/proto_012_Psithaca/lib_protocol/raw_context.mli deleted file mode 100644 index e4a30b69ca51..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/raw_context.mli +++ /dev/null @@ -1,320 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** {1 Errors} *) - -type error += Too_many_internal_operations (* `Permanent *) - -type missing_key_kind = Get | Set | Del | Copy - -(** An internal storage error that should not happen *) -type storage_error = - | Incompatible_protocol_version of string - | Missing_key of string list * missing_key_kind - | Existing_key of string list - | Corrupted_data of string list - -type error += Storage_error of storage_error - -type error += Failed_to_parse_parameter of bytes - -type error += Failed_to_decode_parameter of Data_encoding.json * string - -val storage_error : storage_error -> 'a tzresult - -(** {1 Abstract Context} *) - -(** Abstract view of the context. - Includes a handle to the functional key-value database - ({!Context.t}) along with some in-memory values (gas, etc.). *) -type t - -type root = t - -(** Retrieves the state of the database and gives its abstract view. - It also returns wether this is the first block validated - with this version of the protocol. *) -val prepare : - level:Int32.t -> - predecessor_timestamp:Time.t -> - timestamp:Time.t -> - Context.t -> - t tzresult Lwt.t - -type previous_protocol = Genesis of Parameters_repr.t | Hangzhou_011 - -val prepare_first_block : - level:int32 -> - timestamp:Time.t -> - Context.t -> - (previous_protocol * t) tzresult Lwt.t - -val activate : t -> Protocol_hash.t -> t Lwt.t - -(** Returns the state of the database resulting of operations on its - abstract view *) -val recover : t -> Context.t - -val current_level : t -> Level_repr.t - -val predecessor_timestamp : t -> Time.t - -val current_timestamp : t -> Time.t - -val constants : t -> Constants_repr.parametric - -val patch_constants : - t -> (Constants_repr.parametric -> Constants_repr.parametric) -> t Lwt.t - -val round_durations : t -> Round_repr.Durations.t - -(** Retrieve the cycle eras. *) -val cycle_eras : t -> Level_repr.cycle_eras - -(** Increment the current block fee stash that will be credited to the payload - producer's account at finalize_application *) -val credit_collected_fees_only_call_from_token : t -> Tez_repr.t -> t tzresult - -(** Decrement the current block fee stash that will be credited to the payload - producer's account at finalize_application *) -val spend_collected_fees_only_call_from_token : t -> Tez_repr.t -> t tzresult - -(** Returns the current block fee stash that will be credited to the payload - producer's account at finalize_application *) -val get_collected_fees : t -> Tez_repr.t - -type error += Gas_limit_too_high (* `Permanent *) - -val check_gas_limit_is_valid : t -> 'a Gas_limit_repr.Arith.t -> unit tzresult - -val consume_gas_limit_in_block : t -> 'a Gas_limit_repr.Arith.t -> t tzresult - -val set_gas_limit : t -> 'a Gas_limit_repr.Arith.t -> t - -val set_gas_unlimited : t -> t - -val gas_level : t -> Gas_limit_repr.t - -val gas_consumed : since:t -> until:t -> Gas_limit_repr.Arith.fp - -val remaining_operation_gas : t -> Gas_limit_repr.Arith.fp - -val update_remaining_operation_gas : t -> Gas_limit_repr.Arith.fp -> t - -val block_gas_level : t -> Gas_limit_repr.Arith.fp - -val update_remaining_block_gas : t -> Gas_limit_repr.Arith.fp -> t - -type error += Undefined_operation_nonce (* `Permanent *) - -val init_origination_nonce : t -> Operation_hash.t -> t - -val get_origination_nonce : t -> Contract_repr.origination_nonce tzresult - -val increment_origination_nonce : - t -> (t * Contract_repr.origination_nonce) tzresult - -val unset_origination_nonce : t -> t - -(** {1 Generic accessors} *) - -type key = string list - -type value = bytes - -type tree - -module type T = - Raw_context_intf.T - with type root := root - and type key := key - and type value := value - and type tree := tree - -include T with type t := t - -(** Initialize the local nonce used for preventing a script to - duplicate an internal operation to replay it. *) -val reset_internal_nonce : t -> t - -(** Increments the internal operation nonce. *) -val fresh_internal_nonce : t -> (t * int) tzresult - -(** Mark an internal operation nonce as taken. *) -val record_internal_nonce : t -> int -> t - -(** Check is the internal operation nonce has been taken. *) -val internal_nonce_already_recorded : t -> int -> bool - -val fold_map_temporary_lazy_storage_ids : - t -> - (Lazy_storage_kind.Temp_ids.t -> Lazy_storage_kind.Temp_ids.t * 'res) -> - t * 'res - -val map_temporary_lazy_storage_ids_s : - t -> - (Lazy_storage_kind.Temp_ids.t -> (t * Lazy_storage_kind.Temp_ids.t) Lwt.t) -> - t Lwt.t - -module Cache : - Context.CACHE - with type t := t - and type size := int - and type index := int - and type identifier := string - and type key = Context.Cache.key - and type value = Context.Cache.value - -(* Hashes of non-consensus operations are stored so that, when - finalizing the block, we can compute the block's payload hash. *) -val record_non_consensus_operation_hash : t -> Operation_hash.t -> t - -val non_consensus_operations : t -> Operation_hash.t list - -(** [set_sampler_for_cycle ctxt cycle sampler] evaluates to - [Ok c] with [c] verifying [sampler_for_cycle c cycle = sampler] - if no sampler was set for the same [cycle] beforehand. - In the other case, it returns [Error `Sampler_already_set]. *) -val set_sampler_for_cycle : - t -> - Cycle_repr.t -> - Seed_repr.seed * (Signature.public_key * Signature.public_key_hash) Sampler.t -> - (t, [`Sampler_already_set]) result - -(** [sampler_for_cycle ctxt cycle] evaluates to [Ok sampler] if a sampler was - set for [cycle] using [set_sampler_for_cycle]. - Otherwise, it returns [Error `Sampler_not_set]. *) -val sampler_for_cycle : - t -> - Cycle_repr.t -> - ( Seed_repr.seed * (Signature.public_key * Signature.public_key_hash) Sampler.t, - [`Sampler_not_set] ) - result - -(* The stake distribution is stored both in [t] and in the cache. It - may be sufficient to only store it in the cache. *) -val stake_distribution_for_current_cycle : - t -> Tez_repr.t Signature.Public_key_hash.Map.t tzresult - -val init_stake_distribution_for_current_cycle : - t -> Tez_repr.t Signature.Public_key_hash.Map.t -> t - -module type CONSENSUS = sig - type t - - type 'value slot_map - - type slot_set - - type slot - - type round - - (** Returns a map where each endorser's pkh is associated to the - list of its endorsing slots (in decreasing order) for a given - level. *) - val allowed_endorsements : - t -> (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map - - (** Returns a map where each endorser's pkh is associated to the - list of its endorsing slots (in decreasing order) for a given - level. *) - val allowed_preendorsements : - t -> (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map - - (** [endorsement power ctx] returns the endorsement power of the - current block. *) - val current_endorsement_power : t -> int - - (** Initializes the map of allowed endorsements and preendorsements, - this function must be called only once and before applying - any consensus operation. *) - val initialize_consensus_operation : - t -> - allowed_endorsements: - (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map -> - allowed_preendorsements: - (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map -> - t - - (** [record_grand_parent_endorsement ctx pkh] records an - grand_parent_endorsement for the current block. This is only - useful for the partial construction mode. *) - val record_grand_parent_endorsement : - t -> Signature.Public_key_hash.t -> t tzresult - - (** [record_endorsement ctx ~initial_slot ~power] records an - endorsement for the current block. - - The endorsement should be valid in the sense that - [Int_map.find_opt initial_slot allowed_endorsement ctx = Some - (pkh, power)]. *) - val record_endorsement : t -> initial_slot:slot -> power:int -> t tzresult - - (** [record_preendorsement ctx ~initial_slot ~power round - payload_hash power] records a preendorsement for a proposal at - [round] with payload [payload_hash]. - - The preendorsement should be valid in the sense that - [Int_map.find_opt initial_slot allowed_preendorsement ctx = Some - (pkh, power)]. *) - val record_preendorsement : - t -> initial_slot:slot -> power:int -> round -> t tzresult - - val endorsements_seen : t -> slot_set - - (** [get_preendorsements_quorum_round ctx] returns [None] if no - preendorsement are included in the current block. Otherwise, - return [Some r] where [r] is the round of the preendorsements - included in the block. *) - val get_preendorsements_quorum_round : t -> round option - - (** [set_preendorsements_quorum_round ctx round] sets the round for - preendorsements included in this block. This function should be - called only once. - - This function is only used in [Full_construction] mode. *) - val set_preendorsements_quorum_round : t -> round -> t - - (** [locked_round_evidence ctx] returns the round of the recorded - preendorsements as well as their power. *) - val locked_round_evidence : t -> (round * int) option - - val set_endorsement_branch : t -> Block_hash.t * Block_payload_hash.t -> t - - val endorsement_branch : t -> (Block_hash.t * Block_payload_hash.t) option - - val set_grand_parent_branch : t -> Block_hash.t * Block_payload_hash.t -> t - - val grand_parent_branch : t -> (Block_hash.t * Block_payload_hash.t) option -end - -module Consensus : - CONSENSUS - with type t := t - and type slot := Slot_repr.t - and type 'a slot_map := 'a Slot_repr.Map.t - and type slot_set := Slot_repr.Set.t - and type round := Round_repr.t diff --git a/src/proto_012_Psithaca/lib_protocol/raw_context_intf.ml b/src/proto_012_Psithaca/lib_protocol/raw_context_intf.ml deleted file mode 100644 index dc1817f0a2d6..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/raw_context_intf.ml +++ /dev/null @@ -1,260 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2018-2021 Tarides *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** All context manipulation functions. This signature is included - as-is for direct context accesses, and used in {!Storage_functors} - to provide restricted views to the context. *) - -module type VIEW = sig - (* Same as [Environment_context.VIEW] but with extra getters and - setters functions. *) - - (** The type for context handler. *) - type t - - (** The type for context trees. *) - type tree - - (** The type for context keys. *) - type key = string list - - (** The type for context values. *) - type value = bytes - - (** {2 Getters} *) - - (** [mem t k] is an Lwt promise that resolves to [true] iff [k] is bound - to a value in [t]. *) - val mem : t -> key -> bool Lwt.t - - (** [mem_tree t k] is like {!mem} but for trees. *) - val mem_tree : t -> key -> bool Lwt.t - - (** [get t k] is an Lwt promise that resolves to [Ok v] if [k] is - bound to the value [v] in [t] and {!Storage_Error Missing_key} - otherwise. *) - val get : t -> key -> value tzresult Lwt.t - - (** [get_tree] is like {!get} but for trees. *) - val get_tree : t -> key -> tree tzresult Lwt.t - - (** [find t k] is an Lwt promise that resolves to [Some v] if [k] is - bound to the value [v] in [t] and [None] otherwise. *) - val find : t -> key -> value option Lwt.t - - (** [find_tree t k] is like {!find} but for trees. *) - val find_tree : t -> key -> tree option Lwt.t - - (** [list t key] is the list of files and sub-nodes stored under [k] in [t]. - The result order is not specified but is stable. - - [offset] and [length] are used for pagination. *) - val list : - t -> ?offset:int -> ?length:int -> key -> (string * tree) list Lwt.t - - (** {2 Setters} *) - - (** [init t k v] is an Lwt promise that resolves to [Ok c] if: - - - [k] is unbound in [t]; - - [k] is bound to [v] in [c]; - - and [c] is similar to [t] otherwise. - - It is {!Storage_error Existing_key} if [k] is already bound in [t]. *) - val init : t -> key -> value -> t tzresult Lwt.t - - (** [init_tree] is like {!init} but for trees. *) - val init_tree : t -> key -> tree -> t tzresult Lwt.t - - (** [update t k v] is an Lwt promise that resolves to [Ok c] if: - - - [k] is bound in [t]; - - [k] is bound to [v] in [c]; - - and [c] is similar to [t] otherwise. - - It is {!Storage_error Missing_key} if [k] is not already bound in [t]. *) - val update : t -> key -> value -> t tzresult Lwt.t - - (** [update_tree] is like {!update} but for trees. *) - val update_tree : t -> key -> tree -> t tzresult Lwt.t - - (** [add t k v] is an Lwt promise that resolves to [c] such that: - - - [k] is bound to [v] in [c]; - - and [c] is similar to [t] otherwise. - - If [k] was already bound in [t] to a value that is physically equal - to [v], the result of the function is a promise that resolves to - [t]. Otherwise, the previous binding of [k] in [t] disappears. *) - val add : t -> key -> value -> t Lwt.t - - (** [add_tree] is like {!add} but for trees. *) - val add_tree : t -> key -> tree -> t Lwt.t - - (** [remove t k v] is an Lwt promise that resolves to [c] such that: - - - [k] is unbound in [c]; - - and [c] is similar to [t] otherwise. *) - val remove : t -> key -> t Lwt.t - - (** [remove_existing t k v] is an Lwt promise that resolves to [Ok c] if: - - - [k] is bound in [t] to a value; - - [k] is unbound in [c]; - - and [c] is similar to [t] otherwise.*) - val remove_existing : t -> key -> t tzresult Lwt.t - - (** [remove_existing_tree t k v] is an Lwt promise that reolves to [Ok c] if: - - - [k] is bound in [t] to a tree; - - [k] is unbound in [c]; - - and [c] is similar to [t] otherwise.*) - val remove_existing_tree : t -> key -> t tzresult Lwt.t - - (** [add_or_remove t k v] is: - - - [add t k x] if [v] is [Some x]; - - [remove t k] otherwise. *) - val add_or_remove : t -> key -> value option -> t Lwt.t - - (** [add_or_remove_tree t k v] is: - - - [add_tree t k x] if [v] is [Some x]; - - [remove t k] otherwise. *) - val add_or_remove_tree : t -> key -> tree option -> t Lwt.t - - (** {2 Folds} *) - - (** [fold ?depth t root ~init ~f] recursively folds over the trees - and values of [t]. The [f] callbacks are called with a key relative - to [root]. [f] is never called with an empty key for values; i.e., - folding over a value is a no-op. - - Elements are traversed in lexical order of keys. - - The depth is 0-indexed. If [depth] is set (by default it is not), then [f] - is only called when the conditions described by the parameter is true: - - - [Eq d] folds over nodes and contents of depth exactly [d]. - - [Lt d] folds over nodes and contents of depth strictly less than [d]. - - [Le d] folds over nodes and contents of depth less than or equal to [d]. - - [Gt d] folds over nodes and contents of depth strictly more than [d]. - - [Ge d] folds over nodes and contents of depth more than or equal to [d]. *) - val fold : - ?depth:[`Eq of int | `Le of int | `Lt of int | `Ge of int | `Gt of int] -> - t -> - key -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(key -> tree -> 'a -> 'a Lwt.t) -> - 'a Lwt.t -end - -module type TREE = sig - (** [Tree] provides immutable, in-memory partial mirror of the - context, with lazy reads and delayed writes. The trees are Merkle - trees that carry the same hash as the part of the context they - mirror. - - Trees are immutable and non-persistent (they disappear if the - host crash), held in memory for efficiency, where reads are done - lazily and writes are done only when needed, e.g. on - [Context.commit]. If a key is modified twice, only the last - value will be written to disk on commit. *) - - (** The type for context views. *) - type t - - (** The type for context trees. *) - type tree - - include VIEW with type t := tree and type tree := tree - - (** [empty _] is the empty tree. *) - val empty : t -> tree - - (** [is_empty t] is true iff [t] is [empty _]. *) - val is_empty : tree -> bool - - (** [kind t] is [t]'s kind. It's either a tree node or a leaf - value. *) - val kind : tree -> [`Value | `Tree] - - (** [to_value t] is [Some v] is [t] is a leaf tree and [None] otherwise. *) - val to_value : tree -> value option Lwt.t - - (** [hash t] is [t]'s Merkle hash. *) - val hash : tree -> Context_hash.t - - (** [equal x y] is true iff [x] and [y] have the same Merkle hash. *) - val equal : tree -> tree -> bool - - (** {2 Caches} *) - - (** [clear ?depth t] clears all caches in the tree [t] for subtrees with a - depth higher than [depth]. If [depth] is not set, all of the subtrees are - cleared. *) - val clear : ?depth:int -> tree -> unit -end - -module type T = sig - (** The type for root contexts. *) - type root - - include VIEW - - module Tree : - TREE - with type t := t - and type key := key - and type value := value - and type tree := tree - - (** Internally used in {!Storage_functors} to escape from a view. *) - val project : t -> root - - (** Internally used in {!Storage_functors} to retrieve a full key - from partial key relative a view. *) - val absolute_key : t -> key -> key - - (** Raised if block gas quota is exhausted during gas - consumption. *) - type error += Block_quota_exceeded - - (** Raised if operation gas quota is exhausted during gas - consumption. *) - type error += Operation_quota_exceeded - - (** Internally used in {!Storage_functors} to consume gas from - within a view. May raise {!Block_quota_exceeded} or - {!Operation_quota_exceeded}. *) - val consume_gas : t -> Gas_limit_repr.cost -> t tzresult - - (** Check if consume_gas will fail *) - val check_enough_gas : t -> Gas_limit_repr.cost -> unit tzresult - - val description : t Storage_description.t -end diff --git a/src/proto_012_Psithaca/lib_protocol/raw_level_repr.ml b/src/proto_012_Psithaca/lib_protocol/raw_level_repr.ml deleted file mode 100644 index 01f33c8e4b0c..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/raw_level_repr.ml +++ /dev/null @@ -1,108 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = int32 - -type raw_level = t - -include (Compare.Int32 : Compare.S with type t := t) - -let pp ppf level = Format.fprintf ppf "%ld" level - -let rpc_arg = - let construct raw_level = Int32.to_string raw_level in - let destruct str = - Int32.of_string_opt str |> Option.to_result ~none:"Cannot parse level" - in - RPC_arg.make - ~descr:"A level integer" - ~name:"block_level" - ~construct - ~destruct - () - -let root = 0l - -let succ = Int32.succ - -let add l i = - assert (Compare.Int.(i >= 0)) ; - Int32.add l (Int32.of_int i) - -let sub l i = - assert (Compare.Int.(i >= 0)) ; - let res = Int32.sub l (Int32.of_int i) in - if Compare.Int32.(res >= 0l) then Some res else None - -let pred l = if l = 0l then None else Some (Int32.pred l) - -let diff = Int32.sub - -let to_int32 l = l - -let of_int32_exn l = - if Compare.Int32.(l >= 0l) then l else invalid_arg "Level_repr.of_int32" - -let encoding = - Data_encoding.conv_with_guard - (fun i -> i) - (fun i -> try ok (of_int32_exn i) with Invalid_argument s -> Error s) - Data_encoding.int32 - -type error += Unexpected_level of Int32.t (* `Permanent *) - -let () = - register_error_kind - `Permanent - ~id:"unexpected_level" - ~title:"Unexpected level" - ~description:"Level must be non-negative." - ~pp:(fun ppf l -> - Format.fprintf - ppf - "The level is %s but should be non-negative." - (Int32.to_string l)) - Data_encoding.(obj1 (req "level" int32)) - (function Unexpected_level l -> Some l | _ -> None) - (fun l -> Unexpected_level l) - -let of_int32 l = - Error_monad.catch_f (fun () -> of_int32_exn l) (fun _ -> Unexpected_level l) - -module Index = struct - type t = raw_level - - let path_length = 1 - - let to_path level l = Int32.to_string level :: l - - let of_path = function [s] -> Int32.of_string_opt s | _ -> None - - let rpc_arg = rpc_arg - - let encoding = encoding - - let compare = compare -end diff --git a/src/proto_012_Psithaca/lib_protocol/raw_level_repr.mli b/src/proto_012_Psithaca/lib_protocol/raw_level_repr.mli deleted file mode 100644 index a10ebdaa31ea..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/raw_level_repr.mli +++ /dev/null @@ -1,64 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** The shell's notion of a level: an integer indicating the number of blocks - since genesis: genesis is 0, all other blocks have increasing levels from - there. *) -type t - -type raw_level = t - -(** @raise Invalid_argument when the level to encode is not positive *) -val encoding : raw_level Data_encoding.t - -val rpc_arg : raw_level RPC_arg.arg - -val pp : Format.formatter -> raw_level -> unit - -include Compare.S with type t := raw_level - -val to_int32 : raw_level -> int32 - -(** @raise Invalid_argument when the level to encode is negative *) -val of_int32_exn : int32 -> raw_level - -(** Can trigger Unexpected_level error when the level to encode is negative *) -val of_int32 : int32 -> raw_level tzresult - -val diff : raw_level -> raw_level -> int32 - -val root : raw_level - -val succ : raw_level -> raw_level - -val pred : raw_level -> raw_level option - -(** [add l i] i must be positive *) -val add : raw_level -> int -> raw_level - -(** [sub l i] i must be positive *) -val sub : raw_level -> int -> raw_level option - -module Index : Storage_description.INDEX with type t = raw_level diff --git a/src/proto_012_Psithaca/lib_protocol/receipt_repr.ml b/src/proto_012_Psithaca/lib_protocol/receipt_repr.ml deleted file mode 100644 index eeb6ab22a70c..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/receipt_repr.ml +++ /dev/null @@ -1,410 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type balance = - | Contract of Contract_repr.t - | Legacy_rewards of Signature.Public_key_hash.t * Cycle_repr.t - | Block_fees - | Legacy_deposits of Signature.Public_key_hash.t * Cycle_repr.t - | Deposits of Signature.Public_key_hash.t - | Nonce_revelation_rewards - | Double_signing_evidence_rewards - | Endorsing_rewards - | Baking_rewards - | Baking_bonuses - | Legacy_fees of Signature.Public_key_hash.t * Cycle_repr.t - | Storage_fees - | Double_signing_punishments - | Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool - | Liquidity_baking_subsidies - | Burned - | Commitments of Blinded_public_key_hash.t - | Bootstrap - | Invoice - | Initial_commitments - | Minted - -let balance_encoding = - let open Data_encoding in - def "operation_metadata.alpha.balance" - @@ union - [ - case - (Tag 0) - ~title:"Contract" - (obj2 - (req "kind" (constant "contract")) - (req "contract" Contract_repr.encoding)) - (function Contract c -> Some ((), c) | _ -> None) - (fun ((), c) -> Contract c); - case - (Tag 1) - ~title:"Legacy_rewards" - (obj4 - (req "kind" (constant "freezer")) - (req "category" (constant "legacy_rewards")) - (req "delegate" Signature.Public_key_hash.encoding) - (req "cycle" Cycle_repr.encoding)) - (function Legacy_rewards (d, l) -> Some ((), (), d, l) | _ -> None) - (fun ((), (), d, l) -> Legacy_rewards (d, l)); - case - (Tag 2) - ~title:"Block_fees" - (obj2 - (req "kind" (constant "accumulator")) - (req "category" (constant "block fees"))) - (function Block_fees -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Block_fees); - case - (Tag 3) - ~title:"Legacy_deposits" - (obj4 - (req "kind" (constant "freezer")) - (req "category" (constant "legacy_deposits")) - (req "delegate" Signature.Public_key_hash.encoding) - (req "cycle" Cycle_repr.encoding)) - (function - | Legacy_deposits (d, l) -> Some ((), (), d, l) | _ -> None) - (fun ((), (), d, l) -> Legacy_deposits (d, l)); - case - (Tag 4) - ~title:"Deposits" - (obj3 - (req "kind" (constant "freezer")) - (req "category" (constant "deposits")) - (req "delegate" Signature.Public_key_hash.encoding)) - (function Deposits d -> Some ((), (), d) | _ -> None) - (fun ((), (), d) -> Deposits d); - case - (Tag 5) - ~title:"Nonce_revelation_rewards" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "nonce revelation rewards"))) - (function Nonce_revelation_rewards -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Nonce_revelation_rewards); - case - (Tag 6) - ~title:"Double_signing_evidence_rewards" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "double signing evidence rewards"))) - (function - | Double_signing_evidence_rewards -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Double_signing_evidence_rewards); - case - (Tag 7) - ~title:"Endorsing_rewards" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "endorsing rewards"))) - (function Endorsing_rewards -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Endorsing_rewards); - case - (Tag 8) - ~title:"Baking_rewards" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "baking rewards"))) - (function Baking_rewards -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Baking_rewards); - case - (Tag 9) - ~title:"Baking_bonuses" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "baking bonuses"))) - (function Baking_bonuses -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Baking_bonuses); - case - (Tag 10) - ~title:"Legacy_fees" - (obj4 - (req "kind" (constant "freezer")) - (req "category" (constant "legacy_fees")) - (req "delegate" Signature.Public_key_hash.encoding) - (req "cycle" Cycle_repr.encoding)) - (function Legacy_fees (d, l) -> Some ((), (), d, l) | _ -> None) - (fun ((), (), d, l) -> Legacy_fees (d, l)); - case - (Tag 11) - ~title:"Storage_fees" - (obj2 - (req "kind" (constant "burned")) - (req "category" (constant "storage fees"))) - (function Storage_fees -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Storage_fees); - case - (Tag 12) - ~title:"Double_signing_punishments" - (obj2 - (req "kind" (constant "burned")) - (req "category" (constant "punishments"))) - (function Double_signing_punishments -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Double_signing_punishments); - case - (Tag 13) - ~title:"Lost_endorsing_rewards" - (obj5 - (req "kind" (constant "burned")) - (req "category" (constant "lost endorsing rewards")) - (req "delegate" Signature.Public_key_hash.encoding) - (req "participation" Data_encoding.bool) - (req "revelation" Data_encoding.bool)) - (function - | Lost_endorsing_rewards (d, p, r) -> Some ((), (), d, p, r) - | _ -> None) - (fun ((), (), d, p, r) -> Lost_endorsing_rewards (d, p, r)); - case - (Tag 14) - ~title:"Liquidity_baking_subsidies" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "subsidy"))) - (function Liquidity_baking_subsidies -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Liquidity_baking_subsidies); - case - (Tag 15) - ~title:"Burned" - (obj2 - (req "kind" (constant "burned")) - (req "category" (constant "burned"))) - (function Burned -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Burned); - case - (Tag 16) - ~title:"Commitments" - (obj3 - (req "kind" (constant "commitment")) - (req "category" (constant "commitment")) - (req "committer" Blinded_public_key_hash.encoding)) - (function Commitments bpkh -> Some ((), (), bpkh) | _ -> None) - (fun ((), (), bpkh) -> Commitments bpkh); - case - (Tag 17) - ~title:"Bootstrap" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "bootstrap"))) - (function Bootstrap -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Bootstrap); - case - (Tag 18) - ~title:"Invoice" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "invoice"))) - (function Invoice -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Invoice); - case - (Tag 19) - ~title:"Initial_commitments" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "commitment"))) - (function Initial_commitments -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Initial_commitments); - case - (Tag 20) - ~title:"Minted" - (obj2 - (req "kind" (constant "minted")) - (req "category" (constant "minted"))) - (function Minted -> Some ((), ()) | _ -> None) - (fun ((), ()) -> Minted); - ] - -let is_not_zero c = not (Compare.Int.equal c 0) - -let compare_balance ba bb = - match (ba, bb) with - | (Contract ca, Contract cb) -> Contract_repr.compare ca cb - | (Legacy_rewards (pkha, ca), Legacy_rewards (pkhb, cb)) -> - let c = Signature.Public_key_hash.compare pkha pkhb in - if is_not_zero c then c else Cycle_repr.compare ca cb - | (Legacy_deposits (pkha, ca), Legacy_deposits (pkhb, cb)) -> - let c = Signature.Public_key_hash.compare pkha pkhb in - if is_not_zero c then c else Cycle_repr.compare ca cb - | (Deposits pkha, Deposits pkhb) -> - Signature.Public_key_hash.compare pkha pkhb - | ( Lost_endorsing_rewards (pkha, pa, ra), - Lost_endorsing_rewards (pkhb, pb, rb) ) -> - let c = Signature.Public_key_hash.compare pkha pkhb in - if is_not_zero c then c - else - let c = Compare.Bool.compare pa pb in - if is_not_zero c then c else Compare.Bool.compare ra rb - | (Commitments bpkha, Commitments bpkhb) -> - Blinded_public_key_hash.compare bpkha bpkhb - | (Legacy_fees (pkha, ca), Legacy_fees (pkhb, cb)) -> - let c = Signature.Public_key_hash.compare pkha pkhb in - if is_not_zero c then c else Cycle_repr.compare ca cb - | (_, _) -> - let index b = - match b with - | Contract _ -> 0 - | Legacy_rewards _ -> 1 - | Block_fees -> 2 - | Legacy_deposits _ -> 3 - | Deposits _ -> 4 - | Nonce_revelation_rewards -> 5 - | Double_signing_evidence_rewards -> 6 - | Endorsing_rewards -> 7 - | Baking_rewards -> 8 - | Baking_bonuses -> 9 - | Legacy_fees _ -> 10 - | Storage_fees -> 11 - | Double_signing_punishments -> 12 - | Lost_endorsing_rewards _ -> 13 - | Liquidity_baking_subsidies -> 14 - | Burned -> 15 - | Commitments _ -> 16 - | Bootstrap -> 17 - | Invoice -> 18 - | Initial_commitments -> 19 - | Minted -> 20 - (* don't forget to add parameterized cases in the first part of the function *) - in - Compare.Int.compare (index ba) (index bb) - -type balance_update = Debited of Tez_repr.t | Credited of Tez_repr.t - -let balance_update_encoding = - let open Data_encoding in - def "operation_metadata.alpha.balance_update" - @@ obj1 - (req - "change" - (conv - (function - | Credited v -> Tez_repr.to_mutez v - | Debited v -> Int64.neg (Tez_repr.to_mutez v)) - ( Json.wrap_error @@ fun v -> - if Compare.Int64.(v < 0L) then - match Tez_repr.of_mutez (Int64.neg v) with - | Some v -> Debited v - | None -> assert false (* [of_mutez z] is [None] iff [z < 0] *) - else - match Tez_repr.of_mutez v with - | Some v -> Credited v - | None -> assert false (* same *) ) - int64)) - -type update_origin = - | Block_application - | Protocol_migration - | Subsidy - | Simulation - -let compare_update_origin oa ob = - let index o = - match o with - | Block_application -> 0 - | Protocol_migration -> 1 - | Subsidy -> 2 - | Simulation -> 3 - in - Compare.Int.compare (index oa) (index ob) - -let update_origin_encoding = - let open Data_encoding in - def "operation_metadata.alpha.update_origin" - @@ obj1 @@ req "origin" - @@ union - [ - case - (Tag 0) - ~title:"Block_application" - (constant "block") - (function Block_application -> Some () | _ -> None) - (fun () -> Block_application); - case - (Tag 1) - ~title:"Protocol_migration" - (constant "migration") - (function Protocol_migration -> Some () | _ -> None) - (fun () -> Protocol_migration); - case - (Tag 2) - ~title:"Subsidy" - (constant "subsidy") - (function Subsidy -> Some () | _ -> None) - (fun () -> Subsidy); - case - (Tag 3) - ~title:"Simulation" - (constant "simulation") - (function Simulation -> Some () | _ -> None) - (fun () -> Simulation); - ] - -type balance_updates = (balance * balance_update * update_origin) list - -let balance_updates_encoding = - let open Data_encoding in - def "operation_metadata.alpha.balance_updates" - @@ list - (conv - (function - | (balance, balance_update, update_origin) -> - ((balance, balance_update), update_origin)) - (fun ((balance, balance_update), update_origin) -> - (balance, balance_update, update_origin)) - (merge_objs - (merge_objs balance_encoding balance_update_encoding) - update_origin_encoding)) - -module BalanceMap = Map.Make (struct - type t = balance * update_origin - - let compare (ba, ua) (bb, ub) = - let c = compare_balance ba bb in - if is_not_zero c then c else compare_update_origin ua ub -end) - -let group_balance_updates balance_updates = - List.fold_left_e - (fun acc (b, update, o) -> - (match BalanceMap.find (b, o) acc with - | None -> ok update - | Some present -> ( - match (present, update) with - | (Credited a, Debited b) | (Debited b, Credited a) -> - if Tez_repr.(a >= b) then - Tez_repr.(a -? b) >>? fun update -> ok (Credited update) - else Tez_repr.(b -? a) >>? fun update -> ok (Debited update) - | (Credited a, Credited b) -> - Tez_repr.(a +? b) >>? fun update -> ok (Credited update) - | (Debited a, Debited b) -> - Tez_repr.(a +? b) >>? fun update -> ok (Debited update))) - >>? function - | Credited update when Tez_repr.(update = zero) -> - ok (BalanceMap.remove (b, o) acc) - | update -> ok (BalanceMap.add (b, o) update acc)) - BalanceMap.empty - balance_updates - >>? fun map -> - ok (BalanceMap.fold (fun (b, o) u acc -> (b, u, o) :: acc) map []) diff --git a/src/proto_012_Psithaca/lib_protocol/receipt_repr.mli b/src/proto_012_Psithaca/lib_protocol/receipt_repr.mli deleted file mode 100644 index 7457de8aefd6..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/receipt_repr.mli +++ /dev/null @@ -1,80 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Places where tez can be found in the ledger's state. *) -type balance = - | Contract of Contract_repr.t - | Legacy_rewards of Signature.Public_key_hash.t * Cycle_repr.t - | Block_fees - | Legacy_deposits of Signature.Public_key_hash.t * Cycle_repr.t - | Deposits of Signature.Public_key_hash.t - | Nonce_revelation_rewards - | Double_signing_evidence_rewards - | Endorsing_rewards - | Baking_rewards - | Baking_bonuses - | Legacy_fees of Signature.Public_key_hash.t * Cycle_repr.t - | Storage_fees - | Double_signing_punishments - | Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool - | Liquidity_baking_subsidies - | Burned - | Commitments of Blinded_public_key_hash.t - | Bootstrap - | Invoice - | Initial_commitments - | Minted - -(** Compares two balances. *) -val compare_balance : balance -> balance -> int - -(** A credit or debit of tez to a balance. *) -type balance_update = Debited of Tez_repr.t | Credited of Tez_repr.t - -(** An origin of a balance update *) -type update_origin = - | Block_application (** Update from a block application *) - | Protocol_migration (** Update from a protocol migration *) - | Subsidy (** Update from an inflationary subsidy *) - | Simulation (** Simulation of an operation **) - -(** Compares two origins. *) -val compare_update_origin : update_origin -> update_origin -> int - -(** A list of balance updates. Duplicates may happen. - For example, an entry of the form [(Rewards (b,c), Credited am, ...)] - indicates that the balance of frozen rewards has been increased by [am] - for baker [b] and cycle [c]. *) -type balance_updates = (balance * balance_update * update_origin) list - -(** The property [Json.destruct (Json.construct balance_updates) = balance_updates] - does not always hold for [balance_updates_encoding] when [balance_updates] - contains entries of the form [(_, _ Tez_repr.zero, _)]. This is because the - [balance_update] [(_ Tez_repr.zero)] always decodes into [(Credited Tez_repr.zero)]. *) -val balance_updates_encoding : balance_updates Data_encoding.t - -(** Group updates by (balance x origin), and remove zero-valued balances. *) -val group_balance_updates : balance_updates -> balance_updates tzresult diff --git a/src/proto_012_Psithaca/lib_protocol/roll_repr_legacy.ml b/src/proto_012_Psithaca/lib_protocol/roll_repr_legacy.ml deleted file mode 100644 index 598db52da902..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/roll_repr_legacy.ml +++ /dev/null @@ -1,60 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -include Compare.Int32 - -type roll = t - -let encoding = - Data_encoding.( - with_decoding_guard - (fun t -> if t >= 0l then Ok () else Error "Positive int32 required") - int32) - -let first = 0l - -let succ i = Int32.succ i - -let random sequence ~bound = Seed_repr.take_int32 sequence bound - -let rpc_arg = RPC_arg.like RPC_arg.uint31 "roll" - -let to_int32 v = v - -module Index = struct - type t = roll - - let path_length = 1 - - let to_path roll l = Int32.to_string roll :: l - - let of_path = function s :: _ -> Int32.of_string_opt s | _ -> None - - let rpc_arg = rpc_arg - - let encoding = encoding - - let compare = compare -end diff --git a/src/proto_012_Psithaca/lib_protocol/roll_repr_legacy.mli b/src/proto_012_Psithaca/lib_protocol/roll_repr_legacy.mli deleted file mode 100644 index cb792b0128e7..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/roll_repr_legacy.mli +++ /dev/null @@ -1,44 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = private int32 - -type roll = t - -val encoding : roll Data_encoding.t - -val rpc_arg : roll RPC_arg.t - -val random : Seed_repr.sequence -> bound:roll -> roll * Seed_repr.sequence - -val first : roll - -val succ : roll -> roll - -val to_int32 : roll -> Int32.t - -val ( = ) : roll -> roll -> bool - -module Index : Storage_description.INDEX with type t = roll diff --git a/src/proto_012_Psithaca/lib_protocol/roll_storage_legacy.ml b/src/proto_012_Psithaca/lib_protocol/roll_storage_legacy.ml deleted file mode 100644 index b37010dff898..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/roll_storage_legacy.ml +++ /dev/null @@ -1,359 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | (* `Permanent *) Consume_roll_change - | (* `Permanent *) No_roll_for_delegate - | (* `Permanent *) No_stake_snapshot_for_cycle of Cycle_repr.t - | (* `Permanent *) Unregistered_delegate of Signature.Public_key_hash.t - -let () = - let open Data_encoding in - (* Consume roll change *) - register_error_kind - `Permanent - ~id:"contract.manager.consume_roll_change" - ~title:"Consume roll change" - ~description:"Change is not enough to consume a roll." - ~pp:(fun ppf () -> - Format.fprintf ppf "Not enough change to consume a roll.") - empty - (function Consume_roll_change -> Some () | _ -> None) - (fun () -> Consume_roll_change) ; - (* No roll for delegate *) - register_error_kind - `Permanent - ~id:"contract.manager.no_roll_for_delegate" - ~title:"No roll for delegate" - ~description:"Delegate has no roll." - ~pp:(fun ppf () -> Format.fprintf ppf "Delegate has no roll.") - empty - (function No_roll_for_delegate -> Some () | _ -> None) - (fun () -> No_roll_for_delegate) ; - (* No roll snapshot for cycle *) - register_error_kind - `Permanent - ~id:"contract.manager.no_stake_snapshot_for_cycle" - ~title:"No roll snapshot for cycle" - ~description: - "A snapshot of the rolls distribution does not exist for this cycle." - ~pp:(fun ppf c -> - Format.fprintf - ppf - "A snapshot of the rolls distribution does not exist for cycle %a" - Cycle_repr.pp - c) - (obj1 (req "cycle" Cycle_repr.encoding)) - (function No_stake_snapshot_for_cycle c -> Some c | _ -> None) - (fun c -> No_stake_snapshot_for_cycle c) ; - (* Unregistered delegate *) - register_error_kind - `Permanent - ~id:"contract.manager.unregistered_delegate_legacy" - ~title:"Unregistered delegate" - ~description:"A contract cannot be delegated to an unregistered delegate" - ~pp:(fun ppf k -> - Format.fprintf - ppf - "The provided public key (with hash %a) is not registered as valid \ - delegate key." - Signature.Public_key_hash.pp - k) - (obj1 (req "hash" Signature.Public_key_hash.encoding)) - (function Unregistered_delegate k -> Some k | _ -> None) - (fun k -> Unregistered_delegate k) - -let get_contract_delegate ctxt contract = - Storage.Contract.Delegate.find ctxt contract - -let delegate_pubkey ctxt delegate = - Storage.Contract.Manager.find ctxt (Contract_repr.implicit_contract delegate) - >>=? function - | None | Some (Manager_repr.Hash _) -> fail (Unregistered_delegate delegate) - | Some (Manager_repr.Public_key pk) -> return pk - -let fold ctxt ~f init = - Storage.Roll_legacy.Next.get ctxt >>=? fun last -> - let[@coq_struct "roll"] rec loop ctxt roll acc = - if Roll_repr_legacy.(roll = last) then return acc - else - Storage.Roll_legacy.Owner.find ctxt roll >>=? function - | None -> loop ctxt (Roll_repr_legacy.succ roll) acc - | Some delegate -> - f roll delegate acc >>=? fun acc -> - loop ctxt (Roll_repr_legacy.succ roll) acc - in - loop ctxt Roll_repr_legacy.first init - -let get_change ctxt delegate = - Storage.Roll_legacy.Delegate_change.find ctxt delegate - >|=? Option.value ~default:Tez_repr.zero - -module Delegate = struct - let fresh_roll ctxt = - Storage.Roll_legacy.Next.get ctxt >>=? fun roll -> - Storage.Roll_legacy.Next.update ctxt (Roll_repr_legacy.succ roll) - >|=? fun ctxt -> (roll, ctxt) - - let get_limbo_roll ctxt = - Storage.Roll_legacy.Limbo.find ctxt >>=? function - | None -> - fresh_roll ctxt >>=? fun (roll, ctxt) -> - Storage.Roll_legacy.Limbo.init ctxt roll >|=? fun ctxt -> (roll, ctxt) - | Some roll -> return (roll, ctxt) - - let consume_roll_change ctxt delegate = - let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> - record_trace Consume_roll_change Tez_repr.(change -? tokens_per_roll) - >>?= fun new_change -> - Storage.Roll_legacy.Delegate_change.update ctxt delegate new_change - - let recover_roll_change ctxt delegate = - let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> - Tez_repr.(change +? tokens_per_roll) >>?= fun new_change -> - Storage.Roll_legacy.Delegate_change.update ctxt delegate new_change - - let pop_roll_from_delegate ctxt delegate = - recover_roll_change ctxt delegate >>=? fun ctxt -> - (* beginning: - delegate : roll -> successor_roll -> ... - limbo : limbo_head -> ... - *) - Storage.Roll_legacy.Limbo.find ctxt >>=? fun limbo_head -> - Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate >>=? function - | None -> fail No_roll_for_delegate - | Some roll -> - Storage.Roll_legacy.Owner.remove_existing ctxt roll >>=? fun ctxt -> - Storage.Roll_legacy.Successor.find ctxt roll >>=? fun successor_roll -> - Storage.Roll_legacy.Delegate_roll_list.add_or_remove - ctxt - delegate - successor_roll - >>= fun ctxt -> - (* delegate : successor_roll -> ... - roll ------^ - limbo : limbo_head -> ... *) - Storage.Roll_legacy.Successor.add_or_remove ctxt roll limbo_head - >>= fun ctxt -> - (* delegate : successor_roll -> ... - roll ------v - limbo : limbo_head -> ... *) - Storage.Roll_legacy.Limbo.add ctxt roll >|= fun ctxt -> - (* delegate : successor_roll -> ... - limbo : roll -> limbo_head -> ... *) - ok (roll, ctxt) - - let create_roll_in_delegate ctxt delegate delegate_pk = - consume_roll_change ctxt delegate >>=? fun ctxt -> - (* beginning: - delegate : delegate_head -> ... - limbo : roll -> limbo_successor -> ... - *) - Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate - >>=? fun delegate_head -> - get_limbo_roll ctxt >>=? fun (roll, ctxt) -> - Storage.Roll_legacy.Owner.init ctxt roll delegate_pk >>=? fun ctxt -> - Storage.Roll_legacy.Successor.find ctxt roll >>=? fun limbo_successor -> - Storage.Roll_legacy.Limbo.add_or_remove ctxt limbo_successor >>= fun ctxt -> - (* delegate : delegate_head -> ... - roll ------v - limbo : limbo_successor -> ... *) - Storage.Roll_legacy.Successor.add_or_remove ctxt roll delegate_head - >>= fun ctxt -> - (* delegate : delegate_head -> ... - roll ------^ - limbo : limbo_successor -> ... *) - Storage.Roll_legacy.Delegate_roll_list.add ctxt delegate roll - (* delegate : roll -> delegate_head -> ... - limbo : limbo_successor -> ... *) - >|= ok - - let ensure_inited ctxt delegate = - Storage.Roll_legacy.Delegate_change.mem ctxt delegate >>= function - | true -> return ctxt - | false -> - Storage.Roll_legacy.Delegate_change.init ctxt delegate Tez_repr.zero - - let is_inactive ctxt delegate = - Storage.Contract.Inactive_delegate.mem - ctxt - (Contract_repr.implicit_contract delegate) - >>= fun inactive -> - if inactive then return inactive - else - Storage.Contract.Delegate_desactivation.find - ctxt - (Contract_repr.implicit_contract delegate) - >|=? function - | Some last_active_cycle -> - let ({Level_repr.cycle = current_cycle; _} : Level_repr.t) = - Raw_context.current_level ctxt - in - Cycle_repr.(last_active_cycle < current_cycle) - | None -> - (* This case is only when called from `set_active`, when creating - a contract. *) - false - - let add_amount ctxt delegate amount = - ensure_inited ctxt delegate >>=? fun ctxt -> - let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> - Tez_repr.(amount +? change) >>?= fun change -> - Storage.Roll_legacy.Delegate_change.update ctxt delegate change - >>=? fun ctxt -> - delegate_pubkey ctxt delegate >>=? fun delegate_pk -> - let[@coq_struct "change"] rec loop ctxt change = - if Tez_repr.(change < tokens_per_roll) then return ctxt - else - Tez_repr.(change -? tokens_per_roll) >>?= fun change -> - create_roll_in_delegate ctxt delegate delegate_pk >>=? fun ctxt -> - loop ctxt change - in - is_inactive ctxt delegate >>=? fun inactive -> - if inactive then return ctxt - else - loop ctxt change >>=? fun ctxt -> - Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate - >>=? fun rolls -> - match rolls with - | None -> return ctxt - | Some _ -> - Storage.Legacy_active_delegates_with_rolls.add ctxt delegate >|= ok - - let remove_amount ctxt delegate amount = - let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - let[@coq_struct "change"] rec loop ctxt change = - if Tez_repr.(amount <= change) then return (ctxt, change) - else - pop_roll_from_delegate ctxt delegate >>=? fun (_, ctxt) -> - Tez_repr.(change +? tokens_per_roll) >>?= fun change -> loop ctxt change - in - Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> - is_inactive ctxt delegate >>=? fun inactive -> - (if inactive then return (ctxt, change) - else - loop ctxt change >>=? fun (ctxt, change) -> - Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate - >>=? fun rolls -> - match rolls with - | None -> - Storage.Legacy_active_delegates_with_rolls.remove ctxt delegate - >|= fun ctxt -> ok (ctxt, change) - | Some _ -> return (ctxt, change)) - >>=? fun (ctxt, change) -> - Tez_repr.(change -? amount) >>?= fun change -> - Storage.Roll_legacy.Delegate_change.update ctxt delegate change - - let set_inactive ctxt delegate = - ensure_inited ctxt delegate >>=? fun ctxt -> - let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> - Storage.Contract.Inactive_delegate.add - ctxt - (Contract_repr.implicit_contract delegate) - >>= fun ctxt -> - Storage.Legacy_active_delegates_with_rolls.remove ctxt delegate - >>= fun ctxt -> - let[@coq_struct "change"] rec loop ctxt change = - Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate >>=? function - | None -> return (ctxt, change) - | Some _roll -> - pop_roll_from_delegate ctxt delegate >>=? fun (_, ctxt) -> - Tez_repr.(change +? tokens_per_roll) >>?= fun change -> - loop ctxt change - in - loop ctxt change >>=? fun (ctxt, change) -> - Storage.Roll_legacy.Delegate_change.update ctxt delegate change - - let set_active ctxt delegate = - is_inactive ctxt delegate >>=? fun inactive -> - let current_cycle = (Raw_context.current_level ctxt).cycle in - let preserved_cycles = Constants_storage.preserved_cycles ctxt in - (* When the delegate is new or inactive, she will become active in - `1+preserved_cycles`, and we allow `preserved_cycles` for the - delegate to start baking. When the delegate is active, we only - give her at least `preserved_cycles` after the current cycle - before to be deactivated. *) - Storage.Contract.Delegate_desactivation.find - ctxt - (Contract_repr.implicit_contract delegate) - >>=? fun current_expiration -> - let expiration = - match current_expiration with - | None -> Cycle_repr.add current_cycle (1 + (2 * preserved_cycles)) - | Some current_expiration -> - let delay = - if inactive then 1 + (2 * preserved_cycles) - else 1 + preserved_cycles - in - let updated = Cycle_repr.add current_cycle delay in - Cycle_repr.max current_expiration updated - in - Storage.Contract.Delegate_desactivation.add - ctxt - (Contract_repr.implicit_contract delegate) - expiration - >>= fun ctxt -> - if not inactive then return ctxt - else - ensure_inited ctxt delegate >>=? fun ctxt -> - let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> - Storage.Contract.Inactive_delegate.remove - ctxt - (Contract_repr.implicit_contract delegate) - >>= fun ctxt -> - delegate_pubkey ctxt delegate >>=? fun delegate_pk -> - let[@coq_struct "change"] rec loop ctxt change = - if Tez_repr.(change < tokens_per_roll) then return ctxt - else - Tez_repr.(change -? tokens_per_roll) >>?= fun change -> - create_roll_in_delegate ctxt delegate delegate_pk >>=? fun ctxt -> - loop ctxt change - in - loop ctxt change >>=? fun ctxt -> - Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate - >>=? fun rolls -> - match rolls with - | None -> return ctxt - | Some _ -> - Storage.Legacy_active_delegates_with_rolls.add ctxt delegate >|= ok -end - -module Contract = struct - let add_amount c contract amount = - get_contract_delegate c contract >>=? function - | None -> return c - | Some delegate -> Delegate.add_amount c delegate amount - - let remove_amount c contract amount = - get_contract_delegate c contract >>=? function - | None -> return c - | Some delegate -> Delegate.remove_amount c delegate amount -end diff --git a/src/proto_012_Psithaca/lib_protocol/roll_storage_legacy.mli b/src/proto_012_Psithaca/lib_protocol/roll_storage_legacy.mli deleted file mode 100644 index 9d63dea855be..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/roll_storage_legacy.mli +++ /dev/null @@ -1,173 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** - Basic roll manipulation. - - The storage related to roll (i.e. `Storage.Roll`) is not used outside of - this module. And, this interface enforces the invariant that a roll is - always either in the limbo list or owned by a delegate. -*) - -type error += - | (* `Permanent *) Consume_roll_change - | (* `Permanent *) No_roll_for_delegate - | (* `Permanent *) No_stake_snapshot_for_cycle of Cycle_repr.t - | (* `Permanent *) Unregistered_delegate of Signature.Public_key_hash.t - -(** - [fold ctxt f init] folds [f] on the list of all rolls from [Roll_repr.first] - to [Storage.Next.Roll] of the context [ctxt]. Only rolls which have owners - are considered, rolls without owners are skipped. The first parameter of [f] - is a roll [r], the second parameter of [f] is the owner of [r], and the last - parameter is the initial value of the accumulator. -*) -val fold : - Raw_context.t -> - f:(Roll_repr_legacy.roll -> Signature.Public_key.t -> 'a -> 'a tzresult Lwt.t) -> - 'a -> - 'a tzresult Lwt.t - -module Delegate : sig - val is_inactive : - Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t - - (** - [add_amount ctxt dlg am] performs the following actions: - - 1. if the delegate [dlg] is inactive, increase its change [chg] by [am], - 2. if the [dlg] is active, update [dlg]'s number of rolls [nr], and change - [chg] so that [dlg]'s number of tokens is increased by [am], and equal - to [nr * tokens_per_roll + chg], where [chg < tokens_per_roll]. - *) - val add_amount : - Raw_context.t -> - Signature.Public_key_hash.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t - - (** - [remove_amount ctxt dlg am] performs the following actions: - - 1. if the delegate [dlg] is inactive, decrease its change [chg] by [am], - 2. if the [dlg] is active, update [dlg]'s number of rolls [nr], and change - [chg] so that [dlg]'s number of tokens is decreased by [am], and equal to - [nr * tokens_per_roll + chg], where [chg < tokens_per_roll]. - *) - val remove_amount : - Raw_context.t -> - Signature.Public_key_hash.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t - - (** - [set_inactive ctxt dlg] renders delegate [dlg] inactive and performs the - following actions: - - 1. empty the list of rolls of [dlg], - 2. increase the change of [dlg] by [nr * tokens_per_roll], where [nr] is - [dlg]'s number of rolls prior to inactivation. - *) - val set_inactive : - Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t - - (** - If the delegate [dlg] is already active then [set_active ctxt dlg] - performs the following sequence of actions: - - 1. if the delegate is not scheduled to become inactive, then schedule the - delegate to become inactive after [(preserved_cycles * 2) + 1] cycles, - 2. if the delegate is already scheduled to become inactive at cycle [ic], - then re-schedule it to become inactive at cycle - [max ic (cc + preserved_cycles + 1)], where [cc] is the current cycle. - - If [dlg] is inactive then this function puts [dlg] in active state and - performs the following actions: - - 1. if [dlg] is not scheduled to become inactive, schedule [dlg] to become - inactive after [(preserved_cycles * 2) + 1] cycles, - 2. if the [dlg] is already scheduled to become inactive at cycle [ic], - then re-schedule it to become inactive at cycle - [max ic (cc + (preserved_cycles * 2) + 1)], where [cc] is the current - cycle, - 3. dispatch [dlg]'s change [chg] into [nr] rolls of size [tokens_per_roll] - so that the total amount managed by [dlg] is unchanged and equal to - [(nr * tokens_per_roll) + chg], where [chg < tokens_per_roll]. - *) - val set_active : - Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t -end - -module Contract : sig - (** - Calls [Delegate.add_amount ctxt contract am] if a delegate is associated - to [contract], or returns unchanged [ctxt] otherwise. - *) - val add_amount : - Raw_context.t -> - Contract_repr.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t - - (** - Calls [Delegate.remove_amount ctxt contract am] if a delegate is associated - to [contract], or returns unchanged [ctxt] otherwise. - *) - val remove_amount : - Raw_context.t -> - Contract_repr.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t -end - -(** - [delegate_pubkey ctxt delegate] returns the public key of - [delegate] found in context [ctxt] if there exists a registered - contract. -*) -val delegate_pubkey : - Raw_context.t -> - Signature.Public_key_hash.t -> - Signature.Public_key.t tzresult Lwt.t - -(** - [get_change ctxt delegate] returns the amount of change held by - [delegate] in context [ctxt]. The change is the part of the staking - balance of a delegate that is not part of a roll, i.e., the amount - of staking balance (smaller than the value of a roll) not being - taken into account for baking rights computation. -*) -val get_change : - Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t - -(** - [get_contract_delegate ctxt contract] returns the public key hash - of the delegate whose contract is [contract] in context [ctxt]. -*) -val get_contract_delegate : - Raw_context.t -> - Contract_repr.t -> - Signature.Public_key_hash.t option tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/round_repr.ml b/src/proto_012_Psithaca/lib_protocol/round_repr.ml deleted file mode 100644 index d80ad520b9a5..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/round_repr.ml +++ /dev/null @@ -1,429 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type round = int32 - -type t = round - -module Map = Map.Make (Int32) - -include (Compare.Int32 : Compare.S with type t := t) - -let zero = 0l - -let succ n = - if Compare.Int32.equal n Int32.max_int then - invalid_arg "round_repr.succ: cannot apply succ to maximum round value" - else Int32.succ n - -let pp fmt i = Format.fprintf fmt "%ld" i - -type error += Negative_round of int - -type error += Round_overflow of int - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"negative_round" - ~title:"Negative round" - ~description:"Round cannot be built out of negative integers." - ~pp:(fun ppf i -> - Format.fprintf - ppf - "Negative round cannot be built out of negative integers (%Ld)" - i) - (obj1 (req "Negative_round" int64)) - (function Negative_round i -> Some (Int64.of_int i) | _ -> None) - (fun i -> Negative_round (Int64.to_int i)) ; - register_error_kind - `Permanent - ~id:"round_overflow" - ~title:"Round overflow" - ~description: - "Round cannot be built out of integer greater than maximum int32 value." - ~pp:(fun ppf i -> - Format.fprintf - ppf - "Round cannot be built out of integer greater than maximum int32 value \ - (%Ld)" - i) - (obj1 (req "Negative_round" int64)) - (function Round_overflow i -> Some (Int64.of_int i) | _ -> None) - (fun i -> Round_overflow (Int64.to_int i)) - -let of_int32 i = - if i >= 0l then Ok i else error (Negative_round (Int32.to_int i)) - [@@inline] - -let pred r = - let p = Int32.pred r in - of_int32 p - -let of_int i = - if Compare.Int.(i < 0) then error (Negative_round i) - else - (* i is positive *) - let i32 = Int32.of_int i in - if Compare.Int.(Int32.to_int i32 = i) then Ok i32 - else error (Round_overflow i) - -let to_int i32 = - let i = Int32.to_int i32 in - if Int32.(equal (of_int i) i32) then ok i else error (Round_overflow i) - -let to_int32 t = t [@@inline] - -let to_slot round ~committee_size = - to_int round >|? fun r -> - let slot = r mod committee_size in - Slot_repr.of_int_exn slot - -let encoding = - Data_encoding.conv_with_guard - (fun i -> i) - (fun i -> - match of_int32 i with - | Ok _ as res -> res - | Error _ -> Error "Round_repr.encoding: negative round") - Data_encoding.int32 - -module Durations = struct - type t = { - first_round_duration : Period_repr.t; - delay_increment_per_round : Period_repr.t; - } - - type error += - | Non_increasing_rounds of {increment : Period_repr.t} - | Round_durations_must_be_at_least_one_second of {round : Period_repr.t} - - let () = - register_error_kind - `Permanent - ~id:"durations.non_increasing_rounds" - ~title:"Non increasing round" - ~description:"The provided rounds are not increasing." - ~pp:(fun ppf increment -> - Format.fprintf - ppf - "The provided rounds are not increasing (increment: %a)" - Period_repr.pp - increment) - Data_encoding.(obj1 (req "increment" Period_repr.encoding)) - (function - | Non_increasing_rounds {increment} -> Some increment | _ -> None) - (fun increment -> Non_increasing_rounds {increment}) - - let pp fmt t = - Format.fprintf - fmt - "%a,@ +%a" - Period_repr.pp - t.first_round_duration - Period_repr.pp - t.delay_increment_per_round - - let create ~first_round_duration ~delay_increment_per_round = - error_when - Compare.Int64.(Period_repr.to_seconds first_round_duration < 1L) - (Round_durations_must_be_at_least_one_second - {round = first_round_duration}) - >>? fun () -> - error_when - Compare.Int64.(Period_repr.to_seconds delay_increment_per_round < 1L) - (Non_increasing_rounds {increment = delay_increment_per_round}) - >>? fun () -> ok {first_round_duration; delay_increment_per_round} - - let create_opt ~first_round_duration ~delay_increment_per_round = - match create ~first_round_duration ~delay_increment_per_round with - | Ok v -> Some v - | Error _ -> None - - let encoding = - let open Data_encoding in - conv_with_guard - (fun {first_round_duration; delay_increment_per_round} -> - (first_round_duration, delay_increment_per_round)) - (fun (first_round_duration, delay_increment_per_round) -> - match create_opt ~first_round_duration ~delay_increment_per_round with - | None -> - Error - "Either round durations are non-increasing or minimal block \ - delay < 1" - | Some rounds -> Ok rounds) - (obj2 - (req "first_round_duration" Period_repr.encoding) - (req "delay_increment_per_round" Period_repr.encoding)) - - let round_duration {first_round_duration; delay_increment_per_round} round = - if Compare.Int32.(round < 0l) then - invalid_arg "round must be a non-negative integer" - else - let first_round_duration_s = Period_repr.to_seconds first_round_duration - and delay_increment_per_round_s = - Period_repr.to_seconds delay_increment_per_round - in - Period_repr.of_seconds_exn - Int64.( - add - first_round_duration_s - (mul (of_int32 round) delay_increment_per_round_s)) -end - -type error += Round_too_high of int32 - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"round_too_high" - ~title:"round too high" - ~description:"block round too high." - ~pp:(fun ppf round -> - Format.fprintf ppf "Block round is too high: %ld" round) - (obj1 (req "level_offset_too_high" int32)) - (function Round_too_high round -> Some round | _ -> None) - (fun round -> Round_too_high round) - -(* The duration of round n follows the arithmetic sequence: - - round_duration(0) = first_round_duration - round_duration(r+1) = round_duration(r) + delay_increment_per_round - - Hence, this sequence can be explicited into: - - round_duration(r) = first_round_duration + r * delay_increment_per_round - - The level offset of round r is the sum of the durations of the rounds up - until round r - 1. In other words, when r > 0 - - level_offset_of_round(0) = 0 - level_offset_of_round(r+1) = level_offset_of_round(r) + round_duration(r) - -Hence - - level_offset_of_round(r) = Σ_{k=0}^{r-1} (round_duration(k)) - - After unfolding the series, the same function can be finally explicited into - - level_offset_of_round(0) = 0 - level_offset_of_round(r) = r * first_round_duration - + 1/2 * r * (r - 1) * delay_increment_per_round -*) -let level_offset_of_round round_durations ~round = - if Compare.Int32.(round = zero) then ok Int64.zero - else - let sum_durations = - let Durations.{first_round_duration; delay_increment_per_round} = - round_durations - in - let roundz = Int64.of_int32 round in - let m = Z.of_int64 Int64.(div (mul roundz (pred roundz)) (of_int 2)) in - Z.( - add - (mul - m - (Z.of_int64 @@ Period_repr.to_seconds delay_increment_per_round)) - (mul - (Z.of_int32 round) - (Z.of_int64 @@ Period_repr.to_seconds first_round_duration))) - in - if Compare.Z.(sum_durations > Z.of_int64 Int64.max_int) then - error (Round_too_high round) - else ok (Z.to_int64 sum_durations) - -type error += Level_offset_too_high of Period_repr.t - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"level_offset_too_high" - ~title:"level offset too high" - ~description:"The block's level offset is too high." - ~pp:(fun ppf offset -> - Format.fprintf - ppf - "The block's level offset is too high: %a" - Period_repr.pp - offset) - (obj1 (req "level_offset_too_high" Period_repr.encoding)) - (function Level_offset_too_high offset -> Some offset | _ -> None) - (fun offset -> Level_offset_too_high offset) - -type round_and_offset = {round : int32; offset : Period_repr.t} - -(** Complexity: O(log max_int). *) -let round_and_offset round_durations ~level_offset = - let level_offset_in_seconds = Period_repr.to_seconds level_offset in - (* We have the invariant [round <= level_offset] so there is no need to search - beyond [level_offset]. We set [right_bound] to [level_offset + 1] to avoid - triggering the error level_offset too high when the round equals - [level_offset]. *) - let right_bound = - if Compare.Int64.(level_offset_in_seconds < Int64.of_int32 Int32.max_int) - then Int32.of_int (Int64.to_int level_offset_in_seconds + 1) - else Int32.max_int - in - let rec bin_search min_r max_r = - if Compare.Int32.(min_r >= right_bound) then - error (Level_offset_too_high level_offset) - else - let round = Int32.(add min_r (div (sub max_r min_r) 2l)) in - level_offset_of_round round_durations ~round:(Int32.succ round) - >>? fun next_level_offset -> - if - Compare.Int64.(Period_repr.to_seconds level_offset >= next_level_offset) - then bin_search (Int32.succ round) max_r - else - level_offset_of_round round_durations ~round - >>? fun current_level_offset -> - if - Compare.Int64.( - Period_repr.to_seconds level_offset < current_level_offset) - then bin_search min_r round - else - ok - { - round; - offset = - Period_repr.of_seconds_exn - (Int64.sub - (Period_repr.to_seconds level_offset) - current_level_offset); - } - in - bin_search 0l right_bound - -(** Complexity: O(|round_durations|). *) -let timestamp_of_round round_durations ~predecessor_timestamp ~predecessor_round - ~round = - let pred_round_duration = - Durations.round_duration round_durations predecessor_round - in - (* First, the function computes when the current level l is supposed - to start. This is given by adding to the timestamp of the round - of predecessor level l-1 [predecessor_timestamp], the duration of - its last round [predecessor_round]. *) - Time_repr.(predecessor_timestamp +? pred_round_duration) - >>? fun start_of_current_level -> - (* Finally, we sum the durations of the rounds at the current level l until - reaching current [round]. *) - level_offset_of_round round_durations ~round >>? fun level_offset -> - let level_offset = Period_repr.of_seconds_exn level_offset in - Time_repr.(start_of_current_level +? level_offset) - -(** Unlike [timestamp_of_round], this function gets the starting time - of a given round, given the timestamp and the round of a proposal - at the same level. - - We compute the starting time of [considered_round] from a given - [round_durations] description, some [current_round], and its - starting time [current_timestamp]. - - Complexity: O(|round_durations|). *) -let timestamp_of_another_round_same_level round_durations ~current_timestamp - ~current_round ~considered_round = - level_offset_of_round round_durations ~round:considered_round - >>? fun target_offset -> - level_offset_of_round round_durations ~round:current_round - >>? fun current_offset -> - ok - @@ Time_repr.of_seconds - Int64.( - add - (sub (Time_repr.to_seconds current_timestamp) current_offset) - target_offset) - -type error += - | Round_of_past_timestamp of { - provided_timestamp : Time.t; - predecessor_timestamp : Time.t; - predecessor_round : t; - } - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"round_of_past_timestamp" - ~title:"Round_of_timestamp for past timestamp" - ~description:"Provided timestamp is before the expected level start." - ~pp:(fun ppf (provided_ts, predecessor_ts, round) -> - Format.fprintf - ppf - "Provided timestamp (%a) is before the expected level start (computed \ - based on predecessor_ts %a at round %a)." - Time.pp_hum - provided_ts - Time.pp_hum - predecessor_ts - pp - round) - (obj3 - (req "provided_timestamp" Time.encoding) - (req "predecessor_timestamp" Time.encoding) - (req "predecessor_round" encoding)) - (function - | Round_of_past_timestamp - {provided_timestamp; predecessor_timestamp; predecessor_round} -> - Some (provided_timestamp, predecessor_timestamp, predecessor_round) - | _ -> None) - (fun (provided_timestamp, predecessor_timestamp, predecessor_round) -> - Round_of_past_timestamp - {provided_timestamp; predecessor_timestamp; predecessor_round}) - -let round_of_timestamp round_durations ~predecessor_timestamp ~predecessor_round - ~timestamp = - let round_duration = - Durations.round_duration round_durations predecessor_round - in - Time_repr.(predecessor_timestamp +? round_duration) - >>? fun start_of_current_level -> - Period_repr.of_seconds (Time_repr.diff timestamp start_of_current_level) - |> Error_monad.record_trace - (Round_of_past_timestamp - { - predecessor_timestamp; - provided_timestamp = timestamp; - predecessor_round; - }) - >>? fun diff -> - round_and_offset round_durations ~level_offset:diff - >>? fun round_and_offset -> ok round_and_offset.round - -let level_offset_of_round round_durations ~round = - level_offset_of_round round_durations ~round >>? fun offset -> - ok (Period_repr.of_seconds_exn offset) - -module Internals_for_test = struct - type round_and_offset_raw = {round : round; offset : Period_repr.t} - - let round_and_offset round_durations ~level_offset = - round_and_offset round_durations ~level_offset >|? fun v -> - {round = v.round; offset = v.offset} -end diff --git a/src/proto_012_Psithaca/lib_protocol/round_repr.mli b/src/proto_012_Psithaca/lib_protocol/round_repr.mli deleted file mode 100644 index 292ed5d939b8..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/round_repr.mli +++ /dev/null @@ -1,245 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** A round represents an iteration of the single-shot consensus algorithm. - - Rounds can be seen as an infinite, 0-indexed, list of durations. The - durations are generated by an arithmetic progression depending on - {!val:Constants_repr.minimal_block_delay} (its initial value, a.k.a the one for - round 0) and {!val:Constants_repr.delay_increment_per_round} (its common - difference) . - - Round identifiers are non-negative 32 bit integers. This interface ensures - that no negative round can be created. *) - -type round - -type t = round - -(** Round zero *) -val zero : t - -(** Successor of the given round. - - @raise [Invalid_arg] if applied to the upper bound of the round integer - representation. *) -val succ : t -> t - -(** Predecessor of the given round. - Returns an error if applied to [zero], as negative round are - prohibited. *) -val pred : t -> t tzresult - -(** Building a round from an int32. - Returns an error if applied to a negative number. *) -val of_int32 : int32 -> t tzresult - -val to_int32 : t -> int32 - -(** Building a round from an int. - Returns an error if applied to a negative number or a number - greater than Int32.max_int. *) -val of_int : int -> t tzresult - -(** Building an int from a round. - Returns an error if the value does not fit in max_int. (current - 32bit encodings always fit in int on 64bit architecture though). *) -val to_int : t -> int tzresult - -(** Returns the slot corresponding to the given round [r], that is [r - mod committee_size]. *) -val to_slot : t -> committee_size:int -> Slot_repr.t tzresult - -(** Round encoding. - Be aware that decoding a negative 32 bit integer would lead to an - exception. *) -val encoding : t Data_encoding.t - -val pp : Format.formatter -> t -> unit - -include Compare.S with type t := t - -module Map : Map.S with type key = t - -(** {2 Round duration representation} *) - -module Durations : sig - (** [round_durations] represents the duration of rounds in seconds *) - type t - - val pp : Format.formatter -> t -> unit - - (** {3 Creation functions} *) - - (** [create ~first_round_duration ~delay_increment_per_round] creates a valid - duration value - - @param first_round_duration duration of round 0 - @param delay_increment_per_round amount of time added in from one round - duration to the duration of its next round - @raises Invalid_argument if - - first_round_duration <= 1; or - - delay_increment_per_round is <= 0 - *) - val create : - first_round_duration:Period_repr.t -> - delay_increment_per_round:Period_repr.t -> - t tzresult - - (** [create_opt ~first_round_duration ~delay_increment_per_round] returns a valid duration value - [Some d] when [create ~first_round_duration ~delay_increment_per_round] - does not fail. It returns [None] otherwise. *) - val create_opt : - first_round_duration:Period_repr.t -> - delay_increment_per_round:Period_repr.t -> - t option - - (** {b Warning} May trigger an exception when the expected invariant - does not hold. *) - val encoding : t Data_encoding.encoding - - (** {3 Accessors}*) - - (** [round_duration round_durations ~round] returns the duration of round - [~round]. This duration follows the arithmetic progression - - duration(round_n) = [first_round_duration] + round_n * [delay_increment_per_round] - - *) - val round_duration : t -> round -> Period_repr.t -end - -(** [level_offset_of_round round_durations ~round:r] represents the offset of the - starting time of round [r] with respect to the start of the level. - round = 0 1 2 3 r - - |-----|-----|-----|-----|-----|--- ... ... --|------|------- - | - <-------------------------------------------> - level_offset -*) -val level_offset_of_round : Durations.t -> round:t -> Period_repr.t tzresult - -(** [timestamp_of_round round_durations ~predecessor_timestamp:pred_ts - ~predecessor_round:pred_round ~round] returns the - starting time of round [round] given that the timestamp and the round of - the block at the previous level is [pred_ts] and [pred_round], - respectively. - - pred_round = 0 pred_round - - |-----|.. ... --|--------|-- ... --|------- - | | - | | - pred_ts | - | - start_of_cur_level - | - | - |-----|------|-- ... --|-------|- - cur_round = 0 1 | round - | - res_ts - - Precisely, the resulting timestamp is: - [pred_ts + round_duration(pred_round) + level_offset_of_round(round)]. -*) -val timestamp_of_round : - Durations.t -> - predecessor_timestamp:Time_repr.t -> - predecessor_round:t -> - round:t -> - Time_repr.t tzresult - -(** [timestamp_of_another_round_same_level - round_durations - ~current_timestamp - ~current_round - ~considered_round] - returns the starting time of round [considered_round]. - - start of current - level current ts result - | | | - | | | - |-----|----...--|-- ... ------|- - | | | | - cur_round = 0 1 current considered - round round - - It also works when [considered_round] is lower than [current_round]. - - Precisely, the resulting timestamp is: - [current_timestamp - level_offset_of_round(current_round) - + level_offset_of_round(considered_round)]. -*) -val timestamp_of_another_round_same_level : - Durations.t -> - current_timestamp:Time_repr.t -> - current_round:t -> - considered_round:t -> - Time_repr.t tzresult - -(** [round_of_timestamp round_durations ~predecessor_timestamp ~predecessor_round - ~timestamp:ts] returns the round to which the timestamp [ts] belongs to, - given that the timestamp and the round of the block at the previous level is - [pred_ts] and [pred_round], respectively. - - Precisely, the resulting round is: - [round_and_offset round_durations ~level_offset:diff] where - [diff = ts - (predecessor_timestamp + round_duration(predecessor_round)]. - - Returns an error when the timestamp is before the level start.*) -val round_of_timestamp : - Durations.t -> - predecessor_timestamp:Time_repr.t -> - predecessor_round:t -> - timestamp:Time_repr.t -> - t tzresult - -module Internals_for_test : sig - type round_and_offset_raw = {round : round; offset : Period_repr.t} - - (** [round_and_offset round_durations ~level_offset], where [level_offset] - represents a time offset with respect to the start of the first round, - returns a tuple [(r, round_offset)] where the round [r] is such that - [level_offset_of_round(r) <= level_offset < level_offset_of_round(r+1)] and - [round_offset := level_offset - level_offset_of_round(r)]]. - - round = 0 1 2 3 r - - |-----|-----|-----|-----|-----|--- ... ... --|--------|-- ... --|------- - | - round_delay(r) - | - | - <-----> - round_offset - <---------------------------------------------------> - level_offset -*) - val round_and_offset : - Durations.t -> level_offset:Period_repr.t -> round_and_offset_raw tzresult -end diff --git a/src/proto_012_Psithaca/lib_protocol/sampler.ml b/src/proto_012_Psithaca/lib_protocol/sampler.ml deleted file mode 100644 index 3e7737d2f76e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/sampler.ml +++ /dev/null @@ -1,209 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* - - This module implements the alias method for sampling from a given - distribution. The distribution need not be normalized. - -*) - -module type Mass = sig - type t - - val encoding : t Data_encoding.t - - val zero : t - - val of_int : int -> t - - val mul : t -> t -> t - - val add : t -> t -> t - - val sub : t -> t -> t - - val ( = ) : t -> t -> bool - - val ( <= ) : t -> t -> bool - - val ( < ) : t -> t -> bool -end - -module type S = sig - type mass - - type 'a t - - val create : ('a * mass) list -> 'a t - - val sample : 'a t -> (int_bound:int -> mass_bound:mass -> int * mass) -> 'a - - val encoding : 'a Data_encoding.t -> 'a t Data_encoding.t -end - -module Make (Mass : Mass) : S with type mass = Mass.t = struct - type mass = Mass.t - - type 'a t = { - total : Mass.t; - support : 'a FallbackArray.t; - p : Mass.t FallbackArray.t; - alias : int FallbackArray.t; - } - - let rec init_loop total p alias small large = - match (small, large) with - | ([], _) -> List.iter (fun (_, i) -> FallbackArray.set p i total) large - | (_, []) -> - (* This can only happen because of numerical inaccuracies when using - eg [Mass.t = float] *) - List.iter (fun (_, i) -> FallbackArray.set p i total) small - | ((qi, i) :: small', (qj, j) :: large') -> - FallbackArray.set p i qi ; - FallbackArray.set alias i j ; - let qj' = Mass.sub (Mass.add qi qj) total in - if Mass.(qj' < total) then - init_loop total p alias ((qj', j) :: small') large' - else init_loop total p alias small' ((qj', j) :: large') - - let support : - fallback:'a -> length:int -> ('a * Mass.t) list -> 'a FallbackArray.t = - fun ~fallback ~length measure -> - let a = FallbackArray.make length fallback in - List.iteri (fun i (elt, _) -> FallbackArray.set a i elt) measure ; - a - - let check_and_cleanup measure = - let (total, measure) = - List.fold_left - (fun ((total, m) as acc) ((_, p) as point) -> - if Mass.(zero < p) then (Mass.add total p, point :: m) - else if Mass.(p < zero) then invalid_arg "create" - else (* p = zero: drop point *) - acc) - (Mass.zero, []) - measure - in - match measure with - | [] -> invalid_arg "create" - | (fallback, _) :: _ -> (fallback, total, measure) - - (* NB: duplicate elements in the support are not merged; - the algorithm should still function correctly. *) - let create (measure : ('a * Mass.t) list) = - let (fallback, total, measure) = check_and_cleanup measure in - let length = List.length measure in - let n = Mass.of_int length in - let (_, small, large) = - List.fold_left - (fun (i, small, large) (_, p) -> - let q = Mass.mul p n in - if Mass.(q < total) then (i + 1, (q, i) :: small, large) - else (i + 1, small, (q, i) :: large)) - (0, [], []) - measure - in - let support = support ~fallback ~length measure in - let p = FallbackArray.make length total in - let alias = FallbackArray.make length (-1) in - init_loop total p alias small large ; - {total; support; p; alias} - - let sample {total; support; p; alias} draw_i_elt = - let n = FallbackArray.length support in - let (i, elt) = draw_i_elt ~int_bound:n ~mass_bound:total in - let p = FallbackArray.get p i in - if Mass.(elt < p) then FallbackArray.get support i - else - let j = FallbackArray.get alias i in - assert (Compare.Int.(j >= 0)) ; - FallbackArray.get support j - - (* Note: this could go in the environment maybe? *) - let array_encoding : 'a Data_encoding.t -> 'a FallbackArray.t Data_encoding.t - = - fun venc -> - let open Data_encoding in - conv - (fun array -> - let length = FallbackArray.length array in - let fallback = FallbackArray.fallback array in - let elements = - List.rev (FallbackArray.fold (fun acc elt -> elt :: acc) array []) - in - (length, fallback, elements)) - (fun (length, fallback, elements) -> - let array = FallbackArray.make length fallback in - List.iteri (fun i elt -> FallbackArray.set array i elt) elements ; - array) - (obj3 - (req "length" int31) - (req "fallback" venc) - (req "elements" (list venc))) - - let mass_array_encoding = array_encoding Mass.encoding - - let int_array_encoding = array_encoding Data_encoding.int31 - - let encoding enc = - let open Data_encoding in - conv - (fun {total; support; p; alias} -> (total, support, p, alias)) - (fun (total, support, p, alias) -> {total; support; p; alias}) - (obj4 - (req "total" Mass.encoding) - (req "support" (array_encoding enc)) - (req "p" mass_array_encoding) - (req "alias" int_array_encoding)) -end - -module Internal_for_tests = struct - module Make = Make -end - -module Mass : Mass with type t = int64 = struct - type t = int64 - - let encoding = Data_encoding.int64 - - let zero = 0L - - let of_int = Int64.of_int - - let mul = Int64.mul - - let add = Int64.add - - let sub = Int64.sub - - let ( = ) = Compare.Int64.( = ) - - let ( <= ) = Compare.Int64.( <= ) - - let ( < ) = Compare.Int64.( < ) -end - -include Make (Mass) diff --git a/src/proto_012_Psithaca/lib_protocol/sampler.mli b/src/proto_012_Psithaca/lib_protocol/sampler.mli deleted file mode 100644 index cd4b8b950178..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/sampler.mli +++ /dev/null @@ -1,98 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) -(** Efficient sampling from given finitely supported (nonzero, positive) - measures using the alias method. Measures need not be normalized on input, - but sampling proceeds from the normalized probability measure associated - to the given measure. - *) - -(** [Mass] is the module type describing the measure associated to points. *) -module type Mass = sig - (** [t] is the type describing the measure associated to points. *) - type t - - val encoding : t Data_encoding.t - - val zero : t - - val of_int : int -> t - - val mul : t -> t -> t - - val add : t -> t -> t - - val sub : t -> t -> t - - val ( = ) : t -> t -> bool - - val ( <= ) : t -> t -> bool - - val ( < ) : t -> t -> bool -end - -(** [S] is the module type of a module allowing to construct samplers based - on the alias method. *) -module type S = sig - (** [mass] is the type in which finite measures take their values - (see [Mass] module type). *) - type mass - - (** ['a t] is the type of auxilliary data for sampling from - a given distribution. *) - type 'a t - - (** [create measure] constructs auxilliary data to sample from - [measure] after normalization. Complexity: O(n). - - It is assumed that the measure is positive. [measure] can contain - zero mass elements: those are removed in a pre-processing step. - The total mass of the measure should be strictly positive. - - @raise Invalid_argument if [measure] contains negative mass elements - or if it contains only zero mass elements. *) - val create : ('a * mass) list -> 'a t - - (** [sample auxdata rand] creates a sampler from [auxdata] that follows - the distribution associated to the measure specified when - creating the [auxdata]. The parameter [rand] is a random sampler - for the two random values used by the sampling method. The first - bound is at most the length of the list passed to [create] when - creating [auxdata]. The second bound is at most the sum of all - items in the list passed to [create]. *) - val sample : 'a t -> (int_bound:int -> mass_bound:mass -> int * mass) -> 'a - - (** [encoding e] constructs an encoding for ['a t] given an encoding for ['a]. *) - val encoding : 'a Data_encoding.t -> 'a t Data_encoding.t -end - -(**/**) - -module Internal_for_tests : sig - (** [Make(Mass)] instantiates a module allowing to creates - samplers for [Mass]-valued finite measures. *) - module Make : functor (Mass : Mass) -> S with type mass = Mass.t -end - -include S with type mass = Int64.t diff --git a/src/proto_012_Psithaca/lib_protocol/sapling_repr.ml b/src/proto_012_Psithaca/lib_protocol/sapling_repr.ml deleted file mode 100644 index 2b5dc17ef038..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/sapling_repr.ml +++ /dev/null @@ -1,200 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type transaction = Sapling.UTXO.transaction - -let transaction_encoding = Sapling.UTXO.transaction_encoding - -(* The two data structures in the state are all ordered by position, a diff - contains the elements starting from an offset position up to the most recent - position. A diff can be applied to a state stored in a context to obtain a - new state. - Diffs are used by the Michelson interpreter during the evaluation of smart - contracts to keep a temporary state that may be discarded. - Diffs are also returned by an RPC to allow a client to synchronize its own - state with the chain. - *) -type diff = { - commitments_and_ciphertexts : - (Sapling.Commitment.t * Sapling.Ciphertext.t) list; - nullifiers : Sapling.Nullifier.t list; -} - -let diff_encoding = - let open Data_encoding in - conv - (fun d -> (d.commitments_and_ciphertexts, d.nullifiers)) - (fun (commitments_and_ciphertexts, nullifiers) -> - (match commitments_and_ciphertexts with - | [] -> () - | (_cm_hd, ct_hd) :: rest -> - let memo_size = Sapling.Ciphertext.get_memo_size ct_hd in - List.iter - (fun (_cm, ct) -> - assert ( - Compare.Int.(Sapling.Ciphertext.get_memo_size ct = memo_size))) - rest) ; - {commitments_and_ciphertexts; nullifiers}) - (obj2 - (req - "commitments_and_ciphertexts" - (list (tup2 Sapling.Commitment.encoding Sapling.Ciphertext.encoding))) - (req "nullifiers" (list Sapling.Nullifier.encoding))) - -module Memo_size = struct - type t = int - - let encoding = Data_encoding.uint16 - - let equal = Compare.Int.( = ) - - let max_uint16 = 0xffff - - let max_uint16_z = Z.of_int max_uint16 - - let err = - Error - ("a positive 16-bit integer (between 0 and " ^ string_of_int max_uint16 - ^ ")") - - let parse_z z = - if Compare.Z.(Z.zero <= z) && Compare.Z.(z <= max_uint16_z) then - Ok (Z.to_int z) - else err - - let unparse_to_z = Z.of_int -end - -let transaction_get_memo_size (transaction : Sapling.UTXO.transaction) = - match transaction.outputs with - | [] -> None - | {ciphertext; _} :: _ -> - (* Encoding ensures all ciphertexts have the same memo size. *) - Some (Sapling.Ciphertext.get_memo_size ciphertext) - -open Cache_memory_helpers - -(* This should be exported by [lib_sapling] rather than implemented here. *) -let input_in_memory_size = - (* type input = - * Sapling.UTXO.input = { - * cv : Sapling.CV.t; - * nf : Sapling.Nullifier.t; - * rk : Sapling.UTXO.rk; - * proof_i : Sapling.UTXO.spend_proof; - * signature : Sapling.UTXO.spend_sig; - * } *) - let cv_size = string_size_gen 32 in - let nf_size = string_size_gen 32 in - let rk_size = string_size_gen 32 in - let proof_i_size = string_size_gen @@ (48 + 96 + 48) in - let signature_size = string_size_gen 64 in - header_size +! (word_size *? 5) +! cv_size +! nf_size +! rk_size - +! proof_i_size +! signature_size - -let ciphertext_size = - (* type t = { - * cv : CV.t; - * epk : DH.epk; - * payload_enc : Bytes.t; - * nonce_enc : Crypto_box.nonce; - * payload_out : Bytes.t; - * nonce_out : Crypto_box.nonce; - * } *) - let cv_size = string_size_gen 32 in - let epk_size = string_size_gen 32 in - let nonce_enc_size = - string_size_gen 24 - (* from lib_hacl_glue/unix/hacl.ml:Nonce.size *) - in - let payload_out_size = - string_size_gen (32 + 32 + 16) - (* from lib_sapling/core.ml:Ciphertext.encoding *) - in - let nonce_out_size = string_size_gen 24 in - let fixed_payload_data_size = - 11 + 8 + 32 + 16 + 4 - (* from lib_sapling/core.ml:Ciphertext.get_memo_size *) - in - - fun memo_size -> - let payload_size = string_size_gen (memo_size + fixed_payload_data_size) in - header_size +! (word_size *? 6) +! cv_size +! epk_size +! payload_size - +! nonce_enc_size +! payload_out_size +! nonce_out_size - -let output_in_memory_size = - (* type output = { - * cm : Commitment.t; - * proof_o : output_proof; - * ciphertext : Ciphertext.t; - * } *) - let cm_size = string_size_gen 32 in - let proof_o_size = string_size_gen @@ (48 + 96 + 48) in - let ciphertext_size = ciphertext_size in - - fun memo_size -> - header_size +! (word_size *? 3) +! cm_size +! proof_o_size - +! ciphertext_size memo_size - -(** Returns an approximation of the in-memory size of a Sapling transaction. *) -let transaction_in_memory_size (transaction : Sapling.UTXO.transaction) = - (* type transaction = - * transaction = { - * inputs : Sapling.UTXO.input list; - * outputs : Sapling.UTXO.output list; - * binding_sig : Sapling.UTXO.binding_sig; - * balance : int64; - * root : Sapling.Hash.t; - * } *) - let binding_sig_size = string_size_gen 64 in - let balance_size = int64_size in - let root_size = string_size_gen 32 in - let inputs = List.length transaction.inputs in - let outputs = List.length transaction.outputs in - let memo_size = - Option.value ~default:0 (transaction_get_memo_size transaction) - in - header_size +! (word_size *? 5) - +! (list_cell_size input_in_memory_size *? inputs) - +! (list_cell_size (output_in_memory_size memo_size) *? outputs) - +! binding_sig_size +! balance_size +! root_size - -(** Returns an approximation of the in-memory size of a Sapling diff. *) -let diff_in_memory_size ({commitments_and_ciphertexts; nullifiers} : diff) = - let cms_and_cts = List.length commitments_and_ciphertexts in - let nfs = List.length nullifiers in - let cm_size = string_size_gen 32 in - let nf_size = string_size_gen 32 in - let memo_size = - (* All memo_size in a diff should be equal (see invariant enforced by - [diff] encoding above) *) - match commitments_and_ciphertexts with - | [] -> 0 - | (_, ct) :: _ -> Sapling.Ciphertext.get_memo_size ct - in - header_size +! (word_size *? 2) - +! list_cell_size (boxed_tup2 cm_size (ciphertext_size memo_size)) - *? cms_and_cts - +! (list_cell_size nf_size *? nfs) diff --git a/src/proto_012_Psithaca/lib_protocol/sapling_services.ml b/src/proto_012_Psithaca/lib_protocol/sapling_services.ml deleted file mode 100644 index 738cecaaff22..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/sapling_services.ml +++ /dev/null @@ -1,103 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -let custom_root = - (RPC_path.(open_root / "context" / "sapling") - : RPC_context.t RPC_path.context) - -type diff_query = { - offset_commitment : Int64.t option; - offset_nullifier : Int64.t option; -} - -module S = struct - module Args = struct - type ('query_type, 'output_type) t = { - name : string; - description : string; - query : 'query_type RPC_query.t; - output : 'output_type Data_encoding.t; - f : context -> Sapling.Id.t -> 'query_type -> 'output_type tzresult Lwt.t; - } - - let get_diff_query : diff_query RPC_query.t = - let open RPC_query in - query (fun offset_commitment offset_nullifier -> - {offset_commitment; offset_nullifier}) - |+ opt_field - ~descr: - "Commitments and ciphertexts are returned from the specified \ - offset up to the most recent." - "offset_commitment" - RPC_arg.uint63 - (fun {offset_commitment; _} -> offset_commitment) - |+ opt_field - ~descr: - "Nullifiers are returned from the specified offset up to the most \ - recent." - "offset_nullifier" - RPC_arg.uint63 - (fun {offset_nullifier; _} -> offset_nullifier) - |> seal - - let encoding = - let open Data_encoding in - merge_objs (obj1 (req "root" Sapling.root_encoding)) Sapling.diff_encoding - - let get_diff = - { - name = "get_diff"; - description = - "Returns the root and a diff of a state starting from an optional \ - offset which is zero by default."; - query = get_diff_query; - output = encoding; - f = - (fun ctxt id {offset_commitment; offset_nullifier} -> - Sapling.get_diff ctxt id ?offset_commitment ?offset_nullifier ()); - } - end - - let make_service Args.{name; description; query; output; f} = - let path = RPC_path.(custom_root /: Sapling.rpc_arg / name) in - let service = RPC_service.get_service ~description ~query ~output path in - (service, fun ctxt id q () -> f ctxt id q) - - let get_diff = make_service Args.get_diff -end - -let register () = - let reg ~chunked (service, f) = - Services_registration.register1 ~chunked service f - in - reg ~chunked:false S.get_diff - -let mk_call1 (service, _f) ctxt block id q = - RPC_context.make_call1 service ctxt block id q () - -let get_diff ctxt block id ?offset_commitment ?offset_nullifier () = - mk_call1 S.get_diff ctxt block id {offset_commitment; offset_nullifier} diff --git a/src/proto_012_Psithaca/lib_protocol/sapling_storage.ml b/src/proto_012_Psithaca/lib_protocol/sapling_storage.ml deleted file mode 100644 index 167f75f1f913..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/sapling_storage.ml +++ /dev/null @@ -1,489 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module type COMMITMENTS = sig - val init : Raw_context.t -> Storage.Sapling.id -> Raw_context.t Lwt.t - - val default_root : Sapling.Hash.t - - val get_root : - Raw_context.t -> - Storage.Sapling.id -> - (Raw_context.t * Sapling.Hash.t) tzresult Lwt.t - - val add : - Raw_context.t -> - Storage.Sapling.id -> - Sapling.Commitment.t list -> - int64 -> - (Raw_context.t * int) tzresult Lwt.t - - val get_from : - Raw_context.t -> - Storage.Sapling.id -> - int64 -> - Sapling.Commitment.t list tzresult Lwt.t -end - -module Commitments : COMMITMENTS = struct - module H = Sapling.Hash - - (** Incremental Merkle Tree - * - * A tree of height h contains 2^h leaves and h+1 levels of nodes with - * leaves at level 0 and root at level h. - * - * The leaves are commitments and the tree it is treated as always filled - * with a default value H.uncommitted. This allows to have proofs of - * membership, or witnesses, of fixed size. - * - * All the nodes at the same level of an empty tree have the same hash, - * which can be computed from the default value of the leaves. This is - * stored in the [uncommitted] list. - * - * Any subtree filled with default values is represented by the Empty - * constructor and given its height it's possible to compute its hash - * using the [uncommitted] list. - * - * The leaves are indexed by their position [pos], ranging from 0 to - * (2^h)-1. The encoding of [pos] limits the possible size of the tree. - * In any case the only valid height for the Sapling library is 32, so even - * if the library encodes positions as uint64, they never exceed uint32. - * - * The tree is incremental in the sense that leaves cannot be modified but - * only added and exclusively in successive positions. - * - * Given that elements are added and retrieved by position, it is possible - * to use this information to efficiently navigate the tree. - * Given a tree of height [h] and a position [pos], if pos < pow2 (h-1) only - * the left subtree needs to be inspected recursively. Otherwise only the - * right needs to be visited, decreasing [pos] by [pow2 (h-1)]. - * - * In order to avoid storing the height for each subtree (or worse - * recomputing it), each function with suffix `_height` expects the height - * of the tree as parameter. These functions are only for internal use and - * are later aliased by functions using the default height of a Sapling - * incremental Merkle tree. - * - * Each node of the tree is indexed starting from the root at index 1, - * followed by its left child at index 2, right child at index 3 and so on - * until the last leaf at index 2^(depth+1)-1, or in terms of height - * 2^(32 - height +1) -1. - * The functions left and right return the index of the left and right child - * of a node. - *) - - let pow2 h = Int64.(shift_left 1L h) - - let max_height = 32 - - let max_size = pow2 max_height - - let assert_node node height = - assert ( - let first_of_height = pow2 (max_height - height) in - let first_of_next_height = Int64.shift_left first_of_height 1 in - Compare.Int64.(node >= first_of_height && node < first_of_next_height)) - - let assert_height height = - assert (Compare.Int.(height >= 0 && height <= max_height)) - - let assert_pos pos height = - assert (Compare.Int64.(pos >= 0L && pos <= pow2 height)) - - let default_root = H.uncommitted ~height:max_height - - let init = Storage.Sapling.commitments_init - - let get_root_height ctx id node height = - assert_node node height ; - assert_height height ; - Storage.Sapling.Commitments.find (ctx, id) node >|=? function - | (ctx, None) -> - let hash = H.uncommitted ~height in - (ctx, hash) - | (ctx, Some hash) -> (ctx, hash) - - let left node = Int64.mul node 2L - - let right node = Int64.(add (mul node 2L) 1L) - - (* Not tail-recursive *) - let rec split_at n l = - if Compare.Int64.(n = 0L) then ([], l) - else - match l with - | [] -> ([], l) - | x :: xs -> - let (l1, l2) = split_at Int64.(pred n) xs in - (x :: l1, l2) - - (* [insert tree height pos cms] inserts the list of commitments - [cms] in the tree [tree] of height [height] at the next position [pos]. - Returns the context, the size of the added storage, and the hash of the - node. Not tail-recursive. - Pre: incremental tree /\ - size tree + List.length cms <= pow2 height /\ - pos = size tree /\ - Post: incremental tree /\ - to_list (insert tree height pos cms) = to_list t @ cms *) - let[@coq_struct "height"] rec insert ctx id node height pos cms = - assert_node node height ; - assert_height height ; - assert_pos pos height ; - match (height, cms) with - | (_, []) -> - get_root_height ctx id node height >|=? fun (ctx, h) -> (ctx, 0, h) - | (0, [cm]) -> - let h = H.of_commitment cm in - Storage.Sapling.Commitments.init (ctx, id) node h - >|=? fun (ctx, size) -> (ctx, size, h) - | _ -> - let height = height - 1 in - (if Compare.Int64.(pos < pow2 height) then - let at = Int64.(sub (pow2 height) pos) in - let (cml, cmr) = split_at at cms in - insert ctx id (left node) height pos cml >>=? fun (ctx, size_l, hl) -> - insert ctx id (right node) height 0L cmr >|=? fun (ctx, size_r, hr) -> - (ctx, size_l + size_r, hl, hr) - else - get_root_height ctx id (left node) height >>=? fun (ctx, hl) -> - let pos = Int64.(sub pos (pow2 height)) in - insert ctx id (right node) height pos cms - >|=? fun (ctx, size_r, hr) -> (ctx, size_r, hl, hr)) - >>=? fun (ctx, size_children, hl, hr) -> - let h = H.merkle_hash ~height hl hr in - Storage.Sapling.Commitments.add (ctx, id) node h - >|=? fun (ctx, size, _existing) -> (ctx, size + size_children, h) - - let[@coq_struct "height"] rec fold_from_height ctx id node ~pos ~f ~acc height - = - assert_node node height ; - assert_height height ; - assert_pos pos height ; - Storage.Sapling.Commitments.find (ctx, id) node - (* we don't count gas for this function, it is called only by RPC *) - >>=? - function - | (_ctx, None) -> return acc - | (_ctx, Some h) -> - if Compare.Int.(height = 0) then return (f acc h) - else - let full = pow2 (height - 1) in - if Compare.Int64.(pos < full) then - fold_from_height ctx id (left node) ~pos ~f ~acc (height - 1) - >>=? fun acc -> - (* Setting pos to 0 folds on the whole right subtree *) - fold_from_height ctx id (right node) ~pos:0L ~f ~acc (height - 1) - else - let pos = Int64.(sub pos full) in - fold_from_height ctx id (right node) ~pos ~f ~acc (height - 1) - - let root_node = 1L - - let get_root ctx id = get_root_height ctx id root_node max_height - - (* Expects pos to be the next position to insert. Pos is also the number of - inserted leaves. - A commitment should always be added together with a corresponding - ciphertext in the same position. - [insert] is not tail-recursive so we put a hard limit on the size of the - list of commitments. The use of [split_at] has O(n logn) complexity that is - less relevant on a smaller list. *) - let add ctx id cms pos = - let l = List.length cms in - assert (Compare.Int.(l <= 1000)) ; - let n' = Int64.(add pos (of_int l)) in - assert (Compare.Int64.(n' <= max_size)) ; - insert ctx id root_node max_height pos cms >|=? fun (ctx, size, _h) -> - (ctx, size) - - let get_from ctx id pos = - fold_from_height - ctx - id - root_node - ~pos - ~f:(fun acc c -> H.to_commitment c :: acc) - ~acc:[] - max_height - >|=? fun l -> List.rev l -end - -module Ciphertexts = struct - let init ctx id = Storage.Sapling.ciphertexts_init ctx id - - (* a ciphertext should always be added together with a corresponding - commitment in the same position *) - let add ctx id c pos = Storage.Sapling.Ciphertexts.init (ctx, id) pos c - - let get_from ctx id offset = - let rec aux (ctx, acc) pos = - Storage.Sapling.Ciphertexts.find (ctx, id) pos >>=? fun (ctx, c) -> - match c with - | None -> return (ctx, List.rev acc) - | Some c -> aux (ctx, c :: acc) (Int64.succ pos) - in - aux (ctx, []) offset -end - -(* Collection of nullifiers w/o duplicates, append-only. It has a dual - implementation with a hash map for constant `mem` and with a ordered set to - retrieve by position. *) -module Nullifiers = struct - let init = Storage.Sapling.nullifiers_init - - let size ctx id = Storage.Sapling.Nullifiers_size.get (ctx, id) - - let mem ctx id nf = Storage.Sapling.Nullifiers_hashed.mem (ctx, id) nf - - (* Allows for duplicates as they are already checked by verify_update before - updating the state. - Not tail-recursive so we put a hard limit on the size of the - list of nullifiers. *) - let add ctx id nfs = - assert (Compare.Int.(List.compare_length_with nfs 1000 <= 0)) ; - size ctx id >>=? fun nf_start_pos -> - List.fold_right_es - (fun nf (ctx, pos, acc_size) -> - Storage.Sapling.Nullifiers_hashed.init (ctx, id) nf - >>=? fun (ctx, size) -> - Storage.Sapling.Nullifiers_ordered.init (ctx, id) pos nf >|=? fun ctx -> - (ctx, Int64.succ pos, Z.add acc_size (Z.of_int size))) - nfs - (ctx, nf_start_pos, Z.zero) - >>=? fun (ctx, nf_end_pos, size) -> - Storage.Sapling.Nullifiers_size.update (ctx, id) nf_end_pos >|=? fun ctx -> - (ctx, size) - - let get_from ctx id offset = - let[@coq_struct "pos"] rec aux acc pos = - Storage.Sapling.Nullifiers_ordered.find (ctx, id) pos >>=? function - | None -> return @@ List.rev acc - | Some c -> aux (c :: acc) (Int64.succ pos) - in - aux [] offset -end - -(** Bounded queue of roots. The full size is initialized with the default - uncommitted root, that's why roots storage doesn't need to be carbonated. - A maximum of one new root is added per protocol level. - If multiple transactions for the same shielded pool are processed during the - same contract call or several calls in the same block, only the last root - will be stored. - This property prevents transactions in the same block from depending on each - other and guarantees that a transaction will be valid for a least two hours - (hence the 120 size) after being forged. *) -module Roots = struct - let size = 120l - - (* pos is the index of the last inserted element *) - - let get ctx id = - Storage.Sapling.Roots_pos.get (ctx, id) >>=? fun pos -> - Storage.Sapling.Roots.get (ctx, id) pos - - let init ctx id = - let[@coq_struct "pos"] rec aux ctx pos = - if Compare.Int32.(pos < 0l) then return ctx - else - Storage.Sapling.Roots.init (ctx, id) pos Commitments.default_root - >>=? fun ctx -> aux ctx (Int32.pred pos) - in - aux ctx (Int32.pred size) >>=? fun ctx -> - Storage.Sapling.Roots_pos.init (ctx, id) 0l >>=? fun ctx -> - let level = (Raw_context.current_level ctx).level in - Storage.Sapling.Roots_level.init (ctx, id) level - - let mem ctx id root = - Storage.Sapling.Roots_pos.get (ctx, id) >>=? fun start_pos -> - let rec aux pos = - Storage.Sapling.Roots.get (ctx, id) pos >>=? fun hash -> - if Compare.Int.(Sapling.Hash.compare hash root = 0) then return true - else - let pos = Int32.(pred pos) in - let pos = if Compare.Int32.(pos < 0l) then Int32.pred size else pos in - if Compare.Int32.(pos = start_pos) then return false else aux pos - in - aux start_pos - - (* allows duplicates *) - let add ctx id root = - Storage.Sapling.Roots_pos.get (ctx, id) >>=? fun pos -> - let level = (Raw_context.current_level ctx).level in - Storage.Sapling.Roots_level.get (ctx, id) >>=? fun stored_level -> - if Raw_level_repr.(stored_level = level) then - (* if there is another add during the same level, it will over-write on - the same position *) - Storage.Sapling.Roots.add (ctx, id) pos root >|= ok - else - (* it's the first add for this level *) - (* TODO(samoht): why is it using [update] and not [init] then? *) - Storage.Sapling.Roots_level.update (ctx, id) level >>=? fun ctx -> - let pos = Int32.rem (Int32.succ pos) size in - Storage.Sapling.Roots_pos.update (ctx, id) pos >>=? fun ctx -> - Storage.Sapling.Roots.add (ctx, id) pos root >|= ok -end - -(** This type links the permanent state stored in the context at the specified - id together with the ephemeral diff managed by the Michelson - interpreter. After a successful execution the diff can be applied to update - the state at id. The first time a state is created its id is None, one will - be assigned after the first application. *) -type state = { - id : Lazy_storage_kind.Sapling_state.Id.t option; - diff : Sapling_repr.diff; - memo_size : Sapling_repr.Memo_size.t; -} - -let empty_diff = - Sapling_repr.{commitments_and_ciphertexts = []; nullifiers = []} - -let empty_state ?id ~memo_size () = {id; diff = empty_diff; memo_size} - -(** Returns a state from an existing id. *) -let state_from_id ctxt id = - Storage.Sapling.Memo_size.get (ctxt, id) >|=? fun memo_size -> - ({id = Some id; diff = empty_diff; memo_size}, ctxt) - -let rpc_arg = Storage.Sapling.rpc_arg - -let get_memo_size ctx id = Storage.Sapling.Memo_size.get (ctx, id) - -let init ctx id ~memo_size = - Storage.Sapling.Memo_size.add (ctx, id) memo_size >>= fun ctx -> - Storage.Sapling.Commitments_size.add (ctx, id) Int64.zero >>= fun ctx -> - Commitments.init ctx id >>= fun ctx -> - Nullifiers.init ctx id >>= fun ctx -> - Roots.init ctx id >>=? fun ctx -> Ciphertexts.init ctx id >|= ok - -(* Gas costs for apply_diff. *) -let sapling_apply_diff_cost ~inputs ~outputs = - let open Saturation_repr in - add - (safe_int 1_300_000) - (add - (scale_fast (mul_safe_of_int_exn 5_000) (safe_int inputs)) - (scale_fast (mul_safe_of_int_exn 55_000) (safe_int outputs))) - -(** Applies a diff to a state id stored in the context. Updates Commitments, - Ciphertexts and Nullifiers using the diff and updates the Roots using the - new Commitments tree. *) -let apply_diff ctx id diff = - let open Sapling_repr in - let nb_commitments = List.length diff.commitments_and_ciphertexts in - let nb_nullifiers = List.length diff.nullifiers in - let sapling_cost = - sapling_apply_diff_cost ~inputs:nb_nullifiers ~outputs:nb_commitments - in - Raw_context.consume_gas ctx sapling_cost >>?= fun ctx -> - Storage.Sapling.Commitments_size.get (ctx, id) >>=? fun cm_start_pos -> - let cms = List.rev_map fst diff.commitments_and_ciphertexts in - Commitments.add ctx id cms cm_start_pos >>=? fun (ctx, size) -> - Storage.Sapling.Commitments_size.update - (ctx, id) - (Int64.add cm_start_pos (Int64.of_int nb_commitments)) - >>=? fun ctx -> - List.fold_right_es - (fun (_cm, cp) (ctx, pos, acc_size) -> - Ciphertexts.add ctx id cp pos >|=? fun (ctx, size) -> - (ctx, Int64.succ pos, Z.add acc_size (Z.of_int size))) - diff.commitments_and_ciphertexts - (ctx, cm_start_pos, Z.of_int size) - >>=? fun (ctx, _ct_end_pos, size) -> - Nullifiers.add ctx id diff.nullifiers >>=? fun (ctx, size_nf) -> - let size = Z.add size size_nf in - match diff.commitments_and_ciphertexts with - | [] -> - (* avoids adding duplicates to Roots *) - return (ctx, size) - | _ :: _ -> - Commitments.get_root ctx id >>=? fun (ctx, root) -> - Roots.add ctx id root >|=? fun ctx -> (ctx, size) - -let add {id; diff; memo_size} cm_cipher_list = - assert ( - List.for_all - (fun (_cm, cipher) -> - Compare.Int.(Sapling.Ciphertext.get_memo_size cipher = memo_size)) - cm_cipher_list) ; - { - id; - diff = - { - diff with - commitments_and_ciphertexts = - List.rev cm_cipher_list @ diff.commitments_and_ciphertexts; - }; - memo_size; - } - -let root_mem ctx {id; _} tested_root = - match id with - | Some id -> Roots.mem ctx id tested_root - | None -> - return - Compare.Int.( - Sapling.Hash.compare tested_root Commitments.default_root = 0) - -(* to avoid a double spend we need to check the disk AND the diff *) -let nullifiers_mem ctx {id; diff; _} nf = - let exists_in_diff = - List.exists - (fun v -> Compare.Int.(Sapling.Nullifier.compare nf v = 0)) - diff.nullifiers - in - if exists_in_diff then return (ctx, true) - else - match id with - | None -> return (ctx, false) - | Some id -> Nullifiers.mem ctx id nf - -(* Allows for duplicates as they are already checked by verify_update before - updating the state. *) -let nullifiers_add {id; diff; memo_size} nf = - {id; diff = {diff with nullifiers = nf :: diff.nullifiers}; memo_size} - -type root = Sapling.Hash.t - -let root_encoding = Sapling.Hash.encoding - -let get_diff ctx id ?(offset_commitment = 0L) ?(offset_nullifier = 0L) () = - if - not - Sapling.Commitment.( - valid_position offset_commitment && valid_position offset_nullifier) - then failwith "Invalid argument." - else - Commitments.get_from ctx id offset_commitment >>=? fun commitments -> - Roots.get ctx id >>=? fun root -> - Nullifiers.get_from ctx id offset_nullifier >>=? fun nullifiers -> - Ciphertexts.get_from ctx id offset_commitment - (* we don't count gas for RPCs *) - >|=? fun (_ctx, ciphertexts) -> - match List.combine ~when_different_lengths:() commitments ciphertexts with - | Error () -> failwith "Invalid argument." - | Ok commitments_and_ciphertexts -> - (root, Sapling_repr.{commitments_and_ciphertexts; nullifiers}) diff --git a/src/proto_012_Psithaca/lib_protocol/sapling_validator.ml b/src/proto_012_Psithaca/lib_protocol/sapling_validator.ml deleted file mode 100644 index ce0e41e0133c..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/sapling_validator.ml +++ /dev/null @@ -1,108 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Check that each nullifier is not already present in the state and add it. - Important to avoid spending the same input twice in a transaction. *) -let rec check_and_update_nullifiers ctxt state inputs = - match inputs with - | [] -> return (ctxt, Some state) - | input :: inputs -> ( - Sapling_storage.nullifiers_mem ctxt state Sapling.UTXO.(input.nf) - >>=? function - | (ctxt, true) -> return (ctxt, None) - | (ctxt, false) -> - let state = - Sapling_storage.nullifiers_add state Sapling.UTXO.(input.nf) - in - check_and_update_nullifiers ctxt state inputs) - -let verify_update : - Raw_context.t -> - Sapling_storage.state -> - Sapling_repr.transaction -> - string -> - (Raw_context.t * (Int64.t * Sapling_storage.state) option) tzresult Lwt.t = - fun ctxt state transaction key -> - (* Check the transaction *) - (* To avoid overflowing the balance, the number of inputs and outputs must be - bounded. - Ciphertexts' memo_size must match the state's memo_size. - These constraints are already enforced at the encoding level. *) - assert (Compare.Int.(List.compare_length_with transaction.inputs 5208 <= 0)) ; - assert (Compare.Int.(List.compare_length_with transaction.outputs 2019 <= 0)) ; - let pass = - List.for_all - (fun output -> - Compare.Int.( - Sapling.Ciphertext.get_memo_size Sapling.UTXO.(output.ciphertext) - = state.memo_size)) - transaction.outputs - in - if not pass then return (ctxt, None) - else - (* Check the root is a recent state *) - Sapling_storage.root_mem ctxt state transaction.root >>=? fun pass -> - if not pass then return (ctxt, None) - else - check_and_update_nullifiers ctxt state transaction.inputs >|=? function - | (ctxt, None) -> (ctxt, None) - | (ctxt, Some state) -> - Sapling.Verification.with_verification_ctx (fun vctx -> - let pass = - (* Check all the output ZK proofs *) - List.for_all - (fun output -> Sapling.Verification.check_output vctx output) - transaction.outputs - in - if not pass then (ctxt, None) - else - let pass = - (* Check all the input Zk proofs and signatures *) - List.for_all - (fun input -> - Sapling.Verification.check_spend - vctx - input - transaction.root - key) - transaction.inputs - in - if not pass then (ctxt, None) - else - let pass = - (* Check the signature and balance of the whole transaction *) - Sapling.Verification.final_check vctx transaction key - in - if not pass then (ctxt, None) - else - (* update tree *) - let list_to_add = - List.map - (fun output -> - Sapling.UTXO.(output.cm, output.ciphertext)) - transaction.outputs - in - let state = Sapling_storage.add state list_to_add in - (ctxt, Some (transaction.balance, state))) diff --git a/src/proto_012_Psithaca/lib_protocol/saturation_repr.ml b/src/proto_012_Psithaca/lib_protocol/saturation_repr.ml deleted file mode 100644 index abdbb379d3e2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/saturation_repr.ml +++ /dev/null @@ -1,170 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* let () = assert (Sys.int_size = 63) *) - -type _ t = int - -type mul_safe - -type may_saturate - -let may_saturate : _ t -> may_saturate t = fun x -> x - -let to_int x = x - -let ( < ) : _ t -> _ t -> bool = Compare.Int.( < ) - -let ( <= ) : _ t -> _ t -> bool = Compare.Int.( <= ) - -let ( > ) : _ t -> _ t -> bool = Compare.Int.( > ) - -let ( >= ) : _ t -> _ t -> bool = Compare.Int.( >= ) - -let ( = ) : _ t -> _ t -> bool = Compare.Int.( = ) - -let equal = ( = ) - -let ( <> ) : _ t -> _ t -> bool = Compare.Int.( <> ) - -let max : _ t -> _ t -> _ t = fun x y -> if x >= y then x else y - -let min : _ t -> _ t -> _ t = fun x y -> if x >= y then y else x - -let compare : _ t -> _ t -> _ t = Compare.Int.compare - -let saturated = max_int - -let of_int_opt t = if t >= 0 && t < saturated then Some t else None - -let of_z_opt z = - match Z.to_int z with int -> of_int_opt int | exception Z.Overflow -> None - -let to_z x = Z.of_int x - -let saturate_if_undef = function None -> saturated | Some x -> x - -let safe_int x = of_int_opt x |> saturate_if_undef - -let numbits x = - let x = ref x and n = ref 0 in - (let y = !x lsr 32 in - if y <> 0 then ( - n := !n + 32 ; - x := y)) ; - (let y = !x lsr 16 in - if y <> 0 then ( - n := !n + 16 ; - x := y)) ; - (let y = !x lsr 8 in - if y <> 0 then ( - n := !n + 8 ; - x := y)) ; - (let y = !x lsr 4 in - if y <> 0 then ( - n := !n + 4 ; - x := y)) ; - (let y = !x lsr 2 in - if y <> 0 then ( - n := !n + 2 ; - x := y)) ; - if !x lsr 1 <> 0 then !n + 2 else !n + !x - -let zero = 0 - -let one = 1 - -let small_enough z = - (* The following literal triggers an error if compiled under 32-bit - architectures, please do not modify it. This is a static way to - ensure that this file is compiled under a 64-bit architecture. *) - z land 0x7fffffff80000000 = 0 - -let mul_safe x = if small_enough x then Some x else None - -let mul_safe_exn x = - if small_enough x then x - else failwith (Format.sprintf "mul_safe_exn: %d must be below 2147483648" x) - -let mul_safe_of_int_exn x = - Option.bind (of_int_opt x) mul_safe |> function - | None -> - failwith - (Format.sprintf "mul_safe_of_int_exn: %d must be below 2147483648" x) - | Some x -> x - -(* If [x] is positive, shifting to the right will produce a number - which is positive and is less than [x]. *) -let shift_right x y = (x :> int) lsr y - -let shift_left x y = - if shift_right saturated y < x then saturated else (x :> int) lsl y - -let mul x y = - (* assert (x >= 0 && y >= 0); *) - match x with - | 0 -> 0 - | x -> - if small_enough x && small_enough y then x * y - else if Compare.Int.(y > saturated / x) then saturated - else x * y - -let mul_fast x y = x * y - -let scale_fast x y = - if x = 0 then 0 - else if small_enough y then x * y - else if Compare.Int.(y > saturated / x) then saturated - else x * y - -let add x y = - let z = x + y in - if Compare.Int.(z >= 0) then z else saturated - -let succ x = add one x - -let sub x y = Compare.Int.max (x - y) 0 - -let sub_opt x y = - let s = x - y in - if Compare.Int.(s >= 0) then Some s else None - -(* Notice that Z.erem does not behave as mod on negative numbers. - Fortunately, the inhabitant of [t] are non-negative. *) -let erem x y = x mod y - -let ediv x y = x / y - -let t_to_z_exn z = - match of_z_opt z with - | None -> - (* since the encoding is applied to values of type [t]. *) assert false - | Some x -> x - -let z_encoding = Data_encoding.(check_size 9 (conv to_z t_to_z_exn z)) - -let n_encoding = Data_encoding.(check_size 9 (conv to_z t_to_z_exn n)) - -let pp fmt x = Format.pp_print_int fmt x diff --git a/src/proto_012_Psithaca/lib_protocol/saturation_repr.mli b/src/proto_012_Psithaca/lib_protocol/saturation_repr.mli deleted file mode 100644 index d937abc29813..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/saturation_repr.mli +++ /dev/null @@ -1,204 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module provides saturated arithmetic between 0 and 2^62 - 1. - - This means that the arithmetic operations provided by this module - do not overflow. If an operation would produce an integer [x] - greater than [2 ^ 62 - 1], it is [saturated] to this - value. Similarly, if an operation would produce a negative integer, - it outputs [zero] instead. - - This saturation arithmetic is used to monitor gas levels. While the - gas model can produce values beyond 2^62 - 1, there is no point in - distinguishing these values from 2^62 - 1 because the amount of gas - available is significantly lower than this limit. - - Notice that most saturation arithmetic operations do not behave - as their standard counterparts when one of their operands is - saturated. For instance, - - (saturated + saturated) - saturated = 0 - - For more information about saturation arithmetic, take a look at: - - https://en.wikipedia.org/wiki/Saturation_arithmetic - -*) - -(** An integer of type ['a t] is between [0] and [saturated]. - - The type parameter ['a] is [mul_safe] if the integer is known - not to overflow when multiplied with another [mul_safe t]. - - The type parameter ['a] is [may_saturate] if the integer is - not known to be sufficiently small to prevent overflow during - multiplication. - -*) -type 'a t = private int - -type mul_safe - -type may_saturate - -val may_saturate : _ t -> may_saturate t - -(** [to_int x] returns the underlying integer representing [x]. *) -val to_int : 'a t -> int - -(** 0 *) -val zero : _ t - -(** 1 *) -val one : _ t - -(** 2^62 - 1 *) -val saturated : may_saturate t - -(** We inherit the order over native integers. *) -val ( >= ) : _ t -> _ t -> bool - -val ( > ) : _ t -> _ t -> bool - -val ( <= ) : _ t -> _ t -> bool - -val ( < ) : _ t -> _ t -> bool - -val ( = ) : _ t -> _ t -> bool - -val ( <> ) : _ t -> _ t -> bool - -val equal : _ t -> _ t -> bool - -val min : 'a t -> 'a t -> 'a t - -val max : 'a t -> 'a t -> 'a t - -val compare : 'a t -> 'b t -> int - -(** [numbits x] returns the number of bits used in the binary representation - of [x]. *) -val numbits : 'a t -> int - -(** [shift_right x y] behaves like a logical shift of [x] by [y] bits - to the right. [y] must be between 0 and 63. *) -val shift_right : 'a t -> int -> 'a t - -(** [shift_left x y] behaves like a logical shift of [x] by [y] bits - to the left. [y] must be between 0 and 63. In cases where [x lsl y] - is overflowing, [shift_left x y] is [saturated]. *) -val shift_left : 'a t -> int -> 'a t - -(** [mul x y] behaves like multiplication between native integers as - long as its result stay below [saturated]. Otherwise, [mul] returns - [saturated]. *) -val mul : _ t -> _ t -> may_saturate t - -(** [mul_safe x] returns a [mul_safe t] only if [x] does not trigger - overflows when multiplied with another [mul_safe t]. More precisely, - [x] is safe for fast multiplications if [x < 2147483648]. *) -val mul_safe : _ t -> mul_safe t option - -(** [mul_fast x y] exploits the fact that [x] and [y] are known not to - provoke overflows during multiplication to perform a mere - multiplication. *) -val mul_fast : mul_safe t -> mul_safe t -> may_saturate t - -(** [scale_fast x y] exploits the fact that [x] is known not to - provoke overflows during multiplication to perform a - multiplication faster than [mul]. *) -val scale_fast : mul_safe t -> _ t -> may_saturate t - -(** [add x y] behaves like addition between native integers as long as - its result stay below [saturated]. Otherwise, [add] returns - [saturated]. *) -val add : _ t -> _ t -> may_saturate t - -(** [succ x] is like [add one x] *) -val succ : _ t -> may_saturate t - -(** [sub x y] behaves like subtraction between native integers as long - as its result stay positive. Otherwise, [sub] returns [zero]. - This function assumes that [x] is not saturated. -*) -val sub : 'a t -> _ t -> 'a t - -(** [sub_opt x y] behaves like subtraction between native integers as - long as its result stay positive. Otherwise, [sub] returns - [None]. *) -val sub_opt : 'a t -> _ t -> 'a t option - -(** [ediv x y] returns [x / y]. This operation never saturates, hence - it is exactly the same as its native counterpart. [y] is supposed - to be strictly greater than 0, otherwise this function raises - [Division_by_zero]. *) -val ediv : 'a t -> _ t -> 'a t - -(** [erem x y] returns [x mod y]. [y] is supposed to be strictly - greater than 0, otherwise this function raises - [Division_by_zero]. *) -val erem : _ t -> 'b t -> 'b t - -(** [of_int_opt x] returns [Some x] if [x >= 0] and [x < saturated], - and [None] otherwise. *) -val of_int_opt : int -> may_saturate t option - -(** [of_z_opt x] returns [Some x] if [x >= 0] and [x < saturated], - and [None] otherwise. *) -val of_z_opt : Z.t -> may_saturate t option - -(** When a saturated integer is sufficiently small (i.e. strictly less - than 2147483648), we can assign it the type [mul_safe S.t] to use - it within fast multiplications, named [S.scale_fast] and - [S.mul_fast]. - - The following function allows such type assignment but may raise an - exception if the assumption is wrong. Therefore, [mul_safe_exn] - should only be used to define toplevel values, so that these - exceptions can only occur during startup. - *) -val mul_safe_exn : may_saturate t -> mul_safe t - -(** [mul_safe_of_int_exn x] is the composition of [of_int_opt] and - [mul_safe] in the option monad. This function raises [Invalid_argument] - if [x] is not safe. This function should be used on integer literals - that are obviously [mul_safe]. *) -val mul_safe_of_int_exn : int -> mul_safe t - -(** [safe_int x] is [of_int_opt x |> saturate_if_undef]. *) -val safe_int : int -> may_saturate t - -(** [to_z z] is [Z.of_int]. *) -val to_z : _ t -> Z.t - -(** Encoding for [t] through the encoding for [z] integers. *) -val z_encoding : _ t Data_encoding.t - -(** Encoding for [t] through the encoding for non-negative integers. *) -val n_encoding : _ t Data_encoding.t - -(** A pretty-printer for native integers. *) -val pp : Format.formatter -> _ t -> unit diff --git a/src/proto_012_Psithaca/lib_protocol/script_cache.ml b/src/proto_012_Psithaca/lib_protocol/script_cache.ml deleted file mode 100644 index b32aa4da5baa..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_cache.ml +++ /dev/null @@ -1,109 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -type identifier = string - -let identifier_of_contract addr = Contract.to_b58check addr - -let contract_of_identifier identifier = Contract.of_b58check identifier - -type cached_contract = Script.t * Script_ir_translator.ex_script - -let load_and_elaborate ctxt addr = - Contract.get_script ctxt addr >>=? fun (ctxt, script) -> - match script with - | None -> return (ctxt, None) - | Some script -> - Script_ir_translator.( - parse_script ctxt script ~legacy:true ~allow_forged_in_storage:true - >>=? fun (ex_script, ctxt) -> - (* We consume gas after the fact in order to not have to instrument - [script_size] (for efficiency). - This is safe, as we already pay gas proportional to storage size - in [parse_script] beforehand. *) - let (size, cost) = script_size ex_script in - Gas.consume ctxt cost >>?= fun ctxt -> - return (ctxt, Some (script, ex_script, size))) - -module Client = struct - type cached_value = cached_contract - - let namespace = Cache.create_namespace "contract" - - let cache_index = 0 - - let value_of_identifier ctxt identifier = - (* - - I/O, deserialization, and elaboration of contracts scripts - are cached. - - *) - contract_of_identifier identifier >>?= fun addr -> - load_and_elaborate ctxt addr >>=? function - | (_, None) -> - (* [value_of_identifier ctxt k] is applied to identifiers stored - in the cache. Only script-based contracts that have been - executed are in the cache. Hence, [get_script] always - succeeds for these identifiers if [ctxt] and the [cache] are - properly synchronized by the shell. *) - failwith "Script_cache: Inconsistent script cache." - | (_, Some (unparsed_script, ir_script, _)) -> - return (unparsed_script, ir_script) -end - -module Cache = (val Cache.register_exn (module Client)) - -let find ctxt addr = - let identifier = identifier_of_contract addr in - Cache.find ctxt identifier >>=? function - | Some (unparsed_script, ex_script) -> - return (ctxt, identifier, Some (unparsed_script, ex_script)) - | None -> ( - load_and_elaborate ctxt addr >>=? function - | (ctxt, None) -> return (ctxt, identifier, None) - | (ctxt, Some (unparsed_script, script_ir, size)) -> - let cached_value = (unparsed_script, script_ir) in - Lwt.return - ( Cache.update ctxt identifier (Some (cached_value, size)) - >>? fun ctxt -> - ok (ctxt, identifier, Some (unparsed_script, script_ir)) )) - -let update ctxt identifier updated_script approx_size = - Cache.update ctxt identifier (Some (updated_script, approx_size)) - -let entries ctxt = - Cache.list_identifiers ctxt - |> List.map_e @@ fun (identifier, age) -> - contract_of_identifier identifier >|? fun contract -> (contract, age) - -let contract_rank ctxt addr = - Cache.identifier_rank ctxt (identifier_of_contract addr) - -let size = Cache.size - -let size_limit = Cache.size_limit diff --git a/src/proto_012_Psithaca/lib_protocol/script_cache.mli b/src/proto_012_Psithaca/lib_protocol/script_cache.mli deleted file mode 100644 index 641bad38e99a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_cache.mli +++ /dev/null @@ -1,81 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module manages the cache for smart contracts. - - This cache must be consistent with the on-disk representation - of the smart contracts. In particular, [update] must be called - each time a contract storage is updated. - -*) - -open Alpha_context - -(** Each cached script has a unique identifier in the cache. *) -type identifier - -(** The cache holds the unparsed and the internal representation of - the contract. *) -type cached_contract = Script.t * Script_ir_translator.ex_script - -(** [find ctxt contract] returns [(ctxt', identifier, script)] where: - - [ctxt'] is [ctxt] with less gas; - - [identifier] is the identifier identifying the [contract] in the cache; - - [script = None] if there is no such contract in [ctxt]; - - [script = Some (unparsed_script, ir_script)] where - - [unparsed_script] is the contract source code and storage; - - [script_ir] is a typed internal representation of the contract, i.e., - the abstract syntax tree of its code as well as its storage. - - This function consumes gas depending on the cache. If the contract is not - in the cache, then the function also consumes the gas of [Contract.get_script] - and [Script_ir_translator.parse_script]. *) -val find : - context -> - Contract.t -> - (context * identifier * cached_contract option) tzresult Lwt.t - -(** [update ctxt identifier unparsed_script ir_script size] refreshes the - cached contract identified by [identifier] with a new [unparsed_script], - a new [ir_script], and a new size. *) -val update : context -> identifier -> cached_contract -> int -> context tzresult - -(** [entries ctxt] returns the contracts in the cache as well as their - respective size. The list is sorted by date of last modification: - the least recently updated entry comes first. *) -val entries : context -> (Contract.t * int) list tzresult - -(** [contract_rank ctxt contract] returns the number of contracts - older than [contract] in the cache of [ctxt]. This function - returns [None] if [contract] does not exist in the cache of - [ctxt]. *) -val contract_rank : context -> Contract.t -> int option - -(** [size ctxt] is an overapproximation of the cache size in - memory (in bytes). *) -val size : context -> int - -(** [size_limit ctxt] is the maximal size of the cache (in bytes). *) -val size_limit : context -> int diff --git a/src/proto_012_Psithaca/lib_protocol/script_comparable.ml b/src/proto_012_Psithaca/lib_protocol/script_comparable.ml deleted file mode 100644 index ab542f4867f3..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_comparable.ml +++ /dev/null @@ -1,89 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Script_typed_ir - -let compare_address (x, ex) (y, ey) = - let lres = Contract.compare x y in - if Compare.Int.(lres = 0) then Compare.String.compare ex ey else lres - -type compare_comparable_cont = - | Compare_comparable : - 'a comparable_ty * 'a * 'a * compare_comparable_cont - -> compare_comparable_cont - | Compare_comparable_return : compare_comparable_cont - -let compare_comparable : type a. a comparable_ty -> a -> a -> int = - let rec compare_comparable : - type a. a comparable_ty -> compare_comparable_cont -> a -> a -> int = - fun kind k x y -> - match (kind, x, y) with - | (Unit_key _, (), ()) -> (apply [@tailcall]) 0 k - | (Never_key _, _, _) -> . - | (Signature_key _, x, y) -> (apply [@tailcall]) (Signature.compare x y) k - | (String_key _, x, y) -> (apply [@tailcall]) (Script_string.compare x y) k - | (Bool_key _, x, y) -> (apply [@tailcall]) (Compare.Bool.compare x y) k - | (Mutez_key _, x, y) -> (apply [@tailcall]) (Tez.compare x y) k - | (Key_hash_key _, x, y) -> - (apply [@tailcall]) (Signature.Public_key_hash.compare x y) k - | (Key_key _, x, y) -> - (apply [@tailcall]) (Signature.Public_key.compare x y) k - | (Int_key _, x, y) -> (apply [@tailcall]) (Script_int.compare x y) k - | (Nat_key _, x, y) -> (apply [@tailcall]) (Script_int.compare x y) k - | (Timestamp_key _, x, y) -> - (apply [@tailcall]) (Script_timestamp.compare x y) k - | (Address_key _, x, y) -> (apply [@tailcall]) (compare_address x y) k - | (Bytes_key _, x, y) -> (apply [@tailcall]) (Compare.Bytes.compare x y) k - | (Chain_id_key _, x, y) -> (apply [@tailcall]) (Chain_id.compare x y) k - | (Pair_key ((tl, _), (tr, _), _), (lx, rx), (ly, ry)) -> - (compare_comparable [@tailcall]) - tl - (Compare_comparable (tr, rx, ry, k)) - lx - ly - | (Union_key ((tl, _), _, _), L x, L y) -> - (compare_comparable [@tailcall]) tl k x y - | (Union_key _, L _, R _) -> -1 - | (Union_key _, R _, L _) -> 1 - | (Union_key (_, (tr, _), _), R x, R y) -> - (compare_comparable [@tailcall]) tr k x y - | (Option_key _, None, None) -> (apply [@tailcall]) 0 k - | (Option_key _, None, Some _) -> -1 - | (Option_key _, Some _, None) -> 1 - | (Option_key (t, _), Some x, Some y) -> - (compare_comparable [@tailcall]) t k x y - and apply ret k = - match (ret, k) with - | (0, Compare_comparable (ty, x, y, k)) -> - (compare_comparable [@tailcall]) ty k x y - | (0, Compare_comparable_return) -> 0 - | (ret, _) -> - (* ret <> 0, we perform an early exit *) - if Compare.Int.(ret > 0) then 1 else -1 - in - fun t -> compare_comparable t Compare_comparable_return - [@@coq_axiom_with_reason "non top-level mutually recursive function"] diff --git a/src/proto_012_Psithaca/lib_protocol/script_comparable.mli b/src/proto_012_Psithaca/lib_protocol/script_comparable.mli deleted file mode 100644 index 8f489511625a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_comparable.mli +++ /dev/null @@ -1,29 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val compare_comparable : 'a Script_typed_ir.comparable_ty -> 'a -> 'a -> int - -val compare_address : Script_typed_ir.address -> Script_typed_ir.address -> int diff --git a/src/proto_012_Psithaca/lib_protocol/script_expr_hash.ml b/src/proto_012_Psithaca/lib_protocol/script_expr_hash.ml deleted file mode 100644 index 4b26c6d4234d..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_expr_hash.ml +++ /dev/null @@ -1,44 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let script_expr_hash = "\013\044\064\027" (* expr(54) *) - -module H = - Blake2B.Make - (Base58) - (struct - let name = "script_expr" - - let title = "A script expression ID" - - let b58check_prefix = script_expr_hash - - let size = None - end) - -include H -include Path_encoding.Make_hex (H) - -let () = Base58.check_encoded_prefix b58check_encoding "expr" 54 diff --git a/src/proto_012_Psithaca/lib_protocol/script_expr_hash.mli b/src/proto_012_Psithaca/lib_protocol/script_expr_hash.mli deleted file mode 100644 index 8ba38e2eaaf5..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_expr_hash.mli +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** A specialized Blake2B implementation for hashing Michelson expressions. *) - -include S.HASH - -include Path_encoding.S with type t := t diff --git a/src/proto_012_Psithaca/lib_protocol/script_int_repr.ml b/src/proto_012_Psithaca/lib_protocol/script_int_repr.ml deleted file mode 100644 index f5eff71ab42c..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_int_repr.ml +++ /dev/null @@ -1,113 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type n = Natural_tag - -type z = Integer_tag - -(* We could define `num` as a GADT with constructors for `n` and `z`. - This would enable factorizing the code a bit in the Michelson interpreter and - also make formal the claim that `num` is only instantiated with `n` and `z`, - but it would result in space and time overheads when manipulating `num`s, by - having to deconstruct to and reconstruct from `Z.t`. *) -type 't num = Z.t - -let compare x y = Z.compare x y - -let zero = Z.zero - -let zero_n = Z.zero - -let one_n = Z.one - -let to_string x = Z.to_string x - -let of_string s = Option.catch (fun () -> Z.of_string s) - -let of_int32 n = Z.of_int64 @@ Int64.of_int32 n - -let to_int64 x = Option.catch (fun () -> Z.to_int64 x) - -let of_int64 n = Z.of_int64 n - -let to_int x = Option.catch (fun () -> Z.to_int x) - -let of_int n = Z.of_int n - -let of_zint x = x - -let to_zint x = x - -let add x y = Z.add x y - -let sub x y = Z.sub x y - -let mul x y = Z.mul x y - -let ediv x y = Option.catch (fun () -> Z.ediv_rem x y) - -let add_n = add - -let succ_n = Z.succ - -let mul_n = mul - -let ediv_n = ediv - -let abs x = Z.abs x - -let is_nat x = if Compare.Z.(x < Z.zero) then None else Some x - -let neg x = Z.neg x - -let int x = x - -let shift_left x y = - if Compare.Int.(Z.compare y (Z.of_int 256) > 0) then None - else - let y = Z.to_int y in - Some (Z.shift_left x y) - -let shift_right x y = - if Compare.Int.(Z.compare y (Z.of_int 256) > 0) then None - else - let y = Z.to_int y in - Some (Z.shift_right x y) - -let shift_left_n = shift_left - -let shift_right_n = shift_right - -let logor x y = Z.logor x y - -let logxor x y = Z.logxor x y - -let logand x y = Z.logand x y - -let lognot x = Z.lognot x - -let z_encoding : z num Data_encoding.encoding = Data_encoding.z - -let n_encoding : n num Data_encoding.encoding = Data_encoding.n diff --git a/src/proto_012_Psithaca/lib_protocol/script_int_repr.mli b/src/proto_012_Psithaca/lib_protocol/script_int_repr.mli deleted file mode 100644 index b31894d5982f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_int_repr.mli +++ /dev/null @@ -1,161 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** The types for arbitrary precision integers in Michelson. - The type variable ['t] is always [n] or [z], - [n num] and [z num] are incompatible. - - This is internally a [Z.t]. - This module mostly adds signedness preservation guarantees. *) -type 't num [@@coq_phantom] - -(** Flag for natural numbers. *) -type n = Natural_tag - -(** Flag for relative numbers. *) -type z = Integer_tag - -(** Natural zero. *) -val zero_n : n num - -(** Natural one. *) -val one_n : n num - -(** Natural successor. - - [succ_n x] is the same as [add_n one_n]. - *) -val succ_n : n num -> n num - -(** Relative zero. *) -val zero : z num - -(** Compare two numbers as if they were *) -val compare : 'a num -> 'a num -> int - -(** Conversion to an OCaml [string] in decimal notation. *) -val to_string : _ num -> string - -(** Conversion from an OCaml [string]. - Returns [None] in case of an invalid notation. - Supports [+] and [-] sign modifiers, and [0x], [0o] and [0b] base modifiers. *) -val of_string : string -> z num option - -(** Conversion from an OCaml [int32]. *) -val of_int32 : int32 -> z num - -(** Conversion to an OCaml [int64], returns [None] on overflow. *) -val to_int64 : _ num -> int64 option - -(** Conversion from an OCaml [int64]. *) -val of_int64 : int64 -> z num - -(** Conversion to an OCaml [int], returns [None] on overflow. *) -val to_int : _ num -> int option - -(** Conversion from an OCaml [int]. *) -val of_int : int -> z num - -(** Conversion from a Zarith integer ([Z.t]). *) -val of_zint : Z.t -> z num - -(** Conversion to a Zarith integer ([Z.t]). *) -val to_zint : 'a num -> Z.t - -(** Addition between naturals. *) -val add_n : n num -> n num -> n num - -(** Multiplication with a natural. *) -val mul_n : n num -> 'a num -> 'a num - -(** Euclidean division of a natural. - [ediv_n n d] returns [None] if divisor is zero, - or [Some (q, r)] where [n = d * q + r] and [[0 <= r < d]] otherwise. *) -val ediv_n : n num -> 'a num -> ('a num * n num) option - -(** Sign agnostic addition. - Use {!add_n} when working with naturals to preserve the sign. *) -val add : _ num -> _ num -> z num - -(** Sign agnostic subtraction. - Use {!sub_n} when working with naturals to preserve the sign. *) -val sub : _ num -> _ num -> z num - -(** Sign agnostic multiplication. - Use {!mul_n} when working with a natural to preserve the sign. *) -val mul : _ num -> _ num -> z num - -(** Sign agnostic euclidean division. - [ediv n d] returns [None] if divisor is zero, - or [Some (q, r)] where [n = d * q + r] and [[0 <= r < |d|]] otherwise. - Use {!ediv_n} when working with a natural to preserve the sign. *) -val ediv : _ num -> _ num -> (z num * n num) option - -(** Compute the absolute value of a relative, turning it into a natural. *) -val abs : z num -> n num - -(** Partial identity over [N]. *) -val is_nat : z num -> n num option - -(** Negates a number. *) -val neg : _ num -> z num - -(** Turns a natural into a relative, not changing its value. *) -val int : n num -> z num - -(** Reverses each bit in the representation of the number. - Also applies to the sign. *) -val lognot : _ num -> z num - -(** Shifts the natural to the left of a number of bits between 0 and 256. - Returns [None] if the amount is too high. *) -val shift_left_n : n num -> n num -> n num option - -(** Shifts the natural to the right of a number of bits between 0 and 256. - Returns [None] if the amount is too high. *) -val shift_right_n : n num -> n num -> n num option - -(** Shifts the number to the left of a number of bits between 0 and 256. - Returns [None] if the amount is too high. *) -val shift_left : 'a num -> n num -> 'a num option - -(** Shifts the number to the right of a number of bits between 0 and 256. - Returns [None] if the amount is too high. *) -val shift_right : 'a num -> n num -> 'a num option - -(** Applies a boolean or operation to each bit. *) -val logor : 'a num -> 'a num -> 'a num - -(** Applies a boolean and operation to each bit. *) -val logand : _ num -> n num -> n num - -(** Applies a boolean xor operation to each bit. *) -val logxor : n num -> n num -> n num - -(** Naturals are encoded using Data_encoding.n *) -val n_encoding : n num Data_encoding.encoding - -(** Integers are encoded using Data_encoding.z *) -val z_encoding : z num Data_encoding.encoding diff --git a/src/proto_012_Psithaca/lib_protocol/script_interpreter.ml b/src/proto_012_Psithaca/lib_protocol/script_interpreter.ml deleted file mode 100644 index 1bbd4bc7cb04..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_interpreter.ml +++ /dev/null @@ -1,1798 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* - - This module implements an interpreter for Michelson. It takes the - form of a [step] function that interprets script instructions in a - dedicated abstract machine. - - The interpreter is written in a small-step style: an execution - [step] only interprets a single instruction by updating the - configuration of a dedicated abstract machine. - - This abstract machine has two components: - - - a stack to control which instructions must be executed ; and - - - a stack of values where instructions get their inputs and put - their outputs. - - In addition, the machine has access to effectful primitives to - interact with the execution environment (e.g. the Tezos - node). These primitives live in the [Lwt+State+Error] monad. Hence, - this interpreter produces a computation in the [Lwt+State+Error] - monad. - - This interpreter enjoys the following properties: - - - The interpreter is tail-recursive, hence it is robust to stack - overflow. This property is checked by the compiler thanks to the - [@ocaml.tailcall] annotation of each recursive call. - - - The interpreter is type-preserving. Thanks to GADTs, the typing - rules of Michelson are statically checked by the OCaml typechecker: - a Michelson program cannot go wrong. - - - The interpreter is tagless. Thanks to GADTs, the exact shape of - the stack is known statically so the interpreter does not have to - check that the input stack has the shape expected by the - instruction to be executed. - - Outline - ======= - - This file is organized as follows: - - 1. Definition of runtime errors. - - 2. Interpretation loop: This is the main functionality of this - module, aka the [step] function. - - 3. Interface functions: This part of the module builds high-level - functions on top of the more basic [step] function. - - Auxiliary definitions can be found in {!Script_interpreter_defs}. - - Implementation details are explained along the file. - -*) - -open Alpha_context -open Script -open Script_typed_ir -open Script_ir_translator -open Local_gas_counter -open Script_interpreter_defs -module S = Saturation_repr - -type step_constants = Script_typed_ir.step_constants = { - source : Contract.t; - payer : Contract.t; - self : Contract.t; - amount : Tez.t; - chain_id : Chain_id.t; - now : Script_timestamp.t; - level : Script_int.n Script_int.num; -} - -(* ---- Run-time errors -----------------------------------------------------*) - -type error += Reject of Script.location * Script.expr * execution_trace option - -type error += Overflow of Script.location * execution_trace option - -type error += Runtime_contract_error : Contract.t * Script.expr -> error - -type error += Bad_contract_parameter of Contract.t (* `Permanent *) - -type error += Cannot_serialize_failure - -type error += Cannot_serialize_storage - -type error += Michelson_too_many_recursive_calls - -let () = - let open Data_encoding in - let trace_encoding = - list - @@ obj3 - (req "location" Script.location_encoding) - (req "gas" Gas.encoding) - (req - "stack" - (list (obj2 (req "item" Script.expr_encoding) (opt "annot" string)))) - in - (* Reject *) - register_error_kind - `Temporary - ~id:"michelson_v1.script_rejected" - ~title:"Script failed" - ~description:"A FAILWITH instruction was reached" - (obj3 - (req "location" Script.location_encoding) - (req "with" Script.expr_encoding) - (opt "trace" trace_encoding)) - (function Reject (loc, v, trace) -> Some (loc, v, trace) | _ -> None) - (fun (loc, v, trace) -> Reject (loc, v, trace)) ; - (* Overflow *) - register_error_kind - `Temporary - ~id:"michelson_v1.script_overflow" - ~title:"Script failed (overflow error)" - ~description: - "A FAIL instruction was reached due to the detection of an overflow" - (obj2 - (req "location" Script.location_encoding) - (opt "trace" trace_encoding)) - (function Overflow (loc, trace) -> Some (loc, trace) | _ -> None) - (fun (loc, trace) -> Overflow (loc, trace)) ; - (* Runtime contract error *) - register_error_kind - `Temporary - ~id:"michelson_v1.runtime_error" - ~title:"Script runtime error" - ~description:"Toplevel error for all runtime script errors" - (obj2 - (req "contract_handle" Contract.encoding) - (req "contract_code" Script.expr_encoding)) - (function - | Runtime_contract_error (contract, expr) -> Some (contract, expr) - | _ -> None) - (fun (contract, expr) -> Runtime_contract_error (contract, expr)) ; - (* Bad contract parameter *) - register_error_kind - `Permanent - ~id:"michelson_v1.bad_contract_parameter" - ~title:"Contract supplied an invalid parameter" - ~description: - "Either no parameter was supplied to a contract with a non-unit \ - parameter type, a non-unit parameter was passed to an account, or a \ - parameter was supplied of the wrong type" - Data_encoding.(obj1 (req "contract" Contract.encoding)) - (function Bad_contract_parameter c -> Some c | _ -> None) - (fun c -> Bad_contract_parameter c) ; - (* Cannot serialize failure *) - register_error_kind - `Temporary - ~id:"michelson_v1.cannot_serialize_failure" - ~title:"Not enough gas to serialize argument of FAILWITH" - ~description: - "Argument of FAILWITH was too big to be serialized with the provided gas" - Data_encoding.empty - (function Cannot_serialize_failure -> Some () | _ -> None) - (fun () -> Cannot_serialize_failure) ; - (* Cannot serialize storage *) - register_error_kind - `Temporary - ~id:"michelson_v1.cannot_serialize_storage" - ~title:"Not enough gas to serialize execution storage" - ~description: - "The returned storage was too big to be serialized with the provided gas" - Data_encoding.empty - (function Cannot_serialize_storage -> Some () | _ -> None) - (fun () -> Cannot_serialize_storage) - -(* - - Interpretation loop - =================== - -*) - -(* - - As announced earlier, the [step] function produces a computation in - the [Lwt+State+Error] monad. The [State] monad is implemented by - having the [context] passed as input and returned updated as - output. The [Error] monad is represented by the [tzresult] type - constructor. - - The [step] function is actually defined as an internal - tail-recursive routine of the toplevel [step]. It monitors the gas - level before executing the instruction under focus, once this is - done, it recursively calls itself on the continuation held by the - current instruction. - - For each pure instruction (i.e. that is not monadic), the - interpretation simply updates the input arguments of the [step] - function. Since these arguments are (most likely) stored in - hardware registers and since the tail-recursive calls are compiled - into direct jumps, this interpretation technique offers good - performances while saving safety thanks to a rich typing. - - For each impure instruction, the interpreter makes use of monadic - bindings to compose monadic primitives with the [step] function. - Again, we make sure that the recursive calls to [step] are tail - calls by annotating them with [@ocaml.tailcall]. - - The [step] function is actually based on several mutually - recursive functions that can be separated in two groups: the first - group focuses on the evaluation of continuations while the second - group is about evaluating the instructions. - -*) - -(* - - Evaluation of continuations - =========================== - - As explained in [Script_typed_ir], there are several kinds of - continuations, each having a specific evaluation rules. The - following group of functions starts with a list of evaluation - rules for continuations that generate fresh continuations. This - group ends with the definition of [next], which dispatches - evaluation rules depending on the continuation at stake. - - *) -let rec kmap_exit : - type a b c d e f g h m n o. (a, b, c, d, e, f, g, h, m, n, o) kmap_exit_type - = - fun mk g gas (body, xs, ys, yk) ks accu stack -> - let ys = Script_map.update yk (Some accu) ys in - let ks = mk (KMap_enter_body (body, xs, ys, ks)) in - let (accu, stack) = stack in - (next [@ocaml.tailcall]) g gas ks accu stack - [@@inline] - -and kmap_enter : type a b c d i j k. (a, b, c, d, i, j, k) kmap_enter_type = - fun mk g gas (body, xs, ys) ks accu stack -> - match xs with - | [] -> (next [@ocaml.tailcall]) g gas ks ys (accu, stack) - | (xk, xv) :: xs -> - let ks = mk (KMap_exit_body (body, xs, ys, xk, ks)) in - let res = (xk, xv) in - let stack = (accu, stack) in - (step [@ocaml.tailcall]) g gas body ks res stack - [@@inline] - -and klist_exit : type a b c d i j. (a, b, c, d, i, j) klist_exit_type = - fun mk g gas (body, xs, ys, len) ks accu stack -> - let ks = mk (KList_enter_body (body, xs, accu :: ys, len, ks)) in - let (accu, stack) = stack in - (next [@ocaml.tailcall]) g gas ks accu stack - [@@inline] - -and klist_enter : type a b c d e j. (a, b, c, d, e, j) klist_enter_type = - fun mk g gas (body, xs, ys, len) ks' accu stack -> - match xs with - | [] -> - let ys = {elements = List.rev ys; length = len} in - (next [@ocaml.tailcall]) g gas ks' ys (accu, stack) - | x :: xs -> - let ks = mk (KList_exit_body (body, xs, ys, len, ks')) in - (step [@ocaml.tailcall]) g gas body ks x (accu, stack) - [@@inline] - -and kloop_in_left : type a b c d e f g. (a, b, c, d, e, f, g) kloop_in_left_type - = - fun g gas ks0 ki ks' accu stack -> - match accu with - | L v -> (step [@ocaml.tailcall]) g gas ki ks0 v stack - | R v -> (next [@ocaml.tailcall]) g gas ks' v stack - [@@inline] - -and kloop_in : type a b c r f s. (a, b, c, r, f, s) kloop_in_type = - fun g gas ks0 ki ks' accu stack -> - let (accu', stack') = stack in - if accu then (step [@ocaml.tailcall]) g gas ki ks0 accu' stack' - else (next [@ocaml.tailcall]) g gas ks' accu' stack' - [@@inline] - -and kiter : type a b s r f. (a, b, s, r, f) kiter_type = - fun mk g gas (body, xs) ks accu stack -> - match xs with - | [] -> (next [@ocaml.tailcall]) g gas ks accu stack - | x :: xs -> - let ks = mk (KIter (body, xs, ks)) in - (step [@ocaml.tailcall]) g gas body ks x (accu, stack) - [@@inline] - -and next : - type a s r f. - outdated_context * step_constants -> - local_gas_counter -> - (a, s, r, f) continuation -> - a -> - s -> - (r * f * outdated_context * local_gas_counter) tzresult Lwt.t = - fun ((ctxt, _) as g) gas ks0 accu stack -> - match consume_control gas ks0 with - | None -> fail Gas.Operation_quota_exceeded - | Some gas -> ( - match ks0 with - | KLog (ks, logger) -> - (klog [@ocaml.tailcall]) logger g gas ks0 ks accu stack - | KNil -> Lwt.return (Ok (accu, stack, ctxt, gas)) - | KCons (k, ks) -> (step [@ocaml.tailcall]) g gas k ks accu stack - | KLoop_in (ki, ks') -> - (kloop_in [@ocaml.tailcall]) g gas ks0 ki ks' accu stack - | KReturn (stack', ks) -> (next [@ocaml.tailcall]) g gas ks accu stack' - | KMap_head (f, ks) -> (next [@ocaml.tailcall]) g gas ks (f accu) stack - | KLoop_in_left (ki, ks') -> - (kloop_in_left [@ocaml.tailcall]) g gas ks0 ki ks' accu stack - | KUndip (x, ks) -> (next [@ocaml.tailcall]) g gas ks x (accu, stack) - | KIter (body, xs, ks) -> - let extra = (body, xs) in - (kiter [@ocaml.tailcall]) id g gas extra ks accu stack - | KList_enter_body (body, xs, ys, len, ks) -> - let extra = (body, xs, ys, len) in - (klist_enter [@ocaml.tailcall]) id g gas extra ks accu stack - | KList_exit_body (body, xs, ys, len, ks) -> - let extra = (body, xs, ys, len) in - (klist_exit [@ocaml.tailcall]) id g gas extra ks accu stack - | KMap_enter_body (body, xs, ys, ks) -> - let extra = (body, xs, ys) in - (kmap_enter [@ocaml.tailcall]) id g gas extra ks accu stack - | KMap_exit_body (body, xs, ys, yk, ks) -> - let extra = (body, xs, ys, yk) in - (kmap_exit [@ocaml.tailcall]) id g gas extra ks accu stack - | KView_exit (orig_step_constants, ks) -> - let g = (fst g, orig_step_constants) in - (next [@ocaml.tailcall]) g gas ks accu stack) - -(* - - Evaluation of instructions - ========================== - - The following functions define evaluation rules for instructions that - generate fresh continuations. As such, they expect a constructor - [log_if_needed] which inserts a [KLog] if the evaluation is logged. - - The [step] function is taking care of the evaluation of the other - instructions. - -*) -and ilist_map : type a b c d e f g h. (a, b, c, d, e, f, g, h) ilist_map_type = - fun log_if_needed g gas (body, k) ks accu stack -> - let xs = accu.elements in - let ys = [] in - let len = accu.length in - let ks = - log_if_needed (KList_enter_body (body, xs, ys, len, KCons (k, ks))) - in - let (accu, stack) = stack in - (next [@ocaml.tailcall]) g gas ks accu stack - [@@inline] - -and ilist_iter : type a b c d e f g. (a, b, c, d, e, f, g) ilist_iter_type = - fun log_if_needed g gas (body, k) ks accu stack -> - let xs = accu.elements in - let ks = log_if_needed (KIter (body, xs, KCons (k, ks))) in - let (accu, stack) = stack in - (next [@ocaml.tailcall]) g gas ks accu stack - [@@inline] - -and iset_iter : type a b c d e f g. (a, b, c, d, e, f, g) iset_iter_type = - fun log_if_needed g gas (body, k) ks accu stack -> - let set = accu in - let l = List.rev (Script_set.fold (fun e acc -> e :: acc) set []) in - let ks = log_if_needed (KIter (body, l, KCons (k, ks))) in - let (accu, stack) = stack in - (next [@ocaml.tailcall]) g gas ks accu stack - [@@inline] - -and imap_map : type a b c d e f g h i. (a, b, c, d, e, f, g, h, i) imap_map_type - = - fun log_if_needed g gas (body, k) ks accu stack -> - let map = accu in - let xs = List.rev (Script_map.fold (fun k v a -> (k, v) :: a) map []) in - let ys = Script_map.(empty @@ key_ty map) in - let ks = log_if_needed (KMap_enter_body (body, xs, ys, KCons (k, ks))) in - let (accu, stack) = stack in - (next [@ocaml.tailcall]) g gas ks accu stack - [@@inline] - -and imap_iter : type a b c d e f g h. (a, b, c, d, e, f, g, h) imap_iter_type = - fun log_if_needed g gas (body, k) ks accu stack -> - let map = accu in - let l = List.rev (Script_map.fold (fun k v a -> (k, v) :: a) map []) in - let ks = log_if_needed (KIter (body, l, KCons (k, ks))) in - let (accu, stack) = stack in - (next [@ocaml.tailcall]) g gas ks accu stack - [@@inline] - -and imul_teznat : type a b c d e f. (a, b, c, d, e, f) imul_teznat_type = - fun logger g gas (kinfo, k) ks accu stack -> - let x = accu in - let (y, stack) = stack in - match Script_int.to_int64 y with - | None -> get_log logger >>=? fun log -> fail (Overflow (kinfo.iloc, log)) - | Some y -> - Tez.(x *? y) >>?= fun res -> (step [@ocaml.tailcall]) g gas k ks res stack - -and imul_nattez : type a b c d e f. (a, b, c, d, e, f) imul_nattez_type = - fun logger g gas (kinfo, k) ks accu stack -> - let y = accu in - let (x, stack) = stack in - match Script_int.to_int64 y with - | None -> get_log logger >>=? fun log -> fail (Overflow (kinfo.iloc, log)) - | Some y -> - Tez.(x *? y) >>?= fun res -> (step [@ocaml.tailcall]) g gas k ks res stack - -and ilsl_nat : type a b c d e f. (a, b, c, d, e, f) ilsl_nat_type = - fun logger g gas (kinfo, k) ks accu stack -> - let x = accu and (y, stack) = stack in - match Script_int.shift_left_n x y with - | None -> get_log logger >>=? fun log -> fail (Overflow (kinfo.iloc, log)) - | Some x -> (step [@ocaml.tailcall]) g gas k ks x stack - -and ilsr_nat : type a b c d e f. (a, b, c, d, e, f) ilsr_nat_type = - fun logger g gas (kinfo, k) ks accu stack -> - let x = accu and (y, stack) = stack in - match Script_int.shift_right_n x y with - | None -> get_log logger >>=? fun log -> fail (Overflow (kinfo.iloc, log)) - | Some r -> (step [@ocaml.tailcall]) g gas k ks r stack - -and ifailwith : type a b. (a, b) ifailwith_type = - fun logger (ctxt, _) gas kloc tv accu -> - let v = accu in - let ctxt = update_context gas ctxt in - trace Cannot_serialize_failure (unparse_data ctxt Optimized tv v) - >>=? fun (v, _ctxt) -> - let v = Micheline.strip_locations v in - get_log logger >>=? fun log -> fail (Reject (kloc, v, log)) - -and iexec : type a b c d e f g. (a, b, c, d, e, f, g) iexec_type = - fun logger g gas k ks accu stack -> - let arg = accu and (code, stack) = stack in - let (Lam (code, _)) = code in - let code = - match logger with - | None -> code.kinstr - | Some logger -> log_kinstr logger code.kinstr - in - let ks = KReturn (stack, KCons (k, ks)) in - (step [@ocaml.tailcall]) g gas code ks arg (EmptyCell, EmptyCell) - -and step : type a s b t r f. (a, s, b, t, r, f) step_type = - fun ((ctxt, sc) as g) gas i ks accu stack -> - match consume_instr gas i accu stack with - | None -> fail Gas.Operation_quota_exceeded - | Some gas -> ( - match i with - | ILog (_, event, logger, k) -> - (log [@ocaml.tailcall]) (logger, event) g gas k ks accu stack - | IHalt _ -> (next [@ocaml.tailcall]) g gas ks accu stack - (* stack ops *) - | IDrop (_, k) -> - let (accu, stack) = stack in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IDup (_, k) -> (step [@ocaml.tailcall]) g gas k ks accu (accu, stack) - | ISwap (_, k) -> - let (top, stack) = stack in - (step [@ocaml.tailcall]) g gas k ks top (accu, stack) - | IConst (_, v, k) -> (step [@ocaml.tailcall]) g gas k ks v (accu, stack) - (* options *) - | ICons_some (_, k) -> - (step [@ocaml.tailcall]) g gas k ks (Some accu) stack - | ICons_none (_, k) -> - (step [@ocaml.tailcall]) g gas k ks None (accu, stack) - | IIf_none {branch_if_none; branch_if_some; k; _} -> ( - match accu with - | None -> - let (accu, stack) = stack in - (step [@ocaml.tailcall]) - g - gas - branch_if_none - (KCons (k, ks)) - accu - stack - | Some v -> - (step [@ocaml.tailcall]) - g - gas - branch_if_some - (KCons (k, ks)) - v - stack) - | IOpt_map {body; k; kinfo = _} -> ( - match accu with - | None -> (step [@ocaml.tailcall]) g gas k ks None stack - | Some v -> - let ks' = KMap_head (Option.some, KCons (k, ks)) in - (step [@ocaml.tailcall]) g gas body ks' v stack) - (* pairs *) - | ICons_pair (_, k) -> - let (b, stack) = stack in - (step [@ocaml.tailcall]) g gas k ks (accu, b) stack - | IUnpair (_, k) -> - let (a, b) = accu in - (step [@ocaml.tailcall]) g gas k ks a (b, stack) - | ICar (_, k) -> - let (a, _) = accu in - (step [@ocaml.tailcall]) g gas k ks a stack - | ICdr (_, k) -> - let (_, b) = accu in - (step [@ocaml.tailcall]) g gas k ks b stack - (* unions *) - | ICons_left (_, k) -> (step [@ocaml.tailcall]) g gas k ks (L accu) stack - | ICons_right (_, k) -> (step [@ocaml.tailcall]) g gas k ks (R accu) stack - | IIf_left {branch_if_left; branch_if_right; k; _} -> ( - match accu with - | L v -> - (step [@ocaml.tailcall]) - g - gas - branch_if_left - (KCons (k, ks)) - v - stack - | R v -> - (step [@ocaml.tailcall]) - g - gas - branch_if_right - (KCons (k, ks)) - v - stack) - (* lists *) - | ICons_list (_, k) -> - let (tl, stack) = stack in - let accu = Script_list.cons accu tl in - (step [@ocaml.tailcall]) g gas k ks accu stack - | INil (_, k) -> - let stack = (accu, stack) in - let accu = Script_list.empty in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IIf_cons {branch_if_cons; branch_if_nil; k; _} -> ( - match accu.elements with - | [] -> - let (accu, stack) = stack in - (step [@ocaml.tailcall]) - g - gas - branch_if_nil - (KCons (k, ks)) - accu - stack - | hd :: tl -> - let tl = {elements = tl; length = accu.length - 1} in - (step [@ocaml.tailcall]) - g - gas - branch_if_cons - (KCons (k, ks)) - hd - (tl, stack)) - | IList_map (_, body, k) -> - (ilist_map [@ocaml.tailcall]) id g gas (body, k) ks accu stack - | IList_size (_, k) -> - let list = accu in - let len = Script_int.(abs (of_int list.length)) in - (step [@ocaml.tailcall]) g gas k ks len stack - | IList_iter (_, body, k) -> - (ilist_iter [@ocaml.tailcall]) id g gas (body, k) ks accu stack - (* sets *) - | IEmpty_set (_, ty, k) -> - let res = Script_set.empty ty in - let stack = (accu, stack) in - (step [@ocaml.tailcall]) g gas k ks res stack - | ISet_iter (_, body, k) -> - (iset_iter [@ocaml.tailcall]) id g gas (body, k) ks accu stack - | ISet_mem (_, k) -> - let (set, stack) = stack in - let res = Script_set.mem accu set in - (step [@ocaml.tailcall]) g gas k ks res stack - | ISet_update (_, k) -> - let (presence, (set, stack)) = stack in - let res = Script_set.update accu presence set in - (step [@ocaml.tailcall]) g gas k ks res stack - | ISet_size (_, k) -> - let res = Script_set.size accu in - (step [@ocaml.tailcall]) g gas k ks res stack - (* maps *) - | IEmpty_map (_, ty, k) -> - let res = Script_map.empty ty and stack = (accu, stack) in - (step [@ocaml.tailcall]) g gas k ks res stack - | IMap_map (_, body, k) -> - (imap_map [@ocaml.tailcall]) id g gas (body, k) ks accu stack - | IMap_iter (_, body, k) -> - (imap_iter [@ocaml.tailcall]) id g gas (body, k) ks accu stack - | IMap_mem (_, k) -> - let (map, stack) = stack in - let res = Script_map.mem accu map in - (step [@ocaml.tailcall]) g gas k ks res stack - | IMap_get (_, k) -> - let (map, stack) = stack in - let res = Script_map.get accu map in - (step [@ocaml.tailcall]) g gas k ks res stack - | IMap_update (_, k) -> - let (v, (map, stack)) = stack in - let key = accu in - let res = Script_map.update key v map in - (step [@ocaml.tailcall]) g gas k ks res stack - | IMap_get_and_update (_, k) -> - let key = accu in - let (v, (map, rest)) = stack in - let map' = Script_map.update key v map in - let v' = Script_map.get key map in - (step [@ocaml.tailcall]) g gas k ks v' (map', rest) - | IMap_size (_, k) -> - let res = Script_map.size accu in - (step [@ocaml.tailcall]) g gas k ks res stack - (* Big map operations *) - | IEmpty_big_map (_, tk, tv, k) -> - let ebm = Script_ir_translator.empty_big_map tk tv in - (step [@ocaml.tailcall]) g gas k ks ebm (accu, stack) - | IBig_map_mem (_, k) -> - let (map, stack) = stack in - let key = accu in - ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> - Script_ir_translator.big_map_mem ctxt key map ) - >>=? fun (res, ctxt, gas) -> - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks res stack - | IBig_map_get (_, k) -> - let (map, stack) = stack in - let key = accu in - ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> - Script_ir_translator.big_map_get ctxt key map ) - >>=? fun (res, ctxt, gas) -> - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks res stack - | IBig_map_update (_, k) -> - let key = accu in - let (maybe_value, (map, stack)) = stack in - ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> - Script_ir_translator.big_map_update ctxt key maybe_value map ) - >>=? fun (big_map, ctxt, gas) -> - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks big_map stack - | IBig_map_get_and_update (_, k) -> - let key = accu in - let (v, (map, stack)) = stack in - ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> - Script_ir_translator.big_map_get_and_update ctxt key v map ) - >>=? fun ((v', map'), ctxt, gas) -> - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks v' (map', stack) - (* timestamp operations *) - | IAdd_seconds_to_timestamp (_, k) -> - let n = accu in - let (t, stack) = stack in - let result = Script_timestamp.add_delta t n in - (step [@ocaml.tailcall]) g gas k ks result stack - | IAdd_timestamp_to_seconds (_, k) -> - let t = accu in - let (n, stack) = stack in - let result = Script_timestamp.add_delta t n in - (step [@ocaml.tailcall]) g gas k ks result stack - | ISub_timestamp_seconds (_, k) -> - let t = accu in - let (s, stack) = stack in - let result = Script_timestamp.sub_delta t s in - (step [@ocaml.tailcall]) g gas k ks result stack - | IDiff_timestamps (_, k) -> - let t1 = accu in - let (t2, stack) = stack in - let result = Script_timestamp.diff t1 t2 in - (step [@ocaml.tailcall]) g gas k ks result stack - (* string operations *) - | IConcat_string_pair (_, k) -> - let x = accu in - let (y, stack) = stack in - let s = Script_string.concat_pair x y in - (step [@ocaml.tailcall]) g gas k ks s stack - | IConcat_string (_, k) -> - let ss = accu in - (* The cost for this fold_left has been paid upfront *) - let total_length = - List.fold_left - (fun acc s -> S.add acc (S.safe_int (Script_string.length s))) - S.zero - ss.elements - in - consume gas (Interp_costs.concat_string total_length) >>?= fun gas -> - let s = Script_string.concat ss.elements in - (step [@ocaml.tailcall]) g gas k ks s stack - | ISlice_string (_, k) -> - let offset = accu and (length, (s, stack)) = stack in - let s_length = Z.of_int (Script_string.length s) in - let offset = Script_int.to_zint offset in - let length = Script_int.to_zint length in - if Compare.Z.(offset < s_length && Z.add offset length <= s_length) - then - let s = Script_string.sub s (Z.to_int offset) (Z.to_int length) in - (step [@ocaml.tailcall]) g gas k ks (Some s) stack - else (step [@ocaml.tailcall]) g gas k ks None stack - | IString_size (_, k) -> - let s = accu in - let result = Script_int.(abs (of_int (Script_string.length s))) in - (step [@ocaml.tailcall]) g gas k ks result stack - (* bytes operations *) - | IConcat_bytes_pair (_, k) -> - let x = accu in - let (y, stack) = stack in - let s = Bytes.cat x y in - (step [@ocaml.tailcall]) g gas k ks s stack - | IConcat_bytes (_, k) -> - let ss = accu in - (* The cost for this fold_left has been paid upfront *) - let total_length = - List.fold_left - (fun acc s -> S.add acc (S.safe_int (Bytes.length s))) - S.zero - ss.elements - in - consume gas (Interp_costs.concat_string total_length) >>?= fun gas -> - let s = Bytes.concat Bytes.empty ss.elements in - (step [@ocaml.tailcall]) g gas k ks s stack - | ISlice_bytes (_, k) -> - let offset = accu and (length, (s, stack)) = stack in - let s_length = Z.of_int (Bytes.length s) in - let offset = Script_int.to_zint offset in - let length = Script_int.to_zint length in - if Compare.Z.(offset < s_length && Z.add offset length <= s_length) - then - let s = Bytes.sub s (Z.to_int offset) (Z.to_int length) in - (step [@ocaml.tailcall]) g gas k ks (Some s) stack - else (step [@ocaml.tailcall]) g gas k ks None stack - | IBytes_size (_, k) -> - let s = accu in - let result = Script_int.(abs (of_int (Bytes.length s))) in - (step [@ocaml.tailcall]) g gas k ks result stack - (* currency operations *) - | IAdd_tez (_, k) -> - let x = accu in - let (y, stack) = stack in - Tez.(x +? y) >>?= fun res -> - (step [@ocaml.tailcall]) g gas k ks res stack - | ISub_tez (_, k) -> - let x = accu in - let (y, stack) = stack in - let res = Tez.sub_opt x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | ISub_tez_legacy (_, k) -> - let x = accu in - let (y, stack) = stack in - Tez.(x -? y) >>?= fun res -> - (step [@ocaml.tailcall]) g gas k ks res stack - | IMul_teznat (kinfo, k) -> - imul_teznat None g gas (kinfo, k) ks accu stack - | IMul_nattez (kinfo, k) -> - imul_nattez None g gas (kinfo, k) ks accu stack - (* boolean operations *) - | IOr (_, k) -> - let x = accu in - let (y, stack) = stack in - (step [@ocaml.tailcall]) g gas k ks (x || y) stack - | IAnd (_, k) -> - let x = accu in - let (y, stack) = stack in - (step [@ocaml.tailcall]) g gas k ks (x && y) stack - | IXor (_, k) -> - let x = accu in - let (y, stack) = stack in - let res = Compare.Bool.(x <> y) in - (step [@ocaml.tailcall]) g gas k ks res stack - | INot (_, k) -> - let x = accu in - (step [@ocaml.tailcall]) g gas k ks (not x) stack - (* integer operations *) - | IIs_nat (_, k) -> - let x = accu in - let res = Script_int.is_nat x in - (step [@ocaml.tailcall]) g gas k ks res stack - | IAbs_int (_, k) -> - let x = accu in - let res = Script_int.abs x in - (step [@ocaml.tailcall]) g gas k ks res stack - | IInt_nat (_, k) -> - let x = accu in - let res = Script_int.int x in - (step [@ocaml.tailcall]) g gas k ks res stack - | INeg (_, k) -> - let x = accu in - let res = Script_int.neg x in - (step [@ocaml.tailcall]) g gas k ks res stack - | IAdd_int (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.add x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IAdd_nat (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.add_n x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | ISub_int (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.sub x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IMul_int (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.mul x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IMul_nat (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.mul_n x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IEdiv_teznat (_, k) -> - let x = accu and (y, stack) = stack in - let x = Script_int.of_int64 (Tez.to_mutez x) in - let result = - match Script_int.ediv x y with - | None -> None - | Some (q, r) -> ( - match (Script_int.to_int64 q, Script_int.to_int64 r) with - | (Some q, Some r) -> ( - match (Tez.of_mutez q, Tez.of_mutez r) with - | (Some q, Some r) -> Some (q, r) - (* Cannot overflow *) - | _ -> assert false) - (* Cannot overflow *) - | _ -> assert false) - in - (step [@ocaml.tailcall]) g gas k ks result stack - | IEdiv_tez (_, k) -> - let x = accu and (y, stack) = stack in - let x = Script_int.abs (Script_int.of_int64 (Tez.to_mutez x)) in - let y = Script_int.abs (Script_int.of_int64 (Tez.to_mutez y)) in - let result = - match Script_int.ediv_n x y with - | None -> None - | Some (q, r) -> ( - match Script_int.to_int64 r with - | None -> assert false (* Cannot overflow *) - | Some r -> ( - match Tez.of_mutez r with - | None -> assert false (* Cannot overflow *) - | Some r -> Some (q, r))) - in - (step [@ocaml.tailcall]) g gas k ks result stack - | IEdiv_int (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.ediv x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IEdiv_nat (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.ediv_n x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | ILsl_nat (kinfo, k) -> ilsl_nat None g gas (kinfo, k) ks accu stack - | ILsr_nat (kinfo, k) -> ilsr_nat None g gas (kinfo, k) ks accu stack - | IOr_nat (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.logor x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IAnd_nat (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.logand x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IAnd_int_nat (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.logand x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IXor_nat (_, k) -> - let x = accu and (y, stack) = stack in - let res = Script_int.logxor x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | INot_int (_, k) -> - let x = accu in - let res = Script_int.lognot x in - (step [@ocaml.tailcall]) g gas k ks res stack - (* control *) - | IIf {branch_if_true; branch_if_false; k; _} -> - let (res, stack) = stack in - if accu then - (step [@ocaml.tailcall]) - g - gas - branch_if_true - (KCons (k, ks)) - res - stack - else - (step [@ocaml.tailcall]) - g - gas - branch_if_false - (KCons (k, ks)) - res - stack - | ILoop (_, body, k) -> - let ks = KLoop_in (body, KCons (k, ks)) in - (next [@ocaml.tailcall]) g gas ks accu stack - | ILoop_left (_, bl, br) -> - let ks = KLoop_in_left (bl, KCons (br, ks)) in - (next [@ocaml.tailcall]) g gas ks accu stack - | IDip (_, b, k) -> - let ign = accu in - let ks = KUndip (ign, KCons (k, ks)) in - let (accu, stack) = stack in - (step [@ocaml.tailcall]) g gas b ks accu stack - | IExec (_, k) -> iexec None g gas k ks accu stack - | IApply (_, capture_ty, k) -> - let capture = accu in - let (lam, stack) = stack in - apply ctxt gas capture_ty capture lam >>=? fun (lam', ctxt, gas) -> - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks lam' stack - | ILambda (_, lam, k) -> - (step [@ocaml.tailcall]) g gas k ks lam (accu, stack) - | IFailwith (_, kloc, tv) -> ifailwith None g gas kloc tv accu - (* comparison *) - | ICompare (_, ty, k) -> - let a = accu in - let (b, stack) = stack in - let r = - Script_int.of_int @@ Script_comparable.compare_comparable ty a b - in - (step [@ocaml.tailcall]) g gas k ks r stack - (* comparators *) - | IEq (_, k) -> - let a = accu in - let a = Script_int.compare a Script_int.zero in - let a = Compare.Int.(a = 0) in - (step [@ocaml.tailcall]) g gas k ks a stack - | INeq (_, k) -> - let a = accu in - let a = Script_int.compare a Script_int.zero in - let a = Compare.Int.(a <> 0) in - (step [@ocaml.tailcall]) g gas k ks a stack - | ILt (_, k) -> - let a = accu in - let a = Script_int.compare a Script_int.zero in - let a = Compare.Int.(a < 0) in - (step [@ocaml.tailcall]) g gas k ks a stack - | ILe (_, k) -> - let a = accu in - let a = Script_int.compare a Script_int.zero in - let a = Compare.Int.(a <= 0) in - (step [@ocaml.tailcall]) g gas k ks a stack - | IGt (_, k) -> - let a = accu in - let a = Script_int.compare a Script_int.zero in - let a = Compare.Int.(a > 0) in - (step [@ocaml.tailcall]) g gas k ks a stack - | IGe (_, k) -> - let a = accu in - let a = Script_int.compare a Script_int.zero in - let a = Compare.Int.(a >= 0) in - (step [@ocaml.tailcall]) g gas k ks a stack - (* packing *) - | IPack (_, ty, k) -> - let value = accu in - ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> - Script_ir_translator.pack_data ctxt ty value ) - >>=? fun (bytes, ctxt, gas) -> - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks bytes stack - | IUnpack (_, ty, k) -> - let bytes = accu in - ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> - unpack ctxt ~ty ~bytes ) - >>=? fun (opt, ctxt, gas) -> - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks opt stack - | IAddress (_, k) -> - let (_, address) = accu in - (step [@ocaml.tailcall]) g gas k ks address stack - | IContract (kinfo, t, entrypoint, k) -> ( - let contract = accu in - match (contract, entrypoint) with - | ((contract, "default"), entrypoint) - | ((contract, entrypoint), "default") -> - let ctxt = update_context gas ctxt in - Script_ir_translator.parse_contract_for_script - ctxt - kinfo.iloc - t - contract - ~entrypoint - >>=? fun (ctxt, maybe_contract) -> - let gas = update_local_gas_counter ctxt in - let ctxt = outdated ctxt in - let accu = maybe_contract in - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks accu stack - | _ -> (step [@ocaml.tailcall]) (ctxt, sc) gas k ks None stack) - | ITransfer_tokens (_, k) -> - let p = accu in - let (amount, ((tp, (destination, entrypoint)), stack)) = stack in - transfer (ctxt, sc) gas amount tp p destination entrypoint - >>=? fun (accu, ctxt, gas) -> - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks accu stack - | IImplicit_account (_, k) -> - let key = accu in - let contract = Contract.implicit_contract key in - let res = (unit_t ~annot:None, (contract, "default")) in - (step [@ocaml.tailcall]) g gas k ks res stack - | IView (_, View_signature {name; input_ty; output_ty}, k) -> ( - let input = accu in - let ((c, _entrypoint_is_ignored), stack) = stack in - let ctxt = update_context gas ctxt in - Contract.get_script ctxt c >>=? fun (ctxt, script_opt) -> - let return_none ctxt = - (step [@ocaml.tailcall]) - (outdated ctxt, sc) - (update_local_gas_counter ctxt) - k - ks - None - stack - in - match script_opt with - | None -> (return_none [@ocaml.tailcall]) ctxt - | Some script -> ( - parse_script - ~legacy:true - ~allow_forged_in_storage:true - ctxt - script - >>=? fun (Ex_script {storage; storage_type; views; _}, ctxt) -> - Gas.consume ctxt (Interp_costs.view_get name views) - >>?= fun ctxt -> - match SMap.find name views with - | None -> (return_none [@ocaml.tailcall]) ctxt - | Some view -> ( - let view_result = - Script_ir_translator.parse_view_returning - ctxt - ~legacy:true - storage_type - view - in - trace_eval - (fun () -> - Script_tc_errors.Ill_typed_contract - (Micheline.strip_locations view.view_code, [])) - view_result - >>=? fun (Ex_view f, ctxt) -> - match f with - | Lam - ( { - kloc; - kaft = Item_t (aft_ty, Bot_t, _); - kbef = Item_t (bef_ty, Bot_t, _); - kinstr; - }, - _script_view ) -> ( - pair_t - kloc - (input_ty, None, None) - (storage_type, None, None) - ~annot:None - >>?= fun pair_ty -> - let open Gas_monad in - let io_ty = - Script_ir_translator.merge_types - ~merge_type_error_flag:Default_merge_type_error - ~legacy:true - kloc - aft_ty - output_ty - >>$ fun (out_eq, _ty) -> - merge_types - ~merge_type_error_flag:Default_merge_type_error - ~legacy:true - kloc - bef_ty - pair_ty - >|$ fun (in_eq, _ty) -> (out_eq, in_eq) - in - Gas_monad.run ctxt io_ty >>?= fun (eq, ctxt) -> - match eq with - | Error _ -> (return_none [@ocaml.tailcall]) ctxt - | Ok (Eq, Eq) -> ( - let kkinfo = kinfo_of_kinstr k in - match kkinfo.kstack_ty with - | Item_t (_, s, a) -> - let kstack_ty = Item_t (output_ty, s, a) in - let kkinfo = {kkinfo with kstack_ty} in - let ks = KCons (ICons_some (kkinfo, k), ks) in - (step [@ocaml.tailcall]) - ( outdated ctxt, - { - sc with - source = sc.self; - self = c; - amount = Tez.zero; - } ) - (update_local_gas_counter ctxt) - kinstr - (KView_exit (sc, KReturn (stack, ks))) - (input, storage) - (EmptyCell, EmptyCell)))))) - | ICreate_contract - { - storage_type; - arg_type; - lambda = Lam (_, code); - views; - root_name; - k; - _; - } -> - (* Removed the instruction's arguments manager, spendable and delegatable *) - let delegate = accu in - let (credit, (init, stack)) = stack in - create_contract - g - gas - storage_type - arg_type - code - views - root_name - delegate - credit - init - >>=? fun (res, contract, ctxt, gas) -> - let stack = ((contract, "default"), stack) in - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks res stack - | ISet_delegate (_, k) -> - let delegate = accu in - let operation = Delegation delegate in - let ctxt = update_context gas ctxt in - fresh_internal_nonce ctxt >>?= fun (ctxt, nonce) -> - let res = - (Internal_operation {source = sc.self; operation; nonce}, None) - in - let gas = update_local_gas_counter ctxt in - let ctxt = outdated ctxt in - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks res stack - | IBalance (_, k) -> - let ctxt = update_context gas ctxt in - Contract.get_balance_carbonated ctxt sc.self - >>=? fun (ctxt, balance) -> - let gas = update_local_gas_counter ctxt in - let ctxt = outdated ctxt in - let g = (ctxt, sc) in - (step [@ocaml.tailcall]) g gas k ks balance (accu, stack) - | ILevel (_, k) -> - (step [@ocaml.tailcall]) g gas k ks sc.level (accu, stack) - | INow (_, k) -> (step [@ocaml.tailcall]) g gas k ks sc.now (accu, stack) - | ICheck_signature (_, k) -> - let key = accu and (signature, (message, stack)) = stack in - let res = Signature.check key signature message in - (step [@ocaml.tailcall]) g gas k ks res stack - | IHash_key (_, k) -> - let key = accu in - let res = Signature.Public_key.hash key in - (step [@ocaml.tailcall]) g gas k ks res stack - | IBlake2b (_, k) -> - let bytes = accu in - let hash = Raw_hashes.blake2b bytes in - (step [@ocaml.tailcall]) g gas k ks hash stack - | ISha256 (_, k) -> - let bytes = accu in - let hash = Raw_hashes.sha256 bytes in - (step [@ocaml.tailcall]) g gas k ks hash stack - | ISha512 (_, k) -> - let bytes = accu in - let hash = Raw_hashes.sha512 bytes in - (step [@ocaml.tailcall]) g gas k ks hash stack - | ISource (_, k) -> - let res = (sc.payer, "default") in - (step [@ocaml.tailcall]) g gas k ks res (accu, stack) - | ISender (_, k) -> - let res = (sc.source, "default") in - (step [@ocaml.tailcall]) g gas k ks res (accu, stack) - | ISelf (_, ty, entrypoint, k) -> - let res = (ty, (sc.self, entrypoint)) in - (step [@ocaml.tailcall]) g gas k ks res (accu, stack) - | ISelf_address (_, k) -> - let res = (sc.self, "default") in - (step [@ocaml.tailcall]) g gas k ks res (accu, stack) - | IAmount (_, k) -> - let accu = sc.amount and stack = (accu, stack) in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IDig (_, _n, n', k) -> - let ((accu, stack), x) = - interp_stack_prefix_preserving_operation - (fun v stack -> (stack, v)) - n' - accu - stack - in - let accu = x and stack = (accu, stack) in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IDug (_, _n, n', k) -> - let v = accu in - let (accu, stack) = stack in - let ((accu, stack), ()) = - interp_stack_prefix_preserving_operation - (fun accu stack -> ((v, (accu, stack)), ())) - n' - accu - stack - in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IDipn (_, _n, n', b, k) -> - let (accu, stack, restore_prefix) = kundip n' accu stack k in - let ks = KCons (restore_prefix, ks) in - (step [@ocaml.tailcall]) g gas b ks accu stack - | IDropn (_, _n, n', k) -> - let stack = - let rec aux : - type a s b t. - (b, t, b, t, a, s, a, s) stack_prefix_preservation_witness -> - a -> - s -> - b * t = - fun w accu stack -> - match w with - | KRest -> (accu, stack) - | KPrefix (_, w) -> - let (accu, stack) = stack in - aux w accu stack - in - aux n' accu stack - in - let (accu, stack) = stack in - (step [@ocaml.tailcall]) g gas k ks accu stack - | ISapling_empty_state (_, memo_size, k) -> - let state = Sapling.empty_state ~memo_size () in - (step [@ocaml.tailcall]) g gas k ks state (accu, stack) - | ISapling_verify_update (_, k) -> ( - let transaction = accu in - let (state, stack) = stack in - let address = Contract.to_b58check sc.self in - let chain_id = Chain_id.to_b58check sc.chain_id in - let anti_replay = address ^ chain_id in - let ctxt = update_context gas ctxt in - Sapling.verify_update ctxt state transaction anti_replay - >>=? fun (ctxt, balance_state_opt) -> - let gas = update_local_gas_counter ctxt in - let ctxt = outdated ctxt in - match balance_state_opt with - | Some (balance, state) -> - let state = Some (Script_int.of_int64 balance, state) in - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks state stack - | None -> (step [@ocaml.tailcall]) (ctxt, sc) gas k ks None stack) - | IChainId (_, k) -> - let accu = sc.chain_id and stack = (accu, stack) in - (step [@ocaml.tailcall]) g gas k ks accu stack - | INever _ -> ( match accu with _ -> .) - | IVoting_power (_, k) -> - let key_hash = accu in - let ctxt = update_context gas ctxt in - Vote.get_voting_power ctxt key_hash >>=? fun (ctxt, rolls) -> - let power = Script_int.(abs (of_int32 rolls)) in - let gas = update_local_gas_counter ctxt in - let ctxt = outdated ctxt in - (step [@ocaml.tailcall]) (ctxt, sc) gas k ks power stack - | ITotal_voting_power (_, k) -> - let ctxt = update_context gas ctxt in - Vote.get_total_voting_power ctxt >>=? fun (ctxt, rolls) -> - let power = Script_int.(abs (of_int32 rolls)) in - let gas = update_local_gas_counter ctxt in - let ctxt = outdated ctxt in - let g = (ctxt, sc) in - (step [@ocaml.tailcall]) g gas k ks power (accu, stack) - | IKeccak (_, k) -> - let bytes = accu in - let hash = Raw_hashes.keccak256 bytes in - (step [@ocaml.tailcall]) g gas k ks hash stack - | ISha3 (_, k) -> - let bytes = accu in - let hash = Raw_hashes.sha3_256 bytes in - (step [@ocaml.tailcall]) g gas k ks hash stack - | IAdd_bls12_381_g1 (_, k) -> - let x = accu and (y, stack) = stack in - let accu = Bls12_381.G1.add x y in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IAdd_bls12_381_g2 (_, k) -> - let x = accu and (y, stack) = stack in - let accu = Bls12_381.G2.add x y in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IAdd_bls12_381_fr (_, k) -> - let x = accu and (y, stack) = stack in - let accu = Bls12_381.Fr.add x y in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IMul_bls12_381_g1 (_, k) -> - let x = accu and (y, stack) = stack in - let accu = Bls12_381.G1.mul x y in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IMul_bls12_381_g2 (_, k) -> - let x = accu and (y, stack) = stack in - let accu = Bls12_381.G2.mul x y in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IMul_bls12_381_fr (_, k) -> - let x = accu and (y, stack) = stack in - let accu = Bls12_381.Fr.mul x y in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IMul_bls12_381_fr_z (_, k) -> - let x = accu and (y, stack) = stack in - let x = Bls12_381.Fr.of_z (Script_int.to_zint x) in - let res = Bls12_381.Fr.mul x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IMul_bls12_381_z_fr (_, k) -> - let y = accu and (x, stack) = stack in - let x = Bls12_381.Fr.of_z (Script_int.to_zint x) in - let res = Bls12_381.Fr.mul x y in - (step [@ocaml.tailcall]) g gas k ks res stack - | IInt_bls12_381_fr (_, k) -> - let x = accu in - let res = Script_int.of_zint (Bls12_381.Fr.to_z x) in - (step [@ocaml.tailcall]) g gas k ks res stack - | INeg_bls12_381_g1 (_, k) -> - let x = accu in - let accu = Bls12_381.G1.negate x in - (step [@ocaml.tailcall]) g gas k ks accu stack - | INeg_bls12_381_g2 (_, k) -> - let x = accu in - let accu = Bls12_381.G2.negate x in - (step [@ocaml.tailcall]) g gas k ks accu stack - | INeg_bls12_381_fr (_, k) -> - let x = accu in - let accu = Bls12_381.Fr.negate x in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IPairing_check_bls12_381 (_, k) -> - let pairs = accu in - let check = Bls12_381.pairing_check pairs.elements in - (step [@ocaml.tailcall]) g gas k ks check stack - | IComb (_, _, witness, k) -> - let rec aux : - type before after. - (before, after) comb_gadt_witness -> before -> after = - fun witness stack -> - match (witness, stack) with - | (Comb_one, stack) -> stack - | (Comb_succ witness', (a, tl)) -> - let (b, tl') = aux witness' tl in - ((a, b), tl') - in - let stack = aux witness (accu, stack) in - let (accu, stack) = stack in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IUncomb (_, _, witness, k) -> - let rec aux : - type before after. - (before, after) uncomb_gadt_witness -> before -> after = - fun witness stack -> - match (witness, stack) with - | (Uncomb_one, stack) -> stack - | (Uncomb_succ witness', ((a, b), tl)) -> (a, aux witness' (b, tl)) - in - let stack = aux witness (accu, stack) in - let (accu, stack) = stack in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IComb_get (_, _, witness, k) -> - let comb = accu in - let rec aux : - type before after. - (before, after) comb_get_gadt_witness -> before -> after = - fun witness comb -> - match (witness, comb) with - | (Comb_get_zero, v) -> v - | (Comb_get_one, (a, _)) -> a - | (Comb_get_plus_two witness', (_, b)) -> aux witness' b - in - let accu = aux witness comb in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IComb_set (_, _, witness, k) -> - let value = accu and (comb, stack) = stack in - let rec aux : - type value before after. - (value, before, after) comb_set_gadt_witness -> - value -> - before -> - after = - fun witness value item -> - match (witness, item) with - | (Comb_set_zero, _) -> value - | (Comb_set_one, (_hd, tl)) -> (value, tl) - | (Comb_set_plus_two witness', (hd, tl)) -> - (hd, aux witness' value tl) - in - let accu = aux witness value comb in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IDup_n (_, _, witness, k) -> - let rec aux : - type before after. - (before, after) dup_n_gadt_witness -> before -> after = - fun witness stack -> - match (witness, stack) with - | (Dup_n_zero, (a, _)) -> a - | (Dup_n_succ witness', (_, tl)) -> aux witness' tl - in - let stack = (accu, stack) in - let accu = aux witness stack in - (step [@ocaml.tailcall]) g gas k ks accu stack - (* Tickets *) - | ITicket (_, k) -> - let contents = accu and (amount, stack) = stack in - let ticketer = sc.self in - let accu = {ticketer; contents; amount} in - (step [@ocaml.tailcall]) g gas k ks accu stack - | IRead_ticket (_, k) -> - let {ticketer; contents; amount} = accu in - let stack = (accu, stack) in - let accu = ((ticketer, "default"), (contents, amount)) in - (step [@ocaml.tailcall]) g gas k ks accu stack - | ISplit_ticket (_, k) -> - let ticket = accu and ((amount_a, amount_b), stack) = stack in - let result = - if - Compare.Int.( - Script_int.(compare (add_n amount_a amount_b) ticket.amount) = 0) - then - Some - ( {ticket with amount = amount_a}, - {ticket with amount = amount_b} ) - else None - in - (step [@ocaml.tailcall]) g gas k ks result stack - | IJoin_tickets (_, contents_ty, k) -> - let (ticket_a, ticket_b) = accu in - let result = - if - Compare.Int.( - Contract.compare ticket_a.ticketer ticket_b.ticketer = 0 - && Script_comparable.compare_comparable - contents_ty - ticket_a.contents - ticket_b.contents - = 0) - then - Some - { - ticketer = ticket_a.ticketer; - contents = ticket_a.contents; - amount = Script_int.add_n ticket_a.amount ticket_b.amount; - } - else None - in - (step [@ocaml.tailcall]) g gas k ks result stack - | IOpen_chest (_, k) -> - let open Timelock in - let chest_key = accu in - let (chest, (time_z, stack)) = stack in - (* If the time is not an integer we then consider the proof as - incorrect. Indeed the verification asks for an integer for practical reasons. - Therefore no proof can be correct.*) - let accu = - match Alpha_context.Script_int.to_int time_z with - | None -> R false - | Some time -> ( - match open_chest chest chest_key ~time with - | Correct bytes -> L bytes - | Bogus_cipher -> R false - | Bogus_opening -> R true) - in - (step [@ocaml.tailcall]) g gas k ks accu stack) - -(* - - Zero-cost logging - ================= - -*) - -(* - - The following functions insert a logging instruction and modify the - continuation to continue the logging process in the next execution - steps. - - There is a special treatment of instructions that generate fresh - continuations: we pass a constructor as argument to their - evaluation rules so that they can instrument these fresh - continuations by themselves. - - This on-the-fly instrumentation of the execution allows zero-cost - logging since logging instructions are only introduced if an - initial logging continuation is pushed in the initial continuation - that starts the evaluation. - -*) -and log : - type a s b t r f. logger * logging_event -> (a, s, b, t, r, f) step_type = - fun (logger, event) ((ctxt, _) as g) gas k ks accu stack -> - (match (k, event) with - | (ILog _, LogEntry) -> () - | (_, LogEntry) -> log_entry logger ctxt gas k accu stack - | (_, LogExit prev_kinfo) -> log_exit logger ctxt gas prev_kinfo k accu stack) ; - let k = log_next_kinstr logger k in - let with_log k = match k with KLog _ -> k | _ -> KLog (k, logger) in - match k with - | IList_map (_, body, k) -> - (ilist_map [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack - | IList_iter (_, body, k) -> - (ilist_iter [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack - | ISet_iter (_, body, k) -> - (iset_iter [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack - | IMap_map (_, body, k) -> - (imap_map [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack - | IMap_iter (_, body, k) -> - (imap_iter [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack - | ILoop (_, body, k) -> - let ks = with_log (KLoop_in (body, KCons (k, ks))) in - (next [@ocaml.tailcall]) g gas ks accu stack - | ILoop_left (_, bl, br) -> - let ks = with_log (KLoop_in_left (bl, KCons (br, ks))) in - (next [@ocaml.tailcall]) g gas ks accu stack - | IMul_teznat (kinfo, k) -> - let extra = (kinfo, k) in - (imul_teznat [@ocaml.tailcall]) (Some logger) g gas extra ks accu stack - | IMul_nattez (kinfo, k) -> - let extra = (kinfo, k) in - (imul_nattez [@ocaml.tailcall]) (Some logger) g gas extra ks accu stack - | ILsl_nat (kinfo, k) -> - let extra = (kinfo, k) in - (ilsl_nat [@ocaml.tailcall]) (Some logger) g gas extra ks accu stack - | ILsr_nat (kinfo, k) -> - let extra = (kinfo, k) in - (ilsr_nat [@ocaml.tailcall]) (Some logger) g gas extra ks accu stack - | IFailwith (_, kloc, tv) -> - (ifailwith [@ocaml.tailcall]) (Some logger) g gas kloc tv accu - | IExec (_, k) -> - (iexec [@ocaml.tailcall]) (Some logger) g gas k ks accu stack - | _ -> (step [@ocaml.tailcall]) g gas k (with_log ks) accu stack - [@@inline] - -and klog : - type a s r f. - logger -> - outdated_context * step_constants -> - local_gas_counter -> - (a, s, r, f) continuation -> - (a, s, r, f) continuation -> - a -> - s -> - (r * f * outdated_context * local_gas_counter) tzresult Lwt.t = - fun logger g gas ks0 ks accu stack -> - (match ks with KLog _ -> () | _ -> log_control logger ks) ; - let enable_log ki = log_kinstr logger ki in - let mk k = match k with KLog _ -> k | _ -> KLog (k, logger) in - match ks with - | KCons (ki, ks') -> - let log = enable_log ki in - let ks = mk ks' in - (step [@ocaml.tailcall]) g gas log ks accu stack - | KNil -> (next [@ocaml.tailcall]) g gas ks accu stack - | KLoop_in (ki, ks') -> - let ks' = mk ks' in - let ki = enable_log ki in - (kloop_in [@ocaml.tailcall]) g gas ks0 ki ks' accu stack - | KReturn (stack', ks') -> - let ks' = mk ks' in - let ks = KReturn (stack', ks') in - (next [@ocaml.tailcall]) g gas ks accu stack - | KMap_head (f, ks) -> (next [@ocaml.tailcall]) g gas ks (f accu) stack - | KLoop_in_left (ki, ks') -> - let ks' = mk ks' in - let ki = enable_log ki in - (kloop_in_left [@ocaml.tailcall]) g gas ks0 ki ks' accu stack - | KUndip (x, ks') -> - let ks' = mk ks' in - let ks = KUndip (x, ks') in - (next [@ocaml.tailcall]) g gas ks accu stack - | KIter (body, xs, ks') -> - let ks' = mk ks' in - let body = enable_log body in - (kiter [@ocaml.tailcall]) mk g gas (body, xs) ks' accu stack - | KList_enter_body (body, xs, ys, len, ks') -> - let ks' = mk ks' in - let extra = (body, xs, ys, len) in - (klist_enter [@ocaml.tailcall]) mk g gas extra ks' accu stack - | KList_exit_body (body, xs, ys, len, ks') -> - let ks' = mk ks' in - let extra = (body, xs, ys, len) in - (klist_exit [@ocaml.tailcall]) mk g gas extra ks' accu stack - | KMap_enter_body (body, xs, ys, ks') -> - let ks' = mk ks' in - (kmap_enter [@ocaml.tailcall]) mk g gas (body, xs, ys) ks' accu stack - | KMap_exit_body (body, xs, ys, yk, ks') -> - let ks' = mk ks' in - (kmap_exit [@ocaml.tailcall]) mk g gas (body, xs, ys, yk) ks' accu stack - | KView_exit (orig_step_constants, ks') -> - let g = (fst g, orig_step_constants) in - (next [@ocaml.tailcall]) g gas ks' accu stack - | KLog (_, _) -> - (* This case should never happen. *) - (next [@ocaml.tailcall]) g gas ks accu stack - [@@inline] - -(* - - Entrypoints - =========== - -*) - -let step_descr ~log_now logger (ctxt, sc) descr accu stack = - let gas = (Gas.remaining_operation_gas ctxt :> int) in - (match logger with - | None -> step (outdated ctxt, sc) gas descr.kinstr KNil accu stack - | Some logger -> - (if log_now then - let kinfo = kinfo_of_kinstr descr.kinstr in - logger.log_interp descr.kinstr ctxt kinfo.iloc descr.kbef (accu, stack)) ; - let log = - ILog (kinfo_of_kinstr descr.kinstr, LogEntry, logger, descr.kinstr) - in - step (outdated ctxt, sc) gas log KNil accu stack) - >>=? fun (accu, stack, ctxt, gas) -> - return (accu, stack, update_context gas ctxt) - -let interp logger g (Lam (code, _)) arg = - step_descr ~log_now:true logger g code arg (EmptyCell, EmptyCell) - >|=? fun (ret, (EmptyCell, EmptyCell), ctxt) -> (ret, ctxt) - -let kstep logger ctxt step_constants kinstr accu stack = - let gas = (Gas.remaining_operation_gas ctxt :> int) in - let kinstr = - match logger with - | None -> kinstr - | Some logger -> ILog (kinfo_of_kinstr kinstr, LogEntry, logger, kinstr) - in - step (outdated ctxt, step_constants) gas kinstr KNil accu stack - >>=? fun (accu, stack, ctxt, gas) -> - return (accu, stack, update_context gas ctxt) - -let internal_step ctxt step_constants gas kinstr accu stack = - step (ctxt, step_constants) gas kinstr KNil accu stack - -let step logger ctxt step_constants descr stack = - step_descr ~log_now:false logger (ctxt, step_constants) descr stack - -(* - - High-level functions - ==================== - -*) -let execute logger ctxt mode step_constants ~entrypoint ~internal - unparsed_script cached_script arg : - (Script.expr - * packed_internal_operation list - * context - * Lazy_storage.diffs option - * ex_script - * int) - tzresult - Lwt.t = - (match cached_script with - | None -> - parse_script - ctxt - unparsed_script - ~legacy:true - ~allow_forged_in_storage:true - | Some ex_script -> return (ex_script, ctxt)) - >>=? fun ( Ex_script - { - code_size; - code; - arg_type; - storage; - storage_type; - root_name; - views; - }, - ctxt ) -> - record_trace - (Bad_contract_parameter step_constants.self) - (find_entrypoint arg_type ~root_name entrypoint) - >>?= fun (box, _) -> - trace - (Bad_contract_parameter step_constants.self) - (parse_data ctxt ~legacy:false ~allow_forged:internal arg_type (box arg)) - >>=? fun (arg, ctxt) -> - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - unparsed_script.code - >>?= fun (script_code, ctxt) -> - Script_ir_translator.collect_lazy_storage ctxt arg_type arg - >>?= fun (to_duplicate, ctxt) -> - Script_ir_translator.collect_lazy_storage ctxt storage_type storage - >>?= fun (to_update, ctxt) -> - trace - (Runtime_contract_error (step_constants.self, script_code)) - (interp logger (ctxt, step_constants) code (arg, storage)) - >>=? fun ((ops, storage), ctxt) -> - Script_ir_translator.extract_lazy_storage_diff - ctxt - mode - ~temporary:false - ~to_duplicate - ~to_update - storage_type - storage - >>=? fun (storage, lazy_storage_diff, ctxt) -> - trace - Cannot_serialize_storage - ( unparse_data ctxt mode storage_type storage - >>=? fun (unparsed_storage, ctxt) -> - Lwt.return - ( Gas.consume ctxt (Script.strip_locations_cost unparsed_storage) - >>? fun ctxt -> ok (Micheline.strip_locations unparsed_storage, ctxt) ) - ) - >>=? fun (unparsed_storage, ctxt) -> - Lwt.return - (let (ops, op_diffs) = List.split ops.elements in - let lazy_storage_diff = - match - List.flatten - (List.map - (Option.value ~default:[]) - (op_diffs @ [lazy_storage_diff])) - with - | [] -> None - | diff -> Some diff - in - let script = - Ex_script - {code_size; code; arg_type; storage; storage_type; root_name; views} - in - (* We consume gas after the fact in order to not have to instrument - [script_size] (for efficiency). - This is safe, as we already pay gas proportional to storage size - in [unparse_data]. *) - let (size, cost) = Script_ir_translator.script_size script in - Gas.consume ctxt cost >>? fun ctxt -> - ok (unparsed_storage, ops, ctxt, lazy_storage_diff, script, size)) - -type execution_result = { - ctxt : context; - storage : Script.expr; - lazy_storage_diff : Lazy_storage.diffs option; - operations : packed_internal_operation list; -} - -let execute ?logger ctxt ~cached_script mode step_constants ~script ~entrypoint - ~parameter ~internal = - execute - logger - ctxt - mode - step_constants - ~entrypoint - ~internal - script - cached_script - (Micheline.root parameter) - >|=? fun (storage, operations, ctxt, lazy_storage_diff, ex_script, approx_size) - -> ({ctxt; storage; lazy_storage_diff; operations}, (ex_script, approx_size)) - -(* - - Internals - ========= - -*) - -(* - - We export the internals definitions for tool that requires - a white-box view on the interpreter, typically snoop, the - gas model inference engine. - -*) -module Internals = struct - type nonrec local_gas_counter = local_gas_counter - - type nonrec outdated_context = outdated_context = - | OutDatedContext of Alpha_context.t - [@@unboxed] - - let next logger g gas ks accu stack = - let ks = - match logger with None -> ks | Some logger -> KLog (ks, logger) - in - next g gas ks accu stack - - let step (ctxt, step_constants) gas ks accu stack = - internal_step ctxt step_constants gas ks accu stack -end diff --git a/src/proto_012_Psithaca/lib_protocol/script_interpreter.mli b/src/proto_012_Psithaca/lib_protocol/script_interpreter.mli deleted file mode 100644 index 2f2f5b7c672b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_interpreter.mli +++ /dev/null @@ -1,168 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This is the Michelson interpreter. - - This module offers a way to execute either a Michelson script or a - Michelson instruction. - - Implementation details are documented in the .ml file. - -*) - -open Alpha_context -open Script_typed_ir - -type error += Reject of Script.location * Script.expr * execution_trace option - -type error += Overflow of Script.location * execution_trace option - -type error += Runtime_contract_error : Contract.t * Script.expr -> error - -type error += Bad_contract_parameter of Contract.t (* `Permanent *) - -type error += Cannot_serialize_failure - -type error += Cannot_serialize_storage - -type error += Michelson_too_many_recursive_calls - -type execution_result = { - ctxt : context; - storage : Script.expr; - lazy_storage_diff : Lazy_storage.diffs option; - operations : packed_internal_operation list; -} - -type step_constants = Script_typed_ir.step_constants = { - source : Contract.t; - payer : Contract.t; - self : Contract.t; - amount : Tez.t; - chain_id : Chain_id.t; - now : Script_timestamp.t; - level : Script_int.n Script_int.num; -} - -val step : - logger option -> - context -> - Script_typed_ir.step_constants -> - ('a, 's, 'r, 'f) Script_typed_ir.kdescr -> - 'a -> - 's -> - ('r * 'f * context) tzresult Lwt.t - -(** [execute ?logger ctxt ~cached_script mode step_constant ~script - ~entrypoint ~parameter ~internal] interprets the [script]'s - [entrypoint] for a given [parameter]. - - This will update the local storage of the contract - [step_constants.self]. Other pieces of contextual information - ([source], [payer], [amount], and [chaind_id]) are also passed in - [step_constant]. - - [internal] is [true] if and only if the execution happens within an - internal operation. - - [mode] is the unparsing mode, as declared by - {!Script_ir_translator}. - - [cached_script] is the cached elaboration of [script], that is the - well typed abstract syntax tree produced by the type elaboration of - [script] during a previous execution and stored in the in-memory - cache. - -*) -val execute : - ?logger:logger -> - Alpha_context.t -> - cached_script:Script_ir_translator.ex_script option -> - Script_ir_translator.unparsing_mode -> - step_constants -> - script:Script.t -> - entrypoint:string -> - parameter:Script.expr -> - internal:bool -> - (execution_result * (Script_ir_translator.ex_script * int)) tzresult Lwt.t - -(** [kstep logger ctxt step_constants kinstr accu stack] interprets the - script represented by [kinstr] under the context [ctxt]. This will - turn a stack whose topmost element is [accu] and remaining elements - [stack] into a new accumulator and a new stack. This function also - returns an updated context. If [logger] is given, [kstep] calls back - its functions at specific points of the execution. The execution is - parameterized by some [step_constants]. *) -val kstep : - logger option -> - context -> - step_constants -> - ('a, 's, 'r, 'f) Script_typed_ir.kinstr -> - 'a -> - 's -> - ('r * 'f * context) tzresult Lwt.t - -(** Internal interpretation loop - ============================ - - The following types and the following functions are exposed - in the interface to allow the inference of a gas model in - snoop. - - Strictly speaking, they should not be considered as part of - the interface since they expose implementation details that - may change in the future. - -*) - -module Internals : sig - (** Internally, the interpretation loop uses a local gas counter. *) - type local_gas_counter = int - - (** During the evaluation, the gas level in the context is outdated. - See comments in the implementation file for more details. *) - type outdated_context = OutDatedContext of context [@@unboxed] - - (** [next logger (ctxt, step_constants) local_gas_counter ks accu - stack] is an internal function which interprets the continuation - [ks] to execute the interpreter on the current A-stack. *) - val next : - logger option -> - outdated_context * step_constants -> - local_gas_counter -> - ('a, 's, 'r, 'f) continuation -> - 'a -> - 's -> - ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t - - val step : - outdated_context * step_constants -> - local_gas_counter -> - ('a, 's, 'r, 'f) Script_typed_ir.kinstr -> - 'a -> - 's -> - ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t -end diff --git a/src/proto_012_Psithaca/lib_protocol/script_interpreter_defs.ml b/src/proto_012_Psithaca/lib_protocol/script_interpreter_defs.ml deleted file mode 100644 index 0aacd527bc73..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_interpreter_defs.ml +++ /dev/null @@ -1,855 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* - - This module provides auxiliary definitions used in the interpreter. - - These are internal private definitions. Do not rely on them outside - the interpreter. - -*) - -open Alpha_context -open Script -open Script_typed_ir -open Script_ir_translator -open Local_gas_counter - -(* - - Computing the cost of Michelson instructions - ============================================ - - The function [cost_of_instr] provides a cost model for Michelson - instructions. It is used by the interpreter to track the - consumption of gas. This consumption may depend on the values - on the stack. - - *) - -module Interp_costs = Michelson_v1_gas.Cost_of.Interpreter - -let cost_of_instr : type a s r f. (a, s, r, f) kinstr -> a -> s -> Gas.cost = - fun i accu stack -> - match i with - | IList_map _ -> - let list = accu in - Interp_costs.list_map list - | IList_iter _ -> - let list = accu in - Interp_costs.list_iter list - | ISet_iter _ -> - let set = accu in - Interp_costs.set_iter set - | ISet_mem _ -> - let v = accu and (set, _) = stack in - Interp_costs.set_mem v set - | ISet_update _ -> - let v = accu and (_, (set, _)) = stack in - Interp_costs.set_update v set - | IMap_map _ -> - let map = accu in - Interp_costs.map_map map - | IMap_iter _ -> - let map = accu in - Interp_costs.map_iter map - | IMap_mem _ -> - let v = accu and (map, _) = stack in - Interp_costs.map_mem v map - | IMap_get _ -> - let v = accu and (map, _) = stack in - Interp_costs.map_get v map - | IMap_update _ -> - let k = accu and (_, (map, _)) = stack in - Interp_costs.map_update k map - | IMap_get_and_update _ -> - let k = accu and (_, (map, _)) = stack in - Interp_costs.map_get_and_update k map - | IBig_map_mem _ -> - let (map, _) = stack in - Interp_costs.big_map_mem map.diff - | IBig_map_get _ -> - let (map, _) = stack in - Interp_costs.big_map_get map.diff - | IBig_map_update _ -> - let (_, (map, _)) = stack in - Interp_costs.big_map_update map.diff - | IBig_map_get_and_update _ -> - let (_, (map, _)) = stack in - Interp_costs.big_map_get_and_update map.diff - | IAdd_seconds_to_timestamp _ -> - let n = accu and (t, _) = stack in - Interp_costs.add_seconds_timestamp n t - | IAdd_timestamp_to_seconds _ -> - let t = accu and (n, _) = stack in - Interp_costs.add_timestamp_seconds t n - | ISub_timestamp_seconds _ -> - let t = accu and (n, _) = stack in - Interp_costs.sub_timestamp_seconds t n - | IDiff_timestamps _ -> - let t1 = accu and (t2, _) = stack in - Interp_costs.diff_timestamps t1 t2 - | IConcat_string_pair _ -> - let x = accu and (y, _) = stack in - Interp_costs.concat_string_pair x y - | IConcat_string _ -> - let ss = accu in - Interp_costs.concat_string_precheck ss - | ISlice_string _ -> - let _offset = accu in - let (_length, (s, _)) = stack in - Interp_costs.slice_string s - | IConcat_bytes_pair _ -> - let x = accu and (y, _) = stack in - Interp_costs.concat_bytes_pair x y - | IConcat_bytes _ -> - let ss = accu in - Interp_costs.concat_string_precheck ss - | ISlice_bytes _ -> - let (_, (s, _)) = stack in - Interp_costs.slice_bytes s - | IMul_teznat _ -> Interp_costs.mul_teznat - | IMul_nattez _ -> Interp_costs.mul_nattez - | IAbs_int _ -> - let x = accu in - Interp_costs.abs_int x - | INeg _ -> - let x = accu in - Interp_costs.neg x - | IAdd_int _ -> - let x = accu and (y, _) = stack in - Interp_costs.add_int x y - | IAdd_nat _ -> - let x = accu and (y, _) = stack in - Interp_costs.add_nat x y - | ISub_int _ -> - let x = accu and (y, _) = stack in - Interp_costs.sub_int x y - | IMul_int _ -> - let x = accu and (y, _) = stack in - Interp_costs.mul_int x y - | IMul_nat _ -> - let x = accu and (y, _) = stack in - Interp_costs.mul_nat x y - | IEdiv_teznat _ -> - let x = accu and (y, _) = stack in - Interp_costs.ediv_teznat x y - | IEdiv_int _ -> - let x = accu and (y, _) = stack in - Interp_costs.ediv_int x y - | IEdiv_nat _ -> - let x = accu and (y, _) = stack in - Interp_costs.ediv_nat x y - | ILsl_nat _ -> - let x = accu in - Interp_costs.lsl_nat x - | ILsr_nat _ -> - let x = accu in - Interp_costs.lsr_nat x - | IOr_nat _ -> - let x = accu and (y, _) = stack in - Interp_costs.or_nat x y - | IAnd_nat _ -> - let x = accu and (y, _) = stack in - Interp_costs.and_nat x y - | IAnd_int_nat _ -> - let x = accu and (y, _) = stack in - Interp_costs.and_int_nat x y - | IXor_nat _ -> - let x = accu and (y, _) = stack in - Interp_costs.xor_nat x y - | INot_int _ -> - let x = accu in - Interp_costs.not_int x - | ICompare (_, ty, _) -> - let a = accu and (b, _) = stack in - Interp_costs.compare ty a b - | ICheck_signature _ -> - let key = accu and (_, (message, _)) = stack in - Interp_costs.check_signature key message - | IHash_key _ -> - let pk = accu in - Interp_costs.hash_key pk - | IBlake2b _ -> - let bytes = accu in - Interp_costs.blake2b bytes - | ISha256 _ -> - let bytes = accu in - Interp_costs.sha256 bytes - | ISha512 _ -> - let bytes = accu in - Interp_costs.sha512 bytes - | IKeccak _ -> - let bytes = accu in - Interp_costs.keccak bytes - | ISha3 _ -> - let bytes = accu in - Interp_costs.sha3 bytes - | IPairing_check_bls12_381 _ -> - let pairs = accu in - Interp_costs.pairing_check_bls12_381 pairs - | ISapling_verify_update _ -> - let tx = accu in - let inputs = List.length tx.inputs in - let outputs = List.length tx.outputs in - Interp_costs.sapling_verify_update ~inputs ~outputs - | ISplit_ticket _ -> - let ticket = accu and ((amount_a, amount_b), _) = stack in - Interp_costs.split_ticket ticket.amount amount_a amount_b - | IJoin_tickets (_, ty, _) -> - let (ticket_a, ticket_b) = accu in - Interp_costs.join_tickets ty ticket_a ticket_b - | IHalt _ -> Interp_costs.halt - | IDrop _ -> Interp_costs.drop - | IDup _ -> Interp_costs.dup - | ISwap _ -> Interp_costs.swap - | IConst _ -> Interp_costs.const - | ICons_some _ -> Interp_costs.cons_some - | ICons_none _ -> Interp_costs.cons_none - | IIf_none _ -> Interp_costs.if_none - | IOpt_map _ -> Interp_costs.opt_map - | ICons_pair _ -> Interp_costs.cons_pair - | IUnpair _ -> Interp_costs.unpair - | ICar _ -> Interp_costs.car - | ICdr _ -> Interp_costs.cdr - | ICons_left _ -> Interp_costs.cons_left - | ICons_right _ -> Interp_costs.cons_right - | IIf_left _ -> Interp_costs.if_left - | ICons_list _ -> Interp_costs.cons_list - | INil _ -> Interp_costs.nil - | IIf_cons _ -> Interp_costs.if_cons - | IList_size _ -> Interp_costs.list_size - | IEmpty_set _ -> Interp_costs.empty_set - | ISet_size _ -> Interp_costs.set_size - | IEmpty_map _ -> Interp_costs.empty_map - | IMap_size _ -> Interp_costs.map_size - | IEmpty_big_map _ -> Interp_costs.empty_big_map - | IString_size _ -> Interp_costs.string_size - | IBytes_size _ -> Interp_costs.bytes_size - | IAdd_tez _ -> Interp_costs.add_tez - | ISub_tez _ -> Interp_costs.sub_tez - | ISub_tez_legacy _ -> Interp_costs.sub_tez_legacy - | IOr _ -> Interp_costs.bool_or - | IAnd _ -> Interp_costs.bool_and - | IXor _ -> Interp_costs.bool_xor - | INot _ -> Interp_costs.bool_not - | IIs_nat _ -> Interp_costs.is_nat - | IInt_nat _ -> Interp_costs.int_nat - | IInt_bls12_381_fr _ -> Interp_costs.int_bls12_381_fr - | IEdiv_tez _ -> Interp_costs.ediv_tez - | IIf _ -> Interp_costs.if_ - | ILoop _ -> Interp_costs.loop - | ILoop_left _ -> Interp_costs.loop_left - | IDip _ -> Interp_costs.dip - | IExec _ -> Interp_costs.exec - | IApply _ -> Interp_costs.apply - | ILambda _ -> Interp_costs.lambda - | IFailwith _ -> Gas.free - | IEq _ -> Interp_costs.eq - | INeq _ -> Interp_costs.neq - | ILt _ -> Interp_costs.lt - | ILe _ -> Interp_costs.le - | IGt _ -> Interp_costs.gt - | IGe _ -> Interp_costs.ge - | IPack _ -> Gas.free - | IUnpack _ -> - let b = accu in - Interp_costs.unpack b - | IAddress _ -> Interp_costs.address - | IContract _ -> Interp_costs.contract - | ITransfer_tokens _ -> Interp_costs.transfer_tokens - | IView _ -> Interp_costs.view - | IImplicit_account _ -> Interp_costs.implicit_account - | ISet_delegate _ -> Interp_costs.set_delegate - | IBalance _ -> Interp_costs.balance - | ILevel _ -> Interp_costs.level - | INow _ -> Interp_costs.now - | ISapling_empty_state _ -> Interp_costs.sapling_empty_state - | ISource _ -> Interp_costs.source - | ISender _ -> Interp_costs.sender - | ISelf _ -> Interp_costs.self - | ISelf_address _ -> Interp_costs.self_address - | IAmount _ -> Interp_costs.amount - | IDig (_, n, _, _) -> Interp_costs.dign n - | IDug (_, n, _, _) -> Interp_costs.dugn n - | IDipn (_, n, _, _, _) -> Interp_costs.dipn n - | IDropn (_, n, _, _) -> Interp_costs.dropn n - | IChainId _ -> Interp_costs.chain_id - | ICreate_contract _ -> Interp_costs.create_contract - | INever _ -> ( match accu with _ -> .) - | IVoting_power _ -> Interp_costs.voting_power - | ITotal_voting_power _ -> Interp_costs.total_voting_power - | IAdd_bls12_381_g1 _ -> Interp_costs.add_bls12_381_g1 - | IAdd_bls12_381_g2 _ -> Interp_costs.add_bls12_381_g2 - | IAdd_bls12_381_fr _ -> Interp_costs.add_bls12_381_fr - | IMul_bls12_381_g1 _ -> Interp_costs.mul_bls12_381_g1 - | IMul_bls12_381_g2 _ -> Interp_costs.mul_bls12_381_g2 - | IMul_bls12_381_fr _ -> Interp_costs.mul_bls12_381_fr - | INeg_bls12_381_g1 _ -> Interp_costs.neg_bls12_381_g1 - | INeg_bls12_381_g2 _ -> Interp_costs.neg_bls12_381_g2 - | INeg_bls12_381_fr _ -> Interp_costs.neg_bls12_381_fr - | IMul_bls12_381_fr_z _ -> - let z = accu in - Interp_costs.mul_bls12_381_fr_z z - | IMul_bls12_381_z_fr _ -> - let (z, _) = stack in - Interp_costs.mul_bls12_381_z_fr z - | IDup_n (_, n, _, _) -> Interp_costs.dupn n - | IComb (_, n, _, _) -> Interp_costs.comb n - | IUncomb (_, n, _, _) -> Interp_costs.uncomb n - | IComb_get (_, n, _, _) -> Interp_costs.comb_get n - | IComb_set (_, n, _, _) -> Interp_costs.comb_set n - | ITicket _ -> Interp_costs.ticket - | IRead_ticket _ -> Interp_costs.read_ticket - | IOpen_chest _ -> - let _chest_key = accu and (chest, (time, _)) = stack in - Interp_costs.open_chest - ~chest - ~time:(Alpha_context.Script_int.to_zint time) - | ILog _ -> Gas.free - [@@ocaml.inline always] - [@@coq_axiom_with_reason "unreachable expression `.` not handled"] - -let cost_of_control : type a s r f. (a, s, r, f) continuation -> Gas.cost = - fun ks -> - match ks with - | KLog _ -> Gas.free - | KNil -> Interp_costs.Control.nil - | KCons (_, _) -> Interp_costs.Control.cons - | KReturn _ -> Interp_costs.Control.return - | KMap_head (_, _) -> Interp_costs.Control.map_head - | KUndip (_, _) -> Interp_costs.Control.undip - | KLoop_in (_, _) -> Interp_costs.Control.loop_in - | KLoop_in_left (_, _) -> Interp_costs.Control.loop_in_left - | KIter (_, _, _) -> Interp_costs.Control.iter - | KList_enter_body (_, xs, _, len, _) -> - Interp_costs.Control.list_enter_body xs len - | KList_exit_body (_, _, _, _, _) -> Interp_costs.Control.list_exit_body - | KMap_enter_body (_, _, _, _) -> Interp_costs.Control.map_enter_body - | KMap_exit_body (_, _, map, key, _) -> - Interp_costs.Control.map_exit_body key map - | KView_exit (_, _) -> Interp_costs.Control.view_exit - -(* - - [step] calls [consume_instr] at the beginning of each execution step. - - [Local_gas_counter.consume] is used in the implementation of - [IConcat_string] and [IConcat_bytes] because in that special cases, the - cost is expressed with respect to a non-constant-time computation on the - inputs. - -*) - -let consume_instr local_gas_counter k accu stack = - let cost = cost_of_instr k accu stack in - update_and_check local_gas_counter cost - [@@ocaml.inline always] - -let consume_control local_gas_counter ks = - let cost = cost_of_control ks in - update_and_check local_gas_counter cost - [@@ocaml.inline always] - -(* - - Auxiliary functions used by the instrumentation - =============================================== - -*) - -let log_entry logger ctxt gas k accu stack = - let kinfo = kinfo_of_kinstr k in - let ctxt = update_context gas ctxt in - logger.log_entry k ctxt kinfo.iloc kinfo.kstack_ty (accu, stack) - -let log_exit logger ctxt gas kinfo_prev k accu stack = - let kinfo = kinfo_of_kinstr k in - let ctxt = update_context gas ctxt in - logger.log_exit k ctxt kinfo_prev.iloc kinfo.kstack_ty (accu, stack) - -let log_control logger ks = logger.log_control ks - -let get_log = function - | None -> Lwt.return (Ok None) - | Some logger -> logger.get_log () - [@@ocaml.inline always] - -(* [log_kinstr logger i] emits an instruction to instrument the - execution of [i] with [logger]. *) -let log_kinstr logger i = ILog (kinfo_of_kinstr i, LogEntry, logger, i) - -(* [log_next_kinstr logger i] instruments the next instruction of [i] - with the [logger]. - - Notice that the instrumentation breaks the sharing of continuations - that is normally enforced between branches of conditionals. This - has a performance cost. Anyway, the instrumentation allocates many - new [ILog] instructions and [KLog] continuations which makes - the execution of instrumented code significantly slower than - non-instrumented code. "Zero-cost logging" means that the normal - non-instrumented execution is not impacted by the ability to - instrument it, not that the logging itself has no cost. - -*) -let log_next_kinstr logger i = - let apply k = - ILog - ( kinfo_of_kinstr k, - LogExit (kinfo_of_kinstr i), - logger, - log_kinstr logger k ) - in - kinstr_rewritek i {apply} - -(* We pass the identity function when no instrumentation is needed. *) -let id x = x [@@inline] - -(* - - Auxiliary functions used by the interpretation loop - =================================================== - -*) - -(* The following function pops n elements from the stack - and push their reintroduction in the continuations stack. *) -let rec kundip : - type a s e z c u d w b t. - (a, s, e, z, c, u, d, w) stack_prefix_preservation_witness -> - c -> - u -> - (d, w, b, t) kinstr -> - a * s * (e, z, b, t) kinstr = - fun w accu stack k -> - match w with - | KPrefix (kinfo, w) -> - let k = IConst (kinfo, accu, k) in - let (accu, stack) = stack in - kundip w accu stack k - | KRest -> (accu, stack, k) - -(* [apply ctxt gas ty v lam] specializes [lam] by fixing its first - formal argument to [v]. The type of [v] is represented by [ty]. *) -let apply ctxt gas capture_ty capture lam = - let (Lam (descr, expr)) = lam in - let (Item_t (full_arg_ty, _, _)) = descr.kbef in - let ctxt = update_context gas ctxt in - unparse_data ctxt Optimized capture_ty capture >>=? fun (const_expr, ctxt) -> - let loc = Micheline.dummy_location in - unparse_ty ~loc ctxt capture_ty >>?= fun (ty_expr, ctxt) -> - match full_arg_ty with - | Pair_t ((capture_ty, _, _), (arg_ty, _, _), _) -> - let arg_stack_ty = Item_t (arg_ty, Bot_t, None) in - let full_descr = - { - kloc = descr.kloc; - kbef = arg_stack_ty; - kaft = descr.kaft; - kinstr = - (let kinfo_const = {iloc = descr.kloc; kstack_ty = arg_stack_ty} in - let kinfo_pair = - { - iloc = descr.kloc; - kstack_ty = Item_t (capture_ty, arg_stack_ty, None); - } - in - IConst (kinfo_const, capture, ICons_pair (kinfo_pair, descr.kinstr))); - } - in - let full_expr = - Micheline.Seq - ( loc, - [ - Prim (loc, I_PUSH, [ty_expr; const_expr], []); - Prim (loc, I_PAIR, [], []); - expr; - ] ) - in - let lam' = Lam (full_descr, full_expr) in - let gas = update_local_gas_counter ctxt in - return (lam', outdated ctxt, gas) - | _ -> assert false - -(* [transfer (ctxt, sc) gas tez tp p destination entrypoint] - creates an operation that transfers an amount of [tez] to - a contract determined by [(destination, entrypoint)] - instantiated with argument [p] of type [tp]. *) -let transfer (ctxt, sc) gas amount tp p destination entrypoint = - let ctxt = update_context gas ctxt in - collect_lazy_storage ctxt tp p >>?= fun (to_duplicate, ctxt) -> - let to_update = no_lazy_storage_id in - extract_lazy_storage_diff - ctxt - Optimized - tp - p - ~to_duplicate - ~to_update - ~temporary:true - >>=? fun (p, lazy_storage_diff, ctxt) -> - unparse_data ctxt Optimized tp p >>=? fun (p, ctxt) -> - Gas.consume ctxt (Script.strip_locations_cost p) >>?= fun ctxt -> - let operation = - Transaction - { - amount; - destination; - entrypoint; - parameters = Script.lazy_expr (Micheline.strip_locations p); - } - in - fresh_internal_nonce ctxt >>?= fun (ctxt, nonce) -> - let iop = {source = sc.self; operation; nonce} in - let res = (Internal_operation iop, lazy_storage_diff) in - let gas = update_local_gas_counter ctxt in - let ctxt = outdated ctxt in - return (res, ctxt, gas) - -(* [create_contract (ctxt, sc) gas storage_ty param_ty code root_name - delegate credit init] creates an origination operation for a - contract represented by [code], with some [root_name], some initial - [credit] (taken to contract being executed), and an initial storage - [init] of type [storage_ty]. The type of the new contract argument - is [param_ty]. *) - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/1688 - Refactor the sharing part of unparse_script and create_contract *) -let create_contract (ctxt, sc) gas storage_type param_type code views root_name - delegate credit init = - let ctxt = update_context gas ctxt in - let loc = Micheline.dummy_location in - unparse_ty ~loc ctxt param_type >>?= fun (unparsed_param_type, ctxt) -> - let unparsed_param_type = - Script_ir_translator.add_field_annot root_name None unparsed_param_type - in - unparse_ty ~loc ctxt storage_type >>?= fun (unparsed_storage_type, ctxt) -> - let open Micheline in - let view name {input_ty; output_ty; view_code} views = - Prim - ( loc, - K_view, - [ - String (loc, Script_string.to_string name); - input_ty; - output_ty; - view_code; - ], - [] ) - :: views - in - let views = SMap.fold view views [] |> List.rev in - let code = - strip_locations - (Seq - ( loc, - [ - Prim (loc, K_parameter, [unparsed_param_type], []); - Prim (loc, K_storage, [unparsed_storage_type], []); - Prim (loc, K_code, [code], []); - ] - @ views )) - in - collect_lazy_storage ctxt storage_type init >>?= fun (to_duplicate, ctxt) -> - let to_update = no_lazy_storage_id in - extract_lazy_storage_diff - ctxt - Optimized - storage_type - init - ~to_duplicate - ~to_update - ~temporary:true - >>=? fun (init, lazy_storage_diff, ctxt) -> - unparse_data ctxt Optimized storage_type init >>=? fun (storage, ctxt) -> - Gas.consume ctxt (Script.strip_locations_cost storage) >>?= fun ctxt -> - let storage = strip_locations storage in - Contract.fresh_contract_from_current_nonce ctxt >>?= fun (ctxt, contract) -> - let operation = - Origination - { - credit; - delegate; - preorigination = Some contract; - script = - {code = Script.lazy_expr code; storage = Script.lazy_expr storage}; - } - in - fresh_internal_nonce ctxt >>?= fun (ctxt, nonce) -> - let res = - (Internal_operation {source = sc.self; operation; nonce}, lazy_storage_diff) - in - let gas = update_local_gas_counter ctxt in - let ctxt = outdated ctxt in - return (res, contract, ctxt, gas) - -(* [unpack ctxt ty bytes] deserialize [bytes] into a value of type [ty]. *) -let unpack ctxt ~ty ~bytes = - Gas.consume - ctxt - (Script.deserialization_cost_estimated_from_bytes (Bytes.length bytes)) - >>?= fun ctxt -> - if - Compare.Int.(Bytes.length bytes >= 1) - && Compare.Int.(TzEndian.get_uint8 bytes 0 = 0x05) - then - let str = Bytes.sub_string bytes 1 (Bytes.length bytes - 1) in - match Data_encoding.Binary.of_string_opt Script.expr_encoding str with - | None -> - Lwt.return - ( Gas.consume ctxt (Interp_costs.unpack_failed str) >|? fun ctxt -> - (None, ctxt) ) - | Some expr -> ( - parse_data - ctxt - ~legacy:false - ~allow_forged:false - ty - (Micheline.root expr) - >|= function - | Ok (value, ctxt) -> ok (Some value, ctxt) - | Error _ignored -> - Gas.consume ctxt (Interp_costs.unpack_failed str) >|? fun ctxt -> - (None, ctxt)) - else return (None, ctxt) - -(* [interp_stack_prefix_preserving_operation f w accu stack] applies - a well-typed operation [f] under some prefix of the A-stack - exploiting [w] to justify that the shape of the stack is - preserved. *) -let rec interp_stack_prefix_preserving_operation : - type a s b t c u d w result. - (a -> s -> (b * t) * result) -> - (a, s, b, t, c, u, d, w) stack_prefix_preservation_witness -> - c -> - u -> - (d * w) * result = - fun f n accu stk -> - match (n, stk) with - | (KPrefix (_, n), rest) -> - interp_stack_prefix_preserving_operation f n (fst rest) (snd rest) - |> fun ((v, rest'), result) -> ((accu, (v, rest')), result) - | (KRest, v) -> f accu v - -(* - - Some auxiliary functions have complex types and must be annotated - because of GADTs and polymorphic recursion. - - To improve readibility, we introduce their types as abbreviations: - -*) - -type ('a, 's, 'b, 't, 'r, 'f) step_type = - outdated_context * step_constants -> - local_gas_counter -> - ('a, 's, 'b, 't) kinstr -> - ('b, 't, 'r, 'f) continuation -> - 'a -> - 's -> - ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'm, 'n, 'o) kmap_exit_type = - (('c, 'd, 'e, 'f) continuation -> ('a, 'b, 'g, 'h) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('m * 'n, 'c * 'd, 'o, 'c * 'd) kinstr * ('m * 'n) list * ('m, 'o) map * 'm -> - (('m, 'o) map, 'c * 'd, 'e, 'f) continuation -> - 'o -> - 'a * 'b -> - ('g * 'h * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'j, 'k) kmap_enter_type = - (('a, 'b * 'c, 'd, 'e) continuation -> ('a, 'b * 'c, 'd, 'e) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('j * 'k, 'b * 'c, 'a, 'b * 'c) kinstr * ('j * 'k) list * ('j, 'a) map -> - (('j, 'a) map, 'b * 'c, 'd, 'e) continuation -> - 'b -> - 'c -> - ('d * 'e * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'i, 'j) klist_exit_type = - (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('i, 'a * 'b, 'j, 'a * 'b) kinstr * 'i list * 'j list * local_gas_counter -> - ('j boxed_list, 'a * 'b, 'c, 'd) continuation -> - 'j -> - 'a * 'b -> - ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'j) klist_enter_type = - (('b, 'a * 'c, 'd, 'e) continuation -> ('b, 'a * 'c, 'd, 'e) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('j, 'a * 'c, 'b, 'a * 'c) kinstr * 'j list * 'b list * local_gas_counter -> - ('b boxed_list, 'a * 'c, 'd, 'e) continuation -> - 'a -> - 'c -> - ('d * 'e * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f, 'g) kloop_in_left_type = - outdated_context * step_constants -> - local_gas_counter -> - ('c, 'd, 'e, 'f) continuation -> - ('a, 'g, 'c, 'd) kinstr -> - ('b, 'g, 'e, 'f) continuation -> - ('a, 'b) union -> - 'g -> - ('e * 'f * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'r, 'f, 's) kloop_in_type = - outdated_context * step_constants -> - local_gas_counter -> - ('b, 'c, 'r, 'f) continuation -> - ('a, 's, 'b, 'c) kinstr -> - ('a, 's, 'r, 'f) continuation -> - bool -> - 'a * 's -> - ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 's, 'r, 'f) kiter_type = - (('a, 's, 'r, 'f) continuation -> ('a, 's, 'r, 'f) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('b, 'a * 's, 'a, 's) kinstr * 'b list -> - ('a, 's, 'r, 'f) continuation -> - 'a -> - 's -> - ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h) ilist_map_type = - (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('e, 'a * 'b, 'f, 'a * 'b) kinstr * ('f boxed_list, 'a * 'b, 'g, 'h) kinstr -> - ('g, 'h, 'c, 'd) continuation -> - 'e boxed_list -> - 'a * 'b -> - ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f, 'g) ilist_iter_type = - (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('e, 'a * 'b, 'a, 'b) kinstr * ('a, 'b, 'f, 'g) kinstr -> - ('f, 'g, 'c, 'd) continuation -> - 'e boxed_list -> - 'a * 'b -> - ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f, 'g) iset_iter_type = - (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('e, 'a * 'b, 'a, 'b) kinstr * ('a, 'b, 'f, 'g) kinstr -> - ('f, 'g, 'c, 'd) continuation -> - 'e set -> - 'a * 'b -> - ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i) imap_map_type = - (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('e * 'f, 'a * 'b, 'g, 'a * 'b) kinstr - * (('e, 'g) map, 'a * 'b, 'h, 'i) kinstr -> - ('h, 'i, 'c, 'd) continuation -> - ('e, 'f) map -> - 'a * 'b -> - ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h) imap_iter_type = - (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> - outdated_context * step_constants -> - local_gas_counter -> - ('e * 'f, 'a * 'b, 'a, 'b) kinstr * ('a, 'b, 'g, 'h) kinstr -> - ('g, 'h, 'c, 'd) continuation -> - ('e, 'f) map -> - 'a * 'b -> - ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f) imul_teznat_type = - logger option -> - outdated_context * step_constants -> - local_gas_counter -> - (Tez.t, 'a) kinfo * (Tez.t, 'b, 'c, 'd) kinstr -> - ('c, 'd, 'e, 'f) continuation -> - Tez.t -> - Script_int.n Script_int.num * 'b -> - ('e * 'f * outdated_context * local_gas_counter, error trace) result Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f) imul_nattez_type = - logger option -> - outdated_context * step_constants -> - local_gas_counter -> - (Script_int.n Script_int.num, 'a) kinfo * (Tez.t, 'b, 'c, 'd) kinstr -> - ('c, 'd, 'e, 'f) continuation -> - Script_int.n Script_int.num -> - Tez.t * 'b -> - ('e * 'f * outdated_context * local_gas_counter, error trace) result Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f) ilsl_nat_type = - logger option -> - outdated_context * step_constants -> - local_gas_counter -> - (Script_int.n Script_int.num, 'a) kinfo - * (Script_int.n Script_int.num, 'b, 'c, 'd) kinstr -> - ('c, 'd, 'e, 'f) continuation -> - Script_int.n Script_int.num -> - Script_int.n Script_int.num * 'b -> - ('e * 'f * outdated_context * local_gas_counter, error trace) result Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f) ilsr_nat_type = - logger option -> - outdated_context * step_constants -> - local_gas_counter -> - (Script_int.n Script_int.num, 'a) kinfo - * (Script_int.n Script_int.num, 'b, 'c, 'd) kinstr -> - ('c, 'd, 'e, 'f) continuation -> - Script_int.n Script_int.num -> - Script_int.n Script_int.num * 'b -> - ('e * 'f * outdated_context * local_gas_counter, error trace) result Lwt.t - -type ('a, 'b) ifailwith_type = - logger option -> - outdated_context * step_constants -> - local_gas_counter -> - Script.location -> - 'a ty -> - 'a -> - ('b, error trace) result Lwt.t - -type ('a, 'b, 'c, 'd, 'e, 'f, 'g) iexec_type = - logger option -> - outdated_context * step_constants -> - local_gas_counter -> - ('a, 'b, 'c, 'd) kinstr -> - ('c, 'd, 'e, 'f) continuation -> - 'g -> - ('g, 'a) lambda * 'b -> - ('e * 'f * outdated_context * local_gas_counter) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/script_ir_annot.ml b/src/proto_012_Psithaca/lib_protocol/script_ir_annot.ml deleted file mode 100644 index 90ac3451266a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_ir_annot.ml +++ /dev/null @@ -1,528 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Micheline -open Script_tc_errors - -type var_annot = Var_annot of Non_empty_string.t [@@ocaml.unboxed] - -type type_annot = Type_annot of Non_empty_string.t [@@ocaml.unboxed] - -type field_annot = Field_annot of Non_empty_string.t [@@ocaml.unboxed] - -module FOR_TESTS = struct - let unsafe_var_annot_of_string s = - Var_annot (Non_empty_string.of_string_exn s) - - let unsafe_type_annot_of_string s = - Type_annot (Non_empty_string.of_string_exn s) - - let unsafe_field_annot_of_string s = - Field_annot (Non_empty_string.of_string_exn s) -end - -let some_var_annot_of_string_exn s = - Some (Var_annot (Non_empty_string.of_string_exn s)) - -let some_field_annot_of_string_exn s = - Some (Field_annot (Non_empty_string.of_string_exn s)) - -let default_now_annot = some_var_annot_of_string_exn "now" - -let default_amount_annot = some_var_annot_of_string_exn "amount" - -let default_balance_annot = some_var_annot_of_string_exn "balance" - -let default_level_annot = some_var_annot_of_string_exn "level" - -let default_source_annot = some_var_annot_of_string_exn "source" - -let default_sender_annot = some_var_annot_of_string_exn "sender" - -let default_self_annot = some_var_annot_of_string_exn "self" - -let default_arg_annot = some_var_annot_of_string_exn "arg" - -let lambda_arg_annot = some_var_annot_of_string_exn "@arg" - -let default_param_annot = some_var_annot_of_string_exn "parameter" - -let default_storage_annot = some_var_annot_of_string_exn "storage" - -let default_car_annot = some_field_annot_of_string_exn "car" - -let default_cdr_annot = some_field_annot_of_string_exn "cdr" - -let default_contract_annot = some_field_annot_of_string_exn "contract" - -let default_addr_annot = some_field_annot_of_string_exn "address" - -let default_pack_annot = some_field_annot_of_string_exn "packed" - -let default_unpack_annot = some_field_annot_of_string_exn "unpacked" - -let default_slice_annot = some_field_annot_of_string_exn "slice" - -let default_elt_annot = some_field_annot_of_string_exn "elt" - -let default_key_annot = some_field_annot_of_string_exn "key" - -let default_hd_annot = some_field_annot_of_string_exn "hd" - -let default_tl_annot = some_field_annot_of_string_exn "tl" - -let default_some_annot = some_field_annot_of_string_exn "some" - -let default_left_annot = some_field_annot_of_string_exn "left" - -let default_right_annot = some_field_annot_of_string_exn "right" - -let default_sapling_state_annot = some_var_annot_of_string_exn "sapling" - -let default_sapling_balance_annot = - some_var_annot_of_string_exn "sapling_balance" - -let unparse_type_annot : type_annot option -> string list = function - | None -> [] - | Some (Type_annot a) -> [":" ^ (a :> string)] - -let unparse_var_annot : var_annot option -> string list = function - | None -> [] - | Some (Var_annot a) -> ["@" ^ (a :> string)] - -let unparse_field_annot : field_annot option -> string list = function - | None -> [] - | Some (Field_annot a) -> ["%" ^ (a :> string)] - -let field_to_var_annot : field_annot option -> var_annot option = function - | None -> None - | Some (Field_annot s) -> Some (Var_annot s) - -let type_to_var_annot : type_annot option -> var_annot option = function - | None -> None - | Some (Type_annot s) -> Some (Var_annot s) - -let var_to_field_annot : var_annot option -> field_annot option = function - | None -> None - | Some (Var_annot s) -> Some (Field_annot s) - -let default_annot ~default = function None -> default | annot -> annot - -let gen_access_annot : - var_annot option -> - ?default:field_annot option -> - field_annot option -> - var_annot option = - fun value_annot ?(default = None) field_annot -> - match (value_annot, field_annot, default) with - | (None, None, _) | (Some _, None, None) -> None - | (None, Some (Field_annot f), _) -> Some (Var_annot f) - | (Some (Var_annot v), None, Some (Field_annot f)) -> - Some (Var_annot (Non_empty_string.cat2 v ~sep:"." f)) - | (Some (Var_annot v), Some (Field_annot f), _) -> - Some (Var_annot (Non_empty_string.cat2 v ~sep:"." f)) - -let merge_type_annot : - legacy:bool -> - type_annot option -> - type_annot option -> - type_annot option tzresult = - fun ~legacy annot1 annot2 -> - match (annot1, annot2) with - | (None, None) | (Some _, None) | (None, Some _) -> Result.return_none - | (Some (Type_annot a1), Some (Type_annot a2)) -> - if legacy || Non_empty_string.(a1 = a2) then ok annot1 - else - error - (Inconsistent_annotations (":" ^ (a1 :> string), ":" ^ (a2 :> string))) - -let merge_field_annot : - legacy:bool -> - field_annot option -> - field_annot option -> - field_annot option tzresult = - fun ~legacy annot1 annot2 -> - match (annot1, annot2) with - | (None, None) | (Some _, None) | (None, Some _) -> Result.return_none - | (Some (Field_annot a1), Some (Field_annot a2)) -> - if legacy || Non_empty_string.(a1 = a2) then ok annot1 - else - error - (Inconsistent_annotations ("%" ^ (a1 :> string), "%" ^ (a2 :> string))) - -let merge_var_annot : var_annot option -> var_annot option -> var_annot option = - fun annot1 annot2 -> - match (annot1, annot2) with - | (None, None) | (Some _, None) | (None, Some _) -> None - | (Some (Var_annot a1), Some (Var_annot a2)) -> - if Non_empty_string.(a1 = a2) then annot1 else None - -let error_unexpected_annot loc annot = - match annot with - | [] -> Result.return_unit - | _ :: _ -> error (Unexpected_annotation loc) - -(* Check that the predicate p holds on all s.[k] for k >= i *) -let string_iter p s i = - let len = String.length s in - let rec aux i = - if Compare.Int.(i >= len) then Result.return_unit - else p s.[i] >>? fun () -> aux (i + 1) - in - aux i - -let is_allowed_char = function - | 'a' .. 'z' | 'A' .. 'Z' | '_' | '.' | '%' | '@' | '0' .. '9' -> true - | _ -> false - -(* Valid annotation characters as defined by the allowed_annot_char function from lib_micheline/micheline_parser *) -let check_char loc c = - if is_allowed_char c then Result.return_unit - else error (Unexpected_annotation loc) - -(* This constant is defined in lib_micheline/micheline_parser which is not available in the environment. *) -let max_annot_length = 255 - -type annot_opt = - | Field_annot_opt of Non_empty_string.t option - | Type_annot_opt of Non_empty_string.t option - | Var_annot_opt of Non_empty_string.t option - -let percent = Non_empty_string.of_string_exn "%" - -let percent_percent = Non_empty_string.of_string_exn "%%" - -let at = Non_empty_string.of_string_exn "@" - -let parse_annots loc ?(allow_special_var = false) ?(allow_special_field = false) - l = - (* allow empty annotations as wildcards but otherwise only accept - annotations that start with [a-zA-Z_] *) - let sub_or_wildcard wrap s = - match Non_empty_string.of_string s with - | None -> ok @@ wrap None - | Some s -> ( - match (s :> string).[0] with - | 'a' .. 'z' | 'A' .. 'Z' | '_' | '0' .. '9' -> - (* check that all characters are valid*) - string_iter (check_char loc) (s :> string) 1 >>? fun () -> - ok @@ wrap (Some s) - | _ -> error (Unexpected_annotation loc)) - in - List.map_e - (function - | "@%" when allow_special_var -> ok @@ Var_annot_opt (Some percent) - | "@%%" when allow_special_var -> - ok @@ Var_annot_opt (Some percent_percent) - | "%@" when allow_special_field -> ok @@ Field_annot_opt (Some at) - | s -> ( - let len = String.length s in - if Compare.Int.(len = 0 || len > max_annot_length) then - error (Unexpected_annotation loc) - else - let rest = String.sub s 1 (len - 1) in - match s.[0] with - | ':' -> sub_or_wildcard (fun a -> Type_annot_opt a) rest - | '@' -> sub_or_wildcard (fun a -> Var_annot_opt a) rest - | '%' -> sub_or_wildcard (fun a -> Field_annot_opt a) rest - | _ -> error (Unexpected_annotation loc))) - l - -let opt_var_of_var_opt = function None -> None | Some a -> Some (Var_annot a) - -let opt_field_of_field_opt = function - | None -> None - | Some a -> Some (Field_annot a) - -let opt_type_of_type_opt = function - | None -> None - | Some a -> Some (Type_annot a) - -let classify_annot loc l : - (var_annot option list * type_annot option list * field_annot option list) - tzresult = - try - let (_, rv, _, rt, _, rf) = - List.fold_left - (fun (in_v, rv, in_t, rt, in_f, rf) a -> - match (a, in_v, rv, in_t, rt, in_f, rf) with - | (Var_annot_opt a, true, _, _, _, _, _) - | (Var_annot_opt a, false, [], _, _, _, _) -> - (true, opt_var_of_var_opt a :: rv, false, rt, false, rf) - | (Type_annot_opt a, _, _, true, _, _, _) - | (Type_annot_opt a, _, _, false, [], _, _) -> - (false, rv, true, opt_type_of_type_opt a :: rt, false, rf) - | (Field_annot_opt a, _, _, _, _, true, _) - | (Field_annot_opt a, _, _, _, _, false, []) -> - (false, rv, false, rt, true, opt_field_of_field_opt a :: rf) - | _ -> raise Exit) - (false, [], false, [], false, []) - l - in - ok (List.rev rv, List.rev rt, List.rev rf) - with Exit -> error (Ungrouped_annotations loc) - -let get_one_annot loc = function - | [] -> Result.return_none - | [a] -> ok a - | _ -> error (Unexpected_annotation loc) - -let get_two_annot loc = function - | [] -> ok (None, None) - | [a] -> ok (a, None) - | [a; b] -> ok (a, b) - | _ -> error (Unexpected_annotation loc) - -let parse_type_annot : - Script.location -> string list -> type_annot option tzresult = - fun loc annot -> - parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> - error_unexpected_annot loc vars >>? fun () -> - error_unexpected_annot loc fields >>? fun () -> get_one_annot loc types - -let parse_composed_type_annot : - Script.location -> - string list -> - (type_annot option * field_annot option * field_annot option) tzresult = - fun loc annot -> - parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> - error_unexpected_annot loc vars >>? fun () -> - get_one_annot loc types >>? fun t -> - get_two_annot loc fields >|? fun (f1, f2) -> (t, f1, f2) - -let parse_field_annot : - Script.location -> string list -> field_annot option tzresult = - fun loc annot -> - parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> - error_unexpected_annot loc vars >>? fun () -> - error_unexpected_annot loc types >>? fun () -> get_one_annot loc fields - -let extract_field_annot : - Script.node -> (Script.node * field_annot option) tzresult = function - | Prim (loc, prim, args, annot) -> - let rec extract_first acc = function - | [] -> (None, annot) - | s :: rest -> - if Compare.Int.(String.length s > 0) && Compare.Char.(s.[0] = '%') - then (Some s, List.rev_append acc rest) - else extract_first (s :: acc) rest - in - let (field_annot, annot) = extract_first [] annot in - (match field_annot with - | None -> Result.return_none - | Some field_annot -> parse_field_annot loc [field_annot]) - >|? fun field_annot -> (Prim (loc, prim, args, annot), field_annot) - | expr -> ok (expr, None) - -let check_correct_field : - field_annot option -> field_annot option -> unit tzresult = - fun f1 f2 -> - match (f1, f2) with - | (None, _) | (_, None) -> Result.return_unit - | (Some (Field_annot s1), Some (Field_annot s2)) -> - if Non_empty_string.(s1 = s2) then Result.return_unit - else - error - (Inconsistent_field_annotations - ("%" ^ (s1 :> string), "%" ^ (s2 :> string))) - -let parse_var_annot : - Script.location -> - ?default:var_annot option -> - string list -> - var_annot option tzresult = - fun loc ?default annot -> - parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> - error_unexpected_annot loc types >>? fun () -> - error_unexpected_annot loc fields >>? fun () -> - get_one_annot loc vars >|? function - | Some _ as a -> a - | None -> ( match default with Some a -> a | None -> None) - -let split_last_dot = function - | None -> (None, None) - | Some (Field_annot s) -> ( - match Non_empty_string.split_on_last '.' s with - | Some (s1, s2) -> - let f = - match (s2 :> string) with - | "car" | "cdr" -> None - | _ -> Some (Field_annot s2) - in - (Some (Var_annot s1), f) - | None -> (None, Some (Field_annot s))) - -let split_if_special ~loc ~if_special v f = - match f with - | Some (Field_annot fa) when Non_empty_string.(fa = at) -> ( - match if_special with - | Some special_var -> ok @@ split_last_dot special_var - | None -> error (Unexpected_annotation loc)) - | _ -> ok (v, f) - -let common_prefix v1 v2 = - match (v1, v2) with - | (Some (Var_annot s1), Some (Var_annot s2)) when Non_empty_string.(s1 = s2) - -> - v1 - | (Some _, None) -> v1 - | (None, Some _) -> v2 - | (_, _) -> None - -let parse_constr_annot : - Script.location -> - ?if_special_first:field_annot option -> - ?if_special_second:field_annot option -> - string list -> - (var_annot option - * type_annot option - * field_annot option - * field_annot option) - tzresult = - fun loc ?if_special_first ?if_special_second annot -> - parse_annots ~allow_special_field:true loc annot >>? classify_annot loc - >>? fun (vars, types, fields) -> - get_one_annot loc vars >>? fun v -> - get_one_annot loc types >>? fun t -> - get_two_annot loc fields >>? fun (f1, f2) -> - split_if_special ~loc ~if_special:if_special_first v f1 >>? fun (v1, f1) -> - split_if_special ~loc ~if_special:if_special_second v f2 >|? fun (v2, f2) -> - let v = match v with None -> common_prefix v1 v2 | Some _ -> v in - (v, t, f1, f2) - -let parse_two_var_annot : - Script.location -> - string list -> - (var_annot option * var_annot option) tzresult = - fun loc annot -> - parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> - error_unexpected_annot loc types >>? fun () -> - error_unexpected_annot loc fields >>? fun () -> get_two_annot loc vars - -let var_annot_from_special : - field_name:field_annot option -> - default:var_annot option -> - value_annot:var_annot option -> - var_annot option -> - var_annot option = - fun ~field_name ~default ~value_annot v -> - match v with - | Some (Var_annot va) -> ( - match (va :> string) with - | "%" -> field_to_var_annot field_name - | "%%" -> default - | _ -> v) - | None -> value_annot - -let parse_destr_annot : - Script.location -> - string list -> - default_accessor:field_annot option -> - field_name:field_annot option -> - pair_annot:var_annot option -> - value_annot:var_annot option -> - (var_annot option * field_annot option) tzresult = - fun loc annot ~default_accessor ~field_name ~pair_annot ~value_annot -> - parse_annots loc ~allow_special_var:true annot >>? classify_annot loc - >>? fun (vars, types, fields) -> - error_unexpected_annot loc types >>? fun () -> - get_one_annot loc vars >>? fun v -> - get_one_annot loc fields >|? fun f -> - let default = - gen_access_annot pair_annot field_name ~default:default_accessor - in - let v = var_annot_from_special ~field_name ~default ~value_annot v in - (v, f) - -let parse_unpair_annot : - Script.location -> - string list -> - field_name_car:field_annot option -> - field_name_cdr:field_annot option -> - pair_annot:var_annot option -> - value_annot_car:var_annot option -> - value_annot_cdr:var_annot option -> - (var_annot option - * var_annot option - * field_annot option - * field_annot option) - tzresult = - fun loc - annot - ~field_name_car - ~field_name_cdr - ~pair_annot - ~value_annot_car - ~value_annot_cdr -> - parse_annots loc ~allow_special_var:true annot >>? classify_annot loc - >>? fun (vars, types, fields) -> - error_unexpected_annot loc types >>? fun () -> - get_two_annot loc vars >>? fun (vcar, vcdr) -> - get_two_annot loc fields >|? fun (fcar, fcdr) -> - let default_car = - gen_access_annot pair_annot field_name_car ~default:default_car_annot - in - let default_cdr = - gen_access_annot pair_annot field_name_cdr ~default:default_cdr_annot - in - let vcar = - var_annot_from_special - ~field_name:field_name_car - ~default:default_car - ~value_annot:value_annot_car - vcar - in - let vcdr = - var_annot_from_special - ~field_name:field_name_cdr - ~default:default_cdr - ~value_annot:value_annot_cdr - vcdr - in - (vcar, vcdr, fcar, fcdr) - -let parse_entrypoint_annot : - Script.location -> - ?default:var_annot option -> - string list -> - (var_annot option * field_annot option) tzresult = - fun loc ?default annot -> - parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> - error_unexpected_annot loc types >>? fun () -> - get_one_annot loc fields >>? fun f -> - get_one_annot loc vars >|? function - | Some _ as a -> (a, f) - | None -> ( match default with Some a -> (a, f) | None -> (None, f)) - -let parse_var_type_annot : - Script.location -> - string list -> - (var_annot option * type_annot option) tzresult = - fun loc annot -> - parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> - error_unexpected_annot loc fields >>? fun () -> - get_one_annot loc vars >>? fun v -> - get_one_annot loc types >|? fun t -> (v, t) diff --git a/src/proto_012_Psithaca/lib_protocol/script_ir_annot.mli b/src/proto_012_Psithaca/lib_protocol/script_ir_annot.mli deleted file mode 100644 index 47fab3b005b2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_ir_annot.mli +++ /dev/null @@ -1,230 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -type var_annot = private Var_annot of Non_empty_string.t [@@ocaml.unboxed] - -type type_annot = private Type_annot of Non_empty_string.t [@@ocaml.unboxed] - -type field_annot = private Field_annot of Non_empty_string.t [@@ocaml.unboxed] - -module FOR_TESTS : sig - val unsafe_var_annot_of_string : string -> var_annot - - val unsafe_type_annot_of_string : string -> type_annot - - val unsafe_field_annot_of_string : string -> field_annot -end - -(** Default annotations *) - -val default_now_annot : var_annot option - -val default_amount_annot : var_annot option - -val default_balance_annot : var_annot option - -val default_level_annot : var_annot option - -val default_source_annot : var_annot option - -val default_sender_annot : var_annot option - -val default_self_annot : var_annot option - -val default_arg_annot : var_annot option - -val lambda_arg_annot : var_annot option - -val default_param_annot : var_annot option - -val default_storage_annot : var_annot option - -val default_sapling_state_annot : var_annot option - -val default_sapling_balance_annot : var_annot option - -val default_car_annot : field_annot option - -val default_cdr_annot : field_annot option - -val default_contract_annot : field_annot option - -val default_addr_annot : field_annot option - -val default_pack_annot : field_annot option - -val default_unpack_annot : field_annot option - -val default_slice_annot : field_annot option - -val default_elt_annot : field_annot option - -val default_key_annot : field_annot option - -val default_hd_annot : field_annot option - -val default_tl_annot : field_annot option - -val default_some_annot : field_annot option - -val default_left_annot : field_annot option - -val default_right_annot : field_annot option - -(** Unparse annotations to their string representation *) - -val unparse_type_annot : type_annot option -> string list - -val unparse_var_annot : var_annot option -> string list - -val unparse_field_annot : field_annot option -> string list - -(** Conversion functions between different annotation kinds *) - -val field_to_var_annot : field_annot option -> var_annot option - -val type_to_var_annot : type_annot option -> var_annot option - -val var_to_field_annot : var_annot option -> field_annot option - -(** Replace an annotation by its default value if it is [None] *) -val default_annot : default:'a option -> 'a option -> 'a option - -(** Generate annotation for field accesses, of the form [var.field1.field2] *) -val gen_access_annot : - var_annot option -> - ?default:field_annot option -> - field_annot option -> - var_annot option - -(** Merge type annotations. - @return an error {!Inconsistent_type_annotations} if they are both present - and different, unless [legacy] *) -val merge_type_annot : - legacy:bool -> - type_annot option -> - type_annot option -> - type_annot option tzresult - -(** Merge field annotations. - @return an error {!Inconsistent_type_annotations} if they are both present - and different, unless [legacy] *) -val merge_field_annot : - legacy:bool -> - field_annot option -> - field_annot option -> - field_annot option tzresult - -(** Merge variable annotations, does not fail ([None] if different). *) -val merge_var_annot : var_annot option -> var_annot option -> var_annot option - -(** @return an error {!Unexpected_annotation} in the monad the list is not empty. *) -val error_unexpected_annot : Script.location -> 'a list -> unit tzresult - -(** Parse a type annotation only. *) -val parse_type_annot : - Script.location -> string list -> type_annot option tzresult - -(** Parse a field annotation only. *) -val parse_field_annot : - Script.location -> string list -> field_annot option tzresult - -(** Parse an annotation for composed types, of the form - [:ty_name %field1 %field2] in any order. *) -val parse_composed_type_annot : - Script.location -> - string list -> - (type_annot option * field_annot option * field_annot option) tzresult - -(** Extract and remove a field annotation from a node *) -val extract_field_annot : - Script.node -> (Script.node * field_annot option) tzresult - -(** Check that field annotations match, used for field accesses. *) -val check_correct_field : - field_annot option -> field_annot option -> unit tzresult - -(** Instruction annotations parsing *) - -(** Parse a variable annotation, replaced by a default value if [None]. *) -val parse_var_annot : - Script.location -> - ?default:var_annot option -> - string list -> - var_annot option tzresult - -val is_allowed_char : char -> bool - -val parse_constr_annot : - Script.location -> - ?if_special_first:field_annot option -> - ?if_special_second:field_annot option -> - string list -> - (var_annot option - * type_annot option - * field_annot option - * field_annot option) - tzresult - -val parse_two_var_annot : - Script.location -> - string list -> - (var_annot option * var_annot option) tzresult - -val parse_destr_annot : - Script.location -> - string list -> - default_accessor:field_annot option -> - field_name:field_annot option -> - pair_annot:var_annot option -> - value_annot:var_annot option -> - (var_annot option * field_annot option) tzresult - -val parse_unpair_annot : - Script.location -> - string list -> - field_name_car:field_annot option -> - field_name_cdr:field_annot option -> - pair_annot:var_annot option -> - value_annot_car:var_annot option -> - value_annot_cdr:var_annot option -> - (var_annot option - * var_annot option - * field_annot option - * field_annot option) - tzresult - -val parse_entrypoint_annot : - Script.location -> - ?default:var_annot option -> - string list -> - (var_annot option * field_annot option) tzresult - -val parse_var_type_annot : - Script.location -> - string list -> - (var_annot option * type_annot option) tzresult diff --git a/src/proto_012_Psithaca/lib_protocol/script_ir_translator.ml b/src/proto_012_Psithaca/lib_protocol/script_ir_translator.ml deleted file mode 100644 index ceb7553e3dc0..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_ir_translator.ml +++ /dev/null @@ -1,6787 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Micheline -open Script -open Script_tc_errors -open Script_ir_annot -open Script_typed_ir -module Typecheck_costs = Michelson_v1_gas.Cost_of.Typechecking -module Unparse_costs = Michelson_v1_gas.Cost_of.Unparsing - -type ex_stack_ty = Ex_stack_ty : ('a, 's) stack_ty -> ex_stack_ty - -(* - - The following type represents an instruction parameterized by its - continuation. During the elaboration of the typed term, a sequence - of instructions in Micheline is read from left to right: hence, the - elaboration needs to wait for the next instruction to be elaborated - to be able to construct the current instruction. - -*) -type ('a, 's, 'b, 'u) cinstr = { - apply : - 'r 'f. ('a, 's) kinfo -> ('b, 'u, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr; -} - -(* - - While a [Script_typed_ir.descr] contains a fully defined - instruction, [descr] contains a [cinstr], that is an instruction - parameterized by the next instruction, as explained in the previous - comment. - -*) -type ('a, 's, 'b, 'u) descr = { - loc : Script.location; - bef : ('a, 's) stack_ty; - aft : ('b, 'u) stack_ty; - instr : ('a, 's, 'b, 'u) cinstr; -} - -let close_descr {loc; bef; aft; instr} = - let kinfo = {iloc = loc; kstack_ty = aft} in - let kinfo' = {iloc = loc; kstack_ty = bef} in - let kinstr = instr.apply kinfo' (IHalt kinfo) in - {kloc = loc; kbef = bef; kaft = aft; kinstr} - -let kinfo_of_descr {loc; bef; _} = {iloc = loc; kstack_ty = bef} - -let compose_descr : - type a s b u c v. - Script.location -> - (a, s, b, u) descr -> - (b, u, c, v) descr -> - (a, s, c, v) descr = - fun loc d1 d2 -> - { - loc; - bef = d1.bef; - aft = d2.aft; - instr = - { - apply = - (fun _ k -> - d1.instr.apply - (kinfo_of_descr d1) - (d2.instr.apply (kinfo_of_descr d2) k)); - }; - } - -type tc_context = - | Lambda : tc_context - | Dip : ('a, 's) stack_ty * tc_context -> tc_context - | Toplevel : { - storage_type : 'sto ty; - param_type : 'param ty; - root_name : field_annot option; - } - -> tc_context - -type unparsing_mode = Optimized | Readable | Optimized_legacy - -type type_logger = - Script.location -> - (Script.expr * Script.annot) list -> - (Script.expr * Script.annot) list -> - unit - -let add_dip ty annot prev = - match prev with - | Lambda | Toplevel _ -> - Dip (Item_t (ty, Item_t (unit_t ~annot:None, Bot_t, None), annot), prev) - | Dip (stack, _) -> Dip (Item_t (ty, stack, annot), prev) - -(* ---- Error helpers -------------------------------------------------------*) - -let location = function - | Prim (loc, _, _, _) - | Int (loc, _) - | String (loc, _) - | Bytes (loc, _) - | Seq (loc, _) -> - loc - -let kind_equal a b = - match (a, b) with - | (Int_kind, Int_kind) - | (String_kind, String_kind) - | (Bytes_kind, Bytes_kind) - | (Prim_kind, Prim_kind) - | (Seq_kind, Seq_kind) -> - true - | _ -> false - -let kind = function - | Int _ -> Int_kind - | String _ -> String_kind - | Bytes _ -> Bytes_kind - | Prim _ -> Prim_kind - | Seq _ -> Seq_kind - -let unexpected expr exp_kinds exp_ns exp_prims = - match expr with - | Int (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Int_kind) - | String (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, String_kind) - | Bytes (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Bytes_kind) - | Seq (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Seq_kind) - | Prim (loc, name, _, _) -> ( - let open Michelson_v1_primitives in - match (namespace name, exp_ns) with - | (Type_namespace, Type_namespace) - | (Instr_namespace, Instr_namespace) - | (Constant_namespace, Constant_namespace) -> - Invalid_primitive (loc, exp_prims, name) - | (ns, _) -> Invalid_namespace (loc, name, exp_ns, ns)) - -let check_kind kinds expr = - let kind = kind expr in - if List.exists (kind_equal kind) kinds then Result.return_unit - else - let loc = location expr in - error (Invalid_kind (loc, kinds, kind)) - -(* ---- Unparsing (Typed IR -> Untyped expressions) of types -----------------*) - -(* This part contains the unparsing that does not depend on parsing - (everything that cannot contain a lambda). The rest is located at - the end of the file. *) - -let rec ty_of_comparable_ty : type a. a comparable_ty -> a ty = function - | Unit_key tname -> Unit_t tname - | Never_key tname -> Never_t tname - | Int_key tname -> Int_t tname - | Nat_key tname -> Nat_t tname - | Signature_key tname -> Signature_t tname - | String_key tname -> String_t tname - | Bytes_key tname -> Bytes_t tname - | Mutez_key tname -> Mutez_t tname - | Bool_key tname -> Bool_t tname - | Key_hash_key tname -> Key_hash_t tname - | Key_key tname -> Key_t tname - | Timestamp_key tname -> Timestamp_t tname - | Address_key tname -> Address_t tname - | Chain_id_key tname -> Chain_id_t tname - | Pair_key ((l, al), (r, ar), tname) -> - Pair_t - ( (ty_of_comparable_ty l, al, None), - (ty_of_comparable_ty r, ar, None), - tname ) - | Union_key ((l, al), (r, ar), tname) -> - Union_t ((ty_of_comparable_ty l, al), (ty_of_comparable_ty r, ar), tname) - | Option_key (t, tname) -> Option_t (ty_of_comparable_ty t, tname) - -let add_field_annot a var = function - | Prim (loc, prim, args, annots) -> - Prim - (loc, prim, args, annots @ unparse_field_annot a @ unparse_var_annot var) - | expr -> expr - -let rec unparse_comparable_ty_uncarbonated : - type a loc. loc:loc -> a comparable_ty -> loc Script.michelson_node = - fun ~loc -> function - | Unit_key meta -> Prim (loc, T_unit, [], unparse_type_annot meta.annot) - | Never_key meta -> Prim (loc, T_never, [], unparse_type_annot meta.annot) - | Int_key meta -> Prim (loc, T_int, [], unparse_type_annot meta.annot) - | Nat_key meta -> Prim (loc, T_nat, [], unparse_type_annot meta.annot) - | Signature_key meta -> - Prim (loc, T_signature, [], unparse_type_annot meta.annot) - | String_key meta -> Prim (loc, T_string, [], unparse_type_annot meta.annot) - | Bytes_key meta -> Prim (loc, T_bytes, [], unparse_type_annot meta.annot) - | Mutez_key meta -> Prim (loc, T_mutez, [], unparse_type_annot meta.annot) - | Bool_key meta -> Prim (loc, T_bool, [], unparse_type_annot meta.annot) - | Key_hash_key meta -> - Prim (loc, T_key_hash, [], unparse_type_annot meta.annot) - | Key_key meta -> Prim (loc, T_key, [], unparse_type_annot meta.annot) - | Timestamp_key meta -> - Prim (loc, T_timestamp, [], unparse_type_annot meta.annot) - | Address_key meta -> Prim (loc, T_address, [], unparse_type_annot meta.annot) - | Chain_id_key meta -> - Prim (loc, T_chain_id, [], unparse_type_annot meta.annot) - | Pair_key ((l, al), (r, ar), meta) -> ( - let tl = - add_field_annot al None (unparse_comparable_ty_uncarbonated ~loc l) - in - let tr = - add_field_annot ar None (unparse_comparable_ty_uncarbonated ~loc r) - in - (* Fold [pair a1 (pair ... (pair an-1 an))] into [pair a1 ... an] *) - (* Note that the folding does not happen if the pair on the right has a - field annotation because this annotation would be lost *) - match tr with - | Prim (_, T_pair, ts, []) -> - Prim (loc, T_pair, tl :: ts, unparse_type_annot meta.annot) - | _ -> Prim (loc, T_pair, [tl; tr], unparse_type_annot meta.annot)) - | Union_key ((l, al), (r, ar), meta) -> - let tl = - add_field_annot al None (unparse_comparable_ty_uncarbonated ~loc l) - in - let tr = - add_field_annot ar None (unparse_comparable_ty_uncarbonated ~loc r) - in - Prim (loc, T_or, [tl; tr], unparse_type_annot meta.annot) - | Option_key (t, meta) -> - Prim - ( loc, - T_option, - [unparse_comparable_ty_uncarbonated ~loc t], - unparse_type_annot meta.annot ) - -let unparse_memo_size ~loc memo_size = - let z = Sapling.Memo_size.unparse_to_z memo_size in - Int (loc, z) - -let rec unparse_ty_uncarbonated : - type a loc. loc:loc -> a ty -> loc Script.michelson_node = - fun ~loc ty -> - let prim (name, args, annot) = Prim (loc, name, args, annot) in - match ty with - | Unit_t meta -> prim (T_unit, [], unparse_type_annot meta.annot) - | Int_t meta -> prim (T_int, [], unparse_type_annot meta.annot) - | Nat_t meta -> prim (T_nat, [], unparse_type_annot meta.annot) - | Signature_t meta -> prim (T_signature, [], unparse_type_annot meta.annot) - | String_t meta -> prim (T_string, [], unparse_type_annot meta.annot) - | Bytes_t meta -> prim (T_bytes, [], unparse_type_annot meta.annot) - | Mutez_t meta -> prim (T_mutez, [], unparse_type_annot meta.annot) - | Bool_t meta -> prim (T_bool, [], unparse_type_annot meta.annot) - | Key_hash_t meta -> prim (T_key_hash, [], unparse_type_annot meta.annot) - | Key_t meta -> prim (T_key, [], unparse_type_annot meta.annot) - | Timestamp_t meta -> prim (T_timestamp, [], unparse_type_annot meta.annot) - | Address_t meta -> prim (T_address, [], unparse_type_annot meta.annot) - | Operation_t meta -> prim (T_operation, [], unparse_type_annot meta.annot) - | Chain_id_t meta -> prim (T_chain_id, [], unparse_type_annot meta.annot) - | Never_t meta -> prim (T_never, [], unparse_type_annot meta.annot) - | Bls12_381_g1_t meta -> - prim (T_bls12_381_g1, [], unparse_type_annot meta.annot) - | Bls12_381_g2_t meta -> - prim (T_bls12_381_g2, [], unparse_type_annot meta.annot) - | Bls12_381_fr_t meta -> - prim (T_bls12_381_fr, [], unparse_type_annot meta.annot) - | Contract_t (ut, meta) -> - let t = unparse_ty_uncarbonated ~loc ut in - prim (T_contract, [t], unparse_type_annot meta.annot) - | Pair_t ((utl, l_field, l_var), (utr, r_field, r_var), meta) -> - let annot = unparse_type_annot meta.annot in - let utl = unparse_ty_uncarbonated ~loc utl in - let tl = add_field_annot l_field l_var utl in - let utr = unparse_ty_uncarbonated ~loc utr in - let tr = add_field_annot r_field r_var utr in - (* Fold [pair a1 (pair ... (pair an-1 an))] into [pair a1 ... an] *) - (* Note that the folding does not happen if the pair on the right has an - annotation because this annotation would be lost *) - prim - (match tr with - | Prim (_, T_pair, ts, []) -> (T_pair, tl :: ts, annot) - | _ -> (T_pair, [tl; tr], annot)) - | Union_t ((utl, l_field), (utr, r_field), meta) -> - let annot = unparse_type_annot meta.annot in - let utl = unparse_ty_uncarbonated ~loc utl in - let tl = add_field_annot l_field None utl in - let utr = unparse_ty_uncarbonated ~loc utr in - let tr = add_field_annot r_field None utr in - prim (T_or, [tl; tr], annot) - | Lambda_t (uta, utr, meta) -> - let ta = unparse_ty_uncarbonated ~loc uta in - let tr = unparse_ty_uncarbonated ~loc utr in - prim (T_lambda, [ta; tr], unparse_type_annot meta.annot) - | Option_t (ut, meta) -> - let annot = unparse_type_annot meta.annot in - let ut = unparse_ty_uncarbonated ~loc ut in - prim (T_option, [ut], annot) - | List_t (ut, meta) -> - let t = unparse_ty_uncarbonated ~loc ut in - prim (T_list, [t], unparse_type_annot meta.annot) - | Ticket_t (ut, meta) -> - let t = unparse_comparable_ty_uncarbonated ~loc ut in - prim (T_ticket, [t], unparse_type_annot meta.annot) - | Set_t (ut, meta) -> - let t = unparse_comparable_ty_uncarbonated ~loc ut in - prim (T_set, [t], unparse_type_annot meta.annot) - | Map_t (uta, utr, meta) -> - let ta = unparse_comparable_ty_uncarbonated ~loc uta in - let tr = unparse_ty_uncarbonated ~loc utr in - prim (T_map, [ta; tr], unparse_type_annot meta.annot) - | Big_map_t (uta, utr, meta) -> - let ta = unparse_comparable_ty_uncarbonated ~loc uta in - let tr = unparse_ty_uncarbonated ~loc utr in - prim (T_big_map, [ta; tr], unparse_type_annot meta.annot) - | Sapling_transaction_t (memo_size, meta) -> - prim - ( T_sapling_transaction, - [unparse_memo_size ~loc memo_size], - unparse_type_annot meta.annot ) - | Sapling_state_t (memo_size, meta) -> - prim - ( T_sapling_state, - [unparse_memo_size ~loc memo_size], - unparse_type_annot meta.annot ) - | Chest_key_t meta -> prim (T_chest_key, [], unparse_type_annot meta.annot) - | Chest_t meta -> prim (T_chest, [], unparse_type_annot meta.annot) - -let unparse_ty ~loc ctxt ty = - Gas.consume ctxt (Unparse_costs.unparse_type ty) >|? fun ctxt -> - (unparse_ty_uncarbonated ~loc ty, ctxt) - -let unparse_comparable_ty ~loc ctxt comp_ty = - Gas.consume ctxt (Unparse_costs.unparse_comparable_type comp_ty) - >|? fun ctxt -> (unparse_comparable_ty_uncarbonated ~loc comp_ty, ctxt) - -let[@coq_struct "function_parameter"] rec strip_var_annots = function - | (Int _ | String _ | Bytes _) as atom -> atom - | Seq (loc, args) -> Seq (loc, List.map strip_var_annots args) - | Prim (loc, name, args, annots) -> - let not_var_annot s = Compare.Char.(s.[0] <> '@') in - let annots = List.filter not_var_annot annots in - Prim (loc, name, List.map strip_var_annots args, annots) - -let serialize_ty_for_error ty = - (* - Types are bounded by [Constants.michelson_maximum_type_size], so - [unparse_ty_uncarbonated], [strip_var_annots], and [strip_locations] are - bounded in time. - - It is hence OK to use them in errors that are not caught in the validation - (only once in apply). - *) - let ty = unparse_ty_uncarbonated ~loc:() ty in - Micheline.strip_locations (strip_var_annots ty) - -let[@coq_axiom_with_reason "gadt"] rec comparable_ty_of_ty : - type a. - context -> Script.location -> a ty -> (a comparable_ty * context) tzresult = - fun ctxt loc ty -> - Gas.consume ctxt Typecheck_costs.comparable_ty_of_ty_cycle >>? fun ctxt -> - match ty with - | Unit_t tname -> ok ((Unit_key tname : a comparable_ty), ctxt) - | Never_t tname -> ok (Never_key tname, ctxt) - | Int_t tname -> ok (Int_key tname, ctxt) - | Nat_t tname -> ok (Nat_key tname, ctxt) - | Signature_t tname -> ok (Signature_key tname, ctxt) - | String_t tname -> ok (String_key tname, ctxt) - | Bytes_t tname -> ok (Bytes_key tname, ctxt) - | Mutez_t tname -> ok (Mutez_key tname, ctxt) - | Bool_t tname -> ok (Bool_key tname, ctxt) - | Key_hash_t tname -> ok (Key_hash_key tname, ctxt) - | Key_t tname -> ok (Key_key tname, ctxt) - | Timestamp_t tname -> ok (Timestamp_key tname, ctxt) - | Address_t tname -> ok (Address_key tname, ctxt) - | Chain_id_t tname -> ok (Chain_id_key tname, ctxt) - | Pair_t ((l, al, _), (r, ar, _), pname) -> - comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> - comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> - (Pair_key ((lty, al), (rty, ar), pname), ctxt) - | Union_t ((l, al), (r, ar), tname) -> - comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> - comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> - (Union_key ((lty, al), (rty, ar), tname), ctxt) - | Option_t (tt, tname) -> - comparable_ty_of_ty ctxt loc tt >|? fun (ty, ctxt) -> - (Option_key (ty, tname), ctxt) - | Lambda_t _ | List_t _ | Ticket_t _ | Set_t _ | Map_t _ | Big_map_t _ - | Contract_t _ | Operation_t _ | Bls12_381_fr_t _ | Bls12_381_g1_t _ - | Bls12_381_g2_t _ | Sapling_state_t _ | Sapling_transaction_t _ - | Chest_key_t _ | Chest_t _ -> - let t = serialize_ty_for_error ty in - error (Comparable_type_expected (loc, t)) - -let rec unparse_stack_uncarbonated : - type a s. (a, s) stack_ty -> (Script.expr * Script.annot) list = function - | Bot_t -> [] - | Item_t (ty, rest, annot) -> - let uty = unparse_ty_uncarbonated ~loc:() ty in - let urest = unparse_stack_uncarbonated rest in - (strip_locations uty, unparse_var_annot annot) :: urest - -let serialize_stack_for_error ctxt stack_ty = - match Gas.level ctxt with - | Unaccounted -> unparse_stack_uncarbonated stack_ty - | Limited _ -> [] - -let name_of_ty : type a. a ty -> type_annot option = function - | Unit_t meta -> meta.annot - | Int_t meta -> meta.annot - | Nat_t meta -> meta.annot - | String_t meta -> meta.annot - | Bytes_t meta -> meta.annot - | Mutez_t meta -> meta.annot - | Bool_t meta -> meta.annot - | Key_hash_t meta -> meta.annot - | Key_t meta -> meta.annot - | Timestamp_t meta -> meta.annot - | Address_t meta -> meta.annot - | Signature_t meta -> meta.annot - | Operation_t meta -> meta.annot - | Chain_id_t meta -> meta.annot - | Never_t meta -> meta.annot - | Contract_t (_, meta) -> meta.annot - | Pair_t (_, _, meta) -> meta.annot - | Union_t (_, _, meta) -> meta.annot - | Lambda_t (_, _, meta) -> meta.annot - | Option_t (_, meta) -> meta.annot - | List_t (_, meta) -> meta.annot - | Ticket_t (_, meta) -> meta.annot - | Set_t (_, meta) -> meta.annot - | Map_t (_, _, meta) -> meta.annot - | Big_map_t (_, _, meta) -> meta.annot - | Bls12_381_g1_t meta -> meta.annot - | Bls12_381_g2_t meta -> meta.annot - | Bls12_381_fr_t meta -> meta.annot - | Sapling_state_t (_, meta) -> meta.annot - | Sapling_transaction_t (_, meta) -> meta.annot - | Chest_key_t meta -> meta.annot - | Chest_t meta -> meta.annot - -let unparse_unit ~loc ctxt () = ok (Prim (loc, D_Unit, [], []), ctxt) - -let unparse_int ~loc ctxt v = ok (Int (loc, Script_int.to_zint v), ctxt) - -let unparse_nat ~loc ctxt v = ok (Int (loc, Script_int.to_zint v), ctxt) - -let unparse_string ~loc ctxt s = - ok (String (loc, Script_string.to_string s), ctxt) - -let unparse_bytes ~loc ctxt s = ok (Bytes (loc, s), ctxt) - -let unparse_bool ~loc ctxt b = - ok (Prim (loc, (if b then D_True else D_False), [], []), ctxt) - -let unparse_timestamp ~loc ctxt mode t = - match mode with - | Optimized | Optimized_legacy -> - ok (Int (loc, Script_timestamp.to_zint t), ctxt) - | Readable -> ( - Gas.consume ctxt Unparse_costs.timestamp_readable >>? fun ctxt -> - match Script_timestamp.to_notation t with - | None -> ok (Int (loc, Script_timestamp.to_zint t), ctxt) - | Some s -> ok (String (loc, s), ctxt)) - -let unparse_address ~loc ctxt mode (c, entrypoint) = - Gas.consume ctxt Unparse_costs.contract >>? fun ctxt -> - (match entrypoint with - (* given parse_address, this should not happen *) - | "" -> error Unparsing_invariant_violated - | _ -> ok ()) - >|? fun () -> - match mode with - | Optimized | Optimized_legacy -> - let entrypoint = match entrypoint with "default" -> "" | name -> name in - let bytes = - Data_encoding.Binary.to_bytes_exn - Data_encoding.(tup2 Contract.encoding Variable.string) - (c, entrypoint) - in - (Bytes (loc, bytes), ctxt) - | Readable -> - let notation = - match entrypoint with - | "default" -> Contract.to_b58check c - | entrypoint -> Contract.to_b58check c ^ "%" ^ entrypoint - in - (String (loc, notation), ctxt) - -let unparse_contract ~loc ctxt mode (_, address) = - unparse_address ~loc ctxt mode address - -let unparse_signature ~loc ctxt mode s = - match mode with - | Optimized | Optimized_legacy -> - Gas.consume ctxt Unparse_costs.signature_optimized >|? fun ctxt -> - let bytes = Data_encoding.Binary.to_bytes_exn Signature.encoding s in - (Bytes (loc, bytes), ctxt) - | Readable -> - Gas.consume ctxt Unparse_costs.signature_readable >|? fun ctxt -> - (String (loc, Signature.to_b58check s), ctxt) - -let unparse_mutez ~loc ctxt v = ok (Int (loc, Z.of_int64 (Tez.to_mutez v)), ctxt) - -let unparse_key ~loc ctxt mode k = - match mode with - | Optimized | Optimized_legacy -> - Gas.consume ctxt Unparse_costs.public_key_optimized >|? fun ctxt -> - let bytes = - Data_encoding.Binary.to_bytes_exn Signature.Public_key.encoding k - in - (Bytes (loc, bytes), ctxt) - | Readable -> - Gas.consume ctxt Unparse_costs.public_key_readable >|? fun ctxt -> - (String (loc, Signature.Public_key.to_b58check k), ctxt) - -let unparse_key_hash ~loc ctxt mode k = - match mode with - | Optimized | Optimized_legacy -> - Gas.consume ctxt Unparse_costs.key_hash_optimized >|? fun ctxt -> - let bytes = - Data_encoding.Binary.to_bytes_exn Signature.Public_key_hash.encoding k - in - (Bytes (loc, bytes), ctxt) - | Readable -> - Gas.consume ctxt Unparse_costs.key_hash_readable >|? fun ctxt -> - (String (loc, Signature.Public_key_hash.to_b58check k), ctxt) - -let unparse_operation ~loc ctxt (op, _big_map_diff) = - let bytes = - Data_encoding.Binary.to_bytes_exn Operation.internal_operation_encoding op - in - Gas.consume ctxt (Unparse_costs.operation bytes) >|? fun ctxt -> - (Bytes (loc, bytes), ctxt) - -let unparse_chain_id ~loc ctxt mode chain_id = - match mode with - | Optimized | Optimized_legacy -> - Gas.consume ctxt Unparse_costs.chain_id_optimized >|? fun ctxt -> - let bytes = - Data_encoding.Binary.to_bytes_exn Chain_id.encoding chain_id - in - (Bytes (loc, bytes), ctxt) - | Readable -> - Gas.consume ctxt Unparse_costs.chain_id_readable >|? fun ctxt -> - (String (loc, Chain_id.to_b58check chain_id), ctxt) - -let unparse_bls12_381_g1 ~loc ctxt x = - Gas.consume ctxt Unparse_costs.bls12_381_g1 >|? fun ctxt -> - let bytes = Bls12_381.G1.to_bytes x in - (Bytes (loc, bytes), ctxt) - -let unparse_bls12_381_g2 ~loc ctxt x = - Gas.consume ctxt Unparse_costs.bls12_381_g2 >|? fun ctxt -> - let bytes = Bls12_381.G2.to_bytes x in - (Bytes (loc, bytes), ctxt) - -let unparse_bls12_381_fr ~loc ctxt x = - Gas.consume ctxt Unparse_costs.bls12_381_fr >|? fun ctxt -> - let bytes = Bls12_381.Fr.to_bytes x in - (Bytes (loc, bytes), ctxt) - -let unparse_with_data_encoding ~loc ctxt s unparse_cost encoding = - Lwt.return - ( Gas.consume ctxt unparse_cost >|? fun ctxt -> - let bytes = Data_encoding.Binary.to_bytes_exn encoding s in - (Bytes (loc, bytes), ctxt) ) - -(* -- Unparsing data of complex types -- *) - -type ('ty, 'depth) comb_witness = - | Comb_Pair : ('t, 'd) comb_witness -> (_ * 't, unit -> 'd) comb_witness - | Comb_Any : (_, _) comb_witness - -let unparse_pair (type r) ~loc unparse_l unparse_r ctxt mode - (r_comb_witness : (r, unit -> unit -> _) comb_witness) (l, (r : r)) = - unparse_l ctxt l >>=? fun (l, ctxt) -> - unparse_r ctxt r >|=? fun (r, ctxt) -> - (* Fold combs. - For combs, three notations are supported: - - a) [Pair x1 (Pair x2 ... (Pair xn-1 xn) ...)], - - b) [Pair x1 x2 ... xn-1 xn], and - - c) [{x1; x2; ...; xn-1; xn}]. - In readable mode, we always use b), - in optimized mode we use the shortest to serialize: - - for n=2, [Pair x1 x2], - - for n=3, [Pair x1 (Pair x2 x3)], - - for n>=4, [{x1; x2; ...; xn}]. - *) - let res = - match (mode, r_comb_witness, r) with - | (Optimized, Comb_Pair _, Micheline.Seq (_, r)) -> - (* Optimized case n > 4 *) - Micheline.Seq (loc, l :: r) - | ( Optimized, - Comb_Pair (Comb_Pair _), - Prim (_, D_Pair, [x2; Prim (_, D_Pair, [x3; x4], [])], []) ) -> - (* Optimized case n = 4 *) - Micheline.Seq (loc, [l; x2; x3; x4]) - | (Readable, Comb_Pair _, Prim (_, D_Pair, xs, [])) -> - (* Readable case n > 2 *) - Prim (loc, D_Pair, l :: xs, []) - | _ -> - (* The remaining cases are: - - Optimized n = 2, - - Optimized n = 3, and - - Readable n = 2, - - Optimized_legacy, any n *) - Prim (loc, D_Pair, [l; r], []) - in - (res, ctxt) - -let unparse_union ~loc unparse_l unparse_r ctxt = function - | L l -> - unparse_l ctxt l >|=? fun (l, ctxt) -> (Prim (loc, D_Left, [l], []), ctxt) - | R r -> - unparse_r ctxt r >|=? fun (r, ctxt) -> (Prim (loc, D_Right, [r], []), ctxt) - -let unparse_option ~loc unparse_v ctxt = function - | Some v -> - unparse_v ctxt v >|=? fun (v, ctxt) -> (Prim (loc, D_Some, [v], []), ctxt) - | None -> return (Prim (loc, D_None, [], []), ctxt) - -(* -- Unparsing data of comparable types -- *) - -let comparable_comb_witness2 : - type t. t comparable_ty -> (t, unit -> unit -> unit) comb_witness = function - | Pair_key (_, (Pair_key _, _), _) -> Comb_Pair (Comb_Pair Comb_Any) - | Pair_key _ -> Comb_Pair Comb_Any - | _ -> Comb_Any - -let[@coq_axiom_with_reason "gadt"] rec unparse_comparable_data : - type a loc. - loc:loc -> - context -> - unparsing_mode -> - a comparable_ty -> - a -> - (loc Script.michelson_node * context) tzresult Lwt.t = - fun ~loc ctxt mode ty a -> - (* No need for stack_depth here. Unlike [unparse_data], - [unparse_comparable_data] doesn't call [unparse_code]. - The stack depth is bounded by the type depth, currently bounded - by 1000 (michelson_maximum_type_size). *) - Gas.consume ctxt Unparse_costs.unparse_data_cycle - (* We could have a smaller cost but let's keep it consistent with - [unparse_data] for now. *) - >>?= - fun ctxt -> - match (ty, a) with - | (Unit_key _, v) -> Lwt.return @@ unparse_unit ~loc ctxt v - | (Int_key _, v) -> Lwt.return @@ unparse_int ~loc ctxt v - | (Nat_key _, v) -> Lwt.return @@ unparse_nat ~loc ctxt v - | (String_key _, s) -> Lwt.return @@ unparse_string ~loc ctxt s - | (Bytes_key _, s) -> Lwt.return @@ unparse_bytes ~loc ctxt s - | (Bool_key _, b) -> Lwt.return @@ unparse_bool ~loc ctxt b - | (Timestamp_key _, t) -> Lwt.return @@ unparse_timestamp ~loc ctxt mode t - | (Address_key _, address) -> - Lwt.return @@ unparse_address ~loc ctxt mode address - | (Signature_key _, s) -> Lwt.return @@ unparse_signature ~loc ctxt mode s - | (Mutez_key _, v) -> Lwt.return @@ unparse_mutez ~loc ctxt v - | (Key_key _, k) -> Lwt.return @@ unparse_key ~loc ctxt mode k - | (Key_hash_key _, k) -> Lwt.return @@ unparse_key_hash ~loc ctxt mode k - | (Chain_id_key _, chain_id) -> - Lwt.return @@ unparse_chain_id ~loc ctxt mode chain_id - | (Pair_key ((tl, _), (tr, _), _), pair) -> - let r_witness = comparable_comb_witness2 tr in - let unparse_l ctxt v = unparse_comparable_data ~loc ctxt mode tl v in - let unparse_r ctxt v = unparse_comparable_data ~loc ctxt mode tr v in - unparse_pair ~loc unparse_l unparse_r ctxt mode r_witness pair - | (Union_key ((tl, _), (tr, _), _), v) -> - let unparse_l ctxt v = unparse_comparable_data ~loc ctxt mode tl v in - let unparse_r ctxt v = unparse_comparable_data ~loc ctxt mode tr v in - unparse_union ~loc unparse_l unparse_r ctxt v - | (Option_key (t, _), v) -> - let unparse_v ctxt v = unparse_comparable_data ~loc ctxt mode t v in - unparse_option ~loc unparse_v ctxt v - | (Never_key _, _) -> . - -let pack_node unparsed ctxt = - Gas.consume ctxt (Script.strip_locations_cost unparsed) >>? fun ctxt -> - let bytes = - Data_encoding.Binary.to_bytes_exn - expr_encoding - (Micheline.strip_locations unparsed) - in - Gas.consume ctxt (Script.serialized_cost bytes) >|? fun ctxt -> - let bytes = Bytes.cat (Bytes.of_string "\005") bytes in - (bytes, ctxt) - -let pack_comparable_data ctxt typ data ~mode = - unparse_comparable_data ~loc:() ctxt mode typ data - >>=? fun (unparsed, ctxt) -> Lwt.return @@ pack_node unparsed ctxt - -let hash_bytes ctxt bytes = - Gas.consume ctxt (Michelson_v1_gas.Cost_of.Interpreter.blake2b bytes) - >|? fun ctxt -> (Script_expr_hash.(hash_bytes [bytes]), ctxt) - -let hash_comparable_data ctxt typ data = - pack_comparable_data ctxt typ data ~mode:Optimized_legacy - >>=? fun (bytes, ctxt) -> Lwt.return @@ hash_bytes ctxt bytes - -(* ---- Tickets ------------------------------------------------------------ *) - -(* - All comparable types are dupable, this function exists only to not forget - checking this property when adding new types. -*) -let check_dupable_comparable_ty : type a. a comparable_ty -> unit = function - | Unit_key _ | Never_key _ | Int_key _ | Nat_key _ | Signature_key _ - | String_key _ | Bytes_key _ | Mutez_key _ | Bool_key _ | Key_hash_key _ - | Key_key _ | Timestamp_key _ | Chain_id_key _ | Address_key _ | Pair_key _ - | Union_key _ | Option_key _ -> - () - -let rec check_dupable_ty : - type a. context -> location -> a ty -> context tzresult = - fun ctxt loc ty -> - Gas.consume ctxt Typecheck_costs.check_dupable_cycle >>? fun ctxt -> - match ty with - | Unit_t _ -> ok ctxt - | Int_t _ -> ok ctxt - | Nat_t _ -> ok ctxt - | Signature_t _ -> ok ctxt - | String_t _ -> ok ctxt - | Bytes_t _ -> ok ctxt - | Mutez_t _ -> ok ctxt - | Key_hash_t _ -> ok ctxt - | Key_t _ -> ok ctxt - | Timestamp_t _ -> ok ctxt - | Address_t _ -> ok ctxt - | Bool_t _ -> ok ctxt - | Contract_t (_, _) -> ok ctxt - | Operation_t _ -> ok ctxt - | Chain_id_t _ -> ok ctxt - | Never_t _ -> ok ctxt - | Bls12_381_g1_t _ -> ok ctxt - | Bls12_381_g2_t _ -> ok ctxt - | Bls12_381_fr_t _ -> ok ctxt - | Sapling_state_t _ -> ok ctxt - | Sapling_transaction_t _ -> ok ctxt - | Chest_t _ -> ok ctxt - | Chest_key_t _ -> ok ctxt - | Ticket_t _ -> error (Unexpected_ticket loc) - | Pair_t ((ty_a, _, _), (ty_b, _, _), _) -> - check_dupable_ty ctxt loc ty_a >>? fun ctxt -> - check_dupable_ty ctxt loc ty_b - | Union_t ((ty_a, _), (ty_b, _), _) -> - check_dupable_ty ctxt loc ty_a >>? fun ctxt -> - check_dupable_ty ctxt loc ty_b - | Lambda_t (_, _, _) -> - (* - Lambda are dupable as long as: - - they don't contain non-dupable values, e.g. in `PUSH` - (mostly non-dupable values should probably be considered forged) - - they are not the result of a partial application on a non-dupable - value. `APPLY` rejects non-packable types (because of `PUSH`). - Hence non-dupable should imply non-packable. - *) - ok ctxt - | Option_t (ty, _) -> check_dupable_ty ctxt loc ty - | List_t (ty, _) -> check_dupable_ty ctxt loc ty - | Set_t (key_ty, _) -> - let () = check_dupable_comparable_ty key_ty in - ok ctxt - | Map_t (key_ty, val_ty, _) -> - let () = check_dupable_comparable_ty key_ty in - check_dupable_ty ctxt loc val_ty - | Big_map_t (key_ty, val_ty, _) -> - let () = check_dupable_comparable_ty key_ty in - check_dupable_ty ctxt loc val_ty - -(* ---- Equality witnesses --------------------------------------------------*) - -type ('ta, 'tb) eq = Eq : ('same, 'same) eq - -let record_inconsistent_types loc ta tb = - record_trace_eval (fun () -> - let ta = serialize_ty_for_error ta in - let tb = serialize_ty_for_error tb in - Inconsistent_types (Some loc, ta, tb)) - -let merge_type_metadata : - legacy:bool -> 'a ty_metadata -> 'b ty_metadata -> 'a ty_metadata tzresult = - fun ~legacy {size = size_a; annot = annot_a} {size = size_b; annot = annot_b} -> - Type_size.merge size_a size_b >>? fun size -> - merge_type_annot ~legacy annot_a annot_b >|? fun annot -> {annot; size} - -(* Takes two comparable types and simultaneously merge their annotations and - check that they represent the same type. - - The result contains: - - an equality witness between the types of the two inputs - - the merged type - - an updated context (for gas consumption) - - The tzresult monad is used at two levels: the inner tzresult - is used for tracking merge errors (types of different shapes - or annotation mismatches), the outer tzresult is used only - for gas consumption. Separating these two error cases like - this allows to recover from a type comparison error without - reverting the gas consumption. - *) -let rec merge_comparable_types : - type ta tb. - legacy:bool -> - ta comparable_ty -> - tb comparable_ty -> - ( (ta comparable_ty, tb comparable_ty) eq * ta comparable_ty, - error trace ) - Gas_monad.t = - let open Gas_monad in - fun ~legacy ta tb -> - consume_gas Typecheck_costs.merge_cycle >>$ fun () -> - let merge_type_metadata ~legacy meta_a meta_b = - of_result @@ merge_type_metadata ~legacy meta_a meta_b - in - let merge_field_annot ~legacy annot_a annot_b = - of_result @@ merge_field_annot ~legacy annot_a annot_b - in - let return f eq annot_a annot_b : - ( (ta comparable_ty, tb comparable_ty) eq * ta comparable_ty, - error trace ) - gas_monad = - merge_type_metadata ~legacy annot_a annot_b >>$ fun annot -> - return (eq, f annot) - in - match (ta, tb) with - | (Unit_key annot_a, Unit_key annot_b) -> - return (fun annot -> Unit_key annot) Eq annot_a annot_b - | (Never_key annot_a, Never_key annot_b) -> - return (fun annot -> Never_key annot) Eq annot_a annot_b - | (Int_key annot_a, Int_key annot_b) -> - return (fun annot -> Int_key annot) Eq annot_a annot_b - | (Nat_key annot_a, Nat_key annot_b) -> - return (fun annot -> Nat_key annot) Eq annot_a annot_b - | (Signature_key annot_a, Signature_key annot_b) -> - return (fun annot -> Signature_key annot) Eq annot_a annot_b - | (String_key annot_a, String_key annot_b) -> - return (fun annot -> String_key annot) Eq annot_a annot_b - | (Bytes_key annot_a, Bytes_key annot_b) -> - return (fun annot -> Bytes_key annot) Eq annot_a annot_b - | (Mutez_key annot_a, Mutez_key annot_b) -> - return (fun annot -> Mutez_key annot) Eq annot_a annot_b - | (Bool_key annot_a, Bool_key annot_b) -> - return (fun annot -> Bool_key annot) Eq annot_a annot_b - | (Key_hash_key annot_a, Key_hash_key annot_b) -> - return (fun annot -> Key_hash_key annot) Eq annot_a annot_b - | (Key_key annot_a, Key_key annot_b) -> - return (fun annot -> Key_key annot) Eq annot_a annot_b - | (Timestamp_key annot_a, Timestamp_key annot_b) -> - return (fun annot -> Timestamp_key annot) Eq annot_a annot_b - | (Chain_id_key annot_a, Chain_id_key annot_b) -> - return (fun annot -> Chain_id_key annot) Eq annot_a annot_b - | (Address_key annot_a, Address_key annot_b) -> - return (fun annot -> Address_key annot) Eq annot_a annot_b - | ( Pair_key ((left_a, annot_left_a), (right_a, annot_right_a), annot_a), - Pair_key ((left_b, annot_left_b), (right_b, annot_right_b), annot_b) ) - -> - merge_type_metadata ~legacy annot_a annot_b >>$ fun annot -> - merge_field_annot ~legacy annot_left_a annot_left_b - >>$ fun annot_left -> - merge_field_annot ~legacy annot_right_a annot_right_b - >>$ fun annot_right -> - merge_comparable_types ~legacy left_a left_b >>$ fun (Eq, left) -> - merge_comparable_types ~legacy right_a right_b >|$ fun (Eq, right) -> - ( (Eq : (ta comparable_ty, tb comparable_ty) eq), - Pair_key ((left, annot_left), (right, annot_right), annot) ) - | ( Union_key ((left_a, annot_left_a), (right_a, annot_right_a), annot_a), - Union_key ((left_b, annot_left_b), (right_b, annot_right_b), annot_b) ) - -> - merge_type_metadata ~legacy annot_a annot_b >>$ fun annot -> - merge_field_annot ~legacy annot_left_a annot_left_b - >>$ fun annot_left -> - merge_field_annot ~legacy annot_right_a annot_right_b - >>$ fun annot_right -> - merge_comparable_types ~legacy left_a left_b >>$ fun (Eq, left) -> - merge_comparable_types ~legacy right_a right_b >|$ fun (Eq, right) -> - ( (Eq : (ta comparable_ty, tb comparable_ty) eq), - Union_key ((left, annot_left), (right, annot_right), annot) ) - | (Option_key (ta, annot_a), Option_key (tb, annot_b)) -> - merge_type_metadata ~legacy annot_a annot_b >>$ fun annot -> - merge_comparable_types ~legacy ta tb >|$ fun (Eq, t) -> - ((Eq : (ta comparable_ty, tb comparable_ty) eq), Option_key (t, annot)) - | (_, _) -> - let ta = serialize_ty_for_error (ty_of_comparable_ty ta) in - let tb = serialize_ty_for_error (ty_of_comparable_ty tb) in - of_result @@ error (Inconsistent_types (None, ta, tb)) - -(* This function does not distinguish gas errors from merge errors. If you need - to recover from a type mismatch and consume the exact gas for the failed - comparison, use [merge_comparable_types] instead. -*) -let comparable_ty_eq : - type ta tb. - context -> - ta comparable_ty -> - tb comparable_ty -> - ((ta comparable_ty, tb comparable_ty) eq * context) tzresult = - fun ctxt ta tb -> - Gas_monad.run ctxt (merge_comparable_types ~legacy:true ta tb) - >>? fun (eq_ty, ctxt) -> - eq_ty >|? fun (eq, _ty) -> (eq, ctxt) - -let merge_memo_sizes ms1 ms2 = - if Sapling.Memo_size.equal ms1 ms2 then ok ms1 - else error (Inconsistent_memo_sizes (ms1, ms2)) - -type merge_type_error_flag = Default_merge_type_error | Fast_merge_type_error - -let default_merge_type_error ty1 ty2 = - let ty1 = serialize_ty_for_error ty1 in - let ty2 = serialize_ty_for_error ty2 in - Inconsistent_types (None, ty1, ty2) - -type error += Inconsistent_types_fast - -let fast_merge_type_error _ty1 _ty2 = Inconsistent_types_fast - -let merge_type_error ~merge_type_error_flag = - match merge_type_error_flag with - | Default_merge_type_error -> default_merge_type_error - | Fast_merge_type_error -> fast_merge_type_error - -let record_inconsistent_carbonated ta tb = - Gas_monad.record_trace_eval (fun () -> - let ta = serialize_ty_for_error ta in - let tb = serialize_ty_for_error tb in - Inconsistent_types (None, ta, tb)) - -(* Same as merge_comparable_types but for any types *) -let merge_types : - type a b. - legacy:bool -> - merge_type_error_flag:merge_type_error_flag -> - Script.location -> - a ty -> - b ty -> - ((a ty, b ty) eq * a ty, error trace) Gas_monad.t = - let open Gas_monad in - fun ~legacy ~merge_type_error_flag loc ty1 ty2 -> - let merge_type_metadata tn1 tn2 = - of_result - (merge_type_metadata ~legacy tn1 tn2 - |> record_inconsistent_types loc ty1 ty2) - in - let merge_field_annot ~legacy tn1 tn2 = - of_result (merge_field_annot ~legacy tn1 tn2) - in - let merge_memo_sizes ms1 ms2 = of_result (merge_memo_sizes ms1 ms2) in - let rec help : - type ta tb. - ta ty -> tb ty -> ((ta ty, tb ty) eq * ta ty, error trace) gas_monad = - fun ty1 ty2 -> help0 ty1 ty2 |> record_inconsistent_carbonated ty1 ty2 - and help0 : - type ta tb. - ta ty -> tb ty -> ((ta ty, tb ty) eq * ta ty, error trace) gas_monad = - fun ty1 ty2 -> - consume_gas Typecheck_costs.merge_cycle >>$ fun () -> - let return f eq annot_a annot_b : - ((ta ty, tb ty) eq * ta ty, error trace) gas_monad = - merge_type_metadata annot_a annot_b >>$ fun annot -> return (eq, f annot) - in - match (ty1, ty2) with - | (Unit_t tn1, Unit_t tn2) -> - return (fun tname -> Unit_t tname) Eq tn1 tn2 - | (Int_t tn1, Int_t tn2) -> return (fun tname -> Int_t tname) Eq tn1 tn2 - | (Nat_t tn1, Nat_t tn2) -> return (fun tname -> Nat_t tname) Eq tn1 tn2 - | (Key_t tn1, Key_t tn2) -> return (fun tname -> Key_t tname) Eq tn1 tn2 - | (Key_hash_t tn1, Key_hash_t tn2) -> - return (fun tname -> Key_hash_t tname) Eq tn1 tn2 - | (String_t tn1, String_t tn2) -> - return (fun tname -> String_t tname) Eq tn1 tn2 - | (Bytes_t tn1, Bytes_t tn2) -> - return (fun tname -> Bytes_t tname) Eq tn1 tn2 - | (Signature_t tn1, Signature_t tn2) -> - return (fun tname -> Signature_t tname) Eq tn1 tn2 - | (Mutez_t tn1, Mutez_t tn2) -> - return (fun tname -> Mutez_t tname) Eq tn1 tn2 - | (Timestamp_t tn1, Timestamp_t tn2) -> - return (fun tname -> Timestamp_t tname) Eq tn1 tn2 - | (Address_t tn1, Address_t tn2) -> - return (fun tname -> Address_t tname) Eq tn1 tn2 - | (Bool_t tn1, Bool_t tn2) -> - return (fun tname -> Bool_t tname) Eq tn1 tn2 - | (Chain_id_t tn1, Chain_id_t tn2) -> - return (fun tname -> Chain_id_t tname) Eq tn1 tn2 - | (Never_t tn1, Never_t tn2) -> - return (fun tname -> Never_t tname) Eq tn1 tn2 - | (Operation_t tn1, Operation_t tn2) -> - return (fun tname -> Operation_t tname) Eq tn1 tn2 - | (Bls12_381_g1_t tn1, Bls12_381_g1_t tn2) -> - return (fun tname -> Bls12_381_g1_t tname) Eq tn1 tn2 - | (Bls12_381_g2_t tn1, Bls12_381_g2_t tn2) -> - return (fun tname -> Bls12_381_g2_t tname) Eq tn1 tn2 - | (Bls12_381_fr_t tn1, Bls12_381_fr_t tn2) -> - return (fun tname -> Bls12_381_fr_t tname) Eq tn1 tn2 - | (Map_t (tal, tar, tn1), Map_t (tbl, tbr, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - help tar tbr >>$ fun (Eq, value) -> - merge_comparable_types ~legacy tal tbl >|$ fun (Eq, tk) -> - ((Eq : (ta ty, tb ty) eq), Map_t (tk, value, tname)) - | (Big_map_t (tal, tar, tn1), Big_map_t (tbl, tbr, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - help tar tbr >>$ fun (Eq, value) -> - merge_comparable_types ~legacy tal tbl >|$ fun (Eq, tk) -> - ((Eq : (ta ty, tb ty) eq), Big_map_t (tk, value, tname)) - | (Set_t (ea, tn1), Set_t (eb, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - merge_comparable_types ~legacy ea eb >|$ fun (Eq, e) -> - ((Eq : (ta ty, tb ty) eq), Set_t (e, tname)) - | (Ticket_t (ea, tn1), Ticket_t (eb, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - merge_comparable_types ~legacy ea eb >|$ fun (Eq, e) -> - ((Eq : (ta ty, tb ty) eq), Ticket_t (e, tname)) - | ( Pair_t ((tal, l_field1, l_var1), (tar, r_field1, r_var1), tn1), - Pair_t ((tbl, l_field2, l_var2), (tbr, r_field2, r_var2), tn2) ) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - merge_field_annot ~legacy l_field1 l_field2 >>$ fun l_field -> - merge_field_annot ~legacy r_field1 r_field2 >>$ fun r_field -> - let l_var = merge_var_annot l_var1 l_var2 in - let r_var = merge_var_annot r_var1 r_var2 in - help tal tbl >>$ fun (Eq, left_ty) -> - help tar tbr >|$ fun (Eq, right_ty) -> - ( (Eq : (ta ty, tb ty) eq), - Pair_t ((left_ty, l_field, l_var), (right_ty, r_field, r_var), tname) - ) - | ( Union_t ((tal, tal_annot), (tar, tar_annot), tn1), - Union_t ((tbl, tbl_annot), (tbr, tbr_annot), tn2) ) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - merge_field_annot ~legacy tal_annot tbl_annot >>$ fun left_annot -> - merge_field_annot ~legacy tar_annot tbr_annot >>$ fun right_annot -> - help tal tbl >>$ fun (Eq, left_ty) -> - help tar tbr >|$ fun (Eq, right_ty) -> - ( (Eq : (ta ty, tb ty) eq), - Union_t ((left_ty, left_annot), (right_ty, right_annot), tname) ) - | (Lambda_t (tal, tar, tn1), Lambda_t (tbl, tbr, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - help tal tbl >>$ fun (Eq, left_ty) -> - help tar tbr >|$ fun (Eq, right_ty) -> - ((Eq : (ta ty, tb ty) eq), Lambda_t (left_ty, right_ty, tname)) - | (Contract_t (tal, tn1), Contract_t (tbl, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - help tal tbl >|$ fun (Eq, arg_ty) -> - ((Eq : (ta ty, tb ty) eq), Contract_t (arg_ty, tname)) - | (Option_t (tva, tn1), Option_t (tvb, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - help tva tvb >|$ fun (Eq, ty) -> - ((Eq : (ta ty, tb ty) eq), Option_t (ty, tname)) - | (List_t (tva, tn1), List_t (tvb, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - help tva tvb >|$ fun (Eq, ty) -> - ((Eq : (ta ty, tb ty) eq), List_t (ty, tname)) - | (Sapling_state_t (ms1, tn1), Sapling_state_t (ms2, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - merge_memo_sizes ms1 ms2 >|$ fun ms -> - (Eq, Sapling_state_t (ms, tname)) - | (Sapling_transaction_t (ms1, tn1), Sapling_transaction_t (ms2, tn2)) -> - merge_type_metadata tn1 tn2 >>$ fun tname -> - merge_memo_sizes ms1 ms2 >|$ fun ms -> - (Eq, Sapling_transaction_t (ms, tname)) - | (Chest_t tn1, Chest_t tn2) -> - return (fun tname -> Chest_t tname) Eq tn1 tn2 - | (Chest_key_t tn1, Chest_key_t tn2) -> - return (fun tname -> Chest_key_t tname) Eq tn1 tn2 - | (_, _) -> - of_result @@ error @@ merge_type_error ~merge_type_error_flag ty1 ty2 - in - help ty1 ty2 - [@@coq_axiom_with_reason "non-top-level mutual recursion"] - -(* This function does not distinguish gas errors from merge errors. If you need - to recover from a type mismatch and consume the exact gas for the failed - comparison, use [merge_types] instead. -*) -let ty_eq : - type ta tb. - legacy:bool -> - context -> - Script.location -> - ta ty -> - tb ty -> - ((ta ty, tb ty) eq * context) tzresult = - fun ~legacy ctxt loc ta tb -> - Gas_monad.run ctxt - @@ merge_types - ~merge_type_error_flag:Default_merge_type_error - ~legacy - loc - ta - tb - >>? fun (eq_ty, ctxt) -> - eq_ty >|? fun (eq, _ty) -> (eq, ctxt) - -(* Same as merge_comparable_types and merge_types but for stacks. - A single error monad is used here because there is no need to - recover from stack merging errors. *) -let merge_stacks : - type ta tb ts tu. - legacy:bool -> - Script.location -> - context -> - int -> - (ta, ts) stack_ty -> - (tb, tu) stack_ty -> - (((ta, ts) stack_ty, (tb, tu) stack_ty) eq * (ta, ts) stack_ty * context) - tzresult = - fun ~legacy loc -> - let rec help : - type ta tb ts tu. - context -> - int -> - (ta, ts) stack_ty -> - (tb, tu) stack_ty -> - (((ta, ts) stack_ty, (tb, tu) stack_ty) eq * (ta, ts) stack_ty * context) - tzresult = - fun ctxt lvl stack1 stack2 -> - match (stack1, stack2) with - | (Bot_t, Bot_t) -> ok (Eq, Bot_t, ctxt) - | (Item_t (ty1, rest1, annot1), Item_t (ty2, rest2, annot2)) -> - Gas_monad.run ctxt - @@ merge_types - ~merge_type_error_flag:Default_merge_type_error - ~legacy - loc - ty1 - ty2 - |> record_trace (Bad_stack_item lvl) - >>? fun (eq_ty, ctxt) -> - eq_ty >>? fun (Eq, ty) -> - help ctxt (lvl + 1) rest1 rest2 >|? fun (Eq, rest, ctxt) -> - let annot = merge_var_annot annot1 annot2 in - ( (Eq : ((ta, ts) stack_ty, (tb, tu) stack_ty) eq), - Item_t (ty, rest, annot), - ctxt ) - | (_, _) -> error Bad_stack_length - in - help - -(* ---- Type checker results -------------------------------------------------*) - -type ('a, 's) judgement = - | Typed : ('a, 's, 'b, 'u) descr -> ('a, 's) judgement - | Failed : { - descr : 'b 'u. ('b, 'u) stack_ty -> ('a, 's, 'b, 'u) descr; - } - -> ('a, 's) judgement - -(* ---- Type checker (Untyped expressions -> Typed IR) ----------------------*) - -type ('a, 's, 'b, 'u, 'c, 'v) branch = { - branch : - 'r 'f. - ('a, 's, 'r, 'f) descr -> ('b, 'u, 'r, 'f) descr -> ('c, 'v, 'r, 'f) descr; -} -[@@unboxed] - -let merge_branches : - type a s b u c v. - legacy:bool -> - context -> - Script.location -> - (a, s) judgement -> - (b, u) judgement -> - (a, s, b, u, c, v) branch -> - ((c, v) judgement * context) tzresult = - fun ~legacy ctxt loc btr bfr {branch} -> - match (btr, bfr) with - | (Typed ({aft = aftbt; _} as dbt), Typed ({aft = aftbf; _} as dbf)) -> - let unmatched_branches () = - let aftbt = serialize_stack_for_error ctxt aftbt in - let aftbf = serialize_stack_for_error ctxt aftbf in - Unmatched_branches (loc, aftbt, aftbf) - in - record_trace_eval - unmatched_branches - ( merge_stacks ~legacy loc ctxt 1 aftbt aftbf - >|? fun (Eq, merged_stack, ctxt) -> - ( Typed - (branch - {dbt with aft = merged_stack} - {dbf with aft = merged_stack}), - ctxt ) ) - | (Failed {descr = descrt}, Failed {descr = descrf}) -> - let descr ret = branch (descrt ret) (descrf ret) in - ok (Failed {descr}, ctxt) - | (Typed dbt, Failed {descr = descrf}) -> - ok (Typed (branch dbt (descrf dbt.aft)), ctxt) - | (Failed {descr = descrt}, Typed dbf) -> - ok (Typed (branch (descrt dbf.aft) dbf), ctxt) - -let parse_memo_size (n : (location, _) Micheline.node) : - Sapling.Memo_size.t tzresult = - match n with - | Int (_, z) -> ( - match Sapling.Memo_size.parse_z z with - | Ok _ as ok_memo_size -> ok_memo_size [@coq_cast] - | Error msg -> - error - @@ Invalid_syntactic_constant (location n, strip_locations n, msg)) - | _ -> error @@ Invalid_kind (location n, [Int_kind], kind n) - -type ex_comparable_ty = - | Ex_comparable_ty : 'a comparable_ty -> ex_comparable_ty - -let[@coq_struct "ty"] rec parse_comparable_ty : - stack_depth:int -> - context -> - Script.node -> - (ex_comparable_ty * context) tzresult = - fun ~stack_depth ctxt ty -> - Gas.consume ctxt Typecheck_costs.parse_type_cycle >>? fun ctxt -> - if Compare.Int.(stack_depth > 10000) then - error Typechecking_too_many_recursive_calls - else - match ty with - | Prim (loc, T_unit, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (unit_key ~annot), ctxt) - | Prim (loc, T_never, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (never_key ~annot), ctxt) - | Prim (loc, T_int, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (int_key ~annot), ctxt) - | Prim (loc, T_nat, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (nat_key ~annot), ctxt) - | Prim (loc, T_signature, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (signature_key ~annot), ctxt) - | Prim (loc, T_string, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (string_key ~annot), ctxt) - | Prim (loc, T_bytes, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (bytes_key ~annot), ctxt) - | Prim (loc, T_mutez, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (mutez_key ~annot), ctxt) - | Prim (loc, T_bool, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (bool_key ~annot), ctxt) - | Prim (loc, T_key_hash, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (key_hash_key ~annot), ctxt) - | Prim (loc, T_key, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (key_key ~annot), ctxt) - | Prim (loc, T_timestamp, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (timestamp_key ~annot), ctxt) - | Prim (loc, T_chain_id, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (chain_id_key ~annot), ctxt) - | Prim (loc, T_address, [], annot) -> - parse_type_annot loc annot >|? fun annot -> - (Ex_comparable_ty (address_key ~annot), ctxt) - | Prim - ( loc, - (( T_unit | T_never | T_int | T_nat | T_string | T_bytes | T_mutez - | T_bool | T_key_hash | T_timestamp | T_address | T_chain_id - | T_signature | T_key ) as prim), - l, - _ ) -> - error (Invalid_arity (loc, prim, 0, List.length l)) - | Prim (loc, T_pair, left :: right, annot) -> - parse_type_annot loc annot >>? fun annot -> - extract_field_annot left >>? fun (left, left_annot) -> - (match right with - | [right] -> extract_field_annot right - | right -> - (* Unfold [pair t1 ... tn] as [pair t1 (... (pair tn-1 tn))] *) - ok (Prim (loc, T_pair, right, []), None)) - >>? fun (right, right_annot) -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt right - >>? fun (Ex_comparable_ty right, ctxt) -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt left - >>? fun (Ex_comparable_ty left, ctxt) -> - pair_key loc (left, left_annot) (right, right_annot) ~annot - >|? fun ty -> (Ex_comparable_ty ty, ctxt) - | Prim (loc, T_or, [left; right], annot) -> - parse_type_annot loc annot >>? fun annot -> - extract_field_annot left >>? fun (left, left_annot) -> - extract_field_annot right >>? fun (right, right_annot) -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt right - >>? fun (Ex_comparable_ty right, ctxt) -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt left - >>? fun (Ex_comparable_ty left, ctxt) -> - union_key loc (left, left_annot) (right, right_annot) ~annot - >|? fun ty -> (Ex_comparable_ty ty, ctxt) - | Prim (loc, ((T_pair | T_or) as prim), l, _) -> - error (Invalid_arity (loc, prim, 2, List.length l)) - | Prim (loc, T_option, [t], annot) -> - parse_type_annot loc annot >>? fun annot -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt t - >>? fun (Ex_comparable_ty t, ctxt) -> - option_key loc t ~annot >|? fun ty -> (Ex_comparable_ty ty, ctxt) - | Prim (loc, T_option, l, _) -> - error (Invalid_arity (loc, T_option, 1, List.length l)) - | Prim - ( loc, - (T_set | T_map | T_list | T_lambda | T_contract | T_operation), - _, - _ ) -> - error (Comparable_type_expected (loc, Micheline.strip_locations ty)) - | expr -> - error - @@ unexpected - expr - [] - Type_namespace - [ - T_unit; - T_never; - T_int; - T_nat; - T_string; - T_bytes; - T_mutez; - T_bool; - T_key_hash; - T_timestamp; - T_address; - T_pair; - T_or; - T_option; - T_chain_id; - T_signature; - T_key; - ] - -type ex_ty = Ex_ty : 'a ty -> ex_ty - -let[@coq_axiom_with_reason "complex mutually recursive definition"] rec parse_packable_ty - : - context -> - stack_depth:int -> - legacy:bool -> - Script.node -> - (ex_ty * context) tzresult = - fun ctxt ~stack_depth ~legacy -> - (parse_ty [@tailcall]) - ctxt - ~stack_depth - ~legacy - ~allow_lazy_storage:false - ~allow_operation:false - ~allow_contract: - legacy - (* type contract is forbidden in UNPACK because of - https://gitlab.com/tezos/tezos/-/issues/301 *) - ~allow_ticket:false - -and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_parameter_ty - : - context -> - stack_depth:int -> - legacy:bool -> - Script.node -> - (ex_ty * context) tzresult = - fun ctxt ~stack_depth ~legacy -> - (parse_ty [@tailcall]) - ctxt - ~stack_depth - ~legacy - ~allow_lazy_storage:true - ~allow_operation:false - ~allow_contract:true - ~allow_ticket:true - -and parse_view_input_ty : - context -> - stack_depth:int -> - legacy:bool -> - Script.node -> - (ex_ty * context) tzresult = - fun ctxt ~stack_depth ~legacy -> - (parse_ty [@tailcall]) - ctxt - ~stack_depth - ~legacy - ~allow_lazy_storage:false - ~allow_operation:false - ~allow_contract:true - ~allow_ticket:false - -and parse_view_output_ty : - context -> - stack_depth:int -> - legacy:bool -> - Script.node -> - (ex_ty * context) tzresult = - fun ctxt ~stack_depth ~legacy -> - (parse_ty [@tailcall]) - ctxt - ~stack_depth - ~legacy - ~allow_lazy_storage:false - ~allow_operation:false - ~allow_contract:true - ~allow_ticket:false - -and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_normal_storage_ty - : - context -> - stack_depth:int -> - legacy:bool -> - Script.node -> - (ex_ty * context) tzresult = - fun ctxt ~stack_depth ~legacy -> - (parse_ty [@tailcall]) - ctxt - ~stack_depth - ~legacy - ~allow_lazy_storage:true - ~allow_operation:false - ~allow_contract:legacy - ~allow_ticket:true - -and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_any_ty - : - context -> - stack_depth:int -> - legacy:bool -> - Script.node -> - (ex_ty * context) tzresult = - fun ctxt ~stack_depth ~legacy -> - (parse_ty [@tailcall]) - ctxt - ~stack_depth - ~legacy - ~allow_lazy_storage:true - ~allow_operation:true - ~allow_contract:true - ~allow_ticket:true - -and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_ty : - context -> - stack_depth:int -> - legacy:bool -> - allow_lazy_storage:bool -> - allow_operation:bool -> - allow_contract:bool -> - allow_ticket:bool -> - Script.node -> - (ex_ty * context) tzresult = - fun ctxt - ~stack_depth - ~legacy - ~allow_lazy_storage - ~allow_operation - ~allow_contract - ~allow_ticket - node -> - Gas.consume ctxt Typecheck_costs.parse_type_cycle >>? fun ctxt -> - if Compare.Int.(stack_depth > 10000) then - error Typechecking_too_many_recursive_calls - else - match node with - | Prim (loc, T_unit, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (unit_t ~annot), ctxt) - | Prim (loc, T_int, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (int_t ~annot), ctxt) - | Prim (loc, T_nat, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (nat_t ~annot), ctxt) - | Prim (loc, T_string, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (string_t ~annot), ctxt) - | Prim (loc, T_bytes, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (bytes_t ~annot), ctxt) - | Prim (loc, T_mutez, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (mutez_t ~annot), ctxt) - | Prim (loc, T_bool, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (bool_t ~annot), ctxt) - | Prim (loc, T_key, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (key_t ~annot), ctxt) - | Prim (loc, T_key_hash, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (key_hash_t ~annot), ctxt) - | Prim (loc, T_chest_key, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (chest_key_t ~annot), ctxt) - | Prim (loc, T_chest, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (chest_t ~annot), ctxt) - | Prim (loc, T_timestamp, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (timestamp_t ~annot), ctxt) - | Prim (loc, T_address, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (address_t ~annot), ctxt) - | Prim (loc, T_signature, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (signature_t ~annot), ctxt) - | Prim (loc, T_operation, [], annot) -> - if allow_operation then - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (operation_t ~annot), ctxt) - else error (Unexpected_operation loc) - | Prim (loc, T_chain_id, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (chain_id_t ~annot), ctxt) - | Prim (loc, T_never, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (never_t ~annot), ctxt) - | Prim (loc, T_bls12_381_g1, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (bls12_381_g1_t ~annot), ctxt) - | Prim (loc, T_bls12_381_g2, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (bls12_381_g2_t ~annot), ctxt) - | Prim (loc, T_bls12_381_fr, [], annot) -> - parse_type_annot loc annot >>? fun annot -> - ok (Ex_ty (bls12_381_fr_t ~annot), ctxt) - | Prim (loc, T_contract, [utl], annot) -> - if allow_contract then - parse_parameter_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy utl - >>? fun (Ex_ty tl, ctxt) -> - parse_type_annot loc annot >>? fun annot -> - contract_t loc tl ~annot >|? fun ty -> (Ex_ty ty, ctxt) - else error (Unexpected_contract loc) - | Prim (loc, T_pair, utl :: utr, annot) -> - extract_field_annot utl >>? fun (utl, left_field) -> - parse_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - ~allow_lazy_storage - ~allow_operation - ~allow_contract - ~allow_ticket - utl - >>? fun (Ex_ty tl, ctxt) -> - (match utr with - | [utr] -> extract_field_annot utr - | utr -> - (* Unfold [pair t1 ... tn] as [pair t1 (... (pair tn-1 tn))] *) - ok (Prim (loc, T_pair, utr, []), None)) - >>? fun (utr, right_field) -> - parse_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - ~allow_lazy_storage - ~allow_operation - ~allow_contract - ~allow_ticket - utr - >>? fun (Ex_ty tr, ctxt) -> - parse_type_annot loc annot >>? fun annot -> - pair_t loc (tl, left_field, None) (tr, right_field, None) ~annot - >|? fun ty -> (Ex_ty ty, ctxt) - | Prim (loc, T_or, [utl; utr], annot) -> - extract_field_annot utl >>? fun (utl, left_constr) -> - extract_field_annot utr >>? fun (utr, right_constr) -> - parse_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - ~allow_lazy_storage - ~allow_operation - ~allow_contract - ~allow_ticket - utl - >>? fun (Ex_ty tl, ctxt) -> - parse_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - ~allow_lazy_storage - ~allow_operation - ~allow_contract - ~allow_ticket - utr - >>? fun (Ex_ty tr, ctxt) -> - parse_type_annot loc annot >>? fun annot -> - union_t loc (tl, left_constr) (tr, right_constr) ~annot >|? fun ty -> - (Ex_ty ty, ctxt) - | Prim (loc, T_lambda, [uta; utr], annot) -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy uta - >>? fun (Ex_ty ta, ctxt) -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy utr - >>? fun (Ex_ty tr, ctxt) -> - parse_type_annot loc annot >>? fun annot -> - lambda_t loc ta tr ~annot >|? fun ty -> (Ex_ty ty, ctxt) - | Prim (loc, T_option, [ut], annot) -> - (if legacy then - (* legacy semantics with (broken) field annotations *) - extract_field_annot ut >>? fun (ut, _some_constr) -> - parse_composed_type_annot loc annot - >>? fun (ty_name, _none_constr, _) -> ok (ut, ty_name) - else parse_type_annot loc annot >>? fun annot -> ok (ut, annot)) - >>? fun (ut, annot) -> - parse_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - ~allow_lazy_storage - ~allow_operation - ~allow_contract - ~allow_ticket - ut - >>? fun (Ex_ty t, ctxt) -> - option_t loc t ~annot >|? fun ty -> (Ex_ty ty, ctxt) - | Prim (loc, T_list, [ut], annot) -> - parse_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - ~allow_lazy_storage - ~allow_operation - ~allow_contract - ~allow_ticket - ut - >>? fun (Ex_ty t, ctxt) -> - parse_type_annot loc annot >>? fun annot -> - list_t loc t ~annot >|? fun ty -> (Ex_ty ty, ctxt) - | Prim (loc, T_ticket, [ut], annot) -> - if allow_ticket then - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt ut - >>? fun (Ex_comparable_ty t, ctxt) -> - parse_type_annot loc annot >>? fun annot -> - ticket_t loc t ~annot >|? fun ty -> (Ex_ty ty, ctxt) - else error (Unexpected_ticket loc) - | Prim (loc, T_set, [ut], annot) -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt ut - >>? fun (Ex_comparable_ty t, ctxt) -> - parse_type_annot loc annot >>? fun annot -> - set_t loc t ~annot >|? fun ty -> (Ex_ty ty, ctxt) - | Prim (loc, T_map, [uta; utr], annot) -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt uta - >>? fun (Ex_comparable_ty ta, ctxt) -> - parse_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - ~allow_lazy_storage - ~allow_operation - ~allow_contract - ~allow_ticket - utr - >>? fun (Ex_ty tr, ctxt) -> - parse_type_annot loc annot >>? fun annot -> - map_t loc ta tr ~annot >|? fun ty -> (Ex_ty ty, ctxt) - | Prim (loc, T_sapling_transaction, [memo_size], annot) -> - parse_type_annot loc annot >>? fun annot -> - parse_memo_size memo_size >|? fun memo_size -> - (Ex_ty (sapling_transaction_t ~memo_size ~annot), ctxt) - (* - /!\ When adding new lazy storage kinds, be careful to use - [when allow_lazy_storage] /!\ - Lazy storage should not be packable to avoid stealing a lazy storage - from another contract with `PUSH t id` or `UNPACK`. - *) - | Prim (loc, T_big_map, args, annot) when allow_lazy_storage -> - (parse_big_map_ty [@tailcall]) ctxt ~stack_depth ~legacy loc args annot - | Prim (loc, T_sapling_state, [memo_size], annot) when allow_lazy_storage -> - parse_type_annot loc annot >>? fun annot -> - parse_memo_size memo_size >|? fun memo_size -> - (Ex_ty (sapling_state_t ~memo_size ~annot), ctxt) - | Prim (loc, (T_big_map | T_sapling_state), _, _) -> - error (Unexpected_lazy_storage loc) - | Prim - ( loc, - (( T_unit | T_signature | T_int | T_nat | T_string | T_bytes | T_mutez - | T_bool | T_key | T_key_hash | T_timestamp | T_address | T_chain_id - | T_operation | T_never ) as prim), - l, - _ ) -> - error (Invalid_arity (loc, prim, 0, List.length l)) - | Prim - ( loc, - ((T_set | T_list | T_option | T_contract | T_ticket) as prim), - l, - _ ) -> - error (Invalid_arity (loc, prim, 1, List.length l)) - | Prim (loc, ((T_pair | T_or | T_map | T_lambda) as prim), l, _) -> - error (Invalid_arity (loc, prim, 2, List.length l)) - | expr -> - error - @@ unexpected - expr - [] - Type_namespace - [ - T_pair; - T_or; - T_set; - T_map; - T_list; - T_option; - T_lambda; - T_unit; - T_signature; - T_contract; - T_int; - T_nat; - T_operation; - T_string; - T_bytes; - T_mutez; - T_bool; - T_key; - T_key_hash; - T_timestamp; - T_chain_id; - T_never; - T_bls12_381_g1; - T_bls12_381_g2; - T_bls12_381_fr; - T_ticket; - ] - -and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_big_map_ty - ctxt ~stack_depth ~legacy big_map_loc args map_annot = - Gas.consume ctxt Typecheck_costs.parse_type_cycle >>? fun ctxt -> - match args with - | [key_ty; value_ty] -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt key_ty - >>? fun (Ex_comparable_ty key_ty, ctxt) -> - parse_big_map_value_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - value_ty - >>? fun (Ex_ty value_ty, ctxt) -> - parse_type_annot big_map_loc map_annot >>? fun annot -> - big_map_t big_map_loc key_ty value_ty ~annot >|? fun big_map_ty -> - (Ex_ty big_map_ty, ctxt) - | args -> error @@ Invalid_arity (big_map_loc, T_big_map, 2, List.length args) - -and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_big_map_value_ty - ctxt ~stack_depth ~legacy value_ty = - (parse_ty [@tailcall]) - ctxt - ~stack_depth - ~legacy - ~allow_lazy_storage:false - ~allow_operation:false - ~allow_contract:legacy - ~allow_ticket:true - value_ty - -let parse_storage_ty : - context -> - stack_depth:int -> - legacy:bool -> - Script.node -> - (ex_ty * context) tzresult = - fun ctxt ~stack_depth ~legacy node -> - match node with - | Prim - ( loc, - T_pair, - [Prim (big_map_loc, T_big_map, args, map_annot); remaining_storage], - storage_annot ) - when legacy -> ( - match storage_annot with - | [] -> - (parse_normal_storage_ty [@tailcall]) ctxt ~stack_depth ~legacy node - | [single] - when Compare.Int.(String.length single > 0) - && Compare.Char.(single.[0] = '%') -> - (parse_normal_storage_ty [@tailcall]) ctxt ~stack_depth ~legacy node - | _ -> - (* legacy semantics of big maps used the wrong annotation parser *) - Gas.consume ctxt Typecheck_costs.parse_type_cycle >>? fun ctxt -> - parse_big_map_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - big_map_loc - args - map_annot - >>? fun (Ex_ty big_map_ty, ctxt) -> - parse_normal_storage_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - remaining_storage - >>? fun (Ex_ty remaining_storage, ctxt) -> - parse_composed_type_annot loc storage_annot - >>? fun (annot, map_field, storage_field) -> - pair_t - loc - (big_map_ty, map_field, None) - (remaining_storage, storage_field, None) - ~annot - >|? fun ty -> (Ex_ty ty, ctxt)) - | _ -> (parse_normal_storage_ty [@tailcall]) ctxt ~stack_depth ~legacy node - -let check_packable ~legacy loc root = - let rec check : type t. t ty -> unit tzresult = function - (* /!\ When adding new lazy storage kinds, be sure to return an error. /!\ - Lazy storage should not be packable. *) - | Big_map_t _ -> error (Unexpected_lazy_storage loc) - | Sapling_state_t _ -> error (Unexpected_lazy_storage loc) - | Operation_t _ -> error (Unexpected_operation loc) - | Unit_t _ -> Result.return_unit - | Int_t _ -> Result.return_unit - | Nat_t _ -> Result.return_unit - | Signature_t _ -> Result.return_unit - | String_t _ -> Result.return_unit - | Bytes_t _ -> Result.return_unit - | Mutez_t _ -> Result.return_unit - | Key_hash_t _ -> Result.return_unit - | Key_t _ -> Result.return_unit - | Timestamp_t _ -> Result.return_unit - | Address_t _ -> Result.return_unit - | Bool_t _ -> Result.return_unit - | Chain_id_t _ -> Result.return_unit - | Never_t _ -> Result.return_unit - | Set_t (_, _) -> Result.return_unit - | Ticket_t _ -> error (Unexpected_ticket loc) - | Lambda_t (_, _, _) -> Result.return_unit - | Bls12_381_g1_t _ -> Result.return_unit - | Bls12_381_g2_t _ -> Result.return_unit - | Bls12_381_fr_t _ -> Result.return_unit - | Pair_t ((l_ty, _, _), (r_ty, _, _), _) -> - check l_ty >>? fun () -> check r_ty - | Union_t ((l_ty, _), (r_ty, _), _) -> check l_ty >>? fun () -> check r_ty - | Option_t (v_ty, _) -> check v_ty - | List_t (elt_ty, _) -> check elt_ty - | Map_t (_, elt_ty, _) -> check elt_ty - | Contract_t (_, _) when legacy -> Result.return_unit - | Contract_t (_, _) -> error (Unexpected_contract loc) - | Sapling_transaction_t _ -> ok () - | Chest_key_t _ -> Result.return_unit - | Chest_t _ -> Result.return_unit - in - check root - -type toplevel = { - code_field : Script.node; - arg_type : Script.node; - storage_type : Script.node; - views : view SMap.t; - root_name : field_annot option; -} - -type ('arg, 'storage) code = { - code : (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; - arg_type : 'arg ty; - storage_type : 'storage ty; - views : view SMap.t; - root_name : field_annot option; - code_size : Cache_memory_helpers.sint; -} - -type ex_script = Ex_script : ('a, 'c) script -> ex_script - -type ex_code = Ex_code : ('a, 'c) code -> ex_code - -type 'storage ex_view = - | Ex_view : - ('input * 'storage, 'output) Script_typed_ir.lambda - -> 'storage ex_view - -type (_, _) dig_proof_argument = - | Dig_proof_argument : - ('x, 'a * 's, 'a, 's, 'b, 't, 'c, 'u) stack_prefix_preservation_witness - * 'x ty - * var_annot option - * ('c, 'u) stack_ty - -> ('b, 't) dig_proof_argument - -type (_, _, _) dug_proof_argument = - | Dug_proof_argument : - (('a, 's, 'x, 'a * 's, 'b, 't, 'c, 'u) stack_prefix_preservation_witness - * ('c, 'u) stack_ty) - -> ('b, 't, 'x) dug_proof_argument - -type (_, _) dipn_proof_argument = - | Dipn_proof_argument : - ('fa, 'fs, 'fb, 'fu, 'a, 's, 'b, 'u) stack_prefix_preservation_witness - * context - * ('fa, 'fs, 'fb, 'fu) descr - * ('b, 'u) stack_ty - -> ('a, 's) dipn_proof_argument - -type (_, _) dropn_proof_argument = - | Dropn_proof_argument : - ('fa, 'fs, 'fa, 'fs, 'a, 's, 'a, 's) stack_prefix_preservation_witness - * ('fa, 'fs) stack_ty - -> ('a, 's) dropn_proof_argument - -type 'before comb_proof_argument = - | Comb_proof_argument : - ('a * 's, 'b * 'u) comb_gadt_witness * ('b, 'u) stack_ty - -> ('a * 's) comb_proof_argument - -type 'before uncomb_proof_argument = - | Uncomb_proof_argument : - ('a * 's, 'b * 'u) uncomb_gadt_witness * ('b, 'u) stack_ty - -> ('a * 's) uncomb_proof_argument - -type 'before comb_get_proof_argument = - | Comb_get_proof_argument : - ('before, 'after) comb_get_gadt_witness * 'after ty - -> 'before comb_get_proof_argument - -type ('rest, 'before) comb_set_proof_argument = - | Comb_set_proof_argument : - ('rest, 'before, 'after) comb_set_gadt_witness * 'after ty - -> ('rest, 'before) comb_set_proof_argument - -type 'before dup_n_proof_argument = - | Dup_n_proof_argument : - ('before, 'a) dup_n_gadt_witness * 'a ty - -> 'before dup_n_proof_argument - -let find_entrypoint (type full) (full : full ty) ~root_name entrypoint = - let annot_is_entrypoint entrypoint = function - | None -> false - | Some (Field_annot l) -> Compare.String.((l :> string) = entrypoint) - in - let loc = Micheline.dummy_location in - let rec find_entrypoint : - type t. t ty -> string -> ((Script.node -> Script.node) * ex_ty) option = - fun t entrypoint -> - match t with - | Union_t ((tl, al), (tr, ar), _) -> ( - if annot_is_entrypoint entrypoint al then - Some ((fun e -> Prim (loc, D_Left, [e], [])), Ex_ty tl) - else if annot_is_entrypoint entrypoint ar then - Some ((fun e -> Prim (loc, D_Right, [e], [])), Ex_ty tr) - else - match find_entrypoint tl entrypoint with - | Some (f, t) -> Some ((fun e -> Prim (loc, D_Left, [f e], [])), t) - | None -> ( - match find_entrypoint tr entrypoint with - | Some (f, t) -> - Some ((fun e -> Prim (loc, D_Right, [f e], [])), t) - | None -> None)) - | _ -> None - in - let entrypoint = - if Compare.String.(entrypoint = "") then "default" else entrypoint - in - if Compare.Int.(String.length entrypoint > 31) then - error (Entrypoint_name_too_long entrypoint) - else - match root_name with - | Some (Field_annot root_name) - when Compare.String.(entrypoint = (root_name :> string)) -> - ok ((fun e -> e), Ex_ty full) - | _ -> ( - match find_entrypoint full entrypoint with - | Some result -> ok result - | None -> ( - match entrypoint with - | "default" -> ok ((fun e -> e), Ex_ty full) - | _ -> error (No_such_entrypoint entrypoint))) - -let find_entrypoint_for_type (type full exp) ~legacy ~merge_type_error_flag - ~(full : full ty) ~(expected : exp ty) ~root_name entrypoint loc : - (string * exp ty, error trace) Gas_monad.t = - let open Gas_monad in - match find_entrypoint full ~root_name entrypoint with - | Error _ as err -> of_result err - | Ok (_, Ex_ty ty) -> ( - merge_types ~legacy ~merge_type_error_flag loc ty expected - >??$ fun eq_ty -> - match (entrypoint, root_name) with - | ("default", Some (Field_annot fa)) - when Compare.String.((fa :> string) = "root") -> ( - match eq_ty with - | Ok (Eq, ty) -> return ("default", (ty : exp ty)) - | Error _ -> - merge_types ~legacy ~merge_type_error_flag loc full expected - >?$ fun (Eq, full) -> ok ("root", (full : exp ty))) - | _ -> of_result (eq_ty >|? fun (Eq, ty) -> (entrypoint, (ty : exp ty)))) - -module Entrypoints = Set.Make (String) - -let well_formed_entrypoints (type full) (full : full ty) ~root_name = - let merge path annot (type t) (ty : t ty) reachable - ((first_unreachable, all) as acc) = - match annot with - | None -> - ok - (if reachable then acc - else - match ty with - | Union_t _ -> acc - | _ -> ( - match first_unreachable with - | None -> (Some (List.rev path), all) - | Some _ -> acc)) - | Some (Field_annot name) -> - let name = (name :> string) in - if Compare.Int.(String.length name > 31) then - error (Entrypoint_name_too_long name) - else if Entrypoints.mem name all then error (Duplicate_entrypoint name) - else ok (first_unreachable, Entrypoints.add name all) - in - let rec check : - type t. - t ty -> - prim list -> - bool -> - prim list option * Entrypoints.t -> - (prim list option * Entrypoints.t) tzresult = - fun t path reachable acc -> - match t with - | Union_t ((tl, al), (tr, ar), _) -> - merge (D_Left :: path) al tl reachable acc >>? fun acc -> - merge (D_Right :: path) ar tr reachable acc >>? fun acc -> - check - tl - (D_Left :: path) - (match al with Some _ -> true | None -> reachable) - acc - >>? fun acc -> - check - tr - (D_Right :: path) - (match ar with Some _ -> true | None -> reachable) - acc - | _ -> ok acc - in - let (init, reachable) = - match root_name with - | None -> (Entrypoints.empty, false) - | Some (Field_annot name) -> (Entrypoints.singleton (name :> string), true) - in - check full [] reachable (None, init) >>? fun (first_unreachable, all) -> - if not (Entrypoints.mem "default" all) then Result.return_unit - else - match first_unreachable with - | None -> Result.return_unit - | Some path -> error (Unreachable_entrypoint path) - -let parse_uint ~nb_bits = - assert (Compare.Int.(nb_bits >= 0 && nb_bits <= 30)) ; - let max_int = (1 lsl nb_bits) - 1 in - let max_z = Z.of_int max_int in - function - | Micheline.Int (_, n) when Compare.Z.(Z.zero <= n) && Compare.Z.(n <= max_z) - -> - ok (Z.to_int n) - | node -> - error - @@ Invalid_syntactic_constant - ( location node, - strip_locations node, - "a positive " ^ string_of_int nb_bits - ^ "-bit integer (between 0 and " ^ string_of_int max_int ^ ")" ) - -let parse_uint10 = parse_uint ~nb_bits:10 - -let parse_uint11 = parse_uint ~nb_bits:11 - -(* This type is used to: - - serialize and deserialize tickets when they are stored or transferred, - - type the READ_TICKET instruction. *) -let opened_ticket_type loc ty = - pair_3_key - loc - (address_key ~annot:None, None) - (ty, None) - (nat_key ~annot:None, None) - -(* -- parse data of primitive types -- *) - -let parse_unit ctxt ~legacy = function - | Prim (loc, D_Unit, [], annot) -> - (if legacy then Result.return_unit else error_unexpected_annot loc annot) - >>? fun () -> - Gas.consume ctxt Typecheck_costs.unit >|? fun ctxt -> ((), ctxt) - | Prim (loc, D_Unit, l, _) -> - error @@ Invalid_arity (loc, D_Unit, 0, List.length l) - | expr -> error @@ unexpected expr [] Constant_namespace [D_Unit] - -let parse_bool ctxt ~legacy = function - | Prim (loc, D_True, [], annot) -> - (if legacy then Result.return_unit else error_unexpected_annot loc annot) - >>? fun () -> - Gas.consume ctxt Typecheck_costs.bool >|? fun ctxt -> (true, ctxt) - | Prim (loc, D_False, [], annot) -> - (if legacy then Result.return_unit else error_unexpected_annot loc annot) - >>? fun () -> - Gas.consume ctxt Typecheck_costs.bool >|? fun ctxt -> (false, ctxt) - | Prim (loc, ((D_True | D_False) as c), l, _) -> - error @@ Invalid_arity (loc, c, 0, List.length l) - | expr -> error @@ unexpected expr [] Constant_namespace [D_True; D_False] - -let parse_string ctxt : Script.node -> (Script_string.t * context) tzresult = - function - | String (loc, v) as expr -> - Gas.consume ctxt (Typecheck_costs.check_printable v) >>? fun ctxt -> - record_trace - (Invalid_syntactic_constant - (loc, strip_locations expr, "a printable ascii string")) - (Script_string.of_string v >|? fun s -> (s, ctxt)) - | expr -> error @@ Invalid_kind (location expr, [String_kind], kind expr) - -let parse_bytes ctxt = function - | Bytes (_, v) -> ok (v, ctxt) - | expr -> error @@ Invalid_kind (location expr, [Bytes_kind], kind expr) - -let parse_int ctxt = function - | Int (_, v) -> ok (Script_int.of_zint v, ctxt) - | expr -> error @@ Invalid_kind (location expr, [Int_kind], kind expr) - -let parse_nat ctxt : - Script.node -> (Script_int.n Script_int.num * context) tzresult = function - | Int (loc, v) as expr -> ( - let v = Script_int.of_zint v in - match Script_int.is_nat v with - | Some nat -> ok (nat, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a non-negative integer")) - | expr -> error @@ Invalid_kind (location expr, [Int_kind], kind expr) - -let parse_mutez ctxt : Script.node -> (Tez.t * context) tzresult = function - | Int (loc, v) as expr -> ( - match - let open Option in - bind (catch (fun () -> Z.to_int64 v)) Tez.of_mutez - with - | Some tez -> Ok (tez, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid mutez amount")) - | expr -> error @@ Invalid_kind (location expr, [Int_kind], kind expr) - -let parse_timestamp ctxt : - Script.node -> (Script_timestamp.t * context) tzresult = function - | Int (_, v) (* As unparsed with [Optimized] or out of bounds [Readable]. *) - -> - ok (Script_timestamp.of_zint v, ctxt) - | String (loc, s) as expr (* As unparsed with [Readable]. *) -> ( - Gas.consume ctxt Typecheck_costs.timestamp_readable >>? fun ctxt -> - match Script_timestamp.of_string s with - | Some v -> ok (v, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid timestamp")) - | expr -> - error @@ Invalid_kind (location expr, [String_kind; Int_kind], kind expr) - -let parse_key ctxt : Script.node -> (public_key * context) tzresult = function - | Bytes (loc, bytes) as expr -> ( - (* As unparsed with [Optimized]. *) - Gas.consume ctxt Typecheck_costs.public_key_optimized - >>? fun ctxt -> - match - Data_encoding.Binary.of_bytes_opt Signature.Public_key.encoding bytes - with - | Some k -> ok (k, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid public key")) - | String (loc, s) as expr -> ( - (* As unparsed with [Readable]. *) - Gas.consume ctxt Typecheck_costs.public_key_readable - >>? fun ctxt -> - match Signature.Public_key.of_b58check_opt s with - | Some k -> ok (k, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid public key")) - | expr -> - error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) - -let parse_key_hash ctxt : Script.node -> (public_key_hash * context) tzresult = - function - | Bytes (loc, bytes) as expr -> ( - (* As unparsed with [Optimized]. *) - Gas.consume ctxt Typecheck_costs.key_hash_optimized - >>? fun ctxt -> - match - Data_encoding.Binary.of_bytes_opt - Signature.Public_key_hash.encoding - bytes - with - | Some k -> ok (k, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid key hash")) - | String (loc, s) as expr (* As unparsed with [Readable]. *) -> ( - Gas.consume ctxt Typecheck_costs.key_hash_readable >>? fun ctxt -> - match Signature.Public_key_hash.of_b58check_opt s with - | Some k -> ok (k, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid key hash")) - | expr -> - error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) - -let parse_signature ctxt : Script.node -> (signature * context) tzresult = - function - | Bytes (loc, bytes) as expr (* As unparsed with [Optimized]. *) -> ( - Gas.consume ctxt Typecheck_costs.signature_optimized >>? fun ctxt -> - match Data_encoding.Binary.of_bytes_opt Signature.encoding bytes with - | Some k -> ok (k, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid signature")) - | String (loc, s) as expr (* As unparsed with [Readable]. *) -> ( - Gas.consume ctxt Typecheck_costs.signature_readable >>? fun ctxt -> - match Signature.of_b58check_opt s with - | Some s -> ok (s, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid signature")) - | expr -> - error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) - -let parse_chain_id ctxt : Script.node -> (Chain_id.t * context) tzresult = - function - | Bytes (loc, bytes) as expr -> ( - Gas.consume ctxt Typecheck_costs.chain_id_optimized >>? fun ctxt -> - match Data_encoding.Binary.of_bytes_opt Chain_id.encoding bytes with - | Some k -> ok (k, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid chain id")) - | String (loc, s) as expr -> ( - Gas.consume ctxt Typecheck_costs.chain_id_readable >>? fun ctxt -> - match Chain_id.of_b58check_opt s with - | Some s -> ok (s, ctxt) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid chain id")) - | expr -> - error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) - -let parse_address ctxt : Script.node -> (address * context) tzresult = function - | Bytes (loc, bytes) as expr (* As unparsed with [Optimized]. *) -> ( - Gas.consume ctxt Typecheck_costs.contract >>? fun ctxt -> - match - Data_encoding.Binary.of_bytes_opt - Data_encoding.(tup2 Contract.encoding Variable.string) - bytes - with - | Some (c, entrypoint) -> ( - if Compare.Int.(String.length entrypoint > 31) then - error (Entrypoint_name_too_long entrypoint) - else - match entrypoint with - | "" -> ok ((c, "default"), ctxt) - | "default" -> error (Unexpected_annotation loc) - | name -> ok ((c, name), ctxt)) - | None -> - error - @@ Invalid_syntactic_constant - (loc, strip_locations expr, "a valid address")) - | String (loc, s) (* As unparsed with [Readable]. *) -> - Gas.consume ctxt Typecheck_costs.contract >>? fun ctxt -> - (match String.index_opt s '%' with - | None -> ok (s, "default") - | Some pos -> ( - let len = String.length s - pos - 1 in - let name = String.sub s (pos + 1) len in - if Compare.Int.(len > 31) then error (Entrypoint_name_too_long name) - else - match (String.sub s 0 pos, name) with - | (addr, "") -> ok (addr, "default") - | (_, "default") -> error @@ Unexpected_annotation loc - | addr_and_name -> ok addr_and_name)) - >>? fun (addr, entrypoint) -> - Contract.of_b58check addr >|? fun c -> ((c, entrypoint), ctxt) - | expr -> - error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) - -let parse_never expr : (never * context) tzresult = - error @@ Invalid_never_expr (location expr) - -(* -- parse data of complex types -- *) - -let parse_pair (type r) parse_l parse_r ctxt ~legacy - (r_comb_witness : (r, unit -> _) comb_witness) expr = - let parse_comb loc l rs = - parse_l ctxt l >>=? fun (l, ctxt) -> - (match (rs, r_comb_witness) with - | ([r], _) -> ok r - | ([], _) -> error @@ Invalid_arity (loc, D_Pair, 2, 1) - | (_ :: _, Comb_Pair _) -> - (* Unfold [Pair x1 ... xn] as [Pair x1 (Pair x2 ... xn-1 xn))] - for type [pair ta (pair tb1 tb2)] and n >= 3 only *) - ok (Prim (loc, D_Pair, rs, [])) - | _ -> error @@ Invalid_arity (loc, D_Pair, 2, 1 + List.length rs)) - >>?= fun r -> - parse_r ctxt r >|=? fun (r, ctxt) -> ((l, r), ctxt) - in - match expr with - | Prim (loc, D_Pair, l :: rs, annot) -> - (if legacy then Result.return_unit else error_unexpected_annot loc annot) - >>?= fun () -> parse_comb loc l rs - | Prim (loc, D_Pair, l, _) -> - fail @@ Invalid_arity (loc, D_Pair, 2, List.length l) - (* Unfold [{x1; ...; xn}] as [Pair x1 x2 ... xn-1 xn] for n >= 2 *) - | Seq (loc, l :: (_ :: _ as rs)) -> parse_comb loc l rs - | Seq (loc, l) -> fail @@ Invalid_seq_arity (loc, 2, List.length l) - | expr -> fail @@ unexpected expr [] Constant_namespace [D_Pair] - -let parse_union parse_l parse_r ctxt ~legacy = function - | Prim (loc, D_Left, [v], annot) -> - (if legacy then Result.return_unit else error_unexpected_annot loc annot) - >>?= fun () -> - parse_l ctxt v >|=? fun (v, ctxt) -> (L v, ctxt) - | Prim (loc, D_Left, l, _) -> - fail @@ Invalid_arity (loc, D_Left, 1, List.length l) - | Prim (loc, D_Right, [v], annot) -> - (if legacy then Result.return_unit else error_unexpected_annot loc annot) - >>?= fun () -> - parse_r ctxt v >|=? fun (v, ctxt) -> (R v, ctxt) - | Prim (loc, D_Right, l, _) -> - fail @@ Invalid_arity (loc, D_Right, 1, List.length l) - | expr -> fail @@ unexpected expr [] Constant_namespace [D_Left; D_Right] - -let parse_option parse_v ctxt ~legacy = function - | Prim (loc, D_Some, [v], annot) -> - (if legacy then Result.return_unit else error_unexpected_annot loc annot) - >>?= fun () -> - parse_v ctxt v >|=? fun (v, ctxt) -> (Some v, ctxt) - | Prim (loc, D_Some, l, _) -> - fail @@ Invalid_arity (loc, D_Some, 1, List.length l) - | Prim (loc, D_None, [], annot) -> - Lwt.return - ( (if legacy then Result.return_unit - else error_unexpected_annot loc annot) - >|? fun () -> (None, ctxt) ) - | Prim (loc, D_None, l, _) -> - fail @@ Invalid_arity (loc, D_None, 0, List.length l) - | expr -> fail @@ unexpected expr [] Constant_namespace [D_Some; D_None] - -(* -- parse data of comparable types -- *) - -let comparable_comb_witness1 : - type t. t comparable_ty -> (t, unit -> unit) comb_witness = function - | Pair_key _ -> Comb_Pair Comb_Any - | _ -> Comb_Any - -let[@coq_axiom_with_reason "gadt"] rec parse_comparable_data : - type a. - ?type_logger:type_logger -> - context -> - a comparable_ty -> - Script.node -> - (a * context) tzresult Lwt.t = - fun ?type_logger ctxt ty script_data -> - (* No need for stack_depth here. Unlike [parse_data], - [parse_comparable_data] doesn't call [parse_returning]. - The stack depth is bounded by the type depth, bounded by 1024. *) - let parse_data_error () = - let ty = serialize_ty_for_error (ty_of_comparable_ty ty) in - Invalid_constant (location script_data, strip_locations script_data, ty) - in - let traced_no_lwt body = record_trace_eval parse_data_error body in - let traced body = trace_eval parse_data_error body in - Gas.consume ctxt Typecheck_costs.parse_data_cycle - (* We could have a smaller cost but let's keep it consistent with - [parse_data] for now. *) - >>?= - fun ctxt -> - let legacy = false in - match (ty, script_data) with - | (Unit_key _, expr) -> - Lwt.return @@ traced_no_lwt - @@ (parse_unit ctxt ~legacy expr : (a * context) tzresult) - | (Bool_key _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_bool ctxt ~legacy expr - | (String_key _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_string ctxt expr - | (Bytes_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_bytes ctxt expr - | (Int_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_int ctxt expr - | (Nat_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_nat ctxt expr - | (Mutez_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_mutez ctxt expr - | (Timestamp_key _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_timestamp ctxt expr - | (Key_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_key ctxt expr - | (Key_hash_key _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_key_hash ctxt expr - | (Signature_key _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_signature ctxt expr - | (Chain_id_key _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_chain_id ctxt expr - | (Address_key _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_address ctxt expr - | (Pair_key ((tl, _), (tr, _), _), expr) -> - let r_witness = comparable_comb_witness1 tr in - let parse_l ctxt v = parse_comparable_data ?type_logger ctxt tl v in - let parse_r ctxt v = parse_comparable_data ?type_logger ctxt tr v in - traced @@ parse_pair parse_l parse_r ctxt ~legacy r_witness expr - | (Union_key ((tl, _), (tr, _), _), expr) -> - let parse_l ctxt v = parse_comparable_data ?type_logger ctxt tl v in - let parse_r ctxt v = parse_comparable_data ?type_logger ctxt tr v in - traced @@ parse_union parse_l parse_r ctxt ~legacy expr - | (Option_key (t, _), expr) -> - let parse_v ctxt v = parse_comparable_data ?type_logger ctxt t v in - traced @@ parse_option parse_v ctxt ~legacy expr - | (Never_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_never expr - -(* -- parse data of any type -- *) - -let comb_witness1 : type t. t ty -> (t, unit -> unit) comb_witness = function - | Pair_t _ -> Comb_Pair Comb_Any - | _ -> Comb_Any - -(* - Some values, such as operations, tickets, or big map ids, are used only - internally and are not allowed to be forged by users. - In [parse_data], [allow_forged] should be [false] for: - - PUSH - - UNPACK - - user-provided script parameters - - storage on origination - And [true] for: - - internal calls parameters - - storage after origination -*) - -let[@coq_axiom_with_reason "gadt"] rec parse_data : - type a. - ?type_logger:type_logger -> - stack_depth:int -> - context -> - legacy:bool -> - allow_forged:bool -> - a ty -> - Script.node -> - (a * context) tzresult Lwt.t = - fun ?type_logger ~stack_depth ctxt ~legacy ~allow_forged ty script_data -> - Gas.consume ctxt Typecheck_costs.parse_data_cycle >>?= fun ctxt -> - let non_terminal_recursion ?type_logger ctxt ~legacy ty script_data = - if Compare.Int.(stack_depth > 10_000) then - fail Typechecking_too_many_recursive_calls - else - parse_data - ?type_logger - ~stack_depth:(stack_depth + 1) - ctxt - ~legacy - ~allow_forged - ty - script_data - in - let parse_data_error () = - let ty = serialize_ty_for_error ty in - Invalid_constant (location script_data, strip_locations script_data, ty) - in - let fail_parse_data () = fail (parse_data_error ()) in - let traced_no_lwt body = record_trace_eval parse_data_error body in - let traced body = trace_eval parse_data_error body in - let traced_fail err = Lwt.return @@ traced_no_lwt (error err) in - let parse_items ?type_logger ctxt expr key_type value_type items item_wrapper - = - List.fold_left_es - (fun (last_value, map, ctxt) item -> - match item with - | Prim (loc, D_Elt, [k; v], annot) -> - (if legacy then Result.return_unit - else error_unexpected_annot loc annot) - >>?= fun () -> - parse_comparable_data ?type_logger ctxt key_type k - >>=? fun (k, ctxt) -> - non_terminal_recursion ?type_logger ctxt ~legacy value_type v - >>=? fun (v, ctxt) -> - Lwt.return - ( (match last_value with - | Some value -> - Gas.consume - ctxt - (Michelson_v1_gas.Cost_of.Interpreter.compare - key_type - value - k) - >>? fun ctxt -> - let c = - Script_comparable.compare_comparable key_type value k - in - if Compare.Int.(0 <= c) then - if Compare.Int.(0 = c) then - error (Duplicate_map_keys (loc, strip_locations expr)) - else - error (Unordered_map_keys (loc, strip_locations expr)) - else ok ctxt - | None -> ok ctxt) - >>? fun ctxt -> - Gas.consume - ctxt - (Michelson_v1_gas.Cost_of.Interpreter.map_update k map) - >|? fun ctxt -> - (Some k, Script_map.update k (Some (item_wrapper v)) map, ctxt) - ) - | Prim (loc, D_Elt, l, _) -> - fail @@ Invalid_arity (loc, D_Elt, 2, List.length l) - | Prim (loc, name, _, _) -> - fail @@ Invalid_primitive (loc, [D_Elt], name) - | Int _ | String _ | Bytes _ | Seq _ -> fail_parse_data ()) - (None, Script_map.empty key_type, ctxt) - items - |> traced - >|=? fun (_, items, ctxt) -> (items, ctxt) - in - let parse_big_map_items (type t) ?type_logger ctxt expr - (key_type : t comparable_ty) value_type items item_wrapper = - List.fold_left_es - (fun (last_key, {map; size}, ctxt) item -> - match item with - | Prim (loc, D_Elt, [k; v], annot) -> - (if legacy then Result.return_unit - else error_unexpected_annot loc annot) - >>?= fun () -> - parse_comparable_data ?type_logger ctxt key_type k - >>=? fun (k, ctxt) -> - hash_comparable_data ctxt key_type k >>=? fun (key_hash, ctxt) -> - non_terminal_recursion ?type_logger ctxt ~legacy value_type v - >>=? fun (v, ctxt) -> - Lwt.return - ( (match last_key with - | Some last_key -> - Gas.consume - ctxt - (Michelson_v1_gas.Cost_of.Interpreter.compare - key_type - last_key - k) - >>? fun ctxt -> - let c = - Script_comparable.compare_comparable key_type last_key k - in - if Compare.Int.(0 <= c) then - if Compare.Int.(0 = c) then - error (Duplicate_map_keys (loc, strip_locations expr)) - else - error (Unordered_map_keys (loc, strip_locations expr)) - else ok ctxt - | None -> ok ctxt) - >>? fun ctxt -> - Gas.consume - ctxt - (Michelson_v1_gas.Cost_of.Interpreter.big_map_update - {map; size}) - >>? fun ctxt -> - if Big_map_overlay.mem key_hash map then - error (Duplicate_map_keys (loc, strip_locations expr)) - else - ok - ( Some k, - { - map = - Big_map_overlay.add key_hash (k, item_wrapper v) map; - size = size + 1; - }, - ctxt ) ) - | Prim (loc, D_Elt, l, _) -> - fail @@ Invalid_arity (loc, D_Elt, 2, List.length l) - | Prim (loc, name, _, _) -> - fail @@ Invalid_primitive (loc, [D_Elt], name) - | Int _ | String _ | Bytes _ | Seq _ -> fail_parse_data ()) - (None, {map = Big_map_overlay.empty; size = 0}, ctxt) - items - |> traced - >|=? fun (_, map, ctxt) -> (map, ctxt) - in - match (ty, script_data) with - | (Unit_t _, expr) -> - Lwt.return @@ traced_no_lwt - @@ (parse_unit ctxt ~legacy expr : (a * context) tzresult) - | (Bool_t _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_bool ctxt ~legacy expr - | (String_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_string ctxt expr - | (Bytes_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_bytes ctxt expr - | (Int_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_int ctxt expr - | (Nat_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_nat ctxt expr - | (Mutez_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_mutez ctxt expr - | (Timestamp_t _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_timestamp ctxt expr - | (Key_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_key ctxt expr - | (Key_hash_t _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_key_hash ctxt expr - | (Signature_t _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_signature ctxt expr - | (Operation_t _, _) -> - (* operations cannot appear in parameters or storage, - the protocol should never parse the bytes of an operation *) - assert false - | (Chain_id_t _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_chain_id ctxt expr - | (Address_t _, expr) -> - Lwt.return @@ traced_no_lwt @@ parse_address ctxt expr - | (Contract_t (ty, _), expr) -> - traced - ( parse_address ctxt expr >>?= fun ((c, entrypoint), ctxt) -> - let loc = location expr in - parse_contract - ~stack_depth:(stack_depth + 1) - ~legacy - ctxt - loc - ty - c - ~entrypoint - >|=? fun (ctxt, _) -> ((ty, (c, entrypoint)), ctxt) ) - (* Pairs *) - | (Pair_t ((tl, _, _), (tr, _, _), _), expr) -> - let r_witness = comb_witness1 tr in - let parse_l ctxt v = - non_terminal_recursion ?type_logger ctxt ~legacy tl v - in - let parse_r ctxt v = - non_terminal_recursion ?type_logger ctxt ~legacy tr v - in - traced @@ parse_pair parse_l parse_r ctxt ~legacy r_witness expr - (* Unions *) - | (Union_t ((tl, _), (tr, _), _), expr) -> - let parse_l ctxt v = - non_terminal_recursion ?type_logger ctxt ~legacy tl v - in - let parse_r ctxt v = - non_terminal_recursion ?type_logger ctxt ~legacy tr v - in - traced @@ parse_union parse_l parse_r ctxt ~legacy expr - (* Lambdas *) - | (Lambda_t (ta, tr, _ty_name), (Seq (_loc, _) as script_instr)) -> - traced - @@ parse_returning - Lambda - ?type_logger - ~stack_depth:(stack_depth + 1) - ctxt - ~legacy - (ta, lambda_arg_annot) - tr - script_instr - | (Lambda_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) - (* Options *) - | (Option_t (t, _), expr) -> - let parse_v ctxt v = - non_terminal_recursion ?type_logger ctxt ~legacy t v - in - traced @@ parse_option parse_v ctxt ~legacy expr - (* Lists *) - | (List_t (t, _ty_name), Seq (_loc, items)) -> - traced - @@ List.fold_right_es - (fun v (rest, ctxt) -> - non_terminal_recursion ?type_logger ctxt ~legacy t v - >|=? fun (v, ctxt) -> (Script_list.cons v rest, ctxt)) - items - (Script_list.empty, ctxt) - | (List_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) - (* Tickets *) - | (Ticket_t (t, _ty_name), expr) -> - if allow_forged then - opened_ticket_type (location expr) t >>?= fun ty -> - parse_comparable_data ?type_logger ctxt ty expr - >|=? fun (((ticketer, _entrypoint), (contents, amount)), ctxt) -> - ({ticketer; contents; amount}, ctxt) - else traced_fail (Unexpected_forged_value (location expr)) - (* Sets *) - | (Set_t (t, _ty_name), (Seq (loc, vs) as expr)) -> - traced - @@ List.fold_left_es - (fun (last_value, set, ctxt) v -> - parse_comparable_data ?type_logger ctxt t v >>=? fun (v, ctxt) -> - Lwt.return - ( (match last_value with - | Some value -> - Gas.consume - ctxt - (Michelson_v1_gas.Cost_of.Interpreter.compare t value v) - >>? fun ctxt -> - let c = Script_comparable.compare_comparable t value v in - if Compare.Int.(0 <= c) then - if Compare.Int.(0 = c) then - error - (Duplicate_set_values (loc, strip_locations expr)) - else - error - (Unordered_set_values (loc, strip_locations expr)) - else ok ctxt - | None -> ok ctxt) - >>? fun ctxt -> - Gas.consume - ctxt - (Michelson_v1_gas.Cost_of.Interpreter.set_update v set) - >|? fun ctxt -> (Some v, Script_set.update v true set, ctxt) )) - (None, Script_set.empty t, ctxt) - vs - >|=? fun (_, set, ctxt) -> (set, ctxt) - | (Set_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) - (* Maps *) - | (Map_t (tk, tv, _ty_name), (Seq (_, vs) as expr)) -> - parse_items ?type_logger ctxt expr tk tv vs (fun x -> x) - | (Map_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) - | (Big_map_t (tk, tv, _ty_name), expr) -> - (match expr with - | Int (loc, id) -> - return (Some (id, loc), {map = Big_map_overlay.empty; size = 0}, ctxt) - | Seq (_, vs) -> - parse_big_map_items ?type_logger ctxt expr tk tv vs (fun x -> Some x) - >|=? fun (diff, ctxt) -> (None, diff, ctxt) - | Prim (loc, D_Pair, [Int (loc_id, id); Seq (_, vs)], annot) -> - error_unexpected_annot loc annot >>?= fun () -> - option_t loc tv ~annot:None >>?= fun tv_opt -> - parse_big_map_items ?type_logger ctxt expr tk tv_opt vs (fun x -> x) - >|=? fun (diff, ctxt) -> (Some (id, loc_id), diff, ctxt) - | Prim (_, D_Pair, [Int _; expr], _) -> - traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) - | Prim (_, D_Pair, [expr; _], _) -> - traced_fail (Invalid_kind (location expr, [Int_kind], kind expr)) - | Prim (loc, D_Pair, l, _) -> - traced_fail @@ Invalid_arity (loc, D_Pair, 2, List.length l) - | _ -> - traced_fail - (unexpected expr [Seq_kind; Int_kind] Constant_namespace [D_Pair])) - >>=? fun (id_opt, diff, ctxt) -> - (match id_opt with - | None -> return @@ (None, ctxt) - | Some (id, loc) -> - if allow_forged then - let id = Big_map.Id.parse_z id in - Big_map.exists ctxt id >>=? function - | (_, None) -> traced_fail (Invalid_big_map (loc, id)) - | (ctxt, Some (btk, btv)) -> - Lwt.return - ( parse_comparable_ty - ~stack_depth:(stack_depth + 1) - ctxt - (Micheline.root btk) - >>? fun (Ex_comparable_ty btk, ctxt) -> - parse_big_map_value_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - (Micheline.root btv) - >>? fun (Ex_ty btv, ctxt) -> - comparable_ty_eq ctxt tk btk >>? fun (Eq, ctxt) -> - ty_eq ~legacy:true ctxt loc tv btv >>? fun (Eq, ctxt) -> - ok (Some id, ctxt) ) - else traced_fail (Unexpected_forged_value loc)) - >|=? fun (id, ctxt) -> ({id; diff; key_type = tk; value_type = tv}, ctxt) - | (Never_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_never expr - (* Bls12_381 types *) - | (Bls12_381_g1_t _, Bytes (_, bs)) -> ( - Gas.consume ctxt Typecheck_costs.bls12_381_g1 >>?= fun ctxt -> - match Bls12_381.G1.of_bytes_opt bs with - | Some pt -> return (pt, ctxt) - | None -> fail_parse_data ()) - | (Bls12_381_g1_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) - | (Bls12_381_g2_t _, Bytes (_, bs)) -> ( - Gas.consume ctxt Typecheck_costs.bls12_381_g2 >>?= fun ctxt -> - match Bls12_381.G2.of_bytes_opt bs with - | Some pt -> return (pt, ctxt) - | None -> fail_parse_data ()) - | (Bls12_381_g2_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) - | (Bls12_381_fr_t _, Bytes (_, bs)) -> ( - Gas.consume ctxt Typecheck_costs.bls12_381_fr >>?= fun ctxt -> - match Bls12_381.Fr.of_bytes_opt bs with - | Some pt -> return (pt, ctxt) - | None -> fail_parse_data ()) - | (Bls12_381_fr_t _, Int (_, v)) -> - Gas.consume ctxt Typecheck_costs.bls12_381_fr >>?= fun ctxt -> - return (Bls12_381.Fr.of_z v, ctxt) - | (Bls12_381_fr_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) - (* - /!\ When adding new lazy storage kinds, you may want to guard the parsing - of identifiers with [allow_forged]. - *) - (* Sapling *) - | (Sapling_transaction_t (memo_size, _), Bytes (_, bytes)) -> ( - match - Data_encoding.Binary.of_bytes_opt Sapling.transaction_encoding bytes - with - | Some transaction -> ( - match Sapling.transaction_get_memo_size transaction with - | None -> return (transaction, ctxt) - | Some transac_memo_size -> - Lwt.return - ( merge_memo_sizes memo_size transac_memo_size >|? fun _ms -> - (transaction, ctxt) )) - | None -> fail_parse_data ()) - | (Sapling_transaction_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) - | (Sapling_state_t (memo_size, _), Int (loc, id)) -> - if allow_forged then - let id = Sapling.Id.parse_z id in - Sapling.state_from_id ctxt id >>=? fun (state, ctxt) -> - Lwt.return - ( traced_no_lwt @@ merge_memo_sizes memo_size state.Sapling.memo_size - >|? fun _memo_size -> (state, ctxt) ) - else traced_fail (Unexpected_forged_value loc) - | (Sapling_state_t (memo_size, _), Seq (_, [])) -> - return (Sapling.empty_state ~memo_size (), ctxt) - | (Sapling_state_t _, expr) -> - (* Do not allow to input diffs as they are untrusted and may not be the - result of a verify_update. *) - traced_fail - (Invalid_kind (location expr, [Int_kind; Seq_kind], kind expr)) - (* Time lock*) - | (Chest_key_t _, Bytes (_, bytes)) -> ( - Gas.consume ctxt Typecheck_costs.chest_key >>?= fun ctxt -> - match - Data_encoding.Binary.of_bytes_opt Timelock.chest_key_encoding bytes - with - | Some chest_key -> return (chest_key, ctxt) - | None -> fail_parse_data ()) - | (Chest_key_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) - | (Chest_t _, Bytes (_, bytes)) -> ( - Gas.consume ctxt (Typecheck_costs.chest ~bytes:(Bytes.length bytes)) - >>?= fun ctxt -> - match Data_encoding.Binary.of_bytes_opt Timelock.chest_encoding bytes with - | Some chest -> return (chest, ctxt) - | None -> fail_parse_data ()) - | (Chest_t _, expr) -> - traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) - -and parse_view_returning : - type storage. - ?type_logger:type_logger -> - context -> - legacy:bool -> - storage ty -> - view -> - (storage ex_view * context) tzresult Lwt.t = - fun ?type_logger ctxt ~legacy storage_type {input_ty; output_ty; view_code} -> - let input_ty_loc = location input_ty in - record_trace_eval - (fun () -> - Ill_formed_type - (Some "arg of view", strip_locations input_ty, input_ty_loc)) - (parse_view_input_ty ctxt ~stack_depth:0 ~legacy input_ty) - >>?= fun (Ex_ty input_ty', ctxt) -> - let output_ty_loc = location output_ty in - record_trace_eval - (fun () -> - Ill_formed_type - (Some "return of view", strip_locations output_ty, output_ty_loc)) - (parse_view_output_ty ctxt ~stack_depth:0 ~legacy output_ty) - >>?= fun (Ex_ty output_ty', ctxt) -> - pair_t - input_ty_loc - (input_ty', None, None) - (storage_type, None, None) - ~annot:None - >>?= fun pair_ty -> - parse_instr - ?type_logger - ~stack_depth:0 - Lambda - ctxt - ~legacy - view_code - (Item_t (pair_ty, Bot_t, None)) - >>=? fun (judgement, ctxt) -> - Lwt.return - @@ - match judgement with - | Failed {descr} -> - let cur_view' = - Ex_view - (Lam - (close_descr (descr (Item_t (output_ty', Bot_t, None))), view_code)) - in - ok (cur_view', ctxt) - | Typed ({loc; aft; _} as descr) -> ( - let ill_type_view loc stack_ty () = - let actual = serialize_stack_for_error ctxt stack_ty in - let expected_stack = Item_t (output_ty', Bot_t, None) in - let expected = serialize_stack_for_error ctxt expected_stack in - Ill_typed_view {loc; actual; expected} - in - match aft with - | Item_t (ty, Bot_t, _) -> - record_trace_eval - (ill_type_view loc aft : unit -> _) - ( ty_eq ~legacy ctxt loc ty output_ty' >|? fun (Eq, ctxt) -> - let view' = Ex_view (Lam (close_descr descr, view_code)) in - (view', ctxt) ) - | _ -> error (ill_type_view loc aft ())) - -and typecheck_views : - type storage. - ?type_logger:type_logger -> - context -> - legacy:bool -> - storage ty -> - view SMap.t -> - context tzresult Lwt.t = - fun ?type_logger ctxt ~legacy storage_type views -> - let aux _name cur_view ctxt = - parse_view_returning ?type_logger ctxt ~legacy storage_type cur_view - >|=? fun (_parsed_view, ctxt) -> ctxt - in - SMap.fold_es aux views ctxt - -and[@coq_axiom_with_reason "gadt"] parse_returning : - type arg ret. - ?type_logger:type_logger -> - stack_depth:int -> - tc_context -> - context -> - legacy:bool -> - arg ty * var_annot option -> - ret ty -> - Script.node -> - ((arg, ret) lambda * context) tzresult Lwt.t = - fun ?type_logger - ~stack_depth - tc_context - ctxt - ~legacy - (arg, arg_annot) - ret - script_instr -> - parse_instr - ?type_logger - tc_context - ctxt - ~legacy - ~stack_depth:(stack_depth + 1) - script_instr - (Item_t (arg, Bot_t, arg_annot)) - >>=? function - | (Typed ({loc; aft = Item_t (ty, Bot_t, _) as stack_ty; _} as descr), ctxt) - -> - Lwt.return - @@ record_trace_eval - (fun () -> - let ret = serialize_ty_for_error ret in - let stack_ty = serialize_stack_for_error ctxt stack_ty in - Bad_return (loc, stack_ty, ret)) - ( ty_eq ~legacy ctxt loc ty ret >|? fun (Eq, ctxt) -> - ((Lam (close_descr descr, script_instr) : (arg, ret) lambda), ctxt) - ) - | (Typed {loc; aft = stack_ty; _}, ctxt) -> - let ret = serialize_ty_for_error ret in - let stack_ty = serialize_stack_for_error ctxt stack_ty in - fail @@ Bad_return (loc, stack_ty, ret) - | (Failed {descr}, ctxt) -> - return - ( (Lam (close_descr (descr (Item_t (ret, Bot_t, None))), script_instr) - : (arg, ret) lambda), - ctxt ) - -and[@coq_axiom_with_reason "gadt"] parse_instr : - type a s. - ?type_logger:type_logger -> - stack_depth:int -> - tc_context -> - context -> - legacy:bool -> - Script.node -> - (a, s) stack_ty -> - ((a, s) judgement * context) tzresult Lwt.t = - fun ?type_logger ~stack_depth tc_context ctxt ~legacy script_instr stack_ty -> - let check_item_ty (type a b) ctxt (exp : a ty) (got : b ty) loc name n m : - ((a, b) eq * a ty * context) tzresult = - record_trace_eval (fun () -> - let stack_ty = serialize_stack_for_error ctxt stack_ty in - Bad_stack (loc, name, m, stack_ty)) - @@ record_trace - (Bad_stack_item n) - ( Gas_monad.run ctxt - @@ merge_types - ~legacy - ~merge_type_error_flag:Default_merge_type_error - loc - exp - got - >>? fun (eq_ty, ctxt) -> - eq_ty >|? fun (Eq, ty) -> ((Eq : (a, b) eq), (ty : a ty), ctxt) ) - in - let log_stack loc stack_ty aft = - match (type_logger, script_instr) with - | (None, _) | (Some _, (Int _ | String _ | Bytes _)) -> () - | (Some log, (Prim _ | Seq _)) -> - (* Unparsing for logging is not carbonated as this - is used only by the client and not the protocol *) - let stack_ty = unparse_stack_uncarbonated stack_ty in - let aft = unparse_stack_uncarbonated aft in - log loc stack_ty aft - in - let typed_no_lwt ctxt loc instr aft = - log_stack loc stack_ty aft ; - let j = Typed {loc; instr; bef = stack_ty; aft} in - Ok (j, ctxt) - in - let typed ctxt loc instr aft = - Lwt.return @@ typed_no_lwt ctxt loc instr aft - in - Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>?= fun ctxt -> - let non_terminal_recursion ?type_logger tc_context ctxt ~legacy script_instr - stack_ty = - if Compare.Int.(stack_depth > 10000) then - fail Typechecking_too_many_recursive_calls - else - parse_instr - ?type_logger - tc_context - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - script_instr - stack_ty - in - match (script_instr, stack_ty) with - (* stack ops *) - | (Prim (loc, I_DROP, [], annot), Item_t (_, rest, _)) -> - (error_unexpected_annot loc annot >>?= fun () -> - typed ctxt loc {apply = (fun kinfo k -> IDrop (kinfo, k))} rest - : ((a, s) judgement * context) tzresult Lwt.t) - | (Prim (loc, I_DROP, [n], result_annot), whole_stack) -> - parse_uint10 n >>?= fun whole_n -> - Gas.consume ctxt (Typecheck_costs.proof_argument whole_n) >>?= fun ctxt -> - let rec make_proof_argument : - type a s. - int -> (a, s) stack_ty -> (a, s) dropn_proof_argument tzresult = - fun n stk -> - match (Compare.Int.(n = 0), stk) with - | (true, rest) -> ok @@ Dropn_proof_argument (KRest, rest) - | (false, Item_t (_, rest, _)) -> - make_proof_argument (n - 1) rest - >|? fun (Dropn_proof_argument (n', stack_after_drops)) -> - let kinfo = {iloc = loc; kstack_ty = rest} in - Dropn_proof_argument (KPrefix (kinfo, n'), stack_after_drops) - | (_, _) -> - let whole_stack = serialize_stack_for_error ctxt whole_stack in - error (Bad_stack (loc, I_DROP, whole_n, whole_stack)) - in - error_unexpected_annot loc result_annot >>?= fun () -> - make_proof_argument whole_n whole_stack - >>?= fun (Dropn_proof_argument (n', stack_after_drops)) -> - let kdropn kinfo k = IDropn (kinfo, whole_n, n', k) in - typed ctxt loc {apply = kdropn} stack_after_drops - | (Prim (loc, I_DROP, (_ :: _ :: _ as l), _), _) -> - (* Technically, the arities 0 and 1 are allowed but the error only mentions 1. - However, DROP is equivalent to DROP 1 so hinting at an arity of 1 makes sense. *) - fail (Invalid_arity (loc, I_DROP, 1, List.length l)) - | (Prim (loc, I_DUP, [], annot), Item_t (v, rest, stack_annot)) -> - parse_var_annot loc annot ~default:stack_annot >>?= fun annot -> - record_trace_eval - (fun () -> - let t = serialize_ty_for_error v in - Non_dupable_type (loc, t)) - (check_dupable_ty ctxt loc v) - >>?= fun ctxt -> - let dup = {apply = (fun kinfo k -> IDup (kinfo, k))} in - typed ctxt loc dup (Item_t (v, Item_t (v, rest, stack_annot), annot)) - | (Prim (loc, I_DUP, [n], v_annot), stack_ty) -> - parse_var_annot loc v_annot >>?= fun annot -> - let rec make_proof_argument : - type a s. - int -> (a, s) stack_ty -> (a * s) dup_n_proof_argument tzresult = - fun n (stack_ty : (a, s) stack_ty) -> - match (n, stack_ty) with - | (1, Item_t (hd_ty, _, _)) -> - ok @@ Dup_n_proof_argument (Dup_n_zero, hd_ty) - | (n, Item_t (_, tl_ty, _)) -> - make_proof_argument (n - 1) tl_ty - >|? fun (Dup_n_proof_argument (dup_n_witness, b_ty)) -> - Dup_n_proof_argument (Dup_n_succ dup_n_witness, b_ty) - | _ -> - let whole_stack = serialize_stack_for_error ctxt stack_ty in - error (Bad_stack (loc, I_DUP, 1, whole_stack)) - in - parse_uint10 n >>?= fun n -> - Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> - error_unless (Compare.Int.( > ) n 0) (Dup_n_bad_argument loc) - >>?= fun () -> - record_trace (Dup_n_bad_stack loc) (make_proof_argument n stack_ty) - >>?= fun (Dup_n_proof_argument (witness, after_ty)) -> - record_trace_eval - (fun () -> - let t = serialize_ty_for_error after_ty in - Non_dupable_type (loc, t)) - (check_dupable_ty ctxt loc after_ty) - >>?= fun ctxt -> - let dupn = {apply = (fun kinfo k -> IDup_n (kinfo, n, witness, k))} in - typed ctxt loc dupn (Item_t (after_ty, stack_ty, annot)) - | (Prim (loc, I_DIG, [n], result_annot), stack) -> - let rec make_proof_argument : - type a s. int -> (a, s) stack_ty -> (a, s) dig_proof_argument tzresult - = - fun n stk -> - match (Compare.Int.(n = 0), stk) with - | (true, Item_t (v, rest, annot)) -> - ok @@ Dig_proof_argument (KRest, v, annot, rest) - | (false, Item_t (v, rest, annot)) -> - make_proof_argument (n - 1) rest - >|? fun (Dig_proof_argument (n', x, xv, aft')) -> - let kinfo = {iloc = loc; kstack_ty = aft'} in - Dig_proof_argument - (KPrefix (kinfo, n'), x, xv, Item_t (v, aft', annot)) - | (_, _) -> - let whole_stack = serialize_stack_for_error ctxt stack in - error (Bad_stack (loc, I_DIG, 3, whole_stack)) - in - parse_uint10 n >>?= fun n -> - Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> - error_unexpected_annot loc result_annot >>?= fun () -> - make_proof_argument n stack - >>?= fun (Dig_proof_argument (n', x, stack_annot, aft)) -> - let dig = {apply = (fun kinfo k -> IDig (kinfo, n, n', k))} in - typed ctxt loc dig (Item_t (x, aft, stack_annot)) - | (Prim (loc, I_DIG, (([] | _ :: _ :: _) as l), _), _) -> - fail (Invalid_arity (loc, I_DIG, 1, List.length l)) - | (Prim (loc, I_DUG, [n], result_annot), Item_t (x, whole_stack, stack_annot)) - -> - parse_uint10 n >>?= fun whole_n -> - Gas.consume ctxt (Typecheck_costs.proof_argument whole_n) >>?= fun ctxt -> - let rec make_proof_argument : - type a s x. - int -> - x ty -> - var_annot option -> - (a, s) stack_ty -> - (a, s, x) dug_proof_argument tzresult = - fun n x stack_annot stk -> - match (Compare.Int.(n = 0), stk) with - | (true, rest) -> - ok @@ Dug_proof_argument (KRest, Item_t (x, rest, stack_annot)) - | (false, Item_t (v, rest, annot)) -> - make_proof_argument (n - 1) x stack_annot rest - >|? fun (Dug_proof_argument (n', aft')) -> - let kinfo = {iloc = loc; kstack_ty = aft'} in - Dug_proof_argument (KPrefix (kinfo, n'), Item_t (v, aft', annot)) - | (_, _) -> - let whole_stack = serialize_stack_for_error ctxt whole_stack in - error (Bad_stack (loc, I_DUG, whole_n, whole_stack)) - in - error_unexpected_annot loc result_annot >>?= fun () -> - make_proof_argument whole_n x stack_annot whole_stack - >>?= fun (Dug_proof_argument (n', aft)) -> - let dug = {apply = (fun kinfo k -> IDug (kinfo, whole_n, n', k))} in - typed ctxt loc dug aft - | (Prim (loc, I_DUG, [_], result_annot), stack) -> - Lwt.return - ( error_unexpected_annot loc result_annot >>? fun () -> - let stack = serialize_stack_for_error ctxt stack in - error (Bad_stack (loc, I_DUG, 1, stack)) ) - | (Prim (loc, I_DUG, (([] | _ :: _ :: _) as l), _), _) -> - fail (Invalid_arity (loc, I_DUG, 1, List.length l)) - | ( Prim (loc, I_SWAP, [], annot), - Item_t (v, Item_t (w, rest, stack_annot), cur_top_annot) ) -> - error_unexpected_annot loc annot >>?= fun () -> - let swap = {apply = (fun kinfo k -> ISwap (kinfo, k))} in - let stack_ty = Item_t (w, Item_t (v, rest, cur_top_annot), stack_annot) in - typed ctxt loc swap stack_ty - | (Prim (loc, I_PUSH, [t; d], annot), stack) -> - parse_var_annot loc annot >>?= fun annot -> - parse_packable_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy t - >>?= fun (Ex_ty t, ctxt) -> - parse_data - ?type_logger - ~stack_depth:(stack_depth + 1) - ctxt - ~legacy - ~allow_forged:false - t - d - >>=? fun (v, ctxt) -> - let const = {apply = (fun kinfo k -> IConst (kinfo, v, k))} in - typed ctxt loc const (Item_t (t, stack, annot)) - | (Prim (loc, I_UNIT, [], annot), stack) -> - parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> - let const = {apply = (fun kinfo k -> IConst (kinfo, (), k))} in - typed ctxt loc const (Item_t (unit_t ~annot:ty_name, stack, annot)) - (* options *) - | (Prim (loc, I_SOME, [], annot), Item_t (t, rest, _)) -> - parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> - let cons_some = {apply = (fun kinfo k -> ICons_some (kinfo, k))} in - option_t loc t ~annot:ty_name >>?= fun ty -> - typed ctxt loc cons_some (Item_t (ty, rest, annot)) - | (Prim (loc, I_NONE, [t], annot), stack) -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy t - >>?= fun (Ex_ty t, ctxt) -> - parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> - let cons_none = {apply = (fun kinfo k -> ICons_none (kinfo, k))} in - option_t loc t ~annot:ty_name >>?= fun ty -> - let stack_ty = Item_t (ty, stack, annot) in - typed ctxt loc cons_none stack_ty - | (Prim (loc, I_MAP, [body], annot), Item_t (Option_t (t, _), rest, opt_annot)) - -> ( - check_kind [Seq_kind] body >>?= fun () -> - parse_var_type_annot loc annot >>?= fun (ret_annot, opt_ty_name) -> - let elt_annot = gen_access_annot opt_annot default_some_annot in - non_terminal_recursion - ?type_logger - ~legacy - tc_context - ctxt - body - (Item_t (t, rest, elt_annot)) - >>=? fun (judgement, ctxt) -> - Lwt.return - @@ - match judgement with - | Typed ({loc; aft = Item_t (ret, aft_rest, _aft_annot); _} as kibody) -> - let invalid_map_body () = - let aft = serialize_stack_for_error ctxt kibody.aft in - Invalid_map_body (loc, aft) - in - record_trace_eval - invalid_map_body - ( merge_stacks ~legacy loc ctxt 1 aft_rest rest - >>? fun (Eq, rest, ctxt) -> - option_t loc ret ~annot:opt_ty_name >>? fun opt_ty -> - let final_stack = Item_t (opt_ty, rest, ret_annot) in - let hinfo = - {iloc = loc; kstack_ty = Item_t (ret, aft_rest, ret_annot)} - in - let cinfo = kinfo_of_descr kibody in - let body = kibody.instr.apply cinfo (IHalt hinfo) in - let apply kinfo k = IOpt_map {kinfo; body; k} in - typed_no_lwt ctxt loc {apply} final_stack ) - | Typed {aft = Bot_t; _} -> - let aft = serialize_stack_for_error ctxt Bot_t in - error (Invalid_map_body (loc, aft)) - | Failed _ -> error (Invalid_map_block_fail loc)) - | ( Prim (loc, I_IF_NONE, [bt; bf], annot), - (Item_t (Option_t (t, _), rest, option_annot) as bef) ) -> - check_kind [Seq_kind] bt >>?= fun () -> - check_kind [Seq_kind] bf >>?= fun () -> - error_unexpected_annot loc annot >>?= fun () -> - let annot = gen_access_annot option_annot default_some_annot in - non_terminal_recursion ?type_logger tc_context ctxt ~legacy bt rest - >>=? fun (btr, ctxt) -> - let stack_ty = Item_t (t, rest, annot) in - non_terminal_recursion ?type_logger tc_context ctxt ~legacy bf stack_ty - >>=? fun (bfr, ctxt) -> - let branch ibt ibf = - let ifnone = - { - apply = - (fun kinfo k -> - let hinfo = kinfo_of_kinstr k in - let btinfo = kinfo_of_descr ibt - and bfinfo = kinfo_of_descr ibf in - let branch_if_none = ibt.instr.apply btinfo (IHalt hinfo) - and branch_if_some = ibf.instr.apply bfinfo (IHalt hinfo) in - IIf_none {kinfo; branch_if_none; branch_if_some; k}); - } - in - {loc; instr = ifnone; bef; aft = ibt.aft} - in - Lwt.return @@ merge_branches ~legacy ctxt loc btr bfr {branch} - (* pairs *) - | ( Prim (loc, I_PAIR, [], annot), - Item_t (a, Item_t (b, rest, snd_annot), fst_annot) ) -> - parse_constr_annot - loc - annot - ~if_special_first:(var_to_field_annot fst_annot) - ~if_special_second:(var_to_field_annot snd_annot) - >>?= fun (annot, ty_name, l_field, r_field) -> - pair_t loc (a, l_field, fst_annot) (b, r_field, snd_annot) ~annot:ty_name - >>?= fun ty -> - let stack_ty = Item_t (ty, rest, annot) in - let cons_pair = {apply = (fun kinfo k -> ICons_pair (kinfo, k))} in - typed ctxt loc cons_pair stack_ty - | (Prim (loc, I_PAIR, [n], annot), stack_ty) -> - parse_var_annot loc annot >>?= fun annot -> - let rec make_proof_argument : - type a s. - int -> (a, s) stack_ty -> (a * s) comb_proof_argument tzresult = - fun n stack_ty -> - match (n, stack_ty) with - | (1, Item_t (a_ty, tl_ty, _a_annot_opt)) -> - ok (Comb_proof_argument (Comb_one, Item_t (a_ty, tl_ty, annot))) - | (n, Item_t (a_ty, tl_ty, _prop_annot_opt)) -> - make_proof_argument (n - 1) tl_ty - >>? fun (Comb_proof_argument - (comb_witness, Item_t (b_ty, tl_ty', annot))) -> - pair_t loc (a_ty, None, None) (b_ty, None, None) ~annot:None - >|? fun pair_t -> - Comb_proof_argument - (Comb_succ comb_witness, Item_t (pair_t, tl_ty', annot)) - | _ -> - let whole_stack = serialize_stack_for_error ctxt stack_ty in - error (Bad_stack (loc, I_PAIR, 1, whole_stack)) - in - parse_uint10 n >>?= fun n -> - Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> - error_unless (Compare.Int.( > ) n 1) (Pair_bad_argument loc) - >>?= fun () -> - make_proof_argument n stack_ty - >>?= fun (Comb_proof_argument (witness, after_ty)) -> - let comb = {apply = (fun kinfo k -> IComb (kinfo, n, witness, k))} in - typed ctxt loc comb after_ty - | (Prim (loc, I_UNPAIR, [n], annot), stack_ty) -> - error_unexpected_annot loc annot >>?= fun () -> - let rec make_proof_argument : - type a s. - int -> (a, s) stack_ty -> (a * s) uncomb_proof_argument tzresult = - fun n stack_ty -> - match (n, stack_ty) with - | (1, Item_t (a_ty, tl_ty, annot)) -> - ok @@ Uncomb_proof_argument (Uncomb_one, Item_t (a_ty, tl_ty, annot)) - | ( n, - Item_t - ( Pair_t ((a_ty, field_opt, _), (b_ty, b_field_opt, _), _), - tl_ty, - _ ) ) -> - let b_annot = Script_ir_annot.field_to_var_annot b_field_opt in - make_proof_argument (n - 1) (Item_t (b_ty, tl_ty, b_annot)) - >|? fun (Uncomb_proof_argument (uncomb_witness, after_ty)) -> - Uncomb_proof_argument - ( Uncomb_succ uncomb_witness, - Item_t - (a_ty, after_ty, Script_ir_annot.field_to_var_annot field_opt) - ) - | _ -> - let whole_stack = serialize_stack_for_error ctxt stack_ty in - error (Bad_stack (loc, I_UNPAIR, 1, whole_stack)) - in - parse_uint10 n >>?= fun n -> - Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> - error_unless (Compare.Int.( > ) n 1) (Unpair_bad_argument loc) - >>?= fun () -> - make_proof_argument n stack_ty - >>?= fun (Uncomb_proof_argument (witness, after_ty)) -> - let uncomb = {apply = (fun kinfo k -> IUncomb (kinfo, n, witness, k))} in - typed ctxt loc uncomb after_ty - | (Prim (loc, I_GET, [n], annot), Item_t (comb_ty, rest_ty, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let rec make_proof_argument : - type b. int -> b ty -> b comb_get_proof_argument tzresult = - fun n ty -> - match (n, ty) with - | (0, value_ty) -> - ok @@ Comb_get_proof_argument (Comb_get_zero, value_ty) - | (1, Pair_t ((hd_ty, _at1, _at2), _, _annot)) -> - ok @@ Comb_get_proof_argument (Comb_get_one, hd_ty) - | (n, Pair_t (_, (tl_ty, _bt1, _bt2), _annot)) -> - make_proof_argument (n - 2) tl_ty - >|? fun (Comb_get_proof_argument (comb_get_left_witness, ty')) -> - Comb_get_proof_argument - (Comb_get_plus_two comb_get_left_witness, ty') - | _ -> - let whole_stack = serialize_stack_for_error ctxt stack_ty in - error (Bad_stack (loc, I_GET, 1, whole_stack)) - in - parse_uint11 n >>?= fun n -> - Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> - make_proof_argument n comb_ty - >>?= fun (Comb_get_proof_argument (witness, ty')) -> - let after_stack_ty = Item_t (ty', rest_ty, annot) in - let comb_get = - {apply = (fun kinfo k -> IComb_get (kinfo, n, witness, k))} - in - typed ctxt loc comb_get after_stack_ty - | ( Prim (loc, I_UPDATE, [n], annot), - Item_t (value_ty, Item_t (comb_ty, rest_ty, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let rec make_proof_argument : - type value before. - int -> - value ty -> - before ty -> - (value, before) comb_set_proof_argument tzresult = - fun n value_ty ty -> - match (n, ty) with - | (0, _) -> ok @@ Comb_set_proof_argument (Comb_set_zero, value_ty) - | (1, Pair_t ((_hd_ty, at1, at2), (tl_ty, bt1, bt2), {annot; _})) -> - pair_t loc (value_ty, at1, at2) (tl_ty, bt1, bt2) ~annot - >|? fun after_ty -> Comb_set_proof_argument (Comb_set_one, after_ty) - | (n, Pair_t ((hd_ty, at1, at2), (tl_ty, bt1, bt2), {annot; _})) -> - make_proof_argument (n - 2) value_ty tl_ty - >>? fun (Comb_set_proof_argument (comb_set_left_witness, tl_ty')) -> - pair_t loc (hd_ty, at1, at2) (tl_ty', bt1, bt2) ~annot - >|? fun after_ty -> - Comb_set_proof_argument - (Comb_set_plus_two comb_set_left_witness, after_ty) - | _ -> - let whole_stack = serialize_stack_for_error ctxt stack_ty in - error (Bad_stack (loc, I_UPDATE, 2, whole_stack)) - in - parse_uint11 n >>?= fun n -> - Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> - make_proof_argument n value_ty comb_ty - >>?= fun (Comb_set_proof_argument (witness, after_ty)) -> - let after_stack_ty = Item_t (after_ty, rest_ty, annot) in - let comb_set = - {apply = (fun kinfo k -> IComb_set (kinfo, n, witness, k))} - in - typed ctxt loc comb_set after_stack_ty - | ( Prim (loc, I_UNPAIR, [], annot), - Item_t - ( Pair_t - ( (a, expected_field_annot_a, a_annot), - (b, expected_field_annot_b, b_annot), - _ ), - rest, - pair_annot ) ) -> - parse_unpair_annot - loc - annot - ~pair_annot - ~value_annot_car:a_annot - ~value_annot_cdr:b_annot - ~field_name_car:expected_field_annot_a - ~field_name_cdr:expected_field_annot_b - >>?= fun (annot_a, annot_b, field_a, field_b) -> - check_correct_field field_a expected_field_annot_a >>?= fun () -> - check_correct_field field_b expected_field_annot_b >>?= fun () -> - let unpair = {apply = (fun kinfo k -> IUnpair (kinfo, k))} in - typed ctxt loc unpair (Item_t (a, Item_t (b, rest, annot_b), annot_a)) - | ( Prim (loc, I_CAR, [], annot), - Item_t - (Pair_t ((a, expected_field_annot, a_annot), _, _), rest, pair_annot) ) - -> - parse_destr_annot - loc - annot - ~pair_annot - ~value_annot:a_annot - ~field_name:expected_field_annot - ~default_accessor:default_car_annot - >>?= fun (annot, field_annot) -> - check_correct_field field_annot expected_field_annot >>?= fun () -> - let car = {apply = (fun kinfo k -> ICar (kinfo, k))} in - typed ctxt loc car (Item_t (a, rest, annot)) - | ( Prim (loc, I_CDR, [], annot), - Item_t - (Pair_t (_, (b, expected_field_annot, b_annot), _), rest, pair_annot) ) - -> - parse_destr_annot - loc - annot - ~pair_annot - ~value_annot:b_annot - ~field_name:expected_field_annot - ~default_accessor:default_cdr_annot - >>?= fun (annot, field_annot) -> - check_correct_field field_annot expected_field_annot >>?= fun () -> - let cdr = {apply = (fun kinfo k -> ICdr (kinfo, k))} in - typed ctxt loc cdr (Item_t (b, rest, annot)) - (* unions *) - | (Prim (loc, I_LEFT, [tr], annot), Item_t (tl, rest, stack_annot)) -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy tr - >>?= fun (Ex_ty tr, ctxt) -> - parse_constr_annot - loc - annot - ~if_special_first:(var_to_field_annot stack_annot) - >>?= fun (annot, tname, l_field, r_field) -> - let cons_left = {apply = (fun kinfo k -> ICons_left (kinfo, k))} in - union_t loc (tl, l_field) (tr, r_field) ~annot:tname >>?= fun ty -> - let stack_ty = Item_t (ty, rest, annot) in - typed ctxt loc cons_left stack_ty - | (Prim (loc, I_RIGHT, [tl], annot), Item_t (tr, rest, stack_annot)) -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy tl - >>?= fun (Ex_ty tl, ctxt) -> - parse_constr_annot - loc - annot - ~if_special_second:(var_to_field_annot stack_annot) - >>?= fun (annot, tname, l_field, r_field) -> - let cons_right = {apply = (fun kinfo k -> ICons_right (kinfo, k))} in - union_t loc (tl, l_field) (tr, r_field) ~annot:tname >>?= fun ty -> - let stack_ty = Item_t (ty, rest, annot) in - typed ctxt loc cons_right stack_ty - | ( Prim (loc, I_IF_LEFT, [bt; bf], annot), - (Item_t (Union_t ((tl, l_field), (tr, r_field), _), rest, union_annot) as - bef) ) -> - check_kind [Seq_kind] bt >>?= fun () -> - check_kind [Seq_kind] bf >>?= fun () -> - error_unexpected_annot loc annot >>?= fun () -> - let left_annot = - gen_access_annot union_annot l_field ~default:default_left_annot - in - let right_annot = - gen_access_annot union_annot r_field ~default:default_right_annot - in - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - bt - (Item_t (tl, rest, left_annot)) - >>=? fun (btr, ctxt) -> - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - bf - (Item_t (tr, rest, right_annot)) - >>=? fun (bfr, ctxt) -> - let branch ibt ibf = - let infobt = kinfo_of_descr ibt and infobf = kinfo_of_descr ibf in - let instr = - { - apply = - (fun kinfo k -> - let hinfo = kinfo_of_kinstr k in - let branch_if_left = ibt.instr.apply infobt (IHalt hinfo) - and branch_if_right = ibf.instr.apply infobf (IHalt hinfo) in - IIf_left {kinfo; branch_if_left; branch_if_right; k}); - } - in - {loc; instr; bef; aft = ibt.aft} - in - Lwt.return @@ merge_branches ~legacy ctxt loc btr bfr {branch} - (* lists *) - | (Prim (loc, I_NIL, [t], annot), stack) -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy t - >>?= fun (Ex_ty t, ctxt) -> - parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> - let nil = {apply = (fun kinfo k -> INil (kinfo, k))} in - list_t loc t ~annot:ty_name >>?= fun ty -> - typed ctxt loc nil (Item_t (ty, stack, annot)) - | ( Prim (loc, I_CONS, [], annot), - Item_t (tv, Item_t (List_t (t, ty_name), rest, _), _) ) -> - check_item_ty ctxt tv t loc I_CONS 1 2 >>?= fun (Eq, t, ctxt) -> - parse_var_annot loc annot >>?= fun annot -> - let cons_list = {apply = (fun kinfo k -> ICons_list (kinfo, k))} in - (typed ctxt loc cons_list (Item_t (List_t (t, ty_name), rest, annot)) - : ((a, s) judgement * context) tzresult Lwt.t) - | ( Prim (loc, I_IF_CONS, [bt; bf], annot), - (Item_t (List_t (t, ty_name), rest, list_annot) as bef) ) -> - check_kind [Seq_kind] bt >>?= fun () -> - check_kind [Seq_kind] bf >>?= fun () -> - error_unexpected_annot loc annot >>?= fun () -> - let hd_annot = gen_access_annot list_annot default_hd_annot in - let tl_annot = gen_access_annot list_annot default_tl_annot in - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - bt - (Item_t (t, Item_t (List_t (t, ty_name), rest, tl_annot), hd_annot)) - >>=? fun (btr, ctxt) -> - non_terminal_recursion ?type_logger tc_context ctxt ~legacy bf rest - >>=? fun (bfr, ctxt) -> - let branch ibt ibf = - let infobt = kinfo_of_descr ibt and infobf = kinfo_of_descr ibf in - let instr = - { - apply = - (fun kinfo k -> - let hinfo = kinfo_of_kinstr k in - let branch_if_cons = ibt.instr.apply infobt (IHalt hinfo) - and branch_if_nil = ibf.instr.apply infobf (IHalt hinfo) in - IIf_cons {kinfo; branch_if_nil; branch_if_cons; k}); - } - in - {loc; instr; bef; aft = ibt.aft} - in - Lwt.return @@ merge_branches ~legacy ctxt loc btr bfr {branch} - | (Prim (loc, I_SIZE, [], annot), Item_t (List_t _, rest, _)) -> - parse_var_type_annot loc annot >>?= fun (annot, tname) -> - let list_size = {apply = (fun kinfo k -> IList_size (kinfo, k))} in - typed ctxt loc list_size (Item_t (nat_t ~annot:tname, rest, annot)) - | ( Prim (loc, I_MAP, [body], annot), - Item_t (List_t (elt, _), starting_rest, list_annot) ) -> ( - check_kind [Seq_kind] body >>?= fun () -> - parse_var_type_annot loc annot >>?= fun (ret_annot, list_ty_name) -> - let elt_annot = gen_access_annot list_annot default_elt_annot in - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - body - (Item_t (elt, starting_rest, elt_annot)) - >>=? fun (judgement, ctxt) -> - Lwt.return - @@ - match judgement with - | Typed ({aft = Item_t (ret, rest, _); _} as kibody) -> - let invalid_map_body () = - let aft = serialize_stack_for_error ctxt kibody.aft in - Invalid_map_body (loc, aft) - in - record_trace_eval - invalid_map_body - ( merge_stacks ~legacy loc ctxt 1 rest starting_rest - >>? fun (Eq, rest, ctxt) -> - let binfo = kinfo_of_descr kibody in - let hinfo = - {iloc = loc; kstack_ty = Item_t (ret, rest, ret_annot)} - in - let ibody = kibody.instr.apply binfo (IHalt hinfo) in - let list_map = - {apply = (fun kinfo k -> IList_map (kinfo, ibody, k))} - in - list_t loc ret ~annot:list_ty_name >>? fun ty -> - let stack = Item_t (ty, rest, ret_annot) in - typed_no_lwt ctxt loc list_map stack ) - | Typed {aft; _} -> - let aft = serialize_stack_for_error ctxt aft in - error (Invalid_map_body (loc, aft)) - | Failed _ -> error (Invalid_map_block_fail loc)) - | ( Prim (loc, I_ITER, [body], annot), - Item_t (List_t (elt, _), rest, list_annot) ) -> ( - check_kind [Seq_kind] body >>?= fun () -> - error_unexpected_annot loc annot >>?= fun () -> - let elt_annot = gen_access_annot list_annot default_elt_annot in - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - body - (Item_t (elt, rest, elt_annot)) - >>=? fun (judgement, ctxt) -> - let mk_list_iter ibody = - { - apply = - (fun kinfo k -> - let hinfo = {iloc = loc; kstack_ty = rest} in - let binfo = kinfo_of_descr ibody in - let ibody = ibody.instr.apply binfo (IHalt hinfo) in - IList_iter (kinfo, ibody, k)); - } - in - Lwt.return - @@ - match judgement with - | Typed ({aft; _} as ibody) -> - let invalid_iter_body () = - let aft = serialize_stack_for_error ctxt ibody.aft in - let rest = serialize_stack_for_error ctxt rest in - Invalid_iter_body (loc, rest, aft) - in - record_trace_eval - invalid_iter_body - ( merge_stacks ~legacy loc ctxt 1 aft rest - >>? fun (Eq, rest, ctxt) : ((a, s) judgement * context) tzresult -> - typed_no_lwt ctxt loc (mk_list_iter ibody) rest ) - | Failed {descr} -> typed_no_lwt ctxt loc (mk_list_iter (descr rest)) rest - ) - (* sets *) - | (Prim (loc, I_EMPTY_SET, [t], annot), rest) -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt t - >>?= fun (Ex_comparable_ty t, ctxt) -> - parse_var_type_annot loc annot >>?= fun (annot, tname) -> - let instr = {apply = (fun kinfo k -> IEmpty_set (kinfo, t, k))} in - set_t loc t ~annot:tname >>?= fun ty -> - typed ctxt loc instr (Item_t (ty, rest, annot)) - | ( Prim (loc, I_ITER, [body], annot), - Item_t (Set_t (comp_elt, _), rest, set_annot) ) -> ( - check_kind [Seq_kind] body >>?= fun () -> - error_unexpected_annot loc annot >>?= fun () -> - let elt_annot = gen_access_annot set_annot default_elt_annot in - let elt = ty_of_comparable_ty comp_elt in - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - body - (Item_t (elt, rest, elt_annot)) - >>=? fun (judgement, ctxt) -> - let mk_iset_iter ibody = - { - apply = - (fun kinfo k -> - let hinfo = {iloc = loc; kstack_ty = rest} in - let binfo = kinfo_of_descr ibody in - let ibody = ibody.instr.apply binfo (IHalt hinfo) in - ISet_iter (kinfo, ibody, k)); - } - in - Lwt.return - @@ - match judgement with - | Typed ({aft; _} as ibody) -> - let invalid_iter_body () = - let aft = serialize_stack_for_error ctxt ibody.aft in - let rest = serialize_stack_for_error ctxt rest in - Invalid_iter_body (loc, rest, aft) - in - record_trace_eval - invalid_iter_body - ( merge_stacks ~legacy loc ctxt 1 aft rest - >>? fun (Eq, rest, ctxt) : ((a, s) judgement * context) tzresult -> - typed_no_lwt ctxt loc (mk_iset_iter ibody) rest ) - | Failed {descr} -> typed_no_lwt ctxt loc (mk_iset_iter (descr rest)) rest - ) - | ( Prim (loc, I_MEM, [], annot), - Item_t (v, Item_t (Set_t (elt, _), rest, _), _) ) -> - let elt = ty_of_comparable_ty elt in - parse_var_type_annot loc annot >>?= fun (annot, tname) -> - check_item_ty ctxt elt v loc I_MEM 1 2 >>?= fun (Eq, _, ctxt) -> - let instr = {apply = (fun kinfo k -> ISet_mem (kinfo, k))} in - (typed ctxt loc instr (Item_t (bool_t ~annot:tname, rest, annot)) - : ((a, s) judgement * context) tzresult Lwt.t) - | ( Prim (loc, I_UPDATE, [], annot), - Item_t - ( v, - Item_t (Bool_t _, Item_t (Set_t (elt, tname), rest, set_annot), _), - _ ) ) -> - check_item_ty ctxt (ty_of_comparable_ty elt) v loc I_UPDATE 1 3 - >>?= fun (Eq, _, ctxt) -> - parse_var_annot loc annot ~default:set_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISet_update (kinfo, k))} in - (typed ctxt loc instr (Item_t (Set_t (elt, tname), rest, annot)) - : ((a, s) judgement * context) tzresult Lwt.t) - | (Prim (loc, I_SIZE, [], annot), Item_t (Set_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISet_size (kinfo, k))} in - typed ctxt loc instr (Item_t (nat_t ~annot:None, rest, annot)) - (* maps *) - | (Prim (loc, I_EMPTY_MAP, [tk; tv], annot), stack) -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt tk - >>?= fun (Ex_comparable_ty tk, ctxt) -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy tv - >>?= fun (Ex_ty tv, ctxt) -> - parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> - let instr = {apply = (fun kinfo k -> IEmpty_map (kinfo, tk, k))} in - map_t loc tk tv ~annot:ty_name >>?= fun ty -> - typed ctxt loc instr (Item_t (ty, stack, annot)) - | ( Prim (loc, I_MAP, [body], annot), - Item_t (Map_t (ck, elt, _), starting_rest, _map_annot) ) -> ( - let k = ty_of_comparable_ty ck in - check_kind [Seq_kind] body >>?= fun () -> - parse_var_type_annot loc annot >>?= fun (ret_annot, ty_name) -> - let k_name = field_to_var_annot default_key_annot in - let e_name = field_to_var_annot default_elt_annot in - pair_t loc (k, None, k_name) (elt, None, e_name) ~annot:None - >>?= fun ty -> - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - body - (Item_t (ty, starting_rest, None)) - >>=? fun (judgement, ctxt) -> - Lwt.return - @@ - match judgement with - | Typed ({aft = Item_t (ret, rest, _); _} as ibody) -> - let invalid_map_body () = - let aft = serialize_stack_for_error ctxt ibody.aft in - Invalid_map_body (loc, aft) - in - record_trace_eval - invalid_map_body - ( merge_stacks ~legacy loc ctxt 1 rest starting_rest - >>? fun (Eq, rest, ctxt) -> - let instr = - { - apply = - (fun kinfo k -> - let binfo = kinfo_of_descr ibody in - let hinfo = - {iloc = loc; kstack_ty = Item_t (ret, rest, ret_annot)} - in - let ibody = ibody.instr.apply binfo (IHalt hinfo) in - IMap_map (kinfo, ibody, k)); - } - in - map_t loc ck ret ~annot:ty_name >>? fun ty -> - let stack = Item_t (ty, rest, ret_annot) in - typed_no_lwt ctxt loc instr stack ) - | Typed {aft; _} -> - let aft = serialize_stack_for_error ctxt aft in - error (Invalid_map_body (loc, aft)) - | Failed _ -> error (Invalid_map_block_fail loc)) - | ( Prim (loc, I_ITER, [body], annot), - Item_t (Map_t (comp_elt, element_ty, _), rest, _map_annot) ) -> ( - check_kind [Seq_kind] body >>?= fun () -> - error_unexpected_annot loc annot >>?= fun () -> - let k_name = field_to_var_annot default_key_annot in - let e_name = field_to_var_annot default_elt_annot in - let key = ty_of_comparable_ty comp_elt in - pair_t loc (key, None, k_name) (element_ty, None, e_name) ~annot:None - >>?= fun ty -> - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - body - (Item_t (ty, rest, None)) - >>=? fun (judgement, ctxt) -> - let make_instr ibody = - { - apply = - (fun kinfo k -> - let hinfo = {iloc = loc; kstack_ty = rest} in - let binfo = kinfo_of_descr ibody in - let ibody = ibody.instr.apply binfo (IHalt hinfo) in - IMap_iter (kinfo, ibody, k)); - } - in - Lwt.return - @@ - match judgement with - | Typed ({aft; _} as ibody) -> - let invalid_iter_body () = - let aft = serialize_stack_for_error ctxt ibody.aft in - let rest = serialize_stack_for_error ctxt rest in - Invalid_iter_body (loc, rest, aft) - in - record_trace_eval - invalid_iter_body - ( merge_stacks ~legacy loc ctxt 1 aft rest - >>? fun (Eq, rest, ctxt) : ((a, s) judgement * context) tzresult -> - typed_no_lwt ctxt loc (make_instr ibody) rest ) - | Failed {descr} -> typed_no_lwt ctxt loc (make_instr (descr rest)) rest) - | ( Prim (loc, I_MEM, [], annot), - Item_t (vk, Item_t (Map_t (ck, _, _), rest, _), _) ) -> - let k = ty_of_comparable_ty ck in - check_item_ty ctxt vk k loc I_MEM 1 2 >>?= fun (Eq, _, ctxt) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMap_mem (kinfo, k))} in - (typed ctxt loc instr (Item_t (bool_t ~annot:None, rest, annot)) - : ((a, s) judgement * context) tzresult Lwt.t) - | ( Prim (loc, I_GET, [], annot), - Item_t (vk, Item_t (Map_t (ck, elt, _), rest, _), _) ) -> - let k = ty_of_comparable_ty ck in - check_item_ty ctxt vk k loc I_GET 1 2 >>?= fun (Eq, _, ctxt) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMap_get (kinfo, k))} in - option_t loc elt ~annot:None - >>?= fun ty : ((a, s) judgement * context) tzresult Lwt.t -> - typed ctxt loc instr (Item_t (ty, rest, annot)) - | ( Prim (loc, I_UPDATE, [], annot), - Item_t - ( vk, - Item_t - ( Option_t (vv, _), - Item_t (Map_t (ck, v, map_name), rest, map_annot), - _ ), - _ ) ) -> - let k = ty_of_comparable_ty ck in - check_item_ty ctxt vk k loc I_UPDATE 1 3 >>?= fun (Eq, _, ctxt) -> - check_item_ty ctxt vv v loc I_UPDATE 2 3 >>?= fun (Eq, v, ctxt) -> - parse_var_annot loc annot ~default:map_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMap_update (kinfo, k))} in - (typed ctxt loc instr (Item_t (Map_t (ck, v, map_name), rest, annot)) - : ((a, s) judgement * context) tzresult Lwt.t) - | ( Prim (loc, I_GET_AND_UPDATE, [], annot), - Item_t - ( vk, - Item_t - ( Option_t (vv, vname), - Item_t (Map_t (ck, v, map_name), rest, map_annot), - v_annot ), - _ ) ) -> - let k = ty_of_comparable_ty ck in - check_item_ty ctxt vk k loc I_GET_AND_UPDATE 1 3 >>?= fun (Eq, _, ctxt) -> - check_item_ty ctxt vv v loc I_GET_AND_UPDATE 2 3 >>?= fun (Eq, v, ctxt) -> - parse_var_annot loc annot ~default:map_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMap_get_and_update (kinfo, k))} in - let stack = - Item_t - ( Option_t (vv, vname), - Item_t (Map_t (ck, v, map_name), rest, annot), - v_annot ) - in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - | (Prim (loc, I_SIZE, [], annot), Item_t (Map_t (_, _, _), rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMap_size (kinfo, k))} in - typed ctxt loc instr (Item_t (nat_t ~annot:None, rest, annot)) - (* big_map *) - | (Prim (loc, I_EMPTY_BIG_MAP, [tk; tv], annot), stack) -> - parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt tk - >>?= fun (Ex_comparable_ty tk, ctxt) -> - parse_big_map_value_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy tv - >>?= fun (Ex_ty tv, ctxt) -> - parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> - let instr = - {apply = (fun kinfo k -> IEmpty_big_map (kinfo, tk, tv, k))} - in - big_map_t loc tk tv ~annot:ty_name >>?= fun ty -> - let stack = Item_t (ty, stack, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MEM, [], annot), - Item_t (set_key, Item_t (Big_map_t (map_key, _, _), rest, _), _) ) -> - let k = ty_of_comparable_ty map_key in - check_item_ty ctxt set_key k loc I_MEM 1 2 >>?= fun (Eq, _, ctxt) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IBig_map_mem (kinfo, k))} in - let stack = Item_t (bool_t ~annot:None, rest, annot) in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - | ( Prim (loc, I_GET, [], annot), - Item_t (vk, Item_t (Big_map_t (ck, elt, _), rest, _), _) ) -> - let k = ty_of_comparable_ty ck in - check_item_ty ctxt vk k loc I_GET 1 2 >>?= fun (Eq, _, ctxt) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IBig_map_get (kinfo, k))} in - option_t loc elt ~annot:None >>?= fun ty -> - let stack = Item_t (ty, rest, annot) in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - | ( Prim (loc, I_UPDATE, [], annot), - Item_t - ( set_key, - Item_t - ( Option_t (set_value, _), - Item_t (Big_map_t (map_key, map_value, map_name), rest, map_annot), - _ ), - _ ) ) -> - let k = ty_of_comparable_ty map_key in - check_item_ty ctxt set_key k loc I_UPDATE 1 3 >>?= fun (Eq, _, ctxt) -> - check_item_ty ctxt set_value map_value loc I_UPDATE 2 3 - >>?= fun (Eq, map_value, ctxt) -> - parse_var_annot loc annot ~default:map_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IBig_map_update (kinfo, k))} in - let stack = - Item_t (Big_map_t (map_key, map_value, map_name), rest, annot) - in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - | ( Prim (loc, I_GET_AND_UPDATE, [], annot), - Item_t - ( vk, - Item_t - ( Option_t (vv, vname), - Item_t (Big_map_t (ck, v, map_name), rest, map_annot), - v_annot ), - _ ) ) -> - let k = ty_of_comparable_ty ck in - check_item_ty ctxt vk k loc I_GET_AND_UPDATE 1 3 >>?= fun (Eq, _, ctxt) -> - check_item_ty ctxt vv v loc I_GET_AND_UPDATE 2 3 >>?= fun (Eq, v, ctxt) -> - parse_var_annot loc annot ~default:map_annot >>?= fun annot -> - let instr = - {apply = (fun kinfo k -> IBig_map_get_and_update (kinfo, k))} - in - let stack = - Item_t - ( Option_t (vv, vname), - Item_t (Big_map_t (ck, v, map_name), rest, annot), - v_annot ) - in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - (* Sapling *) - | (Prim (loc, I_SAPLING_EMPTY_STATE, [memo_size], annot), rest) -> - parse_memo_size memo_size >>?= fun memo_size -> - parse_var_annot loc annot ~default:default_sapling_state_annot - >>?= fun annot -> - let instr = - {apply = (fun kinfo k -> ISapling_empty_state (kinfo, memo_size, k))} - in - let stack = - Item_t (sapling_state_t ~memo_size ~annot:None, rest, annot) - in - typed ctxt loc instr stack - | ( Prim (loc, I_SAPLING_VERIFY_UPDATE, [], _), - Item_t - ( Sapling_transaction_t (transaction_memo_size, _), - Item_t - ( (Sapling_state_t (state_memo_size, _) as state_ty), - rest, - stack_annot ), - _ ) ) -> - merge_memo_sizes state_memo_size transaction_memo_size - >>?= fun _memo_size -> - let instr = - {apply = (fun kinfo k -> ISapling_verify_update (kinfo, k))} - in - pair_t - loc - (int_t ~annot:None, None, default_sapling_balance_annot) - (state_ty, None, None) - ~annot:None - >>?= fun pair_ty -> - option_t loc pair_ty ~annot:None >>?= fun ty -> - let stack = Item_t (ty, rest, stack_annot) in - typed ctxt loc instr stack - (* control *) - | (Seq (loc, []), stack) -> - let instr = {apply = (fun _kinfo k -> k)} in - typed ctxt loc instr stack - | (Seq (_, [single]), stack) -> - non_terminal_recursion ?type_logger tc_context ctxt ~legacy single stack - | (Seq (loc, hd :: tl), stack) -> ( - non_terminal_recursion ?type_logger tc_context ctxt ~legacy hd stack - >>=? fun (judgement, ctxt) -> - match judgement with - | Failed _ -> fail (Fail_not_in_tail_position (Micheline.location hd)) - | Typed ({aft = middle; _} as ihd) -> - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - (Seq (Micheline.dummy_location, tl)) - middle - >|=? fun (judgement, ctxt) -> - let judgement = - match judgement with - | Failed {descr} -> - let descr ret = compose_descr loc ihd (descr ret) in - Failed {descr} - | Typed itl -> Typed (compose_descr loc ihd itl) - in - (judgement, ctxt)) - | (Prim (loc, I_IF, [bt; bf], annot), (Item_t (Bool_t _, rest, _) as bef)) -> - check_kind [Seq_kind] bt >>?= fun () -> - check_kind [Seq_kind] bf >>?= fun () -> - error_unexpected_annot loc annot >>?= fun () -> - non_terminal_recursion ?type_logger tc_context ctxt ~legacy bt rest - >>=? fun (btr, ctxt) -> - non_terminal_recursion ?type_logger tc_context ctxt ~legacy bf rest - >>=? fun (bfr, ctxt) -> - let branch ibt ibf = - let infobt = kinfo_of_descr ibt and infobf = kinfo_of_descr ibf in - let instr = - { - apply = - (fun kinfo k -> - let hinfo = kinfo_of_kinstr k in - let branch_if_true = ibt.instr.apply infobt (IHalt hinfo) - and branch_if_false = ibf.instr.apply infobf (IHalt hinfo) in - IIf {kinfo; branch_if_true; branch_if_false; k}); - } - in - {loc; instr; bef; aft = ibt.aft} - in - Lwt.return @@ merge_branches ~legacy ctxt loc btr bfr {branch} - | ( Prim (loc, I_LOOP, [body], annot), - (Item_t (Bool_t _, rest, _stack_annot) as stack) ) -> ( - check_kind [Seq_kind] body >>?= fun () -> - error_unexpected_annot loc annot >>?= fun () -> - non_terminal_recursion ?type_logger tc_context ctxt ~legacy body rest - >>=? fun (judgement, ctxt) -> - Lwt.return - @@ - match judgement with - | Typed ibody -> - let unmatched_branches () = - let aft = serialize_stack_for_error ctxt ibody.aft in - let stack = serialize_stack_for_error ctxt stack in - Unmatched_branches (loc, aft, stack) - in - record_trace_eval - unmatched_branches - ( merge_stacks ~legacy loc ctxt 1 ibody.aft stack - >>? fun (Eq, _stack, ctxt) -> - let instr = - { - apply = - (fun kinfo k -> - let ibody = - ibody.instr.apply (kinfo_of_descr ibody) (IHalt kinfo) - in - ILoop (kinfo, ibody, k)); - } - in - typed_no_lwt ctxt loc instr rest ) - | Failed {descr} -> - let instr = - { - apply = - (fun kinfo k -> - let ibody = descr stack in - let ibody = - ibody.instr.apply (kinfo_of_descr ibody) (IHalt kinfo) - in - ILoop (kinfo, ibody, k)); - } - in - typed_no_lwt ctxt loc instr rest) - | ( Prim (loc, I_LOOP_LEFT, [body], annot), - (Item_t (Union_t ((tl, l_field), (tr, _), _), rest, union_annot) as stack) - ) -> ( - check_kind [Seq_kind] body >>?= fun () -> - parse_var_annot loc annot >>?= fun annot -> - let l_annot = - gen_access_annot union_annot l_field ~default:default_left_annot - in - non_terminal_recursion - ?type_logger - tc_context - ctxt - ~legacy - body - (Item_t (tl, rest, l_annot)) - >>=? fun (judgement, ctxt) -> - Lwt.return - @@ - match judgement with - | Typed ibody -> - let unmatched_branches () = - let aft = serialize_stack_for_error ctxt ibody.aft in - let stack = serialize_stack_for_error ctxt stack in - Unmatched_branches (loc, aft, stack) - in - record_trace_eval - unmatched_branches - ( merge_stacks ~legacy loc ctxt 1 ibody.aft stack - >>? fun (Eq, _stack, ctxt) -> - let instr = - { - apply = - (fun kinfo k -> - let ibody = - ibody.instr.apply (kinfo_of_descr ibody) (IHalt kinfo) - in - ILoop_left (kinfo, ibody, k)); - } - in - let stack = Item_t (tr, rest, annot) in - typed_no_lwt ctxt loc instr stack ) - | Failed {descr} -> - let instr = - { - apply = - (fun kinfo k -> - let ibody = descr stack in - let ibody = - ibody.instr.apply (kinfo_of_descr ibody) (IHalt kinfo) - in - ILoop_left (kinfo, ibody, k)); - } - in - let stack = Item_t (tr, rest, annot) in - typed_no_lwt ctxt loc instr stack) - | (Prim (loc, I_LAMBDA, [arg; ret; code], annot), stack) -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy arg - >>?= fun (Ex_ty arg, ctxt) -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy ret - >>?= fun (Ex_ty ret, ctxt) -> - check_kind [Seq_kind] code >>?= fun () -> - parse_var_annot loc annot >>?= fun annot -> - parse_returning - Lambda - ?type_logger - ~stack_depth:(stack_depth + 1) - ctxt - ~legacy - (arg, default_arg_annot) - ret - code - >>=? fun (lambda, ctxt) -> - let instr = {apply = (fun kinfo k -> ILambda (kinfo, lambda, k))} in - lambda_t loc arg ret ~annot:None >>?= fun ty -> - let stack = Item_t (ty, stack, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_EXEC, [], annot), - Item_t (arg, Item_t (Lambda_t (param, ret, _), rest, _), _) ) -> - check_item_ty ctxt arg param loc I_EXEC 1 2 >>?= fun (Eq, _, ctxt) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IExec (kinfo, k))} in - let stack = Item_t (ret, rest, annot) in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - | ( Prim (loc, I_APPLY, [], annot), - Item_t - ( capture, - Item_t - ( Lambda_t - ( Pair_t - ((capture_ty, _, _), (arg_ty, _, _), {annot = lam_annot; _}), - ret, - _ ), - rest, - _ ), - _ ) ) -> - check_packable ~legacy:false loc capture_ty >>?= fun () -> - check_item_ty ctxt capture capture_ty loc I_APPLY 1 2 - >>?= fun (Eq, capture_ty, ctxt) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IApply (kinfo, capture_ty, k))} in - lambda_t loc arg_ty ret ~annot:lam_annot - (* This cannot fail because the type [lambda 'arg 'ret] is always smaller than - the input type [lambda (pair 'arg 'capture) 'ret]. In an ideal world, there - would be a smart deconstructor to ensure this statically. *) - >>?= - fun res_ty -> - let stack = Item_t (res_ty, rest, annot) in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - | (Prim (loc, I_DIP, [code], annot), Item_t (v, rest, stack_annot)) -> ( - error_unexpected_annot loc annot >>?= fun () -> - check_kind [Seq_kind] code >>?= fun () -> - non_terminal_recursion - ?type_logger - (add_dip v stack_annot tc_context) - ctxt - ~legacy - code - rest - >>=? fun (judgement, ctxt) -> - match judgement with - | Typed descr -> - let instr = - { - apply = - (fun kinfo k -> - let binfo = {iloc = descr.loc; kstack_ty = descr.bef} in - let kinfoh = {iloc = descr.loc; kstack_ty = descr.aft} in - let b = descr.instr.apply binfo (IHalt kinfoh) in - IDip (kinfo, b, k)); - } - in - let stack = Item_t (v, descr.aft, stack_annot) in - typed ctxt loc instr stack - | Failed _ -> fail (Fail_not_in_tail_position loc)) - | (Prim (loc, I_DIP, [n; code], result_annot), stack) -> - parse_uint10 n >>?= fun n -> - Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> - let rec make_proof_argument : - type a s. - int -> - tc_context -> - (a, s) stack_ty -> - (a, s) dipn_proof_argument tzresult Lwt.t = - fun n inner_tc_context stk -> - match (Compare.Int.(n = 0), stk) with - | (true, rest) -> ( - non_terminal_recursion - ?type_logger - inner_tc_context - ctxt - ~legacy - code - rest - >>=? fun (judgement, ctxt) -> - Lwt.return - @@ - match judgement with - | Typed descr -> - ok - (Dipn_proof_argument (KRest, ctxt, descr, descr.aft) - : (a, s) dipn_proof_argument) - | Failed _ -> error (Fail_not_in_tail_position loc)) - | (false, Item_t (v, rest, annot)) -> - make_proof_argument (n - 1) (add_dip v annot tc_context) rest - >|=? fun (Dipn_proof_argument (n', ctxt, descr, aft')) -> - let kinfo' = {iloc = loc; kstack_ty = aft'} in - let w = KPrefix (kinfo', n') in - Dipn_proof_argument (w, ctxt, descr, Item_t (v, aft', annot)) - | (_, _) -> - Lwt.return - (let whole_stack = serialize_stack_for_error ctxt stack in - error (Bad_stack (loc, I_DIP, 1, whole_stack))) - in - error_unexpected_annot loc result_annot >>?= fun () -> - make_proof_argument n tc_context stack - >>=? fun (Dipn_proof_argument (n', ctxt, descr, aft)) -> - let kinfo = {iloc = descr.loc; kstack_ty = descr.bef} in - let kinfoh = {iloc = descr.loc; kstack_ty = descr.aft} in - let b = descr.instr.apply kinfo (IHalt kinfoh) in - let res = {apply = (fun kinfo k -> IDipn (kinfo, n, n', b, k))} in - typed ctxt loc res aft - | (Prim (loc, I_DIP, (([] | _ :: _ :: _ :: _) as l), _), _) -> - (* Technically, the arities 1 and 2 are allowed but the error only mentions 2. - However, DIP {code} is equivalent to DIP 1 {code} so hinting at an arity of 2 makes sense. *) - fail (Invalid_arity (loc, I_DIP, 2, List.length l)) - | (Prim (loc, I_FAILWITH, [], annot), Item_t (v, _rest, _)) -> - Lwt.return - ( error_unexpected_annot loc annot >>? fun () -> - (if legacy then Result.return_unit - else check_packable ~legacy:false loc v) - >|? fun () -> - let instr = {apply = (fun kinfo _k -> IFailwith (kinfo, loc, v))} in - let descr aft = {loc; instr; bef = stack_ty; aft} in - log_stack loc stack_ty Bot_t ; - (Failed {descr}, ctxt) ) - | (Prim (loc, I_NEVER, [], annot), Item_t (Never_t _, _rest, _)) -> - Lwt.return - ( error_unexpected_annot loc annot >|? fun () -> - let instr = {apply = (fun kinfo _k -> INever kinfo)} in - let descr aft = {loc; instr; bef = stack_ty; aft} in - log_stack loc stack_ty Bot_t ; - (Failed {descr}, ctxt) ) - (* timestamp operations *) - | ( Prim (loc, I_ADD, [], annot), - Item_t (Timestamp_t tname, Item_t (Int_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = - {apply = (fun kinfo k -> IAdd_timestamp_to_seconds (kinfo, k))} - in - typed ctxt loc instr (Item_t (Timestamp_t tname, rest, annot)) - | ( Prim (loc, I_ADD, [], annot), - Item_t (Int_t _, Item_t (Timestamp_t tname, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = - {apply = (fun kinfo k -> IAdd_seconds_to_timestamp (kinfo, k))} - in - typed ctxt loc instr (Item_t (Timestamp_t tname, rest, annot)) - | ( Prim (loc, I_SUB, [], annot), - Item_t (Timestamp_t tname, Item_t (Int_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = - {apply = (fun kinfo k -> ISub_timestamp_seconds (kinfo, k))} - in - let stack = Item_t (Timestamp_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_SUB, [], annot), - Item_t - ( Timestamp_t {annot = tn1; size = _}, - Item_t (Timestamp_t {annot = tn2; size = _}, rest, _), - _ ) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_annot ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IDiff_timestamps (kinfo, k))} in - let stack = Item_t (int_t ~annot:tname, rest, annot) in - typed ctxt loc instr stack - (* string operations *) - | ( Prim (loc, I_CONCAT, [], annot), - Item_t (String_t tn1, Item_t (String_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IConcat_string_pair (kinfo, k))} in - typed ctxt loc instr (Item_t (String_t tname, rest, annot)) - | ( 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 -> - let instr = {apply = (fun kinfo k -> IConcat_string (kinfo, k))} in - typed ctxt loc instr (Item_t (String_t tname, rest, annot)) - | ( Prim (loc, I_SLICE, [], annot), - Item_t - ( Nat_t _, - Item_t (Nat_t _, Item_t (String_t tname, rest, string_annot), _), - _ ) ) -> - parse_var_annot - ~default:(gen_access_annot string_annot default_slice_annot) - loc - annot - >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISlice_string (kinfo, k))} in - let stack = Item_t (option_string'_t tname, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_SIZE, [], annot), Item_t (String_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IString_size (kinfo, k))} in - let stack = Item_t (nat_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - (* bytes operations *) - | ( Prim (loc, I_CONCAT, [], annot), - Item_t (Bytes_t tn1, Item_t (Bytes_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IConcat_bytes_pair (kinfo, k))} in - let stack = Item_t (Bytes_t tname, rest, annot) in - typed ctxt loc instr stack - | ( 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 -> - let instr = {apply = (fun kinfo k -> IConcat_bytes (kinfo, k))} in - let stack = Item_t (Bytes_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_SLICE, [], annot), - Item_t - ( Nat_t _, - Item_t (Nat_t _, Item_t (Bytes_t tname, rest, bytes_annot), _), - _ ) ) -> - parse_var_annot - ~default:(gen_access_annot bytes_annot default_slice_annot) - loc - annot - >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISlice_bytes (kinfo, k))} in - let stack = Item_t (option_bytes'_t tname, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_SIZE, [], annot), Item_t (Bytes_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IBytes_size (kinfo, k))} in - let stack = Item_t (nat_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - (* currency operations *) - | ( Prim (loc, I_ADD, [], annot), - Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IAdd_tez (kinfo, k))} in - let stack = Item_t (Mutez_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_SUB, [], annot), - Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) ) -> - if legacy then - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> ISub_tez_legacy (kinfo, k))} in - let stack = Item_t (Mutez_t tname, rest, annot) in - typed ctxt loc instr stack - else fail (Deprecated_instruction I_SUB) - | ( Prim (loc, I_SUB_MUTEZ, [], annot), - Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> ISub_tez (kinfo, k))} in - let stack = Item_t (option_mutez'_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Mutez_t tname, Item_t (Nat_t _, rest, _), _) ) -> - (* no type name check *) - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_teznat (kinfo, k))} in - let stack = Item_t (Mutez_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Nat_t _, Item_t (Mutez_t tname, rest, _), _) ) -> - (* no type name check *) - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_nattez (kinfo, k))} in - let stack = Item_t (Mutez_t tname, rest, annot) in - typed ctxt loc instr stack - (* boolean operations *) - | ( Prim (loc, I_OR, [], annot), - Item_t (Bool_t tn1, Item_t (Bool_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IOr (kinfo, k))} in - let stack = Item_t (Bool_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_AND, [], annot), - Item_t (Bool_t tn1, Item_t (Bool_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IAnd (kinfo, k))} in - let stack = Item_t (Bool_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_XOR, [], annot), - Item_t (Bool_t tn1, Item_t (Bool_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IXor (kinfo, k))} in - let stack = Item_t (Bool_t tname, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_NOT, [], annot), Item_t (Bool_t tname, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INot (kinfo, k))} in - let stack = Item_t (Bool_t tname, rest, annot) in - typed ctxt loc instr stack - (* integer operations *) - | (Prim (loc, I_ABS, [], annot), Item_t (Int_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IAbs_int (kinfo, k))} in - let stack = Item_t (nat_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_ISNAT, [], annot), Item_t (Int_t _, rest, int_annot)) -> - parse_var_annot loc annot ~default:int_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IIs_nat (kinfo, k))} in - let stack = Item_t (option_nat_t, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_INT, [], annot), Item_t (Nat_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IInt_nat (kinfo, k))} in - let stack = Item_t (int_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_NEG, [], annot), Item_t (Int_t tname, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INeg (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_NEG, [], annot), Item_t (Nat_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INeg (kinfo, k))} in - let stack = Item_t (int_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_ADD, [], annot), - Item_t (Int_t tn1, Item_t (Int_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IAdd_int (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_ADD, [], annot), - Item_t (Int_t tname, Item_t (Nat_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IAdd_int (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_ADD, [], annot), - Item_t (Nat_t _, Item_t (Int_t tname, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IAdd_int (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_ADD, [], annot), - Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IAdd_nat (kinfo, k))} in - let stack = Item_t (Nat_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_SUB, [], annot), - Item_t (Int_t tn1, Item_t (Int_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> ISub_int (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_SUB, [], annot), - Item_t (Int_t tname, Item_t (Nat_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISub_int (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_SUB, [], annot), - Item_t (Nat_t _, Item_t (Int_t tname, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISub_int (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_SUB, [], annot), - Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun _tname -> - let instr = {apply = (fun kinfo k -> ISub_int (kinfo, k))} in - let stack = Item_t (int_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Int_t tn1, Item_t (Int_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IMul_int (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Int_t tname, Item_t (Nat_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_int (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Nat_t _, Item_t (Int_t tname, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_nat (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IMul_nat (kinfo, k))} in - let stack = Item_t (Nat_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_EDIV, [], annot), - Item_t (Mutez_t tname, Item_t (Nat_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IEdiv_teznat (kinfo, k))} in - let stack = Item_t (option_pair_mutez'_mutez'_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_EDIV, [], annot), - Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IEdiv_tez (kinfo, k))} in - let stack = Item_t (option_pair_nat_mutez'_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_EDIV, [], annot), - Item_t (Int_t tn1, Item_t (Int_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IEdiv_int (kinfo, k))} in - let stack = Item_t (option_pair_int'_nat_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_EDIV, [], annot), - Item_t (Int_t tname, Item_t (Nat_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IEdiv_int (kinfo, k))} in - let stack = Item_t (option_pair_int'_nat_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_EDIV, [], annot), - Item_t (Nat_t tname, Item_t (Int_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IEdiv_nat (kinfo, k))} in - let stack = Item_t (option_pair_int_nat'_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_EDIV, [], annot), - Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IEdiv_nat (kinfo, k))} in - let stack = Item_t (option_pair_nat'_nat'_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_LSL, [], annot), - Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> ILsl_nat (kinfo, k))} in - let stack = Item_t (Nat_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_LSR, [], annot), - Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> ILsr_nat (kinfo, k))} in - let stack = Item_t (Nat_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_OR, [], annot), - Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IOr_nat (kinfo, k))} in - let stack = Item_t (Nat_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_AND, [], annot), - Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IAnd_nat (kinfo, k))} in - let stack = Item_t (Nat_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_AND, [], annot), - Item_t (Int_t _, Item_t (Nat_t tname, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IAnd_int_nat (kinfo, k))} in - let stack = Item_t (Nat_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_XOR, [], annot), - Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IXor_nat (kinfo, k))} in - let stack = Item_t (Nat_t tname, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_NOT, [], annot), Item_t (Int_t tname, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INot_int (kinfo, k))} in - let stack = Item_t (Int_t tname, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_NOT, [], annot), Item_t (Nat_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INot_int (kinfo, k))} in - let stack = Item_t (int_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - (* comparison *) - | (Prim (loc, I_COMPARE, [], annot), Item_t (t1, Item_t (t2, rest, _), _)) -> - parse_var_annot loc annot >>?= fun annot -> - check_item_ty ctxt t1 t2 loc I_COMPARE 1 2 >>?= fun (Eq, t, ctxt) -> - comparable_ty_of_ty ctxt loc t >>?= fun (key, ctxt) -> - let instr = {apply = (fun kinfo k -> ICompare (kinfo, key, k))} in - let stack = Item_t (int_t ~annot:None, rest, annot) in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - (* comparators *) - | (Prim (loc, I_EQ, [], annot), Item_t (Int_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IEq (kinfo, k))} in - let stack = Item_t (bool_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_NEQ, [], annot), Item_t (Int_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INeq (kinfo, k))} in - let stack = Item_t (bool_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_LT, [], annot), Item_t (Int_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ILt (kinfo, k))} in - let stack = Item_t (bool_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_GT, [], annot), Item_t (Int_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IGt (kinfo, k))} in - let stack = Item_t (bool_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_LE, [], annot), Item_t (Int_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ILe (kinfo, k))} in - let stack = Item_t (bool_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_GE, [], annot), Item_t (Int_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IGe (kinfo, k))} in - let stack = Item_t (bool_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - (* annotations *) - | (Prim (loc, I_CAST, [cast_t], annot), Item_t (t, stack, item_annot)) -> - parse_var_annot loc annot ~default:item_annot >>?= fun annot -> - parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy cast_t - >>?= fun (Ex_ty cast_t, ctxt) -> - ty_eq ~legacy ctxt loc cast_t t >>?= fun (Eq, ctxt) -> - let instr = {apply = (fun _ k -> k)} in - let stack = Item_t (cast_t, stack, annot) in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - | (Prim (loc, I_RENAME, [], annot), Item_t (t, stack, _)) -> - parse_var_annot loc annot >>?= fun annot -> - (* can erase annot *) - let instr = {apply = (fun _ k -> k)} in - let stack = Item_t (t, stack, annot) in - typed ctxt loc instr stack - (* packing *) - | (Prim (loc, I_PACK, [], annot), Item_t (t, rest, unpacked_annot)) -> - check_packable - ~legacy:true - (* allow to pack contracts for hash/signature checks *) loc - t - >>?= fun () -> - parse_var_annot - loc - annot - ~default:(gen_access_annot unpacked_annot default_pack_annot) - >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IPack (kinfo, t, k))} in - let stack = Item_t (bytes_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_UNPACK, [ty], annot), Item_t (Bytes_t _, rest, packed_annot)) - -> - parse_packable_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy ty - >>?= fun (Ex_ty t, ctxt) -> - parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> - option_t loc t ~annot:ty_name >>?= fun res_ty -> - let annot = - default_annot - annot - ~default:(gen_access_annot packed_annot default_unpack_annot) - in - let instr = {apply = (fun kinfo k -> IUnpack (kinfo, t, k))} in - let stack = Item_t (res_ty, rest, annot) in - typed ctxt loc instr stack - (* protocol *) - | ( Prim (loc, I_ADDRESS, [], annot), - Item_t (Contract_t _, rest, contract_annot) ) -> - parse_var_annot - loc - annot - ~default:(gen_access_annot contract_annot default_addr_annot) - >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IAddress (kinfo, k))} in - let stack = Item_t (address_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_CONTRACT, [ty], annot), Item_t (Address_t _, rest, addr_annot)) - -> - parse_parameter_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy ty - >>?= fun (Ex_ty t, ctxt) -> - contract_t loc t ~annot:None >>?= fun contract_ty -> - option_t loc contract_ty ~annot:None >>?= fun res_ty -> - parse_entrypoint_annot - loc - annot - ~default:(gen_access_annot addr_annot default_contract_annot) - >>?= fun (annot, entrypoint) -> - (match entrypoint with - | None -> Ok "default" - | Some (Field_annot entrypoint) -> - let entrypoint = (entrypoint :> string) in - if Compare.String.(entrypoint = "default") then - error (Unexpected_annotation loc) - else if Compare.Int.(String.length entrypoint > 31) then - error (Entrypoint_name_too_long entrypoint) - else Ok entrypoint) - >>?= fun entrypoint -> - let instr = - {apply = (fun kinfo k -> IContract (kinfo, t, entrypoint, k))} - in - let stack = Item_t (res_ty, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_VIEW, [name; output_ty], annot), - Item_t (input_ty, Item_t (Address_t _, rest, addr_annot), _) ) -> - let output_ty_loc = location output_ty in - parse_view_name ctxt name >>?= fun (name, ctxt) -> - parse_view_output_ty ctxt ~stack_depth:0 ~legacy output_ty - >>?= fun (Ex_ty output_ty, ctxt) -> - option_t output_ty_loc output_ty ~annot:None >>?= fun res_ty -> - parse_var_annot - loc - annot - ~default:(gen_access_annot addr_annot default_contract_annot) - >>?= fun annot -> - let instr = - { - apply = - (fun kinfo k -> - IView (kinfo, View_signature {name; input_ty; output_ty}, k)); - } - in - let stack = Item_t (res_ty, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_TRANSFER_TOKENS, [], annot), - Item_t (p, Item_t (Mutez_t _, Item_t (Contract_t (cp, _), rest, _), _), _) - ) -> - check_item_ty ctxt p cp loc I_TRANSFER_TOKENS 1 4 - >>?= fun (Eq, _, ctxt) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ITransfer_tokens (kinfo, k))} in - let stack = Item_t (operation_t ~annot:None, rest, annot) in - (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) - | ( Prim (loc, I_SET_DELEGATE, [], annot), - Item_t (Option_t (Key_hash_t _, _), rest, _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISet_delegate (kinfo, k))} in - let stack = Item_t (operation_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (_, I_CREATE_ACCOUNT, _, _), _) -> - fail (Deprecated_instruction I_CREATE_ACCOUNT) - | (Prim (loc, I_IMPLICIT_ACCOUNT, [], annot), Item_t (Key_hash_t _, rest, _)) - -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IImplicit_account (kinfo, k))} in - let stack = Item_t (contract_unit_t, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_CREATE_CONTRACT, [(Seq _ as code)], annot), - Item_t - ( Option_t (Key_hash_t _, _), - Item_t (Mutez_t _, Item_t (ginit, rest, _), _), - _ ) ) -> - parse_two_var_annot loc annot >>?= fun (op_annot, addr_annot) -> - let canonical_code = Micheline.strip_locations code in - parse_toplevel ctxt ~legacy canonical_code - >>?= fun ({arg_type; storage_type; code_field; views; root_name}, ctxt) -> - record_trace - (Ill_formed_type (Some "parameter", canonical_code, location arg_type)) - (parse_parameter_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - arg_type) - >>?= fun (Ex_ty arg_type, ctxt) -> - (if legacy then Result.return_unit - else well_formed_entrypoints ~root_name arg_type) - >>?= fun () -> - record_trace - (Ill_formed_type (Some "storage", canonical_code, location storage_type)) - (parse_storage_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - storage_type) - >>?= fun (Ex_ty storage_type, ctxt) -> - let arg_annot = - default_annot - (type_to_var_annot (name_of_ty arg_type)) - ~default:default_param_annot - in - let storage_annot = - default_annot - (type_to_var_annot (name_of_ty storage_type)) - ~default:default_storage_annot - in - pair_t - loc - (arg_type, None, arg_annot) - (storage_type, None, storage_annot) - ~annot:None - >>?= fun arg_type_full -> - pair_t - loc - (list_operation_t, None, None) - (storage_type, None, None) - ~annot:None - >>?= fun ret_type_full -> - trace - (Ill_typed_contract (canonical_code, [])) - (parse_returning - (Toplevel {storage_type; param_type = arg_type; root_name}) - ctxt - ~legacy - ?type_logger - ~stack_depth:(stack_depth + 1) - (arg_type_full, None) - ret_type_full - code_field) - >>=? fun ( (Lam - ( { - kbef = Item_t (arg, Bot_t, _); - kaft = Item_t (ret, Bot_t, _); - _; - }, - _ ) as lambda), - ctxt ) -> - let views_result = - typecheck_views ctxt ?type_logger ~legacy storage_type views - in - trace (Ill_typed_contract (canonical_code, [])) views_result - >>=? fun ctxt -> - ty_eq ~legacy ctxt loc arg arg_type_full >>?= fun (Eq, ctxt) -> - ty_eq ~legacy ctxt loc ret ret_type_full >>?= fun (Eq, ctxt) -> - ty_eq ~legacy ctxt loc storage_type ginit >>?= fun (Eq, ctxt) -> - let instr = - { - apply = - (fun kinfo k -> - ICreate_contract - {kinfo; storage_type; arg_type; lambda; views; root_name; k}); - } - in - let stack = - Item_t - ( operation_t ~annot:None, - Item_t (address_t ~annot:None, rest, addr_annot), - op_annot ) - in - typed ctxt loc instr stack - | (Prim (loc, I_NOW, [], annot), stack) -> - parse_var_annot loc annot ~default:default_now_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INow (kinfo, k))} in - let stack = Item_t (timestamp_t ~annot:None, stack, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_AMOUNT, [], annot), stack) -> - parse_var_annot loc annot ~default:default_amount_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IAmount (kinfo, k))} in - let stack = Item_t (mutez_t ~annot:None, stack, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_CHAIN_ID, [], annot), stack) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IChainId (kinfo, k))} in - let stack = Item_t (chain_id_t ~annot:None, stack, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_BALANCE, [], annot), stack) -> - parse_var_annot loc annot ~default:default_balance_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IBalance (kinfo, k))} in - let stack = Item_t (mutez_t ~annot:None, stack, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_LEVEL, [], annot), stack) -> - parse_var_annot loc annot ~default:default_level_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ILevel (kinfo, k))} in - let stack = Item_t (nat_t ~annot:None, stack, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_VOTING_POWER, [], annot), Item_t (Key_hash_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IVoting_power (kinfo, k))} in - let stack = Item_t (nat_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_TOTAL_VOTING_POWER, [], annot), stack) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ITotal_voting_power (kinfo, k))} in - let stack = Item_t (nat_t ~annot:None, stack, annot) in - typed ctxt loc instr stack - | (Prim (_, I_STEPS_TO_QUOTA, _, _), _) -> - fail (Deprecated_instruction I_STEPS_TO_QUOTA) - | (Prim (loc, I_SOURCE, [], annot), stack) -> - parse_var_annot loc annot ~default:default_source_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISource (kinfo, k))} in - let stack = Item_t (address_t ~annot:None, stack, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_SENDER, [], annot), stack) -> - parse_var_annot loc annot ~default:default_sender_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISender (kinfo, k))} in - let stack = Item_t (address_t ~annot:None, stack, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_SELF, [], annot), stack) -> - Lwt.return - ( parse_entrypoint_annot loc annot ~default:default_self_annot - >>? fun (annot, entrypoint) -> - let entrypoint = - Option.fold - ~some:(fun (Field_annot annot) -> (annot :> string)) - ~none:"default" - entrypoint - in - let rec get_toplevel_type : - tc_context -> ((a, s) judgement * context) tzresult = function - | Lambda -> error (Self_in_lambda loc) - | Dip (_, prev) -> get_toplevel_type prev - | Toplevel {param_type; root_name; storage_type = _} -> - find_entrypoint param_type ~root_name entrypoint - >>? fun (_, Ex_ty param_type) -> - contract_t loc param_type ~annot:None >>? fun res_ty -> - let instr = - { - apply = - (fun kinfo k -> ISelf (kinfo, param_type, entrypoint, k)); - } - in - let stack = Item_t (res_ty, stack, annot) in - typed_no_lwt ctxt loc instr stack - in - get_toplevel_type tc_context ) - | (Prim (loc, I_SELF_ADDRESS, [], annot), stack) -> - parse_var_annot loc annot ~default:default_self_annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISelf_address (kinfo, k))} in - let stack = Item_t (address_t ~annot:None, stack, annot) in - typed ctxt loc instr stack - (* cryptography *) - | (Prim (loc, I_HASH_KEY, [], annot), Item_t (Key_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IHash_key (kinfo, k))} in - let stack = Item_t (key_hash_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_CHECK_SIGNATURE, [], annot), - Item_t (Key_t _, Item_t (Signature_t _, Item_t (Bytes_t _, rest, _), _), _) - ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ICheck_signature (kinfo, k))} in - let stack = Item_t (bool_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_BLAKE2B, [], annot), Item_t (Bytes_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IBlake2b (kinfo, k))} in - let stack = Item_t (bytes_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_SHA256, [], annot), Item_t (Bytes_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISha256 (kinfo, k))} in - let stack = Item_t (bytes_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_SHA512, [], annot), Item_t (Bytes_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISha512 (kinfo, k))} in - let stack = Item_t (bytes_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_KECCAK, [], annot), Item_t (Bytes_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IKeccak (kinfo, k))} in - let stack = Item_t (bytes_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_SHA3, [], annot), Item_t (Bytes_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> ISha3 (kinfo, k))} in - let stack = Item_t (bytes_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_ADD, [], annot), - Item_t (Bls12_381_g1_t tn1, Item_t (Bls12_381_g1_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IAdd_bls12_381_g1 (kinfo, k))} in - let stack = Item_t (Bls12_381_g1_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_ADD, [], annot), - Item_t (Bls12_381_g2_t tn1, Item_t (Bls12_381_g2_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IAdd_bls12_381_g2 (kinfo, k))} in - let stack = Item_t (Bls12_381_g2_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_ADD, [], annot), - Item_t (Bls12_381_fr_t tn1, Item_t (Bls12_381_fr_t tn2, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> - let instr = {apply = (fun kinfo k -> IAdd_bls12_381_fr (kinfo, k))} in - let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Bls12_381_g1_t tname, Item_t (Bls12_381_fr_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_bls12_381_g1 (kinfo, k))} in - let stack = Item_t (Bls12_381_g1_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Bls12_381_g2_t tname, Item_t (Bls12_381_fr_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_bls12_381_g2 (kinfo, k))} in - let stack = Item_t (Bls12_381_g2_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Bls12_381_fr_t tname, Item_t (Bls12_381_fr_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_bls12_381_fr (kinfo, k))} in - let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Nat_t {annot = tname; _}, Item_t (Bls12_381_fr_t _, rest, _), _) - ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_bls12_381_fr_z (kinfo, k))} in - let stack = Item_t (bls12_381_fr_t ~annot:tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Int_t {annot = tname; _}, Item_t (Bls12_381_fr_t _, rest, _), _) - ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_bls12_381_fr_z (kinfo, k))} in - let stack = Item_t (bls12_381_fr_t ~annot:tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Bls12_381_fr_t tname, Item_t (Int_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_bls12_381_z_fr (kinfo, k))} in - let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_MUL, [], annot), - Item_t (Bls12_381_fr_t tname, Item_t (Nat_t _, rest, _), _) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IMul_bls12_381_z_fr (kinfo, k))} in - let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_INT, [], annot), Item_t (Bls12_381_fr_t _, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> IInt_bls12_381_fr (kinfo, k))} in - let stack = Item_t (int_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_NEG, [], annot), Item_t (Bls12_381_g1_t tname, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INeg_bls12_381_g1 (kinfo, k))} in - let stack = Item_t (Bls12_381_g1_t tname, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_NEG, [], annot), Item_t (Bls12_381_g2_t tname, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INeg_bls12_381_g2 (kinfo, k))} in - let stack = Item_t (Bls12_381_g2_t tname, rest, annot) in - typed ctxt loc instr stack - | (Prim (loc, I_NEG, [], annot), Item_t (Bls12_381_fr_t tname, rest, _)) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = {apply = (fun kinfo k -> INeg_bls12_381_fr (kinfo, k))} in - let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_PAIRING_CHECK, [], annot), - Item_t - ( List_t - (Pair_t ((Bls12_381_g1_t _, _, _), (Bls12_381_g2_t _, _, _), _), _), - rest, - _ ) ) -> - parse_var_annot loc annot >>?= fun annot -> - let instr = - {apply = (fun kinfo k -> IPairing_check_bls12_381 (kinfo, k))} - in - let stack = Item_t (bool_t ~annot:None, rest, annot) in - typed ctxt loc instr stack - (* Tickets *) - | (Prim (loc, I_TICKET, [], annot), Item_t (t, Item_t (Nat_t _, rest, _), _)) - -> - parse_var_annot loc annot >>?= fun annot -> - comparable_ty_of_ty ctxt loc t >>?= fun (ty, ctxt) -> - ticket_t loc ty ~annot:None >>?= fun res_ty -> - let instr = {apply = (fun kinfo k -> ITicket (kinfo, k))} in - let stack = Item_t (res_ty, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_READ_TICKET, [], annot), - (Item_t (Ticket_t (t, _), _, _) as full_stack) ) -> - parse_var_annot loc annot >>?= fun annot -> - let () = check_dupable_comparable_ty t in - opened_ticket_type loc t >>?= fun opened_ticket_ty -> - let result = ty_of_comparable_ty opened_ticket_ty in - let instr = {apply = (fun kinfo k -> IRead_ticket (kinfo, k))} in - let stack = Item_t (result, full_stack, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_SPLIT_TICKET, [], annot), - Item_t - ( (Ticket_t (t, _) as ticket_t), - Item_t - (Pair_t ((Nat_t _, fa_a, a_a), (Nat_t _, fa_b, a_b), _), rest, _), - _ ) ) -> - parse_var_annot loc annot >>?= fun annot -> - let () = check_dupable_comparable_ty t in - pair_t loc (ticket_t, fa_a, a_a) (ticket_t, fa_b, a_b) ~annot:None - >>?= fun pair_tickets_ty -> - option_t loc pair_tickets_ty ~annot:None >>?= fun res_ty -> - let instr = {apply = (fun kinfo k -> ISplit_ticket (kinfo, k))} in - let stack = Item_t (res_ty, rest, annot) in - typed ctxt loc instr stack - | ( Prim (loc, I_JOIN_TICKETS, [], annot), - Item_t - ( Pair_t (((Ticket_t _ as ty_a), _, _), ((Ticket_t _ as ty_b), _, _), _), - rest, - _ ) ) -> ( - parse_var_annot loc annot >>?= fun annot -> - Gas_monad.run ctxt - @@ merge_types - ~legacy - ~merge_type_error_flag:Default_merge_type_error - loc - ty_a - ty_b - >>?= fun (eq_ty, ctxt) -> - eq_ty >>?= fun (Eq, ty) -> - match ty with - | Ticket_t (contents_ty, _) -> - option_t loc ty ~annot:None >>?= fun res_ty -> - let instr = - {apply = (fun kinfo k -> IJoin_tickets (kinfo, contents_ty, k))} - in - let stack = Item_t (res_ty, rest, annot) in - typed ctxt loc instr stack - | _ -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/1962 - fix injectivity of types *) - assert false) - (* Timelocks *) - | ( Prim (loc, I_OPEN_CHEST, [], _), - Item_t (Chest_key_t _, Item_t (Chest_t _, Item_t (Nat_t _, rest, _), _), _) - ) -> - let instr = {apply = (fun kinfo k -> IOpen_chest (kinfo, k))} in - typed ctxt loc instr (Item_t (union_bytes_bool_t, rest, None)) - (* Primitive parsing errors *) - | ( Prim - ( loc, - (( I_DUP | I_SWAP | I_SOME | I_UNIT | I_PAIR | I_UNPAIR | I_CAR - | I_CDR | I_CONS | I_CONCAT | I_SLICE | I_MEM | I_UPDATE | I_GET - | I_EXEC | I_FAILWITH | I_SIZE | I_ADD | I_SUB | I_SUB_MUTEZ | I_MUL - | I_EDIV | I_OR | I_AND | I_XOR | I_NOT | I_ABS | I_NEG | I_LSL - | I_LSR | I_COMPARE | I_EQ | I_NEQ | I_LT | I_GT | I_LE | I_GE - | I_TRANSFER_TOKENS | I_SET_DELEGATE | I_NOW | I_IMPLICIT_ACCOUNT - | I_AMOUNT | I_BALANCE | I_LEVEL | I_CHECK_SIGNATURE | I_HASH_KEY - | I_SOURCE | I_SENDER | I_BLAKE2B | I_SHA256 | I_SHA512 | I_ADDRESS - | I_RENAME | I_PACK | I_ISNAT | I_INT | I_SELF | I_CHAIN_ID | I_NEVER - | I_VOTING_POWER | I_TOTAL_VOTING_POWER | I_KECCAK | I_SHA3 - | I_PAIRING_CHECK | I_TICKET | I_READ_TICKET | I_SPLIT_TICKET - | I_JOIN_TICKETS | I_OPEN_CHEST ) as name), - (_ :: _ as l), - _ ), - _ ) -> - fail (Invalid_arity (loc, name, 0, List.length l)) - | ( Prim - ( loc, - (( I_NONE | I_LEFT | I_RIGHT | I_NIL | I_MAP | I_ITER | I_EMPTY_SET - | I_LOOP | I_LOOP_LEFT | I_CONTRACT | I_CAST | I_UNPACK - | I_CREATE_CONTRACT ) as name), - (([] | _ :: _ :: _) as l), - _ ), - _ ) -> - fail (Invalid_arity (loc, name, 1, List.length l)) - | ( Prim - ( loc, - (( I_PUSH | I_VIEW | I_IF_NONE | I_IF_LEFT | I_IF_CONS | I_EMPTY_MAP - | I_EMPTY_BIG_MAP | I_IF ) as name), - (([] | [_] | _ :: _ :: _ :: _) as l), - _ ), - _ ) -> - fail (Invalid_arity (loc, name, 2, List.length l)) - | ( Prim (loc, I_LAMBDA, (([] | [_] | [_; _] | _ :: _ :: _ :: _ :: _) as l), _), - _ ) -> - fail (Invalid_arity (loc, I_LAMBDA, 3, List.length l)) - (* Stack errors *) - | ( Prim - ( loc, - (( I_ADD | I_SUB | I_SUB_MUTEZ | I_MUL | I_EDIV | I_AND | I_OR | I_XOR - | I_LSL | I_LSR | I_CONCAT | I_PAIRING_CHECK ) as name), - [], - _ ), - Item_t (ta, Item_t (tb, _, _), _) ) -> - let ta = serialize_ty_for_error ta in - let tb = serialize_ty_for_error tb in - fail (Undefined_binop (loc, name, ta, tb)) - | ( Prim - ( loc, - (( I_NEG | I_ABS | I_NOT | I_SIZE | I_EQ | I_NEQ | I_LT | I_GT | I_LE - | I_GE - (* CONCAT is both unary and binary; this case can only be triggered - on a singleton stack *) - | I_CONCAT ) as name), - [], - _ ), - Item_t (t, _, _) ) -> - let t = serialize_ty_for_error t in - fail (Undefined_unop (loc, name, t)) - | (Prim (loc, ((I_UPDATE | I_SLICE | I_OPEN_CHEST) as name), [], _), stack) -> - Lwt.return - (let stack = serialize_stack_for_error ctxt stack in - error (Bad_stack (loc, name, 3, stack))) - | (Prim (loc, I_CREATE_CONTRACT, _, _), stack) -> - let stack = serialize_stack_for_error ctxt stack in - fail (Bad_stack (loc, I_CREATE_CONTRACT, 7, stack)) - | (Prim (loc, I_TRANSFER_TOKENS, [], _), stack) -> - Lwt.return - (let stack = serialize_stack_for_error ctxt stack in - error (Bad_stack (loc, I_TRANSFER_TOKENS, 4, stack))) - | ( Prim - ( loc, - (( I_DROP | I_DUP | I_CAR | I_CDR | I_UNPAIR | I_SOME | I_BLAKE2B - | I_SHA256 | I_SHA512 | I_DIP | I_IF_NONE | I_LEFT | I_RIGHT - | I_IF_LEFT | I_IF | I_LOOP | I_IF_CONS | I_IMPLICIT_ACCOUNT | I_NEG - | I_ABS | I_INT | I_NOT | I_HASH_KEY | I_EQ | I_NEQ | I_LT | I_GT - | I_LE | I_GE | I_SIZE | I_FAILWITH | I_RENAME | I_PACK | I_ISNAT - | I_ADDRESS | I_SET_DELEGATE | I_CAST | I_MAP | I_ITER | I_LOOP_LEFT - | I_UNPACK | I_CONTRACT | I_NEVER | I_KECCAK | I_SHA3 | I_READ_TICKET - | I_JOIN_TICKETS ) as name), - _, - _ ), - stack ) -> - Lwt.return - (let stack = serialize_stack_for_error ctxt stack in - error (Bad_stack (loc, name, 1, stack))) - | ( Prim - ( loc, - (( I_SWAP | I_PAIR | I_CONS | I_GET | I_MEM | I_EXEC - | I_CHECK_SIGNATURE | I_ADD | I_SUB | I_SUB_MUTEZ | I_MUL | I_EDIV - | I_AND | I_OR | I_XOR | I_LSL | I_LSR | I_COMPARE | I_PAIRING_CHECK - | I_TICKET | I_SPLIT_TICKET ) as name), - _, - _ ), - stack ) -> - Lwt.return - (let stack = serialize_stack_for_error ctxt stack in - error (Bad_stack (loc, name, 2, stack))) - (* Generic parsing errors *) - | (expr, _) -> - fail - @@ unexpected - expr - [Seq_kind] - Instr_namespace - [ - I_DROP; - I_DUP; - I_DIG; - I_DUG; - I_VIEW; - I_SWAP; - I_SOME; - I_UNIT; - I_PAIR; - I_UNPAIR; - I_CAR; - I_CDR; - I_CONS; - I_MEM; - I_UPDATE; - I_MAP; - I_ITER; - I_GET; - I_GET_AND_UPDATE; - I_EXEC; - I_FAILWITH; - I_SIZE; - I_CONCAT; - I_ADD; - I_SUB; - I_SUB_MUTEZ; - I_MUL; - I_EDIV; - I_OR; - I_AND; - I_XOR; - I_NOT; - I_ABS; - I_INT; - I_NEG; - I_LSL; - I_LSR; - I_COMPARE; - I_EQ; - I_NEQ; - I_LT; - I_GT; - I_LE; - I_GE; - I_TRANSFER_TOKENS; - I_CREATE_CONTRACT; - I_NOW; - I_AMOUNT; - I_BALANCE; - I_LEVEL; - I_IMPLICIT_ACCOUNT; - I_CHECK_SIGNATURE; - I_BLAKE2B; - I_SHA256; - I_SHA512; - I_HASH_KEY; - I_PUSH; - I_NONE; - I_LEFT; - I_RIGHT; - I_NIL; - I_EMPTY_SET; - I_DIP; - I_LOOP; - I_IF_NONE; - I_IF_LEFT; - I_IF_CONS; - I_EMPTY_MAP; - I_EMPTY_BIG_MAP; - I_IF; - I_SOURCE; - I_SENDER; - I_SELF; - I_SELF_ADDRESS; - I_LAMBDA; - I_NEVER; - I_VOTING_POWER; - I_TOTAL_VOTING_POWER; - I_KECCAK; - I_SHA3; - I_PAIRING_CHECK; - I_SAPLING_EMPTY_STATE; - I_SAPLING_VERIFY_UPDATE; - I_TICKET; - I_READ_TICKET; - I_SPLIT_TICKET; - I_JOIN_TICKETS; - I_OPEN_CHEST; - ] - -and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_contract : - type arg. - stack_depth:int -> - legacy:bool -> - context -> - Script.location -> - arg ty -> - Contract.t -> - entrypoint:string -> - (context * arg typed_contract) tzresult Lwt.t = - fun ~stack_depth ~legacy ctxt loc arg contract ~entrypoint -> - match Contract.is_implicit contract with - | Some _ -> ( - match entrypoint with - | "default" -> - (* An implicit account on the "default" entrypoint always exists and has type unit. *) - Lwt.return - ( ty_eq ~legacy:true ctxt loc arg (unit_t ~annot:None) - >|? fun (Eq, ctxt) -> - let contract : arg typed_contract = - (arg, (contract, entrypoint)) - in - (ctxt, contract) ) - | _ -> fail (No_such_entrypoint entrypoint)) - | None -> ( - (* Originated account *) - trace (Invalid_contract (loc, contract)) - @@ Contract.get_script_code ctxt contract - >>=? fun (ctxt, code) -> - match code with - | None -> fail (Invalid_contract (loc, contract)) - | Some code -> - Lwt.return - ( Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - code - >>? fun (code, ctxt) -> - (* can only fail because of gas *) - parse_toplevel ctxt ~legacy:true code - >>? fun ({arg_type; root_name; _}, ctxt) -> - parse_parameter_ty - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy:true - arg_type - >>? fun (Ex_ty targ, ctxt) -> - (* we don't check targ size here because it's a legacy contract code *) - Gas_monad.run ctxt - @@ find_entrypoint_for_type - ~legacy - ~merge_type_error_flag:Default_merge_type_error - ~full:targ - ~expected:arg - ~root_name - entrypoint - loc - >>? fun (entrypoint_arg, ctxt) -> - entrypoint_arg >|? fun (entrypoint, arg) -> - let contract : arg typed_contract = - (arg, (contract, entrypoint)) - in - (ctxt, contract) )) - -and parse_view_name ctxt : Script.node -> (Script_string.t * context) tzresult = - function - | String (loc, v) as expr -> - (* The limitation of length of string is same as entrypoint *) - if Compare.Int.(String.length v > 31) then error (View_name_too_long v) - else - let rec check_char i = - if Compare.Int.(i < 0) then ok v - else if Script_ir_annot.is_allowed_char v.[i] then check_char (i - 1) - else error (Bad_view_name loc) - in - Gas.consume ctxt (Typecheck_costs.check_printable v) >>? fun ctxt -> - record_trace - (Invalid_syntactic_constant - ( loc, - strip_locations expr, - "string [a-zA-Z0-9_.%@] and the maximum string length of 31 \ - characters" )) - ( check_char (String.length v - 1) >>? fun v -> - Script_string.of_string v >|? fun s -> (s, ctxt) ) - | expr -> error @@ Invalid_kind (location expr, [String_kind], kind expr) - -and parse_toplevel : - context -> legacy:bool -> Script.expr -> (toplevel * context) tzresult = - fun ctxt ~legacy toplevel -> - record_trace (Ill_typed_contract (toplevel, [])) - @@ - match root toplevel with - | Int (loc, _) -> error (Invalid_kind (loc, [Seq_kind], Int_kind)) - | String (loc, _) -> error (Invalid_kind (loc, [Seq_kind], String_kind)) - | Bytes (loc, _) -> error (Invalid_kind (loc, [Seq_kind], Bytes_kind)) - | Prim (loc, _, _, _) -> error (Invalid_kind (loc, [Seq_kind], Prim_kind)) - | Seq (_, fields) -> ( - let rec find_fields ctxt p s c views fields = - match fields with - | [] -> ok (ctxt, (p, s, c, views)) - | Int (loc, _) :: _ -> error (Invalid_kind (loc, [Prim_kind], Int_kind)) - | String (loc, _) :: _ -> - error (Invalid_kind (loc, [Prim_kind], String_kind)) - | Bytes (loc, _) :: _ -> - error (Invalid_kind (loc, [Prim_kind], Bytes_kind)) - | Seq (loc, _) :: _ -> error (Invalid_kind (loc, [Prim_kind], Seq_kind)) - | Prim (loc, K_parameter, [arg], annot) :: rest -> ( - match p with - | None -> find_fields ctxt (Some (arg, loc, annot)) s c views rest - | Some _ -> error (Duplicate_field (loc, K_parameter))) - | Prim (loc, K_storage, [arg], annot) :: rest -> ( - match s with - | None -> find_fields ctxt p (Some (arg, loc, annot)) c views rest - | Some _ -> error (Duplicate_field (loc, K_storage))) - | Prim (loc, K_code, [arg], annot) :: rest -> ( - match c with - | None -> find_fields ctxt p s (Some (arg, loc, annot)) views rest - | Some _ -> error (Duplicate_field (loc, K_code))) - | Prim (loc, ((K_parameter | K_storage | K_code) as name), args, _) :: _ - -> - error (Invalid_arity (loc, name, 1, List.length args)) - | Prim (loc, K_view, [name; input_ty; output_ty; view_code], _) :: rest - -> - parse_view_name ctxt name >>? fun (str, ctxt) -> - Gas.consume - ctxt - (Michelson_v1_gas.Cost_of.Interpreter.view_update str views) - >>? fun ctxt -> - if SMap.mem str views then error (Duplicated_view_name loc) - else - let views' = - SMap.add str {input_ty; output_ty; view_code} views - in - find_fields ctxt p s c views' rest - | Prim (loc, K_view, args, _) :: _ -> - error (Invalid_arity (loc, K_view, 4, List.length args)) - | Prim (loc, name, _, _) :: _ -> - let allowed = [K_parameter; K_storage; K_code; K_view] in - error (Invalid_primitive (loc, allowed, name)) - in - find_fields ctxt None None None SMap.empty fields - >>? fun (ctxt, toplevel) -> - match toplevel with - | (None, _, _, _) -> error (Missing_field K_parameter) - | (Some _, None, _, _) -> error (Missing_field K_storage) - | (Some _, Some _, None, _) -> error (Missing_field K_code) - | ( Some (p, ploc, pannot), - Some (s, sloc, sannot), - Some (c, cloc, carrot), - views ) -> - let maybe_root_name = - (* root name can be attached to either the parameter - primitive or the toplevel constructor *) - 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) - && Compare.Char.(single.[0] = '%') -> - parse_field_annot ploc [single] >>? fun pannot -> - ok (p, [], pannot) - | _ -> ok (p, pannot, None)) - in - (if legacy then - (* legacy semantics ignores spurious annotations *) - match maybe_root_name with - | Ok (p, _, root_name) -> ok (p, root_name) - | Error _ -> ok (p, None) - else - (* only one field annot is allowed to set the root entrypoint name *) - maybe_root_name >>? fun (p, pannot, root_name) -> - Script_ir_annot.error_unexpected_annot ploc pannot >>? fun () -> - Script_ir_annot.error_unexpected_annot cloc carrot >>? fun () -> - Script_ir_annot.error_unexpected_annot sloc sannot >|? fun () -> - (p, root_name)) - >|? fun (arg_type, root_name) -> - ({code_field = c; arg_type; root_name; views; storage_type = s}, ctxt) - ) - -(* Same as [parse_contract], but does not fail when the contact is missing or - if the expected type doesn't match the actual one. In that case None is - returned and some overapproximation of the typechecking gas is consumed. - This can still fail on gas exhaustion. *) -let parse_contract_for_script : - type arg. - context -> - Script.location -> - arg ty -> - Contract.t -> - entrypoint:string -> - (context * arg typed_contract option) tzresult Lwt.t = - fun ctxt loc arg contract ~entrypoint -> - match Contract.is_implicit contract with - | Some _ -> ( - match entrypoint with - | "default" -> - (* An implicit account on the "default" entrypoint always exists and has type unit. *) - Lwt.return - ( Gas_monad.run ctxt - @@ merge_types - ~legacy:true - ~merge_type_error_flag:Fast_merge_type_error - loc - arg - (unit_t ~annot:None) - >|? fun (eq_ty, ctxt) -> - match eq_ty with - | Ok (Eq, _ty) -> - let contract : arg typed_contract = - (arg, (contract, entrypoint)) - in - (ctxt, Some contract) - | Error _ -> (ctxt, None) ) - | _ -> - Lwt.return - ( Gas.consume ctxt Typecheck_costs.parse_instr_cycle >|? fun ctxt -> - (* An implicit account on any other entrypoint is not a valid contract. *) - (ctxt, None) )) - | None -> ( - (* Originated account *) - trace (Invalid_contract (loc, contract)) - @@ Contract.get_script_code ctxt contract - >>=? fun (ctxt, code) -> - match code with - | None -> return (ctxt, None) - | Some code -> - Lwt.return - ( Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - code - >>? fun (code, ctxt) -> - (* can only fail because of gas *) - match parse_toplevel ctxt ~legacy:true code with - | Error _ -> error (Invalid_contract (loc, contract)) - | Ok ({arg_type; root_name; _}, ctxt) -> ( - match - parse_parameter_ty ctxt ~stack_depth:0 ~legacy:true arg_type - with - | Error _ -> error (Invalid_contract (loc, contract)) - | Ok (Ex_ty targ, ctxt) -> ( - (* we don't check targ size here because it's a legacy contract code *) - Gas_monad.run ctxt - @@ find_entrypoint_for_type - ~legacy:false - ~merge_type_error_flag:Fast_merge_type_error - ~full:targ - ~expected:arg - ~root_name - entrypoint - loc - >|? fun (entrypoint_arg, ctxt) -> - match entrypoint_arg with - | Ok (entrypoint, arg) -> - let contract : arg typed_contract = - (arg, (contract, entrypoint)) - in - (ctxt, Some contract) - | Error _ -> (ctxt, None))) )) - -let parse_code : - ?type_logger:type_logger -> - context -> - legacy:bool -> - code:lazy_expr -> - (ex_code * context) tzresult Lwt.t = - fun ?type_logger ctxt ~legacy ~code -> - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - code - >>?= fun (code, ctxt) -> - Global_constants_storage.expand ctxt code >>=? fun (ctxt, code) -> - parse_toplevel ctxt ~legacy code - >>?= fun ({arg_type; storage_type; code_field; views; root_name}, ctxt) -> - let arg_type_loc = location arg_type in - record_trace - (Ill_formed_type (Some "parameter", code, arg_type_loc)) - (parse_parameter_ty ctxt ~stack_depth:0 ~legacy arg_type) - >>?= fun (Ex_ty arg_type, ctxt) -> - (if legacy then Result.return_unit - else well_formed_entrypoints ~root_name arg_type) - >>?= fun () -> - let storage_type_loc = location storage_type in - record_trace - (Ill_formed_type (Some "storage", code, storage_type_loc)) - (parse_storage_ty ctxt ~stack_depth:0 ~legacy storage_type) - >>?= fun (Ex_ty storage_type, ctxt) -> - let arg_annot = - default_annot - (type_to_var_annot (name_of_ty arg_type)) - ~default:default_param_annot - in - let storage_annot = - default_annot - (type_to_var_annot (name_of_ty storage_type)) - ~default:default_storage_annot - in - - pair_t - storage_type_loc - (arg_type, None, arg_annot) - (storage_type, None, storage_annot) - ~annot:None - >>?= fun arg_type_full -> - pair_t - storage_type_loc - (list_operation_t, None, None) - (storage_type, None, None) - ~annot:None - >>?= fun ret_type_full -> - trace - (Ill_typed_contract (code, [])) - (parse_returning - (Toplevel {storage_type; param_type = arg_type; root_name}) - ctxt - ~legacy - ~stack_depth:0 - ?type_logger - (arg_type_full, None) - ret_type_full - code_field) - >>=? fun (code, ctxt) -> - Lwt.return - (let open Script_typed_ir_size in - let view_size view = - node_size view.view_code ++ node_size view.input_ty - ++ node_size view.output_ty - in - let views_size = SMap.fold (fun _ v s -> view_size v ++ s) views zero in - (* The size of the storage_type and the arg_type is counted by - [lambda_size]. *) - let ir_size = lambda_size code in - let (nodes, code_size) = views_size ++ ir_size in - (* We consume gas after the fact in order to not have to instrument - [node_size] (for efficiency). - This is safe, as we already pay gas proportional to [views_size] - and [ir_size] during their typechecking. *) - Gas.consume ctxt (Script_typed_ir_size_costs.nodes_cost ~nodes) - >>? fun ctxt -> - ok - (Ex_code {code; arg_type; storage_type; views; root_name; code_size}, ctxt)) - -let parse_storage : - ?type_logger:type_logger -> - context -> - legacy:bool -> - allow_forged:bool -> - 'storage ty -> - storage:lazy_expr -> - ('storage * context) tzresult Lwt.t = - fun ?type_logger ctxt ~legacy ~allow_forged storage_type ~storage -> - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - storage - >>?= fun (storage, ctxt) -> - trace_eval - (fun () -> - let storage_type = serialize_ty_for_error storage_type in - Ill_typed_data (None, storage, storage_type)) - (parse_data - ?type_logger - ~stack_depth:0 - ctxt - ~legacy - ~allow_forged - storage_type - (root storage)) - -let[@coq_axiom_with_reason "gadt"] parse_script : - ?type_logger:type_logger -> - context -> - legacy:bool -> - allow_forged_in_storage:bool -> - Script.t -> - (ex_script * context) tzresult Lwt.t = - fun ?type_logger ctxt ~legacy ~allow_forged_in_storage {code; storage} -> - parse_code ~legacy ctxt ?type_logger ~code - >>=? fun ( Ex_code {code; arg_type; storage_type; views; root_name; code_size}, - ctxt ) -> - parse_storage - ?type_logger - ctxt - ~legacy - ~allow_forged:allow_forged_in_storage - storage_type - ~storage - >|=? fun (storage, ctxt) -> - ( Ex_script - {code_size; code; arg_type; storage; storage_type; views; root_name}, - ctxt ) - -let typecheck_code : - legacy:bool -> - show_types:bool -> - context -> - Script.expr -> - (type_map * context) tzresult Lwt.t = - fun ~legacy ~show_types ctxt code -> - (* Constants need to be expanded or [parse_toplevel] may fail. *) - Global_constants_storage.expand ctxt code >>=? fun (ctxt, code) -> - parse_toplevel ctxt ~legacy code - >>?= fun ({arg_type; storage_type; code_field; views; root_name}, ctxt) -> - let type_map = ref [] in - let arg_type_loc = location arg_type in - record_trace - (Ill_formed_type (Some "parameter", code, arg_type_loc)) - (parse_parameter_ty ctxt ~stack_depth:0 ~legacy arg_type) - >>?= fun (Ex_ty arg_type, ctxt) -> - (if legacy then Result.return_unit - else well_formed_entrypoints ~root_name arg_type) - >>?= fun () -> - let storage_type_loc = location storage_type in - record_trace - (Ill_formed_type (Some "storage", code, storage_type_loc)) - (parse_storage_ty ctxt ~stack_depth:0 ~legacy storage_type) - >>?= fun (Ex_ty storage_type, ctxt) -> - let arg_annot = - default_annot - (type_to_var_annot (name_of_ty arg_type)) - ~default:default_param_annot - in - let storage_annot = - default_annot - (type_to_var_annot (name_of_ty storage_type)) - ~default:default_storage_annot - in - pair_t - storage_type_loc - (arg_type, None, arg_annot) - (storage_type, None, storage_annot) - ~annot:None - >>?= fun arg_type_full -> - pair_t - storage_type_loc - (list_operation_t, None, None) - (storage_type, None, None) - ~annot:None - >>?= fun ret_type_full -> - let type_logger loc bef aft = type_map := (loc, (bef, aft)) :: !type_map in - let type_logger = if show_types then Some type_logger else None in - let result = - parse_returning - (Toplevel {storage_type; param_type = arg_type; root_name}) - ctxt - ~legacy - ~stack_depth:0 - ?type_logger - (arg_type_full, None) - ret_type_full - code_field - in - trace (Ill_typed_contract (code, !type_map)) result >>=? fun (Lam _, ctxt) -> - let views_result = - typecheck_views - ctxt - ~type_logger:(fun loc bef aft -> - type_map := (loc, (bef, aft)) :: !type_map) - ~legacy - storage_type - views - in - trace (Ill_typed_contract (code, !type_map)) views_result >|=? fun ctxt -> - (!type_map, ctxt) - -module Entrypoints_map = Map.Make (String) - -let list_entrypoints (type full) (full : full ty) ctxt ~root_name = - let merge path annot (type t) (ty : t ty) reachable - ((unreachables, all) as acc) = - match annot with - | None -> ( - ok - @@ - if reachable then acc - else - match ty with - | Union_t _ -> acc - | _ -> (List.rev path :: unreachables, all)) - | Some (Field_annot name) -> - let name = (name :> string) in - if Compare.Int.(String.length name > 31) then - ok (List.rev path :: unreachables, all) - else if Entrypoints_map.mem name all then - ok (List.rev path :: unreachables, all) - else - unparse_ty ~loc:() ctxt ty >>? fun (unparsed_ty, _) -> - ok - ( unreachables, - Entrypoints_map.add name (List.rev path, unparsed_ty) all ) - in - let rec fold_tree : - type t. - t ty -> - prim list -> - bool -> - prim list list - * (prim list * Script.unlocated_michelson_node) Entrypoints_map.t -> - (prim list list - * (prim list * Script.unlocated_michelson_node) Entrypoints_map.t) - tzresult = - fun t path reachable acc -> - match t with - | Union_t ((tl, al), (tr, ar), _) -> - merge (D_Left :: path) al tl reachable acc >>? fun acc -> - merge (D_Right :: path) ar tr reachable acc >>? fun acc -> - fold_tree - tl - (D_Left :: path) - (match al with Some _ -> true | None -> reachable) - acc - >>? fun acc -> - fold_tree - tr - (D_Right :: path) - (match ar with Some _ -> true | None -> reachable) - acc - | _ -> ok acc - in - unparse_ty ~loc:() ctxt full >>? fun (unparsed_full, _) -> - let (init, reachable) = - match root_name with - | None -> (Entrypoints_map.empty, false) - | Some (Field_annot name) -> - (Entrypoints_map.singleton (name :> string) ([], unparsed_full), true) - in - fold_tree full [] reachable ([], init) - [@@coq_axiom_with_reason "unsupported syntax"] - -(* ---- Unparsing (Typed IR -> Untyped expressions) --------------------------*) - -(* -- Unparsing data of any type -- *) - -let comb_witness2 : type t. t ty -> (t, unit -> unit -> unit) comb_witness = - function - | Pair_t (_, (Pair_t _, _, _), _) -> Comb_Pair (Comb_Pair Comb_Any) - | Pair_t _ -> Comb_Pair Comb_Any - | _ -> Comb_Any - -let[@coq_axiom_with_reason "gadt"] rec unparse_data : - type a. - context -> - stack_depth:int -> - unparsing_mode -> - a ty -> - a -> - (Script.node * context) tzresult Lwt.t = - fun ctxt ~stack_depth mode ty a -> - Gas.consume ctxt Unparse_costs.unparse_data_cycle >>?= fun ctxt -> - let non_terminal_recursion ctxt mode ty a = - if Compare.Int.(stack_depth > 10_000) then - fail Unparsing_too_many_recursive_calls - else unparse_data ctxt ~stack_depth:(stack_depth + 1) mode ty a - in - let loc = Micheline.dummy_location in - match (ty, a) with - | (Unit_t _, v) -> Lwt.return @@ unparse_unit ~loc ctxt v - | (Int_t _, v) -> Lwt.return @@ unparse_int ~loc ctxt v - | (Nat_t _, v) -> Lwt.return @@ unparse_nat ~loc ctxt v - | (String_t _, s) -> Lwt.return @@ unparse_string ~loc ctxt s - | (Bytes_t _, s) -> Lwt.return @@ unparse_bytes ~loc ctxt s - | (Bool_t _, b) -> Lwt.return @@ unparse_bool ~loc ctxt b - | (Timestamp_t _, t) -> Lwt.return @@ unparse_timestamp ~loc ctxt mode t - | (Address_t _, address) -> - Lwt.return @@ unparse_address ~loc ctxt mode address - | (Contract_t _, contract) -> - Lwt.return @@ unparse_contract ~loc ctxt mode contract - | (Signature_t _, s) -> Lwt.return @@ unparse_signature ~loc ctxt mode s - | (Mutez_t _, v) -> Lwt.return @@ unparse_mutez ~loc ctxt v - | (Key_t _, k) -> Lwt.return @@ unparse_key ~loc ctxt mode k - | (Key_hash_t _, k) -> Lwt.return @@ unparse_key_hash ~loc ctxt mode k - | (Operation_t _, operation) -> - Lwt.return @@ unparse_operation ~loc ctxt operation - | (Chain_id_t _, chain_id) -> - Lwt.return @@ unparse_chain_id ~loc ctxt mode chain_id - | (Bls12_381_g1_t _, x) -> Lwt.return @@ unparse_bls12_381_g1 ~loc ctxt x - | (Bls12_381_g2_t _, x) -> Lwt.return @@ unparse_bls12_381_g2 ~loc ctxt x - | (Bls12_381_fr_t _, x) -> Lwt.return @@ unparse_bls12_381_fr ~loc ctxt x - | (Pair_t ((tl, _, _), (tr, _, _), _), pair) -> - let r_witness = comb_witness2 tr in - let unparse_l ctxt v = non_terminal_recursion ctxt mode tl v in - let unparse_r ctxt v = non_terminal_recursion ctxt mode tr v in - unparse_pair ~loc unparse_l unparse_r ctxt mode r_witness pair - | (Union_t ((tl, _), (tr, _), _), v) -> - let unparse_l ctxt v = non_terminal_recursion ctxt mode tl v in - let unparse_r ctxt v = non_terminal_recursion ctxt mode tr v in - unparse_union ~loc unparse_l unparse_r ctxt v - | (Option_t (t, _), v) -> - let unparse_v ctxt v = non_terminal_recursion ctxt mode t v in - unparse_option ~loc unparse_v ctxt v - | (List_t (t, _), items) -> - List.fold_left_es - (fun (l, ctxt) element -> - non_terminal_recursion ctxt mode t element - >|=? fun (unparsed, ctxt) -> (unparsed :: l, ctxt)) - ([], ctxt) - items.elements - >|=? fun (items, ctxt) -> (Micheline.Seq (loc, List.rev items), ctxt) - | (Ticket_t (t, _), {ticketer; contents; amount}) -> - (* ideally we would like to allow a little overhead here because it is only used for unparsing *) - opened_ticket_type loc t >>?= fun opened_ticket_ty -> - let t = ty_of_comparable_ty opened_ticket_ty in - (unparse_data [@tailcall]) - ctxt - ~stack_depth - mode - t - ((ticketer, "default"), (contents, amount)) - | (Set_t (t, _), set) -> - List.fold_left_es - (fun (l, ctxt) item -> - unparse_comparable_data ~loc ctxt mode t item >|=? fun (item, ctxt) -> - (item :: l, ctxt)) - ([], ctxt) - (Script_set.fold (fun e acc -> e :: acc) set []) - >|=? fun (items, ctxt) -> (Micheline.Seq (loc, items), ctxt) - | (Map_t (kt, vt, _), map) -> - let items = Script_map.fold (fun k v acc -> (k, v) :: acc) map [] in - unparse_items ctxt ~stack_depth:(stack_depth + 1) mode kt vt items - >|=? fun (items, ctxt) -> (Micheline.Seq (loc, items), ctxt) - | (Big_map_t (_kt, _vt, _), {id = Some id; diff = {size; _}; _}) - when Compare.Int.( = ) size 0 -> - return (Micheline.Int (loc, Big_map.Id.unparse_to_z id), ctxt) - | (Big_map_t (kt, vt, _), {id = Some id; diff = {map; _}; _}) -> - let items = - Big_map_overlay.fold (fun _ (k, v) acc -> (k, v) :: acc) map [] - in - let items = - (* Sort the items in Michelson comparison order and not in key - hash order. This code path is only exercised for tracing, - so we don't bother carbonating this sort operation - precisely. Also, the sort uses a reverse compare because - [unparse_items] will reverse the result. *) - List.sort - (fun (a, _) (b, _) -> Script_comparable.compare_comparable kt b a) - items - in - (* this can't fail if the original type is well-formed - because [option vt] is always strictly smaller than [big_map kt vt] *) - option_t loc vt ~annot:None >>?= fun vt -> - unparse_items ctxt ~stack_depth:(stack_depth + 1) mode kt vt items - >|=? fun (items, ctxt) -> - ( Micheline.Prim - ( loc, - D_Pair, - [Int (loc, Big_map.Id.unparse_to_z id); Seq (loc, items)], - [] ), - ctxt ) - | (Big_map_t (kt, vt, _), {id = None; diff = {map; _}; _}) -> - let items = - Big_map_overlay.fold - (fun _ (k, v) acc -> - match v with None -> acc | Some v -> (k, v) :: acc) - map - [] - in - let items = - (* See note above. *) - List.sort - (fun (a, _) (b, _) -> Script_comparable.compare_comparable kt b a) - items - in - unparse_items ctxt ~stack_depth:(stack_depth + 1) mode kt vt items - >|=? fun (items, ctxt) -> (Micheline.Seq (loc, items), ctxt) - | (Lambda_t _, Lam (_, original_code)) -> - unparse_code ctxt ~stack_depth:(stack_depth + 1) mode original_code - | (Never_t _, _) -> . - | (Sapling_transaction_t _, s) -> - Lwt.return - ( Gas.consume ctxt (Unparse_costs.sapling_transaction s) >|? fun ctxt -> - let bytes = - Data_encoding.Binary.to_bytes_exn Sapling.transaction_encoding s - in - (Bytes (loc, bytes), ctxt) ) - | (Sapling_state_t _, {id; diff; _}) -> - Lwt.return - ( Gas.consume ctxt (Unparse_costs.sapling_diff diff) >|? fun ctxt -> - ( (match diff with - | {commitments_and_ciphertexts = []; nullifiers = []} -> ( - match id with - | None -> Micheline.Seq (loc, []) - | Some id -> - let id = Sapling.Id.unparse_to_z id in - Micheline.Int (loc, id)) - | diff -> ( - let diff_bytes = - Data_encoding.Binary.to_bytes_exn Sapling.diff_encoding diff - in - let unparsed_diff = Bytes (loc, diff_bytes) in - match id with - | None -> unparsed_diff - | Some id -> - let id = Sapling.Id.unparse_to_z id in - Micheline.Prim - (loc, D_Pair, [Int (loc, id); unparsed_diff], []))), - ctxt ) ) - | (Chest_key_t _, s) -> - unparse_with_data_encoding - ~loc - ctxt - s - Unparse_costs.chest_key - Timelock.chest_key_encoding - | (Chest_t _, s) -> - unparse_with_data_encoding - ~loc - ctxt - s - (Unparse_costs.chest ~plaintext_size:(Timelock.get_plaintext_size s)) - Timelock.chest_encoding - -and unparse_items : - type k v. - context -> - stack_depth:int -> - unparsing_mode -> - k comparable_ty -> - v ty -> - (k * v) list -> - (Script.node list * context) tzresult Lwt.t = - fun ctxt ~stack_depth mode kt vt items -> - List.fold_left_es - (fun (l, ctxt) (k, v) -> - let loc = Micheline.dummy_location in - unparse_comparable_data ~loc ctxt mode kt k >>=? fun (key, ctxt) -> - unparse_data ctxt ~stack_depth:(stack_depth + 1) mode vt v - >|=? fun (value, ctxt) -> (Prim (loc, D_Elt, [key; value], []) :: l, ctxt)) - ([], ctxt) - items - -and[@coq_axiom_with_reason "gadt"] unparse_code ctxt ~stack_depth mode code = - let legacy = true in - Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>?= fun ctxt -> - let non_terminal_recursion ctxt mode code = - if Compare.Int.(stack_depth > 10_000) then - fail Unparsing_too_many_recursive_calls - else unparse_code ctxt ~stack_depth:(stack_depth + 1) mode code - in - match code with - | Prim (loc, I_PUSH, [ty; data], annot) -> - parse_packable_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy ty - >>?= fun (Ex_ty t, ctxt) -> - let allow_forged = - false - (* Forgeable in PUSH data are already forbidden at parsing, - the only case for which this matters is storing a lambda resulting - from APPLYing a non-forgeable but this cannot happen either as long - as all packable values are also forgeable. *) - in - parse_data - ctxt - ~stack_depth:(stack_depth + 1) - ~legacy - ~allow_forged - t - data - >>=? fun (data, ctxt) -> - unparse_data ctxt ~stack_depth:(stack_depth + 1) mode t data - >>=? fun (data, ctxt) -> - return (Prim (loc, I_PUSH, [ty; data], annot), ctxt) - | Seq (loc, items) -> - List.fold_left_es - (fun (l, ctxt) item -> - non_terminal_recursion ctxt mode item >|=? fun (item, ctxt) -> - (item :: l, ctxt)) - ([], ctxt) - items - >>=? fun (items, ctxt) -> - return (Micheline.Seq (loc, List.rev items), ctxt) - | Prim (loc, prim, items, annot) -> - List.fold_left_es - (fun (l, ctxt) item -> - non_terminal_recursion ctxt mode item >|=? fun (item, ctxt) -> - (item :: l, ctxt)) - ([], ctxt) - items - >>=? fun (items, ctxt) -> - return (Prim (loc, prim, List.rev items, annot), ctxt) - | (Int _ | String _ | Bytes _) as atom -> return (atom, ctxt) - -(* Gas accounting may not be perfect in this function, as it is only called by RPCs. *) -(* TODO: https://gitlab.com/tezos/tezos/-/issues/1688 - Refactor the sharing part of unparse_script and create_contract *) -let unparse_script ctxt mode - {code; arg_type; storage; storage_type; root_name; views; _} = - let (Lam (_, original_code)) = code in - unparse_code ctxt ~stack_depth:0 mode original_code >>=? fun (code, ctxt) -> - unparse_data ctxt ~stack_depth:0 mode storage_type storage - >>=? fun (storage, ctxt) -> - Lwt.return - (let loc = Micheline.dummy_location in - unparse_ty ~loc ctxt arg_type >>? fun (arg_type, ctxt) -> - unparse_ty ~loc ctxt storage_type >>? fun (storage_type, ctxt) -> - let arg_type = add_field_annot root_name None arg_type in - let open Micheline in - let view name {input_ty; output_ty; view_code} views = - Prim - ( loc, - K_view, - [ - String (loc, Script_string.to_string name); - input_ty; - output_ty; - view_code; - ], - [] ) - :: views - in - let views = SMap.fold view views [] |> List.rev in - let code = - Seq - ( loc, - [ - Prim (loc, K_parameter, [arg_type], []); - Prim (loc, K_storage, [storage_type], []); - Prim (loc, K_code, [code], []); - ] - @ views ) - in - Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>? fun ctxt -> - Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>? fun ctxt -> - Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>? fun ctxt -> - Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>? fun ctxt -> - Gas.consume ctxt (Script.strip_locations_cost code) >>? fun ctxt -> - Gas.consume ctxt (Script.strip_locations_cost storage) >|? fun ctxt -> - ( { - code = lazy_expr (strip_locations code); - storage = lazy_expr (strip_locations storage); - }, - ctxt )) - -let pack_data_with_mode ctxt typ data ~mode = - unparse_data ~stack_depth:0 ctxt mode typ data >>=? fun (unparsed, ctxt) -> - Lwt.return @@ pack_node unparsed ctxt - -let hash_data ctxt typ data = - pack_data_with_mode ctxt typ data ~mode:Optimized_legacy - >>=? fun (bytes, ctxt) -> Lwt.return @@ hash_bytes ctxt bytes - -let pack_data ctxt typ data = - pack_data_with_mode ctxt typ data ~mode:Optimized_legacy - -(* ---------------- Big map -------------------------------------------------*) - -let empty_big_map key_type value_type = - { - id = None; - diff = {map = Big_map_overlay.empty; size = 0}; - key_type; - value_type; - } - -let big_map_mem ctxt key {id; diff; key_type; _} = - hash_comparable_data ctxt key_type key >>=? fun (key, ctxt) -> - match (Big_map_overlay.find key diff.map, id) with - | (None, None) -> return (false, ctxt) - | (None, Some id) -> - Alpha_context.Big_map.mem ctxt id key >|=? fun (ctxt, res) -> (res, ctxt) - | (Some (_, None), _) -> return (false, ctxt) - | (Some (_, Some _), _) -> return (true, ctxt) - -let big_map_get_by_hash ctxt key {id; diff; value_type; _} = - match (Big_map_overlay.find key diff.map, id) with - | (Some (_, x), _) -> return (x, ctxt) - | (None, None) -> return (None, ctxt) - | (None, Some id) -> ( - Alpha_context.Big_map.get_opt ctxt id key >>=? function - | (ctxt, None) -> return (None, ctxt) - | (ctxt, Some value) -> - parse_data - ~stack_depth:0 - ctxt - ~legacy:true - ~allow_forged:true - value_type - (Micheline.root value) - >|=? fun (x, ctxt) -> (Some x, ctxt)) - -let big_map_get ctxt key map = - hash_comparable_data ctxt map.key_type key >>=? fun (key_hash, ctxt) -> - big_map_get_by_hash ctxt key_hash map - -let big_map_update_by_hash ctxt key_hash key value map = - let contains = Big_map_overlay.mem key_hash map.diff.map in - return - ( { - map with - diff = - { - map = Big_map_overlay.add key_hash (key, value) map.diff.map; - size = (if contains then map.diff.size else map.diff.size + 1); - }; - }, - ctxt ) - -let big_map_update ctxt key value map = - hash_comparable_data ctxt map.key_type key >>=? fun (key_hash, ctxt) -> - big_map_update_by_hash ctxt key_hash key value map - -let big_map_get_and_update ctxt key value map = - hash_comparable_data ctxt map.key_type key >>=? fun (key_hash, ctxt) -> - big_map_update_by_hash ctxt key_hash key value map >>=? fun (map', ctxt) -> - big_map_get_by_hash ctxt key_hash map >>=? fun (old_value, ctxt) -> - return ((old_value, map'), ctxt) - -(* ---------------- Lazy storage---------------------------------------------*) - -type lazy_storage_ids = Lazy_storage.IdSet.t - -let no_lazy_storage_id = Lazy_storage.IdSet.empty - -let diff_of_big_map ctxt mode ~temporary ~ids_to_copy - {id; key_type; value_type; diff} = - (match id with - | Some id -> - if Lazy_storage.IdSet.mem Big_map id ids_to_copy then - Big_map.fresh ~temporary ctxt >|=? fun (ctxt, duplicate) -> - (ctxt, Lazy_storage.Copy {src = id}, duplicate) - else - (* The first occurrence encountered of a big_map reuses the - ID. This way, the payer is only charged for the diff. - For this to work, this diff has to be put at the end of - the global diff, otherwise the duplicates will use the - updated version as a base. This is true because we add - this diff first in the accumulator of - `extract_lazy_storage_updates`, and this accumulator is not - reversed. *) - return (ctxt, Lazy_storage.Existing, id) - | None -> - Big_map.fresh ~temporary ctxt >>=? fun (ctxt, id) -> - Lwt.return - (let kt = unparse_comparable_ty_uncarbonated ~loc:() key_type in - Gas.consume ctxt (Script.strip_locations_cost kt) >>? fun ctxt -> - unparse_ty ~loc:() ctxt value_type >>? fun (kv, ctxt) -> - Gas.consume ctxt (Script.strip_locations_cost kv) >|? fun ctxt -> - let key_type = Micheline.strip_locations kt in - let value_type = Micheline.strip_locations kv in - (ctxt, Lazy_storage.(Alloc Big_map.{key_type; value_type}), id))) - >>=? fun (ctxt, init, id) -> - let pairs = - Big_map_overlay.fold - (fun key_hash (key, value) acc -> (key_hash, key, value) :: acc) - diff.map - [] - in - List.fold_left_es - (fun (acc, ctxt) (key_hash, key, value) -> - Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>?= fun ctxt -> - unparse_comparable_data ~loc:() ctxt mode key_type key - >>=? fun (key_node, ctxt) -> - Gas.consume ctxt (Script.strip_locations_cost key_node) >>?= fun ctxt -> - let key = Micheline.strip_locations key_node in - (match value with - | None -> return (None, ctxt) - | Some x -> - unparse_data ~stack_depth:0 ctxt mode value_type x - >>=? fun (node, ctxt) -> - Lwt.return - ( Gas.consume ctxt (Script.strip_locations_cost node) >|? fun ctxt -> - (Some (Micheline.strip_locations node), ctxt) )) - >|=? fun (value, ctxt) -> - let diff_item = Big_map.{key; key_hash; value} in - (diff_item :: acc, ctxt)) - ([], ctxt) - (List.rev pairs) - >|=? fun (updates, ctxt) -> (Lazy_storage.Update {init; updates}, id, ctxt) - -let diff_of_sapling_state ctxt ~temporary ~ids_to_copy - ({id; diff; memo_size} : Sapling.state) = - (match id with - | Some id -> - if Lazy_storage.IdSet.mem Sapling_state id ids_to_copy then - Sapling.fresh ~temporary ctxt >|=? fun (ctxt, duplicate) -> - (ctxt, Lazy_storage.Copy {src = id}, duplicate) - else return (ctxt, Lazy_storage.Existing, id) - | None -> - Sapling.fresh ~temporary ctxt >|=? fun (ctxt, id) -> - (ctxt, Lazy_storage.Alloc Sapling.{memo_size}, id)) - >|=? fun (ctxt, init, id) -> - (Lazy_storage.Update {init; updates = diff}, id, ctxt) - -(** - Witness flag for whether a type can be populated by a value containing a - lazy storage. - [False_f] must be used only when a value of the type cannot contain a lazy - storage. - - This flag is built in [has_lazy_storage] and used only in - [extract_lazy_storage_updates] and [collect_lazy_storage]. - - This flag is necessary to avoid these two functions to have a quadratic - complexity in the size of the type. - - Add new lazy storage kinds here. - - Please keep the usage of this GADT local. -*) -type 'ty has_lazy_storage = - | True_f : _ has_lazy_storage - | False_f : _ has_lazy_storage - | Pair_f : - 'a has_lazy_storage * 'b has_lazy_storage - -> ('a, 'b) pair has_lazy_storage - | Union_f : - 'a has_lazy_storage * 'b has_lazy_storage - -> ('a, 'b) union has_lazy_storage - | Option_f : 'a has_lazy_storage -> 'a option has_lazy_storage - | List_f : 'a has_lazy_storage -> 'a boxed_list has_lazy_storage - | Map_f : 'v has_lazy_storage -> (_, 'v) map has_lazy_storage - -(** - This function is called only on storage and parameter types of contracts, - once per typechecked contract. It has a complexity linear in the size of - the types, which happen to be literally written types, so the gas for them - has already been paid. -*) -let rec has_lazy_storage : type t. t ty -> t has_lazy_storage = - fun ty -> - let aux1 cons t = - match has_lazy_storage t with False_f -> False_f | h -> cons h - in - let aux2 cons t1 t2 = - match (has_lazy_storage t1, has_lazy_storage t2) with - | (False_f, False_f) -> False_f - | (h1, h2) -> cons h1 h2 - in - match ty with - | Big_map_t (_, _, _) -> True_f - | Sapling_state_t _ -> True_f - | Unit_t _ -> False_f - | Int_t _ -> False_f - | Nat_t _ -> False_f - | Signature_t _ -> False_f - | String_t _ -> False_f - | Bytes_t _ -> False_f - | Mutez_t _ -> False_f - | Key_hash_t _ -> False_f - | Key_t _ -> False_f - | Timestamp_t _ -> False_f - | Address_t _ -> False_f - | Bool_t _ -> False_f - | Lambda_t (_, _, _) -> False_f - | Set_t (_, _) -> False_f - | Contract_t (_, _) -> False_f - | Operation_t _ -> False_f - | Chain_id_t _ -> False_f - | Never_t _ -> False_f - | Bls12_381_g1_t _ -> False_f - | Bls12_381_g2_t _ -> False_f - | Bls12_381_fr_t _ -> False_f - | Sapling_transaction_t _ -> False_f - | Ticket_t _ -> False_f - | Chest_key_t _ -> False_f - | Chest_t _ -> False_f - | Pair_t ((l, _, _), (r, _, _), _) -> aux2 (fun l r -> Pair_f (l, r)) l r - | Union_t ((l, _), (r, _), _) -> aux2 (fun l r -> Union_f (l, r)) l r - | Option_t (t, _) -> aux1 (fun h -> Option_f h) t - | List_t (t, _) -> aux1 (fun h -> List_f h) t - | Map_t (_, t, _) -> aux1 (fun h -> Map_f h) t - -(** - Transforms a value potentially containing lazy storage in an intermediary - state to a value containing lazy storage only represented by identifiers. - - Returns the updated value, the updated set of ids to copy, and the lazy - storage diff to show on the receipt and apply on the storage. - -*) -let[@coq_axiom_with_reason "gadt"] extract_lazy_storage_updates ctxt mode - ~temporary ids_to_copy acc ty x = - let rec aux : - type a. - context -> - unparsing_mode -> - temporary:bool -> - Lazy_storage.IdSet.t -> - Lazy_storage.diffs -> - a ty -> - a -> - has_lazy_storage:a has_lazy_storage -> - (context * a * Lazy_storage.IdSet.t * Lazy_storage.diffs) tzresult Lwt.t = - fun ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage -> - Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>?= fun ctxt -> - match (has_lazy_storage, ty, x) with - | (False_f, _, _) -> return (ctxt, x, ids_to_copy, acc) - | (_, Big_map_t (_, _, _), map) -> - diff_of_big_map ctxt mode ~temporary ~ids_to_copy map - >|=? fun (diff, id, ctxt) -> - let map = - { - map with - diff = {map = Big_map_overlay.empty; size = 0}; - id = Some id; - } - in - let diff = Lazy_storage.make Big_map id diff in - let ids_to_copy = Lazy_storage.IdSet.add Big_map id ids_to_copy in - (ctxt, map, ids_to_copy, diff :: acc) - | (_, Sapling_state_t _, sapling_state) -> - diff_of_sapling_state ctxt ~temporary ~ids_to_copy sapling_state - >|=? fun (diff, id, ctxt) -> - let sapling_state = - Sapling.empty_state ~id ~memo_size:sapling_state.memo_size () - in - let diff = Lazy_storage.make Sapling_state id diff in - let ids_to_copy = Lazy_storage.IdSet.add Sapling_state id ids_to_copy in - (ctxt, sapling_state, ids_to_copy, diff :: acc) - | (Pair_f (hl, hr), Pair_t ((tyl, _, _), (tyr, _, _), _), (xl, xr)) -> - aux ctxt mode ~temporary ids_to_copy acc tyl xl ~has_lazy_storage:hl - >>=? fun (ctxt, xl, ids_to_copy, acc) -> - aux ctxt mode ~temporary ids_to_copy acc tyr xr ~has_lazy_storage:hr - >|=? fun (ctxt, xr, ids_to_copy, acc) -> - (ctxt, (xl, xr), ids_to_copy, acc) - | (Union_f (has_lazy_storage, _), Union_t ((ty, _), (_, _), _), L x) -> - aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage - >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, L x, ids_to_copy, acc) - | (Union_f (_, has_lazy_storage), Union_t ((_, _), (ty, _), _), R x) -> - aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage - >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, R x, ids_to_copy, acc) - | (Option_f has_lazy_storage, Option_t (ty, _), Some x) -> - aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage - >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, Some x, ids_to_copy, acc) - | (List_f has_lazy_storage, List_t (ty, _), l) -> - List.fold_left_es - (fun (ctxt, l, ids_to_copy, acc) x -> - aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage - >|=? fun (ctxt, x, ids_to_copy, acc) -> - (ctxt, Script_list.cons x l, ids_to_copy, acc)) - (ctxt, Script_list.empty, ids_to_copy, acc) - l.elements - >|=? fun (ctxt, l, ids_to_copy, acc) -> - let reversed = {length = l.length; elements = List.rev l.elements} in - (ctxt, reversed, ids_to_copy, acc) - | (Map_f has_lazy_storage, Map_t (_, ty, _), (module M)) -> - let bindings m = M.OPS.fold (fun k v bs -> (k, v) :: bs) m [] in - List.fold_left_es - (fun (ctxt, m, ids_to_copy, acc) (k, x) -> - aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage - >|=? fun (ctxt, x, ids_to_copy, acc) -> - (ctxt, M.OPS.add k x m, ids_to_copy, acc)) - (ctxt, M.OPS.empty, ids_to_copy, acc) - (bindings M.boxed) - >|=? fun (ctxt, m, ids_to_copy, acc) -> - let module M = struct - module OPS = M.OPS - - type key = M.key - - type value = M.value - - let key_ty = M.key_ty - - let boxed = m - - let size = M.size - end in - ( ctxt, - (module M : Boxed_map with type key = M.key and type value = M.value), - ids_to_copy, - acc ) - | (_, Option_t (_, _), None) -> return (ctxt, None, ids_to_copy, acc) - | _ -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/1962 - fix injectivity of types *) - assert false - in - let has_lazy_storage = has_lazy_storage ty in - aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage - -(** We namespace an error type for [fold_lazy_storage]. The error case is only - available when the ['error] parameter is equal to unit. *) -module Fold_lazy_storage = struct - type ('acc, 'error) result = - | Ok : 'acc -> ('acc, 'error) result - | Error : ('acc, unit) result -end - -(** Prematurely abort if [f] generates an error. Use this function without the - [unit] type for [error] if you are in a case where errors are impossible. -*) -let[@coq_axiom_with_reason "gadt"] rec fold_lazy_storage : - type a error. - f:('acc, error) Fold_lazy_storage.result Lazy_storage.IdSet.fold_f -> - init:'acc -> - context -> - a ty -> - a -> - has_lazy_storage:a has_lazy_storage -> - (('acc, error) Fold_lazy_storage.result * context) tzresult = - fun ~f ~init ctxt ty x ~has_lazy_storage -> - Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>? fun ctxt -> - match (has_lazy_storage, ty, x) with - | (_, Big_map_t (_, _, _), {id = Some id; _}) -> - Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>? fun ctxt -> - ok (f.f Big_map id (Fold_lazy_storage.Ok init), ctxt) - | (_, Sapling_state_t _, {id = Some id; _}) -> - Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>? fun ctxt -> - ok (f.f Sapling_state id (Fold_lazy_storage.Ok init), ctxt) - | (False_f, _, _) -> ok (Fold_lazy_storage.Ok init, ctxt) - | (_, Big_map_t (_, _, _), {id = None; _}) -> - ok (Fold_lazy_storage.Ok init, ctxt) - | (_, Sapling_state_t _, {id = None; _}) -> - ok (Fold_lazy_storage.Ok init, ctxt) - | (Pair_f (hl, hr), Pair_t ((tyl, _, _), (tyr, _, _), _), (xl, xr)) -> ( - fold_lazy_storage ~f ~init ctxt tyl xl ~has_lazy_storage:hl - >>? fun (init, ctxt) -> - match init with - | Fold_lazy_storage.Ok init -> - fold_lazy_storage ~f ~init ctxt tyr xr ~has_lazy_storage:hr - | Fold_lazy_storage.Error -> ok (init, ctxt)) - | (Union_f (has_lazy_storage, _), Union_t ((ty, _), (_, _), _), L x) -> - fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage - | (Union_f (_, has_lazy_storage), Union_t ((_, _), (ty, _), _), R x) -> - fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage - | (_, Option_t (_, _), None) -> ok (Fold_lazy_storage.Ok init, ctxt) - | (Option_f has_lazy_storage, Option_t (ty, _), Some x) -> - fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage - | (List_f has_lazy_storage, List_t (ty, _), l) -> - List.fold_left - (fun (acc : (('acc, error) Fold_lazy_storage.result * context) tzresult) - x -> - acc >>? fun (init, ctxt) -> - match init with - | Fold_lazy_storage.Ok init -> - fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage - | Fold_lazy_storage.Error -> ok (init, ctxt)) - (ok (Fold_lazy_storage.Ok init, ctxt)) - l.elements - | (Map_f has_lazy_storage, Map_t (_, ty, _), m) -> - Script_map.fold - (fun _ - v - (acc : (('acc, error) Fold_lazy_storage.result * context) tzresult) -> - acc >>? fun (init, ctxt) -> - match init with - | Fold_lazy_storage.Ok init -> - fold_lazy_storage ~f ~init ctxt ty v ~has_lazy_storage - | Fold_lazy_storage.Error -> ok (init, ctxt)) - m - (ok (Fold_lazy_storage.Ok init, ctxt)) - | _ -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/1962 - fix injectivity of types *) - assert false - -let[@coq_axiom_with_reason "gadt"] collect_lazy_storage ctxt ty x = - let has_lazy_storage = has_lazy_storage ty in - let f kind id (acc : (_, never) Fold_lazy_storage.result) = - let acc = match acc with Fold_lazy_storage.Ok acc -> acc in - Fold_lazy_storage.Ok (Lazy_storage.IdSet.add kind id acc) - in - fold_lazy_storage ~f:{f} ~init:no_lazy_storage_id ctxt ty x ~has_lazy_storage - >>? fun (ids, ctxt) -> - match ids with Fold_lazy_storage.Ok ids -> ok (ids, ctxt) - -let[@coq_axiom_with_reason "gadt"] extract_lazy_storage_diff ctxt mode - ~temporary ~to_duplicate ~to_update ty v = - (* - Basically [to_duplicate] are ids from the argument and [to_update] are ids - from the storage before execution (i.e. it is safe to reuse them since they - will be owned by the same contract). - *) - let to_duplicate = Lazy_storage.IdSet.diff to_duplicate to_update in - extract_lazy_storage_updates ctxt mode ~temporary to_duplicate [] ty v - >|=? fun (ctxt, v, alive, diffs) -> - let diffs = - if temporary then diffs - else - let dead = Lazy_storage.IdSet.diff to_update alive in - Lazy_storage.IdSet.fold_all - {f = (fun kind id acc -> Lazy_storage.make kind id Remove :: acc)} - dead - diffs - in - match diffs with - | [] -> (v, None, ctxt) - | diffs -> (v, Some diffs (* do not reverse *), ctxt) - -let list_of_big_map_ids ids = - Lazy_storage.IdSet.fold Big_map (fun id acc -> id :: acc) ids [] - -let parse_data = parse_data ~stack_depth:0 - -let parse_instr : - type a s. - ?type_logger:type_logger -> - tc_context -> - context -> - legacy:bool -> - Script.node -> - (a, s) stack_ty -> - ((a, s) judgement * context) tzresult Lwt.t = - fun ?type_logger tc_context ctxt ~legacy script_instr stack_ty -> - parse_instr - ~stack_depth:0 - ?type_logger - tc_context - ctxt - ~legacy - script_instr - stack_ty - -let unparse_data = unparse_data ~stack_depth:0 - -let unparse_code ctxt mode code = - (* Constants need to be expanded or [unparse_code] may fail. *) - Global_constants_storage.expand ctxt (strip_locations code) - >>=? fun (ctxt, code) -> unparse_code ~stack_depth:0 ctxt mode (root code) - -let parse_contract ~legacy context loc arg_ty contract ~entrypoint = - parse_contract ~stack_depth:0 ~legacy context loc arg_ty contract ~entrypoint - -let parse_toplevel ctxt ~legacy toplevel = - Global_constants_storage.expand ctxt toplevel >>=? fun (ctxt, toplevel) -> - Lwt.return @@ parse_toplevel ctxt ~legacy toplevel - -let parse_comparable_ty = parse_comparable_ty ~stack_depth:0 - -let parse_big_map_value_ty = parse_big_map_value_ty ~stack_depth:0 - -let parse_packable_ty = parse_packable_ty ~stack_depth:0 - -let parse_parameter_ty = parse_parameter_ty ~stack_depth:0 - -let parse_any_ty = parse_any_ty ~stack_depth:0 - -let parse_ty = parse_ty ~stack_depth:0 - -let ty_eq ctxt = ty_eq ~legacy:true ctxt - -let[@coq_axiom_with_reason "gadt"] get_single_sapling_state ctxt ty x = - let has_lazy_storage = has_lazy_storage ty in - let f (type i a u) (kind : (i, a, u) Lazy_storage.Kind.t) (id : i) - single_id_opt : (Sapling.Id.t option, unit) Fold_lazy_storage.result = - match kind with - | Lazy_storage.Kind.Sapling_state -> ( - match single_id_opt with - | Fold_lazy_storage.Ok None -> Fold_lazy_storage.Ok (Some id) - | Fold_lazy_storage.Ok (Some _) -> - Fold_lazy_storage.Error (* more than one *) - | Fold_lazy_storage.Error -> single_id_opt) - | _ -> single_id_opt - in - fold_lazy_storage ~f:{f} ~init:None ctxt ty x ~has_lazy_storage - >>? fun (id, ctxt) -> - match id with - | Fold_lazy_storage.Ok (Some id) -> ok (Some id, ctxt) - | Fold_lazy_storage.Ok None | Fold_lazy_storage.Error -> ok (None, ctxt) - -(* - - {!Script_cache} needs a measure of the script size in memory. - Determining this size is not easy in OCaml because of sharing. - - Indeed, many values present in the script share the same memory - area. This is especially true for types and stack types: they are - heavily shared in every typed IR internal representation. As a - consequence, computing the size of the typed IR without taking - sharing into account leads to a size which is sometimes two order - of magnitude bigger than the actual size. - - We could track down this sharing. Unfortunately, sharing is not - part of OCaml semantics: for this reason, a compiler can optimize - memory representation by adding more sharing. If two nodes use - different optimization flags or compilers, such a precise - computation of the memory footprint of scripts would lead to two - distinct sizes. As these sizes occur in the blockchain context, - this situation would lead to a fork. - - For this reason, we introduce a *size model* for the script size. - This model provides an overapproximation of the actual size in - memory. The risk is to be too far from the actual size: the cache - would then be wrongly marked as full. This situation would make the - cache less useful but should present no security risk . - -*) -let script_size - (Ex_script - { - code_size; - code = _; - arg_type = _; - storage; - storage_type; - root_name = _; - views = _; - }) = - let (nodes, storage_size) = - Script_typed_ir_size.value_size storage_type storage - in - let cost = Script_typed_ir_size_costs.nodes_cost ~nodes in - (Saturation_repr.(add code_size storage_size |> to_int), cost) diff --git a/src/proto_012_Psithaca/lib_protocol/script_ir_translator.mli b/src/proto_012_Psithaca/lib_protocol/script_ir_translator.mli deleted file mode 100644 index 0dedd1b2aa07..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_ir_translator.mli +++ /dev/null @@ -1,502 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Overview: - -This mli is organized into roughly three parts: - -1. A set of new types prefixed with "ex_" -Michelson is encoded in a GADT that preserves certain properties about its -type system. If you haven't read about GADT's, check out the relevant section -in the Tezos docs: -https://tezos.gitlab.io/developer/gadt.html#generalized-algebraic-data-types-gadts - -The idea is that type representing a Michelson type, ['a ty], is parameterized -by a type 'a. But that 'a can't be just _any_ type; it must be valid according -to the definition of ['a ty]. Thus, if I give you a value of type ['a ty], -all you know is that "there exists some 'a such that 'a ty exists". You must be -careful not to accidentally quantify 'a universally, that is "for all 'a, -'a ty exists", otherwise you'll get an annoying error about 'a trying to escape -it's scope. We do this by hiding 'a in an existential type. This is what -ex_comparable_ty, ex_ty, ex_stack_ty, etc. do. - -2. A set of functions dealing with high-level Michelson types: -This module also provides functions for interacting with the list, map, -set, and big_map Michelson types. - -3. A set of functions for parsing and typechecking Michelson. -Finally, and what you likely came for, the module provides many functions prefixed -with "parse_" that convert untyped Micheline (which is essentially S-expressions -with a few primitive atom types) into the GADT encoding well-typed Michelson. Likewise -there is a number of functions prefixed "unparse_" that do the reverse. These functions -consume gas, and thus are parameterized by an [Alpha_context.t]. - -The variety of functions reflects the variety of things one might want to parse, -from [parse_data] for arbitrary Micheline expressions to [parse_contract] for -well-formed Michelson contracts. -*) - -(** {1 Michelson Existential Witness types} *) -open Alpha_context - -open Script_tc_errors - -type ('ta, 'tb) eq = Eq : ('same, 'same) eq - -type ex_comparable_ty = - | Ex_comparable_ty : 'a Script_typed_ir.comparable_ty -> ex_comparable_ty - -type ex_ty = Ex_ty : 'a Script_typed_ir.ty -> ex_ty - -type ex_stack_ty = - | Ex_stack_ty : ('a, 's) Script_typed_ir.stack_ty -> ex_stack_ty - -type ex_script = Ex_script : ('a, 'b) Script_typed_ir.script -> ex_script - -type toplevel = { - code_field : Script.node; - arg_type : Script.node; - storage_type : Script.node; - views : Script_typed_ir.view Script_typed_ir.SMap.t; - root_name : Script_ir_annot.field_annot option; -} - -type ('arg, 'storage) code = { - code : - ( ('arg, 'storage) Script_typed_ir.pair, - ( Script_typed_ir.operation Script_typed_ir.boxed_list, - 'storage ) - Script_typed_ir.pair ) - Script_typed_ir.lambda; - arg_type : 'arg Script_typed_ir.ty; - storage_type : 'storage Script_typed_ir.ty; - views : Script_typed_ir.view Script_typed_ir.SMap.t; - root_name : Script_ir_annot.field_annot option; - code_size : Cache_memory_helpers.sint; - (** This is an over-approximation of the value size in memory, in - bytes, of the contract's static part, that is its source - code. This includes the code of the contract as well as the code - of the views. The storage size is not taken into account by this - field as it has a dynamic size. *) -} - -type ex_code = Ex_code : ('a, 'c) code -> ex_code - -type 'storage ex_view = - | Ex_view : - ('input * 'storage, 'output) Script_typed_ir.lambda - -> 'storage ex_view - -type ('a, 's, 'b, 'u) cinstr = { - apply : - 'r 'f. - ('a, 's) Script_typed_ir.kinfo -> - ('b, 'u, 'r, 'f) Script_typed_ir.kinstr -> - ('a, 's, 'r, 'f) Script_typed_ir.kinstr; -} - -type ('a, 's, 'b, 'u) descr = { - loc : Script.location; - bef : ('a, 's) Script_typed_ir.stack_ty; - aft : ('b, 'u) Script_typed_ir.stack_ty; - instr : ('a, 's, 'b, 'u) cinstr; -} - -type tc_context = - | Lambda : tc_context - | Dip : ('a, 's) Script_typed_ir.stack_ty * tc_context -> tc_context - | Toplevel : { - storage_type : 'sto Script_typed_ir.ty; - param_type : 'param Script_typed_ir.ty; - root_name : Script_ir_annot.field_annot option; - } - -> tc_context - -type ('a, 's) judgement = - | Typed : ('a, 's, 'b, 'u) descr -> ('a, 's) judgement - | Failed : { - descr : 'b 'u. ('b, 'u) Script_typed_ir.stack_ty -> ('a, 's, 'b, 'u) descr; - } - -> ('a, 's) judgement - -val close_descr : - ('a, 'b, 'c, 'd) descr -> ('a, 'b, 'c, 'd) Script_typed_ir.kdescr - -(** Flag that drives unparsing of typed values to nodes. - - [Optimized_legacy] must be kept backward-compatible in order to compute - valid hashes (of big map keys). - - [Optimized] may be used as long as the result can be read by parse_data. - - [Readable] produces with [string] values instead of [bytes] when feasible. -*) -type unparsing_mode = Optimized | Readable | Optimized_legacy - -type merge_type_error_flag = Default_merge_type_error | Fast_merge_type_error - -(* ---- Lists, Sets and Maps ----------------------------------------------- *) - -(** {2 High-level Michelson Data Types} *) -type type_logger = - Script.location -> - (Script.expr * Script.annot) list -> - (Script.expr * Script.annot) list -> - unit - -(** Create an empty big_map *) -val empty_big_map : - 'a Script_typed_ir.comparable_ty -> - 'b Script_typed_ir.ty -> - ('a, 'b) Script_typed_ir.big_map - -val big_map_mem : - context -> - 'key -> - ('key, 'value) Script_typed_ir.big_map -> - (bool * context) tzresult Lwt.t - -val big_map_get : - context -> - 'key -> - ('key, 'value) Script_typed_ir.big_map -> - ('value option * context) tzresult Lwt.t - -(** Update a big map. See {!big_map_get_and_update} for details. *) -val big_map_update : - context -> - 'key -> - 'value option -> - ('key, 'value) Script_typed_ir.big_map -> - (('key, 'value) Script_typed_ir.big_map * context) tzresult Lwt.t - -(** Update a big map, returning the old value of the given key and the new map. - - This does {i not} modify the underlying storage, only the diff table. - *) -val big_map_get_and_update : - context -> - 'key -> - 'value option -> - ('key, 'value) Script_typed_ir.big_map -> - (('value option * ('key, 'value) Script_typed_ir.big_map) * context) tzresult - Lwt.t - -val ty_eq : - context -> - Script.location -> - 'ta Script_typed_ir.ty -> - 'tb Script_typed_ir.ty -> - (('ta Script_typed_ir.ty, 'tb Script_typed_ir.ty) eq * context) tzresult - -val merge_types : - legacy:bool -> - merge_type_error_flag:merge_type_error_flag -> - Script.location -> - 'a Script_typed_ir.ty -> - 'b Script_typed_ir.ty -> - ( ('a Script_typed_ir.ty, 'b Script_typed_ir.ty) eq * 'a Script_typed_ir.ty, - error trace ) - Gas_monad.t - -(** {3 Parsing and Typechecking Michelson} *) -val parse_comparable_data : - ?type_logger:type_logger -> - context -> - 'a Script_typed_ir.comparable_ty -> - Script.node -> - ('a * context) tzresult Lwt.t - -val parse_data : - ?type_logger:type_logger -> - context -> - legacy:bool -> - allow_forged:bool -> - 'a Script_typed_ir.ty -> - Script.node -> - ('a * context) tzresult Lwt.t - -val unparse_data : - context -> - unparsing_mode -> - 'a Script_typed_ir.ty -> - 'a -> - (Script.node * context) tzresult Lwt.t - -val unparse_comparable_data : - loc:'loc -> - context -> - unparsing_mode -> - 'a Script_typed_ir.comparable_ty -> - 'a -> - ('loc Script.michelson_node * context) tzresult Lwt.t - -val unparse_code : - context -> - unparsing_mode -> - Script.node -> - (Script.node * context) tzresult Lwt.t - -val parse_instr : - ?type_logger:type_logger -> - tc_context -> - context -> - legacy:bool -> - Script.node -> - ('a, 's) Script_typed_ir.stack_ty -> - (('a, 's) judgement * context) tzresult Lwt.t - -(** - [parse_ty] specialized for the right-hand side part of a big map type, i.e. - the `value` in `big_map key value`. -*) -val parse_big_map_value_ty : - context -> legacy:bool -> Script.node -> (ex_ty * context) tzresult - -val parse_packable_ty : - context -> legacy:bool -> Script.node -> (ex_ty * context) tzresult - -val parse_parameter_ty : - context -> legacy:bool -> Script.node -> (ex_ty * context) tzresult - -val parse_comparable_ty : - context -> Script.node -> (ex_comparable_ty * context) tzresult - -val parse_view_input_ty : - context -> - stack_depth:int -> - legacy:bool -> - Script.node -> - (ex_ty * context) tzresult - -val parse_view_output_ty : - context -> - stack_depth:int -> - legacy:bool -> - Script.node -> - (ex_ty * context) tzresult - -val parse_view_returning : - ?type_logger:type_logger -> - context -> - legacy:bool -> - 'storage Script_typed_ir.ty -> - Script_typed_ir.view -> - ('storage ex_view * context) tzresult Lwt.t - -val typecheck_views : - ?type_logger:type_logger -> - context -> - legacy:bool -> - 'storage Script_typed_ir.ty -> - Script_typed_ir.view Script_typed_ir.SMap.t -> - context tzresult Lwt.t - -(** - [parse_ty] allowing big_map values, operations, contract and tickets. -*) -val parse_any_ty : - context -> legacy:bool -> Script.node -> (ex_ty * context) tzresult - -(** We expose [parse_ty] for convenience to external tools. Please use - specialized versions such as [parse_packable_ty], [parse_parameter_ty], - [parse_comparable_ty], or [parse_big_map_value_ty] if possible. *) -val parse_ty : - context -> - legacy:bool -> - allow_lazy_storage:bool -> - allow_operation:bool -> - allow_contract:bool -> - allow_ticket:bool -> - Script.node -> - (ex_ty * context) tzresult - -val unparse_ty : - loc:'loc -> - context -> - 'a Script_typed_ir.ty -> - ('loc Script.michelson_node * context) tzresult - -val unparse_comparable_ty : - loc:'loc -> - context -> - 'a Script_typed_ir.comparable_ty -> - ('loc Script.michelson_node * context) tzresult - -val ty_of_comparable_ty : - 'a Script_typed_ir.comparable_ty -> 'a Script_typed_ir.ty - -val parse_toplevel : - context -> legacy:bool -> Script.expr -> (toplevel * context) tzresult Lwt.t - -val add_field_annot : - Script_ir_annot.field_annot option -> - Script_ir_annot.var_annot option -> - ('loc, 'prim) Micheline.node -> - ('loc, 'prim) Micheline.node - -(** High-level function to typecheck a Michelson script. This function is not - used for validating operations but only for the [typecheck_code] RPC. - - If [show_types] is set to [true], details of the typechecking are returned - in the [type_map], otherwise the returned [type_map] is empty. *) -val typecheck_code : - legacy:bool -> - show_types:bool -> - context -> - Script.expr -> - (type_map * context) tzresult Lwt.t - -val serialize_ty_for_error : 'a Script_typed_ir.ty -> Script.expr - -val parse_code : - ?type_logger:type_logger -> - context -> - legacy:bool -> - code:Script.lazy_expr -> - (ex_code * context) tzresult Lwt.t - -val parse_storage : - ?type_logger:type_logger -> - context -> - legacy:bool -> - allow_forged:bool -> - 'storage Script_typed_ir.ty -> - storage:Script.lazy_expr -> - ('storage * context) tzresult Lwt.t - -(** Combines [parse_code] and [parse_storage] *) -val parse_script : - ?type_logger:type_logger -> - context -> - legacy:bool -> - allow_forged_in_storage:bool -> - Script.t -> - (ex_script * context) tzresult Lwt.t - -(* Gas accounting may not be perfect in this function, as it is only called by RPCs. *) -val unparse_script : - context -> - unparsing_mode -> - ('a, 'b) Script_typed_ir.script -> - (Script.t * context) tzresult Lwt.t - -val parse_contract : - legacy:bool -> - context -> - Script.location -> - 'a Script_typed_ir.ty -> - Contract.t -> - entrypoint:string -> - (context * 'a Script_typed_ir.typed_contract) tzresult Lwt.t - -val parse_contract_for_script : - context -> - Script.location -> - 'a Script_typed_ir.ty -> - Contract.t -> - entrypoint:string -> - (context * 'a Script_typed_ir.typed_contract option) tzresult Lwt.t - -val find_entrypoint : - 't Script_typed_ir.ty -> - root_name:Script_ir_annot.field_annot option -> - string -> - ((Script.node -> Script.node) * ex_ty) tzresult - -module Entrypoints_map : Map.S with type key = string - -val list_entrypoints : - 't Script_typed_ir.ty -> - context -> - root_name:Script_ir_annot.field_annot option -> - (Michelson_v1_primitives.prim list list - * (Michelson_v1_primitives.prim list * Script.unlocated_michelson_node) - Entrypoints_map.t) - tzresult - -val pack_data : - context -> 'a Script_typed_ir.ty -> 'a -> (bytes * context) tzresult Lwt.t - -val hash_comparable_data : - context -> - 'a Script_typed_ir.comparable_ty -> - 'a -> - (Script_expr_hash.t * context) tzresult Lwt.t - -val hash_data : - context -> - 'a Script_typed_ir.ty -> - 'a -> - (Script_expr_hash.t * context) tzresult Lwt.t - -type lazy_storage_ids - -val no_lazy_storage_id : lazy_storage_ids - -(** Traverse the given type, producing a {!lazy_storage_ids} for - use with {!extract_lazy_storage_diff}. - *) -val collect_lazy_storage : - context -> - 'a Script_typed_ir.ty -> - 'a -> - (lazy_storage_ids * context) tzresult - -val list_of_big_map_ids : lazy_storage_ids -> Big_map.Id.t list - -(** Produce a lazy storage diff, containing in-memory writes to - lazy data structures such as big_maps yet to be committed. - - The resulting diff can be committed to the underlying storage - (context) using [Lazy_storage_diff.apply]. - - @param to_duplicate - Lazy data structure reference produced via {!collect_lazy_storage} - that can not be reused. Typically collected via traversing - the parameters to a smart contract. - @param to_update - Lazy data structure reference produced via {!collect_lazy_storage} - that can be reused. Typically collected via traversing the previous - storage of a smart contract. - *) -val extract_lazy_storage_diff : - context -> - unparsing_mode -> - temporary:bool -> - to_duplicate:lazy_storage_ids -> - to_update:lazy_storage_ids -> - 'a Script_typed_ir.ty -> - 'a -> - ('a * Lazy_storage.diffs option * context) tzresult Lwt.t - -(* return [None] if none or more than one found *) -val get_single_sapling_state : - context -> - 'a Script_typed_ir.ty -> - 'a -> - (Sapling.Id.t option * context) tzresult - -(** [script_size script] returns an overapproximation of the size of - the in-memory representation of [script] as well as the cost - associated to computing that overapproximation. *) -val script_size : ex_script -> int * Gas_limit_repr.cost diff --git a/src/proto_012_Psithaca/lib_protocol/script_list.ml b/src/proto_012_Psithaca/lib_protocol/script_list.ml deleted file mode 100644 index 7e9cbdeb2214..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_list.ml +++ /dev/null @@ -1,32 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Script_typed_ir - -let empty : 'a boxed_list = {elements = []; length = 0} - -let cons : 'a -> 'a boxed_list -> 'a boxed_list = - fun elt l -> {length = 1 + l.length; elements = elt :: l.elements} diff --git a/src/proto_012_Psithaca/lib_protocol/script_list.mli b/src/proto_012_Psithaca/lib_protocol/script_list.mli deleted file mode 100644 index 01a4670df6b4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_list.mli +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Empty list. *) -val empty : 'a Script_typed_ir.boxed_list - -(** Prepend an element. *) -val cons : 'a -> 'a Script_typed_ir.boxed_list -> 'a Script_typed_ir.boxed_list diff --git a/src/proto_012_Psithaca/lib_protocol/script_map.ml b/src/proto_012_Psithaca/lib_protocol/script_map.ml deleted file mode 100644 index d53d16aeefeb..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_map.ml +++ /dev/null @@ -1,97 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Script_typed_ir - -let key_ty : type a b. (a, b) map -> a comparable_ty = - fun (module Box) -> Box.key_ty - -let empty : type a b. a comparable_ty -> (a, b) map = - fun ty -> - let module OPS = Map.Make (struct - type t = a - - let compare = Script_comparable.compare_comparable ty - end) in - (module struct - type key = a - - type value = b - - let key_ty = ty - - module OPS = struct - type value = b - - include OPS - - type nonrec t = value t - end - - let boxed = OPS.empty - - let size = 0 - end) - -let get : type key value. key -> (key, value) map -> value option = - fun k (module Box) -> Box.OPS.find k Box.boxed - -let update : type a b. a -> b option -> (a, b) map -> (a, b) map = - fun k v (module Box) -> - let (boxed, size) = - let contains = - match Box.OPS.find k Box.boxed with None -> false | _ -> true - in - match v with - | Some v -> (Box.OPS.add k v Box.boxed, Box.size + if contains then 0 else 1) - | None -> (Box.OPS.remove k Box.boxed, Box.size - if contains then 1 else 0) - in - (module struct - type key = a - - type value = b - - let key_ty = Box.key_ty - - module OPS = Box.OPS - - let boxed = boxed - - let size = size - end) - -let mem : type key value. key -> (key, value) map -> bool = - fun k (module Box) -> - match Box.OPS.find k Box.boxed with None -> false | _ -> true - -let fold : - type key value acc. - (key -> value -> acc -> acc) -> (key, value) map -> acc -> acc = - fun f (module Box) -> Box.OPS.fold f Box.boxed - -let size : type key value. (key, value) map -> Script_int.n Script_int.num = - fun (module Box) -> Script_int.(abs (of_int Box.size)) diff --git a/src/proto_012_Psithaca/lib_protocol/script_map.mli b/src/proto_012_Psithaca/lib_protocol/script_map.mli deleted file mode 100644 index 7bd3cd51e4b4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_map.mli +++ /dev/null @@ -1,49 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -val empty : 'a Script_typed_ir.comparable_ty -> ('a, 'b) Script_typed_ir.map - -val fold : - ('key -> 'value -> 'acc -> 'acc) -> - ('key, 'value) Script_typed_ir.map -> - 'acc -> - 'acc - -val update : - 'a -> - 'b option -> - ('a, 'b) Script_typed_ir.map -> - ('a, 'b) Script_typed_ir.map - -val mem : 'key -> ('key, 'value) Script_typed_ir.map -> bool - -val get : 'key -> ('key, 'value) Script_typed_ir.map -> 'value option - -val key_ty : ('a, 'b) Script_typed_ir.map -> 'a Script_typed_ir.comparable_ty - -val size : ('a, 'b) Script_typed_ir.map -> Script_int.n Script_int.num diff --git a/src/proto_012_Psithaca/lib_protocol/script_repr.ml b/src/proto_012_Psithaca/lib_protocol/script_repr.ml deleted file mode 100644 index c286e56f9087..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_repr.ml +++ /dev/null @@ -1,353 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type location = Micheline.canonical_location - -let location_encoding = Micheline.canonical_location_encoding - -type annot = Micheline.annot - -type expr = Michelson_v1_primitives.prim Micheline.canonical - -type lazy_expr = expr Data_encoding.lazy_t - -type 'location michelson_node = - ('location, Michelson_v1_primitives.prim) Micheline.node - -type unlocated_michelson_node = unit michelson_node - -type node = location michelson_node - -let expr_encoding = - Micheline.canonical_encoding - ~variant:"michelson_v1" - Michelson_v1_primitives.prim_encoding - -type error += Lazy_script_decode (* `Permanent *) - -let () = - register_error_kind - `Permanent - ~id:"invalid_binary_format" - ~title:"Invalid binary format" - ~description: - "Could not deserialize some piece of data from its binary representation" - Data_encoding.empty - (function Lazy_script_decode -> Some () | _ -> None) - (fun () -> Lazy_script_decode) - -let lazy_expr_encoding = Data_encoding.lazy_encoding expr_encoding - -let lazy_expr expr = Data_encoding.make_lazy expr_encoding expr - -type t = {code : lazy_expr; storage : lazy_expr} - -let encoding = - let open Data_encoding in - def "scripted.contracts" - @@ conv - (fun {code; storage} -> (code, storage)) - (fun (code, storage) -> {code; storage}) - (obj2 (req "code" lazy_expr_encoding) (req "storage" lazy_expr_encoding)) - -module S = Saturation_repr - -module Micheline_size = struct - type t = { - nodes : S.may_saturate S.t; - string_bytes : S.may_saturate S.t; - z_bytes : S.may_saturate S.t; - } - - let make ~nodes ~string_bytes ~z_bytes = {nodes; string_bytes; z_bytes} - - let zero = {nodes = S.zero; string_bytes = S.zero; z_bytes = S.zero} - - let add_int acc n = - let numbits = Z.numbits n in - let z_bytes = - S.safe_int ((numbits + 7) / 8) - (* Compute the number of bytes in a Z.t *) - in - { - nodes = S.succ acc.nodes; - string_bytes = acc.string_bytes; - z_bytes = S.add acc.z_bytes z_bytes; - } - - let add_string acc n = - let string_bytes = S.safe_int (String.length n) in - { - nodes = S.succ acc.nodes; - string_bytes = S.add acc.string_bytes string_bytes; - z_bytes = acc.z_bytes; - } - - let add_bytes acc n = - let string_bytes = S.safe_int (Bytes.length n) in - { - nodes = S.succ acc.nodes; - string_bytes = S.add acc.string_bytes string_bytes; - z_bytes = acc.z_bytes; - } - - let add_node s = {s with nodes = S.succ s.nodes} - - (* We model annotations as Seqs of Strings *) - let of_annots acc annots = - List.fold_left (fun acc s -> add_string acc s) acc annots - - let[@coq_struct "nodes"] rec of_nodes acc nodes more_nodes = - let open Micheline in - match nodes with - | [] -> ( - match more_nodes with - | [] -> acc - | nodes :: more_nodes -> - (of_nodes [@ocaml.tailcall]) acc nodes more_nodes) - | Int (_, n) :: nodes -> - let acc = add_int acc n in - (of_nodes [@ocaml.tailcall]) acc nodes more_nodes - | String (_, s) :: nodes -> - let acc = add_string acc s in - (of_nodes [@ocaml.tailcall]) acc nodes more_nodes - | Bytes (_, s) :: nodes -> - let acc = add_bytes acc s in - (of_nodes [@ocaml.tailcall]) acc nodes more_nodes - | Prim (_, _, args, annots) :: nodes -> - let acc = add_node acc in - let acc = of_annots acc annots in - (of_nodes [@ocaml.tailcall]) acc args (nodes :: more_nodes) - | Seq (_, args) :: nodes -> - let acc = add_node acc in - (of_nodes [@ocaml.tailcall]) acc args (nodes :: more_nodes) - - let of_node node = of_nodes zero [node] [] - - let dot_product s1 s2 = - S.add - (S.mul s1.nodes s2.nodes) - (S.add - (S.mul s1.string_bytes s2.string_bytes) - (S.mul s1.z_bytes s2.z_bytes)) -end - -(* Costs pertaining to deserialization of Micheline values (bytes to Micheline). - The costs are given in atomic steps (see [Gas_limit_repr]). *) -module Micheline_decoding = struct - (* Cost vector allowing to compute decoding costs as a function of the - size of the Micheline term *) - let micheline_size_dependent_cost = - let traversal_cost = S.safe_int 60 in - let string_per_byte_cost = S.safe_int 10 in - let z_per_byte_cost = S.safe_int 10 in - Micheline_size.make - ~nodes:traversal_cost - ~string_bytes:string_per_byte_cost - ~z_bytes:z_per_byte_cost - - let bytes_dependent_cost = S.safe_int 20 -end - -(* Costs pertaining to serialization of Micheline values (Micheline to bytes) - The costs are given in atomic steps (see [Gas_limit_repr]). *) -module Micheline_encoding = struct - (* Cost vector allowing to compute encoding cost as a function of the - size of the Micheline term *) - let micheline_size_dependent_cost = - let traversal_cost = S.safe_int 100 in - let string_per_byte_cost = S.safe_int 10 in - let z_per_byte_cost = S.safe_int 25 in - Micheline_size.make - ~nodes:traversal_cost - ~string_bytes:string_per_byte_cost - ~z_bytes:z_per_byte_cost - - let bytes_dependent_cost = S.safe_int 33 -end - -let expr_size expr = Micheline_size.of_node (Micheline.root expr) - -(* Compute the cost of serializing a term of given [size]. *) -let serialization_cost size = - Gas_limit_repr.atomic_step_cost - @@ Micheline_size.dot_product - size - Micheline_encoding.micheline_size_dependent_cost - -(* Compute the cost of deserializing a term of given [size]. *) -let deserialization_cost size = - Gas_limit_repr.atomic_step_cost - @@ Micheline_size.dot_product - size - Micheline_decoding.micheline_size_dependent_cost - -(* Estimate the cost of deserializing a term encoded in [bytes_len] bytes. *) -let deserialization_cost_estimated_from_bytes bytes_len = - Gas_limit_repr.atomic_step_cost - @@ S.mul Micheline_decoding.bytes_dependent_cost (S.safe_int bytes_len) - -(* Estimate the cost of serializing a term from its encoded form, - having [bytes_len] bytes. *) -let serialization_cost_estimated_from_bytes bytes_len = - Gas_limit_repr.atomic_step_cost - @@ S.mul Micheline_encoding.bytes_dependent_cost (S.safe_int bytes_len) - -(* Cost of running [strip_locations] on a term with [size] nodes. - Note that [strip_locations] will reallocate a fresh Micheline tree. - This only depends on the total number of nodes (not the size of - the leaves). *) -let cost_micheline_strip_locations size = - Gas_limit_repr.atomic_step_cost @@ S.mul (S.safe_int size) (S.safe_int 51) - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2049 - Plugin benchmarked gas. - Replace this definition, copied from [cost_michelines_strip_locations]. -*) -(* Cost of running [strip_annotations] on a term with [size] nodes. - Note that [strip_annotations] will reallocate a fresh Micheline tree. - This only depends on the total number of nodes (not the size of - the leaves). *) -let cost_micheline_strip_annotations size = - Gas_limit_repr.atomic_step_cost @@ S.mul (S.safe_int size) (S.safe_int 51) - -(* This is currently used to estimate the cost of serializing an operation. *) -let bytes_node_cost s = serialization_cost_estimated_from_bytes (Bytes.length s) - -let deserialized_cost expr = - Gas_limit_repr.atomic_step_cost @@ deserialization_cost (expr_size expr) - -let serialized_cost bytes = - let cost = - let size = Bytes.length bytes in - S.add (serialization_cost_estimated_from_bytes size) - @@ (* N_IConcat_bytes_pair inlined here *) - S.add (S.safe_int 65) (S.shift_right (S.safe_int size) 4) - in - Gas_limit_repr.atomic_step_cost cost - -let force_decode_cost lexpr = - Data_encoding.apply_lazy - ~fun_value:(fun _ -> Gas_limit_repr.free) - ~fun_bytes:(fun b -> - deserialization_cost_estimated_from_bytes (Bytes.length b)) - ~fun_combine:(fun _ _ -> Gas_limit_repr.free) - lexpr - -let stable_force_decode_cost lexpr = - let has_bytes = - Data_encoding.apply_lazy - ~fun_value:(fun v -> `Only_value v) - ~fun_bytes:(fun b -> `Has_bytes b) - ~fun_combine:(fun _v b -> - (* When the lazy_expr contains both a deserialized version - and a serialized one, we compute the cost from the - serialized version because its is cheaper to do. *) - b) - lexpr - in - match has_bytes with - | `Has_bytes b -> deserialization_cost_estimated_from_bytes (Bytes.length b) - | `Only_value v -> - (* This code path should not be reached in theory because values that are - decoded should have been encoded before. - Here we use Data_encoding.Binary.length, which yields the same results - as serializing the value and taking the size, without the need to - encode (in particular, less allocations). - *) - deserialization_cost_estimated_from_bytes - (Data_encoding.Binary.length expr_encoding v) - -let force_decode lexpr = - match Data_encoding.force_decode lexpr with - | Some v -> ok v - | None -> error Lazy_script_decode - -let force_bytes_cost expr = - (* Estimating the cost directly from the bytes would be cheaper, but - using [serialized_cost] is more accurate. *) - Data_encoding.apply_lazy - ~fun_value:(fun v -> serialization_cost (expr_size v)) - ~fun_bytes:(fun _ -> Gas_limit_repr.free) - ~fun_combine:(fun _ _ -> Gas_limit_repr.free) - expr - -let force_bytes expr = - Error_monad.catch_f - (fun () -> Data_encoding.force_bytes expr) - (fun _ -> Lazy_script_decode) - -let unit = - Micheline.strip_locations (Prim (0, Michelson_v1_primitives.D_Unit, [], [])) - -let unit_parameter = lazy_expr unit - -let is_unit_parameter = - let unit_bytes = Data_encoding.force_bytes unit_parameter in - Data_encoding.apply_lazy - ~fun_value:(fun v -> - match Micheline.root v with - | Prim (_, Michelson_v1_primitives.D_Unit, [], []) -> true - | _ -> false) - ~fun_bytes:(fun b -> Compare.Bytes.equal b unit_bytes) - ~fun_combine:(fun res _ -> res) - -let[@coq_struct "node"] rec strip_annotations node = - let open Micheline in - match node with - | (Int (_, _) | String (_, _) | Bytes (_, _)) as leaf -> leaf - | Prim (loc, name, args, _) -> - Prim (loc, name, List.map strip_annotations args, []) - | Seq (loc, args) -> Seq (loc, List.map strip_annotations args) - -let rec micheline_fold_aux node f acc k = - match node with - | Micheline.Int (_, _) -> k (f acc node) - | Micheline.String (_, _) -> k (f acc node) - | Micheline.Bytes (_, _) -> k (f acc node) - | Micheline.Prim (_, _, subterms, _) -> - micheline_fold_nodes subterms f (f acc node) k - | Micheline.Seq (_, subterms) -> - micheline_fold_nodes subterms f (f acc node) k - -and[@coq_mutual_as_notation] [@coq_struct "subterms"] micheline_fold_nodes - subterms f acc k = - match subterms with - | [] -> k acc - | node :: nodes -> - micheline_fold_nodes nodes f acc @@ fun acc -> - micheline_fold_aux node f acc k - -let fold node init f = micheline_fold_aux node f init (fun x -> x) - -let micheline_nodes node = fold node 0 @@ fun n _ -> n + 1 - -let strip_locations_cost node = - let nodes = micheline_nodes node in - cost_micheline_strip_locations nodes - -let strip_annotations_cost node = - let nodes = micheline_nodes node in - cost_micheline_strip_annotations nodes diff --git a/src/proto_012_Psithaca/lib_protocol/script_repr.mli b/src/proto_012_Psithaca/lib_protocol/script_repr.mli deleted file mode 100644 index 66569c6bf094..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_repr.mli +++ /dev/null @@ -1,130 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Defines a Michelson expression representation as a Micheline node with - canonical ([int]) location and [Michelson_v1_primitives.prim] as content. - - Types [expr] and [node] both define representation of Michelson - expressions and are indeed the same type internally, although this is not - visible outside Micheline due to interface abstraction. *) - -(** Locations are used by Micheline mostly for error-reporting and pretty- - printing expressions. [canonical_location] is simply an [int]. *) -type location = Micheline.canonical_location - -(** Annotations attached to Michelson expressions. *) -type annot = Micheline.annot - -(** Represents a Michelson expression as canonical Micheline. *) -type expr = Michelson_v1_primitives.prim Micheline.canonical - -type error += Lazy_script_decode (* `Permanent *) - -(** A record containing either an underlying serialized representation of an - expression or a deserialized one, or both. If either is absent, it will be - computed on-demand. *) -type lazy_expr = expr Data_encoding.lazy_t - -type 'location michelson_node = - ('location, Michelson_v1_primitives.prim) Micheline.node - -type unlocated_michelson_node = unit michelson_node - -(** Same as [expr], but used in different contexts, as required by Micheline's - abstract interface. *) -type node = location michelson_node - -val location_encoding : location Data_encoding.t - -val expr_encoding : expr Data_encoding.t - -val lazy_expr_encoding : lazy_expr Data_encoding.t - -val lazy_expr : expr -> lazy_expr - -(** Type [t] joins the contract's code and storage in a single record. *) -type t = {code : lazy_expr; storage : lazy_expr} - -val encoding : t Data_encoding.encoding - -(* Basic gas costs of operations related to processing Michelson: *) - -val deserialization_cost_estimated_from_bytes : int -> Gas_limit_repr.cost - -val deserialized_cost : expr -> Gas_limit_repr.cost - -val serialized_cost : bytes -> Gas_limit_repr.cost - -val bytes_node_cost : bytes -> Gas_limit_repr.cost - -(** Returns (a lower bound on) the cost to deserialize a - {!lazy_expr}. If the expression has already been deserialized - (i.e. the lazy expression contains the deserialized value or both - the bytes representation and the deserialized value) then the cost - is {b free}. *) -val force_decode_cost : lazy_expr -> Gas_limit_repr.cost - -(** Like {!force_decode_cost}, excepted that the returned cost does - not depend on the internal state of the lazy_expr. This means that - the cost is never free (excepted for zero bytes expressions). *) -val stable_force_decode_cost : lazy_expr -> Gas_limit_repr.cost - -val force_decode : lazy_expr -> expr tzresult - -(** Returns the cost to serialize a {!lazy_expr}. If the expression - has already been deserialized (i.e. le lazy expression contains the - bytes representation or both the bytes representation and the - deserialized value) then the cost is {b free}. *) -val force_bytes_cost : lazy_expr -> Gas_limit_repr.cost - -val force_bytes : lazy_expr -> bytes tzresult - -val unit_parameter : lazy_expr - -val is_unit_parameter : lazy_expr -> bool - -val strip_annotations : node -> node - -val strip_locations_cost : _ michelson_node -> Gas_limit_repr.cost - -val strip_annotations_cost : node -> Gas_limit_repr.cost - -module Micheline_size : sig - type t = { - nodes : Saturation_repr.may_saturate Saturation_repr.t; - string_bytes : Saturation_repr.may_saturate Saturation_repr.t; - z_bytes : Saturation_repr.may_saturate Saturation_repr.t; - } - - val of_node : node -> t -end - -(** [micheline_nodes root] returns the number of internal nodes in the - micheline expression held from [root]. *) -val micheline_nodes : node -> int - -(** [fold node i f] traverses [node] applying [f] on an - accumulator initialized by [i]. *) -val fold : node -> 'c -> ('c -> node -> 'c) -> 'c diff --git a/src/proto_012_Psithaca/lib_protocol/script_set.ml b/src/proto_012_Psithaca/lib_protocol/script_set.ml deleted file mode 100644 index 703ffae7aaa7..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_set.ml +++ /dev/null @@ -1,75 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Script_typed_ir - -let empty : type a. a comparable_ty -> a set = - fun ty -> - let module OPS = Set.Make (struct - type t = a - - let compare = Script_comparable.compare_comparable ty - end) in - (module struct - type elt = a - - let elt_ty = ty - - module OPS = OPS - - let boxed = OPS.empty - - let size = 0 - end) - -let update : type a. a -> bool -> a set -> a set = - fun v b (module Box) -> - (module struct - type elt = a - - let elt_ty = Box.elt_ty - - module OPS = Box.OPS - - let boxed = - if b then Box.OPS.add v Box.boxed else Box.OPS.remove v Box.boxed - - let size = - let mem = Box.OPS.mem v Box.boxed in - if mem then if b then Box.size else Box.size - 1 - else if b then Box.size + 1 - else Box.size - end) - -let mem : type elt. elt -> elt set -> bool = - fun v (module Box) -> Box.OPS.mem v Box.boxed - -let fold : type elt acc. (elt -> acc -> acc) -> elt set -> acc -> acc = - fun f (module Box) -> Box.OPS.fold f Box.boxed - -let size : type elt. elt set -> Script_int.n Script_int.num = - fun (module Box) -> Script_int.(abs (of_int Box.size)) diff --git a/src/proto_012_Psithaca/lib_protocol/script_set.mli b/src/proto_012_Psithaca/lib_protocol/script_set.mli deleted file mode 100644 index f97a434c25ab..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_set.mli +++ /dev/null @@ -1,37 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -val empty : 'a Script_typed_ir.comparable_ty -> 'a Script_typed_ir.set - -val fold : ('elt -> 'acc -> 'acc) -> 'elt Script_typed_ir.set -> 'acc -> 'acc - -val update : 'a -> bool -> 'a Script_typed_ir.set -> 'a Script_typed_ir.set - -val mem : 'elt -> 'elt Script_typed_ir.set -> bool - -val size : 'elt Script_typed_ir.set -> Script_int.n Script_int.num diff --git a/src/proto_012_Psithaca/lib_protocol/script_string_repr.ml b/src/proto_012_Psithaca/lib_protocol/script_string_repr.ml deleted file mode 100644 index e6e45dd9ee6d..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_string_repr.ml +++ /dev/null @@ -1,77 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Strings of printable characters *) - -type t = string (* Invariant: contains only printable characters *) - -type error += Non_printable_character of (int * string) - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"michelson_v1.non_printable_character" - ~title:"Non printable character in a Michelson string" - ~description: - "Michelson strings are only allowed to contain printable characters \ - (either the newline character or characters in the [32, 126] ASCII \ - range)." - ~pp:(fun ppf (pos, s) -> - Format.fprintf - ppf - "In Michelson string \"%s\", character at position %d has ASCII code \ - %d. Expected: either a newline character (ASCII code 10) or a \ - printable character (ASCII code between 32 and 126)." - s - pos - (Char.code s.[pos])) - (obj2 (req "position" int31) (req "string" string)) - (function Non_printable_character (pos, s) -> Some (pos, s) | _ -> None) - (fun (pos, s) -> Non_printable_character (pos, s)) - -let empty = "" - -let of_string v = - let rec check_printable_ascii i = - if Compare.Int.(i < 0) then ok v - else - match v.[i] with - | '\n' | '\x20' .. '\x7E' -> check_printable_ascii (i - 1) - | _ -> error @@ Non_printable_character (i, v) - in - check_printable_ascii (String.length v - 1) - -let to_string s = s - -let compare = Compare.String.compare - -let length = String.length - -let concat_pair x y = x ^ y - -let concat l = String.concat "" l - -let sub s offset length = String.sub s offset length diff --git a/src/proto_012_Psithaca/lib_protocol/script_string_repr.mli b/src/proto_012_Psithaca/lib_protocol/script_string_repr.mli deleted file mode 100644 index f94b65b389e1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_string_repr.mli +++ /dev/null @@ -1,46 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Strings of printable characters *) - -type t - -type error += Non_printable_character of (int * string) - -val empty : t - -val of_string : string -> t tzresult - -val to_string : t -> string - -val compare : t -> t -> int - -val length : t -> int - -val concat_pair : t -> t -> t - -val concat : t list -> t - -val sub : t -> int -> int -> t diff --git a/src/proto_012_Psithaca/lib_protocol/script_tc_errors.ml b/src/proto_012_Psithaca/lib_protocol/script_tc_errors.ml deleted file mode 100644 index 2fd81d50fb59..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_tc_errors.ml +++ /dev/null @@ -1,201 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Script - -(* ---- Error definitions ---------------------------------------------------*) - -type kind = Int_kind | String_kind | Bytes_kind | Prim_kind | Seq_kind - -type unparsed_stack_ty = (Script.expr * Script.annot) list - -type type_map = (Script.location * (unparsed_stack_ty * unparsed_stack_ty)) list - -(* Structure errors *) -type error += Invalid_arity of Script.location * prim * int * int - -type error += Invalid_seq_arity of Script.location * int * int - -type error += - | Invalid_namespace of - Script.location - * prim - * Michelson_v1_primitives.namespace - * Michelson_v1_primitives.namespace - -type error += Invalid_primitive of Script.location * prim list * prim - -type error += Invalid_kind of Script.location * kind list * kind - -type error += Invalid_never_expr of Script.location - -type error += Missing_field of prim - -type error += Duplicate_field of Script.location * prim - -type error += Unexpected_lazy_storage of Script.location - -type error += Unexpected_operation of Script.location - -type error += Unexpected_contract of Script.location - -type error += No_such_entrypoint of string - -type error += Duplicate_entrypoint of string - -type error += Unreachable_entrypoint of prim list - -type error += Entrypoint_name_too_long of string - -(* Instruction typing errors *) -type error += Fail_not_in_tail_position of Script.location - -type error += - | Undefined_binop : - Script.location * prim * Script.expr * Script.expr - -> error - -type error += Undefined_unop : Script.location * prim * Script.expr -> error - -type error += - | Bad_return : Script.location * unparsed_stack_ty * Script.expr -> error - -type error += - | Bad_stack : Script.location * prim * int * unparsed_stack_ty -> error - -type error += - | Unmatched_branches : - Script.location * unparsed_stack_ty * unparsed_stack_ty - -> error - -(* View errors *) -type error += View_name_too_long of string - -type error += Bad_view_name of Script.location - -type error += - | Ill_typed_view of { - loc : Script.location; - actual : unparsed_stack_ty; - expected : unparsed_stack_ty; - } - -type error += Duplicated_view_name of Script.location - -type error += Self_in_lambda of Script.location - -type error += Bad_stack_length - -type error += Bad_stack_item of int - -type error += Inconsistent_annotations of string * string - -type error += - | Inconsistent_type_annotations : - Script.location * Script.expr * Script.expr - -> error - -type error += Inconsistent_field_annotations of string * string - -type error += Unexpected_annotation of Script.location - -type error += Ungrouped_annotations of Script.location - -type error += Invalid_map_body : Script.location * unparsed_stack_ty -> error - -type error += Invalid_map_block_fail of Script.location - -type error += - | Invalid_iter_body : - Script.location * unparsed_stack_ty * unparsed_stack_ty - -> error - -type error += Type_too_large : Script.location * int -> error - -type error += Pair_bad_argument of Script.location - -type error += Unpair_bad_argument of Script.location - -type error += Dup_n_bad_argument of Script.location - -type error += Dup_n_bad_stack of Script.location - -(* Value typing errors *) -type error += - | Invalid_constant : Script.location * Script.expr * Script.expr -> error - -type error += - | Invalid_syntactic_constant : Script.location * Script.expr * string -> error - -type error += Invalid_contract of Script.location * Contract.t - -type error += Invalid_big_map of Script.location * Big_map.Id.t - -type error += Comparable_type_expected : Script.location * Script.expr -> error - -type error += Inconsistent_type_sizes : int * int -> error - -type error += - | Inconsistent_types : - Script.location option * Script.expr * Script.expr - -> error - -type error += - | Inconsistent_memo_sizes : Sapling.Memo_size.t * Sapling.Memo_size.t -> error - -type error += Unordered_map_keys of Script.location * Script.expr - -type error += Unordered_set_values of Script.location * Script.expr - -type error += Duplicate_map_keys of Script.location * Script.expr - -type error += Duplicate_set_values of Script.location * Script.expr - -(* Toplevel errors *) -type error += - | Ill_typed_data : string option * Script.expr * Script.expr -> error - -type error += Ill_formed_type of string option * Script.expr * Script.location - -type error += Ill_typed_contract : Script.expr * type_map -> error - -(* Deprecation errors *) -type error += Deprecated_instruction of prim - -(* Stackoverflow errors *) -type error += Typechecking_too_many_recursive_calls - -type error += Unparsing_too_many_recursive_calls - -(* Ticket errors *) -type error += Unexpected_ticket of Script.location - -type error += Unexpected_forged_value of Script.location - -type error += Non_dupable_type of Script.location * Script.expr - -(* Impossible errors *) -type error += Unparsing_invariant_violated diff --git a/src/proto_012_Psithaca/lib_protocol/script_tc_errors_registration.ml b/src/proto_012_Psithaca/lib_protocol/script_tc_errors_registration.ml deleted file mode 100644 index 06c60d426ce6..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_tc_errors_registration.ml +++ /dev/null @@ -1,805 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Script -open Script_tc_errors - -(* Helpers for encoding *) -let type_map_enc = - let open Data_encoding in - let stack_enc = list (tup2 Script.expr_encoding (list string)) in - list - (conv - (fun (loc, (bef, aft)) -> (loc, bef, aft)) - (fun (loc, bef, aft) -> (loc, (bef, aft))) - (obj3 - (req "location" Script.location_encoding) - (req "stack_before" stack_enc) - (req "stack_after" stack_enc))) - -let stack_ty_enc = - let open Data_encoding in - list (obj2 (req "type" Script.expr_encoding) (dft "annots" (list string) [])) - -(* main registration *) -let () = - let open Data_encoding in - let located enc = - merge_objs (obj1 (req "location" Script.location_encoding)) enc - in - let arity_enc = int8 in - let namespace_enc = - def - "primitiveNamespace" - ~title:"Primitive namespace" - ~description: - "One of the five possible namespaces of primitive (data constructor, \ - type name, instruction, keyword, or constant hash)." - @@ string_enum - [ - ("type", Michelson_v1_primitives.Type_namespace); - ("constant", Constant_namespace); - ("instruction", Instr_namespace); - ("keyword", Keyword_namespace); - ("constant_hash", Constant_hash_namespace); - ] - in - let kind_enc = - def - "expressionKind" - ~title:"Expression kind" - ~description: - "One of the four possible kinds of expression (integer, string, \ - primitive application or sequence)." - @@ string_enum - [ - ("integer", Int_kind); - ("string", String_kind); - ("bytes", Bytes_kind); - ("primitiveApplication", Prim_kind); - ("sequence", Seq_kind); - ] - in - (* -- Structure errors ---------------------- *) - (* Invalid arity *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_arity" - ~title:"Invalid arity" - ~description: - "In a script or data expression, a primitive was applied to an \ - unsupported number of arguments." - (located - (obj3 - (req "primitive_name" Script.prim_encoding) - (req "expected_arity" arity_enc) - (req "wrong_arity" arity_enc))) - (function - | Invalid_arity (loc, name, exp, got) -> Some (loc, (name, exp, got)) - | _ -> None) - (fun (loc, (name, exp, got)) -> Invalid_arity (loc, name, exp, got)) ; - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_seq_arity" - ~title:"Invalid sequence arity" - ~description: - "In a script or data expression, a sequence was used with a number of \ - elements too small." - (located - (obj2 - (req "minimal_expected_arity" arity_enc) - (req "wrong_arity" arity_enc))) - (function - | Invalid_seq_arity (loc, exp, got) -> Some (loc, (exp, got)) | _ -> None) - (fun (loc, (exp, got)) -> Invalid_seq_arity (loc, exp, got)) ; - (* Missing field *) - register_error_kind - `Permanent - ~id:"michelson_v1.missing_script_field" - ~title:"Script is missing a field (parse error)" - ~description:"When parsing script, a field was expected, but not provided" - (obj1 (req "prim" prim_encoding)) - (function Missing_field prim -> Some prim | _ -> None) - (fun prim -> Missing_field prim) ; - (* Invalid primitive *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_primitive" - ~title:"Invalid primitive" - ~description:"In a script or data expression, a primitive was unknown." - (located - (obj2 - (dft "expected_primitive_names" (list prim_encoding) []) - (req "wrong_primitive_name" prim_encoding))) - (function - | Invalid_primitive (loc, exp, got) -> Some (loc, (exp, got)) | _ -> None) - (fun (loc, (exp, got)) -> Invalid_primitive (loc, exp, got)) ; - (* Invalid kind *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_expression_kind" - ~title:"Invalid expression kind" - ~description: - "In a script or data expression, an expression was of the wrong kind \ - (for instance a string where only a primitive applications can appear)." - (located - (obj2 (req "expected_kinds" (list kind_enc)) (req "wrong_kind" kind_enc))) - (function - | Invalid_kind (loc, exp, got) -> Some (loc, (exp, got)) | _ -> None) - (fun (loc, (exp, got)) -> Invalid_kind (loc, exp, got)) ; - (* Invalid namespace *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_primitive_namespace" - ~title:"Invalid primitive namespace" - ~description: - "In a script or data expression, a primitive was of the wrong namespace." - (located - (obj3 - (req "primitive_name" prim_encoding) - (req "expected_namespace" namespace_enc) - (req "wrong_namespace" namespace_enc))) - (function - | Invalid_namespace (loc, name, exp, got) -> Some (loc, (name, exp, got)) - | _ -> None) - (fun (loc, (name, exp, got)) -> Invalid_namespace (loc, name, exp, got)) ; - (* Invalid literal for type never *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_never_expr" - ~title:"Invalid expression for type never" - ~description: - "In a script or data expression, an expression was provided but a value \ - of type never was expected. No expression can have type never." - (located unit) - (function Invalid_never_expr loc -> Some (loc, ()) | _ -> None) - (fun (loc, ()) -> Invalid_never_expr loc) ; - (* Duplicate field *) - register_error_kind - `Permanent - ~id:"michelson_v1.duplicate_script_field" - ~title:"Script has a duplicated field (parse error)" - ~description:"When parsing script, a field was found more than once" - (obj2 (req "loc" location_encoding) (req "prim" prim_encoding)) - (function Duplicate_field (loc, prim) -> Some (loc, prim) | _ -> None) - (fun (loc, prim) -> Duplicate_field (loc, prim)) ; - (* Unexpected big_map *) - register_error_kind - `Permanent - ~id:"michelson_v1.unexpected_lazy_storage" - ~title:"Lazy storage in unauthorized position (type error)" - ~description: - "When parsing script, a big_map or sapling_state type was found in a \ - position where it could end up stored inside a big_map, which is \ - forbidden for now." - (obj1 (req "loc" location_encoding)) - (function Unexpected_lazy_storage loc -> Some loc | _ -> None) - (fun loc -> Unexpected_lazy_storage loc) ; - (* Unexpected operation *) - register_error_kind - `Permanent - ~id:"michelson_v1.unexpected_operation" - ~title:"Operation in unauthorized position (type error)" - ~description: - "When parsing script, an operation type was found in the storage or \ - parameter field." - (obj1 (req "loc" location_encoding)) - (function Unexpected_operation loc -> Some loc | _ -> None) - (fun loc -> Unexpected_operation loc) ; - (* No such entrypoint *) - register_error_kind - `Permanent - ~id:"michelson_v1.no_such_entrypoint" - ~title:"No such entrypoint (type error)" - ~description:"An entrypoint was not found when calling a contract." - (obj1 (req "entrypoint" string)) - (function No_such_entrypoint entrypoint -> Some entrypoint | _ -> None) - (fun entrypoint -> No_such_entrypoint entrypoint) ; - (* Unreachable entrypoint *) - register_error_kind - `Permanent - ~id:"michelson_v1.unreachable_entrypoint" - ~title:"Unreachable entrypoint (type error)" - ~description:"An entrypoint in the contract is not reachable." - (obj1 (req "path" (list prim_encoding))) - (function Unreachable_entrypoint path -> Some path | _ -> None) - (fun path -> Unreachable_entrypoint path) ; - (* Duplicate entrypoint *) - register_error_kind - `Permanent - ~id:"michelson_v1.duplicate_entrypoint" - ~title:"Duplicate entrypoint (type error)" - ~description:"Two entrypoints have the same name." - (obj1 (req "path" string)) - (function Duplicate_entrypoint entrypoint -> Some entrypoint | _ -> None) - (fun entrypoint -> Duplicate_entrypoint entrypoint) ; - (* Entrypoint name too long *) - register_error_kind - `Permanent - ~id:"michelson_v1.entrypoint_name_too_long" - ~title:"Entrypoint name too long (type error)" - ~description: - "An entrypoint name exceeds the maximum length of 31 characters." - (obj1 (req "name" string)) - (function - | Entrypoint_name_too_long entrypoint -> Some entrypoint | _ -> None) - (fun entrypoint -> Entrypoint_name_too_long entrypoint) ; - (* Unexpected contract *) - register_error_kind - `Permanent - ~id:"michelson_v1.unexpected_contract" - ~title:"Contract in unauthorized position (type error)" - ~description: - "When parsing script, a contract type was found in the storage or \ - parameter field." - (obj1 (req "loc" location_encoding)) - (function Unexpected_contract loc -> Some loc | _ -> None) - (fun loc -> Unexpected_contract loc) ; - (* -- Value typing errors ---------------------- *) - (* Unordered map keys *) - register_error_kind - `Permanent - ~id:"michelson_v1.unordered_map_literal" - ~title:"Invalid map key order" - ~description:"Map keys must be in strictly increasing order" - (obj2 - (req "location" Script.location_encoding) - (req "item" Script.expr_encoding)) - (function Unordered_map_keys (loc, expr) -> Some (loc, expr) | _ -> None) - (fun (loc, expr) -> Unordered_map_keys (loc, expr)) ; - (* Duplicate map keys *) - register_error_kind - `Permanent - ~id:"michelson_v1.duplicate_map_keys" - ~title:"Duplicate map keys" - ~description:"Map literals cannot contain duplicated keys" - (obj2 - (req "location" Script.location_encoding) - (req "item" Script.expr_encoding)) - (function Duplicate_map_keys (loc, expr) -> Some (loc, expr) | _ -> None) - (fun (loc, expr) -> Duplicate_map_keys (loc, expr)) ; - (* Unordered set values *) - register_error_kind - `Permanent - ~id:"michelson_v1.unordered_set_literal" - ~title:"Invalid set value order" - ~description:"Set values must be in strictly increasing order" - (obj2 - (req "location" Script.location_encoding) - (req "value" Script.expr_encoding)) - (function - | Unordered_set_values (loc, expr) -> Some (loc, expr) | _ -> None) - (fun (loc, expr) -> Unordered_set_values (loc, expr)) ; - (* Duplicate set values *) - register_error_kind - `Permanent - ~id:"michelson_v1.duplicate_set_values_in_literal" - ~title:"Sets literals cannot contain duplicate elements" - ~description: - "Set literals cannot contain duplicate elements, but a duplicate was \ - found while parsing." - (obj2 - (req "location" Script.location_encoding) - (req "value" Script.expr_encoding)) - (function - | Duplicate_set_values (loc, expr) -> Some (loc, expr) | _ -> None) - (fun (loc, expr) -> Duplicate_set_values (loc, expr)) ; - (* -- Instruction typing errors ------------- *) - (* Fail not in tail position *) - register_error_kind - `Permanent - ~id:"michelson_v1.fail_not_in_tail_position" - ~title:"FAIL not in tail position" - ~description:"There is non trivial garbage code after a FAIL instruction." - (located empty) - (function Fail_not_in_tail_position loc -> Some (loc, ()) | _ -> None) - (fun (loc, ()) -> Fail_not_in_tail_position loc) ; - (* Undefined binary operation *) - register_error_kind - `Permanent - ~id:"michelson_v1.undefined_binop" - ~title:"Undefined binop" - ~description: - "A binary operation is called on operands of types over which it is not \ - defined." - (located - (obj3 - (req "operator_name" prim_encoding) - (req "wrong_left_operand_type" Script.expr_encoding) - (req "wrong_right_operand_type" Script.expr_encoding))) - (function - | Undefined_binop (loc, n, tyl, tyr) -> Some (loc, (n, tyl, tyr)) - | _ -> None) - (fun (loc, (n, tyl, tyr)) -> Undefined_binop (loc, n, tyl, tyr)) ; - (* Undefined unary operation *) - register_error_kind - `Permanent - ~id:"michelson_v1.undefined_unop" - ~title:"Undefined unop" - ~description: - "A unary operation is called on an operand of type over which it is not \ - defined." - (located - (obj2 - (req "operator_name" prim_encoding) - (req "wrong_operand_type" Script.expr_encoding))) - (function Undefined_unop (loc, n, ty) -> Some (loc, (n, ty)) | _ -> None) - (fun (loc, (n, ty)) -> Undefined_unop (loc, n, ty)) ; - (* Bad return *) - register_error_kind - `Permanent - ~id:"michelson_v1.bad_return" - ~title:"Bad return" - ~description:"Unexpected stack at the end of a lambda or script." - (located - (obj2 - (req "expected_return_type" Script.expr_encoding) - (req "wrong_stack_type" stack_ty_enc))) - (function Bad_return (loc, sty, ty) -> Some (loc, (ty, sty)) | _ -> None) - (fun (loc, (ty, sty)) -> Bad_return (loc, sty, ty)) ; - (* Bad stack *) - register_error_kind - `Permanent - ~id:"michelson_v1.bad_stack" - ~title:"Bad stack" - ~description:"The stack has an unexpected length or contents." - (located - (obj3 - (req "primitive_name" prim_encoding) - (req "relevant_stack_portion" int16) - (req "wrong_stack_type" stack_ty_enc))) - (function - | Bad_stack (loc, name, s, sty) -> Some (loc, (name, s, sty)) | _ -> None) - (fun (loc, (name, s, sty)) -> Bad_stack (loc, name, s, sty)) ; - (* Inconsistent annotations *) - register_error_kind - `Permanent - ~id:"michelson_v1.inconsistent_annotations" - ~title:"Annotations inconsistent between branches" - ~description:"The annotations on two types could not be merged" - (obj2 (req "annot1" string) (req "annot2" string)) - (function - | Inconsistent_annotations (annot1, annot2) -> Some (annot1, annot2) - | _ -> None) - (fun (annot1, annot2) -> Inconsistent_annotations (annot1, annot2)) ; - (* Inconsistent field annotations *) - register_error_kind - `Permanent - ~id:"michelson_v1.inconsistent_field_annotations" - ~title:"Annotations for field accesses is inconsistent" - ~description: - "The specified field does not match the field annotation in the type" - (obj2 (req "annot1" string) (req "annot2" string)) - (function - | Inconsistent_field_annotations (annot1, annot2) -> Some (annot1, annot2) - | _ -> None) - (fun (annot1, annot2) -> Inconsistent_field_annotations (annot1, annot2)) ; - (* Inconsistent type annotations *) - register_error_kind - `Permanent - ~id:"michelson_v1.inconsistent_type_annotations" - ~title:"Types contain inconsistent annotations" - ~description:"The two types contain annotations that do not match" - (located - (obj2 - (req "type1" Script.expr_encoding) - (req "type2" Script.expr_encoding))) - (function - | Inconsistent_type_annotations (loc, ty1, ty2) -> Some (loc, (ty1, ty2)) - | _ -> None) - (fun (loc, (ty1, ty2)) -> Inconsistent_type_annotations (loc, ty1, ty2)) ; - (* Unexpected annotation *) - register_error_kind - `Permanent - ~id:"michelson_v1.unexpected_annotation" - ~title:"An annotation was encountered where no annotation is expected" - ~description:"A node in the syntax tree was improperly annotated" - (located empty) - (function Unexpected_annotation loc -> Some (loc, ()) | _ -> None) - (fun (loc, ()) -> Unexpected_annotation loc) ; - (* Ungrouped annotations *) - register_error_kind - `Permanent - ~id:"michelson_v1.ungrouped_annotations" - ~title:"Annotations of the same kind were found spread apart" - ~description:"Annotations of the same kind must be grouped" - (located empty) - (function Ungrouped_annotations loc -> Some (loc, ()) | _ -> None) - (fun (loc, ()) -> Ungrouped_annotations loc) ; - (* Unmatched branches *) - register_error_kind - `Permanent - ~id:"michelson_v1.unmatched_branches" - ~title:"Unmatched branches" - ~description: - "At the join point at the end of two code branches the stacks have \ - inconsistent lengths or contents." - (located - (obj2 - (req "first_stack_type" stack_ty_enc) - (req "other_stack_type" stack_ty_enc))) - (function - | Unmatched_branches (loc, stya, styb) -> Some (loc, (stya, styb)) - | _ -> None) - (fun (loc, (stya, styb)) -> Unmatched_branches (loc, stya, styb)) ; - (* Bad stack item *) - register_error_kind - `Permanent - ~id:"michelson_v1.bad_stack_item" - ~title:"Bad stack item" - ~description: - "The type of a stack item is unexpected (this error is always \ - accompanied by a more precise one)." - (obj1 (req "item_level" int16)) - (function Bad_stack_item n -> Some n | _ -> None) - (fun n -> Bad_stack_item n) ; - (* SELF in lambda *) - register_error_kind - `Permanent - ~id:"michelson_v1.self_in_lambda" - ~title:"SELF instruction in lambda" - ~description:"A SELF instruction was encountered in a lambda expression." - (located empty) - (function Self_in_lambda loc -> Some (loc, ()) | _ -> None) - (fun (loc, ()) -> Self_in_lambda loc) ; - (* Bad stack length *) - register_error_kind - `Permanent - ~id:"michelson_v1.inconsistent_stack_lengths" - ~title:"Inconsistent stack lengths" - ~description: - "A stack was of an unexpected length (this error is always in the \ - context of a located error)." - empty - (function Bad_stack_length -> Some () | _ -> None) - (fun () -> Bad_stack_length) ; - (* -- Value typing errors ------------------- *) - (* Invalid constant *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_constant" - ~title:"Invalid constant" - ~description:"A data expression was invalid for its expected type." - (located - (obj2 - (req "expected_type" Script.expr_encoding) - (req "wrong_expression" Script.expr_encoding))) - (function - | Invalid_constant (loc, expr, ty) -> Some (loc, (ty, expr)) | _ -> None) - (fun (loc, (ty, expr)) -> Invalid_constant (loc, expr, ty)) ; - (* View name too long *) - register_error_kind - `Permanent - ~id:"michelson_v1.view_name_too_long" - ~title:"View name too long (type error)" - ~description:"A view name exceeds the maximum length of 31 characters." - (obj1 (req "name" string)) - (function View_name_too_long name -> Some name | _ -> None) - (fun name -> View_name_too_long name) ; - (* Duplicated view name *) - register_error_kind - `Permanent - ~id:"michelson_v1.duplicated_view_name" - ~title:"Duplicated view name" - ~description:"The name of view in toplevel should be unique." - (obj1 (req "location" Script.location_encoding)) - (function Duplicated_view_name loc -> Some loc | _ -> None) - (fun loc -> Duplicated_view_name loc) ; - (* Invalid syntactic constant *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_syntactic_constant" - ~title:"Invalid constant (parse error)" - ~description:"A compile-time constant was invalid for its expected form." - (located - (obj2 - (req "expected_form" string) - (req "wrong_expression" Script.expr_encoding))) - (function - | Invalid_syntactic_constant (loc, expr, expected) -> - Some (loc, (expected, expr)) - | _ -> None) - (fun (loc, (expected, expr)) -> - Invalid_syntactic_constant (loc, expr, expected)) ; - (* Invalid contract *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_contract" - ~title:"Invalid contract" - ~description: - "A script or data expression references a contract that does not exist \ - or assumes a wrong type for an existing contract." - (located (obj1 (req "contract" Contract.encoding))) - (function Invalid_contract (loc, c) -> Some (loc, c) | _ -> None) - (fun (loc, c) -> Invalid_contract (loc, c)) ; - (* Invalid big_map *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_big_map" - ~title:"Invalid big_map" - ~description: - "A script or data expression references a big_map that does not exist or \ - assumes a wrong type for an existing big_map." - (located (obj1 (req "big_map" Big_map.Id.encoding))) - (function Invalid_big_map (loc, c) -> Some (loc, c) | _ -> None) - (fun (loc, c) -> Invalid_big_map (loc, c)) ; - (* Comparable type expected *) - register_error_kind - `Permanent - ~id:"michelson_v1.comparable_type_expected" - ~title:"Comparable type expected" - ~description: - "A non comparable type was used in a place where only comparable types \ - are accepted." - (located (obj1 (req "wrong_type" Script.expr_encoding))) - (function - | Comparable_type_expected (loc, ty) -> Some (loc, ty) | _ -> None) - (fun (loc, ty) -> Comparable_type_expected (loc, ty)) ; - (* Inconsistent type sizes *) - register_error_kind - `Permanent - ~id:"michelson_v1.inconsistent_type_sizes" - ~title:"Inconsistent type sizes" - ~description: - "Two types were expected to be equal but they have different sizes." - (obj2 (req "first_type_size" int31) (req "other_type_size" int31)) - (function - | Inconsistent_type_sizes (tya, tyb) -> Some (tya, tyb) | _ -> None) - (fun (tya, tyb) -> Inconsistent_type_sizes (tya, tyb)) ; - (* Inconsistent types *) - register_error_kind - `Permanent - ~id:"michelson_v1.inconsistent_types" - ~title:"Inconsistent types" - ~description: - "This is the basic type clash error, that appears in several places \ - where the equality of two types have to be proven, it is always \ - accompanied with another error that provides more context." - (obj3 - (opt "loc" Script.location_encoding) - (req "first_type" Script.expr_encoding) - (req "other_type" Script.expr_encoding)) - (function - | Inconsistent_types (loc, tya, tyb) -> Some (loc, tya, tyb) | _ -> None) - (fun (loc, tya, tyb) -> Inconsistent_types (loc, tya, tyb)) ; - (* Inconsistent memo_sizes *) - register_error_kind - `Permanent - ~id:"michelson_v1.inconsistent_memo_sizes" - ~title:"Inconsistent memo sizes" - ~description:"Memo sizes of two sapling states or transactions do not match" - (obj2 - (req "first_memo_size" Sapling.Memo_size.encoding) - (req "other_memo_size" Sapling.Memo_size.encoding)) - (function - | Inconsistent_memo_sizes (msa, msb) -> Some (msa, msb) | _ -> None) - (fun (msa, msb) -> Inconsistent_memo_sizes (msa, msb)) ; - (* -- Instruction typing errors ------------------- *) - (* Bad view name *) - register_error_kind - `Permanent - ~id:"michelson_v1.bad_view_name" - ~title:"Bad view name" - ~description:"In a view declaration, the view name must be a string" - (obj1 (req "loc" Script.location_encoding)) - (function Bad_view_name loc -> Some loc | _ -> None) - (fun loc -> Bad_view_name loc) ; - (* Invalid view body *) - register_error_kind - `Permanent - ~id:"michelson_v1.ill_typed_view" - ~title:"Ill typed view" - ~description:"The return of a view block did not match the expected type" - (obj3 - (req "loc" Script.location_encoding) - (req "resulted_view_stack" stack_ty_enc) - (req "expected_view_stack" stack_ty_enc)) - (function - | Ill_typed_view {loc; actual; expected} -> Some (loc, actual, expected) - | _ -> None) - (fun (loc, actual, expected) -> Ill_typed_view {loc; actual; expected}) ; - (* Invalid map body *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_map_body" - ~title:"Invalid map body" - ~description:"The body of a map block did not match the expected type" - (obj2 (req "loc" Script.location_encoding) (req "body_type" stack_ty_enc)) - (function Invalid_map_body (loc, stack) -> Some (loc, stack) | _ -> None) - (fun (loc, stack) -> Invalid_map_body (loc, stack)) ; - (* Invalid map block FAIL *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_map_block_fail" - ~title:"FAIL instruction occurred as body of map block" - ~description: - "FAIL cannot be the only instruction in the body. The proper type of the \ - return list cannot be inferred." - (obj1 (req "loc" Script.location_encoding)) - (function Invalid_map_block_fail loc -> Some loc | _ -> None) - (fun loc -> Invalid_map_block_fail loc) ; - (* Invalid ITER body *) - register_error_kind - `Permanent - ~id:"michelson_v1.invalid_iter_body" - ~title:"ITER body returned wrong stack type" - ~description: - "The body of an ITER instruction must result in the same stack type as \ - before the ITER." - (obj3 - (req "loc" Script.location_encoding) - (req "bef_stack" stack_ty_enc) - (req "aft_stack" stack_ty_enc)) - (function - | Invalid_iter_body (loc, bef, aft) -> Some (loc, bef, aft) | _ -> None) - (fun (loc, bef, aft) -> Invalid_iter_body (loc, bef, aft)) ; - (* Type too large *) - register_error_kind - `Permanent - ~id:"michelson_v1.type_too_large" - ~title:"Stack item type too large" - ~description:"An instruction generated a type larger than the limit." - (obj2 (req "loc" Script.location_encoding) (req "maximum_type_size" uint16)) - (function Type_too_large (loc, maxts) -> Some (loc, maxts) | _ -> None) - (fun (loc, maxts) -> Type_too_large (loc, maxts)) ; - (* Bad PAIR argument *) - register_error_kind - `Permanent - ~id:"michelson_v1.bad_pair_argument" - ~title:"0 or 1 passed to PAIR" - ~description:"PAIR expects an argument of at least 2" - (obj1 (req "loc" Script.location_encoding)) - (function Pair_bad_argument loc -> Some loc | _ -> None) - (fun loc -> Pair_bad_argument loc) ; - (* Bad UNPAIR argument *) - register_error_kind - `Permanent - ~id:"michelson_v1.bad_unpair_argument" - ~title:"0 or 1 passed to UNPAIR" - ~description:"UNPAIR expects an argument of at least 2" - (obj1 (req "loc" Script.location_encoding)) - (function Unpair_bad_argument loc -> Some loc | _ -> None) - (fun loc -> Unpair_bad_argument loc) ; - (* Bad dup_n argument *) - register_error_kind - `Permanent - ~id:"michelson_v1.bad_dupn_argument" - ~title:"0 passed to DUP n" - ~description:"DUP expects an argument of at least 1 (passed 0)" - (obj1 (req "loc" Script.location_encoding)) - (function Dup_n_bad_argument loc -> Some loc | _ -> None) - (fun loc -> Dup_n_bad_argument loc) ; - (* Bad dup_n stack *) - register_error_kind - `Permanent - ~id:"michelson_v1.bad_dupn_stack" - ~title:"Stack too short when typing DUP n" - ~description:"Stack present when typing DUP n was too short" - (obj1 (req "loc" Script.location_encoding)) - (function Dup_n_bad_stack x -> Some x | _ -> None) - (fun x -> Dup_n_bad_stack x) ; - (* -- Toplevel errors ------------------- *) - (* Ill typed data *) - register_error_kind - `Permanent - ~id:"michelson_v1.ill_typed_data" - ~title:"Ill typed data" - ~description: - "The toplevel error thrown when trying to typecheck a data expression \ - against a given type (always followed by more precise errors)." - (obj3 - (opt "identifier" string) - (req "expected_type" Script.expr_encoding) - (req "ill_typed_expression" Script.expr_encoding)) - (function - | Ill_typed_data (name, expr, ty) -> Some (name, ty, expr) | _ -> None) - (fun (name, ty, expr) -> Ill_typed_data (name, expr, ty)) ; - (* Ill formed type *) - register_error_kind - `Permanent - ~id:"michelson_v1.ill_formed_type" - ~title:"Ill formed type" - ~description: - "The toplevel error thrown when trying to parse a type expression \ - (always followed by more precise errors)." - (obj3 - (opt "identifier" string) - (req "ill_formed_expression" Script.expr_encoding) - (req "location" Script.location_encoding)) - (function - | Ill_formed_type (name, expr, loc) -> Some (name, expr, loc) | _ -> None) - (fun (name, expr, loc) -> Ill_formed_type (name, expr, loc)) ; - (* Ill typed contract *) - register_error_kind - `Permanent - ~id:"michelson_v1.ill_typed_contract" - ~title:"Ill typed contract" - ~description: - "The toplevel error thrown when trying to typecheck a contract code \ - against given input, output and storage types (always followed by more \ - precise errors)." - (obj2 - (req "ill_typed_code" Script.expr_encoding) - (req "type_map" type_map_enc)) - (function - | Ill_typed_contract (expr, type_map) -> Some (expr, type_map) | _ -> None) - (fun (expr, type_map) -> Ill_typed_contract (expr, type_map)) ; - (* Deprecated instruction *) - register_error_kind - `Permanent - ~id:"michelson_v1.deprecated_instruction" - ~title:"Script is using a deprecated instruction" - ~description: - "A deprecated instruction usage is disallowed in newly created contracts" - (obj1 (req "prim" prim_encoding)) - (function Deprecated_instruction prim -> Some prim | _ -> None) - (fun prim -> Deprecated_instruction prim) ; - (* Typechecking stack overflow *) - register_error_kind - `Temporary - ~id:"michelson_v1.typechecking_too_many_recursive_calls" - ~title:"Too many recursive calls during typechecking" - ~description:"Too many recursive calls were needed for typechecking" - Data_encoding.empty - (function Typechecking_too_many_recursive_calls -> Some () | _ -> None) - (fun () -> Typechecking_too_many_recursive_calls) ; - (* Unparsing stack overflow *) - register_error_kind - `Temporary - ~id:"michelson_v1.unparsing_stack_overflow" - ~title:"Too many recursive calls during unparsing" - ~description:"Too many recursive calls were needed for unparsing" - Data_encoding.empty - (function Unparsing_too_many_recursive_calls -> Some () | _ -> None) - (fun () -> Unparsing_too_many_recursive_calls) ; - (* Unexpected forged value *) - register_error_kind - `Permanent - ~id:"michelson_v1.unexpected_forged_value" - ~title:"Unexpected forged value" - ~description: - "A forged value was encountered but disallowed for that position." - (obj1 (req "location" Script.location_encoding)) - (function Unexpected_forged_value loc -> Some loc | _ -> None) - (fun loc -> Unexpected_forged_value loc) ; - (* Unexpected ticket *) - register_error_kind - `Permanent - ~id:"michelson_v1.unexpected_ticket" - ~title:"Ticket in unauthorized position (type error)" - ~description:"A ticket type has been found" - (obj1 (req "loc" location_encoding)) - (function Unexpected_ticket loc -> Some loc | _ -> None) - (fun loc -> Unexpected_ticket loc) ; - (* Attempt to duplicate a non-dupable type *) - register_error_kind - `Permanent - ~id:"michelson_v1.non_dupable_type" - ~title:"Non-dupable type duplication attempt" - ~description:"DUP was used on a non-dupable type (e.g. tickets)." - (obj2 (req "loc" location_encoding) (req "type" Script.expr_encoding)) - (function Non_dupable_type (loc, ty) -> Some (loc, ty) | _ -> None) - (fun (loc, ty) -> Non_dupable_type (loc, ty)) diff --git a/src/proto_012_Psithaca/lib_protocol/script_tc_errors_registration.mli b/src/proto_012_Psithaca/lib_protocol/script_tc_errors_registration.mli deleted file mode 100644 index c8dd34c2e0bd..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_tc_errors_registration.mli +++ /dev/null @@ -1,34 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Script - -val type_map_enc : - (location * ((expr * string list) list * (expr * string list) list)) list - Data_encoding.encoding - -val stack_ty_enc : (expr * string list) list Data_encoding.encoding diff --git a/src/proto_012_Psithaca/lib_protocol/script_timestamp_repr.ml b/src/proto_012_Psithaca/lib_protocol/script_timestamp_repr.ml deleted file mode 100644 index 22b51a4945f0..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_timestamp_repr.ml +++ /dev/null @@ -1,55 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t = Z.t - -let compare = Z.compare - -let of_int64 = Z.of_int64 - -let of_string x = - match Time_repr.of_notation x with - | None -> Option.catch (fun () -> Z.of_string x) - | Some time -> Some (of_int64 (Time_repr.to_seconds time)) - -let to_notation x = - Option.catch (fun () -> - Time_repr.to_notation (Time.of_seconds (Z.to_int64 x))) - -let to_num_str = Z.to_string - -let to_string x = match to_notation x with None -> to_num_str x | Some s -> s - -let diff x y = Script_int_repr.of_zint @@ Z.sub x y - -let sub_delta t delta = Z.sub t (Script_int_repr.to_zint delta) - -let add_delta t delta = Z.add t (Script_int_repr.to_zint delta) - -let to_zint x = x - -let of_zint x = x - -let encoding : t Data_encoding.encoding = Data_encoding.z diff --git a/src/proto_012_Psithaca/lib_protocol/script_timestamp_repr.mli b/src/proto_012_Psithaca/lib_protocol/script_timestamp_repr.mli deleted file mode 100644 index 2e628dae2991..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_timestamp_repr.mli +++ /dev/null @@ -1,68 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Defines the internal Michelson representation for timestamps and basic - operations that can be performed on it. *) - -open Script_int_repr - -(** Representation of timestamps specific to the Michelson interpreter. - A number of seconds since the epoch. *) -type t - -(** Convert a number of seconds since the epoch to a timestamp.*) -val of_int64 : int64 -> t - -(** Compare timestamps. Returns [1] if the first timestamp is later than the - second one; [0] if they're equal and [-1] othwerwise. *) -val compare : t -> t -> int - -(** Convert a timestamp to RFC3339 notation if possible **) -val to_notation : t -> string option - -(** Convert a timestamp to a string representation of the seconds *) -val to_num_str : t -> string - -(** Convert to RFC3339 notation if possible, or num if not *) -val to_string : t -> string - -val of_string : string -> t option - -(** Returns difference between timestamps as integral number of seconds - in Michelson representation of numbers. *) -val diff : t -> t -> z num - -(** Add a number of seconds to the timestamp. *) -val add_delta : t -> z num -> t - -(** Subtract a number of seconds from the timestamp. *) -val sub_delta : t -> z num -> t - -val to_zint : t -> Z.t - -val of_zint : Z.t -> t - -(* Timestamps are encoded exactly as Z. *) -val encoding : t Data_encoding.encoding diff --git a/src/proto_012_Psithaca/lib_protocol/script_typed_ir.ml b/src/proto_012_Psithaca/lib_protocol/script_typed_ir.ml deleted file mode 100644 index 9b990909ca57..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_typed_ir.ml +++ /dev/null @@ -1,2201 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Script_int -open Script_ir_annot - -(* - - The step function of the interpreter is parametrized by a bunch of values called the step constants. - These values are indeed constants during the call of a smart contract with the notable exception of - the IView instruction which modifies `source`, `self`, and `amount` and the KView_exit continuation - which restores them. - ====================== - -*) -type step_constants = { - source : Contract.t; - (** The address calling this contract, as returned by SENDER. *) - payer : Contract.t; - (** The address of the implicit account that initiated the chain of contract calls, as returned by SOURCE. *) - self : Contract.t; - (** The address of the contract being executed, as returned by SELF and SELF_ADDRESS. - Also used: - - as ticketer in TICKET - - as caller in VIEW, TRANSFER_TOKENS, and CREATE_CONTRACT *) - amount : Tez.t; - (** The amount of the current transaction, as returned by AMOUNT. *) - chain_id : Chain_id.t; - (** The chain id of the chain, as returned by CHAIN_ID. *) - now : Script_timestamp.t; - (** The earliest time at which the current block could have been timestamped, as returned by NOW. *) - level : Script_int.n Script_int.num; - (** The level of the current block, as returned by LEVEL. *) -} - -(* Preliminary definitions. *) - -type never = | - -type address = Contract.t * string - -type ('a, 'b) pair = 'a * 'b - -type ('a, 'b) union = L of 'a | R of 'b - -type operation = packed_internal_operation * Lazy_storage.diffs option - -type 'a ticket = {ticketer : Contract.t; contents : 'a; amount : n num} - -module type TYPE_SIZE = sig - (* A type size represents the size of its type parameter. - This constraint is enforced inside this module (Script_type_ir), hence there - should be no way to construct a type size outside of it. - - It allows keeping type metadata and types non-private. - - This module is here because we want three levels of visibility over this - code: - - inside this submodule, we have [type 'a t = int] - - outside of [Script_typed_ir], the ['a t] type is abstract and we have - the invariant that whenever [x : 'a t] we have that [x] is exactly - the size of ['a]. - - in-between (inside [Script_typed_ir] but outside the [Type_size] - submodule), the type is abstract but we have access to unsafe - constructors that can break the invariant. - *) - type 'a t - - val merge : 'a t -> 'b t -> 'a t tzresult - - val to_int : 'a t -> Saturation_repr.mul_safe Saturation_repr.t - - (* Unsafe constructors, to be used only safely and inside this module *) - - val one : _ t - - val two : _ t - - val three : _ t - - val four : (_, _) pair option t - - val compound1 : Script.location -> _ t -> _ t tzresult - - val compound2 : Script.location -> _ t -> _ t -> _ t tzresult -end - -module Type_size : TYPE_SIZE = struct - type 'a t = int - - let () = - (* static-like check that all [t] values fit in a [mul_safe] *) - let (_ : Saturation_repr.mul_safe Saturation_repr.t) = - Saturation_repr.mul_safe_of_int_exn Constants.michelson_maximum_type_size - in - () - - let to_int = Saturation_repr.mul_safe_of_int_exn - - let one = 1 - - let two = 2 - - let three = 3 - - let four = 4 - - let merge x y = - if Compare.Int.(x = y) then ok x - else error @@ Script_tc_errors.Inconsistent_type_sizes (x, y) - - let of_int loc size = - let max_size = Constants.michelson_maximum_type_size in - if Compare.Int.(size <= max_size) then ok size - else error (Script_tc_errors.Type_too_large (loc, max_size)) - - let compound1 loc size = of_int loc (1 + size) - - let compound2 loc size1 size2 = of_int loc (1 + size1 + size2) -end - -type empty_cell = EmptyCell - -type end_of_stack = empty_cell * empty_cell - -type 'a ty_metadata = {annot : type_annot option; size : 'a Type_size.t} - -type _ comparable_ty = - | Unit_key : unit ty_metadata -> unit comparable_ty - | Never_key : never ty_metadata -> never comparable_ty - | Int_key : z num ty_metadata -> z num comparable_ty - | Nat_key : n num ty_metadata -> n num comparable_ty - | Signature_key : signature ty_metadata -> signature comparable_ty - | String_key : Script_string.t ty_metadata -> Script_string.t comparable_ty - | Bytes_key : Bytes.t ty_metadata -> Bytes.t comparable_ty - | Mutez_key : Tez.t ty_metadata -> Tez.t comparable_ty - | Bool_key : bool ty_metadata -> bool comparable_ty - | Key_hash_key : public_key_hash ty_metadata -> public_key_hash comparable_ty - | Key_key : public_key ty_metadata -> public_key comparable_ty - | Timestamp_key : - Script_timestamp.t ty_metadata - -> Script_timestamp.t comparable_ty - | Chain_id_key : Chain_id.t ty_metadata -> Chain_id.t comparable_ty - | Address_key : address ty_metadata -> address comparable_ty - | Pair_key : - ('a comparable_ty * field_annot option) - * ('b comparable_ty * field_annot option) - * ('a, 'b) pair ty_metadata - -> ('a, 'b) pair comparable_ty - | Union_key : - ('a comparable_ty * field_annot option) - * ('b comparable_ty * field_annot option) - * ('a, 'b) union ty_metadata - -> ('a, 'b) union comparable_ty - | Option_key : - 'v comparable_ty * 'v option ty_metadata - -> 'v option comparable_ty - -let comparable_ty_metadata : type a. a comparable_ty -> a ty_metadata = function - | Unit_key meta -> meta - | Never_key meta -> meta - | Int_key meta -> meta - | Nat_key meta -> meta - | Signature_key meta -> meta - | String_key meta -> meta - | Bytes_key meta -> meta - | Mutez_key meta -> meta - | Bool_key meta -> meta - | Key_hash_key meta -> meta - | Key_key meta -> meta - | Timestamp_key meta -> meta - | Chain_id_key meta -> meta - | Address_key meta -> meta - | Pair_key (_, _, meta) -> meta - | Union_key (_, _, meta) -> meta - | Option_key (_, meta) -> meta - -let comparable_ty_size t = (comparable_ty_metadata t).size - -let unit_key ~annot = Unit_key {annot; size = Type_size.one} - -let never_key ~annot = Never_key {annot; size = Type_size.one} - -let int_key ~annot = Int_key {annot; size = Type_size.one} - -let nat_key ~annot = Nat_key {annot; size = Type_size.one} - -let signature_key ~annot = Signature_key {annot; size = Type_size.one} - -let string_key ~annot = String_key {annot; size = Type_size.one} - -let bytes_key ~annot = Bytes_key {annot; size = Type_size.one} - -let mutez_key ~annot = Mutez_key {annot; size = Type_size.one} - -let bool_key ~annot = Bool_key {annot; size = Type_size.one} - -let key_hash_key ~annot = Key_hash_key {annot; size = Type_size.one} - -let key_key ~annot = Key_key {annot; size = Type_size.one} - -let timestamp_key ~annot = Timestamp_key {annot; size = Type_size.one} - -let chain_id_key ~annot = Chain_id_key {annot; size = Type_size.one} - -let address_key ~annot = Address_key {annot; size = Type_size.one} - -let pair_key loc (l, fannot_l) (r, fannot_r) ~annot = - Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) - >|? fun size -> Pair_key ((l, fannot_l), (r, fannot_r), {annot; size}) - -let pair_3_key loc l m r = - pair_key loc m r ~annot:None >>? fun r -> pair_key loc l (r, None) ~annot:None - -let union_key loc (l, fannot_l) (r, fannot_r) ~annot = - Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) - >|? fun size -> Union_key ((l, fannot_l), (r, fannot_r), {annot; size}) - -let option_key loc t ~annot = - Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> - Option_key (t, {annot; size}) - -(* - - This signature contains the exact set of functions used in the - protocol. We do not include all [Set.S] because this would - increase the size of the first class modules used to represent - [boxed_set]. - - Warning: for any change in this signature, there must be a - change in [Script_typed_ir_size.value_size] which updates - [boxing_space] in the case for sets. - -*) -module type Boxed_set_OPS = sig - type t - - type elt - - val empty : t - - val add : elt -> t -> t - - val mem : elt -> t -> bool - - val remove : elt -> t -> t - - val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a -end - -module type Boxed_set = sig - type elt - - val elt_ty : elt comparable_ty - - module OPS : Boxed_set_OPS with type elt = elt - - val boxed : OPS.t - - val size : int -end - -type 'elt set = (module Boxed_set with type elt = 'elt) - -(* - - Same remark as for [Boxed_set_OPS]. (See below.) - -*) -module type Boxed_map_OPS = sig - type t - - type key - - type value - - val empty : t - - val add : key -> value -> t -> t - - val remove : key -> t -> t - - val find : key -> t -> value option - - val fold : (key -> value -> 'a -> 'a) -> t -> 'a -> 'a -end - -module type Boxed_map = sig - type key - - type value - - val key_ty : key comparable_ty - - module OPS : Boxed_map_OPS with type key = key and type value = value - - val boxed : OPS.t - - val size : int -end - -type ('key, 'value) map = - (module Boxed_map with type key = 'key and type value = 'value) - -module Big_map_overlay = Map.Make (struct - type t = Script_expr_hash.t - - let compare = Script_expr_hash.compare -end) - -type ('key, 'value) big_map_overlay = { - map : ('key * 'value option) Big_map_overlay.t; - size : int; -} - -type 'elt boxed_list = {elements : 'elt list; length : int} - -module SMap = Map.Make (Script_string) - -type view = { - input_ty : Script.node; - output_ty : Script.node; - view_code : Script.node; -} - -type ('arg, 'storage) script = { - code : (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; - arg_type : 'arg ty; - storage : 'storage; - storage_type : 'storage ty; - views : view SMap.t; - root_name : field_annot option; - code_size : Cache_memory_helpers.sint; - (* This is an over-approximation of the value size in memory, in - bytes, of the contract's static part, that is its source - code. This includes the code of the contract as well as the code - of the views. The storage size is not taken into account by this - field as it has a dynamic size. *) -} - -(* ---- Instructions --------------------------------------------------------*) -and ('before_top, 'before, 'result_top, 'result) kinstr = - (* - Stack - ----- - *) - | IDrop : - ('a, 'b * 's) kinfo * ('b, 's, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IDup : - ('a, 's) kinfo * ('a, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISwap : - ('a, 'b * 's) kinfo * ('b, 'a * 's, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IConst : - ('a, 's) kinfo * 'ty * ('ty, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - (* - Pairs - ----- - *) - | ICons_pair : - ('a, 'b * 's) kinfo * ('a * 'b, 's, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | ICar : - ('a * 'b, 's) kinfo * ('a, 's, 'r, 'f) kinstr - -> ('a * 'b, 's, 'r, 'f) kinstr - | ICdr : - ('a * 'b, 's) kinfo * ('b, 's, 'r, 'f) kinstr - -> ('a * 'b, 's, 'r, 'f) kinstr - | IUnpair : - ('a * 'b, 's) kinfo * ('a, 'b * 's, 'r, 'f) kinstr - -> ('a * 'b, 's, 'r, 'f) kinstr - (* - Options - ------- - *) - | ICons_some : - ('v, 's) kinfo * ('v option, 's, 'r, 'f) kinstr - -> ('v, 's, 'r, 'f) kinstr - | ICons_none : - ('a, 's) kinfo * ('b option, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IIf_none : { - kinfo : ('a option, 'b * 's) kinfo; - branch_if_none : ('b, 's, 'c, 't) kinstr; - branch_if_some : ('a, 'b * 's, 'c, 't) kinstr; - k : ('c, 't, 'r, 'f) kinstr; - } - -> ('a option, 'b * 's, 'r, 'f) kinstr - | IOpt_map : { - kinfo : ('a option, 's) kinfo; - body : ('a, 's, 'b, 's) kinstr; - k : ('b option, 's, 'c, 't) kinstr; - } - -> ('a option, 's, 'c, 't) kinstr - (* - Unions - ------ - *) - | ICons_left : - ('a, 's) kinfo * (('a, 'b) union, 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ICons_right : - ('b, 's) kinfo * (('a, 'b) union, 's, 'r, 'f) kinstr - -> ('b, 's, 'r, 'f) kinstr - | IIf_left : { - kinfo : (('a, 'b) union, 's) kinfo; - branch_if_left : ('a, 's, 'c, 't) kinstr; - branch_if_right : ('b, 's, 'c, 't) kinstr; - k : ('c, 't, 'r, 'f) kinstr; - } - -> (('a, 'b) union, 's, 'r, 'f) kinstr - (* - Lists - ----- - *) - | ICons_list : - ('a, 'a boxed_list * 's) kinfo * ('a boxed_list, 's, 'r, 'f) kinstr - -> ('a, 'a boxed_list * 's, 'r, 'f) kinstr - | INil : - ('a, 's) kinfo * ('b boxed_list, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IIf_cons : { - kinfo : ('a boxed_list, 'b * 's) kinfo; - branch_if_cons : ('a, 'a boxed_list * ('b * 's), 'c, 't) kinstr; - branch_if_nil : ('b, 's, 'c, 't) kinstr; - k : ('c, 't, 'r, 'f) kinstr; - } - -> ('a boxed_list, 'b * 's, 'r, 'f) kinstr - | IList_map : - ('a boxed_list, 'c * 's) kinfo - * ('a, 'c * 's, 'b, 'c * 's) kinstr - * ('b boxed_list, 'c * 's, 'r, 'f) kinstr - -> ('a boxed_list, 'c * 's, 'r, 'f) kinstr - | IList_iter : - ('a boxed_list, 'b * 's) kinfo - * ('a, 'b * 's, 'b, 's) kinstr - * ('b, 's, 'r, 'f) kinstr - -> ('a boxed_list, 'b * 's, 'r, 'f) kinstr - | IList_size : - ('a boxed_list, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> ('a boxed_list, 's, 'r, 'f) kinstr - (* - Sets - ---- - *) - | IEmpty_set : - ('a, 's) kinfo * 'b comparable_ty * ('b set, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISet_iter : - ('a set, 'b * 's) kinfo - * ('a, 'b * 's, 'b, 's) kinstr - * ('b, 's, 'r, 'f) kinstr - -> ('a set, 'b * 's, 'r, 'f) kinstr - | ISet_mem : - ('a, 'a set * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> ('a, 'a set * 's, 'r, 'f) kinstr - | ISet_update : - ('a, bool * ('a set * 's)) kinfo * ('a set, 's, 'r, 'f) kinstr - -> ('a, bool * ('a set * 's), 'r, 'f) kinstr - | ISet_size : - ('a set, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> ('a set, 's, 'r, 'f) kinstr - (* - Maps - ---- - *) - | IEmpty_map : - ('a, 's) kinfo * 'b comparable_ty * (('b, 'c) map, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IMap_map : - (('a, 'b) map, 'd * 's) kinfo - * ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr - * (('a, 'c) map, 'd * 's, 'r, 'f) kinstr - -> (('a, 'b) map, 'd * 's, 'r, 'f) kinstr - | IMap_iter : - (('a, 'b) map, 'c * 's) kinfo - * ('a * 'b, 'c * 's, 'c, 's) kinstr - * ('c, 's, 'r, 'f) kinstr - -> (('a, 'b) map, 'c * 's, 'r, 'f) kinstr - | IMap_mem : - ('a, ('a, 'b) map * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) map * 's, 'r, 'f) kinstr - | IMap_get : - ('a, ('a, 'b) map * 's) kinfo * ('b option, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) map * 's, 'r, 'f) kinstr - | IMap_update : - ('a, 'b option * (('a, 'b) map * 's)) kinfo - * (('a, 'b) map, 's, 'r, 'f) kinstr - -> ('a, 'b option * (('a, 'b) map * 's), 'r, 'f) kinstr - | IMap_get_and_update : - ('a, 'b option * (('a, 'b) map * 's)) kinfo - * ('b option, ('a, 'b) map * 's, 'r, 'f) kinstr - -> ('a, 'b option * (('a, 'b) map * 's), 'r, 'f) kinstr - | IMap_size : - (('a, 'b) map, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (('a, 'b) map, 's, 'r, 'f) kinstr - (* - Big maps - -------- - *) - | IEmpty_big_map : - ('a, 's) kinfo - * 'b comparable_ty - * 'c ty - * (('b, 'c) big_map, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IBig_map_mem : - ('a, ('a, 'b) big_map * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) big_map * 's, 'r, 'f) kinstr - | IBig_map_get : - ('a, ('a, 'b) big_map * 's) kinfo * ('b option, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) big_map * 's, 'r, 'f) kinstr - | IBig_map_update : - ('a, 'b option * (('a, 'b) big_map * 's)) kinfo - * (('a, 'b) big_map, 's, 'r, 'f) kinstr - -> ('a, 'b option * (('a, 'b) big_map * 's), 'r, 'f) kinstr - | IBig_map_get_and_update : - ('a, 'b option * (('a, 'b) big_map * 's)) kinfo - * ('b option, ('a, 'b) big_map * 's, 'r, 'f) kinstr - -> ('a, 'b option * (('a, 'b) big_map * 's), 'r, 'f) kinstr - (* - Strings - ------- - *) - | IConcat_string : - (Script_string.t boxed_list, 's) kinfo - * (Script_string.t, 's, 'r, 'f) kinstr - -> (Script_string.t boxed_list, 's, 'r, 'f) kinstr - | IConcat_string_pair : - (Script_string.t, Script_string.t * 's) kinfo - * (Script_string.t, 's, 'r, 'f) kinstr - -> (Script_string.t, Script_string.t * 's, 'r, 'f) kinstr - | ISlice_string : - (n num, n num * (Script_string.t * 's)) kinfo - * (Script_string.t option, 's, 'r, 'f) kinstr - -> (n num, n num * (Script_string.t * 's), 'r, 'f) kinstr - | IString_size : - (Script_string.t, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (Script_string.t, 's, 'r, 'f) kinstr - (* - Bytes - ----- - *) - | IConcat_bytes : - (bytes boxed_list, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes boxed_list, 's, 'r, 'f) kinstr - | IConcat_bytes_pair : - (bytes, bytes * 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, bytes * 's, 'r, 'f) kinstr - | ISlice_bytes : - (n num, n num * (bytes * 's)) kinfo * (bytes option, 's, 'r, 'f) kinstr - -> (n num, n num * (bytes * 's), 'r, 'f) kinstr - | IBytes_size : - (bytes, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - (* - Timestamps - ---------- - *) - | IAdd_seconds_to_timestamp : - (z num, Script_timestamp.t * 's) kinfo - * (Script_timestamp.t, 's, 'r, 'f) kinstr - -> (z num, Script_timestamp.t * 's, 'r, 'f) kinstr - | IAdd_timestamp_to_seconds : - (Script_timestamp.t, z num * 's) kinfo - * (Script_timestamp.t, 's, 'r, 'f) kinstr - -> (Script_timestamp.t, z num * 's, 'r, 'f) kinstr - | ISub_timestamp_seconds : - (Script_timestamp.t, z num * 's) kinfo - * (Script_timestamp.t, 's, 'r, 'f) kinstr - -> (Script_timestamp.t, z num * 's, 'r, 'f) kinstr - | IDiff_timestamps : - (Script_timestamp.t, Script_timestamp.t * 's) kinfo - * (z num, 's, 'r, 'f) kinstr - -> (Script_timestamp.t, Script_timestamp.t * 's, 'r, 'f) kinstr - (* - Tez - --- - *) - | IAdd_tez : - (Tez.t, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr - -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr - | ISub_tez : - (Tez.t, Tez.t * 's) kinfo * (Tez.t option, 's, 'r, 'f) kinstr - -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr - | ISub_tez_legacy : - (Tez.t, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr - -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr - | IMul_teznat : - (Tez.t, n num * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr - -> (Tez.t, n num * 's, 'r, 'f) kinstr - | IMul_nattez : - (n num, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr - -> (n num, Tez.t * 's, 'r, 'f) kinstr - | IEdiv_teznat : - (Tez.t, n num * 's) kinfo - * ((Tez.t, Tez.t) pair option, 's, 'r, 'f) kinstr - -> (Tez.t, n num * 's, 'r, 'f) kinstr - | IEdiv_tez : - (Tez.t, Tez.t * 's) kinfo - * ((n num, Tez.t) pair option, 's, 'r, 'f) kinstr - -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr - (* - Booleans - -------- - *) - | IOr : - (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (bool, bool * 's, 'r, 'f) kinstr - | IAnd : - (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (bool, bool * 's, 'r, 'f) kinstr - | IXor : - (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (bool, bool * 's, 'r, 'f) kinstr - | INot : - (bool, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (bool, 's, 'r, 'f) kinstr - (* - Integers - -------- - *) - | IIs_nat : - (z num, 's) kinfo * (n num option, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | INeg : - ('a num, 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 's, 'r, 'f) kinstr - | IAbs_int : - (z num, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | IInt_nat : - (n num, 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> (n num, 's, 'r, 'f) kinstr - | IAdd_int : - ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 'b num * 's, 'r, 'f) kinstr - | IAdd_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | ISub_int : - ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 'b num * 's, 'r, 'f) kinstr - | IMul_int : - ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 'b num * 's, 'r, 'f) kinstr - | IMul_nat : - (n num, 'a num * 's) kinfo * ('a num, 's, 'r, 'f) kinstr - -> (n num, 'a num * 's, 'r, 'f) kinstr - | IEdiv_int : - ('a num, 'b num * 's) kinfo - * ((z num, n num) pair option, 's, 'r, 'f) kinstr - -> ('a num, 'b num * 's, 'r, 'f) kinstr - | IEdiv_nat : - (n num, 'a num * 's) kinfo - * (('a num, n num) pair option, 's, 'r, 'f) kinstr - -> (n num, 'a num * 's, 'r, 'f) kinstr - | ILsl_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | ILsr_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | IOr_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - (* Even though `IAnd_nat` and `IAnd_int_nat` could be merged into a single - instruction from both the type and behavior point of views, their gas costs - differ too much (see `cost_N_IAnd_nat` and `cost_N_IAnd_int_nat` in - `Michelson_v1_gas.Cost_of.Generated_costs`), so we keep them separated. *) - | IAnd_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | IAnd_int_nat : - (z num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (z num, n num * 's, 'r, 'f) kinstr - | IXor_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | INot_int : - ('a num, 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 's, 'r, 'f) kinstr - (* - Control - ------- - *) - | IIf : { - kinfo : (bool, 'a * 's) kinfo; - branch_if_true : ('a, 's, 'b, 'u) kinstr; - branch_if_false : ('a, 's, 'b, 'u) kinstr; - k : ('b, 'u, 'r, 'f) kinstr; - } - -> (bool, 'a * 's, 'r, 'f) kinstr - | ILoop : - (bool, 'a * 's) kinfo - * ('a, 's, bool, 'a * 's) kinstr - * ('a, 's, 'r, 'f) kinstr - -> (bool, 'a * 's, 'r, 'f) kinstr - | ILoop_left : - (('a, 'b) union, 's) kinfo - * ('a, 's, ('a, 'b) union, 's) kinstr - * ('b, 's, 'r, 'f) kinstr - -> (('a, 'b) union, 's, 'r, 'f) kinstr - | IDip : - ('a, 'b * 's) kinfo - * ('b, 's, 'c, 't) kinstr - * ('a, 'c * 't, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IExec : - ('a, ('a, 'b) lambda * 's) kinfo * ('b, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) lambda * 's, 'r, 'f) kinstr - | IApply : - ('a, ('a * 'b, 'c) lambda * 's) kinfo - * 'a ty - * (('b, 'c) lambda, 's, 'r, 'f) kinstr - -> ('a, ('a * 'b, 'c) lambda * 's, 'r, 'f) kinstr - | ILambda : - ('a, 's) kinfo - * ('b, 'c) lambda - * (('b, 'c) lambda, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IFailwith : - ('a, 's) kinfo * Script.location * 'a ty - -> ('a, 's, 'r, 'f) kinstr - (* - Comparison - ---------- - *) - | ICompare : - ('a, 'a * 's) kinfo * 'a comparable_ty * (z num, 's, 'r, 'f) kinstr - -> ('a, 'a * 's, 'r, 'f) kinstr - (* - Comparators - ----------- - *) - | IEq : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | INeq : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | ILt : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | IGt : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | ILe : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | IGe : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - (* - Protocol - -------- - *) - | IAddress : - ('a typed_contract, 's) kinfo * (address, 's, 'r, 'f) kinstr - -> ('a typed_contract, 's, 'r, 'f) kinstr - | IContract : - (address, 's) kinfo - * 'a ty - * string - * ('a typed_contract option, 's, 'r, 'f) kinstr - -> (address, 's, 'r, 'f) kinstr - | IView : - ('a, address * 's) kinfo - * ('a, 'b) view_signature - * ('b option, 's, 'r, 'f) kinstr - -> ('a, address * 's, 'r, 'f) kinstr - | ITransfer_tokens : - ('a, Tez.t * ('a typed_contract * 's)) kinfo - * (operation, 's, 'r, 'f) kinstr - -> ('a, Tez.t * ('a typed_contract * 's), 'r, 'f) kinstr - | IImplicit_account : - (public_key_hash, 's) kinfo * (unit typed_contract, 's, 'r, 'f) kinstr - -> (public_key_hash, 's, 'r, 'f) kinstr - | ICreate_contract : { - kinfo : (public_key_hash option, Tez.t * ('a * 's)) kinfo; - storage_type : 'a ty; - arg_type : 'b ty; - lambda : ('b * 'a, operation boxed_list * 'a) lambda; - views : view SMap.t; - root_name : field_annot option; - k : (operation, address * 's, 'r, 'f) kinstr; - } - -> (public_key_hash option, Tez.t * ('a * 's), 'r, 'f) kinstr - | ISet_delegate : - (public_key_hash option, 's) kinfo * (operation, 's, 'r, 'f) kinstr - -> (public_key_hash option, 's, 'r, 'f) kinstr - | INow : - ('a, 's) kinfo * (Script_timestamp.t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IBalance : - ('a, 's) kinfo * (Tez.t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ILevel : - ('a, 's) kinfo * (n num, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ICheck_signature : - (public_key, signature * (bytes * 's)) kinfo * (bool, 's, 'r, 'f) kinstr - -> (public_key, signature * (bytes * 's), 'r, 'f) kinstr - | IHash_key : - (public_key, 's) kinfo * (public_key_hash, 's, 'r, 'f) kinstr - -> (public_key, 's, 'r, 'f) kinstr - | IPack : - ('a, 's) kinfo * 'a ty * (bytes, 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IUnpack : - (bytes, 's) kinfo * 'a ty * ('a option, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | IBlake2b : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | ISha256 : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | ISha512 : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | ISource : - ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISender : - ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISelf : - ('a, 's) kinfo - * 'b ty - * string - * ('b typed_contract, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISelf_address : - ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IAmount : - ('a, 's) kinfo * (Tez.t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISapling_empty_state : - ('a, 's) kinfo - * Sapling.Memo_size.t - * (Sapling.state, 'a * 's, 'b, 'f) kinstr - -> ('a, 's, 'b, 'f) kinstr - | ISapling_verify_update : - (Sapling.transaction, Sapling.state * 's) kinfo - * ((z num, Sapling.state) pair option, 's, 'r, 'f) kinstr - -> (Sapling.transaction, Sapling.state * 's, 'r, 'f) kinstr - | IDig : - ('a, 's) kinfo - * int - * ('b, 'c * 't, 'c, 't, 'a, 's, 'd, 'u) stack_prefix_preservation_witness - * ('b, 'd * 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IDug : - ('a, 'b * 's) kinfo - * int - * ('c, 't, 'a, 'c * 't, 'b, 's, 'd, 'u) stack_prefix_preservation_witness - * ('d, 'u, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IDipn : - ('a, 's) kinfo - * int - * ('c, 't, 'd, 'v, 'a, 's, 'b, 'u) stack_prefix_preservation_witness - * ('c, 't, 'd, 'v) kinstr - * ('b, 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IDropn : - ('a, 's) kinfo - * int - * ('b, 'u, 'b, 'u, 'a, 's, 'a, 's) stack_prefix_preservation_witness - * ('b, 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IChainId : - ('a, 's) kinfo * (Chain_id.t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | INever : (never, 's) kinfo -> (never, 's, 'r, 'f) kinstr - | IVoting_power : - (public_key_hash, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (public_key_hash, 's, 'r, 'f) kinstr - | ITotal_voting_power : - ('a, 's) kinfo * (n num, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IKeccak : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | ISha3 : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | IAdd_bls12_381_g1 : - (Bls12_381.G1.t, Bls12_381.G1.t * 's) kinfo - * (Bls12_381.G1.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G1.t, Bls12_381.G1.t * 's, 'r, 'f) kinstr - | IAdd_bls12_381_g2 : - (Bls12_381.G2.t, Bls12_381.G2.t * 's) kinfo - * (Bls12_381.G2.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G2.t, Bls12_381.G2.t * 's, 'r, 'f) kinstr - | IAdd_bls12_381_fr : - (Bls12_381.Fr.t, Bls12_381.Fr.t * 's) kinfo - * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IMul_bls12_381_g1 : - (Bls12_381.G1.t, Bls12_381.Fr.t * 's) kinfo - * (Bls12_381.G1.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G1.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IMul_bls12_381_g2 : - (Bls12_381.G2.t, Bls12_381.Fr.t * 's) kinfo - * (Bls12_381.G2.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G2.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IMul_bls12_381_fr : - (Bls12_381.Fr.t, Bls12_381.Fr.t * 's) kinfo - * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IMul_bls12_381_z_fr : - (Bls12_381.Fr.t, 'a num * 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, 'a num * 's, 'r, 'f) kinstr - | IMul_bls12_381_fr_z : - ('a num, Bls12_381.Fr.t * 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> ('a num, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IInt_bls12_381_fr : - (Bls12_381.Fr.t, 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - | INeg_bls12_381_g1 : - (Bls12_381.G1.t, 's) kinfo * (Bls12_381.G1.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G1.t, 's, 'r, 'f) kinstr - | INeg_bls12_381_g2 : - (Bls12_381.G2.t, 's) kinfo * (Bls12_381.G2.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G2.t, 's, 'r, 'f) kinstr - | INeg_bls12_381_fr : - (Bls12_381.Fr.t, 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - | IPairing_check_bls12_381 : - ((Bls12_381.G1.t, Bls12_381.G2.t) pair boxed_list, 's) kinfo - * (bool, 's, 'r, 'f) kinstr - -> ((Bls12_381.G1.t, Bls12_381.G2.t) pair boxed_list, 's, 'r, 'f) kinstr - | IComb : - ('a, 's) kinfo - * int - * ('a * 's, 'b * 'u) comb_gadt_witness - * ('b, 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IUncomb : - ('a, 's) kinfo - * int - * ('a * 's, 'b * 'u) uncomb_gadt_witness - * ('b, 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IComb_get : - ('t, 's) kinfo - * int - * ('t, 'v) comb_get_gadt_witness - * ('v, 's, 'r, 'f) kinstr - -> ('t, 's, 'r, 'f) kinstr - | IComb_set : - ('a, 'b * 's) kinfo - * int - * ('a, 'b, 'c) comb_set_gadt_witness - * ('c, 's, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IDup_n : - ('a, 's) kinfo - * int - * ('a * 's, 't) dup_n_gadt_witness - * ('t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ITicket : - ('a, n num * 's) kinfo * ('a ticket, 's, 'r, 'f) kinstr - -> ('a, n num * 's, 'r, 'f) kinstr - | IRead_ticket : - ('a ticket, 's) kinfo - * (address * ('a * n num), 'a ticket * 's, 'r, 'f) kinstr - -> ('a ticket, 's, 'r, 'f) kinstr - | ISplit_ticket : - ('a ticket, (n num * n num) * 's) kinfo - * (('a ticket * 'a ticket) option, 's, 'r, 'f) kinstr - -> ('a ticket, (n num * n num) * 's, 'r, 'f) kinstr - | IJoin_tickets : - ('a ticket * 'a ticket, 's) kinfo - * 'a comparable_ty - * ('a ticket option, 's, 'r, 'f) kinstr - -> ('a ticket * 'a ticket, 's, 'r, 'f) kinstr - | IOpen_chest : - (Timelock.chest_key, Timelock.chest * (n num * 's)) kinfo - * ((bytes, bool) union, 's, 'r, 'f) kinstr - -> (Timelock.chest_key, Timelock.chest * (n num * 's), 'r, 'f) kinstr - (* - Internal control instructions - ----------------------------- - *) - | IHalt : ('a, 's) kinfo -> ('a, 's, 'a, 's) kinstr - | ILog : - ('a, 's) kinfo * logging_event * logger * ('a, 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - -and logging_event = - | LogEntry : logging_event - | LogExit : ('b, 'u) kinfo -> logging_event - -and ('arg, 'ret) lambda = - | Lam : - ('arg, end_of_stack, 'ret, end_of_stack) kdescr * Script.node - -> ('arg, 'ret) lambda -[@@coq_force_gadt] - -and 'arg typed_contract = 'arg ty * address - -and (_, _, _, _) continuation = - | KNil : ('r, 'f, 'r, 'f) continuation - | KCons : - ('a, 's, 'b, 't) kinstr * ('b, 't, 'r, 'f) continuation - -> ('a, 's, 'r, 'f) continuation - | KReturn : - 's * ('a, 's, 'r, 'f) continuation - -> ('a, end_of_stack, 'r, 'f) continuation - | KMap_head : - ('a -> 'b) * ('b, 's, 'r, 'f) continuation - -> ('a, 's, 'r, 'f) continuation - | KUndip : - 'b * ('b, 'a * 's, 'r, 'f) continuation - -> ('a, 's, 'r, 'f) continuation - | KLoop_in : - ('a, 's, bool, 'a * 's) kinstr * ('a, 's, 'r, 'f) continuation - -> (bool, 'a * 's, 'r, 'f) continuation - | KLoop_in_left : - ('a, 's, ('a, 'b) union, 's) kinstr * ('b, 's, 'r, 'f) continuation - -> (('a, 'b) union, 's, 'r, 'f) continuation - | KIter : - ('a, 'b * 's, 'b, 's) kinstr * 'a list * ('b, 's, 'r, 'f) continuation - -> ('b, 's, 'r, 'f) continuation - | KList_enter_body : - ('a, 'c * 's, 'b, 'c * 's) kinstr - * 'a list - * 'b list - * int - * ('b boxed_list, 'c * 's, 'r, 'f) continuation - -> ('c, 's, 'r, 'f) continuation - | KList_exit_body : - ('a, 'c * 's, 'b, 'c * 's) kinstr - * 'a list - * 'b list - * int - * ('b boxed_list, 'c * 's, 'r, 'f) continuation - -> ('b, 'c * 's, 'r, 'f) continuation - | KMap_enter_body : - ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr - * ('a * 'b) list - * ('a, 'c) map - * (('a, 'c) map, 'd * 's, 'r, 'f) continuation - -> ('d, 's, 'r, 'f) continuation - | KMap_exit_body : - ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr - * ('a * 'b) list - * ('a, 'c) map - * 'a - * (('a, 'c) map, 'd * 's, 'r, 'f) continuation - -> ('c, 'd * 's, 'r, 'f) continuation - | KView_exit : - step_constants * ('a, 's, 'r, 'f) continuation - -> ('a, 's, 'r, 'f) continuation - | KLog : - ('a, 's, 'r, 'f) continuation * logger - -> ('a, 's, 'r, 'f) continuation - -and ('a, 's, 'b, 'f, 'c, 'u) logging_function = - ('a, 's, 'b, 'f) kinstr -> - context -> - Script.location -> - ('c, 'u) stack_ty -> - 'c * 'u -> - unit - -and execution_trace = - (Script.location * Gas.t * (Script.expr * string option) list) list - -and logger = { - log_interp : 'a 's 'b 'f 'c 'u. ('a, 's, 'b, 'f, 'c, 'u) logging_function; - log_entry : 'a 's 'b 'f. ('a, 's, 'b, 'f, 'a, 's) logging_function; - log_control : 'a 's 'b 'f. ('a, 's, 'b, 'f) continuation -> unit; - log_exit : 'a 's 'b 'f 'c 'u. ('a, 's, 'b, 'f, 'c, 'u) logging_function; - get_log : unit -> execution_trace option tzresult Lwt.t; -} - -(* ---- Auxiliary types -----------------------------------------------------*) -and 'ty ty = - | Unit_t : unit ty_metadata -> unit ty - | Int_t : z num ty_metadata -> z num ty - | Nat_t : n num ty_metadata -> n num ty - | Signature_t : signature ty_metadata -> signature ty - | String_t : Script_string.t ty_metadata -> Script_string.t ty - | Bytes_t : Bytes.t ty_metadata -> bytes ty - | Mutez_t : Tez.t ty_metadata -> Tez.t ty - | Key_hash_t : public_key_hash ty_metadata -> public_key_hash ty - | Key_t : public_key ty_metadata -> public_key ty - | Timestamp_t : Script_timestamp.t ty_metadata -> Script_timestamp.t ty - | Address_t : address ty_metadata -> address ty - | Bool_t : bool ty_metadata -> bool ty - | Pair_t : - ('a ty * field_annot option * var_annot option) - * ('b ty * field_annot option * var_annot option) - * ('a, 'b) pair ty_metadata - -> ('a, 'b) pair ty - | Union_t : - ('a ty * field_annot option) - * ('b ty * field_annot option) - * ('a, 'b) union ty_metadata - -> ('a, 'b) union ty - | Lambda_t : - 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata - -> ('arg, 'ret) lambda ty - | Option_t : 'v ty * 'v option ty_metadata -> 'v option ty - | List_t : 'v ty * 'v boxed_list ty_metadata -> 'v boxed_list ty - | Set_t : 'v comparable_ty * 'v set ty_metadata -> 'v set ty - | Map_t : - 'k comparable_ty * 'v ty * ('k, 'v) map ty_metadata - -> ('k, 'v) map ty - | Big_map_t : - 'k comparable_ty * 'v ty * ('k, 'v) big_map ty_metadata - -> ('k, 'v) big_map ty - | Contract_t : - 'arg ty * 'arg typed_contract ty_metadata - -> 'arg typed_contract ty - | Sapling_transaction_t : - Sapling.Memo_size.t * Sapling.transaction ty_metadata - -> Sapling.transaction ty - | Sapling_state_t : - Sapling.Memo_size.t * Sapling.state ty_metadata - -> Sapling.state ty - | Operation_t : operation ty_metadata -> operation ty - | Chain_id_t : Chain_id.t ty_metadata -> Chain_id.t ty - | Never_t : never ty_metadata -> never ty - | Bls12_381_g1_t : Bls12_381.G1.t ty_metadata -> Bls12_381.G1.t ty - | Bls12_381_g2_t : Bls12_381.G2.t ty_metadata -> Bls12_381.G2.t ty - | Bls12_381_fr_t : Bls12_381.Fr.t ty_metadata -> Bls12_381.Fr.t ty - | Ticket_t : 'a comparable_ty * 'a ticket ty_metadata -> 'a ticket ty - | Chest_key_t : Timelock.chest_key ty_metadata -> Timelock.chest_key ty - | Chest_t : Timelock.chest ty_metadata -> Timelock.chest ty - -and ('top_ty, 'resty) stack_ty = - | Item_t : - 'ty ty * ('ty2, 'rest) stack_ty * var_annot option - -> ('ty, 'ty2 * 'rest) stack_ty - | Bot_t : (empty_cell, empty_cell) stack_ty - -and ('key, 'value) big_map = { - id : Big_map.Id.t option; - diff : ('key, 'value) big_map_overlay; - key_type : 'key comparable_ty; - value_type : 'value ty; -} - -and ('a, 's, 'r, 'f) kdescr = { - kloc : Script.location; - kbef : ('a, 's) stack_ty; - kaft : ('r, 'f) stack_ty; - kinstr : ('a, 's, 'r, 'f) kinstr; -} - -and ('a, 's) kinfo = {iloc : Script.location; kstack_ty : ('a, 's) stack_ty} - -and (_, _, _, _, _, _, _, _) stack_prefix_preservation_witness = - | KPrefix : - ('y, 'u) kinfo - * ('c, 'v, 'd, 'w, 'x, 's, 'y, 'u) stack_prefix_preservation_witness - -> ( 'c, - 'v, - 'd, - 'w, - 'a, - 'x * 's, - 'a, - 'y * 'u ) - stack_prefix_preservation_witness - | KRest : ('a, 's, 'b, 'u, 'a, 's, 'b, 'u) stack_prefix_preservation_witness - -and ('before, 'after) comb_gadt_witness = - | Comb_one : ('a * ('x * 'before), 'a * ('x * 'before)) comb_gadt_witness - | Comb_succ : - ('before, 'b * 'after) comb_gadt_witness - -> ('a * 'before, ('a * 'b) * 'after) comb_gadt_witness - -and ('before, 'after) uncomb_gadt_witness = - | Uncomb_one : ('rest, 'rest) uncomb_gadt_witness - | Uncomb_succ : - ('b * 'before, 'after) uncomb_gadt_witness - -> (('a * 'b) * 'before, 'a * 'after) uncomb_gadt_witness - -and ('before, 'after) comb_get_gadt_witness = - | Comb_get_zero : ('b, 'b) comb_get_gadt_witness - | Comb_get_one : ('a * 'b, 'a) comb_get_gadt_witness - | Comb_get_plus_two : - ('before, 'after) comb_get_gadt_witness - -> ('a * 'before, 'after) comb_get_gadt_witness - -and ('value, 'before, 'after) comb_set_gadt_witness = - | Comb_set_zero : ('value, _, 'value) comb_set_gadt_witness - | Comb_set_one : ('value, 'hd * 'tl, 'value * 'tl) comb_set_gadt_witness - | Comb_set_plus_two : - ('value, 'before, 'after) comb_set_gadt_witness - -> ('value, 'a * 'before, 'a * 'after) comb_set_gadt_witness -[@@coq_force_gadt] - -and (_, _) dup_n_gadt_witness = - | Dup_n_zero : ('a * 'rest, 'a) dup_n_gadt_witness - | Dup_n_succ : - ('stack, 'b) dup_n_gadt_witness - -> ('a * 'stack, 'b) dup_n_gadt_witness - -and ('a, 'b) view_signature = - | View_signature of { - name : Script_string.t; - input_ty : 'a ty; - output_ty : 'b ty; - } - -let kinfo_of_kinstr : type a s b f. (a, s, b, f) kinstr -> (a, s) kinfo = - fun i -> - match i with - | IDrop (kinfo, _) -> kinfo - | IDup (kinfo, _) -> kinfo - | ISwap (kinfo, _) -> kinfo - | IConst (kinfo, _, _) -> kinfo - | ICons_pair (kinfo, _) -> kinfo - | ICar (kinfo, _) -> kinfo - | ICdr (kinfo, _) -> kinfo - | IUnpair (kinfo, _) -> kinfo - | ICons_some (kinfo, _) -> kinfo - | ICons_none (kinfo, _) -> kinfo - | IIf_none {kinfo; _} -> kinfo - | IOpt_map {kinfo; _} -> kinfo - | ICons_left (kinfo, _) -> kinfo - | ICons_right (kinfo, _) -> kinfo - | IIf_left {kinfo; _} -> kinfo - | ICons_list (kinfo, _) -> kinfo - | INil (kinfo, _) -> kinfo - | IIf_cons {kinfo; _} -> kinfo - | IList_map (kinfo, _, _) -> kinfo - | IList_iter (kinfo, _, _) -> kinfo - | IList_size (kinfo, _) -> kinfo - | IEmpty_set (kinfo, _, _) -> kinfo - | ISet_iter (kinfo, _, _) -> kinfo - | ISet_mem (kinfo, _) -> kinfo - | ISet_update (kinfo, _) -> kinfo - | ISet_size (kinfo, _) -> kinfo - | IEmpty_map (kinfo, _, _) -> kinfo - | IMap_map (kinfo, _, _) -> kinfo - | IMap_iter (kinfo, _, _) -> kinfo - | IMap_mem (kinfo, _) -> kinfo - | IMap_get (kinfo, _) -> kinfo - | IMap_update (kinfo, _) -> kinfo - | IMap_get_and_update (kinfo, _) -> kinfo - | IMap_size (kinfo, _) -> kinfo - | IEmpty_big_map (kinfo, _, _, _) -> kinfo - | IBig_map_mem (kinfo, _) -> kinfo - | IBig_map_get (kinfo, _) -> kinfo - | IBig_map_update (kinfo, _) -> kinfo - | IBig_map_get_and_update (kinfo, _) -> kinfo - | IConcat_string (kinfo, _) -> kinfo - | IConcat_string_pair (kinfo, _) -> kinfo - | ISlice_string (kinfo, _) -> kinfo - | IString_size (kinfo, _) -> kinfo - | IConcat_bytes (kinfo, _) -> kinfo - | IConcat_bytes_pair (kinfo, _) -> kinfo - | ISlice_bytes (kinfo, _) -> kinfo - | IBytes_size (kinfo, _) -> kinfo - | IAdd_seconds_to_timestamp (kinfo, _) -> kinfo - | IAdd_timestamp_to_seconds (kinfo, _) -> kinfo - | ISub_timestamp_seconds (kinfo, _) -> kinfo - | IDiff_timestamps (kinfo, _) -> kinfo - | IAdd_tez (kinfo, _) -> kinfo - | ISub_tez (kinfo, _) -> kinfo - | ISub_tez_legacy (kinfo, _) -> kinfo - | IMul_teznat (kinfo, _) -> kinfo - | IMul_nattez (kinfo, _) -> kinfo - | IEdiv_teznat (kinfo, _) -> kinfo - | IEdiv_tez (kinfo, _) -> kinfo - | IOr (kinfo, _) -> kinfo - | IAnd (kinfo, _) -> kinfo - | IXor (kinfo, _) -> kinfo - | INot (kinfo, _) -> kinfo - | IIs_nat (kinfo, _) -> kinfo - | INeg (kinfo, _) -> kinfo - | IAbs_int (kinfo, _) -> kinfo - | IInt_nat (kinfo, _) -> kinfo - | IAdd_int (kinfo, _) -> kinfo - | IAdd_nat (kinfo, _) -> kinfo - | ISub_int (kinfo, _) -> kinfo - | IMul_int (kinfo, _) -> kinfo - | IMul_nat (kinfo, _) -> kinfo - | IEdiv_int (kinfo, _) -> kinfo - | IEdiv_nat (kinfo, _) -> kinfo - | ILsl_nat (kinfo, _) -> kinfo - | ILsr_nat (kinfo, _) -> kinfo - | IOr_nat (kinfo, _) -> kinfo - | IAnd_nat (kinfo, _) -> kinfo - | IAnd_int_nat (kinfo, _) -> kinfo - | IXor_nat (kinfo, _) -> kinfo - | INot_int (kinfo, _) -> kinfo - | IIf {kinfo; _} -> kinfo - | ILoop (kinfo, _, _) -> kinfo - | ILoop_left (kinfo, _, _) -> kinfo - | IDip (kinfo, _, _) -> kinfo - | IExec (kinfo, _) -> kinfo - | IApply (kinfo, _, _) -> kinfo - | ILambda (kinfo, _, _) -> kinfo - | IFailwith (kinfo, _, _) -> kinfo - | ICompare (kinfo, _, _) -> kinfo - | IEq (kinfo, _) -> kinfo - | INeq (kinfo, _) -> kinfo - | ILt (kinfo, _) -> kinfo - | IGt (kinfo, _) -> kinfo - | ILe (kinfo, _) -> kinfo - | IGe (kinfo, _) -> kinfo - | IAddress (kinfo, _) -> kinfo - | IContract (kinfo, _, _, _) -> kinfo - | ITransfer_tokens (kinfo, _) -> kinfo - | IView (kinfo, _, _) -> kinfo - | IImplicit_account (kinfo, _) -> kinfo - | ICreate_contract {kinfo; _} -> kinfo - | ISet_delegate (kinfo, _) -> kinfo - | INow (kinfo, _) -> kinfo - | IBalance (kinfo, _) -> kinfo - | ILevel (kinfo, _) -> kinfo - | ICheck_signature (kinfo, _) -> kinfo - | IHash_key (kinfo, _) -> kinfo - | IPack (kinfo, _, _) -> kinfo - | IUnpack (kinfo, _, _) -> kinfo - | IBlake2b (kinfo, _) -> kinfo - | ISha256 (kinfo, _) -> kinfo - | ISha512 (kinfo, _) -> kinfo - | ISource (kinfo, _) -> kinfo - | ISender (kinfo, _) -> kinfo - | ISelf (kinfo, _, _, _) -> kinfo - | ISelf_address (kinfo, _) -> kinfo - | IAmount (kinfo, _) -> kinfo - | ISapling_empty_state (kinfo, _, _) -> kinfo - | ISapling_verify_update (kinfo, _) -> kinfo - | IDig (kinfo, _, _, _) -> kinfo - | IDug (kinfo, _, _, _) -> kinfo - | IDipn (kinfo, _, _, _, _) -> kinfo - | IDropn (kinfo, _, _, _) -> kinfo - | IChainId (kinfo, _) -> kinfo - | INever kinfo -> kinfo - | IVoting_power (kinfo, _) -> kinfo - | ITotal_voting_power (kinfo, _) -> kinfo - | IKeccak (kinfo, _) -> kinfo - | ISha3 (kinfo, _) -> kinfo - | IAdd_bls12_381_g1 (kinfo, _) -> kinfo - | IAdd_bls12_381_g2 (kinfo, _) -> kinfo - | IAdd_bls12_381_fr (kinfo, _) -> kinfo - | IMul_bls12_381_g1 (kinfo, _) -> kinfo - | IMul_bls12_381_g2 (kinfo, _) -> kinfo - | IMul_bls12_381_fr (kinfo, _) -> kinfo - | IMul_bls12_381_z_fr (kinfo, _) -> kinfo - | IMul_bls12_381_fr_z (kinfo, _) -> kinfo - | IInt_bls12_381_fr (kinfo, _) -> kinfo - | INeg_bls12_381_g1 (kinfo, _) -> kinfo - | INeg_bls12_381_g2 (kinfo, _) -> kinfo - | INeg_bls12_381_fr (kinfo, _) -> kinfo - | IPairing_check_bls12_381 (kinfo, _) -> kinfo - | IComb (kinfo, _, _, _) -> kinfo - | IUncomb (kinfo, _, _, _) -> kinfo - | IComb_get (kinfo, _, _, _) -> kinfo - | IComb_set (kinfo, _, _, _) -> kinfo - | IDup_n (kinfo, _, _, _) -> kinfo - | ITicket (kinfo, _) -> kinfo - | IRead_ticket (kinfo, _) -> kinfo - | ISplit_ticket (kinfo, _) -> kinfo - | IJoin_tickets (kinfo, _, _) -> kinfo - | IHalt kinfo -> kinfo - | ILog (kinfo, _, _, _) -> kinfo - | IOpen_chest (kinfo, _) -> kinfo - -type kinstr_rewritek = { - apply : 'b 'u 'r 'f. ('b, 'u, 'r, 'f) kinstr -> ('b, 'u, 'r, 'f) kinstr; -} - -let kinstr_rewritek : - type a s r f. (a, s, r, f) kinstr -> kinstr_rewritek -> (a, s, r, f) kinstr - = - fun i f -> - match i with - | IDrop (kinfo, k) -> IDrop (kinfo, f.apply k) - | IDup (kinfo, k) -> IDup (kinfo, f.apply k) - | ISwap (kinfo, k) -> ISwap (kinfo, f.apply k) - | IConst (kinfo, x, k) -> IConst (kinfo, x, f.apply k) - | ICons_pair (kinfo, k) -> ICons_pair (kinfo, f.apply k) - | ICar (kinfo, k) -> ICar (kinfo, f.apply k) - | ICdr (kinfo, k) -> ICdr (kinfo, f.apply k) - | IUnpair (kinfo, k) -> IUnpair (kinfo, f.apply k) - | ICons_some (kinfo, k) -> ICons_some (kinfo, f.apply k) - | ICons_none (kinfo, k) -> ICons_none (kinfo, f.apply k) - | IIf_none {kinfo; branch_if_none; branch_if_some; k} -> - IIf_none - { - kinfo; - branch_if_none = f.apply branch_if_none; - branch_if_some = f.apply branch_if_some; - k = f.apply k; - } - | IOpt_map {kinfo; body; k} -> - let body = f.apply body in - let k = f.apply k in - IOpt_map {kinfo; body; k} - | ICons_left (kinfo, k) -> ICons_left (kinfo, f.apply k) - | ICons_right (kinfo, k) -> ICons_right (kinfo, f.apply k) - | IIf_left {kinfo; branch_if_left; branch_if_right; k} -> - IIf_left - { - kinfo; - branch_if_left = f.apply branch_if_left; - branch_if_right = f.apply branch_if_right; - k = f.apply k; - } - | ICons_list (kinfo, k) -> ICons_list (kinfo, f.apply k) - | INil (kinfo, k) -> INil (kinfo, f.apply k) - | IIf_cons {kinfo; branch_if_cons; branch_if_nil; k} -> - IIf_cons - { - kinfo; - branch_if_cons = f.apply branch_if_cons; - branch_if_nil = f.apply branch_if_nil; - k = f.apply k; - } - | IList_map (kinfo, body, k) -> IList_map (kinfo, f.apply body, f.apply k) - | IList_iter (kinfo, body, k) -> IList_iter (kinfo, f.apply body, f.apply k) - | IList_size (kinfo, k) -> IList_size (kinfo, f.apply k) - | IEmpty_set (kinfo, ty, k) -> IEmpty_set (kinfo, ty, f.apply k) - | ISet_iter (kinfo, body, k) -> ISet_iter (kinfo, f.apply body, f.apply k) - | ISet_mem (kinfo, k) -> ISet_mem (kinfo, f.apply k) - | ISet_update (kinfo, k) -> ISet_update (kinfo, f.apply k) - | ISet_size (kinfo, k) -> ISet_size (kinfo, f.apply k) - | IEmpty_map (kinfo, cty, k) -> IEmpty_map (kinfo, cty, f.apply k) - | IMap_map (kinfo, body, k) -> IMap_map (kinfo, f.apply body, f.apply k) - | IMap_iter (kinfo, body, k) -> IMap_iter (kinfo, f.apply body, f.apply k) - | IMap_mem (kinfo, k) -> IMap_mem (kinfo, f.apply k) - | IMap_get (kinfo, k) -> IMap_get (kinfo, f.apply k) - | IMap_update (kinfo, k) -> IMap_update (kinfo, f.apply k) - | IMap_get_and_update (kinfo, k) -> IMap_get_and_update (kinfo, f.apply k) - | IMap_size (kinfo, k) -> IMap_size (kinfo, f.apply k) - | IEmpty_big_map (kinfo, cty, ty, k) -> - IEmpty_big_map (kinfo, cty, ty, f.apply k) - | IBig_map_mem (kinfo, k) -> IBig_map_mem (kinfo, f.apply k) - | IBig_map_get (kinfo, k) -> IBig_map_get (kinfo, f.apply k) - | IBig_map_update (kinfo, k) -> IBig_map_update (kinfo, f.apply k) - | IBig_map_get_and_update (kinfo, k) -> - IBig_map_get_and_update (kinfo, f.apply k) - | IConcat_string (kinfo, k) -> IConcat_string (kinfo, f.apply k) - | IConcat_string_pair (kinfo, k) -> IConcat_string_pair (kinfo, f.apply k) - | ISlice_string (kinfo, k) -> ISlice_string (kinfo, f.apply k) - | IString_size (kinfo, k) -> IString_size (kinfo, f.apply k) - | IConcat_bytes (kinfo, k) -> IConcat_bytes (kinfo, f.apply k) - | IConcat_bytes_pair (kinfo, k) -> IConcat_bytes_pair (kinfo, f.apply k) - | ISlice_bytes (kinfo, k) -> ISlice_bytes (kinfo, f.apply k) - | IBytes_size (kinfo, k) -> IBytes_size (kinfo, f.apply k) - | IAdd_seconds_to_timestamp (kinfo, k) -> - IAdd_seconds_to_timestamp (kinfo, f.apply k) - | IAdd_timestamp_to_seconds (kinfo, k) -> - IAdd_timestamp_to_seconds (kinfo, f.apply k) - | ISub_timestamp_seconds (kinfo, k) -> - ISub_timestamp_seconds (kinfo, f.apply k) - | IDiff_timestamps (kinfo, k) -> IDiff_timestamps (kinfo, f.apply k) - | IAdd_tez (kinfo, k) -> IAdd_tez (kinfo, f.apply k) - | ISub_tez (kinfo, k) -> ISub_tez (kinfo, f.apply k) - | ISub_tez_legacy (kinfo, k) -> ISub_tez_legacy (kinfo, f.apply k) - | IMul_teznat (kinfo, k) -> IMul_teznat (kinfo, f.apply k) - | IMul_nattez (kinfo, k) -> IMul_nattez (kinfo, f.apply k) - | IEdiv_teznat (kinfo, k) -> IEdiv_teznat (kinfo, f.apply k) - | IEdiv_tez (kinfo, k) -> IEdiv_tez (kinfo, f.apply k) - | IOr (kinfo, k) -> IOr (kinfo, f.apply k) - | IAnd (kinfo, k) -> IAnd (kinfo, f.apply k) - | IXor (kinfo, k) -> IXor (kinfo, f.apply k) - | INot (kinfo, k) -> INot (kinfo, f.apply k) - | IIs_nat (kinfo, k) -> IIs_nat (kinfo, f.apply k) - | INeg (kinfo, k) -> INeg (kinfo, f.apply k) - | IAbs_int (kinfo, k) -> IAbs_int (kinfo, f.apply k) - | IInt_nat (kinfo, k) -> IInt_nat (kinfo, f.apply k) - | IAdd_int (kinfo, k) -> IAdd_int (kinfo, f.apply k) - | IAdd_nat (kinfo, k) -> IAdd_nat (kinfo, f.apply k) - | ISub_int (kinfo, k) -> ISub_int (kinfo, f.apply k) - | IMul_int (kinfo, k) -> IMul_int (kinfo, f.apply k) - | IMul_nat (kinfo, k) -> IMul_nat (kinfo, f.apply k) - | IEdiv_int (kinfo, k) -> IEdiv_int (kinfo, f.apply k) - | IEdiv_nat (kinfo, k) -> IEdiv_nat (kinfo, f.apply k) - | ILsl_nat (kinfo, k) -> ILsl_nat (kinfo, f.apply k) - | ILsr_nat (kinfo, k) -> ILsr_nat (kinfo, f.apply k) - | IOr_nat (kinfo, k) -> IOr_nat (kinfo, f.apply k) - | IAnd_nat (kinfo, k) -> IAnd_nat (kinfo, f.apply k) - | IAnd_int_nat (kinfo, k) -> IAnd_int_nat (kinfo, f.apply k) - | IXor_nat (kinfo, k) -> IXor_nat (kinfo, f.apply k) - | INot_int (kinfo, k) -> INot_int (kinfo, f.apply k) - | IIf {kinfo; branch_if_true; branch_if_false; k} -> - IIf - { - kinfo; - branch_if_true = f.apply branch_if_true; - branch_if_false = f.apply branch_if_false; - k = f.apply k; - } - | ILoop (kinfo, kbody, k) -> ILoop (kinfo, f.apply kbody, f.apply k) - | ILoop_left (kinfo, kl, kr) -> ILoop_left (kinfo, f.apply kl, f.apply kr) - | IDip (kinfo, body, k) -> IDip (kinfo, f.apply body, f.apply k) - | IExec (kinfo, k) -> IExec (kinfo, f.apply k) - | IApply (kinfo, ty, k) -> IApply (kinfo, ty, f.apply k) - | ILambda (kinfo, l, k) -> ILambda (kinfo, l, f.apply k) - | IFailwith (kinfo, i, ty) -> IFailwith (kinfo, i, ty) - | ICompare (kinfo, ty, k) -> ICompare (kinfo, ty, f.apply k) - | IEq (kinfo, k) -> IEq (kinfo, f.apply k) - | INeq (kinfo, k) -> INeq (kinfo, f.apply k) - | ILt (kinfo, k) -> ILt (kinfo, f.apply k) - | IGt (kinfo, k) -> IGt (kinfo, f.apply k) - | ILe (kinfo, k) -> ILe (kinfo, f.apply k) - | IGe (kinfo, k) -> IGe (kinfo, f.apply k) - | IAddress (kinfo, k) -> IAddress (kinfo, f.apply k) - | IContract (kinfo, ty, code, k) -> IContract (kinfo, ty, code, f.apply k) - | ITransfer_tokens (kinfo, k) -> ITransfer_tokens (kinfo, f.apply k) - | IView (kinfo, view_signature, k) -> IView (kinfo, view_signature, f.apply k) - | IImplicit_account (kinfo, k) -> IImplicit_account (kinfo, f.apply k) - | ICreate_contract - {kinfo; storage_type; arg_type; lambda; views; root_name; k} -> - let k = f.apply k in - ICreate_contract - {kinfo; storage_type; arg_type; lambda; views; root_name; k} - | ISet_delegate (kinfo, k) -> ISet_delegate (kinfo, f.apply k) - | INow (kinfo, k) -> INow (kinfo, f.apply k) - | IBalance (kinfo, k) -> IBalance (kinfo, f.apply k) - | ILevel (kinfo, k) -> ILevel (kinfo, f.apply k) - | ICheck_signature (kinfo, k) -> ICheck_signature (kinfo, f.apply k) - | IHash_key (kinfo, k) -> IHash_key (kinfo, f.apply k) - | IPack (kinfo, ty, k) -> IPack (kinfo, ty, f.apply k) - | IUnpack (kinfo, ty, k) -> IUnpack (kinfo, ty, f.apply k) - | IBlake2b (kinfo, k) -> IBlake2b (kinfo, f.apply k) - | ISha256 (kinfo, k) -> ISha256 (kinfo, f.apply k) - | ISha512 (kinfo, k) -> ISha512 (kinfo, f.apply k) - | ISource (kinfo, k) -> ISource (kinfo, f.apply k) - | ISender (kinfo, k) -> ISender (kinfo, f.apply k) - | ISelf (kinfo, ty, s, k) -> ISelf (kinfo, ty, s, f.apply k) - | ISelf_address (kinfo, k) -> ISelf_address (kinfo, f.apply k) - | IAmount (kinfo, k) -> IAmount (kinfo, f.apply k) - | ISapling_empty_state (kinfo, s, k) -> - ISapling_empty_state (kinfo, s, f.apply k) - | ISapling_verify_update (kinfo, k) -> - ISapling_verify_update (kinfo, f.apply k) - | IDig (kinfo, n, p, k) -> IDig (kinfo, n, p, f.apply k) - | IDug (kinfo, n, p, k) -> IDug (kinfo, n, p, f.apply k) - | IDipn (kinfo, n, p, k1, k2) -> IDipn (kinfo, n, p, f.apply k1, f.apply k2) - | IDropn (kinfo, n, p, k) -> IDropn (kinfo, n, p, f.apply k) - | IChainId (kinfo, k) -> IChainId (kinfo, f.apply k) - | INever kinfo -> INever kinfo - | IVoting_power (kinfo, k) -> IVoting_power (kinfo, f.apply k) - | ITotal_voting_power (kinfo, k) -> ITotal_voting_power (kinfo, f.apply k) - | IKeccak (kinfo, k) -> IKeccak (kinfo, f.apply k) - | ISha3 (kinfo, k) -> ISha3 (kinfo, f.apply k) - | IAdd_bls12_381_g1 (kinfo, k) -> IAdd_bls12_381_g1 (kinfo, f.apply k) - | IAdd_bls12_381_g2 (kinfo, k) -> IAdd_bls12_381_g2 (kinfo, f.apply k) - | IAdd_bls12_381_fr (kinfo, k) -> IAdd_bls12_381_fr (kinfo, f.apply k) - | IMul_bls12_381_g1 (kinfo, k) -> IMul_bls12_381_g1 (kinfo, f.apply k) - | IMul_bls12_381_g2 (kinfo, k) -> IMul_bls12_381_g2 (kinfo, f.apply k) - | IMul_bls12_381_fr (kinfo, k) -> IMul_bls12_381_fr (kinfo, f.apply k) - | IMul_bls12_381_z_fr (kinfo, k) -> IMul_bls12_381_z_fr (kinfo, f.apply k) - | IMul_bls12_381_fr_z (kinfo, k) -> IMul_bls12_381_fr_z (kinfo, f.apply k) - | IInt_bls12_381_fr (kinfo, k) -> IInt_bls12_381_fr (kinfo, f.apply k) - | INeg_bls12_381_g1 (kinfo, k) -> INeg_bls12_381_g1 (kinfo, f.apply k) - | INeg_bls12_381_g2 (kinfo, k) -> INeg_bls12_381_g2 (kinfo, f.apply k) - | INeg_bls12_381_fr (kinfo, k) -> INeg_bls12_381_fr (kinfo, f.apply k) - | IPairing_check_bls12_381 (kinfo, k) -> - IPairing_check_bls12_381 (kinfo, f.apply k) - | IComb (kinfo, n, p, k) -> IComb (kinfo, n, p, f.apply k) - | IUncomb (kinfo, n, p, k) -> IUncomb (kinfo, n, p, f.apply k) - | IComb_get (kinfo, n, p, k) -> IComb_get (kinfo, n, p, f.apply k) - | IComb_set (kinfo, n, p, k) -> IComb_set (kinfo, n, p, f.apply k) - | IDup_n (kinfo, n, p, k) -> IDup_n (kinfo, n, p, f.apply k) - | ITicket (kinfo, k) -> ITicket (kinfo, f.apply k) - | IRead_ticket (kinfo, k) -> IRead_ticket (kinfo, f.apply k) - | ISplit_ticket (kinfo, k) -> ISplit_ticket (kinfo, f.apply k) - | IJoin_tickets (kinfo, ty, k) -> IJoin_tickets (kinfo, ty, f.apply k) - | IHalt kinfo -> IHalt kinfo - | ILog (kinfo, event, logger, k) -> ILog (kinfo, event, logger, k) - | IOpen_chest (kinfo, k) -> IOpen_chest (kinfo, f.apply k) - -let ty_metadata : type a. a ty -> a ty_metadata = function - | Unit_t meta -> meta - | Never_t meta -> meta - | Int_t meta -> meta - | Nat_t meta -> meta - | Signature_t meta -> meta - | String_t meta -> meta - | Bytes_t meta -> meta - | Mutez_t meta -> meta - | Bool_t meta -> meta - | Key_hash_t meta -> meta - | Key_t meta -> meta - | Timestamp_t meta -> meta - | Chain_id_t meta -> meta - | Address_t meta -> meta - | Pair_t (_, _, meta) -> meta - | Union_t (_, _, meta) -> meta - | Option_t (_, meta) -> meta - | Lambda_t (_, _, meta) -> meta - | List_t (_, meta) -> meta - | Set_t (_, meta) -> meta - | Map_t (_, _, meta) -> meta - | Big_map_t (_, _, meta) -> meta - | Ticket_t (_, meta) -> meta - | Contract_t (_, meta) -> meta - | Sapling_transaction_t (_, meta) -> meta - | Sapling_state_t (_, meta) -> meta - | Operation_t meta -> meta - | Bls12_381_g1_t meta -> meta - | Bls12_381_g2_t meta -> meta - | Bls12_381_fr_t meta -> meta - | Chest_t meta -> meta - | Chest_key_t meta -> meta - -let ty_size t = (ty_metadata t).size - -let unit_t ~annot = Unit_t {annot; size = Type_size.one} - -let int_t ~annot = Int_t {annot; size = Type_size.one} - -let nat_t ~annot = Nat_t {annot; size = Type_size.one} - -let signature_t ~annot = Signature_t {annot; size = Type_size.one} - -let string_t ~annot = String_t {annot; size = Type_size.one} - -let bytes_t ~annot = Bytes_t {annot; size = Type_size.one} - -let mutez_t ~annot = Mutez_t {annot; size = Type_size.one} - -let key_hash_t ~annot = Key_hash_t {annot; size = Type_size.one} - -let key_t ~annot = Key_t {annot; size = Type_size.one} - -let timestamp_t ~annot = Timestamp_t {annot; size = Type_size.one} - -let address_t ~annot = Address_t {annot; size = Type_size.one} - -let bool_t ~annot = Bool_t {annot; size = Type_size.one} - -let pair_t loc (l, fannot_l, vannot_l) (r, fannot_r, vannot_r) ~annot = - Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> - Pair_t ((l, fannot_l, vannot_l), (r, fannot_r, vannot_r), {annot; size}) - -let union_t loc (l, fannot_l) (r, fannot_r) ~annot = - Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> - Union_t ((l, fannot_l), (r, fannot_r), {annot; size}) - -let union_bytes_bool_t = - Union_t - ( (bytes_t ~annot:None, None), - (bool_t ~annot:None, None), - {annot = None; size = Type_size.three} ) - -let lambda_t loc l r ~annot = - Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> - Lambda_t (l, r, {annot; size}) - -let option_t loc t ~annot = - Type_size.compound1 loc (ty_size t) >|? fun size -> Option_t (t, {annot; size}) - -let option_mutez'_t meta = - let {annot; size = _} = meta in - Option_t (mutez_t ~annot, {annot = None; size = Type_size.two}) - -let option_string'_t meta = - let {annot; size = _} = meta in - Option_t (string_t ~annot, {annot = None; size = Type_size.two}) - -let option_bytes'_t meta = - let {annot; size = _} = meta in - Option_t (bytes_t ~annot, {annot = None; size = Type_size.two}) - -let option_nat_t = - Option_t (nat_t ~annot:None, {annot = None; size = Type_size.two}) - -let option_pair_nat_nat_t = - Option_t - ( Pair_t - ( (nat_t ~annot:None, None, None), - (nat_t ~annot:None, None, None), - {annot = None; size = Type_size.three} ), - {annot = None; size = Type_size.four} ) - -let option_pair_nat'_nat'_t meta = - let {annot; size = _} = meta in - Option_t - ( Pair_t - ( (nat_t ~annot, None, None), - (nat_t ~annot, None, None), - {annot = None; size = Type_size.three} ), - {annot = None; size = Type_size.four} ) - -let option_pair_nat_mutez'_t meta = - let {annot; size = _} = meta in - Option_t - ( Pair_t - ( (nat_t ~annot:None, None, None), - (mutez_t ~annot, None, None), - {annot = None; size = Type_size.three} ), - {annot = None; size = Type_size.four} ) - -let option_pair_mutez'_mutez'_t meta = - let {annot; size = _} = meta in - Option_t - ( Pair_t - ( (mutez_t ~annot, None, None), - (mutez_t ~annot, None, None), - {annot = None; size = Type_size.three} ), - {annot = None; size = Type_size.four} ) - -let option_pair_int'_nat_t meta = - let {annot; size = _} = meta in - Option_t - ( Pair_t - ( (int_t ~annot, None, None), - (nat_t ~annot:None, None, None), - {annot = None; size = Type_size.three} ), - {annot = None; size = Type_size.four} ) - -let option_pair_int_nat'_t meta = - let {annot; size = _} = meta in - Option_t - ( Pair_t - ( (int_t ~annot:None, None, None), - (nat_t ~annot, None, None), - {annot = None; size = Type_size.three} ), - {annot = None; size = Type_size.four} ) - -let list_t loc t ~annot = - Type_size.compound1 loc (ty_size t) >|? fun size -> List_t (t, {annot; size}) - -let operation_t ~annot = Operation_t {annot; size = Type_size.one} - -let list_operation_t = - List_t (operation_t ~annot:None, {annot = None; size = Type_size.two}) - -let set_t loc t ~annot = - Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> - Set_t (t, {annot; size}) - -let map_t loc l r ~annot = - Type_size.compound2 loc (comparable_ty_size l) (ty_size r) >|? fun size -> - Map_t (l, r, {annot; size}) - -let big_map_t loc l r ~annot = - Type_size.compound2 loc (comparable_ty_size l) (ty_size r) >|? fun size -> - Big_map_t (l, r, {annot; size}) - -let contract_t loc t ~annot = - Type_size.compound1 loc (ty_size t) >|? fun size -> - Contract_t (t, {annot; size}) - -let contract_unit_t = - Contract_t (unit_t ~annot:None, {annot = None; size = Type_size.two}) - -let sapling_transaction_t ~memo_size ~annot = - Sapling_transaction_t (memo_size, {annot; size = Type_size.one}) - -let sapling_state_t ~memo_size ~annot = - Sapling_state_t (memo_size, {annot; size = Type_size.one}) - -let chain_id_t ~annot = Chain_id_t {annot; size = Type_size.one} - -let never_t ~annot = Never_t {annot; size = Type_size.one} - -let bls12_381_g1_t ~annot = Bls12_381_g1_t {annot; size = Type_size.one} - -let bls12_381_g2_t ~annot = Bls12_381_g2_t {annot; size = Type_size.one} - -let bls12_381_fr_t ~annot = Bls12_381_fr_t {annot; size = Type_size.one} - -let ticket_t loc t ~annot = - Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> - Ticket_t (t, {annot; size}) - -let chest_key_t ~annot = Chest_key_t {annot; size = Type_size.one} - -let chest_t ~annot = Chest_t {annot; size = Type_size.one} - -type 'a kinstr_traverse = { - apply : 'b 'u 'r 'f. 'a -> ('b, 'u, 'r, 'f) kinstr -> 'a; -} - -let kinstr_traverse i init f = - let rec aux : - type ret a s r f. 'accu -> (a, s, r, f) kinstr -> ('accu -> ret) -> ret = - fun accu t continue -> - let accu = f.apply accu t in - let next k = - (aux [@ocaml.tailcall]) accu k @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - let next2 k1 k2 = - (aux [@ocaml.tailcall]) accu k1 @@ fun accu -> - (aux [@ocaml.tailcall]) accu k2 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - let next3 k1 k2 k3 = - (aux [@ocaml.tailcall]) accu k1 @@ fun accu -> - (aux [@ocaml.tailcall]) accu k2 @@ fun accu -> - (aux [@ocaml.tailcall]) accu k3 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - let return () = (continue [@ocaml.tailcall]) accu in - match t with - | IDrop (_, k) -> (next [@ocaml.tailcall]) k - | IDup (_, k) -> (next [@ocaml.tailcall]) k - | ISwap (_, k) -> (next [@ocaml.tailcall]) k - | IConst (_, _, k) -> (next [@ocaml.tailcall]) k - | ICons_pair (_, k) -> (next [@ocaml.tailcall]) k - | ICar (_, k) -> (next [@ocaml.tailcall]) k - | ICdr (_, k) -> (next [@ocaml.tailcall]) k - | IUnpair (_, k) -> (next [@ocaml.tailcall]) k - | ICons_some (_, k) -> (next [@ocaml.tailcall]) k - | ICons_none (_, k) -> (next [@ocaml.tailcall]) k - | IIf_none {kinfo = _; branch_if_none = k1; branch_if_some = k2; k} -> - (next3 [@ocaml.tailcall]) k1 k2 k - | IOpt_map {kinfo = _; body; k} -> (next2 [@ocaml.tailcall]) body k - | ICons_left (_, k) -> (next [@ocaml.tailcall]) k - | ICons_right (_, k) -> (next [@ocaml.tailcall]) k - | IIf_left {kinfo = _; branch_if_left = k1; branch_if_right = k2; k} -> - (next3 [@ocaml.tailcall]) k1 k2 k - | ICons_list (_, k) -> (next [@ocaml.tailcall]) k - | INil (_, k) -> (next [@ocaml.tailcall]) k - | IIf_cons {kinfo = _; branch_if_nil = k1; branch_if_cons = k2; k} -> - (next3 [@ocaml.tailcall]) k1 k2 k - | IList_map (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 - | IList_iter (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 - | IList_size (_, k) -> (next [@ocaml.tailcall]) k - | IEmpty_set (_, _, k) -> (next [@ocaml.tailcall]) k - | ISet_iter (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 - | ISet_mem (_, k) -> (next [@ocaml.tailcall]) k - | ISet_update (_, k) -> (next [@ocaml.tailcall]) k - | ISet_size (_, k) -> (next [@ocaml.tailcall]) k - | IEmpty_map (_, _, k) -> (next [@ocaml.tailcall]) k - | IMap_map (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 - | IMap_iter (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 - | IMap_mem (_, k) -> (next [@ocaml.tailcall]) k - | IMap_get (_, k) -> (next [@ocaml.tailcall]) k - | IMap_update (_, k) -> (next [@ocaml.tailcall]) k - | IMap_get_and_update (_, k) -> (next [@ocaml.tailcall]) k - | IMap_size (_, k) -> (next [@ocaml.tailcall]) k - | IEmpty_big_map (_, _, _, k) -> (next [@ocaml.tailcall]) k - | IBig_map_mem (_, k) -> (next [@ocaml.tailcall]) k - | IBig_map_get (_, k) -> (next [@ocaml.tailcall]) k - | IBig_map_update (_, k) -> (next [@ocaml.tailcall]) k - | IBig_map_get_and_update (_, k) -> (next [@ocaml.tailcall]) k - | IConcat_string (_, k) -> (next [@ocaml.tailcall]) k - | IConcat_string_pair (_, k) -> (next [@ocaml.tailcall]) k - | ISlice_string (_, k) -> (next [@ocaml.tailcall]) k - | IString_size (_, k) -> (next [@ocaml.tailcall]) k - | IConcat_bytes (_, k) -> (next [@ocaml.tailcall]) k - | IConcat_bytes_pair (_, k) -> (next [@ocaml.tailcall]) k - | ISlice_bytes (_, k) -> (next [@ocaml.tailcall]) k - | IBytes_size (_, k) -> (next [@ocaml.tailcall]) k - | IAdd_seconds_to_timestamp (_, k) -> (next [@ocaml.tailcall]) k - | IAdd_timestamp_to_seconds (_, k) -> (next [@ocaml.tailcall]) k - | ISub_timestamp_seconds (_, k) -> (next [@ocaml.tailcall]) k - | IDiff_timestamps (_, k) -> (next [@ocaml.tailcall]) k - | IAdd_tez (_, k) -> (next [@ocaml.tailcall]) k - | ISub_tez (_, k) -> (next [@ocaml.tailcall]) k - | ISub_tez_legacy (_, k) -> (next [@ocaml.tailcall]) k - | IMul_teznat (_, k) -> (next [@ocaml.tailcall]) k - | IMul_nattez (_, k) -> (next [@ocaml.tailcall]) k - | IEdiv_teznat (_, k) -> (next [@ocaml.tailcall]) k - | IEdiv_tez (_, k) -> (next [@ocaml.tailcall]) k - | IOr (_, k) -> (next [@ocaml.tailcall]) k - | IAnd (_, k) -> (next [@ocaml.tailcall]) k - | IXor (_, k) -> (next [@ocaml.tailcall]) k - | INot (_, k) -> (next [@ocaml.tailcall]) k - | IIs_nat (_, k) -> (next [@ocaml.tailcall]) k - | INeg (_, k) -> (next [@ocaml.tailcall]) k - | IAbs_int (_, k) -> (next [@ocaml.tailcall]) k - | IInt_nat (_, k) -> (next [@ocaml.tailcall]) k - | IAdd_int (_, k) -> (next [@ocaml.tailcall]) k - | IAdd_nat (_, k) -> (next [@ocaml.tailcall]) k - | ISub_int (_, k) -> (next [@ocaml.tailcall]) k - | IMul_int (_, k) -> (next [@ocaml.tailcall]) k - | IMul_nat (_, k) -> (next [@ocaml.tailcall]) k - | IEdiv_int (_, k) -> (next [@ocaml.tailcall]) k - | IEdiv_nat (_, k) -> (next [@ocaml.tailcall]) k - | ILsl_nat (_, k) -> (next [@ocaml.tailcall]) k - | ILsr_nat (_, k) -> (next [@ocaml.tailcall]) k - | IOr_nat (_, k) -> (next [@ocaml.tailcall]) k - | IAnd_nat (_, k) -> (next [@ocaml.tailcall]) k - | IAnd_int_nat (_, k) -> (next [@ocaml.tailcall]) k - | IXor_nat (_, k) -> (next [@ocaml.tailcall]) k - | INot_int (_, k) -> (next [@ocaml.tailcall]) k - | IIf {kinfo = _; branch_if_true = k1; branch_if_false = k2; k} -> - (next3 [@ocaml.tailcall]) k1 k2 k - | ILoop (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 - | ILoop_left (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 - | IDip (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 - | IExec (_, k) -> (next [@ocaml.tailcall]) k - | IApply (_, _, k) -> (next [@ocaml.tailcall]) k - | ILambda (_, _, k) -> (next [@ocaml.tailcall]) k - | IFailwith (_, _, _) -> (return [@ocaml.tailcall]) () - | ICompare (_, _, k) -> (next [@ocaml.tailcall]) k - | IEq (_, k) -> (next [@ocaml.tailcall]) k - | INeq (_, k) -> (next [@ocaml.tailcall]) k - | ILt (_, k) -> (next [@ocaml.tailcall]) k - | IGt (_, k) -> (next [@ocaml.tailcall]) k - | ILe (_, k) -> (next [@ocaml.tailcall]) k - | IGe (_, k) -> (next [@ocaml.tailcall]) k - | IAddress (_, k) -> (next [@ocaml.tailcall]) k - | IContract (_, _, _, k) -> (next [@ocaml.tailcall]) k - | IView (_, _, k) -> (next [@ocaml.tailcall]) k - | ITransfer_tokens (_, k) -> (next [@ocaml.tailcall]) k - | IImplicit_account (_, k) -> (next [@ocaml.tailcall]) k - | ICreate_contract {k; _} -> (next [@ocaml.tailcall]) k - | ISet_delegate (_, k) -> (next [@ocaml.tailcall]) k - | INow (_, k) -> (next [@ocaml.tailcall]) k - | IBalance (_, k) -> (next [@ocaml.tailcall]) k - | ILevel (_, k) -> (next [@ocaml.tailcall]) k - | ICheck_signature (_, k) -> (next [@ocaml.tailcall]) k - | IHash_key (_, k) -> (next [@ocaml.tailcall]) k - | IPack (_, _, k) -> (next [@ocaml.tailcall]) k - | IUnpack (_, _, k) -> (next [@ocaml.tailcall]) k - | IBlake2b (_, k) -> (next [@ocaml.tailcall]) k - | ISha256 (_, k) -> (next [@ocaml.tailcall]) k - | ISha512 (_, k) -> (next [@ocaml.tailcall]) k - | ISource (_, k) -> (next [@ocaml.tailcall]) k - | ISender (_, k) -> (next [@ocaml.tailcall]) k - | ISelf (_, _, _, k) -> (next [@ocaml.tailcall]) k - | ISelf_address (_, k) -> (next [@ocaml.tailcall]) k - | IAmount (_, k) -> (next [@ocaml.tailcall]) k - | ISapling_empty_state (_, _, k) -> (next [@ocaml.tailcall]) k - | ISapling_verify_update (_, k) -> (next [@ocaml.tailcall]) k - | IDig (_, _, _, k) -> (next [@ocaml.tailcall]) k - | IDug (_, _, _, k) -> (next [@ocaml.tailcall]) k - | IDipn (_, _, _, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 - | IDropn (_, _, _, k) -> (next [@ocaml.tailcall]) k - | IChainId (_, k) -> (next [@ocaml.tailcall]) k - | INever _ -> (return [@ocaml.tailcall]) () - | IVoting_power (_, k) -> (next [@ocaml.tailcall]) k - | ITotal_voting_power (_, k) -> (next [@ocaml.tailcall]) k - | IKeccak (_, k) -> (next [@ocaml.tailcall]) k - | ISha3 (_, k) -> (next [@ocaml.tailcall]) k - | IAdd_bls12_381_g1 (_, k) -> (next [@ocaml.tailcall]) k - | IAdd_bls12_381_g2 (_, k) -> (next [@ocaml.tailcall]) k - | IAdd_bls12_381_fr (_, k) -> (next [@ocaml.tailcall]) k - | IMul_bls12_381_g1 (_, k) -> (next [@ocaml.tailcall]) k - | IMul_bls12_381_g2 (_, k) -> (next [@ocaml.tailcall]) k - | IMul_bls12_381_fr (_, k) -> (next [@ocaml.tailcall]) k - | IMul_bls12_381_z_fr (_, k) -> (next [@ocaml.tailcall]) k - | IMul_bls12_381_fr_z (_, k) -> (next [@ocaml.tailcall]) k - | IInt_bls12_381_fr (_, k) -> (next [@ocaml.tailcall]) k - | INeg_bls12_381_g1 (_, k) -> (next [@ocaml.tailcall]) k - | INeg_bls12_381_g2 (_, k) -> (next [@ocaml.tailcall]) k - | INeg_bls12_381_fr (_, k) -> (next [@ocaml.tailcall]) k - | IPairing_check_bls12_381 (_, k) -> (next [@ocaml.tailcall]) k - | IComb (_, _, _, k) -> (next [@ocaml.tailcall]) k - | IUncomb (_, _, _, k) -> (next [@ocaml.tailcall]) k - | IComb_get (_, _, _, k) -> (next [@ocaml.tailcall]) k - | IComb_set (_, _, _, k) -> (next [@ocaml.tailcall]) k - | IDup_n (_, _, _, k) -> (next [@ocaml.tailcall]) k - | ITicket (_, k) -> (next [@ocaml.tailcall]) k - | IRead_ticket (_, k) -> (next [@ocaml.tailcall]) k - | ISplit_ticket (_, k) -> (next [@ocaml.tailcall]) k - | IJoin_tickets (_, _, k) -> (next [@ocaml.tailcall]) k - | IOpen_chest (_, k) -> (next [@ocaml.tailcall]) k - | IHalt _ -> (return [@ocaml.tailcall]) () - | ILog (_, _, _, k) -> (next [@ocaml.tailcall]) k - in - aux init i (fun accu -> accu) - -type 'a ty_traverse = { - apply : 't. 'a -> 't ty -> 'a; - apply_comparable : 't. 'a -> 't comparable_ty -> 'a; -} - -let (ty_traverse, comparable_ty_traverse) = - let rec aux : - type t ret accu. - accu ty_traverse -> accu -> t comparable_ty -> (accu -> ret) -> ret = - fun f accu ty continue -> - let accu = f.apply_comparable accu ty in - let next2 ty1 ty2 = - (aux [@ocaml.tailcall]) f accu ty1 @@ fun accu -> - (aux [@ocaml.tailcall]) f accu ty2 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - let next ty1 = - (aux [@ocaml.tailcall]) f accu ty1 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - let return () = (continue [@ocaml.tailcall]) accu in - match ty with - | Unit_key _ | Int_key _ | Nat_key _ | Signature_key _ | String_key _ - | Bytes_key _ | Mutez_key _ | Key_hash_key _ | Key_key _ | Timestamp_key _ - | Address_key _ | Bool_key _ | Chain_id_key _ | Never_key _ -> - (return [@ocaml.tailcall]) () - | Pair_key ((ty1, _), (ty2, _), _) -> (next2 [@ocaml.tailcall]) ty1 ty2 - | Union_key ((ty1, _), (ty2, _), _) -> (next2 [@ocaml.tailcall]) ty1 ty2 - | Option_key (ty, _) -> (next [@ocaml.tailcall]) ty - and aux' : - type ret t accu. accu ty_traverse -> accu -> t ty -> (accu -> ret) -> ret - = - fun f accu ty continue -> - let accu = f.apply accu ty in - match (ty : t ty) with - | Unit_t _ | Int_t _ | Nat_t _ | Signature_t _ | String_t _ | Bytes_t _ - | Mutez_t _ | Key_hash_t _ | Key_t _ | Timestamp_t _ | Address_t _ - | Bool_t _ - | Sapling_transaction_t (_, _) - | Sapling_state_t (_, _) - | Operation_t _ | Chain_id_t _ | Never_t _ | Bls12_381_g1_t _ - | Bls12_381_g2_t _ | Bls12_381_fr_t _ -> - (continue [@ocaml.tailcall]) accu - | Ticket_t (cty, _) -> aux f accu cty continue - | Chest_key_t _ | Chest_t _ -> (continue [@ocaml.tailcall]) accu - | Pair_t ((ty1, _, _), (ty2, _, _), _) -> - (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue - | Union_t ((ty1, _), (ty2, _), _) -> - (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue - | Lambda_t (ty1, ty2, _) -> - (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue - | Option_t (ty1, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue - | List_t (ty1, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue - | Set_t (cty, _) -> (aux [@ocaml.tailcall]) f accu cty @@ continue - | Map_t (cty, ty1, _) -> - (aux [@ocaml.tailcall]) f accu cty @@ fun accu -> - (next' [@ocaml.tailcall]) f accu ty1 continue - | Big_map_t (cty, ty1, _) -> - (aux [@ocaml.tailcall]) f accu cty @@ fun accu -> - (next' [@ocaml.tailcall]) f accu ty1 continue - | Contract_t (ty1, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue - and next2' : - type a b ret accu. - accu ty_traverse -> accu -> a ty -> b ty -> (accu -> ret) -> ret = - fun f accu ty1 ty2 continue -> - (aux' [@ocaml.tailcall]) f accu ty1 @@ fun accu -> - (aux' [@ocaml.tailcall]) f accu ty2 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - and next' : - type a ret accu. accu ty_traverse -> accu -> a ty -> (accu -> ret) -> ret - = - fun f accu ty1 continue -> - (aux' [@ocaml.tailcall]) f accu ty1 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - ( (fun ty init f -> aux' f init ty (fun accu -> accu)), - fun cty init f -> aux f init cty (fun accu -> accu) ) - -type 'accu stack_ty_traverse = { - apply : 'ty 's. 'accu -> ('ty, 's) stack_ty -> 'accu; -} - -let stack_ty_traverse (type a t) (sty : (a, t) stack_ty) init f = - let rec aux : type b u. 'accu -> (b, u) stack_ty -> 'accu = - fun accu sty -> - match sty with - | Bot_t -> f.apply accu sty - | Item_t (_, sty', _) -> aux (f.apply accu sty) sty' - in - aux init sty - -type 'a value_traverse = { - apply : 't. 'a -> 't ty -> 't -> 'a; - apply_comparable : 't. 'a -> 't comparable_ty -> 't -> 'a; -} - -let value_traverse (type t) (ty : (t ty, t comparable_ty) union) (x : t) init f - = - let rec aux : type ret t. 'accu -> t ty -> t -> ('accu -> ret) -> ret = - fun accu ty x continue -> - let accu = f.apply accu ty x in - let next2 ty1 ty2 x1 x2 = - (aux [@ocaml.tailcall]) accu ty1 x1 @@ fun accu -> - (aux [@ocaml.tailcall]) accu ty2 x2 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - let next ty1 x1 = - (aux [@ocaml.tailcall]) accu ty1 x1 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - let return () = (continue [@ocaml.tailcall]) accu in - let rec on_list ty' accu = function - | [] -> (continue [@ocaml.tailcall]) accu - | x :: xs -> - (aux [@ocaml.tailcall]) accu ty' x @@ fun accu -> - (on_list [@ocaml.tailcall]) ty' accu xs - in - match ty with - | Unit_t _ | Int_t _ | Nat_t _ | Signature_t _ | String_t _ | Bytes_t _ - | Mutez_t _ | Key_hash_t _ | Key_t _ | Timestamp_t _ | Address_t _ - | Bool_t _ - | Sapling_transaction_t (_, _) - | Sapling_state_t (_, _) - | Operation_t _ | Chain_id_t _ | Never_t _ | Bls12_381_g1_t _ - | Bls12_381_g2_t _ | Bls12_381_fr_t _ | Chest_key_t _ | Chest_t _ - | Lambda_t (_, _, _) -> - (return [@ocaml.tailcall]) () - | Pair_t ((ty1, _, _), (ty2, _, _), _) -> - (next2 [@ocaml.tailcall]) ty1 ty2 (fst x) (snd x) - | Union_t ((ty1, _), (ty2, _), _) -> ( - match x with - | L l -> (next [@ocaml.tailcall]) ty1 l - | R r -> (next [@ocaml.tailcall]) ty2 r) - | Option_t (ty, _) -> ( - match x with - | None -> return () - | Some v -> (next [@ocaml.tailcall]) ty v) - | Ticket_t (cty, _) -> (aux' [@ocaml.tailcall]) accu cty x.contents continue - | List_t (ty', _) -> on_list ty' accu x.elements - | Map_t (kty, ty', _) -> - let module M = (val x) in - let bindings = M.OPS.fold (fun k v bs -> (k, v) :: bs) M.boxed [] in - on_bindings accu kty ty' continue bindings - | Set_t (ty', _) -> - let module M = (val x) in - let elements = M.OPS.fold (fun x s -> x :: s) M.boxed [] in - on_list' accu ty' elements continue - | Big_map_t (_, _, _) -> - (* For big maps, there is no obvious recursion scheme so we - delegate this case to the client. *) - (return [@ocaml.tailcall]) () - | Contract_t (_, _) -> (return [@ocaml.tailcall]) () - and on_list' : - type ret t. 'accu -> t comparable_ty -> t list -> ('accu -> ret) -> ret = - fun accu ty' xs continue -> - match xs with - | [] -> (continue [@ocaml.tailcall]) accu - | x :: xs -> - (aux' [@ocaml.tailcall]) accu ty' x @@ fun accu -> - (on_list' [@ocaml.tailcall]) accu ty' xs continue - and on_bindings : - type ret k v. - 'accu -> k comparable_ty -> v ty -> ('accu -> ret) -> (k * v) list -> ret - = - fun accu kty ty' continue xs -> - match xs with - | [] -> (continue [@ocaml.tailcall]) accu - | (k, v) :: xs -> - (aux' [@ocaml.tailcall]) accu kty k @@ fun accu -> - (aux [@ocaml.tailcall]) accu ty' v @@ fun accu -> - (on_bindings [@ocaml.tailcall]) accu kty ty' continue xs - and aux' : type ret t. 'accu -> t comparable_ty -> t -> ('accu -> ret) -> ret - = - fun accu ty x continue -> - let accu = f.apply_comparable accu ty x in - let next2 ty1 ty2 x1 x2 = - (aux' [@ocaml.tailcall]) accu ty1 x1 @@ fun accu -> - (aux' [@ocaml.tailcall]) accu ty2 x2 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - let next ty1 x1 = - (aux' [@ocaml.tailcall]) accu ty1 x1 @@ fun accu -> - (continue [@ocaml.tailcall]) accu - in - let return () = (continue [@ocaml.tailcall]) accu in - match ty with - | Unit_key _ | Int_key _ | Nat_key _ | Signature_key _ | String_key _ - | Bytes_key _ | Mutez_key _ | Key_hash_key _ | Key_key _ | Timestamp_key _ - | Address_key _ | Bool_key _ | Chain_id_key _ | Never_key _ -> - (return [@ocaml.tailcall]) () - | Pair_key ((ty1, _), (ty2, _), _) -> - (next2 [@ocaml.tailcall]) ty1 ty2 (fst x) (snd x) - | Union_key ((ty1, _), (ty2, _), _) -> ( - match x with - | L l -> (next [@ocaml.tailcall]) ty1 l - | R r -> (next [@ocaml.tailcall]) ty2 r) - | Option_key (ty, _) -> ( - match x with - | None -> (return [@ocaml.tailcall]) () - | Some v -> (next [@ocaml.tailcall]) ty v) - in - match ty with - | L ty -> aux init ty x (fun accu -> accu) - | R cty -> aux' init cty x (fun accu -> accu) - [@@coq_axiom_with_reason "local mutually recursive definition not handled"] - -let stack_top_ty : type a b s. (a, b * s) stack_ty -> a ty = function - | Item_t (ty, _, _) -> ty diff --git a/src/proto_012_Psithaca/lib_protocol/script_typed_ir.mli b/src/proto_012_Psithaca/lib_protocol/script_typed_ir.mli deleted file mode 100644 index 5bb1a5814352..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_typed_ir.mli +++ /dev/null @@ -1,1594 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Script_int -open Script_ir_annot - -type step_constants = { - source : Contract.t; - payer : Contract.t; - self : Contract.t; - amount : Tez.t; - chain_id : Chain_id.t; - now : Script_timestamp.t; - level : Script_int.n Script_int.num; -} - -(* Preliminary definitions. *) - -type never = | - -type address = Contract.t * string - -type ('a, 'b) pair = 'a * 'b - -type ('a, 'b) union = L of 'a | R of 'b - -type operation = packed_internal_operation * Lazy_storage.diffs option - -type 'a ticket = {ticketer : Contract.t; contents : 'a; amount : n num} - -type empty_cell = EmptyCell - -type end_of_stack = empty_cell * empty_cell - -module Type_size : sig - type 'a t - - val merge : 'a t -> 'b t -> 'a t tzresult - - val to_int : 'a t -> Saturation_repr.mul_safe Saturation_repr.t -end - -type 'a ty_metadata = {annot : type_annot option; size : 'a Type_size.t} - -type _ comparable_ty = - | Unit_key : unit ty_metadata -> unit comparable_ty - | Never_key : never ty_metadata -> never comparable_ty - | Int_key : z num ty_metadata -> z num comparable_ty - | Nat_key : n num ty_metadata -> n num comparable_ty - | Signature_key : signature ty_metadata -> signature comparable_ty - | String_key : Script_string.t ty_metadata -> Script_string.t comparable_ty - | Bytes_key : Bytes.t ty_metadata -> Bytes.t comparable_ty - | Mutez_key : Tez.t ty_metadata -> Tez.t comparable_ty - | Bool_key : bool ty_metadata -> bool comparable_ty - | Key_hash_key : public_key_hash ty_metadata -> public_key_hash comparable_ty - | Key_key : public_key ty_metadata -> public_key comparable_ty - | Timestamp_key : - Script_timestamp.t ty_metadata - -> Script_timestamp.t comparable_ty - | Chain_id_key : Chain_id.t ty_metadata -> Chain_id.t comparable_ty - | Address_key : address ty_metadata -> address comparable_ty - | Pair_key : - ('a comparable_ty * field_annot option) - * ('b comparable_ty * field_annot option) - * ('a, 'b) pair ty_metadata - -> ('a, 'b) pair comparable_ty - | Union_key : - ('a comparable_ty * field_annot option) - * ('b comparable_ty * field_annot option) - * ('a, 'b) union ty_metadata - -> ('a, 'b) union comparable_ty - | Option_key : - 'v comparable_ty * 'v option ty_metadata - -> 'v option comparable_ty - -val unit_key : annot:type_annot option -> unit comparable_ty - -val never_key : annot:type_annot option -> never comparable_ty - -val int_key : annot:type_annot option -> z num comparable_ty - -val nat_key : annot:type_annot option -> n num comparable_ty - -val signature_key : annot:type_annot option -> signature comparable_ty - -val string_key : annot:type_annot option -> Script_string.t comparable_ty - -val bytes_key : annot:type_annot option -> Bytes.t comparable_ty - -val mutez_key : annot:type_annot option -> Tez.t comparable_ty - -val bool_key : annot:type_annot option -> bool comparable_ty - -val key_hash_key : annot:type_annot option -> public_key_hash comparable_ty - -val key_key : annot:type_annot option -> public_key comparable_ty - -val timestamp_key : annot:type_annot option -> Script_timestamp.t comparable_ty - -val chain_id_key : annot:type_annot option -> Chain_id.t comparable_ty - -val address_key : annot:type_annot option -> address comparable_ty - -val pair_key : - Script.location -> - 'a comparable_ty * field_annot option -> - 'b comparable_ty * field_annot option -> - annot:type_annot option -> - ('a, 'b) pair comparable_ty tzresult - -val pair_3_key : - Script.location -> - 'a comparable_ty * field_annot option -> - 'b comparable_ty * field_annot option -> - 'c comparable_ty * field_annot option -> - ('a, ('b, 'c) pair) pair comparable_ty tzresult - -val union_key : - Script.location -> - 'a comparable_ty * field_annot option -> - 'b comparable_ty * field_annot option -> - annot:type_annot option -> - ('a, 'b) union comparable_ty tzresult - -val option_key : - Script.location -> - 'v comparable_ty -> - annot:type_annot option -> - 'v option comparable_ty tzresult - -module type Boxed_set_OPS = sig - type t - - type elt - - val empty : t - - val add : elt -> t -> t - - val mem : elt -> t -> bool - - val remove : elt -> t -> t - - val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a -end - -module type Boxed_set = sig - type elt - - val elt_ty : elt comparable_ty - - module OPS : Boxed_set_OPS with type elt = elt - - val boxed : OPS.t - - val size : int -end - -type 'elt set = (module Boxed_set with type elt = 'elt) - -module type Boxed_map_OPS = sig - type t - - type key - - type value - - val empty : t - - val add : key -> value -> t -> t - - val remove : key -> t -> t - - val find : key -> t -> value option - - val fold : (key -> value -> 'a -> 'a) -> t -> 'a -> 'a -end - -module type Boxed_map = sig - type key - - type value - - val key_ty : key comparable_ty - - module OPS : Boxed_map_OPS with type key = key and type value = value - - val boxed : OPS.t - - val size : int -end - -type ('key, 'value) map = - (module Boxed_map with type key = 'key and type value = 'value) - -module Big_map_overlay : Map.S with type key = Script_expr_hash.t - -type ('key, 'value) big_map_overlay = { - map : ('key * 'value option) Big_map_overlay.t; - size : int; -} - -type 'elt boxed_list = {elements : 'elt list; length : int} - -module SMap : Map.S with type key = Script_string.t - -type view = { - input_ty : Script.node; - output_ty : Script.node; - view_code : Script.node; -} - -type ('arg, 'storage) script = { - code : (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; - arg_type : 'arg ty; - storage : 'storage; - storage_type : 'storage ty; - views : view SMap.t; - root_name : field_annot option; - code_size : Cache_memory_helpers.sint; -} - -(* ---- Instructions --------------------------------------------------------*) - -(* - - The instructions of Michelson are represented in the following - Generalized Algebraic Datatypes. - - There are three important aspects in that type declaration. - - First, we follow a tagless approach for values: they are directly - represented as OCaml values. This reduces the computational cost of - interpretation because there is no need to check the shape of a - value before applying an operation to it. To achieve that, the GADT - encodes the typing rules of the Michelson programming - language. This static information is sufficient for the typechecker - to justify the absence of runtime checks. As a bonus, it also - ensures that well-typed Michelson programs cannot go wrong: if the - interpreter typechecks then we have the static guarantee that no - stack underflow or type error can occur at runtime. - - Second, we maintain the invariant that the stack type always has a - distinguished topmost element. This invariant is important to - implement the stack as an accumulator followed by a linked list of - cells, a so-called A-Stack. This representation is considered in - the literature[1] as an efficient representation of the stack for a - stack-based abstract machine, mainly because this opens the - opportunity for the accumulator to be stored in a hardware - register. In the GADT, this invariant is encoded by representing - the stack type using two parameters instead of one: the first one - is the type of the accumulator while the second is the type of the - rest of the stack. - - Third, in this representation, each instruction embeds its - potential successor instructions in the control flow. This design - choice permits an efficient implementation of the continuation - stack in the interpreter. Assigning a precise type to this kind of - instruction which is a cell in a linked list of instructions is - similar to the typing of delimited continuations: we need to give a - type to the stack ['before] the execution of the instruction, a - type to the stack ['after] the execution of the instruction and - before the execution of the next, and a type for the [`result]ing - stack type after the execution of the whole chain of instructions. - - Combining these three aspects, the type [kinstr] needs four - parameters: - - ('before_top, 'before, 'result_top, 'result) kinstr - - Notice that we could have chosen to only give two parameters to - [kinstr] by manually enforcing each argument to be a pair but this - is error-prone: with four parameters, this constraint is enforced - by the arity of the type constructor itself. - - Hence, an instruction which has a successor instruction enjoys a - type of the form: - - ... * ('after_top, 'after, 'result_top, 'result) kinstr * ... -> - ('before_top, 'before, 'result_top, 'result) kinstr - - where ['before_top] and ['before] are the types of the stack top - and rest before the instruction chain, ['after_top] and ['after] - are the types of the stack top and rest after the instruction - chain, and ['result_top] and ['result] are the types of the stack - top and rest after the instruction chain. The [IHalt] instruction - ends a sequence of instructions and has no successor, as shown by - its type: - - IHalt : ('a, 's) kinfo -> ('a, 's, 'a, 's) kinstr - - Each instruction is decorated by some metadata (typically to hold - locations). The type for these metadata is [kinfo]: such a value is - only used for logging and error reporting and has no impact on the - operational semantics. - - Notations: - ---------- - - In the following declaration, we use 'a, 'b, 'c, 'd, ... to assign - types to stack cell contents while we use 's, 't, 'u, 'v, ... to - assign types to stacks. - - The types for the final result and stack rest of a whole sequence - of instructions are written 'r and 'f (standing for "result" and - "final stack rest", respectively). - - Instructions for internal execution steps - ========================================= - - Some instructions encoded in the following type are not present in the - source language. They only appear during evaluation to account for - intermediate execution steps. Indeed, since the interpreter follows - a small-step style, it is sometimes necessary to decompose a - source-level instruction (e.g. List_map) into several instructions - with smaller steps. This technique seems required to get an - efficient tail-recursive interpreter. - - References - ========== - [1]: http://www.complang.tuwien.ac.at/projects/interpreters.html - - *) -and ('before_top, 'before, 'result_top, 'result) kinstr = - (* - Stack - ----- - *) - | IDrop : - ('a, 'b * 's) kinfo * ('b, 's, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IDup : - ('a, 's) kinfo * ('a, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISwap : - ('a, 'b * 's) kinfo * ('b, 'a * 's, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IConst : - ('a, 's) kinfo * 'ty * ('ty, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - (* - Pairs - ----- - *) - | ICons_pair : - ('a, 'b * 's) kinfo * ('a * 'b, 's, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | ICar : - ('a * 'b, 's) kinfo * ('a, 's, 'r, 'f) kinstr - -> ('a * 'b, 's, 'r, 'f) kinstr - | ICdr : - ('a * 'b, 's) kinfo * ('b, 's, 'r, 'f) kinstr - -> ('a * 'b, 's, 'r, 'f) kinstr - | IUnpair : - ('a * 'b, 's) kinfo * ('a, 'b * 's, 'r, 'f) kinstr - -> ('a * 'b, 's, 'r, 'f) kinstr - (* - Options - ------- - *) - | ICons_some : - ('v, 's) kinfo * ('v option, 's, 'r, 'f) kinstr - -> ('v, 's, 'r, 'f) kinstr - | ICons_none : - ('a, 's) kinfo * ('b option, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IIf_none : { - kinfo : ('a option, 'b * 's) kinfo; - branch_if_none : ('b, 's, 'c, 't) kinstr; - branch_if_some : ('a, 'b * 's, 'c, 't) kinstr; - k : ('c, 't, 'r, 'f) kinstr; - } - -> ('a option, 'b * 's, 'r, 'f) kinstr - | IOpt_map : { - kinfo : ('a option, 's) kinfo; - body : ('a, 's, 'b, 's) kinstr; - k : ('b option, 's, 'c, 't) kinstr; - } - -> ('a option, 's, 'c, 't) kinstr - (* - Unions - ------ - *) - | ICons_left : - ('a, 's) kinfo * (('a, 'b) union, 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ICons_right : - ('b, 's) kinfo * (('a, 'b) union, 's, 'r, 'f) kinstr - -> ('b, 's, 'r, 'f) kinstr - | IIf_left : { - kinfo : (('a, 'b) union, 's) kinfo; - branch_if_left : ('a, 's, 'c, 't) kinstr; - branch_if_right : ('b, 's, 'c, 't) kinstr; - k : ('c, 't, 'r, 'f) kinstr; - } - -> (('a, 'b) union, 's, 'r, 'f) kinstr - (* - Lists - ----- - *) - | ICons_list : - ('a, 'a boxed_list * 's) kinfo * ('a boxed_list, 's, 'r, 'f) kinstr - -> ('a, 'a boxed_list * 's, 'r, 'f) kinstr - | INil : - ('a, 's) kinfo * ('b boxed_list, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IIf_cons : { - kinfo : ('a boxed_list, 'b * 's) kinfo; - branch_if_cons : ('a, 'a boxed_list * ('b * 's), 'c, 't) kinstr; - branch_if_nil : ('b, 's, 'c, 't) kinstr; - k : ('c, 't, 'r, 'f) kinstr; - } - -> ('a boxed_list, 'b * 's, 'r, 'f) kinstr - | IList_map : - ('a boxed_list, 'c * 's) kinfo - * ('a, 'c * 's, 'b, 'c * 's) kinstr - * ('b boxed_list, 'c * 's, 'r, 'f) kinstr - -> ('a boxed_list, 'c * 's, 'r, 'f) kinstr - | IList_iter : - ('a boxed_list, 'b * 's) kinfo - * ('a, 'b * 's, 'b, 's) kinstr - * ('b, 's, 'r, 'f) kinstr - -> ('a boxed_list, 'b * 's, 'r, 'f) kinstr - | IList_size : - ('a boxed_list, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> ('a boxed_list, 's, 'r, 'f) kinstr - (* - Sets - ---- - *) - | IEmpty_set : - ('a, 's) kinfo * 'b comparable_ty * ('b set, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISet_iter : - ('a set, 'b * 's) kinfo - * ('a, 'b * 's, 'b, 's) kinstr - * ('b, 's, 'r, 'f) kinstr - -> ('a set, 'b * 's, 'r, 'f) kinstr - | ISet_mem : - ('a, 'a set * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> ('a, 'a set * 's, 'r, 'f) kinstr - | ISet_update : - ('a, bool * ('a set * 's)) kinfo * ('a set, 's, 'r, 'f) kinstr - -> ('a, bool * ('a set * 's), 'r, 'f) kinstr - | ISet_size : - ('a set, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> ('a set, 's, 'r, 'f) kinstr - (* - Maps - ---- - *) - | IEmpty_map : - ('a, 's) kinfo * 'b comparable_ty * (('b, 'c) map, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IMap_map : - (('a, 'b) map, 'd * 's) kinfo - * ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr - * (('a, 'c) map, 'd * 's, 'r, 'f) kinstr - -> (('a, 'b) map, 'd * 's, 'r, 'f) kinstr - | IMap_iter : - (('a, 'b) map, 'c * 's) kinfo - * ('a * 'b, 'c * 's, 'c, 's) kinstr - * ('c, 's, 'r, 'f) kinstr - -> (('a, 'b) map, 'c * 's, 'r, 'f) kinstr - | IMap_mem : - ('a, ('a, 'b) map * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) map * 's, 'r, 'f) kinstr - | IMap_get : - ('a, ('a, 'b) map * 's) kinfo * ('b option, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) map * 's, 'r, 'f) kinstr - | IMap_update : - ('a, 'b option * (('a, 'b) map * 's)) kinfo - * (('a, 'b) map, 's, 'r, 'f) kinstr - -> ('a, 'b option * (('a, 'b) map * 's), 'r, 'f) kinstr - | IMap_get_and_update : - ('a, 'b option * (('a, 'b) map * 's)) kinfo - * ('b option, ('a, 'b) map * 's, 'r, 'f) kinstr - -> ('a, 'b option * (('a, 'b) map * 's), 'r, 'f) kinstr - | IMap_size : - (('a, 'b) map, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (('a, 'b) map, 's, 'r, 'f) kinstr - (* - Big maps - -------- - *) - | IEmpty_big_map : - ('a, 's) kinfo - * 'b comparable_ty - * 'c ty - * (('b, 'c) big_map, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IBig_map_mem : - ('a, ('a, 'b) big_map * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) big_map * 's, 'r, 'f) kinstr - | IBig_map_get : - ('a, ('a, 'b) big_map * 's) kinfo * ('b option, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) big_map * 's, 'r, 'f) kinstr - | IBig_map_update : - ('a, 'b option * (('a, 'b) big_map * 's)) kinfo - * (('a, 'b) big_map, 's, 'r, 'f) kinstr - -> ('a, 'b option * (('a, 'b) big_map * 's), 'r, 'f) kinstr - | IBig_map_get_and_update : - ('a, 'b option * (('a, 'b) big_map * 's)) kinfo - * ('b option, ('a, 'b) big_map * 's, 'r, 'f) kinstr - -> ('a, 'b option * (('a, 'b) big_map * 's), 'r, 'f) kinstr - (* - Strings - ------- - *) - | IConcat_string : - (Script_string.t boxed_list, 's) kinfo - * (Script_string.t, 's, 'r, 'f) kinstr - -> (Script_string.t boxed_list, 's, 'r, 'f) kinstr - | IConcat_string_pair : - (Script_string.t, Script_string.t * 's) kinfo - * (Script_string.t, 's, 'r, 'f) kinstr - -> (Script_string.t, Script_string.t * 's, 'r, 'f) kinstr - | ISlice_string : - (n num, n num * (Script_string.t * 's)) kinfo - * (Script_string.t option, 's, 'r, 'f) kinstr - -> (n num, n num * (Script_string.t * 's), 'r, 'f) kinstr - | IString_size : - (Script_string.t, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (Script_string.t, 's, 'r, 'f) kinstr - (* - Bytes - ----- - *) - | IConcat_bytes : - (bytes boxed_list, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes boxed_list, 's, 'r, 'f) kinstr - | IConcat_bytes_pair : - (bytes, bytes * 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, bytes * 's, 'r, 'f) kinstr - | ISlice_bytes : - (n num, n num * (bytes * 's)) kinfo * (bytes option, 's, 'r, 'f) kinstr - -> (n num, n num * (bytes * 's), 'r, 'f) kinstr - | IBytes_size : - (bytes, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - (* - Timestamps - ---------- - *) - | IAdd_seconds_to_timestamp : - (z num, Script_timestamp.t * 's) kinfo - * (Script_timestamp.t, 's, 'r, 'f) kinstr - -> (z num, Script_timestamp.t * 's, 'r, 'f) kinstr - | IAdd_timestamp_to_seconds : - (Script_timestamp.t, z num * 's) kinfo - * (Script_timestamp.t, 's, 'r, 'f) kinstr - -> (Script_timestamp.t, z num * 's, 'r, 'f) kinstr - | ISub_timestamp_seconds : - (Script_timestamp.t, z num * 's) kinfo - * (Script_timestamp.t, 's, 'r, 'f) kinstr - -> (Script_timestamp.t, z num * 's, 'r, 'f) kinstr - | IDiff_timestamps : - (Script_timestamp.t, Script_timestamp.t * 's) kinfo - * (z num, 's, 'r, 'f) kinstr - -> (Script_timestamp.t, Script_timestamp.t * 's, 'r, 'f) kinstr - (* - Tez - --- - *) - | IAdd_tez : - (Tez.t, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr - -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr - | ISub_tez : - (Tez.t, Tez.t * 's) kinfo * (Tez.t option, 's, 'r, 'f) kinstr - -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr - | ISub_tez_legacy : - (Tez.t, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr - -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr - | IMul_teznat : - (Tez.t, n num * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr - -> (Tez.t, n num * 's, 'r, 'f) kinstr - | IMul_nattez : - (n num, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr - -> (n num, Tez.t * 's, 'r, 'f) kinstr - | IEdiv_teznat : - (Tez.t, n num * 's) kinfo - * ((Tez.t, Tez.t) pair option, 's, 'r, 'f) kinstr - -> (Tez.t, n num * 's, 'r, 'f) kinstr - | IEdiv_tez : - (Tez.t, Tez.t * 's) kinfo - * ((n num, Tez.t) pair option, 's, 'r, 'f) kinstr - -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr - (* - Booleans - -------- - *) - | IOr : - (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (bool, bool * 's, 'r, 'f) kinstr - | IAnd : - (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (bool, bool * 's, 'r, 'f) kinstr - | IXor : - (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (bool, bool * 's, 'r, 'f) kinstr - | INot : - (bool, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (bool, 's, 'r, 'f) kinstr - (* - Integers - -------- - *) - | IIs_nat : - (z num, 's) kinfo * (n num option, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | INeg : - ('a num, 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 's, 'r, 'f) kinstr - | IAbs_int : - (z num, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | IInt_nat : - (n num, 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> (n num, 's, 'r, 'f) kinstr - | IAdd_int : - ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 'b num * 's, 'r, 'f) kinstr - | IAdd_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | ISub_int : - ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 'b num * 's, 'r, 'f) kinstr - | IMul_int : - ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 'b num * 's, 'r, 'f) kinstr - | IMul_nat : - (n num, 'a num * 's) kinfo * ('a num, 's, 'r, 'f) kinstr - -> (n num, 'a num * 's, 'r, 'f) kinstr - | IEdiv_int : - ('a num, 'b num * 's) kinfo - * ((z num, n num) pair option, 's, 'r, 'f) kinstr - -> ('a num, 'b num * 's, 'r, 'f) kinstr - | IEdiv_nat : - (n num, 'a num * 's) kinfo - * (('a num, n num) pair option, 's, 'r, 'f) kinstr - -> (n num, 'a num * 's, 'r, 'f) kinstr - | ILsl_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | ILsr_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | IOr_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | IAnd_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | IAnd_int_nat : - (z num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (z num, n num * 's, 'r, 'f) kinstr - | IXor_nat : - (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (n num, n num * 's, 'r, 'f) kinstr - | INot_int : - ('a num, 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> ('a num, 's, 'r, 'f) kinstr - (* - Control - ------- - *) - | IIf : { - kinfo : (bool, 'a * 's) kinfo; - branch_if_true : ('a, 's, 'b, 'u) kinstr; - branch_if_false : ('a, 's, 'b, 'u) kinstr; - k : ('b, 'u, 'r, 'f) kinstr; - } - -> (bool, 'a * 's, 'r, 'f) kinstr - | ILoop : - (bool, 'a * 's) kinfo - * ('a, 's, bool, 'a * 's) kinstr - * ('a, 's, 'r, 'f) kinstr - -> (bool, 'a * 's, 'r, 'f) kinstr - | ILoop_left : - (('a, 'b) union, 's) kinfo - * ('a, 's, ('a, 'b) union, 's) kinstr - * ('b, 's, 'r, 'f) kinstr - -> (('a, 'b) union, 's, 'r, 'f) kinstr - | IDip : - ('a, 'b * 's) kinfo - * ('b, 's, 'c, 't) kinstr - * ('a, 'c * 't, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IExec : - ('a, ('a, 'b) lambda * 's) kinfo * ('b, 's, 'r, 'f) kinstr - -> ('a, ('a, 'b) lambda * 's, 'r, 'f) kinstr - | IApply : - ('a, ('a * 'b, 'c) lambda * 's) kinfo - * 'a ty - * (('b, 'c) lambda, 's, 'r, 'f) kinstr - -> ('a, ('a * 'b, 'c) lambda * 's, 'r, 'f) kinstr - | ILambda : - ('a, 's) kinfo - * ('b, 'c) lambda - * (('b, 'c) lambda, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IFailwith : - ('a, 's) kinfo * Script.location * 'a ty - -> ('a, 's, 'r, 'f) kinstr - (* - Comparison - ---------- - *) - | ICompare : - ('a, 'a * 's) kinfo * 'a comparable_ty * (z num, 's, 'r, 'f) kinstr - -> ('a, 'a * 's, 'r, 'f) kinstr - (* - Comparators - ----------- - *) - | IEq : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | INeq : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | ILt : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | IGt : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | ILe : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - | IGe : - (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr - -> (z num, 's, 'r, 'f) kinstr - (* - Protocol - -------- - *) - | IAddress : - ('a typed_contract, 's) kinfo * (address, 's, 'r, 'f) kinstr - -> ('a typed_contract, 's, 'r, 'f) kinstr - | IContract : - (address, 's) kinfo - * 'a ty - * string - * ('a typed_contract option, 's, 'r, 'f) kinstr - -> (address, 's, 'r, 'f) kinstr - | IView : - ('a, address * 's) kinfo - * ('a, 'b) view_signature - * ('b option, 's, 'r, 'f) kinstr - -> ('a, address * 's, 'r, 'f) kinstr - | ITransfer_tokens : - ('a, Tez.t * ('a typed_contract * 's)) kinfo - * (operation, 's, 'r, 'f) kinstr - -> ('a, Tez.t * ('a typed_contract * 's), 'r, 'f) kinstr - | IImplicit_account : - (public_key_hash, 's) kinfo * (unit typed_contract, 's, 'r, 'f) kinstr - -> (public_key_hash, 's, 'r, 'f) kinstr - | ICreate_contract : { - kinfo : (public_key_hash option, Tez.t * ('a * 's)) kinfo; - storage_type : 'a ty; - arg_type : 'b ty; - lambda : ('b * 'a, operation boxed_list * 'a) lambda; - views : view SMap.t; - root_name : field_annot option; - k : (operation, address * 's, 'r, 'f) kinstr; - } - -> (public_key_hash option, Tez.t * ('a * 's), 'r, 'f) kinstr - | ISet_delegate : - (public_key_hash option, 's) kinfo * (operation, 's, 'r, 'f) kinstr - -> (public_key_hash option, 's, 'r, 'f) kinstr - | INow : - ('a, 's) kinfo * (Script_timestamp.t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IBalance : - ('a, 's) kinfo * (Tez.t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ILevel : - ('a, 's) kinfo * (n num, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ICheck_signature : - (public_key, signature * (bytes * 's)) kinfo * (bool, 's, 'r, 'f) kinstr - -> (public_key, signature * (bytes * 's), 'r, 'f) kinstr - | IHash_key : - (public_key, 's) kinfo * (public_key_hash, 's, 'r, 'f) kinstr - -> (public_key, 's, 'r, 'f) kinstr - | IPack : - ('a, 's) kinfo * 'a ty * (bytes, 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IUnpack : - (bytes, 's) kinfo * 'a ty * ('a option, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | IBlake2b : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | ISha256 : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | ISha512 : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | ISource : - ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISender : - ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISelf : - ('a, 's) kinfo - * 'b ty - * string - * ('b typed_contract, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISelf_address : - ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IAmount : - ('a, 's) kinfo * (Tez.t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ISapling_empty_state : - ('a, 's) kinfo - * Sapling.Memo_size.t - * (Sapling.state, 'a * 's, 'b, 'f) kinstr - -> ('a, 's, 'b, 'f) kinstr - | ISapling_verify_update : - (Sapling.transaction, Sapling.state * 's) kinfo - * ((z num, Sapling.state) pair option, 's, 'r, 'f) kinstr - -> (Sapling.transaction, Sapling.state * 's, 'r, 'f) kinstr - | IDig : - ('a, 's) kinfo - (* - There is a prefix of length [n] common to the input stack - of type ['a * 's] and an intermediary stack of type ['d * 'u]. - *) - * int - (* - Under this common prefix, the input stack has type ['b * 'c * 't] and - the intermediary stack type ['c * 't] because we removed the ['b] from - the input stack. This value of type ['b] is pushed on top of the - stack passed to the continuation. - *) - * ('b, 'c * 't, 'c, 't, 'a, 's, 'd, 'u) stack_prefix_preservation_witness - * ('b, 'd * 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IDug : - ('a, 'b * 's) kinfo - (* - The input stack has type ['a * 'b * 's]. - - There is a prefix of length [n] common to its substack - of type ['b * 's] and the output stack of type ['d * 'u]. - *) - * int - (* - Under this common prefix, the first stack has type ['c * 't] - and the second has type ['a * 'c * 't] because we have pushed - the topmost element of this input stack under the common prefix. - *) - * ('c, 't, 'a, 'c * 't, 'b, 's, 'd, 'u) stack_prefix_preservation_witness - * ('d, 'u, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IDipn : - ('a, 's) kinfo - (* - The body of Dipn is applied under a prefix of size [n]... - *) - * int - (* - ... the relation between the types of the input and output stacks - is characterized by the following witness. - (See forthcoming comments about [stack_prefix_preservation_witness].) - *) - * ('c, 't, 'd, 'v, 'a, 's, 'b, 'u) stack_prefix_preservation_witness - * ('c, 't, 'd, 'v) kinstr - * ('b, 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IDropn : - ('a, 's) kinfo - (* - The input stack enjoys a prefix of length [n]... - *) - * int - (* - ... and the following value witnesses that under this prefix - the stack has type ['b * 'u]. - *) - * ('b, 'u, 'b, 'u, 'a, 's, 'a, 's) stack_prefix_preservation_witness - (* - This stack is passed to the continuation since we drop the - entire prefix. - *) - * ('b, 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IChainId : - ('a, 's) kinfo * (Chain_id.t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | INever : (never, 's) kinfo -> (never, 's, 'r, 'f) kinstr - | IVoting_power : - (public_key_hash, 's) kinfo * (n num, 's, 'r, 'f) kinstr - -> (public_key_hash, 's, 'r, 'f) kinstr - | ITotal_voting_power : - ('a, 's) kinfo * (n num, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IKeccak : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | ISha3 : - (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr - -> (bytes, 's, 'r, 'f) kinstr - | IAdd_bls12_381_g1 : - (Bls12_381.G1.t, Bls12_381.G1.t * 's) kinfo - * (Bls12_381.G1.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G1.t, Bls12_381.G1.t * 's, 'r, 'f) kinstr - | IAdd_bls12_381_g2 : - (Bls12_381.G2.t, Bls12_381.G2.t * 's) kinfo - * (Bls12_381.G2.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G2.t, Bls12_381.G2.t * 's, 'r, 'f) kinstr - | IAdd_bls12_381_fr : - (Bls12_381.Fr.t, Bls12_381.Fr.t * 's) kinfo - * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IMul_bls12_381_g1 : - (Bls12_381.G1.t, Bls12_381.Fr.t * 's) kinfo - * (Bls12_381.G1.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G1.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IMul_bls12_381_g2 : - (Bls12_381.G2.t, Bls12_381.Fr.t * 's) kinfo - * (Bls12_381.G2.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G2.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IMul_bls12_381_fr : - (Bls12_381.Fr.t, Bls12_381.Fr.t * 's) kinfo - * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IMul_bls12_381_z_fr : - (Bls12_381.Fr.t, 'a num * 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, 'a num * 's, 'r, 'f) kinstr - | IMul_bls12_381_fr_z : - ('a num, Bls12_381.Fr.t * 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> ('a num, Bls12_381.Fr.t * 's, 'r, 'f) kinstr - | IInt_bls12_381_fr : - (Bls12_381.Fr.t, 's) kinfo * (z num, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - | INeg_bls12_381_g1 : - (Bls12_381.G1.t, 's) kinfo * (Bls12_381.G1.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G1.t, 's, 'r, 'f) kinstr - | INeg_bls12_381_g2 : - (Bls12_381.G2.t, 's) kinfo * (Bls12_381.G2.t, 's, 'r, 'f) kinstr - -> (Bls12_381.G2.t, 's, 'r, 'f) kinstr - | INeg_bls12_381_fr : - (Bls12_381.Fr.t, 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - -> (Bls12_381.Fr.t, 's, 'r, 'f) kinstr - | IPairing_check_bls12_381 : - ((Bls12_381.G1.t, Bls12_381.G2.t) pair boxed_list, 's) kinfo - * (bool, 's, 'r, 'f) kinstr - -> ((Bls12_381.G1.t, Bls12_381.G2.t) pair boxed_list, 's, 'r, 'f) kinstr - | IComb : - ('a, 's) kinfo - * int - * ('a * 's, 'b * 'u) comb_gadt_witness - * ('b, 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IUncomb : - ('a, 's) kinfo - * int - * ('a * 's, 'b * 'u) uncomb_gadt_witness - * ('b, 'u, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | IComb_get : - ('t, 's) kinfo - * int - * ('t, 'v) comb_get_gadt_witness - * ('v, 's, 'r, 'f) kinstr - -> ('t, 's, 'r, 'f) kinstr - | IComb_set : - ('a, 'b * 's) kinfo - * int - * ('a, 'b, 'c) comb_set_gadt_witness - * ('c, 's, 'r, 'f) kinstr - -> ('a, 'b * 's, 'r, 'f) kinstr - | IDup_n : - ('a, 's) kinfo - * int - * ('a * 's, 't) dup_n_gadt_witness - * ('t, 'a * 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - | ITicket : - ('a, n num * 's) kinfo * ('a ticket, 's, 'r, 'f) kinstr - -> ('a, n num * 's, 'r, 'f) kinstr - | IRead_ticket : - ('a ticket, 's) kinfo - * (address * ('a * n num), 'a ticket * 's, 'r, 'f) kinstr - -> ('a ticket, 's, 'r, 'f) kinstr - | ISplit_ticket : - ('a ticket, (n num * n num) * 's) kinfo - * (('a ticket * 'a ticket) option, 's, 'r, 'f) kinstr - -> ('a ticket, (n num * n num) * 's, 'r, 'f) kinstr - | IJoin_tickets : - ('a ticket * 'a ticket, 's) kinfo - * 'a comparable_ty - * ('a ticket option, 's, 'r, 'f) kinstr - -> ('a ticket * 'a ticket, 's, 'r, 'f) kinstr - | IOpen_chest : - (Timelock.chest_key, Timelock.chest * (n num * 's)) kinfo - * ((bytes, bool) union, 's, 'r, 'f) kinstr - -> (Timelock.chest_key, Timelock.chest * (n num * 's), 'r, 'f) kinstr - (* - - Internal control instructions - ============================= - - The following instructions are not available in the source language. - They are used by the internals of the interpreter. - *) - | IHalt : ('a, 's) kinfo -> ('a, 's, 'a, 's) kinstr - | ILog : - ('a, 's) kinfo * logging_event * logger * ('a, 's, 'r, 'f) kinstr - -> ('a, 's, 'r, 'f) kinstr - -and logging_event = - | LogEntry : logging_event - | LogExit : ('b, 'u) kinfo -> logging_event - -and ('arg, 'ret) lambda = - | Lam : - ('arg, end_of_stack, 'ret, end_of_stack) kdescr * Script.node - -> ('arg, 'ret) lambda -[@@coq_force_gadt] - -and 'arg typed_contract = 'arg ty * address - -(* - - Control stack - ============= - - The control stack is a list of [kinstr]. - - Since [kinstr] denotes a list of instructions, the control stack - can be seen as a list of instruction sequences, each representing a - form of delimited continuation (i.e. a control stack fragment). The - [continuation] GADT ensures that the input and output stack types of the - continuations are consistent. - - Loops have a special treatment because their control stack is reused - as is for the next iteration. This avoids the reallocation of a - control stack cell at each iteration. - - To implement [step] as a tail-recursive function, we implement - higher-order iterators (i.e. MAPs and ITERs) using internal instructions -. Roughly speaking, these instructions help in decomposing the execution - of [I f c] (where [I] is an higher-order iterator over a container [c]) - into three phases: to start the iteration, to execute [f] if there are - elements to be processed in [c], and to loop. - - Dip also has a dedicated constructor in the control stack. This - allows the stack prefix to be restored after the execution of the - [Dip]'s body. - - Following the same style as in [kinstr], [continuation] has four - arguments, two for each stack types. More precisely, with - - [('bef_top, 'bef, 'aft_top, 'aft) continuation] - - we encode the fact that the stack before executing the continuation - has type [('bef_top * 'bef)] and that the stack after this execution - has type [('aft_top * 'aft)]. - -*) -and (_, _, _, _) continuation = - (* This continuation returns immediately. *) - | KNil : ('r, 'f, 'r, 'f) continuation - (* This continuation starts with the next instruction to execute. *) - | KCons : - ('a, 's, 'b, 't) kinstr * ('b, 't, 'r, 'f) continuation - -> ('a, 's, 'r, 'f) continuation - (* This continuation represents a call frame: it stores the caller's - stack of type ['s] and the continuation which expects the callee's - result on top of the stack. *) - | KReturn : - 's * ('a, 's, 'r, 'f) continuation - -> ('a, end_of_stack, 'r, 'f) continuation - (* This continuation is useful when stack head requires some wrapping or - unwrapping before it can be passed forward. For instance this continuation - is used after a [MAP] instruction applied to an option in order to wrap the - result back in a [Some] constructor. - - /!\ When using it, make sure the function runs in constant time or that gas - has been properly charged beforehand. - Also make sure it runs with a small, bounded stack. - *) - | KMap_head : - ('a -> 'b) * ('b, 's, 'r, 'f) continuation - -> ('a, 's, 'r, 'f) continuation - (* This continuation comes right after a [Dip i] to restore the topmost - element ['b] of the stack after having executed [i] in the substack - of type ['a * 's]. *) - | KUndip : - 'b * ('b, 'a * 's, 'r, 'f) continuation - -> ('a, 's, 'r, 'f) continuation - (* This continuation is executed at each iteration of a loop with - a Boolean condition. *) - | KLoop_in : - ('a, 's, bool, 'a * 's) kinstr * ('a, 's, 'r, 'f) continuation - -> (bool, 'a * 's, 'r, 'f) continuation - (* This continuation is executed at each iteration of a loop with - a condition encoded by a sum type. *) - | KLoop_in_left : - ('a, 's, ('a, 'b) union, 's) kinstr * ('b, 's, 'r, 'f) continuation - -> (('a, 'b) union, 's, 'r, 'f) continuation - (* This continuation is executed at each iteration of a traversal. - (Used in List, Map and Set.) *) - | KIter : - ('a, 'b * 's, 'b, 's) kinstr * 'a list * ('b, 's, 'r, 'f) continuation - -> ('b, 's, 'r, 'f) continuation - (* This continuation represents each step of a List.map. *) - | KList_enter_body : - ('a, 'c * 's, 'b, 'c * 's) kinstr - * 'a list - * 'b list - * int - * ('b boxed_list, 'c * 's, 'r, 'f) continuation - -> ('c, 's, 'r, 'f) continuation - (* This continuation represents what is done after each step of a List.map. *) - | KList_exit_body : - ('a, 'c * 's, 'b, 'c * 's) kinstr - * 'a list - * 'b list - * int - * ('b boxed_list, 'c * 's, 'r, 'f) continuation - -> ('b, 'c * 's, 'r, 'f) continuation - (* This continuation represents each step of a Map.map. *) - | KMap_enter_body : - ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr - * ('a * 'b) list - * ('a, 'c) map - * (('a, 'c) map, 'd * 's, 'r, 'f) continuation - -> ('d, 's, 'r, 'f) continuation - (* This continuation represents what is done after each step of a Map.map. *) - | KMap_exit_body : - ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr - * ('a * 'b) list - * ('a, 'c) map - * 'a - * (('a, 'c) map, 'd * 's, 'r, 'f) continuation - -> ('c, 'd * 's, 'r, 'f) continuation - (* This continuation represents what is done after returning from a view. - It holds the original step constants value prior to entering the view. *) - | KView_exit : - step_constants * ('a, 's, 'r, 'f) continuation - -> ('a, 's, 'r, 'f) continuation - (* This continuation instruments the execution with a [logger]. *) - | KLog : - ('a, 's, 'r, 'f) continuation * logger - -> ('a, 's, 'r, 'f) continuation - -(* - - Execution instrumentation - ========================= - - One can observe the context and the stack at some specific points - of an execution step. This feature is implemented by calling back - some [logging_function]s defined in a record of type [logger] - passed as argument to the step function. - - A [logger] is typically embedded in an [KLog] continuation by the - client to trigger an evaluation instrumented with some logging. The - logger is then automatically propagated to the logging instruction - [ILog] as well as to any instructions that need to generate a - backtrace when it fails (e.g., [IFailwith], [IMul_teznat], ...). - -*) -and ('a, 's, 'b, 'f, 'c, 'u) logging_function = - ('a, 's, 'b, 'f) kinstr -> - context -> - Script.location -> - ('c, 'u) stack_ty -> - 'c * 'u -> - unit - -and execution_trace = - (Script.location * Gas.t * (Script.expr * string option) list) list - -and logger = { - log_interp : 'a 's 'b 'f 'c 'u. ('a, 's, 'b, 'f, 'c, 'u) logging_function; - (** [log_interp] is called at each call of the internal function - [interp]. [interp] is called when starting the interpretation of - a script and subsequently at each [Exec] instruction. *) - log_entry : 'a 's 'b 'f. ('a, 's, 'b, 'f, 'a, 's) logging_function; - (** [log_entry] is called {i before} executing each instruction but - {i after} gas for this instruction has been successfully - consumed. *) - log_control : 'a 's 'b 'f. ('a, 's, 'b, 'f) continuation -> unit; - (** [log_control] is called {i before} the interpretation of the - current continuation. *) - log_exit : 'a 's 'b 'f 'c 'u. ('a, 's, 'b, 'f, 'c, 'u) logging_function; - (** [log_exit] is called {i after} executing each instruction. *) - get_log : unit -> execution_trace option tzresult Lwt.t; - (** [get_log] allows to obtain an execution trace, if any was - produced. *) -} - -(* ---- Auxiliary types -----------------------------------------------------*) -and 'ty ty = - | Unit_t : unit ty_metadata -> unit ty - | Int_t : z num ty_metadata -> z num ty - | Nat_t : n num ty_metadata -> n num ty - | Signature_t : signature ty_metadata -> signature ty - | String_t : Script_string.t ty_metadata -> Script_string.t ty - | Bytes_t : Bytes.t ty_metadata -> bytes ty - | Mutez_t : Tez.t ty_metadata -> Tez.t ty - | Key_hash_t : public_key_hash ty_metadata -> public_key_hash ty - | Key_t : public_key ty_metadata -> public_key ty - | Timestamp_t : Script_timestamp.t ty_metadata -> Script_timestamp.t ty - | Address_t : address ty_metadata -> address ty - | Bool_t : bool ty_metadata -> bool ty - | Pair_t : - ('a ty * field_annot option * var_annot option) - * ('b ty * field_annot option * var_annot option) - * ('a, 'b) pair ty_metadata - -> ('a, 'b) pair ty - | Union_t : - ('a ty * field_annot option) - * ('b ty * field_annot option) - * ('a, 'b) union ty_metadata - -> ('a, 'b) union ty - | Lambda_t : - 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata - -> ('arg, 'ret) lambda ty - | Option_t : 'v ty * 'v option ty_metadata -> 'v option ty - | List_t : 'v ty * 'v boxed_list ty_metadata -> 'v boxed_list ty - | Set_t : 'v comparable_ty * 'v set ty_metadata -> 'v set ty - | Map_t : - 'k comparable_ty * 'v ty * ('k, 'v) map ty_metadata - -> ('k, 'v) map ty - | Big_map_t : - 'k comparable_ty * 'v ty * ('k, 'v) big_map ty_metadata - -> ('k, 'v) big_map ty - | Contract_t : - 'arg ty * 'arg typed_contract ty_metadata - -> 'arg typed_contract ty - | Sapling_transaction_t : - Sapling.Memo_size.t * Sapling.transaction ty_metadata - -> Sapling.transaction ty - | Sapling_state_t : - Sapling.Memo_size.t * Sapling.state ty_metadata - -> Sapling.state ty - | Operation_t : operation ty_metadata -> operation ty - | Chain_id_t : Chain_id.t ty_metadata -> Chain_id.t ty - | Never_t : never ty_metadata -> never ty - | Bls12_381_g1_t : Bls12_381.G1.t ty_metadata -> Bls12_381.G1.t ty - | Bls12_381_g2_t : Bls12_381.G2.t ty_metadata -> Bls12_381.G2.t ty - | Bls12_381_fr_t : Bls12_381.Fr.t ty_metadata -> Bls12_381.Fr.t ty - | Ticket_t : 'a comparable_ty * 'a ticket ty_metadata -> 'a ticket ty - | Chest_key_t : Timelock.chest_key ty_metadata -> Timelock.chest_key ty - | Chest_t : Timelock.chest ty_metadata -> Timelock.chest ty - -and ('top_ty, 'resty) stack_ty = - | Item_t : - 'ty ty * ('ty2, 'rest) stack_ty * var_annot option - -> ('ty, 'ty2 * 'rest) stack_ty - | Bot_t : (empty_cell, empty_cell) stack_ty - -and ('key, 'value) big_map = { - id : Big_map.Id.t option; - diff : ('key, 'value) big_map_overlay; - key_type : 'key comparable_ty; - value_type : 'value ty; -} - -and ('a, 's, 'r, 'f) kdescr = { - kloc : Script.location; - kbef : ('a, 's) stack_ty; - kaft : ('r, 'f) stack_ty; - kinstr : ('a, 's, 'r, 'f) kinstr; -} - -and ('a, 's) kinfo = {iloc : Script.location; kstack_ty : ('a, 's) stack_ty} - -(* - - Several instructions work under an arbitrary deep stack prefix - (e.g, IDipn, IDropn, etc). To convince the typechecker that - these instructions are well-typed, we must provide a witness - to statically characterize the relationship between the input - and the output stacks. The inhabitants of the following GADT - act as such witnesses. - - More precisely, a value [w] of type - - [(c, t, d, v, a, s, b, u) stack_prefix_preservation_witness] - - proves that there is a common prefix between an input stack - of type [a * s] and an output stack of type [b * u]. This prefix - is as deep as the number of [KPrefix] application in [w]. When - used with an operation parameterized by a natural number [n] - characterizing the depth at which the operation must be applied, - [w] is the Peano encoding of [n]. - - When this prefix is removed from the two stacks, the input stack - has type [c * t] while the output stack has type [d * v]. - -*) -and (_, _, _, _, _, _, _, _) stack_prefix_preservation_witness = - | KPrefix : - ('y, 'u) kinfo - * ('c, 'v, 'd, 'w, 'x, 's, 'y, 'u) stack_prefix_preservation_witness - -> ( 'c, - 'v, - 'd, - 'w, - 'a, - 'x * 's, - 'a, - 'y * 'u ) - stack_prefix_preservation_witness - | KRest : ('a, 's, 'b, 'u, 'a, 's, 'b, 'u) stack_prefix_preservation_witness - -and ('before, 'after) comb_gadt_witness = - | Comb_one : ('a * ('x * 'before), 'a * ('x * 'before)) comb_gadt_witness - | Comb_succ : - ('before, 'b * 'after) comb_gadt_witness - -> ('a * 'before, ('a * 'b) * 'after) comb_gadt_witness - -and ('before, 'after) uncomb_gadt_witness = - | Uncomb_one : ('rest, 'rest) uncomb_gadt_witness - | Uncomb_succ : - ('b * 'before, 'after) uncomb_gadt_witness - -> (('a * 'b) * 'before, 'a * 'after) uncomb_gadt_witness - -and ('before, 'after) comb_get_gadt_witness = - | Comb_get_zero : ('b, 'b) comb_get_gadt_witness - | Comb_get_one : ('a * 'b, 'a) comb_get_gadt_witness - | Comb_get_plus_two : - ('before, 'after) comb_get_gadt_witness - -> ('a * 'before, 'after) comb_get_gadt_witness - -and ('value, 'before, 'after) comb_set_gadt_witness = - | Comb_set_zero : ('value, _, 'value) comb_set_gadt_witness - | Comb_set_one : ('value, 'hd * 'tl, 'value * 'tl) comb_set_gadt_witness - | Comb_set_plus_two : - ('value, 'before, 'after) comb_set_gadt_witness - -> ('value, 'a * 'before, 'a * 'after) comb_set_gadt_witness -[@@coq_force_gadt] - -(* - - [dup_n_gadt_witness ('s, 't)] ensures that there exists at least - [n] elements in ['s] and that the [n]-th element of ['s] is of type - ['t]. Here [n] follows Peano's encoding (0 and successor). - Besides, [0] corresponds to the topmost element of ['s]. - - This relational predicate is defined by induction on [n]. - -*) -and (_, _) dup_n_gadt_witness = - | Dup_n_zero : ('a * 'rest, 'a) dup_n_gadt_witness - | Dup_n_succ : - ('stack, 'b) dup_n_gadt_witness - -> ('a * 'stack, 'b) dup_n_gadt_witness - -and ('a, 'b) view_signature = - | View_signature of { - name : Script_string.t; - input_ty : 'a ty; - output_ty : 'b ty; - } - -val kinfo_of_kinstr : ('a, 's, 'b, 'f) kinstr -> ('a, 's) kinfo - -type kinstr_rewritek = { - apply : 'b 'u 'r 'f. ('b, 'u, 'r, 'f) kinstr -> ('b, 'u, 'r, 'f) kinstr; -} - -val kinstr_rewritek : - ('a, 's, 'r, 'f) kinstr -> kinstr_rewritek -> ('a, 's, 'r, 'f) kinstr - -val ty_size : 'a ty -> 'a Type_size.t - -val comparable_ty_size : 'a comparable_ty -> 'a Type_size.t - -val unit_t : annot:type_annot option -> unit ty - -val int_t : annot:type_annot option -> z num ty - -val nat_t : annot:type_annot option -> n num ty - -val signature_t : annot:type_annot option -> signature ty - -val string_t : annot:type_annot option -> Script_string.t ty - -val bytes_t : annot:type_annot option -> Bytes.t ty - -val mutez_t : annot:type_annot option -> Tez.t ty - -val key_hash_t : annot:type_annot option -> public_key_hash ty - -val key_t : annot:type_annot option -> public_key ty - -val timestamp_t : annot:type_annot option -> Script_timestamp.t ty - -val address_t : annot:type_annot option -> address ty - -val bool_t : annot:type_annot option -> bool ty - -val pair_t : - Script.location -> - 'a ty * field_annot option * var_annot option -> - 'b ty * field_annot option * var_annot option -> - annot:type_annot option -> - ('a, 'b) pair ty tzresult - -val union_t : - Script.location -> - 'a ty * field_annot option -> - 'b ty * field_annot option -> - annot:type_annot option -> - ('a, 'b) union ty tzresult - -val union_bytes_bool_t : (Bytes.t, bool) union ty - -val lambda_t : - Script.location -> - 'arg ty -> - 'ret ty -> - annot:type_annot option -> - ('arg, 'ret) lambda ty tzresult - -val option_t : - Script.location -> 'v ty -> annot:type_annot option -> 'v option ty tzresult - -(* the quote is used to indicate where the annotation will go *) - -val option_mutez'_t : _ ty_metadata -> Tez.t option ty - -val option_string'_t : _ ty_metadata -> Script_string.t option ty - -val option_bytes'_t : _ ty_metadata -> Bytes.t option ty - -val option_nat_t : n num option ty - -val option_pair_nat_nat_t : (n num, n num) pair option ty - -val option_pair_nat'_nat'_t : _ ty_metadata -> (n num, n num) pair option ty - -val option_pair_nat_mutez'_t : _ ty_metadata -> (n num, Tez.t) pair option ty - -val option_pair_mutez'_mutez'_t : _ ty_metadata -> (Tez.t, Tez.t) pair option ty - -val option_pair_int'_nat_t : _ ty_metadata -> (z num, n num) pair option ty - -val option_pair_int_nat'_t : _ ty_metadata -> (z num, n num) pair option ty - -val list_t : - Script.location -> - 'v ty -> - annot:type_annot option -> - 'v boxed_list ty tzresult - -val list_operation_t : operation boxed_list ty - -val set_t : - Script.location -> - 'v comparable_ty -> - annot:type_annot option -> - 'v set ty tzresult - -val map_t : - Script.location -> - 'k comparable_ty -> - 'v ty -> - annot:type_annot option -> - ('k, 'v) map ty tzresult - -val big_map_t : - Script.location -> - 'k comparable_ty -> - 'v ty -> - annot:type_annot option -> - ('k, 'v) big_map ty tzresult - -val contract_t : - Script.location -> - 'arg ty -> - annot:type_annot option -> - 'arg typed_contract ty tzresult - -val contract_unit_t : unit typed_contract ty - -val sapling_transaction_t : - memo_size:Sapling.Memo_size.t -> - annot:type_annot option -> - Sapling.transaction ty - -val sapling_state_t : - memo_size:Sapling.Memo_size.t -> annot:type_annot option -> Sapling.state ty - -val operation_t : annot:type_annot option -> operation ty - -val chain_id_t : annot:type_annot option -> Chain_id.t ty - -val never_t : annot:type_annot option -> never ty - -val bls12_381_g1_t : annot:type_annot option -> Bls12_381.G1.t ty - -val bls12_381_g2_t : annot:type_annot option -> Bls12_381.G2.t ty - -val bls12_381_fr_t : annot:type_annot option -> Bls12_381.Fr.t ty - -val ticket_t : - Script.location -> - 'a comparable_ty -> - annot:type_annot option -> - 'a ticket ty tzresult - -val chest_key_t : annot:type_annot option -> Timelock.chest_key ty - -val chest_t : annot:type_annot option -> Timelock.chest ty - -(** - - The following functions named `X_traverse` for X in { kinstr, ty, - comparable_ty, value } provide tail recursive top down traversals - over the values of these types. - - The traversal goes through a value and rewrites an accumulator - along the way starting from some [init]ial value for the - accumulator. - - All these traversals follow the same recursion scheme: the - user-provided function is first called on the toplevel value, then - the traversal recurses on the direct subvalues of the same type. - - Hence, the user-provided function must only compute the - contribution of the value on the accumulator minus the contribution - of its subvalues of the same type. - -*) -type 'a kinstr_traverse = { - apply : 'b 'u 'r 'f. 'a -> ('b, 'u, 'r, 'f) kinstr -> 'a; -} - -val kinstr_traverse : - ('a, 'b, 'c, 'd) kinstr -> 'ret -> 'ret kinstr_traverse -> 'ret - -type 'a ty_traverse = { - apply : 't. 'a -> 't ty -> 'a; - apply_comparable : 't. 'a -> 't comparable_ty -> 'a; -} - -val comparable_ty_traverse : 'a comparable_ty -> 'r -> 'r ty_traverse -> 'r - -val ty_traverse : 'a ty -> 'r -> 'r ty_traverse -> 'r - -type 'accu stack_ty_traverse = { - apply : 'ty 's. 'accu -> ('ty, 's) stack_ty -> 'accu; -} - -val stack_ty_traverse : ('a, 's) stack_ty -> 'r -> 'r stack_ty_traverse -> 'r - -type 'a value_traverse = { - apply : 't. 'a -> 't ty -> 't -> 'a; - apply_comparable : 't. 'a -> 't comparable_ty -> 't -> 'a; -} - -val value_traverse : - ('t ty, 't comparable_ty) union -> 't -> 'r -> 'r value_traverse -> 'r - -val stack_top_ty : ('a, 'b * 's) stack_ty -> 'a ty diff --git a/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size.ml b/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size.ml deleted file mode 100644 index 29949bcaaf65..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size.ml +++ /dev/null @@ -1,769 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context -open Script_typed_ir -include Cache_memory_helpers - -let script_string_size s = Script_string.to_string s |> string_size - -(* The model assumes that annotations' sizes are counted once in the - Micheline representation and that the strings are always - shared. (One can check that they are never copied.) Besides, the - following types are unboxed so that they have no tags. *) -let type_annot_size (Script_ir_annot.Type_annot _) = !!0 - -let field_annot_size (Script_ir_annot.Field_annot _) = !!0 - -let var_annot_size (Script_ir_annot.Var_annot _) = !!0 - -(* Memo-sizes are 16-bit integers *) -let sapling_memo_size_size = !!0 - -let (comparable_ty_size, ty_size) = - let base {annot; size = _} = hh3w +! option_size type_annot_size annot in - let apply_comparable : - type a. nodes_and_size -> a comparable_ty -> nodes_and_size = - fun accu cty -> - match cty with - | Unit_key a -> ret_succ_adding accu (base a) - | Int_key a -> ret_succ_adding accu (base a) - | Nat_key a -> ret_succ_adding accu (base a) - | Signature_key a -> ret_succ_adding accu (base a) - | String_key a -> ret_succ_adding accu (base a) - | Bytes_key a -> ret_succ_adding accu (base a) - | Mutez_key a -> ret_succ_adding accu (base a) - | Key_hash_key a -> ret_succ_adding accu (base a) - | Key_key a -> ret_succ_adding accu (base a) - | Timestamp_key a -> ret_succ_adding accu (base a) - | Address_key a -> ret_succ_adding accu (base a) - | Bool_key a -> ret_succ_adding accu (base a) - | Chain_id_key a -> ret_succ_adding accu (base a) - | Never_key a -> ret_succ_adding accu (base a) - | Pair_key ((_ty1, fa1), (_ty2, fa2), a) -> - ret_succ_adding accu - @@ base a +! hh6w - +! option_size field_annot_size fa1 - +! option_size field_annot_size fa2 - | Union_key ((_ty1, fa1), (_ty2, fa2), a) -> - ret_succ_adding accu - @@ base a +! hh6w - +! option_size field_annot_size fa1 - +! option_size field_annot_size fa2 - | Option_key (_ty, a) -> ret_succ_adding accu @@ (base a +! word_size) - and apply : type a. nodes_and_size -> a ty -> nodes_and_size = - fun accu ty -> - match ty with - | Unit_t a -> ret_succ_adding accu @@ base a - | Int_t a -> ret_succ_adding accu @@ base a - | Nat_t a -> ret_succ_adding accu @@ base a - | Signature_t a -> ret_succ_adding accu @@ base a - | String_t a -> ret_succ_adding accu @@ base a - | Bytes_t a -> ret_succ_adding accu @@ base a - | Mutez_t a -> ret_succ_adding accu @@ base a - | Key_hash_t a -> ret_succ_adding accu @@ base a - | Key_t a -> ret_succ_adding accu @@ base a - | Timestamp_t a -> ret_succ_adding accu @@ base a - | Address_t a -> ret_succ_adding accu @@ base a - | Bool_t a -> ret_succ_adding accu @@ base a - | Operation_t a -> ret_succ_adding accu @@ base a - | Chain_id_t a -> ret_succ_adding accu @@ base a - | Never_t a -> ret_succ_adding accu @@ base a - | Bls12_381_g1_t a -> ret_succ_adding accu @@ base a - | Bls12_381_g2_t a -> ret_succ_adding accu @@ base a - | Bls12_381_fr_t a -> ret_succ_adding accu @@ base a - | Chest_key_t a -> ret_succ_adding accu @@ base a - | Chest_t a -> ret_succ_adding accu @@ base a - | Pair_t ((_ty1, fa1, va1), (_ty2, fa2, va2), a) -> - ret_succ_adding accu - @@ base a +! hh8w - +! option_size field_annot_size fa1 - +! option_size var_annot_size va1 - +! option_size field_annot_size fa2 - +! option_size var_annot_size va2 - | Union_t ((_ty1, fa1), (_ty2, fa2), a) -> - ret_succ_adding accu - @@ base a +! hh6w - +! option_size field_annot_size fa1 - +! option_size field_annot_size fa2 - | Lambda_t (_ty1, _ty2, a) -> - ret_succ_adding accu @@ (base a +! (word_size *? 2)) - | Option_t (_ty, a) -> ret_succ_adding accu @@ (base a +! word_size) - | List_t (_ty, a) -> ret_succ_adding accu @@ (base a +! word_size) - | Set_t (_cty, a) -> ret_succ_adding accu @@ (base a +! word_size) - | Map_t (_cty, _ty, a) -> - ret_succ_adding accu @@ (base a +! (word_size *? 2)) - | Big_map_t (_cty, _ty, a) -> - ret_succ_adding accu @@ (base a +! (word_size *? 2)) - | Contract_t (_ty, a) -> ret_succ_adding accu @@ (base a +! word_size) - | Sapling_transaction_t (_m, a) -> - ret_succ_adding accu @@ (base a +! sapling_memo_size_size +! word_size) - | Sapling_state_t (_m, a) -> - ret_succ_adding accu @@ (base a +! sapling_memo_size_size +! word_size) - | Ticket_t (_cty, a) -> ret_succ_adding accu @@ (base a +! word_size) - in - let f = ({apply; apply_comparable} : nodes_and_size ty_traverse) in - ( (fun cty -> comparable_ty_traverse cty zero f), - fun ty -> ty_traverse ty zero f ) - -let stack_ty_size s = - let apply : type a s. nodes_and_size -> (a, s) stack_ty -> nodes_and_size = - fun accu s -> - match s with - | Bot_t -> ret_succ accu - | Item_t (ty, _, annot) -> - ret_succ_adding - (accu ++ ty_size ty) - (h3w +! option_size var_annot_size annot) - in - stack_ty_traverse s zero {apply} - -let script_nat_size n = Script_int.to_zint n |> z_size - -let script_int_size n = Script_int.to_zint n |> z_size - -let signature_size = h3w +? Signature.size - -let key_hash_size (x : Signature.public_key_hash) = - h1w - +? Signature.( - match x with - | Ed25519 _ -> Ed25519.Public_key_hash.size - | Secp256k1 _ -> Secp256k1.Public_key_hash.size - | P256 _ -> P256.Public_key_hash.size) - -let public_key_size (x : public_key) = - let ks = Signature.Public_key.size x in - h1w +? ks - -let mutez_size = h2w - -let timestamp_size x = Script_timestamp.to_zint x |> z_size - -let contract_size = Contract.in_memory_size - -let address_size ((c, s) : address) = h2w +! contract_size c +! string_size s - -let view_signature_size (View_signature {name; input_ty; output_ty}) = - ret_adding - (ty_size input_ty ++ ty_size output_ty) - (h3w +! script_string_size name) - -let script_expr_hash_size = Script_expr_hash.size - -let peano_shape_proof = - let scale = header_size +! h1w in - fun k -> scale *? k - -let stack_prefix_preservation_witness_size = - let kinfo_size = h2w in - let scale = header_size +! (h2w +! kinfo_size) in - fun k -> scale *? k - -let comb_gadt_witness_size = peano_shape_proof - -let uncomb_gadt_witness_size = peano_shape_proof - -let comb_get_gadt_witness_size = peano_shape_proof - -let comb_set_gadt_witness_size = peano_shape_proof - -let dup_n_gadt_witness_size = peano_shape_proof - -let contract_size (arg_ty, address) = - ret_adding (ty_size arg_ty) (h2w +! address_size address) - -let sapling_state_size {Sapling.id; diff; memo_size = _} = - h3w - +! option_size (fun x -> z_size (Sapling.Id.unparse_to_z x)) id - +! Sapling.diff_in_memory_size diff - +! sapling_memo_size_size - -let operation_size - (operation : - packed_internal_operation * Lazy_storage.diffs_item list option) = - let (poi, diffs) = operation in - ret_adding - (Operation.packed_internal_operation_in_memory_size poi - ++ option_size_vec Lazy_storage.diffs_in_memory_size diffs) - h2w - -let chain_id_size = h1w +? Chain_id.size - -(* [contents] is handle by the recursion scheme in [value_size] *) -let ticket_size {ticketer; contents = _; amount} = - h3w +! Contract.in_memory_size ticketer +! script_nat_size amount - -let chest_size chest = - (* - type chest = { - locked_value : locked_value; - rsa_public : rsa_public; - ciphertext : ciphertext; - } - *) - let locked_value_size = 256 in - let rsa_public_size = 256 in - let ciphertext_size = Timelock.get_plaintext_size chest in - h3w +? (locked_value_size + rsa_public_size + ciphertext_size) - -let chest_key_size _ = - (* - type chest_key = { - unlocked_value : unlocked_value; - proof : time_lock_proof - } - *) - let unlocked_value_size = 256 in - let proof_size = 256 in - h2w +? (unlocked_value_size + proof_size) - -let view_size {input_ty; output_ty; view_code} = - ret_adding - (node_size input_ty ++ node_size output_ty ++ node_size view_code) - h3w - -let views_size views = - SMap.fold - (fun k view accu -> - ret_adding (accu ++ view_size view) (script_string_size k +! h4w)) - views - zero - -let kinfo_size {iloc = _; kstack_ty = _} = h2w - -(* The following mutually recursive functions are mostly - tail-recursive and the only recursive call that is not a tailcall - cannot be nested. (See [big_map_size].) For this reason, these - functions should not trigger stack overflows. *) -let rec value_size : - type a. - count_lambda_nodes:bool -> - nodes_and_size -> - (a ty, a comparable_ty) union -> - a -> - nodes_and_size = - fun ~count_lambda_nodes accu ty x -> - let apply : type a. nodes_and_size -> a ty -> a -> nodes_and_size = - fun accu ty x -> - match ty with - | Unit_t _ -> ret_succ accu - | Int_t _ -> ret_succ_adding accu (script_int_size x) - | Nat_t _ -> ret_succ_adding accu (script_nat_size x) - | Signature_t _ -> ret_succ_adding accu signature_size - | String_t _ -> ret_succ_adding accu (script_string_size x) - | Bytes_t _ -> ret_succ_adding accu (bytes_size x) - | Mutez_t _ -> ret_succ_adding accu mutez_size - | Key_hash_t _ -> ret_succ_adding accu (key_hash_size x) - | Key_t _ -> ret_succ_adding accu (public_key_size x) - | Timestamp_t _ -> ret_succ_adding accu (timestamp_size x) - | Address_t _ -> ret_succ_adding accu (address_size x) - | Bool_t _ -> ret_succ accu - | Pair_t (_, _, _) -> ret_succ_adding accu h2w - | Union_t (_, _, _) -> ret_succ_adding accu h1w - | Lambda_t (_, _, _) -> - (lambda_size [@ocaml.tailcall]) ~count_lambda_nodes (ret_succ accu) x - | Option_t (_, _) -> ret_succ_adding accu (option_size (fun _ -> !!0) x) - | List_t (_, _) -> ret_succ_adding accu (h2w +! (h2w *? x.length)) - | Set_t (_, _) -> - let module M = (val x) in - let boxing_space = !!300 in - ret_succ_adding accu (boxing_space +! (h4w *? M.size)) - | Map_t (_, _, _) -> - let module M = (val x) in - let boxing_space = !!300 in - ret_succ_adding accu (boxing_space +! (h5w *? M.size)) - | Big_map_t (cty, ty', _) -> - (big_map_size [@ocaml.tailcall]) - ~count_lambda_nodes - (ret_succ accu) - cty - ty' - x - | Contract_t (_, _) -> ret_succ (accu ++ contract_size x) - | Sapling_transaction_t (_, _) -> - ret_succ_adding accu (Sapling.transaction_in_memory_size x) - | Sapling_state_t (_, _) -> ret_succ_adding accu (sapling_state_size x) - | Operation_t _ -> ret_succ (accu ++ operation_size x) - | Chain_id_t _ -> ret_succ_adding accu chain_id_size - | Never_t _ -> ( match x with _ -> .) - (* Related to https://gitlab.com/dannywillems/ocaml-bls12-381/-/issues/56. - Since the update to blst as a backend for bls12-381, size_in_bytes is not - the correct value for the allocated memory. - There is 1 word for the OCaml block header, 1 word for the C pointer and - a certain number of words for the actual value of the algebraic object - whose size is fixed and defined by the object itself. - For G1, it allocates 3 C values of type blst_fp which is 48 bytes. - For G2, it allocates 3 C values of type blst_fp2 which is 48 * 2 bytes. - For Fr, it allocates 1 C value of type blst_fr which is 32 bytes. - *) - | Bls12_381_g1_t _ -> ret_succ_adding accu !!((2 * 8) + (3 * 48)) - | Bls12_381_g2_t _ -> ret_succ_adding accu !!((2 * 8) + (3 * 48 * 2)) - | Bls12_381_fr_t _ -> ret_succ_adding accu !!((2 * 8) + 32) - | Ticket_t (_, _) -> ret_succ_adding accu (ticket_size x) - | Chest_key_t _ -> ret_succ_adding accu (chest_key_size x) - | Chest_t _ -> ret_succ_adding accu (chest_size x) - in - let apply_comparable : - type a. nodes_and_size -> a comparable_ty -> a -> nodes_and_size = - fun accu ty x -> - match ty with - | Unit_key _ -> ret_succ accu - | Int_key _ -> ret_succ_adding accu (script_int_size x) - | Nat_key _ -> ret_succ_adding accu (script_nat_size x) - | Signature_key _ -> ret_succ_adding accu signature_size - | String_key _ -> ret_succ_adding accu (script_string_size x) - | Bytes_key _ -> ret_succ_adding accu (bytes_size x) - | Mutez_key _ -> ret_succ_adding accu mutez_size - | Key_hash_key _ -> ret_succ_adding accu (key_hash_size x) - | Key_key _ -> ret_succ_adding accu (public_key_size x) - | Timestamp_key _ -> ret_succ_adding accu (timestamp_size x) - | Address_key _ -> ret_succ_adding accu (address_size x) - | Bool_key _ -> ret_succ accu - | Pair_key (_, _, _) -> ret_succ_adding accu h2w - | Union_key (_, _, _) -> ret_succ_adding accu h1w - | Option_key (_, _) -> ret_succ_adding accu (option_size (fun _ -> !!0) x) - | Chain_id_key _ -> ret_succ_adding accu chain_id_size - | Never_key _ -> ( match x with _ -> .) - in - value_traverse ty x accu {apply; apply_comparable} - [@@coq_axiom_with_reason "unreachable expressions '.' not handled for now"] - -and big_map_size : - type a b. - count_lambda_nodes:bool -> - nodes_and_size -> - a comparable_ty -> - b ty -> - (a, b) big_map -> - nodes_and_size = - fun ~count_lambda_nodes accu cty ty' {id; diff; key_type; value_type} -> - (* [Map.bindings] cannot overflow and only consumes a - logarithmic amount of stack. *) - let diff_size = - let map_size = - Big_map_overlay.fold - (fun _key_hash (key, value) accu -> - let accu = ret_succ_adding accu !!script_expr_hash_size in - (* The following recursive call cannot introduce a stack - overflow because this would require a key of type - big_map while big_map is not comparable. *) - let accu = value_size ~count_lambda_nodes accu (R cty) key in - match value with - | None -> accu - | Some value -> - (value_size [@ocaml.tailcall]) - ~count_lambda_nodes - accu - (L ty') - value) - diff.map - accu - in - - ret_adding map_size h2w - in - let big_map_id_size s = z_size (Big_map.Id.unparse_to_z s) in - let id_size = option_size big_map_id_size id in - ret_adding - (comparable_ty_size key_type ++ ty_size value_type ++ diff_size) - (h4w +! id_size) - -and lambda_size : - type i o. - count_lambda_nodes:bool -> nodes_and_size -> (i, o) lambda -> nodes_and_size - = - fun ~count_lambda_nodes accu (Lam (kdescr, node)) -> - (* We assume that the nodes' size have already been counted if the - lambda is not a toplevel lambda. *) - let accu = - ret_adding (accu ++ if count_lambda_nodes then node_size node else zero) h2w - in - (kdescr_size [@ocaml.tailcall]) ~count_lambda_nodes:false accu kdescr - -and kdescr_size : - type a s r f. - count_lambda_nodes:bool -> - nodes_and_size -> - (a, s, r, f) kdescr -> - nodes_and_size = - fun ~count_lambda_nodes accu {kloc = _; kbef; kaft; kinstr} -> - let accu = - ret_adding (accu ++ stack_ty_size kbef ++ stack_ty_size kaft) h4w - in - (kinstr_size [@ocaml.tailcall]) ~count_lambda_nodes accu kinstr - -and kinstr_size : - type a s r f. - count_lambda_nodes:bool -> - nodes_and_size -> - (a, s, r, f) kinstr -> - nodes_and_size = - fun ~count_lambda_nodes accu t -> - let base kinfo = h2w +! kinfo_size kinfo in - let apply : - type a s r f. nodes_and_size -> (a, s, r, f) kinstr -> nodes_and_size = - fun accu t -> - match t with - | IDrop (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IDup (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISwap (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IConst (kinfo, x, k) -> - let accu = ret_succ_adding accu (base kinfo +! word_size) in - (value_size [@ocaml.tailcall]) - ~count_lambda_nodes - accu - (L (stack_top_ty (kinfo_of_kinstr k).kstack_ty)) - x - | ICons_pair (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ICar (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ICdr (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IUnpair (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ICons_some (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ICons_none (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IIf_none {kinfo; _} -> ret_succ_adding accu (base kinfo) - | IOpt_map {kinfo; _} -> ret_succ_adding accu (base kinfo) - | ICons_left (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ICons_right (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IIf_left {kinfo; _} -> ret_succ_adding accu (base kinfo) - | ICons_list (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INil (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IIf_cons {kinfo; _} -> ret_succ_adding accu (base kinfo) - | IList_map (kinfo, _, _) -> ret_succ_adding accu (base kinfo) - | IList_iter (kinfo, _, _) -> ret_succ_adding accu (base kinfo) - | IList_size (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IEmpty_set (kinfo, cty, _) -> - ret_succ_adding - (accu ++ comparable_ty_size cty) - (base kinfo +! word_size) - | ISet_iter (kinfo, _, _) -> ret_succ_adding accu (base kinfo) - | ISet_mem (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISet_update (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISet_size (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IEmpty_map (kinfo, cty, _) -> - ret_succ_adding - (accu ++ comparable_ty_size cty) - (base kinfo +! word_size) - | IMap_map (kinfo, _, _) -> ret_succ_adding accu (base kinfo +! word_size) - | IMap_iter (kinfo, _, _) -> ret_succ_adding accu (base kinfo +! word_size) - | IMap_mem (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMap_get (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMap_update (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMap_get_and_update (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMap_size (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IEmpty_big_map (kinfo, cty, ty, _) -> - ret_succ_adding - (accu ++ comparable_ty_size cty ++ ty_size ty) - (base kinfo +! (word_size *? 2)) - | IBig_map_mem (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IBig_map_get (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IBig_map_update (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IBig_map_get_and_update (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IConcat_string (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IConcat_string_pair (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISlice_string (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IString_size (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IConcat_bytes (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IConcat_bytes_pair (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISlice_bytes (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IBytes_size (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAdd_seconds_to_timestamp (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAdd_timestamp_to_seconds (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISub_timestamp_seconds (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IDiff_timestamps (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAdd_tez (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISub_tez (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISub_tez_legacy (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMul_teznat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMul_nattez (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IEdiv_teznat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IEdiv_tez (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IOr (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAnd (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IXor (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INot (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IIs_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INeg (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAbs_int (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IInt_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAdd_int (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAdd_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISub_int (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMul_int (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMul_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IEdiv_int (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IEdiv_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ILsl_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ILsr_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IOr_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAnd_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAnd_int_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IXor_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INot_int (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IIf {kinfo; _} -> ret_succ_adding accu (base kinfo) - | ILoop (kinfo, _, _) -> ret_succ_adding accu (base kinfo) - | ILoop_left (kinfo, _, _) -> ret_succ_adding accu (base kinfo +! word_size) - | IDip (kinfo, _, _) -> ret_succ_adding accu (base kinfo +! word_size) - | IExec (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IApply (kinfo, ty, _) -> - ret_succ_adding (accu ++ ty_size ty) (base kinfo +! word_size) - | ILambda (kinfo, lambda, _) -> - let accu = ret_succ_adding accu (base kinfo +! word_size) in - (lambda_size [@ocaml.tailcall]) ~count_lambda_nodes accu lambda - | IFailwith (kinfo, _, ty) -> - ret_succ_adding (accu ++ ty_size ty) (base kinfo +! word_size) - | ICompare (kinfo, cty, _) -> - ret_succ_adding - (accu ++ comparable_ty_size cty) - (base kinfo +! word_size) - | IEq (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INeq (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ILt (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IGt (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ILe (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IGe (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAddress (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IContract (kinfo, ty, s, _) -> - ret_succ_adding - (accu ++ ty_size ty) - (base kinfo +! string_size s +! (word_size *? 2)) - | IView (kinfo, s, _) -> - ret_succ_adding (accu ++ view_signature_size s) (base kinfo +! word_size) - | ITransfer_tokens (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IImplicit_account (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ICreate_contract - {kinfo; storage_type; arg_type; lambda; root_name; views; k = _} -> - let accu = - ret_succ_adding - (accu ++ ty_size storage_type ++ ty_size arg_type - ++ views_size views) - (base kinfo +! (word_size *? 4) - +! option_size field_annot_size root_name) - in - (lambda_size [@ocaml.tailcall]) ~count_lambda_nodes accu lambda - | ISet_delegate (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INow (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IBalance (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ILevel (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ICheck_signature (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IHash_key (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IPack (kinfo, ty, _) -> - ret_succ_adding (accu ++ ty_size ty) (base kinfo +! word_size) - | IUnpack (kinfo, ty, _) -> - ret_succ_adding (accu ++ ty_size ty) (base kinfo +! word_size) - | IBlake2b (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISha256 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISha512 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISource (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISender (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISelf (kinfo, ty, s, _) -> - ret_succ_adding - (accu ++ ty_size ty) - (base kinfo +! (word_size *? 2) +! string_size s) - | ISelf_address (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAmount (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISapling_empty_state (kinfo, _m, _) -> - ret_succ_adding accu (base kinfo +! word_size +! sapling_memo_size_size) - | ISapling_verify_update (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IDig (kinfo, n, _, _) -> - ret_succ_adding - accu - (base kinfo +! (word_size *? 2) - +! stack_prefix_preservation_witness_size n) - | IDug (kinfo, n, _, _) -> - ret_succ_adding - accu - (base kinfo +! (word_size *? 2) - +! stack_prefix_preservation_witness_size n) - | IDipn (kinfo, n, _, _, _) -> - ret_succ_adding - accu - (base kinfo +! (word_size *? 2) - +! stack_prefix_preservation_witness_size n) - | IDropn (kinfo, n, _, _) -> - ret_succ_adding - accu - (base kinfo +! (word_size *? 2) - +! stack_prefix_preservation_witness_size n) - | IChainId (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INever kinfo -> ret_succ_adding accu (kinfo_size kinfo) - | IVoting_power (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ITotal_voting_power (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IKeccak (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISha3 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAdd_bls12_381_g1 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAdd_bls12_381_g2 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IAdd_bls12_381_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMul_bls12_381_g1 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMul_bls12_381_g2 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMul_bls12_381_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMul_bls12_381_z_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IMul_bls12_381_fr_z (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IInt_bls12_381_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INeg_bls12_381_g1 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INeg_bls12_381_g2 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | INeg_bls12_381_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IPairing_check_bls12_381 (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IComb (kinfo, n, _, _) -> - ret_succ_adding - accu - (base kinfo +! (word_size *? 2) +! comb_gadt_witness_size n) - | IUncomb (kinfo, n, _, _) -> - ret_succ_adding - accu - (base kinfo +! (word_size *? 2) +! uncomb_gadt_witness_size n) - | IComb_get (kinfo, n, _, _) -> - ret_succ_adding - accu - (base kinfo +! (word_size *? 2) +! comb_get_gadt_witness_size n) - | IComb_set (kinfo, n, _, _) -> - ret_succ_adding - accu - (base kinfo +! (word_size *? 2) +! comb_set_gadt_witness_size n) - | IDup_n (kinfo, n, _, _) -> - ret_succ_adding - accu - (base kinfo +! (word_size *? 2) +! dup_n_gadt_witness_size n) - | ITicket (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IRead_ticket (kinfo, _) -> ret_succ_adding accu (base kinfo) - | ISplit_ticket (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IJoin_tickets (kinfo, cty, _) -> - ret_succ_adding - (accu ++ comparable_ty_size cty) - (base kinfo +! word_size) - | IOpen_chest (kinfo, _) -> ret_succ_adding accu (base kinfo) - | IHalt kinfo -> ret_succ_adding accu (h1w +! kinfo_size kinfo) - | ILog (_, _, _, _) -> - (* This instruction is ignored because it is only used for testing. *) - accu - in - kinstr_traverse t accu {apply} - -let rec kinstr_extra_size : type a s r f. (a, s, r, f) kinstr -> nodes_and_size - = - fun t -> - let ret_zero x = (Nodes.zero, x) in - let apply : - type a s r f. nodes_and_size -> (a, s, r, f) kinstr -> nodes_and_size = - fun accu t -> - let stack_prefix_preservation_witness_size n = ret_zero (!!24 *? n) in - let dup_n_gadt_witness_size n = ret_zero (!!16 *? n) in - let comb n = ret_zero (!!16 *? n) in - let if_join k = - let kinfo = Script_typed_ir.kinfo_of_kinstr k in - stack_ty_size kinfo.kstack_ty - in - let self_size = - match t with - (* Op n *) - | IDig (_, n, _, _) -> stack_prefix_preservation_witness_size n - | IDug (_, n, _, _) -> stack_prefix_preservation_witness_size n - | IDipn (_, n, _, _, _) -> stack_prefix_preservation_witness_size n - | IDropn (_, n, _, _) -> stack_prefix_preservation_witness_size n - | IComb (_, n, _, _) -> comb n - | IUncomb (_, n, _, _) -> comb n - | IComb_get (_, n, _, _) -> comb (n / 2) - | IComb_set (_, n, _, _) -> comb (n / 2) - | IDup_n (_, n, _, _) -> dup_n_gadt_witness_size n - (* Whole stack types after conditionals and loops. *) - | IIf {k; _} -> if_join k - | IIf_cons {k; _} -> if_join k - | IIf_none {k; _} -> if_join k - | IIf_left {k; _} -> if_join k - (* Every instruction whose elaboration uses [merge_types], - [check_item_ty], [comparable_of_ty], or [ty_of_comparable_ty] - to create a type that is embedded in the IR. *) - | IJoin_tickets (_, _, k) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr k in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | ITicket (_, k) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr k in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | IRead_ticket (_, k) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr k in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | ICons_list (_, k) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr k in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | IMap_update (_, k) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr k in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | IMap_get_and_update (_, k) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr k in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | IBig_map_get_and_update (_, k) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr k in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | IApply (_, ty, _) -> ty_size ty - | ICompare (_, ty, _) -> comparable_ty_size ty - | IList_iter (_, body, _) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr body in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | IList_map (_, body, _) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr body in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | ISet_iter (_, body, _) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr body in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | IMap_map (_, body, _) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr body in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | IMap_iter (_, body, _) -> ( - let kinfo = Script_typed_ir.kinfo_of_kinstr body in - match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) - | ILambda (_, lambda, _) -> lambda_extra_size lambda - | ICreate_contract {lambda; _} -> lambda_extra_size lambda - | _ -> zero - in - ret_succ (accu ++ self_size) - in - kinstr_traverse t zero {apply} - -and lambda_extra_size : type i o. (i, o) lambda -> nodes_and_size = - fun (Lam ({kinstr; _}, _)) -> kinstr_extra_size kinstr - -let lambda_size lam = - (* - - The following formula has been obtained through a regression - over the corpus of mainnet contracts in Granada. - - *) - let (lambda_nodes, lambda_size) = - lambda_size ~count_lambda_nodes:true zero lam - in - let (lambda_extra_size_nodes, lambda_extra_size) = lambda_extra_size lam in - let size = (lambda_size *? 157 /? 100) +! (lambda_extra_size *? 18 /? 100) in - (Nodes.add lambda_nodes lambda_extra_size_nodes, size) - -let kinstr_size kinstr = - let (kinstr_extra_size_nodes, kinstr_extra_size) = kinstr_extra_size kinstr in - let (kinstr_nodes, kinstr_size) = - kinstr_size ~count_lambda_nodes:true zero kinstr - in - let size = (kinstr_size *? 157 /? 100) +! (kinstr_extra_size *? 18 /? 100) in - (Nodes.add kinstr_nodes kinstr_extra_size_nodes, size) - -let value_size ty x = value_size ~count_lambda_nodes:true zero (L ty) x diff --git a/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size.mli b/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size.mli deleted file mode 100644 index 5cdbb052e0e1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size.mli +++ /dev/null @@ -1,71 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module provides overapproximation of memory footprint for - Michelson-related values. - - These overapproximations are used by the cache to evaluate its own - memory footprint and enforce declared limit over its size. - -*) - -(** [value_size ty v] returns an overapproximation of the size of the - in-memory representation of [v] of type [ty]. *) -val value_size : - 'a Script_typed_ir.ty -> 'a -> Cache_memory_helpers.nodes_and_size - -(** [ty_size ty] returns an overapproximation of the size of the - in-memory representation of type [ty]. *) -val ty_size : 'a Script_typed_ir.ty -> Cache_memory_helpers.nodes_and_size - -(** [comparable_ty_size cty] returns an overapproximation of the size - of the in-memory representation of comparable type [cty]. *) -val comparable_ty_size : - 'a Script_typed_ir.comparable_ty -> Cache_memory_helpers.nodes_and_size - -(** [lambda_size l] returns an overapproximation of the size of the - internal IR for the Michelson lambda abstraction [l]. *) -val lambda_size : - ('a, 'b) Script_typed_ir.lambda -> Cache_memory_helpers.nodes_and_size - -(** [kinstr_size i] returns an overapproximation of the size of the - internal IR [i]. *) -val kinstr_size : - ('a, 's, 'r, 'f) Script_typed_ir.kinstr -> Cache_memory_helpers.nodes_and_size - -(** [node_size root] returns the size of the in-memory representation - of [root] in bytes. This is an over-approximation of the memory - actually consumed by [root] since no sharing is taken into - account. *) -val node_size : Script_repr.node -> Cache_memory_helpers.nodes_and_size - -(** Pointwise addition (reexport from {!Cache_memory_helpers}) *) -val ( ++ ) : - Cache_memory_helpers.nodes_and_size -> - Cache_memory_helpers.nodes_and_size -> - Cache_memory_helpers.nodes_and_size - -(** Zero vector (reexport from {!Cache_memory_helpers}) *) -val zero : Cache_memory_helpers.nodes_and_size diff --git a/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size_costs.ml b/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size_costs.ml deleted file mode 100644 index b2e4a9af007c..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size_costs.ml +++ /dev/null @@ -1,34 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module S = Saturation_repr - -(** FIXME insert proper gas constants (the gas constant below was fitted on - a non-standard machine) *) -let nodes_cost ~nodes = - let open S in - let nodes = Cache_memory_helpers.Nodes.to_int nodes in - let coeff = safe_int 45 in - Gas_limit_repr.atomic_step_cost (mul coeff (S.safe_int nodes)) diff --git a/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size_costs.mli b/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size_costs.mli deleted file mode 100644 index 9789e3d104af..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/script_typed_ir_size_costs.mli +++ /dev/null @@ -1,28 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** [node_size_cost ~nodes] returns the cost of having called - a function in {!Script_typed_ir_size} that returned [nodes]. *) -val nodes_cost : nodes:Cache_memory_helpers.Nodes.t -> Gas_limit_repr.cost diff --git a/src/proto_012_Psithaca/lib_protocol/seed_repr.ml b/src/proto_012_Psithaca/lib_protocol/seed_repr.ml deleted file mode 100644 index ea1c28351d31..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/seed_repr.ml +++ /dev/null @@ -1,150 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* Tezos Protocol Implementation - Random number generation *) - -type seed = B of State_hash.t - -type t = T of State_hash.t - -type sequence = S of State_hash.t - -type nonce = bytes - -let nonce_encoding = Data_encoding.Fixed.bytes Constants_repr.nonce_length - -let initial_seed = "Laissez-faire les proprietaires." - -let zero_bytes = Bytes.make Nonce_hash.size '\000' - -let state_hash_encoding = - let open Data_encoding in - conv State_hash.to_bytes State_hash.of_bytes_exn (Fixed.bytes Nonce_hash.size) - -let seed_encoding = - let open Data_encoding in - conv (fun (B b) -> b) (fun b -> B b) state_hash_encoding - -let empty = B (State_hash.hash_string [initial_seed]) - -let nonce (B state) nonce = - B (State_hash.hash_bytes [State_hash.to_bytes state; nonce]) - -let initialize_new (B state) append = - T (State_hash.hash_bytes (State_hash.to_bytes state :: zero_bytes :: append)) - -let xor_higher_bits i b = - let higher = TzEndian.get_int32 b 0 in - let r = Int32.logxor higher i in - let res = Bytes.copy b in - TzEndian.set_int32 res 0 r ; - res - -let sequence (T state) n = - State_hash.to_bytes state |> xor_higher_bits n |> fun b -> - S (State_hash.hash_bytes [b]) - -let take (S state) = - let b = State_hash.to_bytes state in - let h = State_hash.hash_bytes [b] in - (State_hash.to_bytes h, S h) - -let take_int32 s bound = - if Compare.Int32.(bound <= 0l) then invalid_arg "Seed_repr.take_int32" - (* FIXME *) - else - let drop_if_over = - Int32.sub Int32.max_int (Int32.rem Int32.max_int bound) - in - let rec loop s = - let (bytes, s) = take s in - let r = Int32.abs (TzEndian.get_int32 bytes 0) in - if Compare.Int32.(r >= drop_if_over) then loop s - else - let v = Int32.rem r bound in - (v, s) - in - loop s - -let take_int64 s bound = - if Compare.Int64.(bound <= 0L) then invalid_arg "Seed_repr.take_int64" - (* FIXME *) - else - let drop_if_over = - Int64.sub Int64.max_int (Int64.rem Int64.max_int bound) - in - - let rec loop s = - let (bytes, s) = take s in - let r = Int64.abs (TzEndian.get_int64 bytes 0) in - if Compare.Int64.(r >= drop_if_over) then loop s - else - let v = Int64.rem r bound in - (v, s) - in - loop s - -type error += Unexpected_nonce_length (* `Permanent *) - -let () = - register_error_kind - `Permanent - ~id:"unexpected_nonce_length" - ~title:"Unexpected nonce length" - ~description:"Nonce length is incorrect." - ~pp:(fun ppf () -> - Format.fprintf - ppf - "Nonce length is not %i bytes long as it should." - Constants_repr.nonce_length) - Data_encoding.empty - (function Unexpected_nonce_length -> Some () | _ -> None) - (fun () -> Unexpected_nonce_length) - -let make_nonce nonce = - if Compare.Int.(Bytes.length nonce <> Constants_repr.nonce_length) then - error Unexpected_nonce_length - else ok nonce - -let hash nonce = Nonce_hash.hash_bytes [nonce] - -let check_hash nonce hash = - Compare.Int.(Bytes.length nonce = Constants_repr.nonce_length) - && Nonce_hash.equal (Nonce_hash.hash_bytes [nonce]) hash - -let nonce_hash_key_part = Nonce_hash.to_path - -let initial_nonce_0 = zero_bytes - -let initial_nonce_hash_0 = hash initial_nonce_0 - -let deterministic_seed seed = nonce seed zero_bytes - -let initial_seeds n = - let[@coq_struct "i"] rec loop acc elt i = - if Compare.Int.(i = 1) then List.rev (elt :: acc) - else loop (elt :: acc) (deterministic_seed elt) (i - 1) - in - loop [] (B (State_hash.hash_bytes [])) n diff --git a/src/proto_012_Psithaca/lib_protocol/seed_repr.mli b/src/proto_012_Psithaca/lib_protocol/seed_repr.mli deleted file mode 100644 index b19f8c93b19e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/seed_repr.mli +++ /dev/null @@ -1,111 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Tezos Protocol Implementation - Random number generation - - This is not expected to be a good cryptographic random number - generator. In particular this is supposed to be used in situations - where the seed is a globally known information. - - The only expected property is: It should be difficult to find a - seed such that the generated sequence is a given one. *) - -(** {2 Random Generation} *) - -(** The state of the random number generator *) -type t - -(** A random seed, to derive random sequences from *) -type seed - -(** A random sequence, to derive random values from *) -type sequence - -(** [initialize_new state ident] returns a new generator *) -val initialize_new : seed -> bytes list -> t - -(** [sequence state n] prepares the n-th sequence of a state *) -val sequence : t -> int32 -> sequence - -(** Generates the next random value in the sequence *) -val take : sequence -> bytes * sequence - -(** [take_int32 s bound] generates the next random value as a bounded [int32] - - @param bound must be a positive integer - @raise Invalid_argument "Seed_repr.take_int32" if [bound] <= 0 - *) -val take_int32 : sequence -> int32 -> int32 * sequence - -(** [take_int64 s bound] generates the next random value as a bounded [int64] - - @param bound must be a positive integer - @raise Invalid_argument "Seed_repr.take_int64" if [bound] <= 0 - *) -val take_int64 : sequence -> int64 -> int64 * sequence - -(** {2 Predefined seeds} *) - -val empty : seed - -(** Returns a new seed by hashing the one passed with a constant. *) -val deterministic_seed : seed -> seed - -(** [initial_seeds n] generates the first [n] seeds for which there are no nonces. - The first seed is a constant value. The kth seed is the hash of seed (k-1) - concatenated with a constant. *) -val initial_seeds : int -> seed list - -(** {2 Entropy} *) - -(** A nonce for adding entropy to the generator *) -type nonce - -(** Add entropy to the seed generator *) -val nonce : seed -> nonce -> seed - -(** Use a byte sequence as a nonce *) -val make_nonce : bytes -> nonce tzresult - -(** Compute the has of a nonce *) -val hash : nonce -> Nonce_hash.t - -(** [check_hash nonce hash] is true if the nonce correspond to the hash *) -val check_hash : nonce -> Nonce_hash.t -> bool - -(** For using nonce hashes as keys in the hierarchical database *) -val nonce_hash_key_part : Nonce_hash.t -> string list -> string list - -(** {2 Predefined nonce} *) - -val initial_nonce_0 : nonce - -val initial_nonce_hash_0 : Nonce_hash.t - -(** {2 Serializers} *) - -val nonce_encoding : nonce Data_encoding.t - -val seed_encoding : seed Data_encoding.t diff --git a/src/proto_012_Psithaca/lib_protocol/seed_storage.ml b/src/proto_012_Psithaca/lib_protocol/seed_storage.ml deleted file mode 100644 index 2f0723743686..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/seed_storage.ml +++ /dev/null @@ -1,127 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | Unknown of { - oldest : Cycle_repr.t; - cycle : Cycle_repr.t; - latest : Cycle_repr.t; - } - -(* `Permanent *) - -let () = - register_error_kind - `Permanent - ~id:"seed.unknown_seed" - ~title:"Unknown seed" - ~description:"The requested seed is not available" - ~pp:(fun ppf (oldest, cycle, latest) -> - if Cycle_repr.(cycle < oldest) then - Format.fprintf - ppf - "The seed for cycle %a has been cleared from the context (oldest \ - known seed is for cycle %a)" - Cycle_repr.pp - cycle - Cycle_repr.pp - oldest - else - Format.fprintf - ppf - "The seed for cycle %a has not been computed yet (latest known seed \ - is for cycle %a)" - Cycle_repr.pp - cycle - Cycle_repr.pp - latest) - Data_encoding.( - obj3 - (req "oldest" Cycle_repr.encoding) - (req "requested" Cycle_repr.encoding) - (req "latest" Cycle_repr.encoding)) - (function - | Unknown {oldest; cycle; latest} -> Some (oldest, cycle, latest) - | _ -> None) - (fun (oldest, cycle, latest) -> Unknown {oldest; cycle; latest}) - -let compute_for_cycle c ~revealed cycle = - match Cycle_repr.pred cycle with - | None -> assert false (* should not happen *) - | Some previous_cycle -> - let levels = Level_storage.levels_with_commitments_in_cycle c revealed in - let combine (c, random_seed, unrevealed) level = - Storage.Seed.Nonce.get c level >>=? function - | Revealed nonce -> - Storage.Seed.Nonce.remove_existing c level >|=? fun c -> - (c, Seed_repr.nonce random_seed nonce, unrevealed) - | Unrevealed u -> - Storage.Seed.Nonce.remove_existing c level >|=? fun c -> - (c, random_seed, u :: unrevealed) - in - Storage.Seed.For_cycle.get c previous_cycle >>=? fun prev_seed -> - let seed = Seed_repr.deterministic_seed prev_seed in - List.fold_left_es combine (c, seed, []) levels - >>=? fun (c, seed, unrevealed) -> - Storage.Seed.For_cycle.init c cycle seed >|=? fun c -> (c, unrevealed) - -let for_cycle ctxt cycle = - let preserved = Constants_storage.preserved_cycles ctxt in - let current_level = Level_storage.current ctxt in - let current_cycle = current_level.cycle in - let latest = - if Cycle_repr.(current_cycle = root) then - Cycle_repr.add current_cycle (preserved + 1) - else Cycle_repr.add current_cycle preserved - in - let oldest = - match Cycle_repr.sub current_cycle preserved with - | None -> Cycle_repr.root - | Some oldest -> oldest - in - error_unless - Cycle_repr.(oldest <= cycle && cycle <= latest) - (Unknown {oldest; cycle; latest}) - >>?= fun () -> Storage.Seed.For_cycle.get ctxt cycle - -let init ctxt = - let preserved = Constants_storage.preserved_cycles ctxt in - List.fold_left_es - (fun (c, ctxt) seed -> - let cycle = Cycle_repr.of_int32_exn (Int32.of_int c) in - Storage.Seed.For_cycle.init ctxt cycle seed >|=? fun ctxt -> (c + 1, ctxt)) - (0, ctxt) - (Seed_repr.initial_seeds (preserved + 2)) - >|=? snd - -let cycle_end ctxt last_cycle = - (* NB: the clearing of past seeds is done elsewhere by the caller *) - let preserved = Constants_storage.preserved_cycles ctxt in - match Cycle_repr.pred last_cycle with - | None -> return (ctxt, []) - | Some revealed -> - (* cycle with revelations *) - let inited_seed_cycle = Cycle_repr.add last_cycle (preserved + 1) in - compute_for_cycle ctxt ~revealed inited_seed_cycle diff --git a/src/proto_012_Psithaca/lib_protocol/seed_storage.mli b/src/proto_012_Psithaca/lib_protocol/seed_storage.mli deleted file mode 100644 index 37e87efed99b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/seed_storage.mli +++ /dev/null @@ -1,47 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += - | Unknown of { - oldest : Cycle_repr.t; - cycle : Cycle_repr.t; - latest : Cycle_repr.t; - } - -(* `Permanent *) - -(** Generates the first [preserved_cycles+2] seeds for which - there are no nonces. *) -val init : Raw_context.t -> Raw_context.t tzresult Lwt.t - -val for_cycle : Raw_context.t -> Cycle_repr.t -> Seed_repr.seed tzresult Lwt.t - -(** If it is the end of the cycle, computes and stores the seed of cycle at - distance [preserved_cycle+2] in the future using the seed of the previous - cycle and the revelations of the current one. *) -val cycle_end : - Raw_context.t -> - Cycle_repr.t -> - (Raw_context.t * Nonce_storage.unrevealed list) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/services_registration.ml b/src/proto_012_Psithaca/lib_protocol/services_registration.ml deleted file mode 100644 index 41880bfc28c3..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/services_registration.ml +++ /dev/null @@ -1,122 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -type rpc_context = { - block_hash : Block_hash.t; - block_header : Block_header.shell_header; - context : Alpha_context.t; -} - -let rpc_init ({block_hash; block_header; context} : Updater.rpc_context) = - let level = block_header.level in - let timestamp = block_header.timestamp in - Alpha_context.prepare - ~level - ~predecessor_timestamp:timestamp - ~timestamp - context - >|=? fun (context, _, _) -> {block_hash; block_header; context} - -let rpc_services = - ref (RPC_directory.empty : Updater.rpc_context RPC_directory.t) - -let register0_fullctxt ~chunked s f = - rpc_services := - RPC_directory.register ~chunked !rpc_services s (fun ctxt q i -> - rpc_init ctxt >>=? fun ctxt -> f ctxt q i) - -let register0 ~chunked s f = - register0_fullctxt ~chunked s (fun {context; _} -> f context) - -let register0_noctxt ~chunked s f = - rpc_services := - RPC_directory.register ~chunked !rpc_services s (fun _ q i -> f q i) - -let register1_fullctxt ~chunked s f = - rpc_services := - RPC_directory.register ~chunked !rpc_services s (fun (ctxt, arg) q i -> - rpc_init ctxt >>=? fun ctxt -> f ctxt arg q i) - -let register1 ~chunked s f = - register1_fullctxt ~chunked s (fun {context; _} x -> f context x) - -let register2_fullctxt ~chunked s f = - rpc_services := - RPC_directory.register - ~chunked - !rpc_services - s - (fun ((ctxt, arg1), arg2) q i -> - rpc_init ctxt >>=? fun ctxt -> f ctxt arg1 arg2 q i) - -let register2 ~chunked s f = - register2_fullctxt ~chunked s (fun {context; _} a1 a2 q i -> - f context a1 a2 q i) - -let opt_register0_fullctxt ~chunked s f = - rpc_services := - RPC_directory.opt_register ~chunked !rpc_services s (fun ctxt q i -> - rpc_init ctxt >>=? fun ctxt -> f ctxt q i) - -let opt_register0 ~chunked s f = - opt_register0_fullctxt ~chunked s (fun {context; _} -> f context) - -let opt_register1_fullctxt ~chunked s f = - rpc_services := - RPC_directory.opt_register ~chunked !rpc_services s (fun (ctxt, arg) q i -> - rpc_init ctxt >>=? fun ctxt -> f ctxt arg q i) - -let opt_register1 ~chunked s f = - opt_register1_fullctxt ~chunked s (fun {context; _} x -> f context x) - -let opt_register2_fullctxt ~chunked s f = - rpc_services := - RPC_directory.opt_register - ~chunked - !rpc_services - s - (fun ((ctxt, arg1), arg2) q i -> - rpc_init ctxt >>=? fun ctxt -> f ctxt arg1 arg2 q i) - -let opt_register2 ~chunked s f = - opt_register2_fullctxt ~chunked s (fun {context; _} a1 a2 q i -> - f context a1 a2 q i) - -let get_rpc_services () = - let p = - RPC_directory.map - (fun c -> - rpc_init c >|= function - | Error t -> - raise (Failure (Format.asprintf "%a" Error_monad.pp_trace t)) - | Ok c -> c.context) - (Storage_description.build_directory Alpha_context.description) - in - RPC_directory.register_dynamic_directory - !rpc_services - RPC_path.(open_root / "context" / "raw" / "json") - (fun _ -> Lwt.return p) diff --git a/src/proto_012_Psithaca/lib_protocol/services_registration.mli b/src/proto_012_Psithaca/lib_protocol/services_registration.mli deleted file mode 100644 index 7c6df68ebd23..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/services_registration.mli +++ /dev/null @@ -1,127 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Functions for RPC service registration, using [Updater.rpc_context] and - [RPC_service.t] from the Protocol Environment. - - This module is a frontend to a mutable service directory. The various - [register] functions update the directory as a side-effect. - - The [get_rpc_services] function returns the resulting [RPC_context]. It is - parameterized by [Updater.rpc_context] which acts as the service prefix (in - practice meaning this type will be passed to each handler). Hence, - Protocol RPC services provide a {i read-only} view of the Ledger state. - *) - -open Alpha_context - -type rpc_context = { - block_hash : Block_hash.t; - block_header : Block_header.shell_header; - context : t; -} - -val rpc_init : Updater.rpc_context -> rpc_context Error_monad.tzresult Lwt.t - -val register0 : - chunked:bool -> - ( [< RPC_service.meth], - Updater.rpc_context, - Updater.rpc_context, - 'a, - 'b, - 'c ) - RPC_service.t -> - (t -> 'a -> 'b -> 'c Error_monad.tzresult Lwt.t) -> - unit - -val register0_noctxt : - chunked:bool -> - ([< RPC_service.meth], Updater.rpc_context, 'a, 'b, 'c, 'd) RPC_service.t -> - ('b -> 'c -> 'd Error_monad.tzresult Lwt.t) -> - unit - -val register1 : - chunked:bool -> - ( [< RPC_service.meth], - Updater.rpc_context, - Updater.rpc_context * 'a, - 'b, - 'c, - 'd ) - RPC_service.t -> - (t -> 'a -> 'b -> 'c -> 'd Error_monad.tzresult Lwt.t) -> - unit - -val register2 : - chunked:bool -> - ( [< RPC_service.meth], - Updater.rpc_context, - (Updater.rpc_context * 'a) * 'b, - 'c, - 'd, - 'e ) - RPC_service.t -> - (t -> 'a -> 'b -> 'c -> 'd -> 'e Error_monad.tzresult Lwt.t) -> - unit - -val opt_register0 : - chunked:bool -> - ( [< RPC_service.meth], - Updater.rpc_context, - Updater.rpc_context, - 'a, - 'b, - 'c ) - RPC_service.t -> - (t -> 'a -> 'b -> 'c option Error_monad.tzresult Lwt.t) -> - unit - -val opt_register1 : - chunked:bool -> - ( [< RPC_service.meth], - Updater.rpc_context, - Updater.rpc_context * 'a, - 'b, - 'c, - 'd ) - RPC_service.t -> - (t -> 'a -> 'b -> 'c -> 'd option Error_monad.tzresult Lwt.t) -> - unit - -val opt_register2 : - chunked:bool -> - ( [< RPC_service.meth], - Updater.rpc_context, - (Updater.rpc_context * 'a) * 'b, - 'c, - 'd, - 'e ) - RPC_service.t -> - (t -> 'a -> 'b -> 'c -> 'd -> 'e option Error_monad.tzresult Lwt.t) -> - unit - -val get_rpc_services : unit -> Updater.rpc_context RPC_directory.directory diff --git a/src/proto_012_Psithaca/lib_protocol/slot_repr.ml b/src/proto_012_Psithaca/lib_protocol/slot_repr.ml deleted file mode 100644 index 3b6c861b2022..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/slot_repr.ml +++ /dev/null @@ -1,138 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type error += Invalid_slot of int - -let () = - register_error_kind - `Permanent - ~id:"slot.invalid_slot" - ~title:"invalid slot" - ~description:"Invalid slot" - ~pp:(fun ppf x -> Format.fprintf ppf "invalid slot: %d" x) - Data_encoding.(obj1 (req "bad_slot" int31)) - (function Invalid_slot x -> Some x | _ -> None) - (fun x -> Invalid_slot x) - -include Compare.Int - -(* TODO? should there be some assertions to verify that slots are - never too big ? Or do that in a storage module that depends on - constants ? *) - -let encoding = Data_encoding.uint16 - -let pp = Format.pp_print_int - -let zero = 0 - -let succ = succ - -let to_int x = x - -let max_value = (1 lsl 16) - 1 - -let of_int_do_not_use_except_for_parameters i = i - -let of_int_exn i = - if Compare.Int.(i < 0 || i > max_value) then - invalid_arg - (Format.sprintf - "valid slot values are in the interval [0, %d] (%d given)" - max_value - i) - else i - -module Map = Map.Make (Compare.Int) -module Set = Set.Make (Compare.Int) - -module List = struct - (* Expected invariant: list of increasing values *) - (* TODO find a way to properly enforce this invariant *) - type nonrec t = t list - - module Compressed = struct - type elt = {skip : int; take : int} - - type encoded = elt list - - let elt_encoding = - Data_encoding.( - conv - (fun {skip; take} -> (skip, take)) - (fun (skip, take) -> {skip; take}) - (obj2 (req "skip" uint16) (req "take" uint16))) - - let encoding = Data_encoding.list elt_encoding - - let encode l : encoded = - let rec loop_taking ~pos ~skipped ~taken l = - match l with - | [] -> if taken > 0 then [{skip = skipped; take = taken}] else [] - | h :: t -> - if h = pos then - loop_taking ~pos:(pos + 1) ~skipped ~taken:(taken + 1) t - else - let elt = {skip = skipped; take = taken} in - let skipped = h - pos in - let taken = 1 in - let elts = loop_taking ~pos:(h + 1) ~skipped ~taken t in - elt :: elts - in - loop_taking ~pos:0 ~skipped:0 ~taken:0 l - - let decode (elts : encoded) = - let rec loop ~pos elts = - match elts with - | [] -> Ok [] - | elt :: elts -> ( - let pos = pos + elt.skip in - match - List.init ~when_negative_length:() elt.take (fun i -> i + pos) - with - | Ok l -> ( - let pos = pos + elt.take in - match loop ~pos elts with Ok t -> Ok (l @ t) | e -> e) - | Error () -> - Error "A compressed element contains a negative list size") - in - loop ~pos:0 elts - end - - let encoding = - Data_encoding.conv_with_guard - Compressed.encode - Compressed.decode - Compressed.encoding - - let slot_range ~min ~count = - error_when (min < 0) (Invalid_slot min) >>? fun () -> - error_when (min > max_value) (Invalid_slot min) >>? fun () -> - error_when (count < 1) (Invalid_slot count) >>? fun () -> - error_when (count > max_value) (Invalid_slot count) >>? fun () -> - let max = min + count - 1 in - error_when (max > max_value) (Invalid_slot max) >>? fun () -> - ok Misc.(min --> max) -end diff --git a/src/proto_012_Psithaca/lib_protocol/slot_repr.mli b/src/proto_012_Psithaca/lib_protocol/slot_repr.mli deleted file mode 100644 index c173ce7c7251..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/slot_repr.mli +++ /dev/null @@ -1,63 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2057 - remake abstract (required index for storage) *) -type t = int - -val encoding : t Data_encoding.t - -val pp : Format.formatter -> t -> unit - -val zero : t - -val succ : t -> t - -val max_value : t - -val of_int_do_not_use_except_for_parameters : int -> t - -(** [of_int i] creates a slot index from integer [i] - - @raise Invalid_argument if [i < 0 || i > max_value] -*) -val of_int_exn : int -> t - -val to_int : t -> int - -module Map : Map.S with type key = t - -module Set : Set.S with type elt = t - -include Compare.S with type t := t - -module List : sig - (* Expected invariant: list of increasing values *) - type nonrec t = t list - - val encoding : t Data_encoding.t - - val slot_range : min:int -> count:int -> t tzresult -end diff --git a/src/proto_012_Psithaca/lib_protocol/stake_storage.ml b/src/proto_012_Psithaca/lib_protocol/stake_storage.ml deleted file mode 100644 index 2927c48e8348..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/stake_storage.ml +++ /dev/null @@ -1,325 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Misc - -module Selected_distribution_for_cycle = struct - module Cache_client = struct - type cached_value = (Signature.Public_key_hash.t * Tez_repr.t) list - - let namespace = Cache_repr.create_namespace "stake_distribution" - - let cache_index = 1 - - let value_of_identifier ctxt identifier = - let cycle = Cycle_repr.of_string_exn identifier in - Storage.Stake.Selected_distribution_for_cycle.get ctxt cycle - end - - module Cache = (val Cache_repr.register_exn (module Cache_client)) - - let identifier_of_cycle cycle = Format.asprintf "%a" Cycle_repr.pp cycle - - let init ctxt cycle stakes = - let id = identifier_of_cycle cycle in - Storage.Stake.Selected_distribution_for_cycle.init ctxt cycle stakes - >>=? fun ctxt -> - let size = Constants_repr.stake_distribution_size in - Cache.update ctxt id (Some (stakes, size)) >>?= fun ctxt -> return ctxt - - let get ctxt cycle = - let id = identifier_of_cycle cycle in - Cache.find ctxt id >>=? function - | None -> Storage.Stake.Selected_distribution_for_cycle.get ctxt cycle - | Some v -> return v - - let remove_existing ctxt cycle = - let id = identifier_of_cycle cycle in - (Cache.find ctxt id >>=? function - | None -> return ctxt - | Some _ -> Cache.update ctxt id None |> Lwt.return) - >>=? fun ctxt -> - Storage.Stake.Selected_distribution_for_cycle.remove_existing ctxt cycle -end - -module Delegate_sampler_state = struct - module Cache_client = struct - type cached_value = - (Signature.Public_key.t * Signature.Public_key_hash.t) Sampler.t - - let namespace = Cache_repr.create_namespace "sampler_state" - - let cache_index = 2 - - let value_of_identifier ctxt identifier = - let cycle = Cycle_repr.of_string_exn identifier in - Storage.Delegate_sampler_state.get ctxt cycle - end - - module Cache = (val Cache_repr.register_exn (module Cache_client)) - - let identifier_of_cycle cycle = Format.asprintf "%a" Cycle_repr.pp cycle - - let init ctxt cycle sampler_state = - let id = identifier_of_cycle cycle in - Storage.Delegate_sampler_state.init ctxt cycle sampler_state - >>=? fun ctxt -> - let size = Constants_repr.sampler_state_size in - Cache.update ctxt id (Some (sampler_state, size)) >>?= fun ctxt -> - return ctxt - - let get ctxt cycle = - let id = identifier_of_cycle cycle in - Cache.find ctxt id >>=? function - | None -> Storage.Delegate_sampler_state.get ctxt cycle - | Some v -> return v - - let remove_existing ctxt cycle = - let id = identifier_of_cycle cycle in - (Cache.find ctxt id >>=? function - | None -> return ctxt - | Some _ -> Cache.update ctxt id None |> Lwt.return) - >>=? fun ctxt -> Storage.Delegate_sampler_state.remove_existing ctxt cycle -end - -let get_staking_balance = Storage.Stake.Staking_balance.get - -let ensure_stake_inited ctxt delegate = - Storage.Stake.Staking_balance.mem ctxt delegate >>= function - | true -> return ctxt - | false -> - Frozen_deposits_storage.init ctxt delegate >>=? fun ctxt -> - Storage.Stake.Staking_balance.init ctxt delegate Tez_repr.zero - -let remove_stake ctxt delegate amount = - ensure_stake_inited ctxt delegate >>=? fun ctxt -> - let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - get_staking_balance ctxt delegate >>=? fun staking_balance_before -> - Tez_repr.(staking_balance_before -? amount) >>?= fun staking_balance -> - Storage.Stake.Staking_balance.update ctxt delegate staking_balance - >>=? fun ctxt -> - Delegate_activation_storage.is_inactive ctxt delegate >>=? fun inactive -> - if (not inactive) && Tez_repr.(staking_balance_before >= tokens_per_roll) then - if Tez_repr.(staking_balance < tokens_per_roll) then - Storage.Stake.Active_delegate_with_one_roll.remove ctxt delegate - >>= fun ctxt -> return ctxt - else return ctxt - else - (* The delegate was not in Stake.Active_delegate_with_one_roll, - either because it was inactive, or because it did not have a - roll, in which case it still does not have a roll. *) - return ctxt - -let add_stake ctxt delegate amount = - ensure_stake_inited ctxt delegate >>=? fun ctxt -> - let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - get_staking_balance ctxt delegate >>=? fun staking_balance_before -> - Tez_repr.(amount +? staking_balance_before) >>?= fun staking_balance -> - Storage.Stake.Staking_balance.update ctxt delegate staking_balance - >>=? fun ctxt -> - if Tez_repr.(staking_balance >= tokens_per_roll) then - Delegate_activation_storage.is_inactive ctxt delegate >>=? fun inactive -> - if inactive || Tez_repr.(staking_balance_before >= tokens_per_roll) then - return ctxt - else - Storage.Stake.Active_delegate_with_one_roll.add ctxt delegate () - >>= fun ctxt -> return ctxt - else - (* The delegate was not in Stake.Active_delegate_with_one_roll, - because it did not have a roll (as otherwise it would have a - roll now). *) - return ctxt - -let deactivate_only_call_from_delegate_storage ctxt delegate = - Storage.Stake.Active_delegate_with_one_roll.remove ctxt delegate - -let activate_only_call_from_delegate_storage ctxt delegate = - ensure_stake_inited ctxt delegate >>=? fun ctxt -> - get_staking_balance ctxt delegate >>=? fun staking_balance -> - let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in - if Tez_repr.(staking_balance >= tokens_per_roll) then - Storage.Stake.Active_delegate_with_one_roll.add ctxt delegate () - >>= fun ctxt -> return ctxt - else return ctxt - -let snapshot ctxt = - Storage.Stake.Last_snapshot.get ctxt >>=? fun index -> - Storage.Stake.Last_snapshot.update ctxt (index + 1) >>=? fun ctxt -> - Storage.Stake.Staking_balance.snapshot ctxt index >>=? fun ctxt -> - Storage.Stake.Active_delegate_with_one_roll.snapshot ctxt index - -let select_distribution_for_cycle ctxt cycle pubkey = - Storage.Stake.Last_snapshot.get ctxt >>=? fun max_index -> - Storage.Seed.For_cycle.get ctxt cycle >>=? fun seed -> - let rd = Seed_repr.initialize_new seed [Bytes.of_string "stake_snapshot"] in - let seq = Seed_repr.sequence rd 0l in - let selected_index = - Seed_repr.take_int32 seq (Int32.of_int max_index) |> fst |> Int32.to_int - in - List.fold_left_es - (fun ctxt index -> - (if Compare.Int.(index = selected_index) then - Storage.Stake.Active_delegate_with_one_roll.fold_snapshot - ctxt - index - ~order:`Sorted - ~init:([], Tez_repr.zero) - ~f:(fun delegate () (acc, total_stake) -> - Storage.Stake.Staking_balance.Snapshot.get ctxt (index, delegate) - >>=? fun staking_balance -> - let delegate_contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Frozen_deposits_limit.find ctxt delegate_contract - >>=? fun frozen_deposits_limit -> - Storage.Contract.Balance.get ctxt delegate_contract - >>=? fun balance -> - Frozen_deposits_storage.get ctxt delegate_contract - >>=? fun frozen_deposits -> - Tez_repr.(balance +? frozen_deposits.current_amount) - >>?= fun total_balance -> - let frozen_deposits_percentage = - Constants_storage.frozen_deposits_percentage ctxt - in - let stake_to_consider = - match frozen_deposits_limit with - | Some frozen_deposits_limit -> ( - try - let max_mutez = Tez_repr.of_mutez_exn Int64.max_int in - let frozen_stake_limit = - if Tez_repr.(frozen_deposits_limit > div_exn max_mutez 100) - then max_mutez - else - Tez_repr.( - div_exn - (mul_exn frozen_deposits_limit 100) - frozen_deposits_percentage) - in - Tez_repr.min staking_balance frozen_stake_limit - with _ -> staking_balance) - | None -> staking_balance - in - let max_staking_capacity = - Tez_repr.( - div_exn (mul_exn total_balance 100) frozen_deposits_percentage) - in - let stake_for_cycle = - Tez_repr.min stake_to_consider max_staking_capacity - in - Tez_repr.(total_stake +? stake_for_cycle) >>?= fun total_stake -> - return ((delegate, stake_for_cycle) :: acc, total_stake)) - >>=? fun (stakes, total_stake) -> - let stakes = - List.sort (fun (_, x) (_, y) -> Tez_repr.compare y x) stakes - in - Selected_distribution_for_cycle.init ctxt cycle stakes >>=? fun ctxt -> - Storage.Total_active_stake.add ctxt cycle total_stake >>= fun ctxt -> - List.fold_left_es - (fun acc (pkh, stake) -> - pubkey ctxt pkh >>=? fun pk -> - return (((pk, pkh), Tez_repr.to_mutez stake) :: acc)) - [] - stakes - >>=? fun stakes_pk -> - let state = Sampler.create stakes_pk in - Delegate_sampler_state.init ctxt cycle state - else return ctxt) - >>=? fun ctxt -> - Storage.Stake.Staking_balance.delete_snapshot ctxt index >>= fun ctxt -> - Storage.Stake.Active_delegate_with_one_roll.delete_snapshot ctxt index - >>= fun ctxt -> return ctxt) - ctxt - Misc.(0 --> (max_index - 1)) - >>=? fun ctxt -> Storage.Stake.Last_snapshot.update ctxt 0 - -let select_distribution_for_cycle_do_not_call_except_for_migration = - select_distribution_for_cycle - -let clear_cycle ctxt cycle = - Storage.Total_active_stake.remove_existing ctxt cycle >>=? fun ctxt -> - Selected_distribution_for_cycle.remove_existing ctxt cycle >>=? fun ctxt -> - Delegate_sampler_state.remove_existing ctxt cycle >>=? fun ctxt -> - Storage.Seed.For_cycle.remove_existing ctxt cycle - -let init_first_cycles ctxt pubkey = - let preserved = Constants_storage.preserved_cycles ctxt in - List.fold_left_es - (fun ctxt c -> - let cycle = Cycle_repr.of_int32_exn (Int32.of_int c) in - snapshot ctxt >>=? fun ctxt -> - select_distribution_for_cycle ctxt cycle pubkey) - ctxt - (0 --> preserved) - >>=? fun ctxt -> - (* Precompute a snapshot for cycle (preserved_cycles + 1) *) - snapshot ctxt - -let fold ctxt ~f ~order init = - Storage.Stake.Active_delegate_with_one_roll.fold - ctxt - ~order - ~init:(Ok init) - ~f:(fun delegate () acc -> - acc >>?= fun acc -> - get_staking_balance ctxt delegate >>=? fun stake -> - f (delegate, stake) acc) - -let select_new_distribution_at_cycle_end ctxt ~new_cycle = - let preserved = Constants_storage.preserved_cycles ctxt in - let for_cycle = Cycle_repr.add new_cycle preserved in - select_distribution_for_cycle ctxt for_cycle - -let clear_at_cycle_end ctxt ~new_cycle = - let max_slashing_period = Constants_storage.max_slashing_period ctxt in - match Cycle_repr.sub new_cycle max_slashing_period with - | None -> return ctxt - | Some cycle_to_clear -> clear_cycle ctxt cycle_to_clear - -let get ctxt delegate = - Storage.Stake.Active_delegate_with_one_roll.mem ctxt delegate >>= function - | true -> get_staking_balance ctxt delegate - | false -> return Tez_repr.zero - -let fold_on_active_delegates_with_rolls = - Storage.Stake.Active_delegate_with_one_roll.fold - -let get_selected_distribution = Selected_distribution_for_cycle.get - -let find_selected_distribution = - Storage.Stake.Selected_distribution_for_cycle.find - -let prepare_stake_distribution ctxt = - let level = Level_storage.current ctxt in - Selected_distribution_for_cycle.get ctxt level.cycle >>=? fun stakes -> - let stake_distribution = - List.fold_left - (fun map (pkh, stake) -> Signature.Public_key_hash.Map.add pkh stake map) - Signature.Public_key_hash.Map.empty - stakes - in - return - (Raw_context.init_stake_distribution_for_current_cycle - ctxt - stake_distribution) - -let get_total_active_stake = Storage.Total_active_stake.get diff --git a/src/proto_012_Psithaca/lib_protocol/stake_storage.mli b/src/proto_012_Psithaca/lib_protocol/stake_storage.mli deleted file mode 100644 index 66984a63211e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/stake_storage.mli +++ /dev/null @@ -1,126 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Delegate_sampler_state : sig - val init : - Raw_context.t -> - Cycle_repr.t -> - Storage.Delegate_sampler_state.value -> - Raw_context.t tzresult Lwt.t - - val get : - Raw_context.t -> - Cycle_repr.t -> - Storage.Delegate_sampler_state.value tzresult Lwt.t - - val remove_existing : - Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t -end - -val remove_stake : - Raw_context.t -> - Signature.Public_key_hash.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t - -val add_stake : - Raw_context.t -> - Signature.Public_key_hash.t -> - Tez_repr.t -> - Raw_context.t tzresult Lwt.t - -val deactivate_only_call_from_delegate_storage : - Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t Lwt.t - -val activate_only_call_from_delegate_storage : - Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t - -val get_staking_balance : - Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t - -val snapshot : Raw_context.t -> Raw_context.t tzresult Lwt.t - -val select_distribution_for_cycle_do_not_call_except_for_migration : - Raw_context.t -> - Cycle_repr.t -> - (Raw_context.t -> - Signature.Public_key_hash.t -> - Signature.Public_key.t tzresult Lwt.t) -> - Raw_context.t tzresult Lwt.t - -val clear_cycle : Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t - -val init_first_cycles : - Raw_context.t -> - (Raw_context.t -> - Signature.Public_key_hash.t -> - Signature.Public_key.t tzresult Lwt.t) -> - Raw_context.t tzresult Lwt.t - -val fold : - Raw_context.t -> - f:(Signature.Public_key_hash.t * Tez_repr.t -> 'a -> 'a tzresult Lwt.t) -> - order:[`Sorted | `Undefined] -> - 'a -> - 'a tzresult Lwt.t - -val select_new_distribution_at_cycle_end : - Raw_context.t -> - new_cycle:Cycle_repr.t -> - (Raw_context.t -> - Signature.Public_key_hash.t -> - Signature.Public_key.t tzresult Lwt.t) -> - Raw_context.t tzresult Lwt.t - -val clear_at_cycle_end : - Raw_context.t -> new_cycle:Cycle_repr.t -> Raw_context.t tzresult Lwt.t - -val get : - Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t - -val fold_on_active_delegates_with_rolls : - Raw_context.t -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(Signature.Public_key_hash.t -> unit -> 'a -> 'a Lwt.t) -> - 'a Lwt.t - -val get_selected_distribution : - Raw_context.t -> - Cycle_repr.t -> - (Signature.Public_key_hash.t * Tez_repr.t) list tzresult Lwt.t - -val find_selected_distribution : - Raw_context.t -> - Cycle_repr.t -> - (Signature.Public_key_hash.t * Tez_repr.t) list option tzresult Lwt.t - -(** Copy the stake distribution for the current cycle (from - [Storage.Stake.Selected_distribution_for_cycle]) in the raw - context. *) -val prepare_stake_distribution : Raw_context.t -> Raw_context.t tzresult Lwt.t - -val get_total_active_stake : - Raw_context.t -> Cycle_repr.t -> Tez_repr.t tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/state_hash.ml b/src/proto_012_Psithaca/lib_protocol/state_hash.ml deleted file mode 100644 index a39ce4a21127..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/state_hash.ml +++ /dev/null @@ -1,44 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let random_state_hash = "\076\064\204" (* rng(53): never used... *) - -module H = - Blake2B.Make - (Base58) - (struct - let name = "random" - - let title = "A random generation state" - - let b58check_prefix = random_state_hash - - let size = None - end) - -include H -include Path_encoding.Make_hex (H) - -let () = Base58.check_encoded_prefix b58check_encoding "rng" 53 diff --git a/src/proto_012_Psithaca/lib_protocol/state_hash.mli b/src/proto_012_Psithaca/lib_protocol/state_hash.mli deleted file mode 100644 index 7ae77f3a0c42..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/state_hash.mli +++ /dev/null @@ -1,30 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** A specialized Blake2B implementation for hashing internal states of random - number generators. *) - -include S.HASH diff --git a/src/proto_012_Psithaca/lib_protocol/storage.ml b/src/proto_012_Psithaca/lib_protocol/storage.ml deleted file mode 100644 index 1dfc0041e643..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/storage.ml +++ /dev/null @@ -1,1616 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Storage_functors -open Storage_sigs - -module Encoding = struct - module UInt16 = struct - type t = int - - let encoding = Data_encoding.uint16 - end - - module Int32 = struct - type t = Int32.t - - let encoding = Data_encoding.int32 - end - - module Int64 = struct - type t = Int64.t - - let encoding = Data_encoding.int64 - end - - module Z = struct - type t = Z.t - - let encoding = Data_encoding.z - end -end - -module Int31_index : sig - include INDEX with type t = int -end = struct - type t = int - - let path_length = 1 - - let to_path c l = string_of_int c :: l - - let of_path = function [] | _ :: _ :: _ -> None | [c] -> int_of_string_opt c - - type 'a ipath = 'a * t - - let args = - Storage_description.One - { - rpc_arg = RPC_arg.int; - encoding = Data_encoding.int31; - compare = Compare.Int.compare; - } -end - -module Make_index (H : Storage_description.INDEX) : - INDEX with type t = H.t and type 'a ipath = 'a * H.t = struct - include H - - type 'a ipath = 'a * t - - let args = Storage_description.One {rpc_arg; encoding; compare} -end - -module type Simple_single_data_storage = sig - type value - - val get : Raw_context.t -> value tzresult Lwt.t - - val update : Raw_context.t -> value -> Raw_context.t tzresult Lwt.t - - val init : Raw_context.t -> value -> Raw_context.t tzresult Lwt.t -end - -module Legacy_block_priority : - Simple_single_data_storage with type value = int = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["block_priority"] - end) - (Encoding.UInt16) - -module Block_round : Simple_single_data_storage with type value = Round_repr.t = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["block_round"] - end) - (Round_repr) - -module Tenderbake = struct - module First_level = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["first_level_of_Tenderbake"] - end) - (Raw_level_repr) - - module Branch = struct - type t = Block_hash.t * Block_payload_hash.t - - let encoding = - Data_encoding.( - obj2 - (req "grand_parent_hash" Block_hash.encoding) - (req "predecessor_payload" Block_payload_hash.encoding)) - end - - module Endorsement_branch = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["endorsement_branch"] - end) - (Branch) - - module Grand_parent_branch = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["grand_parent_branch"] - end) - (Branch) -end - -(** Contracts handling *) - -type deposits = {initial_amount : Tez_repr.t; current_amount : Tez_repr.t} - -module Deposits = struct - type t = deposits - - let encoding = - let open Data_encoding in - conv - (fun {initial_amount; current_amount} -> (initial_amount, current_amount)) - (fun (initial_amount, current_amount) -> {initial_amount; current_amount}) - (obj2 - (req "initial_amount" Tez_repr.encoding) - (req "actual_amount" Tez_repr.encoding)) -end - -type missed_endorsements_info = {remaining_slots : int; missed_levels : int} - -module Missed_endorsements_info = struct - type t = missed_endorsements_info - - let encoding = - let open Data_encoding in - conv - (fun {remaining_slots; missed_levels} -> (remaining_slots, missed_levels)) - (fun (remaining_slots, missed_levels) -> {remaining_slots; missed_levels}) - (obj2 (req "remaining_slots" int31) (req "missed_levels" int31)) -end - -module Contract = struct - module Raw_context = - Make_subcontext (Registered) (Raw_context) - (struct - let name = ["contracts"] - end) - - module Global_counter : Simple_single_data_storage with type value = Z.t = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["global_counter"] - end) - (Encoding.Z) - - module Indexed_context = - Make_indexed_subcontext - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["index"] - end)) - (Make_index (Contract_repr.Index)) - - let fold = Indexed_context.fold_keys - - let list = Indexed_context.keys - - module Balance = - Indexed_context.Make_map - (struct - let name = ["balance"] - end) - (Tez_repr) - - module Missed_endorsements = - Indexed_context.Make_map - (struct - let name = ["missed_endorsements"] - end) - (Missed_endorsements_info) - - module Legacy_frozen_balance_index = - Make_indexed_subcontext - (Make_subcontext (Ghost) (Indexed_context.Raw_context) - (struct - let name = ["frozen_balance"] - end)) - (Make_index (Cycle_repr.Index)) - - module Legacy_frozen_deposits = - Legacy_frozen_balance_index.Make_map - (struct - let name = ["deposits"] - end) - (Tez_repr) - - module Legacy_frozen_fees = - Legacy_frozen_balance_index.Make_map - (struct - let name = ["fees"] - end) - (Tez_repr) - - module Legacy_frozen_rewards = - Legacy_frozen_balance_index.Make_map - (struct - let name = ["rewards"] - end) - (Tez_repr) - - module Manager = - Indexed_context.Make_map - (struct - let name = ["manager"] - end) - (Manager_repr) - - module Delegate = - Indexed_context.Make_map - (struct - let name = ["delegate"] - end) - (Signature.Public_key_hash) - - module Inactive_delegate = - Indexed_context.Make_set - (Registered) - (struct - let name = ["inactive_delegate"] - end) - - module Delegate_desactivation = - Indexed_context.Make_map - (struct - let name = ["delegate_desactivation"] - end) - (Cycle_repr) - - module Delegated = - Make_data_set_storage - (Make_subcontext (Registered) (Indexed_context.Raw_context) - (struct - let name = ["delegated"] - end)) - (Make_index (Contract_repr.Index)) - - module Counter = - Indexed_context.Make_map - (struct - let name = ["counter"] - end) - (Encoding.Z) - - (* Consume gas for serialization and deserialization of expr in this - module *) - module Make_carbonated_map_expr (N : Storage_sigs.NAME) : - Storage_sigs.Non_iterable_indexed_carbonated_data_storage - with type key = Contract_repr.t - and type value = Script_repr.lazy_expr - and type t := Raw_context.t = struct - module I = - Indexed_context.Make_carbonated_map - (N) - (struct - type t = Script_repr.lazy_expr - - let encoding = Script_repr.lazy_expr_encoding - end) - - type context = I.context - - type key = I.key - - type value = I.value - - let mem = I.mem - - let remove_existing = I.remove_existing - - let remove = I.remove - - let consume_deserialize_gas ctxt value = - Raw_context.consume_gas ctxt (Script_repr.force_decode_cost value) - - let consume_serialize_gas ctxt value = - Raw_context.consume_gas ctxt (Script_repr.force_bytes_cost value) - - let get ctxt contract = - I.get ctxt contract >>=? fun (ctxt, value) -> - Lwt.return - (consume_deserialize_gas ctxt value >|? fun ctxt -> (ctxt, value)) - - let find ctxt contract = - I.find ctxt contract >>=? fun (ctxt, value_opt) -> - Lwt.return - @@ - match value_opt with - | None -> ok (ctxt, None) - | Some value -> - consume_deserialize_gas ctxt value >|? fun ctxt -> (ctxt, value_opt) - - let update ctxt contract value = - consume_serialize_gas ctxt value >>?= fun ctxt -> - I.update ctxt contract value - - let add_or_remove ctxt contract value_opt = - match value_opt with - | None -> I.add_or_remove ctxt contract None - | Some value -> - consume_serialize_gas ctxt value >>?= fun ctxt -> - I.add_or_remove ctxt contract value_opt - - let init ctxt contract value = - consume_serialize_gas ctxt value >>?= fun ctxt -> - I.init ctxt contract value - - let add ctxt contract value = - consume_serialize_gas ctxt value >>?= fun ctxt -> - I.add ctxt contract value - end - - module Code = Make_carbonated_map_expr (struct - let name = ["code"] - end) - - module Storage = Make_carbonated_map_expr (struct - let name = ["storage"] - end) - - module Paid_storage_space = - Indexed_context.Make_map - (struct - let name = ["paid_bytes"] - end) - (Encoding.Z) - - module Used_storage_space = - Indexed_context.Make_map - (struct - let name = ["used_bytes"] - end) - (Encoding.Z) - - module Roll_list_legacy = - Indexed_context.Make_map - (struct - let name = ["roll_list"] - end) - (Roll_repr_legacy) - - module Change_legacy = - Indexed_context.Make_map - (struct - let name = ["change"] - end) - (Tez_repr) - - module Frozen_deposits = - Indexed_context.Make_map - (struct - let name = ["frozen_deposits"] - end) - (Deposits) - - module Frozen_deposits_limit = - Indexed_context.Make_map - (struct - let name = ["frozen_deposits_limit"] - end) - (Tez_repr) -end - -module type NEXT = sig - type id - - val init : Raw_context.t -> Raw_context.t tzresult Lwt.t - - val incr : Raw_context.t -> (Raw_context.t * id) tzresult Lwt.t -end - -module Global_constants = struct - module Map = - Make_indexed_carbonated_data_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["global_constant"] - end)) - (Make_index (Script_expr_hash)) - (struct - type t = Script_repr.expr - - let encoding = Script_repr.expr_encoding - end) -end - -(** Big maps handling *) - -module Big_map = struct - type id = Lazy_storage_kind.Big_map.Id.t - - module Raw_context = - Make_subcontext (Registered) (Raw_context) - (struct - let name = ["big_maps"] - end) - - module Next : NEXT with type id := id = struct - module Storage = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["next"] - end) - (Lazy_storage_kind.Big_map.Id) - - let incr ctxt = - Storage.get ctxt >>=? fun i -> - Storage.update ctxt (Lazy_storage_kind.Big_map.Id.next i) >|=? fun ctxt -> - (ctxt, i) - - let init ctxt = Storage.init ctxt Lazy_storage_kind.Big_map.Id.init - end - - module Index = Lazy_storage_kind.Big_map.Id - - module Indexed_context = - Make_indexed_subcontext - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["index"] - end)) - (Make_index (Index)) - - let rpc_arg = Index.rpc_arg - - let fold = Indexed_context.fold_keys - - let list = Indexed_context.keys - - let remove ctxt n = Indexed_context.remove ctxt n - - let copy ctxt ~from ~to_ = Indexed_context.copy ctxt ~from ~to_ - - type key = Raw_context.t * Index.t - - module Total_bytes = - Indexed_context.Make_map - (struct - let name = ["total_bytes"] - end) - (Encoding.Z) - - module Key_type = - Indexed_context.Make_map - (struct - let name = ["key_type"] - end) - (struct - type t = Script_repr.expr - - let encoding = Script_repr.expr_encoding - end) - - module Value_type = - Indexed_context.Make_map - (struct - let name = ["value_type"] - end) - (struct - type t = Script_repr.expr - - let encoding = Script_repr.expr_encoding - end) - - module Contents : - Non_iterable_indexed_carbonated_data_storage_with_values - with type key = Script_expr_hash.t - and type value = Script_repr.expr - and type t := key = struct - module I = - Storage_functors.Make_indexed_carbonated_data_storage - (Make_subcontext (Registered) (Indexed_context.Raw_context) - (struct - let name = ["contents"] - end)) - (Make_index (Script_expr_hash)) - (struct - type t = Script_repr.expr - - let encoding = Script_repr.expr_encoding - end) - - type context = I.context - - type key = I.key - - type value = I.value - - let mem = I.mem - - let remove_existing = I.remove_existing - - let remove = I.remove - - let update = I.update - - let add_or_remove = I.add_or_remove - - let init = I.init - - let add = I.add - - let list_values = I.list_values - - let consume_deserialize_gas ctxt value = - Raw_context.consume_gas ctxt (Script_repr.deserialized_cost value) - - let get ctxt contract = - I.get ctxt contract >>=? fun (ctxt, value) -> - Lwt.return - (consume_deserialize_gas ctxt value >|? fun ctxt -> (ctxt, value)) - - let find ctxt contract = - I.find ctxt contract >>=? fun (ctxt, value_opt) -> - Lwt.return - @@ - match value_opt with - | None -> ok (ctxt, None) - | Some value -> - consume_deserialize_gas ctxt value >|? fun ctxt -> (ctxt, value_opt) - end -end - -module Sapling = struct - type id = Lazy_storage_kind.Sapling_state.Id.t - - module Raw_context = - Make_subcontext (Registered) (Raw_context) - (struct - let name = ["sapling"] - end) - - module Next = struct - module Storage = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["next"] - end) - (Lazy_storage_kind.Sapling_state.Id) - - let incr ctxt = - Storage.get ctxt >>=? fun i -> - Storage.update ctxt (Lazy_storage_kind.Sapling_state.Id.next i) - >|=? fun ctxt -> (ctxt, i) - - let init ctxt = Storage.init ctxt Lazy_storage_kind.Sapling_state.Id.init - end - - module Index = Lazy_storage_kind.Sapling_state.Id - - let rpc_arg = Index.rpc_arg - - module Indexed_context = - Make_indexed_subcontext - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["index"] - end)) - (Make_index (Index)) - - let remove ctxt n = Indexed_context.remove ctxt n - - let copy ctxt ~from ~to_ = Indexed_context.copy ctxt ~from ~to_ - - module Total_bytes = - Indexed_context.Make_map - (struct - let name = ["total_bytes"] - end) - (Encoding.Z) - - module Commitments_size = - Make_single_data_storage (Registered) (Indexed_context.Raw_context) - (struct - let name = ["commitments_size"] - end) - (Encoding.Int64) - - module Memo_size = - Make_single_data_storage (Registered) (Indexed_context.Raw_context) - (struct - let name = ["memo_size"] - end) - (Sapling_repr.Memo_size) - - module Commitments : - Non_iterable_indexed_carbonated_data_storage - with type t := Raw_context.t * id - and type key = int64 - and type value = Sapling.Hash.t = - Make_indexed_carbonated_data_storage - (Make_subcontext (Registered) (Indexed_context.Raw_context) - (struct - let name = ["commitments"] - end)) - (Make_index (struct - type t = int64 - - let rpc_arg = - let construct = Int64.to_string in - let destruct hash = - Int64.of_string_opt hash - |> Result.of_option ~error:"Cannot parse node position" - in - RPC_arg.make - ~descr:"The position of a node in a sapling commitment tree" - ~name:"sapling_node_position" - ~construct - ~destruct - () - - let encoding = - Data_encoding.def - "sapling_node_position" - ~title:"Sapling node position" - ~description: - "The position of a node in a sapling commitment tree" - Data_encoding.int64 - - let compare = Compare.Int64.compare - - let path_length = 1 - - let to_path c l = Int64.to_string c :: l - - let of_path = function [c] -> Int64.of_string_opt c | _ -> None - end)) - (Sapling.Hash) - - let commitments_init ctx id = - Indexed_context.Raw_context.remove (ctx, id) ["commitments"] - >|= fun (ctx, _id) -> ctx - - module Ciphertexts : - Non_iterable_indexed_carbonated_data_storage - with type t := Raw_context.t * id - and type key = int64 - and type value = Sapling.Ciphertext.t = - Make_indexed_carbonated_data_storage - (Make_subcontext (Registered) (Indexed_context.Raw_context) - (struct - let name = ["ciphertexts"] - end)) - (Make_index (struct - type t = int64 - - let rpc_arg = - let construct = Int64.to_string in - let destruct hash = - Int64.of_string_opt hash - |> Result.of_option ~error:"Cannot parse ciphertext position" - in - RPC_arg.make - ~descr:"The position of a sapling ciphertext" - ~name:"sapling_ciphertext_position" - ~construct - ~destruct - () - - let encoding = - Data_encoding.def - "sapling_ciphertext_position" - ~title:"Sapling ciphertext position" - ~description:"The position of a sapling ciphertext" - Data_encoding.int64 - - let compare = Compare.Int64.compare - - let path_length = 1 - - let to_path c l = Int64.to_string c :: l - - let of_path = function [c] -> Int64.of_string_opt c | _ -> None - end)) - (Sapling.Ciphertext) - - let ciphertexts_init ctx id = - Indexed_context.Raw_context.remove (ctx, id) ["commitments"] - >|= fun (ctx, _id) -> ctx - - module Nullifiers_size = - Make_single_data_storage (Registered) (Indexed_context.Raw_context) - (struct - let name = ["nullifiers_size"] - end) - (Encoding.Int64) - - (* For sequential access when building a diff *) - module Nullifiers_ordered : - Non_iterable_indexed_data_storage - with type t := Raw_context.t * id - and type key = int64 - and type value = Sapling.Nullifier.t = - Make_indexed_data_storage - (Make_subcontext (Registered) (Indexed_context.Raw_context) - (struct - let name = ["nullifiers_ordered"] - end)) - (Make_index (struct - type t = int64 - - let rpc_arg = - let construct = Int64.to_string in - let destruct hash = - Int64.of_string_opt hash - |> Result.of_option ~error:"Cannot parse nullifier position" - in - RPC_arg.make - ~descr:"A sapling nullifier position" - ~name:"sapling_nullifier_position" - ~construct - ~destruct - () - - let encoding = - Data_encoding.def - "sapling_nullifier_position" - ~title:"Sapling nullifier position" - ~description:"Sapling nullifier position" - Data_encoding.int64 - - let compare = Compare.Int64.compare - - let path_length = 1 - - let to_path c l = Int64.to_string c :: l - - let of_path = function [c] -> Int64.of_string_opt c | _ -> None - end)) - (Sapling.Nullifier) - - (* Check membership in O(1) for verify_update *) - module Nullifiers_hashed = - Make_carbonated_data_set_storage - (Make_subcontext (Registered) (Indexed_context.Raw_context) - (struct - let name = ["nullifiers_hashed"] - end)) - (Make_index (struct - type t = Sapling.Nullifier.t - - let encoding = Sapling.Nullifier.encoding - - let of_string hexstring = - Option.bind - (Hex.to_bytes (`Hex hexstring)) - (Data_encoding.Binary.of_bytes_opt encoding) - |> Result.of_option ~error:"Cannot parse sapling nullifier" - - let to_string nf = - let b = Data_encoding.Binary.to_bytes_exn encoding nf in - let (`Hex hexstring) = Hex.of_bytes b in - hexstring - - let rpc_arg = - RPC_arg.make - ~descr:"A sapling nullifier" - ~name:"sapling_nullifier" - ~construct:to_string - ~destruct:of_string - () - - let compare = Sapling.Nullifier.compare - - let path_length = 1 - - let to_path c l = to_string c :: l - - let of_path = function - | [c] -> Result.to_option (of_string c) - | _ -> None - end)) - - let nullifiers_init ctx id = - Nullifiers_size.add (ctx, id) Int64.zero >>= fun ctx -> - Indexed_context.Raw_context.remove (ctx, id) ["nullifiers_ordered"] - >>= fun (ctx, id) -> - Indexed_context.Raw_context.remove (ctx, id) ["nullifiers_hashed"] - >|= fun (ctx, _id) -> ctx - - module Roots : - Non_iterable_indexed_data_storage - with type t := Raw_context.t * id - and type key = int32 - and type value = Sapling.Hash.t = - Make_indexed_data_storage - (Make_subcontext (Registered) (Indexed_context.Raw_context) - (struct - let name = ["roots"] - end)) - (Make_index (struct - type t = int32 - - let rpc_arg = - let construct = Int32.to_string in - let destruct hash = - Int32.of_string_opt hash - |> Result.of_option ~error:"Cannot parse nullifier position" - in - RPC_arg.make - ~descr:"A sapling root" - ~name:"sapling_root" - ~construct - ~destruct - () - - let encoding = - Data_encoding.def - "sapling_root" - ~title:"Sapling root" - ~description:"Sapling root" - Data_encoding.int32 - - let compare = Compare.Int32.compare - - let path_length = 1 - - let to_path c l = Int32.to_string c :: l - - let of_path = function [c] -> Int32.of_string_opt c | _ -> None - end)) - (Sapling.Hash) - - module Roots_pos = - Make_single_data_storage (Registered) (Indexed_context.Raw_context) - (struct - let name = ["roots_pos"] - end) - (Encoding.Int32) - - module Roots_level = - Make_single_data_storage (Registered) (Indexed_context.Raw_context) - (struct - let name = ["roots_level"] - end) - (Raw_level_repr) -end - -module Public_key_hash = struct - open Signature - include Signature.Public_key_hash - module Path_Ed25519 = Path_encoding.Make_hex (Ed25519.Public_key_hash) - module Path_Secp256k1 = Path_encoding.Make_hex (Secp256k1.Public_key_hash) - module Path_P256 = Path_encoding.Make_hex (P256.Public_key_hash) - - let to_path (key : public_key_hash) l = - match key with - | Ed25519 h -> ( - match Path_Ed25519.to_path h l with - | [s] -> ["ed25519"; s] - | _ -> assert false) - | Secp256k1 h -> ( - match Path_Secp256k1.to_path h l with - | [s] -> ["secp256k1"; s] - | _ -> assert false) - | P256 h -> ( - match Path_P256.to_path h l with - | [s] -> ["p256"; s] - | _ -> assert false) - - let of_path : _ -> public_key_hash option = function - | "ed25519" :: rest -> ( - match Path_Ed25519.of_path rest with - | Some pkh -> Some (Ed25519 pkh) - | None -> None) - | "secp256k1" :: rest -> ( - match Path_Secp256k1.of_path rest with - | Some pkh -> Some (Secp256k1 pkh) - | None -> None) - | "p256" :: rest -> ( - match Path_P256.of_path rest with - | Some pkh -> Some (P256 pkh) - | None -> None) - | _ -> None - - let path_length = - let l1 = Path_Ed25519.path_length - and l2 = Path_Secp256k1.path_length - and l3 = Path_P256.path_length in - assert (match (l1, l2, l3) with (1, 1, 1) -> true | _ -> false) ; - 2 -end - -module Public_key_hash_index = Make_index (Public_key_hash) - -module Protocol_hash = struct - include Protocol_hash - include Path_encoding.Make_hex (Protocol_hash) -end - -module Delegates = - Make_data_set_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["delegates"] - end)) - (Public_key_hash_index) - -module Legacy_active_delegates_with_rolls = - Make_data_set_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["active_delegates_with_rolls"] - end)) - (Public_key_hash_index) - -module Legacy_delegates_with_frozen_balance_index = - Make_indexed_subcontext - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["delegates_with_frozen_balance"] - end)) - (Make_index (Cycle_repr.Index)) - -module Legacy_delegates_with_frozen_balance = - Make_data_set_storage - (Legacy_delegates_with_frozen_balance_index.Raw_context) - (Public_key_hash_index) - -(** Per cycle storage *) - -type slashed_level = {for_double_endorsing : bool; for_double_baking : bool} - -module Slashed_level = struct - type t = slashed_level - - let encoding = - let open Data_encoding in - conv - (fun {for_double_endorsing; for_double_baking} -> - (for_double_endorsing, for_double_baking)) - (fun (for_double_endorsing, for_double_baking) -> - {for_double_endorsing; for_double_baking}) - (obj2 (req "for_double_endorsing" bool) (req "for_double_baking" bool)) -end - -module Cycle = struct - module Indexed_context = - Make_indexed_subcontext - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["cycle"] - end)) - (Make_index (Cycle_repr.Index)) - - module Slashed_deposits = - Make_indexed_data_storage - (Make_subcontext (Registered) (Indexed_context.Raw_context) - (struct - let name = ["slashed_deposits"] - end)) - (Pair (Make_index (Raw_level_repr.Index)) (Public_key_hash_index)) - (Slashed_level) - - module Last_roll_legacy = - Make_indexed_data_storage - (Make_subcontext (Ghost) (Indexed_context.Raw_context) - (struct - let name = ["last_roll"] - end)) - (Int31_index) - (Roll_repr_legacy) - - module Roll_snapshot_legacy = - Indexed_context.Make_map - (struct - let name = ["roll_snapshot"] - end) - (Encoding.UInt16) - - module Selected_stake_distribution = - Indexed_context.Make_map - (struct - let name = ["selected_stake_distribution"] - end) - (struct - type t = (Signature.Public_key_hash.t * Tez_repr.t) list - - let encoding = - Data_encoding.( - Variable.list - (obj2 - (req "baker" Signature.Public_key_hash.encoding) - (req "active_stake" Tez_repr.encoding))) - end) - - module Total_active_stake = - Indexed_context.Make_map - (struct - let name = ["total_active_stake"] - end) - (Tez_repr) - - let public_key_with_ghost_hash_encoding = - Data_encoding.conv - fst - (fun x -> (x, Signature.Public_key.hash x)) - Signature.Public_key.encoding - - module Delegate_sampler_state = - Indexed_context.Make_map - (struct - let name = ["delegate_sampler_state"] - end) - (struct - type t = - (Signature.Public_key.t * Signature.Public_key_hash.t) Sampler.t - - let encoding = Sampler.encoding public_key_with_ghost_hash_encoding - end) - - type unrevealed_nonce = { - nonce_hash : Nonce_hash.t; - delegate : Signature.Public_key_hash.t; - } - - type nonce_status = - | Unrevealed of unrevealed_nonce - | Revealed of Seed_repr.nonce - - let nonce_status_encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Unrevealed" - (tup2 Nonce_hash.encoding Signature.Public_key_hash.encoding) - (function - | Unrevealed {nonce_hash; delegate} -> Some (nonce_hash, delegate) - | _ -> None) - (fun (nonce_hash, delegate) -> Unrevealed {nonce_hash; delegate}); - case - (Tag 1) - ~title:"Revealed" - Seed_repr.nonce_encoding - (function Revealed nonce -> Some nonce | _ -> None) - (fun nonce -> Revealed nonce); - ] - - module Nonce = - Make_indexed_data_storage - (Make_subcontext (Registered) (Indexed_context.Raw_context) - (struct - let name = ["nonces"] - end)) - (Make_index (Raw_level_repr.Index)) - (struct - type t = nonce_status - - let encoding = nonce_status_encoding - end) - - let nonce_status_encoding_legacy = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Unrevealed" - (tup4 - Nonce_hash.encoding - Signature.Public_key_hash.encoding - Tez_repr.encoding - Tez_repr.encoding) - (function - | Unrevealed _ -> - assert false (* only used in read only for migration *) - | _ -> None) - (fun (nonce_hash, delegate, _, _) -> - Unrevealed {nonce_hash; delegate}); - case - (Tag 1) - ~title:"Revealed" - Seed_repr.nonce_encoding - (function - | Revealed _ -> - assert false (* only used in read only for migration *) - | _ -> None) - (fun nonce -> Revealed nonce); - ] - - module Nonce_legacy = - Make_indexed_data_storage - (Make_subcontext (Ghost) (Indexed_context.Raw_context) - (struct - let name = ["nonces"] - end)) - (Make_index (Raw_level_repr.Index)) - (struct - type t = nonce_status - - let encoding = nonce_status_encoding_legacy - end) - - module Seed = - Indexed_context.Make_map - (struct - let name = ["random_seed"] - end) - (struct - type t = Seed_repr.seed - - let encoding = Seed_repr.seed_encoding - end) -end - -module Slashed_deposits = Cycle.Slashed_deposits - -module Stake = struct - module Staking_balance = - Make_indexed_data_snapshotable_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["staking_balance"] - end)) - (Int31_index) - (Public_key_hash_index) - (Tez_repr) - - module Active_delegate_with_one_roll = - Make_indexed_data_snapshotable_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["active_delegate_with_one_roll"] - end)) - (Int31_index) - (Public_key_hash_index) - (struct - type t = unit - - let encoding = Data_encoding.unit - end) - - module Selected_distribution_for_cycle = Cycle.Selected_stake_distribution - - module Last_snapshot = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["last_snapshot"] - end) - (Encoding.UInt16) -end - -module Total_active_stake = Cycle.Total_active_stake -module Delegate_sampler_state = Cycle.Delegate_sampler_state - -module Roll_legacy = struct - module Raw_context = - Make_subcontext (Ghost) (Raw_context) - (struct - let name = ["rolls"] - end) - - module Indexed_context = - Make_indexed_subcontext - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["index"] - end)) - (Make_index (Roll_repr_legacy.Index)) - - module Next = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["next"] - end) - (Roll_repr_legacy) - - module Limbo = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["limbo"] - end) - (Roll_repr_legacy) - - module Delegate_roll_list = - Wrap_indexed_data_storage - (Contract.Roll_list_legacy) - (struct - type t = Signature.Public_key_hash.t - - let wrap = Contract_repr.implicit_contract - - let unwrap = Contract_repr.is_implicit - end) - - module Successor = - Indexed_context.Make_map - (struct - let name = ["successor"] - end) - (Roll_repr_legacy) - - module Delegate_change = - Wrap_indexed_data_storage - (Contract.Change_legacy) - (struct - type t = Signature.Public_key_hash.t - - let wrap = Contract_repr.implicit_contract - - let unwrap = Contract_repr.is_implicit - end) - - module Snapshoted_owner_index : INDEX with type t = Cycle_repr.t * int = - struct - type t = Cycle_repr.t * int - - let path_length = Cycle_repr.Index.path_length + 1 - - let to_path (c, n) s = Cycle_repr.Index.to_path c (string_of_int n :: s) - - let of_path l = - match Misc.take Cycle_repr.Index.path_length l with - | None | Some (_, ([] | _ :: _ :: _)) -> None - | Some (l1, [l2]) -> ( - match (Cycle_repr.Index.of_path l1, int_of_string_opt l2) with - | (None, _) | (_, None) -> None - | (Some c, Some i) -> Some (c, i)) - - type 'a ipath = ('a * Cycle_repr.t) * int - - let left_args = - Storage_description.One - { - rpc_arg = Cycle_repr.rpc_arg; - encoding = Cycle_repr.encoding; - compare = Cycle_repr.compare; - } - - let right_args = - Storage_description.One - { - rpc_arg = RPC_arg.int; - encoding = Data_encoding.int31; - compare = Compare.Int.compare; - } - - let args = Storage_description.(Pair (left_args, right_args)) - end - - module Owner = - Make_indexed_data_snapshotable_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["owner"] - end)) - (Snapshoted_owner_index) - (Make_index (Roll_repr_legacy.Index)) - (Signature.Public_key) - - module Snapshot_for_cycle = Cycle.Roll_snapshot_legacy - module Last_for_snapshot = Cycle.Last_roll_legacy - - let clear = Indexed_context.clear -end - -(** Votes *) - -module Vote = struct - module Raw_context = - Make_subcontext (Registered) (Raw_context) - (struct - let name = ["votes"] - end) - - module Pred_period_kind = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["pred_period_kind"] - end) - (struct - type t = Voting_period_repr.kind - - let encoding = Voting_period_repr.kind_encoding - end) - - module Current_period = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["current_period"] - end) - (struct - type t = Voting_period_repr.t - - let encoding = Voting_period_repr.encoding - end) - - module Participation_ema = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["participation_ema"] - end) - (Encoding.Int32) - - module Current_proposal = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["current_proposal"] - end) - (Protocol_hash) - - module Listings_size = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["listings_size"] - end) - (Encoding.Int32) - - module Listings = - Make_indexed_data_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["listings"] - end)) - (Public_key_hash_index) - (Encoding.Int32) - - module Proposals = - Make_data_set_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["proposals"] - end)) - (Pair (Make_index (Protocol_hash)) (Public_key_hash_index)) - - module Proposals_count = - Make_indexed_data_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["proposals_count"] - end)) - (Public_key_hash_index) - (Encoding.UInt16) - - module Ballots = - Make_indexed_data_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["ballots"] - end)) - (Public_key_hash_index) - (struct - type t = Vote_repr.ballot - - let encoding = Vote_repr.ballot_encoding - end) -end - -module type FOR_CYCLE = sig - val init : - Raw_context.t -> - Cycle_repr.t -> - Seed_repr.seed -> - Raw_context.t tzresult Lwt.t - - val mem : Raw_context.t -> Cycle_repr.t -> bool Lwt.t - - val get : Raw_context.t -> Cycle_repr.t -> Seed_repr.seed tzresult Lwt.t - - val remove_existing : - Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t -end - -(** Seed *) - -module Seed = struct - type unrevealed_nonce = Cycle.unrevealed_nonce = { - nonce_hash : Nonce_hash.t; - delegate : Signature.Public_key_hash.t; - } - - type nonce_status = Cycle.nonce_status = - | Unrevealed of unrevealed_nonce - | Revealed of Seed_repr.nonce - - module Nonce : - Non_iterable_indexed_data_storage - with type key := Level_repr.t - and type value := nonce_status - and type t := Raw_context.t = struct - open Level_repr - - type context = Raw_context.t - - let mem ctxt (l : Level_repr.t) = Cycle.Nonce.mem (ctxt, l.cycle) l.level - - let get ctxt (l : Level_repr.t) = Cycle.Nonce.get (ctxt, l.cycle) l.level - - let find ctxt (l : Level_repr.t) = Cycle.Nonce.find (ctxt, l.cycle) l.level - - let update ctxt (l : Level_repr.t) v = - Cycle.Nonce.update (ctxt, l.cycle) l.level v - - let init ctxt (l : Level_repr.t) v = - Cycle.Nonce.init (ctxt, l.cycle) l.level v - - let add ctxt (l : Level_repr.t) v = - Cycle.Nonce.add (ctxt, l.cycle) l.level v - - let add_or_remove ctxt (l : Level_repr.t) v = - Cycle.Nonce.add_or_remove (ctxt, l.cycle) l.level v - - let remove_existing ctxt (l : Level_repr.t) = - Cycle.Nonce.remove_existing (ctxt, l.cycle) l.level - - let remove ctxt (l : Level_repr.t) = - Cycle.Nonce.remove (ctxt, l.cycle) l.level - end - - module Nonce_legacy = struct - open Level_repr - - type context = Raw_context.t - - let mem ctxt (l : Level_repr.t) = - Cycle.Nonce_legacy.mem (ctxt, l.cycle) l.level - - let get ctxt (l : Level_repr.t) = - Cycle.Nonce_legacy.get (ctxt, l.cycle) l.level - - let find ctxt (l : Level_repr.t) = - Cycle.Nonce_legacy.find (ctxt, l.cycle) l.level - - let update ctxt (l : Level_repr.t) v = - Cycle.Nonce_legacy.update (ctxt, l.cycle) l.level v - - let init ctxt (l : Level_repr.t) v = - Cycle.Nonce_legacy.init (ctxt, l.cycle) l.level v - - let add ctxt (l : Level_repr.t) v = - Cycle.Nonce_legacy.add (ctxt, l.cycle) l.level v - - let add_or_remove ctxt (l : Level_repr.t) v = - Cycle.Nonce_legacy.add_or_remove (ctxt, l.cycle) l.level v - - let remove_existing ctxt (l : Level_repr.t) = - Cycle.Nonce_legacy.remove_existing (ctxt, l.cycle) l.level - - let remove ctxt (l : Level_repr.t) = - Cycle.Nonce_legacy.remove (ctxt, l.cycle) l.level - end - - module For_cycle : FOR_CYCLE = Cycle.Seed -end - -(** Commitments *) - -module Commitments = - Make_indexed_data_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["commitments"] - end)) - (Make_index (Blinded_public_key_hash.Index)) - (Tez_repr) - -(** Ramp up rewards... *) - -module Ramp_up = struct - type reward = { - baking_reward_fixed_portion : Tez_repr.t; - baking_reward_bonus_per_slot : Tez_repr.t; - endorsing_reward_per_slot : Tez_repr.t; - } - - module Rewards = - Make_indexed_data_storage - (Make_subcontext (Registered) (Raw_context) - (struct - let name = ["ramp_up"; "rewards"] - end)) - (Make_index (Cycle_repr.Index)) - (struct - type t = reward - - let encoding = - Data_encoding.( - conv - (fun { - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - } -> - ( baking_reward_fixed_portion, - baking_reward_bonus_per_slot, - endorsing_reward_per_slot )) - (fun ( baking_reward_fixed_portion, - baking_reward_bonus_per_slot, - endorsing_reward_per_slot ) -> - { - baking_reward_fixed_portion; - baking_reward_bonus_per_slot; - endorsing_reward_per_slot; - }) - (obj3 - (req "baking_reward_fixed_portion" Tez_repr.encoding) - (req "baking_reward_bonus_per_slot" Tez_repr.encoding) - (req "endorsing_reward_per_slot" Tez_repr.encoding))) - end) -end - -module Pending_migration = struct - module Balance_updates = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["pending_migration_balance_updates"] - end) - (struct - type t = Receipt_repr.balance_updates - - let encoding = Receipt_repr.balance_updates_encoding - end) - - module Operation_results = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["pending_migration_operation_results"] - end) - (struct - type t = Migration_repr.origination_result list - - let encoding = Migration_repr.origination_result_list_encoding - end) - - let remove ctxt = - let balance_updates ctxt = - Balance_updates.find ctxt >>=? function - | Some balance_updates -> - Balance_updates.remove ctxt >>= fun ctxt -> - (* When applying balance updates in a migration, we must attach receipts. - The balance updates returned from here will be applied in the first - block of the new protocol. *) - return (ctxt, balance_updates) - | None -> return (ctxt, []) - in - let operation_results ctxt = - Operation_results.find ctxt >>=? function - | Some operation_results -> - Operation_results.remove ctxt >>= fun ctxt -> - return (ctxt, operation_results) - | None -> return (ctxt, []) - in - balance_updates ctxt >>=? fun (ctxt, balance_updates) -> - operation_results ctxt >>=? fun (ctxt, operation_results) -> - return (ctxt, balance_updates, operation_results) -end - -module Liquidity_baking = struct - module Escape_ema = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["liquidity_baking_escape_ema"] - end) - (Encoding.Int32) - - module Cpmm_address = - Make_single_data_storage (Registered) (Raw_context) - (struct - let name = ["liquidity_baking_cpmm_address"] - end) - (Contract_repr) -end - -module Ticket_balance = struct - module Name = struct - let name = ["ticket_balance"] - end - - module Sub_context = Make_subcontext (Registered) (Raw_context) (Name) - module Index = Make_index (Script_expr_hash) - module Table = - Make_indexed_carbonated_data_storage (Sub_context) (Index) (Encoding.Z) -end diff --git a/src/proto_012_Psithaca/lib_protocol/storage.mli b/src/proto_012_Psithaca/lib_protocol/storage.mli deleted file mode 100644 index 2aa47e9dc6ae..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/storage.mli +++ /dev/null @@ -1,693 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Tezos Protocol Implementation - Typed storage - - This module hides the hierarchical (key x value) database under - pre-allocated typed accessors for all persistent entities of the - tezos context. - - This interface enforces no invariant on the contents of the - database. Its goal is to centralize all accessors in order to have - a complete view over the database contents and avoid key - collisions. *) - -open Storage_sigs - -module type Simple_single_data_storage = sig - type value - - val get : Raw_context.t -> value tzresult Lwt.t - - val update : Raw_context.t -> value -> Raw_context.t tzresult Lwt.t - - val init : Raw_context.t -> value -> Raw_context.t tzresult Lwt.t -end - -module Legacy_block_priority : Simple_single_data_storage with type value = int - -module Block_round : Simple_single_data_storage with type value = Round_repr.t - -module Roll_legacy : sig - (** Storage from this submodule must only be accessed through the - module `Roll_legacy`. *) - - module Owner : - Indexed_data_snapshotable_storage - with type key = Roll_repr_legacy.t - and type snapshot = Cycle_repr.t * int - and type value = Signature.Public_key.t - and type t := Raw_context.t - - val clear : Raw_context.t -> Raw_context.t Lwt.t - - (** The next roll to be allocated. *) - module Next : - Single_data_storage - with type value = Roll_repr_legacy.t - and type t := Raw_context.t - - (** Rolls linked lists represent both account owned and free rolls. - All rolls belongs either to the limbo list or to an owned list. *) - - (** Head of the linked list of rolls in limbo *) - module Limbo : - Single_data_storage - with type value = Roll_repr_legacy.t - and type t := Raw_context.t - - (** Rolls associated to contracts, a linked list per contract *) - module Delegate_roll_list : - Indexed_data_storage - with type key = Signature.Public_key_hash.t - and type value = Roll_repr_legacy.t - and type t := Raw_context.t - - (** Use this to iter on a linked list of rolls *) - module Successor : - Indexed_data_storage - with type key = Roll_repr_legacy.t - and type value = Roll_repr_legacy.t - and type t := Raw_context.t - - (** The tez of a contract that are not assigned to rolls *) - module Delegate_change : - Indexed_data_storage - with type key = Signature.Public_key_hash.t - and type value = Tez_repr.t - and type t := Raw_context.t - - (** Index of the randomly selected roll snapshot of a given cycle. *) - module Snapshot_for_cycle : - Indexed_data_storage - with type key = Cycle_repr.t - and type value = int - and type t := Raw_context.t - - (** Last roll in the snapshoted roll allocation of a given cycle. *) - module Last_for_snapshot : - Indexed_data_storage - with type key = int - and type value = Roll_repr_legacy.t - and type t = Raw_context.t * Cycle_repr.t -end - -type deposits = {initial_amount : Tez_repr.t; current_amount : Tez_repr.t} - -type missed_endorsements_info = {remaining_slots : int; missed_levels : int} - -module Contract : sig - (** Storage from this submodule must only be accessed through the - module `Contract`. *) - - module Global_counter : Simple_single_data_storage with type value = Z.t - - (** The domain of alive contracts *) - val fold : - Raw_context.t -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(Contract_repr.t -> 'a -> 'a Lwt.t) -> - 'a Lwt.t - - val list : Raw_context.t -> Contract_repr.t list Lwt.t - - (** The tez possessed by a contract and that can be used. A contract - may also possess tez in frozen deposits. Empty balances (of zero - tez) are only allowed for originated contracts, not for implicit - ones. *) - module Balance : - Indexed_data_storage - with type key = Contract_repr.t - and type value = Tez_repr.t - and type t := Raw_context.t - - (** If the value is not set, the delegate didn't miss any endorsing - opportunity. If it is set, this value is a record of type - [missed_endorsements_info], where: - - [remaining_slots] is the difference between the maximum number of - slots that can be missed and the number of missed slots; - therefore, when the number is positive, it represents the number - of slots that a delegate can still miss before forfeiting its - endorsing rewards for the current cycle; when the number is zero - it means rewards are not lost, but no further slots can be - missed anymore; - - [missed_levels] represents the number of missed levels (for - endorsing). *) - module Missed_endorsements : - Indexed_data_storage - with type key = Contract_repr.t - and type value = missed_endorsements_info - and type t := Raw_context.t - - (** Frozen balance, see 'delegate_storage.mli' for more explanation. - Always update `Delegates_with_frozen_balance` accordingly. - - Deprecated only used for migration - *) - module Legacy_frozen_deposits : - Indexed_data_storage - with type key = Cycle_repr.t - and type value = Tez_repr.t - and type t = Raw_context.t * Contract_repr.t - - (** Deprecated only used for migration *) - module Legacy_frozen_fees : - Indexed_data_storage - with type key = Cycle_repr.t - and type value = Tez_repr.t - and type t = Raw_context.t * Contract_repr.t - - (** Deprecated only used for migration *) - module Legacy_frozen_rewards : - Indexed_data_storage - with type key = Cycle_repr.t - and type value = Tez_repr.t - and type t = Raw_context.t * Contract_repr.t - - (** The manager of a contract *) - module Manager : - Indexed_data_storage - with type key = Contract_repr.t - and type value = Manager_repr.t - and type t := Raw_context.t - - (** The delegate of a contract, if any. *) - module Delegate : - Indexed_data_storage - with type key = Contract_repr.t - and type value = Signature.Public_key_hash.t - and type t := Raw_context.t - - (** All contracts (implicit and originated) that are delegated, if any *) - module Delegated : - Data_set_storage - with type elt = Contract_repr.t - and type t = Raw_context.t * Contract_repr.t - - (** The part of a delegate balance that can't be used. The total - balance is frozen_deposits.current_amount + balance. It also stores - the initial frozen balance in frozen_deposits.initial_amount. We - have current_amount <= initial_amount and current_amount < - initial_amount iff the delegate was slashed. *) - module Frozen_deposits : - Indexed_data_storage - with type key = Contract_repr.t - and type value = deposits - and type t := Raw_context.t - - (** If there is a value, the frozen balance for the contract won't - exceed it (starting in preserved_cycles + 1). *) - module Frozen_deposits_limit : - Indexed_data_storage - with type key = Contract_repr.t - and type value = Tez_repr.t - and type t := Raw_context.t - - module Inactive_delegate : - Data_set_storage with type elt = Contract_repr.t and type t = Raw_context.t - - (** The last cycle where the delegate is considered active; that is, - at the next cycle it will be considered inactive. *) - module Delegate_desactivation : - Indexed_data_storage - with type key = Contract_repr.t - and type value = Cycle_repr.t - and type t := Raw_context.t - - module Counter : - Indexed_data_storage - with type key = Contract_repr.t - and type value = Z.t - and type t := Raw_context.t - - module Code : - Non_iterable_indexed_carbonated_data_storage - with type key = Contract_repr.t - and type value = Script_repr.lazy_expr - and type t := Raw_context.t - - module Storage : - Non_iterable_indexed_carbonated_data_storage - with type key = Contract_repr.t - and type value = Script_repr.lazy_expr - and type t := Raw_context.t - - (** Current storage space in bytes. - Includes code, global storage and big map elements. *) - module Used_storage_space : - Indexed_data_storage - with type key = Contract_repr.t - and type value = Z.t - and type t := Raw_context.t - - (** Maximal space available without needing to burn new fees. *) - module Paid_storage_space : - Indexed_data_storage - with type key = Contract_repr.t - and type value = Z.t - and type t := Raw_context.t -end - -module Big_map : sig - type id = Lazy_storage_kind.Big_map.Id.t - - module Next : sig - val incr : Raw_context.t -> (Raw_context.t * id) tzresult Lwt.t - - val init : Raw_context.t -> Raw_context.t tzresult Lwt.t - end - - (** The domain of alive big maps *) - val fold : - Raw_context.t -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(id -> 'a -> 'a Lwt.t) -> - 'a Lwt.t - - val list : Raw_context.t -> id list Lwt.t - - val remove : Raw_context.t -> id -> Raw_context.t Lwt.t - - val copy : Raw_context.t -> from:id -> to_:id -> Raw_context.t tzresult Lwt.t - - type key = Raw_context.t * id - - val rpc_arg : id RPC_arg.t - - module Contents : sig - include - Non_iterable_indexed_carbonated_data_storage - with type key = Script_expr_hash.t - and type value = Script_repr.expr - and type t := key - - (** HACK *) - val list_values : - ?offset:int -> - ?length:int -> - Raw_context.t * id -> - (Raw_context.t * Script_repr.expr list) tzresult Lwt.t - end - - module Total_bytes : - Indexed_data_storage - with type key = id - and type value = Z.t - and type t := Raw_context.t - - module Key_type : - Indexed_data_storage - with type key = id - and type value = Script_repr.expr - and type t := Raw_context.t - - module Value_type : - Indexed_data_storage - with type key = id - and type value = Script_repr.expr - and type t := Raw_context.t -end - -module Sapling : sig - type id = Lazy_storage_kind.Sapling_state.Id.t - - val rpc_arg : id RPC_arg.t - - module Next : sig - val incr : Raw_context.t -> (Raw_context.t * id) tzresult Lwt.t - - val init : Raw_context.t -> Raw_context.t tzresult Lwt.t - end - - val copy : Raw_context.t -> from:id -> to_:id -> Raw_context.t tzresult Lwt.t - - val remove : Raw_context.t -> id -> Raw_context.t Lwt.t - - module Total_bytes : - Indexed_data_storage - with type key = id - and type value = Z.t - and type t := Raw_context.t - - (* Used by both Commitments and Ciphertexts *) - module Commitments_size : - Single_data_storage with type t := Raw_context.t * id and type value = int64 - - module Memo_size : - Single_data_storage with type t := Raw_context.t * id and type value = int - - module Commitments : - Non_iterable_indexed_carbonated_data_storage - with type t := Raw_context.t * id - and type key = int64 - and type value = Sapling.Hash.t - - val commitments_init : Raw_context.t -> id -> Raw_context.t Lwt.t - - module Ciphertexts : - Non_iterable_indexed_carbonated_data_storage - with type t := Raw_context.t * id - and type key = int64 - and type value = Sapling.Ciphertext.t - - val ciphertexts_init : Raw_context.t -> id -> Raw_context.t Lwt.t - - module Nullifiers_size : - Single_data_storage with type t := Raw_context.t * id and type value = int64 - - module Nullifiers_ordered : - Non_iterable_indexed_data_storage - with type t := Raw_context.t * id - and type key = int64 - and type value = Sapling.Nullifier.t - - module Nullifiers_hashed : - Carbonated_data_set_storage - with type t := Raw_context.t * id - and type elt = Sapling.Nullifier.t - - val nullifiers_init : Raw_context.t -> id -> Raw_context.t Lwt.t - - module Roots : - Non_iterable_indexed_data_storage - with type t := Raw_context.t * id - and type key = int32 - and type value = Sapling.Hash.t - - module Roots_pos : - Single_data_storage with type t := Raw_context.t * id and type value = int32 - - module Roots_level : - Single_data_storage - with type t := Raw_context.t * id - and type value = Raw_level_repr.t -end - -(** Set of all registered delegates. *) -module Delegates : - Data_set_storage - with type t := Raw_context.t - and type elt = Signature.Public_key_hash.t - -type slashed_level = {for_double_endorsing : bool; for_double_baking : bool} - -(** Set used to avoid slashing multiple times the same event *) -module Slashed_deposits : - Indexed_data_storage - with type t := Raw_context.t * Cycle_repr.t - and type key = Raw_level_repr.t * Signature.Public_key_hash.t - and type value = slashed_level - -(** Set of all active delegates with rolls. *) -module Legacy_active_delegates_with_rolls : - Data_set_storage - with type t := Raw_context.t - and type elt = Signature.Public_key_hash.t - -module Stake : sig - (** The map of all the staking balances of all delegates, including - those with less than one roll. It might be large *) - module Staking_balance : - Indexed_data_snapshotable_storage - with type key = Signature.Public_key_hash.t - and type value = Tez_repr.t - and type snapshot = int - and type t := Raw_context.t - - (** This is a set, encoded in a map with value unit. This should be - fairly small compared to staking balance *) - module Active_delegate_with_one_roll : - Indexed_data_snapshotable_storage - with type key = Signature.Public_key_hash.t - and type value = unit - and type snapshot = int - and type t := Raw_context.t - - module Last_snapshot : - Single_data_storage with type value = int and type t := Raw_context.t - - (** List of active stake *) - module Selected_distribution_for_cycle : - Indexed_data_storage - with type key = Cycle_repr.t - and type value = (Signature.Public_key_hash.t * Tez_repr.t) list - and type t := Raw_context.t -end - -(** Sum of the active stakes of all the delegates with rolls *) -module Total_active_stake : - Indexed_data_storage - with type key = Cycle_repr.t - and type value = Tez_repr.t - and type t := Raw_context.t - -(** State of the sampler used to select delegates. Managed synchronously - with [Stake.Selected_distribution_for_cycle]. *) -module Delegate_sampler_state : - Indexed_data_storage - with type key = Cycle_repr.t - and type value = - (Signature.Public_key.t * Signature.Public_key_hash.t) Sampler.t - and type t := Raw_context.t - -(** Set of all the delegates with frozen rewards/deposits/fees for a given cycle. - Deprecated: This is now only used for stitching while migrating from an - emmy protocol. This is to be removed in the next version. - - This table must be cleaned after migration. *) -module Legacy_delegates_with_frozen_balance : - Data_set_storage - with type t = Raw_context.t * Cycle_repr.t - and type elt = Signature.Public_key_hash.t - -(** Votes *) - -module Vote : sig - module Pred_period_kind : - Single_data_storage - with type value = Voting_period_repr.kind - and type t := Raw_context.t - - module Current_period : - Single_data_storage - with type value = Voting_period_repr.t - and type t := Raw_context.t - - (** Participation exponential moving average, in centile of percentage *) - module Participation_ema : - Single_data_storage with type value = int32 and type t := Raw_context.t - - module Current_proposal : - Single_data_storage - with type value = Protocol_hash.t - and type t := Raw_context.t - - (** Sum of all rolls of all delegates. *) - module Listings_size : - Single_data_storage with type value = int32 and type t := Raw_context.t - - (** Contains all delegates with their assigned number of rolls. *) - module Listings : - Indexed_data_storage - with type key = Signature.Public_key_hash.t - and type value = int32 - and type t := Raw_context.t - - (** Set of protocol proposal with corresponding proposer delegate *) - module Proposals : - Data_set_storage - with type elt = Protocol_hash.t * Signature.Public_key_hash.t - and type t := Raw_context.t - - (** Keeps for each delegate the number of proposed protocols *) - module Proposals_count : - Indexed_data_storage - with type key = Signature.Public_key_hash.t - and type value = int - and type t := Raw_context.t - - (** Contains for each delegate its ballot *) - module Ballots : - Indexed_data_storage - with type key = Signature.Public_key_hash.t - and type value = Vote_repr.ballot - and type t := Raw_context.t -end - -module type FOR_CYCLE = sig - val init : - Raw_context.t -> - Cycle_repr.t -> - Seed_repr.seed -> - Raw_context.t tzresult Lwt.t - - val mem : Raw_context.t -> Cycle_repr.t -> bool Lwt.t - - val get : Raw_context.t -> Cycle_repr.t -> Seed_repr.seed tzresult Lwt.t - - val remove_existing : - Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t -end - -(** Seed *) - -module Seed : sig - (** Storage from this submodule must only be accessed through the - module `Seed`. *) - - type unrevealed_nonce = { - nonce_hash : Nonce_hash.t; - delegate : Signature.Public_key_hash.t; - } - - type nonce_status = - | Unrevealed of unrevealed_nonce - | Revealed of Seed_repr.nonce - - module Nonce : - Non_iterable_indexed_data_storage - with type key := Level_repr.t - and type value := nonce_status - and type t := Raw_context.t - - module Nonce_legacy : - Non_iterable_indexed_data_storage - with type key := Level_repr.t - and type value := nonce_status - and type t := Raw_context.t - - module For_cycle : FOR_CYCLE -end - -(** Commitments *) - -module Commitments : - Indexed_data_storage - with type key = Blinded_public_key_hash.t - and type value = Tez_repr.t - and type t := Raw_context.t - -(** Ramp up rewards *) -module Ramp_up : sig - type reward = { - baking_reward_fixed_portion : Tez_repr.t; - baking_reward_bonus_per_slot : Tez_repr.t; - endorsing_reward_per_slot : Tez_repr.t; - } - - module Rewards : - Indexed_data_storage - with type key = Cycle_repr.t - and type value := reward - and type t := Raw_context.t -end - -module Pending_migration : sig - module Balance_updates : - Single_data_storage - with type value = Receipt_repr.balance_updates - and type t := Raw_context.t - - module Operation_results : - Single_data_storage - with type value = Migration_repr.origination_result list - and type t := Raw_context.t - - val remove : - Raw_context.t -> - (Raw_context.t - * Receipt_repr.balance_updates - * Migration_repr.origination_result list) - tzresult - Lwt.t -end - -module Liquidity_baking : sig - (** Exponential moving average (ema) of flags set in protocol_data.contents. - If at any block it's above the threshold set in constants, - liquidity baking permanently shuts off. **) - module Escape_ema : - Single_data_storage with type t := Raw_context.t and type value = Int32.t - - (** Constant product market maker contract that receives liquidity baking subsidy. **) - module Cpmm_address : - Single_data_storage - with type t := Raw_context.t - and type value = Contract_repr.t -end - -(** A map of [Script_repr.expr] values, indexed by their hash ([Script_expr_hash.t]). - Values from this map can be incorporated by any contract via the primitive - [Michelson_v1_primitives.H_constant]. *) -module Global_constants : sig - module Map : - Non_iterable_indexed_carbonated_data_storage - with type t := Raw_context.t - and type key = Script_expr_hash.t - and type value = Script_repr.expr -end - -(** This module exposes a balance table for tracking ticket ownership. - The table is a mapping from keys to values where the keys consist of a - hashed representation of: - - A ticketer, i.e. the creator of the ticket - - The content of a the ticket - - The contract that owns some amount of the ticket - The values of the table are the amounts owned by each key. - *) -module Ticket_balance : sig - module Table : - Non_iterable_indexed_carbonated_data_storage - with type t := Raw_context.t - and type key = Script_expr_hash.t - and type value = Z.t -end - -(** Tenderbake *) - -module Tenderbake : sig - module First_level : - Single_data_storage - with type t := Raw_context.t - and type value = Raw_level_repr.t - - (** [Endorsement_branch] stores a single value composed of the - grandparent hash and the predecessor's payload (computed with - the grandparent hash) used to verify the validity of - endorsements. *) - module Endorsement_branch : - Single_data_storage - with type value = Block_hash.t * Block_payload_hash.t - and type t := Raw_context.t - - (** [Grand_parent_branch] stores a single value composed of the - great-grand parent hash and the grand parent's payload *) - module Grand_parent_branch : - Single_data_storage - with type value = Block_hash.t * Block_payload_hash.t - and type t := Raw_context.t -end diff --git a/src/proto_012_Psithaca/lib_protocol/storage_costs.ml b/src/proto_012_Psithaca/lib_protocol/storage_costs.ml deleted file mode 100644 index dae9e12456fe..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/storage_costs.ml +++ /dev/null @@ -1,43 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* The model for read accesses is the following: - - cost(path_length, read_bytes) = 200_000 + 5000 * path_length + 2 * read_bytes -*) -let read_access ~path_length ~read_bytes = - let open Saturation_repr in - let base_cost = safe_int (200_000 + (5000 * path_length)) in - Gas_limit_repr.atomic_step_cost - (add base_cost (mul (safe_int 2) (safe_int read_bytes))) - -(* The model for write accesses is the following: - - cost(written_bytes) = 200_000 + 4 * written_bytes -*) -let write_access ~written_bytes = - let open Saturation_repr in - Gas_limit_repr.atomic_step_cost - (add (safe_int 200_000) (mul (safe_int 4) (safe_int written_bytes))) diff --git a/src/proto_012_Psithaca/lib_protocol/storage_costs.mli b/src/proto_012_Psithaca/lib_protocol/storage_costs.mli deleted file mode 100644 index 0b91ce04eaae..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/storage_costs.mli +++ /dev/null @@ -1,30 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Cost of reading [read_bytes] at a key of length [path_length]. *) -val read_access : path_length:int -> read_bytes:int -> Gas_limit_repr.cost - -(** Cost of performing a single write access, writing [written_bytes] bytes. *) -val write_access : written_bytes:int -> Gas_limit_repr.cost diff --git a/src/proto_012_Psithaca/lib_protocol/storage_description.ml b/src/proto_012_Psithaca/lib_protocol/storage_description.ml deleted file mode 100644 index 7bac72c5a969..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/storage_description.ml +++ /dev/null @@ -1,388 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module StringMap = Map.Make (String) - -type 'key t = 'key desc_with_path - -(** [desc_with_path] describes a position in the storage. It's composed - [rev_path] which is the reverse path up to the position, and [dir] the - position's [description]. [rev_path] is only useful in case of an error to - print a descriptive message. [List.rev rev_path] is a storage's path that - contains no conflict and allows the registration of a [dir]'s storage. - NB: [rev_path] indicates the position in the tree, so once the node is - added, it won't change; whereas [dir] is mutable because when more subtrees - are added this may require updating it. *) -and 'key desc_with_path = { - rev_path : string list; - mutable dir : 'key description; -} - -and 'key description = - | Empty : 'key description - | Value : { - get : 'key -> 'a option tzresult Lwt.t; - encoding : 'a Data_encoding.t; - } - -> 'key description - | NamedDir : 'key t StringMap.t -> 'key description - | IndexedDir : { - arg : 'a RPC_arg.t; - arg_encoding : 'a Data_encoding.t; - list : 'key -> 'a list tzresult Lwt.t; - subdir : ('key * 'a) t; - } - -> 'key description - -let[@coq_struct "function_parameter"] rec pp : - type a. Format.formatter -> a t -> unit = - fun ppf {dir; _} -> - match dir with - | Empty -> Format.fprintf ppf "Empty" - | Value _e -> Format.fprintf ppf "Value" - | NamedDir map -> - Format.fprintf - ppf - "@[%a@]" - (Format.pp_print_list pp_item) - (StringMap.bindings map) - | IndexedDir {arg; subdir; _} -> - let name = Format.asprintf "<%s>" (RPC_arg.descr arg).name in - pp_item ppf (name, subdir) - -and[@coq_mutual_as_notation] pp_item : - type a. Format.formatter -> string * a t -> unit = - fun ppf (name, desc) -> Format.fprintf ppf "@[%s@ %a@]" name pp desc - -let pp_rev_path ppf path = - Format.fprintf - ppf - "[%a]" - Format.( - pp_print_list - ~pp_sep:(fun ppf () -> pp_print_string ppf " / ") - pp_print_string) - (List.rev path) - -let rec register_named_subcontext : type r. r t -> string list -> r t = - fun desc names -> - match (desc.dir, names) with - | (_, []) -> desc - | (Value _, _) | (IndexedDir _, _) -> - Format.kasprintf - invalid_arg - "Could not register a named subcontext at %a because of an existing %a." - pp_rev_path - desc.rev_path - pp - desc - | (Empty, name :: names) -> - let subdir = {rev_path = name :: desc.rev_path; dir = Empty} in - desc.dir <- NamedDir (StringMap.singleton name subdir) ; - register_named_subcontext subdir names - | (NamedDir map, name :: names) -> - let subdir = - match StringMap.find name map with - | Some subdir -> subdir - | None -> - let subdir = {rev_path = name :: desc.rev_path; dir = Empty} in - desc.dir <- NamedDir (StringMap.add name subdir map) ; - subdir - in - register_named_subcontext subdir names - -type (_, _, _) args = - | One : { - rpc_arg : 'a RPC_arg.t; - encoding : 'a Data_encoding.t; - compare : 'a -> 'a -> int; - } - -> ('key, 'a, 'key * 'a) args - | Pair : - ('key, 'a, 'inter_key) args * ('inter_key, 'b, 'sub_key) args - -> ('key, 'a * 'b, 'sub_key) args - -let rec unpack : type a b c. (a, b, c) args -> c -> a * b = function - | One _ -> fun x -> x - | Pair (l, r) -> - let unpack_l = unpack l in - let unpack_r = unpack r in - fun x -> - let (c, d) = unpack_r x in - let (b, a) = unpack_l c in - (b, (a, d)) - [@@coq_axiom_with_reason "gadt"] - -let rec pack : type a b c. (a, b, c) args -> a -> b -> c = function - | One _ -> fun b a -> (b, a) - | Pair (l, r) -> - let pack_l = pack l in - let pack_r = pack r in - fun b (a, d) -> - let c = pack_l b a in - pack_r c d - [@@coq_axiom_with_reason "gadt"] - -let rec compare : type a b c. (a, b, c) args -> b -> b -> int = function - | One {compare; _} -> compare - | Pair (l, r) -> ( - let compare_l = compare l in - let compare_r = compare r in - fun (a1, b1) (a2, b2) -> - match compare_l a1 a2 with 0 -> compare_r b1 b2 | x -> x) - [@@coq_axiom_with_reason "gadt"] - -let destutter equal l = - match l with - | [] -> [] - | (i, _) :: l -> - let rec loop acc i = function - | [] -> acc - | (j, _) :: l -> if equal i j then loop acc i l else loop (j :: acc) j l - in - loop [i] i l - -let rec register_indexed_subcontext : - type r a b. - r t -> list:(r -> a list tzresult Lwt.t) -> (r, a, b) args -> b t = - fun desc ~list path -> - match path with - | Pair (left, right) -> - let compare_left = compare left in - let equal_left x y = Compare.Int.(compare_left x y = 0) in - let list_left r = list r >|=? fun l -> destutter equal_left l in - let list_right r = - let (a, k) = unpack left r in - list a >|=? fun l -> - List.map snd (List.filter (fun (x, _) -> equal_left x k) l) - in - register_indexed_subcontext - (register_indexed_subcontext desc ~list:list_left left) - ~list:list_right - right - | One {rpc_arg = arg; encoding = arg_encoding; _} -> ( - match desc.dir with - | Value _ | NamedDir _ -> - Format.kasprintf - invalid_arg - "Could not register an indexed subcontext at %a because of an \ - existing %a." - pp_rev_path - desc.rev_path - pp - desc - | Empty -> - let subdir = - { - rev_path = - Format.sprintf "(Maybe of %s)" RPC_arg.(descr arg).name - :: desc.rev_path; - dir = Empty; - } - in - desc.dir <- IndexedDir {arg; arg_encoding; list; subdir} ; - subdir - | IndexedDir {arg = inner_arg; subdir; _} -> ( - match RPC_arg.eq arg inner_arg with - | None -> - Format.kasprintf - invalid_arg - "An indexed subcontext at %a already exists but has a \ - different argument: `%s` <> `%s`." - pp_rev_path - desc.rev_path - (RPC_arg.descr arg).name - (RPC_arg.descr inner_arg).name - | Some RPC_arg.Eq -> subdir)) - [@@coq_axiom_with_reason "gadt"] - -let register_value : - type a b. - a t -> get:(a -> b option tzresult Lwt.t) -> b Data_encoding.t -> unit = - fun desc ~get encoding -> - match desc.dir with - | Empty -> desc.dir <- Value {get; encoding} - | _ -> - Format.kasprintf - invalid_arg - "Could not register a value at %a because of an existing %a." - pp_rev_path - desc.rev_path - pp - desc - -let create () = {rev_path = []; dir = Empty} - -module type INDEX = sig - type t - - include Path_encoding.S with type t := t - - val rpc_arg : t RPC_arg.t - - val encoding : t Data_encoding.t - - val compare : t -> t -> int -end - -type _ handler = - | Handler : { - encoding : 'a Data_encoding.t; - get : 'key -> int -> 'a tzresult Lwt.t; - } - -> 'key handler - -type _ opt_handler = - | Opt_handler : { - encoding : 'a Data_encoding.t; - get : 'key -> int -> 'a option tzresult Lwt.t; - } - -> 'key opt_handler - -let rec combine_object = function - | [] -> - Handler {encoding = Data_encoding.unit; get = (fun _ _ -> return_unit)} - | (name, Opt_handler handler) :: fields -> - let (Handler handlers) = combine_object fields in - Handler - { - encoding = - Data_encoding.merge_objs - Data_encoding.(obj1 (opt name (dynamic_size handler.encoding))) - handlers.encoding; - get = - (fun k i -> - handler.get k i >>=? fun v1 -> - handlers.get k i >|=? fun v2 -> (v1, v2)); - } - [@@coq_axiom_with_reason "gadt"] - -type query = {depth : int} - -let depth_query = - let open RPC_query in - query (fun depth -> {depth}) - |+ field "depth" RPC_arg.uint 0 (fun t -> t.depth) - |> seal - -let build_directory : type key. key t -> key RPC_directory.t = - fun dir -> - let rpc_dir = ref (RPC_directory.empty : key RPC_directory.t) in - let register : - type ikey. - chunked:bool -> (key, ikey) RPC_path.t -> ikey opt_handler -> unit = - fun ~chunked path (Opt_handler {encoding; get}) -> - let service = - RPC_service.get_service ~query:depth_query ~output:encoding path - in - rpc_dir := - RPC_directory.opt_register ~chunked !rpc_dir service (fun k q () -> - get k (q.depth + 1)) - in - let rec build_handler : - type ikey. ikey t -> (key, ikey) RPC_path.t -> ikey opt_handler = - fun desc path -> - match desc.dir with - | Empty -> - Opt_handler - {encoding = Data_encoding.unit; get = (fun _ _ -> return_none)} - | Value {get; encoding} -> - let handler = - Opt_handler - { - encoding; - get = - (fun k i -> if Compare.Int.(i < 0) then return_none else get k); - } - in - register ~chunked:true path handler ; - handler - | NamedDir map -> - let fields = StringMap.bindings map in - let fields = - List.map - (fun (name, dir) -> - (name, build_handler dir RPC_path.(path / name))) - fields - in - let (Handler handler) = combine_object fields in - let handler = - Opt_handler - { - encoding = handler.encoding; - get = - (fun k i -> - if Compare.Int.(i < 0) then return_none - else handler.get k (i - 1) >>=? fun v -> return_some v); - } - in - register ~chunked:true path handler ; - handler - | IndexedDir {arg; arg_encoding; list; subdir} -> - let (Opt_handler handler) = - build_handler subdir RPC_path.(path /: arg) - in - let encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Leaf" - (dynamic_size arg_encoding) - (function (key, None) -> Some key | _ -> None) - (fun key -> (key, None)); - case - (Tag 1) - ~title:"Dir" - (tup2 - (dynamic_size arg_encoding) - (dynamic_size handler.encoding)) - (function (key, Some value) -> Some (key, value) | _ -> None) - (fun (key, value) -> (key, Some value)); - ] - in - let get k i = - if Compare.Int.(i < 0) then return_none - else if Compare.Int.(i = 0) then return_some [] - else - list k >>=? fun keys -> - List.map_es - (fun key -> - if Compare.Int.(i = 1) then return (key, None) - else handler.get (k, key) (i - 1) >|=? fun value -> (key, value)) - keys - >>=? fun values -> return_some values - in - let handler = - Opt_handler - {encoding = Data_encoding.(list (dynamic_size encoding)); get} - in - register ~chunked:true path handler ; - handler - in - ignore (build_handler dir RPC_path.open_root : key opt_handler) ; - !rpc_dir - [@@coq_axiom_with_reason "gadt"] diff --git a/src/proto_012_Psithaca/lib_protocol/storage_description.mli b/src/proto_012_Psithaca/lib_protocol/storage_description.mli deleted file mode 100644 index 33e44cc39f13..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/storage_description.mli +++ /dev/null @@ -1,93 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module is responsible for building the description of the current state - of the storage, which is then used to build specification of the RPC - endpoints for accessing the storage. It produces [resto] [RPC_directory.t] - values, which can be used directly to construct the RPC endpoint tree. *) - -(** Typed description of the key-value context. *) -type 'key t - -(** Trivial display of the key-value context layout. *) -val pp : Format.formatter -> 'key t -> unit - -(** Export an RPC hierarchy for querying the context. There is one service - by possible path in the context. Services for "directory" are able to - aggregate in one JSON object the whole subtree. *) -val build_directory : 'key t -> 'key RPC_directory.t - -(** Create a empty context description, - keys will be registered by side effects. *) -val create : unit -> 'key t - -(** Register a single key accessor at a given path. *) -val register_value : - 'key t -> get:('key -> 'a option tzresult Lwt.t) -> 'a Data_encoding.t -> unit - -(** Return a description for a prefixed fragment of the given context. - All keys registered in the subcontext will be shared by the external - context *) -val register_named_subcontext : 'key t -> string list -> 'key t - -(** Description of an index as a sequence of `RPC_arg.t`. *) -type (_, _, _) args = - | One : { - rpc_arg : 'a RPC_arg.t; - encoding : 'a Data_encoding.t; - compare : 'a -> 'a -> int; - } - -> ('key, 'a, 'key * 'a) args - | Pair : - ('key, 'a, 'inter_key) args * ('inter_key, 'b, 'sub_key) args - -> ('key, 'a * 'b, 'sub_key) args - -(** Return a description for a indexed sub-context. - All keys registered in the subcontext will be shared by the external - context. One should provide a function to list all the registered - index in the context. *) -val register_indexed_subcontext : - 'key t -> - list:('key -> 'arg list tzresult Lwt.t) -> - ('key, 'arg, 'sub_key) args -> - 'sub_key t - -(** Helpers for manipulating and defining indexes. *) - -val pack : ('key, 'a, 'sub_key) args -> 'key -> 'a -> 'sub_key - -val unpack : ('key, 'a, 'sub_key) args -> 'sub_key -> 'key * 'a - -module type INDEX = sig - type t - - include Path_encoding.S with type t := t - - val rpc_arg : t RPC_arg.t - - val encoding : t Data_encoding.t - - val compare : t -> t -> int -end diff --git a/src/proto_012_Psithaca/lib_protocol/storage_functors.ml b/src/proto_012_Psithaca/lib_protocol/storage_functors.ml deleted file mode 100644 index 48a611f95b88..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/storage_functors.ml +++ /dev/null @@ -1,1123 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Storage_sigs - -module Registered = struct - let ghost = false -end - -module Ghost = struct - let ghost = true -end - -module type ENCODER = sig - type t - - val of_bytes : key:(unit -> string list) -> bytes -> t tzresult - - val to_bytes : t -> bytes -end - -module Make_encoder (V : VALUE) : ENCODER with type t := V.t = struct - let of_bytes ~key b = - match Data_encoding.Binary.of_bytes_opt V.encoding b with - | None -> error (Raw_context.Storage_error (Corrupted_data (key ()))) - | Some v -> Ok v - - let to_bytes v = - match Data_encoding.Binary.to_bytes_opt V.encoding v with - | Some b -> b - | None -> Bytes.empty -end - -let len_name = "len" - -let data_name = "data" - -let encode_len_value bytes = - let length = Bytes.length bytes in - Data_encoding.(Binary.to_bytes_exn int31) length - -let decode_len_value key len = - match Data_encoding.(Binary.of_bytes_opt int31) len with - | None -> error (Raw_context.Storage_error (Corrupted_data key)) - | Some len -> ok len - -module Make_subcontext (R : REGISTER) (C : Raw_context.T) (N : NAME) : - Raw_context.T with type t = C.t = struct - type t = C.t - - let to_key k = N.name @ k - - let mem t k = C.mem t (to_key k) - - let mem_tree t k = C.mem_tree t (to_key k) - - let get t k = C.get t (to_key k) - - let get_tree t k = C.get_tree t (to_key k) - - let find t k = C.find t (to_key k) - - let find_tree t k = C.find_tree t (to_key k) - - let add t k v = C.add t (to_key k) v - - let add_tree t k v = C.add_tree t (to_key k) v - - let init t k v = C.init t (to_key k) v - - let init_tree t k v = C.init_tree t (to_key k) v - - let update t k v = C.update t (to_key k) v - - let update_tree t k v = C.update_tree t (to_key k) v - - let add_or_remove t k v = C.add_or_remove t (to_key k) v - - let add_or_remove_tree t k v = C.add_or_remove_tree t (to_key k) v - - let remove_existing t k = C.remove_existing t (to_key k) - - let remove_existing_tree t k = C.remove_existing_tree t (to_key k) - - let remove t k = C.remove t (to_key k) - - let list t ?offset ?length k = C.list t ?offset ?length (to_key k) - - let fold ?depth t k ~order ~init ~f = - C.fold ?depth t (to_key k) ~order ~init ~f - - module Tree = C.Tree - - let project = C.project - - let absolute_key c k = C.absolute_key c (to_key k) - - type error += Block_quota_exceeded = C.Block_quota_exceeded - - type error += Operation_quota_exceeded = C.Operation_quota_exceeded - - let consume_gas = C.consume_gas - - let check_enough_gas = C.check_enough_gas - - let description = - let description = - if R.ghost then Storage_description.create () else C.description - in - Storage_description.register_named_subcontext description N.name -end - -module Make_single_data_storage - (R : REGISTER) - (C : Raw_context.T) - (N : NAME) - (V : VALUE) : Single_data_storage with type t = C.t and type value = V.t = -struct - type t = C.t - - type context = t - - type value = V.t - - let mem t = C.mem t N.name - - include Make_encoder (V) - - let get t = - C.get t N.name >>=? fun b -> - let key () = C.absolute_key t N.name in - Lwt.return (of_bytes ~key b) - - let find t = - C.find t N.name >|= function - | None -> Result.return_none - | Some b -> - let key () = C.absolute_key t N.name in - of_bytes ~key b >|? fun v -> Some v - - let init t v = C.init t N.name (to_bytes v) >|=? fun t -> C.project t - - let update t v = C.update t N.name (to_bytes v) >|=? fun t -> C.project t - - let add t v = C.add t N.name (to_bytes v) >|= fun t -> C.project t - - let add_or_remove t v = - C.add_or_remove t N.name (Option.map to_bytes v) >|= fun t -> C.project t - - let remove t = C.remove t N.name >|= fun t -> C.project t - - let remove_existing t = C.remove_existing t N.name >|=? fun t -> C.project t - - let () = - let open Storage_description in - let description = - if R.ghost then Storage_description.create () else C.description - in - register_value - ~get:find - (register_named_subcontext description N.name) - V.encoding - [@@coq_axiom_with_reason "stack overflow in Coq"] -end - -module type INDEX = sig - type t - - include Path_encoding.S with type t := t - - type 'a ipath - - val args : ('a, t, 'a ipath) Storage_description.args -end - -module Pair (I1 : INDEX) (I2 : INDEX) : INDEX with type t = I1.t * I2.t = struct - type t = I1.t * I2.t - - let path_length = I1.path_length + I2.path_length - - let to_path (x, y) l = I1.to_path x (I2.to_path y l) - - let of_path l = - match Misc.take I1.path_length l with - | None -> None - | Some (l1, l2) -> ( - match (I1.of_path l1, I2.of_path l2) with - | (Some x, Some y) -> Some (x, y) - | _ -> None) - - type 'a ipath = 'a I1.ipath I2.ipath - - let args = Storage_description.Pair (I1.args, I2.args) -end - -module Make_data_set_storage (C : Raw_context.T) (I : INDEX) : - Data_set_storage with type t = C.t and type elt = I.t = struct - type t = C.t - - type context = t - - type elt = I.t - - let inited = Bytes.of_string "inited" - - let mem s i = C.mem s (I.to_path i []) - - let add s i = C.add s (I.to_path i []) inited >|= fun t -> C.project t - - let remove s i = C.remove s (I.to_path i []) >|= fun t -> C.project t - - let clear s = C.remove s [] >|= fun t -> C.project t - - let fold s ~order ~init ~f = - C.fold ~depth:(`Eq I.path_length) s [] ~order ~init ~f:(fun file tree acc -> - match C.Tree.kind tree with - | `Value -> ( - match I.of_path file with None -> assert false | Some p -> f p acc) - | `Tree -> Lwt.return acc) - - let elements s = - fold s ~order:`Sorted ~init:[] ~f:(fun p acc -> Lwt.return (p :: acc)) - - let () = - let open Storage_description in - let unpack = unpack I.args in - register_value (* TODO fixme 'elements...' *) - ~get:(fun c -> - let (c, k) = unpack c in - mem c k >>= function true -> return_some true | false -> return_none) - (register_indexed_subcontext - ~list:(fun c -> elements c >|= ok) - C.description - I.args) - Data_encoding.bool - [@@coq_axiom_with_reason "stack overflow in Coq"] -end - -module Make_indexed_data_storage (C : Raw_context.T) (I : INDEX) (V : VALUE) : - Indexed_data_storage with type t = C.t and type key = I.t and type value = V.t = -struct - type t = C.t - - type context = t - - type key = I.t - - type value = V.t - - include Make_encoder (V) - - let mem s i = C.mem s (I.to_path i []) - - let get s i = - C.get s (I.to_path i []) >>=? fun b -> - let key () = C.absolute_key s (I.to_path i []) in - Lwt.return (of_bytes ~key b) - - let find s i = - C.find s (I.to_path i []) >|= function - | None -> Result.return_none - | Some b -> - let key () = C.absolute_key s (I.to_path i []) in - of_bytes ~key b >|? fun v -> Some v - - let update s i v = - C.update s (I.to_path i []) (to_bytes v) >|=? fun t -> C.project t - - let init s i v = - C.init s (I.to_path i []) (to_bytes v) >|=? fun t -> C.project t - - let add s i v = C.add s (I.to_path i []) (to_bytes v) >|= fun t -> C.project t - - let add_or_remove s i v = - C.add_or_remove s (I.to_path i []) (Option.map to_bytes v) >|= fun t -> - C.project t - - let remove s i = C.remove s (I.to_path i []) >|= fun t -> C.project t - - let remove_existing s i = - C.remove_existing s (I.to_path i []) >|=? fun t -> C.project t - - let clear s = C.remove s [] >|= fun t -> C.project t - - let fold s ~order ~init ~f = - C.fold ~depth:(`Eq I.path_length) s [] ~order ~init ~f:(fun file tree acc -> - C.Tree.to_value tree >>= function - | Some v -> ( - match I.of_path file with - | None -> assert false - | Some path -> ( - let key () = C.absolute_key s file in - match of_bytes ~key v with - | Ok v -> f path v acc - | Error _ -> Lwt.return acc)) - | None -> Lwt.return acc) - - let fold_keys s ~order ~init ~f = - fold s ~order ~init ~f:(fun k _ acc -> f k acc) - - let bindings s = - fold s ~order:`Sorted ~init:[] ~f:(fun p v acc -> - Lwt.return ((p, v) :: acc)) - - let keys s = - fold_keys s ~order:`Sorted ~init:[] ~f:(fun p acc -> Lwt.return (p :: acc)) - - let () = - let open Storage_description in - let unpack = unpack I.args in - register_value - ~get:(fun c -> - let (c, k) = unpack c in - find c k) - (register_indexed_subcontext - ~list:(fun c -> keys c >|= ok) - C.description - I.args) - V.encoding - [@@coq_axiom_with_reason "stack overflow in Coq"] -end - -(* Internal-use-only version of {!Make_indexed_carbonated_data_storage} to - expose fold_keys_unaccounted *) -module Make_indexed_carbonated_data_storage_INTERNAL - (C : Raw_context.T) - (I : INDEX) - (V : VALUE) : - Non_iterable_indexed_carbonated_data_storage_INTERNAL - with type t = C.t - and type key = I.t - and type value = V.t = struct - type t = C.t - - type context = t - - type key = I.t - - type value = V.t - - include Make_encoder (V) - - let data_key i = I.to_path i [data_name] - - let len_key i = I.to_path i [len_name] - - let consume_mem_gas c key = - C.consume_gas - c - (Storage_costs.read_access ~path_length:(List.length key) ~read_bytes:0) - - let existing_size c i = - C.find c (len_key i) >|= function - | None -> ok (0, false) - | Some len -> decode_len_value (len_key i) len >|? fun len -> (len, true) - - let consume_read_gas get c i = - let len_key = len_key i in - get c len_key >>=? fun len -> - Lwt.return - ( decode_len_value len_key len >>? fun read_bytes -> - let cost = - Storage_costs.read_access - ~path_length:(List.length len_key) - ~read_bytes - in - C.consume_gas c cost ) - - (* For the future: here, we bill a generic cost for encoding the value - to bytes. It would be cleaner for users of this functor to provide - gas costs for the encoding. *) - let consume_serialize_write_gas set c i v = - let bytes = to_bytes v in - let len = Bytes.length bytes in - C.consume_gas c (Gas_limit_repr.alloc_mbytes_cost len) >>?= fun c -> - let cost = Storage_costs.write_access ~written_bytes:len in - C.consume_gas c cost >>?= fun c -> - set c (len_key i) (encode_len_value bytes) >|=? fun c -> (c, bytes) - - let consume_remove_gas del c i = - C.consume_gas c (Storage_costs.write_access ~written_bytes:0) >>?= fun c -> - del c (len_key i) - - let mem s i = - let key = data_key i in - consume_mem_gas s key >>?= fun s -> - C.mem s key >|= fun exists -> ok (C.project s, exists) - - let get_unprojected s i = - consume_read_gas C.get s i >>=? fun s -> - C.get s (data_key i) >>=? fun b -> - let key () = C.absolute_key s (data_key i) in - Lwt.return (of_bytes ~key b >|? fun v -> (s, v)) - - let get s i = get_unprojected s i >|=? fun (s, v) -> (C.project s, v) - - let find s i = - let key = data_key i in - consume_mem_gas s key >>?= fun s -> - C.mem s key >>= fun exists -> - if exists then get s i >|=? fun (s, v) -> (s, Some v) - else return (C.project s, None) - - let update s i v = - existing_size s i >>=? fun (prev_size, _) -> - consume_serialize_write_gas C.update s i v >>=? fun (s, bytes) -> - C.update s (data_key i) bytes >|=? fun t -> - let size_diff = Bytes.length bytes - prev_size in - (C.project t, size_diff) - - let init s i v = - consume_serialize_write_gas C.init s i v >>=? fun (s, bytes) -> - C.init s (data_key i) bytes >|=? fun t -> - let size = Bytes.length bytes in - (C.project t, size) - - let add s i v = - let add s i v = C.add s i v >|= ok in - existing_size s i >>=? fun (prev_size, existed) -> - consume_serialize_write_gas add s i v >>=? fun (s, bytes) -> - add s (data_key i) bytes >|=? fun t -> - let size_diff = Bytes.length bytes - prev_size in - (C.project t, size_diff, existed) - - let remove s i = - let remove s i = C.remove s i >|= ok in - existing_size s i >>=? fun (prev_size, existed) -> - consume_remove_gas remove s i >>=? fun s -> - remove s (data_key i) >|=? fun t -> (C.project t, prev_size, existed) - - let remove_existing s i = - existing_size s i >>=? fun (prev_size, _) -> - consume_remove_gas C.remove_existing s i >>=? fun s -> - C.remove_existing s (data_key i) >|=? fun t -> (C.project t, prev_size) - - let add_or_remove s i v = - match v with None -> remove s i | Some v -> add s i v - - (** Because big map values are not stored under some common key, - we have no choice but to fold over all nodes with a path of length - [I.path_length] to retrieve actual keys and then paginate. - - While this is inefficient and will traverse the whole tree ([O(n)]), there - currently isn't a better decent alternative. - - Once https://gitlab.com/tezos/tezos/-/merge_requests/2771 which flattens paths is done, - {!C.list} could be used instead here. *) - let list_values ?(offset = 0) ?(length = max_int) s = - let root = [] in - let depth = `Eq I.path_length in - C.fold - s - root - ~depth - ~order:`Sorted - ~init:(ok (s, [], offset, length)) - ~f:(fun file tree acc -> - match (C.Tree.kind tree, acc) with - | (`Tree, Ok (s, rev_values, offset, length)) -> ( - if Compare.Int.(length <= 0) then - (* Keep going until the end, we have no means of short-circuiting *) - Lwt.return acc - else if Compare.Int.(offset > 0) then - (* Offset (first element) not reached yet *) - let offset = pred offset in - Lwt.return (Ok (s, rev_values, offset, length)) - else - (* Nominal case *) - match I.of_path file with - | None -> assert false - | Some key -> - get_unprojected s key >|=? fun (s, value) -> - (s, value :: rev_values, 0, pred length)) - | _ -> Lwt.return acc) - >|=? fun (s, rev_values, _offset, _length) -> - (C.project s, List.rev rev_values) - - let fold_keys_unaccounted s ~order ~init ~f = - C.fold ~depth:(`Eq I.path_length) s [] ~order ~init ~f:(fun file tree acc -> - match C.Tree.kind tree with - | `Value -> ( - match List.rev file with - | last :: _ when Compare.String.(last = len_name) -> Lwt.return acc - | last :: rest when Compare.String.(last = data_name) -> ( - let file = List.rev rest in - match I.of_path file with - | None -> assert false - | Some path -> f path acc) - | _ -> assert false) - | `Tree -> Lwt.return acc) - - let keys_unaccounted s = - fold_keys_unaccounted s ~order:`Sorted ~init:[] ~f:(fun p acc -> - Lwt.return (p :: acc)) - - let () = - let open Storage_description in - let unpack = unpack I.args in - register_value (* TODO export consumed gas ?? *) - ~get:(fun c -> - let (c, k) = unpack c in - find c k >|=? fun (_, v) -> v) - (register_indexed_subcontext - ~list:(fun c -> keys_unaccounted c >|= ok) - C.description - I.args) - V.encoding - [@@coq_axiom_with_reason "stack overflow in Coq"] -end - -module Make_indexed_carbonated_data_storage : functor - (C : Raw_context.T) - (I : INDEX) - (V : VALUE) - -> - Non_iterable_indexed_carbonated_data_storage_with_values - with type t = C.t - and type key = I.t - and type value = V.t = - Make_indexed_carbonated_data_storage_INTERNAL - -module Make_carbonated_data_set_storage (C : Raw_context.T) (I : INDEX) : - Carbonated_data_set_storage with type t = C.t and type elt = I.t = struct - module V = struct - type t = unit - - let encoding = Data_encoding.unit - end - - module M = Make_indexed_carbonated_data_storage_INTERNAL (C) (I) (V) - - type t = M.t - - type context = t - - type elt = I.t - - let mem = M.mem - - let init s i = M.init s i () - - let remove s i = M.remove s i - - let fold_keys_unaccounted = M.fold_keys_unaccounted -end - -module Make_indexed_data_snapshotable_storage - (C : Raw_context.T) - (Snapshot_index : INDEX) - (I : INDEX) - (V : VALUE) : - Indexed_data_snapshotable_storage - with type t = C.t - and type snapshot = Snapshot_index.t - and type key = I.t - and type value = V.t = struct - type snapshot = Snapshot_index.t - - let data_name = ["current"] - - let snapshot_name = ["snapshot"] - - module C_data = - Make_subcontext (Registered) (C) - (struct - let name = data_name - end) - - module C_snapshot = - Make_subcontext (Registered) (C) - (struct - let name = snapshot_name - end) - - module V_encoder = Make_encoder (V) - include Make_indexed_data_storage (C_data) (I) (V) - module Snapshot = - Make_indexed_data_storage (C_snapshot) (Pair (Snapshot_index) (I)) (V) - - let snapshot_path id = snapshot_name @ Snapshot_index.to_path id [] - - let snapshot_exists s id = C.mem_tree s (snapshot_path id) - - let err_missing_key key = Raw_context.storage_error (Missing_key (key, Copy)) - - let snapshot s id = - C.find_tree s data_name >>= function - | None -> Lwt.return (err_missing_key data_name) - | Some tree -> - C.add_tree s (snapshot_path id) tree >|= (fun t -> C.project t) >|= ok - - let fold_snapshot s id ~order ~init ~f = - C.find_tree s (snapshot_path id) >>= function - | None -> Lwt.return (err_missing_key data_name) - | Some tree -> - C_data.Tree.fold - tree - ~depth:(`Eq I.path_length) - [] - ~order - ~init:(Ok init) - ~f:(fun file tree acc -> - acc >>?= fun acc -> - C.Tree.to_value tree >>= function - | Some v -> ( - match I.of_path file with - | None -> assert false - | Some path -> ( - let key () = C.absolute_key s file in - match V_encoder.of_bytes ~key v with - | Ok v -> f path v acc - | Error _ -> return acc)) - | None -> return acc) - - let delete_snapshot s id = - C.remove s (snapshot_path id) >|= fun t -> C.project t -end - -module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX) : - Indexed_raw_context - with type t = C.t - and type key = I.t - and type 'a ipath = 'a I.ipath = struct - type t = C.t - - type context = t - - type key = I.t - - type 'a ipath = 'a I.ipath - - let clear t = C.remove t [] >|= fun t -> C.project t - - let fold_keys t ~order ~init ~f = - C.fold ~depth:(`Eq I.path_length) t [] ~order ~init ~f:(fun path tree acc -> - match C.Tree.kind tree with - | `Tree -> ( - match I.of_path path with - | None -> assert false - | Some path -> f path acc) - | `Value -> Lwt.return acc) - - let keys t = - fold_keys t ~order:`Sorted ~init:[] ~f:(fun i acc -> Lwt.return (i :: acc)) - - let err_missing_key key = Raw_context.storage_error (Missing_key (key, Copy)) - - let copy t ~from ~to_ = - let from = I.to_path from [] in - let to_ = I.to_path to_ [] in - C.find_tree t from >>= function - | None -> Lwt.return (err_missing_key from) - | Some tree -> C.add_tree t to_ tree >|= ok - - let remove t k = C.remove t (I.to_path k []) - - let description = - Storage_description.register_indexed_subcontext - ~list:(fun c -> keys c >|= ok) - C.description - I.args - - let unpack = Storage_description.unpack I.args - - let pack = Storage_description.pack I.args - - module Raw_context : Raw_context.T with type t = C.t I.ipath = struct - type t = C.t I.ipath - - let to_key i k = I.to_path i k - - let mem c k = - let (t, i) = unpack c in - C.mem t (to_key i k) - - let mem_tree c k = - let (t, i) = unpack c in - C.mem_tree t (to_key i k) - - let get c k = - let (t, i) = unpack c in - C.get t (to_key i k) - - let get_tree c k = - let (t, i) = unpack c in - C.get_tree t (to_key i k) - - let find c k = - let (t, i) = unpack c in - C.find t (to_key i k) - - let find_tree c k = - let (t, i) = unpack c in - C.find_tree t (to_key i k) - - let list c ?offset ?length k = - let (t, i) = unpack c in - C.list t ?offset ?length (to_key i k) - - let init c k v = - let (t, i) = unpack c in - C.init t (to_key i k) v >|=? fun t -> pack t i - - let init_tree c k v = - let (t, i) = unpack c in - C.init_tree t (to_key i k) v >|=? fun t -> pack t i - - let update c k v = - let (t, i) = unpack c in - C.update t (to_key i k) v >|=? fun t -> pack t i - - let update_tree c k v = - let (t, i) = unpack c in - C.update_tree t (to_key i k) v >|=? fun t -> pack t i - - let add c k v = - let (t, i) = unpack c in - C.add t (to_key i k) v >|= fun t -> pack t i - - let add_tree c k v = - let (t, i) = unpack c in - C.add_tree t (to_key i k) v >|= fun t -> pack t i - - let add_or_remove c k v = - let (t, i) = unpack c in - C.add_or_remove t (to_key i k) v >|= fun t -> pack t i - - let add_or_remove_tree c k v = - let (t, i) = unpack c in - C.add_or_remove_tree t (to_key i k) v >|= fun t -> pack t i - - let remove_existing c k = - let (t, i) = unpack c in - C.remove_existing t (to_key i k) >|=? fun t -> pack t i - - let remove_existing_tree c k = - let (t, i) = unpack c in - C.remove_existing_tree t (to_key i k) >|=? fun t -> pack t i - - let remove c k = - let (t, i) = unpack c in - C.remove t (to_key i k) >|= fun t -> pack t i - - let fold ?depth c k ~order ~init ~f = - let (t, i) = unpack c in - C.fold ?depth t (to_key i k) ~order ~init ~f - - module Tree = struct - include C.Tree - - let empty c = - let (t, _) = unpack c in - C.Tree.empty t - end - - let project c = - let (t, _) = unpack c in - C.project t - - let absolute_key c k = - let (t, i) = unpack c in - C.absolute_key t (to_key i k) - - type error += Block_quota_exceeded = C.Block_quota_exceeded - - type error += Operation_quota_exceeded = C.Operation_quota_exceeded - - let consume_gas c g = - let (t, i) = unpack c in - C.consume_gas t g >>? fun t -> ok (pack t i) - - let check_enough_gas c g = - let (t, _i) = unpack c in - C.check_enough_gas t g - - let description = description - end - - module Make_set (R : REGISTER) (N : NAME) : - Data_set_storage with type t = t and type elt = key = struct - type t = C.t - - type context = t - - type elt = I.t - - let inited = Bytes.of_string "inited" - - let mem s i = Raw_context.mem (pack s i) N.name - - let add s i = - Raw_context.add (pack s i) N.name inited >|= fun c -> - let (s, _) = unpack c in - C.project s - - let remove s i = - Raw_context.remove (pack s i) N.name >|= fun c -> - let (s, _) = unpack c in - C.project s - - let clear s = - fold_keys s ~init:s ~order:`Sorted ~f:(fun i s -> - Raw_context.remove (pack s i) N.name >|= fun c -> - let (s, _) = unpack c in - s) - >|= fun t -> C.project t - - let fold s ~order ~init ~f = - fold_keys s ~order ~init ~f:(fun i acc -> - mem s i >>= function true -> f i acc | false -> Lwt.return acc) - - let elements s = - fold s ~order:`Sorted ~init:[] ~f:(fun p acc -> Lwt.return (p :: acc)) - - let () = - let open Storage_description in - let unpack = unpack I.args in - let description = - if R.ghost then Storage_description.create () - else Raw_context.description - in - register_value - ~get:(fun c -> - let (c, k) = unpack c in - mem c k >>= function true -> return_some true | false -> return_none) - (register_named_subcontext description N.name) - Data_encoding.bool - [@@coq_axiom_with_reason "stack overflow in Coq"] - end - - module Make_map (N : NAME) (V : VALUE) : - Indexed_data_storage with type t = t and type key = key and type value = V.t = - struct - type t = C.t - - type context = t - - type key = I.t - - type value = V.t - - include Make_encoder (V) - - let mem s i = Raw_context.mem (pack s i) N.name - - let get s i = - Raw_context.get (pack s i) N.name >>=? fun b -> - let key () = Raw_context.absolute_key (pack s i) N.name in - Lwt.return (of_bytes ~key b) - - let find s i = - Raw_context.find (pack s i) N.name >|= function - | None -> Result.return_none - | Some b -> - let key () = Raw_context.absolute_key (pack s i) N.name in - of_bytes ~key b >|? fun v -> Some v - - let update s i v = - Raw_context.update (pack s i) N.name (to_bytes v) >|=? fun c -> - let (s, _) = unpack c in - C.project s - - let init s i v = - Raw_context.init (pack s i) N.name (to_bytes v) >|=? fun c -> - let (s, _) = unpack c in - C.project s - - let add s i v = - Raw_context.add (pack s i) N.name (to_bytes v) >|= fun c -> - let (s, _) = unpack c in - C.project s - - let add_or_remove s i v = - Raw_context.add_or_remove (pack s i) N.name (Option.map to_bytes v) - >|= fun c -> - let (s, _) = unpack c in - C.project s - - let remove s i = - Raw_context.remove (pack s i) N.name >|= fun c -> - let (s, _) = unpack c in - C.project s - - let remove_existing s i = - Raw_context.remove_existing (pack s i) N.name >|=? fun c -> - let (s, _) = unpack c in - C.project s - - let clear s = - fold_keys s ~order:`Sorted ~init:s ~f:(fun i s -> - Raw_context.remove (pack s i) N.name >|= fun c -> - let (s, _) = unpack c in - s) - >|= fun t -> C.project t - - let fold s ~order ~init ~f = - fold_keys s ~order ~init ~f:(fun i acc -> - get s i >>= function Error _ -> Lwt.return acc | Ok v -> f i v acc) - - let bindings s = - fold s ~order:`Sorted ~init:[] ~f:(fun p v acc -> - Lwt.return ((p, v) :: acc)) - - let fold_keys s ~order ~init ~f = - fold_keys s ~order ~init ~f:(fun i acc -> - mem s i >>= function false -> Lwt.return acc | true -> f i acc) - - let keys s = - fold_keys s ~order:`Sorted ~init:[] ~f:(fun p acc -> - Lwt.return (p :: acc)) - - let () = - let open Storage_description in - let unpack = unpack I.args in - register_value - ~get:(fun c -> - let (c, k) = unpack c in - find c k) - (register_named_subcontext Raw_context.description N.name) - V.encoding - [@@coq_axiom_with_reason "stack overflow in Coq"] - end - - module Make_carbonated_map (N : NAME) (V : VALUE) : - Non_iterable_indexed_carbonated_data_storage - with type t = t - and type key = key - and type value = V.t = struct - type t = C.t - - type context = t - - type key = I.t - - type value = V.t - - include Make_encoder (V) - - let len_name = len_name :: N.name - - let data_name = data_name :: N.name - - let path_length = List.length N.name + 1 - - let consume_mem_gas c = - Raw_context.consume_gas - c - (Storage_costs.read_access ~path_length ~read_bytes:0) - - let existing_size c = - Raw_context.find c len_name >|= function - | None -> ok (0, false) - | Some len -> decode_len_value len_name len >|? fun len -> (len, true) - - let consume_read_gas get c = - get c len_name >>=? fun len -> - Lwt.return - ( decode_len_value len_name len >>? fun read_bytes -> - Raw_context.consume_gas - c - (Storage_costs.read_access ~path_length ~read_bytes) ) - - let consume_write_gas set c v = - let bytes = to_bytes v in - let len = Bytes.length bytes in - Raw_context.consume_gas c (Storage_costs.write_access ~written_bytes:len) - >>?= fun c -> - set c len_name (encode_len_value bytes) >|=? fun c -> (c, bytes) - - let consume_remove_gas del c = - Raw_context.consume_gas c (Storage_costs.write_access ~written_bytes:0) - >>?= fun c -> del c len_name - - let mem s i = - consume_mem_gas (pack s i) >>?= fun c -> - Raw_context.mem c data_name >|= fun res -> ok (Raw_context.project c, res) - - let get s i = - consume_read_gas Raw_context.get (pack s i) >>=? fun c -> - Raw_context.get c data_name >>=? fun b -> - let key () = Raw_context.absolute_key c data_name in - Lwt.return (of_bytes ~key b >|? fun v -> (Raw_context.project c, v)) - - let find s i = - consume_mem_gas (pack s i) >>?= fun c -> - let (s, _) = unpack c in - Raw_context.mem (pack s i) data_name >>= fun exists -> - if exists then get s i >|=? fun (s, v) -> (s, Some v) - else return (C.project s, None) - - let update s i v = - existing_size (pack s i) >>=? fun (prev_size, _) -> - consume_write_gas Raw_context.update (pack s i) v >>=? fun (c, bytes) -> - Raw_context.update c data_name bytes >|=? fun c -> - let size_diff = Bytes.length bytes - prev_size in - (Raw_context.project c, size_diff) - - let init s i v = - consume_write_gas Raw_context.init (pack s i) v >>=? fun (c, bytes) -> - Raw_context.init c data_name bytes >|=? fun c -> - let size = Bytes.length bytes in - (Raw_context.project c, size) - - let add s i v = - let add c k v = Raw_context.add c k v >|= ok in - existing_size (pack s i) >>=? fun (prev_size, existed) -> - consume_write_gas add (pack s i) v >>=? fun (c, bytes) -> - add c data_name bytes >|=? fun c -> - let size_diff = Bytes.length bytes - prev_size in - (Raw_context.project c, size_diff, existed) - - let remove s i = - let remove c k = Raw_context.remove c k >|= ok in - existing_size (pack s i) >>=? fun (prev_size, existed) -> - consume_remove_gas remove (pack s i) >>=? fun c -> - remove c data_name >|=? fun c -> - (Raw_context.project c, prev_size, existed) - - let remove_existing s i = - existing_size (pack s i) >>=? fun (prev_size, _) -> - consume_remove_gas Raw_context.remove_existing (pack s i) >>=? fun c -> - Raw_context.remove_existing c data_name >|=? fun c -> - (Raw_context.project c, prev_size) - - let add_or_remove s i v = - match v with None -> remove s i | Some v -> add s i v - - let () = - let open Storage_description in - let unpack = unpack I.args in - register_value - ~get:(fun c -> - let (c, k) = unpack c in - find c k >|=? fun (_, v) -> v) - (register_named_subcontext Raw_context.description N.name) - V.encoding - [@@coq_axiom_with_reason "stack overflow in Coq"] - end -end - -module type WRAPPER = sig - type t - - type key - - val wrap : t -> key - - val unwrap : key -> t option -end - -module Wrap_indexed_data_storage - (C : Indexed_data_storage) - (K : WRAPPER with type key := C.key) : - Indexed_data_storage - with type t = C.t - and type key = K.t - and type value = C.value = struct - type t = C.t - - type context = C.t - - type key = K.t - - type value = C.value - - let mem ctxt k = C.mem ctxt (K.wrap k) - - let get ctxt k = C.get ctxt (K.wrap k) - - let find ctxt k = C.find ctxt (K.wrap k) - - let update ctxt k v = C.update ctxt (K.wrap k) v - - let init ctxt k v = C.init ctxt (K.wrap k) v - - let add ctxt k v = C.add ctxt (K.wrap k) v - - let add_or_remove ctxt k v = C.add_or_remove ctxt (K.wrap k) v - - let remove_existing ctxt k = C.remove_existing ctxt (K.wrap k) - - let remove ctxt k = C.remove ctxt (K.wrap k) - - let clear ctxt = C.clear ctxt - - let fold ctxt ~order ~init ~f = - C.fold ctxt ~order ~init ~f:(fun k v acc -> - match K.unwrap k with None -> Lwt.return acc | Some k -> f k v acc) - - let bindings s = - fold s ~order:`Sorted ~init:[] ~f:(fun p v acc -> - Lwt.return ((p, v) :: acc)) - - let fold_keys s ~order ~init ~f = - C.fold_keys s ~order ~init ~f:(fun k acc -> - match K.unwrap k with None -> Lwt.return acc | Some k -> f k acc) - - let keys s = - fold_keys s ~order:`Sorted ~init:[] ~f:(fun p acc -> Lwt.return (p :: acc)) -end diff --git a/src/proto_012_Psithaca/lib_protocol/storage_functors.mli b/src/proto_012_Psithaca/lib_protocol/storage_functors.mli deleted file mode 100644 index 5b78bc8a1f7f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/storage_functors.mli +++ /dev/null @@ -1,122 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Tezos Protocol Implementation - Typed storage builders. - - @see [Make_subcontext] - *) - -open Storage_sigs - -module Registered : REGISTER - -module Ghost : REGISTER - -(** Given a [Raw_context], return a new [Raw_context] that projects into - a given subtree. Similar to a {i functional lens}. - *) -module Make_subcontext (_ : REGISTER) (C : Raw_context.T) (_ : NAME) : - Raw_context.T with type t = C.t - -module Make_single_data_storage - (_ : REGISTER) - (C : Raw_context.T) - (_ : NAME) - (V : VALUE) : Single_data_storage with type t = C.t and type value = V.t - -(** A type that can be serialized as a [string list], and used - as a prefix in the typed datastore. - - Useful to implement storage of maps and sets. - *) -module type INDEX = sig - type t - - include Path_encoding.S with type t := t - - type 'a ipath - - val args : ('a, t, 'a ipath) Storage_description.args -end - -module Pair (I1 : INDEX) (I2 : INDEX) : INDEX with type t = I1.t * I2.t - -(** Create storage for a compound type. *) -module Make_data_set_storage (C : Raw_context.T) (I : INDEX) : - Data_set_storage with type t = C.t and type elt = I.t - -(** Like [Make_data_set_storage], adding tracking of storage cost. *) -module Make_carbonated_data_set_storage (C : Raw_context.T) (I : INDEX) : - Carbonated_data_set_storage with type t = C.t and type elt = I.t - -(** This functor creates storage for types with a notion of an index. *) -module Make_indexed_data_storage (C : Raw_context.T) (I : INDEX) (V : VALUE) : - Indexed_data_storage with type t = C.t and type key = I.t and type value = V.t - -(** Like [Make_indexed_data_storage], adding tracking of storage cost. *) -module Make_indexed_carbonated_data_storage - (C : Raw_context.T) - (I : INDEX) - (V : VALUE) : - Non_iterable_indexed_carbonated_data_storage_with_values - with type t = C.t - and type key = I.t - and type value = V.t - -module Make_indexed_data_snapshotable_storage - (C : Raw_context.T) - (Snapshot : INDEX) - (I : INDEX) - (V : VALUE) : - Indexed_data_snapshotable_storage - with type t = C.t - and type snapshot = Snapshot.t - and type key = I.t - and type value = V.t - -module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX) : - Indexed_raw_context - with type t = C.t - and type key = I.t - and type 'a ipath = 'a I.ipath - -module type WRAPPER = sig - type t - - type key - - val wrap : t -> key - - val unwrap : key -> t option -end - -module Wrap_indexed_data_storage - (C : Indexed_data_storage) - (K : WRAPPER with type key := C.key) : - Indexed_data_storage - with type t = C.t - and type key = K.t - and type value = C.value diff --git a/src/proto_012_Psithaca/lib_protocol/storage_sigs.ml b/src/proto_012_Psithaca/lib_protocol/storage_sigs.ml deleted file mode 100644 index 9a3d04cf73c6..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/storage_sigs.ml +++ /dev/null @@ -1,418 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2019-2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** {1 Entity Accessor Signatures} *) - -(** The generic signature of a single data accessor (a single value - bound to a specific key in the hierarchical (key x value) - database). *) -module type Single_data_storage = sig - type t - - type context = t - - (** The type of the value *) - type value - - (** Tells if the data is already defined *) - val mem : context -> bool Lwt.t - - (** Retrieve the value from the storage bucket ; returns a - {!Storage_error} if the key is not set or if the deserialisation - fails *) - val get : context -> value tzresult Lwt.t - - (** Retrieves the value from the storage bucket ; returns [None] if - the data is not initialized, or {!Storage_helpers.Storage_error} - if the deserialisation fails *) - val find : context -> value option tzresult Lwt.t - - (** Allocates the storage bucket and initializes it ; returns a - {!Storage_error Existing_key} if the bucket exists *) - val init : context -> value -> Raw_context.t tzresult Lwt.t - - (** Updates the content of the bucket ; returns a {!Storage_Error - Missing_key} if the value does not exists *) - val update : context -> value -> Raw_context.t tzresult Lwt.t - - (** Allocates the data and initializes it with a value ; just - updates it if the bucket exists *) - val add : context -> value -> Raw_context.t Lwt.t - - (** When the value is [Some v], allocates the data and initializes - it with [v] ; just updates it if the bucket exists. When the - value is [None], delete the storage bucket when the value ; does - nothing if the bucket does not exists. *) - val add_or_remove : context -> value option -> Raw_context.t Lwt.t - - (** Delete the storage bucket ; returns a {!Storage_error - Missing_key} if the bucket does not exists *) - val remove_existing : context -> Raw_context.t tzresult Lwt.t - - (** Removes the storage bucket and its contents ; does nothing if - the bucket does not exists *) - val remove : context -> Raw_context.t Lwt.t -end -[@@coq_precise_signature] - -(** Restricted version of {!Indexed_data_storage} w/o iterators. *) -module type Non_iterable_indexed_data_storage = sig - type t - - type context = t - - (** An abstract type for keys *) - type key - - (** The type of values *) - type value - - (** Tells if a given key is already bound to a storage bucket *) - val mem : context -> key -> bool Lwt.t - - (** Retrieve a value from the storage bucket at a given key ; - returns {!Storage_error Missing_key} if the key is not set ; - returns {!Storage_error Corrupted_data} if the deserialisation - fails. *) - val get : context -> key -> value tzresult Lwt.t - - (** Retrieve a value from the storage bucket at a given key ; - returns [None] if the value is not set ; returns {!Storage_error - Corrupted_data} if the deserialisation fails. *) - val find : context -> key -> value option tzresult Lwt.t - - (** Updates the content of a bucket ; returns A {!Storage_Error - Missing_key} if the value does not exists. *) - val update : context -> key -> value -> Raw_context.t tzresult Lwt.t - - (** Allocates a storage bucket at the given key and initializes it ; - returns a {!Storage_error Existing_key} if the bucket exists. *) - val init : context -> key -> value -> Raw_context.t tzresult Lwt.t - - (** Allocates a storage bucket at the given key and initializes it - with a value ; just updates it if the bucket exists. *) - val add : context -> key -> value -> Raw_context.t Lwt.t - - (** When the value is [Some v], allocates the data and initializes - it with [v] ; just updates it if the bucket exists. When the - value is [None], delete the storage bucket when the value ; does - nothing if the bucket does not exists. *) - val add_or_remove : context -> key -> value option -> Raw_context.t Lwt.t - - (** Delete a storage bucket and its contents ; returns a - {!Storage_error Missing_key} if the bucket does not exists. *) - val remove_existing : context -> key -> Raw_context.t tzresult Lwt.t - - (** Removes a storage bucket and its contents ; does nothing if the - bucket does not exists. *) - val remove : context -> key -> Raw_context.t Lwt.t -end -[@@coq_precise_signature] - -(** Variant of {!Non_iterable_indexed_data_storage} with gas accounting. *) -module type Non_iterable_indexed_carbonated_data_storage = sig - type t - - type context = t - - (** An abstract type for keys *) - type key - - (** The type of values *) - type value - - (** Tells if a given key is already bound to a storage bucket. - Consumes [Gas_repr.read_bytes_cost Z.zero]. *) - val mem : context -> key -> (Raw_context.t * bool) tzresult Lwt.t - - (** Retrieve a value from the storage bucket at a given key ; - returns {!Storage_error Missing_key} if the key is not set ; - returns {!Storage_error Corrupted_data} if the deserialisation - fails. - Consumes [Gas_repr.read_bytes_cost ]. *) - val get : context -> key -> (Raw_context.t * value) tzresult Lwt.t - - (** Retrieve a value from the storage bucket at a given key ; - returns [None] if the value is not set ; returns {!Storage_error - Corrupted_data} if the deserialisation fails. - Consumes [Gas_repr.read_bytes_cost ] if present - or [Gas_repr.read_bytes_cost Z.zero]. *) - val find : context -> key -> (Raw_context.t * value option) tzresult Lwt.t - - (** Updates the content of a bucket ; returns A {!Storage_Error - Missing_key} if the value does not exists. - Consumes serialization cost. - Consumes [Gas_repr.write_bytes_cost ]. - Returns the difference from the old to the new size. *) - val update : context -> key -> value -> (Raw_context.t * int) tzresult Lwt.t - - (** Allocates a storage bucket at the given key and initializes it ; - returns a {!Storage_error Existing_key} if the bucket exists. - Consumes serialization cost. - Consumes [Gas_repr.write_bytes_cost ]. - Returns the size. *) - val init : context -> key -> value -> (Raw_context.t * int) tzresult Lwt.t - - (** Allocates a storage bucket at the given key and initializes it - with a value ; just updates it if the bucket exists. - Consumes serialization cost. - Consumes [Gas_repr.write_bytes_cost ]. - Returns the difference from the old (maybe 0) to the new size, and a boolean - indicating if a value was already associated to this key. *) - val add : - context -> key -> value -> (Raw_context.t * int * bool) tzresult Lwt.t - - (** When the value is [Some v], allocates the data and initializes - it with [v] ; just updates it if the bucket exists. When the - value is [None], delete the storage bucket when the value ; does - nothing if the bucket does not exists. - Consumes serialization cost. - Consumes the same gas cost as either {!remove} or {!init_set}. - Returns the difference from the old (maybe 0) to the new size, and a boolean - indicating if a value was already associated to this key. *) - val add_or_remove : - context -> - key -> - value option -> - (Raw_context.t * int * bool) tzresult Lwt.t - - (** Delete a storage bucket and its contents ; returns a - {!Storage_error Missing_key} if the bucket does not exists. - Consumes [Gas_repr.write_bytes_cost Z.zero]. - Returns the freed size. *) - val remove_existing : context -> key -> (Raw_context.t * int) tzresult Lwt.t - - (** Removes a storage bucket and its contents ; does nothing if the - bucket does not exists. - Consumes [Gas_repr.write_bytes_cost Z.zero]. - Returns the freed size, and a boolean - indicating if a value was already associated to this key. *) - val remove : context -> key -> (Raw_context.t * int * bool) tzresult Lwt.t -end -[@@coq_precise_signature] - -module type Non_iterable_indexed_carbonated_data_storage_with_values = sig - include Non_iterable_indexed_carbonated_data_storage - - (* HACK *) - val list_values : - ?offset:int -> - ?length:int -> - t -> - (Raw_context.t * value list) tzresult Lwt.t -end - -module type Non_iterable_indexed_carbonated_data_storage_INTERNAL = sig - include Non_iterable_indexed_carbonated_data_storage_with_values - - val fold_keys_unaccounted : - context -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(key -> 'a -> 'a Lwt.t) -> - 'a Lwt.t -end - -(** The generic signature of indexed data accessors (a set of values - of the same type indexed by keys of the same form in the - hierarchical (key x value) database). *) -module type Indexed_data_storage = sig - include Non_iterable_indexed_data_storage - - (** Empties all the keys and associated data. *) - val clear : context -> Raw_context.t Lwt.t - - (** Lists all the keys. *) - val keys : context -> key list Lwt.t - - (** Lists all the keys and associated data. *) - val bindings : context -> (key * value) list Lwt.t - - (** Iterates over all the keys and associated data. *) - val fold : - context -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(key -> value -> 'a -> 'a Lwt.t) -> - 'a Lwt.t - - (** Iterate over all the keys. *) - val fold_keys : - context -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(key -> 'a -> 'a Lwt.t) -> - 'a Lwt.t -end - -module type Indexed_data_snapshotable_storage = sig - type snapshot - - type key - - include Indexed_data_storage with type key := key - - module Snapshot : - Indexed_data_storage - with type key = snapshot * key - and type value = value - and type t = t - - val snapshot_exists : context -> snapshot -> bool Lwt.t - - val snapshot : context -> snapshot -> Raw_context.t tzresult Lwt.t - - val fold_snapshot : - context -> - snapshot -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(key -> value -> 'a -> 'a tzresult Lwt.t) -> - 'a tzresult Lwt.t - - val delete_snapshot : context -> snapshot -> Raw_context.t Lwt.t -end - -(** The generic signature of a data set accessor (a set of values - bound to a specific key prefix in the hierarchical (key x value) - database). *) -module type Data_set_storage = sig - type t - - type context = t - - (** The type of elements. *) - type elt - - (** Tells if a elt is a member of the set *) - val mem : context -> elt -> bool Lwt.t - - (** Adds a elt is a member of the set *) - val add : context -> elt -> Raw_context.t Lwt.t - - (** Removes a elt of the set ; does nothing if not a member *) - val remove : context -> elt -> Raw_context.t Lwt.t - - (** Returns the elements of the set, deserialized in a list in no - particular order. *) - val elements : context -> elt list Lwt.t - - (** Iterates over the elements of the set. *) - val fold : - context -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(elt -> 'a -> 'a Lwt.t) -> - 'a Lwt.t - - (** Removes all elements in the set *) - val clear : context -> Raw_context.t Lwt.t -end - -(** Variant of {!Data_set_storage} with gas accounting. *) -module type Carbonated_data_set_storage = sig - type t - - type context = t - - (** The type of elements. *) - type elt - - (** Tells whether an elt is a member of the set. - Consumes [Gas_repr.read_bytes_cost Z.zero] *) - val mem : context -> elt -> (Raw_context.t * bool) tzresult Lwt.t - - (** Adds an elt as a member of the set. - Consumes [Gas_repr.write_bytes_cost ]. - Returns the the new size. *) - val init : context -> elt -> (Raw_context.t * int) tzresult Lwt.t - - (** Removes an elt from the set ; does nothing if not a member. - Consumes [Gas_repr.write_bytes_cost Z.zero]. - Returns the freed size, and a boolean - indicating if a value was already associated to this key. *) - val remove : context -> elt -> (Raw_context.t * int * bool) tzresult Lwt.t - - val fold_keys_unaccounted : - context -> - order:[`Sorted | `Undefined] -> - init:'acc -> - f:(elt -> 'acc -> 'acc Lwt.t) -> - 'acc Lwt.t -end - -module type NAME = sig - val name : Raw_context.key -end - -module type VALUE = sig - type t - - val encoding : t Data_encoding.t -end - -module type REGISTER = sig - val ghost : bool -end - -module type Indexed_raw_context = sig - type t - - type context = t - - type key - - type 'a ipath - - val clear : context -> Raw_context.t Lwt.t - - val fold_keys : - context -> - order:[`Sorted | `Undefined] -> - init:'a -> - f:(key -> 'a -> 'a Lwt.t) -> - 'a Lwt.t - - val keys : context -> key list Lwt.t - - val remove : context -> key -> context Lwt.t - - val copy : context -> from:key -> to_:key -> context tzresult Lwt.t - - module Make_set (_ : REGISTER) (_ : NAME) : - Data_set_storage with type t = t and type elt = key - - module Make_map (_ : NAME) (V : VALUE) : - Indexed_data_storage with type t = t and type key = key and type value = V.t - - module Make_carbonated_map (_ : NAME) (V : VALUE) : - Non_iterable_indexed_carbonated_data_storage - with type t = t - and type key = key - and type value = V.t - - module Raw_context : Raw_context.T with type t = t ipath -end diff --git a/src/proto_012_Psithaca/lib_protocol/test/.ocamlformat b/src/proto_012_Psithaca/lib_protocol/test/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/big_interpreter_stack.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/big_interpreter_stack.tz deleted file mode 100644 index 24832df0827f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/big_interpreter_stack.tz +++ /dev/null @@ -1,5 +0,0 @@ -{ parameter unit ; - storage unit ; - code { CAR ; - { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { {} ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; - NIL operation; PAIR } } diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract.tz deleted file mode 100644 index 48ba07e191fe..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract.tz +++ /dev/null @@ -1,69 +0,0 @@ -# This contract manages a shielded pool with a 1 to 1 conversion with respect to -# the tez, updated by a sapling transaction. The second parameter is an optional -# implicit account used to claim funds when unshielding. -storage (sapling_state 8); -parameter (list (pair (sapling_transaction 8) (option key_hash) ) ); -code { # Stack manipulation - UNPAIR; - NIL operation; - SWAP; - DIP { SWAP}; - AMOUNT ; - SWAP ; - DIP {SWAP} ; - ITER { UNPAIR; - DIP { SWAP }; - # We verify the transaction and update the storage if the transaction is - # valid. The shielded transactions are handled here. - # The new state is pushed on top of the stack in addition to the balance - # of the transaction. If the rest of the script goes well, this state - # will be the new state of the smart contract. - SAPLING_VERIFY_UPDATE; - # In the case of an invalid transaction, we stop. - ASSERT_SOME; - UNPAIR; - # Convert the balance in mutez, keeping the signed - # balance on top of the stack and the balance in mutez as the second - # element - DUP; - DIP { ABS; # in case of negative balance i.e. shielding - PUSH mutez 1; - MUL; }; - # We have three cases now: unshielding, shielding and transfers. - # If the balance is strictly positive (i.e. unshielding), we send funds - # to the given address. - # If no address is given (see ASSERT_SOME), we stop - IFGT { - DIIP { ASSERT_SOME; - IMPLICIT_ACCOUNT }; - SWAP; - DIP { UNIT; - TRANSFER_TOKENS; - SWAP; - # Stack manipulation to order. The operations will consist of the - # TRANSFER_TOKEN operation. - DIP {CONS} ;}; - } - # If the balance is negative or 0 (i.e. shielding or transfer), - # we verify the amount transferred in the transaction is exactly the - # balance of the verify_update output. It does enforce the conversion - # 1-1 between mutez and shielded token. - # No operation is executed. - { - DIIP {SWAP}; - DIP {SWAP}; - SWAP; - SUB_MUTEZ; ASSERT_SOME; - # As we transfer or shield token, an implicit account is not - # required. It is a good practice to verify. - # If an implicit account has been given, it might be an invalid - # operation or a call error. - DIIP { ASSERT_NONE;}; - SWAP; - }; - }; - DIP { - PUSH mutez 0; - ASSERT_CMPEQ;}; - SWAP; - PAIR} \ No newline at end of file diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_double.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_double.tz deleted file mode 100644 index 89148c8c355f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_double.tz +++ /dev/null @@ -1,33 +0,0 @@ -storage (pair (sapling_state :left 8) (sapling_state :right 8) ); -parameter (pair bool (pair (sapling_transaction :left 8) (sapling_transaction :right 8)) ); -code { UNPAIR ; - UNPAIR ; - DIP {UNPAIR} ; - DIIIP {UNPAIR} ; - DIIP {SWAP} ; - IF { SAPLING_VERIFY_UPDATE ; - ASSERT_SOME ; - UNPAIR ; - DROP ; - DIP {DIP {DUP}; - SAPLING_VERIFY_UPDATE; - ASSERT_SOME ; - UNPAIR ; - DROP ; - DROP;}; - } - { DIP { DUP}; - SAPLING_VERIFY_UPDATE; - ASSERT_SOME; - UNPAIR; - DROP; - DROP ; - DIP { SAPLING_VERIFY_UPDATE ; - ASSERT_SOME ; - UNPAIR; - DROP ; - }}; - PAIR; - NIL operation; - PAIR; - } diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_drop.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_drop.tz deleted file mode 100644 index b7e1b3912ff9..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_drop.tz +++ /dev/null @@ -1,14 +0,0 @@ -storage (unit); -parameter (list (sapling_transaction 8)); -code { UNPAIR ; - SAPLING_EMPTY_STATE 8; - SWAP ; - ITER { SAPLING_VERIFY_UPDATE ; - ASSERT_SOME ; - UNPAIR ; - DROP ; - } ; - DROP ; - NIL operation; - PAIR; - } diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_send.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_send.tz deleted file mode 100644 index 6eedc9dbc619..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_send.tz +++ /dev/null @@ -1,20 +0,0 @@ -storage (unit); -parameter (pair (contract (or (sapling_transaction 8) (sapling_state 8))) (sapling_transaction 8)); -code { UNPAIR ; - UNPAIR; - SWAP ; - SAPLING_EMPTY_STATE 8; - SWAP ; - SAPLING_VERIFY_UPDATE ; - ASSERT_SOME ; - UNPAIR ; - DROP ; - PUSH mutez 0; - SWAP ; - RIGHT (sapling_transaction 8); - TRANSFER_TOKENS; - NIL operation; - SWAP; - CONS; - PAIR; - } diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_state_as_arg.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_state_as_arg.tz deleted file mode 100644 index e8a96df046ee..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_contract_state_as_arg.tz +++ /dev/null @@ -1,18 +0,0 @@ -storage (option (sapling_transaction 8)); -parameter (or (sapling_transaction 8) (sapling_state 8)); -code { UNPAIR ; - IF_LEFT - { - DIP {DROP;}; - SOME; - } - { DIP {ASSERT_SOME;}; - SWAP ; - SAPLING_VERIFY_UPDATE; - ASSERT_SOME; - DROP ; - NONE (sapling_transaction 8) ; - }; - NIL operation; - PAIR; - } diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_push_sapling_state.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_push_sapling_state.tz deleted file mode 100644 index 8d1db432bf2e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_push_sapling_state.tz +++ /dev/null @@ -1,11 +0,0 @@ -# Attempt to use `PUSH sapling_state 0` where 0 is the ID of a sapling state. -# sapling_state is not allowed in the instruction PUSH. -parameter unit; -storage unit; -code { DROP; - PUSH (sapling_state 8) 0; - DROP; - PUSH unit Unit; - NIL operation; - PAIR; - } diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_use_existing_state.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_use_existing_state.tz deleted file mode 100644 index b637870653f8..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/sapling_use_existing_state.tz +++ /dev/null @@ -1,12 +0,0 @@ -parameter (pair (sapling_transaction 8) (sapling_state 8)); -storage (sapling_state 8); -code { UNPAIR; - UNPAIR; - DIIP { DROP }; - SAPLING_VERIFY_UPDATE; - ASSERT_SOME; - UNPAIR; - DROP; - NIL operation; - PAIR; - } diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/temp_big_maps.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/temp_big_maps.tz deleted file mode 100644 index 0a9162f8f982..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/temp_big_maps.tz +++ /dev/null @@ -1,81 +0,0 @@ -# Testing passing/originating with big maps from different sources -# This contract is used by test_temp_big_maps.ml - -# The left member of the parameter is either: -# - (Left True) to use a fresh big map -# - (Left False) to use the stored big map -# - (Right bigmap) to use the passed big map - -# The right member of the parameter is used to decide between: -# - passing the argument (positive value) -# - doing nothing (zero) -# - originating (negative value) - -parameter (pair (or bool (big_map int int)) int); -storage (big_map int int); -code - { # parameter * storage :: [] - UNPAIR; # parameter :: storage :: [] - UNPAIR; # parameter.fst :: parameter.snd :: storage :: [] - DIP { SWAP }; # parameter.fst :: storage :: parameter.snd :: [] - IF_LEFT - { # parameter.fst.Left :: storage :: parameter.snd :: [] - IF - { # storage :: parameter.snd :: [] - DROP; # parameter.snd :: [] - EMPTY_BIG_MAP int int; # empty_big_map :: parameter.snd :: [] - PUSH (option int) (Some 2); # Some 2 :: empty_big_map :: parameter.snd :: [] - PUSH int 1; # 1 :: Some 2 :: empty_big_map :: parameter.snd :: [] - UPDATE; # big_map { 1 -> 2 } :: parameter.snd :: [] - } - { # stored_big_map :: parameter.snd :: [] - } - } - { # parameter.fst.Right :: storage :: parameter.snd :: [] - DIP { DROP } # passed_big_map :: parameter.snd :: [] - }; - DUP; # big_map :: big_map :: parameter.snd :: [] - DIG 2; # parameter.snd :: big_map :: big_map :: [] - DUP; # parameter.snd :: parameter.snd :: big_map :: big_map :: [] - IFGT - { # parameter.snd :: big_map :: big_map :: [] - PUSH int -1; - ADD; # parameter.snd - 1 :: big_map :: big_map :: [] - SWAP; # big_map :: parameter.snd - 1 :: big_map :: [] - RIGHT bool ; # Right big_map :: parameter.snd - 1 :: big_map :: [] - PAIR; # Right big_map * (parameter.snd - 1) :: big_map :: [] - DIP { SELF; PUSH mutez 0; }; # Right big_map * (parameter.snd - 1) :: 0 mutez :: self :: big_map :: [] - TRANSFER_TOKENS; # transfer_tokens :: big_map :: [] - NIL operation; # nil_operation :: transfer_tokens :: big_map :: [] - SWAP; # transfer_tokens :: nil_operation :: big_map :: [] - CONS # list operation :: big_map :: [] - } - { # parameter.snd :: big_map :: big_map :: [] - IFEQ - { # big_map :: big_map :: [] - DROP; # big_map :: [] - NIL operation; # list operation :: big_map :: [] - } - { # big_map :: big_map :: [] - PUSH mutez 0; # 0 mutez :: big_map :: big_map :: [] - NONE key_hash; # None key_hash :: 0 mutez :: big_map :: big_map :: [] - CREATE_CONTRACT - { - parameter unit; - storage (big_map int int); - code - { - UNPAIR; - DROP; - NIL operation; - PAIR - } - }; # create_contract :: address :: big_map :: [] - DIP { DROP }; # create_contract :: big_map :: [] - NIL operation; # nil_operation :: create_contract :: big_map :: [] - SWAP; # create_contract :: nil_operation :: big_map :: [] - CONS # list operation :: big_map :: [] - }; - }; - PAIR # (list operation * big_map) :: [] - } diff --git a/src/proto_012_Psithaca/lib_protocol/test/contracts/timelock.tz b/src/proto_012_Psithaca/lib_protocol/test/contracts/timelock.tz deleted file mode 100644 index 2ddad4258117..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/contracts/timelock.tz +++ /dev/null @@ -1,31 +0,0 @@ -# This contract takes a chest and chest key as parameter. -# It tries to open it and stores the resulting bytes if successful. -# Otherwise it stores some hardcoded bytes to test that we are in -# the expected branch -storage (bytes); -parameter (pair (chest_key) (chest)); -code { - UNPAIR; - DIP {DROP}; - UNPAIR; - DIIP {PUSH nat 1000}; - OPEN_CHEST; - IF_LEFT - { # successful case - NIL operation; - PAIR ; - } - { - IF - { # first type of failure - PUSH bytes 0x01; - NIL operation; - PAIR; - } - { # second type of failure - PUSH bytes 0x00; - NIL operation; - PAIR; - } - } - } diff --git a/src/proto_012_Psithaca/lib_protocol/test/dune b/src/proto_012_Psithaca/lib_protocol/test/dune deleted file mode 100644 index 9e269e7ca329..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/dune +++ /dev/null @@ -1,80 +0,0 @@ -(tests - (names main - saturation_fuzzing - test_gas_properties - test_tez_repr - liquidity_baking_pbt - test_script_comparison - test_sampler) - (package tezos-protocol-012-Psithaca-tests) - (deps (glob_files contracts/*)) - (libraries tezos-base - tezos-micheline - tezos-protocol-environment - alcotest-lwt - tezos-test-helpers - qcheck-alcotest - tezos-012-Psithaca-test-helpers - tezos-stdlib-unix - tezos-client-base - tezos-protocol-012-Psithaca-parameters - tezos-base-test-helpers - tezos-sapling - astring - tezos-protocol-plugin-012-Psithaca - tezos-benchmark - tezos-benchmark-012-Psithaca) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_micheline - -open Tezos_client_012_Psithaca - -open Tezos_protocol_012_Psithaca - -open Tezos_protocol_012_Psithaca_parameters - -open Tezos_protocol_plugin_012_Psithaca - -open Tezos_protocol_environment_012_Psithaca - -open Tezos_benchmark_012_Psithaca - -open Tezos_benchmark_type_inference_012_Psithaca - -open Tezos_012_Psithaca_test_helpers - -open Tezos_base_test_helpers))) - -(rule - (copy %{lib:tezos-protocol-012-Psithaca-parameters:test-parameters.json} - protocol_parameters.json)) - -; runs both `Quick and `Slow tests -(rule - (alias runtest_proto_012_Psithaca) - (deps (glob_files contracts/*)) - (package tezos-protocol-012-Psithaca-tests) - (action (run %{exe:main.exe}))) - -; runs only the `Quick tests -(rule - (alias runtest_quick) - (deps (glob_files contracts/*)) - (package tezos-protocol-012-Psithaca-tests) - (action (run %{exe:main.exe} -q))) - -(rule - (alias runtest_saturation_fuzzing) - (package tezos-protocol-012-Psithaca-tests) - (action (run %{exe:saturation_fuzzing.exe}))) - -(rule - (alias runtest_sampler) - (package tezos-protocol-012-Psithaca-tests) - (action (run %{exe:test_sampler.exe}))) - -(rule - (alias runtest_test_script_comparison) - (package tezos-protocol-012-Psithaca-tests) - (action (run %{exe:test_script_comparison.exe}))) - -(rule - (alias runtest_test_tez_repr) - (package tezos-protocol-012-Psithaca-tests) - (action (run %{exe:test_tez_repr.exe}))) - -(rule - (alias runtest_liquidity_baking_pbt) - (package tezos-protocol-012-Psithaca-tests) - (action (run %{exe:liquidity_baking_pbt.exe}))) diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/.ocamlformat b/src/proto_012_Psithaca/lib_protocol/test/helpers/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/README.md b/src/proto_012_Psithaca/lib_protocol/test/helpers/README.md deleted file mode 100644 index b071cfb4ec03..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Helpers to build unit/integration tests for the protocol - -The OPAM package `tezos-alpha-test-helpers` contains helpers to build unit/integration tests, like forging a block, a context, nonces, operations, etc. diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/account.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/account.ml deleted file mode 100644 index 47e8e5a2e7ec..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/account.ml +++ /dev/null @@ -1,115 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type t = { - pkh : Signature.Public_key_hash.t; - pk : Signature.Public_key.t; - sk : Signature.Secret_key.t; -} - -type account = t - -let known_accounts = Signature.Public_key_hash.Table.create 17 - -let random_seed ~rng_state = - Bytes.init Hacl.Ed25519.sk_size (fun _i -> - Char.chr (Random.State.int rng_state 256)) - -let new_account ?seed () = - let (pkh, pk, sk) = Signature.generate_key ~algo:Ed25519 ?seed () in - let account = {pkh; pk; sk} in - Signature.Public_key_hash.Table.add known_accounts pkh account ; - account - -let add_account ({pkh; _} as account) = - Signature.Public_key_hash.Table.add known_accounts pkh account - -let activator_account = - let seed = random_seed ~rng_state:(Random.State.make [|0x1337533D|]) in - new_account ~seed () - -let find pkh = - match Signature.Public_key_hash.Table.find known_accounts pkh with - | Some k -> return k - | None -> failwith "Missing account: %a" Signature.Public_key_hash.pp pkh - -let find_alternate pkh = - let exception Found of t in - try - Signature.Public_key_hash.Table.iter - (fun pkh' account -> - if not (Signature.Public_key_hash.equal pkh pkh') then - raise (Found account)) - known_accounts ; - raise Not_found - with Found account -> account - -let dummy_account = - let seed = - random_seed ~rng_state:(Random.State.make [|0x1337533D; 0x1337533D|]) - in - new_account ~seed () - -let default_initial_balance = Tez.of_mutez_exn 4_000_000_000_000L - -let generate_accounts ?rng_state ?(initial_balances = []) n : (t * Tez.t) list = - Signature.Public_key_hash.Table.clear known_accounts ; - let amount i = - match List.nth_opt initial_balances i with - | None -> default_initial_balance - | Some a -> Tez.of_mutez_exn a - in - let rng_state = - match rng_state with - | None -> Random.State.make_self_init () - | Some state -> state - in - List.map - (fun i -> - let (pkh, pk, sk) = - Signature.generate_key ~algo:Ed25519 ~seed:(random_seed ~rng_state) () - in - let account = {pkh; pk; sk} in - Signature.Public_key_hash.Table.add known_accounts pkh account ; - (account, amount i)) - (0 -- (n - 1)) - -let commitment_secret = - Blinded_public_key_hash.activation_code_of_hex - "aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbb" - |> WithExceptions.Option.get ~loc:__LOC__ - -let new_commitment ?seed () = - let (pkh, pk, sk) = Signature.generate_key ?seed ~algo:Ed25519 () in - let unactivated_account = {pkh; pk; sk} in - let open Commitment in - let pkh = match pkh with Ed25519 pkh -> pkh | _ -> assert false in - let bpkh = Blinded_public_key_hash.of_ed25519_pkh commitment_secret pkh in - Lwt.return - ( (Environment.wrap_tzresult @@ Tez.(one *? 4_000L)) >|? fun amount -> - (unactivated_account, {blinded_public_key_hash = bpkh; amount}) ) diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/account.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/account.mli deleted file mode 100644 index f327344fcfbb..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/account.mli +++ /dev/null @@ -1,68 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type t = { - pkh : Signature.Public_key_hash.t; - pk : Signature.Public_key.t; - sk : Signature.Secret_key.t; -} - -type account = t - -val known_accounts : t Signature.Public_key_hash.Table.t - -val activator_account : account - -val dummy_account : account - -val new_account : ?seed:Bytes.t -> unit -> account - -val add_account : t -> unit - -val find : Signature.Public_key_hash.t -> t tzresult Lwt.t - -val find_alternate : Signature.Public_key_hash.t -> t - -(** 4.000.000.000 tez *) -val default_initial_balance : Tez.t - -(** [generate_accounts ?initial_balances n] : generates [n] random - accounts with the initial balance of the [i]th account given by the - [i]th value in the list [initial_balances] or otherwise - [default_initial_balance] tz (if the list is too short); and add them to the - global account state *) -val generate_accounts : - ?rng_state:Random.State.t -> - ?initial_balances:int64 list -> - int -> - (t * Tez.t) list - -val commitment_secret : Blinded_public_key_hash.activation_code - -val new_commitment : - ?seed:Bytes.t -> unit -> (account * Commitment.t) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/assert.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/assert.ml deleted file mode 100644 index a68d43f6f3b9..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/assert.ml +++ /dev/null @@ -1,178 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -let error ~loc v f = - match v with - | Error err when List.exists f err -> return_unit - | Ok _ -> failwith "Unexpected successful result (%s)" loc - | Error err -> failwith "@[Unexpected error (%s): %a@]" loc pp_print_trace err - -let test_error_encodings e = - let module E = Environment.Error_monad in - ignore (E.pp Format.str_formatter e) ; - let e' = E.json_of_error e |> E.error_of_json in - assert (e = e') - -let proto_error ~loc v f = - error ~loc v (function - | Environment.Ecoproto_error err -> - test_error_encodings err ; - f err - | _ -> false) - -let proto_error_with_info ~loc res error_title = - proto_error ~loc res (function err -> - error_title - = (Error_monad.find_info_of_error (Environment.wrap_tzerror err)).title) - -let equal ~loc (cmp : 'a -> 'a -> bool) msg pp a b = - if not (cmp a b) then - failwith "@[@[[%s]@] - @[%s : %a is not equal to %a@]@]" loc msg pp a pp b - else return_unit - -let leq ~loc (cmp : 'a -> 'a -> int) msg pp a b = - if cmp a b > 0 then - failwith - "@[@[[%s]@] - @[%s : %a is not less or equal to %a@]@]" - loc - msg - pp - a - pp - b - else return_unit - -let not_equal ~loc (cmp : 'a -> 'a -> bool) msg pp a b = - if cmp a b then - failwith "@[@[[%s]@] - @[%s : %a is equal to %a@]@]" loc msg pp a pp b - else return_unit - -module Int32 = struct - include Int32 - - let pp pp v = Format.pp_print_int pp (Int32.to_int v) -end - -module Int64 = struct - include Int64 - - let pp pp v = Format.pp_print_int pp (Int64.to_int v) -end - -(* int *) -let equal_int ~loc (a : int) (b : int) = - equal ~loc Int.equal "Integers aren't equal" Format.pp_print_int a b - -let not_equal_int ~loc (a : int) (b : int) = - not_equal ~loc Int.equal "Integers are equal" Format.pp_print_int a b - -let leq_int ~loc (a : int) (b : int) = - leq ~loc Compare.Int.compare "Integer comparison" Format.pp_print_int a b - -(* int32 *) -let equal_int32 ~loc (a : int32) (b : int32) = - equal ~loc Int32.equal "Int32 aren't equal" Int32.pp a b - -(* int64 *) -let equal_int64 ~loc (a : int64) (b : int64) = - equal ~loc Compare.Int64.( = ) "Int64 aren't equal" Int64.pp a b - -let not_equal_int64 ~loc (a : int64) (b : int64) = - not_equal ~loc Int64.equal "Int64 are equal" Int64.pp a b - -let leq_int64 ~loc (a : int64) (b : int64) = - leq ~loc Compare.Int64.compare "Int64 comparison" Int64.pp a b - -(* bool *) -let equal_bool ~loc (a : bool) (b : bool) = - equal ~loc Bool.equal "Booleans aren't equal" Format.pp_print_bool a b - -let not_equal_bool ~loc (a : bool) (b : bool) = - not_equal ~loc Bool.equal "Booleans are equal" Format.pp_print_bool a b - -(* tez *) -let equal_tez ~loc (a : Alpha_context.Tez.t) (b : Alpha_context.Tez.t) = - let open Alpha_context in - equal ~loc Tez.( = ) "Tez aren't equal" Tez.pp a b - -let not_equal_tez ~loc (a : Alpha_context.Tez.t) (b : Alpha_context.Tez.t) = - let open Alpha_context in - not_equal ~loc Tez.( = ) "Tez are equal" Tez.pp a b - -(* pkh *) -let equal_pkh ~loc (a : Signature.Public_key_hash.t) - (b : Signature.Public_key_hash.t) = - let module PKH = Signature.Public_key_hash in - equal ~loc PKH.equal "Public key hashes aren't equal" PKH.pp a b - -let not_equal_pkh ~loc (a : Signature.Public_key_hash.t) - (b : Signature.Public_key_hash.t) = - let module PKH = Signature.Public_key_hash in - not_equal ~loc PKH.equal "Public key hashes are equal" PKH.pp a b - -let get_some ~loc = function - | Some x -> return x - | None -> failwith "Unexpected None (%s)" loc - -let is_none ~loc ~pp = function - | Some x -> failwith "Unexpected (Some %a) (%s)" pp x loc - | None -> return_unit - -open Context - -(* Some asserts for account operations *) - -(** [balance_is b c amount] checks that the current balance of contract [c] is - [amount]. - Default balance type is [Main], pass [~kind] with [Deposit], [Fees] or - [Rewards] for the others. *) -let balance_is ~loc b contract expected = - Contract.balance b contract >>=? fun balance -> - equal_tez ~loc balance expected - -(** [balance_was_operated ~operand b c old_balance amount] checks that the - current balance of contract [c] is [operand old_balance amount] and - returns the current balance. - Default balance type is [Main], pass [~kind] with [Deposit], [Fees] or - [Rewards] for the others. *) -let balance_was_operated ~operand ~loc b contract old_balance amount = - operand old_balance amount |> Environment.wrap_tzresult >>?= fun expected -> - balance_is ~loc b contract expected - -let balance_was_credited = - balance_was_operated ~operand:Alpha_context.Tez.( +? ) - -let balance_was_debited = balance_was_operated ~operand:Alpha_context.Tez.( -? ) - -let pp_print_list pp out xs = - let list_pp fmt = - Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ";@.") fmt - in - Format.fprintf out "[%a]" (list_pp pp) xs - -let assert_equal_list ~loc eq msg pp = - equal ~loc (List.equal eq) msg (pp_print_list pp) diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/block.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/block.ml deleted file mode 100644 index 5bbb823d5a6d..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/block.ml +++ /dev/null @@ -1,759 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -module Proto_Nonce = Nonce (* Renamed otherwise is masked by Alpha_context *) - -open Alpha_context - -(* This type collects a block and the context that results from its application *) -type t = { - hash : Block_hash.t; - header : Block_header.t; - operations : Operation.packed list; - context : Tezos_protocol_environment.Context.t; -} - -type block = t - -let rpc_context block = - { - Environment.Updater.block_hash = block.hash; - block_header = block.header.shell; - context = block.context; - } - -let rpc_ctxt = - new Environment.proto_rpc_context_of_directory - rpc_context - Plugin.RPC.rpc_services - -(******** Policies ***********) - -(* Policies are functions that take a block and return a tuple - [(account, level, timestamp)] for the [forge_header] function. *) - -(* This type is used only to provide a simpler interface to the exterior. *) -type baker_policy = - | By_round of int - | By_account of public_key_hash - | Excluding of public_key_hash list - -type baking_mode = Application | Baking - -let get_next_baker_by_round round block = - Plugin.RPC.Baking_rights.get rpc_ctxt ~all:true ~max_round:(round + 1) block - >|=? fun bakers -> - let {Plugin.RPC.Baking_rights.delegate = pkh; timestamp; _} = - WithExceptions.Option.get ~loc:__LOC__ - @@ List.find - (fun {Plugin.RPC.Baking_rights.round = r; _} -> r = round) - bakers - in - (pkh, round, WithExceptions.Option.to_exn ~none:(Failure "") timestamp) - -let get_next_baker_by_account pkh block = - Plugin.RPC.Baking_rights.get rpc_ctxt ~delegates:[pkh] block - >>=? fun bakers -> - (match List.hd bakers with - | Some b -> return b - | None -> failwith "No slots found for %a" Signature.Public_key_hash.pp pkh) - >>=? fun {Plugin.RPC.Baking_rights.delegate = pkh; timestamp; round; _} -> - return - (pkh, round, WithExceptions.Option.to_exn ~none:(Failure __LOC__) timestamp) - -let get_next_baker_excluding excludes block = - Plugin.RPC.Baking_rights.get rpc_ctxt block >|=? fun bakers -> - let {Plugin.RPC.Baking_rights.delegate = pkh; timestamp; round; _} = - WithExceptions.Option.get ~loc:__LOC__ - @@ List.find - (fun {Plugin.RPC.Baking_rights.delegate; _} -> - not - (List.mem ~equal:Signature.Public_key_hash.equal delegate excludes)) - bakers - in - (pkh, round, WithExceptions.Option.to_exn ~none:(Failure "") timestamp) - -let dispatch_policy = function - | By_round r -> get_next_baker_by_round r - | By_account a -> get_next_baker_by_account a - | Excluding al -> get_next_baker_excluding al - -let get_next_baker ?(policy = By_round 0) = dispatch_policy policy - -let get_round (b : t) = - let fitness = b.header.shell.fitness in - Fitness.(from_raw fitness >|? round) |> Environment.wrap_tzresult - -module Forge = struct - type header = { - baker : public_key_hash; - (* the signer of the block *) - shell : Block_header.shell_header; - contents : Block_header.contents; - } - - let default_proof_of_work_nonce = - Bytes.create Constants.proof_of_work_nonce_size - - let make_contents ?(proof_of_work_nonce = default_proof_of_work_nonce) - ~payload_hash ~payload_round ?(liquidity_baking_escape_vote = false) - ~seed_nonce_hash () = - Block_header. - { - payload_hash; - payload_round; - proof_of_work_nonce; - seed_nonce_hash; - liquidity_baking_escape_vote; - } - - let make_shell ~level ~predecessor ~timestamp ~fitness ~operations_hash = - Tezos_base.Block_header. - { - level; - predecessor; - timestamp; - fitness; - operations_hash; - (* We don't care of the following values, only the shell validates them. *) - proto_level = 0; - validation_passes = 0; - context = Context_hash.zero; - } - - let set_seed_nonce_hash seed_nonce_hash {baker; shell; contents} = - {baker; shell; contents = {contents with seed_nonce_hash}} - - let set_baker baker header = {header with baker} - - let sign_header {baker; shell; contents} = - Account.find baker >|=? fun delegate -> - let unsigned_bytes = - Data_encoding.Binary.to_bytes_exn - Block_header.unsigned_encoding - (shell, contents) - in - let signature = - Signature.sign - ~watermark:Block_header.(to_watermark (Block_header Chain_id.zero)) - delegate.sk - unsigned_bytes - in - Block_header.{shell; protocol_data = {contents; signature}} - - let classify_operations operations = - let validation_passes_len = List.length Main.validation_passes in - let t = Array.make validation_passes_len [] in - List.iter - (fun (op : packed_operation) -> - List.iter - (fun pass -> t.(pass) <- op :: t.(pass)) - (Main.acceptable_passes op)) - operations ; - let t = Array.map List.rev t in - Array.to_list t - - let forge_header ?(locked_round = None) ?(payload_round = None) - ?(policy = By_round 0) ?timestamp ?(operations = []) - ?liquidity_baking_escape_vote pred = - let pred_fitness = - match Fitness.from_raw pred.header.shell.fitness with - | Ok pred_fitness -> pred_fitness - | _ -> assert false - in - let predecessor_round = Fitness.round pred_fitness in - dispatch_policy policy pred >>=? fun (pkh, round, expected_timestamp) -> - let timestamp = Option.value ~default:expected_timestamp timestamp in - let level = Int32.succ pred.header.shell.level in - Raw_level.of_int32 level |> Environment.wrap_tzresult >>?= fun raw_level -> - Round.of_int round |> Environment.wrap_tzresult >>?= fun round -> - Fitness.create ~level:raw_level ~predecessor_round ~round ~locked_round - >|? Fitness.to_raw |> Environment.wrap_tzresult - >>?= fun fitness -> - (Plugin.RPC.current_level ~offset:1l rpc_ctxt pred >|=? function - | {expected_commitment = true; _} -> Some (fst (Proto_Nonce.generate ())) - | {expected_commitment = false; _} -> None) - >|=? fun seed_nonce_hash -> - let hashes = List.map Operation.hash_packed operations in - let operations_hash = - Operation_list_list_hash.compute [Operation_list_hash.compute hashes] - in - let shell = - make_shell - ~level - ~predecessor:pred.hash - ~timestamp - ~fitness - ~operations_hash - in - let operations = classify_operations operations in - let non_consensus_operations = - List.concat (match List.tl operations with None -> [] | Some l -> l) - in - let hashes = List.map Operation.hash_packed non_consensus_operations in - let non_consensus_operations_hash = Operation_list_hash.compute hashes in - let payload_round = - match payload_round with None -> round | Some r -> r - in - let payload_hash = - Block_payload.hash - ~predecessor:shell.predecessor - payload_round - non_consensus_operations_hash - in - let contents = - make_contents - ~seed_nonce_hash - ?liquidity_baking_escape_vote - ~payload_hash - ~payload_round - () - in - {baker = pkh; shell; contents} - - (* compatibility only, needed by incremental *) - let contents ?(proof_of_work_nonce = default_proof_of_work_nonce) - ?seed_nonce_hash ?(liquidity_baking_escape_vote = false) ~payload_hash - ~payload_round () = - { - Block_header.proof_of_work_nonce; - seed_nonce_hash; - liquidity_baking_escape_vote; - payload_hash; - payload_round; - } -end - -(********* Genesis creation *************) - -(* Hard-coded context key *) -let protocol_param_key = ["protocol_parameters"] - -let check_constants_consistency constants = - let open Constants in - let {blocks_per_cycle; blocks_per_commitment; blocks_per_stake_snapshot; _} = - constants - in - Error_monad.unless (blocks_per_commitment <= blocks_per_cycle) (fun () -> - failwith - "Inconsistent constants : blocks per commitment must be less than \ - blocks per cycle") - >>=? fun () -> - Error_monad.unless (blocks_per_cycle >= blocks_per_stake_snapshot) (fun () -> - failwith - "Inconsistent constants : blocks per cycle must be superior than \ - blocks per roll snapshot") - -let prepare_main_init_params ?bootstrap_contracts commitments constants - initial_accounts = - let open Tezos_protocol_012_Psithaca_parameters in - let bootstrap_accounts = - List.map - (fun (Account.{pk; pkh; _}, amount) -> - Default_parameters.make_bootstrap_account (pkh, pk, amount)) - initial_accounts - in - let parameters = - Default_parameters.parameters_of_constants - ~bootstrap_accounts - ?bootstrap_contracts - ~commitments - constants - in - let json = Default_parameters.json_of_parameters parameters in - let proto_params = - Data_encoding.Binary.to_bytes_exn Data_encoding.json json - in - Tezos_protocol_environment.Context.( - let empty = Memory_context.empty in - add empty ["version"] (Bytes.of_string "genesis") >>= fun ctxt -> - add ctxt protocol_param_key proto_params) - -let initial_context ?(commitments = []) ?bootstrap_contracts constants header - initial_accounts = - prepare_main_init_params - ?bootstrap_contracts - commitments - constants - initial_accounts - >>= fun ctxt -> - Main.init ctxt header >|= Environment.wrap_tzresult >|=? fun {context; _} -> - context - -let initial_alpha_context ?(commitments = []) constants - (block_header : Block_header.shell_header) initial_accounts = - prepare_main_init_params commitments constants initial_accounts - >>= fun ctxt -> - let level = block_header.level in - let timestamp = block_header.timestamp in - let typecheck (ctxt : Alpha_context.context) (script : Alpha_context.Script.t) - = - let allow_forged_in_storage = - false - (* There should be no forged value in bootstrap contracts. *) - in - Script_ir_translator.parse_script - ctxt - ~legacy:true - ~allow_forged_in_storage - script - >>=? fun (Ex_script parsed_script, ctxt) -> - Script_ir_translator.extract_lazy_storage_diff - ctxt - Optimized - parsed_script.storage_type - parsed_script.storage - ~to_duplicate:Script_ir_translator.no_lazy_storage_id - ~to_update:Script_ir_translator.no_lazy_storage_id - ~temporary:false - >>=? fun (storage, lazy_storage_diff, ctxt) -> - Script_ir_translator.unparse_data - ctxt - Optimized - parsed_script.storage_type - storage - >|=? fun (storage, ctxt) -> - let storage = - Alpha_context.Script.lazy_expr (Micheline.strip_locations storage) - in - (({script with storage}, lazy_storage_diff), ctxt) - in - Main.init_cache ctxt >>= fun ctxt -> - Alpha_context.prepare_first_block ~typecheck ~level ~timestamp ctxt - >|= Environment.wrap_tzresult - -let genesis_with_parameters parameters = - let hash = - Block_hash.of_b58check_exn - "BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU" - in - let fitness = - Fitness_repr.create_without_locked_round - ~level:(Protocol.Raw_level_repr.of_int32_exn 0l) - ~predecessor_round:Round_repr.zero - ~round:Round_repr.zero - |> Fitness_repr.to_raw - in - let shell = - Forge.make_shell - ~level:0l - ~predecessor:hash - ~timestamp:Time.Protocol.epoch - ~fitness - ~operations_hash:Operation_list_list_hash.zero - in - let contents = - Forge.make_contents - ~payload_hash:Block_payload_hash.zero - ~payload_round:Round.zero - ~seed_nonce_hash:None - () - in - let open Tezos_protocol_012_Psithaca_parameters in - let json = Default_parameters.json_of_parameters parameters in - let proto_params = - Data_encoding.Binary.to_bytes_exn Data_encoding.json json - in - Tezos_protocol_environment.Context.( - let empty = Memory_context.empty in - add empty ["version"] (Bytes.of_string "genesis") >>= fun ctxt -> - add ctxt protocol_param_key proto_params) - >>= fun ctxt -> - Main.init ctxt shell >|= Environment.wrap_tzresult >|=? fun {context; _} -> - { - hash; - header = {shell; protocol_data = {contents; signature = Signature.zero}}; - operations = []; - context; - } - -let validate_initial_accounts (initial_accounts : (Account.t * Tez.t) list) - tokens_per_roll = - if initial_accounts = [] then - Stdlib.failwith "Must have one account with a roll to bake" ; - (* Check there is at least one roll *) - Lwt.catch - (fun () -> - List.fold_left_es - (fun acc (_, amount) -> - Environment.wrap_tzresult @@ Tez.( +? ) acc amount >>?= fun acc -> - if acc >= tokens_per_roll then raise Exit else return acc) - Tez.zero - initial_accounts - >>=? fun _ -> - failwith "Insufficient tokens in initial accounts to create one roll") - (function Exit -> return_unit | exc -> raise exc) - -let prepare_initial_context_params ?consensus_threshold ?min_proposal_quorum - ?level ?cost_per_byte ?liquidity_baking_subsidy ?endorsing_reward_per_slot - ?baking_reward_bonus_per_slot ?baking_reward_fixed_portion ?origination_size - ?blocks_per_cycle initial_accounts = - let open Tezos_protocol_012_Psithaca_parameters in - let constants = Default_parameters.constants_test in - let min_proposal_quorum = - Option.value ~default:constants.min_proposal_quorum min_proposal_quorum - in - let cost_per_byte = - Option.value ~default:constants.cost_per_byte cost_per_byte - in - let liquidity_baking_subsidy = - Option.value - ~default:constants.liquidity_baking_subsidy - liquidity_baking_subsidy - in - let endorsing_reward_per_slot = - Option.value - ~default:constants.endorsing_reward_per_slot - endorsing_reward_per_slot - in - let baking_reward_bonus_per_slot = - Option.value - ~default:constants.baking_reward_bonus_per_slot - baking_reward_bonus_per_slot - in - let baking_reward_fixed_portion = - Option.value - ~default:constants.baking_reward_fixed_portion - baking_reward_fixed_portion - in - let origination_size = - Option.value ~default:constants.origination_size origination_size - in - let blocks_per_cycle = - Option.value ~default:constants.blocks_per_cycle blocks_per_cycle - in - (* ?origination_size *) - let consensus_threshold = - Option.value ~default:constants.consensus_threshold consensus_threshold - in - let constants = - { - constants with - endorsing_reward_per_slot; - baking_reward_bonus_per_slot; - baking_reward_fixed_portion; - origination_size; - blocks_per_cycle; - min_proposal_quorum; - cost_per_byte; - liquidity_baking_subsidy; - consensus_threshold; - } - in - (* Check there is at least one roll *) - Lwt.catch - (fun () -> - List.fold_left_es - (fun acc (_, amount) -> - Environment.wrap_tzresult @@ Tez.( +? ) acc amount >>?= fun acc -> - if acc >= constants.tokens_per_roll then raise Exit else return acc) - Tez.zero - initial_accounts - >>=? fun _ -> - failwith "Insufficient tokens in initial accounts to create one roll") - (function Exit -> return_unit | exc -> raise exc) - >>=? fun () -> - check_constants_consistency constants >>=? fun () -> - let hash = - Block_hash.of_b58check_exn - "BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU" - in - let level = Option.value ~default:0l level in - let fitness = - Fitness_repr.create_without_locked_round - ~level:(Protocol.Raw_level_repr.of_int32_exn level) - ~predecessor_round:Round_repr.zero - ~round:Round_repr.zero - |> Fitness_repr.to_raw - in - let shell = - Forge.make_shell - ~level - ~predecessor:hash - ~timestamp:Time.Protocol.epoch - ~fitness - ~operations_hash:Operation_list_list_hash.zero - in - validate_initial_accounts initial_accounts constants.tokens_per_roll - (* Perhaps this could return a new type signifying its name *) - >|=? fun _initial_accounts -> (constants, shell, hash) - -(* if no parameter file is passed we check in the current directory - where the test is run *) -let genesis ?commitments ?consensus_threshold ?min_proposal_quorum - ?bootstrap_contracts ?level ?cost_per_byte ?liquidity_baking_subsidy - ?endorsing_reward_per_slot ?baking_reward_bonus_per_slot - ?baking_reward_fixed_portion ?origination_size ?blocks_per_cycle - (initial_accounts : (Account.t * Tez.t) list) = - prepare_initial_context_params - ?consensus_threshold - ?min_proposal_quorum - ?level - ?cost_per_byte - ?liquidity_baking_subsidy - ?endorsing_reward_per_slot - ?baking_reward_bonus_per_slot - ?baking_reward_fixed_portion - ?origination_size - ?blocks_per_cycle - initial_accounts - >>=? fun (constants, shell, hash) -> - initial_context - ?commitments - ?bootstrap_contracts - constants - shell - initial_accounts - >|=? fun context -> - let contents = - Forge.make_contents - ~payload_hash:Block_payload_hash.zero - ~payload_round:Round.zero - ~seed_nonce_hash:None - () - in - { - hash; - header = {shell; protocol_data = {contents; signature = Signature.zero}}; - operations = []; - context; - } - -let alpha_context ?commitments ?min_proposal_quorum - (initial_accounts : (Account.t * Tez.t) list) = - prepare_initial_context_params ?min_proposal_quorum initial_accounts - >>=? fun (constants, shell, _hash) -> - initial_alpha_context ?commitments constants shell initial_accounts - -(********* Baking *************) - -(* Note that by calling this function without [protocol_data], we force the mode - to be partial construction (by correspondingly calling [begin_construction] - without [protocol_data]). *) -let get_application_vstate (pred : t) (operations : Protocol.operation trace) = - Forge.forge_header pred ~operations >>=? fun header -> - Forge.sign_header header >>=? fun header -> - let open Environment.Error_monad in - Main.begin_application - ~chain_id:Chain_id.zero - ~predecessor_context:pred.context - ~predecessor_fitness:pred.header.shell.fitness - ~predecessor_timestamp:pred.header.shell.timestamp - header - >|= Environment.wrap_tzresult - -let get_construction_vstate ?(policy = By_round 0) ?timestamp - ?(protocol_data = None) (pred : t) = - let open Protocol in - dispatch_policy policy pred >>=? fun (_pkh, _round, expected_timestamp) -> - let timestamp = Option.value ~default:expected_timestamp timestamp in - Main.begin_construction - ~chain_id:Chain_id.zero - ~predecessor_context:pred.context - ~predecessor_timestamp:pred.header.shell.timestamp - ~predecessor_level:pred.header.shell.level - ~predecessor_fitness:pred.header.shell.fitness - ~predecessor:pred.hash - ?protocol_data - ~timestamp - () - >|= Environment.wrap_tzresult - -let apply_with_metadata ?(policy = By_round 0) ~baking_mode header - ?(operations = []) pred = - let open Environment.Error_monad in - ( (match baking_mode with - | Application -> - Main.begin_application - ~chain_id:Chain_id.zero - ~predecessor_context:pred.context - ~predecessor_fitness:pred.header.shell.fitness - ~predecessor_timestamp:pred.header.shell.timestamp - header - >|= Environment.wrap_tzresult - | Baking -> - get_construction_vstate - ~policy - ~protocol_data:(Some header.protocol_data) - (pred : t)) - >>=? fun vstate -> - List.fold_left_es - (fun vstate op -> - apply_operation vstate op >|= Environment.wrap_tzresult - >|=? fun (state, _result) -> state) - vstate - operations - >>=? fun vstate -> - Main.finalize_block vstate (Some header.shell) >|= Environment.wrap_tzresult - >|=? fun (validation, result) -> (validation.context, result) ) - >|=? fun (context, result) -> - let hash = Block_header.hash header in - ({hash; header; operations; context}, result) - -let apply header ?(operations = []) pred = - apply_with_metadata header ~operations pred ~baking_mode:Application - >>=? fun (t, _metadata) -> return t - -let bake_with_metadata ?locked_round ?policy ?timestamp ?operation ?operations - ?payload_round ~baking_mode ?liquidity_baking_escape_vote pred = - let operations = - match (operation, operations) with - | (Some op, Some ops) -> Some (op :: ops) - | (Some op, None) -> Some [op] - | (None, Some ops) -> Some ops - | (None, None) -> None - in - Forge.forge_header - ?payload_round - ?locked_round - ?timestamp - ?policy - ?operations - ?liquidity_baking_escape_vote - pred - >>=? fun header -> - Forge.sign_header header >>=? fun header -> - apply_with_metadata ?policy ~baking_mode header ?operations pred - -let bake ?(baking_mode = Application) ?payload_round ?locked_round ?policy - ?timestamp ?operation ?operations ?liquidity_baking_escape_vote pred = - bake_with_metadata - ?payload_round - ~baking_mode - ?locked_round - ?policy - ?timestamp - ?operation - ?operations - ?liquidity_baking_escape_vote - pred - >>=? fun (t, (_metadata : block_header_metadata)) -> return t - -(********** Cycles ****************) - -(* This function is duplicated from Context to avoid a cyclic dependency *) -let get_constants b = Alpha_services.Constants.all rpc_ctxt b - -let bake_n ?(baking_mode = Application) ?policy ?liquidity_baking_escape_vote n - b = - List.fold_left_es - (fun b _ -> bake ~baking_mode ?policy ?liquidity_baking_escape_vote b) - b - (1 -- n) - -let bake_n_with_all_balance_updates ?(baking_mode = Application) ?policy - ?liquidity_baking_escape_vote n b = - List.fold_left_es - (fun (b, balance_updates_rev) _ -> - bake_with_metadata ~baking_mode ?policy ?liquidity_baking_escape_vote b - >>=? fun (b, metadata) -> - let balance_updates_rev = - List.rev_append metadata.balance_updates balance_updates_rev - in - let balance_updates_rev = - List.fold_left - (fun balance_updates_rev -> - let open Apply_results in - function - | Successful_manager_result (Reveal_result _) - | Successful_manager_result (Delegation_result _) -> - balance_updates_rev - | Successful_manager_result (Set_deposits_limit_result _) -> - balance_updates_rev - | Successful_manager_result - (Transaction_result {balance_updates; _}) - | Successful_manager_result - (Origination_result {balance_updates; _}) - | Successful_manager_result - (Register_global_constant_result {balance_updates; _}) -> - List.rev_append balance_updates balance_updates_rev) - balance_updates_rev - metadata.implicit_operations_results - in - return (b, balance_updates_rev)) - (b, []) - (1 -- n) - >|=? fun (b, balance_updates_rev) -> (b, List.rev balance_updates_rev) - -let bake_n_with_origination_results ?(baking_mode = Application) ?policy n b = - List.fold_left_es - (fun (b, origination_results_rev) _ -> - bake_with_metadata ~baking_mode ?policy b >>=? fun (b, metadata) -> - let origination_results_rev = - List.fold_left - (fun origination_results_rev -> - let open Apply_results in - function - | Successful_manager_result (Reveal_result _) - | Successful_manager_result (Delegation_result _) - | Successful_manager_result (Transaction_result _) - | Successful_manager_result (Register_global_constant_result _) - | Successful_manager_result (Set_deposits_limit_result _) -> - origination_results_rev - | Successful_manager_result (Origination_result x) -> - Origination_result x :: origination_results_rev) - origination_results_rev - metadata.implicit_operations_results - in - return (b, origination_results_rev)) - (b, []) - (1 -- n) - >|=? fun (b, origination_results_rev) -> (b, List.rev origination_results_rev) - -let bake_n_with_liquidity_baking_escape_ema ?(baking_mode = Application) ?policy - ?liquidity_baking_escape_vote n b = - List.fold_left_es - (fun (b, _escape_ema) _ -> - bake_with_metadata ~baking_mode ?policy ?liquidity_baking_escape_vote b - >|=? fun (b, metadata) -> (b, metadata.liquidity_baking_escape_ema)) - (b, 0l) - (1 -- n) - -let bake_until_cycle_end ?policy b = - get_constants b >>=? fun Constants.{parametric = {blocks_per_cycle; _}; _} -> - let current_level = b.header.shell.level in - let current_level = Int32.rem current_level blocks_per_cycle in - let delta = Int32.sub blocks_per_cycle current_level in - bake_n ?policy (Int32.to_int delta) b - -let bake_until_n_cycle_end ?policy n b = - List.fold_left_es (fun b _ -> bake_until_cycle_end ?policy b) b (1 -- n) - -let current_cycle b = - get_constants b >>=? fun Constants.{parametric = {blocks_per_cycle; _}; _} -> - let current_level = b.header.shell.level in - let current_cycle = Int32.div current_level blocks_per_cycle in - let current_cycle = Cycle.add Cycle.root (Int32.to_int current_cycle) in - return current_cycle - -let bake_until_cycle ?policy cycle (b : t) = - let rec loop (b : t) = - current_cycle b >>=? fun current_cycle -> - if Cycle.equal cycle current_cycle then return b - else bake_until_cycle_end ?policy b >>=? fun b -> loop b - in - loop b diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/block.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/block.mli deleted file mode 100644 index 621252da276f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/block.mli +++ /dev/null @@ -1,258 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type t = { - hash : Block_hash.t; - header : Block_header.t; - operations : Operation.packed list; - context : Tezos_protocol_environment.Context.t; (** Resulting context *) -} - -type block = t - -val rpc_ctxt : t Environment.RPC_context.simple - -(** Policies to select the next baker: - - [By_round r] selects the baker at round [r] - - [By_account pkh] selects the first slot for baker [pkh] - - [Excluding pkhs] selects the first baker that doesn't belong to [pkhs] -*) -type baker_policy = - | By_round of int - | By_account of public_key_hash - | Excluding of public_key_hash list - -(** - The default baking functions below is to use (blocks) [Application] mode. - Setting [baking_mode] allows to switch to [Full_construction] mode. -*) -type baking_mode = Application | Baking - -(** Returns (account, round, timestamp) of the next baker given - a policy, defaults to By_round 0. *) -val get_next_baker : - ?policy:baker_policy -> - t -> - (public_key_hash * int * Time.Protocol.t) tzresult Lwt.t - -val get_round : block -> Round.t tzresult - -module Forge : sig - val contents : - ?proof_of_work_nonce:Bytes.t -> - ?seed_nonce_hash:Nonce_hash.t -> - ?liquidity_baking_escape_vote:bool -> - payload_hash:Block_payload_hash.t -> - payload_round:Round.t -> - unit -> - Block_header.contents - - type header - - val classify_operations : packed_operation list -> packed_operation list list - - (** Forges a correct header following the policy. - The header can then be modified and applied with [apply]. *) - val forge_header : - ?locked_round:Alpha_context.Round.t option -> - ?payload_round:Round.t option -> - ?policy:baker_policy -> - ?timestamp:Timestamp.time -> - ?operations:Operation.packed list -> - ?liquidity_baking_escape_vote:bool -> - t -> - header tzresult Lwt.t - - (** Sets uniquely seed_nonce_hash of a header *) - val set_seed_nonce_hash : Nonce_hash.t option -> header -> header - - (** Sets the baker that will sign the header to an arbitrary pkh *) - val set_baker : public_key_hash -> header -> header - - (** Signs the header with the key of the baker configured in the header. - The header can no longer be modified, only applied. *) - val sign_header : header -> Block_header.block_header tzresult Lwt.t -end - -val check_constants_consistency : Constants.parametric -> unit tzresult Lwt.t - -(** [genesis accounts] : generates an initial block with the - given constants [] and initializes [accounts] with their - associated amounts. -*) -val genesis : - ?commitments:Commitment.t list -> - ?consensus_threshold:int -> - ?min_proposal_quorum:int32 -> - ?bootstrap_contracts:Parameters.bootstrap_contract list -> - ?level:int32 -> - ?cost_per_byte:Tez.t -> - ?liquidity_baking_subsidy:Tez.t -> - ?endorsing_reward_per_slot:Tez.t -> - ?baking_reward_bonus_per_slot:Tez.t -> - ?baking_reward_fixed_portion:Tez.t -> - ?origination_size:int -> - ?blocks_per_cycle:int32 -> - (Account.t * Tez.tez) list -> - block tzresult Lwt.t - -val genesis_with_parameters : Parameters.t -> block tzresult Lwt.t - -(** [alpha_context accounts] : instantiates an alpha_context with the - given constants [] and initializes [accounts] with their - associated amounts. -*) -val alpha_context : - ?commitments:Commitment.t list -> - ?min_proposal_quorum:int32 -> - (Account.t * Tez.tez) list -> - Alpha_context.t tzresult Lwt.t - -(** - [get_application_vstate pred operations] constructs a protocol validation - environment for operations in application mode on top of the given block - with the given operations. It's a shortcut for [begin_application] -*) -val get_application_vstate : - t -> Protocol.operation list -> validation_state tzresult Lwt.t - -(** - [get_construction_vstate ?policy ?timestamp ?protocol_data pred] - constructs a protocol validation environment for operations in - construction mode on top of the given block. The mode is - full(baking)/partial(mempool) if [protocol_data] given/absent. It's a - shortcut for [begin_construction] - *) -val get_construction_vstate : - ?policy:baker_policy -> - ?timestamp:Timestamp.time -> - ?protocol_data:block_header_data option -> - block -> - validation_state tzresult Lwt.t - -(** applies a signed header and its operations to a block and - obtains a new block *) -val apply : - Block_header.block_header -> - ?operations:Operation.packed list -> - t -> - t tzresult Lwt.t - -(** - [bake b] returns a block [b'] which has as predecessor block [b]. - Optional parameter [policy] allows to pick the next baker in several ways. - This function bundles together [forge_header], [sign_header] and [apply]. - These functions should be used instead of bake to craft unusual blocks for - testing together with setters for properties of the headers. - For examples see seed.ml or double_baking.ml -*) -val bake : - ?baking_mode:baking_mode -> - ?payload_round:Round.t option -> - ?locked_round:Alpha_context.Round.t option -> - ?policy:baker_policy -> - ?timestamp:Timestamp.time -> - ?operation:Operation.packed -> - ?operations:Operation.packed list -> - ?liquidity_baking_escape_vote:bool -> - t -> - t tzresult Lwt.t - -(** Bakes [n] blocks. *) -val bake_n : - ?baking_mode:baking_mode -> - ?policy:baker_policy -> - ?liquidity_baking_escape_vote:bool -> - int -> - t -> - block tzresult Lwt.t - -(** Version of bake_n that returns a list of all balance updates included - in the metadata of baked blocks. **) -val bake_n_with_all_balance_updates : - ?baking_mode:baking_mode -> - ?policy:baker_policy -> - ?liquidity_baking_escape_vote:bool -> - int -> - t -> - (block * Alpha_context.Receipt.balance_updates) tzresult Lwt.t - -(** Version of bake_n that returns a list of all origination results - in the metadata of baked blocks. **) -val bake_n_with_origination_results : - ?baking_mode:baking_mode -> - ?policy:baker_policy -> - int -> - t -> - (block - * Alpha_context.Kind.origination - Apply_results.successful_manager_operation_result - list) - tzresult - Lwt.t - -(** Version of bake_n that returns the liquidity baking escape EMA after [n] blocks. **) -val bake_n_with_liquidity_baking_escape_ema : - ?baking_mode:baking_mode -> - ?policy:baker_policy -> - ?liquidity_baking_escape_vote:bool -> - int -> - t -> - (block * Alpha_context.Liquidity_baking.escape_ema) tzresult Lwt.t - -val current_cycle : t -> Cycle.t tzresult Lwt.t - -(** Given a block [b] at level [l] bakes enough blocks to complete a cycle, - that is [blocks_per_cycle - (l % blocks_per_cycle)]. *) -val bake_until_cycle_end : ?policy:baker_policy -> t -> t tzresult Lwt.t - -(** Bakes enough blocks to end [n] cycles. *) -val bake_until_n_cycle_end : - ?policy:baker_policy -> int -> t -> t tzresult Lwt.t - -(** Bakes enough blocks to reach the cycle. *) -val bake_until_cycle : ?policy:baker_policy -> Cycle.t -> t -> t tzresult Lwt.t - -(** Common util function to create parameters for [initial_context] function *) -val prepare_initial_context_params : - ?consensus_threshold:int -> - ?min_proposal_quorum:int32 -> - ?level:int32 -> - ?cost_per_byte:Tez.t -> - ?liquidity_baking_subsidy:Tez.t -> - ?endorsing_reward_per_slot:Tez.t -> - ?baking_reward_bonus_per_slot:Tez.t -> - ?baking_reward_fixed_portion:Tez.t -> - ?origination_size:int -> - ?blocks_per_cycle:int32 -> - (Account.t * Tez.t) list -> - ( Constants.parametric * Block_header.shell_header * Block_hash.t, - tztrace ) - result - Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/consensus_helpers.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/consensus_helpers.ml deleted file mode 100644 index ad62da449a9b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/consensus_helpers.ml +++ /dev/null @@ -1,108 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -let test_consensus_operation ?construction_mode ?level ?block_payload_hash ?slot - ?round ~endorsed_block ~error_title ~is_preendorsement ~context ~loc () = - (if is_preendorsement then - Op.preendorsement - ~endorsed_block - ?block_payload_hash - ?level - ?slot - ?round - context - () - >|=? fun op -> Operation.pack op - else - Op.endorsement - ~endorsed_block - ?block_payload_hash - ?level - ?slot - ?round - context - () - >|=? fun op -> Operation.pack op) - >>=? fun op -> - match construction_mode with - | None -> - (* meaning Application mode *) - Block.bake ~operations:[op] endorsed_block >>= fun res -> - Assert.proto_error_with_info ~loc res error_title - | Some (pred, protocol_data) -> - (* meaning partial construction or full construction mode, depending on - [protocol_data] *) - Block.get_construction_vstate ~protocol_data pred >>=? fun vstate -> - apply_operation vstate op >|= Environment.wrap_tzresult >>= fun res -> - Assert.proto_error_with_info ~loc res error_title - -let delegate_of_first_slot b = - let module V = Plugin.RPC.Validators in - Context.get_endorsers b >|=? function - | {V.delegate; slots = s :: _ as slots; _} :: _ -> ((delegate, slots), s) - | _ -> assert false - -let delegate_of_slot slot b = - let module V = Plugin.RPC.Validators in - Context.get_endorsers b >|=? fun endorsers -> - List.find_map - (function - | {V.delegate; slots = s :: _ as slots; _} when Slot.equal s slot -> - Some (delegate, slots) - | _ -> None) - endorsers - |> function - | None -> assert false - | Some d -> d - -let test_consensus_op_for_next ~genesis ~kind ~next = - let dorsement ~endorsed_block ~delegate b = - match kind with - | `Preendorsement -> - Op.preendorsement ~endorsed_block ~delegate b () >|=? Operation.pack - | `Endorsement -> - Op.endorsement ~endorsed_block ~delegate b () >|=? Operation.pack - in - Block.bake genesis >>=? fun b1 -> - (match next with - | `Level -> Block.bake b1 - | `Round -> Block.bake ~policy:(By_round 1) genesis) - >>=? fun b2 -> - Incremental.begin_construction ~mempool_mode:true b1 >>=? fun inc -> - delegate_of_first_slot (B b1) >>=? fun (delegate, slot) -> - dorsement ~endorsed_block:b1 ~delegate (B genesis) >>=? fun operation -> - Incremental.add_operation inc operation >>=? fun inc -> - delegate_of_slot slot (B b2) >>=? fun delegate -> - dorsement ~endorsed_block:b2 ~delegate (B b1) >>=? fun operation -> - Incremental.add_operation inc operation >>= fun res -> - let error_title = - match next with - | `Level -> "Consensus operation for future level" - | `Round -> "Consensus operation for future round" - in - Assert.proto_error_with_info ~loc:__LOC__ res error_title diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/context.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/context.ml deleted file mode 100644 index dbd1724846c1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/context.ml +++ /dev/null @@ -1,368 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type t = B of Block.t | I of Incremental.t - -let branch = function B b -> b.hash | I i -> (Incremental.predecessor i).hash - -let level = function B b -> b.header.shell.level | I i -> Incremental.level i - -let get_level ctxt = - level ctxt |> Raw_level.of_int32 |> Environment.wrap_tzresult - -let rpc_ctxt = - object - method call_proto_service0 - : 'm 'q 'i 'o. - ( ([< RPC_service.meth] as 'm), - Environment.RPC_context.t, - Environment.RPC_context.t, - 'q, - 'i, - 'o ) - RPC_service.t -> - t -> - 'q -> - 'i -> - 'o tzresult Lwt.t = - fun s pr q i -> - match pr with - | B b -> Block.rpc_ctxt#call_proto_service0 s b q i - | I b -> Incremental.rpc_ctxt#call_proto_service0 s b q i - - method call_proto_service1 - : 'm 'a 'q 'i 'o. - ( ([< RPC_service.meth] as 'm), - Environment.RPC_context.t, - Environment.RPC_context.t * 'a, - 'q, - 'i, - 'o ) - RPC_service.t -> - t -> - 'a -> - 'q -> - 'i -> - 'o tzresult Lwt.t = - fun s pr a q i -> - match pr with - | B bl -> Block.rpc_ctxt#call_proto_service1 s bl a q i - | I bl -> Incremental.rpc_ctxt#call_proto_service1 s bl a q i - - method call_proto_service2 - : 'm 'a 'b 'q 'i 'o. - ( ([< RPC_service.meth] as 'm), - Environment.RPC_context.t, - (Environment.RPC_context.t * 'a) * 'b, - 'q, - 'i, - 'o ) - RPC_service.t -> - t -> - 'a -> - 'b -> - 'q -> - 'i -> - 'o tzresult Lwt.t = - fun s pr a b q i -> - match pr with - | B bl -> Block.rpc_ctxt#call_proto_service2 s bl a b q i - | I bl -> Incremental.rpc_ctxt#call_proto_service2 s bl a b q i - - method call_proto_service3 - : 'm 'a 'b 'c 'q 'i 'o. - ( ([< RPC_service.meth] as 'm), - Environment.RPC_context.t, - ((Environment.RPC_context.t * 'a) * 'b) * 'c, - 'q, - 'i, - 'o ) - RPC_service.t -> - t -> - 'a -> - 'b -> - 'c -> - 'q -> - 'i -> - 'o tzresult Lwt.t = - fun s pr a b c q i -> - match pr with - | B bl -> Block.rpc_ctxt#call_proto_service3 s bl a b c q i - | I bl -> Incremental.rpc_ctxt#call_proto_service3 s bl a b c q i - end - -let get_endorsers ctxt = Plugin.RPC.Validators.get rpc_ctxt ctxt - -let get_endorser ctxt = - get_endorsers ctxt >|=? fun endorsers -> - let endorser = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd endorsers in - (endorser.delegate, endorser.slots) - -let get_endorser_n ctxt n = - Plugin.RPC.Validators.get rpc_ctxt ctxt >|=? fun endorsers -> - let endorser = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth endorsers n - in - (endorser.delegate, endorser.slots) - -let get_endorsing_power_for_delegate ctxt ?levels pkh = - Plugin.RPC.Validators.get rpc_ctxt ?levels ctxt >>=? fun endorsers -> - let rec find_slots_for_delegate = function - | [] -> return 0 - | {Plugin.RPC.Validators.delegate; slots; _} :: t -> - if Signature.Public_key_hash.equal delegate pkh then - return (List.length slots) - else find_slots_for_delegate t - in - find_slots_for_delegate endorsers - -let get_voting_power = Delegate_services.voting_power rpc_ctxt - -let get_total_voting_power = Alpha_services.Voting.total_voting_power rpc_ctxt - -let get_bakers ?(filter = fun _x -> true) ctxt = - Plugin.RPC.Baking_rights.get rpc_ctxt ctxt >|=? fun bakers -> - List.filter filter bakers - |> List.map (fun p -> p.Plugin.RPC.Baking_rights.delegate) - -let get_baker ctxt ~round = - get_bakers ~filter:(fun x -> x.round = round) ctxt >>=? fun bakers -> - (* there is only one baker for a given round *) - match bakers with [baker] -> return baker | _ -> assert false - -let get_seed_nonce_hash ctxt = - let header = - match ctxt with B {header; _} -> header | I i -> Incremental.header i - in - match header.protocol_data.contents.seed_nonce_hash with - | None -> failwith "No committed nonce" - | Some hash -> return hash - -let get_seed ctxt = Alpha_services.Seed.get rpc_ctxt ctxt - -let get_constants ctxt = Alpha_services.Constants.all rpc_ctxt ctxt - -let get_baking_reward_fixed_portion ctxt = - get_constants ctxt - >>=? fun {Constants.parametric = {baking_reward_fixed_portion; _}; _} -> - return baking_reward_fixed_portion - -let get_bonus_reward ctxt ~endorsing_power = - get_constants ctxt - >>=? fun { - Constants.parametric = - {baking_reward_bonus_per_slot; consensus_threshold; _}; - _; - } -> - let multiplier = max 0 (endorsing_power - consensus_threshold) in - return Test_tez.(baking_reward_bonus_per_slot *! Int64.of_int multiplier) - -let get_endorsing_reward ctxt ~expected_endorsing_power = - get_constants ctxt - >>=? fun {Constants.parametric = {endorsing_reward_per_slot; _}; _} -> - Lwt.return - (Environment.wrap_tzresult - Tez.(endorsing_reward_per_slot *? Int64.of_int expected_endorsing_power)) - -let get_liquidity_baking_subsidy ctxt = - get_constants ctxt - >>=? fun {Constants.parametric = {liquidity_baking_subsidy; _}; _} -> - return liquidity_baking_subsidy - -let get_liquidity_baking_cpmm_address ctxt = - Alpha_services.Liquidity_baking.get_cpmm_address rpc_ctxt ctxt - -(* Voting *) - -module Vote = struct - let get_ballots ctxt = Alpha_services.Voting.ballots rpc_ctxt ctxt - - let get_ballot_list ctxt = Alpha_services.Voting.ballot_list rpc_ctxt ctxt - - let get_current_period ctxt = - Alpha_services.Voting.current_period rpc_ctxt ctxt - - let get_current_quorum ctxt = - Alpha_services.Voting.current_quorum rpc_ctxt ctxt - - let get_listings ctxt = Alpha_services.Voting.listings rpc_ctxt ctxt - - let get_proposals ctxt = Alpha_services.Voting.proposals rpc_ctxt ctxt - - let get_current_proposal ctxt = - Alpha_services.Voting.current_proposal rpc_ctxt ctxt - - let get_protocol (b : Block.t) = - Tezos_protocol_environment.Context.get_protocol b.context - - let get_participation_ema (b : Block.t) = - Environment.Context.find b.context ["votes"; "participation_ema"] - >|= function - | None -> assert false - | Some bytes -> ok (TzEndian.get_int32 bytes 0) - - let set_participation_ema (b : Block.t) ema = - let bytes = Bytes.make 4 '\000' in - TzEndian.set_int32 bytes 0 ema ; - Environment.Context.add b.context ["votes"; "participation_ema"] bytes - >|= fun context -> {b with context} -end - -module Contract = struct - let pp = Alpha_context.Contract.pp - - let equal a b = Alpha_context.Contract.compare a b = 0 - - let pkh c = - Alpha_context.Contract.is_implicit c |> function - | Some p -> return p - | None -> failwith "pkh: only for implicit contracts" - - let balance ctxt contract = - Alpha_services.Contract.balance rpc_ctxt ctxt contract - - let counter ctxt contract = - match Contract.is_implicit contract with - | None -> invalid_arg "Helpers.Context.counter" - | Some mgr -> Alpha_services.Contract.counter rpc_ctxt ctxt mgr - - let manager _ contract = - match Contract.is_implicit contract with - | None -> invalid_arg "Helpers.Context.manager" - | Some pkh -> Account.find pkh - - let is_manager_key_revealed ctxt contract = - match Contract.is_implicit contract with - | None -> invalid_arg "Helpers.Context.is_manager_key_revealed" - | Some mgr -> - Alpha_services.Contract.manager_key rpc_ctxt ctxt mgr >|=? fun res -> - res <> None - - let delegate ctxt contract = - Alpha_services.Contract.delegate rpc_ctxt ctxt contract - - let delegate_opt ctxt contract = - Alpha_services.Contract.delegate_opt rpc_ctxt ctxt contract - - let storage ctxt contract = - Alpha_services.Contract.storage rpc_ctxt ctxt contract - - let script ctxt contract = - Alpha_services.Contract.script rpc_ctxt ctxt contract - >>=? fun {code; storage = _} -> - match Data_encoding.force_decode code with - | Some v -> return v - | None -> invalid_arg "Cannot force lazy script" - - let script_hash ctxt contract = - script ctxt contract >>=? fun script -> - let bytes = Data_encoding.Binary.to_bytes_exn Script.expr_encoding script in - return @@ Script_expr_hash.hash_bytes [bytes] -end - -module Delegate = struct - type info = Delegate_services.info = { - full_balance : Tez.t; - current_frozen_deposits : Tez.t; - frozen_deposits : Tez.t; - staking_balance : Tez.t; - frozen_deposits_limit : Tez.t option; - delegated_contracts : Alpha_context.Contract.t list; - delegated_balance : Tez.t; - deactivated : bool; - grace_period : Cycle.t; - voting_power : int32; - } - - let info ctxt pkh = Delegate_services.info rpc_ctxt ctxt pkh - - let full_balance ctxt pkh = Delegate_services.full_balance rpc_ctxt ctxt pkh - - let current_frozen_deposits ctxt pkh = - Delegate_services.current_frozen_deposits rpc_ctxt ctxt pkh - - let initial_frozen_deposits ctxt pkh = - Delegate_services.frozen_deposits rpc_ctxt ctxt pkh - - let staking_balance ctxt pkh = - Delegate_services.staking_balance rpc_ctxt ctxt pkh - - let frozen_deposits_limit ctxt pkh = - Delegate_services.frozen_deposits_limit rpc_ctxt ctxt pkh - - let deactivated ctxt pkh = Delegate_services.deactivated rpc_ctxt ctxt pkh - - let participation ctxt pkh = Delegate_services.participation rpc_ctxt ctxt pkh -end - -let init ?rng_state ?commitments ?(initial_balances = []) ?consensus_threshold - ?min_proposal_quorum ?bootstrap_contracts ?level ?cost_per_byte - ?liquidity_baking_subsidy ?endorsing_reward_per_slot - ?baking_reward_bonus_per_slot ?baking_reward_fixed_portion ?origination_size - ?blocks_per_cycle n = - let accounts = Account.generate_accounts ?rng_state ~initial_balances n in - let contracts = - List.map - (fun (a, _) -> Alpha_context.Contract.implicit_contract Account.(a.pkh)) - accounts - in - Block.genesis - ?commitments - ?consensus_threshold - ?min_proposal_quorum - ?bootstrap_contracts - ?level - ?cost_per_byte - ?liquidity_baking_subsidy - ?endorsing_reward_per_slot - ?baking_reward_bonus_per_slot - ?baking_reward_fixed_portion - ?origination_size - ?blocks_per_cycle - accounts - >|=? fun blk -> (blk, contracts) - -let init_with_constants constants n = - let accounts = Account.generate_accounts n in - let contracts = - List.map - (fun (a, _) -> Alpha_context.Contract.implicit_contract Account.(a.pkh)) - accounts - in - let open Tezos_protocol_012_Psithaca_parameters in - let bootstrap_accounts = - List.map - (fun (acc, tez) -> - Default_parameters.make_bootstrap_account - (acc.Account.pkh, acc.Account.pk, tez)) - accounts - in - let parameters = - Default_parameters.parameters_of_constants ~bootstrap_accounts constants - in - Block.genesis_with_parameters parameters >|=? fun blk -> (blk, contracts) diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/context.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/context.mli deleted file mode 100644 index 5a61a8258ee0..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/context.mli +++ /dev/null @@ -1,188 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Environment - -type t = B of Block.t | I of Incremental.t - -val branch : t -> Block_hash.t - -val get_level : t -> Raw_level.t tzresult - -val get_endorsers : t -> Plugin.RPC.Validators.t list tzresult Lwt.t - -val get_endorser : t -> (public_key_hash * Slot.t list) tzresult Lwt.t - -val get_endorser_n : t -> int -> (public_key_hash * Slot.t list) tzresult Lwt.t - -val get_endorsing_power_for_delegate : - t -> ?levels:Raw_level.t list -> public_key_hash -> int tzresult Lwt.t - -val get_voting_power : - t -> public_key_hash -> int32 Environment.Error_monad.shell_tzresult Lwt.t - -val get_total_voting_power : - t -> int32 Environment.Error_monad.shell_tzresult Lwt.t - -val get_bakers : - ?filter:(Plugin.RPC.Baking_rights.t -> bool) -> - t -> - public_key_hash list tzresult Lwt.t - -val get_baker : t -> round:int -> public_key_hash tzresult Lwt.t - -val get_seed_nonce_hash : t -> Nonce_hash.t tzresult Lwt.t - -(** Returns the seed of the cycle to which the block belongs to. *) -val get_seed : t -> Seed.seed tzresult Lwt.t - -(** Returns all the constants of the protocol *) -val get_constants : t -> Constants.t tzresult Lwt.t - -val get_baking_reward_fixed_portion : t -> Tez.t tzresult Lwt.t - -val get_bonus_reward : t -> endorsing_power:int -> Tez.t tzresult Lwt.t - -val get_endorsing_reward : - t -> expected_endorsing_power:int -> Tez.t tzresult Lwt.t - -val get_liquidity_baking_subsidy : t -> Tez.t tzresult Lwt.t - -val get_liquidity_baking_cpmm_address : t -> Contract.t tzresult Lwt.t - -module Vote : sig - val get_ballots : t -> Vote.ballots tzresult Lwt.t - - val get_ballot_list : - t -> (Signature.Public_key_hash.t * Vote.ballot) list tzresult Lwt.t - - val get_current_period : t -> Voting_period.info tzresult Lwt.t - - val get_current_quorum : t -> int32 tzresult Lwt.t - - val get_participation_ema : Block.t -> int32 tzresult Lwt.t - - val get_listings : - t -> (Signature.Public_key_hash.t * int32) list tzresult Lwt.t - - val get_proposals : t -> int32 Protocol_hash.Map.t tzresult Lwt.t - - val get_current_proposal : t -> Protocol_hash.t option tzresult Lwt.t - - val get_protocol : Block.t -> Protocol_hash.t Lwt.t - - val set_participation_ema : Block.t -> int32 -> Block.t Lwt.t -end - -module Contract : sig - val pp : Format.formatter -> Contract.t -> unit - - val equal : Contract.t -> Contract.t -> bool - - val pkh : Contract.t -> public_key_hash tzresult Lwt.t - - (** Returns the balance of a contract, by default the main balance. - If the contract is implicit the frozen balances are available too: - deposit, fees or rewards. *) - val balance : t -> Contract.t -> Tez.t tzresult Lwt.t - - val counter : t -> Contract.t -> Z.t tzresult Lwt.t - - val manager : t -> Contract.t -> Account.t tzresult Lwt.t - - val is_manager_key_revealed : t -> Contract.t -> bool tzresult Lwt.t - - val delegate : t -> Contract.t -> public_key_hash tzresult Lwt.t - - val delegate_opt : t -> Contract.t -> public_key_hash option tzresult Lwt.t - - val storage : t -> Contract.t -> Script.expr tzresult Lwt.t - - val script : t -> Contract.t -> Script.expr tzresult Lwt.t - - val script_hash : t -> Contract.t -> Script_expr_hash.t tzresult Lwt.t -end - -module Delegate : sig - type info = Delegate_services.info = { - full_balance : Tez.t; - current_frozen_deposits : Tez.t; - frozen_deposits : Tez.t; - staking_balance : Tez.t; - frozen_deposits_limit : Tez.t option; - delegated_contracts : Alpha_context.Contract.t list; - delegated_balance : Tez.t; - deactivated : bool; - grace_period : Cycle.t; - voting_power : int32; - } - - val info : t -> public_key_hash -> Delegate_services.info tzresult Lwt.t - - val full_balance : t -> public_key_hash -> Tez.t tzresult Lwt.t - - val current_frozen_deposits : t -> public_key_hash -> Tez.t tzresult Lwt.t - - (** calls the RPC [frozen_deposits]: we're using a different name to - be more easily distinguishable from [current_frozen_deposits] *) - val initial_frozen_deposits : t -> public_key_hash -> Tez.t tzresult Lwt.t - - val staking_balance : t -> public_key_hash -> Tez.t tzresult Lwt.t - - val frozen_deposits_limit : - t -> public_key_hash -> Tez.t option tzresult Lwt.t - - val deactivated : t -> public_key_hash -> bool tzresult Lwt.t - - val participation : - t -> public_key_hash -> Delegate.participation_info tzresult Lwt.t -end - -(** [init n] : returns an initial block with [n] initialized accounts - and the associated implicit contracts *) -val init : - ?rng_state:Random.State.t -> - ?commitments:Commitment.t list -> - ?initial_balances:int64 list -> - ?consensus_threshold:int -> - ?min_proposal_quorum:int32 -> - ?bootstrap_contracts:Parameters.bootstrap_contract list -> - ?level:int32 -> - ?cost_per_byte:Tez.t -> - ?liquidity_baking_subsidy:Tez.t -> - ?endorsing_reward_per_slot:Tez.t -> - ?baking_reward_bonus_per_slot:Tez.t -> - ?baking_reward_fixed_portion:Tez.t -> - ?origination_size:int -> - ?blocks_per_cycle:int32 -> - int -> - (Block.t * Alpha_context.Contract.t list) tzresult Lwt.t - -val init_with_constants : - Constants.parametric -> - int -> - (Block.t * Alpha_context.Contract.t list) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/contract_helpers.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/contract_helpers.ml deleted file mode 100644 index 6935d7ade5b8..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/contract_helpers.ml +++ /dev/null @@ -1,101 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Error_monad_operators - -(** Initializes 2 addresses to do only operations plus one that will be - used to bake. *) -let init () = - Context.init ~consensus_threshold:0 3 >|=? fun (b, contracts) -> - let (src0, src1, src2) = - match contracts with - | src0 :: src1 :: src2 :: _ -> (src0, src1, src2) - | _ -> assert false - in - let baker = - match Alpha_context.Contract.is_implicit src0 with - | Some v -> v - | None -> assert false - in - (b, baker, src1, src2) - -(** Returns a block in which the contract is originated. *) -let originate_contract file storage src b baker = - let load_file f = - let ic = open_in f in - let res = really_input_string ic (in_channel_length ic) in - close_in ic ; - res - in - let contract_string = load_file file in - let code = Expr.toplevel_from_string contract_string in - let storage = Expr.from_string storage in - let script = - Alpha_context.Script.{code = lazy_expr code; storage = lazy_expr storage} - in - Op.origination (B b) src ~fee:(Test_tez.of_int 10) ~script - >>=? fun (operation, dst) -> - Incremental.begin_construction ~policy:Block.(By_account baker) b - >>=? fun incr -> - Incremental.add_operation incr operation >>=? fun incr -> - Incremental.finalize_block incr >|=? fun b -> (dst, b) - -let default_source = Contract.implicit_contract Signature.Public_key_hash.zero - -let default_step_constants = - Script_interpreter. - { - source = default_source; - payer = default_source; - self = default_source; - amount = Tez.zero; - chain_id = Chain_id.zero; - now = Script_timestamp.of_zint Z.zero; - level = Script_int.zero_n; - } - -(** Helper function that parses and types a script, its initial storage and - parameters from strings. It then executes the typed script with the storage - and parameter and returns the result. *) -let run_script ctx ?(step_constants = default_step_constants) contract - ?(entrypoint = "default") ~storage ~parameter () = - let contract_expr = Expr.from_string contract in - let storage_expr = Expr.from_string storage in - let parameter_expr = Expr.from_string parameter in - let script = - Script.{code = lazy_expr contract_expr; storage = lazy_expr storage_expr} - in - Script_interpreter.execute - ctx - Readable - step_constants - ~script - ~cached_script:None - ~entrypoint - ~parameter:parameter_expr - ~internal:false - >>=?? fun res -> return res diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/cpmm_logic.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/cpmm_logic.ml deleted file mode 100644 index a1d4d8027c58..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/cpmm_logic.ml +++ /dev/null @@ -1,102 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -(** This is a simulation of the CPMM contract, as implemented in mligo - in [src/proto_alpha/lib_protocol/contracts/cpmm.mligo]. The - interested reader should look for comments in this file to gain a - better understanding of the contract logic. *) -module Simulate_raw = struct - let mutez_to_natural t = Z.of_int64 (Tez.to_mutez t) - - let natural_to_mutez n = Tez.of_mutez_exn (Z.to_int64 n) - - let addLiquidity ~tokenPool ~xtzPool ~lqtTotal ~amount = - let xtzPool = mutez_to_natural xtzPool in - let nat_amount = mutez_to_natural amount in - let lqt_minted = Z.(nat_amount * lqtTotal / xtzPool) in - let tokens_deposited = Z.(cdiv (nat_amount * tokenPool) xtzPool) in - (lqt_minted, tokens_deposited) - - let removeLiquidity ~tokenPool ~xtzPool ~lqtTotal ~lqtBurned = - let xtz_withdrawn = - natural_to_mutez Z.(lqtBurned * mutez_to_natural xtzPool / lqtTotal) - in - let tokens_withdrawn = Z.(lqtBurned * tokenPool / lqtTotal) in - (xtz_withdrawn, tokens_withdrawn) - - let tokenToXtz ~tokenPool ~xtzPool ~tokensSold = - let fee = Z.of_int 999 in - let xtz_bought_nat = - Z.( - tokensSold * fee * mutez_to_natural xtzPool - / ((tokenPool * of_int 1000) + (tokensSold * fee))) - in - let bought = Z.(xtz_bought_nat * of_int 999 / of_int 1000) in - (natural_to_mutez bought, xtz_bought_nat) - - let xtzToToken ~tokenPool ~xtzPool ~amount = - let fee = Z.of_int 999 in - let xtzPool = mutez_to_natural xtzPool in - let nat_amount = mutez_to_natural amount in - let amount_net_burn = Z.(nat_amount * Z.of_int 999 / Z.of_int 1000) in - let tokens_bought = - Z.( - amount_net_burn * fee * tokenPool - / ((xtzPool * Z.of_int 1000) + (amount_net_burn * fee))) - in - (tokens_bought, amount_net_burn) - - let tokenToToken ~tokenPool ~xtzPool ~tokensSold = - let fee = Z.of_int 999 in - let xtz_bought_nat = - Z.( - tokensSold * fee * mutez_to_natural xtzPool - / ((tokenPool * of_int 1000) + (tokensSold * fee))) - in - let xtz_bought_net_burn = Z.(xtz_bought_nat * of_int 999 / of_int 1000) in - (natural_to_mutez xtz_bought_net_burn, xtz_bought_nat) -end - -module Simulate = struct - open Cpmm_repr.Storage - - let addLiquidity {tokenPool; xtzPool; lqtTotal; _} amount = - Simulate_raw.addLiquidity ~xtzPool ~tokenPool ~lqtTotal ~amount - - let removeLiquidity {tokenPool; xtzPool; lqtTotal; _} lqtBurned = - Simulate_raw.removeLiquidity ~tokenPool ~xtzPool ~lqtTotal ~lqtBurned - - let tokenToXtz {tokenPool; xtzPool; _} tokensSold = - Simulate_raw.tokenToXtz ~tokenPool ~xtzPool ~tokensSold - - let xtzToToken {tokenPool; xtzPool; _} amount = - Simulate_raw.xtzToToken ~tokenPool ~xtzPool ~amount - - let tokenToToken {tokenPool; xtzPool; _} tokensSold = - Simulate_raw.tokenToToken ~tokenPool ~xtzPool ~tokensSold -end diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/cpmm_repr.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/cpmm_repr.ml deleted file mode 100644 index 5ec22503b0eb..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/cpmm_repr.ml +++ /dev/null @@ -1,384 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Expr_common - -(* // ============================================================================= - * // Storage - * // ============================================================================= *) - -module Storage = struct - type t = { - tokenPool : Z.t; - xtzPool : Tez.t; - lqtTotal : Z.t; - tokenAddress : Contract.t; - lqtAddress : Contract.t; - } - - let zero : t = - { - tokenPool = Z.zero; - xtzPool = Tez.zero; - lqtTotal = Z.zero; - tokenAddress = - Contract.originated_contract - (Contract.initial_origination_nonce Operation_hash.zero); - lqtAddress = - Contract.originated_contract - (Contract.initial_origination_nonce Operation_hash.zero); - } - - let to_string {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} = - Format.asprintf - "{tokenPool : %a; xtzPool : %s; lqtTotal : %a; tokenAddress : %s; \ - lqtAddress : %s;}" - Z.pp_print - tokenPool - (Int64.to_string @@ Tez.to_mutez xtzPool) - Z.pp_print - lqtTotal - (Contract.to_b58check tokenAddress) - (Contract.to_b58check lqtAddress) - - let pp fmt s = Format.fprintf fmt "%s" (to_string s) - - let eq s s' = s = s' - - let to_expr : - loc:'a -> - t -> - ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = - fun ~loc {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} -> - comb - ~loc - [ - int ~loc tokenPool; - mutez ~loc xtzPool; - int ~loc lqtTotal; - address_string ~loc tokenAddress; - address_string ~loc lqtAddress; - ] - - let to_michelson_string e = - let e = to_expr ~loc:0 e in - Format.asprintf - "%a" - Michelson_v1_printer.print_expr - (Micheline.strip_locations e) - - type exn += Invalid_storage_expr of string - - (** Note: parses a storage unparsed in readable mode (as - e.g. returned by [Alpha_services.Contract.storage]), so that - contracts are represented by strings. *) - let of_expr_exn : - ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node -> t = - function - | Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [ - Tezos_micheline.Micheline.Int (_, tokenPool); - Tezos_micheline.Micheline.Int (_, xtzPool); - Tezos_micheline.Micheline.Int (_, lqtTotal); - Tezos_micheline.Micheline.String (_, tokenAddress); - Tezos_micheline.Micheline.String (_, lqtAddress); - ], - [] ) -> - let xtzPool = Tez.of_mutez_exn (Z.to_int64 xtzPool) in - let tokenAddress = address_of_string_exn tokenAddress in - let lqtAddress = address_of_string_exn lqtAddress in - {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} - | e -> - let canonical = Micheline.strip_locations e in - let msg = - Format.asprintf - "Not a valid CPMM storage: %s /// %a" - (try - Michelson_v1_printer.micheline_string_of_expression - ~zero_loc:true - canonical - with Z.Overflow -> - "Cannot represent as micheline due to overflowing Z -> int") - Michelson_v1_printer.print_expr - canonical - in - raise (Invalid_storage_expr msg) - - let get (ctxt : Context.t) ~(contract : Contract.t) : t tzresult Lwt.t = - Context.Contract.storage ctxt contract >|=? Micheline.root >|=? of_expr_exn - - let of_tuple (tokenPool, xtzPool, lqtTotal, tokenAddress, lqtAddress) = - {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} - - let to_tuple {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} = - (tokenPool, xtzPool, lqtTotal, tokenAddress, lqtAddress) - - let valid {tokenPool; xtzPool; lqtTotal; _} = - tokenPool > Z.zero && lqtTotal > Z.zero && Tez.(xtzPool > Tez.zero) -end - -module Parameter = struct - (* // ============================================================================= - * // Entrypoints - * // ============================================================================= *) - - type add_liquidity = { - owner : Contract.t; - minLqtMinted : Z.t; - maxTokensDeposited : Z.t; - deadline : Script_timestamp.t; - } - - type remove_liquidity = { - to_ : Contract.t; - (* recipient of the liquidity redemption *) - lqtBurned : Z.t; - (* amount of lqt owned by sender to burn *) - minXtzWithdrawn : Tez.t; - (* minimum amount of Tez.t to withdraw *) - minTokensWithdrawn : Z.t; - (* minimum amount of tokens to withdraw *) - deadline : Script_timestamp.t; - (* the time before which the request must be completed *) - } - - type token_to_token = { - outputDexterContract : Contract.t; - minTokensBought : Z.t; - to_ : Contract.t; - tokensSold : Z.t; - deadline : Script_timestamp.t; - } - - type token_to_xtz = { - to_ : Contract.t; - tokensSold : Z.t; - minXtzBought : Tez.t; - deadline : Script_timestamp.t; - } - - type xtz_to_token = { - to_ : Contract.t; - minTokensBought : Z.t; - deadline : Script_timestamp.t; - } - - type t = - | AddLiquidity of add_liquidity - | Default of unit - | RemoveLiquidity of remove_liquidity - | TokenToToken of token_to_token - | TokenToXtz of token_to_xtz - | XtzToToken of xtz_to_token - - let addLiquidity p = AddLiquidity p - - let default p = Default p - - let removeLiquidity p = RemoveLiquidity p - - let tokenToToken p = TokenToToken p - - let tokenToXtz p = TokenToXtz p - - let xtzToToken p = XtzToToken p - - let add_liquidity_to_string : add_liquidity -> string = - fun {owner; minLqtMinted; maxTokensDeposited; deadline} -> - Format.asprintf - "{owner : %s; minLqtMinted : %a; maxTokensDeposited : %a; deadline : %s }" - (Contract.to_b58check owner) - Z.pp_print - minLqtMinted - Z.pp_print - maxTokensDeposited - (Script_timestamp.to_string deadline) - - let remove_liquidity_to_string : remove_liquidity -> string = - fun {to_; lqtBurned; minXtzWithdrawn; minTokensWithdrawn; deadline} -> - Format.asprintf - "{owner : %s; lqtBurned : %a; minXtzWithdrawn : %s; minTokensWithdrawn : \ - %a; deadline : %s }" - (Contract.to_b58check to_) - Z.pp_print - lqtBurned - (Int64.to_string @@ Tez.to_mutez minXtzWithdrawn) - Z.pp_print - minTokensWithdrawn - (Script_timestamp.to_string deadline) - - let token_to_token_to_string : token_to_token -> string = - fun {outputDexterContract; minTokensBought; to_; tokensSold; deadline} -> - Format.asprintf - "{outputDexterContract : %s; minTokensBought : %a; to_ : %s; tokensSold \ - : %a; deadline : %s }" - (Contract.to_b58check outputDexterContract) - Z.pp_print - minTokensBought - (Contract.to_b58check to_) - Z.pp_print - tokensSold - (Script_timestamp.to_string deadline) - - let token_to_xtz_to_string : token_to_xtz -> string = - fun {to_; tokensSold; minXtzBought; deadline} -> - Format.asprintf - "{to_ : %s; tokensSold : %a; minXtzBought : %s; deadline : %s }" - (Contract.to_b58check to_) - Z.pp_print - tokensSold - (Int64.to_string @@ Tez.to_mutez minXtzBought) - (Script_timestamp.to_string deadline) - - let xtz_to_token_to_string : xtz_to_token -> string = - fun {to_; minTokensBought; deadline} -> - Format.asprintf - "{to_ : %s; minTokensBought : %a; deadline : %s }" - (Contract.to_b58check to_) - Z.pp_print - minTokensBought - (Script_timestamp.to_string deadline) - - let to_string : t -> string = function - | AddLiquidity p -> - Format.asprintf "AddLiquidity %s" (add_liquidity_to_string p) - | Default () -> "Default ()" - | RemoveLiquidity p -> - Format.asprintf "RemoveLiquidity %s" (remove_liquidity_to_string p) - | TokenToToken p -> - Format.asprintf "TokenToToken (%s)" (token_to_token_to_string p) - | TokenToXtz p -> - Format.asprintf "TokenToXtz (%s)" (token_to_xtz_to_string p) - | XtzToToken p -> - Format.asprintf "XtzToToken (%s)" (xtz_to_token_to_string p) - - let entrypoint_of_parameter : t -> string = function - | AddLiquidity _ -> "addLiquidity" - | Default _ -> "default" - | RemoveLiquidity _ -> "removeLiquidity" - | TokenToToken _ -> "tokenToToken" - | TokenToXtz _ -> "tokenToXtz" - | XtzToToken _ -> "xtzToToken" - - let pp fmt s = Format.fprintf fmt "%s" (to_string s) - - let eq s s' = s = s' - - let to_expr_rooted : - loc:'a -> - t -> - ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = - fun ~loc -> function - | AddLiquidity {owner; minLqtMinted; maxTokensDeposited; deadline} -> - comb - ~loc - [ - address_string ~loc owner; - int ~loc minLqtMinted; - int ~loc maxTokensDeposited; - timestamp ~loc deadline; - ] - | Default () -> unit ~loc - | RemoveLiquidity - {to_; lqtBurned; minXtzWithdrawn; minTokensWithdrawn; deadline} -> - comb - ~loc - [ - address_string ~loc to_; - int ~loc lqtBurned; - mutez ~loc minXtzWithdrawn; - int ~loc minTokensWithdrawn; - timestamp ~loc deadline; - ] - | TokenToToken - {outputDexterContract; minTokensBought; to_; tokensSold; deadline} -> - comb - ~loc - [ - address_string ~loc outputDexterContract; - int ~loc minTokensBought; - address_string ~loc to_; - int ~loc tokensSold; - timestamp ~loc deadline; - ] - | TokenToXtz {to_; tokensSold; minXtzBought; deadline} -> - comb - ~loc - [ - address_string ~loc to_; - int ~loc tokensSold; - mutez ~loc minXtzBought; - timestamp ~loc deadline; - ] - | XtzToToken {to_; minTokensBought; deadline} -> - comb - ~loc - [ - address_string ~loc to_; - int ~loc minTokensBought; - timestamp ~loc deadline; - ] - - let to_expr : - loc:'a -> - t -> - ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = - fun ~loc p -> - let rooted = to_expr_rooted ~loc p in - match p with - | AddLiquidity _ -> left ~loc @@ left ~loc @@ left ~loc rooted - | Default () -> left ~loc @@ left ~loc @@ right ~loc rooted - | RemoveLiquidity _ -> left ~loc @@ right ~loc @@ left ~loc rooted - | TokenToToken _ -> left ~loc @@ right ~loc @@ right ~loc rooted - | TokenToXtz _ -> right ~loc @@ left ~loc rooted - | XtzToToken _ -> right ~loc @@ right ~loc rooted - - let to_michelson_string e = - let e = to_expr ~loc:0 e in - Format.asprintf - "%a" - Michelson_v1_printer.print_expr - (Micheline.strip_locations e) -end - -let transaction (ctxt : Context.t) ~(contract : Contract.t) ~(src : Contract.t) - ?(amount = Tez.zero) (parameters : Parameter.t) = - let entrypoint = Parameter.entrypoint_of_parameter parameters in - let rooted_param_lazy = - parameters - |> Parameter.to_expr_rooted ~loc:0 - |> Micheline.strip_locations |> Alpha_context.Script.lazy_expr - in - Op.transaction - ctxt - src - contract - amount - ~entrypoint - ~parameters:rooted_param_lazy diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/dune b/src/proto_012_Psithaca/lib_protocol/test/helpers/dune deleted file mode 100644 index ce08a5f18a55..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/dune +++ /dev/null @@ -1,24 +0,0 @@ -(library - (name tezos_012_Psithaca_test_helpers) - (instrumentation (backend bisect_ppx)) - (public_name tezos-012-Psithaca-test-helpers) - (libraries alcotest-lwt - qcheck-alcotest - tezos-test-helpers - tezos-base - tezos-micheline - tezos-stdlib-unix - tezos-shell-services - tezos-protocol-environment - tezos-protocol-012-Psithaca - tezos-protocol-012-Psithaca-parameters - tezos-client-012-Psithaca - tezos-protocol-plugin-012-Psithaca) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_micheline - -open Tezos_stdlib_unix - -open Tezos_protocol_012_Psithaca - -open Tezos_client_012_Psithaca - -open Tezos_protocol_plugin_012_Psithaca - -open Tezos_protocol_environment_012_Psithaca - -open Tezos_shell_services))) diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/dune-project b/src/proto_012_Psithaca/lib_protocol/test/helpers/dune-project deleted file mode 100644 index 8d36470afaad..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/dune-project +++ /dev/null @@ -1,3 +0,0 @@ -(lang dune 2.9) -(formatting (enabled_for ocaml)) -(name tezos-alpha-test-helpers) diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/error_monad_operators.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/error_monad_operators.ml deleted file mode 100644 index 61eb43e4020a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/error_monad_operators.ml +++ /dev/null @@ -1,11 +0,0 @@ -open Protocol - -let ( >>=?? ) x y = - x >>= function - | Ok s -> y s - | Error err -> Lwt.return @@ Error (Environment.wrap_tztrace err) - -let ( >>??= ) x y = - match x with - | Ok s -> y s - | Error err -> Lwt.return @@ Error (Environment.wrap_tztrace err) diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/expr.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/expr.ml deleted file mode 100644 index 37074c20b00e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/expr.ml +++ /dev/null @@ -1,50 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -exception Expression_from_string - -(** Parse a Michelson expression from string, raising an exception on error. *) -let from_string ?(check_micheline_indentation = false) str : Script.expr = - let (ast, errs) = - Michelson_v1_parser.parse_expression ~check:check_micheline_indentation str - in - (match errs with - | [] -> () - | lst -> - Format.printf "expr_from_string: %a\n" Error_monad.pp_print_trace lst ; - raise Expression_from_string) ; - ast.expanded - -(** Parses a Michelson contract from string, raising an exception on error. *) -let toplevel_from_string ?(check_micheline_indentation = false) str = - let (ast, errs) = - Michelson_v1_parser.parse_toplevel ~check:check_micheline_indentation str - in - match errs with [] -> ast.expanded | _ -> Stdlib.failwith "parse toplevel" - -let to_string c = Format.asprintf "%a" Michelson_v1_printer.print_expr c diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/expr_common.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/expr_common.ml deleted file mode 100644 index 1dd79eeba539..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/expr_common.ml +++ /dev/null @@ -1,82 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -(* From OCaml values to Micheline expressions *) - -let seq ~loc l = Tezos_micheline.Micheline.Seq (loc, l) - -let pair ~loc a b = - Tezos_micheline.Micheline.Prim (loc, Script.D_Pair, [a; b], []) - -let comb ~loc es = Tezos_micheline.Micheline.Prim (loc, Script.D_Pair, es, []) - -let none ~loc () = Tezos_micheline.Micheline.Prim (loc, Script.D_None, [], []) - -let some ~loc a = Tezos_micheline.Micheline.Prim (loc, Script.D_Some, [a], []) - -let left ~loc a = Tezos_micheline.Micheline.Prim (loc, Script.D_Left, [a], []) - -let right ~loc b = Tezos_micheline.Micheline.Prim (loc, Script.D_Right, [b], []) - -let unit ~loc = Tezos_micheline.Micheline.Prim (loc, Script.D_Unit, [], []) - -let int ~loc i = Tezos_micheline.Micheline.Int (loc, i) - -let bytes ~loc s = Tezos_micheline.Micheline.Bytes (loc, s) - -let string ~loc s = Tezos_micheline.Micheline.String (loc, s) - -let mutez ~loc m = int ~loc (Z.of_int64 (Tez.to_mutez m)) - -(* Translate a timestamp to a Micheline expression in optimized - form *) -let timestamp ~loc ts = int ~loc (Script_timestamp.to_zint ts) - -let address ~loc adr = - bytes ~loc @@ Data_encoding.Binary.to_bytes_exn Contract.encoding adr - -let address_string ~loc adr = string ~loc @@ Contract.to_b58check adr - -let big_map_id ~loc id = int ~loc @@ Big_map.Id.unparse_to_z id - -(* From Micheline expressions to OCaml values *) - -let timestamp_of_zint zint = Script_timestamp.of_zint zint - -let public_key_of_bytes_exn b = - Data_encoding.Binary.of_bytes_exn Signature.Public_key.encoding b - -let address_of_bytes_exn b = - Data_encoding.Binary.of_bytes_exn Contract.encoding b - -type exn += Invalid_address_expr of string - -let address_of_string_exn s = - match Contract.of_b58check s with - | Ok c -> c - | Error _ -> raise @@ Invalid_address_expr s diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/incremental.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/incremental.ml deleted file mode 100644 index ea9c124bed9f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/incremental.ml +++ /dev/null @@ -1,224 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -module Proto_Nonce = Nonce (* Renamed otherwise is masked by Alpha_context *) - -open Alpha_context - -type t = { - predecessor : Block.t; - state : validation_state; - rev_operations : Operation.packed list; - rev_tickets : operation_receipt list; - header : Block_header.t; - delegate : Account.t; -} - -type incremental = t - -let predecessor {predecessor; _} = predecessor - -let header {header; _} = header - -let rev_tickets {rev_tickets; _} = rev_tickets - -let validation_state {state; _} = state - -let level st = st.header.shell.level - -let rpc_context st = - let fitness = (header st).shell.fitness in - let result = Alpha_context.finalize st.state.ctxt fitness in - { - Environment.Updater.block_hash = Block_hash.zero; - block_header = {st.header.shell with fitness = result.fitness}; - context = result.context; - } - -let rpc_ctxt = - new Environment.proto_rpc_context_of_directory rpc_context rpc_services - -let alpha_ctxt st = st.state.ctxt - -let begin_construction ?timestamp ?seed_nonce_hash ?(mempool_mode = false) - ?(policy = Block.By_round 0) (predecessor : Block.t) = - Block.get_next_baker ~policy predecessor - >>=? fun (delegate, round, real_timestamp) -> - Account.find delegate >>=? fun delegate -> - Round.of_int round |> Environment.wrap_tzresult >>?= fun payload_round -> - let timestamp = Option.value ~default:real_timestamp timestamp in - (match seed_nonce_hash with - | Some _hash -> return seed_nonce_hash - | None -> ( - Plugin.RPC.current_level ~offset:1l Block.rpc_ctxt predecessor - >|=? function - | {expected_commitment = true; _} -> Some (fst (Proto_Nonce.generate ())) - | {expected_commitment = false; _} -> None)) - >>=? fun seed_nonce_hash -> - let contents = - Block.Forge.contents - ?seed_nonce_hash - ~payload_hash:Block_payload_hash.zero - ~payload_round - () - in - let protocol_data = - if mempool_mode then None - else Some {Block_header.contents; signature = Signature.zero} - in - let header = - { - Block_header.shell = - { - predecessor = predecessor.hash; - proto_level = predecessor.header.shell.proto_level; - validation_passes = predecessor.header.shell.validation_passes; - fitness = predecessor.header.shell.fitness; - timestamp; - level = predecessor.header.shell.level; - context = Context_hash.zero; - operations_hash = Operation_list_list_hash.zero; - }; - protocol_data = {contents; signature = Signature.zero}; - } - in - begin_construction - ~chain_id:Chain_id.zero - ~predecessor_context:predecessor.context - ~predecessor_timestamp:predecessor.header.shell.timestamp - ~predecessor_fitness:predecessor.header.shell.fitness - ~predecessor_level:predecessor.header.shell.level - ~predecessor:predecessor.hash - ~timestamp - ?protocol_data - () - >|= fun state -> - Environment.wrap_tzresult state >|? fun state -> - {predecessor; state; rev_operations = []; rev_tickets = []; header; delegate} - -let detect_script_failure : - type kind. kind Apply_results.operation_metadata -> _ = - let rec detect_script_failure : - type kind. kind Apply_results.contents_result_list -> _ = - let open Apply_results in - let detect_script_failure_single (type kind) - (Manager_operation_result - {operation_result; internal_operation_results; _} : - kind Kind.manager Apply_results.contents_result) = - let detect_script_failure (type kind) - (result : kind manager_operation_result) = - match result with - | Applied _ -> Ok () - | Skipped _ -> assert false - | Backtracked (_, None) -> - (* there must be another error for this to happen *) - Ok () - | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) - | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) - in - List.fold_left - (fun acc (Internal_operation_result (_, r)) -> - acc >>? fun () -> detect_script_failure r) - (detect_script_failure operation_result) - internal_operation_results - in - function - | Single_result (Manager_operation_result _ as res) -> - detect_script_failure_single res - | Single_result _ -> Ok () - | Cons_result (res, rest) -> - detect_script_failure_single res >>? fun () -> - detect_script_failure rest - in - fun {contents} -> detect_script_failure contents - -let add_operation ?expect_apply_failure ?expect_failure st op = - let open Apply_results in - apply_operation st.state op >|= Environment.wrap_tzresult >>= fun result -> - match (expect_apply_failure, result) with - | (Some _, Ok _) -> failwith "Error expected while adding operation" - | (Some f, Error err) -> f err >|=? fun () -> st - | (None, result) -> ( - result >>?= fun result -> - match result with - | (state, (Operation_metadata result as metadata)) -> - detect_script_failure result |> fun result -> - (match expect_failure with - | None -> Lwt.return result - | Some f -> ( - match result with - | Ok _ -> failwith "Error expected while adding operation" - | Error e -> f e)) - >|=? fun () -> - { - st with - state; - rev_operations = op :: st.rev_operations; - rev_tickets = metadata :: st.rev_tickets; - } - | (state, (No_operation_metadata as metadata)) -> - return - { - st with - state; - rev_operations = op :: st.rev_operations; - rev_tickets = metadata :: st.rev_tickets; - }) - -let finalize_block st = - let operations = List.rev st.rev_operations in - let operations_hash = - Operation_list_list_hash.compute - [Operation_list_hash.compute (List.map Operation.hash_packed operations)] - in - let shell_header = - { - st.header.shell with - level = Int32.succ st.header.shell.level; - operations_hash; - } - in - finalize_block st.state (Some shell_header) >|= fun x -> - Environment.wrap_tzresult x >|? fun (result, _) -> - let operations = List.rev st.rev_operations in - let operations_hash = - Operation_list_list_hash.compute - [Operation_list_hash.compute (List.map Operation.hash_packed operations)] - in - let header = - { - st.header with - shell = - { - st.header.shell with - level = Int32.succ st.header.shell.level; - operations_hash; - fitness = result.fitness; - }; - } - in - let hash = Block_header.hash header in - {Block.hash; header; operations; context = result.context} diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/incremental.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/incremental.mli deleted file mode 100644 index 87c33f9dc9a4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/incremental.mli +++ /dev/null @@ -1,62 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -type t - -type incremental = t - -val predecessor : incremental -> Block.t - -val header : incremental -> Block_header.t - -val rev_tickets : incremental -> operation_receipt list - -val validation_state : incremental -> validation_state - -val level : incremental -> int32 - -val begin_construction : - ?timestamp:Time.Protocol.t -> - ?seed_nonce_hash:Nonce_hash.t -> - ?mempool_mode:bool -> - ?policy:Block.baker_policy -> - Block.t -> - incremental tzresult Lwt.t - -val add_operation : - ?expect_apply_failure:(error list -> unit tzresult Lwt.t) -> - ?expect_failure:(error list -> unit tzresult Lwt.t) -> - incremental -> - Operation.packed -> - incremental tzresult Lwt.t - -val finalize_block : incremental -> Block.t tzresult Lwt.t - -val rpc_ctxt : incremental Environment.RPC_context.simple - -val alpha_ctxt : incremental -> Alpha_context.context diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_generator.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_generator.ml deleted file mode 100644 index 878d6f4aaa82..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_generator.ml +++ /dev/null @@ -1,351 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Liquidity_baking_machine -open QCheck.Gen -open Lib_test - -let total_xtz = 32_000_000_000_000L - -let ten_subsidies = 25_000_000L - -let rec remove_last_element = function - | [_] -> [] - | x :: rst -> x :: remove_last_element rst - | [] -> raise (Invalid_argument "remove_last_element") - -(** Try to shrink a list by removing elements from the tail of said - list. - - The elements themselves are not shrinked. *) -let shrink_list_spine_tail : 'a list QCheck.Shrink.t = - let rec shrinked_list = function - | [] -> [] - | l -> - let l = remove_last_element l in - l :: shrinked_list l - in - fun l -> QCheck.Iter.of_list (shrinked_list l) - -let gen_balances : int64 -> int -> int -> balances QCheck.Gen.t = - fun max_xtz max_tzbtc max_liquidity -> - let+ xtz = Qcheck_helpers.int64_strictly_positive_gen max_xtz - and+ tzbtc = Qcheck_helpers.int_strictly_positive_gen max_tzbtc - and+ liquidity = Qcheck_helpers.int_strictly_positive_gen max_liquidity in - {xtz; tzbtc; liquidity} - -let gen_specs : int -> int -> specs QCheck.Gen.t = - fun total_tzbtc total_liquidity -> - (* 1. We pick a random number to decide how many implicit account we - will set-up in the specs. Note that there will be one more - implicit accounts, the [Holder], that we will use to reach the - expected balances for the CPMM and the implicit accounts. *) - let* accounts_numbers = int_range 10 20 in - (* 2. To keep the generator simpler, we do not try to strictly reach - the [total_tzbtc] and [total_liquidity] value, but rather we - compute maxima for the implicit accounts balances from - them. *) - (* 2.1. We divide a fraction of the [total_xtz] that we need to - share to the implicit accounts. The rationale is to provide - a large amount to xtz to [Holder], so that we do not have to - worry about it being “rich enough.” *) - let max_xtz = Int64.(div total_xtz (of_int (50 * accounts_numbers))) in - (* 2.2. We divide [total_tzbtc] between the implicit accounts *and* - the CPMM contract. *) - let max_tzbtc = total_tzbtc / (accounts_numbers + 1) in - (* 2.2. We divide [total_liquidity] between the implicit accounts only. *) - let max_liquidity = total_liquidity / accounts_numbers in - let+ cpmm_balance = gen_balances max_xtz max_tzbtc 1 - and+ accounts_balances = - list_repeat accounts_numbers (gen_balances max_xtz max_tzbtc max_liquidity) - in - { - cpmm_min_xtz_balance = cpmm_balance.xtz; - cpmm_min_tzbtc_balance = cpmm_balance.tzbtc; - accounts_balances; - } - -let arb_specs : tzbtc -> liquidity -> specs QCheck.arbitrary = - fun total_tzbtc total_liquidity -> - QCheck.make - ~print:(fun specs -> Format.asprintf "%a" pp_specs specs) - (gen_specs total_tzbtc total_liquidity) - -type 'a optgen = 'a option QCheck.Gen.t - -let ( let*? ) (m : 'a optgen) (f : 'a -> 'b optgen) = - let* x = m in - match x with None -> return None | Some x -> f x - -(** [genopt_oneof l] tries to generate a value using the generators of - [l], one at a time. - - First, the list [l] is randomized, then each generator is - tried. The first one to return a result (not [None]) is picked. If - all generators returns [None], the generators tries again with the - whole list (at most 100 times). If no generator of [l] is able to - return a result, then [genopt_oneof l] returns [None]. *) -let genopt_oneof (l : 'a optgen list) : 'a optgen = - let* l = QCheck.Gen.shuffle_l l in - let rec aux n = function - | [] -> if n = 0 then pure None else aux (n - 1) l - | g :: l -> ( - let* x = g in - match x with None -> aux n l | Some x -> pure @@ Some x) - in - aux 100 l - -let genopt_account ?choice ?(filter = Fun.const true) env : contract_id optgen = - let l = - List.filter - filter - (Option.fold ~none:env.implicit_accounts ~some:(fun x -> [x]) choice) - in - if l = [] then return None else map Option.some (oneofl l) - -let genopt_account_with_tzbtc ?choice ?(min = 1) env state = - genopt_account - ?choice - ~filter:(fun a -> SymbolicMachine.get_tzbtc_balance a env state >= min) - env - -let genopt_account_with_xtz ?choice ?(min = 1L) env state = - genopt_account - ?choice - ~filter:(fun a -> SymbolicMachine.get_xtz_balance a state >= min) - env - -let genopt_account_with_liquidity ?choice ?(min = 1) env state = - genopt_account - ?choice - ~filter:(fun a -> SymbolicMachine.get_liquidity_balance a env state >= min) - env - -let genopt_step_tzbtc_to_xtz : - ?source:contract_id -> - ?destination:contract_id -> - contract_id env -> - SymbolicMachine.t -> - contract_id step optgen = - fun ?source ?destination env state -> - let*? source = genopt_account_with_tzbtc ?choice:source env state in - let*? destination = genopt_account ?choice:destination env in - let+ tzbtc_deposit = - Qcheck_helpers.int_strictly_positive_gen - (SymbolicMachine.get_tzbtc_balance source env state) - in - (* See note (2) *) - if - SymbolicMachine.get_tzbtc_balance env.cpmm_contract env state - < Int.max_int - tzbtc_deposit - then Some (SellTzBTC {source; destination; tzbtc_deposit}) - else None - -let genopt_step_xtz_to_tzbtc : - ?source:contract_id -> - ?destination:contract_id -> - contract_id env -> - SymbolicMachine.t -> - contract_id step optgen = - fun ?source ?destination env state -> - let*? source = genopt_account_with_xtz ?choice:source env state in - let*? destination = genopt_account ?choice:destination env in - let+ xtz_deposit = - map - Int64.of_int - (int_range - 1 - (Int64.to_int @@ SymbolicMachine.get_xtz_balance source state)) - in - (* See note (2) *) - if - SymbolicMachine.get_xtz_balance env.cpmm_contract state - < Int64.(sub max_int (add ten_subsidies xtz_deposit)) - then Some (BuyTzBTC {source; destination; xtz_deposit}) - else None - -let genopt_step_add_liquidity : - ?source:contract_id -> - ?destination:contract_id -> - contract_id env -> - SymbolicMachine.t -> - contract_id step optgen = - fun ?source ?destination env state -> - let rec find_xtz_deposit candidate max_tzbtc_deposit = - let tzbtc_deposit = - SymbolicMachine.predict_required_tzbtc_deposit candidate env state - in - if tzbtc_deposit <= max_tzbtc_deposit then candidate - else find_xtz_deposit (Int64.div candidate 2L) max_tzbtc_deposit - in - let*? source = genopt_account_with_xtz ?choice:source env state in - let*? destination = genopt_account ?choice:destination env in - let source_xtz_pool = SymbolicMachine.get_xtz_balance source state in - (* the source needs at least one xtz *) - if 1L < source_xtz_pool then - let+ candidate = - Qcheck_helpers.int64_strictly_positive_gen source_xtz_pool - in - let xtz_deposit = - find_xtz_deposit - candidate - (SymbolicMachine.get_tzbtc_balance source env state) - in - (* See note (2) *) - if - SymbolicMachine.get_xtz_balance env.cpmm_contract state - < Int64.(sub max_int (add ten_subsidies xtz_deposit)) - then Some (AddLiquidity {source; destination; xtz_deposit}) - else None - else pure None - -let genopt_step_remove_liquidity : - ?source:contract_id -> - ?destination:contract_id -> - contract_id env -> - SymbolicMachine.t -> - contract_id step optgen = - fun ?source ?destination env state -> - let*? source = genopt_account_with_liquidity ?choice:source env state in - let*? destination = genopt_account ?choice:destination env in - let lqt_available = SymbolicMachine.get_liquidity_balance source env state in - if 1 < lqt_available then - let+ lqt_burned = - int_range 1 (SymbolicMachine.get_liquidity_balance source env state) - in - Some (RemoveLiquidity {source; destination; lqt_burned}) - else return None - -let genopt_step : - ?source:contract_id -> - ?destination:contract_id -> - contract_id env -> - SymbolicMachine.t -> - contract_id step optgen = - fun ?source ?destination env state -> - genopt_oneof - [ - genopt_step_tzbtc_to_xtz env state ?source ?destination; - genopt_step_xtz_to_tzbtc env state ?source ?destination; - genopt_step_add_liquidity env state ?source ?destination; - genopt_step_remove_liquidity env state ?source ?destination; - ] - -let rec gen_steps : - ?source:contract_id -> - ?destination:contract_id -> - contract_id env -> - SymbolicMachine.t -> - int -> - contract_id step list QCheck.Gen.t = - fun ?source ?destination env state size -> - if size <= 0 then return [] - else - let* h = genopt_step ?source ?destination env state in - match h with - | None -> pure [] - | Some h -> - let state = SymbolicMachine.step h env state in - let* rst = gen_steps ?source ?destination env state (size - 1) in - pure (h :: rst) - -let gen_scenario : - tzbtc -> liquidity -> int -> (specs * contract_id step list) QCheck.Gen.t = - fun total_tzbtc total_liquidity size -> - let* specs = gen_specs total_tzbtc total_liquidity in - let (state, env) = SymbolicMachine.build specs in - let+ scenario = gen_steps env state size in - (specs, scenario) - -let pp_scenario fmt (specs, steps) = - Format.( - fprintf - fmt - "@[{@ @[ @[specs@ = %a;@]@ @[steps@ = @[[ \ - %a]@]@]@]}@]" - pp_specs - specs - (pp_print_list - ~pp_sep:(fun fmt _ -> fprintf fmt "@ ; ") - (pp_step pp_contract_id)) - steps) - -let arb_scenario : - tzbtc -> - liquidity -> - int -> - (specs * contract_id step list) QCheck.arbitrary = - fun total_tzbtc total_liquidity size -> - QCheck.make - ~print:(Format.asprintf "%a" pp_scenario) - ~shrink:(fun (specs, steps) -> - (* See note (1) *) - QCheck.Iter.pair (QCheck.Iter.return specs) (shrink_list_spine_tail steps)) - (gen_scenario total_tzbtc total_liquidity size) - -let gen_adversary_scenario : - tzbtc -> - liquidity -> - int -> - (specs * contract_id * contract_id step list) QCheck.Gen.t = - fun total_tzbtc total_liquidity size -> - let* specs = gen_specs total_tzbtc total_liquidity in - let (state, env) = SymbolicMachine.build ~subsidy:0L specs in - let* c = oneofl env.implicit_accounts in - let+ scenario = gen_steps ~source:c ~destination:c env state size in - (specs, c, scenario) - -let arb_adversary_scenario : - tzbtc -> - liquidity -> - int -> - (specs * contract_id * contract_id step list) QCheck.arbitrary = - fun total_tzbtc total_liquidity size -> - QCheck.make - ~print:(fun (specs, _, steps) -> - Format.asprintf "%a" pp_scenario (specs, steps)) - ~shrink:(fun (specs, c, steps) -> - (* see note (1) *) - QCheck.Iter.triple - (QCheck.Iter.return specs) - (QCheck.Iter.return c) - (shrink_list_spine_tail steps)) - (gen_adversary_scenario total_tzbtc total_liquidity size) - -(* -------------------------------------------------------------------------- *) - -(* Note (1) - - We shrink a valid scenario by removing steps from its tails, - because a prefix of a valid scenario remains a valid - scenario. Removing a random element of a scenario could lead to an - invalid scenario. *) - -(* Note (2) - - If we are not being careful, it is possible to provoke an overflow - in the xtzPool and tzbtcPool. We try to avoid that as much as - possible by being very careful with the steps that are likely to - add xtz to the contract. *) diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_generator.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_generator.mli deleted file mode 100644 index c0f1a9811438..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_generator.mli +++ /dev/null @@ -1,77 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module provides a set of abstractions to reason about the - so-called “liquidity baking” feature[1]. - - [1]: https://gitlab.com/tezos/tzip/-/blob/master/drafts/current/draft-liquidity_baking.md - - We remind that this feature is built upon three smart contracts: - (1) a CPMM contract initially based on Dexter 2, and (2) two - tokens contracts. - - Our purpose for Liquidity Baking is to easily express and test - invariants regarding the execution of these contracts. To that - end, we have introduced a set of dedicated types to describe - arbitrary contexts in terms of account balances (see - [Liquidity_baking_machine.specs]), along with [build] functions - that turn a description of a context into concrete states. - - In this module, we provide QCheck generators which allow to - construct arbitrary specifications for states, and so-called - scenarios ({i i.e.}, sequences of entrypoint calls). *) - -open Liquidity_baking_machine - -(** [arb_specs max_tzbtc max_liquidity] constructs arbitrary Liquidity - Baking [specs] for an initial state, where at most [max_tzbtc] and - [max_liquidity] are shared among an arbitrary number of implicit - accounts. *) -val arb_specs : tzbtc -> liquidity -> specs QCheck.arbitrary - -(** [arb_scenario max_tzbtc max_liquidity size] constructs arbitrary - Liquidity Baking [specs] with a semantics similar to [arb_specs], along with sequences of {b valid} - scenarios ({i i.e.}, sequences of entrypoint calls) of length - [size]. By valid, we mean that running the scenario using a - Liquidity baking machine initialized with the [specs] should - succeed. *) -val arb_scenario : - tzbtc -> liquidity -> int -> (specs * contract_id step list) QCheck.arbitrary - -(** [arb_adversary_scenario max_tzbtc max_liquidity size] constructs - arbitrary scenarios that can be used to challenge the “no global - gain” property of Liquidity Baking. - - The key idea of this property is the following: a given contract - cannot profit from Liquidity Baking if they are the only one to - interact with the CPMM (in the absence of subsidies). The scenario - generated by [arb_adversary_scenario] only consists in [step] - performed by one contract. This contract is identified by the - [contract_id] returned by this function. *) -val arb_adversary_scenario : - tzbtc -> - liquidity -> - int -> - (specs * contract_id * contract_id step list) QCheck.arbitrary diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.ml deleted file mode 100644 index 0e19624e0cce..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.ml +++ /dev/null @@ -1,1364 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -(** To implement the interface of this module, as described and - documented in the related MLI file, we rely on the OCaml module - system. More precisely, most of the implementation of the two - public machines ([ValidationMachine] and [SymbolicMachine]) is - derived by means of functors. - - The machines provide two key functions which can be used in a - test suite: - - - [M.build specs] which allows to construct an initial state of - a machine [M] that satisfies the properties described by - [specs] (along with the so-called “environment” of the - machine) - - [M.step s env state] (resp. [M.run]) which allows to execute a - so-called scenario [step] (resp. a sequence of [step]s, {i - i.e.}, a complete scenario) by the machine [M] from the state - [state]. - - The module is organized as follows: - - 1. We introduce the necessary abstractions we later use to - specify the properties the initial state of a given machine - needs to satisfy (most notably the [specs] type). - 2. Then, we introduce the [step] type, which describes the - various actions we can make a machine perform as part of a - more complete scenario. - 3. We introduce the [MACHINE] module type which lists the - necessary types and functions we need to derive a machine - capable of executing scenarios, and the [Machine.Make] - functor that we can use to derive such a machine - automatically. - 4. We introduce the [MACHINE_WITH_INIT] module type which is a - superset of [MACHINE], extended with an [init] function - (analogous to {! Context.init}) to create an initial, mostly - blank state, and the [MachineBuilder.Make] functor that we - can use to derive a machine with a [build] function. - 5. We construct the [ConcreteMachine], that allows to - asynchronously execute scenarios against the Tezos - blockchain. - 6. We implement the [AbstractMachine.Make] functor, which we - can use to construct machines that can simulate the - execution scenarios completely off-chains, by reimplementing - the LB features logic in pure OCaml. - 7. We use [AbstractMachine.Make] to create the [SymbolicMachine]. - 8. We use the [AbstractMachine.Make] functor in conjuction with - the [ConcreteMachine] to introduce the [ValidationMachine]. - - _ - / \ A warning for developers willing to modify this module: - / | \ dealing with the subsidy of the Liquidity Baking (LB) - / · \ feature is probably the main source of complexity and - /_______\ fragility of this module. - - At several places (marked with a /!\ note), we need to predict the - xtz pool of the CPMM contract, in order to compute the amount of - tzBTC token it will provide or request. To make this prediction, - we need to determine how many blocks have been/will be baked. This - means that each time we modify the code of the machine functors, - we will probably have to modify the code marked with /!\ too. - - To reduce the potential to get things wrong, we have introduced - constants to prevent the use of “magic numbers” (numbers whose - meaning cannot be guessed only by looking at the formula). The - value of these constants is not statically checked, so pay extra - attention before modifying them. - - Ideally, we could probably compute these magic numbers using a - dedicated machine, whose purpose would be to count the number of - call to the [bake] function. For the sake of simplicity, we do not - do it currently. *) - -(** The number of blocks baked in order to execute the {! - AddLiquidity} step. *) -let blocks_per_add_liquidity_step = 2L - -(** The number of blocks baked by the [init] function. Since - Tenderbake, we need to compensate for deposits, so the number is - no longer constant. It is linear wrt. the number of accounts. *) -let blocks_during_init len = Int64.add 3L len - -(** The number of blocks baked by the [mint_tzbtc] functions *) -let blocks_per_mint_tzbtc = 1L - -(** A timestamp “far in the future” which should not be exceeded when - running tests. *) -let far_future = Alpha_context.Script_timestamp.of_zint (Z.of_int 42_000) -(* Hypothesis: the tests start at timestamp 0, and 42000 is - “big enough.” *) - -(* --------------------------------------------------------------------------- *) - -(** {1 Miscellaneous Helpers} *) - -let is_implicit_exn account = - match Contract.is_implicit account with Some k -> k | _ -> assert false - -module List_helpers = struct - let rec zip l r = - match (l, r) with - | (xl :: rstl, xr :: rstr) -> (xl, xr) :: zip rstl rstr - | _ -> [] - - let nth_exn l n = - match List.nth l n with - | Some x -> x - | _ -> raise (Invalid_argument "nth_exn") - - let assoc_exn c l = - match List.assoc ~equal:( = ) c l with - | Some x -> x - | _ -> raise (Invalid_argument "assoc_exn") -end - -(* --------------------------------------------------------------------------- *) - -(** {1 Characterizing Initial Machines States} *) - -(** In order to run so-called scenarios against our machines, we first - need to characterize their initial state. *) - -type xtz = int64 - -type tzbtc = int - -type liquidity = int - -type balances = {xtz : xtz; tzbtc : tzbtc; liquidity : liquidity} - -let pp_balances fmt b = - Format.fprintf - fmt - "@[{xtz = %a; tzbtc = %d; liquidity = %d}@]" - Tez.pp - (Tez.of_mutez_exn b.xtz) - b.tzbtc - b.liquidity - -let xtz {xtz; _} = xtz - -type specs = { - cpmm_min_xtz_balance : xtz; - cpmm_min_tzbtc_balance : tzbtc; - accounts_balances : balances list; -} - -let pp_specs fmt specs = - Format.( - fprintf - fmt - "@[{@ @[cpmm = {min_xtz = %a; min_tzbtc = %d}@ @[accounts = \ - [@ %a@ ]@]@]@ }@]" - Tez.pp - (Tez.of_mutez_exn specs.cpmm_min_xtz_balance) - specs.cpmm_min_tzbtc_balance - (pp_print_list ~pp_sep:pp_print_space pp_balances) - specs.accounts_balances) - -(* --------------------------------------------------------------------------- *) - -(** {1 Scenario [step] }*) - -type 'a step = - | SellTzBTC of {source : 'a; destination : 'a; tzbtc_deposit : tzbtc} - | BuyTzBTC of {source : 'a; destination : 'a; xtz_deposit : xtz} - | AddLiquidity of {source : 'a; destination : 'a; xtz_deposit : xtz} - | RemoveLiquidity of {source : 'a; destination : 'a; lqt_burned : liquidity} - -let pp_step pp_contract fmt = function - | SellTzBTC p -> - Format.( - fprintf - fmt - "@[SellTzBTC(%a, %dtz₿, %a)@]" - pp_contract - p.source - p.tzbtc_deposit - pp_contract - p.destination) - | BuyTzBTC p -> - Format.( - fprintf - fmt - "@[BuyTzBTC(%a, %aꜩ, %a)@]" - pp_contract - p.source - Tez.pp - (Tez.of_mutez_exn p.xtz_deposit) - pp_contract - p.destination) - | AddLiquidity p -> - Format.( - fprintf - fmt - "@[AddLiquidity(%a, %aꜩ, %a)@]" - pp_contract - p.source - Tez.pp - (Tez.of_mutez_exn p.xtz_deposit) - pp_contract - p.destination) - | RemoveLiquidity p -> - Format.( - fprintf - fmt - "@[RemoveLiquidity(%a, %d lqt, %a)@]" - pp_contract - p.source - p.lqt_burned - pp_contract - p.destination) - -type contract_id = - | Cpmm - | Holder - | TzBTC - | TzBTCAdmin - | Liquidity - | LiquidityAdmin - | ImplicitAccount of int - -let contract_id_to_string = function - | Holder -> "holder" - | Cpmm -> "cpmm" - | TzBTC -> "tzbtc" - | TzBTCAdmin -> "tzbtc_admin" - | Liquidity -> "lqt" - | LiquidityAdmin -> "lqt_admin" - | ImplicitAccount i -> Format.sprintf "#%d" i - -let pp_contract_id fmt c = Format.(fprintf fmt "[%s]" (contract_id_to_string c)) - -(* --------------------------------------------------------------------------- *) - -(** {1 Machines} *) - -(** {2 Machine Environment} *) - -type 'a env = { - cpmm_contract : 'a; - tzbtc_contract : 'a; - tzbtc_admin : 'a; - liquidity_contract : 'a; - liquidity_admin : 'a; - implicit_accounts : 'a list; - holder : 'a; - subsidy : xtz; -} - -let refine_contract env = function - | Cpmm -> env.cpmm_contract - | TzBTC -> env.tzbtc_contract - | TzBTCAdmin -> env.tzbtc_admin - | Liquidity -> env.liquidity_contract - | LiquidityAdmin -> env.liquidity_admin - | Holder -> env.holder - | ImplicitAccount i -> List_helpers.nth_exn env.implicit_accounts i - -let refine_step env step = - match step with - | SellTzBTC p -> - SellTzBTC - { - p with - source = refine_contract env p.source; - destination = refine_contract env p.destination; - } - | BuyTzBTC p -> - BuyTzBTC - { - p with - source = refine_contract env p.source; - destination = refine_contract env p.destination; - } - | AddLiquidity p -> - AddLiquidity - { - p with - source = refine_contract env p.source; - destination = refine_contract env p.destination; - } - | RemoveLiquidity p -> - RemoveLiquidity - { - p with - source = refine_contract env p.source; - destination = refine_contract env p.destination; - } - -(** {2 Machine Module Type} *) - -module type MACHINE = sig - type 'a m - - type contract - - type t - - type operation - - val pp_contract : Format.formatter -> contract -> unit - - val ( >>= ) : 'a m -> ('a -> 'b m) -> 'b m - - val fold_m : ('a -> 'b -> 'a m) -> 'a -> 'b list -> 'a m - - val pure : 'a -> 'a m - - val get_balances : contract -> contract env -> t -> balances m - - val get_xtz_balance : contract -> t -> xtz m - - val get_tzbtc_balance : contract -> contract env -> t -> tzbtc m - - val get_liquidity_balance : contract -> contract env -> t -> liquidity m - - val get_cpmm_total_liquidity : contract env -> t -> liquidity m - - val bake : - invariant:(contract env -> t -> bool m) -> - baker:contract -> - operation list -> - contract env -> - t -> - t m - - val transaction : src:contract -> contract -> xtz -> t -> operation m - - val token_to_xtz : - src:contract -> contract -> tzbtc -> contract env -> t -> operation m - - val xtz_to_token : - src:contract -> contract -> xtz -> contract env -> t -> operation m - - (* [mint_or_burn_tzbtc contract amount env state] will construct an - operation to credit or remove [amount] tzbtc tokens to [contract] *) - val mint_or_burn_tzbtc : - contract -> liquidity -> contract env -> t -> operation m - - (** [approve_tzbtc contract amount env state] will construct an - operation to authorize the CPMM contract to spend [amount] tzbtc - on behalf of [contract] *) - val approve_tzbtc : contract -> tzbtc -> contract env -> t -> operation m - - val add_liquidity : - src:contract -> contract -> xtz -> tzbtc -> contract env -> t -> operation m - - val remove_liquidity : - src:contract -> contract -> liquidity -> contract env -> t -> operation m - - val reveal : Account.t -> t -> operation m -end - -(** {2 Tezos Constants} *) - -let default_subsidy = - let open Tezos_protocol_012_Psithaca_parameters in - Tez.to_mutez @@ Default_parameters.constants_test.liquidity_baking_subsidy - -let security_deposit = 640_000_000L - -(* When calling [Context.init] with a list of initial balances, the - sum of these balances should be equal to this constant. *) -let total_xtz = 32_000_000_000_000L - -let tzbtc_admin_account : Account.t = - { - pkh = - Signature.Public_key_hash.of_b58check_exn - "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; - pk = - Signature.Public_key.of_b58check_exn - "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"; - sk = - Signature.Secret_key.of_b58check_exn - "edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh"; - } - -let cpmm_initial_balance = {xtz = 100L; tzbtc = 1; liquidity = 0} - -let cpmm_initial_liquidity_supply = 100 - -(** {2 Machine Functor} *) - -module Machine = struct - module Make (S : MACHINE) = struct - open S - - let mint_tzbtc destination ~invariant amount env state = - mint_or_burn_tzbtc destination amount env state >>= fun op -> - bake ~invariant ~baker:env.holder [op] env state - - let add_liquidity ~invariant src dst xtz_deposit tzbtc_deposit env state = - approve_tzbtc src tzbtc_deposit env state >>= fun lqt_op -> - bake ~invariant ~baker:env.holder [lqt_op] env state >>= fun state -> - add_liquidity ~src dst xtz_deposit tzbtc_deposit env state - >>= fun cpmm_op -> bake ~invariant ~baker:env.holder [cpmm_op] env state - - let remove_liquidity ~invariant src dst lqt_burned env state = - remove_liquidity ~src dst lqt_burned env state >>= fun cpmm_op -> - bake ~invariant ~baker:env.holder [cpmm_op] env state - - let sell_tzbtc ~invariant src dst tzbtc_deposit env state = - approve_tzbtc src tzbtc_deposit env state >>= fun tzbtc_op -> - bake ~invariant ~baker:env.holder [tzbtc_op] env state >>= fun state -> - token_to_xtz ~src dst tzbtc_deposit env state >>= fun cpmm_op -> - bake ~invariant ~baker:env.holder [cpmm_op] env state - - let buy_tzbtc ~invariant src dst xtz_deposit env state = - xtz_to_token ~src dst xtz_deposit env state >>= fun cpmm_op -> - bake ~invariant ~baker:env.holder [cpmm_op] env state - - let check_state_satisfies_specs (env : S.contract env) (state : S.t) - (specs : specs) = - let implicit_accounts_targets = - List_helpers.zip env.implicit_accounts specs.accounts_balances - in - fold_m - (fun _ acc -> - let expected = List_helpers.assoc_exn acc implicit_accounts_targets in - get_balances acc env state >>= fun amount -> - assert (expected = amount) ; - pure ()) - () - env.implicit_accounts - >>= fun _ -> - get_tzbtc_balance env.cpmm_contract env state - >>= fun cpmm_tzbtc_balance -> - assert (specs.cpmm_min_tzbtc_balance <= cpmm_tzbtc_balance) ; - get_xtz_balance env.cpmm_contract state >>= fun current_cpmm_xtz -> - assert ( - Int64.(to_int specs.cpmm_min_xtz_balance <= to_int @@ current_cpmm_xtz)) ; - pure () - - (** [predict_required_tzbtc_deposit xtz_deposit env state] - predicts the tzbtc deposit which will be required by the CPMM - contract for a deposit of [xtz_deposit]. - - This function is used by the machines to make the according - call to the [approve] entrypoint of the TzBTC contract. *) - let predict_required_tzbtc_deposit xtz_deposit env state = - get_xtz_balance env.cpmm_contract state >>= fun xtzPool -> - (* /!\ We need to take into accounts the number of blocks baked - to actually call the [add_liquidity] entry point of the - CPMM. *) - let xtzPool = - Tez.of_mutez_exn - Int64.(add xtzPool (mul blocks_per_add_liquidity_step env.subsidy)) - in - get_tzbtc_balance env.cpmm_contract env state >>= fun tokenPool -> - let tokenPool = Z.of_int tokenPool in - get_cpmm_total_liquidity env state >>= fun lqtTotal -> - let lqtTotal = Z.of_int lqtTotal in - let amount = Tez.of_mutez_exn xtz_deposit in - let (_, tokens_deposited) = - Cpmm_logic.Simulate_raw.addLiquidity - ~tokenPool - ~xtzPool - ~lqtTotal - ~amount - in - pure (Z.to_int tokens_deposited) - - let step ?(invariant = fun _ _ -> pure true) s env state = - match s with - | SellTzBTC {source; destination; tzbtc_deposit} -> - sell_tzbtc ~invariant source destination tzbtc_deposit env state - | BuyTzBTC {source; destination; xtz_deposit} -> - buy_tzbtc ~invariant source destination xtz_deposit env state - | AddLiquidity {source; destination; xtz_deposit} -> - predict_required_tzbtc_deposit xtz_deposit env state - >>= fun tzbtc_deposit -> - add_liquidity - ~invariant - source - destination - xtz_deposit - tzbtc_deposit - env - state - | RemoveLiquidity {source; destination; lqt_burned} -> - remove_liquidity ~invariant source destination lqt_burned env state - - let run ?(invariant = fun _ _ -> pure true) scenario env state = - fold_m - (fun state s -> step ~invariant (refine_step env s) env state) - state - scenario - end -end - -let initial_xtz_repartition accounts_balances = - let distributed_xtz = List.fold_left Int64.add 0L accounts_balances in - let bootstrap1_xtz = Int64.sub total_xtz distributed_xtz in - let initial_balances = bootstrap1_xtz :: accounts_balances in - let n = List.length initial_balances in - (n, initial_balances) - -(* --------------------------------------------------------------------------- *) - -(** {1 Machines with a [build] Function} *) - -module type MACHINE_WITH_INIT = sig - include MACHINE - - (** [init balances] will create an “initial” state wherein the - [balances] have been distributed to [n] implicit contracts ([n] - being the size of the [balances] list). This function also - creates a [holder] implicit account which has the rest of the - xtz liquidity (the test framework forces the sum of xtz balances - to be equal to [total_xtz]). [init] also accepts an optional - argument [subsidy] to modify the default value of the subsidy - minted by the protocol in favor of the CPMM. *) - val init : - invariant:(contract env -> t -> bool m) -> - ?subsidy:xtz -> - xtz list -> - (t * contract env) m -end - -(** [initial_xtz_pool] balances predicts the value of the CPMM’s xtz - pool just before we start using the [add_liquidity] entrypoint to - provide to each implicit accounts the necessary liquidity - tokens. *) -let initial_xtz_pool balances subsidy = - (* /!\ In addition to the initial CPMM balances, we need to take - into account the subsidies of each block baked before this - point, which currently consist in: - - - One call to the [init] function - - One call to the [mint_tzbtc] function per implicit - accounts - - If the [build] function changes, this functions needs to be - updated accordingly. *) - let len = Int64.of_int (List.length balances) in - Int64.( - add - cpmm_initial_balance.xtz - (mul - (add (blocks_during_init len) (mul blocks_per_mint_tzbtc len)) - subsidy)) - -(** [predict_initial_balances xtz_pool tzbtc_pool lqt_total balances] - evaluates the extra xtz and tzbtc tokens to add to each balance of - the list [balances] so that the related implicit accounts can call - the [add_liquidity] entrypoint in order to have the required - liquidity token. - - For instance, for a balance [b] such that [b.liquidity = 10], we - compute [xtz_etra] and [tzbtc_extra] so that the implicit account - will be able to buy [10] liquidity tokens, and replace [b] with - [{b with xtz = b.xtz + xtz_extra; tzbtc = b.tzbtc + tzbtc_extra}] - in the returned list. - - The implementation of this function is made more complex than it - should due to the mechanism of subsidy of LB. In particular, it is - depends on the number of block baked to buy liquidities. *) -let predict_initial_balances balances subsidy = - let open Z in - let subsidy_z = of_int64 subsidy in - (* Due to the roundness of [Z.( / )], it is not straightforward to - find the inverse of the equation used to compute the number of - liquidity tokens bought with the [add_liquidity] entrypoint. To - find the suitable number of xtz to propose in order to buy - [liquidity_target], we naively search for the correct - solution. We compute a [xtz_candidate] by ignoring the roundness - of [Z.( / )], then increment it until it works. *) - let find_xtz_extra xtz_pool lqt_total liquidity_target = - let rec aux xtz_candidate = - let liquidity_z = xtz_candidate * lqt_total / xtz_pool in - if liquidity_z = liquidity_target then xtz_candidate - else aux (xtz_candidate + Z.one) - in - let xtz_extra_candidate = liquidity_target * xtz_pool / lqt_total in - aux xtz_extra_candidate - in - let rec predict_initial_balances xtz_pool tzbtc_pool lqt_total = function - | {xtz; tzbtc; liquidity} :: rst -> - (* balance inputs *) - (* /!\ We compute two blocks per [add_liquidity] entrypoint, - hence the two subsidies *) - let xtz_pool = - xtz_pool + (Z.of_int64 blocks_per_add_liquidity_step * subsidy_z) - in - let xtz_z = of_int64 xtz in - let tzbtc_z = of_int tzbtc in - let liquidity_z = of_int liquidity in - (* compute extra for being able to buy liquidity tokens *) - let xtz_extra = find_xtz_extra xtz_pool lqt_total liquidity_z in - let tzbtc_extra = cdiv (xtz_extra * tzbtc_pool) xtz_pool in - (* compute new balances *) - let xtz = to_int64 (xtz_z + xtz_extra) in - let tzbtc = to_int (tzbtc_z + tzbtc_extra) in - let liquidity = to_int liquidity_z in - (* new pools *) - let xtz_pool' = xtz_pool + xtz_extra in - let tzbtc_pool' = tzbtc_pool + tzbtc_extra in - let lqt_total' = lqt_total + liquidity_z in - (* recursion time *) - {xtz; tzbtc; liquidity} - :: predict_initial_balances xtz_pool' tzbtc_pool' lqt_total' rst - | [] -> [] - in - predict_initial_balances - (of_int64 @@ initial_xtz_pool balances subsidy) - (of_int cpmm_initial_balance.tzbtc) - (of_int cpmm_initial_liquidity_supply) - balances - -module MachineBuilder = struct - module Make (S : MACHINE_WITH_INIT) = struct - open S - include Machine.Make (S) - - let build : - ?invariant:(S.contract env -> S.t -> bool m) -> - ?subsidy:xtz -> - specs -> - (S.t * S.contract env) m = - fun ?(invariant = fun _ _ -> pure true) - ?(subsidy = default_subsidy) - ({cpmm_min_xtz_balance; accounts_balances; cpmm_min_tzbtc_balance} as - specs) -> - let accounts_balances_with_extra = - predict_initial_balances accounts_balances subsidy - in - let xtz_balances_with_extra = List.map xtz accounts_balances_with_extra in - (* 1. Create an initial context *) - init ~invariant ~subsidy xtz_balances_with_extra >>= fun (state, env) -> - invariant env state >>= fun cond -> - assert cond ; - (* 2. Provide the initial tzBTC liquidities to implicit accounts *) - let accounts = - List_helpers.zip - env.implicit_accounts - (List_helpers.zip accounts_balances accounts_balances_with_extra) - in - fold_m - (fun state (address, (_, balances)) -> - mint_tzbtc ~invariant address balances.tzbtc env state) - state - accounts - >>= fun state -> - (* 3. Make implicit accounts buy liquidities *) - fold_m - (fun state (address, (target_balances, balances_with_extra)) -> - let xtz = Int64.sub balances_with_extra.xtz target_balances.xtz in - let tzbtc = balances_with_extra.tzbtc - target_balances.tzbtc in - add_liquidity ~invariant address address xtz tzbtc env state) - state - accounts - >>= fun state -> - (* 4. Provide any missing tzbtc tokens to [cpmm_contract], if necessary *) - get_tzbtc_balance env.cpmm_contract env state - >>= fun current_cpmm_tzbtc_balance -> - let tzbtc_missing = cpmm_min_tzbtc_balance - current_cpmm_tzbtc_balance in - (if 0 < tzbtc_missing then - (* 4.1. Provide the tokens to the [bootstrap1] account, as a - temporary holder for CPMM missing tzBTC balance *) - mint_tzbtc ~invariant env.holder tzbtc_missing env state >>= fun state -> - (* 4.1. Make [bootstrap1] buy some xtz against the appropriate - amount of tzbtc *) - sell_tzbtc ~invariant env.holder env.holder tzbtc_missing env state - else pure state) - >>= fun state -> - (* 5. Provide any missing xtz tokens to [cpmm_contract], if necessary *) - get_xtz_balance env.cpmm_contract state - >>= fun current_cpmm_xtz_balance -> - let xtz_missing = - Int64.sub cpmm_min_xtz_balance current_cpmm_xtz_balance - in - (if 0L < xtz_missing then - transaction ~src:env.holder env.cpmm_contract xtz_missing state - >>= fun op -> bake ~invariant ~baker:env.holder [op] env state - else pure state) - >>= fun state -> - check_state_satisfies_specs env state specs >>= fun _ -> pure (state, env) - end -end - -(* --------------------------------------------------------------------------- *) - -module ConcreteBaseMachine : - MACHINE_WITH_INIT - with type 'a m = 'a tzresult Lwt.t - and type contract = Contract.t - and type t = Block.t = struct - type 'a m = 'a tzresult Lwt.t - - type contract = Contract.t - - type operation = packed_operation - - type t = Block.t - - let pp_contract = Contract.pp - - let ( >>= ) = ( >>=? ) - - let fold_m = Environment.List.fold_left_es - - let pure = Error_monad.return - - let get_xtz_balance contract blk = - Context.Contract.balance (B blk) contract >>= fun x -> - pure @@ Tez.to_mutez x - - let get_tzbtc_balance contract env blk = - Lqt_fa12_repr.Storage.getBalance_opt - (B blk) - ~contract:env.tzbtc_contract - (contract, "default") - >>=? fun mamount -> - pure (Option.value (Option.map Z.to_int mamount) ~default:0) - - let get_liquidity_balance contract env blk = - Lqt_fa12_repr.Storage.getBalance_opt - (B blk) - ~contract:env.liquidity_contract - (contract, "default") - >>=? fun mamount -> - pure (Option.value (Option.map Z.to_int mamount) ~default:0) - - let get_cpmm_total_liquidity env blk = - Cpmm_repr.Storage.get (B blk) ~contract:env.cpmm_contract - >>=? fun cpmm_storage -> pure @@ Z.to_int cpmm_storage.lqtTotal - - let get_balances contract env blk = - get_xtz_balance contract blk >>= fun xtz -> - get_tzbtc_balance contract env blk >>= fun tzbtc -> - get_liquidity_balance contract env blk >>= fun liquidity -> - pure {xtz; tzbtc; liquidity} - - let bake ~invariant ~baker ops env blk = - Incremental.begin_construction - ~policy:(Block.By_account (is_implicit_exn baker)) - blk - >>= fun incr -> - fold_m Incremental.add_operation incr ops >>= fun incr -> - Incremental.finalize_block incr >>= fun blk -> - invariant env blk >>= fun cond -> - assert cond ; - return blk - - let reveal (account : Account.t) blk = Op.revelation (B blk) account.pk - - let transaction ~src dst amount blk = - Op.transaction (B blk) src dst (Tez.of_mutez_exn amount) - - let token_to_xtz ~src dst tzbtc_deposit env blk = - Cpmm_repr.transaction - (B blk) - ~src - ~contract:env.cpmm_contract - (Cpmm_repr.Parameter.TokenToXtz - { - to_ = dst; - minXtzBought = Tez.zero; - tokensSold = Z.of_int tzbtc_deposit; - deadline = far_future; - }) - - let xtz_to_token ~src dst amount env blk = - Cpmm_repr.transaction - (B blk) - ~src - ~contract:env.cpmm_contract - (Cpmm_repr.Parameter.XtzToToken - {to_ = dst; minTokensBought = Z.zero; deadline = far_future}) - ~amount:(Tez.of_mutez_exn amount) - - let approve_tzbtc src tzbtc env blk = - let maxTokensDeposited = Z.of_int tzbtc in - Lqt_fa12_repr.transaction - (B blk) - ~src - ~contract:env.tzbtc_contract - (Lqt_fa12_repr.Parameter.Approve - {spender = env.cpmm_contract; value = maxTokensDeposited}) - - let mint_or_burn_tzbtc target amount env blk = - let quantity = Z.of_int amount in - let ctxt = Context.B blk in - Lqt_fa12_repr.transaction - ctxt - ~src:env.tzbtc_admin - ~contract:env.tzbtc_contract - (Lqt_fa12_repr.Parameter.mintOrBurn {target; quantity}) - - let add_liquidity ~src dst xtz_deposit tzbtc_deposit env blk = - let amount = Tez.of_mutez_exn xtz_deposit in - let maxTokensDeposited = Z.of_int tzbtc_deposit in - Cpmm_repr.transaction - (B blk) - ~src - ~contract:env.cpmm_contract - ~amount - (Cpmm_repr.Parameter.AddLiquidity - { - owner = dst; - maxTokensDeposited; - minLqtMinted = Z.zero; - deadline = far_future; - }) - - let remove_liquidity ~src dst lqt_burned env blk = - let lqtBurned = Z.of_int lqt_burned in - Cpmm_repr.transaction - (B blk) - ~src - ~contract:env.cpmm_contract - (Cpmm_repr.Parameter.RemoveLiquidity - { - to_ = dst; - lqtBurned; - minXtzWithdrawn = Tez.zero; - minTokensWithdrawn = Z.zero; - deadline = far_future; - }) - - let reveal_tzbtc_admin ~invariant env state = - Account.add_account tzbtc_admin_account ; - transaction ~src:env.holder env.tzbtc_admin 1L state >>= fun op1 -> - bake ~invariant ~baker:env.holder [op1] env state >>= fun state -> - reveal tzbtc_admin_account state >>= fun op2 -> - bake ~invariant ~baker:env.holder [op2] env state - - let init ~invariant ?subsidy accounts_balances = - let liquidity_baking_subsidy = Option.map Tez.of_mutez_exn subsidy in - let (n, initial_balances) = initial_xtz_repartition accounts_balances in - Context.init - n - ~consensus_threshold:0 - ~initial_balances - ~cost_per_byte:Tez.zero - ~endorsing_reward_per_slot:Tez.zero - ~baking_reward_bonus_per_slot:Tez.zero - ~baking_reward_fixed_portion:Tez.zero - ~origination_size:0 - ~blocks_per_cycle:10_000l - ?liquidity_baking_subsidy - >>= function - | (blk, holder :: accounts) -> - let ctxt = Context.B blk in - Context.get_liquidity_baking_cpmm_address ctxt >>= fun cpmm_contract -> - Context.Contract.storage ctxt cpmm_contract >>= fun storage -> - let storage = Cpmm_repr.Storage.of_expr_exn (Micheline.root storage) in - let tzbtc_contract = storage.tokenAddress in - let liquidity_contract = storage.lqtAddress in - Context.Contract.storage ctxt tzbtc_contract >>= fun storage -> - let storage = - Lqt_fa12_repr.Storage.of_expr_exn (Micheline.root storage) - in - let tzbtc_admin = storage.admin in - Context.Contract.storage ctxt liquidity_contract >>= fun storage -> - let storage = - Lqt_fa12_repr.Storage.of_expr_exn (Micheline.root storage) - in - let liquidity_admin = storage.admin in - Context.get_liquidity_baking_subsidy (B blk) >>=? fun subsidy -> - let env = - { - cpmm_contract; - tzbtc_contract; - tzbtc_admin; - liquidity_contract; - liquidity_admin; - implicit_accounts = accounts; - holder; - subsidy = Tez.to_mutez subsidy; - } - in - reveal_tzbtc_admin ~invariant:(fun _ _ -> pure true) env blk - >>= fun blk -> - mint_or_burn_tzbtc env.cpmm_contract cpmm_initial_balance.tzbtc env blk - >>= fun op -> - bake ~invariant:(fun _ _ -> pure true) ~baker:env.holder [op] env blk - >>= fun blk -> - (* Since Tenderbake, we need to compensate for potential deposits - related to the consensus. *) - List.fold_left_i_es - (fun idx blk contract -> - match List.nth accounts_balances idx with - | Some target -> - get_xtz_balance contract blk >>=? fun balance -> - let delta = Int64.(sub target balance) in - if Compare.Int64.(0L = delta) then - (* We need to be able to determine the number of - blocks baked in the init function (to predict the - CPMM balance). So even when there is no delta to - compensate with, we bake an empty block. *) - bake - ~invariant:(fun _ _ -> pure true) - ~baker:env.holder - [] - env - blk - else if Compare.Int64.(0L < delta) then - transaction ~src:env.holder contract delta blk >>= fun op -> - bake - ~invariant:(fun _ _ -> pure true) - ~baker:env.holder - [op] - env - blk - else assert false - | None -> assert false) - blk - accounts - >>=? fun blk -> - (* We did not check the invariant before, because the CPMM - contract was in an inconsistent state. More precisely, it - was supposed to hold tzbtc tokens, while in practice it was - not. This was solved by the last call to [bake]. *) - invariant env blk >>= fun cond -> - assert cond ; - pure (blk, env) - | _ -> assert false -end - -module ConcreteMachine = struct - include ConcreteBaseMachine - include Machine.Make (ConcreteBaseMachine) - include MachineBuilder.Make (ConcreteBaseMachine) -end - -(* --------------------------------------------------------------------------- *) - -(** {1 Abstract Machines} *) - -type 'a state = { - cpmm_total_liquidity : liquidity; - accounts_balances : ('a * balances) list; -} - -let refine_state env state = - { - cpmm_total_liquidity = state.cpmm_total_liquidity; - accounts_balances = - List.map - (fun (c, b) -> (refine_contract env c, b)) - state.accounts_balances; - } - -let update_balances account f state = - match List.assoc ~equal:( = ) account state.accounts_balances with - | Some b -> - { - state with - accounts_balances = - (account, f b) - :: List.remove_assoc ~equal:( = ) account state.accounts_balances; - } - | _ -> assert false - -let update_xtz_balance account f = - update_balances account (fun b -> {b with xtz = f b.xtz}) - -let update_tzbtc_balance account f = - update_balances account (fun b -> {b with tzbtc = f b.tzbtc}) - -let update_liquidity_balance account f = - update_balances account (fun b -> {b with liquidity = f b.liquidity}) - -let transfer_xtz_balance src dest d st = - update_xtz_balance src (fun b -> Int64.sub b d) st - |> update_xtz_balance dest (fun b -> Int64.add b d) - -let transfer_tzbtc_balance src dest d st = - update_tzbtc_balance src (fun b -> b - d) st - |> update_tzbtc_balance dest (fun b -> d + b) - -module AbstractMachine = struct - module type C = sig - type t - - val pp : Format.formatter -> t -> unit - end - - module Make (C : C) : - MACHINE with type 'a m = 'a and type contract = C.t and type t = C.t state = - struct - type 'a m = 'a - - type contract = C.t - - type t = C.t state - - type operation = t -> t - - let pp_contract = C.pp - - let ( >>= ) x f = f x - - let pure = Fun.id - - let fold_m = List.fold_left - - let get_balances account state = - match List.assoc ~equal:( = ) account state.accounts_balances with - | Some x -> x - | _ -> assert false - - let get_xtz_balance account state = (get_balances account state).xtz - - let get_tzbtc_balance account _env state = - (get_balances account state).tzbtc - - let get_liquidity_balance account _env state = - (get_balances account state).liquidity - - let get_balances account _env state = get_balances account state - - let get_cpmm_total_liquidity _env state = state.cpmm_total_liquidity - - let reveal _pk _state state = state - - let transaction ~src dst amount _ state = - transfer_xtz_balance src dst amount state - - let xtz_bought tzbtc env state = - let xtzPool = - Tez.of_mutez_exn @@ get_xtz_balance env.cpmm_contract state - in - let tokenPool = - Z.of_int @@ get_tzbtc_balance env.cpmm_contract env state - in - let tokensSold = Z.of_int tzbtc in - let (xtz_bought, xtz_net_bought) = - Cpmm_logic.Simulate_raw.tokenToXtz ~xtzPool ~tokenPool ~tokensSold - in - (Z.to_int64 xtz_net_bought, Tez.to_mutez xtz_bought) - - let token_to_xtz ~src dst amount env _ state = - let (xtz_bought, xtz_net_bought) = xtz_bought amount env state in - state - |> transfer_tzbtc_balance src env.cpmm_contract amount - |> update_xtz_balance env.cpmm_contract (fun b -> Int64.sub b xtz_bought) - |> update_xtz_balance dst (Int64.add xtz_net_bought) - - let tzbtc_bought env state amount = - let xtzPool = - Tez.of_mutez_exn @@ get_xtz_balance env.cpmm_contract state - in - let tokenPool = - Z.of_int @@ get_tzbtc_balance env.cpmm_contract env state - in - let amount = Tez.of_mutez_exn amount in - let (tzbtc_bought, xtz_earnt) = - Cpmm_logic.Simulate_raw.xtzToToken ~xtzPool ~tokenPool ~amount - in - (Z.to_int tzbtc_bought, Z.to_int64 xtz_earnt) - - let xtz_to_token ~src dst amount env _ state = - let (tzbtc_bought, xtz_earnt) = tzbtc_bought env state amount in - update_xtz_balance src (fun b -> Int64.sub b amount) state - |> update_xtz_balance env.cpmm_contract (Int64.add xtz_earnt) - |> transfer_tzbtc_balance env.cpmm_contract dst tzbtc_bought - - let mint_or_burn_tzbtc target amount _ _ = - update_tzbtc_balance target (( + ) amount) - - let approve_tzbtc _contract _amount _env _state = Fun.id - - let add_liquidity ~src dst xtz_deposit _tzbtc_deposit env _ state = - let xtzPool = - Tez.of_mutez_exn (get_xtz_balance env.cpmm_contract state) - in - let tokenPool = - Z.of_int (get_tzbtc_balance env.cpmm_contract env state) - in - let lqtTotal = Z.of_int state.cpmm_total_liquidity in - let amount = Tez.of_mutez_exn xtz_deposit in - let (lqt_minted, tokens_deposited) = - Cpmm_logic.Simulate_raw.addLiquidity - ~tokenPool - ~xtzPool - ~lqtTotal - ~amount - in - let lqt_minted = Z.to_int lqt_minted in - let tokens_deposited = Z.to_int tokens_deposited in - let state = - transfer_xtz_balance src env.cpmm_contract xtz_deposit state - |> transfer_tzbtc_balance src env.cpmm_contract tokens_deposited - |> update_liquidity_balance dst (( + ) lqt_minted) - in - { - state with - cpmm_total_liquidity = state.cpmm_total_liquidity + lqt_minted; - } - - let remove_liquidity ~src dst lqt_burned env _ state = - let xtzPool = - Tez.of_mutez_exn (get_xtz_balance env.cpmm_contract state) - in - let tokenPool = - Z.of_int (get_tzbtc_balance env.cpmm_contract env state) - in - let lqtTotal = Z.of_int state.cpmm_total_liquidity in - let lqtBurned = Z.of_int lqt_burned in - let (xtz_withdrawn, tokens_withdrawn) = - Cpmm_logic.Simulate_raw.removeLiquidity - ~tokenPool - ~xtzPool - ~lqtTotal - ~lqtBurned - in - let xtz_withdrawn = Tez.to_mutez xtz_withdrawn in - let tokens_withdrawn = Z.to_int tokens_withdrawn in - let state = - update_xtz_balance dst (fun b -> Int64.add b xtz_withdrawn) state - |> update_tzbtc_balance dst (( + ) tokens_withdrawn) - |> update_liquidity_balance src (fun b -> b - lqt_burned) - |> update_xtz_balance env.cpmm_contract (fun b -> - Int64.sub b xtz_withdrawn) - |> update_tzbtc_balance env.cpmm_contract (fun b -> - b - tokens_withdrawn) - in - { - state with - cpmm_total_liquidity = state.cpmm_total_liquidity - lqt_burned; - } - - (* Ideally, we should also deal with the release of security - deposit, but since our tests are not long enough for this to - happen, we omit this aspect of the simulation. *) - let bake ~invariant ~baker operations env state = - let state = - update_xtz_balance env.cpmm_contract (Int64.add env.subsidy) state - |> (fun state -> List.fold_left ( |> ) state operations) - |> update_xtz_balance baker (fun b -> Int64.sub b security_deposit) - in - assert (invariant env state) ; - state - end -end - -(* --------------------------------------------------------------------------- *) - -(** {1 Symbolic Machine} *) - -module SymbolicBaseMachine : - MACHINE_WITH_INIT - with type 'a m = 'a - and type contract = contract_id - and type t = contract_id state = struct - include AbstractMachine.Make (struct - type t = contract_id - - let pp = pp_contract_id - end) - - let init ~invariant:_ ?(subsidy = default_subsidy) accounts_balances = - let (_, initial_balances) = initial_xtz_repartition accounts_balances in - let len = Int64.of_int (List.length accounts_balances) in - match initial_balances with - | holder_xtz :: accounts -> - let xtz_cpmm = - Int64.( - add cpmm_initial_balance.xtz (mul (blocks_during_init len) subsidy)) - in - ( { - cpmm_total_liquidity = cpmm_initial_liquidity_supply; - accounts_balances = - (Cpmm, {cpmm_initial_balance with xtz = xtz_cpmm}) - :: - (Holder, {xtz = holder_xtz; tzbtc = 0; liquidity = 0}) - :: - (TzBTCAdmin, {xtz = 0L; tzbtc = 0; liquidity = 0}) - :: - List.mapi - (fun i xtz -> - (ImplicitAccount i, {xtz; tzbtc = 0; liquidity = 0})) - accounts; - }, - { - cpmm_contract = Cpmm; - tzbtc_contract = TzBTC; - tzbtc_admin = TzBTCAdmin; - liquidity_contract = Liquidity; - liquidity_admin = LiquidityAdmin; - implicit_accounts = - List.mapi (fun i _ -> ImplicitAccount i) accounts; - holder = Holder; - subsidy; - } ) - | [] -> assert false -end - -module SymbolicMachine = struct - include SymbolicBaseMachine - include Machine.Make (SymbolicBaseMachine) - include MachineBuilder.Make (SymbolicBaseMachine) -end - -(* --------------------------------------------------------------------------- *) - -(** {1 Validation Machine} *) - -module ValidationBaseMachine : - MACHINE_WITH_INIT - with type 'a m = 'a ConcreteBaseMachine.m - and type t = ConcreteBaseMachine.t * Contract.t state - and type contract = Contract.t = struct - module GhostMachine = AbstractMachine.Make (struct - type t = Contract.t - - let pp = Contract.pp - end) - - type 'a m = 'a ConcreteBaseMachine.m - - type t = ConcreteBaseMachine.t * GhostMachine.t - - type contract = Contract.t - - type operation = ConcreteBaseMachine.operation * GhostMachine.operation - - let pp_contract = Contract.pp - - let ( >>= ) = ConcreteBaseMachine.( >>= ) - - let fold_m = ConcreteBaseMachine.fold_m - - let pure = ConcreteBaseMachine.pure - - let get_balances contract env (_, state) = - pure (GhostMachine.get_balances contract env state) - - let get_xtz_balance contract (_, state) = - pure (GhostMachine.get_xtz_balance contract state) - - let get_tzbtc_balance contract env (_, state) = - pure (GhostMachine.get_tzbtc_balance contract env state) - - let get_liquidity_balance contract env (_, state) = - pure (GhostMachine.get_liquidity_balance contract env state) - - let get_cpmm_total_liquidity env (_, state) = - pure (GhostMachine.get_cpmm_total_liquidity env state) - - let bake ~invariant ~baker ops env (blk, state) = - let cops = List.map fst ops in - let rops = List.map snd ops in - ConcreteBaseMachine.( - bake ~invariant:(fun _ _ -> pure true) ~baker cops env blk) - >>= fun blk -> - let state = - GhostMachine.bake ~invariant:(fun _ _ -> true) ~baker rops env state - in - invariant env (blk, state) >>= fun cond -> - assert cond ; - pure (blk, state) - - let transaction ~src dst xtz (blk, state) = - ConcreteBaseMachine.transaction ~src dst xtz blk >>= fun cop -> - pure (cop, GhostMachine.transaction ~src dst xtz state) - - let token_to_xtz ~src dst tzbtc env (blk, state) = - ConcreteBaseMachine.token_to_xtz ~src dst tzbtc env blk >>= fun cop -> - pure (cop, GhostMachine.token_to_xtz ~src dst tzbtc env state) - - let xtz_to_token ~src dst xtz env (blk, state) = - ConcreteBaseMachine.xtz_to_token ~src dst xtz env blk >>= fun cop -> - pure (cop, GhostMachine.xtz_to_token ~src dst xtz env state) - - let mint_or_burn_tzbtc dst tzbtc env (blk, state) = - ConcreteBaseMachine.mint_or_burn_tzbtc dst tzbtc env blk >>= fun cop -> - pure (cop, GhostMachine.mint_or_burn_tzbtc dst tzbtc env state) - - let approve_tzbtc dst tzbtc env (blk, state) = - ConcreteBaseMachine.approve_tzbtc dst tzbtc env blk >>= fun cop -> - pure (cop, GhostMachine.approve_tzbtc dst tzbtc env state) - - let add_liquidity ~src dst xtz_deposit tzbtc_deposit env (blk, state) = - ConcreteBaseMachine.add_liquidity ~src dst xtz_deposit tzbtc_deposit env blk - >>= fun cop -> - pure - ( cop, - GhostMachine.add_liquidity ~src dst xtz_deposit tzbtc_deposit env state - ) - - let remove_liquidity ~src dst lqt_burned env (blk, state) = - ConcreteBaseMachine.remove_liquidity ~src dst lqt_burned env blk - >>= fun cop -> - pure (cop, GhostMachine.remove_liquidity ~src dst lqt_burned env state) - - let reveal account (blk, state) = - ConcreteBaseMachine.reveal account blk >>= fun cop -> - pure (cop, GhostMachine.reveal account state) - - let init ~invariant ?subsidy balances = - ConcreteBaseMachine.init - ~invariant:(fun _ _ -> return true) - ?subsidy - balances - >>= fun (blk, env) -> - let (state, _) = - SymbolicBaseMachine.init ~invariant:(fun _ _ -> true) ?subsidy balances - in - let state = refine_state env state in - invariant env (blk, state) >>= fun cond -> - assert cond ; - pure ((blk, state), env) -end - -module ValidationMachine = struct - include ValidationBaseMachine - include Machine.Make (ValidationBaseMachine) - include MachineBuilder.Make (ValidationBaseMachine) - - module Symbolic = struct - let get_xtz_balance = get_xtz_balance - - let get_tzbtc_balance = get_tzbtc_balance - - let get_liquidity_balance = get_liquidity_balance - - let get_cpmm_total_liquidity = get_cpmm_total_liquidity - end - - module Concrete = struct - let get_xtz_balance contract (blk, _) = - ConcreteMachine.get_xtz_balance contract blk - - let get_tzbtc_balance contract env (blk, _) = - ConcreteMachine.get_tzbtc_balance contract env blk - - let get_liquidity_balance contract env (blk, _) = - ConcreteMachine.get_liquidity_balance contract env blk - - let get_cpmm_total_liquidity env (blk, _) = - ConcreteMachine.get_cpmm_total_liquidity env blk - end -end diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.mli deleted file mode 100644 index 76107f8b4d61..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/liquidity_baking_machine.mli +++ /dev/null @@ -1,387 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -(** This module provides the means to test extensively the Liquidity - Baking (LB) feature. We recall that this feature is built upon - three smart contracts: (1) a CPMM contract initially based on - Dexter 2, and (2) two tokens contracts. Our objective is to run - “scenarios” consisting in interleaved, realistic calls to these - contracts, and to assert these scenarios do not yield any - undesirable behaviors. - - To that end, three “machines” are provided. - - - The {! SymbolicMachine} allows to simulate scenarios involving - the LB feature completely off-chain. It can be seen as an - abstraction of the concrete implementation provided by the Tezos - node. - - The {! ConcreteMachine } allows to execute scenarios on-chain. - - The {! ValidationMachine } combines the two previously mentioned - machines. In other words, the {! ValidationMachine} makes the {! - SymbolicMachine} and the [ConcreteMachine] execute the same - scenarios, and asserts they remain synchronized after each baked - block. - - The {! ValidationMachine} allows to (1) validate the {! - SymbolicMachine} ({i i.e.,} the reimplementation of the LB - contracts logic) against the real implementation provided by - Tezos, {b and} the contracts originated by the protocol correctly - implement the LB logic, as implemented by the {! SymbolicMachine}. - That is, the {! ValidationMachine} reports desynchronization of - the two machines, but cannot explain this desynchronization. *) - -(** {1 Machine State Characterization} *) - -type xtz = int64 - -type tzbtc = int - -type liquidity = int - -(** As far as liquidity baking is concerned, an account can hold three - kinds of tokens: [xtz], [tzbtc], and [liquidity]. *) -type balances = {xtz : xtz; tzbtc : tzbtc; liquidity : liquidity} - -val pp_balances : Format.formatter -> balances -> unit - -(** A value of type [specs] allows to specify an initial state of a - “machine”. - - In a nutshell, it consists in specifying the minimal balances of - the CPMM contracts and a set of implicit contracts. The two - machines provided by this module has a [build] function which - turns a [specs] into a consistent initial state for this - machine. *) -type specs = { - cpmm_min_xtz_balance : xtz; - cpmm_min_tzbtc_balance : tzbtc; - accounts_balances : balances list; -} - -val pp_specs : Format.formatter -> specs -> unit - -(** A value of type ['a env] (where ['a] is the type of contract - identifiers) summarizes the different contracts involved in the LB - feature. - - Values of type [env] are constructed by the [build] function of - the machines. *) -type 'a env = private { - cpmm_contract : 'a; - tzbtc_contract : 'a; - tzbtc_admin : 'a; - liquidity_contract : 'a; - liquidity_admin : 'a; - implicit_accounts : 'a list; - holder : 'a; - subsidy : xtz; -} - -(** A value of type ['a step] (where ['a] is the type used to identify - contracts) describes a consistent sequence of LB smart contract - calls. - - For instance, [SellTzBTC] consists in approving an allowance in - the [TzBTC] contract, then calling the [token_to_xtz] entry point - of the [CPMM]. *) -type 'a step = - | SellTzBTC of {source : 'a; destination : 'a; tzbtc_deposit : tzbtc} - | BuyTzBTC of {source : 'a; destination : 'a; xtz_deposit : xtz} - | AddLiquidity of {source : 'a; destination : 'a; xtz_deposit : xtz} - | RemoveLiquidity of {source : 'a; destination : 'a; lqt_burned : liquidity} - -val pp_step : - (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a step -> unit - -(** A summary of the state of a machine, parameterized by the type of - contract identifier. *) -type 'a state = { - cpmm_total_liquidity : liquidity; - accounts_balances : ('a * balances) list; -} - -(** {1 The Symbolic Machine} *) - -(** In the {! SymbolicMachine}, a contract is identified by a symbolic - value. *) -type contract_id = - | Cpmm - | Holder - | TzBTC - | TzBTCAdmin - | Liquidity - | LiquidityAdmin - (* We use integers to distinguish between implicit account because - this integer has the extra benefit of being the index of the - related account in [env.implicit_accounts]. *) - | ImplicitAccount of int - -val pp_contract_id : Format.formatter -> contract_id -> unit - -module SymbolicMachine : sig - (** The state of the {! SymbolicMachine}. *) - type t = contract_id state - - (** [get_xtz_balance c state] returns the amount of mutez owned by - [c] in [state]. *) - val get_xtz_balance : contract_id -> t -> xtz - - (** [get_tzbtc_balance c env state] returns the amount of TzBTC - owned by [c] in [state], according to the [TzBTC] contract. *) - val get_tzbtc_balance : contract_id -> contract_id env -> t -> tzbtc - - (** [get_liquidity_balance c env state] returns the amount of - liquidity token owned by [c] in [state], according to the - [Liquidity] contract. *) - val get_liquidity_balance : contract_id -> contract_id env -> t -> liquidity - - (** [get_cpmm_total_liquidity env state] fetches the current amount - of liquidity tokens distributed by the CPMM contract from the - state [state]. *) - val get_cpmm_total_liquidity : contract_id env -> t -> liquidity - - (** [predict_required_tzbtc_deposit xtz_deposit env state] predicts - the deposit in TzBTC which will be required by the CPMM contract - when executing a step [AddLiquidity] with [xtz_deposit] from - [state]. *) - val predict_required_tzbtc_deposit : xtz -> contract_id env -> t -> tzbtc - - (** [build specs] computes (1) an initial state for the {! - SymbolicMachine}, and (2) the environment associated to this - state. - - The machine enforces the resulting state is consistent with the - [specs] given as inputs, and raises an [Assert_failure] - exception if it does not. - - One can use the optional argument [subsidy] to set the subsidy - amount to a given value (by default, we use the same as the main - chain). Additionally, the [invariant] optional argument can be - used to verify that a given invariant holds at the end of the - initialization. *) - val build : - ?invariant:(contract_id env -> t -> bool) -> - ?subsidy:xtz -> - specs -> - t * contract_id env - - (** [step s env state] executes a single step [s] from [state]. - - The [invariant] optional argument can be used to verify that a - given invariant holds after each baked block. *) - val step : - ?invariant:(contract_id env -> t -> bool) -> - contract_id step -> - contract_id env -> - t -> - t - - (** [run steps env state] executes a list of steps from [state]. - - The [invariant] optional argument can be used to verify that a - given invariant holds after each baked block. *) - val run : - ?invariant:(contract_id env -> t -> bool) -> - contract_id step list -> - contract_id env -> - t -> - t -end - -(** A machine that can execute scenarios onchain. *) -module ConcreteMachine : sig - (** The state of the {! ConcreteMachine}. *) - type t = Block.t - - (** [get_xtz_balance c state] returns the amount of mutez owned by - [c] in [state]. *) - val get_xtz_balance : Contract.t -> t -> xtz tzresult Lwt.t - - (** [get_tzbtc_balance c env state] returns the amount of TzBTC - owned by [c] in [state], according to the [TzBTC] contract. *) - val get_tzbtc_balance : - Contract.t -> Contract.t env -> t -> tzbtc tzresult Lwt.t - - (** [get_liquidity_balance c env state] returns the amount of - liquidity token owned by [c] in [state], according to the - [Liquidity] contract. *) - val get_liquidity_balance : - Contract.t -> Contract.t env -> t -> liquidity tzresult Lwt.t - - (** [get_cpmm_total_liquidity env state] fetches the current amount - of liquidity tokens distributed by the CPMM contract from the - state [state]. *) - val get_cpmm_total_liquidity : Contract.t env -> t -> liquidity tzresult Lwt.t - - (** [build specs] asynchronously computes (1) an initial block for - the {! ConcreteMachine}, and (2) the environment associated to - this block. - - The machine enforces the resulting state is consistent with the - [specs] given as inputs, and raises an [Assert_failure] - exception if it does not. It also enforces that the machines - used underneath remain in sync. - - One can use the optional argument [subsidy] to set the subsidy - amount to a given value (by default, we use the same as the main - chain). Additionally, the [invariant] optional argument can be - used to verify that a given invariant holds at the end of the - initialization. *) - val build : - ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> - ?subsidy:xtz -> - specs -> - (t * Contract.t env) tzresult Lwt.t - - (** [step s env state] asynchronously executes a single step [s] - from [state]. - - The [invariant] optional argument can be used to verify that a - given invariant holds after each baked block. *) - val step : - ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> - Contract.t step -> - Contract.t env -> - t -> - t tzresult Lwt.t - - (** [run lss env state] asynchronously executes a list of steps from - [state]. - - The [invariant] optional argument can be used to verify that a - given invariant holds after each baked block. *) - val run : - ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> - contract_id step list -> - Contract.t env -> - t -> - t tzresult Lwt.t -end - -module ValidationMachine : sig - (** The state of the {! ValidationMachine}. *) - type t = ConcreteMachine.t * Contract.t state - - module Symbolic : sig - (** A collections of functions to introspect the symbolic part of - the [ValidationMachine] state. *) - - (** [get_xtz_balance c state] returns the amount of mutez owned by - [c] in the symbolic part of [state]. *) - val get_xtz_balance : Contract.t -> t -> xtz tzresult Lwt.t - - (** [get_tzbtc_balance c env state] returns the amount of TzBTC - owned by [c] in the symbolic part of [state], according to the - [TzBTC] contract. *) - val get_tzbtc_balance : - Contract.t -> Contract.t env -> t -> tzbtc tzresult Lwt.t - - (** [get_liquidity_balance c env state] returns the amount of - liquidity token owned by [c] in the symbolic part of [state], - according to the [Liquidity] contract. *) - val get_liquidity_balance : - Contract.t -> Contract.t env -> t -> liquidity tzresult Lwt.t - - (** [get_cpmm_total_liquidity env state] fetches the   current - amount of liquidity tokens distributed by the CPMM   contract - using the symbolic part of the state [state]. *) - val get_cpmm_total_liquidity : - Contract.t env -> t -> liquidity tzresult Lwt.t - end - - module Concrete : sig - (** A collections of functions to introspect the concrete part of - the [ValidationMachine] state. *) - - (** [get_xtz_balance c state] returns the amount of mutez owned by - [c] in the concrete part of [state]. *) - val get_xtz_balance : Contract.t -> t -> xtz tzresult Lwt.t - - (** [get_tzbtc_balance c env state] returns the amount of TzBTC - owned by [c] in the concrete part of [state], according to the - [TzBTC] contract. *) - val get_tzbtc_balance : - Contract.t -> Contract.t env -> t -> tzbtc tzresult Lwt.t - - (** [get_liquidity_balance c env state] returns the amount of - liquidity token owned by [c] in the concrete part of [state], - according to the [Liquidity] contract. *) - val get_liquidity_balance : - Contract.t -> Contract.t env -> t -> liquidity tzresult Lwt.t - - (** [get_cpmm_total_liquidity env state] fetches the current - amount of liquidity tokens distributed by the CPMM contract - using the concrete part of the state [state]. *) - val get_cpmm_total_liquidity : - Contract.t env -> t -> liquidity tzresult Lwt.t - end - - (** [build specs] asynchronously computes (1) an initial state for - the {! ValidationMachine}, and (2) the environment associated to - this state. - - The machine enforces the resulting state is consistent with the - [specs] given as inputs, and raises an [Assert_failure] - exception if it does not. It also enforces that the machines - used underneath remain in sync. - - One can use the optional argument [subsidy] to set the subsidy - amount to a given value (by default, we use the same as the main - chain). Additionally, the [invariant] optional argument can be - used to verify that a given invariant holds at the end of the - initialization. *) - val build : - ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> - ?subsidy:xtz -> - specs -> - (t * Contract.t env) tzresult Lwt.t - - (** [step s env state] asynchronously executes a single step [s] - from [state]. - - The [invariant] optional argument can be used to verify that a - given invariant holds after each baked block. *) - val step : - ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> - Contract.t step -> - Contract.t env -> - t -> - t tzresult Lwt.t - - (** [run lss env state] asynchronously executes a list of steps from - [state]. - - The [invariant] optional argument can be used to verify that a - given invariant holds after each baked block. *) - val run : - ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> - contract_id step list -> - Contract.t env -> - t -> - t tzresult Lwt.t -end diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/lqt_fa12_repr.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/lqt_fa12_repr.ml deleted file mode 100644 index 937dfb8297b2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/lqt_fa12_repr.ml +++ /dev/null @@ -1,252 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Expr_common - -module Parameter = struct - (* // ============================================================================= - * // Entrypoints - * // ============================================================================= *) - - (* Note: in the lqt_fa12 contract, [value] is a nat. Hence, it - should always be positive *) - type approve = {spender : Contract.t; value : Z.t} - - type mintOrBurn = {quantity : Z.t; target : Contract.t} - - (* Note: this wrapper does not implement a reprensentation for the - entrypoints transfer, getAllowance, getBalance, getTotalSupply, - as they are not used as of yet. *) - type t = Approve of approve | MintOrBurn of mintOrBurn - - let approve p = - assert (Z.lt Z.zero p.value || Z.equal Z.zero p.value) ; - Approve p - - let mintOrBurn p = MintOrBurn p - - let approve_to_string {spender; value} = - Format.asprintf - "{ spender: %a; value: %a }" - Contract.pp - spender - Z.pp_print - value - - let mint_or_burn_to_string {quantity; target} = - Format.asprintf - "{ quantity: %a; target: %a }" - Z.pp_print - quantity - Contract.pp - target - - let to_string : t -> string = function - | Approve p -> Format.asprintf "Approve %s" (approve_to_string p) - | MintOrBurn p -> Format.asprintf "MintOrBurn %s" (mint_or_burn_to_string p) - - let entrypoint_of_parameter : t -> string = function - | Approve _ -> "approve" - | MintOrBurn _ -> "mintOrBurn" - - let pp fmt s = Format.fprintf fmt "%s" (to_string s) - - let eq s s' = s = s' - - let to_expr_rooted : - loc:'a -> - t -> - ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = - fun ~loc -> function - | MintOrBurn {quantity; target} -> - comb ~loc [int ~loc quantity; address_string ~loc target] - | Approve {spender; value} -> - comb ~loc [address_string ~loc spender; int ~loc value] - - let to_expr : - loc:'a -> - t -> - ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = - fun ~loc p -> - let rooted = to_expr_rooted ~loc p in - match p with - | MintOrBurn _ -> right ~loc @@ left ~loc rooted - | Approve _ -> left ~loc @@ left ~loc @@ left ~loc rooted - - let to_michelson_string e = - let e = to_expr ~loc:0 e in - Format.asprintf - "%a" - Michelson_v1_printer.print_expr - (Micheline.strip_locations e) -end - -(* // ============================================================================= - * // Storage - * // ============================================================================= *) - -module Storage = struct - let pp_big_map_id fmt v = Z.pp_print fmt (Big_map.Id.unparse_to_z v) - - type t = { - tokens : Big_map.Id.t; - allowances : Big_map.Id.t; - admin : Contract.t; - totalSupply : Z.t; - } - - let pp {tokens; allowances; admin; totalSupply} = - Format.asprintf - "{ tokens: %a; allowances: %a; admin: %a; totalSupply: %a}" - Z.pp_print - (Big_map.Id.unparse_to_z tokens) - Z.pp_print - (Big_map.Id.unparse_to_z allowances) - Contract.pp - admin - Z.pp_print - totalSupply - - let null : t = - { - tokens = Big_map.Id.parse_z Z.zero; - allowances = Big_map.Id.parse_z Z.one; - admin = Contract.implicit_contract Signature.Public_key_hash.zero; - totalSupply = Z.zero; - } - - let eq s s' = s = s' - - let to_expr : - loc:'a -> - t -> - ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = - fun ~loc {tokens; allowances; admin; totalSupply} -> - comb - ~loc - [ - big_map_id ~loc tokens; - big_map_id ~loc allowances; - address_string ~loc admin; - int ~loc totalSupply; - ] - - let to_michelson_string e = - let e = to_expr ~loc:0 e in - Format.asprintf - "%a" - Michelson_v1_printer.print_expr - (Micheline.strip_locations e) - - type exn += Invalid_storage_expr of string - - (** Note: parses a storage unparsed in readable mode (as - e.g. returned by [Alpha_services.Contract.storage]), so that - contracts are represented by strings. *) - let of_expr_exn : - ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node -> t = - function - | Tezos_micheline.Micheline.Prim - ( _, - Script.D_Pair, - [ - Tezos_micheline.Micheline.Int (_, tokens); - Tezos_micheline.Micheline.Int (_, allowances); - Tezos_micheline.Micheline.String (_, admin); - Tezos_micheline.Micheline.Int (_, totalSupply); - ], - [] ) -> - let tokens = Big_map.Id.parse_z tokens in - let allowances = Big_map.Id.parse_z allowances in - let admin = address_of_string_exn admin in - {tokens; allowances; admin; totalSupply} - | e -> - let canonical = Micheline.strip_locations e in - let msg = - Format.asprintf - "Not a valid LQT_FA1.2 storage: %s /// %a" - (try - Michelson_v1_printer.micheline_string_of_expression - ~zero_loc:true - canonical - with Z.Overflow -> - "Cannot represent as micheline due to overflowing Z -> int") - Michelson_v1_printer.print_expr - canonical - in - raise (Invalid_storage_expr msg) - - let get (ctxt : Context.t) ~(contract : Contract.t) : t tzresult Lwt.t = - Context.Contract.storage ctxt contract >|=? Micheline.root >|=? of_expr_exn - - let get_alpha_context (ctxt : Context.t) : Alpha_context.t tzresult Lwt.t = - (match ctxt with - | B b -> - (* can perhaps be retrieved through Raw_context.prepare ? *) - Incremental.begin_construction b - | I i -> return i) - >|=? Incremental.alpha_ctxt - - let getBalance_opt (ctxt : Context.t) ~(contract : Contract.t) - (owner : Script_typed_ir.address) = - get ctxt ~contract >>=? fun storage -> - let tokens = storage.tokens in - get_alpha_context ctxt >>=? fun ctxt -> - Script_ir_translator.hash_data - ctxt - Script_typed_ir.(address_t ~annot:None) - owner - >|= Environment.wrap_tzresult - >>=? fun (address_hash, ctxt) -> - Big_map.get_opt ctxt tokens address_hash >|= Environment.wrap_tzresult - >>=? function - | (_, Some canonical) -> ( - match Tezos_micheline.Micheline.root canonical with - | Tezos_micheline.Micheline.Int (_, amount) -> return @@ Some amount - | _ -> assert false) - | (_, None) -> return @@ None - - let getBalance (ctxt : Context.t) ~(contract : Contract.t) - (owner : Script_typed_ir.address) = - getBalance_opt ctxt ~contract owner >|=? Option.value ~default:Z.zero -end - -let transaction (ctxt : Context.t) ~(contract : Contract.t) ~(src : Contract.t) - ?(amount = Tez.zero) (parameters : Parameter.t) = - let entrypoint = Parameter.entrypoint_of_parameter parameters in - let rooted_param_lazy = - parameters - |> Parameter.to_expr_rooted ~loc:0 - |> Micheline.strip_locations |> Alpha_context.Script.lazy_expr - in - Op.transaction - ctxt - src - contract - amount - ~entrypoint - ~parameters:rooted_param_lazy diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/nonce.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/nonce.ml deleted file mode 100644 index 695cdcdbbec9..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/nonce.ml +++ /dev/null @@ -1,35 +0,0 @@ -(**************************************************************************) -(* *) -(* Copyright (c) 2014 - 2018. *) -(* Dynamic Ledger Solutions, Inc.< contact@tezos.com > *) -(* *) -(* All rights reserved.No warranty, explicit or implicit, provided. *) -(* *) -(**************************************************************************) - -open Protocol - -module Table = Hashtbl.Make (struct - type t = Nonce_hash.t - - let hash h = Int32.to_int (TzEndian.get_int32 (Nonce_hash.to_bytes h) 0) - - let equal = Nonce_hash.equal -end) - -let known_nonces = Table.create 17 - -let generate () = - match - Alpha_context.Nonce.of_bytes - @@ Rand.generate Alpha_context.Constants.nonce_length - with - | Ok nonce -> - let hash = Alpha_context.Nonce.hash nonce in - Table.add known_nonces hash nonce ; - (hash, nonce) - | Error _ -> assert false - -let forget_all () = Table.clear known_nonces - -let get hash = Table.find known_nonces hash diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/nonce.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/nonce.mli deleted file mode 100644 index 8a8b258b0658..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/nonce.mli +++ /dev/null @@ -1,33 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** Returns a fresh nonce and its corresponding hash (and stores them). *) -val generate : unit -> Nonce_hash.t * Alpha_context.Nonce.t - -val get : Nonce_hash.t -> Alpha_context.Nonce.t option - -val forget_all : unit -> unit diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/op.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/op.ml deleted file mode 100644 index 336715cea48f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/op.ml +++ /dev/null @@ -1,476 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -let sign ?(watermark = Signature.Generic_operation) sk ctxt contents = - let branch = Context.branch ctxt in - let unsigned = - Data_encoding.Binary.to_bytes_exn - Operation.unsigned_encoding - ({branch}, Contents_list contents) - in - let signature = Some (Signature.sign ~watermark sk unsigned) in - ({shell = {branch}; protocol_data = {contents; signature}} : _ Operation.t) - -(** Generates the block payload hash based on the hash [pred_hash] of - the predecessor block and the hash of non-consensus operations of - the current block [b]. *) -let mk_block_payload_hash pred_hash payload_round (b : Block.t) = - let ops = Block.Forge.classify_operations b.operations in - let non_consensus_operations = - List.concat (match List.tl ops with None -> [] | Some l -> l) - in - let hashes = List.map Operation.hash_packed non_consensus_operations in - let non_consensus_operations_hash = Operation_list_hash.compute hashes in - Block_payload.hash - ~predecessor:pred_hash - payload_round - non_consensus_operations_hash - -(* ctxt is used for getting the branch in sign *) -let endorsement ?delegate ?slot ?level ?round ?block_payload_hash - ~endorsed_block ctxt ?(signing_context = ctxt) () = - let pred_hash = match ctxt with Context.B b -> b.hash | _ -> assert false in - (match delegate with - | None -> Context.get_endorser (B endorsed_block) - | Some v -> return v) - >>=? fun (delegate_pkh, slots) -> - let slot = - match slot with None -> Stdlib.List.hd slots | Some slot -> slot - in - (match level with - | None -> Context.get_level (B endorsed_block) - | Some level -> ok level) - >>?= fun level -> - (match round with - | None -> Block.get_round endorsed_block - | Some round -> ok round) - >>?= fun round -> - let block_payload_hash = - match block_payload_hash with - | None -> mk_block_payload_hash pred_hash round endorsed_block - | Some block_payload_hash -> block_payload_hash - in - let consensus_content = {slot; level; round; block_payload_hash} in - let op = Single (Endorsement consensus_content) in - Account.find delegate_pkh >>=? fun delegate -> - return - (sign - ~watermark:Operation.(to_watermark (Endorsement Chain_id.zero)) - delegate.sk - signing_context - op) - -let preendorsement ?delegate ?slot ?level ?round ?block_payload_hash - ~endorsed_block ctxt ?(signing_context = ctxt) () = - let pred_hash = match ctxt with Context.B b -> b.hash | _ -> assert false in - (match delegate with - | None -> Context.get_endorser (B endorsed_block) - | Some v -> return v) - >>=? fun (delegate_pkh, slots) -> - let slot = - match slot with None -> Stdlib.List.hd slots | Some slot -> slot - in - (match level with - | None -> Context.get_level (B endorsed_block) - | Some level -> ok level) - >>?= fun level -> - (match round with - | None -> Block.get_round endorsed_block - | Some round -> ok round) - >>?= fun round -> - let block_payload_hash = - match block_payload_hash with - | None -> mk_block_payload_hash pred_hash round endorsed_block - | Some block_payload_hash -> block_payload_hash - in - let consensus_content = {slot; level; round; block_payload_hash} in - let op = Single (Preendorsement consensus_content) in - Account.find delegate_pkh >>=? fun delegate -> - return - (sign - ~watermark:Operation.(to_watermark (Preendorsement Chain_id.zero)) - delegate.sk - signing_context - op) - -let sign ?watermark sk ctxt (Contents_list contents) = - Operation.pack (sign ?watermark sk ctxt contents) - -let combine_operations ?public_key ?counter ?spurious_operation ~source ctxt - (packed_operations : packed_operation list) = - assert (match packed_operations with [] -> false | _ :: _ -> true) ; - (* Hypothesis : each operation must have the same branch (is this really true?) *) - let {Tezos_base.Operation.branch} = - (WithExceptions.Option.get ~loc:__LOC__ @@ List.hd packed_operations).shell - in - assert ( - List.for_all - (fun {shell = {Tezos_base.Operation.branch = b; _}; _} -> - Block_hash.(branch = b)) - packed_operations) ; - (* TODO? : check signatures consistency *) - let unpacked_operations = - List.map - (function - | {Alpha_context.protocol_data = Operation_data {contents; _}; _} -> ( - match Contents_list contents with - | Contents_list (Single o) -> Contents o - | Contents_list - (Cons (Manager_operation {operation = Reveal _; _}, Single o)) - -> - Contents o - | _ -> (* TODO : decent error *) assert false)) - packed_operations - in - (match counter with - | Some counter -> return counter - | None -> Context.Contract.counter ctxt source) - >>=? fun counter -> - (* We increment the counter *) - let counter = Z.succ counter in - Context.Contract.manager ctxt source >>=? fun account -> - let public_key = Option.value ~default:account.pk public_key in - (Context.Contract.is_manager_key_revealed ctxt source >|=? function - | false -> - let reveal_op = - Manager_operation - { - source = Signature.Public_key.hash public_key; - fee = Tez.zero; - counter; - operation = Reveal public_key; - gas_limit = Gas.Arith.integral_of_int_exn 10_000; - storage_limit = Z.zero; - } - in - (Some (Contents reveal_op), Z.succ counter) - | true -> (None, counter)) - >>=? fun (manager_op, counter) -> - (* Update counters and transform into a contents_list *) - let operations = - List.fold_left - (fun (counter, acc) -> function - | Contents (Manager_operation m) -> - ( Z.succ counter, - Contents (Manager_operation {m with counter}) :: acc ) - | x -> (counter, x :: acc)) - (counter, match manager_op with None -> [] | Some op -> [op]) - unpacked_operations - |> snd |> List.rev - in - (* patch a random operation with a corrupted pkh *) - let operations = - match spurious_operation with - | None -> operations - | Some op -> ( - let op = - match op with - | {protocol_data; shell = _} -> ( - match protocol_data with - | Operation_data {contents; _} -> ( - match contents with - | Cons _ -> assert false - | Single op -> Alpha_context.Contents op)) - in - (* Select where to insert spurious op *) - let legit_ops = List.length operations in - let index = Random.int legit_ops in - match List.split_n index operations with - | (preserved_prefix, preserved_suffix) -> - preserved_prefix @ op :: preserved_suffix) - in - Environment.wrap_tzresult @@ Operation.of_list operations - >>?= fun operations -> return @@ sign account.sk ctxt operations - -let manager_operation ?counter ?(fee = Tez.zero) ?gas_limit ?storage_limit - ?public_key ~source ctxt operation = - (match counter with - | Some counter -> return counter - | None -> Context.Contract.counter ctxt source) - >>=? fun counter -> - Context.get_constants ctxt >>=? fun c -> - let gas_limit = - let default = c.parametric.hard_gas_limit_per_operation in - Option.value ~default gas_limit - in - let storage_limit = - Option.value - ~default:c.parametric.hard_storage_limit_per_operation - storage_limit - in - Context.Contract.manager ctxt source >>=? fun account -> - let public_key = Option.value ~default:account.pk public_key in - let counter = Z.succ counter in - Context.Contract.is_manager_key_revealed ctxt source >|=? function - | true -> - let op = - Manager_operation - { - source = Signature.Public_key.hash public_key; - fee; - counter; - operation; - gas_limit; - storage_limit; - } - in - Contents_list (Single op) - | false -> - let op_reveal = - Manager_operation - { - source = Signature.Public_key.hash public_key; - fee = Tez.zero; - counter; - operation = Reveal public_key; - gas_limit = Gas.Arith.integral_of_int_exn 10000; - storage_limit = Z.zero; - } - in - let op = - Manager_operation - { - source = Signature.Public_key.hash public_key; - fee; - counter = Z.succ counter; - operation; - gas_limit; - storage_limit; - } - in - Contents_list (Cons (op_reveal, Single op)) - -let revelation ?(fee = Tez.zero) ctxt public_key = - let pkh = Signature.Public_key.hash public_key in - let source = Contract.implicit_contract pkh in - Context.Contract.counter ctxt source >>=? fun counter -> - Context.Contract.manager ctxt source >|=? fun account -> - let counter = Z.succ counter in - let sop = - Contents_list - (Single - (Manager_operation - { - source = Signature.Public_key.hash public_key; - fee; - counter; - operation = Reveal public_key; - gas_limit = Gas.Arith.integral_of_int_exn 10000; - storage_limit = Z.zero; - })) - in - sign account.sk ctxt sop - -let failing_noop ctxt source arbitrary = - let op = Contents_list (Single (Failing_noop arbitrary)) in - Account.find source >>=? fun account -> return @@ sign account.sk ctxt op - -let originated_contract op = - let nonce = Contract.initial_origination_nonce (Operation.hash_packed op) in - Contract.originated_contract nonce - -exception Impossible - -let origination ?counter ?delegate ~script ?(preorigination = None) ?public_key - ?credit ?fee ?gas_limit ?storage_limit ctxt source = - Context.Contract.manager ctxt source >>=? fun account -> - let default_credit = Tez.of_mutez @@ Int64.of_int 1000001 in - let default_credit = - WithExceptions.Option.to_exn ~none:Impossible default_credit - in - let credit = Option.value ~default:default_credit credit in - let operation = Origination {delegate; script; credit; preorigination} in - manager_operation - ?counter - ?public_key - ?fee - ?gas_limit - ?storage_limit - ~source - ctxt - operation - >|=? fun sop -> - let op = sign account.sk ctxt sop in - (op, originated_contract op) - -let register_global_constant ?counter ?public_key ?fee ?gas_limit ?storage_limit - ctxt ~source ~value = - Context.Contract.manager ctxt source >>=? fun account -> - let operation = Register_global_constant {value} in - manager_operation - ?counter - ?public_key - ?fee - ?gas_limit - ?storage_limit - ~source - ctxt - operation - >|=? fun sop -> sign account.sk ctxt sop - -let miss_signed_endorsement ?level ~endorsed_block ctxt = - (match level with None -> Context.get_level ctxt | Some level -> ok level) - >>?= fun level -> - Context.get_endorser ctxt >>=? fun (real_delegate_pkh, slots) -> - let delegate = Account.find_alternate real_delegate_pkh in - endorsement ~delegate:(delegate.pkh, slots) ~level ~endorsed_block ctxt () - -let transaction ?counter ?fee ?gas_limit ?storage_limit - ?(parameters = Script.unit_parameter) ?(entrypoint = "default") ctxt - (src : Contract.t) (dst : Contract.t) (amount : Tez.t) = - let top = Transaction {amount; parameters; destination = dst; entrypoint} in - manager_operation ?counter ?fee ?gas_limit ?storage_limit ~source:src ctxt top - >>=? fun sop -> - Context.Contract.manager ctxt src >|=? fun account -> sign account.sk ctxt sop - -let delegation ?fee ctxt source dst = - let top = Delegation dst in - manager_operation - ?fee - ~gas_limit:(Gas.Arith.integral_of_int_exn 1000) - ~source - ctxt - top - >>=? fun sop -> - Context.Contract.manager ctxt source >|=? fun account -> - sign account.sk ctxt sop - -let set_deposits_limit ?fee ctxt source limit = - let top = Set_deposits_limit limit in - manager_operation - ?fee - ~gas_limit:(Gas.Arith.integral_of_int_exn 1000) - ~source - ctxt - top - >>=? fun sop -> - Context.Contract.manager ctxt source >|=? fun account -> - sign account.sk ctxt sop - -let activation ctxt (pkh : Signature.Public_key_hash.t) activation_code = - (match pkh with - | Ed25519 edpkh -> return edpkh - | _ -> - failwith - "Wrong public key hash : %a - Commitments must be activated with an \ - Ed25519 encrypted public key hash" - Signature.Public_key_hash.pp - pkh) - >|=? fun id -> - let contents = Single (Activate_account {id; activation_code}) in - let branch = Context.branch ctxt in - { - shell = {branch}; - protocol_data = Operation_data {contents; signature = None}; - } - -let double_endorsement ctxt op1 op2 = - let contents = Single (Double_endorsement_evidence {op1; op2}) in - let branch = Context.branch ctxt in - { - shell = {branch}; - protocol_data = Operation_data {contents; signature = None}; - } - -let double_preendorsement ctxt op1 op2 = - let contents = Single (Double_preendorsement_evidence {op1; op2}) in - let branch = Context.branch ctxt in - { - shell = {branch}; - protocol_data = Operation_data {contents; signature = None}; - } - -let double_baking ctxt bh1 bh2 = - let contents = Single (Double_baking_evidence {bh1; bh2}) in - let branch = Context.branch ctxt in - { - shell = {branch}; - protocol_data = Operation_data {contents; signature = None}; - } - -let seed_nonce_revelation ctxt level nonce = - { - shell = {branch = Context.branch ctxt}; - protocol_data = - Operation_data - { - contents = Single (Seed_nonce_revelation {level; nonce}); - signature = None; - }; - } - -let proposals ctxt (pkh : Contract.t) proposals = - Context.Contract.pkh pkh >>=? fun source -> - Context.Vote.get_current_period ctxt - >>=? fun {voting_period = {index; _}; _} -> - let op = Proposals {source; period = index; proposals} in - Account.find source >|=? fun account -> - sign account.sk ctxt (Contents_list (Single op)) - -let ballot ctxt (pkh : Contract.t) proposal ballot = - Context.Contract.pkh pkh >>=? fun source -> - Context.Vote.get_current_period ctxt - >>=? fun {voting_period = {index; _}; _} -> - let op = Ballot {source; period = index; proposal; ballot} in - Account.find source >|=? fun account -> - sign account.sk ctxt (Contents_list (Single op)) - -let dummy_script = - let open Micheline in - Script. - { - code = - lazy_expr - (strip_locations - (Seq - ( (), - [ - Prim ((), K_parameter, [Prim ((), T_unit, [], [])], []); - Prim ((), K_storage, [Prim ((), T_unit, [], [])], []); - Prim - ( (), - K_code, - [ - Seq - ( (), - [ - Prim ((), I_CDR, [], []); - Prim - ( (), - I_NIL, - [Prim ((), T_operation, [], [])], - [] ); - Prim ((), I_PAIR, [], []); - ] ); - ], - [] ); - ] ))); - storage = lazy_expr (strip_locations (Prim ((), D_Unit, [], []))); - } - -let dummy_script_cost = Test_tez.of_mutez_exn 9_500L diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/op.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/op.mli deleted file mode 100644 index 77aeec462235..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/op.mli +++ /dev/null @@ -1,175 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -val endorsement : - ?delegate:public_key_hash * Slot.t list -> - ?slot:Slot.t -> - ?level:Raw_level.t -> - ?round:Round.t -> - ?block_payload_hash:Block_payload_hash.t -> - endorsed_block:Block.t -> - Context.t -> - ?signing_context:Context.t -> - unit -> - Kind.endorsement Operation.t tzresult Lwt.t - -val preendorsement : - ?delegate:public_key_hash * Slot.t list -> - ?slot:Slot.t -> - ?level:Raw_level.t -> - ?round:Round.t -> - ?block_payload_hash:Block_payload_hash.t -> - endorsed_block:Block.t -> - Context.t -> - ?signing_context:Context.t -> - unit -> - Kind.preendorsement Operation.t tzresult Lwt.t - -val miss_signed_endorsement : - ?level:Raw_level.t -> - endorsed_block:Block.t -> - Context.t -> - Kind.endorsement Operation.t tzresult Lwt.t - -val transaction : - ?counter:Z.t -> - ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - ?parameters:Script.lazy_expr -> - ?entrypoint:string -> - Context.t -> - Contract.t -> - Contract.t -> - Tez.t -> - Operation.packed tzresult Lwt.t - -val delegation : - ?fee:Tez.tez -> - Context.t -> - Contract.t -> - public_key_hash option -> - Operation.packed tzresult Lwt.t - -val set_deposits_limit : - ?fee:Tez.tez -> - Context.t -> - Contract.t -> - Tez.tez option -> - Operation.packed tzresult Lwt.t - -val revelation : - ?fee:Tez.tez -> Context.t -> public_key -> Operation.packed tzresult Lwt.t - -val failing_noop : - Context.t -> public_key_hash -> string -> Operation.packed tzresult Lwt.t - -val origination : - ?counter:Z.t -> - ?delegate:public_key_hash -> - script:Script.t -> - ?preorigination:Contract.contract option -> - ?public_key:public_key -> - ?credit:Tez.tez -> - ?fee:Tez.tez -> - ?gas_limit:Gas.Arith.integral -> - ?storage_limit:Z.t -> - Context.t -> - Contract.contract -> - (Operation.packed * Contract.contract) tzresult Lwt.t - -val originated_contract : Operation.packed -> Contract.contract - -val register_global_constant : - ?counter:Z.t -> - ?public_key:Signature.public_key -> - ?fee:Tez.tez -> - ?gas_limit:Alpha_context.Gas.Arith.integral -> - ?storage_limit:Z.t -> - Context.t -> - (* Account doing the registration *) - source:Contract.t -> - (* Micheline value to be registered *) - value:Protocol.Alpha_context.Script.lazy_expr -> - (Protocol.operation, tztrace) result Lwt.t - -val double_endorsement : - Context.t -> - Kind.endorsement Operation.t -> - Kind.endorsement Operation.t -> - Operation.packed - -val double_preendorsement : - Context.t -> - Kind.preendorsement Operation.t -> - Kind.preendorsement Operation.t -> - Operation.packed - -val double_baking : - Context.t -> - Block_header.block_header -> - Block_header.block_header -> - Operation.packed - -val activation : - Context.t -> - Signature.Public_key_hash.t -> - Blinded_public_key_hash.activation_code -> - Operation.packed tzresult Lwt.t - -val combine_operations : - ?public_key:public_key -> - ?counter:counter -> - ?spurious_operation:packed_operation -> - source:Contract.t -> - Context.t -> - packed_operation list -> - packed_operation tzresult Lwt.t - -(** Reveals a seed_nonce that was previously committed at a certain level *) -val seed_nonce_revelation : - Context.t -> Raw_level.t -> Nonce.t -> Operation.packed - -(** Propose a list of protocol hashes during the approval voting *) -val proposals : - Context.t -> - Contract.t -> - Protocol_hash.t list -> - Operation.packed tzresult Lwt.t - -(** Cast a vote yay, nay or pass *) -val ballot : - Context.t -> - Contract.t -> - Protocol_hash.t -> - Vote.ballot -> - Operation.packed tzresult Lwt.t - -val dummy_script : Script.t - -val dummy_script_cost : Tez.t diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/rewards.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/rewards.ml deleted file mode 100644 index bc9c833a8221..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/rewards.ml +++ /dev/null @@ -1,1641 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2019--2021 Nomadic Labs, *) -(* Copyright (c) 2019 Cryptium Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** The tables are precomputed using this the following formulas: - -let max_endos = 256 -let max_reward = 40 - -let r = 0.5 -let a = 3. -let b = 1.5 - -let ( -- ) i j = List.init (j - i + 1) (fun x -> x + i) - -let baking_rewards = - let reward p e = - let r_aux = - if p = 0 then - r *. (float_of_int max_reward) - else - a - in - let r = r_aux /. (float_of_int max_endos) in - let r = 1_000_000. *. r in - Float.to_int ((float_of_int e) *. (ceil r)) in - - let ps = 0 -- 2 in - let es = 0 -- max_endos in - - List.map (fun p -> - List.map (fun e -> - reward p e - ) es |> Array.of_list - ) ps |> Array.of_list - - -let endorsing_rewards = - let reward p e = - let r_aux = - (1. -. r) *. - (float_of_int max_reward) /. - (float_of_int max_endos) in - let r = if p = 0 then r_aux else r_aux /. b in - let r = 1_000_000. *. r in - Float.to_int ((float_of_int e) *. (floor r)) in - - let ps = 0 -- 2 in - let es = 0 -- max_endos in - - List.map (fun p -> - List.map (fun e -> - reward p e - ) es |> Array.of_list - ) ps |> Array.of_list - - *) - -let baking_rewards : int array array = - [| - [| - 0; - 78125; - 156250; - 234375; - 312500; - 390625; - 468750; - 546875; - 625000; - 703125; - 781250; - 859375; - 937500; - 1015625; - 1093750; - 1171875; - 1250000; - 1328125; - 1406250; - 1484375; - 1562500; - 1640625; - 1718750; - 1796875; - 1875000; - 1953125; - 2031250; - 2109375; - 2187500; - 2265625; - 2343750; - 2421875; - 2500000; - 2578125; - 2656250; - 2734375; - 2812500; - 2890625; - 2968750; - 3046875; - 3125000; - 3203125; - 3281250; - 3359375; - 3437500; - 3515625; - 3593750; - 3671875; - 3750000; - 3828125; - 3906250; - 3984375; - 4062500; - 4140625; - 4218750; - 4296875; - 4375000; - 4453125; - 4531250; - 4609375; - 4687500; - 4765625; - 4843750; - 4921875; - 5000000; - 5078125; - 5156250; - 5234375; - 5312500; - 5390625; - 5468750; - 5546875; - 5625000; - 5703125; - 5781250; - 5859375; - 5937500; - 6015625; - 6093750; - 6171875; - 6250000; - 6328125; - 6406250; - 6484375; - 6562500; - 6640625; - 6718750; - 6796875; - 6875000; - 6953125; - 7031250; - 7109375; - 7187500; - 7265625; - 7343750; - 7421875; - 7500000; - 7578125; - 7656250; - 7734375; - 7812500; - 7890625; - 7968750; - 8046875; - 8125000; - 8203125; - 8281250; - 8359375; - 8437500; - 8515625; - 8593750; - 8671875; - 8750000; - 8828125; - 8906250; - 8984375; - 9062500; - 9140625; - 9218750; - 9296875; - 9375000; - 9453125; - 9531250; - 9609375; - 9687500; - 9765625; - 9843750; - 9921875; - 10000000; - 10078125; - 10156250; - 10234375; - 10312500; - 10390625; - 10468750; - 10546875; - 10625000; - 10703125; - 10781250; - 10859375; - 10937500; - 11015625; - 11093750; - 11171875; - 11250000; - 11328125; - 11406250; - 11484375; - 11562500; - 11640625; - 11718750; - 11796875; - 11875000; - 11953125; - 12031250; - 12109375; - 12187500; - 12265625; - 12343750; - 12421875; - 12500000; - 12578125; - 12656250; - 12734375; - 12812500; - 12890625; - 12968750; - 13046875; - 13125000; - 13203125; - 13281250; - 13359375; - 13437500; - 13515625; - 13593750; - 13671875; - 13750000; - 13828125; - 13906250; - 13984375; - 14062500; - 14140625; - 14218750; - 14296875; - 14375000; - 14453125; - 14531250; - 14609375; - 14687500; - 14765625; - 14843750; - 14921875; - 15000000; - 15078125; - 15156250; - 15234375; - 15312500; - 15390625; - 15468750; - 15546875; - 15625000; - 15703125; - 15781250; - 15859375; - 15937500; - 16015625; - 16093750; - 16171875; - 16250000; - 16328125; - 16406250; - 16484375; - 16562500; - 16640625; - 16718750; - 16796875; - 16875000; - 16953125; - 17031250; - 17109375; - 17187500; - 17265625; - 17343750; - 17421875; - 17500000; - 17578125; - 17656250; - 17734375; - 17812500; - 17890625; - 17968750; - 18046875; - 18125000; - 18203125; - 18281250; - 18359375; - 18437500; - 18515625; - 18593750; - 18671875; - 18750000; - 18828125; - 18906250; - 18984375; - 19062500; - 19140625; - 19218750; - 19296875; - 19375000; - 19453125; - 19531250; - 19609375; - 19687500; - 19765625; - 19843750; - 19921875; - 20000000; - |]; - [| - 0; - 11719; - 23438; - 35157; - 46876; - 58595; - 70314; - 82033; - 93752; - 105471; - 117190; - 128909; - 140628; - 152347; - 164066; - 175785; - 187504; - 199223; - 210942; - 222661; - 234380; - 246099; - 257818; - 269537; - 281256; - 292975; - 304694; - 316413; - 328132; - 339851; - 351570; - 363289; - 375008; - 386727; - 398446; - 410165; - 421884; - 433603; - 445322; - 457041; - 468760; - 480479; - 492198; - 503917; - 515636; - 527355; - 539074; - 550793; - 562512; - 574231; - 585950; - 597669; - 609388; - 621107; - 632826; - 644545; - 656264; - 667983; - 679702; - 691421; - 703140; - 714859; - 726578; - 738297; - 750016; - 761735; - 773454; - 785173; - 796892; - 808611; - 820330; - 832049; - 843768; - 855487; - 867206; - 878925; - 890644; - 902363; - 914082; - 925801; - 937520; - 949239; - 960958; - 972677; - 984396; - 996115; - 1007834; - 1019553; - 1031272; - 1042991; - 1054710; - 1066429; - 1078148; - 1089867; - 1101586; - 1113305; - 1125024; - 1136743; - 1148462; - 1160181; - 1171900; - 1183619; - 1195338; - 1207057; - 1218776; - 1230495; - 1242214; - 1253933; - 1265652; - 1277371; - 1289090; - 1300809; - 1312528; - 1324247; - 1335966; - 1347685; - 1359404; - 1371123; - 1382842; - 1394561; - 1406280; - 1417999; - 1429718; - 1441437; - 1453156; - 1464875; - 1476594; - 1488313; - 1500032; - 1511751; - 1523470; - 1535189; - 1546908; - 1558627; - 1570346; - 1582065; - 1593784; - 1605503; - 1617222; - 1628941; - 1640660; - 1652379; - 1664098; - 1675817; - 1687536; - 1699255; - 1710974; - 1722693; - 1734412; - 1746131; - 1757850; - 1769569; - 1781288; - 1793007; - 1804726; - 1816445; - 1828164; - 1839883; - 1851602; - 1863321; - 1875040; - 1886759; - 1898478; - 1910197; - 1921916; - 1933635; - 1945354; - 1957073; - 1968792; - 1980511; - 1992230; - 2003949; - 2015668; - 2027387; - 2039106; - 2050825; - 2062544; - 2074263; - 2085982; - 2097701; - 2109420; - 2121139; - 2132858; - 2144577; - 2156296; - 2168015; - 2179734; - 2191453; - 2203172; - 2214891; - 2226610; - 2238329; - 2250048; - 2261767; - 2273486; - 2285205; - 2296924; - 2308643; - 2320362; - 2332081; - 2343800; - 2355519; - 2367238; - 2378957; - 2390676; - 2402395; - 2414114; - 2425833; - 2437552; - 2449271; - 2460990; - 2472709; - 2484428; - 2496147; - 2507866; - 2519585; - 2531304; - 2543023; - 2554742; - 2566461; - 2578180; - 2589899; - 2601618; - 2613337; - 2625056; - 2636775; - 2648494; - 2660213; - 2671932; - 2683651; - 2695370; - 2707089; - 2718808; - 2730527; - 2742246; - 2753965; - 2765684; - 2777403; - 2789122; - 2800841; - 2812560; - 2824279; - 2835998; - 2847717; - 2859436; - 2871155; - 2882874; - 2894593; - 2906312; - 2918031; - 2929750; - 2941469; - 2953188; - 2964907; - 2976626; - 2988345; - 3000064; - |]; - [| - 0; - 11719; - 23438; - 35157; - 46876; - 58595; - 70314; - 82033; - 93752; - 105471; - 117190; - 128909; - 140628; - 152347; - 164066; - 175785; - 187504; - 199223; - 210942; - 222661; - 234380; - 246099; - 257818; - 269537; - 281256; - 292975; - 304694; - 316413; - 328132; - 339851; - 351570; - 363289; - 375008; - 386727; - 398446; - 410165; - 421884; - 433603; - 445322; - 457041; - 468760; - 480479; - 492198; - 503917; - 515636; - 527355; - 539074; - 550793; - 562512; - 574231; - 585950; - 597669; - 609388; - 621107; - 632826; - 644545; - 656264; - 667983; - 679702; - 691421; - 703140; - 714859; - 726578; - 738297; - 750016; - 761735; - 773454; - 785173; - 796892; - 808611; - 820330; - 832049; - 843768; - 855487; - 867206; - 878925; - 890644; - 902363; - 914082; - 925801; - 937520; - 949239; - 960958; - 972677; - 984396; - 996115; - 1007834; - 1019553; - 1031272; - 1042991; - 1054710; - 1066429; - 1078148; - 1089867; - 1101586; - 1113305; - 1125024; - 1136743; - 1148462; - 1160181; - 1171900; - 1183619; - 1195338; - 1207057; - 1218776; - 1230495; - 1242214; - 1253933; - 1265652; - 1277371; - 1289090; - 1300809; - 1312528; - 1324247; - 1335966; - 1347685; - 1359404; - 1371123; - 1382842; - 1394561; - 1406280; - 1417999; - 1429718; - 1441437; - 1453156; - 1464875; - 1476594; - 1488313; - 1500032; - 1511751; - 1523470; - 1535189; - 1546908; - 1558627; - 1570346; - 1582065; - 1593784; - 1605503; - 1617222; - 1628941; - 1640660; - 1652379; - 1664098; - 1675817; - 1687536; - 1699255; - 1710974; - 1722693; - 1734412; - 1746131; - 1757850; - 1769569; - 1781288; - 1793007; - 1804726; - 1816445; - 1828164; - 1839883; - 1851602; - 1863321; - 1875040; - 1886759; - 1898478; - 1910197; - 1921916; - 1933635; - 1945354; - 1957073; - 1968792; - 1980511; - 1992230; - 2003949; - 2015668; - 2027387; - 2039106; - 2050825; - 2062544; - 2074263; - 2085982; - 2097701; - 2109420; - 2121139; - 2132858; - 2144577; - 2156296; - 2168015; - 2179734; - 2191453; - 2203172; - 2214891; - 2226610; - 2238329; - 2250048; - 2261767; - 2273486; - 2285205; - 2296924; - 2308643; - 2320362; - 2332081; - 2343800; - 2355519; - 2367238; - 2378957; - 2390676; - 2402395; - 2414114; - 2425833; - 2437552; - 2449271; - 2460990; - 2472709; - 2484428; - 2496147; - 2507866; - 2519585; - 2531304; - 2543023; - 2554742; - 2566461; - 2578180; - 2589899; - 2601618; - 2613337; - 2625056; - 2636775; - 2648494; - 2660213; - 2671932; - 2683651; - 2695370; - 2707089; - 2718808; - 2730527; - 2742246; - 2753965; - 2765684; - 2777403; - 2789122; - 2800841; - 2812560; - 2824279; - 2835998; - 2847717; - 2859436; - 2871155; - 2882874; - 2894593; - 2906312; - 2918031; - 2929750; - 2941469; - 2953188; - 2964907; - 2976626; - 2988345; - 3000064; - |]; - |] - -let endorsing_rewards : int array array = - [| - [| - 0; - 78125; - 156250; - 234375; - 312500; - 390625; - 468750; - 546875; - 625000; - 703125; - 781250; - 859375; - 937500; - 1015625; - 1093750; - 1171875; - 1250000; - 1328125; - 1406250; - 1484375; - 1562500; - 1640625; - 1718750; - 1796875; - 1875000; - 1953125; - 2031250; - 2109375; - 2187500; - 2265625; - 2343750; - 2421875; - 2500000; - 2578125; - 2656250; - 2734375; - 2812500; - 2890625; - 2968750; - 3046875; - 3125000; - 3203125; - 3281250; - 3359375; - 3437500; - 3515625; - 3593750; - 3671875; - 3750000; - 3828125; - 3906250; - 3984375; - 4062500; - 4140625; - 4218750; - 4296875; - 4375000; - 4453125; - 4531250; - 4609375; - 4687500; - 4765625; - 4843750; - 4921875; - 5000000; - 5078125; - 5156250; - 5234375; - 5312500; - 5390625; - 5468750; - 5546875; - 5625000; - 5703125; - 5781250; - 5859375; - 5937500; - 6015625; - 6093750; - 6171875; - 6250000; - 6328125; - 6406250; - 6484375; - 6562500; - 6640625; - 6718750; - 6796875; - 6875000; - 6953125; - 7031250; - 7109375; - 7187500; - 7265625; - 7343750; - 7421875; - 7500000; - 7578125; - 7656250; - 7734375; - 7812500; - 7890625; - 7968750; - 8046875; - 8125000; - 8203125; - 8281250; - 8359375; - 8437500; - 8515625; - 8593750; - 8671875; - 8750000; - 8828125; - 8906250; - 8984375; - 9062500; - 9140625; - 9218750; - 9296875; - 9375000; - 9453125; - 9531250; - 9609375; - 9687500; - 9765625; - 9843750; - 9921875; - 10000000; - 10078125; - 10156250; - 10234375; - 10312500; - 10390625; - 10468750; - 10546875; - 10625000; - 10703125; - 10781250; - 10859375; - 10937500; - 11015625; - 11093750; - 11171875; - 11250000; - 11328125; - 11406250; - 11484375; - 11562500; - 11640625; - 11718750; - 11796875; - 11875000; - 11953125; - 12031250; - 12109375; - 12187500; - 12265625; - 12343750; - 12421875; - 12500000; - 12578125; - 12656250; - 12734375; - 12812500; - 12890625; - 12968750; - 13046875; - 13125000; - 13203125; - 13281250; - 13359375; - 13437500; - 13515625; - 13593750; - 13671875; - 13750000; - 13828125; - 13906250; - 13984375; - 14062500; - 14140625; - 14218750; - 14296875; - 14375000; - 14453125; - 14531250; - 14609375; - 14687500; - 14765625; - 14843750; - 14921875; - 15000000; - 15078125; - 15156250; - 15234375; - 15312500; - 15390625; - 15468750; - 15546875; - 15625000; - 15703125; - 15781250; - 15859375; - 15937500; - 16015625; - 16093750; - 16171875; - 16250000; - 16328125; - 16406250; - 16484375; - 16562500; - 16640625; - 16718750; - 16796875; - 16875000; - 16953125; - 17031250; - 17109375; - 17187500; - 17265625; - 17343750; - 17421875; - 17500000; - 17578125; - 17656250; - 17734375; - 17812500; - 17890625; - 17968750; - 18046875; - 18125000; - 18203125; - 18281250; - 18359375; - 18437500; - 18515625; - 18593750; - 18671875; - 18750000; - 18828125; - 18906250; - 18984375; - 19062500; - 19140625; - 19218750; - 19296875; - 19375000; - 19453125; - 19531250; - 19609375; - 19687500; - 19765625; - 19843750; - 19921875; - 20000000; - |]; - [| - 0; - 52083; - 104166; - 156249; - 208332; - 260415; - 312498; - 364581; - 416664; - 468747; - 520830; - 572913; - 624996; - 677079; - 729162; - 781245; - 833328; - 885411; - 937494; - 989577; - 1041660; - 1093743; - 1145826; - 1197909; - 1249992; - 1302075; - 1354158; - 1406241; - 1458324; - 1510407; - 1562490; - 1614573; - 1666656; - 1718739; - 1770822; - 1822905; - 1874988; - 1927071; - 1979154; - 2031237; - 2083320; - 2135403; - 2187486; - 2239569; - 2291652; - 2343735; - 2395818; - 2447901; - 2499984; - 2552067; - 2604150; - 2656233; - 2708316; - 2760399; - 2812482; - 2864565; - 2916648; - 2968731; - 3020814; - 3072897; - 3124980; - 3177063; - 3229146; - 3281229; - 3333312; - 3385395; - 3437478; - 3489561; - 3541644; - 3593727; - 3645810; - 3697893; - 3749976; - 3802059; - 3854142; - 3906225; - 3958308; - 4010391; - 4062474; - 4114557; - 4166640; - 4218723; - 4270806; - 4322889; - 4374972; - 4427055; - 4479138; - 4531221; - 4583304; - 4635387; - 4687470; - 4739553; - 4791636; - 4843719; - 4895802; - 4947885; - 4999968; - 5052051; - 5104134; - 5156217; - 5208300; - 5260383; - 5312466; - 5364549; - 5416632; - 5468715; - 5520798; - 5572881; - 5624964; - 5677047; - 5729130; - 5781213; - 5833296; - 5885379; - 5937462; - 5989545; - 6041628; - 6093711; - 6145794; - 6197877; - 6249960; - 6302043; - 6354126; - 6406209; - 6458292; - 6510375; - 6562458; - 6614541; - 6666624; - 6718707; - 6770790; - 6822873; - 6874956; - 6927039; - 6979122; - 7031205; - 7083288; - 7135371; - 7187454; - 7239537; - 7291620; - 7343703; - 7395786; - 7447869; - 7499952; - 7552035; - 7604118; - 7656201; - 7708284; - 7760367; - 7812450; - 7864533; - 7916616; - 7968699; - 8020782; - 8072865; - 8124948; - 8177031; - 8229114; - 8281197; - 8333280; - 8385363; - 8437446; - 8489529; - 8541612; - 8593695; - 8645778; - 8697861; - 8749944; - 8802027; - 8854110; - 8906193; - 8958276; - 9010359; - 9062442; - 9114525; - 9166608; - 9218691; - 9270774; - 9322857; - 9374940; - 9427023; - 9479106; - 9531189; - 9583272; - 9635355; - 9687438; - 9739521; - 9791604; - 9843687; - 9895770; - 9947853; - 9999936; - 10052019; - 10104102; - 10156185; - 10208268; - 10260351; - 10312434; - 10364517; - 10416600; - 10468683; - 10520766; - 10572849; - 10624932; - 10677015; - 10729098; - 10781181; - 10833264; - 10885347; - 10937430; - 10989513; - 11041596; - 11093679; - 11145762; - 11197845; - 11249928; - 11302011; - 11354094; - 11406177; - 11458260; - 11510343; - 11562426; - 11614509; - 11666592; - 11718675; - 11770758; - 11822841; - 11874924; - 11927007; - 11979090; - 12031173; - 12083256; - 12135339; - 12187422; - 12239505; - 12291588; - 12343671; - 12395754; - 12447837; - 12499920; - 12552003; - 12604086; - 12656169; - 12708252; - 12760335; - 12812418; - 12864501; - 12916584; - 12968667; - 13020750; - 13072833; - 13124916; - 13176999; - 13229082; - 13281165; - 13333248; - |]; - [| - 0; - 52083; - 104166; - 156249; - 208332; - 260415; - 312498; - 364581; - 416664; - 468747; - 520830; - 572913; - 624996; - 677079; - 729162; - 781245; - 833328; - 885411; - 937494; - 989577; - 1041660; - 1093743; - 1145826; - 1197909; - 1249992; - 1302075; - 1354158; - 1406241; - 1458324; - 1510407; - 1562490; - 1614573; - 1666656; - 1718739; - 1770822; - 1822905; - 1874988; - 1927071; - 1979154; - 2031237; - 2083320; - 2135403; - 2187486; - 2239569; - 2291652; - 2343735; - 2395818; - 2447901; - 2499984; - 2552067; - 2604150; - 2656233; - 2708316; - 2760399; - 2812482; - 2864565; - 2916648; - 2968731; - 3020814; - 3072897; - 3124980; - 3177063; - 3229146; - 3281229; - 3333312; - 3385395; - 3437478; - 3489561; - 3541644; - 3593727; - 3645810; - 3697893; - 3749976; - 3802059; - 3854142; - 3906225; - 3958308; - 4010391; - 4062474; - 4114557; - 4166640; - 4218723; - 4270806; - 4322889; - 4374972; - 4427055; - 4479138; - 4531221; - 4583304; - 4635387; - 4687470; - 4739553; - 4791636; - 4843719; - 4895802; - 4947885; - 4999968; - 5052051; - 5104134; - 5156217; - 5208300; - 5260383; - 5312466; - 5364549; - 5416632; - 5468715; - 5520798; - 5572881; - 5624964; - 5677047; - 5729130; - 5781213; - 5833296; - 5885379; - 5937462; - 5989545; - 6041628; - 6093711; - 6145794; - 6197877; - 6249960; - 6302043; - 6354126; - 6406209; - 6458292; - 6510375; - 6562458; - 6614541; - 6666624; - 6718707; - 6770790; - 6822873; - 6874956; - 6927039; - 6979122; - 7031205; - 7083288; - 7135371; - 7187454; - 7239537; - 7291620; - 7343703; - 7395786; - 7447869; - 7499952; - 7552035; - 7604118; - 7656201; - 7708284; - 7760367; - 7812450; - 7864533; - 7916616; - 7968699; - 8020782; - 8072865; - 8124948; - 8177031; - 8229114; - 8281197; - 8333280; - 8385363; - 8437446; - 8489529; - 8541612; - 8593695; - 8645778; - 8697861; - 8749944; - 8802027; - 8854110; - 8906193; - 8958276; - 9010359; - 9062442; - 9114525; - 9166608; - 9218691; - 9270774; - 9322857; - 9374940; - 9427023; - 9479106; - 9531189; - 9583272; - 9635355; - 9687438; - 9739521; - 9791604; - 9843687; - 9895770; - 9947853; - 9999936; - 10052019; - 10104102; - 10156185; - 10208268; - 10260351; - 10312434; - 10364517; - 10416600; - 10468683; - 10520766; - 10572849; - 10624932; - 10677015; - 10729098; - 10781181; - 10833264; - 10885347; - 10937430; - 10989513; - 11041596; - 11093679; - 11145762; - 11197845; - 11249928; - 11302011; - 11354094; - 11406177; - 11458260; - 11510343; - 11562426; - 11614509; - 11666592; - 11718675; - 11770758; - 11822841; - 11874924; - 11927007; - 11979090; - 12031173; - 12083256; - 12135339; - 12187422; - 12239505; - 12291588; - 12343671; - 12395754; - 12447837; - 12499920; - 12552003; - 12604086; - 12656169; - 12708252; - 12760335; - 12812418; - 12864501; - 12916584; - 12968667; - 13020750; - 13072833; - 13124916; - 13176999; - 13229082; - 13281165; - 13333248; - |]; - |] diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/sapling_helpers.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/sapling_helpers.ml deleted file mode 100644 index a5698ff56ac2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/sapling_helpers.ml +++ /dev/null @@ -1,397 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -module Common = struct - let memo_size_of_int i = - match Alpha_context.Sapling.Memo_size.parse_z @@ Z.of_int i with - | Ok memo_size -> memo_size - | Error _ -> assert false - - let int_of_memo_size ms = - Alpha_context.Sapling.Memo_size.unparse_to_z ms |> Z.to_int - - let wrap e = Lwt.return (Environment.wrap_tzresult e) - - let assert_true res = res >|=? fun res -> assert res - - let assert_false res = res >|=? fun res -> assert (not res) - - let assert_some res = res >|=? function Some s -> s | None -> assert false - - let assert_none res = - res >>=? function Some _ -> assert false | None -> return_unit - - let assert_error res = - res >>= function Ok _ -> assert false | Error _ -> return_unit - - let print ?(prefix = "") e v = - Printf.printf - "%s: %s\n" - prefix - Data_encoding.(Json.to_string (Json.construct e v)) - - let to_hex x encoding = - Hex.show (Hex.of_bytes Data_encoding.Binary.(to_bytes_exn encoding x)) - - let randomized_byte ?pos v encoding = - let bytes = Data_encoding.Binary.(to_bytes_exn encoding v) in - let rec aux () = - let random_char = Random.int 256 |> char_of_int in - let pos = Option.value ~default:(Random.int (Bytes.length bytes)) pos in - if random_char = Bytes.get bytes pos then aux () - else Bytes.set bytes pos random_char - in - aux () ; - Data_encoding.Binary.(of_bytes_exn encoding bytes) - - type wallet = { - sk : Tezos_sapling.Core.Wallet.Spending_key.t; - vk : Tezos_sapling.Core.Wallet.Viewing_key.t; - } - - let wallet_gen () = - let sk = - Tezos_sapling.Core.Wallet.Spending_key.of_seed - (Tezos_crypto.Hacl.Rand.gen 32) - in - let vk = Tezos_sapling.Core.Wallet.Viewing_key.of_sk sk in - {sk; vk} - - let gen_addr n vk = - let rec aux n index res = - if Compare.Int.( <= ) n 0 then res - else - let (new_index, new_addr) = - Tezos_sapling.Core.Client.Viewing_key.new_address vk index - in - aux (n - 1) new_index (new_addr :: res) - in - aux n Tezos_sapling.Core.Client.Viewing_key.default_index [] - - let gen_nf () = - let {vk; _} = wallet_gen () in - let addr = - snd - @@ Tezos_sapling.Core.Wallet.Viewing_key.(new_address vk default_index) - in - let amount = 10L in - let rcm = Tezos_sapling.Core.Client.Rcm.random () in - let position = 10L in - Tezos_sapling.Core.Client.Nullifier.compute addr vk ~amount rcm ~position - - let gen_cm_cipher ~memo_size () = - let open Tezos_sapling.Core.Client in - let {vk; _} = wallet_gen () in - let addr = - snd - @@ Tezos_sapling.Core.Wallet.Viewing_key.(new_address vk default_index) - in - let amount = 10L in - let rcm = Tezos_sapling.Core.Client.Rcm.random () in - let cm = Commitment.compute addr ~amount rcm in - let cipher = - let payload_enc = - Data_encoding.Binary.to_bytes_exn - Data_encoding.bytes - (Hacl.Rand.gen (memo_size + 4 + 16 + 11 + 32 + 8)) - in - Data_encoding.Binary.of_bytes_exn - Ciphertext.encoding - (Bytes.concat - Bytes.empty - [ - Bytes.create (32 + 32); - payload_enc; - Bytes.create (24 + 64 + 16 + 24); - ]) - in - (cm, cipher) - - (* rebuilds from empty at each call *) - let client_state_of_diff ~memo_size (root, diff) = - let open Alpha_context.Sapling in - let cs = - Tezos_sapling.Storage.add - (Tezos_sapling.Storage.empty ~memo_size) - diff.commitments_and_ciphertexts - in - assert (Tezos_sapling.Storage.get_root cs = root) ; - List.fold_left - (fun s nf -> Tezos_sapling.Storage.add_nullifier s nf) - cs - diff.nullifiers -end - -module Alpha_context_helpers = struct - include Common - - let init () = - Context.init 1 >>=? fun (b, _) -> - Alpha_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - (* ~fitness:b.header.shell.fitness *) - >>= wrap - >|=? fun (ctxt, _, _) -> ctxt - - (* takes a state obtained from Sapling.empty_state or Sapling.state_from_id and - passed through Sapling.verify_update *) - let finalize ctx = - let open Alpha_context in - let open Sapling in - function - | {id = None; diff; memo_size} -> - Sapling.fresh ~temporary:false ctx >>= wrap >>=? fun (ctx, id) -> - let init = Lazy_storage.Alloc {memo_size} in - let lazy_storage_diff = Lazy_storage.Update {init; updates = diff} in - let diffs = [Lazy_storage.make Sapling_state id lazy_storage_diff] in - Lazy_storage.apply ctx diffs >>= wrap >|=? fun (ctx, _added_size) -> - (ctx, id) - | {id = Some id; diff; _} -> - let init = Lazy_storage.Existing in - let lazy_storage_diff = Lazy_storage.Update {init; updates = diff} in - let diffs = [Lazy_storage.make Sapling_state id lazy_storage_diff] in - Lazy_storage.apply ctx diffs >>= wrap >|=? fun (ctx, _added_size) -> - (ctx, id) - - (* disk only version *) - let verify_update ctx ?memo_size ?id vt = - let anti_replay = "anti-replay" in - (match id with - | None -> - (match memo_size with - | None -> ( - match vt.Environment.Sapling.UTXO.outputs with - | [] -> failwith "Can't infer memo_size from empty outputs" - | output :: _ -> - return - @@ Environment.Sapling.Ciphertext.get_memo_size - output.ciphertext) - | Some memo_size -> return memo_size) - >>=? fun memo_size -> - let memo_size = memo_size_of_int memo_size in - let vs = Alpha_context.Sapling.empty_state ~memo_size () in - return (vs, ctx) - | Some id -> - (* Storage.Sapling.Roots.get (Obj.magic ctx, id) 0l *) - (* >>= wrap *) - (* >>=? fun (_, root) -> *) - (* print ~prefix:"verify: " Environment.Sapling.Hash.encoding root ; *) - Alpha_context.Sapling.state_from_id ctx id >>= wrap) - >>=? fun (vs, ctx) -> - Alpha_context.Sapling.verify_update ctx vs vt anti_replay >>= wrap - >>=? fun (ctx, res) -> - match res with - | None -> return_none - | Some (_balance, vs) -> - finalize ctx vs >>=? fun (ctx, id) -> - let fake_fitness = - Alpha_context.( - let level = - match Raw_level.of_int32 0l with - | Error _ -> assert false - | Ok l -> l - in - Fitness.create_without_locked_round - ~level - ~predecessor_round:Round.zero - ~round:Round.zero - |> Fitness.to_raw) - in - let ectx = (Alpha_context.finalize ctx fake_fitness).context in - (* bump the level *) - Alpha_context.prepare - ectx - ~level: - Alpha_context.( - Raw_level.to_int32 Level.((succ ctx (current ctx)).level)) - ~predecessor_timestamp:(Time.Protocol.of_seconds Int64.zero) - ~timestamp:(Time.Protocol.of_seconds Int64.zero) - >>= wrap - >|=? fun (ctx, _, _) -> Some (ctx, id) - - let transfer_inputs_outputs w cs is = - (* Tezos_sapling.Storage.size cs *) - (* |> fun (a, b) -> *) - (* Printf.printf "%Ld %Ld" a b ; *) - let inputs = - List.map - (fun i -> - Tezos_sapling.Forge.Input.get cs (Int64.of_int i) w.vk - |> WithExceptions.Option.get ~loc:__LOC__ - |> snd) - is - in - let addr = - snd - @@ Tezos_sapling.Core.Wallet.Viewing_key.(new_address w.vk default_index) - in - let memo_size = Tezos_sapling.Storage.get_memo_size cs in - let o = - Tezos_sapling.Forge.make_output addr 1000000L (Bytes.create memo_size) - in - (inputs, [o]) - - let transfer w cs is = - let anti_replay = "anti-replay" in - let (ins, outs) = transfer_inputs_outputs w cs is in - (* change the wallet of this last line *) - Tezos_sapling.Forge.forge_transaction ins outs w.sk anti_replay cs - - let client_state_alpha ctx id = - Alpha_context.Sapling.get_diff ctx id () >>= wrap >>=? fun diff -> - Alpha_context.Sapling.state_from_id ctx id >>= wrap - >|=? fun ({memo_size; _}, _ctx) -> - let memo_size = int_of_memo_size memo_size in - client_state_of_diff ~memo_size diff -end - -(* - Interpreter level -*) - -module Interpreter_helpers = struct - include Common - include Contract_helpers - - (** Returns a block in which the contract is originated. - Also returns the associated anti-replay string and KT1 address. *) - let originate_contract file storage src b baker = - originate_contract file storage src b baker >|=? fun (dst, b) -> - let anti_replay = - Format.asprintf - "%a%a" - Alpha_context.Contract.pp - dst - Chain_id.pp - Chain_id.zero - in - (dst, b, anti_replay) - - let hex_shield ~memo_size wallet anti_replay = - let ps = Tezos_sapling.Storage.empty ~memo_size in - let addr = - snd - @@ Tezos_sapling.Core.Wallet.Viewing_key.( - new_address wallet.vk default_index) - in - let output = - Tezos_sapling.Forge.make_output addr 15L (Bytes.create memo_size) - in - let pt = - Tezos_sapling.Forge.forge_transaction [] [output] wallet.sk anti_replay ps - in - let hex_string = - "0x" - ^ Hex.show - (Hex.of_bytes - Data_encoding.Binary.( - to_bytes_exn - Tezos_sapling.Core.Client.UTXO.transaction_encoding - pt)) - in - hex_string - - (* Make a transaction and sync a local client state. [to_exclude] is the list - of addresses that cannot bake the block*) - let transac_and_sync ~memo_size block parameters amount src dst baker = - let amount_tez = - Test_tez.(Alpha_context.Tez.one_mutez *! Int64.of_int amount) - in - let fee = Test_tez.of_int 10 in - Op.transaction ~fee (B block) src dst amount_tez ~parameters - >>=? fun operation -> - Incremental.begin_construction ~policy:Block.(By_account baker) block - >>=? fun incr -> - Incremental.add_operation incr operation >>=? fun incr -> - Incremental.finalize_block incr >>=? fun block -> - Alpha_services.Contract.single_sapling_get_diff - Block.rpc_ctxt - block - dst - ~offset_commitment:0L - ~offset_nullifier:0L - () - >|=? fun diff -> - let state = client_state_of_diff ~memo_size diff in - (block, state) - - (* Returns a list of printed shield transactions and their total amount. *) - let shield ~memo_size sk number_transac vk printer anti_replay = - let state = Tezos_sapling.Storage.empty ~memo_size in - let rec aux number_transac number_outputs index amount_output total res = - if Compare.Int.(number_transac <= 0) then (res, total) - else - let (new_index, new_addr) = - Tezos_sapling.Core.Wallet.Viewing_key.(new_address vk index) - in - let outputs = - List.init ~when_negative_length:() number_outputs (fun _ -> - Tezos_sapling.Forge.make_output - new_addr - amount_output - (Bytes.create memo_size)) - |> function - | Error () -> assert false (* conditional above guards against this *) - | Ok outputs -> outputs - in - let tr_hex = - to_hex - (Tezos_sapling.Forge.forge_transaction - ~number_dummy_inputs:0 - ~number_dummy_outputs:0 - [] - outputs - sk - anti_replay - state) - Tezos_sapling.Core.Client.UTXO.transaction_encoding - in - aux - (number_transac - 1) - (number_outputs + 1) - new_index - (Int64.add 20L amount_output) - (total + (number_outputs * Int64.to_int amount_output)) - (printer tr_hex :: res) - in - aux - number_transac - 2 - Tezos_sapling.Core.Wallet.Viewing_key.default_index - 20L - 0 - [] - - (* This fails if the operation is not correct wrt the block *) - let next_block block operation = - Incremental.begin_construction block >>=? fun incr -> - Incremental.add_operation incr operation >>=? fun incr -> - Incremental.finalize_block incr -end diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_big_map.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/script_big_map.ml deleted file mode 100644 index 8573cafd1818..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_big_map.ml +++ /dev/null @@ -1,30 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) - -let update k v m ctxt = Protocol.Script_ir_translator.big_map_update ctxt k v m - -let of_list key_ty ty xs ctxt = - List.fold_left_es - (fun (bm, ctxt) (k, v) -> update k (Some v) bm ctxt) - (Protocol.Script_ir_translator.empty_big_map key_ty ty, ctxt) - xs diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_big_map.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/script_big_map.mli deleted file mode 100644 index d3875195820a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_big_map.mli +++ /dev/null @@ -1,44 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) - -(** Update a big map. See [Script_typed_ir.big_map_get_and_update] for details. *) -val update : - 'key -> - 'value option -> - ('key, 'value) Protocol.Script_typed_ir.big_map -> - Protocol.Alpha_context.t -> - (('key, 'value) Protocol.Script_typed_ir.big_map * Protocol.Alpha_context.t) - Protocol.Environment.Error_monad.tzresult - Lwt.t - -(** Convert a list to a [Script_big_map]. If the list contains duplicate keys, - the first occurence is used. - *) -val of_list : - 'key Protocol.Script_typed_ir.comparable_ty -> - 'value Protocol.Script_typed_ir.ty -> - ('key * 'value) list -> - Protocol.Alpha_context.t -> - (('key, 'value) Protocol.Script_typed_ir.big_map * Protocol.Alpha_context.t) - Protocol.Environment.Error_monad.tzresult - Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_list.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/script_list.ml deleted file mode 100644 index b224d784226b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_list.ml +++ /dev/null @@ -1,29 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol.Script_typed_ir (* For record fields *) - -let of_list xs = {elements = xs; length = List.length xs} diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_list.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/script_list.mli deleted file mode 100644 index fecdbe0072c1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_list.mli +++ /dev/null @@ -1,28 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Convert a standard list to a Script IR list. *) -val of_list : 'a list -> 'a Protocol.Script_typed_ir.boxed_list diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_map.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/script_map.ml deleted file mode 100644 index 5b780f7ac8e2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_map.ml +++ /dev/null @@ -1,36 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let of_list : - type k v. - k Protocol.Script_typed_ir.comparable_ty -> - (k * v) list -> - (k, v) Protocol.Script_typed_ir.map = - fun ty1 xs -> - List.fold_left - (fun rs (k, v) -> Protocol.Script_map.update k (Some v) rs) - (Protocol.Script_map.empty ty1) - xs diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_map.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/script_map.mli deleted file mode 100644 index e81cf5956c93..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_map.mli +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Trili Tech *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Convert a list to a [Script_map]. If the list contains duplicate keys, - the last occurence is used. *) -val of_list : - 'k Protocol.Script_typed_ir.comparable_ty -> - ('k * 'v) list -> - ('k, 'v) Protocol.Script_typed_ir.map diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_set.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/script_set.ml deleted file mode 100644 index b02d082465a4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_set.ml +++ /dev/null @@ -1,31 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let of_list ty1 xs = - List.fold_left - (fun rs k -> Protocol.Script_set.update k true rs) - (Protocol.Script_set.empty ty1) - xs diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_set.mli b/src/proto_012_Psithaca/lib_protocol/test/helpers/script_set.mli deleted file mode 100644 index 7df70020e3b3..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/script_set.mli +++ /dev/null @@ -1,32 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Convert a list to a Script IR set. If the list contains duplicates, - the last occurence is used. *) -val of_list : - 'a Protocol.Script_typed_ir.comparable_ty -> - 'a list -> - 'a Protocol.Script_typed_ir.set diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/test_global_constants.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/test_global_constants.ml deleted file mode 100644 index 1e98e513b7d3..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/test_global_constants.ml +++ /dev/null @@ -1,327 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Micheline -open Michelson_v1_primitives - -let create_context () = - let accounts = Account.generate_accounts 2 in - Block.alpha_context accounts - -let expr_to_hash expr = - let lexpr = Script_repr.lazy_expr expr in - Script_repr.force_bytes lexpr >|? fun b -> Script_expr_hash.hash_bytes [b] - -let assert_expr_equal loc = - Assert.equal - ~loc - ( = ) - "Michelson Expressions Not Equal" - Michelson_v1_printer.print_expr - -let assert_proto_error_id loc id result = - let test err = - (Error_monad.find_info_of_error err).id - = "proto." ^ Protocol.name ^ "." ^ id - in - Assert.error ~loc result test - -let assert_ok_lwt x = - match Lwt_main.run x with - | Ok x -> x - | Error _ -> raise @@ Failure "Called assert_ok_lwt on Error" - -let assert_ok = function - | Ok x -> x - | Error _ -> raise @@ Failure "Called assert_ok on Error" - -(** Filters out values that would cause [register] *) -let assume_expr_not_too_large expr = - let node = root expr in - QCheck.assume @@ not - @@ Global_constants_storage.Internal_for_tests.node_too_large node - -module Generators = struct - let context_arbitrary () = - QCheck.make @@ QCheck.Gen.return (create_context () |> assert_ok_lwt) - - let prims = - [ - K_parameter; - K_storage; - K_code; - D_False; - D_Elt; - D_Left; - D_None; - D_Pair; - D_Right; - D_Some; - D_True; - D_Unit; - I_PACK; - I_UNPACK; - I_BLAKE2B; - I_SHA256; - I_SHA512; - I_ABS; - I_ADD; - I_AMOUNT; - I_AND; - I_BALANCE; - I_CAR; - I_CDR; - I_CHAIN_ID; - I_CHECK_SIGNATURE; - I_COMPARE; - I_CONCAT; - I_CONS; - I_CREATE_ACCOUNT; - I_CREATE_CONTRACT; - I_IMPLICIT_ACCOUNT; - I_DIP; - I_DROP; - I_DUP; - I_EDIV; - I_EMPTY_BIG_MAP; - I_EMPTY_MAP; - I_EMPTY_SET; - I_EQ; - I_EXEC; - I_APPLY; - I_FAILWITH; - I_GE; - I_GET; - I_GET_AND_UPDATE; - I_GT; - I_HASH_KEY; - I_IF; - I_IF_CONS; - I_IF_LEFT; - I_IF_NONE; - I_INT; - I_LAMBDA; - I_LE; - I_LEFT; - I_LEVEL; - I_LOOP; - I_LSL; - I_LSR; - I_LT; - I_MAP; - I_MEM; - I_MUL; - I_NEG; - I_NEQ; - I_NIL; - I_NONE; - I_NOT; - I_NOW; - I_OR; - I_PAIR; - I_UNPAIR; - I_PUSH; - I_RIGHT; - I_SIZE; - I_SOME; - I_SOURCE; - I_SENDER; - I_SELF; - I_SELF_ADDRESS; - I_SLICE; - I_STEPS_TO_QUOTA; - I_SUB; - I_SWAP; - I_TRANSFER_TOKENS; - I_SET_DELEGATE; - I_UNIT; - I_UPDATE; - I_XOR; - I_ITER; - I_LOOP_LEFT; - I_ADDRESS; - I_CONTRACT; - I_ISNAT; - I_CAST; - I_RENAME; - I_SAPLING_EMPTY_STATE; - I_SAPLING_VERIFY_UPDATE; - I_DIG; - I_DUG; - I_NEVER; - I_VOTING_POWER; - I_TOTAL_VOTING_POWER; - I_KECCAK; - I_SHA3; - I_PAIRING_CHECK; - I_TICKET; - I_READ_TICKET; - I_SPLIT_TICKET; - I_JOIN_TICKETS; - T_bool; - T_contract; - T_int; - T_key; - T_key_hash; - T_lambda; - T_list; - T_map; - T_big_map; - T_nat; - T_option; - T_or; - T_pair; - T_set; - T_signature; - T_string; - T_bytes; - T_mutez; - T_timestamp; - T_unit; - T_operation; - T_address; - T_sapling_transaction; - T_sapling_state; - T_chain_id; - T_never; - T_bls12_381_g1; - T_bls12_381_g2; - T_bls12_381_fr; - T_ticket; - H_constant; - ] - - let prim_gen = QCheck.Gen.oneofl prims - - let prims_without_constants_gen = - QCheck.Gen.oneofl (List.filter (fun x -> x != H_constant) prims) - - let z_gen = QCheck.Gen.map Z.of_int QCheck.Gen.int - - let micheline_node_gen l_gen p_gen annot_gen : - ('l, 'p) Micheline.node QCheck.Gen.t = - let open Micheline in - let open QCheck.Gen in - fix - (fun self () -> - frequency - [ - (3, map (fun (l, x) -> Int (l, x)) (pair l_gen z_gen)); - (3, map (fun (l, x) -> String (l, x)) (pair l_gen string)); - ( 3, - map - (fun (l, x) -> Bytes (l, Bytes.of_string x)) - (pair l_gen string) ); - ( 1, - map - (fun (l, p, args, annot) -> Prim (l, p, args, annot)) - (quad - l_gen - p_gen - (list_size (int_bound 10) (self ())) - annot_gen) ); - ( 1, - map - (fun (l, args) -> Seq (l, args)) - (pair l_gen (list_size (int_bound 10) (self ()))) ); - ]) - () - - let rec replace_with_constant : - Script.node -> Script.location -> Script.node * Script.node option = - fun node loc -> - let open Michelson_v1_primitives in - let open Micheline in - let rec loop : Script.node list -> Script.node list * Script.node option = - function - | [] -> ([], None) - | hd :: tl -> ( - match replace_with_constant hd loc with - | (node, Some x) -> (node :: tl, Some x) - | (_, None) -> - let (l, x) = loop tl in - (hd :: l, x)) - in - match node with - | (Int (l, _) | String (l, _) | Bytes (l, _)) as node -> - if l = loc then - let hash = - node |> strip_locations |> expr_to_hash |> assert_ok - |> Script_expr_hash.to_b58check - in - (Prim (-1, H_constant, [String (-1, hash)], []), Some node) - else (node, None) - | Prim (l, prim, args, annot) as node -> - if l = loc then - let hash = - node |> strip_locations |> expr_to_hash |> assert_ok - |> Script_expr_hash.to_b58check - in - (Prim (-1, H_constant, [String (-1, hash)], []), Some node) - else - let (result, x) = loop args in - (Prim (l, prim, result, annot), x) - | Seq (l, args) as node -> - if l = loc then - let hash = - node |> strip_locations |> expr_to_hash |> assert_ok - |> Script_expr_hash.to_b58check - in - (Prim (-1, H_constant, [String (-1, hash)], []), Some node) - else - let (result, x) = loop args in - (Seq (l, result), x) - - let micheline_gen p_gen annot_gen = - QCheck.Gen.map - Micheline.strip_locations - (micheline_node_gen (QCheck.Gen.return (-1)) p_gen annot_gen) - - let canonical_without_constant_gen () = - QCheck.Gen.map - strip_locations - (micheline_node_gen - (QCheck.Gen.return (-1)) - prims_without_constants_gen - (QCheck.Gen.return [])) - - let canonical_without_constant_arbitrary () = - QCheck.make (canonical_without_constant_gen ()) - - let canonical_with_constant_gen () = - let open QCheck.Gen in - canonical_without_constant_gen () >>= fun expr -> - let size = Script_repr.micheline_nodes (root expr) in - 0 -- (size - 1) >|= fun loc -> - match replace_with_constant (root expr) loc with - | (_, None) -> assert false - | (node, Some replaced_node) -> - (expr, strip_locations node, strip_locations replaced_node) - - let canonical_with_constant_arbitrary () = - QCheck.make (canonical_with_constant_gen ()) -end diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/test_tez.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/test_tez.ml deleted file mode 100644 index 5809c11c2adf..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/test_tez.ml +++ /dev/null @@ -1,70 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context -open Environment - -(* This module wraps the errors from the protocol *) -open Tez - -let ( +? ) t1 t2 = t1 +? t2 |> wrap_tzresult - -let ( -? ) t1 t2 = t1 -? t2 |> wrap_tzresult - -let ( *? ) t1 t2 = t1 *? t2 |> wrap_tzresult - -let ( /? ) t1 t2 = t1 /? t2 |> wrap_tzresult - -let ( +! ) t1 t2 = - match t1 +? t2 with Ok r -> r | Error _ -> Pervasives.failwith "adding tez" - -let ( -! ) t1 t2 = - match t1 -? t2 with - | Ok r -> r - | Error _ -> Pervasives.failwith "subtracting tez" - -let ( *! ) t1 t2 = - match t1 *? t2 with - | Ok r -> r - | Error _ -> Pervasives.failwith "multiplying tez" - -let ( /! ) t1 t2 = - match t1 /? t2 with - | Ok r -> r - | Error _ -> Pervasives.failwith "dividing tez" - -let of_int x = - match Tez.of_mutez (Int64.mul (Int64.of_int x) 1_000_000L) with - | None -> invalid_arg "tez_of_int" - | Some x -> x - -let of_mutez_exn x = - match Tez.of_mutez x with None -> invalid_arg "tez_of_mutez" | Some x -> x - -let to_mutez = Tez.to_mutez - -let max_tez = - match Tez.of_mutez Int64.max_int with None -> assert false | Some p -> p diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/testable.ml b/src/proto_012_Psithaca/lib_protocol/test/helpers/testable.ml deleted file mode 100644 index 287b46840b00..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/testable.ml +++ /dev/null @@ -1,38 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let contract : Protocol.Alpha_context.Contract.t Alcotest.testable = - let open Protocol in - let open Alpha_context in - Alcotest.testable Contract.pp Contract.( = ) - -let script_expr : Protocol.Alpha_context.Script.expr Alcotest.testable = - Alcotest.testable Michelson_v1_printer.print_expr ( = ) - -let trace : tztrace Alcotest.testable = Alcotest.testable pp_print_trace ( = ) - -let protocol_error : Environment.Error_monad.error Alcotest.testable = - let open Environment.Error_monad in - Alcotest.testable pp ( = ) diff --git a/src/proto_012_Psithaca/lib_protocol/test/helpers/tezos-012-Psithaca-test-helpers.opam b/src/proto_012_Psithaca/lib_protocol/test/helpers/tezos-012-Psithaca-test-helpers.opam deleted file mode 100644 index 3bd2292f1fa6..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/helpers/tezos-012-Psithaca-test-helpers.opam +++ /dev/null @@ -1,25 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-base" - "tezos-stdlib-unix" - "tezos-shell-services" - "tezos-protocol-environment" - "tezos-protocol-012-Psithaca" - "tezos-protocol-012-Psithaca-parameters" - "tezos-client-012-Psithaca" - "tezos-test-helpers" - "alcotest-lwt" - "qcheck-alcotest" -] -build: [ - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: protocol testing framework" diff --git a/src/proto_012_Psithaca/lib_protocol/test/liquidity_baking_pbt.ml b/src/proto_012_Psithaca/lib_protocol/test/liquidity_baking_pbt.ml deleted file mode 100644 index 2778520e7519..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/liquidity_baking_pbt.ml +++ /dev/null @@ -1,299 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: pbt for liquidity baking - Invocation: [QCHECK_SEED=] dune exec src/proto_alpha/lib_protocol/test/liquidity_baking_pbt.exe - Subject: Test liquidity baking contracts using randomly generated inputs. -*) - -open Protocol -open Alpha_context -open Liquidity_baking_machine - -(** We use the “machines” provided by the {! Liquidity_baking_machine} - module. Because using the [ConcreteMachine] (hence, the {! - ValidationMachine} too) is slow, we implement the following - test-suit architecture: - - - One {v QCheck v}-based test is used to validate consistency of - the {! SymbolicMachine} wrt. the [ConcreteMachine], thanks to - the {! ValidationMachine}. - - The rest of the tests use the {! SymbolicMachine} in order to be - more effective. *) - -(** [all_true l] waits for all promises of [l], and returns [true] iff - they all resolve to [true]. *) -let all_true = List.for_all_ep Fun.id - -let extract_qcheck_tzresult : unit tzresult Lwt.t -> bool = - fun p -> - match Lwt_main.run p with - | Ok () -> true - | Error err -> QCheck.Test.fail_reportf "@\n%a@." pp_print_trace err - -let rec run_and_check check scenarios env state = - match scenarios with - | step :: rst -> - let state' = SymbolicMachine.step step env state in - assert (check state state') ; - run_and_check check rst env state' - | [] -> state - -let one_balance_decreases c env state state' = - let xtz = SymbolicMachine.get_xtz_balance c state in - let tzbtc = SymbolicMachine.get_tzbtc_balance c env state in - let lqt = SymbolicMachine.get_liquidity_balance c env state in - let xtz' = SymbolicMachine.get_xtz_balance c state' in - let tzbtc' = SymbolicMachine.get_tzbtc_balance c env state' in - let lqt' = SymbolicMachine.get_liquidity_balance c env state' in - xtz' < xtz || tzbtc' < tzbtc || lqt' < lqt - || (xtz' = xtz && tzbtc' = tzbtc && lqt' = lqt) - -let get_float_balances env state = - let xtz = - Int64.to_float @@ SymbolicMachine.get_xtz_balance env.cpmm_contract state - in - let tzbtc = - Int.to_float - @@ SymbolicMachine.get_tzbtc_balance env.cpmm_contract env state - in - let lqt = - Int.to_float @@ SymbolicMachine.get_cpmm_total_liquidity env state - in - (xtz, tzbtc, lqt) - -(** [is_remove_liquidity_consistent env state state'] returns [true] - iff, when the liquidity pool decreased in [state'], then the - fraction of tzbtc and xtz returned to the liquidity provider is - lesser or equal than the fraction of lqt burnt. *) -let is_remove_liquidity_consistent env state state' = - let (xtz, tzbtc, lqt) = get_float_balances env state in - let (xtz', tzbtc', lqt') = get_float_balances env state' in - if lqt' < lqt then - let flqt = (lqt -. lqt') /. lqt in - let fxtz = (xtz -. xtz') /. xtz in - let ftzbtc = (tzbtc -. tzbtc') /. tzbtc in - fxtz <= flqt && ftzbtc <= flqt - else true - -(** [is_share_price_increasing env state state'] returns [true] iff - the product of supplies (tzbtc, and xtz) increases. - - See https://blog.nomadic-labs.com/progress-report-on-the-verification-of-liquidity-baking-smart-contracts.html#evolution-of-the-product-of-supplies *) -let is_share_price_increasing env state state' = - let (xtz, tzbtc, lqt) = get_float_balances env state in - let (xtz', tzbtc', lqt') = get_float_balances env state' in - xtz *. tzbtc /. (lqt *. lqt) <= xtz' *. tzbtc' /. (lqt' *. lqt') - -(** [positive_pools env state] returns [true] iff the three pools of - the CPMM (as identified in [env]) are strictly positive in - [state]. *) -let positive_pools env state = - let xtz = SymbolicMachine.get_xtz_balance env.cpmm_contract state in - let tzbtc = SymbolicMachine.get_tzbtc_balance env.cpmm_contract env state in - let lqt = SymbolicMachine.get_cpmm_total_liquidity env state in - 0L < xtz && 0 < tzbtc && 0 < lqt - -(** [validate_xtz_balance c env (blk, state)] returns [true] iff the - tez balance for the contract [c] is the same in [blk] and in - [state]. *) -let validate_xtz_balance : - Contract.t -> ValidationMachine.t -> bool tzresult Lwt.t = - fun contract state -> - ValidationMachine.Symbolic.get_xtz_balance contract state >>=? fun expected -> - ValidationMachine.Concrete.get_xtz_balance contract state >>=? fun amount -> - return (amount = expected) - -(** [validate_tzbtc_balance c env (blk, state)] returns [true] iff the - tzbtc balance for the contract [c] is the same in [blk] and in - [state]. *) -let validate_tzbtc_balance : - Contract.t -> Contract.t env -> ValidationMachine.t -> bool tzresult Lwt.t = - fun contract env state -> - ValidationMachine.Symbolic.get_tzbtc_balance contract env state - >>=? fun expected -> - ValidationMachine.Concrete.get_tzbtc_balance contract env state - >>=? fun amount -> return (expected = amount) - -(** [validate_liquidity_balance c env (blk, state)] returns [true] if - the contract [c] holds the same amount of liquidity in [blk] and - [state]. *) -let validate_liquidity_balance : - Contract.t -> Contract.t env -> ValidationMachine.t -> bool tzresult Lwt.t = - fun contract env state -> - ValidationMachine.Symbolic.get_liquidity_balance contract env state - >>=? fun expected -> - ValidationMachine.Concrete.get_liquidity_balance contract env state - >>=? fun amount -> return (expected = amount) - -(** [validate_balances c env (blk, state)] returns true iff the - contract [c] holds the same amount of tez, tzbtc and liquidity in - [blk] and [state]. *) -let validate_balances : - Contract.t -> Contract.t env -> ValidationMachine.t -> bool tzresult Lwt.t = - fun contract env combined_state -> - all_true - [ - validate_xtz_balance contract combined_state; - validate_tzbtc_balance contract env combined_state; - validate_liquidity_balance contract env combined_state; - ] - -(** [validate_cpmm_total_liquidity env state] returns true iff the - CPMM has distributed the same amount of liquidity tokens in its - concrete and symbolic parts of [state]. *) -let validate_cpmm_total_liquidity env state = - ValidationMachine.Concrete.get_cpmm_total_liquidity env state - >>=? fun concrete_cpmm_total_liquidity -> - ValidationMachine.Symbolic.get_cpmm_total_liquidity env state - >>=? fun ghost_cpmm_total_liquidity -> - return (concrete_cpmm_total_liquidity = ghost_cpmm_total_liquidity) - -(** [validate_consistency env (blk, state)] checks if the accounts in - [env] (the CPMM and the implicit accounts) share the same balances - in [blk] and [state]. *) -let validate_consistency : - Contract.t env -> ValidationMachine.t -> bool tzresult Lwt.t = - (* We do not try to validate the xtz balance of [holder] in this - function. Indeed, they are hard to predict due to allocation - fees, and security deposits. *) - fun env state -> - all_true - (validate_cpmm_total_liquidity env state - :: - validate_balances env.cpmm_contract env state - :: - List.map - (fun account -> validate_balances account env state) - env.implicit_accounts) - -(** [validate_storage env blk] returns [true] iff the storage of the - CPMM contract is consistent wrt. to its actual balances (tez, - tzbtc, and liquidity). *) -let validate_storage : - Contract.t env -> ConcreteMachine.t -> bool tzresult Lwt.t = - fun env blk -> - Cpmm_repr.Storage.get (B blk) ~contract:env.cpmm_contract - >>=? fun cpmm_storage -> - all_true - [ - (* 1. Check the CPMM's [xtzPool] is equal to the actual CPMM balance *) - ( ConcreteMachine.get_xtz_balance env.cpmm_contract blk - >>=? fun cpmm_xtz -> return (cpmm_xtz = Tez.to_mutez cpmm_storage.xtzPool) - ); - (* 2. Check the CPMM’s [lqtTotal] is correct wrt. liquidity contract *) - ( Lqt_fa12_repr.Storage.get (B blk) ~contract:env.liquidity_contract - >>=? fun liquidity_storage -> - return (cpmm_storage.lqtTotal = liquidity_storage.totalSupply) ); - (* 3. Check the CPMM’s [tokenPool] is correct *) - ( ConcreteMachine.get_tzbtc_balance env.cpmm_contract env blk - >>=? fun cpmm_tzbtc -> - return (Z.to_int cpmm_storage.tokenPool = cpmm_tzbtc) ); - ] - -(** [machine_validation_tests] is a list of asynchronous tests aiming - at asserting the correctness and consistencies of the machines - themselves. *) -let machine_validation_tests = - [ - QCheck.Test.make - ~count:10 - ~name:"Concrete/Symbolic Consistency" - (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 10) - (fun (specs, scenario) -> - extract_qcheck_tzresult - (let invariant = validate_consistency in - ValidationMachine.build ~invariant specs >>=? fun (state, env) -> - ValidationMachine.run ~invariant scenario env state >>=? fun _ -> - return_unit)); - QCheck.Test.make - ~count:10 - ~name:"Storage consistency" - (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 10) - (fun (specs, scenario) -> - extract_qcheck_tzresult - (let invariant = validate_storage in - ConcreteMachine.build ~invariant specs >>=? fun (state, env) -> - ConcreteMachine.run ~invariant scenario env state >>=? fun _ -> - return_unit)); - QCheck.Test.make - ~count:100_000 - ~name:"Positive pools" - (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 50) - (fun (specs, scenario) -> - extract_qcheck_tzresult - (let invariant = positive_pools in - let (state, env) = SymbolicMachine.build ~invariant specs in - let _ = SymbolicMachine.run ~invariant scenario env state in - return_unit)); - ] - -(** [economic_tests] is a list of asynchronous tests aiming at - asserting the good economic properties of the Liquidity Baking - feature. *) -let economic_tests = - [ - QCheck.Test.make - ~count:100_000 - ~name:"No global gain" - (Liquidity_baking_generator.arb_adversary_scenario 1_000_000 1_000_000 50) - (fun (specs, attacker, scenario) -> - let (state, env) = SymbolicMachine.build ~subsidy:0L specs in - let _ = - run_and_check (one_balance_decreases attacker env) scenario env state - in - true); - QCheck.Test.make - ~count:100_000 - ~name:"Remove liquidities is consistent" - (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 50) - (fun (specs, scenario) -> - let (state, env) = SymbolicMachine.build ~subsidy:0L specs in - let _ = - run_and_check (is_remove_liquidity_consistent env) scenario env state - in - true); - QCheck.Test.make - ~count:100_000 - ~name:"Share price only increases" - (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 50) - (fun (specs, scenario) -> - let (state, env) = SymbolicMachine.build ~subsidy:0L specs in - let _ = - run_and_check (is_share_price_increasing env) scenario env state - in - true); - ] - -let _ = - let open Lib_test.Qcheck_helpers in - Alcotest.run - "Liquidity baking PBT" - [ - ("Machines Cross-Validation", qcheck_wrap machine_validation_tests); - ("Economic Properties", qcheck_wrap economic_tests); - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/main.ml b/src/proto_012_Psithaca/lib_protocol/test/main.ml deleted file mode 100644 index 5afd5cdfd88a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/main.ml +++ /dev/null @@ -1,82 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol - Invocation: dune build @src/proto_alpha/lib_protocol/runtest - Subject: Entrypoint -*) - -let () = - Alcotest_lwt.run - "protocol_012_Psithaca" - [ - ("transfer", Test_transfer.tests); - ("origination", Test_origination.tests); - ("activation", Test_activation.tests); - ("revelation", Test_reveal.tests); - ("endorsement", Test_endorsement.tests); - ("preendorsement", Test_preendorsement.tests); - ("double endorsement", Test_double_endorsement.tests); - ("double preendorsement", Test_double_preendorsement.tests); - ("double baking", Test_double_baking.tests); - ("seed", Test_seed.tests); - ("baking", Test_baking.tests); - ("delegation", Test_delegation.tests); - ("deactivation", Test_deactivation.tests); - ("combined", Test_combined_operations.tests); - ("qty", Test_qty.tests); - ("voting", Test_voting.tests); - ("interpretation", Test_interpretation.tests); - ("typechecking", Test_typechecking.tests); - ("fixed point computation", Test_fixed_point.tests); - ("gas levels", Test_gas_levels.tests); - ("saturation arithmetic", Test_saturation.tests); - ("gas cost functions", Test_gas_costs.tests); - ("lazy storage diff", Test_lazy_storage_diff.tests); - ("global table of constants", Test_global_constants_storage.tests); - ("sapling", Test_sapling.tests); - ("helpers rpcs", Test_helpers_rpcs.tests); - ("failing_noop operation", Test_failing_noop.tests); - ("storage description", Test_storage.tests); - ("time", Test_time_repr.tests); - ("constants", Test_constants.tests); - ("level module", Test_level_module.tests); - ("liquidity baking", Test_liquidity_baking.tests); - ("temp big maps", Test_temp_big_maps.tests); - ("timelock", Test_timelock.tests); - ("script typed ir size", Test_script_typed_ir_size.tests); - ("ticket storage", Test_ticket_storage.tests); - ("ticket scanner", Test_ticket_scanner.tests); - ("ticket balance key", Test_ticket_balance_key.tests); - ("fitness", Test_fitness.tests); - ("round", Test_round_repr.tests); - ("participation monitoring", Test_participation.tests); - ("frozen deposits", Test_frozen_deposits.tests); - ("token movements", Test_token.tests); - ("receipt encodings", Test_receipt.tests); - ] - |> Lwt_main.run diff --git a/src/proto_012_Psithaca/lib_protocol/test/saturation_fuzzing.ml b/src/proto_012_Psithaca/lib_protocol/test/saturation_fuzzing.ml deleted file mode 100644 index bc3a97638f99..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/saturation_fuzzing.ml +++ /dev/null @@ -1,183 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol Library - Invocation: dune exec src/proto_alpha/lib_protocol/test/saturation_fuzzing.exe - Subject: Operations in Saturation_repr -*) - -open Protocol.Saturation_repr -open Lib_test.Qcheck_helpers - -(** A generator that returns a [t] that cannot be [saturated] *) -let unsatured_arb = of_option_arb @@ QCheck.map of_int_opt QCheck.int - -(** The general generator for [t]: generates both unsaturated values - and [saturated]. *) -let t_arb : may_saturate t QCheck.arbitrary = - QCheck.frequency [(1, QCheck.always saturated); (4, unsatured_arb)] - -(* Test. - * Tests that [add] commutes. - *) -let test_add_commutes = - QCheck.Test.make - ~name:"t1 + t2 = t2 + t1" - (QCheck.pair t_arb t_arb) - (fun (t1, t2) -> - let t1_plus_t2 = add t1 t2 in - let t2_plus_t1 = add t2 t1 in - qcheck_eq ~pp t1_plus_t2 t2_plus_t1) - -(* Test. - * Tests that [mul] commutes. - *) -let test_mul_commutes = - QCheck.Test.make - ~name:"t1 * t2 = t2 * t1" - (QCheck.pair t_arb t_arb) - (fun (t1, t2) -> - let t1_times_t2 = mul t1 t2 in - let t2_times_t1 = mul t2 t1 in - qcheck_eq ~pp t1_times_t2 t2_times_t1) - -(* Test. - * Tests that [zero] is neutral for [add]. - *) -let test_add_zero = - QCheck.Test.make ~name:"t + 0 = t" t_arb (fun t -> - let t_plus_zero = add t zero in - qcheck_eq' ~pp ~expected:t ~actual:t_plus_zero ()) - -(* Test. - * Tests that t1 + t2 >= t1 - *) -let test_add_neq = - QCheck.Test.make - ~name:"t1 + t2 >= t1" - (QCheck.pair t_arb t_arb) - (fun (t1, t2) -> - let t1_plus_t2 = add t1 t2 in - t1_plus_t2 >= t1) - -(* Test. - * Tests that 1 is neutral for [mul]. - *) -let test_mul_one = - let one = safe_int 1 in - QCheck.Test.make ~name:"t * 1 = t" t_arb (fun t -> - let t_times_one = mul t one in - qcheck_eq' ~pp ~expected:t ~actual:t_times_one ()) - -(* Test. - * Tests that [t] times [0] equals [0]. - *) -let test_mul_zero = - QCheck.Test.make ~name:"t * 0 = 0" t_arb (fun t -> - let t_times_zero = mul t zero in - qcheck_eq' ~pp ~expected:zero ~actual:t_times_zero ()) - -(* Test. - * Tests that [t] [sub] [zero] equals [t]. - *) -let test_sub_zero = - QCheck.Test.make ~name:"t - 0 = t" t_arb (fun t -> - let t_sub_zero = sub t zero in - qcheck_eq' ~pp ~expected:t ~actual:t_sub_zero ()) - -(* Test. - * Tests that [t] [sub] [t] equals [zero]. - *) -let test_sub_itself = - QCheck.Test.make ~name:"t - t = 0" t_arb (fun t -> - let t_sub_t = sub t t in - qcheck_eq' ~pp ~expected:zero ~actual:t_sub_t ()) - -(* Test. - * Tests that t1 - t2 <= t1 - *) -let test_sub_neq = - QCheck.Test.make - ~name:"t1 - t2 <= t1" - (QCheck.pair t_arb t_arb) - (fun (t1, t2) -> - let t1_minus_t2 = sub t1 t2 in - t1_minus_t2 <= t1) - -(* Test. - * Tests that (t1 + t2) - t2 <= t1 - *) -let test_add_sub = - QCheck.Test.make - ~name:"(t1 + t2) - t2 <= t1" - (QCheck.pair t_arb t_arb) - (fun (t1, t2) -> - let lhs = sub (add t1 t2) t2 in - lhs <= t1) - -(* Test. - * Tests that (t1 - t2) + t2 >= t1 - *) -let test_sub_add = - QCheck.Test.make - ~name:"(t1 - t2) + t2 >= t1" - (QCheck.pair t_arb t_arb) - (fun (t1, t2) -> - let lhs = add (sub t1 t2) t2 in - lhs >= t1) - -(* Test. - * Tests that [saturated] >= t - *) -let test_leq_saturated = - QCheck.Test.make ~name:"t <= saturated" t_arb (fun t -> saturated >= t) - -(* Test. - * Tests that [zero] <= t - *) -let test_geq_zero = QCheck.Test.make ~name:"t >= 0" t_arb (fun t -> zero <= t) - -let tests_add = [test_add_commutes; test_add_zero; test_add_neq] - -let tests_mul = [test_mul_commutes; test_mul_one; test_mul_zero] - -let tests_sub = [test_sub_zero; test_sub_itself; test_sub_neq] - -let tests_add_sub = [test_add_sub; test_sub_add] - -let tests_boundaries = [test_leq_saturated; test_geq_zero] - -let () = - Alcotest.run - "Saturation" - [ - ("add", qcheck_wrap tests_add); - ("mul", qcheck_wrap tests_mul); - ("sub", qcheck_wrap tests_sub); - ("add and sub", qcheck_wrap tests_add_sub); - ("<= and >=", qcheck_wrap tests_boundaries); - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_activation.ml b/src/proto_012_Psithaca/lib_protocol/test/test_activation.ml deleted file mode 100644 index 8dbcfde004c4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_activation.ml +++ /dev/null @@ -1,587 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (activation) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^activation$" - Subject: The activation operation creates an implicit contract from a - registered commitment present in the context. It is - parametrized by a public key hash (pkh) and a secret. - - The commitments are composed of : - - a blinded pkh that can be revealed by the secret ; - - an amount. - - The commitments and the secrets are generated from - /scripts/create_genesis/create_genesis.py and should be - coherent. -*) - -open Protocol -open Alpha_context -open Test_tez - -(* Generated commitments and secrets *) - -let commitments = - List.map - (fun (bpkh, a) -> - Commitment. - { - blinded_public_key_hash = Blinded_public_key_hash.of_b58check_exn bpkh; - amount = Tez.of_mutez_exn (Int64.of_string a); - }) - [ - ("btz1bRL4X5BWo2Fj4EsBdUwexXqgTf75uf1qa", "23932454669343"); - ("btz1SxjV1syBgftgKy721czKi3arVkVwYUFSv", "72954577464032"); - ("btz1LtoNCjiW23txBTenALaf5H6NKF1L3c1gw", "217487035428349"); - ("btz1SUd3mMhEBcWudrn8u361MVAec4WYCcFoy", "4092742372031"); - ("btz1MvBXf4orko1tsGmzkjLbpYSgnwUjEe81r", "17590039016550"); - ("btz1LoDZ3zsjgG3k3cqTpUMc9bsXbchu9qMXT", "26322312350555"); - ("btz1RMfq456hFV5AeDiZcQuZhoMv2dMpb9hpP", "244951387881443"); - ("btz1Y9roTh4A7PsMBkp8AgdVFrqUDNaBE59y1", "80065050465525"); - ("btz1Q1N2ePwhVw5ED3aaRVek6EBzYs1GDkSVD", "3569618927693"); - ("btz1VFFVsVMYHd5WfaDTAt92BeQYGK8Ri4eLy", "9034781424478"); - ] - -type secret_account = { - account : public_key_hash; - activation_code : Blinded_public_key_hash.activation_code; - amount : Tez.t; -} - -let secrets () = - (* Exported from proto_alpha client - TODO : remove when relocated to lib_crypto *) - let read_key mnemonic email password = - match Tezos_client_base.Bip39.of_words mnemonic with - | None -> assert false - | Some t -> - (* TODO: unicode normalization (NFKD)... *) - let passphrase = Bytes.(cat (of_string email) (of_string password)) in - let sk = Tezos_client_base.Bip39.to_seed ~passphrase t in - let sk = Bytes.sub sk 0 32 in - let sk : Signature.Secret_key.t = - Ed25519 - (Data_encoding.Binary.of_bytes_exn Ed25519.Secret_key.encoding sk) - in - let pk = Signature.Secret_key.to_public_key sk in - let pkh = Signature.Public_key.hash pk in - (pkh, pk, sk) - in - List.map - (fun (mnemonic, secret, amount, pkh, password, email) -> - let (pkh', pk, sk) = read_key mnemonic email password in - let pkh = Signature.Public_key_hash.of_b58check_exn pkh in - assert (Signature.Public_key_hash.equal pkh pkh') ; - let account = Account.{pkh; pk; sk} in - Account.add_account account ; - { - account = account.pkh; - activation_code = - Stdlib.Option.get - (Blinded_public_key_hash.activation_code_of_hex secret); - amount = - WithExceptions.Option.to_exn - ~none:(Invalid_argument "tez conversion") - (Tez.of_mutez (Int64.of_string amount)); - }) - [ - ( [ - "envelope"; - "hospital"; - "mind"; - "sunset"; - "cancel"; - "muscle"; - "leisure"; - "thumb"; - "wine"; - "market"; - "exit"; - "lucky"; - "style"; - "picnic"; - "success"; - ], - "0f39ed0b656509c2ecec4771712d9cddefe2afac", - "23932454669343", - "tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF", - "z0eZHQQGKt", - "cjgfoqmk.wpxnvnup@tezos.example.org" ); - ( [ - "flag"; - "quote"; - "will"; - "valley"; - "mouse"; - "chat"; - "hold"; - "prosper"; - "silk"; - "tent"; - "cruel"; - "cause"; - "demise"; - "bottom"; - "practice"; - ], - "41f98b15efc63fa893d61d7d6eee4a2ce9427ac4", - "72954577464032", - "tz1X4maqF9tC1Yn4jULjHRAyzjAtc25Z68TX", - "MHErskWPE6", - "oklmcktr.ztljnpzc@tezos.example.org" ); - ( [ - "library"; - "away"; - "inside"; - "paper"; - "wise"; - "focus"; - "sweet"; - "expose"; - "require"; - "change"; - "stove"; - "planet"; - "zone"; - "reflect"; - "finger"; - ], - "411dfef031eeecc506de71c9df9f8e44297cf5ba", - "217487035428349", - "tz1SWBY7rWMutEuWS54Pt33MkzAS6eWkUuTc", - "0AO6BzQNfN", - "ctgnkvqm.kvtiybky@tezos.example.org" ); - ( [ - "cruel"; - "fluid"; - "damage"; - "demand"; - "mimic"; - "above"; - "village"; - "alpha"; - "vendor"; - "staff"; - "absent"; - "uniform"; - "fire"; - "asthma"; - "milk"; - ], - "08d7d355bc3391d12d140780b39717d9f46fcf87", - "4092742372031", - "tz1amUjiZaevaxQy5wKn4SSRvVoERCip3nZS", - "9kbZ7fR6im", - "bnyxxzqr.tdszcvqb@tezos.example.org" ); - ( [ - "opera"; - "divorce"; - "easy"; - "myself"; - "idea"; - "aim"; - "dash"; - "scout"; - "case"; - "resource"; - "vote"; - "humor"; - "ticket"; - "client"; - "edge"; - ], - "9b7cad042fba557618bdc4b62837c5f125b50e56", - "17590039016550", - "tz1Zaee3QBtD4ErY1SzqUvyYTrENrExu6yQM", - "suxT5H09yY", - "iilkhohu.otnyuvna@tezos.example.org" ); - ( [ - "token"; - "similar"; - "ginger"; - "tongue"; - "gun"; - "sort"; - "piano"; - "month"; - "hotel"; - "vote"; - "undo"; - "success"; - "hobby"; - "shell"; - "cart"; - ], - "124c0ca217f11ffc6c7b76a743d867c8932e5afd", - "26322312350555", - "tz1geDUUhfXK1EMj7VQdRjug1MoFe6gHWnCU", - "4odVdLykaa", - "kwhlglvr.slriitzy@tezos.example.org" ); - ( [ - "shield"; - "warrior"; - "gorilla"; - "birth"; - "steak"; - "neither"; - "feel"; - "only"; - "liberty"; - "float"; - "oven"; - "extend"; - "pulse"; - "suffer"; - "vapor"; - ], - "ac7a2125beea68caf5266a647f24dce9fea018a7", - "244951387881443", - "tz1h3nY7jcZciJgAwRhWcrEwqfVp7VQoffur", - "A6yeMqBFG8", - "lvrmlbyj.yczltcxn@tezos.example.org" ); - ( [ - "waste"; - "open"; - "scan"; - "tip"; - "subway"; - "dance"; - "rent"; - "copper"; - "garlic"; - "laundry"; - "defense"; - "clerk"; - "another"; - "staff"; - "liar"; - ], - "2b3e94be133a960fa0ef87f6c0922c19f9d87ca2", - "80065050465525", - "tz1VzL4Xrb3fL3ckvqCWy6bdGMzU2w9eoRqs", - "oVZqpq60sk", - "rfodmrha.zzdndvyk@tezos.example.org" ); - ( [ - "fiber"; - "next"; - "property"; - "cradle"; - "silk"; - "obey"; - "gossip"; - "push"; - "key"; - "second"; - "across"; - "minimum"; - "nice"; - "boil"; - "age"; - ], - "dac31640199f2babc157aadc0021cd71128ca9ea", - "3569618927693", - "tz1RUHg536oRKhPLFfttcB5gSWAhh4E9TWjX", - "FfytQTTVbu", - "owecikdy.gxnyttya@tezos.example.org" ); - ( [ - "print"; - "labor"; - "budget"; - "speak"; - "poem"; - "diet"; - "chunk"; - "eternal"; - "book"; - "saddle"; - "pioneer"; - "ankle"; - "happy"; - "only"; - "exclude"; - ], - "bb841227f250a066eb8429e56937ad504d7b34dd", - "9034781424478", - "tz1M1LFbgctcPWxstrao9aLr2ECW1fV4pH5u", - "zknAl3lrX2", - "ettilrvh.zsrqrbud@tezos.example.org" ); - ] - -(** Helper: Create a genesis block with predefined commitments, - accounts and balances. *) -let activation_init () = - Context.init ~consensus_threshold:0 ~commitments 1 >|=? fun (b, cs) -> - secrets () |> fun ss -> (b, cs, ss) - -(** Verify the genesis block created by [activation_init] can be - baked. *) -let test_simple_init_with_commitments () = - activation_init () >>=? fun (blk, _contracts, _secrets) -> - Block.bake blk >>=? fun _ -> return_unit - -(** A single activation *) -let test_single_activation () = - activation_init () >>=? fun (blk, _contracts, secrets) -> - let ({account; activation_code; amount = expected_amount; _} as _first_one) = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets - in - (* Contract does not exist *) - Assert.balance_is - ~loc:__LOC__ - (B blk) - (Contract.implicit_contract account) - Tez.zero - >>=? fun () -> - Op.activation (B blk) account activation_code >>=? fun operation -> - Block.bake ~operation blk >>=? fun blk -> - (* Contract does exist *) - Assert.balance_is - ~loc:__LOC__ - (B blk) - (Contract.implicit_contract account) - expected_amount - -(** 10 activations, one per bake. *) -let test_multi_activation_1 () = - activation_init () >>=? fun (blk, _contracts, secrets) -> - List.fold_left_es - (fun blk {account; activation_code; amount = expected_amount; _} -> - Op.activation (B blk) account activation_code >>=? fun operation -> - Block.bake ~operation blk >>=? fun blk -> - Assert.balance_is - ~loc:__LOC__ - (B blk) - (Contract.implicit_contract account) - expected_amount - >|=? fun () -> blk) - blk - secrets - >>=? fun _ -> return_unit - -(** All of the 10 activations occur in one bake. *) -let test_multi_activation_2 () = - activation_init () >>=? fun (blk, _contracts, secrets) -> - List.fold_left_es - (fun ops {account; activation_code; _} -> - Op.activation (B blk) account activation_code >|=? fun op -> op :: ops) - [] - secrets - >>=? fun ops -> - Block.bake ~operations:ops blk >>=? fun blk -> - List.iter_es - (fun {account; amount = expected_amount; _} -> - (* Contract does exist *) - Assert.balance_is - ~loc:__LOC__ - (B blk) - (Contract.implicit_contract account) - expected_amount) - secrets - -(** Transfer with activated account. *) -let test_activation_and_transfer () = - activation_init () >>=? fun (blk, contracts, secrets) -> - let ({account; activation_code; _} as _first_one) = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets - in - let bootstrap_contract = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts - in - let first_contract = Contract.implicit_contract account in - Op.activation (B blk) account activation_code >>=? fun operation -> - Block.bake ~operation blk >>=? fun blk -> - Context.Contract.balance (B blk) bootstrap_contract >>=? fun amount -> - Test_tez.( /? ) amount 2L >>?= fun half_amount -> - Context.Contract.balance (B blk) first_contract - >>=? fun activated_amount_before -> - Op.transaction (B blk) bootstrap_contract first_contract half_amount - >>=? fun operation -> - Block.bake ~operation blk >>=? fun blk -> - Assert.balance_was_credited - ~loc:__LOC__ - (B blk) - (Contract.implicit_contract account) - activated_amount_before - half_amount - -(** Transfer to an unactivated account and then activating it. *) -let test_transfer_to_unactivated_then_activate () = - activation_init () >>=? fun (blk, contracts, secrets) -> - let ({account; activation_code; amount} as _first_one) = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets - in - let bootstrap_contract = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts - in - let unactivated_commitment_contract = Contract.implicit_contract account in - Context.Contract.balance (B blk) bootstrap_contract >>=? fun b_amount -> - b_amount /? 2L >>?= fun b_half_amount -> - Incremental.begin_construction blk >>=? fun inc -> - Op.transaction - (I inc) - bootstrap_contract - unactivated_commitment_contract - b_half_amount - >>=? fun op -> - Incremental.add_operation inc op >>=? fun inc -> - Op.activation (I inc) account activation_code >>=? fun op' -> - Incremental.add_operation inc op' >>=? fun inc -> - Incremental.finalize_block inc >>=? fun blk2 -> - Assert.balance_was_credited - ~loc:__LOC__ - (B blk2) - (Contract.implicit_contract account) - amount - b_half_amount - -(****************************************************************) -(* The following test scenarios are supposed to raise errors. *) -(****************************************************************) - -(** Invalid pkh activation: expected to fail as the context does not - contain any commitment. *) -let test_invalid_activation_with_no_commitments () = - Context.init 1 >>=? fun (blk, _) -> - let secrets = secrets () in - let ({account; activation_code; _} as _first_one) = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets - in - Op.activation (B blk) account activation_code >>=? fun operation -> - Block.bake ~operation blk >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Invalid_activation _ -> true - | _ -> false) - -(** Wrong activation: wrong secret given in the operation. *) -let test_invalid_activation_wrong_secret () = - activation_init () >>=? fun (blk, _, secrets) -> - let ({account; _} as _first_one) = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth secrets 0 - in - let ({activation_code; _} as _second_one) = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth secrets 1 - in - Op.activation (B blk) account activation_code >>=? fun operation -> - Block.bake ~operation blk >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Invalid_activation _ -> true - | _ -> false) - -(** Invalid pkh activation : expected to fail as the context does not - contain an associated commitment. *) -let test_invalid_activation_inexistent_pkh () = - activation_init () >>=? fun (blk, _, secrets) -> - let ({activation_code; _} as _first_one) = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets - in - let inexistent_pkh = - Signature.Public_key_hash.of_b58check_exn - "tz1PeQHGKPWSpNoozvxgqLN9TFsj6rDqNV3o" - in - Op.activation (B blk) inexistent_pkh activation_code >>=? fun operation -> - Block.bake ~operation blk >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Invalid_activation _ -> true - | _ -> false) - -(** Invalid pkh activation : expected to fail as the commitment has - already been claimed. *) -let test_invalid_double_activation () = - activation_init () >>=? fun (blk, _, secrets) -> - let ({account; activation_code; _} as _first_one) = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets - in - Incremental.begin_construction blk >>=? fun inc -> - Op.activation (I inc) account activation_code >>=? fun op -> - Incremental.add_operation inc op >>=? fun inc -> - Op.activation (I inc) account activation_code >>=? fun op' -> - Incremental.add_operation inc op' >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Invalid_activation _ -> true - | _ -> false) - -(** Transfer from an unactivated commitment account. *) -let test_invalid_transfer_from_unactivated_account () = - activation_init () >>=? fun (blk, contracts, secrets) -> - let ({account; _} as _first_one) = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets - in - let bootstrap_contract = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts - in - let unactivated_commitment_contract = Contract.implicit_contract account in - (* No activation *) - Op.transaction - (B blk) - unactivated_commitment_contract - bootstrap_contract - Tez.one - >>=? fun operation -> - Block.bake ~operation blk >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Contract_storage.Empty_implicit_contract pkh -> - if pkh = account then true else false - | _ -> false) - -let tests = - [ - Tztest.tztest - "init with commitments" - `Quick - test_simple_init_with_commitments; - Tztest.tztest "single activation" `Quick test_single_activation; - Tztest.tztest "multi-activation one-by-one" `Quick test_multi_activation_1; - Tztest.tztest - "multi-activation all at a time" - `Quick - test_multi_activation_2; - Tztest.tztest "activation and transfer" `Quick test_activation_and_transfer; - Tztest.tztest - "transfer to unactivated account then activate" - `Quick - test_transfer_to_unactivated_then_activate; - Tztest.tztest - "invalid activation with no commitments" - `Quick - test_invalid_activation_with_no_commitments; - Tztest.tztest - "invalid activation with commitments" - `Quick - test_invalid_activation_inexistent_pkh; - Tztest.tztest - "invalid double activation" - `Quick - test_invalid_double_activation; - Tztest.tztest - "wrong activation code" - `Quick - test_invalid_activation_wrong_secret; - Tztest.tztest - "invalid transfer from unactivated account" - `Quick - test_invalid_transfer_from_unactivated_account; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_baking.ml b/src/proto_012_Psithaca/lib_protocol/test/test_baking.ml deleted file mode 100644 index 4242171ae8af..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_baking.ml +++ /dev/null @@ -1,455 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (baking) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^baking$" - Subject: Rewards and bakers. Tests based on RPCs. -*) - -open Protocol -open Alpha_context - -(** Verify the level is correctly computed when the first cycle is - passed and after baking a certain fixed number of blocks (10 for - the moment). The result should be [blocks_per_cycle + 10] where - [blocks_per_cycle] comes from the constants of the selected - protocol. - - IMPROVEMENTS: - - Randomize the number of cycle. - - Randomize the number of accounts created at the beginning - - Randomize the blocks per cycle. - - Randomize the number of blocks baked after the n cycles baked - previously. *) -let test_cycle () = - Context.init ~consensus_threshold:0 5 >>=? fun (b, _) -> - Context.get_constants (B b) >>=? fun csts -> - let blocks_per_cycle = csts.parametric.blocks_per_cycle in - let pp fmt x = Format.fprintf fmt "%ld" x in - Block.bake b >>=? fun b -> - Block.bake_until_cycle_end b >>=? fun b -> - Context.get_level (B b) >>?= fun curr_level -> - Assert.equal - ~loc:__LOC__ - Int32.equal - "not the right level" - pp - (Alpha_context.Raw_level.to_int32 curr_level) - blocks_per_cycle - >>=? fun () -> - Context.get_level (B b) >>?= fun l -> - Block.bake_n 10 b >>=? fun b -> - Context.get_level (B b) >>?= fun curr_level -> - Assert.equal - ~loc:__LOC__ - Int32.equal - "not the right level" - pp - (Alpha_context.Raw_level.to_int32 curr_level) - (Int32.add (Alpha_context.Raw_level.to_int32 l) 10l) - -let wrap et = et >>= fun e -> Lwt.return (Environment.wrap_tzresult e) - -(** Test baking [n] cycles in a raw works smoothly. *) -let test_bake_n_cycles n () = - let open Block in - let policy = By_round 0 in - Context.init ~consensus_threshold:0 1 >>=? fun (block, _contracts) -> - Block.bake_until_n_cycle_end ~policy n block >>=? fun _block -> return () - -(** Check that, after one or two voting periods, the voting power of a baker is - updated according to the rewards it receives for baking the blocks in the - voting periods. Note we consider only one baker. *) -let test_voting_power_cache () = - let open Block in - let policy = By_round 0 in - Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _contracts) -> - Context.get_constants (B genesis) >>=? fun csts -> - let blocks_per_voting_period = csts.parametric.blocks_per_voting_period in - let blocks_per_voting_periods n = - Int64.of_int (n * Int32.to_int blocks_per_voting_period) - in - Context.get_baking_reward_fixed_portion (B genesis) >>=? fun baking_reward -> - let tokens_per_roll = csts.parametric.tokens_per_roll in - let rolls_from_tez amount = - Test_tez.(amount /! Tez.to_mutez tokens_per_roll) - |> Tez.to_mutez |> Int64.to_int - in - Context.get_bakers (B genesis) >>=? fun bakers -> - let baker = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bakers in - Context.Delegate.full_balance (B genesis) baker >>=? fun full_balance -> - let assert_voting_power n block = - Context.get_voting_power (B block) baker >>=? fun voting_power -> - Assert.equal_int ~loc:__LOC__ n (Int32.to_int voting_power) - in - (* the voting power is the number of rolls *) - let initial_voting_power_at_genesis = rolls_from_tez full_balance in - assert_voting_power initial_voting_power_at_genesis genesis >>=? fun () -> - let rewards_after_one_voting_period = - Test_tez.(baking_reward *! blocks_per_voting_periods 1) - in - let expected_delta_voting_power_after_one_voting_period = - rolls_from_tez rewards_after_one_voting_period - in - Block.bake_n ~policy (Int32.to_int blocks_per_voting_period) genesis - >>=? fun block -> - let expected_voting_power_after_one_voting_period = - initial_voting_power_at_genesis - + expected_delta_voting_power_after_one_voting_period - in - assert_voting_power expected_voting_power_after_one_voting_period block - >>=? fun () -> - let rewards_after_two_voting_periods = - Test_tez.(baking_reward *! blocks_per_voting_periods 2) - in - let expected_delta_voting_power_after_two_voting_periods = - rolls_from_tez rewards_after_two_voting_periods - in - Block.bake_n ~policy (Int32.to_int blocks_per_voting_period) block - >>=? fun block -> - let expected_voting_power_after_two_voting_periods = - initial_voting_power_at_genesis - + expected_delta_voting_power_after_two_voting_periods - in - assert_voting_power expected_voting_power_after_two_voting_periods block - -(** test that after baking, one gets the baking reward fixed portion. *) -let test_basic_baking_reward () = - Context.init ~consensus_threshold:0 1 >>=? fun (genesis, contracts) -> - Block.bake genesis >>=? fun b -> - let baker = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - Context.Contract.pkh baker >>=? fun baker_pkh -> - Context.Contract.balance (B b) baker >>=? fun bal -> - Context.Delegate.current_frozen_deposits (B b) baker_pkh - >>=? fun frozen_deposit -> - Context.get_baking_reward_fixed_portion (B b) >>=? fun br -> - let open Test_tez in - let expected_initial_balance = bal +! frozen_deposit -! br in - Assert.equal_tez - ~loc:__LOC__ - expected_initial_balance - Account.default_initial_balance - -let get_contract_for_pkh contracts pkh = - let rec find_contract = function - | [] -> assert false - | c :: t -> - Context.Contract.pkh c >>=? fun c_pkh -> - if Signature.Public_key_hash.equal c_pkh pkh then return c - else find_contract t - in - find_contract contracts - -let get_baker_different_from_baker ctxt baker = - Context.get_bakers - ~filter:(fun x -> not (Signature.Public_key_hash.equal x.delegate baker)) - ctxt - >>=? fun bakers -> - return (WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bakers) - -(** Test that - - the block producer gets the bonus for including the endorsements; - - the payload producer gets the baking reward. - - The test checks this in two scenarios, in the first one the payload producer - and the block producer are the same delegate, in the second one they are - different. The first scenario is checked by first baking block [b1] and then - block [b2] at round 0 containing a number of endorsements for [b1] and the - checking the balance of [b2]'s baker. For the second scenario another block - [b2'] is build on top of [b1] by a different baker, using the same payload as - [b2]. *) -let test_rewards_block_and_payload_producer () = - Context.init ~consensus_threshold:1 10 >>=? fun (genesis, contracts) -> - Context.get_baker (B genesis) ~round:0 >>=? fun baker_b1 -> - get_contract_for_pkh contracts baker_b1 >>=? fun baker_b1_contract -> - Block.bake ~policy:(By_round 0) genesis >>=? fun b1 -> - Context.get_endorsers (B b1) >>=? fun endorsers -> - List.map_es - (function - | {Plugin.RPC.Validators.delegate; slots; _} -> return (delegate, slots)) - endorsers - >>=? fun endorsers -> - (* We let just a part of the endorsers vote; we assume here that 5 of 10 - endorsers will have together at least one slot (to pass the threshold), but - not all slots (to make the test more interesting, otherwise we know the - total endorsing power). *) - let endorsers = List.take_n 5 endorsers in - List.map_ep - (fun endorser -> - Op.endorsement ~delegate:endorser ~endorsed_block:b1 (B genesis) () - >|=? Operation.pack) - endorsers - >>=? fun endos -> - let endorsing_power = - List.fold_left - (fun acc (_pkh, slots) -> acc + List.length slots) - 0 - endorsers - in - let fee = Tez.one in - Op.transaction (B b1) ~fee baker_b1_contract baker_b1_contract Tez.zero - >>=? fun tx -> - Block.bake ~policy:(By_round 0) ~operations:(tx :: endos) b1 >>=? fun b2 -> - Context.get_baker (B b1) ~round:0 >>=? fun baker_b2 -> - get_contract_for_pkh contracts baker_b2 >>=? fun baker_b2_contract -> - Context.Contract.balance (B b2) baker_b2_contract >>=? fun bal -> - Context.Delegate.current_frozen_deposits (B b2) baker_b2 - >>=? fun frozen_deposit -> - Context.get_baking_reward_fixed_portion (B b2) >>=? fun baking_reward -> - Context.get_bonus_reward (B b2) ~endorsing_power >>=? fun bonus_reward -> - (if Signature.Public_key_hash.equal baker_b2 baker_b1 then - Context.get_baking_reward_fixed_portion (B b1) - else return Tez.zero) - >>=? fun reward_for_b1 -> - (* we are in the first scenario where the payload producer is the same as the - block producer, in our case, [baker_b2]. [baker_b2] gets the baking reward - plus the fee for the transaction [tx]. *) - let expected_balance = - let open Test_tez in - Account.default_initial_balance -! frozen_deposit +! baking_reward - +! bonus_reward +! reward_for_b1 +! fee - in - Assert.equal_tez ~loc:__LOC__ bal expected_balance >>=? fun () -> - (* Some new baker [baker_b2'] bakes b2' at the first round which does not - correspond to a slot of [baker_b2] and it includes the PQC for [b2]. We - check that the fixed baking reward goes to the payload producer [baker_b2], - while the bonus goes to the the block producer (aka baker) [baker_b2']. *) - Context.get_endorsers (B b2) >>=? fun endorsers -> - List.map_es - (function - | {Plugin.RPC.Validators.delegate; slots; _} -> return (delegate, slots)) - endorsers - >>=? fun preendorsers -> - List.map_ep - (fun endorser -> - Op.preendorsement ~delegate:endorser ~endorsed_block:b2 (B b1) () - >|=? Operation.pack) - preendorsers - >>=? fun preendos -> - Context.get_baker (B b1) ~round:0 >>=? fun baker_b2 -> - get_baker_different_from_baker (B b1) baker_b2 >>=? fun baker_b2' -> - Block.bake - ~payload_round:(Some Round.zero) - ~locked_round:(Some Round.zero) - ~policy:(By_account baker_b2') - ~operations:(tx :: preendos @ endos) - b1 - >>=? fun b2' -> - (* [baker_b2], as payload producer, gets the block reward and the fees *) - Context.Contract.balance (B b2') baker_b2_contract >>=? fun bal -> - Context.Delegate.current_frozen_deposits (B b2') baker_b2 - >>=? fun frozen_deposit -> - let reward_for_b1 = - if Signature.Public_key_hash.equal baker_b2 baker_b1 then baking_reward - else Tez.zero - in - let expected_balance = - let open Test_tez in - Account.default_initial_balance +! baking_reward -! frozen_deposit - +! reward_for_b1 +! fee - in - Assert.equal_tez ~loc:__LOC__ bal expected_balance >>=? fun () -> - (* [baker_b2'] gets the bonus because he is the one who included the - endorsements *) - get_contract_for_pkh contracts baker_b2' >>=? fun baker_b2'_contract -> - Context.Contract.balance (B b2') baker_b2'_contract >>=? fun bal' -> - Context.Delegate.current_frozen_deposits (B b2') baker_b2' - >>=? fun frozen_deposits' -> - Context.get_baker (B genesis) ~round:0 >>=? fun baker_b1 -> - let reward_for_b1' = - if Signature.Public_key_hash.equal baker_b2' baker_b1 then baking_reward - else Tez.zero - in - let expected_balance' = - let open Test_tez in - Account.default_initial_balance +! bonus_reward +! reward_for_b1' - -! frozen_deposits' - in - Assert.equal_tez ~loc:__LOC__ bal' expected_balance' - -(** We test that: - - a delegate that has active stake can bake; - - a delegate that has no active stake cannot bake. -*) -let test_enough_active_stake_to_bake ~has_active_stake () = - Context.init 1 >>=? fun (b_for_constants, _) -> - Context.get_constants (B b_for_constants) - >>=? fun Constants.{parametric = {tokens_per_roll; _}; _} -> - let tpr = Tez.to_mutez tokens_per_roll in - (* N.B. setting the balance has an impact on the active stake; without - delegation, the full balance is the same as the staking balance and the - active balance is less or equal the staking balance (see - [Delegate_storage.select_distribution_for_cycle]). *) - let initial_bal1 = if has_active_stake then tpr else Int64.sub tpr 1L in - Context.init ~initial_balances:[initial_bal1; tpr] ~consensus_threshold:0 2 - >>=? fun (b0, accounts) -> - let (account1, _account2) = - match accounts with a1 :: a2 :: _ -> (a1, a2) | _ -> assert false - in - Context.Contract.pkh account1 >>=? fun pkh1 -> - Context.get_constants (B b0) - >>=? fun Constants.{parametric = {baking_reward_fixed_portion; _}; _} -> - Block.bake ~policy:(By_account pkh1) b0 >>= fun b1 -> - if has_active_stake then - b1 >>?= fun b1 -> - Context.Contract.balance (B b1) account1 >>=? fun bal -> - Context.Delegate.current_frozen_deposits (B b1) pkh1 - >>=? fun frozen_deposit -> - let expected_bal = - Test_tez.( - Tez.of_mutez_exn initial_bal1 - -! frozen_deposit +! baking_reward_fixed_portion) - in - Assert.equal_tez ~loc:__LOC__ bal expected_bal - else - (* pkh1 has less than tokens_per_roll so it will have no slots, thus it - cannot be a proposer, thus it cannot bake. Precisely, bake fails because - get_next_baker_by_account fails with "No slots found for pkh1" *) - Assert.error ~loc:__LOC__ b1 (fun _ -> true) - -let test_committee_sampling () = - let test_distribution max_round distribution = - let (initial_balances, bounds) = List.split distribution in - let accounts = - Account.generate_accounts ~initial_balances (List.length initial_balances) - in - let bootstrap_accounts = - List.map - (fun (acc, tez) -> - Default_parameters.make_bootstrap_account - (acc.Account.pkh, acc.Account.pk, tez)) - accounts - in - let constants = - { - Default_parameters.constants_test with - consensus_committee_size = max_round; - consensus_threshold = 0; - } - in - let parameters = - Default_parameters.parameters_of_constants ~bootstrap_accounts constants - in - Block.genesis_with_parameters parameters >>=? fun genesis -> - Plugin.RPC.Baking_rights.get Block.rpc_ctxt ~all:true ~max_round genesis - >|=? fun bakers -> - let stats = Stdlib.Hashtbl.create 10 in - Stdlib.List.iter2 - (fun (acc, _) bounds -> - Stdlib.Hashtbl.add stats acc.Account.pkh (bounds, 0)) - accounts - bounds ; - List.iter - (fun {Plugin.RPC.Baking_rights.delegate = pkh; _} -> - let (bounds, n) = Stdlib.Hashtbl.find stats pkh in - Stdlib.Hashtbl.replace stats pkh (bounds, n + 1)) - bakers ; - let one_failed = ref false in - Format.eprintf - "Testing with baker distribution [%a], committee size %d.@\n" - (Format.pp_print_list - ~pp_sep:(fun ppf () -> Format.fprintf ppf ",") - (fun ppf (tez, _) -> Format.fprintf ppf "%Ld" tez)) - distribution - max_round ; - Stdlib.Hashtbl.iter - (fun pkh ((min_p, max_p), n) -> - let failed = not (n >= min_p && n <= max_p) in - Format.eprintf - " - %s%a %d%s@." - (if failed then "\027[1m" else "") - Signature.Public_key_hash.pp - pkh - n - (if failed then - Format.asprintf " [FAIL]\027[0m should be \\in [%d,%d]" min_p max_p - else "") ; - if failed then one_failed := true) - stats ; - if !one_failed then - Stdlib.failwith - "The proportion of bakers marked as [FAILED] in the log output appear \ - in the wrong proportion in the committee." - else Format.eprintf "Test succesful.@\n" - in - (* The tests below are not deterministic, but the probability that - they fail is infinitesimal. *) - test_distribution - 100_000 - [ - (8_000_000_000L, (9_400, 10_600)); - (8_000_000_000L, (9_400, 10_600)); - (8_000_000_000L, (9_400, 10_600)); - (8_000_000_000L, (9_400, 10_600)); - (8_000_000_000L, (9_400, 10_600)); - (8_000_000_000L, (9_400, 10_600)); - (8_000_000_000L, (9_400, 10_600)); - (8_000_000_000L, (9_400, 10_600)); - (8_000_000_000L, (9_400, 10_600)); - (8_000_000_000L, (9_400, 10_600)); - ] - >>=? fun () -> - test_distribution - 10_000 - [ - (16_000_000_000L, (4_600, 5_400)); - (8_000_000_000L, (2_200, 2_800)); - (8_000_000_000L, (2_200, 2_800)); - ] - >>=? fun () -> - test_distribution - 10_000 - [(792_000_000_000L, (9_830, 9_970)); (8_000_000_000L, (40, 160))] - -let tests = - [ - Tztest.tztest "cycle" `Quick test_cycle; - Tztest.tztest - "test_bake_n_cycles for 12 cycles" - `Quick - (test_bake_n_cycles 12); - Tztest.tztest "voting_power" `Quick test_voting_power_cache; - Tztest.tztest - "the fixed baking reward is given after a bake" - `Quick - test_basic_baking_reward; - Tztest.tztest - "test that the block producer gets the bonus while the payload producer \ - gets the baking reward " - `Quick - test_rewards_block_and_payload_producer; - Tztest.tztest - "test that a delegate with 8000 tez can bake" - `Quick - (test_enough_active_stake_to_bake ~has_active_stake:true); - Tztest.tztest - "test that a delegate with 7999 tez cannot bake" - `Quick - (test_enough_active_stake_to_bake ~has_active_stake:false); - Tztest.tztest "test committee sampling" `Quick test_committee_sampling; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_combined_operations.ml b/src/proto_012_Psithaca/lib_protocol/test/test_combined_operations.ml deleted file mode 100644 index 027f10eb2fe4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_combined_operations.ml +++ /dev/null @@ -1,335 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (combined operations) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^combined$" - Subject: Multiple operations can be grouped in one ensuring their - deterministic application. - - If an invalid operation is present in this group of - operations, the previously applied operations are - backtracked leaving the context unchanged and the - following operations are skipped. Fees attributed to the - operations are collected by the baker nonetheless. - - Only manager operations are allowed in multiple transactions. - They must all belong to the same manager as there is only one - signature. -*) - -open Protocol -open Alpha_context - -let ten_tez = Test_tez.of_int 10 - -let gas_limit = Alpha_context.Gas.Arith.integral_of_int_exn 3000 - -(** Groups ten transactions between the same parties. *) -let test_multiple_transfers () = - Context.init 3 >>=? fun (blk, contracts) -> - let (c1, c2, c3) = - match contracts with [c1; c2; c3] -> (c1, c2, c3) | _ -> assert false - in - List.map_es - (fun _ -> Op.transaction ~gas_limit (B blk) c1 c2 Tez.one) - (1 -- 10) - >>=? fun ops -> - Op.combine_operations ~source:c1 (B blk) ops >>=? fun operation -> - Context.Contract.pkh c3 >>=? fun baker_pkh -> - Incremental.begin_construction ~policy:(By_account baker_pkh) blk - >>=? fun inc -> - Context.Contract.balance (I inc) c1 >>=? fun c1_old_balance -> - Context.Contract.balance (I inc) c2 >>=? fun c2_old_balance -> - Incremental.add_operation inc operation >>=? fun inc -> - Assert.balance_was_debited - ~loc:__LOC__ - (I inc) - c1 - c1_old_balance - (Test_tez.of_int 10) - >>=? fun () -> - Assert.balance_was_credited - ~loc:__LOC__ - (I inc) - c2 - c2_old_balance - (Test_tez.of_int 10) - >>=? fun () -> return_unit - -(** Groups ten delegated originations. *) -let test_multiple_origination_and_delegation () = - Context.init 2 >>=? fun (blk, contracts) -> - let (c1, c2) = - match contracts with [c1; c2] -> (c1, c2) | _ -> assert false - in - let n = 10 in - Context.get_constants (B blk) - >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> - Context.Contract.pkh c2 >>=? fun delegate_pkh -> - (* Deploy n smart contracts with dummy scripts from c1 *) - List.map_es - (fun i -> - Op.origination - ~gas_limit - ~delegate:delegate_pkh - ~counter:(Z.of_int i) - ~fee:Tez.zero - ~script:Op.dummy_script - ~credit:(Test_tez.of_int 10) - (B blk) - c1) - (1 -- n) - >>=? fun originations -> - (* These computed originated contracts are not the ones really created *) - (* We will extract them from the tickets *) - let (originations_operations, _) = List.split originations in - Op.combine_operations ~source:c1 (B blk) originations_operations - >>=? fun operation -> - Incremental.begin_construction blk >>=? fun inc -> - Context.Contract.balance (I inc) c1 >>=? fun c1_old_balance -> - Incremental.add_operation inc operation >>=? fun inc -> - (* To retrieve the originated contracts, it is easier to extract them - from the tickets. Else, we could (could we ?) hash each combined - operation individually. *) - let tickets = Incremental.rev_tickets inc in - let open Apply_results in - let tickets = - List.fold_left - (fun acc -> function - | No_operation_metadata -> assert false - | Operation_metadata {contents} -> - to_list (Contents_result_list contents) @ acc) - [] - tickets - |> List.rev - in - let new_contracts = - List.map - (function - | Contents_result - (Manager_operation_result - { - operation_result = - Applied (Origination_result {originated_contracts = [h]; _}); - _; - }) -> - h - | _ -> assert false) - tickets - in - (* Previous balance - (Credit (n * 10tz) + Origination cost (n tz)) *) - Test_tez.(cost_per_byte *? Int64.of_int origination_size) - >>?= fun origination_burn -> - Test_tez.(origination_burn *? Int64.of_int n) - >>?= fun origination_total_cost -> - Test_tez.( *? ) Op.dummy_script_cost 10L - >>? Test_tez.( +? ) (Test_tez.of_int (10 * n)) - >>? Test_tez.( +? ) origination_total_cost - >>?= fun total_cost -> - Assert.balance_was_debited ~loc:__LOC__ (I inc) c1 c1_old_balance total_cost - >>=? fun () -> - List.iter_es - (fun c -> Assert.balance_is ~loc:__LOC__ (I inc) c (Test_tez.of_int 10)) - new_contracts - -let expect_balance_too_low = function - | Environment.Ecoproto_error (Contract_storage.Balance_too_low _) :: _ -> - return_unit - | _ -> - failwith - "Contract should not have a sufficient balance : operation expected to \ - fail." - -(** Groups three operations, the middle one failing. - Checks that the receipt is consistent. - Variant without fees. *) -let test_failing_operation_in_the_middle () = - Context.init 2 >>=? fun (blk, contracts) -> - let (c1, c2) = - match contracts with [c1; c2] -> (c1, c2) | _ -> assert false - in - Op.transaction ~gas_limit ~fee:Tez.zero (B blk) c1 c2 Tez.one >>=? fun op1 -> - Op.transaction ~gas_limit ~fee:Tez.zero (B blk) c1 c2 Test_tez.max_tez - >>=? fun op2 -> - Op.transaction ~gas_limit ~fee:Tez.zero (B blk) c1 c2 Tez.one >>=? fun op3 -> - let operations = [op1; op2; op3] in - Op.combine_operations ~source:c1 (B blk) operations >>=? fun operation -> - Incremental.begin_construction blk >>=? fun inc -> - Context.Contract.balance (I inc) c1 >>=? fun c1_old_balance -> - Context.Contract.balance (I inc) c2 >>=? fun c2_old_balance -> - Incremental.add_operation ~expect_failure:expect_balance_too_low inc operation - >>=? fun inc -> - let tickets = Incremental.rev_tickets inc in - let open Apply_results in - let tickets = - List.fold_left - (fun acc -> function - | No_operation_metadata -> assert false - | Operation_metadata {contents} -> - to_list (Contents_result_list contents) @ acc) - [] - tickets - in - (match tickets with - | Contents_result - (Manager_operation_result {operation_result = Backtracked _; _}) - :: Contents_result - (Manager_operation_result {operation_result = Failed (_, trace); _}) - :: Contents_result - (Manager_operation_result {operation_result = Skipped _; _}) - :: _ -> - let trace_string = - Format.asprintf "%a" Environment.Error_monad.pp_trace trace - in - let expect = - Format.asprintf "Balance of contract %a too low" Context.Contract.pp c1 - in - assert (Astring.String.is_infix ~affix:expect trace_string) - | _ -> assert false) ; - Assert.balance_is ~loc:__LOC__ (I inc) c1 c1_old_balance >>=? fun () -> - Assert.balance_is ~loc:__LOC__ (I inc) c2 c2_old_balance >>=? fun () -> - return_unit - -(** Groups three operations, the middle one failing. - Checks that the receipt is consistent. - Variant with fees, that should be spent even in case of failure. *) -let test_failing_operation_in_the_middle_with_fees () = - Context.init 2 >>=? fun (blk, contracts) -> - let (c1, c2) = - match contracts with [c1; c2] -> (c1, c2) | _ -> assert false - in - Op.transaction ~fee:Tez.one (B blk) c1 c2 Tez.one >>=? fun op1 -> - Op.transaction ~fee:Tez.one (B blk) c1 c2 Test_tez.max_tez >>=? fun op2 -> - Op.transaction ~fee:Tez.one (B blk) c1 c2 Tez.one >>=? fun op3 -> - let operations = [op1; op2; op3] in - Op.combine_operations ~source:c1 (B blk) operations >>=? fun operation -> - Incremental.begin_construction blk >>=? fun inc -> - Context.Contract.balance (I inc) c1 >>=? fun c1_old_balance -> - Context.Contract.balance (I inc) c2 >>=? fun c2_old_balance -> - Incremental.add_operation ~expect_failure:expect_balance_too_low inc operation - >>=? fun inc -> - let tickets = Incremental.rev_tickets inc in - let open Apply_results in - let tickets = - List.fold_left - (fun acc -> function - | No_operation_metadata -> assert false - | Operation_metadata {contents} -> - to_list (Contents_result_list contents) @ acc) - [] - tickets - in - (match tickets with - | Contents_result - (Manager_operation_result {operation_result = Backtracked _; _}) - :: Contents_result - (Manager_operation_result {operation_result = Failed (_, trace); _}) - :: Contents_result - (Manager_operation_result {operation_result = Skipped _; _}) - :: _ -> - let trace_string = - Format.asprintf "%a" Environment.Error_monad.pp_trace trace - in - let expect = - Format.asprintf "Balance of contract %a too low" Context.Contract.pp c1 - in - assert (Astring.String.is_infix ~affix:expect trace_string) - | _ -> assert false) ; - (* In the presence of a failure, all the fees are collected. Even for skipped operations. *) - Assert.balance_was_debited - ~loc:__LOC__ - (I inc) - c1 - c1_old_balance - (Test_tez.of_int 3) - >>=? fun () -> - Assert.balance_is ~loc:__LOC__ (I inc) c2 c2_old_balance >>=? fun () -> - return_unit - -let expect_wrong_signature list = - if - List.exists - (function - | Environment.Ecoproto_error Apply.Inconsistent_sources -> true - | _ -> false) - list - then return_unit - else - failwith - "Packed operation has invalid source in the middle : operation expected \ - to fail." - -let test_wrong_signature_in_the_middle () = - Context.init 2 >>=? function - | (_, []) | (_, [_]) -> assert false - | (blk, c1 :: c2 :: _) -> - Op.transaction ~gas_limit ~fee:Tez.one (B blk) c1 c2 Tez.one - >>=? fun op1 -> - Op.transaction ~gas_limit ~fee:Tez.one (B blk) c2 c1 Tez.one - >>=? fun op2 -> - Incremental.begin_construction blk >>=? fun inc -> - (* Make legit transfers, performing reveals *) - Incremental.add_operation inc op1 >>=? fun inc -> - Incremental.add_operation inc op2 >>=? fun inc -> - (* Cook transactions for actual test *) - Op.transaction ~gas_limit ~fee:Tez.one (I inc) c1 c2 Tez.one - >>=? fun op1 -> - Op.transaction ~gas_limit ~fee:Tez.one (I inc) c1 c2 Tez.one - >>=? fun op2 -> - Op.transaction ~gas_limit ~fee:Tez.one (I inc) c1 c2 Tez.one - >>=? fun op3 -> - Op.transaction ~gas_limit ~fee:Tez.one (I inc) c2 c1 Tez.one - >>=? fun spurious_operation -> - let operations = [op1; op2; op3] in - Op.combine_operations ~spurious_operation ~source:c1 (I inc) operations - >>=? fun operation -> - Incremental.add_operation - ~expect_apply_failure:expect_wrong_signature - inc - operation - >>=? fun _inc -> return_unit - -let tests = - [ - Tztest.tztest "multiple transfers" `Quick test_multiple_transfers; - Tztest.tztest - "multiple originations and delegations" - `Quick - test_multiple_origination_and_delegation; - Tztest.tztest - "Failing operation in the middle" - `Quick - test_failing_operation_in_the_middle; - Tztest.tztest - "Failing operation in the middle (with fees)" - `Quick - test_failing_operation_in_the_middle_with_fees; - Tztest.tztest - "Failing operation (wrong manager in the middle of a pack)" - `Quick - test_wrong_signature_in_the_middle; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_constants.ml b/src/proto_012_Psithaca/lib_protocol/test/test_constants.ml deleted file mode 100644 index 3476f92ac99f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_constants.ml +++ /dev/null @@ -1,87 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (baking) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^constants$" - Subject: the consistency of parametric constants - *) - -open Test_tez - -let test_constants_consistency () = - let open Default_parameters in - List.iter_es - Block.check_constants_consistency - [constants_mainnet; constants_sandbox; constants_test] - -let test_max_operations_ttl () = - let open Protocol in - (* We check the rationale that the value for [max_operations_time_to_live] is the following: - - [minimal_time_between_blocks * max_operations_time_to_live = 3600] *) - let constants = Default_parameters.constants_mainnet in - Environment.wrap_tzresult - (Alpha_context.Period.mult - (Int32.of_int constants.max_operations_time_to_live) - constants.minimal_block_delay) - >>?= fun result -> - Assert.equal - ~loc:__LOC__ - (fun x y -> Alpha_context.Period.compare x y = 0) - "max_operations_ttl" - Alpha_context.Period.pp - Alpha_context.Period.one_hour - result - -(** Test that the amount of the liquidity baking subsidy is epsilon smaller than - 1/16th of the maximum reward. *) -let liquidity_baking_subsidy_param () = - let constants = Default_parameters.constants_mainnet in - constants.baking_reward_bonus_per_slot - *? Int64.of_int (constants.consensus_committee_size / 3) - >>?= fun baking_reward_bonus -> - constants.baking_reward_fixed_portion +? baking_reward_bonus - >>?= fun baking_rewards -> - constants.endorsing_reward_per_slot - *? Int64.of_int constants.consensus_committee_size - >>?= fun validators_rewards -> - baking_rewards +? validators_rewards >>?= fun total_rewards -> - total_rewards /? 16L >>?= fun expected_subsidy -> - constants.liquidity_baking_subsidy -? expected_subsidy >>?= fun diff -> - let max_diff = 1000 (* mutez *) in - Assert.leq_int ~loc:__LOC__ (Int64.to_int (to_mutez diff)) max_diff - -let tests = - [ - Tztest.tztest "constants consistency" `Quick test_constants_consistency; - Tztest.tztest "max_operations_ttl" `Quick test_max_operations_ttl; - Tztest.tztest - "test liquidity_baking_subsidy parameter is 1/16th of total baking \ - rewards" - `Quick - liquidity_baking_subsidy_param; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_deactivation.ml b/src/proto_012_Psithaca/lib_protocol/test/test_deactivation.ml deleted file mode 100644 index d30303acb4eb..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_deactivation.ml +++ /dev/null @@ -1,351 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (rolls) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^deactivation$" - Subject: After a given number of cycles during which a delegate has not - made use of its baking and endorsing rights, its account will - be deactivated for validator selection. To bake/endorse - again, it will have to re-activate its account. -*) - -open Protocol -open Alpha_context -open Test_tez - -let account_pair = function [a1; a2] -> (a1, a2) | _ -> assert false - -let wrap e = Lwt.return (Environment.wrap_tzresult e) - -(** Check that [Delegate.staking_balance] is the same as [Delegate.full_balance] - (this is not true in general, but in these tests it is because they only deal - with self-delegation. Also, check that [Delegate.staking_balance] coincides - with [Stake_storage.get] when the account is active and it has at least one - roll. *) -let check_stake ~loc (b : Block.t) (account : Account.t) = - Context.Delegate.staking_balance (B b) account.pkh >>=? fun staking_balance -> - Context.Delegate.full_balance (B b) account.pkh >>=? fun full_balance -> - Assert.equal_tez ~loc full_balance staking_balance >>=? fun () -> - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >>= wrap - >>=? fun ctxt -> - Stake_storage.get ctxt account.pkh >>= wrap >>=? fun stake -> - Assert.equal_int64 - ~loc - (Tez_repr.to_mutez stake) - (Tez.to_mutez staking_balance) - -(** Check that [Stake_storage.get] returns 0 (following a deactivation). Note - that in case of deactivation [Delegate.staking_balance] does not necessarily - coincide with [Stake_storage.get] in that [Delegate.staking_balance] may be - positive (while [Stake_storage.get] returns 0 because the account is no - longer in [Active_delegate_with_one_roll] because of deactivation, see - [Stake_storage].) *) -let check_no_stake ~loc (b : Block.t) (account : Account.t) = - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >>= wrap - >>=? fun ctxt -> - Stake_storage.get ctxt account.pkh >>= wrap >>=? fun stake -> - Assert.equal_int64 ~loc (Tez_repr.to_mutez stake) 0L - -(** Create a block with two initialized contracts/accounts. Assert - that the first account has a staking balance that is equal to its - own balance, and that its staking rights are consistent - (check_stake). *) -let test_simple_staking_rights () = - Context.init 2 >>=? fun (b, accounts) -> - let (a1, _a2) = account_pair accounts in - Context.Contract.balance (B b) a1 >>=? fun balance -> - Context.Contract.pkh a1 >>=? fun delegate1 -> - Context.Delegate.current_frozen_deposits (B b) delegate1 - >>=? fun frozen_deposits -> - let expected_initial_balance = - Account.default_initial_balance -! frozen_deposits - in - Assert.equal_tez ~loc:__LOC__ balance expected_initial_balance >>=? fun () -> - Context.Contract.manager (B b) a1 >>=? fun m1 -> - Context.Delegate.info (B b) m1.pkh >>=? fun info -> - Assert.equal_tez - ~loc:__LOC__ - Account.default_initial_balance - info.staking_balance - >>=? fun () -> check_stake ~loc:__LOC__ b m1 - -(** Create a block with two initialized contracts/accounts. Bake - five blocks. Assert that the staking balance of the first account - equals to its balance. Then both accounts have consistent staking - rights. *) -let test_simple_staking_rights_after_baking () = - Context.init ~consensus_threshold:0 2 >>=? fun (b, accounts) -> - let (a1, a2) = account_pair accounts in - Context.Contract.manager (B b) a1 >>=? fun m1 -> - Context.Contract.manager (B b) a2 >>=? fun m2 -> - Block.bake_n ~policy:(By_account m2.pkh) 5 b >>=? fun b -> - Context.Contract.balance (B b) a1 >>=? fun balance -> - Context.Contract.pkh a1 >>=? fun delegate1 -> - Context.Delegate.current_frozen_deposits (B b) delegate1 - >>=? fun frozen_deposits -> - balance +? frozen_deposits >>?= fun full_balance -> - Context.Delegate.info (B b) m1.pkh >>=? fun info -> - Assert.equal_tez ~loc:__LOC__ full_balance info.staking_balance >>=? fun () -> - check_stake ~loc:__LOC__ b m1 >>=? fun () -> check_stake ~loc:__LOC__ b m2 - -let check_active_staking_balance ~loc ~deactivated b (m : Account.t) = - Context.Delegate.info (B b) m.pkh >>=? fun info -> - Assert.equal_bool ~loc info.deactivated deactivated >>=? fun () -> - if deactivated then check_no_stake ~loc b m else check_stake ~loc b m - -let run_until_deactivation () = - Context.init ~consensus_threshold:0 2 >>=? fun (b, accounts) -> - let (a1, a2) = account_pair accounts in - Context.Contract.balance (B b) a1 >>=? fun balance_start -> - Context.Contract.manager (B b) a1 >>=? fun m1 -> - Context.Contract.manager (B b) a2 >>=? fun m2 -> - check_active_staking_balance ~loc:__LOC__ ~deactivated:false b m1 - >>=? fun () -> - Context.Delegate.info (B b) m1.pkh >>=? fun info -> - Block.bake_until_cycle ~policy:(By_account m2.pkh) info.grace_period b - >>=? fun b -> - check_active_staking_balance ~loc:__LOC__ ~deactivated:false b m1 - >>=? fun () -> - Block.bake_until_cycle_end ~policy:(By_account m2.pkh) b >>=? fun b -> - check_active_staking_balance ~loc:__LOC__ ~deactivated:true b m1 - >|=? fun () -> (b, ((a1, m1), balance_start), (a2, m2)) - -(** From an initialized block with two contracts/accounts, the first - one is active then deactivated. After baking, check that the - account is active again. Baking rights are ensured. *) -let test_deactivation_then_bake () = - run_until_deactivation () - >>=? fun ( b, - ((_deactivated_contract, deactivated_account), _start_balance), - (_a2, _m2) ) -> - Block.bake ~policy:(By_account deactivated_account.pkh) b >>=? fun b -> - check_active_staking_balance - ~loc:__LOC__ - ~deactivated:false - b - deactivated_account - -(** check that an account which is deactivated for [preserved_cycles] cannot be - part of a committee *) -let test_a_really_deactivated_account_is_not_in_the_committee () = - run_until_deactivation () - >>=? fun ( b, - ((_deactivated_contract, deactivated_account), _start_balance), - (_a2, m2) ) -> - (* at this point, the deactivated account can either bake (because it still - has rights) and become active again, or, in case it is inactive for another - [preserved_cycles], it has no more rights, thus cannot be part of the - committee. *) - let constants = Default_parameters.constants_test in - Block.bake_until_n_cycle_end - (constants.preserved_cycles + 1) - ~policy:(By_account m2.pkh) - b - >>=? fun b -> - Plugin.RPC.Baking_rights.get - Block.rpc_ctxt - ~delegates:[deactivated_account.pkh] - b - >>=? fun bakers -> - match List.hd bakers with Some _ -> assert false | None -> return_unit - -(** A deactivated account, after baking with self-delegation, is - active again. Preservation of its balance is tested. Baking rights - are ensured. *) -let test_deactivation_then_self_delegation () = - run_until_deactivation () - >>=? fun ( b, - ((deactivated_contract, deactivated_account), _start_balance), - (_a2, m2) ) -> - Op.delegation (B b) deactivated_contract (Some deactivated_account.pkh) - >>=? fun self_delegation -> - Block.bake ~policy:(By_account m2.pkh) b ~operation:self_delegation - >>=? fun b -> - check_active_staking_balance - ~loc:__LOC__ - ~deactivated:false - b - deactivated_account - >>=? fun () -> check_stake ~loc:__LOC__ b deactivated_account - -(** A deactivated account, which is emptied (into a newly created sink - account), then self-delegated, becomes activated. Its balance is - zero. Baking rights are ensured. *) -let test_deactivation_then_empty_then_self_delegation () = - run_until_deactivation () - >>=? fun ( b, - ((deactivated_contract, deactivated_account), _start_balance), - (_a2, m2) ) -> - (* empty the contract *) - Context.Contract.balance (B b) deactivated_contract >>=? fun balance -> - let sink_account = Account.new_account () in - let sink_contract = Contract.implicit_contract sink_account.pkh in - Context.get_constants (B b) - >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> - cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> - let amount = - match balance -? origination_burn with Ok r -> r | Error _ -> assert false - in - Op.transaction (B b) deactivated_contract sink_contract amount - >>=? fun empty_contract -> - Block.bake ~policy:(By_account m2.pkh) ~operation:empty_contract b - >>=? fun b1 -> - (* the account is deactivated, the stake is 0. *) - check_no_stake ~loc:__LOC__ b deactivated_account >>=? fun () -> - (* self delegation *) - Op.delegation (B b1) deactivated_contract (Some deactivated_account.pkh) - >>=? fun self_delegation -> - Block.bake ~policy:(By_account m2.pkh) ~operation:self_delegation b1 - >>=? fun b2 -> - check_active_staking_balance - ~loc:__LOC__ - ~deactivated:false - b2 - deactivated_account - >>=? fun () -> - (* the account is activated, the stake is still 0. *) - Context.Contract.balance (B b2) deactivated_contract >>=? fun balance -> - Assert.equal_tez ~loc:__LOC__ Tez.zero balance - -(** A deactivated account, which is emptied, then self-delegated, then - re-credited of the sunk amount, becomes active again. Staking - rights remain consistent. *) -let test_deactivation_then_empty_then_self_delegation_then_recredit () = - run_until_deactivation () - >>=? fun ( b, - ((deactivated_contract, deactivated_account), _start_balance), - (_a2, m2) ) -> - (* empty the contract *) - Context.Contract.balance (B b) deactivated_contract >>=? fun balance -> - let sink_account = Account.new_account () in - let sink_contract = Contract.implicit_contract sink_account.pkh in - Context.get_constants (B b) - >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> - cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> - let amount = - match balance -? origination_burn with Ok r -> r | Error _ -> assert false - in - Op.transaction (B b) deactivated_contract sink_contract amount - >>=? fun empty_contract -> - Block.bake ~policy:(By_account m2.pkh) ~operation:empty_contract b - >>=? fun b0 -> - (* the account is deactivated, the stake is 0. *) - check_no_stake ~loc:__LOC__ b deactivated_account >>=? fun () -> - (**** self delegation *) - Op.delegation (B b0) deactivated_contract (Some deactivated_account.pkh) - >>=? fun self_delegation -> - Block.bake ~policy:(By_account m2.pkh) ~operation:self_delegation b0 - >>=? fun b1 -> - (* the account is still deactivated *) - check_no_stake ~loc:__LOC__ b deactivated_account >>=? fun () -> - (**** recredit *) - Op.transaction (B b1) sink_contract deactivated_contract amount - >>=? fun recredit_contract -> - Block.bake ~policy:(By_account m2.pkh) ~operation:recredit_contract b1 - >>=? fun b2 -> - check_active_staking_balance - ~loc:__LOC__ - ~deactivated:false - b2 - deactivated_account - >>=? fun () -> - Context.Contract.balance (B b2) deactivated_contract >>=? fun balance2 -> - Assert.equal_tez ~loc:__LOC__ amount balance2 >>=? fun () -> - check_stake ~loc:__LOC__ b2 deactivated_account - -(** Initialize a block with two contracts/accounts. A third new account is also - created. The first account is self-delegated. First account sends to third - one tokens_per_roll tez (so that, once it is active, it can appear in - [Active_delegate_with_one_roll]. The third account has no delegate and is - consistent for baking rights. Then, it is self-delegated and is supposed to - be activated. Again, consistency for baking rights are preserved for the - first and third accounts. *) -let test_delegation () = - Context.init ~consensus_threshold:0 2 >>=? fun (b, accounts) -> - let (a1, a2) = account_pair accounts in - let m3 = Account.new_account () in - Account.add_account m3 ; - Context.Contract.manager (B b) a1 >>=? fun m1 -> - Context.Contract.manager (B b) a2 >>=? fun m2 -> - let a3 = Contract.implicit_contract m3.pkh in - Context.Contract.delegate_opt (B b) a1 >>=? fun delegate -> - (match delegate with - | None -> assert false - | Some pkh -> assert (Signature.Public_key_hash.equal pkh m1.pkh)) ; - let constants = Default_parameters.constants_test in - let one_roll = constants.tokens_per_roll in - Op.transaction (B b) a1 a3 one_roll >>=? fun transact -> - Block.bake ~policy:(By_account m2.pkh) b ~operation:transact >>=? fun b -> - Context.Contract.delegate_opt (B b) a3 >>=? fun delegate -> - (match delegate with None -> () | Some _ -> assert false) ; - check_no_stake ~loc:__LOC__ b m3 >>=? fun () -> - Op.delegation (B b) a3 (Some m3.pkh) >>=? fun delegation -> - Block.bake ~policy:(By_account m2.pkh) b ~operation:delegation >>=? fun b -> - Context.Contract.delegate_opt (B b) a3 >>=? fun delegate -> - (match delegate with - | None -> assert false - | Some pkh -> assert (Signature.Public_key_hash.equal pkh m3.pkh)) ; - check_active_staking_balance ~loc:__LOC__ ~deactivated:false b m3 - >>=? fun () -> - check_stake ~loc:__LOC__ b m3 >>=? fun () -> check_stake ~loc:__LOC__ b m1 - -let tests = - [ - Tztest.tztest "simple staking rights" `Quick test_simple_staking_rights; - Tztest.tztest - "simple staking rights after baking" - `Quick - test_simple_staking_rights_after_baking; - Tztest.tztest "deactivation then bake" `Quick test_deactivation_then_bake; - Tztest.tztest - "deactivation then self delegation" - `Quick - test_deactivation_then_self_delegation; - Tztest.tztest - "deactivation then empty then self delegation" - `Quick - test_deactivation_then_empty_then_self_delegation; - Tztest.tztest - "deactivation then empty then self delegation then recredit" - `Quick - test_deactivation_then_empty_then_self_delegation_then_recredit; - Tztest.tztest "delegate" `Quick test_delegation; - Tztest.tztest - "a really deactivated account is not part of the committee" - `Quick - test_a_really_deactivated_account_is_not_in_the_committee; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_delegation.ml b/src/proto_012_Psithaca/lib_protocol/test/test_delegation.ml deleted file mode 100644 index ab8e525674af..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_delegation.ml +++ /dev/null @@ -1,1580 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (delegation) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^delegation$" - Subject: - Properties on bootstrap contracts (self-delegation, - cannot delete/change their delegate (as opposed to contracts - not-being-delegate which can do these), bootstrap manager - as delegate during origination). - - Properties on delegation depending on whether delegate - keys registration, through origination and delegation. -*) - -open Protocol -open Alpha_context -open Test_tez - -(*****************************************************************************) -(* Bootstrap contracts - ------------------- - Bootstrap contracts are heavily used in other tests. It is helpful to test - some properties of these contracts, so we can correctly interpret the other - tests that use them. *) -(*****************************************************************************) - -let expect_error err = function - | err0 :: _ when err = err0 -> return_unit - | _ -> failwith "Unexpected successful result" - -let expect_alpha_error err = expect_error (Environment.Ecoproto_error err) - -let expect_no_change_registered_delegate_pkh pkh = function - | Environment.Ecoproto_error (Delegate_storage.No_deletion pkh0) :: _ - when pkh0 = pkh -> - return_unit - | _ -> failwith "Delegate can not be deleted and operation should fail." - -(** Bootstrap contracts delegate to themselves. *) -let bootstrap_manager_is_bootstrap_delegate () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - let bootstrap0 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - Context.Contract.delegate (B b) bootstrap0 >>=? fun delegate0 -> - Context.Contract.manager (B b) bootstrap0 >>=? fun manager0 -> - Assert.equal_pkh ~loc:__LOC__ delegate0 manager0.pkh - -(** Bootstrap contracts cannot change their delegate. *) -let bootstrap_delegate_cannot_change ~fee () = - Context.init 2 >>=? fun (b, bootstrap_contracts) -> - let bootstrap0 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth bootstrap_contracts 0 - in - let bootstrap1 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth bootstrap_contracts 1 - in - Context.Contract.pkh bootstrap0 >>=? fun pkh1 -> - Incremental.begin_construction b ~policy:(Block.Excluding [pkh1]) - >>=? fun i -> - Context.Contract.manager (I i) bootstrap1 >>=? fun manager1 -> - Context.Contract.balance (I i) bootstrap0 >>=? fun balance0 -> - Context.Contract.delegate (I i) bootstrap0 >>=? fun delegate0 -> - (* change delegation to bootstrap1 *) - Op.delegation ~fee (I i) bootstrap0 (Some manager1.pkh) - >>=? fun set_delegate -> - if fee > balance0 then - Incremental.add_operation i set_delegate >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - Incremental.add_operation - ~expect_failure:(expect_no_change_registered_delegate_pkh delegate0) - i - set_delegate - >>=? fun i -> - Incremental.finalize_block i >>=? fun b -> - (* bootstrap0 still has same delegate *) - Context.Contract.delegate (B b) bootstrap0 >>=? fun delegate0_after -> - Assert.equal_pkh ~loc:__LOC__ delegate0_after delegate0 >>=? fun () -> - (* fee has been debited *) - Assert.balance_was_debited ~loc:__LOC__ (B b) bootstrap0 balance0 fee - -(** Bootstrap contracts cannot delete their delegation. *) -let bootstrap_delegate_cannot_be_removed ~fee () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - Incremental.begin_construction b >>=? fun i -> - Context.Contract.balance (I i) bootstrap >>=? fun balance -> - Context.Contract.delegate (I i) bootstrap >>=? fun delegate -> - Context.Contract.manager (I i) bootstrap >>=? fun manager -> - (* remove delegation *) - Op.delegation ~fee (I i) bootstrap None >>=? fun set_delegate -> - if fee > balance then - Incremental.add_operation i set_delegate >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - Incremental.add_operation - ~expect_failure:(expect_no_change_registered_delegate_pkh manager.pkh) - i - set_delegate - >>=? fun i -> - (* delegate has not changed *) - Context.Contract.delegate (I i) bootstrap >>=? fun delegate_after -> - Assert.equal_pkh ~loc:__LOC__ delegate delegate_after >>=? fun () -> - (* fee has been debited *) - Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee - -(** Contracts not registered as delegate can change their - delegation. *) -let delegate_can_be_changed_from_unregistered_contract ~fee () = - Context.init 2 >>=? fun (b, bootstrap_contracts) -> - let bootstrap0 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let bootstrap1 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth bootstrap_contracts 1 - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let unregistered = Contract.implicit_contract unregistered_pkh in - Incremental.begin_construction b >>=? fun i -> - Context.Contract.manager (I i) bootstrap0 >>=? fun manager0 -> - Context.Contract.manager (I i) bootstrap1 >>=? fun manager1 -> - let credit = of_int 10 in - Op.transaction ~fee:Tez.zero (I i) bootstrap0 unregistered credit - >>=? fun credit_contract -> - Context.Contract.balance (I i) bootstrap0 >>=? fun balance -> - Incremental.add_operation i credit_contract >>=? fun i -> - (* delegate to bootstrap0 *) - Op.delegation ~fee:Tez.zero (I i) unregistered (Some manager0.pkh) - >>=? fun set_delegate -> - Incremental.add_operation i set_delegate >>=? fun i -> - Context.Contract.delegate (I i) unregistered >>=? fun delegate -> - Assert.equal_pkh ~loc:__LOC__ delegate manager0.pkh >>=? fun () -> - (* change delegation to bootstrap1 *) - Op.delegation ~fee (I i) unregistered (Some manager1.pkh) - >>=? fun change_delegate -> - if fee > balance then - Incremental.add_operation i change_delegate >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - Incremental.add_operation i change_delegate >>=? fun i -> - (* delegate has changed *) - Context.Contract.delegate (I i) unregistered >>=? fun delegate_after -> - Assert.equal_pkh ~loc:__LOC__ delegate_after manager1.pkh >>=? fun () -> - (* fee has been debited *) - Assert.balance_was_debited ~loc:__LOC__ (I i) unregistered credit fee - -(** Contracts not registered as delegate can delete their - delegation. *) -let delegate_can_be_removed_from_unregistered_contract ~fee () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let unregistered = Contract.implicit_contract unregistered_pkh in - Incremental.begin_construction b >>=? fun i -> - Context.Contract.manager (I i) bootstrap >>=? fun manager -> - let credit = of_int 10 in - Op.transaction ~fee:Tez.zero (I i) bootstrap unregistered credit - >>=? fun credit_contract -> - Context.Contract.balance (I i) bootstrap >>=? fun balance -> - Incremental.add_operation i credit_contract >>=? fun i -> - (* delegate to bootstrap *) - Op.delegation ~fee:Tez.zero (I i) unregistered (Some manager.pkh) - >>=? fun set_delegate -> - Incremental.add_operation i set_delegate >>=? fun i -> - Context.Contract.delegate (I i) unregistered >>=? fun delegate -> - Assert.equal_pkh ~loc:__LOC__ delegate manager.pkh >>=? fun () -> - (* remove delegation *) - Op.delegation ~fee (I i) unregistered None >>=? fun delete_delegate -> - if fee > balance then - Incremental.add_operation i delete_delegate >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - Incremental.add_operation i delete_delegate >>=? fun i -> - (* the delegate has been removed *) - (Context.Contract.delegate_opt (I i) unregistered >>=? function - | None -> return_unit - | Some _ -> failwith "Expected delegate to be removed") - >>=? fun () -> - (* fee has been debited *) - Assert.balance_was_debited ~loc:__LOC__ (I i) unregistered credit fee - -(** Bootstrap keys are already registered as delegate keys. *) -let bootstrap_manager_already_registered_delegate ~fee () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - Context.Contract.manager (I i) bootstrap >>=? fun manager -> - let pkh = manager.pkh in - let impl_contract = Contract.implicit_contract pkh in - Context.Contract.balance (I i) impl_contract >>=? fun balance -> - Op.delegation ~fee (I i) impl_contract (Some pkh) >>=? fun sec_reg -> - if fee > balance then - Incremental.add_operation i sec_reg >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - Incremental.add_operation - ~expect_failure:(function - | Environment.Ecoproto_error Delegate_storage.Active_delegate :: _ -> - return_unit - | _ -> failwith "Delegate is already active and operation should fail.") - i - sec_reg - >>=? fun i -> - (* fee has been debited *) - Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract balance fee - -(** Bootstrap manager can be set as delegate of an originated contract - (through origination operation). *) -let delegate_to_bootstrap_by_origination ~fee () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - Context.Contract.manager (I i) bootstrap >>=? fun manager -> - Context.Contract.balance (I i) bootstrap >>=? fun balance -> - (* originate a contract with bootstrap's manager as delegate *) - Op.origination - ~fee - ~credit:Tez.zero - ~delegate:manager.pkh - (I i) - bootstrap - ~script:Op.dummy_script - >>=? fun (op, orig_contract) -> - Context.get_constants (I i) - >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> - (* 0.257tz *) - cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> - fee +? origination_burn >>? ( +? ) Op.dummy_script_cost >>?= fun total_fee -> - if fee > balance then - Incremental.add_operation i op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else if total_fee > balance && balance >= fee then - (* origination did not proceed; fee has been debited *) - Incremental.add_operation - i - ~expect_failure:(function - | Environment.Ecoproto_error (Contract.Balance_too_low _) :: _ -> - return_unit - | _ -> - failwith - "Not enough balance for origination burn: operation should fail.") - op - >>=? fun i -> - (* fee was taken *) - Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee - >>=? fun () -> - (* originated contract has not been created *) - Context.Contract.balance (I i) orig_contract >>= fun err -> - Assert.error ~loc:__LOC__ err (function - | RPC_context.Not_found _ -> true - | _ -> false) - else - (* bootstrap is delegate, fee + origination burn have been debited *) - Incremental.add_operation i op >>=? fun i -> - Context.Contract.delegate (I i) orig_contract >>=? fun delegate -> - Assert.equal_pkh ~loc:__LOC__ delegate manager.pkh >>=? fun () -> - Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance total_fee - -let undelegated_originated_bootstrap_contract () = - Context.init - 1 - ~bootstrap_contracts: - [ - Parameters.{delegate = None; amount = Tez.zero; script = Op.dummy_script}; - ] - >>=? fun (b, _) -> - Block.bake b >>=? fun b -> - (* We know the address of the first originated bootstrap contract because we know the bootstrap origination nonce. This address corresponds to the first TF vesting contract on mainnnet. *) - Lwt.return @@ Environment.wrap_tzresult - @@ Alpha_context.Contract.of_b58check "KT1WPEis2WhAc2FciM2tZVn8qe6pCBe9HkDp" - >>=? fun originated_bootstrap0 -> - Context.Contract.delegate_opt (B b) originated_bootstrap0 - >>=? fun delegate0 -> - match delegate0 with - | None -> return_unit - | Some _ -> failwith "Bootstrap contract should be undelegated (%s)" __LOC__ - -let tests_bootstrap_contracts = - [ - Tztest.tztest - "bootstrap contracts delegate to themselves" - `Quick - bootstrap_manager_is_bootstrap_delegate; - Tztest.tztest - "bootstrap contracts can change their delegate (small fee)" - `Quick - (bootstrap_delegate_cannot_change ~fee:Tez.one_mutez); - Tztest.tztest - "bootstrap contracts can change their delegate (max fee)" - `Quick - (bootstrap_delegate_cannot_change ~fee:max_tez); - Tztest.tztest - "bootstrap contracts cannot remove their delegation (small fee)" - `Quick - (bootstrap_delegate_cannot_be_removed ~fee:Tez.one_mutez); - Tztest.tztest - "bootstrap contracts cannot remove their delegation (max fee)" - `Quick - (bootstrap_delegate_cannot_be_removed ~fee:max_tez); - Tztest.tztest - "contracts not registered as delegate can remove their delegation (small \ - fee)" - `Quick - (delegate_can_be_changed_from_unregistered_contract ~fee:Tez.one_mutez); - Tztest.tztest - "contracts not registered as delegate can remove their delegation (max \ - fee)" - `Quick - (delegate_can_be_changed_from_unregistered_contract ~fee:max_tez); - Tztest.tztest - "contracts not registered as delegate can remove their delegation (small \ - fee)" - `Quick - (delegate_can_be_removed_from_unregistered_contract ~fee:Tez.one_mutez); - Tztest.tztest - "contracts not registered as delegate can remove their delegation (max \ - fee)" - `Quick - (delegate_can_be_removed_from_unregistered_contract ~fee:max_tez); - Tztest.tztest - "bootstrap keys are already registered as delegate keys (small fee)" - `Quick - (bootstrap_manager_already_registered_delegate ~fee:Tez.one_mutez); - Tztest.tztest - "bootstrap keys are already registered as delegate keys (max fee)" - `Quick - (bootstrap_manager_already_registered_delegate ~fee:max_tez); - Tztest.tztest - "bootstrap manager can be delegate (init origination, small fee)" - `Quick - (delegate_to_bootstrap_by_origination ~fee:Tez.one_mutez); - (* balance enough for fee but not for fee + origination burn + dummy script storage cost *) - Tztest.tztest - "bootstrap manager can be delegate (init origination, edge case)" - `Quick - (delegate_to_bootstrap_by_origination - ~fee:(Tez.of_mutez_exn 3_999_999_705_000L)); - (* fee bigger than bootstrap's initial balance*) - Tztest.tztest - "bootstrap manager can be delegate (init origination, large fee)" - `Quick - (delegate_to_bootstrap_by_origination ~fee:(Test_tez.of_int 10_000_000)); - Tztest.tztest - "originated bootstrap contract can be undelegated" - `Quick - undelegated_originated_bootstrap_contract; - ] - -(*****************************************************************************) -(* Delegate registration - --------------------- - A delegate is a pkh. Delegates must be registered. Registration is - done via the self-delegation of the implicit contract corresponding - to the pkh. The implicit contract must be credited when the - self-delegation is done. Furthermore, trying to register an already - registered key raises an error. - - In this series of tests, we verify that - 1- unregistered delegate keys cannot be delegated to, - 2- registered keys can be delegated to, - 3- registering an already registered key raises an error. - - We consider three scenarios for setting a delegate: - - through origination, - - through delegation when the implicit contract has no delegate yet, - - through delegation when the implicit contract already has a delegate. - - We also test that emptying the implicit contract linked to a - registered delegate key does not unregister the delegate key. - - Valid registration - ------------------ - Unregistered key: - - contract not credited and no self-delegation, - - contract credited but no self-delegation, - - contract not credited and self-delegation. - - Not credited: - - no credit operation - - credit operation of 1μꜩ and then debit operation of 1μꜩ *) -(*****************************************************************************) - -(* Part A. - Unregistered delegate keys cannot be used for delegation - - Two main series of tests: without self-delegation and with a failed attempt at self-delegation: - - 1/ no self-delegation - a/ no credit - - no token transfer - - credit of 1μꜩ and then debit of 1μꜩ - b/ with credit of 1μꜩ. - For every scenario, we try three different ways of delegating: - - through origination (init origination) - - through delegation when no delegate was assigned (init delegation) - - through delegation when a delegate was assigned (switch delegation). - - 2/ Self-delegation fails if the contract has no credit. We try the - two possibilities of 1a for non-credited contracts. *) - -let expect_unregistered_key pkh = function - | Environment.Ecoproto_error (Delegate_storage.Unregistered_delegate pkh0) - :: _ - when pkh = pkh0 -> - return_unit - | _ -> failwith "Delegate key is not registered: operation should fail." - -(* Part A. Section 1. - No self-delegation. *) - -(** No token transfer, no self-delegation. Originated account. If - fees are higher than balance, [Balance_too_low] is - raised. Otherwise, it checks the correct exception is raised - (unregistered key), and the fees are still debited. Using RPCs, we - verify the contract has not been originated. *) -let test_unregistered_delegate_key_init_origination ~fee () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - (* origination with delegate argument *) - Op.origination - ~fee - ~delegate:unregistered_pkh - (I i) - bootstrap - ~script:Op.dummy_script - >>=? fun (op, orig_contract) -> - Context.get_constants (I i) - >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> - cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> - fee +? origination_burn >>?= fun _total_fee -> - (* FIXME unused variable *) - Context.Contract.balance (I i) bootstrap >>=? fun balance -> - if fee > balance then - Incremental.add_operation i op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* origination did not proceed; fee has been debited *) - Incremental.add_operation - ~expect_failure:(expect_unregistered_key unregistered_pkh) - i - op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee - >>=? fun () -> - (* originated contract has not been created *) - Context.Contract.balance (I i) orig_contract >>= fun err -> - Assert.error ~loc:__LOC__ err (function - | RPC_context.Not_found _ -> true - | _ -> false) - -(** Delegation when delegate key is not assigned. Delegate account is - initialized. If fees are higher than initial credit (10 tez), - [Balance_too_low] is raised. Otherwise, fees are still debited. The - implicit contract has no delegate. *) -let test_unregistered_delegate_key_init_delegation ~fee () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - let unregistered_delegate_account = Account.new_account () in - let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in - (* initial credit for the delegated contract *) - let credit = of_int 10 in - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit - >>=? fun credit_contract -> - Incremental.add_operation i credit_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract credit >>=? fun _ -> - (* try to delegate *) - Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) - >>=? fun delegate_op -> - if fee > credit then - Incremental.add_operation i delegate_op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* fee has been debited; no delegate *) - Incremental.add_operation - i - ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) - delegate_op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract credit fee - >>=? fun () -> - (* implicit contract has no delegate *) - Context.Contract.delegate (I i) impl_contract >>= fun err -> - Assert.error ~loc:__LOC__ err (function - | RPC_context.Not_found _ -> true - | _ -> false) - -(** Re-delegation when a delegate key was already assigned. If fees - are higher than initial credit (10 tez), [Balance_too_low] is - raised. Otherwise, fees are not debited and the implicit contract - delegate remains unchanged. *) -let test_unregistered_delegate_key_switch_delegation ~fee () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let bootstrap_pkh = - Contract.is_implicit bootstrap |> WithExceptions.Option.get ~loc:__LOC__ - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - let unregistered_delegate_account = Account.new_account () in - let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in - (* initial credit for the delegated contract *) - let credit = of_int 10 in - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit - >>=? fun init_credit -> - Incremental.add_operation i init_credit >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract credit >>=? fun _ -> - (* set and check the initial delegate *) - Op.delegation ~fee:Tez.zero (I i) impl_contract (Some bootstrap_pkh) - >>=? fun delegate_op -> - Incremental.add_operation i delegate_op >>=? fun i -> - Context.Contract.delegate (I i) bootstrap >>=? fun delegate_pkh -> - Assert.equal_pkh ~loc:__LOC__ bootstrap_pkh delegate_pkh >>=? fun () -> - (* try to delegate *) - Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) - >>=? fun delegate_op -> - if fee > credit then - Incremental.add_operation i delegate_op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* fee has been debited; no delegate *) - Incremental.add_operation - i - ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) - delegate_op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract credit fee - >>=? fun () -> - (* implicit contract delegate has not changed *) - Context.Contract.delegate (I i) bootstrap >>=? fun delegate_pkh_after -> - Assert.equal_pkh ~loc:__LOC__ delegate_pkh delegate_pkh_after - -(** Same as [unregistered_delegate_key_init_origination] and credits - [amount], no self-delegation. *) -let test_unregistered_delegate_key_init_origination_credit ~fee ~amount () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - (* credit + check balance *) - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* origination with delegate argument *) - Context.Contract.balance (I i) bootstrap >>=? fun balance -> - Op.origination - ~fee - ~delegate:unregistered_pkh - (I i) - bootstrap - ~script:Op.dummy_script - >>=? fun (op, orig_contract) -> - if fee > balance then - Incremental.add_operation i op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* origination not done, fee taken *) - Incremental.add_operation - ~expect_failure:(expect_unregistered_key unregistered_pkh) - i - op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee - >>=? fun () -> - Context.Contract.balance (I i) orig_contract >>= fun err -> - Assert.error ~loc:__LOC__ err (function - | RPC_context.Not_found _ -> true - | _ -> false) - -(** Same as [unregistered_delegate_key_init_delegation] and credits - the amount [amount] of the implicit contract. *) -let test_unregistered_delegate_key_init_delegation_credit ~fee ~amount () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - let unregistered_delegate_account = Account.new_account () in - let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in - (* credit + check balance *) - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* initial credit for the delegated contract *) - let credit = of_int 10 in - credit +? amount >>?= fun balance -> - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit - >>=? fun init_credit -> - Incremental.add_operation i init_credit >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract balance >>=? fun _ -> - (* try to delegate *) - Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) - >>=? fun delegate_op -> - if fee > credit then - Incremental.add_operation i delegate_op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* fee has been taken, no delegate for contract *) - Incremental.add_operation - ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) - i - delegate_op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract balance fee - >>=? fun () -> - Context.Contract.delegate (I i) impl_contract >>= fun err -> - Assert.error ~loc:__LOC__ err (function - | RPC_context.Not_found _ -> true - | _ -> false) - -(** Same as in [unregistered_delegate_key_switch_delegation] and - credits the amount [amount] to the implicit contract. *) -let test_unregistered_delegate_key_switch_delegation_credit ~fee ~amount () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let bootstrap_pkh = - Contract.is_implicit bootstrap |> WithExceptions.Option.get ~loc:__LOC__ - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - let unregistered_delegate_account = Account.new_account () in - let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in - (* credit + check balance *) - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* initial credit for the delegated contract *) - let credit = of_int 10 in - credit +? amount >>?= fun balance -> - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit - >>=? fun init_credit -> - Incremental.add_operation i init_credit >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract balance >>=? fun _ -> - (* set and check the initial delegate *) - Op.delegation ~fee:Tez.zero (I i) impl_contract (Some bootstrap_pkh) - >>=? fun delegate_op -> - Incremental.add_operation i delegate_op >>=? fun i -> - Context.Contract.delegate (I i) bootstrap >>=? fun delegate_pkh -> - Assert.equal_pkh ~loc:__LOC__ bootstrap_pkh delegate_pkh >>=? fun () -> - (* switch delegate through delegation *) - Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) - >>=? fun delegate_op -> - if fee > credit then - Incremental.add_operation i delegate_op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* fee has been taken, delegate for contract has not changed *) - Incremental.add_operation - ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) - i - delegate_op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract balance fee - >>=? fun () -> - Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> - Assert.not_equal_pkh ~loc:__LOC__ delegate unregistered_delegate_pkh - >>=? fun () -> Assert.equal_pkh ~loc:__LOC__ delegate bootstrap_pkh - -(** A credit of some amount followed by a debit of the same amount, - no self-delegation. *) -let test_unregistered_delegate_key_init_origination_credit_debit ~fee ~amount () - = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - (* credit + check balance *) - Op.transaction (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* debit + check balance *) - Op.transaction (I i) impl_contract bootstrap amount >>=? fun debit_contract -> - Incremental.add_operation i debit_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> - (* origination with delegate argument *) - Context.Contract.balance (I i) bootstrap >>=? fun balance -> - Op.origination - ~fee - ~delegate:unregistered_pkh - (I i) - bootstrap - ~script:Op.dummy_script - >>=? fun (op, orig_contract) -> - if fee > balance then - Incremental.add_operation i op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* fee taken, origination not processed *) - Incremental.add_operation - ~expect_failure:(expect_unregistered_key unregistered_pkh) - i - op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee - >>=? fun () -> - Context.Contract.balance (I i) orig_contract >>= fun err -> - Assert.error ~loc:__LOC__ err (function - | RPC_context.Not_found _ -> true - | _ -> false) - -(** Same as in [unregistered_delegate_key_init_delegation] but credits - then debits the amount [amount] to the implicit contract. *) -let test_unregistered_delegate_key_init_delegation_credit_debit ~amount ~fee () - = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - let unregistered_delegate_account = Account.new_account () in - let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in - (* credit + check balance *) - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* debit + check balance *) - Op.transaction ~fee:Tez.zero (I i) impl_contract bootstrap amount - >>=? fun debit_contract -> - Incremental.add_operation i debit_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> - (* initial credit for the delegated contract *) - let credit = of_int 10 in - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit - >>=? fun credit_contract -> - Incremental.add_operation i credit_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract credit >>=? fun _ -> - (* try to delegate *) - Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) - >>=? fun delegate_op -> - if fee > credit then - Incremental.add_operation i delegate_op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* fee has been taken, no delegate for contract *) - Incremental.add_operation - ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) - i - delegate_op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract credit fee - >>=? fun () -> - Context.Contract.delegate (I i) impl_contract >>= fun err -> - Assert.error ~loc:__LOC__ err (function - | RPC_context.Not_found _ -> true - | _ -> false) - -(** Same as in [unregistered_delegate_key_switch_delegation] but - credits then debits the amount [amount] to the implicit contract. *) -let test_unregistered_delegate_key_switch_delegation_credit_debit ~fee ~amount - () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let bootstrap_pkh = - Contract.is_implicit bootstrap |> WithExceptions.Option.get ~loc:__LOC__ - in - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - let unregistered_delegate_account = Account.new_account () in - let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in - (* credit + check balance *) - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* debit + check balance *) - Op.transaction (I i) impl_contract bootstrap amount >>=? fun debit_contract -> - Incremental.add_operation i debit_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> - (* delegation - initial credit for the delegated contract *) - let credit = of_int 10 in - Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit - >>=? fun credit_contract -> - Incremental.add_operation i credit_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract credit >>=? fun _ -> - (* set and check the initial delegate *) - Op.delegation ~fee:Tez.zero (I i) impl_contract (Some bootstrap_pkh) - >>=? fun delegate_op -> - Incremental.add_operation i delegate_op >>=? fun i -> - Context.Contract.delegate (I i) bootstrap >>=? fun delegate_pkh -> - Assert.equal_pkh ~loc:__LOC__ bootstrap_pkh delegate_pkh >>=? fun () -> - (* switch delegate through delegation *) - Op.delegation (I i) ~fee impl_contract (Some unregistered_delegate_pkh) - >>=? fun delegate_op -> - if fee > credit then - Incremental.add_operation i delegate_op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* fee has been taken, delegate for contract has not changed *) - Incremental.add_operation - ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) - i - delegate_op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract credit fee - >>=? fun () -> - Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> - Assert.not_equal_pkh ~loc:__LOC__ delegate unregistered_delegate_pkh - -(* Part A. Section 2. - Self-delegation to an empty contract fails. *) - -(** Self-delegation with zero-balance contract should fail. *) -let test_failed_self_delegation_no_transaction () = - Context.init 1 >>=? fun (b, _) -> - Incremental.begin_construction b >>=? fun i -> - let account = Account.new_account () in - let unregistered_pkh = Account.(account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - (* check balance *) - Context.Contract.balance (I i) impl_contract >>=? fun balance -> - Assert.equal_tez ~loc:__LOC__ Tez.zero balance >>=? fun _ -> - (* self delegation fails *) - Op.delegation (I i) impl_contract (Some unregistered_pkh) - >>=? fun self_delegation -> - Incremental.add_operation i self_delegation >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Empty_implicit_contract pkh -> - if pkh = unregistered_pkh then true else false - | _ -> false) - -(** Implicit contract is credited then debited of same amount (i.e., - is emptied). Self-delegation fails. *) -let test_failed_self_delegation_emptied_implicit_contract amount () = - (* create an implicit contract *) - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let account = Account.new_account () in - let unregistered_pkh = Account.(account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - (* credit implicit contract and check balance *) - Op.transaction (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* empty implicit contract and check balance *) - Op.transaction (I i) impl_contract bootstrap amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> - (* self delegation fails *) - Op.delegation (I i) impl_contract (Some unregistered_pkh) - >>=? fun self_delegation -> - Incremental.add_operation i self_delegation >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Empty_implicit_contract pkh -> - if pkh = unregistered_pkh then true else false - | _ -> false) - -(** Implicit contract is credited with a non-zero quantity [amount] - tz, then it is delegated. The operation of debit of [amount] tz - should fail as the contract is already delegated. *) -let test_emptying_delegated_implicit_contract_fails amount () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - Context.Contract.manager (I i) bootstrap >>=? fun bootstrap_manager -> - let account = Account.new_account () in - let unregistered_pkh = Account.(account.pkh) in - let impl_contract = Contract.implicit_contract unregistered_pkh in - (* credit unregistered implicit contract and check balance *) - Op.transaction (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* delegate the contract to the bootstrap *) - Op.delegation (I i) impl_contract (Some bootstrap_manager.pkh) - >>=? fun delegation -> - Incremental.add_operation i delegation >>=? fun i -> - (* empty implicit contract and expect error since the contract is delegated *) - Op.transaction (I i) impl_contract bootstrap amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Empty_implicit_delegated_contract _ -> true - | _ -> false) - -(* Part B. - - Valid registration: - - Credit implicit contract with some ꜩ + verification of balance - - Self delegation + verification - - Empty contract + verification of balance + verification of not being erased / self-delegation - - Create delegator implicit contract w first implicit contract as delegate + verification of delegation. *) - -(** Initialized account is credited of [amount] tz, then - self-delegated. *) -let test_valid_delegate_registration_init_delegation_credit amount () = - (* create an implicit contract *) - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let delegate_account = Account.new_account () in - let delegate_pkh = Account.(delegate_account.pkh) in - let impl_contract = Contract.implicit_contract delegate_pkh in - (* credit > 0ꜩ + check balance *) - Op.transaction (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* self delegation + verification *) - Op.delegation (I i) impl_contract (Some delegate_pkh) - >>=? fun self_delegation -> - Incremental.add_operation i self_delegation >>=? fun i -> - Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> - Assert.equal_pkh ~loc:__LOC__ delegate delegate_pkh >>=? fun _ -> - (* create an implicit contract with no delegate *) - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let delegator = Contract.implicit_contract unregistered_pkh in - Op.transaction ~fee:Tez.zero (I i) bootstrap delegator Tez.one - >>=? fun credit_contract -> - Incremental.add_operation i credit_contract >>=? fun i -> - (* check no delegate for delegator contract *) - Context.Contract.delegate (I i) delegator >>= fun err -> - Assert.error ~loc:__LOC__ err (function - | RPC_context.Not_found _ -> true - | _ -> false) - >>=? fun _ -> - (* delegation to the newly registered key *) - Op.delegation (I i) delegator (Some delegate_account.pkh) - >>=? fun delegation -> - Incremental.add_operation i delegation >>=? fun i -> - (* check delegation *) - Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> - Assert.equal_pkh ~loc:__LOC__ delegator_delegate delegate_pkh - -(** Create an implicit contract, credits with [amount] - tz. Self-delegates. Create another implicit contract with - bootstrap as delegate. Re-delegate it to the first implicit - contract. *) -let test_valid_delegate_registration_switch_delegation_credit amount () = - (* create an implicit contract *) - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let delegate_account = Account.new_account () in - let delegate_pkh = Account.(delegate_account.pkh) in - let impl_contract = Contract.implicit_contract delegate_pkh in - (* credit > 0ꜩ + check balance *) - Op.transaction (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* self delegation + verification *) - Op.delegation (I i) impl_contract (Some delegate_pkh) - >>=? fun self_delegation -> - Incremental.add_operation i self_delegation >>=? fun i -> - Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> - Assert.equal_pkh ~loc:__LOC__ delegate delegate_pkh >>=? fun _ -> - (* create an implicit contract with bootstrap's account as delegate *) - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let delegator = Contract.implicit_contract unregistered_pkh in - Op.transaction ~fee:Tez.zero (I i) bootstrap delegator Tez.one - >>=? fun credit_contract -> - Incremental.add_operation i credit_contract >>=? fun i -> - Context.Contract.manager (I i) bootstrap >>=? fun bootstrap_manager -> - Op.delegation (I i) delegator (Some bootstrap_manager.pkh) - >>=? fun delegation -> - Incremental.add_operation i delegation >>=? fun i -> - (* test delegate of new contract is bootstrap *) - Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> - Assert.equal_pkh ~loc:__LOC__ delegator_delegate bootstrap_manager.pkh - >>=? fun _ -> - (* delegation with newly registered key *) - Op.delegation (I i) delegator (Some delegate_account.pkh) - >>=? fun delegation -> - Incremental.add_operation i delegation >>=? fun i -> - Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> - Assert.equal_pkh ~loc:__LOC__ delegator_delegate delegate_pkh - -(** Create an implicit contract. *) -let test_valid_delegate_registration_init_delegation_credit_debit amount () = - (* create an implicit contract *) - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let delegate_account = Account.new_account () in - let delegate_pkh = Account.(delegate_account.pkh) in - let impl_contract = Contract.implicit_contract delegate_pkh in - (* credit > 0ꜩ+ check balance *) - Op.transaction (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* self delegation + verification *) - Op.delegation (I i) impl_contract (Some delegate_pkh) - >>=? fun self_delegation -> - Incremental.add_operation i self_delegation >>=? fun i -> - Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> - Assert.equal_pkh ~loc:__LOC__ delegate_pkh delegate >>=? fun _ -> - (* empty implicit contracts are usually deleted but they are kept if - they were registered as delegates. we empty the contract in - order to verify this. *) - Op.transaction (I i) impl_contract bootstrap amount >>=? fun empty_contract -> - Incremental.add_operation i empty_contract >>=? fun i -> - (* impl_contract is empty *) - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> - (* verify self-delegation after contract is emptied *) - Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> - Assert.equal_pkh ~loc:__LOC__ delegate_pkh delegate >>=? fun _ -> - (* create an implicit contract with no delegate *) - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let delegator = Contract.implicit_contract unregistered_pkh in - Op.transaction ~fee:Tez.zero (I i) bootstrap delegator Tez.one - >>=? fun credit_contract -> - Incremental.add_operation i credit_contract >>=? fun i -> - (* check no delegate for delegator contract *) - Context.Contract.delegate (I i) delegator >>= fun err -> - Assert.error ~loc:__LOC__ err (function - | RPC_context.Not_found _ -> true - | _ -> false) - >>=? fun _ -> - (* delegation to the newly registered key *) - Op.delegation (I i) delegator (Some delegate_account.pkh) - >>=? fun delegation -> - Incremental.add_operation i delegation >>=? fun i -> - (* check delegation *) - Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> - Assert.equal_pkh ~loc:__LOC__ delegator_delegate delegate_pkh - -(** A created implicit contract is credited with [amount] tz, then is - self-delegated. It is emptied (fund back into bootstrap), and - should remain existing (as registered as delegate). Another created - implicit contract is delegated to bootstrap, then should be able to - be re-delegated to the latter contract. *) -let test_valid_delegate_registration_switch_delegation_credit_debit amount () = - (* create an implicit contract *) - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let delegate_account = Account.new_account () in - let delegate_pkh = Account.(delegate_account.pkh) in - let impl_contract = Contract.implicit_contract delegate_pkh in - (* credit > 0ꜩ + check balance *) - Op.transaction (I i) bootstrap impl_contract amount - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> - (* self delegation + verification *) - Op.delegation (I i) impl_contract (Some delegate_pkh) - >>=? fun self_delegation -> - Incremental.add_operation i self_delegation >>=? fun i -> - Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> - Assert.equal_pkh ~loc:__LOC__ delegate_pkh delegate >>=? fun _ -> - (* empty implicit contracts are usually deleted but they are kept if - they were registered as delegates. we empty the contract in - order to verify this. *) - Op.transaction (I i) impl_contract bootstrap amount >>=? fun empty_contract -> - Incremental.add_operation i empty_contract >>=? fun i -> - (* impl_contract is empty *) - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> - (* create an implicit contract with bootstrap's account as delegate *) - let unregistered_account = Account.new_account () in - let unregistered_pkh = Account.(unregistered_account.pkh) in - let delegator = Contract.implicit_contract unregistered_pkh in - Op.transaction ~fee:Tez.zero (I i) bootstrap delegator Tez.one - >>=? fun credit_contract -> - Incremental.add_operation i credit_contract >>=? fun i -> - Context.Contract.manager (I i) bootstrap >>=? fun bootstrap_manager -> - Op.delegation (I i) delegator (Some bootstrap_manager.pkh) - >>=? fun delegation -> - Incremental.add_operation i delegation >>=? fun i -> - (* test delegate of new contract is bootstrap *) - Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> - Assert.equal_pkh ~loc:__LOC__ delegator_delegate bootstrap_manager.pkh - >>=? fun _ -> - (* delegation with newly registered key *) - Op.delegation (I i) delegator (Some delegate_account.pkh) - >>=? fun delegation -> - Incremental.add_operation i delegation >>=? fun i -> - Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> - Assert.equal_pkh ~loc:__LOC__ delegator_delegate delegate_pkh - -(* Part C. - A second self-delegation should raise an [Active_delegate] error. *) - -(** Second self-delegation should fail with implicit contract with - some credit. *) -let test_double_registration () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let account = Account.new_account () in - let pkh = Account.(account.pkh) in - let impl_contract = Contract.implicit_contract pkh in - (* credit 1μꜩ+ check balance *) - Op.transaction (I i) bootstrap impl_contract Tez.one_mutez - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.one_mutez >>=? fun _ -> - (* self-delegation *) - Op.delegation (I i) impl_contract (Some pkh) >>=? fun self_delegation -> - Incremental.add_operation i self_delegation >>=? fun i -> - (* second self-delegation *) - Op.delegation (I i) impl_contract (Some pkh) >>=? fun second_registration -> - Incremental.add_operation i second_registration >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Delegate_storage.Active_delegate -> true - | _ -> false) - -(** Second self-delegation should fail with implicit contract emptied - after first self-delegation. *) -let test_double_registration_when_empty () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let account = Account.new_account () in - let pkh = Account.(account.pkh) in - let impl_contract = Contract.implicit_contract pkh in - (* credit 1μꜩ+ check balance *) - Op.transaction (I i) bootstrap impl_contract Tez.one_mutez - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.one_mutez >>=? fun _ -> - (* self delegation *) - Op.delegation (I i) impl_contract (Some pkh) >>=? fun self_delegation -> - Incremental.add_operation i self_delegation >>=? fun i -> - (* empty the delegate account *) - Op.transaction (I i) impl_contract bootstrap Tez.one_mutez - >>=? fun empty_contract -> - Incremental.add_operation i empty_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> - (* second self-delegation *) - Op.delegation (I i) impl_contract (Some pkh) >>=? fun second_registration -> - Incremental.add_operation i second_registration >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Delegate_storage.Active_delegate -> true - | _ -> false) - -(** Second self-delegation should fail with implicit contract emptied - then credited back after first self-delegation. *) -let test_double_registration_when_recredited () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let account = Account.new_account () in - let pkh = Account.(account.pkh) in - let impl_contract = Contract.implicit_contract pkh in - (* credit 1μꜩ+ check balance *) - Op.transaction (I i) bootstrap impl_contract Tez.one_mutez - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.one_mutez >>=? fun _ -> - (* self delegation *) - Op.delegation (I i) impl_contract (Some pkh) >>=? fun self_delegation -> - Incremental.add_operation i self_delegation >>=? fun i -> - (* empty the delegate account *) - Op.transaction (I i) impl_contract bootstrap Tez.one_mutez - >>=? fun empty_contract -> - Incremental.add_operation i empty_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> - (* credit 1μꜩ+ check balance *) - Op.transaction (I i) bootstrap impl_contract Tez.one_mutez - >>=? fun create_contract -> - Incremental.add_operation i create_contract >>=? fun i -> - Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.one_mutez >>=? fun _ -> - (* second self-delegation *) - Op.delegation (I i) impl_contract (Some pkh) >>=? fun second_registration -> - Incremental.add_operation i second_registration >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Delegate_storage.Active_delegate -> true - | _ -> false) - -(** Self-delegation on unrevealed contract. *) -let test_unregistered_and_unrevealed_self_delegate_key_init_delegation ~fee () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let {Account.pkh; _} = Account.new_account () in - let {Account.pkh = delegate_pkh; _} = Account.new_account () in - let contract = Alpha_context.Contract.implicit_contract pkh in - Op.transaction (I i) bootstrap contract (of_int 10) >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Op.delegation ~fee (I i) contract (Some delegate_pkh) >>=? fun op -> - Context.Contract.balance (I i) contract >>=? fun balance -> - if fee > balance then - Incremental.add_operation i op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* origination did not proceed; fee has been debited *) - Incremental.add_operation - ~expect_failure:(expect_unregistered_key delegate_pkh) - i - op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) contract balance fee - -(** Self-delegation on revealed but not registered contract. *) -let test_unregistered_and_revealed_self_delegate_key_init_delegation ~fee () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let {Account.pkh; pk; _} = Account.new_account () in - let {Account.pkh = delegate_pkh; _} = Account.new_account () in - let contract = Alpha_context.Contract.implicit_contract pkh in - Op.transaction (I i) bootstrap contract (of_int 10) >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Op.revelation (I i) pk >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Op.delegation ~fee (I i) contract (Some delegate_pkh) >>=? fun op -> - Context.Contract.balance (I i) contract >>=? fun balance -> - if fee > balance then - Incremental.add_operation i op >>= fun err -> - Assert.proto_error ~loc:__LOC__ err (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - else - (* origination did not proceed; fee has been debited *) - Incremental.add_operation - ~expect_failure:(expect_unregistered_key delegate_pkh) - i - op - >>=? fun i -> - Assert.balance_was_debited ~loc:__LOC__ (I i) contract balance fee - -(** Self-delegation on revealed and registered contract. *) -let test_registered_self_delegate_key_init_delegation () = - Context.init 1 >>=? fun (b, bootstrap_contracts) -> - Incremental.begin_construction b >>=? fun i -> - let bootstrap = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts - in - let {Account.pkh; _} = Account.new_account () in - let {Account.pkh = delegate_pkh; pk = delegate_pk; _} = - Account.new_account () - in - let contract = Alpha_context.Contract.implicit_contract pkh in - let delegate_contract = - Alpha_context.Contract.implicit_contract delegate_pkh - in - Op.transaction (I i) bootstrap contract (of_int 10) >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Op.transaction (I i) bootstrap delegate_contract (of_int 1) >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Op.revelation (I i) delegate_pk >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Op.delegation (I i) delegate_contract (Some delegate_pkh) >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Op.delegation (I i) contract (Some delegate_pkh) >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Context.Contract.delegate (I i) contract >>=? fun delegate -> - Assert.equal_pkh ~loc:__LOC__ delegate delegate_pkh >>=? fun () -> return_unit - -let tests_delegate_registration = - [ - (*** unregistered delegate key: no self-delegation ***) - (* no token transfer, no self-delegation *) - Tztest.tztest - "unregistered delegate key (origination, small fee)" - `Quick - (test_unregistered_delegate_key_init_origination ~fee:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key (origination, edge case fee)" - `Quick - (test_unregistered_delegate_key_init_origination ~fee:(of_int 3_999_488)); - Tztest.tztest - "unregistered delegate key (origination, large fee)" - `Quick - (test_unregistered_delegate_key_init_origination ~fee:(of_int 10_000_000)); - Tztest.tztest - "unregistered delegate key (init with delegation, small fee)" - `Quick - (test_unregistered_delegate_key_init_delegation ~fee:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key (init with delegation, max fee)" - `Quick - (test_unregistered_delegate_key_init_delegation ~fee:max_tez); - Tztest.tztest - "unregistered delegate key (switch with delegation, small fee)" - `Quick - (test_unregistered_delegate_key_switch_delegation ~fee:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key (switch with delegation, max fee)" - `Quick - (test_unregistered_delegate_key_switch_delegation ~fee:max_tez); - (* credit/debit 1μꜩ, no self-delegation *) - Tztest.tztest - "unregistered delegate key - credit/debit 1μꜩ (origination, small fee)" - `Quick - (test_unregistered_delegate_key_init_origination_credit_debit - ~fee:Tez.one_mutez - ~amount:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key - credit/debit 1μꜩ (origination, large fee)" - `Quick - (test_unregistered_delegate_key_init_origination_credit_debit - ~fee:max_tez - ~amount:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key - credit/debit 1μꜩ (init with delegation, \ - small fee)" - `Quick - (test_unregistered_delegate_key_init_delegation_credit_debit - ~amount:Tez.one_mutez - ~fee:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key - credit/debit 1μꜩ (init with delegation, \ - large fee)" - `Quick - (test_unregistered_delegate_key_init_delegation_credit_debit - ~amount:Tez.one_mutez - ~fee:max_tez); - Tztest.tztest - "unregistered delegate key - credit/debit 1μꜩ (switch with \ - delegation, small fee)" - `Quick - (test_unregistered_delegate_key_switch_delegation_credit_debit - ~amount:Tez.one_mutez - ~fee:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key - credit/debit 1μꜩ (switch with \ - delegation, large fee)" - `Quick - (test_unregistered_delegate_key_switch_delegation_credit_debit - ~amount:Tez.one_mutez - ~fee:max_tez); - (* credit 1μꜩ, no self-delegation *) - Tztest.tztest - "unregistered delegate key - credit 1μꜩ (origination, small fee)" - `Quick - (test_unregistered_delegate_key_init_origination_credit - ~fee:Tez.one_mutez - ~amount:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key - credit 1μꜩ (origination, edge case fee)" - `Quick - (test_unregistered_delegate_key_init_origination_credit - ~fee:(of_int 3_999_488) - ~amount:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key - credit 1μꜩ (origination, large fee)" - `Quick - (test_unregistered_delegate_key_init_origination_credit - ~fee:(of_int 10_000_000) - ~amount:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key - credit 1μꜩ (init with delegation, small \ - fee)" - `Quick - (test_unregistered_delegate_key_init_delegation_credit - ~amount:Tez.one_mutez - ~fee:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key - credit 1μꜩ (init with delegation, large \ - fee)" - `Quick - (test_unregistered_delegate_key_init_delegation_credit - ~amount:Tez.one_mutez - ~fee:max_tez); - Tztest.tztest - "unregistered delegate key - credit 1μꜩ (switch with delegation, \ - small fee)" - `Quick - (test_unregistered_delegate_key_switch_delegation_credit - ~amount:Tez.one_mutez - ~fee:Tez.one_mutez); - Tztest.tztest - "unregistered delegate key - credit 1μꜩ (switch with delegation, \ - large fee)" - `Quick - (test_unregistered_delegate_key_switch_delegation_credit - ~amount:Tez.one_mutez - ~fee:max_tez); - (* self delegation on unrevealed and unregistered contract *) - Tztest.tztest - "unregistered and unrevealed self-delegation (small fee)" - `Quick - (test_unregistered_and_unrevealed_self_delegate_key_init_delegation - ~fee:Tez.one_mutez); - Tztest.tztest - "unregistered and unrevealed self-delegation (large fee)" - `Quick - (test_unregistered_and_unrevealed_self_delegate_key_init_delegation - ~fee:max_tez); - (* self delegation on unregistered contract *) - Tztest.tztest - "unregistered and revealed self-delegation (small fee)" - `Quick - (test_unregistered_and_revealed_self_delegate_key_init_delegation - ~fee:Tez.one_mutez); - Tztest.tztest - "unregistered and revealed self-delegation large fee)" - `Quick - (test_unregistered_and_revealed_self_delegate_key_init_delegation - ~fee:max_tez); - (* self delegation on registered contract *) - Tztest.tztest - "registered and revealed self-delegation" - `Quick - test_registered_self_delegate_key_init_delegation; - (*** unregistered delegate key: failed self-delegation ***) - (* no token transfer, self-delegation *) - Tztest.tztest - "failed self-delegation: no transaction" - `Quick - test_failed_self_delegation_no_transaction; - (* credit 1μtz, debit 1μtz, self-delegation *) - Tztest.tztest - "failed self-delegation: credit & debit 1μꜩ" - `Quick - (test_failed_self_delegation_emptied_implicit_contract Tez.one_mutez); - (* credit 1μtz, delegate, debit 1μtz *) - Tztest.tztest - "empty delegated contract is not deleted: credit 1μꜩ, delegate & \ - debit 1μꜩ" - `Quick - (test_emptying_delegated_implicit_contract_fails Tez.one_mutez); - (*** valid registration ***) - (* valid registration: credit 1 μꜩ, self delegation *) - Tztest.tztest - "valid delegate registration: credit 1μꜩ, self delegation (init with \ - delegation)" - `Quick - (test_valid_delegate_registration_init_delegation_credit Tez.one_mutez); - Tztest.tztest - "valid delegate registration: credit 1μꜩ, self delegation (switch \ - with delegation)" - `Quick - (test_valid_delegate_registration_switch_delegation_credit Tez.one_mutez); - (* valid registration: credit 1 μꜩ, self delegation, debit 1μꜩ *) - Tztest.tztest - "valid delegate registration: credit 1μꜩ, self delegation, debit \ - 1μꜩ (init with delegation)" - `Quick - (test_valid_delegate_registration_init_delegation_credit_debit - Tez.one_mutez); - Tztest.tztest - "valid delegate registration: credit 1μꜩ, self delegation, debit \ - 1μꜩ (switch with delegation)" - `Quick - (test_valid_delegate_registration_switch_delegation_credit_debit - Tez.one_mutez); - (*** double registration ***) - Tztest.tztest "double registration" `Quick test_double_registration; - Tztest.tztest - "double registration when delegate account is emptied" - `Quick - test_double_registration_when_empty; - Tztest.tztest - "double registration when delegate account is emptied and then recredited" - `Quick - test_double_registration_when_recredited; - ] - -(******************************************************************************) -(* Main *) -(******************************************************************************) - -let tests = tests_bootstrap_contracts @ tests_delegate_registration diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_double_baking.ml b/src/proto_012_Psithaca/lib_protocol/test/test_double_baking.ml deleted file mode 100644 index 9a6bdf1b3691..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_double_baking.ml +++ /dev/null @@ -1,365 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (double baking) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^double baking$" - Subject: A double baking evidence operation may be injected when it has - been observed that a baker baked two different blocks at the - same level and same round. -*) - -open Protocol -open Alpha_context - -(****************************************************************) -(* Utility functions *) -(****************************************************************) - -let get_hd_hd = function x :: y :: _ -> (x, y) | _ -> assert false - -let get_first_different_baker baker bakers = - WithExceptions.Option.get ~loc:__LOC__ - @@ List.find - (fun baker' -> Signature.Public_key_hash.( <> ) baker baker') - bakers - -let get_first_different_bakers ctxt = - Context.get_bakers ctxt >|=? function - | [] | [_] -> assert false - | baker_1 :: other_bakers -> - (baker_1, get_first_different_baker baker_1 other_bakers) - -let get_baker_different_from_baker ctxt baker = - Context.get_bakers - ~filter:(fun x -> not (Signature.Public_key_hash.equal x.delegate baker)) - ctxt - >>=? fun bakers -> - return (WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bakers) - -let get_first_different_endorsers ctxt = - Context.get_endorsers ctxt >|=? fun endorsers -> get_hd_hd endorsers - -(** Bake two block at the same level using the same policy (i.e. same - baker). *) -let block_fork ?policy contracts b = - let (contract_a, contract_b) = get_hd_hd contracts in - Op.transaction (B b) contract_a contract_b Alpha_context.Tez.one_cent - >>=? fun operation -> - Block.bake ?policy ~operation b >>=? fun blk_a -> - Block.bake ?policy b >|=? fun blk_b -> (blk_a, blk_b) - -let order_block_hashes ~correct_order bh1 bh2 = - let hash1 = Block_header.hash bh1 in - let hash2 = Block_header.hash bh2 in - let c = Block_hash.compare hash1 hash2 in - if correct_order then if c < 0 then (bh1, bh2) else (bh2, bh1) - else if c < 0 then (bh2, bh1) - else (bh1, bh2) - -let double_baking ctxt ?(correct_order = true) bh1 bh2 = - let (bh1, bh2) = order_block_hashes ~correct_order bh1 bh2 in - Op.double_baking ctxt bh1 bh2 - -(****************************************************************) -(* Tests *) -(****************************************************************) - -(** Simple scenario where two blocks are baked by a same baker and - exposed by a double baking evidence operation. *) -let test_valid_double_baking_evidence () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, contracts) -> - Context.get_constants (B genesis) - >>=? fun Constants.{parametric = {double_baking_punishment; _}; _} -> - get_first_different_bakers (B genesis) >>=? fun (baker1, baker2) -> - block_fork ~policy:(By_account baker1) contracts genesis - >>=? fun (blk_a, blk_b) -> - double_baking (B blk_a) blk_a.header blk_b.header |> fun operation -> - Block.bake ~policy:(By_account baker2) ~operation blk_a >>=? fun blk_final -> - (* Check that the frozen deposits are slashed *) - Context.Delegate.current_frozen_deposits (B blk_a) baker1 - >>=? fun frozen_deposits_before -> - Context.Delegate.current_frozen_deposits (B blk_final) baker1 - >>=? fun frozen_deposits_after -> - let slashed_amount = - Test_tez.(frozen_deposits_before -! frozen_deposits_after) - in - Assert.equal_tez ~loc:__LOC__ slashed_amount double_baking_punishment - >>=? fun () -> - (* Check that the initial frozen deposits has not changed *) - Context.Delegate.initial_frozen_deposits (B blk_final) baker1 - >>=? fun initial_frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ initial_frozen_deposits frozen_deposits_before - -(** Test that the payload producer of the block containing a double - baking evidence (and not the block producer, if different) receives - the reward. *) -let test_payload_producer_gets_evidence_rewards () = - Context.init ~consensus_threshold:0 10 >>=? fun (genesis, contracts) -> - Context.get_constants (B genesis) - >>=? fun Constants. - { - parametric = - {double_baking_punishment; baking_reward_fixed_portion; _}; - _; - } -> - get_first_different_bakers (B genesis) >>=? fun (baker1, baker2) -> - block_fork ~policy:(By_account baker1) contracts genesis >>=? fun (b1, b2) -> - double_baking (B b1) b1.header b2.header |> fun db_evidence -> - Block.bake ~policy:(By_account baker2) ~operation:db_evidence b1 - >>=? fun b_with_evidence -> - Context.get_endorsers (B b_with_evidence) >>=? fun endorsers -> - List.map_es - (function - | {Plugin.RPC.Validators.delegate; slots; _} -> return (delegate, slots)) - endorsers - >>=? fun preendorsers -> - List.map_ep - (fun endorser -> - Op.preendorsement - ~delegate:endorser - ~endorsed_block:b_with_evidence - (B b1) - () - >|=? Operation.pack) - preendorsers - >>=? fun preendos -> - Block.bake - ~payload_round:(Some Round.zero) - ~locked_round:(Some Round.zero) - ~policy:(By_account baker1) - ~operations:(db_evidence :: preendos) - b1 - >>=? fun b' -> - (* the frozen deposits of the double-signer [baker1] are slashed *) - Context.Delegate.current_frozen_deposits (B b1) baker1 - >>=? fun frozen_deposits_before -> - Context.Delegate.current_frozen_deposits (B b') baker1 - >>=? fun frozen_deposits_after -> - let slashed_amount = - Test_tez.(frozen_deposits_before -! frozen_deposits_after) - in - Assert.equal_tez ~loc:__LOC__ slashed_amount double_baking_punishment - >>=? fun () -> - (* [baker2] included the double baking evidence in [b_with_evidence] - and so it receives the reward for the evidence included in [b'] - (besides the reward for proposing the payload). *) - Context.Delegate.full_balance (B b1) baker2 >>=? fun full_balance -> - let evidence_reward = Test_tez.(slashed_amount /! 2L) in - let expected_reward = - Test_tez.(baking_reward_fixed_portion +! evidence_reward) - in - Context.Delegate.full_balance (B b') baker2 - >>=? fun full_balance_with_rewards -> - let real_reward = Test_tez.(full_balance_with_rewards -! full_balance) in - Assert.equal_tez ~loc:__LOC__ expected_reward real_reward >>=? fun () -> - (* [baker1] did not produce the payload, it does not receive the reward for the - evidence *) - Context.Delegate.full_balance (B b1) baker1 >>=? fun full_balance_at_b1 -> - Context.Delegate.full_balance (B b') baker1 >>=? fun full_balance_at_b' -> - Assert.equal_tez - ~loc:__LOC__ - full_balance_at_b' - Test_tez.(full_balance_at_b1 -! double_baking_punishment) - -(****************************************************************) -(* The following test scenarios are supposed to raise errors. *) -(****************************************************************) - -(** Check that a double baking operation fails if it exposes the same two - blocks. *) -let test_same_blocks () = - Context.init 2 >>=? fun (b, _contracts) -> - Block.bake b >>=? fun ba -> - double_baking (B ba) ba.header ba.header |> fun operation -> - Block.bake ~operation ba >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Invalid_double_baking_evidence _ -> true - | _ -> false) - >>=? fun () -> return_unit - -(** Check that an double baking operation that is invalid due to - incorrect ordering of the block headers fails. *) -let test_incorrect_order () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, contracts) -> - block_fork ~policy:(By_round 0) contracts genesis >>=? fun (blk_a, blk_b) -> - double_baking (B genesis) ~correct_order:false blk_a.header blk_b.header - |> fun operation -> - Block.bake ~operation genesis >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Invalid_double_baking_evidence _ -> true - | _ -> false) - -(** Check that a double baking operation exposing two blocks with - different levels fails. *) -let test_different_levels () = - Context.init ~consensus_threshold:0 2 >>=? fun (b, contracts) -> - block_fork ~policy:(By_round 0) contracts b >>=? fun (blk_a, blk_b) -> - Block.bake blk_b >>=? fun blk_b_2 -> - double_baking (B blk_a) blk_a.header blk_b_2.header |> fun operation -> - Block.bake ~operation blk_a >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Invalid_double_baking_evidence _ -> true - | _ -> false) - -(** Check that a double baking operation exposing two yet-to-be-baked - blocks fails. *) -let test_too_early_double_baking_evidence () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, contracts) -> - Block.bake_until_cycle_end genesis >>=? fun b -> - block_fork ~policy:(By_round 0) contracts b >>=? fun (blk_a, blk_b) -> - double_baking (B b) blk_a.header blk_b.header |> fun operation -> - Block.bake ~operation genesis >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Too_early_denunciation {kind = Block; _} -> true - | _ -> false) - -(** Check that after [max_slashing_period * blocks_per_cycle + 1] blocks -- corresponding to 2 cycles - --, it is not possible to create a double baking operation anymore. *) -let test_too_late_double_baking_evidence () = - Context.init ~consensus_threshold:0 2 >>=? fun (b, contracts) -> - Context.get_constants (B b) - >>=? fun Constants.{parametric = {max_slashing_period; _}; _} -> - block_fork ~policy:(By_round 0) contracts b >>=? fun (blk_a, blk_b) -> - Block.bake_until_n_cycle_end max_slashing_period blk_a >>=? fun blk -> - double_baking (B blk) blk_a.header blk_b.header |> fun operation -> - Block.bake ~operation blk >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Outdated_denunciation {kind = Block; _} -> true - | _ -> false) - -(** Check that before [max_slashing_period * blocks_per_cycle] blocks - -- corresponding to 2 cycles --, it is still possible to create a - double baking operation. *) -let test_just_in_time_double_baking_evidence () = - Context.init ~consensus_threshold:0 2 >>=? fun (b, contracts) -> - Context.get_constants (B b) - >>=? fun Constants.{parametric = {blocks_per_cycle; _}; _} -> - block_fork ~policy:(By_round 0) contracts b >>=? fun (blk_a, blk_b) -> - Block.bake_until_cycle_end blk_a >>=? fun blk -> - Block.bake_n Int32.(sub blocks_per_cycle 2l |> to_int) blk >>=? fun blk -> - let operation = double_baking (B blk) blk_a.header blk_b.header in - (* We include the denuncation in the previous to last block of the - cycle. *) - Block.bake ~operation blk >>=? fun _ -> return_unit - -(** Check that an invalid double baking evidence that exposes two - block baking with same level made by different bakers fails. *) -let test_different_delegates () = - Context.init 2 >>=? fun (b, _) -> - get_first_different_bakers (B b) >>=? fun (baker_1, baker_2) -> - Block.bake ~policy:(By_account baker_1) b >>=? fun blk_a -> - Block.bake ~policy:(By_account baker_2) b >>=? fun blk_b -> - double_baking (B blk_a) blk_a.header blk_b.header |> fun operation -> - Block.bake ~operation blk_a >>= fun e -> - Assert.proto_error ~loc:__LOC__ e (function - | Apply.Invalid_double_baking_evidence _ -> true - | _ -> false) - -(** This test is supposed to mimic that a block cannot be baked by one baker and - signed by another. The way it tries to show this is by using a - Double_baking_evidence operation: - - say [baker_1] bakes block blk_a so blk_a has a header with baker_1's - signature - - say we create an artificial [header_b] for a block b' with timestamp [ts] - at the same level as [blk_a], and the header is created such that it says that - b' is baked by the same [baker_1] and signed by [baker_2] - - because [header_b] says that b' is baked by [baker_0], b' has the same - round as [blk_a], which together with the fact that b' and [blk_a] have the - same level, means that double_baking is valid: we have [blk_a] and b' at the - same level and round, but with different timestamps and signed by different - bakers. - This test fails with an error stating that block is signed by the wrong - baker. *) -let test_wrong_signer () = - let header_custom_signer baker baker_2 timestamp b = - Block.Forge.forge_header ~policy:(By_account baker) ~timestamp b - >>=? fun header -> - Block.Forge.set_baker baker_2 header |> Block.Forge.sign_header - in - Context.init 2 >>=? fun (b, _) -> - get_first_different_bakers (B b) >>=? fun (baker_1, baker_2) -> - Block.bake ~policy:(By_account baker_1) b >>=? fun blk_a -> - let ts = Timestamp.of_seconds_string (Int64.to_string 10L) in - match ts with - | None -> assert false - | Some ts -> - header_custom_signer baker_1 baker_2 ts b >>=? fun header_b -> - double_baking (B blk_a) blk_a.header header_b |> fun operation -> - Block.bake ~operation blk_a >>= fun e -> - Assert.proto_error ~loc:__LOC__ e (function - | Block_header.Invalid_block_signature _ -> true - | _ -> false) - -(** an evidence can only be accepted once (this also means that the - same evidence doesn't lead to slashing the offender twice) *) -let test_double_evidence () = - Context.init ~consensus_threshold:0 3 >>=? fun (blk, contracts) -> - block_fork contracts blk >>=? fun (blk_a, blk_b) -> - Block.bake_until_cycle_end blk_a >>=? fun blk -> - double_baking (B blk) blk_a.header blk_b.header |> fun evidence -> - Block.bake ~operation:evidence blk >>=? fun blk -> - double_baking (B blk) blk_b.header blk_a.header |> fun evidence -> - Block.bake ~operation:evidence blk >>= fun e -> - Assert.proto_error ~loc:__LOC__ e (function err -> - let error_info = - Error_monad.find_info_of_error (Environment.wrap_tzerror err) - in - error_info.title = "Unrequired denunciation") - -let tests = - [ - Tztest.tztest - "valid double baking evidence" - `Quick - test_valid_double_baking_evidence; - Tztest.tztest - "payload producer receives the rewards for double baking evidence" - `Quick - test_payload_producer_gets_evidence_rewards; - (* Should fail*) - Tztest.tztest "same blocks" `Quick test_same_blocks; - Tztest.tztest "incorrect order" `Quick test_incorrect_order; - Tztest.tztest "different levels" `Quick test_different_levels; - Tztest.tztest - "too early double baking evidence" - `Quick - test_too_early_double_baking_evidence; - Tztest.tztest - "too late double baking evidence" - `Quick - test_too_late_double_baking_evidence; - Tztest.tztest - "just in time double baking evidence" - `Quick - test_just_in_time_double_baking_evidence; - Tztest.tztest "different delegates" `Quick test_different_delegates; - Tztest.tztest "wrong delegate" `Quick test_wrong_signer; - Tztest.tztest - "reject double injection of an evidence" - `Quick - test_double_evidence; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_double_endorsement.ml b/src/proto_012_Psithaca/lib_protocol/test/test_double_endorsement.ml deleted file mode 100644 index 093a182be5fb..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_double_endorsement.ml +++ /dev/null @@ -1,513 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (double endorsement) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^double endorsement$" - Subject: Double endorsement evidence operation may happen when an - endorser endorsed two different blocks on the same level. -*) - -open Protocol -open Alpha_context - -(****************************************************************) -(* Utility functions *) -(****************************************************************) - -let get_hd_hd = function x :: y :: _ -> (x, y) | _ -> assert false - -let get_first_different_baker baker bakers = - WithExceptions.Option.get ~loc:__LOC__ - @@ List.find - (fun baker' -> Signature.Public_key_hash.( <> ) baker baker') - bakers - -let get_first_different_bakers ctxt = - Context.get_bakers ctxt >|=? function - | [] -> assert false - | baker_1 :: other_bakers -> - (baker_1, get_first_different_baker baker_1 other_bakers) - -let get_first_different_endorsers ctxt = - Context.get_endorsers ctxt >|=? fun endorsers -> get_hd_hd endorsers - -let block_fork b = - get_first_different_bakers (B b) >>=? fun (baker_1, baker_2) -> - Block.bake ~policy:(By_account baker_1) b >>=? fun blk_a -> - Block.bake ~policy:(By_account baker_2) b >|=? fun blk_b -> (blk_a, blk_b) - -(****************************************************************) -(* Tests *) -(****************************************************************) - -let get_first_2_accounts_contracts contracts = - let ((contract1, account1), (contract2, account2)) = - match contracts with - | [a1; a2] -> - ( ( a1, - Contract.is_implicit a1 |> function - | None -> assert false - | Some pkh -> pkh ), - ( a2, - Contract.is_implicit a2 |> function - | None -> assert false - | Some pkh -> pkh ) ) - | _ -> assert false - in - ((contract1, account1), (contract2, account2)) - -let order_endorsements ~correct_order op1 op2 = - let oph1 = Operation.hash op1 in - let oph2 = Operation.hash op2 in - let c = Operation_hash.compare oph1 oph2 in - if correct_order then if c < 0 then (op1, op2) else (op2, op1) - else if c < 0 then (op2, op1) - else (op1, op2) - -let double_endorsement ctxt ?(correct_order = true) op1 op2 = - let (e1, e2) = order_endorsements ~correct_order op1 op2 in - Op.double_endorsement ctxt e1 e2 - -(** This test verifies that when a "cheater" double endorses and - doesn't have enough tokens to re-freeze of full deposit, we only - freeze what we can (i.e. the remaining balance) but we check that - another denunciation will slash 50% of the initial (expected) amount - of the deposit. *) - -(** Simple scenario where two endorsements are made from the same - delegate and exposed by a double_endorsement operation. Also verify - that punishment is operated. *) -let test_valid_double_endorsement_evidence () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> - block_fork genesis >>=? fun (blk_1, blk_2) -> - (* from blk_1 we bake blk_a and from blk_2 we bake blk_b so that - the same delegate endorses blk_a and blk_b and these 2 form - a valid double endorsement evidence; - - note that we cannot have double endorsement evidence - at the level of blk_1, blk_2 because both have as parent genesis - and so the endorsements are identical because the blocks blk_1, blk_2 - are identical. *) - Block.bake blk_1 >>=? fun blk_a -> - Block.bake blk_2 >>=? fun blk_b -> - Context.get_endorser (B blk_a) >>=? fun (delegate, _) -> - Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> - Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> - let operation = double_endorsement (B genesis) endorsement_a endorsement_b in - Context.get_bakers (B blk_a) >>=? fun bakers -> - let baker = get_first_different_baker delegate bakers in - Context.Delegate.full_balance (B blk_a) baker >>=? fun full_balance -> - Block.bake ~policy:(By_account baker) ~operation blk_a >>=? fun blk_final -> - (* Check that parts of the frozen deposits are slashed *) - Context.Delegate.current_frozen_deposits (B blk_a) delegate - >>=? fun frozen_deposits_before -> - Context.Delegate.current_frozen_deposits (B blk_final) delegate - >>=? fun frozen_deposits_after -> - Context.get_constants (B genesis) >>=? fun csts -> - let r = - csts.parametric.ratio_of_frozen_deposits_slashed_per_double_endorsement - in - let expected_frozen_deposits_after = - Test_tez.( - frozen_deposits_before - *! Int64.of_int (r.denominator - r.numerator) - /! Int64.of_int r.denominator) - in - Assert.equal_tez - ~loc:__LOC__ - expected_frozen_deposits_after - frozen_deposits_after - >>=? fun () -> - (* Check that the initial frozen deposits has not changed *) - Context.Delegate.initial_frozen_deposits (B blk_final) delegate - >>=? fun initial_frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ initial_frozen_deposits frozen_deposits_before - >>=? fun () -> - (* Check that [baker] is rewarded with: - - baking_reward_fixed_portion for baking and, - - half of the frozen_deposits for including the evidence *) - let baking_reward = csts.parametric.baking_reward_fixed_portion in - let evidence_reward = Test_tez.(frozen_deposits_after /! 2L) in - let expected_reward = Test_tez.(baking_reward +! evidence_reward) in - Context.Delegate.full_balance (B blk_final) baker - >>=? fun full_balance_with_rewards -> - let real_reward = Test_tez.(full_balance_with_rewards -! full_balance) in - Assert.equal_tez ~loc:__LOC__ expected_reward real_reward - -(** Say a delegate double-endorses twice and say the 2 evidences are timely - included. Then the delegate can no longer bake. *) -let test_two_double_endorsement_evidences_leadsto_no_bake () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> - block_fork genesis >>=? fun (blk_1, blk_2) -> - Block.bake blk_1 >>=? fun blk_a -> - Block.bake blk_2 >>=? fun blk_b -> - Context.get_endorser (B blk_a) >>=? fun (delegate, _) -> - Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> - Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> - let operation = double_endorsement (B genesis) endorsement_a endorsement_b in - Context.get_bakers (B blk_a) >>=? fun bakers -> - let baker = get_first_different_baker delegate bakers in - Context.Delegate.full_balance (B blk_a) baker >>=? fun _full_balance -> - Block.bake ~policy:(By_account baker) ~operation blk_a - >>=? fun blk_with_evidence1 -> - block_fork blk_with_evidence1 >>=? fun (blk_30, blk_40) -> - Block.bake blk_30 >>=? fun blk_3 -> - Block.bake blk_40 >>=? fun blk_4 -> - Op.endorsement ~endorsed_block:blk_3 (B blk_30) () >>=? fun endorsement_3 -> - Op.endorsement ~endorsed_block:blk_4 (B blk_40) () >>=? fun endorsement_4 -> - let operation = - double_endorsement (B blk_with_evidence1) endorsement_3 endorsement_4 - in - Block.bake ~policy:(By_account baker) ~operation blk_3 - >>=? fun blk_with_evidence2 -> - (* Check that all the frozen deposits are slashed *) - Context.Delegate.current_frozen_deposits (B blk_with_evidence2) delegate - >>=? fun frozen_deposits_after -> - Assert.equal_tez ~loc:__LOC__ Tez.zero frozen_deposits_after >>=? fun () -> - Block.bake ~policy:(By_account delegate) blk_with_evidence2 >>= fun b -> - (* a delegate with 0 frozen deposits cannot bake *) - Assert.proto_error ~loc:__LOC__ b (function err -> - let error_info = - Error_monad.find_info_of_error (Environment.wrap_tzerror err) - in - error_info.title = "Zero frozen deposits") - -(****************************************************************) -(* The following test scenarios are supposed to raise errors. *) -(****************************************************************) - -(** Check that an invalid double endorsement operation that exposes a - valid endorsement fails. *) -let test_invalid_double_endorsement () = - Context.init ~consensus_threshold:0 10 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b -> - Op.endorsement ~endorsed_block:b (B genesis) () >>=? fun endorsement -> - Block.bake ~operation:(Operation.pack endorsement) b >>=? fun b -> - Op.double_endorsement (B b) endorsement endorsement |> fun operation -> - Block.bake ~operation b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Invalid_denunciation Endorsement -> true - | _ -> false) - -(** Check that an double endorsement operation that is invalid due to - incorrect ordering of the endorsements fails. *) -let test_invalid_double_endorsement_variant () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> - Block.bake_until_cycle_end genesis >>=? fun b -> - block_fork b >>=? fun (blk_1, blk_2) -> - Block.bake blk_1 >>=? fun blk_a -> - Block.bake blk_2 >>=? fun blk_b -> - Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> - Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> - double_endorsement - (B genesis) - ~correct_order:false - endorsement_a - endorsement_b - |> fun operation -> - Block.bake ~operation genesis >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Invalid_denunciation Endorsement -> true - | _ -> false) - -(** Check that a future-cycle double endorsement fails. *) -let test_too_early_double_endorsement_evidence () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> - Block.bake_until_cycle_end genesis >>=? fun b -> - block_fork b >>=? fun (blk_1, blk_2) -> - Block.bake blk_1 >>=? fun blk_a -> - Block.bake blk_2 >>=? fun blk_b -> - Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> - Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> - double_endorsement (B genesis) endorsement_a endorsement_b |> fun operation -> - Block.bake ~operation genesis >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Too_early_denunciation {kind = Endorsement; _} -> true - | _ -> false) - -(** Check that after [max_slashing_period * blocks_per_cycle + 1], it is not possible - to create a double_endorsement anymore. *) -let test_too_late_double_endorsement_evidence () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> - Context.get_constants (B genesis) - >>=? fun Constants. - {parametric = {max_slashing_period; blocks_per_cycle; _}; _} -> - block_fork genesis >>=? fun (blk_1, blk_2) -> - Block.bake blk_1 >>=? fun blk_a -> - Block.bake blk_2 >>=? fun blk_b -> - Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> - Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> - Block.bake_n ((max_slashing_period * Int32.to_int blocks_per_cycle) + 1) blk_a - >>=? fun blk -> - double_endorsement (B blk) endorsement_a endorsement_b |> fun operation -> - Block.bake ~operation blk >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Outdated_denunciation {kind = Endorsement; _} -> true - | _ -> false) - -(** Check that an invalid double endorsement evidence that exposes two - endorsements made by two different endorsers fails. *) -let test_different_delegates () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun genesis -> - block_fork genesis >>=? fun (blk_1, blk_2) -> - Block.bake blk_1 >>=? fun blk_a -> - Block.bake blk_2 >>=? fun blk_b -> - Context.get_endorser (B blk_a) >>=? fun (endorser_a, a_slots) -> - get_first_different_endorsers (B blk_b) - >>=? fun (endorser_b1c, endorser_b2c) -> - let (endorser_b, b_slots) = - if Signature.Public_key_hash.( = ) endorser_a endorser_b1c.delegate then - (endorser_b2c.delegate, endorser_b2c.slots) - else (endorser_b1c.delegate, endorser_b1c.slots) - in - Op.endorsement - ~delegate:(endorser_a, a_slots) - ~endorsed_block:blk_a - (B blk_1) - () - >>=? fun e_a -> - Op.endorsement - ~delegate:(endorser_b, b_slots) - ~endorsed_block:blk_b - (B blk_2) - () - >>=? fun e_b -> - Block.bake ~operation:(Operation.pack e_b) blk_b >>=? fun _ -> - double_endorsement (B blk_b) e_a e_b |> fun operation -> - Block.bake ~operation blk_b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Inconsistent_denunciation {kind = Endorsement; _} -> true - | _ -> false) - -(** Check that a double endorsement evidence that exposes a ill-formed - endorsement fails. *) -let test_wrong_delegate () = - Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _contracts) -> - block_fork genesis >>=? fun (blk_1, blk_2) -> - Block.bake blk_1 >>=? fun blk_a -> - Block.bake blk_2 >>=? fun blk_b -> - Context.get_endorser (B blk_a) >>=? fun (endorser_a, a_slots) -> - Op.endorsement - ~delegate:(endorser_a, a_slots) - ~endorsed_block:blk_a - (B blk_1) - () - >>=? fun endorsement_a -> - Context.get_endorser_n (B blk_b) 0 >>=? fun (endorser0, slots0) -> - Context.get_endorser_n (B blk_b) 1 >>=? fun (endorser1, slots1) -> - let (endorser_b, b_slots) = - if Signature.Public_key_hash.equal endorser_a endorser0 then - (endorser1, slots1) - else (endorser0, slots0) - in - Op.endorsement - ~delegate:(endorser_b, b_slots) - ~endorsed_block:blk_b - (B blk_2) - () - >>=? fun endorsement_b -> - double_endorsement (B blk_b) endorsement_a endorsement_b |> fun operation -> - Block.bake ~operation blk_b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Inconsistent_denunciation {kind = Endorsement; _} -> true - | _ -> false) - -let test_freeze_more_with_low_balance = - let get_endorsing_slots_for_account ctxt account = - (* Get the slots of the given account in the given context. *) - Context.get_endorsers ctxt >>=? function - | [d1; d2] -> - return - (if Signature.Public_key_hash.equal account d1.delegate then d1 - else if Signature.Public_key_hash.equal account d2.delegate then d2 - else assert false) - .slots - | _ -> assert false - (* there are exactly two endorsers for this test. *) - in - let double_endorse_and_punish b2 account1 = - (* Bake a block on top of [b2] that includes a double-endorsement - denunciation of [account1]. *) - block_fork b2 >>=? fun (blk_d1, blk_d2) -> - Block.bake ~policy:(Block.By_account account1) blk_d1 >>=? fun blk_a -> - Block.bake ~policy:(Block.By_account account1) blk_d2 >>=? fun blk_b -> - get_endorsing_slots_for_account (B blk_a) account1 >>=? fun slots_a -> - Op.endorsement - ~delegate:(account1, slots_a) - ~endorsed_block:blk_a - (B blk_d1) - () - >>=? fun end_a -> - get_endorsing_slots_for_account (B blk_b) account1 >>=? fun slots_b -> - Op.endorsement - ~delegate:(account1, slots_b) - ~endorsed_block:blk_b - (B blk_d2) - () - >>=? fun end_b -> - let denunciation = double_endorsement (B b2) end_a end_b in - Block.bake ~policy:(Excluding [account1]) b2 ~operations:[denunciation] - in - let check_unique_endorser b account2 = - Context.get_endorsers (B b) >>=? function - | [{delegate; _}] when Signature.Public_key_hash.equal account2 delegate -> - return_unit - | _ -> failwith "We are supposed to only have account2 as endorser." - in - fun () -> - let constants = - { - Default_parameters.constants_test with - endorsing_reward_per_slot = Tez.zero; - baking_reward_bonus_per_slot = Tez.zero; - baking_reward_fixed_portion = Tez.zero; - consensus_threshold = 0; - origination_size = 0; - preserved_cycles = 5; - ratio_of_frozen_deposits_slashed_per_double_endorsement = - (* enforce that ratio is 50% is the test's params. *) - {numerator = 1; denominator = 2}; - } - in - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((_contract1, account1), (_contract2, account2)) = - get_first_2_accounts_contracts contracts - in - (* we empty the available balance of [account1]. *) - Context.Delegate.info (B genesis) account1 >>=? fun info1 -> - Op.transaction - (B genesis) - (Contract.implicit_contract account1) - (Contract.implicit_contract account2) - Test_tez.(info1.full_balance -! info1.frozen_deposits) - >>=? fun op -> - Block.bake ~policy:(Block.By_account account2) genesis ~operations:[op] - >>=? fun b2 -> - Context.Delegate.info (B b2) account1 >>=? fun info2 -> - (* after block [b2], the spendable balance of [account1] is 0tz. So, given - that we have the invariant full_balance = spendable balance + - frozen_deposits, in this particular case, full_balance = frozen_deposits - for [account1], and the frozen_deposits didn't change since genesis. *) - Assert.equal_tez ~loc:__LOC__ info2.full_balance info2.frozen_deposits - >>=? fun () -> - Assert.equal_tez ~loc:__LOC__ info1.frozen_deposits info2.frozen_deposits - >>=? fun () -> - double_endorse_and_punish b2 account1 >>=? fun b3 -> - (* Denunciation has happened: we check that the full balance of [account1] - is (still) equal to its deposit. *) - Context.Delegate.info (B b3) account1 >>=? fun info3 -> - Assert.equal_tez - ~loc:__LOC__ - info3.full_balance - info3.current_frozen_deposits - >>=? fun () -> - (* We also check that compared to deposits at block [b2], [account1] lost - 50% of its deposits. *) - let slash_ratio = - constants.ratio_of_frozen_deposits_slashed_per_double_endorsement - in - let expected_frozen_deposits_after = - Test_tez.( - info2.frozen_deposits - *! Int64.of_int (slash_ratio.denominator - slash_ratio.numerator) - /! Int64.of_int slash_ratio.denominator) - in - Assert.equal_tez - ~loc:__LOC__ - expected_frozen_deposits_after - info3.current_frozen_deposits - >>=? fun () -> - (* We now bake until end of cycle only with [account2]: - block of the new cycle are called cX below. *) - Block.bake_until_cycle_end b3 >>=? fun c1 -> - double_endorse_and_punish c1 account1 >>=? fun c2 -> - (* Second denunciation has happened: we check that the full balance of - [account1] reflects the slashing of 50% of the original deposit. Its - current deposits are thus 0tz. *) - Context.Delegate.info (B c2) account1 >>=? fun info4 -> - Assert.equal_tez ~loc:__LOC__ info4.full_balance Tez.zero >>=? fun () -> - Assert.equal_tez ~loc:__LOC__ info4.current_frozen_deposits Tez.zero - >>=? fun () -> - Block.bake c2 ~policy:(By_account account1) >>= fun c3 -> - (* Once the deposits dropped to 0, the baker cannot bake anymore *) - Assert.proto_error_with_info ~loc:__LOC__ c3 "Zero frozen deposits" - >>=? fun () -> - (* We bake [2 * preserved_cycles] additional cycles only with [account2]. - Because [account1] does not bake during this period, it loses its rights. - *) - Block.bake_until_n_cycle_end - ~policy:(By_account account2) - (2 * constants.preserved_cycles) - c2 - >>=? fun d1 -> - Context.Delegate.info (B d1) account1 >>=? fun info5 -> - (* [account1] is only deactivated after 1 + [2 * preserved_cycles] (see - [Delegate_activation_storage.set_active] since the last time it was - active, that is, since the first cycle. Thus the cycle at which - [account1] is deactivated is 2 + [2 * preserved_cycles] from genesis. *) - Assert.equal_bool ~loc:__LOC__ info5.deactivated false >>=? fun () -> - (* account1 is still active, but has no rights. *) - check_unique_endorser d1 account2 >>=? fun () -> - Block.bake_until_cycle_end ~policy:(By_account account2) d1 >>=? fun e1 -> - (* account1 has no rights and furthermore is no longer active. *) - check_unique_endorser e1 account2 >>=? fun () -> - Context.Delegate.info (B e1) account1 >>=? fun info6 -> - Assert.equal_bool ~loc:__LOC__ info6.deactivated true - -let tests = - [ - Tztest.tztest - "valid double endorsement evidence" - `Quick - test_valid_double_endorsement_evidence; - Tztest.tztest - "2 valid double endorsement evidences lead to not being able to bake" - `Quick - test_two_double_endorsement_evidences_leadsto_no_bake; - Tztest.tztest - "invalid double endorsement evidence" - `Quick - test_invalid_double_endorsement; - Tztest.tztest - "another invalid double endorsement evidence" - `Quick - test_invalid_double_endorsement_variant; - Tztest.tztest - "too early double endorsement evidence" - `Quick - test_too_early_double_endorsement_evidence; - Tztest.tztest - "too late double endorsement evidence" - `Quick - test_too_late_double_endorsement_evidence; - Tztest.tztest "different delegates" `Quick test_different_delegates; - Tztest.tztest "wrong delegate" `Quick test_wrong_delegate; - Tztest.tztest - "freeze available balance after slashing" - `Quick - test_freeze_more_with_low_balance; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_double_preendorsement.ml b/src/proto_012_Psithaca/lib_protocol/test/test_double_preendorsement.ml deleted file mode 100644 index d5e5f7a2c2b3..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_double_preendorsement.ml +++ /dev/null @@ -1,337 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (double preendorsement) in Full_construction & Application modes - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ - -- test "^double preendorsement$" - Subject: These tests target different cases for double preendorsement *) - -open Protocol -open Alpha_context - -module type MODE = sig - val name : string - - val baking_mode : Block.baking_mode -end - -module BakeWithMode (Mode : MODE) : sig - val tests : unit Alcotest_lwt.test_case trace -end = struct - let name = Mode.name - - let bake = Block.bake ~baking_mode:Mode.baking_mode - - let bake_n = Block.bake_n ~baking_mode:Mode.baking_mode - - (****************************************************************) - (* Utility functions *) - (****************************************************************) - - (** Helper function for illformed denunciations construction *) - - let pick_endorsers ctxt = - let module V = Plugin.RPC.Validators in - Context.get_endorsers ctxt >>=? function - | a :: b :: _ -> - return ((a.V.delegate, a.V.slots), (b.V.delegate, b.V.slots)) - | _ -> assert false - - let invalid_denunciation loc res = - Assert.proto_error_with_info ~loc res "Invalid denunciation" - - let malformed_double_preendorsement_denunciation - ?(include_endorsement = false) ?(block_round = 0) - ?(mk_evidence = fun ctxt p1 p2 -> Op.double_preendorsement ctxt p1 p2) - ~loc () = - Context.init ~consensus_threshold:0 10 >>=? fun (genesis, _) -> - bake genesis >>=? fun b1 -> - bake ~policy:(By_round 0) b1 >>=? fun b2_A -> - Op.endorsement ~endorsed_block:b1 (B genesis) () >>=? fun e -> - let operations = if include_endorsement then [Operation.pack e] else [] in - bake ~policy:(By_round block_round) ~operations b1 >>=? fun b2_B -> - Op.preendorsement ~endorsed_block:b2_A (B b1) () >>=? fun op1 -> - Op.preendorsement ~endorsed_block:b2_B (B b1) () >>=? fun op2 -> - let op = mk_evidence (B genesis) op1 op2 in - bake b1 ~operations:[op] >>= fun res -> invalid_denunciation loc res - - let max_slashing_period () = - Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> - Context.get_constants (B genesis) - >>=? fun {parametric = {max_slashing_period; blocks_per_cycle; _}; _} -> - return (max_slashing_period * Int32.to_int blocks_per_cycle) - - let unrequired_denunciation loc res = - Assert.proto_error_with_info ~loc res "Unrequired denunciation" - - let inconsistent_denunciation loc res = - Assert.proto_error_with_info ~loc res "Inconsistent denunciation" - - let outdated_denunciation loc res = - Assert.proto_error_with_info ~loc res "Outdated denunciation" - - let unexpected_failure loc res = - (* no error is expected *) - Assert.proto_error ~loc res (function _ -> false) - - let unexpected_success loc _ _ _ _ _ = - Alcotest.fail (loc ^ ": Test should not succeed") - - let expected_success _loc baker pred bbad (d1, _) (d2, _) = - (* same preendorsers in case denunciation succeeds*) - Assert.equal_pkh ~loc:__LOC__ d1 d2 >>=? fun () -> - Context.get_constants (B pred) - >>=? fun Constants. - { - parametric = - { - ratio_of_frozen_deposits_slashed_per_double_endorsement = r; - _; - }; - _; - } -> - (* let's bake the block on top of pred without denunciating d1 *) - bake ~policy:(By_account baker) pred >>=? fun bgood -> - (* Checking what the endorser lost *) - Context.Delegate.current_frozen_deposits (B pred) d1 - >>=? fun frozen_deposit -> - Context.Delegate.full_balance (B bgood) d1 >>=? fun bal_good -> - Context.Delegate.full_balance (B bbad) d1 >>=? fun bal_bad -> - (* the diff of the two balances in normal and in denunciation cases *) - let diff_end_bal = Test_tez.(bal_good -! bal_bad) in - (* amount lost due to denunciation *) - let lost_deposit = - Test_tez.( - frozen_deposit *! Int64.of_int r.numerator /! Int64.of_int r.denominator) - in - (* have of the lost deposts will be earned by the baker *) - let denun_reward = Test_tez.(lost_deposit /! 2L) in - (* if the baker is the endorser, he'll only loose half of the deposits *) - let expected_endo_loss = - if Signature.Public_key_hash.equal baker d1 then - Test_tez.(lost_deposit -! denun_reward) - else lost_deposit - in - Assert.equal_tez ~loc:__LOC__ expected_endo_loss diff_end_bal >>=? fun () -> - (* Checking what the baker earned (or lost) *) - Context.Delegate.full_balance (B bgood) baker >>=? fun bal_good -> - Context.Delegate.full_balance (B bbad) baker >>=? fun bal_bad -> - (* if baker = endorser, the baker's balance in the good case is better, - because half of his deposits are burnt in the bad (double-preendorsement) - situation. In case baker <> endorser, bal_bad of the baker gets half of - burnt deposit of d1, so it's higher - *) - let (high, low) = - if Signature.Public_key_hash.equal baker d1 then (bal_good, bal_bad) - else (bal_bad, bal_good) - in - let diff_baker = Test_tez.(high -! low) in - (* the baker has either earnt or lost (in case baker = d1) half of burnt - endorsement deposits *) - Assert.equal_tez ~loc:__LOC__ denun_reward diff_baker >>=? fun () -> - return_unit - - let order_preendorsements ~correct_order op1 op2 = - let oph1 = Operation.hash op1 in - let oph2 = Operation.hash op2 in - let c = Operation_hash.compare oph1 oph2 in - if correct_order then if c < 0 then (op1, op2) else (op2, op1) - else if c < 0 then (op2, op1) - else (op1, op2) - - (** Helper function for denunciations inclusion *) - let generic_double_preendorsement_denunciation ~nb_blocks_before_double - ~nb_blocks_before_denunciation - ?(test_expected_ok = fun _loc _baker _pred _bbad _d1 _d2 -> return_unit) - ?(test_expected_ko = fun _loc _res -> return_unit) - ?(pick_endorsers = - fun ctxt -> pick_endorsers ctxt >>=? fun (a, _b) -> return (a, a)) ~loc - () = - Context.init ~consensus_threshold:0 10 >>=? fun (genesis, contracts) -> - let addr = - match List.hd contracts with None -> assert false | Some e -> e - in - (* bake `nb_blocks_before_double blocks` before double preendorsing *) - bake_n nb_blocks_before_double genesis >>=? fun blk -> - (* producing two differents blocks and two preendorsements op1 and op2 *) - Op.transaction (B genesis) addr addr Tez.one_mutez >>=? fun trans -> - bake ~policy:(By_round 0) blk >>=? fun head_A -> - bake ~policy:(By_round 0) blk ~operations:[trans] >>=? fun head_B -> - pick_endorsers (B head_A) >>=? fun (d1, d2) -> - (* default: d1 = d2 *) - Op.preendorsement ~delegate:d1 ~endorsed_block:head_A (B blk) () - >>=? fun op1 -> - Op.preendorsement ~delegate:d2 ~endorsed_block:head_B (B blk) () - >>=? fun op2 -> - let (op1, op2) = order_preendorsements ~correct_order:true op1 op2 in - (* bake `nb_blocks_before_denunciation` before double preend. denunciation *) - bake_n nb_blocks_before_denunciation blk >>=? fun blk -> - let op : Operation.packed = Op.double_preendorsement (B blk) op1 op2 in - Context.get_baker (B blk) ~round:0 >>=? fun baker -> - bake ~policy:(By_account baker) blk ~operations:[op] >>= function - | Ok new_head -> - test_expected_ok loc baker blk new_head d1 d2 >>=? fun () -> - let op : Operation.packed = - Op.double_preendorsement (B new_head) op2 op1 - in - bake new_head ~operations:[op] >>= invalid_denunciation loc - >>=? fun () -> - let op : Operation.packed = - Op.double_preendorsement (B new_head) op1 op2 - in - bake new_head ~operations:[op] >>= unrequired_denunciation loc - | Error _ as res -> test_expected_ko loc res - - (****************************************************************) - (* Tests *) - (****************************************************************) - - (** Preendorsing two blocks that are structurally equal is not punished *) - let malformed_double_preendorsement_denunciation_same_payload_hash_1 () = - malformed_double_preendorsement_denunciation ~loc:__LOC__ () - - (** Preendorsing two blocks that are structurally equal up to the endorsements - they include is not punished *) - let malformed_double_preendorsement_denunciation_same_payload_hash_2 () = - malformed_double_preendorsement_denunciation - (* including an endorsement in one of the blocks doesn't change its - payload hash *) - ~include_endorsement:true - ~loc:__LOC__ - () - - (** Denunciation evidence cannot have the same operations *) - let malformed_double_preendorsement_denunciation_same_preendorsement () = - malformed_double_preendorsement_denunciation - (* exactly the same preendorsement operation => illformed *) - ~mk_evidence:(fun ctxt p1 _p2 -> Op.double_preendorsement ctxt p1 p1) - ~loc:__LOC__ - () - - (** Preendorsing two blocks with different rounds is not punished *) - let malformed_double_preendorsement_denunciation_different_rounds () = - malformed_double_preendorsement_denunciation ~loc:__LOC__ ~block_round:1 () - - (** Preendorsing two blocks by two different validators is not punished *) - let malformed_double_preendorsement_denunciation_different_validators () = - generic_double_preendorsement_denunciation - ~nb_blocks_before_double:0 - ~nb_blocks_before_denunciation:2 - ~test_expected_ok:unexpected_success - ~test_expected_ko:inconsistent_denunciation - ~pick_endorsers (* pick different endorsers *) - ~loc:__LOC__ - () - - (** Attempt a denunciation of a double-pre in the first block after genesis *) - let double_preendorsement_just_after_upgrade () = - generic_double_preendorsement_denunciation - ~nb_blocks_before_double:0 - ~nb_blocks_before_denunciation:1 - ~test_expected_ok:expected_success - ~test_expected_ko:unexpected_failure - ~loc:__LOC__ - () - - (** Denunciation of double-pre at level L is injected at level L' = max_slashing_period. - The denunciation is outdated. *) - let double_preendorsement_denunciation_during_slashing_period () = - max_slashing_period () >>=? fun max_slashing_period -> - generic_double_preendorsement_denunciation - ~nb_blocks_before_double:0 - ~nb_blocks_before_denunciation:(max_slashing_period / 2) - ~test_expected_ok:expected_success - ~test_expected_ko:unexpected_failure - ~loc:__LOC__ - () - - (** Denunciation of double-pre at level L is injected 1 block after unfreeze - delay. Too late: denunciation is outdated. *) - let double_preendorsement_denunciation_after_slashing_period () = - max_slashing_period () >>=? fun max_slashing_period -> - generic_double_preendorsement_denunciation - ~nb_blocks_before_double:0 - ~nb_blocks_before_denunciation:(max_slashing_period + 1) - ~test_expected_ok:unexpected_success - ~test_expected_ko:outdated_denunciation - ~loc:__LOC__ - () - - let my_tztest title test = - Tztest.tztest (Format.sprintf "%s: %s" name title) test - - let tests = - [ - (* illformed denunciations *) - my_tztest - "ko: malformed_double_preendorsement_denunciation_same_payload_hash_1" - `Quick - malformed_double_preendorsement_denunciation_same_payload_hash_1; - my_tztest - "ko: malformed_double_preendorsement_denunciation_same_payload_hash_2" - `Quick - malformed_double_preendorsement_denunciation_same_payload_hash_2; - my_tztest - "ko: malformed_double_preendorsement_denunciation_different_rounds" - `Quick - malformed_double_preendorsement_denunciation_different_rounds; - my_tztest - "ko: malformed_double_preendorsement_denunciation_same_preendorsement" - `Quick - malformed_double_preendorsement_denunciation_same_preendorsement; - my_tztest - "ko: malformed_double_preendorsement_denunciation_different_validators" - `Quick - malformed_double_preendorsement_denunciation_different_validators; - my_tztest - "double_preendorsement_just_after_upgrade" - `Quick - double_preendorsement_just_after_upgrade; - (* tests for unfreeze *) - my_tztest - "double_preendorsement_denunciation_during_slashing_period" - `Quick - double_preendorsement_denunciation_during_slashing_period; - my_tztest - "double_preendorsement_denunciation_after_slashing_period" - `Quick - double_preendorsement_denunciation_after_slashing_period; - ] -end - -let tests = - let module AppMode = BakeWithMode (struct - let name = "AppMode" - - let baking_mode = Block.Application - end) in - let module ConstrMode = BakeWithMode (struct - let name = "ConstrMode" - - let baking_mode = Block.Baking - end) in - AppMode.tests @ ConstrMode.tests diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_endorsement.ml b/src/proto_012_Psithaca/lib_protocol/test/test_endorsement.ml deleted file mode 100644 index f84560f38b49..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_endorsement.ml +++ /dev/null @@ -1,594 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (endorsement) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^endorsement$" - Subject: Endorsing a block adds an extra layer of confidence - to the Tezos' PoS algorithm. The block endorsing - operation must be included in the following block. -*) - -open Protocol -open Alpha_context - -let init_genesis ?policy () = - Context.init ~consensus_threshold:0 5 >>=? fun (genesis, _) -> - Block.bake ?policy genesis >>=? fun b -> return (genesis, b) - -(** inject an endorsement and return the block with the endorsement and its - parent. *) -let inject_the_first_endorsement () = - init_genesis () >>=? fun (genesis, b) -> - Op.endorsement ~endorsed_block:b (B genesis) () >>=? fun op -> - Block.bake ~operations:[Operation.pack op] b >>=? fun b' -> return (b', b) - -(****************************************************************) -(* Tests *) -(****************************************************************) - -(** Apply a single endorsement from the slot 0 endorser. *) -let test_simple_endorsement () = - inject_the_first_endorsement () >>=? fun _ -> return_unit - -(****************************************************************) -(* The following test scenarios are supposed to raise errors. *) -(****************************************************************) - -(** Apply an endorsement with a negative slot. *) -let test_negative_slot () = - Context.init 5 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b -> - Context.get_endorser (B b) >>=? fun (delegate, _slots) -> - Lwt.catch - (fun () -> - Op.endorsement - ~delegate:(delegate, [Slot.of_int_do_not_use_except_for_parameters (-1)]) - ~endorsed_block:b - (B genesis) - () - >>=? fun _ -> - failwith "negative slot should not be accepted by the binary format") - (function - | Data_encoding.Binary.Write_error _ -> return_unit | e -> Lwt.fail e) - -(** Apply an endorsement with a non-normalized slot (that is, not the smallest - possible). *) -let test_non_normalized_slot () = - Context.init 5 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b -> - Context.get_endorsers (B b) >>=? fun endorsers_list -> - (* find an endorsers with more than 1 slot *) - List.find_map - (function - | {Plugin.RPC.Validators.delegate; slots; _} -> - if Compare.List_length_with.(slots > 1) then Some (delegate, slots) - else None) - endorsers_list - |> function - | None -> assert false - | Some (delegate, slots) -> - let set_slots = Slot.Set.of_list slots in - (* no duplicated slots *) - Assert.equal_int - ~loc:__LOC__ - (Slot.Set.cardinal set_slots) - (List.length slots) - >>=? fun () -> - (* the first slot should be the smallest slot *) - Assert.equal - ~loc:__LOC__ - (fun x y -> Slot.compare x y = 0) - "the first slot is not the smallest" - Slot.pp - (WithExceptions.Option.get ~loc:__LOC__ @@ List.hd slots) - (WithExceptions.Option.get ~loc:__LOC__ @@ Slot.Set.min_elt set_slots) - >>=? fun () -> - Op.endorsement - ~delegate:(delegate, List.rev slots) - ~endorsed_block:b - (B genesis) - () - >>=? fun op -> - let policy = Block.Excluding [delegate] in - Block.bake ~policy ~operations:[Operation.pack op] b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function err -> - let error_info = - Error_monad.find_info_of_error (Environment.wrap_tzerror err) - in - error_info.title = "wrong slot") - -(** Wrong endorsement predecessor : apply an endorsement with an - incorrect block predecessor. *) -let test_wrong_endorsement_predecessor () = - init_genesis () >>=? fun (genesis, b) -> - Op.endorsement ~endorsed_block:b (B genesis) ~signing_context:(B b) () - >>=? fun operation -> - let operation = Operation.pack operation in - Block.bake ~operation b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Wrong_consensus_operation_branch _ -> true - | _ -> false) - -(** Invalid_endorsement_level: apply an endorsement with an incorrect - level (i.e. the predecessor level). *) -let test_invalid_endorsement_level () = - init_genesis () >>=? fun (genesis, b) -> - Context.get_level (B genesis) >>?= fun genesis_level -> - Op.endorsement ~level:genesis_level ~endorsed_block:b (B genesis) () - >>=? fun op -> - Block.bake ~operations:[Operation.pack op] b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Wrong_level_for_consensus_operation _ -> true - | _ -> false) - -(** Duplicate endorsement : apply an endorsement that has already been applied. *) -let test_duplicate_endorsement () = - init_genesis () >>=? fun (genesis, b) -> - Incremental.begin_construction b >>=? fun inc -> - Op.endorsement ~endorsed_block:b (B genesis) () >>=? fun operation -> - let operation = Operation.pack operation in - Incremental.add_operation inc operation >>=? fun inc -> - Op.endorsement ~endorsed_block:b (B genesis) () >>=? fun operation -> - let operation = Operation.pack operation in - Incremental.add_operation inc operation >>= fun res -> - Assert.proto_error_with_info - ~loc:__LOC__ - res - "double inclusion of consensus operation" - -(** Consensus operation for future level : apply an endorsement with a level in the future *) -let test_consensus_operation_endorsement_for_future_level () = - init_genesis () >>=? fun (genesis, pred) -> - let raw_level = Raw_level.of_int32 (Int32.of_int 10) in - let level = match raw_level with Ok l -> l | Error _ -> assert false in - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:pred - ~level - ~error_title:"Consensus operation for future level" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Consensus operation for old level : apply an endorsement one level in the past *) -let test_consensus_operation_endorsement_for_predecessor_level () = - init_genesis () >>=? fun (genesis, pred) -> - let raw_level = Raw_level.of_int32 (Int32.of_int 0) in - let level = match raw_level with Ok l -> l | Error _ -> assert false in - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:pred - ~level - ~error_title:"Endorsement for previous level" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Consensus operation for old level : apply an endorsement with more than one level in the past *) -let test_consensus_operation_endorsement_for_old_level () = - init_genesis () >>=? fun (genesis, pred) -> - Block.bake genesis >>=? fun next_block -> - let raw_level = Raw_level.of_int32 (Int32.of_int 0) in - let level = match raw_level with Ok l -> l | Error _ -> assert false in - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:pred - ~level - ~error_title:"Consensus operation for old level" - ~context:(Context.B next_block) - ~construction_mode:(pred, None) - () - -(** Consensus operation for future round : apply an endorsement with a round in the future *) -let test_consensus_operation_endorsement_for_future_round () = - init_genesis () >>=? fun (genesis, pred) -> - Environment.wrap_tzresult (Round.of_int 21) >>?= fun round -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:pred - ~round - ~error_title:"Consensus operation for future round" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Consensus operation for old round : apply an endorsement with a round in the past *) -let test_consensus_operation_endorsement_for_old_round () = - init_genesis ~policy:(By_round 10) () >>=? fun (genesis, pred) -> - Environment.wrap_tzresult (Round.of_int 0) >>?= fun round -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:pred - ~round - ~error_title:"Consensus operation for old round" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Consensus operation on competing proposal : apply an endorsement on a competing proposal *) -let test_consensus_operation_endorsement_on_competing_proposal () = - init_genesis () >>=? fun (genesis, pred) -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:pred - ~block_payload_hash:Block_payload_hash.zero - ~error_title:"Consensus operation on competing proposal" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Wrong round : apply an endorsement with an incorrect round *) -let test_wrong_round () = - init_genesis () >>=? fun (genesis, b) -> - Environment.wrap_tzresult (Round.of_int 2) >>?= fun round -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:b - ~round - ~error_title:"wrong round for consensus operation" - ~context:(Context.B genesis) - () - -(** Wrong level : apply an endorsement with an incorrect level *) -let test_wrong_level () = - init_genesis () >>=? fun (genesis, b) -> - let context = Context.B genesis in - let raw_level = Raw_level.of_int32 (Int32.of_int 0) in - let level = match raw_level with Ok l -> l | Error _ -> assert false in - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:b - ~level - ~error_title:"wrong level for consensus operation" - ~context - () - -(** Wrong payload hash : apply an endorsement with an incorrect payload hash *) -let test_wrong_payload_hash () = - init_genesis () >>=? fun (genesis, b) -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:b - ~block_payload_hash:Block_payload_hash.zero - ~error_title:"wrong payload hash for consensus operation" - ~context:(Context.B genesis) - () - -let test_wrong_slot_used () = - init_genesis () >>=? fun (genesis, b) -> - Context.get_endorser (B b) >>=? fun (_, slots) -> - (match slots with - | _x :: y :: _ -> return y - | _ -> failwith "Slots size should be at least of 2 ") - >>=? fun slot -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:false - ~endorsed_block:b - ~slot - ~error_title:"wrong slot" - ~context:(Context.B genesis) - () - -(** Check that: - - a block with not enough endorsement cannot be baked; - - a block with enough endorsement is baked. *) -let test_endorsement_threshold ~sufficient_threshold () = - (* We choose a relative large number of accounts so that the probability that - any delegate has [consensus_threshold] slots is low and most delegates have - about 1 slot so we can get closer to the limit of [consensus_threshold]: we - check that a block with endorsing power [consensus_threshold - 1] won't be - baked. *) - Context.init 10 >>=? fun (genesis, _contracts) -> - Block.bake genesis >>=? fun b -> - Context.get_constants (B b) - >>=? fun {parametric = {consensus_threshold; _}; _} -> - Context.get_endorsers (B b) >>=? fun endorsers_list -> - Block.get_round b >>?= fun round -> - List.fold_left_es - (fun (counter, endos) {Plugin.RPC.Validators.delegate; slots; _} -> - let new_counter = counter + List.length slots in - if - (sufficient_threshold && counter < consensus_threshold) - || ((not sufficient_threshold) && new_counter < consensus_threshold) - then - Op.endorsement - ~round - ~delegate:(delegate, slots) - ~endorsed_block:b - (B genesis) - () - >>=? fun endo -> return (new_counter, Operation.pack endo :: endos) - else return (counter, endos)) - (0, []) - endorsers_list - >>=? fun (_, endos) -> - Block.bake ~operations:endos b >>= fun b -> - if sufficient_threshold then return_unit - else - Assert.proto_error ~loc:__LOC__ b (function err -> - let error_info = - Error_monad.find_info_of_error (Environment.wrap_tzerror err) - in - error_info.title = "Not enough endorsements") - -(** Fitness gap: this is a straightforward update from Emmy to Tenderbake, that - is, check that the level is incremented in a child block. *) -let test_fitness_gap () = - inject_the_first_endorsement () >>=? fun (b, pred_b) -> - let fitness = - match Fitness.from_raw b.header.shell.fitness with - | Ok fitness -> fitness - | _ -> assert false - in - let pred_fitness = - match Fitness.from_raw pred_b.header.shell.fitness with - | Ok fitness -> fitness - | _ -> assert false - in - let level = Fitness.level fitness in - let pred_level = Fitness.level pred_fitness in - let level_diff = - Int32.sub (Raw_level.to_int32 level) (Raw_level.to_int32 pred_level) - in - Assert.equal_int32 ~loc:__LOC__ level_diff 1l - -let test_preendorsement_endorsement_same_level () = - Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b1 -> - Incremental.begin_construction ~mempool_mode:true ~policy:(By_round 2) b1 - >>=? fun i -> - Op.endorsement ~endorsed_block:b1 (B genesis) () >>=? fun op_endo -> - let op_endo = Alpha_context.Operation.pack op_endo in - Incremental.add_operation i op_endo >>=? fun _i -> - Op.preendorsement ~endorsed_block:b1 (B genesis) () >>=? fun op_preendo -> - let op_preendo = Alpha_context.Operation.pack op_preendo in - Incremental.add_operation i op_preendo >>=? fun _i -> return () - -(** Test for endorsement injection with wrong slot in mempool mode. This - test is expected to fail *) -let test_wrong_endorsement_slot_in_mempool_mode () = - Context.init ~consensus_threshold:1 5 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b1 -> - let module V = Plugin.RPC.Validators in - (Context.get_endorsers (B b1) >>=? function - | {V.slots = _ :: non_canonical_slot :: _; _} :: _ -> - (* we didn't use min slot for the injection. It's bad !*) - return (Some non_canonical_slot) - | _ -> assert false) - >>=? fun slot -> - Op.endorsement ~endorsed_block:b1 (B genesis) ?slot () >>=? fun endo -> - let endo = Operation.pack endo in - Incremental.begin_construction ~mempool_mode:true b1 >>=? fun i -> - Incremental.add_operation i endo >>= fun res -> - Assert.proto_error_with_info ~loc:__LOC__ res "wrong slot" - -(** Endorsement for next level *) -let test_endorsement_for_next_level () = - init_genesis () >>=? fun (genesis, _) -> - Consensus_helpers.test_consensus_op_for_next - ~genesis - ~kind:`Endorsement - ~next:`Level - -(** Endorsement for next round *) -let test_endorsement_for_next_round () = - init_genesis () >>=? fun (genesis, _) -> - Consensus_helpers.test_consensus_op_for_next - ~genesis - ~kind:`Endorsement - ~next:`Round - -(** Endorsement of grandparent *) -let test_endorsement_grandparent () = - Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b_gp -> - Block.bake b_gp >>=? fun b -> - Incremental.begin_construction ~mempool_mode:true b >>=? fun i -> - (* Endorsement on grandparent *) - Op.endorsement ~endorsed_block:b_gp (B genesis) () >>=? fun op1 -> - (* Endorsement on parent *) - Op.endorsement ~endorsed_block:b (B b_gp) () >>=? fun op2 -> - let op1 = Alpha_context.Operation.pack op1 in - let op2 = Alpha_context.Operation.pack op2 in - (* Both should be accepted by the mempool *) - Incremental.add_operation i op1 >>=? fun i -> - Incremental.add_operation i op2 >>=? fun _i -> return () - -(** Double inclusion of grandparent endorsement *) -let test_double_endorsement_grandparent () = - Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b_gp -> - Block.bake b_gp >>=? fun b -> - Incremental.begin_construction ~mempool_mode:true b >>=? fun i -> - (* Endorsement on grandparent *) - Op.endorsement ~endorsed_block:b_gp (B genesis) () >>=? fun op1 -> - (* Endorsement on parent *) - Op.endorsement ~endorsed_block:b (B b_gp) () >>=? fun op2 -> - let op1 = Alpha_context.Operation.pack op1 in - let op2 = Alpha_context.Operation.pack op2 in - (* The first grand parent endorsement should be accepted by the - mempool but the second rejected. *) - Incremental.add_operation i op1 >>=? fun i -> - Incremental.add_operation i op1 >>= fun res -> - Assert.proto_error_with_info - ~loc:__LOC__ - res - "double inclusion of consensus operation" - >>=? fun () -> - Incremental.add_operation i op2 >>=? fun _i -> return () - -(** Endorsement of grandparent on same slot as parent *) -let test_endorsement_grandparent_same_slot () = - Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b_gp -> - Block.bake b_gp >>=? fun b -> - Incremental.begin_construction ~mempool_mode:true b >>=? fun i -> - (* Endorsement on parent *) - Consensus_helpers.delegate_of_first_slot (B b) >>=? fun (delegate, slot) -> - Op.endorsement ~endorsed_block:b ~delegate (B b_gp) () >>=? fun op2 -> - (* Endorsement on grandparent *) - Consensus_helpers.delegate_of_slot slot (B b_gp) >>=? fun delegate -> - Op.endorsement ~endorsed_block:b_gp ~delegate (B genesis) () >>=? fun op1 -> - let op1 = Alpha_context.Operation.pack op1 in - let op2 = Alpha_context.Operation.pack op2 in - (* Both should be accepted by the mempool *) - Incremental.add_operation i op1 >>=? fun i -> - Incremental.add_operation i op2 >>=? fun _i -> return () - -(** Endorsement of grandparent in application mode should be rejected *) -let test_endorsement_grandparent_application () = - Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b_gp -> - Block.bake b_gp >>=? fun b -> - Op.endorsement ~endorsed_block:b_gp (B genesis) () >>=? fun op -> - Block.bake ~operations:[Operation.pack op] b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Wrong_level_for_consensus_operation _ -> true - | _ -> false) - -(** Endorsement of grandparent in full construction mode should be rejected *) -let test_endorsement_grandparent_full_construction () = - Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b_gp -> - Block.bake b_gp >>=? fun b -> - Incremental.begin_construction b >>=? fun i -> - (* Endorsement on grandparent *) - Op.endorsement ~endorsed_block:b_gp (B genesis) () >>=? fun op1 -> - let op1 = Alpha_context.Operation.pack op1 in - Incremental.add_operation i op1 >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Wrong_level_for_consensus_operation _ -> true - | _ -> false) - -let tests = - [ - Tztest.tztest "Simple endorsement" `Quick test_simple_endorsement; - Tztest.tztest "Endorsement with slot -1" `Quick test_negative_slot; - Tztest.tztest - "Endorsement wrapped with non-normalized slot" - `Quick - test_non_normalized_slot; - Tztest.tztest "Fitness gap" `Quick test_fitness_gap; - (* Fail scenarios *) - Tztest.tztest - "Wrong endorsement predecessor" - `Quick - test_wrong_endorsement_predecessor; - Tztest.tztest - "Invalid endorsement level" - `Quick - test_invalid_endorsement_level; - Tztest.tztest "Duplicate endorsement" `Quick test_duplicate_endorsement; - Tztest.tztest - "Endorsement for future level" - `Quick - test_consensus_operation_endorsement_for_future_level; - Tztest.tztest - "Endorsement for predecessor level" - `Quick - test_consensus_operation_endorsement_for_old_level; - Tztest.tztest - "Endorsement for old level" - `Quick - test_consensus_operation_endorsement_for_old_level; - Tztest.tztest - "Endorsement for future round" - `Quick - test_consensus_operation_endorsement_for_future_round; - Tztest.tztest - "Endorsement for old round" - `Quick - test_consensus_operation_endorsement_for_old_round; - Tztest.tztest - "Endorsement on competing proposal" - `Quick - test_consensus_operation_endorsement_on_competing_proposal; - Tztest.tztest "Wrong level for consensus operation" `Quick test_wrong_level; - Tztest.tztest "Wrong round for consensus operation" `Quick test_wrong_round; - Tztest.tztest - "Wrong payload hash for consensus operation" - `Quick - test_wrong_payload_hash; - Tztest.tztest - "Wrong slot used for consensus operation" - `Quick - test_wrong_slot_used; - Tztest.tztest - "sufficient endorsement threshold" - `Quick - (test_endorsement_threshold ~sufficient_threshold:true); - Tztest.tztest - "insufficient endorsement threshold" - `Quick - (test_endorsement_threshold ~sufficient_threshold:false); - Tztest.tztest - "Endorsement/Preendorsement at same level" - `Quick - test_preendorsement_endorsement_same_level; - Tztest.tztest - "Wrong endorsement slot in mempool mode" - `Quick - test_wrong_endorsement_slot_in_mempool_mode; - Tztest.tztest - "Endorsement for next level" - `Quick - test_endorsement_for_next_level; - Tztest.tztest - "Endorsement for next round" - `Quick - test_endorsement_for_next_round; - Tztest.tztest - "Endorsement for grandparent" - `Quick - test_endorsement_grandparent; - Tztest.tztest - "Double endorsement of grandparent" - `Quick - test_double_endorsement_grandparent; - Tztest.tztest - "Endorsement for grandparent on same slot as parent" - `Quick - test_endorsement_grandparent_same_slot; - Tztest.tztest - "Endorsement for grandparent in application mode" - `Quick - test_endorsement_grandparent_application; - Tztest.tztest - "Endorsement for grandparent in full construction mode" - `Quick - test_endorsement_grandparent_full_construction; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_failing_noop.ml b/src/proto_012_Psithaca/lib_protocol/test/test_failing_noop.ml deleted file mode 100644 index a791db14ab4e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_failing_noop.ml +++ /dev/null @@ -1,62 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ - -- test "^failing_noop operation$" - Subject: The Failing_noop operation was added bearing in mind the - possibility for the end user to sign arbitrary bytes, - encapsulate in the operation, with the absolute garanty that - the signed bytes can't be used for something against the - user's will. The Failing_noop operation always fails when - applied. - *) - -open Protocol -open Alpha_context - -let register_one_contract () = - Context.init 1 >>=? fun (b, contracts) -> - let contract = - List.nth contracts 0 |> WithExceptions.Option.get ~loc:__LOC__ - in - return (b, contract) - -(** try to apply a failing_noop and assert that the operation fails *) -let failing_noop_must_fail_when_injected () = - register_one_contract () >>=? fun (blk, contract) -> - Contract.is_implicit contract |> function - | None -> Alcotest.fail "only implicit accounts can sign" - | Some source -> - Op.failing_noop (B blk) source "tezos" >>=? fun operation -> - Block.bake ~operation blk >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Failing_noop_error -> true - | _ -> false) - -let tests = - [Tztest.tztest "injection fails" `Quick failing_noop_must_fail_when_injected] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_fitness.ml b/src/proto_012_Psithaca/lib_protocol/test/test_fitness.ml deleted file mode 100644 index 12affd131b6b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_fitness.ml +++ /dev/null @@ -1,157 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (committee selection) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^fitness$" - Subject: test the fitness module -*) - -open Protocol - -let level_zero = Raw_level_repr.of_int32_exn 0l - -let round_of_int32_exn i = - match Round_repr.of_int32 i with - | Ok i -> i - | Error _ -> Stdlib.failwith "Invalid round representation" - -let make_tuple (level, r_opt, r0, r1) = - let r_opt = Option.map round_of_int32_exn r_opt in - let r0 = round_of_int32_exn r0 in - let r1 = round_of_int32_exn r1 in - (level, r_opt, r0, r1) - -let test_cases = - List.map - make_tuple - [ - (3l, Some 1l, 1l, 12l); - (10l, Some 1l, 1l, 12l); - (10l, Some 4l, 2l, 6l); - (10l, Some 4l, 1l, 12l); - (9l, Some 2l, 0l, 3l); - (7l, None, 0l, 3l); - (7l, None, 1l, 3l); - (0l, None, 0l, 0l); - (12l, Some 2l, 8l, 7l); - (10l, Some 0l, 1l, 1l); - (8l, None, 1l, 0l); - (12l, Some 1l, 8l, 7l); - (8l, None, 6l, 0l); - ] - -let rec product l1 l2 = - match l1 with - | [] -> [] - | h :: tl -> List.map (fun x -> (h, x)) l2 @ product tl l2 - -let test_product_cases = product test_cases test_cases - -let tuple_to_fitness (level, locked_round, predecessor_round, round) = - Fitness_repr.create - ~level:(Raw_level_repr.of_int32_exn level) - ~locked_round - ~predecessor_round - ~round - -let tuple_to_fitness_exn tuple = - tuple_to_fitness tuple |> function - | Ok f -> f - | Error err -> - Format.kasprintf - Stdlib.failwith - "cannot create fitness from tuple: %a" - pp_print_trace - (Environment.wrap_tztrace err) - -let test_from_to_raw_fitness tuple = - let fitness = tuple_to_fitness_exn tuple in - Fitness_repr.from_raw (Fitness_repr.to_raw fitness) |> function - | Ok new_fitness -> assert (fitness = new_fitness) - | Error _x -> assert false - -let test_from_to_raw_fitness_all () = - List.iter test_from_to_raw_fitness test_cases ; - return_unit - -let test_locked_round () = - let test_bad_cases = - List.map - make_tuple - [ - (8l, Some 7l, 1l, 1l); - (9l, Some 8l, 0l, 3l); - (10l, Some 7l, 2l, 6l); - (11l, Some 5l, 5l, 1l); - (8l, Some 2l, 1l, 1l); - (9l, Some 3l, 0l, 3l); - (11l, Some 5l, 5l, 1l); - (13l, Some 2l, 1l, 1l); - (10l, Some 4l, 1l, 1l); - (8l, Some 7l, 1l, 1l); - (10l, Some 8l, 2l, 6l); - (11l, Some 9l, 5l, 1l); - (12l, Some 10l, 8l, 7l); - (13l, Some 14l, 1l, 1l); - ] - in - List.iter_es - (fun tuple -> - Environment.wrap_tzresult @@ tuple_to_fitness tuple |> function - | Error - [ - Environment.Ecoproto_error - (Fitness_repr.Locked_round_not_less_than_round _); - ] -> - return_unit - | Error err -> failwith "unexpected failure: %a" pp_print_trace err - | Ok f -> failwith "unexpected success: %a" Fitness_repr.pp f) - test_bad_cases - -let test_compare (tuple1, tuple2) = - let fitness1 = tuple_to_fitness_exn tuple1 in - let fitness2 = tuple_to_fitness_exn tuple2 in - let raw_fitness1 = Fitness_repr.to_raw fitness1 in - let raw_fitness2 = Fitness_repr.to_raw fitness2 in - let cmp_fitness = Fitness_repr.Internal_for_tests.compare fitness1 fitness2 in - let cmp_raw_fitness = Fitness.compare raw_fitness1 raw_fitness2 in - Assert.equal_int ~loc:__LOC__ cmp_fitness cmp_raw_fitness - -let test_compare_all () = List.iter_es test_compare test_product_cases - -let tests = - [ - Tztest.tztest - "from/to raw fitness is identity" - `Quick - test_from_to_raw_fitness_all; - Tztest.tztest "locked round is smaller than round" `Quick test_locked_round; - Tztest.tztest - "compare fitness = compare raw_fitness" - `Quick - test_compare_all; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_fixed_point.ml b/src/proto_012_Psithaca/lib_protocol/test/test_fixed_point.ml deleted file mode 100644 index c4f44f70acf5..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_fixed_point.ml +++ /dev/null @@ -1,174 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (fixed-point decimals) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^fixed point computation$" - Subject: On fixed-point decimal numbers. -*) - -open Protocol - -exception Fixed_point_test_error of string - -let err x = Exn (Fixed_point_test_error x) - -module type Arith = sig - type t - - val zero : t - - val equal : t -> t -> bool - - val random : unit -> t - - val add : t -> t -> t - - val sub : t -> t -> t -end - -let n = Z.of_int 42 - -let n' = Z.of_int 43 - -let basic_arith name (module A : Arith) = - let err msg = err (Format.asprintf "%s test: %s" name msg) in - let x = A.random () in - fail_unless A.(add zero x = x) (err "zero is neutral for +") >>=? fun () -> - let x = A.random () in - let y = A.random () in - fail_unless A.(add x y = add y x) (err "addition is commutative") - >>=? fun () -> - let x = A.random () in - fail_unless - A.(sub (add zero x) x = zero) - (err "addition and subtraction cancel") - >>=? fun () -> - let x = A.random () in - let y = A.random () in - let z = A.random () in - fail_unless - A.(add x (add y z) = add (add x y) z) - (err "addition is associative") - -let arith_from_integral : (module Fixed_point_repr.Full) -> (module Arith) = - fun (module FP) -> - let module Arith = struct - type t = FP.integral - - let zero = FP.zero - - let equal = FP.equal - - let random () = FP.integral_of_int_exn (Random.int 898987) - - let add = FP.add - - let sub = FP.sub - end in - (module Arith) - -let arith_from_fp : (module Fixed_point_repr.Full) -> (module Arith) = - fun (module FP) -> - let module Arith = struct - type t = FP.fp - - let zero = FP.zero - - let equal = FP.equal - - let random () = FP.unsafe_fp (Z.of_int (Random.int 898987)) - - let add = FP.add - - let sub = FP.sub - end in - (module Arith) - -let integral_tests () = - let module FP = Gas_limit_repr.Arith in - (* test roundtrips *) - fail_unless (FP.(integral_to_z (integral_exn n)) = n) (err "roundtrip > 0") - >>=? fun () -> - fail_unless - (FP.(integral_to_z (integral_exn Z.zero)) = Z.zero) - (err "roundtrip = 0") - >>=? fun () -> - (* test ceil/floor on integral *) - fail_unless - FP.(ceil (fp (integral_exn n)) = integral_exn n) - (err "integral;fp;ceil = integral") - >>=? fun () -> - fail_unless - FP.(floor (fp (integral_exn n)) = integral_exn n) - (err "integral;fp;floor = integral") - >>=? fun () -> - fail_unless - (Format.asprintf "%a" FP.pp FP.(fp (integral_exn n)) - = Format.asprintf "%a" FP.pp_integral (FP.integral_exn n)) - (err "pp_integral(integral) = pp(fp(integral))") - >>=? fun () -> basic_arith "integral arith" (arith_from_integral (module FP)) - -let fp_nonzero () = - let decimals = 3 in - let module FP = Gas_limit_repr.Arith in - let prefix msg = Format.asprintf "(%d decimals) %s" decimals msg in - let err msg = err (prefix msg) in - basic_arith (prefix "integral arith") (arith_from_integral (module FP)) - >>=? fun () -> - basic_arith (prefix "fp arith") (arith_from_fp (module FP)) >>=? fun () -> - let epsilon = FP.unsafe_fp Z.one in - fail_unless FP.(ceil epsilon = integral_exn Z.one) (err "ceil eps = 1") - >>=? fun () -> - fail_unless FP.(floor epsilon = integral_exn Z.zero) (err "floor eps = 1") - >>=? fun () -> - let x = Z.of_int (Random.int 980812) in - fail_unless - FP.( - ceil (add (fp (integral_exn x)) (unsafe_fp Z.one)) - = integral_exn (Z.succ x)) - (err "ceil (x + eps) = x + 1") - -let fp_pp () = - let module FP = Gas_limit_repr.Arith in - let prefix msg = Format.asprintf "(%d decimals) %s" 3 msg in - let err msg = err (prefix msg) in - let epsilon = FP.unsafe_fp Z.one in - let ( =:= ) x expected = Format.asprintf "%a" FP.pp x = expected in - fail_unless (epsilon =:= "0.001") (err "eps = 0.001") >>=? fun () -> - fail_unless (FP.unsafe_fp (Z.of_int 1000) =:= "1") (err "1.000 = 1") - >>=? fun () -> - fail_unless (FP.unsafe_fp (Z.of_int 1001) =:= "1.001") (err "1.001") - >>=? fun () -> - fail_unless (FP.unsafe_fp (Z.of_int 10001) =:= "10.001") (err "10.001") - >>=? fun () -> fail_unless (FP.zero =:= "0") (err "0") - -let tests = - [ - Tztest.tztest "Integral tests (3 decimals)" `Quick integral_tests; - Tztest.tztest "FP tests (3 decimals)" `Quick fp_nonzero; - Tztest.tztest "FP pp tests (3 decimals)" `Quick fp_pp; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_frozen_deposits.ml b/src/proto_012_Psithaca/lib_protocol/test/test_frozen_deposits.ml deleted file mode 100644 index d377bd4a1233..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_frozen_deposits.ml +++ /dev/null @@ -1,631 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (frozen_deposits) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^frozen deposits$" - Subject: consistency of frozen deposits and the [set_deposits_limit] operation - *) - -open Protocol -open Alpha_context -open Test_tez - -let constants = - { - Default_parameters.constants_test with - endorsing_reward_per_slot = Tez.zero; - baking_reward_bonus_per_slot = Tez.zero; - baking_reward_fixed_portion = Tez.zero; - consensus_threshold = 0; - origination_size = 0; - } - -let get_first_2_accounts_contracts contracts = - let ((contract1, account1), (contract2, account2)) = - match contracts with - | [a1; a2] -> - ( ( a1, - Contract.is_implicit a1 |> function - | None -> assert false - | Some pkh -> pkh ), - ( a2, - Contract.is_implicit a2 |> function - | None -> assert false - | Some pkh -> pkh ) ) - | _ -> assert false - in - ((contract1, account1), (contract2, account2)) - -(* Terminology: - -- staking balance = full balance + delegated stake; obtained with - Delegate.staking_balance - -- active stake = the amount of tez with which a delegate participates in - consensus; it must be greater than 1 roll and less or equal the staking - balance; it is computed in [Delegate_storage.select_distribution_for_cycle] - -- frozen deposits = represents frozen_deposits_percentage of the maximum stake during - preserved_cycles + max_slashing_period cycles; obtained with - Delegate.current_frozen_deposits - -- spendable balance = full balance - frozen deposits; obtained with Contract.balance - -- full balance = spendable balance + frozen deposits; obtained with Delegate.full_balance -*) -let test_invariants () = - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((contract1, account1), (contract2, _account2)) = - get_first_2_accounts_contracts contracts - in - Context.Delegate.staking_balance (B genesis) account1 - >>=? fun staking_balance -> - Context.Delegate.full_balance (B genesis) account1 >>=? fun full_balance -> - Context.Contract.balance (B genesis) contract1 >>=? fun spendable_balance -> - Context.Delegate.current_frozen_deposits (B genesis) account1 - >>=? fun frozen_deposits -> - (* before delegation *) - Assert.equal_tez ~loc:__LOC__ full_balance staking_balance >>=? fun () -> - Assert.equal_tez - ~loc:__LOC__ - full_balance - Test_tez.(spendable_balance +! frozen_deposits) - >>=? fun () -> - (* to see how delegation plays a role, let's delegate to account1; - N.B. account2 represents a delegate so it cannot delegate to account1; this is - why we go through new_account as an intermediate *) - Context.Contract.balance (B genesis) contract2 >>=? fun spendable_balance2 -> - let new_account = (Account.new_account ()).pkh in - let new_contract = Contract.implicit_contract new_account in - (* we first put some money in new_account *) - Op.transaction (B genesis) contract2 new_contract spendable_balance2 - >>=? fun transfer -> - Block.bake ~operation:transfer genesis >>=? fun b -> - Context.Contract.balance (B b) new_contract >>=? fun new_account_balance -> - Assert.equal_tez ~loc:__LOC__ new_account_balance spendable_balance2 - >>=? fun () -> - Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> - Block.bake ~operation:delegation b >>=? fun b1 -> - Block.bake_until_n_cycle_end constants.preserved_cycles b1 >>=? fun b2 -> - Context.Delegate.staking_balance (B b2) account1 - >>=? fun new_staking_balance -> - Context.Delegate.full_balance (B b2) account1 >>=? fun new_full_balance -> - Context.Contract.balance (B b2) contract1 >>=? fun new_spendable_balance -> - Context.Delegate.current_frozen_deposits (B b2) account1 - >>=? fun new_frozen_deposits -> - (* after delegation, we see the delegated stake reflected in the new staking - balance of account1 *) - Assert.equal_tez - ~loc:__LOC__ - new_staking_balance - Test_tez.(new_full_balance +! new_account_balance) - >>=? fun () -> - Assert.equal_tez - ~loc:__LOC__ - new_full_balance - Test_tez.(new_spendable_balance +! new_frozen_deposits) - >>=? fun () -> - let expected_new_frozen_deposits = - Test_tez.( - (* in this particular example, if we follow the calculation of the active - stake, it is precisely the new_staking_balance *) - new_staking_balance /! 100L - *! Int64.of_int constants.frozen_deposits_percentage) - in - Assert.equal_tez ~loc:__LOC__ new_frozen_deposits expected_new_frozen_deposits - -let test_set_limit balance_percentage () = - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((contract1, account1), (_contract2, account2)) = - get_first_2_accounts_contracts contracts - in - (Context.Delegate.frozen_deposits_limit (B genesis) account1 >>=? function - | Some _ -> Alcotest.fail "unexpected deposits limit" - | None -> return_unit) - >>=? fun () -> - (* Test deposit consistency before and after first cycle *) - Context.Delegate.full_balance (B genesis) account1 >>=? fun full_balance -> - Context.Delegate.current_frozen_deposits (B genesis) account1 - >>=? fun frozen_deposits -> - let expected_deposits = - full_balance *! Int64.of_int constants.frozen_deposits_percentage /! 100L - in - Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_deposits >>=? fun () -> - (* Bake until end of first cycle *) - Block.bake_until_cycle_end genesis >>=? fun b -> - Context.Delegate.full_balance (B genesis) account1 >>=? fun full_balance -> - Context.Delegate.current_frozen_deposits (B genesis) account1 - >>=? fun frozen_deposits -> - let expected_deposits = - full_balance *! Int64.of_int constants.frozen_deposits_percentage /! 100L - in - Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_deposits >>=? fun () -> - (* set deposits limit to balance_percentage out of the balance *) - let limit = - Test_tez.(full_balance *! Int64.of_int balance_percentage /! 100L) - in - Op.set_deposits_limit (B genesis) contract1 (Some limit) >>=? fun operation -> - Block.bake ~policy:(By_account account2) ~operation b >>=? fun b -> - (Context.Delegate.frozen_deposits_limit (B b) account1 >>=? function - | Some set_limit -> Assert.equal_tez ~loc:__LOC__ set_limit limit - | None -> Alcotest.fail "unexpected absence of deposits limit") - >>=? fun () -> - (* the frozen deposits limit affects the active stake for cycles starting with c + - preserved_cycles + 1; the new active stake is taken into account when - computing the frozen deposits for cycle c+1 already, however the user may see - an update to its frozen deposits at cycle c + preserved_cycles + - max_slashing_period at the latest (because up to that cycle the frozen - deposits also depend on the active stake at cycles before cycle c+1). *) - let expected_number_of_cycles_with_previous_deposit = - constants.preserved_cycles + constants.max_slashing_period - in - Block.bake_until_n_cycle_end - ~policy:(By_account account2) - (expected_number_of_cycles_with_previous_deposit - 1) - b - >>=? fun b -> - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits -> - Assert.not_equal_tez ~loc:__LOC__ frozen_deposits Tez.zero >>=? fun () -> - Block.bake_until_cycle_end ~policy:(By_account account2) b >>=? fun b -> - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ frozen_deposits limit - -let test_cannot_bake_with_zero_deposits () = - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((contract1, account1), (_contract2, account2)) = - get_first_2_accounts_contracts contracts - in - (* N.B. there is no non-zero frozen deposits value for which one cannot bake: - even with a small deposit one can still bake, though with a smaller probability - (because the frozen deposits value impacts the active stake and the active - stake is the one used to determine baking/endorsing rights. *) - Op.set_deposits_limit (B genesis) contract1 (Some Tez.zero) - >>=? fun operation -> - Block.bake ~policy:(By_account account2) ~operation genesis >>=? fun b -> - let expected_number_of_cycles_with_previous_deposit = - constants.preserved_cycles + constants.max_slashing_period - 1 - in - Block.bake_until_n_cycle_end - ~policy:(By_account account2) - expected_number_of_cycles_with_previous_deposit - b - >>=? fun b -> - Block.bake ~policy:(By_account account1) b >>= fun b1 -> - (* by now, the active stake of account1 is 0 so it no longer has slots, thus it - cannot be a proposer, thus it cannot bake. Precisely, bake fails because - get_next_baker_by_account fails with "No slots found" *) - Assert.error ~loc:__LOC__ b1 (fun _ -> true) - -let test_deposits_after_stake_removal () = - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((contract1, account1), (contract2, account2)) = - get_first_2_accounts_contracts contracts - in - Context.Delegate.current_frozen_deposits (B genesis) account1 - >>=? fun initial_frozen_deposits_1 -> - Context.Delegate.current_frozen_deposits (B genesis) account2 - >>=? fun initial_frozen_deposits_2 -> - let expected_new_frozen_deposits_2 = - Test_tez.(initial_frozen_deposits_2 *! 3L /! 2L) - in - (* Move half the account1's balance to account2 *) - Context.Delegate.full_balance (B genesis) account1 >>=? fun full_balance -> - let half_balance = Test_tez.(full_balance /! 2L) in - Op.transaction (B genesis) contract1 contract2 half_balance - >>=? fun operation -> - Block.bake ~operation genesis >>=? fun b -> - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits_1 -> - Assert.equal_tez ~loc:__LOC__ frozen_deposits_1 initial_frozen_deposits_1 - >>=? fun () -> - Context.Delegate.current_frozen_deposits (B b) account2 - >>=? fun frozen_deposits_2 -> - Assert.equal_tez ~loc:__LOC__ frozen_deposits_2 initial_frozen_deposits_2 - >>=? fun () -> - (* Bake a cycle to act account2's new frozen deposits *) - Block.bake_until_cycle_end b >>=? fun b -> - let rec loop b n = - if n = 0 then return b - else - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits_1 -> - (* the frozen_deposits is frozen_deposits_percentage of the maximum active stake - during the last preserved_cycles + max_slashing_period cycles; - consequently, though the active stake of account1 has decreased at - cycle c, this decrease makes the frozen deposits smaller only after - preserved cycles + max_slashing_period. *) - Assert.equal_tez ~loc:__LOC__ frozen_deposits_1 initial_frozen_deposits_1 - >>=? fun () -> - (* the active stake of account2 has increased and this increase affects - the frozen_deposits from this cycle as it is greater than previous ones. *) - Context.Delegate.current_frozen_deposits (B b) account2 - >>=? fun frozen_deposits_2 -> - Assert.equal_tez - ~loc:__LOC__ - frozen_deposits_2 - expected_new_frozen_deposits_2 - >>=? fun () -> - Block.bake_until_cycle_end b >>=? fun b -> loop b (pred n) - in - (* the frozen deposits for account1 do not change until [preserved cycles + - max_slashing_period] are baked (-1 because we already baked a cycle) *) - loop b (constants.preserved_cycles + constants.max_slashing_period - 1) - >>=? fun b -> - (* after preserved cycles + max_slashing_period, the frozen_deposits for account1 - reflects the decrease in account1's active stake. *) - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits_1 -> - Assert.equal_tez - ~loc:__LOC__ - frozen_deposits_1 - Test_tez.(initial_frozen_deposits_1 /! 2L) - >>=? fun () -> - Context.Delegate.current_frozen_deposits (B b) account2 - >>=? fun frozen_deposits_2 -> - Assert.equal_tez ~loc:__LOC__ frozen_deposits_2 expected_new_frozen_deposits_2 - -let test_unfreeze_deposits_after_deactivation () = - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((contract1, account1), (_contract2, account2)) = - get_first_2_accounts_contracts contracts - in - Context.Delegate.full_balance (B genesis) account1 >>=? fun initial_balance -> - (* [account1] will not participate (ie bake/endorse); we set the - expected last cycles at which it is considered active and at - which it has non-zero deposits *) - let last_active_cycle = - 1 + (2 * constants.preserved_cycles) - (* according to [Delegate_storage.set_active] *) - in - let last_cycle_with_deposits = - last_active_cycle + constants.preserved_cycles - + constants.max_slashing_period - (* according to [Delegate_storage.freeze_deposits] *) - in - let cycles_to_bake = last_cycle_with_deposits + constants.preserved_cycles in - let rec loop b n = - if n = 0 then return b - else - Block.bake_until_cycle_end ~policy:(By_account account2) b >>=? fun b -> - Context.Delegate.deactivated (B b) account1 >>=? fun is_deactivated -> - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits -> - (* the spendable balance *) - Context.Contract.balance (B b) contract1 >>=? fun balance -> - let new_cycle = cycles_to_bake - n + 1 in - Assert.equal_bool - ~loc:__LOC__ - is_deactivated - (new_cycle > last_active_cycle) - >>=? fun () -> - Assert.equal_bool - ~loc:__LOC__ - (new_cycle > last_cycle_with_deposits) - (* as soon as frozen_deposits are set to zero from a non-zero value v, v is - returned to the spendable balance of account1; in this particular - case, the spendable balance [balance] updated with v is precisely the - initial_balance.*) - (Tez.(frozen_deposits = zero) && Tez.(balance = initial_balance)) - >>=? fun () -> loop b (pred n) - in - loop genesis cycles_to_bake >>=? fun _b -> return_unit - -let test_frozen_deposits_with_delegation () = - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((_contract1, account1), (contract2, account2)) = - get_first_2_accounts_contracts contracts - in - Context.Delegate.staking_balance (B genesis) account1 - >>=? fun initial_staking_balance -> - Context.Delegate.current_frozen_deposits (B genesis) account1 - >>=? fun initial_frozen_deposits -> - Context.Contract.balance (B genesis) contract2 >>=? fun delegated_amount -> - let new_account = Account.new_account () in - let new_contract = Contract.implicit_contract new_account.pkh in - Op.transaction (B genesis) contract2 new_contract delegated_amount - >>=? fun transfer -> - Block.bake ~operation:transfer genesis >>=? fun b -> - Context.Delegate.staking_balance (B b) account2 - >>=? fun new_staking_balance -> - let expected_new_staking_balance = - Test_tez.(initial_staking_balance -! delegated_amount) - in - Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance - >>=? fun () -> - Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> - Block.bake ~operation:delegation b >>=? fun b -> - let expected_new_staking_balance = - Test_tez.(initial_staking_balance +! delegated_amount) - in - Context.Delegate.staking_balance (B b) account1 - >>=? fun new_staking_balance -> - Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance - >>=? fun () -> - (* Bake one cycle to update the frozen deposits *) - Block.bake_until_cycle_end b >>=? fun b -> - let expected_new_frozen_deposits = - Test_tez.( - initial_frozen_deposits - +! delegated_amount - *! Int64.of_int constants.frozen_deposits_percentage - /! 100L) - in - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun new_frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ new_frozen_deposits expected_new_frozen_deposits - >>=? fun () -> - let cycles_to_bake = - 2 * (constants.preserved_cycles + constants.max_slashing_period) - in - let rec loop b n = - if n = 0 then return b - else - Block.bake_until_cycle_end ~policy:(By_account account1) b >>=? fun b -> - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits - >>=? fun () -> loop b (pred n) - in - (* Check that frozen deposits do not change for a sufficient period of - time *) - loop b cycles_to_bake >>=? fun _b -> return_unit - -let test_frozen_deposits_with_overdelegation () = - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((contract1, account1), (contract2, account2)) = - get_first_2_accounts_contracts contracts - in - (* - [account1] and [account2] give their spendable balance to [new_account] - - [new_account] overdelegates to [account1] *) - Context.Delegate.staking_balance (B genesis) account1 - >>=? fun initial_staking_balance -> - Context.Delegate.staking_balance (B genesis) account2 - >>=? fun initial_staking_balance' -> - Context.Delegate.current_frozen_deposits (B genesis) account1 - >>=? fun initial_frozen_deposits -> - Context.Contract.balance (B genesis) contract1 >>=? fun amount -> - Context.Contract.balance (B genesis) contract2 >>=? fun amount' -> - let new_account = (Account.new_account ()).pkh in - let new_contract = Contract.implicit_contract new_account in - Op.transaction (B genesis) contract1 new_contract amount >>=? fun transfer1 -> - Op.transaction (B genesis) contract2 new_contract amount' - >>=? fun transfer2 -> - Block.bake ~operations:[transfer1; transfer2] genesis >>=? fun b -> - let expected_new_staking_balance = - Test_tez.(initial_staking_balance -! amount) - in - Context.Delegate.staking_balance (B b) account1 - >>=? fun new_staking_balance -> - Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance - >>=? fun () -> - let expected_new_staking_balance' = - Test_tez.(initial_staking_balance' -! amount') - in - Context.Delegate.staking_balance (B b) account2 - >>=? fun new_staking_balance' -> - Assert.equal_tez - ~loc:__LOC__ - new_staking_balance' - expected_new_staking_balance' - >>=? fun () -> - Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> - Block.bake ~operation:delegation b >>=? fun b -> - Context.Delegate.staking_balance (B b) account1 - >>=? fun new_staking_balance -> - let expected_new_staking_balance = - Test_tez.(initial_frozen_deposits +! amount +! amount') - in - Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance - >>=? fun () -> - (* Finish the cycle to update the frozen deposits *) - Block.bake_until_cycle_end b >>=? fun b -> - Context.Delegate.full_balance (B b) account1 - >>=? fun expected_new_frozen_deposits -> - (* the equality follows from the definition of active stake in - [Delegate.select_distribution_for_cycle]. *) - assert (initial_frozen_deposits = expected_new_frozen_deposits) ; - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun new_frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ new_frozen_deposits expected_new_frozen_deposits - >>=? fun () -> - let cycles_to_bake = - 2 * (constants.preserved_cycles + constants.max_slashing_period) - in - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits - >>=? fun () -> - let rec loop b n = - if n = 0 then return b - else - Block.bake_until_cycle_end ~policy:(By_account account1) b >>=? fun b -> - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits - >>=? fun () -> loop b (pred n) - in - (* Check that frozen deposits do not change for a sufficient period of - time *) - loop b cycles_to_bake >>=? fun _b -> return_unit - -let test_set_limit_with_overdelegation () = - let constants = {constants with frozen_deposits_percentage = 10} in - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((contract1, account1), (contract2, account2)) = - get_first_2_accounts_contracts contracts - in - (* - [account1] and [account2] will give 80% of their balance to - [new_account] - - [new_account] will overdelegate to [account1] but [account1] will set - its frozen deposits limit to 15% of its stake *) - Context.Delegate.staking_balance (B genesis) account1 - >>=? fun initial_staking_balance -> - Context.Delegate.staking_balance (B genesis) account2 - >>=? fun initial_staking_balance' -> - let amount = Test_tez.(initial_staking_balance *! 8L /! 10L) in - let amount' = Test_tez.(initial_staking_balance' *! 8L /! 10L) in - let limit = Test_tez.(initial_staking_balance *! 15L /! 100L) in - let new_account = (Account.new_account ()).pkh in - let new_contract = Contract.implicit_contract new_account in - Op.transaction (B genesis) contract1 new_contract amount >>=? fun transfer1 -> - Op.transaction (B genesis) contract2 new_contract amount' - >>=? fun transfer2 -> - Block.bake ~operations:[transfer1; transfer2] genesis >>=? fun b -> - Op.set_deposits_limit (B b) contract1 (Some limit) >>=? fun set_deposits -> - Block.bake ~operation:set_deposits b >>=? fun b -> - let expected_new_staking_balance = - Test_tez.(initial_staking_balance -! amount) - in - Context.Delegate.staking_balance (B b) account1 - >>=? fun new_staking_balance -> - Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance - >>=? fun () -> - let expected_new_staking_balance' = - Test_tez.(initial_staking_balance' -! amount') - in - Context.Delegate.staking_balance (B b) account2 - >>=? fun new_staking_balance' -> - Assert.equal_tez - ~loc:__LOC__ - new_staking_balance' - expected_new_staking_balance' - >>=? fun () -> - Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> - Block.bake ~operation:delegation b >>=? fun b -> - (* Finish the cycle to update the frozen deposits *) - Block.bake_until_cycle_end b >>=? fun b -> - let expected_new_frozen_deposits = limit in - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits - >>=? fun () -> - let cycles_to_bake = - 2 * (constants.preserved_cycles + constants.max_slashing_period) - in - let rec loop b n = - if n = 0 then return b - else - Block.bake_until_cycle_end ~policy:(By_account account1) b >>=? fun b -> - Context.Delegate.current_frozen_deposits (B b) account1 - >>=? fun frozen_deposits -> - Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits - >>=? fun () -> loop b (pred n) - in - (* Check that frozen deposits do not change for a sufficient period of - time *) - loop b cycles_to_bake >>=? fun _b -> return_unit - -(** This test fails when [to_cycle] in [Delegate.freeze_deposits] is smaller than - [new_cycle + preserved_cycles]. *) -let test_error_is_thrown_when_smaller_upper_bound_for_frozen_window () = - Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> - let ((contract1, account1), (contract2, _account2)) = - match contracts with - | [a1; a2] -> - ( ( a1, - Contract.is_implicit a1 |> function - | None -> assert false - | Some pkh -> pkh ), - ( a2, - Contract.is_implicit a2 |> function - | None -> assert false - | Some pkh -> pkh ) ) - | _ -> assert false - in - (* [account2] delegates (through [new_account]) to [account1] its spendable - balance. The point is to make [account1] have a lot of staking balance so - that, after [preserved_cycles] when the active stake reflects this increase - in staking balance, its [maximum_stake_to_be_deposited] is bigger than the frozen - deposit which is computed on a smaller window because [to_cycle] is smaller - than [new_cycle + preserved_cycles]. *) - Context.Contract.balance (B genesis) contract2 >>=? fun delegated_amount -> - let new_account = Account.new_account () in - let new_contract = Contract.implicit_contract new_account.pkh in - Op.transaction (B genesis) contract2 new_contract delegated_amount - >>=? fun transfer -> - Block.bake ~operation:transfer genesis >>=? fun b -> - Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> - Block.bake ~operation:delegation b >>=? fun b -> - Block.bake_until_cycle_end b >>=? fun b -> - (* After 1 cycle, namely, at cycle 2, [account1] transfers all its spendable - balance. *) - Context.Contract.balance (B b) contract1 >>=? fun balance1 -> - Op.transaction (B b) contract1 contract2 balance1 >>=? fun operation -> - Block.bake ~operation b >>=? fun b -> - Block.bake_until_n_cycle_end constants.preserved_cycles b >>=? fun _ -> - (* By this time, after [preserved_cycles] passed after [account1] has emptied - its spendable balance, because [account1] had a big staking balance at - cycle 0, at this cycle it has a big active stake, and so its - [maximum_stake_to_be_deposited] too is bigger than [frozen_deposits.current_amount], - so the variable [to_freeze] in [freeze_deposits] is positive. - Because the spendable balance of [account1] is 0, an error "Underflowing - subtraction" is raised at the end of the cycle when updating the balance by - subtracting [to_freeze] in [freeze_deposits]. - Note that by taking [to_cycle] is [new_cycle + preserved_cycles], - [frozen_deposits.current_amount] can no longer be smaller - than [maximum_stake_to_be_deposited], that is, the invariant - maximum_stake_to_be_deposited <= frozen_deposits + balance is preserved. - *) - return_unit - -let tests = - Tztest. - [ - tztest "test invariants" `Quick test_invariants; - tztest "set deposits limit to 0%" `Quick (test_set_limit 0); - tztest "set deposits limit to 5%" `Quick (test_set_limit 5); - tztest - "cannot bake with zero deposits" - `Quick - test_cannot_bake_with_zero_deposits; - tztest - "deposits after stake removal" - `Quick - test_deposits_after_stake_removal; - tztest - "unfreeze deposits after deactivation" - `Quick - test_unfreeze_deposits_after_deactivation; - tztest - "frozen deposits with delegation" - `Quick - test_frozen_deposits_with_delegation; - tztest - "test frozen deposits with overdelegation" - `Quick - test_frozen_deposits_with_overdelegation; - tztest - "test set limit with overdelegation" - `Quick - test_set_limit_with_overdelegation; - tztest - "test error is thrown when the frozen window is smaller" - `Quick - test_error_is_thrown_when_smaller_upper_bound_for_frozen_window; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_gas_costs.ml b/src/proto_012_Psithaca/lib_protocol/test/test_gas_costs.ml deleted file mode 100644 index b2ff11874743..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_gas_costs.ml +++ /dev/null @@ -1,289 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (gas costs) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^gas cost functions$" - Subject: Gas costs - Current limitations: for maps, sets & compare, we only test - integer comparable keys. -*) - -open Protocol -module S = Saturation_repr - -let dummy_list = Script_list.(cons 42 empty) - -let forty_two = Alpha_context.Script_int.of_int 42 - -let forty_two_n = Alpha_context.Script_int.abs forty_two - -let dummy_set = - let open Script_set in - update forty_two true (empty Script_typed_ir.(int_key ~annot:None)) - -let dummy_map = - let open Script_map in - update - forty_two - (Some forty_two) - (empty Script_typed_ir.(int_key ~annot:None)) - -let dummy_timestamp = Alpha_context.Script_timestamp.of_zint (Z.of_int 42) - -let dummy_pk = - Signature.Public_key.of_b58check_exn - "edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU" - -let dummy_bytes = Bytes.of_string "dummy" - -let dummy_string = - match Alpha_context.Script_string.of_string "dummy" with - | Ok s -> s - | Error _ -> assert false - -let dummy_ty = Script_typed_ir.never_t ~annot:None - -let free = ["balance"; "bool"; "parsing_unit"; "unparsing_unit"] - -(* /!\ The compiler will only complain if costs are _removed_ /!\*) -let all_interpreter_costs = - let open Michelson_v1_gas.Cost_of.Interpreter in - [ - ("drop", drop); - ("dup", dup); - ("swap", swap); - ("cons_some", cons_some); - ("cons_none", cons_none); - ("if_none", if_none); - ("cons_pair", cons_pair); - ("car", car); - ("cdr", cdr); - ("cons_left", cons_left); - ("cons_right", cons_right); - ("if_left", if_left); - ("cons_list", cons_list); - ("nil", nil); - ("if_cons", if_cons); - ("list_map", list_map dummy_list); - ("list_size", list_size); - ("list_iter", list_iter dummy_list); - ("empty_set", empty_set); - ("set_iter", set_iter dummy_set); - ("set_mem", set_mem forty_two dummy_set); - ("set_update", set_update forty_two dummy_set); - ("set_size", set_size); - ("empty_map", empty_map); - ("map_map", map_map dummy_map); - ("map_iter", map_iter dummy_map); - ("map_mem", map_mem forty_two dummy_map); - ("map_get", map_get forty_two dummy_map); - ("map_update", map_update forty_two dummy_map); - ("map_size", map_size); - ("add_seconds_timestamp", add_seconds_timestamp forty_two dummy_timestamp); - ("sub_timestamp_seconds", sub_timestamp_seconds dummy_timestamp forty_two); - ("diff_timestamps", diff_timestamps dummy_timestamp dummy_timestamp); - ("concat_string_pair", concat_string_pair dummy_string dummy_string); - ("slice_string", slice_string dummy_string); - ("string_size", string_size); - ("concat_bytes_pair", concat_bytes_pair dummy_bytes dummy_bytes); - ("slice_bytes", slice_bytes dummy_bytes); - ("bytes_size", bytes_size); - ("add_tez", add_tez); - ("sub_tez", sub_tez); - ("mul_teznat", mul_teznat); - ("bool_or", bool_or); - ("bool_and", bool_and); - ("bool_xor", bool_xor); - ("bool_not", bool_not); - ("is_nat", is_nat); - ("abs_int", abs_int forty_two); - ("int_nat", int_nat); - ("neg", neg forty_two); - ("add_int", add_int forty_two forty_two); - ("sub_int", sub_int forty_two forty_two); - ("mul_int", mul_int forty_two forty_two); - ("ediv_teznat", ediv_teznat Alpha_context.Tez.fifty_cents forty_two); - ("ediv_tez", ediv_tez); - ("ediv_int", ediv_int forty_two (Alpha_context.Script_int.of_int 1)); - ("eq", eq); - ("lsl_nat", lsl_nat forty_two); - ("lsr_nat", lsr_nat forty_two); - ("or_nat", or_nat forty_two forty_two); - ("and_nat", and_nat forty_two forty_two); - ("xor_nat", xor_nat forty_two forty_two); - ("not_int", not_int forty_two); - ("if_", if_); - ("loop", loop); - ("loop_left", loop_left); - ("dip", dip); - ("check_signature", check_signature dummy_pk dummy_bytes); - ("blake2b", blake2b dummy_bytes); - ("sha256", sha256 dummy_bytes); - ("sha512", sha512 dummy_bytes); - ("dign", dign 42); - ("dugn", dugn 42); - ("dipn", dipn 42); - ("dropn", dropn 42); - ("neq", neq); - ( "compare", - compare Script_typed_ir.(int_key ~annot:None) forty_two forty_two ); - ( "concat_string_precheck", - concat_string_precheck Script_list.(cons "42" empty) ); - ("concat_string", concat_string (S.safe_int 42)); - ("concat_bytes", concat_bytes (S.safe_int 42)); - ("exec", exec); - ("apply", apply); - ("lambda", lambda); - ("address", address); - ("contract", contract); - ("transfer_tokens", transfer_tokens); - ("implicit_account", implicit_account); - ("create_contract", create_contract); - ("set_delegate", set_delegate); - (* balance is free *) - ("balance", balance); - ("level", level); - ("now", now); - ("hash_key", hash_key dummy_pk); - ("source", source); - ("sender", sender); - ("self", self); - ("self_address", self_address); - ("amount", amount); - ("chain_id", chain_id); - ("unpack_failed", unpack_failed "dummy"); - ] - -(* /!\ The compiler will only complain if costs are _removed_ /!\*) -let all_parsing_costs = - let open Michelson_v1_gas.Cost_of.Typechecking in - [ - ("public_key_optimized", public_key_optimized); - ("public_key_readable", public_key_readable); - ("key_hash_optimized", key_hash_optimized); - ("key_hash_readable", key_hash_readable); - ("signature_optimized", signature_optimized); - ("signature_readable", signature_readable); - ("chain_id_optimized", chain_id_optimized); - ("chain_id_readable", chain_id_readable); - ("address_optimized", address_optimized); - ("contract_optimized", contract_optimized); - ("contract_readable", contract_readable); - ("check_printable", check_printable "dummy"); - ("merge_cycle", merge_cycle); - ("parse_type_cycle", parse_type_cycle); - ("parse_instr_cycle", parse_instr_cycle); - ("parse_data_cycle", parse_data_cycle); - ("bool", bool); - ("parsing_unit", unit); - ("timestamp_readable", timestamp_readable); - ("contract", contract); - ("contract_exists", contract_exists); - ("proof_argument", proof_argument 42); - ] - -(* /!\ The compiler will only complain if costs are _removed_ /!\*) -let all_unparsing_costs = - let open Michelson_v1_gas.Cost_of.Unparsing in - [ - ("public_key_optimized", public_key_optimized); - ("public_key_readable", public_key_readable); - ("key_hash_optimized", key_hash_optimized); - ("key_hash_readable", key_hash_readable); - ("signature_optimized", signature_optimized); - ("signature_readable", signature_readable); - ("chain_id_optimized", chain_id_optimized); - ("chain_id_readable", chain_id_readable); - ("timestamp_readable", timestamp_readable); - ("address_optimized", address_optimized); - ("contract_optimized", contract_optimized); - ("contract_readable", contract_readable); - ("unparse_type", unparse_type dummy_ty); - ("unparse_instr_cycle", unparse_instr_cycle); - ("unparse_data_cycle", unparse_data_cycle); - ("unparsing_unit", unit); - ("contract", contract); - ("operation", operation dummy_bytes); - ] - -(* /!\ The compiler will only complain if costs are _removed_ /!\*) -let all_io_costs = - let open Storage_costs in - [ - ("read_access 0 0", read_access ~path_length:0 ~read_bytes:0); - ("read_access 1 0", read_access ~path_length:1 ~read_bytes:0); - ("read_access 0 1", read_access ~path_length:0 ~read_bytes:1); - ("read_access 1 1", read_access ~path_length:1 ~read_bytes:1); - ("write_access 0", write_access ~written_bytes:0); - ("write_access 1", write_access ~written_bytes:1); - ] - -(* Here we're using knowledge of the internal representation of costs to - cast them to S ... *) -let cast_cost_to_s (c : Alpha_context.Gas.cost) : _ S.t = - Data_encoding.Binary.to_bytes_exn Alpha_context.Gas.cost_encoding c - |> Data_encoding.Binary.of_bytes_exn S.n_encoding - -(** Checks that all costs are positive values. *) -let test_cost_reprs_are_all_positive list () = - List.iter_es - (fun (cost_name, cost) -> - if S.(cost > S.zero) then return_unit - else if S.equal cost S.zero && List.mem ~equal:String.equal cost_name free - then return_unit - else - fail - (Exn - (Failure (Format.asprintf "Gas cost test \"%s\" failed" cost_name)))) - list - -(** Checks that all costs are positive values. *) -let test_costs_are_all_positive list () = - let list = - List.map (fun (cost_name, cost) -> (cost_name, cast_cost_to_s cost)) list - in - test_cost_reprs_are_all_positive list () - -let tests = - [ - Tztest.tztest - "Positivity of interpreter costs" - `Quick - (test_costs_are_all_positive all_interpreter_costs); - Tztest.tztest - "Positivity of typechecking costs" - `Quick - (test_costs_are_all_positive all_parsing_costs); - Tztest.tztest - "Positivity of unparsing costs" - `Quick - (test_costs_are_all_positive all_unparsing_costs); - Tztest.tztest - "Positivity of io costs" - `Quick - (test_cost_reprs_are_all_positive all_io_costs); - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_gas_levels.ml b/src/proto_012_Psithaca/lib_protocol/test/test_gas_levels.ml deleted file mode 100644 index a19c1476d1d5..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_gas_levels.ml +++ /dev/null @@ -1,481 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (Gas levels) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^gas levels$" - Subject: On gas consumption and exhaustion. -*) - -open Protocol -open Raw_context -module S = Saturation_repr - -(* This value is supposed to be larger than the block gas level limit - but not saturated. *) -let opg = max_int / 10000 - -exception Gas_levels_test_error of string - -let err x = Exn (Gas_levels_test_error x) - -let succeed x = match x with Ok _ -> true | _ -> false - -let failed x = not (succeed x) - -let dummy_context () = - Context.init ~consensus_threshold:0 1 >>=? fun (block, _) -> - Raw_context.prepare - ~level:Int32.zero - ~predecessor_timestamp:Time.Protocol.epoch - ~timestamp:Time.Protocol.epoch - (* ~fitness:[] *) - (block.context : Environment_context.Context.t) - >|= Environment.wrap_tzresult - -let consume_gas_lwt context gas = - Lwt.return (consume_gas context (S.safe_int gas)) - >|= Environment.wrap_tzresult - -let consume_gas_limit_in_block_lwt context gas = - Lwt.return (consume_gas_limit_in_block context gas) - >|= Environment.wrap_tzresult - -let test_detect_gas_exhaustion_in_fresh_context () = - dummy_context () >>=? fun context -> - fail_unless - (consume_gas context (S.safe_int opg) |> succeed) - (err "In a fresh context, gas consumption is unlimited.") - -(** Create a context with a given block gas level, capped at the - hard gas limit per block *) -let make_context remaining_block_gas = - let open Gas_limit_repr in - dummy_context () >>=? fun context -> - let hard_limit = Arith.fp (constants context).hard_gas_limit_per_operation in - let hard_limit_block = - Arith.fp (constants context).hard_gas_limit_per_block - in - let block_gas = Arith.(unsafe_fp (Z.of_int remaining_block_gas)) in - let rec aux context to_consume = - (* Because of saturated arithmetic, [to_consume] should never be negative. *) - assert (Arith.(to_consume >= zero)) ; - if Arith.(to_consume = zero) then return context - else if Arith.(to_consume <= hard_limit) then - consume_gas_limit_in_block_lwt context to_consume - else - consume_gas_limit_in_block_lwt context hard_limit >>=? fun context -> - aux context (Arith.sub to_consume hard_limit) - in - aux context Arith.(sub hard_limit_block block_gas) - -(** Test operation gas exhaustion. Should pass when remaining gas is 0, - and fail when it goes over *) -let test_detect_gas_exhaustion_when_operation_gas_hits_zero () = - let gas_op = 100000 in - dummy_context () >>=? fun context -> - set_gas_limit context (Gas_limit_repr.Arith.unsafe_fp (Z.of_int gas_op)) - |> fun context -> - fail_unless - (consume_gas context (S.safe_int gas_op) |> succeed) - (err "Succeed when consuming exactly the remaining operation gas.") - >>=? fun () -> - fail_unless - (consume_gas context (S.safe_int (gas_op + 1)) |> failed) - (err "Fail when consuming more than the remaining operation gas.") - -(** Test block gas exhaustion *) -let test_detect_gas_exhaustion_when_block_gas_hits_zero () = - let gas k = Gas_limit_repr.Arith.unsafe_fp (Z.of_int k) in - let remaining_gas = gas 100000 and too_much = gas (100000 + 1) in - make_context 100000 >>=? fun context -> - fail_unless - (consume_gas_limit_in_block context remaining_gas |> succeed) - (err "Succeed when consuming exactly the remaining block gas.") - >>=? fun () -> - fail_unless - (consume_gas_limit_in_block context too_much |> failed) - (err "Fail when consuming more than the remaining block gas.") - -(** Test invalid gas limit. Should fail when limit is above the hard gas limit per - operation *) -let test_detect_gas_limit_consumption_above_hard_gas_operation_limit () = - dummy_context () >>=? fun context -> - fail_unless - (consume_gas_limit_in_block - context - (Gas_limit_repr.Arith.unsafe_fp (Z.of_int opg)) - |> failed) - (err - "Fail when consuming gas above the hard limit per operation in the \ - block.") - -(** For a given [context], check if its levels match those given in [block_level] and - [operation_level] *) -let check_context_levels context block_level operation_level = - let op_check = - match gas_level context with - | Unaccounted -> true - | Limited {remaining} -> - Gas_limit_repr.Arith.(unsafe_fp (Z.of_int operation_level) = remaining) - in - let block_check = - Gas_limit_repr.Arith.( - unsafe_fp (Z.of_int block_level) = block_gas_level context) - in - fail_unless - (op_check || block_check) - (err "Unexpected block and operation gas levels") - >>=? fun () -> - fail_unless op_check (err "Unexpected operation gas level") >>=? fun () -> - fail_unless block_check (err "Unexpected block gas level") - -let monitor remaining_block_gas initial_operation_level consumed_gas () = - let op_limit = - Gas_limit_repr.Arith.unsafe_fp (Z.of_int initial_operation_level) - in - make_context remaining_block_gas >>=? fun context -> - consume_gas_limit_in_block_lwt context op_limit >>=? fun context -> - set_gas_limit context op_limit |> fun context -> - consume_gas_lwt context consumed_gas >>=? fun context -> - check_context_levels - context - (remaining_block_gas - initial_operation_level) - (initial_operation_level - consumed_gas) - -let test_monitor_gas_level = monitor 1000 100 10 - -(** Test cas consumption mode switching (limited -> unlimited) *) -let test_set_gas_unlimited () = - let init_block_gas = 100000 in - let op_limit_int = 10000 in - let op_limit = Gas_limit_repr.Arith.unsafe_fp (Z.of_int op_limit_int) in - make_context init_block_gas >>=? fun context -> - set_gas_limit context op_limit |> set_gas_unlimited |> fun context -> - consume_gas_lwt context opg >>=? fun context -> - check_context_levels context init_block_gas (-1) - -(** Test cas consumption mode switching (unlimited -> limited) *) -let test_set_gas_limited () = - let init_block_gas = 100000 in - let op_limit_int = 10000 in - let op_limit = Gas_limit_repr.Arith.unsafe_fp (Z.of_int op_limit_int) in - let op_gas = 100 in - make_context init_block_gas >>=? fun context -> - set_gas_unlimited context |> fun context -> - set_gas_limit context op_limit |> fun context -> - consume_gas_lwt context op_gas >>=? fun context -> - check_context_levels context init_block_gas (op_limit_int - op_gas) - -(*** Tests with blocks ***) - -let apply_with_gas header ?(operations = []) (pred : Block.t) = - let open Alpha_context in - (let open Environment.Error_monad in - begin_application - ~chain_id:Chain_id.zero - ~predecessor_context:pred.context - ~predecessor_fitness:pred.header.shell.fitness - ~predecessor_timestamp:pred.header.shell.timestamp - header - >>=? fun vstate -> - List.fold_left_es - (fun vstate op -> - apply_operation vstate op >|=? fun (state, _result) -> state) - vstate - operations - >>=? fun vstate -> - finalize_block vstate (Some header.shell) >|=? fun (validation, result) -> - (validation.context, result.consumed_gas)) - >|= Environment.wrap_tzresult - >|=? fun (context, consumed_gas) -> - let hash = Block_header.hash header in - ({Block.hash; header; operations; context}, consumed_gas) - -let bake_with_gas ?policy ?timestamp ?operation ?operations pred = - let operations = - match (operation, operations) with - | (Some op, Some ops) -> Some (op :: ops) - | (Some op, None) -> Some [op] - | (None, Some ops) -> Some ops - | (None, None) -> None - in - Block.Forge.forge_header ?timestamp ?policy ?operations pred - >>=? fun header -> - Block.Forge.sign_header header >>=? fun header -> - apply_with_gas header ?operations pred - -let check_consumed_gas consumed expected = - fail_unless - Alpha_context.Gas.Arith.(consumed = expected) - (err - (Format.asprintf - "Gas discrepancy: consumed gas : %a | expected : %a\n" - Alpha_context.Gas.Arith.pp - consumed - Alpha_context.Gas.Arith.pp - expected)) - -let lazy_unit = Alpha_context.Script.lazy_expr (Expr.from_string "Unit") - -let prepare_origination block source script = - let code = Expr.toplevel_from_string script in - let script = - Alpha_context.Script.{code = lazy_expr code; storage = lazy_unit} - in - Op.origination (B block) source ~script - -let originate_contract block source script = - prepare_origination block source script >>=? fun (operation, dst) -> - Block.bake ~operation block >>=? fun block -> return (block, dst) - -let init_block to_originate = - Context.init ~consensus_threshold:0 1 >>=? fun (block, contracts) -> - let src = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - (*** originate contracts ***) - let rec full_originate block originated = function - | [] -> return (block, List.rev originated) - | h :: t -> - originate_contract block src h >>=? fun (block, ct) -> - full_originate block (ct :: originated) t - in - full_originate block [] to_originate >>=? fun (block, originated) -> - return (block, src, originated) - -let nil_contract = - "parameter unit;\n\ - storage unit;\n\ - code {\n\ - \ DROP;\n\ - \ UNIT; NIL operation; PAIR\n\ - \ }\n" - -let fail_contract = "parameter unit; storage unit; code { FAIL }" - -let loop_contract = - "parameter unit;\n\ - storage unit;\n\ - code {\n\ - \ DROP;\n\ - \ PUSH bool True;\n\ - \ LOOP {\n\ - \ PUSH string \"GASGASGAS\";\n\ - \ PACK;\n\ - \ SHA3;\n\ - \ DROP;\n\ - \ PUSH bool True\n\ - \ };\n\ - \ UNIT; NIL operation; PAIR\n\ - \ }\n" - -let block_with_one_origination contract = - init_block [contract] >>=? fun (block, src, originated) -> - match originated with [dst] -> return (block, src, dst) | _ -> assert false - -let full_block () = - init_block [nil_contract; fail_contract; loop_contract] - >>=? fun (block, src, originated) -> - let (dst_nil, dst_fail, dst_loop) = - match originated with [c1; c2; c3] -> (c1, c2, c3) | _ -> assert false - in - return (block, src, dst_nil, dst_fail, dst_loop) - -(** Combine a list of operations into an operation list. Also returns - the sum of their gas limits.*) -let combine_operations_with_gas ?counter block src list_dst = - let rec make_op_list full_gas op_list = function - | [] -> return (full_gas, List.rev op_list) - | (dst, gas_limit) :: t -> - Op.transaction ~gas_limit (B block) src dst Alpha_context.Tez.zero - >>=? fun op -> - make_op_list - (Alpha_context.Gas.Arith.add full_gas gas_limit) - (op :: op_list) - t - in - make_op_list Alpha_context.Gas.Arith.zero [] list_dst - >>=? fun (full_gas, op_list) -> - Op.combine_operations ?counter ~source:src (B block) op_list - >>=? fun operation -> return (operation, full_gas) - -(** Applies [combine_operations_with_gas] to lists in a list, then bake a block - with this list of operations. Also returns the sum of all gas limits *) -let bake_operations_with_gas ?counter block src list_list_dst = - let counter = Option.value ~default:Z.zero counter in - let rec make_list full_gas op_list counter = function - | [] -> return (full_gas, List.rev op_list) - | list_dst :: t -> - let n = Z.of_int (List.length list_dst) in - combine_operations_with_gas ~counter block src list_dst - >>=? fun (op, gas) -> - make_list - (Alpha_context.Gas.Arith.add full_gas gas) - (op :: op_list) - (Z.add counter n) - t - in - make_list Alpha_context.Gas.Arith.zero [] counter list_list_dst - >>=? fun (gas_limit_total, operations) -> - bake_with_gas ~operations block >>=? fun (block, consumed_gas) -> - return (block, consumed_gas, gas_limit_total) - -let basic_gas_sampler () = - Alpha_context.Gas.Arith.integral_of_int_exn (100 + Random.int 900) - -let generic_test_block_one_origination contract gas_sampler structure = - block_with_one_origination contract >>=? fun (block, src, dst) -> - let lld = List.map (List.map (fun _ -> (dst, gas_sampler ()))) structure in - bake_operations_with_gas ~counter:Z.one block src lld - >>=? fun (_block, consumed_gas, gas_limit_total) -> - check_consumed_gas consumed_gas gas_limit_total - -let make_batch_test_block_one_origination name contract gas_sampler = - let test = generic_test_block_one_origination contract gas_sampler in - let test_one_operation () = test [[()]] in - let test_one_operation_list () = test [[(); (); ()]] in - let test_many_single_operations () = test [[()]; [()]; [()]] in - let test_mixed_operations () = test [[(); ()]; [()]; [(); (); ()]] in - let app_n = List.map (fun (x, y) -> (x ^ " with contract " ^ name, y)) in - app_n - [ - ("Test bake one operation", test_one_operation); - ("Test bake one operation list", test_one_operation_list); - ("Test multiple single operations", test_many_single_operations); - ("Test both lists and single operations", test_mixed_operations); - ] - -(** Tests the consumption of all gas in a block, should pass *) -let test_consume_exactly_all_block_gas () = - block_with_one_origination nil_contract >>=? fun (block, src, dst) -> - (* assumptions: - hard gas limit per operation = 1040000 - hard gas limit per block = 5200000 - *) - let lld = - List.map - (fun _ -> [(dst, Alpha_context.Gas.Arith.integral_of_int_exn 1040000)]) - [1; 1; 1; 1; 1] - in - bake_operations_with_gas ~counter:Z.one block src lld >>=? fun _ -> return () - -(** Tests the consumption of more than the block gas level with many single - operations, should fail *) -let test_malformed_block_max_limit_reached () = - block_with_one_origination nil_contract >>=? fun (block, src, dst) -> - (* assumptions: - hard gas limit per operation = 1040000 - hard gas limit per block = 5200000 - *) - let lld = - [(dst, Alpha_context.Gas.Arith.integral_of_int_exn 1)] - :: - List.map - (fun _ -> [(dst, Alpha_context.Gas.Arith.integral_of_int_exn 1040000)]) - [1; 1; 1; 1; 1] - in - bake_operations_with_gas ~counter:Z.one block src lld >>= function - | Error _ -> return_unit - | Ok _ -> - fail - (err - "Invalid block: sum of operation gas limits exceeds hard gas limit \ - per block") - -(** Tests the consumption of more than the block gas level with one big - operation list, should fail *) -let test_malformed_block_max_limit_reached' () = - block_with_one_origination nil_contract >>=? fun (block, src, dst) -> - (* assumptions: - hard gas limit per operation = 1040000 - hard gas limit per block = 5200000 - *) - let lld = - [ - (dst, Alpha_context.Gas.Arith.integral_of_int_exn 1) - :: - List.map - (fun _ -> (dst, Alpha_context.Gas.Arith.integral_of_int_exn 1040000)) - [1; 1; 1; 1; 1]; - ] - in - bake_operations_with_gas ~counter:Z.one block src lld >>= function - | Error _ -> return_unit - | Ok _ -> - fail - (err - "Invalid block: sum of gas limits in operation list exceeds hard \ - gas limit per block") - -let test_block_mixed_operations () = - full_block () >>=? fun (block, src, dst_nil, dst_fail, dst_loop) -> - let l = [[dst_nil]; [dst_nil; dst_fail; dst_nil]; [dst_loop]; [dst_nil]] in - let lld = List.map (List.map (fun x -> (x, basic_gas_sampler ()))) l in - bake_operations_with_gas ~counter:(Z.of_int 3) block src lld - >>=? fun (_block, consumed_gas, gas_limit_total) -> - check_consumed_gas consumed_gas gas_limit_total - -let quick (what, how) = Tztest.tztest what `Quick how - -let tests = - List.map - quick - ([ - ( "Detect gas exhaustion in fresh context", - test_detect_gas_exhaustion_in_fresh_context ); - ( "Detect gas exhaustion when operation gas as hits zero", - test_detect_gas_exhaustion_when_operation_gas_hits_zero ); - ( "Detect gas exhaustion when block gas as hits zero", - test_detect_gas_exhaustion_when_block_gas_hits_zero ); - ( "Detect gas limit consumption when it is above the hard gas operation \ - limit", - test_detect_gas_limit_consumption_above_hard_gas_operation_limit ); - ( "Each new operation impacts block gas level, each gas consumption \ - impacts operation gas level", - test_monitor_gas_level ); - ( "Switches operation gas consumption from limited to unlimited", - test_set_gas_unlimited ); - ( "Switches operation gas consumption from unlimited to limited", - test_set_gas_limited ); - ( "Accepts a block that consumes all of its gas", - test_consume_exactly_all_block_gas ); - ( "Detect when the sum of all operation gas limits exceeds the hard gas \ - limit per block", - test_malformed_block_max_limit_reached ); - ( "Detect when gas limit of operation list exceeds the hard gas limit \ - per block", - test_malformed_block_max_limit_reached' ); - ( "Test the gas consumption of various operations", - test_block_mixed_operations ); - ] - @ make_batch_test_block_one_origination "nil" nil_contract basic_gas_sampler - @ make_batch_test_block_one_origination - "fail" - fail_contract - basic_gas_sampler - @ make_batch_test_block_one_origination - "infinite loop" - loop_contract - basic_gas_sampler) diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_gas_properties.ml b/src/proto_012_Psithaca/lib_protocol/test/test_gas_properties.ml deleted file mode 100644 index 9e0c1a32c05d..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_gas_properties.ml +++ /dev/null @@ -1,139 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (gas properties) - Invocation: dune exec src/proto_alpha/lib_protocol/test/test_gas_properties.exe - Subject: Arithmetic properties around gas. -*) - -open Protocol -open Lib_test.Qcheck_helpers - -(** Extract a Tezos result for compatibility with QCheck. *) -let extract_qcheck_result = function - | Ok pure_result -> pure_result - | Error err -> - Format.printf "@\n%a@." Environment.Error_monad.pp_trace err ; - false - -(** [Gas.free] is the neutral element of gas addition: [any_cost +@ Gas.free = Gas.free +@ any_cost = any_cost]. *) -let test_free_neutral (start, any_cost) = - let open Alpha_context in - extract_qcheck_result - ( Gas.consume start Gas.free >>? fun free_first -> - Gas.consume free_first any_cost >>? fun branch1 -> - Gas.consume start any_cost >>? fun cost_first -> - Gas.consume cost_first Gas.free >|? fun branch2 -> - let equal_consumption_from_start t1 t2 = - Gas.Arith.( - qcheck_eq - ~pp - ~eq:equal - (Gas.consumed ~since:start ~until:t1) - (Gas.consumed ~since:start ~until:t2)) - in - equal_consumption_from_start branch1 branch2 - && equal_consumption_from_start branch1 cost_first ) - -(** Consuming [Gas.free] is equivalent to consuming nothing. *) -let test_free_consumption start = - let open Alpha_context in - extract_qcheck_result - ( Gas.consume start Gas.free >|? fun after_empty_consumption -> - Gas.Arith.( - qcheck_eq - ~pp - ~eq:equal - (Gas.consumed ~since:start ~until:after_empty_consumption) - zero) ) - -(** Consuming [cost1] then [cost2] is equivalent to consuming - [Gas.(cost1 +@ cost2)]. *) -let test_consume_commutes (start, cost1, cost2) = - let open Alpha_context in - extract_qcheck_result - ( Gas.consume start cost1 >>? fun after_cost1 -> - Gas.consume after_cost1 cost2 >>? fun branch1 -> - Gas.consume start Gas.(cost1 +@ cost2) >|? fun branch2 -> - Gas.Arith.( - qcheck_eq - ~pp - ~eq:equal - (Gas.consumed ~since:start ~until:branch1) - (Gas.consumed ~since:start ~until:branch2)) ) - -(** Arbitrary context with a gas limit of 100_000_000. *) -let context_arb : Alpha_context.t QCheck.arbitrary = - QCheck.always - (Lwt_main.run - ( Context.init 1 >>=? fun (b, _contracts) -> - Incremental.begin_construction b >|=? fun inc -> - let state = Incremental.validation_state inc in - Alpha_context.Gas.set_limit - state.ctxt - Alpha_context.Gas.Arith.(fp (integral_of_int_exn 100_000_000)) ) - |> function - | Ok a -> a - | Error _ -> assert false) - -(** This arbitrary could be improved (pretty printer and shrinker) if there was a way to convert a [cost] back to an [int]. Otherwise one needs to write a custom [arbitrary] instance, but I wanted to stick to the former design of this test for the time being. *) -let gas_cost_arb : Alpha_context.Gas.cost QCheck.arbitrary = - let open Alpha_context.Gas in - let open QCheck in - let rand = 0 -- 1000 in - let safe_rand = map Saturation_repr.safe_int rand in - choose - [ - map atomic_step_cost safe_rand; - map step_cost safe_rand; - map alloc_cost safe_rand; - map alloc_bytes_cost rand; - map alloc_mbytes_cost rand; - map read_bytes_cost rand; - map write_bytes_cost rand; - ] - -let tests = - [ - QCheck.Test.make - ~count:1000 - ~name:"Consuming commutes" - QCheck.(triple context_arb gas_cost_arb gas_cost_arb) - test_consume_commutes; - QCheck.Test.make - ~count:1000 - ~name:"Consuming [free] consumes nothing" - context_arb - test_free_consumption; - QCheck.Test.make - ~count:1000 - ~name:"[free] is the neutral element of Gas addition" - QCheck.(pair context_arb gas_cost_arb) - test_free_neutral; - ] - -let () = Alcotest.run "gas properties" [("gas properties", qcheck_wrap tests)] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_global_constants_storage.ml b/src/proto_012_Psithaca/lib_protocol/test/test_global_constants_storage.ml deleted file mode 100644 index e9c1f74cefc7..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_global_constants_storage.ml +++ /dev/null @@ -1,138 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) -open Protocol -open Alpha_context -open Test_transfer - -(** Testing - ------- - Component: Protocol (global table of constants) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ - -- test "^global table of constants$" - Subject: This module tests that the global table of constants - can be written to and read from across blocks. -*) - -let get_next_context b = - Incremental.begin_construction b >>=? fun b -> - return (Incremental.alpha_ctxt b) - -let assert_expr_equal loc = - Assert.equal - ~loc - ( = ) - "Michelson Expressions Not Equal" - Michelson_v1_printer.print_expr - -let assert_proto_error_id loc id result = - let test err = - (Error_monad.find_info_of_error err).id - = "proto." ^ Protocol.name ^ "." ^ id - in - Assert.error ~loc result test - -let expr_to_hash expr = - let lexpr = Script_repr.lazy_expr @@ Expr.from_string expr in - Script_repr.force_bytes lexpr >|? fun b -> Script_expr_hash.hash_bytes [b] - -(* This test has a long wind-up, but is very simple: it just asserts - that values written to the global table of constants persist across - blocks. *) -let get_happy_path () = - register_two_contracts () >>=? fun (b, alice, bob) -> - Incremental.begin_construction b >>=? fun b -> - let expr_str = "Pair 3 7" in - let expr = Expr.from_string expr_str in - Environment.wrap_tzresult @@ expr_to_hash expr_str >>?= fun hash -> - Op.register_global_constant - (I b) - ~source:alice - ~value:(Script_repr.lazy_expr expr) - >>=? fun op -> - Incremental.add_operation b op >>=? fun b -> - Incremental.finalize_block b >>=? fun b -> - let assert_unchanged b = - get_next_context b >>=? fun context -> - Global_constants_storage.get context hash >|= Environment.wrap_tzresult - >>=? fun (_, result_expr) -> - assert_expr_equal __LOC__ expr result_expr >|=? fun _ -> b - in - assert_unchanged b >>=? fun b -> - let do_many_transfers b = - Incremental.begin_construction b >>=? fun b -> - n_transactions 10 b alice bob (Tez.of_mutez_exn 1000L) >>=? fun b -> - Incremental.finalize_block b >>=? fun b -> assert_unchanged b - in - do_many_transfers b >>=? do_many_transfers >>=? do_many_transfers >>= fun _ -> - Lwt.return_ok () - -(* Blocks that include a registration of a bad expression should - fail. *) -let test_registration_of_bad_expr_fails () = - register_two_contracts () >>=? fun (b, alice, _) -> - Incremental.begin_construction b >>=? fun b -> - (* To produce the failure, we attempt to register an expression with - a malformed hash. *) - let expr = Expr.from_string "Pair 1 (constant \"foo\")" in - Op.register_global_constant - (I b) - ~source:alice - ~value:(Script_repr.lazy_expr expr) - >>=? fun op -> - Incremental.add_operation b op - >>= assert_proto_error_id __LOC__ "Badly_formed_constant_expression" - -(* You cannot register the same expression twice. *) -let test_no_double_register () = - register_two_contracts () >>=? fun (b, alice, _) -> - Incremental.begin_construction b >>=? fun b -> - let expr = Expr.from_string "Pair 1 2" in - Op.register_global_constant - (I b) - ~source:alice - ~value:(Script_repr.lazy_expr expr) - >>=? fun op -> - Incremental.add_operation b op >>=? fun b -> - (* Register the same expression again *) - Op.register_global_constant - (I b) - ~source:alice - ~value:(Script_repr.lazy_expr expr) - >>=? fun op -> - Incremental.add_operation b op - >>= assert_proto_error_id __LOC__ "Expression_already_registered" - -let tests = - [ - Tztest.tztest "Multiple blocks happy path" `Quick get_happy_path; - Tztest.tztest - "Bad register global operations fail when added to the block" - `Quick - test_registration_of_bad_expr_fails; - Tztest.tztest - "You cannot register the same expression twice." - `Quick - test_no_double_register; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_helpers_rpcs.ml b/src/proto_012_Psithaca/lib_protocol/test/test_helpers_rpcs.ml deleted file mode 100644 index 392da059c317..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_helpers_rpcs.ml +++ /dev/null @@ -1,69 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020-2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (Helpers RPCs) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^helpers rpcs$" - Subject: On RPCs. -*) - -open Protocol -open Alpha_context - -(* Test the baking_rights RPC. - Future levels or cycles are not tested because it's hard in this framework, - using only RPCs, to fabricate them. *) -let test_baking_rights () = - Context.init 2 >>=? fun (b, contracts) -> - let open Plugin.RPC.Baking_rights in - (* default max_round returns 65 results *) - get Block.rpc_ctxt b ~all:true >>=? fun rights -> - assert (Compare.List_length_with.(rights = 65)) ; - (* arbitrary max_round *) - let max_round = 15 in - get Block.rpc_ctxt b ~all:true ~max_round >>=? fun rights -> - assert (Compare.List_length_with.(rights = max_round + 1)) ; - (* filtering by delegate *) - let d = - Option.bind (List.nth contracts 0) Contract.is_implicit - |> WithExceptions.Option.get ~loc:__LOC__ - in - get Block.rpc_ctxt b ~all:true ~delegates:[d] >>=? fun rights -> - assert (List.for_all (fun {delegate; _} -> delegate = d) rights) ; - (* filtering by cycle *) - Plugin.RPC.current_level Block.rpc_ctxt b >>=? fun {cycle; _} -> - get Block.rpc_ctxt b ~all:true ~cycle >>=? fun rights -> - Plugin.RPC.levels_in_current_cycle Block.rpc_ctxt b >>=? fun (first, last) -> - assert ( - List.for_all (fun {level; _} -> level >= first && level <= last) rights) ; - (* filtering by level *) - Plugin.RPC.current_level Block.rpc_ctxt b >>=? fun {level; _} -> - get Block.rpc_ctxt b ~all:true ~levels:[level] >>=? fun rights -> - let expected_level = level in - assert (List.for_all (fun {level; _} -> level = expected_level) rights) ; - return_unit - -let tests = [Tztest.tztest "baking_rights" `Quick test_baking_rights] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_interpretation.ml b/src/proto_012_Psithaca/lib_protocol/test/test_interpretation.ml deleted file mode 100644 index 5fce6966082b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_interpretation.ml +++ /dev/null @@ -1,304 +0,0 @@ -(** Testing - ------- - Component: Protocol (interpretation) - Dependencies: src/proto_alpha/lib_protocol/script_interpreter.ml - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^interpretation$" - Subject: Interpretation of Michelson scripts -*) - -open Protocol -open Alpha_context -open Script_interpreter -open Error_monad_operators - -let test_context () = - Context.init 3 >>=? fun (b, _cs) -> - Incremental.begin_construction b >>=? fun v -> - return (Incremental.alpha_ctxt v) - -let logger = - Script_typed_ir. - { - log_interp = (fun _ _ _ _ _ -> ()); - log_entry = (fun _ _ _ _ _ -> ()); - log_exit = (fun _ _ _ _ _ -> ()); - log_control = (fun _ -> ()); - get_log = (fun () -> Lwt.return (Ok None)); - } - -let run_step ctxt code accu stack = - let open Script_interpreter in - let open Contract_helpers in - step None ctxt default_step_constants code accu stack - >>=? fun ((_, _, ctxt') as r) -> - step (Some logger) ctxt default_step_constants code accu stack - >>=? fun (_, _, ctxt'') -> - if Gas.(remaining_operation_gas ctxt' <> remaining_operation_gas ctxt'') then - Alcotest.failf "Logging should not have an impact on gas consumption." ; - return r - -(** Runs a script with an ill-typed parameter and verifies that a - Bad_contract_parameter error is returned. *) -let test_bad_contract_parameter () = - test_context () >>=? fun ctx -> - (* Run script with a parameter of wrong type *) - Contract_helpers.run_script - ctx - "{parameter unit; storage unit; code { CAR; NIL operation; PAIR }}" - ~storage:"Unit" - ~parameter:"0" - () - >>= function - | Ok _ -> Alcotest.fail "expected an error" - | Error (Environment.Ecoproto_error (Bad_contract_parameter source') :: _) -> - Alcotest.(check Testable.contract) - "incorrect field in Bad_contract_parameter" - Contract_helpers.default_source - source' ; - return_unit - | Error errs -> - Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs - -let test_multiplication_close_to_overflow_passes () = - test_context () >>=? fun ctx -> - (* Get sure that multiplication deals with numbers between 2^62 and - 2^63 without overflowing *) - Contract_helpers.run_script - ctx - "{parameter unit;storage unit;code {DROP; PUSH mutez 2944023901536524477; \ - PUSH nat 2; MUL; DROP; UNIT; NIL operation; PAIR}}" - ~storage:"Unit" - ~parameter:"Unit" - () - >>= function - | Ok _ -> return_unit - | Error errs -> - Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs - -let read_file filename = - let ch = open_in filename in - let s = really_input_string ch (in_channel_length ch) in - close_in ch ; - s - -(** The purpose of these two tests is to check that the Michelson interpreter is - stack-safe (because it is tail-recursive). - - This requires to confront it to deep recursions, typically deeper than what - the gas limit allows. Unfortunately we cannot run the interpreter in - unaccounted gas mode because for efficiency it uses a custom gas management - that represents the gas counter as a mere integer. Instead we set the gas - counter to the highest possible value ([Saturation_repr.saturated]); with - the current gas costs and limits this enables more than a million recursive - calls which is larger than the stack size. *) - -let test_stack_overflow () = - let open Script_typed_ir in - test_context () >>=? fun ctxt -> - (* Set the gas counter to the maximum value *) - let ctxt = - Gas.update_remaining_operation_gas ctxt Saturation_repr.saturated - in - let stack = Bot_t in - let descr kinstr = {kloc = 0; kbef = stack; kaft = stack; kinstr} in - let kinfo = {iloc = -1; kstack_ty = stack} in - let kinfo' = - {iloc = -1; kstack_ty = Item_t (bool_t ~annot:None, stack, None)} - in - let enorme_et_seq n = - let rec aux n acc = - if n = 0 then acc - else aux (n - 1) (IConst (kinfo, true, IDrop (kinfo', acc))) - in - aux n (IHalt kinfo) - in - run_step ctxt (descr (enorme_et_seq 1_000_000)) EmptyCell EmptyCell - >>= function - | Ok _ -> return_unit - | Error trace -> - let trace_string = - Format.asprintf "%a" Environment.Error_monad.pp_trace trace - in - Alcotest.failf "Unexpected error (%s) at %s" trace_string __LOC__ - -(** The stack-safety of the interpreter relies a lot on the stack-safety of - Lwt.bind. This second test is similar to the previous one but uses an - instruction (IBig_map_mem) for which the interpreter calls Lwt.bind. *) - -let test_stack_overflow_in_lwt () = - let open Script_typed_ir in - test_context () >>=? fun ctxt -> - let ctxt = - Gas.update_remaining_operation_gas ctxt Saturation_repr.saturated - in - let stack = Bot_t in - let item ty s = Item_t (ty, s, None) in - let unit_t = unit_t ~annot:None in - let unit_k = unit_key ~annot:None in - let bool_t = bool_t ~annot:None in - big_map_t (-1) unit_k unit_t ~annot:None >>??= fun big_map_t -> - let descr kinstr = {kloc = 0; kbef = stack; kaft = stack; kinstr} in - let kinfo s = {iloc = -1; kstack_ty = s} in - let stack1 = item big_map_t Bot_t in - let stack2 = item big_map_t (item big_map_t Bot_t) in - let stack3 = item unit_t stack2 in - let stack4 = item bool_t stack1 in - let push_empty_big_map k = IEmpty_big_map (kinfo stack, unit_k, unit_t, k) in - let large_mem_seq n = - let rec aux n acc = - if n = 0 then acc - else - aux - (n - 1) - (IDup - ( kinfo stack1, - IConst - ( kinfo stack2, - (), - IBig_map_mem (kinfo stack3, IDrop (kinfo stack4, acc)) ) )) - in - aux n (IDrop (kinfo stack1, IHalt (kinfo stack))) - in - let script = push_empty_big_map (large_mem_seq 1_000_000) in - run_step ctxt (descr script) EmptyCell EmptyCell >>= function - | Ok _ -> return_unit - | Error trace -> - let trace_string = - Format.asprintf "%a" Environment.Error_monad.pp_trace trace - in - Alcotest.failf "Unexpected error (%s) at %s" trace_string __LOC__ - -(** Test the encoding/decoding of script_interpreter.ml specific errors *) -let test_json_roundtrip name testable enc v = - let v' = - Data_encoding.Json.destruct enc (Data_encoding.Json.construct enc v) - in - Alcotest.check - testable - (Format.asprintf "round trip should not change value of %s" name) - v - v' ; - return_unit - -(** Encoding/decoding of script_interpreter.ml specific errors. *) -let test_json_roundtrip_err name e () = - test_json_roundtrip - name - Testable.protocol_error - Environment.Error_monad.error_encoding - e - -let error_encoding_tests = - let contract_zero = - Contract.implicit_contract Signature.Public_key_hash.zero - in - let script_expr_int = Micheline.strip_locations (Micheline.Int (0, Z.zero)) in - List.map - (fun (name, e) -> - Tztest.tztest - (Format.asprintf "test error encoding: %s" name) - `Quick - (test_json_roundtrip_err name e)) - [ - ("Reject", Reject (0, script_expr_int, None)); - ("Overflow", Overflow (0, None)); - ( "Runtime_contract_error", - Runtime_contract_error (contract_zero, script_expr_int) ); - ("Bad_contract_parameter", Bad_contract_parameter contract_zero); - ("Cannot_serialize_failure", Cannot_serialize_failure); - ("Cannot_serialize_storage", Cannot_serialize_storage); - ] - -module Test_map_instr_on_options = struct - type storage = {prev : int option; total : int} - - (* storage: (last input * total); param replaces the last input and - if some – gets added to the total. *) - let test_map_option_script = - {| { parameter (option int); - storage (pair (option int) int); - code { - UNPAIR ; - DIP { CDR } ; - MAP { - DUP ; - DIP { ADD } ; - } ; - PAIR ; - NIL operation ; - PAIR ; - } - } |} - - let run_test_map_opt_script param {prev; total} = - let storage = - Option.fold - ~none:(Format.sprintf "Pair None %d" total) - ~some:(fun p -> Format.sprintf "Pair (Some %d) %d" p total) - prev - in - let parameter = - Option.fold ~none:"None" ~some:(Format.sprintf "Some %d") param - in - test_context () >>=? fun ctxt -> - Contract_helpers.run_script - ctxt - test_map_option_script - ~storage - ~parameter - () - - let assume_storage_shape = - let open Micheline in - let open Michelson_v1_primitives in - function - | Prim (_, D_Pair, [Prim (_, D_None, [], _); Int (_, total)], _) -> - {prev = None; total = Z.to_int total} - | Prim (_, D_Pair, [Prim (_, D_Some, [Int (_, prev)], _); Int (_, total)], _) - -> - {prev = Some (Z.to_int prev); total = Z.to_int total} - | _ -> QCheck.assume_fail () - - let assertions storage_before storage_after = function - | None -> - Assert.is_none ~loc:__LOC__ ~pp:Format.pp_print_int storage_after.prev - >>=? fun () -> - Assert.equal_int ~loc:__LOC__ storage_before.total storage_after.total - | Some input -> - Assert.get_some ~loc:__LOC__ storage_after.prev >>=? fun prev_aft -> - Assert.equal_int ~loc:__LOC__ input prev_aft >>=? fun () -> - Assert.equal_int - ~loc:__LOC__ - (storage_before.total + input) - storage_after.total - - let test_mapping (input, prev, total) = - let storage_before = {prev; total} in - run_test_map_opt_script input storage_before >>=? fun ({storage; _}, _) -> - let new_storage = assume_storage_shape (Micheline.root storage) in - assertions storage_before new_storage input -end - -let tests = - [ - Tztest.tztest "test bad contract error" `Quick test_bad_contract_parameter; - Tztest.tztest "check robustness overflow error" `Slow test_stack_overflow; - Tztest.tztest - "check robustness overflow error in lwt" - `Slow - test_stack_overflow_in_lwt; - Tztest.tztest - "test multiplication no illegitimate overflow" - `Quick - test_multiplication_close_to_overflow_passes; - Tztest.tztest "test stack overflow error" `Slow test_stack_overflow; - Tztest.tztest_qcheck - ~name:"test map instr against options" - QCheck.( - triple - (option small_signed_int) - (option small_signed_int) - small_signed_int) - Test_map_instr_on_options.test_mapping; - ] - @ error_encoding_tests diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_lazy_storage_diff.ml b/src/proto_012_Psithaca/lib_protocol/test/test_lazy_storage_diff.ml deleted file mode 100644 index cd55c3228f92..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_lazy_storage_diff.ml +++ /dev/null @@ -1,141 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol - -(** Generation of input data *) - -let ids = - [|1; 42; 1337; 1984|] |> Array.map Z.of_int - |> Array.map Lazy_storage_kind.Big_map.Id.parse_z - -let strs = [|"0"; "True"; "nat"; "bool"|] - -let exprs = strs |> Array.map Expr.from_string - -let hashes = - strs |> Array.map (fun x -> [x]) |> Array.map Script_expr_hash.hash_string - -let updates_len_existing = [1; 2; 3] - -let updates_len_other = 0 :: updates_len_existing - -let gen_inits idx : - (( Lazy_storage_kind.Big_map.Id.t, - Lazy_storage_kind.Big_map.alloc ) - Lazy_storage_diff.init - * int list) - list = - [ - (Existing, updates_len_existing); - (Copy {src = ids.(idx - 1)}, updates_len_other); - ( Alloc {key_type = exprs.(idx); value_type = exprs.(idx - 1)}, - updates_len_other ); - ] - -let gen_update_list idx : Lazy_storage_kind.Big_map.update list = - [None; Some exprs.(idx)] - |> List.map (fun value -> - Lazy_storage_kind.Big_map. - {key = exprs.(idx); key_hash = hashes.(idx); value}) - -let rec gen_updates updates_len : Lazy_storage_kind.Big_map.updates list = - if updates_len = 0 then [] - else - gen_updates (updates_len - 1) - |> List.map (fun suffix -> - gen_update_list updates_len - |> List.map (fun prefix -> prefix :: suffix)) - |> List.flatten - -let gen_updates_list updates_lens : Lazy_storage_kind.Big_map.updates list = - updates_lens |> List.map gen_updates |> List.flatten - -let gen_diffs idx : - ( Lazy_storage_kind.Big_map.Id.t, - Lazy_storage_kind.Big_map.alloc, - Lazy_storage_kind.Big_map.updates ) - Lazy_storage_diff.diff - list = - let open Lazy_storage_diff in - Remove - :: - (gen_inits idx - |> List.map (fun (init, updates_lens) -> - gen_updates_list updates_lens - |> List.map (fun updates -> Update {init; updates})) - |> List.flatten) - -let gen_diffs_items idx : Lazy_storage_diff.diffs_item list = - let id = ids.(idx) in - gen_diffs idx |> List.map (fun diff -> Lazy_storage_diff.make Big_map id diff) - -let rec gen_diffs_list len : Lazy_storage_diff.diffs list = - if len = 0 then [] - else - gen_diffs_list (len - 1) - |> List.map (fun suffix -> - gen_diffs_items len |> List.map (fun prefix -> prefix :: suffix)) - |> List.flatten - -let diffs_list_lens = [0; 1; 2; 3] - -let diffs_list : Lazy_storage_diff.diffs list = - diffs_list_lens |> List.map gen_diffs_list |> List.flatten - -(** Properties to check *) - -let conversion_roundtrip lazy_storage_diff = - let legacy_big_map_diff = - Contract_storage.Legacy_big_map_diff.of_lazy_storage_diff lazy_storage_diff - in - let reconverted = - Contract_storage.Legacy_big_map_diff.to_lazy_storage_diff - legacy_big_map_diff - in - assert (Stdlib.( = ) reconverted lazy_storage_diff) - -let encoding_roundtrip lazy_storage_diff = - let encoded = - Data_encoding.Binary.to_bytes_exn - Lazy_storage_diff.encoding - lazy_storage_diff - in - match Data_encoding.Binary.of_bytes Lazy_storage_diff.encoding encoded with - | Ok decoded -> assert (Stdlib.( = ) decoded lazy_storage_diff) - | Error _ -> Stdlib.failwith "Decoding failed" - -(** Iterator and test definitions *) - -let on_diffs f () = - List.iter f diffs_list ; - return_unit - -(* Marked Slow because they take 5 to 10 seconds and are unlikely to change *) -let tests = - [ - Tztest.tztest "conversion roundtrip" `Slow (on_diffs conversion_roundtrip); - Tztest.tztest "encoding roundtrip" `Slow (on_diffs encoding_roundtrip); - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_level_module.ml b/src/proto_012_Psithaca/lib_protocol/test/test_level_module.ml deleted file mode 100644 index 64546a24a264..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_level_module.ml +++ /dev/null @@ -1,275 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (baking) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^level module$" - Subject: some functions in the Level module -*) - -open Protocol - -let test_create_cycle_eras () = - let empty_cycle_eras = - Level_repr.create_cycle_eras [] |> Environment.wrap_tzresult - in - Assert.proto_error ~loc:__LOC__ empty_cycle_eras (function - | Level_repr.Invalid_cycle_eras -> true - | _ -> false) - >>=? fun () -> - let increasing_first_levels = - [ - Level_repr. - { - first_level = Raw_level_repr.of_int32_exn 1l; - first_cycle = Cycle_repr.succ Cycle_repr.root; - blocks_per_cycle = 8l; - blocks_per_commitment = 2l; - }; - { - first_level = Raw_level_repr.of_int32_exn 9l; - first_cycle = Cycle_repr.root; - blocks_per_cycle = 8l; - blocks_per_commitment = 2l; - }; - ] - |> Level_repr.create_cycle_eras |> Environment.wrap_tzresult - in - Assert.proto_error ~loc:__LOC__ increasing_first_levels (function - | Level_repr.Invalid_cycle_eras -> true - | _ -> false) - >>=? fun () -> - let increasing_first_cycles = - [ - Level_repr. - { - first_level = Raw_level_repr.of_int32_exn 9l; - first_cycle = Cycle_repr.root; - blocks_per_cycle = 8l; - blocks_per_commitment = 2l; - }; - { - first_level = Raw_level_repr.of_int32_exn 1l; - first_cycle = Cycle_repr.succ Cycle_repr.root; - blocks_per_cycle = 8l; - blocks_per_commitment = 2l; - }; - ] - |> Level_repr.create_cycle_eras |> Environment.wrap_tzresult - in - Assert.proto_error ~loc:__LOC__ increasing_first_cycles (function - | Level_repr.Invalid_cycle_eras -> true - | _ -> false) - -let test_case_1 = - ( [ - Level_repr. - { - first_level = Raw_level_repr.of_int32_exn 1l; - first_cycle = Cycle_repr.root; - blocks_per_cycle = 8l; - blocks_per_commitment = 2l; - }; - ], - [ - (1, (1, 0, 0, 0, false)); - (2, (2, 1, 0, 1, true)); - (3, (3, 2, 0, 2, false)); - (8, (8, 7, 0, 7, true)); - (9, (9, 8, 1, 0, false)); - (16, (16, 15, 1, 7, true)); - (17, (17, 16, 2, 0, false)); - (64, (64, 63, 7, 7, true)); - (65, (65, 64, 8, 0, false)); - ] ) - -let test_case_2 = - ( List.rev - [ - Level_repr. - { - first_level = Raw_level_repr.of_int32_exn 1l; - first_cycle = Cycle_repr.root; - blocks_per_cycle = 8l; - blocks_per_commitment = 2l; - }; - { - first_level = Raw_level_repr.of_int32_exn 17l; - first_cycle = Cycle_repr.of_int32_exn 2l; - blocks_per_cycle = 16l; - blocks_per_commitment = 4l; - }; - ], - [ - (1, (1, 0, 0, 0, false)); - (2, (2, 1, 0, 1, true)); - (3, (3, 2, 0, 2, false)); - (8, (8, 7, 0, 7, true)); - (9, (9, 8, 1, 0, false)); - (16, (16, 15, 1, 7, true)); - (17, (17, 16, 2, 0, false)); - (32, (32, 31, 2, 15, true)); - (33, (33, 32, 3, 0, false)); - (64, (64, 63, 4, 15, true)); - (65, (65, 64, 5, 0, false)); - ] ) - -let test_case_3 = - ( List.rev - [ - Level_repr. - { - first_level = Raw_level_repr.of_int32_exn 1l; - first_cycle = Cycle_repr.root; - blocks_per_cycle = 8l; - blocks_per_commitment = 2l; - }; - { - first_level = Raw_level_repr.of_int32_exn 17l; - first_cycle = Cycle_repr.of_int32_exn 2l; - blocks_per_cycle = 16l; - blocks_per_commitment = 4l; - }; - { - first_level = Raw_level_repr.of_int32_exn 49l; - first_cycle = Cycle_repr.of_int32_exn 4l; - blocks_per_cycle = 6l; - blocks_per_commitment = 3l; - }; - ], - [ - (1, (1, 0, 0, 0, false)); - (2, (2, 1, 0, 1, true)); - (3, (3, 2, 0, 2, false)); - (8, (8, 7, 0, 7, true)); - (9, (9, 8, 1, 0, false)); - (16, (16, 15, 1, 7, true)); - (17, (17, 16, 2, 0, false)); - (32, (32, 31, 2, 15, true)); - (33, (33, 32, 3, 0, false)); - (48, (48, 47, 3, 15, true)); - (49, (49, 48, 4, 0, false)); - (64, (64, 63, 6, 3, false)); - (65, (65, 64, 6, 4, false)); - (66, (66, 65, 6, 5, true)); - (67, (67, 66, 7, 0, false)); - ] ) - -let test_level_from_raw () = - List.iter_es - (fun (cycle_eras, test_cases) -> - List.iter_es - (fun ( input_level, - ( level, - level_position, - cycle, - cycle_position, - expected_commitment ) ) -> - let raw_level = - Raw_level_repr.of_int32_exn (Int32.of_int input_level) - in - Level_repr.create_cycle_eras cycle_eras |> Environment.wrap_tzresult - >>?= fun cycle_eras -> - let level_from_raw = - Protocol.Level_repr.from_raw ~cycle_eras raw_level - in - Assert.equal_int - ~loc:__LOC__ - (Int32.to_int (Raw_level_repr.to_int32 level_from_raw.level)) - level - >>=? fun () -> - Assert.equal_int - ~loc:__LOC__ - (Int32.to_int level_from_raw.level_position) - level_position - >>=? fun () -> - Assert.equal_int - ~loc:__LOC__ - (Int32.to_int (Cycle_repr.to_int32 level_from_raw.cycle)) - cycle - >>=? fun () -> - Assert.equal_int - ~loc:__LOC__ - (Int32.to_int level_from_raw.cycle_position) - cycle_position - >>=? fun () -> - Assert.equal_bool - ~loc:__LOC__ - level_from_raw.expected_commitment - expected_commitment - >>=? fun () -> - let offset = - Int32.neg (Int32.add Int32.one (Int32.of_int input_level)) - in - let res = - Level_repr.from_raw_with_offset ~cycle_eras ~offset raw_level - in - Assert.proto_error - ~loc:__LOC__ - (Environment.wrap_tzresult res) - (fun err -> - let error_info = - Error_monad.find_info_of_error (Environment.wrap_tzerror err) - in - error_info.title = "Negative sum of level and offset")) - test_cases) - [test_case_1; test_case_2; test_case_3] - -let test_first_level_in_cycle () = - let cycle_eras = fst test_case_3 in - let test_cases = - (* cycle, level *) - [ - (0l, 1); - (1l, 9); - (2l, 17); - (3l, 33); - (4l, 49); - (5l, 55); - (6l, 61); - (7l, 67); - ] - in - let f (input_cycle, level) = - Level_repr.create_cycle_eras cycle_eras |> Environment.wrap_tzresult - >>?= fun cycle_eras -> - let input_cycle = Cycle_repr.of_int32_exn input_cycle in - let level_res = - Level_repr.first_level_in_cycle_from_eras ~cycle_eras input_cycle - in - Assert.equal_int - ~loc:__LOC__ - (Int32.to_int (Raw_level_repr.to_int32 level_res.level)) - level - in - List.iter_es f test_cases - -let tests = - [ - Tztest.tztest "create_cycle_eras" `Quick test_create_cycle_eras; - Tztest.tztest "level_from_raw" `Quick test_level_from_raw; - Tztest.tztest "first_level_in_cycle" `Quick test_first_level_in_cycle; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_liquidity_baking.ml b/src/proto_012_Psithaca/lib_protocol/test/test_liquidity_baking.ml deleted file mode 100644 index 8748cbe87ed4..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_liquidity_baking.ml +++ /dev/null @@ -1,562 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Tocqueville Group, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: liquidity baking - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^liquidity baking$" - Subject: Test liquidity baking subsidies, CPMM storage updates, - sunset shut off, and escape hatch shut off. -*) - -open Liquidity_baking_machine -open Protocol -open Test_tez - -let generate_init_state () = - let cpmm_min_xtz_balance = 10_000_000L in - let cpmm_min_tzbtc_balance = 100_000 in - let accounts_balances = - [ - {xtz = 1_000_000L; tzbtc = 1; liquidity = 100}; - {xtz = 1_000L; tzbtc = 1000; liquidity = 100}; - {xtz = 40_000_000L; tzbtc = 350000; liquidity = 300}; - ] - in - ValidationMachine.build - {cpmm_min_xtz_balance; cpmm_min_tzbtc_balance; accounts_balances} - >>=? fun _ -> return_unit - -(* The script hash of - - https://gitlab.com/dexter2tz/dexter2tz/-/blob/d98643881fe14996803997f1283e84ebd2067e35/dexter.liquidity_baking.mligo.tz - -*) -let expected_cpmm_hash = - Script_expr_hash.of_b58check_exn - "exprvEBYbxZruLZ9aUDEC9cUxn5KUj361xsaZXGfCxogFoKQ1er9Np" - -(* The script hash of - - https://gitlab.com/dexter2tz/dexter2tz/-/blob/d98643881fe14996803997f1283e84ebd2067e35/lqt_fa12.mligo.tz - -*) -let expected_lqt_hash = - Script_expr_hash.of_b58check_exn - "exprufAK15C2FCbxGLCEVXFe26p3eQdYuwZRk1morJUwy9NBUmEZVB" - -(* Test that the scripts of the Liquidity Baking contracts (CPMM and LQT) have the expected hashes. *) -let liquidity_baking_origination () = - Context.init 1 >>=? fun (blk, _contracts) -> - Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun cpmm_address -> - Context.Contract.script_hash (B blk) cpmm_address >>=? fun cpmm_hash -> - Lwt.return @@ Environment.wrap_tzresult - @@ Alpha_context.Contract.of_b58check "KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - >>=? fun lqt_address -> - Context.Contract.script_hash (B blk) lqt_address >>=? fun lqt_hash -> - Assert.equal - ~loc:__LOC__ - Script_expr_hash.equal - "Unexpected CPMM script." - Script_expr_hash.pp - cpmm_hash - expected_cpmm_hash - >>=? fun () -> - Assert.equal - ~loc:__LOC__ - Script_expr_hash.equal - "Unexpected LQT script." - Script_expr_hash.pp - lqt_hash - expected_lqt_hash - >>=? fun () -> return_unit - -(* Test that the CPMM address in storage is correct *) -let liquidity_baking_cpmm_address () = - Context.init 1 >>=? fun (blk, _contracts) -> - Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> - Assert.equal - ~loc:__LOC__ - String.equal - "CPMM address in storage is incorrect" - Format.pp_print_string - (Alpha_context.Contract.to_b58check liquidity_baking) - "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5" - >>=? fun () -> return_unit - -(* Test that after [n] blocks, the liquidity baking CPMM contract is credited [n] times the subsidy amount. *) -let liquidity_baking_subsidies n () = - Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> - Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> - Context.Contract.balance (B blk) liquidity_baking >>=? fun old_balance -> - Block.bake_n n blk >>=? fun blk -> - Context.get_liquidity_baking_subsidy (B blk) - >>=? fun liquidity_baking_subsidy -> - (liquidity_baking_subsidy *? Int64.(of_int n)) >>?= fun expected_credit -> - Assert.balance_was_credited - ~loc:__LOC__ - (B blk) - liquidity_baking - old_balance - expected_credit - >>=? fun () -> return_unit - -(* Test that [n] blocks after the liquidity baking sunset, the subsidy is not applied anymore. - More precisely, after the sunset, the total amount credited to the subsidy is only proportional - to the sunset level and in particular it does not depend on [n]. *) -let liquidity_baking_sunset_level n () = - Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> - Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> - Context.get_constants (B blk) >>=? fun csts -> - let sunset = csts.parametric.liquidity_baking_sunset_level in - Context.Contract.balance (B blk) liquidity_baking >>=? fun old_balance -> - Block.bake_n (Int32.to_int sunset + n) blk >>=? fun blk -> - Context.get_liquidity_baking_subsidy (B blk) - >>=? fun liquidity_baking_subsidy -> - (liquidity_baking_subsidy *? Int64.(sub (of_int32 sunset) 1L)) - >>?= fun expected_credit -> - Assert.balance_was_credited - ~loc:__LOC__ - (B blk) - liquidity_baking - old_balance - expected_credit - >>=? fun () -> return_unit - -(* Test that subsidy shuts off at correct escape level alternating baking [n_vote_false] blocks with liquidity_baking_escape_vote = false and [n_vote_true] blocks with it true followed by [bake_after_escape] blocks with it false. *) -(* Escape level is roughly 2*(log(1-1/(2*percent_flagging)) / log(0.999)) *) -let liquidity_baking_escape_hatch n_vote_false n_vote_true escape_level - bake_after_escape () = - Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> - Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> - Context.Contract.balance (B blk) liquidity_baking >>=? fun old_balance -> - let rec bake_escaping blk i = - if i < escape_level then - Block.bake_n n_vote_false blk >>=? fun blk -> - Block.bake_n ~liquidity_baking_escape_vote:true n_vote_true blk - >>=? fun blk -> bake_escaping blk (i + n_vote_false + n_vote_true) - else return blk - in - bake_escaping blk 0 >>=? fun blk -> - Block.bake_n bake_after_escape blk >>=? fun blk -> - Context.get_liquidity_baking_subsidy (B blk) - >>=? fun liquidity_baking_subsidy -> - liquidity_baking_subsidy *? Int64.of_int escape_level - >>?= fun expected_balance -> - Assert.balance_was_credited - ~loc:__LOC__ - (B blk) - liquidity_baking - old_balance - expected_balance - >>=? fun () -> return_unit - -(* 100% of blocks have liquidity_baking_escape_vote = true *) -let liquidity_baking_escape_hatch_100 n () = - liquidity_baking_escape_hatch 0 1 812 n () - -(* 80% of blocks have liquidity_baking_escape_vote = true *) -let liquidity_baking_escape_hatch_80 n () = - liquidity_baking_escape_hatch 1 4 1079 n () - -(* 60% of blocks have liquidity_baking_escape_vote = true *) -let liquidity_baking_escape_hatch_60 n () = - liquidity_baking_escape_hatch 2 3 1624 n () - -(* 40% of blocks have liquidity_baking_escape_vote = true *) -let liquidity_baking_escape_hatch_40 n () = - liquidity_baking_escape_hatch 3 2 3590 n () - -(* 33% of blocks have liquidity_baking_escape_vote = true. - Escape hatch should not be activated. *) -let liquidity_baking_escape_hatch_33 n () = - Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> - Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> - Context.get_constants (B blk) >>=? fun csts -> - let sunset = csts.parametric.liquidity_baking_sunset_level in - Context.Contract.balance (B blk) liquidity_baking >>=? fun old_balance -> - let rec bake_33_percent_escaping blk i = - if i < Int32.to_int sunset + n then - Block.bake blk >>=? fun blk -> - Block.bake blk >>=? fun blk -> - Block.bake ~liquidity_baking_escape_vote:true blk >>=? fun blk -> - bake_33_percent_escaping blk (i + 3) - else return blk - in - bake_33_percent_escaping blk 0 >>=? fun blk -> - Context.get_liquidity_baking_subsidy (B blk) - >>=? fun liquidity_baking_subsidy -> - (liquidity_baking_subsidy *? Int64.(sub (of_int32 sunset) 1L)) - >>?= fun expected_balance -> - Assert.balance_was_credited - ~loc:__LOC__ - (B blk) - liquidity_baking - old_balance - expected_balance - >>=? fun () -> return_unit - -(* Test that the escape EMA in block metadata is correct. *) -let liquidity_baking_escape_ema n_vote_false n_vote_true escape_level - bake_after_escape expected_escape_ema () = - Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> - let rec bake_escaping blk i = - if i < escape_level then - Block.bake_n n_vote_false blk >>=? fun blk -> - Block.bake_n ~liquidity_baking_escape_vote:true n_vote_true blk - >>=? fun blk -> bake_escaping blk (i + n_vote_false + n_vote_true) - else return blk - in - bake_escaping blk 0 >>=? fun blk -> - (* We only need to return the escape EMA at the end. *) - Block.bake_n_with_liquidity_baking_escape_ema bake_after_escape blk - >>=? fun (_blk, escape_ema) -> - Assert.leq_int ~loc:__LOC__ (Int32.to_int escape_ema) expected_escape_ema - >>=? fun () -> return_unit - -(* With no bakers setting the escape vote, EMA should be zero. *) -let liquidity_baking_escape_ema_zero () = - liquidity_baking_escape_ema 0 0 0 100 0 () - -(* The EMA should be not much over the threshold after the escape hatch has been activated. We add 1_000 to the constant to give room for the last update. *) -let liquidity_baking_escape_ema_threshold () = - liquidity_baking_escape_ema 0 1 812 1 667_667 () - -let liquidity_baking_storage n () = - Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> - Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> - Context.get_liquidity_baking_subsidy (B blk) >>=? fun subsidy -> - let expected_storage = - Expr.from_string - (Printf.sprintf - "Pair 1\n\ - \ %d\n\ - \ 100\n\ - \ \"KT1VqarPDicMFn1ejmQqqshUkUXTCTXwmkCN\"\n\ - \ \"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo\"" - (100 + (n * Int64.to_int (to_mutez subsidy)))) - in - Block.bake_n n blk >>=? fun blk -> - Context.Contract.storage (B blk) liquidity_baking >>=? fun storage -> - let to_string expr = - Format.asprintf "%a" Michelson_v1_printer.print_expr expr - in - Assert.equal - ~loc:__LOC__ - String.equal - "Storage isn't equal" - Format.pp_print_string - (to_string storage) - (to_string expected_storage) - >>=? fun () -> return_unit - -let liquidity_baking_balance_update () = - Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> - Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> - Context.get_constants (B blk) >>=? fun csts -> - let sunset = csts.parametric.liquidity_baking_sunset_level in - let subsidy = csts.parametric.liquidity_baking_subsidy in - Block.bake_n_with_all_balance_updates Int32.(to_int (add sunset 100l)) blk - >>=? fun (_blk, balance_updates) -> - let liquidity_baking_updates = - List.filter - (fun el -> - match el with - | ( Alpha_context.Receipt.Contract contract, - Alpha_context.Receipt.Credited _, - Alpha_context.Receipt.Subsidy ) -> - Alpha_context.Contract.(contract = liquidity_baking) - | _ -> false) - balance_updates - in - List.fold_left_e - (fun accum (_, update, _) -> - match update with - | Alpha_context.Receipt.Credited x -> accum +? x - | Alpha_context.Receipt.Debited _ -> assert false) - (of_int 0) - liquidity_baking_updates - >>?= fun credits -> - Assert.equal_int - ~loc:__LOC__ - (Int64.to_int (to_mutez credits)) - ((Int32.to_int sunset - 1) * Int64.to_int (to_mutez subsidy)) - >>=? fun () -> return_unit - -let get_cpmm_result results = - match results with - | cpmm_result :: _results -> cpmm_result - | _ -> assert false - -let get_lqt_result results = - match results with - | _cpmm_result :: lqt_result :: _results -> lqt_result - | _ -> assert false - -let get_address_in_result result = - match result with - | Apply_results.Origination_result {originated_contracts; _} -> ( - match originated_contracts with [c] -> c | _ -> assert false) - -let get_balance_updates_in_result result = - match result with - | Apply_results.Origination_result {balance_updates; _} -> balance_updates - -let get_balance_update_in_result result = - match get_balance_updates_in_result result with - | [(Contract _, Credited balance, Protocol_migration)] -> balance - | [_; _; _; _; _; (Contract _, Credited balance, Protocol_migration)] -> - balance - | _ -> assert false - -let liquidity_baking_origination_result_cpmm_address () = - Context.init 1 >>=? fun (blk, _contracts) -> - Context.get_liquidity_baking_cpmm_address (B blk) - >>=? fun cpmm_address_in_storage -> - Block.bake_n_with_origination_results 1 blk - >>=? fun (_blk, origination_results) -> - let result = get_cpmm_result origination_results in - let address = get_address_in_result result in - Assert.equal - ~loc:__LOC__ - Context.Contract.equal - "CPMM address in storage is not the same as in origination result" - Context.Contract.pp - address - cpmm_address_in_storage - >>=? fun () -> return_unit - -let liquidity_baking_origination_result_cpmm_balance () = - Context.init 1 >>=? fun (blk, _contracts) -> - Block.bake_n_with_origination_results 1 blk - >>=? fun (_blk, origination_results) -> - let result = get_cpmm_result origination_results in - let balance_update = get_balance_update_in_result result in - Assert.equal_tez ~loc:__LOC__ balance_update (of_mutez_exn 100L) - >>=? fun () -> return_unit - -let liquidity_baking_origination_result_lqt_address () = - Context.init 1 >>=? fun (blk, _contracts) -> - Block.bake_n_with_origination_results 1 blk - >>=? fun (_blk, origination_results) -> - let result = get_lqt_result origination_results in - let address = get_address_in_result result in - Assert.equal - ~loc:__LOC__ - String.equal - "LQT address in origination result is incorrect" - Format.pp_print_string - (Alpha_context.Contract.to_b58check address) - "KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - >>=? fun () -> return_unit - -let liquidity_baking_origination_result_lqt_balance () = - Context.init 1 >>=? fun (blk, _contracts) -> - Block.bake_n_with_origination_results 1 blk - >>=? fun (_blk, origination_results) -> - let result = get_lqt_result origination_results in - let balance_updates = get_balance_updates_in_result result in - match balance_updates with - | [ - (Liquidity_baking_subsidies, Debited am1, Protocol_migration); - (Storage_fees, Credited am2, Protocol_migration); - (Liquidity_baking_subsidies, Debited am3, Protocol_migration); - (Storage_fees, Credited am4, Protocol_migration); - ] -> - Assert.equal_tez ~loc:__LOC__ am1 am2 >>=? fun () -> - Assert.equal_tez ~loc:__LOC__ am3 am4 >>=? fun () -> - Assert.equal_tez ~loc:__LOC__ am1 (of_mutez_exn 64_250L) >>=? fun () -> - Assert.equal_tez ~loc:__LOC__ am3 (of_mutez_exn 494_500L) - | _ -> failwith "Unexpected balance updates (%s)" __LOC__ - -(* Test that with no contract at the tzBTC address and the level low enough to indicate we're not on mainnet, three contracts are originated in stitching. *) -let liquidity_baking_origination_test_migration () = - Context.init 1 >>=? fun (blk, _contracts) -> - Block.bake_n_with_origination_results 1 blk - >>=? fun (_blk, origination_results) -> - let num_results = List.length origination_results in - Assert.equal_int ~loc:__LOC__ num_results 3 - -(* Test that with no contract at the tzBTC address and the level high enough to indicate we could be on mainnet, no contracts are originated in stitching. *) -let liquidity_baking_origination_no_tzBTC_mainnet_migration () = - Context.init ~consensus_threshold:0 ~level:1_437_862l 1 - >>=? fun (blk, _contracts) -> - (* By baking a bit we also check that the subsidy application with no CPMM present does nothing rather than stopping the chain.*) - Block.bake_n_with_origination_results 64 blk - >>=? fun (_blk, origination_results) -> - let num_results = List.length origination_results in - Assert.equal_int ~loc:__LOC__ num_results 0 - -let tests = - [ - Tztest.tztest - "test liquidity baking script hashes" - `Quick - liquidity_baking_origination; - Tztest.tztest - "test liquidity baking cpmm is originated at the expected address" - `Quick - liquidity_baking_cpmm_address; - Tztest.tztest "Init Context" `Quick generate_init_state; - Tztest.tztest - "test liquidity baking subsidy is correct" - `Quick - (liquidity_baking_subsidies 64); - Tztest.tztest - "test liquidity baking shuts off at sunset level when baking one block \ - longer" - `Quick - (liquidity_baking_sunset_level 1); - Tztest.tztest - "test liquidity baking shuts off at sunset level when baking two blocks \ - longer" - `Quick - (liquidity_baking_sunset_level 2); - Tztest.tztest - "test liquidity baking shuts off at sunset level when baking 100 blocks \ - longer" - `Quick - (liquidity_baking_sunset_level 100); - Tztest.tztest - "test liquidity baking escape hatch with 100% of bakers flagging when \ - baking one block longer" - `Quick - (liquidity_baking_escape_hatch_100 1); - Tztest.tztest - "test liquidity baking escape hatch with 100% of bakers flagging when \ - baking two blocks longer" - `Quick - (liquidity_baking_escape_hatch_100 2); - Tztest.tztest - "test liquidity baking escape hatch with 100% of bakers flagging when \ - baking 100 blocks longer" - `Quick - (liquidity_baking_escape_hatch_100 100); - Tztest.tztest - "test liquidity baking escape hatch with 80% of bakers flagging when \ - baking one block longer" - `Quick - (liquidity_baking_escape_hatch_80 1); - Tztest.tztest - "test liquidity baking escape hatch with 80% of bakers flagging when \ - baking two blocks longer" - `Quick - (liquidity_baking_escape_hatch_80 2); - Tztest.tztest - "test liquidity baking escape hatch with 80% of bakers flagging when \ - baking 100 blocks longer" - `Quick - (liquidity_baking_escape_hatch_80 100); - Tztest.tztest - "test liquidity baking escape hatch with 60% of bakers flagging when \ - baking one block longer" - `Quick - (liquidity_baking_escape_hatch_60 1); - Tztest.tztest - "test liquidity baking escape hatch with 60% of bakers flagging when \ - baking two blocks longer" - `Quick - (liquidity_baking_escape_hatch_60 2); - Tztest.tztest - "test liquidity baking escape hatch with 60% of bakers flagging when \ - baking 100 blocks longer" - `Quick - (liquidity_baking_escape_hatch_60 100); - Tztest.tztest - "test liquidity baking escape hatch with 40% of bakers flagging when \ - baking one block longer" - `Quick - (liquidity_baking_escape_hatch_40 1); - Tztest.tztest - "test liquidity baking escape hatch with 40% of bakers flagging when \ - baking two blocks longer" - `Quick - (liquidity_baking_escape_hatch_40 2); - Tztest.tztest - "test liquidity baking escape hatch with 40% of bakers flagging when \ - baking 100 blocks longer" - `Quick - (liquidity_baking_escape_hatch_40 100); - Tztest.tztest - "test liquidity baking shuts off at sunset level with escape hatch at \ - 33% and baking one block longer" - `Quick - (liquidity_baking_escape_hatch_33 1); - Tztest.tztest - "test liquidity baking shuts off at sunset level with escape hatch at \ - 33% and baking two blocks longer" - `Quick - (liquidity_baking_escape_hatch_33 2); - Tztest.tztest - "test liquidity baking shuts off at sunset level with escape hatch at \ - 33% and baking 100 blocks longer" - `Quick - (liquidity_baking_escape_hatch_33 100); - Tztest.tztest - "test liquidity baking escape ema in block metadata is zero with no \ - bakers flagging." - `Quick - liquidity_baking_escape_ema_zero; - Tztest.tztest - "test liquidity baking escape ema is equal to the threshold after the \ - escape hatch has been activated" - `Quick - liquidity_baking_escape_ema_threshold; - Tztest.tztest - "test liquidity baking storage is updated" - `Quick - (liquidity_baking_storage 64); - Tztest.tztest - "test liquidity baking balance updates" - `Quick - liquidity_baking_balance_update; - Tztest.tztest - "test liquidity baking CPMM address in storage matches address in the \ - origination result" - `Quick - liquidity_baking_origination_result_cpmm_address; - Tztest.tztest - "test liquidity baking CPMM balance in origination result is 100 mutez" - `Quick - liquidity_baking_origination_result_cpmm_balance; - Tztest.tztest - "test liquidity baking LQT contract is originated at expected address" - `Quick - liquidity_baking_origination_result_lqt_address; - Tztest.tztest - "test liquidity baking LQT balance in origination result is 0 mutez" - `Quick - liquidity_baking_origination_result_lqt_balance; - Tztest.tztest - "test liquidity baking originates three contracts when tzBTC does not \ - exist and level indicates we are not on mainnet" - `Quick - liquidity_baking_origination_test_migration; - Tztest.tztest - "test liquidity baking originates three contracts when tzBTC does not \ - exist and level indicates we might be on mainnet" - `Quick - liquidity_baking_origination_no_tzBTC_mainnet_migration; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_origination.ml b/src/proto_012_Psithaca/lib_protocol/test/test_origination.ml deleted file mode 100644 index 1be2daf1da7a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_origination.ml +++ /dev/null @@ -1,240 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (origination) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^origination$" - Subject: On originating contracts. -*) - -open Protocol -open Alpha_context -open Test_tez - -let ten_tez = of_int 10 - -(* The possible fees are: a given credit, an origination burn fee - (constants_repr.default.origination_burn = 257 mtez), a fee that is paid when - creating an originate contract. *) -let total_fees_for_origination ?(fee = Tez.zero) ?(credit = Tez.zero) b = - Context.get_constants (B b) - >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> - cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> - credit +? fee >>? ( +? ) origination_burn >>? ( +? ) Op.dummy_script_cost - >>?= fun total_fee -> return total_fee - -(* [test_origination_balances fee credit spendable delegatable] takes four - optional parameter: fee is the fee that pay if require to create an - originated contract; credit is the amount of tez that will send to this - contract; delegatable default is set to true meaning that this contract is - able to delegate. - - This function creates 2 contracts, one for originating (called source) and - one for baking; get the balance of the source contract, call the - origination operation to create a new originated contract from this contract - with all the possible fees; and check the balance before/after originated - operation valid. - - the source contract has payed all the fees - - the originated has been credited correctly. - Note that we need 2 contracts because in Tenderbake the baker receives the - fees instantaneously. So to see that the fees are subtracted, we need that - the bake is done by another delegated. *) -let test_origination_balances ~loc:_ ?(fee = Tez.zero) ?(credit = Tez.zero) () = - Context.init 2 >>=? fun (b, contracts) -> - let source = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - let contract_for_bake = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 - in - Context.Contract.pkh source >>=? fun pkh_for_orig -> - Context.Contract.pkh contract_for_bake >>=? fun pkh_for_bake -> - Op.origination (B b) source ~fee ~credit ~script:Op.dummy_script - >>=? fun (operation, new_contract) -> - total_fees_for_origination ~fee ~credit b >>=? fun total_fee -> - Block.bake ~operation ~policy:(By_account pkh_for_bake) b >>=? fun b -> - (* check that after the block has been baked the contract for originating - was debited all the fees *) - Context.Delegate.current_frozen_deposits (B b) pkh_for_orig - >>=? fun deposits -> - total_fee +? deposits >>?= fun total_fee_plus_deposits -> - Assert.balance_was_debited - ~loc:__LOC__ - (B b) - source - Account.default_initial_balance - total_fee_plus_deposits - >>=? fun _ -> - (* check the balance of the originate contract is equal to credit *) - Assert.balance_is ~loc:__LOC__ (B b) new_contract credit - -(** [register_origination fee credit spendable delegatable] takes four - optional parameter: fee for the fee need to be paid if set to - create an originated contract; credit is the amount of tez that - send to this originated contract; spendable default is set to true - meaning that this contract is spendable; delegatable default is - set to true meaning that this contract is able to delegate. *) -let register_origination ?(fee = Tez.zero) ?(credit = Tez.zero) () = - Context.init 2 >>=? fun (b, contracts) -> - let source = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - let contract_for_bake = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 - in - Context.Contract.pkh source >>=? fun source_pkh -> - Context.Contract.pkh contract_for_bake >>=? fun pkh_for_bake -> - Op.origination (B b) source ~fee ~credit ~script:Op.dummy_script - >>=? fun (operation, originated) -> - Block.bake ~operation ~policy:(By_account pkh_for_bake) b >>=? fun b -> - (* fee + credit were debited from source *) - total_fees_for_origination ~fee ~credit b >>=? fun total_fee -> - Context.Delegate.current_frozen_deposits (B b) source_pkh >>=? fun deposits -> - total_fee +? deposits >>?= fun total_fee_plus_deposits -> - Assert.balance_was_debited - ~loc:__LOC__ - (B b) - source - Account.default_initial_balance - total_fee_plus_deposits - >>=? fun () -> - (* originated contract has been credited *) - Assert.balance_was_credited ~loc:__LOC__ (B b) originated Tez.zero credit - >|=? fun () -> - (* TODO spendable or not and delegatable or not if relevant for some - test. Not the case at the moment, cf. uses of - register_origination *) - (b, source, originated) - -(******************************************************) -(* Tests *) -(******************************************************) - -(** Basic test. A contract is created as well as the newly originated - contract (called from origination operation). The balance - before/after are checked. *) -let test_balances_simple () = test_origination_balances ~loc:__LOC__ () - -(** Same as [balances_simple] but credits 10 tez to the originated - contract (no fees). *) -let test_balances_credit () = - test_origination_balances ~loc:__LOC__ ~credit:ten_tez () - -(** Same as [balances_credit] with 10 tez fees. *) -let test_balances_credit_fee () = - test_origination_balances ~loc:__LOC__ ~credit:(of_int 2) ~fee:ten_tez () - -(** Ask source contract to pay a fee when originating a contract. *) -let test_pay_fee () = - register_origination ~credit:(of_int 2) ~fee:ten_tez () - >>=? fun (_b, _contract, _new_contract) -> return_unit - -(******************************************************) -(** Errors *) - -(******************************************************) - -(** Create an originate contract where the contract does not have - enough tez to pay for the fee. *) -let test_not_tez_in_contract_to_pay_fee () = - Context.init 2 >>=? fun (b, contracts) -> - let contract_1 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 - in - let contract_2 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 - in - Incremental.begin_construction b >>=? fun inc -> - (* transfer everything but one tez from 1 to 2 and check balance of 1 *) - Context.Contract.balance (I inc) contract_1 >>=? fun balance -> - balance -? Tez.one >>?= fun amount -> - Op.transaction (I inc) contract_1 contract_2 amount >>=? fun operation -> - Incremental.add_operation inc operation >>=? fun inc -> - Assert.balance_was_debited ~loc:__LOC__ (I inc) contract_1 balance amount - >>=? fun _ -> - (* use this source contract to create an originate contract where it requires - to pay a fee and add an amount of credit into this new contract *) - Op.origination - (I inc) - ~fee:ten_tez - ~credit:Tez.one - contract_1 - ~script:Op.dummy_script - >>=? fun (op, _) -> - Incremental.add_operation inc op >>= fun inc -> - Assert.proto_error ~loc:__LOC__ inc (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - -(* Set the endorser of the block as manager/delegate of the originated - account. *) -let register_contract_get_endorser () = - Context.init 1 >>=? fun (b, contracts) -> - let contract = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - Incremental.begin_construction b >>=? fun inc -> - Context.get_endorser (I inc) >|=? fun (account_endorser, _slots) -> - (inc, contract, account_endorser) - -(* Create multiple originated contracts and ask contract to pay the fee. *) -let n_originations n ?credit ?fee () = - List.fold_left_es - (fun new_contracts _ -> - register_origination ?fee ?credit () - >|=? fun (_b, _source, new_contract) -> new_contract :: new_contracts) - [] - (1 -- n) - -(** Create 100 originations. *) -let test_multiple_originations () = - n_originations 100 ~credit:(of_int 2) ~fee:ten_tez () >>=? fun contracts -> - Assert.equal_int ~loc:__LOC__ (List.length contracts) 100 - -(** Cannot originate two contracts with the same context's counter. *) -let test_counter () = - Context.init 1 >>=? fun (b, contracts) -> - let contract = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - Incremental.begin_construction b >>=? fun inc -> - Op.origination (I inc) ~credit:Tez.one contract ~script:Op.dummy_script - >>=? fun (op1, _) -> - Op.origination (I inc) ~credit:Tez.one contract ~script:Op.dummy_script - >>=? fun (op2, _) -> - Incremental.add_operation inc op1 >>=? fun inc -> - Incremental.add_operation inc op2 >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Contract_storage.Counter_in_the_past _ -> true - | _ -> false) - -(******************************************************) - -let tests = - [ - Tztest.tztest "balances_simple" `Quick test_balances_simple; - Tztest.tztest "balances_credit" `Quick test_balances_credit; - Tztest.tztest "balances_credit_fee" `Quick test_balances_credit_fee; - Tztest.tztest "pay_fee" `Quick test_pay_fee; - Tztest.tztest - "not enough tez in contract to pay fee" - `Quick - test_not_tez_in_contract_to_pay_fee; - Tztest.tztest "multiple originations" `Quick test_multiple_originations; - Tztest.tztest "counter" `Quick test_counter; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_participation.ml b/src/proto_012_Psithaca/lib_protocol/test/test_participation.ml deleted file mode 100644 index 2c61028e62e3..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_participation.ml +++ /dev/null @@ -1,208 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (participation monitoring) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^participation" - Subject: Participation monitoring in Tenderbake -*) - -open Protocol -open Alpha_context - -(** [baker] bakes and [endorser] endorses *) -let bake_and_endorse_once (b_pred, b_cur) baker endorser = - let open Context in - Context.get_endorsers (B b_cur) >>=? fun endorsers_list -> - List.find_map - (function - | {Plugin.RPC.Validators.delegate; slots; _} -> - if Signature.Public_key_hash.equal delegate endorser then - Some (delegate, slots) - else None) - endorsers_list - |> function - | None -> assert false - | Some delegate -> - Block.get_round b_cur >>?= fun round -> - Op.endorsement ~round ~delegate ~endorsed_block:b_cur (B b_pred) () - >>=? fun endorsement -> - let endorsement = Operation.pack endorsement in - Block.bake ~policy:(By_account baker) ~operation:endorsement b_cur - -(** We test that: - - a delegate that participates enough, gets its endorsing rewards at the end of the cycle, - - a delegate that does not participating enough during a cycle, doesn't get rewarded. - - The case distinction is made by the boolean argument [sufficient_participation]. - If [sufficient_participation] is true, - then a validator endorses for as long as the minimal required activity is not reached, - otherwise it does not endorse. - Finally, we check the validator's balance at the end of the cycle. -*) -let test_participation ~sufficient_participation () = - let n_accounts = 2 in - Context.init ~consensus_threshold:1 n_accounts >>=? fun (b0, accounts) -> - Context.get_constants (B b0) >>=? fun csts -> - let blocks_per_cycle = Int32.to_int csts.parametric.blocks_per_cycle in - let mpr = csts.parametric.minimal_participation_ratio in - assert (blocks_per_cycle mod mpr.denominator = 0) ; - (* if this assertion does not hold, then the test might be incorrect *) - let committee_size = csts.parametric.consensus_committee_size in - let expected_nb_slots = blocks_per_cycle * committee_size / n_accounts in - let minimal_nb_active_slots = - mpr.numerator * expected_nb_slots / mpr.denominator - in - let (account1, account2) = - match accounts with a1 :: a2 :: _ -> (a1, a2) | _ -> assert false - in - Context.Contract.pkh account1 >>=? fun del1 -> - Context.Contract.pkh account2 >>=? fun del2 -> - Block.bake ~policy:(By_account del1) b0 >>=? fun b1 -> - (* To separate concerns, only [del1] bakes: this way, we don't need to - consider baking rewards for [del2]. Delegate [del2] endorses only - if the target [minimal_nb_active_slots] is not reached; for the - rest, it is [del1] that endorses. *) - List.fold_left_es - (fun (b_pred, b_crt, endorsing_power) level -> - let int_level = Int32.of_int level in - Environment.wrap_tzresult (Raw_level.of_int32 int_level) >>?= fun level -> - Context.get_endorsing_power_for_delegate (B b_crt) ~levels:[level] del1 - >>=? fun endorsing_power_for_level -> - let (endorser, new_endorsing_power) = - if sufficient_participation && endorsing_power < minimal_nb_active_slots - then (del2, endorsing_power + endorsing_power_for_level) - else (del1, endorsing_power) - in - bake_and_endorse_once (b_pred, b_crt) del1 endorser >>=? fun b -> - return (b_crt, b, new_endorsing_power)) - (b0, b1, 0) - (2 -- (blocks_per_cycle - 1)) - >>=? fun (pred_b, b, _) -> - Context.Contract.balance (B pred_b) account2 >|=? Tez.to_mutez - >>=? fun bal2_at_pred_b -> - Context.Contract.balance (B b) account2 >|=? Tez.to_mutez - >>=? fun bal2_at_b -> - (* - If not sufficient_participation, we check that the balance of del2 at b is the - balance of del2 at pred_b; consequently, no rewards could have been given - to del2. - - If sufficient participation, we check that the balance of del2 at b is the - balance of del2 at pred_b plus the endorsing rewards. *) - Context.get_endorsing_reward (B b) ~expected_endorsing_power:expected_nb_slots - >|=? Tez.to_mutez - >>=? fun er -> - let endorsing_rewards = if sufficient_participation then er else 0L in - let expected_bal2_at_b = Int64.add bal2_at_pred_b endorsing_rewards in - Assert.equal_int64 ~loc:__LOC__ bal2_at_b expected_bal2_at_b - -(* We bake and endorse with 1 out of 2 accounts; we monitor the result - returned by the '../delegates//participation' RPC for the - non-participating account. *) -let test_participation_rpc () = - let n_accounts = 2 in - Context.init ~consensus_threshold:1 n_accounts >>=? fun (b0, accounts) -> - let (account1, account2) = - match accounts with a1 :: a2 :: _ -> (a1, a2) | _ -> assert false - in - Context.Contract.pkh account1 >>=? fun del1 -> - Context.Contract.pkh account2 >>=? fun del2 -> - Context.get_constants (B b0) >>=? fun csts -> - let blocks_per_cycle = Int32.to_int csts.parametric.blocks_per_cycle in - let Constants.{numerator; denominator} = - csts.parametric.minimal_participation_ratio - in - let expected_cycle_activity = - blocks_per_cycle * csts.parametric.consensus_committee_size / n_accounts - in - let minimal_cycle_activity = - expected_cycle_activity * numerator / denominator - in - let allowed_missed_slots = expected_cycle_activity - minimal_cycle_activity in - let expected_endorsing_rewards = - Tez.mul_exn - csts.parametric.endorsing_reward_per_slot - expected_cycle_activity - in - Block.bake ~policy:(By_account del1) b0 >>=? fun b1 -> - List.fold_left_es - (fun (b_pred, b_crt, total_endorsing_power) level_int -> - Context.Delegate.participation (B b_crt) del2 >>=? fun info -> - Assert.equal_int - ~loc:__LOC__ - info.expected_cycle_activity - expected_cycle_activity - >>=? fun () -> - Assert.equal_int - ~loc:__LOC__ - info.minimal_cycle_activity - minimal_cycle_activity - >>=? fun () -> - Assert.equal_int ~loc:__LOC__ info.missed_levels (level_int - 1) - >>=? fun () -> - let missed_slots = total_endorsing_power in - Assert.equal_int ~loc:__LOC__ info.missed_slots missed_slots - >>=? fun () -> - let remaining_allowed_missed_slots = - allowed_missed_slots - missed_slots - in - Assert.equal_int - ~loc:__LOC__ - info.remaining_allowed_missed_slots - (max 0 remaining_allowed_missed_slots) - >>=? fun () -> - let endorsing_rewards = - if remaining_allowed_missed_slots >= 0 then expected_endorsing_rewards - else Tez.zero - in - Assert.equal_tez - ~loc:__LOC__ - info.expected_endorsing_rewards - endorsing_rewards - >>=? fun () -> - bake_and_endorse_once (b_pred, b_crt) del1 del1 >>=? fun b -> - (* [level_int] is the level of [b_crt] *) - level_int |> Int32.of_int |> Raw_level.of_int32 - |> Environment.wrap_tzresult - >>?= fun level -> - Context.get_endorsing_power_for_delegate (B b_crt) ~levels:[level] del2 - >>=? fun endorsing_power -> - return (b_crt, b, total_endorsing_power + endorsing_power)) - (b0, b1, 0) - (1 -- (blocks_per_cycle - 2)) - >>=? fun (_, _, _) -> return_unit - -let tests = - [ - Tztest.tztest - "test insufficient participation" - `Quick - (test_participation ~sufficient_participation:false); - Tztest.tztest - "test minimal participation" - `Quick - (test_participation ~sufficient_participation:true); - Tztest.tztest "test participation RPC" `Quick test_participation_rpc; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_preendorsement.ml b/src/proto_012_Psithaca/lib_protocol/test/test_preendorsement.ml deleted file mode 100644 index 728f4c79c0f5..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_preendorsement.ml +++ /dev/null @@ -1,228 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (preendorsement) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^preendorsement$" -*) - -open Protocol -open Alpha_context - -(****************************************************************) -(* Utility functions *) -(****************************************************************) - -let init_genesis ?policy () = - Context.init ~consensus_threshold:0 5 >>=? fun (genesis, _) -> - Block.bake ?policy genesis >>=? fun b -> return (genesis, b) - -(****************************************************************) -(* Tests *) -(****************************************************************) - -(** Consensus operation for future level : apply a preendorsement with a level in the future *) -let test_consensus_operation_preendorsement_for_future_level () = - init_genesis () >>=? fun (genesis, pred) -> - let raw_level = Raw_level.of_int32 (Int32.of_int 10) in - let level = match raw_level with Ok l -> l | Error _ -> assert false in - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:true - ~endorsed_block:pred - ~level - ~error_title:"Consensus operation for future level" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Consensus operation for old level : apply a preendorsement with a level in the past *) -let test_consensus_operation_preendorsement_for_old_level () = - init_genesis () >>=? fun (genesis, pred) -> - let raw_level = Raw_level.of_int32 (Int32.of_int 0) in - let level = match raw_level with Ok l -> l | Error _ -> assert false in - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:true - ~endorsed_block:pred - ~level - ~error_title:"Consensus operation for old level" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Consensus operation for future round : apply a preendorsement with a round in the future *) -let test_consensus_operation_preendorsement_for_future_round () = - init_genesis () >>=? fun (genesis, pred) -> - Environment.wrap_tzresult (Round.of_int 21) >>?= fun round -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:true - ~endorsed_block:pred - ~round - ~error_title:"Consensus operation for future round" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Consensus operation for old round : apply a preendorsement with a round in the past *) -let test_consensus_operation_preendorsement_for_old_round () = - init_genesis ~policy:(By_round 10) () >>=? fun (genesis, pred) -> - Environment.wrap_tzresult (Round.of_int 0) >>?= fun round -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:true - ~endorsed_block:pred - ~round - ~error_title:"Consensus operation for old round" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Consensus operation on competing proposal : apply a preendorsement on a competing proposal *) -let test_consensus_operation_preendorsement_on_competing_proposal () = - init_genesis () >>=? fun (genesis, pred) -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:true - ~endorsed_block:pred - ~block_payload_hash:Block_payload_hash.zero - ~error_title:"Consensus operation on competing proposal" - ~context:(Context.B genesis) - ~construction_mode:(pred, None) - () - -(** Unexpected preendorsements in block : apply a preendorsement with an incorrect round *) -let test_unexpected_preendorsements_in_blocks () = - init_genesis () >>=? fun (genesis, pred) -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:true - ~endorsed_block:pred - ~error_title:"unexpected preendorsement in block" - ~context:(Context.B genesis) - () - -(** Round too high : apply a preendorsement with a too high round *) -let test_too_high_round () = - init_genesis () >>=? fun (genesis, pred) -> - let raw_level = Raw_level.of_int32 (Int32.of_int 2) in - let level = match raw_level with Ok l -> l | Error _ -> assert false in - Environment.wrap_tzresult (Round.of_int 1) >>?= fun round -> - Consensus_helpers.test_consensus_operation - ~loc:__LOC__ - ~is_preendorsement:true - ~endorsed_block:pred - ~round - ~level - ~error_title:"preendorsement round too high" - ~context:(Context.B genesis) - ~construction_mode:(pred, Some pred.header.protocol_data) - () - -(** Duplicate preendorsement : apply a preendorsement that has already been applied. *) -let test_duplicate_preendorsement () = - init_genesis () >>=? fun (genesis, _) -> - Block.bake genesis >>=? fun b -> - Incremental.begin_construction ~mempool_mode:true b >>=? fun inc -> - Op.preendorsement ~endorsed_block:b (B genesis) () >>=? fun operation -> - let operation = Operation.pack operation in - Incremental.add_operation inc operation >>=? fun inc -> - Op.preendorsement ~endorsed_block:b (B genesis) () >>=? fun operation -> - let operation = Operation.pack operation in - Incremental.add_operation inc operation >>= fun res -> - Assert.proto_error_with_info - ~loc:__LOC__ - res - "double inclusion of consensus operation" - -(** Preendorsement for next level *) -let test_preendorsement_for_next_level () = - init_genesis () >>=? fun (genesis, _) -> - Consensus_helpers.test_consensus_op_for_next - ~genesis - ~kind:`Preendorsement - ~next:`Level - -(** Preendorsement for next round *) -let test_preendorsement_for_next_round () = - init_genesis () >>=? fun (genesis, _) -> - Consensus_helpers.test_consensus_op_for_next - ~genesis - ~kind:`Preendorsement - ~next:`Round - -let tests = - let module AppMode = Test_preendorsement_functor.BakeWithMode (struct - let name = "AppMode" - - let baking_mode = Block.Application - end) in - let module ConstrMode = Test_preendorsement_functor.BakeWithMode (struct - let name = "ConstrMode" - - let baking_mode = Block.Baking - end) in - AppMode.tests @ ConstrMode.tests - @ [ - Tztest.tztest - "Preendorsement for future level" - `Quick - test_consensus_operation_preendorsement_for_future_level; - Tztest.tztest - "Preendorsement for old level" - `Quick - test_consensus_operation_preendorsement_for_old_level; - Tztest.tztest - "Preendorsement for future round" - `Quick - test_consensus_operation_preendorsement_for_future_round; - Tztest.tztest - "Preendorsement for old round" - `Quick - test_consensus_operation_preendorsement_for_old_round; - Tztest.tztest - "Preendorsement on competing proposal" - `Quick - test_consensus_operation_preendorsement_on_competing_proposal; - Tztest.tztest - "Unexpected preendorsements in blocks" - `Quick - test_unexpected_preendorsements_in_blocks; - Tztest.tztest "Preendorsements round too high" `Quick test_too_high_round; - Tztest.tztest - "Duplicate preendorsement" - `Quick - test_duplicate_preendorsement; - Tztest.tztest - "Preendorsement for next level" - `Quick - test_preendorsement_for_next_level; - Tztest.tztest - "Preendorsement for next round" - `Quick - test_preendorsement_for_next_round; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_preendorsement_functor.ml b/src/proto_012_Psithaca/lib_protocol/test/test_preendorsement_functor.ml deleted file mode 100644 index 543738183300..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_preendorsement_functor.ml +++ /dev/null @@ -1,266 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (preendorsement) in Full_construction & Application modes - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^preendorsement$" - Subject: preendorsement inclusion in a block -*) - -open Protocol -open Alpha_context - -(****************************************************************) -(* Utility functions *) -(****************************************************************) -module type MODE = sig - val name : string - - val baking_mode : Block.baking_mode -end - -module BakeWithMode (Mode : MODE) : sig - val tests : unit Alcotest_lwt.test_case trace -end = struct - let name = Mode.name - - let bake = Block.bake ~baking_mode:Mode.baking_mode - - let aux_simple_preendorsement_inclusion ?(payload_round = Some Round.zero) - ?(locked_round = Some Round.zero) ?(block_round = 1) - ?(preend_round = Round.zero) - ?(preend_branch = fun _predpred pred _curr -> pred) - ?(preendorsed_block = fun _predpred _pred curr -> curr) - ?(mk_ops = fun op -> [op]) - ?(get_delegate_and_slot = - fun _predpred _pred _curr -> return (None, None)) - ?(post_process = Ok (fun _ -> return_unit)) ~loc () = - Context.init ~consensus_threshold:1 5 >>=? fun (genesis, _) -> - bake genesis >>=? fun b1 -> - Op.endorsement ~endorsed_block:b1 (B genesis) () >>=? fun endo -> - let endo = Operation.pack endo in - bake b1 ~operations:[endo] >>=? fun b2 -> - let ctxt = Context.B (preend_branch genesis b1 b2) in - let endorsed_block = preendorsed_block genesis b1 b2 in - get_delegate_and_slot genesis b1 b2 >>=? fun (delegate, slot) -> - Op.preendorsement - ?delegate - ?slot - ~round:preend_round - ~endorsed_block - ctxt - () - >>=? fun p -> - let operations = endo :: (mk_ops @@ Operation.pack p) in - bake - ~payload_round - ~locked_round - ~policy:(By_round block_round) - ~operations - b1 - >>= fun res -> - match (res, post_process) with - | (Ok ok, Ok success_fun) -> success_fun ok - | (Error _, Error (error_title, _error_category)) -> - Assert.proto_error_with_info ~loc res error_title - | (Ok _, Error _) -> Assert.error ~loc res (fun _ -> false) - | (Error _, Ok _) -> Assert.error ~loc res (fun _ -> false) - - (****************************************************************) - (* Tests *) - (****************************************************************) - - (** OK: bake a block "_b2_1" at round 1, containing a PQC and a locked - round of round 0 *) - let include_preendorsement_in_block_with_locked_round () = - aux_simple_preendorsement_inclusion ~loc:__LOC__ () >>=? fun _ -> - return_unit - - (** KO: bake a block "_b2_1" at round 1, containing a PQC and a locked - round of round 0. But the preendorsement is on a bad branch *) - let test_preendorsement_with_bad_branch () = - aux_simple_preendorsement_inclusion - (* preendorsement should be on branch _pred to be valid *) - ~preend_branch:(fun predpred _pred _curr -> predpred) - ~loc:__LOC__ - ~post_process:(Error ("Wrong consensus operation branch", `Temporary)) - () - - (** KO: The same preendorsement injected twice in the PQC *) - let duplicate_preendorsement_in_pqc () = - aux_simple_preendorsement_inclusion (* inject the op twice *) - ~mk_ops:(fun op -> [op; op]) - ~loc:__LOC__ - ~post_process:(Error ("double inclusion of consensus operation", `Branch)) - () - - (** KO: locked round declared in the block is not smaller than - that block's round *) - let locked_round_not_before_block_round () = - aux_simple_preendorsement_inclusion - (* default locked_round = 0 < block_round = 1 for this aux function *) - ~block_round:0 - ~loc:__LOC__ - ~post_process:(Error ("Locked round not smaller than round", `Permanent)) - () - - (** KO: because we announce a locked_round, but we don't provide the - preendorsement quorum certificate in the operations *) - let with_locked_round_in_block_but_without_any_pqc () = - (* This test only fails in Application mode. If full_construction mode, the - given locked_round is not used / checked. Moreover, the test succeed in - this case. - *) - let post_process = - if Mode.baking_mode == Block.Application then - Error ("Wrong fitness", `Permanent) - else Ok (fun _ -> return_unit) - in - aux_simple_preendorsement_inclusion - (* with declared locked_round but without a PQC in the ops *) - ~mk_ops:(fun _p -> []) - ~loc:__LOC__ - ~post_process - () - - (** KO: The preendorsed block is the pred one, not the current one *) - let preendorsement_has_wrong_level () = - aux_simple_preendorsement_inclusion - (* preendorsement should be for _curr block to be valid *) - ~preendorsed_block:(fun _predpred pred _curr -> pred) - ~loc:__LOC__ - ~post_process:(Error ("wrong level for consensus operation", `Permanent)) - () - - (** OK: explicit the correct endorser and preendorsing slot in the test *) - let preendorsement_in_block_with_good_slot () = - aux_simple_preendorsement_inclusion - ~get_delegate_and_slot:(fun _predpred _pred curr -> - let module V = Plugin.RPC.Validators in - Context.get_endorsers (B curr) >>=? function - | {V.delegate; slots = s :: _ as slots; _} :: _ -> - return (Some (delegate, slots), Some s) - | _ -> assert false - (* there is at least one endorser with a slot *)) - ~loc:__LOC__ - () - - (** KO: the used slot for injecting the endorsement is not the canonical one *) - let preendorsement_in_block_with_wrong_slot () = - aux_simple_preendorsement_inclusion - ~get_delegate_and_slot:(fun _predpred _pred curr -> - let module V = Plugin.RPC.Validators in - Context.get_endorsers (B curr) >>=? function - | {V.delegate; V.slots = _ :: non_canonical_slot :: _ as slots; _} :: _ - -> - return (Some (delegate, slots), Some non_canonical_slot) - | _ -> assert false - (* there is at least one endorser with a slot *)) - ~loc:__LOC__ - ~post_process:(Error ("wrong slot", `Permanent)) - () - - (** KO: the delegate tries to injects with a canonical slot of another delegate *) - let preendorsement_in_block_with_wrong_signature () = - aux_simple_preendorsement_inclusion - ~get_delegate_and_slot:(fun _predpred _pred curr -> - let module V = Plugin.RPC.Validators in - Context.get_endorsers (B curr) >>=? function - | {V.delegate; _} :: {V.slots = s :: _ as slots; _} :: _ -> - (* the canonical slot s is not owned by the delegate "delegate" !*) - return (Some (delegate, slots), Some s) - | _ -> assert false - (* there is at least one endorser with a slot *)) - ~loc:__LOC__ - ~post_process:(Error ("Invalid operation signature", `Permanent)) - () - - (** KO: cannot have a locked_round higher than attached PQC's round *) - let locked_round_is_higher_than_pqc_round () = - (* This test only fails in Application mode. If full_construction mode, the - given locked_round is not used / checked. Moreover, the test succeed in - this case. - *) - let post_process = - if Mode.baking_mode == Application then - Error ("wrong round for consensus operation", `Permanent) - else Ok (fun _ -> return_unit) - in - aux_simple_preendorsement_inclusion - ~preend_round:Round.zero - ~locked_round:(Some (Round.succ Round.zero)) - ~block_round:2 - ~loc:__LOC__ - ~post_process - () - - let my_tztest title test = - Tztest.tztest (Format.sprintf "%s: %s" name title) test - - let tests = - [ - my_tztest - "ok: include_preendorsement_in_block_with_locked_round" - `Quick - include_preendorsement_in_block_with_locked_round; - my_tztest - "ko: test_preendorsement_with_bad_branch" - `Quick - test_preendorsement_with_bad_branch; - my_tztest - "ko: duplicate_preendorsement_in_pqc" - `Quick - duplicate_preendorsement_in_pqc; - my_tztest - "ko:locked_round_not_before_block_round" - `Quick - locked_round_not_before_block_round; - my_tztest - "ko: with_locked_round_in_block_but_without_any_pqc" - `Quick - with_locked_round_in_block_but_without_any_pqc; - my_tztest - "ko: preendorsement_has_wrong_level" - `Quick - preendorsement_has_wrong_level; - my_tztest - "ok: preendorsement_in_block_with_good_slot" - `Quick - preendorsement_in_block_with_good_slot; - my_tztest - "ko: preendorsement_in_block_with_wrong_slot" - `Quick - preendorsement_in_block_with_wrong_slot; - my_tztest - "ko: preendorsement_in_block_with_wrong_signature" - `Quick - preendorsement_in_block_with_wrong_signature; - my_tztest - "ko: locked_round_is_higher_than_pqc_round" - `Quick - locked_round_is_higher_than_pqc_round; - ] -end diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_qty.ml b/src/proto_012_Psithaca/lib_protocol/test/test_qty.ml deleted file mode 100644 index 4494f0778bfd..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_qty.ml +++ /dev/null @@ -1,159 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (quantities) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^qty$" - Subject: On tez quantities. -*) - -open Protocol - -let known_ok_tez_literals = - [ - (0L, "0"); - (10L, "0.00001"); - (100L, "0.0001"); - (1_000L, "0.001"); - (10_000L, "0.01"); - (100_000L, "0.1"); - (1_000_000L, "1"); - (10_000_000L, "10"); - (100_000_000L, "100"); - (1_000_000_000L, "1000"); - (10_000_000_000L, "10000"); - (100_000_000_000L, "100000"); - (1_000_000_000_000L, "1000000"); - (1_000_000_000_001L, "1000000.000001"); - (1_000_000_000_010L, "1000000.00001"); - (1_000_000_000_100L, "1000000.0001"); - (1_000_000_001_000L, "1000000.001"); - (1_000_000_010_000L, "1000000.01"); - (1_000_000_100_000L, "1000000.1"); - (123_123_123_123_123_123L, "123123123123.123123"); - (999_999_999_999_999_999L, "999999999999.999999"); - ] - -let known_bad_tez_literals = - [ - "10000."; - "100,."; - "100,"; - "1,0000"; - "0.0000,1"; - "0.00,1"; - "0,1"; - "HAHA"; - "0.000,000,1"; - "0.0000000"; - "9,999,999,999,999.999,999"; - ] - -let fail expected given msg = - Format.kasprintf - Stdlib.failwith - "@[%s@ expected: %s@ got: %s@]" - msg - expected - given - -let fail_msg fmt = Format.kasprintf (fail "" "") fmt - -let default_printer _ = "" - -(** Literals which are supposed to be parsed correctly. *) -let test_known_tez_literals () = - List.iter - (fun (v, s) -> - let vv = Tez_repr.of_mutez v in - let vs = Tez_repr.of_string s in - let vs' = - Tez_repr.of_string (String.concat "" (String.split_on_char ',' s)) - in - let vv = - match vv with None -> fail_msg "could not unopt %Ld" v | Some vv -> vv - in - let vs = - match vs with None -> fail_msg "could not unopt %s" s | Some vs -> vs - in - let vs' = - match vs' with - | None -> fail_msg "could not unopt %s" s - | Some vs' -> vs' - in - assert (vv = vs) ; - assert (vv = vs') ; - assert (Tez_repr.to_string vv = s)) - known_ok_tez_literals ; - List.iter - (fun s -> - let vs = Tez_repr.of_string s in - assert (vs = None)) - known_bad_tez_literals ; - return_unit - -(** Randomly generated tez value which is printed into a string then - parsed again for their equality. *) -let test_random_tez_literals () = - for _ = 0 to 100_000 do - let v = Random.int64 12L in - let vv = Tez_repr.of_mutez v in - let vv = - match vv with None -> fail_msg "could not unopt %Ld" v | Some vv -> vv - in - let s = Tez_repr.to_string vv in - let vs = Tez_repr.of_string s in - let s' = String.concat "" (String.split_on_char ',' s) in - let vs' = Tez_repr.of_string s' in - assert (vs <> None) ; - assert (vs' <> None) ; - (match vs with - | None -> assert false - | Some vs -> - let rev = Tez_repr.to_mutez vs in - assert (v = rev)) ; - match vs' with - | None -> assert false - | Some vs' -> - let rev = Tez_repr.to_mutez vs' in - assert (v = rev) - done ; - return_unit - -let tests = - [ - ("tez-literals", fun _ -> test_known_tez_literals ()); - ("rnd-tez-literals", fun _ -> test_random_tez_literals ()); - ] - -let wrap (n, f) = - Alcotest_lwt.test_case n `Quick (fun _ () -> - f () >|= function - | Ok () -> () - | Error error -> - Format.kasprintf Stdlib.failwith "%a" pp_print_trace error) - -let tests = List.map wrap tests diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_receipt.ml b/src/proto_012_Psithaca/lib_protocol/test/test_receipt.ml deleted file mode 100644 index eddfe8337fb2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_receipt.ml +++ /dev/null @@ -1,93 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (token) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^receipt" - Subject: Test receipt endocings. -*) - -open Protocol -open Alpha_context -open Data_encoding - -let random_amount () = - match Tez.of_mutez (Int64.add 1L (Random.int64 100L)) with - | None -> assert false - | Some x -> x - -(** Test that [decode (encode balance_updates) = balance_updates]. *) -let test_encodings balance = - Random.init 0 ; - let am = random_amount () in - let r1 = Receipt.(balance, Debited am, Protocol_migration) in - let r2 = Receipt.(balance, Credited am, Protocol_migration) in - let r3 = Receipt.(balance, Debited am, Subsidy) in - let r4 = Receipt.(balance, Credited am, Subsidy) in - let r5 = Receipt.(balance, Debited am, Simulation) in - let r6 = Receipt.(balance, Credited am, Simulation) in - let r7 = Receipt.(balance, Debited am, Block_application) in - let r8 = Receipt.(balance, Credited am, Block_application) in - let coded = - Json.construct - Receipt.balance_updates_encoding - [r1; r2; r3; r4; r5; r6; r7; r8] - in - let decoded = Json.destruct Receipt.balance_updates_encoding coded in - match decoded with - | [r1'; r2'; r3'; r4'; r5'; r6'; r7'; r8'] -> - assert ( - r1' = r1 && r2' = r2 && r3' = r3 && r4' = r4 && r5 = r5' && r6 = r6' - && r7 = r7' && r8 = r8') ; - return_unit - | _ -> assert false - -let test_encodings () = - let open Receipt in - let pkh = Signature.Public_key_hash.zero in - test_encodings (Contract (Contract.implicit_contract pkh)) >>=? fun () -> - test_encodings (Legacy_rewards (pkh, Cycle.root)) >>=? fun () -> - test_encodings Block_fees >>=? fun () -> - test_encodings (Legacy_deposits (pkh, Cycle.root)) >>=? fun () -> - test_encodings (Deposits pkh) >>=? fun () -> - test_encodings Nonce_revelation_rewards >>=? fun () -> - test_encodings Double_signing_evidence_rewards >>=? fun () -> - test_encodings Endorsing_rewards >>=? fun () -> - test_encodings Baking_rewards >>=? fun () -> - test_encodings Baking_bonuses >>=? fun () -> - test_encodings (Legacy_fees (pkh, Cycle.root)) >>=? fun () -> - test_encodings Storage_fees >>=? fun () -> - test_encodings Double_signing_punishments >>=? fun () -> - test_encodings (Lost_endorsing_rewards (pkh, Random.bool (), Random.bool ())) - >>=? fun () -> - test_encodings Liquidity_baking_subsidies >>=? fun () -> - test_encodings Burned >>=? fun () -> - test_encodings (Commitments Blinded_public_key_hash.zero) >>=? fun () -> - test_encodings Bootstrap >>=? fun () -> - test_encodings Invoice >>=? fun () -> - test_encodings Initial_commitments >>=? fun () -> test_encodings Minted - -let tests = Tztest.[tztest "receipt - encoding" `Quick test_encodings] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_reveal.ml b/src/proto_012_Psithaca/lib_protocol/test/test_reveal.ml deleted file mode 100644 index d85e040313e6..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_reveal.ml +++ /dev/null @@ -1,109 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (revelation) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^revelation$" - Subject: On the reveal operation. -*) - -(** Test for the [Reveal] operation. *) - -open Protocol -open Alpha_context -open Test_tez - -let ten_tez = of_int 10 - -let test_simple_reveal () = - Context.init ~consensus_threshold:0 1 >>=? fun (blk, contracts) -> - let c = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - let new_c = Account.new_account () in - let new_contract = Alpha_context.Contract.implicit_contract new_c.pkh in - (* Create the contract *) - Op.transaction (B blk) c new_contract Tez.one >>=? fun operation -> - Block.bake blk ~operation >>=? fun blk -> - (Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function - | true -> Stdlib.failwith "Unexpected revelation" - | false -> ()) - >>=? fun () -> - (* Reveal the contract *) - Op.revelation (B blk) new_c.pk >>=? fun operation -> - Block.bake blk ~operation >>=? fun blk -> - Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function - | true -> () - | false -> Stdlib.failwith "New contract revelation failed." - -let test_empty_account_on_reveal () = - Context.init ~consensus_threshold:0 1 >>=? fun (blk, contracts) -> - let c = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - let new_c = Account.new_account () in - let new_contract = Alpha_context.Contract.implicit_contract new_c.pkh in - let amount = Tez.one_mutez in - (* Create the contract *) - Op.transaction (B blk) c new_contract amount >>=? fun operation -> - Block.bake blk ~operation >>=? fun blk -> - (Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function - | true -> Stdlib.failwith "Unexpected revelation" - | false -> ()) - >>=? fun () -> - (* Reveal the contract *) - Op.revelation ~fee:amount (B blk) new_c.pk >>=? fun operation -> - Incremental.begin_construction blk >>=? fun inc -> - Incremental.add_operation inc operation >>=? fun _ -> - Block.bake blk ~operation >>=? fun blk -> - Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function - | false -> () - | true -> Stdlib.failwith "Empty account still exists and is revealed." - -let test_not_enough_found_for_reveal () = - Context.init 1 >>=? fun (blk, contracts) -> - let c = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - let new_c = Account.new_account () in - let new_contract = Alpha_context.Contract.implicit_contract new_c.pkh in - (* Create the contract *) - Op.transaction (B blk) c new_contract Tez.one_mutez >>=? fun operation -> - Block.bake blk ~operation >>=? fun blk -> - (Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function - | true -> Stdlib.failwith "Unexpected revelation" - | false -> ()) - >>=? fun () -> - (* Reveal the contract *) - Op.revelation ~fee:Tez.fifty_cents (B blk) new_c.pk >>=? fun operation -> - Block.bake blk ~operation >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - -let tests = - [ - Tztest.tztest "simple reveal" `Quick test_simple_reveal; - Tztest.tztest "empty account on reveal" `Quick test_empty_account_on_reveal; - Tztest.tztest - "not enough found for reveal" - `Quick - test_not_enough_found_for_reveal; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_round_repr.ml b/src/proto_012_Psithaca/lib_protocol/test/test_round_repr.ml deleted file mode 100644 index af81ae884060..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_round_repr.ml +++ /dev/null @@ -1,541 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: protocol - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^round$" - Subject: test the Round_repr module -*) - -open Protocol -open Alpha_context - -let ( >>>=? ) v f = v >|= Environment.wrap_tzresult >>=? f - -let ( >>>?= ) v f = v |> Environment.wrap_tzresult >>?= f - -let ( >>>? ) v f = v |> Environment.wrap_tzresult >>? f - -type round_test = { - (* input: round; output: round duration *) - round_duration : (int * int) list; - (* input: level offset; output: round, round offset *) - round_and_offset : (int * (int * int)) list; - (* input: pred_ts, pred_round, round; output: ts *) - timestamp_of_round : ((int * int * int) * int) list; - (* input: pred_ts, pred_round, ts; output: round *) - round_of_timestamp : ((int * int * int) * int) list; -} - -(* an association list of the input, output values *) -let case_3_4 = - { - round_duration = [(0, 3); (1, 4); (2, 5); (3, 6)]; - round_and_offset = - [ - (0, (0, 0)); - (1, (0, 1)); - (2, (0, 2)); - (3, (1, 0)); - (4, (1, 1)); - (5, (1, 2)); - (6, (1, 3)); - (7, (2, 0)); - (8, (2, 1)); - ]; - timestamp_of_round = [((100, 0, 6), 136); ((100, 1, 6), 137)]; - round_of_timestamp = - [ - ((100, 0, 121), 4); - ((100, 0, 122), 4); - ((100, 0, 123), 4); - ((100, 0, 124), 4); - ((100, 0, 125), 4); - ((100, 0, 126), 4); - ((100, 1, 121), 3); - ((100, 1, 122), 4); - ((100, 1, 123), 4); - ((100, 1, 124), 4); - ((100, 1, 125), 4); - ((100, 1, 126), 4); - ]; - } - -let case_3_6 = - { - round_duration = - [ - (0, 3); - (1, 6); - (2, 9); - (3, 12); - (4, 15); - (5, 18); - (6, 21); - (7, 24); - (8, 27); - ]; - round_and_offset = - [ - (0, (0, 0)); - (1, (0, 1)); - (2, (0, 2)); - (3, (1, 0)); - (4, (1, 1)); - (5, (1, 2)); - (6, (1, 3)); - (7, (1, 4)); - (8, (1, 5)); - (9, (2, 0)); - (10, (2, 1)); - (11, (2, 2)); - (97, (7, 13)); - ]; - timestamp_of_round = - [ - ((100, 0, 0), 103); - ((100, 1, 0), 106); - ((100, 0, 6), 166); - ((100, 1, 6), 169); - ]; - round_of_timestamp = - [ - ((100, 0, 103), 0); - ((100, 0, 104), 0); - ((100, 0, 105), 0); - ((100, 0, 106), 1); - ((100, 0, 111), 1); - ((100, 0, 112), 2); - ((100, 0, 120), 2); - ((100, 0, 121), 3); - ((100, 0, 132), 3); - ((100, 0, 133), 4); - ((100, 1, 106), 0); - ((100, 1, 107), 0); - ((100, 1, 108), 0); - ((100, 1, 109), 1); - ((100, 1, 114), 1); - ((100, 1, 115), 2); - ]; - } - -let test_cases = - [ - (* (first_round_duration, delay_increment_per_round), test_case_expectations *) - ((3, 1), case_3_4, "case_3_4"); - ((3, 3), case_3_6, "case_3_6"); - ] - -let round_of_int i = Round_repr.of_int i |> Environment.wrap_tzresult - -let mk_round_durations first_round_duration delay_increment_per_round = - let first_round_duration = - Period_repr.of_seconds_exn @@ Int64.of_int first_round_duration - in - let delay_increment_per_round = - Period_repr.of_seconds_exn @@ Int64.of_int delay_increment_per_round - in - (* We assume test specifications do respect round_durations - invariants and cannot fail *) - Stdlib.Option.get - @@ Round_repr.Durations.create_opt - ~first_round_duration - ~delay_increment_per_round - -let process_test_case (round_durations, ios, _) = - let open Round_repr in - List.iter_es - (fun (i, o) -> - round_of_int i >>?= fun round -> - let dur = Durations.round_duration round_durations round in - Assert.equal_int64 - ~loc:__LOC__ - (Int64.of_int o) - (Period_repr.to_seconds dur)) - ios.round_duration - >>=? fun () -> - let open Internals_for_test in - (* test [round_and_offset] *) - List.iter_es - (fun (level_offset, (round, ro)) -> - let level_offset = - Period_repr.of_seconds_exn (Int64.of_int level_offset) - in - Environment.wrap_tzresult (round_and_offset round_durations ~level_offset) - >>?= fun round_and_offset -> - Assert.equal_int32 - ~loc:__LOC__ - (Int32.of_int round) - (Round_repr.to_int32 round_and_offset.round) - >>=? fun () -> - Assert.equal_int64 - ~loc:__LOC__ - (Int64.of_int ro) - (Period_repr.to_seconds round_and_offset.offset)) - ios.round_and_offset - >>=? fun () -> - (* test [timestamp_of_round] *) - List.iter_es - (fun ((pred_ts, pred_round, round), o) -> - let predecessor_timestamp = Time_repr.of_seconds (Int64.of_int pred_ts) in - Lwt.return - ( Round_repr.of_int pred_round >>? fun predecessor_round -> - Round_repr.of_int round >>? fun round -> - timestamp_of_round - round_durations - ~predecessor_timestamp - ~predecessor_round - ~round ) - >>>=? fun ts -> - Assert.equal_int64 ~loc:__LOC__ (Int64.of_int o) (Time_repr.to_seconds ts)) - ios.timestamp_of_round - >>=? fun () -> - (* test [round_of_timestamp] *) - List.iter_es - (fun ((pred_ts, pred_round, ts), o) -> - let predecessor_timestamp = Time_repr.of_seconds (Int64.of_int pred_ts) in - Lwt.return - ( Round_repr.of_int pred_round >>? fun predecessor_round -> - round_of_timestamp - round_durations - ~predecessor_timestamp - ~predecessor_round - ~timestamp:(Time_repr.of_seconds (Int64.of_int ts)) ) - >>>=? fun round -> - Assert.equal_int32 - ~loc:__LOC__ - (Int32.of_int o) - (Round_repr.to_int32 round)) - ios.round_of_timestamp - -let test_round () = - let final_test_cases = - List.map - (fun ((first_round_duration, delay_increment_per_round), ios, name) -> - ( mk_round_durations first_round_duration delay_increment_per_round, - ios, - name )) - test_cases - in - (* TODO this could be run in the error monad instead of lwt *) - List.iter_es process_test_case final_test_cases - -let ts_add ts period = - match Timestamp.(ts +? period) with - | Ok ts' -> ts' - | Error _ -> Environment.Pervasives.failwith "timestamp add" - -let test_round_of_timestamp () = - let duration0 = Period.of_seconds_exn 1L in - Environment.wrap_tzresult - @@ Round.Durations.create - ~first_round_duration:duration0 - ~delay_increment_per_round:Period.one_second - >>?= fun round_durations -> - let predecessor_timestamp = Time.Protocol.epoch in - let level_start = ts_add predecessor_timestamp duration0 in - let rec loop ~expected_round ~elapsed_time = - if elapsed_time < 1000 then - let timestamp = - ts_add level_start (Period.of_seconds_exn (Int64.of_int elapsed_time)) - in - match - Round.round_of_timestamp - round_durations - ~predecessor_timestamp - ~timestamp - ~predecessor_round:Round.zero - with - | Ok round -> - Assert.equal_int32 - ~loc:__LOC__ - (Round.to_int32 round) - (Int32.of_int expected_round) - >>=? fun () -> - let elapsed_time = elapsed_time + (expected_round + 1) - and expected_round = 1 + expected_round in - loop ~expected_round ~elapsed_time - | Error _ -> failwith "error " - else return_unit - in - loop ~elapsed_time:0 ~expected_round:0 - -let round_of_timestamp_perf (duration0_int64, dipr) = - let duration0 = Period.of_seconds_exn duration0_int64 in - let delay_increment_per_round = Period.of_seconds_exn dipr in - let round_durations = - Stdlib.Option.get - @@ Round.Durations.create_opt - ~first_round_duration:duration0 - ~delay_increment_per_round - in - let predecessor_timestamp = Time.Protocol.epoch in - let level_start = ts_add predecessor_timestamp duration0 in - let max_ts = Int64.(sub (of_int32 Int32.max_int) duration0_int64) in - let rec loop i = - if i >= 0L then ( - let timestamp = - ts_add level_start (Period.of_seconds_exn (Int64.sub max_ts i)) - in - let t0 = Unix.gettimeofday () in - Round.round_of_timestamp - round_durations - ~predecessor_timestamp - ~timestamp - ~predecessor_round:Round.zero - >>? fun _round -> - let t1 = Unix.gettimeofday () in - let time = t1 -. t0 in - assert (time < 0.01) ; - loop (Int64.pred i)) - else ok () - in - Environment.wrap_tzresult (loop 1000L) >>?= fun () -> return_unit - -let default_round_durations_list = - [(1L, 1L); (1L, 2L); (1L, 3L); (2L, 3L); (2L, 4L)] - -let test_round_of_timestamp_perf () = - List.iter_es round_of_timestamp_perf default_round_durations_list - -let timestamp_of_round_perf (duration0_int64, dipr) = - let duration0 = Period.of_seconds_exn duration0_int64 in - let delay_increment_per_round = Period.of_seconds_exn dipr in - let round_durations = - Stdlib.Option.get - @@ Round.Durations.create_opt - ~first_round_duration:duration0 - ~delay_increment_per_round - in - let predecessor_timestamp = Time.Protocol.epoch in - let rec loop i = - if i >= 0l then ( - Round.of_int32 Int32.(sub max_int i) >>? fun round -> - let t0 = Unix.gettimeofday () in - Round.timestamp_of_round - round_durations - ~predecessor_timestamp - ~predecessor_round:Round.zero - ~round - >>? fun _ts -> - let t1 = Unix.gettimeofday () in - let time = t1 -. t0 in - assert (time < 0.01) ; - loop (Int32.pred i)) - else ok () - in - Environment.wrap_tzresult (loop 1000l) >>?= fun () -> return_unit - -let test_timestamp_of_round_perf () = - List.iter_es timestamp_of_round_perf default_round_durations_list - -let test_error_is_triggered_for_too_high_timestamp () = - let round_durations = - Stdlib.Option.get - @@ Round.Durations.create_opt - ~first_round_duration:Period.one_second - ~delay_increment_per_round:Period.one_second - in - - let predecessor_timestamp = Time.Protocol.epoch in - let res = - Round.round_of_timestamp - round_durations - ~predecessor_timestamp - ~predecessor_round:Round.zero - ~timestamp:(Time_repr.of_seconds Int64.max_int) - in - let res = Environment.wrap_tzresult res in - match res with - | Error _ -> - Assert.proto_error ~loc:__LOC__ res (function err -> - let error_info = - Error_monad.find_info_of_error (Environment.wrap_tzerror err) - in - error_info.title = "level offset too high") - | Ok _ -> Assert.error ~loc:__LOC__ res (fun _ -> false) - -let rec ( --> ) i j = - (* [i; i+1; ...; j] *) - if Compare.Int.(i > j) then [] else i :: (succ i --> j) - -let ts_of_round_inverse (duration0_int64, dipr) round_int = - let first_round_duration = Period.of_seconds_exn duration0_int64 in - let delay_increment_per_round = Period.of_seconds_exn dipr in - let round_durations = - Stdlib.Option.get - @@ Round.Durations.create_opt - ~first_round_duration - ~delay_increment_per_round - in - let predecessor_timestamp = Time.Protocol.epoch in - let predecessor_round = Round.zero in - Round.of_int round_int >>>?= fun round -> - Round.timestamp_of_round - round_durations - ~predecessor_timestamp - ~predecessor_round - ~round - >>>?= fun timestamp -> - Round.round_of_timestamp - round_durations - ~predecessor_timestamp - ~predecessor_round - ~timestamp - >>>?= fun round' -> - Round.to_int round' >>>?= fun round' -> - Assert.equal_int ~loc:__LOC__ round_int round' - -let test_ts_of_round_inverse () = - List.iter_es - (fun durations -> - List.iter_es - (ts_of_round_inverse durations) - ((0 --> 20) @ (60000 --> 60010))) - default_round_durations_list - >>=? fun () -> - List.iter_es - (ts_of_round_inverse (1L, 1L)) - (List.map (fun i -> Int32.to_int Int32.max_int - i) (1 --> 20)) - -let round_of_ts_inverse ~first_round_duration ~delay_increment_per_round ts = - Format.printf "ts = %Ld@." ts ; - let first_round_duration = Period.of_seconds_exn first_round_duration in - let delay_increment_per_round = - Period.of_seconds_exn delay_increment_per_round - in - Round.Durations.create ~first_round_duration ~delay_increment_per_round - >>>?= fun round_durations -> - let predecessor_timestamp = Time.Protocol.epoch in - let predecessor_round = Round.zero in - Timestamp.( +? ) predecessor_timestamp first_round_duration - >>>?= fun level_start -> - let start_of_round timestamp = - Round.round_of_timestamp - round_durations - ~predecessor_timestamp - ~predecessor_round - ~timestamp - >>>? fun round -> - Round.timestamp_of_round - round_durations - ~predecessor_timestamp - ~predecessor_round - ~round - >>>? fun t -> ok (round, t) - in - Period.of_seconds_exn ts |> Timestamp.( +? ) level_start - >>>?= fun timestamp -> - start_of_round timestamp >>?= fun (round, ts_start_of_round) -> - Assert.leq_int64 - ~loc:__LOC__ - (Timestamp.to_seconds ts_start_of_round) - (Timestamp.to_seconds timestamp) - >>=? fun () -> - let pred ts = Period.one_second |> Timestamp.( - ) ts in - let rec iter ts = - start_of_round ts >>?= fun (round', ts_start_of_round') -> - Assert.equal_int64 - ~loc:__LOC__ - (Timestamp.to_seconds ts_start_of_round) - (Timestamp.to_seconds ts_start_of_round') - >>=? fun () -> - Assert.equal_int32 - ~loc:__LOC__ - (Round.to_int32 round) - (Round.to_int32 round') - >>=? fun () -> - if Timestamp.(ts > ts_start_of_round') then iter (pred ts) else return_unit - in - if Timestamp.(timestamp > ts_start_of_round) then iter (pred timestamp) - else return_unit - -let test_round_of_ts_inverse () = - List.iter_es - (fun (first_round_duration, delay_increment_per_round) -> - List.iter_es - (fun ts -> - round_of_ts_inverse - ~first_round_duration - ~delay_increment_per_round - (Int64.of_int ts)) - ((0 --> 20) @ (60000 --> 60010))) - default_round_durations_list - >>=? fun () -> - List.iter_es - (fun ts -> - Format.printf "%Ld@." ts ; - round_of_ts_inverse - ~first_round_duration:1L - ~delay_increment_per_round:2L - ts) - (List.map - (fun i -> Int64.of_int (Int32.to_int Int32.max_int - i)) - (0 --> 20)) - -let test_level_offset_of_round () = - let rd1 = - let first_round_duration = 3 in - let delay_increment_per_round = 1 in - mk_round_durations first_round_duration delay_increment_per_round - in - List.iter_es - (fun (round_durations, tests) -> - List.iter_es - (fun (round, expected_offset) -> - Lwt.return @@ Environment.wrap_tzresult @@ Round_repr.of_int round - >>=? fun round -> - Lwt.return @@ Environment.wrap_tzresult - @@ Round_repr.level_offset_of_round round_durations ~round - >>=? fun computed_offset -> - Assert.equal_int64 - ~loc:__LOC__ - (Period_repr.to_seconds computed_offset) - (Int64.of_int expected_offset)) - tests) - [ - (rd1, [(0, 0); (1, 3); (2, 7)]); - (mk_round_durations 3 3, [(0, 0); (1, 3); (2, 9); (3, 18)]); - ] - -let tests = - Tztest. - [ - tztest "test_level_offset_of_round" `Quick test_level_offset_of_round; - tztest "test Round_duration" `Quick test_round; - tztest "round_of_timestamp" `Quick test_round_of_timestamp; - tztest "round_of_timestamp_perf" `Quick test_round_of_timestamp_perf; - tztest "timestamp_of_round_perf" `Quick test_timestamp_of_round_perf; - tztest - "test level offset too high error is triggered" - `Quick - test_error_is_triggered_for_too_high_timestamp; - tztest "round_of_ts (ts_of_round r) = r" `Quick test_ts_of_round_inverse; - tztest - "ts_of_round (round_of_ts ts) <= ts" - `Quick - test_round_of_ts_inverse; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_sampler.ml b/src/proto_012_Psithaca/lib_protocol/test/test_sampler.ml deleted file mode 100644 index 630794d84a96..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_sampler.ml +++ /dev/null @@ -1,270 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol Library - Invocation: dune exec src/proto_alpha/lib_protocol/test/test_sampler.exe - Subject: Sampler -*) - -open Lib_test.Qcheck_helpers -open Protocol.Sampler - -(* ------------------------------------------------------------------------- *) -(* Helpers *) - -module Int = struct - include Int - - let hash = Hashtbl.hash -end - -let equal_array elt_eq arr1 arr2 = - Array.length arr1 = Array.length arr2 - && Stdlib.List.for_all2 elt_eq (Array.to_list arr1) (Array.to_list arr2) - -(* Support of a distribution on Z (sorted, with potential duplicates) *) -let support cmp array = - Array.to_seq array |> Seq.map fst |> List.of_seq |> List.sort cmp - |> Array.of_list - -(* Support of a distribution on Z (sorted, without duplicates) *) -let support_uniq cmp array = - Array.to_seq array |> Seq.map fst |> List.of_seq |> List.sort_uniq cmp - |> Array.of_list - -module type Std = sig - type t - - val equal : t -> t -> bool - - val compare : t -> t -> int - - val hash : t -> int -end - -module Helpers = struct - let sample_n_times (total : int) sample = - let rec loop n acc = - if n = 0 then acc - else - let res = sample () in - loop (n - 1) (res :: acc) - in - loop total [] - - let empirical_distribution : - type a. - (module Std with type t = a) -> - nsamples:int -> - (unit -> a) -> - (a * int) array = - fun (module H) ~nsamples sampler -> - let module Table = Hashtbl.Make (H) in - let samples = sample_n_times nsamples sampler in - let table = Table.create 127 in - List.iter - (fun sample -> - let count = Option.value ~default:0 (Table.find table sample) in - Table.replace table sample (count + 1)) - samples ; - let result = Table.to_seq table |> Array.of_seq in - (* check that the support of [result] has no duplicate elements (should - be true since we use [replace]). *) - assert ( - equal_array - H.equal - (support H.compare result) - (support_uniq H.compare result)) ; - result -end - -let normalize : ('a * int) array -> ('a * Q.t) array = - fun empirical -> - let total = - Array.fold_left - (fun acc (_, weight) -> Z.add (Z.of_int weight) acc) - Z.zero - empirical - in - Array.map (fun (n, weight) -> (n, Q.(Z.of_int weight /// total))) empirical - -let pp_dist pp fmtr dist = - let l = Array.to_list dist in - Format.pp_print_list - ~pp_sep:(fun fmtr () -> Format.fprintf fmtr ",") - (fun fmtr (elt, w) -> Format.fprintf fmtr "(%a, %f)" pp elt (Q.to_float w)) - fmtr - l - -let linf (dist : ('a * Q.t) array) pmf = - Array.fold_left (fun acc (n, q) -> Q.(max acc (abs (pmf n - q)))) Q.zero dist - -(* ------------------------------------------------------------------------- *) - -let state = - Random.State.make - [| - 0x1337533D; - 71287309; - 666932349; - 719132214; - 461480042; - 387006837; - 443018964; - 450865457; - 901711679; - 833353016; - 397060904; - |] - -module Make_test (Mass : sig - include Mass - - val to_float : t -> float -end) (S : sig - val sample : int_bound:int -> mass_bound:Mass.t -> int * Mass.t -end) = -struct - let make p = - let module Probability = Internal_for_tests.Make (Mass) in - let measure = List.mapi (fun i p -> (i, p)) p in - let total_mass = List.fold_left Mass.add Mass.zero p in - let state = Probability.create measure in - let sampler = Probability.sample state in - let empirical = - normalize - @@ Helpers.empirical_distribution - (module Int) - ~nsamples:5_000_000 - (fun () -> sampler S.sample) - in - (* We need to rescale the empirical to match that the total mass is not necessarily one. *) - let empirical = - let rescaling = Q.of_float (Mass.to_float total_mass) in - Array.map (fun (x, q) -> (x, Q.mul q rescaling)) empirical - in - (* map the mass to Q to better measure the error *) - let truth = - let array = - measure |> List.to_seq - |> Seq.map (fun (_, mass) -> Q.of_float (Mass.to_float mass)) - |> Array.of_seq - in - fun i -> array.(i) - in - let error = linf empirical truth in - let max_error = 0.001 *. Mass.to_float total_mass in - if not Q.(error < Q.of_float max_error) then - QCheck.Test.fail_reportf - "didn't converge (%f)@.%a" - (Q.to_float error) - (pp_dist Format.pp_print_int) - empirical ; - true -end - -(* Testing the alias sampler with float-valued measures *) - -module Probability_mass_float : Mass with type t = float = struct - type t = float - - let encoding = Data_encoding.float - - let zero = 0.0 - - let of_int = float_of_int - - let mul = ( *. ) - - let add = ( +. ) - - let sub = ( -. ) - - let ( = ) = Float.equal - - let ( <= ) (x : t) (y : t) = x <= y - - let ( < ) (x : t) (y : t) = x < y -end - -module Test_float = - Make_test - (struct - include Probability_mass_float - - let to_float x = x - end) - (struct - let sample ~int_bound ~mass_bound = - (Random.State.int state int_bound, Random.State.float state mass_bound) - end) - -(* Testing the alias sampler with Z-valued measures *) - -module Probability_mass_z : Mass with type t = Z.t = struct - let encoding = Data_encoding.z - - include Z - include Z.Compare -end - -module Test_z = - Make_test - (struct - include Probability_mass_z - - let to_float = Z.to_float - end) - (struct - let sample ~int_bound ~mass_bound = - ( Random.State.int state int_bound, - Z.of_int64 (Random.State.int64 state (Z.to_int64 mass_bound)) ) - end) - -let qcheck_wrap = qcheck_wrap ~rand:state - -let alias_float_test = - QCheck.Test.make - ~count:100 - ~name:"alias_float" - QCheck.(list_of_size (Gen.int_range 1 20) pos_float) - Test_float.make - -let alias_z_test = - QCheck.Test.make - ~count:100 - ~name:"alias_z" - QCheck.( - list_of_size - (Gen.int_range 1 20) - (make Gen.(nat >>= fun n -> return (Z.of_int n)))) - Test_z.make - -let () = - Alcotest.run - "Sampling" - [("sampling", qcheck_wrap [alias_float_test; alias_z_test])] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_sapling.ml b/src/proto_012_Psithaca/lib_protocol/test/test_sapling.ml deleted file mode 100644 index 4c5cab0cfaed..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_sapling.ml +++ /dev/null @@ -1,1126 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (Sapling) - Invocation: cd src/proto_alpha/lib_protocol/test - dune exec ./main.exe -- test "^sapling$" - Subject: On the privacy-preserving library Sapling -*) - -open Protocol -open Alpha_context -open Test_tez - -let ( >>??= ) x y = - match x with - | Ok s -> y s - | Error err -> Lwt.return @@ Error (Environment.wrap_tztrace err) - -module Raw_context_tests = struct - open Sapling_helpers.Common - - (* This test adds to the first 100 positions in the commitments tree the - constant value `uncommitted` for which we know the corresponding root and - tests that the returned root is as expected. *) - let commitments_add_uncommitted () = - Context.init 1 >>=? fun (b, _) -> - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >>= wrap - >>=? fun ctx -> - let module H = Tezos_sapling.Core.Client.Hash in - let cm = H.uncommitted ~height:0 in - let expected_root = H.uncommitted ~height:32 in - Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx - >>= wrap - >>=? fun (ctx, id) -> - Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> - List.fold_left_es - (fun ctx pos -> - Sapling_storage.Commitments.get_root ctx id >>= wrap - >>=? fun (ctx, root) -> - assert (root = expected_root) ; - Sapling_storage.Commitments.add - ctx - id - [H.to_commitment cm] - (Int64.of_int pos) - >>= wrap - >>=? fun (ctx, _size) -> - Sapling_storage.Commitments.get_root ctx id >>= wrap - >|=? fun (ctx, root) -> - assert (root = expected_root) ; - ctx) - ctx - (0 -- 99) - >>=? fun _ctx -> return_unit - - (* Nullifiers don't check for duplicates are it's done by verify_update, - however committing to disk twice the same nf causes a storage error by - trying to initialize the same key twice. *) - let nullifier_double () = - Context.init 1 >>=? fun (b, _) -> - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >>= wrap - >>=? fun ctx -> - Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx - >>= wrap - >>=? fun (ctx, id) -> - Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> - let nf = gen_nf () in - let open Sapling_storage in - let state = - {id = Some id; diff = Sapling_storage.empty_diff; memo_size = 0} - in - let state = nullifiers_add state nf in - let state = nullifiers_add state nf in - assert (Compare.List_length_with.(state.diff.nullifiers = 2)) ; - Sapling_storage.Nullifiers.size ctx id >>= wrap >>=? fun disk_size -> - assert (disk_size = 0L) ; - Sapling_storage.apply_diff ctx id state.diff |> assert_error - - (* In this test we add two lists of nullifiers to the state, one is applied to - the context (committed to disk) and one is kept in kept in a diff (only in - memory). We then check that nullifier_mem answers true for those two lists - and false for a third one. *) - let nullifier_test () = - Context.init 1 >>=? fun (b, _) -> - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >>= wrap - >>=? fun ctx -> - Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx - >>= wrap - >>=? fun (ctx, id) -> - Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> - let nf_list_ctx = - List.init ~when_negative_length:() 10 (fun _ -> gen_nf ()) |> function - | Error () -> assert false (* 10 > 0 *) - | Ok nf_list_ctx -> nf_list_ctx - in - let state = - List.fold_left - (fun state nf -> Sapling_storage.nullifiers_add state nf) - {id = Some id; diff = Sapling_storage.empty_diff; memo_size = 0} - nf_list_ctx - in - Sapling_storage.apply_diff ctx id state.diff >>= wrap >>=? fun (ctx, _) -> - let nf_list_diff = - List.init ~when_negative_length:() 10 (fun _ -> gen_nf ()) |> function - | Error () -> assert false (* 10 > 0 *) - | Ok nf_list_diff -> nf_list_diff - in - let state = - List.fold_left - (fun state nf -> Sapling_storage.nullifiers_add state nf) - state - nf_list_diff - in - List.iter_ep - (fun nf -> - Sapling_storage.nullifiers_mem ctx state nf >>= wrap - >>=? fun (_, bool) -> - assert bool ; - return_unit) - (nf_list_ctx @ nf_list_diff) - >>=? fun () -> - let nf_list_absent = - List.init 10 ~when_negative_length:() (fun _ -> gen_nf ()) |> function - | Error () -> assert false (* 10 > 0 *) - | Ok nf_list_absent -> nf_list_absent - in - List.iter_ep - (fun nf -> - Sapling_storage.nullifiers_mem ctx state nf >>= wrap - >>=? fun (_, bool) -> - assert (not bool) ; - return_unit) - nf_list_absent - - (* This test applies a diff with tuples of ciphertext, commitment. Then it - checks the result of get_from with different indexes. *) - let cm_cipher_test () = - Random.self_init () ; - let memo_size = Random.int 200 in - Context.init 1 >>=? fun (b, _) -> - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >>= wrap - >>=? fun ctx -> - Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx - >>= wrap - >>=? fun (ctx, id) -> - Sapling_storage.init ctx id ~memo_size >>= wrap >>=? fun ctx -> - Sapling_storage.state_from_id ctx id >>= wrap >>=? fun (diff, ctx) -> - let list_added = - List.init ~when_negative_length:() 10 (fun _ -> - gen_cm_cipher ~memo_size ()) - |> function - | Error () -> assert false (* 10 > 0 *) - | Ok list_added -> list_added - in - let state = Sapling_storage.add diff list_added in - Sapling_storage.apply_diff ctx id state.diff >>= wrap >>=? fun (ctx, _) -> - let rec test_from from until expected = - if from > until then return_unit - else - Sapling_storage.Ciphertexts.get_from ctx id from >>= wrap - >>=? fun (ctx, result) -> - let expected_cipher = List.map snd expected in - assert (result = expected_cipher) ; - Sapling_storage.Commitments.get_from ctx id from >>= wrap - >>=? fun result -> - let expected_cm = List.map fst expected in - assert (result = expected_cm) ; - test_from - (Int64.succ from) - until - (WithExceptions.Option.get ~loc:__LOC__ @@ List.tl expected) - in - test_from 0L 9L list_added - - (* This test tests the insertion of a list vs inserting one by one. - It does so by checking the equality of the roots. *) - let list_insertion_test () = - Random.self_init () ; - let memo_size = Random.int 200 in - Context.init 1 >>=? fun (b, _) -> - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >>= wrap - >>=? fun ctx -> - Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx - >>= wrap - >>=? fun (ctx, id_one_by_one) -> - Sapling_storage.init ctx id_one_by_one ~memo_size >>= wrap >>=? fun ctx -> - let list_to_add = - fst @@ List.split - @@ (List.init ~when_negative_length:() 33 (fun _ -> - gen_cm_cipher ~memo_size ()) - |> function - | Error () -> assert false (* 33 > 0 *) - | Ok r -> r) - in - let rec test counter ctx = - if counter >= 32 then return_unit - else - (* add a single cm to the existing tree *) - Sapling_storage.Commitments.add - ctx - id_one_by_one - [ - WithExceptions.Option.get ~loc:__LOC__ - @@ List.nth list_to_add counter; - ] - (Int64.of_int counter) - >>= wrap - (* create a new tree and add a list of cms *) - >>=? fun (ctx, _size) -> - Lazy_storage_diff.fresh - Lazy_storage_kind.Sapling_state - ~temporary:false - ctx - >>= wrap - >>=? fun (ctx, id_all_at_once) -> - Sapling_storage.init ctx id_all_at_once ~memo_size >>= wrap - >>=? fun ctx -> - Sapling_storage.Commitments.add - ctx - id_all_at_once - (List.init ~when_negative_length:() (counter + 1) (fun i -> - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth list_to_add i) - |> function - | Error () -> assert false (* counter >= 0*) - | Ok r -> r) - 0L - >>= wrap - >>=? fun (ctx, _size) -> - Sapling_storage.Commitments.get_root ctx id_one_by_one >>= wrap - >>=? fun (ctx, root_one_by_one) -> - Sapling_storage.Commitments.get_root ctx id_all_at_once >>= wrap - >>=? fun (ctx, root_all_at_once) -> - assert (root_all_at_once = root_one_by_one) ; - test (counter + 1) ctx - in - test 0 ctx - - (* This test adds 10 more roots the maximum capacity, all at different - levels, and checks that all but the first 10 are stored. - Then it adds one in the diff and checks it is stored. - Then it adds 10 at the same level and check that only the last one is - stored. *) - let root_test () = - let open Tezos_sapling.Core in - let gen_root () = - Data_encoding.Binary.of_bytes_exn - Validator.Hash.encoding - (Hacl.Rand.gen 32) - in - let roots_ctx = - List.init - ~when_negative_length:() - (Int32.to_int Sapling_storage.Roots.size + 10) - (fun _ -> gen_root ()) - |> function - | Error () -> assert false (* size >= 0 *) - | Ok roots_ctx -> roots_ctx - in - Context.init 1 >>=? fun (b, _) -> - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >>= wrap - >>=? fun ctx -> - Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx - >>= wrap - >>=? fun (ctx, id) -> - Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> - (* Add one root per level to the context *) - List.fold_left_es - (fun (ctx, cnt) root -> - Sapling_storage.Roots.add ctx id root >>= wrap >>=? fun ctx -> - (* Very low level way to "bake" a block. It would be better to use the - helpers functions but they complicate the access to the raw_context. *) - Raw_context.prepare - ~level:(Int32.add b.header.shell.level cnt) - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - (Raw_context.recover ctx) - >>= wrap - >|=? fun ctx -> (ctx, Int32.succ cnt)) - (ctx, 0l) - roots_ctx - >>=? fun (ctx, _) -> - (* Check mem on all the roots in the context. *) - let state = - Sapling_storage. - {id = Some id; diff = Sapling_storage.empty_diff; memo_size = 0} - in - List.fold_left_es - (fun i root -> - Sapling_storage.root_mem ctx state root >>= wrap >|=? fun bool -> - assert (if i < 10 then not bool else bool) ; - i + 1) - 0 - roots_ctx - >>=? fun _ -> - (* Add roots w/o increasing the level *) - let roots_same_level = - List.init ~when_negative_length:() 10 (fun _ -> gen_root ()) |> function - | Error () -> assert false (* 10 > 0 *) - | Ok roots_same_level -> roots_same_level - in - List.fold_left_es - (fun ctx root -> Sapling_storage.Roots.add ctx id root >>= wrap) - ctx - roots_same_level - >>=? fun ctx -> - List.fold_left_es - (fun (i, ctx) root -> - Sapling_storage.root_mem ctx state root >>= wrap >|=? fun bool -> - assert (if i < 9 then not bool else bool) ; - (i + 1, ctx)) - (0, ctx) - roots_same_level - >>=? fun _ -> return_unit - - let test_get_memo_size () = - Context.init 1 >>=? fun (b, _) -> - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >>= wrap - >>=? fun ctx -> - Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx - >>= wrap - >>=? fun (ctx, id) -> - Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> - Sapling_storage.get_memo_size ctx id >>= wrap >|=? fun memo_size -> - assert (memo_size = 0) -end - -module Alpha_context_tests = struct - open Sapling_helpers.Alpha_context_helpers - - (* Create a transaction with memo_size 1, test that is validates with a newly - created empty_state with memo_size 1 and does not with memo_size 0. *) - let test_verify_memo () = - init () >>=? fun ctx -> - let sk = - Tezos_sapling.Core.Wallet.Spending_key.of_seed - (Tezos_crypto.Hacl.Rand.gen 32) - in - let vt = - let ps = Tezos_sapling.Storage.empty ~memo_size:0 in - (* the dummy output will have memo_size 0 *) - Tezos_sapling.Forge.forge_transaction - ~number_dummy_outputs:1 - [] - [] - sk - "anti-replay" - ps - in - verify_update ctx vt ~memo_size:0 |> assert_some >>=? fun _ -> - verify_update ctx vt ~memo_size:1 |> assert_none - - (* Bench the proving and validation time of shielding and transferring several - tokens. *) - let test_bench_phases () = - init () >>=? fun ctx -> - let rounds = 5 in - Printf.printf "\nrounds: %d\n" rounds ; - let w = wallet_gen () in - let cs = Tezos_sapling.Storage.empty ~memo_size:8 in - (* one verify_update to get the id *) - let vt = transfer w cs [] in - verify_update ctx vt |> assert_some >>=? fun (ctx, id) -> - client_state_alpha ctx id >>=? fun cs -> - let start = Unix.gettimeofday () in - let vts = List.map (fun _ -> transfer w cs []) (1 -- rounds) in - let ctime_shields = Unix.gettimeofday () -. start in - Printf.printf "client_shields %f\n" ctime_shields ; - let start = Unix.gettimeofday () in - List.fold_left_es - (fun ctx vt -> - verify_update ctx ~id vt |> assert_some >|=? fun (ctx, _id) -> ctx) - ctx - vts - >>=? fun ctx -> - let vtime_shields = Unix.gettimeofday () -. start in - Printf.printf "valdtr_shields %f\n" vtime_shields ; - client_state_alpha ctx id >>=? fun cs -> - let start = Unix.gettimeofday () in - let vts = List.map (fun i -> transfer w cs [i]) (1 -- rounds) in - let ctime_transfers = Unix.gettimeofday () -. start in - Printf.printf "client_txs %f\n" ctime_transfers ; - let start = Unix.gettimeofday () in - List.fold_left_es - (fun ctx vt -> - verify_update ctx ~id vt |> assert_some >|=? fun (ctx, _id) -> ctx) - ctx - vts - >|=? fun _ctx -> - let vtime_transfers = Unix.gettimeofday () -. start in - Printf.printf "valdtr_txs %f\n" vtime_transfers - - (* Transfer several times the same token. *) - let test_bench_fold_over_same_token () = - init () >>=? fun ctx -> - let rounds = 5 in - let w = wallet_gen () in - let cs = Tezos_sapling.Storage.empty ~memo_size:8 in - (* one verify_update to get the id *) - let vt = transfer w cs [] in - verify_update ctx vt |> assert_some >>=? fun (ctx, id) -> - let rec loop cnt ctx = - if cnt >= rounds then return_unit - else - (* inefficient: re-synch from scratch at each round *) - client_state_alpha ctx id >>=? fun cs -> - let vt = transfer w cs [cnt] in - verify_update ctx ~id vt |> assert_some >>=? fun (ctx, _id) -> - loop (cnt + 1) ctx - in - loop 0 ctx - - (* - The following tests trigger all the branches of - Sapling_validator.verify_update. - The function performs several checks and returns None in case of failure. - During development the function was modified to throw a different exception - for each of its checks so to be sure that they were reached. - *) - - (* Test that double spending the same input fails the nf check. *) - let test_double_spend_same_input () = - init () >>=? fun ctx -> - let w = wallet_gen () in - let cs = Tezos_sapling.Storage.empty ~memo_size:8 in - (* one verify_update to get the id *) - let vt = transfer w cs [] in - verify_update ctx vt |> assert_some >>=? fun (ctx, id) -> - client_state_alpha ctx id >>=? fun cs -> - let vt = transfer w cs [0] in - verify_update ctx ~id vt |> assert_some >>=? fun (_ctx, id) -> - let vt = transfer w cs [0; 0] in - verify_update ctx ~id vt |> assert_none - - let test_verifyupdate_one_transaction () = - init () >>=? fun ctx -> - let w = wallet_gen () in - let cs = Tezos_sapling.Storage.empty ~memo_size:8 in - let vt = transfer w cs [] in - verify_update ctx vt |> assert_some >>=? fun (ctx, id) -> - client_state_alpha ctx id >>=? fun cs -> - let vt = transfer w cs [0] in - (* fails sig check because of wrong balance *) - let vt_broken = - Tezos_sapling.Core.Validator.UTXO. - {vt with balance = Int64.(succ vt.balance)} - in - verify_update ctx ~id vt_broken |> assert_none >>=? fun () -> - (* randomize one output to fail check outputs *) - (* don't randomize the ciphertext as it is not part of the proof *) - let open Tezos_sapling.Core.Client.UTXO in - let o = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd vt.outputs in - let o_wrong_cm = - { - o with - cm = randomized_byte o.cm Tezos_sapling.Core.Client.Commitment.encoding; - } - in - let vt_broken = - Tezos_sapling.Core.Validator.UTXO.{vt with outputs = [o_wrong_cm]} - in - verify_update ctx ~id vt_broken |> assert_none >>=? fun () -> - (* position inside the cv *) - let pos = Random.int 32 in - let o_wrong_cv = - { - o with - ciphertext = - randomized_byte - ~pos - o.ciphertext - Tezos_sapling.Core.Client.Ciphertext.encoding; - } - in - let vt_broken = - Tezos_sapling.Core.Validator.UTXO.{vt with outputs = [o_wrong_cv]} - in - verify_update ctx ~id vt_broken |> assert_none - - let test_verifyupdate_two_transactions () = - init () >>=? fun ctx -> - let w = wallet_gen () in - let cs = Tezos_sapling.Storage.empty ~memo_size:8 in - (* generate the first storage *) - let vt = transfer w cs [] in - verify_update ctx vt |> assert_some >>=? fun (ctx, id1) -> - client_state_alpha ctx id1 >>=? fun cs1 -> - let vt1 = transfer w cs1 [0] in - (* generate the second storage *) - let vt = transfer w cs [] in - verify_update ctx vt |> assert_some >>=? fun (ctx, id2) -> - client_state_alpha ctx id2 >>=? fun cs2 -> - let vt2 = transfer w cs2 [0] in - (* fail root check *) - verify_update ctx ~id:id1 vt2 |> assert_none >>=? fun () -> - (* Swap the root so that it passes the root_mem check but fails - the input check *) - let vt1_broken = - Tezos_sapling.Core.Validator.UTXO.{vt2 with root = vt1.root} - in - verify_update ctx ~id:id1 vt1_broken |> assert_none >>=? fun () -> - (* fail the sig check *) - let vt1_broken = - Tezos_sapling.Core.Validator.UTXO.{vt1 with outputs = vt2.outputs} - in - verify_update ctx ~id:id1 vt1_broken |> assert_none -end - -module Interpreter_tests = struct - open Sapling_helpers.Interpreter_helpers - - let parameters_of_list transactions = - let string = "{ " ^ String.concat " ; " transactions ^ " }" in - Alpha_context.Script.(lazy_expr (Expr.from_string string)) - - (* In this test we use a contract which takes a list of transactions, applies - all of them, and assert all of them are correct. It also enforces a 1-to-1 - conversion with mutez by asking an amount to shield and asking for a pkh to - unshield. - We create 2 keys a and b. We originate the contract, then do two lists of - shield for a, then transfers several outputs to b while unshielding, then - transfer all of b inputs to a while adding dummy inputs and outputs. - At last we fail we make a failing transaction. *) - let test_shielded_tez () = - init () >>=? fun (genesis, baker, src0, src1) -> - let memo_size = 8 in - originate_contract "contracts/sapling_contract.tz" "{ }" src0 genesis baker - >>=? fun (dst, b1, anti_replay) -> - let wa = wallet_gen () in - let (list_transac, total) = - shield - ~memo_size - wa.sk - 4 - wa.vk - (Format.sprintf "Pair 0x%s None") - anti_replay - in - let parameters = parameters_of_list list_transac in - (* a does a list of shield transaction *) - transac_and_sync ~memo_size b1 parameters total src0 dst baker - >>=? fun (b2, _state) -> - (* we shield again on another block, forging with the empty state *) - let (list_transac, total) = - shield - ~memo_size - wa.sk - 4 - wa.vk - (Format.sprintf "Pair 0x%s None") - anti_replay - in - let parameters = parameters_of_list list_transac in - (* a does a list of shield transaction *) - transac_and_sync ~memo_size b2 parameters total src0 dst baker - >>=? fun (b3, state) -> - (* address that will receive an unshield *) - Context.Contract.balance (B b3) src1 >>=? fun balance_before_shield -> - (* address that will receive an unshield *) - let wb = wallet_gen () in - let list_addr = gen_addr 15 wb.vk in - let list_forge_input = - List.init ~when_negative_length:() 14 (fun pos_int -> - let pos = Int64.of_int pos_int in - let forge_input = - snd - (Tezos_sapling.Forge.Input.get state pos wa.vk - |> WithExceptions.Option.get ~loc:__LOC__) - in - forge_input) - |> function - | Error () -> assert false (* 14 > 0 *) - | Ok list_forge_input -> list_forge_input - in - let list_forge_output = - List.map - (fun addr -> Tezos_sapling.Forge.make_output addr 1L (Bytes.create 8)) - list_addr - in - let hex_transac = - to_hex - (Tezos_sapling.Forge.forge_transaction - ~number_dummy_inputs:0 - ~number_dummy_outputs:0 - list_forge_input - list_forge_output - wa.sk - anti_replay - state) - Tezos_sapling.Core.Client.UTXO.transaction_encoding - in - let hex_pkh = - to_hex - (Alpha_context.Contract.is_implicit src1 - |> WithExceptions.Option.get ~loc:__LOC__) - Signature.Public_key_hash.encoding - in - let string = - Format.sprintf "{Pair 0x%s (Some 0x%s) }" hex_transac hex_pkh - in - let parameters = - Alpha_context.Script.(lazy_expr (Expr.from_string string)) - in - (* a transfers to b and unshield some money to src_2 (the pkh) *) - transac_and_sync ~memo_size b3 parameters 0 src0 dst baker - >>=? fun (b4, state) -> - Context.Contract.balance (B b4) src1 >>=? fun balance_after_shield -> - let diff_due_to_shield = - Int64.sub - (Test_tez.to_mutez balance_after_shield) - (Test_tez.to_mutez balance_before_shield) - in - (* The balance after shield is obtained from the balance before shield by - the shield specific update. *) - (* The inputs total [total] mutez and 15 of those are transfered in shielded tez *) - Assert.equal_int ~loc:__LOC__ (Int64.to_int diff_due_to_shield) (total - 15) - >>=? fun () -> - let list_forge_input = - List.init ~when_negative_length:() 15 (fun i -> - let pos = Int64.of_int (i + 14 + 14) in - let forge_input = - snd - (Tezos_sapling.Forge.Input.get state pos wb.vk - |> WithExceptions.Option.get ~loc:__LOC__) - in - forge_input) - |> function - | Error () -> assert false (* 14 > 0 *) - | Ok list_forge_input -> list_forge_input - in - let addr_a = - snd - @@ Tezos_sapling.Core.Client.Viewing_key.new_address - wa.vk - Tezos_sapling.Core.Client.Viewing_key.default_index - in - let output = Tezos_sapling.Forge.make_output addr_a 15L (Bytes.create 8) in - let hex_transac = - to_hex - (Tezos_sapling.Forge.forge_transaction - ~number_dummy_inputs:2 - ~number_dummy_outputs:2 - list_forge_input - [output] - wb.sk - anti_replay - state) - Tezos_sapling.Core.Client.UTXO.transaction_encoding - in - let string = Format.sprintf "{Pair 0x%s None }" hex_transac in - let parameters = - Alpha_context.Script.(lazy_expr (Expr.from_string string)) - in - (* b transfers to a with dummy inputs and outputs *) - transac_and_sync ~memo_size b4 parameters 0 src0 dst baker - >>=? fun (b, _state) -> - (* Here we fail by doing the same transaction again*) - Incremental.begin_construction b >>=? fun incr -> - let fee = Test_tez.of_int 10 in - Op.transaction ~fee (B b) src0 dst Tez.zero ~parameters - >>=? fun operation -> - Incremental.add_operation (* TODO make more precise *) - ~expect_failure:(fun _ -> return_unit) - incr - operation - >>=? fun _incr -> return_unit - - let test_push_sapling_state_should_be_forbidden () = - init () - (* Originating a contract to get a sapling_state with ID 0, used in the next contract *) - >>=? - fun (block, baker, src, _) -> - originate_contract "contracts/sapling_contract.tz" "{ }" src block baker - >>=? fun _ -> - (* Originating the next contract should fail *) - originate_contract - "contracts/sapling_push_sapling_state.tz" - "{ }" - src - block - baker - >>= function - | Error - [ - Environment.Ecoproto_error (Script_tc_errors.Ill_typed_contract _); - Environment.Ecoproto_error - (Script_tc_errors.Unexpected_lazy_storage _); - ] -> - return_unit - | _ -> assert false - - let test_use_state_from_other_contract_and_transact () = - (* - Attempt to use a sapling state of a contract A in a contract B - *) - init () (* Originating the contracts *) >>=? fun (block, baker, src, _) -> - let memo_size = 8 in - (* originate_contract "contracts/sapling_contract.tz" "{ }" src block baker - >>=? fun (_shielded_pool_contract_address, block, _anti_replay_shielded_pool) - -> *) - originate_contract - "contracts/sapling_use_existing_state.tz" - "{ }" - src - block - baker - >>=? fun (existing_state_contract_address, block, anti_replay_2) -> - (* we create one shielding transaction and transform it in Micheline to use - it as a parameter - *) - let wa = wallet_gen () in - let (transactions, _total) = - shield - ~memo_size - wa.sk - 1 - wa.vk - (Format.sprintf "(Pair 0x%s 0)") - anti_replay_2 - in - let transaction = - WithExceptions.Option.get ~loc:__LOC__ @@ List.hd transactions - in - let parameters = - Alpha_context.Script.(lazy_expr (Expr.from_string transaction)) - in - transac_and_sync - ~memo_size - block - parameters - 0 - src - existing_state_contract_address - baker - >|= function - | Ok _ -> Alcotest.failf "Unexpected operations success" - | Error errs -> - assert ( - List.exists - (function - | Environment.Ecoproto_error - (Tezos_raw_protocol_012_Psithaca.Script_tc_errors - .Unexpected_forged_value _) -> - true - | _ -> false) - errs) ; - Result.return_unit - - (* In this test we do two transactions in one block and same two in two block. - We check that the sate is the same expect for roots. - The second transaction is possible only if the first one is done. *) - let test_transac_and_block () = - init () >>=? fun (b, baker, src, _) -> - let memo_size = 8 in - originate_contract "contracts/sapling_contract.tz" "{ }" src b baker - >>=? fun (dst, block_start, anti_replay) -> - let {sk; vk} = wallet_gen () in - let hex_transac_1 = hex_shield ~memo_size {sk; vk} anti_replay in - let string_1 = Format.sprintf "{Pair %s None }" hex_transac_1 in - let parameters_1 = - Alpha_context.Script.(lazy_expr (Expr.from_string string_1)) - in - transac_and_sync ~memo_size block_start parameters_1 15 src dst baker - >>=? fun (block_1, state) -> - let intermediary_root = Tezos_sapling.Storage.get_root state in - let addr = - snd - @@ Tezos_sapling.Core.Wallet.Viewing_key.(new_address vk default_index) - in - let output = Tezos_sapling.Forge.make_output addr 15L (Bytes.create 8) in - let hex_transac_2 = - "0x" - ^ to_hex - (Tezos_sapling.Forge.forge_transaction - [ - snd - (Tezos_sapling.Forge.Input.get state 0L vk - |> WithExceptions.Option.get ~loc:__LOC__); - ] - [output] - sk - anti_replay - state) - Tezos_sapling.Core.Client.UTXO.transaction_encoding - in - let string_2 = Format.sprintf "{Pair %s None }" hex_transac_2 in - let parameters_2 = - Alpha_context.Script.(lazy_expr (Expr.from_string string_2)) - in - transac_and_sync ~memo_size block_1 parameters_2 0 src dst baker - >>=? fun (block_1, state_1) -> - let final_root = Tezos_sapling.Storage.get_root state_1 in - Alpha_services.Contract.single_sapling_get_diff - Block.rpc_ctxt - block_1 - dst - ~offset_commitment:0L - ~offset_nullifier:0L - () - >>=? fun (_root, diff_1) -> - let fee = Test_tez.of_int 10 in - Tez.one_mutez *? Int64.of_int 15 >>?= fun amount_tez -> - Op.transaction - ~fee - (B block_start) - src - dst - amount_tez - ~parameters:parameters_1 - >>=? fun operation -> - Incremental.begin_construction block_start >>=? fun incr -> - Incremental.add_operation incr operation >>=? fun incr -> - (* We need to manually get the counter here *) - let ctx = Incremental.alpha_ctxt incr in - let pkh = - Alpha_context.Contract.is_implicit src - |> WithExceptions.Option.get ~loc:__LOC__ - in - Alpha_context.Contract.get_counter ctx pkh >>= wrap >>=? fun counter -> - Op.transaction - ~counter - ~fee - (B block_start) - src - dst - Tez.zero - ~parameters:parameters_2 - >>=? fun operation -> - Incremental.add_operation incr operation >>=? fun incr -> - Incremental.finalize_block incr >>=? fun block_2 -> - Alpha_services.Contract.single_sapling_get_diff - Block.rpc_ctxt - block_2 - dst - ~offset_commitment:0L - ~offset_nullifier:0L - () - >>=? fun (_root, diff_2) -> - (* We check that the same transactions have passed *) - assert (diff_1 = diff_2) ; - let is_root_in block dst root = - Incremental.begin_construction block >>=? fun incr -> - let ctx_2 = Incremental.alpha_ctxt incr in - Alpha_services.Contract.script Block.rpc_ctxt block dst >>=? fun script -> - let ctx_without_gas_2 = Alpha_context.Gas.set_unlimited ctx_2 in - Script_ir_translator.parse_script - ctx_without_gas_2 - ~legacy:true - ~allow_forged_in_storage:true - script - >>= wrap - >>=? fun (Ex_script script, ctxt) -> - Script_ir_translator.get_single_sapling_state - ctxt - script.storage_type - script.storage - |> wrap - >>=? fun (id, _ctx_2) -> - let single_id = WithExceptions.Option.get ~loc:__LOC__ id in - let id = - Lazy_storage_kind.Sapling_state.Id.parse_z - @@ Alpha_context.Sapling.Id.unparse_to_z single_id - in - Raw_context.prepare - block.context - ~level:block.header.shell.level - ~predecessor_timestamp:block.header.shell.timestamp - ~timestamp:block.header.shell.timestamp - >>= wrap - >>=? fun raw_ctx -> Sapling_storage.Roots.mem raw_ctx id root >>= wrap - in - (* We check that the second state did not store the root in between - transactions. *) - is_root_in block_2 dst intermediary_root |> assert_false >>=? fun () -> - (* We check that the second state did store the final root. *) - is_root_in block_2 dst final_root |> assert_true >>=? fun () -> - (* We check that the first state did store the final root. *) - is_root_in block_1 dst final_root |> assert_true >>=? fun () -> - (* We check that the first state did store the root in between transactions. *) - is_root_in block_1 dst intermediary_root |> assert_true - - (* In this test we try a contract which creates an empty sapling state on the - fly. It then applies a list of transactions, checks they are correct and - drops the result. We make several shields in the same list (since the state - is drop). *) - let test_drop () = - init () >>=? fun (b, baker, src, _) -> - originate_contract "contracts/sapling_contract_drop.tz" "Unit" src b baker - >>=? fun (dst, b, anti_replay) -> - let {sk; vk} = wallet_gen () in - let (list_transac, _total) = - shield ~memo_size:8 sk 4 vk (Format.sprintf "0x%s") anti_replay - in - let parameters = parameters_of_list list_transac in - Op.transaction ~fee:(Test_tez.of_int 10) (B b) src dst Tez.zero ~parameters - >>=? fun operation -> - next_block b operation >>=? fun _b -> return_unit - - (* We use a contrac with two states. Its parameter is two transactions and a - bool. The two transactions are tested valid against the two states, but - only one state according to the bool is updated. - We do two transactions shielding to different keys in the two states. - At each transactions both are applied but only state is updated. - We then check that the first state is updated in the correct way. *) - let test_double () = - init () >>=? fun (b, baker, src, _) -> - let memo_size = 8 in - originate_contract - "contracts/sapling_contract_double.tz" - "(Pair { } { })" - src - b - baker - >>=? fun (dst, b, anti_replay) -> - let wa = wallet_gen () in - let hex_transac_1 = hex_shield ~memo_size wa anti_replay in - let wb = wallet_gen () in - let hex_transac_2 = hex_shield ~memo_size wb anti_replay in - let str_1 = - "(Pair True (Pair " ^ hex_transac_1 ^ " " ^ hex_transac_2 ^ "))" - in - let str_2 = - "(Pair False (Pair " ^ hex_transac_2 ^ " " ^ hex_transac_1 ^ "))" - in - (* transac 1 is applied to state_1*) - let parameters_1 = - Alpha_context.Script.(lazy_expr (Expr.from_string str_1)) - in - (* tranasc_2 is applied to state_2*) - let parameters_2 = - Alpha_context.Script.(lazy_expr (Expr.from_string str_2)) - in - let fee = Test_tez.of_int 10 in - Op.transaction ~fee (B b) src dst Tez.zero ~parameters:parameters_1 - >>=? fun operation -> - next_block b operation >>=? fun b -> - Op.transaction ~fee (B b) src dst Tez.zero ~parameters:parameters_2 - >>=? fun operation -> - next_block b operation >>=? fun b -> - Incremental.begin_construction b >>=? fun incr -> - let ctx = Incremental.alpha_ctxt incr in - let ctx_without_gas = Alpha_context.Gas.set_unlimited ctx in - Alpha_services.Contract.storage Block.rpc_ctxt b dst >>=? fun storage -> - let storage_lazy_expr = Alpha_context.Script.lazy_expr storage in - - (let memo_size = memo_size_of_int memo_size in - let open Script_typed_ir in - let state_ty = sapling_state_t ~memo_size ~annot:None in - pair_t (-1) (state_ty, None, None) (state_ty, None, None) ~annot:None) - >>??= fun tytype -> - Script_ir_translator.parse_storage - ctx_without_gas - ~legacy:true - ~allow_forged:true - tytype - ~storage:storage_lazy_expr - >>= wrap - >>=? fun ((state_1, state_2), _ctx) -> - (*Only works when diff is empty*) - let local_state_from_disk disk_state ctx = - let id = - Alpha_context.Sapling.(disk_state.id) - |> WithExceptions.Option.get ~loc:__LOC__ - in - Alpha_context.Sapling.get_diff - ctx - id - ~offset_commitment:0L - ~offset_nullifier:0L - () - >>= wrap - >|=? fun diff -> client_state_of_diff ~memo_size diff - in - local_state_from_disk state_1 ctx >>=? fun state_1 -> - local_state_from_disk state_2 ctx >|=? fun state_2 -> - (* we check that first state contains 15 to addr_1 but not 15 to addr_2*) - assert (Option.is_some @@ Tezos_sapling.Forge.Input.get state_1 0L wa.vk) ; - assert (Option.is_some @@ Tezos_sapling.Forge.Input.get state_2 0L wa.vk) ; - assert (Option.is_none @@ Tezos_sapling.Forge.Input.get state_1 0L wb.vk) ; - assert (Option.is_none @@ Tezos_sapling.Forge.Input.get state_2 0L wb.vk) - - let test_state_as_arg () = - init () >>=? fun (b, baker, src, _) -> - originate_contract - "contracts/sapling_contract_state_as_arg.tz" - "None" - src - b - baker - >>=? fun (dst, b, anti_replay) -> - originate_contract "contracts/sapling_contract_send.tz" "Unit" src b baker - >>=? fun (dst_2, b, anti_replay_2) -> - let w = wallet_gen () in - let hex_transac_1 = hex_shield ~memo_size:8 w anti_replay in - let string = "Left " ^ hex_transac_1 in - let parameters = - Alpha_context.Script.(lazy_expr (Expr.from_string string)) - in - let fee = Test_tez.of_int 10 in - Op.transaction ~fee (B b) src dst Tez.zero ~parameters >>=? fun operation -> - next_block b operation >>=? fun b -> - let contract = "0x" ^ to_hex dst Alpha_context.Contract.encoding in - let hex_transac_2 = hex_shield ~memo_size:8 w anti_replay_2 in - let string = "(Pair " ^ contract ^ " " ^ hex_transac_2 ^ ")" in - let parameters = - Alpha_context.Script.(lazy_expr (Expr.from_string string)) - in - Op.transaction ~fee (B b) src dst_2 Tez.zero ~parameters - >>=? fun operation -> - next_block b operation >>=? fun _b -> return_unit -end - -let tests = - [ - Tztest.tztest - "commitments_add_uncommitted" - `Quick - Raw_context_tests.commitments_add_uncommitted; - Tztest.tztest "nullifier_double" `Quick Raw_context_tests.nullifier_double; - Tztest.tztest "nullifier_test" `Quick Raw_context_tests.nullifier_test; - Tztest.tztest "cm_cipher_test" `Quick Raw_context_tests.cm_cipher_test; - Tztest.tztest - "list_insertion_test" - `Quick - Raw_context_tests.list_insertion_test; - Tztest.tztest "root" `Quick Raw_context_tests.root_test; - Tztest.tztest - "test_get_memo_size" - `Quick - Raw_context_tests.test_get_memo_size; - Tztest.tztest "test_verify_memo" `Quick Alpha_context_tests.test_verify_memo; - Tztest.tztest - "test_bench_phases" - `Slow - Alpha_context_tests.test_bench_phases; - Tztest.tztest - "test_bench_fold_over_same_token" - `Slow - Alpha_context_tests.test_bench_fold_over_same_token; - Tztest.tztest - "test_double_spend_same_input" - `Quick - Alpha_context_tests.test_double_spend_same_input; - Tztest.tztest - "test_verifyupdate_one_transaction" - `Quick - Alpha_context_tests.test_verifyupdate_one_transaction; - Tztest.tztest - "test_verifyupdate_two_transactions" - `Quick - Alpha_context_tests.test_verifyupdate_two_transactions; - Tztest.tztest "test_shielded_tez" `Quick Interpreter_tests.test_shielded_tez; - Tztest.tztest - "test use state from other contract and transact" - `Quick - Interpreter_tests.test_use_state_from_other_contract_and_transact; - Tztest.tztest - "Instruction PUSH sapling_state 0 should be forbidden" - `Quick - Interpreter_tests.test_push_sapling_state_should_be_forbidden; - Tztest.tztest - "test_transac_and_block" - `Quick - Interpreter_tests.test_transac_and_block; - Tztest.tztest "test_drop" `Quick Interpreter_tests.test_drop; - Tztest.tztest "test_double" `Quick Interpreter_tests.test_double; - Tztest.tztest "test_state_as_arg" `Quick Interpreter_tests.test_state_as_arg; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_saturation.ml b/src/proto_012_Psithaca/lib_protocol/test/test_saturation.ml deleted file mode 100644 index 099ead7ed739..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_saturation.ml +++ /dev/null @@ -1,218 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (saturated arithmetic) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ - -- test "^saturation arithmetic$" - Subject: The gas is represented using saturated arithmetic. - These unit tests check that saturated arithmetic operations - are correctly implemented. -*) - -open Protocol - -let valid (z : _ Saturation_repr.t) = - let x = z |> Saturation_repr.to_int in - x >= 0 && x < max_int - -exception Saturating_test_error of string - -let err x = Exn (Saturating_test_error x) - -let small_enough (z : _ Saturation_repr.t) = - Saturation_repr.(Compare.Int.((z |> to_int) land 0x7fffffff80000000 = 0)) - -let ok_int x = - match Saturation_repr.of_int_opt x with None -> assert false | Some x -> x - -let n = ok_int 123123 - -let m = ok_int 377337 - -let add () = - Saturation_repr.( - fail_unless - (add saturated (ok_int 1) = saturated) - (err "saturated + 1 <> saturated") - >>=? fun () -> - fail_unless (add zero n = n) (err "zero + n <> n") >>=? fun () -> - fail_unless (add n zero = n) (err "n + zero <> n") >>=? fun () -> - let r = add n m in - fail_unless - (valid r && r = ok_int ((n |> to_int) + (m |> to_int))) - (err "add does not behave like + on small numbers.")) - -let sub () = - Saturation_repr.( - fail_unless (sub zero n = zero) (err "zero - n <> zero") >>=? fun () -> - let n = max n m and m = min n m in - let r = sub n m in - fail_unless - (valid r && r = ok_int ((n |> to_int) - (m |> to_int))) - (err "sub does not behave like - on small numbers.")) - -let mul_safe_of_int x = - Saturation_repr.( - match mul_safe (ok_int x) with Some x -> x | None -> assert false) - -let n' = mul_safe_of_int 1000 - -let m' = mul_safe_of_int 10000 - -let mul_fast () = - Saturation_repr.( - fail_unless (mul_fast zero n' = zero) (err "mul_fast zero x <> zero") - >>=? fun () -> - fail_unless (mul_fast n' zero = zero) (err "mul_fast x zero <> zero") - >>=? fun () -> - let r = mul_fast n' m' in - fail_unless - (valid r && r = ok_int ((n' |> to_int) * (m' |> to_int))) - (err "mul_fast does not behave like * on small numbers.")) - -let scale_fast () = - Saturation_repr.( - fail_unless (scale_fast zero n = zero) (err "scale_fast zero x <> zero") - >>=? fun () -> - fail_unless (scale_fast n' zero = zero) (err "scale_fast x zero <> zero") - >>=? fun () -> - fail_unless - (scale_fast n' saturated = saturated) - (err "scale_fast x saturated <> saturated") - >>=? fun () -> - let r = scale_fast n' m in - fail_unless - (valid r && r = ok_int ((n' |> to_int) * (m |> to_int))) - (err "mul_fast does not behave like * on small numbers.")) - -let mul () = - Saturation_repr.( - fail_unless - (mul saturated saturated = saturated) - (err "saturated * saturated <> saturated") - >>=? fun () -> - fail_unless (mul zero saturated = zero) (err "zero * saturated <> zero") - >>=? fun () -> - fail_unless (mul saturated zero = zero) (err "saturated * zero <> zero") - >>=? fun () -> - let max_squared = ok_int (1 lsl 31) in - let r = mul max_squared max_squared in - fail_unless (r = saturated) (err "2 ^ 31 * 2 ^ 31 should be saturated") - >>=? fun () -> - let safe_squared = ok_int ((1 lsl 31) - 1) in - let r = mul safe_squared safe_squared in - fail_unless - (valid r && r <> saturated) - (err "(2 ^ 31 - 1) * (2 ^ 31 - 1) should not be saturated") - >>=? fun () -> - let r = mul n m in - fail_unless - (valid r && r = ok_int ((n |> to_int) * (m |> to_int))) - (err "mul does not behave like * on small numbers.")) - -let shift_left () = - Saturation_repr.( - let must_saturate flag (k, v) = - fail_unless - (Bool.equal flag (shift_left k v = saturated)) - (err - (Printf.sprintf - "shift_left %d %d %s saturated" - (k |> to_int) - v - (if flag then "<>" else "="))) - in - List.iter_es - (must_saturate true) - [(saturated, 1); (shift_right saturated 1, 2); (ok_int 1, 62)] - >>=? fun () -> - List.iter_es - (must_saturate false) - [ - (ok_int 1, 0); - (ok_int 1, 31); - (ok_int 1, 61); - (ok_int 0, 99); - (ok_int ((1 lsl 62) - 2), 0); - ]) - -let of_z_opt () = - fail_unless - (Saturation_repr.(of_z_opt (Z.succ (Z.of_int max_int))) = None) - (err - "of_z_opt should saturate when given a z integer greater than max_int.") - >>=? fun () -> - fail_unless - (Saturation_repr.(of_z_opt (Z.pred Z.zero)) = None) - (err "of_z_opt should fail on a z negative integer.") - >>=? fun () -> - fail_unless - (Saturation_repr.(of_z_opt (Z.of_int min_int)) = None) - (err "of_z_opt should fail on a z negative integer.") - -let encoding encoder () = - let check_encode_decode x = - Data_encoding.Binary.( - match to_bytes encoder (ok_int x) with - | Error _ -> - fail (err (Printf.sprintf "Problem during binary encoding of %d" x)) - | Ok bytes -> ( - match of_bytes encoder bytes with - | Error _ -> - fail - (err (Printf.sprintf "Problem during binary decoding of %d" x)) - | Ok x' -> - fail_unless - (ok_int x = x') - (err - (Printf.sprintf - "decode (encode %d) = %d <> %d" - x - (x' :> int) - x)))) - in - Error_monad.Lwt_tzresult_syntax.join - (List.map check_encode_decode [0; 7373737373; max_int - 1]) - -let tests = - [ - Tztest.tztest "Addition" `Quick add; - Tztest.tztest "Subtraction" `Quick sub; - Tztest.tztest "Multiplication" `Quick mul; - Tztest.tztest "Multiplication (fast version)" `Quick mul_fast; - Tztest.tztest "Shift left" `Quick shift_left; - Tztest.tztest "Scale fast" `Quick scale_fast; - Tztest.tztest "Conversion from Z" `Quick of_z_opt; - Tztest.tztest - "Encoding through z" - `Quick - (encoding Saturation_repr.z_encoding); - Tztest.tztest - "Encoding through n" - `Quick - (encoding Saturation_repr.n_encoding); - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_script_comparison.ml b/src/proto_012_Psithaca/lib_protocol/test/test_script_comparison.ml deleted file mode 100644 index 3c498983811f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_script_comparison.ml +++ /dev/null @@ -1,369 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Script_comparison - Invocation: dune exec src/proto_alpha/lib_protocol/test/test_script_comparison.exe - Subject: PBT of the Script_comparable.compare_comparable function. -*) - -open Protocol -open Alpha_context -open Script_typed_ir -open Lib_test.Qcheck_helpers - -(* Reference implementation *) - -let normalize_compare c = - let open Compare.Int in - if c > 0 then 1 else if c < 0 then -1 else 0 - -(* This reference implementation of the Michelson comparison function is a - simplified version of the Script_ir_translator.compare_comparable function - that was used in the Florence protocol, before a refactoring broke it in - Granada. *) -let rec reference_compare_comparable : type a. a comparable_ty -> a -> a -> int - = - fun ty x y -> - match (ty, x, y) with - | (Unit_key _, (), ()) -> 0 - | (Never_key _, _, _) -> . - | (Signature_key _, x, y) -> normalize_compare @@ Signature.compare x y - | (String_key _, x, y) -> normalize_compare @@ Script_string.compare x y - | (Bool_key _, x, y) -> normalize_compare @@ Compare.Bool.compare x y - | (Mutez_key _, x, y) -> normalize_compare @@ Tez.compare x y - | (Key_hash_key _, x, y) -> - normalize_compare @@ Signature.Public_key_hash.compare x y - | (Key_key _, x, y) -> normalize_compare @@ Signature.Public_key.compare x y - | (Int_key _, x, y) -> normalize_compare @@ Script_int.compare x y - | (Nat_key _, x, y) -> normalize_compare @@ Script_int.compare x y - | (Timestamp_key _, x, y) -> normalize_compare @@ Script_timestamp.compare x y - | (Address_key _, x, y) -> - normalize_compare @@ Script_comparable.compare_address x y - | (Bytes_key _, x, y) -> normalize_compare @@ Compare.Bytes.compare x y - | (Chain_id_key _, x, y) -> normalize_compare @@ Chain_id.compare x y - | (Pair_key ((tl, _), (tr, _), _), (lx, rx), (ly, ry)) -> - let cl = reference_compare_comparable tl lx ly in - if Compare.Int.(cl = 0) then reference_compare_comparable tr rx ry else cl - | (Union_key ((tl, _), _, _), L x, L y) -> reference_compare_comparable tl x y - | (Union_key _, L _, R _) -> -1 - | (Union_key _, R _, L _) -> 1 - | (Union_key (_, (tr, _), _), R x, R y) -> reference_compare_comparable tr x y - | (Option_key _, None, None) -> 0 - | (Option_key _, None, Some _) -> -1 - | (Option_key _, Some _, None) -> 1 - | (Option_key (t, _), Some x, Some y) -> reference_compare_comparable t x y - -(* Generation of one to three values of the same comparable type. *) - -type ex_comparable_data = - | Ex_comparable_data : 'a comparable_ty * 'a -> ex_comparable_data - -type ex_comparable_data_2 = - | Ex_comparable_data_2 : 'a comparable_ty * 'a * 'a -> ex_comparable_data_2 - -type ex_comparable_data_3 = - | Ex_comparable_data_3 : - 'a comparable_ty * 'a * 'a * 'a - -> ex_comparable_data_3 - -(* We use the Michelson samplers from lib_benchmark and turn them into QCheck - generators *) -module Parameters = struct - let atom_size_range : Tezos_benchmark.Base_samplers.range = - {min = 0; max = 10} - - let other_size : Tezos_benchmark.Base_samplers.range = {min = 0; max = 100} - - let parameters : Michelson_samplers.parameters = - { - base_parameters = - { - int_size = atom_size_range; - string_size = atom_size_range; - bytes_size = atom_size_range; - }; - list_size = other_size; - set_size = other_size; - map_size = other_size; - } -end - -module Crypto_samplers = -Tezos_benchmark.Crypto_samplers.Make_finite_key_pool (struct - let size = 1000 - - let algo = `Default -end) - -module Samplers : Michelson_samplers.S = - Michelson_samplers.Make (Parameters) (Crypto_samplers) - -let ex_comparable_data_sampler : - ex_comparable_data Tezos_benchmark.Base_samplers.sampler = - fun random_state -> - let size = - Tezos_benchmark.Base_samplers.sample_in_interval - ~range:{min = 1; max = 20} - random_state - in - let (Ex_comparable_ty ty) = - Samplers.Random_type.m_comparable_type ~size random_state - in - let x = Samplers.Random_value.comparable ty random_state in - Ex_comparable_data (ty, x) - -let ex_comparable_data_2_sampler : - ex_comparable_data_2 Tezos_benchmark.Base_samplers.sampler = - fun random_state -> - let size = - Tezos_benchmark.Base_samplers.sample_in_interval - ~range:{min = 1; max = 20} - random_state - in - let (Ex_comparable_ty ty) = - Samplers.Random_type.m_comparable_type ~size random_state - in - let x = Samplers.Random_value.comparable ty random_state in - let y = Samplers.Random_value.comparable ty random_state in - Ex_comparable_data_2 (ty, x, y) - -let ex_comparable_data_3_sampler : - ex_comparable_data_3 Tezos_benchmark.Base_samplers.sampler = - fun random_state -> - let size = - Tezos_benchmark.Base_samplers.sample_in_interval - ~range:{min = 1; max = 20} - random_state - in - let (Ex_comparable_ty ty) = - Samplers.Random_type.m_comparable_type ~size random_state - in - let x = Samplers.Random_value.comparable ty random_state in - let y = Samplers.Random_value.comparable ty random_state in - let z = Samplers.Random_value.comparable ty random_state in - Ex_comparable_data_3 (ty, x, y, z) - -let comparable_data_generator : ex_comparable_data QCheck.Gen.t = - ex_comparable_data_sampler - -let comparable_data_2_generator : ex_comparable_data_2 QCheck.Gen.t = - ex_comparable_data_2_sampler - -let comparable_data_3_generator : ex_comparable_data_3 QCheck.Gen.t = - ex_comparable_data_3_sampler - -let comparable_data_arbitrary : ex_comparable_data QCheck.arbitrary = - QCheck.make comparable_data_generator - -let comparable_data_2_arbitrary : ex_comparable_data_2 QCheck.arbitrary = - QCheck.make comparable_data_2_generator - -let comparable_data_3_arbitrary : ex_comparable_data_3 QCheck.arbitrary = - QCheck.make comparable_data_3_generator - -(* We need a context because packing (used in one of the tests) and unparsing - (used for pretty-printing error messages) Michelson data are carbonated - operations. But since we don't care about gas consumption here we use the - same value of type context everywhere instead of threading it through the - error monad. *) - -let assert_ok = function Ok x -> x | Error _ -> assert false - -let assert_return x = assert_ok (Lwt_main.run x) - -let ctxt = - assert_return - ( Context.init 3 >>=? fun (b, _cs) -> - Incremental.begin_construction b >>=? fun v -> - return (Incremental.alpha_ctxt v) ) - -let unparse_comparable_ty ty = - Micheline.strip_locations - (fst - (assert_ok - Script_ir_translator.( - unparse_ty ~loc:() ctxt (ty_of_comparable_ty ty)))) - -let unparse_comparable_data ty x = - Micheline.strip_locations - (fst - (assert_return - Script_ir_translator.( - unparse_data ctxt Readable (ty_of_comparable_ty ty) x))) - -let pack_comparable_data ty x = - fst - (assert_return - Script_ir_translator.(pack_data ctxt (ty_of_comparable_ty ty) x)) - -let unpack_comparable_data ty bytes = - let ty = Script_ir_translator.ty_of_comparable_ty ty in - fst (assert_return (Script_interpreter_defs.unpack ctxt ~ty ~bytes)) - -let pp_comparable_ty fmt ty = - Michelson_v1_printer.print_expr fmt (unparse_comparable_ty ty) - -let pp_comparable_data ty fmt x = - Michelson_v1_printer.print_expr fmt (unparse_comparable_data ty x) - -let pp ty x y pp_c fmt c = - Format.fprintf - fmt - "Compare(ty=%a, %a, %a) = %a" - pp_comparable_ty - ty - (pp_comparable_data ty) - x - (pp_comparable_data ty) - y - pp_c - c - -let compare_through_pack ty x y = - Bytes.compare (pack_comparable_data ty x) (pack_comparable_data ty y) = 0 - -let qcheck_compare_comparable ~expected ty x y = - qcheck_eq - ~pp:(pp ty x y Format.pp_print_int) - expected - (Script_comparable.compare_comparable ty x y) - -let qcheck_compare_comparable_eq ~expected ty x y = - qcheck_eq - ~pp:(pp ty x y Format.pp_print_bool) - expected - (Script_comparable.compare_comparable ty x y = 0) - -(* Test. - * Tests that compare_comparable returns the same values than the reference - * implementation. - *) -let test_compatible_with_reference = - QCheck.Test.make - ~name:"compatible_with_reference" - comparable_data_2_arbitrary - (fun (Ex_comparable_data_2 (ty, x, y)) -> - qcheck_compare_comparable - ~expected:(reference_compare_comparable ty x y) - ty - x - y) - -(* Test. - * Tests that compare_comparable returns 0 iff packing then comparing the - * resulting bytes returns 0. - *) -let test_compatible_with_packing = - QCheck.Test.make - ~name:"compatible_with_packing" - comparable_data_2_arbitrary - (fun (Ex_comparable_data_2 (ty, x, y)) -> - qcheck_compare_comparable_eq - ~expected:(compare_through_pack ty x y) - ty - x - y) - -(* Test. - * Tests that compare_comparable is reflexive. - *) -let test_reflexivity = - QCheck.Test.make - ~name:"reflexivity" - comparable_data_arbitrary - (fun (Ex_comparable_data (ty, x)) -> - qcheck_compare_comparable ~expected:0 ty x x) - -(* Test. - * Tests that compare_comparable is symmetric. - *) -let test_symmetry = - QCheck.Test.make - ~name:"symmetry" - comparable_data_2_arbitrary - (fun (Ex_comparable_data_2 (ty, x, y)) -> - qcheck_compare_comparable - ~expected:(-Script_comparable.compare_comparable ty x y) - ty - y - x) - -(* Test. - * Tests that compare_comparable is transitive. - *) -let test_transitivity = - QCheck.Test.make - ~name:"transitivity" - comparable_data_3_arbitrary - (fun (Ex_comparable_data_3 (ty, x, y, z)) -> - let cxy = Script_comparable.compare_comparable ty x y in - let cyz = Script_comparable.compare_comparable ty y z in - match (cxy, cyz) with - | (0, n) | (n, 0) -> qcheck_compare_comparable ~expected:n ty x z - | (-1, -1) -> qcheck_compare_comparable ~expected:(-1) ty x z - | (1, 1) -> qcheck_compare_comparable ~expected:1 ty x z - | _ -> QCheck.assume_fail ()) - -(* Test. - * Tests the round-trip property for PACK and UNPACK (modulo compare_comparable). - *) -let test_pack_unpack = - QCheck.Test.make - ~count: - 100_000 - (* We run this test on many more cases than the default (100) because this - is a very important property. Packing and then unpacking happens each - time data is sent from a contract to another and also each time storage - is saved at the end of a smart contract call and restored at the next - call of the same contract. Also, injectivity of packing (which is a - direct consequence of this) is an important property for big maps - (because the keys are packed and then hashed). *) - ~name:"pack_unpack" - comparable_data_arbitrary - (fun (Ex_comparable_data (ty, x)) -> - let oty = - match option_key (-1) ty ~annot:None with - | Ok ty -> ty - | Error _ -> assert false - in - qcheck_eq - ~cmp:(Script_comparable.compare_comparable oty) - ~pp:(pp_comparable_data oty) - (Some x) - (unpack_comparable_data ty (pack_comparable_data ty x))) - -let () = - Alcotest.run - "Script_comparison" - [ - ("compatible_with_reference", qcheck_wrap [test_compatible_with_reference]); - ("compatible_with_packing", qcheck_wrap [test_compatible_with_packing]); - ("reflexivity", qcheck_wrap [test_reflexivity]); - ("symmetry", qcheck_wrap [test_symmetry]); - ("transitivity", qcheck_wrap [test_transitivity]); - ("pack_unpack", qcheck_wrap [test_pack_unpack]); - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_script_typed_ir_size.ml b/src/proto_012_Psithaca/lib_protocol/test/test_script_typed_ir_size.ml deleted file mode 100644 index 4c6ea30a6019..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_script_typed_ir_size.ml +++ /dev/null @@ -1,400 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (script typed IR size) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ - -- test "^script typed ir size$" - Subject: Script_typed_ir computes good approximation of values' sizes -*) - -open Protocol - -(* - Helpers - ------- -*) - -exception Script_typed_ir_test_error of string - -let err x = Exn (Script_typed_ir_test_error x) - -let wrap e = Lwt.return (Environment.wrap_tzresult e) - -let iter_n_es n f = - let rec aux k = if k = n then return () else f k >>=? fun () -> aux (k + 1) in - aux 0 - -(* - - We use Snoop's samplers to test that our good approximation of - Michelson values' sizes is indeed a good approximation and that it - is never too far from the reality. - - Architecture: - ------------- - - - module [Samplers] provides samplers for values of type [ty], - [comparable_ty], [code] and any value whose types is dynamically - representable with a [ty]. - - - module [Tests] defines the actual testing procedures and reports - error using [Printers]. - -*) - -module Samplers = struct - let size = {Tezos_benchmark.Base_samplers.min = 4; max = 32} - - module Crypto_samplers = - Tezos_benchmark.Crypto_samplers.Make_finite_key_pool (struct - let size = 10 - - let algo = `Default - end) - - include - Michelson_samplers.Make - (struct - let parameters : Michelson_samplers.parameters = - { - base_parameters = - { - Michelson_samplers_base.int_size = size; - string_size = size; - bytes_size = size; - }; - list_size = size; - set_size = size; - map_size = size; - } - end) - (Crypto_samplers) - - let random_state = Random.State.make [|37; 73; 17; 71; 42|] - - let sample_ty () = Random_type.m_type ~size:10 random_state - - let sample_cty () = Random_type.m_comparable_type ~size:10 random_state - - let sample_value ty = Random_value.value ty random_state - - module Gen = - Michelson_mcmc_samplers.Make_code_sampler (Michelson_base) (Crypto_samplers) - (struct - let rng_state = random_state - - let target_size = 500 - - let verbosity = `Silent - end) - - (* Delay and cache the generator as it's expensive to create. *) - let generator = lazy (Gen.generator ~burn_in:(500 * 7) random_state) - - type exdescr = - | Ex_descr : ('a, 's, 'r, 'f) Script_ir_translator.descr -> exdescr - - let sample_ir_code () = - let Michelson_mcmc_samplers.{term = sample; bef = stack; aft = _} = - (Lazy.force generator) random_state - in - let accounts = Account.generate_accounts 1 in - Block.alpha_context accounts >>=? fun ctxt -> - let code = Micheline.root sample in - let (Ex_stack_ty bef) = - Type_helpers.michelson_type_list_to_ex_stack_ty stack ctxt - in - Script_ir_translator.(parse_instr Lambda ctxt ~legacy:true code bef) - >>= wrap - >>=? fun (ir_code, _) -> - match ir_code with - | Script_ir_translator.Typed ir_code -> return (sample, Ex_descr ir_code) - | _ -> assert false -end - -module Printers = struct - let string_of_something f = - Lwt_main.run - (let accounts = Account.generate_accounts 1 in - Block.alpha_context accounts >>=? fun ctxt -> - f ctxt >>= wrap >>=? fun node -> - let printable = - Micheline_printer.printable - Protocol.Michelson_v1_primitives.string_of_prim - node - in - let b = Buffer.create 13 in - let fmt = Format.formatter_of_buffer b in - Format.fprintf fmt "@[%a@]@." Micheline_printer.print_expr printable ; - return @@ Buffer.contents b) - |> function - | Ok s -> s - | Error (errs : tztrace) -> - Format.eprintf "@[Error: %a@]" pp_print_trace errs ; - exit 1 - - let string_of_value : type a. a Script_typed_ir.ty -> a -> string = - fun ty v -> - string_of_something @@ fun ctxt -> - Script_ir_translator.( - unparse_data ctxt Readable ty v >>=? fun (node, _) -> - return @@ Micheline.strip_locations node) - - let string_of_ty ty = - string_of_something @@ fun ctxt -> - Lwt.return - @@ Script_ir_translator.( - unparse_ty ~loc:() ctxt ty >>? fun (node, _) -> - Ok (Micheline.strip_locations node)) - - let string_of_code code = string_of_something @@ fun _ -> return code - - let string_of_comparable_ty cty = - string_of_ty (Script_ir_translator.ty_of_comparable_ty cty) -end - -module Tests = struct - let footprint v = 8 * Obj.(reachable_words (repr v)) - - let stats = Stdlib.Hashtbl.create 13 - - let remember what vsize rsize = Stdlib.Hashtbl.add stats what (vsize, rsize) - - let check_good_approximation kind ratio what vsize x = - let rsize = footprint x in - let vsize = Saturation_repr.to_int vsize in - remember kind vsize rsize ; - fail_unless - (rsize = 0 || (vsize >= rsize / ratio && vsize <= rsize * ratio)) - (err - (Printf.sprintf - "Computed size for %s is not a good approximation (%d ~/~ %d)" - what - vsize - rsize)) - - let check_in_range what w (v, error) = - let lower_bound = v -. error and upper_bound = v +. error in - fail_unless - (lower_bound <= w && w <= upper_bound) - (err - (Printf.sprintf - "For %s: %f not in [%f; %f]" - what - w - lower_bound - upper_bound)) - - let check_stats what ~expected_mean ~expected_stddev ~expected_ratios = - let entries = Stdlib.Hashtbl.find_all stats what in - let nb_entries = List.length entries in - if nb_entries = 0 then - (* TODO break dependency on other test's side effects: - this value is 0 if the generator did not load the values *) - return_unit - else - let nentries = float_of_int @@ nb_entries in - let ratios = - List.map - (fun (vsize, rsize) -> - (1. +. float_of_int vsize) /. (1. +. float_of_int rsize)) - entries - in - let sum = List.fold_left (fun accu r -> accu +. r) 0. ratios in - let mean = sum /. nentries in - Format.printf "mean: %f@." mean ; - let sqr x = x *. x in - let stddev = - sqrt - (List.fold_left (fun accu r -> accu +. sqr (r -. mean)) 0. ratios - /. nentries) - in - let entries_min = List.fold_left min max_float ratios in - let entries_max = List.fold_left max min_float ratios in - check_in_range (what ^ ":mean") mean expected_mean >>=? fun () -> - check_in_range (what ^ ":stddev") stddev expected_stddev >>=? fun () -> - check_in_range (what ^ ":min") entries_min expected_ratios >>=? fun () -> - check_in_range (what ^ ":max") entries_max expected_ratios - - let ty_size nsamples = - iter_n_es nsamples @@ fun i -> - match Samplers.sample_ty () with - | Ex_ty ty -> - check_good_approximation - "ty_size" - 2 - (Printf.sprintf "type #%d `%s'" i (Printers.string_of_ty ty)) - (snd (Script_typed_ir_size.ty_size ty)) - ty - | exception _ -> return () - - let check_ty_size_stats () = - check_stats - "ty_size" - ~expected_mean:(1., 0.01) - ~expected_stddev:(0., 0.01) - ~expected_ratios:(1., 0.05) - - let comparable_ty_size nsamples = - iter_n_es nsamples @@ fun i -> - match Samplers.sample_cty () with - | Ex_comparable_ty cty -> - check_good_approximation - "comparable_ty_size" - 2 - (Printf.sprintf - "comparable type #%d `%s'" - i - (Printers.string_of_comparable_ty cty)) - (snd (Script_typed_ir_size.comparable_ty_size cty)) - cty - | exception _ -> return () - - let check_comparable_ty_size_stats () = - check_stats - "comparable_ty_size" - ~expected_mean:(1., 0.01) - ~expected_stddev:(0., 0.01) - ~expected_ratios:(1., 0.05) - - let contains_exceptions ty = - let apply : type a. bool -> a Script_typed_ir.ty -> bool = - fun accu -> function - (* Boxed sets and maps point to a shared first class module. - This is an overapproximation that we want to ignore in - the tests. *) - | Set_t _ | Map_t _ - (* We also want to avoid interferences between testing - [lambda_size] and [value_size]. *) - | Lambda_t _ | Contract_t _ -> - true - | _ -> accu - in - Script_typed_ir.ty_traverse - ty - false - {apply; apply_comparable = (fun accu _ -> accu)} - - let value_size nsamples = - iter_n_es nsamples @@ fun i -> - match Samplers.sample_ty () with - | Ex_ty ty when not (contains_exceptions ty) -> ( - match Samplers.sample_value ty with - | v -> - check_good_approximation - "value_size" - (* Used to be 3 but leads to flaky tests. Revert when - determinism is restored and the protocol is more precise - about value sizes. - FIXME: https://gitlab.com/tezos/tezos/-/issues/1784 - FIXME: https://gitlab.com/tezos/tezos/-/issues/1834 *) - 10 - (Printf.sprintf - "value #%d `%s' of type `%s'" - i - (Printers.string_of_value ty v) - (Printers.string_of_ty ty)) - (snd (Script_typed_ir_size.value_size ty v)) - v - | exception _ -> return ()) - | _ | (exception _) -> return () - - let check_value_size_stats () = - (* Stddev set to 0.5, used to be 0.2 but leads to flaky tests. - Revert when determinism is restored and the protocol is more - precise about value sizes. - - FIXME: https://gitlab.com/tezos/tezos/-/issues/1784 - FIXME: https://gitlab.com/tezos/tezos/-/issues/1834 - - Expected_ratios set to 9, used to be 3. - Revert when the following issue is implemented: - FIXME: https://gitlab.com/dannywillems/ocaml-bls12-381/-/issues/55 - *) - check_stats - "value_size" - ~expected_mean:(1., 0.2) - ~expected_stddev:(0., 0.7) - ~expected_ratios:(1., 9.) - - let lambda_size nsamples = - iter_n_es nsamples @@ fun i -> - Samplers.sample_ir_code () >>=? fun (code, Samplers.Ex_descr icode) -> - let kinstr = (Script_ir_translator.close_descr icode).kinstr in - check_good_approximation - "lambda_size" - 3 - (Printf.sprintf "code #%d `%s'" i (Printers.string_of_code code)) - (snd (Script_typed_ir_size.kinstr_size kinstr)) - kinstr - - let check_lambda_size_stats () = - check_stats - "lambda_size" - ~expected_mean:(1., 0.2) - ~expected_stddev:(0., 0.1) - ~expected_ratios:(1., 0.4) -end - -let tests = - let open Tztest in - Tests. - [ - tztest "lambda size is a good approximation (fast)" `Quick (fun () -> - lambda_size 50); - tztest "ty size is a good approximation (fast)" `Quick (fun () -> - ty_size 50); - tztest "value size is a good approximation (fast)" `Quick (fun () -> - value_size 50); - tztest - "comparable ty size is a good approximation (fast)" - `Quick - (fun () -> comparable_ty_size 50); - tztest "lambda size is a good approximation" `Slow (fun () -> - lambda_size 2000); - tztest "value size is a good approximation" `Slow (fun () -> - value_size 1000); - tztest "ty size is a good approximation" `Slow (fun () -> ty_size 1000); - tztest "comparable ty size is a good approximation" `Slow (fun () -> - comparable_ty_size 1000); - tztest - "statistics about ty size are satisfying" - `Quick - check_ty_size_stats; - tztest - "statistics about comparable ty size are satisfying" - `Quick - check_comparable_ty_size_stats; - tztest - "statistics about value size are satisfying" - `Quick - check_value_size_stats; - tztest - "statistics about lambda size are satisfying" - `Quick - check_lambda_size_stats; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_seed.ml b/src/proto_012_Psithaca/lib_protocol/test/test_seed.ml deleted file mode 100644 index b0067764e34b..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_seed.ml +++ /dev/null @@ -1,252 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (seed) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^seed$" - Subject: - seed_nonce_hash included in some blocks - - revelation operation of seed_nonce that should correspond - to each seed_nonce_hash -*) - -open Protocol - -(** Baking [blocks_per_commitment] blocks without a [seed_nonce_hash] - commitment fails with [Invalid_commitment]. *) -let test_no_commitment () = - Context.init ~consensus_threshold:0 5 >>=? fun (b, _) -> - Context.get_constants (B b) - >>=? fun {parametric = {blocks_per_commitment; _}; _} -> - let blocks_per_commitment = Int32.to_int blocks_per_commitment in - (* Bake normally until before the commitment *) - Block.bake_n (blocks_per_commitment - 2) b >>=? fun b -> - (* Forge a block with empty commitment and apply it *) - Block.Forge.forge_header b >>=? fun header -> - Block.Forge.set_seed_nonce_hash None header |> Block.Forge.sign_header - >>=? fun header -> - Block.apply header b >>= fun e -> - Assert.proto_error ~loc:__LOC__ e (function - | Alpha_context.Block_header.Invalid_commitment _ -> true - | _ -> false) - -(** Choose a baker, denote it by id. In the first cycle, make id bake only once. - Check that: - - when id reveals the nonce too early, there's an error - - when id reveals at the right time but the wrong value, there's an error - - when another baker reveals correctly, it receives the tip - - revealing twice produces an error *) -let test_revelation_early_wrong_right_twice () = - let open Assert in - Context.init ~consensus_threshold:0 5 >>=? fun (b, _) -> - Context.get_constants (B b) >>=? fun csts -> - let tip = csts.parametric.seed_nonce_revelation_tip in - let blocks_per_commitment = - Int32.to_int csts.parametric.blocks_per_commitment - in - let baking_reward_fixed_portion = - csts.parametric.baking_reward_fixed_portion - in - (* get the pkh of a baker *) - Block.get_next_baker b >>=? fun (pkh, _, _) -> - let id = Alpha_context.Contract.implicit_contract pkh in - let policy = Block.Excluding [pkh] in - (* bake until commitment - 2, excluding id *) - Block.bake_n ~policy (blocks_per_commitment - 2) b >>=? fun b -> - Context.Contract.balance (B b) id >>=? fun bal_main -> - (* the baker [id] will include a seed_nonce commitment *) - Block.bake ~policy:(Block.By_account pkh) b >>=? fun b -> - Context.get_level (B b) >>?= fun level_commitment -> - Context.get_seed_nonce_hash (B b) >>=? fun committed_hash -> - (* test that the baking reward is received *) - balance_was_credited - ~loc:__LOC__ - (B b) - id - bal_main - baking_reward_fixed_portion - >>=? fun () -> - (* test that revealing too early produces an error *) - Op.seed_nonce_revelation - (B b) - level_commitment - (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get committed_hash) - |> fun operation -> - Block.bake ~policy ~operation b >>= fun e -> - let expected = function - | Nonce_storage.Too_early_revelation -> true - | _ -> false - in - Assert.proto_error ~loc:__LOC__ e expected >>=? fun () -> - (* finish the cycle excluding the committing baker, id *) - Block.bake_until_cycle_end ~policy b >>=? fun b -> - (* test that revealing at the right time but the wrong value - produces an error *) - let (wrong_hash, _) = Nonce.generate () in - Op.seed_nonce_revelation - (B b) - level_commitment - (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get wrong_hash) - |> fun operation -> - Block.bake ~operation b >>= fun e -> - Assert.proto_error ~loc:__LOC__ e (function - | Nonce_storage.Inconsistent_nonce -> true - | _ -> false) - >>=? fun () -> - (* reveals correctly *) - Op.seed_nonce_revelation - (B b) - level_commitment - (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get committed_hash) - |> fun operation -> - Block.get_next_baker ~policy b >>=? fun (baker_pkh, _, _) -> - let baker = Alpha_context.Contract.implicit_contract baker_pkh in - Context.Contract.balance (B b) baker >>=? fun baker_bal -> - Block.bake ~policy:(Block.By_account baker_pkh) ~operation b >>=? fun b -> - (* test that the baker gets the tip reward plus the baking reward*) - balance_was_credited - ~loc:__LOC__ - (B b) - baker - baker_bal - Test_tez.(tip +! baking_reward_fixed_portion) - >>=? fun () -> - (* test that revealing twice produces an error *) - Op.seed_nonce_revelation - (B b) - level_commitment - (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get wrong_hash) - |> fun operation -> - Block.bake ~operation ~policy b >>= fun e -> - Assert.proto_error ~loc:__LOC__ e (function - | Nonce_storage.Previously_revealed_nonce -> true - | _ -> false) - -(** Test that revealing too late produces an error. Note that a - committer who doesn't reveal at cycle 1 is not punished.*) -let test_revelation_missing_and_late () = - let open Context in - let open Assert in - Context.init ~consensus_threshold:0 5 >>=? fun (b, _) -> - get_constants (B b) >>=? fun csts -> - let blocks_per_commitment = - Int32.to_int csts.parametric.blocks_per_commitment - in - (* bake until commitment *) - Block.bake_n (blocks_per_commitment - 2) b >>=? fun b -> - (* the next baker [id] will include a seed_nonce commitment *) - Block.get_next_baker b >>=? fun (pkh, _, _) -> - Block.bake b >>=? fun b -> - Context.get_level (B b) >>?= fun level_commitment -> - Context.get_seed_nonce_hash (B b) >>=? fun committed_hash -> - (* finish cycle 0 excluding the committing baker [id] *) - let policy = Block.Excluding [pkh] in - Block.bake_until_cycle_end ~policy b >>=? fun b -> - (* finish cycle 1 excluding the committing baker [id] *) - Block.bake_until_cycle_end ~policy b >>=? fun b -> - (* test that revealing too late (after cycle 1) produces an error *) - Op.seed_nonce_revelation - (B b) - level_commitment - (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get committed_hash) - |> fun operation -> - Block.bake ~operation b >>= fun e -> - Assert.proto_error ~loc:__LOC__ e (function - | Nonce_storage.Too_late_revelation -> true - | _ -> false) - -let wrap e = e >|= Environment.wrap_tzresult - -(** Test that we do not distribute endorsing rewards if the nonce was - not revealed. *) -let test_unrevealed () = - let open Alpha_context in - let constants = - { - Default_parameters.constants_test with - endorsing_reward_per_slot = Tez.one_mutez; - baking_reward_bonus_per_slot = Tez.zero; - baking_reward_fixed_portion = Tez.zero; - seed_nonce_revelation_tip = Tez.zero; - consensus_threshold = 0; - minimal_participation_ratio = Constants.{numerator = 0; denominator = 1}; - } - in - Context.init_with_constants constants 2 >>=? fun (b, accounts) -> - let (account1, account2) = - match accounts with a1 :: a2 :: _ -> (a1, a2) | _ -> assert false - in - let (_delegate1, delegate2) = - match (Contract.is_implicit account1, Contract.is_implicit account2) with - | (Some d, Some d') -> (d, d') - | _ -> assert false - in - (* Delegate 2 will add a nonce but never reveals it *) - Context.get_constants (B b) >>=? fun csts -> - let blocks_per_commitment = - Int32.to_int csts.parametric.blocks_per_commitment - in - let bake_and_endorse_block ?policy (pred_b, b) = - Context.get_endorsers (B b) >>=? fun slots -> - List.map_es - (fun {Plugin.RPC.Validators.delegate; slots; _} -> - Op.endorsement - ~delegate:(delegate, slots) - ~endorsed_block:b - (B pred_b) - () - >>=? fun op -> Operation.pack op |> return) - slots - >>=? fun endorsements -> Block.bake ?policy ~operations:endorsements b - in - (* Bake until commitment *) - Block.bake_n (blocks_per_commitment - 2) b >>=? fun b -> - (* Baker delegate 2 will include a seed_nonce commitment *) - let policy = Block.By_account delegate2 in - Block.bake_until_cycle_end ~policy b >>=? fun b -> - Context.Delegate.info (B b) delegate2 >>=? fun info_before -> - Block.bake ~policy b >>=? fun b' -> - bake_and_endorse_block ~policy (b, b') >>=? fun b -> - (* Finish cycle 1 excluding the first baker *) - Block.bake_until_cycle_end ~policy b >>=? fun b -> - Context.Delegate.info (B b) delegate2 >>=? fun info_after -> - (* Assert that we did not received a reward because we didn't - reveal the nonce. *) - Assert.equal_tez ~loc:__LOC__ info_before.full_balance info_after.full_balance - >>=? fun () -> return_unit - -let tests = - [ - Tztest.tztest "no commitment" `Quick test_no_commitment; - Tztest.tztest - "revelation_early_wrong_right_twice" - `Quick - test_revelation_early_wrong_right_twice; - Tztest.tztest - "revelation_missing_and_late" - `Quick - test_revelation_missing_and_late; - Tztest.tztest "test unrevealed" `Quick test_unrevealed; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_storage.ml b/src/proto_012_Psithaca/lib_protocol/test/test_storage.ml deleted file mode 100644 index b65ceab189b2..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_storage.ml +++ /dev/null @@ -1,224 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Context Storage - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test storage - Subject: Test the correctnesss of debug message from storage_functor - *) - -open Protocol -open Storage_functors -open Storage_sigs - -module Int32 = struct - type t = int32 - - let encoding = Data_encoding.int32 - - module Index = struct - type t = int - - let path_length = 1 - - let to_path c l = string_of_int c :: l - - let of_path = function - | [] | _ :: _ :: _ -> None - | [c] -> int_of_string_opt c - - type 'a ipath = 'a * t - - let args = - Storage_description.One - { - rpc_arg = Environment.RPC_arg.int; - encoding = Data_encoding.int31; - compare = Compare.Int.compare; - } - end -end - -module Int64 = struct - type t = int64 - - let encoding = Data_encoding.int64 - - module Index = struct - type t = int64 - - let path_length = 1 - - let to_path c l = Int64.to_string c :: l - - let of_path = function - | [] | _ :: _ :: _ -> None - | [c] -> Int64.of_string_opt c - - type 'a ipath = 'a * t - - let args = - Storage_description.One - { - rpc_arg = Environment.RPC_arg.int64; - encoding = Data_encoding.int64; - compare = Compare.Int64.compare; - } - end -end - -let create_context name : (module Raw_context.T with type t = Raw_context.t) = - (module Make_subcontext (Registered) (Raw_context) - (struct - let name = [name] - end)) - -let create_subcontext name - (module Context : Raw_context.T with type t = Raw_context.t) : - (module Raw_context.T with type t = Raw_context.t) = - (module Make_subcontext (Registered) (Context) - (struct - let name = [name] - end)) - -let create_single_data_storage name - (module Context : Raw_context.T with type t = Raw_context.t) : - (module Single_data_storage with type t = Context.t and type value = Int32.t) - = - (module Make_single_data_storage (Registered) (Context) - (struct - let name = [name] - end) - (Int32)) - -let create_indexed_subcontext_int32 - (module Context : Raw_context.T with type t = Raw_context.t) : - (module Data_set_storage with type t = Raw_context.t) = - (module Make_data_set_storage (Context) (Int32.Index)) - -let create_indexed_subcontext_int64 - (module Context : Raw_context.T with type t = Raw_context.t) : - (module Data_set_storage with type t = Raw_context.t) = - (module Make_data_set_storage (Context) (Int64.Index)) - -let must_failwith f_prog error = - try - let _ = f_prog () in - Alcotest.fail "Unexpected successful result" - with exc -> - if exc = error then Lwt.return_unit - else Alcotest.fail "Unexpected error result" - -(** Test: - - This test check that creating value where value already exists - fails*) -let test_register_single_data () = - let f_prog () = - let context = create_context "context1" in - let _single_data = create_single_data_storage "single_data" context in - create_single_data_storage "single_data" context - in - let error = - Invalid_argument - "Could not register a value at [context1 / single_data] because of an \ - existing Value." - in - must_failwith f_prog error - -(** Test: - - This test check that creating a subcontext where a value already exists - fails*) -let test_register_named_subcontext () = - let f_prog () = - let context = create_context "context2" in - let subcontext = create_subcontext "sub_context" context in - let _single_data = create_single_data_storage "error_register" subcontext in - let subcontext = create_subcontext "error_register" subcontext in - create_single_data_storage "single_data2" subcontext - in - let error = - Invalid_argument - "Could not register a named subcontext at [context2 / sub_context / \ - error_register] because of an existing Value." - in - must_failwith f_prog error - -(** Test: - - This test check that creating a indexed subcontext where a value already - exists fails*) -let test_register_indexed_subcontext () = - let f_prog () = - let context = create_context "context3" in - let _ = create_single_data_storage "single_value" context in - create_indexed_subcontext_int32 context - in - let error = - Invalid_argument - "Could not register an indexed subcontext at [context3] because of an \ - existing \n\ - single_value Value." - in - must_failwith f_prog error - -(** Test: - - This test check that creating a indexed subcontext where an indexed - subcontext already exists fails*) -let test_register_indexed_subcontext_2 () = - let f_prog () = - let context = create_context "context4" in - let _ = create_indexed_subcontext_int32 context in - create_indexed_subcontext_int64 context - in - let error = - Invalid_argument - "An indexed subcontext at [context4] already exists but has a different \ - argument: `int64` <> `int`." - in - must_failwith f_prog error - -let tests = - [ - Alcotest_lwt.test_case - "register single data in existing path" - `Quick - (fun _ -> test_register_single_data); - Alcotest_lwt.test_case - "register named subcontext in existing path" - `Quick - (fun _ -> test_register_named_subcontext); - Alcotest_lwt.test_case - "register indexed subcontext in existing path" - `Quick - (fun _ -> test_register_indexed_subcontext); - Alcotest_lwt.test_case - "register indexed subcontext with existing indexed subcontext" - `Quick - (fun _ -> test_register_indexed_subcontext_2); - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_temp_big_maps.ml b/src/proto_012_Psithaca/lib_protocol/test/test_temp_big_maps.ml deleted file mode 100644 index 831e68be7919..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_temp_big_maps.ml +++ /dev/null @@ -1,100 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (temporary big maps) - Invocation: cd src/proto_alpha/lib_protocol/test && dune exec ./main.exe -- test "^temp big maps$" - Subject: On temporary big maps. -*) - -open Protocol - -let to_raw_context (b : Block.t) = - Raw_context.prepare - b.context - ~level:b.header.shell.level - ~predecessor_timestamp:b.header.shell.timestamp - ~timestamp:b.header.shell.timestamp - >|= Environment.wrap_tzresult - -let check_no_dangling_temp_big_map b = - to_raw_context b >>=? fun ctxt -> - Storage.Big_map.fold ctxt ~init:() ~order:`Sorted ~f:(fun id () -> - assert (not (Lazy_storage_kind.Big_map.Id.is_temp id)) ; - Lwt.return_unit) - >>= fun () -> - Storage.Big_map.fold ctxt ~init:() ~order:`Undefined ~f:(fun id () -> - assert (not (Lazy_storage_kind.Big_map.Id.is_temp id)) ; - Lwt.return_unit) - >>= fun () -> return_unit - -let call_the_contract b ~baker ~src contract param_left param_right = - let fee = Alpha_context.Tez.one in - let amount = Alpha_context.Tez.zero in - let param = Printf.sprintf "Pair (%s) %s" param_left param_right in - let parameters = Alpha_context.Script.lazy_expr (Expr.from_string param) in - Op.transaction ~fee (B b) src contract amount ~parameters - >>=? fun operation -> - Incremental.begin_construction ~policy:Block.(By_account baker) b - >>=? fun incr -> - Incremental.add_operation incr operation >>=? fun incr -> - Incremental.finalize_block incr - -(** Originates the contract at contracts/temp_big_maps.tz and calls it with - the pair [(param_left, param_right)]. - An action (originating, storing, passing, passing twice) is done on a big - map (either fresh, passed, or stored). - All combinations are exercised. -*) -let test_temp_big_maps_contract param_left param_right () = - Contract_helpers.init () >>=? fun (b, baker, src, _src2) -> - Contract_helpers.originate_contract - "contracts/temp_big_maps.tz" - "{}" - src - b - baker - >>=? fun (contract, b) -> - check_no_dangling_temp_big_map b >>=? fun () -> - call_the_contract b ~baker ~src contract param_left param_right >>=? fun b -> - check_no_dangling_temp_big_map b - -let param_left_values = ["Left True"; "Left False"; "Right {}"] - -let param_right_values = ["-1"; "0"; "1"; "2"] - -let tests = - List.flatten - (List.map - (fun param_left -> - List.map - (fun param_right -> - Tztest.tztest - (Printf.sprintf "temp_big_maps(%s, %s)" param_left param_right) - `Quick - (test_temp_big_maps_contract param_left param_right)) - param_right_values) - param_left_values) diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_tez_repr.ml b/src/proto_012_Psithaca/lib_protocol/test/test_tez_repr.ml deleted file mode 100644 index 12007f6647e7..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_tez_repr.ml +++ /dev/null @@ -1,140 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol Library - Invocation: dune exec src/proto_alpha/lib_protocol/test/test_tez_repr.exe - Subject: Operations in Tez_repr -*) - -open Protocol.Alpha_context -open Test_tez - -let z_mutez_min = Z.zero - -let z_mutez_max = Z.of_int64 Int64.max_int - -let tez_to_z (tez : Tez.t) : Z.t = Z.of_int64 (Tez.to_mutez tez) - -let z_in_mutez_bounds (z : Z.t) : bool = - Z.Compare.(z_mutez_min <= z && z <= z_mutez_max) - -let compare (c' : Z.t) (c : Tez.t tzresult) : bool = - match (z_in_mutez_bounds @@ c', c) with - | (true, Ok c) -> - Lib_test.Qcheck_helpers.qcheck_eq' - ~pp:Z.pp_print - ~expected:c' - ~actual:(tez_to_z c) - () - | (true, Error _) -> - QCheck.Test.fail_reportf - "@[Results are in Z bounds, but tez operation fails.@]" - | (false, Ok _) -> - QCheck.Test.fail_reportf - "@[Results are not in Z bounds, but tez operation did not fail.@]" - | (false, Error _) -> true - -(* [prop_binop f f' (a, b)] compares the function [f] in Tez with a model - function function [f'] in [Z]. - - If [f' a' b'] falls outside Tez bounds, it is true if [f a b] has - failed. If not, it it is true if [f a b = f' a' b'] where [a'] - (resp. [b']) are [a] (resp. [b']) in [Z]. *) -let prop_binop (f : Tez.t -> Tez.t -> Tez.t tzresult) (f' : Z.t -> Z.t -> Z.t) - ((a, b) : Tez.t * Tez.t) : bool = - compare (f' (tez_to_z a) (tez_to_z b)) (f a b) - -(* [prop_binop64 f f' (a, b)] is as [prop_binop] but for binary operations - where the second operand is of type [int64]. *) -let prop_binop64 (f : Tez.t -> int64 -> Tez.t tzresult) (f' : Z.t -> Z.t -> Z.t) - ((a, b) : Tez.t * int64) : bool = - compare (f' (tez_to_z a) (Z.of_int64 b)) (f a b) - -(** Arbitrary int64 by conversion from int32 *) -let arb_int64_of32 : int64 QCheck.arbitrary = - QCheck.(map ~rev:Int64.to_int32 Int64.of_int32 int32) - -(** Arbitrary int64 mixing small positive integers, - int64s from int32 and arbitrary int64 with equal frequency *) -let arb_int64_sizes : int64 QCheck.arbitrary = - let open QCheck in - oneof - [ - QCheck.map ~rev:Int64.to_int Int64.of_int (int_range (-10) 10); - arb_int64_of32; - int64; - ] - -(** Arbitrary positive int64, mixing small positive integers, - int64s from int32 and arbitrary int64 with equal frequency *) -let arb_ui64_sizes : int64 QCheck.arbitrary = - let open QCheck in - map_same_type - (fun i -> - let v = if i = Int64.min_int then Int64.max_int else Int64.abs i in - assert (v >= 0L) ; - v) - arb_int64_sizes - -(** Arbitrary tez based on [arb_tez_sizes] *) -let arb_tez_sizes = - let open QCheck in - map ~rev:Tez.to_mutez Tez.of_mutez_exn arb_ui64_sizes - -let test_coherent_mul = - QCheck.Test.make - ~name:"Tez.(*?) is coherent w.r.t. Z.(*)" - QCheck.(pair arb_tez_sizes arb_ui64_sizes) - (prop_binop64 ( *? ) Z.( * )) - -let test_coherent_sub = - QCheck.Test.make - ~name:"Tez.(-?) is coherent w.r.t. Z.(-)" - QCheck.(pair arb_tez_sizes arb_tez_sizes) - (prop_binop ( -? ) Z.( - )) - -let test_coherent_add = - QCheck.Test.make - ~name:"Tez.(+?) is coherent w.r.t. Z.(+)" - QCheck.(pair arb_tez_sizes arb_tez_sizes) - (prop_binop ( +? ) Z.( + )) - -let test_coherent_div = - QCheck.Test.make - ~name:"Tez.(/?) is coherent w.r.t. Z.(/)" - QCheck.(pair arb_tez_sizes arb_ui64_sizes) - (fun (a, b) -> - QCheck.assume (b > 0L) ; - prop_binop64 ( /? ) Z.( / ) (a, b)) - -let tests = - [test_coherent_mul; test_coherent_sub; test_coherent_add; test_coherent_div] - -let () = - Alcotest.run - "Tez_repr" - [("Tez_repr", Lib_test.Qcheck_helpers.qcheck_wrap tests)] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_ticket_balance_key.ml b/src/proto_012_Psithaca/lib_protocol/test/test_ticket_balance_key.ml deleted file mode 100644 index 455b87809d28..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_ticket_balance_key.ml +++ /dev/null @@ -1,497 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (Ticket_balance_key) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ - -- test "^ticket balance key" - Subject: Ticket balance key hashing -*) - -open Protocol -open Alpha_context - -let ( let* ) m f = m >>=? f - -let wrap m = m >|= Environment.wrap_tzresult - -let new_ctxt () = - let* (block, _) = Context.init 1 in - let* incr = Incremental.begin_construction block in - return @@ Incremental.alpha_ctxt incr - -let make_contract ticketer = wrap @@ Lwt.return @@ Contract.of_b58check ticketer - -let make_ex_ticket ctxt ~ticketer ~typ ~content ~amount = - let* (Script_ir_translator.Ex_comparable_ty cty, ctxt) = - let node = Micheline.root @@ Expr.from_string typ in - wrap @@ Lwt.return @@ Script_ir_translator.parse_comparable_ty ctxt node - in - let* ticketer = make_contract ticketer in - let* (contents, ctxt) = - let node = Micheline.root @@ Expr.from_string content in - wrap @@ Script_ir_translator.parse_comparable_data ctxt cty node - in - let amount = Script_int.(abs @@ of_int amount) in - let ticket = Script_typed_ir.{ticketer; contents; amount} in - return (Ticket_scanner.Ex_ticket (cty, ticket), ctxt) - -let make_key ctxt ~ticketer ~typ ~content ~amount ~owner = - let* (ex_ticket, ctxt) = - make_ex_ticket ctxt ~ticketer ~typ ~content ~amount - in - let* owner = make_contract owner in - let* (key, amount, ctxt) = - wrap - @@ Ticket_balance_key.ticket_balance_key_and_amount ctxt ex_ticket ~owner - in - return (key, amount, ctxt) - -let equal_script_hash ~loc msg key1 key2 = - Assert.equal - ~loc - Script_expr_hash.equal - msg - Script_expr_hash.pp - (Ticket_balance.script_expr_hash_of_key_hash key1) - (Ticket_balance.script_expr_hash_of_key_hash key2) - -let not_equal_script_hash ~loc msg key1 key2 = - Assert.not_equal - ~loc - Script_expr_hash.equal - msg - Script_expr_hash.pp - (Ticket_balance.script_expr_hash_of_key_hash key1) - (Ticket_balance.script_expr_hash_of_key_hash key2) - -let assert_keys ~ticketer1 ~ticketer2 ~typ1 ~typ2 ~amount1 ~amount2 ~content1 - ~content2 ~owner1 ~owner2 assert_condition = - let* ctxt = new_ctxt () in - let* (key1, amount1, ctxt) = - make_key - ctxt - ~ticketer:ticketer1 - ~typ:typ1 - ~content:content1 - ~amount:amount1 - ~owner:owner1 - in - let* (key2, amount2, _) = - make_key - ctxt - ~ticketer:ticketer2 - ~typ:typ2 - ~content:content2 - ~amount:amount2 - ~owner:owner2 - in - assert_condition (key1, amount1) (key2, amount2) - -let assert_keys_not_equal ~loc = - assert_keys (fun (key1, _) (key2, _) -> - not_equal_script_hash ~loc "Assert that keys are not equal" key1 key2) - -let assert_keys_equal ~loc = - assert_keys (fun (key1, _) (key2, _) -> - equal_script_hash ~loc "Assert that keys are equal" key1 key2) - -let assert_amount ~loc ~ticketer ~typ ~content ~amount ~owner expected = - let* ctxt = new_ctxt () in - let* (_, amount, _ctxt) = - make_key ctxt ~ticketer ~typ ~content ~amount ~owner - in - Assert.equal_int ~loc (Z.to_int amount) expected - -(** Test that the amount returned is as expected. *) -let test_amount () = - assert_amount - ~loc:__LOC__ - ~ticketer:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ:"unit" - ~content:"Unit" - ~amount:42 - ~owner:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - 42 - -(** Test that tickets with two different amounts map to the same hash. - The amount is not part of the ticket balance key. *) -let test_different_amounts () = - assert_keys_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"unit" - ~typ2:"unit" - ~content1:"Unit" - ~content2:"Unit" - ~amount1:1 - ~amount2:2 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that two tickets with different ticketers map to different hashes. *) -let test_different_ticketers () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~typ1:"nat" - ~typ2:"nat" - ~content1:"1" - ~content2:"1" - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that two tickets with different owners map to different hashes. *) -let test_different_owners () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"nat" - ~typ2:"nat" - ~content1:"1" - ~content2:"1" - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - -(** Test that two tickets with different contents map to different hashes. *) -let test_different_content () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"nat" - ~typ2:"nat" - ~content1:"1" - ~content2:"2" - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type nat and a ticket of type int, with the same - content, map to different hashes. *) -let test_nat_int () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"nat" - ~typ2:"int" - ~content1:"1" - ~content2:"1" - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type nat and a ticket of type mutez, with the same - content, map to different hashes. *) -let test_nat_mutez () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"nat" - ~typ2:"mutez" - ~content1:"1" - ~content2:"1" - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type nat and a ticket of type bool, with the - contents (False/0), map to different hashes. *) -let test_bool_nat () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"bool" - ~typ2:"nat" - ~content1:"False" - ~content2:"0" - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type nat and a ticket of type bytes, with the - contents (0/0x), map to different hashes. *) -let test_nat_bytes () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"nat" - ~typ2:"bytes" - ~content1:"0" - ~content2:"0x" - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type string and a chain_id with same content - map to different hashes. *) -let test_string_chain_id () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"string" - ~typ2:"chain_id" - ~content1:{|"NetXynUjJNZm7wi"|} - ~content2:{|"NetXynUjJNZm7wi"|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type string and a key_hash with same content - map to different hashes. *) -let test_string_key_hash () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"string" - ~typ2:"key_hash" - ~content1:{|"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"|} - ~content2:{|"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type string and a key with same content - map to different hashes. *) -let test_string_key () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"string" - ~typ2:"key" - ~content1:{|"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"|} - ~content2:{|"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type string and a timestamp with same content - map to different hashes. *) -let test_string_timestamp () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"string" - ~typ2:"timestamp" - ~content1:{|"2019-09-26T10:59:51Z"|} - ~content2:{|"2019-09-26T10:59:51Z"|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type string and a address with same content - map to different hashes. *) -let test_string_address () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"string" - ~typ2:"address" - ~content1:{|"KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%entrypoint"|} - ~content2:{|"KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%entrypoint"|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type string and a signature with same content - map to different hashes. *) -let test_string_signature () = - let signature = - {|"edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7"|} - in - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"string" - ~typ2:"signature" - ~content1:signature - ~content2:signature - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Tests that annotations are not taken into account when hashing keys. - Two comparable types that only differ in their annotations should - map to to the same hash. Here, the type [pair int string] is identical to - [pair (int %id) (string %name)]. - *) -let test_annotation_pair () = - assert_keys_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"(pair int string)" - ~typ2:{|(pair (int %id) (string %name))|} - ~content1:{|Pair 1 "hello"|} - ~content2:{|Pair 1 "hello"|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Tests that annotations are not taken into account when hashing keys. - Here the types [or int string] and [or (int %id) (string %name)] - should hash to the same key. - *) -let test_annotation_or () = - assert_keys_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"(or int string)" - ~typ2:{|(or (int %id) (string %name))|} - ~content1:{|Left 1|} - ~content2:{|Left 1|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Tests that annotations are not taken into account when hashing keys. - Here the types [int] and [(int :int_alias)] should hash to the same key. - *) -let test_annotation_type_alias () = - assert_keys_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"int" - ~typ2:"(int :int_alias)" - ~content1:"0" - ~content2:"0" - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Tests that annotations are not taken into account when hashing keys. - Here the types [pair (or int string) int] and - [pair (or (int %id) (string %name)) int] should hash to the same key. - *) -let test_annotation_pair_or () = - assert_keys_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"pair (or int string) int" - ~typ2:{|pair (or (int %id) (string %name)) int|} - ~content1:{|Pair (Left 1) 2|} - ~content2:{|Pair (Left 1) 2|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type [option int] and [option nat] with the same - content, [None], don't map to the same hash. *) -let test_option_none () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"option int" - ~typ2:"option nat" - ~content1:{|None|} - ~content2:{|None|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -(** Test that a ticket of type [option int] and [option nat] with the same - content, [Some 0], don't map to the same hash. *) -let test_option_some () = - assert_keys_not_equal - ~loc:__LOC__ - ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~typ1:"option int" - ~typ2:"option nat" - ~content1:{|Some 0|} - ~content2:{|Some 0|} - ~amount1:1 - ~amount2:1 - ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" - -let tests = - [ - Tztest.tztest "Test amount" `Quick test_amount; - Tztest.tztest "Test different ticketers" `Quick test_different_ticketers; - Tztest.tztest "Test different owners" `Quick test_different_owners; - Tztest.tztest "Test different content" `Quick test_different_content; - Tztest.tztest "Test different amounts" `Quick test_different_amounts; - Tztest.tztest "Test nat int" `Quick test_nat_int; - Tztest.tztest "Test nat mutez" `Quick test_nat_mutez; - Tztest.tztest "Test not bool" `Quick test_bool_nat; - Tztest.tztest "Test nat bytes" `Quick test_nat_bytes; - Tztest.tztest "Test string chain_id" `Quick test_string_chain_id; - Tztest.tztest "Test string key_hash" `Quick test_string_key_hash; - Tztest.tztest "Test string timestamp" `Quick test_string_timestamp; - Tztest.tztest "Test string address" `Quick test_string_address; - Tztest.tztest "Test string key" `Quick test_string_key; - Tztest.tztest "Test string signature" `Quick test_string_signature; - Tztest.tztest "Test annotations for pair" `Quick test_annotation_pair; - Tztest.tztest "Test annotations for or" `Quick test_annotation_or; - Tztest.tztest - "Test annotations for type alias" - `Quick - test_annotation_type_alias; - Tztest.tztest - "Test annotations for paired ors" - `Quick - test_annotation_pair_or; - Tztest.tztest "Test option none" `Quick test_option_none; - Tztest.tztest "Test option some" `Quick test_option_some; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_ticket_scanner.ml b/src/proto_012_Psithaca/lib_protocol/test/test_ticket_scanner.ml deleted file mode 100644 index d83a71677195..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_ticket_scanner.ml +++ /dev/null @@ -1,593 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (Ticket_scanner) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^ticket scanner" - Subject: Ticket scanner tests -*) - -open Protocol -open Alpha_context - -let ( let* ) m f = m >>=? f - -let wrap m = m >|= Environment.wrap_tzresult - -let new_ctxt () = - let* (block, _) = Context.init 1 in - let* incr = Incremental.begin_construction block in - return @@ Incremental.alpha_ctxt incr - -let assert_equal_string_list ~loc msg = - Assert.assert_equal_list ~loc String.equal msg Format.pp_print_string - -let string_list_of_ex_tickets ctxt tickets = - let accum (xs, ctxt) - (Ticket_scanner.Ex_ticket - (cty, {Script_typed_ir.ticketer; contents; amount})) = - let* (x, ctxt) = - wrap - @@ Script_ir_translator.unparse_data - ctxt - Script_ir_translator.Readable - (Script_ir_translator.ty_of_comparable_ty cty) - contents - in - let content = - Format.kasprintf - Fun.id - "%a" - Michelson_v1_printer.print_expr - (Micheline.strip_locations x) - in - let str = - Format.kasprintf - Fun.id - "(%a, %s, %a)" - Contract.pp - ticketer - content - Z.pp_print - (Script_int.to_zint amount) - in - return (str :: xs, ctxt) - in - let* (xs, ctxt) = List.fold_left_es accum ([], ctxt) tickets in - return (List.rev xs, ctxt) - -let make_ex_ticket ctxt ~ticketer ~type_exp ~content_exp ~amount = - let* (Script_ir_translator.Ex_comparable_ty cty, ctxt) = - let node = Micheline.root @@ Expr.from_string type_exp in - wrap @@ Lwt.return @@ Script_ir_translator.parse_comparable_ty ctxt node - in - let* ticketer = wrap @@ Lwt.return @@ Contract.of_b58check ticketer in - let* (contents, ctxt) = - let node = Micheline.root @@ Expr.from_string content_exp in - wrap @@ Script_ir_translator.parse_comparable_data ctxt cty node - in - let amount = Script_int.(abs @@ of_int amount) in - let ticket = Script_typed_ir.{ticketer; contents; amount} in - return (Ticket_scanner.Ex_ticket (cty, ticket), ctxt) - -let assert_equals_ex_tickets ctxt ~loc ex_tickets expected = - let* (str_tickets, ctxt) = string_list_of_ex_tickets ctxt ex_tickets in - let* (str_tickets_expected, _ctxt) = - string_list_of_ex_tickets ctxt expected - in - assert_equal_string_list - ~loc - "Compare with expected tickets" - (List.sort String.compare str_tickets) - (List.sort String.compare str_tickets_expected) - -let tickets_of_value ctxt ~include_lazy ~type_exp ~value_exp = - let (Script_ir_translator.Ex_ty ty, ctxt) = - let node = Micheline.root @@ Expr.from_string type_exp in - Result.value_f - ~default:(fun () -> Stdlib.failwith "Failed to parse") - (Script_ir_translator.parse_any_ty ctxt ~legacy:false node) - in - let node = Micheline.root @@ Expr.from_string value_exp in - let* (value, ctxt) = - wrap - @@ Script_ir_translator.parse_data - ctxt - ~legacy:false - ~allow_forged:true - ty - node - in - wrap @@ Ticket_scanner.tickets_of_value ctxt ~include_lazy ty value - -let assert_contains_tickets ctxt ~loc ~include_lazy ~type_exp ~value_exp - expected = - let* (ex_tickets, _) = - tickets_of_value ctxt ~include_lazy ~type_exp ~value_exp - in - assert_equals_ex_tickets ctxt ~loc ex_tickets expected - -let assert_fail_non_empty_overlay ctxt ~loc ~include_lazy ~type_exp ~value_exp = - tickets_of_value ctxt ~include_lazy ~type_exp ~value_exp >>= fun res -> - match res with - | Error [x] -> - let x = Format.kasprintf Fun.id "%a" Error_monad.pp x in - Assert.equal - ~loc - String.equal - "" - Format.pp_print_string - "Unsupported big-map value with non-empty overlay" - x - | _ -> failwith "Expected an error at %s" loc - -let make_string_tickets ctxt ticketer_amounts = - List.fold_right_es - (fun (ticketer, content, amount) (tickets, ctxt) -> - let* (ticket, ctxt) = - make_ex_ticket - ctxt - ~ticketer - ~type_exp:"string" - ~content_exp:(Printf.sprintf {|"%s"|} content) - ~amount - in - return (ticket :: tickets, ctxt)) - ticketer_amounts - ([], ctxt) - -let tickets_from_big_map_ref ~pre_populated value_exp = - let* (block, contracts) = Context.init 1 in - let source = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - let* (operation, originated) = - Op.origination (B block) source ~script:Op.dummy_script - in - let* block = Block.bake ~operation block in - let* inc = Incremental.begin_construction block in - let ctxt = Incremental.alpha_ctxt inc in - let* (ctxt, big_map_id) = wrap @@ Big_map.fresh ~temporary:false ctxt in - let int_ty_expr = Expr.from_string "int" in - let* (diffs, ctxt) = - let* (updates, ctxt) = - List.fold_left_es - (fun (kvs, ctxt) (key, value) -> - let* (key_hash, ctxt) = - wrap - @@ Script_ir_translator.hash_comparable_data - ctxt - (Script_typed_ir.int_key ~annot:None) - (Script_int_repr.of_int key) - in - return - ( { - Big_map.key = Expr.from_string @@ string_of_int key; - key_hash; - value = Some (Expr.from_string value); - } - :: kvs, - ctxt )) - ([], ctxt) - pre_populated - in - let alloc = - Big_map. - {key_type = int_ty_expr; value_type = Expr.from_string "ticket string"} - in - return - ( [ - Lazy_storage.make - Lazy_storage.Kind.Big_map - big_map_id - (Update {init = Lazy_storage.Alloc alloc; updates}); - ], - ctxt ) - in - let* ctxt = - wrap - @@ Contract.update_script_storage ctxt originated int_ty_expr (Some diffs) - in - let value_exp = - value_exp @@ Z.to_string (Big_map.Id.unparse_to_z big_map_id) - in - return (value_exp, ctxt) - -let assert_big_map_int_ticket_string_ref ~loc ~pre_populated ~big_map_exp - ex_tickets = - let* (value_exp, ctxt) = - tickets_from_big_map_ref ~pre_populated big_map_exp - in - let* (ex_tickets, ctxt) = make_string_tickets ctxt ex_tickets in - assert_contains_tickets - ctxt - ~include_lazy:true - ~loc - ~type_exp:"big_map int (ticket string)" - ~value_exp - ex_tickets - -let assert_fail_non_empty_overlay_with_big_map_ref ~loc ~pre_populated - ~big_map_exp = - let* (value_exp, ctxt) = - tickets_from_big_map_ref ~pre_populated big_map_exp - in - assert_fail_non_empty_overlay - ctxt - ~include_lazy:true - ~loc - ~type_exp:"big_map int (ticket string)" - ~value_exp - -(** Test that the ticket can be extracted from a a single unit ticket *) -let test_tickets_in_unit_ticket () = - let* ctxt = new_ctxt () in - let type_exp = "ticket(unit)" in - let value_exp = {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" Unit 10|} in - let* (ex_ticket, ctxt) = - make_ex_ticket - ctxt - ~ticketer:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" - ~type_exp:"unit" - ~content_exp:"Unit" - ~amount:10 - in - assert_contains_tickets - ctxt - ~loc:__LOC__ - ~include_lazy:false - ~type_exp - ~value_exp - [ex_ticket] - -let assert_string_tickets ~loc ~include_lazy ~type_exp ~value_exp ~expected = - let* ctxt = new_ctxt () in - let* (ex_tickets, ctxt) = make_string_tickets ctxt expected in - assert_contains_tickets - ctxt - ~include_lazy - ~loc - ~type_exp - ~value_exp - ex_tickets - -(** Test that all tickets can be extracted from a list of tickets *) -let test_tickets_in_list () = - assert_string_tickets - ~loc:__LOC__ - ~include_lazy:false - ~type_exp:"list(ticket(string))" - ~value_exp: - {| - { - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 3; - } - |} - ~expected: - [ - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1); - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "green", 2); - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "blue", 3); - ] - -(** Test that all tickets can be extracted from a pair of tickets *) -let test_tickets_in_pair () = - assert_string_tickets - ~loc:__LOC__ - ~include_lazy:false - ~type_exp:"pair (ticket string) (ticket string)" - ~value_exp: - {| - Pair - (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) - (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2) - |} - ~expected: - [ - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1); - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "green", 2); - ] - -(** Test that all tickets from a map can be extracted. *) -let test_tickets_in_map () = - assert_string_tickets - ~loc:__LOC__ - ~include_lazy:false - ~type_exp:"map int (ticket string)" - ~value_exp: - {| - { - Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); - Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); - } - |} - ~expected: - [ - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1); - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "green", 2); - ] - -(** Test that all tickets from a big-map with non-empty overlay fails. - If we extend the ticket scanner function to support non-empty overlays - this test needs to be adapted. - *) -let test_tickets_in_big_map () = - let* ctxt = new_ctxt () in - assert_fail_non_empty_overlay - ctxt - ~loc:__LOC__ - ~include_lazy:true - ~type_exp:"big_map int (ticket string)" - ~value_exp: - {| - { - Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); - Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); - } - |} - -(** Test that tickets are not extracted from big-map with [include_lazy] set - to false. *) -let test_tickets_in_big_map_strict_only () = - assert_string_tickets - ~loc:__LOC__ - ~include_lazy:false - ~type_exp:"big_map int (ticket string)" - ~value_exp: - {| - { - Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); - Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); - } - |} - ~expected:[] - -(** Test that tickets can be extracted from a list of tickets inside a big-map - This fails due to non-empty overlay. If we extend the ticket scanner - function to support non-empty overlays this test needs to be adapted. -*) -let test_tickets_in_list_in_big_map () = - let* ctxt = new_ctxt () in - assert_fail_non_empty_overlay - ctxt - ~loc:__LOC__ - ~include_lazy:true - ~type_exp:"(big_map int (list(ticket string)))" - ~value_exp: - {| - { - Elt 1 { - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1 ; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1 - }; - Elt 2 { - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1 ; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 1 - } - } - |} - -(** Test that tickets can be extracted from a combination of a list and lazy structure - and that only the strict part is considered with [include_lazy] set to fasle *) -let test_tickets_in_pair_big_map_and_list_strict_only () = - assert_string_tickets - ~loc:__LOC__ - ~include_lazy:false - ~type_exp:"pair (big_map int (ticket string)) (list (ticket string))" - ~value_exp: - {| - Pair - { - Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); - Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1) - } - { - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 1 - } - |} - ~expected: - [ - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "blue", 1); - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "orange", 1); - ] - -(** Test that tickets can be extracted from the left side of an or-expression. *) -let test_tickets_in_or_left () = - assert_string_tickets - ~loc:__LOC__ - ~include_lazy:false - ~type_exp:"or (ticket string) int" - ~value_exp:{| Left (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) |} - ~expected:[("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1)] - -(** Test that tickets can be extracted from the right side of an or-expression. *) -let test_tickets_in_or_right () = - assert_string_tickets - ~loc:__LOC__ - ~include_lazy:false - ~type_exp:"or int (ticket string)" - ~value_exp:{| Right (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) |} - ~expected:[("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1)] - -(* - Big maps have three possible representations. Either as a list of key-value - pairs, as an identifier (int), or as a pair of identifier and overrides. - Example values: - - 1) { Elt "bar" True ; Elt "foo" False } - 2) 42 - 3) Pair 42 { Elt "foo" (Some False) } - *) - -(** Test tickets from empty big_map when passed by reference. *) -let test_tickets_in_empty_big_map_ref () = - assert_big_map_int_ticket_string_ref - ~loc:__LOC__ - ~pre_populated:[] - ~big_map_exp:(Printf.sprintf "%s") - [] - -(** Test tickets from non-empty big-map when passed by reference. - Here, tickets are scanned from the context. *) -let test_tickets_in_non_empty_big_map_ref () = - assert_big_map_int_ticket_string_ref - ~loc:__LOC__ - ~pre_populated: - [ - (1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|}); - (2, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1|}); - (3, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1|}); - ] - ~big_map_exp:(Printf.sprintf "%s") - [ - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1); - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "green", 1); - ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "blue", 1); - ] - -(** Test tickets from empty big-map when passed as a pair of identifier - and overrides. Here, the scanned tickets are only contained in the overlay - why ticket-scanning fails. - - If we extend the ticket scanner function to support non-empty overlays - this test needs to be adapted. - *) -let test_tickets_overlay_in_empty_big_map_ref () = - assert_fail_non_empty_overlay_with_big_map_ref - ~loc:__LOC__ - ~pre_populated:[] - ~big_map_exp: - (Printf.sprintf - {|Pair %s { Elt 1 (Some (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1))}|}) - -(** Test tickets from non-empty big-map when passed as a pair of identifier - and overrides. The scanned tickets are contained in the context as well as - in the overlay. Since overlay is non-empty is non-empty, ticket scanning - fails. - - If we extend the ticket scanner function to support non-empty overlays - this test needs to be adapted - *) -let test_tickets_overlay_in_non_empty_in_big_map_ref () = - assert_fail_non_empty_overlay_with_big_map_ref - ~loc:__LOC__ - ~pre_populated: - [ - (1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|}); - (2, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1|}); - (3, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1|}); - ] - ~big_map_exp: - (Printf.sprintf - {| Pair - %s - { Elt 4 (Some (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 1))} - |}) - -(** Test tickets from non-empty big-map when passed as a pair of identifier - and overrides, and where the override replaces an existing ticket. - Ticket scanning fails due to non-empty overlay. - - If we extend the ticket scanner function to support non-empty overlays - this test needs to be adapted. - *) -let test_tickets_replace_overlay_in_non_empty_in_big_map_ref () = - assert_fail_non_empty_overlay_with_big_map_ref - ~loc:__LOC__ - ~pre_populated: - [(1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|})] - ~big_map_exp: - (Printf.sprintf - {| Pair - %s - { Elt 1 (Some (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1))} - |}) - -(** Test tickets from non-empty big-map when passed as a pair of identifier - and overrides, and where the override removes an existing ticket. - Ticket scanning fails due to non-empty overlay. - - If we extend the ticket scanner function to support non-empty overlays - this test needs to be adapted. - *) -let test_tickets_remove_overlay_in_non_empty_in_big_map_ref () = - assert_fail_non_empty_overlay_with_big_map_ref - ~loc:__LOC__ - ~pre_populated: - [(1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|})] - ~big_map_exp:(Printf.sprintf {| Pair %s { Elt 1 None} |}) - -let tests = - [ - Tztest.tztest - "Test tickets in unit ticket" - `Quick - test_tickets_in_unit_ticket; - Tztest.tztest "Test tickets in list" `Quick test_tickets_in_list; - Tztest.tztest "Test tickets in pair" `Quick test_tickets_in_pair; - Tztest.tztest "Test tickets in map" `Quick test_tickets_in_map; - Tztest.tztest "Test tickets in big map" `Quick test_tickets_in_big_map; - Tztest.tztest - "Test tickets in big map with include lazy set to false" - `Quick - test_tickets_in_big_map_strict_only; - Tztest.tztest - "Test tickets in list in big map" - `Quick - test_tickets_in_list_in_big_map; - Tztest.tztest - "Test tickets in a pair of big-map and list with include lazy set to \ - false" - `Quick - test_tickets_in_pair_big_map_and_list_strict_only; - Tztest.tztest "Test tickets in or left" `Quick test_tickets_in_or_left; - Tztest.tztest "Test tickets in or right" `Quick test_tickets_in_or_right; - Tztest.tztest - "Test tickets in empty big-map ref" - `Quick - test_tickets_overlay_in_empty_big_map_ref; - Tztest.tztest - "Test tickets in big-map ref" - `Quick - test_tickets_in_empty_big_map_ref; - Tztest.tztest - "Test tickets in non-empty big-map ref" - `Quick - test_tickets_in_non_empty_big_map_ref; - Tztest.tztest - "Test tickets in non-empty big-map ref with overlay" - `Quick - test_tickets_overlay_in_non_empty_in_big_map_ref; - Tztest.tztest - "Test tickets replace existing value from overlay" - `Quick - test_tickets_replace_overlay_in_non_empty_in_big_map_ref; - Tztest.tztest - "Test tickets remove existing value from overlay" - `Quick - test_tickets_remove_overlay_in_non_empty_in_big_map_ref; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_ticket_storage.ml b/src/proto_012_Psithaca/lib_protocol/test/test_ticket_storage.ml deleted file mode 100644 index ab67b92e5de1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_ticket_storage.ml +++ /dev/null @@ -1,288 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (Alpha_context.Ticket_balance) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^ticket storage$" - Subject: Ticket storage functions tested using the Ticket_balance module in Alpha_context. -*) - -open Protocol -open Alpha_context - -let ( let* ) m f = m >>=? f - -let wrap m = m >|= Environment.wrap_tzresult - -let make_context () = - let* (block, _) = Context.init 1 in - let* incr = Incremental.begin_construction block in - return (Incremental.alpha_ctxt incr) - -let hash_key ctxt ~ticketer ~typ ~contents ~owner = - let ticketer = Micheline.root @@ Expr.from_string ticketer in - let typ = Micheline.root @@ Expr.from_string typ in - let contents = Micheline.root @@ Expr.from_string contents in - let owner = Micheline.root @@ Expr.from_string owner in - wrap - @@ Lwt.return - (Alpha_context.Ticket_balance.make_key_hash - ctxt - ~ticketer - ~typ - ~contents - ~owner) - -let assert_balance ctxt ~loc key expected = - let* (balance, _) = wrap @@ Ticket_balance.get_balance ctxt key in - match balance with - | Some b -> Assert.equal_int ~loc (Z.to_int b) expected - | None -> failwith "Expected balance %d" expected - -let assert_no_balance ctxt key = - let* (balance, _) = wrap @@ Ticket_balance.get_balance ctxt key in - match balance with - | Some b -> failwith "Expected empty (none) balance but got %d" (Z.to_int b) - | None -> return () - -let adjust_balance ctxt key delta = - wrap @@ Ticket_balance.adjust_balance ctxt key ~delta:(Z.of_int delta) - -let assert_non_overlapping_keys ~loc ~ticketer1 ~ticketer2 ~contents1 ~contents2 - ~typ1 ~typ2 ~owner1 ~owner2 = - let* ctxt = make_context () in - let* (k1, ctxt) = - hash_key - ctxt - ~ticketer:ticketer1 - ~typ:typ1 - ~contents:contents1 - ~owner:owner1 - in - let* (k2, _ctxt) = - hash_key - ctxt - ~ticketer:ticketer2 - ~typ:typ2 - ~contents:contents2 - ~owner:owner2 - in - let k1 = Ticket_balance.script_expr_hash_of_key_hash k1 in - let k2 = Ticket_balance.script_expr_hash_of_key_hash k2 in - Assert.not_equal - ~loc - Script_expr_hash.equal - "Keys should not overlap" - Script_expr_hash.pp - k1 - k2 - -let make_key ctxt content = - hash_key - ctxt - ~ticketer:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~typ:"string" - ~contents:(Printf.sprintf {|"%s"|} content) - ~owner:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - -(** Test that key-hashes constructed from different ticketers don't overlap. *) -let test_non_overlapping_keys_ticketer () = - assert_non_overlapping_keys - ~loc:__LOC__ - ~ticketer1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~ticketer2:{|"KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn"|} - ~typ1:"nat" - ~typ2:"int" - ~contents1:{|"1"|} - ~contents2:{|"1"|} - ~owner1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~owner2:{|"KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn"|} - -(** Test that key-hashes constructed from different contents don't overlap. *) -let test_non_overlapping_keys_contents () = - assert_non_overlapping_keys - ~loc:__LOC__ - ~ticketer1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~ticketer2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~typ1:"string" - ~typ2:"string" - ~contents1:{|"red"|} - ~contents2:{|"blue"|} - ~owner1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~owner2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - -(** Test that key-hashes constructed from different content-types don't overlap. *) -let test_non_overlapping_keys_type () = - assert_non_overlapping_keys - ~loc:__LOC__ - ~ticketer1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~ticketer2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~typ1:"nat" - ~typ2:"int" - ~contents1:{|"1"|} - ~contents2:{|"1"|} - ~owner1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~owner2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - -(** Test that key-hashes constructed from different owners don't overlap. *) -let test_non_overlapping_keys_owner () = - assert_non_overlapping_keys - ~loc:__LOC__ - ~ticketer1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~ticketer2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~typ1:"nat" - ~typ2:"int" - ~contents1:{|"1"|} - ~contents2:{|"1"|} - ~owner1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} - ~owner2:{|"KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn"|} - -(** Test that updating the ticket balance table has - the intended effect. - *) -let test_ticket_balance_single_update () = - let* ctxt = make_context () in - let* (alice_red, ctxt) = make_key ctxt "alice_red" in - let* (_, ctxt) = adjust_balance ctxt alice_red 1 in - assert_balance ctxt ~loc:__LOC__ alice_red 1 - -(** Test that updating the ticket-balance table with different keys - updates both entries. *) -let test_ticket_balance_different_owners () = - let* ctxt = make_context () in - let* (alice_red, ctxt) = make_key ctxt "alice_red" in - let* (alice_blue, ctxt) = make_key ctxt "alice_blue" in - let* (_, ctxt) = adjust_balance ctxt alice_red 1 in - let* (_, ctxt) = adjust_balance ctxt alice_blue 1 in - let* () = assert_balance ctxt ~loc:__LOC__ alice_red 1 in - let* () = assert_balance ctxt ~loc:__LOC__ alice_blue 1 in - return () - -(** Test updating the same entry with multiple updates yields - the net result of all balance updates *) -let test_ticket_balance_multiple_updates () = - let* ctxt = make_context () in - let* (alice_red, ctxt) = make_key ctxt "alice_red" in - let* (_, ctxt) = adjust_balance ctxt alice_red 1 in - let* (_, ctxt) = adjust_balance ctxt alice_red 2 in - let* (_, ctxt) = adjust_balance ctxt alice_red (-1) in - assert_balance ctxt ~loc:__LOC__ alice_red 2 - -(** Test that with no updates to the table, no balance is present in - the table *) -let test_empty_balance () = - let* ctxt = make_context () in - let* (alice_red, ctxt) = make_key ctxt "alice_red" in - assert_no_balance ctxt alice_red - -(** Test that adding one entry with positive balance and then - updating with a negative balance also removes the entry *) -let test_empty_balance_after_update () = - let* ctxt = make_context () in - let* (alice_red, ctxt) = make_key ctxt "alice_red" in - let* (_, ctxt) = adjust_balance ctxt alice_red 1 in - let* (_, ctxt) = adjust_balance ctxt alice_red (-1) in - assert_no_balance ctxt alice_red - -(** Test that attempting to update an entry with a negative balance - results in an error. *) -let test_negative_balance () = - let* ctxt = make_context () in - let* (alice_red, ctxt) = make_key ctxt "alice_red" in - adjust_balance ctxt alice_red (-1) >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (fun _err -> true) - -(** Test that positive storage spaces are returned for operations - resulting in extra storage space and negative for ones that frees up storage. - *) -let test_storage_space () = - let* ctxt = make_context () in - let* (alice_red, ctxt) = make_key ctxt "alice_red" in - (* Space for adding an entry is 65 for the key plus 1 for the value. *) - let* (space, ctxt) = adjust_balance ctxt alice_red 1 in - let* () = Assert.equal_int ~loc:__LOC__ 66 (Z.to_int space) in - (* Adding one does not consume additional space. *) - let* (space, ctxt) = adjust_balance ctxt alice_red 1 in - let* () = Assert.equal_int ~loc:__LOC__ 0 (Z.to_int space) in - (* Adding a big balance costs extra. *) - let* (space, ctxt) = adjust_balance ctxt alice_red 1000 in - let* () = Assert.equal_int ~loc:__LOC__ 1 (Z.to_int space) in - (* Reset balance to zero should free up space. - The freed up space is 65 for the key + 2 for the value *) - let* (b, ctxt) = wrap @@ Ticket_balance.get_balance ctxt alice_red in - let* (space, ctxt) = - wrap - (Ticket_balance.adjust_balance - ctxt - alice_red - ~delta:(Z.neg @@ Option.value ~default:Z.zero b)) - in - let* () = Assert.equal_int ~loc:__LOC__ (-67) (Z.to_int space) in - (* Adjusting the space to 0 again should not free anything *) - let* (space, ctxt) = adjust_balance ctxt alice_red 0 in - let* () = Assert.equal_int ~loc:__LOC__ 0 (Z.to_int space) in - (* Adding a balance requiers extra space. *) - let* (space, _) = adjust_balance ctxt alice_red 10 in - Assert.equal_int ~loc:__LOC__ 66 (Z.to_int space) - -let tests = - [ - Tztest.tztest - "no overlapping keys for ticketer" - `Quick - test_non_overlapping_keys_ticketer; - Tztest.tztest - "no overlapping keys for content" - `Quick - test_non_overlapping_keys_contents; - Tztest.tztest - "no overlapping keys for content type" - `Quick - test_non_overlapping_keys_type; - Tztest.tztest - "no overlapping keys for owner" - `Quick - test_non_overlapping_keys_owner; - Tztest.tztest - "ticket balance single update" - `Quick - test_ticket_balance_single_update; - Tztest.tztest "empty balance" `Quick test_empty_balance; - Tztest.tztest - "empty balance after update" - `Quick - test_empty_balance_after_update; - Tztest.tztest "negative balance" `Quick test_negative_balance; - Tztest.tztest - "ticket balance multiple updates" - `Quick - test_ticket_balance_multiple_updates; - Tztest.tztest - "ticket balance different owners" - `Quick - test_ticket_balance_different_owners; - Tztest.tztest "ticket storage space" `Quick test_storage_space; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_time_repr.ml b/src/proto_012_Psithaca/lib_protocol/test/test_time_repr.ml deleted file mode 100644 index b2f67327deb9..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_time_repr.ml +++ /dev/null @@ -1,44 +0,0 @@ -(** Testing - ------- - Component: Protocol (time repr) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^time$" - Subject: Error handling of time operations -*) - -open Protocol - -let test_nominal_add () = - let t = Time_repr.of_seconds (Int64.of_int 2) in - let addition = - Period_repr.of_seconds Int64.one >>? fun p -> Time_repr.( +? ) t p - in - match addition with - | Ok v -> - Assert.equal - ~loc:__LOC__ - Time_repr.equal - "test_nominal_add" - Time_repr.pp_hum - v - (Time_repr.of_seconds (Int64.of_int 3)) - | Error _ -> failwith "Addition has overflowed" - -let test_overflow_add () = - let t = Time_repr.of_seconds Int64.max_int in - match Period_repr.of_seconds Int64.one with - | Error _ -> failwith "period_repr conversion" - | Ok p -> ( - match Time_repr.( +? ) t p with - | Error _ -> return_unit - | Ok tres -> - failwith - "No overflow: %Ld + %Ld = %Ld" - (Time_repr.to_seconds t) - (Period_repr.to_seconds p) - (Time_repr.to_seconds tres)) - -let tests = - [ - Tztest.tztest "non-overflowing addition" `Quick test_nominal_add; - Tztest.tztest "overflowing addition" `Quick test_overflow_add; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_timelock.ml b/src/proto_012_Psithaca/lib_protocol/test/test_timelock.ml deleted file mode 100644 index 9cdf04695699..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_timelock.ml +++ /dev/null @@ -1,168 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (Timelock) - Invocation: cd src/proto_alpha/lib_protocol/test - dune exec ./main.exe -- test "^timelock$" - Subject: On timelock -*) - -open Protocol - -let wrap e = Lwt.return (Environment.wrap_tzresult e) - -let simple_test () = - let (public, secret) = Timelock.gen_rsa_keys () in - let locked_value = Timelock.gen_locked_value public in - let time = 1000 in - let unlocked_value = Timelock.unlock_with_secret secret ~time locked_value in - let (same_unlocked, proof) = - Timelock.unlock_and_prove_without_secret public ~time locked_value - in - assert (unlocked_value = same_unlocked) ; - let sym_key = Timelock.unlocked_value_to_symmetric_key unlocked_value in - let message = Bytes.create 12 in - let c = Timelock.encrypt sym_key message in - let expected_result = Environment.Timelock.Correct message in - let chest_key = Timelock.{unlocked_value; proof} in - let chest = Timelock.{locked_value; rsa_public = public; ciphertext = c} in - let result = Environment.Timelock.open_chest chest chest_key ~time in - assert (result = expected_result) ; - return_unit - -let contract_test () = - (* Parse a Michelson contract from string. *) - let originate_contract file storage src b = - let load_file f = - let ic = open_in f in - let res = really_input_string ic (in_channel_length ic) in - close_in ic ; - res - in - let contract_string = load_file file in - let code = Expr.toplevel_from_string contract_string in - let storage = Expr.from_string storage in - let script = - Alpha_context.Script.{code = lazy_expr code; storage = lazy_expr storage} - in - Op.origination (B b) src ~fee:(Test_tez.of_int 10) ~script - >>=? fun (operation, dst) -> - Incremental.begin_construction b >>=? fun incr -> - Incremental.add_operation incr operation >>=? fun incr -> - Incremental.finalize_block incr >|=? fun b -> (dst, b) - in - Context.init ~consensus_threshold:0 3 >>=? fun (b, contracts) -> - let src = match contracts with hd :: _ -> hd | _ -> assert false in - originate_contract "contracts/timelock.tz" "0xaa" src b >>=? fun (dst, b) -> - let (public, secret) = Timelock.gen_rsa_keys () in - let locked_value = Timelock.gen_locked_value public in - let time = 1000 in - let unlocked_value = Timelock.unlock_with_secret secret ~time locked_value in - let (_same_unlocked, proof) = - Timelock.unlock_and_prove_without_secret public ~time locked_value - in - let sym_key = Timelock.unlocked_value_to_symmetric_key unlocked_value in - let message = Bytes.of_string "this is my message" in - let c = Timelock.encrypt sym_key message in - let check_storage chest chest_key expected_storage_hexa = - let chest_key_bytes = - "0x" - ^ Hex.show - (Hex.of_bytes - (Data_encoding.Binary.to_bytes_exn - Timelock.chest_key_encoding - chest_key)) - in - let chest_bytes = - "0x" - ^ Hex.show - (Hex.of_bytes - (Data_encoding.Binary.to_bytes_exn Timelock.chest_encoding chest)) - in - let michelson_string = - Format.sprintf "(Pair %s %s )" chest_key_bytes chest_bytes - in - let parameters = - Alpha_context.Script.(lazy_expr (Expr.from_string michelson_string)) - in - let fee = Test_tez.of_int 10 in - Op.transaction ~fee (B b) src dst (Test_tez.of_int 3) ~parameters - >>=? fun operation -> - Incremental.begin_construction b >>=? fun incr -> - Incremental.add_operation incr operation >>=? fun incr -> - Incremental.finalize_block incr >>=? fun block -> - Incremental.begin_construction block >>=? fun incr -> - let ctxt = Incremental.alpha_ctxt incr in - Alpha_context.Contract.get_storage ctxt dst >>= wrap - >>=? fun (_, expr_option) -> - let expr = expr_option |> WithExceptions.Option.get ~loc:__LOC__ in - let bytes = - match Micheline.root expr with - | Micheline.Bytes (_, b) -> b - | _ -> assert false - in - let to_check = Hex.show (Hex.of_bytes bytes) in - assert (to_check = expected_storage_hexa) ; - return_unit - in - let chest_key_correct = Timelock.{unlocked_value; proof} in - let chest_correct = - Timelock.{locked_value; rsa_public = public; ciphertext = c} - in - check_storage - chest_correct - chest_key_correct - (Hex.show (Hex.of_bytes message)) - >>=? fun () -> - (* We redo an RSA parameters generation to create incorrect cipher and proof *) - let (public_bogus, secret_bogus) = Timelock.gen_rsa_keys () in - let locked_value_bogus = Timelock.gen_locked_value public_bogus in - let time = 1000 in - let unlocked_value_bogus = - Timelock.unlock_with_secret secret_bogus ~time locked_value_bogus - in - let (_same_unlocked, proof_bogus) = - Timelock.unlock_and_prove_without_secret public ~time locked_value_bogus - in - let sym_key_bogus = - Timelock.unlocked_value_to_symmetric_key unlocked_value_bogus - in - let c_bogus = Timelock.encrypt sym_key_bogus message in - - let chest_incorrect = - Timelock.{locked_value; rsa_public = public; ciphertext = c_bogus} - in - check_storage chest_incorrect chest_key_correct "00" >>=? fun () -> - let chest_key_incorrect = Timelock.{unlocked_value; proof = proof_bogus} in - check_storage chest_correct chest_key_incorrect "01" >>=? fun () -> - return_unit - -let tests = - [ - Tztest.tztest "simple test" `Quick simple_test; - Tztest.tztest "contract test" `Quick contract_test; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_token.ml b/src/proto_012_Psithaca/lib_protocol/test/test_token.ml deleted file mode 100644 index 39d5b1510b59..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_token.ml +++ /dev/null @@ -1,732 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (token) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^token" - Subject: Token movements in the protocol. -*) - -open Protocol -open Alpha_context -open Test_tez - -let wrap e = e >|= Environment.wrap_tzresult - -(** Creates a context with a single account. Returns the context and the public - key hash of the account. *) -let create_context () = - let accounts = Account.generate_accounts 1 in - Block.alpha_context accounts >>=? fun ctxt -> - match accounts with - | [({pkh; _}, _)] -> return (ctxt, pkh) - | _ -> (* Exactly one account has been generated. *) assert false - -let random_amount () = - match Tez.of_mutez (Int64.add 1L (Random.int64 100L)) with - | None -> assert false - | Some x -> x - -(** Check balances for a simple transfer from [bootstrap] to new [Implicit]. *) -let test_simple_balances () = - Random.init 0 ; - create_context () >>=? fun (ctxt, pkh) -> - let src = `Contract (Contract.implicit_contract pkh) in - let (pkh, _pk, _sk) = Signature.generate_key () in - let dest = `Contract (Contract.implicit_contract pkh) in - let amount = Tez.one in - wrap (Token.transfer ctxt src dest amount) >>=? fun (ctxt', _) -> - wrap (Token.balance ctxt src) >>=? fun bal_src -> - wrap (Token.balance ctxt' src) >>=? fun bal_src' -> - wrap (Token.balance ctxt dest) >>=? fun bal_dest -> - wrap (Token.balance ctxt' dest) >>=? fun bal_dest' -> - bal_src' +? amount >>?= fun add_bal_src'_amount -> - bal_dest +? amount >>?= fun add_bal_dest_amount -> - Assert.equal_tez ~loc:__LOC__ bal_src add_bal_src'_amount >>=? fun () -> - Assert.equal_tez ~loc:__LOC__ bal_dest' add_bal_dest_amount - -(** Check balance updates for a simple transfer from [bootstrap] to new - [Implicit]. *) -let test_simple_balance_updates () = - Random.init 0 ; - create_context () >>=? fun (ctxt, pkh) -> - let src = Contract.implicit_contract pkh in - let (pkh, _pk, _sk) = Signature.generate_key () in - let dest = Contract.implicit_contract pkh in - let amount = Tez.one in - wrap (Token.transfer ctxt (`Contract src) (`Contract dest) amount) - >>=? fun (_, bal_updates) -> - Alcotest.( - check - bool - "Missing balance update for source contract." - (List.mem - ~equal:( = ) - Receipt.(Contract src, Debited amount, Block_application) - bal_updates) - true) ; - Alcotest.( - check - bool - "Missing balance update for destination contract." - (List.mem - ~equal:( = ) - Receipt.(Contract dest, Credited amount, Block_application) - bal_updates) - true) ; - return_unit - -let test_allocated_and_deallocated ctxt dest initial_status status_when_empty = - wrap (Token.allocated ctxt dest) >>=? fun allocated -> - Assert.equal_bool ~loc:__LOC__ allocated initial_status >>=? fun () -> - let amount = Tez.one in - wrap (Token.transfer ctxt `Minted dest amount) >>=? fun (ctxt', _) -> - wrap (Token.allocated ctxt' dest) >>=? fun allocated -> - Assert.equal_bool ~loc:__LOC__ allocated true >>=? fun () -> - wrap (Token.balance ctxt' dest) >>=? fun bal_dest' -> - wrap (Token.transfer ctxt' dest `Burned bal_dest') >>=? fun (ctxt', _) -> - wrap (Token.allocated ctxt' dest) >>=? fun allocated -> - Assert.equal_bool ~loc:__LOC__ allocated status_when_empty >>=? fun () -> - return_unit - -let test_allocated_and_deallocated_when_empty ctxt dest = - test_allocated_and_deallocated ctxt dest false false - -let test_allocated_and_still_allocated_when_empty ctxt dest initial_status = - test_allocated_and_deallocated ctxt dest initial_status true - -let test_allocated () = - Random.init 0 ; - create_context () >>=? fun (ctxt, pkh) -> - let dest = `Delegate_balance pkh in - test_allocated_and_still_allocated_when_empty ctxt dest true >>=? fun _ -> - let (pkh, _pk, _sk) = Signature.generate_key () in - let dest = `Contract (Contract.implicit_contract pkh) in - test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> - let dest = `Collected_commitments Blinded_public_key_hash.zero in - test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> - let dest = `Frozen_deposits pkh in - test_allocated_and_still_allocated_when_empty ctxt dest false >>=? fun _ -> - let dest = `Legacy_deposits (pkh, Cycle.root) in - test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> - let dest = `Legacy_fees (pkh, Cycle.root) in - test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> - let dest = `Legacy_rewards (pkh, Cycle.root) in - test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> - let dest = `Block_fees in - test_allocated_and_still_allocated_when_empty ctxt dest true - -let check_sink_balances ctxt ctxt' dest amount = - wrap (Token.balance ctxt dest) >>=? fun bal_dest -> - wrap (Token.balance ctxt' dest) >>=? fun bal_dest' -> - bal_dest +? amount >>?= fun add_bal_dest_amount -> - Assert.equal_tez ~loc:__LOC__ bal_dest' add_bal_dest_amount - -let test_transferring_to_sink ctxt sink amount expected_bupds = - (* Transferring zero must not return balance updates. *) - (match sink with - | `Contract _ | `Delegate_balance _ -> - return_unit (* Transaction of 0tz is forbidden. *) - | _ -> - wrap (Token.transfer ctxt `Minted sink Tez.zero) - >>=? fun (ctxt', bupds) -> - check_sink_balances ctxt ctxt' sink Tez.zero >>=? fun _ -> - Assert.equal_bool ~loc:__LOC__ (bupds = []) true) - >>=? fun _ -> - (* Test transferring a non null amount. *) - wrap (Token.transfer ctxt `Minted sink amount) >>=? fun (ctxt', bupds) -> - check_sink_balances ctxt ctxt' sink amount >>=? fun _ -> - let expected_bupds = - Receipt.(Minted, Debited amount, Block_application) :: expected_bupds - in - Alcotest.( - check bool "Balance updates do not match." (bupds = expected_bupds) true) ; - return_unit - -let test_transferring_to_contract ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let dest = Contract.implicit_contract pkh in - let amount = random_amount () in - test_transferring_to_sink - ctxt - (`Contract dest) - amount - [(Contract dest, Credited amount, Block_application)] - -let test_transferring_to_collected_commitments ctxt = - let amount = random_amount () in - let bpkh = Blinded_public_key_hash.zero in - test_transferring_to_sink - ctxt - (`Collected_commitments bpkh) - amount - [(Commitments bpkh, Credited amount, Block_application)] - -let test_transferring_to_delegate_balance ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let dest = Contract.implicit_contract pkh in - (* First we need to force the allocation of [dest]. *) - wrap (Token.transfer ctxt `Minted (`Contract dest) Tez.one) - >>=? fun (ctxt, _) -> - wrap (Token.allocated ctxt (`Delegate_balance pkh)) >>=? fun allocated -> - Assert.equal_bool ~loc:__LOC__ allocated true >>=? fun () -> - let amount = random_amount () in - test_transferring_to_sink - ctxt - (`Delegate_balance pkh) - amount - [(Contract dest, Credited amount, Block_application)] - -let test_transferring_to_frozen_deposits ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let amount = random_amount () in - test_transferring_to_sink - ctxt - (`Frozen_deposits pkh) - amount - [(Deposits pkh, Credited amount, Block_application)] - -let test_transferring_to_collected_fees ctxt = - let amount = random_amount () in - test_transferring_to_sink - ctxt - `Block_fees - amount - [(Block_fees, Credited amount, Block_application)] - -let test_transferring_to_legacy_deposits ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let amount = random_amount () in - let cycle = Cycle.(add root (Random.int 10)) in - test_transferring_to_sink - ctxt - (`Legacy_deposits (pkh, cycle)) - amount - [(Legacy_deposits (pkh, cycle), Credited amount, Block_application)] - -let test_transferring_to_legacy_fees ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let amount = random_amount () in - let cycle = Cycle.(add root (Random.int 10)) in - test_transferring_to_sink - ctxt - (`Legacy_fees (pkh, cycle)) - amount - [(Legacy_fees (pkh, cycle), Credited amount, Block_application)] - -let test_transferring_to_legacy_rewards ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let amount = random_amount () in - let cycle = Cycle.(add root (Random.int 10)) in - test_transferring_to_sink - ctxt - (`Legacy_rewards (pkh, cycle)) - amount - [(Legacy_rewards (pkh, cycle), Credited amount, Block_application)] - -let test_transferring_to_burned ctxt = - let amount = random_amount () in - let minted_bupd = Receipt.(Minted, Debited amount, Block_application) in - wrap (Token.transfer ctxt `Minted `Burned amount) >>=? fun (_, bupds) -> - Assert.equal_bool - ~loc:__LOC__ - (bupds = [minted_bupd; (Burned, Credited amount, Block_application)]) - true - >>=? fun () -> - wrap (Token.transfer ctxt `Minted `Storage_fees amount) >>=? fun (_, bupds) -> - Assert.equal_bool - ~loc:__LOC__ - (bupds = [minted_bupd; (Storage_fees, Credited amount, Block_application)]) - true - >>=? fun () -> - wrap (Token.transfer ctxt `Minted `Double_signing_punishments amount) - >>=? fun (_, bupds) -> - Assert.equal_bool - ~loc:__LOC__ - (bupds - = [ - minted_bupd; - (Double_signing_punishments, Credited amount, Block_application); - ]) - true - >>=? fun () -> - let pkh = Signature.Public_key_hash.zero in - let (p, r) = (Random.bool (), Random.bool ()) in - wrap - (Token.transfer ctxt `Minted (`Lost_endorsing_rewards (pkh, p, r)) amount) - >>=? fun (_, bupds) -> - Assert.equal_bool - ~loc:__LOC__ - (bupds - = [ - minted_bupd; - (Lost_endorsing_rewards (pkh, p, r), Credited amount, Block_application); - ]) - true - -let test_transferring_to_sink () = - Random.init 0 ; - create_context () >>=? fun (ctxt, _) -> - test_transferring_to_contract ctxt >>=? fun _ -> - test_transferring_to_collected_commitments ctxt >>=? fun _ -> - test_transferring_to_delegate_balance ctxt >>=? fun _ -> - test_transferring_to_frozen_deposits ctxt >>=? fun _ -> - test_transferring_to_collected_fees ctxt >>=? fun _ -> - test_transferring_to_burned ctxt >>=? fun _ -> - test_transferring_to_legacy_deposits ctxt >>=? fun _ -> - test_transferring_to_legacy_fees ctxt >>=? fun _ -> - test_transferring_to_legacy_rewards ctxt - -let check_src_balances ctxt ctxt' src amount = - wrap (Token.balance ctxt src) >>=? fun bal_src -> - wrap (Token.balance ctxt' src) >>=? fun bal_src' -> - bal_src' +? amount >>?= fun add_bal_src'_amount -> - Assert.equal_tez ~loc:__LOC__ bal_src add_bal_src'_amount - -let test_transferring_from_unbounded_source ctxt src expected_bupds = - (* Transferring zero must not return balance updates. *) - wrap (Token.transfer ctxt src `Burned Tez.zero) >>=? fun (_, bupds) -> - Assert.equal_bool ~loc:__LOC__ (bupds = []) true >>=? fun () -> - (* Test transferring a non null amount. *) - let amount = random_amount () in - wrap (Token.transfer ctxt src `Burned amount) >>=? fun (_, bupds) -> - let expected_bupds = - expected_bupds amount - @ Receipt.[(Burned, Credited amount, Block_application)] - in - Assert.equal_bool ~loc:__LOC__ (bupds = expected_bupds) true >>=? fun () -> - return_unit - -let test_transferring_from_bounded_source ctxt src amount expected_bupds = - (* Transferring zero must not return balance updates. *) - (match src with - | `Contract _ | `Delegate_balance _ -> - return_unit (* Transaction of 0tz is forbidden. *) - | _ -> - wrap (Token.transfer ctxt src `Burned Tez.zero) >>=? fun (ctxt', bupds) -> - check_src_balances ctxt ctxt' src Tez.zero >>=? fun _ -> - Assert.equal_bool ~loc:__LOC__ (bupds = []) true) - >>=? fun _ -> - (* Test transferring a non null amount. *) - wrap (Token.transfer ctxt `Minted src amount) >>=? fun (ctxt, _) -> - wrap (Token.transfer ctxt src `Burned amount) >>=? fun (ctxt', bupds) -> - check_src_balances ctxt ctxt' src amount >>=? fun _ -> - let expected_bupds = - expected_bupds @ Receipt.[(Burned, Credited amount, Block_application)] - in - Assert.equal_bool ~loc:__LOC__ (bupds = expected_bupds) true - -let test_transferring_from_contract ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let src = Contract.implicit_contract pkh in - let amount = random_amount () in - test_transferring_from_bounded_source - ctxt - (`Contract src) - amount - [(Contract src, Debited amount, Block_application)] - -let test_transferring_from_collected_commitments ctxt = - let amount = random_amount () in - let bpkh = Blinded_public_key_hash.zero in - test_transferring_from_bounded_source - ctxt - (`Collected_commitments bpkh) - amount - [(Commitments bpkh, Debited amount, Block_application)] - -let test_transferring_from_delegate_balance ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let amount = random_amount () in - let src = Contract.implicit_contract pkh in - (* First we need to force the allocation of [dest]. *) - wrap (Token.transfer ctxt `Minted (`Contract src) Tez.one) - >>=? fun (ctxt, _) -> - test_transferring_from_bounded_source - ctxt - (`Delegate_balance pkh) - amount - [(Contract src, Debited amount, Block_application)] - -let test_transferring_from_frozen_deposits ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let amount = random_amount () in - test_transferring_from_bounded_source - ctxt - (`Frozen_deposits pkh) - amount - [(Deposits pkh, Debited amount, Block_application)] - -let test_transferring_from_collected_fees ctxt = - let amount = random_amount () in - test_transferring_from_bounded_source - ctxt - `Block_fees - amount - [(Block_fees, Debited amount, Block_application)] - -let test_transferring_from_legacy_deposits ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let amount = random_amount () in - let cycle = Cycle.(add root (Random.int 10)) in - test_transferring_from_bounded_source - ctxt - (`Legacy_deposits (pkh, cycle)) - amount - [(Legacy_deposits (pkh, cycle), Debited amount, Block_application)] - -let test_transferring_from_legacy_fees ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let amount = random_amount () in - let cycle = Cycle.(add root (Random.int 10)) in - test_transferring_from_bounded_source - ctxt - (`Legacy_fees (pkh, cycle)) - amount - [(Legacy_fees (pkh, cycle), Debited amount, Block_application)] - -let test_transferring_from_legacy_rewards ctxt = - let (pkh, _pk, _sk) = Signature.generate_key () in - let amount = random_amount () in - let cycle = Cycle.(add root (Random.int 10)) in - test_transferring_from_bounded_source - ctxt - (`Legacy_rewards (pkh, cycle)) - amount - [(Legacy_rewards (pkh, cycle), Debited amount, Block_application)] - -let test_transferring_from_source () = - Random.init 0 ; - create_context () >>=? fun (ctxt, _) -> - test_transferring_from_unbounded_source ctxt `Invoice (fun am -> - [(Invoice, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_unbounded_source ctxt `Bootstrap (fun am -> - [(Bootstrap, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_unbounded_source ctxt `Initial_commitments (fun am -> - [(Initial_commitments, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_unbounded_source ctxt `Revelation_rewards (fun am -> - [(Nonce_revelation_rewards, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_unbounded_source - ctxt - `Double_signing_evidence_rewards - (fun am -> - [(Double_signing_evidence_rewards, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_unbounded_source ctxt `Endorsing_rewards (fun am -> - [(Endorsing_rewards, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_unbounded_source ctxt `Baking_rewards (fun am -> - [(Baking_rewards, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_unbounded_source ctxt `Baking_bonuses (fun am -> - [(Baking_bonuses, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_unbounded_source ctxt `Minted (fun am -> - [(Minted, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_unbounded_source - ctxt - `Liquidity_baking_subsidies - (fun am -> [(Liquidity_baking_subsidies, Debited am, Block_application)]) - >>=? fun _ -> - test_transferring_from_contract ctxt >>=? fun _ -> - test_transferring_from_collected_commitments ctxt >>=? fun _ -> - test_transferring_from_delegate_balance ctxt >>=? fun _ -> - test_transferring_from_frozen_deposits ctxt >>=? fun _ -> - test_transferring_from_collected_fees ctxt >>=? fun _ -> - test_transferring_from_legacy_deposits ctxt >>=? fun _ -> - test_transferring_from_legacy_fees ctxt >>=? fun _ -> - test_transferring_from_legacy_rewards ctxt - -let cast_to_container_type x = - match x with - | `Burned | `Invoice | `Bootstrap | `Initial_commitments | `Minted - | `Liquidity_baking_subsidies -> - None - | `Contract _ as x -> Some x - | `Collected_commitments _ as x -> Some x - | `Delegate_balance _ as x -> Some x - | `Block_fees as x -> Some x - -(** Generates all combinations of constructors. *) -let build_test_cases () = - create_context () >>=? fun (ctxt, pkh) -> - let origin = `Contract (Contract.implicit_contract pkh) in - let (user1, _, _) = Signature.generate_key () in - let user1c = `Contract (Contract.implicit_contract user1) in - let (user2, _, _) = Signature.generate_key () in - let user2c = `Contract (Contract.implicit_contract user2) in - let (baker1, baker1_pk, _) = Signature.generate_key () in - let baker1c = `Contract (Contract.implicit_contract baker1) in - let (baker2, baker2_pk, _) = Signature.generate_key () in - let baker2c = `Contract (Contract.implicit_contract baker2) in - (* Allocate contracts for user1, user2, baker1, and baker2. *) - wrap (Token.transfer ctxt origin user1c (random_amount ())) - >>=? fun (ctxt, _) -> - wrap (Token.transfer ctxt origin user2c (random_amount ())) - >>=? fun (ctxt, _) -> - wrap (Token.transfer ctxt origin baker1c (random_amount ())) - >>=? fun (ctxt, _) -> - wrap (Token.transfer ctxt origin baker2c (random_amount ())) - >>=? fun (ctxt, _) -> - (* Configure baker1, and baker2 as delegates by self-delegation, for which - revealing their manager key is a prerequisite. *) - wrap (Contract.reveal_manager_key ctxt baker1 baker1_pk) >>=? fun ctxt -> - wrap (Delegate.set ctxt (Contract.implicit_contract baker1) (Some baker1)) - >>=? fun ctxt -> - wrap (Contract.reveal_manager_key ctxt baker2 baker2_pk) >>=? fun ctxt -> - wrap (Delegate.set ctxt (Contract.implicit_contract baker2) (Some baker2)) - (* Let user1 delegate to baker2. *) - >>=? fun ctxt -> - wrap (Delegate.set ctxt (Contract.implicit_contract user1) (Some baker2)) - >>=? fun ctxt -> - let src_list = - [ - (`Invoice, random_amount ()); - (`Bootstrap, random_amount ()); - (`Initial_commitments, random_amount ()); - (`Minted, random_amount ()); - (`Liquidity_baking_subsidies, random_amount ()); - (`Collected_commitments Blinded_public_key_hash.zero, random_amount ()); - (`Delegate_balance baker1, random_amount ()); - (`Delegate_balance baker2, random_amount ()); - (`Block_fees, random_amount ()); - (user1c, random_amount ()); - (user2c, random_amount ()); - (baker1c, random_amount ()); - (baker2c, random_amount ()); - ] - in - let dest_list = - [ - `Collected_commitments Blinded_public_key_hash.zero; - `Delegate_balance baker1; - `Delegate_balance baker2; - `Block_fees; - user1c; - user2c; - baker1c; - baker2c; - `Burned; - ] - in - return (ctxt, List.product src_list dest_list) - -let check_src_balances ctxt ctxt' src amount = - match cast_to_container_type src with - | None -> return_unit - | Some src -> check_src_balances ctxt ctxt' src amount - -let check_sink_balances ctxt ctxt' dest amount = - match cast_to_container_type dest with - | None -> return_unit - | Some dest -> check_sink_balances ctxt ctxt' dest amount - -let rec check_balances ctxt ctxt' src dest amount = - match (cast_to_container_type src, cast_to_container_type dest) with - | (None, None) -> return_unit - | (Some (`Delegate_balance d), Some (`Contract c as contract)) - when Contract.implicit_contract d = c -> - (* src and dest are in fact referring to the same contract *) - check_balances ctxt ctxt' contract contract amount - | (Some (`Contract c as contract), Some (`Delegate_balance d)) - when Contract.implicit_contract d = c -> - (* src and dest are in fact referring to the same contract *) - check_balances ctxt ctxt' contract contract amount - | (Some src, Some dest) when src = dest -> - (* src and dest are the same contract *) - wrap (Token.balance ctxt dest) >>=? fun bal_dest -> - wrap (Token.balance ctxt' dest) >>=? fun bal_dest' -> - Assert.equal_tez ~loc:__LOC__ bal_dest bal_dest' - | (Some src, None) -> check_src_balances ctxt ctxt' src amount - | (None, Some dest) -> check_sink_balances ctxt ctxt' dest amount - | (Some src, Some dest) -> - check_src_balances ctxt ctxt' src amount >>=? fun _ -> - check_sink_balances ctxt ctxt' dest amount - -let test_all_combinations_of_sources_and_sinks () = - Random.init 0 ; - build_test_cases () >>=? fun (ctxt, cases) -> - List.iter_es - (fun ((src, amount), dest) -> - (match cast_to_container_type src with - | None -> return ctxt - | Some src -> - wrap (Token.transfer ctxt `Minted src amount) >>=? fun (ctxt, _) -> - return ctxt) - >>=? fun ctxt -> - wrap (Token.transfer ctxt src dest amount) >>=? fun (ctxt', _) -> - check_balances ctxt ctxt' src dest amount) - cases - -(** [coalesce (account, Credited am1, origin) (account, Credited am2, origin) - = Some (account, Credited (am1+am2), origin)] - - [coalesce (account, Debited am1, origin) (account, Debited am2, origin) - = Some (account, Debited (am1+am2), origin)] - - Fails if bu1 and bu2 have different accounts or different origins, or - if one is a credit while the other is a debit. *) -let coalesce_balance_updates bu1 bu2 = - match (bu1, bu2) with - | ((bu1_bal, bu1_balupd, bu1_origin), (bu2_bal, bu2_balupd, bu2_origin)) -> ( - assert (bu1_bal = bu2_bal) ; - assert (bu1_origin = bu2_origin) ; - let open Receipt in - match (bu1_balupd, bu2_balupd) with - | (Credited bu1_am, Credited bu2_am) -> - let bu_am = - match bu1_am +? bu2_am with Ok am -> am | _ -> assert false - in - (bu1_bal, Credited bu_am, bu1_origin) - | (Debited bu1_am, Debited bu2_am) -> - let bu_am = - match bu1_am +? bu2_am with Ok am -> am | _ -> assert false - in - (bu1_bal, Debited bu_am, bu1_origin) - | (Credited _, Debited _) | (Debited _, Credited _) -> assert false) - -(** Check that elt has the same balance in ctxt1 and ctxt2. *) -let check_balances_are_consistent ctxt1 ctxt2 elt = - match elt with - | #Token.container as elt -> - Token.balance ctxt1 elt >>=? fun elt_bal1 -> - Token.balance ctxt2 elt >>=? fun elt_bal2 -> - assert (elt_bal1 = elt_bal2) ; - return_unit - | `Invoice | `Bootstrap | `Initial_commitments | `Minted - | `Liquidity_baking_subsidies | `Burned -> - return_unit - -(** Test that [transfer_n] is equivalent to n debits followed by n credits. *) -let test_transfer_n ctxt src dest = - (* Run transfer_n. *) - Token.transfer_n ctxt src dest >>=? fun (ctxt1, bal_updates1) -> - (* Debit all sources. *) - List.fold_left_es - (fun (ctxt, bal_updates) (src, am) -> - Token.transfer ctxt src `Burned am >>=? fun (ctxt, debit_logs) -> - return (ctxt, bal_updates @ debit_logs)) - (ctxt, []) - src - >>=? fun (ctxt, debit_logs) -> - (* remove burning balance updates *) - let debit_logs = - List.filter - (fun b -> match b with (Receipt.Burned, _, _) -> false | _ -> true) - debit_logs - in - (* Credit the sink for each source. *) - List.fold_left_es - (fun (ctxt, bal_updates) (_, am) -> - Token.transfer ctxt `Minted dest am >>=? fun (ctxt, credit_logs) -> - return (ctxt, bal_updates @ credit_logs)) - (ctxt, []) - src - >>=? fun (ctxt2, credit_logs) -> - (* remove minting balance updates *) - let credit_logs = - List.filter - (fun b -> match b with (Receipt.Minted, _, _) -> false | _ -> true) - credit_logs - in - (* Check equivalence of balance updates. *) - let credit_logs = - match credit_logs with - | [] -> [] - | head :: tail -> [List.fold_left coalesce_balance_updates head tail] - in - assert (bal_updates1 = debit_logs @ credit_logs) ; - (* Check balances are the same in ctxt1 and ctxt2. *) - List.(iter_es (check_balances_are_consistent ctxt1 ctxt2) (map fst src)) - >>=? fun _ -> check_balances_are_consistent ctxt1 ctxt2 dest - -let test_transfer_n_with_empty_source () = - Random.init 0 ; - create_context () >>=? fun (ctxt, pkh) -> - wrap (test_transfer_n ctxt [] `Block_fees) >>=? fun _ -> - let dest = `Delegate_balance pkh in - wrap (test_transfer_n ctxt [] dest) - -let test_transfer_n_with_non_empty_source () = - Random.init 0 ; - create_context () >>=? fun (ctxt, pkh) -> - let origin = `Contract (Contract.implicit_contract pkh) in - let (user1, _, _) = Signature.generate_key () in - let user1c = `Contract (Contract.implicit_contract user1) in - let (user2, _, _) = Signature.generate_key () in - let user2c = `Contract (Contract.implicit_contract user2) in - let (user3, _, _) = Signature.generate_key () in - let user3c = `Contract (Contract.implicit_contract user3) in - let (user4, _, _) = Signature.generate_key () in - let user4c = `Contract (Contract.implicit_contract user4) in - (* Allocate contracts for user1, user2, user3, and user4. *) - let amount = - match Tez.of_mutez 1000L with None -> assert false | Some x -> x - in - wrap (Token.transfer ctxt origin user1c amount) >>=? fun (ctxt, _) -> - wrap (Token.transfer ctxt origin user2c amount) >>=? fun (ctxt, _) -> - wrap (Token.transfer ctxt origin user3c amount) >>=? fun (ctxt, _) -> - wrap (Token.transfer ctxt origin user4c (random_amount ())) - >>=? fun (ctxt, _) -> - let sources = - [ - (user2c, random_amount ()); - (user3c, random_amount ()); - (user4c, random_amount ()); - ] - in - wrap (test_transfer_n ctxt sources user1c) >>=? fun _ -> - wrap (test_transfer_n ctxt ((user1c, random_amount ()) :: sources) user1c) - -let tests = - Tztest. - [ - tztest "transfer - balances" `Quick test_simple_balances; - tztest "transfer - balance updates" `Quick test_simple_balance_updates; - tztest "transfer - test allocated" `Quick test_allocated; - tztest "transfer - test transfer to sink" `Quick test_transferring_to_sink; - tztest - "transfer - test transfer from source" - `Quick - test_transferring_from_source; - tztest - "transfer - test all (sources x sinks)" - `Quick - test_all_combinations_of_sources_and_sinks; - tztest - "transfer - test from empty sources to a destination" - `Quick - test_transfer_n_with_empty_source; - tztest - "transfer - test from n sources to a destination" - `Quick - test_transfer_n_with_non_empty_source; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_transfer.ml b/src/proto_012_Psithaca/lib_protocol/test/test_transfer.ml deleted file mode 100644 index c00597850c00..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_transfer.ml +++ /dev/null @@ -1,801 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (transfer) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^transfer$" - Subject: Quantities transfer between contracts. -*) - -open Protocol -open Alpha_context -open Test_tez - -(*********************************************************************) -(* Utility functions *) -(*********************************************************************) - -(** - [transfer_and_check_balances b fee src dst amount] - this function takes a block, an optional parameter fee if fee does not - given it will be set to zero tez, a source contract, a destination contract - and the amount that one wants to transfer. - - 1- Transfer the amount of tez (w/wo fee) from a source contract to a - destination contract. - - 2- Check the equivalent of the balance of the source/destination - contract before and after transfer is validated. - - This function returns a pair: - - A block that added a valid operation - - a valid operation *) -let transfer_and_check_balances ?(with_burn = false) ~loc b ?(fee = Tez.zero) - ?expect_failure src dst amount = - fee +? amount >>?= fun amount_fee -> - Context.Contract.balance (I b) src >>=? fun bal_src -> - Context.Contract.balance (I b) dst >>=? fun bal_dst -> - Op.transaction - ~gas_limit:(Alpha_context.Gas.Arith.integral_of_int_exn 3000) - (I b) - ~fee - src - dst - amount - >>=? fun op -> - Incremental.add_operation ?expect_failure b op >>=? fun b -> - Context.get_constants (I b) - >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> - cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> - let amount_fee_maybe_burn = - if with_burn then - match Tez.(amount_fee +? origination_burn) with - | Ok r -> r - | Error _ -> assert false - else amount_fee - in - Assert.balance_was_debited ~loc (I b) src bal_src amount_fee_maybe_burn - >>=? fun () -> - Assert.balance_was_credited ~loc (I b) dst bal_dst amount >|=? fun () -> - (b, op) - -(** - [transfer_to_itself_and_check_balances b fee contract amount] - this function takes a block, an optional parameter fee, - a contract that is a source and a destination contract, - and an amount of tez that one wants to transfer. - - 1- Transfer the amount of tez (w/wo transfer fee) from/to a contract itself. - - 2- Check the equivalent of the balance of the contract before - and after transfer. - - This function returns a pair: - - a block that added the valid transaction - - an valid transaction *) -let transfer_to_itself_and_check_balances ~loc b ?(fee = Tez.zero) contract - amount = - Context.Contract.balance (I b) contract >>=? fun bal -> - Op.transaction (I b) ~fee contract contract amount >>=? fun op -> - Incremental.add_operation b op >>=? fun b -> - Assert.balance_was_debited ~loc (I b) contract bal fee >|=? fun () -> (b, op) - -(** - [n_transactions n b fee source dest amount] - this function takes a number of "n" that one wish to transfer, - a block, an optional parameter fee, a source contract, - a destination contract and an amount one wants to transfer. - - This function will do a transaction from a source contract to - a destination contract with the amount "n" times. *) -let n_transactions n b ?fee source dest amount = - List.fold_left_es - (fun b _ -> - transfer_and_check_balances ~loc:__LOC__ b ?fee source dest amount - >|=? fun (b, _) -> b) - b - (1 -- n) - -let ten_tez = of_int 10 - -(*********************************************************************) -(* Tests *) -(*********************************************************************) - -let register_two_contracts ?consensus_threshold () = - Context.init ?consensus_threshold 2 >|=? function - | (_, []) | (_, [_]) -> assert false - | (b, contract_1 :: contract_2 :: _) -> (b, contract_1, contract_2) - -(** Compute a fraction of 2/[n] of the balance of [contract] *) -let two_over_n_of_balance incr contract n = - Context.Contract.balance (I incr) contract >>=? fun balance -> - Lwt.return (balance /? n >>? fun res -> res *? 2L) - -(********************) -(** Single transfer *) - -(********************) - -let single_transfer ?fee ?expect_failure amount = - register_two_contracts () >>=? fun (b, contract_1, contract_2) -> - Incremental.begin_construction b >>=? fun b -> - transfer_and_check_balances - ~loc:__LOC__ - ?fee - ?expect_failure - b - contract_1 - contract_2 - amount - >>=? fun (b, _) -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(** Single transfer without fee. *) -let test_block_with_a_single_transfer () = single_transfer Tez.one - -(** Single transfer with fee. *) -let test_block_with_a_single_transfer_with_fee () = - single_transfer ~fee:Tez.one Tez.one - -(** Single transfer without fee. *) -let test_transfer_zero_tez () = - single_transfer - ~expect_failure:(function - | Environment.Ecoproto_error (Apply.Empty_transaction _ as e) :: _ -> - Assert.test_error_encodings e ; - return_unit - | _ -> failwith "Empty transaction should fail") - Tez.zero - -(** Transfer zero tez from an implicit contract. *) -let test_transfer_zero_implicit () = - Context.init 1 >>=? fun (b, contracts) -> - let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in - let account = Account.new_account () in - Incremental.begin_construction b >>=? fun i -> - let src = Contract.implicit_contract account.Account.pkh in - Op.transaction (I i) src dest Tez.zero >>=? fun op -> - Incremental.add_operation i op >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Contract_storage.Empty_implicit_contract _ -> true - | _ -> false) - -(** Transfer to originated contract. *) -let test_transfer_to_originate_with_fee () = - Context.init 1 >>=? fun (b, contracts) -> - let contract = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 - in - Incremental.begin_construction b >>=? fun b -> - two_over_n_of_balance b contract 10L >>=? fun fee -> - (* originated contract, paying a fee to originated this contract *) - Op.origination (I b) ~fee:ten_tez contract ~script:Op.dummy_script - >>=? fun (operation, new_contract) -> - Incremental.add_operation b operation >>=? fun b -> - two_over_n_of_balance b contract 3L >>=? fun amount -> - transfer_and_check_balances ~loc:__LOC__ b ~fee contract new_contract amount - >>=? fun (b, _) -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(** Transfer from balance. *) -let test_transfer_amount_of_contract_balance () = - register_two_contracts () >>=? fun (b, contract_1, contract_2) -> - Context.Contract.pkh contract_1 >>=? fun pkh1 -> - (* given that contract_1 no longer has a sufficient balance to bake, - make sure it cannot be chosen as baker *) - Incremental.begin_construction b ~policy:(Block.Excluding [pkh1]) - >>=? fun b -> - (* get the balance of the source contract *) - Context.Contract.balance (I b) contract_1 >>=? fun balance -> - (* transfer all the tez inside contract 1 *) - transfer_and_check_balances ~loc:__LOC__ b contract_1 contract_2 balance - >>=? fun (b, _) -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(** Transfer to oneself. *) -let test_transfers_to_self () = - Context.init 1 >>=? fun (b, contracts) -> - let contract = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 - in - Incremental.begin_construction b >>=? fun b -> - two_over_n_of_balance b contract 3L >>=? fun amount -> - transfer_to_itself_and_check_balances ~loc:__LOC__ b contract amount - >>=? fun (b, _) -> - two_over_n_of_balance b contract 5L >>=? fun fee -> - transfer_to_itself_and_check_balances ~loc:__LOC__ b ~fee contract ten_tez - >>=? fun (b, _) -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(** Forgot to add the valid transaction into the block. *) -let test_missing_transaction () = - register_two_contracts () >>=? fun (b, contract_1, contract_2) -> - (* given that contract_1 no longer has a sufficient balance to bake, - make sure it cannot be chosen as baker *) - Context.Contract.pkh contract_1 >>=? fun pkh1 -> - Incremental.begin_construction b ~policy:(Block.Excluding [pkh1]) - >>=? fun b -> - two_over_n_of_balance b contract_1 6L >>=? fun amount -> - (* Do the transfer 3 times from source contract to destination contract *) - n_transactions 3 b contract_1 contract_2 amount >>=? fun b -> - (* do the fourth transfer from source contract to destination contract *) - Op.transaction (I b) contract_1 contract_2 amount >>=? fun _ -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(** Transfer zero tez to an implicit contract, with fee equals balance of src. *) -let test_transfer_zero_implicit_with_bal_src_as_fee () = - Context.init 1 >>=? fun (b, contracts) -> - let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in - let account = Account.new_account () in - Incremental.begin_construction b >>=? fun i -> - let src = Contract.implicit_contract account.Account.pkh in - Op.transaction (I i) dest src (Tez.of_mutez_exn 100L) >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Context.Contract.balance (I i) src >>=? fun bal_src -> - Assert.equal_tez ~loc:__LOC__ bal_src (Tez.of_mutez_exn 100L) >>=? fun () -> - Op.transaction (I i) ~fee:bal_src src dest Tez.zero >>=? fun op -> - Incremental.add_operation i op >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Apply.Empty_transaction _ -> true - | _ -> false) - -(** Transfer zero tez to an originated contract, with fee equals balance of src. *) -let test_transfer_zero_to_originated_with_bal_src_as_fee () = - Context.init 1 >>=? fun (b, contracts) -> - let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in - let account = Account.new_account () in - Incremental.begin_construction b >>=? fun i -> - let src = Contract.implicit_contract account.Account.pkh in - Op.transaction (I i) dest src (Tez.of_mutez_exn 100L) >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Op.origination (I i) dest ~script:Op.dummy_script - >>=? fun (op, new_contract) -> - Incremental.add_operation i op >>=? fun i -> - Context.Contract.balance (I i) src >>=? fun bal_src -> - Op.transaction (I i) ~fee:bal_src src new_contract Tez.zero >>=? fun op -> - Assert.equal_tez ~loc:__LOC__ bal_src (Tez.of_mutez_exn 100L) >>=? fun () -> - Incremental.add_operation i op >>=? fun i -> - Incremental.finalize_block i >>=? fun _ -> return_unit - -(** Transfer one tez to an implicit contract, with fee equals balance of src. *) -let test_transfer_one_to_implicit_with_bal_src_as_fee () = - Context.init 1 >>=? fun (b, contracts) -> - let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in - let account = Account.new_account () in - Incremental.begin_construction b >>=? fun i -> - let src = Contract.implicit_contract account.Account.pkh in - Op.transaction (I i) dest src (Tez.of_mutez_exn 100L) >>=? fun op -> - Incremental.add_operation i op >>=? fun i -> - Context.Contract.balance (I i) src >>=? fun bal_src -> - Assert.equal_tez ~loc:__LOC__ bal_src (Tez.of_mutez_exn 100L) >>=? fun () -> - Op.transaction (I i) ~fee:bal_src src dest Tez.one >>=? fun op -> - Incremental.add_operation i op >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Contract_storage.Balance_too_low _ -> true - | _ -> false) - -(********************) -(* The following tests are for different kind of contracts: - - implicit to implicit - - implicit to originated - - originated to implicit - - originated to originated *) - -(********************) - -(** Implicit to Implicit. *) -let test_transfer_from_implicit_to_implicit_contract () = - Context.init 1 >>=? fun (b, contracts) -> - let bootstrap_contract = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 - in - let account_a = Account.new_account () in - let account_b = Account.new_account () in - Incremental.begin_construction b >>=? fun b -> - let src = Contract.implicit_contract account_a.Account.pkh in - two_over_n_of_balance b bootstrap_contract 3L >>=? fun amount1 -> - two_over_n_of_balance b bootstrap_contract 10L >>=? fun fee1 -> - transfer_and_check_balances - ~with_burn:true - ~loc:__LOC__ - ~fee:fee1 - b - bootstrap_contract - src - amount1 - >>=? fun (b, _) -> - (* Create an implicit contract as a destination contract. *) - let dest = Contract.implicit_contract account_b.pkh in - two_over_n_of_balance b bootstrap_contract 4L >>=? fun amount2 -> - two_over_n_of_balance b bootstrap_contract 10L >>=? fun fee2 -> - (* Transfer from implicit contract to another implicit contract. *) - transfer_and_check_balances - ~with_burn:true - ~loc:__LOC__ - ~fee:fee2 - b - src - dest - amount2 - >>=? fun (b, _) -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(** Implicit to originated. *) -let test_transfer_from_implicit_to_originated_contract () = - Context.init 1 >>=? fun (b, contracts) -> - let bootstrap_contract = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 - in - let contract = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 - in - let account = Account.new_account () in - let src = Contract.implicit_contract account.Account.pkh in - Incremental.begin_construction b >>=? fun b -> - two_over_n_of_balance b bootstrap_contract 3L >>=? fun amount1 -> - (* transfer the money to implicit contract *) - transfer_and_check_balances - ~with_burn:true - ~loc:__LOC__ - b - bootstrap_contract - src - amount1 - >>=? fun (b, _) -> - (* originated contract *) - Op.origination (I b) contract ~script:Op.dummy_script - >>=? fun (operation, new_contract) -> - Incremental.add_operation b operation >>=? fun b -> - two_over_n_of_balance b bootstrap_contract 4L >>=? fun amount2 -> - (* transfer from implicit contract to originated contract *) - transfer_and_check_balances ~loc:__LOC__ b src new_contract amount2 - >>=? fun (b, _) -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(********************) -(* Slow tests case *) - -(********************) - -let multiple_transfer n ?fee amount = - register_two_contracts () >>=? fun (b, contract_1, contract_2) -> - Incremental.begin_construction b >>=? fun b -> - n_transactions n b ?fee contract_1 contract_2 amount >>=? fun b -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(** 1- Create a block with two contracts; - 2- Apply 100 transfers. -*) -let test_block_with_multiple_transfers () = multiple_transfer 99 (of_int 1000) - -(** 1- Create a block with two contracts; - 2- Apply 100 transfers with 10tz fee. *) -let test_block_with_multiple_transfers_pay_fee () = - multiple_transfer 10 ~fee:ten_tez (of_int 1000) - -(* TODO : increase the number of operations and add a `Slow tag to it in `tests` *) - -(** 1- Create a block with 8 contracts; - 2- Apply multiple transfers without fees; - 3- Apply multiple transfers with fees. *) -let test_block_with_multiple_transfers_with_without_fee () = - Context.init 8 >>=? fun (b, contracts) -> - let contracts = Array.of_list contracts in - Incremental.begin_construction b >>=? fun b -> - let hundred = of_int 100 in - let ten = of_int 10 in - let twenty = of_int 20 in - n_transactions 10 b contracts.(0) contracts.(1) Tez.one >>=? fun b -> - n_transactions 30 b contracts.(1) contracts.(2) hundred >>=? fun b -> - n_transactions 30 b contracts.(1) contracts.(3) hundred >>=? fun b -> - n_transactions 30 b contracts.(4) contracts.(3) hundred >>=? fun b -> - n_transactions 20 b contracts.(0) contracts.(1) hundred >>=? fun b -> - n_transactions 10 b contracts.(1) contracts.(3) hundred >>=? fun b -> - n_transactions 10 b contracts.(1) contracts.(3) hundred >>=? fun b -> - n_transactions 20 ~fee:ten b contracts.(3) contracts.(4) ten >>=? fun b -> - n_transactions 10 ~fee:twenty b contracts.(4) contracts.(5) ten >>=? fun b -> - n_transactions 70 ~fee:twenty b contracts.(6) contracts.(0) twenty - >>=? fun b -> - n_transactions 550 ~fee:twenty b contracts.(6) contracts.(4) twenty - >>=? fun b -> - n_transactions 50 ~fee:ten b contracts.(7) contracts.(5) twenty >>=? fun b -> - n_transactions 30 ~fee:ten b contracts.(0) contracts.(7) hundred >>=? fun b -> - n_transactions 20 ~fee:ten b contracts.(1) contracts.(0) twenty >>=? fun b -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(** Build a chain that has 10 blocks. *) -let test_build_a_chain () = - register_two_contracts ~consensus_threshold:0 () - >>=? fun (b, contract_1, contract_2) -> - let ten = of_int 10 in - List.fold_left_es - (fun b _ -> - Incremental.begin_construction b >>=? fun b -> - transfer_and_check_balances ~loc:__LOC__ b contract_1 contract_2 ten - >>=? fun (b, _) -> Incremental.finalize_block b) - b - (1 -- 10) - >>=? fun _ -> return_unit - -(*********************************************************************) -(* Expected error test cases *) -(*********************************************************************) - -(** Transferring zero tez is forbidden in implicit contract. *) -let test_empty_implicit () = - Context.init 1 >>=? fun (b, contracts) -> - let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in - let account = Account.new_account () in - Incremental.begin_construction b >>=? fun incr -> - let src = Contract.implicit_contract account.Account.pkh in - two_over_n_of_balance incr dest 3L >>=? fun amount -> - (* Transfer zero tez from an implicit contract. *) - Op.transaction (I incr) src dest amount >>=? fun op -> - Incremental.add_operation incr op >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Contract_storage.Empty_implicit_contract _ -> true - | _ -> false) - -(** Balance is too low to transfer. *) -let test_balance_too_low fee () = - register_two_contracts () >>=? fun (b, contract_1, contract_2) -> - Incremental.begin_construction b >>=? fun i -> - Context.Contract.balance (I i) contract_1 >>=? fun balance1 -> - Context.Contract.balance (I i) contract_2 >>=? fun balance2 -> - (* transfer the amount of tez that is bigger than the balance in the source contract *) - Op.transaction ~fee (I i) contract_1 contract_2 max_tez >>=? fun op -> - let expect_failure = function - | Environment.Ecoproto_error (Contract_storage.Balance_too_low _ as e) :: _ - -> - Assert.test_error_encodings e ; - return_unit - | _ -> failwith "balance too low should fail" - in - (* the fee is higher than the balance then raise an error "Balance_too_low" *) - if fee > balance1 then - Incremental.add_operation ~expect_failure i op >>= fun _res -> return_unit - (* the fee is smaller than the balance, then the transfer is accepted - but it is not processed, and fees are taken *) - else - Incremental.add_operation ~expect_failure i op >>=? fun i -> - (* contract_1 loses the fees *) - Assert.balance_was_debited ~loc:__LOC__ (I i) contract_1 balance1 fee - >>=? fun () -> - (* contract_2 is not credited *) - Assert.balance_was_credited ~loc:__LOC__ (I i) contract_2 balance2 Tez.zero - -(** 1- Create a block, and three contracts; - 2- Add a transfer that at the end the balance of a contract is - zero into this block; - 3- Add another transfer that send tez from a zero balance contract; - 4- Catch the expected error: Balance_too_low. *) -let test_balance_too_low_two_transfers fee () = - Context.init 3 >>=? fun (b, contracts) -> - let contract_1 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 - in - let contract_2 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 - in - let contract_3 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 2 - in - Incremental.begin_construction b >>=? fun i -> - Context.Contract.balance (I i) contract_1 >>=? fun balance -> - balance /? 3L >>?= fun res -> - res *? 2L >>?= fun two_third_of_balance -> - transfer_and_check_balances - ~loc:__LOC__ - i - contract_1 - contract_2 - two_third_of_balance - >>=? fun (i, _) -> - Context.Contract.balance (I i) contract_1 >>=? fun balance1 -> - Context.Contract.balance (I i) contract_3 >>=? fun balance3 -> - Op.transaction ~fee (I i) contract_1 contract_3 two_third_of_balance - >>=? fun operation -> - let expect_failure = function - | Environment.Ecoproto_error (Contract_storage.Balance_too_low _ as e) :: _ - -> - Assert.test_error_encodings e ; - return_unit - | _ -> failwith "balance too low should fail" - in - Incremental.add_operation ~expect_failure i operation >>=? fun i -> - (* contract_1 loses the fees *) - Assert.balance_was_debited ~loc:__LOC__ (I i) contract_1 balance1 fee - >>=? fun () -> - (* contract_3 is not credited *) - Assert.balance_was_credited ~loc:__LOC__ (I i) contract_3 balance3 Tez.zero - -(** The counter is already used for the previous operation. *) -let invalid_counter () = - register_two_contracts () >>=? fun (b, contract_1, contract_2) -> - Incremental.begin_construction b >>=? fun b -> - Op.transaction (I b) contract_1 contract_2 Tez.one >>=? fun op1 -> - Op.transaction (I b) contract_1 contract_2 Tez.one >>=? fun op2 -> - Incremental.add_operation b op1 >>=? fun b -> - Incremental.add_operation b op2 >>= fun b -> - Assert.proto_error ~loc:__LOC__ b (function - | Contract_storage.Counter_in_the_past _ -> true - | _ -> false) - -(** Same as before but through a different way to perform this - error. *) -let test_add_the_same_operation_twice () = - register_two_contracts () >>=? fun (b, contract_1, contract_2) -> - Incremental.begin_construction b >>=? fun b -> - transfer_and_check_balances ~loc:__LOC__ b contract_1 contract_2 ten_tez - >>=? fun (b, op_transfer) -> - Op.transaction (I b) contract_1 contract_2 ten_tez >>=? fun _ -> - Incremental.add_operation b op_transfer >>= fun b -> - Assert.proto_error ~loc:__LOC__ b (function - | Contract_storage.Counter_in_the_past _ -> true - | _ -> false) - -(** The counter is in the future *) -let invalid_counter_in_the_future () = - register_two_contracts () >>=? fun (b, contract_1, contract_2) -> - Incremental.begin_construction b >>=? fun b -> - Context.Contract.counter (I b) contract_1 >>=? fun cpt -> - let counter = Z.add cpt (Z.of_int 10) in - Op.transaction (I b) contract_1 contract_2 Tez.one ~counter >>=? fun op -> - Incremental.add_operation b op >>= fun b -> - Assert.proto_error_with_info - ~loc:__LOC__ - b - "Invalid counter (not yet reached) in a manager operation" - -(** Check ownership. *) -let test_ownership_sender () = - register_two_contracts () >>=? fun (b, contract_1, contract_2) -> - Incremental.begin_construction b >>=? fun b -> - (* get the manager of the contract_1 as a sender *) - Context.Contract.manager (I b) contract_1 >>=? fun manager -> - (* create an implicit_contract *) - let imcontract_1 = Alpha_context.Contract.implicit_contract manager.pkh in - transfer_and_check_balances ~loc:__LOC__ b imcontract_1 contract_2 Tez.one - >>=? fun (b, _) -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(*********************************************************************) -(* Random transfer *) - -(* Return a pair of minimum and maximum random number. *) -let random_range (min, max) = - let interv = max - min + 1 in - let init = - Random.self_init () ; - Random.int interv + min - in - init - -(* Return a random contract. *) -let random_contract contract_array = - let i = Random.int (Array.length contract_array) in - contract_array.(i) - -(** Transfer by randomly choose amount 10 contracts, and randomly - choose the amount in the source contract. *) -let test_random_transfer () = - Context.init 10 >>=? fun (b, contracts) -> - let contracts = Array.of_list contracts in - let source = random_contract contracts in - let dest = random_contract contracts in - Context.Contract.pkh source >>=? fun source_pkh -> - (* given that source may not have a sufficient balance for the transfer + to bake, - make sure it cannot be chosen as baker *) - Incremental.begin_construction b ~policy:(Block.Excluding [source_pkh]) - >>=? fun b -> - Context.Contract.balance (I b) source >>=? fun amount -> - (if source = dest then - transfer_to_itself_and_check_balances ~loc:__LOC__ b source amount - else transfer_and_check_balances ~loc:__LOC__ b source dest amount) - >>=? fun (b, _) -> - Incremental.finalize_block b >>=? fun _ -> return_unit - -(** Transfer random transactions. *) -let test_random_multi_transactions () = - let n = random_range (1, 100) in - multiple_transfer n (of_int 100) - -(*********************************************************************) - -let test_bad_entrypoint () = - Context.init 1 >>=? fun (b, _cs) -> - Incremental.begin_construction b >>=? fun v -> - let ctxt = Incremental.alpha_ctxt v in - let storage = "Unit" in - let parameter = "Unit" in - let entrypoint = "bad entrypoint" in - (* bad entrypoint *) - Contract_helpers.run_script - ctxt - "{parameter unit; storage unit; code { CAR; NIL operation; PAIR }}" - ~entrypoint - ~storage - ~parameter - () - >>= function - | Ok _ -> Alcotest.fail "expected error" - | Error lst - when List.mem - ~equal:( = ) - (Environment.Ecoproto_error - (Script_tc_errors.No_such_entrypoint entrypoint)) - lst -> - return () - | Error errs -> - Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs - -let test_bad_parameter () = - Context.init 1 >>=? fun (b, _cs) -> - Incremental.begin_construction b >>=? fun v -> - let ctxt = Incremental.alpha_ctxt v in - let storage = "Unit" in - let parameter = "1" in - (* bad parameter *) - Contract_helpers.run_script - ctxt - "{parameter unit; storage unit; code { CAR; NIL operation; PAIR }}" - ~storage - ~parameter - () - >>= function - | Ok _ -> Alcotest.fail "expected error" - | Error lst - when List.mem - ~equal:( = ) - (Environment.Ecoproto_error - (Script_interpreter.Bad_contract_parameter - (Contract.implicit_contract Signature.Public_key_hash.zero))) - lst -> - return () - | Error errs -> - Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs - -let transfer_to_itself_with_no_such_entrypoint () = - let entrypoint = "bad entrypoint" in - Context.init 1 >>=? fun (b, contract) -> - Incremental.begin_construction b >>=? fun i -> - let addr = match contract with [hd] -> hd | _ -> assert false in - Op.transaction (B b) addr addr Tez.one ~entrypoint >>=? fun transaction -> - let expect_failure = function - | Environment.Ecoproto_error (Script_tc_errors.No_such_entrypoint _ as e) - :: _ -> - Assert.test_error_encodings e ; - return () - | _ -> failwith "no such entrypoint should fail" - in - Incremental.add_operation ~expect_failure i transaction >>= fun _res -> - return () - -let tests = - [ - (* single transfer *) - Tztest.tztest "single transfer" `Quick test_block_with_a_single_transfer; - Tztest.tztest - "single transfer with fee" - `Quick - test_block_with_a_single_transfer_with_fee; - (* transfer zero tez *) - Tztest.tztest "single transfer zero tez" `Quick test_transfer_zero_tez; - Tztest.tztest - "transfer zero tez from implicit contract" - `Quick - test_transfer_zero_implicit; - Tztest.tztest - "transfer zero tez to an implicit contract with balance of src as fee" - `Quick - test_transfer_zero_implicit_with_bal_src_as_fee; - (* transfer to originated contract *) - Tztest.tztest - "transfer to originated contract paying transaction fee" - `Quick - test_transfer_to_originate_with_fee; - Tztest.tztest - "transfer zero tez to an originated contract with balance of src as fee" - `Quick - test_transfer_zero_to_originated_with_bal_src_as_fee; - (* transfer by the balance of contract *) - Tztest.tztest - "transfer the amount from source contract balance" - `Quick - test_transfer_amount_of_contract_balance; - (* transfer to itself *) - Tztest.tztest "transfers to itself" `Quick test_transfers_to_self; - (* missing operation *) - Tztest.tztest "missing transaction" `Quick test_missing_transaction; - (* transfer from/to implicit/originated contracts*) - Tztest.tztest - "transfer from an implicit to implicit contract " - `Quick - test_transfer_from_implicit_to_implicit_contract; - Tztest.tztest - "transfer from an implicit to an originated contract" - `Quick - test_transfer_from_implicit_to_originated_contract; - (* Slow tests *) - Tztest.tztest - "block with multiple transfers" - `Slow - test_block_with_multiple_transfers; - (* TODO increase the number of transaction times *) - Tztest.tztest - "block with multiple transfer paying fee" - `Slow - test_block_with_multiple_transfers_pay_fee; - Tztest.tztest - "block with multiple transfer without paying fee" - `Slow - test_block_with_multiple_transfers_with_without_fee; - (* build the chain *) - Tztest.tztest "build a chain" `Quick test_build_a_chain; - (* Erroneous *) - Tztest.tztest "empty implicit" `Quick test_empty_implicit; - Tztest.tztest - "balance too low - transfer zero" - `Quick - (test_balance_too_low Tez.zero); - Tztest.tztest "balance too low" `Quick (test_balance_too_low Tez.one); - Tztest.tztest - "balance too low (max fee)" - `Quick - (test_balance_too_low max_tez); - Tztest.tztest - "balance too low with two transfers - transfer zero" - `Quick - (test_balance_too_low_two_transfers Tez.zero); - Tztest.tztest - "balance too low with two transfers" - `Quick - (test_balance_too_low_two_transfers Tez.one); - Tztest.tztest - "transfer one tez to an implicit contract with balance of src as fee" - `Quick - test_transfer_one_to_implicit_with_bal_src_as_fee; - Tztest.tztest "invalid_counter" `Quick invalid_counter; - Tztest.tztest - "add the same operation twice" - `Quick - test_add_the_same_operation_twice; - Tztest.tztest - "invalid_counter_in_the_future" - `Quick - invalid_counter_in_the_future; - Tztest.tztest "ownership sender" `Quick test_ownership_sender; - (* Random tests *) - Tztest.tztest "random transfer" `Quick test_random_transfer; - Tztest.tztest "random multi transfer" `Quick test_random_multi_transactions; - Tztest.tztest "bad entrypoint" `Quick test_bad_entrypoint; - Tztest.tztest "bad parameter" `Quick test_bad_parameter; - Tztest.tztest - "no such entrypoint" - `Quick - transfer_to_itself_with_no_such_entrypoint; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_typechecking.ml b/src/proto_012_Psithaca/lib_protocol/test/test_typechecking.ml deleted file mode 100644 index 0ac6aadb4e57..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_typechecking.ml +++ /dev/null @@ -1,915 +0,0 @@ -(** Testing - ------- - Component: Protocol (type-checking) - Invocation: cd src/proto_alpha/lib_protocol/test - dune exec ./main.exe -- test "^typechecking$" - Subject: Type-checking -*) - -open Protocol -open Alpha_context -open Micheline -open Error_monad_operators - -let wrap_error_lwt x = x >>= fun x -> Lwt.return @@ Environment.wrap_tzresult x - -(* Test for Script_ir_translator.unparse_script on a script declaring views. *) -let test_unparse_view () = - let dummy_contract = - "{parameter unit; storage unit; code { CAR; NIL operation; PAIR }; view \ - \"v0\" unit unit { DROP; UNIT }; view \"v1\" nat nat {CAR}}" - in - let contract_expr = Expr.from_string dummy_contract in - let storage_expr = Expr.from_string "Unit" in - let bef = Script.lazy_expr contract_expr |> Data_encoding.force_bytes in - let script = - Script.{code = lazy_expr contract_expr; storage = lazy_expr storage_expr} - in - Context.init 3 >>=? fun (b, _cs) -> - Incremental.begin_construction b >>=? fun v -> - let ctx = Incremental.alpha_ctxt v in - Script_ir_translator.parse_script - ctx - ~legacy:true - ~allow_forged_in_storage:false - script - >>=?? fun (Ex_script script, ctx) -> - Script_ir_translator.unparse_script ctx Readable script - >>=?? fun (unparse_script, _ctx) -> - let aft = Data_encoding.force_bytes unparse_script.code in - Alcotest.(check bytes) "didn't match" bef aft |> return - -let test_context () = - Context.init ~consensus_threshold:0 3 >>=? fun (b, _cs) -> - Incremental.begin_construction b >>=? fun v -> - return (Incremental.alpha_ctxt v) - -let test_context_with_nat_nat_big_map () = - Context.init 3 >>=? fun (b, contracts) -> - let source = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in - Op.origination (B b) source ~script:Op.dummy_script - >>=? fun (operation, originated) -> - Block.bake ~operation b >>=? fun b -> - Incremental.begin_construction b >>=? fun v -> - let ctxt = Incremental.alpha_ctxt v in - wrap_error_lwt @@ Big_map.fresh ~temporary:false ctxt >>=? fun (ctxt, id) -> - let nat_ty = Script_typed_ir.nat_t ~annot:None in - wrap_error_lwt @@ Lwt.return - @@ Script_ir_translator.unparse_ty ~loc:() ctxt nat_ty - >>=? fun (nat_ty_node, ctxt) -> - let nat_ty_expr = Micheline.strip_locations nat_ty_node in - let alloc = Big_map.{key_type = nat_ty_expr; value_type = nat_ty_expr} in - let init = Lazy_storage.Alloc alloc in - let diffs = - [ - Lazy_storage.make - Lazy_storage.Kind.Big_map - id - (Update {init; updates = []}); - ] - in - wrap_error_lwt - @@ Contract.update_script_storage ctxt originated nat_ty_expr (Some diffs) - >>=? fun ctxt -> return (ctxt, id) - -let read_file filename = - let ch = open_in filename in - let s = really_input_string ch (in_channel_length ch) in - close_in ch ; - s - -(** Check that the custom stack overflow exception is triggered when - it should be. *) -let test_typecheck_stack_overflow () = - test_context () >>=? fun ctxt -> - let storage = "Unit" in - let parameter = "Unit" in - let script = read_file "./contracts/big_interpreter_stack.tz" in - Contract_helpers.run_script ctxt script ~storage ~parameter () >>= function - | Ok _ -> Alcotest.fail "expected an error" - | Error lst - when List.mem - ~equal:( = ) - (Environment.Ecoproto_error - Script_tc_errors.Typechecking_too_many_recursive_calls) - lst -> - return () - | Error errs -> - Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs - -(* NOTE: this test fails with an out-of-memory exception. *) -let _test_unparse_stack_overflow () = - test_context () >>=? fun ctxt -> - (* Meme *) - let enorme_et_seq n = - let rec aux n acc = aux (n - 1) @@ Micheline.Seq (0, [acc]) in - aux n (Micheline.Int (0, Z.zero)) - in - Script_ir_translator.(unparse_code ctxt Readable (enorme_et_seq 10_001)) - >>= function - | Ok _ -> Alcotest.fail "expected an error" - | Error trace -> - let trace_string = - Format.asprintf "%a" Environment.Error_monad.pp_trace trace - in - let expect_id = "michelson_v1.unparsing_stack_overflow" in - let expect_descrfiption = - "Too many recursive calls were needed for unparsing" - in - if - Astring.String.is_infix ~affix:expect_id trace_string - && Astring.String.is_infix ~affix:expect_descrfiption trace_string - then return_unit - else - Alcotest.failf - "Unexpected error (%s) at %s" - trace_string - __LOC__ - return_unit - -let location = function - | Prim (loc, _, _, _) - | Int (loc, _) - | String (loc, _) - | Bytes (loc, _) - | Seq (loc, _) -> - loc - -let test_parse_ty ctxt node expected = - let legacy = false in - let allow_lazy_storage = true in - let allow_operation = true in - let allow_contract = true in - let allow_ticket = true in - Environment.wrap_tzresult - ( Script_ir_translator.parse_ty - ctxt - ~legacy - ~allow_lazy_storage - ~allow_operation - ~allow_contract - ~allow_ticket - node - >>? fun (Script_ir_translator.Ex_ty actual, ctxt) -> - Script_ir_translator.ty_eq ctxt (location node) actual expected - >|? fun (_, ctxt) -> ctxt ) - -let var_annot = Script_ir_annot.FOR_TESTS.unsafe_var_annot_of_string - -let type_annot = Script_ir_annot.FOR_TESTS.unsafe_type_annot_of_string - -let field_annot = Script_ir_annot.FOR_TESTS.unsafe_field_annot_of_string - -let test_parse_comb_type () = - let open Script in - let open Script_typed_ir in - let nat_prim = Prim (-1, T_nat, [], []) in - let nat_prim_a = Prim (-1, T_nat, [], ["%a"]) in - let nat_prim_b = Prim (-1, T_nat, [], ["%b"]) in - let nat_prim_c = Prim (-1, T_nat, [], ["%c"]) in - let nat_ty = nat_t ~annot:None in - let pair_prim l = Prim (-1, T_pair, l, []) in - let pair_ty ty1 ty2 = - pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None - in - let pair_prim2 a b = pair_prim [a; b] in - let pair_nat_nat_prim = pair_prim2 nat_prim nat_prim in - pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> - test_context () >>=? fun ctxt -> - (* pair nat nat *) - test_parse_ty ctxt pair_nat_nat_prim pair_nat_nat_ty >>?= fun ctxt -> - (* pair (pair nat nat) nat *) - pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> - test_parse_ty - ctxt - (pair_prim2 pair_nat_nat_prim nat_prim) - pair_pair_nat_nat_nat_ty - >>?= fun ctxt -> - (* pair nat (pair nat nat) *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_pair_nat_nat_ty -> - test_parse_ty - ctxt - (pair_prim2 nat_prim pair_nat_nat_prim) - pair_nat_pair_nat_nat_ty - >>?= fun ctxt -> - (* pair nat nat nat *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_nat_nat_ty -> - test_parse_ty - ctxt - (pair_prim [nat_prim; nat_prim; nat_prim]) - pair_nat_nat_nat_ty - >>?= fun ctxt -> - (* pair (nat %a) nat *) - pair_t - (-1) - (nat_ty, Some (field_annot "a"), None) - (nat_ty, None, None) - ~annot:None - >>??= fun pair_nat_a_nat_ty -> - test_parse_ty ctxt (pair_prim2 nat_prim_a nat_prim) pair_nat_a_nat_ty - >>?= fun ctxt -> - (* pair nat (nat %b) *) - pair_t - (-1) - (nat_ty, None, None) - (nat_ty, Some (field_annot "b"), None) - ~annot:None - >>??= fun pair_nat_nat_b_ty -> - test_parse_ty ctxt (pair_prim2 nat_prim nat_prim_b) pair_nat_nat_b_ty - >>?= fun ctxt -> - (* pair (nat %a) (nat %b) *) - pair_t - (-1) - (nat_ty, Some (field_annot "a"), None) - (nat_ty, Some (field_annot "b"), None) - ~annot:None - >>??= fun pair_nat_a_nat_b_ty -> - test_parse_ty ctxt (pair_prim2 nat_prim_a nat_prim_b) pair_nat_a_nat_b_ty - >>?= fun ctxt -> - (* pair (nat %a) (nat %b) (nat %c) *) - pair_t - (-1) - (nat_ty, Some (field_annot "b"), None) - (nat_ty, Some (field_annot "c"), None) - ~annot:None - >>??= fun pair_nat_b_nat_c_ty -> - pair_t - (-1) - (nat_ty, Some (field_annot "a"), None) - (pair_nat_b_nat_c_ty, None, None) - ~annot:None - >>??= fun pair_nat_a_nat_b_nat_c_ty -> - test_parse_ty - ctxt - (pair_prim [nat_prim_a; nat_prim_b; nat_prim_c]) - pair_nat_a_nat_b_nat_c_ty - >>?= fun ctxt -> - (* pair (nat %a) (pair %b nat nat) *) - pair_t (-1) (nat_ty, None, None) (nat_ty, None, None) ~annot:None - >>??= fun pair_b_nat_nat_ty -> - pair_t - (-1) - (nat_ty, Some (field_annot "a"), None) - (pair_b_nat_nat_ty, Some (field_annot "b"), None) - ~annot:None - >>??= fun pair_nat_a_pair_b_nat_nat_ty -> - test_parse_ty - ctxt - (pair_prim2 nat_prim_a (Prim (-1, T_pair, [nat_prim; nat_prim], ["%b"]))) - pair_nat_a_pair_b_nat_nat_ty - >>?= fun _ -> return_unit - -let test_unparse_ty loc ctxt expected ty = - Environment.wrap_tzresult - ( Script_ir_translator.unparse_ty ~loc:() ctxt ty >>? fun (actual, ctxt) -> - if actual = expected then ok ctxt - else Alcotest.failf "Unexpected error: %s" loc ) - -let test_unparse_comb_type () = - let open Script in - let open Script_typed_ir in - let nat_prim = Prim ((), T_nat, [], []) in - let nat_prim_a = Prim ((), T_nat, [], ["%a"]) in - let nat_prim_b = Prim ((), T_nat, [], ["%b"]) in - let nat_prim_c = Prim ((), T_nat, [], ["%c"]) in - let nat_ty = nat_t ~annot:None in - let pair_prim l = Prim ((), T_pair, l, []) in - let pair_ty ty1 ty2 = - pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None - in - let pair_prim2 a b = pair_prim [a; b] in - let pair_nat_nat_prim = pair_prim2 nat_prim nat_prim in - pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> - test_context () >>=? fun ctxt -> - (* pair nat nat *) - test_unparse_ty __LOC__ ctxt pair_nat_nat_prim pair_nat_nat_ty - >>?= fun ctxt -> - (* pair (pair nat nat) nat *) - pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> - test_unparse_ty - __LOC__ - ctxt - (pair_prim2 pair_nat_nat_prim nat_prim) - pair_pair_nat_nat_nat_ty - >>?= fun ctxt -> - (* pair nat nat nat *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_nat_nat_ty -> - test_unparse_ty - __LOC__ - ctxt - (pair_prim [nat_prim; nat_prim; nat_prim]) - pair_nat_nat_nat_ty - >>?= fun ctxt -> - (* pair (nat %a) nat *) - pair_t - (-1) - (nat_ty, Some (field_annot "a"), None) - (nat_ty, None, None) - ~annot:None - >>??= fun pair_nat_a_nat_ty -> - test_unparse_ty - __LOC__ - ctxt - (pair_prim2 nat_prim_a nat_prim) - pair_nat_a_nat_ty - >>?= fun ctxt -> - (* pair nat (nat %b) *) - pair_t - (-1) - (nat_ty, None, None) - (nat_ty, Some (field_annot "b"), None) - ~annot:None - >>??= fun pair_nat_nat_b_ty -> - test_unparse_ty - __LOC__ - ctxt - (pair_prim2 nat_prim nat_prim_b) - pair_nat_nat_b_ty - >>?= fun ctxt -> - (* pair (nat %a) (nat %b) *) - pair_t - (-1) - (nat_ty, Some (field_annot "a"), None) - (nat_ty, Some (field_annot "b"), None) - ~annot:None - >>??= fun pair_nat_a_nat_b_ty -> - test_unparse_ty - __LOC__ - ctxt - (pair_prim2 nat_prim_a nat_prim_b) - pair_nat_a_nat_b_ty - >>?= fun ctxt -> - (* pair (nat %a) (nat %b) (nat %c) *) - pair_t - (-1) - (nat_ty, Some (field_annot "b"), None) - (nat_ty, Some (field_annot "c"), None) - ~annot:None - >>??= fun pair_nat_b_nat_c_ty -> - pair_t - (-1) - (nat_ty, Some (field_annot "a"), None) - (pair_nat_b_nat_c_ty, None, None) - ~annot:None - >>??= fun pair_nat_a_nat_b_nat_c_ty -> - test_unparse_ty - __LOC__ - ctxt - (pair_prim [nat_prim_a; nat_prim_b; nat_prim_c]) - pair_nat_a_nat_b_nat_c_ty - >>?= fun ctxt -> - (* pair (nat %a) (pair %b nat nat) *) - pair_t (-1) (nat_ty, None, None) (nat_ty, None, None) ~annot:None - >>??= fun pair_nat_nat_ty -> - pair_t - (-1) - (nat_ty, Some (field_annot "a"), None) - (pair_nat_nat_ty, Some (field_annot "b"), None) - ~annot:None - >>??= fun pair_nat_a_pair_b_nat_nat_ty -> - test_unparse_ty - __LOC__ - ctxt - (pair_prim2 nat_prim_a (Prim ((), T_pair, [nat_prim; nat_prim], ["%b"]))) - pair_nat_a_pair_b_nat_nat_ty - >>?= fun ctxt -> - (* pair nat (pair @b nat nat) *) - pair_t - (-1) - (nat_ty, None, None) - (pair_nat_nat_ty, None, Some (var_annot "b")) - ~annot:None - >>??= fun pair_nat_pair_b_nat_nat_ty -> - test_unparse_ty - __LOC__ - ctxt - (pair_prim2 nat_prim (Prim ((), T_pair, [nat_prim; nat_prim], ["@b"]))) - pair_nat_pair_b_nat_nat_ty - >>?= fun ctxt -> - (* pair nat (pair :b nat nat) *) - pair_t - (-1) - (nat_ty, None, None) - (nat_ty, None, None) - ~annot:(Some (type_annot "b")) - >>??= fun pair_b_nat_nat_ty -> - pair_t (-1) (nat_ty, None, None) (pair_b_nat_nat_ty, None, None) ~annot:None - >>??= fun pair_nat_pair_b_nat_nat_ty -> - test_unparse_ty - __LOC__ - ctxt - (pair_prim2 nat_prim (Prim ((), T_pair, [nat_prim; nat_prim], [":b"]))) - pair_nat_pair_b_nat_nat_ty - >>?= fun _ -> return_unit - -let test_unparse_comparable_ty loc ctxt expected ty = - (* unparse_comparable_ty is not exported, the simplest way to call it is to - call parse_ty on a set type *) - let open Script_typed_ir in - Environment.wrap_tzresult - ( set_t (-1) ty ~annot:None >>? fun set_ty_ty -> - Script_ir_translator.unparse_ty ~loc:() ctxt set_ty_ty - >>? fun (actual, ctxt) -> - if actual = Prim ((), T_set, [expected], []) then ok ctxt - else Alcotest.failf "Unexpected error: %s" loc ) - -let test_unparse_comb_comparable_type () = - let open Script in - let open Script_typed_ir in - let nat_prim = Prim ((), T_nat, [], []) in - let nat_prim_a = Prim ((), T_nat, [], ["%a"]) in - let nat_prim_b = Prim ((), T_nat, [], ["%b"]) in - let nat_prim_c = Prim ((), T_nat, [], ["%c"]) in - let nat_ty = nat_key ~annot:None in - let pair_prim l = Prim ((), T_pair, l, []) in - let pair_ty ty1 ty2 = pair_key (-1) (ty1, None) (ty2, None) ~annot:None in - let pair_prim2 a b = pair_prim [a; b] in - let pair_nat_nat_prim = pair_prim2 nat_prim nat_prim in - pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> - test_context () >>=? fun ctxt -> - (* pair nat nat *) - test_unparse_comparable_ty __LOC__ ctxt pair_nat_nat_prim pair_nat_nat_ty - >>?= fun ctxt -> - (* pair (pair nat nat) nat *) - pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> - test_unparse_comparable_ty - __LOC__ - ctxt - (pair_prim2 pair_nat_nat_prim nat_prim) - pair_pair_nat_nat_nat_ty - >>?= fun ctxt -> - (* pair nat nat nat *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_nat_nat_ty -> - test_unparse_comparable_ty - __LOC__ - ctxt - (pair_prim [nat_prim; nat_prim; nat_prim]) - pair_nat_nat_nat_ty - >>?= fun ctxt -> - (* pair (nat %a) nat *) - pair_key (-1) (nat_ty, Some (field_annot "a")) (nat_ty, None) ~annot:None - >>??= fun pair_nat_a_nat_ty -> - test_unparse_comparable_ty - __LOC__ - ctxt - (pair_prim2 nat_prim_a nat_prim) - pair_nat_a_nat_ty - >>?= fun ctxt -> - (* pair nat (nat %b) *) - pair_key (-1) (nat_ty, None) (nat_ty, Some (field_annot "b")) ~annot:None - >>??= fun pair_nat_nat_b_ty -> - test_unparse_comparable_ty - __LOC__ - ctxt - (pair_prim2 nat_prim nat_prim_b) - pair_nat_nat_b_ty - >>?= fun ctxt -> - (* pair (nat %a) (nat %b) *) - pair_key - (-1) - (nat_ty, Some (field_annot "a")) - (nat_ty, Some (field_annot "b")) - ~annot:None - >>??= fun pair_nat_a_nat_b_ty -> - test_unparse_comparable_ty - __LOC__ - ctxt - (pair_prim2 nat_prim_a nat_prim_b) - pair_nat_a_nat_b_ty - >>?= fun ctxt -> - (* pair (nat %a) (nat %b) (nat %c) *) - pair_key - (-1) - (nat_ty, Some (field_annot "b")) - (nat_ty, Some (field_annot "c")) - ~annot:None - >>??= fun pair_nat_b_nat_c_ty -> - pair_key - (-1) - (nat_ty, Some (field_annot "a")) - (pair_nat_b_nat_c_ty, None) - ~annot:None - >>??= fun pair_nat_a_nat_b_nat_c_ty -> - test_unparse_comparable_ty - __LOC__ - ctxt - (pair_prim [nat_prim_a; nat_prim_b; nat_prim_c]) - pair_nat_a_nat_b_nat_c_ty - >>?= fun ctxt -> - (* pair (nat %a) (pair %b nat nat) *) - pair_key - (-1) - (nat_ty, Some (field_annot "a")) - (pair_nat_nat_ty, Some (field_annot "b")) - ~annot:None - >>??= fun pair_nat_a_pair_b_nat_nat_ty -> - test_unparse_comparable_ty - __LOC__ - ctxt - (pair_prim2 nat_prim_a (Prim ((), T_pair, [nat_prim; nat_prim], ["%b"]))) - pair_nat_a_pair_b_nat_nat_ty - >>?= fun ctxt -> - (* pair nat (pair :b nat nat) *) - pair_key (-1) (nat_ty, None) (nat_ty, None) ~annot:(Some (type_annot "b")) - >>??= fun pair_b_nat_nat_ty -> - pair_key (-1) (nat_ty, None) (pair_b_nat_nat_ty, None) ~annot:None - >>??= fun pair_nat_pair_b_nat_nat_ty -> - test_unparse_comparable_ty - __LOC__ - ctxt - (pair_prim2 nat_prim (Prim ((), T_pair, [nat_prim; nat_prim], [":b"]))) - pair_nat_pair_b_nat_nat_ty - >>?= fun _ -> return_unit - -let test_parse_data ?(equal = Stdlib.( = )) loc ctxt ty node expected = - let legacy = false in - let allow_forged = true in - wrap_error_lwt - ( Script_ir_translator.parse_data ctxt ~legacy ~allow_forged ty node - >>=? fun (actual, ctxt) -> - if equal actual expected then return ctxt - else Alcotest.failf "Unexpected error: %s" loc ) - -let test_parse_data_fails loc ctxt ty node = - let legacy = false in - let allow_forged = false in - wrap_error_lwt - (Script_ir_translator.parse_data ctxt ~legacy ~allow_forged ty node - >>= function - | Ok _ -> Alcotest.failf "Unexpected typechecking success: %s" loc - | Error trace -> - let trace_string = - Format.asprintf "%a" Environment.Error_monad.pp_trace trace - in - let expect_id = "michelson_v1.invalid_constant" in - let expect_descrfiption = - "A data expression was invalid for its expected type." - in - if - Astring.String.is_infix ~affix:expect_id trace_string - && Astring.String.is_infix ~affix:expect_descrfiption trace_string - then return_unit - else - Alcotest.failf - "Unexpected error (%s) at %s" - trace_string - __LOC__ - return_unit) - -let test_parse_comb_data () = - let open Script in - let open Script_typed_ir in - let z = Script_int.zero_n in - let z_prim = Micheline.Int (-1, Z.zero) in - let nat_ty = nat_t ~annot:None in - let pair_prim l = Prim (-1, D_Pair, l, []) in - let pair_ty ty1 ty2 = - pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None - in - pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> - let pair_prim2 a b = pair_prim [a; b] in - let pair_z_z_prim = pair_prim2 z_prim z_prim in - list_t (-1) nat_ty ~annot:None >>??= fun list_nat_ty -> - big_map_t (-1) (nat_key ~annot:None) nat_ty ~annot:None - >>??= fun big_map_nat_nat_ty -> - test_context_with_nat_nat_big_map () >>=? fun (ctxt, big_map_id) -> - (* Pair 0 0 *) - test_parse_data __LOC__ ctxt pair_nat_nat_ty pair_z_z_prim (z, z) - >>=? fun ctxt -> - (* {0; 0} *) - test_parse_data - __LOC__ - ctxt - pair_nat_nat_ty - (Micheline.Seq (-1, [z_prim; z_prim])) - (z, z) - >>=? fun ctxt -> - (* Pair (Pair 0 0) 0 *) - pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> - test_parse_data - __LOC__ - ctxt - pair_pair_nat_nat_nat_ty - (pair_prim2 pair_z_z_prim z_prim) - ((z, z), z) - >>=? fun ctxt -> - (* Pair 0 (Pair 0 0) *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_pair_nat_nat_ty -> - test_parse_data - __LOC__ - ctxt - pair_nat_pair_nat_nat_ty - (pair_prim2 z_prim pair_z_z_prim) - (z, (z, z)) - >>=? fun ctxt -> - (* Pair 0 0 0 *) - test_parse_data - __LOC__ - ctxt - pair_nat_pair_nat_nat_ty - (pair_prim [z_prim; z_prim; z_prim]) - (z, (z, z)) - >>=? fun ctxt -> - (* {0; 0; 0} *) - test_parse_data - __LOC__ - ctxt - pair_nat_pair_nat_nat_ty - (Micheline.Seq (-1, [z_prim; z_prim; z_prim])) - (z, (z, z)) - >>=? fun ctxt -> - (* Should fail: {0} against pair nat (list nat) *) - pair_ty nat_ty list_nat_ty >>??= fun pair_nat_list_nat_ty -> - test_parse_data_fails - __LOC__ - ctxt - pair_nat_list_nat_ty - (Micheline.Seq (-1, [z_prim])) - >>=? fun () -> - (* Should fail: {0; 0; 0} against pair nat (list nat) *) - test_parse_data_fails - __LOC__ - ctxt - pair_nat_list_nat_ty - (Micheline.Seq (-1, [z_prim; z_prim; z_prim])) - >>=? fun () -> - (* check Pair 0 (Pair 0 {}) against pair nat (big_map nat nat) - so that the following test fails for the good reason and not because - the big map doesn't exist - *) - let id_z = Big_map.Id.unparse_to_z big_map_id in - let id_prim = Int (-1, id_z) in - let expected_big_map = - let open Script_typed_ir in - let diff = {map = Big_map_overlay.empty; size = 0} in - let nat_key_ty = nat_key ~annot:None in - {id = Some big_map_id; diff; key_type = nat_key_ty; value_type = nat_ty} - in - let equal (nat1, big_map1) (nat2, big_map2) = - (* Custom equal needed because big maps contain boxed maps containing functional values *) - nat1 = nat2 && big_map1.id = big_map2.id - && big_map1.key_type = big_map2.key_type - && big_map1.value_type = big_map2.value_type - && big_map1.diff.size = big_map2.diff.size - && Big_map_overlay.bindings big_map1.diff.map - = Big_map_overlay.bindings big_map2.diff.map - in - pair_ty nat_ty big_map_nat_nat_ty >>??= fun pair_nat_big_map_nat_nat_ty -> - test_parse_data - ~equal - __LOC__ - ctxt - pair_nat_big_map_nat_nat_ty - (pair_prim2 z_prim (pair_prim2 id_prim (Seq (-1, [])))) - (Script_int.zero_n, expected_big_map) - >>=? fun ctxt -> - (* Should fail: Pair 0 0 {} against pair nat (big_map nat nat) *) - test_parse_data_fails - __LOC__ - ctxt - pair_nat_big_map_nat_nat_ty - (pair_prim [z_prim; id_prim; Seq (-1, [])]) - -let test_parse_address () = - let open Script_typed_ir in - test_context_with_nat_nat_big_map () >>=? fun (ctxt, _big_map_id) -> - (* KT1% (empty entrypoint) *) - wrap_error_lwt - (Lwt.return (Contract.of_b58check "KT1FAKEFAKEFAKEFAKEFAKEFAKEFAKGGSE2x")) - >>=? fun kt1fake -> - test_parse_data - __LOC__ - ctxt - (address_t ~annot:None) - (String (-1, "KT1FAKEFAKEFAKEFAKEFAKEFAKEFAKGGSE2x%")) - (kt1fake, "default") - >>=? fun ctxt -> - (* tz1% (empty entrypoint) *) - wrap_error_lwt - (Lwt.return (Contract.of_b58check "tz1fakefakefakefakefakefakefakcphLA5")) - >>=? fun tz1fake -> - test_parse_data - __LOC__ - ctxt - (address_t ~annot:None) - (String (-1, "tz1fakefakefakefakefakefakefakcphLA5%")) - (tz1fake, "default") - >|=? fun _ctxt -> () - -let test_unparse_data loc ctxt ty x ~expected_readable ~expected_optimized = - wrap_error_lwt - ( Script_ir_translator.unparse_data ctxt Script_ir_translator.Readable ty x - >>=? fun (actual_readable, ctxt) -> - (if actual_readable = expected_readable then return ctxt - else Alcotest.failf "Error in readable unparsing: %s" loc) - >>=? fun ctxt -> - Script_ir_translator.unparse_data ctxt Script_ir_translator.Optimized ty x - >>=? fun (actual_optimized, ctxt) -> - if actual_optimized = expected_optimized then return ctxt - else Alcotest.failf "Error in optimized unparsing: %s" loc ) - -let test_unparse_comb_data () = - let open Script in - let open Script_typed_ir in - let z = Script_int.zero_n in - let z_prim = Micheline.Int (-1, Z.zero) in - let nat_ty = nat_t ~annot:None in - let pair_prim l = Prim (-1, D_Pair, l, []) in - let pair_ty ty1 ty2 = - pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None - in - pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> - let pair_prim2 a b = pair_prim [a; b] in - let pair_z_z_prim = pair_prim2 z_prim z_prim in - test_context () >>=? fun ctxt -> - (* Pair 0 0 *) - test_unparse_data - __LOC__ - ctxt - pair_nat_nat_ty - (z, z) - ~expected_readable:pair_z_z_prim - ~expected_optimized:pair_z_z_prim - >>=? fun ctxt -> - (* Pair (Pair 0 0) 0 *) - pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> - test_unparse_data - __LOC__ - ctxt - pair_pair_nat_nat_nat_ty - ((z, z), z) - ~expected_readable:(pair_prim2 pair_z_z_prim z_prim) - ~expected_optimized:(pair_prim2 pair_z_z_prim z_prim) - >>=? fun ctxt -> - (* Readable: Pair 0 0 0; Optimized: Pair 0 (Pair 0 0) *) - pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_pair_nat_nat_ty -> - test_unparse_data - __LOC__ - ctxt - pair_nat_pair_nat_nat_ty - (z, (z, z)) - ~expected_readable:(pair_prim [z_prim; z_prim; z_prim]) - ~expected_optimized:(pair_prim2 z_prim pair_z_z_prim) - >>=? fun ctxt -> - (* Readable: Pair 0 0 0 0; Optimized: {0; 0; 0; 0} *) - pair_ty nat_ty pair_nat_pair_nat_nat_ty - >>??= fun pair_nat_pair_nat_pair_nat_nat_ty -> - test_unparse_data - __LOC__ - ctxt - pair_nat_pair_nat_pair_nat_nat_ty - (z, (z, (z, z))) - ~expected_readable:(pair_prim [z_prim; z_prim; z_prim; z_prim]) - ~expected_optimized:(Micheline.Seq (-1, [z_prim; z_prim; z_prim; z_prim])) - >>=? fun _ -> return_unit - -(* Generate all the possible syntaxes for pairs *) -let gen_pairs left right = - [Prim ((), Script.D_Pair, [left; right], []); Seq ((), [left; right])] - -(* Generate all the possible syntaxes for combs *) -let rec gen_combs leaf arity = - assert (arity >= 2) ; - if arity = 2 then gen_pairs leaf leaf - else - gen_combs leaf (arity - 1) - |> List.map (fun smaller -> - (match smaller with - | Prim (loc, Script.D_Pair, vs, []) -> - Prim (loc, Script.D_Pair, leaf :: vs, []) - | Seq (loc, vs) -> Seq (loc, leaf :: vs) - | _ -> assert false) - :: gen_pairs leaf smaller) - |> List.flatten - -(* Checks the optimality of the Optimized Micheline representation for combs *) -let test_optimal_comb () = - let open Script_typed_ir in - let leaf_ty = nat_t ~annot:None in - let leaf_mich = Int ((), Z.zero) in - let leaf_v = Script_int.zero_n in - let size_of_micheline mich = - let canonical = Micheline.strip_locations mich in - ( canonical, - Bytes.length - @@ Data_encoding.Binary.to_bytes_exn Script.expr_encoding canonical ) - in - let check_optimal_comb loc ctxt ty v arity = - wrap_error_lwt - ( Script_ir_translator.unparse_data - ctxt - Script_ir_translator.Optimized - ty - v - >>=? fun (unparsed, ctxt) -> - let (unparsed_canonical, unparsed_size) = size_of_micheline unparsed in - List.iter_es (fun other_repr -> - let (other_repr_canonical, other_repr_size) = - size_of_micheline other_repr - in - if other_repr_size < unparsed_size then - Alcotest.failf - "At %s, for comb of arity %d, representation %a (size %d \ - bytes) is shorter than representation %a (size %d bytes) \ - returned by unparse_data in Optimized mode" - loc - arity - Michelson_v1_printer.print_expr - other_repr_canonical - other_repr_size - Michelson_v1_printer.print_expr - unparsed_canonical - unparsed_size - else return_unit) - @@ gen_combs leaf_mich arity - >>=? fun () -> return ctxt ) - in - let pair_ty ty1 ty2 = - pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None - in - test_context () >>=? fun ctxt -> - pair_ty leaf_ty leaf_ty >>??= fun comb2_ty -> - let comb2_v = (leaf_v, leaf_v) in - check_optimal_comb __LOC__ ctxt comb2_ty comb2_v 2 >>=? fun ctxt -> - pair_ty leaf_ty comb2_ty >>??= fun comb3_ty -> - let comb3_v = (leaf_v, comb2_v) in - check_optimal_comb __LOC__ ctxt comb3_ty comb3_v 3 >>=? fun ctxt -> - pair_ty leaf_ty comb3_ty >>??= fun comb4_ty -> - let comb4_v = (leaf_v, comb3_v) in - check_optimal_comb __LOC__ ctxt comb4_ty comb4_v 4 >>=? fun ctxt -> - pair_ty leaf_ty comb4_ty >>??= fun comb5_ty -> - let comb5_v = (leaf_v, comb4_v) in - check_optimal_comb __LOC__ ctxt comb5_ty comb5_v 5 >>=? fun _ctxt -> - return_unit - -(* Check that UNPACK on contract is forbidden. - See https://gitlab.com/tezos/tezos/-/issues/301 for the motivation - behind this restriction. - *) -let test_contract_not_packable () = - let contract_unit = - Prim (0, Script.T_contract, [Prim (0, T_unit, [], [])], []) - in - test_context () >>=? fun ctxt -> - (* Test that [contract_unit] is parsable *) - (match Script_ir_translator.parse_any_ty ctxt ~legacy:false contract_unit with - | Ok _ -> return_unit - | Error _ -> Alcotest.failf "Could not parse (contract unit)") - >>=? fun () -> - (* Test that [contract_unit] is not packable *) - (match - Script_ir_translator.parse_packable_ty ctxt ~legacy:false contract_unit - with - | Ok _ -> - Alcotest.failf - "(contract unit) should not be packable, see \ - https://gitlab.com/tezos/tezos/-/issues/301" - | Error _ -> return_unit) - >>=? fun () -> - (* Test that elaboration of the [UNPACK unit] instruction succeeds *) - (Script_ir_translator.parse_instr - Lambda - ctxt - ~legacy:false - (Prim (0, I_UNPACK, [Prim (0, T_unit, [], [])], [])) - (Item_t (Script_typed_ir.bytes_t ~annot:None, Bot_t, None)) - >>= function - | Ok _ -> return_unit - | Error _ -> Alcotest.failf "Could not parse UNPACK unit") - >>=? fun () -> - (* Test that elaboration of the [UNPACK (contract unit)] instruction fails *) - Script_ir_translator.parse_instr - Lambda - ctxt - ~legacy:false - (Prim (0, I_UNPACK, [contract_unit], [])) - (Item_t (Script_typed_ir.bytes_t ~annot:None, Bot_t, None)) - >>= function - | Ok _ -> - Alcotest.failf - "UNPACK (contract unit) should not be allowed, see \ - https://gitlab.com/tezos/tezos/-/issues/301" - | Error _ -> return_unit - -let tests = - [ - Tztest.tztest "test unparse view" `Quick test_unparse_view; - Tztest.tztest - "test typecheck stack overflow error" - `Quick - test_typecheck_stack_overflow; - Tztest.tztest "test comb type parsing" `Quick test_parse_comb_type; - Tztest.tztest "test comb type unparsing" `Quick test_unparse_comb_type; - Tztest.tztest - "test comb comparable type unparsing" - `Quick - test_unparse_comb_comparable_type; - Tztest.tztest "test comb data parsing" `Quick test_parse_comb_data; - Tztest.tztest "test comb data unparsing" `Quick test_unparse_comb_data; - Tztest.tztest "test optimal comb data unparsing" `Quick test_optimal_comb; - Tztest.tztest "test parse address" `Quick test_parse_address; - Tztest.tztest - "test unpackability of the contract type" - `Quick - test_contract_not_packable; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/test_voting.ml b/src/proto_012_Psithaca/lib_protocol/test/test_voting.ml deleted file mode 100644 index 10ae3ba37c41..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/test_voting.ml +++ /dev/null @@ -1,1167 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Protocol (voting) - Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^voting$" - Subject: On the voting process. - -*) - -(* Note that some of these tests assume (more or less) that the - accounts remain active during a voting period, which roughly - translates to the following condition being assumed to hold: - `blocks_per_voting_period <= preserved_cycles * blocks_per_cycle.` - *) - -open Protocol -open Alpha_context - -(* missing stuff in Vote *) -let ballots_zero = Vote.{yay = 0l; nay = 0l; pass = 0l} - -let ballots_equal b1 b2 = - Vote.(b1.yay = b2.yay && b1.nay = b2.nay && b1.pass = b2.pass) - -let ballots_pp ppf v = - Vote.( - Format.fprintf ppf "{ yay = %ld ; nay = %ld ; pass = %ld" v.yay v.nay v.pass) - -(* constants and ratios used in voting: - percent_mul denotes the percent multiplier - initial_participation is 7000 that is, 7/10 * percent_mul - the participation EMA ratio pr_ema_weight / den = 7 / 10 - the participation ratio pr_num / den = 2 / 10 - note: we use the same denominator for both participation EMA and participation rate. - supermajority rate is s_num / s_den = 8 / 10 *) -let percent_mul = 100_00 - -let den = 10 - -let initial_participation_num = 7 - -let initial_participation = initial_participation_num * percent_mul / den - -let pr_ema_weight = 8 - -let pr_num = den - pr_ema_weight - -let s_num = 8 - -let s_den = 10 - -let qr_min_num = 2 - -let qr_max_num = 7 - -let expected_qr_num participation_ema = - let participation_ema = Int32.to_int participation_ema in - let participation_ema = participation_ema * den / percent_mul in - Float.( - of_int qr_min_num - +. of_int participation_ema - *. (of_int qr_max_num -. of_int qr_min_num) - /. of_int den) - -(* Protocol_hash.zero is "PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i" *) -let protos = - Array.map - (fun s -> Protocol_hash.of_b58check_exn s) - [| - "ProtoALphaALphaALphaALphaALphaALphaALpha61322gcLUGH"; - "ProtoALphaALphaALphaALphaALphaALphaALphabc2a7ebx6WB"; - "ProtoALphaALphaALphaALphaALphaALphaALpha84efbeiF6cm"; - "ProtoALphaALphaALphaALphaALphaALphaALpha91249Z65tWS"; - "ProtoALphaALphaALphaALphaALphaALphaALpha537f5h25LnN"; - "ProtoALphaALphaALphaALphaALphaALphaALpha5c8fefgDYkr"; - "ProtoALphaALphaALphaALphaALphaALphaALpha3f31feSSarC"; - "ProtoALphaALphaALphaALphaALphaALphaALphabe31ahnkxSC"; - "ProtoALphaALphaALphaALphaALphaALphaALphabab3bgRb7zQ"; - "ProtoALphaALphaALphaALphaALphaALphaALphaf8d39cctbpk"; - "ProtoALphaALphaALphaALphaALphaALphaALpha3b981byuYxD"; - "ProtoALphaALphaALphaALphaALphaALphaALphaa116bccYowi"; - "ProtoALphaALphaALphaALphaALphaALphaALphacce68eHqboj"; - "ProtoALphaALphaALphaALphaALphaALphaALpha225c7YrWwR7"; - "ProtoALphaALphaALphaALphaALphaALphaALpha58743cJL6FG"; - "ProtoALphaALphaALphaALphaALphaALphaALphac91bcdvmJFR"; - "ProtoALphaALphaALphaALphaALphaALphaALpha1faaadhV7oW"; - "ProtoALphaALphaALphaALphaALphaALphaALpha98232gD94QJ"; - "ProtoALphaALphaALphaALphaALphaALphaALpha9d1d8cijvAh"; - "ProtoALphaALphaALphaALphaALphaALphaALphaeec52dKF6Gx"; - "ProtoALphaALphaALphaALphaALphaALphaALpha841f2cQqajX"; - |] - -(** helper functions *) - -let assert_period_kind expected_kind kind loc = - if Stdlib.(expected_kind = kind) then return_unit - else - Alcotest.failf - "%s - Unexpected voting period kind - expected %a, got %a" - loc - Voting_period.pp_kind - expected_kind - Voting_period.pp_kind - kind - -let assert_period_index expected_index index loc = - if expected_index = index then return_unit - else - Alcotest.failf - "%s - Unexpected voting period index - expected %ld, got %ld" - loc - expected_index - index - -let assert_period_position expected_position position loc = - if position = expected_position then return_unit - else - Alcotest.failf - "%s - Unexpected voting period position blocks - expected %ld, got %ld" - loc - expected_position - position - -let assert_period_remaining expected_remaining remaining loc = - if remaining = expected_remaining then return_unit - else - Alcotest.failf - "%s - Unexpected voting period remaining blocks - expected %ld, got %ld" - loc - expected_remaining - remaining - -let assert_period ?expected_kind ?expected_index ?expected_position - ?expected_remaining b loc = - Context.Vote.get_current_period (B b) - >>=? fun {voting_period; position; remaining} -> - (if Option.is_some expected_kind then - assert_period_kind - (WithExceptions.Option.get ~loc:__LOC__ expected_kind) - voting_period.kind - loc - else return_unit) - >>=? fun () -> - (if Option.is_some expected_index then - assert_period_index - (WithExceptions.Option.get ~loc:__LOC__ expected_index) - voting_period.index - loc - else return_unit) - >>=? fun () -> - (if Option.is_some expected_position then - assert_period_position - (WithExceptions.Option.get ~loc:__LOC__ expected_position) - position - loc - else return_unit) - >>=? fun () -> - if Option.is_some expected_remaining then - assert_period_remaining - (WithExceptions.Option.get ~loc:__LOC__ expected_remaining) - remaining - loc - else return_unit - -let mk_contracts_from_pkh pkh_list = - List.map Contract.implicit_contract pkh_list - -(* get the list of delegates and the list of their rolls from listings *) -let get_delegates_and_rolls_from_listings b = - Context.Vote.get_listings (B b) >|=? fun l -> - (mk_contracts_from_pkh (List.map fst l), List.map snd l) - -(* compute the rolls of each delegate *) -let get_rolls b delegates loc = - Context.Vote.get_listings (B b) >>=? fun l -> - List.map_es - (fun delegate -> - Context.Contract.pkh delegate >>=? fun pkh -> - match List.find_opt (fun (del, _) -> del = pkh) l with - | None -> failwith "%s - Missing delegate" loc - | Some (_, rolls) -> return rolls) - delegates - -(* Checks that the listings are populated *) -let assert_listings_not_empty b ~loc = - Context.Vote.get_listings (B b) >>=? function - | [] -> failwith "Unexpected empty listings (%s)" loc - | _ -> return_unit - -let bake_until_first_block_of_next_period b = - Context.Vote.get_current_period (B b) >>=? fun {remaining; _} -> - Block.bake_n Int32.(add remaining one |> to_int) b - -(** A normal and successful vote sequence. *) -let test_successful_vote num_delegates () = - let open Alpha_context in - let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates - >>=? fun (b, _) -> - (* no ballots in proposal period *) - Context.Vote.get_ballots (B b) >>=? fun v -> - Assert.equal - ~loc:__LOC__ - ballots_equal - "Unexpected ballots" - ballots_pp - v - ballots_zero - >>=? fun () -> - (* no ballots in proposal period *) - (Context.Vote.get_ballot_list (B b) >>=? function - | [] -> return_unit - | _ -> failwith "%s - Unexpected ballot list" __LOC__) - >>=? fun () -> - (* Last baked block is first block of period Proposal *) - assert_period - ~expected_kind:Proposal - ~expected_index:0l - ~expected_position:0l - b - __LOC__ - >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> - (* participation EMA starts at initial_participation *) - Context.Vote.get_participation_ema b >>=? fun v -> - Assert.equal_int ~loc:__LOC__ initial_participation (Int32.to_int v) - >>=? fun () -> - (* listings must be populated in proposal period *) - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> - (* beginning of proposal, denoted by _p1; - take a snapshot of the active delegates and their rolls from listings *) - get_delegates_and_rolls_from_listings b >>=? fun (delegates_p1, rolls_p1) -> - (* no proposals at the beginning of proposal period *) - Context.Vote.get_proposals (B b) >>=? fun ps -> - (if Environment.Protocol_hash.Map.is_empty ps then return_unit - else failwith "%s - Unexpected proposals" __LOC__) - >>=? fun () -> - (* no current proposal during proposal period *) - (Context.Vote.get_current_proposal (B b) >>=? function - | None -> return_unit - | Some _ -> failwith "%s - Unexpected proposal" __LOC__) - >>=? fun () -> - let del1 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates_p1 0 - in - let del2 = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates_p1 1 - in - let props = - List.map (fun i -> protos.(i)) (2 -- Constants.max_proposals_per_delegate) - in - Op.proposals (B b) del1 (Protocol_hash.zero :: props) >>=? fun ops1 -> - Op.proposals (B b) del2 [Protocol_hash.zero] >>=? fun ops2 -> - Block.bake ~operations:[ops1; ops2] b >>=? fun b -> - (* proposals are now populated *) - Context.Vote.get_proposals (B b) >>=? fun ps -> - (* correctly count the double proposal for zero *) - (let weight = - Int32.add - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth rolls_p1 0) - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth rolls_p1 1) - in - match Environment.Protocol_hash.(Map.find zero ps) with - | Some v -> - if v = weight then return_unit - else failwith "%s - Wrong count %ld is not %ld" __LOC__ v weight - | None -> failwith "%s - Missing proposal" __LOC__) - >>=? fun () -> - (* proposing more than maximum_proposals fails *) - Op.proposals (B b) del1 (Protocol_hash.zero :: props) >>=? fun ops -> - Block.bake ~operations:[ops] b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Amendment.Too_many_proposals -> true - | _ -> false) - >>=? fun () -> - (* proposing less than one proposal fails *) - Op.proposals (B b) del1 [] >>=? fun ops -> - Block.bake ~operations:[ops] b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Amendment.Empty_proposal -> true - | _ -> false) - >>=? fun () -> - (* first block of exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* next block is first block of exploration *) - assert_period ~expected_kind:Exploration ~expected_index:1l b __LOC__ - >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> - (* listings must be populated in proposal period before moving to exploration period *) - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> - (* beginning of exploration period, denoted by _p2; - take a snapshot of the active delegates and their rolls from listings *) - get_delegates_and_rolls_from_listings b >>=? fun (delegates_p2, rolls_p2) -> - (* no proposals during exploration period *) - Context.Vote.get_proposals (B b) >>=? fun ps -> - (if Environment.Protocol_hash.Map.is_empty ps then return_unit - else failwith "%s - Unexpected proposals" __LOC__) - >>=? fun () -> - (* current proposal must be set during exploration period *) - (Context.Vote.get_current_proposal (B b) >>=? function - | Some v -> - if Protocol_hash.(equal zero v) then return_unit - else failwith "%s - Wrong proposal" __LOC__ - | None -> failwith "%s - Missing proposal" __LOC__) - >>=? fun () -> - (* unanimous vote: all delegates --active when p2 started-- vote *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - delegates_p2 - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> - Op.ballot (B b) del1 Protocol_hash.zero Vote.Nay >>=? fun op -> - Block.bake ~operations:[op] b >>= fun res -> - Assert.proto_error ~loc:__LOC__ res (function - | Amendment.Unauthorized_ballot -> true - | _ -> false) - >>=? fun () -> - (* Allocate votes from weight (rolls) of active delegates *) - List.fold_left (fun acc v -> Int32.(add v acc)) 0l rolls_p2 - |> fun rolls_sum -> - (* # of Yay rolls in ballots matches votes of the delegates *) - Context.Vote.get_ballots (B b) >>=? fun v -> - Assert.equal - ~loc:__LOC__ - ballots_equal - "Unexpected ballots" - ballots_pp - v - Vote.{yay = rolls_sum; nay = 0l; pass = 0l} - >>=? fun () -> - (* One Yay ballot per delegate *) - (Context.Vote.get_ballot_list (B b) >>=? function - | [] -> failwith "%s - Unexpected empty ballot list" __LOC__ - | l -> - List.iter_es - (fun delegate -> - Context.Contract.pkh delegate >>=? fun pkh -> - match List.find_opt (fun (del, _) -> del = pkh) l with - | None -> failwith "%s - Missing delegate" __LOC__ - | Some (_, Vote.Yay) -> return_unit - | Some _ -> failwith "%s - Wrong ballot" __LOC__) - delegates_p2) - >>=? fun () -> - (* skip to cooldown period *) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_index:2l ~expected_kind:Cooldown b __LOC__ - >>=? fun () -> - (* no ballots in cooldown period *) - Context.Vote.get_ballots (B b) >>=? fun v -> - Assert.equal - ~loc:__LOC__ - ballots_equal - "Unexpected ballots" - ballots_pp - v - ballots_zero - >>=? fun () -> - (* listings must be populated in cooldown period before moving to promotion_vote period *) - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> - (* skip to promotion period *) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_kind:Promotion ~expected_index:3l b __LOC__ - >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> - (* period 3 *) - (* listings must be populated in promotion period *) - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> - (* beginning of promotion period, denoted by _p4; - take a snapshot of the active delegates and their rolls from listings *) - get_delegates_and_rolls_from_listings b >>=? fun (delegates_p4, rolls_p4) -> - (* no proposals during promotion period *) - Context.Vote.get_proposals (B b) >>=? fun ps -> - (if Environment.Protocol_hash.Map.is_empty ps then return_unit - else failwith "%s - Unexpected proposals" __LOC__) - >>=? fun () -> - (* current proposal must be set during promotion period *) - (Context.Vote.get_current_proposal (B b) >>=? function - | Some v -> - if Protocol_hash.(equal zero v) then return_unit - else failwith "%s - Wrong proposal" __LOC__ - | None -> failwith "%s - Missing proposal" __LOC__) - >>=? fun () -> - (* unanimous vote: all delegates --active when p4 started-- vote *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - delegates_p4 - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> - List.fold_left (fun acc v -> Int32.(add v acc)) 0l rolls_p4 - |> fun rolls_sum -> - (* # of Yays in ballots matches rolls of the delegate *) - Context.Vote.get_ballots (B b) >>=? fun v -> - Assert.equal - ~loc:__LOC__ - ballots_equal - "Unexpected ballots" - ballots_pp - v - Vote.{yay = rolls_sum; nay = 0l; pass = 0l} - >>=? fun () -> - (* One Yay ballot per delegate *) - (Context.Vote.get_ballot_list (B b) >>=? function - | [] -> failwith "%s - Unexpected empty ballot list" __LOC__ - | l -> - List.iter_es - (fun delegate -> - Context.Contract.pkh delegate >>=? fun pkh -> - match List.find_opt (fun (del, _) -> del = pkh) l with - | None -> failwith "%s - Missing delegate" __LOC__ - | Some (_, Vote.Yay) -> return_unit - | Some _ -> failwith "%s - Wrong ballot" __LOC__) - delegates_p4) - >>=? fun () -> - (* skip to end of promotion period and activation*) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_kind:Adoption ~expected_index:4l b __LOC__ - >>=? fun () -> - (* skip to end of Adoption period and bake 1 more to activate *) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_kind:Proposal ~expected_index:5l b __LOC__ - >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> - (* zero is the new protocol (before the vote this value is unset) *) - Context.Vote.get_protocol b >>= fun p -> - Assert.equal - ~loc:__LOC__ - Protocol_hash.equal - "Unexpected proposal" - Protocol_hash.pp - p - Protocol_hash.zero - >>=? fun () -> return_unit - -(* given a list of active delegates, - return the first k active delegates with which one can have quorum, that is: - their roll sum divided by the total roll sum is bigger than pr_ema_weight/den *) -let get_smallest_prefix_voters_for_quorum active_delegates active_rolls - participation_ema = - let expected_quorum = expected_qr_num participation_ema in - List.fold_left (fun acc v -> Int32.(add v acc)) 0l active_rolls - |> fun active_rolls_sum -> - let rec loop delegates rolls sum selected = - match (delegates, rolls) with - | ([], []) -> selected - | (del :: delegates, del_rolls :: rolls) -> - if - den * sum - < Float.to_int (expected_quorum *. Int32.to_float active_rolls_sum) - then - loop delegates rolls (sum + Int32.to_int del_rolls) (del :: selected) - else selected - | (_, _) -> [] - in - loop active_delegates active_rolls 0 [] - -let get_expected_participation_ema rolls voter_rolls old_participation_ema = - (* formula to compute the updated participation_ema *) - let get_updated_participation_ema old_participation_ema participation = - ((pr_ema_weight * Int32.to_int old_participation_ema) - + (pr_num * participation)) - / den - in - List.fold_left (fun acc v -> Int32.(add v acc)) 0l rolls |> fun rolls_sum -> - List.fold_left (fun acc v -> Int32.(add v acc)) 0l voter_rolls - |> fun voter_rolls_sum -> - let participation = - Int32.to_int voter_rolls_sum * percent_mul / Int32.to_int rolls_sum - in - get_updated_participation_ema old_participation_ema participation - -(** If not enough quorum - -- get_updated_participation_ema < pr_ema_weight/den -- - in exploration, go back to proposal period. *) -let test_not_enough_quorum_in_exploration num_delegates () = - let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates - >>=? fun (b, delegates) -> - (* proposal period *) - let open Alpha_context in - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> - let proposer = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 - in - Op.proposals (B b) proposer [Protocol_hash.zero] >>=? fun ops -> - Block.bake ~operations:[ops] b >>=? fun b -> - (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* we moved to an exploration period with one proposal *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> - Context.Vote.get_participation_ema b >>=? fun initial_participation_ema -> - (* beginning of exploration period, denoted by _p2; - take a snapshot of the active delegates and their rolls from listings *) - get_delegates_and_rolls_from_listings b >>=? fun (delegates_p2, rolls_p2) -> - Context.Vote.get_participation_ema b >>=? fun participation_ema -> - get_smallest_prefix_voters_for_quorum delegates_p2 rolls_p2 participation_ema - |> fun voters -> - (* take the first two voters out so there cannot be quorum *) - let voters_without_quorum = - WithExceptions.Option.get ~loc:__LOC__ @@ List.tl voters - in - get_rolls b voters_without_quorum __LOC__ - >>=? fun voters_rolls_in_exploration -> - (* all voters_without_quorum vote, for yays; - no nays, so supermajority is satisfied *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - voters_without_quorum - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> - (* bake to next period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* we move back to the proposal period because not enough quorum *) - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> - (* check participation_ema update *) - get_expected_participation_ema - rolls_p2 - voters_rolls_in_exploration - initial_participation_ema - |> fun expected_participation_ema -> - Context.Vote.get_participation_ema b >>=? fun new_participation_ema -> - (* assert the formula to calculate participation_ema is correct *) - Assert.equal_int - ~loc:__LOC__ - expected_participation_ema - (Int32.to_int new_participation_ema) - >>=? fun () -> return_unit - -(** If not enough quorum - -- get_updated_participation_ema < pr_ema_weight/den -- - In promotion period, go back to proposal period. *) -let test_not_enough_quorum_in_promotion num_delegates () = - let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates - >>=? fun (b, delegates) -> - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> - let proposer = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 - in - Op.proposals (B b) proposer [Protocol_hash.zero] >>=? fun ops -> - Block.bake ~operations:[ops] b >>=? fun b -> - (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* we moved to an exploration period with one proposal *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> - (* beginning of exploration period, denoted by _p2; - take a snapshot of the active delegates and their rolls from listings *) - get_delegates_and_rolls_from_listings b >>=? fun (delegates_p2, rolls_p2) -> - Context.Vote.get_participation_ema b >>=? fun participation_ema -> - get_smallest_prefix_voters_for_quorum delegates_p2 rolls_p2 participation_ema - |> fun voters -> - let open Alpha_context in - (* all voters vote, for yays; - no nays, so supermajority is satisfied *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - voters - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> - (* skip to first block cooldown period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* we move to cooldown because we have supermajority and enough quorum *) - assert_period ~expected_kind:Cooldown b __LOC__ >>=? fun () -> - (* skip to first block of promotion period *) - bake_until_first_block_of_next_period b >>=? fun b -> - assert_period ~expected_kind:Promotion b __LOC__ - (* bake_until_first_block_of_next_period ~offset:1l b - * >>=? fun b -> - * assert_period ~expected_kind:Promotion b __LOC__ *) - >>=? - fun () -> - Context.Vote.get_participation_ema b >>=? fun initial_participation_ema -> - (* beginning of promotion period, denoted by _p4; - take a snapshot of the active delegates and their rolls from listings *) - get_delegates_and_rolls_from_listings b >>=? fun (delegates_p4, rolls_p4) -> - Context.Vote.get_participation_ema b >>=? fun participation_ema -> - get_smallest_prefix_voters_for_quorum delegates_p4 rolls_p4 participation_ema - |> fun voters -> - (* take the first voter out so there cannot be quorum *) - let voters_without_quorum = - WithExceptions.Option.get ~loc:__LOC__ @@ List.tl voters - in - get_rolls b voters_without_quorum __LOC__ >>=? fun voter_rolls -> - (* all voters_without_quorum vote, for yays; - no nays, so supermajority is satisfied *) - List.map_es - (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) - voters_without_quorum - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> - (* skip to end of promotion period *) - bake_until_first_block_of_next_period b >>=? fun b -> - get_expected_participation_ema rolls_p4 voter_rolls initial_participation_ema - |> fun expected_participation_ema -> - Context.Vote.get_participation_ema b >>=? fun new_participation_ema -> - (* assert the formula to calculate participation_ema is correct *) - Assert.equal_int - ~loc:__LOC__ - expected_participation_ema - (Int32.to_int new_participation_ema) - >>=? fun () -> - (* we move back to the proposal period because not enough quorum *) - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> - assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> return_unit - -(** Identical proposals (identified by their hash) must be counted as - one. *) -let test_multiple_identical_proposals_count_as_one () = - Context.init 1 >>=? fun (b, delegates) -> - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> - let proposer = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd delegates in - Op.proposals (B b) proposer [Protocol_hash.zero; Protocol_hash.zero] - >>=? fun ops -> - Block.bake ~operations:[ops] b >>=? fun b -> - (* compute the weight of proposals *) - Context.Vote.get_proposals (B b) >>=? fun ps -> - (* compute the rolls of proposer *) - Context.Contract.pkh proposer >>=? fun pkh -> - Context.Vote.get_listings (B b) >>=? fun l -> - (match List.find_opt (fun (del, _) -> del = pkh) l with - | None -> failwith "%s - Missing delegate" __LOC__ - | Some (_, proposer_rolls) -> return proposer_rolls) - >>=? fun proposer_rolls -> - (* correctly count the double proposal for zero as one proposal *) - let expected_weight_proposer = proposer_rolls in - match Environment.Protocol_hash.(Map.find zero ps) with - | Some v -> - if v = expected_weight_proposer then return_unit - else - failwith - "%s - Wrong count %ld is not %ld; identical proposals count as one" - __LOC__ - v - expected_weight_proposer - | None -> failwith "%s - Missing proposal" __LOC__ - -(** Assume the initial balance of allocated by Context.init is at - least 4 times the value of the tokens_per_roll constant. *) -let test_supermajority_in_proposal there_is_a_winner () = - let min_proposal_quorum = 0l in - Context.init - ~consensus_threshold:0 - ~min_proposal_quorum - ~initial_balances:[1L; 1L; 1L] - 10 - >>=? fun (b, delegates) -> - Context.get_constants (B b) - >>=? fun { - parametric = - {blocks_per_cycle; tokens_per_roll; blocks_per_voting_period; _}; - _; - } -> - let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in - let del2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 1 in - let del3 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 2 in - List.map_es (fun del -> Context.Contract.pkh del) [del1; del2; del3] - >>=? fun pkhs -> - let policy = Block.Excluding pkhs in - Op.transaction - (B b) - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 3) - del1 - tokens_per_roll - >>=? fun op1 -> - Op.transaction - (B b) - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 4) - del2 - tokens_per_roll - >>=? fun op2 -> - (if there_is_a_winner then Test_tez.( *? ) tokens_per_roll 3L - else Test_tez.( *? ) tokens_per_roll 2L) - >>?= fun bal3 -> - Op.transaction - (B b) - (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 5) - del3 - bal3 - >>=? fun op3 -> - Block.bake ~policy ~operations:[op1; op2; op3] b >>=? fun b -> - (* we let one voting period pass; we make sure that: - - the three selected delegates remain active by re-registering as delegates - - their number of rolls do not change *) - List.fold_left_es - (fun b _ -> - List.map_es - (fun del -> - Context.Contract.pkh del >>=? fun pkh -> - Op.delegation (B b) del (Some pkh)) - delegates - >>=? fun ops -> - Block.bake ~policy ~operations:ops b >>=? fun b -> - Block.bake_until_cycle_end ~policy b) - b - (1 -- Int32.to_int (Int32.div blocks_per_voting_period blocks_per_cycle)) - >>=? fun b -> - (* make the proposals *) - Op.proposals (B b) del1 [protos.(0)] >>=? fun ops1 -> - Op.proposals (B b) del2 [protos.(0)] >>=? fun ops2 -> - Op.proposals (B b) del3 [protos.(1)] >>=? fun ops3 -> - Block.bake ~policy ~operations:[ops1; ops2; ops3] b >>=? fun b -> - bake_until_first_block_of_next_period b >>=? fun b -> - (* we remain in the proposal period when there is no winner, - otherwise we move to the exploration period *) - (if there_is_a_winner then assert_period ~expected_kind:Exploration b __LOC__ - else assert_period ~expected_kind:Proposal b __LOC__) - >>=? fun () -> return_unit - -(** After one voting period, if [has_quorum] then the period kind must - have been the cooldown vote. Otherwise, it should have remained in - place in the proposal period. *) -let test_quorum_in_proposal has_quorum () = - let total_tokens = 32_000_000_000_000L in - let half_tokens = Int64.div total_tokens 2L in - Context.init - ~consensus_threshold:0 - ~initial_balances:[1L; half_tokens; half_tokens] - 3 - >>=? fun (b, delegates) -> - Context.get_constants (B b) - >>=? fun { - parametric = - { - blocks_per_cycle; - min_proposal_quorum; - blocks_per_voting_period; - _; - }; - _; - } -> - let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in - let del2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 1 in - List.map_es (fun del -> Context.Contract.pkh del) [del1; del2] - >>=? fun pkhs -> - let policy = Block.Excluding pkhs in - let quorum = - if has_quorum then Int64.of_int32 min_proposal_quorum - else Int64.(sub (of_int32 min_proposal_quorum) 10L) - in - let bal = - Int64.(div (mul total_tokens quorum) 100_00L) |> Test_tez.of_mutez_exn - in - Op.transaction (B b) del2 del1 bal >>=? fun op2 -> - Block.bake ~policy ~operations:[op2] b >>=? fun b -> - (* we let one voting period pass; we make sure that: - - the two selected delegates remain active by re-registering as delegates - - their number of rolls do not change *) - List.fold_left_es - (fun b _ -> - List.map_es - (fun del -> - Context.Contract.pkh del >>=? fun pkh -> - Op.delegation (B b) del (Some pkh)) - [del1; del2] - >>=? fun ops -> - Block.bake ~policy ~operations:ops b >>=? fun b -> - Block.bake_until_cycle_end ~policy b) - b - (1 -- Int32.to_int (Int32.div blocks_per_voting_period blocks_per_cycle)) - >>=? fun b -> - (* make the proposal *) - Op.proposals (B b) del1 [protos.(0)] >>=? fun ops -> - Block.bake ~policy ~operations:[ops] b >>=? fun b -> - bake_until_first_block_of_next_period b >>=? fun b -> - (* we remain in the proposal period when there is no quorum, - otherwise we move to the cooldown vote period *) - (if has_quorum then assert_period ~expected_kind:Exploration b __LOC__ - else assert_period ~expected_kind:Proposal b __LOC__) - >>=? fun () -> return_unit - -(** If a supermajority is reached, then the voting period must be - reached. Otherwise, it remains in proposal period. *) -let test_supermajority_in_exploration supermajority () = - let min_proposal_quorum = Int32.(of_int @@ (100_00 / 100)) in - Context.init ~consensus_threshold:0 ~min_proposal_quorum 100 - >>=? fun (b, delegates) -> - let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in - let proposal = protos.(0) in - Op.proposals (B b) del1 [proposal] >>=? fun ops1 -> - Block.bake ~operations:[ops1] b >>=? fun b -> - bake_until_first_block_of_next_period b >>=? fun b -> - (* move to exploration *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> - (* assert our proposal won *) - (Context.Vote.get_current_proposal (B b) >>=? function - | Some v -> - if Protocol_hash.(equal proposal v) then return_unit - else failwith "%s - Wrong proposal" __LOC__ - | None -> failwith "%s - Missing proposal" __LOC__) - >>=? fun () -> - (* beginning of exploration period, denoted by _p2; - take a snapshot of the active delegates and their rolls from listings *) - get_delegates_and_rolls_from_listings b >>=? fun (delegates_p2, _rolls_p2) -> - (* supermajority means [num_yays / (num_yays + num_nays) >= s_num / s_den], - which is equivalent with [num_yays >= num_nays * s_num / (s_den - s_num)] *) - let num_delegates = List.length delegates_p2 in - let num_nays = num_delegates / 5 in - (* any smaller number will do as well *) - let num_yays = num_nays * s_num / (s_den - s_num) in - (* majority/minority vote depending on the [supermajority] parameter *) - let num_yays = if supermajority then num_yays else num_yays - 1 in - let open Alpha_context in - let (nays_delegates, rest) = List.split_n num_nays delegates_p2 in - let (yays_delegates, _) = List.split_n num_yays rest in - List.map_es (fun del -> Op.ballot (B b) del proposal Vote.Yay) yays_delegates - >>=? fun operations_yays -> - List.map_es (fun del -> Op.ballot (B b) del proposal Vote.Nay) nays_delegates - >>=? fun operations_nays -> - let operations = operations_yays @ operations_nays in - Block.bake ~operations b >>=? fun b -> - bake_until_first_block_of_next_period b >>=? fun b -> - (if supermajority then assert_period ~expected_kind:Cooldown b __LOC__ - else assert_period ~expected_kind:Proposal b __LOC__) - >>=? fun () -> return_unit - -(** Test also how the selection scales: all delegates propose max - proposals. *) -let test_no_winning_proposal num_delegates () = - let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates - >>=? fun (b, _) -> - (* beginning of proposal, denoted by _p1; - take a snapshot of the active delegates and their rolls from listings *) - get_delegates_and_rolls_from_listings b >>=? fun (delegates_p1, _rolls_p1) -> - let open Alpha_context in - let props = - List.map (fun i -> protos.(i)) (1 -- Constants.max_proposals_per_delegate) - in - (* all delegates active in p1 propose the same proposals *) - List.map_es (fun del -> Op.proposals (B b) del props) delegates_p1 - >>=? fun ops_list -> - Block.bake ~operations:ops_list b >>=? fun b -> - (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* we stay in the same proposal period because no winning proposal *) - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> return_unit - -(** Vote to pass with maximum possible participation_ema (100%), it is - sufficient for the vote quorum to be equal or greater than the - maximum quorum cap. *) -let test_quorum_capped_maximum num_delegates () = - let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates - >>=? fun (b, delegates) -> - (* set the participation EMA to 100% *) - Context.Vote.set_participation_ema b 100_00l >>= fun b -> - Context.get_constants (B b) >>=? fun {parametric = {quorum_max; _}; _} -> - (* proposal period *) - let open Alpha_context in - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> - (* propose a new protocol *) - let protocol = Protocol_hash.zero in - let proposer = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 - in - Op.proposals (B b) proposer [protocol] >>=? fun ops -> - Block.bake ~operations:[ops] b >>=? fun b -> - (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* we moved to an exploration period with one proposal *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> - (* take percentage of the delegates equal or greater than quorum_max *) - let minimum_to_pass = - Float.of_int (List.length delegates) - *. Int32.(to_float quorum_max) - /. 100_00. - |> Float.ceil |> Float.to_int - in - let voters = List.take_n minimum_to_pass delegates in - (* all voters vote for yays; no nays, so supermajority is satisfied *) - List.map_es (fun del -> Op.ballot (B b) del protocol Vote.Yay) voters - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> - (* skip to next period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* expect to move to cooldown because we have supermajority and enough quorum *) - assert_period ~expected_kind:Cooldown b __LOC__ - -(** Vote to pass with minimum possible participation_ema (0%), it is - sufficient for the vote quorum to be equal or greater than the - minimum quorum cap. *) -let test_quorum_capped_minimum num_delegates () = - let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in - Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates - >>=? fun (b, delegates) -> - (* set the participation EMA to 0% *) - Context.Vote.set_participation_ema b 0l >>= fun b -> - Context.get_constants (B b) >>=? fun {parametric = {quorum_min; _}; _} -> - (* proposal period *) - let open Alpha_context in - assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> - (* propose a new protocol *) - let protocol = Protocol_hash.zero in - let proposer = - WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 - in - Op.proposals (B b) proposer [protocol] >>=? fun ops -> - Block.bake ~operations:[ops] b >>=? fun b -> - (* skip to exploration period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* we moved to an exploration period with one proposal *) - assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> - (* take percentage of the delegates equal or greater than quorum_min *) - let minimum_to_pass = - Float.of_int (List.length delegates) - *. Int32.(to_float quorum_min) - /. 100_00. - |> Float.ceil |> Float.to_int - in - let voters = List.take_n minimum_to_pass delegates in - (* all voters vote for yays; no nays, so supermajority is satisfied *) - List.map_es (fun del -> Op.ballot (B b) del protocol Vote.Yay) voters - >>=? fun operations -> - Block.bake ~operations b >>=? fun b -> - (* skip to next period *) - bake_until_first_block_of_next_period b >>=? fun b -> - (* expect to move to cooldown because we have supermajority and enough quorum *) - assert_period ~expected_kind:Cooldown b __LOC__ - -(* gets the voting power *) -let get_voting_power block pkhash = - let ctxt = Context.B block in - Context.get_voting_power ctxt pkhash - -(** Test that the voting power changes if the balance between bakers changes - and the blockchain moves to the next voting period. It also checks that - the total voting power coincides with the addition of the voting powers - of bakers *) -let test_voting_power_updated_each_voting_period () = - let init_bal1 = 80_000_000_000L in - let init_bal2 = 48_000_000_000L in - let init_bal3 = 40_000_000_000L in - (* Create three accounts with different amounts *) - Context.init - ~consensus_threshold:0 - ~initial_balances:[init_bal1; init_bal2; init_bal3] - 3 - >>=? fun (genesis, contracts) -> - Context.get_constants (B genesis) - >>=? fun {parametric = {tokens_per_roll; _}; _} -> - let con1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in - let con2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 in - let con3 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 2 in - (* Get the key hashes of the bakers *) - Context.Contract.pkh con1 >>=? fun baker1 -> - Context.Contract.pkh con2 >>=? fun baker2 -> - Context.Contract.pkh con3 >>=? fun baker3 -> - (* Retrieve balance of con1 *) - let open Test_tez in - Context.Contract.balance (B genesis) con1 >>=? fun balance1 -> - Context.Delegate.current_frozen_deposits (B genesis) baker1 - >>=? fun frozen_deposits1 -> - balance1 +? frozen_deposits1 >>?= fun full_balance1 -> - Assert.equal_tez ~loc:__LOC__ full_balance1 (of_mutez_exn init_bal1) - >>=? fun () -> - (* Retrieve balance of con2 *) - Context.Contract.balance (B genesis) con2 >>=? fun balance2 -> - Context.Delegate.current_frozen_deposits (B genesis) baker2 - >>=? fun frozen_deposits2 -> - balance2 +? frozen_deposits2 >>?= fun full_balance2 -> - Assert.equal_tez ~loc:__LOC__ full_balance2 (of_mutez_exn init_bal2) - >>=? fun () -> - (* Retrieve balance of con3 *) - Context.Contract.balance (B genesis) con3 >>=? fun balance3 -> - Context.Delegate.current_frozen_deposits (B genesis) baker3 - >>=? fun frozen_deposits3 -> - balance3 +? frozen_deposits3 >>?= fun full_balance3 -> - Assert.equal_tez ~loc:__LOC__ full_balance3 (of_mutez_exn init_bal3) - >>=? fun () -> - (* Auxiliary assert_voting_power *) - let assert_voting_power ~loc n block baker = - get_voting_power block baker >>=? fun voting_power -> - Assert.equal_int ~loc n (Int32.to_int voting_power) - in - (* Auxiliary assert_total_voting_power *) - let assert_total_voting_power ~loc n block = - Context.get_total_voting_power (B block) >>=? fun total_voting_power -> - Assert.equal_int ~loc n (Int32.to_int total_voting_power) - in - (* Assert voting power is equal to the balance divided by tokens_per_roll *) - let expected_power_of_baker_1 = - Int64.(to_int (div (to_mutez full_balance1) (to_mutez tokens_per_roll))) - in - assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 genesis baker1 - >>=? fun () -> - (* Assert voting power is equal to the balance divided by tokens_per_roll *) - let expected_power_of_baker_2 = - Int64.(to_int (div (to_mutez full_balance2) (to_mutez tokens_per_roll))) - in - assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 genesis baker2 - >>=? fun () -> - (* Assert total voting power *) - let expected_power_of_baker_3 = - Int64.(to_int (div (to_mutez full_balance3) (to_mutez tokens_per_roll))) - in - assert_total_voting_power - ~loc:__LOC__ - Int.( - add - (add expected_power_of_baker_1 expected_power_of_baker_2) - expected_power_of_baker_3) - genesis - >>=? fun () -> - (* Create policy that excludes baker1 and baker2 from baking *) - let policy = Block.Excluding [baker1; baker2] in - (* Transfer tokens_per_roll * num_rolls from baker1 to baker2 *) - let num_rolls = 5L in - tokens_per_roll *? num_rolls >>?= fun amount -> - Op.transaction (B genesis) con1 con2 amount >>=? fun op -> - (* Bake the block containing the transaction *) - Block.bake ~policy ~operations:[op] genesis >>=? fun block -> - (* Retrieve balance of con1 *) - Context.Contract.balance (B block) con1 >>=? fun balance1 -> - (* Assert balance has changed by deducing the amount *) - of_mutez_exn init_bal1 -? amount >>?= fun balance1_after_deducing_amount -> - Context.Delegate.current_frozen_deposits (B block) baker1 - >>=? fun frozen_deposit1 -> - balance1_after_deducing_amount -? frozen_deposit1 - >>?= Assert.equal_tez ~loc:__LOC__ balance1 - >>=? fun () -> - (* Retrieve balance of con2 *) - Context.Contract.balance (B block) con2 >>=? fun balance2 -> - (* Assert balance has changed by adding amount *) - of_mutez_exn init_bal2 +? amount >>?= fun balance2_after_adding_amount -> - Context.Delegate.current_frozen_deposits (B block) baker2 - >>=? fun frozen_deposit2 -> - balance2_after_adding_amount -? frozen_deposit2 - >>?= Assert.equal_tez ~loc:__LOC__ balance2 - >>=? fun () -> - Block.bake ~policy block >>=? fun block -> - (* Assert voting power (and total) remains the same before next voting period *) - assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 block baker1 - >>=? fun () -> - assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 block baker2 - >>=? fun () -> - assert_voting_power ~loc:__LOC__ expected_power_of_baker_3 block baker3 - >>=? fun () -> - assert_total_voting_power - ~loc:__LOC__ - Int.( - add - (add expected_power_of_baker_1 expected_power_of_baker_2) - expected_power_of_baker_3) - block - >>=? fun () -> - bake_until_first_block_of_next_period block >>=? fun block -> - (* Assert voting power of baker1 has decreased by num_rolls *) - let expected_power_of_baker_1 = - Int.sub expected_power_of_baker_1 (Int64.to_int num_rolls) - in - assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 block baker1 - >>=? fun _ -> - (* Assert voting power of baker2 has increased by num_rolls *) - let expected_power_of_baker_2 = - Int.add expected_power_of_baker_2 (Int64.to_int num_rolls) - in - assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 block baker2 - >>=? fun _ -> - (* Retrieve voting power of baker3 *) - get_voting_power block baker3 >>=? fun power -> - let power_of_baker_3 = Int32.to_int power in - (* Assert total voting power *) - assert_total_voting_power - ~loc:__LOC__ - Int.( - add - (add expected_power_of_baker_1 expected_power_of_baker_2) - power_of_baker_3) - block - -let test_voting_period_pp () = - let vp = - Voting_period_repr. - { - index = Int32.of_int 123; - kind = Proposal; - start_position = Int32.of_int 321; - } - in - Assert.equal - ~loc:__LOC__ - ( = ) - "Unexpected pretty printing of voting period" - Format.pp_print_string - (Format.asprintf "%a" Voting_period_repr.pp vp) - "index: 123, kind:proposal, start_position: 321" - -let tests = - [ - Tztest.tztest "voting successful_vote" `Quick (test_successful_vote 137); - Tztest.tztest - "voting cooldown, not enough quorum" - `Quick - (test_not_enough_quorum_in_exploration 245); - Tztest.tztest - "voting promotion, not enough quorum" - `Quick - (test_not_enough_quorum_in_promotion 432); - Tztest.tztest - "voting counting double proposal" - `Quick - test_multiple_identical_proposals_count_as_one; - Tztest.tztest - "voting proposal, with supermajority" - `Quick - (test_supermajority_in_proposal true); - Tztest.tztest - "voting proposal, without supermajority" - `Quick - (test_supermajority_in_proposal false); - Tztest.tztest - "voting proposal, with quorum" - `Quick - (test_quorum_in_proposal true); - Tztest.tztest - "voting proposal, without quorum" - `Quick - (test_quorum_in_proposal false); - Tztest.tztest - "voting cooldown, with supermajority" - `Quick - (test_supermajority_in_exploration true); - Tztest.tztest - "voting cooldown, without supermajority" - `Quick - (test_supermajority_in_exploration false); - Tztest.tztest - "voting proposal, no winning proposal" - `Quick - (test_no_winning_proposal 400); - Tztest.tztest - "voting quorum, quorum capped maximum" - `Quick - (test_quorum_capped_maximum 400); - Tztest.tztest - "voting quorum, quorum capped minimum" - `Quick - (test_quorum_capped_minimum 401); - Tztest.tztest - "voting power updated in each voting period" - `Quick - test_voting_power_updated_each_voting_period; - Tztest.tztest "voting period pretty print" `Quick test_voting_period_pp; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/unit/.ocamlformat b/src/proto_012_Psithaca/lib_protocol/test/unit/.ocamlformat deleted file mode 100644 index 5e1158919e85..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/unit/.ocamlformat +++ /dev/null @@ -1,17 +0,0 @@ -version=0.18.0 -wrap-fun-args=false -let-binding-spacing=compact -field-space=loose -break-separators=after -space-around-arrays=false -space-around-lists=false -space-around-records=false -space-around-variants=false -dock-collection-brackets=true -space-around-records=false -sequence-style=separator -doc-comments=before -margin=80 -module-item-spacing=sparse -parens-tuple=always -parens-tuple-patterns=always diff --git a/src/proto_012_Psithaca/lib_protocol/test/unit/dune b/src/proto_012_Psithaca/lib_protocol/test/unit/dune deleted file mode 100644 index 096fe8c7229e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/unit/dune +++ /dev/null @@ -1,20 +0,0 @@ -(test - (name main) - (package tezos-protocol-012-Psithaca-tests) - (libraries tezos-base - tezos-micheline - tezos-protocol-environment - alcotest-lwt - tezos-012-Psithaca-test-helpers - tezos-stdlib-unix - tezos-client-base - tezos-protocol-012-Psithaca-parameters - tezos-base-test-helpers) - (flags (:standard -open Tezos_base__TzPervasives - -open Tezos_base_test_helpers - -open Tezos_micheline - -open Tezos_client_012_Psithaca - -open Tezos_protocol_012_Psithaca - -open Tezos_protocol_environment_012_Psithaca - -open Tezos_012_Psithaca_test_helpers)) - (action (run %{test} "test" "Unit"))) diff --git a/src/proto_012_Psithaca/lib_protocol/test/unit/main.ml b/src/proto_012_Psithaca/lib_protocol/test/unit/main.ml deleted file mode 100644 index 22795576e715..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/unit/main.ml +++ /dev/null @@ -1,60 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) -module Unit_test : sig - (** - * Example: [spec "Alpha_context.ml" Test_alpha_context.test_cases] - * Unit tests needs tag in log (like "[UNIT] some test description here...") - * This function handles such meta data *) - val spec : - string -> - unit Alcotest_lwt.test_case list -> - string * unit Alcotest_lwt.test_case list - - (** Tests with description string without [Unit] are skipped *) - val skip : - string -> - unit Alcotest_lwt.test_case list -> - string * unit Alcotest_lwt.test_case list -end = struct - let spec unit_name test_cases = ("[Unit] " ^ unit_name, test_cases) - - let skip unit_name test_cases = ("[SKIPPED] " ^ unit_name, test_cases) -end - -let () = - Alcotest_lwt.run - "protocol_012_Psithaca unit tests" - [ - Unit_test.spec "Alpha_context.ml" Test_alpha_context.tests; - Unit_test.spec "Raw_level_repr.ml" Test_raw_level_repr.tests; - Unit_test.skip "Raw_level_repr.ml" Test_raw_level_repr.skipped_tests; - Unit_test.spec "Tez_repr.ml" Test_tez_repr.tests; - Unit_test.spec "Contract_repr.ml" Test_contract_repr.tests; - Unit_test.spec "Operation_repr.ml" Test_operation_repr.tests; - Unit_test.spec - "Global_constants_storage.ml" - Test_global_constants_storage.tests; - ] - |> Lwt_main.run diff --git a/src/proto_012_Psithaca/lib_protocol/test/unit/test_alpha_context.ml b/src/proto_012_Psithaca/lib_protocol/test/unit/test_alpha_context.ml deleted file mode 100644 index ef7f84ba9a0e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/unit/test_alpha_context.ml +++ /dev/null @@ -1,129 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Alpha_context - -(** Testing - ------- - Component: Alpha_context - Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe -- test Alpha_context - Dependencies: helpers/block.ml - Subject: To test the modules (including the top-level) - in alpha_context.ml as individual units, particularly - failure cases. Superficial goal: increase coverage percentage. -*) - -(** Creates an Alpha_context without creating a full-fledged block *) -let create () = - let accounts = Account.generate_accounts 1 in - Block.alpha_context accounts - -module Test_Script = struct - (** Force serialise of lazy [Big_map.t] in a given [alpha_context] *) - let test_force_bytes_in_context () = - create () >>=? fun alpha_context -> - let mbytes_pp ppf t = - Format.pp_print_string ppf (Environment.Bytes.to_string t) - in - let open Alpha_context.Script in - Environment.wrap_tzresult - @@ force_bytes_in_context alpha_context - @@ lazy_expr @@ Micheline.strip_locations - @@ Prim (0, D_Unit, [], []) - >>?= fun (bytes, _) -> - Assert.equal - ~loc:__LOC__ - Environment.Bytes.equal - "script serialised incorrectly" - mbytes_pp - bytes - (`Hex "030b" |> Hex.to_bytes_exn) -end - -module Test_Big_map = struct - (** Test failure path: look for a non-existent key in a [Big_map] *) - let test_mem () = - ( create () >>=? fun alpha_context -> - Big_map.fresh ~temporary:true alpha_context >|= Environment.wrap_tzresult - >>=? fun (alpha_context, big_map_id) -> - Big_map.mem - alpha_context - big_map_id - (Script_expr_hash.hash_string ["0"; "0"]) - >|= Environment.wrap_tzresult ) - >>=? fun (_alpha_context, is_member) -> - Assert.equal_bool ~loc:__LOC__ is_member false - - (** Test failure code path of [get_opt] by looking for missing key in a [Big_map.t] *) - let test_get_opt () = - ( create () >>=? fun alpha_context -> - Big_map.fresh ~temporary:true alpha_context >|= Environment.wrap_tzresult - >>=? fun (alpha_context, big_map_id) -> - Big_map.get_opt - alpha_context - big_map_id - (Script_expr_hash.hash_string ["0"; "0"]) - >|= Environment.wrap_tzresult ) - >>=? fun (_alpha_context, value) -> - match value with - | Some _ -> - failwith "get_opt should have failed looking for a non-existent key" - | None -> return_unit - - (** Test existence of a non-existent [Big_map] in an [Alpha_context.t] *) - let test_exists () = - ( create () >>=? fun alpha_context -> - Big_map.fresh ~temporary:true alpha_context >|= Environment.wrap_tzresult - >>=? fun (alpha_context, big_map_id) -> - Big_map.exists alpha_context big_map_id >|= Environment.wrap_tzresult ) - >>=? fun (_alpha_context, value) -> - match value with - | Some _ -> - failwith "exists should have failed looking for a non-existent big_map" - | None -> return_unit -end - -let tests = - [ - Tztest.tztest - "Script.force_bytes_in_context: checks if it serialises a simple \ - michelson expression" - `Quick - Test_Script.test_force_bytes_in_context; - Tztest.tztest - "Big_map.mem: failure case - must return false when starting with an \ - empty map" - `Quick - Test_Big_map.test_mem; - Tztest.tztest - "Big_map.get_opt: failure case - looking up key that doesn't exist" - `Quick - Test_Big_map.test_get_opt; - Tztest.tztest - "Big_map.exists: failure case - looking up big_map that doesn't exist" - `Quick - Test_Big_map.test_exists; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/unit/test_contract_repr.ml b/src/proto_012_Psithaca/lib_protocol/test/unit/test_contract_repr.ml deleted file mode 100644 index 7ecff1016d63..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/unit/test_contract_repr.ml +++ /dev/null @@ -1,161 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Contract_repr - Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe -- test Contract_repr - Dependencies: contract_hash.ml - Subject: To test the modules (including the top-level) - in contract_repr.ml as individual units, particularly - failure cases. Superficial goal: increase coverage percentage. -*) -open Protocol - -open Tztest - -(* - - TODO: Remove dependence on contract_hash.ml and mock it - - *) - -module Test_contract_repr = struct - (** Assert if [is_implicit] correctly returns the implicit contract *) - open Contract_repr - - let dummy_operation_hash = - Operation_hash.of_bytes_exn - (Bytes.of_string "test-operation-hash-of-length-32") - - let dummy_origination_nonce = initial_origination_nonce dummy_operation_hash - - let dummy_contract_hash = - (* WARNING: Uses Contract_repr itself, which is yet to be tested. This happened because Contract_hash wasn't mocked *) - let data = - Data_encoding.Binary.to_bytes_exn - Contract_repr.origination_nonce_encoding - dummy_origination_nonce - in - Contract_hash.hash_bytes [data] - - let dummy_implicit_contract = implicit_contract Signature.Public_key_hash.zero - - let dummy_originated_contract = originated_contract @@ dummy_origination_nonce - - let test_implicit () = - match is_implicit dummy_implicit_contract with - | Some _ -> return_unit - | None -> - failwith - "must have returned the public key hash of implicit contract. \n\ - \ Instead, returned None" - - (** Check if [is_implicit] catches a non-implicit (originated) contract and returns None *) - let test_not_implicit () = - match is_implicit dummy_originated_contract with - | None -> return_unit - | Some _ -> failwith "must have returned the None. Instead, returned Some _" - - let test_originated () = - match is_originated dummy_originated_contract with - | Some _ -> return_unit - | None -> - failwith - "must have returned the origination nonce correctly. Instead \ - returned None." - - let test_not_originated () = - match is_originated dummy_implicit_contract with - | None -> return_unit - | Some _ -> failwith "must have returned the None. Instead, returned Some _" - - let test_to_b58check_implicit () = - Assert.equal - ~loc:__LOC__ - String.equal - "%s should have been equal to %" - Format.pp_print_string - (to_b58check dummy_implicit_contract) - Signature.Public_key_hash.(to_b58check zero) - - let test_to_b58check_originated () = - Assert.equal - ~loc:__LOC__ - String.equal - "%s should have been equal to %" - Format.pp_print_string - (to_b58check dummy_originated_contract) - Contract_hash.(to_b58check @@ dummy_contract_hash) - - let test_originated_contracts_basic () = - let since = dummy_origination_nonce in - let rec incr_n_times nonce = function - | 0 -> nonce - | n -> incr_n_times (Contract_repr.incr_origination_nonce nonce) (n - 1) - in - let until = incr_n_times since 5 in - let contracts = originated_contracts ~since ~until in - Assert.equal_int ~loc:__LOC__ (List.length contracts) 5 -end - -let tests = - [ - tztest - "Contract_repr.is_implicit: must correctly identify a valid implicit \ - contract" - `Quick - Test_contract_repr.test_implicit; - tztest - "Contract_repr.is_implicit: must correctly return None for a originated \ - contract" - `Quick - Test_contract_repr.test_not_implicit; - tztest - "Contract_repr.is_originated: must correctly return operation hash of \ - the originated contract" - `Quick - Test_contract_repr.test_originated; - tztest - "Contract_repr.is_originated: must correctly return None for an implicit \ - contract contract" - `Quick - Test_contract_repr.test_not_originated; - tztest - "Contract_repr.to_b58check: must correctly stringify, b58check encoded, \ - an implicit contract" - `Quick - Test_contract_repr.test_to_b58check_implicit; - tztest - "Contract_repr.originated_contract: must correctly create an originated \ - contract" - `Quick - Test_contract_repr.test_originated_contracts_basic; - tztest - "Contract_repr.to_b58check: must correctly stringify, b58check encoded, \ - an originated contract" - `Quick - Test_contract_repr.test_to_b58check_originated; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/unit/test_global_constants_storage.ml b/src/proto_012_Psithaca/lib_protocol/test/unit/test_global_constants_storage.ml deleted file mode 100644 index 454127b5e679..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/unit/test_global_constants_storage.ml +++ /dev/null @@ -1,413 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Global table of constants - Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe \ - -- test Global_constants_storage - Dependencies: contract_hash.ml - Subject: Test the global table of constants -*) - -open Protocol -open Alpha_context -open Tztest -open Micheline -open QCheck -open Lib_test.Qcheck_helpers -open Michelson_v1_primitives -open Michelson_v1_printer -open Test_global_constants - -(** [get] on a nonexistent global constant - returns an error. *) -let test_get_on_nonexistent_fails = - tztest_qcheck - ~name:"get on a nonexistent global constants fails" - (pair - (Generators.context_arbitrary ()) - (Generators.canonical_without_constant_arbitrary ())) - (fun (context, expr) -> - expr_to_hash expr |> Environment.wrap_tzresult >>?= fun hash -> - Global_constants_storage.get context hash - >|= Environment.wrap_tzresult - >>= assert_proto_error_id __LOC__ "Nonexistent_global") - -(** If registering an expression yields a hash [h] and context [c], - then [get c h] should yield the original expression. *) -let test_get_always_returns_registered_expr = - tztest_qcheck - ~name:"get always returned the registered constant" - (pair - (Generators.context_arbitrary ()) - (Generators.canonical_without_constant_arbitrary ())) - (fun (context, expr) -> - Global_constants_storage.register context expr - >|= Environment.wrap_tzresult - >>=? fun (context, hash, _cost) -> - Global_constants_storage.get context hash >|= Environment.wrap_tzresult - >|=? fun (_context, actual_expr) -> - qcheck_eq ~pp:print_expr actual_expr expr) - -(* Attempts to register an expression that contains references - to expressions not already registered should fail. *) -let test_register_fails_with_unregistered_references = - tztest "register: fails with unregistered references" `Quick (fun () -> - let prim_with_constant = - Expr.from_string - {| Pair 1 - (constant "exprubuoE4JFvkSpxsZJXAvhTdozCNZpgfCnyg6WsiAYX79q4z3bXu")|} - in - create_context () >>=? fun context -> - Global_constants_storage.register context prim_with_constant - >|= Environment.wrap_tzresult - >>= assert_proto_error_id __LOC__ "Nonexistent_global") - -(** Same test as [test_register_fails_with_unregistered_references] - but with random values. *) -let test_register_fails_with_unregistered_references_pbt = - tztest_qcheck - ~name:"register: fails with unregistered references pbt" - (pair - (Generators.context_arbitrary ()) - (Generators.canonical_with_constant_arbitrary ())) - (fun (context, (_, expr, _)) -> - assume_expr_not_too_large expr ; - Global_constants_storage.register context expr - >|= Environment.wrap_tzresult - >>= assert_proto_error_id __LOC__ "Nonexistent_global") - -let rec grow n node = - match n with n when n <= 0 -> node | n -> grow (n - 1) (Seq ((), [node])) - -(* Any expression with a depth that exceeds - [Global_constants_storage.max_allowed_global_constant_depth] - should be rejected. *) -let test_register_fails_if_too_deep = - tztest "register: fails if expression too deep" `Quick (fun () -> - let vdeep_expr = - grow - (Constants_repr.max_allowed_global_constant_depth + 1) - (Int ((), Z.of_int 1)) - |> Micheline.strip_locations - in - create_context () >>=? fun context -> - Global_constants_storage.register context vdeep_expr - >|= Environment.wrap_tzresult - >>= assert_proto_error_id __LOC__ "Expression_too_deep") - -(** [expand] on an expression containing a nonexistent global - constant returns an error. *) -let test_expand_nonexistent_fails = - tztest_qcheck - ~name: - "expand on an expression containing a nonexistent global constant fails" - (pair - (Generators.context_arbitrary ()) - (Generators.canonical_with_constant_arbitrary ())) - @@ fun (context, (_, expr, _)) -> - assume_expr_not_too_large expr ; - Global_constants_storage.expand context expr - >|= Environment.wrap_tzresult - >>= assert_proto_error_id __LOC__ "Nonexistent_global" - -(** Expanding an expression without constants should yield the same expression. *) -let test_expand_no_constants = - tztest "expand: no constants case" `Quick (fun () -> - create_context () >>=? fun context -> - let expected = Expr.from_string "Pair 1 (Pair 2 3)" in - Global_constants_storage.expand context expected - >|= Environment.wrap_tzresult - >>=? fun (_, result_expr) -> - assert_expr_equal __LOC__ expected result_expr) - -(** Similar to [test_expand_no_constants], but random. *) -let test_register_and_expand_orthogonal = - tztest_qcheck - ~name:"register and expand are orthogonal" - (triple - (Generators.context_arbitrary ()) - (Generators.canonical_without_constant_arbitrary ()) - (Generators.canonical_without_constant_arbitrary ())) - (fun (context, expr1, expr2) -> - assume_expr_not_too_large expr1 ; - assume_expr_not_too_large expr2 ; - let open Michelson_v1_printer in - Global_constants_storage.register context expr1 - >|= Environment.wrap_tzresult - >>=? fun (context, _hash, _cost) -> - Global_constants_storage.expand context expr2 - >|= Environment.wrap_tzresult - >|=? fun (_, expr2_result) -> qcheck_eq ~pp:print_expr expr2 expr2_result) - -(** Expanding should expand constants in the given - expression, then expand any new constants, etc. - recursively until no constants remain. *) -let test_expand_deep_constants = - tztest "expand: deep constants" `Quick (fun () -> - (* Should hold for any n, but this test is very slow, - hence we don't do QCheck. *) - let n = 1000 in - let expr1 = Expr.from_string "{}" in - create_context () >>=? fun context -> - let rec n_constants_deep context node n = - Global_constants_storage.register context (strip_locations node) - >|= Environment.wrap_tzresult - >>=? fun (context, hash, _) -> - if n <= 1 then return (context, node, hash) - else - let new_node = - Seq - ( -1, - [ - Prim - ( -1, - H_constant, - [String (-1, Script_expr_hash.to_b58check hash)], - [] ); - ] ) - in - n_constants_deep context new_node (n - 1) - in - n_constants_deep context (root expr1) n >>=? fun (context, _, hash) -> - let deep_expr = - Expr.from_string - @@ Format.sprintf - "{constant \"%s\"; CDR; NIL operation; PAIR}" - (Script_expr_hash.to_b58check hash) - in - Global_constants_storage.expand context deep_expr - >|= Environment.wrap_tzresult - >>=? fun (_, result) -> - let seq_n_deep n = - let rec advance n acc = - match n with 0 -> acc | _ -> advance (n - 1) (Seq (-1, [acc])) - in - advance (n - 1) (Seq (-1, [])) - in - let seq_str = Expr.to_string @@ strip_locations @@ seq_n_deep n in - let expected = - Expr.from_string - @@ Format.sprintf "{ %s; CDR; NIL operation; PAIR; }" - @@ seq_str - in - assert_expr_equal __LOC__ expected result) - -(** The [constant] prim is permitted only to have a - single string argument, representing a valid - Script_repr.expr hash, with no annotations *) -let test_expand_reject_ill_formed = - tztest "expand: ill formed constants are rejected" `Quick (fun () -> - (* first, create a context, register a constant and check - that its expansion works well. *) - create_context () >>=? fun context -> - let some_expr = Expr.from_string "0" in - Global_constants_storage.register context some_expr - >|= Environment.wrap_tzresult - >>=? fun (context, hash, _) -> - let hash = Script_expr_hash.to_b58check hash in - (* check that expansion of the registered constant works *) - Global_constants_storage.expand - context - (Expr.from_string @@ Format.sprintf "constant \"%s\"" hash) - >|= Environment.wrap_tzresult - >>=? fun (context, result) -> - assert_expr_equal __LOC__ some_expr result >>=? fun () -> - let test expr = - let expected = Expr.from_string expr in - Global_constants_storage.expand context expected - >|= Environment.wrap_tzresult - >>= assert_proto_error_id __LOC__ "Badly_formed_constant_expression" - in - (* constant with an argument other than String fails *) - test "constant 9" >>=? fun () -> - (* same as above but nested *) - test "Pair 1 (constant (Pair 2 3))" >>=? fun () -> - (* constant with bad hash fails *) - test "constant \"foobar\"" >>=? fun () -> - (* constant with type annot *) - test @@ Format.sprintf "(constant :a \"%s\")" hash >>=? fun () -> - (* constant with var annot *) - test @@ Format.sprintf "(constant @a \"%s\")" hash >>=? fun () -> - (* constant with field annot *) - test @@ Format.sprintf "(constant %%a \"%s\")" hash) - -(** The [constant] prim is not permitted to have a - [constant] child argument. - - The idea is to have expansion like this: - - constant (constant ) -> constant hash -> value - - But we want to forbid this as a badly formed constant. - Asserting that every constant must be a *static* string - makes it easier to see which constants are used where, because - you can just traverse the AST (no expansion necessary). *) -let test_reject_use_of_inner_constant = - tztest - "expand: use of 'constant (constant ...)' is rejected" - `Quick - (fun () -> - (* First, create a context, register a constant and check - that its expansion works well. *) - create_context () >>=? fun context -> - let some_expr = Expr.from_string "0" in - Global_constants_storage.register context some_expr - >|= Environment.wrap_tzresult - >>=? fun (context, hash, _) -> - let hash = Script_expr_hash.to_b58check hash in - (* Next, register the hash itself as a constant. *) - Global_constants_storage.register - context - (strip_locations (Micheline.String (-1, hash))) - >|= Environment.wrap_tzresult - >>=? fun (context, hash, _) -> - let hash = Script_expr_hash.to_b58check hash in - Global_constants_storage.expand - context - (Expr.from_string - @@ Format.sprintf "{ constant (constant \"%s\") } " hash) - >|= Environment.wrap_tzresult - >>= assert_proto_error_id __LOC__ "Badly_formed_constant_expression") - -(** [test_expand] accepts an expression [stored] to be - registered in the store, an expression [expr] that includes a template slot for - the hash of [stored], and an [expected] expression, and generates a test that - asserts the value of [expr] after expansion matches [expected]. *) -let make_expand_test ~stored ~expr ~expected () = - create_context () >>=? fun context -> - let stored_expr = Expr.from_string stored in - Global_constants_storage.register context stored_expr - >|= Environment.wrap_tzresult - >>=? fun (context, hash, _) -> - let expected = Expr.from_string expected in - let expr_with_constant = - Format.sprintf expr (Script_expr_hash.to_b58check hash) |> Expr.from_string - in - Global_constants_storage.expand context expr_with_constant - >|= Environment.wrap_tzresult - >>=? fun (_, result_expr) -> assert_expr_equal __LOC__ expected result_expr - -let test_expand_data_example = - tztest - "expand: data" - `Quick - (make_expand_test - ~stored:"3" - ~expr:"Pair 1 (Pair 2 (constant \"%s\"))" - ~expected:"Pair 1 (Pair 2 3)") - -let test_expand_types_example = - tztest - "expand: types" - `Quick - (make_expand_test - ~stored:"big_map string string" - ~expr:"PUSH (constant \"%s\") {}" - ~expected:"PUSH (big_map string string) {}") - -let test_expand_instr_example = - tztest - "expand: instr" - `Quick - (make_expand_test - ~stored:"PUSH int 3" - ~expr:"{ DROP; constant \"%s\"; DROP }" - ~expected:"{ DROP; PUSH int 3 ; DROP }") - -(** For any expression [e], when replacing any subexpression - [e'] with a constant hash and registering [e'], calling - [expand] on the new expression yields the - original expression [e]*) -let test_expand_pbt = - let open Michelson_v1_printer in - tztest_qcheck - ~name:"expand: random" - (pair - (Generators.context_arbitrary ()) - (Generators.canonical_with_constant_arbitrary ())) - (fun (context, (full_expr, expr_with_constant, sub_expr)) -> - assume_expr_not_too_large full_expr ; - assume_expr_not_too_large expr_with_constant ; - assume_expr_not_too_large sub_expr ; - Global_constants_storage.register context sub_expr - >|= Environment.wrap_tzresult - >>=? fun (context, _, _) -> - Global_constants_storage.expand context expr_with_constant - >|= Environment.wrap_tzresult - >|=? fun (_, result_expr) -> - qcheck_eq ~pp:print_expr full_expr result_expr) - -let test_expand_is_idempotent = - tztest_qcheck - ~name:"expand is idempotent" - (pair - (Generators.context_arbitrary ()) - (Generators.canonical_with_constant_arbitrary ())) - (fun (context, (full_expr, expr_with_constant, sub_expr)) -> - assume_expr_not_too_large full_expr ; - Global_constants_storage.register context sub_expr - >|= Environment.wrap_tzresult - >>=? fun (context, _, _) -> - Global_constants_storage.expand context expr_with_constant - >|= Environment.wrap_tzresult - >>=? fun (context, result1) -> - Global_constants_storage.expand context full_expr - >|= Environment.wrap_tzresult - >|=? fun (_, result2) -> qcheck_eq ~pp:print_expr result1 result2) - -(** [bottom_up_fold_cps] does not stack overflow even when - given large values. *) -let test_fold_does_not_stack_overflow = - tztest "bottom_up_fold_cps: does not stack overflow" `Quick (fun () -> - let node = grow 1_000_000 @@ Int ((), Z.zero) in - return @@ ignore - @@ Global_constants_storage.Internal_for_tests.bottom_up_fold_cps - () - node - (fun _ _ -> ()) - (fun _ node k -> k () node)) - -let tests = - [ - test_get_on_nonexistent_fails; - test_get_always_returns_registered_expr; - test_register_fails_with_unregistered_references; - test_register_fails_with_unregistered_references_pbt; - test_register_fails_if_too_deep; - test_expand_nonexistent_fails; - test_expand_no_constants; - test_register_and_expand_orthogonal; - test_expand_deep_constants; - test_expand_reject_ill_formed; - test_reject_use_of_inner_constant; - test_expand_data_example; - test_expand_types_example; - test_expand_instr_example; - test_expand_pbt; - test_expand_is_idempotent; - test_fold_does_not_stack_overflow; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/unit/test_operation_repr.ml b/src/proto_012_Psithaca/lib_protocol/test/unit/test_operation_repr.ml deleted file mode 100644 index ee36932c65cf..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/unit/test_operation_repr.ml +++ /dev/null @@ -1,112 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Operation_repr - Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe -- test Operation_repr - Dependencies: -- - Subject: To test the modules (including the top-level) - in operation_repr.ml as individual units, particularly - failure cases. Superficial goal: increase coverage percentage. -*) -open Protocol - -open Tztest - -module Test_operation_repr = struct - open Operation_repr - - let test_of_list_single_case () = - Environment.wrap_tzresult - @@ of_list - [ - Contents - (Manager_operation - { - fee = Obj.magic 0; - operation = Obj.magic 0; - gas_limit = Obj.magic 0; - storage_limit = Obj.magic 0; - counter = Obj.magic 0; - source = Obj.magic 0; - }); - ] - >>?= fun contents_list -> - match contents_list with - | Contents_list (Single _) -> return_unit - | _ -> failwith "Unexpected value" - - let test_of_list_multiple_case () = - Environment.wrap_tzresult - @@ of_list - [ - Contents - (Manager_operation - { - fee = Obj.magic 0; - operation = Obj.magic 0; - gas_limit = Obj.magic 0; - storage_limit = Obj.magic 0; - counter = Obj.magic 0; - source = Obj.magic 0; - }); - Contents - (Manager_operation - { - fee = Obj.magic 0; - operation = Obj.magic 0; - gas_limit = Obj.magic 0; - storage_limit = Obj.magic 0; - counter = Obj.magic 0; - source = Obj.magic 0; - }); - ] - >>?= fun contents_list -> - match contents_list with - | Contents_list (Cons (_, Single _)) -> return_unit - | _ -> failwith "Unexpected value" - - let test_of_list_empty_case () = - match of_list [] with - | Ok _ -> failwith "of_list of an empty list was expected to fail" - | Error _ -> return_unit -end - -let tests = - [ - tztest - "of_list: single element input list" - `Quick - Test_operation_repr.test_of_list_single_case; - tztest - "of_list: multiple element input list" - `Quick - Test_operation_repr.test_of_list_multiple_case; - tztest - "of_list: empty input list" - `Quick - Test_operation_repr.test_of_list_empty_case; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/unit/test_raw_level_repr.ml b/src/proto_012_Psithaca/lib_protocol/test/unit/test_raw_level_repr.ml deleted file mode 100644 index 9543efcdf22e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/unit/test_raw_level_repr.ml +++ /dev/null @@ -1,176 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Protocol -open Tztest - -(** Testing - ------- - Component: Raw_level_repr - Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe \ - -- test '^\[Unit\] Raw_level_repr.ml$' - Dependencies: -- - Subject: To test the modules (including the top-level) - in raw_level_repr.ml as individual units, particularly - failure cases. Superficial goal: increase coverage percentage. -*) - -module Test_raw_level_repr = struct - (* NOTE: Avoid assertions against too many functions from Raw_level_repr. For instance, - Raw_level_repr contains a [compare] function, but while [Assert]'ing, convert them to - int32 (or any convenient OCaml value) and compare instead of using [Raw_level_repr]'s compare *) - - (** Testing [encoding], int32 underneath, by applying it with Data_encoding *) - let test_encoding () = - let encoding = Raw_level_repr.encoding in - let bytes = Bytes.make 4 '0' in - Bytes.set_int32_ne bytes 0 0l ; - (Data_encoding.Binary.of_bytes encoding bytes |> function - | Ok x -> Lwt.return (Ok x) - | Error e -> - failwith - "Data_encoding.Binary.read shouldn't have failed with \ - Raw_level_repr.encoding: %a" - Data_encoding.Binary.pp_read_error - e) - >>=? fun v -> - Assert.equal_int ~loc:__LOC__ (Int32.to_int (Raw_level_repr.to_int32 v)) 0 - >>=? fun () -> - Bytes.set_int32_ne bytes 0 (-1l) ; - Data_encoding.Binary.of_bytes encoding bytes |> function - | Error _ -> return_unit - | Ok x -> - failwith - "Data_encoding.Binary.read shouldn't have succeeded with %a" - Raw_level_repr.pp - x - - (* TODO rpc_arg. RPC_arg needs to be unit tested separately. Preferably, with a functor *) - (* let rpc_arg () = () *) - - (** int32 interop tests *) - let test_int32_interop () = - let int32v = 100l in - Lwt.return (Raw_level_repr.of_int32 int32v) >|= Environment.wrap_tzresult - >>=? fun raw_level -> - Assert.equal_int32 ~loc:__LOC__ (Raw_level_repr.to_int32 raw_level) int32v - >>=? fun () -> - let int32v = -1l in - (Lwt.return (Raw_level_repr.of_int32 int32v) >|= Environment.wrap_tzresult - >>= function - | Ok _ -> failwith "Negative int32s should not be coerced into raw_level" - | Error _ -> return_unit) - >>=? fun () -> - try - let _ = Raw_level_repr.of_int32_exn int32v in - failwith "Negative int32s should not be coerced into raw_level" - with Invalid_argument _ -> return_unit - - (** Asserting [root]'s runtime value. Expected to be [0l] *) - let test_root () = - let root = Raw_level_repr.root in - Assert.equal_int32 ~loc:__LOC__ (root |> Raw_level_repr.to_int32) 0l - - (** Asserting [succ] which is expected to return successor levels *) - let test_succ () = - let next_raw_level = Raw_level_repr.succ Raw_level_repr.root in - Assert.equal_int32 - ~loc:__LOC__ - (next_raw_level |> Raw_level_repr.to_int32) - 1l - >>=? fun () -> - let arbitrary_next_raw_level = - Raw_level_repr.succ (Raw_level_repr.of_int32_exn 99l) - in - Assert.equal_int32 - ~loc:__LOC__ - (arbitrary_next_raw_level |> Raw_level_repr.to_int32) - 100l - - (** Asserting [pred] which is expected to return predecessor levels *) - let test_pred () = - (match Raw_level_repr.pred (Raw_level_repr.of_int32_exn 1l) with - | Some previous_raw_level -> - Assert.equal_int32 - ~loc:__LOC__ - (previous_raw_level |> Raw_level_repr.to_int32) - 0l - | None -> - failwith - "Raw_level_repr.pred should have successfully returned 0l as the \ - predecessor of 1l") - >>=? fun () -> - Raw_level_repr.pred Raw_level_repr.root |> function - | Some _ -> - failwith - "Raw_level_repr.pred should have returned None when asked for \ - predecessor of [root]" - | None -> return_unit - - let test_skip_succ () = - let int32_limit = 0x7FFFFFFFl in - let overflown_next_raw_level = - Raw_level_repr.succ (Raw_level_repr.of_int32_exn int32_limit) - in - if Int32.compare (Raw_level_repr.to_int32 overflown_next_raw_level) 0l >= 0 - then return_unit - else - failwith - "succ of 0x7FFFFFFFl %a was expected to be non-negative" - Assert.Int32.pp - (overflown_next_raw_level |> Raw_level_repr.to_int32) -end - -let tests = - [ - tztest - "Raw_level_repr.encoding: checks if encoding is int32 as expected" - `Quick - Test_raw_level_repr.test_encoding; - tztest - "Raw_level_repr.root: check if value is 0l" - `Quick - Test_raw_level_repr.test_root; - tztest - "Raw_level_repr.succ: basic assertions" - `Quick - Test_raw_level_repr.test_succ; - tztest - "Raw_level_repr.pred: basic assertions" - `Quick - Test_raw_level_repr.test_pred; - tztest - "Raw_level_repr: int32 interop" - `Quick - Test_raw_level_repr.test_int32_interop; - ] - -let skipped_tests = - [ - tztest - "Raw_level_repr.succ: overflow" - `Quick - Test_raw_level_repr.test_skip_succ; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/test/unit/test_tez_repr.ml b/src/proto_012_Psithaca/lib_protocol/test/unit/test_tez_repr.ml deleted file mode 100644 index 6d94465845d6..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/test/unit/test_tez_repr.ml +++ /dev/null @@ -1,202 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Marigold *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Testing - ------- - Component: Tez_repr - Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe -- test Tez_repr - Dependencies: -- - Subject: To test the modules (including the top-level) - in tez_repr.ml as individual units, particularly - failure cases. Superficial goal: increase coverage percentage. -*) -open Protocol - -open Tztest - -module Test_tez_repr = struct - (** Testing predefined units: zero, one_mutez etc *) - let test_predefined_values () = - let zero_int64 = Tez_repr.to_mutez Tez_repr.zero in - Assert.equal_int64 ~loc:__LOC__ zero_int64 0L >>=? fun () -> - let one_mutez_int64 = Tez_repr.to_mutez Tez_repr.one_mutez in - Assert.equal_int64 ~loc:__LOC__ one_mutez_int64 1L >>=? fun () -> - let one_cent_int64 = Tez_repr.to_mutez Tez_repr.one_cent in - Assert.equal_int64 ~loc:__LOC__ one_cent_int64 10000L >>=? fun () -> - let fifty_cents_int64 = Tez_repr.to_mutez Tez_repr.fifty_cents in - Assert.equal_int64 ~loc:__LOC__ fifty_cents_int64 500000L >>=? fun () -> - let one_int64 = Tez_repr.to_mutez Tez_repr.one in - Assert.equal_int64 ~loc:__LOC__ one_int64 1000000L - - let test_subtract () = - (Lwt.return @@ Tez_repr.(one -? zero)) >|= Environment.wrap_tzresult - >>=? fun res -> - Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez res) 1000000L - - let test_substract_underflow () = - (Lwt.return @@ Tez_repr.(zero -? one)) >|= Environment.wrap_tzresult - >>= function - | Ok _ -> failwith "Expected to underflow" - | Error _ -> return_unit - - let test_addition () = - (Lwt.return @@ Tez_repr.(one +? zero)) >|= Environment.wrap_tzresult - >>=? fun res -> - Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez res) 1000000L - - let test_addition_overflow () = - (Lwt.return @@ Tez_repr.(of_mutez_exn 0x7fffffffffffffffL +? one)) - >|= Environment.wrap_tzresult - >>= function - | Ok _ -> failwith "Expected to overflow" - | Error _ -> return_unit - - let test_mul () = - (Lwt.return @@ Tez_repr.(zero *? 1L)) >|= Environment.wrap_tzresult - >>=? fun res -> Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez res) 0L - - let test_mul_overflow () = - (Lwt.return @@ Tez_repr.(of_mutez_exn 0x7fffffffffffffffL *? 2L)) - >|= Environment.wrap_tzresult - >>= function - | Ok _ -> failwith "Expected to overflow" - | Error _ -> return_unit - - let test_div () = - (Lwt.return @@ Tez_repr.(one *? 1L)) >|= Environment.wrap_tzresult - >>=? fun res -> - Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez res) 1000000L - - let test_div_by_zero () = - (Lwt.return @@ Tez_repr.(one /? 0L)) >|= Environment.wrap_tzresult - >>= function - | Ok _ -> failwith "Expected to overflow" - | Error _ -> return_unit - - let test_to_mutez () = - let int64v = Tez_repr.(to_mutez one) in - Assert.equal_int64 ~loc:__LOC__ int64v 1000000L - - let test_of_mutez_non_negative () = - match Tez_repr.of_mutez 1000000L with - | Some tz -> - Assert.equal_int64 - ~loc:__LOC__ - (Tez_repr.to_mutez tz) - Tez_repr.(to_mutez one) - | None -> failwith "should have successfully converted 1000000L to tez" - - let test_of_mutez_negative () = - match Tez_repr.of_mutez (-1000000L) with - | Some _ -> failwith "should have failed to converted -1000000L to tez" - | None -> return_unit - - let test_of_mutez_exn () = - try - let tz = Tez_repr.of_mutez_exn 1000000L in - Assert.equal_int64 - ~loc:__LOC__ - (Tez_repr.to_mutez tz) - Tez_repr.(to_mutez one) - with e -> - let msg = Printexc.to_string e and stack = Printexc.get_backtrace () in - failwith "Unexpected exception: %s %s" msg stack - - let test_of_mutez_exn_negative () = - try - let _ = Tez_repr.of_mutez_exn (-1000000L) in - failwith "should have failed to converted -1000000L to tez" - with - | Invalid_argument _ -> return_unit - | e -> - let msg = Printexc.to_string e and stack = Printexc.get_backtrace () in - failwith "Unexpected exception: %s %s" msg stack - - (* NOTE: Avoid assertions against too many functions from Tez_repr. Convert them to - int64 and compare instead of using [Tez_repr]'s compare *) - - (** Testing [encoding], int64 underneath, by applying it with Data_encoding *) - let test_data_encoding () = - let encoding = Tez_repr.encoding in - let bytes = - Data_encoding.Binary.to_bytes_exn Data_encoding.n (Z.of_int 1000000) - in - (Data_encoding.Binary.of_bytes encoding bytes |> function - | Ok x -> Lwt.return (Ok x) - | Error e -> - failwith - "Data_encoding.Binary.read shouldn't have failed with \ - Tez_repr.encoding: %a" - Data_encoding.Binary.pp_read_error - e) - >>=? fun v -> Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez v) 1000000L -end - -let tests = - [ - tztest - "Check if predefined values hold expected values" - `Quick - Test_tez_repr.test_predefined_values; - tztest "Tez.substract: basic behaviour" `Quick Test_tez_repr.test_subtract; - tztest - "Tez.substract: underflow case" - `Quick - Test_tez_repr.test_substract_underflow; - tztest - "Tez.add: basic behaviour (one + zero)" - `Quick - Test_tez_repr.test_addition; - tztest "Tez.add: overflow" `Quick Test_tez_repr.test_addition_overflow; - tztest "Tez.mul: basic case" `Quick Test_tez_repr.test_mul; - tztest "Tez.mul: overflow case" `Quick Test_tez_repr.test_mul_overflow; - tztest "Tez.div: basic case" `Quick Test_tez_repr.test_div; - tztest "Tez.div: division by zero" `Quick Test_tez_repr.test_div_by_zero; - tztest "Tez.to_mutez: basic assertion" `Quick Test_tez_repr.test_to_mutez; - tztest - "Tez.of_mutez: of non-negative ints" - `Quick - Test_tez_repr.test_of_mutez_non_negative; - tztest - "Tez.of_mutez: of non-negative ints" - `Quick - Test_tez_repr.test_of_mutez_non_negative; - tztest - "Tez.of_mutez: of negative ints" - `Quick - Test_tez_repr.test_of_mutez_negative; - tztest - "Tez.of_mutez_exn: of non-negative ints" - `Quick - Test_tez_repr.test_of_mutez_non_negative; - tztest - "Tez.of_mutez_exn: of negative ints" - `Quick - Test_tez_repr.test_of_mutez_negative; - tztest - "Tez.data_encoding: must encode tezzies correctly" - `Quick - Test_tez_repr.test_data_encoding; - ] diff --git a/src/proto_012_Psithaca/lib_protocol/tez_repr.ml b/src/proto_012_Psithaca/lib_protocol/tez_repr.ml deleted file mode 100644 index 5636b07a16f0..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/tez_repr.ml +++ /dev/null @@ -1,245 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let id = "tez" - -let name = "mutez" - -include Compare.Int64 (* invariant: positive *) - -type error += - | Addition_overflow of t * t (* `Temporary *) - | Subtraction_underflow of t * t (* `Temporary *) - | Multiplication_overflow of t * int64 (* `Temporary *) - | Negative_multiplicator of t * int64 (* `Temporary *) - | Invalid_divisor of t * int64 - -(* `Temporary *) - -let zero = 0L - -(* all other constant are defined from the value of one micro tez *) -let one_mutez = 1L - -let one_cent = Int64.mul one_mutez 10_000L - -let fifty_cents = Int64.mul one_cent 50L - -(* 1 tez = 100 cents = 1_000_000 mutez *) -let one = Int64.mul one_cent 100L - -let of_string s = - let triplets = function - | hd :: tl -> - let len = String.length hd in - Compare.Int.( - len <= 3 && len > 0 && List.for_all (fun s -> String.length s = 3) tl) - | [] -> false - in - let integers s = triplets (String.split_on_char ',' s) in - let decimals s = - let l = String.split_on_char ',' s in - if Compare.List_length_with.(l > 2) then false else triplets (List.rev l) - in - let parse left right = - let remove_commas s = String.concat "" (String.split_on_char ',' s) in - let pad_to_six s = - let len = String.length s in - String.init 6 (fun i -> if Compare.Int.(i < len) then s.[i] else '0') - in - Int64.of_string_opt (remove_commas left ^ pad_to_six (remove_commas right)) - in - match String.split_on_char '.' s with - | [left; right] -> - if String.contains s ',' then - if integers left && decimals right then parse left right else None - else if - Compare.Int.(String.length right > 0) - && Compare.Int.(String.length right <= 6) - then parse left right - else None - | [left] -> - if (not (String.contains s ',')) || integers left then parse left "" - else None - | _ -> None - -let pp ppf amount = - let mult_int = 1_000_000L in - let[@coq_struct "amount"] rec left ppf amount = - let (d, r) = (Int64.(div amount 1000L), Int64.(rem amount 1000L)) in - if d > 0L then Format.fprintf ppf "%a%03Ld" left d r - else Format.fprintf ppf "%Ld" r - in - let right ppf amount = - let triplet ppf v = - if Compare.Int.(v mod 10 > 0) then Format.fprintf ppf "%03d" v - else if Compare.Int.(v mod 100 > 0) then Format.fprintf ppf "%02d" (v / 10) - else Format.fprintf ppf "%d" (v / 100) - in - let (hi, lo) = (amount / 1000, amount mod 1000) in - if Compare.Int.(lo = 0) then Format.fprintf ppf "%a" triplet hi - else Format.fprintf ppf "%03d%a" hi triplet lo - in - let (ints, decs) = - (Int64.(div amount mult_int), Int64.(to_int (rem amount mult_int))) - in - left ppf ints ; - if Compare.Int.(decs > 0) then Format.fprintf ppf ".%a" right decs - -let to_string t = Format.asprintf "%a" pp t - -let ( -? ) t1 t2 = - if t2 <= t1 then ok (Int64.sub t1 t2) - else error (Subtraction_underflow (t1, t2)) - -let sub_opt t1 t2 = if t2 <= t1 then Some (Int64.sub t1 t2) else None - -let ( +? ) t1 t2 = - let t = Int64.add t1 t2 in - if t < t1 then error (Addition_overflow (t1, t2)) else ok t - -let ( *? ) t m = - if m < 0L then error (Negative_multiplicator (t, m)) - else if m = 0L then ok 0L - else if t > Int64.(div max_int m) then error (Multiplication_overflow (t, m)) - else ok (Int64.mul t m) - -let ( /? ) t d = - if d <= 0L then error (Invalid_divisor (t, d)) else ok (Int64.div t d) - -let mul_exn t m = - match t *? Int64.(of_int m) with - | Ok v -> v - | Error _ -> invalid_arg "mul_exn" - -let div_exn t d = - match t /? Int64.(of_int d) with - | Ok v -> v - | Error _ -> invalid_arg "div_exn" - -let of_mutez t = if t < 0L then None else Some t - -let of_mutez_exn x = - match of_mutez x with None -> invalid_arg "Tez.of_mutez" | Some v -> v - -let to_mutez t = t - -let encoding = - let open Data_encoding in - Data_encoding.def - name - (check_size 10 (conv Z.of_int64 (Json.wrap_error Z.to_int64) n)) - -let () = - let open Data_encoding in - register_error_kind - `Temporary - ~id:(id ^ ".addition_overflow") - ~title:("Overflowing " ^ id ^ " addition") - ~pp:(fun ppf (opa, opb) -> - Format.fprintf - ppf - "Overflowing addition of %a %s and %a %s" - pp - opa - id - pp - opb - id) - ~description:("An addition of two " ^ id ^ " amounts overflowed") - (obj1 (req "amounts" (tup2 encoding encoding))) - (function Addition_overflow (a, b) -> Some (a, b) | _ -> None) - (fun (a, b) -> Addition_overflow (a, b)) ; - register_error_kind - `Temporary - ~id:(id ^ ".subtraction_underflow") - ~title:("Underflowing " ^ id ^ " subtraction") - ~pp:(fun ppf (opa, opb) -> - Format.fprintf - ppf - "Underflowing subtraction of %a %s and %a %s" - pp - opa - id - pp - opb - id) - ~description:("A subtraction of two " ^ id ^ " amounts underflowed") - (obj1 (req "amounts" (tup2 encoding encoding))) - (function Subtraction_underflow (a, b) -> Some (a, b) | _ -> None) - (fun (a, b) -> Subtraction_underflow (a, b)) ; - register_error_kind - `Temporary - ~id:(id ^ ".multiplication_overflow") - ~title:("Overflowing " ^ id ^ " multiplication") - ~pp:(fun ppf (opa, opb) -> - Format.fprintf - ppf - "Overflowing multiplication of %a %s and %Ld" - pp - opa - id - opb) - ~description: - ("A multiplication of a " ^ id ^ " amount by an integer overflowed") - (obj2 (req "amount" encoding) (req "multiplicator" int64)) - (function Multiplication_overflow (a, b) -> Some (a, b) | _ -> None) - (fun (a, b) -> Multiplication_overflow (a, b)) ; - register_error_kind - `Temporary - ~id:(id ^ ".negative_multiplicator") - ~title:("Negative " ^ id ^ " multiplicator") - ~pp:(fun ppf (opa, opb) -> - Format.fprintf - ppf - "Multiplication of %a %s by negative integer %Ld" - pp - opa - id - opb) - ~description:("Multiplication of a " ^ id ^ " amount by a negative integer") - (obj2 (req "amount" encoding) (req "multiplicator" int64)) - (function Negative_multiplicator (a, b) -> Some (a, b) | _ -> None) - (fun (a, b) -> Negative_multiplicator (a, b)) ; - register_error_kind - `Temporary - ~id:(id ^ ".invalid_divisor") - ~title:("Invalid " ^ id ^ " divisor") - ~pp:(fun ppf (opa, opb) -> - Format.fprintf - ppf - "Division of %a %s by non positive integer %Ld" - pp - opa - id - opb) - ~description: - ("Multiplication of a " ^ id ^ " amount by a non positive integer") - (obj2 (req "amount" encoding) (req "divisor" int64)) - (function Invalid_divisor (a, b) -> Some (a, b) | _ -> None) - (fun (a, b) -> Invalid_divisor (a, b)) - -type tez = t diff --git a/src/proto_012_Psithaca/lib_protocol/tez_repr.mli b/src/proto_012_Psithaca/lib_protocol/tez_repr.mli deleted file mode 100644 index 168dcac9b04f..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/tez_repr.mli +++ /dev/null @@ -1,75 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type t - -type tez = t - -val zero : t - -val one_mutez : t - -val one_cent : t - -val fifty_cents : t - -val one : t - -val ( -? ) : t -> t -> t tzresult - -(** Same as ( -? ) but returns None instead of an error. *) -val sub_opt : t -> t -> t option - -val ( +? ) : t -> t -> t tzresult - -val ( *? ) : t -> int64 -> t tzresult - -val ( /? ) : t -> int64 -> t tzresult - -val to_mutez : t -> int64 - -(** [of_mutez n] (micro tez) is None if n is negative *) -val of_mutez : int64 -> t option - -(** [of_mutez_exn n] fails if n is negative. - It should only be used at toplevel for constants. *) -val of_mutez_exn : int64 -> t - -(** It should only be used at toplevel for constants. *) -val mul_exn : t -> int -> t - -(** It should only be used at toplevel for constants. *) -val div_exn : t -> int -> t - -val encoding : t Data_encoding.t - -include Compare.S with type t := t - -val pp : Format.formatter -> t -> unit - -val of_string : string -> t option - -val to_string : t -> string diff --git a/src/proto_012_Psithaca/lib_protocol/tezos-embedded-protocol-012-Psithaca.opam b/src/proto_012_Psithaca/lib_protocol/tezos-embedded-protocol-012-Psithaca.opam deleted file mode 100644 index 45fe0519f328..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/tezos-embedded-protocol-012-Psithaca.opam +++ /dev/null @@ -1,25 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-protocol-012-Psithaca" - "tezos-protocol-compiler" - "tezos-protocol-updater" -] -build: [ - [ - "%{tezos-protocol-compiler:lib}%/replace" - "%{tezos-protocol-compiler:lib}%/dune_protocol.template.v1" - "dune" - "%{tezos-protocol-compiler:lib}%/final_protocol_versions" - "012_Psithaca" - ] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: economic-protocol definition, embedded in `tezos-node`" diff --git a/src/proto_012_Psithaca/lib_protocol/tezos-protocol-012-Psithaca-tests.opam b/src/proto_012_Psithaca/lib_protocol/tezos-protocol-012-Psithaca-tests.opam deleted file mode 100644 index 3b775c5ee66c..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/tezos-protocol-012-Psithaca-tests.opam +++ /dev/null @@ -1,36 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-protocol-compiler" - "alcotest-lwt" { with-test & >= "1.1.0" } - "astring" { with-test } - "tezos-test-helpers" { with-test } - "qcheck-alcotest" { with-test } - "tezos-012-Psithaca-test-helpers" { with-test } - "tezos-stdlib-unix" { with-test } - "tezos-protocol-environment" { with-test } - "tezos-client-base" { with-test } - "tezos-protocol-012-Psithaca-parameters" { with-test } - "tezos-shell-services" { with-test } - "tezos-base-test-helpers" { with-test } - "tezos-benchmark" { with-test } - "tezos-benchmark-012-Psithaca" { with-test } -] -build: [ - [ - "%{tezos-protocol-compiler:lib}%/replace" - "%{tezos-protocol-compiler:lib}%/dune_protocol.template.v1" - "dune" - "%{tezos-protocol-compiler:lib}%/final_protocol_versions" - "012_Psithaca" - ] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: tests for economic-protocol definition" diff --git a/src/proto_012_Psithaca/lib_protocol/tezos-protocol-012-Psithaca.opam b/src/proto_012_Psithaca/lib_protocol/tezos-protocol-012-Psithaca.opam deleted file mode 100644 index 5224ae123b0a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/tezos-protocol-012-Psithaca.opam +++ /dev/null @@ -1,23 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-protocol-compiler" -] -build: [ - [ - "%{tezos-protocol-compiler:lib}%/replace" - "%{tezos-protocol-compiler:lib}%/dune_protocol.template.v1" - "dune" - "%{tezos-protocol-compiler:lib}%/final_protocol_versions" - "012_Psithaca" - ] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: economic-protocol definition" diff --git a/src/proto_012_Psithaca/lib_protocol/tezos-protocol-functor-012-Psithaca.opam b/src/proto_012_Psithaca/lib_protocol/tezos-protocol-functor-012-Psithaca.opam deleted file mode 100644 index c2927cef1091..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/tezos-protocol-functor-012-Psithaca.opam +++ /dev/null @@ -1,24 +0,0 @@ -opam-version: "2.0" -maintainer: "contact@tezos.com" -authors: [ "Tezos devteam" ] -homepage: "https://www.tezos.com/" -bug-reports: "https://gitlab.com/tezos/tezos/issues" -dev-repo: "git+https://gitlab.com/tezos/tezos.git" -license: "MIT" -depends: [ - "dune" { >= "2.9" } - "tezos-protocol-012-Psithaca" - "tezos-protocol-compiler" -] -build: [ - [ - "%{tezos-protocol-compiler:lib}%/replace" - "%{tezos-protocol-compiler:lib}%/dune_protocol.template.v1" - "dune" - "%{tezos-protocol-compiler:lib}%/final_protocol_versions" - "012_Psithaca" - ] - ["dune" "build" "-p" name "-j" jobs] - ["dune" "runtest" "-p" name "-j" jobs] {with-test} -] -synopsis: "Tezos/Protocol: economic-protocol definition parameterized by its environment implementation" diff --git a/src/proto_012_Psithaca/lib_protocol/ticket_balance_key.ml b/src/proto_012_Psithaca/lib_protocol/ticket_balance_key.ml deleted file mode 100644 index 8546d3a221b8..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/ticket_balance_key.ml +++ /dev/null @@ -1,70 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -(* This function extracts nodes of: - - Ticketer - - Type of content - - Content - - Owner - to generate at ticket-balance key-hash. -*) -let ticket_balance_key_and_amount ctxt ~owner - (Ticket_scanner.Ex_ticket - (comp_ty, Script_typed_ir.{ticketer; contents; amount})) = - let loc = Micheline.dummy_location in - Script_ir_translator.unparse_comparable_ty ~loc ctxt comp_ty - >>?= fun (cont_ty_unstripped, ctxt) -> - (* We strip the annotations from the content type in order to map - tickets with the same content type, but with different annotations, to the - same hash. *) - Gas.consume ctxt (Script.strip_annotations_cost cont_ty_unstripped) - >>?= fun ctxt -> - let typ = Script.strip_annotations cont_ty_unstripped in - let ticketer_address = (ticketer, "default") in - let owner_address = (owner, "default") in - let address_t = Script_typed_ir.address_t ~annot:None in - Script_ir_translator.unparse_data - ctxt - Script_ir_translator.Optimized_legacy - address_t - ticketer_address - >>=? fun (ticketer, ctxt) -> - Script_ir_translator.unparse_comparable_data - ~loc - ctxt - Script_ir_translator.Optimized_legacy - comp_ty - contents - >>=? fun (contents, ctxt) -> - Script_ir_translator.unparse_data - ctxt - Script_ir_translator.Optimized_legacy - address_t - owner_address - >>=? fun (owner, ctxt) -> - Ticket_balance.make_key_hash ctxt ~ticketer ~typ ~contents ~owner - >>?= fun (hash, ctxt) -> return (hash, Script_int.to_zint amount, ctxt) diff --git a/src/proto_012_Psithaca/lib_protocol/ticket_balance_key.mli b/src/proto_012_Psithaca/lib_protocol/ticket_balance_key.mli deleted file mode 100644 index a88a87bd3921..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/ticket_balance_key.mli +++ /dev/null @@ -1,40 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module exposes a function for generating a ticket-balance key-hash - and an amount, given an owner and a ticket. The key-hash and the amount is - used for populating the global ticket-balance table that tracks ownership - of different types of tickets. - *) - -(** [ticket_balance_key_and_amount ctxt ~owner ex_ticket] returns the [key_hash] - of the given [owner] and [ex_ticket], as well as the amount of the - ticket. *) -val ticket_balance_key_and_amount : - Alpha_context.context -> - owner:Alpha_context.Contract.t -> - Ticket_scanner.ex_ticket -> - (Alpha_context.Ticket_balance.key_hash * Z.t * Alpha_context.context) tzresult - Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/ticket_costs.ml b/src/proto_012_Psithaca/lib_protocol/ticket_costs.ml deleted file mode 100644 index 72be4eda1a76..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/ticket_costs.ml +++ /dev/null @@ -1,52 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -module Constants = struct - module S = Saturation_repr - - (* TODO: Fill in real benchmarked values *) - let cost_contains_tickets_step = S.safe_int 28 - - (* TODO: Fill in real benchmarked values *) - let cost_collect_tickets_step = S.safe_int 360 - - (* TODO: Fill in real benchmarked values *) - let cost_has_tickets_of_ty type_size = S.mul (S.safe_int 20) type_size -end - -let consume_gas_steps ctxt ~step_cost ~num_steps = - let ( * ) = Saturation_repr.mul in - if Compare.Int.(num_steps <= 0) then Ok ctxt - else - let gas = - Gas.atomic_step_cost (step_cost * Saturation_repr.safe_int num_steps) - in - Gas.consume ctxt gas - -let has_tickets_of_ty_cost ty = - Constants.cost_has_tickets_of_ty - Script_typed_ir.(ty_size ty |> Type_size.to_int) diff --git a/src/proto_012_Psithaca/lib_protocol/ticket_costs.mli b/src/proto_012_Psithaca/lib_protocol/ticket_costs.mli deleted file mode 100644 index de052916f7de..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/ticket_costs.mli +++ /dev/null @@ -1,53 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module contains constants and utility functions for gas metering - functions used for extracting and handling tickets for the global ticket - balance table. *) - -module Constants : sig - val cost_contains_tickets_step : Alpha_context.Gas.cost - - val cost_collect_tickets_step : Alpha_context.Gas.cost -end - -(** [consume_gas_steps ctxt ~num_steps] consumes gas corresponding to - a given [num_steps] and [step_cost]. It's useful for paying for gas - upfront where the number of steps can be determined. - - This function is generic and should probably be moved. See issue - https://gitlab.com/tezos/tezos/-/issues/1950. - - *) -val consume_gas_steps : - Alpha_context.t -> - step_cost:Alpha_context.Gas.cost -> - num_steps:int -> - Alpha_context.t tzresult - -(** [has_tickets_of_ty_cost ty] returns the cost of producing a [has_tickets], - used internally in the [Ticket_scanner] module. *) -val has_tickets_of_ty_cost : - 'a Script_typed_ir.ty -> Saturation_repr.may_saturate Saturation_repr.t diff --git a/src/proto_012_Psithaca/lib_protocol/ticket_scanner.ml b/src/proto_012_Psithaca/lib_protocol/ticket_scanner.ml deleted file mode 100644 index ae4281f2cfa1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/ticket_scanner.ml +++ /dev/null @@ -1,515 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -(* Impossible error *) -type error += Unsupported_type_invariant_violated - -type error += Unsupported_non_empty_overlay | Unsupported_type_operation - -let () = - register_error_kind - `Branch - ~id:"Unsupported_non_empty_overlay" - ~title:"Unsupported non empty overlay" - ~description:"Unsupported big-map value with non-empty overlay" - ~pp:(fun ppf () -> - Format.fprintf ppf "Unsupported big-map value with non-empty overlay") - Data_encoding.empty - (function Unsupported_non_empty_overlay -> Some () | _ -> None) - (fun () -> Unsupported_non_empty_overlay) ; - register_error_kind - `Branch - ~id:"Unsupported_type_operation" - ~title:"Unsupported type operation" - ~description:"Types embedding operations are not supported" - ~pp:(fun ppf () -> - Format.fprintf ppf "Types embedding operations are not supported") - Data_encoding.empty - (function Unsupported_type_operation -> Some () | _ -> None) - (fun () -> Unsupported_type_operation) - -type ex_ticket = - | Ex_ticket : - 'a Script_typed_ir.comparable_ty * 'a Script_typed_ir.ticket - -> ex_ticket - -module Ticket_inspection = struct - (* TODO: 1951 - Replace with use of meta-data for ['a ty] type. - Once ['a ty] values can be extended with custom meta data, this type - can be removed. - *) - (** - Witness flag for whether a type can be populated by a value containing a - ticket. [False_ht] must be used only when a value of the type cannot - contain a ticket. - - This flag is necessary for avoiding ticket collection (see below) to have - quadratic complexity in the order of: size-of-the-type * size-of-value. - - This type is local to the [Ticket_scanner] module and should not be - exported. - - *) - type 'a has_tickets = - | True_ht : _ Script_typed_ir.ticket has_tickets - | False_ht : _ has_tickets - | Pair_ht : - 'a has_tickets * 'b has_tickets - -> ('a, 'b) Script_typed_ir.pair has_tickets - | Union_ht : - 'a has_tickets * 'b has_tickets - -> ('a, 'b) Script_typed_ir.union has_tickets - | Option_ht : 'a has_tickets -> 'a option has_tickets - | List_ht : 'a has_tickets -> 'a Script_typed_ir.boxed_list has_tickets - | Set_ht : 'k has_tickets -> 'k Script_typed_ir.set has_tickets - | Map_ht : - 'k has_tickets * 'v has_tickets - -> ('k, 'v) Script_typed_ir.map has_tickets - | Big_map_ht : - 'k has_tickets * 'v has_tickets - -> ('k, 'v) Script_typed_ir.big_map has_tickets - - (* Returns whether or not a comparable type embeds tickets. Currently - this function returns [false] for all input. - - The only reason we keep this code is so that in the future, if tickets were - ever to be comparable, the compiler would detect a missing pattern match - case. - - Note that in case tickets are made comparable, this function needs to change - so that constructors like [Union_key] and [Pair_key] are traversed - recursively. - *) - let has_tickets_of_comparable : - type a ret. - a Script_typed_ir.comparable_ty -> (a has_tickets -> ret) -> ret = - fun key_ty k -> - let open Script_typed_ir in - match key_ty with - | Unit_key _ -> (k [@ocaml.tailcall]) False_ht - | Never_key _ -> (k [@ocaml.tailcall]) False_ht - | Int_key _ -> (k [@ocaml.tailcall]) False_ht - | Nat_key _ -> (k [@ocaml.tailcall]) False_ht - | Signature_key _ -> (k [@ocaml.tailcall]) False_ht - | String_key _ -> (k [@ocaml.tailcall]) False_ht - | Bytes_key _ -> (k [@ocaml.tailcall]) False_ht - | Mutez_key _ -> (k [@ocaml.tailcall]) False_ht - | Bool_key _ -> (k [@ocaml.tailcall]) False_ht - | Key_hash_key _ -> (k [@ocaml.tailcall]) False_ht - | Key_key _ -> (k [@ocaml.tailcall]) False_ht - | Timestamp_key _ -> (k [@ocaml.tailcall]) False_ht - | Chain_id_key _ -> (k [@ocaml.tailcall]) False_ht - | Address_key _ -> (k [@ocaml.tailcall]) False_ht - | Pair_key ((_, _), (_, _), _) -> (k [@ocaml.tailcall]) False_ht - | Union_key (_, (_, _), _) -> (k [@ocaml.tailcall]) False_ht - | Option_key (_, _) -> (k [@ocaml.tailcall]) False_ht - - (* Short circuit pairing of two [has_tickets] values. - If neither left nor right branch contains a ticket, [False_ht] is - returned. *) - let pair_has_tickets pair ht1 ht2 = - match (ht1, ht2) with (False_ht, False_ht) -> False_ht | _ -> pair ht1 ht2 - - let map_has_tickets map ht = - match ht with False_ht -> False_ht | _ -> map ht - - type ('a, 'r) continuation = 'a has_tickets -> 'r tzresult - - (* Creates a [has_tickets] type-witness value from the given ['a ty]. - The returned value matches the given shape of the [ty] value, except - it collapses whole branches where no types embed tickets to [False_ht]. - *) - let rec has_tickets_of_ty : - type a ret. a Script_typed_ir.ty -> (a, ret) continuation -> ret tzresult - = - fun ty k -> - let open Script_typed_ir in - match ty with - | Ticket_t _ -> (k [@ocaml.tailcall]) True_ht - | Unit_t _ -> (k [@ocaml.tailcall]) False_ht - | Int_t _ -> (k [@ocaml.tailcall]) False_ht - | Nat_t _ -> (k [@ocaml.tailcall]) False_ht - | Signature_t _ -> (k [@ocaml.tailcall]) False_ht - | String_t _ -> (k [@ocaml.tailcall]) False_ht - | Bytes_t _ -> (k [@ocaml.tailcall]) False_ht - | Mutez_t _ -> (k [@ocaml.tailcall]) False_ht - | Key_hash_t _ -> (k [@ocaml.tailcall]) False_ht - | Key_t _ -> (k [@ocaml.tailcall]) False_ht - | Timestamp_t _ -> (k [@ocaml.tailcall]) False_ht - | Address_t _ -> (k [@ocaml.tailcall]) False_ht - | Bool_t _ -> (k [@ocaml.tailcall]) False_ht - | Pair_t ((ty1, _, _), (ty2, _, _), _) -> - (has_tickets_of_pair [@ocaml.tailcall]) - ty1 - ty2 - ~pair:(fun ht1 ht2 -> Pair_ht (ht1, ht2)) - k - | Union_t ((ty1, _), (ty2, _), _) -> - (has_tickets_of_pair [@ocaml.tailcall]) - ty1 - ty2 - ~pair:(fun ht1 ht2 -> Union_ht (ht1, ht2)) - k - | Lambda_t (_, _, _) -> - (* As of H, closures cannot contain tickets because APPLY requires - a packable type and tickets are not packable. *) - (k [@ocaml.tailcall]) False_ht - | Option_t (ty, _) -> - (has_tickets_of_ty [@ocaml.tailcall]) ty (fun ht -> - let opt_hty = map_has_tickets (fun ht -> Option_ht ht) ht in - (k [@ocaml.tailcall]) opt_hty) - | List_t (ty, _) -> - (has_tickets_of_ty [@ocaml.tailcall]) ty (fun ht -> - let list_hty = map_has_tickets (fun ht -> List_ht ht) ht in - (k [@ocaml.tailcall]) list_hty) - | Set_t (key_ty, _) -> - (has_tickets_of_comparable [@ocaml.tailcall]) key_ty (fun ht -> - let set_hty = map_has_tickets (fun ht -> Set_ht ht) ht in - (k [@ocaml.tailcall]) set_hty) - | Map_t (key_ty, val_ty, _) -> - (has_tickets_of_key_and_value [@ocaml.tailcall]) - key_ty - val_ty - ~pair:(fun ht1 ht2 -> Map_ht (ht1, ht2)) - k - | Big_map_t (key_ty, val_ty, _) -> - (has_tickets_of_key_and_value [@ocaml.tailcall]) - key_ty - val_ty - ~pair:(fun ht1 ht2 -> Big_map_ht (ht1, ht2)) - k - | Contract_t _ -> (k [@ocaml.tailcall]) False_ht - | Sapling_transaction_t _ -> (k [@ocaml.tailcall]) False_ht - | Sapling_state_t _ -> (k [@ocaml.tailcall]) False_ht - | Operation_t _ -> - (* Operations may contain tickets but they should never be passed - why we fail in this case. *) - error Unsupported_type_operation - | Chain_id_t _ -> (k [@ocaml.tailcall]) False_ht - | Never_t _ -> (k [@ocaml.tailcall]) False_ht - | Bls12_381_g1_t _ -> (k [@ocaml.tailcall]) False_ht - | Bls12_381_g2_t _ -> (k [@ocaml.tailcall]) False_ht - | Bls12_381_fr_t _ -> (k [@ocaml.tailcall]) False_ht - | Chest_t _ -> (k [@ocaml.tailcall]) False_ht - | Chest_key_t _ -> (k [@ocaml.tailcall]) False_ht - - and has_tickets_of_pair : - type a b c ret. - a Script_typed_ir.ty -> - b Script_typed_ir.ty -> - pair:(a has_tickets -> b has_tickets -> c has_tickets) -> - (c, ret) continuation -> - ret tzresult = - fun ty1 ty2 ~pair k -> - (has_tickets_of_ty [@ocaml.tailcall]) ty1 (fun ht1 -> - (has_tickets_of_ty [@ocaml.tailcall]) ty2 (fun ht2 -> - (k [@ocaml.tailcall]) (pair_has_tickets pair ht1 ht2))) - - and has_tickets_of_key_and_value : - type k v t ret. - k Script_typed_ir.comparable_ty -> - v Script_typed_ir.ty -> - pair:(k has_tickets -> v has_tickets -> t has_tickets) -> - (t, ret) continuation -> - ret tzresult = - fun key_ty val_ty ~pair k -> - (has_tickets_of_comparable [@ocaml.tailcall]) key_ty (fun ht1 -> - (has_tickets_of_ty [@ocaml.tailcall]) val_ty (fun ht2 -> - (k [@ocaml.tailcall]) (pair_has_tickets pair ht1 ht2))) - - let has_tickets_of_ty ctxt ty = - Gas.consume ctxt (Ticket_costs.has_tickets_of_ty_cost ty) >>? fun ctxt -> - has_tickets_of_ty ty ok >|? fun ht -> (ht, ctxt) -end - -module Ticket_collection = struct - let consume_gas_steps = - Ticket_costs.consume_gas_steps - ~step_cost:Ticket_costs.Constants.cost_collect_tickets_step - - type accumulator = ex_ticket list - - type 'a continuation = - Alpha_context.context -> accumulator -> 'a tzresult Lwt.t - - (* Currently this always returns the original list. - - If comparables are ever extended to support tickets, this function - needs to be modified. In particular constructors like [Option] and [Pair] - would have to recurse on their arguments. *) - - let tickets_of_comparable : - type a ret. - Alpha_context.context -> - a Script_typed_ir.comparable_ty -> - accumulator -> - ret continuation -> - ret tzresult Lwt.t = - fun ctxt comp_ty acc k -> - let open Script_typed_ir in - match comp_ty with - | Unit_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Never_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Int_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Nat_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Signature_key _ -> (k [@ocaml.tailcall]) ctxt acc - | String_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Bytes_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Mutez_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Bool_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Key_hash_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Key_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Timestamp_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Chain_id_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Address_key _ -> (k [@ocaml.tailcall]) ctxt acc - | Pair_key ((_, _), (_, _), _) -> (k [@ocaml.tailcall]) ctxt acc - | Union_key ((_, _), (_, _), _) -> (k [@ocaml.tailcall]) ctxt acc - | Option_key (_, _) -> (k [@ocaml.tailcall]) ctxt acc - - let tickets_of_set : - type a ret. - Alpha_context.context -> - a Script_typed_ir.comparable_ty -> - a Script_typed_ir.set -> - accumulator -> - ret continuation -> - ret tzresult Lwt.t = - fun ctxt key_ty _set acc k -> - consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> - (* This is only invoked to support any future extensions making tickets - comparable. *) - (tickets_of_comparable [@ocaml.tailcall]) ctxt key_ty acc k - - let rec tickets_of_value : - type a ret. - include_lazy:bool -> - Alpha_context.context -> - a Ticket_inspection.has_tickets -> - a Script_typed_ir.ty -> - a -> - accumulator -> - ret continuation -> - ret tzresult Lwt.t = - fun ~include_lazy ctxt hty ty x acc k -> - let open Script_typed_ir in - consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> - match (hty, ty) with - | (False_ht, _) -> (k [@ocaml.tailcall]) ctxt acc - | (Pair_ht (hty1, hty2), Pair_t ((ty1, _, _), (ty2, _, _), _)) -> - let (l, r) = x in - (tickets_of_value [@ocaml.tailcall]) - ~include_lazy - ctxt - hty1 - ty1 - l - acc - (fun ctxt acc -> - (tickets_of_value [@ocaml.tailcall]) - ~include_lazy - ctxt - hty2 - ty2 - r - acc - k) - | (Union_ht (htyl, htyr), Union_t ((tyl, _), (tyr, _), _)) -> ( - match x with - | L v -> - (tickets_of_value [@ocaml.tailcall]) - ~include_lazy - ctxt - htyl - tyl - v - acc - k - | R v -> - (tickets_of_value [@ocaml.tailcall]) - ~include_lazy - ctxt - htyr - tyr - v - acc - k) - | (Option_ht el_hty, Option_t (el_ty, _)) -> ( - match x with - | Some x -> - (tickets_of_value [@ocaml.tailcall]) - ~include_lazy - ctxt - el_hty - el_ty - x - acc - k - | None -> (k [@ocaml.tailcall]) ctxt acc) - | (List_ht el_hty, List_t (el_ty, _)) -> - let {elements; _} = x in - (tickets_of_list [@ocaml.tailcall]) - ctxt - ~include_lazy - el_hty - el_ty - elements - acc - k - | (Set_ht _, Set_t (key_ty, _)) -> - (tickets_of_set [@ocaml.tailcall]) ctxt key_ty x acc k - | (Map_ht (_, val_hty), Map_t (key_ty, val_ty, _)) -> - (tickets_of_comparable [@ocaml.tailcall]) - ctxt - key_ty - acc - (fun ctxt acc -> - (tickets_of_map [@ocaml.tailcall]) - ctxt - ~include_lazy - val_hty - val_ty - x - acc - k) - | (Big_map_ht (_, val_hty), Big_map_t (key_ty, _, _)) -> - if include_lazy then - (tickets_of_big_map [@ocaml.tailcall]) ctxt val_hty key_ty x acc k - else (k [@ocaml.tailcall]) ctxt acc - | (True_ht, Ticket_t (comp_ty, _)) -> - (k [@ocaml.tailcall]) ctxt (Ex_ticket (comp_ty, x) :: acc) - | _ -> fail Unsupported_type_invariant_violated - - and tickets_of_list : - type a ret. - Alpha_context.context -> - include_lazy:bool -> - a Ticket_inspection.has_tickets -> - a Script_typed_ir.ty -> - a list -> - accumulator -> - ret continuation -> - ret tzresult Lwt.t = - fun ctxt ~include_lazy el_hty el_ty elements acc k -> - consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> - match elements with - | elem :: elems -> - (tickets_of_value [@ocaml.tailcall]) - ~include_lazy - ctxt - el_hty - el_ty - elem - acc - (fun ctxt acc -> - (tickets_of_list [@ocaml.tailcall]) - ~include_lazy - ctxt - el_hty - el_ty - elems - acc - k) - | [] -> (k [@ocaml.tailcall]) ctxt acc - - and tickets_of_map : - type k v ret. - include_lazy:bool -> - Alpha_context.context -> - v Ticket_inspection.has_tickets -> - v Script_typed_ir.ty -> - (k, v) Script_typed_ir.map -> - accumulator -> - ret continuation -> - ret tzresult Lwt.t = - fun ~include_lazy ctxt val_hty val_ty (module M) acc k -> - consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> - (* Pay gas for folding over the values *) - consume_gas_steps ctxt ~num_steps:M.size >>?= fun ctxt -> - let values = M.OPS.fold (fun _ v vs -> v :: vs) M.boxed [] in - (tickets_of_list [@ocaml.tailcall]) - ~include_lazy - ctxt - val_hty - val_ty - values - acc - k - - and tickets_of_big_map : - type k v ret. - Alpha_context.context -> - v Ticket_inspection.has_tickets -> - k Script_typed_ir.comparable_ty -> - (k, v) Script_typed_ir.big_map -> - accumulator -> - ret continuation -> - ret tzresult Lwt.t = - fun ctxt - val_hty - key_ty - {Script_typed_ir.id; diff = {map = _; size}; key_type = _; value_type} - acc - k -> - consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> - (* Require empty overlay *) - if Compare.Int.(size > 0) then fail Unsupported_non_empty_overlay - else - (* Traverse the keys for tickets, although currently keys should never - contain any tickets. *) - (tickets_of_comparable [@ocaml.tailcall]) ctxt key_ty acc (fun ctxt acc -> - (* Accumulate tickets from values of the big-map stored in the context *) - match id with - | Some id -> - let accum (values, ctxt) exp = - Script_ir_translator.parse_data - ~legacy:true - ctxt - ~allow_forged:true - value_type - (Micheline.root exp) - >|=? fun (v, ctxt) -> (v :: values, ctxt) - in - Big_map.list_values ctxt id >>=? fun (ctxt, exps) -> - List.fold_left_es accum ([], ctxt) exps >>=? fun (values, ctxt) -> - (tickets_of_list [@ocaml.tailcall]) - ~include_lazy:true - ctxt - val_hty - value_type - values - acc - k - | None -> (k [@ocaml.tailcall]) ctxt acc) - - let tickets_of_value ctxt ~include_lazy ty x = - Ticket_inspection.has_tickets_of_ty ctxt ty >>?= fun (ht, ctxt) -> - tickets_of_value ctxt ~include_lazy ht ty x [] (fun ctxt ex_tickets -> - return (ex_tickets, ctxt)) -end - -let tickets_of_value ctxt = Ticket_collection.tickets_of_value ctxt diff --git a/src/proto_012_Psithaca/lib_protocol/ticket_scanner.mli b/src/proto_012_Psithaca/lib_protocol/ticket_scanner.mli deleted file mode 100644 index b5f859a89c4e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/ticket_scanner.mli +++ /dev/null @@ -1,55 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module provides an API for extracting tickets of arbitrary types - from an OCaml values, given a type-witness. *) - -(** A type for representing existentially quantified tickets (tickets with - different types of payloads). An [ex_ticket] value consists of: - - A type-witness representing the type of the content of the ticket. - - A ticket value of the particular content type. - *) -type ex_ticket = - | Ex_ticket : - 'a Script_typed_ir.comparable_ty * 'a Script_typed_ir.ticket - -> ex_ticket - -(** [tickets_of_value ctxt ~include_lazy ty value] extracts all tickets from the - given shape [ty] and value [value]. The [include_lazy] flag determines whether - or not to traverse lazy structures (values from the context). - In case the [include_lazy] flag is [true], any big-map contained in the value - must have an empty overlay or else an error of type - [Unsupported_non_empty_overlay] is returned. The reason for this restriction - is that we assume that all lazy big-map diffs should be applied before - calling this function. Dealing with non-empty overlays would be possible - in theory, but practically difficult. The challenge is to distinguish - between overlapping keys between the context and the overlay. - *) -val tickets_of_value : - Alpha_context.context -> - include_lazy:bool -> - 'a Script_typed_ir.ty -> - 'a -> - (ex_ticket list * Alpha_context.context) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/ticket_storage.ml b/src/proto_012_Psithaca/lib_protocol/ticket_storage.ml deleted file mode 100644 index 9e97567d1708..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/ticket_storage.ml +++ /dev/null @@ -1,119 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type key_hash = Script_expr_hash.t - -type error += - | Negative_ticket_balance of {key : Script_expr_hash.t; balance : Z.t} - | Failed_to_hash_node - -let script_expr_hash_of_key_hash key_hash = key_hash - -let hash_bytes_cost bytes = - let module S = Saturation_repr in - let ( + ) = S.add in - let v0 = S.safe_int @@ Bytes.length bytes in - let ( lsr ) = S.shift_right in - S.safe_int 200 + (v0 + (v0 lsr 2)) |> Gas_limit_repr.atomic_step_cost - -let hash_of_node ctxt node = - Raw_context.consume_gas ctxt (Script_repr.strip_locations_cost node) - >>? fun ctxt -> - let node = Micheline.strip_locations node in - match Data_encoding.Binary.to_bytes_opt Script_repr.expr_encoding node with - | Some bytes -> - Raw_context.consume_gas ctxt (hash_bytes_cost bytes) >|? fun ctxt -> - (Script_expr_hash.hash_bytes [bytes], ctxt) - | None -> error Failed_to_hash_node - -let make_key_hash ctxt ~ticketer ~typ ~contents ~owner = - hash_of_node ctxt - @@ Micheline.Seq (Micheline.dummy_location, [ticketer; typ; contents; owner]) - -let () = - let open Data_encoding in - register_error_kind - `Permanent - ~id:"Negative_ticket_balance" - ~title:"Negative ticket balance" - ~description:"Attempted to set a negative ticket balance value" - ~pp:(fun ppf (key, balance) -> - Format.fprintf - ppf - "Attempted to set negative ticket balance value '%a' for key %a." - Z.pp_print - balance - Script_expr_hash.pp - key) - (obj2 (req "key" Script_expr_hash.encoding) (req "balance" Data_encoding.z)) - (function - | Negative_ticket_balance {key; balance} -> Some (key, balance) - | _ -> None) - (fun (key, balance) -> Negative_ticket_balance {key; balance}) ; - register_error_kind - `Branch - ~id:"Failed_to_hash_node" - ~title:"Failed to hash node" - ~description:"Failed to hash node for a key in the ticket-balance table" - ~pp:(fun ppf () -> - Format.fprintf - ppf - "Failed to hash node for a key in the ticket-balance table") - Data_encoding.empty - (function Failed_to_hash_node -> Some () | _ -> None) - (fun () -> Failed_to_hash_node) - -let get_balance ctxt key = - Storage.Ticket_balance.Table.find ctxt key >|=? fun (ctxt, res) -> (res, ctxt) - -let set_balance ctxt key balance = - let cost_of_key = Z.of_int 65 in - fail_when - Compare.Z.(balance < Z.zero) - (Negative_ticket_balance {key; balance}) - >>=? fun () -> - if Compare.Z.(balance = Z.zero) then - Storage.Ticket_balance.Table.remove ctxt key - >|=? fun (ctxt, freed, existed) -> - (* If we remove an existing entry, then we return the freed size for - both the key and the value. *) - let freed = - if existed then Z.neg @@ Z.add cost_of_key (Z.of_int freed) else Z.zero - in - (freed, ctxt) - else - Storage.Ticket_balance.Table.add ctxt key balance - >|=? fun (ctxt, size_diff, existed) -> - let size_diff = - let z_diff = Z.of_int size_diff in - (* For a new entry we also charge the space for storing the key *) - if existed then z_diff else Z.add cost_of_key z_diff - in - (size_diff, ctxt) - -let adjust_balance ctxt key ~delta = - get_balance ctxt key >>=? fun (res, ctxt) -> - let old_balance = Option.value ~default:Z.zero res in - set_balance ctxt key (Z.add old_balance delta) diff --git a/src/proto_012_Psithaca/lib_protocol/ticket_storage.mli b/src/proto_012_Psithaca/lib_protocol/ticket_storage.mli deleted file mode 100644 index c116eb052177..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/ticket_storage.mli +++ /dev/null @@ -1,71 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Trili Tech, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** A value of type [key_hash] is a hashed combination of: - - Ticketer - - Content type - - Content - - Owner -*) -type key_hash - -(** [script_expr_hash_of_key_hash key_hash] returns a [Script_expr_hash.t] value - representation of the given [key_hash]. This is useful for comparing and - pretty-printing key-hash values. *) -val script_expr_hash_of_key_hash : key_hash -> Script_expr_hash.t - -(** [make_key_hash ctxt ~ticketer ~typ ~contents ~owner] creates a hashed - representation of the given [ticketer], [typ], [contents] and [owner]. -*) -val make_key_hash : - Raw_context.t -> - ticketer:Script_repr.node -> - typ:Script_repr.node -> - contents:Script_repr.node -> - owner:Script_repr.node -> - (key_hash * Raw_context.t) tzresult - -(** [get_balance ctxt key] receives the ticket balance for the given - [key] in the context [ctxt]. The [key] represents a ticket content and a - ticket creator pair. In case there exists no value for the given [key], - [None] is returned. - *) -val get_balance : - Raw_context.t -> key_hash -> (Z.t option * Raw_context.t) tzresult Lwt.t - -(** [adjust_balance ctxt key ~delta] adjusts the balance of the - given key (representing a ticket content, creator and owner pair) - and [delta]. The value of [delta] can be positive as well as negative. - If there is no pre-exising balance for the given ticket type and owner, - it is assumed to be 0 and the new balance is [delta]. The function also - returns the difference between the old and the new size of the storage. - Note that the difference may be negative. For example, because when - setting the balance to zero, an entry is removed. - - The function fails with a [Negative_ticket_balance] error - in case the resulting balance is negative. - *) -val adjust_balance : - Raw_context.t -> key_hash -> delta:Z.t -> (Z.t * Raw_context.t) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/time_repr.ml b/src/proto_012_Psithaca/lib_protocol/time_repr.ml deleted file mode 100644 index d19897b7122e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/time_repr.ml +++ /dev/null @@ -1,73 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) -include Time - -type time = Time.t - -type error += Timestamp_add (* `Permanent *) - -type error += Timestamp_sub (* `Permanent *) - -let () = - register_error_kind - `Permanent - ~id:"timestamp_add" - ~title:"Timestamp add" - ~description:"Overflow when adding timestamps." - ~pp:(fun ppf () -> Format.fprintf ppf "Overflow when adding timestamps.") - Data_encoding.empty - (function Timestamp_add -> Some () | _ -> None) - (fun () -> Timestamp_add) ; - register_error_kind - `Permanent - ~id:"timestamp_sub" - ~title:"Timestamp sub" - ~description:"Subtracting timestamps resulted in negative period." - ~pp:(fun ppf () -> - Format.fprintf ppf "Subtracting timestamps resulted in negative period.") - Data_encoding.empty - (function Timestamp_sub -> Some () | _ -> None) - (fun () -> Timestamp_sub) - -let of_seconds_string s = Option.map Time.of_seconds (Int64.of_string_opt s) - -let to_seconds_string s = Int64.to_string (to_seconds s) - -let pp = pp_hum - -let ( +? ) x y = - let span = Period_repr.to_seconds y in - let t64 = Time.add x span in - (* As long as span and time representations are int64, we cannont overflow if - x is negative. *) - if x < Time.of_seconds 0L then ok t64 - else if t64 < Time.of_seconds 0L then error Timestamp_add - else ok t64 - -let ( -? ) x y = - record_trace Timestamp_sub (Period_repr.of_seconds (Time.diff x y)) - -let ( - ) x y = - Time.of_seconds Int64.(sub (Time.to_seconds x) (Period_repr.to_seconds y)) diff --git a/src/proto_012_Psithaca/lib_protocol/time_repr.mli b/src/proto_012_Psithaca/lib_protocol/time_repr.mli deleted file mode 100644 index c35b2da6f283..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/time_repr.mli +++ /dev/null @@ -1,55 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -include module type of struct - include Time -end - -(** Internal timestamp representation. *) -type time = t - -(** Pretty-prints the time stamp using RFC3339 format. *) -val pp : Format.formatter -> t -> unit - -(** Parses RFC3339 representation and returns a timestamp. *) -val of_seconds_string : string -> time option - -(** Returns the timestamp encoded in RFC3339 format. *) -val to_seconds_string : time -> string - -(** Adds a time span to a timestamp. - This function fails on integer overflow *) -val ( +? ) : time -> Period_repr.t -> time tzresult - -(** Returns the difference between two timestamps as a time span. - This function fails when the difference is negative *) -val ( -? ) : time -> time -> Period_repr.t tzresult - -(** [t - p] Returns a timestamps [p] seconds before [t]. - - TODO: https://gitlab.com/tezos/tezos/-/issues/2054 - This function should be made available in the environment. - *) -val ( - ) : time -> Period_repr.t -> time diff --git a/src/proto_012_Psithaca/lib_protocol/token.ml b/src/proto_012_Psithaca/lib_protocol/token.ml deleted file mode 100644 index 957eff96a669..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/token.ml +++ /dev/null @@ -1,266 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type container = - [ `Contract of Contract_repr.t - | `Collected_commitments of Blinded_public_key_hash.t - | `Delegate_balance of Signature.Public_key_hash.t - | `Frozen_deposits of Signature.Public_key_hash.t - | `Block_fees - | `Legacy_deposits of Signature.Public_key_hash.t * Cycle_repr.t - | `Legacy_fees of Signature.Public_key_hash.t * Cycle_repr.t - | `Legacy_rewards of Signature.Public_key_hash.t * Cycle_repr.t ] - -type source = - [ `Invoice - | `Bootstrap - | `Initial_commitments - | `Revelation_rewards - | `Double_signing_evidence_rewards - | `Endorsing_rewards - | `Baking_rewards - | `Baking_bonuses - | `Minted - | `Liquidity_baking_subsidies - | container ] - -type sink = - [ `Storage_fees - | `Double_signing_punishments - | `Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool - | `Burned - | container ] - -let allocated ctxt stored = - match stored with - | `Contract contract -> Contract_storage.allocated ctxt contract - | `Collected_commitments bpkh -> Commitment_storage.exists ctxt bpkh >|= ok - | `Delegate_balance delegate -> - let contract = Contract_repr.implicit_contract delegate in - Contract_storage.allocated ctxt contract - | `Frozen_deposits delegate -> - let contract = Contract_repr.implicit_contract delegate in - Frozen_deposits_storage.allocated ctxt contract >|= ok - | `Block_fees -> return_true - (* TODO: remove in J *) - | `Legacy_deposits (delegate, cycle) -> - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Legacy_frozen_deposits.mem (ctxt, contract) cycle >|= ok - | `Legacy_fees (delegate, cycle) -> - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Legacy_frozen_fees.mem (ctxt, contract) cycle >|= ok - | `Legacy_rewards (delegate, cycle) -> - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Legacy_frozen_rewards.mem (ctxt, contract) cycle >|= ok - -let balance ctxt stored = - match stored with - | `Contract contract -> Contract_storage.get_balance ctxt contract - | `Collected_commitments bpkh -> Commitment_storage.committed_amount ctxt bpkh - | `Delegate_balance delegate -> - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Balance.get ctxt contract - | `Frozen_deposits delegate -> ( - let contract = Contract_repr.implicit_contract delegate in - Frozen_deposits_storage.find ctxt contract >|=? fun frozen_deposits -> - match frozen_deposits with - | None -> Tez_repr.zero - | Some frozen_deposits -> frozen_deposits.current_amount) - | `Block_fees -> return (Raw_context.get_collected_fees ctxt) - (* TODO: remove in J *) - | `Legacy_deposits (delegate, cycle) -> - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Legacy_frozen_deposits.find (ctxt, contract) cycle - >|=? Option.value ~default:Tez_repr.zero - | `Legacy_fees (delegate, cycle) -> - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Legacy_frozen_fees.find (ctxt, contract) cycle - >|=? Option.value ~default:Tez_repr.zero - | `Legacy_rewards (delegate, cycle) -> - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Legacy_frozen_rewards.find (ctxt, contract) cycle - >|=? Option.value ~default:Tez_repr.zero - -let credit ctxt dest amount origin = - let open Receipt_repr in - (match dest with - | `Storage_fees -> return (ctxt, Storage_fees) - | `Double_signing_punishments -> return (ctxt, Double_signing_punishments) - | `Lost_endorsing_rewards (d, p, r) -> - return (ctxt, Lost_endorsing_rewards (d, p, r)) - | `Burned -> return (ctxt, Burned) - | `Contract dest -> - Contract_storage.credit_only_call_from_token ctxt dest amount - >|=? fun ctxt -> (ctxt, Contract dest) - | `Collected_commitments bpkh -> - Commitment_storage.increase_commitment_only_call_from_token - ctxt - bpkh - amount - >|=? fun ctxt -> (ctxt, Commitments bpkh) - | `Delegate_balance delegate -> - let contract = Contract_repr.implicit_contract delegate in - Contract_storage.increase_balance_only_call_from_token - ctxt - contract - amount - >|=? fun ctxt -> (ctxt, Contract contract) - | `Frozen_deposits delegate as dest -> - allocated ctxt dest >>=? fun allocated -> - (if not allocated then Frozen_deposits_storage.init ctxt delegate - else return ctxt) - >>=? fun ctxt -> - Frozen_deposits_storage.credit_only_call_from_token ctxt delegate amount - >|=? fun ctxt -> (ctxt, Deposits delegate) - | `Block_fees -> - Raw_context.credit_collected_fees_only_call_from_token ctxt amount - >>?= fun ctxt -> return (ctxt, Block_fees) - (* TODO: remove in J *) - | `Legacy_deposits (delegate, cycle) as dest -> - let contract = Contract_repr.implicit_contract delegate in - balance ctxt dest >>=? fun old_amount -> - Tez_repr.(old_amount +? amount) >>?= fun new_amount -> - Storage.Contract.Legacy_frozen_deposits.add - (ctxt, contract) - cycle - new_amount - >>= fun ctxt -> return (ctxt, Legacy_deposits (delegate, cycle)) - | `Legacy_fees (delegate, cycle) as dest -> - let contract = Contract_repr.implicit_contract delegate in - balance ctxt dest >>=? fun old_amount -> - Tez_repr.(old_amount +? amount) >>?= fun new_amount -> - Storage.Contract.Legacy_frozen_fees.add (ctxt, contract) cycle new_amount - >>= fun ctxt -> return (ctxt, Legacy_fees (delegate, cycle)) - | `Legacy_rewards (delegate, cycle) as dest -> - let contract = Contract_repr.implicit_contract delegate in - balance ctxt dest >>=? fun old_amount -> - Tez_repr.(old_amount +? amount) >>?= fun new_amount -> - Storage.Contract.Legacy_frozen_rewards.add - (ctxt, contract) - cycle - new_amount - >>= fun ctxt -> return (ctxt, Legacy_rewards (delegate, cycle))) - >|=? fun (ctxt, balance) -> (ctxt, (balance, Credited amount, origin)) - -let spend ctxt src amount origin = - let open Receipt_repr in - (match src with - | `Bootstrap -> return (ctxt, Bootstrap) - | `Invoice -> return (ctxt, Invoice) - | `Initial_commitments -> return (ctxt, Initial_commitments) - | `Minted -> return (ctxt, Minted) - | `Liquidity_baking_subsidies -> return (ctxt, Liquidity_baking_subsidies) - | `Revelation_rewards -> return (ctxt, Nonce_revelation_rewards) - | `Double_signing_evidence_rewards -> - return (ctxt, Double_signing_evidence_rewards) - | `Endorsing_rewards -> return (ctxt, Endorsing_rewards) - | `Baking_rewards -> return (ctxt, Baking_rewards) - | `Baking_bonuses -> return (ctxt, Baking_bonuses) - | `Contract src -> - Contract_storage.spend_only_call_from_token ctxt src amount - >|=? fun ctxt -> (ctxt, Contract src) - | `Collected_commitments bpkh -> - Commitment_storage.decrease_commitment_only_call_from_token - ctxt - bpkh - amount - >>=? fun ctxt -> return (ctxt, Commitments bpkh) - | `Delegate_balance delegate -> - let contract = Contract_repr.implicit_contract delegate in - Contract_storage.decrease_balance_only_call_from_token - ctxt - contract - amount - >|=? fun ctxt -> (ctxt, Contract contract) - | `Frozen_deposits delegate -> - (if Tez_repr.(amount = zero) then return ctxt - else - Frozen_deposits_storage.spend_only_call_from_token ctxt delegate amount) - >>=? fun ctxt -> return (ctxt, Deposits delegate) - | `Block_fees -> - Raw_context.spend_collected_fees_only_call_from_token ctxt amount - >>?= fun ctxt -> return (ctxt, Block_fees) - (* TODO: remove in J *) - | `Legacy_deposits (delegate, cycle) as src -> - balance ctxt src >>=? fun old_amount -> - Tez_repr.(old_amount -? amount) >>?= fun new_amount -> - let contract = Contract_repr.implicit_contract delegate in - (if Tez_repr.(new_amount = zero) then - Storage.Contract.Legacy_frozen_deposits.remove (ctxt, contract) cycle - else - Storage.Contract.Legacy_frozen_deposits.add - (ctxt, contract) - cycle - new_amount) - >>= fun ctxt -> return (ctxt, Legacy_deposits (delegate, cycle)) - | `Legacy_fees (delegate, cycle) as src -> - balance ctxt src >>=? fun old_amount -> - Tez_repr.(old_amount -? amount) >>?= fun new_amount -> - let contract = Contract_repr.implicit_contract delegate in - (if Tez_repr.(new_amount = zero) then - Storage.Contract.Legacy_frozen_fees.remove (ctxt, contract) cycle - else - Storage.Contract.Legacy_frozen_fees.add - (ctxt, contract) - cycle - new_amount) - >>= fun ctxt -> return (ctxt, Legacy_fees (delegate, cycle)) - | `Legacy_rewards (delegate, cycle) as src -> - balance ctxt src >>=? fun old_amount -> - Tez_repr.(old_amount -? amount) >>?= fun new_amount -> - let contract = Contract_repr.implicit_contract delegate in - (if Tez_repr.(new_amount = zero) then - Storage.Contract.Legacy_frozen_rewards.remove (ctxt, contract) cycle - else - Storage.Contract.Legacy_frozen_rewards.add - (ctxt, contract) - cycle - new_amount) - >>= fun ctxt -> return (ctxt, Legacy_rewards (delegate, cycle))) - >|=? fun (ctxt, balance) -> (ctxt, (balance, Debited amount, origin)) - -let transfer_n ?(origin = Receipt_repr.Block_application) ctxt src dest = - let sources = List.filter (fun (_, am) -> Tez_repr.(am <> zero)) src in - match sources with - | [] -> - (* Avoid accessing context data when there is nothing to transfer. *) - return (ctxt, []) - | _ :: _ -> - List.fold_left_es - (fun (ctxt, total, debit_logs) (source, amount) -> - spend ctxt source amount origin >>=? fun (ctxt, debit_log) -> - Tez_repr.(amount +? total) >>?= fun total -> - return (ctxt, total, debit_log :: debit_logs)) - (ctxt, Tez_repr.zero, []) - sources - >>=? fun (ctxt, amount, debit_logs) -> - credit ctxt dest amount origin >|=? fun (ctxt, credit_log) -> - (* Make sure the order of balance updates is : debit logs in the order of - of the parameter [src], and then the credit log. *) - let balance_updates = List.rev (credit_log :: debit_logs) in - (ctxt, balance_updates) - -let transfer ?(origin = Receipt_repr.Block_application) ctxt src dest amount = - transfer_n ~origin ctxt [(src, amount)] dest diff --git a/src/proto_012_Psithaca/lib_protocol/token.mli b/src/proto_012_Psithaca/lib_protocol/token.mli deleted file mode 100644 index ef8c0eabcdca..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/token.mli +++ /dev/null @@ -1,134 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020-2021 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** The aim of this module is to manage operations involving tokens such as - minting, transferring, and burning. Every constructor of the types [source], - [container], or [sink] represents a kind of account that holds a given (or - possibly infinite) amount of tokens. - - Tokens can be transferred from a [source] to a [sink]. To uniformly handle - all cases, special constructors of sources and sinks may be used. For - example, the source [`Minted] is used to express a transfer of minted tokens - to a destination, and the sink [`Burned] is used to express the action of - burning a given amount of tokens taken from a source. Thanks to uniformity, - it is easier to track transfers of tokens throughout the protocol by running - [grep -R "Token.transfer" src/proto_alpha]. *) - -(** [container] is the type of token holders with finite capacity, and whose assets - are contained in the context. Let [d] be a delegate. Be aware that transferring - to/from [`Delegate_balance d] will not update [d]'s stake, while transferring - to/from [`Contract (Contract_repr.implicit_contract d)] will update [d]'s - stake. *) -type container = - [ `Contract of Contract_repr.t - | `Collected_commitments of Blinded_public_key_hash.t - | `Delegate_balance of Signature.Public_key_hash.t - | `Frozen_deposits of Signature.Public_key_hash.t - | `Block_fees - | `Legacy_deposits of Signature.Public_key_hash.t * Cycle_repr.t - | `Legacy_fees of Signature.Public_key_hash.t * Cycle_repr.t - | `Legacy_rewards of Signature.Public_key_hash.t * Cycle_repr.t ] - -(** [source] is the type of token providers. Token providers that are not - containers are considered to have infinite capacity. *) -type source = - [ `Invoice - | `Bootstrap - | `Initial_commitments - | `Revelation_rewards - | `Double_signing_evidence_rewards - | `Endorsing_rewards - | `Baking_rewards - | `Baking_bonuses - | `Minted - | `Liquidity_baking_subsidies - | container ] - -(** [sink] is the type of token receivers. Token receivers that are not - containers are considered to have infinite capacity. *) -type sink = - [ `Storage_fees - | `Double_signing_punishments - | `Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool - | `Burned - | container ] - -(** [allocated ctxt container] returns true if [balance ctxt container] is - guaranteed not to fail, and returns false when [balance ctxt container] may - fail. *) -val allocated : Raw_context.t -> container -> bool tzresult Lwt.t - -(** [balance ctxt container] returns the balance associated to the token holder, - may fail if [allocated ctxt container] returns [false]. - Returns an error with the message "get_balance" if [container] refers to an - originated contract that is not allocated. - Returns a {!Storage_Error Missing_key} error if [container] is of the form - [`Delegate_balance pkh], where [pkh] refers to an implicit contract that is - not allocated. *) -val balance : Raw_context.t -> container -> Tez_repr.t tzresult Lwt.t - -(** [transfer_n ?origin ctxt sources dest] transfers [amount] Tez from [src] to - [dest] for each [(src, amount)] pair in [sources], and returns a new - context, and the list of corresponding balance updates. The function behaves - as though [transfer src dest amount] was invoked for each pair - [(src, amount)] in [sources], however a single balance update is generated - for the total amount transferred to [dest]. - When [sources] is an empty list, the function does nothing to the context, - and returns an empty list of balance updates. *) -val transfer_n : - ?origin:Receipt_repr.update_origin -> - Raw_context.t -> - ([< source] * Tez_repr.t) list -> - [< sink] -> - (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t - -(** [transfer ?origin ctxt src dest amount] transfers [amount] Tez from source - [src] to destination [dest], and returns a new context, and the list of - corresponding balance updates tagged with [origin]. By default, [~origin] is - set to [Receipt_repr.Block_application]. - Returns {!Storage_Error Missing_key} if [src] refers to a contract that is - not allocated. - Returns a [Balance_too_low] error if [src] refers to a contract whose - balance is less than [amount]. - Returns a [Subtraction_underflow] error if [src] refers to a source that is - not a contract and whose balance is less than [amount]. - Returns a [Empty_implicit_delegated_contract] error if [src] is an - implicit contract that delegates to a different contract, and whose balance - is equal to [amount]. - Returns a [Non_existing_contract] error if - [dest] refers to an originated contract that is not allocated. - Returns a [Non_existing_contract] error if [amount <> Tez_repr.zero], and - [dest] refers to an originated contract that is not allocated. - Returns a [Addition_overflow] error if [dest] refers to a sink whose balance - is greater than [Int64.max - amount]. - Returns a [Wrong_level] error if [src] or [dest] refer to a level that is - not the current level. *) -val transfer : - ?origin:Receipt_repr.update_origin -> - Raw_context.t -> - [< source] -> - [< sink] -> - Tez_repr.t -> - (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/vote_repr.ml b/src/proto_012_Psithaca/lib_protocol/vote_repr.ml deleted file mode 100644 index e94cc33ddf52..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/vote_repr.ml +++ /dev/null @@ -1,42 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type proposal = Protocol_hash.t - -type ballot = Yay | Nay | Pass - -let ballot_encoding = - let of_int8 = function - | 0 -> Ok Yay - | 1 -> Ok Nay - | 2 -> Ok Pass - | _ -> Error "ballot_of_int8" - in - let to_int8 = function Yay -> 0 | Nay -> 1 | Pass -> 2 in - let open Data_encoding in - (* union *) - splitted - ~binary:(conv_with_guard to_int8 of_int8 int8) - ~json:(string_enum [("yay", Yay); ("nay", Nay); ("pass", Pass)]) diff --git a/src/proto_012_Psithaca/lib_protocol/vote_repr.mli b/src/proto_012_Psithaca/lib_protocol/vote_repr.mli deleted file mode 100644 index 8a7d4a59b685..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/vote_repr.mli +++ /dev/null @@ -1,33 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** a protocol change proposal *) -type proposal = Protocol_hash.t - -(** votes can be for, against or neutral. - Neutral serves to count towards a quorum *) -type ballot = Yay | Nay | Pass - -val ballot_encoding : ballot Data_encoding.t diff --git a/src/proto_012_Psithaca/lib_protocol/vote_storage.ml b/src/proto_012_Psithaca/lib_protocol/vote_storage.ml deleted file mode 100644 index 3ceec4c6e4e0..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/vote_storage.ml +++ /dev/null @@ -1,169 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -let recorded_proposal_count_for_delegate ctxt proposer = - Storage.Vote.Proposals_count.find ctxt proposer >|=? Option.value ~default:0 - -let record_proposal ctxt proposal proposer = - recorded_proposal_count_for_delegate ctxt proposer >>=? fun count -> - Storage.Vote.Proposals_count.add ctxt proposer (count + 1) >>= fun ctxt -> - Storage.Vote.Proposals.add ctxt (proposal, proposer) >|= ok - -let get_proposals ctxt = - Storage.Vote.Proposals.fold - ctxt - ~order:`Sorted - ~init:(ok Protocol_hash.Map.empty) - ~f:(fun (proposal, delegate) acc -> - (* Assuming the same listings is used at votings *) - Storage.Vote.Listings.get ctxt delegate >>=? fun weight -> - Lwt.return - ( acc >|? fun acc -> - let previous = - match Protocol_hash.Map.find proposal acc with - | None -> 0l - | Some x -> x - in - Protocol_hash.Map.add proposal (Int32.add weight previous) acc )) - -let clear_proposals ctxt = - Storage.Vote.Proposals_count.clear ctxt >>= fun ctxt -> - Storage.Vote.Proposals.clear ctxt - -type ballots = {yay : int32; nay : int32; pass : int32} - -let ballots_encoding = - let open Data_encoding in - conv - (fun {yay; nay; pass} -> (yay, nay, pass)) - (fun (yay, nay, pass) -> {yay; nay; pass}) - @@ obj3 (req "yay" int32) (req "nay" int32) (req "pass" int32) - -let has_recorded_ballot = Storage.Vote.Ballots.mem - -let record_ballot = Storage.Vote.Ballots.init - -let get_ballots ctxt = - Storage.Vote.Ballots.fold - ctxt - ~order:`Sorted - ~f:(fun delegate ballot (ballots : ballots tzresult) -> - (* Assuming the same listings is used at votings *) - Storage.Vote.Listings.get ctxt delegate >>=? fun weight -> - let count = Int32.add weight in - Lwt.return - ( ballots >|? fun ballots -> - match ballot with - | Yay -> {ballots with yay = count ballots.yay} - | Nay -> {ballots with nay = count ballots.nay} - | Pass -> {ballots with pass = count ballots.pass} )) - ~init:(ok {yay = 0l; nay = 0l; pass = 0l}) - -let get_ballot_list = Storage.Vote.Ballots.bindings - -let clear_ballots = Storage.Vote.Ballots.clear - -let listings_encoding = - Data_encoding.( - list - (obj2 (req "pkh" Signature.Public_key_hash.encoding) (req "rolls" int32))) - -let update_listings ctxt = - Storage.Vote.Listings.clear ctxt >>= fun ctxt -> - let tokens_per_roll = - Tez_repr.to_mutez (Constants_storage.tokens_per_roll ctxt) - in - Stake_storage.fold - ctxt - (ctxt, 0l) - ~order:`Sorted - ~f:(fun (delegate, stake) (ctxt, total) -> - let nb_rolls = - Int64.to_int32 @@ Int64.div (Tez_repr.to_mutez stake) tokens_per_roll - in - Storage.Vote.Listings.init ctxt delegate nb_rolls >|=? fun ctxt -> - (ctxt, Int32.add total nb_rolls)) - >>=? fun (ctxt, total) -> - Storage.Vote.Listings_size.add ctxt total >>= fun ctxt -> return ctxt - -let listing_size = Storage.Vote.Listings_size.get - -let in_listings = Storage.Vote.Listings.mem - -let get_listings = Storage.Vote.Listings.bindings - -let get_voting_power_free ctxt owner = - Storage.Vote.Listings.find ctxt owner >|=? Option.value ~default:0l - -(* This function bypasses the carbonated functors to account for gas consumption. - This is a temporary situation intended to be fixed by adding the right - carbonated functors in a future amendment *) -let get_voting_power ctxt owner = - let open Raw_context in - (* Always consume read access to memory *) - (* Accessing an int32 at /votes/listings// *) - consume_gas ctxt (Storage_costs.read_access ~path_length:4 ~read_bytes:4) - >>?= fun ctxt -> - Storage.Vote.Listings.find ctxt owner >|=? function - | None -> (ctxt, 0l) - | Some power -> (ctxt, power) - -let get_total_voting_power_free = listing_size - -(* This function bypasses the carbonated functors to account for gas consumption. - This is a temporary situation intended to be fixed by adding the right - carbonated functors in a future amendment *) -let get_total_voting_power ctxt = - let open Raw_context in - (* Accessing an int32 at /votes/listings_size *) - consume_gas ctxt (Storage_costs.read_access ~path_length:2 ~read_bytes:4) - >>?= fun ctxt -> - get_total_voting_power_free ctxt >|=? fun total_voting_power -> - (ctxt, total_voting_power) - -let get_current_quorum ctxt = - Storage.Vote.Participation_ema.get ctxt >|=? fun participation_ema -> - let quorum_min = Constants_storage.quorum_min ctxt in - let quorum_max = Constants_storage.quorum_max ctxt in - let quorum_diff = Int32.sub quorum_max quorum_min in - Int32.(add quorum_min (div (mul participation_ema quorum_diff) 100_00l)) - -let get_participation_ema = Storage.Vote.Participation_ema.get - -let set_participation_ema = Storage.Vote.Participation_ema.update - -let get_current_proposal = Storage.Vote.Current_proposal.get - -let find_current_proposal = Storage.Vote.Current_proposal.find - -let init_current_proposal = Storage.Vote.Current_proposal.init - -let clear_current_proposal = Storage.Vote.Current_proposal.remove_existing - -let init ctxt ~start_position = - (* participation EMA is in centile of a percentage *) - let participation_ema = Constants_storage.quorum_max ctxt in - Storage.Vote.Participation_ema.init ctxt participation_ema >>=? fun ctxt -> - Voting_period_storage.init_first_period ctxt ~start_position diff --git a/src/proto_012_Psithaca/lib_protocol/vote_storage.mli b/src/proto_012_Psithaca/lib_protocol/vote_storage.mli deleted file mode 100644 index 5bfc0ae34eb5..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/vote_storage.mli +++ /dev/null @@ -1,116 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** Manages all the voting related storage in Storage.Vote. *) - -(** Records a protocol proposal with the delegate that proposed it. *) -val record_proposal : - Raw_context.t -> - Protocol_hash.t -> - Signature.Public_key_hash.t -> - Raw_context.t tzresult Lwt.t - -val recorded_proposal_count_for_delegate : - Raw_context.t -> Signature.Public_key_hash.t -> int tzresult Lwt.t - -(** Computes for each proposal how many delegates proposed it. *) -val get_proposals : Raw_context.t -> int32 Protocol_hash.Map.t tzresult Lwt.t - -val clear_proposals : Raw_context.t -> Raw_context.t Lwt.t - -(** Counts of the votes *) -type ballots = {yay : int32; nay : int32; pass : int32} - -val ballots_encoding : ballots Data_encoding.t - -val has_recorded_ballot : - Raw_context.t -> Signature.Public_key_hash.t -> bool Lwt.t - -(** Records a vote for a delegate, returns a {!Storage_error Existing_key} if - the vote was already registered *) -val record_ballot : - Raw_context.t -> - Signature.Public_key_hash.t -> - Vote_repr.ballot -> - Raw_context.t tzresult Lwt.t - -(** Computes the sum of the current ballots weighted by stake. *) -val get_ballots : Raw_context.t -> ballots tzresult Lwt.t - -val get_ballot_list : - Raw_context.t -> (Signature.Public_key_hash.t * Vote_repr.ballot) list Lwt.t - -val clear_ballots : Raw_context.t -> Raw_context.t Lwt.t - -val listings_encoding : - (Signature.Public_key_hash.t * int32) list Data_encoding.t - -(** Populates [!Storage.Vote.Listings] using the currently existing rolls and - sets Listings_size. Delegates without rolls are not included in the listing. *) -val update_listings : Raw_context.t -> Raw_context.t tzresult Lwt.t - -(** Returns the sum of all rolls of all delegates. *) -val listing_size : Raw_context.t -> int32 tzresult Lwt.t - -(** Verifies the presence of a delegate in the listing. *) -val in_listings : Raw_context.t -> Signature.Public_key_hash.t -> bool Lwt.t - -val get_listings : - Raw_context.t -> (Signature.Public_key_hash.t * int32) list Lwt.t - -val get_voting_power_free : - Raw_context.t -> Signature.public_key_hash -> int32 tzresult Lwt.t - -val get_voting_power : - Raw_context.t -> - Signature.public_key_hash -> - (Raw_context.t * int32) tzresult Lwt.t - -val get_total_voting_power_free : Raw_context.t -> int32 tzresult Lwt.t - -val get_total_voting_power : - Raw_context.t -> (Raw_context.t * int32) tzresult Lwt.t - -val get_current_quorum : Raw_context.t -> int32 tzresult Lwt.t - -val get_participation_ema : Raw_context.t -> int32 tzresult Lwt.t - -val set_participation_ema : - Raw_context.t -> int32 -> Raw_context.t tzresult Lwt.t - -val get_current_proposal : Raw_context.t -> Protocol_hash.t tzresult Lwt.t - -val find_current_proposal : - Raw_context.t -> Protocol_hash.t option tzresult Lwt.t - -val init_current_proposal : - Raw_context.t -> Protocol_hash.t -> Raw_context.t tzresult Lwt.t - -val clear_current_proposal : Raw_context.t -> Raw_context.t tzresult Lwt.t - -(** Sets the initial quorum to 80% and period kind to proposal. *) -val init : - Raw_context.t -> start_position:Int32.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/voting_period_repr.ml b/src/proto_012_Psithaca/lib_protocol/voting_period_repr.ml deleted file mode 100644 index de4cf915bc46..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/voting_period_repr.ml +++ /dev/null @@ -1,175 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -type kind = Proposal | Exploration | Cooldown | Promotion | Adoption - -let string_of_kind = function - | Proposal -> "proposal" - | Exploration -> "exploration" - | Cooldown -> "cooldown" - | Promotion -> "promotion" - | Adoption -> "adoption" - -let pp_kind ppf kind = Format.fprintf ppf "%s" @@ string_of_kind kind - -let kind_encoding = - let open Data_encoding in - union - ~tag_size:`Uint8 - [ - case - (Tag 0) - ~title:"Proposal" - (constant "proposal") - (function Proposal -> Some () | _ -> None) - (fun () -> Proposal); - case - (Tag 1) - ~title:"exploration" - (constant "exploration") - (function Exploration -> Some () | _ -> None) - (fun () -> Exploration); - case - (Tag 2) - ~title:"Cooldown" - (constant "cooldown") - (function Cooldown -> Some () | _ -> None) - (fun () -> Cooldown); - case - (Tag 3) - ~title:"Promotion" - (constant "promotion") - (function Promotion -> Some () | _ -> None) - (fun () -> Promotion); - case - (Tag 4) - ~title:"Adoption" - (constant "adoption") - (function Adoption -> Some () | _ -> None) - (fun () -> Adoption); - ] - -let succ_kind = function - | Proposal -> Exploration - | Exploration -> Cooldown - | Cooldown -> Promotion - | Promotion -> Adoption - | Adoption -> Proposal - -type voting_period = {index : int32; kind : kind; start_position : int32} - -type t = voting_period - -type info = {voting_period : t; position : int32; remaining : int32} - -let root ~start_position = {index = 0l; kind = Proposal; start_position} - -let pp ppf {index; kind; start_position} = - Format.fprintf - ppf - "@[index: %ld,@ kind:%a,@ start_position: %ld@]" - index - pp_kind - kind - start_position - -let pp_info ppf {voting_period; position; remaining} = - Format.fprintf - ppf - "@[voting_period: %a,@ position:%ld,@ remaining: %ld@]" - pp - voting_period - position - remaining - -let encoding = - let open Data_encoding in - conv - (fun {index; kind; start_position} -> (index, kind, start_position)) - (fun (index, kind, start_position) -> {index; kind; start_position}) - (obj3 - (req - "index" - ~description: - "The voting period's index. Starts at 0 with the first block of \ - the Alpha family of protocols." - int32) - (req - ~description: - "One of the several kinds of periods in the voting procedure." - "kind" - kind_encoding) - (req - ~description: - "The relative position of the first level of the period with \ - respect to the first level of the Alpha family of protocols." - "start_position" - int32)) - -let info_encoding = - let open Data_encoding in - conv - (fun {voting_period; position; remaining} -> - (voting_period, position, remaining)) - (fun (voting_period, position, remaining) -> - {voting_period; position; remaining}) - (obj3 - (req - ~description:"The voting period to which the block belongs." - "voting_period" - encoding) - (req - ~description:"The position of the block within the voting period." - "position" - int32) - (req - ~description: - "The number of blocks remaining till the end of the voting period." - "remaining" - int32)) - -include Compare.Make (struct - type nonrec t = t - - let compare p p' = Compare.Int32.compare p.index p'.index -end) - -let raw_reset period ~start_position = - let index = Int32.succ period.index in - let kind = Proposal in - {index; kind; start_position} - -let raw_succ period ~start_position = - let index = Int32.succ period.index in - let kind = succ_kind period.kind in - {index; kind; start_position} - -let position_since (level : Level_repr.t) (voting_period : t) = - Int32.(sub level.level_position voting_period.start_position) - -let remaining_blocks (level : Level_repr.t) (voting_period : t) - ~blocks_per_voting_period = - let position = position_since level voting_period in - Int32.(sub blocks_per_voting_period (succ position)) diff --git a/src/proto_012_Psithaca/lib_protocol/voting_period_repr.mli b/src/proto_012_Psithaca/lib_protocol/voting_period_repr.mli deleted file mode 100644 index 028281ec567e..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/voting_period_repr.mli +++ /dev/null @@ -1,82 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** The voting period kinds are ordered as follows: - Proposal -> Testing_vote -> Testing -> Promotion -> Adoption. - This order is the one used be the function [succ] below. - *) -type kind = - | Proposal (** protocols can be proposed *) - | Exploration (** a proposal can be voted *) - | Cooldown (** a delay before the second vote of the Promotion period. *) - | Promotion (** activation can be voted *) - | Adoption (** a delay before activation *) - -val kind_encoding : kind Data_encoding.t - -(** A voting period can be of several kinds and is uniquely identified by - the counter 'index'. The 'start_position' represents the relative - position of the first level of the period with respect to the - first level of the Alpha family of protocols. *) -type voting_period = {index : Int32.t; kind : kind; start_position : Int32.t} - -type t = voting_period - -(** Information about a block with respect to the voting period it - belongs to: the voting period, the position within the voting - period and the number of remaining blocks till the end of the - period. The following invariant is satisfied: - `position + remaining + 1 = blocks_per_voting_period` *) -type info = {voting_period : t; position : Int32.t; remaining : Int32.t} - -val root : start_position:Int32.t -> t - -include Compare.S with type t := voting_period - -val encoding : t Data_encoding.t - -val info_encoding : info Data_encoding.t - -val pp : Format.formatter -> t -> unit - -val pp_info : Format.formatter -> info -> unit - -val pp_kind : Format.formatter -> kind -> unit - -(** [raw_reset period ~start_position] increment the index by one and set the - kind to Proposal which is the period kind that start the voting - process. [start_position] is the level at wich this voting_period started. -*) -val raw_reset : t -> start_position:Int32.t -> t - -(** [raw_succ period ~start_position] increment the index by one and set the - kind to its successor. [start_position] is the level at which this - voting_period started. *) -val raw_succ : t -> start_position:Int32.t -> t - -val position_since : Level_repr.t -> t -> Int32.t - -val remaining_blocks : - Level_repr.t -> t -> blocks_per_voting_period:Int32.t -> Int32.t diff --git a/src/proto_012_Psithaca/lib_protocol/voting_period_storage.ml b/src/proto_012_Psithaca/lib_protocol/voting_period_storage.ml deleted file mode 100644 index b6a9156bb7a1..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/voting_period_storage.ml +++ /dev/null @@ -1,191 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(* - The shell uses the convention that a context at level n is the resulting - context of the application of block n. - Therefore when using an RPC on the last level of a voting period, the context - that is inspected is the resulting one. - - However [Amendment.may_start_new_voting_period] is run at the end of voting - period and it has to prepare the context for validating operations of the next - period. This causes the counter-intuitive result that the info returned by RPCs - at last level of a voting period mention data of the next voting period. - - For example, when validating the last block of a proposal period at level n - we have: - - Input context: - - voting_period = { kind = Proposal; - index = i; - start_position = n - blocks_per_voting_period} - - - position = n - start_position = blocks_per_voting_period - - remaining = blocks_per_voting_period - (position + 1) = 0 - - - Output context: - - voting_period = { kind = Exploration; - index = i + 1; - start_position = n + 1} - - Now if we calculate position and remaining in the voting period we get - strange results: - - position = n - (n + 1) = -1 - - remaining = blocks_per_voting_period - - To work around this issue, two RPCs were added - `Voting_period_storage.get_rpc_current_info`, which returns the correct - info also for the last context of a period, and - `Voting_period_storage.get_rpc_succ_info`, which can be used at the last - context of a period to craft operations that will be valid for the first - block of the new period. - - This odd behaviour could be fixed if [Amendment.may_start_new_voting_period] - was called when we start validating the first block of a voting period instead - that at the end of the validation of the last block of a voting period. - This should be carefully done because the voting period listing depends on - the rolls and it might break some invariant. - - When this is implemented one should: - - edit the function [reset_current] and [inc_current] to use the - current level and not the next one. - - remove the storage for pred_kind - - make Voting_period_repr.t abstract - - You can also look at the MR description here: - https://gitlab.com/metastatedev/tezos/-/merge_requests/333 - *) - -(* Voting periods start at the first block of a cycle. More formally, - the invariant of start_position with respect to cycle_position is: - cycle_position mod blocks_per_cycle == - position_in_period mod blocks_per_cycle *) - -let set_current = Storage.Vote.Current_period.update - -let get_current = Storage.Vote.Current_period.get - -let init = Storage.Vote.Current_period.init - -let init_first_period ctxt ~start_position = - init ctxt @@ Voting_period_repr.root ~start_position >>=? fun ctxt -> - Storage.Vote.Pred_period_kind.init ctxt Voting_period_repr.Proposal - -let common ctxt = - get_current ctxt >>=? fun current_period -> - Storage.Vote.Pred_period_kind.update ctxt current_period.kind >|=? fun ctxt -> - let start_position = - (* because we are preparing the voting period for the next block we need to - use the next level. *) - Int32.succ (Level_storage.current ctxt).level_position - in - (ctxt, current_period, start_position) - -let reset ctxt = - common ctxt >>=? fun (ctxt, current_period, start_position) -> - Voting_period_repr.raw_reset current_period ~start_position - |> set_current ctxt - -let succ ctxt = - common ctxt >>=? fun (ctxt, current_period, start_position) -> - Voting_period_repr.raw_succ current_period ~start_position |> set_current ctxt - -let get_current_kind ctxt = get_current ctxt >|=? fun {kind; _} -> kind - -let get_current_info ctxt = - get_current ctxt >|=? fun voting_period -> - let blocks_per_voting_period = - Constants_storage.blocks_per_voting_period ctxt - in - let level = Level_storage.current ctxt in - let position = Voting_period_repr.position_since level voting_period in - let remaining = - Voting_period_repr.remaining_blocks - level - voting_period - ~blocks_per_voting_period - in - Voting_period_repr.{voting_period; position; remaining} - -let get_current_remaining ctxt = - get_current ctxt >|=? fun voting_period -> - let blocks_per_voting_period = - Constants_storage.blocks_per_voting_period ctxt - in - Voting_period_repr.remaining_blocks - (Level_storage.current ctxt) - voting_period - ~blocks_per_voting_period - -let is_last_block ctxt = - get_current_remaining ctxt >|=? fun remaining -> - Compare.Int32.(remaining = 0l) - -let get_rpc_current_info ctxt = - get_current_info ctxt - >>=? fun ({voting_period; position; _} as voting_period_info) -> - if Compare.Int32.(position = Int32.minus_one) then - let level = Level_storage.current ctxt in - let blocks_per_voting_period = - Constants_storage.blocks_per_voting_period ctxt - in - Storage.Vote.Pred_period_kind.get ctxt >|=? fun pred_kind -> - let voting_period : Voting_period_repr.t = - { - index = Int32.pred voting_period.index; - kind = pred_kind; - start_position = - Int32.(sub voting_period.start_position blocks_per_voting_period); - } - in - let position = Voting_period_repr.position_since level voting_period in - let remaining = - Voting_period_repr.remaining_blocks - level - voting_period - ~blocks_per_voting_period - in - ({voting_period; remaining; position} : Voting_period_repr.info) - else return voting_period_info - -let get_rpc_succ_info ctxt = - Level_storage.from_raw_with_offset - ctxt - ~offset:1l - (Level_storage.current ctxt).level - >>?= fun level -> - get_current ctxt >|=? fun voting_period -> - let blocks_per_voting_period = - Constants_storage.blocks_per_voting_period ctxt - in - let position = Voting_period_repr.position_since level voting_period in - let remaining = - Voting_period_repr.remaining_blocks - level - voting_period - ~blocks_per_voting_period - in - Voting_period_repr.{voting_period; position; remaining} diff --git a/src/proto_012_Psithaca/lib_protocol/voting_period_storage.mli b/src/proto_012_Psithaca/lib_protocol/voting_period_storage.mli deleted file mode 100644 index f18dc5e9aa10..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/voting_period_storage.mli +++ /dev/null @@ -1,51 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2020 Metastate AG *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -val init : Raw_context.t -> Voting_period_repr.t -> Raw_context.t tzresult Lwt.t - -(** Sets the initial period to [{voting_period = root; kind = Proposal; - start_position}]. *) -val init_first_period : - Raw_context.t -> start_position:Int32.t -> Raw_context.t tzresult Lwt.t - -(** Increment the index by one and set the kind to Proposal. *) -val reset : Raw_context.t -> Raw_context.t tzresult Lwt.t - -(** Increment the index by one and set the kind to its successor. *) -val succ : Raw_context.t -> Raw_context.t tzresult Lwt.t - -val get_current : Raw_context.t -> Voting_period_repr.t tzresult Lwt.t - -val get_current_kind : Raw_context.t -> Voting_period_repr.kind tzresult Lwt.t - -(** Returns true if the context level is the last of current voting period. *) -val is_last_block : Raw_context.t -> bool tzresult Lwt.t - -(** Returns the voting period information for the current level. *) -val get_rpc_current_info : - Raw_context.t -> Voting_period_repr.info tzresult Lwt.t - -(** Returns the voting period information for the next level. *) -val get_rpc_succ_info : Raw_context.t -> Voting_period_repr.info tzresult Lwt.t diff --git a/src/proto_012_Psithaca/lib_protocol/voting_services.ml b/src/proto_012_Psithaca/lib_protocol/voting_services.ml deleted file mode 100644 index 0ff6088eb536..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/voting_services.ml +++ /dev/null @@ -1,152 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -module S = struct - let path = RPC_path.(open_root / "votes") - - let ballots = - RPC_service.get_service - ~description:"Sum of ballots casted so far during a voting period." - ~query:RPC_query.empty - ~output:Vote.ballots_encoding - RPC_path.(path / "ballots") - - let ballot_list = - RPC_service.get_service - ~description:"Ballots casted so far during a voting period." - ~query:RPC_query.empty - ~output: - Data_encoding.( - list - (obj2 - (req "pkh" Signature.Public_key_hash.encoding) - (req "ballot" Vote.ballot_encoding))) - RPC_path.(path / "ballot_list") - - let current_period = - RPC_service.get_service - ~description: - "Returns the voting period (index, kind, starting position) and \ - related information (position, remaining) of the interrogated block." - ~query:RPC_query.empty - ~output:Voting_period.info_encoding - RPC_path.(path / "current_period") - - let successor_period = - RPC_service.get_service - ~description: - "Returns the voting period (index, kind, starting position) and \ - related information (position, remaining) of the next block.Useful to \ - craft operations that will be valid in the next block." - ~query:RPC_query.empty - ~output:Voting_period.info_encoding - RPC_path.(path / "successor_period") - - let current_quorum = - RPC_service.get_service - ~description:"Current expected quorum." - ~query:RPC_query.empty - ~output:Data_encoding.int32 - RPC_path.(path / "current_quorum") - - let listings = - RPC_service.get_service - ~description: - "List of delegates with their voting weight, in number of rolls." - ~query:RPC_query.empty - ~output:Vote.listings_encoding - RPC_path.(path / "listings") - - let proposals = - RPC_service.get_service - ~description:"List of proposals with number of supporters." - ~query:RPC_query.empty - ~output:(Protocol_hash.Map.encoding Data_encoding.int32) - RPC_path.(path / "proposals") - - let current_proposal = - RPC_service.get_service - ~description:"Current proposal under evaluation." - ~query:RPC_query.empty - ~output:(Data_encoding.option Protocol_hash.encoding) - RPC_path.(path / "current_proposal") - - let total_voting_power = - RPC_service.get_service - ~description: - "Total number of rolls for the delegates in the voting listings." - ~query:RPC_query.empty - ~output:Data_encoding.int32 - RPC_path.(path / "total_voting_power") -end - -let register () = - let open Services_registration in - register0 ~chunked:false S.ballots (fun ctxt () () -> Vote.get_ballots ctxt) ; - register0 ~chunked:true S.ballot_list (fun ctxt () () -> - Vote.get_ballot_list ctxt >|= ok) ; - register0 ~chunked:false S.current_period (fun ctxt () () -> - Voting_period.get_rpc_current_info ctxt) ; - register0 ~chunked:false S.successor_period (fun ctxt () () -> - Voting_period.get_rpc_succ_info ctxt) ; - register0 ~chunked:false S.current_quorum (fun ctxt () () -> - Vote.get_current_quorum ctxt) ; - register0 ~chunked:true S.proposals (fun ctxt () () -> - Vote.get_proposals ctxt) ; - register0 ~chunked:true S.listings (fun ctxt () () -> - Vote.get_listings ctxt >|= ok) ; - register0 ~chunked:false S.current_proposal (fun ctxt () () -> - Vote.find_current_proposal ctxt) ; - register0 ~chunked:false S.total_voting_power (fun ctxt () () -> - Vote.get_total_voting_power_free ctxt) - [@@coq_axiom_with_reason - "disabled because we would need to re-create the error e in order to have \ - different polymorphic variables"] - -let ballots ctxt block = RPC_context.make_call0 S.ballots ctxt block () () - -let ballot_list ctxt block = - RPC_context.make_call0 S.ballot_list ctxt block () () - -let current_period ctxt block = - RPC_context.make_call0 S.current_period ctxt block () () - -let successor_period ctxt block = - RPC_context.make_call0 S.successor_period ctxt block () () - -let current_quorum ctxt block = - RPC_context.make_call0 S.current_quorum ctxt block () () - -let listings ctxt block = RPC_context.make_call0 S.listings ctxt block () () - -let proposals ctxt block = RPC_context.make_call0 S.proposals ctxt block () () - -let current_proposal ctxt block = - RPC_context.make_call0 S.current_proposal ctxt block () () - -let total_voting_power ctxt block = - RPC_context.make_call0 S.total_voting_power ctxt block () () diff --git a/src/proto_012_Psithaca/lib_protocol/voting_services.mli b/src/proto_012_Psithaca/lib_protocol/voting_services.mli deleted file mode 100644 index d56157aa6c1a..000000000000 --- a/src/proto_012_Psithaca/lib_protocol/voting_services.mli +++ /dev/null @@ -1,60 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -open Alpha_context - -val ballots : 'a #RPC_context.simple -> 'a -> Vote.ballots shell_tzresult Lwt.t - -val ballot_list : - 'a #RPC_context.simple -> - 'a -> - (Signature.Public_key_hash.t * Vote.ballot) list shell_tzresult Lwt.t - -val current_period : - 'a #RPC_context.simple -> 'a -> Voting_period.info shell_tzresult Lwt.t - -val successor_period : - 'a #RPC_context.simple -> 'a -> Voting_period.info shell_tzresult Lwt.t - -val current_quorum : - 'a #RPC_context.simple -> 'a -> Int32.t shell_tzresult Lwt.t - -val listings : - 'a #RPC_context.simple -> - 'a -> - (Signature.Public_key_hash.t * int32) list shell_tzresult Lwt.t - -val proposals : - 'a #RPC_context.simple -> - 'a -> - Int32.t Protocol_hash.Map.t shell_tzresult Lwt.t - -val current_proposal : - 'a #RPC_context.simple -> 'a -> Protocol_hash.t option shell_tzresult Lwt.t - -val register : unit -> unit - -val total_voting_power : - 'a #RPC_context.simple -> 'a -> Int32.t shell_tzresult Lwt.t diff --git a/src/proto_012_Psithaca/parameters/dune b/src/proto_012_Psithaca/parameters/dune deleted file mode 100644 index f9a324da0bf8..000000000000 --- a/src/proto_012_Psithaca/parameters/dune +++ /dev/null @@ -1,4 +0,0 @@ -(copy_files - (alias copy-parameters) - (mode promote-until-clean) - (files ../lib_parameters/*.json)) \ No newline at end of file diff --git a/tests_python/contracts_012/attic/accounts.tz b/tests_python/contracts_012/attic/accounts.tz deleted file mode 100644 index de80046b29a6..000000000000 --- a/tests_python/contracts_012/attic/accounts.tz +++ /dev/null @@ -1,54 +0,0 @@ -# This is a very simple accounts system. -# (Left key) initializes or deposits into an account -# (Right key (pair mutez (signed mutez))) withdraws mutez amount to a -# IMPLICIT_ACCOUNT created from the key if the balance is available -# and the key is correctly signed -parameter (or (key_hash %Initialize) - (pair %Withdraw - (key %from) - (pair - (mutez %withdraw_amount) - (signature %sig)))); -# Maps the key to the balance they have stored -storage (map :stored_balance key_hash mutez); -code { DUP; CAR; - # Deposit into account - IF_LEFT { DUP; DIIP{ CDR %stored_balance; DUP }; - DIP{ SWAP }; GET @opt_prev_balance; - # Create the account - IF_SOME # Add to an existing account - { RENAME @previous_balance; - AMOUNT; ADD; SOME; SWAP; UPDATE; NIL operation; PAIR } - { DIP{ AMOUNT; SOME }; UPDATE; NIL operation; PAIR }} - # Withdrawal - { DUP; DUP; DUP; DUP; - # Check signature on data - CAR %from; - DIIP{ CDAR %withdraw_amount; PACK ; BLAKE2B @signed_amount }; - DIP{ CDDR %sig }; CHECK_SIGNATURE; - IF {} { PUSH string "Bad signature"; FAILWITH }; - # Get user account information - DIIP{ CDR %stored_balance; DUP }; - CAR %from; HASH_KEY @from_hash; DUP; DIP{ DIP { SWAP }; SWAP}; GET; - # Account does not exist - IF_NONE { PUSH string "Account does not exist"; PAIR; FAILWITH } - # Account exists - { RENAME @previous_balance; - DIP { DROP }; - DUP; DIIP{ DUP; CDAR %withdraw_amount; DUP }; - # Ensure funds are available - DIP{ CMPLT @not_enough }; SWAP; - IF { PUSH string "Not enough funds"; FAILWITH } - { SUB_MUTEZ @new_balance; ASSERT_SOME; DIP{ DUP; DIP{ SWAP }}; DUP; - # Delete account if balance is 0 - PUSH @zero mutez 0; CMPEQ @null_balance; - IF { DROP; NONE @new_balance mutez } - # Otherwise update storage with new balance - { SOME @new_balance }; - SWAP; CAR %from; HASH_KEY @from_hash; UPDATE; - SWAP; DUP; CDAR %withdraw_amount; - # Execute the transfer - DIP{ CAR %from; HASH_KEY @from_hash; IMPLICIT_ACCOUNT @from_account}; UNIT; - TRANSFER_TOKENS @withdraw_transfer_op; - NIL operation; SWAP; CONS; - PAIR }}}} diff --git a/tests_python/contracts_012/attic/add1.tz b/tests_python/contracts_012/attic/add1.tz deleted file mode 100644 index 78d4f9d1c020..000000000000 --- a/tests_python/contracts_012/attic/add1.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter int; -storage int; -code {CAR; # Get the parameter - PUSH int 1; # We're adding 1, so we need to put 1 on the stack - ADD; # Add the two numbers - NIL operation; # We put an empty list of operations on the stack - PAIR} # Create the end value diff --git a/tests_python/contracts_012/attic/add1_list.tz b/tests_python/contracts_012/attic/add1_list.tz deleted file mode 100644 index c11616286475..000000000000 --- a/tests_python/contracts_012/attic/add1_list.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter (list int); -storage (list int); -code { CAR; # Get the parameter - MAP { PUSH int 1; ADD }; # Map over the list adding one - NIL operation; # No internal op - PAIR } # Match the calling convention diff --git a/tests_python/contracts_012/attic/after_strategy.tz b/tests_python/contracts_012/attic/after_strategy.tz deleted file mode 100644 index 70812e52b200..000000000000 --- a/tests_python/contracts_012/attic/after_strategy.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter nat; -storage (pair (pair nat bool) timestamp); -code {DUP; CAR; DIP{CDDR; DUP; NOW; CMPGT}; PAIR; PAIR ; NIL operation ; PAIR}; diff --git a/tests_python/contracts_012/attic/always.tz b/tests_python/contracts_012/attic/always.tz deleted file mode 100644 index a7802fec96c8..000000000000 --- a/tests_python/contracts_012/attic/always.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter nat; -storage (pair nat bool); -code { CAR; PUSH bool True; SWAP; - PAIR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/append.tz b/tests_python/contracts_012/attic/append.tz deleted file mode 100644 index 3b8335455dcd..000000000000 --- a/tests_python/contracts_012/attic/append.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter (pair (list int) (list int)); -storage (list int); -code { CAR; UNPAIR ; # Unpack lists - NIL int; SWAP; # Setup reverse accumulator - ITER {CONS}; # Reverse list - ITER {CONS}; # Append reversed list - NIL operation; - PAIR} diff --git a/tests_python/contracts_012/attic/at_least.tz b/tests_python/contracts_012/attic/at_least.tz deleted file mode 100644 index 6c6d2968cd12..000000000000 --- a/tests_python/contracts_012/attic/at_least.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage mutez; # How much you have to send me -code {CDR; DUP; # Get the amount required (once for comparison, once to save back in storage) - AMOUNT; CMPLT; # Check to make sure no one is wasting my time - IF {FAIL} # Reject the person - {NIL operation;PAIR}} # Finish the transaction diff --git a/tests_python/contracts_012/attic/auction.tz b/tests_python/contracts_012/attic/auction.tz deleted file mode 100644 index af8aedfb7c22..000000000000 --- a/tests_python/contracts_012/attic/auction.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter key_hash; -storage (pair timestamp (pair mutez key_hash)); -code { DUP; CDAR; DUP; NOW; CMPGT; IF {FAIL} {}; SWAP; # Check if auction has ended - DUP; CAR; DIP{CDDR}; AMOUNT; PAIR; SWAP; DIP{SWAP; PAIR}; # Setup replacement storage - DUP; CAR; AMOUNT; CMPLE; IF {FAIL} {}; # Check to make sure that the new amount is greater - DUP; CAR; # Get amount of refund - DIP{CDR; IMPLICIT_ACCOUNT}; UNIT; TRANSFER_TOKENS; # Make refund - NIL operation; SWAP; CONS; PAIR} # Calling convention diff --git a/tests_python/contracts_012/attic/bad_lockup.tz b/tests_python/contracts_012/attic/bad_lockup.tz deleted file mode 100644 index f334e899e71c..000000000000 --- a/tests_python/contracts_012/attic/bad_lockup.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage (pair timestamp (pair address address)); -code { CDR; DUP; CAR; NOW; CMPLT; IF {FAIL} {}; - DUP; CDAR; CONTRACT unit ; ASSERT_SOME ; PUSH mutez 100000000; UNIT; TRANSFER_TOKENS; SWAP; - DUP; CDDR; CONTRACT unit ; ASSERT_SOME ; PUSH mutez 100000000; UNIT; TRANSFER_TOKENS; DIP {SWAP} ; - NIL operation ; SWAP ; CONS ; SWAP ; CONS ; PAIR } diff --git a/tests_python/contracts_012/attic/big_map_union.tz b/tests_python/contracts_012/attic/big_map_union.tz deleted file mode 100644 index 0c971ff11ce9..000000000000 --- a/tests_python/contracts_012/attic/big_map_union.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter (list (pair string int)) ; -storage (pair (big_map string int) unit) ; -code { UNPAPAIR ; - ITER { UNPAIR ; DUUUP ; DUUP; GET ; - IF_NONE { PUSH int 0 } {} ; - SWAP ; DIP { ADD ; SOME } ; - UPDATE } ; - PAIR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/attic/cadr_annotation.tz b/tests_python/contracts_012/attic/cadr_annotation.tz deleted file mode 100644 index 3f4978aebf9e..000000000000 --- a/tests_python/contracts_012/attic/cadr_annotation.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair (pair %p1 unit (string %no_name)) bool); -storage unit; -code { CAR @param; CADR @name %no_name; DROP; UNIT; NIL operation; PAIR } diff --git a/tests_python/contracts_012/attic/concat.tz b/tests_python/contracts_012/attic/concat.tz deleted file mode 100644 index 26814afca55a..000000000000 --- a/tests_python/contracts_012/attic/concat.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter string; -storage string; -code { DUP; - DIP { CDR ; NIL string ; SWAP ; CONS } ; - CAR ; CONS ; - CONCAT; - NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/conditionals.tz b/tests_python/contracts_012/attic/conditionals.tz deleted file mode 100644 index 16bf8e91645c..000000000000 --- a/tests_python/contracts_012/attic/conditionals.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (or string (option int)); -storage string; -code { CAR; # Access the storage - IF_LEFT {} # The string is on top of the stack, nothing to do - { IF_NONE { FAIL} # Fail if None - { PUSH int 0; CMPGT; # Check for negative number - IF {FAIL} # Fail if negative - {PUSH string ""}}}; # Push the empty string - NIL operation; PAIR} # Calling convention diff --git a/tests_python/contracts_012/attic/cons_twice.tz b/tests_python/contracts_012/attic/cons_twice.tz deleted file mode 100644 index 4761b23f71f1..000000000000 --- a/tests_python/contracts_012/attic/cons_twice.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter nat; -storage (list nat); -code { DUP; # Duplicate the storage and parameter - CAR; # Extract the parameter - DIP{CDR}; # Extract the storage - DUP; # Duplicate the parameter - DIP{CONS}; # Add the first instance of the parameter to the list - CONS; # Add the second instance of the parameter to the list - NIL operation; PAIR} # Finish the calling convention diff --git a/tests_python/contracts_012/attic/cps_fact.tz b/tests_python/contracts_012/attic/cps_fact.tz deleted file mode 100644 index 6c8ee7146290..000000000000 --- a/tests_python/contracts_012/attic/cps_fact.tz +++ /dev/null @@ -1,16 +0,0 @@ -storage nat ; -parameter nat ; -code { UNPAIR ; - DIP { SELF ; ADDRESS ; SENDER; - IFCMPEQ {} { DROP ; PUSH @storage nat 1 } }; - DUP ; - PUSH nat 1 ; - IFCMPGE - { DROP ; NIL operation ; PAIR } - { PUSH nat 1 ; SWAP ; SUB @parameter ; ISNAT ; - IF_NONE - { NIL operation ; PAIR } - { DUP ; DIP { PUSH nat 1 ; ADD ; MUL @storage } ; SWAP; - DIP { DIP { SELF; PUSH mutez 0 } ; - TRANSFER_TOKENS ; NIL operation ; SWAP ; CONS } ; - SWAP ; PAIR } } } \ No newline at end of file diff --git a/tests_python/contracts_012/attic/create_add1_lists.tz b/tests_python/contracts_012/attic/create_add1_lists.tz deleted file mode 100644 index 5a4245966379..000000000000 --- a/tests_python/contracts_012/attic/create_add1_lists.tz +++ /dev/null @@ -1,14 +0,0 @@ -parameter unit; -storage address; -code { DROP; NIL int; # starting storage for contract - AMOUNT; # Push the starting balance - NONE key_hash; # No delegate - CREATE_CONTRACT # Create the contract - { parameter (list int) ; - storage (list int) ; - code - { CAR; - MAP {PUSH int 1; ADD}; - NIL operation; - PAIR } }; - NIL operation; SWAP; CONS; PAIR} # Ending calling convention stuff diff --git a/tests_python/contracts_012/attic/data_publisher.tz b/tests_python/contracts_012/attic/data_publisher.tz deleted file mode 100644 index 9240d63021bc..000000000000 --- a/tests_python/contracts_012/attic/data_publisher.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter (pair signature (pair string nat)); -storage (pair (pair key nat) string); -code { DUP; CAR; DIP{CDR; DUP}; - SWAP; DIP{DUP}; CAAR; DIP{DUP; CAR; DIP{CDR; PACK ; BLAKE2B}}; - CHECK_SIGNATURE; - IF { CDR; DUP; DIP{CAR; DIP{CAAR}}; CDR; PUSH nat 1; ADD; - DIP{SWAP}; SWAP; PAIR; PAIR; NIL operation; PAIR} - {FAIL}} diff --git a/tests_python/contracts_012/attic/dispatch.tz b/tests_python/contracts_012/attic/dispatch.tz deleted file mode 100644 index 9c185133ac7f..000000000000 --- a/tests_python/contracts_012/attic/dispatch.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (or string (pair string (lambda unit string))); -storage (pair string (map string (lambda unit string))); -code { DUP; DIP{CDDR}; CAR; # Unpack stack - IF_LEFT { DIP{DUP}; GET; # Get lambda if it exists - IF_NONE {FAIL} {}; # Fail if it doesn't - UNIT; EXEC } # Execute the lambda - { DUP; CAR; DIP {CDR; SOME}; UPDATE; PUSH string ""}; # Update the storage - PAIR; - NIL operation; PAIR} # Calling convention diff --git a/tests_python/contracts_012/attic/empty.tz b/tests_python/contracts_012/attic/empty.tz deleted file mode 100644 index d3aecdb25066..000000000000 --- a/tests_python/contracts_012/attic/empty.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage unit; -code {CDR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/fail_amount.tz b/tests_python/contracts_012/attic/fail_amount.tz deleted file mode 100644 index 95b71c4f0ff1..000000000000 --- a/tests_python/contracts_012/attic/fail_amount.tz +++ /dev/null @@ -1,6 +0,0 @@ -# Fail if the amount transferred is less than 10 -parameter unit; -storage unit; -code { DROP; - AMOUNT; PUSH mutez 10000000; CMPGT; IF {FAIL} {}; - UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/faucet.tz b/tests_python/contracts_012/attic/faucet.tz deleted file mode 100644 index 0c92a0744d94..000000000000 --- a/tests_python/contracts_012/attic/faucet.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter key_hash ; -storage timestamp ; -code { UNPAIR ; SWAP ; - PUSH int 300 ; ADD @FIVE_MINUTES_LATER ; - NOW ; ASSERT_CMPGE ; - IMPLICIT_ACCOUNT ; PUSH mutez 1000000 ; UNIT ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; DIP { NOW } ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/attic/forward.tz b/tests_python/contracts_012/attic/forward.tz deleted file mode 100644 index 829192f5a313..000000000000 --- a/tests_python/contracts_012/attic/forward.tz +++ /dev/null @@ -1,150 +0,0 @@ -parameter - (or string nat) ; -storage - (pair - (pair nat (pair mutez mutez)) # counter from_buyer from_seller - (pair - (pair nat (pair timestamp timestamp)) # Q T Z - (pair - (pair mutez mutez) # K C - (pair - (pair address address) # B S - address)))) ; # W -code - { DUP ; CDDADDR ; # Z - PUSH int 86400 ; SWAP ; ADD ; # one day in second - NOW ; COMPARE ; LT ; - IF { # Before Z + 24 - DUP ; CAR ; # we must receive (Left "buyer") or (Left "seller") - IF_LEFT - { DUP ; PUSH string "buyer" ; COMPARE ; EQ ; - IF { DROP ; - DUP ; CDADAR ; # amount already versed by the buyer - DIP { AMOUNT } ; ADD ; # transaction - # then we rebuild the globals - DIP { DUP ; CDADDR } ; PAIR ; # seller amount - PUSH nat 0 ; PAIR ; # delivery counter at 0 - DIP { CDDR } ; PAIR ; # parameters - # and return Unit - NIL operation ; PAIR } - { PUSH string "seller" ; COMPARE ; EQ ; - IF { DUP ; CDADDR ; # amount already versed by the seller - DIP { AMOUNT } ; ADD ; # transaction - # then we rebuild the globals - DIP { DUP ; CDADAR } ; SWAP ; PAIR ; # buyer amount - PUSH nat 0 ; PAIR ; # delivery counter at 0 - DIP { CDDR } ; PAIR ; # parameters - # and return Unit - NIL operation ; PAIR } - { FAIL } } } # (Left _) - { FAIL } } # (Right _) - { # After Z + 24 - # if balance is emptied, just fail - BALANCE ; PUSH mutez 0 ; IFCMPEQ { FAIL } {} ; - # test if the required amount is reached - DUP ; CDDAAR ; # Q - DIP { DUP ; CDDDADR } ; MUL ; # C - PUSH nat 2 ; MUL ; - BALANCE ; COMPARE ; LT ; # balance < 2 * (Q * C) - IF { # refund the parties - CDR ; DUP ; CADAR ; # amount versed by the buyer - DIP { DUP ; CDDDAAR } ; # B - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; SWAP ; - DUP ; CADDR ; # amount versed by the seller - DIP { DUP ; CDDDADR } ; # S - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS ; SWAP ; - DIP { CONS } ; - DUP ; CADAR ; DIP { DUP ; CADDR } ; ADD ; - BALANCE ; SUB_MUTEZ ; ASSERT_SOME; # bonus to the warehouse - DIP { DUP ; CDDDDR } ; # W - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS ; - DIP { SWAP } ; CONS ; - # leave the storage as-is, as the balance is now 0 - PAIR } - { # otherwise continue - DUP ; CDDADAR ; # T - NOW ; COMPARE ; LT ; - IF { FAIL } # Between Z + 24 and T - { # after T - DUP ; CDDADAR ; # T - PUSH int 86400 ; ADD ; # one day in second - NOW ; COMPARE ; LT ; - IF { # Between T and T + 24 - # we only accept transactions from the buyer - DUP ; CAR ; # we must receive (Left "buyer") - IF_LEFT - { PUSH string "buyer" ; COMPARE ; EQ ; - IF { DUP ; CDADAR ; # amount already versed by the buyer - DIP { AMOUNT } ; ADD ; # transaction - # The amount must not exceed Q * K - DUP ; - DIIP { DUP ; CDDAAR ; # Q - DIP { DUP ; CDDDAAR } ; MUL ; } ; # K - DIP { COMPARE ; GT ; # new amount > Q * K - IF { FAIL } { } } ; # abort or continue - # then we rebuild the globals - DIP { DUP ; CDADDR } ; PAIR ; # seller amount - PUSH nat 0 ; PAIR ; # delivery counter at 0 - DIP { CDDR } ; PAIR ; # parameters - # and return Unit - NIL operation ; PAIR } - { FAIL } } # (Left _) - { FAIL } } # (Right _) - { # After T + 24 - # test if the required payment is reached - DUP ; CDDAAR ; # Q - DIP { DUP ; CDDDAAR } ; MUL ; # K - DIP { DUP ; CDADAR } ; # amount already versed by the buyer - COMPARE ; NEQ ; - IF { # not reached, pay the seller - BALANCE ; - DIP { DUP ; CDDDDADR } ; # S - DIIP { CDR } ; - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; PAIR } - { # otherwise continue - DUP ; CDDADAR ; # T - PUSH int 86400 ; ADD ; - PUSH int 86400 ; ADD ; # two days in second - NOW ; COMPARE ; LT ; - IF { # Between T + 24 and T + 48 - # We accept only delivery notifications, from W - DUP ; CDDDDDR ; # W - SENDER ; - COMPARE ; NEQ ; - IF { FAIL } {} ; # fail if not the warehouse - DUP ; CAR ; # we must receive (Right amount) - IF_LEFT - { FAIL } # (Left _) - { # We increment the counter - DIP { DUP ; CDAAR } ; ADD ; - # And rebuild the globals in advance - DIP { DUP ; CDADR } ; PAIR ; - DIP { CDDR } ; PAIR ; - UNIT ; PAIR ; - # We test if enough have been delivered - DUP ; CDAAR ; - DIP { DUP ; CDDAAR } ; - COMPARE ; LT ; # counter < Q - IF { CDR ; NIL operation } # wait for more - { # Transfer all the money to the seller - BALANCE ; - DIP { DUP ; CDDDDADR } ; # S - DIIP { CDR } ; - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS } } ; - PAIR } - { # after T + 48, transfer everything to the buyer - BALANCE ; - DIP { DUP ; CDDDDAAR } ; # B - DIIP { CDR } ; - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; - PAIR} } } } } } } \ No newline at end of file diff --git a/tests_python/contracts_012/attic/id.tz b/tests_python/contracts_012/attic/id.tz deleted file mode 100644 index 4eee565ca2e9..000000000000 --- a/tests_python/contracts_012/attic/id.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter string; -storage string; -code {CAR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/attic/infinite_loop.tz b/tests_python/contracts_012/attic/infinite_loop.tz deleted file mode 100644 index 77cdbc48c0d1..000000000000 --- a/tests_python/contracts_012/attic/infinite_loop.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage unit; -code { DROP; PUSH bool True; LOOP {PUSH bool True}; UNIT; NIL operation; PAIR } diff --git a/tests_python/contracts_012/attic/insertion_sort.tz b/tests_python/contracts_012/attic/insertion_sort.tz deleted file mode 100644 index 34eca64d092c..000000000000 --- a/tests_python/contracts_012/attic/insertion_sort.tz +++ /dev/null @@ -1,16 +0,0 @@ -parameter (list int) ; -storage (list int) ; -code { CAR ; - NIL int ; SWAP ; - ITER { SWAP; DIIP{NIL int} ; PUSH bool True ; - LOOP - { IF_CONS - { SWAP ; - DIP{DUP ; DIIP{DUP} ; DIP{CMPLT} ; SWAP} ; - SWAP ; - IF { DIP{SWAP ; DIP{CONS}} ; PUSH bool True} - { SWAP ; CONS ; PUSH bool False}} - { NIL int ; PUSH bool False}} ; - SWAP ; CONS ; SWAP ; - ITER {CONS}} ; - NIL operation ; PAIR } diff --git a/tests_python/contracts_012/attic/int_publisher.tz b/tests_python/contracts_012/attic/int_publisher.tz deleted file mode 100644 index 6ee49b979e2c..000000000000 --- a/tests_python/contracts_012/attic/int_publisher.tz +++ /dev/null @@ -1,17 +0,0 @@ -# (signed hash of the string, string) -parameter (option (pair signature int)); -storage (pair key int); -code {DUP; DUP; CAR; - IF_NONE {PUSH mutez 1000000; # Fee pattern from July 26 - AMOUNT; CMPLE; IF {FAIL} {}; - # Provide the data - CDR; DIP {CDDR}} - {DUP; DIP{SWAP}; SWAP; CDAR; # Move key to the top - DIP {DUP; CAR; DIP {CDR; PACK ; BLAKE2B}}; # Arrange the new piece of data - CHECK_SIGNATURE; # Check to ensure the data is authentic - # Update data - IF {CDR; SWAP; DIP{DUP}; CDAR; PAIR} - # Revert the update. This could be replaced with FAIL - {DROP; DUP; CDR; DIP{CDDR}}}; - # Cleanup - DIP{DROP}; NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/king_of_tez.tz b/tests_python/contracts_012/attic/king_of_tez.tz deleted file mode 100644 index 033ead7f168c..000000000000 --- a/tests_python/contracts_012/attic/king_of_tez.tz +++ /dev/null @@ -1,19 +0,0 @@ -parameter key_hash; -storage (pair timestamp (pair mutez key_hash)); -code { DUP; CDAR; - # If the time is more than 2 weeks, any amount makes you king - NOW; CMPGT; - # User becomes king of mutez - IF { CAR; AMOUNT; PAIR; NOW; PUSH int 604800; ADD; PAIR; - NIL operation } - # Check balance to see if user has paid enough to become the new king - { DUP; CDDAR; AMOUNT; CMPLT; - IF { FAIL } # user has not paid out - { CAR; DUP; - # New storage - DIP{ AMOUNT; PAIR; NOW; PUSH int 604800; ADD; PAIR }; - # Pay funds to old king - IMPLICIT_ACCOUNT; AMOUNT; UNIT; TRANSFER_TOKENS; - NIL operation; SWAP; CONS}}; - # Cleanup - PAIR }; diff --git a/tests_python/contracts_012/attic/list_of_transactions.tz b/tests_python/contracts_012/attic/list_of_transactions.tz deleted file mode 100644 index 620ceedd5a67..000000000000 --- a/tests_python/contracts_012/attic/list_of_transactions.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter unit; -storage (list address); -code { CDR; DUP; - DIP {NIL operation}; PUSH bool True; # Setup loop - LOOP {IF_CONS { CONTRACT unit ; ASSERT_SOME ; PUSH mutez 1000000; UNIT; TRANSFER_TOKENS; # Make transfer - SWAP; DIP {CONS}; PUSH bool True} # Setup for next round of loop - { NIL address ; PUSH bool False}}; # Data to satisfy types and end loop - DROP; PAIR}; # Calling convention diff --git a/tests_python/contracts_012/attic/queue.tz b/tests_python/contracts_012/attic/queue.tz deleted file mode 100644 index a074906ddf91..000000000000 --- a/tests_python/contracts_012/attic/queue.tz +++ /dev/null @@ -1,24 +0,0 @@ -parameter (option string); -storage (pair (option string) (pair (pair nat nat) (map nat string))); -code { DUP; CAR; - # Retrieving an element - IF_NONE { CDDR; DUP; CAR; DIP{CDR; DUP}; DUP; - CAR; SWAP; DIP{GET}; # Check if an element is available - SWAP; - # Put NONE on stack and finish - IF_NONE { NONE string; DIP{PAIR}; PAIR} - # Reoption the element and remove the entry from the map - { SOME; - DIP{ DUP; DIP{ CAR; DIP{ NONE string }; UPDATE }; - # Increment the counter and cleanup - DUP; CAR; PUSH nat 1; ADD; DIP{ CDR }; PAIR; PAIR}; - PAIR }} - # Arrange the stack - { DIP{DUP; CDDAR; DIP{CDDDR}; DUP}; SWAP; CAR; - # Add the element to the map - DIP{ SOME; SWAP; CDR; DUP; DIP{UPDATE}; - # Increment the second number - PUSH nat 1; ADD}; - # Cleanup and finish - PAIR; PAIR; NONE string; PAIR }; - NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/reduce_map.tz b/tests_python/contracts_012/attic/reduce_map.tz deleted file mode 100644 index aab8ea60d367..000000000000 --- a/tests_python/contracts_012/attic/reduce_map.tz +++ /dev/null @@ -1,16 +0,0 @@ - -parameter (pair (lambda int int) (list int)); -storage (list int); -code { DIP{NIL int}; - CAR; - DUP; - DIP{CAR; PAIR}; # Unpack data and setup accumulator - CDR; - ITER {PAIR; - DUP; CDAR; - DIP{ DUP; DIP{CDAR}; DUP; - CAR; DIP{CDDR; SWAP}; EXEC; CONS}; - PAIR}; - CDR; DIP{NIL int}; # First reduce - ITER {CONS}; # Reverse - NIL operation; PAIR} # Calling convention diff --git a/tests_python/contracts_012/attic/reentrancy.tz b/tests_python/contracts_012/attic/reentrancy.tz deleted file mode 100644 index b9e614a4e53e..000000000000 --- a/tests_python/contracts_012/attic/reentrancy.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter unit; -storage (pair address address); -code { CDR; DUP; CAR; - CONTRACT unit ; ASSERT_SOME ; PUSH mutez 5000000; UNIT; TRANSFER_TOKENS; - DIP {DUP; CDR; - CONTRACT unit ; ASSERT_SOME ; PUSH mutez 5000000; UNIT; TRANSFER_TOKENS}; - DIIP{NIL operation};DIP{CONS};CONS;PAIR}; diff --git a/tests_python/contracts_012/attic/reservoir.tz b/tests_python/contracts_012/attic/reservoir.tz deleted file mode 100644 index 291e09b262b5..000000000000 --- a/tests_python/contracts_012/attic/reservoir.tz +++ /dev/null @@ -1,25 +0,0 @@ -parameter unit ; -storage - (pair - (pair (timestamp %T) (mutez %N)) - (pair (address %A) (address %B))) ; -code - { CDR ; DUP ; CAAR %T; # T - NOW ; COMPARE ; LE ; - IF { DUP ; CADR %N; # N - BALANCE ; - COMPARE ; LE ; - IF { NIL operation ; PAIR } - { DUP ; CDDR %B; # B - CONTRACT unit ; ASSERT_SOME ; - BALANCE ; UNIT ; - TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; - PAIR } } - { DUP ; CDAR %A; # A - CONTRACT unit ; ASSERT_SOME ; - BALANCE ; - UNIT ; - TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; - PAIR } } diff --git a/tests_python/contracts_012/attic/scrutable_reservoir.tz b/tests_python/contracts_012/attic/scrutable_reservoir.tz deleted file mode 100644 index d415cdda0f54..000000000000 --- a/tests_python/contracts_012/attic/scrutable_reservoir.tz +++ /dev/null @@ -1,67 +0,0 @@ -parameter unit ; -storage - (pair - string # S - (pair - timestamp # T - (pair - (pair mutez mutez) # P N - (pair - address # X - (pair address address))))) ; # A B -code - { DUP ; CDAR ; # S - PUSH string "open" ; - COMPARE ; NEQ ; - IF { FAIL } # on "success", "timeout" or a bad init value - { DUP ; CDDAR ; # T - NOW ; - COMPARE ; LT ; - IF { # Before timeout - # We compute (P + N) mutez - PUSH mutez 0 ; - DIP { DUP ; CDDDAAR } ; ADD ; # P - DIP { DUP ; CDDDADR } ; ADD ; # N - # We compare to the cumulated amount - BALANCE ; - COMPARE; LT ; - IF { # Not enough cash, we just accept the transaction - # and leave the global untouched - CDR ; NIL operation ; PAIR } - { # Enough cash, successful ending - # We update the global - CDDR ; PUSH string "success" ; PAIR ; - # We transfer the fee to the broker - DUP ; CDDAAR ; # P - DIP { DUP ; CDDDAR } ; # X - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS ; - # We transfer the rest to A - DIP { DUP ; CDDADR ; # N - DIP { DUP ; CDDDDAR } ; # A - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS } ; - NIL operation ; SWAP ; CONS ; SWAP ; CONS ; - PAIR } } - { # After timeout, we refund - # We update the global - CDDR ; PUSH string "timeout" ; PAIR ; - # We try to transfer the fee to the broker - BALANCE ; # available - DIP { DUP ; CDDAAR } ; # P - COMPARE ; LT ; # available < P - IF { BALANCE ; # available - DIP { DUP ; CDDDAR } ; # X - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS } - { DUP ; CDDAAR ; # P - DIP { DUP ; CDDDAR } ; # X - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS } ; - # We transfer the rest to B - DIP { BALANCE ; # available - DIP { DUP ; CDDDDDR } ; # B - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT ; TRANSFER_TOKENS } ; - NIL operation ; SWAP ; CONS ; SWAP ; CONS ; - PAIR } } } diff --git a/tests_python/contracts_012/attic/spawn_identities.tz b/tests_python/contracts_012/attic/spawn_identities.tz deleted file mode 100644 index 2208e0d0928d..000000000000 --- a/tests_python/contracts_012/attic/spawn_identities.tz +++ /dev/null @@ -1,20 +0,0 @@ -parameter nat; -storage (list address); -code { DUP; - CAR; # Get the number - DIP{CDR; NIL operation}; # Put the accumulators on the stack - PUSH bool True; # Push true so we have a do while loop - LOOP { DUP; PUSH nat 0; CMPEQ; # Check if the number is 0 - IF { PUSH bool False} # End the loop - { PUSH nat 1; SWAP; SUB; ABS; # Subtract 1. The ABS is to make it back into a nat - PUSH string "init"; # Storage type - PUSH mutez 5000000; # Starting balance - NONE key_hash; - CREATE_CONTRACT - { parameter string ; - storage string ; - code { CAR ; NIL operation ; PAIR } } ; # Make the contract - SWAP ; DIP { SWAP ; DIP { CONS } } ; # emit the operation - SWAP ; DIP { SWAP ; DIP { CONS } } ; # add to the list - PUSH bool True}}; # Continue the loop - DROP; PAIR} # Calling convention diff --git a/tests_python/contracts_012/entrypoints/big_map_entrypoints.tz b/tests_python/contracts_012/entrypoints/big_map_entrypoints.tz deleted file mode 100644 index d49e6257167a..000000000000 --- a/tests_python/contracts_012/entrypoints/big_map_entrypoints.tz +++ /dev/null @@ -1,31 +0,0 @@ -storage - (pair (big_map string nat) (big_map string nat)) ; -parameter - (or (unit %default) - (or (or %mem (string %mem_left) (string %mem_right)) - (or (or %add (pair %add_left string nat) (pair %add_right string nat)) - (or %rem (string %rem_left) (string %rem_right))))) ; -code { UNPAIR ; - IF_LEFT - { DROP ; - DUP ; CAR ; - PUSH mutez 0 ; - NONE key_hash ; - CREATE_CONTRACT - { parameter string ; - storage (big_map string nat) ; - code { UNPAIR ; DROP ; NIL operation ; PAIR }} ; - DIP { DROP } ; - NIL operation ; SWAP ; CONS ; PAIR } - { IF_LEFT - { IF_LEFT - { DIP { UNPAIR } ; DIP { DUP } ; MEM ; ASSERT } - { DIP { UNPAIR ; SWAP } ; DIP { DUP } ; MEM ; ASSERT ; SWAP } } - { IF_LEFT - { IF_LEFT - { UNPAIR ; DIIP { UNPAIR } ; DIP { SOME } ; UPDATE } - { UNPAIR ; DIIP { UNPAIR ; SWAP } ; DIP { SOME } ; UPDATE ; SWAP } } - { IF_LEFT - { DIP { UNPAIR } ; DIP { NONE nat } ; UPDATE } - { DIP { UNPAIR ; SWAP } ; DIP { NONE nat } ; UPDATE ; SWAP } } } ; - PAIR ; NIL operation ; PAIR } } diff --git a/tests_python/contracts_012/entrypoints/delegatable_target.tz b/tests_python/contracts_012/entrypoints/delegatable_target.tz deleted file mode 100644 index 0db00f4945ed..000000000000 --- a/tests_python/contracts_012/entrypoints/delegatable_target.tz +++ /dev/null @@ -1,79 +0,0 @@ -# Michelson pseudo-code to transform from source script. - # This transformation adds 'set_delegate' entrypoint, e.g.: - # - # parameter ; - # storage ; - # code ; - # - # to: -parameter - (or - (or (key_hash %set_delegate) - (unit %remove_delegate)) - (or %default string nat) - ) ; - -storage - (pair - key_hash # manager - (pair string nat) - ) ; - -code { - DUP ; - CAR ; - IF_LEFT - { # 'set_delegate'/'remove_delegate' entrypoints - # Assert no token was sent: - # to send tokens, the default entry point should be used - PUSH mutez 0 ; - AMOUNT ; - ASSERT_CMPEQ ; - # Assert that the sender is the manager - DUUP ; - CDR ; - CAR ; - IMPLICIT_ACCOUNT ; ADDRESS ; - SENDER ; - IFCMPNEQ - { SENDER ; - PUSH string "Only the owner can operate." ; - PAIR ; - FAILWITH ; - } - { DIP { CDR ; NIL operation } ; - IF_LEFT - { # 'set_delegate' entrypoint - SOME ; - SET_DELEGATE ; - CONS ; - PAIR ; - } - { # 'remove_delegate' entrypoint - DROP ; - NONE key_hash ; - SET_DELEGATE ; - CONS ; - PAIR ; - } - } - } - { # Transform the inputs to the original script types - DIP { CDR ; DUP ; CDR } ; - PAIR ; - - # 'default' entrypoint - original code - { UNPAIR; - IF_LEFT - { DIP { UNPAIR ; DROP } } - { DUG 1; UNPAIR ; DIP { DROP } } ; - PAIR ; NIL operation ; PAIR } - # Transform the outputs to the new script types (manager's storage is unchanged) - SWAP ; - CAR ; - SWAP ; - UNPAIR ; - DIP { SWAP ; PAIR } ; - PAIR ; - } - } diff --git a/tests_python/contracts_012/entrypoints/manager.tz b/tests_python/contracts_012/entrypoints/manager.tz deleted file mode 100644 index 06d9b1067bf4..000000000000 --- a/tests_python/contracts_012/entrypoints/manager.tz +++ /dev/null @@ -1,31 +0,0 @@ -parameter - (or - (lambda %do unit (list operation)) - (unit %default)); -storage key_hash; -code - { UNPAIR ; - IF_LEFT - { # 'do' entrypoint - # Assert no token was sent: - # to send tokens, the default entry point should be used - PUSH mutez 0 ; - AMOUNT ; - ASSERT_CMPEQ ; - # Assert that the sender is the manager - DUUP ; - IMPLICIT_ACCOUNT ; - ADDRESS ; - SENDER ; - ASSERT_CMPEQ ; - # Execute the lambda argument - UNIT ; - EXEC ; - PAIR ; - } - { # 'default' entrypoint - DROP ; - NIL operation ; - PAIR ; - } - }; diff --git a/tests_python/contracts_012/entrypoints/no_default_target.tz b/tests_python/contracts_012/entrypoints/no_default_target.tz deleted file mode 100644 index 48d5d53df996..000000000000 --- a/tests_python/contracts_012/entrypoints/no_default_target.tz +++ /dev/null @@ -1,11 +0,0 @@ -storage (pair string nat) ; -parameter - (or unit (or %data string nat)) ; -code { UNPAIR ; - IF_LEFT - { DROP ; NIL operation ; PAIR } - { IF_LEFT - { DIP { UNPAIR ; DROP } } - { DUG 1; UNPAIR ; DIP { DROP } } ; - PAIR ; NIL operation ; PAIR } - } diff --git a/tests_python/contracts_012/entrypoints/no_entrypoint_target.tz b/tests_python/contracts_012/entrypoints/no_entrypoint_target.tz deleted file mode 100644 index d8041507d58c..000000000000 --- a/tests_python/contracts_012/entrypoints/no_entrypoint_target.tz +++ /dev/null @@ -1,11 +0,0 @@ -storage (pair string nat) ; -parameter - (or unit (or string nat)) ; -code { UNPAIR ; - IF_LEFT - { DROP ; NIL operation ; PAIR } - { IF_LEFT - { DIP { UNPAIR ; DROP } } - { DUG 1; UNPAIR ; DIP { DROP } } ; - PAIR ; NIL operation ; PAIR } - } diff --git a/tests_python/contracts_012/entrypoints/rooted_target.tz b/tests_python/contracts_012/entrypoints/rooted_target.tz deleted file mode 100644 index 2ca2dfb1296d..000000000000 --- a/tests_python/contracts_012/entrypoints/rooted_target.tz +++ /dev/null @@ -1,11 +0,0 @@ -storage (pair string nat) ; -parameter - (or %root unit (or %default string nat)) ; -code { UNPAIR ; - IF_LEFT - { DROP ; NIL operation ; PAIR } - { IF_LEFT - { DIP { UNPAIR ; DROP } } - { DUG 1; UNPAIR ; DIP { DROP } } ; - PAIR ; NIL operation ; PAIR } - } diff --git a/tests_python/contracts_012/entrypoints/simple_entrypoints.tz b/tests_python/contracts_012/entrypoints/simple_entrypoints.tz deleted file mode 100644 index 7b7abb7cb86e..000000000000 --- a/tests_python/contracts_012/entrypoints/simple_entrypoints.tz +++ /dev/null @@ -1,4 +0,0 @@ -# A trivial contract with some entrypoints -parameter (or (unit %A) (or (string %B) (nat %C))) ; -storage unit; -code { CDR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/ill_typed/badly_indented.tz b/tests_python/contracts_012/ill_typed/badly_indented.tz deleted file mode 100644 index 0fc54663a9f9..000000000000 --- a/tests_python/contracts_012/ill_typed/badly_indented.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter string; - storage string; - code {CAR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/ill_typed/big_dip.tz b/tests_python/contracts_012/ill_typed/big_dip.tz deleted file mode 100644 index 697370fdc87e..000000000000 --- a/tests_python/contracts_012/ill_typed/big_dip.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter unit; -storage unit; -code { DIP 1073741824 { }; # = 0x3fffffff + 1 - DROP; } diff --git a/tests_python/contracts_012/ill_typed/big_drop.tz b/tests_python/contracts_012/ill_typed/big_drop.tz deleted file mode 100644 index 40d81cf8448b..000000000000 --- a/tests_python/contracts_012/ill_typed/big_drop.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter unit; -storage unit; -code { DROP 1073741824; # = 0x3fffffff + 1 - DROP; } diff --git a/tests_python/contracts_012/ill_typed/big_map_arity.tz b/tests_python/contracts_012/ill_typed/big_map_arity.tz deleted file mode 100644 index 5e5a7d60d5b7..000000000000 --- a/tests_python/contracts_012/ill_typed/big_map_arity.tz +++ /dev/null @@ -1,5 +0,0 @@ -# This contract tests the error message in case the EMPTY_BIG_MAP instruction has bad arity (1 argument instead of 2). -# The expected type-checking error is "primitive EMPTY_BIG_MAP expects 2 arguments but is given 1." -parameter unit; -storage unit; -code { DROP; EMPTY_BIG_MAP nat; DROP; UNIT; NIL operation; PAIR; } diff --git a/tests_python/contracts_012/ill_typed/chain_id_arity.tz b/tests_python/contracts_012/ill_typed/chain_id_arity.tz deleted file mode 100644 index 4bc9f4f70107..000000000000 --- a/tests_python/contracts_012/ill_typed/chain_id_arity.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (chain_id nat); -storage unit; -code { CDR; NIL operation; PAIR } diff --git a/tests_python/contracts_012/ill_typed/comb0.tz b/tests_python/contracts_012/ill_typed/comb0.tz deleted file mode 100644 index ab3c79153035..000000000000 --- a/tests_python/contracts_012/ill_typed/comb0.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage unit; -code { PAIR 0 } diff --git a/tests_python/contracts_012/ill_typed/comb1.tz b/tests_python/contracts_012/ill_typed/comb1.tz deleted file mode 100644 index 07b709d61cfd..000000000000 --- a/tests_python/contracts_012/ill_typed/comb1.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage unit; -code { PAIR 1 } diff --git a/tests_python/contracts_012/ill_typed/contract_annotation_default.tz b/tests_python/contracts_012/ill_typed/contract_annotation_default.tz deleted file mode 100644 index 742e140c5e48..000000000000 --- a/tests_python/contracts_012/ill_typed/contract_annotation_default.tz +++ /dev/null @@ -1,11 +0,0 @@ -parameter (contract (or (or (int %A) (nat %B)) (unit %default))); -storage unit; -code { - CAR; - # CONTRACT %default nat == CONTRACT nat and the former is not allowed. - DUP; ADDRESS; CONTRACT %default nat; ASSERT_SOME; DROP; - DROP; - UNIT; - NIL operation; - PAIR - }; diff --git a/tests_python/contracts_012/ill_typed/dip_failwith.tz b/tests_python/contracts_012/ill_typed/dip_failwith.tz deleted file mode 100644 index fe3a17b7b1ab..000000000000 --- a/tests_python/contracts_012/ill_typed/dip_failwith.tz +++ /dev/null @@ -1,4 +0,0 @@ -# Test that DIP {FAILWITH} is not allowed by the typechecker -parameter string; -storage nat; -code { UNPAIR; DIP {FAILWITH} } diff --git a/tests_python/contracts_012/ill_typed/dup0.tz b/tests_python/contracts_012/ill_typed/dup0.tz deleted file mode 100644 index 2e46599e490a..000000000000 --- a/tests_python/contracts_012/ill_typed/dup0.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage unit; -code { DUP 0 } diff --git a/tests_python/contracts_012/ill_typed/failwith_big_map.tz b/tests_python/contracts_012/ill_typed/failwith_big_map.tz deleted file mode 100644 index 33d73c26123c..000000000000 --- a/tests_python/contracts_012/ill_typed/failwith_big_map.tz +++ /dev/null @@ -1,22 +0,0 @@ -# This contract uses FAILWITH to expose a big map diff -# See https://gitlab.com/tezos/tezos/-/issues/1708#note_667884499 - -parameter (big_map int int); - -# Even if the stored big_map is dropped by the initial CAR instruction, -# it can still be accessed by its big-map id and sent as parameter so -# it is important that the type of the storage matches the type of the -# parameter. - -# This test is now ill-typed because FAILWITH accepts only packable types - -storage (big_map int int); - -code { CAR; - PUSH (option int) (Some 1); - PUSH int 1; - UPDATE; - PUSH (option int) None; - PUSH int 2; - UPDATE; - FAILWITH } diff --git a/tests_python/contracts_012/ill_typed/invalid_self_entrypoint.tz b/tests_python/contracts_012/ill_typed/invalid_self_entrypoint.tz deleted file mode 100644 index 4fac9c635044..000000000000 --- a/tests_python/contracts_012/ill_typed/invalid_self_entrypoint.tz +++ /dev/null @@ -1,10 +0,0 @@ -parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))); -storage unit; -code { - DROP; - # This entrypoint does not exist - SELF %D; DROP; - UNIT; - NIL operation; - PAIR; - } diff --git a/tests_python/contracts_012/ill_typed/map_failwith.tz b/tests_python/contracts_012/ill_typed/map_failwith.tz deleted file mode 100644 index e3e19c0784ce..000000000000 --- a/tests_python/contracts_012/ill_typed/map_failwith.tz +++ /dev/null @@ -1,4 +0,0 @@ -# Test that MAP {FAILWITH} is not allowed by the typechecker -parameter (list nat); -storage unit; -code { UNPAIR; MAP {FAILWITH}; DROP; NIL operation; PAIR } diff --git a/tests_python/contracts_012/ill_typed/missing_only_code_field.tz b/tests_python/contracts_012/ill_typed/missing_only_code_field.tz deleted file mode 100644 index 4b5b2cd62f56..000000000000 --- a/tests_python/contracts_012/ill_typed/missing_only_code_field.tz +++ /dev/null @@ -1,2 +0,0 @@ -storage unit; -parameter nat; \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/missing_only_parameter_field.tz b/tests_python/contracts_012/ill_typed/missing_only_parameter_field.tz deleted file mode 100644 index 1f7e8ac75da9..000000000000 --- a/tests_python/contracts_012/ill_typed/missing_only_parameter_field.tz +++ /dev/null @@ -1,4 +0,0 @@ -storage unit; -code { CAR; - DUP; NEG; ABS; COMPARE; ASSERT_EQ; - UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/missing_only_storage_field.tz b/tests_python/contracts_012/ill_typed/missing_only_storage_field.tz deleted file mode 100644 index 2aa28922287a..000000000000 --- a/tests_python/contracts_012/ill_typed/missing_only_storage_field.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter nat; -code { CAR; - DUP; NEG; ABS; COMPARE; ASSERT_EQ; - UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/missing_parameter_and_storage_fields.tz b/tests_python/contracts_012/ill_typed/missing_parameter_and_storage_fields.tz deleted file mode 100644 index 18e7b35b0a8c..000000000000 --- a/tests_python/contracts_012/ill_typed/missing_parameter_and_storage_fields.tz +++ /dev/null @@ -1,3 +0,0 @@ -code { CAR; - DUP; NEG; ABS; COMPARE; ASSERT_EQ; - UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/multiple_code_field.tz b/tests_python/contracts_012/ill_typed/multiple_code_field.tz deleted file mode 100644 index cd47b356d14e..000000000000 --- a/tests_python/contracts_012/ill_typed/multiple_code_field.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter nat; -storage unit; -code { CAR; - DUP; NEG; ABS; COMPARE; ASSERT_EQ; - UNIT; NIL operation; PAIR }; -code {} \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/multiple_parameter_field.tz b/tests_python/contracts_012/ill_typed/multiple_parameter_field.tz deleted file mode 100644 index e59fb9fe05be..000000000000 --- a/tests_python/contracts_012/ill_typed/multiple_parameter_field.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter nat; -parameter nat; -storage unit; -code { CAR; - DUP; NEG; ABS; COMPARE; ASSERT_EQ; - UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/multiple_storage_and_code_fields.tz b/tests_python/contracts_012/ill_typed/multiple_storage_and_code_fields.tz deleted file mode 100644 index 3b32484dc200..000000000000 --- a/tests_python/contracts_012/ill_typed/multiple_storage_and_code_fields.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter nat; -storage unit; -storage unit; -code { CAR; - DUP; NEG; ABS; COMPARE; ASSERT_EQ; - UNIT; NIL operation; PAIR }; -code {} \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/multiple_storage_field.tz b/tests_python/contracts_012/ill_typed/multiple_storage_field.tz deleted file mode 100644 index 06c25f51d3b2..000000000000 --- a/tests_python/contracts_012/ill_typed/multiple_storage_field.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter nat; -storage unit; -storage unit; -code { CAR; - DUP; NEG; ABS; COMPARE; ASSERT_EQ; - UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/never_literal.tz b/tests_python/contracts_012/ill_typed/never_literal.tz deleted file mode 100644 index ba36b3b5f205..000000000000 --- a/tests_python/contracts_012/ill_typed/never_literal.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { - PUSH never {}; - FAILWITH - } diff --git a/tests_python/contracts_012/ill_typed/pack_big_map.tz b/tests_python/contracts_012/ill_typed/pack_big_map.tz deleted file mode 100644 index 29ae0d665051..000000000000 --- a/tests_python/contracts_012/ill_typed/pack_big_map.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter unit; -storage (pair (big_map int int) unit); -code { CDAR; - DUP; PACK; DROP; - UNIT; SWAP; PAIR; - NIL operation; - PAIR; } diff --git a/tests_python/contracts_012/ill_typed/pack_operation.tz b/tests_python/contracts_012/ill_typed/pack_operation.tz deleted file mode 100644 index 349ca053af27..000000000000 --- a/tests_python/contracts_012/ill_typed/pack_operation.tz +++ /dev/null @@ -1,20 +0,0 @@ -parameter unit; -storage unit; -code { DROP; - UNIT; # starting storage for contract - AMOUNT; # Push the starting balance - NONE key_hash; # No delegate - CREATE_CONTRACT # Create the contract - { parameter unit ; - storage unit ; - code - { CDR; - NIL operation; - PAIR; } }; - DIP { DROP }; - # invalid PACK - PACK; - DROP; - UNIT; - NIL operation; - PAIR; } diff --git a/tests_python/contracts_012/ill_typed/pack_sapling_state.tz b/tests_python/contracts_012/ill_typed/pack_sapling_state.tz deleted file mode 100644 index 0524d9b27911..000000000000 --- a/tests_python/contracts_012/ill_typed/pack_sapling_state.tz +++ /dev/null @@ -1,13 +0,0 @@ -# Verify SAPLING_STATE is not packable. The contract should not typecheck when using `PACK`. -# The lines below PACK are present only in case of PACK allows SAPLING_STATE to -# make the typechecker happy. -parameter unit; -storage (sapling_state 8); -code { UNPAIR; - DROP; - PACK; - DROP; - SAPLING_EMPTY_STATE 8; - NIL operation; - PAIR; - } diff --git a/tests_python/contracts_012/ill_typed/push_big_map_with_id_with_parens.tz b/tests_python/contracts_012/ill_typed/push_big_map_with_id_with_parens.tz deleted file mode 100644 index 2c659e9a639d..000000000000 --- a/tests_python/contracts_012/ill_typed/push_big_map_with_id_with_parens.tz +++ /dev/null @@ -1,10 +0,0 @@ -# This contract verifies it is not possible to use the instruction `PUSH big_map -# tk tv i` where i is the ID of an existing big_map -parameter int; -storage (big_map string nat); -code { UNPAIR; - DROP; - PUSH (big_map string nat) 0; - NIL operation; - PAIR - } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/push_big_map_with_id_without_parens.tz b/tests_python/contracts_012/ill_typed/push_big_map_with_id_without_parens.tz deleted file mode 100644 index c5eeef97c7e3..000000000000 --- a/tests_python/contracts_012/ill_typed/push_big_map_with_id_without_parens.tz +++ /dev/null @@ -1,11 +0,0 @@ -# This contract verifies it is not possible to use the instruction `PUSH big_map -# tk tv i` where i is the ID of an existing big_map -parameter int; -storage (big_map string nat); -code { - UNPAIR; - DROP; - PUSH big_map string nat 0; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/sapling_build_empty_state_with_int_parameter.tz b/tests_python/contracts_012/ill_typed/sapling_build_empty_state_with_int_parameter.tz deleted file mode 100644 index 21b48391060b..000000000000 --- a/tests_python/contracts_012/ill_typed/sapling_build_empty_state_with_int_parameter.tz +++ /dev/null @@ -1,10 +0,0 @@ -parameter nat; -storage (sapling_state 8); -code { - UNPAIR; - SWAP; - DROP; - SAPLING_EMPTY_STATE; - NIL operation; - PAIR; - }; diff --git a/tests_python/contracts_012/ill_typed/set_update_non_comparable.tz b/tests_python/contracts_012/ill_typed/set_update_non_comparable.tz deleted file mode 100644 index 4a70691793c7..000000000000 --- a/tests_python/contracts_012/ill_typed/set_update_non_comparable.tz +++ /dev/null @@ -1,9 +0,0 @@ -# This contract tests the error message in case the UPDATE instruction on set -# is used with a non-comparable type -parameter (set nat); -storage unit; -code { CAR; - PUSH bool True; - NIL operation; - UPDATE; - UNIT; NIL operation; PAIR; } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undig2able.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undig2able.tz deleted file mode 100644 index 6f7061e004a0..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_undig2able.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter unit; -storage unit; -code { - DIG 2; - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undigable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undigable.tz deleted file mode 100644 index 2aba7d303eaf..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_undigable.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { - DROP; - DIG 0; - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undip2able.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undip2able.tz deleted file mode 100644 index e048a24f74b8..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_undip2able.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { - DUP; - DIP 2 { DUP }; - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undipable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undipable.tz deleted file mode 100644 index 09f94b133e50..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_undipable.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter unit; -storage unit; -code { - DIP { DUP }; - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undropable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undropable.tz deleted file mode 100644 index d33142cdb82b..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_undropable.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter unit; -storage unit; -code { - DROP 2; - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undug2able.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undug2able.tz deleted file mode 100644 index 5eef1da706f2..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_undug2able.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter unit; -storage unit; -code { - DUG 2; - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undugable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undugable.tz deleted file mode 100644 index eaf5d7d486e7..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_undugable.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { - DROP; - DUG 0; - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undup2able.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undup2able.tz deleted file mode 100644 index c760764fd5b2..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_undup2able.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter unit; -storage unit; -code { - DUP 2; - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unfailwithable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unfailwithable.tz deleted file mode 100644 index c8cf263e5dcc..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_unfailwithable.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { - DROP; - FAILWITH; - } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_ungetable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_ungetable.tz deleted file mode 100644 index 6bc5a629e2a4..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_ungetable.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { - DROP; - GET; - } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unleftable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unleftable.tz deleted file mode 100644 index 0bc846effa3b..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_unleftable.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { - DROP; - LEFT unit; - } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unpairable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unpairable.tz deleted file mode 100644 index 70f7e3a40c10..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_unpairable.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { - DROP; - UNPAIR; - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unpopable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unpopable.tz deleted file mode 100644 index 0f1d8ea456a2..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_unpopable.tz +++ /dev/null @@ -1,10 +0,0 @@ -parameter unit; -storage unit; -code { - DROP ; - DUP ; - DROP ; - PUSH unit Unit ; - NIL operation ; - PAIR - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unpopable_in_lambda.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unpopable_in_lambda.tz deleted file mode 100644 index 4299b8bef474..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_unpopable_in_lambda.tz +++ /dev/null @@ -1,10 +0,0 @@ -parameter unit; -storage unit; -code { - DROP ; - LAMBDA int unit { DROP ; DUP }; - DROP ; - PUSH unit Unit ; - NIL operation ; - PAIR - } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unrightable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unrightable.tz deleted file mode 100644 index a7cf3d06a470..000000000000 --- a/tests_python/contracts_012/ill_typed/stack_bottom_unrightable.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { - DROP; - RIGHT unit; - } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/ticket_apply.tz b/tests_python/contracts_012/ill_typed/ticket_apply.tz deleted file mode 100644 index a77fb08a6611..000000000000 --- a/tests_python/contracts_012/ill_typed/ticket_apply.tz +++ /dev/null @@ -1,17 +0,0 @@ -# This script attempts to duplicate a ticket by capturing it using APPLY. -# Is should fail at parsing because tickets are not packable so they are -# not allowed to be captured by APPLY. -parameter (ticket unit); -storage (option (pair (ticket unit) (ticket unit))); -code { - CAR; - LAMBDA (pair (ticket unit) unit) (ticket unit) { CAR }; - SWAP; APPLY; - DUP; - UNIT; EXEC; SWAP; - UNIT; EXEC; - PAIR; - SOME; - NIL operation; - PAIR - } diff --git a/tests_python/contracts_012/ill_typed/ticket_dup.tz b/tests_python/contracts_012/ill_typed/ticket_dup.tz deleted file mode 100644 index fee0ea3785bc..000000000000 --- a/tests_python/contracts_012/ill_typed/ticket_dup.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (ticket %store nat) ; -storage unit; -code { UNPAIR; DUP; DROP 2; NIL operation; PAIR } diff --git a/tests_python/contracts_012/ill_typed/ticket_in_ticket.tz b/tests_python/contracts_012/ill_typed/ticket_in_ticket.tz deleted file mode 100644 index ee6bdf238723..000000000000 --- a/tests_python/contracts_012/ill_typed/ticket_in_ticket.tz +++ /dev/null @@ -1,16 +0,0 @@ -# This script attempts to duplicate a ticket by storing it -# in another ticket and calling READ_TICKET twice on it. -# It should fail at parsing because ticket contents must be -# comparable so (ticket (ticket unit)) cannot be built. -parameter (ticket unit); -storage (option (pair (ticket unit) (ticket unit))); -code { - CAR; - PUSH nat 0; - SWAP; - TICKET; - READ_TICKET; CDR; CAR; - SWAP; READ_TICKET; CDR; CAR; - SWAP; DROP; - PAIR; SOME; NIL operation; PAIR - } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/ticket_unpack.tz b/tests_python/contracts_012/ill_typed/ticket_unpack.tz deleted file mode 100644 index 888746f42eb0..000000000000 --- a/tests_python/contracts_012/ill_typed/ticket_unpack.tz +++ /dev/null @@ -1,5 +0,0 @@ -# UNPACK on ticket should produce a type error -parameter unit; -storage (option (ticket nat)); -code { DROP ; PUSH nat 2 ; PACK ; UNPACK (ticket nat) ; - NIL operation ; PAIR } diff --git a/tests_python/contracts_012/ill_typed/uncomb0.tz b/tests_python/contracts_012/ill_typed/uncomb0.tz deleted file mode 100644 index 9c3370912937..000000000000 --- a/tests_python/contracts_012/ill_typed/uncomb0.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage unit; -code { UNPAIR 0 } diff --git a/tests_python/contracts_012/ill_typed/uncomb1.tz b/tests_python/contracts_012/ill_typed/uncomb1.tz deleted file mode 100644 index 6cc515335072..000000000000 --- a/tests_python/contracts_012/ill_typed/uncomb1.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage unit; -code { UNPAIR 1 } diff --git a/tests_python/contracts_012/ill_typed/unpack_sapling_state.tz b/tests_python/contracts_012/ill_typed/unpack_sapling_state.tz deleted file mode 100644 index a80f81eb84b6..000000000000 --- a/tests_python/contracts_012/ill_typed/unpack_sapling_state.tz +++ /dev/null @@ -1,12 +0,0 @@ -# Verify SAPLING_STATE is not packable. The contract should not typecheck when using `UNPACK`. -# The lines below UNPACK are present only in case of UNPACK allows SAPLING_STATE to -# make the typechecker happy. -parameter bytes; -storage (unit); -code { CAR; - UNPACK (sapling_state 8); - DROP; - PUSH unit Unit; - NIL operation; - PAIR; - } diff --git a/tests_python/contracts_012/ill_typed/unpair_field_annotation_mismatch.tz b/tests_python/contracts_012/ill_typed/unpair_field_annotation_mismatch.tz deleted file mode 100644 index c2b3fe0a498d..000000000000 --- a/tests_python/contracts_012/ill_typed/unpair_field_annotation_mismatch.tz +++ /dev/null @@ -1,10 +0,0 @@ -parameter (unit :param_unit); -storage (unit :u1); -code { DROP ; - - UNIT @b; UNIT @a; PAIR %@ %@; - # Field annotations must match (or be ommited) - DUP; UNPAIR %c %d; DROP 2; - DROP; - - UNIT; NIL operation; PAIR } diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_char_set.tz b/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_char_set.tz deleted file mode 100644 index 1bc14a4facef..000000000000 --- a/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_char_set.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage nat ; -code { CAR ; UNPAIR ; VIEW "^$&*!#~(-=)" nat ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_type.tz b/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_type.tz deleted file mode 100644 index 4bde2b617adc..000000000000 --- a/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_type.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage nat ; -code { CAR ; UNPAIR ; VIEW 1 nat ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_name_non_printable_char.tz b/tests_python/contracts_012/ill_typed/view_op_bad_name_non_printable_char.tz deleted file mode 100644 index 22b3f5665af5..000000000000 --- a/tests_python/contracts_012/ill_typed/view_op_bad_name_non_printable_char.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage nat ; -code { CAR ; UNPAIR ; VIEW "\\x00" nat ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_name_too_long.tz b/tests_python/contracts_012/ill_typed/view_op_bad_name_too_long.tz deleted file mode 100644 index 263ecba19684..000000000000 --- a/tests_python/contracts_012/ill_typed/view_op_bad_name_too_long.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter (pair nat address) ; -storage nat ; -code { CAR ; UNPAIR ; VIEW "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" nat ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; - diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_return_type.tz b/tests_python/contracts_012/ill_typed/view_op_bad_return_type.tz deleted file mode 100644 index 3c9ef69e7ffa..000000000000 --- a/tests_python/contracts_012/ill_typed/view_op_bad_return_type.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage nat ; -code { CAR ; UNPAIR ; VIEW "add" string; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_dupable_type.tz b/tests_python/contracts_012/ill_typed/view_op_dupable_type.tz deleted file mode 100644 index 45e7ebc43704..000000000000 --- a/tests_python/contracts_012/ill_typed/view_op_dupable_type.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage nat ; -code { CAR ; UNPAIR ; VIEW "add" (ticket nat); DROP ; PUSH nat 1 ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_invalid_arity.tz b/tests_python/contracts_012/ill_typed/view_op_invalid_arity.tz deleted file mode 100644 index a56f40d15c54..000000000000 --- a/tests_python/contracts_012/ill_typed/view_op_invalid_arity.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage nat ; -code { CAR ; UNPAIR ; VIEW "add" ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_lazy_storage.tz b/tests_python/contracts_012/ill_typed/view_op_lazy_storage.tz deleted file mode 100644 index 82bfb31f0bce..000000000000 --- a/tests_python/contracts_012/ill_typed/view_op_lazy_storage.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter address; -storage (big_map string nat); -code { - CAR; - UNIT; - VIEW "get_map" (big_map string nat); - IF_SOME { PUSH nat 10 ; SOME ; PUSH string "bar"; UPDATE; NIL operation; PAIR; } { FAIL; } - } diff --git a/tests_python/contracts_012/ill_typed/view_op_lazy_storage_type.tz b/tests_python/contracts_012/ill_typed/view_op_lazy_storage_type.tz deleted file mode 100644 index 82bfb31f0bce..000000000000 --- a/tests_python/contracts_012/ill_typed/view_op_lazy_storage_type.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter address; -storage (big_map string nat); -code { - CAR; - UNIT; - VIEW "get_map" (big_map string nat); - IF_SOME { PUSH nat 10 ; SOME ; PUSH string "bar"; UPDATE; NIL operation; PAIR; } { FAIL; } - } diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_input_type.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_input_type.tz deleted file mode 100644 index 9d1551d24285..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_bad_input_type.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter nat ; -storage nat ; -code { CAR ; NIL operation ; PAIR } ; -view "add" string nat { UNPAIR; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_char_set.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_char_set.tz deleted file mode 100644 index f9d2a3f1ad5b..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_char_set.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter nat ; -storage nat ; -code { CAR ; NIL operation ; PAIR } ; -view "^$&*!#~(-=)" nat nat { UNPAIR ; ADD } ; - diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_type.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_type.tz deleted file mode 100644 index fafd89ffd29a..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_type.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter nat ; -storage nat ; -code { CAR ; NIL operation ; PAIR } ; -view 1 nat nat { UNPAIR ; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_non_printable_char.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_non_printable_char.tz deleted file mode 100644 index 7a1128527518..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_non_printable_char.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter nat ; -storage nat ; -code { CAR ; NIL operation ; PAIR } ; -view "\\x00" nat nat { UNPAIR ; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_too_long.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_too_long.tz deleted file mode 100644 index 4f61ae081410..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_too_long.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter nat ; -storage nat ; -code { CAR ; NIL operation ; PAIR } ; -view "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" nat nat { UNPAIR ; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_return_type.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_return_type.tz deleted file mode 100644 index 4572674664ca..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_bad_return_type.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter nat ; -storage nat ; -code { CAR ; NIL operation ; PAIR } ; -view "add" nat nat { DROP ; PUSH unit Unit } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_type.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_type.tz deleted file mode 100644 index a56d7bc4f88e..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_bad_type.tz +++ /dev/null @@ -1,7 +0,0 @@ -{ parameter nat; - storage nat; - code { CAR; NIL operation ; PAIR }; - view "add_v" nat nat { UNPAIR; ADD }; - view "mul_v" nat nat { UNPAIR; PUSH nat 30; LSR; }; -} - diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_input.tz b/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_input.tz deleted file mode 100644 index c252b2eddb28..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_input.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter nat; -storage nat; -code { CAR ; NIL operation ; PAIR } ; -view "dup" (ticket nat) nat { DROP; PUSH nat 1; PUSH nat 1 ; PAIR} ; - diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_output.tz b/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_output.tz deleted file mode 100644 index 17919d0004dc..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_output.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter nat; -storage nat; -code { CAR ; NIL operation ; PAIR } ; -view "dup" address (ticket nat) { DROP; PUSH nat 1; PUSH nat 1 ; TICKET } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_duplicated_name.tz b/tests_python/contracts_012/ill_typed/view_toplevel_duplicated_name.tz deleted file mode 100644 index 680b0ab585d1..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_duplicated_name.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter nat ; -storage nat ; -code { CAR ; NIL operation ; PAIR } ; -view "add" nat nat { UNPAIR ; ADD } ; -view "add" nat unit { DROP ; PUSH unit Unit } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_invalid_arity.tz b/tests_python/contracts_012/ill_typed/view_toplevel_invalid_arity.tz deleted file mode 100644 index 929e27b6a766..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_invalid_arity.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter nat ; -storage nat ; -code { CAR ; NIL operation ; PAIR } ; -view "add" nat nat nat { UNPAIR ; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_input.tz b/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_input.tz deleted file mode 100644 index 3ae7f626a1cf..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_input.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter unit; -storage nat; -code { FAIL }; -view "map" (big_map string nat) unit { DROP; UNIT;}; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_output.tz b/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_output.tz deleted file mode 100644 index b0ecc0503343..000000000000 --- a/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_output.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter unit; -storage nat; -code { FAIL; }; -view "get_map" unit (big_map string nat) { CDR; CDR; }; diff --git a/tests_python/contracts_012/legacy/create_account.tz b/tests_python/contracts_012/legacy/create_account.tz deleted file mode 100644 index 7cd38465a10b..000000000000 --- a/tests_python/contracts_012/legacy/create_account.tz +++ /dev/null @@ -1,29 +0,0 @@ -/* -- optional storage: the address of the created account -- param: Left [hash]: - - Create an account with manager [hash]; then perform a recursive call - on Right [addr] where [addr] is the address of the newly created - account. - - The created account has an initial balance of 100tz. It is not - delegatable. - -- param: Right [addr]: - - Check that the sender is self and that [addr] is a contract of type - [unit]. Finally store [addr]. - -*/ -parameter (or key_hash address) ; -storage (option address) ; -code { CAR; - IF_LEFT - { DIP { PUSH mutez 100000000 ; PUSH bool False ; NONE key_hash }; - CREATE_ACCOUNT ; - DIP { RIGHT key_hash ; DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS } ; - CONS ; NONE address ; SWAP ; PAIR } - { SELF ; ADDRESS ; SENDER ; IFCMPNEQ { FAIL } {} ; - DUP ; CONTRACT unit ; IF_SOME { DROP ; SOME } { FAIL } ; - NIL operation ; PAIR } } ; diff --git a/tests_python/contracts_012/legacy/create_contract.tz b/tests_python/contracts_012/legacy/create_contract.tz deleted file mode 100644 index a162044ac62b..000000000000 --- a/tests_python/contracts_012/legacy/create_contract.tz +++ /dev/null @@ -1,18 +0,0 @@ -parameter (or key_hash address); -storage unit; -code { CAR; - IF_LEFT - { DIP { PUSH string "dummy"; - PUSH mutez 100000000 ; PUSH bool False ; - PUSH bool False ; NONE key_hash } ; - CREATE_CONTRACT - { parameter string ; - storage string ; - code { CAR ; NIL operation ; PAIR } } ; - DIP { RIGHT key_hash ; DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS } ; - CONS ; UNIT ; SWAP ; PAIR } - { SELF ; ADDRESS ; SENDER ; IFCMPNEQ { FAIL } {} ; - CONTRACT string ; IF_SOME {} { FAIL } ; - PUSH mutez 0 ; PUSH string "abcdefg" ; TRANSFER_TOKENS ; - NIL operation; SWAP; CONS ; UNIT ; SWAP ; PAIR } }; diff --git a/tests_python/contracts_012/legacy/create_contract_flags.tz b/tests_python/contracts_012/legacy/create_contract_flags.tz deleted file mode 100644 index 888637dd7266..000000000000 --- a/tests_python/contracts_012/legacy/create_contract_flags.tz +++ /dev/null @@ -1,26 +0,0 @@ -parameter (pair key_hash (pair bool bool)); -storage unit; -code { CAR; - - UNPAPAIR @mgr @spendable @deletagable; - DIP { NONE @delegate key_hash } ; - DIIIIP { UNIT @init; - PUSH @credit mutez 100000000 ; - }; - # type of legacy create_contract - # :: key_hash : option key_hash : bool : bool : mutez : 'g : 'S - # -> operation : address : 'S - CREATE_CONTRACT - { parameter (string %default) ; - storage unit ; - code { DROP; UNIT ; NIL operation ; PAIR } } ; - # simulate create_contract but typecheck for dev - # DROP 6; - # PUSH address "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; - # NONE key_hash; SET_DELEGATE @origination; - DIP { DROP }; - - NIL operation; - SWAP; CONS; - UNIT; SWAP; PAIR - }; diff --git a/tests_python/contracts_012/legacy/create_contract_rootname.tz b/tests_python/contracts_012/legacy/create_contract_rootname.tz deleted file mode 100644 index 13e24ae5cc24..000000000000 --- a/tests_python/contracts_012/legacy/create_contract_rootname.tz +++ /dev/null @@ -1,18 +0,0 @@ -parameter (or key_hash address); -storage unit; -code { CAR; - IF_LEFT - { DIP { PUSH string "dummy"; - PUSH mutez 100000000 ; PUSH bool False ; - PUSH bool False ; NONE key_hash } ; - CREATE_CONTRACT - { parameter (string %root) ; - storage string ; - code { CAR ; NIL operation ; PAIR } } ; - DIP { RIGHT key_hash ; DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS } ; - CONS ; UNIT ; SWAP ; PAIR } - { SELF ; ADDRESS ; SENDER ; IFCMPNEQ { FAIL } {} ; - CONTRACT string ; IF_SOME {} { FAIL } ; - PUSH mutez 0 ; PUSH string "abcdefg" ; TRANSFER_TOKENS ; - NIL operation; SWAP; CONS ; UNIT ; SWAP ; PAIR } }; diff --git a/tests_python/contracts_012/legacy/originator.tz b/tests_python/contracts_012/legacy/originator.tz deleted file mode 100644 index c454e230dc6d..000000000000 --- a/tests_python/contracts_012/legacy/originator.tz +++ /dev/null @@ -1,16 +0,0 @@ -parameter nat ; -storage (list address) ; -code - { DUP ; CAR ; PUSH nat 0 ; CMPNEQ ; - DIP { DUP ; CAR ; DIP { CDR ; NIL operation } } ; - LOOP - { PUSH mutez 5000000 ; - PUSH bool True ; # delegatable - NONE key_hash ; # delegate - PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ; # manager - CREATE_ACCOUNT ; - SWAP ; DIP { SWAP ; DIP { CONS } } ; - SWAP ; DIP { SWAP ; DIP { CONS } } ; - PUSH nat 1 ; SWAP ; SUB ; ABS ; - DUP ; PUSH nat 0 ; CMPNEQ } ; - DROP ; PAIR } diff --git a/tests_python/contracts_012/legacy/steps_to_quota.tz b/tests_python/contracts_012/legacy/steps_to_quota.tz deleted file mode 100644 index 78e76e308931..000000000000 --- a/tests_python/contracts_012/legacy/steps_to_quota.tz +++ /dev/null @@ -1,12 +0,0 @@ -parameter int ; -storage nat ; -code { CAR; - DUP; - GT; - LOOP { PUSH int 1; SWAP; SUB; DUP; GT; }; - DROP; - STEPS_TO_QUOTA; - # PUSH nat 1; - NIL operation; - PAIR; - }; diff --git a/tests_python/contracts_012/macros/assert.tz b/tests_python/contracts_012/macros/assert.tz deleted file mode 100644 index 6c5ce503b551..000000000000 --- a/tests_python/contracts_012/macros/assert.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter bool; -storage unit; -code {CAR; ASSERT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmpeq.tz b/tests_python/contracts_012/macros/assert_cmpeq.tz deleted file mode 100644 index 55621bac8fe3..000000000000 --- a/tests_python/contracts_012/macros/assert_cmpeq.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPEQ; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmpge.tz b/tests_python/contracts_012/macros/assert_cmpge.tz deleted file mode 100644 index e98b17044541..000000000000 --- a/tests_python/contracts_012/macros/assert_cmpge.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPGE; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmpgt.tz b/tests_python/contracts_012/macros/assert_cmpgt.tz deleted file mode 100644 index 7a44174b7259..000000000000 --- a/tests_python/contracts_012/macros/assert_cmpgt.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPGT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmple.tz b/tests_python/contracts_012/macros/assert_cmple.tz deleted file mode 100644 index e4b61cfc44c3..000000000000 --- a/tests_python/contracts_012/macros/assert_cmple.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPLE; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmplt.tz b/tests_python/contracts_012/macros/assert_cmplt.tz deleted file mode 100644 index 290b495378df..000000000000 --- a/tests_python/contracts_012/macros/assert_cmplt.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPLT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmpneq.tz b/tests_python/contracts_012/macros/assert_cmpneq.tz deleted file mode 100644 index 86b601393b8c..000000000000 --- a/tests_python/contracts_012/macros/assert_cmpneq.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPNEQ; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_eq.tz b/tests_python/contracts_012/macros/assert_eq.tz deleted file mode 100644 index 338096a6277c..000000000000 --- a/tests_python/contracts_012/macros/assert_eq.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_EQ; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_ge.tz b/tests_python/contracts_012/macros/assert_ge.tz deleted file mode 100644 index 06bb3cec944b..000000000000 --- a/tests_python/contracts_012/macros/assert_ge.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_GE; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_gt.tz b/tests_python/contracts_012/macros/assert_gt.tz deleted file mode 100644 index d041093b0ebf..000000000000 --- a/tests_python/contracts_012/macros/assert_gt.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_GT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_le.tz b/tests_python/contracts_012/macros/assert_le.tz deleted file mode 100644 index 8250f3f3bdb1..000000000000 --- a/tests_python/contracts_012/macros/assert_le.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_LE; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_lt.tz b/tests_python/contracts_012/macros/assert_lt.tz deleted file mode 100644 index e387e9d74070..000000000000 --- a/tests_python/contracts_012/macros/assert_lt.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_LT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_neq.tz b/tests_python/contracts_012/macros/assert_neq.tz deleted file mode 100644 index 83f19559e1d1..000000000000 --- a/tests_python/contracts_012/macros/assert_neq.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int int); -storage unit; -code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_NEQ; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/big_map_get_add.tz b/tests_python/contracts_012/macros/big_map_get_add.tz deleted file mode 100644 index 2dcf1ce69a08..000000000000 --- a/tests_python/contracts_012/macros/big_map_get_add.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter (pair (pair %set_pair int (option int)) (pair %check_pair int (option int))) ; -storage (pair (big_map int int) unit) ; -code { DUP ; DIP { CDAR } ; - DUP ; DIP { CADR; DUP ; CAR ; DIP { CDR } ; UPDATE ; DUP } ; - CADR ; DUP ; CDR ; DIP { CAR ; GET } ; - IF_SOME { SWAP ; IF_SOME { ASSERT_CMPEQ } {FAIL}} { ASSERT_NONE } ; - UNIT ; SWAP ; PAIR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/macros/big_map_mem.tz b/tests_python/contracts_012/macros/big_map_mem.tz deleted file mode 100644 index 55736ab89da6..000000000000 --- a/tests_python/contracts_012/macros/big_map_mem.tz +++ /dev/null @@ -1,5 +0,0 @@ -# Fails if the boolean does not match the membership criteria -parameter (pair int bool) ; -storage (pair (big_map int unit) unit) ; -code { DUP ; DUP ; CADR ; DIP { CAAR ; DIP { CDAR ; DUP } ; MEM } ; - ASSERT_CMPEQ ; UNIT ; SWAP ; PAIR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/macros/build_list.tz b/tests_python/contracts_012/macros/build_list.tz deleted file mode 100644 index 842056d913ce..000000000000 --- a/tests_python/contracts_012/macros/build_list.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter nat; -storage (list nat); -code { CAR @counter; NIL @acc nat; SWAP; DUP @cmp_num; PUSH nat 0; CMPNEQ; - LOOP { DUP; DIP {SWAP}; CONS @acc; SWAP; PUSH nat 1; SWAP; SUB @counter; - DUP; DIP{ABS}; PUSH int 0; CMPNEQ}; - CONS; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/macros/carn_and_cdrn.tz b/tests_python/contracts_012/macros/carn_and_cdrn.tz deleted file mode 100644 index cc3cdccee81a..000000000000 --- a/tests_python/contracts_012/macros/carn_and_cdrn.tz +++ /dev/null @@ -1,26 +0,0 @@ -# Same as ../opcodes/comb-get.tz but using the CAR n and CDR n macros instead of GET -parameter (pair nat nat nat unit); -storage unit; -code { - CAR ; - - # Checking the first element - DUP ; CAR ; - PUSH nat 1 ; ASSERT_CMPEQ ; - DUP ; CAR 0 ; - PUSH nat 1 ; ASSERT_CMPEQ ; - - # Checking the second element - DUP ; CAR 1 ; - PUSH nat 4 ; ASSERT_CMPEQ ; - - # Checking the third element - DUP ; CAR 2 ; - PUSH nat 2 ; ASSERT_CMPEQ ; - - # Checking the last (fourth) element - DUP ; CDR 3 ; - UNIT ; ASSERT_CMPEQ ; - - DROP ; UNIT ; NIL operation ; PAIR - } diff --git a/tests_python/contracts_012/macros/compare.tz b/tests_python/contracts_012/macros/compare.tz deleted file mode 100644 index 698ef3e695ed..000000000000 --- a/tests_python/contracts_012/macros/compare.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (pair mutez mutez); -storage (list bool); -code {CAR; DUP; DUP; DUP; DUP; DIIIIIP {NIL bool}; - DIIIIP {DUP; CAR; DIP {CDR}; COMPARE; LE; CONS}; - DIIIP {DUP; CAR; DIP {CDR}; COMPARE; GE; CONS}; - DIIP{DUP; CAR; DIP {CDR}; COMPARE; LT; CONS}; - DIP {DUP; CAR; DIP {CDR}; COMPARE; GT; CONS}; - DUP; CAR; DIP {CDR}; COMPARE; EQ; CONS; - NIL operation; PAIR}; diff --git a/tests_python/contracts_012/macros/compare_bytes.tz b/tests_python/contracts_012/macros/compare_bytes.tz deleted file mode 100644 index 3b5e5a9c400c..000000000000 --- a/tests_python/contracts_012/macros/compare_bytes.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (pair bytes bytes); -storage (list bool); -code {CAR; DUP; DUP; DUP; DUP; DIIIIIP {NIL bool}; - DIIIIP {DUP; CAR; DIP {CDR}; COMPARE; LE; CONS}; - DIIIP {DUP; CAR; DIP {CDR}; COMPARE; GE; CONS}; - DIIP{DUP; CAR; DIP {CDR}; COMPARE; LT; CONS}; - DIP {DUP; CAR; DIP {CDR}; COMPARE; GT; CONS}; - DUP; CAR; DIP {CDR}; COMPARE; EQ; CONS; - NIL operation; PAIR}; diff --git a/tests_python/contracts_012/macros/fail.tz b/tests_python/contracts_012/macros/fail.tz deleted file mode 100644 index 7f8bde252130..000000000000 --- a/tests_python/contracts_012/macros/fail.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter unit; -storage unit; -code - { # This contract will never accept a incoming transaction - FAIL}; diff --git a/tests_python/contracts_012/macros/guestbook.tz b/tests_python/contracts_012/macros/guestbook.tz deleted file mode 100644 index b362f94b957e..000000000000 --- a/tests_python/contracts_012/macros/guestbook.tz +++ /dev/null @@ -1,10 +0,0 @@ -parameter string; -storage (map address (option string)); - -code { UNPAIR @message @guestbook; SWAP; - DUP; SENDER; GET @previous_message; - ASSERT_SOME; - ASSERT_NONE; - SWAP; SOME; SOME; SENDER; UPDATE; - NIL operation; - PAIR } diff --git a/tests_python/contracts_012/macros/macro_annotations.tz b/tests_python/contracts_012/macros/macro_annotations.tz deleted file mode 100644 index f48f18e3d942..000000000000 --- a/tests_python/contracts_012/macros/macro_annotations.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage (pair (unit %truc) unit); -code { DROP; UNIT ; UNIT ; PAIR %truc ; UNIT ; - DUUP @new_storage ; - DIP { DROP ; DROP } ; - NIL operation ; PAIR } diff --git a/tests_python/contracts_012/macros/map_caddaadr.tz b/tests_python/contracts_012/macros/map_caddaadr.tz deleted file mode 100644 index 45509839cc01..000000000000 --- a/tests_python/contracts_012/macros/map_caddaadr.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter unit; -storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat); -code { MAP_CDADDAADR @new_storage %value { PUSH mutez 1000000 ; ADD } ; - NIL operation ; SWAP; SET_CAR }; diff --git a/tests_python/contracts_012/macros/max_in_list.tz b/tests_python/contracts_012/macros/max_in_list.tz deleted file mode 100644 index 89c4955e9374..000000000000 --- a/tests_python/contracts_012/macros/max_in_list.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (list int); -storage (option int); -code {CAR; DIP{NONE int}; - ITER {SWAP; - IF_NONE {SOME} - {DIP {DUP}; DUP; DIP{SWAP}; - CMPLE; IF {DROP} {DIP {DROP}}; - SOME}}; - NIL operation; PAIR}; diff --git a/tests_python/contracts_012/macros/min.tz b/tests_python/contracts_012/macros/min.tz deleted file mode 100644 index cedd835bbac8..000000000000 --- a/tests_python/contracts_012/macros/min.tz +++ /dev/null @@ -1,11 +0,0 @@ - -parameter (pair int int); -storage int; -code { CAR; # Ignore the storage - DUP; # Duplicate so we can get both the numbers passed as parameters - DUP; # Second dup so we can access the lesser number - CAR; DIP{CDR}; # Unpack the numbers on top of the stack - CMPLT; # Compare the two numbers, placing a boolean on top of the stack - IF {CAR} {CDR}; # Access the first number if the boolean was true - NIL operation; # Return no op - PAIR} # Pair the numbers satisfying the calling convention diff --git a/tests_python/contracts_012/macros/pair_macro.tz b/tests_python/contracts_012/macros/pair_macro.tz deleted file mode 100644 index 55c70a3be3e9..000000000000 --- a/tests_python/contracts_012/macros/pair_macro.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter unit; -storage unit; -code { UNIT; UNIT; UNIT; UNIT; UNIT; - PAPAPAPAIR @name %x1 %x2 %x3 %x4 %x5; - CDDDAR %x4 @fourth; - DROP; CDR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/set_caddaadr.tz b/tests_python/contracts_012/macros/set_caddaadr.tz deleted file mode 100644 index e98671e40989..000000000000 --- a/tests_python/contracts_012/macros/set_caddaadr.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter mutez; -storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat); -code { DUP ; CAR ; SWAP ; CDR ; - SET_CADDAADR @toplevel_pair_name %value ; - NIL operation ; PAIR }; diff --git a/tests_python/contracts_012/macros/take_my_money.tz b/tests_python/contracts_012/macros/take_my_money.tz deleted file mode 100644 index bb502d041849..000000000000 --- a/tests_python/contracts_012/macros/take_my_money.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter key_hash; -storage unit; -code { CAR; IMPLICIT_ACCOUNT; # Create an account for the recipient of the funds - DIP{UNIT}; # Push a value of the storage type below the contract - PUSH mutez 1000000; # The person can have a ꜩ - UNIT; # Push the contract's argument type - TRANSFER_TOKENS; # Run the transfer - NIL operation; SWAP; CONS; - PAIR }; # Cleanup and put the return values diff --git a/tests_python/contracts_012/macros/unpair_macro.tz b/tests_python/contracts_012/macros/unpair_macro.tz deleted file mode 100644 index 384b6839d88b..000000000000 --- a/tests_python/contracts_012/macros/unpair_macro.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (unit :param_unit); -storage (unit :u1); -code { DROP ; - UNIT :u4 @a4; UNIT :u3 @a3; UNIT :u2 @a2; UNIT :u1 @a1; - PAIR; UNPAIR @x1 @x2; - PPAIPAIR @p1 %x1 %x2 %x3 %x4; UNPPAIPAIR %x1 % %x3 %x4 @uno @due @tre @quattro; - PAPAPAIR @p2 %x1 %x2 %x3 %x4; UNPAPAPAIR @un @deux @trois @quatre; - PAPPAIIR @p3 %x1 %x2 %x3 %x4; UNPAPPAIIR @one @two @three @four; - DIP { DROP; DROP; DROP }; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/authentication.tz b/tests_python/contracts_012/mini_scenarios/authentication.tz deleted file mode 100644 index 021bbd26361a..000000000000 --- a/tests_python/contracts_012/mini_scenarios/authentication.tz +++ /dev/null @@ -1,30 +0,0 @@ -/* - -This contract is an example of using a cryptographic signature to -handle authentication. A public key is stored, and only the owner of -the secret key associated to this public key can interact with the -contract. She is allowed to perform any list of operations by sending -them wrapped in a lambda to the contract with a cryptographic -signature. - -To ensure that each signature is used only once and is not replayed by -an attacker, not only the lambda is signed but also the unique -identifier of the contract (a pair of the contract address and the -chain id) and a counter that is incremented at each successful call. - -More precisely, the signature should check against pack ((chain_id, -self) (param, counter)). - -*/ -parameter (pair (lambda unit (list operation)) signature); -storage (pair (nat %counter) key); -code - { - UNPPAIPAIR; - DUUUP; DUUP ; SELF; CHAIN_ID ; PPAIPAIR; PACK; - DIP { SWAP }; DUUUUUP ; DIP { SWAP }; - DUUUP; DIP {CHECK_SIGNATURE}; SWAP; IF {DROP} {FAILWITH}; - UNIT; EXEC; - DIP { PUSH nat 1; ADD }; - PAPAIR - } diff --git a/tests_python/contracts_012/mini_scenarios/big_map_entrypoints.tz b/tests_python/contracts_012/mini_scenarios/big_map_entrypoints.tz deleted file mode 100644 index d49e6257167a..000000000000 --- a/tests_python/contracts_012/mini_scenarios/big_map_entrypoints.tz +++ /dev/null @@ -1,31 +0,0 @@ -storage - (pair (big_map string nat) (big_map string nat)) ; -parameter - (or (unit %default) - (or (or %mem (string %mem_left) (string %mem_right)) - (or (or %add (pair %add_left string nat) (pair %add_right string nat)) - (or %rem (string %rem_left) (string %rem_right))))) ; -code { UNPAIR ; - IF_LEFT - { DROP ; - DUP ; CAR ; - PUSH mutez 0 ; - NONE key_hash ; - CREATE_CONTRACT - { parameter string ; - storage (big_map string nat) ; - code { UNPAIR ; DROP ; NIL operation ; PAIR }} ; - DIP { DROP } ; - NIL operation ; SWAP ; CONS ; PAIR } - { IF_LEFT - { IF_LEFT - { DIP { UNPAIR } ; DIP { DUP } ; MEM ; ASSERT } - { DIP { UNPAIR ; SWAP } ; DIP { DUP } ; MEM ; ASSERT ; SWAP } } - { IF_LEFT - { IF_LEFT - { UNPAIR ; DIIP { UNPAIR } ; DIP { SOME } ; UPDATE } - { UNPAIR ; DIIP { UNPAIR ; SWAP } ; DIP { SOME } ; UPDATE ; SWAP } } - { IF_LEFT - { DIP { UNPAIR } ; DIP { NONE nat } ; UPDATE } - { DIP { UNPAIR ; SWAP } ; DIP { NONE nat } ; UPDATE ; SWAP } } } ; - PAIR ; NIL operation ; PAIR } } diff --git a/tests_python/contracts_012/mini_scenarios/big_map_magic.tz b/tests_python/contracts_012/mini_scenarios/big_map_magic.tz deleted file mode 100644 index f4e36f639bff..000000000000 --- a/tests_python/contracts_012/mini_scenarios/big_map_magic.tz +++ /dev/null @@ -1,41 +0,0 @@ -# this contracts handles two big_maps -storage - (or (pair (big_map string string) (big_map string string)) unit) ; -parameter - # it has 5 entry points - # swap: swaps the two maps. - (or (unit %swap) - # reset: resets storage, either to a new pair of maps, or to unit - (or (or %reset (pair (big_map string string) (big_map string string)) unit) - # import: drops the existing storage and creates two maps - # from the given lists of string pairs. - (or (pair %import (list (pair string string)) (list (pair string string))) - # add: adds the given list of key - value pairs into the - # first map - (or (list %add (pair string string)) - # rem: removes the given list of key - value pairs - # from the first map - (list %rem string))))) ; -code { UNPAIR ; - IF_LEFT - { DROP ; ASSERT_LEFT ; UNPAIR ; SWAP ; PAIR ; LEFT unit } - { IF_LEFT - { SWAP ; DROP } - { IF_LEFT - { DIP { ASSERT_RIGHT ; DROP } ; - UNPAIR ; - DIP { EMPTY_BIG_MAP string string } ; - ITER { UNPAIR ; DIP { SOME } ; UPDATE } ; - SWAP ; - DIP { EMPTY_BIG_MAP string string } ; - ITER { UNPAIR ; DIP { SOME } ; UPDATE } ; - SWAP ; - PAIR ; LEFT unit } - { IF_LEFT - { DIP { ASSERT_LEFT ; UNPAIR } ; - ITER { UNPAIR ; DIP { SOME } ; UPDATE } ; - PAIR ; LEFT unit } - { DIP { ASSERT_LEFT ; UNPAIR } ; - ITER { DIP { NONE string } ; UPDATE } ; - PAIR ; LEFT unit } }} } ; - NIL operation ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/big_map_read.tz b/tests_python/contracts_012/mini_scenarios/big_map_read.tz deleted file mode 100644 index 60d666e28f29..000000000000 --- a/tests_python/contracts_012/mini_scenarios/big_map_read.tz +++ /dev/null @@ -1,9 +0,0 @@ -storage (nat); -parameter (big_map nat nat); -code { CAR; - PUSH nat 1; - GET; - ASSERT_SOME; - NIL operation; - PAIR; - } diff --git a/tests_python/contracts_012/mini_scenarios/big_map_store.tz b/tests_python/contracts_012/mini_scenarios/big_map_store.tz deleted file mode 100644 index 4dc68145a691..000000000000 --- a/tests_python/contracts_012/mini_scenarios/big_map_store.tz +++ /dev/null @@ -1,8 +0,0 @@ -storage (big_map nat nat); -parameter (unit); -code { DROP; - EMPTY_BIG_MAP nat nat; - NIL operation; - PAIR; - } - diff --git a/tests_python/contracts_012/mini_scenarios/big_map_write.tz b/tests_python/contracts_012/mini_scenarios/big_map_write.tz deleted file mode 100644 index bde3b19baa3d..000000000000 --- a/tests_python/contracts_012/mini_scenarios/big_map_write.tz +++ /dev/null @@ -1,10 +0,0 @@ -storage (unit); -parameter (big_map nat nat); -code { UNPAIR ; - PUSH (option nat) (Some 1); - PUSH nat 1; - UPDATE; - DROP; - NIL operation; - PAIR; - } diff --git a/tests_python/contracts_012/mini_scenarios/create_contract.tz b/tests_python/contracts_012/mini_scenarios/create_contract.tz deleted file mode 100644 index 0d09a1fdfca6..000000000000 --- a/tests_python/contracts_012/mini_scenarios/create_contract.tz +++ /dev/null @@ -1,33 +0,0 @@ -/* -- param: None: - - Create a contract then perform a recursive call on Some [addr] where - [addr] is the address of the newly created contract. - - The created contract simply stores its parameter (a string). It is - initialized with the storage "dummy" and has an initial balance of - 100tz. It has no delegate so these 100tz are totally frozen. - -- param: Some [addr]: - - Check that the sender is self, call the contract at address [addr] - with param "abcdefg" transferring 0tz. - -*/ -parameter (option address) ; -storage unit ; -code { CAR ; - IF_NONE - { PUSH string "dummy" ; - PUSH mutez 100000000 ; NONE key_hash ; - CREATE_CONTRACT - { parameter string ; - storage string ; - code { CAR ; NIL operation ; PAIR } } ; - DIP { SOME ; DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS } ; - CONS ; UNIT ; SWAP ; PAIR } - { SELF ; ADDRESS ; SENDER ; IFCMPNEQ { FAIL } {} ; - CONTRACT string ; IF_SOME {} { FAIL } ; - PUSH mutez 0 ; PUSH string "abcdefg" ; TRANSFER_TOKENS ; - NIL operation; SWAP; CONS ; UNIT ; SWAP ; PAIR } } ; \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/create_contract_simple.tz b/tests_python/contracts_012/mini_scenarios/create_contract_simple.tz deleted file mode 100644 index 2a5185d74889..000000000000 --- a/tests_python/contracts_012/mini_scenarios/create_contract_simple.tz +++ /dev/null @@ -1,14 +0,0 @@ -parameter unit; -storage unit; -code { CAR; - PUSH string "foo"; - PUSH mutez 0; - NONE key_hash; - CREATE_CONTRACT - { parameter string ; - storage string ; - code { CAR ; NIL operation ; PAIR } } ; - DROP; DROP; - NIL operation; - PAIR; - } diff --git a/tests_python/contracts_012/mini_scenarios/default_account.tz b/tests_python/contracts_012/mini_scenarios/default_account.tz deleted file mode 100644 index 74e7693d7ba5..000000000000 --- a/tests_python/contracts_012/mini_scenarios/default_account.tz +++ /dev/null @@ -1,9 +0,0 @@ -/* -Send 100 tz to the implicit account given as parameter. -*/ - -parameter key_hash; -storage unit; -code {DIP{UNIT}; CAR; IMPLICIT_ACCOUNT; - PUSH mutez 100000000; UNIT; TRANSFER_TOKENS; - NIL operation; SWAP; CONS; PAIR} diff --git a/tests_python/contracts_012/mini_scenarios/execution_order_appender.tz b/tests_python/contracts_012/mini_scenarios/execution_order_appender.tz deleted file mode 100644 index 9a519f780924..000000000000 --- a/tests_python/contracts_012/mini_scenarios/execution_order_appender.tz +++ /dev/null @@ -1,17 +0,0 @@ -# Given a storage (adr, str), calls the contract at adr with the -# parameter str -parameter unit; -storage (pair address string); -code { - CDR; - DUP; - UNPAIR; - CONTRACT string; - ASSERT_SOME; - PUSH mutez 0; - DIG 2; - TRANSFER_TOKENS; - NIL operation; - SWAP; - CONS; - PAIR }; diff --git a/tests_python/contracts_012/mini_scenarios/execution_order_caller.tz b/tests_python/contracts_012/mini_scenarios/execution_order_caller.tz deleted file mode 100644 index ead37544f4e8..000000000000 --- a/tests_python/contracts_012/mini_scenarios/execution_order_caller.tz +++ /dev/null @@ -1,17 +0,0 @@ -# Given storage [adr1; ...; adrn], emits operations -# [ TRANSFER_TOKENS Unit (Mutez 0) adr1 ; -# ... ; -# TRANSFER_TOKENS Unit (Mutez 0) adrn ] -parameter unit; -storage (list address); -code { - CDR; - DUP; - MAP { - CONTRACT unit; - ASSERT_SOME; - PUSH mutez 0; - UNIT; - TRANSFER_TOKENS; - }; - PAIR }; diff --git a/tests_python/contracts_012/mini_scenarios/execution_order_storer.tz b/tests_python/contracts_012/mini_scenarios/execution_order_storer.tz deleted file mode 100644 index 2bfc7505e9cd..000000000000 --- a/tests_python/contracts_012/mini_scenarios/execution_order_storer.tz +++ /dev/null @@ -1,4 +0,0 @@ -# Appends the parameter to the string in storage -parameter (string); -storage (string); -code { UNPAIR; SWAP; CONCAT; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/mini_scenarios/fa12_reference.tz b/tests_python/contracts_012/mini_scenarios/fa12_reference.tz deleted file mode 100644 index 7c2265072db4..000000000000 --- a/tests_python/contracts_012/mini_scenarios/fa12_reference.tz +++ /dev/null @@ -1,749 +0,0 @@ -# This contract comes from the gitlab.com/tzip/tzip repository. It is -# distributed under the CC0 1.0 license, which can be found at -# https://gitlab.com/tzip/tzip/-/blob/4b3c67aad5abbf04ec36caea4a1809e7b6e55bb8/LICENSE - -# Its purpose is to serve as a reference contract for TZIP-7, which -# defines Financial Assets 1.2. The original file can be found at -# https://gitlab.com/tzip/tzip/-/blob/4b3c67aad5abbf04ec36caea4a1809e7b6e55bb8/proposals/tzip-7/ManagedLedger.tz - -# This contract was generated from -# https://gitlab.com/morley-framework/morley/tree/ce28076a79b93d48aa7745271e6a1395b8b9e50d/lorentz-contracts/src/Lorentz/Contracts/ManagedLedger.hs -# Storage annotations were added manually. - -parameter (or (or (or (pair %transfer (address :from) - (pair (address :to) - (nat :value))) - (pair %approve (address :spender) - (nat :value))) - (or (pair %getAllowance (pair (address :owner) - (address :spender)) - (contract nat)) - (or (pair %getBalance (address :owner) - (contract nat)) - (pair %getTotalSupply unit - (contract nat))))) - (or (or (bool %setPause) - (address %setAdministrator)) - (or (pair %getAdministrator unit - (contract address)) - (or (pair %mint (address :to) - (nat :value)) - (pair %burn (address :from) - (nat :value)))))); -storage (pair (big_map %ledger (address :user) - (pair (nat :balance) - (map :approvals (address :spender) - (nat :value)))) - (pair (address %admin) - (pair (bool %paused) - (nat %totalSupply)))); -code { CAST (pair (or (or (or (pair address (pair address nat)) (pair address nat)) (or (pair (pair address address) (contract nat)) (or (pair address (contract nat)) (pair unit (contract nat))))) (or (or bool address) (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) (pair (big_map address (pair nat (map address nat))) (pair address (pair bool nat)))); - DUP; - CAR; - DIP { CDR }; - IF_LEFT { IF_LEFT { IF_LEFT { DIP { DUP; - CDR; - CDR; - CAR; - IF { UNIT; - PUSH string "TokenOperationsArePaused"; - PAIR; - FAILWITH } - { } }; - DUP; - DUP; - CDR; - CAR; - DIP { CAR }; - COMPARE; - EQ; - IF { DROP } - { DUP; - CAR; - SENDER; - COMPARE; - EQ; - IF { } - { DUP; - DIP { DUP; - DIP { DIP { DUP }; - CAR; - SENDER; - PAIR; - DUP; - DIP { CDR; - DIP { CAR }; - GET; - IF_NONE { EMPTY_MAP (address) nat } - { CDR } }; - CAR; - GET; - IF_NONE { PUSH nat 0 } - { } }; - DUP; - CAR; - DIP { SENDER; - DIP { DUP; - CDR; - CDR; - DIP { DIP { DUP }; - SWAP }; - SWAP; - SUB; - ISNAT; - IF_NONE { DIP { DUP }; - SWAP; - DIP { DUP }; - SWAP; - CDR; - CDR; - PAIR; - PUSH string "NotEnoughAllowance"; - PAIR; - FAILWITH } - { } }; - PAIR }; - PAIR; - DIP { DROP; - DROP }; - DIP { DUP }; - SWAP; - DIP { DUP; - CAR }; - SWAP; - DIP { CAR }; - GET; - IF_NONE { PUSH nat 0; - DIP { EMPTY_MAP (address) nat }; - PAIR; - EMPTY_MAP (address) nat } - { DUP; - CDR }; - DIP { DIP { DUP }; - SWAP }; - SWAP; - CDR; - CDR; - DUP; - INT; - EQ; - IF { DROP; - NONE nat } - { SOME }; - DIP { DIP { DIP { DUP }; - SWAP }; - SWAP }; - SWAP; - CDR; - CAR; - UPDATE; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR; - SWAP; - CAR; - DIP { SOME }; - DIP { DIP { DUP; - CAR } }; - UPDATE; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR } }; - DIP { DUP }; - SWAP; - DIP { DUP }; - SWAP; - CDR; - CAR; - DIP { CAR }; - GET; - IF_NONE { DUP; - CDR; - CDR; - INT; - EQ; - IF { NONE (pair nat (map address nat)) } - { DUP; - CDR; - CDR; - DIP { EMPTY_MAP (address) nat }; - PAIR; - SOME } } - { DIP { DUP }; - SWAP; - CDR; - CDR; - DIP { DUP; - CAR }; - ADD; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR; - SOME }; - SWAP; - DUP; - DIP { CDR; - CAR; - DIP { DIP { DUP; - CAR } }; - UPDATE; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR }; - DUP; - DIP { CDR; - CDR; - INT; - DIP { DUP; - CDR; - CDR; - CDR }; - ADD; - ISNAT; - IF_NONE { PUSH string "Internal: Negative total supply"; - FAILWITH } - { }; - DIP { DUP; - CDR }; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR; - SWAP; - PAIR; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR }; - DIP { DUP }; - SWAP; - DIP { DUP }; - SWAP; - CAR; - DIP { CAR }; - GET; - IF_NONE { CDR; - CDR; - PUSH nat 0; - SWAP; - PAIR; - PUSH string "NotEnoughBalance"; - PAIR; - FAILWITH } - { }; - DUP; - CAR; - DIP { DIP { DUP }; - SWAP }; - SWAP; - CDR; - CDR; - SWAP; - SUB; - ISNAT; - IF_NONE { CAR; - DIP { DUP }; - SWAP; - CDR; - CDR; - PAIR; - PUSH string "NotEnoughBalance"; - PAIR; - FAILWITH } - { }; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR; - DIP { DUP }; - SWAP; - DIP { DUP; - CAR; - INT; - EQ; - IF { DUP; - CDR; - SIZE; - INT; - EQ; - IF { DROP; - NONE (pair nat (map address nat)) } - { SOME } } - { SOME }; - SWAP; - CAR; - DIP { DIP { DUP; - CAR } }; - UPDATE; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR }; - DUP; - DIP { CDR; - CDR; - NEG; - DIP { DUP; - CDR; - CDR; - CDR }; - ADD; - ISNAT; - IF_NONE { PUSH string "Internal: Negative total supply"; - FAILWITH } - { }; - DIP { DUP; - CDR }; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR; - SWAP; - PAIR; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR }; - DROP }; - NIL operation; - PAIR } - { SENDER; - PAIR; - DIP { DUP; - CDR; - CDR; - CAR; - IF { UNIT; - PUSH string "TokenOperationsArePaused"; - PAIR; - FAILWITH } - { } }; - DIP { DUP }; - SWAP; - DIP { DUP }; - SWAP; - DUP; - DIP { CAR; - DIP { CAR }; - GET; - IF_NONE { EMPTY_MAP (address) nat } - { CDR } }; - CDR; - CAR; - GET; - IF_NONE { PUSH nat 0 } - { }; - DUP; - INT; - EQ; - IF { DROP } - { DIP { DUP }; - SWAP; - CDR; - CDR; - INT; - EQ; - IF { DROP } - { PUSH string "UnsafeAllowanceChange"; - PAIR; - FAILWITH } }; - DIP { DUP }; - SWAP; - DIP { DUP; - CAR }; - SWAP; - DIP { CAR }; - GET; - IF_NONE { PUSH nat 0; - DIP { EMPTY_MAP (address) nat }; - PAIR; - EMPTY_MAP (address) nat } - { DUP; - CDR }; - DIP { DIP { DUP }; - SWAP }; - SWAP; - CDR; - CDR; - DUP; - INT; - EQ; - IF { DROP; - NONE nat } - { SOME }; - DIP { DIP { DIP { DUP }; - SWAP }; - SWAP }; - SWAP; - CDR; - CAR; - UPDATE; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR; - SWAP; - CAR; - DIP { SOME }; - DIP { DIP { DUP; - CAR } }; - UPDATE; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR; - NIL operation; - PAIR } } - { IF_LEFT { DUP; - CAR; - DIP { CDR }; - DIP { DIP { DUP }; - SWAP }; - PAIR; - DUP; - CAR; - DIP { CDR }; - DUP; - DIP { CAR; - DIP { CAR }; - GET; - IF_NONE { EMPTY_MAP (address) nat } - { CDR } }; - CDR; - GET; - IF_NONE { PUSH nat 0 } - { }; - DIP { AMOUNT }; - TRANSFER_TOKENS; - NIL operation; - SWAP; - CONS; - PAIR } - { IF_LEFT { DUP; - CAR; - DIP { CDR }; - DIP { DIP { DUP }; - SWAP }; - PAIR; - DUP; - CAR; - DIP { CDR }; - DIP { CAR }; - GET; - IF_NONE { PUSH nat 0 } - { CAR }; - DIP { AMOUNT }; - TRANSFER_TOKENS; - NIL operation; - SWAP; - CONS; - PAIR } - { DUP; - CAR; - DIP { CDR }; - DIP { DIP { DUP }; - SWAP }; - PAIR; - CDR; - CDR; - CDR; - CDR; - DIP { AMOUNT }; - TRANSFER_TOKENS; - NIL operation; - SWAP; - CONS; - PAIR } } } } - { IF_LEFT { IF_LEFT { DIP { DUP; - CDR; - CAR; - SENDER; - COMPARE; - EQ; - IF { } - { UNIT; - PUSH string "SenderIsNotAdmin"; - PAIR; - FAILWITH } }; - DIP { DUP; - CDR }; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR; - SWAP; - PAIR; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR; - NIL operation; - PAIR } - { DIP { DUP; - CDR; - CAR; - SENDER; - COMPARE; - EQ; - IF { } - { UNIT; - PUSH string "SenderIsNotAdmin"; - PAIR; - FAILWITH } }; - DIP { DUP; - CDR }; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR; - NIL operation; - PAIR } } - { IF_LEFT { DUP; - CAR; - DIP { CDR }; - DIP { DIP { DUP }; - SWAP }; - PAIR; - CDR; - CDR; - CAR; - DIP { AMOUNT }; - TRANSFER_TOKENS; - NIL operation; - SWAP; - CONS; - PAIR } - { IF_LEFT { DIP { DUP; - CDR; - CAR; - SENDER; - COMPARE; - EQ; - IF { } - { UNIT; - PUSH string "SenderIsNotAdmin"; - PAIR; - FAILWITH } }; - DIP { DUP }; - SWAP; - DIP { DUP }; - SWAP; - CAR; - DIP { CAR }; - GET; - IF_NONE { DUP; - CDR; - INT; - EQ; - IF { NONE (pair nat (map address nat)) } - { DUP; - CDR; - DIP { EMPTY_MAP (address) nat }; - PAIR; - SOME } } - { DIP { DUP }; - SWAP; - CDR; - DIP { DUP; - CAR }; - ADD; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR; - SOME }; - SWAP; - DUP; - DIP { CAR; - DIP { DIP { DUP; - CAR } }; - UPDATE; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR }; - DUP; - DIP { CDR; - INT; - DIP { DUP; - CDR; - CDR; - CDR }; - ADD; - ISNAT; - IF_NONE { PUSH string "Internal: Negative total supply"; - FAILWITH } - { }; - DIP { DUP; - CDR }; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR; - SWAP; - PAIR; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR }; - DROP; - NIL operation; - PAIR } - { DIP { DUP; - CDR; - CAR; - SENDER; - COMPARE; - EQ; - IF { } - { UNIT; - PUSH string "SenderIsNotAdmin"; - PAIR; - FAILWITH } }; - DIP { DUP }; - SWAP; - DIP { DUP }; - SWAP; - CAR; - DIP { CAR }; - GET; - IF_NONE { CDR; - PUSH nat 0; - SWAP; - PAIR; - PUSH string "NotEnoughBalance"; - PAIR; - FAILWITH } - { }; - DUP; - CAR; - DIP { DIP { DUP }; - SWAP }; - SWAP; - CDR; - SWAP; - SUB; - ISNAT; - IF_NONE { CAR; - DIP { DUP }; - SWAP; - CDR; - PAIR; - PUSH string "NotEnoughBalance"; - PAIR; - FAILWITH } - { }; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR; - DIP { DUP }; - SWAP; - DIP { DUP; - CAR; - INT; - EQ; - IF { DUP; - CDR; - SIZE; - INT; - EQ; - IF { DROP; - NONE (pair nat (map address nat)) } - { SOME } } - { SOME }; - SWAP; - CAR; - DIP { DIP { DUP; - CAR } }; - UPDATE; - DIP { DUP; - DIP { CDR }; - CAR }; - DIP { DROP }; - PAIR }; - DUP; - DIP { CDR; - NEG; - DIP { DUP; - CDR; - CDR; - CDR }; - ADD; - ISNAT; - IF_NONE { PUSH string "Internal: Negative total supply"; - FAILWITH } - { }; - DIP { DUP; - CDR }; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR; - SWAP; - PAIR; - DIP { DUP; - DIP { CAR }; - CDR }; - DIP { DROP }; - SWAP; - PAIR }; - DROP; - NIL operation; - PAIR } } } } }; diff --git a/tests_python/contracts_012/mini_scenarios/generic_multisig.tz b/tests_python/contracts_012/mini_scenarios/generic_multisig.tz deleted file mode 100644 index 2e78f1cea983..000000000000 --- a/tests_python/contracts_012/mini_scenarios/generic_multisig.tz +++ /dev/null @@ -1,92 +0,0 @@ -# Source: https://github.com/murbard/smart-contracts/blob/master/multisig/michelson/generic.tz -parameter (or (unit %default) - (pair %main - (pair :payload - (nat %counter) # counter, used to prevent replay attacks - (or :action # payload to sign, represents the requested action - (lambda %operation unit (list operation)) - (pair %change_keys # change the keys controlling the multisig - (nat %threshold) # new threshold - (list %keys key)))) # new list of keys - (list %sigs (option signature)))); # signatures - -storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; - -code - { - UNPAIR ; - IF_LEFT - { # Default entry point: do nothing - # This entry point can be used to send tokens to this contract - DROP ; NIL operation ; PAIR } - { # Main entry point - # Assert no token was sent: - # to send tokens, the default entry point should be used - PUSH mutez 0 ; AMOUNT ; ASSERT_CMPEQ ; - SWAP ; DUP ; DIP { SWAP } ; - DIP - { - UNPAIR ; - # pair the payload with the current contract address, to ensure signatures - # can't be replayed accross different contracts if a key is reused. - DUP ; SELF ; ADDRESS ; CHAIN_ID ; PAIR ; PAIR ; - PACK ; # form the binary payload that we expect to be signed - DIP { UNPAIR @counter ; DIP { SWAP } } ; SWAP - } ; - - # Check that the counters match - UNPAIR @stored_counter; DIP { SWAP }; - ASSERT_CMPEQ ; - - # Compute the number of valid signatures - DIP { SWAP } ; UNPAIR @threshold @keys; - DIP - { - # Running count of valid signatures - PUSH @valid nat 0; SWAP ; - ITER - { - DIP { SWAP } ; SWAP ; - IF_CONS - { - IF_SOME - { SWAP ; - DIP - { - SWAP ; DIIP { DUUP } ; - # Checks signatures, fails if invalid - { DUUUP; DIP {CHECK_SIGNATURE}; SWAP; IF {DROP} {FAILWITH} }; - PUSH nat 1 ; ADD @valid } } - { SWAP ; DROP } - } - { - # There were fewer signatures in the list - # than keys. Not all signatures must be present, but - # they should be marked as absent using the option type. - FAIL - } ; - SWAP - } - } ; - # Assert that the threshold is less than or equal to the - # number of valid signatures. - ASSERT_CMPLE ; - # Assert no unchecked signature remains - IF_CONS {FAIL} {} ; - DROP ; - - # Increment counter and place in storage - DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR} ; - - # We have now handled the signature verification part, - # produce the operation requested by the signers. - IF_LEFT - { # Get operation - UNIT ; EXEC - } - { - # Change set of signatures - DIP { CAR } ; SWAP ; PAIR ; NIL operation - }; - PAIR } - } diff --git a/tests_python/contracts_012/mini_scenarios/groth16.tz b/tests_python/contracts_012/mini_scenarios/groth16.tz deleted file mode 100644 index 66ff23a5e73b..000000000000 --- a/tests_python/contracts_012/mini_scenarios/groth16.tz +++ /dev/null @@ -1,74 +0,0 @@ -# The contract returns if the proof verifies, and fails otherwise. -# The verifying key, proof, and inputs are generated from -# ZoKrates, modified to use BLS12-381. -# The circuit proves knowledge of a square root of 113569. -storage unit; - -# The parameter is a pair consisting of: -# * A pair of Fr element inputs, x and y -# * A proof, consisting of -# * G1 points `a` and `c` -# * G2 point `b` -parameter (pair (pair (bls12_381_fr %input_x) (bls12_381_fr %input_y)) - (pair (pair (bls12_381_g1 %proof_a) (bls12_381_g2 %proof_b)) - (bls12_381_g1 %proof_c))); - -code - { - # Discard storage and unpair. Result stack should be - # input{x:y} : proof{a:b:c}. - CAR; UNPPAIPPAIIR; - - # Push the verifying key. Result stack should be - # input{x:y} - # : proof{a:b:c} - # : vk_{a:b:gamma:delta:gamma_{a:b:c}} - DIP 5 - { - PUSH @vk_gamma_c bls12_381_g1 0x063bd6e11e2fcaac1dd8cf68c6b1925a73c3c583e298ed37c41c3715115cf96358a42dbe85a0228cbfd8a6c8a8c54cd015b5ae2860d1cc47f84698d951f14d9448d03f04df2ca0ffe609a2067d6f1a892163a5e05e541279134cae52b1f23c6b; - - PUSH @vk_gamma_b bls12_381_g1 0x11f5b5db1da7f1f26217edcce2219d016003af6e5b4d1ca3ad0ff477e354717e658bf16beddc4f4fb76ce39d3327811e0601709dc7ed98c70463cfa1ba33f99851b52b51d1a042d7425bec6277287441c399973632445ce61e7fdd63a70f0f60; - - PUSH @vk_gamma_a bls12_381_g1 0x03535a322edd23c55b0ca025e54d450d95df49cc9ee873dcd500e8219f4771264bf159b3b105954d85c7bea8ffe1ea0400c767fe58989366c2837fba76f1b4f46644f19be8ad01e22d894b649e427e0d7e04677ee3919d982f0f96bb0a2f0c34; - - PUSH @vk_delta bls12_381_g2 0x10c6d5cdca84fc3c7f33061add256f48e0ab03a697832b338901898b650419eb6f334b28153fb73ad2ecd1cd2ac67053161e9f46cfbdaf7b1132a4654a55162850249650f9b873ac3113fa8c02ef1cd1df481480a4457f351d28f4da89d19fa405c3d77f686dc9a24d2681c9184bf2b091f62e6b24df651a3da8bd7067e14e7908fb02f8955b84af5081614cb5bc49b416d9edf914fc608c441b3f2eb8b6043736ddb9d4e4d62334a23b5625c14ef3e1a7e99258386310221b22d83a5eac035c; - - PUSH @vk_gamma bls12_381_g2 0x16dcbd28bff336c2649c7dd1d8391ac7ce6f7ef0124a9db7a4a485a124199eded7ce963c1c18aee1eca9994fe06f192c00e0fb653e1fc737d8d0e2f2f91424ca01f6e6e7c5c04f1c43db03a2900cf6b942aaed6ae77daea6200e094b78c38d770028d531a9d1a118ec23d5a39be7aa6dc28f778da1988856d2235c4a35e81fa48380f050d4baf7ebd7b5e058bf294da916afc34562f097c02a8fcbcf62a00de44f8ae6cfa7acb8ad254e3aeea8b2af12f65b7ee0f54855cb9bd432f3436f238f; - - PUSH @vk_b bls12_381_g2 0x0e9383f98df2c6e8b5b45f3876c3384596a0cdbc41349f83c4380bf463a050cdbd1d5057aa483a642e66486d1ed7362a1869e423c3877095e215c17282b11108601166f928043254bbce603bf86f4cec9f2e97e9660e98e4f5bce9b2b3bbacb40946b702ccfcc9a31e0bfc1543a2128edcc95807740a2310ae25eb47b935648e392c58dfae5b5e899d3b970d64e4e9e209741ea8bfedcfcc16b3fd890ff02c788ec0943feaaf01bbb354317acb85fcfd611133e4e563d53ca4e0f50e21cf2e7e; - - PUSH @vk_a bls12_381_g1 0x1040577c7d349e332735fc947c868c24a665f812f5dc1e7f60e65e2df80be2267a4b7341ed2287285fccd517acd96d910abba947235c364553aa6445f2f2b3a1a728225a330286ba5197ab87f0edc560d89fc7b623812f7d0d633341726e597a - }; - - # Compute vk_x as - # (vk_gamma_b * input_x) + (vk_gamma_c * input_y) + vk_gamma_a - # Result stack should be - # vk_x - # : input{x:y} - # : proof{a:b:c} - # : vk_{a:b:gamma:delta:gamma_{a:b:c}} - DUP; DUP 12; MUL; - DUP 3; DUP 14; MUL; - ADD; DUP 11; ADD @vk_x; - - # Push the list for the pairing check. The list should be - # [ (proof_a, proof_b); - # (-vk_x, vk_gamma); - # (-proof_c, vk_delta); - # (-vk_a, vk_b) ] - NIL (pair bls12_381_g1 bls12_381_g2); - DUP 9; DUP 9; NEG; PAIR; CONS; - DUP 11; DUP 8; NEG; PAIR; CONS; - DUP 10; DUP 3; NEG; PAIR; CONS; - DUP 6; DUP 6; PAIR; CONS; - - # Compute the pairing check and fail if it doesn't succeed - PAIRING_CHECK; ASSERT; - - # Drop the stack - DROP 13; - - # return no operations - UNIT; NIL operation; PAIR - - } diff --git a/tests_python/contracts_012/mini_scenarios/hardlimit.tz b/tests_python/contracts_012/mini_scenarios/hardlimit.tz deleted file mode 100644 index 464062a52166..000000000000 --- a/tests_python/contracts_012/mini_scenarios/hardlimit.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter unit ; -storage int ; -code { # This contract stops accepting transactions after N incoming transactions - CDR ; DUP ; PUSH int 0 ; CMPLT; IF {PUSH int -1 ; ADD} {FAIL}; - NIL operation ; PAIR} ; diff --git a/tests_python/contracts_012/mini_scenarios/legacy_multisig.tz b/tests_python/contracts_012/mini_scenarios/legacy_multisig.tz deleted file mode 100644 index 98ea6c603898..000000000000 --- a/tests_python/contracts_012/mini_scenarios/legacy_multisig.tz +++ /dev/null @@ -1,78 +0,0 @@ -parameter (pair - (pair :payload - (nat %counter) # counter, used to prevent replay attacks - (or :action # payload to sign, represents the requested action - (pair :transfer # transfer tokens - (mutez %amount) # amount to transfer - (contract %dest unit)) # destination to transfer to - (or - (option %delegate key_hash) # change the delegate to this address - (pair %change_keys # change the keys controlling the multisig - (nat %threshold) # new threshold - (list %keys key))))) # new list of keys - (list %sigs (option signature))); # signatures -storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; -code - { - UNPAIR ; SWAP ; DUP ; DIP { SWAP } ; - DIP - { - UNPAIR ; - # pair the payload with the current contract address, to ensure signatures - # can't be replayed across different contracts if a key is reused. - DUP ; SELF ; ADDRESS ; CHAIN_ID ; PAIR ; PAIR ; - PACK ; # form the binary payload that we expect to be signed - DIP { UNPAIR @counter ; DIP { SWAP } } ; SWAP - } ; - # Check that the counters match - UNPAIR @stored_counter; DIP { SWAP }; - ASSERT_CMPEQ ; - # Compute the number of valid signatures - DIP { SWAP } ; UNPAIR @threshold @keys; - DIP - { - # Running count of valid signatures - PUSH @valid nat 0; SWAP ; - ITER - { - DIP { SWAP } ; SWAP ; - IF_CONS - { - IF_SOME - { SWAP ; - DIP - { - SWAP ; DIIP { DUUP } ; - # Checks signatures, fails if invalid - { DUUUP; DIP {CHECK_SIGNATURE}; SWAP; IF {DROP} {FAILWITH} }; - PUSH nat 1 ; ADD @valid } } - { SWAP ; DROP } - } - { - # There were fewer signatures in the list - # than keys. Not all signatures must be present, but - # they should be marked as absent using the option type. - FAIL - } ; - SWAP - } - } ; - # Assert that the threshold is less than or equal to the - # number of valid signatures. - ASSERT_CMPLE ; - DROP ; DROP ; - # Increment counter and place in storage - DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR} ; - # We have now handled the signature verification part, - # produce the operation requested by the signers. - NIL operation ; SWAP ; - IF_LEFT - { # Transfer tokens - UNPAIR ; UNIT ; TRANSFER_TOKENS ; CONS } - { IF_LEFT { - # Change delegate - SET_DELEGATE ; CONS } - { - # Change set of signatures - DIP { SWAP ; CAR } ; SWAP ; PAIR ; SWAP }} ; - PAIR } diff --git a/tests_python/contracts_012/mini_scenarios/lockup.tz b/tests_python/contracts_012/mini_scenarios/lockup.tz deleted file mode 100644 index a8ff43aa0f85..000000000000 --- a/tests_python/contracts_012/mini_scenarios/lockup.tz +++ /dev/null @@ -1,19 +0,0 @@ -parameter unit; -storage (pair timestamp (pair mutez address)); -code { CDR; # Ignore the parameter - DUP; # Duplicate the storage - CAR; # Get the timestamp - NOW; # Push the current timestamp - CMPLT; # Compare to the current time - IF {FAIL} {}; # Fail if it is too soon - DUP; # Duplicate the storage value - # this must be on the bottom of the stack for us to call transfer tokens - CDR; # Ignore the timestamp, focussing in on the transfer data - DUP; # Duplicate the transfer information - CAR; # Get the amount of the transfer on top of the stack - DIP{CDR}; # Put the contract underneath it - DIP { CONTRACT unit ; ASSERT_SOME } ; - UNIT; # Put the contract's argument type on top of the stack - TRANSFER_TOKENS; # Emit the transfer - NIL operation; SWAP; CONS;# Make a singleton list of internal operations - PAIR} # Pair up to meet the calling convention diff --git a/tests_python/contracts_012/mini_scenarios/lqt_fa12.mligo.tz b/tests_python/contracts_012/mini_scenarios/lqt_fa12.mligo.tz deleted file mode 100644 index 7f606cea3243..000000000000 --- a/tests_python/contracts_012/mini_scenarios/lqt_fa12.mligo.tz +++ /dev/null @@ -1,328 +0,0 @@ -# FA1.2 implementation used for Liquidity Baking - -{ parameter - (or (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (pair (address %to) (nat %value))))) ; - storage - (pair (big_map %tokens address nat) - (pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (pair (address %admin) (nat %total_supply)))) ; - code { DUP ; - CDR ; - PUSH mutez 0 ; - AMOUNT ; - COMPARE ; - NEQ ; - IF { PUSH string "DontSendTez" ; FAILWITH } {} ; - SWAP ; - CAR ; - IF_LEFT - { IF_LEFT - { IF_LEFT - { SWAP ; - DUP ; - DUG 2 ; - CDR ; - CAR ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - SENDER ; - PAIR ; - PUSH nat 0 ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - COMPARE ; - GT ; - PUSH nat 0 ; - DIG 3 ; - DUP ; - DUG 4 ; - DIG 3 ; - DUP ; - DUG 4 ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - COMPARE ; - GT ; - AND ; - IF { PUSH string "UnsafeAllowanceChange" ; FAILWITH } {} ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - CDR ; - DIG 2 ; - DIG 3 ; - CDR ; - PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; - COMPARE ; - EQ ; - IF { DROP ; NONE nat } { SOME } ; - DIG 3 ; - UPDATE ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - NIL operation ; - PAIR } - { SWAP ; - DUP ; - DIG 2 ; - NIL operation ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - PUSH mutez 0 ; - DIG 4 ; - CDR ; - CAR ; - DIG 4 ; - CAR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - TRANSFER_TOKENS ; - CONS ; - PAIR } } - { IF_LEFT - { SWAP ; - DUP ; - DIG 2 ; - NIL operation ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - PUSH mutez 0 ; - DIG 4 ; - CAR ; - DIG 4 ; - CAR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - TRANSFER_TOKENS ; - CONS ; - PAIR } - { SWAP ; - DUP ; - DIG 2 ; - NIL operation ; - SWAP ; - CDR ; - PUSH mutez 0 ; - DIG 3 ; - CDR ; - CDR ; - CDR ; - TRANSFER_TOKENS ; - CONS ; - PAIR } } } - { IF_LEFT - { SWAP ; - DUP ; - DUG 2 ; - CDR ; - CDR ; - CAR ; - SENDER ; - COMPARE ; - NEQ ; - IF { PUSH string "OnlyAdmin" ; FAILWITH } {} ; - DUP ; - CAR ; - DIG 2 ; - DUP ; - DUG 3 ; - CAR ; - DIG 2 ; - DUP ; - DUG 3 ; - CDR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - ADD ; - ISNAT ; - IF_NONE - { PUSH string "Cannot burn more than the target's balance." ; FAILWITH } - {} ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - CDR ; - CDR ; - ADD ; - ABS ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - DIG 4 ; - CAR ; - PUSH nat 0 ; - DIG 4 ; - DUP ; - DUG 5 ; - COMPARE ; - EQ ; - IF { DIG 3 ; DROP ; NONE nat } { DIG 3 ; SOME } ; - DIG 4 ; - CDR ; - UPDATE ; - PAIR ; - DUP ; - DUG 2 ; - CDR ; - CDR ; - CAR ; - PAIR ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - CAR ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - NIL operation ; - PAIR } - { SWAP ; - DUP ; - DUG 2 ; - CDR ; - CAR ; - DIG 2 ; - DUP ; - DUG 3 ; - CAR ; - DIG 2 ; - DUP ; - DUG 3 ; - CAR ; - SENDER ; - COMPARE ; - EQ ; - IF { SWAP } - { SENDER ; - DIG 3 ; - DUP ; - DUG 4 ; - CAR ; - PAIR ; - DIG 3 ; - DUP ; - DUG 4 ; - CDR ; - CDR ; - DIG 3 ; - DUP ; - DUG 4 ; - DIG 2 ; - DUP ; - DUG 3 ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - SUB ; - ISNAT ; - IF_NONE { PUSH string "NotEnoughAllowance" ; FAILWITH } {} ; - DIG 3 ; - PUSH nat 0 ; - DIG 2 ; - DUP ; - DUG 3 ; - COMPARE ; - EQ ; - IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; - DIG 2 ; - UPDATE } ; - DIG 2 ; - DUP ; - DUG 3 ; - CDR ; - CDR ; - DIG 2 ; - DUP ; - DUG 3 ; - DIG 4 ; - DUP ; - DUG 5 ; - CAR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - SUB ; - ISNAT ; - IF_NONE { PUSH string "NotEnoughBalance" ; FAILWITH } {} ; - DIG 2 ; - PUSH nat 0 ; - DIG 2 ; - DUP ; - DUG 3 ; - COMPARE ; - EQ ; - IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; - DIG 3 ; - DUP ; - DUG 4 ; - CAR ; - UPDATE ; - DIG 2 ; - DUP ; - DUG 3 ; - CDR ; - CDR ; - SWAP ; - DUP ; - DUG 2 ; - DIG 4 ; - DUP ; - DUG 5 ; - CDR ; - CAR ; - GET ; - IF_NONE { PUSH nat 0 } {} ; - ADD ; - SWAP ; - PUSH nat 0 ; - DIG 2 ; - DUP ; - DUG 3 ; - COMPARE ; - EQ ; - IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; - DIG 3 ; - CDR ; - CAR ; - UPDATE ; - DIG 2 ; - CDR ; - SWAP ; - PAIR ; - DUP ; - CDR ; - CDR ; - DIG 2 ; - PAIR ; - SWAP ; - CAR ; - PAIR ; - NIL operation ; - PAIR } } } } diff --git a/tests_python/contracts_012/mini_scenarios/multiple_en2.tz b/tests_python/contracts_012/mini_scenarios/multiple_en2.tz deleted file mode 100644 index a1acafd48706..000000000000 --- a/tests_python/contracts_012/mini_scenarios/multiple_en2.tz +++ /dev/null @@ -1,77 +0,0 @@ -{ parameter unit ; - storage (option address) ; - code { SENDER ; - SELF ; - ADDRESS ; - { COMPARE ; - EQ ; - IF { CDR ; - { IF_NONE { { UNIT ; FAILWITH } } {} } ; - DIP { NIL operation } ; - DUP ; - CONTRACT %add unit ; - { IF_NONE {} { { UNIT ; FAILWITH } } } ; - DUP ; - CONTRACT %fact nat ; - { IF_NONE {} { { UNIT ; FAILWITH } } } ; - DUP ; - CONTRACT %add nat ; - { IF_NONE { { UNIT ; FAILWITH } } {} } ; - PUSH mutez 0 ; - PUSH nat 12 ; - TRANSFER_TOKENS ; - SWAP ; - DIP { CONS } ; - DUP ; - CONTRACT unit ; - { IF_NONE { { UNIT ; FAILWITH } } {} } ; - PUSH mutez 0 ; - PUSH unit Unit ; - TRANSFER_TOKENS ; - SWAP ; - DIP { CONS } ; - DUP ; - CONTRACT %sub nat ; - { IF_NONE { { UNIT ; FAILWITH } } {} } ; - PUSH mutez 0 ; - PUSH nat 3 ; - TRANSFER_TOKENS ; - SWAP ; - DIP { CONS } ; - DUP ; - CONTRACT %add nat ; - { IF_NONE { { UNIT ; FAILWITH } } {} } ; - PUSH mutez 0 ; - PUSH nat 5 ; - TRANSFER_TOKENS ; - SWAP ; - DIP { CONS } ; - DROP ; - DIP { NONE address } ; - PAIR } - { CAR ; - DUP ; - DIP { DIP { PUSH int 0 ; PUSH mutez 0 ; NONE key_hash } ; - DROP ; - CREATE_CONTRACT - { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; - storage int ; - code { AMOUNT ; - PUSH mutez 0 ; - { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; - { { DUP ; CAR ; DIP { CDR } } } ; - IF_LEFT - { IF_LEFT { ADD } { SWAP ; SUB } } - { DROP ; DROP ; PUSH int 0 } ; - NIL operation ; - PAIR } } } ; - DIP { SELF ; PUSH mutez 0 } ; - TRANSFER_TOKENS ; - NIL operation ; - SWAP ; - CONS ; - SWAP ; - CONS ; - DIP { SOME } ; - PAIR } } - } } diff --git a/tests_python/contracts_012/mini_scenarios/multiple_entrypoints_counter.tz b/tests_python/contracts_012/mini_scenarios/multiple_entrypoints_counter.tz deleted file mode 100644 index 740190697171..000000000000 --- a/tests_python/contracts_012/mini_scenarios/multiple_entrypoints_counter.tz +++ /dev/null @@ -1,29 +0,0 @@ -{ parameter unit ; - storage (option address) ; - code { SENDER ; SELF ; ADDRESS ; - IFCMPEQ - { CDR ; ASSERT_SOME ; - DIP { NIL operation } ; - DUP ; CONTRACT %add unit ; ASSERT_NONE ; - DUP ; CONTRACT %fact nat ; ASSERT_NONE ; - DUP ; CONTRACT %add nat ; ASSERT_SOME ; PUSH mutez 0 ; PUSH nat 12 ; TRANSFER_TOKENS ; SWAP ; DIP { CONS } ; - DUP ; CONTRACT unit ; ASSERT_SOME ; PUSH mutez 0 ; PUSH unit Unit ; TRANSFER_TOKENS ; SWAP ; DIP { CONS } ; - DUP ; CONTRACT %sub nat ; ASSERT_SOME ; PUSH mutez 0 ; PUSH nat 3 ; TRANSFER_TOKENS ; SWAP ; DIP { CONS } ; - DUP ; CONTRACT %add nat ; ASSERT_SOME ; PUSH mutez 0 ; PUSH nat 5 ; TRANSFER_TOKENS ; SWAP ; DIP { CONS } ; - DROP ; DIP { NONE address } ; PAIR } - { CAR ; DUP ; - DIP - { DIP { PUSH int 0 ; PUSH mutez 0 ; NONE key_hash } ; - DROP ; - CREATE_CONTRACT - { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; - storage int ; - code { AMOUNT ; PUSH mutez 0 ; ASSERT_CMPEQ ; - UNPAIR ; - IF_LEFT - { IF_LEFT { ADD } { SWAP ; SUB } } - { DROP ; DROP ; PUSH int 0 } ; - NIL operation ; PAIR } } } ; - DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; SWAP ; CONS ; - DIP { SOME } ; PAIR } } } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/parameterized_multisig.tz b/tests_python/contracts_012/mini_scenarios/parameterized_multisig.tz deleted file mode 100644 index 16f785ae0a25..000000000000 --- a/tests_python/contracts_012/mini_scenarios/parameterized_multisig.tz +++ /dev/null @@ -1,24 +0,0 @@ -storage (pair bool (pair (map nat (pair bool bool)) (pair key key))); -parameter (or nat (pair signature nat)); -code { DUP; CAR; DIP{CDDR}; # Stack tangling - IF_LEFT { DIP{DUP; CAR}; GET; # Get the value stored for that index - IF_NONE { PUSH bool False} # If not referenced, reject - { DUP; CAR; DIP{CDR}; AND}; - PAIR} - { DUP; CAR; DIP{CDR; DUP; PACK ; BLAKE2B}; PAIR; SWAP; # Create the signature pair - DIP{ DIP{DUP; CDR; DIP{CAR}; DUP}; - SWAP; CAR; DIP{DUP; UNPAIR}; CHECK_SIGNATURE }; # Check the first signature - SWAP; - # If the signature typechecked, get and update the first element of the pair - IF { DIP{DROP; SWAP; DUP}; DUP; - DIP{ GET; IF_NONE{PUSH (pair bool bool) (Pair False False)} {}; - CDR; PUSH bool True; PAIR; SOME }} - # Check the second signature - { DIP{DIP{DUP; CDR}; SWAP; DIP {UNPAIR}; CHECK_SIGNATURE}; SWAP; - IF { DUP; DIP{DIP{SWAP; DUP}; GET}; SWAP; - IF_NONE {PUSH (pair bool bool) (Pair False False)} {}; - CAR; PUSH bool True; SWAP; PAIR; SOME; SWAP} - {FAIL}}; - # Update the stored value and finish off - UPDATE; PAIR; PUSH bool False; PAIR}; - NIL operation; PAIR } diff --git a/tests_python/contracts_012/mini_scenarios/replay.tz b/tests_python/contracts_012/mini_scenarios/replay.tz deleted file mode 100644 index e03ac4ab2113..000000000000 --- a/tests_python/contracts_012/mini_scenarios/replay.tz +++ /dev/null @@ -1,8 +0,0 @@ -# This contract always fail because it tries to execute twice the same operation -parameter unit ; -storage unit ; -code { CDR ; NIL operation ; - SOURCE ; CONTRACT unit ; ASSERT_SOME ; - PUSH mutez 1 ; UNIT ; TRANSFER_TOKENS ; - DUP ; DIP { CONS } ; CONS ; - PAIR } diff --git a/tests_python/contracts_012/mini_scenarios/reveal_signed_preimage.tz b/tests_python/contracts_012/mini_scenarios/reveal_signed_preimage.tz deleted file mode 100644 index 1a7e97eb8a68..000000000000 --- a/tests_python/contracts_012/mini_scenarios/reveal_signed_preimage.tz +++ /dev/null @@ -1,13 +0,0 @@ -parameter (pair bytes signature) ; -storage (pair bytes key) ; -code { - #check that sha256(param.bytes) == storage.bytes - DUP ; UNPAIR ; CAR; SHA256; DIP { CAR } ; ASSERT_CMPEQ ; - - # check that the sig is a valid signature of the preimage - DUP ; UNPAIR ; SWAP ; DIP { UNPAIR ; SWAP } ; CDR ; CHECK_SIGNATURE ; ASSERT ; - - # send all our tokens to the implicit account corresponding to the stored public key - CDR ; DUP ; CDR ; HASH_KEY ; IMPLICIT_ACCOUNT ; - BALANCE ; UNIT ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/self_address_receiver.tz b/tests_python/contracts_012/mini_scenarios/self_address_receiver.tz deleted file mode 100644 index 6ebda8daad9e..000000000000 --- a/tests_python/contracts_012/mini_scenarios/self_address_receiver.tz +++ /dev/null @@ -1,12 +0,0 @@ -# See self_address_sender.tz -parameter (lambda unit address); -storage unit; -code { - UNPAIR; - UNIT; - EXEC; - SELF_ADDRESS; - ASSERT_CMPEQ; - NIL operation; - PAIR - } diff --git a/tests_python/contracts_012/mini_scenarios/self_address_sender.tz b/tests_python/contracts_012/mini_scenarios/self_address_sender.tz deleted file mode 100644 index b0f74073c2ff..000000000000 --- a/tests_python/contracts_012/mini_scenarios/self_address_sender.tz +++ /dev/null @@ -1,17 +0,0 @@ -# This tests that the SELF_ADDRESS inside a lambda returns the address -# of the contract executing the lambda (not the contract defining it). -# To do so, two contracts called the sender and the receiver are used. -# The sender (this contract) sends the lambda { DROP; SELF_ADDRESS } -# to the receiver (see self_address_receiver.tz) who checks that the -# returned value is the same as its SELF_ADDRESS. -parameter (contract (lambda unit address)); -storage unit; -code { - CAR; - BALANCE; - LAMBDA unit address { DROP; SELF_ADDRESS }; - TRANSFER_TOKENS; - DIP { UNIT; NIL operation }; - CONS; - PAIR - } diff --git a/tests_python/contracts_012/mini_scenarios/ticket_builder_fungible.tz b/tests_python/contracts_012/mini_scenarios/ticket_builder_fungible.tz deleted file mode 100644 index 674ae800771d..000000000000 --- a/tests_python/contracts_012/mini_scenarios/ticket_builder_fungible.tz +++ /dev/null @@ -1,40 +0,0 @@ -## A simple fungible token contract implemented using tickets of type -## [ticket unit]. - -## To store and transfer the tokens see ticket_wallet_fungible.tz - -## For non-fungible tokens, see ticket_builder_non_fungible.tz - -parameter (or (ticket %burn unit) (pair %mint (contract %destination (ticket unit)) (nat %amount))); -storage address; -code - { - AMOUNT; PUSH mutez 0; ASSERT_CMPEQ; - - UNPAIR; - IF_LEFT - { - # Burn entrypoint - - # Check that the ticket is ticketed by ourselves - READ_TICKET; CAR; SELF_ADDRESS; ASSERT_CMPEQ; - - # Drop the ticket - DROP; - - # Finish - NIL operation - } - { - # Mint entrypoint - - # Authenticate SENDER - DUP @manager 2; SENDER; ASSERT_CMPEQ; - - UNPAIR; - SWAP; UNIT; TICKET; - PUSH mutez 0; SWAP; TRANSFER_TOKENS; - NIL operation; SWAP; CONS - }; - PAIR - } diff --git a/tests_python/contracts_012/mini_scenarios/ticket_builder_non_fungible.tz b/tests_python/contracts_012/mini_scenarios/ticket_builder_non_fungible.tz deleted file mode 100644 index ae669d17ad60..000000000000 --- a/tests_python/contracts_012/mini_scenarios/ticket_builder_non_fungible.tz +++ /dev/null @@ -1,47 +0,0 @@ -## A simple non-fungible token contract implemented using tickets of -## type [ticket nat] with amounts of 1. - -## To store and transfer the tokens see ticket_wallet_non_fungible.tz - -## For fungible tokens, see ticket_builder_fungible.tz - -parameter (or (ticket %burn nat) (contract %mint_destination (ticket nat))); -storage (pair (address %manager) (nat %counter)); -code - { - AMOUNT; PUSH mutez 0; ASSERT_CMPEQ; - - UNPAIR 3; - IF_LEFT - { - # Burn entrypoint - - # Check that the ticket is ticketed by ourselves - READ_TICKET; CAR; SELF_ADDRESS; ASSERT_CMPEQ; - - # Drop the ticket - DROP; - - # Finish - NIL operation - } - { - # Mint entrypoint - - # Authenticate SENDER - DUP @manager 2; SENDER; ASSERT_CMPEQ; - - # Mint the token - PUSH @amount nat 1; - DUP @counter 4; - TICKET; - - # Send it - PUSH mutez 0; SWAP; TRANSFER_TOKENS; - NIL operation; SWAP; CONS; - - # Increment counter - DIP 2 {PUSH nat 1; ADD}; - }; - PAIR 3 - } diff --git a/tests_python/contracts_012/mini_scenarios/ticket_wallet_fungible.tz b/tests_python/contracts_012/mini_scenarios/ticket_wallet_fungible.tz deleted file mode 100644 index d04180ddb899..000000000000 --- a/tests_python/contracts_012/mini_scenarios/ticket_wallet_fungible.tz +++ /dev/null @@ -1,88 +0,0 @@ -## A simple wallet for fungible tokens implemented using tickets of -## type [ticket unit]. - -## For actually minting or burning the tokens, see ticket_builder_fungible.tz - -## For non-fungible tokens, see ticket_wallet_non_fungible.tz - -parameter (or (ticket %receive unit) (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer))); -storage (pair (address %manager) (big_map %tickets address (ticket unit))); -code - { - AMOUNT; PUSH mutez 0; ASSERT_CMPEQ; - - UNPAIR 3; - IF_LEFT - { - # Receive entrypoint - - # Get the ticketer - READ_TICKET; CAR @ticketer; DUP; - - # Extract the associated ticket, if any, from the stored big map - DIG 4; - NONE (ticket unit); - DIG 2; - GET_AND_UPDATE; - - # Join it with the parameter - IF_SOME - { - DIG 3; - PAIR; - JOIN_TICKETS; - ASSERT_SOME - } - { DIG 2 }; - SOME; - DIG 2; - GET_AND_UPDATE; - ASSERT_NONE; - SWAP; - PAIR; - NIL operation - } - { - # Send entrypoints - - # Authenticate SENDER - DUP @manager 2; SENDER; ASSERT_CMPEQ; - - UNPAIR 3; - - # Get the ticket associated to the requested ticketer - DIG 4; - NONE (ticket unit); - DUP @ticketer 5; - GET_AND_UPDATE; - ASSERT_SOME; - - # Substract the requested amount - READ_TICKET; - GET @total_amount 4; - DUP @amount 5; - SWAP; SUB; ISNAT; ASSERT_SOME @remaining_amount; - - # Split the ticket - DIG 4; PAIR; SWAP; SPLIT_TICKET; - ASSERT_SOME; UNPAIR @to_send @to_keep; - - # Store the ticket to keep - DUG 5; - SOME; - DIG 3; - GET_AND_UPDATE; - ASSERT_NONE; - DIG 2; PAIR; - - # Send the ticket - SWAP; - PUSH mutez 0; - DIG 3; - TRANSFER_TOKENS; - NIL operation; - SWAP; - CONS; - }; - PAIR - } diff --git a/tests_python/contracts_012/mini_scenarios/ticket_wallet_non_fungible.tz b/tests_python/contracts_012/mini_scenarios/ticket_wallet_non_fungible.tz deleted file mode 100644 index ba0170ae830e..000000000000 --- a/tests_python/contracts_012/mini_scenarios/ticket_wallet_non_fungible.tz +++ /dev/null @@ -1,61 +0,0 @@ -## A simple wallet for non-fungible tokens implemented using tickets -## of type [ticket nat]. - -## For each nat [n], the ticketer is assumed to produce at most one -## ticket containing [n] and to always use amounts of exactly one. - -## For fungible tokens, see ticket_wallet_fungible.tz - -parameter (or (ticket %receive nat) (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id))); -storage (pair (address %manager) (big_map %tickets (pair address nat) (ticket nat))); -code - { - AMOUNT; PUSH mutez 0; ASSERT_CMPEQ; - - UNPAIR 3; - IF_LEFT - { - # Receive entrypoint - - # Get the ticketer and id - READ_TICKET; CAST (pair (address %ticketer) (nat %id) (nat %amount)); - UNPAIR 3; - DIG 2; PUSH nat 1; ASSERT_CMPEQ; # This checks that the amount is 1 - PAIR; - - # Extract the associated ticket, if any, from the stored big map - DIP {SOME; DIP {SWAP}}; - GET_AND_UPDATE; - ASSERT_NONE; - - SWAP; - PAIR; - NIL operation - } - { - # Send entrypoints - - # Authenticate SENDER - DUP @manager 2; SENDER; ASSERT_CMPEQ; - - UNPAIR; - - # Get the ticket associated to the requested ticketer and id - DIG 3; - NONE (ticket nat); - DIG 3; - GET_AND_UPDATE; - ASSERT_SOME; - - SWAP; DIG 3; PAIR; DUG 2; - - # Send the ticket - PUSH mutez 0; - SWAP; - TRANSFER_TOKENS; - NIL operation; - SWAP; - CONS; - }; - PAIR - } diff --git a/tests_python/contracts_012/mini_scenarios/tzip4_view.tz b/tests_python/contracts_012/mini_scenarios/tzip4_view.tz deleted file mode 100644 index aee5f1fa15f3..000000000000 --- a/tests_python/contracts_012/mini_scenarios/tzip4_view.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter (or (pair %view_const unit (contract nat)) (pair %view_add (pair int int) (contract int))); -storage unit; -code { - CAR; - IF_LEFT {CDR; AMOUNT; PUSH nat 5; TRANSFER_TOKENS; NIL operation; SWAP; CONS; UNIT; SWAP; PAIR} - {UNPAIR; UNPAIR; ADD; AMOUNT; SWAP; TRANSFER_TOKENS; NIL operation; SWAP; CONS; UNIT; SWAP; PAIR}; - } diff --git a/tests_python/contracts_012/mini_scenarios/vote_for_delegate.tz b/tests_python/contracts_012/mini_scenarios/vote_for_delegate.tz deleted file mode 100644 index 1155c073f588..000000000000 --- a/tests_python/contracts_012/mini_scenarios/vote_for_delegate.tz +++ /dev/null @@ -1,30 +0,0 @@ -parameter (option key_hash) ; -storage (pair - (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) ; -code { # Update the storage - DUP ; CDAAR %addr @%; SENDER ; PAIR %@ %@; UNPAIR; - IFCMPEQ - { UNPAIR ; SWAP ; SET_CADR %key @changed_mgr1_key } - { DUP ; CDDAR ; SENDER ; - IFCMPEQ - { UNPAIR ; SWAP ; SET_CDDR %key } - { FAIL } } ; - # Now compare the proposals - DUP ; CADR ; - DIP { DUP ; CDDR } ; - IF_NONE - { IF_NONE - { NONE key_hash ; - SET_DELEGATE ; NIL operation ; SWAP ; CONS } - { DROP ; NIL operation } } - { SWAP ; - IF_SOME - { DIP { DUP } ; - IFCMPEQ - { SOME ; - SET_DELEGATE ; NIL operation ; SWAP ; CONS } - { DROP ; - NIL operation }} - { DROP ; NIL operation }} ; - PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/weather_insurance.tz b/tests_python/contracts_012/mini_scenarios/weather_insurance.tz deleted file mode 100644 index e7e99e018335..000000000000 --- a/tests_python/contracts_012/mini_scenarios/weather_insurance.tz +++ /dev/null @@ -1,19 +0,0 @@ -parameter (pair (signature %signed_weather_data) (nat :rain %actual_level)); -# (pair (under_key over_key) (pair weather_service_key (pair rain_level days_in_future))) -storage (pair (pair (address %under_key) - (address %over_key)) - (pair (nat :rain %rain_level) (key %weather_service_key))); -code { DUP; DUP; - CAR; MAP_CDR{PACK ; BLAKE2B}; - SWAP; CDDDR %weather_service_key; - DIP {UNPAIR} ; CHECK_SIGNATURE @sigok; # Check if the data has been correctly signed - ASSERT; # If signature is not correct, end the execution - DUP; DUP; DUP; DIIIP{CDR %storage}; # Place storage type on bottom of stack - DIIP{CDAR}; # Place contracts below numbers - DIP{CADR %actual_level}; # Get actual rain - CDDAR %rain_level; # Get rain threshold - CMPLT; IF {CAR %under_key} {CDR %over_key}; # Select contract to receive tokens - CONTRACT unit ; ASSERT_SOME ; - BALANCE; UNIT ; TRANSFER_TOKENS @trans.op; # Setup and execute transfer - NIL operation ; SWAP ; CONS ; - PAIR }; diff --git a/tests_python/contracts_012/mini_scenarios/xcat.tz b/tests_python/contracts_012/mini_scenarios/xcat.tz deleted file mode 100644 index 83e6c7ac1d50..000000000000 --- a/tests_python/contracts_012/mini_scenarios/xcat.tz +++ /dev/null @@ -1,48 +0,0 @@ -parameter (bytes); -storage (unit); -code { - # Extract parameter from initial stack. - CAR @preimage; - DIP { - # Push contract constants to the stack. - # - # There's a temptation to use @storage to parametrize - # a contract but, in general, there's no reason to encumber - # @storage with immutable values. - PUSH @from key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; #changeme - IMPLICIT_ACCOUNT ; - PUSH @to key_hash "tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN"; #changeme - IMPLICIT_ACCOUNT ; - PUSH @target_hash bytes 0x123456; #changeme - PUSH @deadline timestamp "2018-08-08 00:00:00Z"; #changeme - }; - # Test if the deadline has passed. - SWAP; NOW; - IFCMPLT - # In case the deadline did pass: - { - # Ignore parameter, just transfer xtz balance back to @from - DROP; DROP; DROP; BALANCE; UNIT; TRANSFER_TOKENS; - } - # In case the deadline hasn't passed yet: - { - # Test length of parameter. - DUP; SIZE; - PUSH @max_length nat 32; - IFCMPLT - { PUSH string "preimage too long"; FAILWITH; } - { - # Test if it's a preimage of @target_hash. - SHA256 @candidate_hash; - IFCMPNEQ - { PUSH string "invalid preimage"; FAILWITH; } - { - # Transfer xtz balance to @to. - BALANCE; UNIT; TRANSFER_TOKENS; DIP { DROP }; - }; - }; - }; - # Transform single operation into a list. - NIL operation; SWAP; CONS; - UNIT; SWAP; PAIR - } diff --git a/tests_python/contracts_012/mini_scenarios/xcat_dapp.tz b/tests_python/contracts_012/mini_scenarios/xcat_dapp.tz deleted file mode 100644 index 86ca62c5ac50..000000000000 --- a/tests_python/contracts_012/mini_scenarios/xcat_dapp.tz +++ /dev/null @@ -1,79 +0,0 @@ -parameter (or - # First possible action is funding, to create an xcat - (pair %fund - (address %dest) - (pair %settings (bytes %target_hash) (timestamp %deadline))) - - # Other possible action is to claim the tokens (or ask a refund) - (or %claim_refund - (bytes %preimage_claim) - (bytes %refund_hash))); - -storage (pair - (big_map - bytes # The target hash is used as a key - (pair - # We store in %from the person who funded the xcat - (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - ) - unit); - -code { - NIL @operations operation; SWAP; - UNPAPAIR @% @% @%; DIP {DUP}; - IF_LEFT # Let's fund a new xcat! - { - # Unpack the parameters - UNPAIR @% @%; - # Assert that the destination address is of type unit. - # This costs a bit more gas but limits foot-shooting. - DUP; CONTRACT @dest unit; ASSERT_SOME; DROP; - SWAP; UNPAIR @% @%; - DIP - { - AMOUNT @amount; - SENDER; - DUP; CONTRACT @from unit; ASSERT_SOME; DROP; - DIP { PAIR; SWAP; }; PAIR; PAIR; SOME @xcat; - SWAP; - }; - DUP; DIP { MEM; NOT; ASSERT }; # Assert that this target hash isn't already in the map - UPDATE; PAIR @new_storage; SWAP; PAIR; - } - { - # Let's process a claim or a refund - IF_LEFT - { # It's a claim! - DUP; SIZE; PUSH nat 32; ASSERT_CMPGE; - SHA256 @hash; DUP; DIP {SWAP}; - DIIP { - GET; ASSERT_SOME; - # Check deadline and prepare transaction. - DUP; CADR @%; CONTRACT @dest unit; ASSERT_SOME; - SWAP; CDR @%; - UNPAIR @% @%; SWAP; - # The deadline must not have passed - NOW; ASSERT_CMPLT; - # prepare transaction - UNIT; TRANSFER_TOKENS; - }; - } - { # It's a refund! - DUP; - DIP - { - GET; ASSERT_SOME; - DUP; CAAR @%; CONTRACT @from unit; ASSERT_SOME; SWAP; CDR; - UNPAIR @% @%; SWAP; - # The deadline must not HAVE passed - NOW; ASSERT_CMPGE; - UNIT; TRANSFER_TOKENS; SWAP; - }; - }; - # Clear the big map - NONE @none (pair (pair address address) (pair mutez timestamp)); - SWAP; UPDATE @cleared_map; SWAP; DIP { PAIR; SWAP }; - CONS; PAIR; - } - } \ No newline at end of file diff --git a/tests_python/contracts_012/non_regression/bug_262.tz b/tests_python/contracts_012/non_regression/bug_262.tz deleted file mode 100644 index 63475c5ac185..000000000000 --- a/tests_python/contracts_012/non_regression/bug_262.tz +++ /dev/null @@ -1,5 +0,0 @@ -{ parameter unit ; - storage unit ; - code { DROP ; - LAMBDA unit unit {} ; UNIT ; EXEC ; - NIL operation ; PAIR } } \ No newline at end of file diff --git a/tests_python/contracts_012/non_regression/pairk_annot.tz b/tests_python/contracts_012/non_regression/pairk_annot.tz deleted file mode 100644 index 8b0cf242bd9c..000000000000 --- a/tests_python/contracts_012/non_regression/pairk_annot.tz +++ /dev/null @@ -1,7 +0,0 @@ -# Test for old PAIR k annotation handling bug -parameter unit; -storage unit; -code { SENDER; SOURCE; PAIR 2; - SOURCE; SENDER; PAIR 2; - COMPARE; DROP; - CDR; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/abs.tz b/tests_python/contracts_012/opcodes/abs.tz deleted file mode 100644 index d03d0883fe73..000000000000 --- a/tests_python/contracts_012/opcodes/abs.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter nat; -storage unit; -code { CAR; - DUP; NEG; ABS; COMPARE; ASSERT_EQ; - UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add.tz b/tests_python/contracts_012/opcodes/add.tz deleted file mode 100644 index cbefea08a7a4..000000000000 --- a/tests_python/contracts_012/opcodes/add.tz +++ /dev/null @@ -1,25 +0,0 @@ -parameter unit; -storage unit; -code - { - CAR; - - PUSH int 2; PUSH int 2; ADD; PUSH int 4; ASSERT_CMPEQ; - PUSH int 2; PUSH int 2; ADD; PUSH int 4; ASSERT_CMPEQ; - PUSH int 2; PUSH nat 2; ADD; PUSH int 4; ASSERT_CMPEQ; - PUSH nat 2; PUSH int 2; ADD; PUSH int 4; ASSERT_CMPEQ; - PUSH nat 2; PUSH nat 2; ADD; PUSH nat 4; ASSERT_CMPEQ; - - # Offset a timestamp by 60 seconds - PUSH int 60; PUSH timestamp "2019-09-09T12:08:37Z"; ADD; - PUSH timestamp "2019-09-09T12:09:37Z"; ASSERT_CMPEQ; - - PUSH timestamp "2019-09-09T12:08:37Z"; PUSH int 60; ADD; - PUSH timestamp "2019-09-09T12:09:37Z"; ASSERT_CMPEQ; - - PUSH mutez 1000; PUSH mutez 1000; ADD; - PUSH mutez 2000; ASSERT_CMPEQ; - - NIL operation; - PAIR; - } diff --git a/tests_python/contracts_012/opcodes/add_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/add_bls12_381_fr.tz deleted file mode 100644 index e7b60dedc932..000000000000 --- a/tests_python/contracts_012/opcodes/add_bls12_381_fr.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair bls12_381_fr bls12_381_fr); -storage (option (bls12_381_fr)); -code {CAR; UNPAIR; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add_bls12_381_g1.tz b/tests_python/contracts_012/opcodes/add_bls12_381_g1.tz deleted file mode 100644 index 9f817c88d8a5..000000000000 --- a/tests_python/contracts_012/opcodes/add_bls12_381_g1.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair bls12_381_g1 bls12_381_g1); -storage (option (bls12_381_g1)); -code {CAR; UNPAIR; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add_bls12_381_g2.tz b/tests_python/contracts_012/opcodes/add_bls12_381_g2.tz deleted file mode 100644 index 1d1c0688c1d2..000000000000 --- a/tests_python/contracts_012/opcodes/add_bls12_381_g2.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair bls12_381_g2 bls12_381_g2); -storage (option (bls12_381_g2)); -code {CAR; UNPAIR; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add_delta_timestamp.tz b/tests_python/contracts_012/opcodes/add_delta_timestamp.tz deleted file mode 100644 index b9ed86901726..000000000000 --- a/tests_python/contracts_012/opcodes/add_delta_timestamp.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int timestamp); -storage (option timestamp); -code { CAR; DUP; CAR; DIP{CDR}; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add_timestamp_delta.tz b/tests_python/contracts_012/opcodes/add_timestamp_delta.tz deleted file mode 100644 index 766bf9f91f51..000000000000 --- a/tests_python/contracts_012/opcodes/add_timestamp_delta.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair timestamp int); -storage (option timestamp); -code { CAR; DUP; CAR; DIP{CDR}; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/address.tz b/tests_python/contracts_012/opcodes/address.tz deleted file mode 100644 index 7e6bcdec337b..000000000000 --- a/tests_python/contracts_012/opcodes/address.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (contract unit); -storage (option address); -code {CAR; ADDRESS; SOME; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/amount_after_fib_view.tz b/tests_python/contracts_012/opcodes/amount_after_fib_view.tz deleted file mode 100644 index 50fdf3d7c139..000000000000 --- a/tests_python/contracts_012/opcodes/amount_after_fib_view.tz +++ /dev/null @@ -1,24 +0,0 @@ -# This contract calls the view `fib` on the address passed as -# parameter. After returning from the view it stores its AMOUNT. -parameter address ; -storage mutez; -code - { CAR ; - DUP ; - PUSH nat 3 ; - VIEW "fib" nat; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 15000000 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - AMOUNT; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - diff --git a/tests_python/contracts_012/opcodes/amount_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/amount_after_nonexistent_view.tz deleted file mode 100644 index d373e1c9e52b..000000000000 --- a/tests_python/contracts_012/opcodes/amount_after_nonexistent_view.tz +++ /dev/null @@ -1,23 +0,0 @@ -# This contract calls the non-existent view on the address -# passed as parameter. After returning from the view it -# stores it's AMOUNT. -parameter address ; -storage mutez; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "nonexistent" (pair nat nat) ; - ASSERT_NONE ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 15000000 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - AMOUNT; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; diff --git a/tests_python/contracts_012/opcodes/amount_after_view.tz b/tests_python/contracts_012/opcodes/amount_after_view.tz deleted file mode 100644 index eab7c02256ef..000000000000 --- a/tests_python/contracts_012/opcodes/amount_after_view.tz +++ /dev/null @@ -1,26 +0,0 @@ -# This contract calls the view `id` on the address passed as -# parameter. After returning from the view it stores its AMOUNT. -parameter address ; -storage mutez; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "id" (pair nat nat) ; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 15000000 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - AMOUNT; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - - - diff --git a/tests_python/contracts_012/opcodes/and.tz b/tests_python/contracts_012/opcodes/and.tz deleted file mode 100644 index 48e346ca04f3..000000000000 --- a/tests_python/contracts_012/opcodes/and.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair :param (bool %first) (bool %second)); -storage (option bool); -code { CAR ; UNPAIR; AND @and; SOME @res; NIL @noop operation; PAIR; UNPAIR @x @y; PAIR %a %b }; diff --git a/tests_python/contracts_012/opcodes/and_binary.tz b/tests_python/contracts_012/opcodes/and_binary.tz deleted file mode 100644 index 96f60082c713..000000000000 --- a/tests_python/contracts_012/opcodes/and_binary.tz +++ /dev/null @@ -1,27 +0,0 @@ -parameter unit; -storage unit; -code { DROP; - - # 0101 & 0110 = 0100 - PUSH nat 5; PUSH nat 6; AND; PUSH nat 4; ASSERT_CMPEQ; - - # 0110 & 0101 = 0100 - PUSH nat 6; PUSH int 5; AND; PUSH nat 4; ASSERT_CMPEQ; - - # Negative numbers are represented as with a initial virtual - # infinite series of 1's. - # Hence, AND with -1 (1111...) is identity: - - # 12 = ...1100 - # & -1 = ...1111 - # ---- - # = 12 = ...1100 - PUSH nat 12; PUSH int -1; AND; PUSH nat 12; ASSERT_CMPEQ; - - # 12 = ...0001100 - # & -5 = ...1111011 - # ----------------- - # 8 = ...0001000 - PUSH nat 12; PUSH int -5; AND; PUSH nat 8; ASSERT_CMPEQ; - - UNIT; NIL @noop operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/and_logical_1.tz b/tests_python/contracts_012/opcodes/and_logical_1.tz deleted file mode 100644 index 20743c0bfdf9..000000000000 --- a/tests_python/contracts_012/opcodes/and_logical_1.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair bool bool); -storage bool; -code { CAR ; UNPAIR; AND @and; NIL @noop operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/balance.tz b/tests_python/contracts_012/opcodes/balance.tz deleted file mode 100644 index 0a9bfc61494c..000000000000 --- a/tests_python/contracts_012/opcodes/balance.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage mutez; -code {DROP; BALANCE; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/balance_after_fib_view.tz b/tests_python/contracts_012/opcodes/balance_after_fib_view.tz deleted file mode 100644 index b9a52d1e895a..000000000000 --- a/tests_python/contracts_012/opcodes/balance_after_fib_view.tz +++ /dev/null @@ -1,25 +0,0 @@ -# This contract calls the view `fib` on the address passed as -# parameter. After returning from the view it stores its BALANCE. -parameter address ; -storage mutez; -code - { CAR ; - DUP ; - PUSH nat 3 ; - VIEW "fib" nat; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 15000000 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - BALANCE; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - - diff --git a/tests_python/contracts_012/opcodes/balance_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/balance_after_nonexistent_view.tz deleted file mode 100644 index 96bb623530df..000000000000 --- a/tests_python/contracts_012/opcodes/balance_after_nonexistent_view.tz +++ /dev/null @@ -1,22 +0,0 @@ -# This contract calls the noneexistent view on the address passed as -# parameter. After returning from the view it stores it's BALANCE. -parameter address ; -storage mutez; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "nonexistent" (pair nat nat) ; - ASSERT_NONE ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 15000000 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - BALANCE; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; diff --git a/tests_python/contracts_012/opcodes/balance_after_view.tz b/tests_python/contracts_012/opcodes/balance_after_view.tz deleted file mode 100644 index c2acc0320cdc..000000000000 --- a/tests_python/contracts_012/opcodes/balance_after_view.tz +++ /dev/null @@ -1,25 +0,0 @@ -# This contract calls the view `id` on the address passed as -# parameter. After returning from the view it stores its BALANCE. -parameter address ; -storage mutez; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "id" (pair nat nat) ; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 15000000 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - BALANCE; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - - diff --git a/tests_python/contracts_012/opcodes/big_map_mem_nat.tz b/tests_python/contracts_012/opcodes/big_map_mem_nat.tz deleted file mode 100644 index 71ecaf2c4a75..000000000000 --- a/tests_python/contracts_012/opcodes/big_map_mem_nat.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter nat; -storage (pair (big_map nat nat) (option bool)) ; -# stores (map, Some flag) where flag = parameter is a member of -# the map in first component of storage -code { UNPAIR; - DIP { CAR; DUP }; - MEM; SOME; SWAP; PAIR; NIL operation; PAIR;} diff --git a/tests_python/contracts_012/opcodes/big_map_mem_string.tz b/tests_python/contracts_012/opcodes/big_map_mem_string.tz deleted file mode 100644 index 8c557f7dc1f8..000000000000 --- a/tests_python/contracts_012/opcodes/big_map_mem_string.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter string; -storage (pair (big_map string nat) (option bool)) ; -# stores (map, Some flag) where flag = parameter is a member of -# the map in first component of storage -code { UNPAIR; - DIP { CAR; DUP }; - MEM; SOME; SWAP; PAIR; NIL operation; PAIR;} diff --git a/tests_python/contracts_012/opcodes/big_map_to_self.tz b/tests_python/contracts_012/opcodes/big_map_to_self.tz deleted file mode 100644 index 6a9442b9f3e5..000000000000 --- a/tests_python/contracts_012/opcodes/big_map_to_self.tz +++ /dev/null @@ -1,22 +0,0 @@ -parameter (or (pair %have_fun (big_map string nat) unit) (unit %default)); -storage (big_map string nat); -code { - UNPAIR; - DIP {NIL operation}; - IF_LEFT { - DROP - } - { - DROP; - SELF %have_fun; - PUSH mutez 0; - DUP 4; - PUSH (option nat) (Some 8); - PUSH string "hahaha"; - UPDATE; - UNIT; SWAP; PAIR; - TRANSFER_TOKENS; - CONS - }; - PAIR - } diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_push_bytes_not_padded.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_push_bytes_not_padded.tz deleted file mode 100644 index fd4142914d2c..000000000000 --- a/tests_python/contracts_012/opcodes/bls12_381_fr_push_bytes_not_padded.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter unit; -storage (option bls12_381_fr); -code { - DROP; - PUSH bls12_381_fr 0x00; - SOME; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_push_nat.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_push_nat.tz deleted file mode 100644 index 314b97f2a6b9..000000000000 --- a/tests_python/contracts_012/opcodes/bls12_381_fr_push_nat.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter unit; -storage (option bls12_381_fr); -code { - DROP; - PUSH bls12_381_fr 16; - SOME; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_to_int.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_to_int.tz deleted file mode 100644 index 67e2c9b080b1..000000000000 --- a/tests_python/contracts_012/opcodes/bls12_381_fr_to_int.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter bls12_381_fr; -storage int; -code { - CAR; - INT; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_to_mutez.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_to_mutez.tz deleted file mode 100644 index 39630958e515..000000000000 --- a/tests_python/contracts_012/opcodes/bls12_381_fr_to_mutez.tz +++ /dev/null @@ -1,12 +0,0 @@ -parameter bls12_381_fr; -storage mutez; -code { - CAR; - INT; - ISNAT; - ASSERT_SOME; - PUSH mutez 1; - MUL; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_z_int.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_z_int.tz deleted file mode 100644 index 67018c55faba..000000000000 --- a/tests_python/contracts_012/opcodes/bls12_381_fr_z_int.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter int; -storage (bls12_381_fr); -code { - UNPAIR; - MUL; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_z_nat.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_z_nat.tz deleted file mode 100644 index 1376e0c39561..000000000000 --- a/tests_python/contracts_012/opcodes/bls12_381_fr_z_nat.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter nat; -storage (bls12_381_fr); -code { - UNPAIR; - MUL; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_z_fr_int.tz b/tests_python/contracts_012/opcodes/bls12_381_z_fr_int.tz deleted file mode 100644 index 783fb3c0d660..000000000000 --- a/tests_python/contracts_012/opcodes/bls12_381_z_fr_int.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter int; -storage (bls12_381_fr); -code { - UNPAIR; - SWAP; - MUL; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_z_fr_nat.tz b/tests_python/contracts_012/opcodes/bls12_381_z_fr_nat.tz deleted file mode 100644 index 1210e36db0e1..000000000000 --- a/tests_python/contracts_012/opcodes/bls12_381_z_fr_nat.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter nat; -storage (bls12_381_fr); -code { - UNPAIR; - SWAP; - MUL; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bytes.tz b/tests_python/contracts_012/opcodes/bytes.tz deleted file mode 100644 index e4dd8445eecc..000000000000 --- a/tests_python/contracts_012/opcodes/bytes.tz +++ /dev/null @@ -1,11 +0,0 @@ -# A contract that accepts bytes in a default entry point and does nothing. -# Useful for testing transfers of arbitrary sizes. -parameter bytes; -storage unit; -code - { - CDR; # @storage - # == default == # @storage - NIL operation; # list operation : @storage - PAIR; # pair (list operation) @storage - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/car.tz b/tests_python/contracts_012/opcodes/car.tz deleted file mode 100644 index 8fd03ba51052..000000000000 --- a/tests_python/contracts_012/opcodes/car.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair (nat :l) (nat :r)); -storage nat; -code { CAR; CAR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/cdr.tz b/tests_python/contracts_012/opcodes/cdr.tz deleted file mode 100644 index dae260c5be74..000000000000 --- a/tests_python/contracts_012/opcodes/cdr.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair (nat :l) (nat :r)); -storage nat; -code { CAR; CDR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/chain_id.tz b/tests_python/contracts_012/opcodes/chain_id.tz deleted file mode 100644 index 783d13fa0afc..000000000000 --- a/tests_python/contracts_012/opcodes/chain_id.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage unit; -code { CHAIN_ID; DROP; CAR; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/chain_id_store.tz b/tests_python/contracts_012/opcodes/chain_id_store.tz deleted file mode 100644 index 11e57fd210c7..000000000000 --- a/tests_python/contracts_012/opcodes/chain_id_store.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage (option chain_id); -code { DROP; CHAIN_ID; SOME; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/check_signature.tz b/tests_python/contracts_012/opcodes/check_signature.tz deleted file mode 100644 index b5d5b2842648..000000000000 --- a/tests_python/contracts_012/opcodes/check_signature.tz +++ /dev/null @@ -1,10 +0,0 @@ -parameter key; -storage (pair signature string); -code { - DUP; DUP; - DIP{ CDR; DUP; CAR; - DIP{CDR; PACK}}; - CAR; CHECK_SIGNATURE; - IF {} {FAIL} ; - CDR; NIL operation ; PAIR}; - diff --git a/tests_python/contracts_012/opcodes/comb-get.tz b/tests_python/contracts_012/opcodes/comb-get.tz deleted file mode 100644 index 5493d68f2696..000000000000 --- a/tests_python/contracts_012/opcodes/comb-get.tz +++ /dev/null @@ -1,27 +0,0 @@ -# See also ../macros/carn_and_cdrn.tz for the same test using the -# CAR n and CDR n macros. -parameter (pair nat nat nat unit); -storage unit; -code { - CAR ; - - # Checking the first element - DUP ; CAR ; - PUSH nat 1 ; ASSERT_CMPEQ ; - DUP ; GET 1 ; - PUSH nat 1 ; ASSERT_CMPEQ ; - - # Checking the second element - DUP ; GET 3 ; - PUSH nat 4 ; ASSERT_CMPEQ ; - - # Checking the third element - DUP ; GET 5 ; - PUSH nat 2 ; ASSERT_CMPEQ ; - - # Checking the last (fourth) element - DUP ; GET 6 ; - UNIT ; ASSERT_CMPEQ ; - - DROP ; UNIT ; NIL operation ; PAIR - } diff --git a/tests_python/contracts_012/opcodes/comb-literals.tz b/tests_python/contracts_012/opcodes/comb-literals.tz deleted file mode 100644 index 2a2b217d7857..000000000000 --- a/tests_python/contracts_012/opcodes/comb-literals.tz +++ /dev/null @@ -1,9 +0,0 @@ -# This pushes a list of combs to test the effect of the normalize script command -parameter unit; -storage unit; -code { - PUSH - (list (pair nat nat nat nat)) - {Pair 0 3 6 9; Pair 1 (Pair 4 (Pair 7 10)); {2; 5; 8; 11}}; - DROP 2; UNIT; NIL operation; PAIR - } diff --git a/tests_python/contracts_012/opcodes/comb-set-2.tz b/tests_python/contracts_012/opcodes/comb-set-2.tz deleted file mode 100644 index 757acfd380e6..000000000000 --- a/tests_python/contracts_012/opcodes/comb-set-2.tz +++ /dev/null @@ -1,10 +0,0 @@ -# This tests UPDATE on combs. Contrary to comb-set.tz, both the values -# and their types are updated. -parameter (pair nat nat nat unit); -storage (option (pair int nat string bytes)); -code { - CAR ; - PUSH int 2 ; UPDATE 1 ; - PUSH string "toto" ; UPDATE 5 ; - PUSH bytes 0x01 ; UPDATE 6 ; - SOME ; NIL operation ; PAIR ; } diff --git a/tests_python/contracts_012/opcodes/comb-set.tz b/tests_python/contracts_012/opcodes/comb-set.tz deleted file mode 100644 index fe407571923e..000000000000 --- a/tests_python/contracts_012/opcodes/comb-set.tz +++ /dev/null @@ -1,10 +0,0 @@ -# This tests UPDATE on combs. See also comb-set-2.tz for tests of -# UPDATE that also change the type of fields. -parameter unit; -storage (pair nat nat nat unit); -code { CDR ; - PUSH nat 2 ; UPDATE 1 ; - PUSH nat 12 ; UPDATE 3 ; - PUSH nat 8 ; UPDATE 5 ; - UNIT ; UPDATE 6 ; - NIL operation ; PAIR ; } diff --git a/tests_python/contracts_012/opcodes/comb.tz b/tests_python/contracts_012/opcodes/comb.tz deleted file mode 100644 index 6709bde8b883..000000000000 --- a/tests_python/contracts_012/opcodes/comb.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter unit; -storage (pair nat nat nat); -code { DROP ; - PUSH nat 3 ; - PUSH nat 2 ; - PUSH nat 1 ; - NIL operation ; - PAIR 4 - } diff --git a/tests_python/contracts_012/opcodes/compare.tz b/tests_python/contracts_012/opcodes/compare.tz deleted file mode 100644 index 963215fb46cd..000000000000 --- a/tests_python/contracts_012/opcodes/compare.tz +++ /dev/null @@ -1,52 +0,0 @@ -parameter unit; -storage unit; -code { - DROP; - - # bool - PUSH bool True; DUP; COMPARE; ASSERT_EQ; - PUSH bool False; DUP; COMPARE; ASSERT_EQ; - PUSH bool False; PUSH bool True; COMPARE; ASSERT_GT; - PUSH bool True; PUSH bool False; COMPARE; ASSERT_LT; - - # bytes - PUSH bytes 0xAABBCC; DUP; COMPARE; ASSERT_EQ; - PUSH bytes 0x; PUSH bytes 0x; COMPARE; ASSERT_EQ; - PUSH bytes 0x; PUSH bytes 0x01; COMPARE; ASSERT_GT; - PUSH bytes 0x01; PUSH bytes 0x02; COMPARE; ASSERT_GT; - PUSH bytes 0x02; PUSH bytes 0x01; COMPARE; ASSERT_LT; - - # int - PUSH int 1; DUP; COMPARE; ASSERT_EQ; - PUSH int 10; PUSH int 5; COMPARE; ASSERT_LT; - PUSH int -4; PUSH int 1923; COMPARE; ASSERT_GT; - - # nat - PUSH nat 1; DUP; COMPARE; ASSERT_EQ; - PUSH nat 10; PUSH nat 5; COMPARE; ASSERT_LT; - PUSH nat 4; PUSH nat 1923; COMPARE; ASSERT_GT; - - # key_hash - PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; DUP; COMPARE; ASSERT_EQ; - PUSH key_hash "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv"; PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; COMPARE; ASSERT_LT; - PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; PUSH key_hash "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv"; COMPARE; ASSERT_GT; - - # mutez - PUSH mutez 1; DUP; COMPARE; ASSERT_EQ; - PUSH mutez 10; PUSH mutez 5; COMPARE; ASSERT_LT; - PUSH mutez 4; PUSH mutez 1923; COMPARE; ASSERT_GT; - - # string - PUSH string "AABBCC"; DUP; COMPARE; ASSERT_EQ; - PUSH string ""; PUSH string ""; COMPARE; ASSERT_EQ; - PUSH string ""; PUSH string "a"; COMPARE; ASSERT_GT; - PUSH string "a"; PUSH string "b"; COMPARE; ASSERT_GT; - PUSH string "b"; PUSH string "a"; COMPARE; ASSERT_LT; - - # timestamp - PUSH timestamp "2019-09-16T08:38:05Z"; DUP; COMPARE; ASSERT_EQ; - PUSH timestamp "2017-09-16T08:38:04Z"; PUSH timestamp "2019-09-16T08:38:05Z"; COMPARE; ASSERT_GT; - PUSH timestamp "2019-09-16T08:38:05Z"; PUSH timestamp "2019-09-16T08:38:04Z"; COMPARE; ASSERT_LT; - - UNIT; NIL operation; PAIR; - } diff --git a/tests_python/contracts_012/opcodes/compare_big_type.tz b/tests_python/contracts_012/opcodes/compare_big_type.tz deleted file mode 100644 index 666ad3137777..000000000000 --- a/tests_python/contracts_012/opcodes/compare_big_type.tz +++ /dev/null @@ -1,20 +0,0 @@ -# This contract should cost a lot of gas to typecheck -# because big types are compared in COMPARE -parameter unit; -storage unit; -code { DROP; PUSH nat 0 ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DROP ; UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/compare_big_type2.tz b/tests_python/contracts_012/opcodes/compare_big_type2.tz deleted file mode 100644 index 126217d79fdf..000000000000 --- a/tests_python/contracts_012/opcodes/compare_big_type2.tz +++ /dev/null @@ -1,22 +0,0 @@ -# Like compare_big_type.tz but with an extra line -# DUP ; DUP ; COMPARE ; DROP ; -# so that we can measure how much it costs -parameter unit; -storage unit; -code { DROP; PUSH nat 0 ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DUP ; DUP ; COMPARE ; DROP ; - DROP ; UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/comparisons.tz b/tests_python/contracts_012/opcodes/comparisons.tz deleted file mode 100644 index c603f07339ce..000000000000 --- a/tests_python/contracts_012/opcodes/comparisons.tz +++ /dev/null @@ -1,15 +0,0 @@ -parameter (list int); -storage (list (list bool)); -code { - CAR; - - NIL (list bool); - DIP {DUP; MAP { EQ; };}; SWAP; CONS; - DIP {DUP; MAP { NEQ; };}; SWAP; CONS; - DIP {DUP; MAP { LE; };}; SWAP; CONS; - DIP {DUP; MAP { LT; };}; SWAP; CONS; - DIP {DUP; MAP { GE; };}; SWAP; CONS; - DIP {MAP { GT; };}; SWAP; CONS; - - NIL operation; PAIR; - } diff --git a/tests_python/contracts_012/opcodes/concat_hello.tz b/tests_python/contracts_012/opcodes/concat_hello.tz deleted file mode 100644 index e290b90fb2ad..000000000000 --- a/tests_python/contracts_012/opcodes/concat_hello.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter (list string); -storage (list string); -code{ CAR; - MAP { PUSH @hello string "Hello "; CONCAT }; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/concat_hello_bytes.tz b/tests_python/contracts_012/opcodes/concat_hello_bytes.tz deleted file mode 100644 index 55f8ab7a216b..000000000000 --- a/tests_python/contracts_012/opcodes/concat_hello_bytes.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter (list bytes); -storage (list bytes); -code{ CAR; - MAP { PUSH bytes 0xFF; CONCAT }; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/concat_list.tz b/tests_python/contracts_012/opcodes/concat_list.tz deleted file mode 100644 index b570027ff68e..000000000000 --- a/tests_python/contracts_012/opcodes/concat_list.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (list string); -storage string; -code {CAR; PUSH string ""; SWAP; - ITER {SWAP; DIP{NIL string; SWAP; CONS}; CONS; CONCAT}; - NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/cons.tz b/tests_python/contracts_012/opcodes/cons.tz deleted file mode 100644 index 5189b47c36b4..000000000000 --- a/tests_python/contracts_012/opcodes/cons.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter int; -storage (list int); -code { UNPAIR; CONS; NIL operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/contains_all.tz b/tests_python/contracts_012/opcodes/contains_all.tz deleted file mode 100644 index fe4160f87227..000000000000 --- a/tests_python/contracts_012/opcodes/contains_all.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter (pair (list string) (list string)); -storage (option bool); -code {CAR; DUP; CAR; DIP{CDR}; EMPTY_SET string; SWAP; - ITER {PAIR; DUP; CAR; DIP{CDR}; PUSH bool True; SWAP; UPDATE}; - PUSH bool True; SWAP; PAIR; SWAP; - ITER {PAIR; DUP; DUP; CAR; DIP{CDAR; DIP{CDDR}; DUP}; MEM; DIP{SWAP}; AND; SWAP; PAIR}; - CDR; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/contract.tz b/tests_python/contracts_012/opcodes/contract.tz deleted file mode 100644 index 939337918d1c..000000000000 --- a/tests_python/contracts_012/opcodes/contract.tz +++ /dev/null @@ -1,11 +0,0 @@ -parameter address; -storage unit; -code { - CAR; - CONTRACT unit; - ASSERT_SOME; - DROP; - UNIT; - NIL operation; - PAIR - }; diff --git a/tests_python/contracts_012/opcodes/create_contract.tz b/tests_python/contracts_012/opcodes/create_contract.tz deleted file mode 100644 index d3fb8dc617a8..000000000000 --- a/tests_python/contracts_012/opcodes/create_contract.tz +++ /dev/null @@ -1,14 +0,0 @@ -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 unit ; - storage unit ; - code - { CDR; - NIL operation; - PAIR; } }; - DIP {SOME;NIL operation};CONS ; PAIR} # Ending calling convention stuff diff --git a/tests_python/contracts_012/opcodes/create_contract_rootname.tz b/tests_python/contracts_012/opcodes/create_contract_rootname.tz deleted file mode 100644 index b85b4cf8bb41..000000000000 --- a/tests_python/contracts_012/opcodes/create_contract_rootname.tz +++ /dev/null @@ -1,15 +0,0 @@ -# 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_012/opcodes/create_contract_rootname_alt.tz b/tests_python/contracts_012/opcodes/create_contract_rootname_alt.tz deleted file mode 100644 index 226a9abba298..000000000000 --- a/tests_python/contracts_012/opcodes/create_contract_rootname_alt.tz +++ /dev/null @@ -1,14 +0,0 @@ -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 (unit %root) ; - storage unit ; - code - { CDR; - NIL operation; - PAIR; } }; - DIP {SOME;NIL operation}; CONS ; PAIR} # Ending calling convention stuff diff --git a/tests_python/contracts_012/opcodes/create_contract_with_view.tz b/tests_python/contracts_012/opcodes/create_contract_with_view.tz deleted file mode 100644 index c8b591e9d3bc..000000000000 --- a/tests_python/contracts_012/opcodes/create_contract_with_view.tz +++ /dev/null @@ -1,17 +0,0 @@ -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 unit ; - storage unit ; - code - { CDR; - NIL operation; - PAIR; } ; - view "const" nat nat { CAR; } ; - }; - DIP {SOME;NIL operation};CONS ; PAIR} # Ending calling convention stuff - diff --git a/tests_python/contracts_012/opcodes/diff_timestamps.tz b/tests_python/contracts_012/opcodes/diff_timestamps.tz deleted file mode 100644 index f1991a37a5d2..000000000000 --- a/tests_python/contracts_012/opcodes/diff_timestamps.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair timestamp timestamp); -storage int; -code { CAR; DUP; CAR; DIP{CDR}; SUB; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/dig_eq.tz b/tests_python/contracts_012/opcodes/dig_eq.tz deleted file mode 100644 index aaafc4271fae..000000000000 --- a/tests_python/contracts_012/opcodes/dig_eq.tz +++ /dev/null @@ -1,14 +0,0 @@ -parameter (pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat); -storage unit; -# this contract receives a 17-tuple, unpairs it, reverses the order, reverses it again, and pairs it and verifies that the result is the same as the original tuple. -code { CAR; - DUP; - - UNPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAIR; - DIG 0; DIG 1; DIG 2; DIG 3; DIG 4; DIG 5; DIG 6; DIG 7; DIG 8; DIG 9; DIG 10; DIG 11; DIG 12; DIG 13; DIG 14; DIG 15; DIG 16; - # PUSH nat 1; ADD; - DIG 0; DIG 1; DIG 2; DIG 3; DIG 4; DIG 5; DIG 6; DIG 7; DIG 8; DIG 9; DIG 10; DIG 11; DIG 12; DIG 13; DIG 14; DIG 15; DIG 16; - PAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAIR; - ASSERT_CMPEQ; - - UNIT; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dign.tz b/tests_python/contracts_012/opcodes/dign.tz deleted file mode 100644 index ec8a339dd48c..000000000000 --- a/tests_python/contracts_012/opcodes/dign.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair (pair (pair (pair nat nat) nat) nat) nat); -storage nat; -code {CAR; UNPAIR ; UNPAIR ; UNPAIR ; UNPAIR ; DIG 4 ; DIP { DROP ; DROP ; DROP ; DROP } ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dip.tz b/tests_python/contracts_012/opcodes/dip.tz deleted file mode 100644 index f0c32a838747..000000000000 --- a/tests_python/contracts_012/opcodes/dip.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter (pair nat nat); -storage (pair nat nat); -code{ - CAR; UNPAIR; - DUP; DIP { ADD }; - PAIR; - NIL operation; - PAIR}; diff --git a/tests_python/contracts_012/opcodes/dipn.tz b/tests_python/contracts_012/opcodes/dipn.tz deleted file mode 100644 index 55d088e5518f..000000000000 --- a/tests_python/contracts_012/opcodes/dipn.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair (pair (pair (pair nat nat) nat) nat) nat); -storage nat; -code {CAR; UNPAIR ; UNPAIR ; UNPAIR ; UNPAIR ; DIP 5 {PUSH nat 6} ; DROP ; DROP ; DROP ; DROP ; DROP ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dropn.tz b/tests_python/contracts_012/opcodes/dropn.tz deleted file mode 100644 index 4b5379b3a3b3..000000000000 --- a/tests_python/contracts_012/opcodes/dropn.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair (pair (pair (pair nat nat) nat) nat) nat); -storage nat; -code {CAR; UNPAIR ; UNPAIR ; UNPAIR ; UNPAIR ; DROP 4 ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dugn.tz b/tests_python/contracts_012/opcodes/dugn.tz deleted file mode 100644 index 521c052f1fcd..000000000000 --- a/tests_python/contracts_012/opcodes/dugn.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair (pair (pair (pair nat nat) nat) nat) nat); -storage nat; -code {CAR; UNPAIR ; UNPAIR ; UNPAIR ; UNPAIR ; DUG 4 ; DROP ; DROP ; DROP ; DROP ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dup-n.tz b/tests_python/contracts_012/opcodes/dup-n.tz deleted file mode 100644 index 7e530c0971d0..000000000000 --- a/tests_python/contracts_012/opcodes/dup-n.tz +++ /dev/null @@ -1,18 +0,0 @@ -parameter unit; -storage unit; -code - { - DROP ; - PUSH nat 5 ; - PUSH nat 4 ; - PUSH nat 3 ; - PUSH nat 2 ; - PUSH nat 1 ; - DUP 1 ; PUSH nat 1 ; ASSERT_CMPEQ ; - DUP 2 ; PUSH nat 2 ; ASSERT_CMPEQ ; - DUP 3 ; PUSH nat 3 ; ASSERT_CMPEQ ; - DUP 4 ; PUSH nat 4 ; ASSERT_CMPEQ ; - DUP 5 ; PUSH nat 5 ; ASSERT_CMPEQ ; - DROP 5 ; - UNIT ; NIL operation ; PAIR ; - }; diff --git a/tests_python/contracts_012/opcodes/ediv.tz b/tests_python/contracts_012/opcodes/ediv.tz deleted file mode 100644 index a1fc89992a02..000000000000 --- a/tests_python/contracts_012/opcodes/ediv.tz +++ /dev/null @@ -1,13 +0,0 @@ -parameter (pair int int); -storage (pair (option (pair int nat)) (option (pair int nat)) (option (pair int nat)) (option (pair nat nat))); -code { CAR; - # :: nat : nat : 'S -> option (pair nat nat) : 'S - DUP; UNPAIR; ABS; DIP { ABS; }; EDIV; SWAP; - # :: nat : int : 'S -> option (pair int nat) : 'S - DUP; UNPAIR; ABS; EDIV; SWAP; - # :: int : nat : 'S -> option (pair int nat) : 'S - DUP; UNPAIR; DIP { ABS; }; EDIV; SWAP; - # :: int : int : 'S -> option (pair int nat) : 'S - UNPAIR; EDIV; - PAPAPAIR; - NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/ediv_mutez.tz b/tests_python/contracts_012/opcodes/ediv_mutez.tz deleted file mode 100644 index 2df73dd4a0e3..000000000000 --- a/tests_python/contracts_012/opcodes/ediv_mutez.tz +++ /dev/null @@ -1,12 +0,0 @@ -parameter (pair mutez (or mutez nat)); -storage (or (option (pair nat mutez)) (option (pair mutez mutez))); -code { CAR; - UNPAIR; - SWAP; - IF_LEFT { - SWAP; EDIV; LEFT (option (pair mutez mutez)); - } - { - SWAP; EDIV; RIGHT (option (pair nat mutez)); - }; - NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/empty_map.tz b/tests_python/contracts_012/opcodes/empty_map.tz deleted file mode 100644 index 9023fe847b3f..000000000000 --- a/tests_python/contracts_012/opcodes/empty_map.tz +++ /dev/null @@ -1,6 +0,0 @@ -storage (map string string); -parameter unit; -code {DROP; - EMPTY_MAP string string; - PUSH string "world"; SOME; PUSH string "hello"; UPDATE; - NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/exec_concat.tz b/tests_python/contracts_012/opcodes/exec_concat.tz deleted file mode 100644 index 0265f1557f0e..000000000000 --- a/tests_python/contracts_012/opcodes/exec_concat.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter string; -storage string; -code {CAR; - LAMBDA string string - {PUSH string "_abc"; NIL string ; - SWAP ; CONS ; SWAP ; CONS ; CONCAT}; - SWAP; EXEC; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/first.tz b/tests_python/contracts_012/opcodes/first.tz deleted file mode 100644 index 6e47b4c008e8..000000000000 --- a/tests_python/contracts_012/opcodes/first.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (list nat); -storage nat; -code{CAR; IF_CONS {DIP{DROP}} {FAIL}; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/get_and_update_big_map.tz b/tests_python/contracts_012/opcodes/get_and_update_big_map.tz deleted file mode 100644 index 3b39c9a6f733..000000000000 --- a/tests_python/contracts_012/opcodes/get_and_update_big_map.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter string; -storage (pair (option nat) (big_map string nat)); -code { - UNPAPAIR; - GET_AND_UPDATE; - PAIR; - NIL operation; - PAIR - } diff --git a/tests_python/contracts_012/opcodes/get_and_update_map.tz b/tests_python/contracts_012/opcodes/get_and_update_map.tz deleted file mode 100644 index b67f08ce7746..000000000000 --- a/tests_python/contracts_012/opcodes/get_and_update_map.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter string; -storage (pair (option nat) (map string nat)); -code { - UNPAPAIR; - GET_AND_UPDATE; - PAIR; - NIL operation; - PAIR - } diff --git a/tests_python/contracts_012/opcodes/get_big_map_value.tz b/tests_python/contracts_012/opcodes/get_big_map_value.tz deleted file mode 100644 index 4ca52343d45a..000000000000 --- a/tests_python/contracts_012/opcodes/get_big_map_value.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter string; -storage (pair (big_map string string) (option string)); -# retrieves the values stored in the big_map on the left side of the -# pair at the key denoted by the parameter and puts it in the right -# hand side of the storage -code {DUP; CAR; DIP{CDAR; DUP}; GET; SWAP; PAIR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/get_map_value.tz b/tests_python/contracts_012/opcodes/get_map_value.tz deleted file mode 100644 index f46639649a34..000000000000 --- a/tests_python/contracts_012/opcodes/get_map_value.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter string; -storage (pair (option string) (map string string)); -code {DUP; CAR; DIP{CDDR; DUP}; GET; PAIR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/hash_consistency_checker.tz b/tests_python/contracts_012/opcodes/hash_consistency_checker.tz deleted file mode 100644 index fb98a39da496..000000000000 --- a/tests_python/contracts_012/opcodes/hash_consistency_checker.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair mutez (pair timestamp int)) ; -storage bytes ; -code { CAR ; PACK ; BLAKE2B ; NIL operation ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/hash_key.tz b/tests_python/contracts_012/opcodes/hash_key.tz deleted file mode 100644 index 6c7f78b4aaf6..000000000000 --- a/tests_python/contracts_012/opcodes/hash_key.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter key; -storage (option key_hash); -code {CAR; HASH_KEY; SOME ;NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/hash_string.tz b/tests_python/contracts_012/opcodes/hash_string.tz deleted file mode 100644 index b0b8ddea6403..000000000000 --- a/tests_python/contracts_012/opcodes/hash_string.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter string; -storage bytes; -code {CAR; PACK ; BLAKE2B; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/if.tz b/tests_python/contracts_012/opcodes/if.tz deleted file mode 100644 index 4bc0e353daeb..000000000000 --- a/tests_python/contracts_012/opcodes/if.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter bool; -storage (option bool); -code {CAR; IF {PUSH bool True} {PUSH bool False}; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/if_some.tz b/tests_python/contracts_012/opcodes/if_some.tz deleted file mode 100644 index 5c3138b2272b..000000000000 --- a/tests_python/contracts_012/opcodes/if_some.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (option string); -storage string; -code { CAR; IF_SOME {} {PUSH string ""}; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/int.tz b/tests_python/contracts_012/opcodes/int.tz deleted file mode 100644 index 3f199881392a..000000000000 --- a/tests_python/contracts_012/opcodes/int.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter nat; -storage (option int); -# this contract takes a natural number as parameter, converts it to an -# integer and stores it. -code { CAR; INT; SOME; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/iter_fail.tz b/tests_python/contracts_012/opcodes/iter_fail.tz deleted file mode 100644 index 4021e8b57efc..000000000000 --- a/tests_python/contracts_012/opcodes/iter_fail.tz +++ /dev/null @@ -1,4 +0,0 @@ -# Test that ITER {FAILWITH} is allowed by the typechecker -parameter (set nat); -storage unit; -code { UNPAIR; ITER {FAILWITH}; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/keccak.tz b/tests_python/contracts_012/opcodes/keccak.tz deleted file mode 100644 index e96256100999..000000000000 --- a/tests_python/contracts_012/opcodes/keccak.tz +++ /dev/null @@ -1,8 +0,0 @@ -storage (option bytes); -parameter bytes; -code - { - CAR; - KECCAK; SOME; - NIL operation; PAIR - } diff --git a/tests_python/contracts_012/opcodes/left_right.tz b/tests_python/contracts_012/opcodes/left_right.tz deleted file mode 100644 index d5650c03422e..000000000000 --- a/tests_python/contracts_012/opcodes/left_right.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (or bool string); -storage (or string bool); -code {CAR; IF_LEFT {RIGHT string} {LEFT bool}; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/level.tz b/tests_python/contracts_012/opcodes/level.tz deleted file mode 100644 index 7e3adb9d05f4..000000000000 --- a/tests_python/contracts_012/opcodes/level.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage nat; -code {DROP; LEVEL; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/list_concat.tz b/tests_python/contracts_012/opcodes/list_concat.tz deleted file mode 100644 index d7bfb7d134ea..000000000000 --- a/tests_python/contracts_012/opcodes/list_concat.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (list string); -storage string; -code { UNPAIR ; SWAP ; CONS ; CONCAT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_concat_bytes.tz b/tests_python/contracts_012/opcodes/list_concat_bytes.tz deleted file mode 100644 index 0fc8e1620669..000000000000 --- a/tests_python/contracts_012/opcodes/list_concat_bytes.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (list bytes); -storage bytes; -code { UNPAIR ; SWAP ; CONS ; CONCAT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_id.tz b/tests_python/contracts_012/opcodes/list_id.tz deleted file mode 100644 index 6cd3693a1e14..000000000000 --- a/tests_python/contracts_012/opcodes/list_id.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (list string); -storage (list string); -code {CAR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_id_map.tz b/tests_python/contracts_012/opcodes/list_id_map.tz deleted file mode 100644 index 38b4493e8e0f..000000000000 --- a/tests_python/contracts_012/opcodes/list_id_map.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (list string); -storage (list string); -code {CAR; MAP {}; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_iter.tz b/tests_python/contracts_012/opcodes/list_iter.tz deleted file mode 100644 index df904d882234..000000000000 --- a/tests_python/contracts_012/opcodes/list_iter.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (list int); -storage int; -code { CAR; PUSH int 1; SWAP; - ITER { MUL }; - NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_map_block.tz b/tests_python/contracts_012/opcodes/list_map_block.tz deleted file mode 100644 index b5202dd9b6fb..000000000000 --- a/tests_python/contracts_012/opcodes/list_map_block.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (list int); -storage (list int); -code { CAR; PUSH int 0; SWAP; - MAP { DIP{DUP}; ADD; DIP{PUSH int 1; ADD}}; - NIL operation; PAIR; DIP{DROP}} diff --git a/tests_python/contracts_012/opcodes/list_size.tz b/tests_python/contracts_012/opcodes/list_size.tz deleted file mode 100644 index 6ced12799187..000000000000 --- a/tests_python/contracts_012/opcodes/list_size.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (list int); -storage nat; -code {CAR; SIZE; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/loop_failwith.tz b/tests_python/contracts_012/opcodes/loop_failwith.tz deleted file mode 100644 index f81a552c8ebc..000000000000 --- a/tests_python/contracts_012/opcodes/loop_failwith.tz +++ /dev/null @@ -1,4 +0,0 @@ -# Test that LOOP {FAILWITH} is allowed by the typechecker -parameter bool; -storage unit; -code { UNPAIR; LOOP {FAILWITH}; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/loop_left.tz b/tests_python/contracts_012/opcodes/loop_left.tz deleted file mode 100644 index 64bcc76c89cc..000000000000 --- a/tests_python/contracts_012/opcodes/loop_left.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter (list string); -storage (list string); -code { CAR; NIL string; SWAP; PAIR; LEFT (list string); - LOOP_LEFT { DUP; CAR; DIP{CDR}; - IF_CONS { SWAP; DIP{CONS}; PAIR; LEFT (list string) } - { RIGHT (pair (list string) (list string)) }; }; - NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/loop_left_failwith.tz b/tests_python/contracts_012/opcodes/loop_left_failwith.tz deleted file mode 100644 index 98971e409511..000000000000 --- a/tests_python/contracts_012/opcodes/loop_left_failwith.tz +++ /dev/null @@ -1,4 +0,0 @@ -# Test that LOOP_LEFT {FAILWITH} is allowed by the typechecker -parameter (or string nat); -storage nat; -code { CAR; LOOP_LEFT {FAILWITH}; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/map_car.tz b/tests_python/contracts_012/opcodes/map_car.tz deleted file mode 100644 index b763590ece2c..000000000000 --- a/tests_python/contracts_012/opcodes/map_car.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter bool; -storage (pair (bool %b) (nat %n)); -code { DUP; CAR; DIP{CDR}; SWAP; - MAP_CAR @new_storage %b { AND }; - NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/map_id.tz b/tests_python/contracts_012/opcodes/map_id.tz deleted file mode 100644 index ff0a3bbbf213..000000000000 --- a/tests_python/contracts_012/opcodes/map_id.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (map nat nat); -storage (map nat nat); -code { CAR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/map_iter.tz b/tests_python/contracts_012/opcodes/map_iter.tz deleted file mode 100644 index 3ab5c35c73b8..000000000000 --- a/tests_python/contracts_012/opcodes/map_iter.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter (map (int :k) (int :e)); -storage (pair (int :k) (int :e)); -code { CAR; PUSH @acc_e (int :e) 0; PUSH @acc_k (int :k) 0; PAIR % %r; SWAP; - ITER - { DIP {DUP; CAR; DIP{CDR}}; DUP; # Last instr - DIP{CAR; ADD}; SWAP; DIP{CDR; ADD}; PAIR % %r }; - NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/map_map.tz b/tests_python/contracts_012/opcodes/map_map.tz deleted file mode 100644 index 4acbd63c32c4..000000000000 --- a/tests_python/contracts_012/opcodes/map_map.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter nat; -storage (map string nat); -# this contract adds the value passed by parameter to each entry in -# the stored map. -code { UNPAIR; SWAP; - MAP { CDR; DIP {DUP}; ADD; }; - DIP { DROP; }; - NIL operation; PAIR; } diff --git a/tests_python/contracts_012/opcodes/map_map_sideeffect.tz b/tests_python/contracts_012/opcodes/map_map_sideeffect.tz deleted file mode 100644 index 960b02a553ce..000000000000 --- a/tests_python/contracts_012/opcodes/map_map_sideeffect.tz +++ /dev/null @@ -1,12 +0,0 @@ -parameter nat; -storage (pair (map string nat) nat); -# this contract adds the value passed by parameter to each entry in -# the stored map, and it sets the second component of the pair to the -# sum of the map's elements -code { UNPAIR; SWAP; CAR; - DIP 2 { PUSH @sum nat 0; }; - MAP { CDR; DIP {DUP}; ADD; - DUP; DUG 2; DIP 2 { ADD @sum }; - }; - DIP { DROP; }; PAIR; - NIL operation; PAIR; } diff --git a/tests_python/contracts_012/opcodes/map_mem_nat.tz b/tests_python/contracts_012/opcodes/map_mem_nat.tz deleted file mode 100644 index 0c245d7e0a65..000000000000 --- a/tests_python/contracts_012/opcodes/map_mem_nat.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter nat; -storage (pair (map nat nat) (option bool)) ; -# stores (map, Some flag) where flag = parameter is a member of -# the map in first component of storage -code { UNPAIR; - DIP { CAR; DUP }; - MEM; SOME; SWAP; PAIR; NIL operation; PAIR;} diff --git a/tests_python/contracts_012/opcodes/map_mem_string.tz b/tests_python/contracts_012/opcodes/map_mem_string.tz deleted file mode 100644 index 3fa5cd5b579f..000000000000 --- a/tests_python/contracts_012/opcodes/map_mem_string.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter string; -storage (pair (map string nat) (option bool)) ; -# stores (map, Some flag) where flag = parameter is a member of -# the map in first component of storage -code { UNPAIR; - DIP { CAR; DUP }; - MEM; SOME; SWAP; PAIR; NIL operation; PAIR;} diff --git a/tests_python/contracts_012/opcodes/map_size.tz b/tests_python/contracts_012/opcodes/map_size.tz deleted file mode 100644 index 4bd6417e6d79..000000000000 --- a/tests_python/contracts_012/opcodes/map_size.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (map string nat); -storage nat; -code {CAR; SIZE; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/merge_comparable_pairs.tz b/tests_python/contracts_012/opcodes/merge_comparable_pairs.tz deleted file mode 100644 index 14fcc73411c7..000000000000 --- a/tests_python/contracts_012/opcodes/merge_comparable_pairs.tz +++ /dev/null @@ -1,14 +0,0 @@ -# tests that merging comparable pair types works -parameter (set (pair (nat %n) (pair %p (string %s) (int %i)))); -storage nat; -code {UNPAIR; - SWAP; - PUSH nat 3; - COMPARE; - GT; - IF {} - {DROP; - EMPTY_SET (pair nat (pair string int));}; - SIZE; - NIL operation; - PAIR;} diff --git a/tests_python/contracts_012/opcodes/mul.tz b/tests_python/contracts_012/opcodes/mul.tz deleted file mode 100644 index 8432394b526d..000000000000 --- a/tests_python/contracts_012/opcodes/mul.tz +++ /dev/null @@ -1,48 +0,0 @@ -parameter unit ; -storage unit ; -code { CAR ; - DROP ; - # tez-nat, no overflow - PUSH nat 7987 ; - PUSH mutez 10 ; - MUL ; - PUSH mutez 79870 ; - COMPARE ; - ASSERT_EQ ; - # nat-tez, no overflow - PUSH mutez 10 ; - PUSH nat 7987 ; - MUL ; - PUSH mutez 79870 ; - COMPARE ; - ASSERT_EQ ; - # int-int, no overflow - PUSH int 10 ; - PUSH int -7987 ; - MUL ; - PUSH int -79870 ; - COMPARE ; - ASSERT_EQ ; - # int-nat, no overflow - PUSH nat 10 ; - PUSH int -7987 ; - MUL ; - PUSH int -79870 ; - COMPARE ; - ASSERT_EQ ; - # nat-int, no overflow - PUSH int -10 ; - PUSH nat 7987 ; - MUL ; - PUSH int -79870 ; - COMPARE ; - ASSERT_EQ ; - # nat-nat, no overflow - PUSH nat 10 ; - PUSH nat 7987 ; - MUL ; - PUSH nat 79870 ; - COMPARE ; - ASSERT_EQ ; - - UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/mul_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/mul_bls12_381_fr.tz deleted file mode 100644 index dd201863b034..000000000000 --- a/tests_python/contracts_012/opcodes/mul_bls12_381_fr.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair bls12_381_fr bls12_381_fr); -storage (option (bls12_381_fr)); -code {CAR; UNPAIR; MUL; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/mul_bls12_381_g1.tz b/tests_python/contracts_012/opcodes/mul_bls12_381_g1.tz deleted file mode 100644 index af3f376501da..000000000000 --- a/tests_python/contracts_012/opcodes/mul_bls12_381_g1.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair bls12_381_g1 bls12_381_fr); -storage (option (bls12_381_g1)); -code {CAR; UNPAIR; MUL; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/mul_bls12_381_g2.tz b/tests_python/contracts_012/opcodes/mul_bls12_381_g2.tz deleted file mode 100644 index 1875e8e3dac8..000000000000 --- a/tests_python/contracts_012/opcodes/mul_bls12_381_g2.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair bls12_381_g2 bls12_381_fr); -storage (option (bls12_381_g2)); -code {CAR; UNPAIR; MUL; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/mul_overflow.tz b/tests_python/contracts_012/opcodes/mul_overflow.tz deleted file mode 100644 index 5d2b3a3dcff2..000000000000 --- a/tests_python/contracts_012/opcodes/mul_overflow.tz +++ /dev/null @@ -1,18 +0,0 @@ -parameter (or unit unit) ; -storage unit ; -code { CAR ; - IF_LEFT - { - PUSH nat 922337203685477580700 ; - PUSH mutez 10 ; - MUL ; # FAILURE - DROP - } - { - PUSH mutez 10 ; - PUSH nat 922337203685477580700 ; - MUL ; # FAILURE - DROP - } ; - - NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/munch.tz b/tests_python/contracts_012/opcodes/munch.tz deleted file mode 100644 index 7efe43ca092d..000000000000 --- a/tests_python/contracts_012/opcodes/munch.tz +++ /dev/null @@ -1,14 +0,0 @@ -# A contract that accepts bytes in a default entry point and does nothing. -# Useful for testing transfers of arbitrary sizes. -parameter (or (bytes %bytes) - (or (lambda %lambda unit unit) - (or (nat %nat) - (list %list_nat nat)))); -storage unit; -code - { - CDR; # @storage - # == default == # @storage - NIL operation; # list operation : @storage - PAIR; # pair (list operation) @storage - }; diff --git a/tests_python/contracts_012/opcodes/mutez_to_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/mutez_to_bls12_381_fr.tz deleted file mode 100644 index fefc038474da..000000000000 --- a/tests_python/contracts_012/opcodes/mutez_to_bls12_381_fr.tz +++ /dev/null @@ -1,14 +0,0 @@ -parameter mutez; -storage bls12_381_fr; -code { - CAR; - PUSH mutez 1; - SWAP; - EDIV; - ASSERT_SOME; - CAR; - PUSH bls12_381_fr 1; - MUL; - NIL operation; - PAIR; - }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/neg.tz b/tests_python/contracts_012/opcodes/neg.tz deleted file mode 100644 index 9cedf765f1b2..000000000000 --- a/tests_python/contracts_012/opcodes/neg.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter (or int nat); -storage int; -code { - CAR; - IF_LEFT {NEG} {NEG}; - NIL operation; - PAIR - } diff --git a/tests_python/contracts_012/opcodes/neg_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/neg_bls12_381_fr.tz deleted file mode 100644 index cd9b0a945cc5..000000000000 --- a/tests_python/contracts_012/opcodes/neg_bls12_381_fr.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter bls12_381_fr; -storage (option (bls12_381_fr)); -code {CAR; NEG; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/neg_bls12_381_g1.tz b/tests_python/contracts_012/opcodes/neg_bls12_381_g1.tz deleted file mode 100644 index 60806deada20..000000000000 --- a/tests_python/contracts_012/opcodes/neg_bls12_381_g1.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter bls12_381_g1; -storage (option (bls12_381_g1)); -code {CAR; NEG; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/neg_bls12_381_g2.tz b/tests_python/contracts_012/opcodes/neg_bls12_381_g2.tz deleted file mode 100644 index 593052546258..000000000000 --- a/tests_python/contracts_012/opcodes/neg_bls12_381_g2.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter bls12_381_g2; -storage (option (bls12_381_g2)); -code {CAR; NEG; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/none.tz b/tests_python/contracts_012/opcodes/none.tz deleted file mode 100644 index 473a288b4926..000000000000 --- a/tests_python/contracts_012/opcodes/none.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage (option nat); -code { DROP; NONE nat; NIL operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/noop.tz b/tests_python/contracts_012/opcodes/noop.tz deleted file mode 100644 index bd19da15cf49..000000000000 --- a/tests_python/contracts_012/opcodes/noop.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage unit; -code {CDR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/not.tz b/tests_python/contracts_012/opcodes/not.tz deleted file mode 100644 index f89394072d2a..000000000000 --- a/tests_python/contracts_012/opcodes/not.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter bool; -storage (option bool); -code {CAR; NOT; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/not_binary.tz b/tests_python/contracts_012/opcodes/not_binary.tz deleted file mode 100644 index c1e0f97979d7..000000000000 --- a/tests_python/contracts_012/opcodes/not_binary.tz +++ /dev/null @@ -1,12 +0,0 @@ -parameter (or int nat); -storage (option int); -code { CAR; - IF_LEFT - { - NOT; - } - { - NOT; - } ; - SOME; NIL operation ; PAIR - } diff --git a/tests_python/contracts_012/opcodes/or.tz b/tests_python/contracts_012/opcodes/or.tz deleted file mode 100644 index 89d533c4483e..000000000000 --- a/tests_python/contracts_012/opcodes/or.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair bool bool); -storage (option bool); -code {CAR; DUP; CAR; SWAP; CDR; OR; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/or_binary.tz b/tests_python/contracts_012/opcodes/or_binary.tz deleted file mode 100644 index a31f109827ef..000000000000 --- a/tests_python/contracts_012/opcodes/or_binary.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (pair nat nat); -storage (option nat); -# This contract takes a pair of natural numbers as argument and -# stores the result of their binary OR. -code { CAR; - UNPAIR; - OR; - SOME; NIL operation; PAIR - } diff --git a/tests_python/contracts_012/opcodes/originate_big_map.tz b/tests_python/contracts_012/opcodes/originate_big_map.tz deleted file mode 100644 index 97d7db669fe8..000000000000 --- a/tests_python/contracts_012/opcodes/originate_big_map.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (big_map int int); -storage (big_map int int); -code { CAR; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/packunpack.tz b/tests_python/contracts_012/opcodes/packunpack.tz deleted file mode 100644 index ad313fa8aee6..000000000000 --- a/tests_python/contracts_012/opcodes/packunpack.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter (pair (pair (pair string (list int)) (set nat)) bytes) ; -storage unit ; -code { CAR ; UNPAIR ; DIP { DUP } ; - PACK ; ASSERT_CMPEQ ; - UNPACK (pair (pair string (list int)) (set nat)) ; ASSERT_SOME ; DROP ; - UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/packunpack_rev.tz b/tests_python/contracts_012/opcodes/packunpack_rev.tz deleted file mode 100644 index 9c94cd68dcc1..000000000000 --- a/tests_python/contracts_012/opcodes/packunpack_rev.tz +++ /dev/null @@ -1,43 +0,0 @@ -parameter (pair - int - nat - string - bytes - mutez - bool - key_hash - timestamp address); -storage unit ; -code { CAR; - # Check the int - DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK int; ASSERT_SOME; ASSERT_CMPEQ; - # Check the nat - DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK nat; ASSERT_SOME; ASSERT_CMPEQ; - # Check the string - DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK string; ASSERT_SOME; ASSERT_CMPEQ; - # Check the bytes - DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK bytes; ASSERT_SOME; ASSERT_CMPEQ; - # Check the mutez - DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK mutez; ASSERT_SOME; ASSERT_CMPEQ; - # Check the bool - DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK bool; ASSERT_SOME; ASSERT_CMPEQ; - # Check the key_hash - DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK key_hash; ASSERT_SOME; ASSERT_CMPEQ; - # Check the timestamp - DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK timestamp; ASSERT_SOME; ASSERT_CMPEQ; - # Check the address - DUP; PACK; UNPACK address; ASSERT_SOME; ASSERT_CMPEQ; - - # Assert failure modes of unpack - PUSH int 0; PACK; UNPACK nat; ASSERT_SOME; DROP; - PUSH int -1; PACK; UNPACK nat; ASSERT_NONE; - - # Try deserializing invalid byte sequence (no magic number) - PUSH bytes 0x; UNPACK nat; ASSERT_NONE; - PUSH bytes 0x04; UNPACK nat; ASSERT_NONE; - - # Assert failure for byte sequences that do not correspond to - # any micheline value - PUSH bytes 0x05; UNPACK nat; ASSERT_NONE; - - UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/packunpack_rev_cty.tz b/tests_python/contracts_012/opcodes/packunpack_rev_cty.tz deleted file mode 100644 index 7ca7ca64a3c3..000000000000 --- a/tests_python/contracts_012/opcodes/packunpack_rev_cty.tz +++ /dev/null @@ -1,31 +0,0 @@ -parameter (pair key unit signature (option signature) (list unit) (set bool) (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes)); -storage unit ; -# for each uncomparable type t (we take an arbitrary parameter for -# parametric data-types e.g. pair, list), -# that is packable (which excludes big_map, operation, and contract) -# this contract receives a parameter v_t. -# it verifies that pack v_t == pack (unpack (pack v_t)) -code { CAR; - # packable uncomparable types - # checking: key - DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK key; ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - # checking: unit - DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK unit; ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - # checking: signature - DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (signature); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - # checking: option signature - DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (option signature); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - # checking: list unit - DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (list unit); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - # checking: set bool - DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (set bool); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - # checking: pair int int - DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (pair int int); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - # checking: or key_hash timestamp - DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (or key_hash timestamp); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - # checking: map int string - DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (map int string); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - # checking: lambda string bytes - DUP; PACK; DIP { PACK; UNPACK (lambda string bytes); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; - - UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/pair_id.tz b/tests_python/contracts_012/opcodes/pair_id.tz deleted file mode 100644 index 3bfedf2d8cdf..000000000000 --- a/tests_python/contracts_012/opcodes/pair_id.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair bool bool); -storage (option (pair bool bool)); -code {CAR; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/pairing_check.tz b/tests_python/contracts_012/opcodes/pairing_check.tz deleted file mode 100644 index 3b829f315c05..000000000000 --- a/tests_python/contracts_012/opcodes/pairing_check.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (list (pair bls12_381_g1 bls12_381_g2)); -storage (option bool); -code {CAR; PAIRING_CHECK; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/pexec.tz b/tests_python/contracts_012/opcodes/pexec.tz deleted file mode 100644 index eab0c71b4f59..000000000000 --- a/tests_python/contracts_012/opcodes/pexec.tz +++ /dev/null @@ -1,6 +0,0 @@ -parameter nat; -storage nat; -code { - LAMBDA (pair nat nat) nat - {UNPAIR ; ADD}; - SWAP; UNPAIR ; DIP { APPLY } ; EXEC ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/pexec_2.tz b/tests_python/contracts_012/opcodes/pexec_2.tz deleted file mode 100644 index d64f7442f50e..000000000000 --- a/tests_python/contracts_012/opcodes/pexec_2.tz +++ /dev/null @@ -1,11 +0,0 @@ -parameter int; -storage (list int); -code { - UNPAIR @p @s ; # p :: s - LAMBDA (pair int (pair int int)) int - { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL }; # l :: p :: s - SWAP ; APPLY ; # l :: s - PUSH int 3 ; APPLY ; # l :: s - SWAP ; MAP { DIP { DUP } ; EXEC } ; # s :: l - DIP { DROP } ; # s - NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/proxy.tz b/tests_python/contracts_012/opcodes/proxy.tz deleted file mode 100644 index 185bbcd321cc..000000000000 --- a/tests_python/contracts_012/opcodes/proxy.tz +++ /dev/null @@ -1,13 +0,0 @@ -/* This proxy contract transfers the received amount to the contract given as parameter. - It is used to test the SOURCE and SENDER opcodes; see source.tz and sender.tz. */ -parameter (contract unit) ; -storage unit ; -code{ - UNPAIR; - AMOUNT ; - UNIT ; - TRANSFER_TOKENS; - DIP {NIL operation} ; - CONS; - PAIR - } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/ret_int.tz b/tests_python/contracts_012/opcodes/ret_int.tz deleted file mode 100644 index 720a99568e96..000000000000 --- a/tests_python/contracts_012/opcodes/ret_int.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage (option nat); -code {DROP; PUSH nat 300; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/reverse.tz b/tests_python/contracts_012/opcodes/reverse.tz deleted file mode 100644 index 5a851f3e29d0..000000000000 --- a/tests_python/contracts_012/opcodes/reverse.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (list string); -storage (list string); -code { CAR; NIL string; SWAP; - ITER {CONS}; - NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/reverse_loop.tz b/tests_python/contracts_012/opcodes/reverse_loop.tz deleted file mode 100644 index d8117135c984..000000000000 --- a/tests_python/contracts_012/opcodes/reverse_loop.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (list string); -storage (list string); -code { CAR; NIL string; SWAP; PUSH bool True; - LOOP { IF_CONS {SWAP; DIP{CONS}; PUSH bool True} {NIL string; PUSH bool False}}; - DROP; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/sapling_empty_state.tz b/tests_python/contracts_012/opcodes/sapling_empty_state.tz deleted file mode 100644 index 6a568da92dd3..000000000000 --- a/tests_python/contracts_012/opcodes/sapling_empty_state.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage (sapling_state 8); -code { DROP; SAPLING_EMPTY_STATE 8; NIL operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/self.tz b/tests_python/contracts_012/opcodes/self.tz deleted file mode 100644 index d96457fd1331..000000000000 --- a/tests_python/contracts_012/opcodes/self.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit ; -storage address ; -code { DROP ; SELF ; ADDRESS ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/self_address.tz b/tests_python/contracts_012/opcodes/self_address.tz deleted file mode 100644 index 73f4779bab24..000000000000 --- a/tests_python/contracts_012/opcodes/self_address.tz +++ /dev/null @@ -1,11 +0,0 @@ -parameter unit; -storage unit; -code { - DROP; - LAMBDA unit address { DROP; SELF_ADDRESS }; - UNIT; - EXEC; - SELF; ADDRESS; - ASSERT_CMPEQ; - UNIT; NIL operation; PAIR - } diff --git a/tests_python/contracts_012/opcodes/self_address_after_fib_view.tz b/tests_python/contracts_012/opcodes/self_address_after_fib_view.tz deleted file mode 100644 index 0cf80651050a..000000000000 --- a/tests_python/contracts_012/opcodes/self_address_after_fib_view.tz +++ /dev/null @@ -1,25 +0,0 @@ -# This contract calls the view `fib` on the address passed as -# parameter. After returning from the view it stores its -# SELF_ADDRESS. -parameter address ; -storage address ; -code - { CAR ; - DUP ; - PUSH nat 3 ; - VIEW "fib" nat; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 1500 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - SELF_ADDRESS ; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - diff --git a/tests_python/contracts_012/opcodes/self_address_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/self_address_after_nonexistent_view.tz deleted file mode 100644 index 6b174437425c..000000000000 --- a/tests_python/contracts_012/opcodes/self_address_after_nonexistent_view.tz +++ /dev/null @@ -1,26 +0,0 @@ -# This contract calls the non-existent view on the address passed as -# parameter. After returning from the view it stores it's -# SELF_ADDRESS. -parameter address ; -storage address ; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "id" string ; - ASSERT_NONE ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 1500 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - SELF_ADDRESS ; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - - - diff --git a/tests_python/contracts_012/opcodes/self_address_after_view.tz b/tests_python/contracts_012/opcodes/self_address_after_view.tz deleted file mode 100644 index 012c3ce15171..000000000000 --- a/tests_python/contracts_012/opcodes/self_address_after_view.tz +++ /dev/null @@ -1,24 +0,0 @@ -# This contract calls the view `id` on the address passed as -# parameter. After returning from the view it stores its -# SELF_ADDRESS. -parameter address ; -storage address ; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "id" (pair nat nat) ; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 1500 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - SELF_ADDRESS ; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; diff --git a/tests_python/contracts_012/opcodes/self_after_fib_view.tz b/tests_python/contracts_012/opcodes/self_after_fib_view.tz deleted file mode 100644 index 5bacaeb17673..000000000000 --- a/tests_python/contracts_012/opcodes/self_after_fib_view.tz +++ /dev/null @@ -1,27 +0,0 @@ -# This contract calls the view `fib` on the address passed as -# parameter. After returning from the view it stores its -# address from SELF. -parameter address ; -storage address ; -code - { CAR ; - DUP ; - PUSH nat 3 ; - VIEW "fib" nat; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 1500 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - SELF ; - ADDRESS ; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - - diff --git a/tests_python/contracts_012/opcodes/self_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/self_after_nonexistent_view.tz deleted file mode 100644 index 74236b85f7f4..000000000000 --- a/tests_python/contracts_012/opcodes/self_after_nonexistent_view.tz +++ /dev/null @@ -1,28 +0,0 @@ -# This contract calls the non-existent view on the address passed as -# parameter. After returning from the view it stores its -# address from SELF. -parameter address ; -storage address ; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "nonexistent" string ; - ASSERT_NONE ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 1500 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - SELF ; - ADDRESS ; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - - - - diff --git a/tests_python/contracts_012/opcodes/self_after_view.tz b/tests_python/contracts_012/opcodes/self_after_view.tz deleted file mode 100644 index 1dab8f98115d..000000000000 --- a/tests_python/contracts_012/opcodes/self_after_view.tz +++ /dev/null @@ -1,26 +0,0 @@ -# This contract calls the view `id` on the address passed as -# parameter. After returning from the view it stores its -# address from SELF. -parameter address ; -storage address ; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "id" (pair nat nat) ; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 1500 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - SELF ; - ADDRESS ; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - diff --git a/tests_python/contracts_012/opcodes/self_with_default_entrypoint.tz b/tests_python/contracts_012/opcodes/self_with_default_entrypoint.tz deleted file mode 100644 index 47f848c0d5a1..000000000000 --- a/tests_python/contracts_012/opcodes/self_with_default_entrypoint.tz +++ /dev/null @@ -1,19 +0,0 @@ -parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %default) (string %C))); -storage unit; -code { - DROP; - SELF; DROP; - # Refers to entrypoint A of the current contract. - SELF %A; DROP; - # Refers to the default entry of the current contract - SELF %default; PACK; - # "SELF" w/o annotation also refers to the default - # entry of the current contract. Internally, they are equal. - SELF; PACK; ASSERT_CMPEQ; - # The following instruction would not typecheck: - # SELF %D, - # since there is no entrypoint D. - UNIT; - NIL operation; - PAIR; - } diff --git a/tests_python/contracts_012/opcodes/self_with_entrypoint.tz b/tests_python/contracts_012/opcodes/self_with_entrypoint.tz deleted file mode 100644 index ea6f8e1898e2..000000000000 --- a/tests_python/contracts_012/opcodes/self_with_entrypoint.tz +++ /dev/null @@ -1,26 +0,0 @@ -parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))); -storage unit; -code { - DROP; - # Refers to entrypoint A of the current contract. - SELF %A; PACK @Apacked; - # Refers to the default entry of the current contract - SELF %default; PACK @defpacked; DUP; DIP { SWAP }; ASSERT_CMPNEQ; - # "SELF" w/o annotation also refers to the default - # entry of the current contract - SELF; PACK @selfpacked; ASSERT_CMPEQ; - - # Verify the types of the different entrypoints. CAST is noop - # if its argument is convertible with the type of the top of - # the stack. - SELF %A; CAST (contract nat); DROP; - SELF %B; CAST (contract bool); DROP; - SELF %maybe_C; CAST (contract (or (unit) (string))); DROP; - SELF %Z; CAST (contract unit); DROP; - SELF; CAST (contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))); DROP; - SELF %default; CAST (contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))); DROP; - - UNIT; - NIL operation; - PAIR; - } diff --git a/tests_python/contracts_012/opcodes/sender.tz b/tests_python/contracts_012/opcodes/sender.tz deleted file mode 100644 index fb174179aca5..000000000000 --- a/tests_python/contracts_012/opcodes/sender.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter unit ; -storage address ; -code{ - DROP ; - SENDER; - NIL operation ; - PAIR - } diff --git a/tests_python/contracts_012/opcodes/sender_after_fib_view.tz b/tests_python/contracts_012/opcodes/sender_after_fib_view.tz deleted file mode 100644 index 902e1bc8885e..000000000000 --- a/tests_python/contracts_012/opcodes/sender_after_fib_view.tz +++ /dev/null @@ -1,26 +0,0 @@ -# This contract calls the view `fib` on the address passed as -# parameter. After returning from the view it stores its -# SENDER. -parameter address ; -storage address ; -code - { CAR ; - DUP ; - PUSH nat 3 ; - VIEW "fib" nat; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 1500 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - SENDER; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - - diff --git a/tests_python/contracts_012/opcodes/sender_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/sender_after_nonexistent_view.tz deleted file mode 100644 index 9744af68417f..000000000000 --- a/tests_python/contracts_012/opcodes/sender_after_nonexistent_view.tz +++ /dev/null @@ -1,25 +0,0 @@ -# This contract calls the non-existent view on the address passed as -# parameter. After returning from the view it stores it's -# SENDER. -parameter address ; -storage address ; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "id" string ; - ASSERT_NONE ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 1500 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - SENDER; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - - diff --git a/tests_python/contracts_012/opcodes/sender_after_view.tz b/tests_python/contracts_012/opcodes/sender_after_view.tz deleted file mode 100644 index b266defa5f3b..000000000000 --- a/tests_python/contracts_012/opcodes/sender_after_view.tz +++ /dev/null @@ -1,25 +0,0 @@ -# This contract calls the view `id` on the address passed as -# parameter. After returning from the view it stores its -# SENDER. -parameter address ; -storage address ; -code - { CAR ; - DUP ; - PUSH nat 0 ; - VIEW "id" (pair nat nat) ; - ASSERT_SOME ; - DROP ; - CONTRACT nat ; - ASSERT_SOME ; - PUSH mutez 1500 ; - PUSH nat 0 ; - TRANSFER_TOKENS ; - SENDER; - SWAP ; - NIL operation ; - SWAP ; - CONS ; - PAIR - } ; - diff --git a/tests_python/contracts_012/opcodes/set_car.tz b/tests_python/contracts_012/opcodes/set_car.tz deleted file mode 100644 index 460b33856743..000000000000 --- a/tests_python/contracts_012/opcodes/set_car.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter string; -storage (pair (string %s) (nat %n)); -code { DUP; CDR; DIP{CAR}; SET_CAR %s; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/set_cdr.tz b/tests_python/contracts_012/opcodes/set_cdr.tz deleted file mode 100644 index d725756bbcaa..000000000000 --- a/tests_python/contracts_012/opcodes/set_cdr.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter nat; -storage (pair (string %s) (nat %n)); -code { DUP; CDR; DIP{CAR}; SET_CDR %n; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/set_delegate.tz b/tests_python/contracts_012/opcodes/set_delegate.tz deleted file mode 100644 index a7e051e50494..000000000000 --- a/tests_python/contracts_012/opcodes/set_delegate.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (option key_hash); -storage unit; -code { - UNPAIR; - SET_DELEGATE; - DIP {NIL operation}; - CONS; - PAIR - } diff --git a/tests_python/contracts_012/opcodes/set_id.tz b/tests_python/contracts_012/opcodes/set_id.tz deleted file mode 100644 index ede301b0e979..000000000000 --- a/tests_python/contracts_012/opcodes/set_id.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (set string); -storage (set string); -code { CAR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/set_iter.tz b/tests_python/contracts_012/opcodes/set_iter.tz deleted file mode 100644 index 55d8ae34aba7..000000000000 --- a/tests_python/contracts_012/opcodes/set_iter.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (set int); -storage int; -code { CAR; PUSH int 0; SWAP; ITER { ADD }; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/set_member.tz b/tests_python/contracts_012/opcodes/set_member.tz deleted file mode 100644 index ae97cce14345..000000000000 --- a/tests_python/contracts_012/opcodes/set_member.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter string; -storage (pair (set string) (option bool)); -code {DUP; DUP; CAR; DIP{CDAR}; MEM; SOME; DIP {CDAR}; SWAP; PAIR ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/set_size.tz b/tests_python/contracts_012/opcodes/set_size.tz deleted file mode 100644 index aa055cb02192..000000000000 --- a/tests_python/contracts_012/opcodes/set_size.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (set int); -storage nat; -code {CAR; SIZE; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/sets.tz b/tests_python/contracts_012/opcodes/sets.tz deleted file mode 100644 index 42873aca228c..000000000000 --- a/tests_python/contracts_012/opcodes/sets.tz +++ /dev/null @@ -1,40 +0,0 @@ -parameter unit; -storage unit; -code - { - DROP; - - # Numerical types - PUSH (set nat) {0; 1; 3}; DROP; - PUSH (set int) {-1 ; 0; 3}; DROP; - PUSH (set mutez) {1; 4; 5; 10; 1923}; DROP; - PUSH - (set timestamp) - {-1; 0; "2017-09-16T08:38:04Z"; "2019-09-16T08:38:05Z"}; - DROP; - - # Booleans - PUSH (set bool) {}; DROP; - PUSH (set bool) {True}; DROP; - PUSH (set bool) {False}; DROP; - PUSH (set bool) {False; True}; DROP; - - # Strings and bytes - PUSH (set string) {""; "A"; "B"; "a"; "aa"; "b"}; DROP; - PUSH (set bytes) {0x; 0x01; 0x02; 0xAABBCC}; DROP; - - # Addresses - PUSH - (set key_hash) - { "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; - "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" }; - DROP; - PUSH - (set address) - { "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; - "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv"; - "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9"}; - DROP; - - UNIT; NIL operation; PAIR; - } diff --git a/tests_python/contracts_012/opcodes/sha3.tz b/tests_python/contracts_012/opcodes/sha3.tz deleted file mode 100644 index 3ce8cde000e3..000000000000 --- a/tests_python/contracts_012/opcodes/sha3.tz +++ /dev/null @@ -1,8 +0,0 @@ -storage (option bytes); -parameter bytes; -code - { - CAR; - SHA3; SOME; - NIL operation; PAIR - } diff --git a/tests_python/contracts_012/opcodes/shifts.tz b/tests_python/contracts_012/opcodes/shifts.tz deleted file mode 100644 index 71964750c0b8..000000000000 --- a/tests_python/contracts_012/opcodes/shifts.tz +++ /dev/null @@ -1,18 +0,0 @@ -parameter (or (pair nat nat) (pair nat nat)); -storage (option nat); -# this contract takes either (Left a b) and stores (a << b) -# or (Right a b) and stores (a >> b). -# i.e., in the first case, the first component shifted to the left by -# the second, and the second case, component shifted to the right by -# the second. -code { CAR; - IF_LEFT { - UNPAIR; LSL; - } - { - UNPAIR; LSR; - }; - SOME; - NIL operation; - PAIR; - }; diff --git a/tests_python/contracts_012/opcodes/slice.tz b/tests_python/contracts_012/opcodes/slice.tz deleted file mode 100644 index 3461bb5533d1..000000000000 --- a/tests_python/contracts_012/opcodes/slice.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (pair nat nat); -storage (option string); -code { UNPAIR; SWAP; - IF_SOME {SWAP; UNPAIR; SLICE;} {DROP; NONE string;}; - NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/slice_bytes.tz b/tests_python/contracts_012/opcodes/slice_bytes.tz deleted file mode 100644 index c0f60f358765..000000000000 --- a/tests_python/contracts_012/opcodes/slice_bytes.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (pair nat nat); -storage (option bytes); -code { UNPAIR; SWAP; - IF_SOME {SWAP; UNPAIR; SLICE;} {DROP; NONE bytes;}; - NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/slices.tz b/tests_python/contracts_012/opcodes/slices.tz deleted file mode 100644 index fa76827261c0..000000000000 --- a/tests_python/contracts_012/opcodes/slices.tz +++ /dev/null @@ -1,11 +0,0 @@ -parameter (pair bytes signature) ; -storage key ; -code { DUP ; - CAAR ; DUP ; SIZE ; PUSH nat 128 ; SWAP ; SUB ; ISNAT ; IF_SOME {} { FAIL } ; - PUSH nat 128 ; SLICE @payload ; ASSERT_SOME ; - DUP ; DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; SHA256 ; ASSERT_CMPEQ } ; - DUP ; DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; BLAKE2B ; ASSERT_CMPEQ } ; - DUP ; DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; SHA512 ; ASSERT_CMPEQ } ; - DIP { DUP ; CDR ; DIP { DUP ; CADR }} ; SWAP ; DIP { SWAP } ; CHECK_SIGNATURE ; ASSERT ; - CDR ; DUP ; HASH_KEY ; IMPLICIT_ACCOUNT ; BALANCE ; UNIT ; TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/source.tz b/tests_python/contracts_012/opcodes/source.tz deleted file mode 100644 index fc3c642027d3..000000000000 --- a/tests_python/contracts_012/opcodes/source.tz +++ /dev/null @@ -1,10 +0,0 @@ -parameter unit ; - -storage address ; - -code{ - DROP ; - SOURCE; - NIL operation ; - PAIR - } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/split_bytes.tz b/tests_python/contracts_012/opcodes/split_bytes.tz deleted file mode 100644 index f3b623b3c4b3..000000000000 --- a/tests_python/contracts_012/opcodes/split_bytes.tz +++ /dev/null @@ -1,16 +0,0 @@ -parameter bytes ; -storage (list bytes) ; -code { UNPAIR ; - DIP { NIL bytes ; SWAP ; ITER { CONS } } ; - DUP ; SIZE ; PUSH nat 0 ; CMPNEQ ; - DIP { PUSH @index nat 0 } ; - LOOP - { PAIR ; DUP ; - DIP { UNPAIR ; DIP { PUSH nat 1 } ; SLICE ; ASSERT_SOME ; CONS @storage } ; - UNPAIR ; - PUSH nat 1 ; ADD @index ; - DUP ; DIP { DIP { DUP } ; SWAP ; SIZE ; CMPNEQ } ; SWAP ; - } ; - DROP ; DROP ; - NIL bytes ; SWAP ; ITER { CONS } ; - NIL operation ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/split_string.tz b/tests_python/contracts_012/opcodes/split_string.tz deleted file mode 100644 index 909ba604742d..000000000000 --- a/tests_python/contracts_012/opcodes/split_string.tz +++ /dev/null @@ -1,16 +0,0 @@ -parameter string ; -storage (list string) ; -code { UNPAIR ; - DIP { NIL string ; SWAP ; ITER { CONS } } ; - DUP ; SIZE ; PUSH nat 0 ; CMPNEQ ; - DIP { PUSH @index nat 0 } ; - LOOP - { PAIR ; DUP ; - DIP { UNPAIR ; DIP { PUSH nat 1 } ; SLICE ; ASSERT_SOME ; CONS @storage } ; - UNPAIR ; - PUSH nat 1 ; ADD @index ; - DUP ; DIP { DIP { DUP } ; SWAP ; SIZE ; CMPNEQ } ; SWAP ; - } ; - DROP ; DROP ; - NIL string ; SWAP ; ITER { CONS } ; - NIL operation ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/store_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/store_bls12_381_fr.tz deleted file mode 100644 index b40aa9b4ad1c..000000000000 --- a/tests_python/contracts_012/opcodes/store_bls12_381_fr.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter bls12_381_fr; -storage (option (bls12_381_fr)); -code {CAR; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/store_bls12_381_g1.tz b/tests_python/contracts_012/opcodes/store_bls12_381_g1.tz deleted file mode 100644 index 1bc148f54282..000000000000 --- a/tests_python/contracts_012/opcodes/store_bls12_381_g1.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter bls12_381_g1; -storage (option (bls12_381_g1)); -code {CAR; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/store_bls12_381_g2.tz b/tests_python/contracts_012/opcodes/store_bls12_381_g2.tz deleted file mode 100644 index b64087706265..000000000000 --- a/tests_python/contracts_012/opcodes/store_bls12_381_g2.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter bls12_381_g2; -storage (option (bls12_381_g2)); -code {CAR; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/store_input.tz b/tests_python/contracts_012/opcodes/store_input.tz deleted file mode 100644 index 4eee565ca2e9..000000000000 --- a/tests_python/contracts_012/opcodes/store_input.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter string; -storage string; -code {CAR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/store_now.tz b/tests_python/contracts_012/opcodes/store_now.tz deleted file mode 100644 index 1a868ac06f14..000000000000 --- a/tests_python/contracts_012/opcodes/store_now.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage timestamp; -code {DROP; NOW; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/str_id.tz b/tests_python/contracts_012/opcodes/str_id.tz deleted file mode 100644 index f9e0710c328f..000000000000 --- a/tests_python/contracts_012/opcodes/str_id.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter string; -storage (option string); -code { CAR ; SOME ; NIL operation ; PAIR }; diff --git a/tests_python/contracts_012/opcodes/sub_timestamp_delta.tz b/tests_python/contracts_012/opcodes/sub_timestamp_delta.tz deleted file mode 100644 index f154e952414f..000000000000 --- a/tests_python/contracts_012/opcodes/sub_timestamp_delta.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair timestamp int); -storage timestamp; -code { CAR; DUP; CAR; DIP{CDR}; SUB; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/subset.tz b/tests_python/contracts_012/opcodes/subset.tz deleted file mode 100644 index a16ef1695cb2..000000000000 --- a/tests_python/contracts_012/opcodes/subset.tz +++ /dev/null @@ -1,12 +0,0 @@ -parameter (pair (set string) (set string)); -storage bool; -code { CAR; DUP; CDR; DIP{CAR}; # Unpack lists - PUSH bool True; - PAIR; SWAP; # Setup accumulator - ITER { DIP{ DUP; DUP; CDR; - DIP{CAR; DIP{CDR}}}; - MEM; # Check membership - AND; # Combine accumulator and input - PAIR}; - CAR; # Get the accumulator value - NIL operation; PAIR} # Calling convention diff --git a/tests_python/contracts_012/opcodes/tez_add_sub.tz b/tests_python/contracts_012/opcodes/tez_add_sub.tz deleted file mode 100644 index 990fb2ffac4d..000000000000 --- a/tests_python/contracts_012/opcodes/tez_add_sub.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (pair mutez mutez); -storage (option (pair mutez mutez)); -code {CAR; DUP; DUP; CAR; DIP{CDR}; ADD; - DIP{DUP; CAR; DIP{CDR}; SUB_MUTEZ; ASSERT_SOME}; - PAIR; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/ticket_bad.tz b/tests_python/contracts_012/opcodes/ticket_bad.tz deleted file mode 100644 index e183ac5278b5..000000000000 --- a/tests_python/contracts_012/opcodes/ticket_bad.tz +++ /dev/null @@ -1,5 +0,0 @@ -# Although this contract is correctly typed, originating it with a forged -# ticket should be refused -parameter unit; -storage (ticket nat); -code { CDR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/ticket_big_store.tz b/tests_python/contracts_012/opcodes/ticket_big_store.tz deleted file mode 100644 index 6d1de845235e..000000000000 --- a/tests_python/contracts_012/opcodes/ticket_big_store.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter nat ; -storage (big_map unit (ticket nat)); -code { UNPAIR ; PUSH nat 1 ; SWAP ; TICKET ; SOME ; UNIT ; UPDATE ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/ticket_join.tz b/tests_python/contracts_012/opcodes/ticket_join.tz deleted file mode 100644 index 3aef469a48c5..000000000000 --- a/tests_python/contracts_012/opcodes/ticket_join.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter (ticket nat); -storage (option (ticket nat)); -code { UNPAIR ; SWAP ; - IF_NONE {} { PAIR ; JOIN_TICKETS ; ASSERT_SOME } ; - SOME ; - NIL operation ; - PAIR } diff --git a/tests_python/contracts_012/opcodes/ticket_read.tz b/tests_python/contracts_012/opcodes/ticket_read.tz deleted file mode 100644 index c41176a5fee0..000000000000 --- a/tests_python/contracts_012/opcodes/ticket_read.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter (ticket nat); -storage address; -code { CAR ; - READ_TICKET ; DIP { DROP } ; UNPAIR ; DIP { UNPAIR } ; - DIIP { PUSH nat 1 ; ASSERT_CMPEQ } ; - DIP { PUSH nat 42 ; ASSERT_CMPEQ } ; - NIL operation ; - PAIR } diff --git a/tests_python/contracts_012/opcodes/ticket_split.tz b/tests_python/contracts_012/opcodes/ticket_split.tz deleted file mode 100644 index a2587beb717e..000000000000 --- a/tests_python/contracts_012/opcodes/ticket_split.tz +++ /dev/null @@ -1,11 +0,0 @@ -parameter (ticket nat) ; -storage unit; -code - { CAR ; - PUSH (pair nat nat) (Pair 1 2) ; SWAP; - SPLIT_TICKET; ASSERT_SOME; UNPAIR; - READ_TICKET; CDDR; PUSH nat 1; ASSERT_CMPEQ; - DROP; - READ_TICKET; CDDR; PUSH nat 2; ASSERT_CMPEQ; - DROP; - UNIT ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/ticket_store-2.tz b/tests_python/contracts_012/opcodes/ticket_store-2.tz deleted file mode 100644 index cab3dd79d012..000000000000 --- a/tests_python/contracts_012/opcodes/ticket_store-2.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (option (ticket nat)) ; -storage (option (ticket nat)); -code { CAR ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/ticket_store.tz b/tests_python/contracts_012/opcodes/ticket_store.tz deleted file mode 100644 index 926a04aa1e88..000000000000 --- a/tests_python/contracts_012/opcodes/ticket_store.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (ticket nat) ; -storage (option (ticket nat)); -code { CAR ; SOME ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/ticketer-2.tz b/tests_python/contracts_012/opcodes/ticketer-2.tz deleted file mode 100644 index bce940ccabe2..000000000000 --- a/tests_python/contracts_012/opcodes/ticketer-2.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (pair (pair address nat) nat) ; -storage unit; -code { CAR ; UNPAIR ; UNPAIR ; - CONTRACT (ticket nat) ; ASSERT_SOME ; - DIP { TICKET } ; - SWAP ; DIP { PUSH mutez 0 } ; - TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; - UNIT ; SWAP ; PAIR } diff --git a/tests_python/contracts_012/opcodes/ticketer.tz b/tests_python/contracts_012/opcodes/ticketer.tz deleted file mode 100644 index c8ec4565398a..000000000000 --- a/tests_python/contracts_012/opcodes/ticketer.tz +++ /dev/null @@ -1,10 +0,0 @@ -parameter address; -storage nat; -code { UNPAIR ; DIP { DUP } ; - SWAP ; - PUSH nat 1 ; SWAP ; - TICKET ; - DIP { CONTRACT (ticket nat) ; ASSERT_SOME ; PUSH mutez 0 } ; - TRANSFER_TOKENS ; - NIL operation ; SWAP ; CONS ; - PAIR } diff --git a/tests_python/contracts_012/opcodes/transfer_amount.tz b/tests_python/contracts_012/opcodes/transfer_amount.tz deleted file mode 100644 index 973c64f04dcc..000000000000 --- a/tests_python/contracts_012/opcodes/transfer_amount.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter unit; -storage mutez; -code { DROP; AMOUNT; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/transfer_tokens.tz b/tests_python/contracts_012/opcodes/transfer_tokens.tz deleted file mode 100644 index 599b4dae180f..000000000000 --- a/tests_python/contracts_012/opcodes/transfer_tokens.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (contract unit); -storage unit; -code { CAR; DIP{UNIT}; PUSH mutez 100000000; UNIT; - TRANSFER_TOKENS; - NIL operation; SWAP; CONS; PAIR}; diff --git a/tests_python/contracts_012/opcodes/uncomb.tz b/tests_python/contracts_012/opcodes/uncomb.tz deleted file mode 100644 index 84c3ced7ca9c..000000000000 --- a/tests_python/contracts_012/opcodes/uncomb.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter (pair nat nat nat); -storage nat; -code { CAR ; - UNPAIR 3 ; - PUSH nat 100 ; MUL ; - SWAP ; PUSH nat 10 ; MUL ; - ADD ; ADD ; - NIL operation ; PAIR ; } diff --git a/tests_python/contracts_012/opcodes/unpair.tz b/tests_python/contracts_012/opcodes/unpair.tz deleted file mode 100644 index b45f30a03d38..000000000000 --- a/tests_python/contracts_012/opcodes/unpair.tz +++ /dev/null @@ -1,71 +0,0 @@ -parameter (unit :param_unit); -storage (unit :u1); -code { DROP ; - - # No annotation - UNIT; UNIT; PAIR; UNPAIR; DROP 2; - - # Variable annotations are overriden by UNPAIR - UNIT @b; UNIT @a; PAIR; UNPAIR @c @d; DROP 2; - - UNIT @b; UNIT @a; PAIR %@ %@; - DUP; UNPAIR %a %b; DROP 2; - DUP; UNPAIR % %b; DROP 2; - DUP; UNPAIR %a %; DROP 2; - DUP; UNPAIR % %; DROP 2; - DUP; UNPAIR %a; DROP 2; - DUP; UNPAIR %; DROP 2; - DUP; UNPAIR; DROP 2; - DUP; UNPAIR %a %b @a @b; DROP 2; - DUP; UNPAIR @a @b %a %b; DROP 2; - DUP; UNPAIR @a @% %a %b; DROP 2; - DUP; UNPAIR @% @% %a %b; DROP 2; - DUP; UNPAIR @% @b %a %b; DROP 2; - DROP; - - # Same test with non-matching field and variable annotations - UNIT @d; UNIT @c; PAIR %a %b; - DUP; UNPAIR %a %b; DROP 2; - DUP; UNPAIR % %b; DROP 2; - DUP; UNPAIR %a %; DROP 2; - DUP; UNPAIR % %; DROP 2; - DUP; UNPAIR %a; DROP 2; - DUP; UNPAIR %; DROP 2; - DUP; UNPAIR; DROP 2; - DUP; UNPAIR %a %b @a @b; DROP 2; - DUP; UNPAIR @a @b %a %b; DROP 2; - DUP; UNPAIR @a @% %a %b; DROP 2; - DUP; UNPAIR @% @% %a %b; DROP 2; - DUP; UNPAIR @% @b %a %b; DROP 2; - DROP; - - # Same tests without the variable annotations in input - UNIT; UNIT; PAIR %a %b; - DUP; UNPAIR %a %b; DROP 2; - DUP; UNPAIR % %b; DROP 2; - DUP; UNPAIR %a %; DROP 2; - DUP; UNPAIR % %; DROP 2; - DUP; UNPAIR %a; DROP 2; - DUP; UNPAIR %; DROP 2; - DUP; UNPAIR; DROP 2; - DUP; UNPAIR %a %b @a @b; DROP 2; - DUP; UNPAIR @a @b %a %b; DROP 2; - DUP; UNPAIR @a @% %a %b; DROP 2; - DUP; UNPAIR @% @% %a %b; DROP 2; - DUP; UNPAIR @% @b %a %b; DROP 2; - DROP; - - # Tests for @%% - UNIT; UNIT; PAIR %a %b @p; - DUP; UNPAIR @%% @b; DROP 2; - DUP; UNPAIR @a @%%; DROP 2; - DUP; UNPAIR @%% @%%; DROP 2; - DUP; UNPAIR @% @%%; DROP 2; - DUP; UNPAIR @%% @%; DROP 2; - DROP; - - # Swapping variable annotations - UNIT @b; UNIT @a; PAIR @c; UNPAIR @b @a; DROP 2; - - # End of test - UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/update_big_map.tz b/tests_python/contracts_012/opcodes/update_big_map.tz deleted file mode 100644 index c403975a38fb..000000000000 --- a/tests_python/contracts_012/opcodes/update_big_map.tz +++ /dev/null @@ -1,6 +0,0 @@ -storage (pair (big_map string string) unit); -parameter (map string (option string)); -# this contract the stored big_map according to the map taken in parameter -code { UNPAPAIR; - ITER { UNPAIR; UPDATE; } ; - PAIR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/utxo_read.tz b/tests_python/contracts_012/opcodes/utxo_read.tz deleted file mode 100644 index aec29b79730b..000000000000 --- a/tests_python/contracts_012/opcodes/utxo_read.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (pair (ticket nat) nat); -storage address; -code { CAR ; - UNPAIR ; - READ_TICKET ; DIP { DROP } ; UNPAIR ; DIP { UNPAIR } ; - DIIP { ASSERT_CMPEQ } ; - DIP { PUSH nat 42 ; ASSERT_CMPEQ } ; - NIL operation ; - PAIR } diff --git a/tests_python/contracts_012/opcodes/utxor.tz b/tests_python/contracts_012/opcodes/utxor.tz deleted file mode 100644 index 81d9632d35d2..000000000000 --- a/tests_python/contracts_012/opcodes/utxor.tz +++ /dev/null @@ -1,24 +0,0 @@ -parameter (pair address address); -storage nat; -code { UNPAIR ; DIP { DUP } ; - SWAP ; - PUSH nat 5 ; SWAP ; - TICKET ; - PUSH nat 2 ; PUSH nat 3 ; PAIR ; - SWAP ; - SPLIT_TICKET ; - ASSERT_SOME ; - UNPAIR ; - DIP { DIP { DUP ; CAR ; - CONTRACT (pair (ticket nat) nat) ; ASSERT_SOME ; - PUSH mutez 0 } ; - PUSH nat 2 ; SWAP ; PAIR ; } ; - DIP { TRANSFER_TOKENS } ; - SWAP ; - DIP { DIP { CDR ; - CONTRACT (pair (ticket nat) nat) ; ASSERT_SOME ; - PUSH mutez 0 } ; - PUSH nat 3 ; SWAP ; PAIR ; } ; - DIP { TRANSFER_TOKENS } ; - NIL operation ; SWAP ; CONS ; SWAP ; CONS ; - PAIR } diff --git a/tests_python/contracts_012/opcodes/view_fib.tz b/tests_python/contracts_012/opcodes/view_fib.tz deleted file mode 100644 index 1b44288dd4a1..000000000000 --- a/tests_python/contracts_012/opcodes/view_fib.tz +++ /dev/null @@ -1,9 +0,0 @@ -parameter (pair nat address) ; -storage nat; -code { - CAR; - UNPAIR; - VIEW "fib" nat; - IF_SOME {NIL operation ; PAIR;} { FAIL } - } - diff --git a/tests_python/contracts_012/opcodes/view_mutual_recursion.tz b/tests_python/contracts_012/opcodes/view_mutual_recursion.tz deleted file mode 100644 index 9446a195b6e7..000000000000 --- a/tests_python/contracts_012/opcodes/view_mutual_recursion.tz +++ /dev/null @@ -1,11 +0,0 @@ -parameter (pair nat address) ; -storage nat; -code { - CAR; - DUP; - CDR; - SWAP; - VIEW "is_twenty" nat; - IF_SOME {NIL operation ; PAIR;} { FAIL } - } - diff --git a/tests_python/contracts_012/opcodes/view_op_add.tz b/tests_python/contracts_012/opcodes/view_op_add.tz deleted file mode 100644 index e0c611cd3e8c..000000000000 --- a/tests_python/contracts_012/opcodes/view_op_add.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage nat ; -code { CAR ; UNPAIR ; VIEW "add" nat ; IF_SOME { } { FAIL }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_constant.tz b/tests_python/contracts_012/opcodes/view_op_constant.tz deleted file mode 100644 index 5fc8b427884a..000000000000 --- a/tests_python/contracts_012/opcodes/view_op_constant.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage nat; -code { CAR ; UNPAIR ; VIEW "const" nat ; IF_SOME { } { FAIL }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_id.tz b/tests_python/contracts_012/opcodes/view_op_id.tz deleted file mode 100644 index 7eb267bda064..000000000000 --- a/tests_python/contracts_012/opcodes/view_op_id.tz +++ /dev/null @@ -1,4 +0,0 @@ -parameter (pair nat address) ; -storage (pair nat nat) ; -code { CAR ; UNPAIR ; VIEW "id" (pair nat nat) ; IF_SOME { } { FAIL }; NIL operation ; PAIR } ; - diff --git a/tests_python/contracts_012/opcodes/view_op_nonexistent_addr.tz b/tests_python/contracts_012/opcodes/view_op_nonexistent_addr.tz deleted file mode 100644 index f6947732e00e..000000000000 --- a/tests_python/contracts_012/opcodes/view_op_nonexistent_addr.tz +++ /dev/null @@ -1,5 +0,0 @@ -parameter (pair nat address) ; -storage bool ; -code { DROP; PUSH address "tz1SuakBpFdG9b4twyfrSMqZzruxhpMeSrE5"; PUSH nat 0; - VIEW "test" bool; IF_SOME { DROP ; PUSH bool True } { PUSH bool False } ; - NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_nonexistent_func.tz b/tests_python/contracts_012/opcodes/view_op_nonexistent_func.tz deleted file mode 100644 index ca8ae6be4d34..000000000000 --- a/tests_python/contracts_012/opcodes/view_op_nonexistent_func.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage bool ; -code { CAR ; UNPAIR ; VIEW "not_exist" bool ; IF_SOME { DROP; PUSH bool True } { PUSH bool False }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_test_step_contants.tz b/tests_python/contracts_012/opcodes/view_op_test_step_contants.tz deleted file mode 100644 index 42106d2a6087..000000000000 --- a/tests_python/contracts_012/opcodes/view_op_test_step_contants.tz +++ /dev/null @@ -1,8 +0,0 @@ -parameter address ; -storage (option (pair (pair mutez mutez) (pair (pair address address) address ))); -code { CAR ; - UNIT; - VIEW "step_constants" (pair (pair mutez mutez) (pair (pair address address) address )) ; - NIL operation ; - PAIR } ; - diff --git a/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_input_type.tz b/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_input_type.tz deleted file mode 100644 index d99353ace3d9..000000000000 --- a/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_input_type.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair int address) ; -storage nat; -code { CAR ; UNPAIR ; VIEW "add" nat ; IF_SOME { DROP ; PUSH nat 1 } { PUSH nat 0 }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_output_type.tz b/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_output_type.tz deleted file mode 100644 index 258cf616793c..000000000000 --- a/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_output_type.tz +++ /dev/null @@ -1,3 +0,0 @@ -parameter (pair nat address) ; -storage bool; -code { CAR ; UNPAIR ; VIEW "add" bool; IF_SOME { DROP ; PUSH bool True} { PUSH bool False }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_rec.tz b/tests_python/contracts_012/opcodes/view_rec.tz deleted file mode 100644 index 490c72d29498..000000000000 --- a/tests_python/contracts_012/opcodes/view_rec.tz +++ /dev/null @@ -1,12 +0,0 @@ -parameter unit ; -storage unit ; -view "loop" address never { CAR; DUP; VIEW "loop" never; ASSERT_SOME } ; -code { CDR ; - SELF ; - ADDRESS ; - DUP ; - VIEW "loop" never ; - ASSERT_SOME ; - DROP ; - NIL operation ; - PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_toplevel_lib.tz b/tests_python/contracts_012/opcodes/view_toplevel_lib.tz deleted file mode 100644 index 1810a8a8ec4c..000000000000 --- a/tests_python/contracts_012/opcodes/view_toplevel_lib.tz +++ /dev/null @@ -1,67 +0,0 @@ -parameter nat ; -storage nat ; -code { CAR ; NIL operation ; PAIR } ; -view "add" nat nat { UNPAIR ; ADD } ; -view "id" nat (pair nat nat) { } ; -view "test_failwith" nat (pair nat nat) { FAILWITH } ; -view "step_constants" unit (pair (pair mutez mutez) (pair (pair address address) address )) - { DROP ; - SOURCE; - SENDER; - SELF_ADDRESS; - PAIR; - PAIR; - BALANCE; - AMOUNT; - PAIR; - PAIR; - } ; - -view "succ" (pair nat address) nat - { CAR; - UNPAIR; - PUSH nat 1; ADD; - PAIR; - DUP; CDR; SWAP; - VIEW "is_twenty" nat; ASSERT_SOME; - } ; -view "is_twenty" (pair nat address) nat - { - CAR; - DUP; - CAR; - PUSH nat 20 ; - COMPARE; - EQ ; - IF { CAR; } - { DUP; CDR; SWAP; VIEW "succ" nat; ASSERT_SOME } - } ; -view "fib" nat nat - { - CAR; - DUP; - PUSH nat 0 ; - COMPARE ; - EQ ; - IF { } - { DUP; - PUSH nat 1; - COMPARE; - EQ; - IF { } - { DUP; - PUSH nat 1; SWAP; SUB; ABS; - SELF_ADDRESS; - SWAP; - VIEW "fib" nat; - IF_SOME { SWAP; - PUSH nat 2; SWAP; SUB; ABS; - SELF_ADDRESS; - SWAP; - VIEW "fib" nat; - IF_SOME { ADD; } { FAIL } - } - { FAIL }; - } - } - } diff --git a/tests_python/contracts_012/opcodes/voting_power.tz b/tests_python/contracts_012/opcodes/voting_power.tz deleted file mode 100644 index 741bb196788d..000000000000 --- a/tests_python/contracts_012/opcodes/voting_power.tz +++ /dev/null @@ -1,7 +0,0 @@ -parameter key; # A public key -storage (pair nat nat); -code { CAR; - HASH_KEY; VOTING_POWER; # Get the number of rolls for the key - DIP { TOTAL_VOTING_POWER }; # Get the total number of rolls - PAIR; - NIL operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/xor.tz b/tests_python/contracts_012/opcodes/xor.tz deleted file mode 100644 index 557eaa642b9a..000000000000 --- a/tests_python/contracts_012/opcodes/xor.tz +++ /dev/null @@ -1,13 +0,0 @@ -parameter (or (pair bool bool) (pair nat nat)); -storage (option (or bool nat)); -code { - CAR; - IF_LEFT - { - UNPAIR; XOR; LEFT nat - } - { - UNPAIR; XOR; RIGHT bool - } ; - SOME; NIL operation ; PAIR - } diff --git a/tests_python/tests_012/__init__.py b/tests_python/tests_012/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize.out deleted file mode 100644 index 4608b96a4e43..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize.out +++ /dev/null @@ -1,8 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize - -{ Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } -{ Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } -{ { 0 ; 3 ; 6 ; 9 } ; { 1 ; 4 ; 7 ; 10 } ; { 2 ; 5 ; 8 ; 11 } } -{ Pair 0 (Pair 3 (Pair 6 9)) ; - Pair 1 (Pair 4 (Pair 7 10)) ; - Pair 2 (Pair 5 (Pair 8 11)) } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_legacy_flag.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_legacy_flag.out deleted file mode 100644 index 272b3a5969d1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_legacy_flag.out +++ /dev/null @@ -1,8 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_legacy_flag - -{ Elt 0 1 } -At (unshown) location 0, value { Elt %a 0 1 } -is invalid for type map nat nat. -At (unshown) location 1, unexpected annotation. -Fatal error: - ill-typed data expression diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[None].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[None].out deleted file mode 100644 index 0c56e660a7a7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[None].out +++ /dev/null @@ -1,10 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_script[None] - -{ parameter unit ; - storage unit ; - code { PUSH (list (pair nat nat nat nat)) - { Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } ; - DROP 2 ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized].out deleted file mode 100644 index c40d99fcd1e3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized].out +++ /dev/null @@ -1,10 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_script[Optimized] - -{ parameter unit ; - storage unit ; - code { PUSH (list (pair nat nat nat nat)) - { { 0 ; 3 ; 6 ; 9 } ; { 1 ; 4 ; 7 ; 10 } ; { 2 ; 5 ; 8 ; 11 } } ; - DROP 2 ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized_legacy].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized_legacy].out deleted file mode 100644 index 22db8e346804..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized_legacy].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_script[Optimized_legacy] - -{ parameter unit ; - storage unit ; - code { PUSH (list (pair nat nat nat nat)) - { Pair 0 (Pair 3 (Pair 6 9)) ; - Pair 1 (Pair 4 (Pair 7 10)) ; - Pair 2 (Pair 5 (Pair 8 11)) } ; - DROP 2 ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Readable].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Readable].out deleted file mode 100644 index 7a50f118fb80..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Readable].out +++ /dev/null @@ -1,10 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_script[Readable] - -{ parameter unit ; - storage unit ; - code { PUSH (list (pair nat nat nat nat)) - { Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } ; - DROP 2 ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool bytes)].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool bytes)].out deleted file mode 100644 index f9331cdb9377..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool bytes)].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_type[list (pair nat int bool bytes)] - -list (pair nat (pair int (pair bool bytes))) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool)].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool)].out deleted file mode 100644 index e2c6bbe429e6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool)].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_type[list (pair nat int bool)] - -list (pair nat (pair int bool)) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int)].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int)].out deleted file mode 100644 index 03f2db66141a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int)].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_type[list (pair nat int)] - -list (pair nat int) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list nat].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list nat].out deleted file mode 100644 index 937f616c7483..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list nat].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_type[list nat] - -list nat diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[nat].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[nat].out deleted file mode 100644 index 71e141ec0cea..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[nat].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_type[nat] - -nat diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool bytes].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool bytes].out deleted file mode 100644 index 87a35a852421..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool bytes].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_type[pair nat int bool bytes] - -pair nat (pair int (pair bool bytes)) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool].out deleted file mode 100644 index 5ba776793aa7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_type[pair nat int bool] - -pair nat (pair int bool) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int].out deleted file mode 100644 index d91efb117baa..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_type[pair nat int] - -pair nat int diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[None].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[None].out deleted file mode 100644 index ff1b2183f03d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[None].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_unparsing_mode[None] - -{ Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized].out deleted file mode 100644 index 446f096a4991..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_unparsing_mode[Optimized] - -{ { 0 ; 3 ; 6 ; 9 } ; { 1 ; 4 ; 7 ; 10 } ; { 2 ; 5 ; 8 ; 11 } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized_legacy].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized_legacy].out deleted file mode 100644 index 8444bb2c028a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized_legacy].out +++ /dev/null @@ -1,5 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_unparsing_mode[Optimized_legacy] - -{ Pair 0 (Pair 3 (Pair 6 9)) ; - Pair 1 (Pair 4 (Pair 7 10)) ; - Pair 2 (Pair 5 (Pair 8 11)) } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Readable].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Readable].out deleted file mode 100644 index 8802fbabac67..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Readable].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestNormalize::test_normalize_unparsing_mode[Readable] - -{ Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out deleted file mode 100644 index c5299adac0f0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out +++ /dev/null @@ -1,301 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0] - -exprvFK4dJmFGinHHBe92WR4kA7L8WSBQQYDigmyVCyKpiQHCXe9fk [CONTRACT_PATH]/attic/accounts.tz -expruucsMyaSmmP5gmkFWjJfv4a52FQV5EGaf3XpHoeXHQgyJgMJfF [CONTRACT_PATH]/attic/add1.tz -exprvEM4Lvihz6jFYszxazuQQPsHjxA4J54tfLeowwDkY1jjTi8Qft [CONTRACT_PATH]/attic/add1_list.tz -exprta1x6QtexpFktejHoB1KwuMQRXePhgre9rDiJ3GDSZCqb3vtqL [CONTRACT_PATH]/attic/after_strategy.tz -expruEosJCXYteRXxfbAVJ5XythgpVQPMdiu3kbbZj3VAVSVjk8ud7 [CONTRACT_PATH]/attic/always.tz -exprvR9m6PaVeLfPHZjA3A929bbfjonzMJs1Kzcmj8baoEvLct9Ry9 [CONTRACT_PATH]/attic/append.tz -exprvQh7vw7vYfp2qdiyYPCFgd6jVkxqYZimmqoYCGZbqaoMgfLifS [CONTRACT_PATH]/attic/at_least.tz -exprtyZC9vL831BnATCkdrP585F4cEzQQQp1ZqnZSqvCDLqp7S33V1 [CONTRACT_PATH]/attic/auction.tz -expruZ4wjBCm3DQNhEf69L27tqaqAJa1TF34728yyPJ9BUg3sEwcxB [CONTRACT_PATH]/attic/bad_lockup.tz -expruazd13u4uPHS7oFWFeZ5nodWR5QC6nQwgy5LGoUTAR3KXsYPXg [CONTRACT_PATH]/attic/big_map_union.tz -exprv7aEg823PTvrEG5bXr4QGk3XCsEkodhUxWCaMBBSq44ZuAxnNf [CONTRACT_PATH]/attic/cadr_annotation.tz -expruwmej4r1RSMDEmmU4SjWUbrzpURnAwybrSwBaMkHpxVobLkWAe [CONTRACT_PATH]/attic/concat.tz -exprte328K2NmgWrmHLbFrGVjvoZKZNFB7577Vt7cWQa8KdvWbfxYk [CONTRACT_PATH]/attic/conditionals.tz -exprvRVXhJFcFjGMkatDwgaLRcJq4TctY979bjniTqwACgXtC3mWko [CONTRACT_PATH]/attic/cons_twice.tz -exprtcnAL38pt7fyZdCiqd97qcYeESWQStPR6sbN2SxMCfbPJhVjau [CONTRACT_PATH]/attic/cps_fact.tz -exprv9BquR6NXVwKMwD4MS5vdWqqvMzjvWumrBf6NsGQXSfgm2Rtqk [CONTRACT_PATH]/attic/create_add1_lists.tz -exprv4cq5g9hsxWU65zCp8dfUi3RtBzu9rGXZ7otetL23tj1zSkNQ2 [CONTRACT_PATH]/attic/data_publisher.tz -expruavAC89RfrZxSrYwdoA6Wr5ghwdUSns8SNaHcng1JRcqR1dwpR [CONTRACT_PATH]/attic/dispatch.tz -expruat2BS4KCwn9kbopeX1ZwxtrtJbyFhpnpnG6A5KdCBCwHNsdod [CONTRACT_PATH]/attic/empty.tz -exprubD7VQHa8qeqRsFByes3ANZ24mvUnqW3qKAsKVUCncjxYEXtGp [CONTRACT_PATH]/attic/fail_amount.tz -expruYCfXuFoyakdWc3C6Np5ojQrGLDMMN6btVbVEAc97MJzpQYVrm [CONTRACT_PATH]/attic/faucet.tz -expruuvYJkV5YndLNMHFg54yDF1HG6AP4zMsui7RgQBLr6vCZVBVYt [CONTRACT_PATH]/attic/forward.tz -exprv8K6ceBpFH5SFjQm4BRYSLJCHQBFeQU6BFTdvQSRPaPkzdLyAL [CONTRACT_PATH]/attic/id.tz -exprujqMuqia1zKuReMgjumpsn8XAJ5N6RWaoz3kZpLNRUyyQXwrtY [CONTRACT_PATH]/attic/infinite_loop.tz -exprtoE9fvqNeHngkFPopZv412GoqoZ57HgaCi2XFR7YxkwPpvHXBZ [CONTRACT_PATH]/attic/insertion_sort.tz -exprux8tMeArJNXUekbuHqLb6epu2eWXJy85f8Yts5oHASHyWp6bva [CONTRACT_PATH]/attic/int_publisher.tz -expruosSkGQbRDc3NUt5oEqSkt3dqxymQDKDeNxcjRgFNLxARG414v [CONTRACT_PATH]/attic/king_of_tez.tz -exprtZcF9NutGBwyuXTqEi4SyL3bZdAWqzkDc782wxNhYT7LtdY4Lb [CONTRACT_PATH]/attic/list_of_transactions.tz -expruDiMLqyYi67RbkDfNyEjBDgJqQLiCGVx2xLUiWujSkwr7rVyRD [CONTRACT_PATH]/attic/queue.tz -exprtZYeWyxANtdrSANECgXdeakcP9fJm7ecJhpeuGR55a8gDTSXWe [CONTRACT_PATH]/attic/reduce_map.tz -exprvMneQMtBQzcPKboFsEV7R4BAuoF8QLUDMWB62iYLmKz9tztNdJ [CONTRACT_PATH]/attic/reentrancy.tz -exprueaa65wkL9ennP6vZoUP6yCkzz6Wc4cF3w11q8bGXguokXAEvK [CONTRACT_PATH]/attic/reservoir.tz -exprtwrNpVRUJaVTBs5vXFLbt4v6Fb8LRySwc1Ap8ZWZh4JbLfgJ6P [CONTRACT_PATH]/attic/scrutable_reservoir.tz -expruwtkYFMkNLVjKD8hypuDc53SHLQQ65g6VPGiHFXbY5hHwmb552 [CONTRACT_PATH]/attic/spawn_identities.tz -expruiDvGyQG5GzKzcBP7d5Z5doUcdxTmUcM6vL1jCTyTmxLrekmP7 [CONTRACT_PATH]/macros/assert.tz -expruMKaaLoPjYfDaKymizi9fnFY7hSDyPj2NfJFxSuAoEVknDxSM6 [CONTRACT_PATH]/macros/assert_cmpeq.tz -exprtqiRJEnWeqF5KKBRPjamJGoi2oQvekfnRwsdZNRy8w8wkbroKJ [CONTRACT_PATH]/macros/assert_cmpge.tz -exprtZWviL38eegiNAN55KfEtAHhAqUWoadkbxyFCGs3vDnDRzueft [CONTRACT_PATH]/macros/assert_cmpgt.tz -exprvBWTmSLBAGgcuBFSToCQPqH5J1F5R2vf8iJMiPVdZjG3B7hWq7 [CONTRACT_PATH]/macros/assert_cmple.tz -expruuDzygKxAaQ348e6BcRSk8A2Chq4WinaTUCTvg5YEVnGpptBg3 [CONTRACT_PATH]/macros/assert_cmplt.tz -expruxeuWRoEFHhzv7tG1rwderXePZzxtpL9BRQ9N7ZhoFXS6RPy9a [CONTRACT_PATH]/macros/assert_cmpneq.tz -expruaqEBPqAjaUawnFTSbGZXXr1HemnecV8GuLGD15nQvtxaXiH3z [CONTRACT_PATH]/macros/assert_eq.tz -expru9etUCKvNXZyDCx1x55QfZzyGxmgsteFNBoWAZeh6F5FHEHy3m [CONTRACT_PATH]/macros/assert_ge.tz -exprvP9aPgepXY1C4hVPWPMoDGhvSjNvH5sJvB25qcMMPFHurVyH9c [CONTRACT_PATH]/macros/assert_gt.tz -exprtbLVpjXVnhdMUyDM53MXHH2HBNSMxdnXsVTNtFFMHHVn18yUuZ [CONTRACT_PATH]/macros/assert_le.tz -exprtx7nibNobG8Y7asBYktu2NdPv3k3No29rM4nP1WSbricymunvc [CONTRACT_PATH]/macros/assert_lt.tz -exprvQM6Ukz3TKVSo4dqNDYmMvNG5rs3U7WGXpvjSVsM2oQj6SbdLM [CONTRACT_PATH]/macros/assert_neq.tz -exprueGaPWpG6szfmTAccNH5MaoqxovN7JCbx4CDsmpvnhBAUrAizc [CONTRACT_PATH]/macros/big_map_get_add.tz -exprvFc9HFkvwNGZVrJkU2KpXuXieVKCJ9VXbTo51LRWBMAB6oEbWq [CONTRACT_PATH]/macros/big_map_mem.tz -exprv7Gwz5KP32zP9FYPSng9mPqLYbxwttDZin5QPnqzsUM3MZBvLK [CONTRACT_PATH]/macros/build_list.tz -exprvNqdnnqWgrrZYgnkuFeXrboqQYnYiRLSb7wV4E27bdZcbrU5GK [CONTRACT_PATH]/macros/carn_and_cdrn.tz -exprtknptGzyx8quFM8gHyGcpyX5xYeUxUpoVPhZeBkRqz5hUHfuq7 [CONTRACT_PATH]/macros/compare.tz -exprussGZ9wiqKqGkCsFJrfvr5DXxqZiLuHATJuvr3D8ar3KCeNaCz [CONTRACT_PATH]/macros/compare_bytes.tz -expru4Mmhu46yLQj4Q767jgVgvbaNe7B6EwvYvWA9KCrfzCxwBnzCQ [CONTRACT_PATH]/macros/fail.tz -exprtyJ1YYdejX7jRUh8FDjbbwrbAFwZYKPjdEZMNUUWdncqEwvuyr [CONTRACT_PATH]/macros/guestbook.tz -exprvMCL9Ti9C12EZUiFR1YtSp7nYjPN4DoyJPQiyVDYCZsSsheTeV [CONTRACT_PATH]/macros/macro_annotations.tz -expruq2AH96hXvqFqphuMKhJUY8mGMmdHuiHWHjkZqooZoEusTNNRf [CONTRACT_PATH]/macros/map_caddaadr.tz -exprueEkWTdWS8F25vnUP8gWd75MCfxk3vMhETn5dUYtrifV6FU8x5 [CONTRACT_PATH]/macros/max_in_list.tz -expruGfNErSHzpWnoNpgvZ3MRc52jiCHu8YTDUvh2T643QABr7NDZN [CONTRACT_PATH]/macros/min.tz -exprtw4kigYCiREgky6KBKryS7JkaGih6ju8jkjaXtpdcWYrYukRKX [CONTRACT_PATH]/macros/pair_macro.tz -exprtxutG1Nu8d198ebiCraNuQ8a6iYYqJYfGXq19aykNPB1uECc8w [CONTRACT_PATH]/macros/set_caddaadr.tz -exprvCE6JDXrzEfZuxTQzSgxWXtxX5GoNxvidL84CN2TAm6Hk3kuK6 [CONTRACT_PATH]/macros/take_my_money.tz -exprunGqZLZZwm9mY31NFGbBemCgXGevYqLRKdeRKQArPf824Npnni [CONTRACT_PATH]/macros/unpair_macro.tz -exprufRUAYF6r5QHQvK8CzWkKQcdvYkPx5fjEYzWPXc35Dry77KDT1 [CONTRACT_PATH]/mini_scenarios/authentication.tz -exprtjdvZr5J7WfN4SyNgKueLnxX4fALUYJ4cmi675EHJdUu5yyg2n [CONTRACT_PATH]/mini_scenarios/big_map_entrypoints.tz -exprtfWRfK4RoY8CF9VXvcHeBxizfjMMPAkLojfUTuoZkMSyiPKoyK [CONTRACT_PATH]/mini_scenarios/big_map_magic.tz -expruRE8G1Qc1dU8ZeQCTA48D69uPv8hpZYtDiKKHbfiy1mQLno8nx [CONTRACT_PATH]/mini_scenarios/big_map_read.tz -exprtotUpA2o34SHPX7ZQHD69WvJyEykTvPJ8T3RFErKAq4TQHFAgP [CONTRACT_PATH]/mini_scenarios/big_map_store.tz -exprtbeKR4fc2tqCWahuCeXAb42Hpye5dwmq8sj2guSztorTFJnh1J [CONTRACT_PATH]/mini_scenarios/big_map_write.tz -exprvTRcwMZnUPdSeRG8DdiC2xH3DrfMbp8qCwg76Av4pqbX5k4tHw [CONTRACT_PATH]/mini_scenarios/create_contract.tz -exprubRYeqf14u8CU4cEri2RWBrx26gkxyGe5wGeVAf4PDjKdsNhLK [CONTRACT_PATH]/mini_scenarios/create_contract_simple.tz -exprvLDpqaNLp1Cb8hbCqRU6tyU53n9PQkixgcBwFdSLJWsUdwhCQU [CONTRACT_PATH]/mini_scenarios/default_account.tz -expruaNoYRNTQxG5yujhHLetzS68ppQ38MFyi2ZhzNs5WNFv3wBAHG [CONTRACT_PATH]/mini_scenarios/execution_order_appender.tz -exprv6GXw7FheWdWKfY5oxtkB1AcqWkpKQDq4w7rxYFvwypZQijymK [CONTRACT_PATH]/mini_scenarios/execution_order_caller.tz -exprvSqfUw3oLZmQDwys8V5Qn9K1RAgMDGxdUUxzx1wpnyif3uSZG8 [CONTRACT_PATH]/mini_scenarios/execution_order_storer.tz -expruhMQvp6kKepaVGL8EEMPPk6zY1uyyW22Ugrr4ty21dtjDcVdbq [CONTRACT_PATH]/mini_scenarios/fa12_reference.tz -exprub9UzpxmhedNQnsv1J1DazWGJnj1dLhtG1fxkUoWSdFLBGLqJ4 [CONTRACT_PATH]/mini_scenarios/generic_multisig.tz -exprvTVuhJ2wNH8LHYEUiNC6ugx264rdfka1HkGfdVxV5632GjqgNv [CONTRACT_PATH]/mini_scenarios/groth16.tz -expru1u3Ta2uCGgcz6Z86K2mA5ierGB9RMaSwSppzVFxeuiXpBFZrf [CONTRACT_PATH]/mini_scenarios/hardlimit.tz -exprutz4BVGJ3Qms6qjmqvUF8sEk27H1cfqhRT17qpTdhEs5hEjbWm [CONTRACT_PATH]/mini_scenarios/legacy_multisig.tz -exprvRy1WUs7SQaNJm478UQHzz8uJAQoWT3bR5TXSnmbxWAcpZdGKu [CONTRACT_PATH]/mini_scenarios/lockup.tz -exprufAK15C2FCbxGLCEVXFe26p3eQdYuwZRk1morJUwy9NBUmEZVB [CONTRACT_PATH]/mini_scenarios/lqt_fa12.mligo.tz -expruBi6wgss7SRmpBCseBzcu3L283Jfx2CpUjgfuT2MgsozUsvBwt [CONTRACT_PATH]/mini_scenarios/multiple_en2.tz -exprtgxcdQP1EVvEYN2BHjbqTvwzywuYAdCmnfVgeP9zcgkxUrmScN [CONTRACT_PATH]/mini_scenarios/multiple_entrypoints_counter.tz -exprucgYdABPRbbq2yy2rpyt4Z8fv7PN4yhkch3QYZ5QQ5ehbtNA4K [CONTRACT_PATH]/mini_scenarios/parameterized_multisig.tz -exprvJ8zXaBkyXMhJ2eKtPwdwbg5NLrggvW8MEpVK3hk3nAe215PQ6 [CONTRACT_PATH]/mini_scenarios/replay.tz -exprtuiYUMjM6d8XxPda1yfKeN61ko6riom35PzybC31NKXkVhgBQy [CONTRACT_PATH]/mini_scenarios/reveal_signed_preimage.tz -expruB4maBvk1y4JaeSLpDXWC3zKiXK5QFYv4B3R5KfdGEt4B5VvTT [CONTRACT_PATH]/mini_scenarios/self_address_receiver.tz -exprvTG7hjtWXeogStj3pzM1MCVcNg1q6KnivqNVzQjviUrJvsjfQn [CONTRACT_PATH]/mini_scenarios/self_address_sender.tz -expru9ASRmfbXX8Ajf5uDeiZDbNwonrCiS1e6UaDXUstKU3yuwQwdZ [CONTRACT_PATH]/mini_scenarios/ticket_builder_fungible.tz -exprtXrMgaXhLsw6ioNNPThqPF1yDyLjqGdJeB6yMRKLUQZfkTD6jy [CONTRACT_PATH]/mini_scenarios/ticket_builder_non_fungible.tz -expruryVEK55xjeHpeGgHjuLr9jtRS2D1gzAgYXpzGfripoX8qFhNK [CONTRACT_PATH]/mini_scenarios/ticket_wallet_fungible.tz -expruoGtEJH3sXXm2ruNG6DGTFE3GM6fjAS6fzDZKtdaMnRzHvi3Xd [CONTRACT_PATH]/mini_scenarios/ticket_wallet_non_fungible.tz -exprtnBz8poqNTrK4rzTXZFKQx7HWpx4WidHB5wxcM2oTS8NcrkAUt [CONTRACT_PATH]/mini_scenarios/tzip4_view.tz -exprugya6ngixBfjyxV28ffnC8jmJPi4vbJdqD1aVUx82YLhzbH8Tn [CONTRACT_PATH]/mini_scenarios/vote_for_delegate.tz -expruaKedvXmhg6wbV361DHykomz5dPqLi473KxBwJwyicEnKMhpb9 [CONTRACT_PATH]/mini_scenarios/weather_insurance.tz -exprv9PvyjnsPjPCg5f13WtBiuD3o6idDAVWU6QfPtdWMjCLGRpwTh [CONTRACT_PATH]/mini_scenarios/xcat.tz -exprvKm5t6a6LL2d3HjvRiJumGrGei24aRXscJk3zB1hs516Ju4oMZ [CONTRACT_PATH]/mini_scenarios/xcat_dapp.tz -exprucvy7NUDPu2yTWEA6WVsusEZgGRmU1WpVzrFnNZV7m2H8BVysF [CONTRACT_PATH]/non_regression/bug_262.tz -exprv3FvpUYzomvhmzxsQyuR1katpswNnicQZB4jA5uec3MERXk1cB [CONTRACT_PATH]/non_regression/pairk_annot.tz -exprujPzkrPVucSvhHc1d9xm6kcs7oggkQyJXN8L2Rj3fteEABAkTe [CONTRACT_PATH]/opcodes/abs.tz -expruNtqq51Lm75X61pxUx7P2FyR2uyUKLsZNHMXWx6X5rsyJ5M6WX [CONTRACT_PATH]/opcodes/add.tz -exprupWD554EpqFBjo4KUpTqrfQcJAHqr3ijKmv5cmLRJ93Q1SgwGX [CONTRACT_PATH]/opcodes/add_bls12_381_fr.tz -exprugu3H5MPrpWJRZMPMGDM3Dbvykaa1fHejEvYr7ePKaLtahjQV5 [CONTRACT_PATH]/opcodes/add_bls12_381_g1.tz -expru41eYPF7gPvBRAtantBxbFU75RqBEwHPZ7UeX2EgHmExRoA4dh [CONTRACT_PATH]/opcodes/add_bls12_381_g2.tz -exprtcPYR7TZHxzcpmZWjjLgMWp6CeRWAxQ5Bt2bgpUK5uKjmNAdzL [CONTRACT_PATH]/opcodes/add_delta_timestamp.tz -expruLFQ1mcR5sg9sqyFHThknANoBeL4C5HFGgH55MqwPBEb1TUxLt [CONTRACT_PATH]/opcodes/add_timestamp_delta.tz -exprtz1uUW5sVUVaKNLhPaKGjA7jK9JmzWBCQu5Xn1MC3aS1FjTUmK [CONTRACT_PATH]/opcodes/address.tz -expruskF2nSeJeBaVHZsp45yN7mer9a4f8fAUBYvU3oRzbmpm5cVmt [CONTRACT_PATH]/opcodes/amount_after_fib_view.tz -exprucSgNGh1wkijmUcjLdifceE7GeMdLnxL3JZKpbxAmzF41ALo91 [CONTRACT_PATH]/opcodes/amount_after_nonexistent_view.tz -expruUQ1z6YqZM1baKofNLYhK9nocp9puAXCo4MYzEkQPbQcXTnajq [CONTRACT_PATH]/opcodes/amount_after_view.tz -exprvJ4NRS33cboLuTx58f3sbYpXf1m7Cq2ou9gpCh1k8foaCZAoas [CONTRACT_PATH]/opcodes/and.tz -expru5BXwmdpWQ3WDKA24g6gYGwLxPc868wKkdeAaGh899nD77Uxwn [CONTRACT_PATH]/opcodes/and_binary.tz -expruL6aKRTXN2hWb9EXLuJASu7nuBGJxL7VyT1oEjX9b2s3u6Y5Ff [CONTRACT_PATH]/opcodes/and_logical_1.tz -exprtpYYuLewZWKCK1aPb9gfYSiPWSaeXRM4P2e4rpa6UktVueB1uf [CONTRACT_PATH]/opcodes/balance.tz -expruWVQymVzetzkRaBYh4thmdWCvzWZNqdGrCTinGxLn58rPXDkgC [CONTRACT_PATH]/opcodes/balance_after_fib_view.tz -exprukgm7LHJiEywzSseHXp23nXM5Y9GfJ61ULij58BgRQ4nt3bYYT [CONTRACT_PATH]/opcodes/balance_after_nonexistent_view.tz -expruggCnM7PeEcUr2BapBmFMhD1QGvEoM4dUfyxp2u64ic1fM9SYN [CONTRACT_PATH]/opcodes/balance_after_view.tz -exprtZRAy4QHqpF8c3CusD6e1kxWA3KAUrmgeXndfQYSEGArDmkWUm [CONTRACT_PATH]/opcodes/big_map_mem_nat.tz -exprugsT35M51mCw6Fim3ysNKpCh8JyW9m7CYW65QQ7XUEDmspqz2i [CONTRACT_PATH]/opcodes/big_map_mem_string.tz -exprvN3tk4o5YPYJB6aYAxEx8KU93yNSaw4K6mbEZZh9RQayua6odv [CONTRACT_PATH]/opcodes/big_map_to_self.tz -exprv712JoEC7RRhoP7gbTUiVgLbtAgHmenwa5TqhVykDZ3e538MGU [CONTRACT_PATH]/opcodes/bls12_381_fr_push_bytes_not_padded.tz -exprufF1yaR5QHdy8iECBLjhBtDZVLiEjZRuJntSkXjsrJRYozXLmW [CONTRACT_PATH]/opcodes/bls12_381_fr_push_nat.tz -expruSVRATSSsbfHowLHGs5XHms95RuqBWSdDJoUKdns3fWbwasU1p [CONTRACT_PATH]/opcodes/bls12_381_fr_to_int.tz -exprvTBYxSJ7d1z1aZvvAgPrdZUXHzoFxkwBC7McES5BS56xvqkGXg [CONTRACT_PATH]/opcodes/bls12_381_fr_to_mutez.tz -expruTppbXBm1YHSCB4uYv9MQs6zxqRWqbkwGWoiKfF5Sjj5n2TpJx [CONTRACT_PATH]/opcodes/bls12_381_fr_z_int.tz -exprv5Si29PfXErNuJdEvJWQhWRJ3qPETygaWzRE3ctmCU4s6y2V9v [CONTRACT_PATH]/opcodes/bls12_381_fr_z_nat.tz -expruRsYz6JopAFGU95WfFU61SE3RbMGn3XPR9PFiTfLbgQr2kzu7u [CONTRACT_PATH]/opcodes/bls12_381_z_fr_int.tz -expruyE3E3o8EAptRBZtQAB5Kv3sxUZGv7DK6CpJ2YdotQj9gqW5wN [CONTRACT_PATH]/opcodes/bls12_381_z_fr_nat.tz -exprui72n1Jur5Px5ESXgxiF9Uw86DsoXPt1edGDpSv4CvnuPCtBPR [CONTRACT_PATH]/opcodes/bytes.tz -exprtvRRYmpToi9y67ZzNmgjtdrgNkwVduSnBi7GZVrsmgDna8TSjB [CONTRACT_PATH]/opcodes/car.tz -expru5dDnxp1rhgXGmKigbLJ9ASaVHbkpkL6gLggtk9krgYC3jusc8 [CONTRACT_PATH]/opcodes/cdr.tz -expruxH6gEuBmNzg5nWEM4tv3jMBbknbEtTHKTPMeC4EBdFdujbRph [CONTRACT_PATH]/opcodes/chain_id.tz -expruGhHABGLz2wxAyyx3RpfyKHa8HE9voC19vLiAKYWYMMsUUTFdd [CONTRACT_PATH]/opcodes/chain_id_store.tz -exprtjDuLEzh8dcjpCcJiiuKXDdG3XusjuuURVCh3JWKBgjJGsVsMs [CONTRACT_PATH]/opcodes/check_signature.tz -expruHKTiWeY6mty7RokwdyZdwdzHQbu7udbbZbpu3C8h9n6jXnp4v [CONTRACT_PATH]/opcodes/comb-get.tz -exprtsyJo5ceZQM76zpAUeTren1YnBxw2MNDKmx8k11Ejai8T296Sg [CONTRACT_PATH]/opcodes/comb-literals.tz -exprv733yfMh1C9uyuAJJP66WPQDXAjjfcTcSfHhbboJnz6DUCEh41 [CONTRACT_PATH]/opcodes/comb-set-2.tz -exprvHamsTHMJKF6ohaSAwdgp2Sv33LGgYnjase3LUcwXKnJfh53wn [CONTRACT_PATH]/opcodes/comb-set.tz -expruufsxtik2vxyQfL3QKNWWH9TnJZgGx1ELi3AR5L3LM71uqxiP4 [CONTRACT_PATH]/opcodes/comb.tz -expruKknV6VYzPHkSxc3EFb488JPBfUX1UHsJUzceaGFafdnbgsKw2 [CONTRACT_PATH]/opcodes/compare.tz -exprvGXTYwatNh32w78r83SuLAW1YQefufYN1Bcu9AZ1BLDUU77dKR [CONTRACT_PATH]/opcodes/compare_big_type.tz -expruR3ZCLJTuojpTuS2sR3SGxqait52kXQNKfy8bipv69b2XJZG8A [CONTRACT_PATH]/opcodes/compare_big_type2.tz -expruUDL3EP43hFhcdCZD7K1xvfPtiNWfkU2Nyq8jmr9XgZuXqWXc5 [CONTRACT_PATH]/opcodes/comparisons.tz -exprtjqEmEBnmG7yiDXn224ER9bt4qh18LF4LzFSfoeuo1cbJpNBPy [CONTRACT_PATH]/opcodes/concat_hello.tz -exprtqd5qPLeh5Fi52YdkgWuvRXctgUoxU1Q4JDB2VseRk6DAEpMvd [CONTRACT_PATH]/opcodes/concat_hello_bytes.tz -expruv8MHvRmp3ipXYRyyP4aEE4iFHWsNZjNQSaCWUt7fwbgLeFBXY [CONTRACT_PATH]/opcodes/concat_list.tz -expruYk7GXYQ7bKbUcqcHDKs97USVBrxAkzSo2Bkj5AXVjSawDkNAS [CONTRACT_PATH]/opcodes/cons.tz -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_alt.tz -expruxUAUoijmC6A4rZK9XHcQL4WmgreJwT17hrgpuYkg1VeELBdbF [CONTRACT_PATH]/opcodes/create_contract_with_view.tz -exprteqmco8PDGH1PnTGgF5jPjBPCYyZfyvER2ULtv2y3MRgGdcP8T [CONTRACT_PATH]/opcodes/diff_timestamps.tz -exprtt6joHWnYr4AAW3uem8nzbxYgLcSpEJtaUT66qWchoKPS8sFXx [CONTRACT_PATH]/opcodes/dig_eq.tz -exprvKBfwAg4hVHrTtq3UV8AunaqUKxAkvx35TScbZDARNSgH737Ck [CONTRACT_PATH]/opcodes/dign.tz -exprv8t3ZfoBs6B7LMeFNN6U4PRpE1M6MhdtKPT5keNZT4je3RBadj [CONTRACT_PATH]/opcodes/dip.tz -expruncwh1qqNqSwq6kHYXfwhQyjpuJjbernTsyHAMnaLjU5h3qjxr [CONTRACT_PATH]/opcodes/dipn.tz -exprv62zo2ACMdseAu1HKzDDLSjBrYr2nZzi36PCTVJqcBwSdvt4yU [CONTRACT_PATH]/opcodes/dropn.tz -exprujbvaRkoroj5eVgboUyeP3578oJgScTQ78eBYMgfdLVaGWPPTW [CONTRACT_PATH]/opcodes/dugn.tz -exprur99uFkrwM63FXSTqSTypHcfEmzb5KQ9EypTRqZWDY5NP6tCHL [CONTRACT_PATH]/opcodes/dup-n.tz -exprtarW6tiguR7YAo6SxhCUDs1pLDhx9xJEG78h6GnXLAWpt3H1pT [CONTRACT_PATH]/opcodes/ediv.tz -exprvQhRaLYxiWN3QsJgT6VKf6DmGVuXR8DxeU63P9A8iNWA4TVQfs [CONTRACT_PATH]/opcodes/ediv_mutez.tz -exprv8Sy3DsiKMm3ZQPmi46kZGn9ctTigpLB2t6xYFdYkkeVHMXy6z [CONTRACT_PATH]/opcodes/empty_map.tz -exprufqf2G8PoZN768K2YGex6M7zmz7bYHE5LF5QHJBVvFtAFLi6qr [CONTRACT_PATH]/opcodes/exec_concat.tz -exprut53jocMPdPP8FXrKRDYSoRaxk1FXqCt7o46ak2wQaocjsSwwx [CONTRACT_PATH]/opcodes/first.tz -expru5fjTGWP1BXZz3BbbEFyDFkyZGJKHcZ2Y6jDT3CdHHp81n6G1r [CONTRACT_PATH]/opcodes/get_and_update_big_map.tz -exprua5oh3PDJEPQbEsnbHYCz6L7bY6kNvpyhEt7Cg9sPsrx82UmHQ [CONTRACT_PATH]/opcodes/get_and_update_map.tz -exprtgnkjSH6Tdw5C1BMKr8kCJjEnxCfMiaAxHTVLnEcyCQ6WmJ1jr [CONTRACT_PATH]/opcodes/get_big_map_value.tz -expruv8JdHeURNpuLHao37SGJauDPwB9yxFXUaL6hNCdXGzbHSqCZN [CONTRACT_PATH]/opcodes/get_map_value.tz -exprvHC1MDkeqCNL8yrN74nmqk5qrZCvR42qoVUxYCB4ALpgDfmhbL [CONTRACT_PATH]/opcodes/hash_consistency_checker.tz -expruzeve85eDLTpQ1EbgrQQcEUft7AGauZBwtK1ibuvJpwmZt9AE8 [CONTRACT_PATH]/opcodes/hash_key.tz -expruycqvZn4ufKjVQmYXcCfAfm7C81zN3BAqxuYVVfnpFibSKsahG [CONTRACT_PATH]/opcodes/hash_string.tz -expru34ooMhYSarFg7vZCe1Y23jwfxfHiDqwaE1wGXC48yjB21PLi1 [CONTRACT_PATH]/opcodes/if.tz -exprtmbKAmbV2XioTbmpJQpg9QDAxXkTBXmKRWdC8zbk8CWAtVXwAc [CONTRACT_PATH]/opcodes/if_some.tz -expruTGRZeiojz3Rrr45KUcwtpJuJYu6U8pxi4DBZpL2kGavVxxM4H [CONTRACT_PATH]/opcodes/int.tz -exprtu4Xbe67UZyTubEtKx83bMyQGXDwBibcdgLF5hftZYTEL2kSst [CONTRACT_PATH]/opcodes/iter_fail.tz -exprudLYgw6yWSrTHpXYsg9NcZxGGpCxdNFbNv7ksr6Ss8rNmh2fgT [CONTRACT_PATH]/opcodes/keccak.tz -exprusrBf5Sakr6dRngzuPmwsP28X6W56nVqCXqG1Jcfrd1SYwPRuU [CONTRACT_PATH]/opcodes/left_right.tz -exprvHZpmtBKjjsUZmchx2RTLmFAZnYKCnHSKXaKUdP5EUpiPYwsp2 [CONTRACT_PATH]/opcodes/level.tz -exprtkasRZbYRQg7WKnoXwJnRwXkvmjZEY4yPYXKGAQQFUupt5VAmt [CONTRACT_PATH]/opcodes/list_concat.tz -expru32VE4LnqAqhbpUFCdgEdRSHjLQipkXTjn624fL41yk3a4H5Q3 [CONTRACT_PATH]/opcodes/list_concat_bytes.tz -exprvCkexzSQFgEWkFvrkrQ8wATasfkbKCyeXYSM4qZft3g3UuoTBi [CONTRACT_PATH]/opcodes/list_id.tz -exprtbHaLLF4cUTh4VCjtnH32EAA2AFwvPBsCzUTgrrdofbotKMyr7 [CONTRACT_PATH]/opcodes/list_id_map.tz -expruAxpePKSFaGkjukWx4HEZAvXaWvyfyGyxCfhvK9tZjkPNSpZ1m [CONTRACT_PATH]/opcodes/list_iter.tz -exprvSCwmQGBkxgu2Tg5rYUXbyv33SpUskCJS7sPF4LN7e5pQ1fn7z [CONTRACT_PATH]/opcodes/list_map_block.tz -expruu6vcnLhDhSkSo8NNNJWQL99VCFr6iArtKrmavJWSNkQwDJsKC [CONTRACT_PATH]/opcodes/list_size.tz -expru8Et3hTjxKQpydKSThjR6fXSmPEmZDjBTNhTAbuyNjcPYoUQUL [CONTRACT_PATH]/opcodes/loop_failwith.tz -exprv15pFChKhH3QKoJn5BCT1bP4R7DjnXWtTDsSfwf2eVonZNxzZs [CONTRACT_PATH]/opcodes/loop_left.tz -expruAKUrHWCxb3qtVQ1a8qDzrS19HnTm7bS146AztFHekvpqbehaU [CONTRACT_PATH]/opcodes/loop_left_failwith.tz -exprubosuA8peKBt4EEo1RsYjxSxK7HXytSkBFAjns5Zg7ncicPWrC [CONTRACT_PATH]/opcodes/map_car.tz -expruqCpEBS2R8FqpBfDNUNrPhXZr39CBL6zKpyMogJR94sve62iv9 [CONTRACT_PATH]/opcodes/map_id.tz -exprtb1QBmNfCYjce9FnvKdikbtgqcN5o2VdVwZZP2Fmy8C3TJjA7q [CONTRACT_PATH]/opcodes/map_iter.tz -exprtuspLRSrYnp2FyqNcLfsBrBBFD8nnFog2Em3p7tfG4DcGujS3f [CONTRACT_PATH]/opcodes/map_map.tz -exprtipeMFcMFwYRAmzZBMoUjrtPYDk5ZyhMSyuhSgfiJV5UNAcLGp [CONTRACT_PATH]/opcodes/map_map_sideeffect.tz -exprtc9HPyzpfc71TE4a8UbRPxfdm4WGRPNQhfB5fHiWwkh1aA8uzm [CONTRACT_PATH]/opcodes/map_mem_nat.tz -exprtrkfCSUckShrEP5TmC5Y4CdeU35FFL7R8kyJHQUFZ4DNdJZasD [CONTRACT_PATH]/opcodes/map_mem_string.tz -expruqncptpX6oXeX88mAkVHh9DnzWb6vPwT6LvuND9yobgcH5Gd2x [CONTRACT_PATH]/opcodes/map_size.tz -expruZ7Tb7uhcAu3MhiDJFWrJiYseWyagZYEnzjEdpjSei8i73hsfG [CONTRACT_PATH]/opcodes/merge_comparable_pairs.tz -exprvNxEfUTwaryUzets4qyTbHAfNPb5ARQsMsxbm8CnGNHDedqxgy [CONTRACT_PATH]/opcodes/mul.tz -exprtYi1xHmB1AY6j4e3XTPvXpmuWnM4b4o78yVihYt1i2yNjrQqhY [CONTRACT_PATH]/opcodes/mul_bls12_381_fr.tz -expruFTKqYqMmWSakzE1gjs2p8kWtcRWTaddkYL5p2Z8wpcCfe5ei1 [CONTRACT_PATH]/opcodes/mul_bls12_381_g1.tz -exprvBDM3kep2f7bRkhRa2XWt9sdPGJ79sq6TdWNNnM4yydTQ88TaH [CONTRACT_PATH]/opcodes/mul_bls12_381_g2.tz -exprujbPsZAUa1tzgWNgeHEQ22JXDfNhkgx6sCCxbWjYoNWPbTvwhy [CONTRACT_PATH]/opcodes/mul_overflow.tz -exprth31LKm5FDFGxcXg1Rv9z9YeAQ8eu2oYTh2zZ7kJas3f5CWkZm [CONTRACT_PATH]/opcodes/munch.tz -expruP5gECQdRLkmuYg8xqvEAdE4oRGFjDVG3ZkWxtCyxve1jviw6k [CONTRACT_PATH]/opcodes/mutez_to_bls12_381_fr.tz -exprtw9PgkJCxyqdLjuA4dEdRjQXY7Ge4a7jjd2UoU6Q6KrvhFgciM [CONTRACT_PATH]/opcodes/neg.tz -expru5fYi1tAG8a9j2dYT561dXaox8wYjsZDZP18xPa5JN3bUNfHWS [CONTRACT_PATH]/opcodes/neg_bls12_381_fr.tz -expruY94PxNhmT8BeyGrFurRF6gC7XfgsBY9Vjh6hJyiDPaR8nFmri [CONTRACT_PATH]/opcodes/neg_bls12_381_g1.tz -exprv9bM4xnqjA33RkvUzz8ZppJXT32KdNXoYqY2NSh7whBcFPn2QS [CONTRACT_PATH]/opcodes/neg_bls12_381_g2.tz -expruZzA96Rh5o6HBboygY3iD97dgQcepXd45WBBD4DYZ2qcn8cxyY [CONTRACT_PATH]/opcodes/none.tz -expruat2BS4KCwn9kbopeX1ZwxtrtJbyFhpnpnG6A5KdCBCwHNsdod [CONTRACT_PATH]/opcodes/noop.tz -expruMUpBKBPGde4GfNLM8NgMq9nL6KsQXGA3LPt4C6wtMTxcUnE9A [CONTRACT_PATH]/opcodes/not.tz -exprtnpHGyp2TurQb2YzbXBKTipXnrUQ4RrZwPxWfa1yMXS7oi49jV [CONTRACT_PATH]/opcodes/not_binary.tz -exprusKUuYeoKXUAYtUhtknryT9MpbPZVZtbfUNCdRpXUbdzEzbwmN [CONTRACT_PATH]/opcodes/or.tz -exprvG84juZWwLHTrhtvWFWBs8D2wZw6rfpoAbXp2pkekuCMAaPbAn [CONTRACT_PATH]/opcodes/or_binary.tz -exprv39cZxxm6fTcFSbLcwpBbAPW56FPqjdf6aGm21KqGA6DQtwn6u [CONTRACT_PATH]/opcodes/originate_big_map.tz -exprunveMvzjDskHYCvYJzDfRR9aGwwvXkVUMqTwSxJJbEjeq63c2D [CONTRACT_PATH]/opcodes/packunpack.tz -expruKkmmajE1UFXRHXtntLZU8VvnLfFKwYPd4azsAdcrDMaq5zu9H [CONTRACT_PATH]/opcodes/packunpack_rev.tz -exprtk9p4ur3KZK2w8ziFoZVHPABxQWZXeSNowcJuTauL3zTxr1zcH [CONTRACT_PATH]/opcodes/packunpack_rev_cty.tz -expruSamDrL2Dh4zp92cVgfV7ETT7VcnqACDVcvnafi3qgBZq9v3PL [CONTRACT_PATH]/opcodes/pair_id.tz -expru3WFEX5bVjBUkZzuWspLG18hy5jTzbr2WtKEYpfPHGpDFvcqhd [CONTRACT_PATH]/opcodes/pairing_check.tz -expru2U5Bi7ehgkQvP7Qmij4c8gkSFUBNtiCyXMX3WwGjEdRRZc5x1 [CONTRACT_PATH]/opcodes/pexec.tz -expruPr8QtATywJFqPjDhF7gyqdF15L6J7pxgpypzorEvtubdJN8U2 [CONTRACT_PATH]/opcodes/pexec_2.tz -exprvBUenyTMJKwERZ1ULzMVrJ1owqymBF32f627arqtFUzMpaMvbC [CONTRACT_PATH]/opcodes/proxy.tz -exprvPaPcYHvKmnyBMaYXtp6ZuaSEHWr5y92bcroKKppAZvF4RvcWE [CONTRACT_PATH]/opcodes/ret_int.tz -expru8MKLXqiNRYnPccUN4if3VnWfthDy24K4zuJrFh2JaMmmh6Rii [CONTRACT_PATH]/opcodes/reverse.tz -expruta4Bjo3FggDcvZDzEVwzeTcdZptzkJZyFEkdB8suFGbMVtT2Z [CONTRACT_PATH]/opcodes/reverse_loop.tz -exprueR2MPCHUFtPjMZXE57X3EsysuWJXGRz8ZgcPJj21UySLqULV1 [CONTRACT_PATH]/opcodes/sapling_empty_state.tz -exprvSNMswzVUk47vqs4wTGipDb3qDKVUwNBDwXtGzjCprEYx4nWPo [CONTRACT_PATH]/opcodes/self.tz -exprtzokY2FHvPvB9YHSi8MM5YUbPdUPLi7tEKkp8BKongPb2zrZch [CONTRACT_PATH]/opcodes/self_address.tz -exprukm3NvsYbS9ymX3MuXh6LciuF8ef2qt8ktTGaXtyFxCpisMBdD [CONTRACT_PATH]/opcodes/self_address_after_fib_view.tz -expruV4HCC6sRdEL5HyXVC9gTkMZbh8BnxXsKZDTydtztRhDUT3qxa [CONTRACT_PATH]/opcodes/self_address_after_nonexistent_view.tz -expruUWxiqrD566farETUi3VChWNZ5teemC3q4G8tf83xhjTwRSEws [CONTRACT_PATH]/opcodes/self_address_after_view.tz -exprvQ8rhMFcCrwNSLZERQSQ9TMR1Tsnyj7R1jS8J2UESKXUoJuLTV [CONTRACT_PATH]/opcodes/self_after_fib_view.tz -exprvKoMUnUmthGpVmQfYkLa8F6GRwmU36D9jYXNG8j8QbQYNWUoAC [CONTRACT_PATH]/opcodes/self_after_nonexistent_view.tz -exprtXqpN6sqTKUVNissE3rkzKGSBuW2gTh8pRb3XyHZ4dpaAqLnhL [CONTRACT_PATH]/opcodes/self_after_view.tz -exprvDVUQXNsfs9FiHkMSofonWCWcBfYbfxeQy9DRaa5Tnbw1XM18Y [CONTRACT_PATH]/opcodes/self_with_default_entrypoint.tz -expruXGf2YpXKkr74mcv83fQ6bztVD1RBoFXaEnAd9bidnRXcfD3Nj [CONTRACT_PATH]/opcodes/self_with_entrypoint.tz -exprudmJ37Q8ZASPbZSSBfy5UezxLhniszTVkLAB8QKvxkav4gVVYr [CONTRACT_PATH]/opcodes/sender.tz -exprtufbuVP6RKm1PGPUQnZy6dqwxCha1jbafqyVGpCUNWeUVpcBhc [CONTRACT_PATH]/opcodes/sender_after_fib_view.tz -exprug4Jd1WdLqrZWiG8PsGDETN1ahpX5PycBrdNWadM96M5SjvLae [CONTRACT_PATH]/opcodes/sender_after_nonexistent_view.tz -exprvR3pRxvwuwM1c4Jk1zRfuDabRPwLnazpSsySQkzymatANufH9h [CONTRACT_PATH]/opcodes/sender_after_view.tz -exprurSxmHBRCHUxtXcqNkPA8UE6gaFeJa19bBhq1CarZ3CZuAzShs [CONTRACT_PATH]/opcodes/set_car.tz -expruogQk6tG5W7CtZrcMzsRtJ1f9moG9y5Qg5j29NATiaSywvQCcS [CONTRACT_PATH]/opcodes/set_cdr.tz -exprvCt5LtbC3mLLWHdvyxGcX3ND21Ym5GayCvePEHHGXAtgWu32sJ [CONTRACT_PATH]/opcodes/set_delegate.tz -expru133Wm63xA1qs5ymovjbP3N3iwPoTMcdUsbUqqbTf896jU78WR [CONTRACT_PATH]/opcodes/set_id.tz -expru151wgMY5reA7WVbnvkHrh9MVnfYFbCDaiE2aTGmkKACu2ZbJA [CONTRACT_PATH]/opcodes/set_iter.tz -expru13v2dm35MgMgTbwDJ4nEwNjRTau8mqztAyxGxXVbHNmskAA2q [CONTRACT_PATH]/opcodes/set_member.tz -expruE8c9EzG6kYQdp5RQXrAt2CekSFXVtKUzNDUnpVTDygEBP7VvF [CONTRACT_PATH]/opcodes/set_size.tz -exprtzSBcPatLYnGe5xtsSNGVjNBLMmHefxsQ7Q2QNjDMGmADKdWUC [CONTRACT_PATH]/opcodes/sets.tz -exprteVcB53uqnwQsZMTsBojwez6tkgRqj1qWCQTLgaQWxQGiNWXEE [CONTRACT_PATH]/opcodes/sha3.tz -exprvPbB5NtiV87RARduqoXtMoRjjy6jX8WYrfiu3RDjQrTKxPQnoe [CONTRACT_PATH]/opcodes/shifts.tz -exprtnS2EjwJ3MdSWS7R6UbZMqFoUHj1JpUhhtJacXdfmmzRNHL33W [CONTRACT_PATH]/opcodes/slice.tz -exprugZMQtZN7safMU7hV5QpM7nh7Vi5ur9sGjeWsmGRkW1ETox8uR [CONTRACT_PATH]/opcodes/slice_bytes.tz -exprvCqvDAp66YnPaZDdaAkCNafoGtw1fEuWaLxMFeMnX6oqrb93nP [CONTRACT_PATH]/opcodes/slices.tz -exprtzW4jh4MgY6iXgiCXft5q3Mig5XXANHn9CmcL8ApTrdnQgWzAm [CONTRACT_PATH]/opcodes/source.tz -exprvD9HJMfLEUdamfH9U8ozBaxA7hYVRMbK7At6sUqFMmhZ6UorWv [CONTRACT_PATH]/opcodes/split_bytes.tz -exprvJcmHwozD2DTtagjJJfyPgoCvBx5bMzXAkrsteYVvxeMr9SWm3 [CONTRACT_PATH]/opcodes/split_string.tz -expruDY992zB37mWpZwFQCrfDbkwmrCmjSHD4fzQcW1z1AeWeW8M3r [CONTRACT_PATH]/opcodes/store_bls12_381_fr.tz -expruZAkBxtwSXuMp6ZDNp41mJ6uZ4bw7RF9HNzJS9EnzTLxVhQ4SB [CONTRACT_PATH]/opcodes/store_bls12_381_g1.tz -expruZfFC7WkBQhK4Ksg5k5WxBamF4PvH2NGCxcd4DHUkKfeqQEBUe [CONTRACT_PATH]/opcodes/store_bls12_381_g2.tz -exprv8K6ceBpFH5SFjQm4BRYSLJCHQBFeQU6BFTdvQSRPaPkzdLyAL [CONTRACT_PATH]/opcodes/store_input.tz -exprvStWRo24QuETruMmMqkmLme6UAMHuTRNNq9Lq65oFgUvQmJGPV [CONTRACT_PATH]/opcodes/store_now.tz -exprtZPsTsBtNf9hjv7Yfda2EV4Sz3iaHpk4NkYHcKteXbsyQ9d6pH [CONTRACT_PATH]/opcodes/str_id.tz -exprv4UZUuBDCZZjtW5kaezZjaKqpi1GN6vxHsvQNNkFktnaEbDb1M [CONTRACT_PATH]/opcodes/sub_timestamp_delta.tz -expruVuXhQmoBMzZjPeY7VQSuJxefBBTuPyNR7PGnYhwouo9zKg3T1 [CONTRACT_PATH]/opcodes/subset.tz -exprtz2jbsXuMMPAXYAGJZqjuBp8iF38XadE3YuZoC2W5NkyhhHMuq [CONTRACT_PATH]/opcodes/tez_add_sub.tz -exprugbVFDGWcSSozyN3EK3AcdwtPeES3ao45HNogWc5V8fsJ8NsSP [CONTRACT_PATH]/opcodes/ticket_bad.tz -exprtvedUmBuu66gdQXWpEJNQBU96bnUVQmrWWLAbcdsCLV4Rwa34K [CONTRACT_PATH]/opcodes/ticket_big_store.tz -expruqx789AMcKUYwDeeeRvSnwdCw8gMVvWA6vuzPzBQwBM2qcDXJB [CONTRACT_PATH]/opcodes/ticket_join.tz -exprvMp1LX8aeyEq9NiMXGyD34J4offZDANGRwFTxoEWXumEsDdAP8 [CONTRACT_PATH]/opcodes/ticket_read.tz -exprtvtEFi6v3awAwbHivJkjki6mDNivewiCBeJDJT78PqWtq7VyUD [CONTRACT_PATH]/opcodes/ticket_split.tz -exprtifPFaLqHvR9uGWbeLj5r3YVBnKaawt12q3BMhM9wsUdM9dFNy [CONTRACT_PATH]/opcodes/ticket_store-2.tz -exprvJGjz1EDdnAPWZQ7ZngDNDDDXnxA2VY6SHdHKu8LxqcVHd3E6z [CONTRACT_PATH]/opcodes/ticket_store.tz -expruhNaUWmTNpmFWSXUgf1ZjgcUXmjtXGaMumzteyFYzT9CMmU4wc [CONTRACT_PATH]/opcodes/ticketer-2.tz -exprvPfYzs3x1V67saypcaPGwj5rnuKsb3tFi2VtqX7gtP4W3sjfye [CONTRACT_PATH]/opcodes/ticketer.tz -expruhV9RSEPAtKAUhBbdTw5gPFdjcKk8zr7cVLSsGtmJuH3o7VXXo [CONTRACT_PATH]/opcodes/transfer_amount.tz -expru3MSjYZRmQi3yiN6gYa4X6rs88XLWH4H8ivzrCvxs8z8cJfu4Z [CONTRACT_PATH]/opcodes/transfer_tokens.tz -exprtbACDcFtDfEwsBA5LAG13uMRAjnQsFjzNELMS7jQ87bcqgdE6r [CONTRACT_PATH]/opcodes/uncomb.tz -exprufJpS3BWpgv4QBaBEMucbn1jsVpdqEGLLMfXjDuKGPRGCpZUkj [CONTRACT_PATH]/opcodes/unpair.tz -exprv4ACaZe4aECCfG93NGVVHbQBNQ5Atxtju5vWASZSEp5sLECcjg [CONTRACT_PATH]/opcodes/update_big_map.tz -expruWzM36ATA3fAee4WHDS4vvMeewkwhya1fZaa6HFPbjwt9vvGpg [CONTRACT_PATH]/opcodes/utxo_read.tz -expru3YgRPQBAnTWgKytSMs3tRj7dMgtWUxo75b1pUFrTLscKy2byF [CONTRACT_PATH]/opcodes/utxor.tz -expruJxgC2Q8Ubt8tPyQbZ41j6w4b8yw5f6bxjrMMM81TmMC9x5Lrc [CONTRACT_PATH]/opcodes/view_fib.tz -expru9EavkgPCUAwHccJf9j1t4aTTssPKoBkCqC4YNr12kxXSwqFqD [CONTRACT_PATH]/opcodes/view_mutual_recursion.tz -exprv4QXQuZtQE7CpKyecjrXJ8U2ovU1qjUKtw37J6kAEmu3fAKyN5 [CONTRACT_PATH]/opcodes/view_op_add.tz -exprugGjNh2tTsofJyhkNMrQVJnkyLydJywNVMAXL9rW3nhnCmRd3F [CONTRACT_PATH]/opcodes/view_op_constant.tz -exprtn56ZZ3mXHoz9GMS9HGMfmgayukvVXub8zXeDKbE4U7L5L8dXX [CONTRACT_PATH]/opcodes/view_op_id.tz -exprtaNDFRcdw8SB4Bz1a6CKARxZaoxpc6G2hnJYedp1iZgJqEwMNV [CONTRACT_PATH]/opcodes/view_op_nonexistent_addr.tz -exprtmA9Auh8GAHpvKP2qkVhiaRCtokWcw7qg31CaxbouJW1g8yYK7 [CONTRACT_PATH]/opcodes/view_op_nonexistent_func.tz -exprubMFU6xrnHREoXUZinEeV3PuZBjSw35M6gti7tyQ83S6LTKja1 [CONTRACT_PATH]/opcodes/view_op_test_step_contants.tz -exprtj9pixxS7UHchhthZa8zdU2GAjvW7oA7QEMA3PHgf88vmAEjFb [CONTRACT_PATH]/opcodes/view_op_toplevel_inconsistent_input_type.tz -exprurrbjDgnipRBhqb7pPLQFAgtPm5jrpwJjJL5ZvQyFJZzGvqteY [CONTRACT_PATH]/opcodes/view_op_toplevel_inconsistent_output_type.tz -exprvSPcq1w7iTMA3LjQcHegnRUQ621sqQLRJm1Zh4tjHCkmeZV268 [CONTRACT_PATH]/opcodes/view_rec.tz -exprv1LkSMvSyZSBrg9Tf2PdcoiWDYPz2npmYb7rH6bWx2sYMAHMgg [CONTRACT_PATH]/opcodes/view_toplevel_lib.tz -expruF13NKWWyF51seiYv4tsb55dZHYViNWDKTmhLq9b1LXXenwaB2 [CONTRACT_PATH]/opcodes/voting_power.tz -exprvSZMaiMSbKgRYm1W4rcoBGN21bPu8NMQuYBH9ujhXGeHhdtVGk [CONTRACT_PATH]/opcodes/xor.tz diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fac.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fac.tz].out deleted file mode 100644 index f2257eada560..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fac.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_fac.tz] - -exprv5Zq1iL1bPVUnL4TZZcmuezBhf3BBoCa3HyktPw1AivsHv1FnP diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fib.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fib.tz].out deleted file mode 100644 index 4f7a53dfaa93..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fib.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_fib.tz] - -expruJxgC2Q8Ubt8tPyQbZ41j6w4b8yw5f6bxjrMMM81TmMC9x5Lrc diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_mutual_recursion.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_mutual_recursion.tz].out deleted file mode 100644 index 66d9977f1371..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_mutual_recursion.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_mutual_recursion.tz] - -expru9EavkgPCUAwHccJf9j1t4aTTssPKoBkCqC4YNr12kxXSwqFqD diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_add.tz].out deleted file mode 100644 index 60b9ac6aea77..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_add.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_add.tz] - -exprv4QXQuZtQE7CpKyecjrXJ8U2ovU1qjUKtw37J6kAEmu3fAKyN5 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_id.tz].out deleted file mode 100644 index a723a8a7ccb7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_id.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_id.tz] - -exprtn56ZZ3mXHoz9GMS9HGMfmgayukvVXub8zXeDKbE4U7L5L8dXX diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_addr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_addr.tz].out deleted file mode 100644 index fe504296577a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_addr.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_nonexistent_addr.tz] - -exprtaNDFRcdw8SB4Bz1a6CKARxZaoxpc6G2hnJYedp1iZgJqEwMNV diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_func.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_func.tz].out deleted file mode 100644 index dfa7334690a8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_func.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_nonexistent_func.tz] - -exprtmA9Auh8GAHpvKP2qkVhiaRCtokWcw7qg31CaxbouJW1g8yYK7 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_test_step_contants.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_test_step_contants.tz].out deleted file mode 100644 index 34f3e03afa2e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_test_step_contants.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_test_step_contants.tz] - -exprubMFU6xrnHREoXUZinEeV3PuZBjSw35M6gti7tyQ83S6LTKja1 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_input_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_input_type.tz].out deleted file mode 100644 index 3c8e63008161..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_input_type.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_toplevel_inconsistent_input_type.tz] - -exprtj9pixxS7UHchhthZa8zdU2GAjvW7oA7QEMA3PHgf88vmAEjFb diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_output_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_output_type.tz].out deleted file mode 100644 index f8cf06ec46e1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_output_type.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_toplevel_inconsistent_output_type.tz] - -exprurrbjDgnipRBhqb7pPLQFAgtPm5jrpwJjJL5ZvQyFJZzGvqteY diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_rec.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_rec.tz].out deleted file mode 100644 index b16b6437f6fd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_rec.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_rec.tz] - -exprvSPcq1w7iTMA3LjQcHegnRUQ621sqQLRJm1Zh4tjHCkmeZV268 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_toplevel_lib.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_toplevel_lib.tz].out deleted file mode 100644 index a9ab2c1b772f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_toplevel_lib.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_toplevel_lib.tz] - -exprv1LkSMvSyZSBrg9Tf2PdcoiWDYPz2npmYb7rH6bWx2sYMAHMgg diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_receiver.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_receiver.out deleted file mode 100644 index 56b8f1f52cca..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_receiver.out +++ /dev/null @@ -1,53 +0,0 @@ -tests_012/test_contract.py::TestSelfAddressTransfer::test_self_address_originate_receiver - -Node is bootstrapped. -Estimated gas: 1413.723 units (will add 100 for safety) -Estimated storage: 340 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000462 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1514 - Storage limit: 360 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000462 - payload fees(the block proposer) ....... +ꜩ0.000462 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ0 - Script: - { parameter (lambda unit address) ; - storage unit ; - code { UNPAIR ; - UNIT ; - EXEC ; - SELF_ADDRESS ; - ASSERT_CMPEQ ; - NIL operation ; - PAIR } } - Initial storage: Unit - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 83 bytes - Paid storage size diff: 83 bytes - Consumed gas: 1413.723 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.02075 - storage fees ........................... +ꜩ0.02075 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - -New contract [CONTRACT_HASH] originated. -Contract memorized as self_address_receiver. -Injected block at minimal timestamp -[ [ "[BLOCK_HASH]" ], [], [], - [ "[BLOCK_HASH]" ] ] diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_sender.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_sender.out deleted file mode 100644 index 6bd21b2b7f5e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_sender.out +++ /dev/null @@ -1,52 +0,0 @@ -tests_012/test_contract.py::TestSelfAddressTransfer::test_self_address_originate_sender - -Node is bootstrapped. -Estimated gas: 1413.674 units (will add 100 for safety) -Estimated storage: 339 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000461 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1514 - Storage limit: 359 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000461 - payload fees(the block proposer) ....... +ꜩ0.000461 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ0 - Script: - { parameter (contract (lambda unit address)) ; - storage unit ; - code { CAR ; - BALANCE ; - LAMBDA unit address { DROP ; SELF_ADDRESS } ; - TRANSFER_TOKENS ; - DIP { UNIT ; NIL operation } ; - CONS ; - PAIR } } - Initial storage: Unit - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 82 bytes - Paid storage size diff: 82 bytes - Consumed gas: 1413.674 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0205 - storage fees ........................... +ꜩ0.0205 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - -New contract [CONTRACT_HASH] originated. -Contract memorized as self_address_sender. -Injected block at minimal timestamp -[ [], [], [], [ "[BLOCK_HASH]" ] ] diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_send_self_address.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_send_self_address.out deleted file mode 100644 index 8532ebd1d96d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_send_self_address.out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract.py::TestSelfAddressTransfer::test_send_self_address - -Node is bootstrapped. -Estimated gas: 5413.006 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000846 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 5514 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000846 - payload fees(the block proposer) ....... +ꜩ0.000846 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: "[CONTRACT_HASH]" - This transaction was successfully applied - Updated storage: Unit - Storage size: 82 bytes - Consumed gas: 3353.748 - Internal operations: - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: { DROP ; SELF_ADDRESS } - This transaction was successfully applied - Updated storage: Unit - Storage size: 83 bytes - Consumed gas: 2059.258 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--accounts.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--accounts.tz].out deleted file mode 100644 index 51db6b263fa1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--accounts.tz].out +++ /dev/null @@ -1,379 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/accounts.tz] - -Well typed -Gas remaining: 1039925.145 units remaining -{ parameter - (or (key_hash %Initialize) - (pair %Withdraw (key %from) (pair (mutez %withdraw_amount) (signature %sig)))) ; - storage (map :stored_balance key_hash mutez) ; - code { DUP - /* [ pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - CAR - /* [ @parameter or (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig)) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - IF_LEFT - { DUP - /* [ @parameter.Initialize key_hash : @parameter.Initialize key_hash - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - DIIP { CDR %stored_balance - /* [ @stored_balance map :stored_balance key_hash mutez ] */ ; - DUP - /* [ @stored_balance map :stored_balance key_hash mutez - : @stored_balance map :stored_balance key_hash mutez ] */ } - /* [ @parameter.Initialize key_hash : @parameter.Initialize key_hash - : @stored_balance map :stored_balance key_hash mutez - : @stored_balance map :stored_balance key_hash mutez ] */ ; - DIP { SWAP - /* [ @stored_balance map :stored_balance key_hash mutez - : @parameter.Initialize key_hash - : @stored_balance map :stored_balance key_hash mutez ] */ } - /* [ @parameter.Initialize key_hash - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Initialize key_hash - : @stored_balance map :stored_balance key_hash mutez ] */ ; - GET @opt_prev_balance - /* [ @opt_prev_balance option mutez : @parameter.Initialize key_hash - : @stored_balance map :stored_balance key_hash mutez ] */ ; - IF_SOME - { RENAME @previous_balance - /* [ @previous_balance mutez : @parameter.Initialize key_hash - : @stored_balance map :stored_balance key_hash mutez ] */ ; - AMOUNT - /* [ @amount mutez : @previous_balance mutez : @parameter.Initialize key_hash - : @stored_balance map :stored_balance key_hash mutez ] */ ; - ADD - /* [ mutez : @parameter.Initialize key_hash - : @stored_balance map :stored_balance key_hash mutez ] */ ; - SOME - /* [ option mutez : @parameter.Initialize key_hash - : @stored_balance map :stored_balance key_hash mutez ] */ ; - SWAP - /* [ @parameter.Initialize key_hash : option mutez - : @stored_balance map :stored_balance key_hash mutez ] */ ; - UPDATE - /* [ @stored_balance map :stored_balance key_hash mutez ] */ ; - NIL operation - /* [ list operation : @stored_balance map :stored_balance key_hash mutez ] */ ; - PAIR - /* [ pair (list operation) (map :stored_balance @stored_balance key_hash mutez) ] */ } - { DIP { AMOUNT - /* [ @amount mutez : @stored_balance map :stored_balance key_hash mutez ] */ ; - SOME - /* [ option mutez : @stored_balance map :stored_balance key_hash mutez ] */ } - /* [ @parameter.Initialize key_hash : option mutez - : @stored_balance map :stored_balance key_hash mutez ] */ ; - UPDATE - /* [ @stored_balance map :stored_balance key_hash mutez ] */ ; - NIL operation - /* [ list operation : @stored_balance map :stored_balance key_hash mutez ] */ ; - PAIR - /* [ pair (list operation) (map :stored_balance @stored_balance key_hash mutez) ] */ } } - { DUP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - DUP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - DUP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - DUP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - CAR %from - /* [ key - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - DIIP { CDAR %withdraw_amount ; - PACK - /* [ @packed bytes - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - BLAKE2B @signed_amount - /* [ @signed_amount bytes - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ } - /* [ key - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @signed_amount bytes - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - DIP { CDDR %sig } - /* [ key : signature : @signed_amount bytes - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - CHECK_SIGNATURE - /* [ bool - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - IF { /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ } - { PUSH string - "Bad signature" - /* [ string - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : pair (or @parameter - (key_hash %Initialize) - (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) - (map :stored_balance @stored_balance key_hash mutez) ] */ ; - FAILWITH - /* [] */ } ; - DIIP { CDR %stored_balance - /* [ @stored_balance map :stored_balance key_hash mutez ] */ ; - DUP - /* [ @stored_balance map :stored_balance key_hash mutez - : @stored_balance map :stored_balance key_hash mutez ] */ } - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @stored_balance map :stored_balance key_hash mutez ] */ ; - CAR %from - /* [ key - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @stored_balance map :stored_balance key_hash mutez ] */ ; - HASH_KEY @from_hash - /* [ @from_hash key_hash - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @stored_balance map :stored_balance key_hash mutez ] */ ; - DUP - /* [ @from_hash key_hash : @from_hash key_hash - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @stored_balance map :stored_balance key_hash mutez ] */ ; - DIP { DIP { SWAP - /* [ @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ } - /* [ @from_hash key_hash : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - SWAP - /* [ @stored_balance map :stored_balance key_hash mutez : @from_hash key_hash - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ } - /* [ @from_hash key_hash : @stored_balance map :stored_balance key_hash mutez - : @from_hash key_hash - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - GET - /* [ option mutez : @from_hash key_hash - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - IF_NONE - { PUSH string - "Account does not exist" - /* [ string : @from_hash key_hash - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - PAIR - /* [ pair string (key_hash @from_hash) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - FAILWITH - /* [] */ } - { RENAME @previous_balance - /* [ @previous_balance mutez : @from_hash key_hash - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - DIP { DROP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ } - /* [ @previous_balance mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - DUP - /* [ @previous_balance mutez : @previous_balance mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - DIIP { DUP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - CDAR %withdraw_amount ; - DUP - /* [ mutez : mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ } - /* [ @previous_balance mutez : @previous_balance mutez : mutez : mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - DIP { CMPLT @not_enough } - /* [ @previous_balance mutez : @not_enough bool : mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - SWAP - /* [ @not_enough bool : @previous_balance mutez : mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - IF { PUSH string - "Not enough funds" - /* [ string : @previous_balance mutez : mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - FAILWITH - /* [] */ } - { SUB_MUTEZ @new_balance - /* [ @new_balance option mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - ASSERT_SOME ; - DIP { DUP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - DIP { SWAP - /* [ @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ } - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ } - /* [ @new_balance.some mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; - DUP - /* [ @new_balance.some mutez : @new_balance.some mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; - PUSH @zero - mutez - 0 - /* [ @zero mutez : @new_balance.some mutez : @new_balance.some mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; - CMPEQ @null_balance ; - IF { DROP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; - NONE @new_balance - mutez - /* [ @new_balance option mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ } - { SOME @new_balance - /* [ @new_balance option mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ } ; - SWAP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @new_balance option mutez - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; - CAR %from - /* [ key : @new_balance option mutez - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; - HASH_KEY @from_hash - /* [ @from_hash key_hash : @new_balance option mutez - : @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; - UPDATE - /* [ @stored_balance map :stored_balance key_hash mutez - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; - SWAP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - DUP - /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) - : @stored_balance map :stored_balance key_hash mutez ] */ ; - CDAR %withdraw_amount ; - DIP { CAR %from - /* [ key : @stored_balance map :stored_balance key_hash mutez ] */ ; - HASH_KEY @from_hash - /* [ @from_hash key_hash : @stored_balance map :stored_balance key_hash mutez ] */ ; - IMPLICIT_ACCOUNT @from_account - /* [ @from_account contract unit - : @stored_balance map :stored_balance key_hash mutez ] */ } - /* [ mutez : @from_account contract unit - : @stored_balance map :stored_balance key_hash mutez ] */ ; - UNIT - /* [ unit : mutez : @from_account contract unit - : @stored_balance map :stored_balance key_hash mutez ] */ ; - TRANSFER_TOKENS @withdraw_transfer_op - /* [ @withdraw_transfer_op operation - : @stored_balance map :stored_balance key_hash mutez ] */ ; - NIL operation - /* [ list operation : @withdraw_transfer_op operation - : @stored_balance map :stored_balance key_hash mutez ] */ ; - SWAP - /* [ @withdraw_transfer_op operation : list operation - : @stored_balance map :stored_balance key_hash mutez ] */ ; - CONS - /* [ list operation : @stored_balance map :stored_balance key_hash mutez ] */ ; - PAIR - /* [ pair (list operation) (map :stored_balance @stored_balance key_hash mutez) ] */ } } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1.tz].out deleted file mode 100644 index 718ebecbfef5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/add1.tz] - -Well typed -Gas remaining: 1039996.134 units remaining -{ parameter int ; - storage int ; - code { CAR - /* [ @parameter int ] */ ; - PUSH int 1 - /* [ int : @parameter int ] */ ; - ADD - /* [ int ] */ ; - NIL operation - /* [ list operation : int ] */ ; - PAIR - /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1_list.tz].out deleted file mode 100644 index b82e5d9c4955..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1_list.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/add1_list.tz] - -Well typed -Gas remaining: 1039995.173 units remaining -{ parameter (list int) ; - storage (list int) ; - code { CAR - /* [ @parameter list int ] */ ; - MAP { PUSH int 1 /* [ int : @parameter.elt int ] */ ; ADD /* [ int ] */ } - /* [ list int ] */ ; - NIL operation - /* [ list operation : list int ] */ ; - PAIR - /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--after_strategy.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--after_strategy.tz].out deleted file mode 100644 index bb2a0fcd46b0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--after_strategy.tz].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/after_strategy.tz] - -Well typed -Gas remaining: 1039989.643 units remaining -{ parameter nat ; - storage (pair (pair nat bool) timestamp) ; - code { DUP - /* [ pair (nat @parameter) (pair @storage (pair nat bool) timestamp) - : pair (nat @parameter) (pair @storage (pair nat bool) timestamp) ] */ ; - CAR - /* [ @parameter nat - : pair (nat @parameter) (pair @storage (pair nat bool) timestamp) ] */ ; - DIP { CDDR ; - DUP - /* [ timestamp : timestamp ] */ ; - NOW - /* [ @now timestamp : timestamp : timestamp ] */ ; - CMPGT } - /* [ @parameter nat : bool : timestamp ] */ ; - PAIR - /* [ pair (nat @parameter) bool : timestamp ] */ ; - PAIR - /* [ pair (pair (nat @parameter) bool) timestamp ] */ ; - NIL operation - /* [ list operation : pair (pair (nat @parameter) bool) timestamp ] */ ; - PAIR - /* [ pair (list operation) (pair (nat @parameter) bool) timestamp ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--always.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--always.tz].out deleted file mode 100644 index 6c9c14fd13e0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--always.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/always.tz] - -Well typed -Gas remaining: 1039994.981 units remaining -{ parameter nat ; - storage (pair nat bool) ; - code { CAR - /* [ @parameter nat ] */ ; - PUSH bool True - /* [ bool : @parameter nat ] */ ; - SWAP - /* [ @parameter nat : bool ] */ ; - PAIR - /* [ pair (nat @parameter) bool ] */ ; - NIL operation - /* [ list operation : pair (nat @parameter) bool ] */ ; - PAIR - /* [ pair (list operation) (nat @parameter) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--append.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--append.tz].out deleted file mode 100644 index db0f1320bc3a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--append.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/append.tz] - -Well typed -Gas remaining: 1039991.379 units remaining -{ parameter (pair (list int) (list int)) ; - storage (list int) ; - code { CAR - /* [ @parameter pair (list int) (list int) ] */ ; - UNPAIR - /* [ list int : list int ] */ ; - NIL int - /* [ list int : list int : list int ] */ ; - SWAP - /* [ list int : list int : list int ] */ ; - ITER { CONS /* [ list int : list int ] */ } - /* [ list int : list int ] */ ; - ITER { CONS /* [ list int ] */ } - /* [ list int ] */ ; - NIL operation - /* [ list operation : list int ] */ ; - PAIR - /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--at_least.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--at_least.tz].out deleted file mode 100644 index d86bc2879271..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--at_least.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/at_least.tz] - -Well typed -Gas remaining: 1039992.950 units remaining -{ parameter unit ; - storage mutez ; - code { CDR - /* [ @storage mutez ] */ ; - DUP - /* [ @storage mutez : @storage mutez ] */ ; - AMOUNT - /* [ @amount mutez : @storage mutez : @storage mutez ] */ ; - CMPLT ; - IF { FAIL } - { NIL operation - /* [ list operation : @storage mutez ] */ ; - PAIR - /* [ pair (list operation) (mutez @storage) ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--auction.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--auction.tz].out deleted file mode 100644 index 7d56aeb3cdb4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--auction.tz].out +++ /dev/null @@ -1,87 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/auction.tz] - -Well typed -Gas remaining: 1039972.258 units remaining -{ parameter key_hash ; - storage (pair timestamp (pair mutez key_hash)) ; - code { DUP - /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; - CDAR ; - DUP - /* [ timestamp : timestamp - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; - NOW - /* [ @now timestamp : timestamp : timestamp - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; - CMPGT ; - IF { FAIL } - { /* [ timestamp - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ } ; - SWAP - /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) - : timestamp ] */ ; - DUP - /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) - : timestamp ] */ ; - CAR - /* [ @parameter key_hash - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) - : timestamp ] */ ; - DIP { CDDR } - /* [ @parameter key_hash : pair mutez key_hash : timestamp ] */ ; - AMOUNT - /* [ @amount mutez : @parameter key_hash : pair mutez key_hash : timestamp ] */ ; - PAIR - /* [ pair (mutez @amount) (key_hash @parameter) : pair mutez key_hash - : timestamp ] */ ; - SWAP - /* [ pair mutez key_hash : pair (mutez @amount) (key_hash @parameter) - : timestamp ] */ ; - DIP { SWAP - /* [ timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; - PAIR - /* [ pair timestamp (mutez @amount) (key_hash @parameter) ] */ } - /* [ pair mutez key_hash - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - DUP - /* [ pair mutez key_hash : pair mutez key_hash - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - CAR - /* [ mutez : pair mutez key_hash - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - AMOUNT - /* [ @amount mutez : mutez : pair mutez key_hash - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - CMPLE ; - IF { FAIL } - { /* [ pair mutez key_hash - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ } ; - DUP - /* [ pair mutez key_hash : pair mutez key_hash - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - CAR - /* [ mutez : pair mutez key_hash - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - DIP { CDR - /* [ key_hash : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - IMPLICIT_ACCOUNT - /* [ contract unit : pair timestamp (mutez @amount) (key_hash @parameter) ] */ } - /* [ mutez : contract unit - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - UNIT - /* [ unit : mutez : contract unit - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - TRANSFER_TOKENS - /* [ operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - NIL operation - /* [ list operation : operation - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - SWAP - /* [ operation : list operation - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - CONS - /* [ list operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - PAIR - /* [ pair (list operation) timestamp (mutez @amount) (key_hash @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--bad_lockup.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--bad_lockup.tz].out deleted file mode 100644 index 8596f4336905..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--bad_lockup.tz].out +++ /dev/null @@ -1,71 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/bad_lockup.tz] - -Well typed -Gas remaining: 1039972.793 units remaining -{ parameter unit ; - storage (pair timestamp (pair address address)) ; - code { CDR - /* [ @storage pair timestamp address address ] */ ; - DUP - /* [ @storage pair timestamp address address - : @storage pair timestamp address address ] */ ; - CAR - /* [ timestamp : @storage pair timestamp address address ] */ ; - NOW - /* [ @now timestamp : timestamp : @storage pair timestamp address address ] */ ; - CMPLT ; - IF { FAIL } { /* [ @storage pair timestamp address address ] */ } ; - DUP - /* [ @storage pair timestamp address address - : @storage pair timestamp address address ] */ ; - CDAR ; - CONTRACT - unit - /* [ @contract option (contract unit) - : @storage pair timestamp address address ] */ ; - ASSERT_SOME ; - PUSH mutez - 100000000 - /* [ mutez : @contract.some contract unit - : @storage pair timestamp address address ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : @storage pair timestamp address address ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage pair timestamp address address ] */ ; - SWAP - /* [ @storage pair timestamp address address : operation ] */ ; - DUP - /* [ @storage pair timestamp address address - : @storage pair timestamp address address : operation ] */ ; - CDDR ; - CONTRACT - unit - /* [ @contract option (contract unit) : @storage pair timestamp address address - : operation ] */ ; - ASSERT_SOME ; - PUSH mutez - 100000000 - /* [ mutez : @contract.some contract unit - : @storage pair timestamp address address : operation ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : @storage pair timestamp address address : operation ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage pair timestamp address address : operation ] */ ; - DIP { SWAP /* [ operation : @storage pair timestamp address address ] */ } - /* [ operation : operation : @storage pair timestamp address address ] */ ; - NIL operation - /* [ list operation : operation : operation - : @storage pair timestamp address address ] */ ; - SWAP - /* [ operation : list operation : operation - : @storage pair timestamp address address ] */ ; - CONS - /* [ list operation : operation : @storage pair timestamp address address ] */ ; - SWAP - /* [ operation : list operation : @storage pair timestamp address address ] */ ; - CONS - /* [ list operation : @storage pair timestamp address address ] */ ; - PAIR - /* [ pair (list operation) (pair @storage timestamp address address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--big_map_union.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--big_map_union.tz].out deleted file mode 100644 index f10b57e00aad..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--big_map_union.tz].out +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/big_map_union.tz] - -Well typed -Gas remaining: 1039983.939 units remaining -{ parameter (list (pair string int)) ; - storage (pair (big_map string int) unit) ; - code { UNPAPAIR ; - ITER { UNPAIR - /* [ string : int : big_map string int : unit ] */ ; - DUUUP - /* [ big_map string int : string : int : big_map string int : unit ] */ ; - DUUP - /* [ string : big_map string int : string : int : big_map string int : unit ] */ ; - GET - /* [ option int : string : int : big_map string int : unit ] */ ; - IF_NONE - { PUSH int 0 /* [ int : string : int : big_map string int : unit ] */ } - { /* [ @some int : string : int : big_map string int : unit ] */ } ; - SWAP - /* [ string : int : int : big_map string int : unit ] */ ; - DIP { ADD - /* [ int : big_map string int : unit ] */ ; - SOME - /* [ option int : big_map string int : unit ] */ } - /* [ string : option int : big_map string int : unit ] */ ; - UPDATE - /* [ big_map string int : unit ] */ } - /* [ big_map string int : unit ] */ ; - PAIR - /* [ pair (big_map string int) unit ] */ ; - NIL operation - /* [ list operation : pair (big_map string int) unit ] */ ; - PAIR - /* [ pair (list operation) (big_map string int) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cadr_annotation.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cadr_annotation.tz].out deleted file mode 100644 index c9209094fe5c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cadr_annotation.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/cadr_annotation.tz] - -Well typed -Gas remaining: 1039994.745 units remaining -{ parameter (pair (pair %p1 unit (string %no_name)) bool) ; - storage unit ; - code { CAR @param - /* [ @param pair (pair %p1 unit (string %no_name)) bool ] */ ; - CADR @name %no_name ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--concat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--concat.tz].out deleted file mode 100644 index c69756696c96..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--concat.tz].out +++ /dev/null @@ -1,28 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/concat.tz] - -Well typed -Gas remaining: 1039992.618 units remaining -{ parameter string ; - storage string ; - code { DUP - /* [ pair (string @parameter) (string @storage) - : pair (string @parameter) (string @storage) ] */ ; - DIP { CDR - /* [ @storage string ] */ ; - NIL string - /* [ list string : @storage string ] */ ; - SWAP - /* [ @storage string : list string ] */ ; - CONS - /* [ list string ] */ } - /* [ pair (string @parameter) (string @storage) : list string ] */ ; - CAR - /* [ @parameter string : list string ] */ ; - CONS - /* [ list string ] */ ; - CONCAT - /* [ string ] */ ; - NIL operation - /* [ list operation : string ] */ ; - PAIR - /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--conditionals.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--conditionals.tz].out deleted file mode 100644 index 20a0e7c2c13f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--conditionals.tz].out +++ /dev/null @@ -1,20 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/conditionals.tz] - -Well typed -Gas remaining: 1039989.496 units remaining -{ parameter (or string (option int)) ; - storage string ; - code { CAR - /* [ @parameter or string (option int) ] */ ; - IF_LEFT - { /* [ @parameter.left string ] */ } - { IF_NONE - { FAIL } - { PUSH int 0 - /* [ int : @parameter.right.some int ] */ ; - CMPGT ; - IF { FAIL } { PUSH string "" /* [ string ] */ } } } ; - NIL operation - /* [ list operation : string ] */ ; - PAIR - /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cons_twice.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cons_twice.tz].out deleted file mode 100644 index 9d2c7873c26b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cons_twice.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/cons_twice.tz] - -Well typed -Gas remaining: 1039992.638 units remaining -{ parameter nat ; - storage (list nat) ; - code { DUP - /* [ pair (nat @parameter) (list @storage nat) - : pair (nat @parameter) (list @storage nat) ] */ ; - CAR - /* [ @parameter nat : pair (nat @parameter) (list @storage nat) ] */ ; - DIP { CDR /* [ @storage list nat ] */ } - /* [ @parameter nat : @storage list nat ] */ ; - DUP - /* [ @parameter nat : @parameter nat : @storage list nat ] */ ; - DIP { CONS /* [ list nat ] */ } - /* [ @parameter nat : list nat ] */ ; - CONS - /* [ list nat ] */ ; - NIL operation - /* [ list operation : list nat ] */ ; - PAIR - /* [ pair (list operation) (list nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cps_fact.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cps_fact.tz].out deleted file mode 100644 index afd574b441d9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cps_fact.tz].out +++ /dev/null @@ -1,71 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/cps_fact.tz] - -Well typed -Gas remaining: 1039973.219 units remaining -{ storage nat ; - parameter nat ; - code { UNPAIR - /* [ @parameter nat : @storage nat ] */ ; - DIP { SELF - /* [ @self contract nat : @storage nat ] */ ; - ADDRESS - /* [ @self.address address : @storage nat ] */ ; - SENDER - /* [ @sender address : @self.address address : @storage nat ] */ ; - IFCMPEQ - { /* [ @storage nat ] */ } - { DROP /* [] */ ; PUSH @storage nat 1 /* [ @storage nat ] */ } } - /* [ @parameter nat : @storage nat ] */ ; - DUP - /* [ @parameter nat : @parameter nat : @storage nat ] */ ; - PUSH nat 1 - /* [ nat : @parameter nat : @parameter nat : @storage nat ] */ ; - IFCMPGE - { DROP - /* [ @storage nat ] */ ; - NIL operation - /* [ list operation : @storage nat ] */ ; - PAIR - /* [ pair (list operation) (nat @storage) ] */ } - { PUSH nat 1 - /* [ nat : @parameter nat : @storage nat ] */ ; - SWAP - /* [ @parameter nat : nat : @storage nat ] */ ; - SUB @parameter - /* [ @parameter int : @storage nat ] */ ; - ISNAT - /* [ @parameter option nat : @storage nat ] */ ; - IF_NONE - { NIL operation - /* [ list operation : @storage nat ] */ ; - PAIR - /* [ pair (list operation) (nat @storage) ] */ } - { DUP - /* [ @parameter.some nat : @parameter.some nat : @storage nat ] */ ; - DIP { PUSH nat 1 - /* [ nat : @parameter.some nat : @storage nat ] */ ; - ADD - /* [ nat : @storage nat ] */ ; - MUL @storage - /* [ @storage nat ] */ } - /* [ @parameter.some nat : @storage nat ] */ ; - SWAP - /* [ @storage nat : @parameter.some nat ] */ ; - DIP { DIP { SELF - /* [ @self contract nat ] */ ; - PUSH mutez 0 - /* [ mutez : @self contract nat ] */ } - /* [ @parameter.some nat : mutez : @self contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - NIL operation - /* [ list operation : operation ] */ ; - SWAP - /* [ operation : list operation ] */ ; - CONS - /* [ list operation ] */ } - /* [ @storage nat : list operation ] */ ; - SWAP - /* [ list operation : @storage nat ] */ ; - PAIR - /* [ pair (list operation) (nat @storage) ] */ } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--create_add1_lists.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--create_add1_lists.tz].out deleted file mode 100644 index c6541faf298f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--create_add1_lists.tz].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/create_add1_lists.tz] - -Well typed -Gas remaining: 1039986.470 units remaining -{ parameter unit ; - storage address ; - code { DROP - /* [] */ ; - NIL int /* [ @parameter list int ] */ - /* [ list int ] */ ; - AMOUNT - /* [ list int ] */ ; - NONE key_hash - /* [ int : @parameter.elt int ] */ - /* [ option key_hash : @amount mutez : list int ] */ ; - CREATE_CONTRACT - { parameter (list int /* [ list operation : list int ] */) - /* [ int ] */ ; - storage (list int) - /* [ pair (list operation) (list int) ] */ ; - code { CAR ; MAP { PUSH int 1 ; ADD } ; NIL operation ; PAIR } } - /* [ operation : address ] */ ; - NIL operation - /* [ list operation : operation : address ] */ ; - SWAP - /* [ operation : list operation : address ] */ ; - CONS - /* [ list operation : address ] */ ; - PAIR - /* [ pair (list operation) address ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--data_publisher.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--data_publisher.tz].out deleted file mode 100644 index f8f6cb6d73d3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--data_publisher.tz].out +++ /dev/null @@ -1,80 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/data_publisher.tz] - -Well typed -Gas remaining: 1039974.524 units remaining -{ parameter (pair signature (pair string nat)) ; - storage (pair (pair key nat) string) ; - code { DUP - /* [ pair (pair @parameter signature string nat) (pair @storage (pair key nat) string) - : pair (pair @parameter signature string nat) (pair @storage (pair key nat) string) ] */ ; - CAR - /* [ @parameter pair signature string nat - : pair (pair @parameter signature string nat) (pair @storage (pair key nat) string) ] */ ; - DIP { CDR - /* [ @storage pair (pair key nat) string ] */ ; - DUP - /* [ @storage pair (pair key nat) string : @storage pair (pair key nat) string ] */ } - /* [ @parameter pair signature string nat : @storage pair (pair key nat) string - : @storage pair (pair key nat) string ] */ ; - SWAP - /* [ @storage pair (pair key nat) string : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ ; - DIP { DUP - /* [ @parameter pair signature string nat : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ } - /* [ @storage pair (pair key nat) string : @parameter pair signature string nat - : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ ; - CAAR ; - DIP { DUP - /* [ @parameter pair signature string nat : @parameter pair signature string nat - : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ ; - CAR - /* [ signature : @parameter pair signature string nat - : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ ; - DIP { CDR - /* [ pair string nat : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ ; - PACK - /* [ @packed bytes : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ ; - BLAKE2B - /* [ bytes : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ } - /* [ signature : bytes : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ } - /* [ key : signature : bytes : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ ; - CHECK_SIGNATURE - /* [ bool : @parameter pair signature string nat - : @storage pair (pair key nat) string ] */ ; - IF { CDR - /* [ pair string nat : @storage pair (pair key nat) string ] */ ; - DUP - /* [ pair string nat : pair string nat : @storage pair (pair key nat) string ] */ ; - DIP { CAR - /* [ string : @storage pair (pair key nat) string ] */ ; - DIP { CAAR } - /* [ string : key ] */ } - /* [ pair string nat : string : key ] */ ; - CDR - /* [ nat : string : key ] */ ; - PUSH nat 1 - /* [ nat : nat : string : key ] */ ; - ADD - /* [ nat : string : key ] */ ; - DIP { SWAP /* [ key : string ] */ } - /* [ nat : key : string ] */ ; - SWAP - /* [ key : nat : string ] */ ; - PAIR - /* [ pair key nat : string ] */ ; - PAIR - /* [ pair (pair key nat) string ] */ ; - NIL operation - /* [ list operation : pair (pair key nat) string ] */ ; - PAIR - /* [ pair (list operation) (pair key nat) string ] */ } - { FAIL } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--dispatch.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--dispatch.tz].out deleted file mode 100644 index d01aabf96e55..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--dispatch.tz].out +++ /dev/null @@ -1,54 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/dispatch.tz] - -Well typed -Gas remaining: 1039979.486 units remaining -{ parameter (or string (pair string (lambda unit string))) ; - storage (pair string (map string (lambda unit string))) ; - code { DUP - /* [ pair (or @parameter string (pair string (lambda unit string))) - (pair @storage string (map string (lambda unit string))) - : pair (or @parameter string (pair string (lambda unit string))) - (pair @storage string (map string (lambda unit string))) ] */ ; - DIP { CDDR } - /* [ pair (or @parameter string (pair string (lambda unit string))) - (pair @storage string (map string (lambda unit string))) - : map string (lambda unit string) ] */ ; - CAR - /* [ @parameter or string (pair string (lambda unit string)) - : map string (lambda unit string) ] */ ; - IF_LEFT - { DIP { DUP - /* [ map string (lambda unit string) : map string (lambda unit string) ] */ } - /* [ @parameter.left string : map string (lambda unit string) - : map string (lambda unit string) ] */ ; - GET - /* [ option (lambda unit string) : map string (lambda unit string) ] */ ; - IF_NONE - { FAIL } - { /* [ @some lambda unit string : map string (lambda unit string) ] */ } ; - UNIT - /* [ unit : @some lambda unit string : map string (lambda unit string) ] */ ; - EXEC - /* [ string : map string (lambda unit string) ] */ } - { DUP - /* [ @parameter.right pair string (lambda unit string) - : @parameter.right pair string (lambda unit string) - : map string (lambda unit string) ] */ ; - CAR - /* [ string : @parameter.right pair string (lambda unit string) - : map string (lambda unit string) ] */ ; - DIP { CDR - /* [ lambda unit string : map string (lambda unit string) ] */ ; - SOME - /* [ option (lambda unit string) : map string (lambda unit string) ] */ } - /* [ string : option (lambda unit string) : map string (lambda unit string) ] */ ; - UPDATE - /* [ map string (lambda unit string) ] */ ; - PUSH string "" - /* [ string : map string (lambda unit string) ] */ } ; - PAIR - /* [ pair string (map string (lambda unit string)) ] */ ; - NIL operation - /* [ list operation : pair string (map string (lambda unit string)) ] */ ; - PAIR - /* [ pair (list operation) string (map string (lambda unit string)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--empty.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--empty.tz].out deleted file mode 100644 index fde466977ab8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--empty.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/empty.tz] - -Well typed -Gas remaining: 1039997.267 units remaining -{ parameter unit ; - storage unit ; - code { CDR - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--fail_amount.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--fail_amount.tz].out deleted file mode 100644 index bf7624331dca..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--fail_amount.tz].out +++ /dev/null @@ -1,20 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/fail_amount.tz] - -Well typed -Gas remaining: 1039992.147 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - AMOUNT - /* [ @amount mutez ] */ ; - PUSH mutez 10000000 - /* [ mutez : @amount mutez ] */ ; - CMPGT ; - IF { FAIL } { /* [] */ } ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--faucet.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--faucet.tz].out deleted file mode 100644 index 8f95fb90cc79..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--faucet.tz].out +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/faucet.tz] - -Well typed -Gas remaining: 1039986.830 units remaining -{ parameter key_hash ; - storage timestamp ; - code { UNPAIR - /* [ @parameter key_hash : @storage timestamp ] */ ; - SWAP - /* [ @storage timestamp : @parameter key_hash ] */ ; - PUSH int 300 - /* [ int : @storage timestamp : @parameter key_hash ] */ ; - ADD @FIVE_MINUTES_LATER - /* [ @FIVE_MINUTES_LATER timestamp : @parameter key_hash ] */ ; - NOW - /* [ @now timestamp : @FIVE_MINUTES_LATER timestamp : @parameter key_hash ] */ ; - ASSERT_CMPGE ; - IMPLICIT_ACCOUNT - /* [ contract unit ] */ ; - PUSH mutez 1000000 - /* [ mutez : contract unit ] */ ; - UNIT - /* [ unit : mutez : contract unit ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - NIL operation - /* [ list operation : operation ] */ ; - SWAP - /* [ operation : list operation ] */ ; - CONS - /* [ list operation ] */ ; - DIP { NOW /* [ @now timestamp ] */ } - /* [ list operation : @now timestamp ] */ ; - PAIR - /* [ pair (list operation) (timestamp @now) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--forward.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--forward.tz].out deleted file mode 100644 index 1af409e2f7f6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--forward.tz].out +++ /dev/null @@ -1,1920 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/forward.tz] - -Well typed -Gas remaining: 1039634.172 units remaining -{ parameter (or string nat) ; - storage - (pair (pair nat (pair mutez mutez)) - (pair (pair nat (pair timestamp timestamp)) - (pair (pair mutez mutez) (pair (pair address address) address)))) ; - code { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDADDR ; - PUSH int - 86400 - /* [ int : timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - SWAP - /* [ timestamp : int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - ADD - /* [ timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - NOW - /* [ @now timestamp : timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - LT - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CAR - /* [ @parameter or string nat - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF_LEFT - { DUP - /* [ @parameter.left string : @parameter.left string - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PUSH string - "buyer" - /* [ string : @parameter.left string : @parameter.left string - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int : @parameter.left string - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - EQ - /* [ bool : @parameter.left string - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { DROP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDADAR ; - DIP { AMOUNT - /* [ @amount mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } - /* [ mutez : @amount mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - ADD - /* [ mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDADDR } - /* [ mutez : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PAIR - /* [ pair mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PUSH nat - 0 - /* [ nat : pair mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PAIR - /* [ pair nat mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { CDDR } - /* [ pair nat mutez mutez - : pair (pair nat timestamp timestamp) (pair mutez mutez) (pair address address) address ] */ ; - PAIR - /* [ pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - NIL operation - /* [ list operation - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - PAIR - /* [ pair (list operation) - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } - { PUSH string - "seller" - /* [ string : @parameter.left string - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - EQ - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDADDR ; - DIP { AMOUNT - /* [ @amount mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } - /* [ mutez : @amount mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - ADD - /* [ mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDADAR } - /* [ mutez : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - SWAP - /* [ mutez : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PAIR - /* [ pair mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PUSH nat - 0 - /* [ nat : pair mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PAIR - /* [ pair nat mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { CDDR } - /* [ pair nat mutez mutez - : pair (pair nat timestamp timestamp) (pair mutez mutez) (pair address address) address ] */ ; - PAIR - /* [ pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - NIL operation - /* [ list operation - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - PAIR - /* [ pair (list operation) - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } - { FAIL } } } - { FAIL } } - { BALANCE - /* [ @balance mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PUSH mutez - 0 - /* [ mutez : @balance mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IFCMPEQ - { FAIL } - { /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } ; - DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDAAR ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDDADR } - /* [ nat : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - MUL - /* [ mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PUSH nat - 2 - /* [ nat : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - MUL - /* [ mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - BALANCE - /* [ @balance mutez : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - LT - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { CDR - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - DUP - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CADAR ; - DIP { DUP - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CDDDAAR } - /* [ mutez : address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - ASSERT_SOME } - /* [ mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - TRANSFER_TOKENS - /* [ operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - NIL operation - /* [ list operation : operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - SWAP - /* [ operation : list operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CONS - /* [ list operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - SWAP - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - DUP - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - CADDR ; - DIP { DUP - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - CDDDADR } - /* [ mutez : address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - ASSERT_SOME } - /* [ mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - SWAP - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : operation : list operation ] */ ; - DIP { CONS /* [ list operation ] */ } - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - DUP - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - CADAR ; - DIP { DUP - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - CADDR } - /* [ mutez : mutez - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - ADD - /* [ mutez - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - BALANCE - /* [ @balance mutez : mutez - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - SUB_MUTEZ - /* [ option mutez - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - ASSERT_SOME ; - DIP { DUP - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - CDDDDR } - /* [ @some mutez : address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - ASSERT_SOME } - /* [ @some mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - UNIT - /* [ unit : @some mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address : list operation ] */ ; - DIP { SWAP - /* [ list operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } - /* [ operation : list operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CONS - /* [ list operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } - { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDADAR ; - NOW - /* [ @now timestamp : timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - LT - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { FAIL } - { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDADAR ; - PUSH int - 86400 - /* [ int : timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - ADD - /* [ timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - NOW - /* [ @now timestamp : timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - LT - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CAR - /* [ @parameter or string nat - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF_LEFT - { PUSH string - "buyer" - /* [ string : @parameter.left string - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - EQ - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDADAR ; - DIP { AMOUNT - /* [ @amount mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } - /* [ mutez : @amount mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - ADD - /* [ mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DUP - /* [ mutez : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDAAR ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDDAAR } - /* [ nat : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - MUL - /* [ mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } - /* [ mutez : mutez : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - GT - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { FAIL } - { /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } } - /* [ mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDADDR } - /* [ mutez : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PAIR - /* [ pair mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PUSH nat - 0 - /* [ nat : pair mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PAIR - /* [ pair nat mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { CDDR } - /* [ pair nat mutez mutez - : pair (pair nat timestamp timestamp) (pair mutez mutez) (pair address address) address ] */ ; - PAIR - /* [ pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - NIL operation - /* [ list operation - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - PAIR - /* [ pair (list operation) - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } - { FAIL } } - { FAIL } } - { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDAAR ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDDAAR } - /* [ nat : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - MUL - /* [ mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDADAR } - /* [ mutez : mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - NEQ - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { BALANCE - /* [ @balance mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDDDADR } - /* [ @balance mutez : address - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIIP { CDR - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } - /* [ @balance mutez : address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - ASSERT_SOME } - /* [ @balance mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - UNIT - /* [ unit : @balance mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - TRANSFER_TOKENS - /* [ operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - NIL operation - /* [ list operation : operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - SWAP - /* [ operation : list operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CONS - /* [ list operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } - { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDADAR ; - PUSH int - 86400 - /* [ int : timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - ADD - /* [ timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PUSH int - 86400 - /* [ int : timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - ADD - /* [ timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - NOW - /* [ @now timestamp : timestamp - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - LT - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDDDDR ; - SENDER - /* [ @sender address : address - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - COMPARE - /* [ int - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - NEQ - /* [ bool - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF { FAIL } - { /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } ; - DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CAR - /* [ @parameter or string nat - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - IF_LEFT - { FAIL } - { DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDAAR } - /* [ @parameter.right nat : nat - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - ADD - /* [ nat - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDADR } - /* [ nat : pair mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - PAIR - /* [ pair nat mutez mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { CDDR } - /* [ pair nat mutez mutez - : pair (pair nat timestamp timestamp) (pair mutez mutez) (pair address address) address ] */ ; - PAIR - /* [ pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - UNIT - /* [ unit - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - PAIR - /* [ pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - DUP - /* [ pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CDAAR ; - DIP { DUP - /* [ pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CDDAAR } - /* [ nat : nat - : pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - COMPARE - /* [ int - : pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - LT - /* [ bool - : pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - IF { CDR - /* [ pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - NIL operation - /* [ list operation - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } - { BALANCE - /* [ @balance mutez - : pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - DIP { DUP - /* [ pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address - : pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CDDDDADR } - /* [ @balance mutez : address - : pair unit - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - DIIP { CDR - /* [ pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } - /* [ @balance mutez : address - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - ASSERT_SOME } - /* [ @balance mutez : @contract.some contract unit - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - UNIT - /* [ unit : @balance mutez : @contract.some contract unit - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - NIL operation - /* [ list operation : operation - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - SWAP - /* [ operation : list operation - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CONS - /* [ list operation - : pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } } ; - PAIR - /* [ pair (list operation) - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } - { BALANCE - /* [ @balance mutez - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIP { DUP - /* [ pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - CDDDDAAR } - /* [ @balance mutez : address - : pair (or @parameter string nat) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ ; - DIIP { CDR - /* [ @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ } - /* [ @balance mutez : address - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - ASSERT_SOME } - /* [ @balance mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - UNIT - /* [ unit : @balance mutez : @contract.some contract unit - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - TRANSFER_TOKENS - /* [ operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - NIL operation - /* [ list operation : operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - SWAP - /* [ operation : list operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - CONS - /* [ list operation - : @storage pair (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage - (pair nat mutez mutez) - (pair nat timestamp timestamp) - (pair mutez mutez) - (pair address address) - address) ] */ } } } } } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--id.tz].out deleted file mode 100644 index a73e5e8a4ede..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--id.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/id.tz] - -Well typed -Gas remaining: 1039997.267 units remaining -{ parameter string ; - storage string ; - code { CAR - /* [ @parameter string ] */ ; - NIL operation - /* [ list operation : @parameter string ] */ ; - PAIR - /* [ pair (list operation) (string @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--infinite_loop.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--infinite_loop.tz].out deleted file mode 100644 index 07f206951c8a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--infinite_loop.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/infinite_loop.tz] - -Well typed -Gas remaining: 1039994.665 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - PUSH bool True - /* [ bool ] */ ; - LOOP { PUSH bool True /* [ bool ] */ } - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--insertion_sort.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--insertion_sort.tz].out deleted file mode 100644 index c05247970795..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--insertion_sort.tz].out +++ /dev/null @@ -1,63 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/insertion_sort.tz] - -Well typed -Gas remaining: 1039971.505 units remaining -{ parameter (list int) ; - storage (list int) ; - code { CAR - /* [ @parameter list int ] */ ; - NIL int - /* [ list int : @parameter list int ] */ ; - SWAP - /* [ @parameter list int : list int ] */ ; - ITER { SWAP - /* [ list int : @parameter.elt int ] */ ; - DIIP { NIL int /* [ list int ] */ } - /* [ list int : @parameter.elt int : list int ] */ ; - PUSH bool True - /* [ bool : list int : @parameter.elt int : list int ] */ ; - LOOP { IF_CONS - { SWAP - /* [ @tl list int : @hd int : @parameter.elt int : list int ] */ ; - DIP { DUP - /* [ @hd int : @hd int : @parameter.elt int : list int ] */ ; - DIIP { DUP /* [ @parameter.elt int : @parameter.elt int : list int ] */ } - /* [ @hd int : @hd int : @parameter.elt int : @parameter.elt int : list int ] */ ; - DIP { CMPLT } - /* [ @hd int : bool : @parameter.elt int : list int ] */ ; - SWAP - /* [ bool : @hd int : @parameter.elt int : list int ] */ } - /* [ @tl list int : bool : @hd int : @parameter.elt int : list int ] */ ; - SWAP - /* [ bool : @tl list int : @hd int : @parameter.elt int : list int ] */ ; - IF { DIP { SWAP - /* [ @parameter.elt int : @hd int : list int ] */ ; - DIP { CONS /* [ list int ] */ } - /* [ @parameter.elt int : list int ] */ } - /* [ @tl list int : @parameter.elt int : list int ] */ ; - PUSH bool True - /* [ bool : @tl list int : @parameter.elt int : list int ] */ } - { SWAP - /* [ @hd int : @tl list int : @parameter.elt int : list int ] */ ; - CONS - /* [ list int : @parameter.elt int : list int ] */ ; - PUSH bool False - /* [ bool : list int : @parameter.elt int : list int ] */ } } - { NIL int - /* [ list int : @parameter.elt int : list int ] */ ; - PUSH bool False - /* [ bool : list int : @parameter.elt int : list int ] */ } } - /* [ list int : @parameter.elt int : list int ] */ ; - SWAP - /* [ @parameter.elt int : list int : list int ] */ ; - CONS - /* [ list int : list int ] */ ; - SWAP - /* [ list int : list int ] */ ; - ITER { CONS /* [ list int ] */ } - /* [ list int ] */ } - /* [ list int ] */ ; - NIL operation - /* [ list operation : list int ] */ ; - PAIR - /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--int_publisher.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--int_publisher.tz].out deleted file mode 100644 index a839c63f27cb..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--int_publisher.tz].out +++ /dev/null @@ -1,105 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/int_publisher.tz] - -Well typed -Gas remaining: 1039967.523 units remaining -{ parameter (option (pair signature int)) ; - storage (pair key int) ; - code { DUP - /* [ pair (option @parameter (pair signature int)) (pair @storage key int) - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - DUP - /* [ pair (option @parameter (pair signature int)) (pair @storage key int) - : pair (option @parameter (pair signature int)) (pair @storage key int) - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - CAR - /* [ @parameter option (pair signature int) - : pair (option @parameter (pair signature int)) (pair @storage key int) - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - IF_NONE - { PUSH mutez - 1000000 - /* [ mutez - : pair (option @parameter (pair signature int)) (pair @storage key int) - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - AMOUNT - /* [ @amount mutez : mutez - : pair (option @parameter (pair signature int)) (pair @storage key int) - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - CMPLE ; - IF { FAIL } - { /* [ pair (option @parameter (pair signature int)) (pair @storage key int) - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ } ; - CDR - /* [ @storage pair key int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - DIP { CDDR } - /* [ @storage pair key int : int ] */ } - { DUP - /* [ @parameter.some pair signature int : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - DIP { SWAP - /* [ pair (option @parameter (pair signature int)) (pair @storage key int) - : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ } - /* [ @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) - : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - SWAP - /* [ pair (option @parameter (pair signature int)) (pair @storage key int) - : @parameter.some pair signature int : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - CDAR ; - DIP { DUP - /* [ @parameter.some pair signature int : @parameter.some pair signature int - : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - CAR - /* [ signature : @parameter.some pair signature int - : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - DIP { CDR - /* [ int : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - PACK - /* [ @packed bytes : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - BLAKE2B - /* [ bytes : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ } - /* [ signature : bytes : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ } - /* [ key : signature : bytes : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - CHECK_SIGNATURE - /* [ bool : @parameter.some pair signature int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - IF { CDR - /* [ int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - SWAP - /* [ pair (option @parameter (pair signature int)) (pair @storage key int) - : int ] */ ; - DIP { DUP /* [ int : int ] */ } - /* [ pair (option @parameter (pair signature int)) (pair @storage key int) : int - : int ] */ ; - CDAR ; - PAIR - /* [ pair key int : int ] */ } - { DROP - /* [ pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - DUP - /* [ pair (option @parameter (pair signature int)) (pair @storage key int) - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - CDR - /* [ @storage pair key int - : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; - DIP { CDDR } - /* [ @storage pair key int : int ] */ } } ; - DIP { DROP /* [] */ } - /* [ pair key int ] */ ; - NIL operation - /* [ list operation : pair key int ] */ ; - PAIR - /* [ pair (list operation) key int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--king_of_tez.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--king_of_tez.tz].out deleted file mode 100644 index c83fc9eb1926..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--king_of_tez.tz].out +++ /dev/null @@ -1,79 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/king_of_tez.tz] - -Well typed -Gas remaining: 1039971.047 units remaining -{ parameter key_hash ; - storage (pair timestamp (pair mutez key_hash)) ; - code { DUP - /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; - CDAR ; - NOW - /* [ @now timestamp : timestamp - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; - CMPGT ; - IF { CAR - /* [ @parameter key_hash ] */ ; - AMOUNT - /* [ @amount mutez : @parameter key_hash ] */ ; - PAIR - /* [ pair (mutez @amount) (key_hash @parameter) ] */ ; - NOW - /* [ @now timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; - PUSH int - 604800 - /* [ int : @now timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; - ADD - /* [ timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; - PAIR - /* [ pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - NIL operation - /* [ list operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ } - { DUP - /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; - CDDAR ; - AMOUNT - /* [ @amount mutez : mutez - : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; - CMPLT ; - IF { FAIL } - { CAR - /* [ @parameter key_hash ] */ ; - DUP - /* [ @parameter key_hash : @parameter key_hash ] */ ; - DIP { AMOUNT - /* [ @amount mutez : @parameter key_hash ] */ ; - PAIR - /* [ pair (mutez @amount) (key_hash @parameter) ] */ ; - NOW - /* [ @now timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; - PUSH int - 604800 - /* [ int : @now timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; - ADD - /* [ timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; - PAIR - /* [ pair timestamp (mutez @amount) (key_hash @parameter) ] */ } - /* [ @parameter key_hash - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - IMPLICIT_ACCOUNT - /* [ contract unit : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - AMOUNT - /* [ @amount mutez : contract unit - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - UNIT - /* [ unit : @amount mutez : contract unit - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - TRANSFER_TOKENS - /* [ operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - NIL operation - /* [ list operation : operation - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - SWAP - /* [ operation : list operation - : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; - CONS - /* [ list operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ } } ; - PAIR - /* [ pair (list operation) timestamp (mutez @amount) (key_hash @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--list_of_transactions.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--list_of_transactions.tz].out deleted file mode 100644 index 67928a2406df..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--list_of_transactions.tz].out +++ /dev/null @@ -1,49 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/list_of_transactions.tz] - -Well typed -Gas remaining: 1039982.122 units remaining -{ parameter unit ; - storage (list address) ; - code { CDR - /* [ @storage list address ] */ ; - DUP - /* [ @storage list address : @storage list address ] */ ; - DIP { NIL operation /* [ list operation : @storage list address ] */ } - /* [ @storage list address : list operation : @storage list address ] */ ; - PUSH bool - True - /* [ bool : @storage list address : list operation : @storage list address ] */ ; - LOOP { IF_CONS - { CONTRACT - unit - /* [ @storage.hd.contract option (contract unit) : @storage.tl list address - : list operation : @storage list address ] */ ; - ASSERT_SOME ; - PUSH mutez - 1000000 - /* [ mutez : @storage.hd.contract.some contract unit : @storage.tl list address - : list operation : @storage list address ] */ ; - UNIT - /* [ unit : mutez : @storage.hd.contract.some contract unit - : @storage.tl list address : list operation : @storage list address ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage.tl list address : list operation - : @storage list address ] */ ; - SWAP - /* [ @storage.tl list address : operation : list operation - : @storage list address ] */ ; - DIP { CONS /* [ list operation : @storage list address ] */ } - /* [ @storage.tl list address : list operation : @storage list address ] */ ; - PUSH bool - True - /* [ bool : @storage.tl list address : list operation : @storage list address ] */ } - { NIL address - /* [ list address : list operation : @storage list address ] */ ; - PUSH bool - False - /* [ bool : list address : list operation : @storage list address ] */ } } - /* [ @storage list address : list operation : @storage list address ] */ ; - DROP - /* [ list operation : @storage list address ] */ ; - PAIR - /* [ pair (list operation) (list @storage address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--queue.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--queue.tz].out deleted file mode 100644 index 637da4badd51..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--queue.tz].out +++ /dev/null @@ -1,111 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/queue.tz] - -Well typed -Gas remaining: 1039952.504 units remaining -{ parameter (option string) ; - storage (pair (option string) (pair (pair nat nat) (map nat string))) ; - code { DUP - /* [ pair (option @parameter string) - (pair @storage (option string) (pair nat nat) (map nat string)) - : pair (option @parameter string) - (pair @storage (option string) (pair nat nat) (map nat string)) ] */ ; - CAR - /* [ @parameter option string - : pair (option @parameter string) - (pair @storage (option string) (pair nat nat) (map nat string)) ] */ ; - IF_NONE - { CDDR ; - DUP - /* [ pair (pair nat nat) (map nat string) - : pair (pair nat nat) (map nat string) ] */ ; - CAR - /* [ pair nat nat : pair (pair nat nat) (map nat string) ] */ ; - DIP { CDR /* [ map nat string ] */ ; DUP /* [ map nat string : map nat string ] */ } - /* [ pair nat nat : map nat string : map nat string ] */ ; - DUP - /* [ pair nat nat : pair nat nat : map nat string : map nat string ] */ ; - CAR - /* [ nat : pair nat nat : map nat string : map nat string ] */ ; - SWAP - /* [ pair nat nat : nat : map nat string : map nat string ] */ ; - DIP { GET /* [ option string : map nat string ] */ } - /* [ pair nat nat : option string : map nat string ] */ ; - SWAP - /* [ option string : pair nat nat : map nat string ] */ ; - IF_NONE - { NONE string - /* [ option string : pair nat nat : map nat string ] */ ; - DIP { PAIR /* [ pair (pair nat nat) (map nat string) ] */ } - /* [ option string : pair (pair nat nat) (map nat string) ] */ ; - PAIR - /* [ pair (option string) (pair nat nat) (map nat string) ] */ } - { SOME - /* [ option string : pair nat nat : map nat string ] */ ; - DIP { DUP - /* [ pair nat nat : pair nat nat : map nat string ] */ ; - DIP { CAR - /* [ nat : map nat string ] */ ; - DIP { NONE string /* [ option string : map nat string ] */ } - /* [ nat : option string : map nat string ] */ ; - UPDATE - /* [ map nat string ] */ } - /* [ pair nat nat : map nat string ] */ ; - DUP - /* [ pair nat nat : pair nat nat : map nat string ] */ ; - CAR - /* [ nat : pair nat nat : map nat string ] */ ; - PUSH nat 1 - /* [ nat : nat : pair nat nat : map nat string ] */ ; - ADD - /* [ nat : pair nat nat : map nat string ] */ ; - DIP { CDR /* [ nat : map nat string ] */ } - /* [ nat : nat : map nat string ] */ ; - PAIR - /* [ pair nat nat : map nat string ] */ ; - PAIR - /* [ pair (pair nat nat) (map nat string) ] */ } - /* [ option string : pair (pair nat nat) (map nat string) ] */ ; - PAIR - /* [ pair (option string) (pair nat nat) (map nat string) ] */ } } - { DIP { DUP - /* [ pair (option @parameter string) - (pair @storage (option string) (pair nat nat) (map nat string)) - : pair (option @parameter string) - (pair @storage (option string) (pair nat nat) (map nat string)) ] */ ; - CDDAR ; - DIP { CDDDR } - /* [ pair nat nat : map nat string ] */ ; - DUP - /* [ pair nat nat : pair nat nat : map nat string ] */ } - /* [ @parameter.some string : pair nat nat : pair nat nat : map nat string ] */ ; - SWAP - /* [ pair nat nat : @parameter.some string : pair nat nat : map nat string ] */ ; - CAR - /* [ nat : @parameter.some string : pair nat nat : map nat string ] */ ; - DIP { SOME - /* [ option string : pair nat nat : map nat string ] */ ; - SWAP - /* [ pair nat nat : option string : map nat string ] */ ; - CDR - /* [ nat : option string : map nat string ] */ ; - DUP - /* [ nat : nat : option string : map nat string ] */ ; - DIP { UPDATE /* [ map nat string ] */ } - /* [ nat : map nat string ] */ ; - PUSH nat 1 - /* [ nat : nat : map nat string ] */ ; - ADD - /* [ nat : map nat string ] */ } - /* [ nat : nat : map nat string ] */ ; - PAIR - /* [ pair nat nat : map nat string ] */ ; - PAIR - /* [ pair (pair nat nat) (map nat string) ] */ ; - NONE string - /* [ option string : pair (pair nat nat) (map nat string) ] */ ; - PAIR - /* [ pair (option string) (pair nat nat) (map nat string) ] */ } ; - NIL operation - /* [ list operation : pair (option string) (pair nat nat) (map nat string) ] */ ; - PAIR - /* [ pair (list operation) (option string) (pair nat nat) (map nat string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reduce_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reduce_map.tz].out deleted file mode 100644 index 855e6395dac9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reduce_map.tz].out +++ /dev/null @@ -1,58 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/reduce_map.tz] - -Well typed -Gas remaining: 1039975.926 units remaining -{ parameter (pair (lambda int int) (list int)) ; - storage (list int) ; - code { DIP { NIL int /* [ list int ] */ } - /* [ pair (pair @parameter (lambda int int) (list int)) (list @storage int) - : list int ] */ ; - CAR - /* [ @parameter pair (lambda int int) (list int) : list int ] */ ; - DUP - /* [ @parameter pair (lambda int int) (list int) - : @parameter pair (lambda int int) (list int) : list int ] */ ; - DIP { CAR - /* [ lambda int int : list int ] */ ; - PAIR - /* [ pair (lambda int int) (list int) ] */ } - /* [ @parameter pair (lambda int int) (list int) - : pair (lambda int int) (list int) ] */ ; - CDR - /* [ list int : pair (lambda int int) (list int) ] */ ; - ITER { PAIR - /* [ pair (int @elt) (lambda int int) (list int) ] */ ; - DUP - /* [ pair (int @elt) (lambda int int) (list int) - : pair (int @elt) (lambda int int) (list int) ] */ ; - CDAR ; - DIP { DUP - /* [ pair (int @elt) (lambda int int) (list int) - : pair (int @elt) (lambda int int) (list int) ] */ ; - DIP { CDAR } - /* [ pair (int @elt) (lambda int int) (list int) : lambda int int ] */ ; - DUP - /* [ pair (int @elt) (lambda int int) (list int) - : pair (int @elt) (lambda int int) (list int) : lambda int int ] */ ; - CAR - /* [ @elt int : pair (int @elt) (lambda int int) (list int) : lambda int int ] */ ; - DIP { CDDR ; SWAP /* [ lambda int int : list int ] */ } - /* [ @elt int : lambda int int : list int ] */ ; - EXEC - /* [ int : list int ] */ ; - CONS - /* [ list int ] */ } - /* [ lambda int int : list int ] */ ; - PAIR - /* [ pair (lambda int int) (list int) ] */ } - /* [ pair (lambda int int) (list int) ] */ ; - CDR - /* [ list int ] */ ; - DIP { NIL int /* [ list int ] */ } - /* [ list int : list int ] */ ; - ITER { CONS /* [ list int ] */ } - /* [ list int ] */ ; - NIL operation - /* [ list operation : list int ] */ ; - PAIR - /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reentrancy.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reentrancy.tz].out deleted file mode 100644 index 7b4e1bdfa3c1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reentrancy.tz].out +++ /dev/null @@ -1,49 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/reentrancy.tz] - -Well typed -Gas remaining: 1039981.752 units remaining -{ parameter unit ; - storage (pair address address) ; - code { CDR - /* [ @storage pair address address ] */ ; - DUP - /* [ @storage pair address address : @storage pair address address ] */ ; - CAR - /* [ address : @storage pair address address ] */ ; - CONTRACT - unit - /* [ @contract option (contract unit) : @storage pair address address ] */ ; - ASSERT_SOME ; - PUSH mutez - 5000000 - /* [ mutez : @contract.some contract unit : @storage pair address address ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : @storage pair address address ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage pair address address ] */ ; - DIP { DUP - /* [ @storage pair address address : @storage pair address address ] */ ; - CDR - /* [ address : @storage pair address address ] */ ; - CONTRACT - unit - /* [ @contract option (contract unit) : @storage pair address address ] */ ; - ASSERT_SOME ; - PUSH mutez - 5000000 - /* [ mutez : @contract.some contract unit : @storage pair address address ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : @storage pair address address ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage pair address address ] */ } - /* [ operation : operation : @storage pair address address ] */ ; - DIIP { NIL operation /* [ list operation : @storage pair address address ] */ } - /* [ operation : operation : list operation : @storage pair address address ] */ ; - DIP { CONS /* [ list operation : @storage pair address address ] */ } - /* [ operation : list operation : @storage pair address address ] */ ; - CONS - /* [ list operation : @storage pair address address ] */ ; - PAIR - /* [ pair (list operation) (pair @storage address address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reservoir.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reservoir.tz].out deleted file mode 100644 index 8501c7bb7b86..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reservoir.tz].out +++ /dev/null @@ -1,100 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/reservoir.tz] - -Well typed -Gas remaining: 1039963.237 units remaining -{ parameter unit ; - storage (pair (pair (timestamp %T) (mutez %N)) (pair (address %A) (address %B))) ; - code { CDR - /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - DUP - /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - CAAR %T ; - NOW - /* [ @now timestamp : timestamp - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - COMPARE - /* [ int - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - LE - /* [ bool - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - IF { DUP - /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - CADR %N ; - BALANCE - /* [ @balance mutez : mutez - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - COMPARE - /* [ int - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - LE - /* [ bool - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - IF { NIL operation - /* [ list operation - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage (pair (timestamp %T) (mutez %N)) (address %A) (address %B)) ] */ } - { DUP - /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - CDDR %B ; - CONTRACT - unit - /* [ @contract option (contract unit) - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - ASSERT_SOME ; - BALANCE - /* [ @balance mutez : @contract.some contract unit - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - UNIT - /* [ unit : @balance mutez : @contract.some contract unit - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - TRANSFER_TOKENS - /* [ operation - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - NIL operation - /* [ list operation : operation - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - SWAP - /* [ operation : list operation - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - CONS - /* [ list operation - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage (pair (timestamp %T) (mutez %N)) (address %A) (address %B)) ] */ } } - { DUP - /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - CDAR %A ; - CONTRACT - unit - /* [ @contract option (contract unit) - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - ASSERT_SOME ; - BALANCE - /* [ @balance mutez : @contract.some contract unit - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - UNIT - /* [ unit : @balance mutez : @contract.some contract unit - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - TRANSFER_TOKENS - /* [ operation - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - NIL operation - /* [ list operation : operation - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - SWAP - /* [ operation : list operation - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - CONS - /* [ list operation - : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage (pair (timestamp %T) (mutez %N)) (address %A) (address %B)) ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--scrutable_reservoir.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--scrutable_reservoir.tz].out deleted file mode 100644 index 840cee340c35..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--scrutable_reservoir.tz].out +++ /dev/null @@ -1,273 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/scrutable_reservoir.tz] - -Well typed -Gas remaining: 1039876.691 units remaining -{ parameter unit ; - storage - (pair string - (pair timestamp (pair (pair mutez mutez) (pair address (pair address address))))) ; - code { DUP - /* [ pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - CDAR ; - PUSH string - "open" - /* [ string : string - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - COMPARE - /* [ int - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - NEQ - /* [ bool - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - IF { FAIL } - { DUP - /* [ pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - CDDAR ; - NOW - /* [ @now timestamp : timestamp - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - COMPARE - /* [ int - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - LT - /* [ bool - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - IF { PUSH mutez - 0 - /* [ mutez - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - DIP { DUP - /* [ pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - CDDDAAR } - /* [ mutez : mutez - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - ADD - /* [ mutez - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - DIP { DUP - /* [ pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - CDDDADR } - /* [ mutez : mutez - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - ADD - /* [ mutez - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - BALANCE - /* [ @balance mutez : mutez - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - COMPARE - /* [ int - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - LT - /* [ bool - : pair (unit @parameter) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; - IF { CDR - /* [ @storage pair string timestamp (pair mutez mutez) address address address ] */ ; - NIL operation - /* [ list operation - : @storage pair string timestamp (pair mutez mutez) address address address ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage string timestamp (pair mutez mutez) address address address) ] */ } - { CDDR ; - PUSH string - "success" - /* [ string : pair timestamp (pair mutez mutez) address address address ] */ ; - PAIR - /* [ pair string timestamp (pair mutez mutez) address address address ] */ ; - DUP - /* [ pair string timestamp (pair mutez mutez) address address address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CDDAAR ; - DIP { DUP - /* [ pair string timestamp (pair mutez mutez) address address address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CDDDAR } - /* [ mutez : address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : pair string timestamp (pair mutez mutez) address address address ] */ ; - ASSERT_SOME } - /* [ mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - DIP { DUP - /* [ pair string timestamp (pair mutez mutez) address address address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CDDADR ; - DIP { DUP - /* [ pair string timestamp (pair mutez mutez) address address address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CDDDDAR } - /* [ mutez : address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : pair string timestamp (pair mutez mutez) address address address ] */ ; - ASSERT_SOME } - /* [ mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair string timestamp (pair mutez mutez) address address address ] */ } - /* [ operation : operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - NIL operation - /* [ list operation : operation : operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - SWAP - /* [ operation : list operation : operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CONS - /* [ list operation : operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - SWAP - /* [ operation : list operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CONS - /* [ list operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - PAIR - /* [ pair (list operation) string timestamp (pair mutez mutez) address address address ] */ } } - { CDDR ; - PUSH string - "timeout" - /* [ string : pair timestamp (pair mutez mutez) address address address ] */ ; - PAIR - /* [ pair string timestamp (pair mutez mutez) address address address ] */ ; - BALANCE - /* [ @balance mutez - : pair string timestamp (pair mutez mutez) address address address ] */ ; - DIP { DUP - /* [ pair string timestamp (pair mutez mutez) address address address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CDDAAR } - /* [ @balance mutez : mutez - : pair string timestamp (pair mutez mutez) address address address ] */ ; - COMPARE - /* [ int : pair string timestamp (pair mutez mutez) address address address ] */ ; - LT - /* [ bool : pair string timestamp (pair mutez mutez) address address address ] */ ; - IF { BALANCE - /* [ @balance mutez - : pair string timestamp (pair mutez mutez) address address address ] */ ; - DIP { DUP - /* [ pair string timestamp (pair mutez mutez) address address address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CDDDAR } - /* [ @balance mutez : address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : pair string timestamp (pair mutez mutez) address address address ] */ ; - ASSERT_SOME } - /* [ @balance mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - UNIT - /* [ unit : @balance mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair string timestamp (pair mutez mutez) address address address ] */ } - { DUP - /* [ pair string timestamp (pair mutez mutez) address address address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CDDAAR ; - DIP { DUP - /* [ pair string timestamp (pair mutez mutez) address address address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CDDDAR } - /* [ mutez : address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : pair string timestamp (pair mutez mutez) address address address ] */ ; - ASSERT_SOME } - /* [ mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair string timestamp (pair mutez mutez) address address address ] */ } ; - DIP { BALANCE - /* [ @balance mutez - : pair string timestamp (pair mutez mutez) address address address ] */ ; - DIP { DUP - /* [ pair string timestamp (pair mutez mutez) address address address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CDDDDDR } - /* [ @balance mutez : address - : pair string timestamp (pair mutez mutez) address address address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) - : pair string timestamp (pair mutez mutez) address address address ] */ ; - ASSERT_SOME } - /* [ @balance mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - UNIT - /* [ unit : @balance mutez : @contract.some contract unit - : pair string timestamp (pair mutez mutez) address address address ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair string timestamp (pair mutez mutez) address address address ] */ } - /* [ operation : operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - NIL operation - /* [ list operation : operation : operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - SWAP - /* [ operation : list operation : operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CONS - /* [ list operation : operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - SWAP - /* [ operation : list operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - CONS - /* [ list operation - : pair string timestamp (pair mutez mutez) address address address ] */ ; - PAIR - /* [ pair (list operation) string timestamp (pair mutez mutez) address address address ] */ } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--spawn_identities.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--spawn_identities.tz].out deleted file mode 100644 index 91f106df7ec3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--spawn_identities.tz].out +++ /dev/null @@ -1,71 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/spawn_identities.tz] - -Well typed -Gas remaining: 1039971.200 units remaining -{ parameter nat ; - storage (list address) ; - code { /* [ pair (string @parameter) (string @storage) ] */ - DUP - /* [ list operation : @parameter string ] */ ; - CAR - /* [ @parameter nat : pair (nat @parameter) (list @storage address) ] */ ; - DIP { CDR - /* [ @storage list address ] */ ; - NIL operation - /* [ list operation : @storage list address ] */ } - /* [ pair (list operation) (string @parameter) ] */ ; - PUSH bool - True - /* [ bool : @parameter nat : list operation : @storage list address ] */ ; - LOOP { DUP - /* [ @parameter nat : @parameter nat : list operation : @storage list address ] */ ; - PUSH nat - 0 - /* [ nat : @parameter nat : @parameter nat : list operation - : @storage list address ] */ ; - CMPEQ ; - IF { PUSH bool - False - /* [ bool : @parameter nat : list operation : @storage list address ] */ } - { PUSH nat 1 - /* [ nat : @parameter nat : list operation : @storage list address ] */ ; - SWAP - /* [ @parameter nat : nat : list operation : @storage list address ] */ ; - SUB - /* [ int : list operation : @storage list address ] */ ; - ABS - /* [ nat : list operation : @storage list address ] */ ; - PUSH string "init" - /* [ string : nat : list operation : @storage list address ] */ ; - PUSH mutez - 5000000 - /* [ mutez : string : nat : list operation : @storage list address ] */ ; - NONE key_hash - /* [ option key_hash : mutez : string : nat : list operation - : @storage list address ] */ ; - CREATE_CONTRACT - { parameter string ; - storage string ; - code { CAR ; NIL operation ; PAIR } } - /* [ operation : address : nat : list operation : @storage list address ] */ ; - SWAP - /* [ address : operation : nat : list operation : @storage list address ] */ ; - DIP { SWAP - /* [ nat : operation : list operation : @storage list address ] */ ; - DIP { CONS /* [ list operation : @storage list address ] */ } - /* [ nat : list operation : @storage list address ] */ } - /* [ address : nat : list operation : @storage list address ] */ ; - SWAP - /* [ nat : address : list operation : @storage list address ] */ ; - DIP { SWAP - /* [ list operation : address : @storage list address ] */ ; - DIP { CONS /* [ list address ] */ } - /* [ list operation : list address ] */ } - /* [ nat : list operation : list address ] */ ; - PUSH bool True - /* [ bool : nat : list operation : list address ] */ } } - /* [ @parameter nat : list operation : @storage list address ] */ ; - DROP - /* [ list operation : @storage list address ] */ ; - PAIR - /* [ pair (list operation) (list @storage address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert.tz].out deleted file mode 100644 index 580fe2c4f736..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert.tz].out +++ /dev/null @@ -1,15 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert.tz] - -Well typed -Gas remaining: 1039994.573 units remaining -{ parameter bool ; - storage unit ; - code { CAR - /* [ @parameter bool ] */ ; - ASSERT ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpeq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpeq.tz].out deleted file mode 100644 index ececb7d6ec9e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpeq.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmpeq.tz] - -Well typed -Gas remaining: 1039990.676 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - ASSERT_CMPEQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpge.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpge.tz].out deleted file mode 100644 index 808469ab751c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpge.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmpge.tz] - -Well typed -Gas remaining: 1039990.676 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - ASSERT_CMPGE ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpgt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpgt.tz].out deleted file mode 100644 index 069a9c50bdc7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpgt.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmpgt.tz] - -Well typed -Gas remaining: 1039990.676 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - ASSERT_CMPGT ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmple.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmple.tz].out deleted file mode 100644 index 6fc959162746..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmple.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmple.tz] - -Well typed -Gas remaining: 1039990.676 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - ASSERT_CMPLE ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmplt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmplt.tz].out deleted file mode 100644 index a1b965e356e7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmplt.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmplt.tz] - -Well typed -Gas remaining: 1039990.676 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - ASSERT_CMPLT ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpneq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpneq.tz].out deleted file mode 100644 index 5c102bd027b9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpneq.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmpneq.tz] - -Well typed -Gas remaining: 1039990.676 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - ASSERT_CMPNEQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_eq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_eq.tz].out deleted file mode 100644 index 98e95e219f2d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_eq.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_eq.tz] - -Well typed -Gas remaining: 1039990.923 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_ge.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_ge.tz].out deleted file mode 100644 index 7d37efcc1f6e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_ge.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_ge.tz] - -Well typed -Gas remaining: 1039990.923 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GE ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_gt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_gt.tz].out deleted file mode 100644 index 619d923be04f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_gt.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_gt.tz] - -Well typed -Gas remaining: 1039990.923 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_le.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_le.tz].out deleted file mode 100644 index ddcafb8860fc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_le.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_le.tz] - -Well typed -Gas remaining: 1039990.923 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LE ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_lt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_lt.tz].out deleted file mode 100644 index 27c7664335fa..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_lt.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_lt.tz] - -Well typed -Gas remaining: 1039990.923 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LT ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_neq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_neq.tz].out deleted file mode 100644 index a38cce08c937..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_neq.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_neq.tz] - -Well typed -Gas remaining: 1039990.923 units remaining -{ parameter (pair int int) ; - storage unit ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_NEQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_get_add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_get_add.tz].out deleted file mode 100644 index 0a1988426f17..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_get_add.tz].out +++ /dev/null @@ -1,71 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/big_map_get_add.tz] - -Well typed -Gas remaining: 1039968.666 units remaining -{ parameter (pair (pair %set_pair int (option int)) (pair %check_pair int (option int))) ; - storage (pair (big_map int int) unit) ; - code { DUP - /* [ pair (pair @parameter - (pair %set_pair int (option int)) - (pair %check_pair int (option int))) - (pair @storage (big_map int int) unit) - : pair (pair @parameter - (pair %set_pair int (option int)) - (pair %check_pair int (option int))) - (pair @storage (big_map int int) unit) ] */ ; - DIP { CDAR } - /* [ pair (pair @parameter - (pair %set_pair int (option int)) - (pair %check_pair int (option int))) - (pair @storage (big_map int int) unit) : big_map int int ] */ ; - DUP - /* [ pair (pair @parameter - (pair %set_pair int (option int)) - (pair %check_pair int (option int))) - (pair @storage (big_map int int) unit) - : pair (pair @parameter - (pair %set_pair int (option int)) - (pair %check_pair int (option int))) - (pair @storage (big_map int int) unit) : big_map int int ] */ ; - DIP { CADR ; - DUP - /* [ pair int (option int) : pair int (option int) : big_map int int ] */ ; - CAR - /* [ int : pair int (option int) : big_map int int ] */ ; - DIP { CDR /* [ option int : big_map int int ] */ } - /* [ int : option int : big_map int int ] */ ; - UPDATE - /* [ big_map int int ] */ ; - DUP - /* [ big_map int int : big_map int int ] */ } - /* [ pair (pair @parameter - (pair %set_pair int (option int)) - (pair %check_pair int (option int))) - (pair @storage (big_map int int) unit) : big_map int int - : big_map int int ] */ ; - CADR ; - DUP - /* [ pair int (option int) : pair int (option int) : big_map int int - : big_map int int ] */ ; - CDR - /* [ option int : pair int (option int) : big_map int int : big_map int int ] */ ; - DIP { CAR - /* [ int : big_map int int : big_map int int ] */ ; - GET - /* [ option int : big_map int int ] */ } - /* [ option int : option int : big_map int int ] */ ; - IF_SOME - { SWAP - /* [ option int : @some int : big_map int int ] */ ; - IF_SOME { ASSERT_CMPEQ } { FAIL } } - { ASSERT_NONE } ; - UNIT - /* [ unit : big_map int int ] */ ; - SWAP - /* [ big_map int int : unit ] */ ; - PAIR - /* [ pair (big_map int int) unit ] */ ; - NIL operation - /* [ list operation : pair (big_map int int) unit ] */ ; - PAIR - /* [ pair (list operation) (big_map int int) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_mem.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_mem.tz].out deleted file mode 100644 index d25e218c8488..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_mem.tz].out +++ /dev/null @@ -1,31 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/big_map_mem.tz] - -Well typed -Gas remaining: 1039982.471 units remaining -{ parameter (pair int bool) ; - storage (pair (big_map int unit) unit) ; - code { DUP - /* [ pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) - : pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) ] */ ; - DUP - /* [ pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) - : pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) - : pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) ] */ ; - CADR ; - DIP { CAAR ; - DIP { CDAR ; DUP /* [ big_map int unit : big_map int unit ] */ } - /* [ int : big_map int unit : big_map int unit ] */ ; - MEM - /* [ bool : big_map int unit ] */ } - /* [ bool : bool : big_map int unit ] */ ; - ASSERT_CMPEQ ; - UNIT - /* [ unit : big_map int unit ] */ ; - SWAP - /* [ big_map int unit : unit ] */ ; - PAIR - /* [ pair (big_map int unit) unit ] */ ; - NIL operation - /* [ list operation : pair (big_map int unit) unit ] */ ; - PAIR - /* [ pair (list operation) (big_map int unit) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--build_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--build_list.tz].out deleted file mode 100644 index cd4da3f58ae3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--build_list.tz].out +++ /dev/null @@ -1,45 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/build_list.tz] - -Well typed -Gas remaining: 1039982.791 units remaining -{ parameter nat ; - storage (list nat) ; - code { CAR @counter - /* [ @counter nat ] */ ; - NIL @acc nat - /* [ @acc list nat : @counter nat ] */ ; - SWAP - /* [ @counter nat : @acc list nat ] */ ; - DUP @cmp_num - /* [ @cmp_num nat : @counter nat : @acc list nat ] */ ; - PUSH nat 0 - /* [ nat : @cmp_num nat : @counter nat : @acc list nat ] */ ; - CMPNEQ ; - LOOP { DUP - /* [ @counter nat : @counter nat : @acc list nat ] */ ; - DIP { SWAP /* [ @acc list nat : @counter nat ] */ } - /* [ @counter nat : @acc list nat : @counter nat ] */ ; - CONS @acc - /* [ @acc list nat : @counter nat ] */ ; - SWAP - /* [ @counter nat : @acc list nat ] */ ; - PUSH nat 1 - /* [ nat : @counter nat : @acc list nat ] */ ; - SWAP - /* [ @counter nat : nat : @acc list nat ] */ ; - SUB @counter - /* [ @counter int : @acc list nat ] */ ; - DUP - /* [ @counter int : @counter int : @acc list nat ] */ ; - DIP { ABS /* [ nat : @acc list nat ] */ } - /* [ @counter int : nat : @acc list nat ] */ ; - PUSH int 0 - /* [ int : @counter int : nat : @acc list nat ] */ ; - CMPNEQ } - /* [ @counter nat : @acc list nat ] */ ; - CONS - /* [ list nat ] */ ; - NIL operation - /* [ list operation : list nat ] */ ; - PAIR - /* [ pair (list operation) (list nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--carn_and_cdrn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--carn_and_cdrn.tz].out deleted file mode 100644 index 415f570850c2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--carn_and_cdrn.tz].out +++ /dev/null @@ -1,47 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/carn_and_cdrn.tz] - -Well typed -Gas remaining: 1039963.184 units remaining -{ parameter (pair nat nat nat unit) ; - storage unit ; - code { CAR - /* [ @parameter pair nat nat nat unit ] */ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - CAR - /* [ nat : @parameter pair nat nat nat unit ] */ ; - PUSH nat 1 - /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - CAR 0 ; - PUSH nat 1 - /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - CAR 1 ; - PUSH nat 4 - /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - CAR 2 ; - PUSH nat 2 - /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - CDR 3 ; - UNIT - /* [ unit : unit : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare.tz].out deleted file mode 100644 index 6542fcd4c6f4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare.tz].out +++ /dev/null @@ -1,97 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/compare.tz] - -Well typed -Gas remaining: 1039968.322 units remaining -{ parameter (pair mutez mutez) ; - storage (list bool) ; - code { CAR - /* [ @parameter pair mutez mutez ] */ ; - DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; - DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez - : @parameter pair mutez mutez ] */ ; - DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez - : @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; - DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez - : @parameter pair mutez mutez : @parameter pair mutez mutez - : @parameter pair mutez mutez ] */ ; - DIIIIIP - { NIL bool /* [ list bool ] */ } - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez - : @parameter pair mutez mutez : @parameter pair mutez mutez - : @parameter pair mutez mutez : list bool ] */ ; - DIIIIP - { DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; - CAR - /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; - DIP { CDR /* [ mutez : list bool ] */ } - /* [ mutez : mutez : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - LE - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ } - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez - : @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; - DIIIP - { DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; - CAR - /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; - DIP { CDR /* [ mutez : list bool ] */ } - /* [ mutez : mutez : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - GE - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ } - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez - : @parameter pair mutez mutez : list bool ] */ ; - DIIP { DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; - CAR - /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; - DIP { CDR /* [ mutez : list bool ] */ } - /* [ mutez : mutez : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - LT - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ } - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; - DIP { DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; - CAR - /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; - DIP { CDR /* [ mutez : list bool ] */ } - /* [ mutez : mutez : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - GT - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ } - /* [ @parameter pair mutez mutez : list bool ] */ ; - DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; - CAR - /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; - DIP { CDR /* [ mutez : list bool ] */ } - /* [ mutez : mutez : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - EQ - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ ; - NIL operation - /* [ list operation : list bool ] */ ; - PAIR - /* [ pair (list operation) (list bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare_bytes.tz].out deleted file mode 100644 index 3e8066e73de0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare_bytes.tz].out +++ /dev/null @@ -1,97 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/compare_bytes.tz] - -Well typed -Gas remaining: 1039968.322 units remaining -{ parameter (pair bytes bytes) ; - storage (list bool) ; - code { CAR - /* [ @parameter pair bytes bytes ] */ ; - DUP - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes ] */ ; - DUP - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes - : @parameter pair bytes bytes ] */ ; - DUP - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes - : @parameter pair bytes bytes : @parameter pair bytes bytes ] */ ; - DUP - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes - : @parameter pair bytes bytes : @parameter pair bytes bytes - : @parameter pair bytes bytes ] */ ; - DIIIIIP - { NIL bool /* [ list bool ] */ } - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes - : @parameter pair bytes bytes : @parameter pair bytes bytes - : @parameter pair bytes bytes : list bool ] */ ; - DIIIIP - { DUP - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; - CAR - /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; - DIP { CDR /* [ bytes : list bool ] */ } - /* [ bytes : bytes : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - LE - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ } - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes - : @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; - DIIIP - { DUP - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; - CAR - /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; - DIP { CDR /* [ bytes : list bool ] */ } - /* [ bytes : bytes : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - GE - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ } - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes - : @parameter pair bytes bytes : list bool ] */ ; - DIIP { DUP - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; - CAR - /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; - DIP { CDR /* [ bytes : list bool ] */ } - /* [ bytes : bytes : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - LT - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ } - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; - DIP { DUP - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; - CAR - /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; - DIP { CDR /* [ bytes : list bool ] */ } - /* [ bytes : bytes : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - GT - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ } - /* [ @parameter pair bytes bytes : list bool ] */ ; - DUP - /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; - CAR - /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; - DIP { CDR /* [ bytes : list bool ] */ } - /* [ bytes : bytes : list bool ] */ ; - COMPARE - /* [ int : list bool ] */ ; - EQ - /* [ bool : list bool ] */ ; - CONS - /* [ list bool ] */ ; - NIL operation - /* [ list operation : list bool ] */ ; - PAIR - /* [ pair (list operation) (list bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--fail.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--fail.tz].out deleted file mode 100644 index 44d023e672d8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--fail.tz].out +++ /dev/null @@ -1,5 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/fail.tz] - -Well typed -Gas remaining: 1039998.449 units remaining -{ parameter unit ; storage unit ; code { FAIL } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--guestbook.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--guestbook.tz].out deleted file mode 100644 index f0ca38479d3c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--guestbook.tz].out +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/guestbook.tz] - -Well typed -Gas remaining: 1039986.383 units remaining -{ parameter string ; - storage (map address (option string)) ; - code { UNPAIR @message @guestbook - /* [ @message string : @guestbook map address (option string) ] */ ; - SWAP - /* [ @guestbook map address (option string) : @message string ] */ ; - DUP - /* [ @guestbook map address (option string) - : @guestbook map address (option string) : @message string ] */ ; - SENDER - /* [ @sender address : @guestbook map address (option string) - : @guestbook map address (option string) : @message string ] */ ; - GET @previous_message - /* [ @previous_message option (option string) - : @guestbook map address (option string) : @message string ] */ ; - ASSERT_SOME ; - ASSERT_NONE ; - SWAP - /* [ @message string : @guestbook map address (option string) ] */ ; - SOME - /* [ option string : @guestbook map address (option string) ] */ ; - SOME - /* [ option (option string) : @guestbook map address (option string) ] */ ; - SENDER - /* [ @sender address : option (option string) - : @guestbook map address (option string) ] */ ; - UPDATE - /* [ @guestbook map address (option string) ] */ ; - NIL operation - /* [ list operation : @guestbook map address (option string) ] */ ; - PAIR - /* [ pair (list operation) (map @guestbook address (option string)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--macro_annotations.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--macro_annotations.tz].out deleted file mode 100644 index ada98a3ac9ec..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--macro_annotations.tz].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/macro_annotations.tz] - -Well typed -Gas remaining: 1039992.402 units remaining -{ parameter unit ; - storage (pair (unit %truc) unit) ; - code { DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - UNIT - /* [ unit : unit ] */ ; - PAIR %truc - /* [ pair (unit %truc) unit ] */ ; - UNIT - /* [ unit : pair (unit %truc) unit ] */ ; - DUUP @new_storage - /* [ @new_storage pair (unit %truc) unit : unit : pair (unit %truc) unit ] */ ; - DIP { DROP /* [ pair (unit %truc) unit ] */ ; DROP /* [] */ } - /* [ @new_storage pair (unit %truc) unit ] */ ; - NIL operation - /* [ list operation : @new_storage pair (unit %truc) unit ] */ ; - PAIR - /* [ pair (list operation) (pair @new_storage (unit %truc) unit) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--map_caddaadr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--map_caddaadr.tz].out deleted file mode 100644 index 11ea7a729d46..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--map_caddaadr.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/map_caddaadr.tz] - -Well typed -Gas remaining: 1039964.206 units remaining -{ parameter unit ; - storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat) ; - code { MAP_CDADDAADR @new_storage %value - { PUSH mutez 1000000 - /* [ mutez : @value mutez : pair (nat %p) (mutez %value) ] */ ; - ADD - /* [ mutez : pair (nat %p) (mutez %value) ] */ } ; - NIL operation - /* [ list operation - : @new_storage pair unit (pair nat nat (pair (pair (nat %p @p) (mutez %value)) nat) nat) nat ] */ ; - SWAP - /* [ @new_storage pair unit (pair nat nat (pair (pair (nat %p @p) (mutez %value)) nat) nat) nat - : list operation ] */ ; - SET_CAR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--max_in_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--max_in_list.tz].out deleted file mode 100644 index b5e4e2ae51e1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--max_in_list.tz].out +++ /dev/null @@ -1,29 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/max_in_list.tz] - -Well typed -Gas remaining: 1039985.981 units remaining -{ parameter (list int) ; - storage (option int) ; - code { CAR - /* [ @parameter list int ] */ ; - DIP { NONE int /* [ option int ] */ } - /* [ @parameter list int : option int ] */ ; - ITER { SWAP - /* [ option int : @parameter.elt int ] */ ; - IF_NONE - { SOME /* [ option int ] */ } - { DIP { DUP /* [ @parameter.elt int : @parameter.elt int ] */ } - /* [ @some int : @parameter.elt int : @parameter.elt int ] */ ; - DUP - /* [ @some int : @some int : @parameter.elt int : @parameter.elt int ] */ ; - DIP { SWAP /* [ @parameter.elt int : @some int : @parameter.elt int ] */ } - /* [ @some int : @parameter.elt int : @some int : @parameter.elt int ] */ ; - CMPLE ; - IF { DROP /* [ @parameter.elt int ] */ } { DIP { DROP /* [] */ } /* [ @some int ] */ } ; - SOME - /* [ option int ] */ } } - /* [ option int ] */ ; - NIL operation - /* [ list operation : option int ] */ ; - PAIR - /* [ pair (list operation) (option int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--min.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--min.tz].out deleted file mode 100644 index 42c1f18ff275..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--min.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/min.tz] - -Well typed -Gas remaining: 1039990.871 units remaining -{ parameter (pair int int) ; - storage int ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int - : @parameter pair int int ] */ ; - CAR - /* [ int : @parameter pair int int : @parameter pair int int ] */ ; - DIP { CDR /* [ int : @parameter pair int int ] */ } - /* [ int : int : @parameter pair int int ] */ ; - CMPLT ; - IF { CAR /* [ int ] */ } { CDR /* [ int ] */ } ; - NIL operation - /* [ list operation : int ] */ ; - PAIR - /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--pair_macro.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--pair_macro.tz].out deleted file mode 100644 index a61c93ee2b5d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--pair_macro.tz].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/pair_macro.tz] - -Well typed -Gas remaining: 1039988.218 units remaining -{ parameter unit ; - storage unit ; - code { UNIT - /* [ unit : pair (unit @parameter) (unit @storage) ] */ ; - UNIT - /* [ unit : unit : pair (unit @parameter) (unit @storage) ] */ ; - UNIT - /* [ unit : unit : unit : pair (unit @parameter) (unit @storage) ] */ ; - UNIT - /* [ unit : unit : unit : unit : pair (unit @parameter) (unit @storage) ] */ ; - UNIT - /* [ unit : unit : unit : unit : unit : pair (unit @parameter) (unit @storage) ] */ ; - PAPAPAPAIR @name %x1 %x2 %x3 %x4 %x5 ; - CDDDAR %x4 @fourth ; - DROP - /* [ pair (unit @parameter) (unit @storage) ] */ ; - CDR - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--set_caddaadr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--set_caddaadr.tz].out deleted file mode 100644 index 81ca6e6dfb34..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--set_caddaadr.tz].out +++ /dev/null @@ -1,52 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/set_caddaadr.tz] - -Well typed -Gas remaining: 1039968.110 units remaining -{ parameter mutez ; - storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat) ; - code { DUP - /* [ pair (mutez @parameter) - (pair @storage (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat) - : pair (mutez @parameter) - (pair @storage (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat) ] */ ; - CAR - /* [ @parameter mutez - : pair (mutez @parameter) - (pair @storage (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat) ] */ ; - SWAP - /* [ pair (mutez @parameter) - (pair @storage (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat) - : @parameter mutez ] */ ; - CDR - /* [ @storage pair (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat - : @parameter mutez ] */ ; - SET_CADDAADR @toplevel_pair_name %value ; - NIL operation - /* [ list operation - : @toplevel_pair_name pair (pair @storage.car - (nat @storage.car.car) - (pair @storage.car.cdr - (nat @storage.car.cdr.car) - (pair @storage.car.cdr.cdr - (pair @storage.car.cdr.cdr.car - (pair @storage.car.cdr.cdr.car.car - (nat %p @storage.car.cdr.cdr.car.car.p) - (mutez %value @parameter)) - (nat @storage.car.cdr.cdr.car.cdr)) - (nat @storage.car.cdr.cdr.cdr)))) - (nat @storage.cdr) ] */ ; - PAIR - /* [ pair (list operation) - (pair @toplevel_pair_name - (pair @storage.car - (nat @storage.car.car) - (pair @storage.car.cdr - (nat @storage.car.cdr.car) - (pair @storage.car.cdr.cdr - (pair @storage.car.cdr.cdr.car - (pair @storage.car.cdr.cdr.car.car - (nat %p @storage.car.cdr.cdr.car.car.p) - (mutez %value @parameter)) - (nat @storage.car.cdr.cdr.car.cdr)) - (nat @storage.car.cdr.cdr.cdr)))) - (nat @storage.cdr)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--take_my_money.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--take_my_money.tz].out deleted file mode 100644 index e8bbc1fd614f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--take_my_money.tz].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/take_my_money.tz] - -Well typed -Gas remaining: 1039992.790 units remaining -{ parameter key_hash ; - storage unit ; - code { CAR - /* [ @parameter key_hash ] */ ; - IMPLICIT_ACCOUNT - /* [ contract unit ] */ ; - DIP { UNIT /* [ unit ] */ } - /* [ contract unit : unit ] */ ; - PUSH mutez 1000000 - /* [ mutez : contract unit : unit ] */ ; - UNIT - /* [ unit : mutez : contract unit : unit ] */ ; - TRANSFER_TOKENS - /* [ operation : unit ] */ ; - NIL operation - /* [ list operation : operation : unit ] */ ; - SWAP - /* [ operation : list operation : unit ] */ ; - CONS - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--unpair_macro.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--unpair_macro.tz].out deleted file mode 100644 index 8358caec285e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--unpair_macro.tz].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/unpair_macro.tz] - -Well typed -Gas remaining: 1039976.490 units remaining -{ parameter (unit :param_unit) ; - storage (unit :u1) ; - code { DROP - /* [] */ ; - UNIT :u4 @a4 - /* [ @a4 unit :u4 ] */ ; - UNIT :u3 @a3 - /* [ @a3 unit :u3 : @a4 unit :u4 ] */ ; - UNIT :u2 @a2 - /* [ @a2 unit :u2 : @a3 unit :u3 : @a4 unit :u4 ] */ ; - UNIT :u1 @a1 - /* [ @a1 unit :u1 : @a2 unit :u2 : @a3 unit :u3 : @a4 unit :u4 ] */ ; - PAIR - /* [ pair (unit :u1 @a1) (unit :u2 @a2) : @a3 unit :u3 : @a4 unit :u4 ] */ ; - UNPAIR @x1 @x2 - /* [ @x1 unit :u1 : @x2 unit :u2 : @a3 unit :u3 : @a4 unit :u4 ] */ ; - PPAIPAIR @p1 %x1 %x2 %x3 %x4 ; - UNPPAIPAIR %x1 % %x3 %x4 @uno @due @tre @quattro ; - PAPAPAIR @p2 %x1 %x2 %x3 %x4 ; - UNPAPAPAIR @un @deux @trois @quatre ; - PAPPAIIR @p3 %x1 %x2 %x3 %x4 ; - UNPAPPAIIR @one @two @three @four ; - DIP { DROP /* [ @a3 unit :u3 : @a4 unit :u4 ] */ ; DROP /* [ @a4 unit :u4 ] */ ; DROP /* [] */ } - /* [ @x1 unit :u1 ] */ ; - NIL operation - /* [ list operation : @x1 unit :u1 ] */ ; - PAIR - /* [ pair (list operation) (unit :u1 @x1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--authentication.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--authentication.tz].out deleted file mode 100644 index 8170ae63b4b5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--authentication.tz].out +++ /dev/null @@ -1,47 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/authentication.tz] - -Well typed -Gas remaining: 1039978.751 units remaining -{ parameter (pair (lambda unit (list operation)) signature) ; - storage (pair (nat %counter) key) ; - code { UNPPAIPAIR ; - DUUUP - /* [ nat : lambda unit (list operation) : signature : nat : key ] */ ; - DUUP - /* [ lambda unit (list operation) : nat : lambda unit (list operation) - : signature : nat : key ] */ ; - SELF - /* [ @self contract (pair (lambda unit (list operation)) signature) - : lambda unit (list operation) : nat : lambda unit (list operation) - : signature : nat : key ] */ ; - CHAIN_ID - /* [ chain_id : @self contract (pair (lambda unit (list operation)) signature) - : lambda unit (list operation) : nat : lambda unit (list operation) - : signature : nat : key ] */ ; - PPAIPAIR ; - PACK - /* [ @packed bytes : lambda unit (list operation) : signature : nat : key ] */ ; - DIP { SWAP /* [ signature : lambda unit (list operation) : nat : key ] */ } - /* [ @packed bytes : signature : lambda unit (list operation) : nat : key ] */ ; - DUUUUUP - /* [ key : @packed bytes : signature : lambda unit (list operation) : nat - : key ] */ ; - DIP { SWAP - /* [ signature : @packed bytes : lambda unit (list operation) : nat : key ] */ } - /* [ key : signature : @packed bytes : lambda unit (list operation) : nat - : key ] */ ; - DUUUP - /* [ bytes : key : signature : @packed bytes : lambda unit (list operation) - : nat : key ] */ ; - DIP { CHECK_SIGNATURE /* [ bool : lambda unit (list operation) : nat : key ] */ } - /* [ bytes : bool : lambda unit (list operation) : nat : key ] */ ; - SWAP - /* [ bool : bytes : lambda unit (list operation) : nat : key ] */ ; - IF { DROP /* [ lambda unit (list operation) : nat : key ] */ } { FAILWITH /* [] */ } ; - UNIT - /* [ unit : lambda unit (list operation) : nat : key ] */ ; - EXEC - /* [ list operation : nat : key ] */ ; - DIP { PUSH nat 1 /* [ nat : nat : key ] */ ; ADD /* [ nat : key ] */ } - /* [ list operation : nat : key ] */ ; - PAPAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_entrypoints.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_entrypoints.tz].out deleted file mode 100644 index d41e74f26914..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_entrypoints.tz].out +++ /dev/null @@ -1,132 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_entrypoints.tz] - -Well typed -Gas remaining: 1039940.196 units remaining -{ storage (pair (big_map string nat) (big_map string nat)) ; - parameter - (or (unit %default - /* [ list operation : @storage big_map string nat ] */) - (or (or %mem - (string %mem_left) - (string %mem_right) - /* [ pair (list operation) (big_map @storage string nat) ] */) - (or (or %add (pair %add_left string nat) (pair %add_right string nat)) - (or %rem (string %rem_left) (string %rem_right)))) - /* [ @storage big_map string nat ] */) - /* [ @parameter string : @storage big_map string nat ] */ ; - code { UNPAIR - /* [ @parameter or (unit %default) - (or (or %mem (string %mem_left) (string %mem_right)) - (or (or %add (pair %add_left string nat) (pair %add_right string nat)) - (or %rem (string %rem_left) (string %rem_right)))) - : @storage pair (big_map string nat) (big_map string nat) ] */ ; - IF_LEFT - { DROP - /* [ @storage pair (big_map string nat) (big_map string nat) ] */ ; - DUP - /* [ @storage pair (big_map string nat) (big_map string nat) - : @storage pair (big_map string nat) (big_map string nat) ] */ ; - CAR - /* [ big_map string nat - : @storage pair (big_map string nat) (big_map string nat) ] */ ; - PUSH mutez - 0 - /* [ mutez : big_map string nat - : @storage pair (big_map string nat) (big_map string nat) ] */ ; - NONE key_hash - /* [ option key_hash : mutez : big_map string nat - : @storage pair (big_map string nat) (big_map string nat) ] */ ; - CREATE_CONTRACT - { parameter string ; - storage (big_map string nat) ; - code { UNPAIR ; DROP ; NIL operation ; PAIR } } - /* [ operation : address - : @storage pair (big_map string nat) (big_map string nat) ] */ ; - DIP { DROP /* [ @storage pair (big_map string nat) (big_map string nat) ] */ } - /* [ operation : @storage pair (big_map string nat) (big_map string nat) ] */ ; - NIL operation - /* [ list operation : operation - : @storage pair (big_map string nat) (big_map string nat) ] */ ; - SWAP - /* [ operation : list operation - : @storage pair (big_map string nat) (big_map string nat) ] */ ; - CONS - /* [ list operation : @storage pair (big_map string nat) (big_map string nat) ] */ ; - PAIR - /* [ pair (list operation) (pair @storage (big_map string nat) (big_map string nat)) ] */ } - { IF_LEFT - { IF_LEFT - { DIP { UNPAIR /* [ big_map string nat : big_map string nat ] */ } - /* [ @parameter.right.mem.mem_left string : big_map string nat - : big_map string nat ] */ ; - DIP { DUP /* [ big_map string nat : big_map string nat : big_map string nat ] */ } - /* [ @parameter.right.mem.mem_left string : big_map string nat - : big_map string nat : big_map string nat ] */ ; - MEM - /* [ bool : big_map string nat : big_map string nat ] */ ; - ASSERT } - { DIP { UNPAIR - /* [ big_map string nat : big_map string nat ] */ ; - SWAP - /* [ big_map string nat : big_map string nat ] */ } - /* [ @parameter.right.mem.mem_right string : big_map string nat - : big_map string nat ] */ ; - DIP { DUP /* [ big_map string nat : big_map string nat : big_map string nat ] */ } - /* [ @parameter.right.mem.mem_right string : big_map string nat - : big_map string nat : big_map string nat ] */ ; - MEM - /* [ bool : big_map string nat : big_map string nat ] */ ; - ASSERT ; - SWAP - /* [ big_map string nat : big_map string nat ] */ } } - { IF_LEFT - { IF_LEFT - { UNPAIR - /* [ string : nat : @storage pair (big_map string nat) (big_map string nat) ] */ ; - DIIP { UNPAIR /* [ big_map string nat : big_map string nat ] */ } - /* [ string : nat : big_map string nat : big_map string nat ] */ ; - DIP { SOME /* [ option nat : big_map string nat : big_map string nat ] */ } - /* [ string : option nat : big_map string nat : big_map string nat ] */ ; - UPDATE - /* [ big_map string nat : big_map string nat ] */ } - { UNPAIR - /* [ string : nat : @storage pair (big_map string nat) (big_map string nat) ] */ ; - DIIP { UNPAIR - /* [ big_map string nat : big_map string nat ] */ ; - SWAP - /* [ big_map string nat : big_map string nat ] */ } - /* [ string : nat : big_map string nat : big_map string nat ] */ ; - DIP { SOME /* [ option nat : big_map string nat : big_map string nat ] */ } - /* [ string : option nat : big_map string nat : big_map string nat ] */ ; - UPDATE - /* [ big_map string nat : big_map string nat ] */ ; - SWAP - /* [ big_map string nat : big_map string nat ] */ } } - { IF_LEFT - { DIP { UNPAIR /* [ big_map string nat : big_map string nat ] */ } - /* [ @parameter.right.right.rem.rem_left string : big_map string nat - : big_map string nat ] */ ; - DIP { NONE nat /* [ option nat : big_map string nat : big_map string nat ] */ } - /* [ @parameter.right.right.rem.rem_left string : option nat - : big_map string nat : big_map string nat ] */ ; - UPDATE - /* [ big_map string nat : big_map string nat ] */ } - { DIP { UNPAIR - /* [ big_map string nat : big_map string nat ] */ ; - SWAP - /* [ big_map string nat : big_map string nat ] */ } - /* [ @parameter.right.right.rem.rem_right string : big_map string nat - : big_map string nat ] */ ; - DIP { NONE nat /* [ option nat : big_map string nat : big_map string nat ] */ } - /* [ @parameter.right.right.rem.rem_right string : option nat - : big_map string nat : big_map string nat ] */ ; - UPDATE - /* [ big_map string nat : big_map string nat ] */ ; - SWAP - /* [ big_map string nat : big_map string nat ] */ } } } ; - PAIR - /* [ pair (big_map string nat) (big_map string nat) ] */ ; - NIL operation - /* [ list operation : pair (big_map string nat) (big_map string nat) ] */ ; - PAIR - /* [ pair (list operation) (big_map string nat) (big_map string nat) ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_magic.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_magic.tz].out deleted file mode 100644 index c0b664eddbce..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_magic.tz].out +++ /dev/null @@ -1,106 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_magic.tz] - -Well typed -Gas remaining: 1039941.750 units remaining -{ storage (or (pair (big_map string string) (big_map string string)) unit) ; - parameter - (or (unit %swap) - (or (or %reset (pair (big_map string string) (big_map string string)) unit) - (or (pair %import (list (pair string string)) (list (pair string string))) - (or (list %add (pair string string)) (list %rem string))))) ; - code { UNPAIR - /* [ @parameter or (unit %swap) - (or (or %reset (pair (big_map string string) (big_map string string)) unit) - (or (pair %import (list (pair string string)) (list (pair string string))) - (or (list %add (pair string string)) (list %rem string)))) - : @storage or (pair (big_map string string) (big_map string string)) unit ] */ ; - IF_LEFT - { DROP - /* [ @storage or (pair (big_map string string) (big_map string string)) unit ] */ ; - ASSERT_LEFT ; - UNPAIR - /* [ big_map string string : big_map string string ] */ ; - SWAP - /* [ big_map string string : big_map string string ] */ ; - PAIR - /* [ pair (big_map string string) (big_map string string) ] */ ; - LEFT unit - /* [ or (pair (big_map string string) (big_map string string)) unit ] */ } - { IF_LEFT - { SWAP - /* [ @storage or (pair (big_map string string) (big_map string string)) unit - : @parameter.right.reset or (pair (big_map string string) (big_map string string)) unit ] */ ; - DROP - /* [ @parameter.right.reset or (pair (big_map string string) (big_map string string)) unit ] */ } - { IF_LEFT - { DIP { ASSERT_RIGHT ; DROP /* [] */ } - /* [ @parameter.right.right.import pair (list (pair string string)) (list (pair string string)) ] */ ; - UNPAIR - /* [ list (pair string string) : list (pair string string) ] */ ; - DIP { EMPTY_BIG_MAP - string - string - /* [ big_map string string : list (pair string string) ] */ } - /* [ list (pair string string) : big_map string string - : list (pair string string) ] */ ; - ITER { UNPAIR - /* [ string : string : big_map string string : list (pair string string) ] */ ; - DIP { SOME - /* [ option string : big_map string string : list (pair string string) ] */ } - /* [ string : option string : big_map string string - : list (pair string string) ] */ ; - UPDATE - /* [ big_map string string : list (pair string string) ] */ } - /* [ big_map string string : list (pair string string) ] */ ; - SWAP - /* [ list (pair string string) : big_map string string ] */ ; - DIP { EMPTY_BIG_MAP string string - /* [ big_map string string : big_map string string ] */ } - /* [ list (pair string string) : big_map string string : big_map string string ] */ ; - ITER { UNPAIR - /* [ string : string : big_map string string : big_map string string ] */ ; - DIP { SOME /* [ option string : big_map string string : big_map string string ] */ } - /* [ string : option string : big_map string string : big_map string string ] */ ; - UPDATE - /* [ big_map string string : big_map string string ] */ } - /* [ big_map string string : big_map string string ] */ ; - SWAP - /* [ big_map string string : big_map string string ] */ ; - PAIR - /* [ pair (big_map string string) (big_map string string) ] */ ; - LEFT unit - /* [ or (pair (big_map string string) (big_map string string)) unit ] */ } - { IF_LEFT - { DIP { ASSERT_LEFT ; UNPAIR /* [ big_map string string : big_map string string ] */ } - /* [ @parameter.right.right.right.add list (pair string string) - : big_map string string : big_map string string ] */ ; - ITER { UNPAIR - /* [ string : string : big_map string string : big_map string string ] */ ; - DIP { SOME /* [ option string : big_map string string : big_map string string ] */ } - /* [ string : option string : big_map string string : big_map string string ] */ ; - UPDATE - /* [ big_map string string : big_map string string ] */ } - /* [ big_map string string : big_map string string ] */ ; - PAIR - /* [ pair (big_map string string) (big_map string string) ] */ ; - LEFT unit - /* [ or (pair (big_map string string) (big_map string string)) unit ] */ } - { DIP { ASSERT_LEFT ; UNPAIR /* [ big_map string string : big_map string string ] */ } - /* [ @parameter.right.right.right.rem list string : big_map string string - : big_map string string ] */ ; - ITER { DIP { NONE string - /* [ option string : big_map string string : big_map string string ] */ } - /* [ @parameter.right.right.right.rem.elt string : option string - : big_map string string : big_map string string ] */ ; - UPDATE - /* [ big_map string string : big_map string string ] */ } - /* [ big_map string string : big_map string string ] */ ; - PAIR - /* [ pair (big_map string string) (big_map string string) ] */ ; - LEFT unit - /* [ or (pair (big_map string string) (big_map string string)) unit ] */ } } } } ; - NIL operation - /* [ list operation - : or (pair (big_map string string) (big_map string string)) unit ] */ ; - PAIR - /* [ pair (list operation) (or (pair (big_map string string) (big_map string string)) unit) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_read.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_read.tz].out deleted file mode 100644 index 972abc04e756..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_read.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_read.tz] - -Well typed -Gas remaining: 1039993.434 units remaining -{ storage nat ; - parameter (big_map nat nat) ; - code { CAR - /* [ @parameter big_map nat nat ] */ ; - PUSH nat 1 - /* [ nat : @parameter big_map nat nat ] */ ; - GET - /* [ option nat ] */ ; - ASSERT_SOME ; - NIL operation - /* [ list operation : @some nat ] */ ; - PAIR - /* [ pair (list operation) (nat @some) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_store.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_store.tz].out deleted file mode 100644 index 186faf784886..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_store.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_store.tz] - -Well typed -Gas remaining: 1039995.896 units remaining -{ storage (big_map nat nat) ; - parameter unit ; - code { DROP - /* [] */ ; - EMPTY_BIG_MAP nat nat - /* [ big_map nat nat ] */ ; - NIL operation - /* [ list operation : big_map nat nat ] */ ; - PAIR - /* [ pair (list operation) (big_map nat nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_write.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_write.tz].out deleted file mode 100644 index bce73c2de1c7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_write.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_write.tz] - -Well typed -Gas remaining: 1039994.022 units remaining -{ storage unit ; - parameter (big_map nat nat) ; - code { UNPAIR - /* [ @parameter big_map nat nat : @storage unit ] */ ; - PUSH (option nat) - (Some 1) - /* [ option nat : @parameter big_map nat nat : @storage unit ] */ ; - PUSH nat 1 - /* [ nat : option nat : @parameter big_map nat nat : @storage unit ] */ ; - UPDATE - /* [ @parameter big_map nat nat : @storage unit ] */ ; - DROP - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract.tz].out deleted file mode 100644 index fe17421a4c85..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract.tz].out +++ /dev/null @@ -1,75 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/create_contract.tz] - -Well typed -Gas remaining: 1039968.907 units remaining -{ parameter (option address) ; - storage unit ; - code { /* [ pair (string @parameter) (string @storage) ] */ - CAR - /* [ list operation : @parameter string ] */ ; - IF_NONE - { /* [ list operation : @parameter string ] */ - PUSH string "dummy" - /* [ string ] */ ; - PUSH mutez 100000000 - /* [ mutez : string ] */ ; - NONE key_hash - /* [ option key_hash : mutez : string ] */ ; - CREATE_CONTRACT - { parameter string ; - storage string ; - code { CAR ; NIL operation ; PAIR } } - /* [ operation : address ] */ ; - DIP { SOME - /* [ option address ] */ ; - DIP { SELF - /* [ @self contract (option address) ] */ ; - PUSH mutez 0 - /* [ mutez : @self contract (option address) ] */ } - /* [ option address : mutez : @self contract (option address) ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - NIL operation - /* [ list operation : operation ] */ ; - SWAP - /* [ operation : list operation ] */ ; - CONS - /* [ list operation ] */ } - /* [ operation : list operation ] */ ; - CONS - /* [ list operation ] */ ; - UNIT - /* [ unit : list operation ] */ ; - SWAP - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } - { SELF - /* [ @self contract (option address) : @parameter.some address ] */ ; - ADDRESS - /* [ @self.address address : @parameter.some address ] */ ; - SENDER - /* [ @sender address : @self.address address : @parameter.some address ] */ ; - IFCMPNEQ { FAIL } { /* [ @parameter.some address ] */ } ; - CONTRACT string - /* [ @parameter.some.contract option (contract string) ] */ ; - IF_SOME { /* [ @parameter.some.contract.some contract string ] */ } { FAIL } ; - PUSH mutez 0 - /* [ mutez : @parameter.some.contract.some contract string ] */ ; - PUSH string - "abcdefg" - /* [ string : mutez : @parameter.some.contract.some contract string ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - NIL operation - /* [ list operation : operation ] */ ; - SWAP - /* [ operation : list operation ] */ ; - CONS - /* [ list operation ] */ ; - UNIT - /* [ unit : list operation ] */ ; - SWAP - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract_simple.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract_simple.tz].out deleted file mode 100644 index 09a505e2b3a9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract_simple.tz].out +++ /dev/null @@ -1,29 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/create_contract_simple.tz] - -Well typed -Gas remaining: 1039989.249 units remaining -{ parameter unit ; - storage unit ; - code { CAR - /* [ @parameter string ] */ ; - PUSH string - "foo" - /* [ pair (list operation) (string @parameter) ] */ - /* [ list operation : @parameter string ] */ ; - PUSH mutez 0 - /* [ mutez : string : @parameter unit ] */ ; - NONE key_hash - /* [ option key_hash : mutez : string : @parameter unit ] */ ; - CREATE_CONTRACT - { parameter string ; - storage string ; - code { CAR ; NIL operation ; PAIR } } - /* [ operation : address : @parameter unit ] */ ; - DROP - /* [ address : @parameter unit ] */ ; - DROP - /* [ @parameter unit ] */ ; - NIL operation - /* [ list operation : @parameter unit ] */ ; - PAIR - /* [ pair (list operation) (unit @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--default_account.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--default_account.tz].out deleted file mode 100644 index 0d6e700dec3e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--default_account.tz].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/default_account.tz] - -Well typed -Gas remaining: 1039992.790 units remaining -{ parameter key_hash ; - storage unit ; - code { DIP { UNIT /* [ unit ] */ } - /* [ pair (key_hash @parameter) (unit @storage) : unit ] */ ; - CAR - /* [ @parameter key_hash : unit ] */ ; - IMPLICIT_ACCOUNT - /* [ contract unit : unit ] */ ; - PUSH mutez 100000000 - /* [ mutez : contract unit : unit ] */ ; - UNIT - /* [ unit : mutez : contract unit : unit ] */ ; - TRANSFER_TOKENS - /* [ operation : unit ] */ ; - NIL operation - /* [ list operation : operation : unit ] */ ; - SWAP - /* [ operation : list operation : unit ] */ ; - CONS - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_appender.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_appender.tz].out deleted file mode 100644 index 36cef4d6a9ea..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_appender.tz].out +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/execution_order_appender.tz] - -Well typed -Gas remaining: 1039989.364 units remaining -{ parameter unit ; - storage (pair address string) ; - code { CDR - /* [ @storage pair address string ] */ ; - DUP - /* [ @storage pair address string : @storage pair address string ] */ ; - UNPAIR - /* [ address : string : @storage pair address string ] */ ; - CONTRACT - string - /* [ @contract option (contract string) : string - : @storage pair address string ] */ ; - ASSERT_SOME ; - PUSH mutez - 0 - /* [ mutez : @contract.some contract string : string - : @storage pair address string ] */ ; - DIG 2 - /* [ string : mutez : @contract.some contract string - : @storage pair address string ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage pair address string ] */ ; - NIL operation - /* [ list operation : operation : @storage pair address string ] */ ; - SWAP - /* [ operation : list operation : @storage pair address string ] */ ; - CONS - /* [ list operation : @storage pair address string ] */ ; - PAIR - /* [ pair (list operation) (pair @storage address string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_caller.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_caller.tz].out deleted file mode 100644 index ad95e74b3045..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_caller.tz].out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/execution_order_caller.tz] - -Well typed -Gas remaining: 1039991.291 units remaining -{ parameter unit ; - storage (list address) ; - code { CDR - /* [ @storage list address ] */ ; - DUP - /* [ @storage list address : @storage list address ] */ ; - MAP { CONTRACT - unit - /* [ @storage.elt.contract option (contract unit) : @storage list address ] */ ; - ASSERT_SOME ; - PUSH mutez - 0 - /* [ mutez : @storage.elt.contract.some contract unit : @storage list address ] */ ; - UNIT - /* [ unit : mutez : @storage.elt.contract.some contract unit - : @storage list address ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage list address ] */ } - /* [ list operation : @storage list address ] */ ; - PAIR - /* [ pair (list operation) (list @storage address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_storer.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_storer.tz].out deleted file mode 100644 index 34629670e303..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_storer.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/execution_order_storer.tz] - -Well typed -Gas remaining: 1039996.340 units remaining -{ parameter string ; - storage string ; - code { UNPAIR - /* [ @parameter string : @storage string ] */ ; - SWAP - /* [ @storage string : @parameter string ] */ ; - CONCAT - /* [ string ] */ ; - NIL operation - /* [ list operation : string ] */ ; - PAIR - /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--fa12_reference.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--fa12_reference.tz].out deleted file mode 100644 index 005bcaf73f60..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--fa12_reference.tz].out +++ /dev/null @@ -1,2761 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/fa12_reference.tz] - -Well typed -Gas remaining: 1039229.258 units remaining -{ parameter - (or (or (or (pair %transfer (address :from) (pair (address :to) (nat :value))) - (pair %approve (address :spender) (nat :value))) - (or (pair %getAllowance (pair (address :owner) (address :spender)) (contract nat)) - (or (pair %getBalance (address :owner) (contract nat)) - (pair %getTotalSupply unit (contract nat))))) - (or (or (bool %setPause) (address %setAdministrator)) - (or (pair %getAdministrator unit (contract address)) - (or (pair %mint (address :to) (nat :value)) (pair %burn (address :from) (nat :value)))))) ; - storage - (pair (big_map %ledger - (address :user) - (pair (nat :balance) (map :approvals (address :spender) (nat :value)))) - (pair (address %admin) (pair (bool %paused) (nat %totalSupply)))) ; - code { CAST (pair (or (or (or (pair address (pair address nat)) (pair address nat)) - (or (pair (pair address address) (contract nat)) - (or (pair address (contract nat)) (pair unit (contract nat))))) - (or (or bool address) - (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) - (pair (big_map address (pair nat (map address nat))) (pair address (pair bool nat)))) - /* [ pair (or (or (or (pair address address nat) (pair address nat)) - (or (pair (pair address address) (contract nat)) - (or (pair address (contract nat)) (pair unit (contract nat))))) - (or (or bool address) - (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) - (big_map address (pair nat (map address nat))) - address - bool - nat ] */ ; - DUP - /* [ pair (or (or (or (pair address address nat) (pair address nat)) - (or (pair (pair address address) (contract nat)) - (or (pair address (contract nat)) (pair unit (contract nat))))) - (or (or bool address) - (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) - (big_map address (pair nat (map address nat))) - address - bool - nat - : pair (or (or (or (pair address address nat) (pair address nat)) - (or (pair (pair address address) (contract nat)) - (or (pair address (contract nat)) (pair unit (contract nat))))) - (or (or bool address) - (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) - (big_map address (pair nat (map address nat))) - address - bool - nat ] */ ; - CAR - /* [ or (or (or (pair address address nat) (pair address nat)) - (or (pair (pair address address) (contract nat)) - (or (pair address (contract nat)) (pair unit (contract nat))))) - (or (or bool address) - (or (pair unit (contract address)) (or (pair address nat) (pair address nat)))) - : pair (or (or (or (pair address address nat) (pair address nat)) - (or (pair (pair address address) (contract nat)) - (or (pair address (contract nat)) (pair unit (contract nat))))) - (or (or bool address) - (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) - (big_map address (pair nat (map address nat))) - address - bool - nat ] */ ; - DIP { CDR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ or (or (or (pair address address nat) (pair address nat)) - (or (pair (pair address address) (contract nat)) - (or (pair address (contract nat)) (pair unit (contract nat))))) - (or (or bool address) - (or (pair unit (contract address)) (or (pair address nat) (pair address nat)))) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_LEFT - { IF_LEFT - { IF_LEFT - { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ bool - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { UNIT - /* [ unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH string - "TokenOperationsArePaused" - /* [ string : unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } - { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address address nat : pair address address nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ address : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : address : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - COMPARE - /* [ int : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { DROP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SENDER - /* [ @sender address : address : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - COMPARE - /* [ int : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SENDER - /* [ @sender address : address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (address @sender) address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair (address @sender) address : pair (address @sender) address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { EMPTY_MAP - address - nat - /* [ map address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { CDR - /* [ map address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - /* [ pair (address @sender) address : map address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ @sender address : map address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { /* [ @some nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - /* [ pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address address nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { SENDER - /* [ @sender address : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address address nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address address nat : nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ nat : nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SUB - /* [ int : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ISNAT - /* [ option nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { DIP { DUP - /* [ nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address address nat : nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address address nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : pair address address nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address address nat : nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH string - "NotEnoughAllowance" - /* [ string : pair nat nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string nat nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - /* [ @sender address : @some nat : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (address @sender) (nat @some) : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : pair (address @sender) (nat @some) : pair address address nat - : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair address (address @sender) (nat @some) : pair address address nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DROP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address (address @sender) (nat @some) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : address : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : big_map address (pair nat (map address nat)) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option (pair nat (map address nat)) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { EMPTY_MAP - address - nat - /* [ map address nat : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : map address nat : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EMPTY_MAP - address - nat - /* [ map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ map address nat : @some pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { DIP { DUP - /* [ pair address (address @sender) (nat @some) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address (address @sender) (nat @some) : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ map address nat : pair address (address @sender) (nat @some) - : pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address (address @sender) (nat @some) : map address nat - : pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair (address @sender) (nat @some) : map address nat - : pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ @some nat : map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ @some nat : @some nat : map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int : @some nat : map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : @some nat : map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { DROP - /* [ map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NONE nat - /* [ option nat : map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { SOME - /* [ option nat : map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { DIP { DIP { DUP - /* [ pair address (address @sender) (nat @some) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address (address @sender) (nat @some) : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ map address nat : pair address (address @sender) (nat @some) - : pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address (address @sender) (nat @some) : map address nat - : pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ option nat : pair address (address @sender) (nat @some) : map address nat - : pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address (address @sender) (nat @some) : option nat : map address nat - : pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair (address @sender) (nat @some) : option nat : map address nat - : pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ @sender address : option nat : map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - UPDATE - /* [ map address nat : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair nat (map address nat) : pair nat (map address nat) - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ nat : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair nat (map address nat) : nat - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ map address nat : nat : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ map address nat : map address nat : nat - : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ nat : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ map address nat : nat : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ nat : map address nat : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat (map address nat) : pair address (address @sender) (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address (address @sender) (nat @some) : pair nat (map address nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : pair nat (map address nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { SOME - /* [ option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - UPDATE - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR /* [ pair address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - DIP { DROP /* [ pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : big_map address (pair nat (map address nat)) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option (pair nat (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { NONE (pair nat (map address nat)) - /* [ option (pair nat (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { EMPTY_MAP - address - nat - /* [ map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SOME - /* [ option (pair nat (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - { DIP { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some pair nat (map address nat) : pair address address nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address address nat : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ nat : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : nat : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ADD - /* [ nat : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some pair nat (map address nat) : map address nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ nat : map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : nat : map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SOME - /* [ option (pair nat (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - SWAP - /* [ pair address address nat : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address address nat : pair address address nat - : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ pair address nat : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - UPDATE - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR /* [ pair address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - DIP { DROP /* [ pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ int : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ADD - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ISNAT - /* [ option nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { PUSH string - "Internal: Negative total supply" - /* [ string - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address bool nat : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair bool nat : pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair bool nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ bool : @some nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair bool (nat @some) : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ address : pair bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - CDR - /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool (nat @some) : pair address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool (nat @some) - : big_map address (pair nat (map address nat)) ] */ ; - SWAP - /* [ big_map address (pair nat (map address nat)) - : pair address bool (nat @some) ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ address : big_map address (pair nat (map address nat)) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - GET - /* [ option (pair nat (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - IF_NONE - { CDR - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PUSH nat - 0 - /* [ nat : nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ nat : nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PAIR - /* [ pair nat nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PUSH string - "NotEnoughBalance" - /* [ string : pair nat nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PAIR - /* [ pair string nat nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - FAILWITH - /* [] */ } - { /* [ @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; - DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CAR - /* [ nat : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DIP { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ @some pair nat (map address nat) : pair address address nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ pair address address nat : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ nat : pair address address nat : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ pair address address nat : nat : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ pair address nat : nat : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ nat : nat : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ nat : nat : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SUB - /* [ int : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - ISNAT - /* [ option nat : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - IF_NONE - { CAR - /* [ nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ nat : pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ pair address address nat : nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ pair address nat : nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ nat : nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PAIR - /* [ pair nat nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PUSH string - "NotEnoughBalance" - /* [ string : pair nat nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PAIR - /* [ pair string nat nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat : @some pair nat (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; - DIP { DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { CDR - /* [ map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ @some pair nat (map address nat) : map address nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CAR - /* [ nat : map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ @some nat : nat : map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DROP - /* [ map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ @some nat : map address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PAIR - /* [ pair (nat @some) (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair (nat @some) (map address nat) : pair address address nat - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ pair address address nat : pair (nat @some) (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair (nat @some) (map address nat) : pair (nat @some) (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CAR - /* [ @some nat : pair (nat @some) (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - INT - /* [ int : pair (nat @some) (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - EQ - /* [ bool : pair (nat @some) (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - IF { DUP - /* [ pair (nat @some) (map address nat) : pair (nat @some) (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ map address nat : pair (nat @some) (map address nat) - : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SIZE - /* [ nat : pair (nat @some) (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - INT - /* [ int : pair (nat @some) (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - EQ - /* [ bool : pair (nat @some) (map address nat) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - IF { DROP - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - NONE (pair nat (map address nat)) - /* [ option (pair nat (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - { SOME - /* [ option (pair (nat @some) (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } } - { SOME - /* [ option (pair (nat @some) (map address nat)) : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; - SWAP - /* [ pair address address nat : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CAR - /* [ address : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ address : option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - UPDATE - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { CDR /* [ pair address bool (nat @some) ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair address bool (nat @some) ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) - : pair address bool (nat @some) ] */ } - /* [ big_map address (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair address bool (nat @some) ] */ ; - DIP { DROP /* [ pair address bool (nat @some) ] */ } - /* [ big_map address (pair nat (map address nat)) - : pair address bool (nat @some) ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DUP - /* [ pair address address nat : pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { CDR - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - NEG - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ pair address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ pair bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ @some nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ int : @some nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - ADD - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - ISNAT - /* [ option nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - IF_NONE - { PUSH string - "Internal: Negative total supply" - /* [ string - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ pair address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ @some nat : pair address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair address bool (nat @some) : pair address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair address bool (nat @some) : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ pair bool (nat @some) : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ @some nat : pair bool (nat @some) : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair bool (nat @some) : pair bool (nat @some) : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { CAR - /* [ bool : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair bool (nat @some) : bool : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - CDR - /* [ @some nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ @some nat : @some nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DROP - /* [ bool : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ @some nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ bool : @some nat : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PAIR - /* [ pair bool (nat @some) : address - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - SWAP - /* [ address : pair bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PAIR - /* [ pair address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) - : big_map address (pair nat (map address nat)) ] */ ; - CDR - /* [ pair address bool (nat @some) - : big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool (nat @some) : pair address bool (nat @some) - : big_map address (pair nat (map address nat)) ] */ ; - DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool (nat @some) - : big_map address (pair nat (map address nat)) ] */ ; - SWAP - /* [ big_map address (pair nat (map address nat)) - : pair address bool (nat @some) ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair address address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DROP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; - NIL operation - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } - { SENDER - /* [ @sender address : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ bool - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { UNIT - /* [ unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH string - "TokenOperationsArePaused" - /* [ string : unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } - { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - /* [ pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (address @sender) address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (address @sender) address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair (address @sender) address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ @sender address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @sender address : big_map address (pair nat (map address nat)) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option (pair nat (map address nat)) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { EMPTY_MAP - address - nat - /* [ map address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { CDR - /* [ map address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - /* [ pair (address @sender) address nat : map address nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : map address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : map address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { /* [ @some nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DUP - /* [ nat : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { DROP - /* [ pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { DIP { DUP - /* [ pair (address @sender) address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : pair (address @sender) address nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (address @sender) address nat : nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { DROP - /* [ pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { PUSH string - "UnsafeAllowanceChange" - /* [ string : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } } ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (address @sender) address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ @sender address : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : @sender address : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ @sender address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @sender address : big_map address (pair nat (map address nat)) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option (pair nat (map address nat)) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { EMPTY_MAP - address - nat - /* [ map address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : map address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat (map address nat) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EMPTY_MAP - address - nat - /* [ map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ map address nat : @some pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { DIP { DUP - /* [ pair (address @sender) address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair nat (map address nat) : pair (address @sender) address nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (address @sender) address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ map address nat : pair (address @sender) address nat - : pair nat (map address nat) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (address @sender) address nat : map address nat - : pair nat (map address nat) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ nat : nat : map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int : nat : map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : nat : map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { DROP - /* [ map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NONE nat - /* [ option nat : map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { SOME - /* [ option nat : map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { DIP { DIP { DUP - /* [ pair (address @sender) address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair nat (map address nat) : pair (address @sender) address nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (address @sender) address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ map address nat : pair (address @sender) address nat - : pair nat (map address nat) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (address @sender) address nat : map address nat - : pair nat (map address nat) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ option nat : pair (address @sender) address nat : map address nat - : pair nat (map address nat) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (address @sender) address nat : option nat : map address nat - : pair nat (map address nat) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address nat : option nat : map address nat - : pair nat (map address nat) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : option nat : map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - UPDATE - /* [ map address nat : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair nat (map address nat) : pair nat (map address nat) - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair nat (map address nat) : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ map address nat : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ map address nat : map address nat : nat - : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ map address nat : nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ nat : map address nat : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat (map address nat) : pair (address @sender) address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (address @sender) address nat : pair nat (map address nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ @sender address : pair nat (map address nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { SOME - /* [ option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @sender address : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @sender address : option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - UPDATE - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR /* [ pair address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - DIP { DROP /* [ pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NIL operation - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } } - { IF_LEFT - { DUP - /* [ pair (pair address address) (contract nat) - : pair (pair address address) (contract nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ pair address address : pair (pair address address) (contract nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address address : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address address - : pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (pair address address) - (big_map address (pair nat (map address nat))) - address - bool - nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair (pair address address) - (big_map address (pair nat (map address nat))) - address - bool - nat - : pair (pair address address) - (big_map address (pair nat (map address nat))) - address - bool - nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ pair address address - : pair (pair address address) - (big_map address (pair nat (map address nat))) - address - bool - nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address address - : pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address address : pair address address - : pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : big_map address (pair nat (map address nat)) : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option (pair nat (map address nat)) : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { EMPTY_MAP - address - nat - /* [ map address nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { CDR - /* [ map address nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - /* [ pair address address : map address nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ address : map address nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { /* [ @some nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { AMOUNT - /* [ @amount mutez : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : @amount mutez : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NIL operation - /* [ list operation : operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ operation : list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CONS - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } - { IF_LEFT - { DUP - /* [ pair address (contract nat) : pair address (contract nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : pair address (contract nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair address (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address (big_map address (pair nat (map address nat))) address bool nat - : pair address (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address - : pair address (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : big_map address (pair nat (map address nat)) : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option (pair nat (map address nat)) : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { CAR - /* [ nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { AMOUNT - /* [ @amount mutez : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : @amount mutez : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NIL operation - /* [ list operation : operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ operation : list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CONS - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } - { DUP - /* [ pair unit (contract nat) : pair unit (contract nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ unit : pair unit (contract nat) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ unit : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ unit : pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair unit (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { AMOUNT - /* [ @amount mutez : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : @amount mutez : contract nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NIL operation - /* [ list operation : operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ operation : list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CONS - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } } } } - { IF_LEFT - { IF_LEFT - { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SENDER - /* [ @sender address : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - COMPARE - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { UNIT - /* [ unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH string - "SenderIsNotAdmin" - /* [ string : unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } } - /* [ bool - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ bool : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address bool nat : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ bool : pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair bool nat : pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair bool nat : nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ bool : nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ bool : bool : nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ bool : nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ address : pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - CDR - /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool nat : pair address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ ; - SWAP - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NIL operation - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } - { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SENDER - /* [ @sender address : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - COMPARE - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { UNIT - /* [ unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH string - "SenderIsNotAdmin" - /* [ string : unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } } - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address bool nat : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address bool nat : pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : address : pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - CDR - /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool nat : pair address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ ; - SWAP - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NIL operation - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } } - { IF_LEFT - { DUP - /* [ pair unit (contract address) : pair unit (contract address) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ unit : pair unit (contract address) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ unit : contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ contract address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ unit : pair (big_map address (pair nat (map address nat))) address bool nat - : contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair unit (big_map address (pair nat (map address nat))) address bool nat - : contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat : contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { AMOUNT - /* [ @amount mutez : contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : @amount mutez : contract address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NIL operation - /* [ list operation : operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ operation : list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CONS - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } - { IF_LEFT - { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SENDER - /* [ @sender address : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - COMPARE - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { UNIT - /* [ unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH string - "SenderIsNotAdmin" - /* [ string : unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } } - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : big_map address (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { NONE (pair nat (map address nat)) - /* [ option (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { EMPTY_MAP - address - nat - /* [ map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SOME - /* [ option (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - { DIP { DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some pair nat (map address nat) : pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ADD - /* [ nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some pair nat (map address nat) : map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ nat : map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : nat : map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SOME - /* [ option (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - SWAP - /* [ pair address nat : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address nat : pair address nat : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ address : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - UPDATE - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR /* [ pair address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - DIP { DROP /* [ pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ int : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ADD - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ISNAT - /* [ option nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { PUSH string - "Internal: Negative total supply" - /* [ string - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address bool nat : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair bool nat : pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair bool nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ bool : @some nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair bool (nat @some) : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ address : pair bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - CDR - /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool (nat @some) : pair address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool (nat @some) - : big_map address (pair nat (map address nat)) ] */ ; - SWAP - /* [ big_map address (pair nat (map address nat)) - : pair address bool (nat @some) ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DROP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - NIL operation - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PAIR - /* [ pair (list operation) - (big_map address (pair nat (map address nat))) - address - bool - (nat @some) ] */ } - { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SENDER - /* [ @sender address : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - COMPARE - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { UNIT - /* [ unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH string - "SenderIsNotAdmin" - /* [ string : unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string unit - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } } - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ big_map address (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : big_map address (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - GET - /* [ option (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { CDR - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH nat - 0 - /* [ nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ nat : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH string - "NotEnoughBalance" - /* [ string : pair nat nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string nat nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } - { /* [ @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some pair nat (map address nat) : pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : pair address nat : @some pair nat (map address nat) - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address nat : nat : @some pair nat (map address nat) - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ nat : nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SUB - /* [ int : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ISNAT - /* [ option nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { CAR - /* [ nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ nat : pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address nat : nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair nat nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PUSH string - "NotEnoughBalance" - /* [ string : pair nat nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair string nat nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat : @some pair nat (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { DUP - /* [ @some pair nat (map address nat) : @some pair nat (map address nat) - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some pair nat (map address nat) : map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ nat : map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : nat : map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : map address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair (nat @some) (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair (nat @some) (map address nat) : pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ pair address nat : pair (nat @some) (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (nat @some) (map address nat) : pair (nat @some) (map address nat) - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ @some nat : pair (nat @some) (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int : pair (nat @some) (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : pair (nat @some) (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { DUP - /* [ pair (nat @some) (map address nat) : pair (nat @some) (map address nat) - : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ map address nat : pair (nat @some) (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SIZE - /* [ nat : pair (nat @some) (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - INT - /* [ int : pair (nat @some) (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - EQ - /* [ bool : pair (nat @some) (map address nat) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF { DROP - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NONE (pair nat (map address nat)) - /* [ option (pair nat (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - { SOME - /* [ option (pair (nat @some) (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } - { SOME - /* [ option (pair (nat @some) (map address nat)) : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - SWAP - /* [ pair address nat : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ address : option (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ address : option (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - UPDATE - /* [ big_map address (pair nat (map address nat)) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR /* [ pair address bool nat ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair address bool nat ] */ ; - CAR - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) - : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - DIP { DROP /* [ pair address bool nat ] */ } - /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DUP - /* [ pair address nat : pair address nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CDR - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - NEG - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ int : nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ADD - /* [ int - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - ISNAT - /* [ option nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - IF_NONE - { PUSH string - "Internal: Negative total supply" - /* [ string - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair address bool nat : pair address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair address bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair bool nat : pair bool nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR - /* [ bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ pair bool nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - CDR - /* [ nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DROP - /* [ bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } - /* [ @some nat : bool : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ bool : @some nat : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair bool (nat @some) : address - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - SWAP - /* [ address : pair bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - PAIR - /* [ pair address bool (nat @some) - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { DUP - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; - DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair (big_map address (pair nat (map address nat))) address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - CDR - /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool (nat @some) : pair address bool nat - : big_map address (pair nat (map address nat)) ] */ ; - DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } - /* [ pair address bool (nat @some) - : big_map address (pair nat (map address nat)) ] */ ; - SWAP - /* [ big_map address (pair nat (map address nat)) - : pair address bool (nat @some) ] */ ; - PAIR - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } - /* [ pair address nat - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - DROP - /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - NIL operation - /* [ list operation - : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; - PAIR - /* [ pair (list operation) - (big_map address (pair nat (map address nat))) - address - bool - (nat @some) ] */ } } } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--generic_multisig.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--generic_multisig.tz].out deleted file mode 100644 index 7d056c6f0916..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--generic_multisig.tz].out +++ /dev/null @@ -1,438 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/generic_multisig.tz] - -Well typed -Gas remaining: 1039928.421 units remaining -{ parameter - (or (unit %default) - (pair %main - (pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)))) - (list %sigs (option signature)))) ; - storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; - code { UNPAIR - /* [ @parameter or (unit %default) - (pair %main - (pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)))) - (list %sigs (option signature))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - IF_LEFT - { DROP - /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - NIL operation - /* [ list operation - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage (nat %stored_counter) (nat %threshold) (list %keys key)) ] */ } - { PUSH mutez - 0 - /* [ mutez - : @parameter.main pair (pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)))) - (list %sigs (option signature)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - AMOUNT - /* [ @amount mutez : mutez - : @parameter.main pair (pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)))) - (list %sigs (option signature)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ASSERT_CMPEQ ; - SWAP - /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @parameter.main pair (pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)))) - (list %sigs (option signature)) ] */ ; - DUP - /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @parameter.main pair (pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)))) - (list %sigs (option signature)) ] */ ; - DIP { SWAP - /* [ @parameter.main pair (pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)))) - (list %sigs (option signature)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @parameter.main pair (pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)))) - (list %sigs (option signature)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { UNPAIR - /* [ pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DUP - /* [ pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SELF - /* [ @self contract unit - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ADDRESS - /* [ @self.address address - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - CHAIN_ID - /* [ chain_id : @self.address address - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - PAIR - /* [ pair chain_id (address @self.address) - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - PAIR - /* [ pair (pair chain_id (address @self.address)) - (pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)))) - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - PACK - /* [ @packed bytes - : pair :payload - (nat %counter) - (or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { UNPAIR @counter - /* [ @counter nat - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { SWAP - /* [ list (option signature) - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @counter nat : list (option signature) - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @packed bytes : @counter nat : list (option signature) - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ @counter nat : @packed bytes : list (option signature) - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @counter nat : @packed bytes : list (option signature) - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - UNPAIR @stored_counter - /* [ @stored_counter nat : pair (nat %threshold) (list %keys key) : @counter nat - : @packed bytes : list (option signature) - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { SWAP - /* [ @counter nat : pair (nat %threshold) (list %keys key) : @packed bytes - : list (option signature) - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @stored_counter nat : @counter nat : pair (nat %threshold) (list %keys key) - : @packed bytes : list (option signature) - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ASSERT_CMPEQ ; - DIP { SWAP - /* [ list (option signature) : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ pair (nat %threshold) (list %keys key) : list (option signature) - : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - UNPAIR @threshold @keys - /* [ @threshold nat : @keys list key : list (option signature) : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { PUSH @valid - nat - 0 - /* [ @valid nat : @keys list key : list (option signature) : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ @keys list key : @valid nat : list (option signature) : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ITER { DIP { SWAP - /* [ list (option signature) : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @keys.elt key : list (option signature) : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ list (option signature) : @keys.elt key : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - IF_CONS - { IF_SOME - { SWAP - /* [ @tl list (option signature) : @hd.some signature : @keys.elt key - : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { SWAP - /* [ @keys.elt key : @hd.some signature : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIIP { DUUP - /* [ bytes : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @keys.elt key : @hd.some signature : bytes : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - { DUUUP - /* [ bytes : @keys.elt key : @hd.some signature : bytes : @valid nat - : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { CHECK_SIGNATURE - /* [ bool : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ bytes : bool : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ bool : bytes : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - IF { DROP - /* [ @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - { FAILWITH /* [] */ } } ; - PUSH nat - 1 - /* [ nat : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ADD @valid - /* [ @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @tl list (option signature) : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - { SWAP - /* [ @keys.elt key : @tl list (option signature) : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DROP - /* [ @tl list (option signature) : @valid nat : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } } - { FAIL } ; - SWAP - /* [ @valid nat : @tl list (option signature) : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @valid nat : list (option signature) : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @threshold nat : @valid nat : list (option signature) : @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ASSERT_CMPLE ; - IF_CONS - { FAIL } - { /* [ @packed bytes - : or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } ; - DROP - /* [ or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { UNPAIR - /* [ nat : pair (nat %threshold) (list %keys key) ] */ ; - PUSH nat 1 - /* [ nat : nat : pair (nat %threshold) (list %keys key) ] */ ; - ADD @new_counter - /* [ @new_counter nat : pair (nat %threshold) (list %keys key) ] */ ; - PAIR - /* [ pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } - /* [ or :action - (lambda %operation unit (list operation)) - (pair %change_keys (nat %threshold) (list %keys key)) - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; - IF_LEFT - { UNIT - /* [ unit : @operation lambda unit (list operation) - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; - EXEC - /* [ list operation - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } - { DIP { CAR /* [ @new_counter nat ] */ } - /* [ @change_keys pair (nat %threshold) (list %keys key) : @new_counter nat ] */ ; - SWAP - /* [ @new_counter nat : @change_keys pair (nat %threshold) (list %keys key) ] */ ; - PAIR - /* [ pair (nat @new_counter) (pair @change_keys (nat %threshold) (list %keys key)) ] */ ; - NIL operation - /* [ list operation - : pair (nat @new_counter) (pair @change_keys (nat %threshold) (list %keys key)) ] */ } ; - PAIR - /* [ pair (list operation) (nat @new_counter) (nat %threshold) (list %keys key) ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--groth16.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--groth16.tz].out deleted file mode 100644 index f9c2c339693a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--groth16.tz].out +++ /dev/null @@ -1,233 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/groth16.tz] - -Well typed -Gas remaining: 1039478.027 units remaining -{ storage unit ; - parameter - (pair (pair (bls12_381_fr %input_x) (bls12_381_fr %input_y)) - (pair (pair (bls12_381_g1 %proof_a) (bls12_381_g2 %proof_b)) (bls12_381_g1 %proof_c))) ; - code { CAR - /* [ @parameter pair (pair (bls12_381_fr %input_x) (bls12_381_fr %input_y)) - (pair (bls12_381_g1 %proof_a) (bls12_381_g2 %proof_b)) - (bls12_381_g1 %proof_c) ] */ ; - UNPPAIPPAIIR ; - DIP 5 - { PUSH @vk_gamma_c - bls12_381_g1 - 0x063bd6e11e2fcaac1dd8cf68c6b1925a73c3c583e298ed37c41c3715115cf96358a42dbe85a0228cbfd8a6c8a8c54cd015b5ae2860d1cc47f84698d951f14d9448d03f04df2ca0ffe609a2067d6f1a892163a5e05e541279134cae52b1f23c6b - /* [ @vk_gamma_c bls12_381_g1 ] */ ; - PUSH @vk_gamma_b - bls12_381_g1 - 0x11f5b5db1da7f1f26217edcce2219d016003af6e5b4d1ca3ad0ff477e354717e658bf16beddc4f4fb76ce39d3327811e0601709dc7ed98c70463cfa1ba33f99851b52b51d1a042d7425bec6277287441c399973632445ce61e7fdd63a70f0f60 - /* [ @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - PUSH @vk_gamma_a - bls12_381_g1 - 0x03535a322edd23c55b0ca025e54d450d95df49cc9ee873dcd500e8219f4771264bf159b3b105954d85c7bea8ffe1ea0400c767fe58989366c2837fba76f1b4f46644f19be8ad01e22d894b649e427e0d7e04677ee3919d982f0f96bb0a2f0c34 - /* [ @vk_gamma_a bls12_381_g1 : @vk_gamma_b bls12_381_g1 - : @vk_gamma_c bls12_381_g1 ] */ ; - PUSH @vk_delta - bls12_381_g2 - 0x10c6d5cdca84fc3c7f33061add256f48e0ab03a697832b338901898b650419eb6f334b28153fb73ad2ecd1cd2ac67053161e9f46cfbdaf7b1132a4654a55162850249650f9b873ac3113fa8c02ef1cd1df481480a4457f351d28f4da89d19fa405c3d77f686dc9a24d2681c9184bf2b091f62e6b24df651a3da8bd7067e14e7908fb02f8955b84af5081614cb5bc49b416d9edf914fc608c441b3f2eb8b6043736ddb9d4e4d62334a23b5625c14ef3e1a7e99258386310221b22d83a5eac035c - /* [ @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - PUSH @vk_gamma - bls12_381_g2 - 0x16dcbd28bff336c2649c7dd1d8391ac7ce6f7ef0124a9db7a4a485a124199eded7ce963c1c18aee1eca9994fe06f192c00e0fb653e1fc737d8d0e2f2f91424ca01f6e6e7c5c04f1c43db03a2900cf6b942aaed6ae77daea6200e094b78c38d770028d531a9d1a118ec23d5a39be7aa6dc28f778da1988856d2235c4a35e81fa48380f050d4baf7ebd7b5e058bf294da916afc34562f097c02a8fcbcf62a00de44f8ae6cfa7acb8ad254e3aeea8b2af12f65b7ee0f54855cb9bd432f3436f238f - /* [ @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - PUSH @vk_b - bls12_381_g2 - 0x0e9383f98df2c6e8b5b45f3876c3384596a0cdbc41349f83c4380bf463a050cdbd1d5057aa483a642e66486d1ed7362a1869e423c3877095e215c17282b11108601166f928043254bbce603bf86f4cec9f2e97e9660e98e4f5bce9b2b3bbacb40946b702ccfcc9a31e0bfc1543a2128edcc95807740a2310ae25eb47b935648e392c58dfae5b5e899d3b970d64e4e9e209741ea8bfedcfcc16b3fd890ff02c788ec0943feaaf01bbb354317acb85fcfd611133e4e563d53ca4e0f50e21cf2e7e - /* [ @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 - : @vk_gamma_a bls12_381_g1 : @vk_gamma_b bls12_381_g1 - : @vk_gamma_c bls12_381_g1 ] */ ; - PUSH @vk_a - bls12_381_g1 - 0x1040577c7d349e332735fc947c868c24a665f812f5dc1e7f60e65e2df80be2267a4b7341ed2287285fccd517acd96d910abba947235c364553aa6445f2f2b3a1a728225a330286ba5197ab87f0edc560d89fc7b623812f7d0d633341726e597a - /* [ @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ } - /* [ bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP - /* [ bls12_381_fr : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 - : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 12 - /* [ bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - MUL - /* [ bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 - : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 3 - /* [ bls12_381_fr : bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 14 - /* [ bls12_381_g1 : bls12_381_fr : bls12_381_g1 : bls12_381_fr : bls12_381_fr - : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 - : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 - : @vk_gamma_a bls12_381_g1 : @vk_gamma_b bls12_381_g1 - : @vk_gamma_c bls12_381_g1 ] */ ; - MUL - /* [ bls12_381_g1 : bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - ADD - /* [ bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 - : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 11 - /* [ bls12_381_g1 : bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - ADD @vk_x - /* [ @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - NIL (pair bls12_381_g1 bls12_381_g2) - /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr - : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 9 - /* [ bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 - : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 9 - /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - NEG - /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - PAIR - /* [ pair bls12_381_g1 bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - CONS - /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr - : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 11 - /* [ bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 - : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 8 - /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - NEG - /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - PAIR - /* [ pair bls12_381_g1 bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - CONS - /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr - : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 10 - /* [ bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 - : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 3 - /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - NEG - /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - PAIR - /* [ pair bls12_381_g1 bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - CONS - /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr - : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 6 - /* [ bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 - : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - DUP 6 - /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - PAIR - /* [ pair bls12_381_g1 bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) - : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - CONS - /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr - : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 - : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 - : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - PAIRING_CHECK - /* [ bool : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 - : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 - : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 - : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; - ASSERT ; - DROP 13 - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--hardlimit.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--hardlimit.tz].out deleted file mode 100644 index 07619ac50efb..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--hardlimit.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/hardlimit.tz] - -Well typed -Gas remaining: 1039991.583 units remaining -{ parameter unit ; - storage int ; - code { CDR - /* [ @storage int ] */ ; - DUP - /* [ @storage int : @storage int ] */ ; - PUSH int 0 - /* [ int : @storage int : @storage int ] */ ; - CMPLT ; - IF { PUSH int -1 /* [ int : @storage int ] */ ; ADD /* [ int ] */ } { FAIL } ; - NIL operation - /* [ list operation : int ] */ ; - PAIR - /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--legacy_multisig.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--legacy_multisig.tz].out deleted file mode 100644 index 285bf7585614..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--legacy_multisig.tz].out +++ /dev/null @@ -1,501 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/legacy_multisig.tz] - -Well typed -Gas remaining: 1039931.026 units remaining -{ parameter - (pair (pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))))) - (list %sigs (option signature))) ; - storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; - code { UNPAIR - /* [ @parameter pair (pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))))) - (list %sigs (option signature)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @parameter pair (pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))))) - (list %sigs (option signature)) ] */ ; - DUP - /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @parameter pair (pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))))) - (list %sigs (option signature)) ] */ ; - DIP { SWAP - /* [ @parameter pair (pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))))) - (list %sigs (option signature)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @parameter pair (pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))))) - (list %sigs (option signature)) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { UNPAIR - /* [ pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DUP - /* [ pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SELF - /* [ @self contract - (pair (pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))))) - (list %sigs (option signature))) - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ADDRESS - /* [ @self.address address - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - CHAIN_ID - /* [ chain_id : @self.address address - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - PAIR - /* [ pair chain_id (address @self.address) - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - PAIR - /* [ pair (pair chain_id (address @self.address)) - (pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))))) - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - PACK - /* [ @packed bytes - : pair :payload - (nat %counter) - (or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key)))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { UNPAIR @counter - /* [ @counter nat - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : list (option signature) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { SWAP - /* [ list (option signature) - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @counter nat : list (option signature) - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @packed bytes : @counter nat : list (option signature) - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ @counter nat : @packed bytes : list (option signature) - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) - : @counter nat : @packed bytes : list (option signature) - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - UNPAIR @stored_counter - /* [ @stored_counter nat : pair (nat %threshold) (list %keys key) : @counter nat - : @packed bytes : list (option signature) - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { SWAP - /* [ @counter nat : pair (nat %threshold) (list %keys key) : @packed bytes - : list (option signature) - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @stored_counter nat : @counter nat : pair (nat %threshold) (list %keys key) - : @packed bytes : list (option signature) - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ASSERT_CMPEQ ; - DIP { SWAP - /* [ list (option signature) : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ pair (nat %threshold) (list %keys key) : list (option signature) - : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - UNPAIR @threshold @keys - /* [ @threshold nat : @keys list key : list (option signature) : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { PUSH @valid - nat - 0 - /* [ @valid nat : @keys list key : list (option signature) : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ @keys list key : @valid nat : list (option signature) : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ITER { DIP { SWAP - /* [ list (option signature) : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @keys.elt key : list (option signature) : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ list (option signature) : @keys.elt key : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - IF_CONS - { IF_SOME - { SWAP - /* [ @tl list (option signature) : @hd.some signature : @keys.elt key - : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { SWAP - /* [ @keys.elt key : @hd.some signature : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIIP { DUUP - /* [ bytes : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @keys.elt key : @hd.some signature : bytes : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - { DUUUP - /* [ bytes : @keys.elt key : @hd.some signature : bytes : @valid nat - : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { CHECK_SIGNATURE - /* [ bool : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ bytes : bool : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ bool : bytes : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - IF { DROP - /* [ @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - { FAILWITH /* [] */ } } ; - PUSH nat - 1 - /* [ nat : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ADD @valid - /* [ @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @tl list (option signature) : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - { SWAP - /* [ @keys.elt key : @tl list (option signature) : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DROP - /* [ @tl list (option signature) : @valid nat : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } } - { FAIL } ; - SWAP - /* [ @valid nat : @tl list (option signature) : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @valid nat : list (option signature) : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } - /* [ @threshold nat : @valid nat : list (option signature) : @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - ASSERT_CMPLE ; - DROP - /* [ @packed bytes - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DROP - /* [ or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; - DIP { UNPAIR - /* [ nat : pair (nat %threshold) (list %keys key) ] */ ; - PUSH nat 1 - /* [ nat : nat : pair (nat %threshold) (list %keys key) ] */ ; - ADD @new_counter - /* [ @new_counter nat : pair (nat %threshold) (list %keys key) ] */ ; - PAIR - /* [ pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } - /* [ or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; - NIL operation - /* [ list operation - : or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; - SWAP - /* [ or :action - (pair :transfer (mutez %amount) (contract %dest unit)) - (or (option %delegate key_hash) - (pair %change_keys (nat %threshold) (list %keys key))) : list operation - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; - IF_LEFT - { UNPAIR - /* [ mutez : contract unit : list operation - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; - UNIT - /* [ unit : mutez : contract unit : list operation - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; - TRANSFER_TOKENS - /* [ operation : list operation - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; - CONS - /* [ list operation - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } - { IF_LEFT - { SET_DELEGATE - /* [ operation : list operation - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; - CONS - /* [ list operation - : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } - { DIP { SWAP - /* [ pair (nat @new_counter) (nat %threshold) (list %keys key) - : list operation ] */ ; - CAR - /* [ @new_counter nat : list operation ] */ } - /* [ @change_keys pair (nat %threshold) (list %keys key) : @new_counter nat - : list operation ] */ ; - SWAP - /* [ @new_counter nat : @change_keys pair (nat %threshold) (list %keys key) - : list operation ] */ ; - PAIR - /* [ pair (nat @new_counter) (pair @change_keys (nat %threshold) (list %keys key)) - : list operation ] */ ; - SWAP - /* [ list operation - : pair (nat @new_counter) (pair @change_keys (nat %threshold) (list %keys key)) ] */ } } ; - PAIR - /* [ pair (list operation) (nat @new_counter) (nat %threshold) (list %keys key) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lockup.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lockup.tz].out deleted file mode 100644 index 33e437ec7728..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lockup.tz].out +++ /dev/null @@ -1,48 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/lockup.tz] - -Well typed -Gas remaining: 1039981.235 units remaining -{ parameter unit ; - storage (pair timestamp (pair mutez address)) ; - code { CDR - /* [ @storage pair timestamp mutez address ] */ ; - DUP - /* [ @storage pair timestamp mutez address - : @storage pair timestamp mutez address ] */ ; - CAR - /* [ timestamp : @storage pair timestamp mutez address ] */ ; - NOW - /* [ @now timestamp : timestamp : @storage pair timestamp mutez address ] */ ; - CMPLT ; - IF { FAIL } { /* [ @storage pair timestamp mutez address ] */ } ; - DUP - /* [ @storage pair timestamp mutez address - : @storage pair timestamp mutez address ] */ ; - CDR - /* [ pair mutez address : @storage pair timestamp mutez address ] */ ; - DUP - /* [ pair mutez address : pair mutez address - : @storage pair timestamp mutez address ] */ ; - CAR - /* [ mutez : pair mutez address : @storage pair timestamp mutez address ] */ ; - DIP { CDR /* [ address : @storage pair timestamp mutez address ] */ } - /* [ mutez : address : @storage pair timestamp mutez address ] */ ; - DIP { CONTRACT - unit - /* [ @contract option (contract unit) : @storage pair timestamp mutez address ] */ ; - ASSERT_SOME } - /* [ mutez : @contract.some contract unit - : @storage pair timestamp mutez address ] */ ; - UNIT - /* [ unit : mutez : @contract.some contract unit - : @storage pair timestamp mutez address ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage pair timestamp mutez address ] */ ; - NIL operation - /* [ list operation : operation : @storage pair timestamp mutez address ] */ ; - SWAP - /* [ operation : list operation : @storage pair timestamp mutez address ] */ ; - CONS - /* [ list operation : @storage pair timestamp mutez address ] */ ; - PAIR - /* [ pair (list operation) (pair @storage timestamp mutez address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lqt_fa12.mligo.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lqt_fa12.mligo.tz].out deleted file mode 100644 index 783357fc8422..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lqt_fa12.mligo.tz].out +++ /dev/null @@ -1,2834 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/lqt_fa12.mligo.tz] - -Well typed -Gas remaining: 1039662.882 units remaining -{ parameter - (or (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (pair (address %to) (nat %value))))) ; - storage - (pair (big_map %tokens address nat) - (pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (pair (address %admin) (nat %total_supply)))) ; - code { DUP - /* [ pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) - : pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ ; - CDR - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ ; - PUSH mutez - 0 - /* [ mutez - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ ; - AMOUNT - /* [ @amount mutez : mutez - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ ; - COMPARE - /* [ int - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ ; - NEQ - /* [ bool - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ ; - IF { PUSH string - "DontSendTez" - /* [ string - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ ; - FAILWITH - /* [] */ } - { /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ } ; - SWAP - /* [ pair (or @parameter - (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value)))) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ @parameter or (or (or (pair %approve (address %spender) (nat %value)) - (pair %getAllowance - (pair %request (address %owner) (address %spender)) - (contract %callback nat))) - (or (pair %getBalance (address %owner) (contract %callback nat)) - (pair %getTotalSupply (unit %request) (contract %callback nat)))) - (or (pair %mintOrBurn (int %quantity) (address %target)) - (pair %transfer (address %from) (address %to) (nat %value))) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_LEFT - { IF_LEFT - { IF_LEFT - { SWAP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.left.approve pair (address %spender) (nat %value) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.left.approve pair (address %spender) (nat %value) ] */ ; - DUG 2 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ @parameter.left.left.approve pair (address %spender) (nat %value) - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.left.left.approve pair (address %spender) (nat %value) - : @parameter.left.left.approve pair (address %spender) (nat %value) - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 2 - /* [ @parameter.left.left.approve pair (address %spender) (nat %value) - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SENDER - /* [ @sender address : address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PUSH nat - 0 - /* [ nat : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ @parameter.left.left.approve pair (address %spender) (nat %value) : nat - : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.left.left.approve pair (address %spender) (nat %value) - : @parameter.left.left.approve pair (address %spender) (nat %value) : nat - : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 4 - /* [ @parameter.left.left.approve pair (address %spender) (nat %value) : nat - : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ nat : nat : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - COMPARE - /* [ int : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - GT - /* [ bool : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PUSH nat - 0 - /* [ nat : bool : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ big_map (pair (address %owner) (address %spender)) nat : nat : bool - : pair (address @sender) address - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ big_map (pair (address %owner) (address %spender)) nat - : big_map (pair (address %owner) (address %spender)) nat : nat : bool - : pair (address @sender) address - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 4 - /* [ big_map (pair (address %owner) (address %spender)) nat : nat : bool - : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat : nat : bool - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ pair (address @sender) address : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat : nat : bool - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 4 - /* [ pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat : nat : bool - : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - GET - /* [ option nat : nat : bool : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : nat : bool : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { /* [ @some nat : nat : bool : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - COMPARE - /* [ int : bool : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - GT - /* [ bool : bool : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - AND - /* [ bool : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF { PUSH string - "UnsafeAllowanceChange" - /* [ string : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - FAILWITH - /* [] */ } - { /* [ pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - DIG 3 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) ] */ ; - DUG 4 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %admin) (nat %total_supply) : pair (address @sender) address - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @parameter.left.left.approve pair (address %spender) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ @parameter.left.left.approve pair (address %spender) (nat %value) - : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ nat : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PUSH nat - 0 - /* [ nat : nat : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ nat : nat : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ nat : nat : nat : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 2 - /* [ nat : nat : nat : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - COMPARE - /* [ int : nat : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - EQ - /* [ bool : nat : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF { DROP - /* [ big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NONE nat - /* [ option nat : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { SOME - /* [ option nat : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) : pair (address @sender) address - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - DIG 3 - /* [ pair (address @sender) address : option nat - : big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - UPDATE - /* [ big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ big_map address nat - : pair (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (big_map address nat) - (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NIL operation - /* [ list operation - : pair (big_map address nat) - (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (list operation) - (big_map address nat) - (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { SWAP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) ] */ ; - DIG 2 - /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NIL operation - /* [ list operation - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 2 - /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : list operation - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ contract nat : list operation - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PUSH mutez - 0 - /* [ mutez : contract nat : list operation - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 4 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : mutez : contract nat : list operation - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : mutez : contract nat : list operation - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ big_map (pair (address %owner) (address %spender)) nat : mutez - : contract nat : list operation - : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 4 - /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) - : big_map (pair (address %owner) (address %spender)) nat : mutez - : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ pair (address %owner) (address %spender) - : big_map (pair (address %owner) (address %spender)) nat : mutez - : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - GET - /* [ option nat : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { /* [ @some nat : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - TRANSFER_TOKENS - /* [ operation : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CONS - /* [ list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ } } - { IF_LEFT - { SWAP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) ] */ ; - DIG 2 - /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NIL operation - /* [ list operation - : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 2 - /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : list operation - : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ contract nat : list operation - : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PUSH mutez - 0 - /* [ mutez : contract nat : list operation - : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 4 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : mutez : contract nat : list operation - : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ big_map address nat : mutez : contract nat : list operation - : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 4 - /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) - : big_map address nat : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address : big_map address nat : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - GET - /* [ option nat : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { /* [ @some nat : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - TRANSFER_TOKENS - /* [ operation : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CONS - /* [ list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ } - { SWAP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) ] */ ; - DIG 2 - /* [ @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NIL operation - /* [ list operation - : @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) - : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PUSH mutez - 0 - /* [ mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %admin) (nat %total_supply) : mutez : contract nat - : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ nat : mutez : contract nat : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - TRANSFER_TOKENS - /* [ operation : list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CONS - /* [ list operation - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage - (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply)) ] */ } } } - { IF_LEFT - { SWAP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUG 2 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %admin) (nat %total_supply) - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SENDER - /* [ @sender address : address - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - COMPARE - /* [ int : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NEQ - /* [ bool : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF { PUSH string - "OnlyAdmin" - /* [ string : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - FAILWITH - /* [] */ } - { /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - DUP - /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ int : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : int - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : int - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUG 3 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : int - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ big_map address nat : int - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : big_map address nat : int - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : big_map address nat : int - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 3 - /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : big_map address nat : int - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ address : big_map address nat : int - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - GET - /* [ option nat : int - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : int - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { /* [ @some nat : int - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - ADD - /* [ int : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - ISNAT - /* [ option nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH string - "Cannot burn more than the target's balance." - /* [ string : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - SWAP - /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @some nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @some nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 2 - /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ int : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : int : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : int : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUG 4 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : int : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : int : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %admin) (nat %total_supply) : int : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ nat : int : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - ADD - /* [ int : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - ABS - /* [ nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUG 4 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 4 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - CAR - /* [ big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - PUSH nat - 0 - /* [ nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DIG 4 - /* [ @some nat : nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUP - /* [ @some nat : @some nat : nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DUG 5 - /* [ @some nat : nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - COMPARE - /* [ int : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - EQ - /* [ bool : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat : @some nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - IF { DIG 3 - /* [ @some nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - DROP - /* [ big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - NONE nat - /* [ option nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ } - { DIG 3 - /* [ @some nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; - SOME - /* [ option nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat - : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ } ; - DIG 4 - /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) - : option nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat ] */ ; - CDR - /* [ address : option nat : big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat ] */ ; - UPDATE - /* [ big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat ] */ ; - PAIR - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat ] */ ; - DUP - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat ] */ ; - DUG 2 - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : nat - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %admin) (nat %total_supply) : nat - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address : nat - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair address nat - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : pair address nat ] */ ; - DUP - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : pair address nat ] */ ; - DUG 2 - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : pair address nat - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : pair address nat - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ big_map (pair (address %owner) (address %spender)) nat : pair address nat - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (big_map (pair (address %owner) (address %spender)) nat) address nat - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (big_map (pair (address %owner) (address %spender)) nat) address nat ] */ ; - CAR - /* [ big_map address nat - : pair (big_map (pair (address %owner) (address %spender)) nat) address nat ] */ ; - PAIR - /* [ pair (big_map address nat) - (big_map (pair (address %owner) (address %spender)) nat) - address - nat ] */ ; - NIL operation - /* [ list operation - : pair (big_map address nat) - (big_map (pair (address %owner) (address %spender)) nat) - address - nat ] */ ; - PAIR - /* [ pair (list operation) - (big_map address nat) - (big_map (pair (address %owner) (address %spender)) nat) - address - nat ] */ } - { SWAP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) ] */ ; - DUG 2 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) ] */ ; - DUP - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) ] */ ; - DUG 3 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 3 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SENDER - /* [ @sender address : address : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - COMPARE - /* [ int : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - EQ - /* [ bool : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF { SWAP - /* [ big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { SENDER - /* [ @sender address : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @sender address : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @sender address : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 4 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @sender address : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address : @sender address : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 4 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %to) (nat %value) : pair address (address @sender) - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ nat : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 3 - /* [ big_map (pair (address %owner) (address %spender)) nat : nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ big_map (pair (address %owner) (address %spender)) nat - : big_map (pair (address %owner) (address %spender)) nat : nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 4 - /* [ big_map (pair (address %owner) (address %spender)) nat : nat - : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ pair address (address @sender) - : big_map (pair (address %owner) (address %spender)) nat : nat - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ pair address (address @sender) : pair address (address @sender) - : big_map (pair (address %owner) (address %spender)) nat : nat - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 3 - /* [ pair address (address @sender) - : big_map (pair (address %owner) (address %spender)) nat : nat - : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - GET - /* [ option nat : nat : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : nat : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { /* [ @some nat : nat : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - SUB - /* [ int : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - ISNAT - /* [ option nat : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH string - "NotEnoughAllowance" - /* [ string : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat : pair address (address @sender) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - DIG 3 - /* [ big_map (pair (address %owner) (address %spender)) nat : @some nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PUSH nat - 0 - /* [ nat : big_map (pair (address %owner) (address %spender)) nat : @some nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ @some nat : nat : big_map (pair (address %owner) (address %spender)) nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @some nat : @some nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 3 - /* [ @some nat : nat : big_map (pair (address %owner) (address %spender)) nat - : @some nat : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - COMPARE - /* [ int : big_map (pair (address %owner) (address %spender)) nat : @some nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - EQ - /* [ bool : big_map (pair (address %owner) (address %spender)) nat : @some nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF { SWAP - /* [ @some nat : big_map (pair (address %owner) (address %spender)) nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DROP - /* [ big_map (pair (address %owner) (address %spender)) nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NONE nat - /* [ option nat : big_map (pair (address %owner) (address %spender)) nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { SWAP - /* [ @some nat : big_map (pair (address %owner) (address %spender)) nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SOME - /* [ option nat : big_map (pair (address %owner) (address %spender)) nat - : pair address (address @sender) : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - DIG 2 - /* [ pair address (address @sender) : option nat - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - UPDATE - /* [ big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - DIG 2 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 3 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %to) (nat %value) - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ nat : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ big_map address nat : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 3 - /* [ big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 4 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 5 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - GET - /* [ option nat : nat : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : nat : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { /* [ @some nat : nat : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - SUB - /* [ int : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - ISNAT - /* [ option nat : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH string - "NotEnoughBalance" - /* [ string : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - FAILWITH - /* [] */ } - { /* [ @some nat : big_map (pair (address %owner) (address %spender)) nat - : big_map address nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - DIG 2 - /* [ big_map address nat : @some nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PUSH nat - 0 - /* [ nat : big_map address nat : @some nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ @some nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @some nat : @some nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 3 - /* [ @some nat : nat : big_map address nat : @some nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - COMPARE - /* [ int : big_map address nat : @some nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - EQ - /* [ bool : big_map address nat : @some nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF { SWAP - /* [ @some nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DROP - /* [ big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NONE nat - /* [ option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { SWAP - /* [ @some nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SOME - /* [ option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - DIG 3 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 4 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address : option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - UPDATE - /* [ big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 3 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %to) (nat %value) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ big_map address nat : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 2 - /* [ big_map address nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 4 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 5 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : big_map address nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %to) (nat %value) : big_map address nat : nat - : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address : big_map address nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - GET - /* [ option nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF_NONE - { PUSH nat - 0 - /* [ nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { /* [ @some nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - ADD - /* [ nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PUSH nat - 0 - /* [ nat : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUP - /* [ nat : nat : nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DUG 3 - /* [ nat : nat : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - COMPARE - /* [ int : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - EQ - /* [ bool : big_map address nat : nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - IF { SWAP - /* [ nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DROP - /* [ big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NONE nat - /* [ option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } - { SWAP - /* [ nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SOME - /* [ option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } ; - DIG 3 - /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) - : option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CDR - /* [ pair (address %to) (nat %value) : option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ address : option nat : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - UPDATE - /* [ big_map address nat - : big_map (pair (address %owner) (address %spender)) nat - : @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - DIG 2 - /* [ @storage pair (big_map %tokens address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) : big_map address nat - : big_map (pair (address %owner) (address %spender)) nat ] */ ; - SWAP - /* [ big_map address nat - : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : big_map (pair (address %owner) (address %spender)) nat ] */ ; - PAIR - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : big_map (pair (address %owner) (address %spender)) nat ] */ ; - DUP - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : big_map (pair (address %owner) (address %spender)) nat ] */ ; - CDR - /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : big_map (pair (address %owner) (address %spender)) nat ] */ ; - CDR - /* [ pair (address %admin) (nat %total_supply) - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : big_map (pair (address %owner) (address %spender)) nat ] */ ; - DIG 2 - /* [ big_map (pair (address %owner) (address %spender)) nat - : pair (address %admin) (nat %total_supply) - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - SWAP - /* [ pair (big_map address nat) - (big_map %allowances (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) - : pair (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - CAR - /* [ big_map address nat - : pair (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (big_map address nat) - (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - NIL operation - /* [ list operation - : pair (big_map address nat) - (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ ; - PAIR - /* [ pair (list operation) - (big_map address nat) - (big_map (pair (address %owner) (address %spender)) nat) - (address %admin) - (nat %total_supply) ] */ } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_en2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_en2.tz].out deleted file mode 100644 index 0776983db7da..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_en2.tz].out +++ /dev/null @@ -1,205 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/multiple_en2.tz] - -Well typed -Gas remaining: 1039921.322 units remaining -{ parameter unit ; - storage (option address) ; - code { SENDER - /* [ @sender address : pair (unit @parameter) (option @storage address) ] */ ; - SELF - /* [ @self contract unit : @sender address - : pair (unit @parameter) (option @storage address) ] */ ; - ADDRESS - /* [ @self.address address : @sender address - : pair (unit @parameter) (option @storage address) ] */ ; - { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ - COMPARE - /* [ mutez : @amount mutez - : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ ; - EQ - /* [ bool : pair (unit @parameter) (option @storage address) ] */ ; - IF { CDR - /* [ @storage option address ] */ ; - { /* [ mutez : @amount mutez - : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ - IF_NONE - { { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ - UNIT - /* [ unit ] */ ; - FAILWITH - /* [] */ } } - { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ } - /* [ bool - : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ } ; - DIP { NIL operation - /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) - : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ - /* [ list operation ] */ } - /* [] */ ; - DUP - /* [ @parameter or (or (nat %add) (nat %sub)) (unit %default) - : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ ; - CONTRACT %add - unit - /* [ @parameter or (or (nat %add) (nat %sub)) (unit %default) : @storage int ] */ ; - { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ - IF_NONE - { /* [ @storage.some address : list operation ] */ } - { { UNIT /* [ int ] */ ; FAILWITH /* [] */ } } } ; - DUP - /* [ @storage int : @parameter.left.sub nat ] */ ; - CONTRACT %fact nat - /* [ int ] */ ; - { /* [ @parameter.default unit : @storage int ] */ - IF_NONE { /* [] */ } { { UNIT /* [ list operation : int ] */ ; FAILWITH /* [] */ } } - /* [] */ } ; - DUP - /* [ pair (list operation) int ] */ ; - CONTRACT %add - nat - /* [ @storage.some.contract option (contract nat) : @storage.some address - : list operation ] */ ; - { IF_NONE - { { UNIT /* [ unit : @storage.some address : list operation ] */ ; FAILWITH /* [] */ } } - { /* [ @storage.some.contract.some contract nat : @storage.some address - : list operation ] */ } } ; - PUSH mutez - 0 - /* [ mutez : @storage.some.contract.some contract nat : @storage.some address - : list operation ] */ ; - PUSH nat - 12 - /* [ nat : mutez : @storage.some.contract.some contract nat - : @storage.some address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage.some address : list operation ] */ ; - SWAP - /* [ @storage.some address : operation : list operation ] */ ; - DIP { CONS /* [ list operation ] */ } - /* [ @storage.some address : list operation ] */ ; - DUP - /* [ @storage.some address : @storage.some address : list operation ] */ ; - CONTRACT - unit - /* [ @storage.some.contract option (contract unit) : @storage.some address - : list operation ] */ ; - { IF_NONE - { { UNIT /* [ unit : @storage.some address : list operation ] */ ; FAILWITH /* [] */ } } - { /* [ @storage.some.contract.some contract unit : @storage.some address - : list operation ] */ } } ; - PUSH mutez - 0 - /* [ mutez : @storage.some.contract.some contract unit : @storage.some address - : list operation ] */ ; - PUSH unit - Unit - /* [ unit : mutez : @storage.some.contract.some contract unit - : @storage.some address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage.some address : list operation ] */ ; - SWAP - /* [ @storage.some address : operation : list operation ] */ ; - DIP { CONS /* [ list operation ] */ } - /* [ @storage.some address : list operation ] */ ; - DUP - /* [ @storage.some address : @storage.some address : list operation ] */ ; - CONTRACT %sub - nat - /* [ @storage.some.contract option (contract nat) : @storage.some address - : list operation ] */ ; - { IF_NONE - { { UNIT /* [ unit : @storage.some address : list operation ] */ ; FAILWITH /* [] */ } } - { /* [ @storage.some.contract.some contract nat : @storage.some address - : list operation ] */ } } ; - PUSH mutez - 0 - /* [ mutez : @storage.some.contract.some contract nat : @storage.some address - : list operation ] */ ; - PUSH nat - 3 - /* [ nat : mutez : @storage.some.contract.some contract nat - : @storage.some address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage.some address : list operation ] */ ; - SWAP - /* [ @storage.some address : operation : list operation ] */ ; - DIP { CONS /* [ list operation ] */ } - /* [ @storage.some address : list operation ] */ ; - DUP - /* [ @storage.some address : @storage.some address : list operation ] */ ; - CONTRACT %add - nat - /* [ @storage.some.contract option (contract nat) : @storage.some address - : list operation ] */ ; - { IF_NONE - { { UNIT /* [ unit : @storage.some address : list operation ] */ ; FAILWITH /* [] */ } } - { /* [ @storage.some.contract.some contract nat : @storage.some address - : list operation ] */ } } ; - PUSH mutez - 0 - /* [ mutez : @storage.some.contract.some contract nat : @storage.some address - : list operation ] */ ; - PUSH nat - 5 - /* [ nat : mutez : @storage.some.contract.some contract nat - : @storage.some address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage.some address : list operation ] */ ; - SWAP - /* [ @storage.some address : operation : list operation ] */ ; - DIP { CONS /* [ list operation ] */ } - /* [ @storage.some address : list operation ] */ ; - DROP - /* [ list operation ] */ ; - DIP { NONE address /* [ option address ] */ } - /* [ list operation : option address ] */ ; - PAIR - /* [ pair (list operation) (option address) ] */ } - { CAR - /* [ @parameter unit ] */ ; - DUP - /* [ @parameter unit : @parameter unit ] */ ; - DIP { DIP { PUSH int 0 - /* [ int ] */ ; - PUSH mutez 0 - /* [ mutez : int ] */ ; - NONE key_hash - /* [ option key_hash : mutez : int ] */ } - /* [ @parameter unit : option key_hash : mutez : int ] */ ; - DROP - /* [ option key_hash : mutez : int ] */ ; - CREATE_CONTRACT - { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; - storage int ; - code { AMOUNT ; - PUSH mutez 0 ; - { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; - { { DUP ; CAR ; DIP { CDR } } } ; - IF_LEFT - { IF_LEFT { ADD } { SWAP ; SUB } } - { DROP ; DROP ; PUSH int 0 } ; - NIL operation ; - PAIR } } - /* [ operation : address ] */ } - /* [ @parameter unit : operation : address ] */ ; - DIP { SELF - /* [ @self contract unit : operation : address ] */ ; - PUSH mutez 0 - /* [ mutez : @self contract unit : operation : address ] */ } - /* [ @parameter unit : mutez : @self contract unit : operation : address ] */ ; - TRANSFER_TOKENS - /* [ operation : operation : address ] */ ; - NIL operation - /* [ list operation : operation : operation : address ] */ ; - SWAP - /* [ operation : list operation : operation : address ] */ ; - CONS - /* [ list operation : operation : address ] */ ; - SWAP - /* [ operation : list operation : address ] */ ; - CONS - /* [ list operation : address ] */ ; - DIP { SOME /* [ option address ] */ } - /* [ list operation : option address ] */ ; - PAIR - /* [ pair (list operation) (option address) ] */ } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_entrypoints_counter.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_entrypoints_counter.tz].out deleted file mode 100644 index da92fa901a05..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_entrypoints_counter.tz].out +++ /dev/null @@ -1,180 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/multiple_entrypoints_counter.tz] - -Well typed -Gas remaining: 1039924.032 units remaining -{ parameter unit ; - storage (option address) ; - code { SENDER - /* [ @sender address : pair (unit @parameter) (option @storage address) ] */ ; - SELF - /* [ @self contract unit : @sender address - : pair (unit @parameter) (option @storage address) ] */ ; - ADDRESS - /* [ @self.address address : @sender address - : pair (unit @parameter) (option @storage address) ] */ ; - IFCMPEQ - { CDR - /* [ @storage option address ] */ ; - ASSERT_SOME - /* [ int - : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ ; - DIP { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ - NIL operation - /* [ list operation ] */ } - /* [] */ ; - DUP - /* [ @storage.some address : @storage.some address : list operation ] */ ; - CONTRACT %add - unit - /* [ int ] */ - /* [ @storage.some.contract option (contract unit) : @storage.some address - : list operation ] */ ; - ASSERT_NONE ; - DUP - /* [ @storage.some address : @storage.some address : list operation ] */ ; - CONTRACT %fact - nat - /* [ list operation : int ] */ - /* [ @storage.some.contract option (contract nat) : @storage.some address - : list operation ] */ ; - ASSERT_NONE ; - DUP - /* [ @storage.some address : @storage.some address : list operation ] */ ; - CONTRACT %add - nat - /* [ @storage.some.contract option (contract nat) : @storage.some address - : list operation ] */ ; - ASSERT_SOME ; - PUSH mutez - 0 - /* [ mutez : @storage.some.contract.some contract nat : @storage.some address - : list operation ] */ ; - PUSH nat - 12 - /* [ nat : mutez : @storage.some.contract.some contract nat - : @storage.some address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage.some address : list operation ] */ ; - SWAP - /* [ @storage.some address : operation : list operation ] */ ; - DIP { CONS /* [ list operation ] */ } - /* [ @storage.some address : list operation ] */ ; - DUP - /* [ @storage.some address : @storage.some address : list operation ] */ ; - CONTRACT - unit - /* [ @storage.some.contract option (contract unit) : @storage.some address - : list operation ] */ ; - ASSERT_SOME ; - PUSH mutez - 0 - /* [ mutez : @storage.some.contract.some contract unit : @storage.some address - : list operation ] */ ; - PUSH unit - Unit - /* [ unit : mutez : @storage.some.contract.some contract unit - : @storage.some address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage.some address : list operation ] */ ; - SWAP - /* [ @storage.some address : operation : list operation ] */ ; - DIP { CONS /* [ list operation ] */ } - /* [ @storage.some address : list operation ] */ ; - DUP - /* [ @storage.some address : @storage.some address : list operation ] */ ; - CONTRACT %sub - nat - /* [ @storage.some.contract option (contract nat) : @storage.some address - : list operation ] */ ; - ASSERT_SOME ; - PUSH mutez - 0 - /* [ mutez : @storage.some.contract.some contract nat : @storage.some address - : list operation ] */ ; - PUSH nat - 3 - /* [ nat : mutez : @storage.some.contract.some contract nat - : @storage.some address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage.some address : list operation ] */ ; - SWAP - /* [ @storage.some address : operation : list operation ] */ ; - DIP { CONS /* [ list operation ] */ } - /* [ @storage.some address : list operation ] */ ; - DUP - /* [ @storage.some address : @storage.some address : list operation ] */ ; - CONTRACT %add - nat - /* [ @storage.some.contract option (contract nat) : @storage.some address - : list operation ] */ ; - ASSERT_SOME ; - PUSH mutez - 0 - /* [ mutez : @storage.some.contract.some contract nat : @storage.some address - : list operation ] */ ; - PUSH nat - 5 - /* [ nat : mutez : @storage.some.contract.some contract nat - : @storage.some address : list operation ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage.some address : list operation ] */ ; - SWAP - /* [ @storage.some address : operation : list operation ] */ ; - DIP { CONS /* [ list operation ] */ } - /* [ @storage.some address : list operation ] */ ; - DROP - /* [ list operation ] */ ; - DIP { NONE address /* [ option address ] */ } - /* [ list operation : option address ] */ ; - PAIR - /* [ pair (list operation) (option address) ] */ } - { CAR - /* [ @parameter unit ] */ ; - DUP - /* [ @parameter unit : @parameter unit ] */ ; - DIP { DIP { PUSH int 0 - /* [ int ] */ ; - PUSH mutez 0 - /* [ mutez : int ] */ ; - NONE key_hash - /* [ option key_hash : mutez : int ] */ } - /* [ @parameter unit : option key_hash : mutez : int ] */ ; - DROP - /* [ option key_hash : mutez : int ] */ ; - CREATE_CONTRACT - { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; - storage int ; - code { AMOUNT ; - PUSH mutez 0 ; - ASSERT_CMPEQ ; - UNPAIR ; - IF_LEFT - { IF_LEFT { ADD } { SWAP ; SUB } } - { DROP ; DROP ; PUSH int 0 } ; - NIL operation ; - PAIR } } - /* [ operation : address ] */ } - /* [ @parameter unit : operation : address ] */ ; - DIP { SELF - /* [ @self contract unit : operation : address ] */ ; - PUSH mutez 0 - /* [ mutez : @self contract unit : operation : address ] */ } - /* [ @parameter unit : mutez : @self contract unit : operation : address ] */ ; - TRANSFER_TOKENS - /* [ operation : operation : address ] */ ; - NIL operation - /* [ list operation : operation : operation : address ] */ ; - SWAP - /* [ operation : list operation : operation : address ] */ ; - CONS - /* [ list operation : operation : address ] */ ; - SWAP - /* [ operation : list operation : address ] */ ; - CONS - /* [ list operation : address ] */ ; - DIP { SOME /* [ option address ] */ } - /* [ list operation : option address ] */ ; - PAIR - /* [ pair (list operation) (option address) ] */ } - /* [ @amount mutez - : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--parameterized_multisig.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--parameterized_multisig.tz].out deleted file mode 100644 index eb4a0cc5218a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--parameterized_multisig.tz].out +++ /dev/null @@ -1,173 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/parameterized_multisig.tz] - -Well typed -Gas remaining: 1039928.103 units remaining -{ storage (pair bool (pair (map nat (pair bool bool)) (pair key key))) ; - parameter (or nat (pair signature nat)) ; - code { DUP - /* [ pair (or @parameter nat (pair signature nat)) - (pair @storage bool (map nat (pair bool bool)) key key) - : pair (or @parameter nat (pair signature nat)) - (pair @storage bool (map nat (pair bool bool)) key key) ] */ ; - CAR - /* [ @parameter or nat (pair signature nat) - : pair (or @parameter nat (pair signature nat)) - (pair @storage bool (map nat (pair bool bool)) key key) ] */ ; - DIP { CDDR } - /* [ @parameter or nat (pair signature nat) - : pair (map nat (pair bool bool)) key key ] */ ; - IF_LEFT - { DIP { DUP - /* [ pair (map nat (pair bool bool)) key key - : pair (map nat (pair bool bool)) key key ] */ ; - CAR - /* [ map nat (pair bool bool) : pair (map nat (pair bool bool)) key key ] */ } - /* [ @parameter.left nat : map nat (pair bool bool) - : pair (map nat (pair bool bool)) key key ] */ ; - GET - /* [ option (pair bool bool) : pair (map nat (pair bool bool)) key key ] */ ; - IF_NONE - { PUSH bool False /* [ bool : pair (map nat (pair bool bool)) key key ] */ } - { DUP - /* [ @some pair bool bool : @some pair bool bool - : pair (map nat (pair bool bool)) key key ] */ ; - CAR - /* [ bool : @some pair bool bool : pair (map nat (pair bool bool)) key key ] */ ; - DIP { CDR /* [ bool : pair (map nat (pair bool bool)) key key ] */ } - /* [ bool : bool : pair (map nat (pair bool bool)) key key ] */ ; - AND - /* [ bool : pair (map nat (pair bool bool)) key key ] */ } ; - PAIR - /* [ pair bool (map nat (pair bool bool)) key key ] */ } - { DUP - /* [ @parameter.right pair signature nat : @parameter.right pair signature nat - : pair (map nat (pair bool bool)) key key ] */ ; - CAR - /* [ signature : @parameter.right pair signature nat - : pair (map nat (pair bool bool)) key key ] */ ; - DIP { CDR - /* [ nat : pair (map nat (pair bool bool)) key key ] */ ; - DUP - /* [ nat : nat : pair (map nat (pair bool bool)) key key ] */ ; - PACK - /* [ @packed bytes : nat : pair (map nat (pair bool bool)) key key ] */ ; - BLAKE2B - /* [ bytes : nat : pair (map nat (pair bool bool)) key key ] */ } - /* [ signature : bytes : nat : pair (map nat (pair bool bool)) key key ] */ ; - PAIR - /* [ pair signature bytes : nat : pair (map nat (pair bool bool)) key key ] */ ; - SWAP - /* [ nat : pair signature bytes : pair (map nat (pair bool bool)) key key ] */ ; - DIP { DIP { DUP - /* [ pair (map nat (pair bool bool)) key key - : pair (map nat (pair bool bool)) key key ] */ ; - CDR - /* [ pair key key : pair (map nat (pair bool bool)) key key ] */ ; - DIP { CAR /* [ map nat (pair bool bool) ] */ } - /* [ pair key key : map nat (pair bool bool) ] */ ; - DUP - /* [ pair key key : pair key key : map nat (pair bool bool) ] */ } - /* [ pair signature bytes : pair key key : pair key key - : map nat (pair bool bool) ] */ ; - SWAP - /* [ pair key key : pair signature bytes : pair key key - : map nat (pair bool bool) ] */ ; - CAR - /* [ key : pair signature bytes : pair key key : map nat (pair bool bool) ] */ ; - DIP { DUP - /* [ pair signature bytes : pair signature bytes : pair key key - : map nat (pair bool bool) ] */ ; - UNPAIR - /* [ signature : bytes : pair signature bytes : pair key key - : map nat (pair bool bool) ] */ } - /* [ key : signature : bytes : pair signature bytes : pair key key - : map nat (pair bool bool) ] */ ; - CHECK_SIGNATURE - /* [ bool : pair signature bytes : pair key key : map nat (pair bool bool) ] */ } - /* [ nat : bool : pair signature bytes : pair key key - : map nat (pair bool bool) ] */ ; - SWAP - /* [ bool : nat : pair signature bytes : pair key key - : map nat (pair bool bool) ] */ ; - IF { DIP { DROP - /* [ pair key key : map nat (pair bool bool) ] */ ; - SWAP - /* [ map nat (pair bool bool) : pair key key ] */ ; - DUP - /* [ map nat (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } - /* [ nat : map nat (pair bool bool) : map nat (pair bool bool) : pair key key ] */ ; - DUP - /* [ nat : nat : map nat (pair bool bool) : map nat (pair bool bool) - : pair key key ] */ ; - DIP { GET - /* [ option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ ; - IF_NONE - { PUSH (pair bool bool) - (Pair False False) - /* [ pair bool bool : map nat (pair bool bool) : pair key key ] */ } - { /* [ @some pair bool bool : map nat (pair bool bool) : pair key key ] */ } ; - CDR - /* [ bool : map nat (pair bool bool) : pair key key ] */ ; - PUSH bool True - /* [ bool : bool : map nat (pair bool bool) : pair key key ] */ ; - PAIR - /* [ pair bool bool : map nat (pair bool bool) : pair key key ] */ ; - SOME - /* [ option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } - /* [ nat : option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } - { DIP { DIP { DUP - /* [ pair key key : pair key key : map nat (pair bool bool) ] */ ; - CDR - /* [ key : pair key key : map nat (pair bool bool) ] */ } - /* [ pair signature bytes : key : pair key key : map nat (pair bool bool) ] */ ; - SWAP - /* [ key : pair signature bytes : pair key key : map nat (pair bool bool) ] */ ; - DIP { UNPAIR /* [ signature : bytes : pair key key : map nat (pair bool bool) ] */ } - /* [ key : signature : bytes : pair key key : map nat (pair bool bool) ] */ ; - CHECK_SIGNATURE - /* [ bool : pair key key : map nat (pair bool bool) ] */ } - /* [ nat : bool : pair key key : map nat (pair bool bool) ] */ ; - SWAP - /* [ bool : nat : pair key key : map nat (pair bool bool) ] */ ; - IF { DUP - /* [ nat : nat : pair key key : map nat (pair bool bool) ] */ ; - DIP { DIP { SWAP - /* [ map nat (pair bool bool) : pair key key ] */ ; - DUP - /* [ map nat (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } - /* [ nat : map nat (pair bool bool) : map nat (pair bool bool) : pair key key ] */ ; - GET - /* [ option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } - /* [ nat : option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ ; - SWAP - /* [ option (pair bool bool) : nat : map nat (pair bool bool) : pair key key ] */ ; - IF_NONE - { PUSH (pair bool bool) - (Pair False False) - /* [ pair bool bool : nat : map nat (pair bool bool) : pair key key ] */ } - { /* [ @some pair bool bool : nat : map nat (pair bool bool) : pair key key ] */ } ; - CAR - /* [ bool : nat : map nat (pair bool bool) : pair key key ] */ ; - PUSH bool True - /* [ bool : bool : nat : map nat (pair bool bool) : pair key key ] */ ; - SWAP - /* [ bool : bool : nat : map nat (pair bool bool) : pair key key ] */ ; - PAIR - /* [ pair bool bool : nat : map nat (pair bool bool) : pair key key ] */ ; - SOME - /* [ option (pair bool bool) : nat : map nat (pair bool bool) : pair key key ] */ ; - SWAP - /* [ nat : option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } - { FAIL } } ; - UPDATE - /* [ map nat (pair bool bool) : pair key key ] */ ; - PAIR - /* [ pair (map nat (pair bool bool)) key key ] */ ; - PUSH bool False - /* [ bool : pair (map nat (pair bool bool)) key key ] */ ; - PAIR - /* [ pair bool (map nat (pair bool bool)) key key ] */ } ; - NIL operation - /* [ list operation : pair bool (map nat (pair bool bool)) key key ] */ ; - PAIR - /* [ pair (list operation) bool (map nat (pair bool bool)) key key ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--replay.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--replay.tz].out deleted file mode 100644 index bd46a61e0a65..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--replay.tz].out +++ /dev/null @@ -1,33 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/replay.tz] - -Well typed -Gas remaining: 1039989.740 units remaining -{ parameter unit ; - storage unit ; - code { CDR - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - SOURCE - /* [ @source address : list operation : @storage unit ] */ ; - CONTRACT - unit - /* [ @source.contract option (contract unit) : list operation : @storage unit ] */ ; - ASSERT_SOME ; - PUSH mutez - 1 - /* [ mutez : @source.contract.some contract unit : list operation - : @storage unit ] */ ; - UNIT - /* [ unit : mutez : @source.contract.some contract unit : list operation - : @storage unit ] */ ; - TRANSFER_TOKENS - /* [ operation : list operation : @storage unit ] */ ; - DUP - /* [ operation : operation : list operation : @storage unit ] */ ; - DIP { CONS /* [ list operation : @storage unit ] */ } - /* [ operation : list operation : @storage unit ] */ ; - CONS - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--reveal_signed_preimage.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--reveal_signed_preimage.tz].out deleted file mode 100644 index 2b61d5249e34..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--reveal_signed_preimage.tz].out +++ /dev/null @@ -1,70 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/reveal_signed_preimage.tz] - -Well typed -Gas remaining: 1039977.336 units remaining -{ parameter (pair bytes signature) ; - storage (pair bytes key) ; - code { DUP - /* [ pair (pair @parameter bytes signature) (pair @storage bytes key) - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - UNPAIR - /* [ @parameter pair bytes signature : @storage pair bytes key - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - CAR - /* [ bytes : @storage pair bytes key - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - SHA256 - /* [ bytes : @storage pair bytes key - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - DIP { CAR - /* [ bytes : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ } - /* [ bytes : bytes - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ pair (pair @parameter bytes signature) (pair @storage bytes key) - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - UNPAIR - /* [ @parameter pair bytes signature : @storage pair bytes key - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - SWAP - /* [ @storage pair bytes key : @parameter pair bytes signature - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - DIP { UNPAIR - /* [ bytes : signature - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - SWAP - /* [ signature : bytes - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ } - /* [ @storage pair bytes key : signature : bytes - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - CDR - /* [ key : signature : bytes - : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - CHECK_SIGNATURE - /* [ bool : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; - ASSERT ; - CDR - /* [ @storage pair bytes key ] */ ; - DUP - /* [ @storage pair bytes key : @storage pair bytes key ] */ ; - CDR - /* [ key : @storage pair bytes key ] */ ; - HASH_KEY - /* [ key_hash : @storage pair bytes key ] */ ; - IMPLICIT_ACCOUNT - /* [ contract unit : @storage pair bytes key ] */ ; - BALANCE - /* [ @balance mutez : contract unit : @storage pair bytes key ] */ ; - UNIT - /* [ unit : @balance mutez : contract unit : @storage pair bytes key ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage pair bytes key ] */ ; - NIL operation - /* [ list operation : operation : @storage pair bytes key ] */ ; - SWAP - /* [ operation : list operation : @storage pair bytes key ] */ ; - CONS - /* [ list operation : @storage pair bytes key ] */ ; - PAIR - /* [ pair (list operation) (pair @storage bytes key) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_receiver.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_receiver.tz].out deleted file mode 100644 index 65aab1e6b6e3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_receiver.tz].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/self_address_receiver.tz] - -Well typed -Gas remaining: 1039991.719 units remaining -{ parameter (lambda unit address) ; - storage unit ; - code { UNPAIR - /* [ @parameter lambda unit address : @storage unit ] */ ; - UNIT - /* [ unit : @parameter lambda unit address : @storage unit ] */ ; - EXEC - /* [ address : @storage unit ] */ ; - SELF_ADDRESS - /* [ @self address : address : @storage unit ] */ ; - ASSERT_CMPEQ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_sender.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_sender.tz].out deleted file mode 100644 index 3c23a6789001..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_sender.tz].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/self_address_sender.tz] - -Well typed -Gas remaining: 1039991.879 units remaining -{ parameter (contract (lambda unit address)) ; - storage unit ; - code { CAR - /* [ @parameter contract (lambda unit address) ] */ ; - BALANCE - /* [ @balance mutez : @parameter contract (lambda unit address) ] */ ; - LAMBDA - unit - address - { DROP /* [] */ ; SELF_ADDRESS /* [ @self address ] */ } - /* [ lambda unit address : @balance mutez - : @parameter contract (lambda unit address) ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - DIP { UNIT /* [ unit ] */ ; NIL operation /* [ list operation : unit ] */ } - /* [ operation : list operation : unit ] */ ; - CONS - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_fungible.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_fungible.tz].out deleted file mode 100644 index 5a55d386a7bd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_fungible.tz].out +++ /dev/null @@ -1,71 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/ticket_builder_fungible.tz] - -Well typed -Gas remaining: 1039973.685 units remaining -{ parameter - (or (ticket %burn unit) - (pair %mint (contract %destination (ticket unit)) (nat %amount))) ; - storage address ; - code { AMOUNT - /* [ @amount mutez - : pair (or @parameter - (ticket %burn unit) - (pair %mint (contract %destination (ticket unit)) (nat %amount))) - (address @storage) ] */ ; - PUSH mutez - 0 - /* [ mutez : @amount mutez - : pair (or @parameter - (ticket %burn unit) - (pair %mint (contract %destination (ticket unit)) (nat %amount))) - (address @storage) ] */ ; - ASSERT_CMPEQ ; - UNPAIR - /* [ @parameter or (ticket %burn unit) - (pair %mint (contract %destination (ticket unit)) (nat %amount)) - : @storage address ] */ ; - IF_LEFT - { READ_TICKET - /* [ pair address unit nat : @parameter.burn ticket unit : @storage address ] */ ; - CAR - /* [ address : @parameter.burn ticket unit : @storage address ] */ ; - SELF_ADDRESS - /* [ @self address : address : @parameter.burn ticket unit : @storage address ] */ ; - ASSERT_CMPEQ ; - DROP - /* [ @storage address ] */ ; - NIL operation - /* [ list operation : @storage address ] */ } - { DUP @manager - 2 - /* [ @manager address - : @parameter.mint pair (contract %destination (ticket unit)) (nat %amount) - : @storage address ] */ ; - SENDER - /* [ @sender address : @manager address - : @parameter.mint pair (contract %destination (ticket unit)) (nat %amount) - : @storage address ] */ ; - ASSERT_CMPEQ ; - UNPAIR - /* [ contract (ticket unit) : nat : @storage address ] */ ; - SWAP - /* [ nat : contract (ticket unit) : @storage address ] */ ; - UNIT - /* [ unit : nat : contract (ticket unit) : @storage address ] */ ; - TICKET - /* [ ticket unit : contract (ticket unit) : @storage address ] */ ; - PUSH mutez - 0 - /* [ mutez : ticket unit : contract (ticket unit) : @storage address ] */ ; - SWAP - /* [ ticket unit : mutez : contract (ticket unit) : @storage address ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage address ] */ ; - NIL operation - /* [ list operation : operation : @storage address ] */ ; - SWAP - /* [ operation : list operation : @storage address ] */ ; - CONS - /* [ list operation : @storage address ] */ } ; - PAIR - /* [ pair (list operation) (address @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_non_fungible.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_non_fungible.tz].out deleted file mode 100644 index 0cdc9578fb95..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_non_fungible.tz].out +++ /dev/null @@ -1,73 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/ticket_builder_non_fungible.tz] - -Well typed -Gas remaining: 1039970.718 units remaining -{ parameter (or (ticket %burn nat) (contract %mint_destination (ticket nat))) ; - storage (pair (address %manager) (nat %counter)) ; - code { AMOUNT - /* [ @amount mutez - : pair (or @parameter (ticket %burn nat) (contract %mint_destination (ticket nat))) - (pair @storage (address %manager) (nat %counter)) ] */ ; - PUSH mutez - 0 - /* [ mutez : @amount mutez - : pair (or @parameter (ticket %burn nat) (contract %mint_destination (ticket nat))) - (pair @storage (address %manager) (nat %counter)) ] */ ; - ASSERT_CMPEQ ; - UNPAIR - 3 - /* [ or (ticket %burn nat) (contract %mint_destination (ticket nat)) - : @manager address : @counter nat ] */ ; - IF_LEFT - { READ_TICKET - /* [ pair address nat nat : @burn ticket nat : @manager address : @counter nat ] */ ; - CAR - /* [ address : @burn ticket nat : @manager address : @counter nat ] */ ; - SELF_ADDRESS - /* [ @self address : address : @burn ticket nat : @manager address - : @counter nat ] */ ; - ASSERT_CMPEQ ; - DROP - /* [ @manager address : @counter nat ] */ ; - NIL operation - /* [ list operation : @manager address : @counter nat ] */ } - { DUP @manager - 2 - /* [ @manager address : @mint_destination contract (ticket nat) - : @manager address : @counter nat ] */ ; - SENDER - /* [ @sender address : @manager address - : @mint_destination contract (ticket nat) : @manager address : @counter nat ] */ ; - ASSERT_CMPEQ ; - PUSH @amount - nat - 1 - /* [ @amount nat : @mint_destination contract (ticket nat) : @manager address - : @counter nat ] */ ; - DUP @counter - 4 - /* [ @counter nat : @amount nat : @mint_destination contract (ticket nat) - : @manager address : @counter nat ] */ ; - TICKET - /* [ ticket nat : @mint_destination contract (ticket nat) : @manager address - : @counter nat ] */ ; - PUSH mutez - 0 - /* [ mutez : ticket nat : @mint_destination contract (ticket nat) - : @manager address : @counter nat ] */ ; - SWAP - /* [ ticket nat : mutez : @mint_destination contract (ticket nat) - : @manager address : @counter nat ] */ ; - TRANSFER_TOKENS - /* [ operation : @manager address : @counter nat ] */ ; - NIL operation - /* [ list operation : operation : @manager address : @counter nat ] */ ; - SWAP - /* [ operation : list operation : @manager address : @counter nat ] */ ; - CONS - /* [ list operation : @manager address : @counter nat ] */ ; - DIP 2 - { PUSH nat 1 /* [ nat : @counter nat ] */ ; ADD /* [ nat ] */ } - /* [ list operation : @manager address : nat ] */ } ; - PAIR 3 - /* [ pair (list operation) address nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_fungible.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_fungible.tz].out deleted file mode 100644 index 78be9a41db2d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_fungible.tz].out +++ /dev/null @@ -1,224 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/ticket_wallet_fungible.tz] - -Well typed -Gas remaining: 1039935.806 units remaining -{ parameter - (or (ticket %receive unit) - (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer))) ; - storage (pair (address %manager) (big_map %tickets address (ticket unit))) ; - code { AMOUNT - /* [ @amount mutez - : pair (or @parameter - (ticket %receive unit) - (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer))) - (pair @storage (address %manager) (big_map %tickets address (ticket unit))) ] */ ; - PUSH mutez - 0 - /* [ mutez : @amount mutez - : pair (or @parameter - (ticket %receive unit) - (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer))) - (pair @storage (address %manager) (big_map %tickets address (ticket unit))) ] */ ; - ASSERT_CMPEQ ; - UNPAIR - 3 - /* [ or (ticket %receive unit) - (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer)) - : @manager address : @tickets big_map address (ticket unit) ] */ ; - IF_LEFT - { READ_TICKET - /* [ pair address unit nat : @receive ticket unit : @manager address - : @tickets big_map address (ticket unit) ] */ ; - CAR @ticketer - /* [ @ticketer address : @receive ticket unit : @manager address - : @tickets big_map address (ticket unit) ] */ ; - DUP - /* [ @ticketer address : @ticketer address : @receive ticket unit - : @manager address : @tickets big_map address (ticket unit) ] */ ; - DIG 4 - /* [ @tickets big_map address (ticket unit) : @ticketer address - : @ticketer address : @receive ticket unit : @manager address ] */ ; - NONE (ticket unit) - /* [ option (ticket unit) : @tickets big_map address (ticket unit) - : @ticketer address : @ticketer address : @receive ticket unit - : @manager address ] */ ; - DIG 2 - /* [ @ticketer address : option (ticket unit) - : @tickets big_map address (ticket unit) : @ticketer address - : @receive ticket unit : @manager address ] */ ; - GET_AND_UPDATE - /* [ option (ticket unit) : @tickets big_map address (ticket unit) - : @ticketer address : @receive ticket unit : @manager address ] */ ; - IF_SOME - { DIG 3 - /* [ @receive ticket unit : @some ticket unit - : @tickets big_map address (ticket unit) : @ticketer address - : @manager address ] */ ; - PAIR - /* [ pair (ticket @receive unit) (ticket @some unit) - : @tickets big_map address (ticket unit) : @ticketer address - : @manager address ] */ ; - JOIN_TICKETS - /* [ option (ticket unit) : @tickets big_map address (ticket unit) - : @ticketer address : @manager address ] */ ; - ASSERT_SOME } - { DIG 2 - /* [ @receive ticket unit : @tickets big_map address (ticket unit) - : @ticketer address : @manager address ] */ } ; - SOME - /* [ option (ticket unit) : @tickets big_map address (ticket unit) - : @ticketer address : @manager address ] */ ; - DIG 2 - /* [ @ticketer address : option (ticket unit) - : @tickets big_map address (ticket unit) : @manager address ] */ ; - GET_AND_UPDATE - /* [ option (ticket unit) : @tickets big_map address (ticket unit) - : @manager address ] */ ; - ASSERT_NONE ; - SWAP - /* [ @manager address : @tickets big_map address (ticket unit) ] */ ; - PAIR - /* [ pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; - NIL operation - /* [ list operation - : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ } - { DUP @manager - 2 - /* [ @manager address - : @send pair (contract %destination (ticket unit)) (nat %amount) (address %ticketer) - : @manager address : @tickets big_map address (ticket unit) ] */ ; - SENDER - /* [ @sender address : @manager address - : @send pair (contract %destination (ticket unit)) (nat %amount) (address %ticketer) - : @manager address : @tickets big_map address (ticket unit) ] */ ; - ASSERT_CMPEQ ; - UNPAIR - 3 - /* [ @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address : @tickets big_map address (ticket unit) ] */ ; - DIG 4 - /* [ @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - NONE (ticket unit) - /* [ option (ticket unit) : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - DUP @ticketer - 5 - /* [ @ticketer address : option (ticket unit) - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - GET_AND_UPDATE - /* [ option (ticket unit) : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - ASSERT_SOME ; - READ_TICKET - /* [ pair address unit nat : @some ticket unit - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - GET @total_amount - 4 - /* [ @total_amount nat : @some ticket unit - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - DUP @amount - 5 - /* [ @amount nat : @total_amount nat : @some ticket unit - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - SWAP - /* [ @total_amount nat : @amount nat : @some ticket unit - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - SUB - /* [ int : @some ticket unit : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - ISNAT - /* [ option nat : @some ticket unit : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @amount nat : @ticketer address - : @manager address ] */ ; - ASSERT_SOME @remaining_amount ; - DIG 4 - /* [ @amount nat : @remaining_amount nat : @some ticket unit - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @ticketer address - : @manager address ] */ ; - PAIR - /* [ pair (nat @amount) (nat @remaining_amount) : @some ticket unit - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @ticketer address - : @manager address ] */ ; - SWAP - /* [ @some ticket unit : pair (nat @amount) (nat @remaining_amount) - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @ticketer address - : @manager address ] */ ; - SPLIT_TICKET - /* [ option (pair (ticket @amount unit) (ticket @remaining_amount unit)) - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @ticketer address - : @manager address ] */ ; - ASSERT_SOME ; - UNPAIR @to_send @to_keep - /* [ @to_send ticket unit : @to_keep ticket unit - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @ticketer address - : @manager address ] */ ; - DUG 5 - /* [ @to_keep ticket unit : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @ticketer address : @manager address - : @to_send ticket unit ] */ ; - SOME - /* [ option (ticket unit) : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @ticketer address : @manager address - : @to_send ticket unit ] */ ; - DIG 3 - /* [ @ticketer address : option (ticket unit) - : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @manager address - : @to_send ticket unit ] */ ; - GET_AND_UPDATE - /* [ option (ticket unit) : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @manager address - : @to_send ticket unit ] */ ; - ASSERT_NONE ; - DIG 2 - /* [ @manager address : @tickets big_map address (ticket unit) - : @destination contract (ticket unit) : @to_send ticket unit ] */ ; - PAIR - /* [ pair (address @manager) (big_map @tickets address (ticket unit)) - : @destination contract (ticket unit) : @to_send ticket unit ] */ ; - SWAP - /* [ @destination contract (ticket unit) - : pair (address @manager) (big_map @tickets address (ticket unit)) - : @to_send ticket unit ] */ ; - PUSH mutez - 0 - /* [ mutez : @destination contract (ticket unit) - : pair (address @manager) (big_map @tickets address (ticket unit)) - : @to_send ticket unit ] */ ; - DIG 3 - /* [ @to_send ticket unit : mutez : @destination contract (ticket unit) - : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; - NIL operation - /* [ list operation : operation - : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; - SWAP - /* [ operation : list operation - : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; - CONS - /* [ list operation - : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ } ; - PAIR - /* [ pair (list operation) (address @manager) (big_map @tickets address (ticket unit)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_non_fungible.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_non_fungible.tz].out deleted file mode 100644 index 68da04875800..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_non_fungible.tz].out +++ /dev/null @@ -1,132 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/ticket_wallet_non_fungible.tz] - -Well typed -Gas remaining: 1039952.622 units remaining -{ parameter - (or (ticket %receive nat) - (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id))) ; - storage (pair (address %manager) (big_map %tickets (pair address nat) (ticket nat))) ; - code { AMOUNT - /* [ @amount mutez - : pair (or @parameter - (ticket %receive nat) - (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id))) - (pair @storage (address %manager) (big_map %tickets (pair address nat) (ticket nat))) ] */ ; - PUSH mutez - 0 - /* [ mutez : @amount mutez - : pair (or @parameter - (ticket %receive nat) - (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id))) - (pair @storage (address %manager) (big_map %tickets (pair address nat) (ticket nat))) ] */ ; - ASSERT_CMPEQ ; - UNPAIR - 3 - /* [ or (ticket %receive nat) - (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id)) - : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; - IF_LEFT - { READ_TICKET - /* [ pair address nat nat : @receive ticket nat : @manager address - : @tickets big_map (pair address nat) (ticket nat) ] */ ; - CAST (pair (address %ticketer) (nat %id) (nat %amount)) - /* [ pair (address %ticketer) (nat %id) (nat %amount) : @receive ticket nat - : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; - UNPAIR - 3 - /* [ @ticketer address : @id nat : @amount nat : @receive ticket nat - : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; - DIG 2 - /* [ @amount nat : @ticketer address : @id nat : @receive ticket nat - : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; - PUSH nat - 1 - /* [ nat : @amount nat : @ticketer address : @id nat : @receive ticket nat - : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; - ASSERT_CMPEQ ; - PAIR - /* [ pair (address @ticketer) (nat @id) : @receive ticket nat : @manager address - : @tickets big_map (pair address nat) (ticket nat) ] */ ; - DIP { SOME - /* [ option (ticket nat) : @manager address - : @tickets big_map (pair address nat) (ticket nat) ] */ ; - DIP { SWAP - /* [ @tickets big_map (pair address nat) (ticket nat) : @manager address ] */ } - /* [ option (ticket nat) : @tickets big_map (pair address nat) (ticket nat) - : @manager address ] */ } - /* [ pair (address @ticketer) (nat @id) : option (ticket nat) - : @tickets big_map (pair address nat) (ticket nat) : @manager address ] */ ; - GET_AND_UPDATE - /* [ option (ticket nat) : @tickets big_map (pair address nat) (ticket nat) - : @manager address ] */ ; - ASSERT_NONE ; - SWAP - /* [ @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; - PAIR - /* [ pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; - NIL operation - /* [ list operation - : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ } - { DUP @manager - 2 - /* [ @manager address - : @send pair (contract %destination (ticket nat)) (address %ticketer) (nat %id) - : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; - SENDER - /* [ @sender address : @manager address - : @send pair (contract %destination (ticket nat)) (address %ticketer) (nat %id) - : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; - ASSERT_CMPEQ ; - UNPAIR - /* [ contract (ticket nat) : pair (address %ticketer) (nat %id) - : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; - DIG 3 - /* [ @tickets big_map (pair address nat) (ticket nat) : contract (ticket nat) - : pair (address %ticketer) (nat %id) : @manager address ] */ ; - NONE (ticket nat) - /* [ option (ticket nat) : @tickets big_map (pair address nat) (ticket nat) - : contract (ticket nat) : pair (address %ticketer) (nat %id) - : @manager address ] */ ; - DIG 3 - /* [ pair (address %ticketer) (nat %id) : option (ticket nat) - : @tickets big_map (pair address nat) (ticket nat) : contract (ticket nat) - : @manager address ] */ ; - GET_AND_UPDATE - /* [ option (ticket nat) : @tickets big_map (pair address nat) (ticket nat) - : contract (ticket nat) : @manager address ] */ ; - ASSERT_SOME ; - SWAP - /* [ @tickets big_map (pair address nat) (ticket nat) : @some ticket nat - : contract (ticket nat) : @manager address ] */ ; - DIG 3 - /* [ @manager address : @tickets big_map (pair address nat) (ticket nat) - : @some ticket nat : contract (ticket nat) ] */ ; - PAIR - /* [ pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) - : @some ticket nat : contract (ticket nat) ] */ ; - DUG 2 - /* [ @some ticket nat : contract (ticket nat) - : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; - PUSH mutez - 0 - /* [ mutez : @some ticket nat : contract (ticket nat) - : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; - SWAP - /* [ @some ticket nat : mutez : contract (ticket nat) - : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; - TRANSFER_TOKENS - /* [ operation - : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; - NIL operation - /* [ list operation : operation - : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; - SWAP - /* [ operation : list operation - : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; - CONS - /* [ list operation - : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ } ; - PAIR - /* [ pair (list operation) - (address @manager) - (big_map @tickets (pair address nat) (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--tzip4_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--tzip4_view.tz].out deleted file mode 100644 index cce2cd4edbc2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--tzip4_view.tz].out +++ /dev/null @@ -1,56 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/tzip4_view.tz] - -Well typed -Gas remaining: 1039984.179 units remaining -{ parameter - (or (pair %view_const unit (contract nat)) - (pair %view_add (pair int int) (contract int))) ; - storage unit ; - code { CAR - /* [ @parameter or (pair %view_const unit (contract nat)) - (pair %view_add (pair int int) (contract int)) ] */ ; - IF_LEFT - { CDR - /* [ contract nat ] */ ; - AMOUNT - /* [ @amount mutez : contract nat ] */ ; - PUSH nat 5 - /* [ nat : @amount mutez : contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - NIL operation - /* [ list operation : operation ] */ ; - SWAP - /* [ operation : list operation ] */ ; - CONS - /* [ list operation ] */ ; - UNIT - /* [ unit : list operation ] */ ; - SWAP - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } - { UNPAIR - /* [ pair int int : contract int ] */ ; - UNPAIR - /* [ int : int : contract int ] */ ; - ADD - /* [ int : contract int ] */ ; - AMOUNT - /* [ @amount mutez : int : contract int ] */ ; - SWAP - /* [ int : @amount mutez : contract int ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - NIL operation - /* [ list operation : operation ] */ ; - SWAP - /* [ operation : list operation ] */ ; - CONS - /* [ list operation ] */ ; - UNIT - /* [ unit : list operation ] */ ; - SWAP - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--vote_for_delegate.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--vote_for_delegate.tz].out deleted file mode 100644 index f2f97c2832c1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--vote_for_delegate.tz].out +++ /dev/null @@ -1,168 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/vote_for_delegate.tz] - -Well typed -Gas remaining: 1039933.671 units remaining -{ parameter (option key_hash) ; - storage - (pair (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) ; - code { DUP - /* [ pair (option @parameter key_hash) - (pair @storage - (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) - : pair (option @parameter key_hash) - (pair @storage - (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; - CDAAR %addr @% ; - SENDER - /* [ @sender address : @addr address - : pair (option @parameter key_hash) - (pair @storage - (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; - PAIR %@ %@ - /* [ pair (address %sender @sender) (address %addr @addr) - : pair (option @parameter key_hash) - (pair @storage - (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; - UNPAIR - /* [ @sender address : @addr address - : pair (option @parameter key_hash) - (pair @storage - (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; - IFCMPEQ - { UNPAIR - /* [ @parameter option key_hash - : @storage pair (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash)) ] */ ; - SWAP - /* [ @storage pair (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash)) - : @parameter option key_hash ] */ ; - SET_CADR %key @changed_mgr1_key } - { DUP - /* [ pair (option @parameter key_hash) - (pair @storage - (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) - : pair (option @parameter key_hash) - (pair @storage - (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; - CDDAR ; - SENDER - /* [ @sender address : address - : pair (option @parameter key_hash) - (pair @storage - (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; - IFCMPEQ - { UNPAIR - /* [ @parameter option key_hash - : @storage pair (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash)) ] */ ; - SWAP - /* [ @storage pair (pair %mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 (address %addr) (option %key key_hash)) - : @parameter option key_hash ] */ ; - SET_CDDR %key } - { FAIL } } ; - DUP - /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - CADR ; - DIP { DUP - /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - CDDR } - /* [ option key_hash : option key_hash - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - IF_NONE - { IF_NONE - { NONE key_hash - /* [ option key_hash - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - SET_DELEGATE - /* [ operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - NIL operation - /* [ list operation : operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - SWAP - /* [ operation : list operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - CONS - /* [ list operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } - { DROP - /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - NIL operation - /* [ list operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } } - { SWAP - /* [ option key_hash : @some key_hash - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - IF_SOME - { DIP { DUP - /* [ @some key_hash : @some key_hash - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } - /* [ @some key_hash : @some key_hash : @some key_hash - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - IFCMPEQ - { SOME - /* [ option key_hash - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - SET_DELEGATE - /* [ operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - NIL operation - /* [ list operation : operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - SWAP - /* [ operation : list operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - CONS - /* [ list operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } - { DROP - /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - NIL operation - /* [ list operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } } - { DROP - /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; - NIL operation - /* [ list operation - : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } } ; - PAIR - /* [ pair (list operation) - (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) - (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--weather_insurance.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--weather_insurance.tz].out deleted file mode 100644 index 6ccd0863cb37..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--weather_insurance.tz].out +++ /dev/null @@ -1,259 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/weather_insurance.tz] - -Well typed -Gas remaining: 1039960.200 units remaining -{ parameter (pair (signature %signed_weather_data) (nat :rain %actual_level)) ; - storage - (pair (pair (address %under_key) (address %over_key)) - (pair (nat :rain %rain_level) (key %weather_service_key))) ; - code { DUP - /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - DUP - /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - CAR - /* [ @parameter pair (signature %signed_weather_data) (nat :rain %actual_level) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - MAP_CDR - { PACK - /* [ @packed bytes - : @parameter pair (signature %signed_weather_data) (nat :rain %actual_level) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - BLAKE2B - /* [ bytes - : @parameter pair (signature %signed_weather_data) (nat :rain %actual_level) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ } ; - SWAP - /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : @parameter pair (signature %signed_weather_data @parameter.signed_weather_data) bytes - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - CDDDR %weather_service_key ; - DIP { UNPAIR - /* [ @parameter.signed_weather_data signature : bytes - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ } - /* [ key : @parameter.signed_weather_data signature : bytes - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - CHECK_SIGNATURE @sigok - /* [ @sigok bool - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - ASSERT ; - DUP - /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - DUP - /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - DUP - /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ ; - DIIIP - { CDR %storage - /* [ @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ } - /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - DIIP { CDAR } - /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) - : pair (address %under_key) (address %over_key) - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - DIP { CADR %actual_level } - /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) : nat :rain - : pair (address %under_key) (address %over_key) - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - CDDAR %rain_level ; - CMPLT ; - IF { CAR %under_key - /* [ address - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ } - { CDR %over_key - /* [ address - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ } ; - CONTRACT - unit - /* [ @contract option (contract unit) - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - ASSERT_SOME ; - BALANCE - /* [ @balance mutez : @contract.some contract unit - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - UNIT - /* [ unit : @balance mutez : @contract.some contract unit - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - TRANSFER_TOKENS @trans.op - /* [ @trans.op operation - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - NIL operation - /* [ list operation : @trans.op operation - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - SWAP - /* [ @trans.op operation : list operation - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - CONS - /* [ list operation - : @storage pair (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key) ] */ ; - PAIR - /* [ pair (list operation) - (pair @storage - (pair (address %under_key) (address %over_key)) - (nat :rain %rain_level) - (key %weather_service_key)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat.tz].out deleted file mode 100644 index 109ef9d4c0af..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat.tz].out +++ /dev/null @@ -1,93 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/xcat.tz] - -Well typed -Gas remaining: 1039965.793 units remaining -{ parameter bytes ; - storage unit ; - code { CAR @preimage - /* [ @preimage bytes ] */ ; - DIP { PUSH @from key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" - /* [ @from key_hash ] */ ; - IMPLICIT_ACCOUNT - /* [ contract unit ] */ ; - PUSH @to - key_hash - "tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" - /* [ @to key_hash : contract unit ] */ ; - IMPLICIT_ACCOUNT - /* [ contract unit : contract unit ] */ ; - PUSH @target_hash - bytes - 0x123456 - /* [ @target_hash bytes : contract unit : contract unit ] */ ; - PUSH @deadline - timestamp - "2018-08-08 00:00:00Z" - /* [ @deadline timestamp : @target_hash bytes : contract unit : contract unit ] */ } - /* [ @preimage bytes : @deadline timestamp : @target_hash bytes : contract unit - : contract unit ] */ ; - SWAP - /* [ @deadline timestamp : @preimage bytes : @target_hash bytes : contract unit - : contract unit ] */ ; - NOW - /* [ @now timestamp : @deadline timestamp : @preimage bytes : @target_hash bytes - : contract unit : contract unit ] */ ; - IFCMPLT - { DROP - /* [ @target_hash bytes : contract unit : contract unit ] */ ; - DROP - /* [ contract unit : contract unit ] */ ; - DROP - /* [ contract unit ] */ ; - BALANCE - /* [ @balance mutez : contract unit ] */ ; - UNIT - /* [ unit : @balance mutez : contract unit ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ } - { DUP - /* [ @preimage bytes : @preimage bytes : @target_hash bytes : contract unit - : contract unit ] */ ; - SIZE - /* [ nat : @preimage bytes : @target_hash bytes : contract unit - : contract unit ] */ ; - PUSH @max_length - nat - 32 - /* [ @max_length nat : nat : @preimage bytes : @target_hash bytes - : contract unit : contract unit ] */ ; - IFCMPLT - { PUSH string - "preimage too long" - /* [ string : @preimage bytes : @target_hash bytes : contract unit - : contract unit ] */ ; - FAILWITH - /* [] */ } - { SHA256 @candidate_hash - /* [ @candidate_hash bytes : @target_hash bytes : contract unit - : contract unit ] */ ; - IFCMPNEQ - { PUSH string "invalid preimage" - /* [ string : contract unit : contract unit ] */ ; - FAILWITH - /* [] */ } - { BALANCE - /* [ @balance mutez : contract unit : contract unit ] */ ; - UNIT - /* [ unit : @balance mutez : contract unit : contract unit ] */ ; - TRANSFER_TOKENS - /* [ operation : contract unit ] */ ; - DIP { DROP /* [] */ } - /* [ operation ] */ } } } ; - NIL operation - /* [ list operation : operation ] */ ; - SWAP - /* [ operation : list operation ] */ ; - CONS - /* [ list operation ] */ ; - UNIT - /* [ unit : list operation ] */ ; - SWAP - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat_dapp.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat_dapp.tz].out deleted file mode 100644 index ace49540d40e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat_dapp.tz].out +++ /dev/null @@ -1,612 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/xcat_dapp.tz] - -Well typed -Gas remaining: 1039911.852 units remaining -{ parameter - (or (pair %fund - (address %dest) - (pair %settings (bytes %target_hash) (timestamp %deadline))) - (or %claim_refund (bytes %preimage_claim) (bytes %refund_hash))) ; - storage - (pair (big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)))) - unit) ; - code { NIL @operations - operation - /* [ @operations list operation - : pair (or @parameter - (pair %fund - (address %dest) - (pair %settings (bytes %target_hash) (timestamp %deadline))) - (or %claim_refund (bytes %preimage_claim) (bytes %refund_hash))) - (pair @storage - (big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)))) - unit) ] */ ; - SWAP - /* [ pair (or @parameter - (pair %fund - (address %dest) - (pair %settings (bytes %target_hash) (timestamp %deadline))) - (or %claim_refund (bytes %preimage_claim) (bytes %refund_hash))) - (pair @storage - (big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)))) - unit) : @operations list operation ] */ ; - UNPAPAIR @% @% @% ; - DIP { DUP - /* [ big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ } - /* [ @parameter or (pair %fund - (address %dest) - (pair %settings (bytes %target_hash) (timestamp %deadline))) - (or %claim_refund (bytes %preimage_claim) (bytes %refund_hash)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - IF_LEFT - { UNPAIR @% @% - /* [ @dest address : @settings pair (bytes %target_hash) (timestamp %deadline) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DUP - /* [ @dest address : @dest address - : @settings pair (bytes %target_hash) (timestamp %deadline) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - CONTRACT @dest - unit - /* [ @dest option (contract unit) : @dest address - : @settings pair (bytes %target_hash) (timestamp %deadline) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - ASSERT_SOME ; - DROP - /* [ @dest address : @settings pair (bytes %target_hash) (timestamp %deadline) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - SWAP - /* [ @settings pair (bytes %target_hash) (timestamp %deadline) : @dest address - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - UNPAIR @% @% - /* [ @target_hash bytes : @deadline timestamp : @dest address - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DIP { AMOUNT @amount - /* [ @amount mutez : @deadline timestamp : @dest address - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - SENDER - /* [ @sender address : @amount mutez : @deadline timestamp : @dest address - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DUP - /* [ @sender address : @sender address : @amount mutez : @deadline timestamp - : @dest address - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - CONTRACT @from - unit - /* [ @from option (contract unit) : @sender address : @amount mutez - : @deadline timestamp : @dest address - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - ASSERT_SOME ; - DROP - /* [ @sender address : @amount mutez : @deadline timestamp : @dest address - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DIP { PAIR - /* [ pair (mutez @amount) (timestamp @deadline) : @dest address - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - SWAP - /* [ @dest address : pair (mutez @amount) (timestamp @deadline) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ } - /* [ @sender address : @dest address - : pair (mutez @amount) (timestamp @deadline) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - PAIR - /* [ pair (address @sender) (address @dest) - : pair (mutez @amount) (timestamp @deadline) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - PAIR - /* [ pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - SOME @xcat - /* [ @xcat option - (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - SWAP - /* [ big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : @xcat option - (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ } - /* [ @target_hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : @xcat option - (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DUP - /* [ @target_hash bytes : @target_hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : @xcat option - (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DIP { MEM - /* [ bool - : @xcat option - (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - NOT - /* [ bool - : @xcat option - (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - ASSERT } - /* [ @target_hash bytes - : @xcat option - (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - UPDATE - /* [ big_map bytes (pair (pair address address) mutez timestamp) : unit - : @operations list operation ] */ ; - PAIR @new_storage - /* [ @new_storage pair (big_map bytes (pair (pair address address) mutez timestamp)) unit - : @operations list operation ] */ ; - SWAP - /* [ @operations list operation - : @new_storage pair (big_map bytes (pair (pair address address) mutez timestamp)) unit ] */ ; - PAIR - /* [ pair (list @operations operation) - (pair @new_storage (big_map bytes (pair (pair address address) mutez timestamp)) unit) ] */ } - { IF_LEFT - { DUP - /* [ @parameter.claim_refund.preimage_claim bytes - : @parameter.claim_refund.preimage_claim bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - SIZE - /* [ nat : @parameter.claim_refund.preimage_claim bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - PUSH nat - 32 - /* [ nat : nat : @parameter.claim_refund.preimage_claim bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - ASSERT_CMPGE ; - SHA256 @hash - /* [ @hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DUP - /* [ @hash bytes : @hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DIP { SWAP - /* [ big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : @hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ } - /* [ @hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : @hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DIIP { GET - /* [ option - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - ASSERT_SOME ; - DUP - /* [ @some pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)) - : @some pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)) : unit - : @operations list operation ] */ ; - CADR @% ; - CONTRACT @dest - unit - /* [ @dest option (contract unit) - : @some pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)) : unit - : @operations list operation ] */ ; - ASSERT_SOME ; - SWAP - /* [ @some pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)) - : @dest.some contract unit : unit : @operations list operation ] */ ; - CDR @% - /* [ @settings pair (mutez %amount) (timestamp %deadline) - : @dest.some contract unit : unit : @operations list operation ] */ ; - UNPAIR @% @% - /* [ @amount mutez : @deadline timestamp : @dest.some contract unit : unit - : @operations list operation ] */ ; - SWAP - /* [ @deadline timestamp : @amount mutez : @dest.some contract unit : unit - : @operations list operation ] */ ; - NOW - /* [ @now timestamp : @deadline timestamp : @amount mutez - : @dest.some contract unit : unit : @operations list operation ] */ ; - ASSERT_CMPLT ; - UNIT - /* [ unit : @amount mutez : @dest.some contract unit : unit - : @operations list operation ] */ ; - TRANSFER_TOKENS - /* [ operation : unit : @operations list operation ] */ } - /* [ @hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : operation - : unit : @operations list operation ] */ } - { DUP - /* [ @parameter.claim_refund.refund_hash bytes - : @parameter.claim_refund.refund_hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - DIP { GET - /* [ option - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - ASSERT_SOME ; - DUP - /* [ @some pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)) - : @some pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - CAAR @% ; - CONTRACT @from - unit - /* [ @from option (contract unit) - : @some pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - ASSERT_SOME ; - SWAP - /* [ @some pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline)) - : @from.some contract unit - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - CDR - /* [ pair (mutez %amount) (timestamp %deadline) : @from.some contract unit - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - UNPAIR @% @% - /* [ @amount mutez : @deadline timestamp : @from.some contract unit - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - SWAP - /* [ @deadline timestamp : @amount mutez : @from.some contract unit - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - NOW - /* [ @now timestamp : @deadline timestamp : @amount mutez - : @from.some contract unit - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - ASSERT_CMPGE ; - UNIT - /* [ unit : @amount mutez : @from.some contract unit - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - TRANSFER_TOKENS - /* [ operation - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : unit - : @operations list operation ] */ ; - SWAP - /* [ big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : operation - : unit : @operations list operation ] */ } - /* [ @parameter.claim_refund.refund_hash bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : operation - : unit : @operations list operation ] */ } ; - NONE @none - (pair (pair address address) (pair mutez timestamp)) - /* [ @none option (pair (pair address address) mutez timestamp) : bytes - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : operation - : unit : @operations list operation ] */ ; - SWAP - /* [ bytes : @none option (pair (pair address address) mutez timestamp) - : big_map - bytes - (pair (pair %recipients (address %from) (address %dest)) - (pair %settings (mutez %amount) (timestamp %deadline))) : operation - : unit : @operations list operation ] */ ; - UPDATE @cleared_map - /* [ @cleared_map big_map bytes (pair (pair address address) mutez timestamp) - : operation : unit : @operations list operation ] */ ; - SWAP - /* [ operation - : @cleared_map big_map bytes (pair (pair address address) mutez timestamp) - : unit : @operations list operation ] */ ; - DIP { PAIR - /* [ pair (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) unit - : @operations list operation ] */ ; - SWAP - /* [ @operations list operation - : pair (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) unit ] */ } - /* [ operation : @operations list operation - : pair (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) unit ] */ ; - CONS - /* [ list operation - : pair (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) unit ] */ ; - PAIR - /* [ pair (list operation) - (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) - unit ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--bug_262.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--bug_262.tz].out deleted file mode 100644 index 9f307d779a87..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--bug_262.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[non_regression/bug_262.tz] - -Well typed -Gas remaining: 1039994.949 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - LAMBDA unit unit { /* [ @arg unit ] */ } - /* [ lambda unit unit ] */ ; - UNIT - /* [ unit : lambda unit unit ] */ ; - EXEC - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--pairk_annot.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--pairk_annot.tz].out deleted file mode 100644 index 04b0127ccfdd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--pairk_annot.tz].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[non_regression/pairk_annot.tz] - -Well typed -Gas remaining: 1039992.198 units remaining -{ parameter unit ; - storage unit ; - code { SENDER - /* [ @sender address : pair (unit @parameter) (unit @storage) ] */ ; - SOURCE - /* [ @source address : @sender address - : pair (unit @parameter) (unit @storage) ] */ ; - PAIR 2 - /* [ pair address address : pair (unit @parameter) (unit @storage) ] */ ; - SOURCE - /* [ @source address : pair address address - : pair (unit @parameter) (unit @storage) ] */ ; - SENDER - /* [ @sender address : @source address : pair address address - : pair (unit @parameter) (unit @storage) ] */ ; - PAIR 2 - /* [ pair address address : pair address address - : pair (unit @parameter) (unit @storage) ] */ ; - COMPARE - /* [ int : pair (unit @parameter) (unit @storage) ] */ ; - DROP - /* [ pair (unit @parameter) (unit @storage) ] */ ; - CDR - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--abs.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--abs.tz].out deleted file mode 100644 index b02492c2c027..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--abs.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/abs.tz] - -Well typed -Gas remaining: 1039991.794 units remaining -{ parameter nat ; - storage unit ; - code { CAR - /* [ @parameter nat ] */ ; - DUP - /* [ @parameter nat : @parameter nat ] */ ; - NEG - /* [ int : @parameter nat ] */ ; - ABS - /* [ nat : @parameter nat ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add.tz].out deleted file mode 100644 index 8c298e56d221..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add.tz].out +++ /dev/null @@ -1,84 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add.tz] - -Well typed -Gas remaining: 1039944.723 units remaining -{ parameter unit ; - storage unit ; - code { CAR - /* [ @parameter unit ] */ ; - PUSH int 2 - /* [ int : @parameter unit ] */ ; - PUSH int 2 - /* [ int : int : @parameter unit ] */ ; - ADD - /* [ int : @parameter unit ] */ ; - PUSH int 4 - /* [ int : int : @parameter unit ] */ ; - ASSERT_CMPEQ ; - PUSH int 2 - /* [ int : @parameter unit ] */ ; - PUSH int 2 - /* [ int : int : @parameter unit ] */ ; - ADD - /* [ int : @parameter unit ] */ ; - PUSH int 4 - /* [ int : int : @parameter unit ] */ ; - ASSERT_CMPEQ ; - PUSH int 2 - /* [ int : @parameter unit ] */ ; - PUSH nat 2 - /* [ nat : int : @parameter unit ] */ ; - ADD - /* [ int : @parameter unit ] */ ; - PUSH int 4 - /* [ int : int : @parameter unit ] */ ; - ASSERT_CMPEQ ; - PUSH nat 2 - /* [ nat : @parameter unit ] */ ; - PUSH int 2 - /* [ int : nat : @parameter unit ] */ ; - ADD - /* [ int : @parameter unit ] */ ; - PUSH int 4 - /* [ int : int : @parameter unit ] */ ; - ASSERT_CMPEQ ; - PUSH nat 2 - /* [ nat : @parameter unit ] */ ; - PUSH nat 2 - /* [ nat : nat : @parameter unit ] */ ; - ADD - /* [ nat : @parameter unit ] */ ; - PUSH nat 4 - /* [ nat : nat : @parameter unit ] */ ; - ASSERT_CMPEQ ; - PUSH int 60 - /* [ int : @parameter unit ] */ ; - PUSH timestamp "2019-09-09T12:08:37Z" - /* [ timestamp : int : @parameter unit ] */ ; - ADD - /* [ timestamp : @parameter unit ] */ ; - PUSH timestamp "2019-09-09T12:09:37Z" - /* [ timestamp : timestamp : @parameter unit ] */ ; - ASSERT_CMPEQ ; - PUSH timestamp "2019-09-09T12:08:37Z" - /* [ timestamp : @parameter unit ] */ ; - PUSH int 60 - /* [ int : timestamp : @parameter unit ] */ ; - ADD - /* [ timestamp : @parameter unit ] */ ; - PUSH timestamp "2019-09-09T12:09:37Z" - /* [ timestamp : timestamp : @parameter unit ] */ ; - ASSERT_CMPEQ ; - PUSH mutez 1000 - /* [ mutez : @parameter unit ] */ ; - PUSH mutez 1000 - /* [ mutez : mutez : @parameter unit ] */ ; - ADD - /* [ mutez : @parameter unit ] */ ; - PUSH mutez 2000 - /* [ mutez : mutez : @parameter unit ] */ ; - ASSERT_CMPEQ ; - NIL operation - /* [ list operation : @parameter unit ] */ ; - PAIR - /* [ pair (list operation) (unit @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_fr.tz].out deleted file mode 100644 index e1519299998f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_fr.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_bls12_381_fr.tz] - -Well typed -Gas remaining: 1039995.329 units remaining -{ parameter (pair bls12_381_fr bls12_381_fr) ; - storage (option bls12_381_fr) ; - code { CAR - /* [ @parameter pair bls12_381_fr bls12_381_fr ] */ ; - UNPAIR - /* [ bls12_381_fr : bls12_381_fr ] */ ; - ADD - /* [ bls12_381_fr ] */ ; - SOME - /* [ option bls12_381_fr ] */ ; - NIL operation - /* [ list operation : option bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g1.tz].out deleted file mode 100644 index a66dc711461c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g1.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_bls12_381_g1.tz] - -Well typed -Gas remaining: 1039995.329 units remaining -{ parameter (pair bls12_381_g1 bls12_381_g1) ; - storage (option bls12_381_g1) ; - code { CAR - /* [ @parameter pair bls12_381_g1 bls12_381_g1 ] */ ; - UNPAIR - /* [ bls12_381_g1 : bls12_381_g1 ] */ ; - ADD - /* [ bls12_381_g1 ] */ ; - SOME - /* [ option bls12_381_g1 ] */ ; - NIL operation - /* [ list operation : option bls12_381_g1 ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_g1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g2.tz].out deleted file mode 100644 index b6d27a0d65c8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g2.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_bls12_381_g2.tz] - -Well typed -Gas remaining: 1039995.329 units remaining -{ parameter (pair bls12_381_g2 bls12_381_g2) ; - storage (option bls12_381_g2) ; - code { CAR - /* [ @parameter pair bls12_381_g2 bls12_381_g2 ] */ ; - UNPAIR - /* [ bls12_381_g2 : bls12_381_g2 ] */ ; - ADD - /* [ bls12_381_g2 ] */ ; - SOME - /* [ option bls12_381_g2 ] */ ; - NIL operation - /* [ list operation : option bls12_381_g2 ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_g2) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_delta_timestamp.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_delta_timestamp.tz].out deleted file mode 100644 index 6ec5936684b9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_delta_timestamp.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_delta_timestamp.tz] - -Well typed -Gas remaining: 1039993.598 units remaining -{ parameter (pair int timestamp) ; - storage (option timestamp) ; - code { CAR - /* [ @parameter pair int timestamp ] */ ; - DUP - /* [ @parameter pair int timestamp : @parameter pair int timestamp ] */ ; - CAR - /* [ int : @parameter pair int timestamp ] */ ; - DIP { CDR /* [ timestamp ] */ } - /* [ int : timestamp ] */ ; - ADD - /* [ timestamp ] */ ; - SOME - /* [ option timestamp ] */ ; - NIL operation - /* [ list operation : option timestamp ] */ ; - PAIR - /* [ pair (list operation) (option timestamp) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_timestamp_delta.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_timestamp_delta.tz].out deleted file mode 100644 index 29382a1695b0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_timestamp_delta.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_timestamp_delta.tz] - -Well typed -Gas remaining: 1039993.598 units remaining -{ parameter (pair timestamp int) ; - storage (option timestamp) ; - code { CAR - /* [ @parameter pair timestamp int ] */ ; - DUP - /* [ @parameter pair timestamp int : @parameter pair timestamp int ] */ ; - CAR - /* [ timestamp : @parameter pair timestamp int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ timestamp : int ] */ ; - ADD - /* [ timestamp ] */ ; - SOME - /* [ option timestamp ] */ ; - NIL operation - /* [ list operation : option timestamp ] */ ; - PAIR - /* [ pair (list operation) (option timestamp) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--address.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--address.tz].out deleted file mode 100644 index e193ce4f2364..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--address.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/address.tz] - -Well typed -Gas remaining: 1039995.954 units remaining -{ parameter (contract unit) ; - storage (option address) ; - code { CAR - /* [ @parameter contract unit ] */ ; - ADDRESS - /* [ @parameter.address address ] */ ; - SOME - /* [ option address ] */ ; - NIL operation - /* [ list operation : option address ] */ ; - PAIR - /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_fib_view.tz].out deleted file mode 100644 index f349174faa85..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_fib_view.tz].out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/amount_after_fib_view.tz] - -Well typed -Gas remaining: 1039985.607 units remaining -{ parameter address ; - storage mutez ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 3 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "fib" nat - /* [ @parameter.contract option nat : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 15000000 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - AMOUNT - /* [ @amount mutez : operation ] */ ; - SWAP - /* [ operation : @amount mutez ] */ ; - NIL operation - /* [ list operation : operation : @amount mutez ] */ ; - SWAP - /* [ operation : list operation : @amount mutez ] */ ; - CONS - /* [ list operation : @amount mutez ] */ ; - PAIR - /* [ pair (list operation) (mutez @amount) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_nonexistent_view.tz].out deleted file mode 100644 index a3ac48b1b9a9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_nonexistent_view.tz].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/amount_after_nonexistent_view.tz] - -Well typed -Gas remaining: 1039985.815 units remaining -{ parameter address ; - storage mutez ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "nonexistent" - (pair nat nat) - /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; - ASSERT_NONE ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 15000000 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - AMOUNT - /* [ @amount mutez : operation ] */ ; - SWAP - /* [ operation : @amount mutez ] */ ; - NIL operation - /* [ list operation : operation : @amount mutez ] */ ; - SWAP - /* [ operation : list operation : @amount mutez ] */ ; - CONS - /* [ list operation : @amount mutez ] */ ; - PAIR - /* [ pair (list operation) (mutez @amount) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_view.tz].out deleted file mode 100644 index eb1606bad518..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_view.tz].out +++ /dev/null @@ -1,39 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/amount_after_view.tz] - -Well typed -Gas remaining: 1039985.432 units remaining -{ parameter address ; - storage mutez ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "id" - (pair nat nat) - /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 15000000 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - AMOUNT - /* [ @amount mutez : operation ] */ ; - SWAP - /* [ operation : @amount mutez ] */ ; - NIL operation - /* [ list operation : operation : @amount mutez ] */ ; - SWAP - /* [ operation : list operation : @amount mutez ] */ ; - CONS - /* [ list operation : @amount mutez ] */ ; - PAIR - /* [ pair (list operation) (mutez @amount) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and.tz].out deleted file mode 100644 index 160120cb34df..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/and.tz] - -Well typed -Gas remaining: 1039994.393 units remaining -{ parameter (pair :param (bool %first) (bool %second)) ; - storage (option bool) ; - code { CAR - /* [ @param pair :param (bool %first) (bool %second) ] */ ; - UNPAIR - /* [ bool : bool ] */ ; - AND @and - /* [ @and bool ] */ ; - SOME @res - /* [ @res option bool ] */ ; - NIL @noop operation - /* [ @noop list operation : @res option bool ] */ ; - PAIR - /* [ pair (list @noop operation) (option @res bool) ] */ ; - UNPAIR @x @y - /* [ @x list operation : @y option bool ] */ ; - PAIR %a %b - /* [ pair (list %a @x operation) (option %b @y bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_binary.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_binary.tz].out deleted file mode 100644 index b83a04ff8d2e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_binary.tz].out +++ /dev/null @@ -1,50 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/and_binary.tz] - -Well typed -Gas remaining: 1039971.036 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - PUSH nat 5 - /* [ nat ] */ ; - PUSH nat 6 - /* [ nat : nat ] */ ; - AND - /* [ nat ] */ ; - PUSH nat 4 - /* [ nat : nat ] */ ; - ASSERT_CMPEQ ; - PUSH nat 6 - /* [ nat ] */ ; - PUSH int 5 - /* [ int : nat ] */ ; - AND - /* [ nat ] */ ; - PUSH nat 4 - /* [ nat : nat ] */ ; - ASSERT_CMPEQ ; - PUSH nat 12 - /* [ nat ] */ ; - PUSH int -1 - /* [ int : nat ] */ ; - AND - /* [ nat ] */ ; - PUSH nat 12 - /* [ nat : nat ] */ ; - ASSERT_CMPEQ ; - PUSH nat 12 - /* [ nat ] */ ; - PUSH int -5 - /* [ int : nat ] */ ; - AND - /* [ nat ] */ ; - PUSH nat 8 - /* [ nat : nat ] */ ; - ASSERT_CMPEQ ; - UNIT - /* [ unit ] */ ; - NIL @noop operation - /* [ @noop list operation : unit ] */ ; - PAIR - /* [ pair (list @noop operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_logical_1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_logical_1.tz].out deleted file mode 100644 index 813eb62dfa59..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_logical_1.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/and_logical_1.tz] - -Well typed -Gas remaining: 1039996.174 units remaining -{ parameter (pair bool bool) ; - storage bool ; - code { CAR - /* [ @parameter pair bool bool ] */ ; - UNPAIR - /* [ bool : bool ] */ ; - AND @and - /* [ @and bool ] */ ; - NIL @noop operation - /* [ @noop list operation : @and bool ] */ ; - PAIR - /* [ pair (list @noop operation) (bool @and) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance.tz].out deleted file mode 100644 index 3bdce329ce88..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/balance.tz] - -Well typed -Gas remaining: 1039996.803 units remaining -{ parameter unit ; - storage mutez ; - code { DROP - /* [] */ ; - BALANCE - /* [ @balance mutez ] */ ; - NIL operation - /* [ list operation : @balance mutez ] */ ; - PAIR - /* [ pair (list operation) (mutez @balance) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_fib_view.tz].out deleted file mode 100644 index 0c77a876e6f5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_fib_view.tz].out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/balance_after_fib_view.tz] - -Well typed -Gas remaining: 1039985.607 units remaining -{ parameter address ; - storage mutez ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 3 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "fib" nat - /* [ @parameter.contract option nat : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 15000000 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - BALANCE - /* [ @balance mutez : operation ] */ ; - SWAP - /* [ operation : @balance mutez ] */ ; - NIL operation - /* [ list operation : operation : @balance mutez ] */ ; - SWAP - /* [ operation : list operation : @balance mutez ] */ ; - CONS - /* [ list operation : @balance mutez ] */ ; - PAIR - /* [ pair (list operation) (mutez @balance) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_nonexistent_view.tz].out deleted file mode 100644 index 2203259ca5d1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_nonexistent_view.tz].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/balance_after_nonexistent_view.tz] - -Well typed -Gas remaining: 1039985.815 units remaining -{ parameter address ; - storage mutez ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "nonexistent" - (pair nat nat) - /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; - ASSERT_NONE ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 15000000 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - BALANCE - /* [ @balance mutez : operation ] */ ; - SWAP - /* [ operation : @balance mutez ] */ ; - NIL operation - /* [ list operation : operation : @balance mutez ] */ ; - SWAP - /* [ operation : list operation : @balance mutez ] */ ; - CONS - /* [ list operation : @balance mutez ] */ ; - PAIR - /* [ pair (list operation) (mutez @balance) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_view.tz].out deleted file mode 100644 index 9e80c49c3dcc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_view.tz].out +++ /dev/null @@ -1,39 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/balance_after_view.tz] - -Well typed -Gas remaining: 1039985.432 units remaining -{ parameter address ; - storage mutez ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "id" - (pair nat nat) - /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 15000000 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - BALANCE - /* [ @balance mutez : operation ] */ ; - SWAP - /* [ operation : @balance mutez ] */ ; - NIL operation - /* [ list operation : operation : @balance mutez ] */ ; - SWAP - /* [ operation : list operation : @balance mutez ] */ ; - CONS - /* [ list operation : @balance mutez ] */ ; - PAIR - /* [ pair (list operation) (mutez @balance) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_nat.tz].out deleted file mode 100644 index a0f01c3a04a4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_nat.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/big_map_mem_nat.tz] - -Well typed -Gas remaining: 1039991.894 units remaining -{ parameter nat ; - storage (pair (big_map nat nat) (option bool)) ; - code { UNPAIR - /* [ @parameter nat : @storage pair (big_map nat nat) (option bool) ] */ ; - DIP { CAR /* [ big_map nat nat ] */ ; DUP /* [ big_map nat nat : big_map nat nat ] */ } - /* [ @parameter nat : big_map nat nat : big_map nat nat ] */ ; - MEM - /* [ bool : big_map nat nat ] */ ; - SOME - /* [ option bool : big_map nat nat ] */ ; - SWAP - /* [ big_map nat nat : option bool ] */ ; - PAIR - /* [ pair (big_map nat nat) (option bool) ] */ ; - NIL operation - /* [ list operation : pair (big_map nat nat) (option bool) ] */ ; - PAIR - /* [ pair (list operation) (big_map nat nat) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_string.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_string.tz].out deleted file mode 100644 index a44ec7f803f8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_string.tz].out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/big_map_mem_string.tz] - -Well typed -Gas remaining: 1039991.894 units remaining -{ parameter string ; - storage (pair (big_map string nat) (option bool)) ; - code { UNPAIR - /* [ @parameter string : @storage pair (big_map string nat) (option bool) ] */ ; - DIP { CAR - /* [ big_map string nat ] */ ; - DUP - /* [ big_map string nat : big_map string nat ] */ } - /* [ @parameter string : big_map string nat : big_map string nat ] */ ; - MEM - /* [ bool : big_map string nat ] */ ; - SOME - /* [ option bool : big_map string nat ] */ ; - SWAP - /* [ big_map string nat : option bool ] */ ; - PAIR - /* [ pair (big_map string nat) (option bool) ] */ ; - NIL operation - /* [ list operation : pair (big_map string nat) (option bool) ] */ ; - PAIR - /* [ pair (list operation) (big_map string nat) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_to_self.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_to_self.tz].out deleted file mode 100644 index 90bd798d5dfd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_to_self.tz].out +++ /dev/null @@ -1,59 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/big_map_to_self.tz] - -Well typed -Gas remaining: 1039984.417 units remaining -{ parameter (or (pair %have_fun (big_map string nat) unit) (unit %default)) ; - storage (big_map string nat) ; - code { UNPAIR - /* [ @parameter or (pair %have_fun (big_map string nat) unit) (unit %default) - : @storage big_map string nat ] */ ; - DIP { NIL operation /* [ list operation : @storage big_map string nat ] */ } - /* [ @parameter or (pair %have_fun (big_map string nat) unit) (unit %default) - : list operation : @storage big_map string nat ] */ ; - IF_LEFT - { DROP /* [ list operation : @storage big_map string nat ] */ } - { DROP - /* [ list operation : @storage big_map string nat ] */ ; - SELF %have_fun - /* [ @self contract (pair (big_map string nat) unit) : list operation - : @storage big_map string nat ] */ ; - PUSH mutez - 0 - /* [ mutez : @self contract (pair (big_map string nat) unit) : list operation - : @storage big_map string nat ] */ ; - DUP 4 - /* [ big_map string nat : mutez - : @self contract (pair (big_map string nat) unit) : list operation - : @storage big_map string nat ] */ ; - PUSH (option nat) - (Some 8) - /* [ option nat : big_map string nat : mutez - : @self contract (pair (big_map string nat) unit) : list operation - : @storage big_map string nat ] */ ; - PUSH string - "hahaha" - /* [ string : option nat : big_map string nat : mutez - : @self contract (pair (big_map string nat) unit) : list operation - : @storage big_map string nat ] */ ; - UPDATE - /* [ big_map string nat : mutez - : @self contract (pair (big_map string nat) unit) : list operation - : @storage big_map string nat ] */ ; - UNIT - /* [ unit : big_map string nat : mutez - : @self contract (pair (big_map string nat) unit) : list operation - : @storage big_map string nat ] */ ; - SWAP - /* [ big_map string nat : unit : mutez - : @self contract (pair (big_map string nat) unit) : list operation - : @storage big_map string nat ] */ ; - PAIR - /* [ pair (big_map string nat) unit : mutez - : @self contract (pair (big_map string nat) unit) : list operation - : @storage big_map string nat ] */ ; - TRANSFER_TOKENS - /* [ operation : list operation : @storage big_map string nat ] */ ; - CONS - /* [ list operation : @storage big_map string nat ] */ } ; - PAIR - /* [ pair (list operation) (big_map @storage string nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_bytes_not_padded.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_bytes_not_padded.tz].out deleted file mode 100644 index dce18befe18f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_bytes_not_padded.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_push_bytes_not_padded.tz] - -Well typed -Gas remaining: 1039995.606 units remaining -{ parameter unit ; - storage (option bls12_381_fr) ; - code { DROP - /* [] */ ; - PUSH bls12_381_fr 0x00 - /* [ bls12_381_fr ] */ ; - SOME - /* [ option bls12_381_fr ] */ ; - NIL operation - /* [ list operation : option bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_nat.tz].out deleted file mode 100644 index 1740e7aea47d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_nat.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_push_nat.tz] - -Well typed -Gas remaining: 1039995.606 units remaining -{ parameter unit ; - storage (option bls12_381_fr) ; - code { DROP - /* [] */ ; - PUSH bls12_381_fr 16 - /* [ bls12_381_fr ] */ ; - SOME - /* [ option bls12_381_fr ] */ ; - NIL operation - /* [ list operation : option bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_int.tz].out deleted file mode 100644 index a42dbc44c1b6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_int.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_to_int.tz] - -Well typed -Gas remaining: 1039996.803 units remaining -{ parameter bls12_381_fr ; - storage int ; - code { CAR - /* [ @parameter bls12_381_fr ] */ ; - INT - /* [ int ] */ ; - NIL operation - /* [ list operation : int ] */ ; - PAIR - /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_mutez.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_mutez.tz].out deleted file mode 100644 index be46d82f4288..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_mutez.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_to_mutez.tz] - -Well typed -Gas remaining: 1039992.954 units remaining -{ parameter bls12_381_fr ; - storage mutez ; - code { CAR - /* [ @parameter bls12_381_fr ] */ ; - INT - /* [ int ] */ ; - ISNAT - /* [ option nat ] */ ; - ASSERT_SOME ; - PUSH mutez 1 - /* [ mutez : @some nat ] */ ; - MUL - /* [ mutez ] */ ; - NIL operation - /* [ list operation : mutez ] */ ; - PAIR - /* [ pair (list operation) mutez ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_int.tz].out deleted file mode 100644 index a355325fb8f0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_int.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_z_int.tz] - -Well typed -Gas remaining: 1039996.803 units remaining -{ parameter int ; - storage bls12_381_fr ; - code { UNPAIR - /* [ @parameter int : @storage bls12_381_fr ] */ ; - MUL - /* [ bls12_381_fr ] */ ; - NIL operation - /* [ list operation : bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_nat.tz].out deleted file mode 100644 index 37879db7b58d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_nat.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_z_nat.tz] - -Well typed -Gas remaining: 1039996.803 units remaining -{ parameter nat ; - storage bls12_381_fr ; - code { UNPAIR - /* [ @parameter nat : @storage bls12_381_fr ] */ ; - MUL - /* [ bls12_381_fr ] */ ; - NIL operation - /* [ list operation : bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_int.tz].out deleted file mode 100644 index 9c1eed1aa97e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_int.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_z_fr_int.tz] - -Well typed -Gas remaining: 1039996.340 units remaining -{ parameter int ; - storage bls12_381_fr ; - code { UNPAIR - /* [ @parameter int : @storage bls12_381_fr ] */ ; - SWAP - /* [ @storage bls12_381_fr : @parameter int ] */ ; - MUL - /* [ bls12_381_fr ] */ ; - NIL operation - /* [ list operation : bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_nat.tz].out deleted file mode 100644 index 1751cc011e6d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_nat.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_z_fr_nat.tz] - -Well typed -Gas remaining: 1039996.340 units remaining -{ parameter nat ; - storage bls12_381_fr ; - code { UNPAIR - /* [ @parameter nat : @storage bls12_381_fr ] */ ; - SWAP - /* [ @storage bls12_381_fr : @parameter nat ] */ ; - MUL - /* [ bls12_381_fr ] */ ; - NIL operation - /* [ list operation : bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bytes.tz].out deleted file mode 100644 index f225f02dcac7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bytes.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bytes.tz] - -Well typed -Gas remaining: 1039997.267 units remaining -{ parameter bytes ; - storage unit ; - code { CDR - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--car.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--car.tz].out deleted file mode 100644 index 272f47aeeb09..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--car.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/car.tz] - -Well typed -Gas remaining: 1039996.637 units remaining -{ parameter (pair (nat :l) (nat :r)) ; - storage nat ; - code { CAR - /* [ @parameter pair (nat :l) (nat :r) ] */ ; - CAR - /* [ nat :l ] */ ; - NIL operation - /* [ list operation : nat :l ] */ ; - PAIR - /* [ pair (list operation) (nat :l) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cdr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cdr.tz].out deleted file mode 100644 index df2139897527..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cdr.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/cdr.tz] - -Well typed -Gas remaining: 1039996.637 units remaining -{ parameter (pair (nat :l) (nat :r)) ; - storage nat ; - code { CAR - /* [ @parameter pair (nat :l) (nat :r) ] */ ; - CDR - /* [ nat :r ] */ ; - NIL operation - /* [ list operation : nat :r ] */ ; - PAIR - /* [ pair (list operation) (nat :r) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id.tz].out deleted file mode 100644 index 070dce606488..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/chain_id.tz] - -Well typed -Gas remaining: 1039996.340 units remaining -{ parameter unit ; - storage unit ; - code { CHAIN_ID - /* [ chain_id : pair (unit @parameter) (unit @storage) ] */ ; - DROP - /* [ pair (unit @parameter) (unit @storage) ] */ ; - CAR - /* [ @parameter unit ] */ ; - NIL operation - /* [ list operation : @parameter unit ] */ ; - PAIR - /* [ pair (list operation) (unit @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id_store.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id_store.tz].out deleted file mode 100644 index 08f40696caf9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id_store.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/chain_id_store.tz] - -Well typed -Gas remaining: 1039996.037 units remaining -{ parameter unit ; - storage (option chain_id) ; - code { DROP - /* [] */ ; - CHAIN_ID - /* [ chain_id ] */ ; - SOME - /* [ option chain_id ] */ ; - NIL operation - /* [ list operation : option chain_id ] */ ; - PAIR - /* [ pair (list operation) (option chain_id) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--check_signature.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--check_signature.tz].out deleted file mode 100644 index 52f6c404d590..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--check_signature.tz].out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/check_signature.tz] - -Well typed -Gas remaining: 1039988.024 units remaining -{ parameter key ; - storage (pair signature string) ; - code { DUP - /* [ pair (key @parameter) (pair @storage signature string) - : pair (key @parameter) (pair @storage signature string) ] */ ; - DUP - /* [ pair (key @parameter) (pair @storage signature string) - : pair (key @parameter) (pair @storage signature string) - : pair (key @parameter) (pair @storage signature string) ] */ ; - DIP { CDR - /* [ @storage pair signature string - : pair (key @parameter) (pair @storage signature string) ] */ ; - DUP - /* [ @storage pair signature string : @storage pair signature string - : pair (key @parameter) (pair @storage signature string) ] */ ; - CAR - /* [ signature : @storage pair signature string - : pair (key @parameter) (pair @storage signature string) ] */ ; - DIP { CDR - /* [ string : pair (key @parameter) (pair @storage signature string) ] */ ; - PACK - /* [ @packed bytes : pair (key @parameter) (pair @storage signature string) ] */ } - /* [ signature : @packed bytes - : pair (key @parameter) (pair @storage signature string) ] */ } - /* [ pair (key @parameter) (pair @storage signature string) : signature - : @packed bytes : pair (key @parameter) (pair @storage signature string) ] */ ; - CAR - /* [ @parameter key : signature : @packed bytes - : pair (key @parameter) (pair @storage signature string) ] */ ; - CHECK_SIGNATURE - /* [ bool : pair (key @parameter) (pair @storage signature string) ] */ ; - IF { /* [ pair (key @parameter) (pair @storage signature string) ] */ } { FAIL } ; - CDR - /* [ @storage pair signature string ] */ ; - NIL operation - /* [ list operation : @storage pair signature string ] */ ; - PAIR - /* [ pair (list operation) (pair @storage signature string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-get.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-get.tz].out deleted file mode 100644 index a6a0ef9a1aec..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-get.tz].out +++ /dev/null @@ -1,51 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb-get.tz] - -Well typed -Gas remaining: 1039964.212 units remaining -{ parameter (pair nat nat nat unit) ; - storage unit ; - code { CAR - /* [ @parameter pair nat nat nat unit ] */ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - CAR - /* [ nat : @parameter pair nat nat nat unit ] */ ; - PUSH nat 1 - /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - GET 1 - /* [ nat : @parameter pair nat nat nat unit ] */ ; - PUSH nat 1 - /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - GET 3 - /* [ nat : @parameter pair nat nat nat unit ] */ ; - PUSH nat 4 - /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - GET 5 - /* [ nat : @parameter pair nat nat nat unit ] */ ; - PUSH nat 2 - /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; - GET 6 - /* [ unit : @parameter pair nat nat nat unit ] */ ; - UNIT - /* [ unit : unit : @parameter pair nat nat nat unit ] */ ; - ASSERT_CMPEQ ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-literals.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-literals.tz].out deleted file mode 100644 index c62bce8c1037..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-literals.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb-literals.tz] - -Well typed -Gas remaining: 1039992.630 units remaining -{ parameter unit ; - storage unit ; - code { PUSH (list (pair nat nat nat nat)) - { Pair 0 3 6 9 ; Pair 1 (Pair 4 (Pair 7 10)) ; { 2 ; 5 ; 8 ; 11 } } - /* [ list (pair nat nat nat nat) : pair (unit @parameter) (unit @storage) ] */ ; - DROP 2 - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set-2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set-2.tz].out deleted file mode 100644 index d281b53dd407..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set-2.tz].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb-set-2.tz] - -Well typed -Gas remaining: 1039989.821 units remaining -{ parameter (pair nat nat nat unit) ; - storage (option (pair int nat string bytes)) ; - code { CAR - /* [ @parameter pair nat nat nat unit ] */ ; - PUSH int 2 - /* [ int : @parameter pair nat nat nat unit ] */ ; - UPDATE 1 - /* [ pair int nat nat unit ] */ ; - PUSH string "toto" - /* [ string : pair int nat nat unit ] */ ; - UPDATE 5 - /* [ pair int nat string unit ] */ ; - PUSH bytes 0x01 - /* [ bytes : pair int nat string unit ] */ ; - UPDATE 6 - /* [ pair int nat string bytes ] */ ; - SOME - /* [ option (pair int nat string bytes) ] */ ; - NIL operation - /* [ list operation : option (pair int nat string bytes) ] */ ; - PAIR - /* [ pair (list operation) (option (pair int nat string bytes)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set.tz].out deleted file mode 100644 index b26fcb8dc9c0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set.tz].out +++ /dev/null @@ -1,28 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb-set.tz] - -Well typed -Gas remaining: 1039990.023 units remaining -{ parameter unit ; - storage (pair nat nat nat unit) ; - code { CDR - /* [ @storage pair nat nat nat unit ] */ ; - PUSH nat 2 - /* [ nat : @storage pair nat nat nat unit ] */ ; - UPDATE 1 - /* [ pair nat nat nat unit ] */ ; - PUSH nat 12 - /* [ nat : pair nat nat nat unit ] */ ; - UPDATE 3 - /* [ pair nat nat nat unit ] */ ; - PUSH nat 8 - /* [ nat : pair nat nat nat unit ] */ ; - UPDATE 5 - /* [ pair nat nat nat unit ] */ ; - UNIT - /* [ unit : pair nat nat nat unit ] */ ; - UPDATE 6 - /* [ pair nat nat nat unit ] */ ; - NIL operation - /* [ list operation : pair nat nat nat unit ] */ ; - PAIR - /* [ pair (list operation) nat nat nat unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb.tz].out deleted file mode 100644 index aa075fec77b6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb.tz] - -Well typed -Gas remaining: 1039993.734 units remaining -{ parameter unit ; - storage (pair nat nat nat) ; - code { DROP - /* [] */ ; - PUSH nat 3 - /* [ nat ] */ ; - PUSH nat 2 - /* [ nat : nat ] */ ; - PUSH nat 1 - /* [ nat : nat : nat ] */ ; - NIL operation - /* [ list operation : nat : nat : nat ] */ ; - PAIR 4 - /* [ pair (list operation) nat nat nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare.tz].out deleted file mode 100644 index 0696ab8acf78..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare.tz].out +++ /dev/null @@ -1,217 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/compare.tz] - -Well typed -Gas remaining: 1039832.943 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - PUSH bool True - /* [ bool ] */ ; - DUP - /* [ bool : bool ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH bool False - /* [ bool ] */ ; - DUP - /* [ bool : bool ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH bool False - /* [ bool ] */ ; - PUSH bool True - /* [ bool : bool ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH bool True - /* [ bool ] */ ; - PUSH bool False - /* [ bool : bool ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LT ; - PUSH bytes 0xaabbcc - /* [ bytes ] */ ; - DUP - /* [ bytes : bytes ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH bytes 0x - /* [ bytes ] */ ; - PUSH bytes 0x - /* [ bytes : bytes ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH bytes 0x - /* [ bytes ] */ ; - PUSH bytes 0x01 - /* [ bytes : bytes ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH bytes 0x01 - /* [ bytes ] */ ; - PUSH bytes 0x02 - /* [ bytes : bytes ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH bytes 0x02 - /* [ bytes ] */ ; - PUSH bytes 0x01 - /* [ bytes : bytes ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LT ; - PUSH int 1 - /* [ int ] */ ; - DUP - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH int 10 - /* [ int ] */ ; - PUSH int 5 - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LT ; - PUSH int -4 - /* [ int ] */ ; - PUSH int 1923 - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH nat 1 - /* [ nat ] */ ; - DUP - /* [ nat : nat ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH nat 10 - /* [ nat ] */ ; - PUSH nat 5 - /* [ nat : nat ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LT ; - PUSH nat 4 - /* [ nat ] */ ; - PUSH nat 1923 - /* [ nat : nat ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" - /* [ key_hash ] */ ; - DUP - /* [ key_hash : key_hash ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH key_hash "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" - /* [ key_hash ] */ ; - PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" - /* [ key_hash : key_hash ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LT ; - PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" - /* [ key_hash ] */ ; - PUSH key_hash "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" - /* [ key_hash : key_hash ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH mutez 1 - /* [ mutez ] */ ; - DUP - /* [ mutez : mutez ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH mutez 10 - /* [ mutez ] */ ; - PUSH mutez 5 - /* [ mutez : mutez ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LT ; - PUSH mutez 4 - /* [ mutez ] */ ; - PUSH mutez 1923 - /* [ mutez : mutez ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH string "AABBCC" - /* [ string ] */ ; - DUP - /* [ string : string ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH string "" - /* [ string ] */ ; - PUSH string "" - /* [ string : string ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH string "" - /* [ string ] */ ; - PUSH string "a" - /* [ string : string ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH string "a" - /* [ string ] */ ; - PUSH string "b" - /* [ string : string ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH string "b" - /* [ string ] */ ; - PUSH string "a" - /* [ string : string ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LT ; - PUSH timestamp "2019-09-16T08:38:05Z" - /* [ timestamp ] */ ; - DUP - /* [ timestamp : timestamp ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH timestamp "2017-09-16T08:38:04Z" - /* [ timestamp ] */ ; - PUSH timestamp "2019-09-16T08:38:05Z" - /* [ timestamp : timestamp ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_GT ; - PUSH timestamp "2019-09-16T08:38:05Z" - /* [ timestamp ] */ ; - PUSH timestamp "2019-09-16T08:38:04Z" - /* [ timestamp : timestamp ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_LT ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type.tz].out deleted file mode 100644 index 12b1ae2ecd5e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type.tz].out +++ /dev/null @@ -1,3737 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/compare_big_type.tz] - -Well typed -Gas remaining: 1038270.787 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - PUSH nat 0 - /* [ nat ] */ ; - DUP - /* [ nat : nat ] */ ; - PAIR - /* [ pair nat nat ] */ ; - DUP - /* [ pair nat nat : pair nat nat ] */ ; - PAIR - /* [ pair (pair nat nat) nat nat ] */ ; - DUP - /* [ pair (pair nat nat) nat nat : pair (pair nat nat) nat nat ] */ ; - PAIR - /* [ pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat ] */ ; - DUP - /* [ pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat - : pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat ] */ ; - PAIR - /* [ pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - PAIR - /* [ pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - PAIR - /* [ pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - PAIR - /* [ pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - PAIR - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type2.tz].out deleted file mode 100644 index 94aa94b0bf06..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type2.tz].out +++ /dev/null @@ -1,4302 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/compare_big_type2.tz] - -Well typed -Gas remaining: 1037992.958 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - PUSH nat 0 - /* [ nat ] */ ; - DUP - /* [ nat : nat ] */ ; - PAIR - /* [ pair nat nat ] */ ; - DUP - /* [ pair nat nat : pair nat nat ] */ ; - PAIR - /* [ pair (pair nat nat) nat nat ] */ ; - DUP - /* [ pair (pair nat nat) nat nat : pair (pair nat nat) nat nat ] */ ; - PAIR - /* [ pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat ] */ ; - DUP - /* [ pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat - : pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat ] */ ; - PAIR - /* [ pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - PAIR - /* [ pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - PAIR - /* [ pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - PAIR - /* [ pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - PAIR - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DUP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - COMPARE - /* [ int - : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat) - (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) - (pair (pair nat nat) nat nat) - (pair nat nat) - nat - nat ] */ ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comparisons.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comparisons.tz].out deleted file mode 100644 index 45a95f6e874b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comparisons.tz].out +++ /dev/null @@ -1,65 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comparisons.tz] - -Well typed -Gas remaining: 1039972.732 units remaining -{ parameter (list int) ; - storage (list (list bool)) ; - code { CAR - /* [ @parameter list int ] */ ; - NIL (list bool) - /* [ list (list bool) : @parameter list int ] */ ; - DIP { DUP - /* [ @parameter list int : @parameter list int ] */ ; - MAP { EQ /* [ bool : @parameter list int ] */ } - /* [ list bool : @parameter list int ] */ } - /* [ list (list bool) : list bool : @parameter list int ] */ ; - SWAP - /* [ list bool : list (list bool) : @parameter list int ] */ ; - CONS - /* [ list (list bool) : @parameter list int ] */ ; - DIP { DUP - /* [ @parameter list int : @parameter list int ] */ ; - MAP { NEQ /* [ bool : @parameter list int ] */ } - /* [ list bool : @parameter list int ] */ } - /* [ list (list bool) : list bool : @parameter list int ] */ ; - SWAP - /* [ list bool : list (list bool) : @parameter list int ] */ ; - CONS - /* [ list (list bool) : @parameter list int ] */ ; - DIP { DUP - /* [ @parameter list int : @parameter list int ] */ ; - MAP { LE /* [ bool : @parameter list int ] */ } - /* [ list bool : @parameter list int ] */ } - /* [ list (list bool) : list bool : @parameter list int ] */ ; - SWAP - /* [ list bool : list (list bool) : @parameter list int ] */ ; - CONS - /* [ list (list bool) : @parameter list int ] */ ; - DIP { DUP - /* [ @parameter list int : @parameter list int ] */ ; - MAP { LT /* [ bool : @parameter list int ] */ } - /* [ list bool : @parameter list int ] */ } - /* [ list (list bool) : list bool : @parameter list int ] */ ; - SWAP - /* [ list bool : list (list bool) : @parameter list int ] */ ; - CONS - /* [ list (list bool) : @parameter list int ] */ ; - DIP { DUP - /* [ @parameter list int : @parameter list int ] */ ; - MAP { GE /* [ bool : @parameter list int ] */ } - /* [ list bool : @parameter list int ] */ } - /* [ list (list bool) : list bool : @parameter list int ] */ ; - SWAP - /* [ list bool : list (list bool) : @parameter list int ] */ ; - CONS - /* [ list (list bool) : @parameter list int ] */ ; - DIP { MAP { GT /* [ bool ] */ } /* [ list bool ] */ } - /* [ list (list bool) : list bool ] */ ; - SWAP - /* [ list bool : list (list bool) ] */ ; - CONS - /* [ list (list bool) ] */ ; - NIL operation - /* [ list operation : list (list bool) ] */ ; - PAIR - /* [ pair (list operation) (list (list bool)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello.tz].out deleted file mode 100644 index 37bf2a056a20..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/concat_hello.tz] - -Well typed -Gas remaining: 1039995.099 units remaining -{ parameter (list string) ; - storage (list string) ; - code { CAR - /* [ @parameter list string ] */ ; - MAP { PUSH @hello string "Hello " - /* [ @hello string : @parameter.elt string ] */ ; - CONCAT - /* [ string ] */ } - /* [ list string ] */ ; - NIL operation - /* [ list operation : list string ] */ ; - PAIR - /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello_bytes.tz].out deleted file mode 100644 index 13ea77d245c5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello_bytes.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/concat_hello_bytes.tz] - -Well typed -Gas remaining: 1039995.173 units remaining -{ parameter (list bytes) ; - storage (list bytes) ; - code { CAR - /* [ @parameter list bytes ] */ ; - MAP { PUSH bytes 0xff /* [ bytes : @parameter.elt bytes ] */ ; CONCAT /* [ bytes ] */ } - /* [ list bytes ] */ ; - NIL operation - /* [ list operation : list bytes ] */ ; - PAIR - /* [ pair (list operation) (list bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_list.tz].out deleted file mode 100644 index 5f9bc542ad3b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_list.tz].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/concat_list.tz] - -Well typed -Gas remaining: 1039991.417 units remaining -{ parameter (list string) ; - storage string ; - code { CAR - /* [ @parameter list string ] */ ; - PUSH string "" - /* [ string : @parameter list string ] */ ; - SWAP - /* [ @parameter list string : string ] */ ; - ITER { SWAP - /* [ string : @parameter.elt string ] */ ; - DIP { NIL string - /* [ list string : @parameter.elt string ] */ ; - SWAP - /* [ @parameter.elt string : list string ] */ ; - CONS - /* [ list string ] */ } - /* [ string : list string ] */ ; - CONS - /* [ list string ] */ ; - CONCAT - /* [ string ] */ } - /* [ string ] */ ; - NIL operation - /* [ list operation : string ] */ ; - PAIR - /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cons.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cons.tz].out deleted file mode 100644 index 2bbe4fb44b8c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cons.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/cons.tz] - -Well typed -Gas remaining: 1039996.280 units remaining -{ parameter int ; - storage (list int) ; - code { UNPAIR - /* [ @parameter int : @storage list int ] */ ; - CONS - /* [ list int ] */ ; - NIL operation - /* [ list operation : list int ] */ ; - PAIR - /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contains_all.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contains_all.tz].out deleted file mode 100644 index 99af8ee7b93c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contains_all.tz].out +++ /dev/null @@ -1,79 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/contains_all.tz] - -Well typed -Gas remaining: 1039972.367 units remaining -{ parameter (pair (list string) (list string)) ; - storage (option bool) ; - code { CAR - /* [ @parameter pair (list string) (list string) ] */ ; - DUP - /* [ @parameter pair (list string) (list string) - : @parameter pair (list string) (list string) ] */ ; - CAR - /* [ list string : @parameter pair (list string) (list string) ] */ ; - DIP { CDR /* [ list string ] */ } - /* [ list string : list string ] */ ; - EMPTY_SET string - /* [ set string : list string : list string ] */ ; - SWAP - /* [ list string : set string : list string ] */ ; - ITER { PAIR - /* [ pair (string @elt) (set string) : list string ] */ ; - DUP - /* [ pair (string @elt) (set string) : pair (string @elt) (set string) - : list string ] */ ; - CAR - /* [ @elt string : pair (string @elt) (set string) : list string ] */ ; - DIP { CDR /* [ set string : list string ] */ } - /* [ @elt string : set string : list string ] */ ; - PUSH bool True - /* [ bool : @elt string : set string : list string ] */ ; - SWAP - /* [ @elt string : bool : set string : list string ] */ ; - UPDATE - /* [ set string : list string ] */ } - /* [ set string : list string ] */ ; - PUSH bool True - /* [ bool : set string : list string ] */ ; - SWAP - /* [ set string : bool : list string ] */ ; - PAIR - /* [ pair (set string) bool : list string ] */ ; - SWAP - /* [ list string : pair (set string) bool ] */ ; - ITER { PAIR - /* [ pair (string @elt) (set string) bool ] */ ; - DUP - /* [ pair (string @elt) (set string) bool - : pair (string @elt) (set string) bool ] */ ; - DUP - /* [ pair (string @elt) (set string) bool : pair (string @elt) (set string) bool - : pair (string @elt) (set string) bool ] */ ; - CAR - /* [ @elt string : pair (string @elt) (set string) bool - : pair (string @elt) (set string) bool ] */ ; - DIP { CDAR ; - DIP { CDDR } - /* [ set string : bool ] */ ; - DUP - /* [ set string : set string : bool ] */ } - /* [ @elt string : set string : set string : bool ] */ ; - MEM - /* [ bool : set string : bool ] */ ; - DIP { SWAP /* [ bool : set string ] */ } - /* [ bool : bool : set string ] */ ; - AND - /* [ bool : set string ] */ ; - SWAP - /* [ set string : bool ] */ ; - PAIR - /* [ pair (set string) bool ] */ } - /* [ pair (set string) bool ] */ ; - CDR - /* [ bool ] */ ; - SOME - /* [ option bool ] */ ; - NIL operation - /* [ list operation : option bool ] */ ; - PAIR - /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contract.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contract.tz].out deleted file mode 100644 index d12bb163416c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contract.tz].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/contract.tz] - -Well typed -Gas remaining: 1039993.550 units remaining -{ parameter address ; - storage unit ; - code { CAR - /* [ @parameter address ] */ ; - CONTRACT unit - /* [ @parameter.contract option (contract unit) ] */ ; - ASSERT_SOME ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract.tz].out deleted file mode 100644 index f3c4ba9f0512..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract.tz].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/create_contract.tz] - -Well typed -Gas remaining: 1039988.704 units remaining -{ parameter unit ; - storage (option address) ; - code { /* [ pair (unit @parameter) (unit @storage) ] */ - DROP - /* [ list operation : @storage unit ] */ ; - UNIT - /* [ unit ] */ ; - AMOUNT - /* [ pair (list operation) (unit @storage) ] */ ; - NONE key_hash - /* [ option key_hash : @amount mutez : unit ] */ ; - CREATE_CONTRACT - { parameter unit ; storage unit ; code { CDR ; NIL operation ; PAIR } } - /* [ operation : address ] */ ; - DIP { SOME - /* [ option address ] */ ; - NIL operation - /* [ list operation : option address ] */ } - /* [ operation : list operation : option address ] */ ; - CONS - /* [ list operation : option address ] */ ; - PAIR - /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out deleted file mode 100644 index 397048c9d024..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out +++ /dev/null @@ -1,29 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/create_contract_rootname.tz] - -Well typed -Gas remaining: 1039988.704 units remaining -{ parameter unit ; - storage (option address) ; - code { /* [ pair (unit @parameter) (unit @storage) ] */ - DROP - /* [ list operation : @storage unit ] */ ; - UNIT - /* [ unit ] */ ; - AMOUNT - /* [ pair (list operation) (unit @storage) ] */ ; - NONE key_hash - /* [ option key_hash : @amount mutez : unit ] */ ; - CREATE_CONTRACT - { parameter %root unit ; - storage unit ; - code { CDR ; NIL operation ; PAIR } } - /* [ operation : address ] */ ; - DIP { SOME - /* [ option address ] */ ; - NIL operation - /* [ list operation : option address ] */ } - /* [ operation : list operation : option address ] */ ; - CONS - /* [ list operation : option address ] */ ; - PAIR - /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname_alt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname_alt.tz].out deleted file mode 100644 index 84cd164c89cf..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname_alt.tz].out +++ /dev/null @@ -1,29 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/create_contract_rootname_alt.tz] - -Well typed -Gas remaining: 1039988.704 units remaining -{ parameter unit ; - storage (option address) ; - code { /* [ pair (unit @parameter) (unit @storage) ] */ - DROP - /* [ list operation : @storage unit ] */ ; - UNIT - /* [ unit ] */ ; - AMOUNT - /* [ pair (list operation) (unit @storage) ] */ ; - NONE key_hash - /* [ option key_hash : @amount mutez : unit ] */ ; - CREATE_CONTRACT - { parameter (unit %root) ; - storage unit ; - code { CDR ; NIL operation ; PAIR } } - /* [ operation : address ] */ ; - DIP { SOME - /* [ option address ] */ ; - NIL operation - /* [ list operation : option address ] */ } - /* [ operation : list operation : option address ] */ ; - CONS - /* [ list operation : option address ] */ ; - PAIR - /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_with_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_with_view.tz].out deleted file mode 100644 index d5922595a95c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_with_view.tz].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/create_contract_with_view.tz] - -Well typed -Gas remaining: 1039987.516 units remaining -{ parameter unit ; - storage (option address) ; - code { /* [ pair (unit @parameter) (unit @storage) ] */ - DROP - /* [ list operation : @storage unit ] */ ; - UNIT - /* [ unit ] */ ; - AMOUNT - /* [ pair (list operation) (unit @storage) ] */ ; - NONE key_hash - /* [ option key_hash : @amount mutez : unit ] */ ; - CREATE_CONTRACT - { parameter unit /* [ nat ] */ ; - storage unit ; - code { CDR ; NIL operation ; PAIR } ; - view "const" nat nat { CAR } } - /* [ operation : address ] */ ; - DIP { SOME - /* [ option address ] */ ; - NIL operation - /* [ list operation : option address ] */ } - /* [ operation : list operation : option address ] */ ; - CONS - /* [ list operation : option address ] */ ; - PAIR - /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--diff_timestamps.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--diff_timestamps.tz].out deleted file mode 100644 index 5b0a59eeab26..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--diff_timestamps.tz].out +++ /dev/null @@ -1,20 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/diff_timestamps.tz] - -Well typed -Gas remaining: 1039994.373 units remaining -{ parameter (pair timestamp timestamp) ; - storage int ; - code { CAR - /* [ @parameter pair timestamp timestamp ] */ ; - DUP - /* [ @parameter pair timestamp timestamp : @parameter pair timestamp timestamp ] */ ; - CAR - /* [ timestamp : @parameter pair timestamp timestamp ] */ ; - DIP { CDR /* [ timestamp ] */ } - /* [ timestamp : timestamp ] */ ; - SUB - /* [ int ] */ ; - NIL operation - /* [ list operation : int ] */ ; - PAIR - /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dig_eq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dig_eq.tz].out deleted file mode 100644 index a017f9750926..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dig_eq.tz].out +++ /dev/null @@ -1,157 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dig_eq.tz] - -Well typed -Gas remaining: 1039899.367 units remaining -{ parameter - (pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat) ; - storage unit ; - code { CAR - /* [ @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DUP - /* [ @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - UNPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAIR ; - DIG 0 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 1 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 2 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 3 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 4 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 5 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 6 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 7 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 8 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 9 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 10 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 11 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 12 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 13 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 14 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 15 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 16 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 0 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 1 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 2 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 3 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 4 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 5 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 6 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 7 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 8 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 9 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 10 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 11 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 12 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 13 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 14 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 15 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - DIG 16 - /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat - : nat : nat : nat : nat - : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; - PAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAIR ; - ASSERT_CMPEQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dign.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dign.tz].out deleted file mode 100644 index 9ba1b3f08a64..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dign.tz].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dign.tz] - -Well typed -Gas remaining: 1039991.580 units remaining -{ parameter (pair (pair (pair (pair nat nat) nat) nat) nat) ; - storage nat ; - code { CAR - /* [ @parameter pair (pair (pair (pair nat nat) nat) nat) nat ] */ ; - UNPAIR - /* [ pair (pair (pair nat nat) nat) nat : nat ] */ ; - UNPAIR - /* [ pair (pair nat nat) nat : nat : nat ] */ ; - UNPAIR - /* [ pair nat nat : nat : nat : nat ] */ ; - UNPAIR - /* [ nat : nat : nat : nat : nat ] */ ; - DIG 4 - /* [ nat : nat : nat : nat : nat ] */ ; - DIP { DROP /* [ nat : nat : nat ] */ ; DROP /* [ nat : nat ] */ ; DROP /* [ nat ] */ ; DROP /* [] */ } - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dip.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dip.tz].out deleted file mode 100644 index f5e51cd0143f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dip.tz].out +++ /dev/null @@ -1,20 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dip.tz] - -Well typed -Gas remaining: 1039993.958 units remaining -{ parameter (pair nat nat) ; - storage (pair nat nat) ; - code { CAR - /* [ @parameter pair nat nat ] */ ; - UNPAIR - /* [ nat : nat ] */ ; - DUP - /* [ nat : nat : nat ] */ ; - DIP { ADD /* [ nat ] */ } - /* [ nat : nat ] */ ; - PAIR - /* [ pair nat nat ] */ ; - NIL operation - /* [ list operation : pair nat nat ] */ ; - PAIR - /* [ pair (list operation) nat nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dipn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dipn.tz].out deleted file mode 100644 index fd733ff07e75..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dipn.tz].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dipn.tz] - -Well typed -Gas remaining: 1039990.690 units remaining -{ parameter (pair (pair (pair (pair nat nat) nat) nat) nat) ; - storage nat ; - code { CAR - /* [ @parameter pair (pair (pair (pair nat nat) nat) nat) nat ] */ ; - UNPAIR - /* [ pair (pair (pair nat nat) nat) nat : nat ] */ ; - UNPAIR - /* [ pair (pair nat nat) nat : nat : nat ] */ ; - UNPAIR - /* [ pair nat nat : nat : nat : nat ] */ ; - UNPAIR - /* [ nat : nat : nat : nat : nat ] */ ; - DIP 5 { PUSH nat 6 /* [ nat ] */ } - /* [ nat : nat : nat : nat : nat : nat ] */ ; - DROP - /* [ nat : nat : nat : nat : nat ] */ ; - DROP - /* [ nat : nat : nat : nat ] */ ; - DROP - /* [ nat : nat : nat ] */ ; - DROP - /* [ nat : nat ] */ ; - DROP - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dropn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dropn.tz].out deleted file mode 100644 index 483d913e4537..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dropn.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dropn.tz] - -Well typed -Gas remaining: 1039993.947 units remaining -{ parameter (pair (pair (pair (pair nat nat) nat) nat) nat) ; - storage nat ; - code { CAR - /* [ @parameter pair (pair (pair (pair nat nat) nat) nat) nat ] */ ; - UNPAIR - /* [ pair (pair (pair nat nat) nat) nat : nat ] */ ; - UNPAIR - /* [ pair (pair nat nat) nat : nat : nat ] */ ; - UNPAIR - /* [ pair nat nat : nat : nat : nat ] */ ; - UNPAIR - /* [ nat : nat : nat : nat : nat ] */ ; - DROP 4 - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dugn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dugn.tz].out deleted file mode 100644 index 618378b9929d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dugn.tz].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dugn.tz] - -Well typed -Gas remaining: 1039992.076 units remaining -{ parameter (pair (pair (pair (pair nat nat) nat) nat) nat) ; - storage nat ; - code { CAR - /* [ @parameter pair (pair (pair (pair nat nat) nat) nat) nat ] */ ; - UNPAIR - /* [ pair (pair (pair nat nat) nat) nat : nat ] */ ; - UNPAIR - /* [ pair (pair nat nat) nat : nat : nat ] */ ; - UNPAIR - /* [ pair nat nat : nat : nat : nat ] */ ; - UNPAIR - /* [ nat : nat : nat : nat : nat ] */ ; - DUG 4 - /* [ nat : nat : nat : nat : nat ] */ ; - DROP - /* [ nat : nat : nat : nat ] */ ; - DROP - /* [ nat : nat : nat ] */ ; - DROP - /* [ nat : nat ] */ ; - DROP - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dup-n.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dup-n.tz].out deleted file mode 100644 index 6b3687ea1f6a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dup-n.tz].out +++ /dev/null @@ -1,51 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dup-n.tz] - -Well typed -Gas remaining: 1039965.992 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - PUSH nat 5 - /* [ nat ] */ ; - PUSH nat 4 - /* [ nat : nat ] */ ; - PUSH nat 3 - /* [ nat : nat : nat ] */ ; - PUSH nat 2 - /* [ nat : nat : nat : nat ] */ ; - PUSH nat 1 - /* [ nat : nat : nat : nat : nat ] */ ; - DUP 1 - /* [ nat : nat : nat : nat : nat : nat ] */ ; - PUSH nat 1 - /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; - ASSERT_CMPEQ ; - DUP 2 - /* [ nat : nat : nat : nat : nat : nat ] */ ; - PUSH nat 2 - /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; - ASSERT_CMPEQ ; - DUP 3 - /* [ nat : nat : nat : nat : nat : nat ] */ ; - PUSH nat 3 - /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; - ASSERT_CMPEQ ; - DUP 4 - /* [ nat : nat : nat : nat : nat : nat ] */ ; - PUSH nat 4 - /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; - ASSERT_CMPEQ ; - DUP 5 - /* [ nat : nat : nat : nat : nat : nat ] */ ; - PUSH nat 5 - /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; - ASSERT_CMPEQ ; - DROP 5 - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv.tz].out deleted file mode 100644 index 3c29ac4d0478..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv.tz].out +++ /dev/null @@ -1,70 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ediv.tz] - -Well typed -Gas remaining: 1039978.198 units remaining -{ parameter (pair int int) ; - storage - (pair (option (pair int nat)) - (option (pair int nat)) - (option (pair int nat)) - (option (pair nat nat))) ; - code { CAR - /* [ @parameter pair int int ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int ] */ ; - UNPAIR - /* [ int : int : @parameter pair int int ] */ ; - ABS - /* [ nat : int : @parameter pair int int ] */ ; - DIP { ABS /* [ nat : @parameter pair int int ] */ } - /* [ nat : nat : @parameter pair int int ] */ ; - EDIV - /* [ option (pair nat nat) : @parameter pair int int ] */ ; - SWAP - /* [ @parameter pair int int : option (pair nat nat) ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int : option (pair nat nat) ] */ ; - UNPAIR - /* [ int : int : @parameter pair int int : option (pair nat nat) ] */ ; - ABS - /* [ nat : int : @parameter pair int int : option (pair nat nat) ] */ ; - EDIV - /* [ option (pair int nat) : @parameter pair int int : option (pair nat nat) ] */ ; - SWAP - /* [ @parameter pair int int : option (pair int nat) : option (pair nat nat) ] */ ; - DUP - /* [ @parameter pair int int : @parameter pair int int : option (pair int nat) - : option (pair nat nat) ] */ ; - UNPAIR - /* [ int : int : @parameter pair int int : option (pair int nat) - : option (pair nat nat) ] */ ; - DIP { ABS - /* [ nat : @parameter pair int int : option (pair int nat) - : option (pair nat nat) ] */ } - /* [ int : nat : @parameter pair int int : option (pair int nat) - : option (pair nat nat) ] */ ; - EDIV - /* [ option (pair int nat) : @parameter pair int int : option (pair int nat) - : option (pair nat nat) ] */ ; - SWAP - /* [ @parameter pair int int : option (pair int nat) : option (pair int nat) - : option (pair nat nat) ] */ ; - UNPAIR - /* [ int : int : option (pair int nat) : option (pair int nat) - : option (pair nat nat) ] */ ; - EDIV - /* [ option (pair int nat) : option (pair int nat) : option (pair int nat) - : option (pair nat nat) ] */ ; - PAPAPAIR ; - NIL operation - /* [ list operation - : pair (option (pair int nat)) - (option (pair int nat)) - (option (pair int nat)) - (option (pair nat nat)) ] */ ; - PAIR - /* [ pair (list operation) - (option (pair int nat)) - (option (pair int nat)) - (option (pair int nat)) - (option (pair nat nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv_mutez.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv_mutez.tz].out deleted file mode 100644 index 1807aa480aba..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv_mutez.tz].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ediv_mutez.tz] - -Well typed -Gas remaining: 1039987.261 units remaining -{ parameter (pair mutez (or mutez nat)) ; - storage (or (option (pair nat mutez)) (option (pair mutez mutez))) ; - code { CAR - /* [ @parameter pair mutez (or mutez nat) ] */ ; - UNPAIR - /* [ mutez : or mutez nat ] */ ; - SWAP - /* [ or mutez nat : mutez ] */ ; - IF_LEFT - { SWAP - /* [ mutez : mutez ] */ ; - EDIV - /* [ option (pair nat mutez) ] */ ; - LEFT (option (pair mutez mutez)) - /* [ or (option (pair nat mutez)) (option (pair mutez mutez)) ] */ } - { SWAP - /* [ mutez : nat ] */ ; - EDIV - /* [ option (pair mutez mutez) ] */ ; - RIGHT - (option (pair nat mutez)) - /* [ or (option (pair nat mutez)) (option (pair mutez mutez)) ] */ } ; - NIL operation - /* [ list operation : or (option (pair nat mutez)) (option (pair mutez mutez)) ] */ ; - PAIR - /* [ pair (list operation) (or (option (pair nat mutez)) (option (pair mutez mutez))) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--empty_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--empty_map.tz].out deleted file mode 100644 index fff011420a34..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--empty_map.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/empty_map.tz] - -Well typed -Gas remaining: 1039993.086 units remaining -{ storage (map string string) ; - parameter unit ; - code { DROP - /* [] */ ; - EMPTY_MAP string string - /* [ map string string ] */ ; - PUSH string "world" - /* [ string : map string string ] */ ; - SOME - /* [ option string : map string string ] */ ; - PUSH string "hello" - /* [ string : option string : map string string ] */ ; - UPDATE - /* [ map string string ] */ ; - NIL operation - /* [ list operation : map string string ] */ ; - PAIR - /* [ pair (list operation) (map string string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--exec_concat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--exec_concat.tz].out deleted file mode 100644 index 55377c71bf7b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--exec_concat.tz].out +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/exec_concat.tz] - -Well typed -Gas remaining: 1039991.097 units remaining -{ parameter string ; - storage string ; - code { CAR - /* [ @parameter string ] */ ; - LAMBDA - string - string - { PUSH string "_abc" - /* [ string : @arg string ] */ ; - NIL string - /* [ list string : string : @arg string ] */ ; - SWAP - /* [ string : list string : @arg string ] */ ; - CONS - /* [ list string : @arg string ] */ ; - SWAP - /* [ @arg string : list string ] */ ; - CONS - /* [ list string ] */ ; - CONCAT - /* [ string ] */ } - /* [ lambda string string : @parameter string ] */ ; - SWAP - /* [ @parameter string : lambda string string ] */ ; - EXEC - /* [ string ] */ ; - NIL operation - /* [ list operation : string ] */ ; - PAIR - /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--first.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--first.tz].out deleted file mode 100644 index b4dfc99f9944..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--first.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/first.tz] - -Well typed -Gas remaining: 1039994.458 units remaining -{ parameter (list nat) ; - storage nat ; - code { CAR - /* [ @parameter list nat ] */ ; - IF_CONS { DIP { DROP /* [] */ } /* [ @parameter.hd nat ] */ } { FAIL } ; - NIL operation - /* [ list operation : @parameter.hd nat ] */ ; - PAIR - /* [ pair (list operation) (nat @parameter.hd) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_big_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_big_map.tz].out deleted file mode 100644 index 06fa0a72d0d8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_big_map.tz].out +++ /dev/null @@ -1,15 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/get_and_update_big_map.tz] - -Well typed -Gas remaining: 1039993.030 units remaining -{ parameter string ; - storage (pair (option nat) (big_map string nat)) ; - code { UNPAPAIR ; - GET_AND_UPDATE - /* [ option nat : big_map string nat ] */ ; - PAIR - /* [ pair (option nat) (big_map string nat) ] */ ; - NIL operation - /* [ list operation : pair (option nat) (big_map string nat) ] */ ; - PAIR - /* [ pair (list operation) (option nat) (big_map string nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_map.tz].out deleted file mode 100644 index 18ebc6f3da3d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_map.tz].out +++ /dev/null @@ -1,15 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/get_and_update_map.tz] - -Well typed -Gas remaining: 1039993.090 units remaining -{ parameter string ; - storage (pair (option nat) (map string nat)) ; - code { UNPAPAIR ; - GET_AND_UPDATE - /* [ option nat : map string nat ] */ ; - PAIR - /* [ pair (option nat) (map string nat) ] */ ; - NIL operation - /* [ list operation : pair (option nat) (map string nat) ] */ ; - PAIR - /* [ pair (list operation) (option nat) (map string nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_big_map_value.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_big_map_value.tz].out deleted file mode 100644 index 8b646afc10e1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_big_map_value.tz].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/get_big_map_value.tz] - -Well typed -Gas remaining: 1039990.479 units remaining -{ parameter string ; - storage (pair (big_map string string) (option string)) ; - code { DUP - /* [ pair (string @parameter) (pair @storage (big_map string string) (option string)) - : pair (string @parameter) (pair @storage (big_map string string) (option string)) ] */ ; - CAR - /* [ @parameter string - : pair (string @parameter) (pair @storage (big_map string string) (option string)) ] */ ; - DIP { CDAR ; DUP /* [ big_map string string : big_map string string ] */ } - /* [ @parameter string : big_map string string : big_map string string ] */ ; - GET - /* [ option string : big_map string string ] */ ; - SWAP - /* [ big_map string string : option string ] */ ; - PAIR - /* [ pair (big_map string string) (option string) ] */ ; - NIL operation - /* [ list operation : pair (big_map string string) (option string) ] */ ; - PAIR - /* [ pair (list operation) (big_map string string) (option string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_map_value.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_map_value.tz].out deleted file mode 100644 index 564d2dea6bfe..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_map_value.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/get_map_value.tz] - -Well typed -Gas remaining: 1039991.007 units remaining -{ parameter string ; - storage (pair (option string) (map string string)) ; - code { DUP - /* [ pair (string @parameter) (pair @storage (option string) (map string string)) - : pair (string @parameter) (pair @storage (option string) (map string string)) ] */ ; - CAR - /* [ @parameter string - : pair (string @parameter) (pair @storage (option string) (map string string)) ] */ ; - DIP { CDDR ; DUP /* [ map string string : map string string ] */ } - /* [ @parameter string : map string string : map string string ] */ ; - GET - /* [ option string : map string string ] */ ; - PAIR - /* [ pair (option string) (map string string) ] */ ; - NIL operation - /* [ list operation : pair (option string) (map string string) ] */ ; - PAIR - /* [ pair (list operation) (option string) (map string string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_consistency_checker.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_consistency_checker.tz].out deleted file mode 100644 index 809b62ed64bc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_consistency_checker.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/hash_consistency_checker.tz] - -Well typed -Gas remaining: 1039995.929 units remaining -{ parameter (pair mutez (pair timestamp int)) ; - storage bytes ; - code { CAR - /* [ @parameter pair mutez timestamp int ] */ ; - PACK - /* [ @parameter.packed bytes ] */ ; - BLAKE2B - /* [ bytes ] */ ; - NIL operation - /* [ list operation : bytes ] */ ; - PAIR - /* [ pair (list operation) bytes ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_key.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_key.tz].out deleted file mode 100644 index 371873be8b07..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_key.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/hash_key.tz] - -Well typed -Gas remaining: 1039996.037 units remaining -{ parameter key ; - storage (option key_hash) ; - code { CAR - /* [ @parameter key ] */ ; - HASH_KEY - /* [ key_hash ] */ ; - SOME - /* [ option key_hash ] */ ; - NIL operation - /* [ list operation : option key_hash ] */ ; - PAIR - /* [ pair (list operation) (option key_hash) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_string.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_string.tz].out deleted file mode 100644 index b13c5a0579e4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_string.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/hash_string.tz] - -Well typed -Gas remaining: 1039996.340 units remaining -{ parameter string ; - storage bytes ; - code { CAR - /* [ @parameter string ] */ ; - PACK - /* [ @parameter.packed bytes ] */ ; - BLAKE2B - /* [ bytes ] */ ; - NIL operation - /* [ list operation : bytes ] */ ; - PAIR - /* [ pair (list operation) bytes ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if.tz].out deleted file mode 100644 index 50615c8c6c60..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if.tz].out +++ /dev/null @@ -1,15 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/if.tz] - -Well typed -Gas remaining: 1039994.330 units remaining -{ parameter bool ; - storage (option bool) ; - code { CAR - /* [ @parameter bool ] */ ; - IF { PUSH bool True /* [ bool ] */ } { PUSH bool False /* [ bool ] */ } ; - SOME - /* [ option bool ] */ ; - NIL operation - /* [ list operation : option bool ] */ ; - PAIR - /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if_some.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if_some.tz].out deleted file mode 100644 index 841b190cc7cd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if_some.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/if_some.tz] - -Well typed -Gas remaining: 1039995.219 units remaining -{ parameter (option string) ; - storage string ; - code { CAR - /* [ @parameter option string ] */ ; - IF_SOME { /* [ @parameter.some string ] */ } { PUSH string "" /* [ string ] */ } ; - NIL operation - /* [ list operation : string ] */ ; - PAIR - /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--int.tz].out deleted file mode 100644 index 84a40518a7d1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--int.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/int.tz] - -Well typed -Gas remaining: 1039996.037 units remaining -{ parameter nat ; - storage (option int) ; - code { CAR - /* [ @parameter nat ] */ ; - INT - /* [ int ] */ ; - SOME - /* [ option int ] */ ; - NIL operation - /* [ list operation : option int ] */ ; - PAIR - /* [ pair (list operation) (option int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--iter_fail.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--iter_fail.tz].out deleted file mode 100644 index 9007a6bb01ef..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--iter_fail.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/iter_fail.tz] - -Well typed -Gas remaining: 1039996.234 units remaining -{ parameter (set nat) ; - storage unit ; - code { UNPAIR - /* [ @parameter set nat : @storage unit ] */ ; - ITER { FAILWITH /* [] */ } - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--keccak.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--keccak.tz].out deleted file mode 100644 index d4fb835625e2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--keccak.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/keccak.tz] - -Well typed -Gas remaining: 1039996.037 units remaining -{ storage (option bytes) ; - parameter bytes ; - code { CAR - /* [ @parameter bytes ] */ ; - KECCAK - /* [ bytes ] */ ; - SOME - /* [ option bytes ] */ ; - NIL operation - /* [ list operation : option bytes ] */ ; - PAIR - /* [ pair (list operation) (option bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--left_right.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--left_right.tz].out deleted file mode 100644 index fa88c3b4a52b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--left_right.tz].out +++ /dev/null @@ -1,15 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/left_right.tz] - -Well typed -Gas remaining: 1039994.130 units remaining -{ parameter (or bool string) ; - storage (or string bool) ; - code { CAR - /* [ @parameter or bool string ] */ ; - IF_LEFT - { RIGHT string /* [ or string bool ] */ } - { LEFT bool /* [ or string bool ] */ } ; - NIL operation - /* [ list operation : or string bool ] */ ; - PAIR - /* [ pair (list operation) (or string bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--level.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--level.tz].out deleted file mode 100644 index 535a279f1f9a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--level.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/level.tz] - -Well typed -Gas remaining: 1039996.803 units remaining -{ parameter unit ; - storage nat ; - code { DROP - /* [] */ ; - LEVEL - /* [ @level nat ] */ ; - NIL operation - /* [ list operation : @level nat ] */ ; - PAIR - /* [ pair (list operation) (nat @level) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat.tz].out deleted file mode 100644 index 55523e259630..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_concat.tz] - -Well typed -Gas remaining: 1039995.574 units remaining -{ parameter (list string) ; - storage string ; - code { UNPAIR - /* [ @parameter list string : @storage string ] */ ; - SWAP - /* [ @storage string : @parameter list string ] */ ; - CONS - /* [ list string ] */ ; - CONCAT - /* [ string ] */ ; - NIL operation - /* [ list operation : string ] */ ; - PAIR - /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat_bytes.tz].out deleted file mode 100644 index a1dd6671f5cf..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat_bytes.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_concat_bytes.tz] - -Well typed -Gas remaining: 1039995.574 units remaining -{ parameter (list bytes) ; - storage bytes ; - code { UNPAIR - /* [ @parameter list bytes : @storage bytes ] */ ; - SWAP - /* [ @storage bytes : @parameter list bytes ] */ ; - CONS - /* [ list bytes ] */ ; - CONCAT - /* [ bytes ] */ ; - NIL operation - /* [ list operation : bytes ] */ ; - PAIR - /* [ pair (list operation) bytes ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id.tz].out deleted file mode 100644 index ecaaf06159ca..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_id.tz] - -Well typed -Gas remaining: 1039996.880 units remaining -{ parameter (list string) ; - storage (list string) ; - code { CAR - /* [ @parameter list string ] */ ; - NIL operation - /* [ list operation : @parameter list string ] */ ; - PAIR - /* [ pair (list operation) (list @parameter string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id_map.tz].out deleted file mode 100644 index 9ab3162055c2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id_map.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_id_map.tz] - -Well typed -Gas remaining: 1039996.174 units remaining -{ parameter (list string) ; - storage (list string) ; - code { CAR - /* [ @parameter list string ] */ ; - MAP { /* [ @parameter.elt string ] */ } - /* [ list string ] */ ; - NIL operation - /* [ list operation : list string ] */ ; - PAIR - /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_iter.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_iter.tz].out deleted file mode 100644 index 57a6f3132ef0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_iter.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_iter.tz] - -Well typed -Gas remaining: 1039994.793 units remaining -{ parameter (list int) ; - storage int ; - code { CAR - /* [ @parameter list int ] */ ; - PUSH int 1 - /* [ int : @parameter list int ] */ ; - SWAP - /* [ @parameter list int : int ] */ ; - ITER { MUL /* [ int ] */ } - /* [ int ] */ ; - NIL operation - /* [ list operation : int ] */ ; - PAIR - /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_map_block.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_map_block.tz].out deleted file mode 100644 index 9d6429884bde..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_map_block.tz].out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_map_block.tz] - -Well typed -Gas remaining: 1039990.664 units remaining -{ parameter (list int) ; - storage (list int) ; - code { CAR - /* [ @parameter list int ] */ ; - PUSH int 0 - /* [ int : @parameter list int ] */ ; - SWAP - /* [ @parameter list int : int ] */ ; - MAP { DIP { DUP /* [ int : int ] */ } - /* [ @parameter.elt int : int : int ] */ ; - ADD - /* [ int : int ] */ ; - DIP { PUSH int 1 /* [ int : int ] */ ; ADD /* [ int ] */ } - /* [ int : int ] */ } - /* [ list int : int ] */ ; - NIL operation - /* [ list operation : list int : int ] */ ; - PAIR - /* [ pair (list operation) (list int) : int ] */ ; - DIP { DROP /* [] */ } - /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_size.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_size.tz].out deleted file mode 100644 index 0faf56f04559..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_size.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_size.tz] - -Well typed -Gas remaining: 1039996.720 units remaining -{ parameter (list int) ; - storage nat ; - code { CAR - /* [ @parameter list int ] */ ; - SIZE - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_failwith.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_failwith.tz].out deleted file mode 100644 index 0e3c047edec0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_failwith.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/loop_failwith.tz] - -Well typed -Gas remaining: 1039996.317 units remaining -{ parameter bool ; - storage unit ; - code { UNPAIR - /* [ @parameter bool : @storage unit ] */ ; - LOOP { FAILWITH /* [] */ } - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left.tz].out deleted file mode 100644 index 3049b90d4135..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left.tz].out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/loop_left.tz] - -Well typed -Gas remaining: 1039983.876 units remaining -{ parameter (list string) ; - storage (list string) ; - code { CAR - /* [ @parameter list string ] */ ; - NIL string - /* [ list string : @parameter list string ] */ ; - SWAP - /* [ @parameter list string : list string ] */ ; - PAIR - /* [ pair (list @parameter string) (list string) ] */ ; - LEFT (list string) - /* [ or (pair (list @parameter string) (list string)) (list string) ] */ ; - LOOP_LEFT - { DUP - /* [ pair (list @parameter string) (list string) - : pair (list @parameter string) (list string) ] */ ; - CAR - /* [ @parameter list string : pair (list @parameter string) (list string) ] */ ; - DIP { CDR /* [ list string ] */ } - /* [ @parameter list string : list string ] */ ; - IF_CONS - { SWAP - /* [ @parameter.tl list string : @parameter.hd string : list string ] */ ; - DIP { CONS /* [ list string ] */ } - /* [ @parameter.tl list string : list string ] */ ; - PAIR - /* [ pair (list @parameter.tl string) (list string) ] */ ; - LEFT (list string) - /* [ or (pair (list @parameter.tl string) (list string)) (list string) ] */ } - { RIGHT - (pair (list string) (list string)) - /* [ or (pair (list string) (list string)) (list string) ] */ } } - /* [ list string ] */ ; - NIL operation - /* [ list operation : list string ] */ ; - PAIR - /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left_failwith.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left_failwith.tz].out deleted file mode 100644 index 295a8f528edd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left_failwith.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/loop_left_failwith.tz] - -Well typed -Gas remaining: 1039996.076 units remaining -{ parameter (or string nat) ; - storage nat ; - code { CAR - /* [ @parameter or string nat ] */ ; - LOOP_LEFT { FAILWITH /* [] */ } - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_car.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_car.tz].out deleted file mode 100644 index 8dd9764177d4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_car.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_car.tz] - -Well typed -Gas remaining: 1039990.103 units remaining -{ parameter bool ; - storage (pair (bool %b) (nat %n)) ; - code { DUP - /* [ pair (bool @parameter) (pair @storage (bool %b) (nat %n)) - : pair (bool @parameter) (pair @storage (bool %b) (nat %n)) ] */ ; - CAR - /* [ @parameter bool - : pair (bool @parameter) (pair @storage (bool %b) (nat %n)) ] */ ; - DIP { CDR /* [ @storage pair (bool %b) (nat %n) ] */ } - /* [ @parameter bool : @storage pair (bool %b) (nat %n) ] */ ; - SWAP - /* [ @storage pair (bool %b) (nat %n) : @parameter bool ] */ ; - MAP_CAR @new_storage %b { AND /* [ bool ] */ } ; - NIL operation - /* [ list operation : @storage pair (bool %b) (nat %n @storage.n) ] */ ; - PAIR - /* [ pair (list operation) (pair @storage (bool %b) (nat %n @storage.n)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_id.tz].out deleted file mode 100644 index 1d0e1b192f02..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_id.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_id.tz] - -Well typed -Gas remaining: 1039996.494 units remaining -{ parameter (map nat nat) ; - storage (map nat nat) ; - code { CAR - /* [ @parameter map nat nat ] */ ; - NIL operation - /* [ list operation : @parameter map nat nat ] */ ; - PAIR - /* [ pair (list operation) (map @parameter nat nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_iter.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_iter.tz].out deleted file mode 100644 index 87bb1981710e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_iter.tz].out +++ /dev/null @@ -1,47 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_iter.tz] - -Well typed -Gas remaining: 1039985.509 units remaining -{ parameter (map (int :k) (int :e)) ; - storage (pair (int :k) (int :e)) ; - code { CAR - /* [ @parameter map (int :k) (int :e) ] */ ; - PUSH @acc_e (int :e) 0 - /* [ @acc_e int :e : @parameter map (int :k) (int :e) ] */ ; - PUSH @acc_k - (int :k) - 0 - /* [ @acc_k int :k : @acc_e int :e : @parameter map (int :k) (int :e) ] */ ; - PAIR % %r - /* [ pair (int :k @acc_k) (int :e %r @acc_e) - : @parameter map (int :k) (int :e) ] */ ; - SWAP - /* [ @parameter map (int :k) (int :e) - : pair (int :k @acc_k) (int :e %r @acc_e) ] */ ; - ITER { DIP { DUP - /* [ pair (int :k @acc_k) (int :e %r @acc_e) - : pair (int :k @acc_k) (int :e %r @acc_e) ] */ ; - CAR - /* [ @acc_k int :k : pair (int :k @acc_k) (int :e %r @acc_e) ] */ ; - DIP { CDR /* [ @acc_e int :e ] */ } - /* [ @acc_k int :k : @acc_e int :e ] */ } - /* [ pair (int :k @key) (int :e @elt) : @acc_k int :k : @acc_e int :e ] */ ; - DUP - /* [ pair (int :k @key) (int :e @elt) : pair (int :k @key) (int :e @elt) - : @acc_k int :k : @acc_e int :e ] */ ; - DIP { CAR - /* [ @key int :k : @acc_k int :k : @acc_e int :e ] */ ; - ADD - /* [ int :k : @acc_e int :e ] */ } - /* [ pair (int :k @key) (int :e @elt) : int :k : @acc_e int :e ] */ ; - SWAP - /* [ int :k : pair (int :k @key) (int :e @elt) : @acc_e int :e ] */ ; - DIP { CDR /* [ @elt int :e : @acc_e int :e ] */ ; ADD /* [ int :e ] */ } - /* [ int :k : int :e ] */ ; - PAIR % %r - /* [ pair (int :k) (int :e %r) ] */ } - /* [ pair (int :k) (int :e %r) ] */ ; - NIL operation - /* [ list operation : pair (int :k) (int :e %r) ] */ ; - PAIR - /* [ pair (list operation) (int :k) (int :e %r) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map.tz].out deleted file mode 100644 index 9bd007ce33aa..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_map.tz] - -Well typed -Gas remaining: 1039992.454 units remaining -{ parameter nat ; - storage (map string nat) ; - code { UNPAIR - /* [ @parameter nat : @storage map string nat ] */ ; - SWAP - /* [ @storage map string nat : @parameter nat ] */ ; - MAP { CDR - /* [ @elt nat : @parameter nat ] */ ; - DIP { DUP /* [ @parameter nat : @parameter nat ] */ } - /* [ @elt nat : @parameter nat : @parameter nat ] */ ; - ADD - /* [ nat : @parameter nat ] */ } - /* [ map string nat : @parameter nat ] */ ; - DIP { DROP /* [] */ } - /* [ map string nat ] */ ; - NIL operation - /* [ list operation : map string nat ] */ ; - PAIR - /* [ pair (list operation) (map string nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map_sideeffect.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map_sideeffect.tz].out deleted file mode 100644 index 3dca6dd1eb7b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map_sideeffect.tz].out +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_map_sideeffect.tz] - -Well typed -Gas remaining: 1039986.934 units remaining -{ parameter nat ; - storage (pair (map string nat) nat) ; - code { UNPAIR - /* [ @parameter nat : @storage pair (map string nat) nat ] */ ; - SWAP - /* [ @storage pair (map string nat) nat : @parameter nat ] */ ; - CAR - /* [ map string nat : @parameter nat ] */ ; - DIP 2 - { PUSH @sum nat 0 /* [ @sum nat ] */ } - /* [ map string nat : @parameter nat : @sum nat ] */ ; - MAP { CDR - /* [ @elt nat : @parameter nat : @sum nat ] */ ; - DIP { DUP /* [ @parameter nat : @parameter nat : @sum nat ] */ } - /* [ @elt nat : @parameter nat : @parameter nat : @sum nat ] */ ; - ADD - /* [ nat : @parameter nat : @sum nat ] */ ; - DUP - /* [ nat : nat : @parameter nat : @sum nat ] */ ; - DUG 2 - /* [ nat : @parameter nat : nat : @sum nat ] */ ; - DIP 2 { ADD @sum /* [ @sum nat ] */ } - /* [ nat : @parameter nat : @sum nat ] */ } - /* [ map string nat : @parameter nat : @sum nat ] */ ; - DIP { DROP /* [ @sum nat ] */ } - /* [ map string nat : @sum nat ] */ ; - PAIR - /* [ pair (map string nat) (nat @sum) ] */ ; - NIL operation - /* [ list operation : pair (map string nat) (nat @sum) ] */ ; - PAIR - /* [ pair (list operation) (map string nat) (nat @sum) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_nat.tz].out deleted file mode 100644 index 26a2f64e12b1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_nat.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_mem_nat.tz] - -Well typed -Gas remaining: 1039991.954 units remaining -{ parameter nat ; - storage (pair (map nat nat) (option bool)) ; - code { UNPAIR - /* [ @parameter nat : @storage pair (map nat nat) (option bool) ] */ ; - DIP { CAR /* [ map nat nat ] */ ; DUP /* [ map nat nat : map nat nat ] */ } - /* [ @parameter nat : map nat nat : map nat nat ] */ ; - MEM - /* [ bool : map nat nat ] */ ; - SOME - /* [ option bool : map nat nat ] */ ; - SWAP - /* [ map nat nat : option bool ] */ ; - PAIR - /* [ pair (map nat nat) (option bool) ] */ ; - NIL operation - /* [ list operation : pair (map nat nat) (option bool) ] */ ; - PAIR - /* [ pair (list operation) (map nat nat) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_string.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_string.tz].out deleted file mode 100644 index b78bd9e9df66..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_string.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_mem_string.tz] - -Well typed -Gas remaining: 1039991.954 units remaining -{ parameter string ; - storage (pair (map string nat) (option bool)) ; - code { UNPAIR - /* [ @parameter string : @storage pair (map string nat) (option bool) ] */ ; - DIP { CAR /* [ map string nat ] */ ; DUP /* [ map string nat : map string nat ] */ } - /* [ @parameter string : map string nat : map string nat ] */ ; - MEM - /* [ bool : map string nat ] */ ; - SOME - /* [ option bool : map string nat ] */ ; - SWAP - /* [ map string nat : option bool ] */ ; - PAIR - /* [ pair (map string nat) (option bool) ] */ ; - NIL operation - /* [ list operation : pair (map string nat) (option bool) ] */ ; - PAIR - /* [ pair (list operation) (map string nat) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_size.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_size.tz].out deleted file mode 100644 index 123ff0b01fc0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_size.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_size.tz] - -Well typed -Gas remaining: 1039996.637 units remaining -{ parameter (map string nat) ; - storage nat ; - code { CAR - /* [ @parameter map string nat ] */ ; - SIZE - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--merge_comparable_pairs.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--merge_comparable_pairs.tz].out deleted file mode 100644 index d2a9726e0b9c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--merge_comparable_pairs.tz].out +++ /dev/null @@ -1,31 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/merge_comparable_pairs.tz] - -Well typed -Gas remaining: 1039990.293 units remaining -{ parameter (set (pair (nat %n) (pair %p (string %s) (int %i)))) ; - storage nat ; - code { UNPAIR - /* [ @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) - : @storage nat ] */ ; - SWAP - /* [ @storage nat - : @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ ; - PUSH nat - 3 - /* [ nat : @storage nat - : @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ ; - COMPARE - /* [ int : @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ ; - GT - /* [ bool : @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ ; - IF { /* [ @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ } - { DROP - /* [] */ ; - EMPTY_SET (pair nat (pair string int)) - /* [ set (pair nat string int) ] */ } ; - SIZE - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul.tz].out deleted file mode 100644 index f4e5b4249eaf..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul.tz].out +++ /dev/null @@ -1,82 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul.tz] - -Well typed -Gas remaining: 1039959.301 units remaining -{ parameter unit ; - storage unit ; - code { CAR - /* [ @parameter unit ] */ ; - DROP - /* [] */ ; - PUSH nat 7987 - /* [ nat ] */ ; - PUSH mutez 10 - /* [ mutez : nat ] */ ; - MUL - /* [ mutez ] */ ; - PUSH mutez 79870 - /* [ mutez : mutez ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH mutez 10 - /* [ mutez ] */ ; - PUSH nat 7987 - /* [ nat : mutez ] */ ; - MUL - /* [ mutez ] */ ; - PUSH mutez 79870 - /* [ mutez : mutez ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH int 10 - /* [ int ] */ ; - PUSH int -7987 - /* [ int : int ] */ ; - MUL - /* [ int ] */ ; - PUSH int -79870 - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH nat 10 - /* [ nat ] */ ; - PUSH int -7987 - /* [ int : nat ] */ ; - MUL - /* [ int ] */ ; - PUSH int -79870 - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH int -10 - /* [ int ] */ ; - PUSH nat 7987 - /* [ nat : int ] */ ; - MUL - /* [ int ] */ ; - PUSH int -79870 - /* [ int : int ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - PUSH nat 10 - /* [ nat ] */ ; - PUSH nat 7987 - /* [ nat : nat ] */ ; - MUL - /* [ nat ] */ ; - PUSH nat 79870 - /* [ nat : nat ] */ ; - COMPARE - /* [ int ] */ ; - ASSERT_EQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_fr.tz].out deleted file mode 100644 index efa1d14a992f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_fr.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul_bls12_381_fr.tz] - -Well typed -Gas remaining: 1039995.329 units remaining -{ parameter (pair bls12_381_fr bls12_381_fr) ; - storage (option bls12_381_fr) ; - code { CAR - /* [ @parameter pair bls12_381_fr bls12_381_fr ] */ ; - UNPAIR - /* [ bls12_381_fr : bls12_381_fr ] */ ; - MUL - /* [ bls12_381_fr ] */ ; - SOME - /* [ option bls12_381_fr ] */ ; - NIL operation - /* [ list operation : option bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g1.tz].out deleted file mode 100644 index 1c0d887c831f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g1.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul_bls12_381_g1.tz] - -Well typed -Gas remaining: 1039995.329 units remaining -{ parameter (pair bls12_381_g1 bls12_381_fr) ; - storage (option bls12_381_g1) ; - code { CAR - /* [ @parameter pair bls12_381_g1 bls12_381_fr ] */ ; - UNPAIR - /* [ bls12_381_g1 : bls12_381_fr ] */ ; - MUL - /* [ bls12_381_g1 ] */ ; - SOME - /* [ option bls12_381_g1 ] */ ; - NIL operation - /* [ list operation : option bls12_381_g1 ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_g1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g2.tz].out deleted file mode 100644 index d21874d9fb49..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g2.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul_bls12_381_g2.tz] - -Well typed -Gas remaining: 1039995.329 units remaining -{ parameter (pair bls12_381_g2 bls12_381_fr) ; - storage (option bls12_381_g2) ; - code { CAR - /* [ @parameter pair bls12_381_g2 bls12_381_fr ] */ ; - UNPAIR - /* [ bls12_381_g2 : bls12_381_fr ] */ ; - MUL - /* [ bls12_381_g2 ] */ ; - SOME - /* [ option bls12_381_g2 ] */ ; - NIL operation - /* [ list operation : option bls12_381_g2 ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_g2) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_overflow.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_overflow.tz].out deleted file mode 100644 index efa225b8c49e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_overflow.tz].out +++ /dev/null @@ -1,29 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul_overflow.tz] - -Well typed -Gas remaining: 1039991.544 units remaining -{ parameter (or unit unit) ; - storage unit ; - code { CAR - /* [ @parameter or unit unit ] */ ; - IF_LEFT - { PUSH nat 922337203685477580700 - /* [ nat : @parameter.left unit ] */ ; - PUSH mutez 10 - /* [ mutez : nat : @parameter.left unit ] */ ; - MUL - /* [ mutez : @parameter.left unit ] */ ; - DROP - /* [ @parameter.left unit ] */ } - { PUSH mutez 10 - /* [ mutez : @parameter.right unit ] */ ; - PUSH nat 922337203685477580700 - /* [ nat : mutez : @parameter.right unit ] */ ; - MUL - /* [ mutez : @parameter.right unit ] */ ; - DROP - /* [ @parameter.right unit ] */ } ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--munch.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--munch.tz].out deleted file mode 100644 index 8741bc184828..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--munch.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/munch.tz] - -Well typed -Gas remaining: 1039996.425 units remaining -{ parameter - (or (bytes %bytes) (or (lambda %lambda unit unit) (or (nat %nat) (list %list_nat nat)))) ; - storage unit ; - code { CDR - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mutez_to_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mutez_to_bls12_381_fr.tz].out deleted file mode 100644 index 612a9dd0787f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mutez_to_bls12_381_fr.tz].out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mutez_to_bls12_381_fr.tz] - -Well typed -Gas remaining: 1039991.653 units remaining -{ parameter mutez ; - storage bls12_381_fr ; - code { CAR - /* [ @parameter mutez ] */ ; - PUSH mutez 1 - /* [ mutez : @parameter mutez ] */ ; - SWAP - /* [ @parameter mutez : mutez ] */ ; - EDIV - /* [ option (pair nat mutez) ] */ ; - ASSERT_SOME ; - CAR - /* [ nat ] */ ; - PUSH bls12_381_fr 1 - /* [ bls12_381_fr : nat ] */ ; - MUL - /* [ bls12_381_fr ] */ ; - NIL operation - /* [ list operation : bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg.tz].out deleted file mode 100644 index 49c1843df0c2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/neg.tz] - -Well typed -Gas remaining: 1039995.361 units remaining -{ parameter (or int nat) ; - storage int ; - code { CAR - /* [ @parameter or int nat ] */ ; - IF_LEFT { NEG /* [ int ] */ } { NEG /* [ int ] */ } ; - NIL operation - /* [ list operation : int ] */ ; - PAIR - /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_fr.tz].out deleted file mode 100644 index 479b0be9e1e4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_fr.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/neg_bls12_381_fr.tz] - -Well typed -Gas remaining: 1039996.037 units remaining -{ parameter bls12_381_fr ; - storage (option bls12_381_fr) ; - code { CAR - /* [ @parameter bls12_381_fr ] */ ; - NEG - /* [ bls12_381_fr ] */ ; - SOME - /* [ option bls12_381_fr ] */ ; - NIL operation - /* [ list operation : option bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g1.tz].out deleted file mode 100644 index 95656a8287d7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g1.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/neg_bls12_381_g1.tz] - -Well typed -Gas remaining: 1039996.037 units remaining -{ parameter bls12_381_g1 ; - storage (option bls12_381_g1) ; - code { CAR - /* [ @parameter bls12_381_g1 ] */ ; - NEG - /* [ bls12_381_g1 ] */ ; - SOME - /* [ option bls12_381_g1 ] */ ; - NIL operation - /* [ list operation : option bls12_381_g1 ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_g1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g2.tz].out deleted file mode 100644 index 884f183eee52..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g2.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/neg_bls12_381_g2.tz] - -Well typed -Gas remaining: 1039996.037 units remaining -{ parameter bls12_381_g2 ; - storage (option bls12_381_g2) ; - code { CAR - /* [ @parameter bls12_381_g2 ] */ ; - NEG - /* [ bls12_381_g2 ] */ ; - SOME - /* [ option bls12_381_g2 ] */ ; - NIL operation - /* [ list operation : option bls12_381_g2 ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_g2) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--none.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--none.tz].out deleted file mode 100644 index bc51cfab6bba..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--none.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/none.tz] - -Well typed -Gas remaining: 1039996.417 units remaining -{ parameter unit ; - storage (option nat) ; - code { DROP - /* [] */ ; - NONE nat - /* [ option nat ] */ ; - NIL operation - /* [ list operation : option nat ] */ ; - PAIR - /* [ pair (list operation) (option nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--noop.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--noop.tz].out deleted file mode 100644 index 95d59989eba5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--noop.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/noop.tz] - -Well typed -Gas remaining: 1039997.267 units remaining -{ parameter unit ; - storage unit ; - code { CDR - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not.tz].out deleted file mode 100644 index ad6a9cc30a7b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/not.tz] - -Well typed -Gas remaining: 1039996.037 units remaining -{ parameter bool ; - storage (option bool) ; - code { CAR - /* [ @parameter bool ] */ ; - NOT - /* [ bool ] */ ; - SOME - /* [ option bool ] */ ; - NIL operation - /* [ list operation : option bool ] */ ; - PAIR - /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not_binary.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not_binary.tz].out deleted file mode 100644 index ba4ec737da7e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not_binary.tz].out +++ /dev/null @@ -1,15 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/not_binary.tz] - -Well typed -Gas remaining: 1039994.585 units remaining -{ parameter (or int nat) ; - storage (option int) ; - code { CAR - /* [ @parameter or int nat ] */ ; - IF_LEFT { NOT /* [ int ] */ } { NOT /* [ int ] */ } ; - SOME - /* [ option int ] */ ; - NIL operation - /* [ list operation : option int ] */ ; - PAIR - /* [ pair (list operation) (option int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or.tz].out deleted file mode 100644 index 9094a6ec1ea6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or.tz].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/or.tz] - -Well typed -Gas remaining: 1039993.625 units remaining -{ parameter (pair bool bool) ; - storage (option bool) ; - code { CAR - /* [ @parameter pair bool bool ] */ ; - DUP - /* [ @parameter pair bool bool : @parameter pair bool bool ] */ ; - CAR - /* [ bool : @parameter pair bool bool ] */ ; - SWAP - /* [ @parameter pair bool bool : bool ] */ ; - CDR - /* [ bool : bool ] */ ; - OR - /* [ bool ] */ ; - SOME - /* [ option bool ] */ ; - NIL operation - /* [ list operation : option bool ] */ ; - PAIR - /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or_binary.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or_binary.tz].out deleted file mode 100644 index b51af4351567..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or_binary.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/or_binary.tz] - -Well typed -Gas remaining: 1039995.329 units remaining -{ parameter (pair nat nat) ; - storage (option nat) ; - code { CAR - /* [ @parameter pair nat nat ] */ ; - UNPAIR - /* [ nat : nat ] */ ; - OR - /* [ nat ] */ ; - SOME - /* [ option nat ] */ ; - NIL operation - /* [ list operation : option nat ] */ ; - PAIR - /* [ pair (list operation) (option nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--originate_big_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--originate_big_map.tz].out deleted file mode 100644 index 1a20de4a05c4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--originate_big_map.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/originate_big_map.tz] - -Well typed -Gas remaining: 1039996.374 units remaining -{ parameter (big_map int int) ; - storage (big_map int int) ; - code { CAR - /* [ @parameter big_map int int ] */ ; - NIL operation - /* [ list operation : @parameter big_map int int ] */ ; - PAIR - /* [ pair (list operation) (big_map @parameter int int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack.tz].out deleted file mode 100644 index b58425d33ba3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack.tz].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/packunpack.tz] - -Well typed -Gas remaining: 1039986.390 units remaining -{ parameter (pair (pair (pair string (list int)) (set nat)) bytes) ; - storage unit ; - code { CAR - /* [ @parameter pair (pair (pair string (list int)) (set nat)) bytes ] */ ; - UNPAIR - /* [ pair (pair string (list int)) (set nat) : bytes ] */ ; - DIP { DUP /* [ bytes : bytes ] */ } - /* [ pair (pair string (list int)) (set nat) : bytes : bytes ] */ ; - PACK - /* [ @packed bytes : bytes : bytes ] */ ; - ASSERT_CMPEQ ; - UNPACK - (pair (pair string (list int)) (set nat)) - /* [ @unpacked option (pair (pair string (list int)) (set nat)) ] */ ; - ASSERT_SOME ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev.tz].out deleted file mode 100644 index 16142b62ce1c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev.tz].out +++ /dev/null @@ -1,171 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/packunpack_rev.tz] - -Well typed -Gas remaining: 1039885.614 units remaining -{ parameter (pair int nat string bytes mutez bool key_hash timestamp address) ; - storage unit ; - code { CAR - /* [ @parameter pair int nat string bytes mutez bool key_hash timestamp address ] */ ; - DUP - /* [ @parameter pair int nat string bytes mutez bool key_hash timestamp address - : @parameter pair int nat string bytes mutez bool key_hash timestamp address ] */ ; - CAR - /* [ int - : @parameter pair int nat string bytes mutez bool key_hash timestamp address ] */ ; - DIP { UNPAIR - /* [ int : pair nat string bytes mutez bool key_hash timestamp address ] */ } - /* [ int : int : pair nat string bytes mutez bool key_hash timestamp address ] */ ; - PACK - /* [ @packed bytes : int - : pair nat string bytes mutez bool key_hash timestamp address ] */ ; - UNPACK - int - /* [ @packed.unpacked option int : int - : pair nat string bytes mutez bool key_hash timestamp address ] */ ; - ASSERT_SOME ; - ASSERT_CMPEQ ; - DUP - /* [ pair nat string bytes mutez bool key_hash timestamp address - : pair nat string bytes mutez bool key_hash timestamp address ] */ ; - CAR - /* [ nat : pair nat string bytes mutez bool key_hash timestamp address ] */ ; - DIP { UNPAIR /* [ nat : pair string bytes mutez bool key_hash timestamp address ] */ } - /* [ nat : nat : pair string bytes mutez bool key_hash timestamp address ] */ ; - PACK - /* [ @packed bytes : nat - : pair string bytes mutez bool key_hash timestamp address ] */ ; - UNPACK - nat - /* [ @packed.unpacked option nat : nat - : pair string bytes mutez bool key_hash timestamp address ] */ ; - ASSERT_SOME ; - ASSERT_CMPEQ ; - DUP - /* [ pair string bytes mutez bool key_hash timestamp address - : pair string bytes mutez bool key_hash timestamp address ] */ ; - CAR - /* [ string : pair string bytes mutez bool key_hash timestamp address ] */ ; - DIP { UNPAIR /* [ string : pair bytes mutez bool key_hash timestamp address ] */ } - /* [ string : string : pair bytes mutez bool key_hash timestamp address ] */ ; - PACK - /* [ @packed bytes : string : pair bytes mutez bool key_hash timestamp address ] */ ; - UNPACK - string - /* [ @packed.unpacked option string : string - : pair bytes mutez bool key_hash timestamp address ] */ ; - ASSERT_SOME ; - ASSERT_CMPEQ ; - DUP - /* [ pair bytes mutez bool key_hash timestamp address - : pair bytes mutez bool key_hash timestamp address ] */ ; - CAR - /* [ bytes : pair bytes mutez bool key_hash timestamp address ] */ ; - DIP { UNPAIR /* [ bytes : pair mutez bool key_hash timestamp address ] */ } - /* [ bytes : bytes : pair mutez bool key_hash timestamp address ] */ ; - PACK - /* [ @packed bytes : bytes : pair mutez bool key_hash timestamp address ] */ ; - UNPACK - bytes - /* [ @packed.unpacked option bytes : bytes - : pair mutez bool key_hash timestamp address ] */ ; - ASSERT_SOME ; - ASSERT_CMPEQ ; - DUP - /* [ pair mutez bool key_hash timestamp address - : pair mutez bool key_hash timestamp address ] */ ; - CAR - /* [ mutez : pair mutez bool key_hash timestamp address ] */ ; - DIP { UNPAIR /* [ mutez : pair bool key_hash timestamp address ] */ } - /* [ mutez : mutez : pair bool key_hash timestamp address ] */ ; - PACK - /* [ @packed bytes : mutez : pair bool key_hash timestamp address ] */ ; - UNPACK - mutez - /* [ @packed.unpacked option mutez : mutez - : pair bool key_hash timestamp address ] */ ; - ASSERT_SOME ; - ASSERT_CMPEQ ; - DUP - /* [ pair bool key_hash timestamp address - : pair bool key_hash timestamp address ] */ ; - CAR - /* [ bool : pair bool key_hash timestamp address ] */ ; - DIP { UNPAIR /* [ bool : pair key_hash timestamp address ] */ } - /* [ bool : bool : pair key_hash timestamp address ] */ ; - PACK - /* [ @packed bytes : bool : pair key_hash timestamp address ] */ ; - UNPACK - bool - /* [ @packed.unpacked option bool : bool : pair key_hash timestamp address ] */ ; - ASSERT_SOME ; - ASSERT_CMPEQ ; - DUP - /* [ pair key_hash timestamp address : pair key_hash timestamp address ] */ ; - CAR - /* [ key_hash : pair key_hash timestamp address ] */ ; - DIP { UNPAIR /* [ key_hash : pair timestamp address ] */ } - /* [ key_hash : key_hash : pair timestamp address ] */ ; - PACK - /* [ @packed bytes : key_hash : pair timestamp address ] */ ; - UNPACK - key_hash - /* [ @packed.unpacked option key_hash : key_hash : pair timestamp address ] */ ; - ASSERT_SOME ; - ASSERT_CMPEQ ; - DUP - /* [ pair timestamp address : pair timestamp address ] */ ; - CAR - /* [ timestamp : pair timestamp address ] */ ; - DIP { UNPAIR /* [ timestamp : address ] */ } - /* [ timestamp : timestamp : address ] */ ; - PACK - /* [ @packed bytes : timestamp : address ] */ ; - UNPACK timestamp - /* [ @packed.unpacked option timestamp : timestamp : address ] */ ; - ASSERT_SOME ; - ASSERT_CMPEQ ; - DUP - /* [ address : address ] */ ; - PACK - /* [ @packed bytes : address ] */ ; - UNPACK address - /* [ @packed.unpacked option address : address ] */ ; - ASSERT_SOME ; - ASSERT_CMPEQ ; - PUSH int 0 - /* [ int ] */ ; - PACK - /* [ @packed bytes ] */ ; - UNPACK nat - /* [ @packed.unpacked option nat ] */ ; - ASSERT_SOME ; - DROP - /* [] */ ; - PUSH int -1 - /* [ int ] */ ; - PACK - /* [ @packed bytes ] */ ; - UNPACK nat - /* [ @packed.unpacked option nat ] */ ; - ASSERT_NONE ; - PUSH bytes 0x - /* [ bytes ] */ ; - UNPACK nat - /* [ @unpacked option nat ] */ ; - ASSERT_NONE ; - PUSH bytes 0x04 - /* [ bytes ] */ ; - UNPACK nat - /* [ @unpacked option nat ] */ ; - ASSERT_NONE ; - PUSH bytes 0x05 - /* [ bytes ] */ ; - UNPACK nat - /* [ @unpacked option nat ] */ ; - ASSERT_NONE ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev_cty.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev_cty.tz].out deleted file mode 100644 index b130f232e1f5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev_cty.tz].out +++ /dev/null @@ -1,614 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/packunpack_rev_cty.tz] - -Well typed -Gas remaining: 1039871.738 units remaining -{ parameter - (pair key - unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes)) ; - storage unit ; - code { CAR - /* [ @parameter pair key - unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DUP - /* [ @parameter pair key - unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) - : @parameter pair key - unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - CAR - /* [ key - : @parameter pair key - unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { UNPAIR - /* [ key - : pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ key : key - : pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - PACK - /* [ @packed bytes : key - : pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { PACK - /* [ @packed bytes - : pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - UNPACK - key - /* [ @packed.unpacked option key - : pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes - : pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes - : pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) - : pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - CAR - /* [ unit - : pair unit - signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { UNPAIR - /* [ unit - : pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ unit : unit - : pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - PACK - /* [ @packed bytes : unit - : pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { PACK - /* [ @packed bytes - : pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - UNPACK - unit - /* [ @packed.unpacked option unit - : pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes - : pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes - : pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) - : pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - CAR - /* [ signature - : pair signature - (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { UNPAIR - /* [ signature - : pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ signature : signature - : pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - PACK - /* [ @packed bytes : signature - : pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { PACK - /* [ @packed bytes - : pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - UNPACK - signature - /* [ @packed.unpacked option signature - : pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes - : pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes - : pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) - : pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - CAR - /* [ option signature - : pair (option signature) - (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { UNPAIR - /* [ option signature - : pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ option signature : option signature - : pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - PACK - /* [ @packed bytes : option signature - : pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { PACK - /* [ @packed bytes - : pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - UNPACK - (option signature) - /* [ @packed.unpacked option (option signature) - : pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes - : pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes - : pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) - : pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - CAR - /* [ list unit - : pair (list unit) - (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { UNPAIR - /* [ list unit - : pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ list unit : list unit - : pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - PACK - /* [ @packed bytes : list unit - : pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { PACK - /* [ @packed bytes - : pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - UNPACK - (list unit) - /* [ @packed.unpacked option (list unit) - : pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes - : pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes - : pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) - : pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - CAR - /* [ set bool - : pair (set bool) - (pair int int) - (or key_hash timestamp) - (map int string) - (lambda string bytes) ] */ ; - DIP { UNPAIR - /* [ set bool - : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ } - /* [ set bool : set bool - : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - PACK - /* [ @packed bytes : set bool - : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - DIP { PACK - /* [ @packed bytes - : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - UNPACK - (set bool) - /* [ @packed.unpacked option (set bool) - : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes - : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes - : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) - : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - CAR - /* [ pair int int - : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - DIP { UNPAIR - /* [ pair int int - : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ } - /* [ pair int int : pair int int - : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - PACK - /* [ @packed bytes : pair int int - : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - DIP { PACK - /* [ @packed bytes - : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - UNPACK - (pair int int) - /* [ @packed.unpacked option (pair int int) - : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes - : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes - : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ pair (or key_hash timestamp) (map int string) (lambda string bytes) - : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - CAR - /* [ or key_hash timestamp - : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; - DIP { UNPAIR - /* [ or key_hash timestamp : pair (map int string) (lambda string bytes) ] */ } - /* [ or key_hash timestamp : or key_hash timestamp - : pair (map int string) (lambda string bytes) ] */ ; - PACK - /* [ @packed bytes : or key_hash timestamp - : pair (map int string) (lambda string bytes) ] */ ; - DIP { PACK - /* [ @packed bytes : pair (map int string) (lambda string bytes) ] */ ; - UNPACK - (or key_hash timestamp) - /* [ @packed.unpacked option (or key_hash timestamp) - : pair (map int string) (lambda string bytes) ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes - : pair (map int string) (lambda string bytes) ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes - : pair (map int string) (lambda string bytes) ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ pair (map int string) (lambda string bytes) - : pair (map int string) (lambda string bytes) ] */ ; - CAR - /* [ map int string : pair (map int string) (lambda string bytes) ] */ ; - DIP { UNPAIR /* [ map int string : lambda string bytes ] */ } - /* [ map int string : map int string : lambda string bytes ] */ ; - PACK - /* [ @packed bytes : map int string : lambda string bytes ] */ ; - DIP { PACK - /* [ @packed bytes : lambda string bytes ] */ ; - UNPACK - (map int string) - /* [ @packed.unpacked option (map int string) : lambda string bytes ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes : lambda string bytes ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes : lambda string bytes ] */ ; - ASSERT_CMPEQ ; - DUP - /* [ lambda string bytes : lambda string bytes ] */ ; - PACK - /* [ @packed bytes : lambda string bytes ] */ ; - DIP { PACK - /* [ @packed bytes ] */ ; - UNPACK (lambda string bytes) - /* [ @packed.unpacked option (lambda string bytes) ] */ ; - ASSERT_SOME ; - PACK - /* [ @packed.unpacked.some.packed bytes ] */ } - /* [ @packed bytes : @packed.unpacked.some.packed bytes ] */ ; - ASSERT_CMPEQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pair_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pair_id.tz].out deleted file mode 100644 index 1ff3aed19b47..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pair_id.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/pair_id.tz] - -Well typed -Gas remaining: 1039995.649 units remaining -{ parameter (pair bool bool) ; - storage (option (pair bool bool)) ; - code { CAR - /* [ @parameter pair bool bool ] */ ; - SOME - /* [ option (pair bool bool) ] */ ; - NIL operation - /* [ list operation : option (pair bool bool) ] */ ; - PAIR - /* [ pair (list operation) (option (pair bool bool)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pairing_check.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pairing_check.tz].out deleted file mode 100644 index 5eab4455b17b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pairing_check.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/pairing_check.tz] - -Well typed -Gas remaining: 1039995.709 units remaining -{ parameter (list (pair bls12_381_g1 bls12_381_g2)) ; - storage (option bool) ; - code { CAR - /* [ @parameter list (pair bls12_381_g1 bls12_381_g2) ] */ ; - PAIRING_CHECK - /* [ bool ] */ ; - SOME - /* [ option bool ] */ ; - NIL operation - /* [ list operation : option bool ] */ ; - PAIR - /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec.tz].out deleted file mode 100644 index 631bbbc2f75b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/pexec.tz] - -Well typed -Gas remaining: 1039992.874 units remaining -{ parameter nat ; - storage nat ; - code { LAMBDA - (pair nat nat) - nat - { UNPAIR /* [ nat : nat ] */ ; ADD /* [ nat ] */ } - /* [ lambda (pair nat nat) nat : pair (nat @parameter) (nat @storage) ] */ ; - SWAP - /* [ pair (nat @parameter) (nat @storage) : lambda (pair nat nat) nat ] */ ; - UNPAIR - /* [ @parameter nat : @storage nat : lambda (pair nat nat) nat ] */ ; - DIP { APPLY /* [ lambda nat nat ] */ } - /* [ @parameter nat : lambda nat nat ] */ ; - EXEC - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec_2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec_2.tz].out deleted file mode 100644 index 19226a51409e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec_2.tz].out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/pexec_2.tz] - -Well typed -Gas remaining: 1039986.241 units remaining -{ parameter int ; - storage (list int) ; - code { UNPAIR @p @s - /* [ @p int : @s list int ] */ ; - LAMBDA - (pair int (pair int int)) - int - { UNPAIR - /* [ int : pair int int ] */ ; - DIP { UNPAIR /* [ int : int ] */ } - /* [ int : int : int ] */ ; - ADD - /* [ int : int ] */ ; - MUL - /* [ int ] */ } - /* [ lambda (pair int int int) int : @p int : @s list int ] */ ; - SWAP - /* [ @p int : lambda (pair int int int) int : @s list int ] */ ; - APPLY - /* [ lambda (pair int int) int : @s list int ] */ ; - PUSH int 3 - /* [ int : lambda (pair int int) int : @s list int ] */ ; - APPLY - /* [ lambda int int : @s list int ] */ ; - SWAP - /* [ @s list int : lambda int int ] */ ; - MAP { DIP { DUP /* [ lambda int int : lambda int int ] */ } - /* [ @s.elt int : lambda int int : lambda int int ] */ ; - EXEC - /* [ int : lambda int int ] */ } - /* [ list int : lambda int int ] */ ; - DIP { DROP /* [] */ } - /* [ list int ] */ ; - NIL operation - /* [ list operation : list int ] */ ; - PAIR - /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--proxy.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--proxy.tz].out deleted file mode 100644 index a7ab55a70096..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--proxy.tz].out +++ /dev/null @@ -1,20 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/proxy.tz] - -Well typed -Gas remaining: 1039994.321 units remaining -{ parameter (contract unit) ; - storage unit ; - code { UNPAIR - /* [ @parameter contract unit : @storage unit ] */ ; - AMOUNT - /* [ @amount mutez : @parameter contract unit : @storage unit ] */ ; - UNIT - /* [ unit : @amount mutez : @parameter contract unit : @storage unit ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage unit ] */ ; - DIP { NIL operation /* [ list operation : @storage unit ] */ } - /* [ operation : list operation : @storage unit ] */ ; - CONS - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ret_int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ret_int.tz].out deleted file mode 100644 index 9dc43d75028c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ret_int.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ret_int.tz] - -Well typed -Gas remaining: 1039995.756 units remaining -{ parameter unit ; - storage (option nat) ; - code { DROP - /* [] */ ; - PUSH nat 300 - /* [ nat ] */ ; - SOME - /* [ option nat ] */ ; - NIL operation - /* [ list operation : option nat ] */ ; - PAIR - /* [ pair (list operation) (option nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse.tz].out deleted file mode 100644 index 0b05a6045466..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/reverse.tz] - -Well typed -Gas remaining: 1039994.173 units remaining -{ parameter (list string) ; - storage (list string) ; - code { CAR - /* [ @parameter list string ] */ ; - NIL string - /* [ list string : @parameter list string ] */ ; - SWAP - /* [ @parameter list string : list string ] */ ; - ITER { CONS /* [ list string ] */ } - /* [ list string ] */ ; - NIL operation - /* [ list operation : list string ] */ ; - PAIR - /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse_loop.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse_loop.tz].out deleted file mode 100644 index 7fcff7506b7a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse_loop.tz].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/reverse_loop.tz] - -Well typed -Gas remaining: 1039987.683 units remaining -{ parameter (list string) ; - storage (list string) ; - code { CAR - /* [ @parameter list string ] */ ; - NIL string - /* [ list string : @parameter list string ] */ ; - SWAP - /* [ @parameter list string : list string ] */ ; - PUSH bool True - /* [ bool : @parameter list string : list string ] */ ; - LOOP { IF_CONS - { SWAP - /* [ @parameter.tl list string : @parameter.hd string : list string ] */ ; - DIP { CONS /* [ list string ] */ } - /* [ @parameter.tl list string : list string ] */ ; - PUSH bool True - /* [ bool : @parameter.tl list string : list string ] */ } - { NIL string - /* [ list string : list string ] */ ; - PUSH bool False - /* [ bool : list string : list string ] */ } } - /* [ @parameter list string : list string ] */ ; - DROP - /* [ list string ] */ ; - NIL operation - /* [ list operation : list string ] */ ; - PAIR - /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sapling_empty_state.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sapling_empty_state.tz].out deleted file mode 100644 index 5a9108c8fc51..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sapling_empty_state.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sapling_empty_state.tz] - -Well typed -Gas remaining: 1039996.757 units remaining -{ parameter unit ; - storage (sapling_state 8) ; - code { DROP - /* [] */ ; - SAPLING_EMPTY_STATE 8 - /* [ @sapling sapling_state 8 ] */ ; - NIL operation - /* [ list operation : @sapling sapling_state 8 ] */ ; - PAIR - /* [ pair (list operation) (sapling_state @sapling 8) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self.tz].out deleted file mode 100644 index 8e6e8055b917..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self.tz] - -Well typed -Gas remaining: 1039996.340 units remaining -{ parameter unit ; - storage address ; - code { DROP - /* [] */ ; - SELF - /* [ @self contract unit ] */ ; - ADDRESS - /* [ @self.address address ] */ ; - NIL operation - /* [ list operation : @self.address address ] */ ; - PAIR - /* [ pair (list operation) (address @self.address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address.tz].out deleted file mode 100644 index 240bd023957f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address.tz].out +++ /dev/null @@ -1,28 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_address.tz] - -Well typed -Gas remaining: 1039988.984 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - LAMBDA - unit - address - { DROP /* [] */ ; SELF_ADDRESS /* [ @self address ] */ } - /* [ lambda unit address ] */ ; - UNIT - /* [ unit : lambda unit address ] */ ; - EXEC - /* [ address ] */ ; - SELF - /* [ @self contract unit : address ] */ ; - ADDRESS - /* [ @self.address address : address ] */ ; - ASSERT_CMPEQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_fib_view.tz].out deleted file mode 100644 index 62bbea17f30a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_fib_view.tz].out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_address_after_fib_view.tz] - -Well typed -Gas remaining: 1039985.607 units remaining -{ parameter address ; - storage address ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 3 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "fib" nat - /* [ @parameter.contract option nat : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 1500 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - SELF_ADDRESS - /* [ @self address : operation ] */ ; - SWAP - /* [ operation : @self address ] */ ; - NIL operation - /* [ list operation : operation : @self address ] */ ; - SWAP - /* [ operation : list operation : @self address ] */ ; - CONS - /* [ list operation : @self address ] */ ; - PAIR - /* [ pair (list operation) (address @self) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_nonexistent_view.tz].out deleted file mode 100644 index 2a77224abd90..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_nonexistent_view.tz].out +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_address_after_nonexistent_view.tz] - -Well typed -Gas remaining: 1039986.090 units remaining -{ parameter address ; - storage address ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "id" string - /* [ @parameter.contract option string : @parameter address ] */ ; - ASSERT_NONE ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 1500 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - SELF_ADDRESS - /* [ @self address : operation ] */ ; - SWAP - /* [ operation : @self address ] */ ; - NIL operation - /* [ list operation : operation : @self address ] */ ; - SWAP - /* [ operation : list operation : @self address ] */ ; - CONS - /* [ list operation : @self address ] */ ; - PAIR - /* [ pair (list operation) (address @self) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_view.tz].out deleted file mode 100644 index 511c9288f6df..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_view.tz].out +++ /dev/null @@ -1,39 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_address_after_view.tz] - -Well typed -Gas remaining: 1039985.432 units remaining -{ parameter address ; - storage address ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "id" - (pair nat nat) - /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 1500 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - SELF_ADDRESS - /* [ @self address : operation ] */ ; - SWAP - /* [ operation : @self address ] */ ; - NIL operation - /* [ list operation : operation : @self address ] */ ; - SWAP - /* [ operation : list operation : @self address ] */ ; - CONS - /* [ list operation : @self address ] */ ; - PAIR - /* [ pair (list operation) (address @self) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_fib_view.tz].out deleted file mode 100644 index 0e5fd8f4453e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_fib_view.tz].out +++ /dev/null @@ -1,40 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_after_fib_view.tz] - -Well typed -Gas remaining: 1039985.135 units remaining -{ parameter address ; - storage address ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 3 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "fib" nat - /* [ @parameter.contract option nat : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 1500 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - SELF - /* [ @self contract address : operation ] */ ; - ADDRESS - /* [ @self.address address : operation ] */ ; - SWAP - /* [ operation : @self.address address ] */ ; - NIL operation - /* [ list operation : operation : @self.address address ] */ ; - SWAP - /* [ operation : list operation : @self.address address ] */ ; - CONS - /* [ list operation : @self.address address ] */ ; - PAIR - /* [ pair (list operation) (address @self.address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_nonexistent_view.tz].out deleted file mode 100644 index 4bbcdb2c6e04..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_nonexistent_view.tz].out +++ /dev/null @@ -1,39 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_after_nonexistent_view.tz] - -Well typed -Gas remaining: 1039985.527 units remaining -{ parameter address ; - storage address ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "nonexistent" - string - /* [ @parameter.contract option string : @parameter address ] */ ; - ASSERT_NONE ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 1500 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - SELF - /* [ @self contract address : operation ] */ ; - ADDRESS - /* [ @self.address address : operation ] */ ; - SWAP - /* [ operation : @self.address address ] */ ; - NIL operation - /* [ list operation : operation : @self.address address ] */ ; - SWAP - /* [ operation : list operation : @self.address address ] */ ; - CONS - /* [ list operation : @self.address address ] */ ; - PAIR - /* [ pair (list operation) (address @self.address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_view.tz].out deleted file mode 100644 index 384cdd964205..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_view.tz].out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_after_view.tz] - -Well typed -Gas remaining: 1039984.961 units remaining -{ parameter address ; - storage address ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "id" - (pair nat nat) - /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 1500 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - SELF - /* [ @self contract address : operation ] */ ; - ADDRESS - /* [ @self.address address : operation ] */ ; - SWAP - /* [ operation : @self.address address ] */ ; - NIL operation - /* [ list operation : operation : @self.address address ] */ ; - SWAP - /* [ operation : list operation : @self.address address ] */ ; - CONS - /* [ list operation : @self.address address ] */ ; - PAIR - /* [ pair (list operation) (address @self.address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_default_entrypoint.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_default_entrypoint.tz].out deleted file mode 100644 index db60bbec1e13..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_default_entrypoint.tz].out +++ /dev/null @@ -1,31 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_with_default_entrypoint.tz] - -Well typed -Gas remaining: 1039988.615 units remaining -{ parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %default) (string %C))) ; - storage unit ; - code { DROP - /* [] */ ; - SELF - /* [ @self contract unit ] */ ; - DROP - /* [] */ ; - SELF %A - /* [ @self contract nat ] */ ; - DROP - /* [] */ ; - SELF %default - /* [ @self contract unit ] */ ; - PACK - /* [ @self.packed bytes ] */ ; - SELF - /* [ @self contract unit : @self.packed bytes ] */ ; - PACK - /* [ @self.packed bytes : @self.packed bytes ] */ ; - ASSERT_CMPEQ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_entrypoint.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_entrypoint.tz].out deleted file mode 100644 index 69b7e50ba2d6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_entrypoint.tz].out +++ /dev/null @@ -1,70 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_with_entrypoint.tz] - -Well typed -Gas remaining: 1039967.216 units remaining -{ parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ; - storage unit ; - code { DROP - /* [] */ ; - SELF %A - /* [ @self contract nat ] */ ; - PACK @Apacked - /* [ @Apacked bytes ] */ ; - SELF %default - /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) - : @Apacked bytes ] */ ; - PACK @defpacked - /* [ @defpacked bytes : @Apacked bytes ] */ ; - DUP - /* [ @defpacked bytes : @defpacked bytes : @Apacked bytes ] */ ; - DIP { SWAP /* [ @Apacked bytes : @defpacked bytes ] */ } - /* [ @defpacked bytes : @Apacked bytes : @defpacked bytes ] */ ; - ASSERT_CMPNEQ ; - SELF - /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) - : @defpacked bytes ] */ ; - PACK @selfpacked - /* [ @selfpacked bytes : @defpacked bytes ] */ ; - ASSERT_CMPEQ ; - SELF %A - /* [ @self contract nat ] */ ; - CAST (contract nat) - /* [ @self contract nat ] */ ; - DROP - /* [] */ ; - SELF %B - /* [ @self contract bool ] */ ; - CAST (contract bool) - /* [ @self contract bool ] */ ; - DROP - /* [] */ ; - SELF %maybe_C - /* [ @self contract (or (unit %Z) (string %C)) ] */ ; - CAST (contract (or unit string)) - /* [ @self contract (or unit string) ] */ ; - DROP - /* [] */ ; - SELF %Z - /* [ @self contract unit ] */ ; - CAST (contract unit) - /* [ @self contract unit ] */ ; - DROP - /* [] */ ; - SELF - /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ] */ ; - CAST (contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))) - /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ] */ ; - DROP - /* [] */ ; - SELF %default - /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ] */ ; - CAST (contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))) - /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ] */ ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender.tz].out deleted file mode 100644 index 55e1a9bc53cb..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sender.tz] - -Well typed -Gas remaining: 1039996.803 units remaining -{ parameter unit ; - storage address ; - code { DROP - /* [] */ ; - SENDER - /* [ @sender address ] */ ; - NIL operation - /* [ list operation : @sender address ] */ ; - PAIR - /* [ pair (list operation) (address @sender) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_fib_view.tz].out deleted file mode 100644 index 208c6a7be694..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_fib_view.tz].out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sender_after_fib_view.tz] - -Well typed -Gas remaining: 1039985.607 units remaining -{ parameter address ; - storage address ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 3 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "fib" nat - /* [ @parameter.contract option nat : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 1500 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - SENDER - /* [ @sender address : operation ] */ ; - SWAP - /* [ operation : @sender address ] */ ; - NIL operation - /* [ list operation : operation : @sender address ] */ ; - SWAP - /* [ operation : list operation : @sender address ] */ ; - CONS - /* [ list operation : @sender address ] */ ; - PAIR - /* [ pair (list operation) (address @sender) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_nonexistent_view.tz].out deleted file mode 100644 index 53e769b37b02..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_nonexistent_view.tz].out +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sender_after_nonexistent_view.tz] - -Well typed -Gas remaining: 1039986.090 units remaining -{ parameter address ; - storage address ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "id" string - /* [ @parameter.contract option string : @parameter address ] */ ; - ASSERT_NONE ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 1500 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - SENDER - /* [ @sender address : operation ] */ ; - SWAP - /* [ operation : @sender address ] */ ; - NIL operation - /* [ list operation : operation : @sender address ] */ ; - SWAP - /* [ operation : list operation : @sender address ] */ ; - CONS - /* [ list operation : @sender address ] */ ; - PAIR - /* [ pair (list operation) (address @sender) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_view.tz].out deleted file mode 100644 index 0911445c0390..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_view.tz].out +++ /dev/null @@ -1,39 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sender_after_view.tz] - -Well typed -Gas remaining: 1039985.432 units remaining -{ parameter address ; - storage address ; - code { CAR - /* [ @parameter address ] */ ; - DUP - /* [ @parameter address : @parameter address ] */ ; - PUSH nat 0 - /* [ nat : @parameter address : @parameter address ] */ ; - VIEW "id" - (pair nat nat) - /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; - ASSERT_SOME ; - DROP - /* [ @parameter address ] */ ; - CONTRACT nat - /* [ @parameter.contract option (contract nat) ] */ ; - ASSERT_SOME ; - PUSH mutez 1500 - /* [ mutez : @parameter.contract.some contract nat ] */ ; - PUSH nat 0 - /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - SENDER - /* [ @sender address : operation ] */ ; - SWAP - /* [ operation : @sender address ] */ ; - NIL operation - /* [ list operation : operation : @sender address ] */ ; - SWAP - /* [ operation : list operation : @sender address ] */ ; - CONS - /* [ list operation : @sender address ] */ ; - PAIR - /* [ pair (list operation) (address @sender) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_car.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_car.tz].out deleted file mode 100644 index 965817881bc2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_car.tz].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_car.tz] - -Well typed -Gas remaining: 1039991.314 units remaining -{ parameter string ; - storage (pair (string %s) (nat %n)) ; - code { DUP - /* [ pair (string @parameter) (pair @storage (string %s) (nat %n)) - : pair (string @parameter) (pair @storage (string %s) (nat %n)) ] */ ; - CDR - /* [ @storage pair (string %s) (nat %n) - : pair (string @parameter) (pair @storage (string %s) (nat %n)) ] */ ; - DIP { CAR /* [ @parameter string ] */ } - /* [ @storage pair (string %s) (nat %n) : @parameter string ] */ ; - SET_CAR %s ; - NIL operation - /* [ list operation : @storage pair (string %s @parameter) (nat %n @storage.n) ] */ ; - PAIR - /* [ pair (list operation) (pair @storage (string %s @parameter) (nat %n @storage.n)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_cdr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_cdr.tz].out deleted file mode 100644 index 0a9af5151dde..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_cdr.tz].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_cdr.tz] - -Well typed -Gas remaining: 1039991.782 units remaining -{ parameter nat ; - storage (pair (string %s) (nat %n)) ; - code { DUP - /* [ pair (nat @parameter) (pair @storage (string %s) (nat %n)) - : pair (nat @parameter) (pair @storage (string %s) (nat %n)) ] */ ; - CDR - /* [ @storage pair (string %s) (nat %n) - : pair (nat @parameter) (pair @storage (string %s) (nat %n)) ] */ ; - DIP { CAR /* [ @parameter nat ] */ } - /* [ @storage pair (string %s) (nat %n) : @parameter nat ] */ ; - SET_CDR %n ; - NIL operation - /* [ list operation : @storage pair (string %s @storage.s) (nat %n @parameter) ] */ ; - PAIR - /* [ pair (list operation) (pair @storage (string %s @storage.s) (nat %n @parameter)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_delegate.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_delegate.tz].out deleted file mode 100644 index abcb3bda4652..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_delegate.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_delegate.tz] - -Well typed -Gas remaining: 1039995.476 units remaining -{ parameter (option key_hash) ; - storage unit ; - code { UNPAIR - /* [ @parameter option key_hash : @storage unit ] */ ; - SET_DELEGATE - /* [ operation : @storage unit ] */ ; - DIP { NIL operation /* [ list operation : @storage unit ] */ } - /* [ operation : list operation : @storage unit ] */ ; - CONS - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_id.tz].out deleted file mode 100644 index b640e740523c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_id.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_id.tz] - -Well typed -Gas remaining: 1039996.880 units remaining -{ parameter (set string) ; - storage (set string) ; - code { CAR - /* [ @parameter set string ] */ ; - NIL operation - /* [ list operation : @parameter set string ] */ ; - PAIR - /* [ pair (list operation) (set @parameter string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_iter.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_iter.tz].out deleted file mode 100644 index dc215f4d2401..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_iter.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_iter.tz] - -Well typed -Gas remaining: 1039994.793 units remaining -{ parameter (set int) ; - storage int ; - code { CAR - /* [ @parameter set int ] */ ; - PUSH int 0 - /* [ int : @parameter set int ] */ ; - SWAP - /* [ @parameter set int : int ] */ ; - ITER { ADD /* [ int ] */ } - /* [ int ] */ ; - NIL operation - /* [ list operation : int ] */ ; - PAIR - /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_member.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_member.tz].out deleted file mode 100644 index 3c08a1664bad..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_member.tz].out +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_member.tz] - -Well typed -Gas remaining: 1039988.400 units remaining -{ parameter string ; - storage (pair (set string) (option bool)) ; - code { DUP - /* [ pair (string @parameter) (pair @storage (set string) (option bool)) - : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; - DUP - /* [ pair (string @parameter) (pair @storage (set string) (option bool)) - : pair (string @parameter) (pair @storage (set string) (option bool)) - : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; - CAR - /* [ @parameter string - : pair (string @parameter) (pair @storage (set string) (option bool)) - : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; - DIP { CDAR } - /* [ @parameter string : set string - : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; - MEM - /* [ bool - : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; - SOME - /* [ option bool - : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; - DIP { CDAR } - /* [ option bool : set string ] */ ; - SWAP - /* [ set string : option bool ] */ ; - PAIR - /* [ pair (set string) (option bool) ] */ ; - NIL operation - /* [ list operation : pair (set string) (option bool) ] */ ; - PAIR - /* [ pair (list operation) (set string) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_size.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_size.tz].out deleted file mode 100644 index 1bfdb40fee41..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_size.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_size.tz] - -Well typed -Gas remaining: 1039996.720 units remaining -{ parameter (set int) ; - storage nat ; - code { CAR - /* [ @parameter set int ] */ ; - SIZE - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sets.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sets.tz].out deleted file mode 100644 index 98e24100ac5f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sets.tz].out +++ /dev/null @@ -1,68 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sets.tz] - -Well typed -Gas remaining: 1038009.188 units remaining -{ parameter unit ; - storage unit ; - code { DROP - /* [] */ ; - PUSH (set nat) { 0 ; 1 ; 3 } - /* [ set nat ] */ ; - DROP - /* [] */ ; - PUSH (set int) { -1 ; 0 ; 3 } - /* [ set int ] */ ; - DROP - /* [] */ ; - PUSH (set mutez) { 1 ; 4 ; 5 ; 10 ; 1923 } - /* [ set mutez ] */ ; - DROP - /* [] */ ; - PUSH (set timestamp) - { -1 ; 0 ; "2017-09-16T08:38:04Z" ; "2019-09-16T08:38:05Z" } - /* [ set timestamp ] */ ; - DROP - /* [] */ ; - PUSH (set bool) {} - /* [ set bool ] */ ; - DROP - /* [] */ ; - PUSH (set bool) { True } - /* [ set bool ] */ ; - DROP - /* [] */ ; - PUSH (set bool) { False } - /* [ set bool ] */ ; - DROP - /* [] */ ; - PUSH (set bool) { False ; True } - /* [ set bool ] */ ; - DROP - /* [] */ ; - PUSH (set string) { "" ; "A" ; "B" ; "a" ; "aa" ; "b" } - /* [ set string ] */ ; - DROP - /* [] */ ; - PUSH (set bytes) { 0x ; 0x01 ; 0x02 ; 0xaabbcc } - /* [ set bytes ] */ ; - DROP - /* [] */ ; - PUSH (set key_hash) - { "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ; - "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" } - /* [ set key_hash ] */ ; - DROP - /* [] */ ; - PUSH (set address) - { "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ; - "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" ; - "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9" } - /* [ set address ] */ ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sha3.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sha3.tz].out deleted file mode 100644 index ab45db0b9640..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sha3.tz].out +++ /dev/null @@ -1,16 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sha3.tz] - -Well typed -Gas remaining: 1039996.037 units remaining -{ storage (option bytes) ; - parameter bytes ; - code { CAR - /* [ @parameter bytes ] */ ; - SHA3 - /* [ bytes ] */ ; - SOME - /* [ option bytes ] */ ; - NIL operation - /* [ list operation : option bytes ] */ ; - PAIR - /* [ pair (list operation) (option bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--shifts.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--shifts.tz].out deleted file mode 100644 index 64558ac80847..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--shifts.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/shifts.tz] - -Well typed -Gas remaining: 1039993.299 units remaining -{ parameter (or (pair nat nat) (pair nat nat)) ; - storage (option nat) ; - code { CAR - /* [ @parameter or (pair nat nat) (pair nat nat) ] */ ; - IF_LEFT - { UNPAIR /* [ nat : nat ] */ ; LSL /* [ nat ] */ } - { UNPAIR /* [ nat : nat ] */ ; LSR /* [ nat ] */ } ; - SOME - /* [ option nat ] */ ; - NIL operation - /* [ list operation : option nat ] */ ; - PAIR - /* [ pair (list operation) (option nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice.tz].out deleted file mode 100644 index 61c2ac15bf94..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/slice.tz] - -Well typed -Gas remaining: 1039992.627 units remaining -{ parameter (pair nat nat) ; - storage (option string) ; - code { UNPAIR - /* [ @parameter pair nat nat : @storage option string ] */ ; - SWAP - /* [ @storage option string : @parameter pair nat nat ] */ ; - IF_SOME - { SWAP - /* [ @parameter pair nat nat : @storage.some string ] */ ; - UNPAIR - /* [ nat : nat : @storage.some string ] */ ; - SLICE - /* [ @storage.some.slice option string ] */ } - { DROP /* [] */ ; NONE string /* [ option string ] */ } ; - NIL operation - /* [ list operation : option string ] */ ; - PAIR - /* [ pair (list operation) (option string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice_bytes.tz].out deleted file mode 100644 index 2fc811f5c1ae..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice_bytes.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/slice_bytes.tz] - -Well typed -Gas remaining: 1039992.627 units remaining -{ parameter (pair nat nat) ; - storage (option bytes) ; - code { UNPAIR - /* [ @parameter pair nat nat : @storage option bytes ] */ ; - SWAP - /* [ @storage option bytes : @parameter pair nat nat ] */ ; - IF_SOME - { SWAP - /* [ @parameter pair nat nat : @storage.some bytes ] */ ; - UNPAIR - /* [ nat : nat : @storage.some bytes ] */ ; - SLICE - /* [ @storage.some.slice option bytes ] */ } - { DROP /* [] */ ; NONE bytes /* [ option bytes ] */ } ; - NIL operation - /* [ list operation : option bytes ] */ ; - PAIR - /* [ pair (list operation) (option bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slices.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slices.tz].out deleted file mode 100644 index ef74797ca296..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slices.tz].out +++ /dev/null @@ -1,156 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/slices.tz] - -Well typed -Gas remaining: 1039935.257 units remaining -{ parameter (pair bytes signature) ; - storage key ; - code { DUP - /* [ pair (pair @parameter bytes signature) (key @storage) - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - CAAR ; - DUP - /* [ bytes : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SIZE - /* [ nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - PUSH nat - 128 - /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SWAP - /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SUB - /* [ int : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - ISNAT - /* [ option nat : bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - IF_SOME - { /* [ @some nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ } - { FAIL } ; - PUSH nat - 128 - /* [ nat : @some nat : bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SLICE @payload - /* [ @payload option bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - ASSERT_SOME ; - DUP - /* [ @payload.some bytes : @payload.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - DIP { DIP { DUP - /* [ pair (pair @parameter bytes signature) (key @storage) - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - CAAR ; - PUSH nat - 32 - /* [ nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - PUSH nat - 0 - /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SLICE - /* [ @slice option bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - ASSERT_SOME } - /* [ @payload.some bytes : @slice.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SHA256 - /* [ bytes : @slice.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - ASSERT_CMPEQ } - /* [ @payload.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - DUP - /* [ @payload.some bytes : @payload.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - DIP { DIP { DUP - /* [ pair (pair @parameter bytes signature) (key @storage) - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - CAAR ; - PUSH nat - 32 - /* [ nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - PUSH nat - 32 - /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SLICE - /* [ @slice option bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - ASSERT_SOME } - /* [ @payload.some bytes : @slice.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - BLAKE2B - /* [ bytes : @slice.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - ASSERT_CMPEQ } - /* [ @payload.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - DUP - /* [ @payload.some bytes : @payload.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - DIP { DIP { DUP - /* [ pair (pair @parameter bytes signature) (key @storage) - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - CAAR ; - PUSH nat - 64 - /* [ nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - PUSH nat - 64 - /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SLICE - /* [ @slice option bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - ASSERT_SOME } - /* [ @payload.some bytes : @slice.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SHA512 - /* [ bytes : @slice.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - ASSERT_CMPEQ } - /* [ @payload.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - DIP { DUP - /* [ pair (pair @parameter bytes signature) (key @storage) - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - CDR - /* [ @storage key : pair (pair @parameter bytes signature) (key @storage) ] */ ; - DIP { DUP - /* [ pair (pair @parameter bytes signature) (key @storage) - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - CADR } - /* [ @storage key : signature - : pair (pair @parameter bytes signature) (key @storage) ] */ } - /* [ @payload.some bytes : @storage key : signature - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - SWAP - /* [ @storage key : @payload.some bytes : signature - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - DIP { SWAP - /* [ signature : @payload.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ } - /* [ @storage key : signature : @payload.some bytes - : pair (pair @parameter bytes signature) (key @storage) ] */ ; - CHECK_SIGNATURE - /* [ bool : pair (pair @parameter bytes signature) (key @storage) ] */ ; - ASSERT ; - CDR - /* [ @storage key ] */ ; - DUP - /* [ @storage key : @storage key ] */ ; - HASH_KEY - /* [ key_hash : @storage key ] */ ; - IMPLICIT_ACCOUNT - /* [ contract unit : @storage key ] */ ; - BALANCE - /* [ @balance mutez : contract unit : @storage key ] */ ; - UNIT - /* [ unit : @balance mutez : contract unit : @storage key ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage key ] */ ; - NIL operation - /* [ list operation : operation : @storage key ] */ ; - SWAP - /* [ operation : list operation : @storage key ] */ ; - CONS - /* [ list operation : @storage key ] */ ; - PAIR - /* [ pair (list operation) (key @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--source.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--source.tz].out deleted file mode 100644 index f27b61fb6234..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--source.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/source.tz] - -Well typed -Gas remaining: 1039996.803 units remaining -{ parameter unit ; - storage address ; - code { DROP - /* [] */ ; - SOURCE - /* [ @source address ] */ ; - NIL operation - /* [ list operation : @source address ] */ ; - PAIR - /* [ pair (list operation) (address @source) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_bytes.tz].out deleted file mode 100644 index ee3a53431a1a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_bytes.tz].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/split_bytes.tz] - -Well typed -Gas remaining: 1039970.057 units remaining -{ parameter bytes ; - storage (list bytes) ; - code { UNPAIR - /* [ @parameter bytes : @storage list bytes ] */ ; - DIP { NIL bytes - /* [ list bytes : @storage list bytes ] */ ; - SWAP - /* [ @storage list bytes : list bytes ] */ ; - ITER { CONS /* [ list bytes ] */ } - /* [ list bytes ] */ } - /* [ @parameter bytes : list bytes ] */ ; - DUP - /* [ @parameter bytes : @parameter bytes : list bytes ] */ ; - SIZE - /* [ nat : @parameter bytes : list bytes ] */ ; - PUSH nat 0 - /* [ nat : nat : @parameter bytes : list bytes ] */ ; - CMPNEQ ; - DIP { PUSH @index nat 0 /* [ @index nat : @parameter bytes : list bytes ] */ } - /* [ bool : @index nat : @parameter bytes : list bytes ] */ ; - LOOP { PAIR - /* [ pair (nat @index) (bytes @parameter) : list bytes ] */ ; - DUP - /* [ pair (nat @index) (bytes @parameter) : pair (nat @index) (bytes @parameter) - : list bytes ] */ ; - DIP { UNPAIR - /* [ @index nat : @parameter bytes : list bytes ] */ ; - DIP { PUSH nat 1 /* [ nat : @parameter bytes : list bytes ] */ } - /* [ @index nat : nat : @parameter bytes : list bytes ] */ ; - SLICE - /* [ @parameter.slice option bytes : list bytes ] */ ; - ASSERT_SOME ; - CONS @storage - /* [ @storage list bytes ] */ } - /* [ pair (nat @index) (bytes @parameter) : @storage list bytes ] */ ; - UNPAIR - /* [ @index nat : @parameter bytes : @storage list bytes ] */ ; - PUSH nat 1 - /* [ nat : @index nat : @parameter bytes : @storage list bytes ] */ ; - ADD @index - /* [ @index nat : @parameter bytes : @storage list bytes ] */ ; - DUP - /* [ @index nat : @index nat : @parameter bytes : @storage list bytes ] */ ; - DIP { DIP { DUP /* [ @parameter bytes : @parameter bytes : @storage list bytes ] */ } - /* [ @index nat : @parameter bytes : @parameter bytes : @storage list bytes ] */ ; - SWAP - /* [ @parameter bytes : @index nat : @parameter bytes : @storage list bytes ] */ ; - SIZE - /* [ nat : @index nat : @parameter bytes : @storage list bytes ] */ ; - CMPNEQ } - /* [ @index nat : bool : @parameter bytes : @storage list bytes ] */ ; - SWAP - /* [ bool : @index nat : @parameter bytes : @storage list bytes ] */ } - /* [ @index nat : @parameter bytes : list bytes ] */ ; - DROP - /* [ @parameter bytes : list bytes ] */ ; - DROP - /* [ list bytes ] */ ; - NIL bytes - /* [ list bytes : list bytes ] */ ; - SWAP - /* [ list bytes : list bytes ] */ ; - ITER { CONS /* [ list bytes ] */ } - /* [ list bytes ] */ ; - NIL operation - /* [ list operation : list bytes ] */ ; - PAIR - /* [ pair (list operation) (list bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_string.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_string.tz].out deleted file mode 100644 index e0b7d1f3228c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_string.tz].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/split_string.tz] - -Well typed -Gas remaining: 1039970.057 units remaining -{ parameter string ; - storage (list string) ; - code { UNPAIR - /* [ @parameter string : @storage list string ] */ ; - DIP { NIL string - /* [ list string : @storage list string ] */ ; - SWAP - /* [ @storage list string : list string ] */ ; - ITER { CONS /* [ list string ] */ } - /* [ list string ] */ } - /* [ @parameter string : list string ] */ ; - DUP - /* [ @parameter string : @parameter string : list string ] */ ; - SIZE - /* [ nat : @parameter string : list string ] */ ; - PUSH nat 0 - /* [ nat : nat : @parameter string : list string ] */ ; - CMPNEQ ; - DIP { PUSH @index nat 0 /* [ @index nat : @parameter string : list string ] */ } - /* [ bool : @index nat : @parameter string : list string ] */ ; - LOOP { PAIR - /* [ pair (nat @index) (string @parameter) : list string ] */ ; - DUP - /* [ pair (nat @index) (string @parameter) - : pair (nat @index) (string @parameter) : list string ] */ ; - DIP { UNPAIR - /* [ @index nat : @parameter string : list string ] */ ; - DIP { PUSH nat 1 /* [ nat : @parameter string : list string ] */ } - /* [ @index nat : nat : @parameter string : list string ] */ ; - SLICE - /* [ @parameter.slice option string : list string ] */ ; - ASSERT_SOME ; - CONS @storage - /* [ @storage list string ] */ } - /* [ pair (nat @index) (string @parameter) : @storage list string ] */ ; - UNPAIR - /* [ @index nat : @parameter string : @storage list string ] */ ; - PUSH nat 1 - /* [ nat : @index nat : @parameter string : @storage list string ] */ ; - ADD @index - /* [ @index nat : @parameter string : @storage list string ] */ ; - DUP - /* [ @index nat : @index nat : @parameter string : @storage list string ] */ ; - DIP { DIP { DUP /* [ @parameter string : @parameter string : @storage list string ] */ } - /* [ @index nat : @parameter string : @parameter string : @storage list string ] */ ; - SWAP - /* [ @parameter string : @index nat : @parameter string : @storage list string ] */ ; - SIZE - /* [ nat : @index nat : @parameter string : @storage list string ] */ ; - CMPNEQ } - /* [ @index nat : bool : @parameter string : @storage list string ] */ ; - SWAP - /* [ bool : @index nat : @parameter string : @storage list string ] */ } - /* [ @index nat : @parameter string : list string ] */ ; - DROP - /* [ @parameter string : list string ] */ ; - DROP - /* [ list string ] */ ; - NIL string - /* [ list string : list string ] */ ; - SWAP - /* [ list string : list string ] */ ; - ITER { CONS /* [ list string ] */ } - /* [ list string ] */ ; - NIL operation - /* [ list operation : list string ] */ ; - PAIR - /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_fr.tz].out deleted file mode 100644 index d7679c4c9d16..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_fr.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_bls12_381_fr.tz] - -Well typed -Gas remaining: 1039996.500 units remaining -{ parameter bls12_381_fr ; - storage (option bls12_381_fr) ; - code { CAR - /* [ @parameter bls12_381_fr ] */ ; - SOME - /* [ option bls12_381_fr ] */ ; - NIL operation - /* [ list operation : option bls12_381_fr ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g1.tz].out deleted file mode 100644 index 84ece93e6a5e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g1.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_bls12_381_g1.tz] - -Well typed -Gas remaining: 1039996.500 units remaining -{ parameter bls12_381_g1 ; - storage (option bls12_381_g1) ; - code { CAR - /* [ @parameter bls12_381_g1 ] */ ; - SOME - /* [ option bls12_381_g1 ] */ ; - NIL operation - /* [ list operation : option bls12_381_g1 ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_g1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g2.tz].out deleted file mode 100644 index 06839924d096..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g2.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_bls12_381_g2.tz] - -Well typed -Gas remaining: 1039996.500 units remaining -{ parameter bls12_381_g2 ; - storage (option bls12_381_g2) ; - code { CAR - /* [ @parameter bls12_381_g2 ] */ ; - SOME - /* [ option bls12_381_g2 ] */ ; - NIL operation - /* [ list operation : option bls12_381_g2 ] */ ; - PAIR - /* [ pair (list operation) (option bls12_381_g2) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_input.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_input.tz].out deleted file mode 100644 index d4f2e3c1124b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_input.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_input.tz] - -Well typed -Gas remaining: 1039997.267 units remaining -{ parameter string ; - storage string ; - code { CAR - /* [ @parameter string ] */ ; - NIL operation - /* [ list operation : @parameter string ] */ ; - PAIR - /* [ pair (list operation) (string @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_now.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_now.tz].out deleted file mode 100644 index ecbb62125bbd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_now.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_now.tz] - -Well typed -Gas remaining: 1039996.803 units remaining -{ parameter unit ; - storage timestamp ; - code { DROP - /* [] */ ; - NOW - /* [ @now timestamp ] */ ; - NIL operation - /* [ list operation : @now timestamp ] */ ; - PAIR - /* [ pair (list operation) (timestamp @now) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--str_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--str_id.tz].out deleted file mode 100644 index 0866a7471c97..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--str_id.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/str_id.tz] - -Well typed -Gas remaining: 1039996.500 units remaining -{ parameter string ; - storage (option string) ; - code { CAR - /* [ @parameter string ] */ ; - SOME - /* [ option string ] */ ; - NIL operation - /* [ list operation : option string ] */ ; - PAIR - /* [ pair (list operation) (option string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sub_timestamp_delta.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sub_timestamp_delta.tz].out deleted file mode 100644 index 20a61ffddea1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sub_timestamp_delta.tz].out +++ /dev/null @@ -1,20 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sub_timestamp_delta.tz] - -Well typed -Gas remaining: 1039994.373 units remaining -{ parameter (pair timestamp int) ; - storage timestamp ; - code { CAR - /* [ @parameter pair timestamp int ] */ ; - DUP - /* [ @parameter pair timestamp int : @parameter pair timestamp int ] */ ; - CAR - /* [ timestamp : @parameter pair timestamp int ] */ ; - DIP { CDR /* [ int ] */ } - /* [ timestamp : int ] */ ; - SUB - /* [ timestamp ] */ ; - NIL operation - /* [ list operation : timestamp ] */ ; - PAIR - /* [ pair (list operation) timestamp ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--subset.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--subset.tz].out deleted file mode 100644 index 7d58ca1fb0c3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--subset.tz].out +++ /dev/null @@ -1,46 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/subset.tz] - -Well typed -Gas remaining: 1039984.961 units remaining -{ parameter (pair (set string) (set string)) ; - storage bool ; - code { CAR - /* [ @parameter pair (set string) (set string) ] */ ; - DUP - /* [ @parameter pair (set string) (set string) - : @parameter pair (set string) (set string) ] */ ; - CDR - /* [ set string : @parameter pair (set string) (set string) ] */ ; - DIP { CAR /* [ set string ] */ } - /* [ set string : set string ] */ ; - PUSH bool True - /* [ bool : set string : set string ] */ ; - PAIR - /* [ pair bool (set string) : set string ] */ ; - SWAP - /* [ set string : pair bool (set string) ] */ ; - ITER { DIP { DUP - /* [ pair bool (set string) : pair bool (set string) ] */ ; - DUP - /* [ pair bool (set string) : pair bool (set string) : pair bool (set string) ] */ ; - CDR - /* [ set string : pair bool (set string) : pair bool (set string) ] */ ; - DIP { CAR - /* [ bool : pair bool (set string) ] */ ; - DIP { CDR /* [ set string ] */ } - /* [ bool : set string ] */ } - /* [ set string : bool : set string ] */ } - /* [ @elt string : set string : bool : set string ] */ ; - MEM - /* [ bool : bool : set string ] */ ; - AND - /* [ bool : set string ] */ ; - PAIR - /* [ pair bool (set string) ] */ } - /* [ pair bool (set string) ] */ ; - CAR - /* [ bool ] */ ; - NIL operation - /* [ list operation : bool ] */ ; - PAIR - /* [ pair (list operation) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--tez_add_sub.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--tez_add_sub.tz].out deleted file mode 100644 index 0abc83666944..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--tez_add_sub.tz].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/tez_add_sub.tz] - -Well typed -Gas remaining: 1039986.225 units remaining -{ parameter (pair mutez mutez) ; - storage (option (pair mutez mutez)) ; - code { CAR - /* [ @parameter pair mutez mutez ] */ ; - DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; - DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez - : @parameter pair mutez mutez ] */ ; - CAR - /* [ mutez : @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; - DIP { CDR /* [ mutez : @parameter pair mutez mutez ] */ } - /* [ mutez : mutez : @parameter pair mutez mutez ] */ ; - ADD - /* [ mutez : @parameter pair mutez mutez ] */ ; - DIP { DUP - /* [ @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; - CAR - /* [ mutez : @parameter pair mutez mutez ] */ ; - DIP { CDR /* [ mutez ] */ } - /* [ mutez : mutez ] */ ; - SUB_MUTEZ - /* [ option mutez ] */ ; - ASSERT_SOME } - /* [ mutez : @some mutez ] */ ; - PAIR - /* [ pair mutez (mutez @some) ] */ ; - SOME - /* [ option (pair mutez (mutez @some)) ] */ ; - NIL operation - /* [ list operation : option (pair mutez (mutez @some)) ] */ ; - PAIR - /* [ pair (list operation) (option (pair mutez (mutez @some))) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_bad.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_bad.tz].out deleted file mode 100644 index 7de15dc21377..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_bad.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_bad.tz] - -Well typed -Gas remaining: 1039996.963 units remaining -{ parameter unit ; - storage (ticket nat) ; - code { CDR - /* [ @storage ticket nat ] */ ; - NIL operation - /* [ list operation : @storage ticket nat ] */ ; - PAIR - /* [ pair (list operation) (ticket @storage nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_big_store.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_big_store.tz].out deleted file mode 100644 index 339fb92cb81b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_big_store.tz].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_big_store.tz] - -Well typed -Gas remaining: 1039992.430 units remaining -{ parameter nat ; - storage (big_map unit (ticket nat)) ; - code { UNPAIR - /* [ @parameter nat : @storage big_map unit (ticket nat) ] */ ; - PUSH nat 1 - /* [ nat : @parameter nat : @storage big_map unit (ticket nat) ] */ ; - SWAP - /* [ @parameter nat : nat : @storage big_map unit (ticket nat) ] */ ; - TICKET - /* [ ticket nat : @storage big_map unit (ticket nat) ] */ ; - SOME - /* [ option (ticket nat) : @storage big_map unit (ticket nat) ] */ ; - UNIT - /* [ unit : option (ticket nat) : @storage big_map unit (ticket nat) ] */ ; - UPDATE - /* [ @storage big_map unit (ticket nat) ] */ ; - NIL operation - /* [ list operation : @storage big_map unit (ticket nat) ] */ ; - PAIR - /* [ pair (list operation) (big_map @storage unit (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_join.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_join.tz].out deleted file mode 100644 index 2de77ed165c4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_join.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_join.tz] - -Well typed -Gas remaining: 1039990.843 units remaining -{ parameter (ticket nat) ; - storage (option (ticket nat)) ; - code { UNPAIR - /* [ @parameter ticket nat : @storage option (ticket nat) ] */ ; - SWAP - /* [ @storage option (ticket nat) : @parameter ticket nat ] */ ; - IF_NONE - { /* [ @parameter ticket nat ] */ } - { PAIR - /* [ pair (ticket @storage.some nat) (ticket @parameter nat) ] */ ; - JOIN_TICKETS - /* [ option (ticket nat) ] */ ; - ASSERT_SOME } ; - SOME - /* [ option (ticket nat) ] */ ; - NIL operation - /* [ list operation : option (ticket nat) ] */ ; - PAIR - /* [ pair (list operation) (option (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_read.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_read.tz].out deleted file mode 100644 index 4a9a121ae027..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_read.tz].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_read.tz] - -Well typed -Gas remaining: 1039984.150 units remaining -{ parameter (ticket nat) ; - storage address ; - code { CAR - /* [ @parameter ticket nat ] */ ; - READ_TICKET - /* [ pair address nat nat : @parameter ticket nat ] */ ; - DIP { DROP /* [] */ } - /* [ pair address nat nat ] */ ; - UNPAIR - /* [ address : pair nat nat ] */ ; - DIP { UNPAIR /* [ nat : nat ] */ } - /* [ address : nat : nat ] */ ; - DIIP { PUSH nat 1 /* [ nat : nat ] */ ; ASSERT_CMPEQ } - /* [ address : nat ] */ ; - DIP { PUSH nat 42 /* [ nat : nat ] */ ; ASSERT_CMPEQ } - /* [ address ] */ ; - NIL operation - /* [ list operation : address ] */ ; - PAIR - /* [ pair (list operation) address ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_split.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_split.tz].out deleted file mode 100644 index d1aeff5d8e20..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_split.tz].out +++ /dev/null @@ -1,39 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_split.tz] - -Well typed -Gas remaining: 1039978.358 units remaining -{ parameter (ticket nat) ; - storage unit ; - code { CAR - /* [ @parameter ticket nat ] */ ; - PUSH (pair nat nat) (Pair 1 2) - /* [ pair nat nat : @parameter ticket nat ] */ ; - SWAP - /* [ @parameter ticket nat : pair nat nat ] */ ; - SPLIT_TICKET - /* [ option (pair (ticket nat) (ticket nat)) ] */ ; - ASSERT_SOME ; - UNPAIR - /* [ ticket nat : ticket nat ] */ ; - READ_TICKET - /* [ pair address nat nat : ticket nat : ticket nat ] */ ; - CDDR ; - PUSH nat 1 - /* [ nat : nat : ticket nat : ticket nat ] */ ; - ASSERT_CMPEQ ; - DROP - /* [ ticket nat ] */ ; - READ_TICKET - /* [ pair address nat nat : ticket nat ] */ ; - CDDR ; - PUSH nat 2 - /* [ nat : nat : ticket nat ] */ ; - ASSERT_CMPEQ ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store-2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store-2.tz].out deleted file mode 100644 index 03125c41dce4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store-2.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_store-2.tz] - -Well typed -Gas remaining: 1039996.494 units remaining -{ parameter (option (ticket nat)) ; - storage (option (ticket nat)) ; - code { CAR - /* [ @parameter option (ticket nat) ] */ ; - NIL operation - /* [ list operation : @parameter option (ticket nat) ] */ ; - PAIR - /* [ pair (list operation) (option @parameter (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store.tz].out deleted file mode 100644 index 921d7157b436..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_store.tz] - -Well typed -Gas remaining: 1039996.114 units remaining -{ parameter (ticket nat) ; - storage (option (ticket nat)) ; - code { CAR - /* [ @parameter ticket nat ] */ ; - SOME - /* [ option (ticket nat) ] */ ; - NIL operation - /* [ list operation : option (ticket nat) ] */ ; - PAIR - /* [ pair (list operation) (option (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer-2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer-2.tz].out deleted file mode 100644 index 8d4c412361d8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer-2.tz].out +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticketer-2.tz] - -Well typed -Gas remaining: 1039987.194 units remaining -{ parameter (pair (pair address nat) nat) ; - storage unit ; - code { CAR - /* [ @parameter pair (pair address nat) nat ] */ ; - UNPAIR - /* [ pair address nat : nat ] */ ; - UNPAIR - /* [ address : nat : nat ] */ ; - CONTRACT (ticket nat) - /* [ @contract option (contract (ticket nat)) : nat : nat ] */ ; - ASSERT_SOME ; - DIP { TICKET /* [ ticket nat ] */ } - /* [ @contract.some contract (ticket nat) : ticket nat ] */ ; - SWAP - /* [ ticket nat : @contract.some contract (ticket nat) ] */ ; - DIP { PUSH mutez 0 /* [ mutez : @contract.some contract (ticket nat) ] */ } - /* [ ticket nat : mutez : @contract.some contract (ticket nat) ] */ ; - TRANSFER_TOKENS - /* [ operation ] */ ; - NIL operation - /* [ list operation : operation ] */ ; - SWAP - /* [ operation : list operation ] */ ; - CONS - /* [ list operation ] */ ; - UNIT - /* [ unit : list operation ] */ ; - SWAP - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer.tz].out deleted file mode 100644 index 4a7124409f1a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer.tz].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticketer.tz] - -Well typed -Gas remaining: 1039987.710 units remaining -{ parameter address ; - storage nat ; - code { UNPAIR - /* [ @parameter address : @storage nat ] */ ; - DIP { DUP /* [ @storage nat : @storage nat ] */ } - /* [ @parameter address : @storage nat : @storage nat ] */ ; - SWAP - /* [ @storage nat : @parameter address : @storage nat ] */ ; - PUSH nat 1 - /* [ nat : @storage nat : @parameter address : @storage nat ] */ ; - SWAP - /* [ @storage nat : nat : @parameter address : @storage nat ] */ ; - TICKET - /* [ ticket nat : @parameter address : @storage nat ] */ ; - DIP { CONTRACT - (ticket nat) - /* [ @parameter.contract option (contract (ticket nat)) : @storage nat ] */ ; - ASSERT_SOME ; - PUSH mutez - 0 - /* [ mutez : @parameter.contract.some contract (ticket nat) : @storage nat ] */ } - /* [ ticket nat : mutez : @parameter.contract.some contract (ticket nat) - : @storage nat ] */ ; - TRANSFER_TOKENS - /* [ operation : @storage nat ] */ ; - NIL operation - /* [ list operation : operation : @storage nat ] */ ; - SWAP - /* [ operation : list operation : @storage nat ] */ ; - CONS - /* [ list operation : @storage nat ] */ ; - PAIR - /* [ pair (list operation) (nat @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_amount.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_amount.tz].out deleted file mode 100644 index 7998161ca7ff..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_amount.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/transfer_amount.tz] - -Well typed -Gas remaining: 1039996.803 units remaining -{ parameter unit ; - storage mutez ; - code { DROP - /* [] */ ; - AMOUNT - /* [ @amount mutez ] */ ; - NIL operation - /* [ list operation : @amount mutez ] */ ; - PAIR - /* [ pair (list operation) (mutez @amount) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_tokens.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_tokens.tz].out deleted file mode 100644 index 24f838cd9839..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_tokens.tz].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/transfer_tokens.tz] - -Well typed -Gas remaining: 1039993.170 units remaining -{ parameter (contract unit) ; - storage unit ; - code { CAR - /* [ @parameter contract unit ] */ ; - DIP { UNIT /* [ unit ] */ } - /* [ @parameter contract unit : unit ] */ ; - PUSH mutez 100000000 - /* [ mutez : @parameter contract unit : unit ] */ ; - UNIT - /* [ unit : mutez : @parameter contract unit : unit ] */ ; - TRANSFER_TOKENS - /* [ operation : unit ] */ ; - NIL operation - /* [ list operation : operation : unit ] */ ; - SWAP - /* [ operation : list operation : unit ] */ ; - CONS - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--uncomb.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--uncomb.tz].out deleted file mode 100644 index 3f49cedeb157..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--uncomb.tz].out +++ /dev/null @@ -1,28 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/uncomb.tz] - -Well typed -Gas remaining: 1039992.541 units remaining -{ parameter (pair nat nat nat) ; - storage nat ; - code { CAR - /* [ @parameter pair nat nat nat ] */ ; - UNPAIR 3 - /* [ nat : nat : nat ] */ ; - PUSH nat 100 - /* [ nat : nat : nat : nat ] */ ; - MUL - /* [ nat : nat : nat ] */ ; - SWAP - /* [ nat : nat : nat ] */ ; - PUSH nat 10 - /* [ nat : nat : nat : nat ] */ ; - MUL - /* [ nat : nat : nat ] */ ; - ADD - /* [ nat : nat ] */ ; - ADD - /* [ nat ] */ ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--unpair.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--unpair.tz].out deleted file mode 100644 index 7af2cc9d0a14..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--unpair.tz].out +++ /dev/null @@ -1,322 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/unpair.tz] - -Well typed -Gas remaining: 1039903.879 units remaining -{ parameter (unit :param_unit) ; - storage (unit :u1) ; - code { DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - UNIT - /* [ unit : unit ] */ ; - PAIR - /* [ pair unit unit ] */ ; - UNPAIR - /* [ unit : unit ] */ ; - DROP 2 - /* [] */ ; - UNIT @b - /* [ @b unit ] */ ; - UNIT @a - /* [ @a unit : @b unit ] */ ; - PAIR - /* [ pair (unit @a) (unit @b) ] */ ; - UNPAIR @c @d - /* [ @c unit : @d unit ] */ ; - DROP 2 - /* [] */ ; - UNIT @b - /* [ @b unit ] */ ; - UNIT @a - /* [ @a unit : @b unit ] */ ; - PAIR %@ %@ - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR %a %b - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR % %b - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR %a % - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR % % - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR %a - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR % - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR %a %b @a @b - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR @a @b %a %b - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR @a @% %a %b - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR @% @% %a %b - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DUP - /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; - UNPAIR @% @b %a %b - /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; - DROP 2 - /* [ pair (unit %a @a) (unit %b @b) ] */ ; - DROP - /* [] */ ; - UNIT @d - /* [ @d unit ] */ ; - UNIT @c - /* [ @c unit : @d unit ] */ ; - PAIR %a %b - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR %a %b - /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR % %b - /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR %a % - /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR % % - /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR %a - /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR % - /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR - /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR %a %b @a @b - /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR @a @b %a %b - /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR @a @% %a %b - /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR @% @% %a %b - /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DUP - /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; - UNPAIR @% @b %a %b - /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; - DROP 2 - /* [ pair (unit %a @c) (unit %b @d) ] */ ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - UNIT - /* [ unit : unit ] */ ; - PAIR %a %b - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR %a %b - /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR % %b - /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR %a % - /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR % % - /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR %a - /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR % - /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR - /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR %a %b @a @b - /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR @a @b %a %b - /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR @a @% %a %b - /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR @% @% %a %b - /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DUP - /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; - UNPAIR @% @b %a %b - /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ pair (unit %a) (unit %b) ] */ ; - DROP - /* [] */ ; - UNIT - /* [ unit ] */ ; - UNIT - /* [ unit : unit ] */ ; - PAIR %a %b @p - /* [ @p pair (unit %a) (unit %b) ] */ ; - DUP - /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; - UNPAIR @%% @b - /* [ @p.a unit : @b unit : @p pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ @p pair (unit %a) (unit %b) ] */ ; - DUP - /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; - UNPAIR @a @%% - /* [ @a unit : @p.b unit : @p pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ @p pair (unit %a) (unit %b) ] */ ; - DUP - /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; - UNPAIR @%% @%% - /* [ @p.a unit : @p.b unit : @p pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ @p pair (unit %a) (unit %b) ] */ ; - DUP - /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; - UNPAIR @% @%% - /* [ @a unit : @p.b unit : @p pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ @p pair (unit %a) (unit %b) ] */ ; - DUP - /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; - UNPAIR @%% @% - /* [ @p.a unit : @b unit : @p pair (unit %a) (unit %b) ] */ ; - DROP 2 - /* [ @p pair (unit %a) (unit %b) ] */ ; - DROP - /* [] */ ; - UNIT @b - /* [ @b unit ] */ ; - UNIT @a - /* [ @a unit : @b unit ] */ ; - PAIR @c - /* [ @c pair (unit @a) (unit @b) ] */ ; - UNPAIR @b @a - /* [ @b unit : @a unit ] */ ; - DROP 2 - /* [] */ ; - UNIT - /* [ unit ] */ ; - NIL operation - /* [ list operation : unit ] */ ; - PAIR - /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--update_big_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--update_big_map.tz].out deleted file mode 100644 index 935a43eb7a41..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--update_big_map.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/update_big_map.tz] - -Well typed -Gas remaining: 1039991.231 units remaining -{ storage (pair (big_map string string) unit) ; - parameter (map string (option string)) ; - code { UNPAPAIR ; - ITER { UNPAIR - /* [ @key string : @elt option string : big_map string string : unit ] */ ; - UPDATE - /* [ big_map string string : unit ] */ } - /* [ big_map string string : unit ] */ ; - PAIR - /* [ pair (big_map string string) unit ] */ ; - NIL operation - /* [ list operation : pair (big_map string string) unit ] */ ; - PAIR - /* [ pair (list operation) (big_map string string) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxo_read.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxo_read.tz].out deleted file mode 100644 index 56833fa66b96..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxo_read.tz].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/utxo_read.tz] - -Well typed -Gas remaining: 1039984.190 units remaining -{ parameter (pair (ticket nat) nat) ; - storage address ; - code { CAR - /* [ @parameter pair (ticket nat) nat ] */ ; - UNPAIR - /* [ ticket nat : nat ] */ ; - READ_TICKET - /* [ pair address nat nat : ticket nat : nat ] */ ; - DIP { DROP /* [ nat ] */ } - /* [ pair address nat nat : nat ] */ ; - UNPAIR - /* [ address : pair nat nat : nat ] */ ; - DIP { UNPAIR /* [ nat : nat : nat ] */ } - /* [ address : nat : nat : nat ] */ ; - DIIP { ASSERT_CMPEQ } - /* [ address : nat ] */ ; - DIP { PUSH nat 42 /* [ nat : nat ] */ ; ASSERT_CMPEQ } - /* [ address ] */ ; - NIL operation - /* [ list operation : address ] */ ; - PAIR - /* [ pair (list operation) address ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxor.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxor.tz].out deleted file mode 100644 index 6b5b7d05b339..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxor.tz].out +++ /dev/null @@ -1,109 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/utxor.tz] - -Well typed -Gas remaining: 1039966.683 units remaining -{ parameter (pair address address) ; - storage nat ; - code { UNPAIR - /* [ @parameter pair address address : @storage nat ] */ ; - DIP { DUP /* [ @storage nat : @storage nat ] */ } - /* [ @parameter pair address address : @storage nat : @storage nat ] */ ; - SWAP - /* [ @storage nat : @parameter pair address address : @storage nat ] */ ; - PUSH nat - 5 - /* [ nat : @storage nat : @parameter pair address address : @storage nat ] */ ; - SWAP - /* [ @storage nat : nat : @parameter pair address address : @storage nat ] */ ; - TICKET - /* [ ticket nat : @parameter pair address address : @storage nat ] */ ; - PUSH nat - 2 - /* [ nat : ticket nat : @parameter pair address address : @storage nat ] */ ; - PUSH nat - 3 - /* [ nat : nat : ticket nat : @parameter pair address address : @storage nat ] */ ; - PAIR - /* [ pair nat nat : ticket nat : @parameter pair address address - : @storage nat ] */ ; - SWAP - /* [ ticket nat : pair nat nat : @parameter pair address address - : @storage nat ] */ ; - SPLIT_TICKET - /* [ option (pair (ticket nat) (ticket nat)) : @parameter pair address address - : @storage nat ] */ ; - ASSERT_SOME ; - UNPAIR - /* [ ticket nat : ticket nat : @parameter pair address address : @storage nat ] */ ; - DIP { DIP { DUP - /* [ @parameter pair address address : @parameter pair address address - : @storage nat ] */ ; - CAR - /* [ address : @parameter pair address address : @storage nat ] */ ; - CONTRACT - (pair (ticket nat) nat) - /* [ @contract option (contract (pair (ticket nat) nat)) - : @parameter pair address address : @storage nat ] */ ; - ASSERT_SOME ; - PUSH mutez - 0 - /* [ mutez : @contract.some contract (pair (ticket nat) nat) - : @parameter pair address address : @storage nat ] */ } - /* [ ticket nat : mutez : @contract.some contract (pair (ticket nat) nat) - : @parameter pair address address : @storage nat ] */ ; - PUSH nat - 2 - /* [ nat : ticket nat : mutez : @contract.some contract (pair (ticket nat) nat) - : @parameter pair address address : @storage nat ] */ ; - SWAP - /* [ ticket nat : nat : mutez : @contract.some contract (pair (ticket nat) nat) - : @parameter pair address address : @storage nat ] */ ; - PAIR - /* [ pair (ticket nat) nat : mutez - : @contract.some contract (pair (ticket nat) nat) - : @parameter pair address address : @storage nat ] */ } - /* [ ticket nat : pair (ticket nat) nat : mutez - : @contract.some contract (pair (ticket nat) nat) - : @parameter pair address address : @storage nat ] */ ; - DIP { TRANSFER_TOKENS - /* [ operation : @parameter pair address address : @storage nat ] */ } - /* [ ticket nat : operation : @parameter pair address address : @storage nat ] */ ; - SWAP - /* [ operation : ticket nat : @parameter pair address address : @storage nat ] */ ; - DIP { DIP { CDR - /* [ address : @storage nat ] */ ; - CONTRACT - (pair (ticket nat) nat) - /* [ @contract option (contract (pair (ticket nat) nat)) : @storage nat ] */ ; - ASSERT_SOME ; - PUSH mutez - 0 - /* [ mutez : @contract.some contract (pair (ticket nat) nat) : @storage nat ] */ } - /* [ ticket nat : mutez : @contract.some contract (pair (ticket nat) nat) - : @storage nat ] */ ; - PUSH nat - 3 - /* [ nat : ticket nat : mutez : @contract.some contract (pair (ticket nat) nat) - : @storage nat ] */ ; - SWAP - /* [ ticket nat : nat : mutez : @contract.some contract (pair (ticket nat) nat) - : @storage nat ] */ ; - PAIR - /* [ pair (ticket nat) nat : mutez - : @contract.some contract (pair (ticket nat) nat) : @storage nat ] */ } - /* [ operation : pair (ticket nat) nat : mutez - : @contract.some contract (pair (ticket nat) nat) : @storage nat ] */ ; - DIP { TRANSFER_TOKENS /* [ operation : @storage nat ] */ } - /* [ operation : operation : @storage nat ] */ ; - NIL operation - /* [ list operation : operation : operation : @storage nat ] */ ; - SWAP - /* [ operation : list operation : operation : @storage nat ] */ ; - CONS - /* [ list operation : operation : @storage nat ] */ ; - SWAP - /* [ operation : list operation : @storage nat ] */ ; - CONS - /* [ list operation : @storage nat ] */ ; - PAIR - /* [ pair (list operation) (nat @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_fib.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_fib.tz].out deleted file mode 100644 index fbe72ac3e8c7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_fib.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_fib.tz] - -Well typed -Gas remaining: 1039993.990 units remaining -{ parameter (pair nat address) ; - storage nat ; - code { CAR - /* [ @parameter pair nat address ] */ ; - UNPAIR - /* [ nat : address ] */ ; - VIEW "fib" nat - /* [ @contract option nat ] */ ; - IF_SOME - { NIL operation - /* [ list operation : @contract.some nat ] */ ; - PAIR - /* [ pair (list operation) (nat @contract.some) ] */ } - { FAIL } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_mutual_recursion.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_mutual_recursion.tz].out deleted file mode 100644 index 9aaa3e22c06a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_mutual_recursion.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_mutual_recursion.tz] - -Well typed -Gas remaining: 1039992.695 units remaining -{ parameter (pair nat address) ; - storage nat ; - code { CAR - /* [ @parameter pair nat address ] */ ; - DUP - /* [ @parameter pair nat address : @parameter pair nat address ] */ ; - CDR - /* [ address : @parameter pair nat address ] */ ; - SWAP - /* [ @parameter pair nat address : address ] */ ; - VIEW "is_twenty" nat - /* [ @contract option nat ] */ ; - IF_SOME - { NIL operation - /* [ list operation : @contract.some nat ] */ ; - PAIR - /* [ pair (list operation) (nat @contract.some) ] */ } - { FAIL } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_add.tz].out deleted file mode 100644 index 8a62319d8924..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_add.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_add.tz] - -Well typed -Gas remaining: 1039993.770 units remaining -{ parameter (pair nat address) ; - storage nat ; - code { CAR - /* [ @parameter pair nat address ] */ ; - UNPAIR - /* [ nat : address ] */ ; - VIEW "add" nat - /* [ @contract option nat ] */ ; - IF_SOME { /* [ @contract.some nat ] */ } { FAIL } ; - NIL operation - /* [ list operation : @contract.some nat ] */ ; - PAIR - /* [ pair (list operation) (nat @contract.some) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_constant.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_constant.tz].out deleted file mode 100644 index de42c2c0a404..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_constant.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_constant.tz] - -Well typed -Gas remaining: 1039993.750 units remaining -{ parameter (pair nat address) ; - storage nat ; - code { CAR - /* [ @parameter pair nat address ] */ ; - UNPAIR - /* [ nat : address ] */ ; - VIEW "const" nat - /* [ @contract option nat ] */ ; - IF_SOME { /* [ @contract.some nat ] */ } { FAIL } ; - NIL operation - /* [ list operation : @contract.some nat ] */ ; - PAIR - /* [ pair (list operation) (nat @contract.some) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_id.tz].out deleted file mode 100644 index d9279a6bdb19..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_id.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_id.tz] - -Well typed -Gas remaining: 1039992.989 units remaining -{ parameter (pair nat address) ; - storage (pair nat nat) ; - code { CAR - /* [ @parameter pair nat address ] */ ; - UNPAIR - /* [ nat : address ] */ ; - VIEW "id" (pair nat nat) - /* [ @contract option (pair nat nat) ] */ ; - IF_SOME { /* [ @contract.some pair nat nat ] */ } { FAIL } ; - NIL operation - /* [ list operation : @contract.some pair nat nat ] */ ; - PAIR - /* [ pair (list operation) (pair @contract.some nat nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_addr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_addr.tz].out deleted file mode 100644 index 9a9131a547a2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_addr.tz].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_nonexistent_addr.tz] - -Well typed -Gas remaining: 1039342.059 units remaining -{ parameter (pair nat address) ; - storage bool ; - code { DROP - /* [] */ ; - PUSH address "tz1SuakBpFdG9b4twyfrSMqZzruxhpMeSrE5" - /* [ address ] */ ; - PUSH nat 0 - /* [ nat : address ] */ ; - VIEW "test" bool - /* [ @contract option bool ] */ ; - IF_SOME - { DROP /* [] */ ; PUSH bool True /* [ bool ] */ } - { PUSH bool False /* [ bool ] */ } ; - NIL operation - /* [ list operation : bool ] */ ; - PAIR - /* [ pair (list operation) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_func.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_func.tz].out deleted file mode 100644 index d8b49a53770f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_func.tz].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_nonexistent_func.tz] - -Well typed -Gas remaining: 1039993.059 units remaining -{ parameter (pair nat address) ; - storage bool ; - code { CAR - /* [ @parameter pair nat address ] */ ; - UNPAIR - /* [ nat : address ] */ ; - VIEW "not_exist" bool - /* [ @contract option bool ] */ ; - IF_SOME - { DROP /* [] */ ; PUSH bool True /* [ bool ] */ } - { PUSH bool False /* [ bool ] */ } ; - NIL operation - /* [ list operation : bool ] */ ; - PAIR - /* [ pair (list operation) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_test_step_contants.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_test_step_contants.tz].out deleted file mode 100644 index d837439afbe6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_test_step_contants.tz].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_test_step_contants.tz] - -Well typed -Gas remaining: 1039992.390 units remaining -{ parameter address ; - storage (option (pair (pair mutez mutez) (pair (pair address address) address))) ; - code { CAR - /* [ @parameter address ] */ ; - UNIT - /* [ unit : @parameter address ] */ ; - VIEW "step_constants" - (pair (pair mutez mutez) (pair (pair address address) address)) - /* [ @parameter.contract option (pair (pair mutez mutez) (pair address address) address) ] */ ; - NIL operation - /* [ list operation - : @parameter.contract option (pair (pair mutez mutez) (pair address address) address) ] */ ; - PAIR - /* [ pair (list operation) - (option @parameter.contract (pair (pair mutez mutez) (pair address address) address)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_input_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_input_type.tz].out deleted file mode 100644 index 3d6b281ed422..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_input_type.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_toplevel_inconsistent_input_type.tz] - -Well typed -Gas remaining: 1039993.119 units remaining -{ parameter (pair int address) ; - storage nat ; - code { CAR - /* [ @parameter pair int address ] */ ; - UNPAIR - /* [ int : address ] */ ; - VIEW "add" nat - /* [ @contract option nat ] */ ; - IF_SOME { DROP /* [] */ ; PUSH nat 1 /* [ nat ] */ } { PUSH nat 0 /* [ nat ] */ } ; - NIL operation - /* [ list operation : nat ] */ ; - PAIR - /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_output_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_output_type.tz].out deleted file mode 100644 index d89bb7ef51f1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_output_type.tz].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_toplevel_inconsistent_output_type.tz] - -Well typed -Gas remaining: 1039993.119 units remaining -{ parameter (pair nat address) ; - storage bool ; - code { CAR - /* [ @parameter pair nat address ] */ ; - UNPAIR - /* [ nat : address ] */ ; - VIEW "add" bool - /* [ @contract option bool ] */ ; - IF_SOME - { DROP /* [] */ ; PUSH bool True /* [ bool ] */ } - { PUSH bool False /* [ bool ] */ } ; - NIL operation - /* [ list operation : bool ] */ ; - PAIR - /* [ pair (list operation) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_rec.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_rec.tz].out deleted file mode 100644 index 2dc1cde40ecd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_rec.tz].out +++ /dev/null @@ -1,33 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_rec.tz] - -Well typed -Gas remaining: 1039987.709 units remaining -{ parameter unit ; - storage unit ; - view "loop" - address - never - { CAR - /* [ address ] */ ; - DUP - /* [ address : address ] */ ; - VIEW "loop" never - /* [ @contract option never ] */ ; - ASSERT_SOME } ; - code { CDR - /* [ @storage unit ] */ ; - SELF - /* [ @self contract unit : @storage unit ] */ ; - ADDRESS - /* [ @self.address address : @storage unit ] */ ; - DUP - /* [ @self.address address : @self.address address : @storage unit ] */ ; - VIEW "loop" never - /* [ @self.address.contract option never : @storage unit ] */ ; - ASSERT_SOME ; - DROP - /* [ @storage unit ] */ ; - NIL operation - /* [ list operation : @storage unit ] */ ; - PAIR - /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_toplevel_lib.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_toplevel_lib.tz].out deleted file mode 100644 index 3566383e137d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_toplevel_lib.tz].out +++ /dev/null @@ -1,148 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_toplevel_lib.tz] - -Well typed -Gas remaining: 1039942.437 units remaining -{ parameter nat ; - storage nat ; - code { CAR - /* [ @parameter nat ] */ ; - NIL operation - /* [ list operation : @parameter nat ] */ ; - PAIR - /* [ pair (list operation) (nat @parameter) ] */ } ; - view "add" nat nat { UNPAIR /* [ nat : nat ] */ ; ADD /* [ nat ] */ } ; - view "id" nat (pair nat nat) { /* [ pair nat nat ] */ } ; - view "test_failwith" nat (pair nat nat) { FAILWITH /* [] */ } ; - view "step_constants" - unit - (pair (pair mutez mutez) (pair (pair address address) address)) - { DROP - /* [] */ ; - SOURCE - /* [ @source address ] */ ; - SENDER - /* [ @sender address : @source address ] */ ; - SELF_ADDRESS - /* [ @self address : @sender address : @source address ] */ ; - PAIR - /* [ pair (address @self) (address @sender) : @source address ] */ ; - PAIR - /* [ pair (pair (address @self) (address @sender)) (address @source) ] */ ; - BALANCE - /* [ @balance mutez - : pair (pair (address @self) (address @sender)) (address @source) ] */ ; - AMOUNT - /* [ @amount mutez : @balance mutez - : pair (pair (address @self) (address @sender)) (address @source) ] */ ; - PAIR - /* [ pair (mutez @amount) (mutez @balance) - : pair (pair (address @self) (address @sender)) (address @source) ] */ ; - PAIR - /* [ pair (pair (mutez @amount) (mutez @balance)) - (pair (address @self) (address @sender)) - (address @source) ] */ } ; - view "succ" - (pair nat address) - nat - { CAR - /* [ pair nat address ] */ ; - UNPAIR - /* [ nat : address ] */ ; - PUSH nat 1 - /* [ nat : nat : address ] */ ; - ADD - /* [ nat : address ] */ ; - PAIR - /* [ pair nat address ] */ ; - DUP - /* [ pair nat address : pair nat address ] */ ; - CDR - /* [ address : pair nat address ] */ ; - SWAP - /* [ pair nat address : address ] */ ; - VIEW "is_twenty" nat - /* [ @contract option nat ] */ ; - ASSERT_SOME } ; - view "is_twenty" - (pair nat address) - nat - { CAR - /* [ pair nat address ] */ ; - DUP - /* [ pair nat address : pair nat address ] */ ; - CAR - /* [ nat : pair nat address ] */ ; - PUSH nat 20 - /* [ nat : nat : pair nat address ] */ ; - COMPARE - /* [ int : pair nat address ] */ ; - EQ - /* [ bool : pair nat address ] */ ; - IF { CAR /* [ nat ] */ } - { DUP - /* [ pair nat address : pair nat address ] */ ; - CDR - /* [ address : pair nat address ] */ ; - SWAP - /* [ pair nat address : address ] */ ; - VIEW "succ" nat - /* [ @contract option nat ] */ ; - ASSERT_SOME } } ; - view "fib" - nat - nat - { CAR - /* [ nat ] */ ; - DUP - /* [ nat : nat ] */ ; - PUSH nat 0 - /* [ nat : nat : nat ] */ ; - COMPARE - /* [ int : nat ] */ ; - EQ - /* [ bool : nat ] */ ; - IF { /* [ nat ] */ } - { DUP - /* [ nat : nat ] */ ; - PUSH nat 1 - /* [ nat : nat : nat ] */ ; - COMPARE - /* [ int : nat ] */ ; - EQ - /* [ bool : nat ] */ ; - IF { /* [ nat ] */ } - { DUP - /* [ nat : nat ] */ ; - PUSH nat 1 - /* [ nat : nat : nat ] */ ; - SWAP - /* [ nat : nat : nat ] */ ; - SUB - /* [ int : nat ] */ ; - ABS - /* [ nat : nat ] */ ; - SELF_ADDRESS - /* [ @self address : nat : nat ] */ ; - SWAP - /* [ nat : @self address : nat ] */ ; - VIEW "fib" nat - /* [ @self.contract option nat : nat ] */ ; - IF_SOME - { SWAP - /* [ nat : @self.contract.some nat ] */ ; - PUSH nat 2 - /* [ nat : nat : @self.contract.some nat ] */ ; - SWAP - /* [ nat : nat : @self.contract.some nat ] */ ; - SUB - /* [ int : @self.contract.some nat ] */ ; - ABS - /* [ nat : @self.contract.some nat ] */ ; - SELF_ADDRESS - /* [ @self address : nat : @self.contract.some nat ] */ ; - SWAP - /* [ nat : @self address : @self.contract.some nat ] */ ; - VIEW "fib" nat - /* [ @self.contract option nat : @self.contract.some nat ] */ ; - IF_SOME { ADD /* [ nat ] */ } { FAIL } } - { FAIL } } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--voting_power.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--voting_power.tz].out deleted file mode 100644 index 398157ecc039..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--voting_power.tz].out +++ /dev/null @@ -1,20 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/voting_power.tz] - -Well typed -Gas remaining: 1039994.233 units remaining -{ parameter key ; - storage (pair nat nat) ; - code { CAR - /* [ @parameter key ] */ ; - HASH_KEY - /* [ key_hash ] */ ; - VOTING_POWER - /* [ nat ] */ ; - DIP { TOTAL_VOTING_POWER /* [ nat ] */ } - /* [ nat : nat ] */ ; - PAIR - /* [ pair nat nat ] */ ; - NIL operation - /* [ list operation : pair nat nat ] */ ; - PAIR - /* [ pair (list operation) nat nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--xor.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--xor.tz].out deleted file mode 100644 index f9da7562f119..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--xor.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/xor.tz] - -Well typed -Gas remaining: 1039990.984 units remaining -{ parameter (or (pair bool bool) (pair nat nat)) ; - storage (option (or bool nat)) ; - code { CAR - /* [ @parameter or (pair bool bool) (pair nat nat) ] */ ; - IF_LEFT - { UNPAIR /* [ bool : bool ] */ ; XOR /* [ bool ] */ ; LEFT nat /* [ or bool nat ] */ } - { UNPAIR /* [ nat : nat ] */ ; XOR /* [ nat ] */ ; RIGHT bool /* [ or bool nat ] */ } ; - SOME - /* [ option (or bool nat) ] */ ; - NIL operation - /* [ list operation : option (or bool nat) ] */ ; - PAIR - /* [ pair (list operation) (option (or bool nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[Fr].out deleted file mode 100644 index 8b49506f5fd6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_one[Fr] - -storage - (Some 0x0200000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G1].out deleted file mode 100644 index fc3fdf65638f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_one[G1] - -storage - (Some 0x0572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G2].out deleted file mode 100644 index db602b9c2b16..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_one[G2] - -storage - (Some 0x0a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a0530f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf30468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[Fr].out deleted file mode 100644 index f2675822471d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_random[Fr] - -storage - (Some 0x660dec4a316a24f34cad26e886cb480da89c55113f5c1a2b6bfdaab82d737708) -emitted operations - -big_map diff - - -storage - (Some 0xa711c66e47a4f376a769f9accfd675dcc6a2b9ce09c0482923c19f8218f16849) -emitted operations - -big_map diff - - -storage - (Some 0x111a13c7d5feb5e8fe5b2c5550d3335c04737fcbeece373eabf07b1b1604bb3b) -emitted operations - -big_map diff - - -storage - (Some 0x366bf41ff7bd7828a3d206500267d5c888aa120292be0cd6399fe4b9db75625b) -emitted operations - -big_map diff - - -storage - (Some 0x86b8dc4aa73cccb08dd143980ec0a4f73c2067807b3b4f2ff96368cb5efd8d4e) -emitted operations - -big_map diff - - -storage - (Some 0x7b83a6a4c37d5536bebe96766b25195e32b69257f3dc2d1e6fcdd7144db0f80c) -emitted operations - -big_map diff - - -storage - (Some 0xac54d72aff4eb7b9acce60a61f8f2ca1a1a387557cd6df2e9fe690ce209eca63) -emitted operations - -big_map diff - - -storage - (Some 0x183b7f72e291320045c63ad9453dacada669ef605e72c708a8735ae2fa7f795d) -emitted operations - -big_map diff - - -storage - (Some 0xb82eba460eb5d8e64d597cca0278098e87f2e1bba06d0fe19f6da2075084c66f) -emitted operations - -big_map diff - - -storage - (Some 0xb87216f6813286cfabec830fa176f2aa127cc1b99b824d312bd8d239c2555d6e) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G1].out deleted file mode 100644 index 7d8a78442e03..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_random[G1] - -storage - (Some 0x058026aa05e53a8be99d756ad00d2f3577786eeb07abe3d0bb51a9c6c4786fa31579791ecca13a22e423a3ca2e1d8ae6049f0d41d63294fa63d9679c2dfda2ccc5263bdff7d8f404fb566e3a420fdf9bcc003cd33b7d4a46f1d9a1dd059c879f) -emitted operations - -big_map diff - - -storage - (Some 0x11613e266146d8bf256974bfd8bc7bcfc1aa33d1abb8407d5199c18c1d71bdc27c37bcc64a30f3e39ef8f04e521a099a029636513b15f1e71a7aa6042fff9d1d552c542caa5f302071504d524d511173027aa21ad9d1928dba8a201c9f24d9a3) -emitted operations - -big_map diff - - -storage - (Some 0x026fcea34d1a4c5125142dfa3b616086309cab49e60e548d95de658af4d9329c269dc132bd5d884617e8767600daeee90c6f5d25f3d63540f3b799d291e5df4a90244346ed780d5c9d3afa8f3c9a196e089fa4edc4a9806592e8561d626579e3) -emitted operations - -big_map diff - - -storage - (Some 0x0f048c8e56ad4ddbb3fe800e2667ecaa5683d33a2828c7f9341ed2708f83e1cc58484085399822f6af8f05e9761cb49f0ee1db03e81501d8982d1362518386e77fbcf240d9d4768187ab4727c6b4ede0057dbe0358f37dac17eb2eb395088a44) -emitted operations - -big_map diff - - -storage - (Some 0x114c27c6a72b3eb7bb0176261d670ce20a9cf90a52da5b68faf2013bac314f7987e735ac04ebb1c164a48f60c16ec4be0c1eb74c865b1df94202b4eceb42e22d86099ad360339303463d68c0d931774304fa4c780208abcf1c79640b0c4190ce) -emitted operations - -big_map diff - - -storage - (Some 0x054b5561e8d9de0052a167f4886efd49890dfda073843dee3077c37ccb3d7ad2326970eb9615f318a0851b30aaa7f1150b4a687ddf9672bdbcf159358ea75025adc8584532a046b48d30868ee38dba0ca8a209af29cd791594cfb7e9ae991119) -emitted operations - -big_map diff - - -storage - (Some 0x174e2a1898303aba4520148510fbdc740d8154886d04d1ef7f65c904cbd2171af98345f2463bf26c35576da1be372d680bd755d4c860640a9991cfe703590382c2c20ab7121bc94926dac025e25526ffbb234785bfb6eb5ebd9b8be521e5cda3) -emitted operations - -big_map diff - - -storage - (Some 0x04cf46cee905ad068310d3e0764cba786372efd7eea4a8a2354da24eea26af1578320cc25a5c0dd9fa016c16ef956b071529c2fe97c6c69690675a5484220900d6c48d03976289801f818899416e014e9d50ca19c165b9c43e4de8ee0b16a792) -emitted operations - -big_map diff - - -storage - (Some 0x0ec968f32f75a84a3bac57f2025ebcef650a8ccf5da9b27ca53331eda42ca2848948e8e9cc7588acdc9430ba4051a0c70ada591853bf90ebcd4df22ce469c453ce5d4bfb7d968ba8b85ec48188f7912a549dc7a81f246264da9b355aeb1b0178) -emitted operations - -big_map diff - - -storage - (Some 0x018637aff527610ee1a083eca3f3ad2a989dbcce2a393e24703e52e418b8d373433155bda3bb4664aef12d8cb058932d14d26d519045ce36b21cb50c77373077cced9fc000b8696cc5e035ad7d2dbdf41971c8403bee31ae0a6a36263066b847) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G2].out deleted file mode 100644 index a58357132e6a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_random[G2] - -storage - (Some 0x139bd98ba7fa37cb7e1ba9177ca818063bd14a8aba77a7f4dbff7a6c848683ac17415104d5c63e46df848499f209dfbc105f18d1e114210fbce28d22f30818e75bc412526a55f7937ac290bf37adadeee6f40b9614b74b1962376d5c3078085a02a53c9021eba8b107a43bdebaef9fddc6a8c8d8c19138d06a332f986f256c32b8f19d5e39f203eba23ea36b4bcff9300dad02b62de4defe358fe6b835b3d93571ef66989530e61090c3db145c389f66ab2ee01e4f05a9ca18fb1ecf48faed94) -emitted operations - -big_map diff - - -storage - (Some 0x192438792f58ae648d5cc73d07d263f0866430fa798d61cddcf35ac48533cd60ceb7e1adaf2ac7475b0819d583b5fe210454a94b83d8a110f699db4c1963dd9bbc1f5b8d1de6ae59f0c5c1d0c0fccdc04d5cfaf901b9c1b713b48938589bd53419a11025e8f61abf088d72b3fe3e3f8d6682e235804855d5a02897ad8ce252fb2584670c27dd81e48ba14d01b09add9e0857cd0cfd23bce8702ad2cf73709debce427df15ba1bd920c941eabc712fa2652e906a1f49d604222410929de6498a1) -emitted operations - -big_map diff - - -storage - (Some 0x14e9b22683a66543ec447b7aa76e4404424709728507581d0b3f60a8062c3f7c7d3365197c59f7c961fa9731084f5be60d0a936e93d556bdef2032cdcae2fa9902dcbe105e01d7ab7126d83486d882c4efd2fc1ac55044157333be19acf0cb7a10bc41c8081c9babd8d5b41b645badd4a679b3d4e1b3ea2c0e1f53b39c00b3889a40306c9b9ee2da5831e90148334d91016474d07e0f4e36d2d51b5ca11b633b9a940b9c126aebf4a2537c18fdc6967fb677824bfa902157e53cb499a021e57b) -emitted operations - -big_map diff - - -storage - (Some 0x139bf65acd684812defe34a647e77d562d16ec07aadc8df7460835bb42e52783265fc7062d24399533488aa26f177f300a05c44ba3deb272a9334bfbd15e3df49169622e8cc739c8d8ad1658769e94f28c36b3ddc608a71ea590f5d956820116019860de9ec8f5257791279a546c6d7efc62ce91114bcb11053f999f5adf35c0f0da321602ce11347567aefe05c58bfc17693d82a530ed5c07e7e1d87d3ac3c639005480f5fc9b9fb378aa693781d0ba8ee097bff01964faa41c9361ae9da3ed) -emitted operations - -big_map diff - - -storage - (Some 0x17df1d683296888e1ef6becb004061a658609faa7aecfc56e09be2cb07f621e6bf383f3ed9eaa5ad6eb4c5ff3e4ac51615cf8e6d23843b1665d6efefdc8024b15651ee05b939f1fc529a5d4233d58ee83cd4fcd07508eb0fa1229bf649db9fb407167c5d410f1f4c403bd4cc234e3f757d74587ead39d549b88e6d6e0e187498386152a981e26a0ecfbc89349db5e5f502e61c367aea8d829cbc8d2441362f075c9245a82c8daf849dde2316fb06127db9eeb2d99a5bfee90e39ac18ac062db2) -emitted operations - -big_map diff - - -storage - (Some 0x072666f55bcd0330329524efb1a8bf981fcb0ee73c739be4b83339fa2953888bf058a115c834ed7460f6ef6e7aa36d0d1002adc9e373cfcfc62f47a6a6670700c749e6df92e360fa0a379c5621b39f35b02c578aea5e79d54f692d2fab9ad7c01527640d6462324d6a137bf7c36abd863f3efe2953d3b1729e8d3f07321af14f38893ca2e61eba4c987a5f7988569c4f0626e86728ce9292df1bd38c5e21b32d329b86f8f41eaa11eac36cc0ddf0b3fba543d94f4d3a4b992eb7e60fe9680072) -emitted operations - -big_map diff - - -storage - (Some 0x152f2b940efd3d2c53640e2ccf881935f114404ac116a54c859c59511058db4d7e2f4369e3e846ccdda94e72e22e06ce0fb52ada3931bb686d52e45ef020b58b9da28f370cd27a595b07eae78ec26e044f58c15cd256fb426e0b862a37bb751212256f5e61ef53dcf799657d5071e6dfa1040b2ac0ec31e18069d2e6e7e6424d09ece1b68a8be6d56dca3de4d467e8a80c395cd9ebe4645d3e465f0263bc100bb9d49dbaadf0572836c8bf03d8c2155068a1f56017864a51e8f4915d24885afa) -emitted operations - -big_map diff - - -storage - (Some 0x0c5ae8a5d7042b893b4600512b81b205b0f3aec3b00d0b2ece549e31c0466f49cd8900270ac48f253e66dc8a05a83e3c0ed8790344651fb0d17ef0c0f86340687e890424c06b5426e6732c3ff837ad4c76a2dfb9f5d80e80eadd024cc4c386f10bc203d5bba633fa3f50fb84140e9ef8c0f7c83ad41b2d1230b8af982e541c07f137b59b71142a4e2be49d9a0fd1212f11fe2ebabe025ab38dfc64f38e724edea44610b88239679e60d9ee151174a3bd1425eb865b8533c0b833577e430ae37a) -emitted operations - -big_map diff - - -storage - (Some 0x127093c56626b5e31114ddc6565ac257c3f5642d4eeabb469c2e6cfa23c713bd87fbccc738eae6c6356eb1bc3e62babc1985437cd7bcf96041d3547efa5c1c5ab0dc66aecae18f5a70055a4f4c518b6f7f31f18709d0a7f37f5eb3cd413557f7164ead5569fd618dee7145ce3b5786a4d5551c63b6936e682e618f9db2aa1c97117369cde387255d063890b4a7c788b80ebabf2427faab4c8cc0a71d467ca7c78cc625fd9dbb48fd485124cdf1c5748f6488a06f1e71b429fc904f249fd5885f) -emitted operations - -big_map diff - - -storage - (Some 0x0e18a45de8e16ce54070d9df1ee055e933e7c65e2d33bbfd9eba62dbcd84c00eca86bffec4f0e02ea6172242243ca205067af2bd83fee2481e6ed3fee5b327e9d7aa95513d1fa3b60093b86b29ae14df53b03ac63f5b0c2ea3df9575fddd2bc7045df4179eb4de582fd6c3955d1947036131eea418e57fa977181e9b7c6af89686f47593bc3e1d9ea0be7c46004f23ce0d3abe0bd9fbae591d5b3fba5ed26ee6756ab595e79f27825afe20fa68d7d6b954356b589c80dc909d5d91c6afed0440) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[Fr].out deleted file mode 100644 index c5ad3b60accd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_zero[Fr] - -storage - (Some 0x0100000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G1].out deleted file mode 100644 index 71b4d0d5d00e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_zero[G1] - -storage - (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G2].out deleted file mode 100644 index aa98c7d2c4d6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_zero[G2] - -storage - (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[Fr].out deleted file mode 100644 index a940808843a8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_one[Fr] - -storage - (Some 0xf09d35856fcfe3dd435bed02f67e1a34b246f9eb48f9034e3bce2a83ba806c23) -emitted operations - -big_map diff - - -storage - (Some 0x2a5cababf8f15f832f44e2a935f029722c2e4c87fdcd3ad1bf4ec872042d9f11) -emitted operations - -big_map diff - - -storage - (Some 0x90bdbed3c04f5a16f7dd885aa2bf82e0688da08f687d29a38c6ebf46631d7a38) -emitted operations - -big_map diff - - -storage - (Some 0xb0df3414f8f1b9b0265f7d243790b57dbf3f028bd0e99707a4ec7c6753ff9c5a) -emitted operations - -big_map diff - - -storage - (Some 0xd908b12f4af05efc5a4fc60806a64be2cc267846d93f2d6e857334c2aa66dd62) -emitted operations - -big_map diff - - -storage - (Some 0xb2a92200b1c95da0fbc293e7fb078961820240c26c87ff727a63fbcd3bf7591a) -emitted operations - -big_map diff - - -storage - (Some 0xa4fcd4658ae7312cd766f6d32afb2a57acbc386000d7a817fb45b4ddb7064c5f) -emitted operations - -big_map diff - - -storage - (Some 0x93e781ac13e039a74b9329fe4c62581e78cbe5f98c3a40ef4aef0afffb52e915) -emitted operations - -big_map diff - - -storage - (Some 0x4c7dc9dffae7cafafb2d713f334576a96a530ed57c5fe4c083130f67cce8c33b) -emitted operations - -big_map diff - - -storage - (Some 0x2a72fa0e849cecab222419ae6b7ef22b21221f06f7755caab4aa0c035d10d90e) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G1].out deleted file mode 100644 index 3589386b9675..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_one[G1] - -storage - (Some 0x03511648ff12b05121af6aee879ec39ded8e895f3bf83c64425c374ed1f1eb022d69b23657d36c7caf3a4680c0ac4617193583c1f57a61b18d61b2584a9b373bb45564b67ebdb884f7fc771ee639d596d343b302872a39a649b25eb4420963af) -emitted operations - -big_map diff - - -storage - (Some 0x01382fcd60894365df78f25e41a72e66a8b82633a94c8aad9a782bf880951b2e77794775bc0f2beb2200896c3042f24219fbc49d8c9f4a446ef1e5d3c8bf0d5da5e5c7480389030f971eef2fe382ecf7017351d7a838456e9f32fc7c32400277) -emitted operations - -big_map diff - - -storage - (Some 0x046dfb65aeebf558d612af9e6efe5aca9332026c0bf584afe7f11166a511a209cb750b2a037f28c476d49c0f8d5b42401479f06b06eddadef2139b142d1f44d4d63ec870a12fd574a89fefb05000a48a0c1d4cad1ec1fb53ffecbb05d2fd1a26) -emitted operations - -big_map diff - - -storage - (Some 0x12f06982de9983d040b51bf0cbbca5c8eebd6636f81c49a4b56d06ef8092126c50a0451931917a5ae0a551b16d0e3fa60bab06dbd78fc6a64f6c9647ae4ea534baf2fa5f08d438399937e4458563f47c1e8c4f0495d5c0f6609492d548310cb5) -emitted operations - -big_map diff - - -storage - (Some 0x0d8b71b72b170030fcb76bc7324fa823f8b59f2cb6b014687620a3d01c8cae25a41c423ff9258524571ab273fdd1783704b9fd0d5a4e1801cfb819aff9297579012d3cf77291ad1a2748fb1727c46fe3d0f9d2feadcc57c2cd495b6cb9314a5a) -emitted operations - -big_map diff - - -storage - (Some 0x016a3c5fff7923ad1c3566886a6dd256e32e69d992fd92a34496ae3667b33df6b699b7805fe732c68c98703e93a2ab9716dcf3d2a244889d3ff2804b9aa2043e7b07398789e39b8ac022606a90f303f176dca030856cc0777c2df1f7fe1a58f3) -emitted operations - -big_map diff - - -storage - (Some 0x11851bdd68f0062a6f4729647cc25af2431689ef7bddd79f82a4682d6d1292fcd7922a697a4fb8982d26680ad4af336004af74b34bdb318d0fdae9d0413065d47a5202903a59cb033460b3d88b942e5f611d542fd2e8b9c9d300b3b153f43efb) -emitted operations - -big_map diff - - -storage - (Some 0x07809251bc1b99439e63008e8d783acbe2fde93625f4175c33db220d96c310931753794535e47d84317de54b035582e9060a1f49de845f3f870a46e7e8939bf2d387f2e6d87f2244cb26b9e153723629d92adaa94f46e1be7458fc45c556fb0c) -emitted operations - -big_map diff - - -storage - (Some 0x0ce4e3355f0a5df9eab02eecb2510de9a9837611481d4fe8e5f803e7c60db5da63a1afb13a019a0f1f199d0ffe87297c01d5cbae9a4df48cef28ab34c8e2a684b1601fe30729e2512e937eea6e4071fb715926508fe1efaa9edf0633a1057718) -emitted operations - -big_map diff - - -storage - (Some 0x1358174de7b56cf42eb7d6ffe1ed41fefed8bacb3b18c88925e69ec8c51992ff84942d2d468d49e256d77c5d38d9d71b016480cb05ae9ed0c549b8446e9366493ceffc9471c206a359d8c9f58351ee2f6292208442baa3cfd09813af73d0b7c7) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G2].out deleted file mode 100644 index 70e3c1799267..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_one[G2] - -storage - (Some 0x08fefb71e4511ed0d6a3bd0409725b908a0c192d13307a72b1c83e586f534897e3d2a7276eddf2c0027b44058e5da8e11911a8bae300eba2295ae0121dd9f78d2dbb3fa6f38f397b8b67dfb43d1c7303e699925597f04c463c55e625b66d0c02107220b0a6af8b1c2f445c396e3920a573e573b90d51d0d7e3baeb7921f35a261a1324fa74cb05cfc5dc3b09c14ea2fb14e0c74a54dd945b8256a69e2f72c084e54e29ba8b0dcaae61f8dded3054c47d0e96eee36c0bb002d2803f7b51cfb96f) -emitted operations - -big_map diff - - -storage - (Some 0x0508c45054a19a896a24fc4cd6f35ff97a3db9375bcd489f2737f4182c6f7dfbbb7412497f3609d417e44934c4ac10b717c67161445629d6d7532e40929c795b8b3d672a053cb59408352c24d5148e97e807dfbca83a3fa49a629b4a00a5a79c0f2f871ff459bfe82b647c864560019a5894f7b0725917bded14f81631f4df52cb88e0d72fb0503d90a562f7b28f49cb00ecf93cf750fb701e2e3fb50a7f1ddb205562a0c84097c241a0491785a8080fcb0340842eb81908a282343ca94c6d38) -emitted operations - -big_map diff - - -storage - (Some 0x128b9b6b5677981632671b3a4200b33265fe75ac2569fd7613357b59dd740e2abb342cd40c3f7021972c2b85a4cc9f680f7e28d1c48fe5bd039569424c63eb9606e7199bcbaf81d3b45ecaee9f469a2278ce9b933961384a21cc547facaa61cc03b6424ecc1f5d20cbec956c93024ed9153c2c3862fdcbcaac5cd2e13806f6ae2ca4d3253b7f712b54c879e26dbf3e5807f58735263798c2c6bc07be9012e4eb586d64021ce5a0ad7ec6dac72224f7a121f2630f07a49e4ad438e359b72c16c8) -emitted operations - -big_map diff - - -storage - (Some 0x040323c862873989f4eb7aedcd6cf03d9c4e6d89fe86ab05767f3b10b988fd452383160f11559ec04b6ad10fab6765fa07416b61c915c55945811dec59808a3640b58243bcdf79cc7d8c5c7b4769118e86fbb5cd9296b6ea8b1009b309f33f6619c20ac87938bd643e0d8fe7f41a2f7fb89987340cc557beb9c499b7ae0beb651d13a16b55fed41e98e8118495d570e3165305df86cd00ab6b884471b0c89c2099731f613bdf07fa5b453fe47edf688b7e340f24aadef705903b4c0abe322a90) -emitted operations - -big_map diff - - -storage - (Some 0x05c66c2a9cd7bff629a8be6b6915f8cbd5b9b50430ad9f1f95ef83df93a289b14b0c069a45e9a3083c8091222e3f44e30b3ed9b7fbec7939db06aad0d5140c7c4933840deb9a514e568e2efa86a4ba835752a6ca91359f8dc20ac43f3fb30a3c04f8c1d1e302d37a0ddf2f4cbef9cc2b317ff16dd818725cb0d0195974992b14ee683afa06101db2acc697ac3f4202ef126995a62e8ae1dff6298dc9f768ab5a183d3a00cc56c81bcf3ab05c17087e66e743d559a4707b23c4b33f484aed3848) -emitted operations - -big_map diff - - -storage - (Some 0x03c9200acd88aa776039333734833f04c3673ef47f8e39ef44a98489a3683f6eb75032a6a5e134adab3b0c06931f444c10c4302c59f70893d23492c5ab767a6f60bc5521aa4ae879706b992726ce64cda1187e26ae2fd0cb3d05fcfa3e8f379902765404f27b2d4b0e22b20cc86a9ab7f0cd3f3f13fb6863ff9d4f26860c3905341d1a267a738e4385270f746afc93260fb6b00fe51f9a34c77e18e99d2c6e21c653eb82450e5bfb2d0d9a40d5e45696a1e1b4e32ea747f1e87500177b67e37c) -emitted operations - -big_map diff - - -storage - (Some 0x0cf8aec4898b6cf6698e74551deb9aac87a11dab50c7a3cbc69b2c4b4b230e9cab2290f2135fc365a6ed4dfaae5504821866a9bc35f182f2bc41a5bc2e4b998385e157bb9b7aab5b3722aa145b45681c85318f45a754c6c324b8ed3be1519ac013f476059991edef5732f11ccef162d314a7eae6aa22d8ab1d63a9d7207bbf3eb73021dc2f3562a7c69326de49e44470106e5429bda1ad096008838511176e879d4902b41cad20ac87bbc36c0d79d424e2a396893566cedfff341354fe901619) -emitted operations - -big_map diff - - -storage - (Some 0x0b9da9500e096383beb19b243b5d02ce37649b33f4e1671d649d8804552882fc1eee23f9fd522b022cabb4c962f73f0208e73a90df86cfcada188576f7f9d0a68b274aa0686402cd6b9af6fa0077d090c7d876faa1ff8222d00a8cd137ba02d31751a64a107ff326767085a8e486c60b604fa734c79935604869499ca2c5a79a8d37fc453c48cd18406e1486b7169445020494338e65c0db9bc80313cd0c4f8bb0c3d797e2a043652d5ee3a13e9ec97b6caa76b139d9e0ca05dcce3318a0ac4f) -emitted operations - -big_map diff - - -storage - (Some 0x091a244f18b87030e2b863c4229cb5e1afe53134e8a49ef8381da6f9a6816bd811cc485d0d9f4af8e702d2473367facc10c88b308cd546cb4f17a41ecf063b1326771b8b06099c402d787fde9f0cc13e837ca584134f725fc4d257ae04aa791d1100b618548b45488a0a0c52831f0f6252d805cc24118a8077d3985011d9afd8524d0dc630fd9c9279187251aa699bb308c895051974015232739452ad614031630ec533cae1f874210d39fda10a3cc34816075703b6e1c7f2902c6afad0518e) -emitted operations - -big_map diff - - -storage - (Some 0x1401fb979d3d7ba9f9b7464c12cc4b299242008ae161e00bccc6d791f8c6c69475eced6fd21f854e1f10e479af46730d08f0ce149b481d41e0862e195794d641337be00ad3ddc17eed2a107d6b20c8abfd109e0f75416f8d03059aa54e1b5c31170a0511c66e5557226619e6d0ddeb786b77fbc2a0e4125d37ed956db6f8eff7238e326d4dfe859f452b9082c21be1c60aec585dc2296b6ba5c10d91ab8235cfa1aa64f11bd5bab8bd9d929e6d0d86e8ce126617376551bc613366fd6e4ded1a) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[Fr].out deleted file mode 100644 index c7f2b0cedf60..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_random[Fr] - -storage - (Some 0x32c59df1aa60931c6fa6ff2b2d3358ebb570cc673b3519afec797a9a4dfd7427) -emitted operations - -big_map diff - - -storage - (Some 0xf2bff685b56f9e6f601d6a12abdf82db11d0ddf088620f605f873edacd48213f) -emitted operations - -big_map diff - - -storage - (Some 0x49c26f616a9483bbcfa389d8cf7fbe992621180d464407e757114a0804103f1b) -emitted operations - -big_map diff - - -storage - (Some 0x522f644c7566b3ad9445a0ac25b904b76c72434093ac409435d135f6e88e1431) -emitted operations - -big_map diff - - -storage - (Some 0x9efb69b24f277cbd42e5631c2e0ca566bfdaa9d27aa9608741b691fa01ce913e) -emitted operations - -big_map diff - - -storage - (Some 0xf0a71c2682cf211a1c325c530d0505eadc8a18974dffa4619e9b191050540c68) -emitted operations - -big_map diff - - -storage - (Some 0x4b18e93c841b6e6145923e527fd4fc35d6dbd6efba45745dd040a212a93d2d6f) -emitted operations - -big_map diff - - -storage - (Some 0x0918faba389d8ffb1b18345d62186f0980efd1724b792a9fa84e037513b4b165) -emitted operations - -big_map diff - - -storage - (Some 0x9806b79c2d171acc44814af407331430dc012ee27c5e52ae4660e8a3ea967242) -emitted operations - -big_map diff - - -storage - (Some 0xbeb8fa12abe52ffa9fa48d73d3c176a0bc3f8be04586f86dd456e3049dee0428) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G1].out deleted file mode 100644 index ffca597ddd9b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_random[G1] - -storage - (Some 0x0572db5547103186bdf2f89953627c1c6ee79da42909470ccdb2b3a63d1a56872fa3f3998a53af08e34f6cbbb5d2ae31134939f276ca6eed853a730194aec002dcda3bb02231e12852a23d52665bbb4fd4c9ca2060976768f294e3a651bdfa24) -emitted operations - -big_map diff - - -storage - (Some 0x19bf076ad1697fb06e3006ba85b7299a58da677178781306ed64bfec71f97195e0fe8e5bbf9bf9f130c27fac85cf0ae102f80edcfe8374130006f99a0415e7debe4e2452084af7a92ec6b32a3c23acb1e936098bde4e99ae33d5bd4f098189a5) -emitted operations - -big_map diff - - -storage - (Some 0x0f8a8b4f0e2bf9e5612e906f9dee13de3a4a86a78779579ae0931938c9e33fabc200051dca4c290d3cda64c46c22d65102bbde334d33cc4d9b77b220848ca969b86a4d3fc828ebff8c154f8606a99fdb6c12f8e3a936b7f717307ac66617c155) -emitted operations - -big_map diff - - -storage - (Some 0x168ff86947fb37c511c29b34cd5683045eae063d394d4ca6fb478be51fd0d51f02362afa2e5b829e161744b0cb44537009da2ef5522ecaca11925bbca35be447402f2385fdb000647b0f97fd957706ad54a89dccc9d91a967fd7d3245699ce9a) -emitted operations - -big_map diff - - -storage - (Some 0x132714e690347a4818aa28078c04a9fa00af5a874f6e384b3c10385edff00b078fdd9b2d24756216cd221fcea02836061565f5e4903c19654928de543888be273f11954cfa069ee8b7b28f1501d723b5cd53a070c99976789683a9ba84ec3f88) -emitted operations - -big_map diff - - -storage - (Some 0x1160d2c1a9468460987e83389d2b14e83da2203bccda6af5698088fba85a70b0f81338e7266f1d2aa35c0c9fd90849cb19271f959b22d25e9d39be01e81ca28cbfd941681141e8494cc53eebf0fed66cf1d9c25cff0acb79a9c8de89978d665c) -emitted operations - -big_map diff - - -storage - (Some 0x19e4f619ba2bed08319d9c6d8233ac67992f979a09c1c2b578f6db33160da265453b6534404273f58b62b465081f177a04b2b5742855d0273a9a4b285040d806ac3c9b4222967dda1ca5b15b701e1cd8ea6d903ba3de1d4b772edd312f5f0e4e) -emitted operations - -big_map diff - - -storage - (Some 0x11cdd047200409941c0c76b6d3bcbd8e213190b4a0129a7bca64383d7574b41465771ecf903dec7f572dd4363595be400ca671f579f590ce3014426b45cf4ad91eaab36cc69b4d594dd60c3521ef037eeb4ecacc4449aa71f26f434e35a87746) -emitted operations - -big_map diff - - -storage - (Some 0x00b2274f474533ac0db515a0e9dfaa821f5da4d22602adc3b63757e0258b237710273f0385067c920250f3ac93e58c5106501678f78b7248129687c46e47737e9737cb4b57bd37495b2966b61239e5fe91946d65c19f948d89a2905f23ba4b33) -emitted operations - -big_map diff - - -storage - (Some 0x02469c3272ed5ff2685c19feeb227f6ac7fd45eef79266e78dc17bc53930ba5b754f94ee6f07c28a0be5f7cd63ba616c0cde39bbdb8e3add322a8d0ced1627e2601442dad06a7b1c0fd9ba9e08bca8866913f0336de0075564dad5ecc63c6cc7) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G2].out deleted file mode 100644 index a14878b6a203..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_random[G2] - -storage - (Some 0x14e6a70d1e489c9feeefc7314994b0207da500737728cc2cd17919ed6d5eae570622815ee576563c25075fad12129e900b9764ef6332c435e56a57c1a46b1c427889456fbc01b6e571ea995e925337e6cdff2d062520c61c52d2377e773ba34e08bc7961bb8618eb9951954ca98d01eb69e56e04d16b7a2c21d8cb74ed0bcef735fdc43e6939c4d4194958ac1d5f70d41407d01b8bf34478d970a86af954f0ec67bad1a95c43ea118b8ae2e9ad7053cfd92b0058755e4dc1128e4e17476a8653) -emitted operations - -big_map diff - - -storage - (Some 0x071616c0847497f2acd699cdfa848cd50527971ba6d99ab2debfaad23f658f233c262e78e4f841e4e24b16a981b46f5b13b2de1c75de619374ce4715cda6598b7603c474f4bfae3201e26ec1a0ea4dcac5bb859067aa907fd113cbb8e12eaba0099bc61dfcb137a7978464d2c4c2db5eea9dc673857ad8dbacaf8a30156c2495bb0f09dc5e6b66c9b9a5245a5dd99afe0e9f735ed6682f0d92af05b3f965697c1e8f4ee5aea15caaa6e6905db608aa78c788554f1d63bf1781322ca089a73226) -emitted operations - -big_map diff - - -storage - (Some 0x0bcb3473d903308ecbf86e3d7339f636944b30ae69b693ee870ce4313dc5c678a8e3efc782df3c143200fc9f9c74da9805e4d15ec9fd45471f05f6a89c234b4bb353f5f0b59ff1c32aa0a53e3cb5d00d2f1a4bbeb26df8feafc8c6eadd4271ee0a479169a73291553225df03876a1cf264fe9fec6c1d7abb9498b6e9fe6f68373dfb11c897c8f4587bb68a73348624dc114b4430ca48f9e93c2ffdba64d0200b6213aa1c30dc5b8ee1ada58f7d8f17209c80a0638dac2d84706bb964d5adc810) -emitted operations - -big_map diff - - -storage - (Some 0x02bfcc6cedc5432b3094b3c3a07f4f5605e396779c996fc4451a148626994422aaa2813f25e971377cf4a79199e6b64c08dfd812339542c370ab0968994699fe11be923f5ffdfafc489e92f00aa3e7b346c15a216f4756318f2e275c1add44b1184926b94b03ff641a4dd7c48a62a8bc95db0e10051542e64838e919936b1dedb53eff5aff762504b52e7d7f29038b9807052c826bb33a2a63a23d97f1ae4631b78597169d5a8c5c7b44e76a9612b4caf931cb991bc50c400ca2dae41fd284bb) -emitted operations - -big_map diff - - -storage - (Some 0x199dae008159f71a8766dc2dd36b38eea3cc4570f53c5a75e1c634104c2de1fae8d08d82d746a32620f9fe735e1167c20dc0f1f29d8cb8c7003a0134003fd6bedbf06e3ca40163ade57d7c58134ccd178132839a421a0c54e4e3d7f1f7f6f3c302b2e86c3571aa93f060ac296490439624e0a65c3793ca193d12a87dd59d9db0ded93cb48dd1bdf2c253d512fa8740d40c60c89c6f6f3d0a1e031e9cb792c42988c5fd2df05221d44f0b98db56fcd3fce8dc52f7aac73e65da92a97edd38b871) -emitted operations - -big_map diff - - -storage - (Some 0x057b2871d7a164fd1ff36b65aa26203e9ead4073db80fd3e65cb11f526c3a36d04fd5d42d77f2eaf8ecbd87d31860ac60702affc28f09199509f4bcafcafc555e2924dc7023af9663d5e2add1febb92f274f7712bd50773cb3c21e058e06842911a67737914abdeb318d01a4dce9de50cff14a385c919d69f2b6dc9a4fbab82e4bc73ff153379aa09f44c9237c28a97b194536cf4ef1d033722ee02f2da4fdd2c22c6aa5876eb5e4632f57b86c9a5b1a750a6ce6eb38a21c9ebbad3477cc5081) -emitted operations - -big_map diff - - -storage - (Some 0x0f560f66aa318954f1a715277e07586e66ad90e4cae0e3cdd99a927c59cf9dd4fba60a1ab352ce417440e078116f8d4e06102984b8bcad27f90712873b678249ee83a01a30b0a8feacfa2bb4b068fa0f0342ad55bd269bdbebe7c5cfd5769098084ea794e5252f7cf5b0fd10db3a17f5fef9c3df9418109b9a269790dc35ab83821d39cd373dd26a60fcac49f57f1372111b5f5e8bfc1c2c921545561a541a1fd6f3e7b5dab870c16ffa8c41a8d1cc91d148f99700e3968e0cbff2f74b4613e9) -emitted operations - -big_map diff - - -storage - (Some 0x12d73c3ffbbb0e5135c89aed8a0bb246ac94ba2ffb79fdf103a7c9e71bf09b67fc928fef16c4013b45b963bad15e0e020c0635fb75638ffe385e578e06098e1ea4e5697a3850fc31f888c7ffc8544c4322ab5fda30c34b6959636ce6db02998b03c35b506840723cc3bc4788c47e64ad00ccf727581c76898bf1b331860ead87f9984965c6ec515f0b2ea1bc1a1aad1a0e9c8bc1799a1777a8acda5dc68ae83f7200ad998be79c35f252aa1e427c0b51c9fb463665acb7e7678797a0e0677659) -emitted operations - -big_map diff - - -storage - (Some 0x12f203deaa2a60bb330227161f38c0104c92c1598751bae6af52102dbbd6c9c4d2ec72155b9b4363d90ec83dc7f9a23a0fca208610b342d53abf1d5729ae6e39806844a6eef99c0df4bfe6eaa8b1216c0dc9e4d9f6c4d1f7f8a323459aabcc78184bf83ce121264be8e3931e50275dccfeb4318b1d6a834fd3e5df9b0f33748ce3e88da3bee4f3111f3c0787ac93891c073e576342224498c6c3fd5055bb3c33a8165c56dc6829261511b573401e707e055f9e43b1f29307ffb9959fb114162d) -emitted operations - -big_map diff - - -storage - (Some 0x1636bb0aa543964f7b8b5eb9c79a168f4840befc80a40b98716f5be1c85587c87d541df53c5344fc43fd59e7bef0192e149733e479d7e718938a4da503972a834f9e2b725430a3349f1d8359add70c286d912d26afdf0bf9ef72290cce771c9e11bd93d75a681fac52f10efe82c86b2a6e08a154ccdf56ab2af2c199dc9519ed94bc7aea2b2afec5cba663652bc8906c02c0a16e0c8d7ccc739dd4e0939dd5438ee244b52cc7cc22b3711c5738ee6a110442a7a75e8c5324b2e0a2c9ec61c475) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[Fr].out deleted file mode 100644 index 0fb71f1daa1f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_zero[Fr] - -storage - (Some 0xa739fa15d114468388738a042a2d5c1697ae01687088c0f12b1a9aa08e8d333b) -emitted operations - -big_map diff - - -storage - (Some 0x90d72fcd8feff9474e2e54b4b9dd25693f4165bbd63e9fb1df790005841cd138) -emitted operations - -big_map diff - - -storage - (Some 0x1d88e731f9ace2515da1c8a180a91edc5a582ed1c55d4cfd32eec3124afe754c) -emitted operations - -big_map diff - - -storage - (Some 0x239754a5133c74f2cd2e055471a52aad9bf61d0cb8d87c1a145e52fa4b623471) -emitted operations - -big_map diff - - -storage - (Some 0xd96f5c434bc636ac77a076276cf41025130b480175d4ac3b89b492fe8ce02a59) -emitted operations - -big_map diff - - -storage - (Some 0x55da36ff0ab31698692128f58826a17fe737a5de292b3833f84f6b2dc088be48) -emitted operations - -big_map diff - - -storage - (Some 0x8aaac27a92aca48439a67deb4f7d04a291eaf8df409a966a5cc5938a433c8e46) -emitted operations - -big_map diff - - -storage - (Some 0x75c6cc6c226ce12140160f0740499913a5c2c4788868273b15dca2bd7a6b6837) -emitted operations - -big_map diff - - -storage - (Some 0x800a55193f60eb4de95f6c29ab095ac4f3f1d21a1e90096eba89c4c00f2d8a31) -emitted operations - -big_map diff - - -storage - (Some 0x995fdb626195b85107a30d8d6106e7d8c46af3c8f3f6be0bebe198652d2e6c00) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G1].out deleted file mode 100644 index 9e6952939b3d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_zero[G1] - -storage - (Some 0x0e134832be250ddb5839670997abb5d7a89811c1335e7db37a321efe001c35422abe6a14ac850eea1acee01cad17c0330c5437362450b8d760a2d1f0e07fb3dc465a4ef1ceb1b026e6314e5a53a7aa4e7c8e5fc77472c691498680d465c593c9) -emitted operations - -big_map diff - - -storage - (Some 0x05ee99471b023ea35057440bf490170def6356133c85549b45895c0a14f45e450fe1fb44305d57a417461cef5a7132ea137b46dde47bee6177d3300341999d6d3dc996d19767d8c30b8b8425b34230813eda03d6db53f8f2b5e2ac99d0d9aa4a) -emitted operations - -big_map diff - - -storage - (Some 0x0e8cc3b0289c1ec90eb49b97da831d4d9bddf1d3ed02e26ca7328ad618945ca288e736aa7c7c06e59ddd34522765eb5f02ca674a5dffe0aab83d25086876d5a87ebcf4d5903125a8f5c637f9ae0618a1f682d5d18c0bfaeeec866c2dbabbe41b) -emitted operations - -big_map diff - - -storage - (Some 0x16fddca3f0f59d49ba43f6861d71d8f4353f6d43899b14311f4914987ad0fb359cd4048b9dc8db6378e302107296037311ec2289dac6db85e45d3dc93673eb3104711664872dc931d4cfe6fcc6a4afded609a738759078d371b5538436180f24) -emitted operations - -big_map diff - - -storage - (Some 0x114f5bff07e03161a9c9fdd20fbb672a71a9aebe2c187e821d4005129278d5d5c195926c7718afda76194b35943339a00efc8c4c040e9b1dbad9ed20768c9c62e4dcdb680bc0add60b218bb42328a116d3e43d579024dfdb4df0f1f0c016d8ec) -emitted operations - -big_map diff - - -storage - (Some 0x0cdd83bdfa776066c37697324ce0a444d064ebb079d99fdb2c03e63563030f824fa95bc7e1c10ad14cd6362857e9a0010073d89e5fae09c29ee2d1a6e8770f7c5a19be2e2e465a50539833b1a463e24d3ea02c606c5990cb8c892200b6e3ec55) -emitted operations - -big_map diff - - -storage - (Some 0x05a3fc74d5c1f3a883631ef0fb7bc08705e85b62786f2d61560ca231e6f7178d10d6c9a97ff5ef4218046e66f9142d1314d8e28bbba2db0f505669a31b4ccb4cb08aab73e175871139b2fff8cf687a0affe2463f0cdcc88f51a4123434533e79) -emitted operations - -big_map diff - - -storage - (Some 0x039b2ab4cabbf7bc5d0851aa4034d4e478e6350a6508d54fe37232e92e5b673ba1bc14db53ebdb317493c9fb3089a25f0ffb75f9a4da47eb6e54be326a07dd56cf8b57a52d49892669f79922569eebedd0848b172deb497b959855b85d66a8c6) -emitted operations - -big_map diff - - -storage - (Some 0x08fe5a710347c0b1a5f1f61c9268778af2611a42f883479e289f1ae28ae1c15408aef3943b951c8377b6a79faefbfbf2150c7fa5f938156c3d8f27b7f5e5143220f5e0752d762ab54a53d9178f4112eddebd4daca6a585cc469be1ab4f5d5ca2) -emitted operations - -big_map diff - - -storage - (Some 0x00d471074aee131574be07c9b749d7bbd09234578fb2acb4a248e6583564b341cb55f2a2b61a227a093a0dbd4bdea67f190a01cd3614435914153e782cf7332911ad79c48a1dbcb8072063f834347441530091809be2c15692b8c0b98ae646bb) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G2].out deleted file mode 100644 index 240be454e6d0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_zero[G2] - -storage - (Some 0x131c7f76cfde58ed74ce8c26a4e9c6a6e135fcee1a61a41e5c0f2f33a718d6bfcfb7de2f43d98608b68dcca040c217a6007c5a33c5bb8d523634469302348d23df90d150b28e4f41f1539afa50adf951126233146e4dc98d21a0de35312571b310696279b7105aa5830ef3cfa6df1ff1379f17b24ab561c899e3fc830942e23a4b73019b1ef5110baa4068ba2e8b4c2c09e3b16b0894333f41eccf24b96be85a0d17ef071657b1abfd6fd0e7878aa55d3a5446a9c0ee5b5c293ff8d3cb4722f0) -emitted operations - -big_map diff - - -storage - (Some 0x09de05cde8a5a7a1328aac8335bce420aa41f1077e3be4aa51f93b3a8e822423ef67d263d8042a65bcd89e0091a6b3dc03727a50fd6fc80ed0b1078e81560e759b8013d48261a2cd0e65bc83b9a37cd8e952bcb6a63e5c9ac016d7d588915e0d0fa9247132b7488528ee8f136bc9026f8531c5baacd1647a768bc801e726200b34fcdea976e82d1633e1da82a36cec580f8f3e197860bb36ff010e747a361c54f11003d33b6d3c8c29eaa13be92034b2d9e04a1b6e81fea1911fa8c8b1010b8e) -emitted operations - -big_map diff - - -storage - (Some 0x11d76ee03154c0ee80237e9d757e5fc6fb6f0dff68032489db4edfa4a79d4a2ad8af5854d1b80e5eab6046d236bbc97b16a1dbe3dfeac51233c05fb1ce011cffa48dd38b052ff81783cca048ce5d7c44743a57feceee2512aeeb75344fc0123a18459f774f0e6474bf80a154a754e3abfd281dad0a967cdbfe25e98e8d0a22a41c41f0822fffcd3d92a519b40d48f9b109f79370c21568150d9dfbbdbb3187605e4e675280fdc6de9689de0c82083da87a4a776efad2beeb2b2a8e238faf0543) -emitted operations - -big_map diff - - -storage - (Some 0x056ddeca0596e44d080a38cb233517d706f5529482d8e7cf5618e2c1b17222bb3cf9627173a05ed34c19e925244c775d0bae3e10aead5ef97474d420845b1752c054222387e5767797f2ecbebee3f002e930c7ecc666719760a2a7625590d2261360cf5c50023104c36e79765707275f0517283f1834b3b378946f48675459342b701b5d421af115764b639736ec666712e9e21a5028fa9958afb36e610e74bbfe0db03a3147409e11b2d12e45513f0ed91cae918ab723773aa1d16956754b7a) -emitted operations - -big_map diff - - -storage - (Some 0x016319cfc0cc2f9682f2171aee2448828d2dae206cd4eee18485d4d528dbe42d91331c54b99071c54f60852279bee33408843ad79e654427d875c5ac932a82596e88bfd0ed1e7bedeac67cd6d260730a1bfdeb7ee072c10bac1536b77b89ecb614f3b216d3ef4cbf7d12fb26d61e5e3b50ef7fde0ec13311606c55ec631935f5abe99ffced1ff1879df289694091866f088752642b4791b742acef63b6c7068f2789c7a5c37c5b923c9f855deeb15af919537ebc700f0754a5b3cf76a4aeb585) -emitted operations - -big_map diff - - -storage - (Some 0x0487d5eefd82485134b6dc3eb070ad29f24b283e66b21b7ab89dc9837833d577282d6886900daca411e1251851c6898a14540427013fd1777ff4bc6caa17c499b45714fd944c23123c21996f08ddf9c841be93bbc3b427f3e97bcc96f0d2dc80076e1cf2b08d1e061e5dc05d04a9700f0f498c55740cdb07513113481cb2be4ec8b2445c06207bd49199f8784321e3e6188f33ed153ccd194cce9574678af873a515e2fc683d1e949131ec946e212e80c4b48876ac5b4329ebd66e30c3e64716) -emitted operations - -big_map diff - - -storage - (Some 0x1825a997ebad0d60dff12bad0b182818c5939c85bb90df49815f161f160c34b007b765d5f45bf8be5714f5687e8ed52d0067d80904c49cf9f9d7a6f6b6748ef1722a4fe7e5c3ad6e4535188dab7b4fd756e024bff36798349a6b3796d4e0eba00e4a44260a6527af74bc062df2fd3d922b04052e654483234d944edfa3e81b9432d16b804deca1690a2a6ffd276fda7e0f427e3315cf2555c0d3d146715393a24939b0bf36d6284c672a212f7e7902ee2e873281d396290bf26af6b3a330f058) -emitted operations - -big_map diff - - -storage - (Some 0x14fd9f5cb51b90075b3250c91c45be2eeabc425584b7b451539f238c191ad58c6c364020ec6a8ae1810fcd6a894999da065bb45ad11327c28d9bcb1fe85d45b10a2e42fbb1f3eef622a8c261e52ae5207840c8805fd2b8448c7f97aaff8bcb710cba0f99825e190b5de72f359c21058d3a17a30799f1d1552dd1128aeed5ef96ba586e62fd71a004cda332362df3d70b15816951c6070599f40ac6a1bff7d8c21744f00da365ac6c2b81e7abc752a01736e089226911da70e7b908a130af37b3) -emitted operations - -big_map diff - - -storage - (Some 0x07c239bc8ae325e0ea294eb2d7a8134c9986099cdae78224b2326f9d419769b065570154776fa16b98c1b5bf2f69eef41403ed7557754558c686ad6c00cc61b386f3a2a8185d1738e9c6ff6cdf9353ae1a30265ed02828a2979de0e8f10b15d3087901b1d719a2fdf367564719fb05a9196c282f244ef434090e39ff091feb12c45c117c2d68e36e8bf37aa7b7847213110f3424cea97cca09e3939d418883ef7f394715e5448f833fa0ff61ebc8c9d9fc5ecbe8d2480f4955cda3097cd72289) -emitted operations - -big_map diff - - -storage - (Some 0x070a718668a1f4e692191f9a7653827f6051848cfa72df0c3e99fcffcdd9e09267f8e6711948b43565699d4bf02feb0f0faacfa8e44cb5c50d2d07a54c811a0fb86a1e0f565efe32ec11bc147ec6f8073067c6330afe0c5be6ec5962921f58bf0b97bb667d15b6b0596cfe29f41fd994c1ff7332dea6699dd72f828593485a97d72f8322ba503653a6a82a42dfe68eb9166bfb6fe8478bea584d01d252c7e256bbae17b371a8bb87916ddfdbcb28ebb7f4670ce1dd3be5067e38b0e9c9f17140) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[Fr].out deleted file mode 100644 index c0a6f8b6fce7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_one[Fr] - -storage - (Some 0x0100000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G1].out deleted file mode 100644 index 67ca0a74ca9d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_one[G1] - -storage - (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G2].out deleted file mode 100644 index f8967f511039..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_one[G2] - -storage - (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[Fr].out deleted file mode 100644 index 361bb212e04d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_random[Fr] - -storage - (Some 0x6b1f61b3ffa8e49f9a840c0f4114fbc6061bf98a51e51fe4a396f041c50f5e02) -emitted operations - -big_map diff - - -storage - (Some 0x0e4c13a518d43c1a04ca2b7b16ca21d8f2443a861e7b6184a85cee5892916903) -emitted operations - -big_map diff - - -storage - (Some 0xa18e92f24830c77e59167062c6e8b22c08b86800c498b932bffaccb68fa1b934) -emitted operations - -big_map diff - - -storage - (Some 0xa91c486e8bdcba53453336ed752ef9b214926a2b3ab452552a31eda0ef3cfd3b) -emitted operations - -big_map diff - - -storage - (Some 0x0b9fb344957ac93904848f30fb9c068ca7c9cbdd6006445489226be02676026c) -emitted operations - -big_map diff - - -storage - (Some 0xdad4e76170b71edf3c7ae65a00659f332dfa08e9d2cec5a632f8100cf938ac62) -emitted operations - -big_map diff - - -storage - (Some 0xdcb9d72844fc8c9d4e25acafc2c1945f1f8b0556817c333f0e6c0e5c932f4c5f) -emitted operations - -big_map diff - - -storage - (Some 0x53745aa1b2b2734a0b038307fec0d0f20e6ce9d512a4ccca1ce49dc8b294b93e) -emitted operations - -big_map diff - - -storage - (Some 0xb1cc9dcc3ba2a71687b388d23758da47c067e1fa6f0b185fd5d39b9050416a12) -emitted operations - -big_map diff - - -storage - (Some 0xdad6443c3e503dc862ecd96031f0f5c40fc4560b73313dc153bac7118338aa14) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G1].out deleted file mode 100644 index d43d9901b55c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_random[G1] - -storage - (Some 0x043d39d06dae5a1faa8e462a13a7254b8ca438e47c7846fbeeef71e44379e7df2e29613e18d658ab0da4547b4f3852590831612b23e928a01f20857216d823ca7c5e07fbda46923ea626380c4c95cc2046b9b228ffc599eee8ae2788484a1e4c) -emitted operations - -big_map diff - - -storage - (Some 0x05b38be001d64a2d9e17a27d90e29b9f8f8bb28c7c8720371e7f72612f0306a97162cad563ee5af54df372c89035a2830404865f74dde79ccf6640806f47cfa66373656335a4ad64cb383ee44f339707678730d141cefb643ae5a7ca36fd2b0f) -emitted operations - -big_map diff - - -storage - (Some 0x0f644fff548f117895a24c9e4345c4dfb995caaeb5a01c1bd8092677f0dda287a03d7c86b0cb50a61739e21a5950de540abf3818624bd6f162d808aa8ff6b9993ce584fecf10d3aad86ef521545f2b5dc76839620e52d27f42fbc7d9e548b250) -emitted operations - -big_map diff - - -storage - (Some 0x0dd72a72f8dc7d26d4f54ce50d6bac81bad784cf2b886d5d2ff66a06f5358e945c5c70b81693ace7d21e6fdf8db436820d5f1d73d015e5799f7fe9a1e4068fee0e6874f3e8c56f85f673e0b1cba80511b1f4bbc02d8461b2919bf8cdbdf9a051) -emitted operations - -big_map diff - - -storage - (Some 0x0da1488962b00f17e629884dee4f153e0a717af426bde7c75da0f5067ea5e63297ba068bc230e5179081af8a23c5d5b618f5b3bdae5915cd2724687e228a4c1843578a0c2aa2297031745fc1f3b77024851cad2bdb815197fbc1d76e7dc17e7d) -emitted operations - -big_map diff - - -storage - (Some 0x153d1e9eaba3bb00055584ad97fe9b49fa83bad011d1b97598bfac9db9c54a8ee0152887ddb42d1d46ac4d4ff97da3210e5d38c8b1f74d70b56e94f953a289ca8604fe6731498987c3bd186fb24f569a0c403c0173dfa6765f1cbcc75248547b) -emitted operations - -big_map diff - - -storage - (Some 0x0165ba92201bc7848e74e23c842141407b407f09ae7922e01a290c4268579c84f2a3bdc20a8a1005e9669064ad2e634405e460b2eb3026d92cd2833ae7d1f5a009756ac91c58f2ca88a358c9312de31f9caec97acad38cdbf9f1f8c844ec23ee) -emitted operations - -big_map diff - - -storage - (Some 0x02bbf3966383231f6c0b5a0fd62240867a8944331afa0c6d06b5f1bf83d3c2eb5a37edde3f51860afe887526e343fafe007cd4b0abe3d4868391ccc730e997525108e17740b0edbed0d1cc15bbe411f33e35232ae16e79c77b6acf22ae67210e) -emitted operations - -big_map diff - - -storage - (Some 0x0ec1ff5c67f23f47f82e834bce1d48e56e76b78f42d7ee530e660718c3cac29f207d58aa4c231376f8a8ea4951f37d680991eb20bfd4c9033acda6621b2861bcd983a1066f6add9510215cfe0e66485e6433331232d37d944d1cb56230727b1b) -emitted operations - -big_map diff - - -storage - (Some 0x0b020051cc583ef24590ef0626e7bb42d30556013f5b490c78bd1c689c759e04e3865f04b6807f9b7a52e4f4fd23a4a70684f9d93f58388210075b8de217efbcdbaa41c4c7126dc925c1263d36953db065b15d7fbdd248857651db0f6229ee89) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G2].out deleted file mode 100644 index 29566bb593a4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_random[G2] - -storage - (Some 0x0a8801dd5d45269185fef3af4c71e27aa302f843c4f75ce58267d5cba2588d63e240629f85cb551fca316f32709a3c6e02487c3309ffda4098b64d73d16074121a6a8bd6ffe89151c45ddd7381e05b7243db96e4f6edfa06c57d0bb0265b20bf03d1c067162e0dda121fa11b9c7dfbd14a027f8b5af1630ab703a146b9a5ec97e820133a732fdf0f438814a693e77a820edf72b5820459bcb682af727b7590463ff39b863dffd2a9839fca3f6530b13942c53a5ba928be5b039b125b88716729) -emitted operations - -big_map diff - - -storage - (Some 0x0afc630b73b1d1b407c89c797f07acf80710dfa9ce57b46722e7dcb8a43a847341372d2eedfd6c2a3c42305306ed468512fd95cfceec1194d749b13948f699beea5b33aeacb902d2e12a2b65e9589c57d26251b350edd142cec634b23a7318bf1553647560e99b285b82153ba4f70fb7c3f494fe5cb65c0b7f1446adedc646d14628f45b4b8d7a22510b8551490b04cf0a0103d13a5deb5d68d32a85189cccf1134dd908da9ea8ee034d067f729d892bad11a45113f0e5f5ab25c021759417f2) -emitted operations - -big_map diff - - -storage - (Some 0x0b8026c50e2cf76e4fc00cf25ada386641261fbe457250746098edbe44d28eb0961b4f4aa7d3d3f65e0f3d0d92a131ef17cf0aa479c55d0c529b2ca05b8488adf9dd829d91f0bec387c5e91ff7082678c6e76a74649279bb327f3a4f3cc73d80104e0f1880c6647428a0b7a5883214cb46255a49c13cf4d8106818b782078ef1007f7e34790535e97ebf8b1cbf3b723317b7223c824964da23c4b6bd421a76603c0dfc8f2779acdea5cdb721f71dd9fd44f9488ad519057def31360c1673e5e3) -emitted operations - -big_map diff - - -storage - (Some 0x0fd3a77a6a919626d31505fbf7ea71d3f60b78dffb1b7232c1b3569dbb67381aa9df4ab99aa25934912112b2b9f1612004b3c9f71504341d8abb591f6d7ba5b9309217467d332b6ae66d634937a112cba73009befc554a2f9c6701d65a29e8cb1525e405ef803bf935000e2b0ed5b7ba1106dce0369069391fda557b7282e7ca77513fea88f364dbfb17ca9b9c308a860760a41f8268069fe3f9f84002add2e2e14b6a4497b3ef826fc885a633050c1d9852e942006aeb234d2944e17a5afc58) -emitted operations - -big_map diff - - -storage - (Some 0x00ea54ce4ab2f8cea7e6f172c249638844225c5e72980030f45e5645680d9f2860ff22d0310d7e2a39b70b2fd2e91fbb099428b8e20bc8895f9e9308b66c8afaaa06f1bea33ff8dd55524d1206e22278e1e4b23aa1eda324bd1446467a995f400fc4d7ab9df219f5af91a3bab904077f36e25450bbbe708f5f4d5a1f0fc3383af24a86ccd3f424bb1acaa65015c0fd9e0e5020e8ac03981166b9ced9b74e0712424e60950c9a774daa4d2677290794c5a34dad95b9e6123d83adb9dfb84acd22) -emitted operations - -big_map diff - - -storage - (Some 0x1667ce729e66b328dfddd67b3308183f2adba83792b637a9d6a54ee5c520f4a84b6d4446e906650ef19be90956246a12109589b3b1c2694b39d3d5ab8a3d2570e70b15a3ce81fdf28b488f90fe54809069b3143faeadf4392fa41b0178382e8e05579ff476cc9290b1847ed3895beebdc1c2fa106cc097ad369d2652b57feffee233a9f8e879164a649e59b7cb22fbef1252d6ab8cf8376f56df57627a064a206843d58ea6fefb53a07088c93786d13f47a91a07839b58d0d230598709bf12eb) -emitted operations - -big_map diff - - -storage - (Some 0x042c1082a0a914a892b975934ca4b161aa2b2c3d45600fc565d71047c95b1e6f0348534309ca6f506f74f1089187507f099ce83b41b120cd8b8d7a6bfec0cfbbeb90a5936ca9dd386e2335eb8c12f9a84ad4ad2a1ecf69bf05427bbe96482384112b2326686e63c03d9f3ded29536fe476366b1ec177c016370ad1b21c93970dfe04779be2dbdcbd1a306f5c6ca9f5bb0629414f83ae3549ab79ee283fb0be885a9706355efc1aa0d0ae6243118e7ac6cc8303e68d0afeaaf6add5d41caa7b57) -emitted operations - -big_map diff - - -storage - (Some 0x191f9cec71fc06393c562a77e79041f3851837dc39efa4b458bb55b6f89e15c8fef9dbadb3f75b4b9873c094503742210deb4371bb8293c102c122bef0c8972b6dcb4f9add18109234c3b94400e3e5ceb52f59beb33ca036c89bb60ad7b629e80ffff89bfcbc65f23e1ce932cf2992530fcb0056901ea31cc425585fcd63b444e2ee671eb7109b0978d23a19ab468387087dda6c1354fc4b645d3f0a6975eef41ba75a14b4450db71f4d899e71d4fa7a52b275b06e1ffdf36f539244c69654de) -emitted operations - -big_map diff - - -storage - (Some 0x091703cb9cd4ba012c631f8be02f949e9c488987c6144dd8a1660a4eb65a41474cac5edeb65824214875ee21298fee01083224b8cb2bcb353c47a796567b823aa8075d28e9e8ed55895dbdbfa8efe589c8c58218308bdf4d7737b27b0c6daeae17b36d402a7f7ea148c3fba6ec80633d64cfce6b31d055bff659b875ce0b513f4bbfd5e79580f1a5d896e551f082ef3912efabf6b0dadbc53fa3e03aab4817ad547fc2877f4850ed5861e37ccc29115c203f6c92154a84f898ac1fce677f702d) -emitted operations - -big_map diff - - -storage - (Some 0x0ed6b993962b955b8fbd1b7e7207ee2faad1460282274305837f89ed9081a405ad1a088f9d46487015b082db7ce3c80f09408e6d2f2e02868d1be1dcf067c8143a887921dc7098ef4c116800562a2786611a65b437ade3db1629d5eaf3b8eb56199fd734d8017287f5b24d4b4f0afae0cc86db7e751d2e1cb25d06f6bb3c7ba69c3b5d94a6913e9e1c8d870fb1a4470a1864d95b7519f8d7230465df4fc23e7f08fb912a467496a58b024b0e82ea5b8cac35aeceb1509db29b2f5bcde0c2d5b8) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[Fr].out deleted file mode 100644 index ec813cc3434b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_zero[Fr] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G1].out deleted file mode 100644 index 749f9cfc630b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_zero[G1] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G2].out deleted file mode 100644 index bf26d720e3d5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_zero[G2] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes.out deleted file mode 100644 index 79fcfae9c560..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes.out +++ /dev/null @@ -1,8 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes - -Invalid argument passed to contract KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi. -At (unshown) location 0, value - 0xf7ef66f95c90b2f953eb0555af65f22095d4f54b40ea8c6dcc2014740e8662c16bb8786723 -is invalid for type bls12_381_fr. -Fatal error: - error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_groth16.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_groth16.out deleted file mode 100644 index ab42c9a1fd0a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_groth16.out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_groth16 - -storage - Unit -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[Fr].out deleted file mode 100644 index 7a8e5e9d8a5c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_one[Fr] - -storage - (Some 0x0100000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G1].out deleted file mode 100644 index f49cf663fe32..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_one[G1] - -storage - (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G2].out deleted file mode 100644 index 017f8a53bdf0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_one[G2] - -storage - (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[Fr].out deleted file mode 100644 index a1fef32cc1b6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_random[Fr] - -storage - (Some 0x3a14168aa51fae4ac33e62e94267e61ced8f00785e295c9c7125b881afbe111a) -emitted operations - -big_map diff - - -storage - (Some 0xe842c1ffe3c767806c91f42120e27cda0e3578a1c52c53e1b33a65cff1e22b1b) -emitted operations - -big_map diff - - -storage - (Some 0xeafb8e3cf1e223497893cdc3130c6c13aa7d3d3e6a3502034d19d3ef4a39ee18) -emitted operations - -big_map diff - - -storage - (Some 0x614e3f935e4b1511d8b63143d2a7e3bb2235c5f1b1a8597f44347c4ff1e7764d) -emitted operations - -big_map diff - - -storage - (Some 0xb34999b9256eb7205c0303553559e8b14668241277fc207b21ec9aadc4451a1d) -emitted operations - -big_map diff - - -storage - (Some 0x307b86cff0794406b7e07ff937fa843c09a4e0dade758b297e39569dd41c5b04) -emitted operations - -big_map diff - - -storage - (Some 0x6322ae545e19b2b35e4649e021b2025caa9df47de27b69e023c71e349fb8643c) -emitted operations - -big_map diff - - -storage - (Some 0x36d7ee80fb7f1e6bc31f1384ed67d8c5b195f4daf6ca413e64703cbc4e9d0d53) -emitted operations - -big_map diff - - -storage - (Some 0xfc6cd59996ca5aa047bd59b6001a43e3777d9b19ae65de6ce8c2ef7f52cf1c4a) -emitted operations - -big_map diff - - -storage - (Some 0x6e9f624533c9bed9c971db028e9bd5ad034d25d38f1387b090a2cea2685fcf16) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G1].out deleted file mode 100644 index d831458dc9ec..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_random[G1] - -storage - (Some 0x0e3c67b12372907bb20da67474058dd766c165200d525b1e0ccb5ff5e3f2c8ab66ce557601ee6f39a81d7f89715e350303ca13302a0866206377c197d62d8e5149dfe3b944179af3646b886a0bb16b89e9864a7bbf89f18d1177c1c010213e4b) -emitted operations - -big_map diff - - -storage - (Some 0x1627a49ada91f905e37da3cb998e77177177866dfa21b714e8e60a969d993dea22dfea1468ec27bb502abffecd297af208a8954ec9b70cce4b5f045e9ad030e1e3a9e822ba31fc9ecda63f7483ed87dd251c117657f331ed316161c22ebd9a8b) -emitted operations - -big_map diff - - -storage - (Some 0x0044c4f40be86203e6d9879fe49fb510b1e40b1a58e26db3265f5c62b49ee1311f12f1e8fd034be3f4027c1a5dcdf0610a721358155dde11af7e315a1246f483973321095593a72d236149904a4761ec3134b482ef46851052e78e24fad5fa2d) -emitted operations - -big_map diff - - -storage - (Some 0x140bc58ab952ed42a4fd28fef1f76f5207f8202f15bb12375d8a4102a6c9323cdf80dca17ee79d1a80cb438b56f75a901822447a54c0b4858e2dbede0ed4634ee0d0f190c2b0f347247da09edc81cbbfcf2f5be25b842cf1777e151582ab797b) -emitted operations - -big_map diff - - -storage - (Some 0x0413f511b1c65f6a27766c69d4518eff63f9bb913feede2c82b7943f620feb27772f48b1a8b0196b88935a8b67eef112038f995b978f71a5d2d0470d026ae5c786be0ebe748045399a688f550e4950f2b5e0bea6131466d72a8eb4c6fbf2f750) -emitted operations - -big_map diff - - -storage - (Some 0x00e088d901aec4f3701eba2206c722276395202270c2a66471a5442861ef6ba997f2b12686e7b5413b24db4aec0babb207e5f81cccca63d939853e1b389695d58e907550fe6e4b347d870ab526b2b7667b888b92182366b5300314dc2fe305d0) -emitted operations - -big_map diff - - -storage - (Some 0x11641aa9417f8eb1659c74cd4a8f180242283634c5b059c497fedd502fad9c6fa00ecc991e978260a7452e79735d5e101559382cd1f3f92d964dc8a3f54b8d7dc37855650bbe11fa9b5e90881002b290951781aee93495d0e5703b35db31bf38) -emitted operations - -big_map diff - - -storage - (Some 0x0804d36e490be2f867fcc99338af37df61df443c73e47bd18f4f6eb8748a31ce403bb3a8aba27f281898a5f8e72f6c4f1321db8c96fffa9893be378e259ea6534fa1aa8be504b3f896e2af2a4cc53c6d017dcb587700689d81382f1cb1013f55) -emitted operations - -big_map diff - - -storage - (Some 0x1843835c32147cd7191e2f2aeecfef744f96757e1e5d2427c7cbe351d2142bb5723dc61b6211adfd79d335d632d72cb10d2e0686443369c8f26dd290b98af5e8d892a4085cfd7eac21742b783c57fbc5ee5a5a89a5b2a03ed732a0271bd2b548) -emitted operations - -big_map diff - - -storage - (Some 0x0d8dc00f3ecfb62c9e9e4af0dc3392fc24f2861de4e609b77d8866f561d90904e9e5531b5203cf646d5a22c4a26885520de353e43fb6cf32bbe12b2f243c858ecf9c388cb02be5b935ff8411f76991c00411a40a990d63af69902d0f3dbb18ee) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G2].out deleted file mode 100644 index 0d43bd2eae81..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_random[G2] - -storage - (Some 0x0d95415b2c0375d132c0700938c4590a75498165c923d00317fc3baf5048081b92995c9f651438490ea51f47ae1f871d06450ed22ec65658e7583c95236d3224479355196db6f0e0f8edc6c26c6d1e7c6edd8fc0217d86942a0078705c2188d90b4ccbc374d0076cbd6d0f9f01f4992fc87e8b2b4e17d3d4c91c14e3a0eb33000b34a923350c7a7c6f72f04d64db00320cd31bba7dea1243ddfca66e8e14fbd2b233c2201b43bd099e0f68cb9ce347cabe68ab4f42e972bbcb834d9d73da0eec) -emitted operations - -big_map diff - - -storage - (Some 0x1953081fd90afdd618ed308d2e556cc466cd7c0bdc79bcfcf25b96ece923fe8517e72c98034097d9eee722f737e39a41113223084fa6fd9daab9efb9e0481087c30f3cfef3e046fc2f1bab2a8b142a94335ac957f8521646fe4925cd443430f00c90e874ef50eca42050742f7f605d0f8cfe00c5571a2a99240b88541e3a7c08c91af2bc89ad29b4d397d10d42c93e9b0ac8dff1d86ad777e8b5c6f8880411a139155e8ffa1708e085972bbe6d4d5c4f39415e5ee902c3427d54ea84334b7ff3) -emitted operations - -big_map diff - - -storage - (Some 0x06a72dbd7d92de83d95290f1d7e8923e0d8e29eb84024b18fcea2097225481c29fbbbe7d030ff1b4018f12418b9c28a60728f0e17309868072e1dc188bc9548e4f3a0d4fc35ea2203f42539b462b7070feea8293fe47818fe89809ad977179620d727fc335198a6ddbb9e4ba25def0445c22c227bbd811cb005828b2d42024d1ccba6c20d5987bfe9ce114ca112c04b50d142f815aa648bdfb092e5509b72013b6417e6f5b5ada3cc590a6d4ba0ba908afc6ab5dc5a34ae976afc74d8e75da1d) -emitted operations - -big_map diff - - -storage - (Some 0x13ff1086d5713b7931883f01c36424ef26d28dd314473c073ca3ade1da5e8fcd7e22a86f0514beeb5b16f53176bb8ac70d8fe482a5ff16db0f19ac5738b52efc3f9228a997da35fa8e3a2cc9aea049fb23fbf5926f199ed7f29c73022610e4e70ca6547613b84940c90bfe7438339770ee180237cf717b67d2eac23fee8c42c17e0a5a903e0eeaf854856a241781298e0b13af3d210efad5757c6112565bffdcdbf649ba5b645d6d1a46fdea5014d2f3edf257af5ec593fbf69f14f0d8e3ef24) -emitted operations - -big_map diff - - -storage - (Some 0x0f3012df11a5a21ea69e484e3b1aae6426f47131b6c8de2d2ddcf5f08b7e2264beab80d08bdc3464e5ba93ae5c70dfa81792d5af6898237318173dee0241ad29f3a243837764dc8a5f66deb5868fd69ab434912233d3ccdedde5b8ee484a4b6f07ce143b9d525568a35c28ce4ad2ab57463cdc2fd6cd967864e130645e0f2807bf13228b000a2dc124dd4fa45bcee53202b486642d735da0ad84458ff8989cdfe9ff1478b2d80b4e45dad71d7098bffc890d65b720372793fc0ce9c6fc169b0c) -emitted operations - -big_map diff - - -storage - (Some 0x1429e92a93f2ba48ebe5d66ecfaa3b148e8414beae4aa83b5c054caf6937f30821e23621e278e197966ab69806010819156379b3a6f4674207d680dbd0e45a1399efe202631f30507fa96d88c4363bbe852e95edabd9902bc72485e6dce044a0072da73fb04a55e27613ddadd5915d0637f5756e4a489eb29347e76fb329c0e289a156f8e758ccbec03376ccd67a528a0abaa11be4c810443b52082cb54174e2019ea8d9d7373c99e103908da27c1aab943e745d5026304527528def70f391ad) -emitted operations - -big_map diff - - -storage - (Some 0x07d9eda0c029333aa344535a1520d5e1ff32767edc4a9d2f963fae4bf7a76762a1402a70fe2497059912016e20a082a20faff41e659f197f5c99532070782107a586dbd7e6609b31b89b4e91d5eb85ea01aac0e19aaeba32f86090c9f489b1ab0f8c51be59ebfd70a90246e364f817054a149dbc7fb6ad6e5ed3991c3e55f6dd08bcffc0f9e1e7d1c4fef6ed7141aced0da4ff47847aa5f5d7347bdf698525b75c840569e1dc731c1971eafebb305e77d44b2b06737a9f60d3b0cefe5a3412eb) -emitted operations - -big_map diff - - -storage - (Some 0x1047eb6211bae046da85a8085a23c5df6f73ed25abb394b16fa673842d19107b2e40ab9289b36f2699dfe34f5fecd2ad0596e9d73d3b697bb342d5b4a74922fac2c0ba20ed89db874e23dc07ef1c02df48ed3b5f2b9e63e1749b65d64ff3572c1034d01a148145d63b85d0f01b7c84c47ead9963b84233ce9f5cc48b1cee86b094087fba5d718ab4aa8a09153b078aa6036351a3042bfeff633a6e023945a0b6d88bd82cebf4c4b9010d16f98a30299ba276f8451ce728c26010a05bd09ba365) -emitted operations - -big_map diff - - -storage - (Some 0x0acd7057df12eccc09376a20c70c6c054bdd064503446d525413fc494251c0f19181eeb1280c83b6d34916a3904900bf177981828b72d00113c22542eda6e9130fe13f4b9d2f3dc2a78962fac295596cfa28f95bff49e35358f8a85cc764f2030dbadceba39d7e87f274f1b22e0d1f92e79a4452c6a97efad1aa6a71ba2987d6506341c1b8f9352548cdd40f445e545b051e6665e110109b6e80894d973b10ab4469a21d5d167563c2ac7645523fae0a2ae2745318b660f2cd19d725c3a17fda) -emitted operations - -big_map diff - - -storage - (Some 0x04f081fba03150088bdfae16217e3785de649dd8866c728a2ce05abb271cdb664a45d8c539f1a6c7b42335e5beb4a97e07c41c2e946a74f95d390b574fde8df58bda9d43fa695b02ea8cd290949097ba7cec710d802cfbce1a804c74e8b6826a017b201bf0b344cf7d469ebb203b4eb2b7ca41b6f7cd3797423276d55742542d9435b6261956076718a1eaf5fcdf0f1a127b43756c11c7baf603bfb4f929933ad5c263c9774bd6eee6131705416739a15d49c87bbe0a182ab62f70f55db77144) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[Fr].out deleted file mode 100644 index acf4fd1c07cb..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_zero[Fr] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G1].out deleted file mode 100644 index 60ea7219a688..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_zero[G1] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G2].out deleted file mode 100644 index d8c642e2de46..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_zero[G2] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[Fr].out deleted file mode 100644 index 6d167393c71e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_one[Fr] - -storage - (Some 0x286f0ec6252484c8bb981a3b8382b975c4ea92e11d1889a4bac541d0657db547) -emitted operations - -big_map diff - - -storage - (Some 0xd3b3ab5cfdfbd937887b10406248e8afef754b2692568adeca80be1c7abe3057) -emitted operations - -big_map diff - - -storage - (Some 0x469fba7341e28e67f35affe2fe4b97662a8b6481cf297346ee94e3d7d932c92d) -emitted operations - -big_map diff - - -storage - (Some 0x8a7177b61d33e4cb78eead124de5a06175df7e3b59f3bc4dca273de59b8a4151) -emitted operations - -big_map diff - - -storage - (Some 0x252050ca68bc0bc7940a33b68e12982233df654e652e96f2d28ab32be9ba046c) -emitted operations - -big_map diff - - -storage - (Some 0xae809d9a60de4be2126f115a819b9399358c9063790951f0373420a664335748) -emitted operations - -big_map diff - - -storage - (Some 0x128327880e041a2d6890d969f494c5581025dc3cdc3e3b6ce2d790f8ee68821e) -emitted operations - -big_map diff - - -storage - (Some 0x709b3e567cd3889a553a34818720157dd38724cf85ff458cfa91cb624db84b72) -emitted operations - -big_map diff - - -storage - (Some 0x932b426e549c4acc360611dfca579d436d7ce59111cb3f2bce5e9fa1562d4c1c) -emitted operations - -big_map diff - - -storage - (Some 0xef9144b2686c7a1de7488aeb9669bc3dafce03e580b27796d5489bbc2d5cef30) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G1].out deleted file mode 100644 index 9aa626685773..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_one[G1] - -storage - (Some 0x121ad63b7b9c90355f2862d56fe793c29fd884e311a65917f860071464068682612e78f29d936ceea7056ccd2506f12d03ffb304ff19fd039c7404c0af9119775534e2d93c5f9fe172893767c1dc12a25edfff52434bd309aed1d54bd0a89fc4) -emitted operations - -big_map diff - - -storage - (Some 0x0538edb42138a4fec97b74645550b722d7e87ccdea13249fe9fbad25e314d8587287821622e9c7cbd8b5ffc5b244a5c70600605fd5a514fbf6d13764bdb35639fc7edb3b95006fad00083bdb65420ac4a2b7a5a67100ec7b0fed8cc3f5bcf251) -emitted operations - -big_map diff - - -storage - (Some 0x0e4b6dbffad2f4b3ff5be58477f3dca892a060954b35a0ba682a9e388071023d32e4d4f241d6b926348d1b76b78369af05485f02b87fe3666c70f04ed7439d175fcd2d76fb9790cd4fea48c38f2fa1194799208195286274a0c94aa4e7225c1b) -emitted operations - -big_map diff - - -storage - (Some 0x0ef689c3ad66bbc9bdb16bae245346c3e1d314091c15b37622720ef5e70defd6c59d2f4e4335c791644c28f967aa5a510607bc31d79aa0a40fe637c47fd825bc06c7ae7839eaeca4a0e4dd8f1589ca8db8b4fee09b91f5a43e04f17ef9ba3c04) -emitted operations - -big_map diff - - -storage - (Some 0x143c03201ff3222e412deca15c6345f6f3a82ea30a8d0b289952dfd4e6edca156617cffdfac43466e7745e5ad5222c7f09b8ed107474064dc0c94140949264aa6b3aec28772a8b1b3dd0571ecf433ccc9a7e51d2ac119b7bbeadec90d1f3c837) -emitted operations - -big_map diff - - -storage - (Some 0x122c5f9870721941131cbed468f1c754dc52f494fcd486dc761b4281e17eb41d29a40a983de68cec836a36f6d3c396e1054b6904fd965d74805b1c088ac71e7b5eeb41a1611b399c63777170365859ce68ed99bfde5158a207ade9807f5cc458) -emitted operations - -big_map diff - - -storage - (Some 0x0fbe56abacb7f089a1e46ca6d2837b8f98e51dd1054445c2dc599deec36800688b6add762d6eaea36823fe5e867955730f1c175b454fb0bae81377a0b30a0017d2c11b4a768b78679e8634e8d2567874ef10b5f523f2e7bf8e4698311de58051) -emitted operations - -big_map diff - - -storage - (Some 0x05014fcf35b18ed937a24b4ec2f635e371e331766f6971204a6d458c6876381476ed691a0d020a6b487b14cf4512fcc20678c937e35d63f63e52af3fd081162d4c34a1333ebcc40841a7bccec941e8596956cb56bae1d2768ce7dcebb31ed170) -emitted operations - -big_map diff - - -storage - (Some 0x016f4c61393eacd1b8365656d475d00271c146649018368fe2b0acb056daa92e133a45acc5ebc121d100673f49a55b1f0a91f97170f0ac67e8f8fa516a173fae35645c26748696f5d6b2094d0a4e5a8402f59cde699ff5627d3f16034d745174) -emitted operations - -big_map diff - - -storage - (Some 0x0a8fdae48244aa6f45cb349ccf56b7dce450c08036f96ca38a13ac8ba3c136bd9bd83a91559c7f5269f4e7f34f001e6d0152b902148420a763d285716810dd24cc17b9b486e8578ad7dbedeee3a4eab0d1ad73cbd3a1ea783b875b171d897030) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G2].out deleted file mode 100644 index 1d1db1246331..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_one[G2] - -storage - (Some 0x09437976147a4d0d174d809df2b91247f2e2a482fa928fed9817b1740ddd941be108809ec427bba3abebab29e0fc91360dd9f11f94ec1c4cc3da10c13df7fe0a3e089b48c7f129c02c3fc47211f895c2243242f1a238cfca841e8d9d1e7927e400b626a5e4a4bf8f147aa6cd82073d5ec66504722a4ac8cf5939d5676a8b2b37731c94dce4e64ba9862eb657d17d789c19b1fb83a099335db3c569279fad3516257eef911af59c39e72a10da16e2c87394bee5a58b107c55ae00470377dea973) -emitted operations - -big_map diff - - -storage - (Some 0x05ef75bfe22c1366532a0be4e76af4f44c83653e53e7441e31eafd50d23f406093a42d56830ea0b2d6bd72c946c82bd6020366ebc02291ce6864c9923414fa0db8065979cd8031a84ab0bfe58ffa7d97c4f5829fc22126f8818d2b30cec132250207685a42ebd4b3566d3ae6437b12d1397ff6101d5cafb3283c0a26113b39436141bf2a09ec817d49145171a7cb0b4005483eff64cc380f7fab70479ff783e05b0c6a15245c93b732d9483adc38a3beb0179f766e685fae2ac8b91b888a4f3f) -emitted operations - -big_map diff - - -storage - (Some 0x16f479fc7f990fe798762da4e839ae6ab1c3ea82caa08d6d5892f28585b14ae178dcec9cbfe6f1a8128dcd46b87df07609798415e658f9387aa6138fbe3c335fb2327ffd2504c3f5aebd3285a2d08fc9966e8dd12f1c70dfdb369cc98f67b712179379ea1fd9bf46362cd7878a3667aa89f8c08627ad8d60868f219d49ed36336e393e0b7ebccd9027edbe634ab2d44507d065115a3ab3f4bd2ec1bb6361f580aa0040ccb0501426bd186e1e1971f7575e1e12ce77c8c2d8269799dd380de810) -emitted operations - -big_map diff - - -storage - (Some 0x04ff37dc37877f596cf0fee3190b74567c6925c5822c8776a1fdb926d250ecbd59c16109b3e18bf6389fd29a51f9815904b4d3277553a1afed4dc7c441cd16078016edf441df1bd21bf3590b701727a7a4ee5cfb77b4af06f154fcfe47cb44f91400cebb1f66c59f2ef796b5d8309c6d20a948156624e4d46ac09bc6b2566c115d2bc989e53137ee0bfa6e2e17d7b6fd10448f47c61b0fead5e32eb9f24f1f7635730a822166aa400d5537614fbf808d6e40f92746d6932993e74c3b57ef1520) -emitted operations - -big_map diff - - -storage - (Some 0x0b7028a94c140119e30ec04b76f245e78dc6d9828bcb5f503f44f2048faa675fac874f88b058c9b6e9ea2fb878a931fe0606479ff1fbaa8f8a1caa797ee960de8ee345eaef846578e7c6eef78aaa1a16c9cb9985821639cea2ec5866219d77de1593c6981c3da9e8c0a64bd8aa12a12d83e03494bf94ce9b098feb97a8921fc3a4a2656ba5a5eb130210b66766a0dc8512eb97e67cd5fe60859f1810ec7a1237fd80d4cb73e8641e1990a0e9e5c61f738ad8125b9108d78f96d704f3d43c71cd) -emitted operations - -big_map diff - - -storage - (Some 0x0f3e9c3968ce220c8d22fa306fd12e8afd05be41538ce630650650c8461563267ee4eb22e87818cd9e9022a1c23641d50b904a7acea602f907c97fb8701fe29fd6b2a276052b1d5cc152510016c466fe3ffb38ebdc0036058383c7643efaf10f07e7a1e694e4618c2057f4070912400e0c1457b32223be85ceb98afc5a9891ef467bbd4f96aeaf59dd92f39fd7698d4a1464d7b940f605a0afb023c06b2316ae5ce3e522e10e9e67ec2bc5dfef45e85e1272e5d4c26a7eb6b5255eea7117bea5) -emitted operations - -big_map diff - - -storage - (Some 0x17b906ef7baf4816f9ff3930b61253bbee2dc0cb2580449c234979733739d60b1e4c250cf38460240ddd8de171da0e790404c64d73d02d42540bb35b99bb9ef2d51af633c8546ed8eefd7a47cca204d3e6a2a82a6a661940e40995de3068033e12ad259c9a05af8b88196215be9a4310fa41e88454d8037572147571482cb0ffd39d50d1b09c2a68ae8a5694842bc8f9104104b65969eee42a43680a763fb577b0811d4b03d04c5060521b569d253014832d66cbb2163b1a15d5dc395969d47a) -emitted operations - -big_map diff - - -storage - (Some 0x0192202a64ffc9df0023d8b9b7125fb5b889386ea4e421bd8a113b1ebe45f491ecf552369e0e9e297d75264e73f5ac29119347d4871f1452d0375b4a19eaec758c58f6066bdc7c804ac9bab38b61f475913d0b1e80d8eb00790a11cd5ba3b81001069862fe6de4183f916099da7b8cfffdea73965df644dbb21fe2c9036296b01506fbd8299a8dce20c185f12a864e6c0f3c2e18a2e79a922a5f8bc59f48a4cd8ef322c678f080a10c4585c27af5c3bcb38a19f10c83ac484d81b55eb1393dd7) -emitted operations - -big_map diff - - -storage - (Some 0x1251e8448175157c4d2856be19064bf584481dfda30cae0d0b6f1e33b2a335be1a02dba175aec178718db6dc67409e8d09ae2872ec0d74b84c4a6eba82024630c290c6da27f387b39abe0f4fef1e1879bd17d32b1712cd9c2fa59c42796a6beb0f820092b9a5722b03aaf53470ead23b1d1c0a2263f2f010a5872d0251a81e21c21f4900aad8cad4f5615a9f9966e1090b13b49d84b63a6480c608dde86c383c6c943ca211d57b11aa4d518ef81121fa2604c2e650998138942d892fd49c258b) -emitted operations - -big_map diff - - -storage - (Some 0x05d336c2765803c6cb4b385ab9d4f4fa1ce2da0e5efd59a1fff5367678e6620664406da388d05b3b448be22281b2b3460f0c2b3b46ef2845bb1bf11ca2909f321cc35a295c656d7f0a432c31d6ff82b62cebfe000324d5bd35dfcff4016e526d0c424b33f830246ebca7fc52d1843d93275265da2bb6edb6edf6b9a0ff928cbb621aaa0c274614b185e39f3b8a91e50a13c54002d7842ba912b15f0671bc8e10bee8c8cd6f219f7115d9ed6d259cd029e75fc00ddb4cb508841b3c4ffe383d31) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[Fr].out deleted file mode 100644 index 343592a52c8a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_random[Fr] - -storage - (Some 0xb33a7eba53cdefc6ad9cb5c1328402d360c44984ea5dc51c2f542faadc6be816) -emitted operations - -big_map diff - - -storage - (Some 0xd3c6ed5a38abf39effe32bb89f2750a7792d10533191c9e7c24c4a110e918462) -emitted operations - -big_map diff - - -storage - (Some 0x712b1fcd10c384804b22abbcd62dbf10434baf60e33078f349b47a245a99394f) -emitted operations - -big_map diff - - -storage - (Some 0xc2a04fd112a74a4c60193a518a7a2dd968e63c4f122c5ccda2842e30040a1d0a) -emitted operations - -big_map diff - - -storage - (Some 0x145e33354dccac366850661cd8dc6b08f69edcd424055700833440bd798c1f1e) -emitted operations - -big_map diff - - -storage - (Some 0x9add5ab74ffe4b42e3618c846e60ea2b8a785d5b9392762ede89f50c85ff7803) -emitted operations - -big_map diff - - -storage - (Some 0x90827b0e55cd078db382a78e437a2320adeaf00847ad95a6c920ef2a13954727) -emitted operations - -big_map diff - - -storage - (Some 0x5bb1c6b970d42235a163ce608b783311e47114fd2d755624d9ec2c416d09250a) -emitted operations - -big_map diff - - -storage - (Some 0x3c32dff99dd4798310d347d73dcd51055acb344aca9135fd75a5b5be45ac8221) -emitted operations - -big_map diff - - -storage - (Some 0x8951db6a4a847740ee7a89d7e4057e2ba8e0fa5fbd8a6989c99f204492765e3b) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G1].out deleted file mode 100644 index 9df2946a3777..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_random[G1] - -storage - (Some 0x04e31b8535d081c6216917afc0b998284a19efb004598e40af32cf07a7c01baacb96621f42800d560e7bbc1cd76ef211046404a2303e2df0f827efee06a0146a3cf18a213b890080e33478eb652c142191363cec93bfe88f0f29ee65cd8a45a3) -emitted operations - -big_map diff - - -storage - (Some 0x158932735210b3c07f9c15eedec8acccefe84d080d3d5e06795e6ea3383e34a57c8ed1c091b6990d636dc3dc6e2b0a03077fb11f6c64d76840c168238b5838d2f06a27d48b1bd95cfd43b68f0a5871d22df1117b398118e71379602ee7a98e08) -emitted operations - -big_map diff - - -storage - (Some 0x0a32114ba43665abeb4ddb111a262bcd7ef8aab2f628627a4e237dea512835b4c8f7d3ed3bb2c4f8c99d68cff26b138519da6ab3ef7d260c2dbf7e84cb65890d65df014911b2d3f6d6e4248a23f36add20fc3c27c93560959c366a408ea38847) -emitted operations - -big_map diff - - -storage - (Some 0x14512db2530c824ca00345cc815036ad2a6e9d048c7571c74aff33f9f6b3a54239a893ac73142f3e0c74a5d179c0c5b2010a163762468c6feb4d27f1abccc4cf3fca36ce15868737320bff7aa4294bde62d103155e63b74de46d06d6b06ee1fd) -emitted operations - -big_map diff - - -storage - (Some 0x0e4459b6675e6b703556b06bc3db6adf195e4a0e3262bb12fa82fdbbb41d6aa0620743ed337ee87654fa8a22d907847b0d0c3e578ef5c00e360dba8567b12e4f3ecad77a2bdb303888af1c2fd730f5bdcbccfb4ad50e8571a0da0db8d7f63227) -emitted operations - -big_map diff - - -storage - (Some 0x0f32aa210d52283f4495ca85ce595df832cfa90d212922afe466a3d58203d419fa6cac2bc33fe2ef42c684c97ea061f90f49309180a9238b366642cc78ff5bd4ee8ee82aee112368248ec1a13d36210649b5696528e64a16e04f7c52ee14fd8c) -emitted operations - -big_map diff - - -storage - (Some 0x1658a9b3195f1103234c8115a54afd9455751a59223922cfb3b2c680be32511087f3ae762616d843fbfa19096fd58d990d6b9ddff4af5bcdfd44e7f49ed23393bf466a82b3e8e2281d883c6ccf8708755add7581a6a90f19be9263d8d624266b) -emitted operations - -big_map diff - - -storage - (Some 0x0182e82dbcb3151a65e424f9d5962e652eecf163a5a06ef5dcf1835009cd2cc0106b125bc6187a3eabaa25a8c4ef5c5b1009427ce8cf6efc38cdbd6efeb6c5463cd5d508fcf28bd7bd2c7eaf90b29bdc49cdde479a6c64bfb086d023972bb0f5) -emitted operations - -big_map diff - - -storage - (Some 0x130144b4bf38c092a5239371271624d48cbe36a0461feece232015f64917f2bec1bcba8e57597932d2a2776e2288b0e3068a74d96f52781b2b11a40ae730c56d909b6aa82afe81f291ba17667f8def0c8c62cf75b800d42460e5f1956eee18e9) -emitted operations - -big_map diff - - -storage - (Some 0x00f309e7224d4e6d1c59e27e2f651300d9bbb17f58ccf23943d88c7a4ada9902779c3d92a701e419cbf2e719927d94ac106420f6c2c79cc43631033d59ea62663c1c4eb127c43806a2b9d0e34bebca1ade68fefc795913823724a74a15df6a76) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G2].out deleted file mode 100644 index 91f8d40afedd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_random[G2] - -storage - (Some 0x0b2d5f882010f2406dd4fdda47ed2dce0a7419de3ce13360c709d420955d8fd254c0369250de38a69484f3d42266e56a0df6a9f48674db24a8adc43947f4d4155059769fda12b7de6de9c7d70166c3aa3b5780b3ef4e6285860935c5025a48a70ddb77c5df41cc6653f5ef1edf35776fd7f926e303115c1eca0465ab524626e16095d2d1bd516bf2bfc2ab4bb39c968c03bbda48f947a526fe887442e9cfd9dba4ac84be8f8d03308b9f32d566289a6cbfe19a87b13f87c3220bde5223f13568) -emitted operations - -big_map diff - - -storage - (Some 0x1170918e77a35dfc20db737834c50807efd778b7f0371e0a5cc5621df21f45311fc7d2cf36fa244a15605ac94f9bb12d0002517d54651966d9159aebc372ff2a7deec9a0d7dc80bce22025ace6cc1a32b8165e89790a8d6205121eb00238782709157dd20f2755c12822abc330be0b4a72df19d04d71f8cbd0357de1af8336987fd5db4f91f8813e66ded7570255c2fb11a13ba75e65187d7f342d7b4ef3ab41778bbd01f42680c86488bd7864cb78d9326e2e69f7195fd2fd09e06cffcce84d) -emitted operations - -big_map diff - - -storage - (Some 0x13d581984d95ad0ccedc521ee63077dfbfd3570ddf8dc0372f7411b903ce87caf5fc8a1cb1f66762e267a48f46a488ff1610ef168e28b79c9ab047ac9707de363b1ef06fb5ad86d919acadb9a6bca419d05dd129bc7436d4a8f024d4bdf7af8c0b1342fe8a6e949a51bb0901116d89437e7e18b8a40fb4be11f447879fb2651f7d449d70f84a1f959cc42869a85fe608062802296c3fe013f46b28c458ba28651c70fb61056b9a6af6b947e80becb252040dc8fc2fa9c79478973118d0984fda) -emitted operations - -big_map diff - - -storage - (Some 0x065e2a7e8b6ce16f9d46bfefa994cd13fa6813f6bad47e1d792dfd2e9bb4c3449cd7ebb05a8fb6b82b49116ca0dfb8a4041d960f46a4b0ac4bfe755470dff54f7b4d5bcb4f4d52ccf520b3f7e5defd6e6eac7b09f09f0e429c27477d5ec3a12706ad589e303bbed584d1ce39479c7a709bd73d4cc204ba78b7f4d70927a17d61dcd8e10e3359f396f98509f3b63cb16a06b68abc4b9597262f73f181bf042ef5c79b97c40304c259034534b3716d8168bf975565beea7f1ea21bfee63140d7db) -emitted operations - -big_map diff - - -storage - (Some 0x0c886b3d45067177888373985b7ad9e01f50fa934a67021f917ffe8a4f5730885c490f312bcb74590609a0550b26985711c932d4b30f82101a6b058f27b41edc2374273063470c3015840a9074c433cff7008f7c237bca62eac80cf82408ac85147a01f835601cb405e7a5daafb481462de4f5e765821c5e9c24d79945ffeb9926bcb5c516b1be62474f152fdcd79a7318f5733f19908cb27a4339c7cec46d2e904026ec421f41935ac05ee52dcd32ddf957d36da0478a231483cee910e158e9) -emitted operations - -big_map diff - - -storage - (Some 0x016720c0b2c7541ade5089d83b25c42eb26f76120904edf5d48c12a654df5bc690f3b8274f9a13b471e9d3397b253d5b0070d7e75316b1fe6581e120becefae1963f2c02e3dbe78fccaa0e82f3dc6b26b0f8fc878ccee3aca8681570864732791521735b6585f5543059a43e88d2293b372e76838962fcef28d9063259fcd7dc6216c833ad99fa0cd83c7aba57176da20a8a10c28d40cb495a3b4a7bfdddaa5b721a85b9dcb606bda5763eab6faea0ebceb638af2b2d8c61fa35c7e22d0393f3) -emitted operations - -big_map diff - - -storage - (Some 0x00971061214085d6e490b4e543696d4e2a5da1d7e3593bbb04444ffbc824a8f9bd9273b0a75f9672e5ef75407dc4daa503ebd0198f1af03f5d49688de7c9864836a521b93804a442d582b103d2ce3acf805ab611ed00d94eafe205fee48b1cc808c738a923f793e75b4a3070be1cc70d25eea3939703cddd1490f0f518d0cdcdcd7942b294020cd26338a25d3d8a2ddd02988eec1b3a4bbe0e13b6508b5a3bf790ff8ae7c78fc5ecd3760c7be57e94decf97f0271e7ef0c7396133b2b8927441) -emitted operations - -big_map diff - - -storage - (Some 0x17a0f51a199054d24bf00e707680a5318740b1e0f60935ae262a04a2e6a965d78ca4b066c8810c1c4ece3ba054b4f706132145795844cc04aba7fe5b92af3010c7d2ea264d82257de9caa012d267d5d2f040204d3a9b162ff35d58a94171a1dd0a6bf8ecae4b6109dca88a2bb07a4f2aff9148cb1d5af227278cafdc4a482070df87bd7cb968efafc621bd9fc0019e1114dd78975957c315f8f0988093457cbd710ba31b0f9eeda8b8d78e9d5833037ccb4a729726c3bb14941344aac882b9f1) -emitted operations - -big_map diff - - -storage - (Some 0x19d4f927fb96db848401d650a01ad72d05be245d7d75dc7e670e054e450e59b4c57119c8ba3df43e36ed405553a3439e13d903d0d8644031b13e46030ca2cd9f1450ac1428b54b399db96ed24f3d017a97bf5509470689b7585fdd848c587bc30f2c4d9df0e3b88e7d70a1288dddbc86e9c1f17cc110ea1a84f6900287a6a6ee016f59e02129792808721cee006337cb16657108891cb67ffdb6a5fd6fe4b5160cac312ca16aafd01ad9352a69b9e5ed2fdcbd58624fa800dcf0af4f6afc6cac) -emitted operations - -big_map diff - - -storage - (Some 0x0d4c4a2a8095869ea61b83d864cf7ad2611aeae6d8f2c980e8646e3cf101ebcc53ec086effeff6e79b97c09cd9e49b5719b698cb3540859837103da3bba5f89814a66a4bde5b6b8e12a585cefef8a2b884bb38e4dba52c3dccbe775291f971d41177f7ed1a9360fbc3ab6227d0f71a11dfd2a44f8e7d6fc4e8f42ad1e10bb1bdb3868595beddefd15f75c45fa857bbdb05955023d97e7360438d8588415ee12a626d8c0e147e9de1ccf2ded3e2826e5ebd9f48ca19fdd8b12c98dc6c8da4c951) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[Fr].out deleted file mode 100644 index 372ba7deee07..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_zero[Fr] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G1].out deleted file mode 100644 index 80a26025ddf4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_zero[G1] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G2].out deleted file mode 100644 index 70737f226cf0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_zero[G2] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[Fr].out deleted file mode 100644 index 015844d5742c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_one[Fr] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G1].out deleted file mode 100644 index ff7aaf69204c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_one[G1] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G2].out deleted file mode 100644 index 4b7ac8320d1e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_one[G2] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[Fr].out deleted file mode 100644 index 54b3dc67580b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_random[Fr] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G1].out deleted file mode 100644 index 7d180a3dcca7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_random[G1] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G2].out deleted file mode 100644 index f9893737a0df..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_random[G2] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[Fr].out deleted file mode 100644 index 23f7706109bb..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_zero[Fr] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G1].out deleted file mode 100644 index bc9c14446669..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_zero[G1] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G2].out deleted file mode 100644 index b6ed7273cf56..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_zero[G2] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[Fr].out deleted file mode 100644 index 16264131f06c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_one[Fr] - -storage - (Some 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G1].out deleted file mode 100644 index 7259fc3a8b58..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_one[G1] - -storage - (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb114d1d6855d545a8aa7d76c8cf2e21f267816aef1db507c96655b9d5caac42364e6f38ba0ecb751bad54dcd6b939c2ca) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G2].out deleted file mode 100644 index 281fe3ec3d81..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_one[G2] - -storage - (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb813fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed0d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[Fr].out deleted file mode 100644 index 97d8fb6a7a5a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_random[Fr] - -storage - (Some 0x9ac69bc1db5f20d9044178b065f5a09c8442bae11c45371f325e816bf721d739) -emitted operations - -big_map diff - - -storage - (Some 0x24a3fec4e7f8ad2ed4b6b0284e5d03ad143f3ac4d0ef3aed1f302c3459823c59) -emitted operations - -big_map diff - - -storage - (Some 0x0dd533bc546e5dcc64ac9d74ef41109f23d374ad2885194873e582d7700d0d16) -emitted operations - -big_map diff - - -storage - (Some 0xc0f43e2aff39fa4bcf5319a48396587b076d0193d9a1c31b676614d9b6a2dc0d) -emitted operations - -big_map diff - - -storage - (Some 0xbf12217bfe47d2f1d96db15e3f4a8eb9ba1229c610e2c0ca85205e217fe44422) -emitted operations - -big_map diff - - -storage - (Some 0x5b33082c052de9699109edb03ca4961ccdce7dc0b21f35ffa208f0c380d47353) -emitted operations - -big_map diff - - -storage - (Some 0x56bd703658653401c10d85274f305dec559e9630f202e307dfa3bb3980829360) -emitted operations - -big_map diff - - -storage - (Some 0x8b7fa597cd2d60533467ba57c1a15029a40239dd4cbf50341e7eb8aaa53abf4f) -emitted operations - -big_map diff - - -storage - (Some 0xcf62b00037ebd1ad24ffc51831e12878fdd817915f3bfc1f23150099fb2fb81e) -emitted operations - -big_map diff - - -storage - (Some 0x41df1100e72effd309b1f30f51729681df099140be3fbeeebf55468b9cb35d22) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G1].out deleted file mode 100644 index 821ab890ddd9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_random[G1] - -storage - (Some 0x197eab592fb38019ed2b362a048af848d1cc13b4a6c1d035f0dec4f5c461df58ddc92c9b6cab42fe3683000d91ceafe418d5a984c5833a305e02b18372d56e0b3943e34fc5aa2e79dcc359d8a299928b43bec4667443ab008dc91432a9e81ae1) -emitted operations - -big_map diff - - -storage - (Some 0x15d02840b69f06135d0fb3b82ae94649b2a10da9f7b4a5df7365c95b9d04c755a863ff2010332a8cf2609e08578ff02a05d1699ce8d778f3d2d7aa3841ec11e23682ab0e7933b43d8bd7e8e2c3b0dc5bb3878d7c0f01fcdc2b4e97f84c46472c) -emitted operations - -big_map diff - - -storage - (Some 0x14f7f5b6207b770382e65ebe91981942bc7c88908d1b2e73c6ee1322300f703877064d65d16493a3a9c3e6c45b049dfc0166df18d9caa4a3ba208d1ec549ea8cd27dccb7e22497594b4981ad758393a96de9be4247b185d8117774616032a403) -emitted operations - -big_map diff - - -storage - (Some 0x19b7acfd822ce85763c2d9e81425e571397c506ee31a5ae31c44fad5288bf3ca43c1abf6e78d380f0f75dcb83e1ec9cd17edeaaadb33ca8c4640da22fbb6733c5c11cd77bffc1a8e900399f6ea807bdda382b5173ee95ccb8807f52923a4297f) -emitted operations - -big_map diff - - -storage - (Some 0x16a404c56efceca50db3014d9c764842f6cd2221ff6b89605bc617b48a12e791e01c089489a5cfcf8f02956dcf8d2d8b015b9061f8f854b00f95fd177a0e9d8254b9dcb23e486a2ed13a79cf4f2fb430cf3d1c1eb727909712cc71e780226728) -emitted operations - -big_map diff - - -storage - (Some 0x03fd56e83ffaec3a3441bdcd46ad961f62819e72e9aeadb78b830a271c4d480014215b337fc7fcca3a7a6c9e57b62ed909c0dc635400cf2268eb1b1c841ca68e5cdb7edbba2a388714319740348180b33795377af9228b13035cdb4bbfa5bb60) -emitted operations - -big_map diff - - -storage - (Some 0x0a31c603358cc5f0536c3b4cc7bb8ed1a6e0da1113eb42a13a07201f071f69f84fdab55bfcf3791495317a9826e0a9ca07ea3e8155f0c3a0df59c86120a0decf70bfd0886be8433932dfb62e7eaabb68da56859be8c78fe0efe6d774fbf2ca1b) -emitted operations - -big_map diff - - -storage - (Some 0x0b2b25da57dfdbcd47c80f821d732052e890661fec1b1a89e2bf83b1bfcc0f0c59fa59be2eea602692472819aa581cc319742355a5c737fb173d6fd2b53772de1fb90859d39fc6d9d64528be91b41230dccef41eb8af2e228d73bf80ce152dea) -emitted operations - -big_map diff - - -storage - (Some 0x072cfea08d58f5fc8db45c45c7ac6fcc01a0279b33652a685e1e961c2385b307ef336ff7a7529008158388ec3342a3980b0ffd641f1319835631e7e4c72450900c2d4cfc9ca2a9427189047b4d84ce7cb21148b414f1a160efa4b069c0a884ca) -emitted operations - -big_map diff - - -storage - (Some 0x12d6f85f33ad5cf0c0fc2c77c79bb7ac152b065cbdafbb7ae9b190ef16f3f3ba07a1a7be5af71e80038b843fc6d9772612da90cb178d7a6b48bc95b33cc431168d84bb441364c1df012faa8b53fa7b602d2a961fb65a8e13d37cc4e1d417b8d8) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G2].out deleted file mode 100644 index 913b98b613f6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_random[G2] - -storage - (Some 0x04c4113c5de4461ee1effcfc208bb5a9804748c180af325b70966de7c379381de993a4659457b37367c9284ebf914033072014d5e51b7a11f6ceecdf68e310399700d00cd49696797fd39a95e701043291aa570cc853a3fc98389428112e62e90827091bae55288eddb843baa59bbbae59aeefc2e92d212a062dca9e1e96d621c4fae7cd94b1abab9b6efcbc720723b60ddfba8ba68bc874a1aab91b5fa6c6cb36a5cec01fb27b513a87c84ee21f18badc394467093a111040da3175c968157c) -emitted operations - -big_map diff - - -storage - (Some 0x19bf6c44cbd63175794a5730a440de20c66d93c2955412f40501117770de06ca62ac213b332dabafc32fb535c27c734d11d897534063baba835363bc6c8bb52d436d0cd6d3b7d80aae8f412960c6e31938b4c8b361ed3452dcf3fcc5021475dd02b7a90965f4ff09880874e59b382e0c1b37619a6f1320a124cf55b36b3aa716e42a588ae6f01af4364d08e3c0d814ef0d02bbeb23ef4c23f4b145aef8a73bb1ffc4895bafccfc86e621c05afbd218cdd3c2fc69268dc8a16129194a72c606c7) -emitted operations - -big_map diff - - -storage - (Some 0x11f4ea2b3cd84230f43e085ae38a0c60d712486564ce5eabf2de3df5f0da8d891657ce1f0c9fcf016b9aff1f48bc583d12ced40a391db04687b45de84f4a59eeef3c3db75ad8862c4241d03dd0bf36ff855156a58f185234bef6ec7301826f8c00b0f31e6a7c2c87eb9866c0259cf5b30997a7ea4513a70edc430c2e201822a3cea3bf3e0d2ad17680036d3423f2db7f132866d134609c331dc4aa1caf0caef348c51633e789f152b6cc255a8fc426c27331b519eb0cefd05b08bd23c2db1aba) -emitted operations - -big_map diff - - -storage - (Some 0x08968210984e1431183676214a406cb925239d7eb1334a07bae001019419d0f41ade7163bcf5578b7b7cea9c9efa12ca0dced010adea7a72bce2be7f2dee13be641ee209b87fb4ae77b00b43f30f770f6c745e9d4617d22020d5686ae40a495219db215c85c3166e233a2027314f1c3807aca9e90315a9dd0da624a87c61c709e2fad9b800290ebddbb413f5655ebb6b01008c500234652c966f668524577ddd3268ba1934d0eb44171fb2d2c8f24c21ff1edc3a68473604e2660646de8fe01a) -emitted operations - -big_map diff - - -storage - (Some 0x04d151207587d306af535541cd193cfc0f0039e84155c78bf9b0e5ef4b61f6cc49f39f9e84ed48c7c9b04c6e78dfc4b317fadc38e9900aefc0ff618ff983eb713861d8ff8cd0af5a9445f0cad43bef39ed4e0855072b8dae4ccec6f6ae7e1a62134d156f2cd1587df87ae54cbb3a6de862dbda2c898cc94e93833a573380d3af53d17061668c6693264cb124c87ab2050c9ecf6526f6401055724eb2fcb5173453c77870eedb8f774a711b8b75d0e7308c8e1aa3acda6466c48f148dbe04d1ad) -emitted operations - -big_map diff - - -storage - (Some 0x0c430e8fe9556cc97d2b00a6d84ae91f4eabd287e8a9ab9fb158b80eae7b000109f5ef7dd5d1efc9b7de64077041337110cdaa2bb05c7dbd6751bcdb6ade70100794d1a0ef3d462ae7e6a969a83e9f81245d389810da2e3ba8993ef7daff017005b222f1c29db487aac92aab1068afda51cd1e5489fc8931d2d9bdc142db5cccc17c65f729a57cf0ef7e4af9449f77000f39713ef371664621e2ad89f7c0261f4415dee34a6fe7c8dd041257bd2b793745d70103be171d0326cdc0321487d37d) -emitted operations - -big_map diff - - -storage - (Some 0x093485ee7701aefb89433f119a5b8d5a4230dabdafe8e55f26b23190b8550a1c51aa83ea1939d33de5477a4599f5101d0b36aa79caab813b87e102a83105b6bdb892e2381578aad742e53293c9bd24463156ca976342cbd03059b174e811884207b155b1dfc641bb0180493fcf47ed39010fd2d8420098b6ce5c1378cd402f725e7a91ee74cf068e4111a76ebdd2e6030b0220df748b9882f8f17cfbd1e624341262073563e037281c86eb70212e399c5efe102e9b0ba01f0b89ef266cb37cf9) -emitted operations - -big_map diff - - -storage - (Some 0x19428930e5a0f05f3319c7f034baf62b00cabd1568cff58065f30046b90021873cf56360730fefba5f2930d9d661dcb5034274f468bd901fed787268a0abaf18641ff90df4651d82e5c6d8c76af87032a8ff6e6e8b1a7bf2965e6f23cf0da586112cd75db7d04b7ed070d16a4372f0520b1c06a995af83d4389b418b8c026f2f3ddbe2ff6d0d8430a61b9b7cce9ff9d7196e415e4390bab69c57f39392dc448df55ea15f576492d15d046904d49e634a03809ccb1873ec89f23e95753c335495) -emitted operations - -big_map diff - - -storage - (Some 0x17692241047f40181fc0ea3d78c9c576477c5c2bef94dc7e795a1f06a32278f59ee4a862338c8d91093336652ea979e20595946083e9500ad695371dd38a84d3782f9bd1362c22210abff64e461b6f0dd6480f5af62ad72f6501a3b1cd5cd36215eec26a3f41f51d8066b88cf6882651b9a90fab9858e91e8cbb4231cc523aa5d031ba95123bc6a5f8e4b2f52fff5b650a81e87155d9e039f6aa9807a4ff68e91c61fc0b80d10e28ffda4e1f088079926575b35ef7f776cb0f36648066765c01) -emitted operations - -big_map diff - - -storage - (Some 0x1541b770bc7b492490eba70ec85bdc68ca78eb22e4f67bfabdf84ee7769e615efde8e6bd754d03ec62c41583b0bef01d06ff063375db383cf814f3807a5127afd82f55bf157bba04e36399cbaf189f63da12d29b0c584833d55b6e788e27d4a5176635964576c34bc77e17c29ffd8cad66a2b14880bfb03f5fbef5a66152617a093935ceca865ff6115b04a3720316db0b0b49aecb7883f2700551b8b1f632d7d6dbb1b2a4777c8745300a152eb4b46c742d08df7e8f99715df3a561c233ef00) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[Fr].out deleted file mode 100644 index bc22ba307053..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_zero[Fr] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G1].out deleted file mode 100644 index 8fefc56069a9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_zero[G1] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G2].out deleted file mode 100644 index b98f76c3d6cf..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_zero[G2] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g1.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g1.out deleted file mode 100644 index 95b89fe096d4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g1.out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_neg_g1 - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g2.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g2.out deleted file mode 100644 index 385f759e1a5a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g2.out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_neg_g2 - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_nil.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_nil.out deleted file mode 100644 index e66ebfa4d9c2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_nil.out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_nil - -storage - (Some True) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_one.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_one.out deleted file mode 100644 index 39f819e6f764..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_one.out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_one_one - -storage - (Some False) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_random.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_random.out deleted file mode 100644 index ac166d307f77..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_random.out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_one_random - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_zero.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_zero.out deleted file mode 100644 index cd0c784681ae..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_zero.out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_one_zero - -storage - (Some True) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_one.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_one.out deleted file mode 100644 index 0964d74f7af6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_one.out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_random_one - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_random.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_random.out deleted file mode 100644 index c8f1b6fe0143..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_random.out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_random_random - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - -storage - (Some False) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_zero.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_zero.out deleted file mode 100644 index b3d8481af27e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_zero.out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_random_zero - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_one.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_one.out deleted file mode 100644 index 15a8345bf9a2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_one.out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_zero_one - -storage - (Some True) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_random.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_random.out deleted file mode 100644 index a82ad61f7a2b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_random.out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_zero_random - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_zero.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_zero.out deleted file mode 100644 index 7c777eb84708..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_zero.out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_zero_zero - -storage - (Some True) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_signature_aggregation.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_signature_aggregation.out deleted file mode 100644 index 15895f8b2db1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_signature_aggregation.out +++ /dev/null @@ -1,142 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_signature_aggregation - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - -storage - (Some True) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[Fr].out deleted file mode 100644 index 98e893cbb1e0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_one[Fr] - -storage - (Some 0x0100000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G1].out deleted file mode 100644 index f2a038316ece..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_one[G1] - -storage - (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G2].out deleted file mode 100644 index ed061f0b4c62..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_one[G2] - -storage - (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[Fr].out deleted file mode 100644 index 64f7daab127d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[Fr].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_random[Fr] - -storage - (Some 0x4fa3eebe8eb999919b25e9496a740ba7e3db1e6af6d7dfc4226af5b7ff1bb31a) -emitted operations - -big_map diff - - -storage - (Some 0xeb3b4692c6d5d3be4529f58dc95561395d4fb06a4b56d5ecee427cb769df650c) -emitted operations - -big_map diff - - -storage - (Some 0x0fd278b6ab93ce8d6b66643b0173fd4e80d0d1776d0de34b13b6ff24227bae29) -emitted operations - -big_map diff - - -storage - (Some 0x9a6bc10fb59d3d43dd642524ddeb3f901c185488da989078efbd0166b878a66b) -emitted operations - -big_map diff - - -storage - (Some 0xd2e244946f6aa1a9f2e36a9f83faf915dd94d7fb31b1a4642eb7bb73861d0a58) -emitted operations - -big_map diff - - -storage - (Some 0xce66a6b5c6d97c52c44f3430271d6c466b1c9f656d43a3f6db6fb76a77b56d02) -emitted operations - -big_map diff - - -storage - (Some 0xfb437df580e072dbc887e9e0546c0843ccdc7b31264730e8e2f3c341a2d13908) -emitted operations - -big_map diff - - -storage - (Some 0xa1d61bc7847d649c7ed6bfdb0511393e83e6a8fe6a8999748ea767f44e2bca11) -emitted operations - -big_map diff - - -storage - (Some 0x5839a13cbc9d2ab02bba8d95197a7145d30d49b05c809ecf226e3e10a5181e02) -emitted operations - -big_map diff - - -storage - (Some 0x90348d02274bba201f5cb5a914c73410d7b34f5bbe090b3cfbe92ae307709055) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G1].out deleted file mode 100644 index 1f3e72010847..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G1].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_random[G1] - -storage - (Some 0x18782e3fbbe1f7abb5e2021b79bce810b5e8ae950c1e60d41731f0ae2ee4ebacbe59a9837bc34d5c61896561b04002be1760374bfa91e105077c507da80c080fe3a6c0ed820ce2515535f339b3f1510016ad6da0ff1a277065798e11aec2f74d) -emitted operations - -big_map diff - - -storage - (Some 0x1054b960d67ee71da9b596e7c543faf72544ba1ea2bc24d635f3da62feeeab2d0b00a8fed7ecf450767e1fdf1f2a913c127c6632387c6b5364a82dd2ff346b93cd29555913377b887c32e5a58fa37a7e69d1d82065e8b84865fee75aca361e6a) -emitted operations - -big_map diff - - -storage - (Some 0x0dbd1f474d065640ee4bde569142e26f7101a5c339c2f6630db6201c47483ed1303637aacb90002e1d7e7a84804b126205a8189fa87963e0fc81ea9c63e0a288768689f0ebe0868d98e9bb7e975026876f1df8502c6340adb3fde872f308704c) -emitted operations - -big_map diff - - -storage - (Some 0x141bebcd3a9c4145dcf836d368618d106cb3ab96669cce51cda04944eb3e0f07f0151a6fb4ba31d395692d4a305d623818a95f330d82b398d85782eb3a2793e098078058a289d5c5903cb78541807339db47e47d7dbbf2b5b4f0b6f9af323626) -emitted operations - -big_map diff - - -storage - (Some 0x088dcd93944d3cd43068b322488e178dd56f0ac3572d535d2c2d1da410e27572e425a4fcbbb8e10836f88d4010dba4a105a5ba71e19fc20bc6054df060a52887551b7b81196d63a3572c080705e9598e20cf3319343940de851d3d7ead06e8e9) -emitted operations - -big_map diff - - -storage - (Some 0x14c66800599dae815074aecfc36e2d43e2cdcf0c6663d9a0ab082488230ed0f6af46976598062df148d8b96144f55c5210e252370e812f951b90cc9765edbd2db2ba8157590338b3f5717a1bed450453f2674e3502bc95b2a8808e6d7442eada) -emitted operations - -big_map diff - - -storage - (Some 0x172318134285db82ebf7eab40d471dd4f733c0a624b360d8df00305ed381f3d59c7a54ce3996be88a63ce593a01c66e813ddee3711dca2ff243ea1e7141de5aec0a7611e67fa1f9c0e89ce7145ce58d0eef987d8949ad02d671166597d3a03ed) -emitted operations - -big_map diff - - -storage - (Some 0x0eb24546ddd153b1f2511c6155417c1d3fcc9750cb6b3af4367d01d485c2b6dba27cb1a7f19286e646e2f7a7aaf0363415735526cbb0f20f3d4141e6776f3c8b3255ee11ef05418ebfa62cf7e03220a5013a27e020544752260e295156f49c0a) -emitted operations - -big_map diff - - -storage - (Some 0x0e76d4b163d641ed1edbfdebdfa71c9fb6ad2e556e56ea0dadc3ea6bfc59b77e1e070063d9eb428b7730f35362310ac917e2386fd701b9389afb48d090552b8cb7a808aaec6669a06db758a7b30cf50933a275bac9a6e56ee4011fce86c496dd) -emitted operations - -big_map diff - - -storage - (Some 0x0a58dd111159092a784e404e0fbe2b03681a0c60ce1ebe52fea33f9780ac82118b6b8583b68fed0907adffdeef055d74120b04a2ebfd3a2a60a638cc4cd997090bb9b04d19cddcd61f9078903bd9f3e65fcdf9e5aec6de5a574ff7daef7cb079) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G2].out deleted file mode 100644 index e19cf8d9575a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G2].out +++ /dev/null @@ -1,72 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_random[G2] - -storage - (Some 0x0fdb404adcca2b3e91f5b6824e6f3c88d0086605135f34e733a47749f72e941ea0a546307b76881a2735b6aa24d630a20b9c453f8be68c3a875c4623df2156e61419a83dec2945fab6a50256f03cc9beabfb209d91858be53ead266aff598280191da483f4545715b6bfed1f3bc1aed02f97ed2e92f5bd9818432d1a17c6cef0b738beacef691b40c48b310a3befb95c10e67239e6fdf04c5c6720107466f19bb4d21b06ec221b72cf1a0b6ec4c1657872af587ffdda647cb36f9d73089b83d5) -emitted operations - -big_map diff - - -storage - (Some 0x00ec703f53406268b162add4b534cafad633e6d9453d289aad5f00a7ac68e2a9b1d97e9fb3b622bd95597b62b1fa0e7211fc2a54d8fded35cd021de7396db9dc1bdadce1d940da9c0dfbc6883c1212c639f2982b0f8943fe08ec1a12f1ea03081326c959ac2d47e6f75eacdf604efaa784796cafa511ad560c73552b9db0f8c9e0b1c281163f05b5d86b6b939c8fa5f512f6352c990f48e11a057e748a9695ae1d277918be1aa8fab5c96df723c47825136ef09c36d562214c25a087a5667b39) -emitted operations - -big_map diff - - -storage - (Some 0x17100f69943b685b53113c589254c0b26b23808b376a6addffa896ef873147871a0194d077acce64254e667890048f18056a3208afc3295e0829902800cfa9fcf50edc78841749d02198a3946010e6d800bd36171d41dfb6d79988f61524136003db45da43b3825c6dcf8b9ef46c8a40c842fcc3fee4ccf6d119b7b643ead789612ba75fca0d0a16dd31be31658c7b1d122b6a32d75113bb900ccf4a4da9cefc69b23814c486c9ade79d82eaa0593167b14a06ea2158f9d7710318d82553f1c5) -emitted operations - -big_map diff - - -storage - (Some 0x039c8fa2998d6fd874ea7b5cdfa5089bbe4cddd9958b445b6f33f65c27fd47b56a911e8134fe620275e7feece2ba1f560f731c917b8f756ec340c9d213a14c0f04bc79488ad38ca088d96c9a1c899aabc6cbf5070abf3231394b917c428fb0c5148e4d6c75c3b64e614582fefd2ccc979767d4b4da262d9c95ab27cf2fdf500268f0de8ecce5dad0f8ff5a06ef0e270f0dafac5b9ee6c9ff6665954a58e7dc792a257c1d80f27c1f91f9dedf4efc8da6e1d69d445364c7b7c076aef189f594e7) -emitted operations - -big_map diff - - -storage - (Some 0x118f6abab59d71635a4206e8fd16212e6d2f5f7c756e4308505f9e6473002a198292be2c834ca70cb40a1abeb3989c820a94d180da0025992a5c5ce516a2fa84c2e66d772acaf71c990aecefe420f885823f55bfdfa13db98035ae41c06ee6dc1305555d6da8ba4a92fd9eda92934ac5aed6db9fcc925fa51193a0ddf04594f2707d680d710171f041222e14644debfd14f43b880a07bdca546ffd02d792ed38be37171971ff662b094d54a37816aff6efbb2e57875dd9af97dee97e8c5f6109) -emitted operations - -big_map diff - - -storage - (Some 0x11308b1d8c4cb3cb1a57c98f1163ea78c44c1035cbc741988dc56a3c10c3d3b94b29445eae3199073857dbe6b146d6aa087a91a83306c1cbbc1f2eef3d058639ceda4e98ab1124dbaccc52dd25d7116675de0ba740fe95f2700ec1504461365a08ff04b06bba77a77b5b7ffa45a3ec56c8626fb7219f0d2d891251c1b4881f141bbbaf09217044e9bb69c8c1652476500153567f2ca8dd517cbd1c3467c10771d02fbf45fdad811118b325ce97e43ef72beff8857f44b0968de7b01a770fddd0) -emitted operations - -big_map diff - - -storage - (Some 0x0172fab176d798aed92f6ac9abeb28c510d77fd42601522db72c8fd7abe52fa0ce5adfb2ef67739bc4fb64fbbe3cd52b12a54aa1af0a44cdcc5c9110c13eac553ff037f1a8f304d052a0fc96ea40c946d5d31a8427feb1249fec862c28356afc0794bfcdc71fb3dfcf664e9a8db201c5b774ec45c2f0028531ff6abd2292dc1856fa9420fc8f5b632e84a592d73b25ba0fbb3e8cc6371e5f0d6c04b356f0e9d786545619a397f1dc1041854b5bde626b1b1d01258d6b16a80588453996a6eb00) -emitted operations - -big_map diff - - -storage - (Some 0x0156d0250e60af2f0678224eed0afee0594bb6f85293f7c4ab93b17ea0231bc1590d28250968931b8ee23a6f0f364d8c029e81178b6e60e9de5f858d44b102b823a028c4b8c230cf78e5f8a77964fda2bc4cb1a8cafd08641dcb20689b0903c104e58754b4c52b2b225473b407544d32823b8a7b47b2b919b96da883e20bd8a526ffe21928186d36d8355c16aa56523004f6dc232f441b80a9efaedec4dfd3abafffa97af0623f434e324120ecf61516affd143cc275ebda8c7552c89c718764) -emitted operations - -big_map diff - - -storage - (Some 0x058b2dbf9ed4d328d9afa79262a86ef47a044bba9226441df410d255040ae88931ca92ad6f127656c2309a3f9724af830cdb406c0cf88f930976f2b162d300d58930a9ef86869073be0043e9383e5875d9f5ce8a2cfee895f2591b6a265811ca13baaa13b0d54995b9ac5c2bd893730b07abf2f8b4c99b121870227c594365dac3e330dbeff1c2fb93f8b1dc6ec4d8311525ee7f96ac8b71f94b149bde3749c2d03fb8494592daafb6963c6a9427b887d67b0ad72c29804aff97897e6272379b) -emitted operations - -big_map diff - - -storage - (Some 0x0cfe1a34585ccf7095a05262a23fa1acde77911d1b9d0f894d63457ae6da644c417569c14a4e39b0ee2e51926a1ce7f108d6d899a1e78d27e6586f31d50fdf882d001bdb7fe934061214b756c5a9e64b66b5b13cd4c44ba1dd97101e394f82ec0661b38d968d819b85eab59f321c42b2d05e8037f4d1ba00bcaa80f2fe8f4130c4e292c073a856e095cc823965ffe97918ef4fa0f24b9bfa56b0ce783b3a6362de2781080d6ff52651e6ff71176b873318138cade3d284921c3eacf1734f5854) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[Fr].out deleted file mode 100644 index 88cb9becc290..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[Fr].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_zero[Fr] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G1].out deleted file mode 100644 index fc8adbe26dbf..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G1].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_zero[G1] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G2].out deleted file mode 100644 index 8062679b969c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G2].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_zero[G2] - -storage - (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert.tz].out deleted file mode 100644 index 73b229b0e7b4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert.tz].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert.tz] - -{ parameter bool ; - storage unit ; - code { CAR ; - { IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpeq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpeq.tz].out deleted file mode 100644 index 63aefde095f8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpeq.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmpeq.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpge.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpge.tz].out deleted file mode 100644 index eadfe810d1e8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpge.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmpge.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - { { COMPARE ; GE } ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpgt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpgt.tz].out deleted file mode 100644 index 6c3e2fc00d97..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpgt.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmpgt.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - { { COMPARE ; GT } ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmple.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmple.tz].out deleted file mode 100644 index a7a0aa339255..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmple.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmple.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - { { COMPARE ; LE } ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmplt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmplt.tz].out deleted file mode 100644 index 7db26261470c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmplt.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmplt.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - { { COMPARE ; LT } ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpneq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpneq.tz].out deleted file mode 100644 index 8281a51a45a5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpneq.tz].out +++ /dev/null @@ -1,12 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmpneq.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - { { COMPARE ; NEQ } ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_eq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_eq.tz].out deleted file mode 100644 index f9d6aa69ffb6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_eq.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_eq.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - COMPARE ; - { EQ ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_ge.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_ge.tz].out deleted file mode 100644 index e6839e18cde3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_ge.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_ge.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - COMPARE ; - { GE ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_gt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_gt.tz].out deleted file mode 100644 index 8131a6070565..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_gt.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_gt.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - COMPARE ; - { GT ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_le.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_le.tz].out deleted file mode 100644 index 8f6de3876233..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_le.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_le.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - COMPARE ; - { LE ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_lt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_lt.tz].out deleted file mode 100644 index 62b0df98f5dc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_lt.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_lt.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - COMPARE ; - { LT ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_neq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_neq.tz].out deleted file mode 100644 index 7517c229153d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_neq.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_neq.tz] - -{ parameter (pair int int) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - DIP { CDR } ; - COMPARE ; - { NEQ ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_get_add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_get_add.tz].out deleted file mode 100644 index f8f1fb38a522..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_get_add.tz].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/big_map_get_add.tz] - -{ parameter (pair (pair %set_pair int (option int)) (pair %check_pair int (option int))) ; - storage (pair (big_map int int) unit) ; - code { DUP ; - DIP { { CDR ; CAR } } ; - DUP ; - DIP { { CAR ; CDR } ; DUP ; CAR ; DIP { CDR } ; UPDATE ; DUP } ; - { CAR ; CDR } ; - DUP ; - CDR ; - DIP { CAR ; GET } ; - { IF_NONE - { { IF_NONE {} { { UNIT ; FAILWITH } } } } - { SWAP ; - { IF_NONE - { { UNIT ; FAILWITH } } - { { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } } } } } ; - UNIT ; - SWAP ; - PAIR ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_mem.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_mem.tz].out deleted file mode 100644 index 6db7b356f9b9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_mem.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/big_map_mem.tz] - -{ parameter (pair int bool) ; - storage (pair (big_map int unit) unit) ; - code { DUP ; - DUP ; - { CAR ; CDR } ; - DIP { { CAR ; CAR } ; DIP { { CDR ; CAR } ; DUP } ; MEM } ; - { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; - UNIT ; - SWAP ; - PAIR ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--build_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--build_list.tz].out deleted file mode 100644 index a20f0c24ff94..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--build_list.tz].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/build_list.tz] - -{ parameter nat ; - storage (list nat) ; - code { CAR @counter ; - NIL @acc nat ; - SWAP ; - DUP @cmp_num ; - PUSH nat 0 ; - { COMPARE ; NEQ } ; - LOOP { DUP ; - DIP { SWAP } ; - CONS @acc ; - SWAP ; - PUSH nat 1 ; - SWAP ; - SUB @counter ; - DUP ; - DIP { ABS } ; - PUSH int 0 ; - { COMPARE ; NEQ } } ; - CONS ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--carn_and_cdrn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--carn_and_cdrn.tz].out deleted file mode 100644 index c39037ddb4e2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--carn_and_cdrn.tz].out +++ /dev/null @@ -1,29 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/carn_and_cdrn.tz] - -{ parameter (pair nat nat nat unit) ; - storage unit ; - code { CAR ; - DUP ; - CAR ; - PUSH nat 1 ; - { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; - DUP ; - { GET 1 } ; - PUSH nat 1 ; - { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; - DUP ; - { GET 3 } ; - PUSH nat 4 ; - { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; - DUP ; - { GET 5 } ; - PUSH nat 2 ; - { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; - DUP ; - { GET 6 } ; - UNIT ; - { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; - DROP ; - UNIT ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare.tz].out deleted file mode 100644 index 37cd38a739c8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/compare.tz] - -{ parameter (pair mutez mutez) ; - storage (list bool) ; - code { CAR ; - DUP ; - DUP ; - DUP ; - DUP ; - DIP 5 { NIL bool } ; - DIP 4 { DUP ; CAR ; DIP { CDR } ; COMPARE ; LE ; CONS } ; - DIP 3 { DUP ; CAR ; DIP { CDR } ; COMPARE ; GE ; CONS } ; - DIP 2 { DUP ; CAR ; DIP { CDR } ; COMPARE ; LT ; CONS } ; - DIP { DUP ; CAR ; DIP { CDR } ; COMPARE ; GT ; CONS } ; - DUP ; - CAR ; - DIP { CDR } ; - COMPARE ; - EQ ; - CONS ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare_bytes.tz].out deleted file mode 100644 index 6250ef70c159..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare_bytes.tz].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/compare_bytes.tz] - -{ parameter (pair bytes bytes) ; - storage (list bool) ; - code { CAR ; - DUP ; - DUP ; - DUP ; - DUP ; - DIP 5 { NIL bool } ; - DIP 4 { DUP ; CAR ; DIP { CDR } ; COMPARE ; LE ; CONS } ; - DIP 3 { DUP ; CAR ; DIP { CDR } ; COMPARE ; GE ; CONS } ; - DIP 2 { DUP ; CAR ; DIP { CDR } ; COMPARE ; LT ; CONS } ; - DIP { DUP ; CAR ; DIP { CDR } ; COMPARE ; GT ; CONS } ; - DUP ; - CAR ; - DIP { CDR } ; - COMPARE ; - EQ ; - CONS ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--fail.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--fail.tz].out deleted file mode 100644 index 64d32bbf527a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--fail.tz].out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/fail.tz] - -{ parameter unit ; storage unit ; code { { UNIT ; FAILWITH } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--guestbook.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--guestbook.tz].out deleted file mode 100644 index 0ded6828d28f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--guestbook.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/guestbook.tz] - -{ parameter string ; - storage (map address (option string)) ; - code { UNPAIR @message @guestbook ; - SWAP ; - DUP ; - SENDER ; - GET @previous_message ; - { IF_NONE { { UNIT ; FAILWITH } } {} } ; - { IF_NONE {} { { UNIT ; FAILWITH } } } ; - SWAP ; - SOME ; - SOME ; - SENDER ; - UPDATE ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--macro_annotations.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--macro_annotations.tz].out deleted file mode 100644 index c2cb3318b0d3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--macro_annotations.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/macro_annotations.tz] - -{ parameter unit ; - storage (pair (unit %truc) unit) ; - code { DROP ; - UNIT ; - UNIT ; - PAIR %truc ; - UNIT ; - DUP @new_storage 2 ; - DIP { DROP ; DROP } ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--map_caddaadr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--map_caddaadr.tz].out deleted file mode 100644 index 269f1aa95c0e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--map_caddaadr.tz].out +++ /dev/null @@ -1,40 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/map_caddaadr.tz] - -{ parameter unit ; - storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat) ; - code { { DUP ; - DIP { CDR @%% ; - { DUP ; - DIP { CAR @%% ; - { DUP ; - DIP { CDR @%% ; - { DUP ; - DIP { CDR @%% ; - { DUP ; - DIP { CAR @%% ; - { DUP ; - DIP { CAR @%% ; - { DUP ; - CDR @value ; - { PUSH mutez 1000000 ; ADD } ; - SWAP ; - CAR @%% ; - PAIR %@ %value } } ; - CDR @%% ; - SWAP ; - PAIR %@ %@ } } ; - CDR @%% ; - SWAP ; - PAIR %@ %@ } } ; - CAR @%% ; - PAIR %@ %@ } } ; - CAR @%% ; - PAIR %@ %@ } } ; - CDR @%% ; - SWAP ; - PAIR %@ %@ } } ; - CAR @%% ; - PAIR %@ %@ @new_storage } ; - NIL operation ; - SWAP ; - { CDR @%% ; SWAP ; PAIR % %@ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--max_in_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--max_in_list.tz].out deleted file mode 100644 index e1547da1de33..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--max_in_list.tz].out +++ /dev/null @@ -1,17 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/max_in_list.tz] - -{ parameter (list int) ; - storage (option int) ; - code { CAR ; - DIP { NONE int } ; - ITER { SWAP ; - IF_NONE - { SOME } - { DIP { DUP } ; - DUP ; - DIP { SWAP } ; - { COMPARE ; LE } ; - IF { DROP } { DIP { DROP } } ; - SOME } } ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--min.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--min.tz].out deleted file mode 100644 index 237da146c9dc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--min.tz].out +++ /dev/null @@ -1,13 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/min.tz] - -{ parameter (pair int int) ; - storage int ; - code { CAR ; - DUP ; - DUP ; - CAR ; - DIP { CDR } ; - { COMPARE ; LT } ; - IF { CAR } { CDR } ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--pair_macro.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--pair_macro.tz].out deleted file mode 100644 index a3da0c31fabc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--pair_macro.tz].out +++ /dev/null @@ -1,18 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/pair_macro.tz] - -{ parameter unit ; - storage unit ; - code { UNIT ; - UNIT ; - UNIT ; - UNIT ; - UNIT ; - { DIP 3 { PAIR %x4 %x5 } ; - DIP 2 { PAIR %x3 } ; - DIP { PAIR %x2 } ; - PAIR %x1 @name } ; - { CDR ; CDR ; CDR ; CAR %x4 @fourth } ; - DROP ; - CDR ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--set_caddaadr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--set_caddaadr.tz].out deleted file mode 100644 index 768648c3987b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--set_caddaadr.tz].out +++ /dev/null @@ -1,33 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/set_caddaadr.tz] - -{ parameter mutez ; - storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat) ; - code { DUP ; - CAR ; - SWAP ; - CDR ; - { DUP ; - DIP { CAR @%% ; - { DUP ; - DIP { CDR @%% ; - { DUP ; - DIP { CDR @%% ; - { DUP ; - DIP { CAR @%% ; - { DUP ; - DIP { CAR @%% ; { DUP ; CDR %value ; DROP ; CAR @%% ; PAIR %@ %value } } ; - CDR @%% ; - SWAP ; - PAIR %@ %@ } } ; - CDR @%% ; - SWAP ; - PAIR %@ %@ } } ; - CAR @%% ; - PAIR %@ %@ } } ; - CAR @%% ; - PAIR %@ %@ } } ; - CDR @%% ; - SWAP ; - PAIR %@ %@ @toplevel_pair_name } ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--take_my_money.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--take_my_money.tz].out deleted file mode 100644 index fc9217b03bf6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--take_my_money.tz].out +++ /dev/null @@ -1,14 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/take_my_money.tz] - -{ parameter key_hash ; - storage unit ; - code { CAR ; - IMPLICIT_ACCOUNT ; - DIP { UNIT } ; - PUSH mutez 1000000 ; - UNIT ; - TRANSFER_TOKENS ; - NIL operation ; - SWAP ; - CONS ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--unpair_macro.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--unpair_macro.tz].out deleted file mode 100644 index 1b5a2e9a4d4d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--unpair_macro.tz].out +++ /dev/null @@ -1,20 +0,0 @@ -tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/unpair_macro.tz] - -{ parameter (unit :param_unit) ; - storage (unit :u1) ; - code { DROP ; - UNIT :u4 @a4 ; - UNIT :u3 @a3 ; - UNIT :u2 @a2 ; - UNIT :u1 @a1 ; - PAIR ; - UNPAIR @x1 @x2 ; - { DIP 2 { PAIR %x3 %x4 } ; PAIR %x1 %x2 ; PAIR @p1 } ; - { UNPAIR ; UNPAIR ; DIP 2 { UNPAIR } } ; - { DIP 2 { PAIR %x3 %x4 } ; DIP { PAIR %x2 } ; PAIR %x1 @p2 } ; - { UNPAIR ; DIP { UNPAIR } ; DIP 2 { UNPAIR } } ; - { DIP { PAIR %x2 %x3 } ; DIP { PAIR % %x4 } ; PAIR %x1 @p3 } ; - { UNPAIR ; DIP { UNPAIR } ; DIP { UNPAIR } } ; - DIP { DROP ; DROP ; DROP } ; - NIL operation ; - PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_diff.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_diff.out deleted file mode 100644 index 91dd75404766..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_diff.out +++ /dev/null @@ -1,29 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_origination_diff - -Node is bootstrapped. -This simulation failed: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1040000 - Storage limit: 60000 bytes - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter (big_map int int) ; - storage (big_map int int) ; - code { CAR ; NIL operation ; PAIR } } - Initial storage: (Pair 0 { Elt 1 (Some 4) }) - No delegate for this contract - This operation FAILED. - -Ill typed data: 1: (Pair 0 { Elt 1 (Some 4) }) -is not an expression of type big_map int int -At line 1 characters 0 to 26, value (Pair 0 { Elt 1 (Some 4) }) -is invalid for type big_map int int. -At line 1 characters 6 to 7, -Unexpected forged value. -Fatal error: - origination simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_id.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_id.out deleted file mode 100644 index f1bf6c969bb1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_id.out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_origination_id - -Node is bootstrapped. -This simulation failed: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1040000 - Storage limit: 60000 bytes - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter (big_map int int) ; - storage (big_map int int) ; - code { CAR ; NIL operation ; PAIR } } - Initial storage: 0 - No delegate for this contract - This operation FAILED. - -Ill typed data: 1: 0 is not an expression of type big_map int int -At line 1 characters 0 to 1, value 0 is invalid for type big_map int int. -At line 1 characters 0 to 1, -Unexpected forged value. -Fatal error: - origination simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_literal.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_literal.out deleted file mode 100644 index 590a4ff18932..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_literal.out +++ /dev/null @@ -1,50 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_origination_literal - -Node is bootstrapped. -Estimated gas: 1638.345 units (will add 100 for safety) -Estimated storage: 403 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.00046 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1739 - Storage limit: 423 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00046 - payload fees(the block proposer) ....... +ꜩ0.00046 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter (big_map int int) ; - storage (big_map int int) ; - code { CAR ; NIL operation ; PAIR } } - Initial storage: { Elt 0 0 } - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 146 bytes - Updated big_maps: - New map(4) of type (big_map int int) - Set map(4)[0] to 0 - Paid storage size diff: 146 bytes - Consumed gas: 1638.345 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0365 - storage fees ........................... +ꜩ0.0365 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as originate_big_map_literal. -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_diff.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_diff.out deleted file mode 100644 index 12e3d71a254e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_diff.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_transfer_diff - -Node is bootstrapped. -This simulation failed: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1040000 - Storage limit: 60000 bytes - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: (Pair 0 { Elt 1 (Some 4) }) - This operation FAILED. - -Invalid argument passed to contract [CONTRACT_HASH]. -At (unshown) location 0, value (Pair 0 { Elt 1 (Some 4) }) -is invalid for type big_map int int. -At (unshown) location 1, Unexpected forged value. -Fatal error: - transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_id.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_id.out deleted file mode 100644 index 6fc4325186f8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_id.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_transfer_id - -Node is bootstrapped. -This simulation failed: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1040000 - Storage limit: 60000 bytes - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: 0 - This operation FAILED. - -Invalid argument passed to contract [CONTRACT_HASH]. -At (unshown) location 0, value 0 is invalid for type big_map int int. -At (unshown) location 0, Unexpected forged value. -Fatal error: - transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainLevel::test_level.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainLevel::test_level.out deleted file mode 100644 index 5ccd959c2d47..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainLevel::test_level.out +++ /dev/null @@ -1,123 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainLevel::test_level - -Node is bootstrapped. -Estimated gas: 1406.044 units (will add 100 for safety) -Estimated storage: 300 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000424 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1507 - Storage limit: 320 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000424 - payload fees(the block proposer) ....... +ꜩ0.000424 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ100 - Script: - { parameter unit ; - storage nat ; - code { DROP ; LEVEL ; NIL operation ; PAIR } } - Initial storage: 9999999 - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 43 bytes - Paid storage size diff: 43 bytes - Consumed gas: 1406.044 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01075 - storage fees ........................... +ꜩ0.01075 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - -New contract [CONTRACT_HASH] originated. -Contract memorized as level. -Injected block at minimal timestamp -Injected block at minimal timestamp -Node is bootstrapped. -Estimated gas: 2049.563 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000467 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2150 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000467 - payload fees(the block proposer) ....... +ꜩ0.000467 - Transaction: - Amount: ꜩ500 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Updated storage: 4 - Storage size: 40 bytes - Consumed gas: 2049.563 - Balance updates: - [CONTRACT_HASH] ... -ꜩ500 - [CONTRACT_HASH] ... +ꜩ500 - -Injected block at minimal timestamp -{ "level": [LEVEL], "proto": 1, - "predecessor": "[BLOCK_HASH]", - "timestamp": "[TIMESTAMP]", "validation_pass": 4, - "operations_hash": "[OPERATION_HASH]", - "fitness": "[FITNESS]", - "context": "[CONTEXT]" } -4 -Injected block at minimal timestamp -Injected block at minimal timestamp -4 -Node is bootstrapped. -Estimated gas: 1202.350 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000383 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1303 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000383 - payload fees(the block proposer) ....... +ꜩ0.000383 - Transaction: - Amount: ꜩ500 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Updated storage: 7 - Storage size: 40 bytes - Consumed gas: 1202.350 - Balance updates: - [CONTRACT_HASH] ... -ꜩ500 - [CONTRACT_HASH] ... +ꜩ500 - -Injected block at minimal timestamp -7 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_contract_fails.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_contract_fails.out deleted file mode 100644 index bcc125d7efa3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_contract_fails.out +++ /dev/null @@ -1,2 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_contract_fails - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_gen_keys.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_gen_keys.out deleted file mode 100644 index 78abad21129e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_gen_keys.out +++ /dev/null @@ -1,2 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_gen_keys - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_init_proxy.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_init_proxy.out deleted file mode 100644 index 6ed3c49e7854..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_init_proxy.out +++ /dev/null @@ -1,53 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_init_proxy - -Node is bootstrapped. -Estimated gas: 1409.594 units (will add 100 for safety) -Estimated storage: 312 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000437 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1510 - Storage limit: 332 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000437 - payload fees(the block proposer) ....... +ꜩ0.000437 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter (contract unit) ; - storage unit ; - code { UNPAIR ; - AMOUNT ; - UNIT ; - TRANSFER_TOKENS ; - DIP { NIL operation } ; - CONS ; - PAIR } } - Initial storage: Unit - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 55 bytes - Paid storage size diff: 55 bytes - Consumed gas: 1409.594 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01375 - storage fees ........................... +ꜩ0.01375 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as proxy. -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_now.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_now.out deleted file mode 100644 index b92c1b50abac..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_now.out +++ /dev/null @@ -1,2 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_now - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_self.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_self.out deleted file mode 100644 index e4bce90a657d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_self.out +++ /dev/null @@ -1,2 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_self - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_sender.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_sender.out deleted file mode 100644 index 8fa62935b57c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_sender.out +++ /dev/null @@ -1,2 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_sender - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_set_delegate.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_set_delegate.out deleted file mode 100644 index 1f28dd08f1e5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_set_delegate.out +++ /dev/null @@ -1,123 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_set_delegate - -Node is bootstrapped. -Estimated gas: 1408.028 units (will add 100 for safety) -Estimated storage: 308 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000433 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1509 - Storage limit: 328 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000433 - payload fees(the block proposer) ....... +ꜩ0.000433 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter (option key_hash) ; - storage unit ; - code { UNPAIR ; SET_DELEGATE ; DIP { NIL operation } ; CONS ; PAIR } } - Initial storage: Unit - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 51 bytes - Paid storage size diff: 51 bytes - Consumed gas: 1408.028 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01275 - storage fees ........................... +ꜩ0.01275 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as set_delegate. -Injected block at minimal timestamp -Injected block at minimal timestamp -none -Node is bootstrapped. -Estimated gas: 3056.175 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000612 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 3157 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000612 - payload fees(the block proposer) ....... +ꜩ0.000612 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: (Some "[CONTRACT_HASH]") - This transaction was successfully applied - Updated storage: Unit - Storage size: 51 bytes - Consumed gas: 2056.175 - Internal operations: - Delegation: - Contract: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This delegation was successfully applied - Consumed gas: 1000 - -Injected block at minimal timestamp -[CONTRACT_HASH] (known as bootstrap5) -Node is bootstrapped. -Estimated gas: 2202.482 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000486 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2303 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000486 - payload fees(the block proposer) ....... +ꜩ0.000486 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: None - This transaction was successfully applied - Updated storage: Unit - Storage size: 51 bytes - Consumed gas: 1202.482 - Internal operations: - Delegation: - Contract: [CONTRACT_HASH] - To: nobody - This delegation was successfully applied - Consumed gas: 1000 - -Injected block at minimal timestamp -none diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice.out deleted file mode 100644 index 97b84db5e807..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice.out +++ /dev/null @@ -1,87 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice - -Node is bootstrapped. -Estimated gas: 1828.800 units (will add 100 for safety) -Estimated storage: 835 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.001023 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1929 - Storage limit: 855 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.001023 - payload fees(the block proposer) ....... +ꜩ0.001023 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter (pair bytes signature) ; - storage key ; - code { DUP ; - CAAR ; - DUP ; - SIZE ; - PUSH nat 128 ; - SWAP ; - SUB ; - ISNAT ; - ASSERT_SOME ; - PUSH nat 128 ; - SLICE @payload ; - ASSERT_SOME ; - DUP ; - DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; - SHA256 ; - ASSERT_CMPEQ } ; - DUP ; - DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; - BLAKE2B ; - ASSERT_CMPEQ } ; - DUP ; - DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; - SHA512 ; - ASSERT_CMPEQ } ; - DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; - SWAP ; - DIP { SWAP } ; - CHECK_SIGNATURE ; - ASSERT ; - CDR ; - DUP ; - HASH_KEY ; - IMPLICIT_ACCOUNT ; - BALANCE ; - UNIT ; - TRANSFER_TOKENS ; - NIL operation ; - SWAP ; - CONS ; - PAIR } } - Initial storage: - "[OPERATION_HASH]na" - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 578 bytes - Paid storage size diff: 578 bytes - Consumed gas: 1828.800 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.1445 - storage fees ........................... +ꜩ0.1445 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as slices. -Injected block at minimal timestamp diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 \"spsig1PPUFZucuAQybs5wsqs.818025e860.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 \"spsig1PPUFZucuAQybs5wsqs.818025e860.out" deleted file mode 100644 index 05bf8d60e5fa..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 \"spsig1PPUFZucuAQybs5wsqs.818025e860.out" +++ /dev/null @@ -1,66 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] - -Node is bootstrapped. -This simulation failed: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1040000 - Storage limit: 60000 bytes - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: (Pair 0xe009ab79e8b84ef0 - "sp[SIGNATURE]m") - This operation FAILED. - -Runtime error in contract [CONTRACT_HASH]: - 01: { parameter (pair bytes signature) ; - 02: storage key ; - 03: code { DUP ; - 04: CAAR ; - 05: DUP ; - 06: SIZE ; - 07: PUSH nat 128 ; - 08: SWAP ; - 09: SUB ; - 10: ISNAT ; - 11: ASSERT_SOME ; - 12: PUSH nat 128 ; - 13: SLICE @payload ; - 14: ASSERT_SOME ; - 15: DUP ; - 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; - 17: SHA256 ; - 18: ASSERT_CMPEQ } ; - 19: DUP ; - 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; - 21: BLAKE2B ; - 22: ASSERT_CMPEQ } ; - 23: DUP ; - 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; - 25: SHA512 ; - 26: ASSERT_CMPEQ } ; - 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; - 28: SWAP ; - 29: DIP { SWAP } ; - 30: CHECK_SIGNATURE ; - 31: ASSERT ; - 32: CDR ; - 33: DUP ; - 34: HASH_KEY ; - 35: IMPLICIT_ACCOUNT ; - 36: BALANCE ; - 37: UNIT ; - 38: TRANSFER_TOKENS ; - 39: NIL operation ; - 40: SWAP ; - 41: CONS ; - 42: PAIR } } -At line 11 characters 9 to 20, -script reached FAILWITH instruction -with Unit -Fatal error: - transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.2d6806d54e.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.2d6806d54e.out deleted file mode 100644 index a54058e22fff..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.2d6806d54e.out +++ /dev/null @@ -1,66 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2deaad01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] - -Node is bootstrapped. -This simulation failed: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1040000 - Storage limit: 60000 bytes - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 - "sp[SIGNATURE]m") - This operation FAILED. - -Runtime error in contract [CONTRACT_HASH]: - 01: { parameter (pair bytes signature) ; - 02: storage key ; - 03: code { DUP ; - 04: CAAR ; - 05: DUP ; - 06: SIZE ; - 07: PUSH nat 128 ; - 08: SWAP ; - 09: SUB ; - 10: ISNAT ; - 11: ASSERT_SOME ; - 12: PUSH nat 128 ; - 13: SLICE @payload ; - 14: ASSERT_SOME ; - 15: DUP ; - 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; - 17: SHA256 ; - 18: ASSERT_CMPEQ } ; - 19: DUP ; - 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; - 21: BLAKE2B ; - 22: ASSERT_CMPEQ } ; - 23: DUP ; - 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; - 25: SHA512 ; - 26: ASSERT_CMPEQ } ; - 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; - 28: SWAP ; - 29: DIP { SWAP } ; - 30: CHECK_SIGNATURE ; - 31: ASSERT ; - 32: CDR ; - 33: DUP ; - 34: HASH_KEY ; - 35: IMPLICIT_ACCOUNT ; - 36: BALANCE ; - 37: UNIT ; - 38: TRANSFER_TOKENS ; - 39: NIL operation ; - 40: SWAP ; - 41: CONS ; - 42: PAIR } } -At line 22 characters 15 to 27, -script reached FAILWITH instruction -with Unit -Fatal error: - transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.378d03ae2d.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.378d03ae2d.out deleted file mode 100644 index 5850dca7842d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.378d03ae2d.out +++ /dev/null @@ -1,66 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150733eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] - -Node is bootstrapped. -This simulation failed: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1040000 - Storage limit: 60000 bytes - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 - "sp[SIGNATURE]m") - This operation FAILED. - -Runtime error in contract [CONTRACT_HASH]: - 01: { parameter (pair bytes signature) ; - 02: storage key ; - 03: code { DUP ; - 04: CAAR ; - 05: DUP ; - 06: SIZE ; - 07: PUSH nat 128 ; - 08: SWAP ; - 09: SUB ; - 10: ISNAT ; - 11: ASSERT_SOME ; - 12: PUSH nat 128 ; - 13: SLICE @payload ; - 14: ASSERT_SOME ; - 15: DUP ; - 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; - 17: SHA256 ; - 18: ASSERT_CMPEQ } ; - 19: DUP ; - 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; - 21: BLAKE2B ; - 22: ASSERT_CMPEQ } ; - 23: DUP ; - 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; - 25: SHA512 ; - 26: ASSERT_CMPEQ } ; - 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; - 28: SWAP ; - 29: DIP { SWAP } ; - 30: CHECK_SIGNATURE ; - 31: ASSERT ; - 32: CDR ; - 33: DUP ; - 34: HASH_KEY ; - 35: IMPLICIT_ACCOUNT ; - 36: BALANCE ; - 37: UNIT ; - 38: TRANSFER_TOKENS ; - 39: NIL operation ; - 40: SWAP ; - 41: CONS ; - 42: PAIR } } -At line 26 characters 15 to 27, -script reached FAILWITH instruction -with Unit -Fatal error: - transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.57fdc7ad1c.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.57fdc7ad1c.out deleted file mode 100644 index d2392538cc62..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.57fdc7ad1c.out +++ /dev/null @@ -1,66 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "p2sigsceCzcDw2AeYDzUonj4JT341WC9Px4wdhHBxbZcG1FhfqFVuG7f2fGCzrEHSAZgrsrQWpxduDPk9qZRgrpzwJnSHC3gZJ")] - -Node is bootstrapped. -This simulation failed: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1040000 - Storage limit: 60000 bytes - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 - "p2[SIGNATURE]") - This operation FAILED. - -Runtime error in contract [CONTRACT_HASH]: - 01: { parameter (pair bytes signature) ; - 02: storage key ; - 03: code { DUP ; - 04: CAAR ; - 05: DUP ; - 06: SIZE ; - 07: PUSH nat 128 ; - 08: SWAP ; - 09: SUB ; - 10: ISNAT ; - 11: ASSERT_SOME ; - 12: PUSH nat 128 ; - 13: SLICE @payload ; - 14: ASSERT_SOME ; - 15: DUP ; - 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; - 17: SHA256 ; - 18: ASSERT_CMPEQ } ; - 19: DUP ; - 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; - 21: BLAKE2B ; - 22: ASSERT_CMPEQ } ; - 23: DUP ; - 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; - 25: SHA512 ; - 26: ASSERT_CMPEQ } ; - 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; - 28: SWAP ; - 29: DIP { SWAP } ; - 30: CHECK_SIGNATURE ; - 31: ASSERT ; - 32: CDR ; - 33: DUP ; - 34: HASH_KEY ; - 35: IMPLICIT_ACCOUNT ; - 36: BALANCE ; - 37: UNIT ; - 38: TRANSFER_TOKENS ; - 39: NIL operation ; - 40: SWAP ; - 41: CONS ; - 42: PAIR } } -At line 31 characters 9 to 15, -script reached FAILWITH instruction -with Unit -Fatal error: - transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75.c583c796bf.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75.c583c796bf.out deleted file mode 100644 index a3c3b7a93f98..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75.c583c796bf.out +++ /dev/null @@ -1,66 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] - -Node is bootstrapped. -This simulation failed: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1040000 - Storage limit: 60000 bytes - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 - "sp[SIGNATURE]m") - This operation FAILED. - -Runtime error in contract [CONTRACT_HASH]: - 01: { parameter (pair bytes signature) ; - 02: storage key ; - 03: code { DUP ; - 04: CAAR ; - 05: DUP ; - 06: SIZE ; - 07: PUSH nat 128 ; - 08: SWAP ; - 09: SUB ; - 10: ISNAT ; - 11: ASSERT_SOME ; - 12: PUSH nat 128 ; - 13: SLICE @payload ; - 14: ASSERT_SOME ; - 15: DUP ; - 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; - 17: SHA256 ; - 18: ASSERT_CMPEQ } ; - 19: DUP ; - 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; - 21: BLAKE2B ; - 22: ASSERT_CMPEQ } ; - 23: DUP ; - 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; - 25: SHA512 ; - 26: ASSERT_CMPEQ } ; - 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; - 28: SWAP ; - 29: DIP { SWAP } ; - 30: CHECK_SIGNATURE ; - 31: ASSERT ; - 32: CDR ; - 33: DUP ; - 34: HASH_KEY ; - 35: IMPLICIT_ACCOUNT ; - 36: BALANCE ; - 37: UNIT ; - 38: TRANSFER_TOKENS ; - 39: NIL operation ; - 40: SWAP ; - 41: CONS ; - 42: PAIR } } -At line 18 characters 15 to 27, -script reached FAILWITH instruction -with Unit -Fatal error: - transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out deleted file mode 100644 index 537cc249e7e7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out +++ /dev/null @@ -1,46 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] - -Node is bootstrapped. -Estimated gas: 4184.720 units (will add 100 for safety) -Estimated storage: 257 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000936 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 4285 - Storage limit: 277 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000936 - payload fees(the block proposer) ....... +ꜩ0.000936 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 - "sp[SIGNATURE]m") - This transaction was successfully applied - Updated storage: - [OPERATION_HASH]48f709699019725ba - Storage size: 578 bytes - Consumed gas: 2764.720 - Internal operations: - Transaction: - Amount: ꜩ1000 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Consumed gas: 1420 - Balance updates: - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_source.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_source.out deleted file mode 100644 index ce1d610a1d4b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_source.out +++ /dev/null @@ -1,119 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_source - -Node is bootstrapped. -Estimated gas: 2066.897 units (will add 100 for safety) -Estimated storage: 322 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000527 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2167 - Storage limit: 342 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000527 - payload fees(the block proposer) ....... +ꜩ0.000527 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter unit ; - storage address ; - code { DROP ; SOURCE ; NIL operation ; PAIR } } - Initial storage: "[CONTRACT_HASH]" - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 65 bytes - Paid storage size diff: 65 bytes - Consumed gas: 2066.897 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01625 - storage fees ........................... +ꜩ0.01625 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as source. -Injected block at minimal timestamp -Node is bootstrapped. -Estimated gas: 2710.682 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.00053 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2811 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00053 - payload fees(the block proposer) ....... +ꜩ0.00053 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Updated storage: 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c - Storage size: 65 bytes - Consumed gas: 2710.682 - -Injected block at minimal timestamp -"[CONTRACT_HASH]" -[CONTRACT_HASH] - -Node is bootstrapped. -Estimated gas: 4338.863 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000738 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 4439 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000738 - payload fees(the block proposer) ....... +ꜩ0.000738 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: "[CONTRACT_HASH]" - This transaction was successfully applied - Updated storage: Unit - Storage size: 55 bytes - Consumed gas: 3126.358 - Internal operations: - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Updated storage: 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c - Storage size: 65 bytes - Consumed gas: 1212.505 - -Injected block at minimal timestamp -"[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_bytes.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_bytes.out deleted file mode 100644 index c67c65266a30..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_bytes.out +++ /dev/null @@ -1,139 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_split_bytes - -Node is bootstrapped. -Estimated gas: 1446.644 units (will add 100 for safety) -Estimated storage: 511 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.00064 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1547 - Storage limit: 531 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00064 - payload fees(the block proposer) ....... +ꜩ0.00064 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter bytes ; - storage (list bytes) ; - code { UNPAIR ; - DIP { NIL bytes ; SWAP ; ITER { CONS } } ; - DUP ; - SIZE ; - PUSH nat 0 ; - CMPNEQ ; - DIP { PUSH @index nat 0 } ; - LOOP { PAIR ; - DUP ; - DIP { UNPAIR ; DIP { PUSH nat 1 } ; SLICE ; ASSERT_SOME ; CONS @storage } ; - UNPAIR ; - PUSH nat 1 ; - ADD @index ; - DUP ; - DIP { DIP { DUP } ; SWAP ; SIZE ; CMPNEQ } ; - SWAP } ; - DROP ; - DROP ; - NIL bytes ; - SWAP ; - ITER { CONS } ; - NIL operation ; - PAIR } } - Initial storage: {} - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 254 bytes - Paid storage size diff: 254 bytes - Consumed gas: 1446.644 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0635 - storage fees ........................... +ꜩ0.0635 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as split_bytes. -Injected block at minimal timestamp -Node is bootstrapped. -Estimated gas: 2097.375 units (will add 100 for safety) -Estimated storage: 18 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000481 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2198 - Storage limit: 38 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000481 - payload fees(the block proposer) ....... +ꜩ0.000481 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: 0xaabbcc - This transaction was successfully applied - Updated storage: { 0xaa ; 0xbb ; 0xcc } - Storage size: 272 bytes - Paid storage size diff: 18 bytes - Consumed gas: 2097.375 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0045 - storage fees ........................... +ꜩ0.0045 - -Injected block at minimal timestamp -{ 0xaa ; 0xbb ; 0xcc } -Node is bootstrapped. -Estimated gas: 1206.814 units (will add 100 for safety) -Estimated storage: 18 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000392 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1307 - Storage limit: 38 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000392 - payload fees(the block proposer) ....... +ꜩ0.000392 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: 0xddeeff - This transaction was successfully applied - Updated storage: { 0xaa ; 0xbb ; 0xcc ; 0xdd ; 0xee ; 0xff } - Storage size: 290 bytes - Paid storage size diff: 18 bytes - Consumed gas: 1206.814 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0045 - storage fees ........................... +ꜩ0.0045 - -Injected block at minimal timestamp -{ 0xaa ; 0xbb ; 0xcc ; 0xdd ; 0xee ; 0xff } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_string.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_string.out deleted file mode 100644 index 316ea751920b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_string.out +++ /dev/null @@ -1,139 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_split_string - -Node is bootstrapped. -Estimated gas: 1446.644 units (will add 100 for safety) -Estimated storage: 511 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.00064 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1547 - Storage limit: 531 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00064 - payload fees(the block proposer) ....... +ꜩ0.00064 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter string ; - storage (list string) ; - code { UNPAIR ; - DIP { NIL string ; SWAP ; ITER { CONS } } ; - DUP ; - SIZE ; - PUSH nat 0 ; - CMPNEQ ; - DIP { PUSH @index nat 0 } ; - LOOP { PAIR ; - DUP ; - DIP { UNPAIR ; DIP { PUSH nat 1 } ; SLICE ; ASSERT_SOME ; CONS @storage } ; - UNPAIR ; - PUSH nat 1 ; - ADD @index ; - DUP ; - DIP { DIP { DUP } ; SWAP ; SIZE ; CMPNEQ } ; - SWAP } ; - DROP ; - DROP ; - NIL string ; - SWAP ; - ITER { CONS } ; - NIL operation ; - PAIR } } - Initial storage: {} - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 254 bytes - Paid storage size diff: 254 bytes - Consumed gas: 1446.644 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0635 - storage fees ........................... +ꜩ0.0635 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as split_string. -Injected block at minimal timestamp -Node is bootstrapped. -Estimated gas: 2097.362 units (will add 100 for safety) -Estimated storage: 18 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000481 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2198 - Storage limit: 38 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000481 - payload fees(the block proposer) ....... +ꜩ0.000481 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: "abc" - This transaction was successfully applied - Updated storage: { "a" ; "b" ; "c" } - Storage size: 272 bytes - Paid storage size diff: 18 bytes - Consumed gas: 2097.362 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0045 - storage fees ........................... +ꜩ0.0045 - -Injected block at minimal timestamp -{ "a" ; "b" ; "c" } -Node is bootstrapped. -Estimated gas: 1206.801 units (will add 100 for safety) -Estimated storage: 18 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000392 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1307 - Storage limit: 38 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000392 - payload fees(the block proposer) ....... +ꜩ0.000392 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: "def" - This transaction was successfully applied - Updated storage: { "a" ; "b" ; "c" ; "d" ; "e" ; "f" } - Storage size: 290 bytes - Paid storage size diff: 18 bytes - Consumed gas: 1206.801 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0045 - storage fees ........................... +ꜩ0.0045 - -Injected block at minimal timestamp -{ "a" ; "b" ; "c" ; "d" ; "e" ; "f" } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out deleted file mode 100644 index 050517c2c48c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out +++ /dev/null @@ -1,185 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_store_input - -Node is bootstrapped. -Estimated gas: 1420.040 units (will add 100 for safety) -Estimated storage: 257 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000406 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1521 - Storage limit: 277 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000406 - payload fees(the block proposer) ....... +ꜩ0.000406 - Transaction: - Amount: ꜩ1000 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Consumed gas: 1420.040 - Balance updates: - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - -Injected block at minimal timestamp -Node is bootstrapped. -Estimated gas: 1420.040 units (will add 100 for safety) -Estimated storage: 257 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000406 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1521 - Storage limit: 277 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000406 - payload fees(the block proposer) ....... +ꜩ0.000406 - Transaction: - Amount: ꜩ2000 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Consumed gas: 1420.040 - Balance updates: - [CONTRACT_HASH] ... -ꜩ2000 - [CONTRACT_HASH] ... +ꜩ2000 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - -Injected block at minimal timestamp -1000 ꜩ -2000 ꜩ -Node is bootstrapped. -Estimated gas: 1405.336 units (will add 100 for safety) -Estimated storage: 298 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000422 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1506 - Storage limit: 318 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000422 - payload fees(the block proposer) ....... +ꜩ0.000422 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ100 - Script: - { parameter string ; - storage string ; - code { CAR ; NIL operation ; PAIR } } - Initial storage: "" - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 41 bytes - Paid storage size diff: 41 bytes - Consumed gas: 1405.336 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01025 - storage fees ........................... +ꜩ0.01025 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - -New contract [CONTRACT_HASH] originated. -Contract memorized as store_input. -Injected block at minimal timestamp -Node is bootstrapped. -Estimated gas: 2049.248 units (will add 100 for safety) -Estimated storage: 7 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000483 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2150 - Storage limit: 27 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000483 - payload fees(the block proposer) ....... +ꜩ0.000483 - Transaction: - Amount: ꜩ100 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: "abcdefg" - This transaction was successfully applied - Updated storage: "abcdefg" - Storage size: 48 bytes - Paid storage size diff: 7 bytes - Consumed gas: 2049.248 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00175 - storage fees ........................... +ꜩ0.00175 - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - -Injected block at minimal timestamp -200 ꜩ -"abcdefg" -Node is bootstrapped. -Estimated gas: 1202.528 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000395 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1303 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000395 - payload fees(the block proposer) ....... +ꜩ0.000395 - Transaction: - Amount: ꜩ100 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: "xyz" - This transaction was successfully applied - Updated storage: "xyz" - Storage size: 44 bytes - Consumed gas: 1202.528 - Balance updates: - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - -Injected block at minimal timestamp -"xyz" diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz].out deleted file mode 100644 index 0affd6b05dcb..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz].out +++ /dev/null @@ -1,93 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz] - -Node is bootstrapped. -Estimated gas: 3415.815 units (will add 100 for safety) -Estimated storage: 385 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000711 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 3516 - Storage limit: 405 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000711 - payload fees(the block proposer) ....... +ꜩ0.000711 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter unit ; - storage unit ; - code { DROP ; - PUSH nat 0 ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DROP ; - UNIT ; - NIL operation ; - PAIR } } - Initial storage: Unit - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 128 bytes - Paid storage size diff: 128 bytes - Consumed gas: 3415.815 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.032 - storage fees ........................... +ꜩ0.032 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as compare_big_type. -Injected block at minimal timestamp -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz].out deleted file mode 100644 index d2a1102dc7bc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz].out +++ /dev/null @@ -1,97 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz] - -Node is bootstrapped. -Estimated gas: 3740.366 units (will add 100 for safety) -Estimated storage: 393 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000752 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 3841 - Storage limit: 413 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000752 - payload fees(the block proposer) ....... +ꜩ0.000752 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter unit ; - storage unit ; - code { DROP ; - PUSH nat 0 ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - PAIR ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DUP ; - DUP ; - COMPARE ; - DROP ; - DROP ; - UNIT ; - NIL operation ; - PAIR } } - Initial storage: Unit - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 136 bytes - Paid storage size diff: 136 bytes - Consumed gas: 3740.366 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.034 - storage fees ........................... +ꜩ0.034 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as compare_big_type2. -Injected block at minimal timestamp -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_amount.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_amount.out deleted file mode 100644 index 0d8eddd2c790..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_amount.out +++ /dev/null @@ -1,83 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_transfer_amount - -Node is bootstrapped. -Estimated gas: 1405.897 units (will add 100 for safety) -Estimated storage: 297 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000421 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1506 - Storage limit: 317 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000421 - payload fees(the block proposer) ....... +ꜩ0.000421 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ100 - Script: - { parameter unit ; - storage mutez ; - code { DROP ; AMOUNT ; NIL operation ; PAIR } } - Initial storage: 0 - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 40 bytes - Paid storage size diff: 40 bytes - Consumed gas: 1405.897 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01 - storage fees ........................... +ꜩ0.01 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - -New contract [CONTRACT_HASH] originated. -Contract memorized as transfer_amount. -Injected block at minimal timestamp -Node is bootstrapped. -Estimated gas: 2049.528 units (will add 100 for safety) -Estimated storage: 4 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000467 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2150 - Storage limit: 24 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000467 - payload fees(the block proposer) ....... +ꜩ0.000467 - Transaction: - Amount: ꜩ500 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Updated storage: 500000000 - Storage size: 44 bytes - Paid storage size diff: 4 bytes - Consumed gas: 2049.528 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.001 - storage fees ........................... +ꜩ0.001 - [CONTRACT_HASH] ... -ꜩ500 - [CONTRACT_HASH] ... +ꜩ500 - -Injected block at minimal timestamp -500000000 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_tokens.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_tokens.out deleted file mode 100644 index 5d512b1fb6be..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_tokens.out +++ /dev/null @@ -1,238 +0,0 @@ -tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_transfer_tokens - -Node is bootstrapped. -Estimated gas: 1405.250 units (will add 100 for safety) -Estimated storage: 295 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000419 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1506 - Storage limit: 315 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000419 - payload fees(the block proposer) ....... +ꜩ0.000419 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ100 - Script: - { parameter unit ; storage unit ; code { CDR ; NIL operation ; PAIR } } - Initial storage: Unit - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 38 bytes - Paid storage size diff: 38 bytes - Consumed gas: 1405.250 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0095 - storage fees ........................... +ꜩ0.0095 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - -New contract [CONTRACT_HASH] originated. -Contract memorized as test_transfer_account1. -Injected block at minimal timestamp -Node is bootstrapped. -Estimated gas: 1405.250 units (will add 100 for safety) -Estimated storage: 295 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000419 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1506 - Storage limit: 315 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000419 - payload fees(the block proposer) ....... +ꜩ0.000419 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ20 - Script: - { parameter unit ; storage unit ; code { CDR ; NIL operation ; PAIR } } - Initial storage: Unit - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 38 bytes - Paid storage size diff: 38 bytes - Consumed gas: 1405.250 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0095 - storage fees ........................... +ꜩ0.0095 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ20 - [CONTRACT_HASH] ... +ꜩ20 - -New contract [CONTRACT_HASH] originated. -Contract memorized as test_transfer_account2. -Injected block at minimal timestamp -Node is bootstrapped. -Estimated gas: 1411.459 units (will add 100 for safety) -Estimated storage: 323 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000449 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 1512 - Storage limit: 343 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000449 - payload fees(the block proposer) ....... +ꜩ0.000449 - Origination: - From: [CONTRACT_HASH] - Credit: ꜩ1000 - Script: - { parameter (contract unit) ; - storage unit ; - code { CAR ; - DIP { UNIT } ; - PUSH mutez 100000000 ; - UNIT ; - TRANSFER_TOKENS ; - NIL operation ; - SWAP ; - CONS ; - PAIR } } - Initial storage: Unit - No delegate for this contract - This origination was successfully applied - Originated contracts: - [CONTRACT_HASH] - Storage size: 66 bytes - Paid storage size diff: 66 bytes - Consumed gas: 1411.459 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0165 - storage fees ........................... +ꜩ0.0165 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - [CONTRACT_HASH] ... -ꜩ1000 - [CONTRACT_HASH] ... +ꜩ1000 - -New contract [CONTRACT_HASH] originated. -Contract memorized as transfer_tokens. -Injected block at minimal timestamp -100 ꜩ -[CONTRACT_HASH] - -Node is bootstrapped. -Estimated gas: 5177.026 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000825 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 5278 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000825 - payload fees(the block proposer) ....... +ꜩ0.000825 - Transaction: - Amount: ꜩ100 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: "[CONTRACT_HASH]" - This transaction was successfully applied - Updated storage: Unit - Storage size: 66 bytes - Consumed gas: 3128.352 - Balance updates: - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - Internal operations: - Transaction: - Amount: ꜩ100 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Updated storage: Unit - Storage size: 38 bytes - Consumed gas: 2048.674 - Balance updates: - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - -Injected block at minimal timestamp -200 ꜩ -[CONTRACT_HASH] - -Node is bootstrapped. -Estimated gas: 4323.909 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.00074 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 4424 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00074 - payload fees(the block proposer) ....... +ꜩ0.00074 - Transaction: - Amount: ꜩ100 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Parameter: "[CONTRACT_HASH]" - This transaction was successfully applied - Updated storage: Unit - Storage size: 66 bytes - Consumed gas: 2275.235 - Balance updates: - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - Internal operations: - Transaction: - Amount: ꜩ100 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Updated storage: Unit - Storage size: 38 bytes - Consumed gas: 2048.674 - Balance updates: - [CONTRACT_HASH] ... -ꜩ100 - [CONTRACT_HASH] ... +ꜩ100 - -Injected block at minimal timestamp -120 ꜩ diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" deleted file mode 100644 index f1d6749a08ee..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-"hello"-(Pair None 4)-big_map_diff10] - -storage - (Pair None 4) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["hello"] to 4 -trace - - location: 13 (remaining gas: 1039989.246 units remaining) - [ (Pair "hello" (Some 4) {}) ] - - location: 13 (remaining gas: 1039989.236 units remaining) - [ "hello" @parameter - (Pair (Some 4) {}) @storage ] - - location: 14 (remaining gas: 1039989.221 units remaining) - [ (Pair (Some 4) {}) @storage ] - - location: 16 (remaining gas: 1039989.211 units remaining) - [ (Some 4) - {} ] - - location: 14 (remaining gas: 1039989.181 units remaining) - [ "hello" @parameter - (Some 4) - {} ] - - location: 17 (remaining gas: 1039988.109 units remaining) - [ None - { Elt "hello" 4 } ] - - location: 18 (remaining gas: 1039988.094 units remaining) - [ (Pair None { Elt "hello" 4 }) ] - - location: 19 (remaining gas: 1039988.079 units remaining) - [ {} - (Pair None { Elt "hello" 4 }) ] - - location: 21 (remaining gas: 1039988.064 units remaining) - [ (Pair {} None { Elt "hello" 4 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0427752f13.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0427752f13.out" deleted file mode 100644 index 8cc228fcf8fa..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0427752f13.out" +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt "hello" 4 })-"hello"-(Pair (Some 4) 4)-big_map_diff12] - -storage - (Pair (Some 4) 4) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["hello"] to 5 -trace - - location: 13 (remaining gas: 1039987.916 units remaining) - [ (Pair "hello" (Some 5) { Elt "hello" 4 }) ] - - location: 13 (remaining gas: 1039987.906 units remaining) - [ "hello" @parameter - (Pair (Some 5) { Elt "hello" 4 }) @storage ] - - location: 14 (remaining gas: 1039987.891 units remaining) - [ (Pair (Some 5) { Elt "hello" 4 }) @storage ] - - location: 16 (remaining gas: 1039987.881 units remaining) - [ (Some 5) - { Elt "hello" 4 } ] - - location: 14 (remaining gas: 1039987.851 units remaining) - [ "hello" @parameter - (Some 5) - { Elt "hello" 4 } ] - - location: 17 (remaining gas: 1039986.774 units remaining) - [ (Some 4) - { Elt "hello" 5 } ] - - location: 18 (remaining gas: 1039986.759 units remaining) - [ (Pair (Some 4) { Elt "hello" 5 }) ] - - location: 19 (remaining gas: 1039986.744 units remaining) - [ {} - (Pair (Some 4) { Elt "hello" 5 }) ] - - location: 21 (remaining gas: 1039986.729 units remaining) - [ (Pair {} (Some 4) { Elt "hello" 5 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0793dc66d5.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0793dc66d5.out" deleted file mode 100644 index 2bc064c3f32a..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0793dc66d5.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt "hello" 4 })-"hi"-(Pair None 4)-big_map_diff13] - -storage - (Pair None 4) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["hello"] to 4 - Set map(4)["hi"] to 5 -trace - - location: 13 (remaining gas: 1039987.946 units remaining) - [ (Pair "hi" (Some 5) { Elt "hello" 4 }) ] - - location: 13 (remaining gas: 1039987.936 units remaining) - [ "hi" @parameter - (Pair (Some 5) { Elt "hello" 4 }) @storage ] - - location: 14 (remaining gas: 1039987.921 units remaining) - [ (Pair (Some 5) { Elt "hello" 4 }) @storage ] - - location: 16 (remaining gas: 1039987.911 units remaining) - [ (Some 5) - { Elt "hello" 4 } ] - - location: 14 (remaining gas: 1039987.881 units remaining) - [ "hi" @parameter - (Some 5) - { Elt "hello" 4 } ] - - location: 17 (remaining gas: 1039986.906 units remaining) - [ None - { Elt "hello" 4 ; Elt "hi" 5 } ] - - location: 18 (remaining gas: 1039986.891 units remaining) - [ (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) ] - - location: 19 (remaining gas: 1039986.876 units remaining) - [ {} - (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) ] - - location: 21 (remaining gas: 1039986.861 units remaining) - [ (Pair {} None { Elt "hello" 4 ; Elt "hi" 5 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .df114499b8.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .df114499b8.out" deleted file mode 100644 index 90cf876d8073..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .df114499b8.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt "1" 1 ; Elt "2" 2 })-"1"-(Pair (Some 1) 4)-big_map_diff14] - -storage - (Pair (Some 1) 4) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["2"] to 2 - Unset map(4)["1"] -trace - - location: 13 (remaining gas: 1039987.042 units remaining) - [ (Pair "1" None { Elt "1" 1 ; Elt "2" 2 }) ] - - location: 13 (remaining gas: 1039987.032 units remaining) - [ "1" @parameter - (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] - - location: 14 (remaining gas: 1039987.017 units remaining) - [ (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] - - location: 16 (remaining gas: 1039987.007 units remaining) - [ None - { Elt "1" 1 ; Elt "2" 2 } ] - - location: 14 (remaining gas: 1039986.977 units remaining) - [ "1" @parameter - None - { Elt "1" 1 ; Elt "2" 2 } ] - - location: 17 (remaining gas: 1039986.033 units remaining) - [ (Some 1) - { Elt "2" 2 } ] - - location: 18 (remaining gas: 1039986.018 units remaining) - [ (Pair (Some 1) { Elt "2" 2 }) ] - - location: 19 (remaining gas: 1039986.003 units remaining) - [ {} - (Pair (Some 1) { Elt "2" 2 }) ] - - location: 21 (remaining gas: 1039985.988 units remaining) - [ (Pair {} (Some 1) { Elt "2" 2 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .f9bea98de9.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .f9bea98de9.out" deleted file mode 100644 index bab91446cb0a..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .f9bea98de9.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt "1" 1 ; Elt "2" 2 })-"1"-(Pair (Some 1) 4)-big_map_diff15] - -storage - (Pair (Some 1) 4) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["2"] to 2 - Unset map(4)["1"] -trace - - location: 13 (remaining gas: 1039987.042 units remaining) - [ (Pair "1" None { Elt "1" 1 ; Elt "2" 2 }) ] - - location: 13 (remaining gas: 1039987.032 units remaining) - [ "1" @parameter - (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] - - location: 14 (remaining gas: 1039987.017 units remaining) - [ (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] - - location: 16 (remaining gas: 1039987.007 units remaining) - [ None - { Elt "1" 1 ; Elt "2" 2 } ] - - location: 14 (remaining gas: 1039986.977 units remaining) - [ "1" @parameter - None - { Elt "1" 1 ; Elt "2" 2 } ] - - location: 17 (remaining gas: 1039986.033 units remaining) - [ (Some 1) - { Elt "2" 2 } ] - - location: 18 (remaining gas: 1039986.018 units remaining) - [ (Pair (Some 1) { Elt "2" 2 }) ] - - location: 19 (remaining gas: 1039986.003 units remaining) - [ {} - (Pair (Some 1) { Elt "2" 2 }) ] - - location: 21 (remaining gas: 1039985.988 units remaining) - [ (Pair {} (Some 1) { Elt "2" 2 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"hello\" 4 })-.1db12cd837.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"hello\" 4 })-.1db12cd837.out" deleted file mode 100644 index f2fc60c81829..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"hello\" 4 })-.1db12cd837.out" +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt "hello" 4 })-"hello"-(Pair (Some 4) 4)-big_map_diff11] - -storage - (Pair (Some 4) 4) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Unset map(4)["hello"] -trace - - location: 13 (remaining gas: 1039988.016 units remaining) - [ (Pair "hello" None { Elt "hello" 4 }) ] - - location: 13 (remaining gas: 1039988.006 units remaining) - [ "hello" @parameter - (Pair None { Elt "hello" 4 }) @storage ] - - location: 14 (remaining gas: 1039987.991 units remaining) - [ (Pair None { Elt "hello" 4 }) @storage ] - - location: 16 (remaining gas: 1039987.981 units remaining) - [ None - { Elt "hello" 4 } ] - - location: 14 (remaining gas: 1039987.951 units remaining) - [ "hello" @parameter - None - { Elt "hello" 4 } ] - - location: 17 (remaining gas: 1039986.874 units remaining) - [ (Some 4) - {} ] - - location: 18 (remaining gas: 1039986.859 units remaining) - [ (Pair (Some 4) {}) ] - - location: 19 (remaining gas: 1039986.844 units remaining) - [ {} - (Pair (Some 4) {}) ] - - location: 21 (remaining gas: 1039986.829 units remaining) - [ (Pair {} (Some 4) {}) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-\"hello\"-(Pair N.6fc7d0acf2.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-\"hello\"-(Pair N.6fc7d0acf2.out" deleted file mode 100644 index 0816a5510631..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-\"hello\"-(Pair N.6fc7d0acf2.out" +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-"hello"-(Pair None 4)-big_map_diff9] - -storage - (Pair None 4) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Unset map(4)["hello"] -trace - - location: 13 (remaining gas: 1039989.346 units remaining) - [ (Pair "hello" None {}) ] - - location: 13 (remaining gas: 1039989.336 units remaining) - [ "hello" @parameter - (Pair None {}) @storage ] - - location: 14 (remaining gas: 1039989.321 units remaining) - [ (Pair None {}) @storage ] - - location: 16 (remaining gas: 1039989.311 units remaining) - [ None - {} ] - - location: 14 (remaining gas: 1039989.281 units remaining) - [ "hello" @parameter - None - {} ] - - location: 17 (remaining gas: 1039988.209 units remaining) - [ None - {} ] - - location: 18 (remaining gas: 1039988.194 units remaining) - [ (Pair None {}) ] - - location: 19 (remaining gas: 1039988.179 units remaining) - [ {} - (Pair None {}) ] - - location: 21 (remaining gas: 1039988.164 units remaining) - [ (Pair {} None {}) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"tw.524c5459f8.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"tw.524c5459f8.out" deleted file mode 100644 index f70db4bc7d1c..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"tw.524c5459f8.out" +++ /dev/null @@ -1,46 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } None)-"1"-(Pair 4 (Some "one"))-big_map_diff2] - -storage - (Pair 4 (Some "one")) -emitted operations - -big_map diff - New map(4) of type (big_map string string) - Set map(4)["2"] to "two" - Set map(4)["1"] to "one" -trace - - location: 12 (remaining gas: 1039983.953 units remaining) - [ (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) ] - - location: 12 (remaining gas: 1039983.943 units remaining) - [ (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) - (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) ] - - location: 13 (remaining gas: 1039983.933 units remaining) - [ "1" @parameter - (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) ] - - location: 14 (remaining gas: 1039983.918 units remaining) - [ (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) ] - - location: 17 (remaining gas: 1039983.908 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } None) @storage ] - - location: 18 (remaining gas: 1039983.898 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } ] - - location: 19 (remaining gas: 1039983.888 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - { Elt "1" "one" ; Elt "2" "two" } ] - - location: 14 (remaining gas: 1039983.858 units remaining) - [ "1" @parameter - { Elt "1" "one" ; Elt "2" "two" } - { Elt "1" "one" ; Elt "2" "two" } ] - - location: 20 (remaining gas: 1039982.948 units remaining) - [ (Some "one") - { Elt "1" "one" ; Elt "2" "two" } ] - - location: 21 (remaining gas: 1039982.938 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - (Some "one") ] - - location: 22 (remaining gas: 1039982.923 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } (Some "one")) ] - - location: 23 (remaining gas: 1039982.908 units remaining) - [ {} - (Pair { Elt "1" "one" ; Elt "2" "two" } (Some "one")) ] - - location: 25 (remaining gas: 1039982.893 units remaining) - [ (Pair {} { Elt "1" "one" ; Elt "2" "two" } (Some "one")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"\".33eba403e7.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"\".33eba403e7.out" deleted file mode 100644 index 085ebec66966..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"\".33eba403e7.out" +++ /dev/null @@ -1,45 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt "hello" "hi" } None)-""-(Pair 4 None)-big_map_diff1] - -storage - (Pair 4 None) -emitted operations - -big_map diff - New map(4) of type (big_map string string) - Set map(4)["hello"] to "hi" -trace - - location: 12 (remaining gas: 1039985.031 units remaining) - [ (Pair "" { Elt "hello" "hi" } None) ] - - location: 12 (remaining gas: 1039985.021 units remaining) - [ (Pair "" { Elt "hello" "hi" } None) - (Pair "" { Elt "hello" "hi" } None) ] - - location: 13 (remaining gas: 1039985.011 units remaining) - [ "" @parameter - (Pair "" { Elt "hello" "hi" } None) ] - - location: 14 (remaining gas: 1039984.996 units remaining) - [ (Pair "" { Elt "hello" "hi" } None) ] - - location: 17 (remaining gas: 1039984.986 units remaining) - [ (Pair { Elt "hello" "hi" } None) @storage ] - - location: 18 (remaining gas: 1039984.976 units remaining) - [ { Elt "hello" "hi" } ] - - location: 19 (remaining gas: 1039984.966 units remaining) - [ { Elt "hello" "hi" } - { Elt "hello" "hi" } ] - - location: 14 (remaining gas: 1039984.936 units remaining) - [ "" @parameter - { Elt "hello" "hi" } - { Elt "hello" "hi" } ] - - location: 20 (remaining gas: 1039984.061 units remaining) - [ None - { Elt "hello" "hi" } ] - - location: 21 (remaining gas: 1039984.051 units remaining) - [ { Elt "hello" "hi" } - None ] - - location: 22 (remaining gas: 1039984.036 units remaining) - [ (Pair { Elt "hello" "hi" } None) ] - - location: 23 (remaining gas: 1039984.021 units remaining) - [ {} - (Pair { Elt "hello" "hi" } None) ] - - location: 25 (remaining gas: 1039984.006 units remaining) - [ (Pair {} { Elt "hello" "hi" } None) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"h.a5cd1005c9.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"h.a5cd1005c9.out" deleted file mode 100644 index ad4c2d7be3d8..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"h.a5cd1005c9.out" +++ /dev/null @@ -1,45 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt "hello" "hi" } None)-"hello"-(Pair 4 (Some "hi"))-big_map_diff0] - -storage - (Pair 4 (Some "hi")) -emitted operations - -big_map diff - New map(4) of type (big_map string string) - Set map(4)["hello"] to "hi" -trace - - location: 12 (remaining gas: 1039984.981 units remaining) - [ (Pair "hello" { Elt "hello" "hi" } None) ] - - location: 12 (remaining gas: 1039984.971 units remaining) - [ (Pair "hello" { Elt "hello" "hi" } None) - (Pair "hello" { Elt "hello" "hi" } None) ] - - location: 13 (remaining gas: 1039984.961 units remaining) - [ "hello" @parameter - (Pair "hello" { Elt "hello" "hi" } None) ] - - location: 14 (remaining gas: 1039984.946 units remaining) - [ (Pair "hello" { Elt "hello" "hi" } None) ] - - location: 17 (remaining gas: 1039984.936 units remaining) - [ (Pair { Elt "hello" "hi" } None) @storage ] - - location: 18 (remaining gas: 1039984.926 units remaining) - [ { Elt "hello" "hi" } ] - - location: 19 (remaining gas: 1039984.916 units remaining) - [ { Elt "hello" "hi" } - { Elt "hello" "hi" } ] - - location: 14 (remaining gas: 1039984.886 units remaining) - [ "hello" @parameter - { Elt "hello" "hi" } - { Elt "hello" "hi" } ] - - location: 20 (remaining gas: 1039983.840 units remaining) - [ (Some "hi") - { Elt "hello" "hi" } ] - - location: 21 (remaining gas: 1039983.830 units remaining) - [ { Elt "hello" "hi" } - (Some "hi") ] - - location: 22 (remaining gas: 1039983.815 units remaining) - [ (Pair { Elt "hello" "hi" } (Some "hi")) ] - - location: 23 (remaining gas: 1039983.800 units remaining) - [ {} - (Pair { Elt "hello" "hi" } (Some "hi")) ] - - location: 25 (remaining gas: 1039983.785 units remaining) - [ (Pair {} { Elt "hello" "hi" } (Some "hi")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .6f3d35b151.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .6f3d35b151.out" deleted file mode 100644 index ca5783720721..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .6f3d35b151.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{}-(Pair 4 Unit)-big_map_diff3] - -storage - (Pair 4 Unit) -emitted operations - -big_map diff - New map(4) of type (big_map string string) - Set map(4)["2"] to "two" - Set map(4)["1"] to "one" -trace - - location: 15 (remaining gas: 1039984.639 units remaining) - [ (Pair {} { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 15 (remaining gas: 1039984.629 units remaining) - [ {} @parameter - (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 16 (remaining gas: 1039984.614 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 18 (remaining gas: 1039984.604 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 16 (remaining gas: 1039984.574 units remaining) - [ {} @parameter - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 19 (remaining gas: 1039984.574 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 23 (remaining gas: 1039984.559 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 24 (remaining gas: 1039984.544 units remaining) - [ {} - (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 26 (remaining gas: 1039984.529 units remaining) - [ (Pair {} { Elt "1" "one" ; Elt "2" "two" } Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .76aeaa0706.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .76aeaa0706.out" deleted file mode 100644 index 809f7c4f281b..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .76aeaa0706.out" +++ /dev/null @@ -1,48 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "1" (Some "two") }-(Pair 4 Unit)-big_map_diff4] - -storage - (Pair 4 Unit) -emitted operations - -big_map diff - New map(4) of type (big_map string string) - Set map(4)["2"] to "two" - Set map(4)["1"] to "two" -trace - - location: 15 (remaining gas: 1039984.121 units remaining) - [ (Pair { Elt "1" (Some "two") } { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 15 (remaining gas: 1039984.111 units remaining) - [ { Elt "1" (Some "two") } @parameter - (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 16 (remaining gas: 1039984.096 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 18 (remaining gas: 1039984.086 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 16 (remaining gas: 1039984.056 units remaining) - [ { Elt "1" (Some "two") } @parameter - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 19 (remaining gas: 1039984.056 units remaining) - [ (Pair "1" (Some "two")) - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 21 (remaining gas: 1039984.046 units remaining) - [ "1" @key - (Some "two") @elt - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 22 (remaining gas: 1039983.111 units remaining) - [ { Elt "1" "two" ; Elt "2" "two" } - Unit ] - - location: 19 (remaining gas: 1039983.096 units remaining) - [ { Elt "1" "two" ; Elt "2" "two" } - Unit ] - - location: 23 (remaining gas: 1039983.081 units remaining) - [ (Pair { Elt "1" "two" ; Elt "2" "two" } Unit) ] - - location: 24 (remaining gas: 1039983.066 units remaining) - [ {} - (Pair { Elt "1" "two" ; Elt "2" "two" } Unit) ] - - location: 26 (remaining gas: 1039983.051 units remaining) - [ (Pair {} { Elt "1" "two" ; Elt "2" "two" } Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7e7197f248.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7e7197f248.out" deleted file mode 100644 index 076094a58227..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7e7197f248.out" +++ /dev/null @@ -1,48 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "1" (Some "two") }-(Pair 4 Unit)-big_map_diff8] - -storage - (Pair 4 Unit) -emitted operations - -big_map diff - New map(4) of type (big_map string string) - Set map(4)["2"] to "two" - Set map(4)["1"] to "two" -trace - - location: 15 (remaining gas: 1039984.121 units remaining) - [ (Pair { Elt "1" (Some "two") } { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 15 (remaining gas: 1039984.111 units remaining) - [ { Elt "1" (Some "two") } @parameter - (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 16 (remaining gas: 1039984.096 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 18 (remaining gas: 1039984.086 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 16 (remaining gas: 1039984.056 units remaining) - [ { Elt "1" (Some "two") } @parameter - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 19 (remaining gas: 1039984.056 units remaining) - [ (Pair "1" (Some "two")) - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 21 (remaining gas: 1039984.046 units remaining) - [ "1" @key - (Some "two") @elt - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 22 (remaining gas: 1039983.111 units remaining) - [ { Elt "1" "two" ; Elt "2" "two" } - Unit ] - - location: 19 (remaining gas: 1039983.096 units remaining) - [ { Elt "1" "two" ; Elt "2" "two" } - Unit ] - - location: 23 (remaining gas: 1039983.081 units remaining) - [ (Pair { Elt "1" "two" ; Elt "2" "two" } Unit) ] - - location: 24 (remaining gas: 1039983.066 units remaining) - [ {} - (Pair { Elt "1" "two" ; Elt "2" "two" } Unit) ] - - location: 26 (remaining gas: 1039983.051 units remaining) - [ (Pair {} { Elt "1" "two" ; Elt "2" "two" } Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" deleted file mode 100644 index ded22b12e938..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" +++ /dev/null @@ -1,49 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "3" (Some "three") }-(Pair 4 Unit)-big_map_diff5] - -storage - (Pair 4 Unit) -emitted operations - -big_map diff - New map(4) of type (big_map string string) - Set map(4)["2"] to "two" - Set map(4)["3"] to "three" - Set map(4)["1"] to "one" -trace - - location: 15 (remaining gas: 1039984.101 units remaining) - [ (Pair { Elt "3" (Some "three") } { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 15 (remaining gas: 1039984.091 units remaining) - [ { Elt "3" (Some "three") } @parameter - (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 16 (remaining gas: 1039984.076 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 18 (remaining gas: 1039984.066 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 16 (remaining gas: 1039984.036 units remaining) - [ { Elt "3" (Some "three") } @parameter - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 19 (remaining gas: 1039984.036 units remaining) - [ (Pair "3" (Some "three")) - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 21 (remaining gas: 1039984.026 units remaining) - [ "3" @key - (Some "three") @elt - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 22 (remaining gas: 1039983.091 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } - Unit ] - - location: 19 (remaining gas: 1039983.076 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } - Unit ] - - location: 23 (remaining gas: 1039983.061 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } Unit) ] - - location: 24 (remaining gas: 1039983.046 units remaining) - [ {} - (Pair { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } Unit) ] - - location: 26 (remaining gas: 1039983.031 units remaining) - [ (Pair {} { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .b688cc94a7.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .b688cc94a7.out" deleted file mode 100644 index ca5366eb562b..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .b688cc94a7.out" +++ /dev/null @@ -1,49 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "3" None }-(Pair 4 Unit)-big_map_diff6] - -storage - (Pair 4 Unit) -emitted operations - -big_map diff - New map(4) of type (big_map string string) - Set map(4)["2"] to "two" - Unset map(4)["3"] - Set map(4)["1"] to "one" -trace - - location: 15 (remaining gas: 1039984.265 units remaining) - [ (Pair { Elt "3" None } { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 15 (remaining gas: 1039984.255 units remaining) - [ { Elt "3" None } @parameter - (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 16 (remaining gas: 1039984.240 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 18 (remaining gas: 1039984.230 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 16 (remaining gas: 1039984.200 units remaining) - [ { Elt "3" None } @parameter - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 19 (remaining gas: 1039984.200 units remaining) - [ (Pair "3" None) - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 21 (remaining gas: 1039984.190 units remaining) - [ "3" @key - None @elt - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 22 (remaining gas: 1039983.255 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 19 (remaining gas: 1039983.240 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 23 (remaining gas: 1039983.225 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 24 (remaining gas: 1039983.210 units remaining) - [ {} - (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 26 (remaining gas: 1039983.195 units remaining) - [ (Pair {} { Elt "1" "one" ; Elt "2" "two" } Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .c68db221ed.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .c68db221ed.out" deleted file mode 100644 index 8abe8c64b4e3..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .c68db221ed.out" +++ /dev/null @@ -1,48 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "2" None }-(Pair 4 Unit)-big_map_diff7] - -storage - (Pair 4 Unit) -emitted operations - -big_map diff - New map(4) of type (big_map string string) - Unset map(4)["2"] - Set map(4)["1"] to "one" -trace - - location: 15 (remaining gas: 1039984.265 units remaining) - [ (Pair { Elt "2" None } { Elt "1" "one" ; Elt "2" "two" } Unit) ] - - location: 15 (remaining gas: 1039984.255 units remaining) - [ { Elt "2" None } @parameter - (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 16 (remaining gas: 1039984.240 units remaining) - [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] - - location: 18 (remaining gas: 1039984.230 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 16 (remaining gas: 1039984.200 units remaining) - [ { Elt "2" None } @parameter - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 19 (remaining gas: 1039984.200 units remaining) - [ (Pair "2" None) - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 21 (remaining gas: 1039984.190 units remaining) - [ "2" @key - None @elt - { Elt "1" "one" ; Elt "2" "two" } - Unit ] - - location: 22 (remaining gas: 1039983.255 units remaining) - [ { Elt "1" "one" } - Unit ] - - location: 19 (remaining gas: 1039983.240 units remaining) - [ { Elt "1" "one" } - Unit ] - - location: 23 (remaining gas: 1039983.225 units remaining) - [ (Pair { Elt "1" "one" } Unit) ] - - location: 24 (remaining gas: 1039983.210 units remaining) - [ {} - (Pair { Elt "1" "one" } Unit) ] - - location: 26 (remaining gas: 1039983.195 units remaining) - [ (Pair {} { Elt "1" "one" } Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit].out deleted file mode 100644 index 6e787a39b245..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit] - -Runtime error in contract [CONTRACT_HASH]: - 01: parameter (or unit unit) ; - 02: storage unit ; - 03: code { CAR ; - 04: IF_LEFT - 05: { - 06: PUSH nat 922337203685477580700 ; - 07: PUSH mutez 10 ; - 08: MUL ; # FAILURE - 09: DROP - 10: } - 11: { - 12: PUSH mutez 10 ; - 13: PUSH nat 922337203685477580700 ; - 14: MUL ; # FAILURE - 15: DROP - 16: } ; - 17: - 18: NIL operation ; PAIR } - 19: -At line 8 characters 11 to 14, -unexpected arithmetic overflow -Fatal error: - error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit].out deleted file mode 100644 index 94e5af1e6635..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit] - -Runtime error in contract [CONTRACT_HASH]: - 01: parameter (or unit unit) ; - 02: storage unit ; - 03: code { CAR ; - 04: IF_LEFT - 05: { - 06: PUSH nat 922337203685477580700 ; - 07: PUSH mutez 10 ; - 08: MUL ; # FAILURE - 09: DROP - 10: } - 11: { - 12: PUSH mutez 10 ; - 13: PUSH nat 922337203685477580700 ; - 14: MUL ; # FAILURE - 15: DROP - 16: } ; - 17: - 18: NIL operation ; PAIR } - 19: -At line 14 characters 11 to 14, -unexpected arithmetic overflow -Fatal error: - error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))].out deleted file mode 100644 index d0cc3bd45211..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))] - -Runtime error in contract [CONTRACT_HASH]: - 01: parameter (or (pair nat nat) (pair nat nat)); - 02: storage (option nat); - 03: # this contract takes either (Left a b) and stores (a << b) - 04: # or (Right a b) and stores (a >> b). - 05: # i.e., in the first case, the first component shifted to the left by - 06: # the second, and the second case, component shifted to the right by - 07: # the second. - 08: code { CAR; - 09: IF_LEFT { - 10: UNPAIR; LSL; - 11: } - 12: { - 13: UNPAIR; LSR; - 14: }; - 15: SOME; - 16: NIL operation; - 17: PAIR; - 18: }; - 19: -At line 10 characters 25 to 28, -unexpected arithmetic overflow -Fatal error: - error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))].out deleted file mode 100644 index f82415042b42..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))] - -Runtime error in contract [CONTRACT_HASH]: - 01: parameter (or (pair nat nat) (pair nat nat)); - 02: storage (option nat); - 03: # this contract takes either (Left a b) and stores (a << b) - 04: # or (Right a b) and stores (a >> b). - 05: # i.e., in the first case, the first component shifted to the left by - 06: # the second, and the second case, component shifted to the right by - 07: # the second. - 08: code { CAR; - 09: IF_LEFT { - 10: UNPAIR; LSL; - 11: } - 12: { - 13: UNPAIR; LSR; - 14: }; - 15: SOME; - 16: NIL operation; - 17: PAIR; - 18: }; - 19: -At line 10 characters 25 to 28, -unexpected arithmetic overflow -Fatal error: - error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))].out deleted file mode 100644 index 007e71539eda..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))] - -Runtime error in contract [CONTRACT_HASH]: - 01: parameter (or (pair nat nat) (pair nat nat)); - 02: storage (option nat); - 03: # this contract takes either (Left a b) and stores (a << b) - 04: # or (Right a b) and stores (a >> b). - 05: # i.e., in the first case, the first component shifted to the left by - 06: # the second, and the second case, component shifted to the right by - 07: # the second. - 08: code { CAR; - 09: IF_LEFT { - 10: UNPAIR; LSL; - 11: } - 12: { - 13: UNPAIR; LSR; - 14: }; - 15: SOME; - 16: NIL operation; - 17: PAIR; - 18: }; - 19: -At line 13 characters 25 to 28, -unexpected arithmetic overflow -Fatal error: - error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))].out deleted file mode 100644 index fd56c0e5185f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))] - -Runtime error in contract [CONTRACT_HASH]: - 01: parameter (or (pair nat nat) (pair nat nat)); - 02: storage (option nat); - 03: # this contract takes either (Left a b) and stores (a << b) - 04: # or (Right a b) and stores (a >> b). - 05: # i.e., in the first case, the first component shifted to the left by - 06: # the second, and the second case, component shifted to the right by - 07: # the second. - 08: code { CAR; - 09: IF_LEFT { - 10: UNPAIR; LSL; - 11: } - 12: { - 13: UNPAIR; LSR; - 14: }; - 15: SOME; - 16: NIL operation; - 17: PAIR; - 18: }; - 19: -At line 13 characters 25 to 28, -unexpected arithmetic overflow -Fatal error: - error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0.5].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0.5].out deleted file mode 100644 index 0ff01d81e30c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0.5].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[0.5] - -storage - 500000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 0) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039774.922 units remaining) - [ 500000 @balance ] - - location: 9 (remaining gas: 1039774.907 units remaining) - [ {} - 500000 @balance ] - - location: 11 (remaining gas: 1039774.892 units remaining) - [ (Pair {} 500000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0].out deleted file mode 100644 index 2456d766b4f3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 0) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039774.922 units remaining) - [ 0 @balance ] - - location: 9 (remaining gas: 1039774.907 units remaining) - [ {} - 0 @balance ] - - location: 11 (remaining gas: 1039774.892 units remaining) - [ (Pair {} 0) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1000].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1000].out deleted file mode 100644 index eb911e0f67a2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1000].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[1000] - -storage - 1000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 0) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039774.922 units remaining) - [ 1000000000 @balance ] - - location: 9 (remaining gas: 1039774.907 units remaining) - [ {} - 1000000000 @balance ] - - location: 11 (remaining gas: 1039774.892 units remaining) - [ (Pair {} 1000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1].out deleted file mode 100644 index 3e139d63f8e1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[1] - -storage - 1000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 0) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039774.922 units remaining) - [ 1000000 @balance ] - - location: 9 (remaining gas: 1039774.907 units remaining) - [ {} - 1000000 @balance ] - - location: 11 (remaining gas: 1039774.892 units remaining) - [ (Pair {} 1000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1e-06].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1e-06].out deleted file mode 100644 index 4946990bfef0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1e-06].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[1e-06] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 0) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039774.922 units remaining) - [ 1 @balance ] - - location: 9 (remaining gas: 1039774.907 units remaining) - [ {} - 1 @balance ] - - location: 11 (remaining gas: 1039774.892 units remaining) - [ (Pair {} 1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[5].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[5].out deleted file mode 100644 index 6a551763f6af..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[5].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[5] - -storage - 5000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 0) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039774.922 units remaining) - [ 5000000 @balance ] - - location: 9 (remaining gas: 1039774.907 units remaining) - [ {} - 5000000 @balance ] - - location: 11 (remaining gas: 1039774.892 units remaining) - [ (Pair {} 5000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[8000000000000.0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[8000000000000.0].out deleted file mode 100644 index 1b12751eb036..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[8000000000000.0].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[8000000000000.0] - -storage - 8000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 0) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039774.922 units remaining) - [ 8000000000000000000 @balance ] - - location: 9 (remaining gas: 1039774.907 units remaining) - [ {} - 8000000000000000000 @balance ] - - location: 11 (remaining gas: 1039774.892 units remaining) - [ (Pair {} 8000000000000000000) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }) )-(Right (Righ.7492e8cdea.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }) )-(Right (Righ.7492e8cdea.out" deleted file mode 100644 index e47ae22bc48a..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }) )-(Right (Righ.7492e8cdea.out" +++ /dev/null @@ -1,90 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }) )-(Right (Right (Right (Left { Pair "3" "three" }))))-(Left (Pair 4 5))-big_map_diff4] - -storage - (Left (Pair 4 5)) -emitted operations - -big_map diff - New map(5) of type (big_map string string) - Set map(5)["2"] to "two" - New map(4) of type (big_map string string) - Set map(4)["3"] to "three" - Set map(4)["1"] to "one" -trace - - location: 43 (remaining gas: 1039916.593 units remaining) - [ (Pair (Right (Right (Right (Left { Pair "3" "three" })))) - (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] - - location: 43 (remaining gas: 1039916.583 units remaining) - [ (Right (Right (Right (Left { Pair "3" "three" })))) @parameter - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 44 (remaining gas: 1039916.573 units remaining) - [ (Right (Right (Left { Pair "3" "three" }))) @parameter.right - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 60 (remaining gas: 1039916.563 units remaining) - [ (Right (Left { Pair "3" "three" })) @parameter.right.right - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 65 (remaining gas: 1039916.553 units remaining) - [ (Left { Pair "3" "three" }) @parameter.right.right.right - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 108 (remaining gas: 1039916.543 units remaining) - [ { Pair "3" "three" } @parameter.right.right.right.add - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 110 (remaining gas: 1039916.528 units remaining) - [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 113 (remaining gas: 1039916.518 units remaining) - [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] - - location: 113 (remaining gas: 1039916.503 units remaining) - [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] - - location: 119 (remaining gas: 1039916.493 units remaining) - [ { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 110 (remaining gas: 1039916.463 units remaining) - [ { Pair "3" "three" } @parameter.right.right.right.add - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 120 (remaining gas: 1039916.463 units remaining) - [ (Pair "3" "three") @parameter.right.right.right.add.elt - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 122 (remaining gas: 1039916.453 units remaining) - [ "3" - "three" - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 123 (remaining gas: 1039916.438 units remaining) - [ "three" - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 125 (remaining gas: 1039916.423 units remaining) - [ (Some "three") - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 123 (remaining gas: 1039916.393 units remaining) - [ "3" - (Some "three") - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 126 (remaining gas: 1039915.461 units remaining) - [ { Elt "1" "one" ; Elt "3" "three" } - { Elt "2" "two" } ] - - location: 120 (remaining gas: 1039915.446 units remaining) - [ { Elt "1" "one" ; Elt "3" "three" } - { Elt "2" "two" } ] - - location: 127 (remaining gas: 1039915.431 units remaining) - [ (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" }) ] - - location: 128 (remaining gas: 1039915.416 units remaining) - [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] - - location: 108 (remaining gas: 1039915.401 units remaining) - [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] - - location: 65 (remaining gas: 1039915.386 units remaining) - [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] - - location: 60 (remaining gas: 1039915.371 units remaining) - [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] - - location: 44 (remaining gas: 1039915.356 units remaining) - [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] - - location: 151 (remaining gas: 1039915.341 units remaining) - [ {} - (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] - - location: 153 (remaining gas: 1039915.326 units remaining) - [ (Pair {} (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" }))) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Left Unit)-(.21b30dd90f.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Left Unit)-(.21b30dd90f.out" deleted file mode 100644 index 345d4f93b165..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Left Unit)-(.21b30dd90f.out" +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))-(Left Unit)-(Left (Pair 4 5))-big_map_diff0] - -storage - (Left (Pair 4 5)) -emitted operations - -big_map diff - New map(5) of type (big_map string string) - Set map(5)["1"] to "one" - New map(4) of type (big_map string string) - Set map(4)["2"] to "two" -trace - - location: 43 (remaining gas: 1039917.501 units remaining) - [ (Pair (Left Unit) (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] - - location: 43 (remaining gas: 1039917.491 units remaining) - [ (Left Unit) @parameter - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 44 (remaining gas: 1039917.481 units remaining) - [ Unit @parameter.swap - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 46 (remaining gas: 1039917.471 units remaining) - [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 48 (remaining gas: 1039917.461 units remaining) - [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] - - location: 48 (remaining gas: 1039917.446 units remaining) - [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] - - location: 54 (remaining gas: 1039917.436 units remaining) - [ { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 55 (remaining gas: 1039917.426 units remaining) - [ { Elt "2" "two" } - { Elt "1" "one" } ] - - location: 56 (remaining gas: 1039917.411 units remaining) - [ (Pair { Elt "2" "two" } { Elt "1" "one" }) ] - - location: 57 (remaining gas: 1039917.396 units remaining) - [ (Left (Pair { Elt "2" "two" } { Elt "1" "one" })) ] - - location: 44 (remaining gas: 1039917.381 units remaining) - [ (Left (Pair { Elt "2" "two" } { Elt "1" "one" })) ] - - location: 151 (remaining gas: 1039917.366 units remaining) - [ {} - (Left (Pair { Elt "2" "two" } { Elt "1" "one" })) ] - - location: 153 (remaining gas: 1039917.351 units remaining) - [ (Pair {} (Left (Pair { Elt "2" "two" } { Elt "1" "one" }))) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .2873ef610c.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .2873ef610c.out" deleted file mode 100644 index e20fb1c461bd..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .2873ef610c.out" +++ /dev/null @@ -1,39 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))-(Right (Left (Left (Pair { Elt "3" "three" } { Elt "4" "four" }))))-(Left (Pair 4 5))-big_map_diff1] - -storage - (Left (Pair 4 5)) -emitted operations - -big_map diff - New map(5) of type (big_map string string) - Set map(5)["4"] to "four" - New map(4) of type (big_map string string) - Set map(4)["3"] to "three" -trace - - location: 43 (remaining gas: 1039913.797 units remaining) - [ (Pair (Right (Left (Left (Pair { Elt "3" "three" } { Elt "4" "four" })))) - (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] - - location: 43 (remaining gas: 1039913.787 units remaining) - [ (Right (Left (Left (Pair { Elt "3" "three" } { Elt "4" "four" })))) @parameter - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 44 (remaining gas: 1039913.777 units remaining) - [ (Left (Left (Pair { Elt "3" "three" } { Elt "4" "four" }))) @parameter.right - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 60 (remaining gas: 1039913.767 units remaining) - [ (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) @parameter.right.reset - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 62 (remaining gas: 1039913.757 units remaining) - [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage - (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) @parameter.right.reset ] - - location: 63 (remaining gas: 1039913.747 units remaining) - [ (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) ] - - location: 60 (remaining gas: 1039913.732 units remaining) - [ (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) ] - - location: 44 (remaining gas: 1039913.717 units remaining) - [ (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) ] - - location: 151 (remaining gas: 1039913.702 units remaining) - [ {} - (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) ] - - location: 153 (remaining gas: 1039913.687 units remaining) - [ (Pair {} (Left (Pair { Elt "3" "three" } { Elt "4" "four" }))) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .8a6f480005.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .8a6f480005.out" deleted file mode 100644 index 7698aecb731b..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .8a6f480005.out" +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))-(Right (Left (Right Unit)))-(Right Unit)-big_map_diff2] - -storage - (Right Unit) -emitted operations - -big_map diff - -trace - - location: 43 (remaining gas: 1039916.861 units remaining) - [ (Pair (Right (Left (Right Unit))) (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] - - location: 43 (remaining gas: 1039916.851 units remaining) - [ (Right (Left (Right Unit))) @parameter - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 44 (remaining gas: 1039916.841 units remaining) - [ (Left (Right Unit)) @parameter.right - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 60 (remaining gas: 1039916.831 units remaining) - [ (Right Unit) @parameter.right.reset - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 62 (remaining gas: 1039916.821 units remaining) - [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage - (Right Unit) @parameter.right.reset ] - - location: 63 (remaining gas: 1039916.811 units remaining) - [ (Right Unit) ] - - location: 60 (remaining gas: 1039916.796 units remaining) - [ (Right Unit) ] - - location: 44 (remaining gas: 1039916.781 units remaining) - [ (Right Unit) ] - - location: 151 (remaining gas: 1039916.766 units remaining) - [ {} - (Right Unit) ] - - location: 153 (remaining gas: 1039916.751 units remaining) - [ (Pair {} (Right Unit)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Right.d336ca1903.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Right.d336ca1903.out" deleted file mode 100644 index d0bdefc1e6ed..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Right.d336ca1903.out" +++ /dev/null @@ -1,83 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))-(Right (Right (Right (Right { "1" }))))-(Left (Pair 4 5))-big_map_diff5] - -storage - (Left (Pair 4 5)) -emitted operations - -big_map diff - New map(5) of type (big_map string string) - Set map(5)["2"] to "two" - New map(4) of type (big_map string string) - Unset map(4)["1"] -trace - - location: 43 (remaining gas: 1039916.857 units remaining) - [ (Pair (Right (Right (Right (Right { "1" })))) - (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] - - location: 43 (remaining gas: 1039916.847 units remaining) - [ (Right (Right (Right (Right { "1" })))) @parameter - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 44 (remaining gas: 1039916.837 units remaining) - [ (Right (Right (Right { "1" }))) @parameter.right - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 60 (remaining gas: 1039916.827 units remaining) - [ (Right (Right { "1" })) @parameter.right.right - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 65 (remaining gas: 1039916.817 units remaining) - [ (Right { "1" }) @parameter.right.right.right - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 108 (remaining gas: 1039916.807 units remaining) - [ { "1" } @parameter.right.right.right.rem - (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 131 (remaining gas: 1039916.792 units remaining) - [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] - - location: 134 (remaining gas: 1039916.782 units remaining) - [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] - - location: 134 (remaining gas: 1039916.767 units remaining) - [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] - - location: 140 (remaining gas: 1039916.757 units remaining) - [ { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 131 (remaining gas: 1039916.727 units remaining) - [ { "1" } @parameter.right.right.right.rem - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 141 (remaining gas: 1039916.727 units remaining) - [ "1" @parameter.right.right.right.rem.elt - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 143 (remaining gas: 1039916.712 units remaining) - [ { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 145 (remaining gas: 1039916.697 units remaining) - [ None - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 143 (remaining gas: 1039916.667 units remaining) - [ "1" @parameter.right.right.right.rem.elt - None - { Elt "1" "one" } - { Elt "2" "two" } ] - - location: 147 (remaining gas: 1039915.735 units remaining) - [ {} - { Elt "2" "two" } ] - - location: 141 (remaining gas: 1039915.720 units remaining) - [ {} - { Elt "2" "two" } ] - - location: 148 (remaining gas: 1039915.705 units remaining) - [ (Pair {} { Elt "2" "two" }) ] - - location: 149 (remaining gas: 1039915.690 units remaining) - [ (Left (Pair {} { Elt "2" "two" })) ] - - location: 108 (remaining gas: 1039915.675 units remaining) - [ (Left (Pair {} { Elt "2" "two" })) ] - - location: 65 (remaining gas: 1039915.660 units remaining) - [ (Left (Pair {} { Elt "2" "two" })) ] - - location: 60 (remaining gas: 1039915.645 units remaining) - [ (Left (Pair {} { Elt "2" "two" })) ] - - location: 44 (remaining gas: 1039915.630 units remaining) - [ (Left (Pair {} { Elt "2" "two" })) ] - - location: 151 (remaining gas: 1039915.615 units remaining) - [ {} - (Left (Pair {} { Elt "2" "two" })) ] - - location: 153 (remaining gas: 1039915.600 units remaining) - [ (Pair {} (Left (Pair {} { Elt "2" "two" }))) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair \"foo\" \"bar\" } { P.7f2ee47600.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair \"foo\" \"bar\" } { P.7f2ee47600.out" deleted file mode 100644 index 4ca99999edd6..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair \"foo\" \"bar\" } { P.7f2ee47600.out" +++ /dev/null @@ -1,135 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" }) )))-(Left (Pair 4 5))-big_map_diff3] - -storage - (Left (Pair 4 5)) -emitted operations - -big_map diff - New map(5) of type (big_map string string) - Set map(5)["gaz"] to "baz" - New map(4) of type (big_map string string) - Set map(4)["foo"] to "bar" -trace - - location: 43 (remaining gas: 1039919.139 units remaining) - [ (Pair (Right (Right (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" })))) (Right Unit)) ] - - location: 43 (remaining gas: 1039919.129 units remaining) - [ (Right (Right (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" })))) @parameter - (Right Unit) @storage ] - - location: 44 (remaining gas: 1039919.119 units remaining) - [ (Right (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" }))) @parameter.right - (Right Unit) @storage ] - - location: 60 (remaining gas: 1039919.109 units remaining) - [ (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" })) @parameter.right.right - (Right Unit) @storage ] - - location: 65 (remaining gas: 1039919.099 units remaining) - [ (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" }) @parameter.right.right.import - (Right Unit) @storage ] - - location: 67 (remaining gas: 1039919.084 units remaining) - [ (Right Unit) @storage ] - - location: 70 (remaining gas: 1039919.074 units remaining) - [ Unit @storage.right ] - - location: 70 (remaining gas: 1039919.059 units remaining) - [ Unit @storage.right ] - - location: 76 (remaining gas: 1039919.049 units remaining) - [ ] - - location: 67 (remaining gas: 1039919.019 units remaining) - [ (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" }) @parameter.right.right.import ] - - location: 77 (remaining gas: 1039919.009 units remaining) - [ { Pair "foo" "bar" } - { Pair "gaz" "baz" } ] - - location: 78 (remaining gas: 1039918.994 units remaining) - [ { Pair "gaz" "baz" } ] - - location: 80 (remaining gas: 1039918.979 units remaining) - [ {} - { Pair "gaz" "baz" } ] - - location: 78 (remaining gas: 1039918.949 units remaining) - [ { Pair "foo" "bar" } - {} - { Pair "gaz" "baz" } ] - - location: 83 (remaining gas: 1039918.949 units remaining) - [ (Pair "foo" "bar") @elt - {} - { Pair "gaz" "baz" } ] - - location: 85 (remaining gas: 1039918.939 units remaining) - [ "foo" - "bar" - {} - { Pair "gaz" "baz" } ] - - location: 86 (remaining gas: 1039918.924 units remaining) - [ "bar" - {} - { Pair "gaz" "baz" } ] - - location: 88 (remaining gas: 1039918.909 units remaining) - [ (Some "bar") - {} - { Pair "gaz" "baz" } ] - - location: 86 (remaining gas: 1039918.879 units remaining) - [ "foo" - (Some "bar") - {} - { Pair "gaz" "baz" } ] - - location: 89 (remaining gas: 1039917.881 units remaining) - [ { Elt "foo" "bar" } - { Pair "gaz" "baz" } ] - - location: 83 (remaining gas: 1039917.866 units remaining) - [ { Elt "foo" "bar" } - { Pair "gaz" "baz" } ] - - location: 90 (remaining gas: 1039917.856 units remaining) - [ { Pair "gaz" "baz" } - { Elt "foo" "bar" } ] - - location: 91 (remaining gas: 1039917.841 units remaining) - [ { Elt "foo" "bar" } ] - - location: 93 (remaining gas: 1039917.826 units remaining) - [ {} - { Elt "foo" "bar" } ] - - location: 91 (remaining gas: 1039917.796 units remaining) - [ { Pair "gaz" "baz" } - {} - { Elt "foo" "bar" } ] - - location: 96 (remaining gas: 1039917.796 units remaining) - [ (Pair "gaz" "baz") @elt - {} - { Elt "foo" "bar" } ] - - location: 98 (remaining gas: 1039917.786 units remaining) - [ "gaz" - "baz" - {} - { Elt "foo" "bar" } ] - - location: 99 (remaining gas: 1039917.771 units remaining) - [ "baz" - {} - { Elt "foo" "bar" } ] - - location: 101 (remaining gas: 1039917.756 units remaining) - [ (Some "baz") - {} - { Elt "foo" "bar" } ] - - location: 99 (remaining gas: 1039917.726 units remaining) - [ "gaz" - (Some "baz") - {} - { Elt "foo" "bar" } ] - - location: 102 (remaining gas: 1039916.728 units remaining) - [ { Elt "gaz" "baz" } - { Elt "foo" "bar" } ] - - location: 96 (remaining gas: 1039916.713 units remaining) - [ { Elt "gaz" "baz" } - { Elt "foo" "bar" } ] - - location: 103 (remaining gas: 1039916.703 units remaining) - [ { Elt "foo" "bar" } - { Elt "gaz" "baz" } ] - - location: 104 (remaining gas: 1039916.688 units remaining) - [ (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" }) ] - - location: 105 (remaining gas: 1039916.673 units remaining) - [ (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] - - location: 65 (remaining gas: 1039916.658 units remaining) - [ (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] - - location: 60 (remaining gas: 1039916.643 units remaining) - [ (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] - - location: 44 (remaining gas: 1039916.628 units remaining) - [ (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] - - location: 151 (remaining gas: 1039916.613 units remaining) - [ {} - (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] - - location: 153 (remaining gas: 1039916.598 units remaining) - [ (Pair {} (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" }))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_check_signature.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_check_signature.out deleted file mode 100644 index 206f5005c7ac..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_check_signature.out +++ /dev/null @@ -1,241 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_check_signature - -storage - (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039651.625 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 9 (remaining gas: 1039651.615 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 10 (remaining gas: 1039651.605 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 11 (remaining gas: 1039651.590 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 13 (remaining gas: 1039651.580 units remaining) - [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") @storage - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 14 (remaining gas: 1039651.570 units remaining) - [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") @storage - (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") @storage - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 15 (remaining gas: 1039651.560 units remaining) - [ "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") @storage - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 16 (remaining gas: 1039651.545 units remaining) - [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") @storage - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 18 (remaining gas: 1039651.535 units remaining) - [ "hello" - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 19 (remaining gas: 1039651.044 units remaining) - [ 0x05010000000568656c6c6f @packed - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 16 (remaining gas: 1039651.014 units remaining) - [ "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - 0x05010000000568656c6c6f @packed - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 11 (remaining gas: 1039650.984 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - 0x05010000000568656c6c6f @packed - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 20 (remaining gas: 1039650.974 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @parameter - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - 0x05010000000568656c6c6f @packed - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 21 (remaining gas: 1039585.162 units remaining) - [ True - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 22 (remaining gas: 1039585.152 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 22 (remaining gas: 1039585.137 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - - location: 28 (remaining gas: 1039585.127 units remaining) - [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") @storage ] - - location: 29 (remaining gas: 1039585.112 units remaining) - [ {} - (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") @storage ] - - location: 31 (remaining gas: 1039585.097 units remaining) - [ (Pair {} - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "hello") ] - -Runtime error in contract [CONTRACT_HASH]: - 01: parameter key; - 02: storage (pair signature string); - 03: code { - 04: DUP; DUP; - 05: DIP{ CDR; DUP; CAR; - 06: DIP{CDR; PACK}}; - 07: CAR; CHECK_SIGNATURE; - 08: IF {} {FAIL} ; - 09: CDR; NIL operation ; PAIR}; - 10: - 11: -At line 8 characters 14 to 18, -script reached FAILWITH instruction -with Unit -trace - - location: 9 (remaining gas: 1039651.635 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 9 (remaining gas: 1039651.625 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 10 (remaining gas: 1039651.615 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 11 (remaining gas: 1039651.600 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 13 (remaining gas: 1039651.590 units remaining) - [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") @storage - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 14 (remaining gas: 1039651.580 units remaining) - [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") @storage - (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") @storage - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 15 (remaining gas: 1039651.570 units remaining) - [ "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") @storage - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 16 (remaining gas: 1039651.555 units remaining) - [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") @storage - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 18 (remaining gas: 1039651.545 units remaining) - [ "abcd" - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 19 (remaining gas: 1039651.087 units remaining) - [ 0x05010000000461626364 @packed - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 16 (remaining gas: 1039651.057 units remaining) - [ "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - 0x05010000000461626364 @packed - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 11 (remaining gas: 1039651.027 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - 0x05010000000461626364 @packed - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 20 (remaining gas: 1039651.017 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @parameter - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - 0x05010000000461626364 @packed - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 21 (remaining gas: 1039585.206 units remaining) - [ False - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 22 (remaining gas: 1039585.196 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] - - location: 26 (remaining gas: 1039585.186 units remaining) - [ Unit - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" - "abcd") ] -Fatal error: - error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit].out deleted file mode 100644 index 9643cd26e8d9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit].out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039988.319 units remaining) - [ (Pair 0 Unit) ] - - location: 7 (remaining gas: 1039988.309 units remaining) - [ 0 @parameter ] - - location: 8 (remaining gas: 1039988.299 units remaining) - [ 0 @parameter - 0 @parameter ] - - location: 9 (remaining gas: 1039988.259 units remaining) - [ 0 - 0 @parameter ] - - location: 10 (remaining gas: 1039988.234 units remaining) - [ 0 - 0 @parameter ] - - location: 11 (remaining gas: 1039988.199 units remaining) - [ 0 ] - - location: 13 (remaining gas: 1039988.184 units remaining) - [ True ] - - location: 14 (remaining gas: 1039988.174 units remaining) - [ ] - - location: 14 (remaining gas: 1039988.159 units remaining) - [ ] - - location: 20 (remaining gas: 1039988.149 units remaining) - [ Unit ] - - location: 21 (remaining gas: 1039988.134 units remaining) - [ {} - Unit ] - - location: 23 (remaining gas: 1039988.119 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit].out deleted file mode 100644 index 40bf09181f50..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit].out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039988.319 units remaining) - [ (Pair 12039123919239192312931 Unit) ] - - location: 7 (remaining gas: 1039988.309 units remaining) - [ 12039123919239192312931 @parameter ] - - location: 8 (remaining gas: 1039988.299 units remaining) - [ 12039123919239192312931 @parameter - 12039123919239192312931 @parameter ] - - location: 9 (remaining gas: 1039988.259 units remaining) - [ -12039123919239192312931 - 12039123919239192312931 @parameter ] - - location: 10 (remaining gas: 1039988.234 units remaining) - [ 12039123919239192312931 - 12039123919239192312931 @parameter ] - - location: 11 (remaining gas: 1039988.199 units remaining) - [ 0 ] - - location: 13 (remaining gas: 1039988.184 units remaining) - [ True ] - - location: 14 (remaining gas: 1039988.174 units remaining) - [ ] - - location: 14 (remaining gas: 1039988.159 units remaining) - [ ] - - location: 20 (remaining gas: 1039988.149 units remaining) - [ Unit ] - - location: 21 (remaining gas: 1039988.134 units remaining) - [ {} - Unit ] - - location: 23 (remaining gas: 1039988.119 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit].out deleted file mode 100644 index 8f0fe26aa9dd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit].out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039988.319 units remaining) - [ (Pair 948 Unit) ] - - location: 7 (remaining gas: 1039988.309 units remaining) - [ 948 @parameter ] - - location: 8 (remaining gas: 1039988.299 units remaining) - [ 948 @parameter - 948 @parameter ] - - location: 9 (remaining gas: 1039988.259 units remaining) - [ -948 - 948 @parameter ] - - location: 10 (remaining gas: 1039988.234 units remaining) - [ 948 - 948 @parameter ] - - location: 11 (remaining gas: 1039988.199 units remaining) - [ 0 ] - - location: 13 (remaining gas: 1039988.184 units remaining) - [ True ] - - location: 14 (remaining gas: 1039988.174 units remaining) - [ ] - - location: 14 (remaining gas: 1039988.159 units remaining) - [ ] - - location: 20 (remaining gas: 1039988.149 units remaining) - [ Unit ] - - location: 21 (remaining gas: 1039988.134 units remaining) - [ {} - Unit ] - - location: 23 (remaining gas: 1039988.119 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit].out deleted file mode 100644 index bde601847c3f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit].out +++ /dev/null @@ -1,211 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039925.003 units remaining) - [ (Pair Unit Unit) ] - - location: 7 (remaining gas: 1039924.993 units remaining) - [ Unit @parameter ] - - location: 8 (remaining gas: 1039924.983 units remaining) - [ 2 - Unit @parameter ] - - location: 11 (remaining gas: 1039924.973 units remaining) - [ 2 - 2 - Unit @parameter ] - - location: 14 (remaining gas: 1039924.918 units remaining) - [ 4 - Unit @parameter ] - - location: 15 (remaining gas: 1039924.908 units remaining) - [ 4 - 4 - Unit @parameter ] - - location: 20 (remaining gas: 1039924.873 units remaining) - [ 0 - Unit @parameter ] - - location: 21 (remaining gas: 1039924.858 units remaining) - [ True - Unit @parameter ] - - location: 22 (remaining gas: 1039924.848 units remaining) - [ Unit @parameter ] - - location: 22 (remaining gas: 1039924.833 units remaining) - [ Unit @parameter ] - - location: 28 (remaining gas: 1039924.823 units remaining) - [ 2 - Unit @parameter ] - - location: 31 (remaining gas: 1039924.813 units remaining) - [ 2 - 2 - Unit @parameter ] - - location: 34 (remaining gas: 1039924.758 units remaining) - [ 4 - Unit @parameter ] - - location: 35 (remaining gas: 1039924.748 units remaining) - [ 4 - 4 - Unit @parameter ] - - location: 40 (remaining gas: 1039924.713 units remaining) - [ 0 - Unit @parameter ] - - location: 41 (remaining gas: 1039924.698 units remaining) - [ True - Unit @parameter ] - - location: 42 (remaining gas: 1039924.688 units remaining) - [ Unit @parameter ] - - location: 42 (remaining gas: 1039924.673 units remaining) - [ Unit @parameter ] - - location: 48 (remaining gas: 1039924.663 units remaining) - [ 2 - Unit @parameter ] - - location: 51 (remaining gas: 1039924.653 units remaining) - [ 2 - 2 - Unit @parameter ] - - location: 54 (remaining gas: 1039924.598 units remaining) - [ 4 - Unit @parameter ] - - location: 55 (remaining gas: 1039924.588 units remaining) - [ 4 - 4 - Unit @parameter ] - - location: 60 (remaining gas: 1039924.553 units remaining) - [ 0 - Unit @parameter ] - - location: 61 (remaining gas: 1039924.538 units remaining) - [ True - Unit @parameter ] - - location: 62 (remaining gas: 1039924.528 units remaining) - [ Unit @parameter ] - - location: 62 (remaining gas: 1039924.513 units remaining) - [ Unit @parameter ] - - location: 68 (remaining gas: 1039924.503 units remaining) - [ 2 - Unit @parameter ] - - location: 71 (remaining gas: 1039924.493 units remaining) - [ 2 - 2 - Unit @parameter ] - - location: 74 (remaining gas: 1039924.438 units remaining) - [ 4 - Unit @parameter ] - - location: 75 (remaining gas: 1039924.428 units remaining) - [ 4 - 4 - Unit @parameter ] - - location: 80 (remaining gas: 1039924.393 units remaining) - [ 0 - Unit @parameter ] - - location: 81 (remaining gas: 1039924.378 units remaining) - [ True - Unit @parameter ] - - location: 82 (remaining gas: 1039924.368 units remaining) - [ Unit @parameter ] - - location: 82 (remaining gas: 1039924.353 units remaining) - [ Unit @parameter ] - - location: 88 (remaining gas: 1039924.343 units remaining) - [ 2 - Unit @parameter ] - - location: 91 (remaining gas: 1039924.333 units remaining) - [ 2 - 2 - Unit @parameter ] - - location: 94 (remaining gas: 1039924.278 units remaining) - [ 4 - Unit @parameter ] - - location: 95 (remaining gas: 1039924.268 units remaining) - [ 4 - 4 - Unit @parameter ] - - location: 100 (remaining gas: 1039924.233 units remaining) - [ 0 - Unit @parameter ] - - location: 101 (remaining gas: 1039924.218 units remaining) - [ True - Unit @parameter ] - - location: 102 (remaining gas: 1039924.208 units remaining) - [ Unit @parameter ] - - location: 102 (remaining gas: 1039924.193 units remaining) - [ Unit @parameter ] - - location: 108 (remaining gas: 1039924.183 units remaining) - [ 60 - Unit @parameter ] - - location: 111 (remaining gas: 1039924.173 units remaining) - [ "2019-09-09T12:08:37Z" - 60 - Unit @parameter ] - - location: 114 (remaining gas: 1039924.118 units remaining) - [ "2019-09-09T12:09:37Z" - Unit @parameter ] - - location: 115 (remaining gas: 1039924.108 units remaining) - [ "2019-09-09T12:09:37Z" - "2019-09-09T12:09:37Z" - Unit @parameter ] - - location: 120 (remaining gas: 1039924.073 units remaining) - [ 0 - Unit @parameter ] - - location: 121 (remaining gas: 1039924.058 units remaining) - [ True - Unit @parameter ] - - location: 122 (remaining gas: 1039924.048 units remaining) - [ Unit @parameter ] - - location: 122 (remaining gas: 1039924.033 units remaining) - [ Unit @parameter ] - - location: 128 (remaining gas: 1039924.023 units remaining) - [ "2019-09-09T12:08:37Z" - Unit @parameter ] - - location: 131 (remaining gas: 1039924.013 units remaining) - [ 60 - "2019-09-09T12:08:37Z" - Unit @parameter ] - - location: 134 (remaining gas: 1039923.958 units remaining) - [ "2019-09-09T12:09:37Z" - Unit @parameter ] - - location: 135 (remaining gas: 1039923.948 units remaining) - [ "2019-09-09T12:09:37Z" - "2019-09-09T12:09:37Z" - Unit @parameter ] - - location: 140 (remaining gas: 1039923.913 units remaining) - [ 0 - Unit @parameter ] - - location: 141 (remaining gas: 1039923.898 units remaining) - [ True - Unit @parameter ] - - location: 142 (remaining gas: 1039923.888 units remaining) - [ Unit @parameter ] - - location: 142 (remaining gas: 1039923.873 units remaining) - [ Unit @parameter ] - - location: 148 (remaining gas: 1039923.863 units remaining) - [ 1000 - Unit @parameter ] - - location: 151 (remaining gas: 1039923.853 units remaining) - [ 1000 - 1000 - Unit @parameter ] - - location: 154 (remaining gas: 1039923.833 units remaining) - [ 2000 - Unit @parameter ] - - location: 155 (remaining gas: 1039923.823 units remaining) - [ 2000 - 2000 - Unit @parameter ] - - location: 160 (remaining gas: 1039923.788 units remaining) - [ 0 - Unit @parameter ] - - location: 161 (remaining gas: 1039923.773 units remaining) - [ True - Unit @parameter ] - - location: 162 (remaining gas: 1039923.763 units remaining) - [ Unit @parameter ] - - location: 162 (remaining gas: 1039923.748 units remaining) - [ Unit @parameter ] - - location: 168 (remaining gas: 1039923.733 units remaining) - [ {} - Unit @parameter ] - - location: 170 (remaining gas: 1039923.718 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000.3c2de60480.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000.3c2de60480.out deleted file mode 100644 index dc616e16cde6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000.3c2de60480.out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000000000000000000000000000000000000000000000000000000000000)] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.524 units remaining) - [ (Pair (Pair 0x0000000000000000000000000000000000000000000000000000000000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000) - None) ] - - location: 10 (remaining gas: 1039992.514 units remaining) - [ (Pair 0x0000000000000000000000000000000000000000000000000000000000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000) @parameter ] - - location: 11 (remaining gas: 1039992.504 units remaining) - [ 0x0000000000000000000000000000000000000000000000000000000000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039992.459 units remaining) - [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 13 (remaining gas: 1039992.444 units remaining) - [ (Some 0x0000000000000000000000000000000000000000000000000000000000000000) ] - - location: 14 (remaining gas: 1039992.429 units remaining) - [ {} - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) ] - - location: 16 (remaining gas: 1039992.414 units remaining) - [ (Pair {} - (Some 0x0000000000000000000000000000000000000000000000000000000000000000)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000.12b2c1172b.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000.12b2c1172b.out deleted file mode 100644 index da262115ebfe..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000.12b2c1172b.out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000000000000000000000000000000000000000000000000000000000000)] - -storage - (Some 0x0100000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.524 units remaining) - [ (Pair (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000) - None) ] - - location: 10 (remaining gas: 1039992.514 units remaining) - [ (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000) @parameter ] - - location: 11 (remaining gas: 1039992.504 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039992.459 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 13 (remaining gas: 1039992.444 units remaining) - [ (Some 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 14 (remaining gas: 1039992.429 units remaining) - [ {} - (Some 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 16 (remaining gas: 1039992.414 units remaining) - [ (Pair {} - (Some 0x0100000000000000000000000000000000000000000000000000000000000000)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x010.0e44fc6f40.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x010.0e44fc6f40.out deleted file mode 100644 index 964be17ffd41..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x010.0e44fc6f40.out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x0100000000000000000000000000000000000000000000000000000000000000)] - -storage - (Some 0x0100000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.524 units remaining) - [ (Pair (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000) - None) ] - - location: 10 (remaining gas: 1039992.514 units remaining) - [ (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000) @parameter ] - - location: 11 (remaining gas: 1039992.504 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 - 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039992.459 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 13 (remaining gas: 1039992.444 units remaining) - [ (Some 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 14 (remaining gas: 1039992.429 units remaining) - [ {} - (Some 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 16 (remaining gas: 1039992.414 units remaining) - [ (Pair {} - (Some 0x0100000000000000000000000000000000000000000000000000000000000000)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0.7e0ed229a3.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0.7e0ed229a3.out deleted file mode 100644 index 7e3e53f07a5b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0.7e0ed229a3.out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0x0200000000000000000000000000000000000000000000000000000000000000)] - -storage - (Some 0x0200000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.524 units remaining) - [ (Pair (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 - 0x0100000000000000000000000000000000000000000000000000000000000000) - None) ] - - location: 10 (remaining gas: 1039992.514 units remaining) - [ (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 - 0x0100000000000000000000000000000000000000000000000000000000000000) @parameter ] - - location: 11 (remaining gas: 1039992.504 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 - 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039992.459 units remaining) - [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] - - location: 13 (remaining gas: 1039992.444 units remaining) - [ (Some 0x0200000000000000000000000000000000000000000000000000000000000000) ] - - location: 14 (remaining gas: 1039992.429 units remaining) - [ {} - (Some 0x0200000000000000000000000000000000000000000000000000000000000000) ] - - location: 16 (remaining gas: 1039992.414 units remaining) - [ (Pair {} - (Some 0x0200000000000000000000000000000000000000000000000000000000000000)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some \"1970.7c1b1e4e5b.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some \"1970.7c1b1e4e5b.out" deleted file mode 100644 index c8b84e53c207..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some \"1970.7c1b1e4e5b.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some "1970-01-01T00:00:00Z")] - -storage - (Some "1970-01-01T00:00:00Z") -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.553 units remaining) - [ (Pair (Pair -100 "1970-01-01T00:01:40Z") None) ] - - location: 10 (remaining gas: 1039990.543 units remaining) - [ (Pair -100 "1970-01-01T00:01:40Z") @parameter ] - - location: 11 (remaining gas: 1039990.533 units remaining) - [ (Pair -100 "1970-01-01T00:01:40Z") @parameter - (Pair -100 "1970-01-01T00:01:40Z") @parameter ] - - location: 12 (remaining gas: 1039990.523 units remaining) - [ -100 - (Pair -100 "1970-01-01T00:01:40Z") @parameter ] - - location: 13 (remaining gas: 1039990.508 units remaining) - [ (Pair -100 "1970-01-01T00:01:40Z") @parameter ] - - location: 15 (remaining gas: 1039990.498 units remaining) - [ "1970-01-01T00:01:40Z" ] - - location: 13 (remaining gas: 1039990.468 units remaining) - [ -100 - "1970-01-01T00:01:40Z" ] - - location: 16 (remaining gas: 1039990.413 units remaining) - [ "1970-01-01T00:00:00Z" ] - - location: 17 (remaining gas: 1039990.398 units remaining) - [ (Some "1970-01-01T00:00:00Z") ] - - location: 18 (remaining gas: 1039990.383 units remaining) - [ {} - (Some "1970-01-01T00:00:00Z") ] - - location: 20 (remaining gas: 1039990.368 units remaining) - [ (Pair {} (Some "1970-01-01T00:00:00Z")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 \"1970-01-01T00:00:0.528ed42c01.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 \"1970-01-01T00:00:0.528ed42c01.out" deleted file mode 100644 index 2a69ae290fc5..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 \"1970-01-01T00:00:0.528ed42c01.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 "1970-01-01T00:00:00Z")-(Some "1970-01-01T00:00:00Z")] - -storage - (Some "1970-01-01T00:00:00Z") -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.453 units remaining) - [ (Pair (Pair 0 "1970-01-01T00:00:00Z") None) ] - - location: 10 (remaining gas: 1039990.443 units remaining) - [ (Pair 0 "1970-01-01T00:00:00Z") @parameter ] - - location: 11 (remaining gas: 1039990.433 units remaining) - [ (Pair 0 "1970-01-01T00:00:00Z") @parameter - (Pair 0 "1970-01-01T00:00:00Z") @parameter ] - - location: 12 (remaining gas: 1039990.423 units remaining) - [ 0 - (Pair 0 "1970-01-01T00:00:00Z") @parameter ] - - location: 13 (remaining gas: 1039990.408 units remaining) - [ (Pair 0 "1970-01-01T00:00:00Z") @parameter ] - - location: 15 (remaining gas: 1039990.398 units remaining) - [ "1970-01-01T00:00:00Z" ] - - location: 13 (remaining gas: 1039990.368 units remaining) - [ 0 - "1970-01-01T00:00:00Z" ] - - location: 16 (remaining gas: 1039990.313 units remaining) - [ "1970-01-01T00:00:00Z" ] - - location: 17 (remaining gas: 1039990.298 units remaining) - [ (Some "1970-01-01T00:00:00Z") ] - - location: 18 (remaining gas: 1039990.283 units remaining) - [ {} - (Some "1970-01-01T00:00:00Z") ] - - location: 20 (remaining gas: 1039990.268 units remaining) - [ (Pair {} (Some "1970-01-01T00:00:00Z")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some \"1970-.6566111ad2.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some \"1970-.6566111ad2.out" deleted file mode 100644 index 48041181fad7..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some \"1970-.6566111ad2.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some "1970-01-01T00:03:20Z")] - -storage - (Some "1970-01-01T00:03:20Z") -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.553 units remaining) - [ (Pair (Pair 100 "1970-01-01T00:01:40Z") None) ] - - location: 10 (remaining gas: 1039990.543 units remaining) - [ (Pair 100 "1970-01-01T00:01:40Z") @parameter ] - - location: 11 (remaining gas: 1039990.533 units remaining) - [ (Pair 100 "1970-01-01T00:01:40Z") @parameter - (Pair 100 "1970-01-01T00:01:40Z") @parameter ] - - location: 12 (remaining gas: 1039990.523 units remaining) - [ 100 - (Pair 100 "1970-01-01T00:01:40Z") @parameter ] - - location: 13 (remaining gas: 1039990.508 units remaining) - [ (Pair 100 "1970-01-01T00:01:40Z") @parameter ] - - location: 15 (remaining gas: 1039990.498 units remaining) - [ "1970-01-01T00:01:40Z" ] - - location: 13 (remaining gas: 1039990.468 units remaining) - [ 100 - "1970-01-01T00:01:40Z" ] - - location: 16 (remaining gas: 1039990.413 units remaining) - [ "1970-01-01T00:03:20Z" ] - - location: 17 (remaining gas: 1039990.398 units remaining) - [ (Some "1970-01-01T00:03:20Z") ] - - location: 18 (remaining gas: 1039990.383 units remaining) - [ {} - (Some "1970-01-01T00:03:20Z") ] - - location: 20 (remaining gas: 1039990.368 units remaining) - [ (Pair {} (Some "1970-01-01T00:03:20Z")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair \"1970-01-01T00:00:00Z.72c424f3da.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair \"1970-01-01T00:00:00Z.72c424f3da.out" deleted file mode 100644 index 8d294941312f..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair \"1970-01-01T00:00:00Z.72c424f3da.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair "1970-01-01T00:00:00Z" 0)-(Some "1970-01-01T00:00:00Z")] - -storage - (Some "1970-01-01T00:00:00Z") -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.453 units remaining) - [ (Pair (Pair "1970-01-01T00:00:00Z" 0) None) ] - - location: 10 (remaining gas: 1039990.443 units remaining) - [ (Pair "1970-01-01T00:00:00Z" 0) @parameter ] - - location: 11 (remaining gas: 1039990.433 units remaining) - [ (Pair "1970-01-01T00:00:00Z" 0) @parameter - (Pair "1970-01-01T00:00:00Z" 0) @parameter ] - - location: 12 (remaining gas: 1039990.423 units remaining) - [ "1970-01-01T00:00:00Z" - (Pair "1970-01-01T00:00:00Z" 0) @parameter ] - - location: 13 (remaining gas: 1039990.408 units remaining) - [ (Pair "1970-01-01T00:00:00Z" 0) @parameter ] - - location: 15 (remaining gas: 1039990.398 units remaining) - [ 0 ] - - location: 13 (remaining gas: 1039990.368 units remaining) - [ "1970-01-01T00:00:00Z" - 0 ] - - location: 16 (remaining gas: 1039990.313 units remaining) - [ "1970-01-01T00:00:00Z" ] - - location: 17 (remaining gas: 1039990.298 units remaining) - [ (Some "1970-01-01T00:00:00Z") ] - - location: 18 (remaining gas: 1039990.283 units remaining) - [ {} - (Some "1970-01-01T00:00:00Z") ] - - location: 20 (remaining gas: 1039990.268 units remaining) - [ (Pair {} (Some "1970-01-01T00:00:00Z")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some \"1970.7c4b12e9aa.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some \"1970.7c4b12e9aa.out" deleted file mode 100644 index 2a2325747c6e..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some \"1970.7c4b12e9aa.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some "1970-01-01T00:00:00Z")] - -storage - (Some "1970-01-01T00:00:00Z") -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.553 units remaining) - [ (Pair (Pair "1970-01-01T00:01:40Z" -100) None) ] - - location: 10 (remaining gas: 1039990.543 units remaining) - [ (Pair "1970-01-01T00:01:40Z" -100) @parameter ] - - location: 11 (remaining gas: 1039990.533 units remaining) - [ (Pair "1970-01-01T00:01:40Z" -100) @parameter - (Pair "1970-01-01T00:01:40Z" -100) @parameter ] - - location: 12 (remaining gas: 1039990.523 units remaining) - [ "1970-01-01T00:01:40Z" - (Pair "1970-01-01T00:01:40Z" -100) @parameter ] - - location: 13 (remaining gas: 1039990.508 units remaining) - [ (Pair "1970-01-01T00:01:40Z" -100) @parameter ] - - location: 15 (remaining gas: 1039990.498 units remaining) - [ -100 ] - - location: 13 (remaining gas: 1039990.468 units remaining) - [ "1970-01-01T00:01:40Z" - -100 ] - - location: 16 (remaining gas: 1039990.413 units remaining) - [ "1970-01-01T00:00:00Z" ] - - location: 17 (remaining gas: 1039990.398 units remaining) - [ (Some "1970-01-01T00:00:00Z") ] - - location: 18 (remaining gas: 1039990.383 units remaining) - [ {} - (Some "1970-01-01T00:00:00Z") ] - - location: 20 (remaining gas: 1039990.368 units remaining) - [ (Pair {} (Some "1970-01-01T00:00:00Z")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some \"1970-.af32743640.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some \"1970-.af32743640.out" deleted file mode 100644 index 1695417d8fa4..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some \"1970-.af32743640.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some "1970-01-01T00:03:20Z")] - -storage - (Some "1970-01-01T00:03:20Z") -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.553 units remaining) - [ (Pair (Pair "1970-01-01T00:01:40Z" 100) None) ] - - location: 10 (remaining gas: 1039990.543 units remaining) - [ (Pair "1970-01-01T00:01:40Z" 100) @parameter ] - - location: 11 (remaining gas: 1039990.533 units remaining) - [ (Pair "1970-01-01T00:01:40Z" 100) @parameter - (Pair "1970-01-01T00:01:40Z" 100) @parameter ] - - location: 12 (remaining gas: 1039990.523 units remaining) - [ "1970-01-01T00:01:40Z" - (Pair "1970-01-01T00:01:40Z" 100) @parameter ] - - location: 13 (remaining gas: 1039990.508 units remaining) - [ (Pair "1970-01-01T00:01:40Z" 100) @parameter ] - - location: 15 (remaining gas: 1039990.498 units remaining) - [ 100 ] - - location: 13 (remaining gas: 1039990.468 units remaining) - [ "1970-01-01T00:01:40Z" - 100 ] - - location: 16 (remaining gas: 1039990.413 units remaining) - [ "1970-01-01T00:03:20Z" ] - - location: 17 (remaining gas: 1039990.398 units remaining) - [ (Some "1970-01-01T00:03:20Z") ] - - location: 18 (remaining gas: 1039990.383 units remaining) - [ {} - (Some "1970-01-01T00:03:20Z") ] - - location: 20 (remaining gas: 1039990.368 units remaining) - [ (Pair {} (Some "1970-01-01T00:03:20Z")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[address.tz-None-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[address.tz-None-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" deleted file mode 100644 index abca1690d6f8..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[address.tz-None-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[address.tz-None-"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"-(Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5")] - -storage - (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039343.609 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" None) ] - - location: 9 (remaining gas: 1039343.599 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter ] - - location: 10 (remaining gas: 1039343.589 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter.address ] - - location: 11 (remaining gas: 1039343.574 units remaining) - [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 12 (remaining gas: 1039343.559 units remaining) - [ {} - (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 14 (remaining gas: 1039343.544 units remaining) - [ (Pair {} (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5")) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)].out deleted file mode 100644 index 59214aa8a292..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)].out +++ /dev/null @@ -1,31 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)] - -storage - (Some False) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.303 units remaining) - [ (Pair (Pair False False) None) ] - - location: 10 (remaining gas: 1039991.293 units remaining) - [ (Pair False False) @param ] - - location: 11 (remaining gas: 1039991.283 units remaining) - [ False - False ] - - location: 12 (remaining gas: 1039991.263 units remaining) - [ False @and ] - - location: 13 (remaining gas: 1039991.248 units remaining) - [ (Some False) @res ] - - location: 14 (remaining gas: 1039991.233 units remaining) - [ {} @noop - (Some False) @res ] - - location: 16 (remaining gas: 1039991.218 units remaining) - [ (Pair {} (Some False)) ] - - location: 17 (remaining gas: 1039991.208 units remaining) - [ {} @x - (Some False) @y ] - - location: 18 (remaining gas: 1039991.193 units remaining) - [ (Pair {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)].out deleted file mode 100644 index 0de1989da302..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)].out +++ /dev/null @@ -1,31 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)] - -storage - (Some False) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.303 units remaining) - [ (Pair (Pair False True) None) ] - - location: 10 (remaining gas: 1039991.293 units remaining) - [ (Pair False True) @param ] - - location: 11 (remaining gas: 1039991.283 units remaining) - [ False - True ] - - location: 12 (remaining gas: 1039991.263 units remaining) - [ False @and ] - - location: 13 (remaining gas: 1039991.248 units remaining) - [ (Some False) @res ] - - location: 14 (remaining gas: 1039991.233 units remaining) - [ {} @noop - (Some False) @res ] - - location: 16 (remaining gas: 1039991.218 units remaining) - [ (Pair {} (Some False)) ] - - location: 17 (remaining gas: 1039991.208 units remaining) - [ {} @x - (Some False) @y ] - - location: 18 (remaining gas: 1039991.193 units remaining) - [ (Pair {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)].out deleted file mode 100644 index 4b6236ae6839..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)].out +++ /dev/null @@ -1,31 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)] - -storage - (Some False) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.303 units remaining) - [ (Pair (Pair True False) None) ] - - location: 10 (remaining gas: 1039991.293 units remaining) - [ (Pair True False) @param ] - - location: 11 (remaining gas: 1039991.283 units remaining) - [ True - False ] - - location: 12 (remaining gas: 1039991.263 units remaining) - [ False @and ] - - location: 13 (remaining gas: 1039991.248 units remaining) - [ (Some False) @res ] - - location: 14 (remaining gas: 1039991.233 units remaining) - [ {} @noop - (Some False) @res ] - - location: 16 (remaining gas: 1039991.218 units remaining) - [ (Pair {} (Some False)) ] - - location: 17 (remaining gas: 1039991.208 units remaining) - [ {} @x - (Some False) @y ] - - location: 18 (remaining gas: 1039991.193 units remaining) - [ (Pair {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)].out deleted file mode 100644 index 8b9d30f12fd8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)].out +++ /dev/null @@ -1,31 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.303 units remaining) - [ (Pair (Pair True True) None) ] - - location: 10 (remaining gas: 1039991.293 units remaining) - [ (Pair True True) @param ] - - location: 11 (remaining gas: 1039991.283 units remaining) - [ True - True ] - - location: 12 (remaining gas: 1039991.263 units remaining) - [ True @and ] - - location: 13 (remaining gas: 1039991.248 units remaining) - [ (Some True) @res ] - - location: 14 (remaining gas: 1039991.233 units remaining) - [ {} @noop - (Some True) @res ] - - location: 16 (remaining gas: 1039991.218 units remaining) - [ (Pair {} (Some True)) ] - - location: 17 (remaining gas: 1039991.208 units remaining) - [ {} @x - (Some True) @y ] - - location: 18 (remaining gas: 1039991.193 units remaining) - [ (Pair {} (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit].out deleted file mode 100644 index 21e63c6ba144..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit].out +++ /dev/null @@ -1,93 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039960.451 units remaining) - [ (Pair Unit Unit) ] - - location: 7 (remaining gas: 1039960.441 units remaining) - [ ] - - location: 8 (remaining gas: 1039960.431 units remaining) - [ 5 ] - - location: 11 (remaining gas: 1039960.421 units remaining) - [ 6 - 5 ] - - location: 14 (remaining gas: 1039960.371 units remaining) - [ 4 ] - - location: 15 (remaining gas: 1039960.361 units remaining) - [ 4 - 4 ] - - location: 20 (remaining gas: 1039960.326 units remaining) - [ 0 ] - - location: 21 (remaining gas: 1039960.311 units remaining) - [ True ] - - location: 22 (remaining gas: 1039960.301 units remaining) - [ ] - - location: 22 (remaining gas: 1039960.286 units remaining) - [ ] - - location: 28 (remaining gas: 1039960.276 units remaining) - [ 6 ] - - location: 31 (remaining gas: 1039960.266 units remaining) - [ 5 - 6 ] - - location: 34 (remaining gas: 1039960.216 units remaining) - [ 4 ] - - location: 35 (remaining gas: 1039960.206 units remaining) - [ 4 - 4 ] - - location: 40 (remaining gas: 1039960.171 units remaining) - [ 0 ] - - location: 41 (remaining gas: 1039960.156 units remaining) - [ True ] - - location: 42 (remaining gas: 1039960.146 units remaining) - [ ] - - location: 42 (remaining gas: 1039960.131 units remaining) - [ ] - - location: 48 (remaining gas: 1039960.121 units remaining) - [ 12 ] - - location: 51 (remaining gas: 1039960.111 units remaining) - [ -1 - 12 ] - - location: 54 (remaining gas: 1039960.061 units remaining) - [ 12 ] - - location: 55 (remaining gas: 1039960.051 units remaining) - [ 12 - 12 ] - - location: 60 (remaining gas: 1039960.016 units remaining) - [ 0 ] - - location: 61 (remaining gas: 1039960.001 units remaining) - [ True ] - - location: 62 (remaining gas: 1039959.991 units remaining) - [ ] - - location: 62 (remaining gas: 1039959.976 units remaining) - [ ] - - location: 68 (remaining gas: 1039959.966 units remaining) - [ 12 ] - - location: 71 (remaining gas: 1039959.956 units remaining) - [ -5 - 12 ] - - location: 74 (remaining gas: 1039959.906 units remaining) - [ 8 ] - - location: 75 (remaining gas: 1039959.896 units remaining) - [ 8 - 8 ] - - location: 80 (remaining gas: 1039959.861 units remaining) - [ 0 ] - - location: 81 (remaining gas: 1039959.846 units remaining) - [ True ] - - location: 82 (remaining gas: 1039959.836 units remaining) - [ ] - - location: 82 (remaining gas: 1039959.821 units remaining) - [ ] - - location: 88 (remaining gas: 1039959.811 units remaining) - [ Unit ] - - location: 89 (remaining gas: 1039959.796 units remaining) - [ {} @noop - Unit ] - - location: 91 (remaining gas: 1039959.781 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False].out deleted file mode 100644 index 27ca95166a14..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False] - -storage - False -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039993.804 units remaining) - [ (Pair (Pair False False) False) ] - - location: 9 (remaining gas: 1039993.794 units remaining) - [ (Pair False False) @parameter ] - - location: 10 (remaining gas: 1039993.784 units remaining) - [ False - False ] - - location: 11 (remaining gas: 1039993.764 units remaining) - [ False @and ] - - location: 12 (remaining gas: 1039993.749 units remaining) - [ {} @noop - False @and ] - - location: 14 (remaining gas: 1039993.734 units remaining) - [ (Pair {} False) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False].out deleted file mode 100644 index 1b7db01827a7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False] - -storage - False -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039993.804 units remaining) - [ (Pair (Pair False True) False) ] - - location: 9 (remaining gas: 1039993.794 units remaining) - [ (Pair False True) @parameter ] - - location: 10 (remaining gas: 1039993.784 units remaining) - [ False - True ] - - location: 11 (remaining gas: 1039993.764 units remaining) - [ False @and ] - - location: 12 (remaining gas: 1039993.749 units remaining) - [ {} @noop - False @and ] - - location: 14 (remaining gas: 1039993.734 units remaining) - [ (Pair {} False) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False].out deleted file mode 100644 index 5a138dcd59b3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False] - -storage - False -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039993.804 units remaining) - [ (Pair (Pair True False) False) ] - - location: 9 (remaining gas: 1039993.794 units remaining) - [ (Pair True False) @parameter ] - - location: 10 (remaining gas: 1039993.784 units remaining) - [ True - False ] - - location: 11 (remaining gas: 1039993.764 units remaining) - [ False @and ] - - location: 12 (remaining gas: 1039993.749 units remaining) - [ {} @noop - False @and ] - - location: 14 (remaining gas: 1039993.734 units remaining) - [ (Pair {} False) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True].out deleted file mode 100644 index 44ef8c1e01c8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True].out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True] - -storage - True -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039993.804 units remaining) - [ (Pair (Pair True True) False) ] - - location: 9 (remaining gas: 1039993.794 units remaining) - [ (Pair True True) @parameter ] - - location: 10 (remaining gas: 1039993.784 units remaining) - [ True - True ] - - location: 11 (remaining gas: 1039993.764 units remaining) - [ True @and ] - - location: 12 (remaining gas: 1039993.749 units remaining) - [ {} @noop - True @and ] - - location: 14 (remaining gas: 1039993.734 units remaining) - [ (Pair {} True) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000].out deleted file mode 100644 index 142b36bb6d72..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000] - -storage - 4000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 111) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039774.922 units remaining) - [ 4000000000000 @balance ] - - location: 9 (remaining gas: 1039774.907 units remaining) - [ {} - 4000000000000 @balance ] - - location: 11 (remaining gas: 1039774.892 units remaining) - [ (Pair {} 4000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out deleted file mode 100644 index 88515501cb5a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out +++ /dev/null @@ -1,43 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (Some False))1] - -storage - (Pair 4 (Some False)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[0] to 1 -trace - - location: 12 (remaining gas: 1039987.011 units remaining) - [ (Pair 1 { Elt 0 1 } None) ] - - location: 12 (remaining gas: 1039987.001 units remaining) - [ 1 @parameter - (Pair { Elt 0 1 } None) @storage ] - - location: 13 (remaining gas: 1039986.986 units remaining) - [ (Pair { Elt 0 1 } None) @storage ] - - location: 15 (remaining gas: 1039986.976 units remaining) - [ { Elt 0 1 } ] - - location: 16 (remaining gas: 1039986.966 units remaining) - [ { Elt 0 1 } - { Elt 0 1 } ] - - location: 13 (remaining gas: 1039986.936 units remaining) - [ 1 @parameter - { Elt 0 1 } - { Elt 0 1 } ] - - location: 17 (remaining gas: 1039986.163 units remaining) - [ False - { Elt 0 1 } ] - - location: 18 (remaining gas: 1039986.148 units remaining) - [ (Some False) - { Elt 0 1 } ] - - location: 19 (remaining gas: 1039986.138 units remaining) - [ { Elt 0 1 } - (Some False) ] - - location: 20 (remaining gas: 1039986.123 units remaining) - [ (Pair { Elt 0 1 } (Some False)) ] - - location: 21 (remaining gas: 1039986.108 units remaining) - [ {} - (Pair { Elt 0 1 } (Some False)) ] - - location: 23 (remaining gas: 1039986.093 units remaining) - [ (Pair {} { Elt 0 1 } (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out deleted file mode 100644 index d6c58685ff01..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out +++ /dev/null @@ -1,43 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (Some False))0] - -storage - (Pair 4 (Some False)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[0] to 1 -trace - - location: 12 (remaining gas: 1039987.011 units remaining) - [ (Pair 1 { Elt 0 1 } None) ] - - location: 12 (remaining gas: 1039987.001 units remaining) - [ 1 @parameter - (Pair { Elt 0 1 } None) @storage ] - - location: 13 (remaining gas: 1039986.986 units remaining) - [ (Pair { Elt 0 1 } None) @storage ] - - location: 15 (remaining gas: 1039986.976 units remaining) - [ { Elt 0 1 } ] - - location: 16 (remaining gas: 1039986.966 units remaining) - [ { Elt 0 1 } - { Elt 0 1 } ] - - location: 13 (remaining gas: 1039986.936 units remaining) - [ 1 @parameter - { Elt 0 1 } - { Elt 0 1 } ] - - location: 17 (remaining gas: 1039986.163 units remaining) - [ False - { Elt 0 1 } ] - - location: 18 (remaining gas: 1039986.148 units remaining) - [ (Some False) - { Elt 0 1 } ] - - location: 19 (remaining gas: 1039986.138 units remaining) - [ { Elt 0 1 } - (Some False) ] - - location: 20 (remaining gas: 1039986.123 units remaining) - [ (Pair { Elt 0 1 } (Some False)) ] - - location: 21 (remaining gas: 1039986.108 units remaining) - [ {} - (Pair { Elt 0 1 } (Some False)) ] - - location: 23 (remaining gas: 1039986.093 units remaining) - [ (Pair {} { Elt 0 1 } (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out deleted file mode 100644 index 7f6a339bf2ab..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out +++ /dev/null @@ -1,43 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (Some True))1] - -storage - (Pair 4 (Some True)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[1] to 0 -trace - - location: 12 (remaining gas: 1039987.011 units remaining) - [ (Pair 1 { Elt 1 0 } None) ] - - location: 12 (remaining gas: 1039987.001 units remaining) - [ 1 @parameter - (Pair { Elt 1 0 } None) @storage ] - - location: 13 (remaining gas: 1039986.986 units remaining) - [ (Pair { Elt 1 0 } None) @storage ] - - location: 15 (remaining gas: 1039986.976 units remaining) - [ { Elt 1 0 } ] - - location: 16 (remaining gas: 1039986.966 units remaining) - [ { Elt 1 0 } - { Elt 1 0 } ] - - location: 13 (remaining gas: 1039986.936 units remaining) - [ 1 @parameter - { Elt 1 0 } - { Elt 1 0 } ] - - location: 17 (remaining gas: 1039986.163 units remaining) - [ True - { Elt 1 0 } ] - - location: 18 (remaining gas: 1039986.148 units remaining) - [ (Some True) - { Elt 1 0 } ] - - location: 19 (remaining gas: 1039986.138 units remaining) - [ { Elt 1 0 } - (Some True) ] - - location: 20 (remaining gas: 1039986.123 units remaining) - [ (Pair { Elt 1 0 } (Some True)) ] - - location: 21 (remaining gas: 1039986.108 units remaining) - [ {} - (Pair { Elt 1 0 } (Some True)) ] - - location: 23 (remaining gas: 1039986.093 units remaining) - [ (Pair {} { Elt 1 0 } (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.73700321f8.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.73700321f8.out deleted file mode 100644 index 933ffdc00ed0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.73700321f8.out +++ /dev/null @@ -1,43 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (Some True))0] - -storage - (Pair 4 (Some True)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[1] to 0 -trace - - location: 12 (remaining gas: 1039987.011 units remaining) - [ (Pair 1 { Elt 1 0 } None) ] - - location: 12 (remaining gas: 1039987.001 units remaining) - [ 1 @parameter - (Pair { Elt 1 0 } None) @storage ] - - location: 13 (remaining gas: 1039986.986 units remaining) - [ (Pair { Elt 1 0 } None) @storage ] - - location: 15 (remaining gas: 1039986.976 units remaining) - [ { Elt 1 0 } ] - - location: 16 (remaining gas: 1039986.966 units remaining) - [ { Elt 1 0 } - { Elt 1 0 } ] - - location: 13 (remaining gas: 1039986.936 units remaining) - [ 1 @parameter - { Elt 1 0 } - { Elt 1 0 } ] - - location: 17 (remaining gas: 1039986.163 units remaining) - [ True - { Elt 1 0 } ] - - location: 18 (remaining gas: 1039986.148 units remaining) - [ (Some True) - { Elt 1 0 } ] - - location: 19 (remaining gas: 1039986.138 units remaining) - [ { Elt 1 0 } - (Some True) ] - - location: 20 (remaining gas: 1039986.123 units remaining) - [ (Pair { Elt 1 0 } (Some True)) ] - - location: 21 (remaining gas: 1039986.108 units remaining) - [ {} - (Pair { Elt 1 0 } (Some True)) ] - - location: 23 (remaining gas: 1039986.093 units remaining) - [ (Pair {} { Elt 1 0 } (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.1182eca937.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.1182eca937.out deleted file mode 100644 index f3b3c13c182d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.1182eca937.out +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pair 4 (Some True))0] - -storage - (Pair 4 (Some True)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[1] to 4 - Set map(4)[2] to 11 -trace - - location: 12 (remaining gas: 1039985.980 units remaining) - [ (Pair 1 { Elt 1 4 ; Elt 2 11 } None) ] - - location: 12 (remaining gas: 1039985.970 units remaining) - [ 1 @parameter - (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 13 (remaining gas: 1039985.955 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 15 (remaining gas: 1039985.945 units remaining) - [ { Elt 1 4 ; Elt 2 11 } ] - - location: 16 (remaining gas: 1039985.935 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 13 (remaining gas: 1039985.905 units remaining) - [ 1 @parameter - { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 17 (remaining gas: 1039985.131 units remaining) - [ True - { Elt 1 4 ; Elt 2 11 } ] - - location: 18 (remaining gas: 1039985.116 units remaining) - [ (Some True) - { Elt 1 4 ; Elt 2 11 } ] - - location: 19 (remaining gas: 1039985.106 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - (Some True) ] - - location: 20 (remaining gas: 1039985.091 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 21 (remaining gas: 1039985.076 units remaining) - [ {} - (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 23 (remaining gas: 1039985.061 units remaining) - [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out deleted file mode 100644 index 0683aadc22e2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pair 4 (Some True))1] - -storage - (Pair 4 (Some True)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[1] to 4 - Set map(4)[2] to 11 -trace - - location: 12 (remaining gas: 1039985.980 units remaining) - [ (Pair 1 { Elt 1 4 ; Elt 2 11 } None) ] - - location: 12 (remaining gas: 1039985.970 units remaining) - [ 1 @parameter - (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 13 (remaining gas: 1039985.955 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 15 (remaining gas: 1039985.945 units remaining) - [ { Elt 1 4 ; Elt 2 11 } ] - - location: 16 (remaining gas: 1039985.935 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 13 (remaining gas: 1039985.905 units remaining) - [ 1 @parameter - { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 17 (remaining gas: 1039985.131 units remaining) - [ True - { Elt 1 4 ; Elt 2 11 } ] - - location: 18 (remaining gas: 1039985.116 units remaining) - [ (Some True) - { Elt 1 4 ; Elt 2 11 } ] - - location: 19 (remaining gas: 1039985.106 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - (Some True) ] - - location: 20 (remaining gas: 1039985.091 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 21 (remaining gas: 1039985.076 units remaining) - [ {} - (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 23 (remaining gas: 1039985.061 units remaining) - [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.1eead33885.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.1eead33885.out deleted file mode 100644 index 2a6aa7432bfe..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.1eead33885.out +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pair 4 (Some True))1] - -storage - (Pair 4 (Some True)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[1] to 4 - Set map(4)[2] to 11 -trace - - location: 12 (remaining gas: 1039985.980 units remaining) - [ (Pair 2 { Elt 1 4 ; Elt 2 11 } None) ] - - location: 12 (remaining gas: 1039985.970 units remaining) - [ 2 @parameter - (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 13 (remaining gas: 1039985.955 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 15 (remaining gas: 1039985.945 units remaining) - [ { Elt 1 4 ; Elt 2 11 } ] - - location: 16 (remaining gas: 1039985.935 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 13 (remaining gas: 1039985.905 units remaining) - [ 2 @parameter - { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 17 (remaining gas: 1039985.131 units remaining) - [ True - { Elt 1 4 ; Elt 2 11 } ] - - location: 18 (remaining gas: 1039985.116 units remaining) - [ (Some True) - { Elt 1 4 ; Elt 2 11 } ] - - location: 19 (remaining gas: 1039985.106 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - (Some True) ] - - location: 20 (remaining gas: 1039985.091 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 21 (remaining gas: 1039985.076 units remaining) - [ {} - (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 23 (remaining gas: 1039985.061 units remaining) - [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out deleted file mode 100644 index f35820c42463..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pair 4 (Some True))0] - -storage - (Pair 4 (Some True)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[1] to 4 - Set map(4)[2] to 11 -trace - - location: 12 (remaining gas: 1039985.980 units remaining) - [ (Pair 2 { Elt 1 4 ; Elt 2 11 } None) ] - - location: 12 (remaining gas: 1039985.970 units remaining) - [ 2 @parameter - (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 13 (remaining gas: 1039985.955 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 15 (remaining gas: 1039985.945 units remaining) - [ { Elt 1 4 ; Elt 2 11 } ] - - location: 16 (remaining gas: 1039985.935 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 13 (remaining gas: 1039985.905 units remaining) - [ 2 @parameter - { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 17 (remaining gas: 1039985.131 units remaining) - [ True - { Elt 1 4 ; Elt 2 11 } ] - - location: 18 (remaining gas: 1039985.116 units remaining) - [ (Some True) - { Elt 1 4 ; Elt 2 11 } ] - - location: 19 (remaining gas: 1039985.106 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - (Some True) ] - - location: 20 (remaining gas: 1039985.091 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 21 (remaining gas: 1039985.076 units remaining) - [ {} - (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 23 (remaining gas: 1039985.061 units remaining) - [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out deleted file mode 100644 index 40380c2f5868..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pair 4 (Some False))1] - -storage - (Pair 4 (Some False)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[1] to 4 - Set map(4)[2] to 11 -trace - - location: 12 (remaining gas: 1039985.980 units remaining) - [ (Pair 3 { Elt 1 4 ; Elt 2 11 } None) ] - - location: 12 (remaining gas: 1039985.970 units remaining) - [ 3 @parameter - (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 13 (remaining gas: 1039985.955 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 15 (remaining gas: 1039985.945 units remaining) - [ { Elt 1 4 ; Elt 2 11 } ] - - location: 16 (remaining gas: 1039985.935 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 13 (remaining gas: 1039985.905 units remaining) - [ 3 @parameter - { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 17 (remaining gas: 1039985.131 units remaining) - [ False - { Elt 1 4 ; Elt 2 11 } ] - - location: 18 (remaining gas: 1039985.116 units remaining) - [ (Some False) - { Elt 1 4 ; Elt 2 11 } ] - - location: 19 (remaining gas: 1039985.106 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - (Some False) ] - - location: 20 (remaining gas: 1039985.091 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] - - location: 21 (remaining gas: 1039985.076 units remaining) - [ {} - (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] - - location: 23 (remaining gas: 1039985.061 units remaining) - [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out deleted file mode 100644 index fa1acb858113..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pair 4 (Some False))0] - -storage - (Pair 4 (Some False)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) - Set map(4)[1] to 4 - Set map(4)[2] to 11 -trace - - location: 12 (remaining gas: 1039985.980 units remaining) - [ (Pair 3 { Elt 1 4 ; Elt 2 11 } None) ] - - location: 12 (remaining gas: 1039985.970 units remaining) - [ 3 @parameter - (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 13 (remaining gas: 1039985.955 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 15 (remaining gas: 1039985.945 units remaining) - [ { Elt 1 4 ; Elt 2 11 } ] - - location: 16 (remaining gas: 1039985.935 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 13 (remaining gas: 1039985.905 units remaining) - [ 3 @parameter - { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 17 (remaining gas: 1039985.131 units remaining) - [ False - { Elt 1 4 ; Elt 2 11 } ] - - location: 18 (remaining gas: 1039985.116 units remaining) - [ (Some False) - { Elt 1 4 ; Elt 2 11 } ] - - location: 19 (remaining gas: 1039985.106 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - (Some False) ] - - location: 20 (remaining gas: 1039985.091 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] - - location: 21 (remaining gas: 1039985.076 units remaining) - [ {} - (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] - - location: 23 (remaining gas: 1039985.061 units remaining) - [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0].out deleted file mode 100644 index a695dad77649..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0].out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0] - -storage - (Pair 4 (Some False)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) -trace - - location: 12 (remaining gas: 1039988.004 units remaining) - [ (Pair 1 {} None) ] - - location: 12 (remaining gas: 1039987.994 units remaining) - [ 1 @parameter - (Pair {} None) @storage ] - - location: 13 (remaining gas: 1039987.979 units remaining) - [ (Pair {} None) @storage ] - - location: 15 (remaining gas: 1039987.969 units remaining) - [ {} ] - - location: 16 (remaining gas: 1039987.959 units remaining) - [ {} - {} ] - - location: 13 (remaining gas: 1039987.929 units remaining) - [ 1 @parameter - {} - {} ] - - location: 17 (remaining gas: 1039987.158 units remaining) - [ False - {} ] - - location: 18 (remaining gas: 1039987.143 units remaining) - [ (Some False) - {} ] - - location: 19 (remaining gas: 1039987.133 units remaining) - [ {} - (Some False) ] - - location: 20 (remaining gas: 1039987.118 units remaining) - [ (Pair {} (Some False)) ] - - location: 21 (remaining gas: 1039987.103 units remaining) - [ {} - (Pair {} (Some False)) ] - - location: 23 (remaining gas: 1039987.088 units remaining) - [ (Pair {} {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1].out deleted file mode 100644 index ecbd7447efd2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1].out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1] - -storage - (Pair 4 (Some False)) -emitted operations - -big_map diff - New map(4) of type (big_map nat nat) -trace - - location: 12 (remaining gas: 1039988.004 units remaining) - [ (Pair 1 {} None) ] - - location: 12 (remaining gas: 1039987.994 units remaining) - [ 1 @parameter - (Pair {} None) @storage ] - - location: 13 (remaining gas: 1039987.979 units remaining) - [ (Pair {} None) @storage ] - - location: 15 (remaining gas: 1039987.969 units remaining) - [ {} ] - - location: 16 (remaining gas: 1039987.959 units remaining) - [ {} - {} ] - - location: 13 (remaining gas: 1039987.929 units remaining) - [ 1 @parameter - {} - {} ] - - location: 17 (remaining gas: 1039987.158 units remaining) - [ False - {} ] - - location: 18 (remaining gas: 1039987.143 units remaining) - [ (Some False) - {} ] - - location: 19 (remaining gas: 1039987.133 units remaining) - [ {} - (Some False) ] - - location: 20 (remaining gas: 1039987.118 units remaining) - [ (Pair {} (Some False)) ] - - location: 21 (remaining gas: 1039987.103 units remaining) - [ {} - (Pair {} (Some False)) ] - - location: 23 (remaining gas: 1039987.088 units remaining) - [ (Pair {} {} (Some False)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" deleted file mode 100644 index 48a1663e2d42..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"baz"-(Pair 4 (Some False))] - -storage - (Pair 4 (Some False)) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["bar"] to 4 - Set map(4)["foo"] to 11 -trace - - location: 12 (remaining gas: 1039985.438 units remaining) - [ (Pair "baz" { Elt "bar" 4 ; Elt "foo" 11 } None) ] - - location: 12 (remaining gas: 1039985.428 units remaining) - [ "baz" @parameter - (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 13 (remaining gas: 1039985.413 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 15 (remaining gas: 1039985.403 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 16 (remaining gas: 1039985.393 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 13 (remaining gas: 1039985.363 units remaining) - [ "baz" @parameter - { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 17 (remaining gas: 1039984.384 units remaining) - [ False - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 18 (remaining gas: 1039984.369 units remaining) - [ (Some False) - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 19 (remaining gas: 1039984.359 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - (Some False) ] - - location: 20 (remaining gas: 1039984.344 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] - - location: 21 (remaining gas: 1039984.329 units remaining) - [ {} - (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] - - location: 23 (remaining gas: 1039984.314 units remaining) - [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" deleted file mode 100644 index 296dc0dd5dfa..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"foo"-(Pair 4 (Some True))] - -storage - (Pair 4 (Some True)) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["bar"] to 4 - Set map(4)["foo"] to 11 -trace - - location: 12 (remaining gas: 1039985.438 units remaining) - [ (Pair "foo" { Elt "bar" 4 ; Elt "foo" 11 } None) ] - - location: 12 (remaining gas: 1039985.428 units remaining) - [ "foo" @parameter - (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 13 (remaining gas: 1039985.413 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 15 (remaining gas: 1039985.403 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 16 (remaining gas: 1039985.393 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 13 (remaining gas: 1039985.363 units remaining) - [ "foo" @parameter - { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 17 (remaining gas: 1039984.384 units remaining) - [ True - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 18 (remaining gas: 1039984.369 units remaining) - [ (Some True) - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 19 (remaining gas: 1039984.359 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - (Some True) ] - - location: 20 (remaining gas: 1039984.344 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - - location: 21 (remaining gas: 1039984.329 units remaining) - [ {} - (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - - location: 23 (remaining gas: 1039984.314 units remaining) - [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" deleted file mode 100644 index 837191329436..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" +++ /dev/null @@ -1,44 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"bar"-(Pair 4 (Some True))] - -storage - (Pair 4 (Some True)) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["bar"] to 4 - Set map(4)["foo"] to 11 -trace - - location: 12 (remaining gas: 1039985.438 units remaining) - [ (Pair "bar" { Elt "bar" 4 ; Elt "foo" 11 } None) ] - - location: 12 (remaining gas: 1039985.428 units remaining) - [ "bar" @parameter - (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 13 (remaining gas: 1039985.413 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 15 (remaining gas: 1039985.403 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 16 (remaining gas: 1039985.393 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 13 (remaining gas: 1039985.363 units remaining) - [ "bar" @parameter - { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 17 (remaining gas: 1039984.384 units remaining) - [ True - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 18 (remaining gas: 1039984.369 units remaining) - [ (Some True) - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 19 (remaining gas: 1039984.359 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - (Some True) ] - - location: 20 (remaining gas: 1039984.344 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - - location: 21 (remaining gas: 1039984.329 units remaining) - [ {} - (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - - location: 23 (remaining gas: 1039984.314 units remaining) - [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\".968709d39d.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\".968709d39d.out" deleted file mode 100644 index 16b5c6272bde..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\".968709d39d.out" +++ /dev/null @@ -1,43 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "foo" 0 } None)-"foo"-(Pair 4 (Some True))] - -storage - (Pair 4 (Some True)) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["foo"] to 0 -trace - - location: 12 (remaining gas: 1039986.718 units remaining) - [ (Pair "foo" { Elt "foo" 0 } None) ] - - location: 12 (remaining gas: 1039986.708 units remaining) - [ "foo" @parameter - (Pair { Elt "foo" 0 } None) @storage ] - - location: 13 (remaining gas: 1039986.693 units remaining) - [ (Pair { Elt "foo" 0 } None) @storage ] - - location: 15 (remaining gas: 1039986.683 units remaining) - [ { Elt "foo" 0 } ] - - location: 16 (remaining gas: 1039986.673 units remaining) - [ { Elt "foo" 0 } - { Elt "foo" 0 } ] - - location: 13 (remaining gas: 1039986.643 units remaining) - [ "foo" @parameter - { Elt "foo" 0 } - { Elt "foo" 0 } ] - - location: 17 (remaining gas: 1039985.665 units remaining) - [ True - { Elt "foo" 0 } ] - - location: 18 (remaining gas: 1039985.650 units remaining) - [ (Some True) - { Elt "foo" 0 } ] - - location: 19 (remaining gas: 1039985.640 units remaining) - [ { Elt "foo" 0 } - (Some True) ] - - location: 20 (remaining gas: 1039985.625 units remaining) - [ (Pair { Elt "foo" 0 } (Some True)) ] - - location: 21 (remaining gas: 1039985.610 units remaining) - [ {} - (Pair { Elt "foo" 0 } (Some True)) ] - - location: 23 (remaining gas: 1039985.595 units remaining) - [ (Pair {} { Elt "foo" 0 } (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" deleted file mode 100644 index 666895ebf6cb..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" +++ /dev/null @@ -1,43 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "foo" 1 } None)-"bar"-(Pair 4 (Some False))] - -storage - (Pair 4 (Some False)) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) - Set map(4)["foo"] to 1 -trace - - location: 12 (remaining gas: 1039986.718 units remaining) - [ (Pair "bar" { Elt "foo" 1 } None) ] - - location: 12 (remaining gas: 1039986.708 units remaining) - [ "bar" @parameter - (Pair { Elt "foo" 1 } None) @storage ] - - location: 13 (remaining gas: 1039986.693 units remaining) - [ (Pair { Elt "foo" 1 } None) @storage ] - - location: 15 (remaining gas: 1039986.683 units remaining) - [ { Elt "foo" 1 } ] - - location: 16 (remaining gas: 1039986.673 units remaining) - [ { Elt "foo" 1 } - { Elt "foo" 1 } ] - - location: 13 (remaining gas: 1039986.643 units remaining) - [ "bar" @parameter - { Elt "foo" 1 } - { Elt "foo" 1 } ] - - location: 17 (remaining gas: 1039985.665 units remaining) - [ False - { Elt "foo" 1 } ] - - location: 18 (remaining gas: 1039985.650 units remaining) - [ (Some False) - { Elt "foo" 1 } ] - - location: 19 (remaining gas: 1039985.640 units remaining) - [ { Elt "foo" 1 } - (Some False) ] - - location: 20 (remaining gas: 1039985.625 units remaining) - [ (Pair { Elt "foo" 1 } (Some False)) ] - - location: 21 (remaining gas: 1039985.610 units remaining) - [ {} - (Pair { Elt "foo" 1 } (Some False)) ] - - location: 23 (remaining gas: 1039985.595 units remaining) - [ (Pair {} { Elt "foo" 1 } (Some False)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair 4 (Some False))].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair 4 (Some False))].out" deleted file mode 100644 index 11325b8157a5..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair 4 (Some False))].out" +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-"bar"-(Pair 4 (Some False))] - -storage - (Pair 4 (Some False)) -emitted operations - -big_map diff - New map(4) of type (big_map string nat) -trace - - location: 12 (remaining gas: 1039987.960 units remaining) - [ (Pair "bar" {} None) ] - - location: 12 (remaining gas: 1039987.950 units remaining) - [ "bar" @parameter - (Pair {} None) @storage ] - - location: 13 (remaining gas: 1039987.935 units remaining) - [ (Pair {} None) @storage ] - - location: 15 (remaining gas: 1039987.925 units remaining) - [ {} ] - - location: 16 (remaining gas: 1039987.915 units remaining) - [ {} - {} ] - - location: 13 (remaining gas: 1039987.885 units remaining) - [ "bar" @parameter - {} - {} ] - - location: 17 (remaining gas: 1039986.909 units remaining) - [ False - {} ] - - location: 18 (remaining gas: 1039986.894 units remaining) - [ (Some False) - {} ] - - location: 19 (remaining gas: 1039986.884 units remaining) - [ {} - (Some False) ] - - location: 20 (remaining gas: 1039986.869 units remaining) - [ (Pair {} (Some False)) ] - - location: 21 (remaining gas: 1039986.854 units remaining) - [ {} - (Pair {} (Some False)) ] - - location: 23 (remaining gas: 1039986.839 units remaining) - [ (Pair {} {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out deleted file mode 100644 index 2b352118d848..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0x0000000000000000000000000000000000000000000000000000000000000000)] - -storage - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.391 units remaining) - [ (Pair Unit None) ] - - location: 8 (remaining gas: 1039993.381 units remaining) - [ ] - - location: 9 (remaining gas: 1039993.371 units remaining) - [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.356 units remaining) - [ (Some 0x0000000000000000000000000000000000000000000000000000000000000000) ] - - location: 13 (remaining gas: 1039993.341 units remaining) - [ {} - (Some 0x0000000000000000000000000000000000000000000000000000000000000000) ] - - location: 15 (remaining gas: 1039993.326 units remaining) - [ (Pair {} - (Some 0x0000000000000000000000000000000000000000000000000000000000000000)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x100000000000.d1219ca789.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x100000000000.d1219ca789.out deleted file mode 100644 index a8ca19bc798f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x100000000000.d1219ca789.out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x1000000000000000000000000000000000000000000000000000000000000000)] - -storage - (Some 0x1000000000000000000000000000000000000000000000000000000000000000) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.391 units remaining) - [ (Pair Unit None) ] - - location: 8 (remaining gas: 1039993.381 units remaining) - [ ] - - location: 9 (remaining gas: 1039993.371 units remaining) - [ 0x1000000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.356 units remaining) - [ (Some 0x1000000000000000000000000000000000000000000000000000000000000000) ] - - location: 13 (remaining gas: 1039993.341 units remaining) - [ {} - (Some 0x1000000000000000000000000000000000000000000000000000000000000000) ] - - location: 15 (remaining gas: 1039993.326 units remaining) - [ (Pair {} - (Some 0x1000000000000000000000000000000000000000000000000000000000000000)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0].out deleted file mode 100644 index 6dd195dda91a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 0x0000000000000000000000000000000000000000000000000000000000000000 0) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 0x0000000000000000000000000000000000000000000000000000000000000000 @parameter ] - - location: 8 (remaining gas: 1039994.663 units remaining) - [ 0 ] - - location: 9 (remaining gas: 1039994.648 units remaining) - [ {} - 0 ] - - location: 11 (remaining gas: 1039994.633 units remaining) - [ (Pair {} 0) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1].out deleted file mode 100644 index 2b3f3acda3ce..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 0) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @parameter ] - - location: 8 (remaining gas: 1039994.663 units remaining) - [ 1 ] - - location: 9 (remaining gas: 1039994.648 units remaining) - [ {} - 1 ] - - location: 11 (remaining gas: 1039994.633 units remaining) - [ (Pair {} 1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f2.7a85c336ff.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f2.7a85c336ff.out deleted file mode 100644 index 391d2f43b235..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f2.7a85c336ff.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f24e50a89a6423f939026ed91349fc9af16c27-17832688077013577776524784494464728518213913213412866604053735695200962927400] - -storage - 17832688077013577776524784494464728518213913213412866604053735695200962927400 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 0x28db8e57af88d9576acd181b89f24e50a89a6423f939026ed91349fc9af16c27 0) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 0x28db8e57af88d9576acd181b89f24e50a89a6423f939026ed91349fc9af16c27 @parameter ] - - location: 8 (remaining gas: 1039994.663 units remaining) - [ 17832688077013577776524784494464728518213913213412866604053735695200962927400 ] - - location: 9 (remaining gas: 1039994.648 units remaining) - [ {} - 17832688077013577776524784494464728518213913213412866604053735695200962927400 ] - - location: 11 (remaining gas: 1039994.633 units remaining) - [ (Pair {} - 17832688077013577776524784494464728518213913213412866604053735695200962927400) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986.b821eb26b3.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986.b821eb26b3.out deleted file mode 100644 index d50cfbd38689..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986.b821eb26b3.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986fe0f7c81fab16d26819d0534b7691c0b0719-11320265829256585830781521966149529460476767408210445238902869222031333517497] - -storage - 11320265829256585830781521966149529460476767408210445238902869222031333517497 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 0xb9e8abf8dc324a010007addde986fe0f7c81fab16d26819d0534b7691c0b0719 0) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 0xb9e8abf8dc324a010007addde986fe0f7c81fab16d26819d0534b7691c0b0719 @parameter ] - - location: 8 (remaining gas: 1039994.663 units remaining) - [ 11320265829256585830781521966149529460476767408210445238902869222031333517497 ] - - location: 9 (remaining gas: 1039994.648 units remaining) - [ {} - 11320265829256585830781521966149529460476767408210445238902869222031333517497 ] - - location: 11 (remaining gas: 1039994.633 units remaining) - [ (Pair {} - 11320265829256585830781521966149529460476767408210445238902869222031333517497) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16].out deleted file mode 100644 index bc9501dfd03c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16] - -storage - 16 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039989.509 units remaining) - [ (Pair 0x1000000000000000000000000000000000000000000000000000000000000000 0) ] - - location: 7 (remaining gas: 1039989.499 units remaining) - [ 0x1000000000000000000000000000000000000000000000000000000000000000 @parameter ] - - location: 8 (remaining gas: 1039989.374 units remaining) - [ 16 ] - - location: 9 (remaining gas: 1039989.359 units remaining) - [ (Some 16) ] - - location: 11 (remaining gas: 1039989.349 units remaining) - [ 16 @some ] - - location: 11 (remaining gas: 1039989.334 units remaining) - [ 16 @some ] - - location: 17 (remaining gas: 1039989.324 units remaining) - [ 1 - 16 @some ] - - location: 20 (remaining gas: 1039989.324 units remaining) - [ 16 ] - - location: 21 (remaining gas: 1039989.309 units remaining) - [ {} - 16 ] - - location: 23 (remaining gas: 1039989.294 units remaining) - [ (Pair {} 16) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0accef5bef.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0accef5bef.out deleted file mode 100644 index 7dbb232f0b7b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0accef5bef.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000--42-0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73] - -storage - 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair -42 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ -42 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.457 units remaining) - [ 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] - - location: 9 (remaining gas: 1039994.442 units remaining) - [ {} - 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] - - location: 11 (remaining gas: 1039994.427 units remaining) - [ (Pair {} 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0ecc537252.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0ecc537252.out deleted file mode 100644 index c34b6ee49065..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0ecc537252.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-2-0x0200000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0200000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 2 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 2 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.457 units remaining) - [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] - - location: 9 (remaining gas: 1039994.442 units remaining) - [ {} - 0x0200000000000000000000000000000000000000000000000000000000000000 ] - - location: 11 (remaining gas: 1039994.427 units remaining) - [ (Pair {} 0x0200000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2229b767cd.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2229b767cd.out deleted file mode 100644 index 97f716102e0c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2229b767cd.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000--1-0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73] - -storage - 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair -1 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ -1 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.457 units remaining) - [ 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] - - location: 9 (remaining gas: 1039994.442 units remaining) - [ {} - 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] - - location: 11 (remaining gas: 1039994.427 units remaining) - [ (Pair {} 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2ff549b46b.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2ff549b46b.out deleted file mode 100644 index 61ac661c8b5e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2ff549b46b.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-0-0x0000000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0000000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 0 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 0 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.458 units remaining) - [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 9 (remaining gas: 1039994.443 units remaining) - [ {} - 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 11 (remaining gas: 1039994.428 units remaining) - [ (Pair {} 0x0000000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.bf8a711be6.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.bf8a711be6.out deleted file mode 100644 index 9581090d026b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.bf8a711be6.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-52435875175126190479447740508185965837690552500527637822603658699938581184514-0x0100000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0100000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 52435875175126190479447740508185965837690552500527637822603658699938581184514 - 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.d41cbb044b.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.d41cbb044b.out deleted file mode 100644 index 3dec992e4be9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.d41cbb044b.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-1-0x0100000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0100000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 1 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 1 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.457 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 9 (remaining gas: 1039994.442 units remaining) - [ {} - 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 11 (remaining gas: 1039994.427 units remaining) - [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.a50412e458.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.a50412e458.out deleted file mode 100644 index f40696bb9248..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.a50412e458.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f-22620284817922784902564672469917992996328211127984472897491698543785655336309-0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62] - -storage - 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 22620284817922784902564672469917992996328211127984472897491698543785655336309 - 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter - 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.f3a349c4a7.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.f3a349c4a7.out deleted file mode 100644 index cc884b83d6b3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.f3a349c4a7.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f-33644916630334844239120348434626468649534186770809802792596996408934105684394-0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221] - -storage - 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 33644916630334844239120348434626468649534186770809802792596996408934105684394 - 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter - 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.1b9676e4c2.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.1b9676e4c2.out deleted file mode 100644 index 468e2cd19554..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.1b9676e4c2.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-69615968247920749285624776342583898043608129789011377475114141186797415307882-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] - -storage - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 69615968247920749285624776342583898043608129789011377475114141186797415307882 - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.e966dc6de5.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.e966dc6de5.out deleted file mode 100644 index 78dc893e86b1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.e966dc6de5.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-17180093072794558806177035834397932205917577288483739652510482486858834123369-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] - -storage - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 17180093072794558806177035834397932205917577288483739652510482486858834123369 - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.964835cc43.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.964835cc43.out deleted file mode 100644 index b3cbf75babc6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.964835cc43.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-1-0x0100000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0100000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 1 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 1 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.457 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 9 (remaining gas: 1039994.442 units remaining) - [ {} - 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 11 (remaining gas: 1039994.427 units remaining) - [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.b25ea709fb.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.b25ea709fb.out deleted file mode 100644 index 6ea8cef6c256..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.b25ea709fb.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-0-0x0000000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0000000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 0 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 0 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.458 units remaining) - [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 9 (remaining gas: 1039994.443 units remaining) - [ {} - 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 11 (remaining gas: 1039994.428 units remaining) - [ (Pair {} 0x0000000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.eae36753ea.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.eae36753ea.out deleted file mode 100644 index 4df7e8f123b7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.eae36753ea.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-52435875175126190479447740508185965837690552500527637822603658699938581184514-0x0100000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0100000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 52435875175126190479447740508185965837690552500527637822603658699938581184514 - 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.ee57dac8f7.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.ee57dac8f7.out deleted file mode 100644 index fd88d683b058..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.ee57dac8f7.out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-2-0x0200000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0200000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 2 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 2 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.457 units remaining) - [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] - - location: 9 (remaining gas: 1039994.442 units remaining) - [ {} - 0x0200000000000000000000000000000000000000000000000000000000000000 ] - - location: 11 (remaining gas: 1039994.427 units remaining) - [ (Pair {} 0x0200000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out deleted file mode 100644 index bf1b847aa4ec..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f-22620284817922784902564672469917992996328211127984472897491698543785655336309-0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62] - -storage - 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 22620284817922784902564672469917992996328211127984472897491698543785655336309 - 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter - 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.bd5800f6b8.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.bd5800f6b8.out deleted file mode 100644 index f388e993fba4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.bd5800f6b8.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f-33644916630334844239120348434626468649534186770809802792596996408934105684394-0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221] - -storage - 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 33644916630334844239120348434626468649534186770809802792596996408934105684394 - 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter - 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.00e897789a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.00e897789a.out deleted file mode 100644 index fc558998e551..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.00e897789a.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-17180093072794558806177035834397932205917577288483739652510482486858834123369-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] - -storage - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 17180093072794558806177035834397932205917577288483739652510482486858834123369 - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.a4697eaa13.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.a4697eaa13.out deleted file mode 100644 index eb22e253da18..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.a4697eaa13.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-69615968247920749285624776342583898043608129789011377475114141186797415307882-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] - -storage - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.798 units remaining) - [ (Pair 69615968247920749285624776342583898043608129789011377475114141186797415307882 - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] - - location: 7 (remaining gas: 1039994.788 units remaining) - [ 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] - - location: 8 (remaining gas: 1039994.424 units remaining) - [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 9 (remaining gas: 1039994.409 units remaining) - [ {} - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 11 (remaining gas: 1039994.394 units remaining) - [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.0177355bbf.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.0177355bbf.out deleted file mode 100644 index 0e28c015a739..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.0177355bbf.out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-2-0x0200000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0200000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 2 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 2 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - 2 @parameter ] - - location: 9 (remaining gas: 1039993.849 units remaining) - [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] - - location: 10 (remaining gas: 1039993.834 units remaining) - [ {} - 0x0200000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.819 units remaining) - [ (Pair {} 0x0200000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.744166c609.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.744166c609.out deleted file mode 100644 index 233aff5a652f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.744166c609.out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000--1-0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73] - -storage - 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair -1 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ -1 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - -1 @parameter ] - - location: 9 (remaining gas: 1039993.849 units remaining) - [ 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] - - location: 10 (remaining gas: 1039993.834 units remaining) - [ {} - 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] - - location: 12 (remaining gas: 1039993.819 units remaining) - [ (Pair {} 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.9f3c5cdc6a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.9f3c5cdc6a.out deleted file mode 100644 index a1ea71b4bfd9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.9f3c5cdc6a.out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-0-0x0000000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0000000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 0 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 0 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - 0 @parameter ] - - location: 9 (remaining gas: 1039993.850 units remaining) - [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 10 (remaining gas: 1039993.835 units remaining) - [ {} - 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.820 units remaining) - [ (Pair {} 0x0000000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.a54cb341ba.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.a54cb341ba.out deleted file mode 100644 index 5e1bbb009218..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.a54cb341ba.out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000--42-0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73] - -storage - 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair -42 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ -42 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - -42 @parameter ] - - location: 9 (remaining gas: 1039993.849 units remaining) - [ 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] - - location: 10 (remaining gas: 1039993.834 units remaining) - [ {} - 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] - - location: 12 (remaining gas: 1039993.819 units remaining) - [ (Pair {} 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.b0dc584c94.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.b0dc584c94.out deleted file mode 100644 index 00c2b789aa17..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.b0dc584c94.out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-1-0x0100000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0100000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 1 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 1 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - 1 @parameter ] - - location: 9 (remaining gas: 1039993.849 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 10 (remaining gas: 1039993.834 units remaining) - [ {} - 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.819 units remaining) - [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.bddcad090c.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.bddcad090c.out deleted file mode 100644 index 8cb48f693eae..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.bddcad090c.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-52435875175126190479447740508185965837690552500527637822603658699938581184514-0x0100000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0100000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 52435875175126190479447740508185965837690552500527637822603658699938581184514 - 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.92c153eb47.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.92c153eb47.out deleted file mode 100644 index aacb2fffc956..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.92c153eb47.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f-22620284817922784902564672469917992996328211127984472897491698543785655336309-0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62] - -storage - 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 22620284817922784902564672469917992996328211127984472897491698543785655336309 - 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter - 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage - 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.290ab49d11.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.290ab49d11.out deleted file mode 100644 index b7bdcaa334bb..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.290ab49d11.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f-33644916630334844239120348434626468649534186770809802792596996408934105684394-0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221] - -storage - 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 33644916630334844239120348434626468649534186770809802792596996408934105684394 - 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter - 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage - 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.69f3589a06.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.69f3589a06.out deleted file mode 100644 index 378c083f107f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.69f3589a06.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-17180093072794558806177035834397932205917577288483739652510482486858834123369-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] - -storage - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 17180093072794558806177035834397932205917577288483739652510482486858834123369 - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage - 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.fee3c5cf43.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.fee3c5cf43.out deleted file mode 100644 index 14dfca40e3ac..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.fee3c5cf43.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-69615968247920749285624776342583898043608129789011377475114141186797415307882-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] - -storage - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 69615968247920749285624776342583898043608129789011377475114141186797415307882 - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage - 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.1bccc033e8.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.1bccc033e8.out deleted file mode 100644 index e5c31af94bb7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.1bccc033e8.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-52435875175126190479447740508185965837690552500527637822603658699938581184514-0x0100000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0100000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 52435875175126190479447740508185965837690552500527637822603658699938581184514 - 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.40958700fe.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.40958700fe.out deleted file mode 100644 index 4f0b31b80a76..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.40958700fe.out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-0-0x0000000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0000000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 0 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 0 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - 0 @parameter ] - - location: 9 (remaining gas: 1039993.850 units remaining) - [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 10 (remaining gas: 1039993.835 units remaining) - [ {} - 0x0000000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.820 units remaining) - [ (Pair {} 0x0000000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.6c62b03d78.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.6c62b03d78.out deleted file mode 100644 index 82e22e036221..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.6c62b03d78.out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-1-0x0100000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0100000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 1 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 1 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - 1 @parameter ] - - location: 9 (remaining gas: 1039993.849 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 10 (remaining gas: 1039993.834 units remaining) - [ {} - 0x0100000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.819 units remaining) - [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.d23f269341.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.d23f269341.out deleted file mode 100644 index 044d347cc2f2..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.d23f269341.out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-2-0x0200000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0200000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 2 0x0100000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 2 @parameter - 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage - 2 @parameter ] - - location: 9 (remaining gas: 1039993.849 units remaining) - [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] - - location: 10 (remaining gas: 1039993.834 units remaining) - [ {} - 0x0200000000000000000000000000000000000000000000000000000000000000 ] - - location: 12 (remaining gas: 1039993.819 units remaining) - [ (Pair {} 0x0200000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.927f808504.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.927f808504.out deleted file mode 100644 index 32d293214e82..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.927f808504.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f-22620284817922784902564672469917992996328211127984472897491698543785655336309-0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62] - -storage - 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 22620284817922784902564672469917992996328211127984472897491698543785655336309 - 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter - 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage - 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.0c114c956a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.0c114c956a.out deleted file mode 100644 index f97d6bac4814..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.0c114c956a.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f-33644916630334844239120348434626468649534186770809802792596996408934105684394-0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221] - -storage - 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 33644916630334844239120348434626468649534186770809802792596996408934105684394 - 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter - 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage - 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.03c4f38e68.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.03c4f38e68.out deleted file mode 100644 index 254103eb4f7f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.03c4f38e68.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-69615968247920749285624776342583898043608129789011377475114141186797415307882-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] - -storage - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 69615968247920749285624776342583898043608129789011377475114141186797415307882 - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage - 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.8ed19cfdd9.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.8ed19cfdd9.out deleted file mode 100644 index 92beeb5bdce0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.8ed19cfdd9.out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-17180093072794558806177035834397932205917577288483739652510482486858834123369-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] - -storage - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.200 units remaining) - [ (Pair 17180093072794558806177035834397932205917577288483739652510482486858834123369 - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] - - location: 7 (remaining gas: 1039994.190 units remaining) - [ 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter - 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] - - location: 8 (remaining gas: 1039994.180 units remaining) - [ 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage - 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter ] - - location: 9 (remaining gas: 1039993.816 units remaining) - [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 10 (remaining gas: 1039993.801 units remaining) - [ {} - 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] - - location: 12 (remaining gas: 1039993.786 units remaining) - [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34].out deleted file mode 100644 index 6a58103fccae..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34] - -storage - 34 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039994.492 units remaining) - [ (Pair (Pair 34 17) 0) ] - - location: 9 (remaining gas: 1039994.482 units remaining) - [ (Pair 34 17) @parameter ] - - location: 10 (remaining gas: 1039994.472 units remaining) - [ 34 ] - - location: 11 (remaining gas: 1039994.457 units remaining) - [ {} - 34 ] - - location: 13 (remaining gas: 1039994.442 units remaining) - [ (Pair {} 34) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17].out deleted file mode 100644 index a2b6390e0b1e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17] - -storage - 17 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039994.492 units remaining) - [ (Pair (Pair 34 17) 0) ] - - location: 9 (remaining gas: 1039994.482 units remaining) - [ (Pair 34 17) @parameter ] - - location: 10 (remaining gas: 1039994.472 units remaining) - [ 17 ] - - location: 11 (remaining gas: 1039994.457 units remaining) - [ {} - 17 ] - - location: 13 (remaining gas: 1039994.442 units remaining) - [ (Pair {} 17) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some \"NetXdQprcVkpaWU\")-Unit-(Some \".8420090f97.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some \"NetXdQprcVkpaWU\")-Unit-(Some \".8420090f97.out" deleted file mode 100644 index 45bab2656a8e..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some \"NetXdQprcVkpaWU\")-Unit-(Some \".8420090f97.out" +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some "NetXdQprcVkpaWU")-Unit-(Some "NetXdQprcVkpaWU")] - -storage - (Some "NetXdQprcVkpaWU") -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039992.257 units remaining) - [ (Pair Unit (Some "NetXdQprcVkpaWU")) ] - - location: 8 (remaining gas: 1039992.247 units remaining) - [ ] - - location: 9 (remaining gas: 1039992.232 units remaining) - [ "NetXdQprcVkpaWU" ] - - location: 10 (remaining gas: 1039992.217 units remaining) - [ (Some "NetXdQprcVkpaWU") ] - - location: 11 (remaining gas: 1039992.202 units remaining) - [ {} - (Some "NetXdQprcVkpaWU") ] - - location: 13 (remaining gas: 1039992.187 units remaining) - [ (Pair {} (Some "NetXdQprcVkpaWU")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" deleted file mode 100644 index b00b052d004f..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some "NetXdQprcVkpaWU")] - -storage - (Some "NetXdQprcVkpaWU") -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.807 units remaining) - [ (Pair Unit (Some "NetXdQprcVkpaWU")) ] - - location: 8 (remaining gas: 1039993.797 units remaining) - [ ] - - location: 9 (remaining gas: 1039993.782 units remaining) - [ "NetXdQprcVkpaWU" ] - - location: 10 (remaining gas: 1039993.767 units remaining) - [ (Some "NetXdQprcVkpaWU") ] - - location: 11 (remaining gas: 1039993.752 units remaining) - [ {} - (Some "NetXdQprcVkpaWU") ] - - location: 13 (remaining gas: 1039993.737 units remaining) - [ (Pair {} (Some "NetXdQprcVkpaWU")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some \"NetXdQprcVkpaWU\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some \"NetXdQprcVkpaWU\")].out" deleted file mode 100644 index cbff5cef3b8b..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some \"NetXdQprcVkpaWU\")].out" +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some "NetXdQprcVkpaWU")] - -storage - (Some "NetXdQprcVkpaWU") -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.957 units remaining) - [ (Pair Unit None) ] - - location: 8 (remaining gas: 1039993.947 units remaining) - [ ] - - location: 9 (remaining gas: 1039993.932 units remaining) - [ "NetXdQprcVkpaWU" ] - - location: 10 (remaining gas: 1039993.917 units remaining) - [ (Some "NetXdQprcVkpaWU") ] - - location: 11 (remaining gas: 1039993.902 units remaining) - [ {} - (Some "NetXdQprcVkpaWU") ] - - location: 13 (remaining gas: 1039993.887 units remaining) - [ (Pair {} (Some "NetXdQprcVkpaWU")) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out deleted file mode 100644 index f39b23d0a041..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out +++ /dev/null @@ -1,123 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039950.642 units remaining) - [ (Pair (Pair 1 4 2 Unit) Unit) ] - - location: 11 (remaining gas: 1039950.632 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 12 (remaining gas: 1039950.622 units remaining) - [ (Pair 1 4 2 Unit) @parameter - (Pair 1 4 2 Unit) @parameter ] - - location: 13 (remaining gas: 1039950.612 units remaining) - [ 1 - (Pair 1 4 2 Unit) @parameter ] - - location: 14 (remaining gas: 1039950.602 units remaining) - [ 1 - 1 - (Pair 1 4 2 Unit) @parameter ] - - location: 19 (remaining gas: 1039950.567 units remaining) - [ 0 - (Pair 1 4 2 Unit) @parameter ] - - location: 20 (remaining gas: 1039950.552 units remaining) - [ True - (Pair 1 4 2 Unit) @parameter ] - - location: 21 (remaining gas: 1039950.542 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 21 (remaining gas: 1039950.527 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 27 (remaining gas: 1039950.517 units remaining) - [ (Pair 1 4 2 Unit) @parameter - (Pair 1 4 2 Unit) @parameter ] - - location: 28 (remaining gas: 1039950.487 units remaining) - [ 1 - (Pair 1 4 2 Unit) @parameter ] - - location: 30 (remaining gas: 1039950.477 units remaining) - [ 1 - 1 - (Pair 1 4 2 Unit) @parameter ] - - location: 35 (remaining gas: 1039950.442 units remaining) - [ 0 - (Pair 1 4 2 Unit) @parameter ] - - location: 36 (remaining gas: 1039950.427 units remaining) - [ True - (Pair 1 4 2 Unit) @parameter ] - - location: 37 (remaining gas: 1039950.417 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 37 (remaining gas: 1039950.402 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 43 (remaining gas: 1039950.392 units remaining) - [ (Pair 1 4 2 Unit) @parameter - (Pair 1 4 2 Unit) @parameter ] - - location: 44 (remaining gas: 1039950.361 units remaining) - [ 4 - (Pair 1 4 2 Unit) @parameter ] - - location: 46 (remaining gas: 1039950.351 units remaining) - [ 4 - 4 - (Pair 1 4 2 Unit) @parameter ] - - location: 51 (remaining gas: 1039950.316 units remaining) - [ 0 - (Pair 1 4 2 Unit) @parameter ] - - location: 52 (remaining gas: 1039950.301 units remaining) - [ True - (Pair 1 4 2 Unit) @parameter ] - - location: 53 (remaining gas: 1039950.291 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 53 (remaining gas: 1039950.276 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 59 (remaining gas: 1039950.266 units remaining) - [ (Pair 1 4 2 Unit) @parameter - (Pair 1 4 2 Unit) @parameter ] - - location: 60 (remaining gas: 1039950.234 units remaining) - [ 2 - (Pair 1 4 2 Unit) @parameter ] - - location: 62 (remaining gas: 1039950.224 units remaining) - [ 2 - 2 - (Pair 1 4 2 Unit) @parameter ] - - location: 67 (remaining gas: 1039950.189 units remaining) - [ 0 - (Pair 1 4 2 Unit) @parameter ] - - location: 68 (remaining gas: 1039950.174 units remaining) - [ True - (Pair 1 4 2 Unit) @parameter ] - - location: 69 (remaining gas: 1039950.164 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 69 (remaining gas: 1039950.149 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 75 (remaining gas: 1039950.139 units remaining) - [ (Pair 1 4 2 Unit) @parameter - (Pair 1 4 2 Unit) @parameter ] - - location: 76 (remaining gas: 1039950.106 units remaining) - [ Unit - (Pair 1 4 2 Unit) @parameter ] - - location: 78 (remaining gas: 1039950.096 units remaining) - [ Unit - Unit - (Pair 1 4 2 Unit) @parameter ] - - location: 81 (remaining gas: 1039950.086 units remaining) - [ 0 - (Pair 1 4 2 Unit) @parameter ] - - location: 82 (remaining gas: 1039950.071 units remaining) - [ True - (Pair 1 4 2 Unit) @parameter ] - - location: 83 (remaining gas: 1039950.061 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 83 (remaining gas: 1039950.046 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 89 (remaining gas: 1039950.036 units remaining) - [ ] - - location: 90 (remaining gas: 1039950.026 units remaining) - [ Unit ] - - location: 91 (remaining gas: 1039950.011 units remaining) - [ {} - Unit ] - - location: 93 (remaining gas: 1039949.996 units remaining) - [ (Pair {} Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" deleted file mode 100644 index 1f92cbe932b2..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 "toto" 0x01))] - -storage - (Some (Pair 2 4 "toto" 0x01)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039985.116 units remaining) - [ (Pair (Pair 1 4 2 Unit) None) ] - - location: 16 (remaining gas: 1039985.106 units remaining) - [ (Pair 1 4 2 Unit) @parameter ] - - location: 17 (remaining gas: 1039985.096 units remaining) - [ 2 - (Pair 1 4 2 Unit) @parameter ] - - location: 20 (remaining gas: 1039985.055 units remaining) - [ (Pair 2 4 2 Unit) ] - - location: 22 (remaining gas: 1039985.045 units remaining) - [ "toto" - (Pair 2 4 2 Unit) ] - - location: 25 (remaining gas: 1039984.999 units remaining) - [ (Pair 2 4 "toto" Unit) ] - - location: 27 (remaining gas: 1039984.989 units remaining) - [ 0x01 - (Pair 2 4 "toto" Unit) ] - - location: 30 (remaining gas: 1039984.942 units remaining) - [ (Pair 2 4 "toto" 0x01) ] - - location: 32 (remaining gas: 1039984.927 units remaining) - [ (Some (Pair 2 4 "toto" 0x01)) ] - - location: 33 (remaining gas: 1039984.912 units remaining) - [ {} - (Some (Pair 2 4 "toto" 0x01)) ] - - location: 35 (remaining gas: 1039984.897 units remaining) - [ (Pair {} (Some (Pair 2 4 "toto" 0x01))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out deleted file mode 100644 index 57838a34ced9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out +++ /dev/null @@ -1,39 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)] - -storage - (Pair 2 12 8 Unit) -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039985.453 units remaining) - [ (Pair Unit 1 4 2 Unit) ] - - location: 11 (remaining gas: 1039985.443 units remaining) - [ (Pair 1 4 2 Unit) @storage ] - - location: 12 (remaining gas: 1039985.433 units remaining) - [ 2 - (Pair 1 4 2 Unit) @storage ] - - location: 15 (remaining gas: 1039985.392 units remaining) - [ (Pair 2 4 2 Unit) ] - - location: 17 (remaining gas: 1039985.382 units remaining) - [ 12 - (Pair 2 4 2 Unit) ] - - location: 20 (remaining gas: 1039985.339 units remaining) - [ (Pair 2 12 2 Unit) ] - - location: 22 (remaining gas: 1039985.329 units remaining) - [ 8 - (Pair 2 12 2 Unit) ] - - location: 25 (remaining gas: 1039985.283 units remaining) - [ (Pair 2 12 8 Unit) ] - - location: 27 (remaining gas: 1039985.273 units remaining) - [ Unit - (Pair 2 12 8 Unit) ] - - location: 28 (remaining gas: 1039985.226 units remaining) - [ (Pair 2 12 8 Unit) ] - - location: 30 (remaining gas: 1039985.211 units remaining) - [ {} - (Pair 2 12 8 Unit) ] - - location: 32 (remaining gas: 1039985.196 units remaining) - [ (Pair {} 2 12 8 Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out deleted file mode 100644 index f5c806d89367..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)] - -storage - (Pair 1 2 3) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.399 units remaining) - [ (Pair Unit 0 0 0) ] - - location: 10 (remaining gas: 1039990.389 units remaining) - [ ] - - location: 11 (remaining gas: 1039990.379 units remaining) - [ 3 ] - - location: 14 (remaining gas: 1039990.369 units remaining) - [ 2 - 3 ] - - location: 17 (remaining gas: 1039990.359 units remaining) - [ 1 - 2 - 3 ] - - location: 20 (remaining gas: 1039990.344 units remaining) - [ {} - 1 - 2 - 3 ] - - location: 22 (remaining gas: 1039990.330 units remaining) - [ (Pair {} 1 2 3) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit].out deleted file mode 100644 index 043836fe75be..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit].out +++ /dev/null @@ -1,398 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039782.668 units remaining) - [ (Pair Unit Unit) ] - - location: 7 (remaining gas: 1039782.658 units remaining) - [ ] - - location: 8 (remaining gas: 1039782.648 units remaining) - [ True ] - - location: 11 (remaining gas: 1039782.638 units remaining) - [ True - True ] - - location: 12 (remaining gas: 1039782.603 units remaining) - [ 0 ] - - location: 14 (remaining gas: 1039782.588 units remaining) - [ True ] - - location: 15 (remaining gas: 1039782.578 units remaining) - [ ] - - location: 15 (remaining gas: 1039782.563 units remaining) - [ ] - - location: 21 (remaining gas: 1039782.553 units remaining) - [ False ] - - location: 24 (remaining gas: 1039782.543 units remaining) - [ False - False ] - - location: 25 (remaining gas: 1039782.508 units remaining) - [ 0 ] - - location: 27 (remaining gas: 1039782.493 units remaining) - [ True ] - - location: 28 (remaining gas: 1039782.483 units remaining) - [ ] - - location: 28 (remaining gas: 1039782.468 units remaining) - [ ] - - location: 34 (remaining gas: 1039782.458 units remaining) - [ False ] - - location: 37 (remaining gas: 1039782.448 units remaining) - [ True - False ] - - location: 40 (remaining gas: 1039782.413 units remaining) - [ 1 ] - - location: 42 (remaining gas: 1039782.398 units remaining) - [ True ] - - location: 43 (remaining gas: 1039782.388 units remaining) - [ ] - - location: 43 (remaining gas: 1039782.373 units remaining) - [ ] - - location: 49 (remaining gas: 1039782.363 units remaining) - [ True ] - - location: 52 (remaining gas: 1039782.353 units remaining) - [ False - True ] - - location: 55 (remaining gas: 1039782.318 units remaining) - [ -1 ] - - location: 57 (remaining gas: 1039782.303 units remaining) - [ True ] - - location: 58 (remaining gas: 1039782.293 units remaining) - [ ] - - location: 58 (remaining gas: 1039782.278 units remaining) - [ ] - - location: 64 (remaining gas: 1039782.268 units remaining) - [ 0xaabbcc ] - - location: 67 (remaining gas: 1039782.258 units remaining) - [ 0xaabbcc - 0xaabbcc ] - - location: 68 (remaining gas: 1039782.223 units remaining) - [ 0 ] - - location: 70 (remaining gas: 1039782.208 units remaining) - [ True ] - - location: 71 (remaining gas: 1039782.198 units remaining) - [ ] - - location: 71 (remaining gas: 1039782.183 units remaining) - [ ] - - location: 77 (remaining gas: 1039782.173 units remaining) - [ 0x ] - - location: 80 (remaining gas: 1039782.163 units remaining) - [ 0x - 0x ] - - location: 83 (remaining gas: 1039782.128 units remaining) - [ 0 ] - - location: 85 (remaining gas: 1039782.113 units remaining) - [ True ] - - location: 86 (remaining gas: 1039782.103 units remaining) - [ ] - - location: 86 (remaining gas: 1039782.088 units remaining) - [ ] - - location: 92 (remaining gas: 1039782.078 units remaining) - [ 0x ] - - location: 95 (remaining gas: 1039782.068 units remaining) - [ 0x01 - 0x ] - - location: 98 (remaining gas: 1039782.033 units remaining) - [ 1 ] - - location: 100 (remaining gas: 1039782.018 units remaining) - [ True ] - - location: 101 (remaining gas: 1039782.008 units remaining) - [ ] - - location: 101 (remaining gas: 1039781.993 units remaining) - [ ] - - location: 107 (remaining gas: 1039781.983 units remaining) - [ 0x01 ] - - location: 110 (remaining gas: 1039781.973 units remaining) - [ 0x02 - 0x01 ] - - location: 113 (remaining gas: 1039781.938 units remaining) - [ 1 ] - - location: 115 (remaining gas: 1039781.923 units remaining) - [ True ] - - location: 116 (remaining gas: 1039781.913 units remaining) - [ ] - - location: 116 (remaining gas: 1039781.898 units remaining) - [ ] - - location: 122 (remaining gas: 1039781.888 units remaining) - [ 0x02 ] - - location: 125 (remaining gas: 1039781.878 units remaining) - [ 0x01 - 0x02 ] - - location: 128 (remaining gas: 1039781.843 units remaining) - [ -1 ] - - location: 130 (remaining gas: 1039781.828 units remaining) - [ True ] - - location: 131 (remaining gas: 1039781.818 units remaining) - [ ] - - location: 131 (remaining gas: 1039781.803 units remaining) - [ ] - - location: 137 (remaining gas: 1039781.793 units remaining) - [ 1 ] - - location: 140 (remaining gas: 1039781.783 units remaining) - [ 1 - 1 ] - - location: 141 (remaining gas: 1039781.748 units remaining) - [ 0 ] - - location: 143 (remaining gas: 1039781.733 units remaining) - [ True ] - - location: 144 (remaining gas: 1039781.723 units remaining) - [ ] - - location: 144 (remaining gas: 1039781.708 units remaining) - [ ] - - location: 150 (remaining gas: 1039781.698 units remaining) - [ 10 ] - - location: 153 (remaining gas: 1039781.688 units remaining) - [ 5 - 10 ] - - location: 156 (remaining gas: 1039781.653 units remaining) - [ -1 ] - - location: 158 (remaining gas: 1039781.638 units remaining) - [ True ] - - location: 159 (remaining gas: 1039781.628 units remaining) - [ ] - - location: 159 (remaining gas: 1039781.613 units remaining) - [ ] - - location: 165 (remaining gas: 1039781.603 units remaining) - [ -4 ] - - location: 168 (remaining gas: 1039781.593 units remaining) - [ 1923 - -4 ] - - location: 171 (remaining gas: 1039781.558 units remaining) - [ 1 ] - - location: 173 (remaining gas: 1039781.543 units remaining) - [ True ] - - location: 174 (remaining gas: 1039781.533 units remaining) - [ ] - - location: 174 (remaining gas: 1039781.518 units remaining) - [ ] - - location: 180 (remaining gas: 1039781.508 units remaining) - [ 1 ] - - location: 183 (remaining gas: 1039781.498 units remaining) - [ 1 - 1 ] - - location: 184 (remaining gas: 1039781.463 units remaining) - [ 0 ] - - location: 186 (remaining gas: 1039781.448 units remaining) - [ True ] - - location: 187 (remaining gas: 1039781.438 units remaining) - [ ] - - location: 187 (remaining gas: 1039781.423 units remaining) - [ ] - - location: 193 (remaining gas: 1039781.413 units remaining) - [ 10 ] - - location: 196 (remaining gas: 1039781.403 units remaining) - [ 5 - 10 ] - - location: 199 (remaining gas: 1039781.368 units remaining) - [ -1 ] - - location: 201 (remaining gas: 1039781.353 units remaining) - [ True ] - - location: 202 (remaining gas: 1039781.343 units remaining) - [ ] - - location: 202 (remaining gas: 1039781.328 units remaining) - [ ] - - location: 208 (remaining gas: 1039781.318 units remaining) - [ 4 ] - - location: 211 (remaining gas: 1039781.308 units remaining) - [ 1923 - 4 ] - - location: 214 (remaining gas: 1039781.273 units remaining) - [ 1 ] - - location: 216 (remaining gas: 1039781.258 units remaining) - [ True ] - - location: 217 (remaining gas: 1039781.248 units remaining) - [ ] - - location: 217 (remaining gas: 1039781.233 units remaining) - [ ] - - location: 223 (remaining gas: 1039781.223 units remaining) - [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] - - location: 226 (remaining gas: 1039781.213 units remaining) - [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" - "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] - - location: 227 (remaining gas: 1039781.177 units remaining) - [ 0 ] - - location: 229 (remaining gas: 1039781.162 units remaining) - [ True ] - - location: 230 (remaining gas: 1039781.152 units remaining) - [ ] - - location: 230 (remaining gas: 1039781.137 units remaining) - [ ] - - location: 236 (remaining gas: 1039781.127 units remaining) - [ "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" ] - - location: 239 (remaining gas: 1039781.117 units remaining) - [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" - "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" ] - - location: 242 (remaining gas: 1039781.081 units remaining) - [ -1 ] - - location: 244 (remaining gas: 1039781.066 units remaining) - [ True ] - - location: 245 (remaining gas: 1039781.056 units remaining) - [ ] - - location: 245 (remaining gas: 1039781.041 units remaining) - [ ] - - location: 251 (remaining gas: 1039781.031 units remaining) - [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] - - location: 254 (remaining gas: 1039781.021 units remaining) - [ "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" - "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] - - location: 257 (remaining gas: 1039780.985 units remaining) - [ 1 ] - - location: 259 (remaining gas: 1039780.970 units remaining) - [ True ] - - location: 260 (remaining gas: 1039780.960 units remaining) - [ ] - - location: 260 (remaining gas: 1039780.945 units remaining) - [ ] - - location: 266 (remaining gas: 1039780.935 units remaining) - [ 1 ] - - location: 269 (remaining gas: 1039780.925 units remaining) - [ 1 - 1 ] - - location: 270 (remaining gas: 1039780.890 units remaining) - [ 0 ] - - location: 272 (remaining gas: 1039780.875 units remaining) - [ True ] - - location: 273 (remaining gas: 1039780.865 units remaining) - [ ] - - location: 273 (remaining gas: 1039780.850 units remaining) - [ ] - - location: 279 (remaining gas: 1039780.840 units remaining) - [ 10 ] - - location: 282 (remaining gas: 1039780.830 units remaining) - [ 5 - 10 ] - - location: 285 (remaining gas: 1039780.795 units remaining) - [ -1 ] - - location: 287 (remaining gas: 1039780.780 units remaining) - [ True ] - - location: 288 (remaining gas: 1039780.770 units remaining) - [ ] - - location: 288 (remaining gas: 1039780.755 units remaining) - [ ] - - location: 294 (remaining gas: 1039780.745 units remaining) - [ 4 ] - - location: 297 (remaining gas: 1039780.735 units remaining) - [ 1923 - 4 ] - - location: 300 (remaining gas: 1039780.700 units remaining) - [ 1 ] - - location: 302 (remaining gas: 1039780.685 units remaining) - [ True ] - - location: 303 (remaining gas: 1039780.675 units remaining) - [ ] - - location: 303 (remaining gas: 1039780.660 units remaining) - [ ] - - location: 309 (remaining gas: 1039780.650 units remaining) - [ "AABBCC" ] - - location: 312 (remaining gas: 1039780.640 units remaining) - [ "AABBCC" - "AABBCC" ] - - location: 313 (remaining gas: 1039780.605 units remaining) - [ 0 ] - - location: 315 (remaining gas: 1039780.590 units remaining) - [ True ] - - location: 316 (remaining gas: 1039780.580 units remaining) - [ ] - - location: 316 (remaining gas: 1039780.565 units remaining) - [ ] - - location: 322 (remaining gas: 1039780.555 units remaining) - [ "" ] - - location: 325 (remaining gas: 1039780.545 units remaining) - [ "" - "" ] - - location: 328 (remaining gas: 1039780.510 units remaining) - [ 0 ] - - location: 330 (remaining gas: 1039780.495 units remaining) - [ True ] - - location: 331 (remaining gas: 1039780.485 units remaining) - [ ] - - location: 331 (remaining gas: 1039780.470 units remaining) - [ ] - - location: 337 (remaining gas: 1039780.460 units remaining) - [ "" ] - - location: 340 (remaining gas: 1039780.450 units remaining) - [ "a" - "" ] - - location: 343 (remaining gas: 1039780.415 units remaining) - [ 1 ] - - location: 345 (remaining gas: 1039780.400 units remaining) - [ True ] - - location: 346 (remaining gas: 1039780.390 units remaining) - [ ] - - location: 346 (remaining gas: 1039780.375 units remaining) - [ ] - - location: 352 (remaining gas: 1039780.365 units remaining) - [ "a" ] - - location: 355 (remaining gas: 1039780.355 units remaining) - [ "b" - "a" ] - - location: 358 (remaining gas: 1039780.320 units remaining) - [ 1 ] - - location: 360 (remaining gas: 1039780.305 units remaining) - [ True ] - - location: 361 (remaining gas: 1039780.295 units remaining) - [ ] - - location: 361 (remaining gas: 1039780.280 units remaining) - [ ] - - location: 367 (remaining gas: 1039780.270 units remaining) - [ "b" ] - - location: 370 (remaining gas: 1039780.260 units remaining) - [ "a" - "b" ] - - location: 373 (remaining gas: 1039780.225 units remaining) - [ -1 ] - - location: 375 (remaining gas: 1039780.210 units remaining) - [ True ] - - location: 376 (remaining gas: 1039780.200 units remaining) - [ ] - - location: 376 (remaining gas: 1039780.185 units remaining) - [ ] - - location: 382 (remaining gas: 1039780.175 units remaining) - [ "2019-09-16T08:38:05Z" ] - - location: 385 (remaining gas: 1039780.165 units remaining) - [ "2019-09-16T08:38:05Z" - "2019-09-16T08:38:05Z" ] - - location: 386 (remaining gas: 1039780.130 units remaining) - [ 0 ] - - location: 388 (remaining gas: 1039780.115 units remaining) - [ True ] - - location: 389 (remaining gas: 1039780.105 units remaining) - [ ] - - location: 389 (remaining gas: 1039780.090 units remaining) - [ ] - - location: 395 (remaining gas: 1039780.080 units remaining) - [ "2017-09-16T08:38:04Z" ] - - location: 398 (remaining gas: 1039780.070 units remaining) - [ "2019-09-16T08:38:05Z" - "2017-09-16T08:38:04Z" ] - - location: 401 (remaining gas: 1039780.035 units remaining) - [ 1 ] - - location: 403 (remaining gas: 1039780.020 units remaining) - [ True ] - - location: 404 (remaining gas: 1039780.010 units remaining) - [ ] - - location: 404 (remaining gas: 1039779.995 units remaining) - [ ] - - location: 410 (remaining gas: 1039779.985 units remaining) - [ "2019-09-16T08:38:05Z" ] - - location: 413 (remaining gas: 1039779.975 units remaining) - [ "2019-09-16T08:38:04Z" - "2019-09-16T08:38:05Z" ] - - location: 416 (remaining gas: 1039779.940 units remaining) - [ -1 ] - - location: 418 (remaining gas: 1039779.925 units remaining) - [ True ] - - location: 419 (remaining gas: 1039779.915 units remaining) - [ ] - - location: 419 (remaining gas: 1039779.900 units remaining) - [ ] - - location: 425 (remaining gas: 1039779.890 units remaining) - [ Unit ] - - location: 426 (remaining gas: 1039779.875 units remaining) - [ {} - Unit ] - - location: 428 (remaining gas: 1039779.860 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out deleted file mode 100644 index 723f99e4e525..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out +++ /dev/null @@ -1,350 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ { False ; False ; False ; True ; True } ;\n { False ; False ; True ; True ; True } ;\n { True ; True ; False ; False ; False } ;\n { True ; True ; True ; False ; False } ;\n { True ; True ; False ; True ; True } ;\n { False ; False ; True ; False ; False } }] - -storage - { { False ; False ; False ; True ; True } ; - { False ; False ; True ; True ; True } ; - { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039962.637 units remaining) - [ (Pair { -9999999 ; -1 ; 0 ; 1 ; 9999999 } {}) ] - - location: 10 (remaining gas: 1039962.627 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 11 (remaining gas: 1039962.612 units remaining) - [ {} - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 14 (remaining gas: 1039962.597 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 16 (remaining gas: 1039962.587 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 17 (remaining gas: 1039962.587 units remaining) - [ -9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 19 (remaining gas: 1039962.572 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 17 (remaining gas: 1039962.557 units remaining) - [ -1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 19 (remaining gas: 1039962.542 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 17 (remaining gas: 1039962.527 units remaining) - [ 0 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 19 (remaining gas: 1039962.512 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 17 (remaining gas: 1039962.497 units remaining) - [ 1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 19 (remaining gas: 1039962.482 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 17 (remaining gas: 1039962.467 units remaining) - [ 9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 19 (remaining gas: 1039962.452 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 17 (remaining gas: 1039962.437 units remaining) - [ { False ; False ; True ; False ; False } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 14 (remaining gas: 1039962.407 units remaining) - [ {} - { False ; False ; True ; False ; False } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 20 (remaining gas: 1039962.397 units remaining) - [ { False ; False ; True ; False ; False } - {} - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 21 (remaining gas: 1039962.382 units remaining) - [ { { False ; False ; True ; False ; False } } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 22 (remaining gas: 1039962.367 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 24 (remaining gas: 1039962.357 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 25 (remaining gas: 1039962.357 units remaining) - [ -9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 27 (remaining gas: 1039962.342 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 25 (remaining gas: 1039962.327 units remaining) - [ -1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 27 (remaining gas: 1039962.312 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 25 (remaining gas: 1039962.297 units remaining) - [ 0 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 27 (remaining gas: 1039962.282 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 25 (remaining gas: 1039962.267 units remaining) - [ 1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 27 (remaining gas: 1039962.252 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 25 (remaining gas: 1039962.237 units remaining) - [ 9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 27 (remaining gas: 1039962.222 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 25 (remaining gas: 1039962.207 units remaining) - [ { True ; True ; False ; True ; True } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 22 (remaining gas: 1039962.177 units remaining) - [ { { False ; False ; True ; False ; False } } - { True ; True ; False ; True ; True } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 28 (remaining gas: 1039962.167 units remaining) - [ { True ; True ; False ; True ; True } - { { False ; False ; True ; False ; False } } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 29 (remaining gas: 1039962.152 units remaining) - [ { { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 30 (remaining gas: 1039962.137 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 32 (remaining gas: 1039962.127 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 33 (remaining gas: 1039962.127 units remaining) - [ -9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 35 (remaining gas: 1039962.112 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 33 (remaining gas: 1039962.097 units remaining) - [ -1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 35 (remaining gas: 1039962.082 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 33 (remaining gas: 1039962.067 units remaining) - [ 0 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 35 (remaining gas: 1039962.052 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 33 (remaining gas: 1039962.037 units remaining) - [ 1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 35 (remaining gas: 1039962.022 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 33 (remaining gas: 1039962.007 units remaining) - [ 9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 35 (remaining gas: 1039961.992 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 33 (remaining gas: 1039961.977 units remaining) - [ { True ; True ; True ; False ; False } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 30 (remaining gas: 1039961.947 units remaining) - [ { { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { True ; True ; True ; False ; False } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 36 (remaining gas: 1039961.937 units remaining) - [ { True ; True ; True ; False ; False } - { { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 37 (remaining gas: 1039961.922 units remaining) - [ { { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 38 (remaining gas: 1039961.907 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 40 (remaining gas: 1039961.897 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 41 (remaining gas: 1039961.897 units remaining) - [ -9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 43 (remaining gas: 1039961.882 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 41 (remaining gas: 1039961.867 units remaining) - [ -1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 43 (remaining gas: 1039961.852 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 41 (remaining gas: 1039961.837 units remaining) - [ 0 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 43 (remaining gas: 1039961.822 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 41 (remaining gas: 1039961.807 units remaining) - [ 1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 43 (remaining gas: 1039961.792 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 41 (remaining gas: 1039961.777 units remaining) - [ 9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 43 (remaining gas: 1039961.762 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 41 (remaining gas: 1039961.747 units remaining) - [ { True ; True ; False ; False ; False } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 38 (remaining gas: 1039961.717 units remaining) - [ { { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { True ; True ; False ; False ; False } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 44 (remaining gas: 1039961.707 units remaining) - [ { True ; True ; False ; False ; False } - { { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 45 (remaining gas: 1039961.692 units remaining) - [ { { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 46 (remaining gas: 1039961.677 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 48 (remaining gas: 1039961.667 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 49 (remaining gas: 1039961.667 units remaining) - [ -9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 51 (remaining gas: 1039961.652 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 49 (remaining gas: 1039961.637 units remaining) - [ -1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 51 (remaining gas: 1039961.622 units remaining) - [ False - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 49 (remaining gas: 1039961.607 units remaining) - [ 0 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 51 (remaining gas: 1039961.592 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 49 (remaining gas: 1039961.577 units remaining) - [ 1 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 51 (remaining gas: 1039961.562 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 49 (remaining gas: 1039961.547 units remaining) - [ 9999999 @parameter.elt - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 51 (remaining gas: 1039961.532 units remaining) - [ True - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 49 (remaining gas: 1039961.517 units remaining) - [ { False ; False ; True ; True ; True } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 46 (remaining gas: 1039961.487 units remaining) - [ { { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { False ; False ; True ; True ; True } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 52 (remaining gas: 1039961.477 units remaining) - [ { False ; False ; True ; True ; True } - { { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 53 (remaining gas: 1039961.462 units remaining) - [ { { False ; False ; True ; True ; True } ; - { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 54 (remaining gas: 1039961.447 units remaining) - [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] - - location: 56 (remaining gas: 1039961.447 units remaining) - [ -9999999 @parameter.elt ] - - location: 58 (remaining gas: 1039961.432 units remaining) - [ False ] - - location: 56 (remaining gas: 1039961.417 units remaining) - [ -1 @parameter.elt ] - - location: 58 (remaining gas: 1039961.402 units remaining) - [ False ] - - location: 56 (remaining gas: 1039961.387 units remaining) - [ 0 @parameter.elt ] - - location: 58 (remaining gas: 1039961.372 units remaining) - [ False ] - - location: 56 (remaining gas: 1039961.357 units remaining) - [ 1 @parameter.elt ] - - location: 58 (remaining gas: 1039961.342 units remaining) - [ True ] - - location: 56 (remaining gas: 1039961.327 units remaining) - [ 9999999 @parameter.elt ] - - location: 58 (remaining gas: 1039961.312 units remaining) - [ True ] - - location: 56 (remaining gas: 1039961.297 units remaining) - [ { False ; False ; False ; True ; True } ] - - location: 54 (remaining gas: 1039961.267 units remaining) - [ { { False ; False ; True ; True ; True } ; - { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } - { False ; False ; False ; True ; True } ] - - location: 59 (remaining gas: 1039961.257 units remaining) - [ { False ; False ; False ; True ; True } - { { False ; False ; True ; True ; True } ; - { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } ] - - location: 60 (remaining gas: 1039961.242 units remaining) - [ { { False ; False ; False ; True ; True } ; - { False ; False ; True ; True ; True } ; - { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } ] - - location: 61 (remaining gas: 1039961.227 units remaining) - [ {} - { { False ; False ; False ; True ; True } ; - { False ; False ; True ; True ; True } ; - { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } } ] - - location: 63 (remaining gas: 1039961.212 units remaining) - [ (Pair {} - { { False ; False ; False ; True ; True } ; - { False ; False ; True ; True ; True } ; - { True ; True ; False ; False ; False } ; - { True ; True ; True ; False ; False } ; - { True ; True ; False ; True ; True } ; - { False ; False ; True ; False ; False } }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"World!\" }-{ \"Hello World!\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"World!\" }-{ \"Hello World!\" }].out" deleted file mode 100644 index 0316f3a9f753..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"World!\" }-{ \"Hello World!\" }].out" +++ /dev/null @@ -1,28 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ "World!" }-{ "Hello World!" }] - -storage - { "Hello World!" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.305 units remaining) - [ (Pair { "World!" } {}) ] - - location: 9 (remaining gas: 1039992.295 units remaining) - [ { "World!" } @parameter ] - - location: 10 (remaining gas: 1039992.295 units remaining) - [ "World!" @parameter.elt ] - - location: 12 (remaining gas: 1039992.285 units remaining) - [ "Hello " @hello - "World!" @parameter.elt ] - - location: 15 (remaining gas: 1039992.220 units remaining) - [ "Hello World!" ] - - location: 10 (remaining gas: 1039992.205 units remaining) - [ { "Hello World!" } ] - - location: 16 (remaining gas: 1039992.190 units remaining) - [ {} - { "Hello World!" } ] - - location: 18 (remaining gas: 1039992.175 units remaining) - [ (Pair {} { "Hello World!" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"test1\" ; \"test2\" }-{ \"Hello test1.c27e8c3ee6.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"test1\" ; \"test2\" }-{ \"Hello test1.c27e8c3ee6.out" deleted file mode 100644 index 138cb94e8d89..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"test1\" ; \"test2\" }-{ \"Hello test1.c27e8c3ee6.out" +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ "test1" ; "test2" }-{ "Hello test1" ; "Hello test2" }] - -storage - { "Hello test1" ; "Hello test2" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.151 units remaining) - [ (Pair { "test1" ; "test2" } {}) ] - - location: 9 (remaining gas: 1039992.141 units remaining) - [ { "test1" ; "test2" } @parameter ] - - location: 10 (remaining gas: 1039992.141 units remaining) - [ "test1" @parameter.elt ] - - location: 12 (remaining gas: 1039992.131 units remaining) - [ "Hello " @hello - "test1" @parameter.elt ] - - location: 15 (remaining gas: 1039992.066 units remaining) - [ "Hello test1" ] - - location: 10 (remaining gas: 1039992.051 units remaining) - [ "test2" @parameter.elt ] - - location: 12 (remaining gas: 1039992.041 units remaining) - [ "Hello " @hello - "test2" @parameter.elt ] - - location: 15 (remaining gas: 1039991.976 units remaining) - [ "Hello test2" ] - - location: 10 (remaining gas: 1039991.961 units remaining) - [ { "Hello test1" ; "Hello test2" } ] - - location: 16 (remaining gas: 1039991.946 units remaining) - [ {} - { "Hello test1" ; "Hello test2" } ] - - location: 18 (remaining gas: 1039991.931 units remaining) - [ (Pair {} { "Hello test1" ; "Hello test2" }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}].out deleted file mode 100644 index f0e2661da9da..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.479 units remaining) - [ (Pair {} {}) ] - - location: 9 (remaining gas: 1039992.469 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039992.469 units remaining) - [ {} ] - - location: 16 (remaining gas: 1039992.454 units remaining) - [ {} - {} ] - - location: 18 (remaining gas: 1039992.439 units remaining) - [ (Pair {} {}) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out deleted file mode 100644 index 9ff4f50d3817..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }] - -storage - { 0xffab ; 0xffcd } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.398 units remaining) - [ (Pair { 0xab ; 0xcd } {}) ] - - location: 9 (remaining gas: 1039992.388 units remaining) - [ { 0xab ; 0xcd } @parameter ] - - location: 10 (remaining gas: 1039992.388 units remaining) - [ 0xab @parameter.elt ] - - location: 12 (remaining gas: 1039992.378 units remaining) - [ 0xff - 0xab @parameter.elt ] - - location: 15 (remaining gas: 1039992.313 units remaining) - [ 0xffab ] - - location: 10 (remaining gas: 1039992.298 units remaining) - [ 0xcd @parameter.elt ] - - location: 12 (remaining gas: 1039992.288 units remaining) - [ 0xff - 0xcd @parameter.elt ] - - location: 15 (remaining gas: 1039992.223 units remaining) - [ 0xffcd ] - - location: 10 (remaining gas: 1039992.208 units remaining) - [ { 0xffab ; 0xffcd } ] - - location: 16 (remaining gas: 1039992.193 units remaining) - [ {} - { 0xffab ; 0xffcd } ] - - location: 18 (remaining gas: 1039992.178 units remaining) - [ (Pair {} { 0xffab ; 0xffcd }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out deleted file mode 100644 index cc46d28d82c4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out +++ /dev/null @@ -1,28 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }] - -storage - { 0xffcd } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.498 units remaining) - [ (Pair { 0xcd } {}) ] - - location: 9 (remaining gas: 1039992.488 units remaining) - [ { 0xcd } @parameter ] - - location: 10 (remaining gas: 1039992.488 units remaining) - [ 0xcd @parameter.elt ] - - location: 12 (remaining gas: 1039992.478 units remaining) - [ 0xff - 0xcd @parameter.elt ] - - location: 15 (remaining gas: 1039992.413 units remaining) - [ 0xffcd ] - - location: 10 (remaining gas: 1039992.398 units remaining) - [ { 0xffcd } ] - - location: 16 (remaining gas: 1039992.383 units remaining) - [ {} - { 0xffcd } ] - - location: 18 (remaining gas: 1039992.368 units remaining) - [ (Pair {} { 0xffcd }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}].out deleted file mode 100644 index 5ce91f07ecdc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.598 units remaining) - [ (Pair {} {}) ] - - location: 9 (remaining gas: 1039992.588 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039992.588 units remaining) - [ {} ] - - location: 16 (remaining gas: 1039992.573 units remaining) - [ {} - {} ] - - location: 18 (remaining gas: 1039992.558 units remaining) - [ (Pair {} {}) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"Hello\" ; \" \" ; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"Hello\" ; \" \" ; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" deleted file mode 100644 index f17bf0e00dd4..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"Hello\" ; \" \" ; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" +++ /dev/null @@ -1,119 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_list.tz-""-{ "Hello" ; " " ; "World" ; "!" }-"Hello World!"] - -storage - "Hello World!" -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039987.037 units remaining) - [ (Pair { "Hello" ; " " ; "World" ; "!" } "") ] - - location: 8 (remaining gas: 1039987.027 units remaining) - [ { "Hello" ; " " ; "World" ; "!" } @parameter ] - - location: 9 (remaining gas: 1039987.017 units remaining) - [ "" - { "Hello" ; " " ; "World" ; "!" } @parameter ] - - location: 12 (remaining gas: 1039987.007 units remaining) - [ { "Hello" ; " " ; "World" ; "!" } @parameter - "" ] - - location: 13 (remaining gas: 1039987.007 units remaining) - [ "Hello" @parameter.elt - "" ] - - location: 15 (remaining gas: 1039986.997 units remaining) - [ "" - "Hello" @parameter.elt ] - - location: 16 (remaining gas: 1039986.982 units remaining) - [ "Hello" @parameter.elt ] - - location: 18 (remaining gas: 1039986.967 units remaining) - [ {} - "Hello" @parameter.elt ] - - location: 20 (remaining gas: 1039986.957 units remaining) - [ "Hello" @parameter.elt - {} ] - - location: 21 (remaining gas: 1039986.942 units remaining) - [ { "Hello" } ] - - location: 16 (remaining gas: 1039986.912 units remaining) - [ "" - { "Hello" } ] - - location: 22 (remaining gas: 1039986.897 units remaining) - [ { "" ; "Hello" } ] - - location: 23 (remaining gas: 1039986.777 units remaining) - [ "Hello" ] - - location: 13 (remaining gas: 1039986.762 units remaining) - [ " " @parameter.elt - "Hello" ] - - location: 15 (remaining gas: 1039986.752 units remaining) - [ "Hello" - " " @parameter.elt ] - - location: 16 (remaining gas: 1039986.737 units remaining) - [ " " @parameter.elt ] - - location: 18 (remaining gas: 1039986.722 units remaining) - [ {} - " " @parameter.elt ] - - location: 20 (remaining gas: 1039986.712 units remaining) - [ " " @parameter.elt - {} ] - - location: 21 (remaining gas: 1039986.697 units remaining) - [ { " " } ] - - location: 16 (remaining gas: 1039986.667 units remaining) - [ "Hello" - { " " } ] - - location: 22 (remaining gas: 1039986.652 units remaining) - [ { "Hello" ; " " } ] - - location: 23 (remaining gas: 1039986.532 units remaining) - [ "Hello " ] - - location: 13 (remaining gas: 1039986.517 units remaining) - [ "World" @parameter.elt - "Hello " ] - - location: 15 (remaining gas: 1039986.507 units remaining) - [ "Hello " - "World" @parameter.elt ] - - location: 16 (remaining gas: 1039986.492 units remaining) - [ "World" @parameter.elt ] - - location: 18 (remaining gas: 1039986.477 units remaining) - [ {} - "World" @parameter.elt ] - - location: 20 (remaining gas: 1039986.467 units remaining) - [ "World" @parameter.elt - {} ] - - location: 21 (remaining gas: 1039986.452 units remaining) - [ { "World" } ] - - location: 16 (remaining gas: 1039986.422 units remaining) - [ "Hello " - { "World" } ] - - location: 22 (remaining gas: 1039986.407 units remaining) - [ { "Hello " ; "World" } ] - - location: 23 (remaining gas: 1039986.286 units remaining) - [ "Hello World" ] - - location: 13 (remaining gas: 1039986.271 units remaining) - [ "!" @parameter.elt - "Hello World" ] - - location: 15 (remaining gas: 1039986.261 units remaining) - [ "Hello World" - "!" @parameter.elt ] - - location: 16 (remaining gas: 1039986.246 units remaining) - [ "!" @parameter.elt ] - - location: 18 (remaining gas: 1039986.231 units remaining) - [ {} - "!" @parameter.elt ] - - location: 20 (remaining gas: 1039986.221 units remaining) - [ "!" @parameter.elt - {} ] - - location: 21 (remaining gas: 1039986.206 units remaining) - [ { "!" } ] - - location: 16 (remaining gas: 1039986.176 units remaining) - [ "Hello World" - { "!" } ] - - location: 22 (remaining gas: 1039986.161 units remaining) - [ { "Hello World" ; "!" } ] - - location: 23 (remaining gas: 1039986.040 units remaining) - [ "Hello World!" ] - - location: 13 (remaining gas: 1039986.025 units remaining) - [ "Hello World!" ] - - location: 24 (remaining gas: 1039986.010 units remaining) - [ {} - "Hello World!" ] - - location: 26 (remaining gas: 1039985.995 units remaining) - [ (Pair {} "Hello World!") ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" deleted file mode 100644 index a13a5bb067c8..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" +++ /dev/null @@ -1,96 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_list.tz-""-{ "a" ; "b" ; "c" }-"abc"] - -storage - "abc" -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039987.241 units remaining) - [ (Pair { "a" ; "b" ; "c" } "") ] - - location: 8 (remaining gas: 1039987.231 units remaining) - [ { "a" ; "b" ; "c" } @parameter ] - - location: 9 (remaining gas: 1039987.221 units remaining) - [ "" - { "a" ; "b" ; "c" } @parameter ] - - location: 12 (remaining gas: 1039987.211 units remaining) - [ { "a" ; "b" ; "c" } @parameter - "" ] - - location: 13 (remaining gas: 1039987.211 units remaining) - [ "a" @parameter.elt - "" ] - - location: 15 (remaining gas: 1039987.201 units remaining) - [ "" - "a" @parameter.elt ] - - location: 16 (remaining gas: 1039987.186 units remaining) - [ "a" @parameter.elt ] - - location: 18 (remaining gas: 1039987.171 units remaining) - [ {} - "a" @parameter.elt ] - - location: 20 (remaining gas: 1039987.161 units remaining) - [ "a" @parameter.elt - {} ] - - location: 21 (remaining gas: 1039987.146 units remaining) - [ { "a" } ] - - location: 16 (remaining gas: 1039987.116 units remaining) - [ "" - { "a" } ] - - location: 22 (remaining gas: 1039987.101 units remaining) - [ { "" ; "a" } ] - - location: 23 (remaining gas: 1039986.981 units remaining) - [ "a" ] - - location: 13 (remaining gas: 1039986.966 units remaining) - [ "b" @parameter.elt - "a" ] - - location: 15 (remaining gas: 1039986.956 units remaining) - [ "a" - "b" @parameter.elt ] - - location: 16 (remaining gas: 1039986.941 units remaining) - [ "b" @parameter.elt ] - - location: 18 (remaining gas: 1039986.926 units remaining) - [ {} - "b" @parameter.elt ] - - location: 20 (remaining gas: 1039986.916 units remaining) - [ "b" @parameter.elt - {} ] - - location: 21 (remaining gas: 1039986.901 units remaining) - [ { "b" } ] - - location: 16 (remaining gas: 1039986.871 units remaining) - [ "a" - { "b" } ] - - location: 22 (remaining gas: 1039986.856 units remaining) - [ { "a" ; "b" } ] - - location: 23 (remaining gas: 1039986.736 units remaining) - [ "ab" ] - - location: 13 (remaining gas: 1039986.721 units remaining) - [ "c" @parameter.elt - "ab" ] - - location: 15 (remaining gas: 1039986.711 units remaining) - [ "ab" - "c" @parameter.elt ] - - location: 16 (remaining gas: 1039986.696 units remaining) - [ "c" @parameter.elt ] - - location: 18 (remaining gas: 1039986.681 units remaining) - [ {} - "c" @parameter.elt ] - - location: 20 (remaining gas: 1039986.671 units remaining) - [ "c" @parameter.elt - {} ] - - location: 21 (remaining gas: 1039986.656 units remaining) - [ { "c" } ] - - location: 16 (remaining gas: 1039986.626 units remaining) - [ "ab" - { "c" } ] - - location: 22 (remaining gas: 1039986.611 units remaining) - [ { "ab" ; "c" } ] - - location: 23 (remaining gas: 1039986.491 units remaining) - [ "abc" ] - - location: 13 (remaining gas: 1039986.476 units remaining) - [ "abc" ] - - location: 24 (remaining gas: 1039986.461 units remaining) - [ {} - "abc" ] - - location: 26 (remaining gas: 1039986.446 units remaining) - [ (Pair {} "abc") ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{}-\"\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{}-\"\"].out" deleted file mode 100644 index 282dd7c01375..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{}-\"\"].out" +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_list.tz-""-{}-""] - -storage - "" -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039987.613 units remaining) - [ (Pair {} "") ] - - location: 8 (remaining gas: 1039987.603 units remaining) - [ {} @parameter ] - - location: 9 (remaining gas: 1039987.593 units remaining) - [ "" - {} @parameter ] - - location: 12 (remaining gas: 1039987.583 units remaining) - [ {} @parameter - "" ] - - location: 13 (remaining gas: 1039987.583 units remaining) - [ "" ] - - location: 24 (remaining gas: 1039987.568 units remaining) - [ {} - "" ] - - location: 26 (remaining gas: 1039987.553 units remaining) - [ (Pair {} "") ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out deleted file mode 100644 index 1771411d5d0d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }] - -storage - { 99 ; -5 ; 10 } -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.045 units remaining) - [ (Pair 99 { -5 ; 10 }) ] - - location: 8 (remaining gas: 1039994.035 units remaining) - [ 99 @parameter - { -5 ; 10 } @storage ] - - location: 9 (remaining gas: 1039994.020 units remaining) - [ { 99 ; -5 ; 10 } ] - - location: 10 (remaining gas: 1039994.005 units remaining) - [ {} - { 99 ; -5 ; 10 } ] - - location: 12 (remaining gas: 1039993.990 units remaining) - [ (Pair {} { 99 ; -5 ; 10 }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out deleted file mode 100644 index 4bbc35568f62..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }] - -storage - { -5 ; 10 } -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.145 units remaining) - [ (Pair -5 { 10 }) ] - - location: 8 (remaining gas: 1039994.135 units remaining) - [ -5 @parameter - { 10 } @storage ] - - location: 9 (remaining gas: 1039994.120 units remaining) - [ { -5 ; 10 } ] - - location: 10 (remaining gas: 1039994.105 units remaining) - [ {} - { -5 ; 10 } ] - - location: 12 (remaining gas: 1039994.090 units remaining) - [ (Pair {} { -5 ; 10 }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }].out deleted file mode 100644 index c95a25fa5532..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }].out +++ /dev/null @@ -1,22 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }] - -storage - { 10 } -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.245 units remaining) - [ (Pair 10 {}) ] - - location: 8 (remaining gas: 1039994.235 units remaining) - [ 10 @parameter - {} @storage ] - - location: 9 (remaining gas: 1039994.220 units remaining) - [ { 10 } ] - - location: 10 (remaining gas: 1039994.205 units remaining) - [ {} - { 10 } ] - - location: 12 (remaining gas: 1039994.190 units remaining) - [ (Pair {} { 10 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"A\" } { \"B\" })-(Some False)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"A\" } { \"B\" })-(Some False)].out" deleted file mode 100644 index 605e66d5d2e5..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"A\" } { \"B\" })-(Some False)].out" +++ /dev/null @@ -1,166 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "A" } { "B" })-(Some False)] - -storage - (Some False) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039963.179 units remaining) - [ (Pair (Pair { "A" } { "B" }) None) ] - - location: 12 (remaining gas: 1039963.169 units remaining) - [ (Pair { "A" } { "B" }) @parameter ] - - location: 13 (remaining gas: 1039963.159 units remaining) - [ (Pair { "A" } { "B" }) @parameter - (Pair { "A" } { "B" }) @parameter ] - - location: 14 (remaining gas: 1039963.149 units remaining) - [ { "A" } - (Pair { "A" } { "B" }) @parameter ] - - location: 15 (remaining gas: 1039963.134 units remaining) - [ (Pair { "A" } { "B" }) @parameter ] - - location: 17 (remaining gas: 1039963.124 units remaining) - [ { "B" } ] - - location: 15 (remaining gas: 1039963.094 units remaining) - [ { "A" } - { "B" } ] - - location: 18 (remaining gas: 1039962.874 units remaining) - [ {} - { "A" } - { "B" } ] - - location: 20 (remaining gas: 1039962.864 units remaining) - [ { "A" } - {} - { "B" } ] - - location: 21 (remaining gas: 1039962.864 units remaining) - [ "A" @elt - {} - { "B" } ] - - location: 23 (remaining gas: 1039962.849 units remaining) - [ (Pair "A" {}) - { "B" } ] - - location: 24 (remaining gas: 1039962.839 units remaining) - [ (Pair "A" {}) - (Pair "A" {}) - { "B" } ] - - location: 25 (remaining gas: 1039962.829 units remaining) - [ "A" @elt - (Pair "A" {}) - { "B" } ] - - location: 26 (remaining gas: 1039962.814 units remaining) - [ (Pair "A" {}) - { "B" } ] - - location: 28 (remaining gas: 1039962.804 units remaining) - [ {} - { "B" } ] - - location: 26 (remaining gas: 1039962.774 units remaining) - [ "A" @elt - {} - { "B" } ] - - location: 29 (remaining gas: 1039962.764 units remaining) - [ True - "A" @elt - {} - { "B" } ] - - location: 32 (remaining gas: 1039962.754 units remaining) - [ "A" @elt - True - {} - { "B" } ] - - location: 33 (remaining gas: 1039962.554 units remaining) - [ { "A" } - { "B" } ] - - location: 21 (remaining gas: 1039962.539 units remaining) - [ { "A" } - { "B" } ] - - location: 34 (remaining gas: 1039962.529 units remaining) - [ True - { "A" } - { "B" } ] - - location: 37 (remaining gas: 1039962.519 units remaining) - [ { "A" } - True - { "B" } ] - - location: 38 (remaining gas: 1039962.504 units remaining) - [ (Pair { "A" } True) - { "B" } ] - - location: 39 (remaining gas: 1039962.494 units remaining) - [ { "B" } - (Pair { "A" } True) ] - - location: 40 (remaining gas: 1039962.494 units remaining) - [ "B" @elt - (Pair { "A" } True) ] - - location: 42 (remaining gas: 1039962.479 units remaining) - [ (Pair "B" { "A" } True) ] - - location: 43 (remaining gas: 1039962.469 units remaining) - [ (Pair "B" { "A" } True) - (Pair "B" { "A" } True) ] - - location: 44 (remaining gas: 1039962.459 units remaining) - [ (Pair "B" { "A" } True) - (Pair "B" { "A" } True) - (Pair "B" { "A" } True) ] - - location: 45 (remaining gas: 1039962.449 units remaining) - [ "B" @elt - (Pair "B" { "A" } True) - (Pair "B" { "A" } True) ] - - location: 46 (remaining gas: 1039962.434 units remaining) - [ (Pair "B" { "A" } True) - (Pair "B" { "A" } True) ] - - location: 49 (remaining gas: 1039962.424 units remaining) - [ (Pair { "A" } True) - (Pair "B" { "A" } True) ] - - location: 50 (remaining gas: 1039962.414 units remaining) - [ { "A" } - (Pair "B" { "A" } True) ] - - location: 51 (remaining gas: 1039962.399 units remaining) - [ (Pair "B" { "A" } True) ] - - location: 54 (remaining gas: 1039962.389 units remaining) - [ (Pair { "A" } True) ] - - location: 55 (remaining gas: 1039962.379 units remaining) - [ True ] - - location: 51 (remaining gas: 1039962.349 units remaining) - [ { "A" } - True ] - - location: 56 (remaining gas: 1039962.339 units remaining) - [ { "A" } - { "A" } - True ] - - location: 46 (remaining gas: 1039962.309 units remaining) - [ "B" @elt - { "A" } - { "A" } - True ] - - location: 57 (remaining gas: 1039962.124 units remaining) - [ False - { "A" } - True ] - - location: 58 (remaining gas: 1039962.109 units remaining) - [ { "A" } - True ] - - location: 60 (remaining gas: 1039962.099 units remaining) - [ True - { "A" } ] - - location: 58 (remaining gas: 1039962.069 units remaining) - [ False - True - { "A" } ] - - location: 61 (remaining gas: 1039962.049 units remaining) - [ False - { "A" } ] - - location: 62 (remaining gas: 1039962.039 units remaining) - [ { "A" } - False ] - - location: 63 (remaining gas: 1039962.024 units remaining) - [ (Pair { "A" } False) ] - - location: 40 (remaining gas: 1039962.009 units remaining) - [ (Pair { "A" } False) ] - - location: 64 (remaining gas: 1039961.999 units remaining) - [ False ] - - location: 65 (remaining gas: 1039961.984 units remaining) - [ (Some False) ] - - location: 66 (remaining gas: 1039961.969 units remaining) - [ {} - (Some False) ] - - location: 68 (remaining gas: 1039961.954 units remaining) - [ (Pair {} (Some False)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" deleted file mode 100644 index c44d0bfe137e..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" +++ /dev/null @@ -1,410 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" })-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039962.499 units remaining) - [ (Pair (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) None) ] - - location: 12 (remaining gas: 1039962.489 units remaining) - [ (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter ] - - location: 13 (remaining gas: 1039962.479 units remaining) - [ (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter - (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter ] - - location: 14 (remaining gas: 1039962.469 units remaining) - [ { "B" ; "B" ; "asdf" ; "C" } - (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter ] - - location: 15 (remaining gas: 1039962.454 units remaining) - [ (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter ] - - location: 17 (remaining gas: 1039962.444 units remaining) - [ { "B" ; "C" ; "asdf" } ] - - location: 15 (remaining gas: 1039962.414 units remaining) - [ { "B" ; "B" ; "asdf" ; "C" } - { "B" ; "C" ; "asdf" } ] - - location: 18 (remaining gas: 1039962.194 units remaining) - [ {} - { "B" ; "B" ; "asdf" ; "C" } - { "B" ; "C" ; "asdf" } ] - - location: 20 (remaining gas: 1039962.184 units remaining) - [ { "B" ; "B" ; "asdf" ; "C" } - {} - { "B" ; "C" ; "asdf" } ] - - location: 21 (remaining gas: 1039962.184 units remaining) - [ "B" @elt - {} - { "B" ; "C" ; "asdf" } ] - - location: 23 (remaining gas: 1039962.169 units remaining) - [ (Pair "B" {}) - { "B" ; "C" ; "asdf" } ] - - location: 24 (remaining gas: 1039962.159 units remaining) - [ (Pair "B" {}) - (Pair "B" {}) - { "B" ; "C" ; "asdf" } ] - - location: 25 (remaining gas: 1039962.149 units remaining) - [ "B" @elt - (Pair "B" {}) - { "B" ; "C" ; "asdf" } ] - - location: 26 (remaining gas: 1039962.134 units remaining) - [ (Pair "B" {}) - { "B" ; "C" ; "asdf" } ] - - location: 28 (remaining gas: 1039962.124 units remaining) - [ {} - { "B" ; "C" ; "asdf" } ] - - location: 26 (remaining gas: 1039962.094 units remaining) - [ "B" @elt - {} - { "B" ; "C" ; "asdf" } ] - - location: 29 (remaining gas: 1039962.084 units remaining) - [ True - "B" @elt - {} - { "B" ; "C" ; "asdf" } ] - - location: 32 (remaining gas: 1039962.074 units remaining) - [ "B" @elt - True - {} - { "B" ; "C" ; "asdf" } ] - - location: 33 (remaining gas: 1039961.874 units remaining) - [ { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 21 (remaining gas: 1039961.859 units remaining) - [ "B" @elt - { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 23 (remaining gas: 1039961.844 units remaining) - [ (Pair "B" { "B" }) - { "B" ; "C" ; "asdf" } ] - - location: 24 (remaining gas: 1039961.834 units remaining) - [ (Pair "B" { "B" }) - (Pair "B" { "B" }) - { "B" ; "C" ; "asdf" } ] - - location: 25 (remaining gas: 1039961.824 units remaining) - [ "B" @elt - (Pair "B" { "B" }) - { "B" ; "C" ; "asdf" } ] - - location: 26 (remaining gas: 1039961.809 units remaining) - [ (Pair "B" { "B" }) - { "B" ; "C" ; "asdf" } ] - - location: 28 (remaining gas: 1039961.799 units remaining) - [ { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 26 (remaining gas: 1039961.769 units remaining) - [ "B" @elt - { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 29 (remaining gas: 1039961.759 units remaining) - [ True - "B" @elt - { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 32 (remaining gas: 1039961.749 units remaining) - [ "B" @elt - True - { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 33 (remaining gas: 1039961.479 units remaining) - [ { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 21 (remaining gas: 1039961.464 units remaining) - [ "asdf" @elt - { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 23 (remaining gas: 1039961.449 units remaining) - [ (Pair "asdf" { "B" }) - { "B" ; "C" ; "asdf" } ] - - location: 24 (remaining gas: 1039961.439 units remaining) - [ (Pair "asdf" { "B" }) - (Pair "asdf" { "B" }) - { "B" ; "C" ; "asdf" } ] - - location: 25 (remaining gas: 1039961.429 units remaining) - [ "asdf" @elt - (Pair "asdf" { "B" }) - { "B" ; "C" ; "asdf" } ] - - location: 26 (remaining gas: 1039961.414 units remaining) - [ (Pair "asdf" { "B" }) - { "B" ; "C" ; "asdf" } ] - - location: 28 (remaining gas: 1039961.404 units remaining) - [ { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 26 (remaining gas: 1039961.374 units remaining) - [ "asdf" @elt - { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 29 (remaining gas: 1039961.364 units remaining) - [ True - "asdf" @elt - { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 32 (remaining gas: 1039961.354 units remaining) - [ "asdf" @elt - True - { "B" } - { "B" ; "C" ; "asdf" } ] - - location: 33 (remaining gas: 1039961.084 units remaining) - [ { "B" ; "asdf" } - { "B" ; "C" ; "asdf" } ] - - location: 21 (remaining gas: 1039961.069 units remaining) - [ "C" @elt - { "B" ; "asdf" } - { "B" ; "C" ; "asdf" } ] - - location: 23 (remaining gas: 1039961.054 units remaining) - [ (Pair "C" { "B" ; "asdf" }) - { "B" ; "C" ; "asdf" } ] - - location: 24 (remaining gas: 1039961.044 units remaining) - [ (Pair "C" { "B" ; "asdf" }) - (Pair "C" { "B" ; "asdf" }) - { "B" ; "C" ; "asdf" } ] - - location: 25 (remaining gas: 1039961.034 units remaining) - [ "C" @elt - (Pair "C" { "B" ; "asdf" }) - { "B" ; "C" ; "asdf" } ] - - location: 26 (remaining gas: 1039961.019 units remaining) - [ (Pair "C" { "B" ; "asdf" }) - { "B" ; "C" ; "asdf" } ] - - location: 28 (remaining gas: 1039961.009 units remaining) - [ { "B" ; "asdf" } - { "B" ; "C" ; "asdf" } ] - - location: 26 (remaining gas: 1039960.979 units remaining) - [ "C" @elt - { "B" ; "asdf" } - { "B" ; "C" ; "asdf" } ] - - location: 29 (remaining gas: 1039960.969 units remaining) - [ True - "C" @elt - { "B" ; "asdf" } - { "B" ; "C" ; "asdf" } ] - - location: 32 (remaining gas: 1039960.959 units remaining) - [ "C" @elt - True - { "B" ; "asdf" } - { "B" ; "C" ; "asdf" } ] - - location: 33 (remaining gas: 1039960.619 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } ] - - location: 21 (remaining gas: 1039960.604 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } ] - - location: 34 (remaining gas: 1039960.594 units remaining) - [ True - { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } ] - - location: 37 (remaining gas: 1039960.584 units remaining) - [ { "B" ; "C" ; "asdf" } - True - { "B" ; "C" ; "asdf" } ] - - location: 38 (remaining gas: 1039960.569 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) - { "B" ; "C" ; "asdf" } ] - - location: 39 (remaining gas: 1039960.559 units remaining) - [ { "B" ; "C" ; "asdf" } - (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 40 (remaining gas: 1039960.559 units remaining) - [ "B" @elt - (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 42 (remaining gas: 1039960.544 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 43 (remaining gas: 1039960.534 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 44 (remaining gas: 1039960.524 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 45 (remaining gas: 1039960.514 units remaining) - [ "B" @elt - (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 46 (remaining gas: 1039960.499 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 49 (remaining gas: 1039960.489 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 50 (remaining gas: 1039960.479 units remaining) - [ { "B" ; "C" ; "asdf" } - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 51 (remaining gas: 1039960.464 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 54 (remaining gas: 1039960.454 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 55 (remaining gas: 1039960.444 units remaining) - [ True ] - - location: 51 (remaining gas: 1039960.414 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 56 (remaining gas: 1039960.404 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 46 (remaining gas: 1039960.374 units remaining) - [ "B" @elt - { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 57 (remaining gas: 1039960.154 units remaining) - [ True - { "B" ; "C" ; "asdf" } - True ] - - location: 58 (remaining gas: 1039960.139 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 60 (remaining gas: 1039960.129 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 58 (remaining gas: 1039960.099 units remaining) - [ True - True - { "B" ; "C" ; "asdf" } ] - - location: 61 (remaining gas: 1039960.079 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 62 (remaining gas: 1039960.069 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 63 (remaining gas: 1039960.054 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 40 (remaining gas: 1039960.039 units remaining) - [ "C" @elt - (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 42 (remaining gas: 1039960.024 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 43 (remaining gas: 1039960.014 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 44 (remaining gas: 1039960.004 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 45 (remaining gas: 1039959.994 units remaining) - [ "C" @elt - (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 46 (remaining gas: 1039959.979 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 49 (remaining gas: 1039959.969 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 50 (remaining gas: 1039959.959 units remaining) - [ { "B" ; "C" ; "asdf" } - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 51 (remaining gas: 1039959.944 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 54 (remaining gas: 1039959.934 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 55 (remaining gas: 1039959.924 units remaining) - [ True ] - - location: 51 (remaining gas: 1039959.894 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 56 (remaining gas: 1039959.884 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 46 (remaining gas: 1039959.854 units remaining) - [ "C" @elt - { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 57 (remaining gas: 1039959.634 units remaining) - [ True - { "B" ; "C" ; "asdf" } - True ] - - location: 58 (remaining gas: 1039959.619 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 60 (remaining gas: 1039959.609 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 58 (remaining gas: 1039959.579 units remaining) - [ True - True - { "B" ; "C" ; "asdf" } ] - - location: 61 (remaining gas: 1039959.559 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 62 (remaining gas: 1039959.549 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 63 (remaining gas: 1039959.534 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 40 (remaining gas: 1039959.519 units remaining) - [ "asdf" @elt - (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 42 (remaining gas: 1039959.504 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 43 (remaining gas: 1039959.494 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 44 (remaining gas: 1039959.484 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 45 (remaining gas: 1039959.474 units remaining) - [ "asdf" @elt - (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 46 (remaining gas: 1039959.459 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 49 (remaining gas: 1039959.449 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 50 (remaining gas: 1039959.439 units remaining) - [ { "B" ; "C" ; "asdf" } - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 51 (remaining gas: 1039959.424 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 54 (remaining gas: 1039959.414 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 55 (remaining gas: 1039959.404 units remaining) - [ True ] - - location: 51 (remaining gas: 1039959.374 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 56 (remaining gas: 1039959.364 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 46 (remaining gas: 1039959.334 units remaining) - [ "asdf" @elt - { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 57 (remaining gas: 1039959.114 units remaining) - [ True - { "B" ; "C" ; "asdf" } - True ] - - location: 58 (remaining gas: 1039959.099 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 60 (remaining gas: 1039959.089 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 58 (remaining gas: 1039959.059 units remaining) - [ True - True - { "B" ; "C" ; "asdf" } ] - - location: 61 (remaining gas: 1039959.039 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 62 (remaining gas: 1039959.029 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 63 (remaining gas: 1039959.014 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 40 (remaining gas: 1039958.999 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 64 (remaining gas: 1039958.989 units remaining) - [ True ] - - location: 65 (remaining gas: 1039958.974 units remaining) - [ (Some True) ] - - location: 66 (remaining gas: 1039958.959 units remaining) - [ {} - (Some True) ] - - location: 68 (remaining gas: 1039958.944 units remaining) - [ (Pair {} (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" deleted file mode 100644 index dc49c27995b1..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" +++ /dev/null @@ -1,437 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" })-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039962.499 units remaining) - [ (Pair (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) None) ] - - location: 12 (remaining gas: 1039962.489 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter ] - - location: 13 (remaining gas: 1039962.479 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter - (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter ] - - location: 14 (remaining gas: 1039962.469 units remaining) - [ { "B" ; "C" ; "asdf" } - (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter ] - - location: 15 (remaining gas: 1039962.454 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter ] - - location: 17 (remaining gas: 1039962.444 units remaining) - [ { "B" ; "B" ; "asdf" ; "C" } ] - - location: 15 (remaining gas: 1039962.414 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 18 (remaining gas: 1039962.194 units remaining) - [ {} - { "B" ; "C" ; "asdf" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 20 (remaining gas: 1039962.184 units remaining) - [ { "B" ; "C" ; "asdf" } - {} - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 21 (remaining gas: 1039962.184 units remaining) - [ "B" @elt - {} - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 23 (remaining gas: 1039962.169 units remaining) - [ (Pair "B" {}) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 24 (remaining gas: 1039962.159 units remaining) - [ (Pair "B" {}) - (Pair "B" {}) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 25 (remaining gas: 1039962.149 units remaining) - [ "B" @elt - (Pair "B" {}) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 26 (remaining gas: 1039962.134 units remaining) - [ (Pair "B" {}) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 28 (remaining gas: 1039962.124 units remaining) - [ {} - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 26 (remaining gas: 1039962.094 units remaining) - [ "B" @elt - {} - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 29 (remaining gas: 1039962.084 units remaining) - [ True - "B" @elt - {} - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 32 (remaining gas: 1039962.074 units remaining) - [ "B" @elt - True - {} - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 33 (remaining gas: 1039961.874 units remaining) - [ { "B" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 21 (remaining gas: 1039961.859 units remaining) - [ "C" @elt - { "B" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 23 (remaining gas: 1039961.844 units remaining) - [ (Pair "C" { "B" }) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 24 (remaining gas: 1039961.834 units remaining) - [ (Pair "C" { "B" }) - (Pair "C" { "B" }) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 25 (remaining gas: 1039961.824 units remaining) - [ "C" @elt - (Pair "C" { "B" }) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 26 (remaining gas: 1039961.809 units remaining) - [ (Pair "C" { "B" }) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 28 (remaining gas: 1039961.799 units remaining) - [ { "B" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 26 (remaining gas: 1039961.769 units remaining) - [ "C" @elt - { "B" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 29 (remaining gas: 1039961.759 units remaining) - [ True - "C" @elt - { "B" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 32 (remaining gas: 1039961.749 units remaining) - [ "C" @elt - True - { "B" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 33 (remaining gas: 1039961.479 units remaining) - [ { "B" ; "C" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 21 (remaining gas: 1039961.464 units remaining) - [ "asdf" @elt - { "B" ; "C" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 23 (remaining gas: 1039961.449 units remaining) - [ (Pair "asdf" { "B" ; "C" }) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 24 (remaining gas: 1039961.439 units remaining) - [ (Pair "asdf" { "B" ; "C" }) - (Pair "asdf" { "B" ; "C" }) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 25 (remaining gas: 1039961.429 units remaining) - [ "asdf" @elt - (Pair "asdf" { "B" ; "C" }) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 26 (remaining gas: 1039961.414 units remaining) - [ (Pair "asdf" { "B" ; "C" }) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 28 (remaining gas: 1039961.404 units remaining) - [ { "B" ; "C" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 26 (remaining gas: 1039961.374 units remaining) - [ "asdf" @elt - { "B" ; "C" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 29 (remaining gas: 1039961.364 units remaining) - [ True - "asdf" @elt - { "B" ; "C" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 32 (remaining gas: 1039961.354 units remaining) - [ "asdf" @elt - True - { "B" ; "C" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 33 (remaining gas: 1039961.014 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 21 (remaining gas: 1039960.999 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 34 (remaining gas: 1039960.989 units remaining) - [ True - { "B" ; "C" ; "asdf" } - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 37 (remaining gas: 1039960.979 units remaining) - [ { "B" ; "C" ; "asdf" } - True - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 38 (remaining gas: 1039960.964 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) - { "B" ; "B" ; "asdf" ; "C" } ] - - location: 39 (remaining gas: 1039960.954 units remaining) - [ { "B" ; "B" ; "asdf" ; "C" } - (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 40 (remaining gas: 1039960.954 units remaining) - [ "B" @elt - (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 42 (remaining gas: 1039960.939 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 43 (remaining gas: 1039960.929 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 44 (remaining gas: 1039960.919 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 45 (remaining gas: 1039960.909 units remaining) - [ "B" @elt - (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 46 (remaining gas: 1039960.894 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 49 (remaining gas: 1039960.884 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 50 (remaining gas: 1039960.874 units remaining) - [ { "B" ; "C" ; "asdf" } - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 51 (remaining gas: 1039960.859 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 54 (remaining gas: 1039960.849 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 55 (remaining gas: 1039960.839 units remaining) - [ True ] - - location: 51 (remaining gas: 1039960.809 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 56 (remaining gas: 1039960.799 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 46 (remaining gas: 1039960.769 units remaining) - [ "B" @elt - { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 57 (remaining gas: 1039960.549 units remaining) - [ True - { "B" ; "C" ; "asdf" } - True ] - - location: 58 (remaining gas: 1039960.534 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 60 (remaining gas: 1039960.524 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 58 (remaining gas: 1039960.494 units remaining) - [ True - True - { "B" ; "C" ; "asdf" } ] - - location: 61 (remaining gas: 1039960.474 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 62 (remaining gas: 1039960.464 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 63 (remaining gas: 1039960.449 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 40 (remaining gas: 1039960.434 units remaining) - [ "B" @elt - (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 42 (remaining gas: 1039960.419 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 43 (remaining gas: 1039960.409 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 44 (remaining gas: 1039960.399 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 45 (remaining gas: 1039960.389 units remaining) - [ "B" @elt - (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 46 (remaining gas: 1039960.374 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 49 (remaining gas: 1039960.364 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 50 (remaining gas: 1039960.354 units remaining) - [ { "B" ; "C" ; "asdf" } - (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 51 (remaining gas: 1039960.339 units remaining) - [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] - - location: 54 (remaining gas: 1039960.329 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 55 (remaining gas: 1039960.319 units remaining) - [ True ] - - location: 51 (remaining gas: 1039960.289 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 56 (remaining gas: 1039960.279 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 46 (remaining gas: 1039960.249 units remaining) - [ "B" @elt - { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 57 (remaining gas: 1039960.029 units remaining) - [ True - { "B" ; "C" ; "asdf" } - True ] - - location: 58 (remaining gas: 1039960.014 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 60 (remaining gas: 1039960.004 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 58 (remaining gas: 1039959.974 units remaining) - [ True - True - { "B" ; "C" ; "asdf" } ] - - location: 61 (remaining gas: 1039959.954 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 62 (remaining gas: 1039959.944 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 63 (remaining gas: 1039959.929 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 40 (remaining gas: 1039959.914 units remaining) - [ "asdf" @elt - (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 42 (remaining gas: 1039959.899 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 43 (remaining gas: 1039959.889 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 44 (remaining gas: 1039959.879 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 45 (remaining gas: 1039959.869 units remaining) - [ "asdf" @elt - (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 46 (remaining gas: 1039959.854 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 49 (remaining gas: 1039959.844 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 50 (remaining gas: 1039959.834 units remaining) - [ { "B" ; "C" ; "asdf" } - (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 51 (remaining gas: 1039959.819 units remaining) - [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] - - location: 54 (remaining gas: 1039959.809 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 55 (remaining gas: 1039959.799 units remaining) - [ True ] - - location: 51 (remaining gas: 1039959.769 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 56 (remaining gas: 1039959.759 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 46 (remaining gas: 1039959.729 units remaining) - [ "asdf" @elt - { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 57 (remaining gas: 1039959.509 units remaining) - [ True - { "B" ; "C" ; "asdf" } - True ] - - location: 58 (remaining gas: 1039959.494 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 60 (remaining gas: 1039959.484 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 58 (remaining gas: 1039959.454 units remaining) - [ True - True - { "B" ; "C" ; "asdf" } ] - - location: 61 (remaining gas: 1039959.434 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 62 (remaining gas: 1039959.424 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 63 (remaining gas: 1039959.409 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 40 (remaining gas: 1039959.394 units remaining) - [ "C" @elt - (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 42 (remaining gas: 1039959.379 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 43 (remaining gas: 1039959.369 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 44 (remaining gas: 1039959.359 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 45 (remaining gas: 1039959.349 units remaining) - [ "C" @elt - (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 46 (remaining gas: 1039959.334 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 49 (remaining gas: 1039959.324 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 50 (remaining gas: 1039959.314 units remaining) - [ { "B" ; "C" ; "asdf" } - (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 51 (remaining gas: 1039959.299 units remaining) - [ (Pair "C" { "B" ; "C" ; "asdf" } True) ] - - location: 54 (remaining gas: 1039959.289 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 55 (remaining gas: 1039959.279 units remaining) - [ True ] - - location: 51 (remaining gas: 1039959.249 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 56 (remaining gas: 1039959.239 units remaining) - [ { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 46 (remaining gas: 1039959.209 units remaining) - [ "C" @elt - { "B" ; "C" ; "asdf" } - { "B" ; "C" ; "asdf" } - True ] - - location: 57 (remaining gas: 1039958.989 units remaining) - [ True - { "B" ; "C" ; "asdf" } - True ] - - location: 58 (remaining gas: 1039958.974 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 60 (remaining gas: 1039958.964 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 58 (remaining gas: 1039958.934 units remaining) - [ True - True - { "B" ; "C" ; "asdf" } ] - - location: 61 (remaining gas: 1039958.914 units remaining) - [ True - { "B" ; "C" ; "asdf" } ] - - location: 62 (remaining gas: 1039958.904 units remaining) - [ { "B" ; "C" ; "asdf" } - True ] - - location: 63 (remaining gas: 1039958.889 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 40 (remaining gas: 1039958.874 units remaining) - [ (Pair { "B" ; "C" ; "asdf" } True) ] - - location: 64 (remaining gas: 1039958.864 units remaining) - [ True ] - - location: 65 (remaining gas: 1039958.849 units remaining) - [ (Some True) ] - - location: 66 (remaining gas: 1039958.834 units remaining) - [ {} - (Some True) ] - - location: 68 (remaining gas: 1039958.819 units remaining) - [ (Pair {} (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" } { \"B\" })-(Some True)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" } { \"B\" })-(Some True)].out" deleted file mode 100644 index 197c63eff07f..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" } { \"B\" })-(Some True)].out" +++ /dev/null @@ -1,166 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "B" } { "B" })-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039963.179 units remaining) - [ (Pair (Pair { "B" } { "B" }) None) ] - - location: 12 (remaining gas: 1039963.169 units remaining) - [ (Pair { "B" } { "B" }) @parameter ] - - location: 13 (remaining gas: 1039963.159 units remaining) - [ (Pair { "B" } { "B" }) @parameter - (Pair { "B" } { "B" }) @parameter ] - - location: 14 (remaining gas: 1039963.149 units remaining) - [ { "B" } - (Pair { "B" } { "B" }) @parameter ] - - location: 15 (remaining gas: 1039963.134 units remaining) - [ (Pair { "B" } { "B" }) @parameter ] - - location: 17 (remaining gas: 1039963.124 units remaining) - [ { "B" } ] - - location: 15 (remaining gas: 1039963.094 units remaining) - [ { "B" } - { "B" } ] - - location: 18 (remaining gas: 1039962.874 units remaining) - [ {} - { "B" } - { "B" } ] - - location: 20 (remaining gas: 1039962.864 units remaining) - [ { "B" } - {} - { "B" } ] - - location: 21 (remaining gas: 1039962.864 units remaining) - [ "B" @elt - {} - { "B" } ] - - location: 23 (remaining gas: 1039962.849 units remaining) - [ (Pair "B" {}) - { "B" } ] - - location: 24 (remaining gas: 1039962.839 units remaining) - [ (Pair "B" {}) - (Pair "B" {}) - { "B" } ] - - location: 25 (remaining gas: 1039962.829 units remaining) - [ "B" @elt - (Pair "B" {}) - { "B" } ] - - location: 26 (remaining gas: 1039962.814 units remaining) - [ (Pair "B" {}) - { "B" } ] - - location: 28 (remaining gas: 1039962.804 units remaining) - [ {} - { "B" } ] - - location: 26 (remaining gas: 1039962.774 units remaining) - [ "B" @elt - {} - { "B" } ] - - location: 29 (remaining gas: 1039962.764 units remaining) - [ True - "B" @elt - {} - { "B" } ] - - location: 32 (remaining gas: 1039962.754 units remaining) - [ "B" @elt - True - {} - { "B" } ] - - location: 33 (remaining gas: 1039962.554 units remaining) - [ { "B" } - { "B" } ] - - location: 21 (remaining gas: 1039962.539 units remaining) - [ { "B" } - { "B" } ] - - location: 34 (remaining gas: 1039962.529 units remaining) - [ True - { "B" } - { "B" } ] - - location: 37 (remaining gas: 1039962.519 units remaining) - [ { "B" } - True - { "B" } ] - - location: 38 (remaining gas: 1039962.504 units remaining) - [ (Pair { "B" } True) - { "B" } ] - - location: 39 (remaining gas: 1039962.494 units remaining) - [ { "B" } - (Pair { "B" } True) ] - - location: 40 (remaining gas: 1039962.494 units remaining) - [ "B" @elt - (Pair { "B" } True) ] - - location: 42 (remaining gas: 1039962.479 units remaining) - [ (Pair "B" { "B" } True) ] - - location: 43 (remaining gas: 1039962.469 units remaining) - [ (Pair "B" { "B" } True) - (Pair "B" { "B" } True) ] - - location: 44 (remaining gas: 1039962.459 units remaining) - [ (Pair "B" { "B" } True) - (Pair "B" { "B" } True) - (Pair "B" { "B" } True) ] - - location: 45 (remaining gas: 1039962.449 units remaining) - [ "B" @elt - (Pair "B" { "B" } True) - (Pair "B" { "B" } True) ] - - location: 46 (remaining gas: 1039962.434 units remaining) - [ (Pair "B" { "B" } True) - (Pair "B" { "B" } True) ] - - location: 49 (remaining gas: 1039962.424 units remaining) - [ (Pair { "B" } True) - (Pair "B" { "B" } True) ] - - location: 50 (remaining gas: 1039962.414 units remaining) - [ { "B" } - (Pair "B" { "B" } True) ] - - location: 51 (remaining gas: 1039962.399 units remaining) - [ (Pair "B" { "B" } True) ] - - location: 54 (remaining gas: 1039962.389 units remaining) - [ (Pair { "B" } True) ] - - location: 55 (remaining gas: 1039962.379 units remaining) - [ True ] - - location: 51 (remaining gas: 1039962.349 units remaining) - [ { "B" } - True ] - - location: 56 (remaining gas: 1039962.339 units remaining) - [ { "B" } - { "B" } - True ] - - location: 46 (remaining gas: 1039962.309 units remaining) - [ "B" @elt - { "B" } - { "B" } - True ] - - location: 57 (remaining gas: 1039962.124 units remaining) - [ True - { "B" } - True ] - - location: 58 (remaining gas: 1039962.109 units remaining) - [ { "B" } - True ] - - location: 60 (remaining gas: 1039962.099 units remaining) - [ True - { "B" } ] - - location: 58 (remaining gas: 1039962.069 units remaining) - [ True - True - { "B" } ] - - location: 61 (remaining gas: 1039962.049 units remaining) - [ True - { "B" } ] - - location: 62 (remaining gas: 1039962.039 units remaining) - [ { "B" } - True ] - - location: 63 (remaining gas: 1039962.024 units remaining) - [ (Pair { "B" } True) ] - - location: 40 (remaining gas: 1039962.009 units remaining) - [ (Pair { "B" } True) ] - - location: 64 (remaining gas: 1039961.999 units remaining) - [ True ] - - location: 65 (remaining gas: 1039961.984 units remaining) - [ (Some True) ] - - location: 66 (remaining gas: 1039961.969 units remaining) - [ {} - (Some True) ] - - location: 68 (remaining gas: 1039961.954 units remaining) - [ (Pair {} (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"c\" } { \"B\" })-(Some False)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"c\" } { \"B\" })-(Some False)].out" deleted file mode 100644 index 4dab6b7ac088..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"c\" } { \"B\" })-(Some False)].out" +++ /dev/null @@ -1,166 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "c" } { "B" })-(Some False)] - -storage - (Some False) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039963.179 units remaining) - [ (Pair (Pair { "c" } { "B" }) None) ] - - location: 12 (remaining gas: 1039963.169 units remaining) - [ (Pair { "c" } { "B" }) @parameter ] - - location: 13 (remaining gas: 1039963.159 units remaining) - [ (Pair { "c" } { "B" }) @parameter - (Pair { "c" } { "B" }) @parameter ] - - location: 14 (remaining gas: 1039963.149 units remaining) - [ { "c" } - (Pair { "c" } { "B" }) @parameter ] - - location: 15 (remaining gas: 1039963.134 units remaining) - [ (Pair { "c" } { "B" }) @parameter ] - - location: 17 (remaining gas: 1039963.124 units remaining) - [ { "B" } ] - - location: 15 (remaining gas: 1039963.094 units remaining) - [ { "c" } - { "B" } ] - - location: 18 (remaining gas: 1039962.874 units remaining) - [ {} - { "c" } - { "B" } ] - - location: 20 (remaining gas: 1039962.864 units remaining) - [ { "c" } - {} - { "B" } ] - - location: 21 (remaining gas: 1039962.864 units remaining) - [ "c" @elt - {} - { "B" } ] - - location: 23 (remaining gas: 1039962.849 units remaining) - [ (Pair "c" {}) - { "B" } ] - - location: 24 (remaining gas: 1039962.839 units remaining) - [ (Pair "c" {}) - (Pair "c" {}) - { "B" } ] - - location: 25 (remaining gas: 1039962.829 units remaining) - [ "c" @elt - (Pair "c" {}) - { "B" } ] - - location: 26 (remaining gas: 1039962.814 units remaining) - [ (Pair "c" {}) - { "B" } ] - - location: 28 (remaining gas: 1039962.804 units remaining) - [ {} - { "B" } ] - - location: 26 (remaining gas: 1039962.774 units remaining) - [ "c" @elt - {} - { "B" } ] - - location: 29 (remaining gas: 1039962.764 units remaining) - [ True - "c" @elt - {} - { "B" } ] - - location: 32 (remaining gas: 1039962.754 units remaining) - [ "c" @elt - True - {} - { "B" } ] - - location: 33 (remaining gas: 1039962.554 units remaining) - [ { "c" } - { "B" } ] - - location: 21 (remaining gas: 1039962.539 units remaining) - [ { "c" } - { "B" } ] - - location: 34 (remaining gas: 1039962.529 units remaining) - [ True - { "c" } - { "B" } ] - - location: 37 (remaining gas: 1039962.519 units remaining) - [ { "c" } - True - { "B" } ] - - location: 38 (remaining gas: 1039962.504 units remaining) - [ (Pair { "c" } True) - { "B" } ] - - location: 39 (remaining gas: 1039962.494 units remaining) - [ { "B" } - (Pair { "c" } True) ] - - location: 40 (remaining gas: 1039962.494 units remaining) - [ "B" @elt - (Pair { "c" } True) ] - - location: 42 (remaining gas: 1039962.479 units remaining) - [ (Pair "B" { "c" } True) ] - - location: 43 (remaining gas: 1039962.469 units remaining) - [ (Pair "B" { "c" } True) - (Pair "B" { "c" } True) ] - - location: 44 (remaining gas: 1039962.459 units remaining) - [ (Pair "B" { "c" } True) - (Pair "B" { "c" } True) - (Pair "B" { "c" } True) ] - - location: 45 (remaining gas: 1039962.449 units remaining) - [ "B" @elt - (Pair "B" { "c" } True) - (Pair "B" { "c" } True) ] - - location: 46 (remaining gas: 1039962.434 units remaining) - [ (Pair "B" { "c" } True) - (Pair "B" { "c" } True) ] - - location: 49 (remaining gas: 1039962.424 units remaining) - [ (Pair { "c" } True) - (Pair "B" { "c" } True) ] - - location: 50 (remaining gas: 1039962.414 units remaining) - [ { "c" } - (Pair "B" { "c" } True) ] - - location: 51 (remaining gas: 1039962.399 units remaining) - [ (Pair "B" { "c" } True) ] - - location: 54 (remaining gas: 1039962.389 units remaining) - [ (Pair { "c" } True) ] - - location: 55 (remaining gas: 1039962.379 units remaining) - [ True ] - - location: 51 (remaining gas: 1039962.349 units remaining) - [ { "c" } - True ] - - location: 56 (remaining gas: 1039962.339 units remaining) - [ { "c" } - { "c" } - True ] - - location: 46 (remaining gas: 1039962.309 units remaining) - [ "B" @elt - { "c" } - { "c" } - True ] - - location: 57 (remaining gas: 1039962.124 units remaining) - [ False - { "c" } - True ] - - location: 58 (remaining gas: 1039962.109 units remaining) - [ { "c" } - True ] - - location: 60 (remaining gas: 1039962.099 units remaining) - [ True - { "c" } ] - - location: 58 (remaining gas: 1039962.069 units remaining) - [ False - True - { "c" } ] - - location: 61 (remaining gas: 1039962.049 units remaining) - [ False - { "c" } ] - - location: 62 (remaining gas: 1039962.039 units remaining) - [ { "c" } - False ] - - location: 63 (remaining gas: 1039962.024 units remaining) - [ (Pair { "c" } False) ] - - location: 40 (remaining gas: 1039962.009 units remaining) - [ (Pair { "c" } False) ] - - location: 64 (remaining gas: 1039961.999 units remaining) - [ False ] - - location: 65 (remaining gas: 1039961.984 units remaining) - [ (Some False) ] - - location: 66 (remaining gas: 1039961.969 units remaining) - [ {} - (Some False) ] - - location: 68 (remaining gas: 1039961.954 units remaining) - [ (Pair {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)].out deleted file mode 100644 index 8c83513a868c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)].out +++ /dev/null @@ -1,63 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039963.427 units remaining) - [ (Pair (Pair {} {}) None) ] - - location: 12 (remaining gas: 1039963.417 units remaining) - [ (Pair {} {}) @parameter ] - - location: 13 (remaining gas: 1039963.407 units remaining) - [ (Pair {} {}) @parameter - (Pair {} {}) @parameter ] - - location: 14 (remaining gas: 1039963.397 units remaining) - [ {} - (Pair {} {}) @parameter ] - - location: 15 (remaining gas: 1039963.382 units remaining) - [ (Pair {} {}) @parameter ] - - location: 17 (remaining gas: 1039963.372 units remaining) - [ {} ] - - location: 15 (remaining gas: 1039963.342 units remaining) - [ {} - {} ] - - location: 18 (remaining gas: 1039963.122 units remaining) - [ {} - {} - {} ] - - location: 20 (remaining gas: 1039963.112 units remaining) - [ {} - {} - {} ] - - location: 21 (remaining gas: 1039963.112 units remaining) - [ {} - {} ] - - location: 34 (remaining gas: 1039963.102 units remaining) - [ True - {} - {} ] - - location: 37 (remaining gas: 1039963.092 units remaining) - [ {} - True - {} ] - - location: 38 (remaining gas: 1039963.077 units remaining) - [ (Pair {} True) - {} ] - - location: 39 (remaining gas: 1039963.067 units remaining) - [ {} - (Pair {} True) ] - - location: 40 (remaining gas: 1039963.067 units remaining) - [ (Pair {} True) ] - - location: 64 (remaining gas: 1039963.057 units remaining) - [ True ] - - location: 65 (remaining gas: 1039963.042 units remaining) - [ (Some True) ] - - location: 66 (remaining gas: 1039963.027 units remaining) - [ {} - (Some True) ] - - location: 68 (remaining gas: 1039963.012 units remaining) - [ (Pair {} (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contract.tz-Unit-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contract.tz-Unit-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" deleted file mode 100644 index d6b635359adc..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contract.tz-Unit-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" +++ /dev/null @@ -1,29 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contract.tz-Unit-"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039340.345 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" Unit) ] - - location: 7 (remaining gas: 1039340.335 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter ] - - location: 8 (remaining gas: 1039340.085 units remaining) - [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter.contract ] - - location: 11 (remaining gas: 1039340.075 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter.contract.some ] - - location: 11 (remaining gas: 1039340.060 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter.contract.some ] - - location: 17 (remaining gas: 1039340.050 units remaining) - [ ] - - location: 18 (remaining gas: 1039340.040 units remaining) - [ Unit ] - - location: 19 (remaining gas: 1039340.025 units remaining) - [ {} - Unit ] - - location: 21 (remaining gas: 1039340.010 units remaining) - [ (Pair {} Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" deleted file mode 100644 index 56f33bb0882b..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" +++ /dev/null @@ -1,49 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm")] - -storage - (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") -emitted operations - Internal origination: - From: KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi - Credit: ꜩ0.05 - Script: - { parameter unit ; storage unit ; code { CDR ; NIL operation ; PAIR } } - Initial storage: Unit - No delegate for this contract - big_map diff - - trace - - location: 8 (remaining gas: 1039984.194 units remaining) - [ (Pair Unit None) ] - - location: 8 (remaining gas: 1039984.184 units remaining) - [ ] - - location: 9 (remaining gas: 1039984.174 units remaining) - [ Unit ] - - location: 10 (remaining gas: 1039984.159 units remaining) - [ 50000 @amount - Unit ] - - location: 11 (remaining gas: 1039984.144 units remaining) - [ None - 50000 @amount - Unit ] - - location: 13 (remaining gas: 1039983.538 units remaining) - [ 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b - "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm" ] - - location: 25 (remaining gas: 1039983.523 units remaining) - [ "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm" ] - - location: 27 (remaining gas: 1039983.508 units remaining) - [ (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] - - location: 28 (remaining gas: 1039983.493 units remaining) - [ {} - (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] - - location: 25 (remaining gas: 1039983.463 units remaining) - [ 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b - {} - (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] - - location: 30 (remaining gas: 1039983.448 units remaining) - [ { 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b } - (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] - - location: 31 (remaining gas: 1039983.433 units remaining) - [ (Pair { 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b } - (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair \"1970-01-01T00:03:20Z\" \"19.90e9215d17.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair \"1970-01-01T00:03:20Z\" \"19.90e9215d17.out" deleted file mode 100644 index bc28b1cdc720..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair \"1970-01-01T00:03:20Z\" \"19.90e9215d17.out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z")-200] - -storage - 200 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039991.353 units remaining) - [ (Pair (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") 111) ] - - location: 9 (remaining gas: 1039991.343 units remaining) - [ (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 10 (remaining gas: 1039991.333 units remaining) - [ (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter - (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 11 (remaining gas: 1039991.323 units remaining) - [ "1970-01-01T00:03:20Z" - (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 12 (remaining gas: 1039991.308 units remaining) - [ (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 14 (remaining gas: 1039991.298 units remaining) - [ "1970-01-01T00:00:00Z" ] - - location: 12 (remaining gas: 1039991.268 units remaining) - [ "1970-01-01T00:03:20Z" - "1970-01-01T00:00:00Z" ] - - location: 15 (remaining gas: 1039991.213 units remaining) - [ 200 ] - - location: 16 (remaining gas: 1039991.198 units remaining) - [ {} - 200 ] - - location: 18 (remaining gas: 1039991.183 units remaining) - [ (Pair {} 200) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0].out deleted file mode 100644 index 438ed9200f1f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0].out +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039991.553 units remaining) - [ (Pair (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") 111) ] - - location: 9 (remaining gas: 1039991.543 units remaining) - [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 10 (remaining gas: 1039991.533 units remaining) - [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter - (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 11 (remaining gas: 1039991.523 units remaining) - [ "1970-01-01T00:00:00Z" - (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 12 (remaining gas: 1039991.508 units remaining) - [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 14 (remaining gas: 1039991.498 units remaining) - [ "1970-01-01T00:00:00Z" ] - - location: 12 (remaining gas: 1039991.468 units remaining) - [ "1970-01-01T00:00:00Z" - "1970-01-01T00:00:00Z" ] - - location: 15 (remaining gas: 1039991.413 units remaining) - [ 0 ] - - location: 16 (remaining gas: 1039991.398 units remaining) - [ {} - 0 ] - - location: 18 (remaining gas: 1039991.383 units remaining) - [ (Pair {} 0) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1].out deleted file mode 100644 index 158119a92ce9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1].out +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1] - -storage - -1 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039991.553 units remaining) - [ (Pair (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") 111) ] - - location: 9 (remaining gas: 1039991.543 units remaining) - [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter ] - - location: 10 (remaining gas: 1039991.533 units remaining) - [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter - (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter ] - - location: 11 (remaining gas: 1039991.523 units remaining) - [ "1970-01-01T00:00:00Z" - (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter ] - - location: 12 (remaining gas: 1039991.508 units remaining) - [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter ] - - location: 14 (remaining gas: 1039991.498 units remaining) - [ "1970-01-01T00:00:01Z" ] - - location: 12 (remaining gas: 1039991.468 units remaining) - [ "1970-01-01T00:00:00Z" - "1970-01-01T00:00:01Z" ] - - location: 15 (remaining gas: 1039991.413 units remaining) - [ -1 ] - - location: 16 (remaining gas: 1039991.398 units remaining) - [ {} - -1 ] - - location: 18 (remaining gas: 1039991.383 units remaining) - [ (Pair {} -1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1].out deleted file mode 100644 index e67644c0c7e8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1].out +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039991.553 units remaining) - [ (Pair (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") 111) ] - - location: 9 (remaining gas: 1039991.543 units remaining) - [ (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 10 (remaining gas: 1039991.533 units remaining) - [ (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter - (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 11 (remaining gas: 1039991.523 units remaining) - [ "1970-01-01T00:00:01Z" - (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 12 (remaining gas: 1039991.508 units remaining) - [ (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter ] - - location: 14 (remaining gas: 1039991.498 units remaining) - [ "1970-01-01T00:00:00Z" ] - - location: 12 (remaining gas: 1039991.468 units remaining) - [ "1970-01-01T00:00:01Z" - "1970-01-01T00:00:00Z" ] - - location: 15 (remaining gas: 1039991.413 units remaining) - [ 1 ] - - location: 16 (remaining gas: 1039991.398 units remaining) - [ {} - 1 ] - - location: 18 (remaining gas: 1039991.383 units remaining) - [ (Pair {} 1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out deleted file mode 100644 index c915ccc0a863..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out +++ /dev/null @@ -1,3431 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pair 13 (Pair 12 (Pair 11 (Pair 10 (Pair 9 (Pair 8 (Pair 7 (Pair 6 (Pair 5 (Pair 4 (Pair 3 (Pair 2 1))))))))))))))))-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 24 (remaining gas: 1039868.707 units remaining) - [ (Pair (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) Unit) ] - - location: 24 (remaining gas: 1039868.697 units remaining) - [ (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 25 (remaining gas: 1039868.687 units remaining) - [ (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 27 (remaining gas: 1039868.677 units remaining) - [ 17 - (Pair 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 28 (remaining gas: 1039868.662 units remaining) - [ (Pair 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 30 (remaining gas: 1039868.652 units remaining) - [ 16 - (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 28 (remaining gas: 1039868.622 units remaining) - [ 17 - 16 - (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 31 (remaining gas: 1039868.574 units remaining) - [ (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 34 (remaining gas: 1039868.564 units remaining) - [ 15 - (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 31 (remaining gas: 1039868.539 units remaining) - [ 16 - 15 - (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 31 (remaining gas: 1039868.529 units remaining) - [ 17 - 16 - 15 - (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 31 (remaining gas: 1039868.529 units remaining) - [ 17 - 16 - 15 - (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 35 (remaining gas: 1039868.480 units remaining) - [ (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 38 (remaining gas: 1039868.470 units remaining) - [ 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 35 (remaining gas: 1039868.445 units remaining) - [ 15 - 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 35 (remaining gas: 1039868.435 units remaining) - [ 16 - 15 - 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 35 (remaining gas: 1039868.425 units remaining) - [ 17 - 16 - 15 - 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 35 (remaining gas: 1039868.425 units remaining) - [ 17 - 16 - 15 - 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 39 (remaining gas: 1039868.374 units remaining) - [ (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 42 (remaining gas: 1039868.364 units remaining) - [ 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 39 (remaining gas: 1039868.339 units remaining) - [ 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 39 (remaining gas: 1039868.329 units remaining) - [ 15 - 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 39 (remaining gas: 1039868.319 units remaining) - [ 16 - 15 - 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 39 (remaining gas: 1039868.309 units remaining) - [ 17 - 16 - 15 - 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 39 (remaining gas: 1039868.309 units remaining) - [ 17 - 16 - 15 - 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 43 (remaining gas: 1039868.257 units remaining) - [ (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 46 (remaining gas: 1039868.247 units remaining) - [ 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 43 (remaining gas: 1039868.222 units remaining) - [ 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 43 (remaining gas: 1039868.212 units remaining) - [ 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 43 (remaining gas: 1039868.202 units remaining) - [ 15 - 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 43 (remaining gas: 1039868.192 units remaining) - [ 16 - 15 - 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 43 (remaining gas: 1039868.182 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 43 (remaining gas: 1039868.182 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 47 (remaining gas: 1039868.128 units remaining) - [ (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 50 (remaining gas: 1039868.118 units remaining) - [ 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 47 (remaining gas: 1039868.093 units remaining) - [ 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 47 (remaining gas: 1039868.083 units remaining) - [ 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 47 (remaining gas: 1039868.073 units remaining) - [ 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 47 (remaining gas: 1039868.063 units remaining) - [ 15 - 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 47 (remaining gas: 1039868.053 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 47 (remaining gas: 1039868.043 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 47 (remaining gas: 1039868.043 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 51 (remaining gas: 1039867.988 units remaining) - [ (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 54 (remaining gas: 1039867.978 units remaining) - [ 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 51 (remaining gas: 1039867.953 units remaining) - [ 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 51 (remaining gas: 1039867.943 units remaining) - [ 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 51 (remaining gas: 1039867.933 units remaining) - [ 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 51 (remaining gas: 1039867.923 units remaining) - [ 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 51 (remaining gas: 1039867.913 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 51 (remaining gas: 1039867.903 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 51 (remaining gas: 1039867.893 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 51 (remaining gas: 1039867.893 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.835 units remaining) - [ (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 58 (remaining gas: 1039867.825 units remaining) - [ 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.800 units remaining) - [ 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.790 units remaining) - [ 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.780 units remaining) - [ 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.770 units remaining) - [ 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.760 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.750 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.740 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.730 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 55 (remaining gas: 1039867.730 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.671 units remaining) - [ (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 62 (remaining gas: 1039867.661 units remaining) - [ 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.636 units remaining) - [ 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.626 units remaining) - [ 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.616 units remaining) - [ 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.606 units remaining) - [ 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.596 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.586 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.576 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.566 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.556 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 59 (remaining gas: 1039867.556 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.495 units remaining) - [ (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 66 (remaining gas: 1039867.485 units remaining) - [ 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.460 units remaining) - [ 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.450 units remaining) - [ 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.440 units remaining) - [ 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.430 units remaining) - [ 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.420 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.410 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.400 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.390 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.380 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.370 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 63 (remaining gas: 1039867.370 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.308 units remaining) - [ (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 70 (remaining gas: 1039867.298 units remaining) - [ 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.273 units remaining) - [ 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.263 units remaining) - [ 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.253 units remaining) - [ 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.243 units remaining) - [ 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.233 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.223 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.213 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.203 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.193 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.183 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.173 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 67 (remaining gas: 1039867.173 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039867.109 units remaining) - [ (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 74 (remaining gas: 1039867.099 units remaining) - [ 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039867.074 units remaining) - [ 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039867.064 units remaining) - [ 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039867.054 units remaining) - [ 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039867.044 units remaining) - [ 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039867.034 units remaining) - [ 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039867.024 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039867.014 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039867.004 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039866.994 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039866.984 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039866.974 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039866.964 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 71 (remaining gas: 1039866.964 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.899 units remaining) - [ (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 78 (remaining gas: 1039866.889 units remaining) - [ 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.864 units remaining) - [ 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.854 units remaining) - [ 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.844 units remaining) - [ 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.834 units remaining) - [ 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.824 units remaining) - [ 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.814 units remaining) - [ 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.804 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.794 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.784 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.774 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.764 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.754 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.744 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 75 (remaining gas: 1039866.744 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.677 units remaining) - [ (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 82 (remaining gas: 1039866.667 units remaining) - [ 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.642 units remaining) - [ 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.632 units remaining) - [ 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.622 units remaining) - [ 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.612 units remaining) - [ 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.602 units remaining) - [ 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.592 units remaining) - [ 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.582 units remaining) - [ 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.572 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.562 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.552 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.542 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.532 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.522 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.512 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 79 (remaining gas: 1039866.512 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.444 units remaining) - [ (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 86 (remaining gas: 1039866.434 units remaining) - [ 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.409 units remaining) - [ 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.399 units remaining) - [ 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.389 units remaining) - [ 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.379 units remaining) - [ 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.369 units remaining) - [ 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.359 units remaining) - [ 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.349 units remaining) - [ 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.339 units remaining) - [ 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.329 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.319 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.309 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.299 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.289 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.279 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.269 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 83 (remaining gas: 1039866.269 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 87 (remaining gas: 1039866.209 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 89 (remaining gas: 1039866.143 units remaining) - [ 16 - 17 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 91 (remaining gas: 1039866.070 units remaining) - [ 15 - 16 - 17 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 93 (remaining gas: 1039865.991 units remaining) - [ 14 - 15 - 16 - 17 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 95 (remaining gas: 1039865.904 units remaining) - [ 13 - 14 - 15 - 16 - 17 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 97 (remaining gas: 1039865.811 units remaining) - [ 12 - 13 - 14 - 15 - 16 - 17 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 99 (remaining gas: 1039865.711 units remaining) - [ 11 - 12 - 13 - 14 - 15 - 16 - 17 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 101 (remaining gas: 1039865.605 units remaining) - [ 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 103 (remaining gas: 1039865.491 units remaining) - [ 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 105 (remaining gas: 1039865.371 units remaining) - [ 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 107 (remaining gas: 1039865.244 units remaining) - [ 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 109 (remaining gas: 1039865.111 units remaining) - [ 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 111 (remaining gas: 1039864.970 units remaining) - [ 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 113 (remaining gas: 1039864.823 units remaining) - [ 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 115 (remaining gas: 1039864.669 units remaining) - [ 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 117 (remaining gas: 1039864.509 units remaining) - [ 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 119 (remaining gas: 1039864.341 units remaining) - [ 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 121 (remaining gas: 1039864.281 units remaining) - [ 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 123 (remaining gas: 1039864.215 units remaining) - [ 2 - 1 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 125 (remaining gas: 1039864.142 units remaining) - [ 3 - 2 - 1 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 127 (remaining gas: 1039864.063 units remaining) - [ 4 - 3 - 2 - 1 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 129 (remaining gas: 1039863.976 units remaining) - [ 5 - 4 - 3 - 2 - 1 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 131 (remaining gas: 1039863.883 units remaining) - [ 6 - 5 - 4 - 3 - 2 - 1 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 133 (remaining gas: 1039863.783 units remaining) - [ 7 - 6 - 5 - 4 - 3 - 2 - 1 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 135 (remaining gas: 1039863.677 units remaining) - [ 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 137 (remaining gas: 1039863.563 units remaining) - [ 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 139 (remaining gas: 1039863.443 units remaining) - [ 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 141 (remaining gas: 1039863.316 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 12 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 143 (remaining gas: 1039863.183 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 13 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 145 (remaining gas: 1039863.042 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 14 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 147 (remaining gas: 1039862.895 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 15 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 149 (remaining gas: 1039862.741 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 16 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 151 (remaining gas: 1039862.581 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - 17 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 153 (remaining gas: 1039862.413 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.345 units remaining) - [ 2 - 1 - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 159 (remaining gas: 1039862.330 units remaining) - [ (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.305 units remaining) - [ 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.295 units remaining) - [ 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.285 units remaining) - [ 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.275 units remaining) - [ 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.265 units remaining) - [ 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.255 units remaining) - [ 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.245 units remaining) - [ 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.235 units remaining) - [ 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.225 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.215 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.205 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.195 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.185 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.175 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.165 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 156 (remaining gas: 1039862.165 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039862.098 units remaining) - [ 3 - (Pair 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 163 (remaining gas: 1039862.083 units remaining) - [ (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039862.058 units remaining) - [ 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039862.048 units remaining) - [ 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039862.038 units remaining) - [ 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039862.028 units remaining) - [ 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039862.018 units remaining) - [ 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039862.008 units remaining) - [ 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039861.998 units remaining) - [ 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039861.988 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039861.978 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039861.968 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039861.958 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039861.948 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039861.938 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039861.928 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 160 (remaining gas: 1039861.928 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.863 units remaining) - [ 4 - (Pair 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 167 (remaining gas: 1039861.848 units remaining) - [ (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.823 units remaining) - [ 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.813 units remaining) - [ 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.803 units remaining) - [ 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.793 units remaining) - [ 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.783 units remaining) - [ 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.773 units remaining) - [ 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.763 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.753 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.743 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.733 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.723 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.713 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.703 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 164 (remaining gas: 1039861.703 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.639 units remaining) - [ 5 - (Pair 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 171 (remaining gas: 1039861.624 units remaining) - [ (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.599 units remaining) - [ 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.589 units remaining) - [ 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.579 units remaining) - [ 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.569 units remaining) - [ 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.559 units remaining) - [ 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.549 units remaining) - [ 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.539 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.529 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.519 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.509 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.499 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.489 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 168 (remaining gas: 1039861.489 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.427 units remaining) - [ 6 - (Pair 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 175 (remaining gas: 1039861.412 units remaining) - [ (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.387 units remaining) - [ 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.377 units remaining) - [ 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.367 units remaining) - [ 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.357 units remaining) - [ 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.347 units remaining) - [ 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.337 units remaining) - [ 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.327 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.317 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.307 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.297 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.287 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 172 (remaining gas: 1039861.287 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.226 units remaining) - [ 7 - (Pair 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 179 (remaining gas: 1039861.211 units remaining) - [ (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.186 units remaining) - [ 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.176 units remaining) - [ 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.166 units remaining) - [ 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.156 units remaining) - [ 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.146 units remaining) - [ 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.136 units remaining) - [ 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.126 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.116 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.106 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.096 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 176 (remaining gas: 1039861.096 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039861.037 units remaining) - [ 8 - (Pair 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 183 (remaining gas: 1039861.022 units remaining) - [ (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.997 units remaining) - [ 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.987 units remaining) - [ 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.977 units remaining) - [ 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.967 units remaining) - [ 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.957 units remaining) - [ 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.947 units remaining) - [ 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.937 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.927 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.917 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 180 (remaining gas: 1039860.917 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.859 units remaining) - [ 9 - (Pair 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 187 (remaining gas: 1039860.844 units remaining) - [ (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.819 units remaining) - [ 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.809 units remaining) - [ 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.799 units remaining) - [ 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.789 units remaining) - [ 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.779 units remaining) - [ 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.769 units remaining) - [ 15 - 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.759 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.749 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 184 (remaining gas: 1039860.749 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 188 (remaining gas: 1039860.694 units remaining) - [ 10 - (Pair 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 191 (remaining gas: 1039860.679 units remaining) - [ (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 188 (remaining gas: 1039860.654 units remaining) - [ 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 188 (remaining gas: 1039860.644 units remaining) - [ 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 188 (remaining gas: 1039860.634 units remaining) - [ 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 188 (remaining gas: 1039860.624 units remaining) - [ 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 188 (remaining gas: 1039860.614 units remaining) - [ 15 - 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 188 (remaining gas: 1039860.604 units remaining) - [ 16 - 15 - 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 188 (remaining gas: 1039860.594 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 188 (remaining gas: 1039860.594 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 192 (remaining gas: 1039860.540 units remaining) - [ 11 - (Pair 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 195 (remaining gas: 1039860.525 units remaining) - [ (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 192 (remaining gas: 1039860.500 units remaining) - [ 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 192 (remaining gas: 1039860.490 units remaining) - [ 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 192 (remaining gas: 1039860.480 units remaining) - [ 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 192 (remaining gas: 1039860.470 units remaining) - [ 15 - 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 192 (remaining gas: 1039860.460 units remaining) - [ 16 - 15 - 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 192 (remaining gas: 1039860.450 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 192 (remaining gas: 1039860.450 units remaining) - [ 17 - 16 - 15 - 14 - 13 - 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 196 (remaining gas: 1039860.398 units remaining) - [ 12 - (Pair 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 199 (remaining gas: 1039860.383 units remaining) - [ (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 196 (remaining gas: 1039860.358 units remaining) - [ 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 196 (remaining gas: 1039860.348 units remaining) - [ 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 196 (remaining gas: 1039860.338 units remaining) - [ 15 - 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 196 (remaining gas: 1039860.328 units remaining) - [ 16 - 15 - 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 196 (remaining gas: 1039860.318 units remaining) - [ 17 - 16 - 15 - 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 196 (remaining gas: 1039860.318 units remaining) - [ 17 - 16 - 15 - 14 - 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 200 (remaining gas: 1039860.267 units remaining) - [ 13 - (Pair 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 203 (remaining gas: 1039860.252 units remaining) - [ (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 200 (remaining gas: 1039860.227 units remaining) - [ 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 200 (remaining gas: 1039860.217 units remaining) - [ 15 - 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 200 (remaining gas: 1039860.207 units remaining) - [ 16 - 15 - 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 200 (remaining gas: 1039860.197 units remaining) - [ 17 - 16 - 15 - 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 200 (remaining gas: 1039860.197 units remaining) - [ 17 - 16 - 15 - 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 204 (remaining gas: 1039860.148 units remaining) - [ 14 - (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 207 (remaining gas: 1039860.133 units remaining) - [ (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 204 (remaining gas: 1039860.108 units remaining) - [ 15 - (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 204 (remaining gas: 1039860.098 units remaining) - [ 16 - 15 - (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 204 (remaining gas: 1039860.088 units remaining) - [ 17 - 16 - 15 - (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 204 (remaining gas: 1039860.088 units remaining) - [ 17 - 16 - 15 - (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 208 (remaining gas: 1039860.040 units remaining) - [ 15 - (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 211 (remaining gas: 1039860.025 units remaining) - [ (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 208 (remaining gas: 1039860 units remaining) - [ 16 - (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 208 (remaining gas: 1039859.990 units remaining) - [ 17 - 16 - (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 208 (remaining gas: 1039859.990 units remaining) - [ 17 - 16 - (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 212 (remaining gas: 1039859.975 units remaining) - [ 16 - (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 214 (remaining gas: 1039859.960 units remaining) - [ (Pair 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 212 (remaining gas: 1039859.930 units remaining) - [ 17 - (Pair 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 215 (remaining gas: 1039859.915 units remaining) - [ (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) - (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] - - location: 218 (remaining gas: 1039859.160 units remaining) - [ 0 ] - - location: 219 (remaining gas: 1039859.145 units remaining) - [ True ] - - location: 220 (remaining gas: 1039859.135 units remaining) - [ ] - - location: 220 (remaining gas: 1039859.120 units remaining) - [ ] - - location: 226 (remaining gas: 1039859.110 units remaining) - [ Unit ] - - location: 227 (remaining gas: 1039859.095 units remaining) - [ {} - Unit ] - - location: 229 (remaining gas: 1039859.080 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out deleted file mode 100644 index ef1cd7ba980f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out +++ /dev/null @@ -1,3431 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair 10 (Pair 14 (Pair 19 (Pair 9 (Pair 18 (Pair 6 (Pair 8 (Pair 11 (Pair 4 (Pair 13 (Pair 15 (Pair 5 1))))))))))))))))-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 24 (remaining gas: 1039868.707 units remaining) - [ (Pair (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) Unit) ] - - location: 24 (remaining gas: 1039868.697 units remaining) - [ (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 25 (remaining gas: 1039868.687 units remaining) - [ (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 27 (remaining gas: 1039868.677 units remaining) - [ 2 - (Pair 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 28 (remaining gas: 1039868.662 units remaining) - [ (Pair 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 30 (remaining gas: 1039868.652 units remaining) - [ 3 - (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 28 (remaining gas: 1039868.622 units remaining) - [ 2 - 3 - (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 31 (remaining gas: 1039868.574 units remaining) - [ (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 34 (remaining gas: 1039868.564 units remaining) - [ 12 - (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 31 (remaining gas: 1039868.539 units remaining) - [ 3 - 12 - (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 31 (remaining gas: 1039868.529 units remaining) - [ 2 - 3 - 12 - (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 31 (remaining gas: 1039868.529 units remaining) - [ 2 - 3 - 12 - (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 35 (remaining gas: 1039868.480 units remaining) - [ (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 38 (remaining gas: 1039868.470 units remaining) - [ 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 35 (remaining gas: 1039868.445 units remaining) - [ 12 - 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 35 (remaining gas: 1039868.435 units remaining) - [ 3 - 12 - 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 35 (remaining gas: 1039868.425 units remaining) - [ 2 - 3 - 12 - 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 35 (remaining gas: 1039868.425 units remaining) - [ 2 - 3 - 12 - 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 39 (remaining gas: 1039868.374 units remaining) - [ (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 42 (remaining gas: 1039868.364 units remaining) - [ 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 39 (remaining gas: 1039868.339 units remaining) - [ 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 39 (remaining gas: 1039868.329 units remaining) - [ 12 - 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 39 (remaining gas: 1039868.319 units remaining) - [ 3 - 12 - 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 39 (remaining gas: 1039868.309 units remaining) - [ 2 - 3 - 12 - 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 39 (remaining gas: 1039868.309 units remaining) - [ 2 - 3 - 12 - 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 43 (remaining gas: 1039868.257 units remaining) - [ (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 46 (remaining gas: 1039868.247 units remaining) - [ 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 43 (remaining gas: 1039868.222 units remaining) - [ 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 43 (remaining gas: 1039868.212 units remaining) - [ 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 43 (remaining gas: 1039868.202 units remaining) - [ 12 - 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 43 (remaining gas: 1039868.192 units remaining) - [ 3 - 12 - 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 43 (remaining gas: 1039868.182 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 43 (remaining gas: 1039868.182 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 47 (remaining gas: 1039868.128 units remaining) - [ (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 50 (remaining gas: 1039868.118 units remaining) - [ 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 47 (remaining gas: 1039868.093 units remaining) - [ 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 47 (remaining gas: 1039868.083 units remaining) - [ 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 47 (remaining gas: 1039868.073 units remaining) - [ 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 47 (remaining gas: 1039868.063 units remaining) - [ 12 - 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 47 (remaining gas: 1039868.053 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 47 (remaining gas: 1039868.043 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 47 (remaining gas: 1039868.043 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 51 (remaining gas: 1039867.988 units remaining) - [ (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 54 (remaining gas: 1039867.978 units remaining) - [ 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 51 (remaining gas: 1039867.953 units remaining) - [ 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 51 (remaining gas: 1039867.943 units remaining) - [ 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 51 (remaining gas: 1039867.933 units remaining) - [ 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 51 (remaining gas: 1039867.923 units remaining) - [ 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 51 (remaining gas: 1039867.913 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 51 (remaining gas: 1039867.903 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 51 (remaining gas: 1039867.893 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 51 (remaining gas: 1039867.893 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.835 units remaining) - [ (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 58 (remaining gas: 1039867.825 units remaining) - [ 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.800 units remaining) - [ 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.790 units remaining) - [ 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.780 units remaining) - [ 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.770 units remaining) - [ 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.760 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.750 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.740 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.730 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 55 (remaining gas: 1039867.730 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.671 units remaining) - [ (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 62 (remaining gas: 1039867.661 units remaining) - [ 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.636 units remaining) - [ 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.626 units remaining) - [ 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.616 units remaining) - [ 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.606 units remaining) - [ 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.596 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.586 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.576 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.566 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.556 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 59 (remaining gas: 1039867.556 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.495 units remaining) - [ (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 66 (remaining gas: 1039867.485 units remaining) - [ 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.460 units remaining) - [ 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.450 units remaining) - [ 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.440 units remaining) - [ 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.430 units remaining) - [ 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.420 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.410 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.400 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.390 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.380 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.370 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 63 (remaining gas: 1039867.370 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.308 units remaining) - [ (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 70 (remaining gas: 1039867.298 units remaining) - [ 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.273 units remaining) - [ 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.263 units remaining) - [ 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.253 units remaining) - [ 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.243 units remaining) - [ 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.233 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.223 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.213 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.203 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.193 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.183 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.173 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 67 (remaining gas: 1039867.173 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039867.109 units remaining) - [ (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 74 (remaining gas: 1039867.099 units remaining) - [ 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039867.074 units remaining) - [ 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039867.064 units remaining) - [ 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039867.054 units remaining) - [ 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039867.044 units remaining) - [ 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039867.034 units remaining) - [ 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039867.024 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039867.014 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039867.004 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039866.994 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039866.984 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039866.974 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039866.964 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 71 (remaining gas: 1039866.964 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.899 units remaining) - [ (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 78 (remaining gas: 1039866.889 units remaining) - [ 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.864 units remaining) - [ 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.854 units remaining) - [ 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.844 units remaining) - [ 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.834 units remaining) - [ 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.824 units remaining) - [ 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.814 units remaining) - [ 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.804 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.794 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.784 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.774 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.764 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.754 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.744 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 75 (remaining gas: 1039866.744 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.677 units remaining) - [ (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 82 (remaining gas: 1039866.667 units remaining) - [ 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.642 units remaining) - [ 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.632 units remaining) - [ 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.622 units remaining) - [ 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.612 units remaining) - [ 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.602 units remaining) - [ 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.592 units remaining) - [ 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.582 units remaining) - [ 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.572 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.562 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.552 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.542 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.532 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.522 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.512 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 79 (remaining gas: 1039866.512 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.444 units remaining) - [ (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 86 (remaining gas: 1039866.434 units remaining) - [ 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.409 units remaining) - [ 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.399 units remaining) - [ 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.389 units remaining) - [ 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.379 units remaining) - [ 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.369 units remaining) - [ 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.359 units remaining) - [ 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.349 units remaining) - [ 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.339 units remaining) - [ 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.329 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.319 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.309 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.299 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.289 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.279 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.269 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 83 (remaining gas: 1039866.269 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 87 (remaining gas: 1039866.209 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 89 (remaining gas: 1039866.143 units remaining) - [ 3 - 2 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 91 (remaining gas: 1039866.070 units remaining) - [ 12 - 3 - 2 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 93 (remaining gas: 1039865.991 units remaining) - [ 16 - 12 - 3 - 2 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 95 (remaining gas: 1039865.904 units remaining) - [ 10 - 16 - 12 - 3 - 2 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 97 (remaining gas: 1039865.811 units remaining) - [ 14 - 10 - 16 - 12 - 3 - 2 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 99 (remaining gas: 1039865.711 units remaining) - [ 19 - 14 - 10 - 16 - 12 - 3 - 2 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 101 (remaining gas: 1039865.605 units remaining) - [ 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 103 (remaining gas: 1039865.491 units remaining) - [ 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 105 (remaining gas: 1039865.371 units remaining) - [ 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 107 (remaining gas: 1039865.244 units remaining) - [ 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 109 (remaining gas: 1039865.111 units remaining) - [ 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 111 (remaining gas: 1039864.970 units remaining) - [ 4 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 113 (remaining gas: 1039864.823 units remaining) - [ 13 - 4 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 115 (remaining gas: 1039864.669 units remaining) - [ 15 - 13 - 4 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 117 (remaining gas: 1039864.509 units remaining) - [ 5 - 15 - 13 - 4 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 119 (remaining gas: 1039864.341 units remaining) - [ 1 - 5 - 15 - 13 - 4 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 121 (remaining gas: 1039864.281 units remaining) - [ 1 - 5 - 15 - 13 - 4 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 123 (remaining gas: 1039864.215 units remaining) - [ 5 - 1 - 15 - 13 - 4 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 125 (remaining gas: 1039864.142 units remaining) - [ 15 - 5 - 1 - 13 - 4 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 127 (remaining gas: 1039864.063 units remaining) - [ 13 - 15 - 5 - 1 - 4 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 129 (remaining gas: 1039863.976 units remaining) - [ 4 - 13 - 15 - 5 - 1 - 11 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 131 (remaining gas: 1039863.883 units remaining) - [ 11 - 4 - 13 - 15 - 5 - 1 - 8 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 133 (remaining gas: 1039863.783 units remaining) - [ 8 - 11 - 4 - 13 - 15 - 5 - 1 - 6 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 135 (remaining gas: 1039863.677 units remaining) - [ 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - 18 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 137 (remaining gas: 1039863.563 units remaining) - [ 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - 9 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 139 (remaining gas: 1039863.443 units remaining) - [ 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - 19 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 141 (remaining gas: 1039863.316 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - 14 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 143 (remaining gas: 1039863.183 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - 10 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 145 (remaining gas: 1039863.042 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - 16 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 147 (remaining gas: 1039862.895 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - 12 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 149 (remaining gas: 1039862.741 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - 3 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 151 (remaining gas: 1039862.581 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - 2 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 153 (remaining gas: 1039862.413 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.345 units remaining) - [ 5 - 1 - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 159 (remaining gas: 1039862.330 units remaining) - [ (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.305 units remaining) - [ 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.295 units remaining) - [ 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.285 units remaining) - [ 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.275 units remaining) - [ 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.265 units remaining) - [ 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.255 units remaining) - [ 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.245 units remaining) - [ 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.235 units remaining) - [ 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.225 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.215 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.205 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.195 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.185 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.175 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.165 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 156 (remaining gas: 1039862.165 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039862.098 units remaining) - [ 15 - (Pair 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 163 (remaining gas: 1039862.083 units remaining) - [ (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039862.058 units remaining) - [ 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039862.048 units remaining) - [ 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039862.038 units remaining) - [ 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039862.028 units remaining) - [ 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039862.018 units remaining) - [ 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039862.008 units remaining) - [ 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039861.998 units remaining) - [ 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039861.988 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039861.978 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039861.968 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039861.958 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039861.948 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039861.938 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039861.928 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 160 (remaining gas: 1039861.928 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.863 units remaining) - [ 13 - (Pair 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 167 (remaining gas: 1039861.848 units remaining) - [ (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.823 units remaining) - [ 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.813 units remaining) - [ 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.803 units remaining) - [ 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.793 units remaining) - [ 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.783 units remaining) - [ 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.773 units remaining) - [ 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.763 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.753 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.743 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.733 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.723 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.713 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.703 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 164 (remaining gas: 1039861.703 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.639 units remaining) - [ 4 - (Pair 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 171 (remaining gas: 1039861.624 units remaining) - [ (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.599 units remaining) - [ 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.589 units remaining) - [ 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.579 units remaining) - [ 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.569 units remaining) - [ 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.559 units remaining) - [ 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.549 units remaining) - [ 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.539 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.529 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.519 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.509 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.499 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.489 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 168 (remaining gas: 1039861.489 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.427 units remaining) - [ 11 - (Pair 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 175 (remaining gas: 1039861.412 units remaining) - [ (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.387 units remaining) - [ 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.377 units remaining) - [ 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.367 units remaining) - [ 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.357 units remaining) - [ 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.347 units remaining) - [ 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.337 units remaining) - [ 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.327 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.317 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.307 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.297 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.287 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 172 (remaining gas: 1039861.287 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.226 units remaining) - [ 8 - (Pair 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 179 (remaining gas: 1039861.211 units remaining) - [ (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.186 units remaining) - [ 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.176 units remaining) - [ 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.166 units remaining) - [ 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.156 units remaining) - [ 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.146 units remaining) - [ 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.136 units remaining) - [ 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.126 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.116 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.106 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.096 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 176 (remaining gas: 1039861.096 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039861.037 units remaining) - [ 6 - (Pair 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 183 (remaining gas: 1039861.022 units remaining) - [ (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.997 units remaining) - [ 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.987 units remaining) - [ 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.977 units remaining) - [ 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.967 units remaining) - [ 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.957 units remaining) - [ 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.947 units remaining) - [ 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.937 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.927 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.917 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 180 (remaining gas: 1039860.917 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.859 units remaining) - [ 18 - (Pair 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 187 (remaining gas: 1039860.844 units remaining) - [ (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.819 units remaining) - [ 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.809 units remaining) - [ 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.799 units remaining) - [ 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.789 units remaining) - [ 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.779 units remaining) - [ 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.769 units remaining) - [ 12 - 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.759 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.749 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 184 (remaining gas: 1039860.749 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 188 (remaining gas: 1039860.694 units remaining) - [ 9 - (Pair 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 191 (remaining gas: 1039860.679 units remaining) - [ (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 188 (remaining gas: 1039860.654 units remaining) - [ 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 188 (remaining gas: 1039860.644 units remaining) - [ 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 188 (remaining gas: 1039860.634 units remaining) - [ 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 188 (remaining gas: 1039860.624 units remaining) - [ 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 188 (remaining gas: 1039860.614 units remaining) - [ 12 - 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 188 (remaining gas: 1039860.604 units remaining) - [ 3 - 12 - 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 188 (remaining gas: 1039860.594 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 188 (remaining gas: 1039860.594 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 192 (remaining gas: 1039860.540 units remaining) - [ 19 - (Pair 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 195 (remaining gas: 1039860.525 units remaining) - [ (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 192 (remaining gas: 1039860.500 units remaining) - [ 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 192 (remaining gas: 1039860.490 units remaining) - [ 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 192 (remaining gas: 1039860.480 units remaining) - [ 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 192 (remaining gas: 1039860.470 units remaining) - [ 12 - 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 192 (remaining gas: 1039860.460 units remaining) - [ 3 - 12 - 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 192 (remaining gas: 1039860.450 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 192 (remaining gas: 1039860.450 units remaining) - [ 2 - 3 - 12 - 16 - 10 - 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 196 (remaining gas: 1039860.398 units remaining) - [ 14 - (Pair 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 199 (remaining gas: 1039860.383 units remaining) - [ (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 196 (remaining gas: 1039860.358 units remaining) - [ 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 196 (remaining gas: 1039860.348 units remaining) - [ 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 196 (remaining gas: 1039860.338 units remaining) - [ 12 - 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 196 (remaining gas: 1039860.328 units remaining) - [ 3 - 12 - 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 196 (remaining gas: 1039860.318 units remaining) - [ 2 - 3 - 12 - 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 196 (remaining gas: 1039860.318 units remaining) - [ 2 - 3 - 12 - 16 - 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 200 (remaining gas: 1039860.267 units remaining) - [ 10 - (Pair 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 203 (remaining gas: 1039860.252 units remaining) - [ (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 200 (remaining gas: 1039860.227 units remaining) - [ 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 200 (remaining gas: 1039860.217 units remaining) - [ 12 - 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 200 (remaining gas: 1039860.207 units remaining) - [ 3 - 12 - 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 200 (remaining gas: 1039860.197 units remaining) - [ 2 - 3 - 12 - 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 200 (remaining gas: 1039860.197 units remaining) - [ 2 - 3 - 12 - 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 204 (remaining gas: 1039860.148 units remaining) - [ 16 - (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 207 (remaining gas: 1039860.133 units remaining) - [ (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 204 (remaining gas: 1039860.108 units remaining) - [ 12 - (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 204 (remaining gas: 1039860.098 units remaining) - [ 3 - 12 - (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 204 (remaining gas: 1039860.088 units remaining) - [ 2 - 3 - 12 - (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 204 (remaining gas: 1039860.088 units remaining) - [ 2 - 3 - 12 - (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 208 (remaining gas: 1039860.040 units remaining) - [ 12 - (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 211 (remaining gas: 1039860.025 units remaining) - [ (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 208 (remaining gas: 1039860 units remaining) - [ 3 - (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 208 (remaining gas: 1039859.990 units remaining) - [ 2 - 3 - (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 208 (remaining gas: 1039859.990 units remaining) - [ 2 - 3 - (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 212 (remaining gas: 1039859.975 units remaining) - [ 3 - (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 214 (remaining gas: 1039859.960 units remaining) - [ (Pair 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 212 (remaining gas: 1039859.930 units remaining) - [ 2 - (Pair 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 215 (remaining gas: 1039859.915 units remaining) - [ (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) - (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] - - location: 218 (remaining gas: 1039859.160 units remaining) - [ 0 ] - - location: 219 (remaining gas: 1039859.145 units remaining) - [ True ] - - location: 220 (remaining gas: 1039859.135 units remaining) - [ ] - - location: 220 (remaining gas: 1039859.120 units remaining) - [ ] - - location: 226 (remaining gas: 1039859.110 units remaining) - [ Unit ] - - location: 227 (remaining gas: 1039859.095 units remaining) - [ {} - Unit ] - - location: 229 (remaining gas: 1039859.080 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out deleted file mode 100644 index abdd55127e74..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out +++ /dev/null @@ -1,61 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5] - -storage - 5 -emitted operations - -big_map diff - -trace - - location: 15 (remaining gas: 1039987.170 units remaining) - [ (Pair (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) 0) ] - - location: 15 (remaining gas: 1039987.160 units remaining) - [ (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) @parameter ] - - location: 16 (remaining gas: 1039987.150 units remaining) - [ (Pair (Pair (Pair 1 2) 3) 4) - 5 ] - - location: 17 (remaining gas: 1039987.140 units remaining) - [ (Pair (Pair 1 2) 3) - 4 - 5 ] - - location: 18 (remaining gas: 1039987.130 units remaining) - [ (Pair 1 2) - 3 - 4 - 5 ] - - location: 19 (remaining gas: 1039987.120 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 20 (remaining gas: 1039987.033 units remaining) - [ 5 - 1 - 2 - 3 - 4 ] - - location: 22 (remaining gas: 1039987.018 units remaining) - [ 1 - 2 - 3 - 4 ] - - location: 24 (remaining gas: 1039987.008 units remaining) - [ 2 - 3 - 4 ] - - location: 25 (remaining gas: 1039986.998 units remaining) - [ 3 - 4 ] - - location: 26 (remaining gas: 1039986.988 units remaining) - [ 4 ] - - location: 27 (remaining gas: 1039986.978 units remaining) - [ ] - - location: 22 (remaining gas: 1039986.948 units remaining) - [ 5 ] - - location: 28 (remaining gas: 1039986.933 units remaining) - [ {} - 5 ] - - location: 30 (remaining gas: 1039986.918 units remaining) - [ (Pair {} 5) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out deleted file mode 100644 index 151d7e05c7be..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)] - -storage - (Pair 1 2) -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039990.758 units remaining) - [ (Pair (Pair 1 1) 0 0) ] - - location: 11 (remaining gas: 1039990.748 units remaining) - [ (Pair 1 1) @parameter ] - - location: 12 (remaining gas: 1039990.738 units remaining) - [ 1 - 1 ] - - location: 13 (remaining gas: 1039990.728 units remaining) - [ 1 - 1 - 1 ] - - location: 14 (remaining gas: 1039990.713 units remaining) - [ 1 - 1 ] - - location: 16 (remaining gas: 1039990.658 units remaining) - [ 2 ] - - location: 14 (remaining gas: 1039990.628 units remaining) - [ 1 - 2 ] - - location: 17 (remaining gas: 1039990.613 units remaining) - [ (Pair 1 2) ] - - location: 18 (remaining gas: 1039990.598 units remaining) - [ {} - (Pair 1 2) ] - - location: 20 (remaining gas: 1039990.583 units remaining) - [ (Pair {} 1 2) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out deleted file mode 100644 index 0218b12b4a84..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)] - -storage - (Pair 15 24) -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039990.758 units remaining) - [ (Pair (Pair 15 9) 0 0) ] - - location: 11 (remaining gas: 1039990.748 units remaining) - [ (Pair 15 9) @parameter ] - - location: 12 (remaining gas: 1039990.738 units remaining) - [ 15 - 9 ] - - location: 13 (remaining gas: 1039990.728 units remaining) - [ 15 - 15 - 9 ] - - location: 14 (remaining gas: 1039990.713 units remaining) - [ 15 - 9 ] - - location: 16 (remaining gas: 1039990.658 units remaining) - [ 24 ] - - location: 14 (remaining gas: 1039990.628 units remaining) - [ 15 - 24 ] - - location: 17 (remaining gas: 1039990.613 units remaining) - [ (Pair 15 24) ] - - location: 18 (remaining gas: 1039990.598 units remaining) - [ {} - (Pair 15 24) ] - - location: 20 (remaining gas: 1039990.583 units remaining) - [ (Pair {} 15 24) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out deleted file mode 100644 index 80ff2c6ec1a5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out +++ /dev/null @@ -1,93 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6] - -storage - 6 -emitted operations - -big_map diff - -trace - - location: 15 (remaining gas: 1039986.010 units remaining) - [ (Pair (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) 0) ] - - location: 15 (remaining gas: 1039986 units remaining) - [ (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) @parameter ] - - location: 16 (remaining gas: 1039985.990 units remaining) - [ (Pair (Pair (Pair 1 2) 3) 4) - 5 ] - - location: 17 (remaining gas: 1039985.980 units remaining) - [ (Pair (Pair 1 2) 3) - 4 - 5 ] - - location: 18 (remaining gas: 1039985.970 units remaining) - [ (Pair 1 2) - 3 - 4 - 5 ] - - location: 19 (remaining gas: 1039985.960 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 20 (remaining gas: 1039985.908 units remaining) - [ ] - - location: 23 (remaining gas: 1039985.898 units remaining) - [ 6 ] - - location: 20 (remaining gas: 1039985.873 units remaining) - [ 5 - 6 ] - - location: 20 (remaining gas: 1039985.863 units remaining) - [ 4 - 5 - 6 ] - - location: 20 (remaining gas: 1039985.853 units remaining) - [ 3 - 4 - 5 - 6 ] - - location: 20 (remaining gas: 1039985.843 units remaining) - [ 2 - 3 - 4 - 5 - 6 ] - - location: 20 (remaining gas: 1039985.833 units remaining) - [ 1 - 2 - 3 - 4 - 5 - 6 ] - - location: 20 (remaining gas: 1039985.833 units remaining) - [ 1 - 2 - 3 - 4 - 5 - 6 ] - - location: 26 (remaining gas: 1039985.823 units remaining) - [ 2 - 3 - 4 - 5 - 6 ] - - location: 27 (remaining gas: 1039985.813 units remaining) - [ 3 - 4 - 5 - 6 ] - - location: 28 (remaining gas: 1039985.803 units remaining) - [ 4 - 5 - 6 ] - - location: 29 (remaining gas: 1039985.793 units remaining) - [ 5 - 6 ] - - location: 30 (remaining gas: 1039985.783 units remaining) - [ 6 ] - - location: 31 (remaining gas: 1039985.768 units remaining) - [ {} - 6 ] - - location: 33 (remaining gas: 1039985.753 units remaining) - [ (Pair {} 6) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out deleted file mode 100644 index 3f38b3f3431d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out +++ /dev/null @@ -1,39 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5] - -storage - 5 -emitted operations - -big_map diff - -trace - - location: 15 (remaining gas: 1039990.347 units remaining) - [ (Pair (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) 0) ] - - location: 15 (remaining gas: 1039990.337 units remaining) - [ (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) @parameter ] - - location: 16 (remaining gas: 1039990.327 units remaining) - [ (Pair (Pair (Pair 1 2) 3) 4) - 5 ] - - location: 17 (remaining gas: 1039990.317 units remaining) - [ (Pair (Pair 1 2) 3) - 4 - 5 ] - - location: 18 (remaining gas: 1039990.307 units remaining) - [ (Pair 1 2) - 3 - 4 - 5 ] - - location: 19 (remaining gas: 1039990.297 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 20 (remaining gas: 1039990.227 units remaining) - [ 5 ] - - location: 22 (remaining gas: 1039990.212 units remaining) - [ {} - 5 ] - - location: 24 (remaining gas: 1039990.197 units remaining) - [ (Pair {} 5) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out deleted file mode 100644 index cbcd0a0ddeab..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out +++ /dev/null @@ -1,57 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 15 (remaining gas: 1039987.936 units remaining) - [ (Pair (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) 0) ] - - location: 15 (remaining gas: 1039987.926 units remaining) - [ (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) @parameter ] - - location: 16 (remaining gas: 1039987.916 units remaining) - [ (Pair (Pair (Pair 1 2) 3) 4) - 5 ] - - location: 17 (remaining gas: 1039987.906 units remaining) - [ (Pair (Pair 1 2) 3) - 4 - 5 ] - - location: 18 (remaining gas: 1039987.896 units remaining) - [ (Pair 1 2) - 3 - 4 - 5 ] - - location: 19 (remaining gas: 1039987.886 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 20 (remaining gas: 1039987.799 units remaining) - [ 2 - 3 - 4 - 5 - 1 ] - - location: 22 (remaining gas: 1039987.789 units remaining) - [ 3 - 4 - 5 - 1 ] - - location: 23 (remaining gas: 1039987.779 units remaining) - [ 4 - 5 - 1 ] - - location: 24 (remaining gas: 1039987.769 units remaining) - [ 5 - 1 ] - - location: 25 (remaining gas: 1039987.759 units remaining) - [ 1 ] - - location: 26 (remaining gas: 1039987.744 units remaining) - [ {} - 1 ] - - location: 28 (remaining gas: 1039987.729 units remaining) - [ (Pair {} 1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit].out deleted file mode 100644 index e67663195ffd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit].out +++ /dev/null @@ -1,248 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039951.987 units remaining) - [ (Pair Unit Unit) ] - - location: 7 (remaining gas: 1039951.977 units remaining) - [ ] - - location: 8 (remaining gas: 1039951.967 units remaining) - [ 5 ] - - location: 11 (remaining gas: 1039951.957 units remaining) - [ 4 - 5 ] - - location: 14 (remaining gas: 1039951.947 units remaining) - [ 3 - 4 - 5 ] - - location: 17 (remaining gas: 1039951.937 units remaining) - [ 2 - 3 - 4 - 5 ] - - location: 20 (remaining gas: 1039951.927 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 23 (remaining gas: 1039951.906 units remaining) - [ 1 - 1 - 2 - 3 - 4 - 5 ] - - location: 25 (remaining gas: 1039951.896 units remaining) - [ 1 - 1 - 1 - 2 - 3 - 4 - 5 ] - - location: 30 (remaining gas: 1039951.861 units remaining) - [ 0 - 1 - 2 - 3 - 4 - 5 ] - - location: 31 (remaining gas: 1039951.846 units remaining) - [ True - 1 - 2 - 3 - 4 - 5 ] - - location: 32 (remaining gas: 1039951.836 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 32 (remaining gas: 1039951.821 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 38 (remaining gas: 1039951.799 units remaining) - [ 2 - 1 - 2 - 3 - 4 - 5 ] - - location: 40 (remaining gas: 1039951.789 units remaining) - [ 2 - 2 - 1 - 2 - 3 - 4 - 5 ] - - location: 45 (remaining gas: 1039951.754 units remaining) - [ 0 - 1 - 2 - 3 - 4 - 5 ] - - location: 46 (remaining gas: 1039951.739 units remaining) - [ True - 1 - 2 - 3 - 4 - 5 ] - - location: 47 (remaining gas: 1039951.729 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 47 (remaining gas: 1039951.714 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 53 (remaining gas: 1039951.691 units remaining) - [ 3 - 1 - 2 - 3 - 4 - 5 ] - - location: 55 (remaining gas: 1039951.681 units remaining) - [ 3 - 3 - 1 - 2 - 3 - 4 - 5 ] - - location: 60 (remaining gas: 1039951.646 units remaining) - [ 0 - 1 - 2 - 3 - 4 - 5 ] - - location: 61 (remaining gas: 1039951.631 units remaining) - [ True - 1 - 2 - 3 - 4 - 5 ] - - location: 62 (remaining gas: 1039951.621 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 62 (remaining gas: 1039951.606 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 68 (remaining gas: 1039951.582 units remaining) - [ 4 - 1 - 2 - 3 - 4 - 5 ] - - location: 70 (remaining gas: 1039951.572 units remaining) - [ 4 - 4 - 1 - 2 - 3 - 4 - 5 ] - - location: 75 (remaining gas: 1039951.537 units remaining) - [ 0 - 1 - 2 - 3 - 4 - 5 ] - - location: 76 (remaining gas: 1039951.522 units remaining) - [ True - 1 - 2 - 3 - 4 - 5 ] - - location: 77 (remaining gas: 1039951.512 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 77 (remaining gas: 1039951.497 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 83 (remaining gas: 1039951.472 units remaining) - [ 5 - 1 - 2 - 3 - 4 - 5 ] - - location: 85 (remaining gas: 1039951.462 units remaining) - [ 5 - 5 - 1 - 2 - 3 - 4 - 5 ] - - location: 90 (remaining gas: 1039951.427 units remaining) - [ 0 - 1 - 2 - 3 - 4 - 5 ] - - location: 91 (remaining gas: 1039951.412 units remaining) - [ True - 1 - 2 - 3 - 4 - 5 ] - - location: 92 (remaining gas: 1039951.402 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 92 (remaining gas: 1039951.387 units remaining) - [ 1 - 2 - 3 - 4 - 5 ] - - location: 98 (remaining gas: 1039951.315 units remaining) - [ ] - - location: 100 (remaining gas: 1039951.305 units remaining) - [ Unit ] - - location: 101 (remaining gas: 1039951.290 units remaining) - [ {} - Unit ] - - location: 103 (remaining gas: 1039951.275 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out deleted file mode 100644 index c79f2bac3360..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out +++ /dev/null @@ -1,142 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0)))] - -storage - (Pair (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) -emitted operations - -big_map diff - -trace - - location: 25 (remaining gas: 1039969.963 units remaining) - [ (Pair (Pair -8 2) None None None None) ] - - location: 25 (remaining gas: 1039969.953 units remaining) - [ (Pair -8 2) @parameter ] - - location: 26 (remaining gas: 1039969.943 units remaining) - [ (Pair -8 2) @parameter - (Pair -8 2) @parameter ] - - location: 27 (remaining gas: 1039969.933 units remaining) - [ -8 - 2 - (Pair -8 2) @parameter ] - - location: 28 (remaining gas: 1039969.908 units remaining) - [ 8 - 2 - (Pair -8 2) @parameter ] - - location: 29 (remaining gas: 1039969.893 units remaining) - [ 2 - (Pair -8 2) @parameter ] - - location: 31 (remaining gas: 1039969.868 units remaining) - [ 2 - (Pair -8 2) @parameter ] - - location: 29 (remaining gas: 1039969.838 units remaining) - [ 8 - 2 - (Pair -8 2) @parameter ] - - location: 32 (remaining gas: 1039969.698 units remaining) - [ (Some (Pair 4 0)) - (Pair -8 2) @parameter ] - - location: 33 (remaining gas: 1039969.688 units remaining) - [ (Pair -8 2) @parameter - (Some (Pair 4 0)) ] - - location: 34 (remaining gas: 1039969.678 units remaining) - [ (Pair -8 2) @parameter - (Pair -8 2) @parameter - (Some (Pair 4 0)) ] - - location: 35 (remaining gas: 1039969.668 units remaining) - [ -8 - 2 - (Pair -8 2) @parameter - (Some (Pair 4 0)) ] - - location: 36 (remaining gas: 1039969.643 units remaining) - [ 8 - 2 - (Pair -8 2) @parameter - (Some (Pair 4 0)) ] - - location: 37 (remaining gas: 1039969.503 units remaining) - [ (Some (Pair 4 0)) - (Pair -8 2) @parameter - (Some (Pair 4 0)) ] - - location: 38 (remaining gas: 1039969.493 units remaining) - [ (Pair -8 2) @parameter - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 39 (remaining gas: 1039969.483 units remaining) - [ (Pair -8 2) @parameter - (Pair -8 2) @parameter - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 40 (remaining gas: 1039969.473 units remaining) - [ -8 - 2 - (Pair -8 2) @parameter - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 41 (remaining gas: 1039969.458 units remaining) - [ 2 - (Pair -8 2) @parameter - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 43 (remaining gas: 1039969.433 units remaining) - [ 2 - (Pair -8 2) @parameter - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 41 (remaining gas: 1039969.403 units remaining) - [ -8 - 2 - (Pair -8 2) @parameter - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 44 (remaining gas: 1039969.263 units remaining) - [ (Some (Pair -4 0)) - (Pair -8 2) @parameter - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 45 (remaining gas: 1039969.253 units remaining) - [ (Pair -8 2) @parameter - (Some (Pair -4 0)) - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 46 (remaining gas: 1039969.243 units remaining) - [ -8 - 2 - (Some (Pair -4 0)) - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 47 (remaining gas: 1039969.103 units remaining) - [ (Some (Pair -4 0)) - (Some (Pair -4 0)) - (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 49 (remaining gas: 1039969.055 units remaining) - [ (Some (Pair 4 0)) - (Some (Pair 4 0)) ] - - location: 52 (remaining gas: 1039969.040 units remaining) - [ (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] - - location: 49 (remaining gas: 1039969.015 units remaining) - [ (Some (Pair -4 0)) - (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] - - location: 49 (remaining gas: 1039969.005 units remaining) - [ (Some (Pair -4 0)) - (Some (Pair -4 0)) - (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] - - location: 49 (remaining gas: 1039969.005 units remaining) - [ (Some (Pair -4 0)) - (Some (Pair -4 0)) - (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] - - location: 53 (remaining gas: 1039968.990 units remaining) - [ (Some (Pair -4 0)) - (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] - - location: 55 (remaining gas: 1039968.975 units remaining) - [ (Pair (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] - - location: 53 (remaining gas: 1039968.945 units remaining) - [ (Some (Pair -4 0)) - (Pair (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] - - location: 56 (remaining gas: 1039968.930 units remaining) - [ (Pair (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] - - location: 57 (remaining gas: 1039968.915 units remaining) - [ {} - (Pair (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] - - location: 59 (remaining gas: 1039968.900 units remaining) - [ (Pair {} (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (.3caea50555.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (.3caea50555.out deleted file mode 100644 index 27086e5770e0..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (.3caea50555.out +++ /dev/null @@ -1,142 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1)))] - -storage - (Pair (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) -emitted operations - -big_map diff - -trace - - location: 25 (remaining gas: 1039969.963 units remaining) - [ (Pair (Pair 10 -3) None None None None) ] - - location: 25 (remaining gas: 1039969.953 units remaining) - [ (Pair 10 -3) @parameter ] - - location: 26 (remaining gas: 1039969.943 units remaining) - [ (Pair 10 -3) @parameter - (Pair 10 -3) @parameter ] - - location: 27 (remaining gas: 1039969.933 units remaining) - [ 10 - -3 - (Pair 10 -3) @parameter ] - - location: 28 (remaining gas: 1039969.908 units remaining) - [ 10 - -3 - (Pair 10 -3) @parameter ] - - location: 29 (remaining gas: 1039969.893 units remaining) - [ -3 - (Pair 10 -3) @parameter ] - - location: 31 (remaining gas: 1039969.868 units remaining) - [ 3 - (Pair 10 -3) @parameter ] - - location: 29 (remaining gas: 1039969.838 units remaining) - [ 10 - 3 - (Pair 10 -3) @parameter ] - - location: 32 (remaining gas: 1039969.698 units remaining) - [ (Some (Pair 3 1)) - (Pair 10 -3) @parameter ] - - location: 33 (remaining gas: 1039969.688 units remaining) - [ (Pair 10 -3) @parameter - (Some (Pair 3 1)) ] - - location: 34 (remaining gas: 1039969.678 units remaining) - [ (Pair 10 -3) @parameter - (Pair 10 -3) @parameter - (Some (Pair 3 1)) ] - - location: 35 (remaining gas: 1039969.668 units remaining) - [ 10 - -3 - (Pair 10 -3) @parameter - (Some (Pair 3 1)) ] - - location: 36 (remaining gas: 1039969.643 units remaining) - [ 10 - -3 - (Pair 10 -3) @parameter - (Some (Pair 3 1)) ] - - location: 37 (remaining gas: 1039969.503 units remaining) - [ (Some (Pair -3 1)) - (Pair 10 -3) @parameter - (Some (Pair 3 1)) ] - - location: 38 (remaining gas: 1039969.493 units remaining) - [ (Pair 10 -3) @parameter - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 39 (remaining gas: 1039969.483 units remaining) - [ (Pair 10 -3) @parameter - (Pair 10 -3) @parameter - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 40 (remaining gas: 1039969.473 units remaining) - [ 10 - -3 - (Pair 10 -3) @parameter - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 41 (remaining gas: 1039969.458 units remaining) - [ -3 - (Pair 10 -3) @parameter - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 43 (remaining gas: 1039969.433 units remaining) - [ 3 - (Pair 10 -3) @parameter - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 41 (remaining gas: 1039969.403 units remaining) - [ 10 - 3 - (Pair 10 -3) @parameter - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 44 (remaining gas: 1039969.263 units remaining) - [ (Some (Pair 3 1)) - (Pair 10 -3) @parameter - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 45 (remaining gas: 1039969.253 units remaining) - [ (Pair 10 -3) @parameter - (Some (Pair 3 1)) - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 46 (remaining gas: 1039969.243 units remaining) - [ 10 - -3 - (Some (Pair 3 1)) - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 47 (remaining gas: 1039969.103 units remaining) - [ (Some (Pair -3 1)) - (Some (Pair 3 1)) - (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 49 (remaining gas: 1039969.055 units remaining) - [ (Some (Pair -3 1)) - (Some (Pair 3 1)) ] - - location: 52 (remaining gas: 1039969.040 units remaining) - [ (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] - - location: 49 (remaining gas: 1039969.015 units remaining) - [ (Some (Pair 3 1)) - (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] - - location: 49 (remaining gas: 1039969.005 units remaining) - [ (Some (Pair -3 1)) - (Some (Pair 3 1)) - (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] - - location: 49 (remaining gas: 1039969.005 units remaining) - [ (Some (Pair -3 1)) - (Some (Pair 3 1)) - (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] - - location: 53 (remaining gas: 1039968.990 units remaining) - [ (Some (Pair 3 1)) - (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] - - location: 55 (remaining gas: 1039968.975 units remaining) - [ (Pair (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] - - location: 53 (remaining gas: 1039968.945 units remaining) - [ (Some (Pair -3 1)) - (Pair (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] - - location: 56 (remaining gas: 1039968.930 units remaining) - [ (Pair (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] - - location: 57 (remaining gas: 1039968.915 units remaining) - [ {} - (Pair (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] - - location: 59 (remaining gas: 1039968.900 units remaining) - [ (Pair {} (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair No.f9448c04fb.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair No.f9448c04fb.out deleted file mode 100644 index 6051aaea92a3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair No.f9448c04fb.out +++ /dev/null @@ -1,142 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair None None None None)] - -storage - (Pair None None None None) -emitted operations - -big_map diff - -trace - - location: 25 (remaining gas: 1039969.963 units remaining) - [ (Pair (Pair 10 0) None None None None) ] - - location: 25 (remaining gas: 1039969.953 units remaining) - [ (Pair 10 0) @parameter ] - - location: 26 (remaining gas: 1039969.943 units remaining) - [ (Pair 10 0) @parameter - (Pair 10 0) @parameter ] - - location: 27 (remaining gas: 1039969.933 units remaining) - [ 10 - 0 - (Pair 10 0) @parameter ] - - location: 28 (remaining gas: 1039969.908 units remaining) - [ 10 - 0 - (Pair 10 0) @parameter ] - - location: 29 (remaining gas: 1039969.893 units remaining) - [ 0 - (Pair 10 0) @parameter ] - - location: 31 (remaining gas: 1039969.868 units remaining) - [ 0 - (Pair 10 0) @parameter ] - - location: 29 (remaining gas: 1039969.838 units remaining) - [ 10 - 0 - (Pair 10 0) @parameter ] - - location: 32 (remaining gas: 1039969.698 units remaining) - [ None - (Pair 10 0) @parameter ] - - location: 33 (remaining gas: 1039969.688 units remaining) - [ (Pair 10 0) @parameter - None ] - - location: 34 (remaining gas: 1039969.678 units remaining) - [ (Pair 10 0) @parameter - (Pair 10 0) @parameter - None ] - - location: 35 (remaining gas: 1039969.668 units remaining) - [ 10 - 0 - (Pair 10 0) @parameter - None ] - - location: 36 (remaining gas: 1039969.643 units remaining) - [ 10 - 0 - (Pair 10 0) @parameter - None ] - - location: 37 (remaining gas: 1039969.503 units remaining) - [ None - (Pair 10 0) @parameter - None ] - - location: 38 (remaining gas: 1039969.493 units remaining) - [ (Pair 10 0) @parameter - None - None ] - - location: 39 (remaining gas: 1039969.483 units remaining) - [ (Pair 10 0) @parameter - (Pair 10 0) @parameter - None - None ] - - location: 40 (remaining gas: 1039969.473 units remaining) - [ 10 - 0 - (Pair 10 0) @parameter - None - None ] - - location: 41 (remaining gas: 1039969.458 units remaining) - [ 0 - (Pair 10 0) @parameter - None - None ] - - location: 43 (remaining gas: 1039969.433 units remaining) - [ 0 - (Pair 10 0) @parameter - None - None ] - - location: 41 (remaining gas: 1039969.403 units remaining) - [ 10 - 0 - (Pair 10 0) @parameter - None - None ] - - location: 44 (remaining gas: 1039969.263 units remaining) - [ None - (Pair 10 0) @parameter - None - None ] - - location: 45 (remaining gas: 1039969.253 units remaining) - [ (Pair 10 0) @parameter - None - None - None ] - - location: 46 (remaining gas: 1039969.243 units remaining) - [ 10 - 0 - None - None - None ] - - location: 47 (remaining gas: 1039969.103 units remaining) - [ None - None - None - None ] - - location: 49 (remaining gas: 1039969.055 units remaining) - [ None - None ] - - location: 52 (remaining gas: 1039969.040 units remaining) - [ (Pair None None) ] - - location: 49 (remaining gas: 1039969.015 units remaining) - [ None - (Pair None None) ] - - location: 49 (remaining gas: 1039969.005 units remaining) - [ None - None - (Pair None None) ] - - location: 49 (remaining gas: 1039969.005 units remaining) - [ None - None - (Pair None None) ] - - location: 53 (remaining gas: 1039968.990 units remaining) - [ None - (Pair None None) ] - - location: 55 (remaining gas: 1039968.975 units remaining) - [ (Pair None None None) ] - - location: 53 (remaining gas: 1039968.945 units remaining) - [ None - (Pair None None None) ] - - location: 56 (remaining gas: 1039968.930 units remaining) - [ (Pair None None None None) ] - - location: 57 (remaining gas: 1039968.915 units remaining) - [ {} - (Pair None None None None) ] - - location: 59 (remaining gas: 1039968.900 units remaining) - [ (Pair {} None None None None) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)].out deleted file mode 100644 index b31a4a4d5a4f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)] - -storage - (Left None) -emitted operations - -big_map diff - -trace - - location: 19 (remaining gas: 1039981.901 units remaining) - [ (Pair (Pair 10 (Left 0)) (Left None)) ] - - location: 19 (remaining gas: 1039981.891 units remaining) - [ (Pair 10 (Left 0)) @parameter ] - - location: 20 (remaining gas: 1039981.881 units remaining) - [ 10 - (Left 0) ] - - location: 21 (remaining gas: 1039981.871 units remaining) - [ (Left 0) - 10 ] - - location: 22 (remaining gas: 1039981.861 units remaining) - [ 0 - 10 ] - - location: 24 (remaining gas: 1039981.851 units remaining) - [ 10 - 0 ] - - location: 25 (remaining gas: 1039981.711 units remaining) - [ None ] - - location: 26 (remaining gas: 1039981.696 units remaining) - [ (Left None) ] - - location: 22 (remaining gas: 1039981.681 units remaining) - [ (Left None) ] - - location: 39 (remaining gas: 1039981.666 units remaining) - [ {} - (Left None) ] - - location: 41 (remaining gas: 1039981.651 units remaining) - [ (Pair {} (Left None)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (So.f782cc1dec.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (So.f782cc1dec.out deleted file mode 100644 index bc587cb24256..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (So.f782cc1dec.out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (Some (Pair 1 0)))] - -storage - (Left (Some (Pair 1 0))) -emitted operations - -big_map diff - -trace - - location: 19 (remaining gas: 1039981.901 units remaining) - [ (Pair (Pair 10 (Left 10)) (Left None)) ] - - location: 19 (remaining gas: 1039981.891 units remaining) - [ (Pair 10 (Left 10)) @parameter ] - - location: 20 (remaining gas: 1039981.881 units remaining) - [ 10 - (Left 10) ] - - location: 21 (remaining gas: 1039981.871 units remaining) - [ (Left 10) - 10 ] - - location: 22 (remaining gas: 1039981.861 units remaining) - [ 10 - 10 ] - - location: 24 (remaining gas: 1039981.851 units remaining) - [ 10 - 10 ] - - location: 25 (remaining gas: 1039981.711 units remaining) - [ (Some (Pair 1 0)) ] - - location: 26 (remaining gas: 1039981.696 units remaining) - [ (Left (Some (Pair 1 0))) ] - - location: 22 (remaining gas: 1039981.681 units remaining) - [ (Left (Some (Pair 1 0))) ] - - location: 39 (remaining gas: 1039981.666 units remaining) - [ {} - (Left (Some (Pair 1 0))) ] - - location: 41 (remaining gas: 1039981.651 units remaining) - [ (Pair {} (Left (Some (Pair 1 0)))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Som.016b4db96c.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Som.016b4db96c.out deleted file mode 100644 index 45bb02f14157..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Som.016b4db96c.out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Some (Pair 3 1)))] - -storage - (Left (Some (Pair 3 1))) -emitted operations - -big_map diff - -trace - - location: 19 (remaining gas: 1039981.901 units remaining) - [ (Pair (Pair 10 (Left 3)) (Left None)) ] - - location: 19 (remaining gas: 1039981.891 units remaining) - [ (Pair 10 (Left 3)) @parameter ] - - location: 20 (remaining gas: 1039981.881 units remaining) - [ 10 - (Left 3) ] - - location: 21 (remaining gas: 1039981.871 units remaining) - [ (Left 3) - 10 ] - - location: 22 (remaining gas: 1039981.861 units remaining) - [ 3 - 10 ] - - location: 24 (remaining gas: 1039981.851 units remaining) - [ 10 - 3 ] - - location: 25 (remaining gas: 1039981.711 units remaining) - [ (Some (Pair 3 1)) ] - - location: 26 (remaining gas: 1039981.696 units remaining) - [ (Left (Some (Pair 3 1))) ] - - location: 22 (remaining gas: 1039981.681 units remaining) - [ (Left (Some (Pair 3 1))) ] - - location: 39 (remaining gas: 1039981.666 units remaining) - [ {} - (Left (Some (Pair 3 1))) ] - - location: 41 (remaining gas: 1039981.651 units remaining) - [ (Pair {} (Left (Some (Pair 3 1)))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)].out deleted file mode 100644 index 194fa4dc850d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)] - -storage - (Right None) -emitted operations - -big_map diff - -trace - - location: 19 (remaining gas: 1039981.901 units remaining) - [ (Pair (Pair 10 (Right 0)) (Left None)) ] - - location: 19 (remaining gas: 1039981.891 units remaining) - [ (Pair 10 (Right 0)) @parameter ] - - location: 20 (remaining gas: 1039981.881 units remaining) - [ 10 - (Right 0) ] - - location: 21 (remaining gas: 1039981.871 units remaining) - [ (Right 0) - 10 ] - - location: 22 (remaining gas: 1039981.861 units remaining) - [ 0 - 10 ] - - location: 32 (remaining gas: 1039981.851 units remaining) - [ 10 - 0 ] - - location: 33 (remaining gas: 1039981.711 units remaining) - [ None ] - - location: 34 (remaining gas: 1039981.696 units remaining) - [ (Right None) ] - - location: 22 (remaining gas: 1039981.681 units remaining) - [ (Right None) ] - - location: 39 (remaining gas: 1039981.666 units remaining) - [ {} - (Right None) ] - - location: 41 (remaining gas: 1039981.651 units remaining) - [ (Pair {} (Right None)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (.e705a30e07.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (.e705a30e07.out deleted file mode 100644 index 852f89144cce..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (.e705a30e07.out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (Some (Pair 1 0)))] - -storage - (Right (Some (Pair 1 0))) -emitted operations - -big_map diff - -trace - - location: 19 (remaining gas: 1039981.901 units remaining) - [ (Pair (Pair 10 (Right 10)) (Left None)) ] - - location: 19 (remaining gas: 1039981.891 units remaining) - [ (Pair 10 (Right 10)) @parameter ] - - location: 20 (remaining gas: 1039981.881 units remaining) - [ 10 - (Right 10) ] - - location: 21 (remaining gas: 1039981.871 units remaining) - [ (Right 10) - 10 ] - - location: 22 (remaining gas: 1039981.861 units remaining) - [ 10 - 10 ] - - location: 32 (remaining gas: 1039981.851 units remaining) - [ 10 - 10 ] - - location: 33 (remaining gas: 1039981.711 units remaining) - [ (Some (Pair 1 0)) ] - - location: 34 (remaining gas: 1039981.696 units remaining) - [ (Right (Some (Pair 1 0))) ] - - location: 22 (remaining gas: 1039981.681 units remaining) - [ (Right (Some (Pair 1 0))) ] - - location: 39 (remaining gas: 1039981.666 units remaining) - [ {} - (Right (Some (Pair 1 0))) ] - - location: 41 (remaining gas: 1039981.651 units remaining) - [ (Pair {} (Right (Some (Pair 1 0)))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (S.44485eda6a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (S.44485eda6a.out deleted file mode 100644 index d62b27fed57a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (S.44485eda6a.out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (Some (Pair 3 1)))] - -storage - (Right (Some (Pair 3 1))) -emitted operations - -big_map diff - -trace - - location: 19 (remaining gas: 1039981.901 units remaining) - [ (Pair (Pair 10 (Right 3)) (Left None)) ] - - location: 19 (remaining gas: 1039981.891 units remaining) - [ (Pair 10 (Right 3)) @parameter ] - - location: 20 (remaining gas: 1039981.881 units remaining) - [ 10 - (Right 3) ] - - location: 21 (remaining gas: 1039981.871 units remaining) - [ (Right 3) - 10 ] - - location: 22 (remaining gas: 1039981.861 units remaining) - [ 3 - 10 ] - - location: 32 (remaining gas: 1039981.851 units remaining) - [ 10 - 3 ] - - location: 33 (remaining gas: 1039981.711 units remaining) - [ (Some (Pair 3 1)) ] - - location: 34 (remaining gas: 1039981.696 units remaining) - [ (Right (Some (Pair 3 1))) ] - - location: 22 (remaining gas: 1039981.681 units remaining) - [ (Right (Some (Pair 3 1))) ] - - location: 39 (remaining gas: 1039981.666 units remaining) - [ {} - (Right (Some (Pair 3 1))) ] - - location: 41 (remaining gas: 1039981.651 units remaining) - [ (Pair {} (Right (Some (Pair 3 1)))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (S.8ab987af15.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (S.8ab987af15.out deleted file mode 100644 index 8d96cfab11c5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (S.8ab987af15.out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (Some (Pair 0 5)))] - -storage - (Right (Some (Pair 0 5))) -emitted operations - -big_map diff - -trace - - location: 19 (remaining gas: 1039981.901 units remaining) - [ (Pair (Pair 5 (Right 10)) (Left None)) ] - - location: 19 (remaining gas: 1039981.891 units remaining) - [ (Pair 5 (Right 10)) @parameter ] - - location: 20 (remaining gas: 1039981.881 units remaining) - [ 5 - (Right 10) ] - - location: 21 (remaining gas: 1039981.871 units remaining) - [ (Right 10) - 5 ] - - location: 22 (remaining gas: 1039981.861 units remaining) - [ 10 - 5 ] - - location: 32 (remaining gas: 1039981.851 units remaining) - [ 5 - 10 ] - - location: 33 (remaining gas: 1039981.711 units remaining) - [ (Some (Pair 0 5)) ] - - location: 34 (remaining gas: 1039981.696 units remaining) - [ (Right (Some (Pair 0 5))) ] - - location: 22 (remaining gas: 1039981.681 units remaining) - [ (Right (Some (Pair 0 5))) ] - - location: 39 (remaining gas: 1039981.666 units remaining) - [ {} - (Right (Some (Pair 0 5))) ] - - location: 41 (remaining gas: 1039981.651 units remaining) - [ (Pair {} (Right (Some (Pair 0 5)))) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt \"hello\" \"world\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt \"hello\" \"world\" }].out" deleted file mode 100644 index 469a5d0f99ec..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt \"hello\" \"world\" }].out" +++ /dev/null @@ -1,33 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt "hello" "world" }] - -storage - { Elt "hello" "world" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039989.971 units remaining) - [ (Pair Unit {}) ] - - location: 9 (remaining gas: 1039989.961 units remaining) - [ ] - - location: 10 (remaining gas: 1039989.741 units remaining) - [ {} ] - - location: 13 (remaining gas: 1039989.731 units remaining) - [ "world" - {} ] - - location: 16 (remaining gas: 1039989.716 units remaining) - [ (Some "world") - {} ] - - location: 17 (remaining gas: 1039989.706 units remaining) - [ "hello" - (Some "world") - {} ] - - location: 20 (remaining gas: 1039989.556 units remaining) - [ { Elt "hello" "world" } ] - - location: 21 (remaining gas: 1039989.541 units remaining) - [ {} - { Elt "hello" "world" } ] - - location: 23 (remaining gas: 1039989.526 units remaining) - [ (Pair {} { Elt "hello" "world" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" deleted file mode 100644 index 980d5ed568b5..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" +++ /dev/null @@ -1,48 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[exec_concat.tz-"?"-""-"_abc"] - -storage - "_abc" -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039987.134 units remaining) - [ (Pair "" "?") ] - - location: 7 (remaining gas: 1039987.124 units remaining) - [ "" @parameter ] - - location: 8 (remaining gas: 1039987.114 units remaining) - [ { PUSH string "_abc" ; NIL string ; SWAP ; CONS ; SWAP ; CONS ; CONCAT } - "" @parameter ] - - location: 22 (remaining gas: 1039987.104 units remaining) - [ "" @parameter - { PUSH string "_abc" ; NIL string ; SWAP ; CONS ; SWAP ; CONS ; CONCAT } ] - - location: 12 (remaining gas: 1039987.094 units remaining) - [ "_abc" - "" @arg ] - - location: 15 (remaining gas: 1039987.079 units remaining) - [ {} - "_abc" - "" @arg ] - - location: 17 (remaining gas: 1039987.069 units remaining) - [ "_abc" - {} - "" @arg ] - - location: 18 (remaining gas: 1039987.054 units remaining) - [ { "_abc" } - "" @arg ] - - location: 19 (remaining gas: 1039987.044 units remaining) - [ "" @arg - { "_abc" } ] - - location: 20 (remaining gas: 1039987.029 units remaining) - [ { "" ; "_abc" } ] - - location: 21 (remaining gas: 1039986.909 units remaining) - [ "_abc" ] - - location: 23 (remaining gas: 1039986.879 units remaining) - [ "_abc" ] - - location: 24 (remaining gas: 1039986.864 units remaining) - [ {} - "_abc" ] - - location: 26 (remaining gas: 1039986.849 units remaining) - [ (Pair {} "_abc") ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"test\"-\"test_abc\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"test\"-\"test_abc\"].out" deleted file mode 100644 index aaa9c79f9c28..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"test\"-\"test_abc\"].out" +++ /dev/null @@ -1,48 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[exec_concat.tz-"?"-"test"-"test_abc"] - -storage - "test_abc" -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039987.094 units remaining) - [ (Pair "test" "?") ] - - location: 7 (remaining gas: 1039987.084 units remaining) - [ "test" @parameter ] - - location: 8 (remaining gas: 1039987.074 units remaining) - [ { PUSH string "_abc" ; NIL string ; SWAP ; CONS ; SWAP ; CONS ; CONCAT } - "test" @parameter ] - - location: 22 (remaining gas: 1039987.064 units remaining) - [ "test" @parameter - { PUSH string "_abc" ; NIL string ; SWAP ; CONS ; SWAP ; CONS ; CONCAT } ] - - location: 12 (remaining gas: 1039987.054 units remaining) - [ "_abc" - "test" @arg ] - - location: 15 (remaining gas: 1039987.039 units remaining) - [ {} - "_abc" - "test" @arg ] - - location: 17 (remaining gas: 1039987.029 units remaining) - [ "_abc" - {} - "test" @arg ] - - location: 18 (remaining gas: 1039987.014 units remaining) - [ { "_abc" } - "test" @arg ] - - location: 19 (remaining gas: 1039987.004 units remaining) - [ "test" @arg - { "_abc" } ] - - location: 20 (remaining gas: 1039986.989 units remaining) - [ { "test" ; "_abc" } ] - - location: 21 (remaining gas: 1039986.869 units remaining) - [ "test_abc" ] - - location: 23 (remaining gas: 1039986.839 units remaining) - [ "test_abc" ] - - location: 24 (remaining gas: 1039986.824 units remaining) - [ {} - "test_abc" ] - - location: 26 (remaining gas: 1039986.809 units remaining) - [ (Pair {} "test_abc") ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out deleted file mode 100644 index 655c0f3109a4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039991.033 units remaining) - [ (Pair { 1 ; 2 ; 3 ; 4 } 111) ] - - location: 8 (remaining gas: 1039991.023 units remaining) - [ { 1 ; 2 ; 3 ; 4 } @parameter ] - - location: 9 (remaining gas: 1039991.013 units remaining) - [ 1 @parameter.hd - { 2 ; 3 ; 4 } @parameter.tl ] - - location: 11 (remaining gas: 1039990.998 units remaining) - [ { 2 ; 3 ; 4 } @parameter.tl ] - - location: 13 (remaining gas: 1039990.988 units remaining) - [ ] - - location: 11 (remaining gas: 1039990.958 units remaining) - [ 1 @parameter.hd ] - - location: 9 (remaining gas: 1039990.943 units remaining) - [ 1 @parameter.hd ] - - location: 18 (remaining gas: 1039990.928 units remaining) - [ {} - 1 @parameter.hd ] - - location: 20 (remaining gas: 1039990.913 units remaining) - [ (Pair {} 1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4].out deleted file mode 100644 index cc7dd42f5d6b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4] - -storage - 4 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039991.333 units remaining) - [ (Pair { 4 } 111) ] - - location: 8 (remaining gas: 1039991.323 units remaining) - [ { 4 } @parameter ] - - location: 9 (remaining gas: 1039991.313 units remaining) - [ 4 @parameter.hd - {} @parameter.tl ] - - location: 11 (remaining gas: 1039991.298 units remaining) - [ {} @parameter.tl ] - - location: 13 (remaining gas: 1039991.288 units remaining) - [ ] - - location: 11 (remaining gas: 1039991.258 units remaining) - [ 4 @parameter.hd ] - - location: 9 (remaining gas: 1039991.243 units remaining) - [ 4 @parameter.hd ] - - location: 18 (remaining gas: 1039991.228 units remaining) - [ {} - 4 @parameter.hd ] - - location: 20 (remaining gas: 1039991.213 units remaining) - [ (Pair {} 4) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-\"hello\"-(Pair .161d86cef6.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-\"hello\"-(Pair .161d86cef6.out" deleted file mode 100644 index 9d02b880505d..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-\"hello\"-(Pair .161d86cef6.out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-"hello"-(Pair None { Elt "hello" 4 })] - -storage - (Pair None { Elt "hello" 4 }) -emitted operations - -big_map diff - -trace - - location: 13 (remaining gas: 1039989.746 units remaining) - [ (Pair "hello" (Some 4) {}) ] - - location: 13 (remaining gas: 1039989.736 units remaining) - [ "hello" @parameter - (Pair (Some 4) {}) @storage ] - - location: 14 (remaining gas: 1039989.721 units remaining) - [ (Pair (Some 4) {}) @storage ] - - location: 16 (remaining gas: 1039989.711 units remaining) - [ (Some 4) - {} ] - - location: 14 (remaining gas: 1039989.681 units remaining) - [ "hello" @parameter - (Some 4) - {} ] - - location: 17 (remaining gas: 1039989.496 units remaining) - [ None - { Elt "hello" 4 } ] - - location: 18 (remaining gas: 1039989.481 units remaining) - [ (Pair None { Elt "hello" 4 }) ] - - location: 19 (remaining gas: 1039989.466 units remaining) - [ {} - (Pair None { Elt "hello" 4 }) ] - - location: 21 (remaining gas: 1039989.451 units remaining) - [ (Pair {} None { Elt "hello" 4 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).684ab7e326.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).684ab7e326.out" deleted file mode 100644 index 5e6b64ab7d35..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).684ab7e326.out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt "hello" 4 })-"hi"-(Pair None { Elt "hello" 4 ; Elt "hi" 5 })] - -storage - (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) -emitted operations - -big_map diff - -trace - - location: 13 (remaining gas: 1039989.362 units remaining) - [ (Pair "hi" (Some 5) { Elt "hello" 4 }) ] - - location: 13 (remaining gas: 1039989.352 units remaining) - [ "hi" @parameter - (Pair (Some 5) { Elt "hello" 4 }) @storage ] - - location: 14 (remaining gas: 1039989.337 units remaining) - [ (Pair (Some 5) { Elt "hello" 4 }) @storage ] - - location: 16 (remaining gas: 1039989.327 units remaining) - [ (Some 5) - { Elt "hello" 4 } ] - - location: 14 (remaining gas: 1039989.297 units remaining) - [ "hi" @parameter - (Some 5) - { Elt "hello" 4 } ] - - location: 17 (remaining gas: 1039989.007 units remaining) - [ None - { Elt "hello" 4 ; Elt "hi" 5 } ] - - location: 18 (remaining gas: 1039988.992 units remaining) - [ (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) ] - - location: 19 (remaining gas: 1039988.977 units remaining) - [ {} - (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) ] - - location: 21 (remaining gas: 1039988.962 units remaining) - [ (Pair {} None { Elt "hello" 4 ; Elt "hi" 5 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).d49817fb83.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).d49817fb83.out" deleted file mode 100644 index 8a4671f44a82..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).d49817fb83.out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt "hello" 4 })-"hello"-(Pair (Some 4) { Elt "hello" 5 })] - -storage - (Pair (Some 4) { Elt "hello" 5 }) -emitted operations - -big_map diff - -trace - - location: 13 (remaining gas: 1039989.332 units remaining) - [ (Pair "hello" (Some 5) { Elt "hello" 4 }) ] - - location: 13 (remaining gas: 1039989.322 units remaining) - [ "hello" @parameter - (Pair (Some 5) { Elt "hello" 4 }) @storage ] - - location: 14 (remaining gas: 1039989.307 units remaining) - [ (Pair (Some 5) { Elt "hello" 4 }) @storage ] - - location: 16 (remaining gas: 1039989.297 units remaining) - [ (Some 5) - { Elt "hello" 4 } ] - - location: 14 (remaining gas: 1039989.267 units remaining) - [ "hello" @parameter - (Some 5) - { Elt "hello" 4 } ] - - location: 17 (remaining gas: 1039988.977 units remaining) - [ (Some 4) - { Elt "hello" 5 } ] - - location: 18 (remaining gas: 1039988.962 units remaining) - [ (Pair (Some 4) { Elt "hello" 5 }) ] - - location: 19 (remaining gas: 1039988.947 units remaining) - [ {} - (Pair (Some 4) { Elt "hello" 5 }) ] - - location: 21 (remaining gas: 1039988.932 units remaining) - [ (Pair {} (Some 4) { Elt "hello" 5 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .6900b1da14.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .6900b1da14.out" deleted file mode 100644 index f16ee1ae16ba..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .6900b1da14.out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt "1" 1 ; Elt "2" 2 })-"1"-(Pair (Some 1) { Elt "2" 2 })1] - -storage - (Pair (Some 1) { Elt "2" 2 }) -emitted operations - -big_map diff - -trace - - location: 13 (remaining gas: 1039989.033 units remaining) - [ (Pair "1" None { Elt "1" 1 ; Elt "2" 2 }) ] - - location: 13 (remaining gas: 1039989.023 units remaining) - [ "1" @parameter - (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] - - location: 14 (remaining gas: 1039989.008 units remaining) - [ (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] - - location: 16 (remaining gas: 1039988.998 units remaining) - [ None - { Elt "1" 1 ; Elt "2" 2 } ] - - location: 14 (remaining gas: 1039988.968 units remaining) - [ "1" @parameter - None - { Elt "1" 1 ; Elt "2" 2 } ] - - location: 17 (remaining gas: 1039988.573 units remaining) - [ (Some 1) - { Elt "2" 2 } ] - - location: 18 (remaining gas: 1039988.558 units remaining) - [ (Pair (Some 1) { Elt "2" 2 }) ] - - location: 19 (remaining gas: 1039988.543 units remaining) - [ {} - (Pair (Some 1) { Elt "2" 2 }) ] - - location: 21 (remaining gas: 1039988.528 units remaining) - [ (Pair {} (Some 1) { Elt "2" 2 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .bca0ede8be.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .bca0ede8be.out" deleted file mode 100644 index 8e3e8d6dde08..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .bca0ede8be.out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt "1" 1 ; Elt "2" 2 })-"1"-(Pair (Some 1) { Elt "2" 2 })0] - -storage - (Pair (Some 1) { Elt "2" 2 }) -emitted operations - -big_map diff - -trace - - location: 13 (remaining gas: 1039989.033 units remaining) - [ (Pair "1" None { Elt "1" 1 ; Elt "2" 2 }) ] - - location: 13 (remaining gas: 1039989.023 units remaining) - [ "1" @parameter - (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] - - location: 14 (remaining gas: 1039989.008 units remaining) - [ (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] - - location: 16 (remaining gas: 1039988.998 units remaining) - [ None - { Elt "1" 1 ; Elt "2" 2 } ] - - location: 14 (remaining gas: 1039988.968 units remaining) - [ "1" @parameter - None - { Elt "1" 1 ; Elt "2" 2 } ] - - location: 17 (remaining gas: 1039988.573 units remaining) - [ (Some 1) - { Elt "2" 2 } ] - - location: 18 (remaining gas: 1039988.558 units remaining) - [ (Pair (Some 1) { Elt "2" 2 }) ] - - location: 19 (remaining gas: 1039988.543 units remaining) - [ {} - (Pair (Some 1) { Elt "2" 2 }) ] - - location: 21 (remaining gas: 1039988.528 units remaining) - [ (Pair {} (Some 1) { Elt "2" 2 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" deleted file mode 100644 index e91a6ddb38db..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt "hello" 4 })-"hello"-(Pair (Some 4) {})] - -storage - (Pair (Some 4) {}) -emitted operations - -big_map diff - -trace - - location: 13 (remaining gas: 1039989.432 units remaining) - [ (Pair "hello" None { Elt "hello" 4 }) ] - - location: 13 (remaining gas: 1039989.422 units remaining) - [ "hello" @parameter - (Pair None { Elt "hello" 4 }) @storage ] - - location: 14 (remaining gas: 1039989.407 units remaining) - [ (Pair None { Elt "hello" 4 }) @storage ] - - location: 16 (remaining gas: 1039989.397 units remaining) - [ None - { Elt "hello" 4 } ] - - location: 14 (remaining gas: 1039989.367 units remaining) - [ "hello" @parameter - None - { Elt "hello" 4 } ] - - location: 17 (remaining gas: 1039989.077 units remaining) - [ (Some 4) - {} ] - - location: 18 (remaining gas: 1039989.062 units remaining) - [ (Pair (Some 4) {}) ] - - location: 19 (remaining gas: 1039989.047 units remaining) - [ {} - (Pair (Some 4) {}) ] - - location: 21 (remaining gas: 1039989.032 units remaining) - [ (Pair {} (Some 4) {}) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-\"hello\"-(Pair None {})].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-\"hello\"-(Pair None {})].out" deleted file mode 100644 index a393b2da07f7..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-\"hello\"-(Pair None {})].out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-"hello"-(Pair None {})] - -storage - (Pair None {}) -emitted operations - -big_map diff - -trace - - location: 13 (remaining gas: 1039989.846 units remaining) - [ (Pair "hello" None {}) ] - - location: 13 (remaining gas: 1039989.836 units remaining) - [ "hello" @parameter - (Pair None {}) @storage ] - - location: 14 (remaining gas: 1039989.821 units remaining) - [ (Pair None {}) @storage ] - - location: 16 (remaining gas: 1039989.811 units remaining) - [ None - {} ] - - location: 14 (remaining gas: 1039989.781 units remaining) - [ "hello" @parameter - None - {} ] - - location: 17 (remaining gas: 1039989.596 units remaining) - [ None - {} ] - - location: 18 (remaining gas: 1039989.581 units remaining) - [ (Pair None {}) ] - - location: 19 (remaining gas: 1039989.566 units remaining) - [ {} - (Pair None {}) ] - - location: 21 (remaining gas: 1039989.551 units remaining) - [ (Pair {} None {}) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"1\" \"one\" ; .bc4127094e.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"1\" \"one\" ; .bc4127094e.out" deleted file mode 100644 index f32bf7eea1b3..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"1\" \"one\" ; .bc4127094e.out" +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt "1" "one" ; Elt "2" "two" })-"1"-(Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" })] - -storage - (Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" }) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039986.547 units remaining) - [ (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) ] - - location: 12 (remaining gas: 1039986.537 units remaining) - [ (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) - (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) ] - - location: 13 (remaining gas: 1039986.527 units remaining) - [ "1" @parameter - (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) ] - - location: 14 (remaining gas: 1039986.512 units remaining) - [ (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) ] - - location: 17 (remaining gas: 1039986.502 units remaining) - [ (Pair None { Elt "1" "one" ; Elt "2" "two" }) @storage ] - - location: 18 (remaining gas: 1039986.492 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } ] - - location: 19 (remaining gas: 1039986.482 units remaining) - [ { Elt "1" "one" ; Elt "2" "two" } - { Elt "1" "one" ; Elt "2" "two" } ] - - location: 14 (remaining gas: 1039986.452 units remaining) - [ "1" @parameter - { Elt "1" "one" ; Elt "2" "two" } - { Elt "1" "one" ; Elt "2" "two" } ] - - location: 20 (remaining gas: 1039986.267 units remaining) - [ (Some "one") - { Elt "1" "one" ; Elt "2" "two" } ] - - location: 21 (remaining gas: 1039986.252 units remaining) - [ (Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" }) ] - - location: 22 (remaining gas: 1039986.237 units remaining) - [ {} - (Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" }) ] - - location: 24 (remaining gas: 1039986.222 units remaining) - [ (Pair {} (Some "one") { Elt "1" "one" ; Elt "2" "two" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"\"-(P.0c03056487.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"\"-(P.0c03056487.out" deleted file mode 100644 index 46f19946b29a..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"\"-(P.0c03056487.out" +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt "hello" "hi" })-""-(Pair None { Elt "hello" "hi" })] - -storage - (Pair None { Elt "hello" "hi" }) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039987.050 units remaining) - [ (Pair "" None { Elt "hello" "hi" }) ] - - location: 12 (remaining gas: 1039987.040 units remaining) - [ (Pair "" None { Elt "hello" "hi" }) - (Pair "" None { Elt "hello" "hi" }) ] - - location: 13 (remaining gas: 1039987.030 units remaining) - [ "" @parameter - (Pair "" None { Elt "hello" "hi" }) ] - - location: 14 (remaining gas: 1039987.015 units remaining) - [ (Pair "" None { Elt "hello" "hi" }) ] - - location: 17 (remaining gas: 1039987.005 units remaining) - [ (Pair None { Elt "hello" "hi" }) @storage ] - - location: 18 (remaining gas: 1039986.995 units remaining) - [ { Elt "hello" "hi" } ] - - location: 19 (remaining gas: 1039986.985 units remaining) - [ { Elt "hello" "hi" } - { Elt "hello" "hi" } ] - - location: 14 (remaining gas: 1039986.955 units remaining) - [ "" @parameter - { Elt "hello" "hi" } - { Elt "hello" "hi" } ] - - location: 20 (remaining gas: 1039986.805 units remaining) - [ None - { Elt "hello" "hi" } ] - - location: 21 (remaining gas: 1039986.790 units remaining) - [ (Pair None { Elt "hello" "hi" }) ] - - location: 22 (remaining gas: 1039986.775 units remaining) - [ {} - (Pair None { Elt "hello" "hi" }) ] - - location: 24 (remaining gas: 1039986.760 units remaining) - [ (Pair {} None { Elt "hello" "hi" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"hell.cc45544c66.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"hell.cc45544c66.out" deleted file mode 100644 index c66696c489ec..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"hell.cc45544c66.out" +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt "hello" "hi" })-"hello"-(Pair (Some "hi") { Elt "hello" "hi" })] - -storage - (Pair (Some "hi") { Elt "hello" "hi" }) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039987 units remaining) - [ (Pair "hello" None { Elt "hello" "hi" }) ] - - location: 12 (remaining gas: 1039986.990 units remaining) - [ (Pair "hello" None { Elt "hello" "hi" }) - (Pair "hello" None { Elt "hello" "hi" }) ] - - location: 13 (remaining gas: 1039986.980 units remaining) - [ "hello" @parameter - (Pair "hello" None { Elt "hello" "hi" }) ] - - location: 14 (remaining gas: 1039986.965 units remaining) - [ (Pair "hello" None { Elt "hello" "hi" }) ] - - location: 17 (remaining gas: 1039986.955 units remaining) - [ (Pair None { Elt "hello" "hi" }) @storage ] - - location: 18 (remaining gas: 1039986.945 units remaining) - [ { Elt "hello" "hi" } ] - - location: 19 (remaining gas: 1039986.935 units remaining) - [ { Elt "hello" "hi" } - { Elt "hello" "hi" } ] - - location: 14 (remaining gas: 1039986.905 units remaining) - [ "hello" @parameter - { Elt "hello" "hi" } - { Elt "hello" "hi" } ] - - location: 20 (remaining gas: 1039986.755 units remaining) - [ (Some "hi") - { Elt "hello" "hi" } ] - - location: 21 (remaining gas: 1039986.740 units remaining) - [ (Pair (Some "hi") { Elt "hello" "hi" }) ] - - location: 22 (remaining gas: 1039986.725 units remaining) - [ {} - (Pair (Some "hi") { Elt "hello" "hi" }) ] - - location: 24 (remaining gas: 1039986.710 units remaining) - [ (Pair {} (Some "hi") { Elt "hello" "hi" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" deleted file mode 100644 index 14dcf7cfe34e..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[hash_key.tz-None-"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"-(Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx")] - -storage - (Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039668.957 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" None) ] - - location: 8 (remaining gas: 1039668.947 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @parameter ] - - location: 9 (remaining gas: 1039668.292 units remaining) - [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] - - location: 10 (remaining gas: 1039668.277 units remaining) - [ (Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") ] - - location: 11 (remaining gas: 1039668.262 units remaining) - [ {} - (Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") ] - - location: 13 (remaining gas: 1039668.247 units remaining) - [ (Pair {} (Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" deleted file mode 100644 index 0294665126d5..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[hash_key.tz-None-"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTawUPqR8vZTAMcx61ES"-(Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k")] - -storage - (Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k") -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039668.957 units remaining) - [ (Pair "edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTawUPqR8vZTAMcx61ES" None) ] - - location: 8 (remaining gas: 1039668.947 units remaining) - [ "edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTawUPqR8vZTAMcx61ES" @parameter ] - - location: 9 (remaining gas: 1039668.292 units remaining) - [ "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k" ] - - location: 10 (remaining gas: 1039668.277 units remaining) - [ (Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k") ] - - location: 11 (remaining gas: 1039668.262 units remaining) - [ {} - (Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k") ] - - location: 13 (remaining gas: 1039668.247 units remaining) - [ (Pair {} (Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"12345\"-0xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"12345\"-0xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" deleted file mode 100644 index 5198a93e4cee..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"12345\"-0xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-"12345"-0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f] - -storage - 0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.241 units remaining) - [ (Pair "12345" 0x00) ] - - location: 7 (remaining gas: 1039994.231 units remaining) - [ "12345" @parameter ] - - location: 8 (remaining gas: 1039993.740 units remaining) - [ 0x0501000000053132333435 @parameter.packed ] - - location: 9 (remaining gas: 1039993.298 units remaining) - [ 0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f ] - - location: 10 (remaining gas: 1039993.283 units remaining) - [ {} - 0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f ] - - location: 12 (remaining gas: 1039993.268 units remaining) - [ (Pair {} 0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"abcdefg\"-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"abcdefg\"-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" deleted file mode 100644 index eb69749a8503..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"abcdefg\"-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-"abcdefg"-0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e] - -storage - 0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.221 units remaining) - [ (Pair "abcdefg" 0x00) ] - - location: 7 (remaining gas: 1039994.211 units remaining) - [ "abcdefg" @parameter ] - - location: 8 (remaining gas: 1039993.654 units remaining) - [ 0x05010000000761626364656667 @parameter.packed ] - - location: 9 (remaining gas: 1039993.210 units remaining) - [ 0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e ] - - location: 10 (remaining gas: 1039993.195 units remaining) - [ {} - 0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e ] - - location: 12 (remaining gas: 1039993.180 units remaining) - [ (Pair {} 0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)].out deleted file mode 100644 index c11260cd1903..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)] - -storage - (Some False) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039991.305 units remaining) - [ (Pair False None) ] - - location: 8 (remaining gas: 1039991.295 units remaining) - [ False @parameter ] - - location: 9 (remaining gas: 1039991.285 units remaining) - [ ] - - location: 15 (remaining gas: 1039991.275 units remaining) - [ False ] - - location: 9 (remaining gas: 1039991.260 units remaining) - [ False ] - - location: 18 (remaining gas: 1039991.245 units remaining) - [ (Some False) ] - - location: 19 (remaining gas: 1039991.230 units remaining) - [ {} - (Some False) ] - - location: 21 (remaining gas: 1039991.215 units remaining) - [ (Pair {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)].out deleted file mode 100644 index a588a6adcb03..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039991.305 units remaining) - [ (Pair True None) ] - - location: 8 (remaining gas: 1039991.295 units remaining) - [ True @parameter ] - - location: 9 (remaining gas: 1039991.285 units remaining) - [ ] - - location: 11 (remaining gas: 1039991.275 units remaining) - [ True ] - - location: 9 (remaining gas: 1039991.260 units remaining) - [ True ] - - location: 18 (remaining gas: 1039991.245 units remaining) - [ (Some True) ] - - location: 19 (remaining gas: 1039991.230 units remaining) - [ {} - (Some True) ] - - location: 21 (remaining gas: 1039991.215 units remaining) - [ (Pair {} (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-(Some \"hello\")-\"hello\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-(Some \"hello\")-\"hello\"].out" deleted file mode 100644 index 0ae59ef448d1..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-(Some \"hello\")-\"hello\"].out" +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[if_some.tz-"?"-(Some "hello")-"hello"] - -storage - "hello" -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039992.411 units remaining) - [ (Pair (Some "hello") "?") ] - - location: 8 (remaining gas: 1039992.401 units remaining) - [ (Some "hello") @parameter ] - - location: 10 (remaining gas: 1039992.391 units remaining) - [ "hello" ] - - location: 10 (remaining gas: 1039992.376 units remaining) - [ "hello" ] - - location: 16 (remaining gas: 1039992.361 units remaining) - [ {} - "hello" ] - - location: 18 (remaining gas: 1039992.346 units remaining) - [ (Pair {} "hello") ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-None-\"\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-None-\"\"].out" deleted file mode 100644 index 4303f734550c..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-None-\"\"].out" +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[if_some.tz-"?"-None-""] - -storage - "" -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039992.575 units remaining) - [ (Pair None "?") ] - - location: 8 (remaining gas: 1039992.565 units remaining) - [ None @parameter ] - - location: 10 (remaining gas: 1039992.555 units remaining) - [ ] - - location: 12 (remaining gas: 1039992.545 units remaining) - [ "" ] - - location: 10 (remaining gas: 1039992.530 units remaining) - [ "" ] - - location: 16 (remaining gas: 1039992.515 units remaining) - [ {} - "" ] - - location: 18 (remaining gas: 1039992.500 units remaining) - [ (Pair {} "") ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)].out deleted file mode 100644 index a31049a6db6d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)] - -storage - (Some 0) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.957 units remaining) - [ (Pair 0 None) ] - - location: 8 (remaining gas: 1039993.947 units remaining) - [ 0 @parameter ] - - location: 9 (remaining gas: 1039993.932 units remaining) - [ 0 ] - - location: 10 (remaining gas: 1039993.917 units remaining) - [ (Some 0) ] - - location: 11 (remaining gas: 1039993.902 units remaining) - [ {} - (Some 0) ] - - location: 13 (remaining gas: 1039993.887 units remaining) - [ (Pair {} (Some 0)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)].out deleted file mode 100644 index 3c0cb54e839f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)] - -storage - (Some 1) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.957 units remaining) - [ (Pair 1 None) ] - - location: 8 (remaining gas: 1039993.947 units remaining) - [ 1 @parameter ] - - location: 9 (remaining gas: 1039993.932 units remaining) - [ 1 ] - - location: 10 (remaining gas: 1039993.917 units remaining) - [ (Some 1) ] - - location: 11 (remaining gas: 1039993.902 units remaining) - [ {} - (Some 1) ] - - location: 13 (remaining gas: 1039993.887 units remaining) - [ (Pair {} (Some 1)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)].out deleted file mode 100644 index 8c4d872a7d91..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)] - -storage - (Some 9999) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.957 units remaining) - [ (Pair 9999 None) ] - - location: 8 (remaining gas: 1039993.947 units remaining) - [ 9999 @parameter ] - - location: 9 (remaining gas: 1039993.932 units remaining) - [ 9999 ] - - location: 10 (remaining gas: 1039993.917 units remaining) - [ (Some 9999) ] - - location: 11 (remaining gas: 1039993.902 units remaining) - [ {} - (Some 9999) ] - - location: 13 (remaining gas: 1039993.887 units remaining) - [ (Pair {} (Some 9999)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e.34c02678c9.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e.34c02678c9.out deleted file mode 100644 index 8185a1c3118d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e.34c02678c9.out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4)] - -storage - (Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.957 units remaining) - [ (Pair 0x48656c6c6f2c20776f726c6421 None) ] - - location: 8 (remaining gas: 1039993.947 units remaining) - [ 0x48656c6c6f2c20776f726c6421 @parameter ] - - location: 9 (remaining gas: 1039992.490 units remaining) - [ 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 ] - - location: 10 (remaining gas: 1039992.475 units remaining) - [ (Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4) ] - - location: 11 (remaining gas: 1039992.460 units remaining) - [ {} - (Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4) ] - - location: 13 (remaining gas: 1039992.445 units remaining) - [ (Pair {} - (Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Left True)-(Right True)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Left True)-(Right True)].out" deleted file mode 100644 index 96798c5942bc..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Left True)-(Right True)].out" +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[left_right.tz-(Left "X")-(Left True)-(Right True)] - -storage - (Right True) -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039990.926 units remaining) - [ (Pair (Left True) (Left "X")) ] - - location: 11 (remaining gas: 1039990.916 units remaining) - [ (Left True) @parameter ] - - location: 12 (remaining gas: 1039990.906 units remaining) - [ True @parameter.left ] - - location: 14 (remaining gas: 1039990.891 units remaining) - [ (Right True) ] - - location: 12 (remaining gas: 1039990.876 units remaining) - [ (Right True) ] - - location: 19 (remaining gas: 1039990.861 units remaining) - [ {} - (Right True) ] - - location: 21 (remaining gas: 1039990.846 units remaining) - [ (Pair {} (Right True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Right \"a\")-(Left \"a\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Right \"a\")-(Left \"a\")].out" deleted file mode 100644 index 72695097beb4..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Right \"a\")-(Left \"a\")].out" +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[left_right.tz-(Left "X")-(Right "a")-(Left "a")] - -storage - (Left "a") -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039990.902 units remaining) - [ (Pair (Right "a") (Left "X")) ] - - location: 11 (remaining gas: 1039990.892 units remaining) - [ (Right "a") @parameter ] - - location: 12 (remaining gas: 1039990.882 units remaining) - [ "a" @parameter.right ] - - location: 17 (remaining gas: 1039990.867 units remaining) - [ (Left "a") ] - - location: 12 (remaining gas: 1039990.852 units remaining) - [ (Left "a") ] - - location: 19 (remaining gas: 1039990.837 units remaining) - [ {} - (Left "a") ] - - location: 21 (remaining gas: 1039990.822 units remaining) - [ (Pair {} (Left "a")) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1].out deleted file mode 100644 index 87a3a32e550e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 111) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039994.923 units remaining) - [ 1 @level ] - - location: 9 (remaining gas: 1039994.908 units remaining) - [ {} - 1 @level ] - - location: 11 (remaining gas: 1039994.893 units remaining) - [ (Pair {} 1) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" deleted file mode 100644 index c6a322512a4b..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat.tz-"abc"-{ "d" ; "e" ; "f" }-"abcdef"] - -storage - "abcdef" -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039992.898 units remaining) - [ (Pair { "d" ; "e" ; "f" } "abc") ] - - location: 8 (remaining gas: 1039992.888 units remaining) - [ { "d" ; "e" ; "f" } @parameter - "abc" @storage ] - - location: 9 (remaining gas: 1039992.878 units remaining) - [ "abc" @storage - { "d" ; "e" ; "f" } @parameter ] - - location: 10 (remaining gas: 1039992.863 units remaining) - [ { "abc" ; "d" ; "e" ; "f" } ] - - location: 11 (remaining gas: 1039992.723 units remaining) - [ "abcdef" ] - - location: 12 (remaining gas: 1039992.708 units remaining) - [ {} - "abcdef" ] - - location: 14 (remaining gas: 1039992.693 units remaining) - [ (Pair {} "abcdef") ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{}-\"abc\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{}-\"abc\"].out" deleted file mode 100644 index 61dd6bb056cc..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{}-\"abc\"].out" +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat.tz-"abc"-{}-"abc"] - -storage - "abc" -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.270 units remaining) - [ (Pair {} "abc") ] - - location: 8 (remaining gas: 1039993.260 units remaining) - [ {} @parameter - "abc" @storage ] - - location: 9 (remaining gas: 1039993.250 units remaining) - [ "abc" @storage - {} @parameter ] - - location: 10 (remaining gas: 1039993.235 units remaining) - [ { "abc" } ] - - location: 11 (remaining gas: 1039993.125 units remaining) - [ "abc" ] - - location: 12 (remaining gas: 1039993.110 units remaining) - [ {} - "abc" ] - - location: 14 (remaining gas: 1039993.095 units remaining) - [ (Pair {} "abc") ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out deleted file mode 100644 index eb0c95e7c0ce..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100] - -storage - 0x001100 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.014 units remaining) - [ (Pair { 0x00 ; 0x11 ; 0x00 } 0x) ] - - location: 8 (remaining gas: 1039993.004 units remaining) - [ { 0x00 ; 0x11 ; 0x00 } @parameter - 0x @storage ] - - location: 9 (remaining gas: 1039992.994 units remaining) - [ 0x @storage - { 0x00 ; 0x11 ; 0x00 } @parameter ] - - location: 10 (remaining gas: 1039992.979 units remaining) - [ { 0x ; 0x00 ; 0x11 ; 0x00 } ] - - location: 11 (remaining gas: 1039992.839 units remaining) - [ 0x001100 ] - - location: 12 (remaining gas: 1039992.824 units remaining) - [ {} - 0x001100 ] - - location: 14 (remaining gas: 1039992.809 units remaining) - [ (Pair {} 0x001100) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x].out deleted file mode 100644 index 0c13a3d9c08b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x] - -storage - 0x -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.314 units remaining) - [ (Pair {} 0x) ] - - location: 8 (remaining gas: 1039993.304 units remaining) - [ {} @parameter - 0x @storage ] - - location: 9 (remaining gas: 1039993.294 units remaining) - [ 0x @storage - {} @parameter ] - - location: 10 (remaining gas: 1039993.279 units remaining) - [ { 0x } ] - - location: 11 (remaining gas: 1039993.169 units remaining) - [ 0x ] - - location: 12 (remaining gas: 1039993.154 units remaining) - [ {} - 0x ] - - location: 14 (remaining gas: 1039993.139 units remaining) - [ (Pair {} 0x) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out deleted file mode 100644 index 5262f39f7c17..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00] - -storage - 0x00abcdef00 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.014 units remaining) - [ (Pair { 0xcd ; 0xef ; 0x00 } 0x00ab) ] - - location: 8 (remaining gas: 1039993.004 units remaining) - [ { 0xcd ; 0xef ; 0x00 } @parameter - 0x00ab @storage ] - - location: 9 (remaining gas: 1039992.994 units remaining) - [ 0x00ab @storage - { 0xcd ; 0xef ; 0x00 } @parameter ] - - location: 10 (remaining gas: 1039992.979 units remaining) - [ { 0x00ab ; 0xcd ; 0xef ; 0x00 } ] - - location: 11 (remaining gas: 1039992.839 units remaining) - [ 0x00abcdef00 ] - - location: 12 (remaining gas: 1039992.824 units remaining) - [ {} - 0x00abcdef00 ] - - location: 14 (remaining gas: 1039992.809 units remaining) - [ (Pair {} 0x00abcdef00) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd].out deleted file mode 100644 index bd24f1060b2b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd] - -storage - 0xabcd -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.314 units remaining) - [ (Pair {} 0xabcd) ] - - location: 8 (remaining gas: 1039993.304 units remaining) - [ {} @parameter - 0xabcd @storage ] - - location: 9 (remaining gas: 1039993.294 units remaining) - [ 0xabcd @storage - {} @parameter ] - - location: 10 (remaining gas: 1039993.279 units remaining) - [ { 0xabcd } ] - - location: 11 (remaining gas: 1039993.169 units remaining) - [ 0xabcd ] - - location: 12 (remaining gas: 1039993.154 units remaining) - [ {} - 0xabcd ] - - location: 14 (remaining gas: 1039993.139 units remaining) - [ (Pair {} 0xabcd) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" deleted file mode 100644 index 1f14db663cc8..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id.tz-{""}-{ "1" ; "2" ; "3" }-{ "1" ; "2" ; "3" }] - -storage - { "1" ; "2" ; "3" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039994.539 units remaining) - [ (Pair { "1" ; "2" ; "3" } { "" }) ] - - location: 9 (remaining gas: 1039994.529 units remaining) - [ { "1" ; "2" ; "3" } @parameter ] - - location: 10 (remaining gas: 1039994.514 units remaining) - [ {} - { "1" ; "2" ; "3" } @parameter ] - - location: 12 (remaining gas: 1039994.499 units remaining) - [ (Pair {} { "1" ; "2" ; "3" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" deleted file mode 100644 index 214a4660bd14..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id.tz-{""}-{ "a" ; "b" ; "c" }-{ "a" ; "b" ; "c" }] - -storage - { "a" ; "b" ; "c" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039994.539 units remaining) - [ (Pair { "a" ; "b" ; "c" } { "" }) ] - - location: 9 (remaining gas: 1039994.529 units remaining) - [ { "a" ; "b" ; "c" } @parameter ] - - location: 10 (remaining gas: 1039994.514 units remaining) - [ {} - { "a" ; "b" ; "c" } @parameter ] - - location: 12 (remaining gas: 1039994.499 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{}-{}].out" deleted file mode 100644 index 8e4aeb5bcb20..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{}-{}].out" +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id.tz-{""}-{}-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039994.911 units remaining) - [ (Pair {} { "" }) ] - - location: 9 (remaining gas: 1039994.901 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039994.886 units remaining) - [ {} - {} @parameter ] - - location: 12 (remaining gas: 1039994.871 units remaining) - [ (Pair {} {}) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" deleted file mode 100644 index ee6935c47fcf..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id_map.tz-{""}-{ "1" ; "2" ; "3" }-{ "1" ; "2" ; "3" }] - -storage - { "1" ; "2" ; "3" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039993.518 units remaining) - [ (Pair { "1" ; "2" ; "3" } { "" }) ] - - location: 9 (remaining gas: 1039993.508 units remaining) - [ { "1" ; "2" ; "3" } @parameter ] - - location: 10 (remaining gas: 1039993.508 units remaining) - [ "1" ] - - location: 10 (remaining gas: 1039993.493 units remaining) - [ "2" ] - - location: 10 (remaining gas: 1039993.478 units remaining) - [ "3" ] - - location: 10 (remaining gas: 1039993.463 units remaining) - [ { "1" ; "2" ; "3" } ] - - location: 12 (remaining gas: 1039993.448 units remaining) - [ {} - { "1" ; "2" ; "3" } ] - - location: 14 (remaining gas: 1039993.433 units remaining) - [ (Pair {} { "1" ; "2" ; "3" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" deleted file mode 100644 index 3b1caf6cdff5..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id_map.tz-{""}-{ "a" ; "b" ; "c" }-{ "a" ; "b" ; "c" }] - -storage - { "a" ; "b" ; "c" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039993.518 units remaining) - [ (Pair { "a" ; "b" ; "c" } { "" }) ] - - location: 9 (remaining gas: 1039993.508 units remaining) - [ { "a" ; "b" ; "c" } @parameter ] - - location: 10 (remaining gas: 1039993.508 units remaining) - [ "a" ] - - location: 10 (remaining gas: 1039993.493 units remaining) - [ "b" ] - - location: 10 (remaining gas: 1039993.478 units remaining) - [ "c" ] - - location: 10 (remaining gas: 1039993.463 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 12 (remaining gas: 1039993.448 units remaining) - [ {} - { "a" ; "b" ; "c" } ] - - location: 14 (remaining gas: 1039993.433 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{}-{}].out" deleted file mode 100644 index 58589fde07e1..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{}-{}].out" +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id_map.tz-{""}-{}-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039993.890 units remaining) - [ (Pair {} { "" }) ] - - location: 9 (remaining gas: 1039993.880 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039993.880 units remaining) - [ {} ] - - location: 12 (remaining gas: 1039993.865 units remaining) - [ {} - {} ] - - location: 14 (remaining gas: 1039993.850 units remaining) - [ (Pair {} {}) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out deleted file mode 100644 index 7040bc57e419..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20] - -storage - 20 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039991.873 units remaining) - [ (Pair { 10 ; 2 ; 1 } 0) ] - - location: 8 (remaining gas: 1039991.863 units remaining) - [ { 10 ; 2 ; 1 } @parameter ] - - location: 9 (remaining gas: 1039991.853 units remaining) - [ 1 - { 10 ; 2 ; 1 } @parameter ] - - location: 12 (remaining gas: 1039991.843 units remaining) - [ { 10 ; 2 ; 1 } @parameter - 1 ] - - location: 13 (remaining gas: 1039991.843 units remaining) - [ 10 @parameter.elt - 1 ] - - location: 15 (remaining gas: 1039991.739 units remaining) - [ 10 ] - - location: 13 (remaining gas: 1039991.724 units remaining) - [ 2 @parameter.elt - 10 ] - - location: 15 (remaining gas: 1039991.620 units remaining) - [ 20 ] - - location: 13 (remaining gas: 1039991.605 units remaining) - [ 1 @parameter.elt - 20 ] - - location: 15 (remaining gas: 1039991.501 units remaining) - [ 20 ] - - location: 13 (remaining gas: 1039991.486 units remaining) - [ 20 ] - - location: 16 (remaining gas: 1039991.471 units remaining) - [ {} - 20 ] - - location: 18 (remaining gas: 1039991.456 units remaining) - [ (Pair {} 20) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out deleted file mode 100644 index 7d81ce16671e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162] - -storage - 162 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039991.873 units remaining) - [ (Pair { 3 ; 6 ; 9 } 0) ] - - location: 8 (remaining gas: 1039991.863 units remaining) - [ { 3 ; 6 ; 9 } @parameter ] - - location: 9 (remaining gas: 1039991.853 units remaining) - [ 1 - { 3 ; 6 ; 9 } @parameter ] - - location: 12 (remaining gas: 1039991.843 units remaining) - [ { 3 ; 6 ; 9 } @parameter - 1 ] - - location: 13 (remaining gas: 1039991.843 units remaining) - [ 3 @parameter.elt - 1 ] - - location: 15 (remaining gas: 1039991.739 units remaining) - [ 3 ] - - location: 13 (remaining gas: 1039991.724 units remaining) - [ 6 @parameter.elt - 3 ] - - location: 15 (remaining gas: 1039991.620 units remaining) - [ 18 ] - - location: 13 (remaining gas: 1039991.605 units remaining) - [ 9 @parameter.elt - 18 ] - - location: 15 (remaining gas: 1039991.501 units remaining) - [ 162 ] - - location: 13 (remaining gas: 1039991.486 units remaining) - [ 162 ] - - location: 16 (remaining gas: 1039991.471 units remaining) - [ {} - 162 ] - - location: 18 (remaining gas: 1039991.456 units remaining) - [ (Pair {} 162) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out deleted file mode 100644 index 3b9c8e154e9e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out +++ /dev/null @@ -1,136 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }] - -storage - { 1 ; 2 ; 3 ; 4 } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039985.969 units remaining) - [ (Pair { 1 ; 1 ; 1 ; 1 } { 0 }) ] - - location: 9 (remaining gas: 1039985.959 units remaining) - [ { 1 ; 1 ; 1 ; 1 } @parameter ] - - location: 10 (remaining gas: 1039985.949 units remaining) - [ 0 - { 1 ; 1 ; 1 ; 1 } @parameter ] - - location: 13 (remaining gas: 1039985.939 units remaining) - [ { 1 ; 1 ; 1 ; 1 } @parameter - 0 ] - - location: 14 (remaining gas: 1039985.939 units remaining) - [ 1 @parameter.elt - 0 ] - - location: 16 (remaining gas: 1039985.924 units remaining) - [ 0 ] - - location: 18 (remaining gas: 1039985.914 units remaining) - [ 0 - 0 ] - - location: 16 (remaining gas: 1039985.884 units remaining) - [ 1 @parameter.elt - 0 - 0 ] - - location: 19 (remaining gas: 1039985.829 units remaining) - [ 1 - 0 ] - - location: 20 (remaining gas: 1039985.814 units remaining) - [ 0 ] - - location: 22 (remaining gas: 1039985.804 units remaining) - [ 1 - 0 ] - - location: 25 (remaining gas: 1039985.749 units remaining) - [ 1 ] - - location: 20 (remaining gas: 1039985.719 units remaining) - [ 1 - 1 ] - - location: 14 (remaining gas: 1039985.704 units remaining) - [ 1 @parameter.elt - 1 ] - - location: 16 (remaining gas: 1039985.689 units remaining) - [ 1 ] - - location: 18 (remaining gas: 1039985.679 units remaining) - [ 1 - 1 ] - - location: 16 (remaining gas: 1039985.649 units remaining) - [ 1 @parameter.elt - 1 - 1 ] - - location: 19 (remaining gas: 1039985.594 units remaining) - [ 2 - 1 ] - - location: 20 (remaining gas: 1039985.579 units remaining) - [ 1 ] - - location: 22 (remaining gas: 1039985.569 units remaining) - [ 1 - 1 ] - - location: 25 (remaining gas: 1039985.514 units remaining) - [ 2 ] - - location: 20 (remaining gas: 1039985.484 units remaining) - [ 2 - 2 ] - - location: 14 (remaining gas: 1039985.469 units remaining) - [ 1 @parameter.elt - 2 ] - - location: 16 (remaining gas: 1039985.454 units remaining) - [ 2 ] - - location: 18 (remaining gas: 1039985.444 units remaining) - [ 2 - 2 ] - - location: 16 (remaining gas: 1039985.414 units remaining) - [ 1 @parameter.elt - 2 - 2 ] - - location: 19 (remaining gas: 1039985.359 units remaining) - [ 3 - 2 ] - - location: 20 (remaining gas: 1039985.344 units remaining) - [ 2 ] - - location: 22 (remaining gas: 1039985.334 units remaining) - [ 1 - 2 ] - - location: 25 (remaining gas: 1039985.279 units remaining) - [ 3 ] - - location: 20 (remaining gas: 1039985.249 units remaining) - [ 3 - 3 ] - - location: 14 (remaining gas: 1039985.234 units remaining) - [ 1 @parameter.elt - 3 ] - - location: 16 (remaining gas: 1039985.219 units remaining) - [ 3 ] - - location: 18 (remaining gas: 1039985.209 units remaining) - [ 3 - 3 ] - - location: 16 (remaining gas: 1039985.179 units remaining) - [ 1 @parameter.elt - 3 - 3 ] - - location: 19 (remaining gas: 1039985.124 units remaining) - [ 4 - 3 ] - - location: 20 (remaining gas: 1039985.109 units remaining) - [ 3 ] - - location: 22 (remaining gas: 1039985.099 units remaining) - [ 1 - 3 ] - - location: 25 (remaining gas: 1039985.044 units remaining) - [ 4 ] - - location: 20 (remaining gas: 1039985.014 units remaining) - [ 4 - 4 ] - - location: 14 (remaining gas: 1039984.999 units remaining) - [ { 1 ; 2 ; 3 ; 4 } - 4 ] - - location: 26 (remaining gas: 1039984.984 units remaining) - [ {} - { 1 ; 2 ; 3 ; 4 } - 4 ] - - location: 28 (remaining gas: 1039984.969 units remaining) - [ (Pair {} { 1 ; 2 ; 3 ; 4 }) - 4 ] - - location: 29 (remaining gas: 1039984.954 units remaining) - [ 4 ] - - location: 31 (remaining gas: 1039984.944 units remaining) - [ ] - - location: 29 (remaining gas: 1039984.914 units remaining) - [ (Pair {} { 1 ; 2 ; 3 ; 4 }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out deleted file mode 100644 index f6621e550850..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out +++ /dev/null @@ -1,136 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }] - -storage - { 1 ; 3 ; 5 ; 3 } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039985.969 units remaining) - [ (Pair { 1 ; 2 ; 3 ; 0 } { 0 }) ] - - location: 9 (remaining gas: 1039985.959 units remaining) - [ { 1 ; 2 ; 3 ; 0 } @parameter ] - - location: 10 (remaining gas: 1039985.949 units remaining) - [ 0 - { 1 ; 2 ; 3 ; 0 } @parameter ] - - location: 13 (remaining gas: 1039985.939 units remaining) - [ { 1 ; 2 ; 3 ; 0 } @parameter - 0 ] - - location: 14 (remaining gas: 1039985.939 units remaining) - [ 1 @parameter.elt - 0 ] - - location: 16 (remaining gas: 1039985.924 units remaining) - [ 0 ] - - location: 18 (remaining gas: 1039985.914 units remaining) - [ 0 - 0 ] - - location: 16 (remaining gas: 1039985.884 units remaining) - [ 1 @parameter.elt - 0 - 0 ] - - location: 19 (remaining gas: 1039985.829 units remaining) - [ 1 - 0 ] - - location: 20 (remaining gas: 1039985.814 units remaining) - [ 0 ] - - location: 22 (remaining gas: 1039985.804 units remaining) - [ 1 - 0 ] - - location: 25 (remaining gas: 1039985.749 units remaining) - [ 1 ] - - location: 20 (remaining gas: 1039985.719 units remaining) - [ 1 - 1 ] - - location: 14 (remaining gas: 1039985.704 units remaining) - [ 2 @parameter.elt - 1 ] - - location: 16 (remaining gas: 1039985.689 units remaining) - [ 1 ] - - location: 18 (remaining gas: 1039985.679 units remaining) - [ 1 - 1 ] - - location: 16 (remaining gas: 1039985.649 units remaining) - [ 2 @parameter.elt - 1 - 1 ] - - location: 19 (remaining gas: 1039985.594 units remaining) - [ 3 - 1 ] - - location: 20 (remaining gas: 1039985.579 units remaining) - [ 1 ] - - location: 22 (remaining gas: 1039985.569 units remaining) - [ 1 - 1 ] - - location: 25 (remaining gas: 1039985.514 units remaining) - [ 2 ] - - location: 20 (remaining gas: 1039985.484 units remaining) - [ 3 - 2 ] - - location: 14 (remaining gas: 1039985.469 units remaining) - [ 3 @parameter.elt - 2 ] - - location: 16 (remaining gas: 1039985.454 units remaining) - [ 2 ] - - location: 18 (remaining gas: 1039985.444 units remaining) - [ 2 - 2 ] - - location: 16 (remaining gas: 1039985.414 units remaining) - [ 3 @parameter.elt - 2 - 2 ] - - location: 19 (remaining gas: 1039985.359 units remaining) - [ 5 - 2 ] - - location: 20 (remaining gas: 1039985.344 units remaining) - [ 2 ] - - location: 22 (remaining gas: 1039985.334 units remaining) - [ 1 - 2 ] - - location: 25 (remaining gas: 1039985.279 units remaining) - [ 3 ] - - location: 20 (remaining gas: 1039985.249 units remaining) - [ 5 - 3 ] - - location: 14 (remaining gas: 1039985.234 units remaining) - [ 0 @parameter.elt - 3 ] - - location: 16 (remaining gas: 1039985.219 units remaining) - [ 3 ] - - location: 18 (remaining gas: 1039985.209 units remaining) - [ 3 - 3 ] - - location: 16 (remaining gas: 1039985.179 units remaining) - [ 0 @parameter.elt - 3 - 3 ] - - location: 19 (remaining gas: 1039985.124 units remaining) - [ 3 - 3 ] - - location: 20 (remaining gas: 1039985.109 units remaining) - [ 3 ] - - location: 22 (remaining gas: 1039985.099 units remaining) - [ 1 - 3 ] - - location: 25 (remaining gas: 1039985.044 units remaining) - [ 4 ] - - location: 20 (remaining gas: 1039985.014 units remaining) - [ 3 - 4 ] - - location: 14 (remaining gas: 1039984.999 units remaining) - [ { 1 ; 3 ; 5 ; 3 } - 4 ] - - location: 26 (remaining gas: 1039984.984 units remaining) - [ {} - { 1 ; 3 ; 5 ; 3 } - 4 ] - - location: 28 (remaining gas: 1039984.969 units remaining) - [ (Pair {} { 1 ; 3 ; 5 ; 3 }) - 4 ] - - location: 29 (remaining gas: 1039984.954 units remaining) - [ 4 ] - - location: 31 (remaining gas: 1039984.944 units remaining) - [ ] - - location: 29 (remaining gas: 1039984.914 units remaining) - [ (Pair {} { 1 ; 3 ; 5 ; 3 }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}].out deleted file mode 100644 index a4efd4c4e7c7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}].out +++ /dev/null @@ -1,36 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039986.369 units remaining) - [ (Pair {} { 0 }) ] - - location: 9 (remaining gas: 1039986.359 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039986.349 units remaining) - [ 0 - {} @parameter ] - - location: 13 (remaining gas: 1039986.339 units remaining) - [ {} @parameter - 0 ] - - location: 14 (remaining gas: 1039986.339 units remaining) - [ {} - 0 ] - - location: 26 (remaining gas: 1039986.324 units remaining) - [ {} - {} - 0 ] - - location: 28 (remaining gas: 1039986.309 units remaining) - [ (Pair {} {}) - 0 ] - - location: 29 (remaining gas: 1039986.294 units remaining) - [ 0 ] - - location: 31 (remaining gas: 1039986.284 units remaining) - [ ] - - location: 29 (remaining gas: 1039986.254 units remaining) - [ (Pair {} {}) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out deleted file mode 100644 index b8aa5db61d9e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6] - -storage - 6 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.220 units remaining) - [ (Pair { 1 ; 2 ; 3 ; 4 ; 5 ; 6 } 111) ] - - location: 8 (remaining gas: 1039994.210 units remaining) - [ { 1 ; 2 ; 3 ; 4 ; 5 ; 6 } @parameter ] - - location: 9 (remaining gas: 1039994.195 units remaining) - [ 6 ] - - location: 10 (remaining gas: 1039994.180 units remaining) - [ {} - 6 ] - - location: 12 (remaining gas: 1039994.165 units remaining) - [ (Pair {} 6) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out deleted file mode 100644 index 15754fc3681c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3] - -storage - 3 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.520 units remaining) - [ (Pair { 1 ; 2 ; 3 } 111) ] - - location: 8 (remaining gas: 1039994.510 units remaining) - [ { 1 ; 2 ; 3 } @parameter ] - - location: 9 (remaining gas: 1039994.495 units remaining) - [ 3 ] - - location: 10 (remaining gas: 1039994.480 units remaining) - [ {} - 3 ] - - location: 12 (remaining gas: 1039994.465 units remaining) - [ (Pair {} 3) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1].out deleted file mode 100644 index 371c740de31f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.720 units remaining) - [ (Pair { 1 } 111) ] - - location: 8 (remaining gas: 1039994.710 units remaining) - [ { 1 } @parameter ] - - location: 9 (remaining gas: 1039994.695 units remaining) - [ 1 ] - - location: 10 (remaining gas: 1039994.680 units remaining) - [ {} - 1 ] - - location: 12 (remaining gas: 1039994.665 units remaining) - [ (Pair {} 1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0].out deleted file mode 100644 index 058a5faddf19..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.820 units remaining) - [ (Pair {} 111) ] - - location: 8 (remaining gas: 1039994.810 units remaining) - [ {} @parameter ] - - location: 9 (remaining gas: 1039994.795 units remaining) - [ 0 ] - - location: 10 (remaining gas: 1039994.780 units remaining) - [ {} - 0 ] - - location: 12 (remaining gas: 1039994.765 units remaining) - [ (Pair {} 0) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" deleted file mode 100644 index a121fbfbae0e..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" +++ /dev/null @@ -1,163 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[loop_left.tz-{""}-{ "c" ; "b" ; "a" }-{ "a" ; "b" ; "c" }] - -storage - { "a" ; "b" ; "c" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039977.710 units remaining) - [ (Pair { "c" ; "b" ; "a" } { "" }) ] - - location: 9 (remaining gas: 1039977.700 units remaining) - [ { "c" ; "b" ; "a" } @parameter ] - - location: 10 (remaining gas: 1039977.685 units remaining) - [ {} - { "c" ; "b" ; "a" } @parameter ] - - location: 12 (remaining gas: 1039977.675 units remaining) - [ { "c" ; "b" ; "a" } @parameter - {} ] - - location: 13 (remaining gas: 1039977.660 units remaining) - [ (Pair { "c" ; "b" ; "a" } {}) ] - - location: 14 (remaining gas: 1039977.645 units remaining) - [ (Left (Pair { "c" ; "b" ; "a" } {})) ] - - location: 17 (remaining gas: 1039977.645 units remaining) - [ (Pair { "c" ; "b" ; "a" } {}) ] - - location: 19 (remaining gas: 1039977.635 units remaining) - [ (Pair { "c" ; "b" ; "a" } {}) - (Pair { "c" ; "b" ; "a" } {}) ] - - location: 20 (remaining gas: 1039977.625 units remaining) - [ { "c" ; "b" ; "a" } @parameter - (Pair { "c" ; "b" ; "a" } {}) ] - - location: 21 (remaining gas: 1039977.610 units remaining) - [ (Pair { "c" ; "b" ; "a" } {}) ] - - location: 23 (remaining gas: 1039977.600 units remaining) - [ {} ] - - location: 21 (remaining gas: 1039977.570 units remaining) - [ { "c" ; "b" ; "a" } @parameter - {} ] - - location: 24 (remaining gas: 1039977.560 units remaining) - [ "c" @parameter.hd - { "b" ; "a" } @parameter.tl - {} ] - - location: 26 (remaining gas: 1039977.550 units remaining) - [ { "b" ; "a" } @parameter.tl - "c" @parameter.hd - {} ] - - location: 27 (remaining gas: 1039977.535 units remaining) - [ "c" @parameter.hd - {} ] - - location: 29 (remaining gas: 1039977.520 units remaining) - [ { "c" } ] - - location: 27 (remaining gas: 1039977.490 units remaining) - [ { "b" ; "a" } @parameter.tl - { "c" } ] - - location: 30 (remaining gas: 1039977.475 units remaining) - [ (Pair { "b" ; "a" } { "c" }) ] - - location: 31 (remaining gas: 1039977.460 units remaining) - [ (Left (Pair { "b" ; "a" } { "c" })) ] - - location: 24 (remaining gas: 1039977.445 units remaining) - [ (Left (Pair { "b" ; "a" } { "c" })) ] - - location: 17 (remaining gas: 1039977.430 units remaining) - [ (Pair { "b" ; "a" } { "c" }) ] - - location: 19 (remaining gas: 1039977.420 units remaining) - [ (Pair { "b" ; "a" } { "c" }) - (Pair { "b" ; "a" } { "c" }) ] - - location: 20 (remaining gas: 1039977.410 units remaining) - [ { "b" ; "a" } @parameter - (Pair { "b" ; "a" } { "c" }) ] - - location: 21 (remaining gas: 1039977.395 units remaining) - [ (Pair { "b" ; "a" } { "c" }) ] - - location: 23 (remaining gas: 1039977.385 units remaining) - [ { "c" } ] - - location: 21 (remaining gas: 1039977.355 units remaining) - [ { "b" ; "a" } @parameter - { "c" } ] - - location: 24 (remaining gas: 1039977.345 units remaining) - [ "b" @parameter.hd - { "a" } @parameter.tl - { "c" } ] - - location: 26 (remaining gas: 1039977.335 units remaining) - [ { "a" } @parameter.tl - "b" @parameter.hd - { "c" } ] - - location: 27 (remaining gas: 1039977.320 units remaining) - [ "b" @parameter.hd - { "c" } ] - - location: 29 (remaining gas: 1039977.305 units remaining) - [ { "b" ; "c" } ] - - location: 27 (remaining gas: 1039977.275 units remaining) - [ { "a" } @parameter.tl - { "b" ; "c" } ] - - location: 30 (remaining gas: 1039977.260 units remaining) - [ (Pair { "a" } { "b" ; "c" }) ] - - location: 31 (remaining gas: 1039977.245 units remaining) - [ (Left (Pair { "a" } { "b" ; "c" })) ] - - location: 24 (remaining gas: 1039977.230 units remaining) - [ (Left (Pair { "a" } { "b" ; "c" })) ] - - location: 17 (remaining gas: 1039977.215 units remaining) - [ (Pair { "a" } { "b" ; "c" }) ] - - location: 19 (remaining gas: 1039977.205 units remaining) - [ (Pair { "a" } { "b" ; "c" }) - (Pair { "a" } { "b" ; "c" }) ] - - location: 20 (remaining gas: 1039977.195 units remaining) - [ { "a" } @parameter - (Pair { "a" } { "b" ; "c" }) ] - - location: 21 (remaining gas: 1039977.180 units remaining) - [ (Pair { "a" } { "b" ; "c" }) ] - - location: 23 (remaining gas: 1039977.170 units remaining) - [ { "b" ; "c" } ] - - location: 21 (remaining gas: 1039977.140 units remaining) - [ { "a" } @parameter - { "b" ; "c" } ] - - location: 24 (remaining gas: 1039977.130 units remaining) - [ "a" @parameter.hd - {} @parameter.tl - { "b" ; "c" } ] - - location: 26 (remaining gas: 1039977.120 units remaining) - [ {} @parameter.tl - "a" @parameter.hd - { "b" ; "c" } ] - - location: 27 (remaining gas: 1039977.105 units remaining) - [ "a" @parameter.hd - { "b" ; "c" } ] - - location: 29 (remaining gas: 1039977.090 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 27 (remaining gas: 1039977.060 units remaining) - [ {} @parameter.tl - { "a" ; "b" ; "c" } ] - - location: 30 (remaining gas: 1039977.045 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) ] - - location: 31 (remaining gas: 1039977.030 units remaining) - [ (Left (Pair {} { "a" ; "b" ; "c" })) ] - - location: 24 (remaining gas: 1039977.015 units remaining) - [ (Left (Pair {} { "a" ; "b" ; "c" })) ] - - location: 17 (remaining gas: 1039977 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) ] - - location: 19 (remaining gas: 1039976.990 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) - (Pair {} { "a" ; "b" ; "c" }) ] - - location: 20 (remaining gas: 1039976.980 units remaining) - [ {} @parameter - (Pair {} { "a" ; "b" ; "c" }) ] - - location: 21 (remaining gas: 1039976.965 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) ] - - location: 23 (remaining gas: 1039976.955 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 21 (remaining gas: 1039976.925 units remaining) - [ {} @parameter - { "a" ; "b" ; "c" } ] - - location: 24 (remaining gas: 1039976.915 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 35 (remaining gas: 1039976.900 units remaining) - [ (Right { "a" ; "b" ; "c" }) ] - - location: 24 (remaining gas: 1039976.885 units remaining) - [ (Right { "a" ; "b" ; "c" }) ] - - location: 17 (remaining gas: 1039976.870 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 41 (remaining gas: 1039976.855 units remaining) - [ {} - { "a" ; "b" ; "c" } ] - - location: 43 (remaining gas: 1039976.840 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{}-{}].out" deleted file mode 100644 index 127dcdfabce2..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{}-{}].out" +++ /dev/null @@ -1,52 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[loop_left.tz-{""}-{}-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039978.082 units remaining) - [ (Pair {} { "" }) ] - - location: 9 (remaining gas: 1039978.072 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039978.057 units remaining) - [ {} - {} @parameter ] - - location: 12 (remaining gas: 1039978.047 units remaining) - [ {} @parameter - {} ] - - location: 13 (remaining gas: 1039978.032 units remaining) - [ (Pair {} {}) ] - - location: 14 (remaining gas: 1039978.017 units remaining) - [ (Left (Pair {} {})) ] - - location: 17 (remaining gas: 1039978.017 units remaining) - [ (Pair {} {}) ] - - location: 19 (remaining gas: 1039978.007 units remaining) - [ (Pair {} {}) - (Pair {} {}) ] - - location: 20 (remaining gas: 1039977.997 units remaining) - [ {} @parameter - (Pair {} {}) ] - - location: 21 (remaining gas: 1039977.982 units remaining) - [ (Pair {} {}) ] - - location: 23 (remaining gas: 1039977.972 units remaining) - [ {} ] - - location: 21 (remaining gas: 1039977.942 units remaining) - [ {} @parameter - {} ] - - location: 24 (remaining gas: 1039977.932 units remaining) - [ {} ] - - location: 35 (remaining gas: 1039977.917 units remaining) - [ (Right {}) ] - - location: 24 (remaining gas: 1039977.902 units remaining) - [ (Right {}) ] - - location: 17 (remaining gas: 1039977.887 units remaining) - [ {} ] - - location: 41 (remaining gas: 1039977.872 units remaining) - [ {} - {} ] - - location: 43 (remaining gas: 1039977.857 units remaining) - [ (Pair {} {}) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out deleted file mode 100644 index 3e6e600e313d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }] - -storage - { Elt 0 0 ; Elt 3 4 } -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039993.699 units remaining) - [ (Pair { Elt 0 0 ; Elt 3 4 } {}) ] - - location: 11 (remaining gas: 1039993.689 units remaining) - [ { Elt 0 0 ; Elt 3 4 } @parameter ] - - location: 12 (remaining gas: 1039993.674 units remaining) - [ {} - { Elt 0 0 ; Elt 3 4 } @parameter ] - - location: 14 (remaining gas: 1039993.659 units remaining) - [ (Pair {} { Elt 0 0 ; Elt 3 4 }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out deleted file mode 100644 index ce1ad16cf869..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }] - -storage - { Elt 0 0 } -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039994.154 units remaining) - [ (Pair { Elt 0 0 } {}) ] - - location: 11 (remaining gas: 1039994.144 units remaining) - [ { Elt 0 0 } @parameter ] - - location: 12 (remaining gas: 1039994.129 units remaining) - [ {} - { Elt 0 0 } @parameter ] - - location: 14 (remaining gas: 1039994.114 units remaining) - [ (Pair {} { Elt 0 0 }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out deleted file mode 100644 index d1932e6dcb18..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }] - -storage - { Elt 0 1 } -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039994.154 units remaining) - [ (Pair { Elt 0 1 } {}) ] - - location: 11 (remaining gas: 1039994.144 units remaining) - [ { Elt 0 1 } @parameter ] - - location: 12 (remaining gas: 1039994.129 units remaining) - [ {} - { Elt 0 1 } @parameter ] - - location: 14 (remaining gas: 1039994.114 units remaining) - [ (Pair {} { Elt 0 1 }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out deleted file mode 100644 index f1bc24482162..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out +++ /dev/null @@ -1,152 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)] - -storage - (Pair 2 200) -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039978.509 units remaining) - [ (Pair { Elt 0 100 ; Elt 2 100 } 0 0) ] - - location: 11 (remaining gas: 1039978.499 units remaining) - [ { Elt 0 100 ; Elt 2 100 } @parameter ] - - location: 12 (remaining gas: 1039978.489 units remaining) - [ 0 @acc_e - { Elt 0 100 ; Elt 2 100 } @parameter ] - - location: 15 (remaining gas: 1039978.479 units remaining) - [ 0 @acc_k - 0 @acc_e - { Elt 0 100 ; Elt 2 100 } @parameter ] - - location: 18 (remaining gas: 1039978.464 units remaining) - [ (Pair 0 0) - { Elt 0 100 ; Elt 2 100 } @parameter ] - - location: 19 (remaining gas: 1039978.454 units remaining) - [ { Elt 0 100 ; Elt 2 100 } @parameter - (Pair 0 0) ] - - location: 20 (remaining gas: 1039978.454 units remaining) - [ (Pair 0 100) - (Pair 0 0) ] - - location: 22 (remaining gas: 1039978.439 units remaining) - [ (Pair 0 0) ] - - location: 24 (remaining gas: 1039978.429 units remaining) - [ (Pair 0 0) - (Pair 0 0) ] - - location: 25 (remaining gas: 1039978.419 units remaining) - [ 0 @acc_k - (Pair 0 0) ] - - location: 26 (remaining gas: 1039978.404 units remaining) - [ (Pair 0 0) ] - - location: 28 (remaining gas: 1039978.394 units remaining) - [ 0 @acc_e ] - - location: 26 (remaining gas: 1039978.364 units remaining) - [ 0 @acc_k - 0 @acc_e ] - - location: 22 (remaining gas: 1039978.334 units remaining) - [ (Pair 0 100) - 0 @acc_k - 0 @acc_e ] - - location: 29 (remaining gas: 1039978.324 units remaining) - [ (Pair 0 100) - (Pair 0 100) - 0 @acc_k - 0 @acc_e ] - - location: 30 (remaining gas: 1039978.309 units remaining) - [ (Pair 0 100) - 0 @acc_k - 0 @acc_e ] - - location: 32 (remaining gas: 1039978.299 units remaining) - [ 0 @key - 0 @acc_k - 0 @acc_e ] - - location: 33 (remaining gas: 1039978.244 units remaining) - [ 0 - 0 @acc_e ] - - location: 30 (remaining gas: 1039978.214 units remaining) - [ (Pair 0 100) - 0 - 0 @acc_e ] - - location: 34 (remaining gas: 1039978.204 units remaining) - [ 0 - (Pair 0 100) - 0 @acc_e ] - - location: 35 (remaining gas: 1039978.189 units remaining) - [ (Pair 0 100) - 0 @acc_e ] - - location: 37 (remaining gas: 1039978.179 units remaining) - [ 100 @elt - 0 @acc_e ] - - location: 38 (remaining gas: 1039978.124 units remaining) - [ 100 ] - - location: 35 (remaining gas: 1039978.094 units remaining) - [ 0 - 100 ] - - location: 39 (remaining gas: 1039978.079 units remaining) - [ (Pair 0 100) ] - - location: 20 (remaining gas: 1039978.064 units remaining) - [ (Pair 2 100) - (Pair 0 100) ] - - location: 22 (remaining gas: 1039978.049 units remaining) - [ (Pair 0 100) ] - - location: 24 (remaining gas: 1039978.039 units remaining) - [ (Pair 0 100) - (Pair 0 100) ] - - location: 25 (remaining gas: 1039978.029 units remaining) - [ 0 @acc_k - (Pair 0 100) ] - - location: 26 (remaining gas: 1039978.014 units remaining) - [ (Pair 0 100) ] - - location: 28 (remaining gas: 1039978.004 units remaining) - [ 100 @acc_e ] - - location: 26 (remaining gas: 1039977.974 units remaining) - [ 0 @acc_k - 100 @acc_e ] - - location: 22 (remaining gas: 1039977.944 units remaining) - [ (Pair 2 100) - 0 @acc_k - 100 @acc_e ] - - location: 29 (remaining gas: 1039977.934 units remaining) - [ (Pair 2 100) - (Pair 2 100) - 0 @acc_k - 100 @acc_e ] - - location: 30 (remaining gas: 1039977.919 units remaining) - [ (Pair 2 100) - 0 @acc_k - 100 @acc_e ] - - location: 32 (remaining gas: 1039977.909 units remaining) - [ 2 @key - 0 @acc_k - 100 @acc_e ] - - location: 33 (remaining gas: 1039977.854 units remaining) - [ 2 - 100 @acc_e ] - - location: 30 (remaining gas: 1039977.824 units remaining) - [ (Pair 2 100) - 2 - 100 @acc_e ] - - location: 34 (remaining gas: 1039977.814 units remaining) - [ 2 - (Pair 2 100) - 100 @acc_e ] - - location: 35 (remaining gas: 1039977.799 units remaining) - [ (Pair 2 100) - 100 @acc_e ] - - location: 37 (remaining gas: 1039977.789 units remaining) - [ 100 @elt - 100 @acc_e ] - - location: 38 (remaining gas: 1039977.734 units remaining) - [ 200 ] - - location: 35 (remaining gas: 1039977.704 units remaining) - [ 2 - 200 ] - - location: 39 (remaining gas: 1039977.689 units remaining) - [ (Pair 2 200) ] - - location: 20 (remaining gas: 1039977.674 units remaining) - [ (Pair 2 200) ] - - location: 40 (remaining gas: 1039977.659 units remaining) - [ {} - (Pair 2 200) ] - - location: 42 (remaining gas: 1039977.644 units remaining) - [ (Pair {} 2 200) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out deleted file mode 100644 index 61dbfad8a435..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out +++ /dev/null @@ -1,152 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)] - -storage - (Pair 3 101) -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039978.509 units remaining) - [ (Pair { Elt 1 1 ; Elt 2 100 } 0 0) ] - - location: 11 (remaining gas: 1039978.499 units remaining) - [ { Elt 1 1 ; Elt 2 100 } @parameter ] - - location: 12 (remaining gas: 1039978.489 units remaining) - [ 0 @acc_e - { Elt 1 1 ; Elt 2 100 } @parameter ] - - location: 15 (remaining gas: 1039978.479 units remaining) - [ 0 @acc_k - 0 @acc_e - { Elt 1 1 ; Elt 2 100 } @parameter ] - - location: 18 (remaining gas: 1039978.464 units remaining) - [ (Pair 0 0) - { Elt 1 1 ; Elt 2 100 } @parameter ] - - location: 19 (remaining gas: 1039978.454 units remaining) - [ { Elt 1 1 ; Elt 2 100 } @parameter - (Pair 0 0) ] - - location: 20 (remaining gas: 1039978.454 units remaining) - [ (Pair 1 1) - (Pair 0 0) ] - - location: 22 (remaining gas: 1039978.439 units remaining) - [ (Pair 0 0) ] - - location: 24 (remaining gas: 1039978.429 units remaining) - [ (Pair 0 0) - (Pair 0 0) ] - - location: 25 (remaining gas: 1039978.419 units remaining) - [ 0 @acc_k - (Pair 0 0) ] - - location: 26 (remaining gas: 1039978.404 units remaining) - [ (Pair 0 0) ] - - location: 28 (remaining gas: 1039978.394 units remaining) - [ 0 @acc_e ] - - location: 26 (remaining gas: 1039978.364 units remaining) - [ 0 @acc_k - 0 @acc_e ] - - location: 22 (remaining gas: 1039978.334 units remaining) - [ (Pair 1 1) - 0 @acc_k - 0 @acc_e ] - - location: 29 (remaining gas: 1039978.324 units remaining) - [ (Pair 1 1) - (Pair 1 1) - 0 @acc_k - 0 @acc_e ] - - location: 30 (remaining gas: 1039978.309 units remaining) - [ (Pair 1 1) - 0 @acc_k - 0 @acc_e ] - - location: 32 (remaining gas: 1039978.299 units remaining) - [ 1 @key - 0 @acc_k - 0 @acc_e ] - - location: 33 (remaining gas: 1039978.244 units remaining) - [ 1 - 0 @acc_e ] - - location: 30 (remaining gas: 1039978.214 units remaining) - [ (Pair 1 1) - 1 - 0 @acc_e ] - - location: 34 (remaining gas: 1039978.204 units remaining) - [ 1 - (Pair 1 1) - 0 @acc_e ] - - location: 35 (remaining gas: 1039978.189 units remaining) - [ (Pair 1 1) - 0 @acc_e ] - - location: 37 (remaining gas: 1039978.179 units remaining) - [ 1 @elt - 0 @acc_e ] - - location: 38 (remaining gas: 1039978.124 units remaining) - [ 1 ] - - location: 35 (remaining gas: 1039978.094 units remaining) - [ 1 - 1 ] - - location: 39 (remaining gas: 1039978.079 units remaining) - [ (Pair 1 1) ] - - location: 20 (remaining gas: 1039978.064 units remaining) - [ (Pair 2 100) - (Pair 1 1) ] - - location: 22 (remaining gas: 1039978.049 units remaining) - [ (Pair 1 1) ] - - location: 24 (remaining gas: 1039978.039 units remaining) - [ (Pair 1 1) - (Pair 1 1) ] - - location: 25 (remaining gas: 1039978.029 units remaining) - [ 1 @acc_k - (Pair 1 1) ] - - location: 26 (remaining gas: 1039978.014 units remaining) - [ (Pair 1 1) ] - - location: 28 (remaining gas: 1039978.004 units remaining) - [ 1 @acc_e ] - - location: 26 (remaining gas: 1039977.974 units remaining) - [ 1 @acc_k - 1 @acc_e ] - - location: 22 (remaining gas: 1039977.944 units remaining) - [ (Pair 2 100) - 1 @acc_k - 1 @acc_e ] - - location: 29 (remaining gas: 1039977.934 units remaining) - [ (Pair 2 100) - (Pair 2 100) - 1 @acc_k - 1 @acc_e ] - - location: 30 (remaining gas: 1039977.919 units remaining) - [ (Pair 2 100) - 1 @acc_k - 1 @acc_e ] - - location: 32 (remaining gas: 1039977.909 units remaining) - [ 2 @key - 1 @acc_k - 1 @acc_e ] - - location: 33 (remaining gas: 1039977.854 units remaining) - [ 3 - 1 @acc_e ] - - location: 30 (remaining gas: 1039977.824 units remaining) - [ (Pair 2 100) - 3 - 1 @acc_e ] - - location: 34 (remaining gas: 1039977.814 units remaining) - [ 3 - (Pair 2 100) - 1 @acc_e ] - - location: 35 (remaining gas: 1039977.799 units remaining) - [ (Pair 2 100) - 1 @acc_e ] - - location: 37 (remaining gas: 1039977.789 units remaining) - [ 100 @elt - 1 @acc_e ] - - location: 38 (remaining gas: 1039977.734 units remaining) - [ 101 ] - - location: 35 (remaining gas: 1039977.704 units remaining) - [ 3 - 101 ] - - location: 39 (remaining gas: 1039977.689 units remaining) - [ (Pair 3 101) ] - - location: 20 (remaining gas: 1039977.674 units remaining) - [ (Pair 3 101) ] - - location: 40 (remaining gas: 1039977.659 units remaining) - [ {} - (Pair 3 101) ] - - location: 42 (remaining gas: 1039977.644 units remaining) - [ (Pair {} 3 101) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"bar\" 5 ; Elt \"foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"bar\" 5 ; Elt \"foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" deleted file mode 100644 index ff415657be0f..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"bar\" 5 ; Elt \"foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" +++ /dev/null @@ -1,68 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt "bar" 5 ; Elt "foo" 1 }-15-{ Elt "bar" 20 ; Elt "foo" 16 }] - -storage - { Elt "bar" 20 ; Elt "foo" 16 } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039988.041 units remaining) - [ (Pair 15 { Elt "bar" 5 ; Elt "foo" 1 }) ] - - location: 9 (remaining gas: 1039988.031 units remaining) - [ 15 @parameter - { Elt "bar" 5 ; Elt "foo" 1 } @storage ] - - location: 10 (remaining gas: 1039988.021 units remaining) - [ { Elt "bar" 5 ; Elt "foo" 1 } @storage - 15 @parameter ] - - location: 11 (remaining gas: 1039988.021 units remaining) - [ (Pair "bar" 5) - 15 @parameter ] - - location: 13 (remaining gas: 1039988.011 units remaining) - [ 5 @elt - 15 @parameter ] - - location: 14 (remaining gas: 1039987.996 units remaining) - [ 15 @parameter ] - - location: 16 (remaining gas: 1039987.986 units remaining) - [ 15 @parameter - 15 @parameter ] - - location: 14 (remaining gas: 1039987.956 units remaining) - [ 5 @elt - 15 @parameter - 15 @parameter ] - - location: 17 (remaining gas: 1039987.901 units remaining) - [ 20 - 15 @parameter ] - - location: 11 (remaining gas: 1039987.886 units remaining) - [ (Pair "foo" 1) - 15 @parameter ] - - location: 13 (remaining gas: 1039987.876 units remaining) - [ 1 @elt - 15 @parameter ] - - location: 14 (remaining gas: 1039987.861 units remaining) - [ 15 @parameter ] - - location: 16 (remaining gas: 1039987.851 units remaining) - [ 15 @parameter - 15 @parameter ] - - location: 14 (remaining gas: 1039987.821 units remaining) - [ 1 @elt - 15 @parameter - 15 @parameter ] - - location: 17 (remaining gas: 1039987.766 units remaining) - [ 16 - 15 @parameter ] - - location: 11 (remaining gas: 1039987.751 units remaining) - [ { Elt "bar" 20 ; Elt "foo" 16 } - 15 @parameter ] - - location: 18 (remaining gas: 1039987.736 units remaining) - [ 15 @parameter ] - - location: 20 (remaining gas: 1039987.726 units remaining) - [ ] - - location: 18 (remaining gas: 1039987.696 units remaining) - [ { Elt "bar" 20 ; Elt "foo" 16 } ] - - location: 21 (remaining gas: 1039987.681 units remaining) - [ {} - { Elt "bar" 20 ; Elt "foo" 16 } ] - - location: 23 (remaining gas: 1039987.666 units remaining) - [ (Pair {} { Elt "bar" 20 ; Elt "foo" 16 }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" deleted file mode 100644 index 9cb0ff466142..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" +++ /dev/null @@ -1,50 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt "foo" 1 }-10-{ Elt "foo" 11 }] - -storage - { Elt "foo" 11 } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039988.540 units remaining) - [ (Pair 10 { Elt "foo" 1 }) ] - - location: 9 (remaining gas: 1039988.530 units remaining) - [ 10 @parameter - { Elt "foo" 1 } @storage ] - - location: 10 (remaining gas: 1039988.520 units remaining) - [ { Elt "foo" 1 } @storage - 10 @parameter ] - - location: 11 (remaining gas: 1039988.520 units remaining) - [ (Pair "foo" 1) - 10 @parameter ] - - location: 13 (remaining gas: 1039988.510 units remaining) - [ 1 @elt - 10 @parameter ] - - location: 14 (remaining gas: 1039988.495 units remaining) - [ 10 @parameter ] - - location: 16 (remaining gas: 1039988.485 units remaining) - [ 10 @parameter - 10 @parameter ] - - location: 14 (remaining gas: 1039988.455 units remaining) - [ 1 @elt - 10 @parameter - 10 @parameter ] - - location: 17 (remaining gas: 1039988.400 units remaining) - [ 11 - 10 @parameter ] - - location: 11 (remaining gas: 1039988.385 units remaining) - [ { Elt "foo" 11 } - 10 @parameter ] - - location: 18 (remaining gas: 1039988.370 units remaining) - [ 10 @parameter ] - - location: 20 (remaining gas: 1039988.360 units remaining) - [ ] - - location: 18 (remaining gas: 1039988.330 units remaining) - [ { Elt "foo" 11 } ] - - location: 21 (remaining gas: 1039988.315 units remaining) - [ {} - { Elt "foo" 11 } ] - - location: 23 (remaining gas: 1039988.300 units remaining) - [ (Pair {} { Elt "foo" 11 }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}].out deleted file mode 100644 index 8760d9c7de28..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039988.934 units remaining) - [ (Pair 10 {}) ] - - location: 9 (remaining gas: 1039988.924 units remaining) - [ 10 @parameter - {} @storage ] - - location: 10 (remaining gas: 1039988.914 units remaining) - [ {} @storage - 10 @parameter ] - - location: 11 (remaining gas: 1039988.914 units remaining) - [ {} - 10 @parameter ] - - location: 18 (remaining gas: 1039988.899 units remaining) - [ 10 @parameter ] - - location: 20 (remaining gas: 1039988.889 units remaining) - [ ] - - location: 18 (remaining gas: 1039988.859 units remaining) - [ {} ] - - location: 21 (remaining gas: 1039988.844 units remaining) - [ {} - {} ] - - location: 23 (remaining gas: 1039988.829 units remaining) - [ (Pair {} {}) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 .7396e5f090.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 .7396e5f090.out deleted file mode 100644 index 10374688bda7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 .7396e5f090.out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 1 } (Some False))] - -storage - (Pair { Elt 0 1 } (Some False)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039988.154 units remaining) - [ (Pair 1 { Elt 0 1 } None) ] - - location: 12 (remaining gas: 1039988.144 units remaining) - [ 1 @parameter - (Pair { Elt 0 1 } None) @storage ] - - location: 13 (remaining gas: 1039988.129 units remaining) - [ (Pair { Elt 0 1 } None) @storage ] - - location: 15 (remaining gas: 1039988.119 units remaining) - [ { Elt 0 1 } ] - - location: 16 (remaining gas: 1039988.109 units remaining) - [ { Elt 0 1 } - { Elt 0 1 } ] - - location: 13 (remaining gas: 1039988.079 units remaining) - [ 1 @parameter - { Elt 0 1 } - { Elt 0 1 } ] - - location: 17 (remaining gas: 1039987.929 units remaining) - [ False - { Elt 0 1 } ] - - location: 18 (remaining gas: 1039987.914 units remaining) - [ (Some False) - { Elt 0 1 } ] - - location: 19 (remaining gas: 1039987.904 units remaining) - [ { Elt 0 1 } - (Some False) ] - - location: 20 (remaining gas: 1039987.889 units remaining) - [ (Pair { Elt 0 1 } (Some False)) ] - - location: 21 (remaining gas: 1039987.874 units remaining) - [ {} - (Pair { Elt 0 1 } (Some False)) ] - - location: 23 (remaining gas: 1039987.859 units remaining) - [ (Pair {} { Elt 0 1 } (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out deleted file mode 100644 index cb796ca357d8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 0 } (Some True))] - -storage - (Pair { Elt 1 0 } (Some True)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039988.154 units remaining) - [ (Pair 1 { Elt 1 0 } None) ] - - location: 12 (remaining gas: 1039988.144 units remaining) - [ 1 @parameter - (Pair { Elt 1 0 } None) @storage ] - - location: 13 (remaining gas: 1039988.129 units remaining) - [ (Pair { Elt 1 0 } None) @storage ] - - location: 15 (remaining gas: 1039988.119 units remaining) - [ { Elt 1 0 } ] - - location: 16 (remaining gas: 1039988.109 units remaining) - [ { Elt 1 0 } - { Elt 1 0 } ] - - location: 13 (remaining gas: 1039988.079 units remaining) - [ 1 @parameter - { Elt 1 0 } - { Elt 1 0 } ] - - location: 17 (remaining gas: 1039987.929 units remaining) - [ True - { Elt 1 0 } ] - - location: 18 (remaining gas: 1039987.914 units remaining) - [ (Some True) - { Elt 1 0 } ] - - location: 19 (remaining gas: 1039987.904 units remaining) - [ { Elt 1 0 } - (Some True) ] - - location: 20 (remaining gas: 1039987.889 units remaining) - [ (Pair { Elt 1 0 } (Some True)) ] - - location: 21 (remaining gas: 1039987.874 units remaining) - [ {} - (Pair { Elt 1 0 } (Some True)) ] - - location: 23 (remaining gas: 1039987.859 units remaining) - [ (Pair {} { Elt 1 0 } (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out deleted file mode 100644 index 7bdeef3d3c56..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pair { Elt 1 4 ; Elt 2 11 } (Some True))] - -storage - (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039987.699 units remaining) - [ (Pair 1 { Elt 1 4 ; Elt 2 11 } None) ] - - location: 12 (remaining gas: 1039987.689 units remaining) - [ 1 @parameter - (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 13 (remaining gas: 1039987.674 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 15 (remaining gas: 1039987.664 units remaining) - [ { Elt 1 4 ; Elt 2 11 } ] - - location: 16 (remaining gas: 1039987.654 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 13 (remaining gas: 1039987.624 units remaining) - [ 1 @parameter - { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 17 (remaining gas: 1039987.439 units remaining) - [ True - { Elt 1 4 ; Elt 2 11 } ] - - location: 18 (remaining gas: 1039987.424 units remaining) - [ (Some True) - { Elt 1 4 ; Elt 2 11 } ] - - location: 19 (remaining gas: 1039987.414 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - (Some True) ] - - location: 20 (remaining gas: 1039987.399 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 21 (remaining gas: 1039987.384 units remaining) - [ {} - (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 23 (remaining gas: 1039987.369 units remaining) - [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out deleted file mode 100644 index 14a5f6d3c18a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pair { Elt 1 4 ; Elt 2 11 } (Some True))] - -storage - (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039987.699 units remaining) - [ (Pair 2 { Elt 1 4 ; Elt 2 11 } None) ] - - location: 12 (remaining gas: 1039987.689 units remaining) - [ 2 @parameter - (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 13 (remaining gas: 1039987.674 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 15 (remaining gas: 1039987.664 units remaining) - [ { Elt 1 4 ; Elt 2 11 } ] - - location: 16 (remaining gas: 1039987.654 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 13 (remaining gas: 1039987.624 units remaining) - [ 2 @parameter - { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 17 (remaining gas: 1039987.439 units remaining) - [ True - { Elt 1 4 ; Elt 2 11 } ] - - location: 18 (remaining gas: 1039987.424 units remaining) - [ (Some True) - { Elt 1 4 ; Elt 2 11 } ] - - location: 19 (remaining gas: 1039987.414 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - (Some True) ] - - location: 20 (remaining gas: 1039987.399 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 21 (remaining gas: 1039987.384 units remaining) - [ {} - (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] - - location: 23 (remaining gas: 1039987.369 units remaining) - [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out deleted file mode 100644 index abb8917ba56f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pair { Elt 1 4 ; Elt 2 11 } (Some False))] - -storage - (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039987.699 units remaining) - [ (Pair 3 { Elt 1 4 ; Elt 2 11 } None) ] - - location: 12 (remaining gas: 1039987.689 units remaining) - [ 3 @parameter - (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 13 (remaining gas: 1039987.674 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] - - location: 15 (remaining gas: 1039987.664 units remaining) - [ { Elt 1 4 ; Elt 2 11 } ] - - location: 16 (remaining gas: 1039987.654 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 13 (remaining gas: 1039987.624 units remaining) - [ 3 @parameter - { Elt 1 4 ; Elt 2 11 } - { Elt 1 4 ; Elt 2 11 } ] - - location: 17 (remaining gas: 1039987.439 units remaining) - [ False - { Elt 1 4 ; Elt 2 11 } ] - - location: 18 (remaining gas: 1039987.424 units remaining) - [ (Some False) - { Elt 1 4 ; Elt 2 11 } ] - - location: 19 (remaining gas: 1039987.414 units remaining) - [ { Elt 1 4 ; Elt 2 11 } - (Some False) ] - - location: 20 (remaining gas: 1039987.399 units remaining) - [ (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] - - location: 21 (remaining gas: 1039987.384 units remaining) - [ {} - (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] - - location: 23 (remaining gas: 1039987.369 units remaining) - [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))].out deleted file mode 100644 index a694a3b068f4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))].out +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))] - -storage - (Pair {} (Some False)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039988.504 units remaining) - [ (Pair 1 {} None) ] - - location: 12 (remaining gas: 1039988.494 units remaining) - [ 1 @parameter - (Pair {} None) @storage ] - - location: 13 (remaining gas: 1039988.479 units remaining) - [ (Pair {} None) @storage ] - - location: 15 (remaining gas: 1039988.469 units remaining) - [ {} ] - - location: 16 (remaining gas: 1039988.459 units remaining) - [ {} - {} ] - - location: 13 (remaining gas: 1039988.429 units remaining) - [ 1 @parameter - {} - {} ] - - location: 17 (remaining gas: 1039988.314 units remaining) - [ False - {} ] - - location: 18 (remaining gas: 1039988.299 units remaining) - [ (Some False) - {} ] - - location: 19 (remaining gas: 1039988.289 units remaining) - [ {} - (Some False) ] - - location: 20 (remaining gas: 1039988.274 units remaining) - [ (Pair {} (Some False)) ] - - location: 21 (remaining gas: 1039988.259 units remaining) - [ {} - (Pair {} (Some False)) ] - - location: 23 (remaining gas: 1039988.244 units remaining) - [ (Pair {} {} (Some False)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" deleted file mode 100644 index 2b97af7a2e53..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"bar"-(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True))] - -storage - (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039987.567 units remaining) - [ (Pair "bar" { Elt "bar" 4 ; Elt "foo" 11 } None) ] - - location: 12 (remaining gas: 1039987.557 units remaining) - [ "bar" @parameter - (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 13 (remaining gas: 1039987.542 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 15 (remaining gas: 1039987.532 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 16 (remaining gas: 1039987.522 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 13 (remaining gas: 1039987.492 units remaining) - [ "bar" @parameter - { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 17 (remaining gas: 1039987.307 units remaining) - [ True - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 18 (remaining gas: 1039987.292 units remaining) - [ (Some True) - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 19 (remaining gas: 1039987.282 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - (Some True) ] - - location: 20 (remaining gas: 1039987.267 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - - location: 21 (remaining gas: 1039987.252 units remaining) - [ {} - (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - - location: 23 (remaining gas: 1039987.237 units remaining) - [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" deleted file mode 100644 index 2373d63fabe3..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"foo"-(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True))] - -storage - (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039987.567 units remaining) - [ (Pair "foo" { Elt "bar" 4 ; Elt "foo" 11 } None) ] - - location: 12 (remaining gas: 1039987.557 units remaining) - [ "foo" @parameter - (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 13 (remaining gas: 1039987.542 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 15 (remaining gas: 1039987.532 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 16 (remaining gas: 1039987.522 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 13 (remaining gas: 1039987.492 units remaining) - [ "foo" @parameter - { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 17 (remaining gas: 1039987.307 units remaining) - [ True - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 18 (remaining gas: 1039987.292 units remaining) - [ (Some True) - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 19 (remaining gas: 1039987.282 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - (Some True) ] - - location: 20 (remaining gas: 1039987.267 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - - location: 21 (remaining gas: 1039987.252 units remaining) - [ {} - (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - - location: 23 (remaining gas: 1039987.237 units remaining) - [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" deleted file mode 100644 index 25cb7f94f8a4..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"baz"-(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False))] - -storage - (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039987.567 units remaining) - [ (Pair "baz" { Elt "bar" 4 ; Elt "foo" 11 } None) ] - - location: 12 (remaining gas: 1039987.557 units remaining) - [ "baz" @parameter - (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 13 (remaining gas: 1039987.542 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] - - location: 15 (remaining gas: 1039987.532 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 16 (remaining gas: 1039987.522 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 13 (remaining gas: 1039987.492 units remaining) - [ "baz" @parameter - { Elt "bar" 4 ; Elt "foo" 11 } - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 17 (remaining gas: 1039987.307 units remaining) - [ False - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 18 (remaining gas: 1039987.292 units remaining) - [ (Some False) - { Elt "bar" 4 ; Elt "foo" 11 } ] - - location: 19 (remaining gas: 1039987.282 units remaining) - [ { Elt "bar" 4 ; Elt "foo" 11 } - (Some False) ] - - location: 20 (remaining gas: 1039987.267 units remaining) - [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] - - location: 21 (remaining gas: 1039987.252 units remaining) - [ {} - (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] - - location: 23 (remaining gas: 1039987.237 units remaining) - [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" deleted file mode 100644 index 1793c4146a13..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "foo" 0 } None)-"foo"-(Pair { Elt "foo" 0 } (Some True))] - -storage - (Pair { Elt "foo" 0 } (Some True)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039988.066 units remaining) - [ (Pair "foo" { Elt "foo" 0 } None) ] - - location: 12 (remaining gas: 1039988.056 units remaining) - [ "foo" @parameter - (Pair { Elt "foo" 0 } None) @storage ] - - location: 13 (remaining gas: 1039988.041 units remaining) - [ (Pair { Elt "foo" 0 } None) @storage ] - - location: 15 (remaining gas: 1039988.031 units remaining) - [ { Elt "foo" 0 } ] - - location: 16 (remaining gas: 1039988.021 units remaining) - [ { Elt "foo" 0 } - { Elt "foo" 0 } ] - - location: 13 (remaining gas: 1039987.991 units remaining) - [ "foo" @parameter - { Elt "foo" 0 } - { Elt "foo" 0 } ] - - location: 17 (remaining gas: 1039987.841 units remaining) - [ True - { Elt "foo" 0 } ] - - location: 18 (remaining gas: 1039987.826 units remaining) - [ (Some True) - { Elt "foo" 0 } ] - - location: 19 (remaining gas: 1039987.816 units remaining) - [ { Elt "foo" 0 } - (Some True) ] - - location: 20 (remaining gas: 1039987.801 units remaining) - [ (Pair { Elt "foo" 0 } (Some True)) ] - - location: 21 (remaining gas: 1039987.786 units remaining) - [ {} - (Pair { Elt "foo" 0 } (Some True)) ] - - location: 23 (remaining gas: 1039987.771 units remaining) - [ (Pair {} { Elt "foo" 0 } (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" deleted file mode 100644 index ed7a9995a660..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "foo" 1 } None)-"bar"-(Pair { Elt "foo" 1 } (Some False))] - -storage - (Pair { Elt "foo" 1 } (Some False)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039988.066 units remaining) - [ (Pair "bar" { Elt "foo" 1 } None) ] - - location: 12 (remaining gas: 1039988.056 units remaining) - [ "bar" @parameter - (Pair { Elt "foo" 1 } None) @storage ] - - location: 13 (remaining gas: 1039988.041 units remaining) - [ (Pair { Elt "foo" 1 } None) @storage ] - - location: 15 (remaining gas: 1039988.031 units remaining) - [ { Elt "foo" 1 } ] - - location: 16 (remaining gas: 1039988.021 units remaining) - [ { Elt "foo" 1 } - { Elt "foo" 1 } ] - - location: 13 (remaining gas: 1039987.991 units remaining) - [ "bar" @parameter - { Elt "foo" 1 } - { Elt "foo" 1 } ] - - location: 17 (remaining gas: 1039987.841 units remaining) - [ False - { Elt "foo" 1 } ] - - location: 18 (remaining gas: 1039987.826 units remaining) - [ (Some False) - { Elt "foo" 1 } ] - - location: 19 (remaining gas: 1039987.816 units remaining) - [ { Elt "foo" 1 } - (Some False) ] - - location: 20 (remaining gas: 1039987.801 units remaining) - [ (Pair { Elt "foo" 1 } (Some False)) ] - - location: 21 (remaining gas: 1039987.786 units remaining) - [ {} - (Pair { Elt "foo" 1 } (Some False)) ] - - location: 23 (remaining gas: 1039987.771 units remaining) - [ (Pair {} { Elt "foo" 1 } (Some False)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair {} (Some False))].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair {} (Some False))].out" deleted file mode 100644 index d8eaa16bfc05..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair {} (Some False))].out" +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-"bar"-(Pair {} (Some False))] - -storage - (Pair {} (Some False)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039988.460 units remaining) - [ (Pair "bar" {} None) ] - - location: 12 (remaining gas: 1039988.450 units remaining) - [ "bar" @parameter - (Pair {} None) @storage ] - - location: 13 (remaining gas: 1039988.435 units remaining) - [ (Pair {} None) @storage ] - - location: 15 (remaining gas: 1039988.425 units remaining) - [ {} ] - - location: 16 (remaining gas: 1039988.415 units remaining) - [ {} - {} ] - - location: 13 (remaining gas: 1039988.385 units remaining) - [ "bar" @parameter - {} - {} ] - - location: 17 (remaining gas: 1039988.270 units remaining) - [ False - {} ] - - location: 18 (remaining gas: 1039988.255 units remaining) - [ (Some False) - {} ] - - location: 19 (remaining gas: 1039988.245 units remaining) - [ {} - (Some False) ] - - location: 20 (remaining gas: 1039988.230 units remaining) - [ (Pair {} (Some False)) ] - - location: 21 (remaining gas: 1039988.215 units remaining) - [ {} - (Pair {} (Some False)) ] - - location: 23 (remaining gas: 1039988.200 units remaining) - [ (Pair {} {} (Some False)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" deleted file mode 100644 index 6a9d61d2fa04..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 ; Elt "d" 4 ; Elt "e" 5 ; Elt "f" 6 }-6] - -storage - 6 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039991.503 units remaining) - [ (Pair { Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 ; Elt "d" 4 ; Elt "e" 5 ; Elt "f" 6 } 111) ] - - location: 9 (remaining gas: 1039991.493 units remaining) - [ { Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 ; Elt "d" 4 ; Elt "e" 5 ; Elt "f" 6 } @parameter ] - - location: 10 (remaining gas: 1039991.478 units remaining) - [ 6 ] - - location: 11 (remaining gas: 1039991.463 units remaining) - [ {} - 6 ] - - location: 13 (remaining gas: 1039991.448 units remaining) - [ (Pair {} 6) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" deleted file mode 100644 index 3c98980d1d46..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 }-3] - -storage - 3 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039993.290 units remaining) - [ (Pair { Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 } 111) ] - - location: 9 (remaining gas: 1039993.280 units remaining) - [ { Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 } @parameter ] - - location: 10 (remaining gas: 1039993.265 units remaining) - [ 3 ] - - location: 11 (remaining gas: 1039993.250 units remaining) - [ {} - 3 ] - - location: 13 (remaining gas: 1039993.235 units remaining) - [ (Pair {} 3) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 }-1].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 }-1].out" deleted file mode 100644 index 8d19f5b7c50b..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 }-1].out" +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt "a" 1 }-1] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039994.318 units remaining) - [ (Pair { Elt "a" 1 } 111) ] - - location: 9 (remaining gas: 1039994.308 units remaining) - [ { Elt "a" 1 } @parameter ] - - location: 10 (remaining gas: 1039994.293 units remaining) - [ 1 ] - - location: 11 (remaining gas: 1039994.278 units remaining) - [ {} - 1 ] - - location: 13 (remaining gas: 1039994.263 units remaining) - [ (Pair {} 1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0].out deleted file mode 100644 index 8d7ef741acac..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039994.692 units remaining) - [ (Pair {} 111) ] - - location: 9 (remaining gas: 1039994.682 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039994.667 units remaining) - [ 0 ] - - location: 11 (remaining gas: 1039994.652 units remaining) - [ {} - 0 ] - - location: 13 (remaining gas: 1039994.637 units remaining) - [ (Pair {} 0) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit].out deleted file mode 100644 index cec0840b05ac..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit].out +++ /dev/null @@ -1,131 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039944.576 units remaining) - [ (Pair Unit Unit) ] - - location: 7 (remaining gas: 1039944.566 units remaining) - [ Unit @parameter ] - - location: 8 (remaining gas: 1039944.556 units remaining) - [ ] - - location: 9 (remaining gas: 1039944.546 units remaining) - [ 7987 ] - - location: 12 (remaining gas: 1039944.536 units remaining) - [ 10 - 7987 ] - - location: 15 (remaining gas: 1039944.536 units remaining) - [ 79870 ] - - location: 16 (remaining gas: 1039944.526 units remaining) - [ 79870 - 79870 ] - - location: 19 (remaining gas: 1039944.491 units remaining) - [ 0 ] - - location: 21 (remaining gas: 1039944.476 units remaining) - [ True ] - - location: 22 (remaining gas: 1039944.466 units remaining) - [ ] - - location: 22 (remaining gas: 1039944.451 units remaining) - [ ] - - location: 28 (remaining gas: 1039944.441 units remaining) - [ 10 ] - - location: 31 (remaining gas: 1039944.431 units remaining) - [ 7987 - 10 ] - - location: 34 (remaining gas: 1039944.431 units remaining) - [ 79870 ] - - location: 35 (remaining gas: 1039944.421 units remaining) - [ 79870 - 79870 ] - - location: 38 (remaining gas: 1039944.386 units remaining) - [ 0 ] - - location: 40 (remaining gas: 1039944.371 units remaining) - [ True ] - - location: 41 (remaining gas: 1039944.361 units remaining) - [ ] - - location: 41 (remaining gas: 1039944.346 units remaining) - [ ] - - location: 47 (remaining gas: 1039944.336 units remaining) - [ 10 ] - - location: 50 (remaining gas: 1039944.326 units remaining) - [ -7987 - 10 ] - - location: 53 (remaining gas: 1039944.220 units remaining) - [ -79870 ] - - location: 54 (remaining gas: 1039944.210 units remaining) - [ -79870 - -79870 ] - - location: 57 (remaining gas: 1039944.175 units remaining) - [ 0 ] - - location: 59 (remaining gas: 1039944.160 units remaining) - [ True ] - - location: 60 (remaining gas: 1039944.150 units remaining) - [ ] - - location: 60 (remaining gas: 1039944.135 units remaining) - [ ] - - location: 66 (remaining gas: 1039944.125 units remaining) - [ 10 ] - - location: 69 (remaining gas: 1039944.115 units remaining) - [ -7987 - 10 ] - - location: 72 (remaining gas: 1039944.009 units remaining) - [ -79870 ] - - location: 73 (remaining gas: 1039943.999 units remaining) - [ -79870 - -79870 ] - - location: 76 (remaining gas: 1039943.964 units remaining) - [ 0 ] - - location: 78 (remaining gas: 1039943.949 units remaining) - [ True ] - - location: 79 (remaining gas: 1039943.939 units remaining) - [ ] - - location: 79 (remaining gas: 1039943.924 units remaining) - [ ] - - location: 85 (remaining gas: 1039943.914 units remaining) - [ -10 ] - - location: 88 (remaining gas: 1039943.904 units remaining) - [ 7987 - -10 ] - - location: 91 (remaining gas: 1039943.798 units remaining) - [ -79870 ] - - location: 92 (remaining gas: 1039943.788 units remaining) - [ -79870 - -79870 ] - - location: 95 (remaining gas: 1039943.753 units remaining) - [ 0 ] - - location: 97 (remaining gas: 1039943.738 units remaining) - [ True ] - - location: 98 (remaining gas: 1039943.728 units remaining) - [ ] - - location: 98 (remaining gas: 1039943.713 units remaining) - [ ] - - location: 104 (remaining gas: 1039943.703 units remaining) - [ 10 ] - - location: 107 (remaining gas: 1039943.693 units remaining) - [ 7987 - 10 ] - - location: 110 (remaining gas: 1039943.587 units remaining) - [ 79870 ] - - location: 111 (remaining gas: 1039943.577 units remaining) - [ 79870 - 79870 ] - - location: 114 (remaining gas: 1039943.542 units remaining) - [ 0 ] - - location: 116 (remaining gas: 1039943.527 units remaining) - [ True ] - - location: 117 (remaining gas: 1039943.517 units remaining) - [ ] - - location: 117 (remaining gas: 1039943.502 units remaining) - [ ] - - location: 123 (remaining gas: 1039943.492 units remaining) - [ Unit ] - - location: 124 (remaining gas: 1039943.477 units remaining) - [ {} - Unit ] - - location: 126 (remaining gas: 1039943.462 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000.be11332c7f.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000.be11332c7f.out deleted file mode 100644 index 8c209c0b84c3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000.be11332c7f.out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000000000000000000000000000000000000000000000000] - -storage - 0x0101000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039987.713 units remaining) - [ (Pair 257 0x0000000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039987.703 units remaining) - [ 257 @parameter ] - - location: 8 (remaining gas: 1039987.693 units remaining) - [ 1 - 257 @parameter ] - - location: 11 (remaining gas: 1039987.683 units remaining) - [ 257 @parameter - 1 ] - - location: 12 (remaining gas: 1039987.543 units remaining) - [ (Some (Pair 257 0)) ] - - location: 14 (remaining gas: 1039987.533 units remaining) - [ (Pair 257 0) @some ] - - location: 14 (remaining gas: 1039987.518 units remaining) - [ (Pair 257 0) @some ] - - location: 20 (remaining gas: 1039987.508 units remaining) - [ 257 ] - - location: 21 (remaining gas: 1039987.498 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 - 257 ] - - location: 24 (remaining gas: 1039987.166 units remaining) - [ 0x0101000000000000000000000000000000000000000000000000000000000000 ] - - location: 25 (remaining gas: 1039987.151 units remaining) - [ {} - 0x0101000000000000000000000000000000000000000000000000000000000000 ] - - location: 27 (remaining gas: 1039987.136 units remaining) - [ (Pair {} 0x0101000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x10000000000000000000.8230fb4fac.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x10000000000000000000.8230fb4fac.out deleted file mode 100644 index a38e72278e0d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x10000000000000000000.8230fb4fac.out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x1000000000000000000000000000000000000000000000000000000000000000] - -storage - 0x1000000000000000000000000000000000000000000000000000000000000000 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039987.713 units remaining) - [ (Pair 16 0x0200000000000000000000000000000000000000000000000000000000000000) ] - - location: 7 (remaining gas: 1039987.703 units remaining) - [ 16 @parameter ] - - location: 8 (remaining gas: 1039987.693 units remaining) - [ 1 - 16 @parameter ] - - location: 11 (remaining gas: 1039987.683 units remaining) - [ 16 @parameter - 1 ] - - location: 12 (remaining gas: 1039987.543 units remaining) - [ (Some (Pair 16 0)) ] - - location: 14 (remaining gas: 1039987.533 units remaining) - [ (Pair 16 0) @some ] - - location: 14 (remaining gas: 1039987.518 units remaining) - [ (Pair 16 0) @some ] - - location: 20 (remaining gas: 1039987.508 units remaining) - [ 16 ] - - location: 21 (remaining gas: 1039987.498 units remaining) - [ 0x0100000000000000000000000000000000000000000000000000000000000000 - 16 ] - - location: 24 (remaining gas: 1039987.167 units remaining) - [ 0x1000000000000000000000000000000000000000000000000000000000000000 ] - - location: 25 (remaining gas: 1039987.152 units remaining) - [ {} - 0x1000000000000000000000000000000000000000000000000000000000000000 ] - - location: 27 (remaining gas: 1039987.137 units remaining) - [ (Pair {} 0x1000000000000000000000000000000000000000000000000000000000000000) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2].out deleted file mode 100644 index 0867b5c733dd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2].out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2] - -storage - 2 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.641 units remaining) - [ (Pair (Left -2) 0) ] - - location: 9 (remaining gas: 1039992.631 units remaining) - [ (Left -2) @parameter ] - - location: 10 (remaining gas: 1039992.621 units remaining) - [ -2 @parameter.left ] - - location: 12 (remaining gas: 1039992.581 units remaining) - [ 2 ] - - location: 10 (remaining gas: 1039992.566 units remaining) - [ 2 ] - - location: 15 (remaining gas: 1039992.551 units remaining) - [ {} - 2 ] - - location: 17 (remaining gas: 1039992.536 units remaining) - [ (Pair {} 2) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0].out deleted file mode 100644 index 4ca986199d07..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0].out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.641 units remaining) - [ (Pair (Left 0) 0) ] - - location: 9 (remaining gas: 1039992.631 units remaining) - [ (Left 0) @parameter ] - - location: 10 (remaining gas: 1039992.621 units remaining) - [ 0 @parameter.left ] - - location: 12 (remaining gas: 1039992.581 units remaining) - [ 0 ] - - location: 10 (remaining gas: 1039992.566 units remaining) - [ 0 ] - - location: 15 (remaining gas: 1039992.551 units remaining) - [ {} - 0 ] - - location: 17 (remaining gas: 1039992.536 units remaining) - [ (Pair {} 0) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2].out deleted file mode 100644 index f9001507df02..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2].out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2] - -storage - -2 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.641 units remaining) - [ (Pair (Left 2) 0) ] - - location: 9 (remaining gas: 1039992.631 units remaining) - [ (Left 2) @parameter ] - - location: 10 (remaining gas: 1039992.621 units remaining) - [ 2 @parameter.left ] - - location: 12 (remaining gas: 1039992.581 units remaining) - [ -2 ] - - location: 10 (remaining gas: 1039992.566 units remaining) - [ -2 ] - - location: 15 (remaining gas: 1039992.551 units remaining) - [ {} - -2 ] - - location: 17 (remaining gas: 1039992.536 units remaining) - [ (Pair {} -2) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0].out deleted file mode 100644 index b1951ca8b639..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0].out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.641 units remaining) - [ (Pair (Right 0) 0) ] - - location: 9 (remaining gas: 1039992.631 units remaining) - [ (Right 0) @parameter ] - - location: 10 (remaining gas: 1039992.621 units remaining) - [ 0 @parameter.right ] - - location: 14 (remaining gas: 1039992.581 units remaining) - [ 0 ] - - location: 10 (remaining gas: 1039992.566 units remaining) - [ 0 ] - - location: 15 (remaining gas: 1039992.551 units remaining) - [ {} - 0 ] - - location: 17 (remaining gas: 1039992.536 units remaining) - [ (Pair {} 0) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2].out deleted file mode 100644 index 690fc426fac7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2].out +++ /dev/null @@ -1,25 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2] - -storage - -2 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039992.641 units remaining) - [ (Pair (Right 2) 0) ] - - location: 9 (remaining gas: 1039992.631 units remaining) - [ (Right 2) @parameter ] - - location: 10 (remaining gas: 1039992.621 units remaining) - [ 2 @parameter.right ] - - location: 14 (remaining gas: 1039992.581 units remaining) - [ -2 ] - - location: 10 (remaining gas: 1039992.566 units remaining) - [ -2 ] - - location: 15 (remaining gas: 1039992.551 units remaining) - [ {} - -2 ] - - location: 17 (remaining gas: 1039992.536 units remaining) - [ (Pair {} -2) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None].out deleted file mode 100644 index 99b08e73f2b8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None] - -storage - None -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.327 units remaining) - [ (Pair Unit (Some 10)) ] - - location: 8 (remaining gas: 1039994.317 units remaining) - [ ] - - location: 9 (remaining gas: 1039994.302 units remaining) - [ None ] - - location: 11 (remaining gas: 1039994.287 units remaining) - [ {} - None ] - - location: 13 (remaining gas: 1039994.272 units remaining) - [ (Pair {} None) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)].out deleted file mode 100644 index 260d89338a55..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.957 units remaining) - [ (Pair False None) ] - - location: 8 (remaining gas: 1039993.947 units remaining) - [ False @parameter ] - - location: 9 (remaining gas: 1039993.937 units remaining) - [ True ] - - location: 10 (remaining gas: 1039993.922 units remaining) - [ (Some True) ] - - location: 11 (remaining gas: 1039993.907 units remaining) - [ {} - (Some True) ] - - location: 13 (remaining gas: 1039993.892 units remaining) - [ (Pair {} (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)].out deleted file mode 100644 index a562518ab7c7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)] - -storage - (Some False) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.957 units remaining) - [ (Pair True None) ] - - location: 8 (remaining gas: 1039993.947 units remaining) - [ True @parameter ] - - location: 9 (remaining gas: 1039993.937 units remaining) - [ False ] - - location: 10 (remaining gas: 1039993.922 units remaining) - [ (Some False) ] - - location: 11 (remaining gas: 1039993.907 units remaining) - [ {} - (Some False) ] - - location: 13 (remaining gas: 1039993.892 units remaining) - [ (Pair {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)].out deleted file mode 100644 index 8959830172dc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)] - -storage - (Some 7) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.640 units remaining) - [ (Pair (Left -8) None) ] - - location: 10 (remaining gas: 1039991.630 units remaining) - [ (Left -8) @parameter ] - - location: 11 (remaining gas: 1039991.620 units remaining) - [ -8 @parameter.left ] - - location: 13 (remaining gas: 1039991.570 units remaining) - [ 7 ] - - location: 11 (remaining gas: 1039991.555 units remaining) - [ 7 ] - - location: 16 (remaining gas: 1039991.540 units remaining) - [ (Some 7) ] - - location: 17 (remaining gas: 1039991.525 units remaining) - [ {} - (Some 7) ] - - location: 19 (remaining gas: 1039991.510 units remaining) - [ (Pair {} (Some 7)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)].out deleted file mode 100644 index ca49cf1ecc31..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)] - -storage - (Some 8) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.640 units remaining) - [ (Pair (Left -9) None) ] - - location: 10 (remaining gas: 1039991.630 units remaining) - [ (Left -9) @parameter ] - - location: 11 (remaining gas: 1039991.620 units remaining) - [ -9 @parameter.left ] - - location: 13 (remaining gas: 1039991.570 units remaining) - [ 8 ] - - location: 11 (remaining gas: 1039991.555 units remaining) - [ 8 ] - - location: 16 (remaining gas: 1039991.540 units remaining) - [ (Some 8) ] - - location: 17 (remaining gas: 1039991.525 units remaining) - [ {} - (Some 8) ] - - location: 19 (remaining gas: 1039991.510 units remaining) - [ (Pair {} (Some 8)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)].out deleted file mode 100644 index 3e9e63e63200..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)] - -storage - (Some -1) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.640 units remaining) - [ (Pair (Left 0) None) ] - - location: 10 (remaining gas: 1039991.630 units remaining) - [ (Left 0) @parameter ] - - location: 11 (remaining gas: 1039991.620 units remaining) - [ 0 @parameter.left ] - - location: 13 (remaining gas: 1039991.570 units remaining) - [ -1 ] - - location: 11 (remaining gas: 1039991.555 units remaining) - [ -1 ] - - location: 16 (remaining gas: 1039991.540 units remaining) - [ (Some -1) ] - - location: 17 (remaining gas: 1039991.525 units remaining) - [ {} - (Some -1) ] - - location: 19 (remaining gas: 1039991.510 units remaining) - [ (Pair {} (Some -1)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)].out deleted file mode 100644 index 0ce373cf61af..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)] - -storage - (Some -8) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.640 units remaining) - [ (Pair (Left 7) None) ] - - location: 10 (remaining gas: 1039991.630 units remaining) - [ (Left 7) @parameter ] - - location: 11 (remaining gas: 1039991.620 units remaining) - [ 7 @parameter.left ] - - location: 13 (remaining gas: 1039991.570 units remaining) - [ -8 ] - - location: 11 (remaining gas: 1039991.555 units remaining) - [ -8 ] - - location: 16 (remaining gas: 1039991.540 units remaining) - [ (Some -8) ] - - location: 17 (remaining gas: 1039991.525 units remaining) - [ {} - (Some -8) ] - - location: 19 (remaining gas: 1039991.510 units remaining) - [ (Pair {} (Some -8)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)].out deleted file mode 100644 index 341cb4eb8780..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)] - -storage - (Some -9) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.640 units remaining) - [ (Pair (Left 8) None) ] - - location: 10 (remaining gas: 1039991.630 units remaining) - [ (Left 8) @parameter ] - - location: 11 (remaining gas: 1039991.620 units remaining) - [ 8 @parameter.left ] - - location: 13 (remaining gas: 1039991.570 units remaining) - [ -9 ] - - location: 11 (remaining gas: 1039991.555 units remaining) - [ -9 ] - - location: 16 (remaining gas: 1039991.540 units remaining) - [ (Some -9) ] - - location: 17 (remaining gas: 1039991.525 units remaining) - [ {} - (Some -9) ] - - location: 19 (remaining gas: 1039991.510 units remaining) - [ (Pair {} (Some -9)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)].out deleted file mode 100644 index f8004a52381e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)] - -storage - (Some -1) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.640 units remaining) - [ (Pair (Right 0) None) ] - - location: 10 (remaining gas: 1039991.630 units remaining) - [ (Right 0) @parameter ] - - location: 11 (remaining gas: 1039991.620 units remaining) - [ 0 @parameter.right ] - - location: 15 (remaining gas: 1039991.570 units remaining) - [ -1 ] - - location: 11 (remaining gas: 1039991.555 units remaining) - [ -1 ] - - location: 16 (remaining gas: 1039991.540 units remaining) - [ (Some -1) ] - - location: 17 (remaining gas: 1039991.525 units remaining) - [ {} - (Some -1) ] - - location: 19 (remaining gas: 1039991.510 units remaining) - [ (Pair {} (Some -1)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)].out deleted file mode 100644 index e2ab81878c2d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)] - -storage - (Some -8) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.640 units remaining) - [ (Pair (Right 7) None) ] - - location: 10 (remaining gas: 1039991.630 units remaining) - [ (Right 7) @parameter ] - - location: 11 (remaining gas: 1039991.620 units remaining) - [ 7 @parameter.right ] - - location: 15 (remaining gas: 1039991.570 units remaining) - [ -8 ] - - location: 11 (remaining gas: 1039991.555 units remaining) - [ -8 ] - - location: 16 (remaining gas: 1039991.540 units remaining) - [ (Some -8) ] - - location: 17 (remaining gas: 1039991.525 units remaining) - [ {} - (Some -8) ] - - location: 19 (remaining gas: 1039991.510 units remaining) - [ (Pair {} (Some -8)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)].out deleted file mode 100644 index aed6afe4314b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)] - -storage - (Some -9) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039991.640 units remaining) - [ (Pair (Right 8) None) ] - - location: 10 (remaining gas: 1039991.630 units remaining) - [ (Right 8) @parameter ] - - location: 11 (remaining gas: 1039991.620 units remaining) - [ 8 @parameter.right ] - - location: 15 (remaining gas: 1039991.570 units remaining) - [ -9 ] - - location: 11 (remaining gas: 1039991.555 units remaining) - [ -9 ] - - location: 16 (remaining gas: 1039991.540 units remaining) - [ (Some -9) ] - - location: 17 (remaining gas: 1039991.525 units remaining) - [ {} - (Some -9) ] - - location: 19 (remaining gas: 1039991.510 units remaining) - [ (Pair {} (Some -9)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)].out deleted file mode 100644 index 5b96023794ae..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)].out +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)] - -storage - (Some False) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.715 units remaining) - [ (Pair (Pair False False) None) ] - - location: 10 (remaining gas: 1039990.705 units remaining) - [ (Pair False False) @parameter ] - - location: 11 (remaining gas: 1039990.695 units remaining) - [ (Pair False False) @parameter - (Pair False False) @parameter ] - - location: 12 (remaining gas: 1039990.685 units remaining) - [ False - (Pair False False) @parameter ] - - location: 13 (remaining gas: 1039990.675 units remaining) - [ (Pair False False) @parameter - False ] - - location: 14 (remaining gas: 1039990.665 units remaining) - [ False - False ] - - location: 15 (remaining gas: 1039990.650 units remaining) - [ False ] - - location: 16 (remaining gas: 1039990.635 units remaining) - [ (Some False) ] - - location: 17 (remaining gas: 1039990.620 units remaining) - [ {} - (Some False) ] - - location: 19 (remaining gas: 1039990.605 units remaining) - [ (Pair {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)].out deleted file mode 100644 index 0145dbad770b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)].out +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.715 units remaining) - [ (Pair (Pair False True) None) ] - - location: 10 (remaining gas: 1039990.705 units remaining) - [ (Pair False True) @parameter ] - - location: 11 (remaining gas: 1039990.695 units remaining) - [ (Pair False True) @parameter - (Pair False True) @parameter ] - - location: 12 (remaining gas: 1039990.685 units remaining) - [ False - (Pair False True) @parameter ] - - location: 13 (remaining gas: 1039990.675 units remaining) - [ (Pair False True) @parameter - False ] - - location: 14 (remaining gas: 1039990.665 units remaining) - [ True - False ] - - location: 15 (remaining gas: 1039990.650 units remaining) - [ True ] - - location: 16 (remaining gas: 1039990.635 units remaining) - [ (Some True) ] - - location: 17 (remaining gas: 1039990.620 units remaining) - [ {} - (Some True) ] - - location: 19 (remaining gas: 1039990.605 units remaining) - [ (Pair {} (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)].out deleted file mode 100644 index 5ca2b285f0ba..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)].out +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.715 units remaining) - [ (Pair (Pair True False) None) ] - - location: 10 (remaining gas: 1039990.705 units remaining) - [ (Pair True False) @parameter ] - - location: 11 (remaining gas: 1039990.695 units remaining) - [ (Pair True False) @parameter - (Pair True False) @parameter ] - - location: 12 (remaining gas: 1039990.685 units remaining) - [ True - (Pair True False) @parameter ] - - location: 13 (remaining gas: 1039990.675 units remaining) - [ (Pair True False) @parameter - True ] - - location: 14 (remaining gas: 1039990.665 units remaining) - [ False - True ] - - location: 15 (remaining gas: 1039990.650 units remaining) - [ True ] - - location: 16 (remaining gas: 1039990.635 units remaining) - [ (Some True) ] - - location: 17 (remaining gas: 1039990.620 units remaining) - [ {} - (Some True) ] - - location: 19 (remaining gas: 1039990.605 units remaining) - [ (Pair {} (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)].out deleted file mode 100644 index 50bd4b5a9c56..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)].out +++ /dev/null @@ -1,35 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)] - -storage - (Some True) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039990.715 units remaining) - [ (Pair (Pair True True) None) ] - - location: 10 (remaining gas: 1039990.705 units remaining) - [ (Pair True True) @parameter ] - - location: 11 (remaining gas: 1039990.695 units remaining) - [ (Pair True True) @parameter - (Pair True True) @parameter ] - - location: 12 (remaining gas: 1039990.685 units remaining) - [ True - (Pair True True) @parameter ] - - location: 13 (remaining gas: 1039990.675 units remaining) - [ (Pair True True) @parameter - True ] - - location: 14 (remaining gas: 1039990.665 units remaining) - [ True - True ] - - location: 15 (remaining gas: 1039990.650 units remaining) - [ True ] - - location: 16 (remaining gas: 1039990.635 units remaining) - [ (Some True) ] - - location: 17 (remaining gas: 1039990.620 units remaining) - [ {} - (Some True) ] - - location: 19 (remaining gas: 1039990.605 units remaining) - [ (Pair {} (Some True)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)].out deleted file mode 100644 index fe0f77583800..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)] - -storage - (Some 8) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.824 units remaining) - [ (Pair (Pair 0 8) None) ] - - location: 10 (remaining gas: 1039992.814 units remaining) - [ (Pair 0 8) @parameter ] - - location: 11 (remaining gas: 1039992.804 units remaining) - [ 0 - 8 ] - - location: 12 (remaining gas: 1039992.749 units remaining) - [ 8 ] - - location: 13 (remaining gas: 1039992.734 units remaining) - [ (Some 8) ] - - location: 14 (remaining gas: 1039992.719 units remaining) - [ {} - (Some 8) ] - - location: 16 (remaining gas: 1039992.704 units remaining) - [ (Pair {} (Some 8)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)].out deleted file mode 100644 index 58de04bbb320..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)] - -storage - (Some 15) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.824 units remaining) - [ (Pair (Pair 14 1) None) ] - - location: 10 (remaining gas: 1039992.814 units remaining) - [ (Pair 14 1) @parameter ] - - location: 11 (remaining gas: 1039992.804 units remaining) - [ 14 - 1 ] - - location: 12 (remaining gas: 1039992.749 units remaining) - [ 15 ] - - location: 13 (remaining gas: 1039992.734 units remaining) - [ (Some 15) ] - - location: 14 (remaining gas: 1039992.719 units remaining) - [ {} - (Some 15) ] - - location: 16 (remaining gas: 1039992.704 units remaining) - [ (Pair {} (Some 15)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)].out deleted file mode 100644 index 5916c50e9f91..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)] - -storage - (Some 15) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.824 units remaining) - [ (Pair (Pair 15 4) None) ] - - location: 10 (remaining gas: 1039992.814 units remaining) - [ (Pair 15 4) @parameter ] - - location: 11 (remaining gas: 1039992.804 units remaining) - [ 15 - 4 ] - - location: 12 (remaining gas: 1039992.749 units remaining) - [ 15 ] - - location: 13 (remaining gas: 1039992.734 units remaining) - [ (Some 15) ] - - location: 14 (remaining gas: 1039992.719 units remaining) - [ {} - (Some 15) ] - - location: 16 (remaining gas: 1039992.704 units remaining) - [ (Pair {} (Some 15)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)].out deleted file mode 100644 index 97adce911211..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)] - -storage - (Some 12) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.824 units remaining) - [ (Pair (Pair 4 8) None) ] - - location: 10 (remaining gas: 1039992.814 units remaining) - [ (Pair 4 8) @parameter ] - - location: 11 (remaining gas: 1039992.804 units remaining) - [ 4 - 8 ] - - location: 12 (remaining gas: 1039992.749 units remaining) - [ 12 ] - - location: 13 (remaining gas: 1039992.734 units remaining) - [ (Some 12) ] - - location: 14 (remaining gas: 1039992.719 units remaining) - [ {} - (Some 12) ] - - location: 16 (remaining gas: 1039992.704 units remaining) - [ (Pair {} (Some 12)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)].out deleted file mode 100644 index f3fcd58b547a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)] - -storage - (Some 7) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.824 units remaining) - [ (Pair (Pair 7 7) None) ] - - location: 10 (remaining gas: 1039992.814 units remaining) - [ (Pair 7 7) @parameter ] - - location: 11 (remaining gas: 1039992.804 units remaining) - [ 7 - 7 ] - - location: 12 (remaining gas: 1039992.749 units remaining) - [ 7 ] - - location: 13 (remaining gas: 1039992.734 units remaining) - [ (Some 7) ] - - location: 14 (remaining gas: 1039992.719 units remaining) - [ {} - (Some 7) ] - - location: 16 (remaining gas: 1039992.704 units remaining) - [ (Pair {} (Some 7)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)].out deleted file mode 100644 index 6e3c16582f08..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)].out +++ /dev/null @@ -1,26 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)] - -storage - (Some 8) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039992.824 units remaining) - [ (Pair (Pair 8 0) None) ] - - location: 10 (remaining gas: 1039992.814 units remaining) - [ (Pair 8 0) @parameter ] - - location: 11 (remaining gas: 1039992.804 units remaining) - [ 8 - 0 ] - - location: 12 (remaining gas: 1039992.749 units remaining) - [ 8 ] - - location: 13 (remaining gas: 1039992.734 units remaining) - [ (Some 8) ] - - location: 14 (remaining gas: 1039992.719 units remaining) - [ {} - (Some 8) ] - - location: 16 (remaining gas: 1039992.704 units remaining) - [ (Pair {} (Some 8)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".368bdfd73a.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".368bdfd73a.out" deleted file mode 100644 index d24dc5144bda..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".368bdfd73a.out" +++ /dev/null @@ -1,845 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair "foobar" (Pair 0x00AABBCC (Pair 1000 (Pair False (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"))))))))-Unit1] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039185.305 units remaining) - [ (Pair (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - Unit) ] - - location: 16 (remaining gas: 1039185.295 units remaining) - [ (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] - - location: 17 (remaining gas: 1039185.285 units remaining) - [ (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter - (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] - - location: 18 (remaining gas: 1039185.275 units remaining) - [ -1 - (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] - - location: 19 (remaining gas: 1039185.260 units remaining) - [ (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] - - location: 21 (remaining gas: 1039185.250 units remaining) - [ -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 19 (remaining gas: 1039185.220 units remaining) - [ -1 - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 22 (remaining gas: 1039184.993 units remaining) - [ 0x050041 @packed - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 23 (remaining gas: 1039184.573 units remaining) - [ (Some -1) @packed.unpacked - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 26 (remaining gas: 1039184.563 units remaining) - [ -1 @packed.unpacked.some - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 26 (remaining gas: 1039184.548 units remaining) - [ -1 @packed.unpacked.some - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 34 (remaining gas: 1039184.513 units remaining) - [ 0 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 35 (remaining gas: 1039184.498 units remaining) - [ True - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 36 (remaining gas: 1039184.488 units remaining) - [ (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 36 (remaining gas: 1039184.473 units remaining) - [ (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 42 (remaining gas: 1039184.463 units remaining) - [ (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 43 (remaining gas: 1039184.453 units remaining) - [ 1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 44 (remaining gas: 1039184.438 units remaining) - [ (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 46 (remaining gas: 1039184.428 units remaining) - [ 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 44 (remaining gas: 1039184.398 units remaining) - [ 1 - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 47 (remaining gas: 1039184.171 units remaining) - [ 0x050001 @packed - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 48 (remaining gas: 1039183.751 units remaining) - [ (Some 1) @packed.unpacked - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 51 (remaining gas: 1039183.741 units remaining) - [ 1 @packed.unpacked.some - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 51 (remaining gas: 1039183.726 units remaining) - [ 1 @packed.unpacked.some - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 59 (remaining gas: 1039183.691 units remaining) - [ 0 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 60 (remaining gas: 1039183.676 units remaining) - [ True - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 61 (remaining gas: 1039183.666 units remaining) - [ (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 61 (remaining gas: 1039183.651 units remaining) - [ (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 67 (remaining gas: 1039183.641 units remaining) - [ (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 68 (remaining gas: 1039183.631 units remaining) - [ "foobar" - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 69 (remaining gas: 1039183.616 units remaining) - [ (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 71 (remaining gas: 1039183.606 units remaining) - [ "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 69 (remaining gas: 1039183.576 units remaining) - [ "foobar" - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 72 (remaining gas: 1039183.052 units remaining) - [ 0x050100000006666f6f626172 @packed - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 73 (remaining gas: 1039182.377 units remaining) - [ (Some "foobar") @packed.unpacked - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 76 (remaining gas: 1039182.367 units remaining) - [ "foobar" @packed.unpacked.some - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 76 (remaining gas: 1039182.352 units remaining) - [ "foobar" @packed.unpacked.some - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 84 (remaining gas: 1039182.317 units remaining) - [ 0 - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 85 (remaining gas: 1039182.302 units remaining) - [ True - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 86 (remaining gas: 1039182.292 units remaining) - [ (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 86 (remaining gas: 1039182.277 units remaining) - [ (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 92 (remaining gas: 1039182.267 units remaining) - [ (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 93 (remaining gas: 1039182.257 units remaining) - [ 0x00aabbcc - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 94 (remaining gas: 1039182.242 units remaining) - [ (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 96 (remaining gas: 1039182.232 units remaining) - [ 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 94 (remaining gas: 1039182.202 units remaining) - [ 0x00aabbcc - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 97 (remaining gas: 1039181.744 units remaining) - [ 0x050a0000000400aabbcc @packed - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 98 (remaining gas: 1039181.183 units remaining) - [ (Some 0x00aabbcc) @packed.unpacked - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 101 (remaining gas: 1039181.173 units remaining) - [ 0x00aabbcc @packed.unpacked.some - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 101 (remaining gas: 1039181.158 units remaining) - [ 0x00aabbcc @packed.unpacked.some - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 109 (remaining gas: 1039181.123 units remaining) - [ 0 - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 110 (remaining gas: 1039181.108 units remaining) - [ True - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 111 (remaining gas: 1039181.098 units remaining) - [ (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 111 (remaining gas: 1039181.083 units remaining) - [ (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 117 (remaining gas: 1039181.073 units remaining) - [ (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 118 (remaining gas: 1039181.063 units remaining) - [ 1000 - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 119 (remaining gas: 1039181.048 units remaining) - [ (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 121 (remaining gas: 1039181.038 units remaining) - [ 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 119 (remaining gas: 1039181.008 units remaining) - [ 1000 - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 122 (remaining gas: 1039180.748 units remaining) - [ 0x0500a80f @packed - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 123 (remaining gas: 1039180.308 units remaining) - [ (Some 1000) @packed.unpacked - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 126 (remaining gas: 1039180.298 units remaining) - [ 1000 @packed.unpacked.some - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 126 (remaining gas: 1039180.283 units remaining) - [ 1000 @packed.unpacked.some - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 134 (remaining gas: 1039180.248 units remaining) - [ 0 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 135 (remaining gas: 1039180.233 units remaining) - [ True - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 136 (remaining gas: 1039180.223 units remaining) - [ (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 136 (remaining gas: 1039180.208 units remaining) - [ (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 142 (remaining gas: 1039180.198 units remaining) - [ (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 143 (remaining gas: 1039180.188 units remaining) - [ False - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 144 (remaining gas: 1039180.173 units remaining) - [ (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 146 (remaining gas: 1039180.163 units remaining) - [ False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 144 (remaining gas: 1039180.133 units remaining) - [ False - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 147 (remaining gas: 1039179.906 units remaining) - [ 0x050303 @packed - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 148 (remaining gas: 1039179.486 units remaining) - [ (Some False) @packed.unpacked - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 151 (remaining gas: 1039179.476 units remaining) - [ False @packed.unpacked.some - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 151 (remaining gas: 1039179.461 units remaining) - [ False @packed.unpacked.some - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 159 (remaining gas: 1039179.426 units remaining) - [ 0 - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 160 (remaining gas: 1039179.411 units remaining) - [ True - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 161 (remaining gas: 1039179.401 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 161 (remaining gas: 1039179.386 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 167 (remaining gas: 1039179.376 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 168 (remaining gas: 1039179.366 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 169 (remaining gas: 1039179.351 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 171 (remaining gas: 1039179.341 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 169 (remaining gas: 1039179.311 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 172 (remaining gas: 1039178.221 units remaining) - [ 0x050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 173 (remaining gas: 1039177.268 units remaining) - [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 176 (remaining gas: 1039177.258 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 176 (remaining gas: 1039177.243 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 184 (remaining gas: 1039177.207 units remaining) - [ 0 - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 185 (remaining gas: 1039177.192 units remaining) - [ True - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 186 (remaining gas: 1039177.182 units remaining) - [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 186 (remaining gas: 1039177.167 units remaining) - [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 192 (remaining gas: 1039177.157 units remaining) - [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 193 (remaining gas: 1039177.147 units remaining) - [ "2019-09-09T08:35:33Z" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 194 (remaining gas: 1039177.132 units remaining) - [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 196 (remaining gas: 1039177.122 units remaining) - [ "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 194 (remaining gas: 1039177.092 units remaining) - [ "2019-09-09T08:35:33Z" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 197 (remaining gas: 1039176.733 units remaining) - [ 0x050095bbb0d70b @packed - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 198 (remaining gas: 1039176.233 units remaining) - [ (Some "2019-09-09T08:35:33Z") @packed.unpacked - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 201 (remaining gas: 1039176.223 units remaining) - [ "2019-09-09T08:35:33Z" @packed.unpacked.some - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 201 (remaining gas: 1039176.208 units remaining) - [ "2019-09-09T08:35:33Z" @packed.unpacked.some - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 209 (remaining gas: 1039176.173 units remaining) - [ 0 - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 210 (remaining gas: 1039176.158 units remaining) - [ True - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 211 (remaining gas: 1039176.148 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 211 (remaining gas: 1039176.133 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 217 (remaining gas: 1039176.123 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 218 (remaining gas: 1039165.170 units remaining) - [ 0x050a000000160000bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 219 (remaining gas: 1038514.247 units remaining) - [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 222 (remaining gas: 1038514.237 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 222 (remaining gas: 1038514.222 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 230 (remaining gas: 1038514.186 units remaining) - [ 0 ] - - location: 231 (remaining gas: 1038514.171 units remaining) - [ True ] - - location: 232 (remaining gas: 1038514.161 units remaining) - [ ] - - location: 232 (remaining gas: 1038514.146 units remaining) - [ ] - - location: 238 (remaining gas: 1038514.136 units remaining) - [ 0 ] - - location: 241 (remaining gas: 1038513.909 units remaining) - [ 0x050000 @packed ] - - location: 242 (remaining gas: 1038513.489 units remaining) - [ (Some 0) @packed.unpacked ] - - location: 245 (remaining gas: 1038513.479 units remaining) - [ 0 @packed.unpacked.some ] - - location: 245 (remaining gas: 1038513.464 units remaining) - [ 0 @packed.unpacked.some ] - - location: 251 (remaining gas: 1038513.454 units remaining) - [ ] - - location: 252 (remaining gas: 1038513.444 units remaining) - [ -1 ] - - location: 255 (remaining gas: 1038513.217 units remaining) - [ 0x050041 @packed ] - - location: 256 (remaining gas: 1038416.897 units remaining) - [ None @packed.unpacked ] - - location: 259 (remaining gas: 1038416.887 units remaining) - [ ] - - location: 259 (remaining gas: 1038416.872 units remaining) - [ ] - - location: 265 (remaining gas: 1038416.862 units remaining) - [ 0x ] - - location: 268 (remaining gas: 1038416.602 units remaining) - [ None @unpacked ] - - location: 271 (remaining gas: 1038416.592 units remaining) - [ ] - - location: 271 (remaining gas: 1038416.577 units remaining) - [ ] - - location: 277 (remaining gas: 1038416.567 units remaining) - [ 0x04 ] - - location: 280 (remaining gas: 1038416.287 units remaining) - [ None @unpacked ] - - location: 283 (remaining gas: 1038416.277 units remaining) - [ ] - - location: 283 (remaining gas: 1038416.262 units remaining) - [ ] - - location: 289 (remaining gas: 1038416.252 units remaining) - [ 0x05 ] - - location: 292 (remaining gas: 1038415.972 units remaining) - [ None @unpacked ] - - location: 295 (remaining gas: 1038415.962 units remaining) - [ ] - - location: 295 (remaining gas: 1038415.947 units remaining) - [ ] - - location: 301 (remaining gas: 1038415.937 units remaining) - [ Unit ] - - location: 302 (remaining gas: 1038415.922 units remaining) - [ {} - Unit ] - - location: 304 (remaining gas: 1038415.907 units remaining) - [ (Pair {} Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".735d9ae802.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".735d9ae802.out" deleted file mode 100644 index 89f333f82bd8..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".735d9ae802.out" +++ /dev/null @@ -1,845 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair "foobar" (Pair 0x00AABBCC (Pair 1000 (Pair False (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"))))))))-Unit0] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039185.305 units remaining) - [ (Pair (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - Unit) ] - - location: 16 (remaining gas: 1039185.295 units remaining) - [ (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] - - location: 17 (remaining gas: 1039185.285 units remaining) - [ (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter - (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] - - location: 18 (remaining gas: 1039185.275 units remaining) - [ -1 - (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] - - location: 19 (remaining gas: 1039185.260 units remaining) - [ (Pair -1 - 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] - - location: 21 (remaining gas: 1039185.250 units remaining) - [ -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 19 (remaining gas: 1039185.220 units remaining) - [ -1 - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 22 (remaining gas: 1039184.993 units remaining) - [ 0x050041 @packed - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 23 (remaining gas: 1039184.573 units remaining) - [ (Some -1) @packed.unpacked - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 26 (remaining gas: 1039184.563 units remaining) - [ -1 @packed.unpacked.some - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 26 (remaining gas: 1039184.548 units remaining) - [ -1 @packed.unpacked.some - -1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 34 (remaining gas: 1039184.513 units remaining) - [ 0 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 35 (remaining gas: 1039184.498 units remaining) - [ True - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 36 (remaining gas: 1039184.488 units remaining) - [ (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 36 (remaining gas: 1039184.473 units remaining) - [ (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 42 (remaining gas: 1039184.463 units remaining) - [ (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 43 (remaining gas: 1039184.453 units remaining) - [ 1 - (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 44 (remaining gas: 1039184.438 units remaining) - [ (Pair 1 - "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 46 (remaining gas: 1039184.428 units remaining) - [ 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 44 (remaining gas: 1039184.398 units remaining) - [ 1 - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 47 (remaining gas: 1039184.171 units remaining) - [ 0x050001 @packed - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 48 (remaining gas: 1039183.751 units remaining) - [ (Some 1) @packed.unpacked - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 51 (remaining gas: 1039183.741 units remaining) - [ 1 @packed.unpacked.some - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 51 (remaining gas: 1039183.726 units remaining) - [ 1 @packed.unpacked.some - 1 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 59 (remaining gas: 1039183.691 units remaining) - [ 0 - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 60 (remaining gas: 1039183.676 units remaining) - [ True - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 61 (remaining gas: 1039183.666 units remaining) - [ (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 61 (remaining gas: 1039183.651 units remaining) - [ (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 67 (remaining gas: 1039183.641 units remaining) - [ (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 68 (remaining gas: 1039183.631 units remaining) - [ "foobar" - (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 69 (remaining gas: 1039183.616 units remaining) - [ (Pair "foobar" - 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 71 (remaining gas: 1039183.606 units remaining) - [ "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 69 (remaining gas: 1039183.576 units remaining) - [ "foobar" - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 72 (remaining gas: 1039183.052 units remaining) - [ 0x050100000006666f6f626172 @packed - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 73 (remaining gas: 1039182.377 units remaining) - [ (Some "foobar") @packed.unpacked - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 76 (remaining gas: 1039182.367 units remaining) - [ "foobar" @packed.unpacked.some - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 76 (remaining gas: 1039182.352 units remaining) - [ "foobar" @packed.unpacked.some - "foobar" - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 84 (remaining gas: 1039182.317 units remaining) - [ 0 - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 85 (remaining gas: 1039182.302 units remaining) - [ True - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 86 (remaining gas: 1039182.292 units remaining) - [ (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 86 (remaining gas: 1039182.277 units remaining) - [ (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 92 (remaining gas: 1039182.267 units remaining) - [ (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 93 (remaining gas: 1039182.257 units remaining) - [ 0x00aabbcc - (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 94 (remaining gas: 1039182.242 units remaining) - [ (Pair 0x00aabbcc - 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 96 (remaining gas: 1039182.232 units remaining) - [ 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 94 (remaining gas: 1039182.202 units remaining) - [ 0x00aabbcc - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 97 (remaining gas: 1039181.744 units remaining) - [ 0x050a0000000400aabbcc @packed - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 98 (remaining gas: 1039181.183 units remaining) - [ (Some 0x00aabbcc) @packed.unpacked - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 101 (remaining gas: 1039181.173 units remaining) - [ 0x00aabbcc @packed.unpacked.some - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 101 (remaining gas: 1039181.158 units remaining) - [ 0x00aabbcc @packed.unpacked.some - 0x00aabbcc - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 109 (remaining gas: 1039181.123 units remaining) - [ 0 - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 110 (remaining gas: 1039181.108 units remaining) - [ True - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 111 (remaining gas: 1039181.098 units remaining) - [ (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 111 (remaining gas: 1039181.083 units remaining) - [ (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 117 (remaining gas: 1039181.073 units remaining) - [ (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 118 (remaining gas: 1039181.063 units remaining) - [ 1000 - (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 119 (remaining gas: 1039181.048 units remaining) - [ (Pair 1000 - False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 121 (remaining gas: 1039181.038 units remaining) - [ 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 119 (remaining gas: 1039181.008 units remaining) - [ 1000 - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 122 (remaining gas: 1039180.748 units remaining) - [ 0x0500a80f @packed - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 123 (remaining gas: 1039180.308 units remaining) - [ (Some 1000) @packed.unpacked - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 126 (remaining gas: 1039180.298 units remaining) - [ 1000 @packed.unpacked.some - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 126 (remaining gas: 1039180.283 units remaining) - [ 1000 @packed.unpacked.some - 1000 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 134 (remaining gas: 1039180.248 units remaining) - [ 0 - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 135 (remaining gas: 1039180.233 units remaining) - [ True - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 136 (remaining gas: 1039180.223 units remaining) - [ (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 136 (remaining gas: 1039180.208 units remaining) - [ (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 142 (remaining gas: 1039180.198 units remaining) - [ (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 143 (remaining gas: 1039180.188 units remaining) - [ False - (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 144 (remaining gas: 1039180.173 units remaining) - [ (Pair False - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 146 (remaining gas: 1039180.163 units remaining) - [ False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 144 (remaining gas: 1039180.133 units remaining) - [ False - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 147 (remaining gas: 1039179.906 units remaining) - [ 0x050303 @packed - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 148 (remaining gas: 1039179.486 units remaining) - [ (Some False) @packed.unpacked - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 151 (remaining gas: 1039179.476 units remaining) - [ False @packed.unpacked.some - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 151 (remaining gas: 1039179.461 units remaining) - [ False @packed.unpacked.some - False - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 159 (remaining gas: 1039179.426 units remaining) - [ 0 - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 160 (remaining gas: 1039179.411 units remaining) - [ True - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 161 (remaining gas: 1039179.401 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 161 (remaining gas: 1039179.386 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 167 (remaining gas: 1039179.376 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 168 (remaining gas: 1039179.366 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 169 (remaining gas: 1039179.351 units remaining) - [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 171 (remaining gas: 1039179.341 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 169 (remaining gas: 1039179.311 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 172 (remaining gas: 1039178.221 units remaining) - [ 0x050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 173 (remaining gas: 1039177.268 units remaining) - [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 176 (remaining gas: 1039177.258 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 176 (remaining gas: 1039177.243 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 184 (remaining gas: 1039177.207 units remaining) - [ 0 - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 185 (remaining gas: 1039177.192 units remaining) - [ True - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 186 (remaining gas: 1039177.182 units remaining) - [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 186 (remaining gas: 1039177.167 units remaining) - [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 192 (remaining gas: 1039177.157 units remaining) - [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 193 (remaining gas: 1039177.147 units remaining) - [ "2019-09-09T08:35:33Z" - (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 194 (remaining gas: 1039177.132 units remaining) - [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] - - location: 196 (remaining gas: 1039177.122 units remaining) - [ "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 194 (remaining gas: 1039177.092 units remaining) - [ "2019-09-09T08:35:33Z" - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 197 (remaining gas: 1039176.733 units remaining) - [ 0x050095bbb0d70b @packed - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 198 (remaining gas: 1039176.233 units remaining) - [ (Some "2019-09-09T08:35:33Z") @packed.unpacked - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 201 (remaining gas: 1039176.223 units remaining) - [ "2019-09-09T08:35:33Z" @packed.unpacked.some - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 201 (remaining gas: 1039176.208 units remaining) - [ "2019-09-09T08:35:33Z" @packed.unpacked.some - "2019-09-09T08:35:33Z" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 209 (remaining gas: 1039176.173 units remaining) - [ 0 - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 210 (remaining gas: 1039176.158 units remaining) - [ True - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 211 (remaining gas: 1039176.148 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 211 (remaining gas: 1039176.133 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 217 (remaining gas: 1039176.123 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 218 (remaining gas: 1039165.170 units remaining) - [ 0x050a000000160000bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 219 (remaining gas: 1038514.247 units remaining) - [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 222 (remaining gas: 1038514.237 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 222 (remaining gas: 1038514.222 units remaining) - [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some - "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] - - location: 230 (remaining gas: 1038514.186 units remaining) - [ 0 ] - - location: 231 (remaining gas: 1038514.171 units remaining) - [ True ] - - location: 232 (remaining gas: 1038514.161 units remaining) - [ ] - - location: 232 (remaining gas: 1038514.146 units remaining) - [ ] - - location: 238 (remaining gas: 1038514.136 units remaining) - [ 0 ] - - location: 241 (remaining gas: 1038513.909 units remaining) - [ 0x050000 @packed ] - - location: 242 (remaining gas: 1038513.489 units remaining) - [ (Some 0) @packed.unpacked ] - - location: 245 (remaining gas: 1038513.479 units remaining) - [ 0 @packed.unpacked.some ] - - location: 245 (remaining gas: 1038513.464 units remaining) - [ 0 @packed.unpacked.some ] - - location: 251 (remaining gas: 1038513.454 units remaining) - [ ] - - location: 252 (remaining gas: 1038513.444 units remaining) - [ -1 ] - - location: 255 (remaining gas: 1038513.217 units remaining) - [ 0x050041 @packed ] - - location: 256 (remaining gas: 1038416.897 units remaining) - [ None @packed.unpacked ] - - location: 259 (remaining gas: 1038416.887 units remaining) - [ ] - - location: 259 (remaining gas: 1038416.872 units remaining) - [ ] - - location: 265 (remaining gas: 1038416.862 units remaining) - [ 0x ] - - location: 268 (remaining gas: 1038416.602 units remaining) - [ None @unpacked ] - - location: 271 (remaining gas: 1038416.592 units remaining) - [ ] - - location: 271 (remaining gas: 1038416.577 units remaining) - [ ] - - location: 277 (remaining gas: 1038416.567 units remaining) - [ 0x04 ] - - location: 280 (remaining gas: 1038416.287 units remaining) - [ None @unpacked ] - - location: 283 (remaining gas: 1038416.277 units remaining) - [ ] - - location: 283 (remaining gas: 1038416.262 units remaining) - [ ] - - location: 289 (remaining gas: 1038416.252 units remaining) - [ 0x05 ] - - location: 292 (remaining gas: 1038415.972 units remaining) - [ None @unpacked ] - - location: 295 (remaining gas: 1038415.962 units remaining) - [ ] - - location: 295 (remaining gas: 1038415.947 units remaining) - [ ] - - location: 301 (remaining gas: 1038415.937 units remaining) - [ Unit ] - - location: 302 (remaining gas: 1038415.922 units remaining) - [ {} - Unit ] - - location: 304 (remaining gas: 1038415.907 units remaining) - [ (Pair {} Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" deleted file mode 100644 index 359da4be18b8..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" +++ /dev/null @@ -1,1194 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" (Pair Unit (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") (Pair { Unit } (Pair { True } (Pair (Pair 19 10) (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK } )))))))))-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 28 (remaining gas: 1039468.020 units remaining) - [ (Pair (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) - Unit) ] - - location: 28 (remaining gas: 1039468.010 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) @parameter ] - - location: 29 (remaining gas: 1039468 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) @parameter - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) @parameter ] - - location: 30 (remaining gas: 1039467.990 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) @parameter ] - - location: 31 (remaining gas: 1039467.975 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) @parameter ] - - location: 33 (remaining gas: 1039467.965 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 31 (remaining gas: 1039467.935 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 34 (remaining gas: 1039466.063 units remaining) - [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed - "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 35 (remaining gas: 1039466.048 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 37 (remaining gas: 1039464.176 units remaining) - [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 38 (remaining gas: 1039143.032 units remaining) - [ (Some "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav") @packed.unpacked - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 41 (remaining gas: 1039143.022 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @packed.unpacked.some - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 41 (remaining gas: 1039143.007 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @packed.unpacked.some - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 47 (remaining gas: 1039141.135 units remaining) - [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed.unpacked.some.packed - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 35 (remaining gas: 1039141.105 units remaining) - [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed - 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed.unpacked.some.packed - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 50 (remaining gas: 1039141.070 units remaining) - [ 0 - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 51 (remaining gas: 1039141.055 units remaining) - [ True - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 52 (remaining gas: 1039141.045 units remaining) - [ (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 52 (remaining gas: 1039141.030 units remaining) - [ (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 58 (remaining gas: 1039141.020 units remaining) - [ (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 59 (remaining gas: 1039141.010 units remaining) - [ Unit - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 60 (remaining gas: 1039140.995 units remaining) - [ (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 62 (remaining gas: 1039140.985 units remaining) - [ Unit - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 60 (remaining gas: 1039140.955 units remaining) - [ Unit - Unit - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 63 (remaining gas: 1039140.728 units remaining) - [ 0x05030b @packed - Unit - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 64 (remaining gas: 1039140.713 units remaining) - [ Unit - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 66 (remaining gas: 1039140.486 units remaining) - [ 0x05030b @packed - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 67 (remaining gas: 1039140.066 units remaining) - [ (Some Unit) @packed.unpacked - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 70 (remaining gas: 1039140.056 units remaining) - [ Unit @packed.unpacked.some - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 70 (remaining gas: 1039140.041 units remaining) - [ Unit @packed.unpacked.some - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 76 (remaining gas: 1039139.814 units remaining) - [ 0x05030b @packed.unpacked.some.packed - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 64 (remaining gas: 1039139.784 units remaining) - [ 0x05030b @packed - 0x05030b @packed.unpacked.some.packed - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 79 (remaining gas: 1039139.749 units remaining) - [ 0 - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 80 (remaining gas: 1039139.734 units remaining) - [ True - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 81 (remaining gas: 1039139.724 units remaining) - [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 81 (remaining gas: 1039139.709 units remaining) - [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 87 (remaining gas: 1039139.699 units remaining) - [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 88 (remaining gas: 1039139.689 units remaining) - [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 89 (remaining gas: 1039139.674 units remaining) - [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 91 (remaining gas: 1039139.664 units remaining) - [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 89 (remaining gas: 1039139.634 units remaining) - [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 92 (remaining gas: 1039137.147 units remaining) - [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 93 (remaining gas: 1039137.132 units remaining) - [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 95 (remaining gas: 1039134.645 units remaining) - [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 96 (remaining gas: 1039132.842 units remaining) - [ (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe") @packed.unpacked - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 99 (remaining gas: 1039132.832 units remaining) - [ "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe" @packed.unpacked.some - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 99 (remaining gas: 1039132.817 units remaining) - [ "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe" @packed.unpacked.some - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 105 (remaining gas: 1039130.330 units remaining) - [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 93 (remaining gas: 1039130.300 units remaining) - [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed - 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 108 (remaining gas: 1039130.264 units remaining) - [ 0 - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 109 (remaining gas: 1039130.249 units remaining) - [ True - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 110 (remaining gas: 1039130.239 units remaining) - [ (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 110 (remaining gas: 1039130.224 units remaining) - [ (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 116 (remaining gas: 1039130.214 units remaining) - [ (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 117 (remaining gas: 1039130.204 units remaining) - [ (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 118 (remaining gas: 1039130.189 units remaining) - [ (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 120 (remaining gas: 1039130.179 units remaining) - [ (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 118 (remaining gas: 1039130.149 units remaining) - [ (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 121 (remaining gas: 1039127.500 units remaining) - [ 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed - (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 122 (remaining gas: 1039127.485 units remaining) - [ (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 124 (remaining gas: 1039124.836 units remaining) - [ 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 125 (remaining gas: 1039122.892 units remaining) - [ (Some (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe")) @packed.unpacked - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 129 (remaining gas: 1039122.882 units remaining) - [ (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe") @packed.unpacked.some - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 129 (remaining gas: 1039122.867 units remaining) - [ (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe") @packed.unpacked.some - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 135 (remaining gas: 1039120.218 units remaining) - [ 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 122 (remaining gas: 1039120.188 units remaining) - [ 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed - 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 138 (remaining gas: 1039120.152 units remaining) - [ 0 - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 139 (remaining gas: 1039120.137 units remaining) - [ True - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 140 (remaining gas: 1039120.127 units remaining) - [ (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 140 (remaining gas: 1039120.112 units remaining) - [ (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 146 (remaining gas: 1039120.102 units remaining) - [ (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 147 (remaining gas: 1039120.092 units remaining) - [ { Unit } - (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 148 (remaining gas: 1039120.077 units remaining) - [ (Pair { Unit } - { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 150 (remaining gas: 1039120.067 units remaining) - [ { Unit } - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 148 (remaining gas: 1039120.037 units remaining) - [ { Unit } - { Unit } - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 151 (remaining gas: 1039119.549 units remaining) - [ 0x050200000002030b @packed - { Unit } - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 152 (remaining gas: 1039119.534 units remaining) - [ { Unit } - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 154 (remaining gas: 1039119.046 units remaining) - [ 0x050200000002030b @packed - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 155 (remaining gas: 1039118.425 units remaining) - [ (Some { Unit }) @packed.unpacked - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 159 (remaining gas: 1039118.415 units remaining) - [ { Unit } @packed.unpacked.some - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 159 (remaining gas: 1039118.400 units remaining) - [ { Unit } @packed.unpacked.some - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 165 (remaining gas: 1039117.912 units remaining) - [ 0x050200000002030b @packed.unpacked.some.packed - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 152 (remaining gas: 1039117.882 units remaining) - [ 0x050200000002030b @packed - 0x050200000002030b @packed.unpacked.some.packed - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 168 (remaining gas: 1039117.847 units remaining) - [ 0 - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 169 (remaining gas: 1039117.832 units remaining) - [ True - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 170 (remaining gas: 1039117.822 units remaining) - [ (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 170 (remaining gas: 1039117.807 units remaining) - [ (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 176 (remaining gas: 1039117.797 units remaining) - [ (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 177 (remaining gas: 1039117.787 units remaining) - [ { True } - (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 178 (remaining gas: 1039117.772 units remaining) - [ (Pair { True } - (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 180 (remaining gas: 1039117.762 units remaining) - [ { True } - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 178 (remaining gas: 1039117.732 units remaining) - [ { True } - { True } - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 181 (remaining gas: 1039117.244 units remaining) - [ 0x050200000002030a @packed - { True } - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 182 (remaining gas: 1039117.229 units remaining) - [ { True } - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 184 (remaining gas: 1039116.741 units remaining) - [ 0x050200000002030a @packed - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 185 (remaining gas: 1039115.920 units remaining) - [ (Some { True }) @packed.unpacked - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 189 (remaining gas: 1039115.910 units remaining) - [ { True } @packed.unpacked.some - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 189 (remaining gas: 1039115.895 units remaining) - [ { True } @packed.unpacked.some - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 195 (remaining gas: 1039115.407 units remaining) - [ 0x050200000002030a @packed.unpacked.some.packed - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 182 (remaining gas: 1039115.377 units remaining) - [ 0x050200000002030a @packed - 0x050200000002030a @packed.unpacked.some.packed - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 198 (remaining gas: 1039115.342 units remaining) - [ 0 - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 199 (remaining gas: 1039115.327 units remaining) - [ True - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 200 (remaining gas: 1039115.317 units remaining) - [ (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 200 (remaining gas: 1039115.302 units remaining) - [ (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 206 (remaining gas: 1039115.292 units remaining) - [ (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 207 (remaining gas: 1039115.282 units remaining) - [ (Pair 19 10) - (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 208 (remaining gas: 1039115.267 units remaining) - [ (Pair (Pair 19 10) - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 210 (remaining gas: 1039115.257 units remaining) - [ (Pair 19 10) - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 208 (remaining gas: 1039115.227 units remaining) - [ (Pair 19 10) - (Pair 19 10) - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 211 (remaining gas: 1039114.676 units remaining) - [ 0x0507070013000a @packed - (Pair 19 10) - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 212 (remaining gas: 1039114.661 units remaining) - [ (Pair 19 10) - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 214 (remaining gas: 1039114.110 units remaining) - [ 0x0507070013000a @packed - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 215 (remaining gas: 1039113.410 units remaining) - [ (Some (Pair 19 10)) @packed.unpacked - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 220 (remaining gas: 1039113.400 units remaining) - [ (Pair 19 10) @packed.unpacked.some - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 220 (remaining gas: 1039113.385 units remaining) - [ (Pair 19 10) @packed.unpacked.some - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 226 (remaining gas: 1039112.834 units remaining) - [ 0x0507070013000a @packed.unpacked.some.packed - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 212 (remaining gas: 1039112.804 units remaining) - [ 0x0507070013000a @packed - 0x0507070013000a @packed.unpacked.some.packed - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 229 (remaining gas: 1039112.769 units remaining) - [ 0 - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 230 (remaining gas: 1039112.754 units remaining) - [ True - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 231 (remaining gas: 1039112.744 units remaining) - [ (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 231 (remaining gas: 1039112.729 units remaining) - [ (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 237 (remaining gas: 1039112.719 units remaining) - [ (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 238 (remaining gas: 1039112.709 units remaining) - [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 239 (remaining gas: 1039112.694 units remaining) - [ (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK }) ] - - location: 241 (remaining gas: 1039112.684 units remaining) - [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 239 (remaining gas: 1039112.654 units remaining) - [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 242 (remaining gas: 1039111.402 units remaining) - [ 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed - (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 243 (remaining gas: 1039111.387 units remaining) - [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 245 (remaining gas: 1039110.135 units remaining) - [ 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 246 (remaining gas: 1039109.042 units remaining) - [ (Some (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5")) @packed.unpacked - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 251 (remaining gas: 1039109.032 units remaining) - [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked.some - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 251 (remaining gas: 1039109.017 units remaining) - [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked.some - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 257 (remaining gas: 1039107.765 units remaining) - [ 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed.unpacked.some.packed - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 243 (remaining gas: 1039107.735 units remaining) - [ 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed - 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed.unpacked.some.packed - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 260 (remaining gas: 1039107.700 units remaining) - [ 0 - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 261 (remaining gas: 1039107.685 units remaining) - [ True - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 262 (remaining gas: 1039107.675 units remaining) - [ (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 262 (remaining gas: 1039107.660 units remaining) - [ (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 268 (remaining gas: 1039107.650 units remaining) - [ (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 269 (remaining gas: 1039107.640 units remaining) - [ { Elt 0 "foo" ; Elt 1 "bar" } - (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 270 (remaining gas: 1039107.625 units remaining) - [ (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] - - location: 272 (remaining gas: 1039107.615 units remaining) - [ { Elt 0 "foo" ; Elt 1 "bar" } - { PACK } ] - - location: 270 (remaining gas: 1039107.585 units remaining) - [ { Elt 0 "foo" ; Elt 1 "bar" } - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK } ] - - location: 273 (remaining gas: 1039105.980 units remaining) - [ 0x050200000018070400000100000003666f6f070400010100000003626172 @packed - { Elt 0 "foo" ; Elt 1 "bar" } - { PACK } ] - - location: 274 (remaining gas: 1039105.965 units remaining) - [ { Elt 0 "foo" ; Elt 1 "bar" } - { PACK } ] - - location: 276 (remaining gas: 1039104.360 units remaining) - [ 0x050200000018070400000100000003666f6f070400010100000003626172 @packed - { PACK } ] - - location: 277 (remaining gas: 1039102.504 units remaining) - [ (Some { Elt 0 "foo" ; Elt 1 "bar" }) @packed.unpacked - { PACK } ] - - location: 282 (remaining gas: 1039102.494 units remaining) - [ { Elt 0 "foo" ; Elt 1 "bar" } @packed.unpacked.some - { PACK } ] - - location: 282 (remaining gas: 1039102.479 units remaining) - [ { Elt 0 "foo" ; Elt 1 "bar" } @packed.unpacked.some - { PACK } ] - - location: 288 (remaining gas: 1039100.874 units remaining) - [ 0x050200000018070400000100000003666f6f070400010100000003626172 @packed.unpacked.some.packed - { PACK } ] - - location: 274 (remaining gas: 1039100.844 units remaining) - [ 0x050200000018070400000100000003666f6f070400010100000003626172 @packed - 0x050200000018070400000100000003666f6f070400010100000003626172 @packed.unpacked.some.packed - { PACK } ] - - location: 291 (remaining gas: 1039100.809 units remaining) - [ 0 - { PACK } ] - - location: 292 (remaining gas: 1039100.794 units remaining) - [ True - { PACK } ] - - location: 293 (remaining gas: 1039100.784 units remaining) - [ { PACK } ] - - location: 293 (remaining gas: 1039100.769 units remaining) - [ { PACK } ] - - location: 299 (remaining gas: 1039100.759 units remaining) - [ { PACK } - { PACK } ] - - location: 300 (remaining gas: 1039100.086 units remaining) - [ 0x050200000002030c @packed - { PACK } ] - - location: 301 (remaining gas: 1039100.071 units remaining) - [ { PACK } ] - - location: 303 (remaining gas: 1039099.398 units remaining) - [ 0x050200000002030c @packed ] - - location: 304 (remaining gas: 1039098.217 units remaining) - [ (Some { PACK }) @packed.unpacked ] - - location: 309 (remaining gas: 1039098.207 units remaining) - [ { PACK } @packed.unpacked.some ] - - location: 309 (remaining gas: 1039098.192 units remaining) - [ { PACK } @packed.unpacked.some ] - - location: 315 (remaining gas: 1039097.519 units remaining) - [ 0x050200000002030c @packed.unpacked.some.packed ] - - location: 301 (remaining gas: 1039097.489 units remaining) - [ 0x050200000002030c @packed - 0x050200000002030c @packed.unpacked.some.packed ] - - location: 318 (remaining gas: 1039097.454 units remaining) - [ 0 ] - - location: 319 (remaining gas: 1039097.439 units remaining) - [ True ] - - location: 320 (remaining gas: 1039097.429 units remaining) - [ ] - - location: 320 (remaining gas: 1039097.414 units remaining) - [ ] - - location: 326 (remaining gas: 1039097.404 units remaining) - [ Unit ] - - location: 327 (remaining gas: 1039097.389 units remaining) - [ {} - Unit ] - - location: 329 (remaining gas: 1039097.374 units remaining) - [ (Pair {} Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.4e20b52378.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.4e20b52378.out" deleted file mode 100644 index 9684d352eff7..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.4e20b52378.out" +++ /dev/null @@ -1,1032 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" (Pair Unit (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" (Pair None (Pair { } (Pair { } (Pair (Pair 40 -10) (Pair (Right "2019-09-09T08:35:33Z") (Pair { } { DUP ; DROP ; PACK } )))))))))-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 28 (remaining gas: 1039478.033 units remaining) - [ (Pair (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) - Unit) ] - - location: 28 (remaining gas: 1039478.023 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) @parameter ] - - location: 29 (remaining gas: 1039478.013 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) @parameter - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) @parameter ] - - location: 30 (remaining gas: 1039478.003 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) @parameter ] - - location: 31 (remaining gas: 1039477.988 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) @parameter ] - - location: 33 (remaining gas: 1039477.978 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 31 (remaining gas: 1039477.948 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 34 (remaining gas: 1039476.076 units remaining) - [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed - "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 35 (remaining gas: 1039476.061 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 37 (remaining gas: 1039474.189 units remaining) - [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 38 (remaining gas: 1039153.045 units remaining) - [ (Some "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav") @packed.unpacked - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 41 (remaining gas: 1039153.035 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @packed.unpacked.some - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 41 (remaining gas: 1039153.020 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @packed.unpacked.some - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 47 (remaining gas: 1039151.148 units remaining) - [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed.unpacked.some.packed - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 35 (remaining gas: 1039151.118 units remaining) - [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed - 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed.unpacked.some.packed - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 50 (remaining gas: 1039151.083 units remaining) - [ 0 - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 51 (remaining gas: 1039151.068 units remaining) - [ True - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 52 (remaining gas: 1039151.058 units remaining) - [ (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 52 (remaining gas: 1039151.043 units remaining) - [ (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 58 (remaining gas: 1039151.033 units remaining) - [ (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 59 (remaining gas: 1039151.023 units remaining) - [ Unit - (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 60 (remaining gas: 1039151.008 units remaining) - [ (Pair Unit - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 62 (remaining gas: 1039150.998 units remaining) - [ Unit - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 60 (remaining gas: 1039150.968 units remaining) - [ Unit - Unit - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 63 (remaining gas: 1039150.741 units remaining) - [ 0x05030b @packed - Unit - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 64 (remaining gas: 1039150.726 units remaining) - [ Unit - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 66 (remaining gas: 1039150.499 units remaining) - [ 0x05030b @packed - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 67 (remaining gas: 1039150.079 units remaining) - [ (Some Unit) @packed.unpacked - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 70 (remaining gas: 1039150.069 units remaining) - [ Unit @packed.unpacked.some - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 70 (remaining gas: 1039150.054 units remaining) - [ Unit @packed.unpacked.some - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 76 (remaining gas: 1039149.827 units remaining) - [ 0x05030b @packed.unpacked.some.packed - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 64 (remaining gas: 1039149.797 units remaining) - [ 0x05030b @packed - 0x05030b @packed.unpacked.some.packed - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 79 (remaining gas: 1039149.762 units remaining) - [ 0 - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 80 (remaining gas: 1039149.747 units remaining) - [ True - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 81 (remaining gas: 1039149.737 units remaining) - [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 81 (remaining gas: 1039149.722 units remaining) - [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 87 (remaining gas: 1039149.712 units remaining) - [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 88 (remaining gas: 1039149.702 units remaining) - [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 89 (remaining gas: 1039149.687 units remaining) - [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 91 (remaining gas: 1039149.677 units remaining) - [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 89 (remaining gas: 1039149.647 units remaining) - [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 92 (remaining gas: 1039147.160 units remaining) - [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed - "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 93 (remaining gas: 1039147.145 units remaining) - [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 95 (remaining gas: 1039144.658 units remaining) - [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 96 (remaining gas: 1039142.855 units remaining) - [ (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe") @packed.unpacked - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 99 (remaining gas: 1039142.845 units remaining) - [ "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe" @packed.unpacked.some - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 99 (remaining gas: 1039142.830 units remaining) - [ "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe" @packed.unpacked.some - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 105 (remaining gas: 1039140.343 units remaining) - [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 93 (remaining gas: 1039140.313 units remaining) - [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed - 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 108 (remaining gas: 1039140.277 units remaining) - [ 0 - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 109 (remaining gas: 1039140.262 units remaining) - [ True - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 110 (remaining gas: 1039140.252 units remaining) - [ (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 110 (remaining gas: 1039140.237 units remaining) - [ (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 116 (remaining gas: 1039140.227 units remaining) - [ (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 117 (remaining gas: 1039140.217 units remaining) - [ None - (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 118 (remaining gas: 1039140.202 units remaining) - [ (Pair None - {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 120 (remaining gas: 1039140.192 units remaining) - [ None - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 118 (remaining gas: 1039140.162 units remaining) - [ None - None - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 121 (remaining gas: 1039139.935 units remaining) - [ 0x050306 @packed - None - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 122 (remaining gas: 1039139.920 units remaining) - [ None - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 124 (remaining gas: 1039139.693 units remaining) - [ 0x050306 @packed - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 125 (remaining gas: 1039139.273 units remaining) - [ (Some None) @packed.unpacked - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 129 (remaining gas: 1039139.263 units remaining) - [ None @packed.unpacked.some - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 129 (remaining gas: 1039139.248 units remaining) - [ None @packed.unpacked.some - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 135 (remaining gas: 1039139.021 units remaining) - [ 0x050306 @packed.unpacked.some.packed - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 122 (remaining gas: 1039138.991 units remaining) - [ 0x050306 @packed - 0x050306 @packed.unpacked.some.packed - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 138 (remaining gas: 1039138.956 units remaining) - [ 0 - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 139 (remaining gas: 1039138.941 units remaining) - [ True - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 140 (remaining gas: 1039138.931 units remaining) - [ (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 140 (remaining gas: 1039138.916 units remaining) - [ (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 146 (remaining gas: 1039138.906 units remaining) - [ (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 147 (remaining gas: 1039138.896 units remaining) - [ {} - (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 148 (remaining gas: 1039138.881 units remaining) - [ (Pair {} - {} - (Pair 40 -10) - (Right "2019-09-09T08:35:33Z") - {} - { DUP ; DROP ; PACK }) ] - - location: 150 (remaining gas: 1039138.871 units remaining) - [ {} - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 148 (remaining gas: 1039138.841 units remaining) - [ {} - {} - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 151 (remaining gas: 1039138.515 units remaining) - [ 0x050200000000 @packed - {} - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 152 (remaining gas: 1039138.500 units remaining) - [ {} - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 154 (remaining gas: 1039138.174 units remaining) - [ 0x050200000000 @packed - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 155 (remaining gas: 1039137.694 units remaining) - [ (Some {}) @packed.unpacked - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 159 (remaining gas: 1039137.684 units remaining) - [ {} @packed.unpacked.some - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 159 (remaining gas: 1039137.669 units remaining) - [ {} @packed.unpacked.some - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 165 (remaining gas: 1039137.343 units remaining) - [ 0x050200000000 @packed.unpacked.some.packed - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 152 (remaining gas: 1039137.313 units remaining) - [ 0x050200000000 @packed - 0x050200000000 @packed.unpacked.some.packed - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 168 (remaining gas: 1039137.278 units remaining) - [ 0 - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 169 (remaining gas: 1039137.263 units remaining) - [ True - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 170 (remaining gas: 1039137.253 units remaining) - [ (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 170 (remaining gas: 1039137.238 units remaining) - [ (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 176 (remaining gas: 1039137.228 units remaining) - [ (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 177 (remaining gas: 1039137.218 units remaining) - [ {} - (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 178 (remaining gas: 1039137.203 units remaining) - [ (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 180 (remaining gas: 1039137.193 units remaining) - [ {} - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 178 (remaining gas: 1039137.163 units remaining) - [ {} - {} - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 181 (remaining gas: 1039136.837 units remaining) - [ 0x050200000000 @packed - {} - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 182 (remaining gas: 1039136.822 units remaining) - [ {} - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 184 (remaining gas: 1039136.496 units remaining) - [ 0x050200000000 @packed - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 185 (remaining gas: 1039136.016 units remaining) - [ (Some {}) @packed.unpacked - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 189 (remaining gas: 1039136.006 units remaining) - [ {} @packed.unpacked.some - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 189 (remaining gas: 1039135.991 units remaining) - [ {} @packed.unpacked.some - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 195 (remaining gas: 1039135.665 units remaining) - [ 0x050200000000 @packed.unpacked.some.packed - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 182 (remaining gas: 1039135.635 units remaining) - [ 0x050200000000 @packed - 0x050200000000 @packed.unpacked.some.packed - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 198 (remaining gas: 1039135.600 units remaining) - [ 0 - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 199 (remaining gas: 1039135.585 units remaining) - [ True - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 200 (remaining gas: 1039135.575 units remaining) - [ (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 200 (remaining gas: 1039135.560 units remaining) - [ (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 206 (remaining gas: 1039135.550 units remaining) - [ (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 207 (remaining gas: 1039135.540 units remaining) - [ (Pair 40 -10) - (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 208 (remaining gas: 1039135.525 units remaining) - [ (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 210 (remaining gas: 1039135.515 units remaining) - [ (Pair 40 -10) - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 208 (remaining gas: 1039135.485 units remaining) - [ (Pair 40 -10) - (Pair 40 -10) - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 211 (remaining gas: 1039134.934 units remaining) - [ 0x0507070028004a @packed - (Pair 40 -10) - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 212 (remaining gas: 1039134.919 units remaining) - [ (Pair 40 -10) - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 214 (remaining gas: 1039134.368 units remaining) - [ 0x0507070028004a @packed - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 215 (remaining gas: 1039133.668 units remaining) - [ (Some (Pair 40 -10)) @packed.unpacked - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 220 (remaining gas: 1039133.658 units remaining) - [ (Pair 40 -10) @packed.unpacked.some - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 220 (remaining gas: 1039133.643 units remaining) - [ (Pair 40 -10) @packed.unpacked.some - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 226 (remaining gas: 1039133.092 units remaining) - [ 0x0507070028004a @packed.unpacked.some.packed - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 212 (remaining gas: 1039133.062 units remaining) - [ 0x0507070028004a @packed - 0x0507070028004a @packed.unpacked.some.packed - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 229 (remaining gas: 1039133.027 units remaining) - [ 0 - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 230 (remaining gas: 1039133.012 units remaining) - [ True - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 231 (remaining gas: 1039133.002 units remaining) - [ (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 231 (remaining gas: 1039132.987 units remaining) - [ (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 237 (remaining gas: 1039132.977 units remaining) - [ (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 238 (remaining gas: 1039132.967 units remaining) - [ (Right "2019-09-09T08:35:33Z") - (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 239 (remaining gas: 1039132.952 units remaining) - [ (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] - - location: 241 (remaining gas: 1039132.942 units remaining) - [ (Right "2019-09-09T08:35:33Z") - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 239 (remaining gas: 1039132.912 units remaining) - [ (Right "2019-09-09T08:35:33Z") - (Right "2019-09-09T08:35:33Z") - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 242 (remaining gas: 1039132.391 units remaining) - [ 0x0505080095bbb0d70b @packed - (Right "2019-09-09T08:35:33Z") - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 243 (remaining gas: 1039132.376 units remaining) - [ (Right "2019-09-09T08:35:33Z") - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 245 (remaining gas: 1039131.855 units remaining) - [ 0x0505080095bbb0d70b @packed - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 246 (remaining gas: 1039131.214 units remaining) - [ (Some (Right "2019-09-09T08:35:33Z")) @packed.unpacked - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 251 (remaining gas: 1039131.204 units remaining) - [ (Right "2019-09-09T08:35:33Z") @packed.unpacked.some - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 251 (remaining gas: 1039131.189 units remaining) - [ (Right "2019-09-09T08:35:33Z") @packed.unpacked.some - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 257 (remaining gas: 1039130.668 units remaining) - [ 0x0505080095bbb0d70b @packed.unpacked.some.packed - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 243 (remaining gas: 1039130.638 units remaining) - [ 0x0505080095bbb0d70b @packed - 0x0505080095bbb0d70b @packed.unpacked.some.packed - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 260 (remaining gas: 1039130.603 units remaining) - [ 0 - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 261 (remaining gas: 1039130.588 units remaining) - [ True - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 262 (remaining gas: 1039130.578 units remaining) - [ (Pair {} { DUP ; DROP ; PACK }) ] - - location: 262 (remaining gas: 1039130.563 units remaining) - [ (Pair {} { DUP ; DROP ; PACK }) ] - - location: 268 (remaining gas: 1039130.553 units remaining) - [ (Pair {} { DUP ; DROP ; PACK }) - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 269 (remaining gas: 1039130.543 units remaining) - [ {} - (Pair {} { DUP ; DROP ; PACK }) ] - - location: 270 (remaining gas: 1039130.528 units remaining) - [ (Pair {} { DUP ; DROP ; PACK }) ] - - location: 272 (remaining gas: 1039130.518 units remaining) - [ {} - { DUP ; DROP ; PACK } ] - - location: 270 (remaining gas: 1039130.488 units remaining) - [ {} - {} - { DUP ; DROP ; PACK } ] - - location: 273 (remaining gas: 1039130.162 units remaining) - [ 0x050200000000 @packed - {} - { DUP ; DROP ; PACK } ] - - location: 274 (remaining gas: 1039130.147 units remaining) - [ {} - { DUP ; DROP ; PACK } ] - - location: 276 (remaining gas: 1039129.821 units remaining) - [ 0x050200000000 @packed - { DUP ; DROP ; PACK } ] - - location: 277 (remaining gas: 1039129.341 units remaining) - [ (Some {}) @packed.unpacked - { DUP ; DROP ; PACK } ] - - location: 282 (remaining gas: 1039129.331 units remaining) - [ {} @packed.unpacked.some - { DUP ; DROP ; PACK } ] - - location: 282 (remaining gas: 1039129.316 units remaining) - [ {} @packed.unpacked.some - { DUP ; DROP ; PACK } ] - - location: 288 (remaining gas: 1039128.990 units remaining) - [ 0x050200000000 @packed.unpacked.some.packed - { DUP ; DROP ; PACK } ] - - location: 274 (remaining gas: 1039128.960 units remaining) - [ 0x050200000000 @packed - 0x050200000000 @packed.unpacked.some.packed - { DUP ; DROP ; PACK } ] - - location: 291 (remaining gas: 1039128.925 units remaining) - [ 0 - { DUP ; DROP ; PACK } ] - - location: 292 (remaining gas: 1039128.910 units remaining) - [ True - { DUP ; DROP ; PACK } ] - - location: 293 (remaining gas: 1039128.900 units remaining) - [ { DUP ; DROP ; PACK } ] - - location: 293 (remaining gas: 1039128.885 units remaining) - [ { DUP ; DROP ; PACK } ] - - location: 299 (remaining gas: 1039128.875 units remaining) - [ { DUP ; DROP ; PACK } - { DUP ; DROP ; PACK } ] - - location: 300 (remaining gas: 1039127.738 units remaining) - [ 0x05020000000603210320030c @packed - { DUP ; DROP ; PACK } ] - - location: 301 (remaining gas: 1039127.723 units remaining) - [ { DUP ; DROP ; PACK } ] - - location: 303 (remaining gas: 1039126.586 units remaining) - [ 0x05020000000603210320030c @packed ] - - location: 304 (remaining gas: 1039124.345 units remaining) - [ (Some { DUP ; DROP ; PACK }) @packed.unpacked ] - - location: 309 (remaining gas: 1039124.335 units remaining) - [ { DUP ; DROP ; PACK } @packed.unpacked.some ] - - location: 309 (remaining gas: 1039124.320 units remaining) - [ { DUP ; DROP ; PACK } @packed.unpacked.some ] - - location: 315 (remaining gas: 1039123.183 units remaining) - [ 0x05020000000603210320030c @packed.unpacked.some.packed ] - - location: 301 (remaining gas: 1039123.153 units remaining) - [ 0x05020000000603210320030c @packed - 0x05020000000603210320030c @packed.unpacked.some.packed ] - - location: 318 (remaining gas: 1039123.118 units remaining) - [ 0 ] - - location: 319 (remaining gas: 1039123.103 units remaining) - [ True ] - - location: 320 (remaining gas: 1039123.093 units remaining) - [ ] - - location: 320 (remaining gas: 1039123.078 units remaining) - [ ] - - location: 326 (remaining gas: 1039123.068 units remaining) - [ Unit ] - - location: 327 (remaining gas: 1039123.053 units remaining) - [ {} - Unit ] - - location: 329 (remaining gas: 1039123.038 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))].out deleted file mode 100644 index a11b48dde9c6..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))] - -storage - (Some (Pair False False)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039993.234 units remaining) - [ (Pair (Pair False False) None) ] - - location: 12 (remaining gas: 1039993.224 units remaining) - [ (Pair False False) @parameter ] - - location: 13 (remaining gas: 1039993.209 units remaining) - [ (Some (Pair False False)) ] - - location: 14 (remaining gas: 1039993.194 units remaining) - [ {} - (Some (Pair False False)) ] - - location: 16 (remaining gas: 1039993.179 units remaining) - [ (Pair {} (Some (Pair False False))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))].out deleted file mode 100644 index aee166018b89..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))] - -storage - (Some (Pair False True)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039993.234 units remaining) - [ (Pair (Pair False True) None) ] - - location: 12 (remaining gas: 1039993.224 units remaining) - [ (Pair False True) @parameter ] - - location: 13 (remaining gas: 1039993.209 units remaining) - [ (Some (Pair False True)) ] - - location: 14 (remaining gas: 1039993.194 units remaining) - [ {} - (Some (Pair False True)) ] - - location: 16 (remaining gas: 1039993.179 units remaining) - [ (Pair {} (Some (Pair False True))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))].out deleted file mode 100644 index 0d5d310c9d97..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))] - -storage - (Some (Pair True False)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039993.234 units remaining) - [ (Pair (Pair True False) None) ] - - location: 12 (remaining gas: 1039993.224 units remaining) - [ (Pair True False) @parameter ] - - location: 13 (remaining gas: 1039993.209 units remaining) - [ (Some (Pair True False)) ] - - location: 14 (remaining gas: 1039993.194 units remaining) - [ {} - (Some (Pair True False)) ] - - location: 16 (remaining gas: 1039993.179 units remaining) - [ (Pair {} (Some (Pair True False))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))].out deleted file mode 100644 index 3cdd76bdb2e4..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))] - -storage - (Some (Pair True True)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039993.234 units remaining) - [ (Pair (Pair True True) None) ] - - location: 12 (remaining gas: 1039993.224 units remaining) - [ (Pair True True) @parameter ] - - location: 13 (remaining gas: 1039993.209 units remaining) - [ (Some (Pair True True)) ] - - location: 14 (remaining gas: 1039993.194 units remaining) - [ {} - (Some (Pair True True)) ] - - location: 16 (remaining gas: 1039993.179 units remaining) - [ (Pair {} (Some (Pair True True))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52].out deleted file mode 100644 index fc264351ed8e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52].out +++ /dev/null @@ -1,47 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52] - -storage - 52 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039989.309 units remaining) - [ (Pair 38 14) ] - - location: 7 (remaining gas: 1039989.299 units remaining) - [ { UNPAIR ; ADD } - (Pair 38 14) ] - - location: 15 (remaining gas: 1039989.289 units remaining) - [ (Pair 38 14) - { UNPAIR ; ADD } ] - - location: 16 (remaining gas: 1039989.279 units remaining) - [ 38 @parameter - 14 @storage - { UNPAIR ; ADD } ] - - location: 17 (remaining gas: 1039989.264 units remaining) - [ 14 @storage - { UNPAIR ; ADD } ] - - location: 19 (remaining gas: 1039989.039 units remaining) - [ { PUSH nat 14 ; PAIR ; { UNPAIR ; ADD } } ] - - location: 17 (remaining gas: 1039989.009 units remaining) - [ 38 @parameter - { PUSH nat 14 ; PAIR ; { UNPAIR ; ADD } } ] - - location: 12 (remaining gas: 1039988.999 units remaining) - [ 14 - 38 ] - - location: 12 (remaining gas: 1039988.984 units remaining) - [ (Pair 14 38) @arg ] - - location: 13 (remaining gas: 1039988.974 units remaining) - [ 14 - 38 ] - - location: 14 (remaining gas: 1039988.919 units remaining) - [ 52 ] - - location: 20 (remaining gas: 1039988.889 units remaining) - [ 52 ] - - location: 21 (remaining gas: 1039988.874 units remaining) - [ {} - 52 ] - - location: 23 (remaining gas: 1039988.859 units remaining) - [ (Pair {} 52) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out deleted file mode 100644 index 88586313650a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out +++ /dev/null @@ -1,282 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }] - -storage - { 0 ; 7 ; 14 ; 21 } -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039979.891 units remaining) - [ (Pair 4 { 0 ; 1 ; 2 ; 3 }) ] - - location: 8 (remaining gas: 1039979.881 units remaining) - [ 4 @p - { 0 ; 1 ; 2 ; 3 } @s ] - - location: 9 (remaining gas: 1039979.871 units remaining) - [ { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } - 4 @p - { 0 ; 1 ; 2 ; 3 } @s ] - - location: 23 (remaining gas: 1039979.861 units remaining) - [ 4 @p - { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } - { 0 ; 1 ; 2 ; 3 } @s ] - - location: 24 (remaining gas: 1039979.636 units remaining) - [ { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } - { 0 ; 1 ; 2 ; 3 } @s ] - - location: 25 (remaining gas: 1039979.626 units remaining) - [ 3 - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } - { 0 ; 1 ; 2 ; 3 } @s ] - - location: 28 (remaining gas: 1039979.401 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } - { 0 ; 1 ; 2 ; 3 } @s ] - - location: 29 (remaining gas: 1039979.391 units remaining) - [ { 0 ; 1 ; 2 ; 3 } @s - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 30 (remaining gas: 1039979.391 units remaining) - [ 0 @s.elt - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 32 (remaining gas: 1039979.376 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 34 (remaining gas: 1039979.366 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 32 (remaining gas: 1039979.336 units remaining) - [ 0 @s.elt - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 16 (remaining gas: 1039979.326 units remaining) - [ 3 - 0 ] - - location: 16 (remaining gas: 1039979.311 units remaining) - [ (Pair 3 0) ] - - location: 16 (remaining gas: 1039979.301 units remaining) - [ 4 - (Pair 3 0) ] - - location: 16 (remaining gas: 1039979.286 units remaining) - [ (Pair 4 3 0) @arg ] - - location: 17 (remaining gas: 1039979.276 units remaining) - [ 4 - (Pair 3 0) ] - - location: 18 (remaining gas: 1039979.261 units remaining) - [ (Pair 3 0) ] - - location: 20 (remaining gas: 1039979.251 units remaining) - [ 3 - 0 ] - - location: 18 (remaining gas: 1039979.221 units remaining) - [ 4 - 3 - 0 ] - - location: 21 (remaining gas: 1039979.166 units remaining) - [ 7 - 0 ] - - location: 22 (remaining gas: 1039979.065 units remaining) - [ 0 ] - - location: 35 (remaining gas: 1039979.035 units remaining) - [ 0 - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 30 (remaining gas: 1039979.020 units remaining) - [ 1 @s.elt - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 32 (remaining gas: 1039979.005 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 34 (remaining gas: 1039978.995 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 32 (remaining gas: 1039978.965 units remaining) - [ 1 @s.elt - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 16 (remaining gas: 1039978.955 units remaining) - [ 3 - 1 ] - - location: 16 (remaining gas: 1039978.940 units remaining) - [ (Pair 3 1) ] - - location: 16 (remaining gas: 1039978.930 units remaining) - [ 4 - (Pair 3 1) ] - - location: 16 (remaining gas: 1039978.915 units remaining) - [ (Pair 4 3 1) @arg ] - - location: 17 (remaining gas: 1039978.905 units remaining) - [ 4 - (Pair 3 1) ] - - location: 18 (remaining gas: 1039978.890 units remaining) - [ (Pair 3 1) ] - - location: 20 (remaining gas: 1039978.880 units remaining) - [ 3 - 1 ] - - location: 18 (remaining gas: 1039978.850 units remaining) - [ 4 - 3 - 1 ] - - location: 21 (remaining gas: 1039978.795 units remaining) - [ 7 - 1 ] - - location: 22 (remaining gas: 1039978.691 units remaining) - [ 7 ] - - location: 35 (remaining gas: 1039978.661 units remaining) - [ 7 - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 30 (remaining gas: 1039978.646 units remaining) - [ 2 @s.elt - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 32 (remaining gas: 1039978.631 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 34 (remaining gas: 1039978.621 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 32 (remaining gas: 1039978.591 units remaining) - [ 2 @s.elt - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 16 (remaining gas: 1039978.581 units remaining) - [ 3 - 2 ] - - location: 16 (remaining gas: 1039978.566 units remaining) - [ (Pair 3 2) ] - - location: 16 (remaining gas: 1039978.556 units remaining) - [ 4 - (Pair 3 2) ] - - location: 16 (remaining gas: 1039978.541 units remaining) - [ (Pair 4 3 2) @arg ] - - location: 17 (remaining gas: 1039978.531 units remaining) - [ 4 - (Pair 3 2) ] - - location: 18 (remaining gas: 1039978.516 units remaining) - [ (Pair 3 2) ] - - location: 20 (remaining gas: 1039978.506 units remaining) - [ 3 - 2 ] - - location: 18 (remaining gas: 1039978.476 units remaining) - [ 4 - 3 - 2 ] - - location: 21 (remaining gas: 1039978.421 units remaining) - [ 7 - 2 ] - - location: 22 (remaining gas: 1039978.317 units remaining) - [ 14 ] - - location: 35 (remaining gas: 1039978.287 units remaining) - [ 14 - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 30 (remaining gas: 1039978.272 units remaining) - [ 3 @s.elt - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 32 (remaining gas: 1039978.257 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 34 (remaining gas: 1039978.247 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 32 (remaining gas: 1039978.217 units remaining) - [ 3 @s.elt - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 16 (remaining gas: 1039978.207 units remaining) - [ 3 - 3 ] - - location: 16 (remaining gas: 1039978.192 units remaining) - [ (Pair 3 3) ] - - location: 16 (remaining gas: 1039978.182 units remaining) - [ 4 - (Pair 3 3) ] - - location: 16 (remaining gas: 1039978.167 units remaining) - [ (Pair 4 3 3) @arg ] - - location: 17 (remaining gas: 1039978.157 units remaining) - [ 4 - (Pair 3 3) ] - - location: 18 (remaining gas: 1039978.142 units remaining) - [ (Pair 3 3) ] - - location: 20 (remaining gas: 1039978.132 units remaining) - [ 3 - 3 ] - - location: 18 (remaining gas: 1039978.102 units remaining) - [ 4 - 3 - 3 ] - - location: 21 (remaining gas: 1039978.047 units remaining) - [ 7 - 3 ] - - location: 22 (remaining gas: 1039977.943 units remaining) - [ 21 ] - - location: 35 (remaining gas: 1039977.913 units remaining) - [ 21 - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 30 (remaining gas: 1039977.898 units remaining) - [ { 0 ; 7 ; 14 ; 21 } - { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 36 (remaining gas: 1039977.883 units remaining) - [ { PUSH int 3 ; - PAIR ; - { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] - - location: 38 (remaining gas: 1039977.873 units remaining) - [ ] - - location: 36 (remaining gas: 1039977.843 units remaining) - [ { 0 ; 7 ; 14 ; 21 } ] - - location: 39 (remaining gas: 1039977.828 units remaining) - [ {} - { 0 ; 7 ; 14 ; 21 } ] - - location: 41 (remaining gas: 1039977.813 units remaining) - [ (Pair {} { 0 ; 7 ; 14 ; 21 }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)].out deleted file mode 100644 index ce62a83e88ea..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)].out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)] - -storage - (Some 300) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.541 units remaining) - [ (Pair Unit None) ] - - location: 8 (remaining gas: 1039993.531 units remaining) - [ ] - - location: 9 (remaining gas: 1039993.521 units remaining) - [ 300 ] - - location: 12 (remaining gas: 1039993.506 units remaining) - [ (Some 300) ] - - location: 13 (remaining gas: 1039993.491 units remaining) - [ {} - (Some 300) ] - - location: 15 (remaining gas: 1039993.476 units remaining) - [ (Pair {} (Some 300)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" deleted file mode 100644 index 425d52e23f47..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" +++ /dev/null @@ -1,42 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[reverse.tz-{""}-{ "c" ; "b" ; "a" }-{ "a" ; "b" ; "c" }] - -storage - { "a" ; "b" ; "c" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039990.977 units remaining) - [ (Pair { "c" ; "b" ; "a" } { "" }) ] - - location: 9 (remaining gas: 1039990.967 units remaining) - [ { "c" ; "b" ; "a" } @parameter ] - - location: 10 (remaining gas: 1039990.952 units remaining) - [ {} - { "c" ; "b" ; "a" } @parameter ] - - location: 12 (remaining gas: 1039990.942 units remaining) - [ { "c" ; "b" ; "a" } @parameter - {} ] - - location: 13 (remaining gas: 1039990.942 units remaining) - [ "c" @parameter.elt - {} ] - - location: 15 (remaining gas: 1039990.927 units remaining) - [ { "c" } ] - - location: 13 (remaining gas: 1039990.912 units remaining) - [ "b" @parameter.elt - { "c" } ] - - location: 15 (remaining gas: 1039990.897 units remaining) - [ { "b" ; "c" } ] - - location: 13 (remaining gas: 1039990.882 units remaining) - [ "a" @parameter.elt - { "b" ; "c" } ] - - location: 15 (remaining gas: 1039990.867 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 13 (remaining gas: 1039990.852 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 16 (remaining gas: 1039990.837 units remaining) - [ {} - { "a" ; "b" ; "c" } ] - - location: 18 (remaining gas: 1039990.822 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{}-{}].out" deleted file mode 100644 index 6d4f9478a112..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{}-{}].out" +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[reverse.tz-{""}-{}-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039991.349 units remaining) - [ (Pair {} { "" }) ] - - location: 9 (remaining gas: 1039991.339 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039991.324 units remaining) - [ {} - {} @parameter ] - - location: 12 (remaining gas: 1039991.314 units remaining) - [ {} @parameter - {} ] - - location: 13 (remaining gas: 1039991.314 units remaining) - [ {} ] - - location: 16 (remaining gas: 1039991.299 units remaining) - [ {} - {} ] - - location: 18 (remaining gas: 1039991.284 units remaining) - [ (Pair {} {}) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" deleted file mode 100644 index 237f3ee98370..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" +++ /dev/null @@ -1,131 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{""}-{ "c" ; "b" ; "a" }-{ "a" ; "b" ; "c" }] - -storage - { "a" ; "b" ; "c" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039982.192 units remaining) - [ (Pair { "c" ; "b" ; "a" } { "" }) ] - - location: 9 (remaining gas: 1039982.182 units remaining) - [ { "c" ; "b" ; "a" } @parameter ] - - location: 10 (remaining gas: 1039982.167 units remaining) - [ {} - { "c" ; "b" ; "a" } @parameter ] - - location: 12 (remaining gas: 1039982.157 units remaining) - [ { "c" ; "b" ; "a" } @parameter - {} ] - - location: 13 (remaining gas: 1039982.147 units remaining) - [ True - { "c" ; "b" ; "a" } @parameter - {} ] - - location: 16 (remaining gas: 1039982.147 units remaining) - [ { "c" ; "b" ; "a" } @parameter - {} ] - - location: 18 (remaining gas: 1039982.137 units remaining) - [ "c" @parameter.hd - { "b" ; "a" } @parameter.tl - {} ] - - location: 20 (remaining gas: 1039982.127 units remaining) - [ { "b" ; "a" } @parameter.tl - "c" @parameter.hd - {} ] - - location: 21 (remaining gas: 1039982.112 units remaining) - [ "c" @parameter.hd - {} ] - - location: 23 (remaining gas: 1039982.097 units remaining) - [ { "c" } ] - - location: 21 (remaining gas: 1039982.067 units remaining) - [ { "b" ; "a" } @parameter.tl - { "c" } ] - - location: 24 (remaining gas: 1039982.057 units remaining) - [ True - { "b" ; "a" } @parameter - { "c" } ] - - location: 18 (remaining gas: 1039982.042 units remaining) - [ True - { "b" ; "a" } @parameter - { "c" } ] - - location: 16 (remaining gas: 1039982.027 units remaining) - [ { "b" ; "a" } @parameter - { "c" } ] - - location: 18 (remaining gas: 1039982.017 units remaining) - [ "b" @parameter.hd - { "a" } @parameter.tl - { "c" } ] - - location: 20 (remaining gas: 1039982.007 units remaining) - [ { "a" } @parameter.tl - "b" @parameter.hd - { "c" } ] - - location: 21 (remaining gas: 1039981.992 units remaining) - [ "b" @parameter.hd - { "c" } ] - - location: 23 (remaining gas: 1039981.977 units remaining) - [ { "b" ; "c" } ] - - location: 21 (remaining gas: 1039981.947 units remaining) - [ { "a" } @parameter.tl - { "b" ; "c" } ] - - location: 24 (remaining gas: 1039981.937 units remaining) - [ True - { "a" } @parameter - { "b" ; "c" } ] - - location: 18 (remaining gas: 1039981.922 units remaining) - [ True - { "a" } @parameter - { "b" ; "c" } ] - - location: 16 (remaining gas: 1039981.907 units remaining) - [ { "a" } @parameter - { "b" ; "c" } ] - - location: 18 (remaining gas: 1039981.897 units remaining) - [ "a" @parameter.hd - {} @parameter.tl - { "b" ; "c" } ] - - location: 20 (remaining gas: 1039981.887 units remaining) - [ {} @parameter.tl - "a" @parameter.hd - { "b" ; "c" } ] - - location: 21 (remaining gas: 1039981.872 units remaining) - [ "a" @parameter.hd - { "b" ; "c" } ] - - location: 23 (remaining gas: 1039981.857 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 21 (remaining gas: 1039981.827 units remaining) - [ {} @parameter.tl - { "a" ; "b" ; "c" } ] - - location: 24 (remaining gas: 1039981.817 units remaining) - [ True - {} @parameter - { "a" ; "b" ; "c" } ] - - location: 18 (remaining gas: 1039981.802 units remaining) - [ True - {} @parameter - { "a" ; "b" ; "c" } ] - - location: 16 (remaining gas: 1039981.787 units remaining) - [ {} @parameter - { "a" ; "b" ; "c" } ] - - location: 18 (remaining gas: 1039981.777 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 28 (remaining gas: 1039981.762 units remaining) - [ {} - { "a" ; "b" ; "c" } ] - - location: 30 (remaining gas: 1039981.752 units remaining) - [ False - {} @parameter - { "a" ; "b" ; "c" } ] - - location: 18 (remaining gas: 1039981.737 units remaining) - [ False - {} @parameter - { "a" ; "b" ; "c" } ] - - location: 16 (remaining gas: 1039981.722 units remaining) - [ {} @parameter - { "a" ; "b" ; "c" } ] - - location: 33 (remaining gas: 1039981.712 units remaining) - [ { "a" ; "b" ; "c" } ] - - location: 34 (remaining gas: 1039981.697 units remaining) - [ {} - { "a" ; "b" ; "c" } ] - - location: 36 (remaining gas: 1039981.682 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{}-{}].out" deleted file mode 100644 index 1b3e40264e2f..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{}-{}].out" +++ /dev/null @@ -1,50 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{""}-{}-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039982.564 units remaining) - [ (Pair {} { "" }) ] - - location: 9 (remaining gas: 1039982.554 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039982.539 units remaining) - [ {} - {} @parameter ] - - location: 12 (remaining gas: 1039982.529 units remaining) - [ {} @parameter - {} ] - - location: 13 (remaining gas: 1039982.519 units remaining) - [ True - {} @parameter - {} ] - - location: 16 (remaining gas: 1039982.519 units remaining) - [ {} @parameter - {} ] - - location: 18 (remaining gas: 1039982.509 units remaining) - [ {} ] - - location: 28 (remaining gas: 1039982.494 units remaining) - [ {} - {} ] - - location: 30 (remaining gas: 1039982.484 units remaining) - [ False - {} @parameter - {} ] - - location: 18 (remaining gas: 1039982.469 units remaining) - [ False - {} @parameter - {} ] - - location: 16 (remaining gas: 1039982.454 units remaining) - [ {} @parameter - {} ] - - location: 33 (remaining gas: 1039982.444 units remaining) - [ {} ] - - location: 34 (remaining gas: 1039982.429 units remaining) - [ {} - {} ] - - location: 36 (remaining gas: 1039982.414 units remaining) - [ (Pair {} {}) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0].out deleted file mode 100644 index b4ab6636d25d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.857 units remaining) - [ (Pair Unit {}) ] - - location: 8 (remaining gas: 1039994.847 units remaining) - [ ] - - location: 9 (remaining gas: 1039994.832 units remaining) - [ {} @sapling ] - - location: 11 (remaining gas: 1039994.817 units remaining) - [ {} - {} @sapling ] - - location: 13 (remaining gas: 1039994.802 units remaining) - [ (Pair {} {}) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit].out deleted file mode 100644 index 7bd609ae2c8b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit].out +++ /dev/null @@ -1,46 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039984.339 units remaining) - [ (Pair Unit Unit) ] - - location: 7 (remaining gas: 1039984.329 units remaining) - [ ] - - location: 8 (remaining gas: 1039984.319 units remaining) - [ { DROP ; SELF_ADDRESS } ] - - location: 14 (remaining gas: 1039984.309 units remaining) - [ Unit - { DROP ; SELF_ADDRESS } ] - - location: 12 (remaining gas: 1039984.299 units remaining) - [ ] - - location: 13 (remaining gas: 1039984.284 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] - - location: 15 (remaining gas: 1039984.254 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" ] - - location: 16 (remaining gas: 1039984.239 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self - "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" ] - - location: 17 (remaining gas: 1039984.229 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self.address - "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" ] - - location: 20 (remaining gas: 1039984.193 units remaining) - [ 0 ] - - location: 21 (remaining gas: 1039984.178 units remaining) - [ True ] - - location: 22 (remaining gas: 1039984.168 units remaining) - [ ] - - location: 22 (remaining gas: 1039984.153 units remaining) - [ ] - - location: 28 (remaining gas: 1039984.143 units remaining) - [ Unit ] - - location: 29 (remaining gas: 1039984.128 units remaining) - [ {} - Unit ] - - location: 31 (remaining gas: 1039984.113 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit].out deleted file mode 100644 index 34396ccd66a8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit].out +++ /dev/null @@ -1,47 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 13 (remaining gas: 1039983.500 units remaining) - [ (Pair (Right (Left Unit)) Unit) ] - - location: 13 (remaining gas: 1039983.490 units remaining) - [ ] - - location: 14 (remaining gas: 1039983.475 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] - - location: 15 (remaining gas: 1039983.465 units remaining) - [ ] - - location: 16 (remaining gas: 1039983.450 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%A" @self ] - - location: 17 (remaining gas: 1039983.440 units remaining) - [ ] - - location: 18 (remaining gas: 1039983.425 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] - - location: 19 (remaining gas: 1039972.472 units remaining) - [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @self.packed ] - - location: 20 (remaining gas: 1039972.457 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self - 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @self.packed ] - - location: 21 (remaining gas: 1039961.504 units remaining) - [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @self.packed - 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @self.packed ] - - location: 24 (remaining gas: 1039961.469 units remaining) - [ 0 ] - - location: 25 (remaining gas: 1039961.454 units remaining) - [ True ] - - location: 26 (remaining gas: 1039961.444 units remaining) - [ ] - - location: 26 (remaining gas: 1039961.429 units remaining) - [ ] - - location: 32 (remaining gas: 1039961.419 units remaining) - [ Unit ] - - location: 33 (remaining gas: 1039961.404 units remaining) - [ {} - Unit ] - - location: 35 (remaining gas: 1039961.389 units remaining) - [ (Pair {} Unit) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit].out deleted file mode 100644 index c26f56a21d20..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit].out +++ /dev/null @@ -1,93 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 13 (remaining gas: 1039954.631 units remaining) - [ (Pair (Left (Left 0)) Unit) ] - - location: 13 (remaining gas: 1039954.621 units remaining) - [ ] - - location: 14 (remaining gas: 1039954.606 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%A" @self ] - - location: 15 (remaining gas: 1039943.620 units remaining) - [ 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] - - location: 16 (remaining gas: 1039943.605 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self - 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] - - location: 17 (remaining gas: 1039932.652 units remaining) - [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked - 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] - - location: 18 (remaining gas: 1039932.642 units remaining) - [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked - 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked - 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] - - location: 19 (remaining gas: 1039932.627 units remaining) - [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked - 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] - - location: 21 (remaining gas: 1039932.617 units remaining) - [ 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked - 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] - - location: 19 (remaining gas: 1039932.587 units remaining) - [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked - 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked - 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] - - location: 24 (remaining gas: 1039932.552 units remaining) - [ -1 - 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] - - location: 25 (remaining gas: 1039932.537 units remaining) - [ True - 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] - - location: 26 (remaining gas: 1039932.527 units remaining) - [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] - - location: 26 (remaining gas: 1039932.512 units remaining) - [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] - - location: 32 (remaining gas: 1039932.497 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self - 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] - - location: 33 (remaining gas: 1039921.544 units remaining) - [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @selfpacked - 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] - - location: 36 (remaining gas: 1039921.509 units remaining) - [ 0 ] - - location: 37 (remaining gas: 1039921.494 units remaining) - [ True ] - - location: 38 (remaining gas: 1039921.484 units remaining) - [ ] - - location: 38 (remaining gas: 1039921.469 units remaining) - [ ] - - location: 44 (remaining gas: 1039921.454 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%A" @self ] - - location: 48 (remaining gas: 1039921.444 units remaining) - [ ] - - location: 49 (remaining gas: 1039921.429 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%B" @self ] - - location: 53 (remaining gas: 1039921.419 units remaining) - [ ] - - location: 54 (remaining gas: 1039921.404 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%maybe_C" @self ] - - location: 60 (remaining gas: 1039921.394 units remaining) - [ ] - - location: 61 (remaining gas: 1039921.379 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%Z" @self ] - - location: 65 (remaining gas: 1039921.369 units remaining) - [ ] - - location: 66 (remaining gas: 1039921.354 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] - - location: 76 (remaining gas: 1039921.344 units remaining) - [ ] - - location: 77 (remaining gas: 1039921.329 units remaining) - [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] - - location: 87 (remaining gas: 1039921.319 units remaining) - [ ] - - location: 88 (remaining gas: 1039921.309 units remaining) - [ Unit ] - - location: 89 (remaining gas: 1039921.294 units remaining) - [ {} - Unit ] - - location: 91 (remaining gas: 1039921.279 units remaining) - [ (Pair {} Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" deleted file mode 100644 index f67f6179b746..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" +++ /dev/null @@ -1,49 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair "hello" 0)-""-(Pair "" 0)] - -storage - (Pair "" 0) -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039987.561 units remaining) - [ (Pair "" "hello" 0) ] - - location: 9 (remaining gas: 1039987.551 units remaining) - [ (Pair "" "hello" 0) - (Pair "" "hello" 0) ] - - location: 10 (remaining gas: 1039987.541 units remaining) - [ (Pair "hello" 0) @storage - (Pair "" "hello" 0) ] - - location: 11 (remaining gas: 1039987.526 units remaining) - [ (Pair "" "hello" 0) ] - - location: 13 (remaining gas: 1039987.516 units remaining) - [ "" @parameter ] - - location: 11 (remaining gas: 1039987.486 units remaining) - [ (Pair "hello" 0) @storage - "" @parameter ] - - location: 15 (remaining gas: 1039987.476 units remaining) - [ (Pair "hello" 0) @storage - (Pair "hello" 0) @storage - "" @parameter ] - - location: 16 (remaining gas: 1039987.466 units remaining) - [ "hello" - (Pair "hello" 0) @storage - "" @parameter ] - - location: 17 (remaining gas: 1039987.456 units remaining) - [ (Pair "hello" 0) @storage - "" @parameter ] - - location: 18 (remaining gas: 1039987.446 units remaining) - [ 0 @storage.n - "" @parameter ] - - location: 19 (remaining gas: 1039987.436 units remaining) - [ "" @parameter - 0 @storage.n ] - - location: 20 (remaining gas: 1039987.421 units remaining) - [ (Pair "" 0) @storage ] - - location: 21 (remaining gas: 1039987.406 units remaining) - [ {} - (Pair "" 0) @storage ] - - location: 23 (remaining gas: 1039987.391 units remaining) - [ (Pair {} "" 0) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" deleted file mode 100644 index 419116f73969..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" +++ /dev/null @@ -1,49 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair "hello" 0)-"abc"-(Pair "abc" 0)] - -storage - (Pair "abc" 0) -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039987.531 units remaining) - [ (Pair "abc" "hello" 0) ] - - location: 9 (remaining gas: 1039987.521 units remaining) - [ (Pair "abc" "hello" 0) - (Pair "abc" "hello" 0) ] - - location: 10 (remaining gas: 1039987.511 units remaining) - [ (Pair "hello" 0) @storage - (Pair "abc" "hello" 0) ] - - location: 11 (remaining gas: 1039987.496 units remaining) - [ (Pair "abc" "hello" 0) ] - - location: 13 (remaining gas: 1039987.486 units remaining) - [ "abc" @parameter ] - - location: 11 (remaining gas: 1039987.456 units remaining) - [ (Pair "hello" 0) @storage - "abc" @parameter ] - - location: 15 (remaining gas: 1039987.446 units remaining) - [ (Pair "hello" 0) @storage - (Pair "hello" 0) @storage - "abc" @parameter ] - - location: 16 (remaining gas: 1039987.436 units remaining) - [ "hello" - (Pair "hello" 0) @storage - "abc" @parameter ] - - location: 17 (remaining gas: 1039987.426 units remaining) - [ (Pair "hello" 0) @storage - "abc" @parameter ] - - location: 18 (remaining gas: 1039987.416 units remaining) - [ 0 @storage.n - "abc" @parameter ] - - location: 19 (remaining gas: 1039987.406 units remaining) - [ "abc" @parameter - 0 @storage.n ] - - location: 20 (remaining gas: 1039987.391 units remaining) - [ (Pair "abc" 0) @storage ] - - location: 21 (remaining gas: 1039987.376 units remaining) - [ {} - (Pair "abc" 0) @storage ] - - location: 23 (remaining gas: 1039987.361 units remaining) - [ (Pair {} "abc" 0) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"world\"-(Pair \"world\" 0)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"world\"-(Pair \"world\" 0)].out" deleted file mode 100644 index 99d16e7db2dd..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"world\"-(Pair \"world\" 0)].out" +++ /dev/null @@ -1,49 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair "hello" 0)-"world"-(Pair "world" 0)] - -storage - (Pair "world" 0) -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039987.511 units remaining) - [ (Pair "world" "hello" 0) ] - - location: 9 (remaining gas: 1039987.501 units remaining) - [ (Pair "world" "hello" 0) - (Pair "world" "hello" 0) ] - - location: 10 (remaining gas: 1039987.491 units remaining) - [ (Pair "hello" 0) @storage - (Pair "world" "hello" 0) ] - - location: 11 (remaining gas: 1039987.476 units remaining) - [ (Pair "world" "hello" 0) ] - - location: 13 (remaining gas: 1039987.466 units remaining) - [ "world" @parameter ] - - location: 11 (remaining gas: 1039987.436 units remaining) - [ (Pair "hello" 0) @storage - "world" @parameter ] - - location: 15 (remaining gas: 1039987.426 units remaining) - [ (Pair "hello" 0) @storage - (Pair "hello" 0) @storage - "world" @parameter ] - - location: 16 (remaining gas: 1039987.416 units remaining) - [ "hello" - (Pair "hello" 0) @storage - "world" @parameter ] - - location: 17 (remaining gas: 1039987.406 units remaining) - [ (Pair "hello" 0) @storage - "world" @parameter ] - - location: 18 (remaining gas: 1039987.396 units remaining) - [ 0 @storage.n - "world" @parameter ] - - location: 19 (remaining gas: 1039987.386 units remaining) - [ "world" @parameter - 0 @storage.n ] - - location: 20 (remaining gas: 1039987.371 units remaining) - [ (Pair "world" 0) @storage ] - - location: 21 (remaining gas: 1039987.356 units remaining) - [ {} - (Pair "world" 0) @storage ] - - location: 23 (remaining gas: 1039987.341 units remaining) - [ (Pair {} "world" 0) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 0)-1-(Pair \"hello\" 1)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 0)-1-(Pair \"hello\" 1)].out" deleted file mode 100644 index 43427018d89d..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 0)-1-(Pair \"hello\" 1)].out" +++ /dev/null @@ -1,46 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair "hello" 0)-1-(Pair "hello" 1)] - -storage - (Pair "hello" 1) -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039988.178 units remaining) - [ (Pair 1 "hello" 0) ] - - location: 9 (remaining gas: 1039988.168 units remaining) - [ (Pair 1 "hello" 0) - (Pair 1 "hello" 0) ] - - location: 10 (remaining gas: 1039988.158 units remaining) - [ (Pair "hello" 0) @storage - (Pair 1 "hello" 0) ] - - location: 11 (remaining gas: 1039988.143 units remaining) - [ (Pair 1 "hello" 0) ] - - location: 13 (remaining gas: 1039988.133 units remaining) - [ 1 @parameter ] - - location: 11 (remaining gas: 1039988.103 units remaining) - [ (Pair "hello" 0) @storage - 1 @parameter ] - - location: 15 (remaining gas: 1039988.093 units remaining) - [ (Pair "hello" 0) @storage - (Pair "hello" 0) @storage - 1 @parameter ] - - location: 16 (remaining gas: 1039988.083 units remaining) - [ 0 - (Pair "hello" 0) @storage - 1 @parameter ] - - location: 17 (remaining gas: 1039988.073 units remaining) - [ (Pair "hello" 0) @storage - 1 @parameter ] - - location: 18 (remaining gas: 1039988.063 units remaining) - [ "hello" @storage.s - 1 @parameter ] - - location: 19 (remaining gas: 1039988.048 units remaining) - [ (Pair "hello" 1) @storage ] - - location: 20 (remaining gas: 1039988.033 units remaining) - [ {} - (Pair "hello" 1) @storage ] - - location: 22 (remaining gas: 1039988.018 units remaining) - [ (Pair {} "hello" 1) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 500)-3-(Pair \"hello\" 3)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 500)-3-(Pair \"hello\" 3)].out" deleted file mode 100644 index 334ac1c28dac..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 500)-3-(Pair \"hello\" 3)].out" +++ /dev/null @@ -1,46 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair "hello" 500)-3-(Pair "hello" 3)] - -storage - (Pair "hello" 3) -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039988.178 units remaining) - [ (Pair 3 "hello" 500) ] - - location: 9 (remaining gas: 1039988.168 units remaining) - [ (Pair 3 "hello" 500) - (Pair 3 "hello" 500) ] - - location: 10 (remaining gas: 1039988.158 units remaining) - [ (Pair "hello" 500) @storage - (Pair 3 "hello" 500) ] - - location: 11 (remaining gas: 1039988.143 units remaining) - [ (Pair 3 "hello" 500) ] - - location: 13 (remaining gas: 1039988.133 units remaining) - [ 3 @parameter ] - - location: 11 (remaining gas: 1039988.103 units remaining) - [ (Pair "hello" 500) @storage - 3 @parameter ] - - location: 15 (remaining gas: 1039988.093 units remaining) - [ (Pair "hello" 500) @storage - (Pair "hello" 500) @storage - 3 @parameter ] - - location: 16 (remaining gas: 1039988.083 units remaining) - [ 500 - (Pair "hello" 500) @storage - 3 @parameter ] - - location: 17 (remaining gas: 1039988.073 units remaining) - [ (Pair "hello" 500) @storage - 3 @parameter ] - - location: 18 (remaining gas: 1039988.063 units remaining) - [ "hello" @storage.s - 3 @parameter ] - - location: 19 (remaining gas: 1039988.048 units remaining) - [ (Pair "hello" 3) @storage ] - - location: 20 (remaining gas: 1039988.033 units remaining) - [ {} - (Pair "hello" 3) @storage ] - - location: 22 (remaining gas: 1039988.018 units remaining) - [ (Pair {} "hello" 3) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 7)-100-(Pair \"hello\" 100)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 7)-100-(Pair \"hello\" 100)].out" deleted file mode 100644 index a2fea7a57765..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 7)-100-(Pair \"hello\" 100)].out" +++ /dev/null @@ -1,46 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair "hello" 7)-100-(Pair "hello" 100)] - -storage - (Pair "hello" 100) -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039988.178 units remaining) - [ (Pair 100 "hello" 7) ] - - location: 9 (remaining gas: 1039988.168 units remaining) - [ (Pair 100 "hello" 7) - (Pair 100 "hello" 7) ] - - location: 10 (remaining gas: 1039988.158 units remaining) - [ (Pair "hello" 7) @storage - (Pair 100 "hello" 7) ] - - location: 11 (remaining gas: 1039988.143 units remaining) - [ (Pair 100 "hello" 7) ] - - location: 13 (remaining gas: 1039988.133 units remaining) - [ 100 @parameter ] - - location: 11 (remaining gas: 1039988.103 units remaining) - [ (Pair "hello" 7) @storage - 100 @parameter ] - - location: 15 (remaining gas: 1039988.093 units remaining) - [ (Pair "hello" 7) @storage - (Pair "hello" 7) @storage - 100 @parameter ] - - location: 16 (remaining gas: 1039988.083 units remaining) - [ 7 - (Pair "hello" 7) @storage - 100 @parameter ] - - location: 17 (remaining gas: 1039988.073 units remaining) - [ (Pair "hello" 7) @storage - 100 @parameter ] - - location: 18 (remaining gas: 1039988.063 units remaining) - [ "hello" @storage.s - 100 @parameter ] - - location: 19 (remaining gas: 1039988.048 units remaining) - [ (Pair "hello" 100) @storage ] - - location: 20 (remaining gas: 1039988.033 units remaining) - [ {} - (Pair "hello" 100) @storage ] - - location: 22 (remaining gas: 1039988.018 units remaining) - [ (Pair {} "hello" 100) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" deleted file mode 100644 index f0dca424f003..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ "a" ; "b" ; "c" }-{ "a" ; "b" ; "c" }] - -storage - { "a" ; "b" ; "c" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039993.773 units remaining) - [ (Pair { "a" ; "b" ; "c" } {}) ] - - location: 9 (remaining gas: 1039993.763 units remaining) - [ { "a" ; "b" ; "c" } @parameter ] - - location: 10 (remaining gas: 1039993.748 units remaining) - [ {} - { "a" ; "b" ; "c" } @parameter ] - - location: 12 (remaining gas: 1039993.733 units remaining) - [ (Pair {} { "a" ; "b" ; "c" }) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"asdf\" ; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"asdf\" ; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" deleted file mode 100644 index c5bc49081234..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"asdf\" ; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ "asdf" ; "bcde" }-{ "asdf" ; "bcde" }] - -storage - { "asdf" ; "bcde" } -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039994.212 units remaining) - [ (Pair { "asdf" ; "bcde" } {}) ] - - location: 9 (remaining gas: 1039994.202 units remaining) - [ { "asdf" ; "bcde" } @parameter ] - - location: 10 (remaining gas: 1039994.187 units remaining) - [ {} - { "asdf" ; "bcde" } @parameter ] - - location: 12 (remaining gas: 1039994.172 units remaining) - [ (Pair {} { "asdf" ; "bcde" }) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}].out deleted file mode 100644 index 9cf1d4bc35c8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}].out +++ /dev/null @@ -1,19 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}] - -storage - {} -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039995.025 units remaining) - [ (Pair {} {}) ] - - location: 9 (remaining gas: 1039995.015 units remaining) - [ {} @parameter ] - - location: 10 (remaining gas: 1039995 units remaining) - [ {} - {} @parameter ] - - location: 12 (remaining gas: 1039994.985 units remaining) - [ (Pair {} {}) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out deleted file mode 100644 index 37b9bba85809..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out +++ /dev/null @@ -1,47 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94] - -storage - -94 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039990.518 units remaining) - [ (Pair { -100 ; 1 ; 2 ; 3 } 111) ] - - location: 8 (remaining gas: 1039990.508 units remaining) - [ { -100 ; 1 ; 2 ; 3 } @parameter ] - - location: 9 (remaining gas: 1039990.498 units remaining) - [ 0 - { -100 ; 1 ; 2 ; 3 } @parameter ] - - location: 12 (remaining gas: 1039990.488 units remaining) - [ { -100 ; 1 ; 2 ; 3 } @parameter - 0 ] - - location: 13 (remaining gas: 1039990.488 units remaining) - [ -100 @parameter.elt - 0 ] - - location: 15 (remaining gas: 1039990.433 units remaining) - [ -100 ] - - location: 13 (remaining gas: 1039990.418 units remaining) - [ 1 @parameter.elt - -100 ] - - location: 15 (remaining gas: 1039990.363 units remaining) - [ -99 ] - - location: 13 (remaining gas: 1039990.348 units remaining) - [ 2 @parameter.elt - -99 ] - - location: 15 (remaining gas: 1039990.293 units remaining) - [ -97 ] - - location: 13 (remaining gas: 1039990.278 units remaining) - [ 3 @parameter.elt - -97 ] - - location: 15 (remaining gas: 1039990.223 units remaining) - [ -94 ] - - location: 13 (remaining gas: 1039990.208 units remaining) - [ -94 ] - - location: 16 (remaining gas: 1039990.193 units remaining) - [ {} - -94 ] - - location: 18 (remaining gas: 1039990.178 units remaining) - [ (Pair {} -94) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1].out deleted file mode 100644 index 0c16b0d15cee..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039991.873 units remaining) - [ (Pair { 1 } 111) ] - - location: 8 (remaining gas: 1039991.863 units remaining) - [ { 1 } @parameter ] - - location: 9 (remaining gas: 1039991.853 units remaining) - [ 0 - { 1 } @parameter ] - - location: 12 (remaining gas: 1039991.843 units remaining) - [ { 1 } @parameter - 0 ] - - location: 13 (remaining gas: 1039991.843 units remaining) - [ 1 @parameter.elt - 0 ] - - location: 15 (remaining gas: 1039991.788 units remaining) - [ 1 ] - - location: 13 (remaining gas: 1039991.773 units remaining) - [ 1 ] - - location: 16 (remaining gas: 1039991.758 units remaining) - [ {} - 1 ] - - location: 18 (remaining gas: 1039991.743 units remaining) - [ (Pair {} 1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0].out deleted file mode 100644 index 46e022d0202f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0].out +++ /dev/null @@ -1,27 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039992.173 units remaining) - [ (Pair {} 111) ] - - location: 8 (remaining gas: 1039992.163 units remaining) - [ {} @parameter ] - - location: 9 (remaining gas: 1039992.153 units remaining) - [ 0 - {} @parameter ] - - location: 12 (remaining gas: 1039992.143 units remaining) - [ {} @parameter - 0 ] - - location: 13 (remaining gas: 1039992.143 units remaining) - [ 0 ] - - location: 16 (remaining gas: 1039992.128 units remaining) - [ {} - 0 ] - - location: 18 (remaining gas: 1039992.113 units remaining) - [ (Pair {} 0) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hello\" ; \"World\" } None)-\"\"-(Pai.3d2044726e.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hello\" ; \"World\" } None)-\"\"-(Pai.3d2044726e.out" deleted file mode 100644 index c9b68333b65c..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hello\" ; \"World\" } None)-\"\"-(Pai.3d2044726e.out" +++ /dev/null @@ -1,61 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { "Hello" ; "World" } None)-""-(Pair { "Hello" ; "World" } (Some False))] - -storage - (Pair { "Hello" ; "World" } (Some False)) -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039983.293 units remaining) - [ (Pair "" { "Hello" ; "World" } None) ] - - location: 11 (remaining gas: 1039983.283 units remaining) - [ (Pair "" { "Hello" ; "World" } None) - (Pair "" { "Hello" ; "World" } None) ] - - location: 12 (remaining gas: 1039983.273 units remaining) - [ (Pair "" { "Hello" ; "World" } None) - (Pair "" { "Hello" ; "World" } None) - (Pair "" { "Hello" ; "World" } None) ] - - location: 13 (remaining gas: 1039983.263 units remaining) - [ "" @parameter - (Pair "" { "Hello" ; "World" } None) - (Pair "" { "Hello" ; "World" } None) ] - - location: 14 (remaining gas: 1039983.248 units remaining) - [ (Pair "" { "Hello" ; "World" } None) - (Pair "" { "Hello" ; "World" } None) ] - - location: 17 (remaining gas: 1039983.238 units remaining) - [ (Pair { "Hello" ; "World" } None) @storage - (Pair "" { "Hello" ; "World" } None) ] - - location: 18 (remaining gas: 1039983.228 units remaining) - [ { "Hello" ; "World" } - (Pair "" { "Hello" ; "World" } None) ] - - location: 14 (remaining gas: 1039983.198 units remaining) - [ "" @parameter - { "Hello" ; "World" } - (Pair "" { "Hello" ; "World" } None) ] - - location: 19 (remaining gas: 1039982.978 units remaining) - [ False - (Pair "" { "Hello" ; "World" } None) ] - - location: 20 (remaining gas: 1039982.963 units remaining) - [ (Some False) - (Pair "" { "Hello" ; "World" } None) ] - - location: 21 (remaining gas: 1039982.948 units remaining) - [ (Pair "" { "Hello" ; "World" } None) ] - - location: 24 (remaining gas: 1039982.938 units remaining) - [ (Pair { "Hello" ; "World" } None) @storage ] - - location: 25 (remaining gas: 1039982.928 units remaining) - [ { "Hello" ; "World" } ] - - location: 21 (remaining gas: 1039982.898 units remaining) - [ (Some False) - { "Hello" ; "World" } ] - - location: 26 (remaining gas: 1039982.888 units remaining) - [ { "Hello" ; "World" } - (Some False) ] - - location: 27 (remaining gas: 1039982.873 units remaining) - [ (Pair { "Hello" ; "World" } (Some False)) ] - - location: 28 (remaining gas: 1039982.858 units remaining) - [ {} - (Pair { "Hello" ; "World" } (Some False)) ] - - location: 30 (remaining gas: 1039982.843 units remaining) - [ (Pair {} { "Hello" ; "World" } (Some False)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hi\" } None)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hi\" } None)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" deleted file mode 100644 index f422fe657467..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hi\" } None)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" +++ /dev/null @@ -1,61 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { "Hi" } None)-"Hi"-(Pair { "Hi" } (Some True))] - -storage - (Pair { "Hi" } (Some True)) -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039983.772 units remaining) - [ (Pair "Hi" { "Hi" } None) ] - - location: 11 (remaining gas: 1039983.762 units remaining) - [ (Pair "Hi" { "Hi" } None) - (Pair "Hi" { "Hi" } None) ] - - location: 12 (remaining gas: 1039983.752 units remaining) - [ (Pair "Hi" { "Hi" } None) - (Pair "Hi" { "Hi" } None) - (Pair "Hi" { "Hi" } None) ] - - location: 13 (remaining gas: 1039983.742 units remaining) - [ "Hi" @parameter - (Pair "Hi" { "Hi" } None) - (Pair "Hi" { "Hi" } None) ] - - location: 14 (remaining gas: 1039983.727 units remaining) - [ (Pair "Hi" { "Hi" } None) - (Pair "Hi" { "Hi" } None) ] - - location: 17 (remaining gas: 1039983.717 units remaining) - [ (Pair { "Hi" } None) @storage - (Pair "Hi" { "Hi" } None) ] - - location: 18 (remaining gas: 1039983.707 units remaining) - [ { "Hi" } - (Pair "Hi" { "Hi" } None) ] - - location: 14 (remaining gas: 1039983.677 units remaining) - [ "Hi" @parameter - { "Hi" } - (Pair "Hi" { "Hi" } None) ] - - location: 19 (remaining gas: 1039983.492 units remaining) - [ True - (Pair "Hi" { "Hi" } None) ] - - location: 20 (remaining gas: 1039983.477 units remaining) - [ (Some True) - (Pair "Hi" { "Hi" } None) ] - - location: 21 (remaining gas: 1039983.462 units remaining) - [ (Pair "Hi" { "Hi" } None) ] - - location: 24 (remaining gas: 1039983.452 units remaining) - [ (Pair { "Hi" } None) @storage ] - - location: 25 (remaining gas: 1039983.442 units remaining) - [ { "Hi" } ] - - location: 21 (remaining gas: 1039983.412 units remaining) - [ (Some True) - { "Hi" } ] - - location: 26 (remaining gas: 1039983.402 units remaining) - [ { "Hi" } - (Some True) ] - - location: 27 (remaining gas: 1039983.387 units remaining) - [ (Pair { "Hi" } (Some True)) ] - - location: 28 (remaining gas: 1039983.372 units remaining) - [ {} - (Pair { "Hi" } (Some True)) ] - - location: 30 (remaining gas: 1039983.357 units remaining) - [ (Pair {} { "Hi" } (Some True)) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-\"Hi\"-(Pair {} (Some False))].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-\"Hi\"-(Pair {} (Some False))].out" deleted file mode 100644 index 8e3eb8792a57..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-\"Hi\"-(Pair {} (Some False))].out" +++ /dev/null @@ -1,61 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-"Hi"-(Pair {} (Some False))] - -storage - (Pair {} (Some False)) -emitted operations - -big_map diff - -trace - - location: 11 (remaining gas: 1039984.106 units remaining) - [ (Pair "Hi" {} None) ] - - location: 11 (remaining gas: 1039984.096 units remaining) - [ (Pair "Hi" {} None) - (Pair "Hi" {} None) ] - - location: 12 (remaining gas: 1039984.086 units remaining) - [ (Pair "Hi" {} None) - (Pair "Hi" {} None) - (Pair "Hi" {} None) ] - - location: 13 (remaining gas: 1039984.076 units remaining) - [ "Hi" @parameter - (Pair "Hi" {} None) - (Pair "Hi" {} None) ] - - location: 14 (remaining gas: 1039984.061 units remaining) - [ (Pair "Hi" {} None) - (Pair "Hi" {} None) ] - - location: 17 (remaining gas: 1039984.051 units remaining) - [ (Pair {} None) @storage - (Pair "Hi" {} None) ] - - location: 18 (remaining gas: 1039984.041 units remaining) - [ {} - (Pair "Hi" {} None) ] - - location: 14 (remaining gas: 1039984.011 units remaining) - [ "Hi" @parameter - {} - (Pair "Hi" {} None) ] - - location: 19 (remaining gas: 1039983.861 units remaining) - [ False - (Pair "Hi" {} None) ] - - location: 20 (remaining gas: 1039983.846 units remaining) - [ (Some False) - (Pair "Hi" {} None) ] - - location: 21 (remaining gas: 1039983.831 units remaining) - [ (Pair "Hi" {} None) ] - - location: 24 (remaining gas: 1039983.821 units remaining) - [ (Pair {} None) @storage ] - - location: 25 (remaining gas: 1039983.811 units remaining) - [ {} ] - - location: 21 (remaining gas: 1039983.781 units remaining) - [ (Some False) - {} ] - - location: 26 (remaining gas: 1039983.771 units remaining) - [ {} - (Some False) ] - - location: 27 (remaining gas: 1039983.756 units remaining) - [ (Pair {} (Some False)) ] - - location: 28 (remaining gas: 1039983.741 units remaining) - [ {} - (Pair {} (Some False)) ] - - location: 30 (remaining gas: 1039983.726 units remaining) - [ (Pair {} {} (Some False)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out deleted file mode 100644 index e7a62b39c4f1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6] - -storage - 6 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039992.075 units remaining) - [ (Pair { 1 ; 2 ; 3 ; 4 ; 5 ; 6 } 111) ] - - location: 8 (remaining gas: 1039992.065 units remaining) - [ { 1 ; 2 ; 3 ; 4 ; 5 ; 6 } @parameter ] - - location: 9 (remaining gas: 1039992.050 units remaining) - [ 6 ] - - location: 10 (remaining gas: 1039992.035 units remaining) - [ {} - 6 ] - - location: 12 (remaining gas: 1039992.020 units remaining) - [ (Pair {} 6) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out deleted file mode 100644 index c9e499b3996a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3] - -storage - 3 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.640 units remaining) - [ (Pair { 1 ; 2 ; 3 } 111) ] - - location: 8 (remaining gas: 1039993.630 units remaining) - [ { 1 ; 2 ; 3 } @parameter ] - - location: 9 (remaining gas: 1039993.615 units remaining) - [ 3 ] - - location: 10 (remaining gas: 1039993.600 units remaining) - [ {} - 3 ] - - location: 12 (remaining gas: 1039993.585 units remaining) - [ (Pair {} 3) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1].out deleted file mode 100644 index dbc893156115..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1] - -storage - 1 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.520 units remaining) - [ (Pair { 1 } 111) ] - - location: 8 (remaining gas: 1039994.510 units remaining) - [ { 1 } @parameter ] - - location: 9 (remaining gas: 1039994.495 units remaining) - [ 1 ] - - location: 10 (remaining gas: 1039994.480 units remaining) - [ {} - 1 ] - - location: 12 (remaining gas: 1039994.465 units remaining) - [ (Pair {} 1) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0].out deleted file mode 100644 index 4407ad4c6053..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0].out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0] - -storage - 0 -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.820 units remaining) - [ (Pair {} 111) ] - - location: 8 (remaining gas: 1039994.810 units remaining) - [ {} @parameter ] - - location: 9 (remaining gas: 1039994.795 units remaining) - [ 0 ] - - location: 10 (remaining gas: 1039994.780 units remaining) - [ {} - 0 ] - - location: 12 (remaining gas: 1039994.765 units remaining) - [ (Pair {} 0) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a.a07ae9dddf.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a.a07ae9dddf.out deleted file mode 100644 index b363ff7ea1fb..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a.a07ae9dddf.out +++ /dev/null @@ -1,24 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722)] - -storage - (Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722) -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039993.957 units remaining) - [ (Pair 0x48656c6c6f2c20776f726c6421 None) ] - - location: 8 (remaining gas: 1039993.947 units remaining) - [ 0x48656c6c6f2c20776f726c6421 @parameter ] - - location: 9 (remaining gas: 1039992.490 units remaining) - [ 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722 ] - - location: 10 (remaining gas: 1039992.475 units remaining) - [ (Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722) ] - - location: 11 (remaining gas: 1039992.460 units remaining) - [ {} - (Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722) ] - - location: 13 (remaining gas: 1039992.445 units remaining) - [ (Pair {} - (Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)].out deleted file mode 100644 index 319389b31832..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)] - -storage - (Some 0) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Left (Pair 0 0)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Left (Pair 0 0)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 0 0) @parameter.left ] - - location: 17 (remaining gas: 1039989.674 units remaining) - [ 0 - 0 ] - - location: 18 (remaining gas: 1039989.674 units remaining) - [ 0 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 0 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 0) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 0) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 0)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)].out deleted file mode 100644 index 4ca9302454b3..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)] - -storage - (Some 0) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Left (Pair 0 1)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Left (Pair 0 1)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 0 1) @parameter.left ] - - location: 17 (remaining gas: 1039989.674 units remaining) - [ 0 - 1 ] - - location: 18 (remaining gas: 1039989.674 units remaining) - [ 0 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 0 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 0) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 0) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 0)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)].out deleted file mode 100644 index 9767e95878bc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)] - -storage - (Some 4) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Left (Pair 1 2)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Left (Pair 1 2)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 1 2) @parameter.left ] - - location: 17 (remaining gas: 1039989.674 units remaining) - [ 1 - 2 ] - - location: 18 (remaining gas: 1039989.674 units remaining) - [ 4 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 4 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 4) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 4) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 4)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)].out deleted file mode 100644 index d4515ea764d5..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)] - -storage - (Some 60) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Left (Pair 15 2)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Left (Pair 15 2)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 15 2) @parameter.left ] - - location: 17 (remaining gas: 1039989.674 units remaining) - [ 15 - 2 ] - - location: 18 (remaining gas: 1039989.674 units remaining) - [ 60 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 60 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 60) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 60) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 60)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)].out deleted file mode 100644 index 7438e9021817..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)] - -storage - (Some 16) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Left (Pair 8 1)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Left (Pair 8 1)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 8 1) @parameter.left ] - - location: 17 (remaining gas: 1039989.674 units remaining) - [ 8 - 1 ] - - location: 18 (remaining gas: 1039989.674 units remaining) - [ 16 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 16 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 16) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 16) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 16)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)].out deleted file mode 100644 index 3a1126488924..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)] - -storage - (Some 0) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Right (Pair 0 0)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Right (Pair 0 0)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 0 0) @parameter.right ] - - location: 20 (remaining gas: 1039989.674 units remaining) - [ 0 - 0 ] - - location: 21 (remaining gas: 1039989.674 units remaining) - [ 0 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 0 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 0) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 0) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 0)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)].out deleted file mode 100644 index 426c4a4750b8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)] - -storage - (Some 0) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Right (Pair 0 1)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Right (Pair 0 1)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 0 1) @parameter.right ] - - location: 20 (remaining gas: 1039989.674 units remaining) - [ 0 - 1 ] - - location: 21 (remaining gas: 1039989.674 units remaining) - [ 0 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 0 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 0) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 0) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 0)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)].out deleted file mode 100644 index 3415da0027cd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)] - -storage - (Some 0) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Right (Pair 1 2)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Right (Pair 1 2)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 1 2) @parameter.right ] - - location: 20 (remaining gas: 1039989.674 units remaining) - [ 1 - 2 ] - - location: 21 (remaining gas: 1039989.674 units remaining) - [ 0 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 0 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 0) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 0) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 0)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)].out deleted file mode 100644 index 34ee09106209..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)] - -storage - (Some 3) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Right (Pair 15 2)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Right (Pair 15 2)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 15 2) @parameter.right ] - - location: 20 (remaining gas: 1039989.674 units remaining) - [ 15 - 2 ] - - location: 21 (remaining gas: 1039989.674 units remaining) - [ 3 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 3 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 3) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 3) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 3)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)].out deleted file mode 100644 index a81434d99414..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)].out +++ /dev/null @@ -1,30 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)] - -storage - (Some 4) -emitted operations - -big_map diff - -trace - - location: 14 (remaining gas: 1039989.704 units remaining) - [ (Pair (Right (Pair 8 1)) None) ] - - location: 14 (remaining gas: 1039989.694 units remaining) - [ (Right (Pair 8 1)) @parameter ] - - location: 15 (remaining gas: 1039989.684 units remaining) - [ (Pair 8 1) @parameter.right ] - - location: 20 (remaining gas: 1039989.674 units remaining) - [ 8 - 1 ] - - location: 21 (remaining gas: 1039989.674 units remaining) - [ 4 ] - - location: 15 (remaining gas: 1039989.659 units remaining) - [ 4 ] - - location: 22 (remaining gas: 1039989.644 units remaining) - [ (Some 4) ] - - location: 23 (remaining gas: 1039989.629 units remaining) - [ {} - (Some 4) ] - - location: 25 (remaining gas: 1039989.614 units remaining) - [ (Pair {} (Some 4)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None].out deleted file mode 100644 index be74e3e6af86..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None].out +++ /dev/null @@ -1,31 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None] - -storage - None -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039989.042 units remaining) - [ (Pair (Pair 0 0) None) ] - - location: 10 (remaining gas: 1039989.032 units remaining) - [ (Pair 0 0) @parameter - None @storage ] - - location: 11 (remaining gas: 1039989.022 units remaining) - [ None @storage - (Pair 0 0) @parameter ] - - location: 13 (remaining gas: 1039989.012 units remaining) - [ (Pair 0 0) @parameter ] - - location: 15 (remaining gas: 1039989.002 units remaining) - [ ] - - location: 16 (remaining gas: 1039988.987 units remaining) - [ None ] - - location: 13 (remaining gas: 1039988.972 units remaining) - [ None ] - - location: 22 (remaining gas: 1039988.957 units remaining) - [ {} - None ] - - location: 24 (remaining gas: 1039988.942 units remaining) - [ (Pair {} None) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" deleted file mode 100644 index 635d3d4a9cf0..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 0 0-(Some "")] - -storage - (Some "") -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.898 units remaining) - [ (Pair (Pair 0 0) (Some "Foo")) ] - - location: 10 (remaining gas: 1039988.888 units remaining) - [ (Pair 0 0) @parameter - (Some "Foo") @storage ] - - location: 11 (remaining gas: 1039988.878 units remaining) - [ (Some "Foo") @storage - (Pair 0 0) @parameter ] - - location: 13 (remaining gas: 1039988.868 units remaining) - [ "Foo" @storage.some - (Pair 0 0) @parameter ] - - location: 19 (remaining gas: 1039988.858 units remaining) - [ (Pair 0 0) @parameter - "Foo" @storage.some ] - - location: 20 (remaining gas: 1039988.848 units remaining) - [ 0 - 0 - "Foo" @storage.some ] - - location: 21 (remaining gas: 1039988.808 units remaining) - [ (Some "") ] - - location: 13 (remaining gas: 1039988.793 units remaining) - [ (Some "") ] - - location: 22 (remaining gas: 1039988.778 units remaining) - [ {} - (Some "") ] - - location: 24 (remaining gas: 1039988.763 units remaining) - [ (Pair {} (Some "")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 10-None].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 10-None].out" deleted file mode 100644 index 05ac55895964..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 10-None].out" +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 0 10-None] - -storage - None -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.898 units remaining) - [ (Pair (Pair 0 10) (Some "Foo")) ] - - location: 10 (remaining gas: 1039988.888 units remaining) - [ (Pair 0 10) @parameter - (Some "Foo") @storage ] - - location: 11 (remaining gas: 1039988.878 units remaining) - [ (Some "Foo") @storage - (Pair 0 10) @parameter ] - - location: 13 (remaining gas: 1039988.868 units remaining) - [ "Foo" @storage.some - (Pair 0 10) @parameter ] - - location: 19 (remaining gas: 1039988.858 units remaining) - [ (Pair 0 10) @parameter - "Foo" @storage.some ] - - location: 20 (remaining gas: 1039988.848 units remaining) - [ 0 - 10 - "Foo" @storage.some ] - - location: 21 (remaining gas: 1039988.808 units remaining) - [ None ] - - location: 13 (remaining gas: 1039988.793 units remaining) - [ None ] - - location: 22 (remaining gas: 1039988.778 units remaining) - [ {} - None ] - - location: 24 (remaining gas: 1039988.763 units remaining) - [ (Pair {} None) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" deleted file mode 100644 index 9fa8b466a588..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 0 2-(Some "Fo")] - -storage - (Some "Fo") -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.898 units remaining) - [ (Pair (Pair 0 2) (Some "Foo")) ] - - location: 10 (remaining gas: 1039988.888 units remaining) - [ (Pair 0 2) @parameter - (Some "Foo") @storage ] - - location: 11 (remaining gas: 1039988.878 units remaining) - [ (Some "Foo") @storage - (Pair 0 2) @parameter ] - - location: 13 (remaining gas: 1039988.868 units remaining) - [ "Foo" @storage.some - (Pair 0 2) @parameter ] - - location: 19 (remaining gas: 1039988.858 units remaining) - [ (Pair 0 2) @parameter - "Foo" @storage.some ] - - location: 20 (remaining gas: 1039988.848 units remaining) - [ 0 - 2 - "Foo" @storage.some ] - - location: 21 (remaining gas: 1039988.808 units remaining) - [ (Some "Fo") ] - - location: 13 (remaining gas: 1039988.793 units remaining) - [ (Some "Fo") ] - - location: 22 (remaining gas: 1039988.778 units remaining) - [ {} - (Some "Fo") ] - - location: 24 (remaining gas: 1039988.763 units remaining) - [ (Pair {} (Some "Fo")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" deleted file mode 100644 index 57ce8c271fad..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 1 1-(Some "o")] - -storage - (Some "o") -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.898 units remaining) - [ (Pair (Pair 1 1) (Some "Foo")) ] - - location: 10 (remaining gas: 1039988.888 units remaining) - [ (Pair 1 1) @parameter - (Some "Foo") @storage ] - - location: 11 (remaining gas: 1039988.878 units remaining) - [ (Some "Foo") @storage - (Pair 1 1) @parameter ] - - location: 13 (remaining gas: 1039988.868 units remaining) - [ "Foo" @storage.some - (Pair 1 1) @parameter ] - - location: 19 (remaining gas: 1039988.858 units remaining) - [ (Pair 1 1) @parameter - "Foo" @storage.some ] - - location: 20 (remaining gas: 1039988.848 units remaining) - [ 1 - 1 - "Foo" @storage.some ] - - location: 21 (remaining gas: 1039988.808 units remaining) - [ (Some "o") ] - - location: 13 (remaining gas: 1039988.793 units remaining) - [ (Some "o") ] - - location: 22 (remaining gas: 1039988.778 units remaining) - [ {} - (Some "o") ] - - location: 24 (remaining gas: 1039988.763 units remaining) - [ (Pair {} (Some "o")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 3-None].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 3-None].out" deleted file mode 100644 index 533cc770e1c2..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 3-None].out" +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 1 3-None] - -storage - None -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.898 units remaining) - [ (Pair (Pair 1 3) (Some "Foo")) ] - - location: 10 (remaining gas: 1039988.888 units remaining) - [ (Pair 1 3) @parameter - (Some "Foo") @storage ] - - location: 11 (remaining gas: 1039988.878 units remaining) - [ (Some "Foo") @storage - (Pair 1 3) @parameter ] - - location: 13 (remaining gas: 1039988.868 units remaining) - [ "Foo" @storage.some - (Pair 1 3) @parameter ] - - location: 19 (remaining gas: 1039988.858 units remaining) - [ (Pair 1 3) @parameter - "Foo" @storage.some ] - - location: 20 (remaining gas: 1039988.848 units remaining) - [ 1 - 3 - "Foo" @storage.some ] - - location: 21 (remaining gas: 1039988.808 units remaining) - [ None ] - - location: 13 (remaining gas: 1039988.793 units remaining) - [ None ] - - location: 22 (remaining gas: 1039988.778 units remaining) - [ {} - None ] - - location: 24 (remaining gas: 1039988.763 units remaining) - [ (Pair {} None) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 10 5-None].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 10 5-None].out" deleted file mode 100644 index 4c16587872d3..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 10 5-None].out" +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 10 5-None] - -storage - None -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.898 units remaining) - [ (Pair (Pair 10 5) (Some "Foo")) ] - - location: 10 (remaining gas: 1039988.888 units remaining) - [ (Pair 10 5) @parameter - (Some "Foo") @storage ] - - location: 11 (remaining gas: 1039988.878 units remaining) - [ (Some "Foo") @storage - (Pair 10 5) @parameter ] - - location: 13 (remaining gas: 1039988.868 units remaining) - [ "Foo" @storage.some - (Pair 10 5) @parameter ] - - location: 19 (remaining gas: 1039988.858 units remaining) - [ (Pair 10 5) @parameter - "Foo" @storage.some ] - - location: 20 (remaining gas: 1039988.848 units remaining) - [ 10 - 5 - "Foo" @storage.some ] - - location: 21 (remaining gas: 1039988.808 units remaining) - [ None ] - - location: 13 (remaining gas: 1039988.793 units remaining) - [ None ] - - location: 22 (remaining gas: 1039988.778 units remaining) - [ {} - None ] - - location: 24 (remaining gas: 1039988.763 units remaining) - [ (Pair {} None) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some\"FooFooFooFooFooFooFooFooFooFooFooFooFooFo.c508d67bb0.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some\"FooFooFooFooFooFooFooFooFooFooFooFooFooFo.c508d67bb0.out" deleted file mode 100644 index 5d14300881f4..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some\"FooFooFooFooFooFooFooFooFooFooFooFooFooFo.c508d67bb0.out" +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some"FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo"-Pair 1 10000-None] - -storage - None -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039928.928 units remaining) - [ (Pair (Pair 1 10000) - (Some "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo")) ] - - location: 10 (remaining gas: 1039928.918 units remaining) - [ (Pair 1 10000) @parameter - (Some "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo") @storage ] - - location: 11 (remaining gas: 1039928.908 units remaining) - [ (Some "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo") @storage - (Pair 1 10000) @parameter ] - - location: 13 (remaining gas: 1039928.898 units remaining) - [ "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo" @storage.some - (Pair 1 10000) @parameter ] - - location: 19 (remaining gas: 1039928.888 units remaining) - [ (Pair 1 10000) @parameter - "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo" @storage.some ] - - location: 20 (remaining gas: 1039928.878 units remaining) - [ 1 - 10000 - "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo" @storage.some ] - - location: 21 (remaining gas: 1039928.463 units remaining) - [ None ] - - location: 13 (remaining gas: 1039928.448 units remaining) - [ None ] - - location: 22 (remaining gas: 1039928.433 units remaining) - [ {} - None ] - - location: 24 (remaining gas: 1039928.418 units remaining) - [ (Pair {} None) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None].out deleted file mode 100644 index 056809f94e7f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None].out +++ /dev/null @@ -1,31 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None] - -storage - None -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039989.042 units remaining) - [ (Pair (Pair 0 1) None) ] - - location: 10 (remaining gas: 1039989.032 units remaining) - [ (Pair 0 1) @parameter - None @storage ] - - location: 11 (remaining gas: 1039989.022 units remaining) - [ None @storage - (Pair 0 1) @parameter ] - - location: 13 (remaining gas: 1039989.012 units remaining) - [ (Pair 0 1) @parameter ] - - location: 15 (remaining gas: 1039989.002 units remaining) - [ ] - - location: 16 (remaining gas: 1039988.987 units remaining) - [ None ] - - location: 13 (remaining gas: 1039988.972 units remaining) - [ None ] - - location: 22 (remaining gas: 1039988.957 units remaining) - [ {} - None ] - - location: 24 (remaining gas: 1039988.942 units remaining) - [ (Pair {} None) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out deleted file mode 100644 index ace4c5ffd265..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)] - -storage - (Some 0x) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.942 units remaining) - [ (Pair (Pair 0 0) (Some 0xaabbcc)) ] - - location: 10 (remaining gas: 1039988.932 units remaining) - [ (Pair 0 0) @parameter - (Some 0xaabbcc) @storage ] - - location: 11 (remaining gas: 1039988.922 units remaining) - [ (Some 0xaabbcc) @storage - (Pair 0 0) @parameter ] - - location: 13 (remaining gas: 1039988.912 units remaining) - [ 0xaabbcc @storage.some - (Pair 0 0) @parameter ] - - location: 19 (remaining gas: 1039988.902 units remaining) - [ (Pair 0 0) @parameter - 0xaabbcc @storage.some ] - - location: 20 (remaining gas: 1039988.892 units remaining) - [ 0 - 0 - 0xaabbcc @storage.some ] - - location: 21 (remaining gas: 1039988.852 units remaining) - [ (Some 0x) ] - - location: 13 (remaining gas: 1039988.837 units remaining) - [ (Some 0x) ] - - location: 22 (remaining gas: 1039988.822 units remaining) - [ {} - (Some 0x) ] - - location: 24 (remaining gas: 1039988.807 units remaining) - [ (Pair {} (Some 0x)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out deleted file mode 100644 index 5bd41372be37..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)] - -storage - (Some 0xaa) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.942 units remaining) - [ (Pair (Pair 0 1) (Some 0xaabbcc)) ] - - location: 10 (remaining gas: 1039988.932 units remaining) - [ (Pair 0 1) @parameter - (Some 0xaabbcc) @storage ] - - location: 11 (remaining gas: 1039988.922 units remaining) - [ (Some 0xaabbcc) @storage - (Pair 0 1) @parameter ] - - location: 13 (remaining gas: 1039988.912 units remaining) - [ 0xaabbcc @storage.some - (Pair 0 1) @parameter ] - - location: 19 (remaining gas: 1039988.902 units remaining) - [ (Pair 0 1) @parameter - 0xaabbcc @storage.some ] - - location: 20 (remaining gas: 1039988.892 units remaining) - [ 0 - 1 - 0xaabbcc @storage.some ] - - location: 21 (remaining gas: 1039988.852 units remaining) - [ (Some 0xaa) ] - - location: 13 (remaining gas: 1039988.837 units remaining) - [ (Some 0xaa) ] - - location: 22 (remaining gas: 1039988.822 units remaining) - [ {} - (Some 0xaa) ] - - location: 24 (remaining gas: 1039988.807 units remaining) - [ (Pair {} (Some 0xaa)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out deleted file mode 100644 index bdc0aadfb384..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0] - -storage - (Some 0xbb) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.942 units remaining) - [ (Pair (Pair 1 1) (Some 0xaabbcc)) ] - - location: 10 (remaining gas: 1039988.932 units remaining) - [ (Pair 1 1) @parameter - (Some 0xaabbcc) @storage ] - - location: 11 (remaining gas: 1039988.922 units remaining) - [ (Some 0xaabbcc) @storage - (Pair 1 1) @parameter ] - - location: 13 (remaining gas: 1039988.912 units remaining) - [ 0xaabbcc @storage.some - (Pair 1 1) @parameter ] - - location: 19 (remaining gas: 1039988.902 units remaining) - [ (Pair 1 1) @parameter - 0xaabbcc @storage.some ] - - location: 20 (remaining gas: 1039988.892 units remaining) - [ 1 - 1 - 0xaabbcc @storage.some ] - - location: 21 (remaining gas: 1039988.852 units remaining) - [ (Some 0xbb) ] - - location: 13 (remaining gas: 1039988.837 units remaining) - [ (Some 0xbb) ] - - location: 22 (remaining gas: 1039988.822 units remaining) - [ {} - (Some 0xbb) ] - - location: 24 (remaining gas: 1039988.807 units remaining) - [ (Pair {} (Some 0xbb)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out deleted file mode 100644 index 9039624247d1..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1] - -storage - (Some 0xbb) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.942 units remaining) - [ (Pair (Pair 1 1) (Some 0xaabbcc)) ] - - location: 10 (remaining gas: 1039988.932 units remaining) - [ (Pair 1 1) @parameter - (Some 0xaabbcc) @storage ] - - location: 11 (remaining gas: 1039988.922 units remaining) - [ (Some 0xaabbcc) @storage - (Pair 1 1) @parameter ] - - location: 13 (remaining gas: 1039988.912 units remaining) - [ 0xaabbcc @storage.some - (Pair 1 1) @parameter ] - - location: 19 (remaining gas: 1039988.902 units remaining) - [ (Pair 1 1) @parameter - 0xaabbcc @storage.some ] - - location: 20 (remaining gas: 1039988.892 units remaining) - [ 1 - 1 - 0xaabbcc @storage.some ] - - location: 21 (remaining gas: 1039988.852 units remaining) - [ (Some 0xbb) ] - - location: 13 (remaining gas: 1039988.837 units remaining) - [ (Some 0xbb) ] - - location: 22 (remaining gas: 1039988.822 units remaining) - [ {} - (Some 0xbb) ] - - location: 24 (remaining gas: 1039988.807 units remaining) - [ (Pair {} (Some 0xbb)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out deleted file mode 100644 index fcc33f223012..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)] - -storage - (Some 0xbbcc) -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.942 units remaining) - [ (Pair (Pair 1 2) (Some 0xaabbcc)) ] - - location: 10 (remaining gas: 1039988.932 units remaining) - [ (Pair 1 2) @parameter - (Some 0xaabbcc) @storage ] - - location: 11 (remaining gas: 1039988.922 units remaining) - [ (Some 0xaabbcc) @storage - (Pair 1 2) @parameter ] - - location: 13 (remaining gas: 1039988.912 units remaining) - [ 0xaabbcc @storage.some - (Pair 1 2) @parameter ] - - location: 19 (remaining gas: 1039988.902 units remaining) - [ (Pair 1 2) @parameter - 0xaabbcc @storage.some ] - - location: 20 (remaining gas: 1039988.892 units remaining) - [ 1 - 2 - 0xaabbcc @storage.some ] - - location: 21 (remaining gas: 1039988.852 units remaining) - [ (Some 0xbbcc) ] - - location: 13 (remaining gas: 1039988.837 units remaining) - [ (Some 0xbbcc) ] - - location: 22 (remaining gas: 1039988.822 units remaining) - [ {} - (Some 0xbbcc) ] - - location: 24 (remaining gas: 1039988.807 units remaining) - [ (Pair {} (Some 0xbbcc)) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None].out deleted file mode 100644 index c0d8cff4a565..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None].out +++ /dev/null @@ -1,37 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None] - -storage - None -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.942 units remaining) - [ (Pair (Pair 1 3) (Some 0xaabbcc)) ] - - location: 10 (remaining gas: 1039988.932 units remaining) - [ (Pair 1 3) @parameter - (Some 0xaabbcc) @storage ] - - location: 11 (remaining gas: 1039988.922 units remaining) - [ (Some 0xaabbcc) @storage - (Pair 1 3) @parameter ] - - location: 13 (remaining gas: 1039988.912 units remaining) - [ 0xaabbcc @storage.some - (Pair 1 3) @parameter ] - - location: 19 (remaining gas: 1039988.902 units remaining) - [ (Pair 1 3) @parameter - 0xaabbcc @storage.some ] - - location: 20 (remaining gas: 1039988.892 units remaining) - [ 1 - 3 - 0xaabbcc @storage.some ] - - location: 21 (remaining gas: 1039988.852 units remaining) - [ None ] - - location: 13 (remaining gas: 1039988.837 units remaining) - [ None ] - - location: 22 (remaining gas: 1039988.822 units remaining) - [ {} - None ] - - location: 24 (remaining gas: 1039988.807 units remaining) - [ (Pair {} None) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaab.df5895de85.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaab.df5895de85.out deleted file mode 100644 index 821cf5fd08fd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaab.df5895de85.out +++ /dev/null @@ -1,38 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc-Pair 1 10000-None] - -storage - None -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.942 units remaining) - [ (Pair (Pair 1 10000) - (Some 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc)) ] - - location: 10 (remaining gas: 1039988.932 units remaining) - [ (Pair 1 10000) @parameter - (Some 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc) @storage ] - - location: 11 (remaining gas: 1039988.922 units remaining) - [ (Some 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc) @storage - (Pair 1 10000) @parameter ] - - location: 13 (remaining gas: 1039988.912 units remaining) - [ 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc @storage.some - (Pair 1 10000) @parameter ] - - location: 19 (remaining gas: 1039988.902 units remaining) - [ (Pair 1 10000) @parameter - 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc @storage.some ] - - location: 20 (remaining gas: 1039988.892 units remaining) - [ 1 - 10000 - 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc @storage.some ] - - location: 21 (remaining gas: 1039988.477 units remaining) - [ None ] - - location: 13 (remaining gas: 1039988.462 units remaining) - [ None ] - - location: 22 (remaining gas: 1039988.447 units remaining) - [ {} - None ] - - location: 24 (remaining gas: 1039988.432 units remaining) - [ (Pair {} None) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"Hello\"-(Some \"Hello\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"Hello\"-(Some \"Hello\")].out" deleted file mode 100644 index 50bfdf6aeb65..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"Hello\"-(Some \"Hello\")].out" +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[str_id.tz-None-"Hello"-(Some "Hello")] - -storage - (Some "Hello") -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.491 units remaining) - [ (Pair "Hello" None) ] - - location: 8 (remaining gas: 1039994.481 units remaining) - [ "Hello" @parameter ] - - location: 9 (remaining gas: 1039994.466 units remaining) - [ (Some "Hello") ] - - location: 10 (remaining gas: 1039994.451 units remaining) - [ {} - (Some "Hello") ] - - location: 12 (remaining gas: 1039994.436 units remaining) - [ (Pair {} (Some "Hello")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"abcd\"-(Some \"abcd\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"abcd\"-(Some \"abcd\")].out" deleted file mode 100644 index 3ea650a63a94..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"abcd\"-(Some \"abcd\")].out" +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[str_id.tz-None-"abcd"-(Some "abcd")] - -storage - (Some "abcd") -emitted operations - -big_map diff - -trace - - location: 8 (remaining gas: 1039994.501 units remaining) - [ (Pair "abcd" None) ] - - location: 8 (remaining gas: 1039994.491 units remaining) - [ "abcd" @parameter ] - - location: 9 (remaining gas: 1039994.476 units remaining) - [ (Some "abcd") ] - - location: 10 (remaining gas: 1039994.461 units remaining) - [ {} - (Some "abcd") ] - - location: 12 (remaining gas: 1039994.446 units remaining) - [ (Pair {} (Some "abcd")) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-\"1970-01-01T00:03:20Z\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-\"1970-01-01T00:03:20Z\"].out" deleted file mode 100644 index 8e27fe5702f2..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-\"1970-01-01T00:03:20Z\"].out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-"1970-01-01T00:03:20Z"] - -storage - "1970-01-01T00:03:20Z" -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039991.553 units remaining) - [ (Pair (Pair "1970-01-01T00:01:40Z" -100) "1970-01-01T00:01:51Z") ] - - location: 9 (remaining gas: 1039991.543 units remaining) - [ (Pair "1970-01-01T00:01:40Z" -100) @parameter ] - - location: 10 (remaining gas: 1039991.533 units remaining) - [ (Pair "1970-01-01T00:01:40Z" -100) @parameter - (Pair "1970-01-01T00:01:40Z" -100) @parameter ] - - location: 11 (remaining gas: 1039991.523 units remaining) - [ "1970-01-01T00:01:40Z" - (Pair "1970-01-01T00:01:40Z" -100) @parameter ] - - location: 12 (remaining gas: 1039991.508 units remaining) - [ (Pair "1970-01-01T00:01:40Z" -100) @parameter ] - - location: 14 (remaining gas: 1039991.498 units remaining) - [ -100 ] - - location: 12 (remaining gas: 1039991.468 units remaining) - [ "1970-01-01T00:01:40Z" - -100 ] - - location: 15 (remaining gas: 1039991.413 units remaining) - [ "1970-01-01T00:03:20Z" ] - - location: 16 (remaining gas: 1039991.398 units remaining) - [ {} - "1970-01-01T00:03:20Z" ] - - location: 18 (remaining gas: 1039991.383 units remaining) - [ (Pair {} "1970-01-01T00:03:20Z") ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-\"1970-01-01T00:00:00Z\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-\"1970-01-01T00:00:00Z\"].out" deleted file mode 100644 index d0073a04e534..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-\"1970-01-01T00:00:00Z\"].out" +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-"1970-01-01T00:00:00Z"] - -storage - "1970-01-01T00:00:00Z" -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039991.553 units remaining) - [ (Pair (Pair "1970-01-01T00:01:40Z" 100) "1970-01-01T00:01:51Z") ] - - location: 9 (remaining gas: 1039991.543 units remaining) - [ (Pair "1970-01-01T00:01:40Z" 100) @parameter ] - - location: 10 (remaining gas: 1039991.533 units remaining) - [ (Pair "1970-01-01T00:01:40Z" 100) @parameter - (Pair "1970-01-01T00:01:40Z" 100) @parameter ] - - location: 11 (remaining gas: 1039991.523 units remaining) - [ "1970-01-01T00:01:40Z" - (Pair "1970-01-01T00:01:40Z" 100) @parameter ] - - location: 12 (remaining gas: 1039991.508 units remaining) - [ (Pair "1970-01-01T00:01:40Z" 100) @parameter ] - - location: 14 (remaining gas: 1039991.498 units remaining) - [ 100 ] - - location: 12 (remaining gas: 1039991.468 units remaining) - [ "1970-01-01T00:01:40Z" - 100 ] - - location: 15 (remaining gas: 1039991.413 units remaining) - [ "1970-01-01T00:00:00Z" ] - - location: 16 (remaining gas: 1039991.398 units remaining) - [ {} - "1970-01-01T00:00:00Z" ] - - location: 18 (remaining gas: 1039991.383 units remaining) - [ (Pair {} "1970-01-01T00:00:00Z") ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 200000000000000000.3db82d2c25.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 200000000000000000.3db82d2c25.out deleted file mode 100644 index 948f70cdeb37..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 200000000000000000.3db82d2c25.out +++ /dev/null @@ -1,34 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 2000000000000000000)--1999999999999999900] - -storage - -1999999999999999900 -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039991.553 units remaining) - [ (Pair (Pair "1970-01-01T00:01:40Z" 2000000000000000000) "1970-01-01T00:01:51Z") ] - - location: 9 (remaining gas: 1039991.543 units remaining) - [ (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter ] - - location: 10 (remaining gas: 1039991.533 units remaining) - [ (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter - (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter ] - - location: 11 (remaining gas: 1039991.523 units remaining) - [ "1970-01-01T00:01:40Z" - (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter ] - - location: 12 (remaining gas: 1039991.508 units remaining) - [ (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter ] - - location: 14 (remaining gas: 1039991.498 units remaining) - [ 2000000000000000000 ] - - location: 12 (remaining gas: 1039991.468 units remaining) - [ "1970-01-01T00:01:40Z" - 2000000000000000000 ] - - location: 15 (remaining gas: 1039991.413 units remaining) - [ -1999999999999999900 ] - - location: 16 (remaining gas: 1039991.398 units remaining) - [ {} - -1999999999999999900 ] - - location: 18 (remaining gas: 1039991.383 units remaining) - [ (Pair {} -1999999999999999900) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair .b461aa042b.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair .b461aa042b.out deleted file mode 100644 index 13ed6d183eaf..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair .b461aa042b.out +++ /dev/null @@ -1,71 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair 3000000 1000000))] - -storage - (Some (Pair 3000000 1000000)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039980.750 units remaining) - [ (Pair (Pair 2000000 1000000) None) ] - - location: 12 (remaining gas: 1039980.740 units remaining) - [ (Pair 2000000 1000000) @parameter ] - - location: 13 (remaining gas: 1039980.730 units remaining) - [ (Pair 2000000 1000000) @parameter - (Pair 2000000 1000000) @parameter ] - - location: 14 (remaining gas: 1039980.720 units remaining) - [ (Pair 2000000 1000000) @parameter - (Pair 2000000 1000000) @parameter - (Pair 2000000 1000000) @parameter ] - - location: 15 (remaining gas: 1039980.710 units remaining) - [ 2000000 - (Pair 2000000 1000000) @parameter - (Pair 2000000 1000000) @parameter ] - - location: 16 (remaining gas: 1039980.695 units remaining) - [ (Pair 2000000 1000000) @parameter - (Pair 2000000 1000000) @parameter ] - - location: 18 (remaining gas: 1039980.685 units remaining) - [ 1000000 - (Pair 2000000 1000000) @parameter ] - - location: 16 (remaining gas: 1039980.655 units remaining) - [ 2000000 - 1000000 - (Pair 2000000 1000000) @parameter ] - - location: 19 (remaining gas: 1039980.635 units remaining) - [ 3000000 - (Pair 2000000 1000000) @parameter ] - - location: 20 (remaining gas: 1039980.620 units remaining) - [ (Pair 2000000 1000000) @parameter ] - - location: 22 (remaining gas: 1039980.610 units remaining) - [ (Pair 2000000 1000000) @parameter - (Pair 2000000 1000000) @parameter ] - - location: 23 (remaining gas: 1039980.600 units remaining) - [ 2000000 - (Pair 2000000 1000000) @parameter ] - - location: 24 (remaining gas: 1039980.585 units remaining) - [ (Pair 2000000 1000000) @parameter ] - - location: 26 (remaining gas: 1039980.575 units remaining) - [ 1000000 ] - - location: 24 (remaining gas: 1039980.545 units remaining) - [ 2000000 - 1000000 ] - - location: 27 (remaining gas: 1039980.525 units remaining) - [ (Some 1000000) ] - - location: 29 (remaining gas: 1039980.515 units remaining) - [ 1000000 @some ] - - location: 29 (remaining gas: 1039980.500 units remaining) - [ 1000000 @some ] - - location: 20 (remaining gas: 1039980.470 units remaining) - [ 3000000 - 1000000 @some ] - - location: 35 (remaining gas: 1039980.455 units remaining) - [ (Pair 3000000 1000000) ] - - location: 36 (remaining gas: 1039980.440 units remaining) - [ (Some (Pair 3000000 1000000)) ] - - location: 37 (remaining gas: 1039980.425 units remaining) - [ {} - (Some (Pair 3000000 1000000)) ] - - location: 39 (remaining gas: 1039980.410 units remaining) - [ (Pair {} (Some (Pair 3000000 1000000))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair .1e8cf7679c.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair .1e8cf7679c.out deleted file mode 100644 index e8170a8679af..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair .1e8cf7679c.out +++ /dev/null @@ -1,71 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair 3320000 1300000))] - -storage - (Some (Pair 3320000 1300000)) -emitted operations - -big_map diff - -trace - - location: 12 (remaining gas: 1039980.750 units remaining) - [ (Pair (Pair 2310000 1010000) None) ] - - location: 12 (remaining gas: 1039980.740 units remaining) - [ (Pair 2310000 1010000) @parameter ] - - location: 13 (remaining gas: 1039980.730 units remaining) - [ (Pair 2310000 1010000) @parameter - (Pair 2310000 1010000) @parameter ] - - location: 14 (remaining gas: 1039980.720 units remaining) - [ (Pair 2310000 1010000) @parameter - (Pair 2310000 1010000) @parameter - (Pair 2310000 1010000) @parameter ] - - location: 15 (remaining gas: 1039980.710 units remaining) - [ 2310000 - (Pair 2310000 1010000) @parameter - (Pair 2310000 1010000) @parameter ] - - location: 16 (remaining gas: 1039980.695 units remaining) - [ (Pair 2310000 1010000) @parameter - (Pair 2310000 1010000) @parameter ] - - location: 18 (remaining gas: 1039980.685 units remaining) - [ 1010000 - (Pair 2310000 1010000) @parameter ] - - location: 16 (remaining gas: 1039980.655 units remaining) - [ 2310000 - 1010000 - (Pair 2310000 1010000) @parameter ] - - location: 19 (remaining gas: 1039980.635 units remaining) - [ 3320000 - (Pair 2310000 1010000) @parameter ] - - location: 20 (remaining gas: 1039980.620 units remaining) - [ (Pair 2310000 1010000) @parameter ] - - location: 22 (remaining gas: 1039980.610 units remaining) - [ (Pair 2310000 1010000) @parameter - (Pair 2310000 1010000) @parameter ] - - location: 23 (remaining gas: 1039980.600 units remaining) - [ 2310000 - (Pair 2310000 1010000) @parameter ] - - location: 24 (remaining gas: 1039980.585 units remaining) - [ (Pair 2310000 1010000) @parameter ] - - location: 26 (remaining gas: 1039980.575 units remaining) - [ 1010000 ] - - location: 24 (remaining gas: 1039980.545 units remaining) - [ 2310000 - 1010000 ] - - location: 27 (remaining gas: 1039980.525 units remaining) - [ (Some 1300000) ] - - location: 29 (remaining gas: 1039980.515 units remaining) - [ 1300000 @some ] - - location: 29 (remaining gas: 1039980.500 units remaining) - [ 1300000 @some ] - - location: 20 (remaining gas: 1039980.470 units remaining) - [ 3320000 - 1300000 @some ] - - location: 35 (remaining gas: 1039980.455 units remaining) - [ (Pair 3320000 1300000) ] - - location: 36 (remaining gas: 1039980.440 units remaining) - [ (Some (Pair 3320000 1300000)) ] - - location: 37 (remaining gas: 1039980.425 units remaining) - [ {} - (Some (Pair 3320000 1300000)) ] - - location: 39 (remaining gas: 1039980.410 units remaining) - [ (Pair {} (Some (Pair 3320000 1300000))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142].out deleted file mode 100644 index 7413c60982a9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142].out +++ /dev/null @@ -1,50 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142] - -storage - 142 -emitted operations - -big_map diff - -trace - - location: 10 (remaining gas: 1039988.846 units remaining) - [ (Pair (Pair 1 4 2) 0) ] - - location: 10 (remaining gas: 1039988.836 units remaining) - [ (Pair 1 4 2) @parameter ] - - location: 11 (remaining gas: 1039988.799 units remaining) - [ 1 - 4 - 2 ] - - location: 13 (remaining gas: 1039988.789 units remaining) - [ 100 - 1 - 4 - 2 ] - - location: 16 (remaining gas: 1039988.685 units remaining) - [ 100 - 4 - 2 ] - - location: 17 (remaining gas: 1039988.675 units remaining) - [ 4 - 100 - 2 ] - - location: 18 (remaining gas: 1039988.665 units remaining) - [ 10 - 4 - 100 - 2 ] - - location: 21 (remaining gas: 1039988.561 units remaining) - [ 40 - 100 - 2 ] - - location: 22 (remaining gas: 1039988.506 units remaining) - [ 140 - 2 ] - - location: 23 (remaining gas: 1039988.451 units remaining) - [ 142 ] - - location: 24 (remaining gas: 1039988.436 units remaining) - [ {} - 142 ] - - location: 26 (remaining gas: 1039988.421 units remaining) - [ (Pair {} 142) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit].out deleted file mode 100644 index 0cee98524344..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit].out +++ /dev/null @@ -1,462 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit] - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039873.089 units remaining) - [ (Pair Unit Unit) ] - - location: 7 (remaining gas: 1039873.079 units remaining) - [ ] - - location: 8 (remaining gas: 1039873.069 units remaining) - [ Unit ] - - location: 9 (remaining gas: 1039873.059 units remaining) - [ Unit - Unit ] - - location: 10 (remaining gas: 1039873.044 units remaining) - [ (Pair Unit Unit) ] - - location: 11 (remaining gas: 1039873.034 units remaining) - [ Unit - Unit ] - - location: 12 (remaining gas: 1039872.969 units remaining) - [ ] - - location: 14 (remaining gas: 1039872.959 units remaining) - [ Unit @b ] - - location: 15 (remaining gas: 1039872.949 units remaining) - [ Unit @a - Unit @b ] - - location: 16 (remaining gas: 1039872.934 units remaining) - [ (Pair Unit Unit) ] - - location: 17 (remaining gas: 1039872.924 units remaining) - [ Unit @c - Unit @d ] - - location: 18 (remaining gas: 1039872.859 units remaining) - [ ] - - location: 20 (remaining gas: 1039872.849 units remaining) - [ Unit @b ] - - location: 21 (remaining gas: 1039872.839 units remaining) - [ Unit @a - Unit @b ] - - location: 22 (remaining gas: 1039872.824 units remaining) - [ (Pair Unit Unit) ] - - location: 23 (remaining gas: 1039872.814 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 24 (remaining gas: 1039872.804 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 25 (remaining gas: 1039872.739 units remaining) - [ (Pair Unit Unit) ] - - location: 27 (remaining gas: 1039872.729 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 28 (remaining gas: 1039872.719 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 29 (remaining gas: 1039872.654 units remaining) - [ (Pair Unit Unit) ] - - location: 31 (remaining gas: 1039872.644 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 32 (remaining gas: 1039872.634 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 33 (remaining gas: 1039872.569 units remaining) - [ (Pair Unit Unit) ] - - location: 35 (remaining gas: 1039872.559 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 36 (remaining gas: 1039872.549 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 37 (remaining gas: 1039872.484 units remaining) - [ (Pair Unit Unit) ] - - location: 39 (remaining gas: 1039872.474 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 40 (remaining gas: 1039872.464 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 41 (remaining gas: 1039872.399 units remaining) - [ (Pair Unit Unit) ] - - location: 43 (remaining gas: 1039872.389 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 44 (remaining gas: 1039872.379 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 45 (remaining gas: 1039872.314 units remaining) - [ (Pair Unit Unit) ] - - location: 47 (remaining gas: 1039872.304 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 48 (remaining gas: 1039872.294 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 49 (remaining gas: 1039872.229 units remaining) - [ (Pair Unit Unit) ] - - location: 51 (remaining gas: 1039872.219 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 52 (remaining gas: 1039872.209 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 53 (remaining gas: 1039872.144 units remaining) - [ (Pair Unit Unit) ] - - location: 55 (remaining gas: 1039872.134 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 56 (remaining gas: 1039872.124 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 57 (remaining gas: 1039872.059 units remaining) - [ (Pair Unit Unit) ] - - location: 59 (remaining gas: 1039872.049 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 60 (remaining gas: 1039872.039 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 61 (remaining gas: 1039871.974 units remaining) - [ (Pair Unit Unit) ] - - location: 63 (remaining gas: 1039871.964 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 64 (remaining gas: 1039871.954 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 65 (remaining gas: 1039871.889 units remaining) - [ (Pair Unit Unit) ] - - location: 67 (remaining gas: 1039871.879 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 68 (remaining gas: 1039871.869 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 69 (remaining gas: 1039871.804 units remaining) - [ (Pair Unit Unit) ] - - location: 71 (remaining gas: 1039871.794 units remaining) - [ ] - - location: 72 (remaining gas: 1039871.784 units remaining) - [ Unit @d ] - - location: 73 (remaining gas: 1039871.774 units remaining) - [ Unit @c - Unit @d ] - - location: 74 (remaining gas: 1039871.759 units remaining) - [ (Pair Unit Unit) ] - - location: 75 (remaining gas: 1039871.749 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 76 (remaining gas: 1039871.739 units remaining) - [ Unit @c - Unit @d - (Pair Unit Unit) ] - - location: 77 (remaining gas: 1039871.674 units remaining) - [ (Pair Unit Unit) ] - - location: 79 (remaining gas: 1039871.664 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 80 (remaining gas: 1039871.654 units remaining) - [ Unit @c - Unit @d - (Pair Unit Unit) ] - - location: 81 (remaining gas: 1039871.589 units remaining) - [ (Pair Unit Unit) ] - - location: 83 (remaining gas: 1039871.579 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 84 (remaining gas: 1039871.569 units remaining) - [ Unit @c - Unit @d - (Pair Unit Unit) ] - - location: 85 (remaining gas: 1039871.504 units remaining) - [ (Pair Unit Unit) ] - - location: 87 (remaining gas: 1039871.494 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 88 (remaining gas: 1039871.484 units remaining) - [ Unit @c - Unit @d - (Pair Unit Unit) ] - - location: 89 (remaining gas: 1039871.419 units remaining) - [ (Pair Unit Unit) ] - - location: 91 (remaining gas: 1039871.409 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 92 (remaining gas: 1039871.399 units remaining) - [ Unit @c - Unit @d - (Pair Unit Unit) ] - - location: 93 (remaining gas: 1039871.334 units remaining) - [ (Pair Unit Unit) ] - - location: 95 (remaining gas: 1039871.324 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 96 (remaining gas: 1039871.314 units remaining) - [ Unit @c - Unit @d - (Pair Unit Unit) ] - - location: 97 (remaining gas: 1039871.249 units remaining) - [ (Pair Unit Unit) ] - - location: 99 (remaining gas: 1039871.239 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 100 (remaining gas: 1039871.229 units remaining) - [ Unit @c - Unit @d - (Pair Unit Unit) ] - - location: 101 (remaining gas: 1039871.164 units remaining) - [ (Pair Unit Unit) ] - - location: 103 (remaining gas: 1039871.154 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 104 (remaining gas: 1039871.144 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 105 (remaining gas: 1039871.079 units remaining) - [ (Pair Unit Unit) ] - - location: 107 (remaining gas: 1039871.069 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 108 (remaining gas: 1039871.059 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 109 (remaining gas: 1039870.994 units remaining) - [ (Pair Unit Unit) ] - - location: 111 (remaining gas: 1039870.984 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 112 (remaining gas: 1039870.974 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 113 (remaining gas: 1039870.909 units remaining) - [ (Pair Unit Unit) ] - - location: 115 (remaining gas: 1039870.899 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 116 (remaining gas: 1039870.889 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 117 (remaining gas: 1039870.824 units remaining) - [ (Pair Unit Unit) ] - - location: 119 (remaining gas: 1039870.814 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 120 (remaining gas: 1039870.804 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 121 (remaining gas: 1039870.739 units remaining) - [ (Pair Unit Unit) ] - - location: 123 (remaining gas: 1039870.729 units remaining) - [ ] - - location: 124 (remaining gas: 1039870.719 units remaining) - [ Unit ] - - location: 125 (remaining gas: 1039870.709 units remaining) - [ Unit - Unit ] - - location: 126 (remaining gas: 1039870.694 units remaining) - [ (Pair Unit Unit) ] - - location: 127 (remaining gas: 1039870.684 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 128 (remaining gas: 1039870.674 units remaining) - [ Unit - Unit - (Pair Unit Unit) ] - - location: 129 (remaining gas: 1039870.609 units remaining) - [ (Pair Unit Unit) ] - - location: 131 (remaining gas: 1039870.599 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 132 (remaining gas: 1039870.589 units remaining) - [ Unit - Unit - (Pair Unit Unit) ] - - location: 133 (remaining gas: 1039870.524 units remaining) - [ (Pair Unit Unit) ] - - location: 135 (remaining gas: 1039870.514 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 136 (remaining gas: 1039870.504 units remaining) - [ Unit - Unit - (Pair Unit Unit) ] - - location: 137 (remaining gas: 1039870.439 units remaining) - [ (Pair Unit Unit) ] - - location: 139 (remaining gas: 1039870.429 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 140 (remaining gas: 1039870.419 units remaining) - [ Unit - Unit - (Pair Unit Unit) ] - - location: 141 (remaining gas: 1039870.354 units remaining) - [ (Pair Unit Unit) ] - - location: 143 (remaining gas: 1039870.344 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 144 (remaining gas: 1039870.334 units remaining) - [ Unit - Unit - (Pair Unit Unit) ] - - location: 145 (remaining gas: 1039870.269 units remaining) - [ (Pair Unit Unit) ] - - location: 147 (remaining gas: 1039870.259 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 148 (remaining gas: 1039870.249 units remaining) - [ Unit - Unit - (Pair Unit Unit) ] - - location: 149 (remaining gas: 1039870.184 units remaining) - [ (Pair Unit Unit) ] - - location: 151 (remaining gas: 1039870.174 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 152 (remaining gas: 1039870.164 units remaining) - [ Unit - Unit - (Pair Unit Unit) ] - - location: 153 (remaining gas: 1039870.099 units remaining) - [ (Pair Unit Unit) ] - - location: 155 (remaining gas: 1039870.089 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 156 (remaining gas: 1039870.079 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 157 (remaining gas: 1039870.014 units remaining) - [ (Pair Unit Unit) ] - - location: 159 (remaining gas: 1039870.004 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 160 (remaining gas: 1039869.994 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 161 (remaining gas: 1039869.929 units remaining) - [ (Pair Unit Unit) ] - - location: 163 (remaining gas: 1039869.919 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 164 (remaining gas: 1039869.909 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 165 (remaining gas: 1039869.844 units remaining) - [ (Pair Unit Unit) ] - - location: 167 (remaining gas: 1039869.834 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 168 (remaining gas: 1039869.824 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 169 (remaining gas: 1039869.759 units remaining) - [ (Pair Unit Unit) ] - - location: 171 (remaining gas: 1039869.749 units remaining) - [ (Pair Unit Unit) - (Pair Unit Unit) ] - - location: 172 (remaining gas: 1039869.739 units remaining) - [ Unit @a - Unit @b - (Pair Unit Unit) ] - - location: 173 (remaining gas: 1039869.674 units remaining) - [ (Pair Unit Unit) ] - - location: 175 (remaining gas: 1039869.664 units remaining) - [ ] - - location: 176 (remaining gas: 1039869.654 units remaining) - [ Unit ] - - location: 177 (remaining gas: 1039869.644 units remaining) - [ Unit - Unit ] - - location: 178 (remaining gas: 1039869.629 units remaining) - [ (Pair Unit Unit) @p ] - - location: 179 (remaining gas: 1039869.619 units remaining) - [ (Pair Unit Unit) @p - (Pair Unit Unit) @p ] - - location: 180 (remaining gas: 1039869.609 units remaining) - [ Unit @p.a - Unit @b - (Pair Unit Unit) @p ] - - location: 181 (remaining gas: 1039869.544 units remaining) - [ (Pair Unit Unit) @p ] - - location: 183 (remaining gas: 1039869.534 units remaining) - [ (Pair Unit Unit) @p - (Pair Unit Unit) @p ] - - location: 184 (remaining gas: 1039869.524 units remaining) - [ Unit @a - Unit @p.b - (Pair Unit Unit) @p ] - - location: 185 (remaining gas: 1039869.459 units remaining) - [ (Pair Unit Unit) @p ] - - location: 187 (remaining gas: 1039869.449 units remaining) - [ (Pair Unit Unit) @p - (Pair Unit Unit) @p ] - - location: 188 (remaining gas: 1039869.439 units remaining) - [ Unit @p.a - Unit @p.b - (Pair Unit Unit) @p ] - - location: 189 (remaining gas: 1039869.374 units remaining) - [ (Pair Unit Unit) @p ] - - location: 191 (remaining gas: 1039869.364 units remaining) - [ (Pair Unit Unit) @p - (Pair Unit Unit) @p ] - - location: 192 (remaining gas: 1039869.354 units remaining) - [ Unit @a - Unit @p.b - (Pair Unit Unit) @p ] - - location: 193 (remaining gas: 1039869.289 units remaining) - [ (Pair Unit Unit) @p ] - - location: 195 (remaining gas: 1039869.279 units remaining) - [ (Pair Unit Unit) @p - (Pair Unit Unit) @p ] - - location: 196 (remaining gas: 1039869.269 units remaining) - [ Unit @p.a - Unit @b - (Pair Unit Unit) @p ] - - location: 197 (remaining gas: 1039869.204 units remaining) - [ (Pair Unit Unit) @p ] - - location: 199 (remaining gas: 1039869.194 units remaining) - [ ] - - location: 200 (remaining gas: 1039869.184 units remaining) - [ Unit @b ] - - location: 201 (remaining gas: 1039869.174 units remaining) - [ Unit @a - Unit @b ] - - location: 202 (remaining gas: 1039869.159 units remaining) - [ (Pair Unit Unit) @c ] - - location: 203 (remaining gas: 1039869.149 units remaining) - [ Unit @b - Unit @a ] - - location: 204 (remaining gas: 1039869.084 units remaining) - [ ] - - location: 206 (remaining gas: 1039869.074 units remaining) - [ Unit ] - - location: 207 (remaining gas: 1039869.059 units remaining) - [ {} - Unit ] - - location: 209 (remaining gas: 1039869.044 units remaining) - [ (Pair {} Unit) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-\"edpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-\"edpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" deleted file mode 100644 index e01136ae2e98..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-\"edpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"-(Pair 666 3330)] - -storage - (Pair 666 3330) -emitted operations - -big_map diff - -trace - - location: 9 (remaining gas: 1039666.323 units remaining) - [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" 0 0) ] - - location: 9 (remaining gas: 1039666.313 units remaining) - [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @parameter ] - - location: 10 (remaining gas: 1039665.658 units remaining) - [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] - - location: 11 (remaining gas: 1039445.120 units remaining) - [ 666 ] - - location: 12 (remaining gas: 1039445.105 units remaining) - [ ] - - location: 14 (remaining gas: 1039234.727 units remaining) - [ 3330 ] - - location: 12 (remaining gas: 1039234.697 units remaining) - [ 666 - 3330 ] - - location: 15 (remaining gas: 1039234.682 units remaining) - [ (Pair 666 3330) ] - - location: 16 (remaining gas: 1039234.667 units remaining) - [ {} - (Pair 666 3330) ] - - location: 18 (remaining gas: 1039234.652 units remaining) - [ (Pair {} 666 3330) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))].out deleted file mode 100644 index b021b9670f1d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))] - -storage - (Some (Left False)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Left (Pair False False)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Left (Pair False False)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair False False) @parameter.left ] - - location: 19 (remaining gas: 1039986.729 units remaining) - [ False - False ] - - location: 20 (remaining gas: 1039986.709 units remaining) - [ False ] - - location: 21 (remaining gas: 1039986.694 units remaining) - [ (Left False) ] - - location: 17 (remaining gas: 1039986.679 units remaining) - [ (Left False) ] - - location: 28 (remaining gas: 1039986.664 units remaining) - [ (Some (Left False)) ] - - location: 29 (remaining gas: 1039986.649 units remaining) - [ {} - (Some (Left False)) ] - - location: 31 (remaining gas: 1039986.634 units remaining) - [ (Pair {} (Some (Left False))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))].out deleted file mode 100644 index 0bb69d3ad379..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))] - -storage - (Some (Left True)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Left (Pair False True)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Left (Pair False True)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair False True) @parameter.left ] - - location: 19 (remaining gas: 1039986.729 units remaining) - [ False - True ] - - location: 20 (remaining gas: 1039986.709 units remaining) - [ True ] - - location: 21 (remaining gas: 1039986.694 units remaining) - [ (Left True) ] - - location: 17 (remaining gas: 1039986.679 units remaining) - [ (Left True) ] - - location: 28 (remaining gas: 1039986.664 units remaining) - [ (Some (Left True)) ] - - location: 29 (remaining gas: 1039986.649 units remaining) - [ {} - (Some (Left True)) ] - - location: 31 (remaining gas: 1039986.634 units remaining) - [ (Pair {} (Some (Left True))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))].out deleted file mode 100644 index 110677de363e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))] - -storage - (Some (Left True)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Left (Pair True False)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Left (Pair True False)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair True False) @parameter.left ] - - location: 19 (remaining gas: 1039986.729 units remaining) - [ True - False ] - - location: 20 (remaining gas: 1039986.709 units remaining) - [ True ] - - location: 21 (remaining gas: 1039986.694 units remaining) - [ (Left True) ] - - location: 17 (remaining gas: 1039986.679 units remaining) - [ (Left True) ] - - location: 28 (remaining gas: 1039986.664 units remaining) - [ (Some (Left True)) ] - - location: 29 (remaining gas: 1039986.649 units remaining) - [ {} - (Some (Left True)) ] - - location: 31 (remaining gas: 1039986.634 units remaining) - [ (Pair {} (Some (Left True))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))].out deleted file mode 100644 index 55902d209582..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))] - -storage - (Some (Left False)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Left (Pair True True)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Left (Pair True True)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair True True) @parameter.left ] - - location: 19 (remaining gas: 1039986.729 units remaining) - [ True - True ] - - location: 20 (remaining gas: 1039986.709 units remaining) - [ False ] - - location: 21 (remaining gas: 1039986.694 units remaining) - [ (Left False) ] - - location: 17 (remaining gas: 1039986.679 units remaining) - [ (Left False) ] - - location: 28 (remaining gas: 1039986.664 units remaining) - [ (Some (Left False)) ] - - location: 29 (remaining gas: 1039986.649 units remaining) - [ {} - (Some (Left False)) ] - - location: 31 (remaining gas: 1039986.634 units remaining) - [ (Pair {} (Some (Left False))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))].out deleted file mode 100644 index c4573befc22f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))] - -storage - (Some (Right 0)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Right (Pair 0 0)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Right (Pair 0 0)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair 0 0) @parameter.right ] - - location: 24 (remaining gas: 1039986.729 units remaining) - [ 0 - 0 ] - - location: 25 (remaining gas: 1039986.674 units remaining) - [ 0 ] - - location: 26 (remaining gas: 1039986.659 units remaining) - [ (Right 0) ] - - location: 17 (remaining gas: 1039986.644 units remaining) - [ (Right 0) ] - - location: 28 (remaining gas: 1039986.629 units remaining) - [ (Some (Right 0)) ] - - location: 29 (remaining gas: 1039986.614 units remaining) - [ {} - (Some (Right 0)) ] - - location: 31 (remaining gas: 1039986.599 units remaining) - [ (Pair {} (Some (Right 0))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))].out deleted file mode 100644 index c3303fbf3b98..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))] - -storage - (Some (Right 1)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Right (Pair 0 1)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Right (Pair 0 1)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair 0 1) @parameter.right ] - - location: 24 (remaining gas: 1039986.729 units remaining) - [ 0 - 1 ] - - location: 25 (remaining gas: 1039986.674 units remaining) - [ 1 ] - - location: 26 (remaining gas: 1039986.659 units remaining) - [ (Right 1) ] - - location: 17 (remaining gas: 1039986.644 units remaining) - [ (Right 1) ] - - location: 28 (remaining gas: 1039986.629 units remaining) - [ (Some (Right 1)) ] - - location: 29 (remaining gas: 1039986.614 units remaining) - [ {} - (Some (Right 1)) ] - - location: 31 (remaining gas: 1039986.599 units remaining) - [ (Pair {} (Some (Right 1))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))].out deleted file mode 100644 index 1cfa8069aa68..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))] - -storage - (Some (Right 1)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Right (Pair 1 0)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Right (Pair 1 0)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair 1 0) @parameter.right ] - - location: 24 (remaining gas: 1039986.729 units remaining) - [ 1 - 0 ] - - location: 25 (remaining gas: 1039986.674 units remaining) - [ 1 ] - - location: 26 (remaining gas: 1039986.659 units remaining) - [ (Right 1) ] - - location: 17 (remaining gas: 1039986.644 units remaining) - [ (Right 1) ] - - location: 28 (remaining gas: 1039986.629 units remaining) - [ (Some (Right 1)) ] - - location: 29 (remaining gas: 1039986.614 units remaining) - [ {} - (Some (Right 1)) ] - - location: 31 (remaining gas: 1039986.599 units remaining) - [ (Pair {} (Some (Right 1))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))].out deleted file mode 100644 index c5aa1e891270..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))] - -storage - (Some (Right 0)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Right (Pair 1 1)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Right (Pair 1 1)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair 1 1) @parameter.right ] - - location: 24 (remaining gas: 1039986.729 units remaining) - [ 1 - 1 ] - - location: 25 (remaining gas: 1039986.674 units remaining) - [ 0 ] - - location: 26 (remaining gas: 1039986.659 units remaining) - [ (Right 0) ] - - location: 17 (remaining gas: 1039986.644 units remaining) - [ (Right 0) ] - - location: 28 (remaining gas: 1039986.629 units remaining) - [ (Some (Right 0)) ] - - location: 29 (remaining gas: 1039986.614 units remaining) - [ {} - (Some (Right 0)) ] - - location: 31 (remaining gas: 1039986.599 units remaining) - [ (Pair {} (Some (Right 0))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))].out deleted file mode 100644 index 3a5445a5efad..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))] - -storage - (Some (Right 63)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Right (Pair 42 21)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Right (Pair 42 21)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair 42 21) @parameter.right ] - - location: 24 (remaining gas: 1039986.729 units remaining) - [ 42 - 21 ] - - location: 25 (remaining gas: 1039986.674 units remaining) - [ 63 ] - - location: 26 (remaining gas: 1039986.659 units remaining) - [ (Right 63) ] - - location: 17 (remaining gas: 1039986.644 units remaining) - [ (Right 63) ] - - location: 28 (remaining gas: 1039986.629 units remaining) - [ (Some (Right 63)) ] - - location: 29 (remaining gas: 1039986.614 units remaining) - [ {} - (Some (Right 63)) ] - - location: 31 (remaining gas: 1039986.599 units remaining) - [ (Pair {} (Some (Right 63))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))].out deleted file mode 100644 index cf13144f4774..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))].out +++ /dev/null @@ -1,32 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))] - -storage - (Some (Right 21)) -emitted operations - -big_map diff - -trace - - location: 16 (remaining gas: 1039986.759 units remaining) - [ (Pair (Right (Pair 42 63)) None) ] - - location: 16 (remaining gas: 1039986.749 units remaining) - [ (Right (Pair 42 63)) @parameter ] - - location: 17 (remaining gas: 1039986.739 units remaining) - [ (Pair 42 63) @parameter.right ] - - location: 24 (remaining gas: 1039986.729 units remaining) - [ 42 - 63 ] - - location: 25 (remaining gas: 1039986.674 units remaining) - [ 21 ] - - location: 26 (remaining gas: 1039986.659 units remaining) - [ (Right 21) ] - - location: 17 (remaining gas: 1039986.644 units remaining) - [ (Right 21) ] - - location: 28 (remaining gas: 1039986.629 units remaining) - [ (Some (Right 21)) ] - - location: 29 (remaining gas: 1039986.614 units remaining) - [ {} - (Some (Right 21)) ] - - location: 31 (remaining gas: 1039986.599 units remaining) - [ (Pair {} (Some (Right 21))) ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_hash_consistency_michelson_cli.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_hash_consistency_michelson_cli.out deleted file mode 100644 index 0380b3fc5ffb..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_hash_consistency_michelson_cli.out +++ /dev/null @@ -1,23 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_hash_consistency_michelson_cli - -Raw packed data: 0x0507070080acd2c6a501070700bcc485a30b0022 -Script-expression-ID-Hash: expruenXhGp5JQoHJTGv4DzBR8Zm3HGvea8Q8BaMPywsY2bxrHAEgC -Raw Script-expression-ID-Hash: 0x95a69fcbbf773989333dc9b31e246575812dbea19d25089f83a2aeeea16ab4bc -Ledger Blake2b hash: B5B7PuGGVUrdHUW9Df8wPNJQRuUmx56aH1XVpvbUZvW7 -Raw Sha256 hash: 0x538634a0f81b55f1c946c1207a25c262479566d20bd3d5cd2cdbb2940fc45774 -Raw Sha512 hash: 0x49d5c19c2da4ee74f85225c95625a4b77b94724f4285b436b9d4be27d40491354bdc8e9d8a3d9b2857e5fb59b172605edd02fc4b61ce3cd3f84aa11ed1731ff6 -Gas remaining: 1039997.927 units remaining -storage - 0x95a69fcbbf773989333dc9b31e246575812dbea19d25089f83a2aeeea16ab4bc -emitted operations - -big_map diff - - -storage - 0x95a69fcbbf773989333dc9b31e246575812dbea19d25089f83a2aeeea16ab4bc -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_level.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_level.out deleted file mode 100644 index 5852d1c8ff5a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_level.out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_level - -storage - 10 -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.948 units remaining) - [ (Pair Unit 9999999) ] - - location: 7 (remaining gas: 1039994.938 units remaining) - [ ] - - location: 8 (remaining gas: 1039994.923 units remaining) - [ 10 @level ] - - location: 9 (remaining gas: 1039994.908 units remaining) - [ {} - 10 @level ] - - location: 11 (remaining gas: 1039994.893 units remaining) - [ (Pair {} 10) ] - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" deleted file mode 100644 index e4f96e31b1b6..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt "bar" 5 ; Elt "foo" 1 } 6)-15-(Pair { Elt "bar" 20 ; Elt "foo" 16 } 36)] - -storage - (Pair { Elt "bar" 20 ; Elt "foo" 16 } 36) -emitted operations - -big_map diff - - diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" deleted file mode 100644 index 928c8032a426..000000000000 --- "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt "foo" 1 } 1)-10-(Pair { Elt "foo" 11 } 11)] - -storage - (Pair { Elt "foo" 11 } 11) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out deleted file mode 100644 index 511bc3654a14..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out +++ /dev/null @@ -1,9 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)] - -storage - (Pair {} 0) -emitted operations - -big_map diff - - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_now.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_now.out deleted file mode 100644 index c554477d2bb7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_now.out +++ /dev/null @@ -1,21 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_now - -storage - "2021-10-13T10:16:52Z" -emitted operations - -big_map diff - -trace - - location: 7 (remaining gas: 1039994.848 units remaining) - [ (Pair Unit "2017-07-13T09:19:01Z") ] - - location: 7 (remaining gas: 1039994.838 units remaining) - [ ] - - location: 8 (remaining gas: 1039994.823 units remaining) - [ "2021-10-13T10:16:52Z" @now ] - - location: 9 (remaining gas: 1039994.808 units remaining) - [ {} - "2021-10-13T10:16:52Z" @now ] - - location: 11 (remaining gas: 1039994.793 units remaining) - [ (Pair {} "2021-10-13T10:16:52Z") ] - diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_packunpack.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_packunpack.out deleted file mode 100644 index 4d8f7a7aee15..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_packunpack.out +++ /dev/null @@ -1,106 +0,0 @@ -tests_012/test_contract_opcodes.py::TestContractOpcodes::test_packunpack - -storage - Unit -emitted operations - -big_map diff - -trace - - location: 15 (remaining gas: 1039977.531 units remaining) - [ (Pair (Pair (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003) - Unit) ] - - location: 15 (remaining gas: 1039977.521 units remaining) - [ (Pair (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003) @parameter ] - - location: 16 (remaining gas: 1039977.511 units remaining) - [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] - - location: 17 (remaining gas: 1039977.496 units remaining) - [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] - - location: 19 (remaining gas: 1039977.486 units remaining) - [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] - - location: 17 (remaining gas: 1039977.456 units remaining) - [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] - - location: 20 (remaining gas: 1039975.016 units remaining) - [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 @packed - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] - - location: 23 (remaining gas: 1039974.981 units remaining) - [ 0 - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] - - location: 24 (remaining gas: 1039974.966 units remaining) - [ True - 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] - - location: 25 (remaining gas: 1039974.956 units remaining) - [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] - - location: 25 (remaining gas: 1039974.941 units remaining) - [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] - - location: 31 (remaining gas: 1039971.783 units remaining) - [ (Some (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 })) @unpacked ] - - location: 40 (remaining gas: 1039971.773 units remaining) - [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) @unpacked.some ] - - location: 40 (remaining gas: 1039971.758 units remaining) - [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) @unpacked.some ] - - location: 46 (remaining gas: 1039971.748 units remaining) - [ ] - - location: 47 (remaining gas: 1039971.738 units remaining) - [ Unit ] - - location: 48 (remaining gas: 1039971.723 units remaining) - [ {} - Unit ] - - location: 50 (remaining gas: 1039971.708 units remaining) - [ (Pair {} Unit) ] - -Runtime error in contract [CONTRACT_HASH]: - 1: parameter (pair (pair (pair string (list int)) (set nat)) bytes) ; - 2: storage unit ; - 3: code { CAR ; UNPAIR ; DIP { DUP } ; - 4: PACK ; ASSERT_CMPEQ ; - 5: UNPACK (pair (pair string (list int)) (set nat)) ; ASSERT_SOME ; DROP ; - 6: UNIT ; NIL operation ; PAIR } - 7: -At line 4 characters 14 to 26, -script reached FAILWITH instruction -with Unit -trace - - location: 15 (remaining gas: 1039977.531 units remaining) - [ (Pair (Pair (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004) - Unit) ] - - location: 15 (remaining gas: 1039977.521 units remaining) - [ (Pair (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004) @parameter ] - - location: 16 (remaining gas: 1039977.511 units remaining) - [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] - - location: 17 (remaining gas: 1039977.496 units remaining) - [ 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] - - location: 19 (remaining gas: 1039977.486 units remaining) - [ 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] - - location: 17 (remaining gas: 1039977.456 units remaining) - [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] - - location: 20 (remaining gas: 1039975.016 units remaining) - [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 @packed - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] - - location: 23 (remaining gas: 1039974.981 units remaining) - [ -1 - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] - - location: 24 (remaining gas: 1039974.966 units remaining) - [ False - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] - - location: 25 (remaining gas: 1039974.956 units remaining) - [ 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] - - location: 29 (remaining gas: 1039974.946 units remaining) - [ Unit - 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] -Fatal error: - error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_add_liquidity.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_add_liquidity.out deleted file mode 100644 index 2cb76616e71e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_add_liquidity.out +++ /dev/null @@ -1,83 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_add_liquidity - -Node is bootstrapped. -Estimated gas: 11854.210 units (will add 100 for safety) -Estimated storage: 141 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.001551 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 11955 - Storage limit: 161 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.001551 - payload fees(the block proposer) ....... +ꜩ0.001551 - Transaction: - Amount: ꜩ9001 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: addLiquidity - Parameter: (Pair "[CONTRACT_HASH]" 0 1000000000 "[TIMESTAMP]") - This transaction was successfully applied - Updated storage: - { 722 ; - 9013500100 ; - 72107 ; - 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; - 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } - Storage size: 4633 bytes - Paid storage size diff: 3 bytes - Consumed gas: 2911.771 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00075 - storage fees ........................... +ꜩ0.00075 - [CONTRACT_HASH] ... -ꜩ9001 - [CONTRACT_HASH] ... +ꜩ9001 - Internal operations: - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: transfer - Parameter: (Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 - (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 721)) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(1)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 - 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 999999279 - Set map(0)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 99999279 - Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 721 - Storage size: 2263 bytes - Paid storage size diff: 68 bytes - Consumed gas: 4394.451 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.017 - storage fees ........................... +ꜩ0.017 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: mintOrBurn - Parameter: (Pair 72007 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78) - This transaction was successfully applied - Updated storage: - { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 72107 } - Updated big_maps: - Set map(2)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 72007 - Storage size: 2048 bytes - Paid storage size diff: 70 bytes - Consumed gas: 4547.988 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0175 - storage fees ........................... +ꜩ0.0175 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approval.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approval.out deleted file mode 100644 index 2c343c6c373a..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approval.out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_approval - -Node is bootstrapped. -Estimated gas: 2375.388 units (will add 100 for safety) -Estimated storage: 68 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000555 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2476 - Storage limit: 88 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000555 - payload fees(the block proposer) ....... +ꜩ0.000555 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: approve - Parameter: (Pair "[CONTRACT_HASH]" 1000) - This transaction was successfully applied - Updated storage: - { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 72107 } - Updated big_maps: - Set map(3)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 - 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c)] to 1000 - Storage size: 2116 bytes - Paid storage size diff: 68 bytes - Consumed gas: 2375.388 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.017 - storage fees ........................... +ꜩ0.017 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approved_transfer.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approved_transfer.out deleted file mode 100644 index b2c07dc7373e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approved_transfer.out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_approved_transfer - -Node is bootstrapped. -Estimated gas: 4366.195 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000804 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 4467 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000804 - payload fees(the block proposer) ....... +ꜩ0.000804 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: transfer - Parameter: (Pair "[CONTRACT_HASH]" - "[CONTRACT_HASH]" - 1000) - This transaction was successfully applied - Updated storage: - { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 72107 } - Updated big_maps: - Unset map(3)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 - 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c)] - Set map(2)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 71007 - Set map(2)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] to 1000 - Storage size: 2116 bytes - Consumed gas: 4366.195 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve1.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve1.out deleted file mode 100644 index 08d8d166d54d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve1.out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_call_approve1 - -Node is bootstrapped. -Estimated gas: 2375.464 units (will add 100 for safety) -Estimated storage: 71 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000558 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2476 - Storage limit: 91 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000558 - payload fees(the block proposer) ....... +ꜩ0.000558 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: approve - Parameter: (Pair "[CONTRACT_HASH]" 1000000000) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(1)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 - 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 - Storage size: 2053 bytes - Paid storage size diff: 71 bytes - Consumed gas: 2375.464 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01775 - storage fees ........................... +ꜩ0.01775 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve2.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve2.out deleted file mode 100644 index 4a76141eb2cd..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve2.out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_call_approve2 - -Node is bootstrapped. -Estimated gas: 2375.464 units (will add 100 for safety) -Estimated storage: 71 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000558 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2476 - Storage limit: 91 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000558 - payload fees(the block proposer) ....... +ꜩ0.000558 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: approve - Parameter: (Pair "[CONTRACT_HASH]" 1000000000) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(1)[(Pair 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c - 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 - Storage size: 2124 bytes - Paid storage size diff: 71 bytes - Consumed gas: 2375.464 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01775 - storage fees ........................... +ꜩ0.01775 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve3.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve3.out deleted file mode 100644 index ccd2b7c7a352..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve3.out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_call_approve3 - -Node is bootstrapped. -Estimated gas: 2375.464 units (will add 100 for safety) -Estimated storage: 71 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000558 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2476 - Storage limit: 91 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000558 - payload fees(the block proposer) ....... +ꜩ0.000558 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: approve - Parameter: (Pair "[CONTRACT_HASH]" 1000000000) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(1)[(Pair 0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6 - 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 - Storage size: 2195 bytes - Paid storage size diff: 71 bytes - Consumed gas: 2375.464 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01775 - storage fees ........................... +ꜩ0.01775 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_mint_or_burn.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_mint_or_burn.out deleted file mode 100644 index a196ce78b0de..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_mint_or_burn.out +++ /dev/null @@ -1,40 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_call_mint_or_burn - -Node is bootstrapped. -Estimated gas: 4548.314 units (will add 100 for safety) -Estimated storage: 71 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000777 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 4649 - Storage limit: 91 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000777 - payload fees(the block proposer) ....... +ꜩ0.000777 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: mintOrBurn - Parameter: (Pair 100000000 "[CONTRACT_HASH]") - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(0)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 100000000 - Storage size: 1982 bytes - Paid storage size diff: 71 bytes - Consumed gas: 4548.941 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01775 - storage fees ........................... +ꜩ0.01775 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_dex_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_dex_storage.out deleted file mode 100644 index 35934a19c03f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_dex_storage.out +++ /dev/null @@ -1,7 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_dex_storage - -Pair 712 - 8895894353 - 71107 - "[CONTRACT_HASH]" - "[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_lqt_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_lqt_storage.out deleted file mode 100644 index 7b4f11764452..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_lqt_storage.out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_lqt_storage - -Pair 2 3 "[CONTRACT_HASH]" 71107 diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out deleted file mode 100644 index 353910347f1d..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out +++ /dev/null @@ -1,80 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_remove_liquidity - -Node is bootstrapped. -Estimated gas: 10533.836 units (will add 100 for safety) -Estimated storage: 67 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.001416 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 10634 - Storage limit: 87 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.001416 - payload fees(the block proposer) ....... +ꜩ0.001416 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: removeLiquidity - Parameter: (Pair "[CONTRACT_HASH]" 1000 0 0 "[TIMESTAMP]") - This transaction was successfully applied - Updated storage: - { 712 ; - 8895894353 ; - 71107 ; - 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; - 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } - Storage size: 4633 bytes - Consumed gas: 2913.981 - Internal operations: - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: mintOrBurn - Parameter: (Pair -1000 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c) - This transaction was successfully applied - Updated storage: - { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 71107 } - Updated big_maps: - Unset map(2)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] - Storage size: 2048 bytes - Consumed gas: 2522.649 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: transfer - Parameter: (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 - (Pair 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c 10)) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 711 - Set map(0)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] to 10 - Storage size: 2330 bytes - Paid storage size diff: 67 bytes - Consumed gas: 3677.206 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01675 - storage fees ........................... +ꜩ0.01675 - Transaction: - Amount: ꜩ125.105747 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Consumed gas: 1420 - Balance updates: - [CONTRACT_HASH] ... -ꜩ125.105747 - [CONTRACT_HASH] ... +ꜩ125.105747 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_setup.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_setup.out deleted file mode 100644 index d0f34ec3c344..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_setup.out +++ /dev/null @@ -1,8 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_setup - -"[CONTRACT_HASH]" -Pair 1 - 100 - 100 - "[CONTRACT_HASH]" - "[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_tok_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_tok_storage.out deleted file mode 100644 index a537d1ec8a1e..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_tok_storage.out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_tok_storage - -Pair 0 1 "[CONTRACT_HASH]" 100010000 diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_add_liquidity.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_add_liquidity.out deleted file mode 100644 index a3eb3f301791..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_add_liquidity.out +++ /dev/null @@ -1,83 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_add_liquidity - -Node is bootstrapped. -Estimated gas: 11854.210 units (will add 100 for safety) -Estimated storage: 141 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.001551 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 11955 - Storage limit: 161 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.001551 - payload fees(the block proposer) ....... +ꜩ0.001551 - Transaction: - Amount: ꜩ9001 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: addLiquidity - Parameter: (Pair "[CONTRACT_HASH]" 0 1000000000 "[TIMESTAMP]") - This transaction was successfully applied - Updated storage: - { 722 ; - 9013500100 ; - 72107 ; - 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; - 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } - Storage size: 4633 bytes - Paid storage size diff: 3 bytes - Consumed gas: 2911.771 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00075 - storage fees ........................... +ꜩ0.00075 - [CONTRACT_HASH] ... -ꜩ9001 - [CONTRACT_HASH] ... +ꜩ9001 - Internal operations: - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: transfer - Parameter: (Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 - (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 721)) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(1)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 - 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 999999279 - Set map(0)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 99999279 - Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 721 - Storage size: 2263 bytes - Paid storage size diff: 68 bytes - Consumed gas: 4394.451 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.017 - storage fees ........................... +ꜩ0.017 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: mintOrBurn - Parameter: (Pair 72007 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78) - This transaction was successfully applied - Updated storage: - { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 72107 } - Updated big_maps: - Set map(2)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 72007 - Storage size: 2048 bytes - Paid storage size diff: 70 bytes - Consumed gas: 4547.988 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.0175 - storage fees ........................... +ꜩ0.0175 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out deleted file mode 100644 index b523ea381261..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out +++ /dev/null @@ -1,75 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_buy_tok - -Node is bootstrapped. -Estimated gas: 7499.668 units (will add 100 for safety) -Estimated storage: 326 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.001107 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 7600 - Storage limit: 346 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.001107 - payload fees(the block proposer) ....... +ꜩ0.001107 - Transaction: - Amount: ꜩ9001 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: xtzToToken - Parameter: (Pair "[CONTRACT_HASH]" 0 "[TIMESTAMP]") - This transaction was successfully applied - Updated storage: - { 362 ; - 18007999100 ; - 72107 ; - 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; - 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } - Storage size: 4634 bytes - Paid storage size diff: 1 bytes - Consumed gas: 2402.458 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00025 - storage fees ........................... +ꜩ0.00025 - [CONTRACT_HASH] ... -ꜩ9001 - [CONTRACT_HASH] ... +ꜩ9001 - Internal operations: - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: transfer - Parameter: (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 - (Pair 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c 360)) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 361 - Set map(0)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] to 360 - Storage size: 2331 bytes - Paid storage size diff: 68 bytes - Consumed gas: 3677.210 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.017 - storage fees ........................... +ꜩ0.017 - Transaction: - Amount: ꜩ9.001 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Consumed gas: 1420 - Balance updates: - [CONTRACT_HASH] ... -ꜩ9.001 - [CONTRACT_HASH] ... +ꜩ9.001 - [CONTRACT_HASH] ... -ꜩ0.06425 - storage fees ........................... +ꜩ0.06425 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve1.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve1.out deleted file mode 100644 index 1435a7ad409c..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve1.out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_call_approve1 - -Node is bootstrapped. -Estimated gas: 2375.464 units (will add 100 for safety) -Estimated storage: 71 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000558 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2476 - Storage limit: 91 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000558 - payload fees(the block proposer) ....... +ꜩ0.000558 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: approve - Parameter: (Pair "[CONTRACT_HASH]" 1000000000) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(1)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 - 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 - Storage size: 2053 bytes - Paid storage size diff: 71 bytes - Consumed gas: 2375.464 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01775 - storage fees ........................... +ꜩ0.01775 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve2.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve2.out deleted file mode 100644 index 7ef25cb3dec9..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve2.out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_call_approve2 - -Node is bootstrapped. -Estimated gas: 2375.464 units (will add 100 for safety) -Estimated storage: 71 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000558 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2476 - Storage limit: 91 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000558 - payload fees(the block proposer) ....... +ꜩ0.000558 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: approve - Parameter: (Pair "[CONTRACT_HASH]" 1000000000) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(1)[(Pair 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c - 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 - Storage size: 2124 bytes - Paid storage size diff: 71 bytes - Consumed gas: 2375.464 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01775 - storage fees ........................... +ꜩ0.01775 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve3.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve3.out deleted file mode 100644 index b0be0ba16311..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve3.out +++ /dev/null @@ -1,41 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_call_approve3 - -Node is bootstrapped. -Estimated gas: 2375.464 units (will add 100 for safety) -Estimated storage: 71 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000558 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 2476 - Storage limit: 91 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000558 - payload fees(the block proposer) ....... +ꜩ0.000558 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: approve - Parameter: (Pair "[CONTRACT_HASH]" 1000000000) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(1)[(Pair 0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6 - 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 - Storage size: 2195 bytes - Paid storage size diff: 71 bytes - Consumed gas: 2375.464 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01775 - storage fees ........................... +ꜩ0.01775 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_mint_or_burn.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_mint_or_burn.out deleted file mode 100644 index ee84d8a5c15b..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_mint_or_burn.out +++ /dev/null @@ -1,40 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_call_mint_or_burn - -Node is bootstrapped. -Estimated gas: 4548.314 units (will add 100 for safety) -Estimated storage: 71 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000777 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 4649 - Storage limit: 91 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000777 - payload fees(the block proposer) ....... +ꜩ0.000777 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: mintOrBurn - Parameter: (Pair 100000000 "[CONTRACT_HASH]") - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(0)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 100000000 - Storage size: 1982 bytes - Paid storage size diff: 71 bytes - Consumed gas: 4548.941 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.01775 - storage fees ........................... +ꜩ0.01775 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_dex_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_dex_storage.out deleted file mode 100644 index 36ab02138639..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_dex_storage.out +++ /dev/null @@ -1,7 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_dex_storage - -Pair 462 - 14117137204 - 72107 - "[CONTRACT_HASH]" - "[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_lqt_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_lqt_storage.out deleted file mode 100644 index 44e4dc9acdd8..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_lqt_storage.out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_lqt_storage - -Pair 2 3 "[CONTRACT_HASH]" 72107 diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out deleted file mode 100644 index b9dfed6faf07..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out +++ /dev/null @@ -1,74 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_sell_tok - -Node is bootstrapped. -Estimated gas: 9818.099 units (will add 100 for safety) -Estimated storage: no bytes added -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.001337 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 9919 - Storage limit: 0 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.001337 - payload fees(the block proposer) ....... +ꜩ0.001337 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: tokenToXtz - Parameter: (Pair "[CONTRACT_HASH]" 100 0 "[TIMESTAMP]") - This transaction was successfully applied - Updated storage: - { 462 ; - 14117137204 ; - 72107 ; - 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; - 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } - Storage size: 4633 bytes - Consumed gas: 2403.612 - Internal operations: - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: transfer - Parameter: (Pair 0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6 - (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 100)) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(1)[(Pair 0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6 - 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 999999900 - Unset map(0)[0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6] - Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 461 - Storage size: 2331 bytes - Consumed gas: 4574.487 - Transaction: - Amount: ꜩ3891.966034 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Consumed gas: 1420 - Balance updates: - [CONTRACT_HASH] ... -ꜩ3891.966034 - [CONTRACT_HASH] ... +ꜩ3891.966034 - Transaction: - Amount: ꜩ3.895862 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - This transaction was successfully applied - Consumed gas: 1420 - Balance updates: - [CONTRACT_HASH] ... -ꜩ3.895862 - [CONTRACT_HASH] ... +ꜩ3.895862 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_setup.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_setup.out deleted file mode 100644 index c2d918b666cc..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_setup.out +++ /dev/null @@ -1,8 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_setup - -"[CONTRACT_HASH]" -Pair 1 - 100 - 100 - "[CONTRACT_HASH]" - "[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_tok_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_tok_storage.out deleted file mode 100644 index 5251c4db61c7..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_tok_storage.out +++ /dev/null @@ -1,3 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_tok_storage - -Pair 0 1 "[CONTRACT_HASH]" 100010000 diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_transfer.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_transfer.out deleted file mode 100644 index cba1b68b4f4f..000000000000 --- a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_transfer.out +++ /dev/null @@ -1,43 +0,0 @@ -tests_012/test_liquidity_baking.py::TestTrades::test_transfer - -Node is bootstrapped. -Estimated gas: 3679.110 units (will add 100 for safety) -Estimated storage: 68 bytes added (will add 20 for safety) -Operation successfully injected in the node. -Operation hash is '[BLOCK_HASH]' -NOT waiting for the operation to be included. -Use command - tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] -and/or an external block explorer to make sure that it has been included. -This sequence of operations was run: - Manager signed operations: - From: [CONTRACT_HASH] - Fee to the baker: ꜩ0.000735 - Expected counter: [EXPECTED_COUNTER] - Gas limit: 3780 - Storage limit: 88 bytes - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000735 - payload fees(the block proposer) ....... +ꜩ0.000735 - Transaction: - Amount: ꜩ0 - From: [CONTRACT_HASH] - To: [CONTRACT_HASH] - Entrypoint: transfer - Parameter: (Pair "[CONTRACT_HASH]" - "[CONTRACT_HASH]" - 100) - This transaction was successfully applied - Updated storage: - { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } - Updated big_maps: - Set map(0)[0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6] to 100 - Set map(0)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] to 260 - Storage size: 2399 bytes - Paid storage size diff: 68 bytes - Consumed gas: 3679.110 - Balance updates: - [CONTRACT_HASH] ... -ꜩ0.017 - storage fees ........................... +ꜩ0.017 - -Injected block at minimal timestamp diff --git a/tests_python/tests_012/conftest.py b/tests_python/tests_012/conftest.py deleted file mode 100644 index 354e05df60fb..000000000000 --- a/tests_python/tests_012/conftest.py +++ /dev/null @@ -1,121 +0,0 @@ -"""Protocol-specific hooks and fixtures""" - -import tempfile -from typing import Optional, Iterator, List -import pytest -from launchers.sandbox import Sandbox -from tools import constants, utils -from tools.client_regression import ClientRegression -from client.client import Client -from client.client_output import CreateMockupResult - -from . import protocol - - -@pytest.fixture(scope="class") -def client(sandbox: Sandbox) -> Iterator[Client]: - """One node with protocol 012. - - Activate protocol 012 one year in the past. This avoids waiting - when baking blocks manually from the client using `bake for` - """ - sandbox.add_node(0, params=constants.NODE_PARAMS) - client = sandbox.client(0) - parameters = protocol.get_parameters() - parameters['consensus_threshold'] = 0 - protocol.activate(client, parameters=parameters, activate_in_the_past=True) - yield client - - -@pytest.fixture(scope="class") -def client_regtest_bis(sandbox: Sandbox) -> Iterator[Client]: - """One node with protocol 012, regression test enabled. - - Activate protocol 012 one year in the past. (see fixture client). - """ - - def reg_client_factory( - client_path: str, - admin_client_path: str, - host: Optional[str] = None, - base_dir: Optional[str] = None, - rpc_port: Optional[int] = None, - use_tls: Optional[bool] = None, - endpoint: Optional[str] = 'http://127.0.0.1:8732', - mode: str = None, - disable_disclaimer: bool = True, - ) -> ClientRegression: - client = ClientRegression( - client_path=client_path, - admin_client_path=admin_client_path, - host=host, - base_dir=base_dir, - rpc_port=rpc_port, - use_tls=use_tls, - endpoint=endpoint, - mode=mode, - disable_disclaimer=disable_disclaimer, - ) - return client - - sandbox.add_node( - 1, client_factory=reg_client_factory, params=constants.NODE_PARAMS - ) - client = sandbox.client(1) - parameters = protocol.get_parameters() - parameters['consensus_threshold'] = 0 - protocol.activate(client, activate_in_the_past=True, parameters=parameters) - yield client - - -@pytest.fixture(scope="class") -def clients(sandbox: Sandbox, request) -> Iterator[List[Client]]: - """N node with protocol 012. Parameterized by the number of nodes. - - Number of nodes is specified as a class annotation. - @pytest.mark.parametrize('clients', [N], indirect=True) - - Activate protocol 012 one year in the past. (see fixture client). - """ - assert request.param is not None - num_nodes = request.param - for i in range(num_nodes): - # Large number may increases peers connection time - sandbox.add_node(i, params=constants.NODE_PARAMS) - parameters = protocol.get_parameters() - parameters['consensus_threshold'] = 0 - parameters['minimal_block_delay'] = '1' - parameters['delay_increment_per_round'] = '1' - protocol.activate( - sandbox.client(0), parameters=parameters, activate_in_the_past=True - ) - - clients = sandbox.all_clients() - for client in clients: - proto = protocol.HASH - assert utils.check_protocol(client, proto) - yield clients - - -@pytest.fixture -def mockup_client(sandbox: Sandbox) -> Iterator[Client]: - """ - Returns a mockup client with its persistent directory created - - This is done in two steps, because we want to create the mockup - with a client that doesn't have "--mode mockup" (as per - the public documentation) but we want to return a - client that has "--mode mockup" and uses the base-dir created - in the first step. - - There is no way around this pattern. If you want to create - a mockup using custom arguments; you MUST do the same - as this method. - """ - with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: - unmanaged_client = sandbox.create_client(base_dir=base_dir) - res = unmanaged_client.create_mockup( - protocol=protocol.HASH - ).create_mockup_result - assert res == CreateMockupResult.OK - yield sandbox.create_client(base_dir=base_dir, mode="mockup") diff --git a/tests_python/tests_012/contract_paths.py b/tests_python/tests_012/contract_paths.py deleted file mode 100644 index 351ddf8caa24..000000000000 --- a/tests_python/tests_012/contract_paths.py +++ /dev/null @@ -1,20 +0,0 @@ -from os import path -from typing import List -from tools import paths - - -def all_contracts(directories: List[str] = None) -> List[str]: - return paths.all_contracts(CONTRACT_PATH, directories) - - -def all_legacy_contracts() -> List[str]: - return all_contracts(['legacy']) - - -CONTRACT_PATH = path.join(paths.TEZOS_HOME, 'tests_python', 'contracts_012') -ATTIC_CONTRACT_PATH = path.join(CONTRACT_PATH, 'attic') -MACROS_CONTRACT_PATH = path.join(CONTRACT_PATH, 'macros') -ILLTYPED_CONTRACT_PATH = path.join(CONTRACT_PATH, 'ill_typed') -LEGACY_CONTRACT_PATH = path.join(CONTRACT_PATH, 'legacy') -OPCODES_CONTRACT_PATH = path.join(CONTRACT_PATH, 'opcodes') -MINI_SCENARIOS_CONTRACT_PATH = path.join(CONTRACT_PATH, 'mini_scenarios') diff --git a/tests_python/tests_012/per_block_vote_files/false.json b/tests_python/tests_012/per_block_vote_files/false.json deleted file mode 100644 index af74e026a98a..000000000000 --- a/tests_python/tests_012/per_block_vote_files/false.json +++ /dev/null @@ -1 +0,0 @@ -{"liquidity_baking_escape_vote": false} diff --git a/tests_python/tests_012/per_block_vote_files/invalid.json b/tests_python/tests_012/per_block_vote_files/invalid.json deleted file mode 100644 index 200b380f75f3..000000000000 --- a/tests_python/tests_012/per_block_vote_files/invalid.json +++ /dev/null @@ -1 +0,0 @@ -{"liquidity_baking_escape_vote": true diff --git a/tests_python/tests_012/per_block_vote_files/non_boolean.json b/tests_python/tests_012/per_block_vote_files/non_boolean.json deleted file mode 100644 index a5de5f628964..000000000000 --- a/tests_python/tests_012/per_block_vote_files/non_boolean.json +++ /dev/null @@ -1 +0,0 @@ -{"liquidity_baking_escape_vote": "true"} diff --git a/tests_python/tests_012/per_block_vote_files/true.json b/tests_python/tests_012/per_block_vote_files/true.json deleted file mode 100644 index cc092c95ad99..000000000000 --- a/tests_python/tests_012/per_block_vote_files/true.json +++ /dev/null @@ -1 +0,0 @@ -{"liquidity_baking_escape_vote": true} diff --git a/tests_python/tests_012/per_block_vote_files/wrong_key.json b/tests_python/tests_012/per_block_vote_files/wrong_key.json deleted file mode 100644 index 37863375f220..000000000000 --- a/tests_python/tests_012/per_block_vote_files/wrong_key.json +++ /dev/null @@ -1 +0,0 @@ -{"liquidity_baking_escape": true } diff --git a/tests_python/tests_012/protocol.py b/tests_python/tests_012/protocol.py deleted file mode 100644 index 138aaec40312..000000000000 --- a/tests_python/tests_012/protocol.py +++ /dev/null @@ -1,69 +0,0 @@ -import datetime -from enum import Enum, auto -from typing import Optional -from copy import deepcopy -from tools import constants, utils - -HASH = constants.ITHACA -DAEMON = constants.ITHACA_DAEMON -PARAMETERS = constants.ITHACA_PARAMETERS - -TENDERBAKE_PARAMETERS = deepcopy(PARAMETERS) -TENDERBAKE_PARAMETERS['consensus_threshold'] = 45 -TENDERBAKE_PARAMETERS['consensus_committee_size'] = 67 - -FOLDER = constants.ITHACA_FOLDER - -PREV_HASH = constants.HANGZHOU -PREV_DAEMON = constants.HANGZHOU_DAEMON -PREV_PARAMETERS = constants.HANGZHOU_PARAMETERS - - -def activate( - client, - parameters=PARAMETERS, - proto=HASH, - timestamp=None, - activate_in_the_past=False, -): - utils.activate_protocol( - client, proto, parameters, timestamp, activate_in_the_past - ) - - -class Protocol(Enum): - CURRENT = auto() - PREV = auto() - - -def get_parameters(protocol: Optional[Protocol] = Protocol.CURRENT): - """ - Args: - protocol (Protocol): protocol id (either CURRENT or PREV). - Defaults to CURRENT - - Returns: - A fresh copy of the protocol parameters w.r.t to protocol - """ - # deepcopy call prevents any unforeseen and unwanted side effects - # on the array parameters - # e.g., bootstrap_accounts, commitments, endorsement_reward - return deepcopy( - dict((PARAMETERS if protocol is Protocol.CURRENT else PREV_PARAMETERS)) - ) - - -def get_now(client) -> str: - """Returns the timestamp of next-to-last block, - offset by the minimum time between blocks""" - - timestamp_date = client.get_block_timestamp(block='head~1') - - constants = client.rpc('get', '/chains/main/blocks/head/context/constants') - - delta = datetime.timedelta(seconds=int(constants['minimal_block_delay'])) - - now_date = timestamp_date + delta - - rfc3399_format = "%Y-%m-%dT%H:%M:%SZ" - return now_date.strftime(rfc3399_format) diff --git a/tests_python/tests_012/test_accuser.py b/tests_python/tests_012/test_accuser.py deleted file mode 100644 index 1104ed5c67c0..000000000000 --- a/tests_python/tests_012/test_accuser.py +++ /dev/null @@ -1,126 +0,0 @@ -import time - -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox -from . import protocol - - -NUM_NODES = 2 - - -@pytest.mark.multinode -@pytest.mark.incremental -class TestAccuser: - """Constructs a double endorsement, and lets the accuser inject - the evidence.""" - - def test_init(self, sandbox: Sandbox): - for i in range(NUM_NODES): - sandbox.add_node(i, params=constants.NODE_PARAMS) - protocol.activate(sandbox.client(0), activate_in_the_past=True) - # We inject 3 blocks so that the double-endorsement-evidence operation - # is always branched from a known predecessor. (If the level of the - # evidence is smaller than 5, then the operation is branched from the - # head; however the node might change branch, and then the operation - # becomes invalid, namely "branch refused".) - for i in range(3): - utils.bake(sandbox.client(0)) - - def test_level(self, sandbox: Sandbox): - level = 4 - for client in sandbox.all_clients(): - assert utils.check_level(client, level) - - def test_terminate_node_1(self, sandbox: Sandbox): - sandbox.node(1).terminate() - - def test_bake_node_0(self, sandbox: Sandbox): - """Client 0 bakes block A at level 5, not communicated to node 1. - Inject an operation (transfer) to ensure a different hash""" - sandbox.client(0).transfer(1, 'bootstrap4', 'bootstrap5') - sandbox.client(0).propose( - delegates=['bootstrap1'], args=['--minimal-timestamp'] - ) - - def test_endorse_node_0(self, sandbox: Sandbox, session: dict): - """bootstrap1 builds an endorsement for block A""" - client = sandbox.client(0) - client.run(["endorse", "for", 'bootstrap3', '--force']) - mempool = client.get_mempool() - endorsement = mempool['applied'][0] - session['endorsement1'] = endorsement - utils.bake(client, bake_for='bootstrap2') - - def test_terminate_node_0(self, sandbox: Sandbox): - sandbox.node(0).terminate() - - def test_restart_node_1(self, sandbox: Sandbox): - sandbox.node(1).run() - assert sandbox.client(1).check_node_listening() - - def test_start_accuser(self, sandbox: Sandbox): - sandbox.add_accuser(1, proto=protocol.DAEMON) - # We make sure that there is enough time for the accuser to start - # listing to the node's block stream, otherwise the accuser might miss - # the next two blocks. - time.sleep(2) - - def test_bake_node_1(self, sandbox: Sandbox): - """Client 1 bakes block B at level 5, not communicated to node 0""" - sandbox.client(1).propose( - delegates=['bootstrap1'], args=['--minimal-timestamp'] - ) - - def test_endorse_node_2(self, sandbox: Sandbox, session: dict): - """bootstrap1 builds an endorsement for block B, which is included in - a new block at level 6 by bootstrap2""" - client = sandbox.client(1) - client.run(["endorse", "for", 'bootstrap3', "--force"]) - mempool = client.get_mempool() - endorsement = mempool['applied'][0] - session['endorsement2'] = endorsement - utils.bake(client, bake_for='bootstrap2') - mempool = client.get_mempool() - client.get_operations("4") - - def test_restart_node_0(self, sandbox: Sandbox): - sandbox.node(0).run() - sandbox.client(0).check_node_listening() - - def test_check_level(self, sandbox: Sandbox): - """All nodes are at level 6, head is either block A or B""" - level = 6 - for client in sandbox.all_clients(): - assert utils.check_level(client, level) - - def test_bake_block(self, sandbox: Sandbox): - """Bake a block on node 0, which makes the chain on node 0 longer; in - this way, we make sure that node 1 sees the block at level 6, - which containts the conflicting endorsement. - """ - utils.bake(sandbox.client(0)) - - @pytest.mark.xfail(reason="Works locally - CI fails") - def test_double_baking_evidence_generated(self, sandbox: Sandbox): - """Check that a double baking evidence operation is in the - mempool of node 1 or in the block at level 7, depending on - whether the double endorsement operation has reached node 1 - before or after node 1 sees the block at level 7. - """ - in_mempool = False - in_block = False - - mempool = sandbox.client(1).get_mempool() - applied = mempool['applied'] - evidence_kind = "double_baking_evidence" - - if len(applied) > 0 and len(applied[0]['contents']) > 0: - in_mempool = applied[0]['contents'][0]['kind'] == evidence_kind - - if not in_mempool: - ops = sandbox.client(1).get_operations() - if len(ops[2]) > 0 and len(ops[2][0]['contents']) > 0: - in_block = ops[2][0]['contents'][0]['kind'] == evidence_kind - - assert in_mempool or in_block diff --git a/tests_python/tests_012/test_baker_endorser.py b/tests_python/tests_012/test_baker_endorser.py deleted file mode 100644 index e5747f5f8516..000000000000 --- a/tests_python/tests_012/test_baker_endorser.py +++ /dev/null @@ -1,113 +0,0 @@ -import itertools -import random -import time -import subprocess -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox -from . import protocol - -random.seed(42) -KEYS = [f'bootstrap{i}' for i in range(1, 6)] -NEXT_KEY = itertools.cycle(KEYS) -NUM_NODES = 5 -NEW_NODES = 5 -REPLACE = False -NUM_CYCLES = 60 -TIME_BETWEEN_CYCLE = 2 -assert NEW_NODES <= NUM_CYCLES - - -def random_op(client): - sender = next(NEXT_KEY) - dest = random.choice([key for key in KEYS if key != sender]) - amount = random.randrange(10000) - return client.transfer(amount, sender, dest) - - -@pytest.mark.baker -@pytest.mark.endorser -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -class TestAllDaemonsWithOperations: - """Runs two baker and two endorsers, generates random op, and - add (or replace) new nodes dynamically. After a little while, - we kill the bakers and check everyone synchronize to the same head.""" - - def test_setup_network(self, sandbox: Sandbox): - parameters = protocol.get_parameters() - # each priority has a delay of 1 sec - # parameters["time_between_blocks"] = ["1"] - for i in range(NUM_NODES): - sandbox.add_node(i, params=constants.NODE_PARAMS) - protocol.activate(sandbox.client(0), parameters=parameters) - time.sleep(3) - for i in range(NUM_NODES - 1): - sandbox.add_baker(i, [f'bootstrap{5 - i}'], protocol.DAEMON) - - def test_wait_for_protocol(self, sandbox: Sandbox): - clients = sandbox.all_clients() - for client in clients: - proto = protocol.HASH - assert utils.check_protocol(client, proto) - - def test_network_gen_operations_and_add_nodes( - self, sandbox: Sandbox, session - ): - node_add_period = NUM_CYCLES // NEW_NODES - for cycle in range(NUM_CYCLES): - i = random.randrange(NUM_NODES) - client = sandbox.client(i) - try: - transfer = random_op(client) - session[f'op{cycle}'] = transfer.operation_hash - except subprocess.CalledProcessError: - # some operations may be invalid, e.g. the client sends - # several operation with the same counter - print('# IGNORED INVALID OPERATION') - - if cycle % node_add_period == 0: - # add node - running_nodes = list(sandbox.nodes.keys()) - new_node = max(running_nodes) + 1 - if REPLACE: - running_nodes.remove(0) - running_nodes.remove(1) - sandbox.rm_node(random.choice(running_nodes)) - sandbox.add_node(new_node, params=constants.NODE_PARAMS) - proto = protocol.HASH - assert utils.check_protocol(sandbox.client(new_node), proto) - time.sleep(TIME_BETWEEN_CYCLE) - - def test_kill_baker(self, sandbox: Sandbox): - for i in range(NUM_NODES - 1): - sandbox.rm_baker(i, proto=protocol.DAEMON) - - def test_synchronize(self, sandbox: Sandbox): - utils.synchronize(sandbox.all_clients()) - - @pytest.mark.xfail(reason="Not enough time to reach level?") - def test_progress(self, sandbox: Sandbox): - level = sandbox.client(0).get_level() - assert level >= 5 - - def test_check_operations(self, sandbox: Sandbox): - min_level = min( - [client.get_level() for client in sandbox.all_clients()] - ) - heads_hash = set() - # check there is exactly one head - for client in sandbox.all_clients(): - block_hash = utils.get_block_hash(client, min_level) - heads_hash.add(block_hash) - assert len(heads_hash) == 1 - # TODO check for operations inclusion - - def test_check_logs(self, sandbox: Sandbox): - if not sandbox.log_dir: - pytest.skip() - assert sandbox.logs - # TODO check more things in the log! endorsement, baking... - error_pattern = r"Uncaught|registered" - assert utils.check_logs(sandbox.logs, error_pattern) diff --git a/tests_python/tests_012/test_basic.py b/tests_python/tests_012/test_basic.py deleted file mode 100644 index f40471aa5bfd..000000000000 --- a/tests_python/tests_012/test_basic.py +++ /dev/null @@ -1,503 +0,0 @@ -from os import path -from typing import List -import pytest -from client.client import Client -from tools import constants, utils -from tools.paths import ACCOUNT_PATH -from tools.utils import assert_run_failure -from .contract_paths import CONTRACT_PATH - - -BAKE_ARGS: List[str] = [] -TRANSFER_ARGS = ['--burn-cap', '0.257'] - - -@pytest.mark.incremental -class TestRawContext: - def test_delegates(self, client: Client): - path = '/chains/main/blocks/head/context/raw/bytes/delegates/?depth=2' - res = client.rpc('get', path) - expected = { - "ed25519": { - "02298c03ed7d454a101eb7022bc95f7e5f41ac78": None, - "a9ceae0f8909125492a7c4700acc59274cc6c846": None, - "c55cf02dbeecc978d9c84625dcae72bb77ea4fbd": None, - "dac9f52543da1aed0bc1d6b46bf7c10db7014cd6": None, - "e7670f32038107a59a2b9cfefae36ea21f5aa63c": None, - } - } - assert res == expected - - def test_no_service_1(self, client: Client): - path = '/chains/main/blocks/head/context/raw/bytes/non-existent' - with assert_run_failure('No service found at this URL'): - client.rpc('get', path) - - def test_no_service_2(self, client: Client): - path = ( - '/chains/main/blocks/head/context/raw/bytes/' - 'non-existent?depth=-1' - ) - expected = r'Failed to parse argument \'depth\' \("-1"\)' - with assert_run_failure(expected): - client.rpc('get', path) - - def test_no_service_3(self, client: Client): - path = '/chains/main/blocks/head/context/raw/bytes/non-existent?depth=0' - with assert_run_failure('No service found at this URL'): - client.rpc('get', path) - - def test_bake(self, client: Client): - utils.bake(client, 'bootstrap4') - - @pytest.mark.parametrize( - "identity, message, expected_signature", - [ - ( - 'bootstrap1', - 'msg1', - 'edsigtz68o4FdbpvycnAMDLaa7hpmmhjDx' - 'hx4Zu3QWHLYJtcY1mVhW9m6CCvsciFXwf1' - 'zLmah8fJP51cqaeaciBPGy5osH11AnR', - ), - ( - 'bootstrap2', - 'msg2', - 'edsigtZqhR5SW6vbRSmqwzfS1KiJZLYLe' - 'FhLcCEw7WxjBDxotVx83M2rLe4Baq52SUT' - 'jxfXhQ5J3TabCwqt78kNpoU8j42GDEk4', - ), - ( - 'bootstrap3', - 'msg3', - 'edsigu2PvAWxVYY3jQFVfBRW2Dg61xZMN' - 'esHiNbwCTmpJSyfcJMW8Ch9WABHqsgHQRB' - 'aSs6zZNHVGXfHSBnGCxT9x2b49L2zpMW', - ), - ( - 'bootstrap4', - 'msg4', - 'edsigu5jieost8eeD3JwVrpPuSnKzLLvR3' - 'aqezLPDTvxC3p41qwBEpxuViKriipxig5' - '2NQmJ7AFXTzhM3xgKM2ZaADcSMYWztuJ', - ), - ], - ) - def test_sign_message(self, client, identity, message, expected_signature): - assert client.sign_message(message, identity) == expected_signature - - @pytest.mark.parametrize( - "identity, message, signature", - [ - ( - 'bootstrap1', - 'msg1', - 'edsigtz68o4FdbpvycnAMDLaa7hpmmhjDx' - 'hx4Zu3QWHLYJtcY1mVhW9m6CCvsciFXwf1' - 'zLmah8fJP51cqaeaciBPGy5osH11AnR', - ), - ( - 'bootstrap2', - 'msg2', - 'edsigtZqhR5SW6vbRSmqwzfS1KiJZLYLe' - 'FhLcCEw7WxjBDxotVx83M2rLe4Baq52SUT' - 'jxfXhQ5J3TabCwqt78kNpoU8j42GDEk4', - ), - ( - 'bootstrap3', - 'msg3', - 'edsigu2PvAWxVYY3jQFVfBRW2Dg61xZMN' - 'esHiNbwCTmpJSyfcJMW8Ch9WABHqsgHQRB' - 'aSs6zZNHVGXfHSBnGCxT9x2b49L2zpMW', - ), - ( - 'bootstrap4', - 'msg4', - 'edsigu5jieost8eeD3JwVrpPuSnKzLLvR3' - 'aqezLPDTvxC3p41qwBEpxuViKriipxig5' - '2NQmJ7AFXTzhM3xgKM2ZaADcSMYWztuJ', - ), - ], - ) - def test_check_message(self, client, identity, message, signature): - assert client.check_message(message, identity, signature) - - @pytest.mark.parametrize( - "identity, message, head_block", - [ - ("bootstrap1", "msg1", False), - ("bootstrap2", "msg2", False), - ("bootstrap3", "msg3", True), - ("bootstrap4", "msg4", True), - ], - ) - def test_fail_inject_signed_arbitrary_ope( - self, client, identity, message, head_block - ): - if head_block: - signature = client.sign_message(message, identity, block="head") - else: - signature = client.sign_message(message, identity) - chain_id = client.rpc('get', '/chains/main/chain_id') - head_hash = client.rpc('get', '/chains/main/blocks/head/hash') - run_json = { - 'operation': { - "branch": head_hash, - "contents": [{"kind": "failing_noop", "arbitrary": message}], - 'signature': signature, - }, - 'chain_id': chain_id, - } - run_operation_path = ( - '/chains/main/blocks/head/helpers/scripts/run_operation' - ) - with assert_run_failure( - 'The failing_noop operation cannot be executed by the protocol' - ): - client.rpc('post', run_operation_path, data=run_json) - - def test_gen_keys(self, client: Client, session): - session['keys'] = ['foo', 'bar', 'boo'] - sigs = [None, 'secp256k1', 'ed25519'] - for key, sig in zip(session['keys'], sigs): - args = [] if sig is None else ['--sig', sig] - client.gen_key(key, args) - - def test_transfers(self, client: Client, session): - client.transfer(1000, 'bootstrap1', session['keys'][0], TRANSFER_ARGS) - utils.bake(client) - client.transfer(2000, 'bootstrap1', session['keys'][1], TRANSFER_ARGS) - utils.bake(client) - client.transfer(3000, 'bootstrap1', session['keys'][2], TRANSFER_ARGS) - utils.bake(client) - - def test_balances(self, client: Client, session): - assert client.get_balance(session['keys'][0]) == 1000 - assert client.get_balance(session['keys'][1]) == 2000 - assert client.get_balance(session['keys'][2]) == 3000 - - def test_transfer_bar_foo(self, client: Client, session): - client.reveal(session['keys'][1], ['--fee', '0', '--force-low-fee']) - utils.bake(client) - client.transfer( - 1000, - session['keys'][1], - session['keys'][0], - ['--fee', '0', '--force-low-fee'], - ) - utils.bake(client) - - def test_balances_bar_foo(self, client: Client, session): - assert client.get_balance(session['keys'][0]) == 2000 - assert client.get_balance(session['keys'][1]) == 1000 - - def test_transfer_foo_bar(self, client: Client, session): - client.reveal(session['keys'][0], ['--fee', '0', '--force-low-fee']) - utils.bake(client) - client.transfer( - 1000, session['keys'][0], session['keys'][1], ['--fee', '0.05'] - ) - utils.bake(client) - - def test_balances_foo_bar(self, client: Client, session): - # 999.95 = 1000 - transfer fees - assert client.get_balance(session['keys'][0]) == 999.95 - assert client.get_balance(session['keys'][1]) == 2000 - - def test_transfer_failure(self, client: Client, session): - with pytest.raises(Exception): - client.transfer(999.95, session['keys'][0], session['keys'][1]) - - def test_originate_contract_noop(self, client: Client): - contract = path.join(CONTRACT_PATH, 'opcodes', 'noop.tz') - client.remember('noop', contract) - client.typecheck(contract) - client.originate( - 'noop', 1000, 'bootstrap1', contract, ['--burn-cap', '0.295'] - ) - utils.bake(client) - - def test_transfer_to_noop(self, client: Client): - client.transfer(10, 'bootstrap1', 'noop', ['--arg', 'Unit']) - utils.bake(client) - - def test_contract_hardlimit(self, client: Client): - contract = path.join(CONTRACT_PATH, 'mini_scenarios', 'hardlimit.tz') - client.originate( - 'hardlimit', - 1000, - 'bootstrap1', - contract, - ['--init', '3', '--burn-cap', '0.341'], - ) - utils.bake(client) - client.transfer(10, 'bootstrap1', 'hardlimit', ['--arg', 'Unit']) - utils.bake(client) - client.transfer(10, 'bootstrap1', 'hardlimit', ['--arg', 'Unit']) - utils.bake(client) - - def test_transfers_bootstraps5_bootstrap1(self, client: Client): - bootstrap5 = constants.IDENTITIES['bootstrap5']['identity'] - all_deposits = client.frozen_deposits(bootstrap5) - balance = client.get_mutez_balance('bootstrap5') - assert balance + all_deposits == utils.mutez_of_tez(4000000.0) - client.transfer( - 400000, - 'bootstrap5', - 'bootstrap1', - ['--fee', '0', '--force-low-fee'], - ) - utils.bake(client) - client.transfer( - 400000, - 'bootstrap1', - 'bootstrap5', - ['--fee', '0', '--force-low-fee'], - ) - utils.bake(client) - all_deposits = client.frozen_deposits(bootstrap5) - assert client.get_mutez_balance( - 'bootstrap5' - ) + all_deposits == utils.mutez_of_tez(4000000.0) - - def test_activate_accounts(self, client: Client, session): - account = f"{ACCOUNT_PATH}/king_commitment.json" - session['keys'] += ['king', 'queen'] - client.activate_account(session['keys'][3], account) - utils.bake(client) - account = f"{ACCOUNT_PATH}/queen_commitment.json" - client.activate_account(session['keys'][4], account) - utils.bake(client) - assert client.get_balance(session['keys'][3]) == 23932454.669343 - assert client.get_balance(session['keys'][4]) == 72954577.464032 - - def test_transfer_king_queen(self, client: Client, session): - keys = session['keys'] - client.transfer(10, keys[3], keys[4], TRANSFER_ARGS) - utils.bake(client) - - def test_duplicate_alias(self, client: Client): - client.add_address("baz", "foo", force=True) - show_foo = client.show_address("foo", show_secret=True) - assert show_foo.secret_key is not None - - -@pytest.mark.incremental -class TestRememberContract: - @pytest.mark.parametrize( - "contract_name,non_originated_contract_address", - [ - ("test", "KT1BuEZtb68c1Q4yjtckcNjGELqWt56Xyesc"), - ("test-2", "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9"), - ], - ) - def test_non_originated_contract_no_forcing_not_saved_before( - self, - client, - contract_name, - non_originated_contract_address, - ): - client.remember_contract(contract_name, non_originated_contract_address) - - # As it is always the same client, the contracts have been saved - # before - @pytest.mark.parametrize( - "contract_name,non_originated_contract_address", - [ - ("test", "KT1BuEZtb68c1Q4yjtckcNjGELqWt56Xyesc"), - ("test-2", "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9"), - ], - ) - def test_non_originated_contract_with_forcing_and_saved_before( - self, - client, - contract_name, - non_originated_contract_address, - ): - client.remember_contract( - contract_name, non_originated_contract_address, force=True - ) - - # As it is always the same client, the contracts have been saved - # before - @pytest.mark.parametrize( - "contract_name,non_originated_contract_address", - [ - ("test", "KT1BuEZtb68c1Q4yjtckcNjGELqWt56Xyesc"), - ("test-2", "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9"), - ], - ) - def test_non_originated_contract_no_forcing_and_saved_before( - self, - client, - contract_name, - non_originated_contract_address, - ): - expected_error = f"The contract alias {contract_name} already exists" - - with assert_run_failure(expected_error): - client.remember_contract( - contract_name, non_originated_contract_address, force=False - ) - - # Test operation size. - def test_operation_size_originate_byte_contract(self, client: Client): - contract = path.join(CONTRACT_PATH, 'opcodes', 'bytes.tz') - client.remember('bytes', contract) - client.typecheck(contract) - client.originate( - 'bytes', 1000, 'bootstrap1', contract, ['--burn-cap', '0.295'] - ) - utils.bake(client) - - # Test that operations under 16KB can be injected in the node. - def test_operation_size_small(self, client: Client): - bytes_arg = "0x" + ("00" * 6 * 1024) # 6 KB of data. - - client.transfer(10, 'bootstrap1', 'bytes', ['--arg', bytes_arg]) - utils.bake(client) - - # Test that operations between 16KB and 32KB can be injected in the node. - def test_operation_size_medium(self, client: Client): - bytes_arg = "0x" + ("00" * 24 * 1024) # 24 KB of data. - - client.transfer(10, 'bootstrap1', 'bytes', ['--arg', bytes_arg]) - utils.bake(client) - - # Test that operations above 32KB fail to be injected. - def test_operation_size_oversized(self, client: Client): - bytes_arg = "0x" + ("00" * 36 * 1024) # 36 KB of data. - - expected_error = "Oversized operation" - with assert_run_failure(expected_error): - client.transfer(10, 'bootstrap1', 'bytes', ['--arg', bytes_arg]) - - # Test operation size with various data types. - def test_operation_size_originate_munch_contract(self, client: Client): - contract = path.join(CONTRACT_PATH, 'opcodes', 'munch.tz') - client.remember('munch', contract) - client.typecheck(contract) - client.originate( - 'munch', 1000, 'bootstrap1', contract, ['--burn-cap', '0.295'] - ) - utils.bake(client) - - # Test that a large operation under 32KB can be injected in the node - # (variant using a lambda with deep nesting). - def test_operation_size_with_lambda_ok(self, client: Client): - # Each pair of braces is encoded on 5 bytes so this takes - # 5 * 6 * 1024 = 30 KB < 32KB - big_arg = ("{" * 6 * 1024) + ("}" * 6 * 1024) - - client.transfer( - 10, - 'bootstrap1', - 'munch', - ['--arg', big_arg, "--entrypoint", "lambda"], - ) - utils.bake(client) - - # Test that a large operation over 32KB cannot be injected in the node, - # and the error is not a stack overflow - # (variant using a lambda with deep nesting). - def test_operation_size_with_lambda_fail(self, client: Client): - # Each pair of braces is encoded on 5 bytes so this takes - # 5 * 7 * 1024 = 35 KB > 32KB - big_arg = ("{" * 7 * 1024) + ("}" * 7 * 1024) - - expected_error = "Oversized operation" - with assert_run_failure(expected_error): - client.transfer( - 10, - 'bootstrap1', - 'munch', - ['--arg', big_arg, "--entrypoint", "lambda"], - ) - - # Test that a large operation under 32KB can be injected in the node - # (variant using a long list). - def test_operation_size_with_list_ok(self, client: Client): - # Each element in the list takes 2 bytes so about 30KB in total - big_arg = "{" + ("0; " * 15 * 1024) + "}" - - client.transfer( - 10, - 'bootstrap1', - 'munch', - ['--arg', big_arg, "--entrypoint", "list_nat"], - ) - utils.bake(client) - - def test_operation_size_with_list_syntax_error(self, client: Client): - # Each element in the list takes 2 bytes so about 30KB in total - big_arg = "{" + ("0; " * 15 * 1024) + "'foo;'" + "}" - - expected_error = "transfer simulation failed" - with assert_run_failure(expected_error): - client.transfer( - 10, - 'bootstrap1', - 'munch', - ['--arg', big_arg, "--entrypoint", "list_nat"], - ) - - def test_operation_size_with_list_ill_typed(self, client: Client): - # Each element in the list takes 2 bytes so about 30KB in total - big_arg = "{" + ("0; " * 15 * 1024) + "Unit;" + "}" - - expected_error = "transfer simulation failed" - with assert_run_failure(expected_error): - client.transfer( - 10, - 'bootstrap1', - 'munch', - ['--arg', big_arg, "--entrypoint", "list_nat"], - ) - - # Test that a large operation over 32KB cannot be injected in the node, - # and the error is not a stack overflow - # (variant using a long list). - def test_operation_size_with_list_fail(self, client: Client): - # Each element in the list takes 2 bytes so about 34KB in total - big_arg = "{" + ("0; " * 17 * 1024) + "}" - - expected_error = "Oversized operation" - with assert_run_failure(expected_error): - client.transfer( - 10, - 'bootstrap1', - 'munch', - ['--arg', big_arg, "--entrypoint", "list_nat"], - ) - - # Test that a large operation under 32KB can be injected in the node - # (variant using a big nat). - def test_operation_size_with_nat_ok(self, client: Client): - # The encoding for nat uses a byte to encode 7 bits of the number - # so the size of 2 ** (7 * n) is about n bytes - big_arg = 2 ** (7 * 30 * 1024) - - client.transfer( - 10, - 'bootstrap1', - 'munch', - ['--arg', f"{big_arg}", "--entrypoint", "nat"], - ) - utils.bake(client) - - # Test that a large operation over 32KB cannot be injected in the node, - # and the error is not a stack overflow - # (variant using a big nat). - def test_operation_size_with_nat_fail(self, client: Client): - # The encoding for nat uses a byte to encode 7 bits of the number - # so the size of 2 ** (7 * n) is about n bytes - big_arg = 2 ** (7 * 33 * 1024) - - expected_error = "Oversized operation" - with assert_run_failure(expected_error): - client.transfer( - 10, - 'bootstrap1', - 'munch', - ['--arg', f"{big_arg}", "--entrypoint", "nat"], - ) diff --git a/tests_python/tests_012/test_binaries.py b/tests_python/tests_012/test_binaries.py deleted file mode 100644 index 63cb9934746d..000000000000 --- a/tests_python/tests_012/test_binaries.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -Tests common utility functionality of binaries shipped with Tezos. -""" - -import subprocess -from typing import List - -from process import process_utils -from tools import paths -from . import protocol - - -PROTO_BINARIES = [ - binary + "-" + protocol.DAEMON - for binary in ["tezos-baker", "tezos-accuser"] -] - -BINARIES = [ - "tezos-codec", - "tezos-client", - "tezos-admin-client", - "tezos-protocol-compiler", - "tezos-node", - "tezos-snoop", - "tezos-validator", -] + PROTO_BINARIES - - -def run_cmd(cmd: List[str]) -> str: - """Pretty print a command. Execute it, print and return its standard - output.""" - print(process_utils.format_command(cmd)) - process_ret = subprocess.run( - cmd, check=True, capture_output=True, text=True - ) - print(process_ret.stdout) - return process_ret.stdout.strip() - - -class TestBinaries: - def test_version(self): - """Tests that all binaries accept the --version flag and that the - report the same version""" - versions = set() - for binary in BINARIES: - version = run_cmd([paths.TEZOS_HOME + binary, "--version"]) - versions.add(version) - assert len(versions) == 1, "All binaries should report the same version" diff --git a/tests_python/tests_012/test_bootstrap.py b/tests_python/tests_012/test_bootstrap.py deleted file mode 100644 index c817b0354534..000000000000 --- a/tests_python/tests_012/test_bootstrap.py +++ /dev/null @@ -1,221 +0,0 @@ -import time - -import pytest -from launchers.sandbox import Sandbox -from . import protocol - -LOG_LEVEL = {"validator.chain": "debug", "validator.peer": "debug"} - - -def params(threshold=0, latency=3): - return [ - '--sync-latency', - str(latency), - '--synchronisation-threshold', - str(threshold), - '--connections', - '100', - ] - - -def add_fully_delegated_baker(sandbox: Sandbox, node: int, protocol: str): - """Add a baker that has all known bootstrap accounts delegated to it.""" - sandbox.add_baker(node, [], proto=protocol) - - -@pytest.mark.baker -@pytest.mark.incremental -class TestThresholdZero: - """Threshold 0, peer always bootstrapped.""" - - def test_setup_network(self, sandbox: Sandbox): - sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) - sandbox.add_baker(0, ['bootstrap5'], proto=protocol.DAEMON) - - def test_bootstrap(self, sandbox: Sandbox): - client = sandbox.client(0) - assert client.sync_state() == 'synced' - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.incremental -class TestThresholdOne: - """First peer has threshold zero, second peer has threshold one""" - - def test_setup_network(self, sandbox: Sandbox): - sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) - protocol.activate(sandbox.client(0)) - sandbox.add_baker(0, ['bootstrap5'], proto=protocol.DAEMON) - - def test_bootstrap(self, sandbox: Sandbox): - client = sandbox.client(0) - assert client.sync_state() == 'synced' - - def test_add_node(self, sandbox: Sandbox): - sandbox.add_node( - 1, params=params(1), log_levels=LOG_LEVEL, config_client=False - ) - sandbox.client(1).bootstrapped() - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.incremental -class TestThresholdTwo: - def test_setup_network(self, sandbox: Sandbox): - sandbox.add_node(0, params=params(0), log_levels=LOG_LEVEL) - protocol.activate(sandbox.client(0)) - time.sleep(3) - sandbox.add_baker(0, ['bootstrap5'], proto=protocol.DAEMON) - - def test_add_nodes(self, sandbox: Sandbox): - sandbox.add_node( - 1, params=params(2), log_levels=LOG_LEVEL, config_client=False - ) - sandbox.add_node( - 2, params=params(2), log_levels=LOG_LEVEL, config_client=False - ) - sandbox.add_node( - 3, params=params(1), log_levels=LOG_LEVEL, config_client=False - ) - - # Some lower timeouts (5, 10) make the test fails. 15 seems to be enough - # If the test fails again, look at increasing this timeout first. - @pytest.mark.timeout(15) - def test_node_3_bootstrapped(self, sandbox: Sandbox): - sandbox.client(3).bootstrapped() - - # See comment for previous test - @pytest.mark.timeout(5) - def test_node_1_bootstrapped(self, sandbox: Sandbox): - sandbox.client(1).bootstrapped() - - -@pytest.mark.slow -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.incremental -class TestStuck: - def test_setup_network(self, sandbox: Sandbox): - sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) - protocol.activate(sandbox.client(0)) - add_fully_delegated_baker(sandbox, 0, protocol.DAEMON) - - def test_kill_baker(self, sandbox: Sandbox): - """Bake a few blocks and kill baker""" - time.sleep(14) - sandbox.rm_baker(0, proto=protocol.DAEMON) - time.sleep(5) - - def test_progress(self, sandbox: Sandbox): - assert sandbox.client(0).get_level() >= 2 - - def test_add_node(self, sandbox: Sandbox): - sandbox.add_node( - 1, params=params(2), config_client=False, log_levels=LOG_LEVEL - ) - sandbox.add_node( - 2, params=params(2), config_client=False, log_levels=LOG_LEVEL - ) - - def test_all_nodes_boostrap(self, sandbox: Sandbox): - """Eventually, 1 and 2 are bootstrapped with the chain stuck. """ - sandbox.client(1).bootstrapped() - sandbox.client(2).bootstrapped() - assert sandbox.client(1).sync_state() == 'stuck' - assert sandbox.client(2).sync_state() == 'stuck' - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.incremental -class TestSplitView: - def test_setup_network(self, sandbox: Sandbox): - sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) - protocol.activate(sandbox.client(0)) - sandbox.add_node( - 1, params=params(), config_client=False, log_levels=LOG_LEVEL - ) - sandbox.add_node( - 2, - params=params(2, latency=15), - config_client=False, - log_levels=LOG_LEVEL, - ) - add_fully_delegated_baker(sandbox, 0, protocol.DAEMON) - - @pytest.mark.timeout(10) - def test_all_nodes_boostrap(self, sandbox: Sandbox): - assert sandbox.client(0).sync_state() == 'synced' - assert sandbox.client(1).sync_state() == 'synced' - sandbox.client(2).bootstrapped() - - def test_pause(self): - time.sleep(2) - - def test_disconnect_node(self, sandbox: Sandbox): - """node 1 is disconnected from baker""" - sandbox.client(1).ban_peer(sandbox.node(0).p2p_port) - sandbox.client(0).ban_peer(sandbox.node(1).p2p_port) - - def test_sync_status(self, sandbox: Sandbox): - assert sandbox.client(0).sync_state() == 'synced' - assert sandbox.client(1).sync_state() == 'synced' - assert sandbox.client(2).sync_state() == 'synced' - - -NUM_NODES = 8 -RUNNING_TIME = 10 - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -class TestManyNodesBootstrap: - """Run many nodes, bake for a while, add a node and check it's bootstrapped - when it should be.""" - - def test_init(self, sandbox: Sandbox): - sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) - parameters = protocol.get_parameters() - protocol.activate(sandbox.client(0), parameters=parameters) - time.sleep(3) - add_fully_delegated_baker(sandbox, 0, protocol.DAEMON) - sandbox.add_node( - 1, params=params(), log_levels=LOG_LEVEL, config_client=False - ) - - def test_bootstrap(self, sandbox: Sandbox): - sandbox.client(0).bootstrapped() - sandbox.client(1).bootstrapped() - - def test_add_nodes(self, sandbox: Sandbox): - for i in range(2, NUM_NODES): - sandbox.add_node( - i, params=params(), config_client=False, log_levels=LOG_LEVEL - ) - - def test_let_baking(self): - time.sleep(RUNNING_TIME) - - def test_progress(self, sandbox, session): - cur_level = sandbox.client(NUM_NODES - 1).get_level() - assert cur_level > RUNNING_TIME // 2 # check progress - session['cur_level'] = cur_level - - @pytest.mark.timeout(50) - def test_add_one_more_node(self, sandbox, session): - new_node = NUM_NODES - sandbox.add_node( - new_node, - params=params(NUM_NODES), - config_client=False, - log_levels=LOG_LEVEL, - ) - time.sleep(1) - sandbox.client(new_node).p2p_stat() - sandbox.client(new_node).bootstrapped() - cur_level = session['cur_level'] - assert sandbox.client(new_node).get_level() >= cur_level diff --git a/tests_python/tests_012/test_client.py b/tests_python/tests_012/test_client.py deleted file mode 100644 index f42255fba442..000000000000 --- a/tests_python/tests_012/test_client.py +++ /dev/null @@ -1,35 +0,0 @@ -import pytest -from client.client import Client -from tools.utils import assert_run_failure, bake - - -@pytest.mark.client -@pytest.mark.incremental -@pytest.mark.usefixtures("encrypted_account_with_tez") -class TestSimulation: - """ Tests the behavior of the --simulation flag. """ - - def test_transfer_simulation(self, client: Client): - """ Tests that --simulation does not ask for the key password. """ - client.transfer( - 0.1, "encrypted_account", "bootstrap1", ["--simulation"] - ) - - def test_transfer_without_simulation(self, client: Client): - """ Tests that the client asks for the password w/o --simulation. """ - with assert_run_failure("End_of_file", mode="stdout"): - client.transfer(0.1, "encrypted_account", "bootstrap1") - - def test_delegate_simulation(self, client: Client): - """ Tests that --simulation does not ask for the key password. """ - client.gen_key("delegate") - client.transfer(100, "bootstrap1", "delegate", ["--burn-cap", "1.0"]) - bake(client, bake_for="bootstrap1") - client.register_delegate("delegate") - bake(client, bake_for="bootstrap1") - client.set_delegate("encrypted_account", "delegate", ["--simulation"]) - - def test_delegate_without_simulation(self, client: Client): - """ Tests that the client asks for the password w/o --simulation. """ - with assert_run_failure("End_of_file", mode="stdout"): - client.set_delegate("encrypted_account", "delegate") diff --git a/tests_python/tests_012/test_client_without_node.py b/tests_python/tests_012/test_client_without_node.py deleted file mode 100644 index 8e5a27bac845..000000000000 --- a/tests_python/tests_012/test_client_without_node.py +++ /dev/null @@ -1,450 +0,0 @@ -"""Node-less tests for the client. - -Some client tests do not require a node running, nor a -persistent mockup environment. These can be placed here. -""" -import json -import os -import subprocess -import tempfile -from typing import List, Optional -import pytest -from client.client import Client -from tools.utils import assert_run_failure - -# Note that specifying "endpoint" and "web_port" is required -# for the final assertion of test_config_init_roundtrip to pass. That's because -# `config init -o` writes them even if unspecified by `--config-file` -# (it's a fine behavior, I just wanted to highlight it). -_INPUT_CONFIG_FILE = { - "confirmations": 1, - "endpoint": "http://127.0.0.1:8732", - "remote_signer": "http://127.0.0.2", - "web_port": 8080, - "password_filename": "/tmp/doesnt_exist", -} -_INPUT_CONFIG_FILES = [None, _INPUT_CONFIG_FILE] -_CMD_LINE_ARGS = { - "--endpoint": "http://127.0.0.1:9732", - "--wait": "3", - "--remote-signer": "http://10.0.0.2", - "--password-filename": "/tmp/doesnt_exist_either", -} -_CONFIG_FILE_FLAG = "--config-file" - - -@pytest.mark.client -class TestImportKeyMnemonic: - """ Checks that the keys are correctly imported from a mnemonic. """ - - @pytest.fixture - def mnemonic(self): - return ( - "seek paddle siege sting siege sick kidney " - + "detect coral because comfort long enforce napkin enter" - ) - - @pytest.fixture - def passphrase(self): - return "very_secure_passphrase" - - def test_import_simple(self, client: Client): - """ Tests a simple import. """ - mnemonic = "release easy pulp drop select attack false math cook \ -angry spin ostrich round dress acoustic" - prms = ["import", "keys", "from", "mnemonic", "zebra", "--force"] - stdin = mnemonic + "\n\n" - client.run_generic(prms, stdin=stdin) - addr = client.get_known_addresses() - assert addr.wallet["zebra"] == "tz1aGUKE72eN21iWztoDEeH4FeKaxWb7SAUb" - - def test_import_already_present_alias(self, client: Client, mnemonic): - """ Tests that importing fails if the alias is already present. """ - prms = [ - "import", - "keys", - "from", - "mnemonic", - "super_original", - "--force", - ] - stdin = mnemonic + "\n\n" - client.run_generic(prms, stdin=stdin) - prms = ["import", "keys", "from", "mnemonic", "super_original"] - expected_error = "The secret_key alias super_original already exists." - with assert_run_failure(expected_error): - client.run_generic(prms, stdin=stdin) - - def test_import_passphrase(self, client: Client, mnemonic, passphrase): - """ Tests an import where the user specifies a passphrase. """ - stdin = mnemonic + "\n" + passphrase + "\n" - prms = ["import", "keys", "from", "mnemonic", "key", "--force"] - client.run_generic(prms, stdin=stdin) - addr = client.get_known_addresses() - assert addr.wallet["key"] == "tz1QSF4TSVzaosgbaxnFJpRbs7798Skeb8Re" - - def test_encrypted(self, client: Client, mnemonic, passphrase): - """ Tests an import where the user wants to encrypt the key. """ - encrypt_pwd = "imgonnaencryptthiskeysohard" - stdin = ( - mnemonic - + "\n" - + passphrase - + "\n" - + encrypt_pwd - + "\n" - + encrypt_pwd - + "\n" - ) - prms = [ - "import", - "keys", - "from", - "mnemonic", - "cryptkey", - "--encrypt", - "--force", - ] - client.run_generic(prms, stdin=stdin) - addr = client.get_known_addresses() - pkh = addr.wallet["cryptkey"] - secret_key = client.show_address( - "cryptkey", show_secret=True - ).secret_key - assert secret_key is not None - assert secret_key.startswith("encrypted:") - assert pkh == "tz1QSF4TSVzaosgbaxnFJpRbs7798Skeb8Re" - - def test_gen_key_from_menmonic_bad_mnemonic(self, client: Client): - """ Tests that the command fails if the user gives a bad mnemonic. """ - prms = ["import", "keys", "from", "mnemonic", "alias", "--force"] - stdin = "hello\n\n" - expected_error = '"hello" is not a valid BIP39 mnemonic.' - with assert_run_failure(expected_error): - client.run_generic(prms, stdin=stdin) - - -@pytest.mark.usefixtures("encrypted_account_with_tez") -class TestStopLoopPassword: - """Tests that the client stops asking for the password after - three erroneous passwords given by the user""" - - @pytest.mark.parametrize('stdin', ["\n\n\n", "\n\n\nign", "\n\n\npassword"]) - def test_stops_after_three_tries(self, client: Client, stdin): - with assert_run_failure("3 incorrect password attempt"): - client.transfer(0.1, 'encrypted_account', 'bootstrap1', stdin=stdin) - - @pytest.mark.parametrize( - 'stdin', ["password\n", "\npassword\n", "\n\npassword\n"] - ) - def test_password_succeed_before_three_tries(self, client: Client, stdin): - client.transfer(0.1, 'encrypted_account', 'bootstrap1', stdin=stdin) - - -@pytest.mark.client -class TestChainId: - def test_chain_id_block_hash(self, nodeless_client: Client): - block_hash = 'BKyFui5WPY1n3e9aKF3qd2kGBKBtHu3rtm5miYFnUagJC1BdHTF' - prms = ['compute', 'chain', 'id', 'from', 'block', 'hash', block_hash] - assert nodeless_client.run(prms).strip() == 'NetXuwrXPL4VeX5' - - def test_chain_id_seed(self, nodeless_client: Client): - seed = 'choucroute' - prms = ['compute', 'chain', 'id', 'from', 'seed', seed] - assert nodeless_client.run(prms).strip() == 'NetXLGmPi3c5DXf' - - -def _write_config_file( - client: Client, filename: str, config_dict: Optional[dict] -): - """Writes `config_dict` to `filename`. Returns the json effectively - written""" - assert client is not None - assert filename is not None - assert config_dict is not None - - augmented_dict = dict(config_dict) # Copy for safety - # We need to set base_dir, it's required in the config file - augmented_dict["base_dir"] = client.base_dir - with open(filename, 'w') as handle: - json.dump(augmented_dict, handle) - - return augmented_dict - - -def _with_config_file_cmd(config_file: Optional[str], cmd: List[str]): - """Prefixes `cmd` with ["--config-file", config_file] if - config_file is not None""" - return ([_CONFIG_FILE_FLAG, config_file] if config_file else []) + cmd - - -def _gen_assert_msg(flag, sent, received): - result = f"Json sent with --{flag} differs from" - result += " json received" - result += f"\nJson sent is:\n{sent}" - result += f"\nwhile json received is:\n{received}" - - -@pytest.mark.client -@pytest.mark.parametrize('config_dict', _INPUT_CONFIG_FILES) -class TestConfigInit: - def test_config_init( - self, nodeless_client: Client, config_dict: Optional[dict] - ): - """ - Tests that calling - `[--config-file config_dict]? config init -o tmp_file` - works and yields valid json. - """ - try: - out_file = tempfile.mktemp(prefix='tezos-client.config_file') - in_file = None - - if config_dict is not None: - in_file = tempfile.mktemp(prefix='tezos-client.config_file') - _write_config_file(nodeless_client, in_file, config_dict) - - cmd = _with_config_file_cmd( - in_file, ["config", "init", "-o", out_file] - ) - nodeless_client.run(cmd) - # Try loading the file as json, to check it is valid - with open(out_file) as handle: - json.load(handle) - finally: - if in_file is not None: - os.remove(in_file) - os.remove(out_file) - - def test_config_init_roundtrip( - self, nodeless_client: Client, config_dict: Optional[dict] - ): - """Tests that calling `config init -o tmp_file` and - feeding its result to `tezos-client --config-file` works - and yields the same result (i.e. calling `tezos-client - --config-file tmp_file config init -o tmp_file2 yields - a `tmp_file2` that is similar to `tmp_file`). - - `config_dict` specifies the content of the initial config file - to use or None not to specify one. - """ - try: - if config_dict is None: - # Take initial json from default output of `config init` - - tmp_file1 = tempfile.mktemp(prefix='tezos-client.config_file') - cmd = ["config", "init", "-o", tmp_file1] - nodeless_client.run(cmd) - with open(tmp_file1) as handle: - json1 = json.load(handle) - - # Execute an arbitrary effectless command: - list_protos = ["list", "understood", "protocols"] - # This checks that - # `--config-file tmp_file1 arbitrary command` works - cmd = _with_config_file_cmd(tmp_file1, list_protos) - nodeless_client.run(cmd) - else: - # Take initial json from config_dict - - # Write config_dict to a file - tmp_file1 = tempfile.mktemp(prefix='tezos-client.config_file') - json1 = _write_config_file( - nodeless_client, tmp_file1, config_dict - ) - - # Execute `config init -o` - tmp_file2 = tempfile.mktemp(prefix='tezos-client.config_file') - cmd = _with_config_file_cmd( - tmp_file1, ["config", "init", "-o", tmp_file2] - ) - nodeless_client.run(cmd) - - # Load file generated by `config init -o` - with open(tmp_file2) as handle: - json2 = json.load(handle) - - # and finally check that the json generated by `config init -o` - # matches the input data (either the default one or the one - # specified with --config-file) - assert json1 == json2, _gen_assert_msg( - _CONFIG_FILE_FLAG, json1, json2 - ) - finally: - os.remove(tmp_file1) - os.remove(tmp_file2) - - -def _cmd_line_flag_to_json_field(cmd_line_flag: str): - if cmd_line_flag == "--wait": - return "confirmations" - result = cmd_line_flag - if cmd_line_flag.startswith("--"): - result = result[2:] - return result.replace("-", "_") - - -@pytest.mark.client -@pytest.mark.parametrize('config_dict', _INPUT_CONFIG_FILES) -class TestConfigShow: - """ Tests of `tezos-client config show` """ - - def test_config_show( - self, nodeless_client: Client, config_dict: Optional[dict] - ): - """ - Tests that calling `config show` works, with or without - specifying `--config-file` - """ - try: - tmp_file = None - if config_dict is not None: - tmp_file = tempfile.mktemp(prefix='tezos-client.config_file') - _write_config_file(nodeless_client, tmp_file, config_dict) - - cmd = _with_config_file_cmd(tmp_file, ["config", "show"]) - nodeless_client.run(cmd) - finally: - if tmp_file is not None: - os.remove(tmp_file) - - @pytest.mark.parametrize('cmd_line_args', [{}, _CMD_LINE_ARGS]) - def test_config_show_roundtrip( - self, - nodeless_client: Client, - config_dict: Optional[dict], - cmd_line_args: dict, - ): - """ - Tests calling `config show` with or without `--config-file` - and with some command line parameters (`cmd_line_arg`). It - then parses the output to check its valid json and to check - that command line parameters were honored. - - Then it feeds this output to a new call to `--config-file file - config show` and checks that the json returned by this second call - agrees with what was specified by `file`. - - This is a roundtrip test using a small matrix. - """ - try: - in_file1 = None - in_file2 = None - if config_dict is not None: - in_file1 = tempfile.mktemp(prefix='tezos-client.config_file') - _write_config_file(nodeless_client, in_file1, config_dict) - - cmd = [] - # Pass command line parameters - for (flag, value) in cmd_line_args.items(): - cmd += [flag, value] - cmd += ["config", "show"] - cmd = _with_config_file_cmd(in_file1, cmd) - # Take standard output - (stdout, _, _) = nodeless_client.run_generic(cmd) - - output_json1 = json.loads(stdout) - # Verify that command line parameters were honored - for (flag, value) in cmd_line_args.items(): - input_value = cmd_line_args[flag] - assert isinstance(input_value, str) - output_value = output_json1[_cmd_line_flag_to_json_field(flag)] - output_value = str(output_value) - err_msg = ( - f"Value of command line flag {flag} is not honored:" - f" passed {input_value} but" - f" config show yielded {output_value}" - ) - assert output_value == input_value, err_msg - in_file2 = tempfile.mktemp(prefix='tezos-client.config_file') - # Write output of first call to `config show` to disk, - # to pass it to second call below - with open(in_file2, 'w') as handle: - handle.write(json.dumps(output_json1)) - - # Use previous ouput file as input now - cmd = _with_config_file_cmd(in_file2, ["config", "show"]) - (stdout, _, _) = nodeless_client.run_generic(cmd) - - output_json2 = json.loads(stdout) - - # And finally check that the final output matches the input - assert output_json1 == output_json2, _gen_assert_msg( - _CONFIG_FILE_FLAG, output_json1, output_json2 - ) - finally: - for in_file in [in_file1, in_file2]: - if in_file is not None: - os.remove(in_file) - - -@pytest.mark.client -class TestConfigValid: - """ Tests of validity of tezos-client config """ - - def test_config_node_port(self, nodeless_client: Client): - """ - Tests that calling `config show` works, with a valid node port - """ - self._run_config_show_with_node_port(nodeless_client, 8732) - self._run_config_show_with_node_port(nodeless_client, 58732) - pytest.raises( - subprocess.CalledProcessError, - self._run_config_show_with_node_port, - nodeless_client, - 158732, - ) - pytest.raises( - subprocess.CalledProcessError, - self._run_config_show_with_node_port, - nodeless_client, - -8732, - ) - - def test_config_web_port(self, nodeless_client: Client): - """ - Tests that calling `config show` works, with a valid node port - """ - self._run_config_show_with_web_port(nodeless_client, 8732) - self._run_config_show_with_web_port(nodeless_client, 58732) - pytest.raises( - subprocess.CalledProcessError, - self._run_config_show_with_web_port, - nodeless_client, - 158732, - ) - pytest.raises( - subprocess.CalledProcessError, - self._run_config_show_with_web_port, - nodeless_client, - -8732, - ) - - def _run_config_show_with_temp_config_file( - self, nodeless_client: Client, config_dict: dict - ): - try: - tmp_file = tempfile.mktemp(prefix='tezos-client.config_file') - _write_config_file(nodeless_client, tmp_file, config_dict) - - cmd = _with_config_file_cmd(tmp_file, ["config", "show"]) - nodeless_client.run(cmd) - finally: - if tmp_file is not None: - os.remove(tmp_file) - - def _run_config_show_with_node_port( - self, nodeless_client: Client, port: int - ): - config_dict = {"node_port": port} - self._run_config_show_with_temp_config_file( - nodeless_client, config_dict - ) - - def _run_config_show_with_web_port( - self, nodeless_client: Client, port: int - ): - config_dict = {"web_port": port} - self._run_config_show_with_temp_config_file( - nodeless_client, config_dict - ) diff --git a/tests_python/tests_012/test_codec.py b/tests_python/tests_012/test_codec.py deleted file mode 100644 index bb87d8b037f7..000000000000 --- a/tests_python/tests_012/test_codec.py +++ /dev/null @@ -1,23 +0,0 @@ -from typing import Any -import pytest -from codec.codec import Codec -from tools import paths - -CODEC_BIN = paths.TEZOS_HOME + "tezos-codec" - -ENCODINGS = [ - ( - "network_version", - {"p2p_version": 0, "distributed_db_version": 1, "chain_name": "main"}, - ) -] - - -@pytest.mark.codec -class TestCodec: - @pytest.mark.parametrize("encoding_name, data", ENCODINGS) - def test_codec_encode_decode(self, encoding_name: str, data: Any): - codec = Codec(CODEC_BIN) - data_encoded = codec.encode(encoding_name, data_json=data) - data_decoded = codec.decode(encoding_name, data=data_encoded) - assert data_decoded == data diff --git a/tests_python/tests_012/test_contract.py b/tests_python/tests_012/test_contract.py deleted file mode 100644 index 5941681eeb8e..000000000000 --- a/tests_python/tests_012/test_contract.py +++ /dev/null @@ -1,2296 +0,0 @@ -import os -import re -import itertools -from typing import List, Union, Any -import pytest - -from client.client import Client -from tools import utils -from tools.constants import IDENTITIES -from tools.utils import originate -from .contract_paths import ( - CONTRACT_PATH, - ILLTYPED_CONTRACT_PATH, - all_contracts, - all_legacy_contracts, -) - - -ID_SCRIPT_LITERAL = ''' -parameter unit; storage unit; code {CAR; NIL operation; PAIR} -'''.strip() -ID_SCRIPT_HASH = ''' -exprtpyospPfMqcARmu5FGukprC7kbbe4jb4zxFd4Gxrp2vcCPjRNa -'''.strip() - - -@pytest.mark.contract -@pytest.mark.incremental -class TestManager: - def test_manager_origination(self, client: Client, session: dict): - path = os.path.join(CONTRACT_PATH, 'entrypoints', 'manager.tz') - pubkey = IDENTITIES['bootstrap2']['identity'] - originate(client, session, path, f'"{pubkey}"', 1000) - originate( - client, session, path, f'"{pubkey}"', 1000, contract_name="manager2" - ) - - def test_delegatable_origination(self, client: Client, session: dict): - path = os.path.join( - CONTRACT_PATH, 'entrypoints', 'delegatable_target.tz' - ) - pubkey = IDENTITIES['bootstrap2']['identity'] - originate( - client, session, path, f'Pair "{pubkey}" (Pair "hello" 45)', 1000 - ) - - def test_target_with_entrypoints_origination(self, client: Client, session): - path = os.path.join( - CONTRACT_PATH, 'entrypoints', 'big_map_entrypoints.tz' - ) - originate( - client, session, path, 'Pair {} {}', 1000, contract_name='target' - ) - - def test_target_without_entrypoints_origination( - self, client: Client, session - ): - path = os.path.join( - CONTRACT_PATH, 'entrypoints', 'no_entrypoint_target.tz' - ) - originate( - client, - session, - path, - 'Pair "hello" 42', - 1000, - contract_name='target_no_entrypoints', - ) - - def test_target_without_default_origination(self, client: Client, session): - path = os.path.join( - CONTRACT_PATH, 'entrypoints', 'no_default_target.tz' - ) - originate( - client, - session, - path, - 'Pair "hello" 42', - 1000, - contract_name='target_no_default', - ) - - def test_target_with_root_origination(self, client: Client, session): - path = os.path.join(CONTRACT_PATH, 'entrypoints', 'rooted_target.tz') - originate( - client, - session, - path, - 'Pair "hello" 42', - 1000, - contract_name='rooted_target', - ) - - def test_manager_set_delegate(self, client: Client): - client.set_delegate('manager', 'bootstrap2', []) - utils.bake(client, bake_for='bootstrap5') - bootstrap2_pkh = IDENTITIES['bootstrap2']['identity'] - client.set_delegate('delegatable_target', bootstrap2_pkh, []) - utils.bake(client, bake_for='bootstrap5') - delegate = IDENTITIES['bootstrap2']['identity'] - assert client.get_delegate('manager', []).delegate == delegate - assert ( - client.get_delegate('delegatable_target', []).delegate == delegate - ) - client.set_delegate('manager', 'bootstrap3', []) - utils.bake(client, bake_for='bootstrap5') - client.set_delegate('delegatable_target', 'bootstrap3', []) - utils.bake(client, bake_for='bootstrap5') - delegate = IDENTITIES['bootstrap3']['identity'] - assert client.get_delegate('manager', []).delegate == delegate - assert ( - client.get_delegate('delegatable_target', []).delegate == delegate - ) - - def test_manager_withdraw_delegate(self, client: Client): - client.withdraw_delegate('manager', []) - utils.bake(client, bake_for='bootstrap5') - client.withdraw_delegate('delegatable_target', []) - utils.bake(client, bake_for='bootstrap5') - assert client.get_delegate('manager', []).delegate is None - assert client.get_delegate('delegatable_target', []).delegate is None - - def test_transfer_to_manager(self, client: Client): - balance = client.get_mutez_balance('manager') - balance_bootstrap = client.get_mutez_balance('bootstrap2') - amount = 10.001 - amount_mutez = utils.mutez_of_tez(amount) - client.transfer( - amount, - 'bootstrap2', - 'manager', - ['--gas-limit', f'{128 * 15450 + 108}'], - ) - utils.bake(client, bake_for='bootstrap5') - new_balance = client.get_mutez_balance('manager') - new_balance_bootstrap = client.get_mutez_balance('bootstrap2') - fee = 0.000382 - fee_mutez = utils.mutez_of_tez(fee) - assert balance + amount_mutez == new_balance - assert ( - balance_bootstrap - fee_mutez - amount_mutez - == new_balance_bootstrap - ) - - def test_simple_transfer_from_manager_to_implicit(self, client: Client): - balance = client.get_mutez_balance('manager') - balance_bootstrap = client.get_mutez_balance('bootstrap2') - amount = 10.1 - amount_mutez = utils.mutez_of_tez(amount) - client.transfer( - amount, - 'manager', - 'bootstrap2', - ['--gas-limit', f'{128 * 26350 + 12}'], - ) - utils.bake(client, bake_for='bootstrap5') - new_balance = client.get_mutez_balance('manager') - new_balance_bootstrap = client.get_mutez_balance('bootstrap2') - fee = 0.000584 - fee_mutez = utils.mutez_of_tez(fee) - assert balance - amount_mutez == new_balance - assert ( - balance_bootstrap + amount_mutez - fee_mutez - == new_balance_bootstrap - ) - - def test_transfer_from_manager_to_manager(self, client: Client): - balance = client.get_mutez_balance('manager') - balance_dest = client.get_mutez_balance('manager2') - balance_bootstrap = client.get_mutez_balance('bootstrap2') - amount = 10 - amount_mutez = utils.mutez_of_tez(amount) - client.transfer( - amount, - 'manager', - 'manager2', - ['--gas-limit', f'{128 * 44950 + 112}'], - ) - utils.bake(client, bake_for='bootstrap5') - new_balance = client.get_mutez_balance('manager') - new_balance_dest = client.get_mutez_balance('manager2') - new_balance_bootstrap = client.get_mutez_balance('bootstrap2') - fee = 0.000787 - fee_mutez = utils.mutez_of_tez(fee) - assert balance - amount_mutez == new_balance - assert balance_dest + amount_mutez == new_balance_dest - assert balance_bootstrap - fee_mutez == new_balance_bootstrap - - def test_transfer_from_manager_to_default(self, client: Client): - client.transfer( - 10, 'manager', 'bootstrap2', ['--entrypoint', 'default'] - ) - utils.bake(client, bake_for='bootstrap5') - client.transfer(10, 'manager', 'manager', ['--entrypoint', 'default']) - utils.bake(client, bake_for='bootstrap5') - - def test_transfer_from_manager_to_target(self, client: Client): - client.transfer(10, 'manager', 'target', ['--burn-cap', '0.356']) - utils.bake(client, bake_for='bootstrap5') - - def test_transfer_from_manager_to_entrypoint_with_args( - self, client: Client - ): - arg = 'Pair "hello" 42' - # using 'transfer' - client.transfer( - 0, - 'manager', - 'target', - ['--entrypoint', 'add_left', '--arg', arg, '--burn-cap', '0.067'], - ) - utils.bake(client, bake_for='bootstrap5') - client.transfer( - 0, - 'manager', - 'target', - ['--entrypoint', 'mem_left', '--arg', '"hello"'], - ) - utils.bake(client, bake_for='bootstrap5') - - # using 'call' - client.call( - 'manager', - 'target', - ['--entrypoint', 'add_left', '--arg', arg, '--burn-cap', '0.067'], - ) - utils.bake(client, bake_for='bootstrap5') - client.call( - 'manager', - 'target', - ['--entrypoint', 'mem_left', '--arg', '"hello"'], - ) - utils.bake(client, bake_for='bootstrap5') - - def test_transfer_from_manager_no_entrypoint_with_args( - self, client: Client - ): - arg = 'Left Unit' - client.transfer(0, 'manager', 'target_no_entrypoints', ['--arg', arg]) - utils.bake(client, bake_for='bootstrap5') - - client.call('manager', 'target_no_entrypoints', ['--arg', arg]) - utils.bake(client, bake_for='bootstrap5') - - def test_transfer_from_manager_to_no_default_with_args( - self, client: Client - ): - arg = 'Left Unit' - client.transfer(0, 'manager', 'target_no_default', ['--arg', arg]) - utils.bake(client, bake_for='bootstrap5') - - client.call('manager', 'target_no_default', ['--arg', arg]) - utils.bake(client, bake_for='bootstrap5') - - def test_transfer_from_manager_to_rooted_target_with_args( - self, client: Client - ): - arg = 'Left Unit' - client.transfer( - 0, - 'manager', - 'rooted_target', - ['--arg', arg, '--entrypoint', 'root'], - ) - utils.bake(client, bake_for='bootstrap5') - - client.call( - 'manager', 'rooted_target', ['--arg', arg, '--entrypoint', 'root'] - ) - utils.bake(client, bake_for='bootstrap5') - - -# This test to verifies contract execution order. There are 3 -# contracts: Storer, Caller, and Appender. Storer appends its argument -# to storage. Caller calls the list of unit contracts in its -# storage. Appender calls the string contract in its storage with a -# stored argument. -# -# For each test, there is one unique Storer. Each test is -# parameterized by a tree and the expected final storage of the -# Storer. A leaf in the tree is a string. Inner nodes are lists of -# leafs/inner nodes. The test maps maps over this tree to build a -# tree of contracts. Leaf nodes map to Appender contracts calling -# the Storer. Inner nodes map to Caller contract that calling -# children. -# -# Example. Given the tree: ["A", ["B"], "C"], we obtain -# Caller([Appender("A"), Caller([Appender("B")]), Appender("C")]) -# Before the protocol 009, contract execution order was in BFS -# In BFS, Storer would've ended up with storage ACB. -# In DFS, Storer will end up with storage ABC. -@pytest.mark.contract -@pytest.mark.incremental -class TestExecutionOrdering: - STORER = f'{CONTRACT_PATH}/mini_scenarios/execution_order_storer.tz' - CALLER = f'{CONTRACT_PATH}/mini_scenarios/execution_order_caller.tz' - APPENDER = f'{CONTRACT_PATH}/mini_scenarios/execution_order_appender.tz' - - def originate_storer(self, client: Client, session: dict): - origination = originate( - client, session, self.STORER, '""', 0, arguments=['--force'] - ) - session['storer'] = origination.contract - utils.bake(client, bake_for='bootstrap3') - return origination.contract - - def originate_appender( - self, client: Client, session: dict, storer: str, argument: str - ): - origination = originate( - client, - session, - self.APPENDER, - f'Pair "{storer}" "{argument}"', - 0, - contract_name=f'appender-{argument}', - arguments=['--force'], - ) - session[f'appender.{argument}'] = origination.contract - utils.bake(client, bake_for='bootstrap3') - return origination.contract - - def originate_caller( - self, client: Client, session: dict, callees: List[str] - ): - storage = "{" + '; '.join(map('"{}"'.format, callees)) + "}" - origination = originate( - client, - session, - self.CALLER, - storage, - 0, - contract_name=f'caller-{hash(storage)}', - ) - utils.bake(client, bake_for='bootstrap3') - return origination.contract - - @pytest.mark.parametrize( - "tree, expected", - [ - # before 009, the result should be "DABCEFG". - ([["A", "B", "C"], "D", ["E", "F", "G"]], "ABCDEFG"), - # before 009, the result should be "ACB". - ([["A", ["B"], "C"]], "ABC"), - # before 009, the result should be "ABDC". - ([["A", ["B", ["C"], "D"]]], "ABCD"), - ([], ""), - ], - ) - def test_ordering( - self, - client: Client, - session: dict, - # approximation of recursive type annotation - tree: Union[str, List[Any]], - expected: str, - ): - storer = self.originate_storer(client, session) - - def deploy_tree(tree: Union[str, List[Any]]) -> str: - # leaf - if isinstance(tree, str): - # deploy and return caller str - return self.originate_appender(client, session, storer, tree) - # inner node - children = list(map(deploy_tree, tree)) - return self.originate_caller(client, session, children) - - root = deploy_tree(tree) - - client.transfer( - 0, - 'bootstrap2', - root, - ["--burn-cap", "5"], - ) - utils.bake(client, bake_for='bootstrap3') - assert client.get_storage(storer) == '"{}"'.format(expected) - - -@pytest.mark.contract -@pytest.mark.regression -class TestTypecheck: - """Regression testing of Michelson typechecking""" - - @pytest.mark.parametrize("contract", all_contracts()) - def test_typecheck(self, client_regtest: Client, contract): - client = client_regtest - assert contract.endswith( - '.tz' - ), "test contract should have .tz extension" - client.typecheck(os.path.join(CONTRACT_PATH, contract), details=True) - - -@pytest.mark.slow -@pytest.mark.contract -class TestContracts: - """Test type checking errors""" - - @pytest.mark.parametrize("contract", all_legacy_contracts()) - def test_deprecated_typecheck_breaks(self, client, contract): - if contract in [ - "legacy/create_contract.tz", - "legacy/create_contract_flags.tz", - "legacy/create_contract_rootname.tz", - ]: - with utils.assert_run_failure(r'ill-typed script'): - client.typecheck(os.path.join(CONTRACT_PATH, contract)) - else: - with utils.assert_run_failure(r'Use of deprecated instruction'): - client.typecheck(os.path.join(CONTRACT_PATH, contract)) - - @pytest.mark.parametrize("contract", all_legacy_contracts()) - def test_deprecated_typecheck_in_legacy(self, client, contract): - if contract in [ - "legacy/create_contract.tz", - "legacy/create_contract_flags.tz", - "legacy/create_contract_rootname.tz", - ]: - with utils.assert_run_failure(r'ill-typed script'): - client.typecheck( - os.path.join(CONTRACT_PATH, contract), legacy=True - ) - else: - with utils.assert_run_failure(r'Use of deprecated instruction'): - client.typecheck( - os.path.join(CONTRACT_PATH, contract), legacy=True - ) - - @pytest.mark.parametrize( - "contract,error_pattern", - [ - # Even though the interpreter uses a nonempty stack internally, - # the typechecker should not be able to observe it. - ( - "stack_bottom_unfailwithable.tz", - r'wrong stack type for instruction FAILWITH', - ), - ( - "stack_bottom_unrightable.tz", - r'wrong stack type for instruction RIGHT', - ), - ( - "stack_bottom_unleftable.tz", - r'wrong stack type for instruction LEFT', - ), - ( - "stack_bottom_ungetable.tz", - r'wrong stack type for instruction GET', - ), - ( - "stack_bottom_unpairable.tz", - r'wrong stack type for instruction UNPAIR', - ), - ( - "stack_bottom_undug2able.tz", - r'wrong stack type for instruction DUG', - ), - ( - "stack_bottom_undugable.tz", - r'wrong stack type for instruction DUG', - ), - ( - "stack_bottom_undig2able.tz", - r'wrong stack type for instruction DIG', - ), - ( - "stack_bottom_undigable.tz", - r'wrong stack type for instruction DIG', - ), - ( - "stack_bottom_undip2able.tz", - r'wrong stack type for instruction DUP', - ), - ( - "stack_bottom_undipable.tz", - r'wrong stack type for instruction DUP', - ), - ( - "stack_bottom_undup2able.tz", - r'wrong stack type for instruction DUP', - ), - ( - "stack_bottom_undropable.tz", - r'wrong stack type for instruction DROP', - ), - ( - "stack_bottom_unpopable.tz", - r'wrong stack type for instruction DUP', - ), - ( - "stack_bottom_unpopable_in_lambda.tz", - r'wrong stack type for instruction DUP', - ), - # operations cannot be PACKed - ( - "pack_operation.tz", - r'operation type forbidden in parameter, storage and constants', - ), - # big_maps cannot be PACKed - ( - "pack_big_map.tz", - r'big_map or sapling_state type not expected here', - ), - ( - "invalid_self_entrypoint.tz", - r'Contract has no entrypoint named D', - ), - ("contract_annotation_default.tz", r'unexpected annotation'), - # Missing field - ( - "missing_only_storage_field.tz", - r'Missing contract field: storage', - ), - ("missing_only_code_field.tz", r'Missing contract field: code'), - ( - "missing_only_parameter_field.tz", - r'Missing contract field: parameter', - ), - ( - "missing_parameter_and_storage_fields.tz", - r'Missing contract field: parameter', - ), - # Duplicated field - ( - "multiple_parameter_field.tz", - r'duplicate contract field: parameter', - ), - ("multiple_code_field.tz", r'duplicate contract field: code'), - ("multiple_storage_field.tz", r'duplicate contract field: storage'), - # The first duplicated field is reported, storage in this case - ( - "multiple_storage_and_code_fields.tz", - r'duplicate contract field: storage', - ), - # error message for set update on non-comparable type - ( - "set_update_non_comparable.tz", - r'Type nat is not compatible with type list operation', - ), - # error message for the arity of the chain_id type - ( - "chain_id_arity.tz", - r'primitive chain_id expects 0 arguments but is given 1', - ), - # error message for DIP over the limit - ("big_dip.tz", r'expected a positive 10-bit integer'), - # error message for DROP over the limit - ("big_drop.tz", r'expected a positive 10-bit integer'), - # error message for set update on non-comparable type - ( - "set_update_non_comparable.tz", - r'Type nat is not compatible with type list operation', - ), - # error message for attempting to push a value of type never - ("never_literal.tz", r'type never has no inhabitant.'), - # field annotation mismatch with UNPAIR - ( - "unpair_field_annotation_mismatch.tz", - r'The field access annotation does not match', - ), - # COMB, UNCOMB, and DUP cannot take 0 as argument - ("comb0.tz", r"PAIR expects an argument of at least 2"), - ("comb1.tz", r"PAIR expects an argument of at least 2"), - ("uncomb0.tz", r"UNPAIR expects an argument of at least 2"), - ("uncomb1.tz", r"UNPAIR expects an argument of at least 2"), - ("dup0.tz", r"DUP n expects an argument of at least 1"), - ( - "push_big_map_with_id_with_parens.tz", - r"big_map or sapling_state type not expected here", - ), - ( - "push_big_map_with_id_without_parens.tz", - r"primitive PUSH expects 2 arguments but is given 4", - ), - # sapling_state is not packable - ( - "pack_sapling_state.tz", - r"big_map or sapling_state type not expected here", - ), - # sapling_state is not packable - ( - "unpack_sapling_state.tz", - r"big_map or sapling_state type not expected here", - ), - # Ticket duplication attempt - ( - "ticket_dup.tz", - r'ticket nat cannot be used here because it is not duplicable', - ), - # error message for ticket unpack - ("ticket_unpack.tz", r'Ticket in unauthorized position'), - # error message for attempting to use APPLY to capture a ticket - ("ticket_apply.tz", r'Ticket in unauthorized position'), - # error message for attempting to wrap a ticket in a ticket - ( - "ticket_in_ticket.tz", - r'comparable type expected.Type ticket unit is not comparable', - ), - # error message for DIP { FAILWITH } - ( - "dip_failwith.tz", - r'The FAIL instruction must appear in a tail position.', - ), - # error message for MAP { FAILWITH } - ( - "map_failwith.tz", - r'The proper type of the return list cannot be inferred.', - ), - ], - ) - def test_ill_typecheck(self, client: Client, contract, error_pattern): - with utils.assert_run_failure(error_pattern): - client.typecheck(os.path.join(ILLTYPED_CONTRACT_PATH, contract)) - - def test_zero_transfer_to_implicit_contract(self, client): - pubkey = IDENTITIES['bootstrap3']['identity'] - err = ( - 'Transactions of 0ꜩ towards a contract without code are ' - rf'forbidden \({pubkey}\).' - ) - with utils.assert_run_failure(err): - client.transfer(0, 'bootstrap2', 'bootstrap3', []) - - def test_zero_transfer_to_nonexistent_contract(self, client): - nonexistent = "KT1Fcq4inD44aMhmUiTEHR1QMQwJT7p2u641" - err = rf'Contract {nonexistent} does not exist' - with utils.assert_run_failure(err): - client.transfer(0, 'bootstrap2', nonexistent, []) - - -FIRST_EXPLOSION = ''' -{ parameter unit; - storage unit; - code{ DROP; PUSH nat 0 ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DROP ; UNIT ; NIL operation ; PAIR} } -''' - - -# FIRST_EXPLOSION costs a large amount of gas just for typechecking. -# FIRST_EXPLOSION_BIGTYPE type size exceeds the protocol set bound. -FIRST_EXPLOSION_BIGTYPE = ''' -{ parameter unit; - storage unit; - code{ DROP; PUSH nat 0 ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DUP ; PAIR ; - DROP ; UNIT ; NIL operation ; PAIR} } -''' - - -SECOND_EXPLOSION = ''' -{ parameter (list int) ; - storage (list (list (list int))) ; - code { CAR ; DIP { NIL (list int) } ; - DUP ; ITER { DROP ; DUP ; DIP { CONS } } ; - DROP ; DIP { NIL (list (list int)) } ; - DUP ; ITER { DROP ; DUP ; DIP { CONS } } ; - DROP ; NIL operation ; PAIR } } -''' - - -@pytest.mark.incremental -@pytest.mark.contract -class TestView: - def test_deploy_view_lib(self, client, session): - path = f'{CONTRACT_PATH}/opcodes/view_toplevel_lib.tz' - originate(client, session, path, '3', 999) - session['lib'] = session['contract'] - client.bake('bootstrap3', ["--minimal-timestamp"]) - - @pytest.mark.parametrize( - "contract,init_storage,expected", - [ - ('view_op_id', '(Pair 0 0)', 'Pair 10 3'), - ('view_op_add', '42', '13'), - ('view_fib', '0', '55'), - ('view_mutual_recursion', '0', '20'), - ('view_op_nonexistent_func', 'True', 'False'), - ('view_op_nonexistent_addr', 'True', 'False'), - ('view_op_toplevel_inconsistent_input_type', '5', '0'), - ('view_op_toplevel_inconsistent_output_type', 'True', 'False'), - ], - ) - def test_runtime(self, client, session, contract, init_storage, expected): - path = f'{CONTRACT_PATH}/opcodes/' + contract + '.tz' - originate(client, session, path, init_storage, 0) - client.transfer( - 0, - 'bootstrap1', - contract, - [ - "--arg", - "(Pair 10 \"" + session['lib'] + "\")", - '--gas-limit', - '1000000', - "--burn-cap", - "0.1", - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - assert client.get_storage(contract) == expected - - def test_create_contract( - self, - client, - session, - ): - contract = 'create_contract_with_view' - path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' - originate(client, session, path, 'None', 0) - client.transfer( - 0, - 'bootstrap1', - contract, - [ - "--arg", - "Unit", - "--burn-cap", - "0.1", - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - - addr = client.get_storage(contract).split()[1] - contract = 'view_op_constant' - path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' - originate(client, session, path, '2', 0) - expected = "10" - - client.transfer( - 0, - "bootstrap1", - contract, - [ - "--arg", - f"(Pair {expected} {addr})", - "--burn-cap", - "0.1", - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - - assert client.get_storage(contract) == expected - - def test_step_constants(self, client, session): - contract = 'view_op_test_step_contants' - path = f'{CONTRACT_PATH}/opcodes/' + contract + '.tz' - originate(client, session, path, 'None', 0) - client.transfer( - 0, - 'bootstrap1', - contract, - [ - "--arg", - "\"" + session['lib'] + "\"", - '--gas-limit', - '5000', - "--burn-cap", - "0.1", - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - - source = IDENTITIES['bootstrap1']['identity'] - self_address = session['lib'] - sender = session['contract'] - expected = ( - 'Some (Pair (Pair 0 999000000)\n' - + ' (Pair "' - + self_address - + '" "' - + sender - + '")\n' - + ' "' - + source - + '")' - ) - - assert client.get_storage(contract) == expected - - @pytest.mark.parametrize( - "contract", - [ - 'self_after_view', - 'self_after_fib_view', - 'self_after_nonexistent_view', - ], - ) - def test_self(self, client, session, contract): - path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' - lib_address = session['lib'] - originate(client, session, path, f'"{lib_address}"', 1000) - client.bake('bootstrap2', ["--minimal-timestamp"]) - self_address = session['contract'] - client.transfer( - 0, - 'bootstrap1', - contract, - [ - '--arg', - f'"{lib_address}"', - '--burn-cap', - '0.1', - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - assert client.get_storage(contract) == f'"{self_address}"' - - @pytest.mark.parametrize( - "contract", - [ - 'self_address_after_view', - 'self_address_after_fib_view', - 'self_address_after_nonexistent_view', - ], - ) - def test_self_address(self, client, session, contract): - path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' - lib_address = session['lib'] - originate(client, session, path, f'"{lib_address}"', 1000) - client.bake('bootstrap2', ["--minimal-timestamp"]) - self_address = session['contract'] - client.transfer( - 0, - 'bootstrap1', - contract, - [ - '--arg', - f'"{lib_address}"', - '--burn-cap', - '0.1', - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - assert client.get_storage(contract) == f'"{self_address}"' - - @pytest.mark.parametrize( - "contract", - [ - 'sender_after_view', - 'sender_after_fib_view', - 'sender_after_nonexistent_view', - ], - ) - def test_sender(self, client, session, contract): - path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' - lib_address = session['lib'] - originate(client, session, path, f'"{lib_address}"', 1000) - client.bake('bootstrap2', ["--minimal-timestamp"]) - sender = IDENTITIES['bootstrap1']['identity'] - client.transfer( - 0, - 'bootstrap1', - contract, - [ - '--arg', - f'"{lib_address}"', - '--burn-cap', - '0.1', - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - assert client.get_storage(contract) == f'"{sender}"' - - @pytest.mark.parametrize( - "contract", - [ - 'balance_after_view', - 'balance_after_fib_view', - 'balance_after_nonexistent_view', - ], - ) - def test_balance_after_view(self, client, session, contract): - path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' - lib_address = session['lib'] - initial_balance = 1000 - originate(client, session, path, '0', initial_balance) - client.bake('bootstrap2', ["--minimal-timestamp"]) - amount = 10 - client.transfer( - amount, - 'bootstrap1', - contract, - [ - '--arg', - f'"{lib_address}"', - '--burn-cap', - '0.1', - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - expected_balance = initial_balance + amount - assert ( - client.get_storage(contract) - == f'{utils.mutez_of_tez(expected_balance)}' - ) - - @pytest.mark.parametrize( - "contract", - [ - 'amount_after_view', - 'amount_after_fib_view', - 'amount_after_nonexistent_view', - ], - ) - def test_amount_after_view(self, client, session, contract): - path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' - lib_address = session['lib'] - originate(client, session, path, '0', 1000) - client.bake('bootstrap2', ["--minimal-timestamp"]) - amount = 3 - client.transfer( - amount, - 'bootstrap1', - contract, - [ - '--arg', - f'"{lib_address}"', - '--burn-cap', - '0.1', - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - assert client.get_storage(contract) == f'{utils.mutez_of_tez(amount)}' - - def test_recursion(self, client, session): - contract = 'view_rec' - path = f'{CONTRACT_PATH}/opcodes/' + contract + '.tz' - originate(client, session, path, 'Unit', 0) - with utils.assert_run_failure( - "Gas limit exceeded during typechecking or execution." - ): - client.transfer( - 0, - 'bootstrap1', - contract, - [ - "--arg", - "Unit", - '--gas-limit', - '5000', - ], - ) - client.bake('bootstrap2', ["--minimal-timestamp"]) - - @pytest.mark.parametrize( - "contract,expected_error", - [ - ( - 'view_toplevel_bad_type', - 'the return of a view block did not match the expected type.', - ), - ( - 'view_toplevel_bad_return_type', - 'the return of a view block did not match the expected type.', - ), - ( - 'view_toplevel_bad_input_type', - 'operator ADD is undefined between string', - ), - ( - 'view_toplevel_invalid_arity', - 'primitive view expects 4 arguments', - ), - ( - 'view_toplevel_bad_name_too_long', - 'exceeds the maximum length of 31 characters', - ), - ( - 'view_toplevel_bad_name_invalid_type', - 'only a string can be used here', - ), - ( - 'view_toplevel_bad_name_non_printable_char', - 'string \\[a-zA-Z0-9_.%@\\]', - ), - ( - 'view_toplevel_bad_name_invalid_char_set', - 'string \\[a-zA-Z0-9_.%@\\]', - ), - ( - 'view_toplevel_duplicated_name', - 'the name of view in toplevel should be unique', - ), - ( - 'view_toplevel_dupable_type_output', - 'Ticket in unauthorized position', - ), - ( - 'view_toplevel_dupable_type_input', - 'Ticket in unauthorized position', - ), - ( - 'view_toplevel_lazy_storage_input', - 'big_map or sapling_state type not expected here', - ), - ( - 'view_toplevel_lazy_storage_output', - 'big_map or sapling_state type not expected here', - ), - ('view_op_invalid_arity', 'primitive VIEW expects 2 arguments'), - ( - 'view_op_bad_name_invalid_type', - 'unexpected int, only a string', - ), - ( - 'view_op_bad_name_too_long', - 'exceeds the maximum length of 31 characters', - ), - ( - 'view_op_bad_name_non_printable_char', - 'string \\[a-zA-Z0-9_.%@\\]', - ), - ( - 'view_op_bad_name_invalid_char_set', - 'string \\[a-zA-Z0-9_.%@\\]', - ), - ( - 'view_op_bad_return_type', - 'two branches don\'t end with the same stack type', - ), - ( - 'view_op_dupable_type', - 'Ticket in unauthorized position', - ), - ( - 'view_op_lazy_storage', - 'big_map or sapling_state type not expected here', - ), - ], - ) - def test_typechecking_error( - self, client, session, contract, expected_error - ): - path = f'{CONTRACT_PATH}/ill_typed/' + contract + '.tz' - with utils.assert_run_failure(expected_error): - originate(client, session, path, '4', 0) - - -@pytest.mark.contract -class TestGasBound: - def test_write_contract(self, tmpdir, session: dict): - items = { - 'first_explosion.tz': FIRST_EXPLOSION, - 'first_explosion_bigtype.tz': FIRST_EXPLOSION_BIGTYPE, - 'second_explosion.tz': SECOND_EXPLOSION, - }.items() - for name, script in items: - contract = f'{tmpdir}/{name}' - with open(contract, 'w') as contract_file: - contract_file.write(script) - session[name] = contract - - def test_originate_first_explosion(self, client: Client, session: dict): - name = 'first_explosion.tz' - contract = session[name] - client.typecheck(contract) - args = ['-G', f'{1461}', '--burn-cap', '10'] - - expected_error = "Gas limit exceeded during typechecking or execution" - with utils.assert_run_failure(expected_error): - client.originate(f'{name}', 0, 'bootstrap1', contract, args) - - def test_originate_big_type(self, client: Client, session: dict): - name = 'first_explosion_bigtype.tz' - contract = session[name] - - expected_error = "type exceeded maximum type size" - with utils.assert_run_failure(expected_error): - client.typecheck(contract) - - def test_originate_second_explosion(self, client: Client, session: dict): - name = 'second_explosion.tz' - contract = session[name] - storage = '{}' - inp = '{1;2;3;4;5;6;7;8;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1}' - client.run_script(contract, storage, inp) - - def test_originate_second_explosion_fail( - self, client: Client, session: dict - ): - name = 'second_explosion.tz' - contract = session[name] - storage = '{}' - inp = ( - '{1;2;3;4;5;6;7;8;9;0;1;2;3;4;5;6;7;1;1;1;1;1;1;1;1;1;1;1' - + ';1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1}' - ) - - expected_error = ( - "Cannot serialize the resulting storage" - + " value within the provided gas bounds." - ) - with utils.assert_run_failure(expected_error): - client.run_script(contract, storage, inp, gas=9290) - - def test_typecheck_map_dup_key(self, client: Client): - - expected_error = ( - 'Map literals cannot contain duplicate' - + ' keys, however a duplicate key was found' - ) - with utils.assert_run_failure(expected_error): - client.typecheck_data('{ Elt 0 1 ; Elt 0 1}', '(map nat nat)') - - def test_typecheck_map_bad_ordering(self, client: Client): - - expected_error = ( - "Keys in a map literal must be in strictly" - + " ascending order, but they were unordered in literal" - ) - with utils.assert_run_failure(expected_error): - client.typecheck_data( - '{ Elt 0 1 ; Elt 10 1 ; Elt 5 1 }', '(map nat nat)' - ) - - def test_typecheck_set_bad_ordering(self, client: Client): - - expected_error = ( - "Values in a set literal must be in strictly" - + " ascending order, but they were unordered in literal" - ) - with utils.assert_run_failure(expected_error): - client.typecheck_data('{ "A" ; "C" ; "B" }', '(set string)') - - def test_typecheck_set_no_duplicates(self, client: Client): - expected_error = ( - "Set literals cannot contain duplicate values," - + " however a duplicate value was found" - ) - with utils.assert_run_failure(expected_error): - client.typecheck_data('{ "A" ; "B" ; "B" }', '(set string)') - - -@pytest.mark.incremental -@pytest.mark.contract -class TestChainId: - def test_chain_id_opcode(self, client: Client, session: dict): - path = os.path.join(CONTRACT_PATH, 'opcodes', 'chain_id.tz') - originate(client, session, path, 'Unit', 0) - client.call('bootstrap2', "chain_id", []) - utils.bake(client, bake_for='bootstrap5') - - def test_chain_id_authentication_origination(self, client: Client, session): - path = os.path.join( - CONTRACT_PATH, 'mini_scenarios', 'authentication.tz' - ) - pubkey = IDENTITIES['bootstrap1']['public'] - originate(client, session, path, f'Pair 0 "{pubkey}"', 1000) - utils.bake(client, bake_for='bootstrap5') - - def test_chain_id_authentication_first_run( - self, client: Client, session: dict - ): - destination = IDENTITIES['bootstrap2']['identity'] - operation = ( - '{DROP; NIL operation; ' - + f'PUSH address "{destination}"; ' - + 'CONTRACT unit; ASSERT_SOME; PUSH mutez 1000; UNIT; ' - + 'TRANSFER_TOKENS; CONS}' - ) - chain_id = client.rpc('get', 'chains/main/chain_id') - contract_address = session['contract'] - packed = client.pack( - f'Pair (Pair "{chain_id}" "{contract_address}") ' - + f'(Pair {operation} 0)', - 'pair (pair chain_id address)' - + '(pair (lambda unit (list operation)) nat)', - ) - signature = client.sign_bytes_of_string(packed, "bootstrap1") - client.call( - 'bootstrap2', - 'authentication', - ['--arg', f'Pair {operation} \"{signature}\"'], - ) - utils.bake(client, bake_for='bootstrap5') - - -@pytest.mark.incremental -@pytest.mark.contract -class TestBigMapToSelf: - def test_big_map_to_self_origination(self, client: Client, session: dict): - path = os.path.join(CONTRACT_PATH, 'opcodes', 'big_map_to_self.tz') - originate(client, session, path, '{}', 0) - utils.bake(client, bake_for='bootstrap5') - - def test_big_map_to_self_transfer(self, client: Client): - client.call('bootstrap2', "big_map_to_self", []) - utils.bake(client, bake_for='bootstrap5') - - client.transfer(0, 'bootstrap2', "big_map_to_self", []) - utils.bake(client, bake_for='bootstrap5') - - -@pytest.mark.incremental -@pytest.mark.contract -class TestNonRegression: - """Test contract-related non-regressions""" - - def test_issue_242_originate(self, client: Client, session: dict): - path = os.path.join(CONTRACT_PATH, 'non_regression', 'bug_262.tz') - originate(client, session, path, 'Unit', 1) - - def test_issue_242_assert_balance(self, client: Client): - assert client.get_balance('bug_262') == 1 - - -@pytest.mark.incremental -@pytest.mark.contract -class TestMiniScenarios: - """Test mini scenarios""" - - # replay.tz related tests - def test_replay_originate(self, client: Client, session: dict): - path = os.path.join(CONTRACT_PATH, 'mini_scenarios', 'replay.tz') - originate(client, session, path, 'Unit', 0) - - def test_replay_transfer_fail(self, client: Client): - with utils.assert_run_failure("Internal operation replay attempt"): - client.transfer(10, "bootstrap1", "replay", []) - - # create_contract.tz related tests - def test_create_contract_originate(self, client: Client, session: dict): - path = os.path.join( - CONTRACT_PATH, 'mini_scenarios', 'create_contract.tz' - ) - originate(client, session, path, 'Unit', 1000) - - def test_create_contract_balance(self, client: Client): - assert client.get_balance('create_contract') == 1000 - - def test_create_contract_perform_creation(self, client: Client): - transfer_result = client.transfer( - 0, - "bootstrap1", - "create_contract", - ['-arg', 'None', '--burn-cap', '10'], - ) - utils.bake(client, bake_for='bootstrap5') - pattern = r"New contract (\w*) originated" - match = re.search(pattern, transfer_result.client_output) - assert match is not None - kt_1 = match.groups()[0] - assert client.get_storage(kt_1) == '"abcdefg"' - assert client.get_balance(kt_1) == 100 - assert client.get_balance('create_contract') == 900 - - # Originates a contract that when called, creates a contract with a - # rootname annotation. Such annotations comes in two flavors, thus the - # parameterization. Then calls the first contract and verifies the - # existence and type of the root entrypoint of the create contract. - @pytest.mark.parametrize( - "contract", - [ - 'create_contract_rootname.tz', - 'create_contract_rootname_alt.tz', - ], - ) - def test_create_contract_rootname_originate( - self, client: Client, session: dict, contract - ): - path = os.path.join(CONTRACT_PATH, 'opcodes', contract) - origination_res = originate(client, session, path, 'None', 1000) - - transfer_result = client.transfer( - 0, - "bootstrap1", - origination_res.contract, - ['-arg', 'Unit', '--burn-cap', '10'], - ) - utils.bake(client, bake_for='bootstrap5') - - pattern = r"New contract (\w*) originated" - match = re.search(pattern, transfer_result.client_output) - assert match is not None - kt_1 = match.groups()[0] - - entrypoint_type = client.get_contract_entrypoint_type( - 'root', kt_1 - ).entrypoint_type - - assert entrypoint_type == 'unit', ( - 'the entrypoint my_root of the originated contract should exist' - 'with type unit' - ) - - # default_account.tz related tests - def test_default_account_originate(self, client: Client, session: dict): - path = os.path.join( - CONTRACT_PATH, 'mini_scenarios', 'default_account.tz' - ) - originate(client, session, path, 'Unit', 1000) - - def test_default_account_transfer_then_bake(self, client: Client): - tz1 = IDENTITIES['bootstrap4']['identity'] - client.transfer( - 0, - "bootstrap1", - "default_account", - ['-arg', f'"{tz1}"', '--burn-cap', '10'], - ) - utils.bake(client, bake_for='bootstrap5') - account = 'tz1SuakBpFdG9b4twyfrSMqZzruxhpMeSrE5' - client.transfer( - 0, - "bootstrap1", - "default_account", - ['-arg', f'"{account}"', '--burn-cap', '10'], - ) - utils.bake(client, bake_for='bootstrap5') - assert client.get_balance(account) == 100 - - # Test bytes, SHA252, CHECK_SIGNATURE - def test_reveal_signed_preimage_originate( - self, client: Client, session: dict - ): - path = os.path.join( - CONTRACT_PATH, 'mini_scenarios', 'reveal_signed_preimage.tz' - ) - byt = ( - '0x9995c2ef7bcc7ae3bd15bdd9b02' - + 'dc6e877c27b26732340d641a4cbc6524813bb' - ) - sign = 'p2pk66uq221795tFxT7jfNmXtBMdjMf6RAaxRTwv1dbuSHbH6yfqGwz' - storage = f'(Pair {byt} "{sign}")' - originate(client, session, path, storage, 1000) - - def test_wrong_preimage(self, client: Client): - byt = ( - '0x050100000027566f756c657a2d766f75732' - + '0636f75636865722061766563206d6f692c20636520736f6972' - ) - sign = ( - 'p2sigvgDSBnN1bUsfwyMvqpJA1cFhE5s5oi7SetJ' - + 'VQ6LJsbFrU2idPvnvwJhf5v9DhM9ZTX1euS9DgWozVw6BTHiK9VcQVpAU8' - ) - arg = f'(Pair {byt} "{sign}")' - - # We check failure of ASSERT_CMPEQ in the script. - with utils.assert_run_failure("At line 8 characters 9 to 21"): - client.transfer( - 0, - "bootstrap1", - "reveal_signed_preimage", - ['-arg', arg, '--burn-cap', '10'], - ) - - def test_wrong_signature(self, client: Client): - byt = ( - '0x050100000027566f756c657a2d766f757320636' - + 'f75636865722061766563206d6f692c20636520736f6972203f' - ) - sign = ( - 'p2sigvgDSBnN1bUsfwyMvqpJA1cFhE5s5oi7SetJVQ6' - + 'LJsbFrU2idPvnvwJhf5v9DhM9ZTX1euS9DgWozVw6BTHiK9VcQVpAU8' - ) - arg = f'(Pair {byt} "{sign}")' - - # We check failure of CHECK_SIGNATURE ; ASSERT in the script. - with utils.assert_run_failure("At line 15 characters 9 to 15"): - client.transfer( - 0, - "bootstrap1", - "reveal_signed_preimage", - ['-arg', arg, '--burn-cap', '10'], - ) - - def test_good_preimage_and_signature(self, client: Client): - byt = ( - '0x050100000027566f756c657a2d766f757320636f7563' - + '6865722061766563206d6f692c20636520736f6972203f' - ) - sign = ( - 'p2sigsceCzcDw2AeYDzUonj4JT341WC9Px4wdhHBxbZcG1F' - + 'hfqFVuG7f2fGCzrEHSAZgrsrQWpxduDPk9qZRgrpzwJnSHC3gZJ' - ) - arg = f'(Pair {byt} "{sign}")' - client.transfer( - 0, - "bootstrap1", - "reveal_signed_preimage", - ['-arg', arg, '--burn-cap', '10'], - ) - utils.bake(client, bake_for='bootstrap5') - - # Test vote_for_delegate - def test_vote_for_delegate_originate(self, client: Client, session: dict): - b_3 = IDENTITIES['bootstrap3']['identity'] - b_4 = IDENTITIES['bootstrap4']['identity'] - path = os.path.join( - CONTRACT_PATH, 'mini_scenarios', 'vote_for_delegate.tz' - ) - storage = f'''(Pair (Pair "{b_3}" None) (Pair "{b_4}" None))''' - originate(client, session, path, storage, 1000) - assert client.get_delegate('vote_for_delegate').delegate is None - - def test_vote_for_delegate_wrong_identity1(self, client: Client): - # We check failure of CHECK_SIGNATURE ; ASSERT in the script. - with utils.assert_run_failure("At line 15 characters 57 to 61"): - client.transfer( - 0, - "bootstrap1", - "vote_for_delegate", - ['-arg', 'None', '--burn-cap', '10'], - ) - - def test_vote_for_delegate_wrong_identity2(self, client: Client): - # We check failure of CHECK_SIGNATURE ; ASSERT in the script. - with utils.assert_run_failure("At line 15 characters 57 to 61"): - client.transfer( - 0, - "bootstrap2", - "vote_for_delegate", - ['-arg', 'None', '--burn-cap', '10'], - ) - - def test_vote_for_delegate_b3_vote_for_b5(self, client: Client): - b_5 = IDENTITIES['bootstrap5']['identity'] - client.transfer( - 0, - "bootstrap3", - "vote_for_delegate", - ['-arg', f'(Some "{b_5}")', '--burn-cap', '10'], - ) - utils.bake(client, bake_for='bootstrap5') - storage = client.get_storage('vote_for_delegate') - assert re.search(b_5, storage) - - def test_vote_for_delegate_still_no_delegate1(self, client: Client): - assert client.get_delegate('vote_for_delegate').delegate is None - - def test_vote_for_delegate_b4_vote_for_b2(self, client: Client): - b_2 = IDENTITIES['bootstrap2']['identity'] - client.transfer( - 0, - "bootstrap4", - "vote_for_delegate", - ['-arg', f'(Some "{b_2}")', '--burn-cap', '10'], - ) - utils.bake(client, bake_for='bootstrap5') - storage = client.get_storage('vote_for_delegate') - assert re.search(b_2, storage) - - def test_vote_for_delegate_still_no_delegate2(self, client: Client): - assert client.get_delegate('vote_for_delegate').delegate is None - - def test_vote_for_delegate_b4_vote_for_b5(self, client: Client): - b_5 = IDENTITIES['bootstrap5']['identity'] - client.transfer( - 0, - "bootstrap4", - "vote_for_delegate", - ['-arg', f'(Some "{b_5}")', '--burn-cap', '10'], - ) - utils.bake(client, bake_for='bootstrap5') - storage = client.get_storage('vote_for_delegate') - assert re.search(b_5, storage) - - def test_vote_for_delegate_has_delegate(self, client: Client): - b_5 = IDENTITIES['bootstrap5']['identity'] - result = client.get_delegate('vote_for_delegate') - assert result.delegate == b_5 - - def test_multiple_entrypoints_counter(self, session: dict, client: Client): - path = os.path.join( - CONTRACT_PATH, 'mini_scenarios', 'multiple_entrypoints_counter.tz' - ) - - storage = 'None' - - # originate contract - originate(client, session, path, storage, 0) - utils.bake(client, bake_for='bootstrap5') - - # call contract: creates the internal contract and calls it. - client.transfer( - 0, - 'bootstrap1', - 'multiple_entrypoints_counter', - ['--burn-cap', '10'], - ) - utils.bake(client, bake_for='bootstrap5') - assert client.get_storage('multiple_entrypoints_counter') == 'None', ( - "The storage of the multiple_entrypoints_counter contract" - " should be None" - ) - - # Test CONTRACT with/without entrypoint annotation on literal address - # parameters with/without entrypoint annotation - def test_originate_simple_entrypoints(self, session: dict, client: Client): - """originates the contract simple_entrypoints.tz - with entrypoint %A of type unit used in - test_simple_entrypoints""" - - contract_target = os.path.join( - CONTRACT_PATH, 'entrypoints', 'simple_entrypoints.tz' - ) - originate(client, session, contract_target, 'Unit', 0) - utils.bake(client, bake_for='bootstrap5') - - @pytest.mark.parametrize( - 'contract_annotation, contract_type, param, expected_storage', - [ - # tests passing adr to CONTRACT %A unit - # where adr has an entrypoint %A of type unit, is allowed. - ('%A', 'unit', '"{adr}"', '(Some "{adr}%A")'), - ('%B', 'string', '"{adr}"', '(Some "{adr}%B")'), - ('%C', 'nat', '"{adr}"', '(Some "{adr}%C")'), - # tests passing adr%A to CONTRACT %A unit: redundant specification - # of entrypoint not allowed so CONTRACT returns None - ('%A', 'unit', '"{adr}%A"', 'None'), - ('%A', 'unit', '"{adr}%B"', 'None'), - ('%A', 'unit', '"{adr}%D"', 'None'), - ('%A', 'unit', '"{adr}%A"', 'None'), - ('%B', 'unit', '"{adr}%A"', 'None'), - ('%D', 'unit', '"{adr}%A"', 'None'), - # tests passing adr%A to CONTRACT unit: - # where adr has an entrypoint %A of type unit, is allowed. - ('', 'unit', '"{adr}%A"', '(Some "{adr}%A")'), - ('', 'string', '"{adr}%B"', '(Some "{adr}%B")'), - ('', 'nat', '"{adr}%C"', '(Some "{adr}%C")'), - # tests passing adr%B to CONTRACT unit: - # as entrypoint %B of simple_entrypoints.tz has type string, - # CONTRACT will return None. - ('', 'unit', '"{adr}%B"', 'None'), - # tests passing adr%D to CONTRACT unit: - # as entrypoint %D does not exist in simple_entrypoints.tz, - # CONTRACT will return None. - ('', 'unit', '"{adr}%D"', 'None'), - # tests passing adr to CONTRACT unit: - # as adr does not have type unit, CONTRACT returns None. - ('', 'unit', '"{adr}"', 'None'), - # entrypoint that does not exist - ('%D', 'unit', '"{adr}"', 'None'), - # ill-typed entrypoints - ('%A', 'int', '"{adr}"', 'None'), - ('%B', 'unit', '"{adr}"', 'None'), - ('%C', 'int', '"{adr}"', 'None'), - ], - ) - def test_simple_entrypoints( - self, - session, - client, - contract_annotation, - contract_type, - param, - expected_storage, - ): - contract = f'''parameter address; -storage (option address); -code {{ - CAR; - CONTRACT {contract_annotation} {contract_type}; - IF_SOME {{ ADDRESS; SOME }} {{ NONE address; }}; - NIL operation; - PAIR - }};''' - - param = param.format(adr=session['contract']) - expected_storage = expected_storage.format(adr=session['contract']) - run_script_res = client.run_script(contract, 'None', param, file=False) - assert run_script_res.storage == expected_storage - - -@pytest.mark.contract -class TestComparables: - def test_comparable_unit(self, client): - client.typecheck_data('{}', '(set unit)') - client.typecheck_data('{Unit}', '(set unit)') - - def test_comparable_options(self, client): - client.typecheck_data('{}', '(set (option nat))') - client.typecheck_data('{None; Some 1; Some 2}', '(set (option int))') - utils.assert_typecheck_data_failure( - client, '{Some "foo"; Some "bar"}', '(set (option string))' - ) - utils.assert_typecheck_data_failure( - client, '{Some Unit; None}', '(set (option unit))' - ) - - def test_comparable_unions(self, client): - client.typecheck_data('{}', '(set (or unit bool))') - client.typecheck_data( - '{Left 3; Left 4; Right "bar"; Right "foo"}', - '(set (or nat string))', - ) - utils.assert_typecheck_data_failure( - client, '{Left 2; Left 1}', '(set (or mutez unit))' - ) - utils.assert_typecheck_data_failure( - client, '{Right True; Right False}', '(set (or unit bool))' - ) - utils.assert_typecheck_data_failure( - client, '{Right 0; Left 1}', '(set (or nat nat))' - ) - - def test_comparable_pair(self, client: Client): - # tests that comb pairs are comparable and that the order is the - # expected one - client.typecheck_data('{}', '(set (pair nat string))') - client.typecheck_data('{Pair 0 "foo"}', '(set (pair nat string))') - client.typecheck_data( - '{Pair 0 "foo"; Pair 1 "bar"}', '(set (pair nat string))' - ) - client.typecheck_data( - '{Pair 0 "bar"; Pair 0 "foo"; \ - Pair 1 "bar"; Pair 1 "foo"}', - '(set (pair nat string))', - ) - client.typecheck_data('{}', '(set (pair nat (pair string bytes)))') - - client.typecheck_data('{}', '(map (pair nat string) unit)') - client.typecheck_data( - '{Elt (Pair 0 "foo") Unit}', '(map (pair nat string) unit)' - ) - client.typecheck_data( - '{Elt (Pair 0 "foo") Unit; \ - Elt (Pair 1 "bar") Unit}', - '(map (pair nat string) unit)', - ) - client.typecheck_data( - '{Elt (Pair 0 "bar") Unit; \ - Elt (Pair 0 "foo") Unit; \ - Elt (Pair 1 "bar") Unit; \ - Elt (Pair 1 "foo") Unit}', - '(map (pair nat string) unit)', - ) - client.typecheck_data('{}', '(map (pair nat (pair string bytes)) unit)') - - client.typecheck_data('{}', '(big_map (pair nat string) unit)') - client.typecheck_data( - '{Elt (Pair 0 "foo") Unit}', '(big_map (pair nat string) unit)' - ) - client.typecheck_data( - '{Elt (Pair 0 "foo") Unit; \ - Elt (Pair 1 "bar") Unit}', - '(big_map (pair nat string) unit)', - ) - client.typecheck_data( - '{Elt (Pair 0 "bar") Unit; \ - Elt (Pair 0 "foo") Unit; \ - Elt (Pair 1 "bar") Unit; \ - Elt (Pair 1 "foo") Unit}', - '(big_map (pair nat string) unit)', - ) - client.typecheck_data( - '{}', '(big_map (pair nat (pair string bytes)) unit)' - ) - client.typecheck_data('{}', '(set (pair (pair nat nat) nat))') - client.typecheck_data( - '{}', - '(set (pair (pair int nat) \ - (pair bool bytes)))', - ) - - def test_order_of_pairs(self, client: Client): - # tests that badly-ordered set literals are rejected - utils.assert_typecheck_data_failure( - client, '{Pair 0 "foo"; Pair 0 "bar"}', '(set (pair nat string))' - ) - utils.assert_typecheck_data_failure( - client, '{Pair 1 "bar"; Pair 0 "foo"}', '(set (pair nat string))' - ) - - def test_comparable_chain_id(self, client): - client.typecheck_data('{}', '(set chain_id)') - chain1 = client.rpc('get', 'chains/main/chain_id') - chain2 = 'NetXZVhNXbDTx5M' - utils.assert_typecheck_data_failure( - client, - '{"' + f'{chain1}' + '"; "' + f'{chain2}' + '"}', - '(set chain_id)', - ) - client.typecheck_data( - '{"' + f'{chain2}' + '"; "' + f'{chain1}' + '"}', '(set chain_id)' - ) - - def test_comparable_signature(self, client): - client.typecheck_data('{}', '(set signature)') - packed = client.pack('Unit', 'unit') - sig1 = client.sign_bytes_of_string(packed, "bootstrap1") - sig2 = client.sign_bytes_of_string(packed, "bootstrap2") - utils.assert_typecheck_data_failure( - client, - '{"' + f'{sig1}' + '"; "' + f'{sig2}' + '"}', - '(set signature)', - ) - client.typecheck_data( - '{"' + f'{sig2}' + '"; "' + f'{sig1}' + '"}', '(set signature)' - ) - - def test_comparable_key(self, client): - pubkey1 = IDENTITIES['bootstrap1']['public'] - pubkey2 = IDENTITIES['bootstrap2']['public'] - client.typecheck_data('{}', '(set key)') - utils.assert_typecheck_data_failure( - client, - '{"' + f'{pubkey1}' + '"; "' + f'{pubkey2}' + '"}', - '(set key)', - ) - client.typecheck_data( - '{"' + f'{pubkey2}' + '"; "' + f'{pubkey1}' + '"}', '(set key)' - ) - - def test_comparable_key_different_schemes(self, client): - client.gen_key('sk1', ['--sig', 'ed25519']) - key1 = client.show_address('sk1').public_key - - client.gen_key('sk2', ['--sig', 'secp256k1']) - key2 = client.show_address('sk2').public_key - - client.gen_key('sk3', ['--sig', 'p256']) - key3 = client.show_address('sk3').public_key - - # Three public keys of the three different signature schemes, ordered - client.typecheck_data( - '{"' + key1 + '"; "' + key2 + '"; "' + key3 + '"}', '(set key)' - ) - - # Test all orderings that do not respect the comparable order - utils.assert_typecheck_data_failure( - client, - '{"' + key1 + '"; "' + key3 + '"; "' + key2 + '"}', - '(set key)', - ) - - utils.assert_typecheck_data_failure( - client, - '{"' + key2 + '"; "' + key1 + '"; "' + key3 + '"}', - '(set key)', - ) - - utils.assert_typecheck_data_failure( - client, - '{"' + key2 + '"; "' + key3 + '"; "' + key1 + '"}', - '(set key)', - ) - - utils.assert_typecheck_data_failure( - client, - '{"' + key3 + '"; "' + key1 + '"; "' + key2 + '"}', - '(set key)', - ) - - utils.assert_typecheck_data_failure( - client, - '{"' + key3 + '"; "' + key2 + '"; "' + key1 + '"}', - '(set key)', - ) - - -@pytest.mark.contract -class TestTypecheckingErrors: - def test_big_map_arity_error(self, client: Client): - error_pattern = ( - 'primitive EMPTY_BIG_MAP expects 2 arguments but is given 1.' - ) - with utils.assert_run_failure(error_pattern): - client.typecheck( - os.path.join(CONTRACT_PATH, 'ill_typed', 'big_map_arity.tz') - ) - - -BAD_ANNOT_TEST = ''' -parameter bytes; -storage (option (lambda unit unit)); -code { CAR; UNPACK (lambda unit unit); NIL operation; PAIR} -''' - - -@pytest.mark.incremental -@pytest.mark.contract -class TestBadAnnotation: - def test_write_contract_bad_annot(self, tmpdir, session: dict): - name = 'bad_annot.tz' - contract = f'{tmpdir}/{name}' - script = BAD_ANNOT_TEST - with open(contract, 'w') as contract_file: - contract_file.write(script) - session[name] = contract - - def test_bad_annotation(self, client: Client, session: dict): - name = 'bad_annot.tz' - contract = session[name] - - # This was produced by running "tezos-client hash data '{ UNIT - # ; PAIR ; CAR %faa }' of type 'lambda unit unit'" and - # replacing the two last bytes (that correspond to the two - # 'a's at the end of the annotation) by the 0xff byte which is - # not a valid UTF8-encoding of a string - parameter = '0x05020000000e034f03420416000000042566ffff' - - res = client.run_script(contract, 'None', parameter) - assert res.storage == 'None' - - -@pytest.mark.contract -class TestOrderInTopLevelDoesNotMatter: - @pytest.fixture - def contract_splitted_in_top_level_elements(self): - return [ - "parameter nat", - "storage unit", - "code { CDR; NIL operation; PAIR }", - ] - - def test_shuffle( - self, client: Client, contract_splitted_in_top_level_elements - ): - """ - Test that the storage, code, and parameter sections can appear in any - order in a contract script. - """ - for shuffled_list in itertools.permutations( - contract_splitted_in_top_level_elements - ): - contract = ";\n".join(shuffled_list) - client.typecheck(contract, file=False) - - -@pytest.mark.incremental -@pytest.mark.contract -@pytest.mark.regression -class TestSelfAddressTransfer: - def test_self_address_originate_sender( - self, client_regtest_scrubbed, session - ): - client = client_regtest_scrubbed - path = os.path.join( - CONTRACT_PATH, 'mini_scenarios', 'self_address_sender.tz' - ) - originate(client, session, path, 'Unit', 0) - - def test_self_address_originate_receiver( - self, client_regtest_scrubbed, session - ): - client = client_regtest_scrubbed - path = os.path.join( - CONTRACT_PATH, 'mini_scenarios', 'self_address_receiver.tz' - ) - originate(client, session, path, 'Unit', 0) - session['receiver_address'] = session['contract'] - - def test_send_self_address(self, client_regtest_scrubbed, session): - client = client_regtest_scrubbed - receiver_address = session['receiver_address'] - client.transfer( - 0, - 'bootstrap2', - 'self_address_sender', - ['--arg', f'"{receiver_address}"', '--burn-cap', '2'], - ) - utils.bake(client, 'bootstrap5') - - -@pytest.mark.slow -@pytest.mark.contract -@pytest.mark.regression -class TestScriptHashRegression: - @pytest.mark.parametrize( - "client_regtest_custom_scrubber", - [[(re.escape(CONTRACT_PATH), '[CONTRACT_PATH]')]], - indirect=True, - ) - def test_contract_hash(self, client_regtest_custom_scrubber: Client): - client = client_regtest_custom_scrubber - contracts = all_contracts() - contracts.sort() - for contract in contracts: - assert contract.endswith( - '.tz' - ), "test contract should have .tz extension" - - client.hash_script( - [os.path.join(CONTRACT_PATH, contract) for contract in contracts], - display_names=True, - ) - - -@pytest.mark.contract -class TestScriptHashOrigination: - def test_contract_hash_with_origination( - self, client: Client, session: dict - ): - script = ID_SCRIPT_LITERAL - originate( - client, - session, - contract=script, - init_storage='Unit', - amount=1000, - contract_name='dummy_contract', - ) - [(hash1, _)] = client.hash_script([script]) - hash2 = client.get_script_hash('dummy_contract') - assert hash1 == hash2 - - -@pytest.mark.contract -class TestScriptHashMultiple: - """Test tezos-client hash script with diffent number and type of - arguments""" - - def test_contract_hashes_empty(self, client: Client): - assert client.hash_script([]) == [] - - def test_contract_hashes_single(self, client: Client): - assert client.hash_script([ID_SCRIPT_LITERAL]) == [ - (ID_SCRIPT_HASH, None) - ] - - def test_contract_hashes_single_display_names(self, client: Client): - assert client.hash_script([ID_SCRIPT_LITERAL], display_names=True,) == [ - ( - ID_SCRIPT_HASH, - 'Literal script 1', - ) - ] - - def test_contract_hashes_mixed(self, client: Client): - contract_path = os.path.join(CONTRACT_PATH, 'attic', 'empty.tz') - script_empty_hash = ''' -expruat2BS4KCwn9kbopeX1ZwxtrtJbyFhpnpnG6A5KdCBCwHNsdod - '''.strip() - with open(contract_path, 'r') as contract_file: - script = contract_file.read() - - hashes = client.hash_script([contract_path, script]) - - assert hashes == [ - ( - script_empty_hash, - None, - ), - ( - script_empty_hash, - None, - ), - ] - - hashes = client.hash_script( - [contract_path, script], display_names=True - ) - - assert hashes == [ - ( - script_empty_hash, - contract_path, - ), - ( - script_empty_hash, - 'Literal script 2', - ), - ] - - @pytest.mark.parametrize( - "for_script, display_names, results", - [ - ('csv', True, (ID_SCRIPT_HASH, 'Literal script 1')), - ('csv', False, (ID_SCRIPT_HASH, None)), - ('tsv', True, (ID_SCRIPT_HASH, 'Literal script 1')), - ('tsv', False, (ID_SCRIPT_HASH, None)), - ], - ) - def test_contract_hashes_for_script( - self, client: Client, for_script, display_names, results - ): - assert ( - client.hash_script( - [ID_SCRIPT_LITERAL], - display_names=display_names, - for_script=for_script, - ) - == [results] - ) - - -@pytest.mark.contract -@pytest.mark.regression -class TestNormalize: - """Regression tests for the "normalize data" command.""" - - modes = [None, 'Readable', 'Optimized', 'Optimized_legacy'] - - @pytest.mark.parametrize('mode', modes) - def test_normalize_unparsing_mode(self, client_regtest_scrubbed, mode): - client = client_regtest_scrubbed - input_data = ( - '{Pair 0 3 6 9; Pair 1 (Pair 4 (Pair 7 10)); {2; 5; 8; 11}}' - ) - input_type = 'list (pair nat nat nat nat)' - client.normalize(input_data, input_type, mode=mode) - - def test_normalize_legacy_flag(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - input_data = '{Elt %a 0 1}' - input_type = 'map nat nat' - client.normalize(input_data, input_type, legacy=True) - error_pattern = 'unexpected annotation.' - with utils.assert_run_failure(error_pattern): - client.normalize(input_data, input_type, legacy=False) - - @pytest.mark.parametrize('mode', modes) - def test_normalize_script(self, client_regtest_scrubbed, mode): - client = client_regtest_scrubbed - path = os.path.join(CONTRACT_PATH, 'opcodes', 'comb-literals.tz') - client.normalize_script(path, mode=mode) - - types = [ - 'nat', - 'list nat', - 'pair nat int', - 'list (pair nat int)', - 'pair nat int bool', - 'list (pair nat int bool)', - 'pair nat int bool bytes', - 'list (pair nat int bool bytes)', - ] - - @pytest.mark.parametrize('typ', types) - def test_normalize_type(self, client_regtest_scrubbed, typ): - client = client_regtest_scrubbed - client.normalize_type(typ) - - -@pytest.mark.contract -class TestTZIP4View: - """Tests for the "run tzip4 view" command.""" - - def test_run_view(self, client: Client, session: dict): - - path = os.path.join(CONTRACT_PATH, 'mini_scenarios', 'tzip4_view.tz') - originate( - client, - session, - contract=path, - init_storage='Unit', - amount=1000, - contract_name='view_contract', - ) - utils.bake(client, bake_for='bootstrap5') - - const_view_res = client.run_view( - "view_const", "view_contract", "Unit", [] - ) - add_view_res = client.run_view( - "view_add", "view_contract", "Pair 1 3", [] - ) - - assert const_view_res.result == "5\n" and add_view_res.result == "4\n" - - -@pytest.mark.contract -@pytest.mark.incremental -class TestBadIndentation: - """Tests for the "hash script" and "convert script" commands on - badly-indented scripts.""" - - BADLY_INDENTED = os.path.join(ILLTYPED_CONTRACT_PATH, 'badly_indented.tz') - - SCRIPT_HASH = "exprv8K6ceBpFH5SFjQm4BRYSLJCHQBFeQU6BFTdvQSRPaPkzdLyAL" - - def test_bad_indentation_ill_typed(self, client): - with utils.assert_run_failure('syntax error in program'): - client.typecheck(self.BADLY_INDENTED) - - def test_bad_indentation_hash(self, client): - assert client.hash_script([self.BADLY_INDENTED]) == [ - (self.SCRIPT_HASH, None) - ] - - def test_formatting(self, client, session): - session['formatted_script'] = client.convert_script( - self.BADLY_INDENTED, 'Michelson', 'Michelson' - ) - - def test_formatted_hash(self, client, session): - assert client.hash_script([session['formatted_script']]) == [ - (self.SCRIPT_HASH, None) - ] - - def test_formatted_typechecks(self, client, session): - client.typecheck(session['formatted_script'], file=False) - - -@pytest.mark.contract -@pytest.mark.incremental -class TestContractTypeChecking: - """Typechecking tests for the address and (contract _) types.""" - - def check_address(self, client, address): - """An address followed by an entrypoint typechecks at type address if - and only if the entrypoint is not "default".""" - - address_a = f'"{address}%a"' - address_opt = client.normalize( - f'"{address}"', 'address', 'Optimized' - ).strip() - address_opt_a = client.normalize( - address_a, 'address', 'Optimized' - ).strip() - - client.typecheck_data(f'"{address}"', 'address') - client.typecheck_data(f'{address_a}', 'address') - client.typecheck_data(f'{address_opt}', 'address') - client.typecheck_data(f'{address_opt_a}', 'address') - - unexpected_annotation_error = "unexpected annotation." - - with utils.assert_run_failure(unexpected_annotation_error): - client.typecheck_data(f'"{address}%default"', 'address') - - # 64656661756c74 is "default" in hexa - with utils.assert_run_failure(unexpected_annotation_error): - client.typecheck_data(address_opt + '64656661756c74', 'address') - - def check_contract_ok(self, client, address, entrypoint, typ): - """Helper to check that an address followed by an entrypoint typechecks - at type (contract typ) using both readable and optimised - representations.""" - - address_readable = f'"{address}"' - if entrypoint is not None: - address_readable = f'"{address}%{entrypoint}"' - - address_opt = client.normalize( - address_readable, 'address', 'Optimized' - ).strip() - - client.typecheck_data(address_readable, f'contract ({typ})') - client.typecheck_data(address_opt, f'contract ({typ})') - - client.run_script( - f""" -parameter unit; -storage address; -code {{ - CDR; - CONTRACT ({typ}); - ASSERT_SOME; - ADDRESS; - NIL operation; - PAIR }}""", - address_readable, - 'Unit', - file=False, - ) - - def check_contract_ko( - self, client, address, entrypoint, typ, expected_error - ): - """Helper to check that an address followed by an entrypoint does not - typecheck at type (contract typ) using both readable and optimised - representations.""" - - address_readable = f'"{address}"' - if entrypoint is not None: - address_readable = f'"{address}%{entrypoint}"' - - address_opt = client.normalize( - address_readable, 'address', 'Optimized' - ).strip() - - with utils.assert_run_failure(expected_error): - client.typecheck_data(address_readable, f'contract ({typ})') - with utils.assert_run_failure(expected_error): - client.typecheck_data(address_opt, f'contract ({typ})') - - client.run_script( - f""" -parameter unit; -storage address; -code {{ - CDR; - DUP; - CONTRACT ({typ}); - ASSERT_NONE; - NIL operation; - PAIR }}""", - address_readable, - 'Unit', - file=False, - ) - - def test_implicit(self, client): - """The address of an implicit account followed by some entrypoint - typechecks: - - at type address if the entrypoint is not "default", - - at type (contract ) if the entrypoint is empty and ty is unit.""" - - tz1 = 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx' - - self.check_address(client, tz1) - self.check_contract_ok(client, tz1, None, 'unit') - - no_entrypoint_error = 'Contract has no entrypoint named a' - type_mismatch_error = 'Type nat is not compatible with type unit.' - self.check_contract_ko(client, tz1, 'a', 'unit', no_entrypoint_error) - self.check_contract_ko(client, tz1, 'a', 'nat', no_entrypoint_error) - self.check_contract_ko(client, tz1, None, 'nat', type_mismatch_error) - - def test_originated_inexistent(self, client): - """The address of an inexistent originated account followed by some - entrypoint typechecks: - - at type address if the entrypoint is not "default", - - at no (contract _) type.""" - - kt1 = 'KT1RvwLgpxVv9ANCKsDb5vBgTaZRG1W4bKWP' - - self.check_address(client, kt1) - - invalid_contract_error = 'invalid contract.' - self.check_contract_ko( - client, kt1, None, 'unit', invalid_contract_error - ) - self.check_contract_ko(client, kt1, 'a', 'unit', invalid_contract_error) - self.check_contract_ko(client, kt1, None, 'nat', invalid_contract_error) - self.check_contract_ko(client, kt1, 'a', 'nat', invalid_contract_error) - - def test_originated_no_default(self, client, session): - """The address of an existent originated account that does not specify - a default entrypoint followed by some entrypoint typechecks: - - at type address if the entrypoint is not "default", - - at type (contract ) if - - the entrypoint is empty and is the root type - - the entrypoint is non-empty, one of the declared entrypoints, and - is the type associated to that entrypoint.""" - - path = os.path.join( - CONTRACT_PATH, 'entrypoints', 'simple_entrypoints.tz' - ) - origination = originate(client, session, path, 'Unit', 0) - kt1 = origination.contract - root_type = 'or (unit %A) (or (string %B) (nat %C))' - a_type = 'unit' - b_type = 'string' - - self.check_address(client, kt1) - self.check_contract_ok(client, kt1, None, root_type) - self.check_contract_ok(client, kt1, 'A', a_type) - self.check_contract_ok(client, kt1, 'B', b_type) - - no_entrypoint_error = 'Contract has no entrypoint named a' - self.check_contract_ko(client, kt1, 'a', a_type, no_entrypoint_error) - - def test_originated_with_default(self, client, session): - """The address of an existent originated account that specifies - a default entrypoint followed by some entrypoint typechecks: - - at type address if the entrypoint is not "default", - - at type (contract ) if - - the entrypoint is empty and is the type of the default - entrypoint - - the entrypoint is non-empty, one of the declared entrypoints, and - is the type associated to that entrypoint.""" - - path = os.path.join( - CONTRACT_PATH, 'entrypoints', 'delegatable_target.tz' - ) - initial_storage = 'Pair "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" "" 0' - origination = originate(client, session, path, initial_storage, 0) - kt1 = origination.contract - root_type = ( - 'or (or (key_hash %set_delegate) (unit %remove_delegate))' - '(or %default string nat)' - ) - default_type = 'or string nat' - - self.check_address(client, kt1) - self.check_contract_ok(client, kt1, None, default_type) - self.check_contract_ok(client, kt1, 'set_delegate', 'key_hash') - - no_entrypoint_error = 'Contract has no entrypoint named a' - self.check_contract_ko(client, kt1, 'a', root_type, no_entrypoint_error) - - type_mismatch_error = 'is not compatible with type' - self.check_contract_ko( - client, kt1, None, root_type, type_mismatch_error - ) diff --git a/tests_python/tests_012/test_contract_annotations.py b/tests_python/tests_012/test_contract_annotations.py deleted file mode 100644 index c34dcc016ee1..000000000000 --- a/tests_python/tests_012/test_contract_annotations.py +++ /dev/null @@ -1,88 +0,0 @@ -import pytest -from tools.utils import assert_typecheck_data_failure, assert_typecheck_failure -from client.client import Client - - -@pytest.mark.slow -@pytest.mark.contract -class TestAnnotations: - """Tests of Michelson annotations.""" - - def test_annotation_length_success(self, client: Client): - client.typecheck_data('3', f"(int :{'a' * 254})") - - def test_annotation_length_failure(self, client: Client): - assert_typecheck_data_failure( - client, - '3', - f"(int :{'a' * 255})", - r'annotation exceeded maximum length \(255 chars\)', - ) - - def test_field_annotation_in_type_alphabetic(self, client): - client.typecheck_data('Pair 0 0', 'pair (nat %x) (int %y)') - - def test_field_annotation_in_type_numeral(self, client): - client.typecheck_data('Pair 0 0', 'pair (nat %1) (int %2)') - - def test_field_annotation_in_type_invalid_character(self, client): - assert_typecheck_data_failure( - client, - 'Pair 0 0', - 'pair (nat %.) (int %.)', - 'unexpected annotation', - ) - - def test_field_annotation_in_instruction_alphabetic(self, client): - client.typecheck_data( - '{ CAR %x }', 'lambda (pair (nat %x) (int %y)) nat' - ) - - def test_field_annotation_in_instruction_numeral(self, client): - client.typecheck_data( - '{ CAR %1 }', 'lambda (pair (nat %1) (int %2)) nat' - ) - - def test_field_annotation_in_instruction_invalid_character(self, client): - assert_typecheck_data_failure( - client, - '{ CAR %. }', - 'lambda (pair (nat %.) (int %.)) nat', - 'unexpected annotation', - ) - - def test_field_annotation_in_root_alphabetic(self, client): - client.typecheck( - 'parameter %r unit; storage unit; code {FAILWITH}', file=False - ) - - def test_field_annotation_in_root_numeral(self, client): - client.typecheck( - 'parameter %1 unit; storage unit; code {FAILWITH}', file=False - ) - - def test_field_annotation_in_root_invalid_character(self, client): - assert_typecheck_failure( - client, - 'parameter %. unit; storage unit; code {FAILWITH}', - 'unexpected annotation', - file=False, - ) - - def test_field_annotation_in_root_type_alphabetic(self, client): - client.typecheck( - 'parameter (unit %r); storage unit; code {FAILWITH}', file=False - ) - - def test_field_annotation_in_root_type_numeral(self, client): - client.typecheck( - 'parameter (unit %1); storage unit; code {FAILWITH}', file=False - ) - - def test_field_annotation_in_root_type_invalid_character(self, client): - assert_typecheck_failure( - client, - 'parameter (unit %.); storage unit; code {FAILWITH}', - 'unexpected annotation', - file=False, - ) diff --git a/tests_python/tests_012/test_contract_baker.py b/tests_python/tests_012/test_contract_baker.py deleted file mode 100644 index 73dfd0cd43a5..000000000000 --- a/tests_python/tests_012/test_contract_baker.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -import pytest -from tools import constants, utils -from client.client import Client -from . import contract_paths - - -@pytest.mark.contract -@pytest.mark.baker -@pytest.mark.incremental -class TestOriginationCall: - """Test a simple contract origination and call""" - - def test_originate(self, client: Client, session: dict): - initial_storage = 'Unit' - contract = os.path.join( - contract_paths.OPCODES_CONTRACT_PATH, 'transfer_tokens.tz' - ) - args = ['--init', initial_storage, '--burn-cap', '0.400'] - origination = client.originate( - 'foobar', 1000, 'bootstrap1', contract, args - ) - session['contract'] = origination.contract - utils.bake(client, bake_for="bootstrap5") - - # Unsolved mystery: - # client.wait_for_inclusion(origination.operation_hash) - # fails sometimes with tezos-client crashing. Maybe caused with - # subprocess captured of forked process output? - # - # Safer to poll with `check_block_contain_operations` - assert utils.check_block_contains_operations( - client, [origination.operation_hash] - ) - - def test_call(self, client: Client, session: dict): - contract = session['contract'] - bootstrap3 = '"tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU"' - transfer = client.call('bootstrap2', contract, ['--arg', bootstrap3]) - utils.bake(client, bake_for="bootstrap5") - assert utils.check_block_contains_operations( - client, [transfer.operation_hash] - ) - - def test_balance(self, client: Client): - bootstrap3 = constants.IDENTITIES['bootstrap3']['identity'] - deposit = client.frozen_deposits(bootstrap3) - balance = client.get_mutez_balance('bootstrap3') - assert balance + deposit == utils.mutez_of_tez(4000100.0) - - def test_query_storage(self, client: Client, session: dict): - contract = session['contract'] - url = f'/chains/main/blocks/head/context/contracts/{contract}/storage' - res = client.rpc('get', url) - assert res['prim'] == 'Unit' diff --git a/tests_python/tests_012/test_contract_bls12_381.py b/tests_python/tests_012/test_contract_bls12_381.py deleted file mode 100644 index 50e626c0623f..000000000000 --- a/tests_python/tests_012/test_contract_bls12_381.py +++ /dev/null @@ -1,317 +0,0 @@ -from os import path -import random -from hashlib import blake2b -import pytest - -from tools.bls12_381 import G1, G2, Fr, pairing_check -from tools.utils import assert_run_failure -from .contract_paths import MINI_SCENARIOS_CONTRACT_PATH, OPCODES_CONTRACT_PATH - - -def check_contract(client, contract_name, arg, expected_storage): - contract_path = path.join(OPCODES_CONTRACT_PATH, f'{contract_name}.tz') - result = client.run_script(contract_path, 'None', arg) - assert result.storage == f'(Some {expected_storage})' - - -def check_contract_binop(client, contract_name, arg0, arg1, expected_storage): - check_contract( - client, contract_name, f'Pair {arg0} {arg1}', expected_storage - ) - - -# prefix a type name with 'bls12_381_' -def bls(tname): - return f'bls12_381_{tname}' - - -# Store -def check_store(client, cls, arg): - arg = cls.to_hex(arg) - check_contract(client, f'store_{bls(cls.name)}', arg, arg) - - -# Add -def check_add(client, cls, xxx, yyy): - check_contract_binop( - client, - f'add_{bls(cls.name)}', - cls.to_hex(xxx), - cls.to_hex(yyy), - cls.to_hex(cls.add(xxx, yyy)), - ) - - -# Mul -def check_mul(client, cls, xxx, yyy): - check_contract_binop( - client, - f'mul_{bls(cls.name)}', - cls.to_hex(xxx), - Fr.to_hex(yyy), - cls.to_hex(cls.mul(xxx, yyy)), - ) - - -# Neg -def check_neg(client, cls, arg): - res = cls.to_hex(cls.neg(arg)) - arg = cls.to_hex(arg) - check_contract(client, f'neg_{bls(cls.name)}', arg, res) - - -# Pairing Check -def check_pairing_check(client, args): - res = pairing_check(args) - args = [(G1.to_hex(g1), G2.to_hex(g2)) for g1, g2 in args] - args = [f'Pair {g1} {g2}' for g1, g2 in args] - args = f'{{ {"; ".join(args)} }}' - check_contract(client, 'pairing_check', args, res) - - -# Setting this higher makes things rather slow -RANDOM_ITERATIONS = range(10) - - -STORE_CLASSES = [G1, G2, Fr] -CURVES = [G1, G2] -ADD_CLASSES = [G1, G2, Fr] -MUL_CLASSES = [G1, G2, Fr] -NEG_CLASSES = [G1, G2, Fr] - - -@pytest.mark.incremental -@pytest.mark.contract -@pytest.mark.regression -class TestBls12_381: - - # Fix the random seed to ensure reproducibility - h = blake2b() - h.update(b'seed') - gen = random.Random() - gen.seed(bytes.fromhex(h.hexdigest())) - - # Store - - @pytest.mark.parametrize("cls", STORE_CLASSES) - def test_store_zero(self, client_regtest, cls): - check_store(client_regtest, cls, cls.zero) - - @pytest.mark.parametrize("cls", STORE_CLASSES) - def test_store_one(self, client_regtest, cls): - check_store(client_regtest, cls, cls.one) - - @pytest.mark.parametrize("cls", STORE_CLASSES) - def test_store_random(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_store(client_regtest, cls, cls.random(self.gen)) - - # Add - @pytest.mark.parametrize("cls", ADD_CLASSES) - def test_add_zero_zero(self, client_regtest, cls): - check_add(client_regtest, cls, cls.zero, cls.zero) - - @pytest.mark.parametrize("cls", ADD_CLASSES) - def test_add_zero_one(self, client_regtest, cls): - check_add(client_regtest, cls, cls.zero, cls.one) - - @pytest.mark.parametrize("cls", ADD_CLASSES) - def test_add_zero_random(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_add(client_regtest, cls, cls.zero, cls.random(self.gen)) - - @pytest.mark.parametrize("cls", ADD_CLASSES) - def test_add_one_zero(self, client_regtest, cls): - check_add(client_regtest, cls, cls.one, cls.zero) - - @pytest.mark.parametrize("cls", ADD_CLASSES) - def test_add_one_one(self, client_regtest, cls): - check_add(client_regtest, cls, cls.one, cls.one) - - @pytest.mark.parametrize("cls", ADD_CLASSES) - def test_add_one_random(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_add(client_regtest, cls, cls.one, cls.random(self.gen)) - - @pytest.mark.parametrize("cls", ADD_CLASSES) - def test_add_random_zero(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_add(client_regtest, cls, cls.random(self.gen), cls.zero) - - @pytest.mark.parametrize("cls", ADD_CLASSES) - def test_add_random_one(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_add(client_regtest, cls, cls.random(self.gen), cls.one) - - @pytest.mark.parametrize("cls", ADD_CLASSES) - def test_add_random_random(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_add( - client_regtest, cls, cls.random(self.gen), cls.random(self.gen) - ) - - # Mul - @pytest.mark.parametrize("cls", MUL_CLASSES) - def test_mul_zero_zero(self, client_regtest, cls): - check_mul(client_regtest, cls, cls.zero, Fr.zero) - - @pytest.mark.parametrize("cls", MUL_CLASSES) - def test_mul_zero_one(self, client_regtest, cls): - check_mul(client_regtest, cls, cls.zero, Fr.one) - - @pytest.mark.parametrize("cls", MUL_CLASSES) - def test_mul_zero_random(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_mul(client_regtest, cls, cls.zero, Fr.random(self.gen)) - - @pytest.mark.parametrize("cls", MUL_CLASSES) - def test_mul_one_zero(self, client_regtest, cls): - check_mul(client_regtest, cls, cls.one, Fr.zero) - - @pytest.mark.parametrize("cls", MUL_CLASSES) - def test_mul_one_one(self, client_regtest, cls): - check_mul(client_regtest, cls, cls.one, Fr.one) - - @pytest.mark.parametrize("cls", MUL_CLASSES) - def test_mul_one_random(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_mul(client_regtest, cls, cls.one, Fr.random(self.gen)) - - @pytest.mark.parametrize("cls", MUL_CLASSES) - def test_mul_random_zero(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_mul(client_regtest, cls, cls.random(self.gen), Fr.zero) - - @pytest.mark.parametrize("cls", MUL_CLASSES) - def test_mul_random_one(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_mul(client_regtest, cls, cls.random(self.gen), Fr.one) - - @pytest.mark.parametrize("cls", MUL_CLASSES) - def test_mul_random_random(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_mul( - client_regtest, cls, cls.random(self.gen), Fr.random(self.gen) - ) - - # Neg - @pytest.mark.parametrize("cls", NEG_CLASSES) - def test_neg_zero(self, client_regtest, cls): - check_neg(client_regtest, cls, cls.zero) - - @pytest.mark.parametrize("cls", NEG_CLASSES) - def test_neg_one(self, client_regtest, cls): - check_neg(client_regtest, cls, cls.one) - - @pytest.mark.parametrize("cls", NEG_CLASSES) - def test_neg_random(self, client_regtest, cls): - for _ in RANDOM_ITERATIONS: - check_neg(client_regtest, cls, cls.random(self.gen)) - - # Pairing checks - def test_pairing_nil(self, client_regtest): - check_pairing_check(client_regtest, []) - - def test_pairing_zero_zero(self, client_regtest): - args = [(G1.zero, G2.zero)] - check_pairing_check(client_regtest, args) - - def test_pairing_zero_one(self, client_regtest): - args = [(G1.zero, G2.one)] - check_pairing_check(client_regtest, args) - - def test_pairing_zero_random(self, client_regtest): - for _ in RANDOM_ITERATIONS: - args = [(G1.zero, G2.random(self.gen))] - check_pairing_check(client_regtest, args) - - def test_pairing_one_zero(self, client_regtest): - args = [(G1.one, G2.zero)] - check_pairing_check(client_regtest, args) - - def test_pairing_one_one(self, client_regtest): - args = [(G1.one, G2.one)] - check_pairing_check(client_regtest, args) - - def test_pairing_one_random(self, client_regtest): - for _ in RANDOM_ITERATIONS: - args = [(G1.one, G2.random(self.gen))] - check_pairing_check(client_regtest, args) - - def test_pairing_random_zero(self, client_regtest): - for _ in RANDOM_ITERATIONS: - args = [(G1.random(self.gen), G2.zero)] - check_pairing_check(client_regtest, args) - - def test_pairing_random_one(self, client_regtest): - for _ in RANDOM_ITERATIONS: - args = [(G1.random(self.gen), G2.one)] - check_pairing_check(client_regtest, args) - - def test_pairing_random_random(self, client_regtest): - for _ in RANDOM_ITERATIONS: - args = [(G1.random(self.gen), G2.random(self.gen))] - check_pairing_check(client_regtest, args) - - def test_pairing_neg_g1(self, client_regtest): - for _ in RANDOM_ITERATIONS: - g1_point = G1.random(self.gen) - g2_point = G2.random(self.gen) - args = [(g1_point, g2_point), (G1.neg(g1_point), g2_point)] - check_pairing_check(client_regtest, args) - - def test_pairing_neg_g2(self, client_regtest): - for _ in RANDOM_ITERATIONS: - g1_point = G1.random(self.gen) - g2_point = G2.random(self.gen) - args = [(g1_point, g2_point), (g1_point, G2.neg(g2_point))] - check_pairing_check(client_regtest, args) - - # Pairing Check test based on signature aggregation - def test_signature_aggregation(self, client_regtest): - for _ in RANDOM_ITERATIONS: - sk0 = Fr.random(self.gen) # secret key - pk0 = G2.mul(G2.one, sk0) # public key - # we don't have hash-to-curve on g1, so compute a random point - msg_hash = G1.random(self.gen) # message hash - sig0 = G1.mul(msg_hash, sk0) # signature - args0 = [(msg_hash, pk0), (G1.neg(sig0), G2.one)] - check_pairing_check(client_regtest, args0) - - sk1 = Fr.random(self.gen) # secret key - pk1 = G2.mul(G2.one, sk1) # public key - # we don't have hash-to-curve on g1, so compute a random point - sig1 = G1.mul(msg_hash, sk1) # signature - args1 = [ - (G1.add(msg_hash, msg_hash), G2.add(pk0, pk1)), - (G1.neg(G1.add(sig0, sig1)), G2.add(G2.one, G2.one)), - ] - check_pairing_check(client_regtest, args1) - - def test_groth16(self, client_regtest): - # pylint: disable=line-too-long - # The verifying key, proof, and inputs are generated from - # ZoKrates, modified to use BLS12-381. - # The circuit proves knowledge of a square root of 113569. - - input_x = "0xa1bb010000000000000000000000000000000000000000000000000000000000" # noqa - input_y = "0x0100000000000000000000000000000000000000000000000000000000000000" # noqa - proof_a = "0x0a2841423326ab08f5f406409775e43fa0f9a0b97631fa85d2dd9242507d25059e9cf48b8b98f99a0008671423a148ec106d70637056972ef49fb6f62de2e89ba3682b9972292b6bb4e6f53799a75d2f8001ccfde280d8ac05fc209352236cbd" # noqa - proof_b = "0x0fced939fb1ad733f99669f50a383ef632f6d41dfbde434a6715afd5c7dfbb7bc5835e058ad8b590c7b38dd137d0bd0f0e1540f1b45d8aa626c360e2ea484a116243f7c802034de915db6b18d5303946f676e423cbd6046d37a82208d500625a11c7250ccb953a7ee49d704ad14de4b727733cff7cf06875d8b6444f3c0a8cbf0bd980e539c74bd5b37bb15fe816f23407d269193105fda71adf35fae9309d9d46729fcd4685699097a86f0460a2bc8b16293940cabfdcfe0f27e4107e74e90c" # noqa - proof_c = "0x0a1fb5a144ca3bdfe4ad0f183cf71dd7fdd28cbef4fcd47b5b419f65186703f62ecaaa1255fa21a6ebdd917ab1f9bd9707de7066865e2ff3875e22088619125a0d4088a622ab42224425ef89a5a149ce2db9c8292b62c7e7aaa7e87f3535304b" # noqa - - inputs = f"Pair {input_x} {input_y}" - proof = f"Pair (Pair {proof_a} {proof_b}) {proof_c}" - arg = f"Pair ({inputs}) ({proof})" - - contract = path.join(MINI_SCENARIOS_CONTRACT_PATH, 'groth16.tz') - client_regtest.run_script(contract, 'Unit', arg) - - def test_fr_bytes_parameters_more_than_32_bytes(self, client_regtest): - random_bytes = ( - "0xf7ef66f95c90b2f953eb0555af65f22095d4f54b40ea8c6d" - + "cc2014740e8662c16bb8786723" - ) - contract = path.join(OPCODES_CONTRACT_PATH, 'bls12_381_fr_to_int.tz') - with assert_run_failure(r'error running script'): - client_regtest.run_script(contract, storage='0', inp=random_bytes) diff --git a/tests_python/tests_012/test_contract_macros.py b/tests_python/tests_012/test_contract_macros.py deleted file mode 100644 index 8528f37165f7..000000000000 --- a/tests_python/tests_012/test_contract_macros.py +++ /dev/null @@ -1,447 +0,0 @@ -from os import path -import pytest -from tools.utils import ( - assert_run_script_failwith, - assert_transfer_failwith, - init_with_transfer, - bake, - assert_storage_contains, -) -from tools.client_regression import ClientRegression -from client.client import Client -from .contract_paths import MACROS_CONTRACT_PATH, CONTRACT_PATH, all_contracts - - -@pytest.mark.contract -class TestContractMacros: - """Tests for contracts using macros that do not require origination.""" - - @pytest.mark.parametrize( - "contract,param,storage,expected", - [ # FORMAT: assert_output contract_file storage input expected_result - # Build list - ('build_list.tz', '{}', '0', '{ 0 }'), - ('build_list.tz', '{}', '3', '{ 0 ; 1 ; 2 ; 3 }'), - ( - 'build_list.tz', - '{}', - '10', - '{ 0 ; 1 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7 ; 8 ; 9 ; 10 }', - ), - # Find maximum int in list -- returns None if not found - ('max_in_list.tz', 'None', '{}', 'None'), - ('max_in_list.tz', 'None', '{ 1 }', '(Some 1)'), - ('max_in_list.tz', 'None', '{ -1 }', '(Some -1)'), - ( - 'max_in_list.tz', - 'None', - '{ 10 ; -1 ; -20 ; 100 ; 0 }', - '(Some 100)', - ), - ( - 'max_in_list.tz', - 'None', - '{ 10 ; -1 ; -20 ; 100 ; 0 }', - '(Some 100)', - ), - ( - 'max_in_list.tz', - 'None', - '{ -10 ; -1 ; -20 ; -100 }', - '(Some -1)', - ), - # Test comparisons on tez { EQ ; GT ; LT ; GE ; LE } - ( - 'compare.tz', - '{}', - '(Pair 1000000 2000000)', - '{ False ; False ; True ; False ; True }', - ), - ( - 'compare.tz', - '{}', - '(Pair 2000000 1000000)', - '{ False ; True ; False ; True ; False }', - ), - ( - 'compare.tz', - '{}', - '(Pair 2370000 2370000)', - '{ True ; False ; False ; True ; True }', - ), - # Test ASSERT - ('assert.tz', 'Unit', 'True', 'Unit'), - # ASSERT_{OP} - ('assert_eq.tz', 'Unit', '(Pair -1 -1)', 'Unit'), - ('assert_eq.tz', 'Unit', '(Pair -1 -1)', 'Unit'), - ('assert_neq.tz', 'Unit', '(Pair 0 -1)', 'Unit'), - ('assert_lt.tz', 'Unit', '(Pair -1 0)', 'Unit'), - ('assert_le.tz', 'Unit', '(Pair 0 0)', 'Unit'), - ('assert_le.tz', 'Unit', '(Pair -1 0)', 'Unit'), - ('assert_gt.tz', 'Unit', '(Pair 0 -1)', 'Unit'), - ('assert_ge.tz', 'Unit', '(Pair 0 0)', 'Unit'), - ('assert_ge.tz', 'Unit', '(Pair 0 -1)', 'Unit'), - # ASSERT_CMP{OP} - ('assert_cmpeq.tz', 'Unit', '(Pair -1 -1)', 'Unit'), - ('assert_cmpneq.tz', 'Unit', '(Pair 0 -1)', 'Unit'), - ('assert_cmplt.tz', 'Unit', '(Pair -1 0)', 'Unit'), - ('assert_cmple.tz', 'Unit', '(Pair -1 0)', 'Unit'), - ('assert_cmple.tz', 'Unit', '(Pair 0 0)', 'Unit'), - ('assert_cmpgt.tz', 'Unit', '(Pair 0 -1)', 'Unit'), - ('assert_cmpge.tz', 'Unit', '(Pair 0 -1)', 'Unit'), - ('assert_cmpge.tz', 'Unit', '(Pair 0 0)', 'Unit'), - # Tests the SET_CAR and SET_CDR instructions - ( - 'set_caddaadr.tz', - '(Pair (Pair 1 2 (Pair (Pair 3 0) 4) 5) 6)', - '3000000', - '(Pair (Pair 1 2 (Pair (Pair 3 3000000) 4) 5) 6)', - ), - ( - 'map_caddaadr.tz', - '(Pair (Pair 1 2 (Pair (Pair 3 0) 4) 5) 6)', - 'Unit', - '(Pair (Pair 1 2 (Pair (Pair 3 1000000) 4) 5) 6)', - ), - # Test comparisons on bytes { EQ ; GT ; LT ; GE ; LE } - ( - 'compare_bytes.tz', - '{}', - '(Pair 0x33 0x34)', - '{ False ; False ; True ; False ; True }', - ), - ( - 'compare_bytes.tz', - '{}', - '(Pair 0x33 0x33aa)', - '{ False ; False ; True ; False ; True }', - ), - ( - 'compare_bytes.tz', - '{}', - '(Pair 0x33 0x33)', - '{ True ; False ; False ; True ; True }', - ), - ( - 'compare_bytes.tz', - '{}', - '(Pair 0x34 0x33)', - '{ False ; True ; False ; True ; False }', - ), - ], - ) - def test_contract_input_output( - self, - client: Client, - contract: str, - param: str, - storage: str, - expected: str, - ): - assert contract.endswith( - '.tz' - ), "test contract should have .tz extension" - contract = path.join(MACROS_CONTRACT_PATH, contract) - run_script_res = client.run_script(contract, param, storage) - assert run_script_res.storage == expected - - @pytest.mark.parametrize( - "contract,param,storage", - [ # FORMAT: assert_output contract_file storage input expected_result - ('assert.tz', 'Unit', 'False'), - ('assert_eq.tz', 'Unit', '(Pair 0 -1)'), - ('assert_eq.tz', 'Unit', '(Pair 0 -1)'), - ('assert_neq.tz', 'Unit', '(Pair -1 -1)'), - ('assert_lt.tz', 'Unit', '(Pair 0 -1)'), - ('assert_lt.tz', 'Unit', '(Pair 0 0)'), - ('assert_le.tz', 'Unit', '(Pair 0 -1)'), - ('assert_gt.tz', 'Unit', '(Pair -1 0)'), - ('assert_gt.tz', 'Unit', '(Pair 0 0)'), - ('assert_ge.tz', 'Unit', '(Pair -1 0)'), - ('assert_cmpeq.tz', 'Unit', '(Pair 0 -1)'), - ('assert_cmpneq.tz', 'Unit', '(Pair -1 -1)'), - ('assert_cmplt.tz', 'Unit', '(Pair 0 0)'), - ('assert_cmplt.tz', 'Unit', '(Pair 0 -1)'), - ('assert_cmple.tz', 'Unit', '(Pair 0 -1)'), - ('assert_cmpgt.tz', 'Unit', '(Pair 0 0)'), - ('assert_cmpgt.tz', 'Unit', '(Pair -1 0)'), - ('assert_cmpge.tz', 'Unit', '(Pair -1 0)'), - ], - ) - def test_contract_failures(self, client: Client, contract, param, storage): - contract = path.join(MACROS_CONTRACT_PATH, contract) - assert_run_script_failwith(client, contract, param, storage) - - -@pytest.mark.slow -@pytest.mark.contract -class TestGuestBook: - """Test on the guestbook contract.""" - - def test_guestbook(self, client: Client): - contract = path.join(MACROS_CONTRACT_PATH, 'guestbook.tz') - - init_with_transfer( - client, - contract, - '{ Elt "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" None }', - 100, - 'bootstrap1', - ) - - assert_transfer_failwith( - client, - 0, - 'bootstrap2', - 'guestbook', - ['--arg', '"Pas moi"', '--burn-cap', '10'], - ) - - client.transfer( - 0, - 'bootstrap1', - 'guestbook', - ['-arg', '"Coucou"', '--burn-cap', '10'], - ) - bake(client) - assert_storage_contains( - client, - 'guestbook', - '{ Elt "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" (Some "Coucou") }', - ) - - assert_transfer_failwith( - client, - 0, - 'bootstrap3', - 'guestbook', - ['--arg', '"Pas moi non plus"', '--burn-cap', '10'], - ) - assert_transfer_failwith( - client, - 0, - 'bootstrap1', - 'guestbook', - ['--arg', '"Recoucou ?"', '--burn-cap', '10'], - ) - - -@pytest.mark.slow -@pytest.mark.contract -class TestBigmap: - """Tests on the big_map_mem contract.""" - - def test_bigmap(self, client: Client): - contract = path.join(MACROS_CONTRACT_PATH, 'big_map_mem.tz') - - init_with_transfer( - client, - contract, - '(Pair { Elt 1 Unit ; Elt 2 Unit ; Elt 3 Unit } Unit)', - 100, - 'bootstrap1', - ) - - client.transfer( - 1, - 'bootstrap1', - 'big_map_mem', - ['-arg', '(Pair 0 False)', '--burn-cap', '10'], - ) - bake(client) - - assert_transfer_failwith( - client, - 0, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 0 True)', '--burn-cap', '10'], - ) - - client.transfer( - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 0 False)', '--burn-cap', '10'], - ) - bake(client) - assert_transfer_failwith( - client, - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 0 True)', '--burn-cap', '10'], - ) - client.transfer( - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 1 True)', '--burn-cap', '10'], - ) - bake(client) - assert_transfer_failwith( - client, - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 1 False)', '--burn-cap', '10'], - ) - client.transfer( - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 2 True)', '--burn-cap', '10'], - ) - bake(client) - assert_transfer_failwith( - client, - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 2 False)', '--burn-cap', '10'], - ) - client.transfer( - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 3 True)', '--burn-cap', '10'], - ) - bake(client) - assert_transfer_failwith( - client, - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 3 False)', '--burn-cap', '10'], - ) - client.transfer( - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 4 False)', '--burn-cap', '10'], - ) - bake(client) - assert_transfer_failwith( - client, - 1, - 'bootstrap1', - 'big_map_mem', - ['--arg', '(Pair 4 True)', '--burn-cap', '10'], - ) - - -@pytest.mark.slow -@pytest.mark.contract -class TestBigmapGetAdd: - """Tests on the big_map_get_add contract.""" - - def test_bigmap(self, client: Client): - contract = path.join(MACROS_CONTRACT_PATH, 'big_map_get_add.tz') - - init_with_transfer( - client, - contract, - '(Pair { Elt 0 1 ; Elt 1 2 ; Elt 2 3 } Unit)', - 100, - 'bootstrap1', - ) - - client.transfer( - 1, - 'bootstrap1', - 'big_map_get_add', - [ - '--arg', - '(Pair (Pair 200 (Some 2)) (Pair 200 (Some 2)))', - '--burn-cap', - '10', - ], - ) - bake(client) - client.transfer( - 1, - 'bootstrap1', - 'big_map_get_add', - [ - '--arg', - '(Pair (Pair 200 None) (Pair 200 None))', - '--burn-cap', - '10', - ], - ) - bake(client) - client.transfer( - 1, - 'bootstrap1', - 'big_map_get_add', - [ - '--arg', - '(Pair (Pair 200 None) (Pair 300 None))', - '--burn-cap', - '10', - ], - ) - bake(client) - client.transfer( - 1, - 'bootstrap1', - 'big_map_get_add', - [ - '--arg', - '(Pair (Pair 1 None) (Pair 200 None))', - '--burn-cap', - '10', - ], - ) - bake(client) - client.transfer( - 1, - 'bootstrap1', - 'big_map_get_add', - [ - '--arg', - '(Pair (Pair 1 (Some 2)) (Pair 0 (Some 1)))', - '--burn-cap', - '10', - ], - ) - bake(client) - client.transfer( - 1, - 'bootstrap1', - 'big_map_get_add', - [ - '--arg', - '(Pair (Pair 400 (Some 1232)) (Pair 400 (Some 1232)))', - '--burn-cap', - '10', - ], - ) - bake(client) - client.transfer( - 1, - 'bootstrap1', - 'big_map_get_add', - [ - '--arg', - '(Pair (Pair 401 (Some 0)) (Pair 400 (Some 1232)))', - '--burn-cap', - '10', - ], - ) - bake(client) - - -@pytest.mark.regression -class TestMacroExpansion: - """Test expanding macros""" - - @pytest.mark.parametrize("contract", all_contracts(['macros'])) - def test_macro_expansion( - self, client_regtest: ClientRegression, contract: str - ): - """This test expands macros in all macro test contracts, with - regression detection enabled. This test should fail if the definition - of any macros change. - """ - client_regtest.expand_macros(path.join(CONTRACT_PATH, contract)) diff --git a/tests_python/tests_012/test_contract_onchain_opcodes.py b/tests_python/tests_012/test_contract_onchain_opcodes.py deleted file mode 100644 index 16f920fd6ede..000000000000 --- a/tests_python/tests_012/test_contract_onchain_opcodes.py +++ /dev/null @@ -1,1312 +0,0 @@ -from os import path - -import pytest -from tools.client_regression import ClientRegression -from tools import paths -from tools.utils import ( - assert_run_failure, - assert_storage_contains, - bake, - init_with_transfer, - assert_balance, -) -from tools.constants import IDENTITIES -from .contract_paths import OPCODES_CONTRACT_PATH, MINI_SCENARIOS_CONTRACT_PATH -from . import protocol - -KEY1 = 'foo' -KEY2 = 'bar' - - -@pytest.mark.incremental -@pytest.mark.slow -@pytest.mark.contract -@pytest.mark.regression -class TestContractOnchainOpcodes: - """Tests for individual opcodes that requires origination.""" - - def test_gen_keys(self, client_regtest_scrubbed: ClientRegression): - """Add keys used by later tests.""" - client = client_regtest_scrubbed - client.gen_key(KEY1) - client.gen_key(KEY2) - - def test_store_input(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - client.transfer(1000, "bootstrap1", KEY1, ['--burn-cap', '0.257']) - bake(client) - - client.transfer(2000, "bootstrap1", KEY2, ['--burn-cap', '0.257']) - bake(client) - - assert_balance(client, KEY1, 1000) - assert_balance(client, KEY2, 2000) - - # Create a contract and transfer 100 ꜩ to it - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'store_input.tz'), - '""', - 100, - 'bootstrap1', - ) - - client.transfer( - 100, - "bootstrap1", - "store_input", - ["-arg", '"abcdefg"', '--burn-cap', '10'], - ) - bake(client) - - assert_balance(client, "store_input", 200) - - assert_storage_contains(client, "store_input", '"abcdefg"') - - client.transfer( - 100, - "bootstrap1", - "store_input", - ["-arg", '"xyz"', '--burn-cap', '10'], - ) - bake(client) - - assert_storage_contains(client, "store_input", '"xyz"') - - def test_transfer_amount(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'transfer_amount.tz'), - '0', - 100, - 'bootstrap1', - ) - - client.transfer( - 500, - "bootstrap1", - 'transfer_amount', - ['-arg', 'Unit', '--burn-cap', '10'], - ) - - bake(client) - - assert_storage_contains(client, "transfer_amount", '500000000') - - def test_now(self, client_regtest_scrubbed: ClientRegression): - # Regtest is disabled for this test, since one would need to - # scrub storage for this one as it changes (the timestamp) - # on every run. - client = client_regtest_scrubbed - client.set_regtest(None) - - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'store_now.tz'), - '"2017-07-13T09:19:01Z"', - 100, - 'bootstrap1', - ) - - client.transfer( - 500, "bootstrap1", 'store_now', ['-arg', 'Unit', '--burn-cap', '10'] - ) - bake(client) - - assert_storage_contains( - client, 'store_now', f'"{protocol.get_now(client)}"' - ) - - def test_transfer_tokens(self, client_regtest_scrubbed: ClientRegression): - """Tests TRANSFER_TOKENS.""" - client = client_regtest_scrubbed - client.originate( - 'test_transfer_account1', - 100, - 'bootstrap1', - path.join(OPCODES_CONTRACT_PATH, 'noop.tz'), - ['--burn-cap', '10'], - ) - bake(client) - - client.originate( - 'test_transfer_account2', - 20, - 'bootstrap1', - path.join(OPCODES_CONTRACT_PATH, 'noop.tz'), - ['--burn-cap', '10'], - ) - bake(client) - - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'transfer_tokens.tz'), - 'Unit', - 1000, - 'bootstrap1', - ) - - assert_balance(client, 'test_transfer_account1', 100) - - account1_addr = client.get_contract_address('test_transfer_account1') - client.transfer( - 100, - 'bootstrap1', - 'transfer_tokens', - ['-arg', f'"{account1_addr}"', '--burn-cap', '10'], - ) - bake(client) - - # Why isn't this 200 ꜩ? Baking fee? - assert_balance(client, 'test_transfer_account1', 200) - - account2_addr = client.get_contract_address('test_transfer_account2') - client.transfer( - 100, - 'bootstrap1', - 'transfer_tokens', - ['-arg', f'"{account2_addr}"', '--burn-cap', '10'], - ) - bake(client) - - assert_balance(client, 'test_transfer_account2', 120) - - def test_self(self, client_regtest_scrubbed: ClientRegression): - # Regtest is disabled for this test, since one would need to - # scrub storage for this one as it changes (the contract - # address) on every run. - client = client_regtest_scrubbed - client.set_regtest(None) - - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'self.tz'), - '"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"', - 1000, - 'bootstrap1', - ) - - client.transfer(0, 'bootstrap1', 'self', ['--burn-cap', '10']) - bake(client) - - self_addr = client.get_contract_address('self') - assert_storage_contains(client, 'self', f'"{self_addr}"') - - def test_contract_fails(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - client.set_regtest(None) - - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'contract.tz'), - 'Unit', - 1000, - 'bootstrap1', - ) - - client.transfer(0, 'bootstrap1', 'self', ['--burn-cap', '10']) - bake(client) - addr = client.get_contract_address('contract') - - with assert_run_failure(r'script reached FAILWITH instruction'): - client.transfer( - 0, - 'bootstrap1', - 'contract', - ['-arg', f'"{addr}"', '--burn-cap', '10'], - ) - - def test_init_proxy(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'proxy.tz'), - 'Unit', - 1000, - 'bootstrap1', - ) - - def test_source(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - init_store = IDENTITIES['bootstrap4']['identity'] - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'source.tz'), - f'"{init_store}"', - 1000, - 'bootstrap1', - ) - - # direct transfer to the contract - client.transfer(0, 'bootstrap2', 'source', ['--burn-cap', '10']) - bake(client) - - source_addr = IDENTITIES['bootstrap2']['identity'] - assert_storage_contains(client, 'source', f'"{source_addr}"') - - # indirect transfer to the contract through proxy - contract_addr = client.get_contract_address('source') - client.transfer( - 0, - 'bootstrap2', - 'proxy', - ['--burn-cap', '10', '--arg', f'"{contract_addr}"'], - ) - bake(client) - assert_storage_contains(client, 'source', f'"{source_addr}"') - - def test_sender(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - client.set_regtest(None) - - init_store = IDENTITIES['bootstrap4']['identity'] - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'sender.tz'), - f'"{init_store}"', - 1000, - 'bootstrap1', - ) - - # direct transfer to the contract - client.transfer(0, 'bootstrap2', 'sender', ['--burn-cap', '10']) - bake(client) - - sender_addr = IDENTITIES['bootstrap2']['identity'] - assert_storage_contains(client, 'sender', f'"{sender_addr}"') - - # indirect transfer to the contract through proxy - contract_addr = client.get_contract_address('sender') - proxy_addr = client.get_contract_address('proxy') - client.transfer( - 0, - 'bootstrap2', - 'proxy', - ['--burn-cap', '10', '--arg', f'"{contract_addr}"'], - ) - bake(client) - assert_storage_contains(client, 'sender', f'"{proxy_addr}"') - - def test_slice(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'slices.tz'), - '"sppk7dBPqMPjDjXgKbb5f7V3PuKUrA4Zuwc3c3H7XqQerqPUWbK7Hna"', - 1000, - 'bootstrap1', - ) - - @pytest.mark.parametrize( - 'contract_arg', - [ - line.rstrip('\n') - for line in open( - f'{paths.TEZOS_HOME}' - + '/tests_python/tests_012/' - + 'test_slice_fails_params.txt' - ) - ], - ) - def test_slice_fails( - self, client_regtest_scrubbed: ClientRegression, contract_arg: str - ): - client = client_regtest_scrubbed - - with assert_run_failure(r'script reached FAILWITH instruction'): - client.transfer( - 0, - 'bootstrap1', - 'slices', - ['-arg', contract_arg, '--burn-cap', '10'], - ) - # bake(client) - - @pytest.mark.parametrize( - 'contract_arg', - [ - line.rstrip('\n') - for line in open( - f'{paths.TEZOS_HOME}' - + '/tests_python/tests_012/' - + 'test_slice_success_params.txt' - ) - ], - ) - def test_slice_success( - self, client_regtest_scrubbed: ClientRegression, contract_arg: str - ): - client = client_regtest_scrubbed - client.transfer( - 0, - 'bootstrap1', - 'slices', - ['-arg', contract_arg, '--burn-cap', '10'], - ) - bake(client) - - def test_split_string(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'split_string.tz'), - '{}', - 1000, - 'bootstrap1', - ) - - client.transfer( - 0, - 'bootstrap1', - 'split_string', - ['-arg', '"abc"', '--burn-cap', '10'], - ) - bake(client) - assert_storage_contains(client, 'split_string', '{ "a" ; "b" ; "c" }') - - client.transfer( - 0, - 'bootstrap1', - 'split_string', - ['-arg', '"def"', '--burn-cap', '10'], - ) - bake(client) - assert_storage_contains( - client, 'split_string', '{ "a" ; "b" ; "c" ; "d" ; "e" ; "f" }' - ) - - def test_split_bytes(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'split_bytes.tz'), - '{}', - 1000, - 'bootstrap1', - ) - - client.transfer( - 0, - 'bootstrap1', - 'split_bytes', - ['-arg', '0xaabbcc', '--burn-cap', '10'], - ) - bake(client) - assert_storage_contains(client, 'split_bytes', '{ 0xaa ; 0xbb ; 0xcc }') - - client.transfer( - 0, - 'bootstrap1', - 'split_bytes', - ['-arg', '0xddeeff', '--burn-cap', '10'], - ) - bake(client) - assert_storage_contains( - client, 'split_bytes', '{ 0xaa ; 0xbb ; 0xcc ; 0xdd ; 0xee ; 0xff }' - ) - - def test_set_delegate(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'set_delegate.tz'), - 'Unit', - 1000, - 'bootstrap1', - ) - bake(client) - - assert client.get_delegate('set_delegate').delegate is None - - addr = IDENTITIES['bootstrap5']['identity'] - client.transfer( - 0, 'bootstrap1', 'set_delegate', ['-arg', f'(Some "{addr}")'] - ) - bake(client) - - assert client.get_delegate('set_delegate').delegate == addr - - client.transfer(0, 'bootstrap1', 'set_delegate', ['-arg', 'None']) - bake(client) - - assert client.get_delegate('set_delegate').delegate is None - - @pytest.mark.parametrize( - 'contract', - [ - 'compare_big_type.tz', - 'compare_big_type2.tz', - ], - ) - def test_trace_origination(self, client_regtest_scrubbed, contract): - client = client_regtest_scrubbed - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, contract), - 'Unit', - 1000, - 'bootstrap1', - ) - bake(client) - - -@pytest.mark.incremental -class TestTickets: - """Tests for tickets.""" - - def test_ticket_user_forge(self, client): - bake(client) - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticket_store-2.tz'), - 'None', - 100, - 'bootstrap1', - 'storer', - ) - - # Create parameter by hand with a ticket type but no ticket in it - client.transfer( - 100, 'bootstrap1', 'storer', ['-arg', 'None', '--burn-cap', '10'] - ) - - with assert_run_failure(r'Unexpected forged value'): - # Create parameter by hand with a ticket in it - client.transfer( - 100, - 'bootstrap1', - 'storer', - ['-arg', 'Some 1', '--burn-cap', '10'], - ) - - with assert_run_failure(r'Unexpected forged value'): - # Create storage by hand with a ticket in it - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticket_bad.tz'), - '1', - 100, - 'bootstrap1', - 'ticket_bad', - ) - - def test_ticket_user_big_forge(self, client): - bake(client) - contract_name = 'big_storer' - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticket_big_store.tz'), - '{}', - 100, - 'bootstrap1', - contract_name, - ) - bake(client) - client.transfer( - 100, 'bootstrap1', contract_name, ['-arg', '42', '--burn-cap', '10'] - ) - bake(client) - storage = client.get_storage(contract_name) - - with assert_run_failure(r'Unexpected forged value'): - # Create a storage with the ID of a big map that has tickets in it - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticket_big_store.tz'), - storage, - 100, - 'bootstrap1', - 'thief', - ) - - with assert_run_failure(r'Unexpected forged value'): - # Create a storage with the ID of a big map that has tickets in it - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticket_big_store.tz'), - '(Pair ' + storage + ' {})', - 100, - 'bootstrap1', - 'thief', - ) - - def test_ticket_read(self, client): - """Test TICKETS""" - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticketer.tz'), - '42', - 100, - 'bootstrap1', - 'ticketer_read', - ) - bake(client) - ticketer_addr = client.get_contract_address('ticketer_read') - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticket_read.tz'), - '"' + ticketer_addr + '"', - 100, - 'bootstrap1', - 'reader', - ) - bake(client) - reader_addr = client.get_contract_address('reader') - client.transfer( - 100, - 'bootstrap1', - 'ticketer_read', - ['-arg', '"' + reader_addr + '"', '--burn-cap', '10'], - ) - bake(client) - assert_storage_contains(client, "reader", '"' + ticketer_addr + '"') - - def test_bad_ticket(self, client): - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticketer.tz'), - '42', - 100, - 'bootstrap1', - 'ticketer_bad', - ) - bake(client) - ticketer_addr = client.get_contract_address('ticketer_bad') - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticket_read.tz'), - '"' + ticketer_addr + '"', - 100, - 'bootstrap1', - 'reader_bad', - ) - bake(client) - with assert_run_failure(r'Unexpected forged value'): - client.transfer( - 100, - 'bootstrap1', - 'reader_bad', - ['-arg', '1', '--burn-cap', '10'], - ) - bake(client) - - def test_ticket_utxo(self, client): - """Test UTXOs""" - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'utxor.tz'), - '42', - 100, - 'bootstrap1', - ) - bake(client) - utxor_addr = client.get_contract_address('utxor') - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'utxo_read.tz'), - '"' + utxor_addr + '"', - 100, - 'bootstrap1', - "reader_a", - ) - bake(client) - reader_a_addr = client.get_contract_address('reader_a') - utxor_addr = client.get_contract_address('utxor') - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'utxo_read.tz'), - '"' + utxor_addr + '"', - 100, - 'bootstrap1', - "reader_b", - ) - bake(client) - reader_b_addr = client.get_contract_address('reader_b') - client.transfer( - 100, - 'bootstrap1', - 'utxor', - [ - '-arg', - '(Pair "' + reader_a_addr + '" "' + reader_b_addr + '")', - '--burn-cap', - '10', - ], - ) - bake(client) - - def test_ticket_split(self, client): - def ticket(target_addr, param, utxo_amount): - param = ( - '(Pair (Pair "' - + target_addr - + '" ' - + str(param) - + ') ' - + str(utxo_amount) - + ')' - ) - client.transfer( - 100, - 'bootstrap1', - 'ticketer', - ['-arg', param, '--burn-cap', '10'], - ) - - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticketer-2.tz'), - 'Unit', - 100, - 'bootstrap1', - 'ticketer', - ) - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticket_split.tz'), - 'Unit', - 100, - 'bootstrap1', - 'splitter', - ) - bake(client) - splitter_addr = client.get_contract_address('splitter') - ticket(splitter_addr, 42, 3) - with assert_run_failure(r'script reached FAILWITH instruction'): - # Wrong Split Amount - ticket(splitter_addr, 42, 4) - bake(client) - - def test_ticket_join(self, client): - """Test JOIN""" - - def params(target_addr, utxo_amount, param): - return ( - '(Pair (Pair "' - + target_addr - + '" ' - + str(param) - + ') ' - + str(utxo_amount) - + ')' - ) - - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticketer-2.tz'), - 'Unit', - 100, - 'bootstrap1', - 'ticketer_a', - ) - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticketer-2.tz'), - 'Unit', - 100, - 'bootstrap1', - 'ticketer_b', - ) - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'ticket_join.tz'), - 'None', - 100, - 'bootstrap1', - 'joiner', - ) - bake(client) - joiner_addr = client.get_contract_address('joiner') - client.transfer( - 100, - 'bootstrap1', - 'ticketer_a', - ['-arg', params(joiner_addr, 42, 1), '--burn-cap', '10'], - ) - bake(client) - client.transfer( - 100, - 'bootstrap1', - 'ticketer_a', - ['-arg', params(joiner_addr, 144, 1), '--burn-cap', '10'], - ) - bake(client) - with assert_run_failure(r'script reached FAILWITH instruction'): - # Different Ticketer - client.transfer( - 100, - 'bootstrap1', - 'ticketer_b', - ['-arg', params(joiner_addr, 23, 1), '--burn-cap', '10'], - ) - with assert_run_failure(r'script reached FAILWITH instruction'): - # Different Content - client.transfer( - 100, - 'bootstrap1', - 'ticketer_a', - ['-arg', params(joiner_addr, 21, 23), '--burn-cap', '10'], - ) - - def test_ticket_fungible_originations(self, client, session): - """Test the origination of builder and wallet contracts for fungible - tokens implemented using tickets.""" - - builder_path = path.join( - MINI_SCENARIOS_CONTRACT_PATH, 'ticket_builder_fungible.tz' - ) - - wallet_path = path.join( - MINI_SCENARIOS_CONTRACT_PATH, 'ticket_wallet_fungible.tz' - ) - - manager_address = IDENTITIES['bootstrap1']['identity'] - - builders = {} - wallets = {} - - # Helper functions - def originate_builder(name): - """Create a fungible token contract managed by bootstrap1.""" - origination = client.originate( - contract_name=f'builder_{name}', - amount="0", - sender='bootstrap1', - contract=builder_path, - args=['--init', f'"{manager_address}"', '--burn-cap', "10"], - ) - builders[name] = origination.contract - bake(client) - - def originate_wallet(name): - """Create a fungible token wallet managed by bootstrap1.""" - origination = client.originate( - contract_name=f'wallet_{name}', - amount="0", - sender='bootstrap1', - contract=wallet_path, - args=[ - '--init', - f'Pair "{manager_address}" {{}}', - '--burn-cap', - "10", - ], - ) - wallets[name] = origination.contract - bake(client) - - # Create 3 token contracts "A", "B", and "C". - originate_builder("A") - originate_builder("B") - originate_builder("C") - - # Create 2 wallets "Alice" and "Bob". - originate_wallet("Alice") - originate_wallet("Bob") - - session['fungible_builders'] = builders - session['fungible_wallets'] = wallets - - def test_ticket_fungible_transfers(self, client, session): - """Test the life cycle of fungible tokens implemented using tickets.""" - - manager_address = IDENTITIES['bootstrap1']['identity'] - - builders = session['fungible_builders'] - wallets = session['fungible_wallets'] - - def mint(builder, wallet, amount): - """Mint fungible tokens.""" - wallet_address = wallets[wallet] - parameter = f'(Pair "{wallet_address}%receive" {amount})' - client.transfer( - amount=0, - giver=manager_address, - receiver=f'builder_{builder}', - args=[ - '--burn-cap', - '2', - '--entrypoint', - 'mint', - '--arg', - parameter, - ], - ) - bake(client) - - def burn(builder, wallet, amount): - """Burn fungible tokens.""" - builder_addr = builders[builder] - parameter = f'Pair "{builder_addr}%burn" {amount} "{builder_addr}"' - client.transfer( - amount=0, - giver=manager_address, - receiver=f'wallet_{wallet}', - args=[ - '--burn-cap', - '2', - '--entrypoint', - 'send', - '--arg', - parameter, - ], - ) - bake(client) - - def transfer(builder, source_wallet, destination_wallet, amount): - """Transfer fungible tokens.""" - builder_addr = builders[builder] - dest_addr = wallets[destination_wallet] - parameter = f'Pair "{dest_addr}%receive" {amount} "{builder_addr}"' - client.transfer( - amount=0, - giver=manager_address, - receiver=f'wallet_{source_wallet}', - args=[ - '--burn-cap', - '2', - '--entrypoint', - 'send', - '--arg', - parameter, - ], - ) - bake(client) - - # 100A --> Alice - mint(builder="A", wallet="Alice", amount=100) - # 100B --> Alice - mint(builder="B", wallet="Alice", amount=100) - - # Fail: Alice --1C--> Bob - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="C", - source_wallet="Alice", - destination_wallet="Bob", - amount=1, - ) - - # Fail: Alice --0C--> Bob - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="C", - source_wallet="Alice", - destination_wallet="Bob", - amount=0, - ) - - # Fail: Alice --150A--> Bob - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="A", - source_wallet="Alice", - destination_wallet="Bob", - amount=150, - ) - - # Fail: Bob --50A--> Alice - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="A", - source_wallet="Bob", - destination_wallet="Alice", - amount=50, - ) - - # Alice --50A--> Bob - transfer( - builder="A", - source_wallet="Alice", - destination_wallet="Bob", - amount=50, - ) - - # Alice --50A--> Bob - transfer( - builder="A", - source_wallet="Alice", - destination_wallet="Bob", - amount=50, - ) - - # Alice --0A--> Bob - transfer( - builder="A", - source_wallet="Alice", - destination_wallet="Bob", - amount=0, - ) - - # Fail: Alice --1A--> Bob - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="A", - source_wallet="Alice", - destination_wallet="Bob", - amount=1, - ) - - # Bob --100A--> Bob - transfer( - builder="A", - source_wallet="Bob", - destination_wallet="Bob", - amount=100, - ) - - # Fail: Bob --150A--> Bob - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="A", - source_wallet="Bob", - destination_wallet="Bob", - amount=150, - ) - - # Bob --100A--> - burn(builder="A", wallet="Bob", amount=100) - - # Bob --0A--> - burn(builder="A", wallet="Bob", amount=0) - - # Fail: Bob --1A--> - with assert_run_failure(r'script reached FAILWITH instruction'): - burn(builder="A", wallet="Bob", amount=1) - - def test_ticket_non_fungible_originations(self, client, session): - """Test the origination of builder and wallet contracts for - non-fungible tokens implemented using tickets.""" - - builder_path = path.join( - MINI_SCENARIOS_CONTRACT_PATH, 'ticket_builder_non_fungible.tz' - ) - - wallet_path = path.join( - MINI_SCENARIOS_CONTRACT_PATH, 'ticket_wallet_non_fungible.tz' - ) - - manager_address = IDENTITIES['bootstrap1']['identity'] - - builders = {} - wallets = {} - - # Helper functions - def originate_builder(name): - """Create a non-fungible token contract managed by bootstrap1.""" - storage = f'(Pair "{manager_address}" 0)' - origination = client.originate( - contract_name=f'nft_builder_{name}', - amount="0", - sender='bootstrap1', - contract=builder_path, - args=['--init', storage, '--burn-cap', "10"], - ) - builders[name] = origination.contract - bake(client) - - def originate_wallet(name): - """Create a non-fungible token wallet managed by bootstrap1.""" - origination = client.originate( - contract_name=f'nft_wallet_{name}', - amount="0", - sender='bootstrap1', - contract=wallet_path, - args=[ - '--init', - f'Pair "{manager_address}" {{}}', - '--burn-cap', - "10", - ], - ) - wallets[name] = origination.contract - bake(client) - - # Create 3 token contracts "A", "B", and "C". - originate_builder("A") - originate_builder("B") - originate_builder("C") - - # Create 2 wallets "Alice" and "Bob". - originate_wallet("Alice") - originate_wallet("Bob") - - session['non_fungible_builders'] = builders - session['non_fungible_wallets'] = wallets - - def test_ticket_non_fungible_transfers(self, client, session): - """Test the life cycle of non-fungible tokens implemented using - tickets.""" - - manager_address = IDENTITIES['bootstrap1']['identity'] - - builders = session['non_fungible_builders'] - wallets = session['non_fungible_wallets'] - - def mint(builder, wallet, token_id): - """Mint a non-fungible token and assert that it has the expected - id.""" - builder_alias = f'nft_builder_{builder}' - expected_builder_storage = f'Pair "{manager_address}" {token_id}' - actual_builder_storage = client.get_storage(builder_alias) - assert expected_builder_storage == actual_builder_storage - - wallet_address = wallets[wallet] - parameter = f'"{wallet_address}%receive"' - client.transfer( - amount=0, - giver=manager_address, - receiver=builder_alias, - args=[ - '--burn-cap', - '2', - '--entrypoint', - 'mint_destination', - '--arg', - parameter, - ], - ) - bake(client) - - def burn(builder, wallet, token_id): - """Burn a non-fungible token.""" - builder_addr = builders[builder] - parameter = ( - f'Pair "{builder_addr}%burn" "{builder_addr}" {token_id}' - ) - client.transfer( - amount=0, - giver=manager_address, - receiver=f'nft_wallet_{wallet}', - args=[ - '--burn-cap', - '2', - '--entrypoint', - 'send', - '--arg', - parameter, - ], - ) - bake(client) - - def transfer(builder, source_wallet, destination_wallet, token_id): - """Transfer fungible tokens.""" - builder_addr = builders[builder] - dest_addr = wallets[destination_wallet] - parameter = ( - f'Pair "{dest_addr}%receive" "{builder_addr}" {token_id}' - ) - client.transfer( - amount=0, - giver=manager_address, - receiver=f'nft_wallet_{source_wallet}', - args=[ - '--burn-cap', - '2', - '--entrypoint', - 'send', - '--arg', - parameter, - ], - ) - bake(client) - - # A0 --> Alice - mint(builder="A", wallet="Alice", token_id=0) - # A1 --> Alice - mint(builder="A", wallet="Alice", token_id=1) - # B0 --> Alice - mint(builder="B", wallet="Alice", token_id=0) - - # Fail: Alice --C0--> Bob - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="C", - source_wallet="Alice", - destination_wallet="Bob", - token_id=0, - ) - - # Fail: Alice --A2--> Bob - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="A", - source_wallet="Alice", - destination_wallet="Bob", - token_id=2, - ) - - # Fail: Bob --A0--> Alice - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="A", - source_wallet="Bob", - destination_wallet="Alice", - token_id=0, - ) - - # Fail: Bob --A1--> Bob - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="A", - source_wallet="Bob", - destination_wallet="Bob", - token_id=1, - ) - - # Alice --A1--> Bob - transfer( - builder="A", - source_wallet="Alice", - destination_wallet="Bob", - token_id=1, - ) - - # Alice --A0--> Bob - transfer( - builder="A", - source_wallet="Alice", - destination_wallet="Bob", - token_id=0, - ) - - # Fail: Alice --A1--> Bob - with assert_run_failure(r'script reached FAILWITH instruction'): - transfer( - builder="A", - source_wallet="Alice", - destination_wallet="Bob", - token_id=1, - ) - - # Bob --A0--> Bob - transfer( - builder="A", - source_wallet="Bob", - destination_wallet="Bob", - token_id=0, - ) - - # Bob --A0--> - burn(builder="A", wallet="Bob", token_id=0) - - # Bob --A1--> - burn(builder="A", wallet="Bob", token_id=1) - - # Fail: Bob --B0--> - with assert_run_failure(r'script reached FAILWITH instruction'): - burn(builder="B", wallet="Bob", token_id=0) - - # Alice --B0--> - burn(builder="B", wallet="Alice", token_id=0) - - -ORIGINATE_BIG_MAP_FILE = path.join( - OPCODES_CONTRACT_PATH, 'originate_big_map.tz' -) - - -@pytest.mark.incremental -@pytest.mark.contract -@pytest.mark.regression -class TestContractBigMapOrigination: - def test_big_map_origination_literal(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - # originate a first version of the contract from a literal so - # that a big_map with id 0 exists - init_with_transfer( - client, - ORIGINATE_BIG_MAP_FILE, - '{Elt 0 0}', - 1000, - 'bootstrap1', - contract_name='originate_big_map_literal', - ) - - def test_big_map_origination_id(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - # originate again the same script from the big-map id 0 - with assert_run_failure(r'Unexpected forged value'): - init_with_transfer( - client, - ORIGINATE_BIG_MAP_FILE, - '0', - 1000, - 'bootstrap1', - contract_name='originate_big_map_id', - ) - - def test_big_map_origination_diff(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - - # originate again the same script from a big-diff - with assert_run_failure(r'Unexpected forged value'): - init_with_transfer( - client, - ORIGINATE_BIG_MAP_FILE, - 'Pair 0 {Elt 1 (Some 4)}', - 1000, - 'bootstrap1', - contract_name='originate_big_map_diff', - ) - - def test_big_map_transfer_id(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - # call the first contract, passing an id as parameter - with assert_run_failure(r'Unexpected forged value'): - client.call( - source='bootstrap1', - destination='originate_big_map_literal', - args=['--arg', '0'], - ) - - def test_big_map_transfer_diff(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - # call the first contract, passing a diff as parameter - with assert_run_failure(r'Unexpected forged value'): - client.call( - source='bootstrap1', - destination='originate_big_map_literal', - args=['--arg', 'Pair 0 {Elt 1 (Some 4)}'], - ) - - -@pytest.mark.incremental -@pytest.mark.slow -@pytest.mark.contract -@pytest.mark.regression -class TestContractOnchainLevel: - """Onchain tests for LEVEL.""" - - # This test needs to be in a separate class to not depend on the number - # of operations happening before - - def test_level(self, client_regtest_scrubbed: ClientRegression): - client = client_regtest_scrubbed - - init_with_transfer( - client, - path.join(OPCODES_CONTRACT_PATH, 'level.tz'), - '9999999', - 100, - 'bootstrap1', - ) - bake(client) - client.transfer( - 500, "bootstrap1", 'level', ['-arg', 'Unit', '--burn-cap', '10'] - ) - bake(client) - level = client.get_level() - slevel = str(level) - assert_storage_contains(client, 'level', slevel) - bake(client) - bake(client) - # checks the storage hasn't changed even though the current level has - assert_storage_contains(client, 'level', slevel) - # Run again to check the storage gets updated - client.transfer( - 500, "bootstrap1", 'level', ['-arg', 'Unit', '--burn-cap', '10'] - ) - bake(client) - assert_storage_contains(client, 'level', str(level + 3)) diff --git a/tests_python/tests_012/test_contract_opcodes.py b/tests_python/tests_012/test_contract_opcodes.py deleted file mode 100644 index abab6e86b61e..000000000000 --- a/tests_python/tests_012/test_contract_opcodes.py +++ /dev/null @@ -1,1943 +0,0 @@ -from os import path - -import pytest - -from tools.client_regression import ClientRegression -from tools.constants import IDENTITIES -from tools.utils import ( - assert_run_failure, - assert_run_script_failwith, - assert_run_script_success, -) -from .contract_paths import MINI_SCENARIOS_CONTRACT_PATH, OPCODES_CONTRACT_PATH - - -PUBLIC_KEY = IDENTITIES['bootstrap1']['public'] - - -@pytest.mark.slow -@pytest.mark.contract -@pytest.mark.regression -class TestContractOpcodes: - """Tests for individual opcodes that do not require origination.""" - - @pytest.mark.parametrize( - "contract,param,storage,expected", - [ # FORMAT: assert_output contract_file storage input expected_result - # TODO add tests for map_car.tz, subset.tz - # NB: noop.tz is tested in test_basic.sh - ('cons.tz', '{}', '10', '{ 10 }'), - ('cons.tz', '{ 10 }', '-5', '{ -5 ; 10 }'), - ('cons.tz', '{ -5 ; 10 }', '99', '{ 99 ; -5 ; 10 }'), - # Tests on Options - ('none.tz', 'Some 10', 'Unit', 'None'), - ('ret_int.tz', 'None', 'Unit', '(Some 300)'), - # Map block on lists - ('list_map_block.tz', '{0}', '{}', '{}'), - ( - 'list_map_block.tz', - '{0}', - '{ 1 ; 1 ; 1 ; 1 }', - '{ 1 ; 2 ; 3 ; 4 }', - ), - ( - 'list_map_block.tz', - '{0}', - '{ 1 ; 2 ; 3 ; 0 }', - '{ 1 ; 3 ; 5 ; 3 }', - ), - # Reverse a list - ('reverse.tz', '{""}', '{}', '{}'), - ( - 'reverse.tz', - '{""}', - '{ "c" ; "b" ; "a" }', - '{ "a" ; "b" ; "c" }', - ), - # Reverse using LOOP_LEFT - ('loop_left.tz', '{""}', '{}', '{}'), - ( - 'loop_left.tz', - '{""}', - '{ "c" ; "b" ; "a" }', - '{ "a" ; "b" ; "c" }', - ), - # Identity on strings - ('str_id.tz', 'None', '"Hello"', '(Some "Hello")'), - ('str_id.tz', 'None', '"abcd"', '(Some "abcd")'), - # Slice strings - ('slice.tz', 'None', 'Pair 0 0', 'None'), - ('slice.tz', 'Some "Foo"', 'Pair 10 5', 'None'), - ('slice.tz', 'Some "Foo"', 'Pair 0 0', '(Some "")'), - ('slice.tz', 'Some "Foo"', 'Pair 0 10', 'None'), - ('slice.tz', 'Some "Foo"', 'Pair 0 2', '(Some "Fo")'), - ('slice.tz', 'Some "Foo"', 'Pair 1 3', 'None'), - ('slice.tz', 'Some "Foo"', 'Pair 1 1', '(Some "o")'), - # Stress-test the failure case of slice for a - # non-trivial gas consumption - ( - 'slice.tz', - 'Some' + '"' + 'Foo' * 2000 + '"', - 'Pair 1 10000', - 'None', - ), - # Slice bytes - ('slice_bytes.tz', 'None', 'Pair 0 1', 'None'), - ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 0 0', '(Some 0x)'), - ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 0 1', '(Some 0xaa)'), - ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 1 1', '(Some 0xbb)'), - ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 1 2', '(Some 0xbbcc)'), - ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 1 3', 'None'), - ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 1 1', '(Some 0xbb)'), - # Stress-test the failure case of slice for a - # non-trivial gas consumption - ( - 'slice_bytes.tz', - 'Some 0x' + 'aabbcc' * 2000, - 'Pair 1 10000', - 'None', - ), - # Identity on pairs - ( - 'pair_id.tz', - 'None', - '(Pair True False)', - '(Some (Pair True False))', - ), - ( - 'pair_id.tz', - 'None', - '(Pair False True)', - '(Some (Pair False True))', - ), - ( - 'pair_id.tz', - 'None', - '(Pair True True)', - '(Some (Pair True True))', - ), - ( - 'pair_id.tz', - 'None', - '(Pair False False)', - '(Some (Pair False False))', - ), - # Tests CAR and CDR instructions - ('car.tz', '0', '(Pair 34 17)', '34'), - ('cdr.tz', '0', '(Pair 34 17)', '17'), - # Logical not - ('not.tz', 'None', 'True', '(Some False)'), - ('not.tz', 'None', 'False', '(Some True)'), - # Logical and - ('and.tz', 'None', '(Pair False False)', '(Some False)'), - ('and.tz', 'None', '(Pair False True)', '(Some False)'), - ('and.tz', 'None', '(Pair True False)', '(Some False)'), - ('and.tz', 'None', '(Pair True True)', '(Some True)'), - # Logical or - ('or.tz', 'None', '(Pair False False)', '(Some False)'), - ('or.tz', 'None', '(Pair False True)', '(Some True)'), - ('or.tz', 'None', '(Pair True False)', '(Some True)'), - ('or.tz', 'None', '(Pair True True)', '(Some True)'), - # Logical and - ('and_logical_1.tz', 'False', "(Pair False False)", 'False'), - ('and_logical_1.tz', 'False', "(Pair False True)", 'False'), - ('and_logical_1.tz', 'False', "(Pair True False)", 'False'), - ('and_logical_1.tz', 'False', "(Pair True True)", 'True'), - # Binary and - ('and_binary.tz', 'Unit', 'Unit', 'Unit'), - # Binary or - ('or_binary.tz', 'None', '(Pair 4 8)', '(Some 12)'), - ('or_binary.tz', 'None', '(Pair 0 8)', '(Some 8)'), - ('or_binary.tz', 'None', '(Pair 8 0)', '(Some 8)'), - ('or_binary.tz', 'None', '(Pair 15 4)', '(Some 15)'), - ('or_binary.tz', 'None', '(Pair 14 1)', '(Some 15)'), - ('or_binary.tz', 'None', '(Pair 7 7)', '(Some 7)'), - # Binary not - ('not_binary.tz', 'None', '(Left 0)', '(Some -1)'), - ('not_binary.tz', 'None', '(Left 8)', '(Some -9)'), - ('not_binary.tz', 'None', '(Left 7)', '(Some -8)'), - ('not_binary.tz', 'None', '(Left -9)', '(Some 8)'), - ('not_binary.tz', 'None', '(Left -8)', '(Some 7)'), - ('not_binary.tz', 'None', '(Right 0)', '(Some -1)'), - ('not_binary.tz', 'None', '(Right 8)', '(Some -9)'), - ('not_binary.tz', 'None', '(Right 7)', '(Some -8)'), - # XOR - ( - 'xor.tz', - 'None', - 'Left (Pair False False)', - '(Some (Left False))', - ), - ('xor.tz', 'None', 'Left (Pair False True)', '(Some (Left True))'), - ('xor.tz', 'None', 'Left (Pair True False)', '(Some (Left True))'), - ('xor.tz', 'None', 'Left (Pair True True)', '(Some (Left False))'), - ('xor.tz', 'None', 'Right (Pair 0 0)', '(Some (Right 0))'), - ('xor.tz', 'None', 'Right (Pair 0 1)', '(Some (Right 1))'), - ('xor.tz', 'None', 'Right (Pair 1 0)', '(Some (Right 1))'), - ('xor.tz', 'None', 'Right (Pair 1 1)', '(Some (Right 0))'), - ('xor.tz', 'None', 'Right (Pair 42 21)', '(Some (Right 63))'), - ('xor.tz', 'None', 'Right (Pair 42 63)', '(Some (Right 21))'), - # test shifts: LSL & LSR - ('shifts.tz', 'None', '(Left (Pair 8 1))', '(Some 16)'), - ('shifts.tz', 'None', '(Left (Pair 0 0))', '(Some 0)'), - ('shifts.tz', 'None', '(Left (Pair 0 1))', '(Some 0)'), - ('shifts.tz', 'None', '(Left (Pair 1 2))', '(Some 4)'), - ('shifts.tz', 'None', '(Left (Pair 15 2))', '(Some 60)'), - ('shifts.tz', 'None', '(Right (Pair 8 1))', '(Some 4)'), - ('shifts.tz', 'None', '(Right (Pair 0 0))', '(Some 0)'), - ('shifts.tz', 'None', '(Right (Pair 0 1))', '(Some 0)'), - ('shifts.tz', 'None', '(Right (Pair 1 2))', '(Some 0)'), - ('shifts.tz', 'None', '(Right (Pair 15 2))', '(Some 3)'), - # Concatenate all strings of a list into one string - ('concat_list.tz', '""', '{ "a" ; "b" ; "c" }', '"abc"'), - ('concat_list.tz', '""', '{}', '""'), - ( - 'concat_list.tz', - '""', - '{ "Hello" ; " " ; "World" ; "!" }', - '"Hello World!"', - ), - # Concatenate the bytes in storage with all bytes in the given list - ('concat_hello_bytes.tz', '{}', '{ 0xcd }', '{ 0xffcd }'), - ('concat_hello_bytes.tz', '{}', '{}', '{}'), - ( - 'concat_hello_bytes.tz', - '{}', - '{ 0xab ; 0xcd }', - '{ 0xffab ; 0xffcd }', - ), - # Identity on lists - ( - 'list_id.tz', - '{""}', - '{ "1" ; "2" ; "3" }', - '{ "1" ; "2" ; "3" }', - ), - ('list_id.tz', '{""}', '{}', '{}'), - ( - 'list_id.tz', - '{""}', - '{ "a" ; "b" ; "c" }', - '{ "a" ; "b" ; "c" }', - ), - ( - 'list_id_map.tz', - '{""}', - '{ "1" ; "2" ; "3" }', - '{ "1" ; "2" ; "3" }', - ), - ('list_id_map.tz', '{""}', '{}', '{}'), - ( - 'list_id_map.tz', - '{""}', - '{ "a" ; "b" ; "c" }', - '{ "a" ; "b" ; "c" }', - ), - # Identity on maps - ('map_id.tz', '{}', '{ Elt 0 1 }', '{ Elt 0 1 }'), - ('map_id.tz', '{}', '{ Elt 0 0 }', '{ Elt 0 0 }'), - ( - 'map_id.tz', - '{}', - '{ Elt 0 0 ; Elt 3 4 }', - '{ Elt 0 0 ; Elt 3 4 }', - ), - # Memberships in maps - ( - 'map_mem_nat.tz', - '(Pair { Elt 0 1 } None)', - '1', - '(Pair { Elt 0 1 } (Some False))', - ), - ('map_mem_nat.tz', '(Pair {} None)', '1', '(Pair {} (Some False))'), - ( - 'map_mem_nat.tz', - '(Pair { Elt 1 0 } None)', - '1', - '(Pair { Elt 1 0 } (Some True))', - ), - ( - 'map_mem_nat.tz', - '(Pair { Elt 1 4 ; Elt 2 11 } None)', - '1', - '(Pair { Elt 1 4 ; Elt 2 11 } (Some True))', - ), - ( - 'map_mem_nat.tz', - '(Pair { Elt 1 4 ; Elt 2 11 } None)', - '2', - '(Pair { Elt 1 4 ; Elt 2 11 } (Some True))', - ), - ( - 'map_mem_nat.tz', - '(Pair { Elt 1 4 ; Elt 2 11 } None)', - '3', - '(Pair { Elt 1 4 ; Elt 2 11 } (Some False))', - ), - ( - 'map_mem_string.tz', - '(Pair { Elt "foo" 1 } None)', - '"bar"', - '(Pair { Elt "foo" 1 } (Some False))', - ), - ( - 'map_mem_string.tz', - '(Pair {} None)', - '"bar"', - '(Pair {} (Some False))', - ), - ( - 'map_mem_string.tz', - '(Pair { Elt "foo" 0 } None)', - '"foo"', - '(Pair { Elt "foo" 0 } (Some True))', - ), - ( - 'map_mem_string.tz', - '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', - '"foo"', - '(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True))', - ), - ( - 'map_mem_string.tz', - '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', - '"bar"', - '(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True))', - ), - ( - 'map_mem_string.tz', - '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', - '"baz"', - '(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False))', - ), - # Mapping over maps - ('map_map.tz', '{}', '10', '{}'), - ('map_map.tz', '{ Elt "foo" 1 }', '10', '{ Elt "foo" 11 }'), - ( - 'map_map.tz', - '{ Elt "bar" 5 ; Elt "foo" 1 }', - '15', - '{ Elt "bar" 20 ; Elt "foo" 16 }', - ), - # Memberships in big maps - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 0 1 } None)', - '1', - '(Pair 4 (Some False))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair {} None)', - '1', - '(Pair 4 (Some False))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 1 0 } None)', - '1', - '(Pair 4 (Some True))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 1 4 ; Elt 2 11 } None)', - '1', - '(Pair 4 (Some True))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 1 4 ; Elt 2 11 } None)', - '2', - '(Pair 4 (Some True))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 1 4 ; Elt 2 11 } None)', - '3', - '(Pair 4 (Some False))', - ), - ( - 'big_map_mem_string.tz', - '(Pair { Elt "foo" 1 } None)', - '"bar"', - '(Pair 4 (Some False))', - ), - ( - 'big_map_mem_string.tz', - '(Pair {} None)', - '"bar"', - '(Pair 4 (Some False))', - ), - ( - 'big_map_mem_string.tz', - '(Pair { Elt "foo" 0 } None)', - '"foo"', - '(Pair 4 (Some True))', - ), - ( - 'big_map_mem_string.tz', - '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', - '"foo"', - '(Pair 4 (Some True))', - ), - ( - 'big_map_mem_string.tz', - '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', - '"bar"', - '(Pair 4 (Some True))', - ), - ( - 'big_map_mem_string.tz', - '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', - '"baz"', - '(Pair 4 (Some False))', - ), - # Memberships in big maps - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 0 1 } None)', - '1', - '(Pair 4 (Some False))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair {} None)', - '1', - '(Pair 4 (Some False))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 1 0 } None)', - '1', - '(Pair 4 (Some True))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 1 4 ; Elt 2 11 } None)', - '1', - '(Pair 4 (Some True))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 1 4 ; Elt 2 11 } None)', - '2', - '(Pair 4 (Some True))', - ), - ( - 'big_map_mem_nat.tz', - '(Pair { Elt 1 4 ; Elt 2 11 } None)', - '3', - '(Pair 4 (Some False))', - ), - # Identity on sets - ('set_id.tz', '{}', '{ "a" ; "b" ; "c" }', '{ "a" ; "b" ; "c" }'), - ('set_id.tz', '{}', '{}', '{}'), - ('set_id.tz', '{}', '{ "asdf" ; "bcde" }', '{ "asdf" ; "bcde" }'), - # List concat - ('list_concat.tz', '"abc"', '{ "d" ; "e" ; "f" }', '"abcdef"'), - ('list_concat.tz', '"abc"', '{}', '"abc"'), - ( - 'list_concat_bytes.tz', - '0x00ab', - '{ 0xcd ; 0xef ; 0x00 }', - '0x00abcdef00', - ), - ( - 'list_concat_bytes.tz', - '0x', - '{ 0x00 ; 0x11 ; 0x00 }', - '0x001100', - ), - ('list_concat_bytes.tz', '0xabcd', '{}', '0xabcd'), - ('list_concat_bytes.tz', '0x', '{}', '0x'), - # List iter - ('list_iter.tz', '0', '{ 10 ; 2 ; 1 }', '20'), - ('list_iter.tz', '0', '{ 3 ; 6 ; 9 }', '162'), - # List size - ('list_size.tz', '111', '{}', '0'), - ('list_size.tz', '111', '{ 1 }', '1'), - ('list_size.tz', '111', '{ 1 ; 2 ; 3 }', '3'), - ('list_size.tz', '111', '{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }', '6'), - # Set member -- set is in storage - ( - 'set_member.tz', - '(Pair {} None)', - '"Hi"', - '(Pair {} (Some False))', - ), - ( - 'set_member.tz', - '(Pair { "Hi" } None)', - '"Hi"', - '(Pair { "Hi" } (Some True))', - ), - ( - 'set_member.tz', - '(Pair { "Hello" ; "World" } None)', - '""', - '(Pair { "Hello" ; "World" } (Some False))', - ), - # Set size - ('set_size.tz', '111', '{}', '0'), - ('set_size.tz', '111', '{ 1 }', '1'), - ('set_size.tz', '111', '{ 1 ; 2 ; 3 }', '3'), - ('set_size.tz', '111', '{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }', '6'), - # Set iter - ('set_iter.tz', '111', '{}', '0'), - ('set_iter.tz', '111', '{ 1 }', '1'), - ('set_iter.tz', '111', '{ -100 ; 1 ; 2 ; 3 }', '-94'), - # Map size - ('map_size.tz', '111', '{}', '0'), - ('map_size.tz', '111', '{ Elt "a" 1 }', '1'), - ( - 'map_size.tz', - '111', - '{ Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 }', - '3', - ), - ( - 'map_size.tz', - '111', - '{ Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 ; \ - Elt "d" 4 ; Elt "e" 5 ; Elt "f" 6 }', - '6', - ), - # Contains all elements -- does the second list contain - # all of the same elements as the first one? I'm ignoring - # element multiplicity - ('contains_all.tz', 'None', '(Pair {} {})', '(Some True)'), - ( - 'contains_all.tz', - 'None', - '(Pair { "c" } { "B" })', - '(Some False)', - ), - ( - 'contains_all.tz', - 'None', - '(Pair { "A" } { "B" })', - '(Some False)', - ), - ( - 'contains_all.tz', - 'None', - '(Pair { "B" } { "B" })', - '(Some True)', - ), - ( - 'contains_all.tz', - 'None', - '(Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" })', - '(Some True)', - ), - ( - 'contains_all.tz', - 'None', - '(Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" })', - '(Some True)', - ), - # Concatenate the string in storage with all strings in - # the given list - ('concat_hello.tz', '{}', '{ "World!" }', '{ "Hello World!" }'), - ('concat_hello.tz', '{}', '{}', '{}'), - ( - 'concat_hello.tz', - '{}', - '{ "test1" ; "test2" }', - '{ "Hello test1" ; "Hello test2" }', - ), - # Create an empty map and add a string to it - ('empty_map.tz', '{}', 'Unit', '{ Elt "hello" "world" }'), - # Get the value stored at the given key in the map - ( - 'get_map_value.tz', - '(Pair None { Elt "hello" "hi" })', - '"hello"', - '(Pair (Some "hi") { Elt "hello" "hi" })', - ), - ( - 'get_map_value.tz', - '(Pair None { Elt "hello" "hi" })', - '""', - '(Pair None { Elt "hello" "hi" })', - ), - ( - 'get_map_value.tz', - '(Pair None { Elt "1" "one" ; \ - Elt "2" "two" })', - '"1"', - '(Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" })', - ), - # Get and update the value stored at the given key in the map - ( - 'get_and_update_map.tz', - '(Pair None {})', - '"hello"', - '(Pair None {})', - ), - ( - 'get_and_update_map.tz', - '(Pair (Some 4) {})', - '"hello"', - '(Pair None { Elt "hello" 4 })', - ), - ( - 'get_and_update_map.tz', - '(Pair None { Elt "hello" 4 })', - '"hello"', - '(Pair (Some 4) {})', - ), - ( - 'get_and_update_map.tz', - '(Pair (Some 5) { Elt "hello" 4 })', - '"hello"', - '(Pair (Some 4) { Elt "hello" 5 })', - ), - ( - 'get_and_update_map.tz', - '(Pair (Some 5) { Elt "hello" 4 })', - '"hi"', - '(Pair None { Elt "hello" 4 ; Elt "hi" 5 })', - ), - ( - 'get_and_update_map.tz', - '(Pair None { Elt "1" 1 ; \ - Elt "2" 2 })', - '"1"', - '(Pair (Some 1) { Elt "2" 2 })', - ), - ( - 'get_and_update_map.tz', - '(Pair None { Elt "1" 1 ; \ - Elt "2" 2 })', - '"1"', - '(Pair (Some 1) { Elt "2" 2 })', - ), - # Map iter - ( - 'map_iter.tz', - '(Pair 0 0)', - '{ Elt 0 100 ; Elt 2 100 }', - '(Pair 2 200)', - ), - ( - 'map_iter.tz', - '(Pair 0 0)', - '{ Elt 1 1 ; Elt 2 100 }', - '(Pair 3 101)', - ), - # Return True if True branch of if was taken and False otherwise - ('if.tz', 'None', 'True', '(Some True)'), - ('if.tz', 'None', 'False', '(Some False)'), - # Generate a pair of or types - ('left_right.tz', '(Left "X")', '(Left True)', '(Right True)'), - ('left_right.tz', '(Left "X")', '(Right "a")', '(Left "a")'), - # Reverse a list - ('reverse_loop.tz', '{""}', '{}', '{}'), - ( - 'reverse_loop.tz', - '{""}', - '{ "c" ; "b" ; "a" }', - '{ "a" ; "b" ; "c" }', - ), - # Exec concat contract - ('exec_concat.tz', '"?"', '""', '"_abc"'), - ('exec_concat.tz', '"?"', '"test"', '"test_abc"'), - # Get the current balance of the contract - ('balance.tz', '111', 'Unit', '4000000000000'), - # Get the current level of the block - # Test the produced variable annotation - ('level.tz', '111', 'Unit', '1'), - # Test addition and subtraction on tez - ( - 'tez_add_sub.tz', - 'None', - '(Pair 2000000 1000000)', - '(Some (Pair 3000000 1000000))', - ), - ( - 'tez_add_sub.tz', - 'None', - '(Pair 2310000 1010000)', - '(Some (Pair 3320000 1300000))', - ), - # Test various additions - ('add.tz', 'Unit', 'Unit', 'Unit'), - # Test ABS - ('abs.tz', 'Unit', '12039123919239192312931', 'Unit'), - ('abs.tz', 'Unit', '0', 'Unit'), - ('abs.tz', 'Unit', '948', 'Unit'), - # Test INT - ('int.tz', 'None', '0', '(Some 0)'), - ('int.tz', 'None', '1', '(Some 1)'), - ('int.tz', 'None', '9999', '(Some 9999)'), - # Test DIP - ('dip.tz', '(Pair 0 0)', '(Pair 15 9)', '(Pair 15 24)'), - ('dip.tz', '(Pair 0 0)', '(Pair 1 1)', '(Pair 1 2)'), - # Test get first element of list - ('first.tz', '111', '{ 1 ; 2 ; 3 ; 4 }', '1'), - ('first.tz', '111', '{ 4 }', '4'), - # Hash input string - # Test assumed to be correct -- hash is based on encoding of AST - ( - 'hash_string.tz', - '0x00', - '"abcdefg"', - '0x46fdbcb4ea4eadad5615c' - + 'daa17d67f783e01e21149ce2b27de497600b4cd8f4e', - ), - ( - 'hash_string.tz', - '0x00', - '"12345"', - '0xb4c26c20de52a4eaf0d8a34' - + '0db47ad8cb1e74049570859c9a9a3952b204c772f', - ), - # IF_SOME - ('if_some.tz', '"?"', '(Some "hello")', '"hello"'), - ('if_some.tz', '"?"', 'None', '""'), - # Tests the SET_CAR and SET_CDR instructions - ('set_car.tz', '(Pair "hello" 0)', '"world"', '(Pair "world" 0)'), - ('set_car.tz', '(Pair "hello" 0)', '"abc"', '(Pair "abc" 0)'), - ('set_car.tz', '(Pair "hello" 0)', '""', '(Pair "" 0)'), - ('set_cdr.tz', '(Pair "hello" 0)', '1', '(Pair "hello" 1)'), - ('set_cdr.tz', '(Pair "hello" 500)', '3', '(Pair "hello" 3)'), - ('set_cdr.tz', '(Pair "hello" 7)', '100', '(Pair "hello" 100)'), - # Convert a public key to a public key hash - ( - 'hash_key.tz', - 'None', - '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"', - '(Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx")', - ), - ( - 'hash_key.tz', - 'None', - '"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTawUPqR8vZTAMcx61ES"', - '(Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k")', - ), - # Test timestamp operations - ( - 'add_timestamp_delta.tz', - 'None', - '(Pair 100 100)', - '(Some "1970-01-01T00:03:20Z")', - ), - ( - 'add_timestamp_delta.tz', - 'None', - '(Pair 100 -100)', - '(Some "1970-01-01T00:00:00Z")', - ), - ( - 'add_timestamp_delta.tz', - 'None', - '(Pair "1970-01-01T00:00:00Z" 0)', - '(Some "1970-01-01T00:00:00Z")', - ), - ( - 'add_delta_timestamp.tz', - 'None', - '(Pair 100 100)', - '(Some "1970-01-01T00:03:20Z")', - ), - ( - 'add_delta_timestamp.tz', - 'None', - '(Pair -100 100)', - '(Some "1970-01-01T00:00:00Z")', - ), - ( - 'add_delta_timestamp.tz', - 'None', - '(Pair 0 "1970-01-01T00:00:00Z")', - '(Some "1970-01-01T00:00:00Z")', - ), - ( - 'sub_timestamp_delta.tz', - '111', - '(Pair 100 100)', - '"1970-01-01T00:00:00Z"', - ), - ( - 'sub_timestamp_delta.tz', - '111', - '(Pair 100 -100)', - '"1970-01-01T00:03:20Z"', - ), - ( - 'sub_timestamp_delta.tz', - '111', - '(Pair 100 2000000000000000000)', - '-1999999999999999900', - ), - ('diff_timestamps.tz', '111', '(Pair 0 0)', '0'), - ('diff_timestamps.tz', '111', '(Pair 0 1)', '-1'), - ('diff_timestamps.tz', '111', '(Pair 1 0)', '1'), - ( - 'diff_timestamps.tz', - '111', - '(Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z")', - '200', - ), - # Test pack/unpack - ( - 'packunpack_rev.tz', - 'Unit', - '(Pair -1 (Pair 1 (Pair "foobar" (Pair 0x00AABBCC (Pair 1000 ' - + '(Pair False (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ' - + '(Pair "2019-09-09T08:35:33Z" ' - + '"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"))))))))', - 'Unit', - ), - ( - 'packunpack_rev.tz', - 'Unit', - '(Pair -1 (Pair 1 (Pair "foobar" (Pair 0x00AABBCC (Pair 1000 ' - + '(Pair False (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ' - + '(Pair "2019-09-09T08:35:33Z" ' - + '"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"))))))))', - 'Unit', - ), - ( - 'packunpack_rev_cty.tz', - 'Unit', - '(Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9' - + 'sDVC9yav" (Pair Unit (Pair "edsigthTzJ8X7MPmNeEwybRAv' - + 'dxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8' - + 'V2w8ayB5dMJzrYCHhD8C7" (Pair (Some "edsigthTzJ8X7MPmN' - + 'eEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5' - + 'CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") (Pair { Unit } (Pair' - + ' { True } (Pair (Pair 19 10) (Pair (Left "tz1cxcwwnz' - + 'ENRdhe2Kb8ZdTrdNy4bFNyScx5") (Pair { Elt 0 "foo" ; El' - + 't 1 "bar" } { PACK } )))))))))', - 'Unit', - ), - ( - 'packunpack_rev_cty.tz', - 'Unit', - '(Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9' - + 'sDVC9yav" (Pair Unit (Pair "edsigthTzJ8X7MPmNeEwybRAv' - + 'dxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8' - + 'V2w8ayB5dMJzrYCHhD8C7" (Pair None (Pair { } (Pair {' - + ' } (Pair (Pair 40 -10) (Pair (Right "2019-09-09T08:' - + '35:33Z") (Pair { } { DUP ; DROP ; PACK } )))))))))', - 'Unit', - ), - # Test EDIV on nat and int - ( - 'ediv.tz', - '(Pair None None None None)', - '(Pair 10 -3)', - '(Pair (Some (Pair -3 1)) (Some (Pair 3 1)) ' - + '(Some (Pair -3 1)) (Some (Pair 3 1)))', - ), - ( - 'ediv.tz', - '(Pair None None None None)', - '(Pair 10 0)', - '(Pair None None None None)', - ), - ( - 'ediv.tz', - '(Pair None None None None)', - '(Pair -8 2)', - '(Pair (Some (Pair -4 0)) (Some (Pair -4 0)) ' - + '(Some (Pair 4 0)) (Some (Pair 4 0)))', - ), - # Test EDIV on mutez - ( - 'ediv_mutez.tz', - '(Left None)', - '(Pair 10 (Left 10))', - '(Left (Some (Pair 1 0)))', - ), - ( - 'ediv_mutez.tz', - '(Left None)', - '(Pair 10 (Left 3))', - '(Left (Some (Pair 3 1)))', - ), - ( - 'ediv_mutez.tz', - '(Left None)', - '(Pair 10 (Left 0))', - '(Left None)', - ), - ( - 'ediv_mutez.tz', - '(Left None)', - '(Pair 10 (Right 10))', - '(Right (Some (Pair 1 0)))', - ), - ( - 'ediv_mutez.tz', - '(Left None)', - '(Pair 10 (Right 3))', - '(Right (Some (Pair 3 1)))', - ), - ( - 'ediv_mutez.tz', - '(Left None)', - '(Pair 10 (Right 0))', - '(Right None)', - ), - ( - 'ediv_mutez.tz', - '(Left None)', - '(Pair 5 (Right 10))', - '(Right (Some (Pair 0 5)))', - ), - # Test compare - ('compare.tz', 'Unit', 'Unit', 'Unit'), - # Test comparison combinators: - # GT, GE, LT, LE, NEQ, EQ - ( - 'comparisons.tz', - '{}', - '{ -9999999; -1 ; 0 ; 1 ; 9999999 }', - '{ ' + '{ False ; False ; False ; True ; True } ;' - "\n" - ' { False ; False ; True ; True ; True } ;' - "\n" - ' { True ; True ; False ; False ; False } ;' - "\n" - ' { True ; True ; True ; False ; False } ;' - "\n" - ' { True ; True ; False ; True ; True } ;' - "\n" - ' { False ; False ; True ; False ; False }' - ' }', - ), - # Test ADDRESS - ( - 'address.tz', - 'None', - '"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"', - '(Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5")', - ), - # Test (CONTRACT unit) - ( - 'contract.tz', - 'Unit', - '"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"', - 'Unit', - ), - # Test create_contract - ( - 'create_contract.tz', - 'None', - 'Unit', - '(Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm")', - ), - # Test multiplication - success case (no overflow) - # Failure case is tested in m̀ul_overflow.tz - ('mul.tz', 'Unit', 'Unit', 'Unit'), - # Test NEG - ('neg.tz', '0', '(Left 2)', '-2'), - ('neg.tz', '0', '(Right 2)', '-2'), - ('neg.tz', '0', '(Left 0)', '0'), - ('neg.tz', '0', '(Right 0)', '0'), - ('neg.tz', '0', '(Left -2)', '2'), - # Test DIGN, DUGN, DROPN, DIPN - ('dign.tz', '0', '(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)', '5'), - ('dugn.tz', '0', '(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)', '1'), - ('dropn.tz', '0', '(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)', '5'), - ('dipn.tz', '0', '(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)', '6'), - # Test DIGN 17 times. - ( - 'dig_eq.tz', - 'Unit', - '(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pair 13 (Pair 12' - + ' (Pair 11 (Pair 10 (Pair 9 (Pair 8 (Pair 7 (Pair 6 (P' - + 'air 5 (Pair 4 (Pair 3 (Pair 2 1))))))))))))))))', - 'Unit', - ), - ( - 'dig_eq.tz', - 'Unit', - '(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair 10 (Pair 14 (' - + 'Pair 19 (Pair 9 (Pair 18 (Pair 6 (Pair 8 (Pair 11 (Pa' - + 'ir 4 (Pair 13 (Pair 15 (Pair 5 1))))))))))))))))', - 'Unit', - ), - # Test Partial Exec - ('pexec.tz', '14', '38', '52'), - ('pexec_2.tz', "{ 0 ; 1 ; 2 ; 3}", '4', "{ 0 ; 7 ; 14 ; 21 }"), - # Test CHAIN_ID - ('chain_id_store.tz', 'None', 'Unit', '(Some "NetXdQprcVkpaWU")'), - ( - 'chain_id_store.tz', - '(Some 0x7a06a770)', - 'Unit', - '(Some "NetXdQprcVkpaWU")', - ), - ( - 'chain_id_store.tz', - '(Some "NetXdQprcVkpaWU")', - 'Unit', - '(Some "NetXdQprcVkpaWU")', - ), - # Test SELF - ('self_with_entrypoint.tz', 'Unit', 'Left (Left 0)', 'Unit'), - ('self_with_default_entrypoint.tz', 'Unit', 'Unit', 'Unit'), - # Test SELF_ADDRESS - ('self_address.tz', 'Unit', 'Unit', 'Unit'), - # Test UNPAIR - ('unpair.tz', 'Unit', 'Unit', 'Unit'), - # Test VOTING_POWER - ( - 'voting_power.tz', - '(Pair 0 0)', - f'"{PUBLIC_KEY}"', - '(Pair 666 3330)', - ), - # Test KECCAK - ( - 'keccak.tz', - 'None', - f'0x{b"Hello, world!".hex()}', - '(Some 0xb6e16d27ac5ab427a7f68900ac5559ce2' - + '72dc6c37c82b3e052246c82244c50e4)', - ), - # Test SHA3 - ( - 'sha3.tz', - 'None', - f'0x{b"Hello, world!".hex()}', - '(Some 0xf345a219da005ebe9c1a1eaad97bbf38' - + 'a10c8473e41d0af7fb617caa0c6aa722)', - ), - # Test COMBs - ('comb.tz', '(Pair 0 0 0)', 'Unit', '(Pair 1 2 3)'), - ('uncomb.tz', '0', '(Pair 1 4 2)', '142'), - ('comb-get.tz', 'Unit', '(Pair 1 4 2 Unit)', 'Unit'), - ('comb-set.tz', '(Pair 1 4 2 Unit)', 'Unit', '(Pair 2 12 8 Unit)'), - ( - 'comb-set-2.tz', - 'None', - '(Pair 1 4 2 Unit)', - '(Some (Pair 2 4 "toto" 0x01))', - ), - # Test DUP n - ('dup-n.tz', 'Unit', 'Unit', 'Unit'), - # Test Sapling - ('sapling_empty_state.tz', '{}', 'Unit', '0'), - # Test building Fr element from nat. - # The initial storage is dropped then any value is valid. - # Random values can be generated using the following OCaml program. - # let r = Bls12_381.Fr.(random ()) in - # let x = Bls12_381.Fr.random () in - # Printf.printf "Param = (Pair %s 0x%s). Result = 0x%s" - # (Bls12_381.Fr.to_string r) - # (Hex.(show (of_bytes (Bls12_381.Fr.to_bytes x)))) - # (Hex.(show (of_bytes (Bls12_381.Fr.(to_bytes (mul r x)))))) - ( - 'bls12_381_fr_z_nat.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '0', - '0x00000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_fr_z_nat.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '1', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - # The natural is 1 in Fr. - ( - 'bls12_381_fr_z_nat.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '524358751751261904794477405081859658376905525005276378226036' - '58699938581184514', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_fr_z_nat.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '2', - '0x02000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_fr_z_nat.tz', - '0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c' - + '5401f', - '3364491663033484423912034843462646864953418677080980279259699' - + '6408934105684394', - '0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca91' - + '8a221', - ), - ( - 'bls12_381_fr_z_nat.tz', - '0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfc' - + 'dbe3f', - '2262028481792278490256467246991799299632821112798447289749169' - + '8543785655336309', - '0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe6' - + '77c62', - ), - ( - 'bls12_381_fr_z_nat.tz', - '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' - + 'fcf2d', - '1718009307279455880617703583439793220591757728848373965251048' - + '2486858834123369', - '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' - + 'bf221', - ), - # Same than previous one, but we added the order to the natural to - # verify the modulo is computed correctly and the multiplication - # computation does not fail. - ( - 'bls12_381_fr_z_nat.tz', - '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' - + 'fcf2d', - '69615968247920749285624776342583898043608129789011377475114141' - + '186797415307882', - '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' - + 'bf221', - ), - # Test with (positive and negative) integers. - ( - 'bls12_381_fr_z_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '0', - '0x00000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_fr_z_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '1', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_fr_z_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '524358751751261904794477405081859658376905525005276378226036' - '58699938581184514', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_fr_z_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '2', - '0x02000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_fr_z_int.tz', - '0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c' - + '5401f', - '3364491663033484423912034843462646864953418677080980279259699' - + '6408934105684394', - '0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca91' - + '8a221', - ), - ( - 'bls12_381_fr_z_int.tz', - '0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfc' - + 'dbe3f', - '2262028481792278490256467246991799299632821112798447289749169' - + '8543785655336309', - '0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe6' - + '77c62', - ), - ( - 'bls12_381_fr_z_int.tz', - '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' - + 'fcf2d', - '1718009307279455880617703583439793220591757728848373965251048' - + '2486858834123369', - '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' - + 'bf221', - ), - # Same than previous one, but we added the order to the natural to - # verify the modulo is computed correctly and the multiplication - # computation does not fail. - ( - 'bls12_381_fr_z_int.tz', - '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' - + 'fcf2d', - '69615968247920749285624776342583898043608129789011377475114141' - + '186797415307882', - '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' - + 'bf221', - ), - ( - 'bls12_381_fr_z_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '-1', - '0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953' - + 'a7ed73', - ), - ( - 'bls12_381_fr_z_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '-42', - '0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a' - + '7ed73', - ), - # Test building Fr element from nat. - # The initial storage is dropped then any value is valid. - # Random values can be generated using the following OCaml program. - # let r = Bls12_381.Fr.(random ()) in - # let x = Bls12_381.Fr.random () in - # Printf.printf "Param = (Pair %s 0x%s). Result = 0x%s" - # (Bls12_381.Fr.to_string r) - # (Hex.(show (of_bytes (Bls12_381.Fr.to_bytes x)))) - # (Hex.(show (of_bytes (Bls12_381.Fr.(to_bytes (mul r x)))))) - ( - 'bls12_381_z_fr_nat.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '0', - '0x00000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_z_fr_nat.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '1', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - # The natural is 1 in Fr. - ( - 'bls12_381_z_fr_nat.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '524358751751261904794477405081859658376905525005276378226036' - '58699938581184514', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_z_fr_nat.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '2', - '0x02000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_z_fr_nat.tz', - '0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c' - + '5401f', - '3364491663033484423912034843462646864953418677080980279259699' - + '6408934105684394', - '0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca91' - + '8a221', - ), - ( - 'bls12_381_z_fr_nat.tz', - '0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfc' - + 'dbe3f', - '2262028481792278490256467246991799299632821112798447289749169' - + '8543785655336309', - '0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe6' - + '77c62', - ), - ( - 'bls12_381_z_fr_nat.tz', - '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' - + 'fcf2d', - '1718009307279455880617703583439793220591757728848373965251048' - + '2486858834123369', - '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' - + 'bf221', - ), - # Same than previous one, but we added the order to the natural to - # verify the modulo is computed correctly and the multiplication - # computation does not fail. - ( - 'bls12_381_z_fr_nat.tz', - '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' - + 'fcf2d', - '69615968247920749285624776342583898043608129789011377475114141' - + '186797415307882', - '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' - + 'bf221', - ), - # Test with (positive and negative) integers. - ( - 'bls12_381_z_fr_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '0', - '0x00000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_z_fr_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '1', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_z_fr_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '524358751751261904794477405081859658376905525005276378226036' - '58699938581184514', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_z_fr_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '2', - '0x02000000000000000000000000000000000000000000000000000000000' - + '00000', - ), - ( - 'bls12_381_z_fr_int.tz', - '0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c' - + '5401f', - '3364491663033484423912034843462646864953418677080980279259699' - + '6408934105684394', - '0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca91' - + '8a221', - ), - ( - 'bls12_381_z_fr_int.tz', - '0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfc' - + 'dbe3f', - '2262028481792278490256467246991799299632821112798447289749169' - + '8543785655336309', - '0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe6' - + '77c62', - ), - ( - 'bls12_381_z_fr_int.tz', - '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' - + 'fcf2d', - '1718009307279455880617703583439793220591757728848373965251048' - + '2486858834123369', - '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' - + 'bf221', - ), - ( - 'bls12_381_z_fr_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '-1', - '0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953' - + 'a7ed73', - ), - ( - 'bls12_381_z_fr_int.tz', - '0x01000000000000000000000000000000000000000000000000000000000' - + '00000', - '-42', - '0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a' - + '7ed73', - ), - # Same than previous one, but we added the order to the natural to - # verify the modulo is computed correctly and the multiplication - # computation does not fail. - ( - 'bls12_381_z_fr_int.tz', - '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' - + 'fcf2d', - '69615968247920749285624776342583898043608129789011377475114141' - + '186797415307882', - '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' - + 'bf221', - ), - # Test Fr bytes can be pushed without being padded - ( - 'add_bls12_381_fr.tz', - 'None', - 'Pair 0x00 0x00', - '(Some 0x000000000000000000000000000000000000000000000000000000' - + '0000000000)', - ), - ( - 'add_bls12_381_fr.tz', - 'None', - 'Pair 0x01 0x00', - '(Some 0x010000000000000000000000000000000000000000000000000000' - + '0000000000)', - ), - ( - 'add_bls12_381_fr.tz', - 'None', - 'Pair 0x010000 0x00', - '(Some 0x010000000000000000000000000000000000000000000000000000' - + '0000000000)', - ), - ( - 'add_bls12_381_fr.tz', - 'None', - 'Pair 0x010000 0x010000', - '(Some 0x020000000000000000000000000000000000000000000000000000' - + '0000000000)', - ), - ( - 'bls12_381_fr_push_bytes_not_padded.tz', - 'None', - 'Unit', - '(Some 0x000000000000000000000000000000000000000000000000000000' - + '0000000000)', - ), - ( - 'bls12_381_fr_push_nat.tz', - 'None', - 'Unit', - '(Some 0x100000000000000000000000000000000000000000000000000000' - + '0000000000)', - ), - ('bls12_381_fr_to_int.tz', '0', '0x00', '0'), - ('bls12_381_fr_to_int.tz', '0', '0x01', '1'), - # Generated using - # let r = Bls12_381.Fr.(random ()) in - # Printf.printf "%s = 0x%s" - # (Bls12_381.Fr.to_string r) - # (Hex.(show (of_bytes (Bls12_381.Fr.to_bytes r)))) - ( - 'bls12_381_fr_to_int.tz', - '0', - '0x28db8e57af88d9576acd181b89f24e50a89a6423f939026ed91349fc9' - + 'af16c27', - '1783268807701357777652478449446472851821391321341286660405373' - + '5695200962927400', - ), - ( - 'bls12_381_fr_to_int.tz', - '0', - '0xb9e8abf8dc324a010007addde986fe0f7c81fab16d26819d0534b7691c' - + '0b0719', - '1132026582925658583078152196614952946047676740821044523890286' - + '9222031333517497', - ), - # Mutez -> Fr - ( - 'mutez_to_bls12_381_fr.tz', - '0x02', - '16', - '0x100000000000000000000000000000000000000000000000000000000' - + '0000000', - ), - # # would fail if trying to PACK mutez and UNPACK to Fr - ( - 'mutez_to_bls12_381_fr.tz', - '0x00', - '257', - '0x010100000000000000000000000000000000000000000000000000000' - + '0000000', - ), - # Fr -> Mutez - ('bls12_381_fr_to_mutez.tz', '0', '0x10', '16'), - ], - ) - def test_contract_input_output( - self, - client_regtest: ClientRegression, - contract: str, - param: str, - storage: str, - expected: str, - ): - client = client_regtest - assert contract.endswith( - '.tz' - ), "test contract should have .tz extension" - contract = path.join(OPCODES_CONTRACT_PATH, contract) - run_script_res = client.run_script( - contract, param, storage, trace_stack=True - ) - assert run_script_res.storage == expected - - @pytest.mark.parametrize("balance", [0, 0.000001, 0.5, 1, 5, 1000, 8e12]) - def test_balance(self, client_regtest: ClientRegression, balance: float): - client = client_regtest - contract = 'balance.tz' - contract = path.join(OPCODES_CONTRACT_PATH, contract) - run_script_res = client.run_script( - contract, '0', 'Unit', balance=balance, trace_stack=True - ) - assert run_script_res.storage == str(int(1000000 * balance)) - - def test_now(self, client_regtest: ClientRegression): - """Test that the --now flag of 'tezos-client run script' affects the - value returned by the NOW instruction. See also - test_contract_onchain_opcodes.py for a complementary test of the NOW - instruction.""" - client = client_regtest - contract = 'store_now.tz' - initial_storage = '"2017-07-13T09:19:01Z"' - now = '2021-10-13T10:16:52Z' - contract = path.join(OPCODES_CONTRACT_PATH, contract) - run_script_res = client.run_script( - contract, - storage=initial_storage, - inp='Unit', - now=now, - trace_stack=True, - ) - assert run_script_res.storage == f'"{now}"' - - def test_level(self, client_regtest: ClientRegression): - """Test that the --level flag of 'tezos-client run script' affects the - value returned by the LEVEL instruction. See also - test_contract_onchain_opcodes.py for a complementary test of the LEVEL - instuction.""" - client = client_regtest - contract = 'level.tz' - initial_storage = '9999999' - level = 10 - contract = path.join(OPCODES_CONTRACT_PATH, contract) - run_script_res = client.run_script( - contract, - storage=initial_storage, - inp='Unit', - level=level, - trace_stack=True, - ) - assert run_script_res.storage == f'{level}' - - @pytest.mark.parametrize( - "contract,param,storage,expected,big_map_diff", - [ # FORMAT: assert_output contract_file storage input expected_result - # expected_diffs - # Get the value stored at the given key in the big map - ( - 'get_big_map_value.tz', - '(Pair { Elt "hello" "hi" } None)', - '"hello"', - '(Pair 4 (Some "hi"))', - [ - ["New map(4) of type (big_map string string)"], - ['Set map(4)["hello"] to "hi"'], - ], - ), - ( - 'get_big_map_value.tz', - '(Pair { Elt "hello" "hi" } None)', - '""', - '(Pair 4 None)', - [ - ["New map(4) of type (big_map string string)"], - ['Set map(4)["hello"] to "hi"'], - ], - ), - ( - 'get_big_map_value.tz', - '(Pair { Elt "1" "one" ; Elt "2" "two" } None)', - '"1"', - '(Pair 4 (Some "one"))', - [ - ["New map(4) of type (big_map string string)"], - ['Set map(4)["2"] to "two"'], - ['Set map(4)["1"] to "one"'], - ], - ), - # Test updating big maps - ( - 'update_big_map.tz', - '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', - '{}', - '(Pair 4 Unit)', - [ - ["New map(4) of type (big_map string string)"], - ['Set map(4)["2"] to "two"'], - ['Set map(4)["1"] to "one"'], - ], - ), - ( - 'update_big_map.tz', - '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', - '{ Elt "1" (Some "two") }', - '(Pair 4 Unit)', - [ - ["New map(4) of type (big_map string string)"], - ['Set map(4)["2"] to "two"'], - ['Set map(4)["1"] to "two"'], - ], - ), - ( - 'update_big_map.tz', - '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', - '{ Elt "3" (Some "three") }', - '(Pair 4 Unit)', - [ - ["New map(4) of type (big_map string string)"], - ['Set map(4)["2"] to "two"'], - ['Set map(4)["3"] to "three"'], - ['Set map(4)["1"] to "one"'], - ], - ), - ( - 'update_big_map.tz', - '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', - '{ Elt "3" None }', - '(Pair 4 Unit)', - [ - ["New map(4) of type (big_map string string)"], - ['Set map(4)["2"] to "two"'], - ['Unset map(4)["3"]'], - ['Set map(4)["1"] to "one"'], - ], - ), - ( - 'update_big_map.tz', - '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', - '{ Elt "2" None }', - '(Pair 4 Unit)', - [ - ["New map(4) of type (big_map string string)"], - ['Unset map(4)["2"]'], - ['Set map(4)["1"] to "one"'], - ], - ), - ( - 'update_big_map.tz', - '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', - '{ Elt "1" (Some "two") }', - '(Pair 4 Unit)', - [ - ["New map(4) of type (big_map string string)"], - ['Set map(4)["2"] to "two"'], - ['Set map(4)["1"] to "two"'], - ], - ), - # test the GET_AND_UPDATE instruction on big maps - # Get and update the value stored at the given key in the map - ( - 'get_and_update_big_map.tz', - '(Pair None {})', - '"hello"', - '(Pair None 4)', - [ - ["New map(4) of type (big_map string nat)"], - ['Unset map(4)["hello"]'], - ], - ), - ( - 'get_and_update_big_map.tz', - '(Pair (Some 4) {})', - '"hello"', - '(Pair None 4)', - [ - ["New map(4) of type (big_map string nat)"], - ['Set map(4)["hello"] to 4'], - ], - ), - ( - 'get_and_update_big_map.tz', - '(Pair None { Elt "hello" 4 })', - '"hello"', - '(Pair (Some 4) 4)', - [ - ["New map(4) of type (big_map string nat)"], - ['Unset map(4)["hello"]'], - ], - ), - ( - 'get_and_update_big_map.tz', - '(Pair (Some 5) { Elt "hello" 4 })', - '"hello"', - '(Pair (Some 4) 4)', - [ - ["New map(4) of type (big_map string nat)"], - ['Set map(4)["hello"] to 5'], - ], - ), - ( - 'get_and_update_big_map.tz', - '(Pair (Some 5) { Elt "hello" 4 })', - '"hi"', - '(Pair None 4)', - [ - ["New map(4) of type (big_map string nat)"], - ['Set map(4)["hello"] to 4'], - ['Set map(4)["hi"] to 5'], - ], - ), - ( - 'get_and_update_big_map.tz', - '(Pair None { Elt "1" 1 ; \ - Elt "2" 2 })', - '"1"', - '(Pair (Some 1) 4)', - [ - ["New map(4) of type (big_map string nat)"], - ['Set map(4)["2"] to 2'], - ['Unset map(4)["1"]'], - ], - ), - ( - 'get_and_update_big_map.tz', - '(Pair None { Elt "1" 1 ; \ - Elt "2" 2 })', - '"1"', - '(Pair (Some 1) 4)', - [ - ["New map(4) of type (big_map string nat)"], - ['Set map(4)["2"] to 2'], - ['Unset map(4)["1"]'], - ], - ), - ], - ) - def test__big_map_contract_io( - self, - client_regtest: ClientRegression, - contract: str, - param: str, - storage: str, - expected: str, - big_map_diff: str, - ): - client = client_regtest - contract = path.join(OPCODES_CONTRACT_PATH, contract) - run_script_res = client.run_script( - contract, param, storage, trace_stack=True - ) - assert run_script_res.storage == expected - assert run_script_res.big_map_diff == big_map_diff - - @pytest.mark.parametrize( - "storage,param,expected,big_map_diff", - [ # test swap - ( - '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))', - '(Left Unit)', - '(Left (Pair 4 5))', - [ - ['New map(5) of type (big_map string string)'], - ['Set map(5)["1"] to "one"'], - ['New map(4) of type (big_map string string)'], - ['Set map(4)["2"] to "two"'], - ], - ), - # test reset with new map - ( - '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))', - '(Right (Left (Left (Pair { Elt "3" "three" } ' - + '{ Elt "4" "four" }))))', - '(Left (Pair 4 5))', - [ - ['New map(5) of type (big_map string string)'], - ['Set map(5)["4"] to "four"'], - ['New map(4) of type (big_map string string)'], - ['Set map(4)["3"] to "three"'], - ], - ), - # test reset to unit - ( - '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))', - '(Right (Left (Right Unit)))', - '(Right Unit)', - [], - ), - # test import to big_map - ( - '(Right Unit)', - '(Right (Right (Left (Pair { Pair "foo" "bar" } ' - + '{ Pair "gaz" "baz" }) )))', - '(Left (Pair 4 5))', - [ - ['New map(5) of type (big_map string string)'], - ['Set map(5)["gaz"] to "baz"'], - ['New map(4) of type (big_map string string)'], - ['Set map(4)["foo"] to "bar"'], - ], - ), - # test add to big_map - ( - '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }) )', - '(Right (Right (Right (Left { Pair "3" "three" }))))', - '(Left (Pair 4 5))', - [ - ['New map(5) of type (big_map string string)'], - ['Set map(5)["2"] to "two"'], - ['New map(4) of type (big_map string string)'], - ['Set map(4)["3"] to "three"'], - ['Set map(4)["1"] to "one"'], - ], - ), - # test remove from big_map - ( - '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))', - '(Right (Right (Right (Right { "1" }))))', - '(Left (Pair 4 5))', - [ - ['New map(5) of type (big_map string string)'], - ['Set map(5)["2"] to "two"'], - ['New map(4) of type (big_map string string)'], - ['Unset map(4)["1"]'], - ], - ), - ], - ) - def test_big_map_magic( - self, - client_regtest: ClientRegression, - storage: str, - param: str, - expected: str, - big_map_diff: str, - ): - client = client_regtest - contract = path.join(MINI_SCENARIOS_CONTRACT_PATH, 'big_map_magic.tz') - run_script_res = client.run_script( - contract, storage, param, trace_stack=True - ) - assert run_script_res.storage == expected - assert run_script_res.big_map_diff == big_map_diff - - def test_packunpack(self, client_regtest: ClientRegression): - """Test PACK/UNPACK and binary format.""" - client = client_regtest - assert_run_script_success( - client, - path.join(OPCODES_CONTRACT_PATH, 'packunpack.tz'), - 'Unit', - '(Pair (Pair (Pair "toto" {3;7;9;1}) {1;2;3}) ' - + '0x05070707070100000004746f746f020000000800030' - + '007000900010200000006000100020003)', - ) - assert_run_script_failwith( - client, - path.join(OPCODES_CONTRACT_PATH, 'packunpack.tz'), - 'Unit', - '(Pair (Pair (Pair "toto" {3;7;9;1}) {1;2;3}) ' - + '0x05070707070100000004746f746f020000000800030' - + '0070009000102000000060001000200030004)', - ) - - def test_check_signature(self, client_regtest: ClientRegression): - client = client_regtest - sig = ( - 'edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt' - + '9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF' - ) - assert_run_script_success( - client, - path.join(OPCODES_CONTRACT_PATH, 'check_signature.tz'), - f'(Pair "{sig}" "hello")', - '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"', - ) - assert_run_script_failwith( - client, - path.join(OPCODES_CONTRACT_PATH, 'check_signature.tz'), - f'(Pair "{sig}" "abcd")', - '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"', - ) - - def test_hash_consistency_michelson_cli( - self, client_regtest: ClientRegression - ): - client = client_regtest - hash_result = client.hash( - '(Pair 22220000000 (Pair "2017-12-13T04:49:00Z" 034))', - '(pair mutez (pair timestamp int))', - ).blake2b - hash_contract = path.join( - OPCODES_CONTRACT_PATH, 'hash_consistency_checker.tz' - ) - run_script_res = client.run_script( - hash_contract, - '0x00', - '(Pair 22220000000 (Pair "2017-12-13T04:49:00Z" 034))', - ) - assert run_script_res.storage == hash_result - run_script_res = client.run_script( - hash_contract, - '0x00', - '(Pair 22220000000 (Pair "2017-12-13T04:49:00Z" 034))', - ) - assert run_script_res.storage == hash_result - - @pytest.mark.parametrize( - "contract,param,storage", - [ # FORMAT: assert_output contract_file storage input - # Test overflow in shift - ('shifts.tz', 'None', '(Left (Pair 1 257))'), - ('shifts.tz', 'None', '(Left (Pair 123 257))'), - ('shifts.tz', 'None', '(Right (Pair 1 257))'), - ('shifts.tz', 'None', '(Right (Pair 123 257))'), - ('mul_overflow.tz', 'Unit', 'Left Unit'), - ('mul_overflow.tz', 'Unit', 'Right Unit'), - ], - ) - def test_arithmetic_overflow( - self, - client_regtest_scrubbed: ClientRegression, - contract: str, - param: str, - storage: str, - ): - client = client_regtest_scrubbed - contract = path.join(OPCODES_CONTRACT_PATH, contract) - - with assert_run_failure(r'unexpected arithmetic overflow'): - client.run_script(contract, param, storage) - - @pytest.mark.skip(reason="Bug in annotation system") - def test_fails_annotated_set_car_cdr( - self, client_regtest: ClientRegression - ): - """Tests the SET_CAR and SET_CDR instructions.""" - client = client_regtest - - with assert_run_failure(r'The two annotations do not match'): - client.run_script( - path.join(OPCODES_CONTRACT_PATH, 'set_car.tz'), - '(Pair %wrong %field "hello" 0)', - '""', - ) - - @pytest.mark.parametrize( - "contract,storage,param,expected", - [ # FORMAT: assert_output contract_file storage input expected_result - # Mapping over maps - ('map_map_sideeffect.tz', '(Pair {} 0)', '10', '(Pair {} 0)'), - ( - 'map_map_sideeffect.tz', - '(Pair { Elt "foo" 1 } 1)', - '10', - '(Pair { Elt "foo" 11 } 11)', - ), - ( - 'map_map_sideeffect.tz', - '(Pair { Elt "bar" 5 ; Elt "foo" 1 } 6)', - '15', - '(Pair { Elt "bar" 20 ; Elt "foo" 16 } 36)', - ), - ], - ) - def test_map_map_sideeffect( - self, - client_regtest: ClientRegression, - contract: str, - param: str, - storage: str, - expected: str, - ): - client = client_regtest - contract = path.join(OPCODES_CONTRACT_PATH, contract) - run_script_res = client.run_script(contract, storage, param) - assert run_script_res.storage == expected diff --git a/tests_python/tests_012/test_cors.py b/tests_python/tests_012/test_cors.py deleted file mode 100644 index 80b064285d86..000000000000 --- a/tests_python/tests_012/test_cors.py +++ /dev/null @@ -1,47 +0,0 @@ -import pytest -from daemons.node import Node -from launchers.sandbox import Sandbox -from tools import utils - - -@pytest.fixture(scope="class") -def node(sandbox: Sandbox): - """Launches one node in sandbox mode (genesis)""" - sandbox.add_node(0, params=['--cors-origin', '*']) - yield sandbox.node(0) - - -class TestCors: - def test_preflight(self, node: Node): - origin = 'localhost' - port = node.rpc_port - headers = { - 'Origin': origin, - 'Access-Control-Request-Method': 'GET', - 'Access-Control-Request-Headers': 'Content-Type', - } - res = utils.rpc( - origin, - port, - 'options', - '/chains/main/blocks/head/header/shell', - headers=headers, - ) - print(res.headers) - assert res.headers["access-control-allow-origin"] == '*' - assert res.headers["access-control-allow-methods"] == 'GET' - assert res.headers["access-control-allow-headers"] == 'Content-Type' - - def test_request(self, node: Node): - origin = 'localhost' - port = node.rpc_port - headers = {'Origin': origin, 'Content-Type': 'application/json'} - res = utils.rpc( - origin, - port, - 'get', - '/chains/main/blocks/head/header/shell', - headers=headers, - ) - print(res.headers) - assert res.headers["access-control-allow-origin"] == '*' diff --git a/tests_python/tests_012/test_crypto.py b/tests_python/tests_012/test_crypto.py deleted file mode 100644 index 995b48fdf617..000000000000 --- a/tests_python/tests_012/test_crypto.py +++ /dev/null @@ -1,47 +0,0 @@ -from random import getrandbits - -from os import path - -import pytest - -from Crypto.Hash import keccak, SHA3_256 - -from .contract_paths import OPCODES_CONTRACT_PATH - -RANDOM_ITERATIONS = 50 - -HASH_FUNCTIONS = { - "keccak": lambda bytes_to_hash: keccak.new(digest_bits=256) - .update(bytes_to_hash) - .hexdigest(), - "sha3": lambda bytes_to_hash: SHA3_256.new() - .update(bytes_to_hash) - .hexdigest(), -} - - -@pytest.fixture(params=HASH_FUNCTIONS.keys()) -def hash_fun(request): - return request.param - - -@pytest.mark.contract -class TestHash: - @pytest.mark.parametrize( - "bytes_to_hash", - [b"", b"a"] - + [ - getrandbits(bytes_length * 8).to_bytes( - bytes_length, byteorder="little" - ) - for bytes_length in [32] - for _ in range(RANDOM_ITERATIONS) - ], - ) - def test_hash(self, client, hash_fun, bytes_to_hash): - contract = path.join(OPCODES_CONTRACT_PATH, f"{hash_fun}.tz") - - hashed = HASH_FUNCTIONS[hash_fun](bytes_to_hash) - arg = f"0x{bytes_to_hash.hex()}" - result = client.run_script(contract, "None", arg) - assert result.storage == f"(Some 0x{hashed})" diff --git a/tests_python/tests_012/test_fa12.py b/tests_python/tests_012/test_fa12.py deleted file mode 100644 index ce94cc066e46..000000000000 --- a/tests_python/tests_012/test_fa12.py +++ /dev/null @@ -1,352 +0,0 @@ -"""This file tests the tezos-client commands offering support for the -FA1.2 standard. Several implementations of the standard are tested.""" - -import json -import os -import pytest -from tools import utils -from tools.constants import IDENTITIES -from client.client import Client -from .contract_paths import CONTRACT_PATH - -BAKE_ARGS = ['--minimal-timestamp'] -BURN_CAP_ARGS = ['--burn-cap', '1.0'] - - -def reset_viewer(client: Client, contract: str): - args = ['--arg', '0'] - client.transfer(0.0, 'bootstrap2', contract, args) - client.bake('bootstrap5', BAKE_ARGS) - - -def check_expected_balance(client, token_contract, addr, expected): - bal = client.fa12_get_balance_offchain(token_contract, addr, []) - return bal.amount == expected - - -def check_expected_allowance(client, token_contract, src, dst, expected): - alw = client.fa12_get_allowance_offchain(token_contract, src, dst, []) - return alw.amount == expected - - -@pytest.fixture( - scope="class", - ids=[ - 'fa12_reference', - 'lqt_fa12', - ], - params=[ - ( - 'fa12_reference', - 'fa12_reference.tz', - lambda key: f'Pair {{}} (Pair "{key}" (Pair False 0))', - ), - ( - 'lqt_fa12', - 'lqt_fa12.mligo.tz', - lambda key: f'Pair {{}} {{}} "{key}" 0', - ), - ], -) -def token_contract(client: Client, session: dict, request): - (contract_alias, contract_path, init_fun) = request.param - - path = os.path.join(CONTRACT_PATH, 'mini_scenarios', contract_path) - identity = IDENTITIES['bootstrap2']['identity'] - init = init_fun(identity) - - utils.originate(client, session, path, init, 0, contract_alias) - - if contract_alias == 'fa12_reference': - identity = IDENTITIES['bootstrap2']['identity'] - param = f'(Pair "{identity}" 20000)' - args = [ - '--entrypoint', - 'mint', - '--arg', - param, - '--burn-cap', - '0.078', - ] - client.transfer(0, 'bootstrap2', contract_alias, args) - client.bake('bootstrap5', BAKE_ARGS) - elif contract_alias == 'lqt_fa12': - identity = IDENTITIES['bootstrap2']['identity'] - param = f'(Pair 20000 "{identity}")' - args = [ - '--entrypoint', - 'mintOrBurn', - '--arg', - param, - '--burn-cap', - '0.078', - ] - client.transfer(0, 'bootstrap2', contract_alias, args) - client.bake('bootstrap5', BAKE_ARGS) - - return contract_alias - - -@pytest.fixture(scope="class") -def view(client: Client, session: dict): - # Only deploy once, it can be used by any fa1.2 contract - contract_alias = 'nat-viewer' - args = ['--init', '0', '--burn-cap', '0.08'] - viewer = "parameter nat; storage nat; code { CAR; NIL operation; PAIR; }" - - origination = client.originate( - contract_alias, 0, 'bootstrap1', viewer, args - ) - session['contract'] = origination.contract - client.bake('bootstrap5', BAKE_ARGS) - return contract_alias - - -class TestFA12Basic: - def test_check_contract(self, client: Client, token_contract: str): - assert client.fa12_check(token_contract).check - - # NOTE: this test does not depend on the token_contract - # fixture (nor should it) - def test_check_contract_fail(self, client: Client, session: dict): - path = os.path.join(CONTRACT_PATH, 'entrypoints', 'manager.tz') - identity = IDENTITIES['bootstrap2']['identity'] - init = f'"{identity}"' - token_contract = 'manager-fail' - utils.originate(client, session, path, init, 0, token_contract) - - assert not client.fa12_check(token_contract).check - - def test_get_balance_offchain(self, client: Client, token_contract: str): - res = client.fa12_get_balance_offchain(token_contract, 'bootstrap2', []) - assert res.amount == 20000 - - def test_get_allowance_offchain(self, client: Client, token_contract: str): - res = client.fa12_get_allowance_offchain( - token_contract, 'bootstrap2', 'bootstrap3', [] - ) - assert res.amount == 0 - - def test_get_total_supply_offchain( - self, client: Client, token_contract: str - ): - res = client.fa12_get_total_supply_offchain(token_contract, []) - expected = 20000 - assert res.amount == expected - - def test_get_balance_callback( - self, client: Client, token_contract: str, view - ): - reset_viewer(client, view) - client.fa12_get_balance_callback( - token_contract, 'bootstrap2', view, BURN_CAP_ARGS - ) - client.bake('bootstrap5', BAKE_ARGS) - utils.assert_storage_contains(client, view, '20000') - - def test_get_allowance_callback( - self, client: Client, token_contract: str, view - ): - reset_viewer(client, view) - client.fa12_get_allowance_callback( - token_contract, 'bootstrap2', 'bootstrap3', view, BURN_CAP_ARGS - ) - client.bake('bootstrap5', BAKE_ARGS) - utils.assert_storage_contains(client, view, '0') - - def test_get_total_supply_callback( - self, client: Client, token_contract: str, view - ): - reset_viewer(client, view) - client.fa12_get_total_supply_callback( - token_contract, 'bootstrap2', view, BURN_CAP_ARGS - ) - client.bake('bootstrap5', BAKE_ARGS) - expected = '20000' - utils.assert_storage_contains(client, view, expected) - - -@pytest.mark.incremental -class TestFA12Incremental: - def test_transfer(self, client: Client, token_contract: str): - client.fa12_transfer( - token_contract, 100, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS - ) - client.bake('bootstrap5', BAKE_ARGS) - - assert check_expected_balance( - client, token_contract, 'bootstrap2', 19900 - ) and check_expected_balance(client, token_contract, 'bootstrap3', 100) - - def test_transfer_not_enough_balance( - self, client: Client, token_contract: str - ): - if token_contract == 'fa12_reference': - error_pattern = r'Not enough balance' - else: - error_pattern = '' - with utils.assert_run_failure(error_pattern): - client.fa12_transfer( - token_contract, 200, 'bootstrap3', 'bootstrap2', BURN_CAP_ARGS - ) - - def test_approve(self, client: Client, token_contract: str): - client.fa12_approve( - token_contract, 20, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS - ) - client.bake('bootstrap5', BAKE_ARGS) - - assert check_expected_allowance( - client, token_contract, 'bootstrap2', 'bootstrap3', 20 - ) - - def test_approve_unsafe_allowance_change( - self, client: Client, token_contract - ): - if token_contract == 'fa12_reference': - error_pattern = r'Unsafe allowance change' - else: - error_pattern = '' - with utils.assert_run_failure(error_pattern): - client.fa12_approve( - token_contract, 30, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS - ) - - def test_transfer_as(self, client: Client, token_contract: str): - client.fa12_transfer_as( - token_contract, - 10, - 'bootstrap2', - 'bootstrap3', - 'bootstrap3', - BURN_CAP_ARGS, - ) - client.bake('bootstrap5', BAKE_ARGS) - - assert ( - check_expected_balance(client, token_contract, 'bootstrap2', 19890) - and check_expected_balance( - client, token_contract, 'bootstrap3', 110 - ) - and check_expected_allowance( - client, token_contract, 'bootstrap2', 'bootstrap3', 10 - ) - ) - - def test_transfer_as_not_enough_allowance( - self, client: Client, token_contract - ): - if token_contract == 'fa12_reference': - error_pattern = r'Not enough allowance' - else: - error_pattern = '' - with utils.assert_run_failure(error_pattern): - client.fa12_transfer_as( - token_contract, - 20, - 'bootstrap2', - 'bootstrap3', - 'bootstrap3', - BURN_CAP_ARGS, - ) - - def test_multiple_transfers(self, client: Client, token_contract: str): - op1 = client.fa12_mk_batch_transfer('bootstrap4', token_contract, 100) - op2 = client.fa12_mk_batch_transfer('bootstrap5', token_contract, 10) - json_ops = json.dumps(op1 + op2, separators=(',', ':')) - client.fa12_multiple_tokens_transfers( - 'bootstrap2', json_ops, BURN_CAP_ARGS - ) - client.bake('bootstrap5', BAKE_ARGS) - - assert ( - check_expected_balance(client, token_contract, 'bootstrap2', 19780) - and check_expected_balance( - client, token_contract, 'bootstrap4', 100 - ) - and check_expected_balance(client, token_contract, 'bootstrap5', 10) - and check_expected_allowance( - client, token_contract, 'bootstrap2', 'bootstrap3', 10 - ) - ) - - def test_multiple_transfers_fail(self, client: Client, token_contract: str): - op1 = client.fa12_mk_batch_transfer('bootstrap4', token_contract, 100) - op2 = client.fa12_mk_batch_transfer( - 'bootstrap5', token_contract, 100000 - ) - json_ops = json.dumps(op1 + op2, separators=(',', ':')) - - bal_sender_before = client.fa12_get_balance_offchain( - token_contract, 'bootstrap2', [] - ) - bal_receiver1_before = client.fa12_get_balance_offchain( - token_contract, 'bootstrap4', [] - ) - bal_receiver2_before = client.fa12_get_balance_offchain( - token_contract, 'bootstrap5', [] - ) - - error_pattern = r'multiple transfers simulation failed' - with utils.assert_run_failure(error_pattern): - client.fa12_multiple_tokens_transfers( - 'bootstrap2', json_ops, BURN_CAP_ARGS - ) - - client.bake('bootstrap5', BAKE_ARGS) - - assert ( - check_expected_balance( - client, - token_contract, - 'bootstrap2', - bal_sender_before.amount, - ) - and check_expected_balance( - client, - token_contract, - 'bootstrap4', - bal_receiver1_before.amount, - ) - and check_expected_balance( - client, - token_contract, - 'bootstrap5', - bal_receiver2_before.amount, - ) - ) - - def test_multiple_transfers_as(self, client: Client, token_contract: str): - client.fa12_approve( - token_contract, 0, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS - ) - client.bake('bootstrap5', BAKE_ARGS) - - client.fa12_approve( - token_contract, 30, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS - ) - client.bake('bootstrap5', BAKE_ARGS) - check_allowance_before = check_expected_allowance( - client, token_contract, 'bootstrap2', 'bootstrap3', 30 - ) - - op1 = client.fa12_mk_batch_transfer('bootstrap4', token_contract, 10) - op2 = client.fa12_mk_batch_transfer('bootstrap5', token_contract, 20) - json_ops = json.dumps(op1 + op2, separators=(',', ':')) - - client.fa12_multiple_tokens_transfers_as( - 'bootstrap2', 'bootstrap3', json_ops, BURN_CAP_ARGS - ) - client.bake('bootstrap5', BAKE_ARGS) - - assert ( - check_expected_balance(client, token_contract, 'bootstrap2', 19750) - and check_expected_balance( - client, token_contract, 'bootstrap4', 110 - ) - and check_expected_balance(client, token_contract, 'bootstrap5', 30) - and check_allowance_before - and check_expected_allowance( - client, token_contract, 'bootstrap2', 'bootstrap3', 0 - ) - ) diff --git a/tests_python/tests_012/test_forge_block.py b/tests_python/tests_012/test_forge_block.py deleted file mode 100755 index b931cf986537..000000000000 --- a/tests_python/tests_012/test_forge_block.py +++ /dev/null @@ -1,46 +0,0 @@ -import datetime -import pytest -from tools import constants -from tools.constants import PROTO_DEMO_NOOPS -from launchers.sandbox import Sandbox - - -@pytest.mark.slow -@pytest.mark.incremental -class TestForgeBlock: - """ Check that a block more than 5 seconds in the future is rejected """ - - def test_setup_network(self, sandbox: Sandbox): - sandbox.add_node(1, params=constants.NODE_PARAMS) - - def test_protocol_exists(self, sandbox: Sandbox): - client = sandbox.client(1) - protocols = client.list_protocols() - assert PROTO_DEMO_NOOPS in protocols - - def test_activate_proto_demo_time_shifted_ok(self, sandbox: Sandbox): - parameters = {} # type: dict - delta = datetime.timedelta(seconds=5) - sandbox.client(1).activate_protocol_json( - PROTO_DEMO_NOOPS, - parameters, - key='activator', - timestamp=(datetime.datetime.utcnow() + delta).strftime( - "%Y-%m-%dT%H:%M:%SZ" - ), - fitness='1', - ) - - @pytest.mark.xfail - def test_activate_proto_demo_time_shifted_ko(self, sandbox: Sandbox): - parameters = {} # type: dict - delta = datetime.timedelta(seconds=30) - sandbox.client(1).activate_protocol_json( - PROTO_DEMO_NOOPS, - parameters, - key='activator', - timestamp=(datetime.datetime.utcnow() + delta).strftime( - "%Y-%m-%dT%H:%M:%SZ" - ), - fitness='1', - ) diff --git a/tests_python/tests_012/test_fork.py b/tests_python/tests_012/test_fork.py deleted file mode 100644 index 0ce7d92a6a53..000000000000 --- a/tests_python/tests_012/test_fork.py +++ /dev/null @@ -1,88 +0,0 @@ -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox -from . import protocol - - -NUM_NODES = 3 - - -@pytest.mark.multinode -@pytest.mark.incremental -class TestFork: - """Constructs two independent branches on disconnected subsets of nodes, - one head has higher fitness. At reconnection, check the the highest - fitness head is the chosen one""" - - def test_init(self, sandbox: Sandbox): - for i in range(NUM_NODES): - sandbox.add_node(i, params=constants.NODE_PARAMS) - parameters = protocol.get_parameters() - parameters['consensus_threshold'] = 0 - protocol.activate( - sandbox.client(0), parameters=parameters, activate_in_the_past=True - ) - - def test_level(self, sandbox: Sandbox): - level = 1 - for client in sandbox.all_clients(): - assert utils.check_level(client, level) - - def test_terminate_nodes_1_and_2(self, sandbox: Sandbox): - sandbox.node(1).terminate() - sandbox.node(2).terminate() - - def test_bake_node_0(self, sandbox: Sandbox): - """Client 0 bakes block A at level 2, not communicated to 1 and 2""" - utils.bake(sandbox.client(0)) - - def test_endorse_node_0(self, sandbox: Sandbox, session: dict): - """bootstrap1 builds an endorsement for block A""" - client = sandbox.client(0) - client.run(["endorse", "for", "bootstrap1", "--force"]) - mempool = client.get_mempool() - endorsement = mempool['applied'][0] - session['endorsement1'] = endorsement - - def test_bake_node_0_again(self, sandbox: Sandbox): - """Client 0 bakes block A' at level 3, not communicated to 1 and 2""" - utils.bake(sandbox.client(0), bake_for='bootstrap1') - - def test_first_branch(self, sandbox: Sandbox, session: dict): - head = sandbox.client(0).get_head() - assert head['header']['level'] == 3 - session['hash1'] = head['hash'] - assert len(head['operations'][0]) == 1 - - def test_terminate_node_0(self, sandbox: Sandbox): - sandbox.node(0).terminate() - - def test_restart_node_2(self, sandbox: Sandbox): - sandbox.node(2).run() - assert sandbox.client(2).check_node_listening() - - def test_bake_node_2(self, sandbox: Sandbox): - """Client 2 bakes block B at level 2, not communicated to 0 and 1""" - utils.bake(sandbox.client(2), bake_for='bootstrap1') - - def test_bake_node_2_again(self, sandbox: Sandbox): - """Client 2 bakes block B' at level 3, not communicated to 0 and 1""" - utils.bake(sandbox.client(2), bake_for='bootstrap1') - - def test_second_branch(self, sandbox: Sandbox, session: dict): - head = sandbox.client(2).get_head() - session['hash2'] = head['hash'] - assert head['header']['level'] == 3 - assert len(head['operations'][0]) == 1 - - def test_restart_all(self, sandbox: Sandbox): - sandbox.node(0).run() - sandbox.node(1).run() - assert sandbox.client(0).check_node_listening() - assert sandbox.client(1).check_node_listening() - - def test_check_head(self, sandbox: Sandbox, session: dict): - """All nodes are at level 3, head should be hash1""" - for client in sandbox.all_clients(): - head = client.get_head() - assert session['hash1'] == head['hash'] diff --git a/tests_python/tests_012/test_injection.py b/tests_python/tests_012/test_injection.py deleted file mode 100644 index fee00a37d5d4..000000000000 --- a/tests_python/tests_012/test_injection.py +++ /dev/null @@ -1,103 +0,0 @@ -import os -from typing import List -import subprocess -import pytest -from tools import utils, paths, constants -from tools.constants import PROTO_DEMO_NOOPS, PROTO_GENESIS -from client.client import Client - - -@pytest.fixture(scope="class") -def clients(sandbox): - """Launches 3 nodes in sandbox mode (genesis, doesn't activate 012).""" - num_nodes = 3 - for i in range(num_nodes): - sandbox.add_node(i, params=constants.NODE_PARAMS) - yield sandbox.all_clients() - - -PROTO = f'{paths.TEZOS_HOME}/src/bin_client/test/proto_test_injection' -COMPILER = ( - f'{paths.TEZOS_HOME}/_build/default/src/lib_protocol_compiler/bin/' - 'main_native.exe' -) -PARAMS = ['-p', PROTO_GENESIS] - - -@pytest.mark.incremental -class TestInjectionAndActivation: - """Protocol injection and activation""" - - def test_check_resources(self): - assert os.path.isfile(COMPILER) - assert os.path.isdir(PROTO) - - def test_compute_hash(self, session: dict): - cmd = [COMPILER, '-hash-only', PROTO] - res = subprocess.run( - cmd, universal_newlines=True, check=True, stdout=subprocess.PIPE - ) - proto_hash = res.stdout[:-1] - assert len(proto_hash) == 51 - session['proto_hash'] = proto_hash - - def test_injection(self, clients: List[Client]): - clients[0].inject_protocol(PROTO) - - def test_check_injected(self, clients: List[Client], session: dict): - proto = session['proto_hash'] - protos = clients[0].list_protocols() - assert proto in protos - - def test_environment_version(self, clients: List[Client], session: dict): - proto = session['proto_hash'] - assert clients[0].environment_protocol(proto) == "V1" - - def test_activation(self, clients: List[Client], session: dict): - proto = session['proto_hash'] - parameters = {} # type: dict - res = clients[0].activate_protocol_json( - proto, parameters, key='activator', fitness='1' - ) - assert res.block_hash - - def test_check_protocol(self, clients: List[Client], session: dict): - proto = session['proto_hash'] - for client in clients: - assert utils.check_protocol(client, proto, params=PARAMS) - - -@pytest.fixture(scope="class") -def client(sandbox): - """One node in sandbox mode (genesis, doesn't activate 012).""" - sandbox.add_node(0) - client = sandbox.client(0) - yield client - - -@pytest.mark.incremental -class TestActivation: - """ Protocol activation (protocol already linked to the node) """ - - def test_proto_known(self, client: Client): - res = client.list_protocols() - assert PROTO_DEMO_NOOPS in res - - def test_first_protocol(self, client: Client): - proto = 'PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i' - assert client.get_protocol() == proto - - def test_activate_demo(self, client: Client): - proto = PROTO_DEMO_NOOPS - parameters = {} # type: dict - res = client.activate_protocol_json( - proto, parameters, key='activator', fitness='1' - ) - assert res.block_hash - - def test_level1(self, client: Client): - assert client.get_level(params=PARAMS) == 1 - - def test_protocol_genesis(self, client: Client): - proto = PROTO_GENESIS - assert client.get_protocol(params=PARAMS) == proto diff --git a/tests_python/tests_012/test_liquidity_baking.py b/tests_python/tests_012/test_liquidity_baking.py deleted file mode 100644 index 17aaafa06305..000000000000 --- a/tests_python/tests_012/test_liquidity_baking.py +++ /dev/null @@ -1,279 +0,0 @@ -import pytest - -from tools import utils -from tools.constants import IDENTITIES - -DEX = "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5" -TOK = "KT1VqarPDicMFn1ejmQqqshUkUXTCTXwmkCN" -LQT = "KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" -BOOTSTRAP1 = IDENTITIES['bootstrap1']['identity'] -TOK_ADMIN = BOOTSTRAP1 -BOOTSTRAP2 = IDENTITIES['bootstrap2']['identity'] -BOOTSTRAP3 = IDENTITIES['bootstrap3']['identity'] -FUTURE = "2050-01-01T00:00:00Z" - - -@pytest.mark.contract -@pytest.mark.regression -@pytest.mark.incremental -class SetupMintAndApprove: - """Test calling entrypoints of liquidity baking contracts""" - - def test_setup(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - assert DEX == client.rpc( - 'get', - "/chains/main/blocks/head/context/liquidity_baking/cpmm_address", - ) - dex_storage = client.get_storage(DEX).split() - assert dex_storage[4].strip('"') == TOK - assert dex_storage[5].strip('"') == LQT - - # mint some test TOK (1 tzBTC?) for ourselves - def test_call_mint_or_burn(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.call( - TOK_ADMIN, - TOK, - [ - '--entrypoint', - 'mintOrBurn', - '--arg', - f'(Pair 100000000 "{BOOTSTRAP1}")', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - # pre-approve big allowances in TOK for DEX - def test_call_approve1(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.call( - 'bootstrap1', - TOK, - [ - '--entrypoint', - 'approve', - '--arg', - f'(Pair "{DEX}" 1000000000)', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - def test_call_approve2(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.call( - 'bootstrap2', - TOK, - [ - '--entrypoint', - 'approve', - '--arg', - f'(Pair "{DEX}" 1000000000)', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - def test_call_approve3(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.call( - 'bootstrap3', - TOK, - [ - '--entrypoint', - 'approve', - '--arg', - f'(Pair "{DEX}" 1000000000)', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - -@pytest.mark.contract -@pytest.mark.regression -@pytest.mark.incremental -class TestAddApproveTransferRemove(SetupMintAndApprove): - """Test add/approve/transfer/remove liquidity""" - - # first add liquidity on DEX so that we have some LQT - def test_add_liquidity(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.transfer( - 9001, - 'bootstrap1', - DEX, - [ - '--entrypoint', - 'addLiquidity', - '--arg', - f'(Pair "{BOOTSTRAP1}" 0 1000000000 "{FUTURE}")', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - # test LQT approval - def test_approval(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.call( - 'bootstrap1', - LQT, - [ - '--entrypoint', - 'approve', - '--arg', - f'(Pair "{BOOTSTRAP2}" 1000)', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - # transfer LQT to bootstrap2 (using approval) - def test_approved_transfer(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.call( - 'bootstrap2', - LQT, - [ - '--entrypoint', - 'transfer', - '--arg', - f'(Pair "{BOOTSTRAP1}" "{BOOTSTRAP2}" 1000)', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - # now remove LQT for bootstrap2 - def test_remove_liquidity(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.call( - 'bootstrap2', - DEX, - [ - '--entrypoint', - 'removeLiquidity', - '--arg', - f'(Pair "{BOOTSTRAP2}" 1000 0 0 "{FUTURE}")', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - # check DEX storage - def test_dex_storage(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.get_storage(DEX) - - # check LQT storage - def test_lqt_storage(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.get_storage(LQT) - - # check TOK storage - def test_tok_storage(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.get_storage(TOK) - - -@pytest.mark.contract -@pytest.mark.regression -@pytest.mark.incremental -class TestTrades(SetupMintAndApprove): - """Test trades""" - - # add liquidity - def test_add_liquidity(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.transfer( - 9001, - 'bootstrap1', - DEX, - [ - '--entrypoint', - 'addLiquidity', - '--arg', - f'(Pair "{BOOTSTRAP1}" 0 1000000000 "{FUTURE}")', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - # bootstrap2 buys some TOK - def test_buy_tok(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.transfer( - 9001, - 'bootstrap2', - DEX, - [ - '--entrypoint', - 'xtzToToken', - '--arg', - f'(Pair "{BOOTSTRAP2}" 0 "{FUTURE}")', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - # bootstrap2 transfers TOK to bootstrap3 - def test_transfer(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.call( - 'bootstrap2', - TOK, - [ - '--entrypoint', - 'transfer', - '--arg', - f'(Pair "{BOOTSTRAP2}" "{BOOTSTRAP3}" 100)', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - # bootstrap3 sells TOK - def test_sell_tok(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.call( - 'bootstrap3', - DEX, - [ - '--entrypoint', - 'tokenToXtz', - '--arg', - f'(Pair "{BOOTSTRAP3}" 100 0 "{FUTURE}")', - '--burn-cap', - '10', - ], - ) - utils.bake(client, 'bootstrap5') - - # check DEX storage - def test_dex_storage(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.get_storage(DEX) - - # check LQT storage - def test_lqt_storage(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.get_storage(LQT) - - # check TOK storage - def test_tok_storage(self, client_regtest_scrubbed): - client = client_regtest_scrubbed - client.get_storage(TOK) diff --git a/tests_python/tests_012/test_many_bakers.py b/tests_python/tests_012/test_many_bakers.py deleted file mode 100644 index f13981411ede..000000000000 --- a/tests_python/tests_012/test_many_bakers.py +++ /dev/null @@ -1,42 +0,0 @@ -import time -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox -from . import protocol - -# TODO parameterize test - -MINIMAL_BLOCK_DELAY = 15 - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -class TestManyBakers: - """Run 5 bakers and num nodes, wait and check logs""" - - def test_init(self, sandbox: Sandbox): - for i in range(10): - sandbox.add_node(i, params=constants.NODE_PARAMS) - protocol.activate(sandbox.client(0)) - for i in range(5): - sandbox.add_baker(i, [f'bootstrap{i + 1}'], proto=protocol.DAEMON) - - def test_wait(self): - # expects two level to be added to level start - time.sleep(2 * MINIMAL_BLOCK_DELAY) - - def test_progress(self, sandbox: Sandbox): - min_level = min( - [client.get_level() for client in sandbox.all_clients()] - ) - assert min_level >= 3 - - @pytest.mark.xfail - def test_check_logs(self, sandbox: Sandbox): - if not sandbox.log_dir: - pytest.skip() - assert sandbox.logs - error_pattern = r"canceled|crashed" - assert utils.check_logs(sandbox.logs, error_pattern) diff --git a/tests_python/tests_012/test_many_nodes.py b/tests_python/tests_012/test_many_nodes.py deleted file mode 100644 index a24489cb4d00..000000000000 --- a/tests_python/tests_012/test_many_nodes.py +++ /dev/null @@ -1,66 +0,0 @@ -import random -import time -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox -from . import protocol - -NUM_NODES = 5 -NEW_NODES = 3 -REPLACE = False -ERROR_PATTERN = r"Uncaught|registered" - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -class TestManyNodesBootstrap: - """Run many nodes, wait a while, run more nodes, check logs""" - - def test_init(self, sandbox: Sandbox): - sandbox.add_node(0, params=constants.NODE_PARAMS) - parameters = dict(protocol.PARAMETERS) - # smaller threshold to make (almost sure) that 3/5 of the delegates - # have enough endorsing power - parameters['consensus_threshold'] = 5 - parameters['minimal_block_delay'] = '3' - parameters['delay_increment_per_round'] = '1' - protocol.activate(sandbox.client(0), parameters) - for i in range(1, NEW_NODES): - sandbox.add_node(i, params=constants.NODE_PARAMS) - for i in range(3): - sandbox.add_baker(i, [f'bootstrap{i + 1}'], proto=protocol.DAEMON) - - def test_add_nodes(self, sandbox: Sandbox): - for i in range(NEW_NODES, NUM_NODES): - sandbox.add_node(i, params=constants.NODE_PARAMS) - - def test_sleep_30s(self): - time.sleep(30) - - def test_add_more_nodes(self, sandbox: Sandbox): - new_node = NUM_NODES - for i in range(NEW_NODES): - if REPLACE: - running_nodes = list(sandbox.nodes.keys()) - sandbox.rm_node(random.choice(running_nodes)) - sandbox.add_node(new_node + i, params=constants.NODE_PARAMS) - - def test_kill_baker(self, sandbox: Sandbox): - assert utils.check_logs(sandbox.logs, ERROR_PATTERN) - for i in range(3): - sandbox.rm_baker(i, proto=protocol.DAEMON) - - def test_synchronize(self, sandbox: Sandbox): - utils.synchronize(sandbox.all_clients()) - - def test_progress(self, sandbox: Sandbox): - level = sandbox.client(0).get_level() - assert level >= 5 - - def test_check_logs(self, sandbox: Sandbox): - if not sandbox.log_dir: - pytest.skip() - assert sandbox.logs - assert utils.check_logs(sandbox.logs, ERROR_PATTERN) diff --git a/tests_python/tests_012/test_mempool.py b/tests_python/tests_012/test_mempool.py deleted file mode 100644 index 11d9a459c2d7..000000000000 --- a/tests_python/tests_012/test_mempool.py +++ /dev/null @@ -1,66 +0,0 @@ -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox - -from . import protocol - - -@pytest.mark.mempool -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -class TestMempool: - " Tests mempool" - - def test_init(self, sandbox: Sandbox): - sandbox.add_node(1, params=constants.NODE_PARAMS) - sandbox.add_node(2, params=constants.NODE_PARAMS) - sandbox.add_node( - 3, params=constants.NODE_PARAMS + ['--disable-mempool'] - ) - protocol.activate(sandbox.client(1), activate_in_the_past=True) - - def test_level1(self, sandbox: Sandbox): - level = 1 - for client in sandbox.all_clients(): - assert utils.check_level(client, level) - - def test_running_prevalidators(self, sandbox: Sandbox): - assert sandbox.client(1).get_prevalidator() - assert sandbox.client(2).get_prevalidator() - assert not sandbox.client(3).get_prevalidator() - - def test_mempool_empty(self, sandbox: Sandbox): - for i in range(1, 4): - assert sandbox.client(i).mempool_is_empty() - - def test_transfer(self, sandbox: Sandbox, session: dict): - client = sandbox.client(1) - session['trsfr_hash'] = client.transfer( - 1.000, 'bootstrap1', 'bootstrap2' - ).operation_hash - - def test_mempool_include_transfer(self, sandbox: Sandbox, session: dict): - assert utils.check_mempool_contains_operations( - sandbox.client(1), [session['trsfr_hash']] - ) - assert utils.check_mempool_contains_operations( - sandbox.client(2), [session['trsfr_hash']] - ) - assert sandbox.client(3).mempool_is_empty() - - def test_bake_for1(self, sandbox: Sandbox): - utils.bake(sandbox.client(1)) - - def test_level2(self, sandbox: Sandbox): - level = 2 - for client in sandbox.all_clients(): - assert utils.check_level(client, level) - - def test_mempools_are_empty(self, sandbox: Sandbox): - for i in range(1, 4): - assert sandbox.client(i).mempool_is_empty() - - def test_injection_fails_on_mempool_disabled_node(self, sandbox: Sandbox): - with pytest.raises(Exception): - sandbox.client(3).transfer(2.000, 'bootstrap2', 'bootstrap3') diff --git a/tests_python/tests_012/test_migration.py b/tests_python/tests_012/test_migration.py deleted file mode 100644 index ca1566181e6a..000000000000 --- a/tests_python/tests_012/test_migration.py +++ /dev/null @@ -1,298 +0,0 @@ -import time - -import pytest - -from launchers.sandbox import Sandbox -from tools import constants, utils -from tools.constants import PROTO_GENESIS -from . import protocol - -MIGRATION_LEVEL = 8 -BAKER = 'bootstrap1' -BAKER_PKH = constants.IDENTITIES[BAKER]['identity'] -PREV_DEPOSIT = protocol.PREV_PARAMETERS["block_security_deposit"] -BAKER_BALANCE = next( - bal for [BAKER_PKH, bal] in protocol.PARAMETERS["bootstrap_accounts"] -) - -PREV_DEPOSIT_RECEIPTS = [ - { - "kind": "contract", - "contract": BAKER_PKH, - "change": "-" + PREV_DEPOSIT, - "origin": "block", - }, - { - "kind": "freezer", - "category": "deposits", - "delegate": BAKER_PKH, - "cycle": 0, - "change": PREV_DEPOSIT, - "origin": "block", - }, -] - -# configure user-activate-upgrade at MIGRATION_LEVEL to test migration -NODE_CONFIG = { - 'network': { - 'genesis': { - 'timestamp': '2018-06-30T16:07:32Z', - 'block': 'BLockGenesisGenesisGenesisGenesisGenesisf79b5d1CoW2', - 'protocol': PROTO_GENESIS, - }, - 'genesis_parameters': { - 'values': {'genesis_pubkey': constants.GENESIS_PK} - }, - 'chain_name': 'TEZOS', - 'sandboxed_chain_name': 'SANDBOXED_TEZOS', - 'user_activated_upgrades': [ - {'level': MIGRATION_LEVEL, 'replacement_protocol': protocol.HASH} - ], - } -} - - -def filter_out_rewards(balance_updates): - """Keep elements for BAKER_PKH which either have no category key - or are not labeled as rewards""" - return [ - bu - for bu in balance_updates - if ( - ("delegate" in bu and bu["delegate"] == BAKER_PKH) - or ("contract" in bu and bu["contract"] == BAKER_PKH) - ) - and ("category" not in bu or bu["category"] != 'rewards') - ] - - -@pytest.fixture(scope="class") -def client(sandbox): - sandbox.add_node(0, params=constants.NODE_PARAMS, node_config=NODE_CONFIG) - protocol.activate( - sandbox.client(0), - proto=protocol.PREV_HASH, - parameters=protocol.PREV_PARAMETERS, - activate_in_the_past=True, - ) - yield sandbox.client(0) - - -all_bootstrap_accounts = [f"bootstrap{i}" for i in range(1, 6)] - - -def endorse_all(client, endorse="endorse"): - cmd = [endorse, "for"] + all_bootstrap_accounts + ["--force"] - client.run(cmd) - - -def manual_bake(client, baker): - """Tenderbake baking using propose/preendorse/endorse - - Using the 3 lower level steps instead of `bake for` allows to control who - bakes while (pre)endorsing with all known accounts. Such fine-grained - control cannot be achieved through `bake for`. - - """ - client.propose([baker], ["--minimal-timestamp"]) - endorse_all(client, endorse="preendorse") - endorse_all(client) - - -@pytest.mark.incremental -class TestMigration: - """Test migration from PROTO_A (the previous protocol) to PROTO_B (the - current protocol). - - After migration, test snapshots: - - node0: activate PROTO_A, migrate to PROTO_B, bake, export - a snapshot in full and rolling modes, and terminate - - node1: import full, bake - - node2: import rolling, sync, bake - - node3: reconstruct full, sync, bake - - all 4 are synced - """ - - def test_init(self, client): - # 1: genesis block - client.get_head() - client.rpc('get', '/config/network/user_activated_upgrades') - - def test_activate(self, client, sandbox): - # 2: activated PROTO_A - utils.bake(client, BAKER) - assert client.get_protocol() == protocol.PREV_HASH - assert sandbox.client(0).get_head()['header']['proto'] == 1 - metadata = client.get_metadata() - assert metadata['balance_updates'] == PREV_DEPOSIT_RECEIPTS - # PROTO_A is using env. V1+, metadata hashes should be present - _ops_metadata_hash = client.get_operations_metadata_hash() - _block_metadata_hash = client.get_block_metadata_hash() - - def test_migration(self, client, sandbox): - # 3: last block of PROTO_A, runs migration code (MIGRATION_LEVEL) - for _i in range(MIGRATION_LEVEL - 2): - utils.bake(client, BAKER) - metadata = client.get_metadata() - assert metadata['next_protocol'] == protocol.HASH - assert metadata['balance_updates'] == PREV_DEPOSIT_RECEIPTS - # PROTO_B is using env. V1+, metadata hashes should be present - _ops_metadata_hash = client.get_operations_metadata_hash() - _block_metadata_hash = client.get_block_metadata_hash() - assert sandbox.client(0).get_head()['header']['proto'] == 2 - - def test_new_proto(self, client, sandbox): - # 4: first block of PROTO_B - manual_bake(client, BAKER) - # client.multibake(args=["--minimal-timestamp"]) - # utils.bake(client, "bootstrap1 bootstrap2") - assert client.get_protocol() == protocol.HASH - assert sandbox.client(0).get_head()['header']['proto'] == 2 - # check that migration balance update appears in receipts - _metadata = client.get_metadata() - constants = client.rpc( - 'get', '/chains/main/blocks/head/context/constants' - ) - # N.B.: after migration, the values being used are those set in - # raw_context - bond = str( - int(constants["frozen_deposits_percentage"]) - * int(int(BAKER_BALANCE) / 100) - ) - block_reward = str(constants["baking_reward_fixed_portion"]) - deposit = str((MIGRATION_LEVEL - 1) * int(PREV_DEPOSIT)) - # these receipts appear in the first block of TB - migration_receipts = [ - { - "kind": "freezer", - "category": "deposits", - "delegate": BAKER_PKH, - "change": bond, - "origin": "migration", - }, - { - "kind": "freezer", - "category": "legacy_deposits", - "delegate": BAKER_PKH, - "cycle": 0, - "change": "-" + deposit, - "origin": "migration", - }, - { - "kind": "contract", - "contract": BAKER_PKH, - "change": "-" + str(int(bond) - int(deposit)), - "origin": "migration", - }, - # BAKER has baked the first block of TB; - # hence, the reward for baking - { - "kind": "contract", - "contract": BAKER_PKH, - "change": block_reward, - "origin": "block", - }, - ] - initial_balance_updates = migration_receipts - new_balance_updates = filter_out_rewards(_metadata['balance_updates']) - assert initial_balance_updates == new_balance_updates - _ops_metadata_hash = client.get_operations_metadata_hash() - _block_metadata_hash = client.get_block_metadata_hash() - - def test_new_proto_second(self, client): - # 5: second block of PROTO_B - manual_bake(client, BAKER) - metadata = client.get_metadata() - constants = client.rpc( - 'get', '/chains/main/blocks/head/context/constants' - ) - # N.B.: after migration, the values being used are those set - # in raw_context - # using protocol.PARAMETERS["consensus_threshold"] is wrong - bonus_per_slot = constants["baking_reward_bonus_per_slot"] - bonus = ( - constants["consensus_committee_size"] - - constants["consensus_threshold"] - ) * int(bonus_per_slot) - block_reward = str(constants["baking_reward_fixed_portion"]) - receipts = [ - { - "kind": "contract", - "contract": BAKER_PKH, - "change": block_reward, - "origin": "block", - }, - { - "kind": "contract", - "contract": BAKER_PKH, - "change": str(bonus), - "origin": "block", - }, - ] - assert filter_out_rewards(metadata['balance_updates']) == receipts - - def test_terminate_node0(self, client, sandbox: Sandbox, session: dict): - # to export rolling snapshot, we need to be at level > 60 - # (see `max_operations_ttl`) - level = client.get_head()['header']['level'] - for _ in range(60 - level + 1): - manual_bake(client, BAKER) - assert client.get_head()['header']['level'] == 61 - - # terminate node0 - session['head_hash'] = sandbox.client(0).get_head()['hash'] - sandbox.node(0).terminate() - time.sleep(1) - - def test_export_snapshots(self, sandbox, tmpdir, session: dict): - node_export = sandbox.node(0) - file_full = f'{tmpdir}/FILE.full' - file_rolling = f'{tmpdir}/FILE.rolling' - head_hash = session['head_hash'] - session['snapshot_full'] = file_full - session['snapshot_rolling'] = file_rolling - node_export.snapshot_export(file_full, params=['--block', head_hash]) - node_export.snapshot_export( - file_rolling, params=['--block', head_hash, '--rolling'] - ) - - def test_import_full_snapshot_node1(self, sandbox, session): - sandbox.add_node( - 1, snapshot=session['snapshot_full'], node_config=NODE_CONFIG - ) - client = sandbox.client(1) - client.multibake(args=["--minimal-timestamp"]) - - def test_import_rolling_snapshot_node2(self, sandbox, session): - sandbox.add_node( - 2, - snapshot=session['snapshot_rolling'], - params=constants.NODE_PARAMS, - node_config=NODE_CONFIG, - ) - client = sandbox.client(2) - utils.synchronize([sandbox.client(1), client], max_diff=0) - client.multibake(args=["--minimal-timestamp"]) - - def test_reconstruct_full_node3(self, sandbox, session): - sandbox.add_node( - 3, - snapshot=session['snapshot_full'], - node_config=NODE_CONFIG, - params=constants.NODE_PARAMS, - ) - sandbox.node(3).terminate() - time.sleep(3) - sandbox.node(3).reconstruct() - sandbox.node(3).run() - client = sandbox.client(3) - assert client.check_node_listening() - utils.synchronize( - [sandbox.client(1), sandbox.client(2), client], max_diff=0 - ) - client.multibake(args=["--minimal-timestamp"]) - - def test_rerun_node0(self, sandbox): - sandbox.node(0).run() - sandbox.client(0).check_node_listening() - utils.synchronize(sandbox.all_clients(), max_diff=0) diff --git a/tests_python/tests_012/test_mockup.py b/tests_python/tests_012/test_mockup.py deleted file mode 100644 index f88cc5cf1f82..000000000000 --- a/tests_python/tests_012/test_mockup.py +++ /dev/null @@ -1,762 +0,0 @@ -""" This file tests the mockup mode (tezos-client --mode mockup). - In this mode the client does not need a node running. - - Make sure to either use the fixture mockup_client or - to mimick it if you want a mockup with custom parameters. - - Care is taken not to leave any base_dir dangling after - tests are finished. Please continue doing this. -""" -import json -import os -import re -import shutil -import tempfile -from pathlib import Path -from typing import Any, List, Optional, Tuple -import pytest -from launchers.sandbox import Sandbox -from client.client import Client -from client.client_output import CreateMockupResult - -from . import protocol - -_BA_FLAG = "bootstrap-accounts" -_PC_FLAG = "protocol-constants" - - -@pytest.mark.client -def test_list_mockup_protocols(sandbox: Sandbox): - """Executes `tezos-client list mockup protocols` - The call must succeed and return a non empty list. - """ - try: - client = sandbox.create_client() - protocols = client.list_mockup_protocols().mockup_protocols - assert protocols - finally: - shutil.rmtree(client.base_dir) - - -@pytest.mark.client -def test_create_mockup_dir_exists_nonempty(sandbox: Sandbox): - """Executes `tezos-client --base-dir /tmp/mdir create mockup` - when /tmp/mdir is a non empty directory which is NOT a mockup - directory. The call must fail. - """ - with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: - # Make the directory not empty - with open(os.path.join(base_dir, "whatever"), "w") as handle: - handle.write("") - unmanaged_client = sandbox.create_client(base_dir=base_dir) - res = unmanaged_client.create_mockup( - protocol=protocol.HASH, check=False - ).create_mockup_result - assert res == CreateMockupResult.DIR_NOT_EMPTY - - -@pytest.mark.client -def test_retrieve_addresses(mockup_client: Client): - """Retrieves known addresses of a fresh mockup. - The call must succeed. - """ - addresses = mockup_client.get_known_addresses().wallet - assert addresses == { - 'bootstrap1': 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', - 'bootstrap2': 'tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN', - 'bootstrap3': 'tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU', - 'bootstrap4': 'tz1b7tUupMgCNw2cCLpKTkSD1NZzB5TkP2sv', - 'bootstrap5': 'tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv', - } - - -@pytest.mark.client -def test_create_mockup_already_initialized(mockup_client: Client): - """Executes `tezos-client --base-dir /tmp/mdir create mockup` - when /tmp/mdir is not fresh. - The call must fail. - """ - # mockup was created already by fixture, try to create it second time: - res = mockup_client.create_mockup( - protocol=protocol.HASH, check=False - ).create_mockup_result - # it should fail: - assert res == CreateMockupResult.ALREADY_INITIALIZED - - -@pytest.mark.client -def test_transfer(mockup_client: Client): - """Executes `tezos-client --base-dir /tmp/mdir -M mockup - transfer 1 from bootstrap1 to bootstrap2` - in a valid mockup environment. - The call must succeed and the balances must be updated correctly. - """ - giver = "bootstrap1" - receiver = "bootstrap2" - transferred = 1.0 - - giver_balance_before = mockup_client.get_balance(giver) - receiver_balance_before = mockup_client.get_balance(receiver) - mockup_client.transfer(transferred, giver, receiver) - giver_balance_after = mockup_client.get_balance(giver) - receiver_balance_after = mockup_client.get_balance(receiver) - - assert giver_balance_after < giver_balance_before - transferred - assert receiver_balance_after == receiver_balance_before + transferred - - -# It's impossible to guess values of chain_id, these ones have been -# obtained by looking at the output of `compute chain id from seed` -@pytest.mark.parametrize( - 'chain_id', - [ - "NetXcqTGZX74DxG", - "NetXaFDF7xZQCpR", - "NetXkKbtqncJcAz", - "NetXjjE5cZUeWPy", - "NetXi7C1pyLhQNe", - ], -) -@pytest.mark.parametrize( - 'initial_timestamp', ["2020-07-21T17:11:10+02:00", "1970-01-01T00:00:00Z"] -) -@pytest.mark.client -def test_create_mockup_custom_constants( - sandbox: Sandbox, chain_id: str, initial_timestamp: str -): - """Tests `tezos-client create mockup` --protocols-constants argument - The call must succeed. - - Args: - mockup_client: the client to use - chain_id (str): the string to pass for field `chain_id` - initial_timestamp(str): an ISO-8601 formatted date string - """ - # Use another directory so that the constants change takes effect - with tempfile.TemporaryDirectory( - prefix='tezos-client.' - ) as base_dir, tempfile.NamedTemporaryFile( - prefix='tezos-custom-constants', mode='w+t' - ) as json_file: - json_data = { - "hard_gas_limit_per_operation": "400000", - "chain_id": chain_id, - "initial_timestamp": initial_timestamp, - } - json.dump(json_data, json_file) - json_file.flush() - unmanaged_client = sandbox.create_client(base_dir=base_dir) - res = unmanaged_client.create_mockup( - protocol=protocol.HASH, protocol_constants_file=json_file.name - ).create_mockup_result - assert res == CreateMockupResult.OK - - -def _create_accounts_list(): - """ - Returns a list of dictionary with 3 entries, that are - valid for being translated to json and passed - to `--bootstrap-accounts` - """ - accounts_list = [] - - def add_account(name: str, sk_uri: str, amount: str): - entry = { - "name": name, - "sk_uri": "unencrypted:" + sk_uri, - "amount": amount, - } - accounts_list.append(entry) - - # Took json structure from - # https://gitlab.com/tezos/tezos/-/merge_requests/1720 - add_account( - "bootstrap0", - "edsk2uqQB9AY4FvioK2YMdfmyMrer5R8mGFyuaLLFfSRo8EoyNdht3", - "2000000000000", - ) - add_account( - "bootstrap1", - "edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh", - "1000000000000", - ) - - return accounts_list - - -@pytest.mark.client -def test_create_mockup_custom_bootstrap_accounts(sandbox: Sandbox): - """Tests `tezos-client create mockup` --bootstrap-accounts argument - The call must succeed. - """ - accounts_list = _create_accounts_list() - - # Use another directory so that the constants change takes effect - with tempfile.TemporaryDirectory( - prefix='tezos-client.' - ) as base_dir, tempfile.NamedTemporaryFile( - prefix='tezos-bootstrap-accounts', mode='w+t' - ) as json_file: - json.dump(accounts_list, json_file) - json_file.flush() - # Follow pattern of mockup_client fixture: - unmanaged_client = sandbox.create_client(base_dir=base_dir) - res = unmanaged_client.create_mockup( - protocol=protocol.HASH, bootstrap_accounts_file=json_file.name - ).create_mockup_result - assert res == CreateMockupResult.OK - mock_client = sandbox.create_client(base_dir=base_dir, mode="mockup") - addresses_result = mock_client.get_known_addresses() - names_sent = sorted([account["name"] for account in accounts_list]) - names_witnessed = sorted(list(addresses_result.wallet.keys())) - assert names_sent == names_witnessed - - -@pytest.mark.client -def test_transfer_bad_base_dir(sandbox: Sandbox): - """Executes `tezos-client --base-dir /tmp/mdir create mockup` - when /tmp/mdir looks like a dubious base directory. - Checks that a warning is printed. - """ - try: - unmanaged_client = sandbox.create_client() - res = unmanaged_client.create_mockup( - protocol=protocol.HASH - ).create_mockup_result - assert res == CreateMockupResult.OK - base_dir = unmanaged_client.base_dir - mockup_dir = os.path.join(base_dir, "mockup") - - # A valid mockup has a directory named "mockup", in its directory: - assert os.path.isdir(mockup_dir) - mock_client = sandbox.create_client(base_dir=base_dir, mode="mockup") - # Delete this directory: - shutil.rmtree(mockup_dir) - # And put a file instead: - Path(os.path.join(mockup_dir)).touch() - - # Now execute a command - cmd = ["transfer", "1", "from", "bootstrap1", "to", "bootstrap2"] - (_, err_output, _) = mock_client.run_generic(cmd, check=False) - # See - # https://gitlab.com/tezos/tezos/-/merge_requests/1760#note_329071488 - # for the content being matched - searched = "Some commands .* might not work correctly." - # Witness that warning is printed: - assert re.search( - searched, err_output - ), f"'{searched}' not matched in error output" - finally: - shutil.rmtree(base_dir) - - -@pytest.mark.client -def test_config_show_mockup(mockup_client: Client): - """Executes `tezos-client --mode mockup config show` in - a state where it should succeed. - """ - mockup_client.run_generic(["--protocol", protocol.HASH, "config", "show"]) - - -@pytest.mark.client -def test_config_show_mockup_fail(mockup_client: Client): - """Executes `tezos-client --mode mockup config show` when - base dir is NOT a mockup. It should fail as this is dangerous - (the default base directory could contain sensitive data, - such as private keys) - """ - shutil.rmtree(mockup_client.base_dir) # See test_config_init_mockup_fail - # for a variant of how to make the base dir invalid for the mockup mode - _, _, return_code = mockup_client.run_generic( - ["config", "show"], check=False - ) - - # recreate directory: the cleanup later on expects its existence - os.mkdir(mockup_client.base_dir) - assert return_code != 0 - - -@pytest.mark.client -def test_config_init_mockup(mockup_client: Client): - """Executes `tezos-client config init mockup` in - a state where it should succeed. - """ - # We cannot use NamedTemporaryFile because `config init mockup` - # does not overwrite files. Because NamedTemporaryFile creates the file - # it would make the test fail. - ba_json_file = tempfile.mktemp(prefix='tezos-bootstrap-accounts') - pc_json_file = tempfile.mktemp(prefix='tezos-proto-consts') - # 1/ call `config init mockup` - mockup_client.run( - [ - "--protocol", - protocol.HASH, - "config", - "init", - f"--{_BA_FLAG}", - ba_json_file, - f"--{_PC_FLAG}", - pc_json_file, - ] - ) - - # 2/ Try loading the files, to check they are valid json - with open(ba_json_file) as handle: - json.load(handle) - with open(pc_json_file) as handle: - json.load(handle) - - # Cleanup - os.remove(ba_json_file) - os.remove(pc_json_file) - - -@pytest.mark.client -def test_config_init_mockup_fail(mockup_client: Client): - """Executes `tezos-client config init mockup` when - base dir is NOT a mockup. It should fail as this is dangerous - (the default base directory could contain sensitive data, - such as private keys) - """ - ba_json_file = tempfile.mktemp(prefix='tezos-bootstrap-accounts') - pc_json_file = tempfile.mktemp(prefix='tezos-proto-consts') - cmd = [ - "--protocol", - protocol.HASH, - "config", - "init", - f"--{_BA_FLAG}", - ba_json_file, - f"--{_PC_FLAG}", - pc_json_file, - ] - - # A valid mockup has a directory named "mockup" in its base_dir: - mockup_dir = os.path.join(mockup_client.base_dir, "mockup") - assert os.path.isdir(mockup_dir) - # Delete this directory, so that the base_dir is not a valid mockup - # base dir anymore: - shutil.rmtree(mockup_dir) # See test_config_show_mockup_fail above - # for a variant of how to make the base_dir invalid for the mockup mode - - _, _, return_code = mockup_client.run_generic(cmd, check=False) - assert return_code != 0 - # Check the test doesn't leak directories: - assert not os.path.exists(ba_json_file) - assert not os.path.exists(pc_json_file) - - -def _try_json_loads(flag: str, string: str) -> Any: - """ Converts the given string to a json object """ - try: - return json.loads(string) - except json.JSONDecodeError: - pytest.fail( - f"""Write back of {flag} value is not valid json: -{string}""" - ) - # Added to get rid of pylint warning inconsistent-return-statements. - # pytest.fail has no return value (NoReturn). - return None - - -def _get_state_using_config_init_mockup( - mock_client: Client, -) -> Tuple[str, str]: - """ - Calls `config init mockup` on a mockup client and returns - the strings of the bootstrap accounts and the protocol - constants - - Note that because this a mockup specific operation, the `mock_client` - parameter must be in mockup mode; do not give a vanilla client. - """ - ba_json_file = tempfile.mktemp(prefix='tezos-bootstrap-accounts') - pc_json_file = tempfile.mktemp(prefix='tezos-proto-consts') - - mock_client.run( - [ - "--protocol", - protocol.HASH, - "config", - "init", - f"--{_BA_FLAG}", - ba_json_file, - f"--{_PC_FLAG}", - pc_json_file, - ] - ) - - with open(ba_json_file) as handle: - ba_str = handle.read() - with open(pc_json_file) as handle: - pc_str = handle.read() - - # Cleanup of tempfile.mktemp - os.remove(ba_json_file) - os.remove(pc_json_file) - - return (ba_str, pc_str) - - -def _get_state_using_config_show_mockup( - mock_client: Client, -) -> Tuple[str, str]: - """ - Calls `--mode mockup config show` on a mockup client and returns - the strings of the bootstrap accounts and the protocol - constants, by parsing standard output. - - Note that because this a mockup specific operation, the `mock_client` - parameter must be in mockup mode; do not give a vanilla client. - """ - - def _find_line_starting_with(strings, searched) -> int: - i = 0 - for string in strings: - if string.startswith(searched): - return i - i += 1 - return -1 - - def _parse_config_init_output(string: str) -> Tuple[str, str]: - """Parses the output of `--mode mockup config init` - and return the json of the bootstrap accounts - and the protocol constants - """ - tagline1 = f"Default value of --{_BA_FLAG}:" - bootstrap_accounts_index = string.find(tagline1) - assert bootstrap_accounts_index >= 0, f"{_BA_FLAG} line not found" - - tagline2 = f"Default value of --{_PC_FLAG}:" - proto_constants_index = string.find(tagline2) - assert proto_constants_index > 0, f"{_PC_FLAG} line not found" - - bc_json = string[ - bootstrap_accounts_index + len(tagline1) : proto_constants_index - 1 - ] - - pc_json = string[proto_constants_index + len(tagline2) + 1 :] - return (bc_json, pc_json) - - stdout = mock_client.run(["--protocol", protocol.HASH, "config", "show"]) - return _parse_config_init_output(stdout) - - -def write_file(filename, contents): - filename.write(contents) - filename.flush() - - -def _gen_assert_msg(flag, sent, received): - return ( - f"Json sent with --{flag} differs from json received" - f"\nJson sent is:\n{sent}" - f"\nwhile json received is:\n{received}" - ) - - -def rm_amounts(bootstrap_accounts): - for account in bootstrap_accounts: - account.pop('amount', None) - - -def compute_expected_amounts( - bootstrap_accounts, frozen_deposits_percentage: int -) -> None: - pct = 100 - frozen_deposits_percentage - for account in bootstrap_accounts: - account['amount'] = str(int(pct * int(account['amount']) / 100)) - - -def _test_create_mockup_init_show_roundtrip( - sandbox: Sandbox, - read_initial_state, - read_final_state, - bootstrap_json: Optional[str] = None, - protocol_constants_json: Optional[str] = None, -): - """1/ Creates a mockup, using possibly custom bootstrap_accounts - (as specified by `bootstrap_json`) - 2/ Then execute either `--mode mockup config show` or - `--mode mockup config init` to obtain the mockup's parameters - (parse stdout if `show` is called, - read the files generated by `init` otherwise) - - This is done by executing `read_initial_state` - 3/ Recreate a mockup using the output gathered in 2/ and call - `--mode mockup config show`/`--mode mockup config init` - (this is done by executing `read_final_state`) to check that output - received is similar to output seen in 2. - - This is a roundtrip test. - """ - - ba_file = None - pc_file = None - - try: - if protocol_constants_json is not None: - pc_file = tempfile.mktemp(prefix='tezos-proto-consts') - with open(pc_file, 'w') as handle: - handle.write(protocol_constants_json) - - if bootstrap_json is not None: - ba_file = tempfile.mktemp(prefix='tezos-bootstrap-accounts') - with open(ba_file, 'w') as handle: - handle.write(bootstrap_json) - - with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: - # Follow pattern of mockup_client fixture: - unmanaged_client = sandbox.create_client(base_dir=base_dir) - res = unmanaged_client.create_mockup( - protocol=protocol.HASH, - bootstrap_accounts_file=ba_file, - protocol_constants_file=pc_file, - ).create_mockup_result - assert res == CreateMockupResult.OK - mock_client = sandbox.create_client( - base_dir=base_dir, mode="mockup" - ) - (ba_str, pc_str) = read_initial_state(mock_client) - finally: - if pc_file is not None: - os.remove(pc_file) - if ba_file is not None: - os.remove(ba_file) - - # 2a/ Check the json obtained is valid by building json objects - ba_sent = _try_json_loads(_BA_FLAG, ba_str) - pc_sent = _try_json_loads(_PC_FLAG, pc_str) - - # Test that the initial mockup call honored the values it received. If - # it didn't, all calls would return the default values all along, and - # everything would seem fine; but it wouldn't be. This was witnessed in - # https://gitlab.com/tezos/tezos/-/issues/938 - if bootstrap_json: - ba_input = json.loads(bootstrap_json) - # adjust amount field on Tenderbake w.r.t. to frozen_deposits_percentage - compute_expected_amounts( - ba_input, int(pc_sent['frozen_deposits_percentage']) - ) - assert ba_sent == ba_input - - if protocol_constants_json: - pc_input = json.loads(protocol_constants_json) - assert pc_sent == pc_input - - # 3/ Pass obtained json to a new mockup instance, to check json - # is valid w.r.t. ocaml encoding - - # Use another directory so that the constants change takes effect - with tempfile.TemporaryDirectory( - prefix='tezos-client.' - ) as base_dir, tempfile.NamedTemporaryFile( - prefix='tezos-bootstrap-accounts', mode='w+t' - ) as ba_json_file, tempfile.NamedTemporaryFile( - prefix='tezos-proto-consts', mode='w+t' - ) as pc_json_file, tempfile.TemporaryDirectory( - prefix='tezos-client.' - ) as base_dir: - - write_file(ba_json_file, ba_str) - write_file(pc_json_file, pc_str) - - with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: - # Follow pattern of mockup_client fixture: - unmanaged_client = sandbox.create_client(base_dir=base_dir) - res = unmanaged_client.create_mockup( - protocol=protocol.HASH, - protocol_constants_file=pc_json_file.name, - bootstrap_accounts_file=ba_json_file.name, - ).create_mockup_result - assert res == CreateMockupResult.OK - mock_client = sandbox.create_client( - base_dir=base_dir, mode="mockup" - ) - # 4/ Retrieve state again - (ba_received_str, pc_received_str) = read_final_state(mock_client) - - # Convert it to json objects (check that json is valid) - ba_received = _try_json_loads(_BA_FLAG, ba_received_str) - pc_received = _try_json_loads(_PC_FLAG, pc_received_str) - - # and finally check that json objects received are the same - # as the ones that were given as input - - # adjust amount field on Tenderbake w.r.t. to frozen_deposits_percentage - compute_expected_amounts( - ba_sent, int(pc_sent['frozen_deposits_percentage']) - ) - - assert ba_sent == ba_received, _gen_assert_msg( - _BA_FLAG, ba_sent, ba_received - ) - assert pc_sent == pc_received, _gen_assert_msg( - _PC_FLAG, pc_sent, pc_received - ) - - -@pytest.mark.client -@pytest.mark.parametrize( - 'initial_bootstrap_accounts', [None, json.dumps(_create_accounts_list())] -) -@pytest.mark.parametrize( - 'protocol_constants', - [ - None, - json.dumps( - { - "initial_timestamp": "2021-02-03T12:34:56Z", - "chain_id": "NetXaFDF7xZQCpR", - "min_proposal_quorum": 501, - "quorum_max": 7001, - "quorum_min": 2001, - "hard_storage_limit_per_operation": "60001", - "cost_per_byte": "251", - "baking_reward_fixed_portion": "20000000", - "baking_reward_bonus_per_slot": "2500", - "endorsing_reward_per_slot": "2857", - "origination_size": 258, - "seed_nonce_revelation_tip": "125001", - "tokens_per_roll": "8000000001", - "proof_of_work_threshold": "-2", - "hard_gas_limit_per_block": "10400001", - "hard_gas_limit_per_operation": "1040001", - 'consensus_committee_size': 12, - # DO NOT EDIT the value consensus_threshold this is actually a - # constant, not a parameter - 'consensus_threshold': 0, - 'delegate_selection': 'random', - 'minimal_participation_ratio': { - 'denominator': 5, - 'numerator': 1, - }, - 'minimal_block_delay': '1', - 'delay_increment_per_round': '1', - 'max_slashing_period': 12, - "blocks_per_voting_period": 65, - "blocks_per_stake_snapshot": 5, - "blocks_per_commitment": 5, - "blocks_per_cycle": 9, - "preserved_cycles": 3, - "liquidity_baking_escape_ema_threshold": 1000000, - "liquidity_baking_subsidy": "2500000", - "liquidity_baking_sunset_level": 1024, - "max_operations_time_to_live": 120, - "frozen_deposits_percentage": 10, - 'ratio_of_frozen_deposits_slashed_per_double_endorsement': { - 'numerator': 1, - 'denominator': 2, - }, - "double_baking_punishment": "640000001", - } - ), - ], -) -@pytest.mark.parametrize( - 'read_initial_state', - [_get_state_using_config_show_mockup, _get_state_using_config_init_mockup], -) -@pytest.mark.parametrize( - 'read_final_state', - [_get_state_using_config_show_mockup, _get_state_using_config_init_mockup], -) -def test_create_mockup_config_show_init_roundtrip( - sandbox: Sandbox, - initial_bootstrap_accounts, - protocol_constants, - read_initial_state, - read_final_state, -): - """1/ Create a mockup, using possibly custom bootstrap_accounts - (as specified by `initial_bootstrap_json`). - 2/ Then execute either `--mode mockup config show` - or `--mode mockup config init` to obtain the mockup's parameters, - as specified by `read_initial_state`. - 3/ Recreate a mockup using the output gathered in 2/ and call - `read_final_state` to check that output - received is similar to output seen in 2. - This is a roundtrip test using a matrix. - """ - _test_create_mockup_init_show_roundtrip( - sandbox, - read_initial_state, - read_final_state, - initial_bootstrap_accounts, - protocol_constants, - ) - - -def test_transfer_rpc(mockup_client: Client): - """Variant of test_transfer that uses RPCs to get the balances.""" - giver = "bootstrap1" - receiver = "bootstrap2" - transferred = 1.0 - transferred_mutz = transferred * 1000000 - - def get_balance(tz1): - res = mockup_client.rpc( - 'get', - f'chains/main/blocks/head/context/contracts/{tz1}/balance', - ) - return float(res) - - addresses = mockup_client.get_known_addresses() - giver_tz1 = addresses.wallet[giver] - recvr_tz1 = addresses.wallet[receiver] - giver_balance_before = get_balance(giver_tz1) - receiver_balance_before = get_balance(recvr_tz1) - mockup_client.transfer(transferred, giver, receiver) - giver_balance_after = get_balance(giver_tz1) - receiver_balance_after = get_balance(recvr_tz1) - - assert giver_balance_after < giver_balance_before - transferred_mutz - assert receiver_balance_after == receiver_balance_before + transferred_mutz - - -@pytest.mark.parametrize( - 'protos', - [ - (proto1, proto2) - for proto1 in [protocol.HASH, protocol.PREV_HASH] - for proto2 in [protocol.HASH, protocol.PREV_HASH, ""] - ], -) -@pytest.mark.parametrize( - 'command', - [ - ["config", "show"], - ["config", "init"], - ["list", "known", "addresses"], - ["get", "balance", "for", "bootstrap1"], - ], -) -def test_proto_mix( - sandbox: Sandbox, protos: Tuple[str, str], command: List[str] -): - """ - This test covers 3 cases: - - 1/ When proto's second element equals the first member: - it tests that the command works. - 2/ When proto's second element is empty: - it tests that the correct mockup implementation is picked - (i.e. the one of the first element) and that the command works. - 3/ When protos' second element is not empty and differs from - the first member: it tests - that creating a mockup with a protocol and using it with another - protocol fails. - """ - proto1 = protos[0] - proto2 = protos[1] - with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: - # Follow pattern of mockup_client fixture: - unmanaged_client = sandbox.create_client(base_dir=base_dir) - res = unmanaged_client.create_mockup(protocol=proto1) - assert res.create_mockup_result == CreateMockupResult.OK - mock_client = sandbox.create_client(base_dir=base_dir, mode="mockup") - cmd = (["--protocol", proto2] if proto2 else []) + command - success = (proto2 == proto1) or (not proto2) - (_, _, return_code) = mock_client.run_generic(cmd, check=False) - assert (return_code == 0) == success diff --git a/tests_python/tests_012/test_multinode_snapshot.py b/tests_python/tests_012/test_multinode_snapshot.py deleted file mode 100644 index b993886cda0a..000000000000 --- a/tests_python/tests_012/test_multinode_snapshot.py +++ /dev/null @@ -1,753 +0,0 @@ -import tempfile -import shutil -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox -from . import protocol - -PARAMS = constants.NODE_PARAMS - -BATCH_1 = 48 -BATCH_2 = 48 # not enough bakes to drag the savepoint after snapshot import -BATCH_3 = 32 # enough bakes to drag the savepoint -GROUP1 = [0, 1, 2] -GROUP2 = [0, 1, 2, 3, 4, 5] -GROUP_FULL = [1, 3] -GROUP_ROLLING = [2, 4, 5] -SNAPSHOT_DIR = tempfile.mkdtemp(prefix='tezos-snapshots.') -BLOCKS_PER_CYCLE = 8 -PRESERVED_CYCLES = 2 -RETAINED_CYCLES = 8 - - -def clean(node): - shutil.rmtree(node.node_dir) - - -# Restart node. Side effect: clean store caches -def restart(sandbox, node_id): - sandbox.node(node_id).terminate_or_kill() - sandbox.node(node_id).run() - assert sandbox.client(node_id).check_node_listening() - - -@pytest.mark.multinode -@pytest.mark.incremental -@pytest.mark.snapshot -@pytest.mark.slow -class TestMultiNodeSnapshot: - # Tests both the snapshot mechanism and the store's behaviour - # TL;DR, how it works: - # - bake few blocks using all history modes - # - export all kinds of snapshots - # - import all kinds of snapshots - # - check consistency (the snapshot's window includes genesis) - # - bake a few blocks - # - check consistency (the checkpoints should not move yet) - # - bake a few blocks - # - check consistency (the checkpoints should have moved) - # - export all kinds of snapshots - # - import all kinds of snapshots - # - check consistency (checkpoints should be still valid) - # - bake a few blocks - # - check consistency (the checkpoints should have moved) - - def test_init(self, sandbox: Sandbox): - # Node 0: archive baker - sandbox.add_node(0, params=PARAMS + ['--history-mode', 'archive']) - # Node 1: full - sandbox.add_node(1, params=PARAMS + ['--history-mode', 'full']) - # Node 2: rolling - sandbox.add_node(2, params=PARAMS + ['--history-mode', 'rolling']) - protocol.activate(sandbox.client(GROUP1[0]), activate_in_the_past=True) - - def test_bake_batch_1(self, sandbox, session): - for _ in range(BATCH_1): - utils.bake(sandbox.client(0)) - sandbox.client(0).run(['endorse', "for", 'bootstrap2', '--force']) - session['head_hash'] = sandbox.client(0).get_head()['hash'] - session['head_level'] = sandbox.client(0).get_head()['header']['level'] - session['snapshot_level'] = session['head_level'] - - def test_group1_batch_1(self, sandbox, session): - for i in GROUP1: - assert utils.check_level(sandbox.client(i), session['head_level']) - - ########################################################################### - # Export all kinds of snapshots - def test_archive_export_full_1(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node0_batch_1.full' - export_level = session['snapshot_level'] - sandbox.node(0).snapshot_export( - file, params=['--block', f'{export_level}'] - ) - - def test_archive_export_rolling_1(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node0_batch_1.rolling' - export_level = session['snapshot_level'] - sandbox.node(0).snapshot_export( - file, params=['--block', f'{export_level}', '--rolling'] - ) - - def test_full_export_full_1(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node1_batch_1.full' - export_level = session['snapshot_level'] - sandbox.node(1).snapshot_export( - file, params=['--block', f'{export_level}'] - ) - - def test_full_export_rolling_1(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node1_batch_1.rolling' - export_level = session['snapshot_level'] - sandbox.node(1).snapshot_export( - file, params=['--block', f'{export_level}', '--rolling'] - ) - - def test_rolling_export_rolling_1(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node2_batch_1.rolling' - export_level = session['snapshot_level'] - sandbox.node(2).snapshot_export( - file, params=['--block', f'{export_level}', '--rolling'] - ) - - ########################################################################### - # Import all kinds of snapshots - # New node: 3 - def test_run_full_node_from_archive_1(self, sandbox): - file = f'{SNAPSHOT_DIR}/node0_batch_1.full' - sandbox.add_node(3, snapshot=file, params=PARAMS) - - # New node: 4 - def test_run_rolling_node_from_archive_1(self, sandbox): - file = f'{SNAPSHOT_DIR}/node0_batch_1.rolling' - sandbox.add_node(4, snapshot=file, params=PARAMS) - - # Reset node 1 - def test_reset_full_node_from_full_1(self, sandbox): - file = f'{SNAPSHOT_DIR}/node1_batch_1.full' - sandbox.rm_node(1) - sandbox.add_node(1, snapshot=file, params=PARAMS) - - # New node: 5 - def test_run_rolling_node_from_full_1(self, sandbox): - file = f'{SNAPSHOT_DIR}/node1_batch_1.rolling' - sandbox.add_node(5, snapshot=file, params=PARAMS) - - # Reset node 2 - def test_reset_rolling_node_from_rolling_1(self, sandbox): - file = f'{SNAPSHOT_DIR}/node2_batch_1.rolling' - sandbox.rm_node(2) - sandbox.add_node(2, snapshot=file, params=PARAMS) - - ########################################################################### - # Check consistency of imported snapshots - # Do not factorize calls to ease debugging - # For the full nodes - def test_node_1_consistency_1(self, sandbox, session): - node_id = 1 - restart(sandbox, node_id) - expected_level = session['snapshot_level'] - expected_checkpoint = expected_level - expected_savepoint = expected_checkpoint - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.full_node_blocks_availability( - node_id, sandbox, expected_savepoint, expected_level - ) - - def test_node_3_consistency_1(self, sandbox, session): - node_id = 3 - restart(sandbox, node_id) - expected_level = session['snapshot_level'] - expected_checkpoint = expected_level - expected_savepoint = expected_checkpoint - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.full_node_blocks_availability( - node_id, sandbox, expected_savepoint, expected_level - ) - - # For the rolling nodes - def test_node_2_consistency_1(self, sandbox, session): - node_id = 2 - restart(sandbox, node_id) - expected_level = session['snapshot_level'] - expected_checkpoint = expected_level - expected_savepoint = expected_checkpoint - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - def test_node_4_consistency_1(self, sandbox, session): - node_id = 4 - restart(sandbox, node_id) - expected_level = session['snapshot_level'] - expected_checkpoint = expected_level - expected_savepoint = expected_checkpoint - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - def test_node_5_consistency_1(self, sandbox, session): - node_id = 5 - restart(sandbox, node_id) - expected_level = session['snapshot_level'] - expected_checkpoint = expected_level - expected_savepoint = expected_checkpoint - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - ########################################################################### - # Bake a few blocks - def test_bake_batch_2(self, sandbox, session): - for _ in range(BATCH_2): - utils.bake(sandbox.client(0)) - sandbox.client(0).run(['endorse', 'for', 'bootstrap2', '--force']) - session['head_hash'] = sandbox.client(0).get_head()['hash'] - session['head_level'] = sandbox.client(0).get_head()['header']['level'] - for i in GROUP2: - assert utils.check_level(sandbox.client(i), session['head_level']) - - ########################################################################### - # Check consistency of imported snapshots after > 5 baked cycles - # The savepoints of full and rolling nodes **have not** been dragged yet - - # For the full nodes - def test_node_1_consistency_2(self, sandbox, session): - node_id = 1 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - savepoint_when_imported = session['snapshot_level'] - expected_savepoint = savepoint_when_imported - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.full_node_blocks_availability( - node_id, sandbox, expected_savepoint, expected_level - ) - - def test_node_3_consistency_2(self, sandbox, session): - node_id = 3 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - savepoint_when_imported = session['snapshot_level'] - expected_savepoint = savepoint_when_imported - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.full_node_blocks_availability( - node_id, sandbox, expected_savepoint, expected_level - ) - - # For the rolling nodes - # The caboose of rolling mode were no dragged yet as - # (checkpoint - max_op_ttl(head)) < savepoint - def test_node_2_consistency_2(self, sandbox, session): - node_id = 2 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - savepoint_when_imported = session['snapshot_level'] - expected_savepoint = savepoint_when_imported - head = sandbox.client(node_id).get_head() - max_op_ttl = head['metadata']['max_operations_ttl'] - expected_caboose = max(expected_checkpoint - max_op_ttl, 0) - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - def test_node_4_consistency_2(self, sandbox, session): - node_id = 4 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - savepoint_when_imported = session['snapshot_level'] - expected_savepoint = savepoint_when_imported - head = sandbox.client(node_id).get_head() - max_op_ttl = head['metadata']['max_operations_ttl'] - expected_caboose = max(expected_checkpoint - max_op_ttl, 0) - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - def test_node_5_consistency_2(self, sandbox, session): - node_id = 5 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - savepoint_when_imported = session['snapshot_level'] - expected_savepoint = savepoint_when_imported - head = sandbox.client(node_id).get_head() - max_op_ttl = head['metadata']['max_operations_ttl'] - expected_caboose = max(expected_checkpoint - max_op_ttl, 0) - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - ########################################################################### - # Bake a few blocks - def test_bake_batch_3(self, sandbox, session): - for _ in range(BATCH_3): - utils.bake(sandbox.client(0)) - sandbox.client(0).run(['endorse', 'for', 'bootstrap2', '--force']) - session['head_hash'] = sandbox.client(0).get_head()['hash'] - session['head_level'] = sandbox.client(0).get_head()['header']['level'] - session['snapshot_level'] = session['head_level'] - for i in GROUP2: - assert utils.check_level(sandbox.client(i), session['head_level']) - - ########################################################################### - # Check consistency of imported snapshots after > 5 baked cycles - # The savepoints of full and rolling nodes **have** been dragged yet - - # For the full nodes - def test_node_1_consistency_3(self, sandbox, session): - node_id = 1 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - expected_savepoint = expected_checkpoint - ( - RETAINED_CYCLES * BLOCKS_PER_CYCLE - ) - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.full_node_blocks_availability( - node_id, sandbox, expected_savepoint, expected_level - ) - - def test_node_3_consistency_3(self, sandbox, session): - node_id = 3 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - expected_savepoint = expected_checkpoint - ( - RETAINED_CYCLES * BLOCKS_PER_CYCLE - ) - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.full_node_blocks_availability( - node_id, sandbox, expected_savepoint, expected_level - ) - - # For the rolling nodes - def test_node_2_consistency_3(self, sandbox, session): - node_id = 2 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - head = sandbox.client(node_id).get_head() - max_op_ttl = head['metadata']['max_operations_ttl'] - expected_savepoint = expected_checkpoint - ( - RETAINED_CYCLES * BLOCKS_PER_CYCLE - ) - expected_caboose = max(expected_checkpoint - max_op_ttl, 0) - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - def test_node_4_consistency_3(self, sandbox, session): - node_id = 4 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - head = sandbox.client(node_id).get_head() - max_op_ttl = head['metadata']['max_operations_ttl'] - expected_savepoint = expected_checkpoint - ( - RETAINED_CYCLES * BLOCKS_PER_CYCLE - ) - expected_caboose = max(expected_checkpoint - max_op_ttl, 0) - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - def test_node_5_consistency_3(self, sandbox, session): - node_id = 5 - restart(sandbox, node_id) - expected_level = session['head_level'] - # last allowed fork level of the head - expected_checkpoint = ( - expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE - ) - head = sandbox.client(node_id).get_head() - max_op_ttl = head['metadata']['max_operations_ttl'] - expected_savepoint = expected_checkpoint - ( - RETAINED_CYCLES * BLOCKS_PER_CYCLE - ) - expected_caboose = max(expected_checkpoint - max_op_ttl, 0) - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - ########################################################################### - # Re-export all kinds of snapshots - def test_archive_export_full_2(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node0_batch_3.full' - export_level = session['snapshot_level'] - sandbox.node(0).snapshot_export( - file, params=['--block', f'{export_level}'] - ) - - def test_archive_export_rolling_2(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node0_batch_3.rolling' - export_level = session['snapshot_level'] - sandbox.node(0).snapshot_export( - file, params=['--block', f'{export_level}', '--rolling'] - ) - - def test_full_export_full_2(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node1_batch_3.full' - export_level = session['snapshot_level'] - sandbox.node(1).snapshot_export( - file, params=['--block', f'{export_level}'] - ) - - def test_full_export_rolling_2(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node1_batch_3.rolling' - export_level = session['snapshot_level'] - sandbox.node(1).snapshot_export( - file, params=['--block', f'{export_level}', '--rolling'] - ) - - def test_rolling_export_rolling_2(self, sandbox, session): - file = f'{SNAPSHOT_DIR}/node2_batch_3.rolling' - export_level = session['snapshot_level'] - sandbox.node(2).snapshot_export( - file, params=['--block', f'{export_level}', '--rolling'] - ) - - ########################################################################### - # Import all kinds of snapshots - # Reset node: 3 - def test_run_full_node_from_archive_2(self, sandbox): - file = f'{SNAPSHOT_DIR}/node0_batch_3.full' - sandbox.rm_node(3) - sandbox.add_node(3, snapshot=file, params=PARAMS) - - # Reset node: 4 - def test_run_rolling_node_from_archive_2(self, sandbox): - file = f'{SNAPSHOT_DIR}/node0_batch_3.rolling' - sandbox.rm_node(4) - sandbox.add_node(4, snapshot=file, params=PARAMS) - - # Reset node 1 - def test_reset_full_node_from_full_2(self, sandbox): - file = f'{SNAPSHOT_DIR}/node1_batch_3.full' - sandbox.rm_node(1) - sandbox.add_node(1, snapshot=file, params=PARAMS) - - # Reset node: 5 - def test_run_rolling_node_from_full_2(self, sandbox): - file = f'{SNAPSHOT_DIR}/node1_batch_3.rolling' - sandbox.rm_node(5) - sandbox.add_node(5, snapshot=file, params=PARAMS) - - # Reset node 2 - def test_reset_rolling_node_from_rolling_2(self, sandbox): - file = f'{SNAPSHOT_DIR}/node2_batch_3.rolling' - sandbox.rm_node(2) - sandbox.add_node(2, snapshot=file, params=PARAMS) - - ########################################################################### - # Check consistency of imported snapshots with > 5 cycles - - # For the full nodes - def test_node_1_consistency_4(self, sandbox, session): - node_id = 1 - restart(sandbox, node_id) - expected_level = session['head_level'] - expected_checkpoint = expected_level - expected_savepoint = expected_checkpoint - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.full_node_blocks_availability( - node_id, sandbox, expected_savepoint, expected_level - ) - - def test_node_3_consistency_4(self, sandbox, session): - node_id = 3 - restart(sandbox, node_id) - expected_level = session['head_level'] - expected_checkpoint = expected_level - expected_savepoint = expected_checkpoint - expected_caboose = 0 - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.full_node_blocks_availability( - node_id, sandbox, expected_savepoint, expected_level - ) - - # For the rolling nodes - def test_node_2_consistency_4(self, sandbox, session): - node_id = 2 - restart(sandbox, node_id) - expected_level = session['head_level'] - expected_checkpoint = expected_level - head = sandbox.client(node_id).get_head() - max_op_ttl = head['metadata']['max_operations_ttl'] - expected_savepoint = expected_checkpoint - expected_caboose = expected_checkpoint - max_op_ttl - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - def test_node_4_consistency_4(self, sandbox, session): - node_id = 4 - restart(sandbox, node_id) - expected_level = session['head_level'] - expected_checkpoint = expected_level - head = sandbox.client(node_id).get_head() - max_op_ttl = head['metadata']['max_operations_ttl'] - expected_savepoint = expected_checkpoint - expected_caboose = expected_checkpoint - max_op_ttl - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - def test_node_5_consistency_4(self, sandbox, session): - node_id = 5 - restart(sandbox, node_id) - expected_level = session['head_level'] - expected_checkpoint = expected_level - head = sandbox.client(node_id).get_head() - max_op_ttl = head['metadata']['max_operations_ttl'] - expected_savepoint = expected_checkpoint - expected_caboose = expected_checkpoint - max_op_ttl - utils.node_consistency_after_import( - node_id, - sandbox, - expected_level, - expected_checkpoint, - expected_savepoint, - expected_caboose, - ) - utils.rolling_node_blocks_availability( - node_id, - sandbox, - expected_savepoint, - expected_caboose, - expected_level, - ) - - ########################################################################### - # Clean exported snapshots - - def test_clean_files(self): - shutil.rmtree(SNAPSHOT_DIR) diff --git a/tests_python/tests_012/test_multinode_storage_reconstruction.py b/tests_python/tests_012/test_multinode_storage_reconstruction.py deleted file mode 100644 index e3dcea034a18..000000000000 --- a/tests_python/tests_012/test_multinode_storage_reconstruction.py +++ /dev/null @@ -1,180 +0,0 @@ -import pytest -from tools import utils -from launchers.sandbox import Sandbox -from . import protocol - -PARAMS = ['--bootstrap-threshold', '0'] -# 2*cycle_size - (protocol_activation) -CEMENTED_LIMIT = 2 * 8 - 1 -# The whole store is cemented -BATCH_1 = 48 -# 2 cycles are pruned in full 5 mode -# This constant is above MAX_OP_TTL -BATCH_2 = 144 - -SNAPSHOT_1 = f'snapshot_block_{BATCH_1}.full' -SNAPSHOT_2 = f'snapshot_block_{BATCH_2}.full' - - -def clear_cache(sandbox, node_id): - # Restart node to clear the store's cache - sandbox.node(node_id).terminate_or_kill() - sandbox.node(node_id).run() - assert sandbox.client(node_id).check_node_listening() - - -@pytest.mark.multinode -@pytest.mark.incremental -@pytest.mark.snapshot -@pytest.mark.slow -class TestMultiNodeStorageReconstruction: - def test_init(self, sandbox: Sandbox): - sandbox.add_node(0, params=PARAMS) - parameters = protocol.get_parameters() - parameters['consensus_threshold'] = 0 - protocol.activate( - sandbox.client(0), parameters=parameters, activate_in_the_past=True - ) - # Keep node 3 in the dance - # History mode by default (full) - sandbox.add_node(3, params=PARAMS) - - # Node 0 bakes a few blocks - def test_bake_node0_level_a(self, sandbox: Sandbox, session: dict): - for _ in range(BATCH_1): - utils.bake(sandbox.client(0)) - session['head_hash'] = sandbox.client(0).get_head()['hash'] - session['head_level'] = sandbox.client(0).get_head()['header']['level'] - - # Node 3 tries to reconstruct its storage after the first batch. - # Reconstruct is expected to fail: nothing to reconstruct - def test_reconstruct_on_bootstrapped_node(self, sandbox: Sandbox): - # Stop, reconstruct the storage and restart the node - sandbox.node(3).terminate_or_kill() - pattern = 'nothing to reconstruct.' - with utils.assert_run_failure(pattern): - sandbox.node(3).reconstruct() - sandbox.node(3).run() - assert sandbox.client(3).check_node_listening() - - # Node 0 exports a snapshot - def test_export_snapshot_batch1(self, sandbox: Sandbox, session: dict): - node_export = sandbox.node(0) - session['snapshot_1_head_hash'] = session['head_hash'] - session['snapshot_1_head_level'] = session['head_level'] - file = f'{sandbox.node(0).node_dir}/{SNAPSHOT_1}' - export_level = session['head_level'] - assert export_level == (BATCH_1 + 1) - node_export.snapshot_export(file, params=['--block', f'{export_level}']) - - # Node 1 import and reconstruct (using the `--reconstruct` - # flag of the `snapshot import` command) - def test_node1_import_and_reconstruct( - self, sandbox: Sandbox, session: dict - ): - n0_tmpdir = sandbox.node(0).node_dir - file = f'{n0_tmpdir}/{SNAPSHOT_1}' - sandbox.add_node( - 1, - snapshot=file, - reconstruct=True, - params=PARAMS + ['--history-mode', 'archive'], - ) - assert utils.check_level(sandbox.client(1), session['head_level']) - clear_cache(sandbox, 1) - - # Test that all the reconstructed blocks can be requested - # with their metadata - def test_node1_request_all_blocks_with_metadata( - self, sandbox: Sandbox, session: dict - ): - for i in range(session['head_level']): - assert utils.get_block_at_level(sandbox.client(1), i) - - # Node 2 import and then reconstruct using the dedicated command. - def test_import_before_reconstruct(self, sandbox: Sandbox, session: dict): - n0_tmpdir = sandbox.node(0).node_dir - file = f'{n0_tmpdir}/{SNAPSHOT_1}' - sandbox.add_node(2, snapshot=file) - assert utils.check_level(sandbox.client(2), session['head_level']) - - # Checking node's 2 storage - def test_unavailable_blocks_node2(self, sandbox: Sandbox, session: dict): - # We must fail while requesting those pruned blocks - for i in range(1, session['snapshot_1_head_level'] - 1): - utils.get_block_metadata_at_level( - sandbox.client(2), i, expect_failure=True - ) - - # Call the reconstruct command on Node 2 - def test_reconstruct_after_snapshot_import(self, sandbox: Sandbox): - # Stop, reconstruct the storage and restart the node - sandbox.node(2).terminate_or_kill() - sandbox.node(2).reconstruct() - sandbox.node(2).run() - assert sandbox.client(2).check_node_listening() - - # Test that all the reconstructed blocks can be requested - # with their metadata - def test_available_blocks_node_2(self, sandbox: Sandbox, session: dict): - # We should now success requesting those reconstructed blocks - for i in range(session['head_level']): - assert utils.get_block_at_level(sandbox.client(2), i) - - # Second batch - - # Bake a few blocks - def test_bake_node0_level_b(self, sandbox: Sandbox, session: dict): - for _ in range(BATCH_2 - BATCH_1): - utils.bake(sandbox.client(0)) - session['head_hash'] = sandbox.client(0).get_head()['hash'] - session['head_level'] = sandbox.client(0).get_head()['header']['level'] - assert utils.check_level(sandbox.client(0), session['head_level']) - assert utils.check_level(sandbox.client(1), session['head_level']) - assert utils.check_level(sandbox.client(2), session['head_level']) - - # Node 0 exports a snapshot (with no floating to reconstruct) - def test_export_snapshot_batch2(self, sandbox: Sandbox, session: dict): - node_export = sandbox.node(0) - # to export on a cemented cycle - export_block_level = 64 - export_block = utils.get_block_at_level( - sandbox.client(0), export_block_level - ) - export_block_hash = export_block['hash'] - session['snapshot_2_head_hash'] = export_block_hash - session['snapshot_2_head_level'] = export_block_level - file = f'{sandbox.node(0).node_dir}/{SNAPSHOT_2}' - node_export.snapshot_export( - file, params=['--block', f'{export_block_level}'] - ) - - # Check that node 3 (full bootstrapped) can be reconstructed - def test_sync_node3(self, sandbox: Sandbox, session: dict): - assert utils.check_level(sandbox.client(3), session['head_level']) - clear_cache(sandbox, 3) - - # Checking node's 3 storage - def test_unavailable_blocks_node3(self, sandbox: Sandbox): - savepoint = int(sandbox.client(3).get_savepoint()) - assert utils.get_block_at_level(sandbox.client(3), savepoint) - # We must fail while requesting blocks before savepoint - for i in range(1, savepoint): - utils.get_block_metadata_at_level( - sandbox.client(3), i, expect_failure=True - ) - - def test_reconstruct_command_after_bootstrap(self, sandbox: Sandbox): - # Stop, reconstruct the storage and restart the node - sandbox.node(3).terminate_or_kill() - sandbox.node(3).reconstruct() - # History mode is now archive - sandbox.node(3).run() - assert sandbox.client(3).check_node_listening() - - def test_available_blocks_node3(self, sandbox: Sandbox, session: dict): - assert sandbox.client(3).get_savepoint() == 0 - assert sandbox.client(3).get_caboose() == 0 - # We should now success requesting those reconstructed blocks - for i in range(session['head_level']): - assert utils.get_block_at_level(sandbox.client(3), i) diff --git a/tests_python/tests_012/test_multiple_transfers.py b/tests_python/tests_012/test_multiple_transfers.py deleted file mode 100644 index 468147f64c20..000000000000 --- a/tests_python/tests_012/test_multiple_transfers.py +++ /dev/null @@ -1,133 +0,0 @@ -"""Test the multiple transfer feature of tezos-client""" -import os -import json -import pytest - -from client.client import Client -from tools import utils -from tools.constants import IDENTITIES -from .contract_paths import CONTRACT_PATH - - -def manager(client: Client) -> str: - """Originate and return the alias of a manager contract""" - alias = 'manager' - path = os.path.join(CONTRACT_PATH, 'entrypoints', alias + '.tz') - pubkey = IDENTITIES['bootstrap2']['identity'] - utils.init_with_transfer( - client, path, f'"{pubkey}"', 1000, sender='bootstrap1' - ) - return alias - - -@pytest.fixture(scope="class") -def big_map_entrypoints(client: Client) -> str: - """Originate and return the alias of a big_map_entrypoints contract""" - alias = 'big_map_entrypoints' - path = os.path.join(CONTRACT_PATH, 'entrypoints', alias + '.tz') - utils.init_with_transfer( - client, path, 'Pair {} {Elt "Hello" 42}', 1000, sender='bootstrap1' - ) - return alias - - -@pytest.fixture -def source(client: Client, request) -> str: - """A contract alias that will be used as source for a multiple transfers - command. - - This fixture is indirectly instantiated: the argument specifies - whether the alias of an originated manager contract should be - returned (if argument equals 'manager'). Otherwise, the alias is - assumed to already exist in the client's wallet and is returned - unmodified. - """ - alias = request.param - return manager(client) if alias == 'manager' else alias - - -@pytest.mark.contract -@pytest.mark.incremental -class TestMultipleTransfers: - def test_empty(self, client: Client): - with utils.assert_run_failure(r'Empty operation list'): - json_obj = '[]' - client.run(client.cmd_batch('bootstrap1', json_obj)) - - @pytest.mark.parametrize( - "payer, source", - [('bootstrap2', 'manager'), ('bootstrap4', 'bootstrap4')], - indirect=["source"], - ) - def test_transfer_json_to_entrypoint_with_args( - self, big_map_entrypoints: str, client: Client, payer: str, source: str - ): - """Test the multiple transfers command with a single transfer - to a contract's entrypoint, with implicit accounts or a manager - contract as source as per parametrization. - """ - balance_source = client.get_mutez_balance(source) - balance_payer = client.get_mutez_balance(payer) - fee = 0.0123 - fee_mutez = utils.mutez_of_tez(fee) - json_obj = [ - { - "destination": big_map_entrypoints, - "amount": "0", - "fee": str(fee), - "gas-limit": "65942", - "storage-limit": "1024", - "arg": '"Hello"', - "entrypoint": "mem_right", - } - ] - json_ops = json.dumps(json_obj, separators=(',', ':')) - client.run(client.cmd_batch(source, json_ops)) - utils.bake(client, 'bootstrap5') - new_balance_source = client.get_mutez_balance(source) - new_balance_payer = client.get_mutez_balance(payer) - - if payer != source: - assert balance_source == new_balance_source - - assert balance_payer - fee_mutez == new_balance_payer - - @pytest.mark.parametrize( - "payer, source", - [('bootstrap2', 'manager'), ('bootstrap4', 'bootstrap4')], - ) - def test_multiple_transfers(self, client: Client, payer: str, source: str): - """Test a multiple transfers to implicit accounts, with implicit - accounts or a manager contract as source as per parametrization. - """ - balance_source = client.get_mutez_balance(source) - balance_bootstrap1 = client.get_mutez_balance('bootstrap1') - balance_bootstrap3 = client.get_mutez_balance('bootstrap3') - amount_1 = 10.1 - amount_mutez_1 = utils.mutez_of_tez(amount_1) - amount_3 = 11.01 - amount_mutez_3 = utils.mutez_of_tez(amount_3) - json_obj = [ - {"destination": "bootstrap1", "amount": str(amount_1)}, - {"destination": "bootstrap3", "amount": str(amount_3)}, - ] - json_ops = json.dumps(json_obj, separators=(',', ':')) - client.run(client.cmd_batch(source, json_ops)) - utils.bake(client, 'bootstrap5') - new_balance_source = client.get_mutez_balance(source) - new_balance_bootstrap1 = client.get_mutez_balance('bootstrap1') - new_balance_bootstrap3 = client.get_mutez_balance('bootstrap3') - - if payer == source: - fee_first_transfer = 404 - fee_second_transfer = 308 - source_fee_mutez = fee_first_transfer + fee_second_transfer - else: - source_fee_mutez = 0 - - assert ( - balance_source - amount_mutez_1 - amount_mutez_3 - source_fee_mutez - == new_balance_source - ) - assert balance_bootstrap1 + amount_mutez_1 == new_balance_bootstrap1 - assert balance_bootstrap3 + amount_mutez_3 == new_balance_bootstrap3 diff --git a/tests_python/tests_012/test_multisig.py b/tests_python/tests_012/test_multisig.py deleted file mode 100644 index 06108327a82c..000000000000 --- a/tests_python/tests_012/test_multisig.py +++ /dev/null @@ -1,620 +0,0 @@ -# tezos-client has builtin support for multisig smart contracts. See -# docs/user/multisig.rst for more details about it. - -# This file tests the client multisig support; more precisely it tests -# that both the generic and the legacy versions of the multisig smart -# contract behave as intended. For all commands, we check that we can -# interact with the multisig contract when invoking it by its address -# or by its alias. - -import os -import re -from typing import List -import pytest -from tools import utils, constants -from client.client import Client -from .contract_paths import MINI_SCENARIOS_CONTRACT_PATH, ATTIC_CONTRACT_PATH - - -def get_keys(client): - """Generate 3 pairs of keys using various schemes and return the list - of aliases.""" - keys = ['foo', 'bar', 'boo'] - sigs = [None, 'secp256k1', 'ed25519'] - for key, sig in zip(keys, sigs): - args = [] if sig is None else ['--sig', sig] - client.gen_key(key, args) - return keys - - -@pytest.fixture(scope="class") -def keys(client): - return get_keys(client) - - -def msig_path(msig_version: str) -> str: - return os.path.join( - MINI_SCENARIOS_CONTRACT_PATH, f'{msig_version}_multisig.tz' - ) - - -MSIG_PARAMS = [ - {'by_address': by_address, 'msig_version': msig_version} - for msig_version in ['generic', 'legacy'] - for by_address in [True, False] -] - - -def parse_msig_storage(storage: str): - """Parse the storage of a multisig contract to get its counter (as a - number), threshold (as a number), and the keys of the signers (as - Micheline sequence in a string).""" - # put everything on a single line - storage = ' '.join(storage.split('\n')) - storage_regexp = r'Pair\s+?([0-9]+)\s+?([0-9]+)\s+?(.*)\s*' - match = re.search(storage_regexp, storage) - assert match is not None - return { - 'counter': int(match[1]), - 'threshold': int(match[2]), - 'keys': match[3], - } - - -def resolve_key_alias(client: Client, alias: str) -> str: - """Convert a key alias into a public key that can be understood in - Michelson.""" - ret = client.show_address(alias).public_key - assert ret is not None - return ret - - -def build_michelson_key_list(client: Client, keys: List[str]): - """From a list of key aliases, build a Michelson list of public keys.""" - keys = [resolve_key_alias(client, k) for k in keys] - return '{"' + '"; "'.join(keys) + '"}' - - -def build_msig_storage( - client: Client, counter: int, threshold: int, keys: List[str] -): - """Build a multisig storage from its components: a counter, a - threshold and the list of signer public keys.""" - keys = build_michelson_key_list(client, keys) - return f'Pair {counter} {threshold} {keys}' - - -def assert_michelson_eq(client, data1, data2, typ): - """Check that two Michelson expressions of the same type are equal by - normalizing them.""" - normalized1 = client.normalize(data=data1, typ=typ) - normalized2 = client.normalize(data=data2, typ=typ) - assert normalized1 == normalized2 - - -def assert_msig_storage_eq(client, data1, data2): - """Check that two multisig storages are equal.""" - assert_michelson_eq(client, data1, data2, 'pair nat nat (list key)') - - -def assert_msig_counter_incr(current_storage, new_storage): - """Check that [new_storage] is the same multisig storage than - [current_storage] except that it uses the next counter.""" - current_storage = parse_msig_storage(current_storage) - new_storage = parse_msig_storage(new_storage) - assert new_storage['counter'] == 1 + current_storage['counter'] - assert new_storage['threshold'] == current_storage['threshold'] - assert new_storage['keys'] == current_storage['keys'] - - -@pytest.fixture(scope="class", params=MSIG_PARAMS) -def msig(client: Client, keys, request): - """This fixture originates a multisig contract with a threshold of 2 - and the keys given as parameter. The version of the script is given by - the msig_version parameter, it can be either 'generic' or - 'legacy'. This fixture returns a dictionary containing: - - - a [handle] that can be used to interact with the contract: - either the address of the script or an alias, depending on the - [by_address] parameter - - - the list of [keys] that are stored in the contract which is a - copy of the [keys] parameter - - - the [version], which is a copy of the [msig_version] parameter - - """ - - # We use the same alias for all multisig originations, this makes - # testing simpler but requires using the '--force' option. - msig_alias = 'msig' - msig_version = request.param['msig_version'] - by_address = request.param['by_address'] - initial_storage = build_msig_storage( - client=client, counter=0, threshold=2, keys=keys - ) - deployment = client.originate( - msig_alias, - 100, - 'bootstrap1', - msig_path(msig_version), - # Initialize with empty key list and null threshold - ['--init', initial_storage, '--burn-cap', '100', '--force'], - ) - utils.bake(client) - handle = deployment.contract if by_address else msig_alias - return {'handle': handle, 'keys': keys, 'version': msig_version} - - -@pytest.mark.incremental -class TestMultisig: - def test_deploy_multisig(self, msig, client: Client): - """Test that: - - the script originated by the "deploy multisig" command, - - the generic_multisig.tz script found in the mini_scenarios - directory, and - - the script printed by the "show multisig script" - are the same.""" - keys = msig['keys'] - - # The command cannot originate the legacy contract so there is - # nothing to test in the legacy case. - if msig['version'] == 'generic': - client.deploy_msig( - 'dummy_msig', - 100, - 'bootstrap1', - 2, - keys, - ['--burn-cap', '100', '--force'], - ) - utils.bake(client) - expected_hash = ( - 'exprub9UzpxmhedNQnsv1J1DazWGJnj1dLhtG1fxkUoWSdFLBGLqJ4' - ) - assert expected_hash in client.run( - ['show', 'supported', 'multisig', 'hashes'] - ) - assert client.get_script_hash(msig['handle']) == expected_hash - assert client.get_script_hash('dummy_msig') == expected_hash - assert client.hash_script( - [client.run(['show', 'multisig', 'script'])] - ) == [(expected_hash, None)] - assert client.get_balance('dummy_msig') == 100 - - def test_transfer(self, msig, client: Client, session: dict): - """Test the client command for signing a multisig transfer from key - number 0 and store the signature in the session.""" - keys = msig['keys'] - key = keys[0] - session['sig0'] = client.msig_sign_transfer( - msig['handle'], 10, 'bootstrap2', key - ) - - def test_prepare_msig_transfer(self, msig, client: Client): - """Test the client command for preparing a transfer. The result of the - command is ignored in this test, we only test that the command - succeeds.""" - client.msig_prepare_transfer(msig['handle'], 10, 'bootstrap2') - - def test_prepare_msig_sign(self, msig, client: Client, session: dict): - """Produce signatures for keys number 1 and 2 using the the - preparation command together with the sign_bytes client command. The - signatures are stored in the session.""" - to_sign = client.msig_prepare_transfer( - msig['handle'], 10, 'bootstrap2', ['--bytes-only'] - ) - session['sig1'] = client.sign_bytes_of_string(to_sign, msig['keys'][1]) - session['sig2'] = client.sign_bytes_of_string(to_sign, msig['keys'][2]) - - def test_transfer_failure(self, msig, client: Client, session: dict): - """Test transfer failure when there are too few signatures.""" - error_pattern = ( - r"Not enough signatures: " - + r"only 1 signatures were given " - + r"but the threshold is currently 2" - ) - - with utils.assert_run_failure(error_pattern): - client.msig_transfer( - msig['handle'], - 10, - 'bootstrap2', - 'bootstrap1', - [session['sig2']], - ) - - def test_transfer_success(self, msig, client: Client, session: dict): - """Test a successful transfer using signatures obtained by different - methods. The signatures are taken from the session.""" - current_storage = client.get_storage(msig['handle']) - current_balance = client.get_balance(msig['handle']) - - client.msig_transfer( - msig['handle'], - 10, - 'bootstrap2', - 'bootstrap1', - [session['sig0'], session['sig2']], - ) - utils.bake(client) - new_storage = client.get_storage(msig['handle']) - assert_msig_counter_incr(current_storage, new_storage) - new_balance = client.get_balance(msig['handle']) - assert new_balance == current_balance - 10 - - def test_default_entrypoint(self, msig, client): - """The generic multisig contract features an unauthorized default - entrypoint to receive donations but the legacy one does not.""" - - def cmd(): - client.transfer( - amount=100, giver='bootstrap1', receiver=msig['handle'] - ) - - if msig['version'] == 'legacy': - error_pattern = r'Invalid argument passed to contract' - with utils.assert_run_failure(error_pattern): - cmd() - else: - current_storage = client.get_storage(msig['handle']) - current_balance = client.get_balance(msig['handle']) - cmd() - utils.bake(client) - new_storage = client.get_storage(msig['handle']) - new_balance = client.get_balance(msig['handle']) - assert new_storage == current_storage - assert new_balance == current_balance + 100 - - def test_transfer_with_entrypoint(self, msig, client: Client): - """Both versions of the contract can call arbitrary entrypoints of - type unit. This test uses the two possible methods to produce the - signatures.""" - current_storage = client.get_storage(msig['handle']) - current_balance = client.get_balance(msig['handle']) - contract = ( - 'parameter (or (unit %a) (string %b)); ' - 'storage unit; ' - 'code {CDR; NIL operation; PAIR}' - ) - client.originate( - 'dest_entrypoint', - 0, - 'bootstrap1', - contract, - args=['--burn-cap', '10.0', '--force'], - ) - args = ['--entrypoint', 'a'] - utils.bake(client) - to_sign = client.msig_prepare_transfer( - msig_name=msig['handle'], - amount=10, - dest='dest_entrypoint', - args=args + ['--bytes-only'], - ) - sig0 = client.sign_bytes_of_string(to_sign, msig['keys'][0]) - sig2 = client.msig_sign_transfer( - msig_name=msig['handle'], - amount=10, - dest='dest_entrypoint', - secret_key=msig['keys'][2], - args=args, - ) - client.msig_transfer( - msig_name=msig['handle'], - amount=10, - dest='dest_entrypoint', - src='bootstrap1', - signatures=[sig0, sig2], - args=args, - ) - utils.bake(client) - new_storage = client.get_storage(msig['handle']) - new_balance = client.get_balance(msig['handle']) - assert_msig_counter_incr(current_storage, new_storage) - assert new_balance == current_balance - 10 - - def test_transfer_with_arg(self, msig, client: Client): - """The generic multisig contract can call other contracts with - arbitrary parameters but the legacy one can only send Unit.""" - contract = ( - 'parameter (or (int %a) (string %b)); ' - 'storage unit; ' - 'code {CDR; NIL operation; PAIR}' - ) - client.originate( - 'dest', - 0, - 'bootstrap1', - contract, - args=['--burn-cap', '10.0', '--force'], - ) - args = ['--entrypoint', 'a', '--arg', '42'] - utils.bake(client) - - def cmd(): - return client.msig_prepare_transfer( - msig_name=msig['handle'], - amount=10, - dest='dest', - args=args + ['--bytes-only'], - ) - - if msig['version'] == 'legacy': - error_pattern = ( - r'This multisig contract can only transfer tokens to' - ' contracts of type unit; calling a contract with argument 42' - ' is not supported.' - ) - with utils.assert_run_failure(error_pattern): - cmd() - else: - current_storage = client.get_storage(msig['handle']) - current_balance = client.get_balance(msig['handle']) - to_sign = cmd() - utils.bake(client) - sig0 = client.sign_bytes_of_string(to_sign, msig['keys'][0]) - sig2 = client.msig_sign_transfer( - msig_name=msig['handle'], - amount=10, - dest='dest', - secret_key=msig['keys'][2], - args=args, - ) - client.msig_transfer( - msig_name=msig['handle'], - amount=10, - dest='dest', - src='bootstrap1', - signatures=[sig0, sig2], - args=args, - ) - utils.bake(client) - new_storage = client.get_storage(msig['handle']) - new_balance = client.get_balance(msig['handle']) - assert_msig_counter_incr(current_storage, new_storage) - assert new_balance == current_balance - 10 - - def test_transfer_ill_typed(self, msig, client: Client): - """Test that the multisig transfer preparation command type checks the - parameter.""" - error_pattern = ( - ( - r'The entrypoint b of contract .* ' - 'called from a multisig contract is of type string; ' - 'the provided parameter 42 is ill-typed.' - ) - if msig['version'] == 'generic' - else ( - r'This multisig contract can only transfer tokens to' - ' contracts of type unit; calling a contract with argument 42' - ' is not supported.' - ) - ) - - args = ['--entrypoint', 'b', '--arg', '42'] - - def cmd(): - client.msig_prepare_transfer( - msig_name=msig['handle'], - amount=10, - dest='dest', - args=args + ['--bytes-only'], - ) - - with utils.assert_run_failure(error_pattern): - cmd() - - def test_transfer_too_high(self, msig, client: Client): - """Test that the multisig transfer preparation command checks the - balance.""" - expected_warning = ( - 'Transferred amount is bigger than current multisig balance' - ) - - client.msig_prepare_transfer( - msig_name=msig['handle'], - amount=1000, - dest='bootstrap1', - args=['--bytes-only'], - expected_warning=expected_warning, - ) - - def test_multiple_operations(self, msig, client: Client): - """The generic multisig client can run lambdas, this can be used to - atomically run several operations.""" - bootstrap1_address = constants.IDENTITIES['bootstrap1']['identity'] - bootstrap2_address = constants.IDENTITIES['bootstrap2']['identity'] - bootstrap3_address = constants.IDENTITIES['bootstrap3']['identity'] - lam = ( - '{ DROP; NIL operation; ' - f'PUSH key_hash "{bootstrap1_address}"; IMPLICIT_ACCOUNT; ' - 'PUSH mutez 1000000; UNIT; TRANSFER_TOKENS; CONS; ' - f'PUSH key_hash "{bootstrap2_address}"; IMPLICIT_ACCOUNT; ' - 'PUSH mutez 2000000; UNIT; TRANSFER_TOKENS; CONS; ' - f'PUSH key_hash "{bootstrap3_address}"; SOME; ' - 'SET_DELEGATE; CONS}' - ) - lam = client.normalize( - lam, typ='lambda unit (list operation)', mode='Optimized' - ) - - def cmd(): - return client.msig_prepare_lambda( - msig_name=msig['handle'], lam=lam, args=['--bytes-only'] - ) - - if msig['version'] == 'legacy': - error_pattern = 'This multisig contract has a fixed set of actions' - with utils.assert_run_failure(error_pattern): - cmd() - else: - current_storage = client.get_storage(msig['handle']) - current_balance = client.get_balance(msig['handle']) - to_sign = cmd() - sig0 = client.sign_bytes_of_string(to_sign, msig['keys'][0]) - sig2 = client.msig_sign_lambda( - msig_name=msig['handle'], lam=lam, secret_key=msig['keys'][2] - ) - client.msig_run_lambda( - msig_name=msig['handle'], - lam=lam, - src='bootstrap1', - signatures=[sig0, sig2], - ) - utils.bake(client) - new_storage = client.get_storage(msig['handle']) - new_balance = client.get_balance(msig['handle']) - assert_msig_counter_incr(current_storage, new_storage) - assert new_balance == current_balance - 3 - # TODO: check the delegate change - - def test_multiple_operations_failure(self, msig, client: Client): - """Test for the error message for ill-typed lambdas.""" - lam = '{ DROP }' - - def cmd(): - client.msig_prepare_lambda( - msig_name=msig['handle'], lam=lam, args=['--bytes-only'] - ) - - error_pattern = ( - ( - r'The provided lambda .* for multisig contract' - r' is ill-typed; .* is expected.' - ) - if msig['version'] == 'generic' - else 'This multisig contract has a fixed set of actions' - ) - - with utils.assert_run_failure(error_pattern): - cmd() - - def test_delegate_change(self, msig, client: Client): - """Test the multisig command for changing delegate.""" - current_storage = client.get_storage(msig['handle']) - current_balance = client.get_balance(msig['handle']) - sig0 = client.msig_sign_set_delegate( - msig['handle'], 'bootstrap5', msig['keys'][0] - ) - to_sign = client.msig_prepare_set_delegate( - msig['handle'], 'bootstrap5', ['--bytes-only'] - ) - sig2 = client.sign_bytes_of_string(to_sign, msig['keys'][2]) - client.msig_set_delegate( - msig['handle'], 'bootstrap5', 'bootstrap1', [sig0, sig2] - ) - utils.bake(client) - new_storage = client.get_storage(msig['handle']) - new_balance = client.get_balance(msig['handle']) - assert_msig_counter_incr(current_storage, new_storage) - assert new_balance == current_balance - - def test_delegate_withdraw(self, msig, client: Client): - """Test the multisig command for removing delegation.""" - current_storage = client.get_storage(msig['handle']) - current_balance = client.get_balance(msig['handle']) - sig0 = client.msig_sign_withdrawing_delegate( - msig['handle'], msig['keys'][0] - ) - to_sign = client.msig_prepare_withdrawing_delegate( - msig['handle'], ['--bytes-only'] - ) - - sig1 = client.sign_bytes_of_string(to_sign, msig['keys'][1]) - client.msig_withdrawing_delegate( - msig['handle'], 'bootstrap1', [sig0, sig1] - ) - utils.bake(client) - new_storage = client.get_storage(msig['handle']) - new_balance = client.get_balance(msig['handle']) - assert_msig_counter_incr(current_storage, new_storage) - assert new_balance == current_balance - - def test_run_transaction_change_keys_and_threshold( - self, msig, client: Client - ): - """Test changing the keys and threshold with the `run transaction` - command.""" - current_storage = client.get_storage(msig['handle']) - current_counter = parse_msig_storage(storage=current_storage)['counter'] - current_balance = client.get_balance(msig['handle']) - keys = msig['keys'] - sig0 = client.msig_sign_setting_threshold( - msig['handle'], keys[0], 2, [keys[0], keys[2]] - ) - to_sign = client.msig_prepare_setting_threshold( - msig['handle'], 2, [keys[0], keys[2]], ['--bytes-only'] - ) - sig2 = client.sign_bytes_of_string(to_sign, msig['keys'][2]) - client.msig_run_transaction( - msig['handle'], to_sign, 'bootstrap1', [sig0, sig2] - ) - utils.bake(client) - new_storage = client.get_storage(msig['handle']) - expected_counter = 1 + current_counter - expected_storage = build_msig_storage( - client=client, - counter=expected_counter, - threshold=2, - keys=[keys[0], keys[2]], - ) - assert_msig_storage_eq(client, new_storage, expected_storage) - new_balance = client.get_balance(msig['handle']) - assert new_balance == current_balance - - def test_change_keys_and_threshold(self, msig, client: Client): - """Test changing the keys and threshold with `set threshold of - multisig` command.""" - current_storage = client.get_storage(msig['handle']) - current_counter = parse_msig_storage(storage=current_storage)['counter'] - current_balance = client.get_balance(msig['handle']) - keys = msig['keys'] - new_keys = [keys[0], keys[2]] - sig0 = client.msig_sign_setting_threshold( - msig['handle'], keys[0], 2, new_keys - ) - to_sign = client.msig_prepare_setting_threshold( - msig['handle'], 2, new_keys, ['--bytes-only'] - ) - sig2 = client.sign_bytes_of_string(to_sign, msig['keys'][2]) - client.msig_set_threshold( - msig['handle'], 2, new_keys, 'bootstrap1', [sig0, sig2] - ) - utils.bake(client) - new_storage = client.get_storage(msig['handle']) - expected_counter = 1 + current_counter - expected_storage = build_msig_storage( - client=client, - counter=expected_counter, - threshold=2, - keys=[keys[0], keys[2]], - ) - assert_msig_storage_eq(client, new_storage, expected_storage) - new_balance = client.get_balance(msig['handle']) - assert new_balance == current_balance - - -class TestUnsupportedMultisig: - """Verify that non-multisig contracts are rejected""" - - def test_deploy_nonmultisig(self, client: Client): - contract = os.path.join(ATTIC_CONTRACT_PATH, 'id.tz') - client.originate( - 'id', - 0, - 'bootstrap1', - contract, - args=['--burn-cap', '10.0', '--force', '--init', '""'], - ) - utils.bake(client) - - error_pattern = ( - 'The hash of this script is ' - 'exprv8K6ceBpFH5SFjQm4BRYSLJCHQBFeQU6BFTdvQSRPaPkzdLyAL, ' - 'it was not found among in the list of known multisig ' - 'script hashes.' - ) - - with utils.assert_run_failure(error_pattern): - client.msig_transfer('id', 10, 'bootstrap2', 'bootstrap1', []) diff --git a/tests_python/tests_012/test_nonce_seed_revelation.py b/tests_python/tests_012/test_nonce_seed_revelation.py deleted file mode 100644 index 6a0f8506ac21..000000000000 --- a/tests_python/tests_012/test_nonce_seed_revelation.py +++ /dev/null @@ -1,133 +0,0 @@ -import time -import pytest -from tools import constants -from launchers.sandbox import Sandbox -from . import protocol - - -BLOCKS_PER_COMMITMENT = protocol.PARAMETERS['blocks_per_commitment'] -BLOCKS_PER_CYCLE = protocol.PARAMETERS['blocks_per_cycle'] -FIRST_PROTOCOL_BLOCK = 1 -TIMEOUT = 60 - -MINIMAL_BLOCK_DELAY = 1 -DELAY_INCREMENT_PER_ROUND = 1 -TEST_DURATION = ( - FIRST_PROTOCOL_BLOCK + 2 * BLOCKS_PER_CYCLE -) * MINIMAL_BLOCK_DELAY -NUM_NODES = 5 - - -@pytest.mark.incremental -@pytest.mark.slow -@pytest.mark.baker -class TestNonceSeedRevelation: - """Test baker injection of nonce revelations. - - See http://tezos.gitlab.io/012_ithaca/proof_of_stake.html - - Runs a node and a baker. The baker bakes two full cycles. - We collect nonce hashes from the first cycle. And check - that they are revealed in the second cycle""" - - def test_init(self, sandbox: Sandbox): - """Run a node and a baker. - - The node runs in archive mode to get metadata in `client.get_block()`. - The protocol is activated in the past so the baker can submit blocks - immediately without waiting for current time.""" - - node_params = constants.NODE_PARAMS + ['--history-mode', 'archive'] - for i in range(NUM_NODES): - sandbox.add_node(i, params=node_params) - - # client setup - parameters = protocol.get_parameters() - parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) - parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) - protocol.activate(sandbox.client(0), parameters=parameters) - - # baker setup - # delegated_accounts = [f'bootstrap{i}' for i in range(1, 6)] - for i in range(NUM_NODES): - sandbox.add_baker( - i, - [f"bootstrap{i + 1}"], - proto=protocol.DAEMON, - log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, - ) - - @pytest.mark.timeout(2 * TEST_DURATION) - def test_wait_for_two_cycles(self, sandbox: Sandbox): - """Poll the node until target level is reached """ - target = FIRST_PROTOCOL_BLOCK + 2 * BLOCKS_PER_CYCLE - level = target - 1 - while level < target: - time.sleep( - 4 * MINIMAL_BLOCK_DELAY - ) # sleep first to avoid useless first query - if sandbox.client(0).get_level() >= target: - break - # No need to bake more - for i in range(NUM_NODES): - sandbox.rm_baker(i, proto=protocol.DAEMON) - - def test_get_all_blocks(self, sandbox: Sandbox, session: dict): - """Retrieve all blocks for two full cycles. """ - blocks = [ - sandbox.client(0).get_block(FIRST_PROTOCOL_BLOCK + i) - for i in range(2 * BLOCKS_PER_CYCLE) - ] - session['blocks'] = blocks - - def test_cycle_alignment(self, session): - """Test cycles start where they are supposed to start. - - Not really needed but helps clarifying cycles positions.""" - - blocks = session['blocks'] - # blocks[0] is considered cycle = 0, cycle_position = 0 for the new - # protocol, but because it is a protocol transition block, it - # doesn't have the "cycle" and "cycle_position" metadata (unlike - # the remaining blocks) - initial_block_level = blocks[1]['metadata']['level_info'] - assert initial_block_level['cycle'] == 0 - assert initial_block_level['cycle_position'] == 1 - final_block_level = blocks[BLOCKS_PER_CYCLE]['metadata']['level_info'] - assert final_block_level['cycle'] == 1 - assert final_block_level['cycle_position'] == 0 - - def test_collect_seed_nonce_hashes(self, session): - """Collect nonce hashes in the block headers in the first cycle """ - seed_nonce_hashes = {} - blocks = session['blocks'] - for i in range(BLOCKS_PER_CYCLE // BLOCKS_PER_COMMITMENT): - level = (i + 1) * BLOCKS_PER_COMMITMENT - 1 - seed_nonce_hash = blocks[level]['header']['seed_nonce_hash'] - seed_nonce_hashes[level] = seed_nonce_hash - session['seed_nonce_hashes'] = seed_nonce_hashes - - def test_check_revelations(self, session): - """Collect reveal ops in second cycle and check they match - the nonce hashes from first cycle.""" - blocks = session['blocks'] - seed_nonce_hashes = session['seed_nonce_hashes'] - ops = [] - # collect all operations - for i in range(BLOCKS_PER_CYCLE, 2 * BLOCKS_PER_CYCLE): - ops.extend(blocks[i]['operations'][2]) - reveal_ops = {} - for operation in ops: - content = operation['contents'][0] - # there should be only revelations there - assert content['kind'] == "seed_nonce_revelation" - level = content['level'] - FIRST_PROTOCOL_BLOCK - # Can't submit twice the same reveal op - assert level not in reveal_ops - # level should match a seed - assert level in seed_nonce_hashes - reveal_ops[level] = content['nonce'] - - # check all nonce hashes have been revealed - assert len(reveal_ops) == len(seed_nonce_hashes) - # we could go a step further and check that revelations are correct diff --git a/tests_python/tests_012/test_openapi.py b/tests_python/tests_012/test_openapi.py deleted file mode 100644 index 9348d2302b31..000000000000 --- a/tests_python/tests_012/test_openapi.py +++ /dev/null @@ -1,73 +0,0 @@ -""" Tests generating the implementation of openapi/swagger: - https://swagger.io/ - - This script launches a sandbox node, activates folder specific - protocol, gets the RPC descriptions as JSON, and converts this JSON - into an OpenAPI specification. - - This test mimicks src/openapi/generate.sh. -""" - -import json -import subprocess -from pathlib import Path -import requests -import openapi_spec_validator -import pytest - -from launchers.sandbox import Sandbox -from tools.constants import NODE_PARAMS -from . import protocol - - -def _get_tezos_node_version() -> str: - cmd = ["ocaml", "../scripts/print_version.ml"] - process_ret = subprocess.run( - cmd, check=True, capture_output=True, text=True - ) - version = process_ret.stdout.strip() - assert version, "version should not be empty" - return version - - -class TestOpenAPI: - @pytest.fixture(scope="class") - def sandbox(self, sandbox: Sandbox): - sandbox.add_node(0, params=NODE_PARAMS) - client = sandbox.client(0) - protocol.activate(client) - return sandbox - - @pytest.mark.parametrize( - "rpc_path", ["describe", "describe/chains/main/blocks/head/"] - ) - def test_validity(self, sandbox: Sandbox, rpc_path: str, tmp_path: Path): - """ - Mimicks the script src/openapi/generate.sh. Generates the API - and check it generates a valid OpenAPI specification. - """ - node = sandbox.node(0) - addr = f"http://localhost:{node.rpc_port}/{rpc_path}?recurse=yes" - json_path = tmp_path / "result.json" - with open(json_path, "w") as o_file: - json_res = requests.get(addr).json() - json.dump(json_res, o_file) - - # If you need to debug, insert time.sleep(15) in there, - # to give you time to inspect generated files before the - # enclosing 'with' block finishes or to execute the dune - # command manually while the temporary files are still there. - version = _get_tezos_node_version() - cmd = [ - "dune", - "exec", - "../src/bin_openapi/rpc_openapi.exe", - "--", - version, - str(json_path.absolute()), - ] - process_ret = subprocess.run( - cmd, check=True, capture_output=True, text=True - ) - res = json.loads(process_ret.stdout) - openapi_spec_validator.validate_spec(res) diff --git a/tests_python/tests_012/test_p2p.py b/tests_python/tests_012/test_p2p.py deleted file mode 100644 index f4d54953ce5b..000000000000 --- a/tests_python/tests_012/test_p2p.py +++ /dev/null @@ -1,147 +0,0 @@ -import time -import pytest -from tools import constants -from launchers.sandbox import Sandbox - - -NUM_NODES = 5 -NUM_RETRIES = 20 # empirical values for testing a liveness property -POLLING_TIME = 10 # NUM_RETRY * POLLING_TIME = 200s, should be conservative - - -@pytest.mark.multinode -@pytest.mark.incremental -class TestTrustedRing: - """This test sets up a network of public peers (running the default - p2p protocol), with no initial bootstrap peers. It initializes a - trusted ring relationship, and checks that points are advertised - correctly to the whole network.""" - - def test_init(self, sandbox: Sandbox): - for i in range(NUM_NODES): - sandbox.add_node( - i, - private=False, - peers=[], - params=constants.NODE_PARAMS, - config_client=False, - ) - - def test_no_peers(self, sandbox: Sandbox): - """ Initially, nobody knows other peers. """ - for client in sandbox.all_clients(): - res = client.p2p_stat() - assert not res.peers - - def test_add_peers(self, sandbox: Sandbox): - """ Set up a trusted ring topology. """ - base_p2p = sandbox.p2p - for i in range(NUM_NODES): - client = sandbox.client(i) - client.trust_peer(base_p2p + ((i + 1) % NUM_NODES)) - - def test_check_clique(self, sandbox: Sandbox): - """Everyone should be connected to everyone else. This is a - liveness property. Its realization depends on the timing of the - p2p maintenance process. The check is repeated up to NUM_RETRIES - times with a POLLING_TIME seconds wait.""" - for i in range(NUM_NODES): - client = sandbox.client(i) - for _ in range(NUM_RETRIES): - points = client.p2p_stat().points.values() - num_connected = len( - [point for point in points if point.is_connected] - ) - if num_connected == NUM_NODES - 1: - break - time.sleep(POLLING_TIME) - assert num_connected == NUM_NODES - 1 - - def test_check_tables(self, sandbox: Sandbox): - """Test various assumptions on the point/peer tables. - Each peer has exactly one trusted neighbor. Tables don't - contain their own peer/point id and contain exactly NUM_NODES - 1 - values. - - The previous test should guarantee that maintenance has been - performed when this test is run.""" - base_p2p = sandbox.p2p - for i in range(NUM_NODES): - client = sandbox.client(i) - point_id = f'127.0.0.1:{base_p2p + i}' - peer_id = client.rpc('get', '/network/self') - res = client.p2p_stat() - assert peer_id not in res.peers - assert point_id not in res.points - num_trusted = 0 - for point_id, point in res.points.items(): - num_trusted += point.is_trusted - assert num_trusted == 1 - assert len(res.peers) == NUM_NODES - 1 - assert len(res.points) == NUM_NODES - 1 - - def test_set_expected_peers(self, sandbox: Sandbox): - """For all nodes, we add one expected peer_id - for the successor node.""" - peers_id = {} - for i in range(NUM_NODES): - client = sandbox.client(i) - peers_id[i] = client.rpc('get', '/network/self') - - for i in range(NUM_NODES): - client = sandbox.client(i) - client.set_expected_peer_id( - sandbox.p2p + ((i + 1) % NUM_NODES), - peers_id[(i + 1) % NUM_NODES], - ) - - def test_expected_peers(self, sandbox: Sandbox): - """For all nodes, we check that expected peer_id was - set properly.""" - peers_id = {} - for i in range(NUM_NODES): - client = sandbox.client(i) - peers_id[i] = client.rpc('get', '/network/self') - - for i in range(NUM_NODES): - client = sandbox.client(i) - expected_id = client.get_expected_peer_id( - sandbox.p2p + ((i + 1) % NUM_NODES) - ) - assert expected_id == peers_id[(i + 1) % NUM_NODES] - - def test_wrong_expected_peer(self, sandbox: Sandbox): - """We change the expected peer_id set previously to a wrong - expected peer_id.""" - peers_id = {} - for i in range(NUM_NODES): - client = sandbox.client(i) - peers_id[i] = client.rpc('get', '/network/self') - - for i in range(NUM_NODES): - client = sandbox.client(i) - client.set_expected_peer_id( - sandbox.p2p + ((i + 2) % NUM_NODES), peers_id[i] - ) - - def test_check_stat_with_wrong_expected_peers(self, sandbox: Sandbox): - """All nodes are public, everyone should be connected. But - only one neighbor should be trusted.""" - base_p2p = sandbox.p2p - for i in range(NUM_NODES): - client = sandbox.client(i) - point_id = '127.0.0.1:' + str(base_p2p + i) - peer_id = client.rpc('get', '/network/self') - res = client.p2p_stat() - assert peer_id not in res.peers - assert point_id not in res.points - num_trusted = 0 - num_connected = 0 - for point_id, point in res.points.items(): - num_trusted += point.is_trusted - num_connected += point.is_connected - assert len(res.peers) == NUM_NODES - 1 - assert len(res.points) == NUM_NODES - 1 - assert num_trusted == 1 - # We lost two connections - assert num_connected == NUM_NODES - 1 - 2 diff --git a/tests_python/tests_012/test_per_block_votes.py b/tests_python/tests_012/test_per_block_votes.py deleted file mode 100644 index 5bf3b73bac3b..000000000000 --- a/tests_python/tests_012/test_per_block_votes.py +++ /dev/null @@ -1,131 +0,0 @@ -import time - -from typing import Optional, Iterator - -import pytest - -from launchers.sandbox import Sandbox -from tools import utils, constants, paths - -from . import protocol - -MINIMAL_BLOCK_DELAY = 2 -SLEEP = 2 * MINIMAL_BLOCK_DELAY - - -def run_vote_file(sandbox: Sandbox, filename: str) -> None: - sandbox.rm_baker(0, proto=protocol.DAEMON) - sandbox.add_baker( - 0, - [f'bootstrap{i}' for i in range(1, 6)], - proto=protocol.DAEMON, - run_params=["--votefile", filename], - ) - if not sandbox.log_dir: - pytest.skip() - time.sleep(SLEEP) - assert sandbox.logs - - -def run_vote_file_test(sandbox: Sandbox, filename: str) -> None: - run_vote_file(sandbox, filename) - assert utils.check_logs( - sandbox.logs, - ( - r'The provided block vote file path ' - f'"{filename}" does not point to an existing file.' - '|' - r'The provided block vote file path ' - f'"{filename}" does not point to a valid JSON file.' - '|' - r'The provided block vote file ' - f'"{filename}" is a valid JSON file but its content is unexpected.' - ), - ) - - -def run_vote_file_test_error( - sandbox: Sandbox, filename: str, error_pattern: str -) -> None: - run_vote_file(sandbox, filename) - assert not utils.check_logs(sandbox.logs, error_pattern) - - -def run_nonexistent_file_test(sandbox, filename): - error_pattern = ( - r'The provided block vote file path ' - f'"{filename}" does not point to an existing file.' - ) - run_vote_file_test_error(sandbox, filename, error_pattern) - - -def run_invalid_file_test(sandbox, filename): - error_pattern = ( - r'The provided block vote file path ' - f'"{filename}" does not point to a valid JSON file.' - ) - run_vote_file_test_error(sandbox, filename, error_pattern) - - -def run_wrong_content_file_test(sandbox, filename): - error_pattern = ( - r'The provided block vote file ' - f'"{filename}" is a valid JSON file but its content is unexpected.' - ) - run_vote_file_test_error(sandbox, filename, error_pattern) - - -@pytest.fixture(scope="class") -def sandbox(log_dir: Optional[str], singleprocess: bool) -> Iterator[Sandbox]: - """Sandboxed network of nodes where daemons are allowed to fail. - - Nodes, bakers and endorsers are added/removed dynamically.""" - # log_dir is None if not provided on command-line - # singleprocess is false if not provided on command-line - with Sandbox( - paths.TEZOS_HOME, - constants.IDENTITIES, - log_dir=log_dir, - singleprocess=singleprocess, - ) as sandbox: - yield sandbox - - -class TestAllPerBlockVotes: - def test_setup_network(self, sandbox: Sandbox): - sandbox.add_node(0, params=constants.NODE_PARAMS) - parameters = protocol.get_parameters() - parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) - parameters['delay_increment_per_round'] = "1" - protocol.activate(sandbox.client(0), parameters=parameters) - sandbox.add_baker(0, ['bootstrap1'], proto=protocol.DAEMON) - - def test_wait_for_protocol(self, sandbox: Sandbox): - clients = sandbox.all_clients() - for client in clients: - proto = protocol.HASH - assert utils.check_protocol(client, proto) - - def test_true_vote_file(self, sandbox: Sandbox): - filename = "tests_012/per_block_vote_files/true.json" - run_vote_file_test(sandbox, filename) - - def test_false_vote_file(self, sandbox: Sandbox): - filename = "tests_012/per_block_vote_files/false.json" - run_vote_file_test(sandbox, filename) - - def test_nonexistent_vote_file(self, sandbox: Sandbox): - filename = "tests_012/per_block_vote_files/nonexistant.json" - run_nonexistent_file_test(sandbox, filename) - - def test_invalid_json(self, sandbox: Sandbox): - filename = "tests_012/per_block_vote_files/invalid.json" - run_invalid_file_test(sandbox, filename) - - def test_nonboolean(self, sandbox: Sandbox): - filename = "tests_012/per_block_vote_files/non_boolean.json" - run_wrong_content_file_test(sandbox, filename) - - def test_wrong_key(self, sandbox: Sandbox): - filename = "tests_012/per_block_vote_files/wrong_key.json" - run_wrong_content_file_test(sandbox, filename) diff --git a/tests_python/tests_012/test_programs.py b/tests_python/tests_012/test_programs.py deleted file mode 100644 index 184f8a17c817..000000000000 --- a/tests_python/tests_012/test_programs.py +++ /dev/null @@ -1,97 +0,0 @@ -import itertools -from client.client import Client - -CONVERT_INPUT_FORMATS = ["michelson", "json", "binary"] -CONVERT_OUTPUT_FORMATS = ["michelson", "json", "binary", "ocaml"] -CONVERT_SCRIPT = { - "michelson": """{ parameter unit ; - storage unit ; - code { CDR ; - NIL operation ; - SELF ; - PUSH mutez 0 ; - UNIT ; - TRANSFER_TOKENS ; - DUP ; - DIP { CONS } ; - CONS ; - PAIR } }""", - "json": """[ { "prim": "parameter", "args": [ { "prim": "unit" } ] }, - { "prim": "storage", "args": [ { "prim": "unit" } ] }, - { "prim": "code", - "args": - [ [ { "prim": "CDR" }, - { "prim": "NIL", "args": [ { "prim": "operation" } ] }, - { "prim": "SELF" }, - { "prim": "PUSH", "args": [ { "prim": "mutez" }, { "int": "0" } ] }, - { "prim": "UNIT" }, { "prim": "TRANSFER_TOKENS" }, - { "prim": "DUP" }, - { "prim": "DIP", "args": [ [ { "prim": "CONS" } ] ] }, - { "prim": "CONS" }, { "prim": "PAIR" } ] ] } ]""", - "binary": "0x02000000300500036c0501036c050202000000210317053d036d03490743036a0000034f034d0321051f0200000002031b031b0342", # pylint: disable=line-too-long # noqa: E501 - "ocaml": "Seq (0, [Prim (1, K_parameter, [Prim (2, T_unit, [], [])], []); Prim (3, K_storage, [Prim (4, T_unit, [], [])], []); Prim (5, K_code, [Seq (6, [Prim (7, I_CDR, [], []); Prim (8, I_NIL, [Prim (9, T_operation, [], [])], []); Prim (10, I_SELF, [], []); Prim (11, I_PUSH, [Prim (12, T_mutez, [], []); Int (13, Z.zero)], []); Prim (14, I_UNIT, [], []); Prim (15, I_TRANSFER_TOKENS, [], []); Prim (16, I_DUP, [], []); Prim (17, I_DIP, [Seq (18, [Prim (19, I_CONS, [], [])])], []); Prim (20, I_CONS, [], []); Prim (21, I_PAIR, [], [])])], [])])", # pylint: disable=line-too-long # noqa: E501 -} -CONVERT_DATA = { - "michelson": """{ DROP ; - PUSH address "tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU" ; - CONTRACT unit ; - { IF_NONE { { UNIT ; FAILWITH } } {} } ; - PUSH mutez 1 ; - UNIT ; - TRANSFER_TOKENS ; - DIP { NIL operation } ; - CONS }""", - "json": """[ { "prim": "DROP" }, - { "prim": "PUSH", - "args": - [ { "prim": "address" }, - { "string": "tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU" } ] }, - { "prim": "CONTRACT", "args": [ { "prim": "unit" } ] }, - [ { "prim": "IF_NONE", - "args": [ [ [ { "prim": "UNIT" }, { "prim": "FAILWITH" } ] ], [] ] } ], - { "prim": "PUSH", "args": [ { "prim": "mutez" }, { "int": "1" } ] }, - { "prim": "UNIT" }, { "prim": "TRANSFER_TOKENS" }, - { "prim": "DIP", - "args": [ [ { "prim": "NIL", "args": [ { "prim": "operation" } ] } ] ] }, - { "prim": "CONS" } ]""", - "binary": "0x020000006403200743036e0100000024747a31666173774354446369527a45346f4a396a6e32566d3264766a6579413966557a550555036c0200000015072f02000000090200000004034f032702000000000743036a0001034f034d051f0200000004053d036d031b", # pylint: disable=line-too-long # noqa: E501 - "ocaml": "Seq (0, [Prim (1, I_DROP, [], []); Prim (2, I_PUSH, [Prim (3, T_address, [], []); String (4, \"tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU\")], []); Prim (5, I_CONTRACT, [Prim (6, T_unit, [], [])], []); Seq (7, [Prim (8, I_IF_NONE, [Seq (9, [Seq (10, [Prim (11, I_UNIT, [], []); Prim (12, I_FAILWITH, [], [])])]); Seq (13, [])], [])]); Prim (14, I_PUSH, [Prim (15, T_mutez, [], []); Int (16, Z.one)], []); Prim (17, I_UNIT, [], []); Prim (18, I_TRANSFER_TOKENS, [], []); Prim (19, I_DIP, [Seq (20, [Prim (21, I_NIL, [Prim (22, T_operation, [], [])], [])])], []); Prim (23, I_CONS, [], [])])", # pylint: disable=line-too-long # noqa: E501 - "type": "lambda unit (list operation)", -} - - -class TestProgramsCommands: - def test_convert_script(self, client: Client): - for (input_, output) in itertools.product( - CONVERT_INPUT_FORMATS, CONVERT_OUTPUT_FORMATS - ): - result = client.run( - [ - "convert", - "script", - CONVERT_SCRIPT[input_], - "from", - input_, - "to", - output, - ] - ) - assert result.strip() == f"{CONVERT_SCRIPT[output]}" - - def test_convert_data(self, client: Client): - for (input_, output, typecheck) in itertools.product( - CONVERT_INPUT_FORMATS, CONVERT_OUTPUT_FORMATS, [True, False] - ): - args = [ - "convert", - "data", - CONVERT_DATA[input_], - "from", - input_, - "to", - output, - ] - if typecheck: - args += ["--type", CONVERT_DATA["type"]] - result = client.run(args) - assert result.strip() == f"{CONVERT_DATA[output]}" diff --git a/tests_python/tests_012/test_proto_demo_counter.py b/tests_python/tests_012/test_proto_demo_counter.py deleted file mode 100644 index 12c2c7bb5e68..000000000000 --- a/tests_python/tests_012/test_proto_demo_counter.py +++ /dev/null @@ -1,88 +0,0 @@ -import time -import pytest -from tools import constants -from tools.constants import PROTO_DEMO_COUNTER, PROTO_GENESIS -from client.client import Client - -PARAMS = ['-p', PROTO_GENESIS] - - -@pytest.fixture(scope="class") -def client(sandbox): - """One node with genesis.""" - sandbox.add_node(0, params=constants.NODE_PARAMS) - client = sandbox.client(0) - yield client - - -@pytest.mark.incremental -class TestProtoDemo: - """Activate protocol demo_counter, inject operations and bake block. - - This test relies on the fixture client which launches a single - sandboxed node. - """ - - def test_proto_known(self, client: Client): - res = client.list_protocols() - assert PROTO_DEMO_COUNTER in res - - def test_proto_client_known(self, client: Client): - res = client.list_understood_protocols() - assert PROTO_DEMO_COUNTER[:12] in res - - def test_first_protocol(self, client: Client): - proto = 'PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i' - assert client.get_protocol() == proto - - def test_activate_proto(self, client: Client): - parameters = {'init_a': 100, 'init_b': 100} - res = client.activate_protocol_json( - PROTO_DEMO_COUNTER, parameters, key='activator', fitness='1' - ) - assert res.block_hash - - def test_level1(self, client: Client): - assert client.get_level() == 1 - - def test_protocol_genesis(self, client: Client): - assert client.get_protocol() == PROTO_GENESIS - - def test_bake_command(self, client: Client): - time.sleep(1) - client.run(['bake', 'This is block 2']) - - def test_level2(self, client: Client): - head = client.rpc('get', '/chains/main/blocks/head/') - assert head['header']['level'] == 2 - - def test_inject_operations(self, client: Client): - client.run(['increment', 'a']) - client.run(['increment', 'b']) - client.run(['transfer', '10']) - - def test_mempool(self, client: Client): - ops = client.get_mempool() - assert len(ops['applied']) == 3 - - def test_bake_command_2(self, client: Client): - time.sleep(1) - client.run(['bake', 'This is block 3']) - - def test_level3(self, client: Client): - head = client.rpc('get', '/chains/main/blocks/head/') - assert head['header']['level'] == 3 - - def test_rpc_counter_a(self, client: Client): - head = client.rpc('get', '/chains/main/blocks/head/counter/a') - assert head == 91 - - def test_rpc_counter_b(self, client: Client): - head = client.rpc('get', '/chains/main/blocks/head/counter/b') - assert head == 111 - - def test_get_counter_commands(self, client: Client): - message_a = client.run(['get', 'a']) - assert message_a == "The counter value is 91\n" - message_b = client.run(['get', 'b']) - assert message_b == "The counter value is 111\n" diff --git a/tests_python/tests_012/test_proto_demo_noops_manual_bake.py b/tests_python/tests_012/test_proto_demo_noops_manual_bake.py deleted file mode 100644 index 215f2ed99f1e..000000000000 --- a/tests_python/tests_012/test_proto_demo_noops_manual_bake.py +++ /dev/null @@ -1,97 +0,0 @@ -import time -import pytest -from tools.constants import PROTO_DEMO_NOOPS, PROTO_GENESIS -from client.client import Client - -PARAMS = ['-p', PROTO_GENESIS] - - -@pytest.fixture(scope="class") -def client(sandbox): - """One node with genesis.""" - sandbox.add_node(0) - client = sandbox.client(0) - yield client - - -def forge_block_header_data(protocol_data): - """ - Returns a binary encoding for a dict of the form - `{'block_header_data: string}`, as expected by the protocol. - - This corresponds to the encoding given by - `data_encoding.(obj1 (req "block_header_data" string))`. See - `lib_data_encoding/data_encoding.mli` for the spec. - """ - assert len(protocol_data) == 1 and 'block_header_data' in protocol_data - string = protocol_data['block_header_data'] - tag = '0000' - padded_hex_len = f'{len(string):#06x}'[2:] - return tag + padded_hex_len + bytes(string, 'utf-8').hex() - - -@pytest.mark.incremental -class TestProtoDemo: - """Activate protocol demo_noops, injection some operations and bake block. - - This test relies on the fixture client which launches a single - sandboxed node. - """ - - def test_proto_known(self, client: Client): - res = client.list_protocols() - assert PROTO_DEMO_NOOPS in res - - def test_first_protocol(self, client: Client): - proto = 'PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i' - assert client.get_protocol() == proto - - def test_activate_proto(self, client: Client): - parameters = {} # type: dict - res = client.activate_protocol_json( - PROTO_DEMO_NOOPS, parameters, key='activator', fitness='1' - ) - assert res.block_hash - - def test_level1(self, client: Client): - assert client.get_level(params=PARAMS) == 1 - - def test_protocol_genesis(self, client: Client): - assert client.get_protocol(params=PARAMS) == PROTO_GENESIS - - def test_manual_bake(self, client: Client): - time.sleep(1) - message = "hello world" - - data = { - "protocol_data": { - "protocol": PROTO_DEMO_NOOPS, - "block_header_data": message, - }, - "operations": [], - } - block = client.rpc( - 'post', - '/chains/main/blocks/head/helpers/preapply/block', - data=data, - params=PARAMS, - ) - - protocol_data = {'block_header_data': message} - encoded = forge_block_header_data(protocol_data) - - shell_header = block['shell_header'] - shell_header['protocol_data'] = encoded - encoded = client.rpc( - 'post', - '/chains/main/blocks/head/helpers/forge_block_header', - data=shell_header, - params=PARAMS, - ) - - inject = {'data': encoded['block'], 'operations': []} - client.rpc('post', '/injection/block', data=inject, params=PARAMS) - - def test_level2(self, client: Client): - head = client.rpc('get', '/chains/main/blocks/head/', params=PARAMS) - assert head['header']['level'] == 2 diff --git a/tests_python/tests_012/test_rpc.py b/tests_python/tests_012/test_rpc.py deleted file mode 100644 index 2a32d6ec010d..000000000000 --- a/tests_python/tests_012/test_rpc.py +++ /dev/null @@ -1,639 +0,0 @@ -import os -import time -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox -from . import protocol -from . import contract_paths - -CHAIN_ID = "main" -BLOCK_ID = "head" -PKH = "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" -PROTOCOL_HASH = protocol.HASH -BLOCK_LEVEL = "3" -LIST_OFFSET = "0" -OPERATION_OFFSET = "0" - - -@pytest.fixture(scope="class") -def session(): - session = {} - session["implicit_accounts"] = [ - "tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN", - "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv", - "tz1b7tUupMgCNw2cCLpKTkSD1NZzB5TkP2sv", - "tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU", - "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx", - ] - return session - - -@pytest.fixture(scope="class") -def contract_name(): - return "contract_identity" - - -@pytest.fixture(scope="class", params=[None, "proxy"]) -def sandbox(request, sandbox: Sandbox, contract_name, session: dict): - """Adds two nodes to sandbox. Using the first node, originates the - identity contract `id.tz` with the name contract_name and makes it - address available under session['originated_accounts']. - """ - sandbox.add_node(1, params=constants.NODE_PARAMS, mode=request.param) - sandbox.add_node(2, params=constants.NODE_PARAMS, mode=request.param) - client = sandbox.client(1) - parameters = protocol.get_parameters() - parameters['consensus_threshold'] = 0 - protocol.activate( - sandbox.client(1), activate_in_the_past=True, parameters=parameters - ) - - utils.bake(client) - time.sleep(2) - # Deploy a contract - contract = os.path.join(contract_paths.CONTRACT_PATH, 'attic', 'id.tz') - args = ['--init', "\"tezos\"", '--burn-cap', '10.0'] - origination = client.originate( - contract_name, 10.0, "bootstrap1", contract, args - ) - session['originated_accounts'] = [origination.contract] - utils.bake(client) - assert utils.check_block_contains_operations( - client, [origination.operation_hash] - ) - return sandbox - - -@pytest.mark.incremental -@pytest.mark.mempool -@pytest.mark.multinode -@pytest.mark.slow -class TestRPCsExistence: - """ - Tests the existence of RPCs. It does not check the output! - Existence relying on the storage are tested using bootstrap - accounts/originated contracts. - """ - - block_hash = "" - - def test_config_file(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/config') - - def test_network_self(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/network/self') - - def test_constants(self, sandbox: Sandbox): - sandbox.client(2).rpc('get', '/network/self') - utils.bake(sandbox.client(1)) - time.sleep(3) - - def test_chain_blocks(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', f'/chains/{CHAIN_ID}/blocks') - - def test_chain_chain_id(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', f'/chains/{CHAIN_ID}/chain_id') - - def test_chain_invalid_blocks(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', f'/chains/{CHAIN_ID}/invalid_blocks') - - def test_errors(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/errors') - - def test_fetch_protocol_protocol_hash(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', f'/fetch_protocol/{PROTOCOL_HASH}') - - def test_network_connections(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/network/connections') - - def test_network_connections_peer_id(self, sandbox: Sandbox): - peer_id = sandbox.client(2).rpc('get', '/network/self') - sandbox.client(1).rpc('get', f'/network/connections/{peer_id}') - - def test_network_greylist_clear(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/network/greylist/clear') - - def test_network_peers(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/network/peers') - - def test_network_peers_peer_id(self, sandbox: Sandbox): - peer_id = sandbox.client(2).rpc('get', '/network/self') - sandbox.client(1).rpc('get', f'/network/peers/{peer_id}') - - def test_network_peers_peer_id_ban(self, sandbox: Sandbox): - peer_id = sandbox.client(2).rpc('get', '/network/self') - sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/ban') - - def test_network_peers_peer_id_banned(self, sandbox: Sandbox): - peer_id = sandbox.client(2).rpc('get', '/network/self') - sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/banned') - - def test_network_peers_peer_id_unban(self, sandbox: Sandbox): - peer_id = sandbox.client(2).rpc('get', '/network/self') - sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/unban') - - def test_network_peers_peer_id_untrust(self, sandbox: Sandbox): - peer_id = sandbox.client(2).rpc('get', '/network/self') - sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/untrust') - - def test_network_peers_peer_id_trust(self, sandbox: Sandbox): - peer_id = sandbox.client(2).rpc('get', '/network/self') - sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/trust') - - def test_network_points(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/network/points') - - def test_network_points_point(self, sandbox: Sandbox): - points = sandbox.client(1).rpc('get', '/network/points') - point = points[-1][0] - sandbox.client(1).rpc('get', f'/network/points/{point}') - - def test_network_points_point_ban(self, sandbox: Sandbox): - points = sandbox.client(1).rpc('get', '/network/points') - point = points[-1][0] - sandbox.client(1).rpc('get', f'/network/points/{point}/ban') - - def test_network_points_point_banned(self, sandbox: Sandbox): - points = sandbox.client(1).rpc('get', '/network/points') - point = points[-1][0] - sandbox.client(1).rpc('get', f'/network/points/{point}/banned') - - def test_network_points_point_trust(self, sandbox: Sandbox): - points = sandbox.client(1).rpc('get', '/network/points') - point = points[-1][0] - sandbox.client(1).rpc('get', f'/network/points/{point}/trust') - - def test_network_points_point_unban(self, sandbox: Sandbox): - points = sandbox.client(1).rpc('get', '/network/points') - point = points[-1][0] - sandbox.client(1).rpc('get', f'/network/points/{point}/unban') - - def test_network_points_point_untrust(self, sandbox: Sandbox): - points = sandbox.client(1).rpc('get', '/network/points') - point = points[-1][0] - sandbox.client(1).rpc('get', f'/network/points/{point}/untrust') - - def test_network_stat(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/network/stat') - - def test_network_version(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/network/version') - - def test_network_versions(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/network/versions') - - def test_protocols(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/protocols') - - def test_protocols_protocol_hash(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', f'/protocols/{PROTOCOL_HASH}') - - def test_workers_block_validator(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/workers/block_validator') - - def test_workers_chain_validators(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/workers/chain_validators') - - def test_workers_chain_validator(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', f'/workers/chain_validators/{CHAIN_ID}') - - def test_workers_chain_validator_ddb(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/workers/chain_validators/{CHAIN_ID}/ddb' - ) - - def test_workers_chain_validator_peers_validators(self, sandbox): - sandbox.client(1).rpc( - 'get', f'/workers/chain_validators/{CHAIN_ID}/' 'peers_validators' - ) - - def test_workers_prevalidators(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', '/workers/prevalidators') - - def test_workers_prevalidators_chain_id(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', f'/workers/prevalidators/{CHAIN_ID}') - - def test_chain_block(self, sandbox: Sandbox): - sandbox.client(1).rpc('get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}') - - def test_chain_block_context_constants(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/constants' - ) - - def test_chain_block_context_constants_errors(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/constants/errors', - ) - - def test_chain_block_context_contracts(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/contracts' - ) - - def test_chain_block_context_contract_id( - self, sandbox: Sandbox, session: dict - ): - accounts = session["originated_accounts"] + session["implicit_accounts"] - for contract_id in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/contracts/{contract_id}', - ) - - def test_chain_block_context_contract_balance( - self, sandbox: Sandbox, session: dict - ): - accounts = session["originated_accounts"] + session["implicit_accounts"] - for contract_id in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/contracts/{contract_id}/balance', - ) - - def test_chain_block_context_contract_counter( - self, sandbox: Sandbox, session: dict - ): - # only implicit contracts, see - # proto_012_Psithaca/lib_protocol/contract_repr.ml - for contract_id in session["implicit_accounts"]: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/contracts/{contract_id}/counter', - ) - - def test_chain_block_context_contract_delegate( - self, sandbox: Sandbox, session: dict - ): - for contract_id in session["implicit_accounts"]: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/contracts/{contract_id}/delegate', - ) - - def test_chain_block_context_contract_script_originated( - self, sandbox: Sandbox, session: dict - ): - # only originated contracts - accounts = session["originated_accounts"] - for contract_id in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/contracts/{contract_id}/script', - ) - - def test_chain_block_context_contract_script_implicit( - self, sandbox: Sandbox, session: dict - ): - accounts = session["implicit_accounts"] - for contract_id in accounts: - with utils.assert_run_failure('No service found at this URL'): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/contracts/{contract_id}/' - 'script', - ) - - def test_chain_block_context_contract_storage_originated( - self, sandbox: Sandbox, session: dict - ): - # only originated contracts - accounts = session["originated_accounts"] - for contract_id in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/contracts/{contract_id}/storage', - ) - - def test_chain_block_context_contract_storage_implicit( - self, sandbox: Sandbox, session: dict - ): - # only implicit contracts - accounts = session["implicit_accounts"] - for contract_id in accounts: - with utils.assert_run_failure('No service found at this URL'): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/contracts/{contract_id}/' - 'storage', - ) - - def test_chain_block_context_delegates(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/delegates' - ) - - def test_chain_block_context_delegate_implicit( - self, sandbox: Sandbox, session: dict - ): - # only implicit accounts - accounts = session["implicit_accounts"] - for pkh in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/delegates/{pkh}', - ) - - def test_chain_block_context_delegate_deactivated_implicit( - self, sandbox: Sandbox, session: dict - ): - # only implicit accounts - accounts = session["implicit_accounts"] - for pkh in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/delegates/{pkh}/deactivated', - ) - - def test_chain_block_context_delegate_delegated_balance_implicit( - self, sandbox: Sandbox, session: dict - ): - # only implicit accounts - accounts = session["implicit_accounts"] - for pkh in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/delegates/{pkh}/delegated_balance', - ) - - def test_chain_block_context_delegate_delegated_contracts_implicit( - self, sandbox: Sandbox, session: dict - ): - # only implicit accounts - accounts = session["implicit_accounts"] - for pkh in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/delegates/{pkh}/' - 'delegated_contracts', - ) - - def test_chain_block_context_delegate_frozen_deposits_implicit( - self, sandbox: Sandbox, session: dict - ): - # only implicit accounts - accounts = session["implicit_accounts"] - for pkh in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/delegates/{pkh}/' - 'frozen_deposits', - ) - - def test_chain_block_context_delegate_grace_period_implicit( - self, sandbox: Sandbox, session: dict - ): - # only implicit accounts - accounts = session["implicit_accounts"] - for pkh in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/delegates/{pkh}/grace_period', - ) - - def test_chain_block_context_delegate_staking_balance_implicit( - self, sandbox: Sandbox, session: dict - ): - # only implicit accounts - accounts = session["implicit_accounts"] - for pkh in accounts: - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/delegates/{pkh}/staking_balance', - ) - - def test_chain_block_context_nonces_block_level(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/nonces/{BLOCK_LEVEL}', - ) - - def test_chain_block_context_raw_bytes(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/raw/bytes' - ) - - def test_chain_block_hash(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/hash' - ) - - def test_chain_block_header(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header' - ) - - def test_chain_block_header_protocol_data(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header/protocol_data', - ) - - def test_chain_block_header_protocol_data_raw(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header/protocol_data/raw', - ) - - def test_chain_block_header_raw(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header/raw' - ) - - def test_chain_block_header_shell(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header/shell' - ) - - def test_chain_block_helpers_baking_rights(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'helpers/baking_rights', - ) - - def test_chain_block_helpers_complete_prefix1(self, sandbox: Sandbox): - prefix = PKH[:10] - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'helpers/complete/{prefix}', - ) - - def test_chain_block_helpers_complete_prefix2(self, sandbox: Sandbox): - res = utils.bake(sandbox.client(1)) - prefix = res.block_hash[:5] - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'helpers/complete/{prefix}', - ) - - def test_chain_block_helpers_current_level(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'helpers/current_level', - ) - - def test_chain_block_helpers_endorsing_rights(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'helpers/endorsing_rights', - ) - - def test_chain_block_helpers_levels_in_current_cycle( - self, sandbox: Sandbox - ): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - 'helpers/levels_in_current_cycle', - ) - - def test_chain_block_live_blocks(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'live_blocks' - ) - - def test_chain_block_metadata(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'metadata' - ) - - def test_chain_block_operation_hashes(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'operation_hashes' - ) - - def test_add_transactions(self, sandbox: Sandbox): - sandbox.client(1).transfer(1.000, 'bootstrap1', 'bootstrap2') - sandbox.client(2).transfer(1.000, 'bootstrap3', 'bootstrap4') - # FIXME: Use client.endorse - # Not clear where to put it w.r.t to Tenderbake, - # knowing that bake for does endorse - sandbox.client(1).run(["endorse", "for", 'bootstrap2', '--force']) - utils.bake(sandbox.client(1)) - time.sleep(3) - - def test_chain_block_operation_hashes_list_offset(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'operation_hashes/{LIST_OFFSET}', - ) - - def test_chain_block_operation_hashes_list_operation( - self, sandbox: Sandbox - ): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'operation_hashes/{LIST_OFFSET}/{OPERATION_OFFSET}', - ) - - def test_chain_block_operations(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'operations' - ) - - def test_chain_block_operations_list(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'operations/{LIST_OFFSET}', - ) - - def test_chain_block_operations_list_operation(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'operations/{LIST_OFFSET}/' - f'{OPERATION_OFFSET}', - ) - - def test_chain_block_votes_ballot_list(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' f'votes/ballot_list' - ) - - def test_chain_block_votes_ballots(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/ballots' - ) - - def test_chain_block_votes_current_period(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/current_period', - ) - - def test_chain_block_votes_current_proposal(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/current_proposal', - ) - - def test_chain_block_votes_current_quorum(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/current_quorum', - ) - - def test_chain_block_votes_listings(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/listings' - ) - - def test_chain_block_votes_proposals(self, sandbox: Sandbox): - sandbox.client(1).rpc( - 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/proposals' - ) - - def test_stat_gc(self, sandbox: Sandbox): - assert sandbox.client(1).rpc('get', "/stats/gc") - - def test_stat_memory(self, sandbox: Sandbox): - assert sandbox.client(1).rpc('get', "/stats/memory") - - -class TestDeprecatedRPCs: - def test_chain_block_context_contract_delegatable( - self, sandbox: Sandbox, session: dict - ): - for contract_id in session["implicit_accounts"]: - with utils.assert_run_failure(r"Did not find service"): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/' - f'{BLOCK_ID}/context/contracts/' - f'{contract_id}/delegatable', - ) - - def test_chain_block_context_contract_spendable( - self, sandbox: Sandbox, session: dict - ): - accounts = session["originated_accounts"] + session["implicit_accounts"] - for contract_id in accounts: - with utils.assert_run_failure(r"Did not find service"): - sandbox.client(1).rpc( - 'get', - f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' - f'context/contracts/{contract_id}/' - 'spendable', - ) diff --git a/tests_python/tests_012/test_sapling.py b/tests_python/tests_012/test_sapling.py deleted file mode 100644 index f8b6af4fb939..000000000000 --- a/tests_python/tests_012/test_sapling.py +++ /dev/null @@ -1,962 +0,0 @@ -import json -import re -from os import path -import pytest -from tools import utils, paths, constants -from tools.utils import assert_run_failure -from . import contract_paths -from . import protocol - -CONTRACT_PATH = path.join( - paths.TEZOS_HOME, 'src', protocol.FOLDER, 'lib_protocol', 'test' -) -TX_AMOUNT = 100.0 - - -# TODO: Use a random valid memo size for shielded-tez and others -@pytest.fixture -def contract_path(): - return CONTRACT_PATH - - -@pytest.fixture(scope="class") -def sandbox(sandbox): - sandbox.add_node(0, params=constants.NODE_PARAMS) - parameters = protocol.get_parameters() - parameters['consensus_threshold'] = 0 - protocol.activate( - sandbox.client(0), parameters=parameters, activate_in_the_past=True - ) - return sandbox - - -@pytest.fixture(scope="class") -def node(sandbox): - return sandbox.node(0) - - -@pytest.fixture(scope="class") -def client(sandbox, node): - client = sandbox.get_new_client(node) - return client - - -@pytest.fixture -def mnemonic(): - return [ - "morning", - "dinosaur", - "estate", - "youth", - "sausage", - "feature", - "apology", - "bullet", - "square", - "type", - "zoo", - "coyote", - "extra", - "fabric", - "grain", - "phone", - "pipe", - "despair", - "razor", - "ranch", - "blouse", - "debris", - "urge", - "evidence", - ] - - -@pytest.fixture -def non_originated_contract_address(): - return "KT1MXuZJJFg4EVpLQeLeuHvznTRiNefh3yCs" - - -@pytest.fixture -def non_originated_contract_name(): - return "fake-contract" - - -@pytest.fixture -def key_name(): - return "test_key_name" - - -# here baker 'account' has baked a block and has sent 'tx_amount' -def check_baker_balance(client, account, tx_amount): - parameters = dict(protocol.PARAMETERS) - initial_amount = float(parameters["bootstrap_accounts"][0][1]) - identity = constants.IDENTITIES[account]['identity'] - all_deposits = client.frozen_deposits(identity) - # sender's balance without fees - expected_baker_balance = ( - initial_amount / 1000000 - all_deposits / 1000000 - tx_amount - ) - baker_balance = client.get_balance(account) - # the fees are assumed to be at most 1 tez - fees_upper_bound = 3 - assert expected_baker_balance - fees_upper_bound <= baker_balance - assert baker_balance <= expected_baker_balance - - -@pytest.mark.client -class TestSaplingWalletImportKey: - @pytest.fixture - def client( - self, - sandbox, - node, - non_originated_contract_name, - non_originated_contract_address, - ): - """ - A client with a pre-registered contract to link the wallet with. - """ - client = sandbox.get_new_client(node) - client.remember_contract( - non_originated_contract_name, non_originated_contract_address - ) - return client - - def test_import_key_no_force(self, client, mnemonic, key_name): - """ - Import key without forcing and without pre-existing alias - """ - client.sapling_import_key(key_name, mnemonic, force=False) - - def test_import_key_force_and_non_previously_saved( - self, - client, - mnemonic, - key_name, - ): - """ - Import key with forcing and without pre-existing alias - """ - client.sapling_import_key(key_name, mnemonic, force=True) - - def test_import_key_force_and_previously_saved( - self, - client, - mnemonic, - key_name, - ): - """ - Import key with forcing and with pre-existing alias - """ - client.sapling_import_key(key_name, mnemonic, force=False) - client.sapling_import_key(key_name, mnemonic, force=True) - - -class TestSaplingWalletAddressGeneration: - @pytest.fixture - def client(self, sandbox, node, key_name, mnemonic): - """ - A client with a sapling wallet - """ - client = sandbox.get_new_client(node) - client.sapling_import_key(key_name, mnemonic, force=False) - return client - - @pytest.mark.parametrize( - "expected_address,expected_index", - [ - ( - "zet13XtyU5Bkasoj1b19sy4DJc7U13XydbxLHqLUdf8Y5tarGb" - "HgFLgDrT6J6FYJoHGL3", - 0, - ) - ], - ) - def test_generate_first_address_of_key( - self, client, key_name, expected_address, expected_index - ): - result = client.sapling_gen_address(key_name) - assert result.index == expected_index - assert result.address == expected_address - - @pytest.mark.parametrize( - "requested_index,expected_address,expected_index", - [ - ( - 0, - "zet13XtyU5Bkasoj1b19sy4DJc7U13XydbxLHqLUdf8Y5tarGb" - "HgFLgDrT6J6FYJoHGL3", - 0, - ), - ( - 1, - "zet13mN26QV67FgPzMSzrigXjKZNMMtCubhi9L3kUePnFYdXqEj" - "c8pmjw1h2wC6NLZf5F", - 1, - ), - ( - 2, - "zet12hzbYRRKbWwKPY61FkjLg7CRWTcjooqeH7VH18fA6Vxnwy7" - "WyTrAEqBXmEdHp9woU", - 4, - ), - ( - 3, - "zet12hzbYRRKbWwKPY61FkjLg7CRWTcjooqeH7VH18fA6Vxnwy7" - "WyTrAEqBXmEdHp9woU", - 4, - ), - ( - 4, - "zet12hzbYRRKbWwKPY61FkjLg7CRWTcjooqeH7VH18fA6Vxnwy7" - "WyTrAEqBXmEdHp9woU", - 4, - ), - ( - 100, - "zet14LmgdAzVrTtQKpeuD3f2y7wFSjXTMEexNNuiEWhGimm25en" - "xkqmwmbdFsC4y6YmYx", - 100, - ), - ( - 143534, - "zet14EWNxZYoHJASHFpcCYSfTfQokWSMzdJeV5SfaGEPDtiYiDC" - "X5jz8QkMF5jZaK5F4k", - 143536, - ), - ( - 42, - "zet143WVQUmNodhSe4ytHL6gvtdXYhRp7bywDWASUFYUCMGAS71" - "juXT6AyWY89fjg3eZn", - 42, - ), - ( - 90870987456348, - "zet13CiUqFsVEr2LdMnyyUQNL3Nh74sa4LdU6V3oD3YfcizbwuF" - "tftPRYvRrB2zsVaEw1", - 90870987456348, - ), - ], - ) - def test_generate_address_with_address_index( - self, - client, - key_name, - expected_address, - expected_index, - requested_index, - ): - result = client.sapling_gen_address(key_name, index=requested_index) - assert result.index == expected_index - assert result.address == expected_address - - -@pytest.mark.client -@pytest.mark.contract -@pytest.mark.incremental -class TestSaplingShieldedTez: - """ - Tests involving sapling key management and shielded transactions using - the shielded tez example contract. - """ - - @pytest.fixture - def contract_path(self): - return path.join(CONTRACT_PATH, 'contracts', 'sapling_contract.tz') - - @pytest.fixture - def contract_name(self): - return "sapling" - - @pytest.fixture(scope="session") - def tmpdir(self, tmpdir_factory): - """ - Temporary directory. Forged transactions will be saved - in this directory. - FIXME/IMPROVEME: tmpdir_factory is a fixture provided by pytest. It is - session-scoped, then the fixture tmpdir must be session-scoped. - Would be nice to have a class-scoped fixture. - """ - tmpdir = tmpdir_factory.mktemp("sapling_transactions_shielded_tez") - return tmpdir - - def test_originate_sapling_contract( - self, contract_path, client, session, contract_name - ): - sender = "bootstrap1" - origination = client.originate( - contract_name=contract_name, - amount=0, - sender=sender, - contract=contract_path, - args=["--init", "{ }", "--burn-cap", "3.0"], - ) - session["contract_address"] = origination.contract - utils.bake(client, bake_for=sender) - assert utils.check_block_contains_operations( - client, - [origination.operation_hash], - ) - - def test_generate_bob(self, client, session, contract_name): - key_name = "bob" - result = client.sapling_gen_key(key_name=key_name) - client.sapling_use_key_for_contract( - key_name, contract_name, memo_size=8 - ) - session['bob_mnemonic'] = result.mnemonic - - def test_list_keys_bob(self, client): - keys = client.sapling_list_keys() - assert keys == ["bob"] - - def test_list_keys_with_alice_and_bob(self, client, contract_name): - """ - NB: another key (ali) is generated in the test, but the mnemonic - is not saved. - We add this test to verify the list keys command orders alphabetically - """ - key_name = "ali" - client.sapling_gen_key(key_name=key_name) - client.sapling_use_key_for_contract( - key_name=key_name, contract_name=contract_name - ) - keys = client.sapling_list_keys() - assert keys == ["ali", "bob"] - - def test_generate_bob_address_0(self, client, session): - result = client.sapling_gen_address( - key_name="bob", - ) - session['last_address_index'] = result.index - session['bob_address_0'] = result.address - - def test_generate_bob_address_1(self, client, session): - result = client.sapling_gen_address( - key_name="bob", - ) - assert result.index > session['last_address_index'] - session['bob_address_1'] = result.address - - def test_check_bob_balance(self, client, contract_name): - result = client.sapling_get_balance( - key_name="bob", - contract_name=contract_name, - ) - assert result.balance == 0 - - def test_shield_bob_address_0(self, client, session, contract_name): - client.sapling_shield( - amount=TX_AMOUNT, - src="bootstrap2", - dest=session['bob_address_0'], - contract=contract_name, - args=["--burn-cap", "3.0"], - ) - utils.bake(client, bake_for="bootstrap1") - check_baker_balance(client, "bootstrap2", TX_AMOUNT) - bob_balance = client.sapling_get_balance( - key_name="bob", contract_name=contract_name - ).balance - assert bob_balance == TX_AMOUNT - - def test_check_contract_balance_after_shielding( - self, client, contract_name - ): - assert client.get_balance(contract_name) == TX_AMOUNT - - def test_regenerate_bob_from_mnemonic(self, client, session): - # Overwrite the old 'bob' key with one restored from the mnemonic. - key_name = "bob" - client.sapling_import_key( - key_name=key_name, - mnemonic=session['bob_mnemonic'], - force=True, - ) - - def test_derive_alice(self, client, contract_name): - result = client.sapling_derive_key( - source_key_name='bob', - target_key_name='alice', - contract_name=contract_name, - index='0', - ) - assert result.path == '0/0' - - def test_derive_yves(self, client, contract_name): - result = client.sapling_derive_key( - source_key_name='bob', - target_key_name='yves', - contract_name=contract_name, - index='1', - ) - assert result.path == '0/1' - - def test_generate_alice_address_0(self, client, session): - result = client.sapling_gen_address( - key_name="alice", - ) - session['alice_address_0'] = result.address - - def test_alice_shields_money_insufficient_funds( - self, client, session, contract_name - ): - bootstrap3 = constants.IDENTITIES['bootstrap3']['identity'] - alice_balance = int(client.get_balance('bootstrap3')) - amount = 2 * alice_balance - with assert_run_failure( - r"Balance of contract {} too low \({}\) to spend {}".format( - bootstrap3, alice_balance, amount - ) - ): - client.sapling_shield( - amount=amount, - src="bootstrap3", - dest=session['alice_address_0'], - contract=contract_name, - args=["--burn-cap", "3.0"], - ) - - def test_alice_shields_money(self, client, session, contract_name): - client.sapling_shield( - amount=TX_AMOUNT, - src="bootstrap3", - dest=session['alice_address_0'], - contract=contract_name, - args=[ - "--burn-cap", - "3.0", - ], - ) - utils.bake(client, bake_for="bootstrap1") - check_baker_balance(client, "bootstrap3", TX_AMOUNT) - alice_balance = client.sapling_get_balance( - key_name="alice", contract_name=contract_name - ).balance - assert alice_balance == TX_AMOUNT - - @pytest.mark.parametrize( - "transaction_file,use_json", - [ - ("sapling_transaction.bin", False), - ("sapling_transaction.json", True), - ], - ) - def test_forge_alice_to_bob_insufficient_funds( - self, - client, - tmpdir, - contract_name, - session, - transaction_file, - use_json, - ): - transaction_file = f'{tmpdir}/{transaction_file}' - amount = 2100000000.0 - account = 'alice' - additional_args = [] - if use_json: - additional_args += ["--json"] - - with assert_run_failure( - r"Balance too low \({}\) to spend {}".format(100, int(amount)) - ): - client.sapling_forge_transaction( - amount=amount, - src=account, - dest=session['bob_address_1'], - contract=contract_name, - file=transaction_file, - args=additional_args, - ) - - def test_forge_alice_to_bob_address_0( - self, tmpdir, session, client, contract_name - ): - transaction_file = f'{tmpdir}/sapling_transaction0.bin' - client.sapling_forge_transaction( - amount=TX_AMOUNT, - src='alice', - dest=session['bob_address_0'], - contract=contract_name, - file=transaction_file, - ) - - def test_forge_alice_to_bob_address_1_binary_format( - self, tmpdir, session, client, contract_name - ): - transaction_file = f'{tmpdir}/sapling_transaction1.bin' - client.sapling_forge_transaction( - amount=50.0, - src='alice', - dest=session['bob_address_1'], - contract=contract_name, - file=transaction_file, - ) - - @pytest.mark.parametrize( - "key_name,expected_balance", [("alice", TX_AMOUNT), ("bob", TX_AMOUNT)] - ) - def test_check_sapling_balances_post_forge_binary_format( - self, client, contract_name, key_name, expected_balance - ): - result = client.sapling_get_balance( - key_name=key_name, - contract_name=contract_name, - ) - assert result.balance == expected_balance - - def test_submit_alice_to_bob_address_1_binary_format( - self, client, tmpdir, contract_name - ): - transaction_file = f'{tmpdir}/sapling_transaction1.bin' - additional_args = ["--burn-cap", "3.0"] - client.sapling_submit( - file=transaction_file, - fee_payer='bootstrap2', - contract=contract_name, - args=additional_args, - ) - utils.bake(client, bake_for="bootstrap2") - - @pytest.mark.parametrize( - "key_name,expected_balance", [("alice", 50.0), ("bob", 150.0)] - ) - def test_check_sapling_balances_after_successfull_transaction_in_binary( - self, client, contract_name, key_name, expected_balance - ): - balance = client.sapling_get_balance( - key_name=key_name, contract_name=contract_name - ).balance - assert balance == expected_balance - - def test_forge_alice_to_bob_address_1_json_format( - self, tmpdir, session, client, contract_name - ): - transaction_file = f'{tmpdir}/sapling_transaction1.json' - client.sapling_forge_transaction( - amount=50.0, - src='alice', - dest=session['bob_address_1'], - contract=contract_name, - file=transaction_file, - args=['--json'], - ) - # Try to load the file as JSON. Must not fail. - with open(transaction_file, "r") as file_descriptor: - json.load(file_descriptor) - - @pytest.mark.parametrize( - "key_name,expected_balance", [("alice", 50.0), ("bob", 150.0)] - ) - def test_check_sapling_balances_post_forge_json_format( - self, client, contract_name, key_name, expected_balance - ): - result = client.sapling_get_balance( - key_name=key_name, - contract_name=contract_name, - ) - assert result.balance == expected_balance - - def test_submit_alice_to_bob_address_1_json_format( - self, client, tmpdir, contract_name - ): - transaction_file = f'{tmpdir}/sapling_transaction1.json' - additional_args = ["--burn-cap", "3.0", "--json"] - client.sapling_submit( - file=transaction_file, - fee_payer='bootstrap2', - contract=contract_name, - args=additional_args, - ) - utils.bake(client, bake_for="bootstrap2") - - @pytest.mark.parametrize( - "key_name,expected_balance", [("alice", 0.0), ("bob", 200.0)] - ) - def test_check_sapling_balances_after_successfull_transaction_in_json( - self, client, contract_name, key_name, expected_balance - ): - balance = client.sapling_get_balance( - key_name=key_name, contract_name=contract_name - ).balance - assert balance == expected_balance - - @pytest.mark.parametrize( - "transaction_file,use_json", - [ - ("sapling_transaction0.bin", False), - # ("sapling_transaction0.json", True), - ], - ) - def test_submit_alice_to_bob0( - self, client, transaction_file, use_json, tmpdir, contract_name - ): - transaction_file = f'{tmpdir}/{transaction_file}' - additional_args = ["--burn-cap", "3.0"] - if use_json: - additional_args.append("--json") - - with assert_run_failure(r'transfer simulation failed'): - client.sapling_submit( - file=transaction_file, - fee_payer='bootstrap2', - contract=contract_name, - args=additional_args, - ) - - @pytest.mark.parametrize( - "requested_token,real_balance,key_name", - [ - (2100000000, 200, "bob"), - (300, 200, "bob"), - (2100000000, 0, "alice"), - (100, 0, "alice"), - ], - ) - def test_unshields_money_insufficient_funds( - self, client, contract_name, requested_token, real_balance, key_name - ): - with assert_run_failure( - r'Balance too low \({}\) to spend {}'.format( - real_balance, requested_token - ) - ): - client.sapling_unshield( - amount=requested_token, - src=key_name, - dest="bootstrap4", - contract=contract_name, - args=["--burn-cap", "3.0"], - ) - - def test_bob_unshields_money(self, client, contract_name): - bootstrap4_prev_balance = client.get_balance('bootstrap4') - amount = 90.0 - client.sapling_unshield( - amount=amount, - src="bob", - dest="bootstrap4", - contract=contract_name, - args=["--burn-cap", "3.0"], - ) - utils.bake(client, bake_for="bootstrap2") - bob_balance = client.sapling_get_balance( - key_name="bob", contract_name=contract_name - ).balance - assert bob_balance == 200.0 - amount - bootstrap4_balance = client.get_balance("bootstrap4") - # The receiver pays fees by default so it will not get the full amount, - # but still, it should have more than before - assert bootstrap4_balance >= bootstrap4_prev_balance - assert bootstrap4_balance <= bootstrap4_prev_balance + amount - - def test_check_state_with_another_client( - self, sandbox, node, contract_name, session - ): - client = sandbox.get_new_client(node) - client.remember_contract(contract_name, session["contract_address"]) - key_name = "bob" - # Restore bob's key from mnemonic: - client.sapling_import_key( - key_name=key_name, - mnemonic=session['bob_mnemonic'], - ) - client.sapling_use_key_for_contract( - key_name, contract_name, memo_size=8 - ) - # Check Bob's balance again, it should be the same: - bob_balance = client.sapling_get_balance( - key_name=key_name, contract_name=contract_name - ).balance - assert bob_balance == 110.0 - - @pytest.mark.parametrize( - "transparent_signer,baker", [("bootstrap4", "bootstrap2")] - ) - def test_shielded_transfer_using_non_sapling_transfer_method( - self, client, contract_name, session, transparent_signer, baker, tmpdir - ): - transaction_filename = f'{tmpdir}/sapling_transaction_2.bin' - client.sapling_forge_transaction( - amount=10.0, - src='bob', - dest=session['bob_address_1'], - contract=contract_name, - file=transaction_filename, - args=[], - ) - with open(transaction_filename, "r") as file_descriptor: - content = re.sub(r'\s+', ' ', file_descriptor.read()) - client.transfer( - 0, - giver=transparent_signer, - receiver=contract_name, - args=[ - "--arg", - '{Pair %s None }' % content, - "--burn-cap", - "3.0", - ], - ) - utils.bake(client, bake_for=baker) - - @pytest.mark.parametrize( - "key_name,expected_balance", [("alice", 0.0), ("bob", 110.0)] - ) - def test_check_sapling_balances_after_calling_smart_contract( - self, client, contract_name, key_name, expected_balance - ): - balance = client.sapling_get_balance( - key_name=key_name, contract_name=contract_name - ).balance - assert balance == expected_balance - - -class TestSaplingMemoSize: - @pytest.fixture(scope="class") - def contract_name(self): - return "sapling_memo_size" - - @pytest.fixture(scope="class") - def contract_generator(self): - def generator(memo_size): - return ''' -parameter unit; -storage (sapling_state %s); -code { - DROP; - SAPLING_EMPTY_STATE %s; - NIL operation; - PAIR; - } -''' % ( - memo_size, - memo_size, - ) - - return generator - - @pytest.mark.parametrize("memo_size", [0, 1, 10, 42, 100, 65535]) - def test_originate_with_valid_size_and_update_with_valid_size( - self, client, memo_size, contract_name, tmpdir, contract_generator - ): - contract_path = tmpdir.join("c.tz") - contract_path.write(contract_generator(memo_size)) - sender = "bootstrap1" - client.originate( - contract_name=contract_name, - amount=0, - sender=sender, - contract=str(contract_path), - args=["--init", '{ }', "--burn-cap", "3.0", "--force"], - ) - utils.bake(client, bake_for="bootstrap1") - client.transfer( - 0, - giver="bootstrap1", - receiver=contract_name, - args=["--arg", "Unit", "--burn-cap", "3.0"], - ) - utils.bake(client, bake_for="bootstrap1") - - @pytest.mark.parametrize("memo_size", [-1, 65536, 65598909, 908923434]) - def test_originate_with_invalid_size( - self, - client, - memo_size, - contract_path, - contract_name, - contract_generator, - tmpdir, - ): - contract_path = tmpdir.join("c.tz") - contract_path.write(contract_generator(memo_size)) - sender = "bootstrap1" - err = r"expected a positive 16-bit integer" - with assert_run_failure(err): - client.originate( - contract_name=contract_name, - amount=0, - sender=sender, - contract=str(contract_path), - args=["--init", "{ }", "--burn-cap", "3.0", "--force"], - ) - - -@pytest.mark.incremental -class TestSaplingStateCorruption: - @pytest.fixture(scope="session") - def tmpdir(self, tmpdir_factory): - """ - Temporary directory. Forged transactions will be saved - in this directory. - FIXME/IMPROVEME: tmpdir_factory is a fixture provided by pytest. It is - session-scoped, then the fixture tmpdir must be session-scoped. - Would be nice to have a class-scoped fixture. - """ - tmpdir = tmpdir_factory.mktemp("sapling_transactions_shielded_tez") - return tmpdir - - def test_push_sapling_state_with_id_is_forbidden( - self, client, contract_path - ): - contract_name = ( - f"{contract_path}/contracts/sapling_push_sapling_state.tz" - ) - sender = "bootstrap1" - msg = r"big_map or sapling_state type not expected here" - with assert_run_failure(msg): - client.originate( - contract_name="push_sapling_state", - amount=0, - sender=sender, - contract=contract_name, - args=["--init", "Unit", "--burn-cap", "3.0"], - ) - - def test_originate_with_empty(self, client): - """ - Makes sure sapling state with id 0 exists - """ - contract = path.join( - contract_paths.OPCODES_CONTRACT_PATH, "sapling_empty_state.tz" - ) - client.originate( - amount=0, - sender="bootstrap1", - contract=contract, - contract_name="sapling_empty_state", - args=["--init", "{}", "--burn-cap", "3.0"], - ) - utils.bake(client, bake_for="bootstrap1") - - def test_originate_with_id_is_forbidden(self, client): - contract = path.join( - contract_paths.OPCODES_CONTRACT_PATH, "sapling_empty_state.tz" - ) - with assert_run_failure(r'Unexpected forged value'): - client.originate( - amount=0, - sender="bootstrap1", - contract=contract, - contract_name="sapling_empty_state2", - args=["--init", "0", "--burn-cap", "3.0"], - ) - - -class TestSaplingDifferentMemosize: - """ - Deploy a sapling contract using a sapling state with a memo size N and - create transactions with a memo size of M - """ - - @pytest.fixture - def contract_path(self): - return f'{CONTRACT_PATH}/contracts/sapling_contract.tz' - - def test_shield_with_different_memo_size(self, contract_path, client): - contract_name = "sapling_memo_size_different" - implicit_account = "bootstrap1" - contract_address = client.originate( - contract_name=contract_name, - amount=0, - sender=implicit_account, - contract=contract_path, - args=["--init", "{ }", "--burn-cap", "3.0"], - ).contract - utils.bake(client, bake_for=implicit_account) - client.sapling_gen_key(key_name='alice') - client.sapling_use_key_for_contract( - 'alice', contract_name, memo_size=16 - ) - address = client.sapling_gen_address(key_name='alice').address - # Key was registered with a memo_size of 16, it should fail - with assert_run_failure(r"Memo sizes of two sapling states"): - client.sapling_shield( - amount=TX_AMOUNT, - src=implicit_account, - dest=address, - contract=contract_address, - args=["--burn-cap", "3.0"], - ) - - -class TestSaplingRightMemosize: - """ - Deploy a sapling contract using a sapling state with a memo size N and - create transactions with a memo size of N and diverse messages - """ - - @pytest.fixture - def contract_path(self): - return f'{CONTRACT_PATH}/contracts/sapling_contract.tz' - - def test_shield_with_same_memo_size(self, contract_path, client): - contract_name = "sapling_memo_size_same" - implicit_account = "bootstrap1" - contract_address = client.originate( - contract_name=contract_name, - amount=0, - sender=implicit_account, - contract=contract_path, - args=["--init", "{ }", "--burn-cap", "3.0"], - ).contract - utils.bake(client, bake_for=implicit_account) - client.sapling_gen_key(key_name='alice') - client.sapling_use_key_for_contract('alice', contract_name, memo_size=8) - address = client.sapling_gen_address(key_name='alice').address - # Should pass since memo-sizes are equal and message is - # filled with 0's - client.sapling_shield( - amount=TX_AMOUNT, - src=implicit_account, - dest=address, - contract=contract_address, - args=["--burn-cap", "3.0"], - ) - utils.bake(client, bake_for="bootstrap2") - # Deriving a new key should work as well since - # the memo-size is kept - client.sapling_derive_key( - source_key_name='alice', - target_key_name='bob', - contract_name=contract_name, - index=10, - ) - address_derived = client.sapling_gen_address(key_name='bob').address - client.sapling_shield( - amount=TX_AMOUNT, - src=implicit_account, - dest=address_derived, - contract=contract_address, - args=["--burn-cap", "3.0"], - ) - utils.bake(client, bake_for="bootstrap2") - # Now with a too short message - client.sapling_shield( - amount=TX_AMOUNT, - src=implicit_account, - dest=address, - contract=contract_address, - args=["--burn-cap", "3.0", "--message", "aB"], - ) - utils.bake(client, bake_for="bootstrap2") - # Now with a right length message - client.sapling_shield( - amount=TX_AMOUNT, - src=implicit_account, - dest=address, - contract=contract_address, - args=["--burn-cap", "3.0", "--message", "aBbf19F00a"], - ) - utils.bake(client, bake_for="bootstrap2") - # Now with a too long message - client.sapling_shield( - amount=TX_AMOUNT, - src=implicit_account, - dest=address, - contract=contract_address, - args=["--burn-cap", "3.0", "--message", "aBbf19F00aaBbf19F00aC"], - ) - utils.bake(client, bake_for="bootstrap2") diff --git a/tests_python/tests_012/test_slice_fails_params.txt b/tests_python/tests_012/test_slice_fails_params.txt deleted file mode 100644 index 7241bd22aff3..000000000000 --- a/tests_python/tests_012/test_slice_fails_params.txt +++ /dev/null @@ -1,5 +0,0 @@ -(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "p2sigsceCzcDw2AeYDzUonj4JT341WC9Px4wdhHBxbZcG1FhfqFVuG7f2fGCzrEHSAZgrsrQWpxduDPk9qZRgrpzwJnSHC3gZJ") -(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") -(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2deaad01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") -(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150733eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") -(Pair 0xe009ab79e8b84ef0 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") diff --git a/tests_python/tests_012/test_slice_success_params.txt b/tests_python/tests_012/test_slice_success_params.txt deleted file mode 100644 index 8c0d89bd8142..000000000000 --- a/tests_python/tests_012/test_slice_success_params.txt +++ /dev/null @@ -1 +0,0 @@ -(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") diff --git a/tests_python/tests_012/test_tenderbake.py b/tests_python/tests_012/test_tenderbake.py deleted file mode 100644 index b2fac3f0978d..000000000000 --- a/tests_python/tests_012/test_tenderbake.py +++ /dev/null @@ -1,59 +0,0 @@ -import time -import copy -import pytest -from tools import constants -from launchers.sandbox import Sandbox -from . import protocol - - -MINIMAL_BLOCK_DELAY = 4 -DELAY_INCREMENT_PER_ROUND = 1 -TEST_DURATION = 5 * MINIMAL_BLOCK_DELAY -NUM_NODES = 5 - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -@pytest.mark.tenderbake -class TestProtoTenderbake: - """Run a number of nodes and bakers, wait and check that all blocks - were agreed upon at round 0""" - - def test_init(self, sandbox: Sandbox): - - for i in range(NUM_NODES): - sandbox.add_node(i, params=constants.NODE_PARAMS) - - proto_params = dict(protocol.TENDERBAKE_PARAMETERS) - parameters = copy.deepcopy(proto_params) - parameters['consensus_threshold'] = ( - 2 * (parameters['consensus_threshold'] // 3) + 1 - ) - parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) - parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) - protocol.activate(sandbox.client(0), parameters=parameters) - - for i in range(NUM_NODES): - sandbox.add_baker( - i, - [f'bootstrap{i + 1}'], - proto=protocol.DAEMON, - log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, - ) - - def test_wait(self): - time.sleep(TEST_DURATION) - - def test_level(self, sandbox: Sandbox): - # a decision should be taken in the first round, so we can deduce at - # which minimal level the nodes should be at - expected_min_level = 1 + TEST_DURATION // MINIMAL_BLOCK_DELAY - for client in sandbox.all_clients(): - level = client.get_level() - assert level >= expected_min_level - for i in range(level + 1): - if i > 1: - block_round = client.get_tenderbake_round(level=str(i)) - assert block_round == 0 diff --git a/tests_python/tests_012/test_tenderbake_bakers_restart.py b/tests_python/tests_012/test_tenderbake_bakers_restart.py deleted file mode 100644 index 897d602cd673..000000000000 --- a/tests_python/tests_012/test_tenderbake_bakers_restart.py +++ /dev/null @@ -1,80 +0,0 @@ -import copy -import time -import pytest -from tools import constants -from launchers.sandbox import Sandbox -from . import protocol - -NUM_NODES = 5 # because we assume 5 (bootstrap) accounts -NUM_TEST_CYCLES = 4 -# CYCLE_DUR should be correlated with MINIMAL_BLOCK_DELAY and -# DELAY_INCREMENT_PER_ROUND below -CYCLE_DUR = 10 -MINIMAL_BLOCK_DELAY = 4 -DELAY_INCREMENT_PER_ROUND = 1 - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -@pytest.mark.tenderbake -class TestProtoTenderbake: - """Run a number of nodes and start the bakers incrementally, each one - after one round duration more. After all bakers have been - started, they should be able to reach a decision.""" - - def test_init(self, sandbox: Sandbox): - for i in range(NUM_NODES): - sandbox.add_node( - i, - params=constants.NODE_PARAMS, - log_levels=constants.TENDERBAKE_NODE_LOG_LEVELS, - ) - - proto_params = dict(protocol.TENDERBAKE_PARAMETERS) - parameters = copy.deepcopy(proto_params) - parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) - parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) - parameters['consensus_threshold'] = ( - 2 * (parameters['consensus_threshold'] // 3) + 1 - ) - - protocol.activate(sandbox.client(0), parameters=parameters) - - for i in range(NUM_NODES): - sandbox.add_baker( - i, - [f'bootstrap{i + 1}'], - proto=protocol.DAEMON, - log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, - ) - - def test_restart(self, sandbox): - # in the even cycles we run all the bakers - # in the odd cycles one is dead - # we iterate cyclically through the bakers to choose the dead one - dead_baker = 0 - for cycle in range(NUM_TEST_CYCLES): - if cycle % 2 == 1: - sandbox.rm_baker(dead_baker, proto=protocol.DAEMON) - # we let some time pass - # (there will be no progress during this time) - time.sleep(MINIMAL_BLOCK_DELAY) - else: - if cycle > 1: - sandbox.add_baker( - dead_baker, - [f'bootstrap{dead_baker + 1}'], - proto=protocol.DAEMON, - log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, - ) - # the CYCLE_DUR is long enough for bakers to take a decision - time.sleep(CYCLE_DUR) - dead_baker = (dead_baker + 1) % NUM_NODES - - def test_level(self, sandbox): - expected_min_level = 2 + NUM_TEST_CYCLES / 2 - for client in sandbox.all_clients(): - level = client.get_level() - assert level >= expected_min_level diff --git a/tests_python/tests_012/test_tenderbake_incremental_start.py b/tests_python/tests_012/test_tenderbake_incremental_start.py deleted file mode 100644 index 0f36d4208483..000000000000 --- a/tests_python/tests_012/test_tenderbake_incremental_start.py +++ /dev/null @@ -1,82 +0,0 @@ -import copy -import time -import pytest -from tools import constants -from launchers.sandbox import Sandbox -from . import protocol - -NUM_NODES = 5 # because we assume 5 (bootstrap) accounts -NUM_EARLY_START_NODES = 2 -MINIMAL_BLOCK_DELAY = 4 -DELAY_INCREMENT_PER_ROUND = 1 -TEST_DURATION = 5 * MINIMAL_BLOCK_DELAY - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -@pytest.mark.tenderbake -class TestProtoTenderbakeIncrementalStart: - """Run a number of nodes and start the bakers incrementally, each one - after one round duration more. After all bakers have been - started, they should be able to reach a decision.""" - - def test_init_nodes(self, sandbox: Sandbox): - for i in range(NUM_NODES): - sandbox.add_node( - i, - params=constants.NODE_PARAMS, - log_levels=constants.TENDERBAKE_NODE_LOG_LEVELS, - ) - - def test_start_some_bakers(self, sandbox: Sandbox): - for i in range(NUM_EARLY_START_NODES): - account = f'bootstrap{i + 1}' - sandbox.add_baker( - i, - [account], - proto=protocol.DAEMON, - log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, - ) - - def test_activate(self, sandbox): - proto_params = dict(protocol.TENDERBAKE_PARAMETERS) - parameters = copy.deepcopy(proto_params) - parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) - parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) - parameters['consensus_threshold'] = ( - 2 * (parameters['consensus_threshold'] // 3) + 1 - ) - - time.sleep(2 * MINIMAL_BLOCK_DELAY) - protocol.activate( - sandbox.client(0), - parameters=parameters, - ) - - def test_start_remaining_bakers(self, sandbox: Sandbox): - for i in range(NUM_EARLY_START_NODES, NUM_NODES): - account = f'bootstrap{i + 1}' - sandbox.add_baker( - i, - [account], - proto=protocol.DAEMON, - log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, - ) - time.sleep(MINIMAL_BLOCK_DELAY) - - def test_wait(self): - time.sleep(TEST_DURATION) - - def test_level(self, sandbox): - # a decision should be taken in the first round, so we can deduce at - # which minimal level the nodes should be at - expected_min_level = 1 + TEST_DURATION // MINIMAL_BLOCK_DELAY - for client in sandbox.all_clients(): - level = client.get_level() - assert level >= expected_min_level - for i in range(level + 1): - if i > 1: - block_round = client.get_tenderbake_round(level=str(i)) - assert block_round == 0 diff --git a/tests_python/tests_012/test_tenderbake_long_dynamic_bake.py b/tests_python/tests_012/test_tenderbake_long_dynamic_bake.py deleted file mode 100644 index 317504fecd72..000000000000 --- a/tests_python/tests_012/test_tenderbake_long_dynamic_bake.py +++ /dev/null @@ -1,237 +0,0 @@ -import copy -import itertools -import random -import time -import subprocess -from datetime import datetime -from typing import List, Optional, Tuple, Dict, Iterable, Any - -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox -from client.client import Client -from . import protocol - -# This test runs NUM_NODES, and 3 bakers. It runs NUM_TEST_CYCLES test cycles -# (not to be confused for protocol cycle) where each cycle lasts -# TIME_BETWEEN_CYCLE seconds, for TEST_DURATION seconds. -# At each cycle, a random transaction is injected. Every CHECK_PROGRESS -# cycles, a client checks that the chain is progressing. -# It does so by polling the chain (and checking that the level is increasing) -# at most MAX_RETRY times, with a timeout of TIMEOUT seconds -# At the end of the test, checks that the chain has at least -# EXPECTED_LEVEL blocks - -random.seed(42) -KEYS = [f'bootstrap{i}' for i in range(1, 6)] -NEXT_KEY = itertools.cycle(KEYS) -NUM_NODES = 5 -NUM_TEST_CYCLES = 500 -TIME_BETWEEN_CYCLE = 2 -CHECK_PROGRESS = 10 -KILL_BAKER = 4 -TIMEOUT = 6 -MAX_RETRY = 6 -TEST_DURATION = 300 # duration of the main loop -MINIMAL_BLOCK_DELAY = 1 -DELAY_INCREMENT_PER_ROUND = 1 -MAX_LEVEL_DURATION = 6 # that is, decision expected in at most 3 rounds -EXPECTED_LEVEL = TEST_DURATION // MAX_LEVEL_DURATION - - -def random_op(client: Client) -> None: - sender = next(NEXT_KEY) - dest = random.choice([key for key in KEYS if key != sender]) - amount = random.randrange(10) + 1 - client.run(['transfer', str(amount), 'from', sender, 'to', dest]) - - -def setup_parameters() -> Dict[str, Any]: - proto_params = dict(protocol.TENDERBAKE_PARAMETERS) - parameters = copy.deepcopy(proto_params) - parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) - parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) - parameters['consensus_threshold'] = ( - 2 * (parameters['consensus_threshold'] // 3) + 1 - ) - return parameters - - -def add_nodes( - sandbox: Sandbox, - node_peers_assoc: Iterable[Tuple[int, Optional[List[int]]]], -) -> None: - for node_id, peers in node_peers_assoc: - sandbox.add_node( - node_id, - params=constants.NODE_PARAMS, - log_levels=constants.TENDERBAKE_NODE_LOG_LEVELS, - peers=peers, - ) - - -def add_bakers(sandbox: Sandbox, nodes: Iterable[int]) -> None: - for node_id in nodes: - account = f'bootstrap{node_id + 1}' - sandbox.add_baker( - node_id, - [account], - proto=protocol.DAEMON, - log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, - ) - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -@pytest.mark.tenderbake -@pytest.mark.manual -class TestAllDaemonsWithOperations: - """Runs three baker, generates random op, and - add (or replace) new nodes dynamically. After a little while, - we kill the bakers and check everyone synchronize to the same head.""" - - def test_setup_network(self, sandbox: Sandbox): - parameters = setup_parameters() - add_nodes(sandbox, [(i, None) for i in range(NUM_NODES)]) - protocol.activate(sandbox.client(0), parameters=parameters) - add_bakers(sandbox, range(NUM_NODES - 1)) - - def test_wait_for_012(self, sandbox: Sandbox): - clients = sandbox.all_clients() - for client in clients: - proto = protocol.HASH - assert utils.check_protocol(client, proto) - - def test_network_gen_operations(self, sandbox: Sandbox, session): - dead_baker = NUM_NODES - 1 - cur_time = datetime.now() - cycle = 1 - while (datetime.now() - cur_time).total_seconds() < TEST_DURATION: - i = random.randrange(NUM_NODES) - client = sandbox.client(i) - try: - random_op(client) - except subprocess.CalledProcessError: - # some operations may be invalid, e.g. the client sends - # several operation with the same counter - print('# IGNORED INVALID OPERATION') - - # test chain progresses every X cycles - if cycle % CHECK_PROGRESS == 0: - client = sandbox.client(0) - - level_before = client.get_level() - current_time = datetime.now().strftime("%H:%M:%S") - print(current_time, "client level: ", level_before) - - retry = MAX_RETRY - while client.get_level() == level_before and retry >= 1: - if retry != MAX_RETRY: - current_time = datetime.now().strftime("%H:%M:%S") - print( - current_time, - "level did not increase, retries: ", - retry, - ) - time.sleep(TIMEOUT) - retry -= 1 - msg = f"chain level didn't increase for {MAX_RETRY*TIMEOUT}s" - assert retry, msg - - # cyclically kill bakers - if cycle % KILL_BAKER == 0: - baker = (dead_baker + 1) % NUM_NODES - current_time = datetime.now().strftime("%H:%M:%S") - print(current_time, "killing baker on node ", baker) - sandbox.rm_baker(baker, proto=protocol.DAEMON) - time.sleep(1) - # wake up the dead baker - current_time = datetime.now().strftime("%H:%M:%S") - print(current_time, "starting baker on node ", dead_baker) - sandbox.add_baker( - dead_baker, - [f'bootstrap{dead_baker+1}'], - proto=protocol.DAEMON, - log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, - ) - # set the next baker to die - dead_baker = baker - time.sleep(TIME_BETWEEN_CYCLE) - cycle += 1 - session['dead_baker'] = dead_baker - - def test_kill_baker(self, sandbox: Sandbox, session): - for i in range(NUM_NODES): - if i != session['dead_baker']: - sandbox.rm_baker(i, proto=protocol.DAEMON) - - def test_synchronize(self, sandbox: Sandbox): - utils.synchronize(sandbox.all_clients()) - - def test_check_operations(self, sandbox: Sandbox): - min_level = min( - [client.get_level() for client in sandbox.all_clients()] - ) - heads_hash = set() - assert min_level >= EXPECTED_LEVEL - # check there is exactly one head - for client in sandbox.all_clients(): - block_hash = utils.get_block_hash(client, min_level) - heads_hash.add(block_hash) - assert len(heads_hash) == 1 - - -@pytest.mark.baker -@pytest.mark.multinode -@pytest.mark.slow -@pytest.mark.incremental -@pytest.mark.tenderbake -@pytest.mark.manual -class TestAllDaemonsWithOperationsRingTopo(TestAllDaemonsWithOperations): - """Runs three baker, generates random op, and - add (or replace) new nodes dynamically. After a little while, - we kill the bakers and check everyone synchronize to the same head. - Use a ring topology instead of the default clique""" - - def test_setup_network(self, sandbox: Sandbox): - parameters = setup_parameters() - add_nodes( - sandbox, - [ - (i, [(i + 1) % NUM_NODES, (NUM_NODES + i - 1) % NUM_NODES]) - for i in range(NUM_NODES) - ], - ) - protocol.activate(sandbox.client(0), parameters=parameters) - add_bakers(sandbox, range(NUM_NODES - 1)) - - def test_check_topology(self, sandbox: Sandbox): - for i in range(NUM_NODES): - client = sandbox.client(i) - res = client.p2p_stat() - num_connected = 0 - for point in res.points.values(): - num_connected += point.is_connected - assert num_connected == 2 - - # The calls to super() below allow to implicitly specifiy the test sequence - # by "pseudo-redefining" some inherited methods. Otherwise, there's no - # guarantee regarding when test_check_topology will be executed. - # - # pylint: disable=W0235 - def test_wait_for_012(self, sandbox: Sandbox): - super().test_wait_for_012(sandbox) - - def test_network_gen_operations(self, sandbox: Sandbox, session): - super().test_network_gen_operations(sandbox, session) - - def test_kill_baker(self, sandbox: Sandbox, session): - super().test_kill_baker(sandbox, session) - - def test_synchronize(self, sandbox: Sandbox): - utils.synchronize(sandbox.all_clients()) - - def test_check_operations(self, sandbox: Sandbox): - super().test_check_operations(sandbox) diff --git a/tests_python/tests_012/test_tenderbake_manual_bake.py b/tests_python/tests_012/test_tenderbake_manual_bake.py deleted file mode 100644 index e8297d0caad7..000000000000 --- a/tests_python/tests_012/test_tenderbake_manual_bake.py +++ /dev/null @@ -1,231 +0,0 @@ -import copy -import time -import pytest -from tools import utils, constants -from launchers.sandbox import Sandbox -from . import protocol - - -MINIMAL_BLOCK_DELAY = 1 -TRANSFER_AMOUNT = 500 -INITIAL_BALANCE = 4000000.0 -FEE = 0.1 -ALL_ACOUNTS = [ - 'bootstrap1', - 'bootstrap2', - 'bootstrap3', - 'bootstrap4', - 'bootstrap5', -] - - -def find_account(identity): - for account, keys in constants.IDENTITIES.items(): - if keys['identity'] == identity: - return account - return None - - -def baker_at_round_0(client, level='head'): - if level == 'head': - arg = '' - else: - arg = f'?level={level}' - res = client.rpc( - 'get', f'/chains/main/blocks/head/helpers/baking_rights{arg}' - ) - delegate_id = res[0]['delegate'] - return find_account(delegate_id) - - -@pytest.mark.slow -@pytest.mark.tenderbake -@pytest.mark.incremental -@pytest.mark.tenderbake -class TestManualBake: - """Run a number of nodes, and bake, preendorse, and endorse using the - client commands""" - - def test_init(self, sandbox: Sandbox): - sandbox.add_node(0, params=constants.NODE_PARAMS) - - proto_params = dict(protocol.TENDERBAKE_PARAMETERS) - parameters = copy.deepcopy(proto_params) - parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) - parameters['delay_increment_per_round'] = '1' - protocol.activate( - sandbox.client(0), - parameters=proto_params, - activate_in_the_past=True, - ) - - def test_choose_players(self, sandbox: Sandbox, session: dict): - # we will make a transfer to someone who is not baking, to simplify - # the computation of the expected balance - client = sandbox.client(0) - session['level2_baker'] = baker_at_round_0(client) - session['level3_baker'] = baker_at_round_0(client, str(3)) - # recepient should also be different from bootstrap1 because - # bootstrap1 makes the transfer and we don't want a self-transfer - for account in ALL_ACOUNTS[1:]: - if account not in [ - session['level3_baker'], - session['level2_baker'], - ]: - session['recepient'] = account - break - - def test_bake(self, sandbox: Sandbox, session: dict): - client = sandbox.client(0) - client.propose([session['level2_baker']], ['--minimal-timestamp']) - - def test_deposit(self, sandbox: Sandbox, session: dict): - """Test balance of the receipient takes into account deposits taken at - level 2""" - client = sandbox.client(0) - balance = client.get_mutez_balance(session['recepient']) - recepient_pkh = constants.IDENTITIES[session['recepient']]['identity'] - deposit_mutez = client.frozen_deposits(recepient_pkh) - assert balance == utils.mutez_of_tez(INITIAL_BALANCE) - deposit_mutez - - def test_level(self, sandbox: Sandbox): - client = sandbox.client(0) - head = client.get_head() - assert head['header']['level'] == 2 - - def test_preendorse(self, sandbox: Sandbox): - client = sandbox.client(0) - client.run(['preendorse', 'for', 'bootstrap1', '--force']) - client.run(['preendorse', 'for', 'bootstrap2', '--force']) - client.run(['preendorse', 'for', 'bootstrap3', '--force']) - client.run(['preendorse', 'for', 'bootstrap4', '--force']) - - def test_transfer(self, sandbox: Sandbox, session: dict): - client = sandbox.client(0) - transfer = client.transfer( - TRANSFER_AMOUNT, - 'bootstrap1', - session['recepient'], - ['--fee', str(FEE), '--force-low-fee'], - ) - session["transfer_hash"] = transfer.operation_hash - - def test_endorse(self, sandbox: Sandbox): - client = sandbox.client(0) - client.run(['endorse', 'for', 'bootstrap1', '--force']) - client.run(['endorse', 'for', 'bootstrap2', '--force']) - client.run(['endorse', 'for', 'bootstrap3', '--force']) - client.run(['endorse', 'for', 'bootstrap4', '--force']) - - def test_transfer_is_pending(self, sandbox: Sandbox, session: dict): - client = sandbox.client(0) - pending_ops = client.rpc( - 'get', '/chains/main/mempool/pending_operations' - ) - # Checking the transfer hash is in pending_operaionts - assert any( - map( - lambda op: op["hash"] == session["transfer_hash"], - pending_ops["applied"], - ) - ) - - def test_bake_again(self, sandbox: Sandbox, session: dict): - print("Sleeping") - time.sleep(2 * MINIMAL_BLOCK_DELAY) - client = sandbox.client(0) - client.propose([session['level3_baker']], ['--minimal-timestamp']) - client.get_head() - - def test_level_again(self, sandbox: Sandbox): - client = sandbox.client(0) - head = client.get_head() - assert head['header']['level'] == 3 - - def test_balance(self, sandbox: Sandbox, session: dict): - client = sandbox.client(0) - recepient_pkh = constants.IDENTITIES[session['recepient']]['identity'] - deposit_mutez = client.frozen_deposits(recepient_pkh) - balance = client.get_mutez_balance(session['recepient']) - assert ( - balance - == utils.mutez_of_tez(INITIAL_BALANCE + TRANSFER_AMOUNT) - - deposit_mutez - ) - - def test_bake_fail(self, sandbox: Sandbox): - """Baking with not enough endorsing power should fail in Tenderbake. - - This is the case in sandboxed mode since a lone bootstrap account does - not have enough slots in the default settings. - - """ - client = sandbox.client(0) - error_pattern = 'Delegates do not have enough voting power.' - with utils.assert_run_failure(error_pattern): - utils.bake(client, bake_for='bootstrap1') - - -@pytest.mark.incremental -@pytest.mark.tenderbake -class TestManualBakeNullThreshold: - """Run a number of nodes, and bake when no endorsements are expected""" - - def test_init(self, sandbox: Sandbox): - sandbox.add_node(0, params=constants.NODE_PARAMS) - proto_params = protocol.TENDERBAKE_PARAMETERS - parameters = copy.deepcopy(proto_params) - parameters['consensus_threshold'] = 0 - - protocol.activate( - sandbox.client(0), parameters=parameters, activate_in_the_past=True - ) - - def test_choose_players(self, sandbox: Sandbox, session: dict): - # we will make a transfer to someone who is not baking, to simplify - # the computation of the expected balance - client = sandbox.client(0) - session['level2_baker'] = baker_at_round_0(client) - session['level3_baker'] = baker_at_round_0(client, str(3)) - # recepient should also be different from bootstrap1 because - # bootstrap1 makes the transfer and we don't want a self-transfer - for account in ALL_ACOUNTS[1:]: - if account not in [ - session['level3_baker'], - session['level2_baker'], - ]: - session['recepient'] = account - break - - def test_bake(self, sandbox: Sandbox, session: dict): - client = sandbox.client(0) - client.propose([session['level2_baker']], ['--minimal-timestamp']) - - def test_level(self, sandbox: Sandbox): - client = sandbox.client(0) - level = client.get_level() - assert level == 2 - - def test_transfer(self, sandbox: Sandbox, session: dict): - client = sandbox.client(0) - client.transfer(TRANSFER_AMOUNT, 'bootstrap1', session['recepient']) - - def test_bake_again(self, sandbox: Sandbox, session: dict): - client = sandbox.client(0) - client.propose([session['level3_baker']], ['--minimal-timestamp']) - - def test_level_again(self, sandbox: Sandbox): - client = sandbox.client(0) - head = client.get_head() - assert head['header']['level'] == 3 - - def test_balance(self, sandbox: Sandbox, session: dict): - client = sandbox.client(0) - balance = client.get_mutez_balance(session['recepient']) - recepient_pkh = constants.IDENTITIES[session['recepient']]['identity'] - deposit_mutez = client.frozen_deposits(recepient_pkh) - assert ( - balance - == utils.mutez_of_tez(INITIAL_BALANCE + TRANSFER_AMOUNT) - - deposit_mutez - ) diff --git a/tests_python/tests_012/test_tls.py b/tests_python/tests_012/test_tls.py deleted file mode 100755 index 475d786823bb..000000000000 --- a/tests_python/tests_012/test_tls.py +++ /dev/null @@ -1,23 +0,0 @@ -import pytest -from tools import constants -from client.client import Client - - -@pytest.fixture(scope="class") -def client(sandbox): - sandbox.add_node( - 0, - use_tls=(constants.TEZOS_CRT, constants.TEZOS_KEY), - params=constants.NODE_PARAMS, - ) - yield sandbox.client(0) - - -@pytest.mark.vote -@pytest.mark.incremental -@pytest.mark.skip(reason="requires to install a custom CA") -class TestTLS: - """Test voting protocol with manual baking, 4 blocks per voting period.""" - - def test_bootstrapped(self, client: Client): - assert client.bootstrapped() diff --git a/tests_python/tests_012/test_voting.py b/tests_python/tests_012/test_voting.py deleted file mode 100644 index dc8b38ba0331..000000000000 --- a/tests_python/tests_012/test_voting.py +++ /dev/null @@ -1,249 +0,0 @@ -import copy -import shutil -import pytest -from client.client import Client -from tools import constants, paths, utils -from . import protocol - - -@pytest.fixture(scope="class") -def client(sandbox): - """One node, 4 blocks per voting period.""" - proto_params = dict(protocol.PARAMETERS) - parameters = copy.deepcopy(proto_params) - parameters["blocks_per_voting_period"] = 4 - parameters['consensus_threshold'] = 0 - sandbox.add_node(0, params=constants.NODE_PARAMS) - protocol.activate(sandbox.client(0), parameters, activate_in_the_past=True) - yield sandbox.client(0) - - -@pytest.mark.vote -@pytest.mark.incremental -class TestManualBaking: - """Test voting protocol with manual baking, 4 blocks per voting period.""" - - def test_current_period(self, client: Client): - period_info = client.get_current_period() - level = client.get_current_level() - assert level["level_position"] == 0 - assert period_info["voting_period"]["index"] == 0 - assert period_info["voting_period"]["kind"] == "proposal" - assert period_info["voting_period"]["start_position"] == 0 - assert period_info["position"] == 0 - assert period_info["remaining"] == 3 - - def test_succ_period(self, client: Client): - period_info = client.get_succ_period() - assert period_info["voting_period"]["index"] == 0 - assert period_info["voting_period"]["kind"] == "proposal" - assert period_info["voting_period"]["start_position"] == 0 - assert period_info["position"] == 1 - assert period_info["remaining"] == 2 - - def test_level_info_offset(self, client: Client): - level = client.get_current_level(offset=1) - assert level["level_position"] == 1 - level = client.get_current_level(offset=4) - assert level["level_position"] == 4 - level = client.get_current_level(offset=10) - assert level["level_position"] == 10 - - def test_bake_two_blocks(self, client: Client): - utils.bake(client) - utils.bake(client) - period_info = client.get_current_period() - level = client.get_current_level() - assert level["level_position"] == 2 - assert period_info["voting_period"]["index"] == 0 - assert period_info["voting_period"]["kind"] == "proposal" - assert period_info["voting_period"]["start_position"] == 0 - assert period_info["position"] == 2 - assert period_info["remaining"] == 1 - - def test_last_block_of_proposal_period(self, client: Client): - # last block of voting period 0 - utils.bake(client) - period_info = client.get_current_period() - assert period_info["voting_period"]["index"] == 0 - assert period_info["voting_period"]["kind"] == "proposal" - assert period_info["voting_period"]["start_position"] == 0 - assert period_info["position"] == 3 - assert period_info["remaining"] == 0 - - def test_listing_is_not_empty(self, client: Client): - assert client.get_listings() != [] - - def test_inject_proto1(self, client: Client, tmpdir): - proto_fp = ( - f'{paths.TEZOS_HOME}/src/bin_client/test/proto_test_injection' - ) - - for i in range(1, 4): - proto = f'{tmpdir}/proto{i}' - shutil.copytree(proto_fp, proto) - main = f'{proto}/main.ml' - print(main) - with open(main, "a") as file: - file.write(f'(* {i} *)') - client.inject_protocol(proto) - - # this is maybe useless because the protocol already knows more than 4 - # protocol - def test_known_protocol(self, client: Client, session: dict): - protos = client.list_protocols() - assert len(protos) >= 4 - session['protos'] = protos[:4] - - def test_proposals_is_empty(self, client: Client): - assert client.get_proposals() == [] - - def test_show_voting_period2(self, client: Client): - client.show_voting_period() - - def test_bake_first_block_of_proposal_period(self, client: Client): - # using the client it's not possible to add voting operation on the - # first block of a voting period. This is to be fixed in a future - # protocol - utils.bake(client) - period_info = client.get_current_period() - assert period_info["voting_period"]["index"] == 1 - assert period_info["voting_period"]["kind"] == "proposal" - assert period_info["voting_period"]["start_position"] == 4 - assert period_info["position"] == 0 - assert period_info["remaining"] == 3 - - def test_submit_proposals(self, client: Client, session: dict): - protos = session['protos'] - client.submit_proposals('bootstrap1', [protos[0]]) - client.submit_proposals('bootstrap2', [protos[0], protos[1]]) - client.submit_proposals('bootstrap3', [protos[1]]) - client.submit_proposals('bootstrap4', [protos[2]]) - - def test_bake_one_block(self, client: Client): - utils.bake(client) - period_info = client.get_current_period() - assert period_info["voting_period"]["index"] == 1 - assert period_info["voting_period"]["kind"] == "proposal" - assert period_info["voting_period"]["start_position"] == 4 - assert period_info["position"] == 1 - assert period_info["remaining"] == 2 - - def test_proposals_is_not_empty(self, client: Client): - assert client.get_proposals() != [] - - def test_bake_until_prev_last_block_of_voting_period(self, client: Client): - utils.bake(client) - period_info = client.get_current_period() - assert period_info["position"] == 2 - assert period_info["remaining"] == 1 - - def test_break_proposal_tie(self, client: Client, session: dict): - protos = session['protos'] - client.submit_proposals('bootstrap4', [protos[1]]) - - def test_bake_last_block_of_proposal_period(self, client: Client): - utils.bake(client) - period_info = client.get_current_period() - metadata = client.get_metadata() - level = client.get_current_level() - level_info = metadata["level_info"] - meta_period_info = metadata["voting_period_info"] - expected_commitment = level["expected_commitment"] - assert level["level"] == level_info["level"] - assert level["level_position"] == level_info["level_position"] - assert level["cycle"] == level_info["cycle"] - assert level["cycle_position"] == level_info["cycle_position"] - assert expected_commitment == level_info["expected_commitment"] - assert level["level_position"] == 7 - assert period_info["voting_period"]["index"] == 1 - assert period_info["voting_period"]["kind"] == "proposal" - assert period_info["voting_period"]["start_position"] == 4 - assert period_info["position"] == 3 - assert period_info["remaining"] == 0 - assert meta_period_info == period_info - - def test_listing_is_not_empty2(self, client: Client): - assert client.get_listings() != [] - - def test_current_proposal(self, client: Client, session: dict): - expected = session['protos'][1] - assert expected == client.get_current_proposal() - - def test_bake_first_block_of_cooldown_vote_period(self, client: Client): - # using the client it's not possible to add voting operation on the - # first block of a voting period. This is to be fixed in a future - # protocol - utils.bake(client) - period_info = client.get_current_period() - assert period_info["voting_period"]["index"] == 2 - assert period_info["voting_period"]["kind"] == "exploration" - assert period_info["voting_period"]["start_position"] == 8 - assert period_info["position"] == 0 - assert period_info["remaining"] == 3 - - def test_submit_ballot(self, client: Client, session: dict): - # next block is going to be of 'exploration' kind - proto = session['protos'][1] - for i in range(1, 4): - client.submit_ballot(f'bootstrap{i}', proto, 'yay') - - def test_bake_until_prev_last_block_of_voting_period2(self, client: Client): - utils.bake(client) - utils.bake(client) - period_info = client.get_current_period() - level = client.get_current_level() - assert level["level_position"] == 10 - assert period_info["voting_period"]["index"] == 2 - assert period_info["voting_period"]["kind"] == "exploration" - assert period_info["voting_period"]["start_position"] == 8 - assert period_info["position"] == 2 - assert period_info["remaining"] == 1 - - def test_submit_failing_ballot(self, client: Client, session: dict): - proto = session['protos'][1] - client.submit_ballot(f'bootstrap{4}', proto, 'nay') - - def test_level_info_offset2(self, client: Client): - level = client.get_current_level(block='head~1') - assert level["level_position"] == 9 - level = client.get_current_level(block='head~4') - assert level["level_position"] == 6 - level = client.get_current_level(block='head~10') - assert level["level_position"] == 0 - - def test_bake_first_block_of_new_proposal_period(self, client: Client): - utils.bake(client) - # Because of the current hack in proposal here we make sure we get the - # correct value - level = client.get_current_level() - period_info = client.get_current_period() - metadata = client.get_metadata() - level_info = metadata["level_info"] - meta_period_info = metadata["voting_period_info"] - expected_commitment = level["expected_commitment"] - assert level["level"] == level_info["level"] - assert level["level_position"] == level_info["level_position"] - assert level["cycle"] == level_info["cycle"] - assert level["cycle_position"] == level_info["cycle_position"] - assert expected_commitment == level_info["expected_commitment"] - assert level["level_position"] == 11 - assert period_info["voting_period"]["index"] == 2 - assert period_info["voting_period"]["kind"] == "exploration" - assert period_info["voting_period"]["start_position"] == 8 - assert period_info["position"] == 3 - assert period_info["remaining"] == 0 - assert meta_period_info == period_info - utils.bake(client) - period_info = client.get_current_period() - level = client.get_current_level() - assert level["level_position"] == 12 - assert period_info["voting_period"]["index"] == 3 - assert period_info["voting_period"]["kind"] == "proposal" - assert period_info["voting_period"]["start_position"] == 12 - assert period_info["position"] == 0 - assert period_info["remaining"] == 3 - assert client.get_listings() != '[]' - # strange behavior here, RPC returns 'null' on stderr - assert client.get_current_proposal() is None - assert client.get_ballot_list() == [] diff --git a/tests_python/tests_012/test_voting_full.py b/tests_python/tests_012/test_voting_full.py deleted file mode 100644 index 00d07d84b9d1..000000000000 --- a/tests_python/tests_012/test_voting_full.py +++ /dev/null @@ -1,217 +0,0 @@ -import time - -import subprocess -import pytest - -from launchers.sandbox import Sandbox -from client.client import Client -from tools import utils, constants -from . import protocol - -BLOCKS_PER_VOTING_PERIOD = 8 -OFFSET = int(BLOCKS_PER_VOTING_PERIOD / 2) -POLLING_TIME = 5 -BAKING_RATE = 1 -NUM_NODES = 5 -BAKER = "bootstrap1" -ERROR_PATTERN = r"Uncaught|registered|error" - -PROTO_A = protocol.PREV_HASH -PROTO_A_DAEMON = protocol.PREV_DAEMON -PROTO_A_PATH = f"proto_{PROTO_A_DAEMON.replace('-','_')}" -PROTO_B = protocol.HASH -PROTO_B_DAEMON = protocol.DAEMON - - -def client_get_current_period_kind(client) -> dict: - res = client.get_current_period() - return res['voting_period']['kind'] - - -def tenderbake(client: Client): - """Call to 'bake for' that uses the multi-account command for Tenderbake. - - In particular, this allows to never get a 'Delegates do not have enough - voting power' error in sandboxed mode since we bake for all known accounts - (aka all bootstrap accounts) by default in method multibake. - - """ - client.multibake(args=['--minimal-timestamp']) - - -def bake_n_blocks(client: Client, baker: str, n_blocks: int): - for _ in range(n_blocks): - utils.bake(client, bake_for=baker) - - -def bake_until_next_voting_period(client: Client, baker: str, offset: int = 0): - period_info = client.get_current_period() - remaining_blocks = period_info["remaining"] - # if offset is the constant OFFSET, it will take us to - # the middle of the next voting period - bake_n_blocks(client, baker, 1 + remaining_blocks + offset) - - -@pytest.mark.timeout(60) -def wait_until_level(clients, level): - print(f"Waiting until {level}") - for client in clients: - while client.get_level() < level: - time.sleep(1) - - -def assert_all_clients_in_period(clients, period): - for client in clients: - assert client_get_current_period_kind(client) == period - - -@pytest.mark.vote -@pytest.mark.slow -@pytest.mark.baker -@pytest.mark.incremental -class TestVotingFull: - """This tests the migration from PROTO_A to PROTO_B using the voting - procedure. PROTO_A and PROTO_B are the previous and - respectively the current protocol as given by the 'protocol' - module. - - This test advances through all the periods of the voting procedure - until the last one (adoption), by manually baking the right number - of blocks. Once the adoption period is reached, a baker takes over - to bake the remaining blocks of the period. From there the baker - for the next protocol, which was started at the beginning of the - test, takes over. (Bakers are used to make the test more - realistic. However, to be sure that proposals and ballots are - injected at the right moment, manual baking is used instead.) - - This test differs in the following aspects from test_voting.py: - - it uses more nodes, not just one - - it goes through all voting periods, not just the first two - - it uses bakers - - it uses already registered protocols, instead of injecting a - new dummy protocol - """ - - def test_add_initial_nodes(self, sandbox: Sandbox): - for i in range(NUM_NODES): - sandbox.add_node(i, params=constants.NODE_PARAMS) - - def test_activate_proto_a(self, sandbox: Sandbox): - parameters = protocol.get_parameters(protocol.Protocol.PREV) - parameters["blocks_per_voting_period"] = BLOCKS_PER_VOTING_PERIOD - utils.activate_protocol( - sandbox.client(0), - PROTO_A, - parameters=parameters, - activate_in_the_past=True, - ) - - # def test_add_bakers(self, sandbox: Sandbox): - # """Add a baker per node""" - # sandbox.add_baker( - # 1, [f"bootstrap{i}" for i in range(1, 6)], proto=PROTO_B_DAEMON - # ) - - def test_client_knows_proto_b(self, sandbox: Sandbox): - client = sandbox.client(0) - protos = client.list_protocols() - assert PROTO_B in protos - - def test_proposal_period(self, sandbox: Sandbox): - assert_all_clients_in_period(sandbox.all_clients(), 'proposal') - - def test_submit_proto_b_proposal(self, sandbox): - client = sandbox.client(0) - proposals = client.submit_proposals(BAKER, [PROTO_B]) - # bake a block for the submit proposal to be included - bake_n_blocks(client, BAKER, 1) - client.wait_for_inclusion(proposals.operation_hash, check_previous=1) - - def test_check_proto_b_proposed(self, sandbox: Sandbox): - clients = sandbox.all_clients() - wait_until_level(clients, sandbox.client(0).get_level()) - for client in clients: - proposals = client.get_proposals() - assert PROTO_B in [proto for (proto, _) in proposals] - - def test_wait_for_exploration_period(self, sandbox: Sandbox): - client = sandbox.client(0) - bake_until_next_voting_period(client, BAKER, OFFSET) - clients = sandbox.all_clients() - wait_until_level(clients, client.get_level()) - assert_all_clients_in_period(clients, 'exploration') - - def test_delegates_vote_proto_b(self, sandbox: Sandbox): - client = sandbox.client(0) - listings = client.get_listings() - # submit ballot for all bakers with listings - for listing in listings: - client.submit_ballot(listing["pkh"], PROTO_B, 'yay') - - def test_wait_for_cooldown(self, sandbox: Sandbox): - client = sandbox.client(0) - bake_until_next_voting_period(client, BAKER, OFFSET) - clients = sandbox.all_clients() - wait_until_level(clients, client.get_level()) - assert_all_clients_in_period(clients, 'cooldown') - - def test_wait_for_promotion_period(self, sandbox: Sandbox): - client = sandbox.client(0) - bake_until_next_voting_period(client, BAKER, OFFSET) - clients = sandbox.all_clients() - wait_until_level(clients, client.get_level()) - assert_all_clients_in_period(clients, 'promotion') - - def test_vote_in_promotion_phase(self, sandbox: Sandbox): - client = sandbox.client(0) - listings = client.get_listings() - for listing in listings: - client.submit_ballot(listing["pkh"], PROTO_B, 'yay') - - def test_wait_for_adoption(self, sandbox: Sandbox): - client = sandbox.client(0) - bake_until_next_voting_period(client, BAKER) - clients = sandbox.all_clients() - wait_until_level(clients, client.get_level()) - assert_all_clients_in_period(clients, 'adoption') - - @pytest.mark.timeout(60) - def test_all_nodes_run_proto_b(self, sandbox: Sandbox): - # we let a PROTO_A baker bake the last blocks of PROTO_A - # sandbox.add_baker( - # 0, [f"bootstrap{i}" for i in range(1, 6)], proto=PROTO_A_DAEMON - # ) - # for i in range(1,NUM_NODES): - # sandbox.add_baker( - # i, [f"bootstrap{i}"], proto=PROTO_B_DAEMON - # ) - clients = sandbox.all_clients() - client = clients[0] - utils.bake(client, bake_for="bootstrap2") - all_have_proto_b = False - while not all_have_proto_b: - try: - utils.bake(client, bake_for="bootstrap2") - except subprocess.CalledProcessError: - # A fatal error is raised when we do not have enough endorsing - # power. - # This is typical of a simple bake for call in Tenderbake - # Therefore this means we actually have migrated to Tenderbake - # Let's use a baking call that is sure to pass - tenderbake(client) - # either succeeds out of the loop or fails due to the timeout header - client_protocols = [client.get_protocol() for c in clients] - all_have_proto_b = all(p == PROTO_B for p in client_protocols) - time.sleep(POLLING_TIME) - - def test_new_chain_progress(self, sandbox: Sandbox): - # sandbox.rm_baker(0, proto=PROTO_A_DAEMON) - client = sandbox.client(0) - level_before = client.get_level(chain='main') - tenderbake(client) - print(f"level before {level_before}") - assert utils.check_level_greater_than(client, level_before + 1) - - @pytest.mark.xfail - def test_check_logs(self, sandbox: Sandbox): - assert utils.check_logs(sandbox.logs, ERROR_PATTERN) diff --git a/tests_python/tests_alpha/protocol.py b/tests_python/tests_alpha/protocol.py index 34166afbfda8..06e52dccd1cc 100644 --- a/tests_python/tests_alpha/protocol.py +++ b/tests_python/tests_alpha/protocol.py @@ -14,9 +14,9 @@ TENDERBAKE_PARAMETERS['consensus_committee_size'] = 67 FOLDER = constants.ALPHA_FOLDER -PREV_HASH = constants.ITHACA -PREV_DAEMON = constants.ITHACA_DAEMON -PREV_PARAMETERS = constants.ITHACA_PARAMETERS +PREV_HASH = constants.HANGZHOU +PREV_DAEMON = constants.HANGZHOU_DAEMON +PREV_PARAMETERS = constants.HANGZHOU_PARAMETERS def activate( diff --git a/tests_python/tools/constants.py b/tests_python/tools/constants.py index 002aa5d008c7..f398c3dd430e 100644 --- a/tests_python/tools/constants.py +++ b/tests_python/tools/constants.py @@ -102,11 +102,6 @@ HANGZHOU_DAEMON = "011-PtHangz2" HANGZHOU_FOLDER = "proto_011_PtHangz2" HANGZHOU_PARAMETERS = get_parameters(HANGZHOU_FOLDER) -ITHACA = "PsithacaTTq3oumpKDw1pVvRrAtqiK4hKnP3Q4FNrXN9yc6KPhp" -ITHACA_DAEMON = "012-Psithaca" -ITHACA_FOLDER = "proto_012_Psithaca" -ITHACA_PARAMETERS = get_parameters(ITHACA_FOLDER) - TEZOS_CRT = """ Certificate: Data: -- GitLab From 80f9ed5d26ebb8e6cecf323c31068fb587f91255 Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Thu, 16 Dec 2021 23:58:09 +0000 Subject: [PATCH 06/10] Protocol: Ithaca --- docs/012/cli-commands.rst | 41 + docs/012/consensus.rst | 453 ++ docs/012/global_constants.rst | 141 + docs/012/glossary.rst | 179 + docs/012/liquidity_baking.rst | 51 + docs/012/michelson.rst | 3821 ++++++++++ docs/012/plugins.rst | 53 + docs/012/proof_of_stake.rst | 171 + docs/012/protocol.rst | 62 + docs/012/protocol_overview.rst | 112 + docs/012/sapling.rst | 496 ++ docs/012/timelock.rst | 129 + docs/012/voting.rst | 331 + docs/index.rst | 10 + docs/protocols/012_ithaca.rst | 160 + .../final_protocol_versions | 3 +- .../bin_accuser/.ocamlformat | 17 + src/proto_012_PsiThaCa/bin_accuser/dune | 20 + .../bin_accuser/dune-project | 3 + .../bin_accuser/main_accuser_012_PsiThaCa.ml | 38 + .../tezos-accuser-012-PsiThaCa.opam | 20 + src/proto_012_PsiThaCa/bin_baker/.ocamlformat | 17 + src/proto_012_PsiThaCa/bin_baker/dune | 20 + src/proto_012_PsiThaCa/bin_baker/dune-project | 3 + .../bin_baker/main_baker_012_PsiThaCa.ml | 38 + .../bin_baker/tezos-baker-012-PsiThaCa.opam | 20 + .../lib_benchmark/.ocamlformat | 17 + .../lib_benchmark/README.md | 42 + .../lib_benchmark/autocomp.ml | 382 + src/proto_012_PsiThaCa/lib_benchmark/dune | 27 + .../lib_benchmark/dune-project | 3 + .../lib_benchmark/execution_context.ml | 84 + .../lib_benchmark/kernel.ml | 39 + .../lib_benchmark_type_inference/.ocamlformat | 17 + .../lib_benchmark_type_inference/dune | 17 + .../lib_benchmark_type_inference/dune-project | 3 + .../lib_benchmark_type_inference/inference.ml | 1150 +++ .../inference.mli | 145 + .../lib_benchmark_type_inference/int_map.ml | 26 + .../mikhailsky.ml | 422 + .../mikhailsky.mli | 330 + .../mikhailsky_prim.ml | 570 ++ .../lib_benchmark_type_inference/monads.ml | 83 + .../lib_benchmark_type_inference/stores.ml | 85 + .../test/.ocamlformat | 17 + .../lib_benchmark_type_inference/test/dune | 10 + .../test/test_inference.ml | 615 ++ .../test/test_uf.ml | 63 + ...benchmark-type-inference-012-PsiThaCa.opam | 24 + .../lib_benchmark_type_inference/type.ml | 201 + .../lib_benchmark_type_inference/type.mli | 111 + .../lib_benchmark_type_inference/uf.ml | 99 + .../lib_benchmark/micheline_sampler.ml | 110 + .../lib_benchmark/micheline_sampler.mli | 70 + .../lib_benchmark/michelson_mcmc_samplers.ml | 337 + .../lib_benchmark/michelson_mcmc_samplers.mli | 115 + .../lib_benchmark/michelson_samplers.ml | 727 ++ .../lib_benchmark/michelson_samplers.mli | 131 + .../lib_benchmark/michelson_samplers_base.ml | 127 + .../lib_benchmark/michelson_samplers_base.mli | 67 + .../lib_benchmark/mikhailsky_to_michelson.ml | 229 + src/proto_012_PsiThaCa/lib_benchmark/rules.ml | 975 +++ .../lib_benchmark/sampling_helpers.ml | 41 + .../lib_benchmark/state_space.ml | 78 + .../lib_benchmark/test/.ocamlformat | 17 + .../lib_benchmark/test/dune | 41 + .../lib_benchmark/test/test_autocompletion.ml | 120 + .../lib_benchmark/test/test_distribution.ml | 182 + .../lib_benchmark/test/test_helpers.ml | 83 + .../lib_benchmark/test/test_sampling_code.ml | 98 + .../lib_benchmark/test/test_sampling_data.ml | 87 + .../tezos-benchmark-012-PsiThaCa.opam | 32 + .../lib_benchmark/type_helpers.ml | 88 + .../lib_benchmark/type_helpers.mli | 58 + .../lib_benchmarks_proto/.ocamlformat | 17 + .../lib_benchmarks_proto/cache_benchmarks.ml | 195 + .../lib_benchmarks_proto/dune | 31 + .../lib_benchmarks_proto/dune-project | 3 + .../encodings_benchmarks.ml | 432 ++ .../lib_benchmarks_proto/gas_helpers.ml | 36 + .../global_constants_storage_benchmarks.ml | 727 ++ .../interpreter_benchmarks.ml | 3139 ++++++++ .../lib_benchmarks_proto/interpreter_model.ml | 538 ++ .../interpreter_workload.ml | 1562 ++++ .../michelson_commands.ml | 202 + .../michelson_generation.ml | 113 + .../michelson_generation.mli | 61 + .../lib_benchmarks_proto/michelson_types.ml | 138 + .../registration_helpers.ml | 37 + .../sapling_benchmarks.ml | 152 + .../lib_benchmarks_proto/sapling_commands.ml | 134 + .../sapling_generation.ml | 560 ++ .../script_repr_benchmarks.ml | 143 + .../script_typed_ir_size_benchmarks.ml | 338 + .../lib_benchmarks_proto/size.ml | 206 + .../lib_benchmarks_proto/tags.ml | 32 + .../tezos-benchmarks-proto-012-PsiThaCa.opam | 28 + .../translator_benchmarks.ml | 854 +++ .../lib_benchmarks_proto/translator_model.ml | 68 + .../translator_workload.ml | 186 + .../lib_client/.ocamlformat | 17 + .../lib_client/annotated_manager_operation.ml | 123 + .../annotated_manager_operation.mli | 98 + .../lib_client/client_proto_args.ml | 573 ++ .../lib_client/client_proto_args.mli | 141 + .../lib_client/client_proto_context.ml | 747 ++ .../lib_client/client_proto_context.mli | 386 + .../lib_client/client_proto_contracts.ml | 156 + .../lib_client/client_proto_contracts.mli | 74 + .../lib_client/client_proto_fa12.ml | 975 +++ .../lib_client/client_proto_fa12.mli | 161 + .../lib_client/client_proto_multisig.ml | 1210 +++ .../lib_client/client_proto_multisig.mli | 150 + .../lib_client/client_proto_programs.ml | 344 + .../lib_client/client_proto_programs.mli | 204 + .../lib_client/client_proto_utils.ml | 55 + .../lib_client/client_proto_utils.mli | 40 + src/proto_012_PsiThaCa/lib_client/dune | 24 + .../lib_client/dune-project | 3 + .../lib_client/injection.ml | 1071 +++ .../lib_client/injection.mli | 105 + src/proto_012_PsiThaCa/lib_client/light.ml | 37 + src/proto_012_PsiThaCa/lib_client/limit.ml | 64 + src/proto_012_PsiThaCa/lib_client/limit.mli | 49 + .../lib_client/managed_contract.ml | 321 + .../lib_client/managed_contract.mli | 125 + .../lib_client/michelson_v1_emacs.ml | 234 + .../lib_client/michelson_v1_emacs.mli | 39 + .../lib_client/michelson_v1_entrypoints.ml | 216 + .../lib_client/michelson_v1_entrypoints.mli | 108 + .../lib_client/michelson_v1_error_reporter.ml | 767 ++ .../michelson_v1_error_reporter.mli | 32 + .../lib_client/michelson_v1_helpers.ml | 60 + .../lib_client/michelson_v1_macros.ml | 1519 ++++ .../lib_client/michelson_v1_macros.mli | 86 + .../lib_client/michelson_v1_parser.ml | 103 + .../lib_client/michelson_v1_parser.mli | 55 + .../lib_client/michelson_v1_printer.ml | 241 + .../lib_client/michelson_v1_printer.mli | 65 + src/proto_012_PsiThaCa/lib_client/mockup.ml | 1158 +++ .../lib_client/operation_result.ml | 666 ++ .../lib_client/operation_result.mli | 35 + .../lib_client/protocol_client_context.ml | 272 + src/proto_012_PsiThaCa/lib_client/proxy.ml | 184 + .../lib_client/test/.ocamlformat | 17 + .../lib_client/test/assert.ml | 37 + src/proto_012_PsiThaCa/lib_client/test/dune | 17 + .../test/test_client_proto_context.ml | 71 + .../test/test_client_proto_contracts.ml | 94 + .../test/test_michelson_v1_macros.ml | 1345 ++++ .../lib_client/test/test_proxy.ml | 89 + .../lib_client/tezos-client-012-PsiThaCa.opam | 31 + .../lib_client_commands/.ocamlformat | 17 + .../alpha_commands_registration.ml | 38 + .../client_proto_context_commands.ml | 1958 +++++ .../client_proto_contracts_commands.ml | 87 + .../client_proto_fa12_commands.ml | 764 ++ .../client_proto_mockup_commands.ml | 81 + .../client_proto_mockup_commands.mli | 26 + .../client_proto_multisig_commands.ml | 1136 +++ .../client_proto_multisig_commands.mli | 26 + .../client_proto_programs_commands.ml | 966 +++ .../client_proto_programs_commands.mli | 26 + .../client_proto_stresstest_commands.ml | 1004 +++ .../client_proto_utils_commands.ml | 162 + .../client_proto_utils_commands.mli | 26 + .../lib_client_commands/dune | 57 + .../lib_client_commands/dune-project | 3 + ...nt-012-PsiThaCa-commands-registration.opam | 24 + .../tezos-client-012-PsiThaCa-commands.opam | 22 + .../lib_client_sapling/.ocamlformat | 17 + .../client_sapling_commands.ml | 796 ++ .../client_sapling_commands.mli | 23 + .../lib_client_sapling/context.ml | 553 ++ .../lib_client_sapling/context.mli | 157 + .../lib_client_sapling/dune | 19 + .../lib_client_sapling/dune-project | 3 + .../tezos-client-sapling-012-PsiThaCa.opam | 24 + .../lib_client_sapling/wallet.ml | 126 + .../lib_client_sapling/wallet.mli | 75 + .../lib_delegate/.ocamlformat | 17 + .../lib_delegate/abstract_context_index.ml | 35 + .../lib_delegate/abstract_context_index.mli | 31 + .../lib_delegate/baking_actions.ml | 531 ++ .../lib_delegate/baking_actions.mli | 125 + .../lib_delegate/baking_cache.ml | 85 + .../lib_delegate/baking_commands.ml | 374 + .../lib_delegate/baking_commands.mli | 30 + .../baking_commands_registration.ml | 29 + .../lib_delegate/baking_configuration.ml | 310 + .../lib_delegate/baking_configuration.mli | 118 + .../lib_delegate/baking_errors.ml | 65 + .../lib_delegate/baking_events.ml | 789 ++ .../lib_delegate/baking_files.ml | 37 + .../lib_delegate/baking_files.mli | 33 + .../lib_delegate/baking_highwatermarks.ml | 230 + .../lib_delegate/baking_highwatermarks.mli | 91 + .../lib_delegate/baking_lib.ml | 487 ++ .../lib_delegate/baking_lib.mli | 65 + .../lib_delegate/baking_nonces.ml | 321 + .../lib_delegate/baking_nonces.mli | 114 + .../lib_delegate/baking_pow.ml | 85 + .../lib_delegate/baking_pow.mli | 40 + .../lib_delegate/baking_scheduling.ml | 787 ++ .../lib_delegate/baking_scheduling.mli | 83 + .../lib_delegate/baking_simulator.ml | 120 + .../lib_delegate/baking_simulator.mli | 61 + .../lib_delegate/baking_state.ml | 847 ++ .../lib_delegate/baking_state.mli | 226 + .../lib_delegate/block_forge.ml | 360 + .../lib_delegate/block_forge.mli | 63 + .../lib_delegate/client_baking_blocks.ml | 188 + .../lib_delegate/client_baking_blocks.mli | 68 + .../client_baking_denunciation.ml | 489 ++ .../client_baking_denunciation.mli | 31 + .../lib_delegate/client_baking_scheduling.ml | 33 + .../lib_delegate/client_baking_scheduling.mli | 54 + .../lib_delegate/client_daemon.ml | 147 + .../lib_delegate/client_daemon.mli | 53 + .../lib_delegate/context_ops.ml | 108 + .../lib_delegate/delegate_events.ml | 788 ++ src/proto_012_PsiThaCa/lib_delegate/dune | 89 + .../lib_delegate/dune-project | 3 + .../liquidity_baking_vote_file.ml | 162 + .../lib_delegate/logging.ml | 167 + .../lib_delegate/logging.mli | 83 + .../lib_delegate/node_rpc.ml | 200 + .../lib_delegate/node_rpc.mli | 76 + .../lib_delegate/operation_pool.ml | 327 + .../lib_delegate/operation_pool.mli | 123 + .../lib_delegate/operation_selection.ml | 316 + .../lib_delegate/operation_selection.mli | 48 + .../lib_delegate/operation_worker.ml | 658 ++ .../lib_delegate/operation_worker.mli | 94 + .../lib_delegate/state_transitions.ml | 703 ++ .../lib_delegate/state_transitions.mli | 90 + .../lib_delegate/test/.ocamlformat | 17 + .../lib_delegate/test/README.md | 116 + src/proto_012_PsiThaCa/lib_delegate/test/dune | 25 + .../lib_delegate/test/main.ml | 10 + .../test/mockup_simulator/.ocamlformat | 17 + .../mockup_simulator/broadcast_services.ml | 85 + .../lib_delegate/test/mockup_simulator/dune | 24 + .../mockup_simulator/faked_client_context.ml | 163 + .../test/mockup_simulator/faked_daemon.ml | 29 + .../test/mockup_simulator/faked_services.ml | 295 + .../test/mockup_simulator/mockup_simulator.ml | 1285 ++++ .../mockup_simulator/mockup_simulator.mli | 244 + .../lib_delegate/test/test_scenario.ml | 1317 ++++ .../tezos-accuser-012-PsiThaCa-commands.opam | 23 + .../tezos-baking-012-PsiThaCa-commands.opam | 24 + .../tezos-baking-012-PsiThaCa.opam | 33 + .../tezos-endorser-012-PsiThaCa-commands.opam | 23 + .../lib_parameters/.ocamlformat | 17 + .../lib_parameters/default_parameters.ml | 224 + .../lib_parameters/default_parameters.mli | 48 + src/proto_012_PsiThaCa/lib_parameters/dune | 47 + .../lib_parameters/dune-project | 3 + src/proto_012_PsiThaCa/lib_parameters/gen.ml | 62 + ...ezos-protocol-012-PsiThaCa-parameters.opam | 18 + .../lib_plugin/.ocamlformat | 17 + src/proto_012_PsiThaCa/lib_plugin/dune | 27 + .../lib_plugin/dune-project | 3 + src/proto_012_PsiThaCa/lib_plugin/plugin.ml | 3277 ++++++++ .../lib_plugin/plugin_registerer.ml | 31 + .../lib_plugin/test/.ocamlformat | 17 + src/proto_012_PsiThaCa/lib_plugin/test/dune | 16 + .../lib_plugin/test/test_consensus_filter.ml | 499 ++ ...otocol-plugin-012-PsiThaCa-registerer.opam | 18 + .../tezos-protocol-plugin-012-PsiThaCa.opam | 22 + .../lib_protocol/.ocamlformat | 17 + .../lib_protocol/TEZOS_PROTOCOL | 129 + .../lib_protocol/alpha_context.ml | 436 ++ .../lib_protocol/alpha_context.mli | 2436 ++++++ .../lib_protocol/alpha_services.ml | 194 + .../lib_protocol/alpha_services.mli | 81 + .../lib_protocol/amendment.ml | 266 + .../lib_protocol/amendment.mli | 81 + src/proto_012_PsiThaCa/lib_protocol/apply.ml | 2658 +++++++ src/proto_012_PsiThaCa/lib_protocol/apply.mli | 282 + .../lib_protocol/apply_results.ml | 1478 ++++ .../lib_protocol/apply_results.mli | 250 + src/proto_012_PsiThaCa/lib_protocol/baking.ml | 130 + .../lib_protocol/baking.mli | 60 + .../lib_protocol/blinded_public_key_hash.ml | 59 + .../lib_protocol/blinded_public_key_hash.mli | 45 + .../lib_protocol/block_header_repr.ml | 502 ++ .../lib_protocol/block_header_repr.mli | 159 + .../lib_protocol/block_payload_hash.ml | 42 + .../lib_protocol/block_payload_hash.mli | 28 + .../lib_protocol/block_payload_repr.ml | 41 + .../lib_protocol/block_payload_repr.mli | 41 + .../lib_protocol/bootstrap_storage.ml | 120 + .../lib_protocol/bootstrap_storage.mli | 38 + .../lib_protocol/cache_memory_helpers.ml | 168 + .../lib_protocol/cache_repr.ml | 249 + .../lib_protocol/cache_repr.mli | 233 + .../lib_protocol/commitment_repr.ml | 36 + .../lib_protocol/commitment_repr.mli | 31 + .../lib_protocol/commitment_storage.ml | 44 + .../lib_protocol/commitment_storage.mli | 45 + .../lib_protocol/constants_repr.ml | 644 ++ .../lib_protocol/constants_repr.mli | 197 + .../lib_protocol/constants_services.ml | 59 + .../lib_protocol/constants_services.mli | 34 + .../lib_protocol/constants_storage.ml | 150 + .../lib_protocol/constants_storage.mli | 91 + .../lib_protocol/contract_delegate_storage.ml | 83 + .../contract_delegate_storage.mli | 88 + .../lib_protocol/contract_hash.ml | 45 + .../lib_protocol/contract_hash.mli | 29 + .../lib_protocol/contract_manager_storage.ml | 130 + .../lib_protocol/contract_manager_storage.mli | 67 + .../lib_protocol/contract_repr.ml | 214 + .../lib_protocol/contract_repr.mli | 99 + .../lib_protocol/contract_services.ml | 527 ++ .../lib_protocol/contract_services.mli | 126 + .../lib_protocol/contract_storage.ml | 629 ++ .../lib_protocol/contract_storage.mli | 184 + .../lib_protocol/contracts/cpmm.bin | 1 + .../lib_protocol/contracts/cpmm.mligo | 388 + .../lib_protocol/contracts/cpmm.tz | 929 +++ .../lib_protocol/contracts/lqt.bin | 1 + .../lib_protocol/contracts/lqt.mligo | 164 + .../lib_protocol/contracts/lqt.tz | 327 + .../lib_protocol/coq-of-ocaml/README.md | 11 + .../lib_protocol/coq-of-ocaml/config.json | 255 + .../lib_protocol/cycle_repr.ml | 85 + .../lib_protocol/cycle_repr.mli | 61 + .../delegate_activation_storage.ml | 87 + .../delegate_activation_storage.mli | 39 + .../lib_protocol/delegate_services.ml | 418 + .../lib_protocol/delegate_services.mli | 122 + .../lib_protocol/delegate_storage.ml | 908 +++ .../lib_protocol/delegate_storage.mli | 242 + src/proto_012_PsiThaCa/lib_protocol/dune | 1 + .../lib_protocol/dune-project | 3 + src/proto_012_PsiThaCa/lib_protocol/dune.inc | 708 ++ .../lib_protocol/fees_storage.ml | 111 + .../lib_protocol/fees_storage.mli | 77 + .../lib_protocol/fitness_repr.ml | 289 + .../lib_protocol/fitness_repr.mli | 96 + .../lib_protocol/fixed_point_repr.ml | 94 + .../lib_protocol/fixed_point_repr.mli | 105 + .../lib_protocol/frozen_deposits_storage.ml | 61 + .../lib_protocol/frozen_deposits_storage.mli | 52 + .../lib_protocol/gas_limit_repr.ml | 210 + .../lib_protocol/gas_limit_repr.mli | 110 + .../lib_protocol/gas_monad.ml | 53 + .../lib_protocol/gas_monad.mli | 71 + .../lib_protocol/global_constants_costs.ml | 47 + .../lib_protocol/global_constants_costs.mli | 34 + .../lib_protocol/global_constants_storage.ml | 270 + .../lib_protocol/global_constants_storage.mli | 150 + .../lib_protocol/init_storage.ml | 312 + .../lib_protocol/init_storage.mli | 55 + .../lib_protocol/lazy_storage_diff.ml | 439 ++ .../lib_protocol/lazy_storage_diff.mli | 71 + .../lib_protocol/lazy_storage_kind.ml | 325 + .../lib_protocol/lazy_storage_kind.mli | 178 + .../lib_protocol/level_repr.ml | 336 + .../lib_protocol/level_repr.mli | 115 + .../lib_protocol/level_storage.ml | 122 + .../lib_protocol/level_storage.mli | 71 + .../lib_protocol/liquidity_baking_cpmm.ml | 13 + .../lib_protocol/liquidity_baking_lqt.ml | 13 + .../liquidity_baking_migration.ml | 242 + .../liquidity_baking_migration.mli | 33 + .../lib_protocol/liquidity_baking_repr.ml | 71 + .../lib_protocol/liquidity_baking_repr.mli | 36 + .../lib_protocol/local_gas_counter.ml | 99 + src/proto_012_PsiThaCa/lib_protocol/main.ml | 822 ++ src/proto_012_PsiThaCa/lib_protocol/main.mli | 139 + .../lib_protocol/manager_repr.ml | 52 + .../lib_protocol/manager_repr.mli | 38 + .../lib_protocol/michelson_v1_gas.ml | 1809 +++++ .../lib_protocol/michelson_v1_gas.mli | 506 ++ .../lib_protocol/michelson_v1_primitives.ml | 799 ++ .../lib_protocol/michelson_v1_primitives.mli | 230 + .../lib_protocol/migration_repr.ml | 62 + .../lib_protocol/migration_repr.mli | 39 + src/proto_012_PsiThaCa/lib_protocol/misc.ml | 92 + src/proto_012_PsiThaCa/lib_protocol/misc.mli | 51 + .../lib_protocol/non_empty_string.ml | 42 + .../lib_protocol/non_empty_string.mli | 45 + .../lib_protocol/nonce_hash.ml | 45 + .../lib_protocol/nonce_hash.mli | 31 + .../lib_protocol/nonce_storage.ml | 132 + .../lib_protocol/nonce_storage.mli | 60 + .../lib_protocol/operation_repr.ml | 1149 +++ .../lib_protocol/operation_repr.mli | 377 + .../lib_protocol/parameters_repr.ml | 132 + .../lib_protocol/parameters_repr.mli | 57 + .../lib_protocol/path_encoding.ml | 54 + .../lib_protocol/path_encoding.mli | 48 + .../lib_protocol/period_repr.ml | 164 + .../lib_protocol/period_repr.mli | 73 + .../lib_protocol/raw_context.ml | 1295 ++++ .../lib_protocol/raw_context.mli | 320 + .../lib_protocol/raw_context_intf.ml | 260 + .../lib_protocol/raw_level_repr.ml | 108 + .../lib_protocol/raw_level_repr.mli | 64 + .../lib_protocol/receipt_repr.ml | 410 + .../lib_protocol/receipt_repr.mli | 80 + .../lib_protocol/roll_repr_legacy.ml | 60 + .../lib_protocol/roll_repr_legacy.mli | 44 + .../lib_protocol/roll_storage_legacy.ml | 359 + .../lib_protocol/roll_storage_legacy.mli | 173 + .../lib_protocol/round_repr.ml | 429 ++ .../lib_protocol/round_repr.mli | 245 + .../lib_protocol/sampler.ml | 209 + .../lib_protocol/sampler.mli | 98 + .../lib_protocol/sapling_repr.ml | 200 + .../lib_protocol/sapling_services.ml | 103 + .../lib_protocol/sapling_storage.ml | 489 ++ .../lib_protocol/sapling_validator.ml | 108 + .../lib_protocol/saturation_repr.ml | 170 + .../lib_protocol/saturation_repr.mli | 204 + .../lib_protocol/script_cache.ml | 109 + .../lib_protocol/script_cache.mli | 81 + .../lib_protocol/script_comparable.ml | 89 + .../lib_protocol/script_comparable.mli | 29 + .../lib_protocol/script_expr_hash.ml | 44 + .../lib_protocol/script_expr_hash.mli | 31 + .../lib_protocol/script_int_repr.ml | 113 + .../lib_protocol/script_int_repr.mli | 161 + .../lib_protocol/script_interpreter.ml | 1798 +++++ .../lib_protocol/script_interpreter.mli | 168 + .../lib_protocol/script_interpreter_defs.ml | 855 +++ .../lib_protocol/script_ir_annot.ml | 528 ++ .../lib_protocol/script_ir_annot.mli | 230 + .../lib_protocol/script_ir_translator.ml | 6787 +++++++++++++++++ .../lib_protocol/script_ir_translator.mli | 502 ++ .../lib_protocol/script_list.ml | 32 + .../lib_protocol/script_list.mli | 31 + .../lib_protocol/script_map.ml | 97 + .../lib_protocol/script_map.mli | 49 + .../lib_protocol/script_repr.ml | 353 + .../lib_protocol/script_repr.mli | 130 + .../lib_protocol/script_set.ml | 75 + .../lib_protocol/script_set.mli | 37 + .../lib_protocol/script_string_repr.ml | 77 + .../lib_protocol/script_string_repr.mli | 46 + .../lib_protocol/script_tc_errors.ml | 201 + .../script_tc_errors_registration.ml | 805 ++ .../script_tc_errors_registration.mli | 34 + .../lib_protocol/script_timestamp_repr.ml | 55 + .../lib_protocol/script_timestamp_repr.mli | 68 + .../lib_protocol/script_typed_ir.ml | 2201 ++++++ .../lib_protocol/script_typed_ir.mli | 1594 ++++ .../lib_protocol/script_typed_ir_size.ml | 741 ++ .../lib_protocol/script_typed_ir_size.mli | 71 + .../script_typed_ir_size_costs.ml | 34 + .../script_typed_ir_size_costs.mli | 28 + .../lib_protocol/seed_repr.ml | 150 + .../lib_protocol/seed_repr.mli | 111 + .../lib_protocol/seed_storage.ml | 127 + .../lib_protocol/seed_storage.mli | 47 + .../lib_protocol/services_registration.ml | 122 + .../lib_protocol/services_registration.mli | 127 + .../lib_protocol/slot_repr.ml | 138 + .../lib_protocol/slot_repr.mli | 63 + .../lib_protocol/stake_storage.ml | 325 + .../lib_protocol/stake_storage.mli | 126 + .../lib_protocol/state_hash.ml | 44 + .../lib_protocol/state_hash.mli | 30 + .../lib_protocol/storage.ml | 1616 ++++ .../lib_protocol/storage.mli | 693 ++ .../lib_protocol/storage_costs.ml | 43 + .../lib_protocol/storage_costs.mli | 30 + .../lib_protocol/storage_description.ml | 388 + .../lib_protocol/storage_description.mli | 93 + .../lib_protocol/storage_functors.ml | 1123 +++ .../lib_protocol/storage_functors.mli | 122 + .../lib_protocol/storage_sigs.ml | 418 + .../lib_protocol/test/.ocamlformat | 17 + .../test/contracts/big_interpreter_stack.tz | 5 + .../test/contracts/sapling_contract.tz | 69 + .../test/contracts/sapling_contract_double.tz | 33 + .../test/contracts/sapling_contract_drop.tz | 14 + .../test/contracts/sapling_contract_send.tz | 20 + .../sapling_contract_state_as_arg.tz | 18 + .../contracts/sapling_push_sapling_state.tz | 11 + .../contracts/sapling_use_existing_state.tz | 12 + .../test/contracts/temp_big_maps.tz | 81 + .../lib_protocol/test/contracts/timelock.tz | 31 + src/proto_012_PsiThaCa/lib_protocol/test/dune | 80 + .../lib_protocol/test/helpers/.ocamlformat | 17 + .../lib_protocol/test/helpers/README.md | 3 + .../lib_protocol/test/helpers/account.ml | 115 + .../lib_protocol/test/helpers/account.mli | 68 + .../lib_protocol/test/helpers/assert.ml | 178 + .../lib_protocol/test/helpers/block.ml | 759 ++ .../lib_protocol/test/helpers/block.mli | 258 + .../test/helpers/consensus_helpers.ml | 108 + .../lib_protocol/test/helpers/context.ml | 368 + .../lib_protocol/test/helpers/context.mli | 188 + .../test/helpers/contract_helpers.ml | 101 + .../lib_protocol/test/helpers/cpmm_logic.ml | 102 + .../lib_protocol/test/helpers/cpmm_repr.ml | 384 + .../lib_protocol/test/helpers/dune | 24 + .../lib_protocol/test/helpers/dune-project | 3 + .../test/helpers/error_monad_operators.ml | 11 + .../lib_protocol/test/helpers/expr.ml | 50 + .../lib_protocol/test/helpers/expr_common.ml | 82 + .../lib_protocol/test/helpers/incremental.ml | 224 + .../lib_protocol/test/helpers/incremental.mli | 62 + .../helpers/liquidity_baking_generator.ml | 351 + .../helpers/liquidity_baking_generator.mli | 77 + .../test/helpers/liquidity_baking_machine.ml | 1364 ++++ .../test/helpers/liquidity_baking_machine.mli | 387 + .../test/helpers/lqt_fa12_repr.ml | 252 + .../lib_protocol/test/helpers/nonce.ml | 35 + .../lib_protocol/test/helpers/nonce.mli | 33 + .../lib_protocol/test/helpers/op.ml | 476 ++ .../lib_protocol/test/helpers/op.mli | 175 + .../lib_protocol/test/helpers/rewards.ml | 1641 ++++ .../test/helpers/sapling_helpers.ml | 397 + .../test/helpers/script_big_map.ml | 30 + .../test/helpers/script_big_map.mli | 44 + .../lib_protocol/test/helpers/script_list.ml | 29 + .../lib_protocol/test/helpers/script_list.mli | 28 + .../lib_protocol/test/helpers/script_map.ml | 36 + .../lib_protocol/test/helpers/script_map.mli | 31 + .../lib_protocol/test/helpers/script_set.ml | 31 + .../lib_protocol/test/helpers/script_set.mli | 32 + .../test/helpers/test_global_constants.ml | 327 + .../lib_protocol/test/helpers/test_tez.ml | 70 + .../lib_protocol/test/helpers/testable.ml | 38 + .../tezos-012-PsiThaCa-test-helpers.opam | 25 + .../lib_protocol/test/liquidity_baking_pbt.ml | 299 + .../lib_protocol/test/main.ml | 82 + .../lib_protocol/test/saturation_fuzzing.ml | 183 + .../lib_protocol/test/test_activation.ml | 587 ++ .../lib_protocol/test/test_baking.ml | 455 ++ .../test/test_combined_operations.ml | 335 + .../lib_protocol/test/test_constants.ml | 87 + .../lib_protocol/test/test_deactivation.ml | 351 + .../lib_protocol/test/test_delegation.ml | 1580 ++++ .../lib_protocol/test/test_double_baking.ml | 365 + .../test/test_double_endorsement.ml | 513 ++ .../test/test_double_preendorsement.ml | 337 + .../lib_protocol/test/test_endorsement.ml | 594 ++ .../lib_protocol/test/test_failing_noop.ml | 62 + .../lib_protocol/test/test_fitness.ml | 157 + .../lib_protocol/test/test_fixed_point.ml | 174 + .../lib_protocol/test/test_frozen_deposits.ml | 631 ++ .../lib_protocol/test/test_gas_costs.ml | 289 + .../lib_protocol/test/test_gas_levels.ml | 481 ++ .../lib_protocol/test/test_gas_properties.ml | 139 + .../test/test_global_constants_storage.ml | 138 + .../lib_protocol/test/test_helpers_rpcs.ml | 69 + .../lib_protocol/test/test_interpretation.ml | 304 + .../test/test_lazy_storage_diff.ml | 141 + .../lib_protocol/test/test_level_module.ml | 275 + .../test/test_liquidity_baking.ml | 562 ++ .../lib_protocol/test/test_origination.ml | 240 + .../lib_protocol/test/test_participation.ml | 208 + .../lib_protocol/test/test_preendorsement.ml | 228 + .../test/test_preendorsement_functor.ml | 266 + .../lib_protocol/test/test_qty.ml | 159 + .../lib_protocol/test/test_receipt.ml | 93 + .../lib_protocol/test/test_reveal.ml | 109 + .../lib_protocol/test/test_round_repr.ml | 541 ++ .../lib_protocol/test/test_sampler.ml | 270 + .../lib_protocol/test/test_sapling.ml | 1126 +++ .../lib_protocol/test/test_saturation.ml | 218 + .../test/test_script_comparison.ml | 369 + .../test/test_script_typed_ir_size.ml | 400 + .../lib_protocol/test/test_seed.ml | 252 + .../lib_protocol/test/test_storage.ml | 224 + .../lib_protocol/test/test_temp_big_maps.ml | 100 + .../lib_protocol/test/test_tez_repr.ml | 140 + .../test/test_ticket_balance_key.ml | 497 ++ .../lib_protocol/test/test_ticket_scanner.ml | 593 ++ .../lib_protocol/test/test_ticket_storage.ml | 288 + .../lib_protocol/test/test_time_repr.ml | 44 + .../lib_protocol/test/test_timelock.ml | 168 + .../lib_protocol/test/test_token.ml | 732 ++ .../lib_protocol/test/test_transfer.ml | 801 ++ .../lib_protocol/test/test_typechecking.ml | 915 +++ .../lib_protocol/test/test_voting.ml | 1167 +++ .../lib_protocol/test/unit/.ocamlformat | 17 + .../lib_protocol/test/unit/dune | 20 + .../lib_protocol/test/unit/main.ml | 60 + .../test/unit/test_alpha_context.ml | 129 + .../test/unit/test_contract_repr.ml | 161 + .../unit/test_global_constants_storage.ml | 413 + .../test/unit/test_operation_repr.ml | 112 + .../test/unit/test_raw_level_repr.ml | 176 + .../lib_protocol/test/unit/test_tez_repr.ml | 202 + .../lib_protocol/tez_repr.ml | 245 + .../lib_protocol/tez_repr.mli | 75 + .../tezos-embedded-protocol-012-PsiThaCa.opam | 25 + .../tezos-protocol-012-PsiThaCa-tests.opam | 36 + .../tezos-protocol-012-PsiThaCa.opam | 23 + .../tezos-protocol-functor-012-PsiThaCa.opam | 24 + .../lib_protocol/ticket_balance_key.ml | 70 + .../lib_protocol/ticket_balance_key.mli | 40 + .../lib_protocol/ticket_costs.ml | 52 + .../lib_protocol/ticket_costs.mli | 53 + .../lib_protocol/ticket_scanner.ml | 515 ++ .../lib_protocol/ticket_scanner.mli | 55 + .../lib_protocol/ticket_storage.ml | 119 + .../lib_protocol/ticket_storage.mli | 71 + .../lib_protocol/time_repr.ml | 73 + .../lib_protocol/time_repr.mli | 55 + src/proto_012_PsiThaCa/lib_protocol/token.ml | 266 + src/proto_012_PsiThaCa/lib_protocol/token.mli | 134 + .../lib_protocol/vote_repr.ml | 42 + .../lib_protocol/vote_repr.mli | 33 + .../lib_protocol/vote_storage.ml | 169 + .../lib_protocol/vote_storage.mli | 116 + .../lib_protocol/voting_period_repr.ml | 175 + .../lib_protocol/voting_period_repr.mli | 82 + .../lib_protocol/voting_period_storage.ml | 191 + .../lib_protocol/voting_period_storage.mli | 51 + .../lib_protocol/voting_services.ml | 152 + .../lib_protocol/voting_services.mli | 60 + src/proto_012_PsiThaCa/parameters/dune | 4 + tests_python/contracts_012/attic/accounts.tz | 54 + tests_python/contracts_012/attic/add1.tz | 7 + tests_python/contracts_012/attic/add1_list.tz | 6 + .../contracts_012/attic/after_strategy.tz | 3 + tests_python/contracts_012/attic/always.tz | 4 + tests_python/contracts_012/attic/append.tz | 8 + tests_python/contracts_012/attic/at_least.tz | 6 + tests_python/contracts_012/attic/auction.tz | 8 + .../contracts_012/attic/bad_lockup.tz | 6 + .../contracts_012/attic/big_map_union.tz | 8 + .../contracts_012/attic/cadr_annotation.tz | 3 + tests_python/contracts_012/attic/concat.tz | 7 + .../contracts_012/attic/conditionals.tz | 9 + .../contracts_012/attic/cons_twice.tz | 9 + tests_python/contracts_012/attic/cps_fact.tz | 16 + .../contracts_012/attic/create_add1_lists.tz | 14 + .../contracts_012/attic/data_publisher.tz | 8 + tests_python/contracts_012/attic/dispatch.tz | 9 + tests_python/contracts_012/attic/empty.tz | 3 + .../contracts_012/attic/fail_amount.tz | 6 + tests_python/contracts_012/attic/faucet.tz | 7 + tests_python/contracts_012/attic/forward.tz | 150 + tests_python/contracts_012/attic/id.tz | 3 + .../contracts_012/attic/infinite_loop.tz | 3 + .../contracts_012/attic/insertion_sort.tz | 16 + .../contracts_012/attic/int_publisher.tz | 17 + .../contracts_012/attic/king_of_tez.tz | 19 + .../attic/list_of_transactions.tz | 8 + tests_python/contracts_012/attic/queue.tz | 24 + .../contracts_012/attic/reduce_map.tz | 16 + .../contracts_012/attic/reentrancy.tz | 7 + tests_python/contracts_012/attic/reservoir.tz | 25 + .../attic/scrutable_reservoir.tz | 67 + .../contracts_012/attic/spawn_identities.tz | 20 + .../entrypoints/big_map_entrypoints.tz | 31 + .../entrypoints/delegatable_target.tz | 79 + .../contracts_012/entrypoints/manager.tz | 31 + .../entrypoints/no_default_target.tz | 11 + .../entrypoints/no_entrypoint_target.tz | 11 + .../entrypoints/rooted_target.tz | 11 + .../entrypoints/simple_entrypoints.tz | 4 + .../contracts_012/ill_typed/badly_indented.tz | 3 + .../contracts_012/ill_typed/big_dip.tz | 4 + .../contracts_012/ill_typed/big_drop.tz | 4 + .../contracts_012/ill_typed/big_map_arity.tz | 5 + .../contracts_012/ill_typed/chain_id_arity.tz | 3 + tests_python/contracts_012/ill_typed/comb0.tz | 3 + tests_python/contracts_012/ill_typed/comb1.tz | 3 + .../ill_typed/contract_annotation_default.tz | 11 + .../contracts_012/ill_typed/dip_failwith.tz | 4 + tests_python/contracts_012/ill_typed/dup0.tz | 3 + .../ill_typed/failwith_big_map.tz | 22 + .../ill_typed/invalid_self_entrypoint.tz | 10 + .../contracts_012/ill_typed/map_failwith.tz | 4 + .../ill_typed/missing_only_code_field.tz | 2 + .../ill_typed/missing_only_parameter_field.tz | 4 + .../ill_typed/missing_only_storage_field.tz | 4 + .../missing_parameter_and_storage_fields.tz | 3 + .../ill_typed/multiple_code_field.tz | 6 + .../ill_typed/multiple_parameter_field.tz | 6 + .../multiple_storage_and_code_fields.tz | 7 + .../ill_typed/multiple_storage_field.tz | 6 + .../contracts_012/ill_typed/never_literal.tz | 6 + .../contracts_012/ill_typed/pack_big_map.tz | 7 + .../contracts_012/ill_typed/pack_operation.tz | 20 + .../ill_typed/pack_sapling_state.tz | 13 + .../push_big_map_with_id_with_parens.tz | 10 + .../push_big_map_with_id_without_parens.tz | 11 + ...ng_build_empty_state_with_int_parameter.tz | 10 + .../ill_typed/set_update_non_comparable.tz | 9 + .../ill_typed/stack_bottom_undig2able.tz | 5 + .../ill_typed/stack_bottom_undigable.tz | 6 + .../ill_typed/stack_bottom_undip2able.tz | 6 + .../ill_typed/stack_bottom_undipable.tz | 5 + .../ill_typed/stack_bottom_undropable.tz | 5 + .../ill_typed/stack_bottom_undug2able.tz | 5 + .../ill_typed/stack_bottom_undugable.tz | 6 + .../ill_typed/stack_bottom_undup2able.tz | 5 + .../ill_typed/stack_bottom_unfailwithable.tz | 6 + .../ill_typed/stack_bottom_ungetable.tz | 6 + .../ill_typed/stack_bottom_unleftable.tz | 6 + .../ill_typed/stack_bottom_unpairable.tz | 6 + .../ill_typed/stack_bottom_unpopable.tz | 10 + .../stack_bottom_unpopable_in_lambda.tz | 10 + .../ill_typed/stack_bottom_unrightable.tz | 6 + .../contracts_012/ill_typed/ticket_apply.tz | 17 + .../contracts_012/ill_typed/ticket_dup.tz | 3 + .../ill_typed/ticket_in_ticket.tz | 16 + .../contracts_012/ill_typed/ticket_unpack.tz | 5 + .../contracts_012/ill_typed/uncomb0.tz | 3 + .../contracts_012/ill_typed/uncomb1.tz | 3 + .../ill_typed/unpack_sapling_state.tz | 12 + .../unpair_field_annotation_mismatch.tz | 10 + .../view_op_bad_name_invalid_char_set.tz | 3 + .../view_op_bad_name_invalid_type.tz | 3 + .../view_op_bad_name_non_printable_char.tz | 3 + .../ill_typed/view_op_bad_name_too_long.tz | 4 + .../ill_typed/view_op_bad_return_type.tz | 3 + .../ill_typed/view_op_dupable_type.tz | 3 + .../ill_typed/view_op_invalid_arity.tz | 3 + .../ill_typed/view_op_lazy_storage.tz | 8 + .../ill_typed/view_op_lazy_storage_type.tz | 8 + .../ill_typed/view_toplevel_bad_input_type.tz | 4 + ...view_toplevel_bad_name_invalid_char_set.tz | 5 + .../view_toplevel_bad_name_invalid_type.tz | 4 + ...ew_toplevel_bad_name_non_printable_char.tz | 4 + .../view_toplevel_bad_name_too_long.tz | 4 + .../view_toplevel_bad_return_type.tz | 4 + .../ill_typed/view_toplevel_bad_type.tz | 7 + .../view_toplevel_dupable_type_input.tz | 5 + .../view_toplevel_dupable_type_output.tz | 4 + .../view_toplevel_duplicated_name.tz | 5 + .../ill_typed/view_toplevel_invalid_arity.tz | 4 + .../view_toplevel_lazy_storage_input.tz | 4 + .../view_toplevel_lazy_storage_output.tz | 4 + .../contracts_012/legacy/create_account.tz | 29 + .../contracts_012/legacy/create_contract.tz | 18 + .../legacy/create_contract_flags.tz | 26 + .../legacy/create_contract_rootname.tz | 18 + .../contracts_012/legacy/originator.tz | 16 + .../contracts_012/legacy/steps_to_quota.tz | 12 + tests_python/contracts_012/macros/assert.tz | 3 + .../contracts_012/macros/assert_cmpeq.tz | 3 + .../contracts_012/macros/assert_cmpge.tz | 3 + .../contracts_012/macros/assert_cmpgt.tz | 3 + .../contracts_012/macros/assert_cmple.tz | 3 + .../contracts_012/macros/assert_cmplt.tz | 3 + .../contracts_012/macros/assert_cmpneq.tz | 3 + .../contracts_012/macros/assert_eq.tz | 3 + .../contracts_012/macros/assert_ge.tz | 3 + .../contracts_012/macros/assert_gt.tz | 3 + .../contracts_012/macros/assert_le.tz | 3 + .../contracts_012/macros/assert_lt.tz | 3 + .../contracts_012/macros/assert_neq.tz | 3 + .../contracts_012/macros/big_map_get_add.tz | 7 + .../contracts_012/macros/big_map_mem.tz | 5 + .../contracts_012/macros/build_list.tz | 6 + .../contracts_012/macros/carn_and_cdrn.tz | 26 + tests_python/contracts_012/macros/compare.tz | 9 + .../contracts_012/macros/compare_bytes.tz | 9 + tests_python/contracts_012/macros/fail.tz | 5 + .../contracts_012/macros/guestbook.tz | 10 + .../contracts_012/macros/macro_annotations.tz | 6 + .../contracts_012/macros/map_caddaadr.tz | 4 + .../contracts_012/macros/max_in_list.tz | 9 + tests_python/contracts_012/macros/min.tz | 11 + .../contracts_012/macros/pair_macro.tz | 6 + .../contracts_012/macros/set_caddaadr.tz | 5 + .../contracts_012/macros/take_my_money.tz | 9 + .../contracts_012/macros/unpair_macro.tz | 9 + .../mini_scenarios/authentication.tz | 30 + .../mini_scenarios/big_map_entrypoints.tz | 31 + .../mini_scenarios/big_map_magic.tz | 41 + .../mini_scenarios/big_map_read.tz | 9 + .../mini_scenarios/big_map_store.tz | 8 + .../mini_scenarios/big_map_write.tz | 10 + .../mini_scenarios/create_contract.tz | 33 + .../mini_scenarios/create_contract_simple.tz | 14 + .../mini_scenarios/default_account.tz | 9 + .../execution_order_appender.tz | 17 + .../mini_scenarios/execution_order_caller.tz | 17 + .../mini_scenarios/execution_order_storer.tz | 4 + .../mini_scenarios/fa12_reference.tz | 749 ++ .../mini_scenarios/generic_multisig.tz | 92 + .../contracts_012/mini_scenarios/groth16.tz | 74 + .../contracts_012/mini_scenarios/hardlimit.tz | 5 + .../mini_scenarios/legacy_multisig.tz | 78 + .../contracts_012/mini_scenarios/lockup.tz | 19 + .../mini_scenarios/lqt_fa12.mligo.tz | 328 + .../mini_scenarios/multiple_en2.tz | 77 + .../multiple_entrypoints_counter.tz | 29 + .../mini_scenarios/parameterized_multisig.tz | 24 + .../contracts_012/mini_scenarios/replay.tz | 8 + .../mini_scenarios/reveal_signed_preimage.tz | 13 + .../mini_scenarios/self_address_receiver.tz | 12 + .../mini_scenarios/self_address_sender.tz | 17 + .../mini_scenarios/ticket_builder_fungible.tz | 40 + .../ticket_builder_non_fungible.tz | 47 + .../mini_scenarios/ticket_wallet_fungible.tz | 88 + .../ticket_wallet_non_fungible.tz | 61 + .../mini_scenarios/tzip4_view.tz | 7 + .../mini_scenarios/vote_for_delegate.tz | 30 + .../mini_scenarios/weather_insurance.tz | 19 + .../contracts_012/mini_scenarios/xcat.tz | 48 + .../contracts_012/mini_scenarios/xcat_dapp.tz | 79 + .../contracts_012/non_regression/bug_262.tz | 5 + .../non_regression/pairk_annot.tz | 7 + tests_python/contracts_012/opcodes/abs.tz | 5 + tests_python/contracts_012/opcodes/add.tz | 25 + .../contracts_012/opcodes/add_bls12_381_fr.tz | 3 + .../contracts_012/opcodes/add_bls12_381_g1.tz | 3 + .../contracts_012/opcodes/add_bls12_381_g2.tz | 3 + .../opcodes/add_delta_timestamp.tz | 3 + .../opcodes/add_timestamp_delta.tz | 3 + tests_python/contracts_012/opcodes/address.tz | 3 + .../opcodes/amount_after_fib_view.tz | 24 + .../opcodes/amount_after_nonexistent_view.tz | 23 + .../opcodes/amount_after_view.tz | 26 + tests_python/contracts_012/opcodes/and.tz | 3 + .../contracts_012/opcodes/and_binary.tz | 27 + .../contracts_012/opcodes/and_logical_1.tz | 3 + tests_python/contracts_012/opcodes/balance.tz | 3 + .../opcodes/balance_after_fib_view.tz | 25 + .../opcodes/balance_after_nonexistent_view.tz | 22 + .../opcodes/balance_after_view.tz | 25 + .../contracts_012/opcodes/big_map_mem_nat.tz | 7 + .../opcodes/big_map_mem_string.tz | 7 + .../contracts_012/opcodes/big_map_to_self.tz | 22 + .../bls12_381_fr_push_bytes_not_padded.tz | 9 + .../opcodes/bls12_381_fr_push_nat.tz | 9 + .../opcodes/bls12_381_fr_to_int.tz | 8 + .../opcodes/bls12_381_fr_to_mutez.tz | 12 + .../opcodes/bls12_381_fr_z_int.tz | 8 + .../opcodes/bls12_381_fr_z_nat.tz | 8 + .../opcodes/bls12_381_z_fr_int.tz | 9 + .../opcodes/bls12_381_z_fr_nat.tz | 9 + tests_python/contracts_012/opcodes/bytes.tz | 11 + tests_python/contracts_012/opcodes/car.tz | 3 + tests_python/contracts_012/opcodes/cdr.tz | 3 + .../contracts_012/opcodes/chain_id.tz | 3 + .../contracts_012/opcodes/chain_id_store.tz | 3 + .../contracts_012/opcodes/check_signature.tz | 10 + .../contracts_012/opcodes/comb-get.tz | 27 + .../contracts_012/opcodes/comb-literals.tz | 9 + .../contracts_012/opcodes/comb-set-2.tz | 10 + .../contracts_012/opcodes/comb-set.tz | 10 + tests_python/contracts_012/opcodes/comb.tz | 9 + tests_python/contracts_012/opcodes/compare.tz | 52 + .../contracts_012/opcodes/compare_big_type.tz | 20 + .../opcodes/compare_big_type2.tz | 22 + .../contracts_012/opcodes/comparisons.tz | 15 + .../contracts_012/opcodes/concat_hello.tz | 4 + .../opcodes/concat_hello_bytes.tz | 4 + .../contracts_012/opcodes/concat_list.tz | 5 + tests_python/contracts_012/opcodes/cons.tz | 3 + .../contracts_012/opcodes/contains_all.tz | 7 + .../contracts_012/opcodes/contract.tz | 11 + .../contracts_012/opcodes/create_contract.tz | 14 + .../opcodes/create_contract_rootname.tz | 15 + .../opcodes/create_contract_rootname_alt.tz | 14 + .../opcodes/create_contract_with_view.tz | 17 + .../contracts_012/opcodes/diff_timestamps.tz | 3 + tests_python/contracts_012/opcodes/dig_eq.tz | 14 + tests_python/contracts_012/opcodes/dign.tz | 3 + tests_python/contracts_012/opcodes/dip.tz | 8 + tests_python/contracts_012/opcodes/dipn.tz | 3 + tests_python/contracts_012/opcodes/dropn.tz | 3 + tests_python/contracts_012/opcodes/dugn.tz | 3 + tests_python/contracts_012/opcodes/dup-n.tz | 18 + tests_python/contracts_012/opcodes/ediv.tz | 13 + .../contracts_012/opcodes/ediv_mutez.tz | 12 + .../contracts_012/opcodes/empty_map.tz | 6 + .../contracts_012/opcodes/exec_concat.tz | 7 + tests_python/contracts_012/opcodes/first.tz | 3 + .../opcodes/get_and_update_big_map.tz | 9 + .../opcodes/get_and_update_map.tz | 9 + .../opcodes/get_big_map_value.tz | 6 + .../contracts_012/opcodes/get_map_value.tz | 3 + .../opcodes/hash_consistency_checker.tz | 3 + .../contracts_012/opcodes/hash_key.tz | 3 + .../contracts_012/opcodes/hash_string.tz | 3 + tests_python/contracts_012/opcodes/if.tz | 3 + tests_python/contracts_012/opcodes/if_some.tz | 3 + tests_python/contracts_012/opcodes/int.tz | 5 + .../contracts_012/opcodes/iter_fail.tz | 4 + tests_python/contracts_012/opcodes/keccak.tz | 8 + .../contracts_012/opcodes/left_right.tz | 3 + tests_python/contracts_012/opcodes/level.tz | 3 + .../contracts_012/opcodes/list_concat.tz | 3 + .../opcodes/list_concat_bytes.tz | 3 + tests_python/contracts_012/opcodes/list_id.tz | 3 + .../contracts_012/opcodes/list_id_map.tz | 3 + .../contracts_012/opcodes/list_iter.tz | 5 + .../contracts_012/opcodes/list_map_block.tz | 5 + .../contracts_012/opcodes/list_size.tz | 3 + .../contracts_012/opcodes/loop_failwith.tz | 4 + .../contracts_012/opcodes/loop_left.tz | 7 + .../opcodes/loop_left_failwith.tz | 4 + tests_python/contracts_012/opcodes/map_car.tz | 5 + tests_python/contracts_012/opcodes/map_id.tz | 3 + .../contracts_012/opcodes/map_iter.tz | 7 + tests_python/contracts_012/opcodes/map_map.tz | 8 + .../opcodes/map_map_sideeffect.tz | 12 + .../contracts_012/opcodes/map_mem_nat.tz | 7 + .../contracts_012/opcodes/map_mem_string.tz | 7 + .../contracts_012/opcodes/map_size.tz | 3 + .../opcodes/merge_comparable_pairs.tz | 14 + tests_python/contracts_012/opcodes/mul.tz | 48 + .../contracts_012/opcodes/mul_bls12_381_fr.tz | 3 + .../contracts_012/opcodes/mul_bls12_381_g1.tz | 3 + .../contracts_012/opcodes/mul_bls12_381_g2.tz | 3 + .../contracts_012/opcodes/mul_overflow.tz | 18 + tests_python/contracts_012/opcodes/munch.tz | 14 + .../opcodes/mutez_to_bls12_381_fr.tz | 14 + tests_python/contracts_012/opcodes/neg.tz | 8 + .../contracts_012/opcodes/neg_bls12_381_fr.tz | 3 + .../contracts_012/opcodes/neg_bls12_381_g1.tz | 3 + .../contracts_012/opcodes/neg_bls12_381_g2.tz | 3 + tests_python/contracts_012/opcodes/none.tz | 3 + tests_python/contracts_012/opcodes/noop.tz | 3 + tests_python/contracts_012/opcodes/not.tz | 3 + .../contracts_012/opcodes/not_binary.tz | 12 + tests_python/contracts_012/opcodes/or.tz | 3 + .../contracts_012/opcodes/or_binary.tz | 9 + .../opcodes/originate_big_map.tz | 3 + .../contracts_012/opcodes/packunpack.tz | 6 + .../contracts_012/opcodes/packunpack_rev.tz | 43 + .../opcodes/packunpack_rev_cty.tz | 31 + tests_python/contracts_012/opcodes/pair_id.tz | 3 + .../contracts_012/opcodes/pairing_check.tz | 3 + tests_python/contracts_012/opcodes/pexec.tz | 6 + tests_python/contracts_012/opcodes/pexec_2.tz | 11 + tests_python/contracts_012/opcodes/proxy.tz | 13 + tests_python/contracts_012/opcodes/ret_int.tz | 3 + tests_python/contracts_012/opcodes/reverse.tz | 5 + .../contracts_012/opcodes/reverse_loop.tz | 5 + .../opcodes/sapling_empty_state.tz | 3 + tests_python/contracts_012/opcodes/self.tz | 3 + .../contracts_012/opcodes/self_address.tz | 11 + .../opcodes/self_address_after_fib_view.tz | 25 + .../self_address_after_nonexistent_view.tz | 26 + .../opcodes/self_address_after_view.tz | 24 + .../opcodes/self_after_fib_view.tz | 27 + .../opcodes/self_after_nonexistent_view.tz | 28 + .../contracts_012/opcodes/self_after_view.tz | 26 + .../opcodes/self_with_default_entrypoint.tz | 19 + .../opcodes/self_with_entrypoint.tz | 26 + tests_python/contracts_012/opcodes/sender.tz | 8 + .../opcodes/sender_after_fib_view.tz | 26 + .../opcodes/sender_after_nonexistent_view.tz | 25 + .../opcodes/sender_after_view.tz | 25 + tests_python/contracts_012/opcodes/set_car.tz | 3 + tests_python/contracts_012/opcodes/set_cdr.tz | 3 + .../contracts_012/opcodes/set_delegate.tz | 9 + tests_python/contracts_012/opcodes/set_id.tz | 3 + .../contracts_012/opcodes/set_iter.tz | 3 + .../contracts_012/opcodes/set_member.tz | 3 + .../contracts_012/opcodes/set_size.tz | 3 + tests_python/contracts_012/opcodes/sets.tz | 40 + tests_python/contracts_012/opcodes/sha3.tz | 8 + tests_python/contracts_012/opcodes/shifts.tz | 18 + tests_python/contracts_012/opcodes/slice.tz | 5 + .../contracts_012/opcodes/slice_bytes.tz | 5 + tests_python/contracts_012/opcodes/slices.tz | 11 + tests_python/contracts_012/opcodes/source.tz | 10 + .../contracts_012/opcodes/split_bytes.tz | 16 + .../contracts_012/opcodes/split_string.tz | 16 + .../opcodes/store_bls12_381_fr.tz | 3 + .../opcodes/store_bls12_381_g1.tz | 3 + .../opcodes/store_bls12_381_g2.tz | 3 + .../contracts_012/opcodes/store_input.tz | 3 + .../contracts_012/opcodes/store_now.tz | 3 + tests_python/contracts_012/opcodes/str_id.tz | 3 + .../opcodes/sub_timestamp_delta.tz | 3 + tests_python/contracts_012/opcodes/subset.tz | 12 + .../contracts_012/opcodes/tez_add_sub.tz | 5 + .../contracts_012/opcodes/ticket_bad.tz | 5 + .../contracts_012/opcodes/ticket_big_store.tz | 3 + .../contracts_012/opcodes/ticket_join.tz | 7 + .../contracts_012/opcodes/ticket_read.tz | 8 + .../contracts_012/opcodes/ticket_split.tz | 11 + .../contracts_012/opcodes/ticket_store-2.tz | 3 + .../contracts_012/opcodes/ticket_store.tz | 3 + .../contracts_012/opcodes/ticketer-2.tz | 9 + .../contracts_012/opcodes/ticketer.tz | 10 + .../contracts_012/opcodes/transfer_amount.tz | 3 + .../contracts_012/opcodes/transfer_tokens.tz | 5 + tests_python/contracts_012/opcodes/uncomb.tz | 8 + tests_python/contracts_012/opcodes/unpair.tz | 71 + .../contracts_012/opcodes/update_big_map.tz | 6 + .../contracts_012/opcodes/utxo_read.tz | 9 + tests_python/contracts_012/opcodes/utxor.tz | 24 + .../contracts_012/opcodes/view_fib.tz | 9 + .../opcodes/view_mutual_recursion.tz | 11 + .../contracts_012/opcodes/view_op_add.tz | 3 + .../contracts_012/opcodes/view_op_constant.tz | 3 + .../contracts_012/opcodes/view_op_id.tz | 4 + .../opcodes/view_op_nonexistent_addr.tz | 5 + .../opcodes/view_op_nonexistent_func.tz | 3 + .../opcodes/view_op_test_step_contants.tz | 8 + ...iew_op_toplevel_inconsistent_input_type.tz | 3 + ...ew_op_toplevel_inconsistent_output_type.tz | 3 + .../contracts_012/opcodes/view_rec.tz | 12 + .../opcodes/view_toplevel_lib.tz | 67 + .../contracts_012/opcodes/voting_power.tz | 7 + tests_python/contracts_012/opcodes/xor.tz | 13 + tests_python/tests_012/__init__.py | 0 ...contract.TestNormalize::test_normalize.out | 8 + ...tNormalize::test_normalize_legacy_flag.out | 8 + ...Normalize::test_normalize_script[None].out | 10 + ...lize::test_normalize_script[Optimized].out | 10 + ...est_normalize_script[Optimized_legacy].out | 12 + ...alize::test_normalize_script[Readable].out | 10 + ...e_type[list (pair nat int bool bytes)].out | 3 + ...rmalize_type[list (pair nat int bool)].out | 3 + ...st_normalize_type[list (pair nat int)].out | 3 + ...rmalize::test_normalize_type[list nat].out | 3 + ...estNormalize::test_normalize_type[nat].out | 3 + ...ormalize_type[pair nat int bool bytes].out | 3 + ...test_normalize_type[pair nat int bool].out | 3 + ...ize::test_normalize_type[pair nat int].out | 3 + ...e::test_normalize_unparsing_mode[None].out | 3 + ...st_normalize_unparsing_mode[Optimized].out | 3 + ...alize_unparsing_mode[Optimized_legacy].out | 5 + ...est_normalize_unparsing_mode[Readable].out | 3 + ..._hash[client_regtest_custom_scrubber0].out | 301 + ...st_contract_hash[opcodes--view_fac.tz].out | 3 + ...st_contract_hash[opcodes--view_fib.tz].out | 3 + ...ash[opcodes--view_mutual_recursion.tz].out | 3 + ...contract_hash[opcodes--view_op_add.tz].out | 3 + ..._contract_hash[opcodes--view_op_id.tz].out | 3 + ...[opcodes--view_op_nonexistent_addr.tz].out | 3 + ...[opcodes--view_op_nonexistent_func.tz].out | 3 + ...pcodes--view_op_test_step_contants.tz].out | 3 + ...p_toplevel_inconsistent_input_type.tz].out | 3 + ..._toplevel_inconsistent_output_type.tz].out | 3 + ...st_contract_hash[opcodes--view_rec.tz].out | 3 + ...ct_hash[opcodes--view_toplevel_lib.tz].out | 3 + ...::test_self_address_originate_receiver.out | 53 + ...er::test_self_address_originate_sender.out | 52 + ...ddressTransfer::test_send_self_address.out | 42 + ...ck::test_typecheck[attic--accounts.tz].out | 379 + ...echeck::test_typecheck[attic--add1.tz].out | 16 + ...k::test_typecheck[attic--add1_list.tz].out | 14 + ...st_typecheck[attic--after_strategy.tz].out | 27 + ...heck::test_typecheck[attic--always.tz].out | 18 + ...heck::test_typecheck[attic--append.tz].out | 22 + ...ck::test_typecheck[attic--at_least.tz].out | 18 + ...eck::test_typecheck[attic--auction.tz].out | 87 + ...::test_typecheck[attic--bad_lockup.tz].out | 71 + ...est_typecheck[attic--big_map_union.tz].out | 34 + ...t_typecheck[attic--cadr_annotation.tz].out | 17 + ...heck::test_typecheck[attic--concat.tz].out | 28 + ...test_typecheck[attic--conditionals.tz].out | 20 + ...::test_typecheck[attic--cons_twice.tz].out | 23 + ...ck::test_typecheck[attic--cps_fact.tz].out | 71 + ...typecheck[attic--create_add1_lists.tz].out | 30 + ...st_typecheck[attic--data_publisher.tz].out | 80 + ...ck::test_typecheck[attic--dispatch.tz].out | 54 + ...check::test_typecheck[attic--empty.tz].out | 12 + ...:test_typecheck[attic--fail_amount.tz].out | 20 + ...heck::test_typecheck[attic--faucet.tz].out | 35 + ...eck::test_typecheck[attic--forward.tz].out | 1920 +++++ ...ypecheck::test_typecheck[attic--id.tz].out | 12 + ...est_typecheck[attic--infinite_loop.tz].out | 18 + ...st_typecheck[attic--insertion_sort.tz].out | 63 + ...est_typecheck[attic--int_publisher.tz].out | 105 + ...:test_typecheck[attic--king_of_tez.tz].out | 79 + ...echeck[attic--list_of_transactions.tz].out | 49 + ...check::test_typecheck[attic--queue.tz].out | 111 + ...::test_typecheck[attic--reduce_map.tz].out | 58 + ...::test_typecheck[attic--reentrancy.tz].out | 49 + ...k::test_typecheck[attic--reservoir.tz].out | 100 + ...pecheck[attic--scrutable_reservoir.tz].out | 273 + ..._typecheck[attic--spawn_identities.tz].out | 71 + ...eck::test_typecheck[macros--assert.tz].out | 15 + ...est_typecheck[macros--assert_cmpeq.tz].out | 21 + ...est_typecheck[macros--assert_cmpge.tz].out | 21 + ...est_typecheck[macros--assert_cmpgt.tz].out | 21 + ...est_typecheck[macros--assert_cmple.tz].out | 21 + ...est_typecheck[macros--assert_cmplt.tz].out | 21 + ...st_typecheck[macros--assert_cmpneq.tz].out | 21 + ...::test_typecheck[macros--assert_eq.tz].out | 23 + ...::test_typecheck[macros--assert_ge.tz].out | 23 + ...::test_typecheck[macros--assert_gt.tz].out | 23 + ...::test_typecheck[macros--assert_le.tz].out | 23 + ...::test_typecheck[macros--assert_lt.tz].out | 23 + ...:test_typecheck[macros--assert_neq.tz].out | 23 + ..._typecheck[macros--big_map_get_add.tz].out | 71 + ...test_typecheck[macros--big_map_mem.tz].out | 31 + ...:test_typecheck[macros--build_list.tz].out | 45 + ...st_typecheck[macros--carn_and_cdrn.tz].out | 47 + ...ck::test_typecheck[macros--compare.tz].out | 97 + ...st_typecheck[macros--compare_bytes.tz].out | 97 + ...check::test_typecheck[macros--fail.tz].out | 5 + ...::test_typecheck[macros--guestbook.tz].out | 36 + ...ypecheck[macros--macro_annotations.tz].out | 24 + ...est_typecheck[macros--map_caddaadr.tz].out | 18 + ...test_typecheck[macros--max_in_list.tz].out | 29 + ...echeck::test_typecheck[macros--min.tz].out | 23 + ...:test_typecheck[macros--pair_macro.tz].out | 26 + ...est_typecheck[macros--set_caddaadr.tz].out | 52 + ...st_typecheck[macros--take_my_money.tz].out | 26 + ...est_typecheck[macros--unpair_macro.tz].out | 32 + ...eck[mini_scenarios--authentication.tz].out | 47 + ...ini_scenarios--big_map_entrypoints.tz].out | 132 + ...heck[mini_scenarios--big_map_magic.tz].out | 106 + ...check[mini_scenarios--big_map_read.tz].out | 17 + ...heck[mini_scenarios--big_map_store.tz].out | 14 + ...heck[mini_scenarios--big_map_write.tz].out | 21 + ...ck[mini_scenarios--create_contract.tz].out | 75 + ..._scenarios--create_contract_simple.tz].out | 29 + ...ck[mini_scenarios--default_account.tz].out | 26 + ...cenarios--execution_order_appender.tz].out | 34 + ..._scenarios--execution_order_caller.tz].out | 25 + ..._scenarios--execution_order_storer.tz].out | 16 + ...eck[mini_scenarios--fa12_reference.tz].out | 2761 +++++++ ...k[mini_scenarios--generic_multisig.tz].out | 438 ++ ..._typecheck[mini_scenarios--groth16.tz].out | 233 + ...ypecheck[mini_scenarios--hardlimit.tz].out | 18 + ...ck[mini_scenarios--legacy_multisig.tz].out | 501 ++ ...t_typecheck[mini_scenarios--lockup.tz].out | 48 + ...eck[mini_scenarios--lqt_fa12.mligo.tz].out | 2834 +++++++ ...check[mini_scenarios--multiple_en2.tz].out | 205 + ...rios--multiple_entrypoints_counter.tz].out | 180 + ..._scenarios--parameterized_multisig.tz].out | 173 + ...t_typecheck[mini_scenarios--replay.tz].out | 33 + ..._scenarios--reveal_signed_preimage.tz].out | 70 + ...i_scenarios--self_address_receiver.tz].out | 19 + ...ini_scenarios--self_address_sender.tz].out | 24 + ...scenarios--ticket_builder_fungible.tz].out | 71 + ...arios--ticket_builder_non_fungible.tz].out | 73 + ..._scenarios--ticket_wallet_fungible.tz].out | 224 + ...narios--ticket_wallet_non_fungible.tz].out | 132 + ...pecheck[mini_scenarios--tzip4_view.tz].out | 56 + ...[mini_scenarios--vote_for_delegate.tz].out | 168 + ...[mini_scenarios--weather_insurance.tz].out | 259 + ...est_typecheck[mini_scenarios--xcat.tz].out | 93 + ...ypecheck[mini_scenarios--xcat_dapp.tz].out | 612 ++ ..._typecheck[non_regression--bug_262.tz].out | 18 + ...echeck[non_regression--pairk_annot.tz].out | 32 + ...check::test_typecheck[opcodes--abs.tz].out | 23 + ...check::test_typecheck[opcodes--add.tz].out | 84 + ...ypecheck[opcodes--add_bls12_381_fr.tz].out | 18 + ...ypecheck[opcodes--add_bls12_381_g1.tz].out | 18 + ...ypecheck[opcodes--add_bls12_381_g2.tz].out | 18 + ...check[opcodes--add_delta_timestamp.tz].out | 22 + ...check[opcodes--add_timestamp_delta.tz].out | 22 + ...k::test_typecheck[opcodes--address.tz].out | 16 + ...eck[opcodes--amount_after_fib_view.tz].out | 38 + ...des--amount_after_nonexistent_view.tz].out | 37 + ...pecheck[opcodes--amount_after_view.tz].out | 39 + ...check::test_typecheck[opcodes--and.tz].out | 22 + ...test_typecheck[opcodes--and_binary.tz].out | 50 + ...t_typecheck[opcodes--and_logical_1.tz].out | 16 + ...k::test_typecheck[opcodes--balance.tz].out | 14 + ...ck[opcodes--balance_after_fib_view.tz].out | 38 + ...es--balance_after_nonexistent_view.tz].out | 37 + ...echeck[opcodes--balance_after_view.tz].out | 39 + ...typecheck[opcodes--big_map_mem_nat.tz].out | 22 + ...echeck[opcodes--big_map_mem_string.tz].out | 25 + ...typecheck[opcodes--big_map_to_self.tz].out | 59 + ...bls12_381_fr_push_bytes_not_padded.tz].out | 16 + ...eck[opcodes--bls12_381_fr_push_nat.tz].out | 16 + ...check[opcodes--bls12_381_fr_to_int.tz].out | 14 + ...eck[opcodes--bls12_381_fr_to_mutez.tz].out | 21 + ...echeck[opcodes--bls12_381_fr_z_int.tz].out | 14 + ...echeck[opcodes--bls12_381_fr_z_nat.tz].out | 14 + ...echeck[opcodes--bls12_381_z_fr_int.tz].out | 16 + ...echeck[opcodes--bls12_381_z_fr_nat.tz].out | 16 + ...eck::test_typecheck[opcodes--bytes.tz].out | 12 + ...check::test_typecheck[opcodes--car.tz].out | 14 + ...check::test_typecheck[opcodes--cdr.tz].out | 14 + ...::test_typecheck[opcodes--chain_id.tz].out | 16 + ..._typecheck[opcodes--chain_id_store.tz].out | 16 + ...typecheck[opcodes--check_signature.tz].out | 42 + ...::test_typecheck[opcodes--comb-get.tz].out | 51 + ...t_typecheck[opcodes--comb-literals.tz].out | 17 + ...test_typecheck[opcodes--comb-set-2.tz].out | 26 + ...::test_typecheck[opcodes--comb-set.tz].out | 28 + ...heck::test_typecheck[opcodes--comb.tz].out | 18 + ...k::test_typecheck[opcodes--compare.tz].out | 217 + ...ypecheck[opcodes--compare_big_type.tz].out | 3737 +++++++++ ...pecheck[opcodes--compare_big_type2.tz].out | 4302 +++++++++++ ...est_typecheck[opcodes--comparisons.tz].out | 65 + ...st_typecheck[opcodes--concat_hello.tz].out | 17 + ...echeck[opcodes--concat_hello_bytes.tz].out | 14 + ...est_typecheck[opcodes--concat_list.tz].out | 30 + ...heck::test_typecheck[opcodes--cons.tz].out | 14 + ...st_typecheck[opcodes--contains_all.tz].out | 79 + ...::test_typecheck[opcodes--contract.tz].out | 19 + ...typecheck[opcodes--create_contract.tz].out | 27 + ...[opcodes--create_contract_rootname.tz].out | 29 + ...odes--create_contract_rootname_alt.tz].out | 29 + ...opcodes--create_contract_with_view.tz].out | 30 + ...typecheck[opcodes--diff_timestamps.tz].out | 20 + ...ck::test_typecheck[opcodes--dig_eq.tz].out | 157 + ...heck::test_typecheck[opcodes--dign.tz].out | 24 + ...check::test_typecheck[opcodes--dip.tz].out | 20 + ...heck::test_typecheck[opcodes--dipn.tz].out | 32 + ...eck::test_typecheck[opcodes--dropn.tz].out | 22 + ...heck::test_typecheck[opcodes--dugn.tz].out | 30 + ...eck::test_typecheck[opcodes--dup-n.tz].out | 51 + ...heck::test_typecheck[opcodes--ediv.tz].out | 70 + ...test_typecheck[opcodes--ediv_mutez.tz].out | 30 + ...:test_typecheck[opcodes--empty_map.tz].out | 22 + ...est_typecheck[opcodes--exec_concat.tz].out | 34 + ...eck::test_typecheck[opcodes--first.tz].out | 13 + ...ck[opcodes--get_and_update_big_map.tz].out | 15 + ...echeck[opcodes--get_and_update_map.tz].out | 15 + ...pecheck[opcodes--get_big_map_value.tz].out | 24 + ...t_typecheck[opcodes--get_map_value.tz].out | 22 + ...[opcodes--hash_consistency_checker.tz].out | 16 + ...::test_typecheck[opcodes--hash_key.tz].out | 16 + ...est_typecheck[opcodes--hash_string.tz].out | 16 + ...echeck::test_typecheck[opcodes--if.tz].out | 15 + ...k::test_typecheck[opcodes--if_some.tz].out | 13 + ...check::test_typecheck[opcodes--int.tz].out | 16 + ...:test_typecheck[opcodes--iter_fail.tz].out | 14 + ...ck::test_typecheck[opcodes--keccak.tz].out | 16 + ...test_typecheck[opcodes--left_right.tz].out | 15 + ...eck::test_typecheck[opcodes--level.tz].out | 14 + ...est_typecheck[opcodes--list_concat.tz].out | 18 + ...pecheck[opcodes--list_concat_bytes.tz].out | 18 + ...k::test_typecheck[opcodes--list_id.tz].out | 12 + ...est_typecheck[opcodes--list_id_map.tz].out | 14 + ...:test_typecheck[opcodes--list_iter.tz].out | 18 + ..._typecheck[opcodes--list_map_block.tz].out | 25 + ...:test_typecheck[opcodes--list_size.tz].out | 14 + ...t_typecheck[opcodes--loop_failwith.tz].out | 14 + ...:test_typecheck[opcodes--loop_left.tz].out | 41 + ...echeck[opcodes--loop_left_failwith.tz].out | 14 + ...k::test_typecheck[opcodes--map_car.tz].out | 21 + ...ck::test_typecheck[opcodes--map_id.tz].out | 12 + ...::test_typecheck[opcodes--map_iter.tz].out | 47 + ...k::test_typecheck[opcodes--map_map.tz].out | 23 + ...echeck[opcodes--map_map_sideeffect.tz].out | 36 + ...est_typecheck[opcodes--map_mem_nat.tz].out | 22 + ..._typecheck[opcodes--map_mem_string.tz].out | 22 + ...::test_typecheck[opcodes--map_size.tz].out | 14 + ...ck[opcodes--merge_comparable_pairs.tz].out | 31 + ...check::test_typecheck[opcodes--mul.tz].out | 82 + ...ypecheck[opcodes--mul_bls12_381_fr.tz].out | 18 + ...ypecheck[opcodes--mul_bls12_381_g1.tz].out | 18 + ...ypecheck[opcodes--mul_bls12_381_g2.tz].out | 18 + ...st_typecheck[opcodes--mul_overflow.tz].out | 29 + ...eck::test_typecheck[opcodes--munch.tz].out | 13 + ...eck[opcodes--mutez_to_bls12_381_fr.tz].out | 25 + ...check::test_typecheck[opcodes--neg.tz].out | 13 + ...ypecheck[opcodes--neg_bls12_381_fr.tz].out | 16 + ...ypecheck[opcodes--neg_bls12_381_g1.tz].out | 16 + ...ypecheck[opcodes--neg_bls12_381_g2.tz].out | 16 + ...heck::test_typecheck[opcodes--none.tz].out | 14 + ...heck::test_typecheck[opcodes--noop.tz].out | 12 + ...check::test_typecheck[opcodes--not.tz].out | 16 + ...test_typecheck[opcodes--not_binary.tz].out | 15 + ...echeck::test_typecheck[opcodes--or.tz].out | 24 + ...:test_typecheck[opcodes--or_binary.tz].out | 18 + ...pecheck[opcodes--originate_big_map.tz].out | 12 + ...test_typecheck[opcodes--packunpack.tz].out | 27 + ..._typecheck[opcodes--packunpack_rev.tz].out | 171 + ...echeck[opcodes--packunpack_rev_cty.tz].out | 614 ++ ...k::test_typecheck[opcodes--pair_id.tz].out | 14 + ...t_typecheck[opcodes--pairing_check.tz].out | 16 + ...eck::test_typecheck[opcodes--pexec.tz].out | 23 + ...k::test_typecheck[opcodes--pexec_2.tz].out | 41 + ...eck::test_typecheck[opcodes--proxy.tz].out | 20 + ...k::test_typecheck[opcodes--ret_int.tz].out | 16 + ...k::test_typecheck[opcodes--reverse.tz].out | 18 + ...st_typecheck[opcodes--reverse_loop.tz].out | 32 + ...check[opcodes--sapling_empty_state.tz].out | 14 + ...heck::test_typecheck[opcodes--self.tz].out | 16 + ...st_typecheck[opcodes--self_address.tz].out | 28 + ...codes--self_address_after_fib_view.tz].out | 38 + ...elf_address_after_nonexistent_view.tz].out | 36 + ...k[opcodes--self_address_after_view.tz].out | 39 + ...check[opcodes--self_after_fib_view.tz].out | 40 + ...codes--self_after_nonexistent_view.tz].out | 39 + ...typecheck[opcodes--self_after_view.tz].out | 41 + ...odes--self_with_default_entrypoint.tz].out | 31 + ...heck[opcodes--self_with_entrypoint.tz].out | 70 + ...ck::test_typecheck[opcodes--sender.tz].out | 14 + ...eck[opcodes--sender_after_fib_view.tz].out | 38 + ...des--sender_after_nonexistent_view.tz].out | 36 + ...pecheck[opcodes--sender_after_view.tz].out | 39 + ...k::test_typecheck[opcodes--set_car.tz].out | 19 + ...k::test_typecheck[opcodes--set_cdr.tz].out | 19 + ...st_typecheck[opcodes--set_delegate.tz].out | 16 + ...ck::test_typecheck[opcodes--set_id.tz].out | 12 + ...::test_typecheck[opcodes--set_iter.tz].out | 18 + ...test_typecheck[opcodes--set_member.tz].out | 36 + ...::test_typecheck[opcodes--set_size.tz].out | 14 + ...heck::test_typecheck[opcodes--sets.tz].out | 68 + ...heck::test_typecheck[opcodes--sha3.tz].out | 16 + ...ck::test_typecheck[opcodes--shifts.tz].out | 17 + ...eck::test_typecheck[opcodes--slice.tz].out | 22 + ...est_typecheck[opcodes--slice_bytes.tz].out | 22 + ...ck::test_typecheck[opcodes--slices.tz].out | 156 + ...ck::test_typecheck[opcodes--source.tz].out | 14 + ...est_typecheck[opcodes--split_bytes.tz].out | 72 + ...st_typecheck[opcodes--split_string.tz].out | 72 + ...echeck[opcodes--store_bls12_381_fr.tz].out | 14 + ...echeck[opcodes--store_bls12_381_g1.tz].out | 14 + ...echeck[opcodes--store_bls12_381_g2.tz].out | 14 + ...est_typecheck[opcodes--store_input.tz].out | 12 + ...:test_typecheck[opcodes--store_now.tz].out | 14 + ...ck::test_typecheck[opcodes--str_id.tz].out | 14 + ...check[opcodes--sub_timestamp_delta.tz].out | 20 + ...ck::test_typecheck[opcodes--subset.tz].out | 46 + ...est_typecheck[opcodes--tez_add_sub.tz].out | 37 + ...test_typecheck[opcodes--ticket_bad.tz].out | 12 + ...ypecheck[opcodes--ticket_big_store.tz].out | 24 + ...est_typecheck[opcodes--ticket_join.tz].out | 23 + ...est_typecheck[opcodes--ticket_read.tz].out | 24 + ...st_typecheck[opcodes--ticket_split.tz].out | 39 + ..._typecheck[opcodes--ticket_store-2.tz].out | 12 + ...st_typecheck[opcodes--ticket_store.tz].out | 14 + ...test_typecheck[opcodes--ticketer-2.tz].out | 35 + ...::test_typecheck[opcodes--ticketer.tz].out | 37 + ...typecheck[opcodes--transfer_amount.tz].out | 14 + ...typecheck[opcodes--transfer_tokens.tz].out | 24 + ...ck::test_typecheck[opcodes--uncomb.tz].out | 28 + ...ck::test_typecheck[opcodes--unpair.tz].out | 322 + ..._typecheck[opcodes--update_big_map.tz].out | 18 + ...:test_typecheck[opcodes--utxo_read.tz].out | 26 + ...eck::test_typecheck[opcodes--utxor.tz].out | 109 + ...::test_typecheck[opcodes--view_fib.tz].out | 18 + ...eck[opcodes--view_mutual_recursion.tz].out | 22 + ...est_typecheck[opcodes--view_op_add.tz].out | 17 + ...ypecheck[opcodes--view_op_constant.tz].out | 17 + ...test_typecheck[opcodes--view_op_id.tz].out | 17 + ...[opcodes--view_op_nonexistent_addr.tz].out | 21 + ...[opcodes--view_op_nonexistent_func.tz].out | 19 + ...pcodes--view_op_test_step_contants.tz].out | 19 + ...p_toplevel_inconsistent_input_type.tz].out | 17 + ..._toplevel_inconsistent_output_type.tz].out | 19 + ...::test_typecheck[opcodes--view_rec.tz].out | 33 + ...pecheck[opcodes--view_toplevel_lib.tz].out | 148 + ...st_typecheck[opcodes--voting_power.tz].out | 20 + ...check::test_typecheck[opcodes--xor.tz].out | 17 + ...81.TestBls12_381::test_add_one_one[Fr].out | 9 + ...81.TestBls12_381::test_add_one_one[G1].out | 9 + ...81.TestBls12_381::test_add_one_one[G2].out | 9 + ...TestBls12_381::test_add_one_random[Fr].out | 72 + ...TestBls12_381::test_add_one_random[G1].out | 72 + ...TestBls12_381::test_add_one_random[G2].out | 72 + ...1.TestBls12_381::test_add_one_zero[Fr].out | 9 + ...1.TestBls12_381::test_add_one_zero[G1].out | 9 + ...1.TestBls12_381::test_add_one_zero[G2].out | 9 + ...TestBls12_381::test_add_random_one[Fr].out | 72 + ...TestBls12_381::test_add_random_one[G1].out | 72 + ...TestBls12_381::test_add_random_one[G2].out | 72 + ...tBls12_381::test_add_random_random[Fr].out | 72 + ...tBls12_381::test_add_random_random[G1].out | 72 + ...tBls12_381::test_add_random_random[G2].out | 72 + ...estBls12_381::test_add_random_zero[Fr].out | 72 + ...estBls12_381::test_add_random_zero[G1].out | 72 + ...estBls12_381::test_add_random_zero[G2].out | 72 + ...1.TestBls12_381::test_add_zero_one[Fr].out | 9 + ...1.TestBls12_381::test_add_zero_one[G1].out | 9 + ...1.TestBls12_381::test_add_zero_one[G2].out | 9 + ...estBls12_381::test_add_zero_random[Fr].out | 72 + ...estBls12_381::test_add_zero_random[G1].out | 72 + ...estBls12_381::test_add_zero_random[G2].out | 72 + ....TestBls12_381::test_add_zero_zero[Fr].out | 9 + ....TestBls12_381::test_add_zero_zero[G1].out | 9 + ....TestBls12_381::test_add_zero_zero[G2].out | 9 + ...fr_bytes_parameters_more_than_32_bytes.out | 8 + ..._bls12_381.TestBls12_381::test_groth16.out | 9 + ...81.TestBls12_381::test_mul_one_one[Fr].out | 9 + ...81.TestBls12_381::test_mul_one_one[G1].out | 9 + ...81.TestBls12_381::test_mul_one_one[G2].out | 9 + ...TestBls12_381::test_mul_one_random[Fr].out | 72 + ...TestBls12_381::test_mul_one_random[G1].out | 72 + ...TestBls12_381::test_mul_one_random[G2].out | 72 + ...1.TestBls12_381::test_mul_one_zero[Fr].out | 9 + ...1.TestBls12_381::test_mul_one_zero[G1].out | 9 + ...1.TestBls12_381::test_mul_one_zero[G2].out | 9 + ...TestBls12_381::test_mul_random_one[Fr].out | 72 + ...TestBls12_381::test_mul_random_one[G1].out | 72 + ...TestBls12_381::test_mul_random_one[G2].out | 72 + ...tBls12_381::test_mul_random_random[Fr].out | 72 + ...tBls12_381::test_mul_random_random[G1].out | 72 + ...tBls12_381::test_mul_random_random[G2].out | 72 + ...estBls12_381::test_mul_random_zero[Fr].out | 72 + ...estBls12_381::test_mul_random_zero[G1].out | 72 + ...estBls12_381::test_mul_random_zero[G2].out | 72 + ...1.TestBls12_381::test_mul_zero_one[Fr].out | 9 + ...1.TestBls12_381::test_mul_zero_one[G1].out | 9 + ...1.TestBls12_381::test_mul_zero_one[G2].out | 9 + ...estBls12_381::test_mul_zero_random[Fr].out | 72 + ...estBls12_381::test_mul_zero_random[G1].out | 72 + ...estBls12_381::test_mul_zero_random[G2].out | 72 + ....TestBls12_381::test_mul_zero_zero[Fr].out | 9 + ....TestBls12_381::test_mul_zero_zero[G1].out | 9 + ....TestBls12_381::test_mul_zero_zero[G2].out | 9 + ...12_381.TestBls12_381::test_neg_one[Fr].out | 9 + ...12_381.TestBls12_381::test_neg_one[G1].out | 9 + ...12_381.TestBls12_381::test_neg_one[G2].out | 9 + ...381.TestBls12_381::test_neg_random[Fr].out | 72 + ...381.TestBls12_381::test_neg_random[G1].out | 72 + ...381.TestBls12_381::test_neg_random[G2].out | 72 + ...2_381.TestBls12_381::test_neg_zero[Fr].out | 9 + ...2_381.TestBls12_381::test_neg_zero[G1].out | 9 + ...2_381.TestBls12_381::test_neg_zero[G2].out | 9 + ...381.TestBls12_381::test_pairing_neg_g1.out | 72 + ...381.TestBls12_381::test_pairing_neg_g2.out | 72 + ...12_381.TestBls12_381::test_pairing_nil.out | 9 + ...81.TestBls12_381::test_pairing_one_one.out | 9 + ...TestBls12_381::test_pairing_one_random.out | 72 + ...1.TestBls12_381::test_pairing_one_zero.out | 9 + ...TestBls12_381::test_pairing_random_one.out | 72 + ...tBls12_381::test_pairing_random_random.out | 72 + ...estBls12_381::test_pairing_random_zero.out | 72 + ...1.TestBls12_381::test_pairing_zero_one.out | 9 + ...estBls12_381::test_pairing_zero_random.out | 72 + ....TestBls12_381::test_pairing_zero_zero.out | 9 + ...tBls12_381::test_signature_aggregation.out | 142 + ..._381.TestBls12_381::test_store_one[Fr].out | 9 + ..._381.TestBls12_381::test_store_one[G1].out | 9 + ..._381.TestBls12_381::test_store_one[G2].out | 9 + ...1.TestBls12_381::test_store_random[Fr].out | 72 + ...1.TestBls12_381::test_store_random[G1].out | 72 + ...1.TestBls12_381::test_store_random[G2].out | 72 + ...381.TestBls12_381::test_store_zero[Fr].out | 9 + ...381.TestBls12_381::test_store_zero[G1].out | 9 + ...381.TestBls12_381::test_store_zero[G2].out | 9 + ...est_macro_expansion[macros--assert.tz].out | 9 + ...cro_expansion[macros--assert_cmpeq.tz].out | 12 + ...cro_expansion[macros--assert_cmpge.tz].out | 12 + ...cro_expansion[macros--assert_cmpgt.tz].out | 12 + ...cro_expansion[macros--assert_cmple.tz].out | 12 + ...cro_expansion[macros--assert_cmplt.tz].out | 12 + ...ro_expansion[macros--assert_cmpneq.tz].out | 12 + ..._macro_expansion[macros--assert_eq.tz].out | 13 + ..._macro_expansion[macros--assert_ge.tz].out | 13 + ..._macro_expansion[macros--assert_gt.tz].out | 13 + ..._macro_expansion[macros--assert_le.tz].out | 13 + ..._macro_expansion[macros--assert_lt.tz].out | 13 + ...macro_expansion[macros--assert_neq.tz].out | 13 + ..._expansion[macros--big_map_get_add.tz].out | 23 + ...acro_expansion[macros--big_map_mem.tz].out | 14 + ...macro_expansion[macros--build_list.tz].out | 24 + ...ro_expansion[macros--carn_and_cdrn.tz].out | 29 + ...st_macro_expansion[macros--compare.tz].out | 22 + ...ro_expansion[macros--compare_bytes.tz].out | 22 + ...:test_macro_expansion[macros--fail.tz].out | 3 + ..._macro_expansion[macros--guestbook.tz].out | 18 + ...xpansion[macros--macro_annotations.tz].out | 13 + ...cro_expansion[macros--map_caddaadr.tz].out | 40 + ...acro_expansion[macros--max_in_list.tz].out | 17 + ...::test_macro_expansion[macros--min.tz].out | 13 + ...macro_expansion[macros--pair_macro.tz].out | 18 + ...cro_expansion[macros--set_caddaadr.tz].out | 33 + ...ro_expansion[macros--take_my_money.tz].out | 14 + ...cro_expansion[macros--unpair_macro.tz].out | 20 + ...ination::test_big_map_origination_diff.out | 29 + ...igination::test_big_map_origination_id.out | 27 + ...tion::test_big_map_origination_literal.out | 50 + ...rigination::test_big_map_transfer_diff.out | 23 + ...pOrigination::test_big_map_transfer_id.out | 22 + ...s.TestContractOnchainLevel::test_level.out | 123 + ...actOnchainOpcodes::test_contract_fails.out | 2 + ...tContractOnchainOpcodes::test_gen_keys.out | 2 + ...ontractOnchainOpcodes::test_init_proxy.out | 53 + ...s.TestContractOnchainOpcodes::test_now.out | 2 + ....TestContractOnchainOpcodes::test_self.out | 2 + ...estContractOnchainOpcodes::test_sender.out | 2 + ...tractOnchainOpcodes::test_set_delegate.out | 123 + ...TestContractOnchainOpcodes::test_slice.out | 87 + ...\"spsig1PPUFZucuAQybs5wsqs.818025e860.out" | 66 + ...0e55c43a9a857214d8761e67b75.2d6806d54e.out | 66 + ...0e55c43a9a857214d8761e67b75.378d03ae2d.out | 66 + ...0e55c43a9a857214d8761e67b75.57fdc7ad1c.out | 66 + ...0e55c43a9a857214d8761e67b75.c583c796bf.out | 66 + ...ef0e55c43a9a857214d8761e67b.7da5c9014e.out | 46 + ...estContractOnchainOpcodes::test_source.out | 119 + ...ntractOnchainOpcodes::test_split_bytes.out | 139 + ...tractOnchainOpcodes::test_split_string.out | 139 + ...ntractOnchainOpcodes::test_store_input.out | 185 + ...trace_origination[compare_big_type.tz].out | 93 + ...race_origination[compare_big_type2.tz].out | 97 + ...ctOnchainOpcodes::test_transfer_amount.out | 83 + ...ctOnchainOpcodes::test_transfer_tokens.out | 238 + ...(Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" | 35 + ...(Some 5) { Elt \"hello\" 4.0427752f13.out" | 35 + ...(Some 5) { Elt \"hello\" 4.0793dc66d5.out" | 36 + ...None { Elt \"1\" 1 ; .df114499b8.out" | 36 + ...None { Elt \"1\" 1 ; .f9bea98de9.out" | 36 + ...None { Elt \"hello\" 4 })-.1db12cd837.out" | 35 + ...None {})-\"hello\"-(Pair N.6fc7d0acf2.out" | 35 + ..." \"one\" ; Elt \"2\" \"tw.524c5459f8.out" | 46 + ...ello\" \"hi\" } None)-\"\".33eba403e7.out" | 45 + ...hello\" \"hi\" } None)-\"h.a5cd1005c9.out" | 45 + ...one\" ; Elt \"2\" \"two\" .6f3d35b151.out" | 36 + ...one\" ; Elt \"2\" \"two\" .76aeaa0706.out" | 48 + ...one\" ; Elt \"2\" \"two\" .7e7197f248.out" | 48 + ...one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" | 49 + ...one\" ; Elt \"2\" \"two\" .b688cc94a7.out" | 49 + ...one\" ; Elt \"2\" \"two\" .c68db221ed.out" | 48 + ...erflow[mul_overflow.tz-Unit-Left Unit].out | 26 + ...rflow[mul_overflow.tz-Unit-Right Unit].out | 26 + ...ow[shifts.tz-None-(Left (Pair 1 257))].out | 26 + ...[shifts.tz-None-(Left (Pair 123 257))].out | 26 + ...w[shifts.tz-None-(Right (Pair 1 257))].out | 26 + ...shifts.tz-None-(Right (Pair 123 257))].out | 26 + ...TestContractOpcodes::test_balance[0.5].out | 21 + ...s.TestContractOpcodes::test_balance[0].out | 21 + ...estContractOpcodes::test_balance[1000].out | 21 + ...s.TestContractOpcodes::test_balance[1].out | 21 + ...stContractOpcodes::test_balance[1e-06].out | 21 + ...s.TestContractOpcodes::test_balance[5].out | 21 + ...Opcodes::test_balance[8000000000000.0].out | 21 + ... \"two\" }) )-(Right (Righ.7492e8cdea.out" | 90 + ... \"two\" }))-(Left Unit)-(.21b30dd90f.out" | 44 + ... \"two\" }))-(Right (Left .2873ef610c.out" | 39 + ... \"two\" }))-(Right (Left .8a6f480005.out" | 35 + ... \"two\" }))-(Right (Right.d336ca1903.out" | 83 + ...Pair \"foo\" \"bar\" } { P.7f2ee47600.out" | 135 + ...tContractOpcodes::test_check_signature.out | 241 + ...tract_input_output[abs.tz-Unit-0-Unit].out | 38 + ....tz-Unit-12039123919239192312931-Unit].out | 38 + ...act_input_output[abs.tz-Unit-948-Unit].out | 38 + ...ct_input_output[add.tz-Unit-Unit-Unit].out | 211 + ...r 0x00 0x00-(Some 0x0000000.3c2de60480.out | 30 + ...r 0x01 0x00-(Some 0x0100000.12b2c1172b.out | 30 + ...r 0x010000 0x00-(Some 0x010.0e44fc6f40.out | 30 + ...r 0x010000 0x010000-(Some 0.7e0ed229a3.out | 30 + ...air -100 100)-(Some \"1970.7c1b1e4e5b.out" | 36 + ...air 0 \"1970-01-01T00:00:0.528ed42c01.out" | 36 + ...air 100 100)-(Some \"1970-.6566111ad2.out" | 36 + ...air \"1970-01-01T00:00:00Z.72c424f3da.out" | 36 + ...air 100 -100)-(Some \"1970.7c4b12e9aa.out" | 36 + ...air 100 100)-(Some \"1970-.af32743640.out" | 36 + ...dhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" | 23 + ...-None-(Pair False False)-(Some False)].out | 31 + ...z-None-(Pair False True)-(Some False)].out | 31 + ...z-None-(Pair True False)-(Some False)].out | 31 + ....tz-None-(Pair True True)-(Some True)].out | 31 + ...t_output[and_binary.tz-Unit-Unit-Unit].out | 93 + ...l_1.tz-False-(Pair False False)-False].out | 24 + ...al_1.tz-False-(Pair False True)-False].out | 24 + ...al_1.tz-False-(Pair True False)-False].out | 24 + ...ical_1.tz-False-(Pair True True)-True].out | 24 + ...put[balance.tz-111-Unit-4000000000000].out | 21 + ...lt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out | 43 + ...lt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out | 43 + ...lt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out | 43 + ...lt 1 0 } None)-1-(Pair 4 (S.73700321f8.out | 43 + ...lt 1 4 ; Elt 2 11 } None)-1.1182eca937.out | 44 + ...lt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out | 44 + ...lt 1 4 ; Elt 2 11 } None)-2.1eead33885.out | 44 + ...lt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out | 44 + ...lt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out | 44 + ...lt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out | 44 + ...air {} None)-1-(Pair 4 (Some False))0].out | 42 + ...air {} None)-1-(Pair 4 (Some False))1].out | 42 + ... \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" | 44 + ... \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" | 44 + ... \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" | 44 + ... \"foo\" 0 } None)-\"foo\".968709d39d.out" | 43 + ... \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" | 43 + ... None)-\"bar\"-(Pair 4 (Some False))].out" | 42 + ...padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out | 24 + ...e-Unit-(Some 0x100000000000.d1219ca789.out | 24 + ...utput[bls12_381_fr_to_int.tz-0-0x00-0].out | 21 + ...utput[bls12_381_fr_to_int.tz-0-0x01-1].out | 21 + ...8db8e57af88d9576acd181b89f2.7a85c336ff.out | 22 + ...9e8abf8dc324a010007addde986.b821eb26b3.out | 22 + ...ut[bls12_381_fr_to_mutez.tz-0-0x10-16].out | 32 + ...000000000000000000000000000.0accef5bef.out | 22 + ...000000000000000000000000000.0ecc537252.out | 22 + ...000000000000000000000000000.2229b767cd.out | 22 + ...000000000000000000000000000.2ff549b46b.out | 22 + ...000000000000000000000000000.bf8a711be6.out | 23 + ...000000000000000000000000000.d41cbb044b.out | 22 + ...a5ad0a633e4880d2296f08ec5c1.a50412e458.out | 23 + ...cd0fa853810e356f1eb79721e80.f3a349c4a7.out | 23 + ...be1766f92cd82c5e5135c374a03.1b9676e4c2.out | 23 + ...be1766f92cd82c5e5135c374a03.e966dc6de5.out | 23 + ...000000000000000000000000000.964835cc43.out | 22 + ...000000000000000000000000000.b25ea709fb.out | 22 + ...000000000000000000000000000.eae36753ea.out | 23 + ...000000000000000000000000000.ee57dac8f7.out | 22 + ...a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out | 23 + ...cd0fa853810e356f1eb79721e80.bd5800f6b8.out | 23 + ...be1766f92cd82c5e5135c374a03.00e897789a.out | 23 + ...be1766f92cd82c5e5135c374a03.a4697eaa13.out | 23 + ...000000000000000000000000000.0177355bbf.out | 25 + ...000000000000000000000000000.744166c609.out | 25 + ...000000000000000000000000000.9f3c5cdc6a.out | 25 + ...000000000000000000000000000.a54cb341ba.out | 25 + ...000000000000000000000000000.b0dc584c94.out | 25 + ...000000000000000000000000000.bddcad090c.out | 26 + ...a5ad0a633e4880d2296f08ec5c1.92c153eb47.out | 26 + ...cd0fa853810e356f1eb79721e80.290ab49d11.out | 26 + ...be1766f92cd82c5e5135c374a03.69f3589a06.out | 26 + ...be1766f92cd82c5e5135c374a03.fee3c5cf43.out | 26 + ...000000000000000000000000000.1bccc033e8.out | 26 + ...000000000000000000000000000.40958700fe.out | 25 + ...000000000000000000000000000.6c62b03d78.out | 25 + ...000000000000000000000000000.d23f269341.out | 25 + ...a5ad0a633e4880d2296f08ec5c1.927f808504.out | 26 + ...cd0fa853810e356f1eb79721e80.0c114c956a.out | 26 + ...be1766f92cd82c5e5135c374a03.03c4f38e68.out | 26 + ...be1766f92cd82c5e5135c374a03.8ed19cfdd9.out | 26 + ...input_output[car.tz-0-(Pair 34 17)-34].out | 21 + ...input_output[cdr.tz-0-(Pair 34 17)-17].out | 21 + ...prcVkpaWU\")-Unit-(Some \".8420090f97.out" | 23 + ...770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" | 23 + ...None-Unit-(Some \"NetXdQprcVkpaWU\")].out" | 23 + ...mb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out | 123 + ... Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" | 36 + ...r 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out | 39 + ...omb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out | 30 + ...nput_output[compare.tz-Unit-Unit-Unit].out | 398 + ...; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out | 350 + ...-{ \"World!\" }-{ \"Hello World!\" }].out" | 28 + ..."test2\" }-{ \"Hello test1.c27e8c3ee6.out" | 35 + ...input_output[concat_hello.tz-{}-{}-{}].out | 21 + ...}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out | 35 + ...hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out | 28 + ...output[concat_hello_bytes.tz-{}-{}-{}].out | 21 + ...; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" | 119 + ...\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" | 96 + ...t_output[concat_list.tz-\"\"-{}-\"\"].out" | 27 + ...ns.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out | 22 + ..._output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out | 22 + ...act_input_output[cons.tz-{}-10-{ 10 }].out | 22 + ...ir { \"A\" } { \"B\" })-(Some False)].out" | 166 + ...\"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" | 410 + ...\"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" | 437 ++ ...air { \"B\" } { \"B\" })-(Some True)].out" | 166 + ...ir { \"c\" } { \"B\" })-(Some False)].out" | 166 + ..._all.tz-None-(Pair {} {})-(Some True)].out | 63 + ...wnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" | 29 + ...Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" | 49 + ...970-01-01T00:03:20Z\" \"19.90e9215d17.out" | 34 + ...t[diff_timestamps.tz-111-(Pair 0 0)-0].out | 34 + ...[diff_timestamps.tz-111-(Pair 0 1)--1].out | 34 + ...t[diff_timestamps.tz-111-(Pair 1 0)-1].out | 34 + ...r 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out | 3431 +++++++++ ... 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out | 3431 +++++++++ ...air (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out | 61 + ...p.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out | 36 + ...z-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out | 36 + ...air (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out | 93 + ...air (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out | 39 + ...air (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out | 57 + ..._input_output[dup-n.tz-Unit-Unit-Unit].out | 248 + ... None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out | 142 + ... None)-(Pair 10 -3)-(Pair (.3caea50555.out | 142 + ... None)-(Pair 10 0)-(Pair No.f9448c04fb.out | 142 + ... None)-(Pair 10 (Left 0))-(Left None)].out | 37 + ...air 10 (Left 10))-(Left (So.f782cc1dec.out | 37 + ...air 10 (Left 3))-(Left (Som.016b4db96c.out | 37 + ...one)-(Pair 10 (Right 0))-(Right None)].out | 37 + ...air 10 (Right 10))-(Right (.e705a30e07.out | 37 + ...air 10 (Right 3))-(Right (S.44485eda6a.out | 37 + ...air 5 (Right 10))-(Right (S.8ab987af15.out | 37 + ...-{}-Unit-{ Elt \"hello\" \"world\" }].out" | 33 + ...t[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" | 48 + ...oncat.tz-\"?\"-\"test\"-\"test_abc\"].out" | 48 + ...tput[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out | 30 + ...act_input_output[first.tz-111-{ 4 }-4].out | 30 + ...me 4) {})-\"hello\"-(Pair .161d86cef6.out" | 34 + ...me 5) { Elt \"hello\" 4 }).684ab7e326.out" | 34 + ...me 5) { Elt \"hello\" 4 }).d49817fb83.out" | 34 + ...e { Elt \"1\" 1 ; .6900b1da14.out" | 34 + ...e { Elt \"1\" 1 ; .bca0ede8be.out" | 34 + ... { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" | 34 + ...ir None {})-\"hello\"-(Pair None {})].out" | 34 + ... \"1\" \"one\" ; .bc4127094e.out" | 41 + ..."hello\" \"hi\" })-\"\"-(P.0c03056487.out" | 41 + ...\"hello\" \"hi\" })-\"hell.cc45544c66.out" | 41 + ...nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" | 23 + ...2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" | 23 + ...xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" | 23 + ...-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" | 23 + ..._output[if.tz-None-False-(Some False)].out | 27 + ...ut_output[if.tz-None-True-(Some True)].out | 27 + ....tz-\"?\"-(Some \"hello\")-\"hello\"].out" | 23 + ...ut_output[if_some.tz-\"?\"-None-\"\"].out" | 25 + ...t_input_output[int.tz-None-0-(Some 0)].out | 23 + ...t_input_output[int.tz-None-1-(Some 1)].out | 23 + ...t_output[int.tz-None-9999-(Some 9999)].out | 23 + ...c20776f726c6421-(Some 0xb6e.34c02678c9.out | 24 + ...Left \"X\")-(Left True)-(Right True)].out" | 25 + ...ft \"X\")-(Right \"a\")-(Left \"a\")].out" | 25 + ...ract_input_output[level.tz-111-Unit-1].out | 21 + ...{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" | 27 + ...ut[list_concat.tz-\"abc\"-{}-\"abc\"].out" | 27 + ...tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out | 27 + ..._output[list_concat_bytes.tz-0x-{}-0x].out | 27 + ...b-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out | 27 + ...list_concat_bytes.tz-0xabcd-{}-0xabcd].out | 27 + ... ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" | 19 + ... ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 19 + ...input_output[list_id.tz-{\"\"}-{}-{}].out" | 19 + ... ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" | 27 + ... ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 27 + ...t_output[list_id_map.tz-{\"\"}-{}-{}].out" | 21 + ...tput[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out | 42 + ...tput[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out | 42 + ...}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out | 136 + ...}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out | 136 + ...ut_output[list_map_block.tz-{0}-{}-{}].out | 36 + ...ze.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out | 21 + ...tput[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out | 21 + ...input_output[list_size.tz-111-{ 1 }-1].out | 21 + ...ct_input_output[list_size.tz-111-{}-0].out | 21 + ... ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 163 + ...put_output[loop_left.tz-{\"\"}-{}-{}].out" | 52 + ...0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out | 19 + ...[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out | 19 + ...[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out | 19 + ... Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out | 152 + ...-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out | 152 + ...foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" | 68 + ...lt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" | 50 + ...ract_input_output[map_map.tz-{}-10-{}].out | 32 + ... 1 } None)-1-(Pair { Elt 0 .7396e5f090.out | 42 + ... 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out | 42 + ... 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out | 42 + ... 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out | 42 + ... 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out | 42 + ...air {} None)-1-(Pair {} (Some False))].out | 42 + ...ar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" | 42 + ...ar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" | 42 + ...ar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" | 42 + ...oo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" | 42 + ...oo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" | 42 + ...None)-\"bar\"-(Pair {} (Some False))].out" | 42 + ... \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" | 21 + ...\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" | 21 + ...ut[map_size.tz-111-{ Elt \"a\" 1 }-1].out" | 21 + ...act_input_output[map_size.tz-111-{}-0].out | 21 + ...ct_input_output[mul.tz-Unit-Unit-Unit].out | 131 + ...0-257-0x0101000000000000000.be11332c7f.out | 38 + ...2-16-0x10000000000000000000.8230fb4fac.out | 38 + ...act_input_output[neg.tz-0-(Left -2)-2].out | 25 + ...ract_input_output[neg.tz-0-(Left 0)-0].out | 25 + ...act_input_output[neg.tz-0-(Left 2)--2].out | 25 + ...act_input_output[neg.tz-0-(Right 0)-0].out | 25 + ...ct_input_output[neg.tz-0-(Right 2)--2].out | 25 + ...nput_output[none.tz-Some 10-Unit-None].out | 21 + ..._output[not.tz-None-False-(Some True)].out | 23 + ..._output[not.tz-None-True-(Some False)].out | 23 + ...not_binary.tz-None-(Left -8)-(Some 7)].out | 27 + ...not_binary.tz-None-(Left -9)-(Some 8)].out | 27 + ...not_binary.tz-None-(Left 0)-(Some -1)].out | 27 + ...not_binary.tz-None-(Left 7)-(Some -8)].out | 27 + ...not_binary.tz-None-(Left 8)-(Some -9)].out | 27 + ...ot_binary.tz-None-(Right 0)-(Some -1)].out | 27 + ...ot_binary.tz-None-(Right 7)-(Some -8)].out | 27 + ...ot_binary.tz-None-(Right 8)-(Some -9)].out | 27 + ...-None-(Pair False False)-(Some False)].out | 35 + ...tz-None-(Pair False True)-(Some True)].out | 35 + ...tz-None-(Pair True False)-(Some True)].out | 35 + ....tz-None-(Pair True True)-(Some True)].out | 35 + ...or_binary.tz-None-(Pair 0 8)-(Some 8)].out | 26 + ..._binary.tz-None-(Pair 14 1)-(Some 15)].out | 26 + ..._binary.tz-None-(Pair 15 4)-(Some 15)].out | 26 + ...r_binary.tz-None-(Pair 4 8)-(Some 12)].out | 26 + ...or_binary.tz-None-(Pair 7 7)-(Some 7)].out | 26 + ...or_binary.tz-None-(Pair 8 0)-(Some 8)].out | 26 + ... (Pair 1 (Pair \"foobar\".368bdfd73a.out" | 845 ++ ... (Pair 1 (Pair \"foobar\".735d9ae802.out" | 845 ++ ...ir \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" | 1194 +++ ...ir \"edpkuBknW28nW72KG6RoH.4e20b52378.out" | 1032 +++ ...alse False)-(Some (Pair False False))].out | 21 + ... False True)-(Some (Pair False True))].out | 21 + ... True False)-(Some (Pair True False))].out | 21 + ...ir True True)-(Some (Pair True True))].out | 21 + ...ntract_input_output[pexec.tz-14-38-52].out | 47 + ... 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out | 282 + ...utput[ret_int.tz-None-Unit-(Some 300)].out | 23 + ... ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 42 + ...input_output[reverse.tz-{\"\"}-{}-{}].out" | 27 + ... ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 131 + ..._output[reverse_loop.tz-{\"\"}-{}-{}].out" | 50 + ...tput[sapling_empty_state.tz-{}-Unit-0].out | 21 + ...output[self_address.tz-Unit-Unit-Unit].out | 46 + ..._default_entrypoint.tz-Unit-Unit-Unit].out | 47 + ...entrypoint.tz-Unit-Left (Left 0)-Unit].out | 93 + ...Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" | 49 + ..."hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" | 49 + ...lo\" 0)-\"world\"-(Pair \"world\" 0)].out" | 49 + ...ir \"hello\" 0)-1-(Pair \"hello\" 1)].out" | 46 + ... \"hello\" 500)-3-(Pair \"hello\" 3)].out" | 46 + ..."hello\" 7)-100-(Pair \"hello\" 100)].out" | 46 + ... ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" | 19 + ...; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" | 19 + ...tract_input_output[set_id.tz-{}-{}-{}].out | 19 + ..._iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out | 47 + ..._input_output[set_iter.tz-111-{ 1 }-1].out | 32 + ...act_input_output[set_iter.tz-111-{}-0].out | 27 + ..."World\" } None)-\"\"-(Pai.3d2044726e.out" | 61 + ...)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" | 61 + ... None)-\"Hi\"-(Pair {} (Some False))].out" | 61 + ...ze.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out | 21 + ...utput[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out | 21 + ..._input_output[set_size.tz-111-{ 1 }-1].out | 21 + ...act_input_output[set_size.tz-111-{}-0].out | 21 + ...0776f726c6421-(Some 0xf345a.a07ae9dddf.out | 24 + ...ts.tz-None-(Left (Pair 0 0))-(Some 0)].out | 30 + ...ts.tz-None-(Left (Pair 0 1))-(Some 0)].out | 30 + ...ts.tz-None-(Left (Pair 1 2))-(Some 4)].out | 30 + ....tz-None-(Left (Pair 15 2))-(Some 60)].out | 30 + ...s.tz-None-(Left (Pair 8 1))-(Some 16)].out | 30 + ...s.tz-None-(Right (Pair 0 0))-(Some 0)].out | 30 + ...s.tz-None-(Right (Pair 0 1))-(Some 0)].out | 30 + ...s.tz-None-(Right (Pair 1 2))-(Some 0)].out | 30 + ....tz-None-(Right (Pair 15 2))-(Some 3)].out | 30 + ...s.tz-None-(Right (Pair 8 1))-(Some 4)].out | 30 + ...ut_output[slice.tz-None-Pair 0 0-None].out | 31 + ...tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" | 37 + ...slice.tz-Some \"Foo\"-Pair 0 10-None].out" | 37 + ...-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" | 37 + ...z-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" | 37 + ...[slice.tz-Some \"Foo\"-Pair 1 3-None].out" | 37 + ...slice.tz-Some \"Foo\"-Pair 10 5-None].out" | 37 + ...FooFooFooFooFooFooFooFooFo.c508d67bb0.out" | 38 + ...put[slice_bytes.tz-None-Pair 0 1-None].out | 31 + ...s.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out | 37 + ...tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out | 37 + ...z-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out | 37 + ...z-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out | 37 + ...-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out | 37 + ..._bytes.tz-Some 0xaabbcc-Pair 1 3-None].out | 37 + ...aabbccaabbccaabbccaabbccaab.df5895de85.out | 38 + ...d.tz-None-\"Hello\"-(Some \"Hello\")].out" | 21 + ..._id.tz-None-\"abcd\"-(Some \"abcd\")].out" | 21 + ...r 100 -100)-\"1970-01-01T00:03:20Z\"].out" | 34 + ...ir 100 100)-\"1970-01-01T00:00:00Z\"].out" | 34 + ...Pair 100 200000000000000000.3db82d2c25.out | 34 + ...00000 1000000)-(Some (Pair .b461aa042b.out | 71 + ...10000 1010000)-(Some (Pair .1e8cf7679c.out | 71 + ...t_output[uncomb.tz-0-(Pair 1 4 2)-142].out | 50 + ...input_output[unpair.tz-Unit-Unit-Unit].out | 462 ++ ...dpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" | 32 + ...Pair False False)-(Some (Left False))].out | 32 + ... (Pair False True)-(Some (Left True))].out | 32 + ... (Pair True False)-(Some (Left True))].out | 32 + ... (Pair True True)-(Some (Left False))].out | 32 + ...one-Right (Pair 0 0)-(Some (Right 0))].out | 32 + ...one-Right (Pair 0 1)-(Some (Right 1))].out | 32 + ...one-Right (Pair 1 0)-(Some (Right 1))].out | 32 + ...one-Right (Pair 1 1)-(Some (Right 0))].out | 32 + ...-Right (Pair 42 21)-(Some (Right 63))].out | 32 + ...-Right (Pair 42 63)-(Some (Right 21))].out | 32 + ...s::test_hash_consistency_michelson_cli.out | 23 + ...pcodes.TestContractOpcodes::test_level.out | 21 + ...bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" | 9 + ...\"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" | 9 + ...eeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out | 9 + ..._opcodes.TestContractOpcodes::test_now.out | 21 + ...s.TestContractOpcodes::test_packunpack.out | 106 + ...roveTransferRemove::test_add_liquidity.out | 83 + ...ddApproveTransferRemove::test_approval.out | 41 + ...TransferRemove::test_approved_transfer.out | 41 + ...roveTransferRemove::test_call_approve1.out | 41 + ...roveTransferRemove::test_call_approve2.out | 41 + ...roveTransferRemove::test_call_approve3.out | 41 + ...TransferRemove::test_call_mint_or_burn.out | 40 + ...pproveTransferRemove::test_dex_storage.out | 7 + ...pproveTransferRemove::test_lqt_storage.out | 3 + ...eTransferRemove::test_remove_liquidity.out | 80 + ...stAddApproveTransferRemove::test_setup.out | 8 + ...pproveTransferRemove::test_tok_storage.out | 3 + ..._baking.TestTrades::test_add_liquidity.out | 83 + ...uidity_baking.TestTrades::test_buy_tok.out | 75 + ..._baking.TestTrades::test_call_approve1.out | 41 + ..._baking.TestTrades::test_call_approve2.out | 41 + ..._baking.TestTrades::test_call_approve3.out | 41 + ...ing.TestTrades::test_call_mint_or_burn.out | 40 + ...ty_baking.TestTrades::test_dex_storage.out | 7 + ...ty_baking.TestTrades::test_lqt_storage.out | 3 + ...idity_baking.TestTrades::test_sell_tok.out | 74 + ...iquidity_baking.TestTrades::test_setup.out | 8 + ...ty_baking.TestTrades::test_tok_storage.out | 3 + ...idity_baking.TestTrades::test_transfer.out | 43 + tests_python/tests_012/conftest.py | 121 + tests_python/tests_012/contract_paths.py | 20 + .../tests_012/per_block_vote_files/false.json | 1 + .../per_block_vote_files/invalid.json | 1 + .../per_block_vote_files/non_boolean.json | 1 + .../tests_012/per_block_vote_files/true.json | 1 + .../per_block_vote_files/wrong_key.json | 1 + tests_python/tests_012/protocol.py | 69 + tests_python/tests_012/test_accuser.py | 126 + tests_python/tests_012/test_baker_endorser.py | 113 + tests_python/tests_012/test_basic.py | 503 ++ tests_python/tests_012/test_binaries.py | 48 + tests_python/tests_012/test_bootstrap.py | 221 + tests_python/tests_012/test_client.py | 35 + .../tests_012/test_client_without_node.py | 450 ++ tests_python/tests_012/test_codec.py | 23 + tests_python/tests_012/test_contract.py | 2296 ++++++ .../tests_012/test_contract_annotations.py | 88 + tests_python/tests_012/test_contract_baker.py | 55 + .../tests_012/test_contract_bls12_381.py | 317 + .../tests_012/test_contract_macros.py | 447 ++ .../test_contract_onchain_opcodes.py | 1312 ++++ .../tests_012/test_contract_opcodes.py | 1943 +++++ tests_python/tests_012/test_cors.py | 47 + tests_python/tests_012/test_crypto.py | 47 + tests_python/tests_012/test_fa12.py | 352 + tests_python/tests_012/test_forge_block.py | 46 + tests_python/tests_012/test_fork.py | 88 + tests_python/tests_012/test_injection.py | 103 + .../tests_012/test_liquidity_baking.py | 279 + tests_python/tests_012/test_many_bakers.py | 42 + tests_python/tests_012/test_many_nodes.py | 66 + tests_python/tests_012/test_mempool.py | 66 + tests_python/tests_012/test_migration.py | 298 + tests_python/tests_012/test_mockup.py | 762 ++ .../tests_012/test_multinode_snapshot.py | 753 ++ .../test_multinode_storage_reconstruction.py | 180 + .../tests_012/test_multiple_transfers.py | 133 + tests_python/tests_012/test_multisig.py | 620 ++ .../tests_012/test_nonce_seed_revelation.py | 133 + tests_python/tests_012/test_openapi.py | 73 + tests_python/tests_012/test_p2p.py | 147 + .../tests_012/test_per_block_votes.py | 131 + tests_python/tests_012/test_programs.py | 97 + .../tests_012/test_proto_demo_counter.py | 88 + .../test_proto_demo_noops_manual_bake.py | 97 + tests_python/tests_012/test_rpc.py | 639 ++ tests_python/tests_012/test_sapling.py | 962 +++ .../tests_012/test_slice_fails_params.txt | 5 + .../tests_012/test_slice_success_params.txt | 1 + tests_python/tests_012/test_tenderbake.py | 59 + .../test_tenderbake_bakers_restart.py | 80 + .../test_tenderbake_incremental_start.py | 82 + .../test_tenderbake_long_dynamic_bake.py | 237 + .../tests_012/test_tenderbake_manual_bake.py | 231 + tests_python/tests_012/test_tls.py | 23 + tests_python/tests_012/test_voting.py | 249 + tests_python/tests_012/test_voting_full.py | 217 + tests_python/tests_alpha/protocol.py | 6 +- tests_python/tools/constants.py | 5 + 1942 files changed, 245890 insertions(+), 4 deletions(-) create mode 100644 docs/012/cli-commands.rst create mode 100644 docs/012/consensus.rst create mode 100644 docs/012/global_constants.rst create mode 100644 docs/012/glossary.rst create mode 100644 docs/012/liquidity_baking.rst create mode 100644 docs/012/michelson.rst create mode 100644 docs/012/plugins.rst create mode 100644 docs/012/proof_of_stake.rst create mode 100644 docs/012/protocol.rst create mode 100644 docs/012/protocol_overview.rst create mode 100644 docs/012/sapling.rst create mode 100644 docs/012/timelock.rst create mode 100644 docs/012/voting.rst create mode 100644 docs/protocols/012_ithaca.rst create mode 100644 src/proto_012_PsiThaCa/bin_accuser/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/bin_accuser/dune create mode 100644 src/proto_012_PsiThaCa/bin_accuser/dune-project create mode 100644 src/proto_012_PsiThaCa/bin_accuser/main_accuser_012_PsiThaCa.ml create mode 100644 src/proto_012_PsiThaCa/bin_accuser/tezos-accuser-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/bin_baker/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/bin_baker/dune create mode 100644 src/proto_012_PsiThaCa/bin_baker/dune-project create mode 100644 src/proto_012_PsiThaCa/bin_baker/main_baker_012_PsiThaCa.ml create mode 100644 src/proto_012_PsiThaCa/bin_baker/tezos-baker-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/README.md create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/autocomp.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/dune create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/execution_context.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/kernel.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/dune create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/inference.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/inference.mli create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/int_map.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky.mli create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky_prim.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/monads.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/stores.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/dune create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/test_inference.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/test_uf.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/tezos-benchmark-type-inference-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/type.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/type.mli create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/uf.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/micheline_sampler.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/micheline_sampler.mli create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/michelson_mcmc_samplers.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/michelson_mcmc_samplers.mli create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers.mli create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers_base.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers_base.mli create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/mikhailsky_to_michelson.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/rules.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/sampling_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/state_space.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/test/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/test/dune create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/test/test_autocompletion.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/test/test_distribution.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/test/test_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/test/test_sampling_code.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/test/test_sampling_data.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/tezos-benchmark-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/type_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmark/type_helpers.mli create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/cache_benchmarks.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/dune create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/encodings_benchmarks.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/gas_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/global_constants_storage_benchmarks.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_benchmarks.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_model.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_workload.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_generation.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_generation.mli create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_types.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/registration_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_benchmarks.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_generation.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/script_repr_benchmarks.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/script_typed_ir_size_benchmarks.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/size.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/tags.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/tezos-benchmarks-proto-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_benchmarks.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_model.ml create mode 100644 src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_workload.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_client/annotated_manager_operation.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/annotated_manager_operation.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_args.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_args.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_context.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_context.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_contracts.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_contracts.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_fa12.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_fa12.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_multisig.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_multisig.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_programs.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_programs.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_utils.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/client_proto_utils.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/dune create mode 100644 src/proto_012_PsiThaCa/lib_client/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_client/injection.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/injection.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/light.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/limit.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/limit.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/managed_contract.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/managed_contract.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_emacs.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_emacs.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_entrypoints.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_entrypoints.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_error_reporter.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_error_reporter.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_macros.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_macros.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_parser.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_parser.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_printer.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/michelson_v1_printer.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/mockup.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/operation_result.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/operation_result.mli create mode 100644 src/proto_012_PsiThaCa/lib_client/protocol_client_context.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/proxy.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/test/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_client/test/assert.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/test/dune create mode 100644 src/proto_012_PsiThaCa/lib_client/test/test_client_proto_context.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/test/test_client_proto_contracts.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/test/test_michelson_v1_macros.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/test/test_proxy.ml create mode 100644 src/proto_012_PsiThaCa/lib_client/tezos-client-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/alpha_commands_registration.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_context_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_contracts_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_fa12_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_mockup_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_mockup_commands.mli create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_multisig_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_multisig_commands.mli create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_programs_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_programs_commands.mli create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_stresstest_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_utils_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/client_proto_utils_commands.mli create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/dune create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/tezos-client-012-PsiThaCa-commands-registration.opam create mode 100644 src/proto_012_PsiThaCa/lib_client_commands/tezos-client-012-PsiThaCa-commands.opam create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/client_sapling_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/client_sapling_commands.mli create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/context.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/context.mli create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/dune create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/tezos-client-sapling-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/wallet.ml create mode 100644 src/proto_012_PsiThaCa/lib_client_sapling/wallet.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_delegate/abstract_context_index.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/abstract_context_index.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_actions.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_actions.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_cache.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_commands.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_commands.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_commands_registration.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_configuration.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_configuration.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_errors.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_events.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_files.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_files.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_highwatermarks.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_highwatermarks.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_lib.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_lib.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_nonces.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_nonces.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_pow.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_pow.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_scheduling.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_scheduling.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_simulator.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_simulator.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_state.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/baking_state.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/block_forge.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/block_forge.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/client_baking_blocks.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/client_baking_blocks.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/client_baking_denunciation.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/client_baking_denunciation.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/client_baking_scheduling.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/client_baking_scheduling.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/client_daemon.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/client_daemon.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/context_ops.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/delegate_events.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/dune create mode 100644 src/proto_012_PsiThaCa/lib_delegate/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_delegate/liquidity_baking_vote_file.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/logging.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/logging.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/node_rpc.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/node_rpc.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/operation_pool.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/operation_pool.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/operation_selection.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/operation_selection.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/operation_worker.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/operation_worker.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/state_transitions.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/state_transitions.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/README.md create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/dune create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/main.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/broadcast_services.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/dune create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_client_context.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_daemon.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_services.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/mockup_simulator.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/mockup_simulator.mli create mode 100644 src/proto_012_PsiThaCa/lib_delegate/test/test_scenario.ml create mode 100644 src/proto_012_PsiThaCa/lib_delegate/tezos-accuser-012-PsiThaCa-commands.opam create mode 100644 src/proto_012_PsiThaCa/lib_delegate/tezos-baking-012-PsiThaCa-commands.opam create mode 100644 src/proto_012_PsiThaCa/lib_delegate/tezos-baking-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_delegate/tezos-endorser-012-PsiThaCa-commands.opam create mode 100644 src/proto_012_PsiThaCa/lib_parameters/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_parameters/default_parameters.ml create mode 100644 src/proto_012_PsiThaCa/lib_parameters/default_parameters.mli create mode 100644 src/proto_012_PsiThaCa/lib_parameters/dune create mode 100644 src/proto_012_PsiThaCa/lib_parameters/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_parameters/gen.ml create mode 100644 src/proto_012_PsiThaCa/lib_parameters/tezos-protocol-012-PsiThaCa-parameters.opam create mode 100644 src/proto_012_PsiThaCa/lib_plugin/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_plugin/dune create mode 100644 src/proto_012_PsiThaCa/lib_plugin/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_plugin/plugin.ml create mode 100644 src/proto_012_PsiThaCa/lib_plugin/plugin_registerer.ml create mode 100644 src/proto_012_PsiThaCa/lib_plugin/test/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_plugin/test/dune create mode 100644 src/proto_012_PsiThaCa/lib_plugin/test/test_consensus_filter.ml create mode 100644 src/proto_012_PsiThaCa/lib_plugin/tezos-protocol-plugin-012-PsiThaCa-registerer.opam create mode 100644 src/proto_012_PsiThaCa/lib_plugin/tezos-protocol-plugin-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_protocol/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_protocol/TEZOS_PROTOCOL create mode 100644 src/proto_012_PsiThaCa/lib_protocol/alpha_context.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/alpha_context.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/alpha_services.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/alpha_services.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/amendment.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/amendment.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/apply.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/apply.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/apply_results.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/apply_results.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/baking.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/baking.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/blinded_public_key_hash.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/blinded_public_key_hash.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/block_header_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/block_header_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/block_payload_hash.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/block_payload_hash.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/block_payload_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/block_payload_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/bootstrap_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/bootstrap_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/cache_memory_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/cache_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/cache_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/commitment_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/commitment_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/commitment_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/commitment_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/constants_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/constants_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/constants_services.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/constants_services.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/constants_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/constants_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_delegate_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_delegate_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_hash.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_hash.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_manager_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_manager_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_services.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_services.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contract_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.bin create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.mligo create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.bin create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.mligo create mode 100644 src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/coq-of-ocaml/README.md create mode 100644 src/proto_012_PsiThaCa/lib_protocol/coq-of-ocaml/config.json create mode 100644 src/proto_012_PsiThaCa/lib_protocol/cycle_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/cycle_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/delegate_activation_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/delegate_activation_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/delegate_services.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/delegate_services.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/delegate_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/delegate_storage.mli create mode 120000 src/proto_012_PsiThaCa/lib_protocol/dune create mode 100644 src/proto_012_PsiThaCa/lib_protocol/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_protocol/dune.inc create mode 100644 src/proto_012_PsiThaCa/lib_protocol/fees_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/fees_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/fitness_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/fitness_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/fixed_point_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/fixed_point_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/frozen_deposits_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/frozen_deposits_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/gas_limit_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/gas_limit_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/gas_monad.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/gas_monad.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/global_constants_costs.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/global_constants_costs.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/global_constants_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/global_constants_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/init_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/init_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/lazy_storage_diff.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/lazy_storage_diff.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/lazy_storage_kind.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/lazy_storage_kind.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/level_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/level_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/level_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/level_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_cpmm.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_lqt.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_migration.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_migration.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/local_gas_counter.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/main.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/main.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/manager_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/manager_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/michelson_v1_gas.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/michelson_v1_gas.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/michelson_v1_primitives.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/michelson_v1_primitives.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/migration_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/migration_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/misc.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/misc.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/non_empty_string.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/non_empty_string.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/nonce_hash.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/nonce_hash.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/nonce_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/nonce_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/operation_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/operation_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/parameters_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/parameters_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/path_encoding.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/path_encoding.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/period_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/period_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/raw_context.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/raw_context.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/raw_context_intf.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/raw_level_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/raw_level_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/receipt_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/receipt_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/roll_repr_legacy.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/roll_repr_legacy.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/roll_storage_legacy.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/roll_storage_legacy.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/round_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/round_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/sampler.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/sampler.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/sapling_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/sapling_services.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/sapling_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/sapling_validator.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/saturation_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/saturation_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_cache.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_cache.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_comparable.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_comparable.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_expr_hash.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_expr_hash.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_int_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_int_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_interpreter.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_interpreter.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_interpreter_defs.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_ir_annot.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_ir_annot.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_ir_translator.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_ir_translator.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_list.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_list.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_map.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_map.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_set.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_set.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_string_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_string_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_tc_errors.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_tc_errors_registration.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_tc_errors_registration.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_timestamp_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_timestamp_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_typed_ir.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_typed_ir.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size_costs.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size_costs.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/seed_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/seed_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/seed_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/seed_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/services_registration.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/services_registration.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/slot_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/slot_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/stake_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/stake_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/state_hash.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/state_hash.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/storage_costs.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/storage_costs.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/storage_description.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/storage_description.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/storage_functors.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/storage_functors.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/storage_sigs.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/big_interpreter_stack.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_double.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_drop.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_send.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_state_as_arg.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_push_sapling_state.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_use_existing_state.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/temp_big_maps.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/contracts/timelock.tz create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/dune create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/README.md create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/account.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/account.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/assert.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/block.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/block.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/consensus_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/context.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/context.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/contract_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/cpmm_logic.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/cpmm_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/dune create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/dune-project create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/error_monad_operators.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/expr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/expr_common.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/incremental.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/incremental.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_generator.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_generator.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_machine.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_machine.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/lqt_fa12_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/nonce.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/nonce.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/op.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/op.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/rewards.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/sapling_helpers.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_big_map.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_big_map.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_list.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_list.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_map.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_map.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_set.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_set.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/test_global_constants.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/test_tez.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/testable.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/helpers/tezos-012-PsiThaCa-test-helpers.opam create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/liquidity_baking_pbt.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/main.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/saturation_fuzzing.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_activation.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_baking.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_combined_operations.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_constants.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_deactivation.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_delegation.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_double_baking.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_double_endorsement.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_double_preendorsement.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_endorsement.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_failing_noop.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_fitness.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_fixed_point.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_frozen_deposits.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_gas_costs.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_gas_levels.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_gas_properties.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_global_constants_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_helpers_rpcs.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_interpretation.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_lazy_storage_diff.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_level_module.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_liquidity_baking.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_origination.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_participation.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_preendorsement.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_preendorsement_functor.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_qty.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_receipt.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_reveal.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_round_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_sampler.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_sapling.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_saturation.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_script_comparison.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_script_typed_ir_size.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_seed.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_temp_big_maps.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_tez_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_balance_key.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_scanner.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_time_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_timelock.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_token.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_transfer.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_typechecking.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/test_voting.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/unit/.ocamlformat create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/unit/dune create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/unit/main.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/unit/test_alpha_context.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/unit/test_contract_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/unit/test_global_constants_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/unit/test_operation_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/unit/test_raw_level_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/test/unit/test_tez_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/tez_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/tez_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/tezos-embedded-protocol-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-012-PsiThaCa-tests.opam create mode 100644 src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-functor-012-PsiThaCa.opam create mode 100644 src/proto_012_PsiThaCa/lib_protocol/ticket_balance_key.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/ticket_balance_key.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/ticket_costs.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/ticket_costs.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/ticket_scanner.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/ticket_scanner.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/ticket_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/ticket_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/time_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/time_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/token.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/token.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/vote_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/vote_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/vote_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/vote_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/voting_period_repr.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/voting_period_repr.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/voting_period_storage.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/voting_period_storage.mli create mode 100644 src/proto_012_PsiThaCa/lib_protocol/voting_services.ml create mode 100644 src/proto_012_PsiThaCa/lib_protocol/voting_services.mli create mode 100644 src/proto_012_PsiThaCa/parameters/dune create mode 100644 tests_python/contracts_012/attic/accounts.tz create mode 100644 tests_python/contracts_012/attic/add1.tz create mode 100644 tests_python/contracts_012/attic/add1_list.tz create mode 100644 tests_python/contracts_012/attic/after_strategy.tz create mode 100644 tests_python/contracts_012/attic/always.tz create mode 100644 tests_python/contracts_012/attic/append.tz create mode 100644 tests_python/contracts_012/attic/at_least.tz create mode 100644 tests_python/contracts_012/attic/auction.tz create mode 100644 tests_python/contracts_012/attic/bad_lockup.tz create mode 100644 tests_python/contracts_012/attic/big_map_union.tz create mode 100644 tests_python/contracts_012/attic/cadr_annotation.tz create mode 100644 tests_python/contracts_012/attic/concat.tz create mode 100644 tests_python/contracts_012/attic/conditionals.tz create mode 100644 tests_python/contracts_012/attic/cons_twice.tz create mode 100644 tests_python/contracts_012/attic/cps_fact.tz create mode 100644 tests_python/contracts_012/attic/create_add1_lists.tz create mode 100644 tests_python/contracts_012/attic/data_publisher.tz create mode 100644 tests_python/contracts_012/attic/dispatch.tz create mode 100644 tests_python/contracts_012/attic/empty.tz create mode 100644 tests_python/contracts_012/attic/fail_amount.tz create mode 100644 tests_python/contracts_012/attic/faucet.tz create mode 100644 tests_python/contracts_012/attic/forward.tz create mode 100644 tests_python/contracts_012/attic/id.tz create mode 100644 tests_python/contracts_012/attic/infinite_loop.tz create mode 100644 tests_python/contracts_012/attic/insertion_sort.tz create mode 100644 tests_python/contracts_012/attic/int_publisher.tz create mode 100644 tests_python/contracts_012/attic/king_of_tez.tz create mode 100644 tests_python/contracts_012/attic/list_of_transactions.tz create mode 100644 tests_python/contracts_012/attic/queue.tz create mode 100644 tests_python/contracts_012/attic/reduce_map.tz create mode 100644 tests_python/contracts_012/attic/reentrancy.tz create mode 100644 tests_python/contracts_012/attic/reservoir.tz create mode 100644 tests_python/contracts_012/attic/scrutable_reservoir.tz create mode 100644 tests_python/contracts_012/attic/spawn_identities.tz create mode 100644 tests_python/contracts_012/entrypoints/big_map_entrypoints.tz create mode 100644 tests_python/contracts_012/entrypoints/delegatable_target.tz create mode 100644 tests_python/contracts_012/entrypoints/manager.tz create mode 100644 tests_python/contracts_012/entrypoints/no_default_target.tz create mode 100644 tests_python/contracts_012/entrypoints/no_entrypoint_target.tz create mode 100644 tests_python/contracts_012/entrypoints/rooted_target.tz create mode 100644 tests_python/contracts_012/entrypoints/simple_entrypoints.tz create mode 100644 tests_python/contracts_012/ill_typed/badly_indented.tz create mode 100644 tests_python/contracts_012/ill_typed/big_dip.tz create mode 100644 tests_python/contracts_012/ill_typed/big_drop.tz create mode 100644 tests_python/contracts_012/ill_typed/big_map_arity.tz create mode 100644 tests_python/contracts_012/ill_typed/chain_id_arity.tz create mode 100644 tests_python/contracts_012/ill_typed/comb0.tz create mode 100644 tests_python/contracts_012/ill_typed/comb1.tz create mode 100644 tests_python/contracts_012/ill_typed/contract_annotation_default.tz create mode 100644 tests_python/contracts_012/ill_typed/dip_failwith.tz create mode 100644 tests_python/contracts_012/ill_typed/dup0.tz create mode 100644 tests_python/contracts_012/ill_typed/failwith_big_map.tz create mode 100644 tests_python/contracts_012/ill_typed/invalid_self_entrypoint.tz create mode 100644 tests_python/contracts_012/ill_typed/map_failwith.tz create mode 100644 tests_python/contracts_012/ill_typed/missing_only_code_field.tz create mode 100644 tests_python/contracts_012/ill_typed/missing_only_parameter_field.tz create mode 100644 tests_python/contracts_012/ill_typed/missing_only_storage_field.tz create mode 100644 tests_python/contracts_012/ill_typed/missing_parameter_and_storage_fields.tz create mode 100644 tests_python/contracts_012/ill_typed/multiple_code_field.tz create mode 100644 tests_python/contracts_012/ill_typed/multiple_parameter_field.tz create mode 100644 tests_python/contracts_012/ill_typed/multiple_storage_and_code_fields.tz create mode 100644 tests_python/contracts_012/ill_typed/multiple_storage_field.tz create mode 100644 tests_python/contracts_012/ill_typed/never_literal.tz create mode 100644 tests_python/contracts_012/ill_typed/pack_big_map.tz create mode 100644 tests_python/contracts_012/ill_typed/pack_operation.tz create mode 100644 tests_python/contracts_012/ill_typed/pack_sapling_state.tz create mode 100644 tests_python/contracts_012/ill_typed/push_big_map_with_id_with_parens.tz create mode 100644 tests_python/contracts_012/ill_typed/push_big_map_with_id_without_parens.tz create mode 100644 tests_python/contracts_012/ill_typed/sapling_build_empty_state_with_int_parameter.tz create mode 100644 tests_python/contracts_012/ill_typed/set_update_non_comparable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undig2able.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undigable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undip2able.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undipable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undropable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undug2able.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undugable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_undup2able.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unfailwithable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_ungetable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unleftable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unpairable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unpopable.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unpopable_in_lambda.tz create mode 100644 tests_python/contracts_012/ill_typed/stack_bottom_unrightable.tz create mode 100644 tests_python/contracts_012/ill_typed/ticket_apply.tz create mode 100644 tests_python/contracts_012/ill_typed/ticket_dup.tz create mode 100644 tests_python/contracts_012/ill_typed/ticket_in_ticket.tz create mode 100644 tests_python/contracts_012/ill_typed/ticket_unpack.tz create mode 100644 tests_python/contracts_012/ill_typed/uncomb0.tz create mode 100644 tests_python/contracts_012/ill_typed/uncomb1.tz create mode 100644 tests_python/contracts_012/ill_typed/unpack_sapling_state.tz create mode 100644 tests_python/contracts_012/ill_typed/unpair_field_annotation_mismatch.tz create mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_char_set.tz create mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_type.tz create mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_name_non_printable_char.tz create mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_name_too_long.tz create mode 100644 tests_python/contracts_012/ill_typed/view_op_bad_return_type.tz create mode 100644 tests_python/contracts_012/ill_typed/view_op_dupable_type.tz create mode 100644 tests_python/contracts_012/ill_typed/view_op_invalid_arity.tz create mode 100644 tests_python/contracts_012/ill_typed/view_op_lazy_storage.tz create mode 100644 tests_python/contracts_012/ill_typed/view_op_lazy_storage_type.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_input_type.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_char_set.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_type.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_name_non_printable_char.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_name_too_long.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_return_type.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_bad_type.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_input.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_output.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_duplicated_name.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_invalid_arity.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_input.tz create mode 100644 tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_output.tz create mode 100644 tests_python/contracts_012/legacy/create_account.tz create mode 100644 tests_python/contracts_012/legacy/create_contract.tz create mode 100644 tests_python/contracts_012/legacy/create_contract_flags.tz create mode 100644 tests_python/contracts_012/legacy/create_contract_rootname.tz create mode 100644 tests_python/contracts_012/legacy/originator.tz create mode 100644 tests_python/contracts_012/legacy/steps_to_quota.tz create mode 100644 tests_python/contracts_012/macros/assert.tz create mode 100644 tests_python/contracts_012/macros/assert_cmpeq.tz create mode 100644 tests_python/contracts_012/macros/assert_cmpge.tz create mode 100644 tests_python/contracts_012/macros/assert_cmpgt.tz create mode 100644 tests_python/contracts_012/macros/assert_cmple.tz create mode 100644 tests_python/contracts_012/macros/assert_cmplt.tz create mode 100644 tests_python/contracts_012/macros/assert_cmpneq.tz create mode 100644 tests_python/contracts_012/macros/assert_eq.tz create mode 100644 tests_python/contracts_012/macros/assert_ge.tz create mode 100644 tests_python/contracts_012/macros/assert_gt.tz create mode 100644 tests_python/contracts_012/macros/assert_le.tz create mode 100644 tests_python/contracts_012/macros/assert_lt.tz create mode 100644 tests_python/contracts_012/macros/assert_neq.tz create mode 100644 tests_python/contracts_012/macros/big_map_get_add.tz create mode 100644 tests_python/contracts_012/macros/big_map_mem.tz create mode 100644 tests_python/contracts_012/macros/build_list.tz create mode 100644 tests_python/contracts_012/macros/carn_and_cdrn.tz create mode 100644 tests_python/contracts_012/macros/compare.tz create mode 100644 tests_python/contracts_012/macros/compare_bytes.tz create mode 100644 tests_python/contracts_012/macros/fail.tz create mode 100644 tests_python/contracts_012/macros/guestbook.tz create mode 100644 tests_python/contracts_012/macros/macro_annotations.tz create mode 100644 tests_python/contracts_012/macros/map_caddaadr.tz create mode 100644 tests_python/contracts_012/macros/max_in_list.tz create mode 100644 tests_python/contracts_012/macros/min.tz create mode 100644 tests_python/contracts_012/macros/pair_macro.tz create mode 100644 tests_python/contracts_012/macros/set_caddaadr.tz create mode 100644 tests_python/contracts_012/macros/take_my_money.tz create mode 100644 tests_python/contracts_012/macros/unpair_macro.tz create mode 100644 tests_python/contracts_012/mini_scenarios/authentication.tz create mode 100644 tests_python/contracts_012/mini_scenarios/big_map_entrypoints.tz create mode 100644 tests_python/contracts_012/mini_scenarios/big_map_magic.tz create mode 100644 tests_python/contracts_012/mini_scenarios/big_map_read.tz create mode 100644 tests_python/contracts_012/mini_scenarios/big_map_store.tz create mode 100644 tests_python/contracts_012/mini_scenarios/big_map_write.tz create mode 100644 tests_python/contracts_012/mini_scenarios/create_contract.tz create mode 100644 tests_python/contracts_012/mini_scenarios/create_contract_simple.tz create mode 100644 tests_python/contracts_012/mini_scenarios/default_account.tz create mode 100644 tests_python/contracts_012/mini_scenarios/execution_order_appender.tz create mode 100644 tests_python/contracts_012/mini_scenarios/execution_order_caller.tz create mode 100644 tests_python/contracts_012/mini_scenarios/execution_order_storer.tz create mode 100644 tests_python/contracts_012/mini_scenarios/fa12_reference.tz create mode 100644 tests_python/contracts_012/mini_scenarios/generic_multisig.tz create mode 100644 tests_python/contracts_012/mini_scenarios/groth16.tz create mode 100644 tests_python/contracts_012/mini_scenarios/hardlimit.tz create mode 100644 tests_python/contracts_012/mini_scenarios/legacy_multisig.tz create mode 100644 tests_python/contracts_012/mini_scenarios/lockup.tz create mode 100644 tests_python/contracts_012/mini_scenarios/lqt_fa12.mligo.tz create mode 100644 tests_python/contracts_012/mini_scenarios/multiple_en2.tz create mode 100644 tests_python/contracts_012/mini_scenarios/multiple_entrypoints_counter.tz create mode 100644 tests_python/contracts_012/mini_scenarios/parameterized_multisig.tz create mode 100644 tests_python/contracts_012/mini_scenarios/replay.tz create mode 100644 tests_python/contracts_012/mini_scenarios/reveal_signed_preimage.tz create mode 100644 tests_python/contracts_012/mini_scenarios/self_address_receiver.tz create mode 100644 tests_python/contracts_012/mini_scenarios/self_address_sender.tz create mode 100644 tests_python/contracts_012/mini_scenarios/ticket_builder_fungible.tz create mode 100644 tests_python/contracts_012/mini_scenarios/ticket_builder_non_fungible.tz create mode 100644 tests_python/contracts_012/mini_scenarios/ticket_wallet_fungible.tz create mode 100644 tests_python/contracts_012/mini_scenarios/ticket_wallet_non_fungible.tz create mode 100644 tests_python/contracts_012/mini_scenarios/tzip4_view.tz create mode 100644 tests_python/contracts_012/mini_scenarios/vote_for_delegate.tz create mode 100644 tests_python/contracts_012/mini_scenarios/weather_insurance.tz create mode 100644 tests_python/contracts_012/mini_scenarios/xcat.tz create mode 100644 tests_python/contracts_012/mini_scenarios/xcat_dapp.tz create mode 100644 tests_python/contracts_012/non_regression/bug_262.tz create mode 100644 tests_python/contracts_012/non_regression/pairk_annot.tz create mode 100644 tests_python/contracts_012/opcodes/abs.tz create mode 100644 tests_python/contracts_012/opcodes/add.tz create mode 100644 tests_python/contracts_012/opcodes/add_bls12_381_fr.tz create mode 100644 tests_python/contracts_012/opcodes/add_bls12_381_g1.tz create mode 100644 tests_python/contracts_012/opcodes/add_bls12_381_g2.tz create mode 100644 tests_python/contracts_012/opcodes/add_delta_timestamp.tz create mode 100644 tests_python/contracts_012/opcodes/add_timestamp_delta.tz create mode 100644 tests_python/contracts_012/opcodes/address.tz create mode 100644 tests_python/contracts_012/opcodes/amount_after_fib_view.tz create mode 100644 tests_python/contracts_012/opcodes/amount_after_nonexistent_view.tz create mode 100644 tests_python/contracts_012/opcodes/amount_after_view.tz create mode 100644 tests_python/contracts_012/opcodes/and.tz create mode 100644 tests_python/contracts_012/opcodes/and_binary.tz create mode 100644 tests_python/contracts_012/opcodes/and_logical_1.tz create mode 100644 tests_python/contracts_012/opcodes/balance.tz create mode 100644 tests_python/contracts_012/opcodes/balance_after_fib_view.tz create mode 100644 tests_python/contracts_012/opcodes/balance_after_nonexistent_view.tz create mode 100644 tests_python/contracts_012/opcodes/balance_after_view.tz create mode 100644 tests_python/contracts_012/opcodes/big_map_mem_nat.tz create mode 100644 tests_python/contracts_012/opcodes/big_map_mem_string.tz create mode 100644 tests_python/contracts_012/opcodes/big_map_to_self.tz create mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_push_bytes_not_padded.tz create mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_push_nat.tz create mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_to_int.tz create mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_to_mutez.tz create mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_z_int.tz create mode 100644 tests_python/contracts_012/opcodes/bls12_381_fr_z_nat.tz create mode 100644 tests_python/contracts_012/opcodes/bls12_381_z_fr_int.tz create mode 100644 tests_python/contracts_012/opcodes/bls12_381_z_fr_nat.tz create mode 100644 tests_python/contracts_012/opcodes/bytes.tz create mode 100644 tests_python/contracts_012/opcodes/car.tz create mode 100644 tests_python/contracts_012/opcodes/cdr.tz create mode 100644 tests_python/contracts_012/opcodes/chain_id.tz create mode 100644 tests_python/contracts_012/opcodes/chain_id_store.tz create mode 100644 tests_python/contracts_012/opcodes/check_signature.tz create mode 100644 tests_python/contracts_012/opcodes/comb-get.tz create mode 100644 tests_python/contracts_012/opcodes/comb-literals.tz create mode 100644 tests_python/contracts_012/opcodes/comb-set-2.tz create mode 100644 tests_python/contracts_012/opcodes/comb-set.tz create mode 100644 tests_python/contracts_012/opcodes/comb.tz create mode 100644 tests_python/contracts_012/opcodes/compare.tz create mode 100644 tests_python/contracts_012/opcodes/compare_big_type.tz create mode 100644 tests_python/contracts_012/opcodes/compare_big_type2.tz create mode 100644 tests_python/contracts_012/opcodes/comparisons.tz create mode 100644 tests_python/contracts_012/opcodes/concat_hello.tz create mode 100644 tests_python/contracts_012/opcodes/concat_hello_bytes.tz create mode 100644 tests_python/contracts_012/opcodes/concat_list.tz create mode 100644 tests_python/contracts_012/opcodes/cons.tz create mode 100644 tests_python/contracts_012/opcodes/contains_all.tz create mode 100644 tests_python/contracts_012/opcodes/contract.tz create mode 100644 tests_python/contracts_012/opcodes/create_contract.tz create mode 100644 tests_python/contracts_012/opcodes/create_contract_rootname.tz create mode 100644 tests_python/contracts_012/opcodes/create_contract_rootname_alt.tz create mode 100644 tests_python/contracts_012/opcodes/create_contract_with_view.tz create mode 100644 tests_python/contracts_012/opcodes/diff_timestamps.tz create mode 100644 tests_python/contracts_012/opcodes/dig_eq.tz create mode 100644 tests_python/contracts_012/opcodes/dign.tz create mode 100644 tests_python/contracts_012/opcodes/dip.tz create mode 100644 tests_python/contracts_012/opcodes/dipn.tz create mode 100644 tests_python/contracts_012/opcodes/dropn.tz create mode 100644 tests_python/contracts_012/opcodes/dugn.tz create mode 100644 tests_python/contracts_012/opcodes/dup-n.tz create mode 100644 tests_python/contracts_012/opcodes/ediv.tz create mode 100644 tests_python/contracts_012/opcodes/ediv_mutez.tz create mode 100644 tests_python/contracts_012/opcodes/empty_map.tz create mode 100644 tests_python/contracts_012/opcodes/exec_concat.tz create mode 100644 tests_python/contracts_012/opcodes/first.tz create mode 100644 tests_python/contracts_012/opcodes/get_and_update_big_map.tz create mode 100644 tests_python/contracts_012/opcodes/get_and_update_map.tz create mode 100644 tests_python/contracts_012/opcodes/get_big_map_value.tz create mode 100644 tests_python/contracts_012/opcodes/get_map_value.tz create mode 100644 tests_python/contracts_012/opcodes/hash_consistency_checker.tz create mode 100644 tests_python/contracts_012/opcodes/hash_key.tz create mode 100644 tests_python/contracts_012/opcodes/hash_string.tz create mode 100644 tests_python/contracts_012/opcodes/if.tz create mode 100644 tests_python/contracts_012/opcodes/if_some.tz create mode 100644 tests_python/contracts_012/opcodes/int.tz create mode 100644 tests_python/contracts_012/opcodes/iter_fail.tz create mode 100644 tests_python/contracts_012/opcodes/keccak.tz create mode 100644 tests_python/contracts_012/opcodes/left_right.tz create mode 100644 tests_python/contracts_012/opcodes/level.tz create mode 100644 tests_python/contracts_012/opcodes/list_concat.tz create mode 100644 tests_python/contracts_012/opcodes/list_concat_bytes.tz create mode 100644 tests_python/contracts_012/opcodes/list_id.tz create mode 100644 tests_python/contracts_012/opcodes/list_id_map.tz create mode 100644 tests_python/contracts_012/opcodes/list_iter.tz create mode 100644 tests_python/contracts_012/opcodes/list_map_block.tz create mode 100644 tests_python/contracts_012/opcodes/list_size.tz create mode 100644 tests_python/contracts_012/opcodes/loop_failwith.tz create mode 100644 tests_python/contracts_012/opcodes/loop_left.tz create mode 100644 tests_python/contracts_012/opcodes/loop_left_failwith.tz create mode 100644 tests_python/contracts_012/opcodes/map_car.tz create mode 100644 tests_python/contracts_012/opcodes/map_id.tz create mode 100644 tests_python/contracts_012/opcodes/map_iter.tz create mode 100644 tests_python/contracts_012/opcodes/map_map.tz create mode 100644 tests_python/contracts_012/opcodes/map_map_sideeffect.tz create mode 100644 tests_python/contracts_012/opcodes/map_mem_nat.tz create mode 100644 tests_python/contracts_012/opcodes/map_mem_string.tz create mode 100644 tests_python/contracts_012/opcodes/map_size.tz create mode 100644 tests_python/contracts_012/opcodes/merge_comparable_pairs.tz create mode 100644 tests_python/contracts_012/opcodes/mul.tz create mode 100644 tests_python/contracts_012/opcodes/mul_bls12_381_fr.tz create mode 100644 tests_python/contracts_012/opcodes/mul_bls12_381_g1.tz create mode 100644 tests_python/contracts_012/opcodes/mul_bls12_381_g2.tz create mode 100644 tests_python/contracts_012/opcodes/mul_overflow.tz create mode 100644 tests_python/contracts_012/opcodes/munch.tz create mode 100644 tests_python/contracts_012/opcodes/mutez_to_bls12_381_fr.tz create mode 100644 tests_python/contracts_012/opcodes/neg.tz create mode 100644 tests_python/contracts_012/opcodes/neg_bls12_381_fr.tz create mode 100644 tests_python/contracts_012/opcodes/neg_bls12_381_g1.tz create mode 100644 tests_python/contracts_012/opcodes/neg_bls12_381_g2.tz create mode 100644 tests_python/contracts_012/opcodes/none.tz create mode 100644 tests_python/contracts_012/opcodes/noop.tz create mode 100644 tests_python/contracts_012/opcodes/not.tz create mode 100644 tests_python/contracts_012/opcodes/not_binary.tz create mode 100644 tests_python/contracts_012/opcodes/or.tz create mode 100644 tests_python/contracts_012/opcodes/or_binary.tz create mode 100644 tests_python/contracts_012/opcodes/originate_big_map.tz create mode 100644 tests_python/contracts_012/opcodes/packunpack.tz create mode 100644 tests_python/contracts_012/opcodes/packunpack_rev.tz create mode 100644 tests_python/contracts_012/opcodes/packunpack_rev_cty.tz create mode 100644 tests_python/contracts_012/opcodes/pair_id.tz create mode 100644 tests_python/contracts_012/opcodes/pairing_check.tz create mode 100644 tests_python/contracts_012/opcodes/pexec.tz create mode 100644 tests_python/contracts_012/opcodes/pexec_2.tz create mode 100644 tests_python/contracts_012/opcodes/proxy.tz create mode 100644 tests_python/contracts_012/opcodes/ret_int.tz create mode 100644 tests_python/contracts_012/opcodes/reverse.tz create mode 100644 tests_python/contracts_012/opcodes/reverse_loop.tz create mode 100644 tests_python/contracts_012/opcodes/sapling_empty_state.tz create mode 100644 tests_python/contracts_012/opcodes/self.tz create mode 100644 tests_python/contracts_012/opcodes/self_address.tz create mode 100644 tests_python/contracts_012/opcodes/self_address_after_fib_view.tz create mode 100644 tests_python/contracts_012/opcodes/self_address_after_nonexistent_view.tz create mode 100644 tests_python/contracts_012/opcodes/self_address_after_view.tz create mode 100644 tests_python/contracts_012/opcodes/self_after_fib_view.tz create mode 100644 tests_python/contracts_012/opcodes/self_after_nonexistent_view.tz create mode 100644 tests_python/contracts_012/opcodes/self_after_view.tz create mode 100644 tests_python/contracts_012/opcodes/self_with_default_entrypoint.tz create mode 100644 tests_python/contracts_012/opcodes/self_with_entrypoint.tz create mode 100644 tests_python/contracts_012/opcodes/sender.tz create mode 100644 tests_python/contracts_012/opcodes/sender_after_fib_view.tz create mode 100644 tests_python/contracts_012/opcodes/sender_after_nonexistent_view.tz create mode 100644 tests_python/contracts_012/opcodes/sender_after_view.tz create mode 100644 tests_python/contracts_012/opcodes/set_car.tz create mode 100644 tests_python/contracts_012/opcodes/set_cdr.tz create mode 100644 tests_python/contracts_012/opcodes/set_delegate.tz create mode 100644 tests_python/contracts_012/opcodes/set_id.tz create mode 100644 tests_python/contracts_012/opcodes/set_iter.tz create mode 100644 tests_python/contracts_012/opcodes/set_member.tz create mode 100644 tests_python/contracts_012/opcodes/set_size.tz create mode 100644 tests_python/contracts_012/opcodes/sets.tz create mode 100644 tests_python/contracts_012/opcodes/sha3.tz create mode 100644 tests_python/contracts_012/opcodes/shifts.tz create mode 100644 tests_python/contracts_012/opcodes/slice.tz create mode 100644 tests_python/contracts_012/opcodes/slice_bytes.tz create mode 100644 tests_python/contracts_012/opcodes/slices.tz create mode 100644 tests_python/contracts_012/opcodes/source.tz create mode 100644 tests_python/contracts_012/opcodes/split_bytes.tz create mode 100644 tests_python/contracts_012/opcodes/split_string.tz create mode 100644 tests_python/contracts_012/opcodes/store_bls12_381_fr.tz create mode 100644 tests_python/contracts_012/opcodes/store_bls12_381_g1.tz create mode 100644 tests_python/contracts_012/opcodes/store_bls12_381_g2.tz create mode 100644 tests_python/contracts_012/opcodes/store_input.tz create mode 100644 tests_python/contracts_012/opcodes/store_now.tz create mode 100644 tests_python/contracts_012/opcodes/str_id.tz create mode 100644 tests_python/contracts_012/opcodes/sub_timestamp_delta.tz create mode 100644 tests_python/contracts_012/opcodes/subset.tz create mode 100644 tests_python/contracts_012/opcodes/tez_add_sub.tz create mode 100644 tests_python/contracts_012/opcodes/ticket_bad.tz create mode 100644 tests_python/contracts_012/opcodes/ticket_big_store.tz create mode 100644 tests_python/contracts_012/opcodes/ticket_join.tz create mode 100644 tests_python/contracts_012/opcodes/ticket_read.tz create mode 100644 tests_python/contracts_012/opcodes/ticket_split.tz create mode 100644 tests_python/contracts_012/opcodes/ticket_store-2.tz create mode 100644 tests_python/contracts_012/opcodes/ticket_store.tz create mode 100644 tests_python/contracts_012/opcodes/ticketer-2.tz create mode 100644 tests_python/contracts_012/opcodes/ticketer.tz create mode 100644 tests_python/contracts_012/opcodes/transfer_amount.tz create mode 100644 tests_python/contracts_012/opcodes/transfer_tokens.tz create mode 100644 tests_python/contracts_012/opcodes/uncomb.tz create mode 100644 tests_python/contracts_012/opcodes/unpair.tz create mode 100644 tests_python/contracts_012/opcodes/update_big_map.tz create mode 100644 tests_python/contracts_012/opcodes/utxo_read.tz create mode 100644 tests_python/contracts_012/opcodes/utxor.tz create mode 100644 tests_python/contracts_012/opcodes/view_fib.tz create mode 100644 tests_python/contracts_012/opcodes/view_mutual_recursion.tz create mode 100644 tests_python/contracts_012/opcodes/view_op_add.tz create mode 100644 tests_python/contracts_012/opcodes/view_op_constant.tz create mode 100644 tests_python/contracts_012/opcodes/view_op_id.tz create mode 100644 tests_python/contracts_012/opcodes/view_op_nonexistent_addr.tz create mode 100644 tests_python/contracts_012/opcodes/view_op_nonexistent_func.tz create mode 100644 tests_python/contracts_012/opcodes/view_op_test_step_contants.tz create mode 100644 tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_input_type.tz create mode 100644 tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_output_type.tz create mode 100644 tests_python/contracts_012/opcodes/view_rec.tz create mode 100644 tests_python/contracts_012/opcodes/view_toplevel_lib.tz create mode 100644 tests_python/contracts_012/opcodes/voting_power.tz create mode 100644 tests_python/contracts_012/opcodes/xor.tz create mode 100644 tests_python/tests_012/__init__.py create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_legacy_flag.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[None].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized_legacy].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Readable].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool bytes)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list nat].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[nat].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool bytes].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[None].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized_legacy].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Readable].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fac.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fib.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_mutual_recursion.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_add.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_id.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_addr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_func.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_test_step_contants.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_input_type.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_output_type.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_rec.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_toplevel_lib.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_receiver.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_sender.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_send_self_address.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--accounts.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1_list.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--after_strategy.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--always.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--append.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--at_least.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--auction.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--bad_lockup.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--big_map_union.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cadr_annotation.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--concat.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--conditionals.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cons_twice.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cps_fact.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--create_add1_lists.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--data_publisher.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--dispatch.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--empty.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--fail_amount.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--faucet.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--forward.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--id.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--infinite_loop.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--insertion_sort.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--int_publisher.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--king_of_tez.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--list_of_transactions.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--queue.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reduce_map.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reentrancy.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reservoir.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--scrutable_reservoir.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--spawn_identities.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpeq.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpge.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpgt.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmple.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmplt.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpneq.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_eq.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_ge.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_gt.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_le.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_lt.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_neq.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_get_add.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_mem.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--build_list.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--carn_and_cdrn.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare_bytes.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--fail.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--guestbook.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--macro_annotations.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--map_caddaadr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--max_in_list.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--min.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--pair_macro.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--set_caddaadr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--take_my_money.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--unpair_macro.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--authentication.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_entrypoints.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_magic.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_read.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_store.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_write.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract_simple.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--default_account.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_appender.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_caller.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_storer.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--fa12_reference.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--generic_multisig.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--groth16.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--hardlimit.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--legacy_multisig.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lockup.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lqt_fa12.mligo.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_en2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_entrypoints_counter.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--parameterized_multisig.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--replay.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--reveal_signed_preimage.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_receiver.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_sender.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_fungible.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_non_fungible.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_fungible.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_non_fungible.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--tzip4_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--vote_for_delegate.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--weather_insurance.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat_dapp.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--bug_262.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--pairk_annot.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--abs.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_fr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g1.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_delta_timestamp.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_timestamp_delta.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--address.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_fib_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_nonexistent_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_binary.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_logical_1.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_fib_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_nonexistent_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_nat.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_string.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_to_self.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_bytes_not_padded.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_nat.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_int.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_mutez.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_int.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_nat.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_int.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_nat.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bytes.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--car.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cdr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id_store.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--check_signature.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-get.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-literals.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set-2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comparisons.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello_bytes.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_list.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cons.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contains_all.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contract.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname_alt.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_with_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--diff_timestamps.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dig_eq.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dign.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dip.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dipn.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dropn.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dugn.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dup-n.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv_mutez.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--empty_map.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--exec_concat.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--first.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_big_map.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_map.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_big_map_value.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_map_value.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_consistency_checker.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_key.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_string.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if_some.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--int.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--iter_fail.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--keccak.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--left_right.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--level.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat_bytes.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id_map.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_iter.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_map_block.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_size.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_failwith.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left_failwith.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_car.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_id.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_iter.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map_sideeffect.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_nat.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_string.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_size.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--merge_comparable_pairs.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_fr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g1.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_overflow.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--munch.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mutez_to_bls12_381_fr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_fr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g1.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--none.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--noop.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not_binary.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or_binary.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--originate_big_map.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev_cty.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pair_id.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pairing_check.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec_2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--proxy.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ret_int.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse_loop.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sapling_empty_state.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_fib_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_nonexistent_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_fib_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_nonexistent_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_default_entrypoint.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_entrypoint.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_fib_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_nonexistent_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_view.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_car.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_cdr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_delegate.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_id.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_iter.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_member.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_size.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sets.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sha3.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--shifts.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice_bytes.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slices.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--source.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_bytes.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_string.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_fr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g1.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_input.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_now.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--str_id.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sub_timestamp_delta.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--subset.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--tez_add_sub.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_bad.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_big_store.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_join.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_read.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_split.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store-2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer-2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_amount.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_tokens.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--uncomb.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--unpair.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--update_big_map.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxo_read.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxor.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_fib.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_mutual_recursion.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_add.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_constant.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_id.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_addr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_func.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_test_step_contants.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_input_type.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_output_type.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_rec.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_toplevel_lib.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--voting_power.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--xor.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_groth16.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g1.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g2.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_nil.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_one.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_random.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_zero.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_one.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_random.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_zero.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_one.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_random.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_zero.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_signature_aggregation.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[Fr].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpeq.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpge.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpgt.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmple.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmplt.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpneq.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_eq.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_ge.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_gt.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_le.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_lt.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_neq.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_get_add.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_mem.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--build_list.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--carn_and_cdrn.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare_bytes.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--fail.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--guestbook.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--macro_annotations.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--map_caddaadr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--max_in_list.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--min.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--pair_macro.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--set_caddaadr.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--take_my_money.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--unpair_macro.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_diff.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_id.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_literal.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_diff.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_id.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainLevel::test_level.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_contract_fails.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_gen_keys.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_init_proxy.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_now.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_self.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_sender.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_set_delegate.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice.out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 \"spsig1PPUFZucuAQybs5wsqs.818025e860.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.2d6806d54e.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.378d03ae2d.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.57fdc7ad1c.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75.c583c796bf.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_source.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_bytes.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_string.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_amount.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_tokens.out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0427752f13.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0793dc66d5.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .df114499b8.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .f9bea98de9.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"hello\" 4 })-.1db12cd837.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-\"hello\"-(Pair N.6fc7d0acf2.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"tw.524c5459f8.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"\".33eba403e7.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"h.a5cd1005c9.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .6f3d35b151.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .76aeaa0706.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7e7197f248.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .b688cc94a7.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .c68db221ed.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0.5].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1000].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1e-06].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[5].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[8000000000000.0].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }) )-(Right (Righ.7492e8cdea.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Left Unit)-(.21b30dd90f.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .2873ef610c.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .8a6f480005.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Right.d336ca1903.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair \"foo\" \"bar\" } { P.7f2ee47600.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_check_signature.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000.3c2de60480.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000.12b2c1172b.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x010.0e44fc6f40.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0.7e0ed229a3.out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some \"1970.7c1b1e4e5b.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 \"1970-01-01T00:00:0.528ed42c01.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some \"1970-.6566111ad2.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair \"1970-01-01T00:00:00Z.72c424f3da.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some \"1970.7c4b12e9aa.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some \"1970-.af32743640.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[address.tz-None-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.73700321f8.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.1182eca937.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.1eead33885.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\".968709d39d.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair 4 (Some False))].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x100000000000.d1219ca789.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f2.7a85c336ff.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986.b821eb26b3.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0accef5bef.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0ecc537252.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2229b767cd.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2ff549b46b.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.bf8a711be6.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.d41cbb044b.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.a50412e458.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.f3a349c4a7.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.1b9676e4c2.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.e966dc6de5.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.964835cc43.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.b25ea709fb.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.eae36753ea.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.ee57dac8f7.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.bd5800f6b8.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.00e897789a.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.a4697eaa13.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.0177355bbf.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.744166c609.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.9f3c5cdc6a.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.a54cb341ba.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.b0dc584c94.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.bddcad090c.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.92c153eb47.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.290ab49d11.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.69f3589a06.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.fee3c5cf43.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.1bccc033e8.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.40958700fe.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.6c62b03d78.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.d23f269341.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.927f808504.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.0c114c956a.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.03c4f38e68.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.8ed19cfdd9.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some \"NetXdQprcVkpaWU\")-Unit-(Some \".8420090f97.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some \"NetXdQprcVkpaWU\")].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"World!\" }-{ \"Hello World!\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"test1\" ; \"test2\" }-{ \"Hello test1.c27e8c3ee6.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"Hello\" ; \" \" ; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{}-\"\"].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"A\" } { \"B\" })-(Some False)].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" } { \"B\" })-(Some True)].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"c\" } { \"B\" })-(Some False)].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contract.tz-Unit-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair \"1970-01-01T00:03:20Z\" \"19.90e9215d17.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (.3caea50555.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair No.f9448c04fb.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (So.f782cc1dec.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Som.016b4db96c.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (.e705a30e07.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (S.44485eda6a.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (S.8ab987af15.out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt \"hello\" \"world\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"test\"-\"test_abc\"].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-\"hello\"-(Pair .161d86cef6.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).684ab7e326.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).d49817fb83.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .6900b1da14.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .bca0ede8be.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-\"hello\"-(Pair None {})].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"1\" \"one\" ; .bc4127094e.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"\"-(P.0c03056487.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"hell.cc45544c66.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"12345\"-0xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"abcdefg\"-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-(Some \"hello\")-\"hello\"].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-None-\"\"].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e.34c02678c9.out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Left True)-(Right True)].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Right \"a\")-(Left \"a\")].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{}-\"abc\"].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{}-{}].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{}-{}].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{}-{}].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"bar\" 5 ; Elt \"foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 .7396e5f090.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair {} (Some False))].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 }-1].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000.be11332c7f.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x10000000000000000000.8230fb4fac.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".368bdfd73a.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".735d9ae802.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.4e20b52378.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{}-{}].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{}-{}].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"world\"-(Pair \"world\" 0)].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 0)-1-(Pair \"hello\" 1)].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 500)-3-(Pair \"hello\" 3)].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 7)-100-(Pair \"hello\" 100)].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"asdf\" ; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hello\" ; \"World\" } None)-\"\"-(Pai.3d2044726e.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hi\" } None)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-\"Hi\"-(Pair {} (Some False))].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a.a07ae9dddf.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 10-None].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 3-None].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 10 5-None].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some\"FooFooFooFooFooFooFooFooFooFooFooFooFooFo.c508d67bb0.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaab.df5895de85.out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"Hello\"-(Some \"Hello\")].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"abcd\"-(Some \"abcd\")].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-\"1970-01-01T00:03:20Z\"].out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-\"1970-01-01T00:00:00Z\"].out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 200000000000000000.3db82d2c25.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair .b461aa042b.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair .1e8cf7679c.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit].out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-\"edpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_hash_consistency_michelson_cli.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_level.out create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" create mode 100644 "tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_now.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_packunpack.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_add_liquidity.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approval.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approved_transfer.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve1.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve2.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve3.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_mint_or_burn.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_dex_storage.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_lqt_storage.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_setup.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_tok_storage.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_add_liquidity.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve1.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve2.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve3.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_mint_or_burn.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_dex_storage.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_lqt_storage.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_setup.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_tok_storage.out create mode 100644 tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_transfer.out create mode 100644 tests_python/tests_012/conftest.py create mode 100644 tests_python/tests_012/contract_paths.py create mode 100644 tests_python/tests_012/per_block_vote_files/false.json create mode 100644 tests_python/tests_012/per_block_vote_files/invalid.json create mode 100644 tests_python/tests_012/per_block_vote_files/non_boolean.json create mode 100644 tests_python/tests_012/per_block_vote_files/true.json create mode 100644 tests_python/tests_012/per_block_vote_files/wrong_key.json create mode 100644 tests_python/tests_012/protocol.py create mode 100644 tests_python/tests_012/test_accuser.py create mode 100644 tests_python/tests_012/test_baker_endorser.py create mode 100644 tests_python/tests_012/test_basic.py create mode 100644 tests_python/tests_012/test_binaries.py create mode 100644 tests_python/tests_012/test_bootstrap.py create mode 100644 tests_python/tests_012/test_client.py create mode 100644 tests_python/tests_012/test_client_without_node.py create mode 100644 tests_python/tests_012/test_codec.py create mode 100644 tests_python/tests_012/test_contract.py create mode 100644 tests_python/tests_012/test_contract_annotations.py create mode 100644 tests_python/tests_012/test_contract_baker.py create mode 100644 tests_python/tests_012/test_contract_bls12_381.py create mode 100644 tests_python/tests_012/test_contract_macros.py create mode 100644 tests_python/tests_012/test_contract_onchain_opcodes.py create mode 100644 tests_python/tests_012/test_contract_opcodes.py create mode 100644 tests_python/tests_012/test_cors.py create mode 100644 tests_python/tests_012/test_crypto.py create mode 100644 tests_python/tests_012/test_fa12.py create mode 100755 tests_python/tests_012/test_forge_block.py create mode 100644 tests_python/tests_012/test_fork.py create mode 100644 tests_python/tests_012/test_injection.py create mode 100644 tests_python/tests_012/test_liquidity_baking.py create mode 100644 tests_python/tests_012/test_many_bakers.py create mode 100644 tests_python/tests_012/test_many_nodes.py create mode 100644 tests_python/tests_012/test_mempool.py create mode 100644 tests_python/tests_012/test_migration.py create mode 100644 tests_python/tests_012/test_mockup.py create mode 100644 tests_python/tests_012/test_multinode_snapshot.py create mode 100644 tests_python/tests_012/test_multinode_storage_reconstruction.py create mode 100644 tests_python/tests_012/test_multiple_transfers.py create mode 100644 tests_python/tests_012/test_multisig.py create mode 100644 tests_python/tests_012/test_nonce_seed_revelation.py create mode 100644 tests_python/tests_012/test_openapi.py create mode 100644 tests_python/tests_012/test_p2p.py create mode 100644 tests_python/tests_012/test_per_block_votes.py create mode 100644 tests_python/tests_012/test_programs.py create mode 100644 tests_python/tests_012/test_proto_demo_counter.py create mode 100644 tests_python/tests_012/test_proto_demo_noops_manual_bake.py create mode 100644 tests_python/tests_012/test_rpc.py create mode 100644 tests_python/tests_012/test_sapling.py create mode 100644 tests_python/tests_012/test_slice_fails_params.txt create mode 100644 tests_python/tests_012/test_slice_success_params.txt create mode 100644 tests_python/tests_012/test_tenderbake.py create mode 100644 tests_python/tests_012/test_tenderbake_bakers_restart.py create mode 100644 tests_python/tests_012/test_tenderbake_incremental_start.py create mode 100644 tests_python/tests_012/test_tenderbake_long_dynamic_bake.py create mode 100644 tests_python/tests_012/test_tenderbake_manual_bake.py create mode 100755 tests_python/tests_012/test_tls.py create mode 100644 tests_python/tests_012/test_voting.py create mode 100644 tests_python/tests_012/test_voting_full.py diff --git a/docs/012/cli-commands.rst b/docs/012/cli-commands.rst new file mode 100644 index 000000000000..695a9d3f3d19 --- /dev/null +++ b/docs/012/cli-commands.rst @@ -0,0 +1,41 @@ +********************** +Command Line Interface +********************** + +This document is a prettier output of the documentation produced by +the command ``man`` of the different Tezos binaries. You can obtain similar pages +using shell commands such as (:ref:`indicating the appropriate protocol `): + +:: + + tezos-client -protocol man -verbosity 3 + +The rest of this page documents the protocol-dependent tools. +The protocol-independent tools are documented :doc:`here <../shell/cli-commands>`. + + +.. _client_manual_012: + +Client manual +============= + +.. raw:: html + :file: tezos-client.html + + +.. _baker_manual_012: + +Baker manual +============ + +.. raw:: html + :file: tezos-baker.html + + +.. _accuser_manual_012: + +Accuser manual +============== + +.. raw:: html + :file: tezos-accuser.html diff --git a/docs/012/consensus.rst b/docs/012/consensus.rst new file mode 100644 index 000000000000..bbc3972283dd --- /dev/null +++ b/docs/012/consensus.rst @@ -0,0 +1,453 @@ +The consensus algorithm +======================= + +This document provides a high-level description of Tenderbake, the Tezos +:doc:`proof-of-stake` consensus algorithm, as implemented in the +I protocol. + +History +------- + +Before Tenderbake, there was +`Emmy* `_, +a Nakamoto-style consensus consisting of a series of improvements of the one in +the `Tezos whitepaper `_. + +Emmy*, like any Nakamoto-style consensus algorithm (such as `Bitcoin +`_ or `Ouroboros +`_), offers *probabilistic* +finality: forks of arbitrary length are possible but they collapse +with a probability that increases rapidly with fork length. + +`Tenderbake `_ instead, like any classic +BFT-style consensus algorithm (such as +`PBFT `_ or +`Tendermint `_), offers *deterministic* +finality: a block that has just been appended to the chain of some node is known +to be final once it has two additional blocks on top of it, regardless of +network latency. + + +Overview +-------- + +The starting point for Tenderbake is +`Tendermint `_, the first classic-style algorithm +for blockchains. + +Tenderbake adapts Tendermint to the Tezos blockchain, but the adjustments +required are +`substantive `_: + +* Tenderbake is tailored to match the Tezos architecture by using only + communication primitives and network assumptions which Tezos supports. +* Tenderbake makes weaker network assumptions than Tendermint, at the price of + adding the extra assumption that participants have loosely synchronized clocks + — which is fine, because Tezos already uses them. + +The design of Tenderbake and its rationale are described at +length in the `technical report `_ and in a +`Nomadic Labs's blog +post `_. Here we +only provide a user/developer perspective. +Tenderbake is executed for each new block level by a "committee" whose members +are called *validators*, which are delegates selected at random based on their +stake, in the same way as endorsers are selected in Emmy*. We let +``CONSENSUS_COMMITTEE_SIZE`` be the number of validator slots per level. This +constant has the role of ``ENDORSERS_PER_BLOCK`` in Emmy*. + +For each level, Tenderbake proceeds in rounds. Each *round* represents an +attempt by the validators to agree on the content of the block for the current +level, that is, on the sequence of non-consensus operations the block contains. +We call this sequence the block's *payload*. + +Each round has an associated duration. Round durations are set to increase so +that for any possible message delay, there is a round that is sufficiently long +for all required messages to be exchanged. +Round durations depend on protocol parameters ``MINIMAL_BLOCK_DELAY`` and ``DELAY_INCREMENT_PER_ROUND``. +These parameters specify round durations as follows: + +.. math:: + + round\_duration(0) &= minimal\_block\_delay \\ + round\_duration(r+1) &= round\_duration(r) + delay\_increment\_per\_round \\ + & = minimal\_block\_delay + (r + 1) * delay\_increment\_per\_round + +Round durations thus increase linearly with ``DELAY_INCREMENT_PER_ROUND``. + +Schematically, a round consists in the following steps: + +* a validator designated for that round injects a *candidate block* (representing a proposal) and consensus operations (representing votes) into the node to which it is attached, which then +* diffuses those blocks and consensus operations to other nodes of the network, and thus +* communicates them to the validators attached to those nodes, to carry out voting on which block to accept. + +Unlike Emmy*, Tenderbake has `two types of +votes `_: +before endorsing a block ``b``, a validator preendorses ``b``. Furthermore, +to be able to endorse, a validator must have observed a preendorsement *quorum*, that is a +set of preendorsements from validators having at least :math:`\lceil CONSENSUS\_COMMITTEE\_SIZE \times \frac{2}{3} \rceil` validator slots. Similarly, to be able to decide, a validator must have observed an endorsement quorum, that is, a set of endorsements from validators having at least :math:`\lceil CONSENSUS\_COMMITTEE\_SIZE \times \frac{2}{3} \rceil` validator slots. The +endorsement quorum for a block ``b`` is included in a block ``b'`` on top of ``b``, +serving as a certification that ``b`` has been agreed upon. +We also say that block ``b'`` confirms block ``b``. + +The validator's whose turn is to inject a candidate block at a given round is +called the *proposer* at that round. Proposers in Tenderbake are selected +similarly to bakers in Emmy*: the proposer at round ``r`` is the +validator who has the validator slot ``r``. A proposer who has observed a +preendorsement quorum for a candidate block in a previous round, is required to propose a block with +the same *payload* as +the initial block. We talk about a *re-proposal* in this case. + + +.. _finality_012: + +Transaction and block finality +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A transaction is final as soon as the block including it has a confirmation (that is, a block on top of it). +Indeed, as hinted above, a block contains the certification (that is, the endorsement quorum) for the previous +payload. Thanks to the endorsement quorum, Tenderbake guarantees **transaction finality +after 1 confirmation**. + +It may be possible that different validators decide at different rounds, though on the same payload. The blocks at these different rounds differ precisely because they contain, in the header, as part of the block fitness, +the round at which they were proposed. +Among these "candidate" blocks, the block with the smallest round has the highest fitness and so it will be the one decided. +Consequently, to agree on a block, that is, on both the payload and the header, Tenderbake needs one more +confirmation, and thus guarantees +**block finality after 2 confirmations**. + +Time between blocks +~~~~~~~~~~~~~~~~~~~~~~~ + +The time between blocks represents the difference between the timestamps of the blocks. The timestamp of a block is given by the beginning of the round at which the block has been agreed upon. Thus, the time between blocks depends on the round at which decisions are taken. For +example, if the decision at the previous level was taken at round 4 and at the current level at round 2, then the current block's delay relative to +its predecessor, is :math:`round\_duration(4) + round\_duration(0) + round\_duration(1)`. +The general case is as follows, say that the decision at the previous +level is taken at round ``m`` and the decision at the current level is +taken at round ``n``, then the current block's delay relative to its +predecessor is :math:`round\_duration(m) + \sum_{i=0}^{n-1} round\_duration(i)`. +We note that, under +normal network conditions, and with active and compliant validators, decisions +should be taken at round 0, meaning that the time between blocks would be +:math:`round\_duration(0)` seconds i.e., parameter ``MINIMAL_BLOCK_DELAY``. + + +Validator selection: staking balance, active stake, and frozen deposits +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Validator selection is based on the stake, as in Emmy*, with the exception that +it is based on the delegate's *active stake* instead of its *staking +balance* (or rather the corresponding rolls. +**NB**: rolls do not play a +role anymore, except for establishing a minimum required staking +balance). Let us first (re)define these and related concepts. + +- The *(maximal) staking balance* of a delegate is its full balance (i.e. all the tokens owned by the delegate) plus the + balances of all accounts that have delegated to it. +- The *active stake* of a delegate is the amount of tez with which + it participates in consensus. It is at most its + staking balance. It must be at least ``TOKEN_PER_ROLL`` tez. We explain below how it is computed. +- The *frozen deposit* represents a percentage ``FROZEN_DEPOSIT_PERCENTAGE`` + of the maximum active stake during the last ``PRESERVED_CYCLES + MAX_SLASHING_PERIOD``. This amount + represents the delegate's skin in the game: in the case that the + delegate behaves badly, its frozen deposit is partly slashed (see + :ref:`slashing_012`). Taking the maximum over an + interval of cycles (instead of just considering the active stake at + the cycle where the bad action can occur) allows to avoid situations + where a malicious delegate empties its accounts between the time when + rights are attributed and the time when the deposit is frozen. The frozen deposits are updated at the end of each cycle. +- The *spendable balance* of a delegate is its full balance + minus the frozen deposits. + +We state next the RPCs which allow to retrieve these types of balances, and also some invariants about them +(Note that these are just invariants, not definitions; for +instance, the frozen deposits are computed in terms of the full balance, +not the other way around.): + +- ``delegated balance`` represents the total amount of tokens delegated by others to a + given delegate; it excludes the delegate's full balance; it is obtained + with ``../context/delegates//delegated_balance`` +- ``staking balance = full balance + delegated balance``; it is obtained with + ``../context/delegates//staking_balance`` +- ``full balance = spendable balance + frozen deposit``; it is obtained with + ``../context/delegates//full_balance`` +- ``frozen deposit`` is obtained with ``../context/delegates//frozen_deposits`` +- ``spendable balance`` is obtained with ``../context/contracts//balance`` + +Delegates can set an upper limit to their frozen deposits with the +commands ``tezos-client set deposit limit for to +``, and unset this limit with the command ``tezos-client +unset deposit limit for ``. These commands are implemented by +using a new manager operation ``Set_deposits_limit``. When emitting such a +command in cycle ``c``, it affects the active stake for cycles starting +with ``c + PRESERVED_CYCLES + 1``; the new active stake is +taken into account when computing the frozen deposit for cycle ``c+1`` +already, however the user may see an update to its frozen deposit at +cycle ``c + PRESERVED_CYCLES + MAX_SLASHING_PERIOD`` at the +latest (because up to that cycle the frozen deposit also depends on the +active stake at cycles before cycle ``c+1``). + +The active stake is computed ``PRESERVED_CYCLES`` in advance: at +the end of cycle ``c`` for cycle ``c + PRESERVED_CYCLES`` (as in Emmy*). Intuitively, +the active stake is set to 10 times the delegate's chosen frozen +deposit limit, without going beyond its available staking balance, +nor its maximum staking capacity (determined by its full balance). +More precisely, the active stake is the minimum between: + +- the delegate's staking balance, and +- 10 times the delegate's *deposit cap*, i.e. ``deposit_cap * 100 / deposit_percentage``. If the delegate has not set a frozen deposit limit, ``deposit_cap`` is its full balance. Otherwise ``deposit_cap`` is the minimum between its full balance and the frozen deposit limit set by the delegate. + +Let's take some examples. Say that the full balance of a delegate is ``1000`` tez. +Then its theoretical maximum staking balance is +``10000`` tez. The following table lists some scenarios (assuming for +simplicity no changes in the delegate's full and staking balances +during the last 8 cycles). + +.. list-table:: + :widths: 20 20 20 20 20 + :header-rows: 1 + + * - Staking balance + - Frozen deposit limit + - Active stake + - Frozen deposit + - Spendable balance + * - 9000 + - -- + - 9000 + - 900 + - 100 + * - 12000 + - -- + - 10000 + - 1000 + - 0 + * - 9000 + - 400 + - 4000 + - 400 + - 600 + * - 12000 + - 400 + - 4000 + - 400 + - 600 + +We note in passing that this new schema basically solves the main +problem of over-delegation: a delegate will not fail anymore to bake +and endorse because of an insufficient balance to pay the +deposit. However, a delegate can still be over-delegated, and it will be +rewarded based on its active stake, not on its staking balance. + +Economic Incentives +~~~~~~~~~~~~~~~~~~~ + +As Emmy*, Tenderbake rewards participation in consensus and punishes bad +behavior. Notable changes however are as follows: + +* Fees and baking rewards go to the payload producer, the one who selected the + transactions to be included in the block (and was the first to propose a + block with that payload). In case of re-proposal, the payload producer might + be different from the block proposer, the baker who injects the block. +* Including extra endorsements, that is, more than the minimal required to + obtain a quorum, is rewarded with a bonus. +* Endorsing rewards are shared equally among all validators. Participation above + a minimal threshold per cycle is however required. +* Deposits are no longer frozen and unfrozen, instead a percentage of the active stake is always locked. +* Validators are rewarded instantaneously for baking blocks and including extra endorsements, and not at the end of the cycle like in Emmy*. +* At the end of a cycle ``c``, the following actions happen: + + - the selection of the consensus committee cycle ``c + PRESERVED_CYCLES``, based on the current active stake distribution, + - the distribution of endorsing rewards, + - the adjustment of frozen deposits. + + +Fees +^^^^ + +The fees associated to the transactions included in a block go to the payload +producer. This is only natural given that this is the validator that selects the +transactions to be included; see `an in-depth blog +post `_ for further motivation. + +The payload producer is usually the same delegate as the block +proposer (that is, the one that signs and injects the block): that's +always true for blocks at round 0; however, in case of re-proposals +this is not necessarily the case (see the algorithm description above). + +Fees are given to the payload producer immediately, that is, they are +already reflected in the blockchain state obtained after applying the injected +block. + +Rewards +^^^^^^^ + +There are three kinds of rewards: baking rewards, endorsing rewards, and a bonus for including extra endorsements. + +The baking rewards are treated in the same way as fees: they go to the *payload* +producer and are distributed immediately. + +To encourage fairness and participation, the *block* proposer receives +a bonus for the extra endorsements it includes in the block. +The bonus is proportional to the number of +validator slots above the threshold of :math:`\lceil CONSENSUS\_COMMITTEE\_SIZE \times \frac{2}{3} \rceil` that +the included endorsements represent. The bonus is also distributed +immediately. + +The endorsing rewards are shared among all validators, proportionally +to their *expected* number of validator slots. The endorsing reward +may be received even if the validator's endorsement is not included in +a block. However, two conditions must be met: + + - the validator has revealed its nonce, and + - the validator has been present during the cycle. + +Not giving rewards in case of missing revelations is not new as it is :ref:`adapted` +from Emmy*. +The second condition is new. We say that a delegate is *present* during a cycle +if the endorsing power (that is, the number of validator slots at the +corresponding level) of all the endorsements included by the delegate during the +cycle represents at least ``MINIMAL_PARTICIPATION_RATIO`` of the delegate's expected number of +validator slots for the current cycle (which is ``BLOCKS_PER_CYCLE * +CONSENSUS_COMMITTEE_SIZE * active_stake / total_active_stake``). +The endorsing rewards are distributed at the end of the cycle. + +Regarding the concrete values for rewards, we first fix the total reward per +level, call it ``total_rewards``, to ``80 / blocks_per_minute`` tez. +Assuming ``blocks_per_minute = 2``, ``total_rewards`` is 40 tez. +We define: + +- ``BAKING_REWARD_FIXED_PORTION := baking_reward_ratio * total_rewards`` +- ``bonus := (1 - baking_reward_ratio) * bonus_ratio * total_rewards`` is the max bonus +- ``endorsing_reward := (1 - baking_reward_ratio) * (1 - bonus_ratio) * total_rewards`` + +where: + +- ``baking_reward_ratio`` to ``1 / 4``, +- ``bonus_ratio`` to ``1 / 3``. + +Thus, we obtain ``BAKING_REWARD_FIXED_PORTION = 10`` tez, +(maximum) ``bonus = 10`` tez, and ``endorsing_rewards = 20`` tez. +The bonus per additional endorsement slot is in turn ``bonus / +(CONSENSUS_COMMITTEE_SIZE / 3)`` (because there are at most +``CONSENSUS_COMMITTEE_SIZE / 3`` validator slots corresponding to the +additional endorsements included in a block). The rewards per +endorsement slot are ``endorsing_rewards / CONSENSUS_COMMITTEE_SIZE``. +Assuming ``CONSENSUS_COMMITTEE_SIZE = 8000``, we obtain a bonus per slot of +``10 / (8000 / 3) = 0.00375`` tez and an endorsing +rewards per slot of ``20 / 8000 = 0.0025`` tez. + +Let's take an example. Say a block has round 1, is proposed by +delegate B, and contains the payload from round 0 produced by delegate +A. Also, B includes endorsements with endorsing power ``6000``. Then A receives +the fees and 10 tez (the ``BAKING_REWARD_FIXED_PORTION``) as a reward for +producing the block's payload. For simpler calculations, let's assume +``CONSENSUS_COMMITTEE_SIZE = 8000``. Concerning the bonus, the minimum required validator slots is ``5334``, and there are ``2666 = 8000 - 5334`` additional validator slots. +Therefore B receives the bonus ``(6000 - 5334) * 0.00375 = 2.4975`` tez. (Note +that B only included endorsements corresponding to 666 additional validator slots, about a quarter of the +maximum 2666 extra endorsements it could have theoretically included.) Finally, consider some +delegate C, whose active stake at some cycle is 5% of the total stake. Note that +his expected number of validator slots for that cycle is ``5/100 * 8192 * 8000 = +3,276,800`` slots. Assume also that the endorsing power of C's endorsements +included during that cycle has been ``3,123,456`` slots. Given that this number is +bigger than the minimum required (``3,276,800 * 2 / 3``), it receives an endorsing +reward of ``3,276,800 * 0.0025 = 8192`` tez for that cycle. + +.. _slashing_012: + +Slashing +^^^^^^^^ + +Like in Emmy*, not revealing nonces and double signing are punishable. If a +validator does not reveal its nonce by the end of the cycle, it does not receive +its endorsing rewards. If a validator double signs, that is, it double bakes or +it double (pre)endorses (which means voting on two different proposals at the +same round), the frozen deposit is slashed. The slashed amount for double baking +is ``DOUBLE_BAKING_PUNISHMENT``. The slashed amount for double (pre)endorsing is +a fixed percentage ``RATIO_OF_FROZEN_DEPOSITS_SLASHED_PER_DOUBLE_ENDORSEMENT`` +of the frozen deposit. The payload producer that includes the misbehavior +evidence is rewarded half of the slashed amount. + +The evidence for double signing at a given level can be collected by any +:ref:`accuser` and included as an *accusation* operation in a block +for a period of ``MAX_SLASHING_PERIOD``. + +We note that selfish baking is not an issue in Tenderbake: say we are at round +``r`` and the validator which is proposer at round ``r+1`` does not (pre)endorse +at round ``r`` in the hope that the block at round ``r`` is not agreed upon and +its turn comes to propose at round ``r+1``. Under the assumption that the +correct validators have more than two thirds of the total stake, these correct +validators have sufficient power for agreement to be reached, thus the lack of +participation of a selfish baker does not have an impact. + +.. _cs_constants_012: + +Consensus related protocol parameters +------------------------------------- + +.. list-table:: + :widths: 55 25 + :header-rows: 1 + + * - Parameter name + - Parameter value + * - ``CONSENSUS_COMMITTEE_SIZE`` + - 7000 + * - ``CONSENSUS_THRESHOLD`` + - ``ceil(2 * CONSENSUS_COMMITTEE_SIZE / 3)`` + * - ``MINIMAL_BLOCK_DELAY`` + - 30s + * - ``DELAY_INCREMENT_PER_ROUND`` + - 15s + * - ``MINIMAL_PARTICIPATION_RATIO`` + - 2/3 + * - ``FROZEN_DEPOSITS_PERCENTAGE`` + - 10 + * - ``MAX_SLASHING_PERIOD`` + - 2 cycles + * - ``DOUBLE_BAKING_PUNISHMENT`` + - 640 tez + * - ``RATIO_OF_FROZEN_DEPOSITS_SLASHED_PER_DOUBLE_ENDORSEMENT`` + - 1/2 + * - ``BAKING_REWARD_FIXED_PORTION`` + - 10 tez + * - ``BAKING_REWARD_BONUS_PER_SLOT`` + - ``bonus / (CONSENSUS_COMMITTEE_SIZE / 3)`` = 0.004286 tez + * - ``ENDORSING_REWARD_PER_SLOT`` + - ``endorsing_reward / CONSENSUS_COMMITTEE_SIZE`` = 0.002857 tez + + +.. _shell_proto_revisit_012: + +Shell-protocol interaction revisited +------------------------------------ + +:ref:`Recall` that, for the shell to interact with the economic protocol, two notions are defined abstractly at the level of the shell and made concrete at the level of the consensus protocol. +Namely, these two notions are the protocol-specific header and the fitness. +As in Emmy*, the protocol-specific header contains the fields: + +- ``signature``: a digital signature of the shell and protocol headers (excluding the signature itself) +- ``seed_nonce_hash``: a commitment to :ref:`a random number`, used to generate entropy on the chain +- ``proof_of_work_nonce``: a nonce used to pass a low-difficulty proof-of-work for the block, as a spam prevention measure +- ``liquidity_baking_escape_vote``: :ref:`a flag` that requests ending the subsidy. + +There are two additional fields: ``payload_hash`` and ``payload_round`` which are needed for establishing if a block is :ref:`final`. + +.. _fitness_012: + +The fitness is given by the tuple ``(level, locked_round, predecessor_round, round)``. +The fitness encapsulates more information than in Emmy* because Tenderbake is more complex: recall that blocks at the last level only represent :ref:`candidate blocks`. +In Emmy*, only the level mattered. +But in Tenderbake, we need to, for instance, allow for new blocks at the same level to be accepted by nodes. +Therefore the fitness also includes the block's round. +Furthermore, we also allow to change the predecessor block when it has a :ref:`smaller round`. +Therefore the fitness also includes the predecessor block's round. + + + +Further External Resources +-------------------------- + +* Tenderbake `report `_ +* Tenderbake `blog post `_. +* Tenderbake `tzip `_. diff --git a/docs/012/global_constants.rst b/docs/012/global_constants.rst new file mode 100644 index 000000000000..9b8286f906b5 --- /dev/null +++ b/docs/012/global_constants.rst @@ -0,0 +1,141 @@ +Global Constants +================ + +The size limit for :doc:`Michelson ` contracts is quite small, limited to 60 +kilobytes as of Granada protocol. Global constants are a feature added +in Hangzhou protocol that enables the re-use of user-defined Micheline chunks in Michelson scripts, allowing +for larger and more complex contracts on the chain. It works in the +following way: + +- Fragments of Michelson code (written in the :doc:`Micheline format <../shell/micheline>`) are + registered on the chain via a new operation + ``register_global_constant``. An example expression might be the + integer ``999`` or the lambda expression ``{ PUSH int 999; ADD }`` +- Included in the receipt of the operation is a hash of the expression + registered. For example the hash ``999`` is + ``expruQN5r2umbZVHy6WynYM8f71F8zS4AERz9bugF8UkPBEqrHLuU8``. +- Constants can be referenced inside a Michelson script with the new + primitive ``constant``. For example, we could write a lambda + equivalent to the one above like so: + ``{ PUSH int (constant "expruQN5r2umbZVHy6WynYM8f71F8zS4AERz9bugF8UkPBEqrHLuU8"); ADD }`` + +Global Constant Registration +---------------------------- + +The new ``register_global_constant`` operation includes an object with a +single key ``"value"``, the value of which is the Micheline expression +to be registered. + +You can submit this operation conveniently through a new :doc:`tezos-client ` command. +For example, the command: + +.. code:: sh + + tezos-client register global constant "999" from bootstrap1 --burn-cap 0.017 + +would result in the output: + +:: + + Node is bootstrapped. + Estimated gas: 1440 units (will add 100 for safety) + Estimated storage: 68 bytes added (will add 20 for safety) + Operation successfully injected in the node. + Operation hash is 'onsFknW5iWa6eiTYqAghY4peQZ7JYQUJg5fR8MwAQkMKjXfNqGf' + NOT waiting for the operation to be included. + Use command + tezos-client wait for onsFknW5iWa6eiTYqAghY4peQZ7JYQUJg5fR8MwAQkMKjXfNqGf to be included --confirmations 5 --branch BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU + and/or an external block explorer to make sure that it has been included. + This sequence of operations was run: + Manager signed operations: + From: tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx + Fee to the baker: ꜩ0.000385 + Expected counter: 1 + Gas limit: 1540 + Storage limit: 88 bytes + Balance updates: + tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ................ -ꜩ0.000385 + fees(the baker who will include this operation,0) ... +ꜩ0.000385 + Register Global: + Value: 999 + This global constant registration was successfully applied + Balance updates: + tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx ... -ꜩ0.017 + Consumed gas: 1440 + Storage size: 68 bytes + Global address: expruQN5r2umbZVHy6WynYM8f71F8zS4AERz9bugF8UkPBEqrHLuU8 + +As you can see, the address of the constant is returned in the operation +receipt in the field ``Global address``. This address is the Base58-encode Blake2b +hash of the binary serialization of the registered Micheline expression. +This means constants are content-addressable - given a particular Micheline +expression, you can always calculate its on-chain address and check if it’s registered. + +A few points about registering global constants: + +- Global constants may contain references to other constants; however, + any referenced constants must already be registered on the chain. As a + corollary, you cannot have cyclic references. +- Global constants are not type-checked before registration - any + valid Micheline expression may be registered. That said, attempting + to originate a contract that uses a constant in an ill-typed way will + fail. +- The total depth of the expression registered as a constant (after + expanding all constant references) may not exceed 10,000. +- The total number of nodes in the Micheline expression being + registered (after expanding all constant references) may not exceed + the ``max_micheline_node_count`` protocol constant. As of Hangzhou + this is 50,000. +- The total number of bytes in the Micheline expression being + registered (after expanding all constant references) may not exceed + the ``max_micheline_bytes_limit`` protocol constant. As of Hangzhou + this is 50,000. + +Originating a Contract that uses Global Constants +------------------------------------------------- + +A global constant can be referenced in Michelson scripts via the +primitive ``constant``, which accepts a single string argument, being +the hash of the expression to be referenced at runtime. This primitive +can be used to replace any Micheline node in the bodies of the +``parameter``, ``storage``, ``code``, or ``view`` fields of a Michelson script. For +example, we replace every instance of the type ``lambda unit unit`` and +value 999 with their respective hashes: + +.. code-block:: michelson + + parameter (constant "exprtYirrFwYKm6yKLzJNtYRbq49zedYq16BonRvMzHiwSbUekB9YL"); + storage (big_map int (constant "exprtYirrFwYKm6yKLzJNtYRbq49zedYq16BonRvMzHiwSbUekB9YL")); + code { + PUSH int (constant "expruQN5r2umbZVHy6WynYM8f71F8zS4AERz9bugF8UkPBEqrHLuU8"); + # + }; + +The full expansion of this contract would be: + +.. code-block:: michelson + + parameter (lambda unit unit); + storage (big_map int (lambda unit unit)); + code { + PUSH int 999; + # + }; + +During origination, all constants are expanded recursively. The +operation will fail if the resulting contract is ill-typed. Global +constant expansion consumes gas; thus, the operation may also fail due +to gas exhaustion. + +Global Constants at Runtime +--------------------------- + +Contracts that use global constants are semantically equivalent to the +contract with all constants expanded. + +Note that using the `UNPACK `__ +operation to deserialize a lambda which contains a reference to a global +constant is not supported. Similarly, originating a contract which contains +a reference to a global constant using the +`CREATE_CONTRACT `__ +instruction will also fail. diff --git a/docs/012/glossary.rst b/docs/012/glossary.rst new file mode 100644 index 000000000000..6c0bc44efb72 --- /dev/null +++ b/docs/012/glossary.rst @@ -0,0 +1,179 @@ +Glossary +======== + +This glossary is divided in two sections, the first one concerns Tezos, and +the second one concerns the `economic protocol`_. The definitions in the latter +section may be different for other protocol versions. + +Tezos +----- + +.. include:: ../shell/glossary.rst.h + +Protocol +-------- + +_`Accuser` + When a node_ attempts to inject several incompatible blocks (or when it tries + to abuse the network in another similar way), another node_ can make an + accusation: show evidence of attempted abuse. The node_ making the accusation + is the accuser. + + The accuser is awarded some funds from the baking_ deposit of the accused. + + When using :ref:`Octez `, accusations are handled by a + separate binary. + +_`Account` + An account is a unique identifier within the protocol. There are different + kinds of accounts (see `Originated account`_ and `Implicit account`_). + + In the Context_, each account is associated with a balance (an amount of + tez available). + +_`Baker` + When a node_ creates a new block_, it is the baker of this block_. + Baking_ rights are distributed to different accounts based on their + available balance. Only a node_ that handles an account_ with baking_ rights + is allowed to bake; blocks created by another node_ are invalid. + The baker selects transactions from the mempool_ to be included in the block_ it bakes. + + When using :ref:`Octez `, baking_ is handled by a separate + binary. + +_`Baking`/_`Endorsing rights` + A delegate_ is allowed to bake/endorse a block_ if he holds the + baking/endorsing right for that block_. At the start of a Cycle_, + baking and endorsing rights are computed for all the block_ heights in the + cycle_, based on the proportion of the stake owned by each account. + + For each block_ height, there are several accounts that are allowed to bake. + These different accounts are given different Priorities. + + For each block_ height, there are several accounts that are allowed to + endorse. There can be multiple endorsements per block_. + +_`Burn` + To ensure responsible use of the storage space on the public blockchain, + there are some costs charged to users for consuming storage. These + costs are burnt (i.e., the amount of tez is destroyed). For example, + a per-byte storage cost is burnt for increasing the storage space of a + smart contract; a fixed amount is burnt for allocating a new contract + (which consumes space by storing its address on the blockchain). + + See also `Fee`_. + +_`Constants` + Protocols are parameterized by several parameters called protocol constants, which may vary from one protocol to another or from one network to another. + +_`Contract` + See account_. + +_`Cycle` + A cycle is a set of consecutive blocks. E.g., cycle 12 started at block_ + height 49152 and ended at block_ height 53248. + + Cycles are used as a unit of “time” in the block_ chain. For example, the + different phases in the amendment voting procedures are defined based on + cycles. + +_`Delegate` + An `Implicit account`_ to which an account_ has delegated their baking_ and + `endorsing rights`_. The baking_ rights and `endorsing rights`_ are + calculated based on the total balance of tez that an account_ has been + delegated to. + +_`Delegation` + An operation_ in which an account_ balance is lent to a + delegate_. This increases the delegate_'s stake and consequently + its Baking_ rights. The delegate_ does not control the funds from + the account_. + +_`Double baking` + When a baker_ signs two different blocks at the same height, it is called + double baking. Double baking is detrimental to the network and might be + indicative of an attempt to double spend. As such, it is punished by the + network: an accuser_ can provide proof of the double baking to be awarded + part of the baker_'s deposit. + +_`Endorser` + When a block_ is created and propagated on the network, nodes that have + `endorsing rights`_ for the matching block_ height can emit an endorsement + operation_. The accounts that emit the block_ are the endorsers of the block_. + Endorsement operations_ are included in the next block_. + + When using :ref:`Octez `, endorsing is handled by a separate binary. + +_`Fee` + To ensure responsible use of computation resources of other nodes, and also to encourage active participation in the consensus protocol, there are some + fees that users pay to bakers for including their operations in blocks. + For example, fees are paid to a baker for operations such as a transaction_ or a revelation of a public key. + + See also `Burn`_. + +_`Gas` + A measure of the number of elementary operations_ performed during + the execution of a `smart contract`_. Gas is used to measure how + much computing power is used to execute a `smart contract`_. + +_`Implicit account` + An account_ that is linked to a public key. Contrary to a `smart + contract`_, an `Implicit account`_ cannot include a script and it + cannot reject incoming transactions. + + If registered, an `Implicit account`_ can act as a delegate_. + + The address of an `Implicit account`_ always starts with the + letters `tz` followed by `1`, `2` or `3` (depending on the + signature scheme) and finally the hash of the public key. + +.. _glossary_michelson_012: + +Michelson + The built-in language used by a `smart contract`_. + +_`Operations` + The main operations in the protocol are transactions (to transfer funds + or to execute smart contracts), accusations, activations, delegations, + endorsements and originations. + +_`Originated account` + See `smart contract`_. + +_`Origination` + An operation_ to create a `smart contract`_. + +_`Priority` + A rank of different baking_ rights. Each rank corresponds to a time span. A + baker_ with baking_ rights at a given priority is only allowed to bake during + the priority's corresponding time span. Baking_ outside of one's designated + priority, results in an invalid block_. + +_`Roll` + An amount of tez (e.g., 6000ꜩ) serving as a minimal amount to + determine delegates' baking_ rights in a cycle_. A delegate_ with + twice as much stake as another will be given twice as many rights + to bake. A roll also serves as a unit to determine delegates' + voting rights in a cycle_. + +_`Smart contract` + Account_ which is associated to a :ref:`Michelson ` script. They are + created with an explicit origination_ operation and are therefore + sometimes called originated accounts. The address of a smart + contract always starts with the letters ``KT1``. + +_`Transaction` + An operation_ to transfer tez between two accounts, or to run the code of a + `smart contract`_. + +_`Voting period` + Any of the ``proposal``, ``exploration``, ``cooldown``, + ``promotion`` or ``adoption`` stages in the voting procedure when + amending the `economic protocol`_. + +_`Voting listings` + The list calculated at the beginning of each `voting period`_ that contains + the staking balance (in number of rolls) of each delegate_ that owns more + than one roll_ at that moment. For each delegate_, The voting listings + reflects the weight of the vote emitted by the delegate_ when amending the + `economic protocol`_. diff --git a/docs/012/liquidity_baking.rst b/docs/012/liquidity_baking.rst new file mode 100644 index 000000000000..88e4d2c58e5e --- /dev/null +++ b/docs/012/liquidity_baking.rst @@ -0,0 +1,51 @@ +Liquidity Baking +================ + +Liquidity baking incentivizes large amounts of decentralized liquidity provision between tez and tzBTC by minting a small amount of tez every block and depositing it inside of a constant product market making smart-contract. It includes an escape hatch mechanism as a contingency. + +Contracts +~~~~~~~~~ + +During activation of Granada protocol, a constant product market making (CPMM) Michelson contract has been deployed on the chain with address ``KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5`` as well as an associated liquidity token contract (LQT) with address ``KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo``. + +.. warning:: + + while the CPMM and LQT contract originations provide an ``Origination_result``, the LQT contract contains two big maps not included in a `lazy_storage_diff` field. Indexers and other tooling may need manual updates to include these. + +The CPMM maintains a balance of ``a`` tez and ``b`` `tzBTC `_, where tzBTC is the `FA1.2 token `_ found at address ``KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn``. The smart contract accepts deposits of ``da`` tez and returns ``db`` tzBTC (or vice versa) where the invariant ``(a + da * (1 - f - n)) * (b - db) = a b`` is preserved, and ``f`` and ``n`` are a fee and burn, set at 0.1% each. Calculations are done with precision of 1000, rounding down on division. + +To implement this contract, we use a fork of the open source code base used by `version two `_ of the "Dexter" project. The implementation of this contract has been `formally verified `_ against its functional specification. The contract code is modified in the following way: + +1. The fee is set to 0.1% only (the fee in Dexter v2 is set to 0.3%). Rationale: given the subsidy it is not necessary to charge a large fee and better to improve liquidity. +2. An additional 0.1% of every trade is burned by being transferred to the null implicit account. Rationale: this mechanism offsets inflation from the subsidy. The inflation is exactly balanced at a daily trade volume of 7.2 million tez. +3. The ability to set a delegate has been removed. Rationale: the subsidy means there is no need for a baker for that contract and having one would create an imbalance. +4. The ability to set a manager has been removed. Rationale: the only privilege of the Dexter manager is to set Dexter's delegate so this role is now unnecessary. + +The LIGO and Michelson code for these contracts, as well as detailed documentation, can be found on `the liquidity baking branch of the Dexter 2 repository `_. + +Subsidy +~~~~~~~ + +At every block in the chain, a small amount of tez is minted and credited to the CPMM contract, and the CPMM's ``%default`` entrypoint is called to update the ``xtz_pool`` balance in its storage. The amount that is minted and sent to the CPMM contract is 1/16th of the rewards for a block of priority 0 with all endorsements; currently these rewards are 40 tez per block so the amount that is sent to the CPMM contract is 2.5 tez per block. + +So the credits to the CPMM contract can be accounted for by indexers, they are included in block metadata as a balance update with a new constructor for ``update_origin``, ``Subsidy``. + +As a safety precaution, the subsidy expires automatically at a given +level called the liquidity baking sunset level. The sunset level can +be renewed periodically by protocol amendment. + +.. _esc_hatch_012: + +Escape hatch +~~~~~~~~~~~~ + +In addition to the sunset mechanism, an escape hatch is included. At every block, the baker producing the block can choose to include a flag that requests ending the subsidy. The context maintains an exponential moving average of that flag calculated as such with integer arithmetic: + +``e[0] = 0`` +``e[n+1] = (1999 * e[n] // 2000) + (1000 if flag[n] else 0)`` + +If at any block ``e[n] >= 666667`` then it means that an exponential moving average with a window size on the order of two thousand blocks has had roughly at least a third of blocks demanding the end of the subsidy. If that is the case, the subsidy is permanently halted (though it can be reactivated by a protocol upgrade). + +For indicative purposes, if a fraction ``f`` of blocks start signalling the flag, the threshold is reached after roughly ``2*(log(1-1/(3f)) / log(0.999))`` blocks, about 812 blocks if everyone signals, 1079 blocks if 80% do, 1624 blocks if 60% do, 3590 blocks if 40% do, etc. Recall for comparison that assuming two blocks per minute there are 2880 blocks per day. + +The escape hatch can be invoked through a JSON file containing a vote that is repeatedly submitted on each baked block, e.g. ``tezos-baker run with local node ~/.tezos-node alice --votefile "per_block_votes.json"`` where ``per_block_votes.json`` contains just ``{"liquidity_baking_escape_vote": true}``. See also the :ref:`baker man page`. diff --git a/docs/012/michelson.rst b/docs/012/michelson.rst new file mode 100644 index 000000000000..5d7212e70edd --- /dev/null +++ b/docs/012/michelson.rst @@ -0,0 +1,3821 @@ +Michelson: the language of Smart Contracts in Tezos +=================================================== + +This specification gives a detailed formal semantics of the Michelson +language and a short explanation of how smart contracts are executed +and interact in the blockchain. + +The language is stack-based, with high level data types and primitives, +and strict static type checking. Its design cherry picks traits from +several language families. Vigilant readers will notice direct +references to Forth, Scheme, ML and Cat. + +A Michelson program is a series of instructions that are run in +sequence: each instruction receives as input the stack resulting from the +previous instruction, and rewrites it for the next one. The stack +contains both immediate values and heap allocated structures. All values +are immutable and garbage collected. + +The types of the input and output stack are fixed and monomorphic, +and the program is typechecked before being introduced into the system. +No smart contract execution can fail because an instruction has been +executed on a stack of unexpected length or contents. + +This specification gives the complete instruction set, type system and +semantics of the language. It is meant as a precise reference manual, +not an easy introduction. Even though, some examples are provided at +the end of the document and can be read first or at the same time as +the specification. The document also starts with a less formal +explanation of the context: how Michelson code interacts with the +blockchain. + +Semantics of smart contracts and transactions +--------------------------------------------- + +The Tezos ledger currently has two types of accounts that can hold +tokens (and be the destinations of transactions). + + - An implicit account is a non programmable account, whose tokens + are spendable and delegatable by a public key. Its address is + directly the public key hash, and starts with ``tz1``, ``tz2`` or + ``tz3``. + - A smart contract is a programmable account. A transaction to such + an address can provide data, and can fail for reasons decided by + its Michelson code. Its address is a unique hash that depends on + the operation that led to its creation, and starts with ``KT1``. + +From Michelson, they are indistinguishable. A safe way to think about +this is to consider that implicit accounts are smart contracts that +always succeed to receive tokens, and does nothing else. + +Intra-transaction semantics +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Alongside their tokens, smart contracts keep a piece of storage. Both +are ruled by a specific logic specified by a Michelson program. A +transaction to a smart contract will provide an input value and in +option some tokens, and in return, the smart contract can modify its +storage and transfer its tokens. + +The Michelson program receives as input a stack containing a single +pair whose first element is an input value and second element the +content of the storage space. It must return a stack containing a +single pair whose first element is the list of internal operations +that it wants to emit, and second element is the new contents of the +storage space. Alternatively, a Michelson program can fail, explicitly +using a specific opcode, or because something went wrong that could +not be caught by the type system (e.g. gas exhaustion). + +A bit of polymorphism can be used at contract level, with a +lightweight system of named entrypoints: instead of an input value, +the contract can be called with an entrypoint name and an argument, +and these two components are transformed automatically in a simple and +deterministic way to an input value. This feature is available both +for users and from Michelson code. See the dedicated section. + +Inter-transaction semantics +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An operation included in the blockchain is a sequence of "external +operations" signed as a whole by a source address. These operations +are of three kinds: + + - Transactions to transfer tokens to implicit accounts or tokens and + parameters to a smart contract (or, optionally, to a specified + entrypoint of a smart contract). + - Originations to create new smart contracts from its Michelson + source code, an initial amount of tokens transferred from the + source, and an initial storage contents. + - Delegations to assign the tokens of the source to the stake of + another implicit account (without transferring any tokens). + +Smart contracts can also emit "internal operations". These are run +in sequence after the external transaction completes, as in the +following schema for a sequence of two external operations. + +:: + + +------+----------------+-------+----------------+ + | op 1 | internal ops 1 | op 2 | internal ops 2 | + +------+----------------+-------+----------------+ + +Smart contracts called by internal transactions can in turn also emit +internal operation. The interpretation of the internal operations +of a given external operation uses a stack, as in the following +example, also with two external operations. + +:: + + +-----------+---------------+--------------------------+ + | executing | emissions | resulting stack | + +-----------+---------------+--------------------------+ + | op 1 | 1a, 1b, 1c | 1a, 1b, 1c | + | op 1a | 1ai, 1aj | 1ai, 1aj, 1b, 1c | + | op 1ai | | 1aj, 1b, 1c | + | op 1aj | | 1b, 1c | + | op 1b | 1bi | 1bi, 1c | + | op 1bi | | 1c | + | op 1c | | | + | op 2 | 2a, 2b | 2a, 2b | + | op 2a | 2ai | 2ai, 2b | + | op 2ai | 2ai1 | 2ai1, 2b | + | op 2ai1 | | 2b | + | op 2b | 2bi | 2bi | + | op 2bi | 2bi1 | 2bi1 | + | op 2bi1 | 2bi2 | 2bi2 | + | op 2bi2 | | | + +-----------+---------------+--------------------------+ + +Failures +~~~~~~~~ + +All transactions can fail for a few reasons, mostly: + + - Not enough tokens in the source to spend the specified amount. + - The script took too many execution steps. + - The script failed programmatically using the ``FAILWITH`` instruction. + +External transactions can also fail for these additional reasons: + + - The signature of the external operations was wrong. + - The code or initial storage in an origination did not typecheck. + - The parameter in a transfer did not typecheck. + - The destination did not exist. + - The specified entrypoint did not exist. + +All these errors cannot happen in internal transactions, as the type +system catches them at operation creation time. In particular, +Michelson has two types to talk about other accounts: ``address`` and +``contract t``. The ``address`` type merely gives the guarantee that +the value has the form of a Tezos address. The ``contract t`` type, on +the other hand, guarantees that the value is indeed a valid, existing +account whose parameter type is ``t``. To make a transaction from +Michelson, a value of type ``contract t`` must be provided, and the +type system checks that the argument to the transaction is indeed of +type ``t``. Hence, all transactions made from Michelson are well +formed by construction. + +In any case, when a failure happens, either total success or total +failure is guaranteed. If a transaction (internal or external) fails, +then the whole sequence fails and all the effects up to the failure +are reverted. These transactions can still be included in blocks, and +the transaction fees are given to the implicit account who baked the +block. + +Language semantics +------------------ + +This specification explains in a symbolic way the computation performed by the +Michelson interpreter on a given program and initial stack to produce +the corresponding resulting stack. The Michelson interpreter is a pure +function: it only builds a result stack from the elements of an initial +one, without affecting its environment. This semantics is then naturally +given in what is called a big step form: a symbolic definition of a +recursive reference interpreter. This definition takes the form of a +list of rules that cover all the possible inputs of the interpreter +(program and stack), and describe the computation of the corresponding +resulting stacks. + +Rules form and selection +~~~~~~~~~~~~~~~~~~~~~~~~ + +The rules have the main following form. + +:: + + > (syntax pattern) / (initial stack pattern) => (result stack pattern) + iff (conditions) + where (recursions) + and (more recursions) + +The left hand side of the ``=>`` sign is used for selecting the rule. +Given a program and an initial stack, one (and only one) rule can be +selected using the following process. First, the toplevel structure of +the program must match the syntax pattern. This is quite simple since +there are only a few non-trivial patterns to deal with instruction +sequences, and the rest is made of trivial patterns that match one +specific instruction. Then, the initial stack must match the initial +stack pattern. Finally, some rules add extra conditions over the values +in the stack that follow the ``iff`` keyword. Sometimes, several rules +may apply in a given context. In this case, the one that appears first +in this specification is to be selected. If no rule applies, the result +is equivalent to the one for the explicit ``FAILWITH`` instruction. This +case does not happen on well-typed programs, as explained in the next +section. + +The right hand side describes the result of the interpreter if the rule +applies. It consists in a stack pattern, whose parts are either +constants, or elements of the context (program and initial stack) that +have been named on the left hand side of the ``=>`` sign. + +Recursive rules (big step form) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes, the result of interpreting a program is derived from the +result of interpreting another one (as in conditionals or function +calls). In these cases, the rule contains a clause of the following +form. + +:: + + where (intermediate program) / (intermediate stack) => (partial result) + +This means that this rule applies in case interpreting the intermediate +state on the left gives the pattern on the right. + +The left hand sign of the ``=>`` sign is constructed from elements of +the initial state or other partial results, and the right hand side +identify parts that can be used to build the result stack of the rule. + +If the partial result pattern does not actually match the result of the +interpretation, then the result of the whole rule is equivalent to the +one for the explicit ``FAILWITH`` instruction. Again, this case does not +happen on well-typed programs, as explained in the next section. + +Format of patterns +~~~~~~~~~~~~~~~~~~ + +Code patterns are of one of the following syntactical forms. + +- ``INSTR`` (an uppercase identifier) is a simple instruction (e.g. + ``DROP``). +- ``INSTR (arg) ...`` is a compound instruction, whose arguments can be + code, data or type patterns (e.g. ``PUSH nat 3``). +- ``{ (instr) ; ... }`` is a possibly empty sequence of instructions, + (e.g. ``IF { SWAP ; DROP } { DROP }``), nested sequences can drop the + braces. +- ``name`` is a pattern that matches any program and names a part of + the matched program that can be used to build the result. +- ``_`` is a pattern that matches any instruction. + +Stack patterns are of one of the following syntactical forms. + +- ``[FAILED]`` is the special failed state. +- ``[]`` is the empty stack. +- ``(top) : (rest)`` is a stack whose top element is matched by the + data pattern ``(top)`` on the left, and whose remaining elements are + matched by the stack pattern ``(rest)`` on the right (e.g. + ``x : y : rest``). +- ``name`` is a pattern that matches any stack and names it in order to + use it to build the result. +- ``_`` is a pattern that matches any stack. + +Data patterns are of one of the following syntactical forms. + +- integer/natural number literals, (e.g. ``3``). +- string literals, (e.g. ``"contents"``). +- raw byte sequence literals (e.g. ``0xABCDEF42``). +- ``Tag`` (capitalized) is a symbolic constant, (e.g. ``Unit``, + ``True``, ``False``). +- ``(Tag (arg) ...)`` tagged constructed data, (e.g. ``(Pair 3 4)``). +- a code pattern for first class code values. +- ``name`` to name a value in order to use it to build the result. +- ``_`` to match any value. + +The domain of instruction names, symbolic constants and data +constructors is fixed by this specification. Michelson does not let the +programmer introduce its own types. + +Be aware that the syntax used in the specification may differ from +the :ref:`concrete syntax `. In particular +some instructions are annotated with types that are not present in the +concrete language because they are synthesized by the typechecker. + +Shortcuts +~~~~~~~~~ + +Sometimes, it is easier to think (and shorter to write) in terms of +program rewriting than in terms of big step semantics. When it is the +case, and when both are equivalents, we write rules of the form: + +:: + + p / S => S'' + where p' / S' => S'' + +using the following shortcut: + +:: + + p / S => p' / S' + +The concrete language also has some syntax sugar to group some common +sequences of operations as one. This is described in this specification +using a simple regular expression style recursive instruction rewriting. + +.. _michelson_type_system_012: + +Introduction to the type system and notations +--------------------------------------------- + +This specification describes a type system for Michelson. To make things +clear, in particular to readers that are not accustomed to reading +formal programming language specifications, it does not give a +typechecking or inference algorithm. It only gives an intentional +definition of what we consider to be well-typed programs. For each +syntactical form, it describes the stacks that are considered well-typed +inputs, and the resulting outputs. + +The type system is sound, meaning that if a program can be given a type, +then if run on a well-typed input stack, the interpreter will never +apply an interpretation rule on a stack of unexpected length or +contents. Also, it will never reach a state where it cannot select an +appropriate rule to continue the execution. Well-typed programs do not +block, and do not go wrong. + +Type notations +~~~~~~~~~~~~~~ + +The specification introduces notations for the types of values, terms +and stacks. Apart from a subset of value types that appear in the form +of type annotations in some places throughout the language, it is +important to understand that this type language only exists in the +specification. + +A stack type can be written: + +- ``[]`` for the empty stack. +- ``(top) : (rest)`` for the stack whose first value has type ``(top)`` + and queue has stack type ``(rest)``. + +Instructions, programs and primitives of the language are also typed, +their types are written: + +:: + + (type of stack before) -> (type of stack after) + +The types of values in the stack are written: + +- ``identifier`` for a primitive data-type (e.g. ``bool``). +- ``identifier (arg)`` for a parametric data-type with one parameter + type ``(arg)`` (e.g. ``list nat``). +- ``identifier (arg) ...`` for a parametric data-type with several + parameters (e.g. ``map string int``). +- ``[ (type of stack before) -> (type of stack after) ]`` for a code + quotation, (e.g. ``[ int : int : [] -> int : [] ]``). +- ``lambda (arg) (ret)`` is a shortcut for + ``[ (arg) : [] -> (ret) : [] ]``. + +Meta type variables +~~~~~~~~~~~~~~~~~~~ + +The typing rules introduce meta type variables. To be clear, this has +nothing to do with polymorphism, which Michelson does not have. These +variables only live at the specification level, and are used to express +the consistency between the parts of the program. For instance, the +typing rule for the ``IF`` construct introduces meta variables to +express that both branches must have the same type. + +Here are the notations for meta type variables: + +- ``'a`` for a type variable. +- ``'A`` for a stack type variable. +- ``_`` for an anonymous type or stack type variable. + +Typing rules +~~~~~~~~~~~~ + +The system is syntax directed, meaning that it defines a single +typing rule for each syntax construct. A typing rule restricts the type +of input stacks that are authorized for this syntax construct, links the +output type to the input type, and links both of them to the +subexpressions when needed, using meta type variables. + +Typing rules are of the form: + +:: + + (syntax pattern) + :: (type of stack before) -> (type of stack after) [rule-name] + iff (premises) + +Where premises are typing requirements over subprograms or values in the +stack, both of the form ``(x) :: (type)``, meaning that value ``(x)`` +must have type ``(type)``. + +A program is shown well-typed if one can find an instance of a rule that +applies to the toplevel program expression, with all meta type variables +replaced by non variable type expressions, and of which all type +requirements in the premises can be proven well-typed in the same +manner. For the reader unfamiliar with formal type systems, this is +called building a typing derivation. + +Here is an example typing derivation on a small program that computes +``(x+5)*10`` for a given input ``x``, obtained by instantiating the +typing rules for instructions ``PUSH``, ``ADD`` and for the sequence, as +found in the next sections. When instantiating, we replace the ``iff`` +with ``by``. + +:: + + { PUSH nat 5 ; ADD ; PUSH nat 10 ; MUL } + :: [ nat : [] -> nat : [] ] + by { PUSH nat 5 ; ADD } + :: [ nat : [] -> nat : [] ] + by PUSH nat 5 + :: [ nat : [] -> nat : nat : [] ] + by 5 :: nat + and ADD + :: [ nat : nat : [] -> nat : [] ] + and { PUSH nat 10 ; MUL } + :: [ nat : [] -> nat : [] ] + by PUSH nat 10 + :: [ nat : [] -> nat : nat : [] ] + by 10 :: nat + and MUL + :: [ nat : nat : [] -> nat : [] ] + +Producing such a typing derivation can be done in a number of manners, +such as unification or abstract interpretation. In the implementation of +Michelson, this is done by performing a recursive symbolic evaluation of +the program on an abstract stack representing the input type provided by +the programmer, and checking that the resulting symbolic stack is +consistent with the expected result, also provided by the programmer. + +Side note +~~~~~~~~~ + +As with most type systems, it is incomplete. There are programs that +cannot be given a type in this type system, yet that would not go wrong +if executed. This is a necessary compromise to make the type system +usable. Also, it is important to remember that the implementation of +Michelson does not accept as many programs as the type system describes +as well-typed. This is because the implementation uses a simple single +pass typechecking algorithm, and does not handle any form of +polymorphism. + +Core data types and notations +----------------------------- + +- ``string``, ``nat``, ``int`` and ``bytes``: The core primitive + constant types. + +- ``bool``: The type for booleans whose values are ``True`` and + ``False``. + +- ``unit``: The type whose only value is ``Unit``, to use as a + placeholder when some result or parameter is not necessary. For + instance, when the only goal of a contract is to update its storage. + +- ``never``: The empty type. Since ``never`` has no inhabitant, no value of + this type is allowed to occur in a well-typed program. + +- ``list (t)``: A single, immutable, homogeneous linked list, whose + elements are of type ``(t)``, and that we write ``{}`` for the empty + list or ``{ first ; ... }``. In the semantics, we use chevrons to + denote a subsequence of elements. For instance: ``{ head ; }``. + +- ``pair (l) (r)``: A pair of values ``a`` and ``b`` of types ``(l)`` + and ``(r)``, that we write ``(Pair a b)``. + +- ``pair (t{1}) ... (t{n})`` with ``n > 2``: A shorthand for ``pair (t{1}) (pair (t{2}) ... (pair (t{n-1}) (t{n})) ...)``. + +- ``option (t)``: Optional value of type ``(t)`` that we write ``None`` + or ``(Some v)``. + +- ``or (l) (r)``: A union of two types: a value holding either a value + ``a`` of type ``(l)`` or a value ``b`` of type ``(r)``, that we write + ``(Left a)`` or ``(Right b)``. + +- ``set (t)``: Immutable sets of values of type ``(t)`` that we write as + lists ``{ item ; ... }``, of course with their elements unique, and + sorted. + +- ``map (k) (t)``: Immutable maps from keys of type ``(k)`` of values + of type ``(t)`` that we write ``{ Elt key value ; ... }``, with keys + sorted. + +- ``big_map (k) (t)``: Lazily deserialized maps from keys of type + ``(k)`` of values of type ``(t)``. + These maps should be used if you intend to store large amounts of data in a map. + Using ``big_map`` can reduce gas costs significantly compared to standard maps, as data is lazily deserialized. + Note however that individual operations on ``big_map`` have higher gas costs than those over standard maps. + A ``big_map`` also has a lower storage cost than a standard map of the same size, when large keys are used, since only the hash of each key is stored in a ``big_map``. + + A ``big_map`` cannot appear inside another ``big_map``. + See the section on :ref:`operations on big maps ` for a description of the syntax of values of type ``big_map (k) (t)`` and available operations. + +Core instructions +----------------- + +Control structures +~~~~~~~~~~~~~~~~~~ + +- ``FAILWITH``: Explicitly abort the current program. + +:: + + :: 'a : \_ -> \_ + +This special instruction aborts the current program exposing the top +element of the stack in its error message (first rule below). It makes +the output useless since all subsequent instructions will simply +ignore their usual semantics to propagate the failure up to the main +result (second rule below). Its type is thus completely generic. + +:: + + > FAILWITH / a : _ => [FAILED] + > _ / [FAILED] => [FAILED] + +- ``{}``: Empty sequence. + +:: + + :: 'A -> 'A + + > {} / SA => SA + +- ``{ I ; C }``: Sequence. + +:: + + :: 'A -> 'C + iff I :: [ 'A -> 'B ] + C :: [ 'B -> 'C ] + + > I ; C / SA => SC + where I / SA => SB + and C / SB => SC + +- ``IF bt bf``: Conditional branching. + +:: + + :: bool : 'A -> 'B + iff bt :: [ 'A -> 'B ] + bf :: [ 'A -> 'B ] + + > IF bt bf / True : S => bt / S + > IF bt bf / False : S => bf / S + +- ``LOOP body``: A generic loop. + +:: + + :: bool : 'A -> 'A + iff body :: [ 'A -> bool : 'A ] + + > LOOP body / True : S => body ; LOOP body / S + > LOOP body / False : S => S + +- ``LOOP_LEFT body``: A loop with an accumulator. + +:: + + :: (or 'a 'b) : 'A -> 'b : 'A + iff body :: [ 'a : 'A -> (or 'a 'b) : 'A ] + + > LOOP_LEFT body / (Left a) : S => body ; LOOP_LEFT body / a : S + > LOOP_LEFT body / (Right b) : S => b : S + +- ``DIP code``: Runs code protecting the top element of the stack. + +:: + + :: 'b : 'A -> 'b : 'C + iff code :: [ 'A -> 'C ] + + > DIP code / x : S => x : S' + where code / S => S' + +- ``DIP n code``: Runs code protecting the ``n`` topmost elements of + the stack. In particular, ``DIP 0 code`` is equivalent to ``code`` + and ``DIP 1 code`` is equivalent to ``DIP code``. + +:: + + :: 'a{1} : ... : 'a{n} : 'A -> 'a{1} : ... : 'a{n} : 'B + iff code :: [ 'A -> 'B ] + + > DIP n code / x{1} : ... : x{n} : S => x{1} : ... : x{n} : S' + where code / S => S' + +- ``EXEC``: Execute a function from the stack. + +:: + + :: 'a : lambda 'a 'b : 'C -> 'b : 'C + + > EXEC / a : f : S => r : S + where f / a : [] => r : [] + +- ``APPLY``: Partially apply a tuplified function from the stack. + Values that are not both pushable and storable + (values of type ``operation``, ``contract _`` and ``big map _ _``) + cannot be captured by ``APPLY`` (cannot appear in ``'a``). + +:: + + :: 'a : lambda (pair 'a 'b) 'c : 'C -> lambda 'b 'c : 'C + + > APPLY / a : f : S => { PUSH 'a a ; PAIR ; f } : S + +Stack operations +~~~~~~~~~~~~~~~~ + +- ``DROP``: Drop the top element of the stack. + +:: + + :: _ : 'A -> 'A + + > DROP / _ : S => S + +- ``DROP n``: Drop the `n` topmost elements of the stack. In + particular, ``DROP 0`` is a noop and ``DROP 1`` is equivalent to + ``DROP``. + +:: + + :: 'a{1} : ... : 'a{n} : 'A -> 'A + + > DROP n / x{1} : ... : x{n} : S => S + +- ``DUP``: Duplicate the top element of the stack. + +:: + + :: 'a : 'A -> 'a : 'a : 'A + + > DUP / x : S => x : x : S + +- ``DUP n``: Duplicate the N-th element of the stack. `DUP 1` is equivalent to `DUP`. `DUP 0` is rejected. + +:: + + DUP 1 :: 'a : 'A -> 'a : 'a : 'A + + DUP (n+1) :: 'a : 'A -> 'b : 'a : 'A + iff DUP n :: 'A -> 'b : 'A + + > DUP 1 / x : S => x : x : S + + > DUP (n+1) / x : S => y : x : S + iff DUP n / S => y : S + + +- ``SWAP``: Exchange the top two elements of the stack. + +:: + + :: 'a : 'b : 'A -> 'b : 'a : 'A + + > SWAP / x : y : S => y : x : S + +- ``DIG n``: Take the element at depth ``n`` of the stack and move it + on top. The element on top of the stack is at depth ``0`` so that + ``DIG 0`` is a no-op and ``DIG 1`` is equivalent to ``SWAP``. + +:: + + :: 'a{1} : ... : 'a{n} : 'b : 'A -> 'b : 'a{1} : ... : 'a{n} : 'A + + > DIG n / x{1} : ... : x{n} : y : S => y : x{1} : ... : x{n} : S + +- ``DUG n``: Place the element on top of the stack at depth ``n``. The + element on top of the stack is at depth ``0`` so that ``DUG 0`` is a + no-op and ``DUG 1`` is equivalent to ``SWAP``. + +:: + + :: 'b : 'a{1} : ... : 'a{n} : 'A -> 'a{1} : ... : 'a{n} : 'b : 'A + + > DUG n / y : x{1} : ... : x{n} : S => x{1} : ... : x{n} : y : S + +- ``PUSH 'a x``: Push a constant value of a given type onto the stack. + +:: + + :: 'A -> 'a : 'A + iff x :: 'a + + > PUSH 'a x / S => x : S + +- ``LAMBDA 'a 'b code``: Push a lambda with the given parameter type `'a` and return + type `'b` onto the stack. + +:: + + :: 'A -> (lambda 'a 'b) : 'A + + > LAMBDA _ _ code / S => code : S + +Generic comparison +~~~~~~~~~~~~~~~~~~ + +Comparison only works on a class of types that we call comparable. A +``COMPARE`` operation is defined in an ad hoc way for each comparable +type, but the result of compare is always an ``int``, which can in turn +be checked in a generic manner using the following combinators. The +result of ``COMPARE`` is ``0`` if the top two elements of the stack are +equal, negative if the first element in the stack is less than the +second, and positive otherwise. + +- ``EQ``: Checks that the top element of the stack is equal to zero. + +:: + + :: int : 'S -> bool : 'S + + > EQ / 0 : S => True : S + > EQ / v : S => False : S + iff v <> 0 + +- ``NEQ``: Checks that the top element of the stack is not equal to zero. + +:: + + :: int : 'S -> bool : 'S + + > NEQ / 0 : S => False : S + > NEQ / v : S => True : S + iff v <> 0 + +- ``LT``: Checks that the top element of the stack is less than zero. + +:: + + :: int : 'S -> bool : 'S + + > LT / v : S => True : S + iff v < 0 + > LT / v : S => False : S + iff v >= 0 + +- ``GT``: Checks that the top element of the stack is greater than zero. + +:: + + :: int : 'S -> bool : 'S + + > GT / v : S => C / True : S + iff v > 0 + > GT / v : S => C / False : S + iff v <= 0 + +- ``LE``: Checks that the top element of the stack is less than or equal to + zero. + +:: + + :: int : 'S -> bool : 'S + + > LE / v : S => True : S + iff v <= 0 + > LE / v : S => False : S + iff v > 0 + +- ``GE``: Checks that the top of the stack is greater than or equal to + zero. + +:: + + :: int : 'S -> bool : 'S + + > GE / v : S => True : S + iff v >= 0 + > GE / v : S => False : S + iff v < 0 + +Operations +---------- + +Operations on unit +~~~~~~~~~~~~~~~~~~ + +- ``UNIT``: Push a unit value onto the stack. + +:: + + :: 'A -> unit : 'A + + > UNIT / S => Unit : S + +- ``COMPARE``: Unit comparison + +:: + + :: unit : unit : 'S -> int : 'S + + > COMPARE / Unit : Unit : S => 0 : S + +Operations on type never +~~~~~~~~~~~~~~~~~~~~~~~~ + +The type ``never`` is the type of forbidden values. The most prominent +scenario in which ``never`` is used is when implementing a contract +template with no additional entrypoint. A contract template defines a set +of basic entrypoints, and its ``parameter`` declaration contains a type +variable for additional entrypoints in some branch of an union type, or +wrapped inside an option type. Letting this type variable be ``never`` in +a particular implementation indicates that the contract template has not +been extended, and turns the branch in the code that processes the +additional entrypoints into a forbidden branch. + +Values of type ``never`` cannot occur in a well-typed program. However, +they can be abstracted in the ``parameter`` declaration of a contract---or +by using the ``LAMBDA`` operation---thus indicating that the corresponding +branches in the code are forbidden. The type ``never`` also plays a role +when introducing values of union or option type with ``LEFT never``, +``RIGHT never``, or ``NONE never``. In such cases, the created values can +be inspected with the operations ``IF_LEFT``, ``IF_RIGHT``, or +``IF_NONE``, and the corresponding branches in the code are forbidden +branches. + +- ``NEVER``: Close a forbidden branch. + +:: + + :: never : 'A -> 'B + +- ``COMPARE``: Trivial comparison on type ``never`` + +:: + + :: never : never : 'S -> int : 'S + + +Operations on booleans +~~~~~~~~~~~~~~~~~~~~~~ + +- ``OR`` + +:: + + :: bool : bool : 'S -> bool : 'S + + > OR / x : y : S => (x | y) : S + +- ``AND`` + +:: + + :: bool : bool : 'S -> bool : 'S + + > AND / x : y : S => (x & y) : S + +- ``XOR`` + +:: + + :: bool : bool : 'S -> bool : 'S + + > XOR / x : y : S => (x ^ y) : S + +- ``NOT`` + +:: + + :: bool : 'S -> bool : 'S + + > NOT / x : S => ~x : S + +- ``COMPARE``: Boolean comparison + +:: + + :: bool : bool : 'S -> int : 'S + + > COMPARE / False : False : S => 0 : S + > COMPARE / False : True : S => -1 : S + > COMPARE / True : False : S => 1 : S + > COMPARE / True : True : S => 0 : S + +Operations on integers and natural numbers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Integers and naturals are arbitrary-precision, meaning that the only size +limit is gas. + +- ``NEG`` + +:: + + :: int : 'S -> int : 'S + :: nat : 'S -> int : 'S + + > NEG / x : S => -x : S + +- ``ABS`` + +:: + + :: int : 'S -> nat : 'S + + > ABS / x : S => abs (x) : S + +- ``ISNAT`` + +:: + + :: int : 'S -> option nat : 'S + + > ISNAT / x : S => Some (x) : S + iff x >= 0 + + > ISNAT / x : S => None : S + iff x < 0 + +- ``INT`` + +:: + + :: nat : 'S -> int : 'S + + > INT / x : S => x : S + +- ``ADD`` + +:: + + :: int : int : 'S -> int : 'S + :: int : nat : 'S -> int : 'S + :: nat : int : 'S -> int : 'S + :: nat : nat : 'S -> nat : 'S + + > ADD / x : y : S => (x + y) : S + +- ``SUB`` + +:: + + :: int : int : 'S -> int : 'S + :: int : nat : 'S -> int : 'S + :: nat : int : 'S -> int : 'S + :: nat : nat : 'S -> int : 'S + + > SUB / x : y : S => (x - y) : S + +- ``MUL`` + +:: + + :: int : int : 'S -> int : 'S + :: int : nat : 'S -> int : 'S + :: nat : int : 'S -> int : 'S + :: nat : nat : 'S -> nat : 'S + + > MUL / x : y : S => (x * y) : S + +- ``EDIV``: Perform Euclidean division + +:: + + :: int : int : 'S -> option (pair int nat) : 'S + :: int : nat : 'S -> option (pair int nat) : 'S + :: nat : int : 'S -> option (pair int nat) : 'S + :: nat : nat : 'S -> option (pair nat nat) : 'S + + > EDIV / x : 0 : S => None : S + > EDIV / x : y : S => Some (Pair (x / y) (x % y)) : S + iff y <> 0 + +Bitwise logical operators are also available on unsigned integers. + +- ``OR`` + +:: + + :: nat : nat : 'S -> nat : 'S + + > OR / x : y : S => (x | y) : S + +- ``AND``: (also available when the top operand is signed) + +:: + + :: nat : nat : 'S -> nat : 'S + :: int : nat : 'S -> nat : 'S + + > AND / x : y : S => (x & y) : S + +- ``XOR`` + +:: + + :: nat : nat : 'S -> nat : 'S + + > XOR / x : y : S => (x ^ y) : S + +- ``NOT``: Two's complement + +:: + + :: nat : 'S -> int : 'S + :: int : 'S -> int : 'S + + > NOT / x : S => ~x : S + + +The return type of ``NOT`` is an ``int`` and not a ``nat``. This is +because the sign is also negated. The resulting integer is computed +using two's complement. For instance, the boolean negation of ``0`` is +``-1``. To get a natural back, a possibility is to use ``AND`` with an +unsigned mask afterwards. + + +- ``LSL`` + +:: + + :: nat : nat : 'S -> nat : 'S + + > LSL / x : s : S => (x << s) : S + iff s <= 256 + > LSL / x : s : S => [FAILED] + iff s > 256 + +- ``LSR`` + +:: + + :: nat : nat : 'S -> nat : 'S + + > LSR / x : s : S => (x >> s) : S + iff s <= 256 + > LSR / x : s : S => [FAILED] + iff s > 256 + +- ``COMPARE``: Integer/natural comparison + +:: + + :: int : int : 'S -> int : 'S + :: nat : nat : 'S -> int : 'S + + > COMPARE / x : y : S => -1 : S + iff x < y + > COMPARE / x : y : S => 0 : S + iff x = y + > COMPARE / x : y : S => 1 : S + iff x > y + +Operations on strings +~~~~~~~~~~~~~~~~~~~~~ + +Strings are mostly used for naming things without having to rely on +external ID databases. They are restricted to the printable subset of +7-bit ASCII, plus some escaped characters (see section on +constants). So what can be done is basically use string constants as +is, concatenate or splice them, and use them as keys. + + +- ``CONCAT``: String concatenation. + +:: + + :: string : string : 'S -> string : 'S + + > CONCAT / s : t : S => (s ^ t) : S + + :: string list : 'S -> string : 'S + + > CONCAT / {} : S => "" : S + > CONCAT / { s ; } : S => (s ^ r) : S + where CONCAT / { } : S => r : S + +- ``SIZE``: number of characters in a string. + +:: + + :: string : 'S -> nat : 'S + +- ``SLICE``: String access. + +:: + + :: nat : nat : string : 'S -> option string : 'S + + > SLICE / offset : length : s : S => Some ss : S + where ss is the substring of s at the given offset and of the given length + iff offset and (offset + length) are in bounds + > SLICE / offset : length : s : S => None : S + iff offset or (offset + length) are out of bounds + +- ``COMPARE``: Lexicographic comparison. + +:: + + :: string : string : 'S -> int : 'S + + > COMPARE / s : t : S => -1 : S + iff s < t + > COMPARE / s : t : S => 0 : S + iff s = t + > COMPARE / s : t : S => 1 : S + iff s > t + +Operations on pairs and right combs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The type ``pair l r`` is the type of binary pairs composed of a left +element of type ``l`` and a right element of type ``r``. A value of +type ``pair l r`` is written ``Pair x y`` where ``x`` is a value of +type ``l`` and ``y`` is a value of type ``r``. + +To build tuples of length greater than 2, right combs have specific +optimized operations. For any ``n > 2``, the compact notations ``pair +t{0} t{1} ... t{n-2} t{n-1}`` is provided for the type of right combs +``pair t{0} (pair t{1} ... (pair t{n-2} t{n-1}) ...)``. Similarly, the +compact notation ``Pair x{0} x{1} ... x{n-2} x{n-1}`` is provided for +the right-comb value ``Pair x{0} (Pair x{1} ... (Pair x{n-2} x{n-1}) +...)``. Right-comb values can also be written using sequences; ``Pair +x{0} x{1} ... x{n-2} x{n-1}`` can be written ``{x{0}; x{1}; ...; x{n-2}; x{n-1}}``. + +- ``PAIR``: Build a binary pair from the stack's top two elements. + +:: + + :: 'a : 'b : 'S -> pair 'a 'b : 'S + + > PAIR / x : y : S => Pair x y : S + +- ``PAIR n``: Fold ``n`` values on the top of the stack in a right comb. + ``PAIR 0`` and ``PAIR 1`` are rejected. ``PAIR 2`` is equivalent to ``PAIR``. + +:: + + PAIR 2 :: 'a : 'b : 'S -> pair 'a 'b : 'S + PAIR (k+1) :: 'x : 'S -> pair 'x 'y : 'T + iff PAIR k :: 'S -> 'y : 'T + + Or equivalently, for n >= 2, + PAIR n :: 'a{0} : ... : 'a{n-1} : 'A -> pair 'a{0} ... 'a{n-1} : 'A + + > PAIR 2 / x : y : S => Pair x y : S + > PAIR (k+1) / x : S => Pair x y : T + iff PAIR k / S => y : T + + Or equivalently, for n >= 2, + > PAIR n / x{0} : ... : x{n-1} : S => Pair x{0} ... x{n-1} : S + +- ``UNPAIR``: Split a pair into its components. + +:: + + :: pair 'a 'b : 'S -> 'a : 'b : 'S + + > UNPAIR / Pair a b : S => a : b : S + + +- ``UNPAIR n``: Unfold ``n`` values from a right comb on the top of the stack. ``UNPAIR 0`` and ``UNPAIR 1`` are rejected. ``UNPAIR 2`` is equivalent to ``UNPAIR``. + +:: + + UNPAIR 2 :: pair 'a 'b : 'A -> 'a : 'b : 'A + UNPAIR (k+1) :: pair 'a 'b : 'A -> 'a : 'B + iff UNPAIR k :: 'b : 'A -> 'B + + Or equivalently, for n >= 2, + UNPAIR n :: pair 'a{0} ... 'a{n-1} : S -> 'a{0} : ... : 'a{n-1} : S + + > UNPAIR 2 / Pair x y : S => x : y : S + > UNPAIR (k+1) / Pair x y : SA => x : SB + iff UNPAIR k / y : SA => SB + + Or equivalently, for n >= 2, + > UNPAIR n / Pair x{0} ... x{n-1} : S => x{0} : ... : x{n-1} : S + +- ``CAR``: Access the left part of a pair. + +:: + + :: pair 'a _ : 'S -> 'a : 'S + + > CAR / Pair x _ : S => x : S + +- ``CDR``: Access the right part of a pair. + +:: + + :: pair _ 'b : 'S -> 'b : 'S + + > CDR / Pair _ y : S => y : S + +- ``GET k``: Access an element or a sub comb in a right comb. + + The nodes of a right comb of size ``n`` are canonically numbered as follows: + +:: + + 0 + / \ + 1 2 + / \ + 3 4 + / \ + 5 ... + 2n-2 + / \ + 2n-1 2n + + +Or in plain English: + + - The root is numbered with 0, + - The left child of the node numbered by ``k`` is numbered by ``k+1``, and + - The right child of the node numbered by ``k`` is numbered by ``k+2``. + +The ``GET k`` instruction accesses the node numbered by ``k``. In +particular, for a comb of size ``n``, the ``n-1`` first elements are +accessed by ``GET 1``, ``GET 3``, ..., and ``GET (2n-1)`` and the last +element is accessed by ``GET (2n)``. + +:: + + GET 0 :: 'a : 'S -> 'a : 'S + GET 1 :: pair 'x _ : 'S -> 'x : 'S + GET (k+2) :: pair _ 'y : 'S -> 'z : 'S + iff GET k :: 'y : 'S -> 'z : 'S + + Or equivalently, + GET 0 :: 'a : 'S -> 'a : 'S + GET (2k) :: pair 'a{0} ... 'a{k-1} 'a{k} : 'S -> 'a{k} : 'S + GET (2k+1) :: pair 'a{0} ... 'a{k} 'a{k+1} : 'S -> 'a{k} : 'S + + > GET 0 / x : S => x : S + > GET 1 / Pair x _ : S => x : S + > GET (k+2) / Pair _ y : S => GET k / y : S + + Or equivalently, + > GET 0 / x : S => x : S + > GET (2k) / Pair x{0} ... x{k-1} x{k} : 'S -> x{k} : 'S + > GET (2k+1) / Pair x{0} ... x{k} x{k+1} : 'S -> x{k} : 'S + + +- ``UPDATE k``: Update an element or a sub comb in a right comb. The topmost stack element is the new value to insert in the comb, the second stack element is the right comb to update. The meaning of ``k`` is the same as for the ``GET k`` instruction. + +:: + + UPDATE 0 :: 'a : 'b : 'S -> 'a : 'S + UPDATE 1 :: 'a2 : pair 'a1 'b : 'S -> pair 'a2 'b : 'S + UPDATE (k+2) :: 'c : pair 'a 'b1 : 'S -> pair 'a 'b2 : 'S + iff UPDATE k :: 'c : 'b1 : 'S -> 'b2 : 'S + + Or equivalently, + UPDATE 0 :: 'a : 'b : 'S -> 'a : 'S + UPDATE (2k) :: 'c : pair 'a{0} ... 'a{k-1} 'a{k} : 'S -> pair 'a{0} ... 'a{k-1} 'c : 'S + UPDATE (2k+1) :: 'c : pair 'a{0} ... 'a{k} 'a{k+1} : 'S -> pair 'a{0} ... 'a{k-1} 'c 'a{k+1} : 'S + + > UPDATE 0 / x : _ : S => x : S + > UPDATE 1 / x2 : Pair x1 y : S => Pair x2 y : S + > UPDATE (k+2) / z : Pair x y1 : S => Pair x y2 : S + iff UPDATE k / z : y1 : S => y2 : S + + Or equivalently, + > UPDATE 0 / x : _ : S => x : S + > UPDATE (2k) / z : Pair x{0} ... x{k-1} x{k} : 'S => Pair x{0} ... x{k-1} z : 'S + > UPDATE (2k+1) / z : Pair x{0} ... x{k-1} x{k} x{k+1} : 'S => Pair x{0} ... x{k-1} z x{k+1} : 'S + +- ``COMPARE``: Lexicographic comparison. + +:: + + :: pair 'a 'b : pair 'a 'b : 'S -> int : 'S + + > COMPARE / (Pair sa sb) : (Pair ta tb) : S => -1 : S + iff COMPARE / sa : ta : S => -1 : S + > COMPARE / (Pair sa sb) : (Pair ta tb) : S => 1 : S + iff COMPARE / sa : ta : S => 1 : S + > COMPARE / (Pair sa sb) : (Pair ta tb) : S => r : S + iff COMPARE / sa : ta : S => 0 : S + COMPARE / sb : tb : S => r : S + +Operations on sets +~~~~~~~~~~~~~~~~~~ + +- ``EMPTY_SET 'elt``: Build a new, empty set for elements of a given + type. + + The ``'elt`` type must be comparable (the ``COMPARE`` + primitive must be defined over it). + +:: + + :: 'S -> set 'elt : 'S + + > EMPTY_SET _ / S => {} : S + +- ``MEM``: Check for the presence of an element in a set. + +:: + + :: 'elt : set 'elt : 'S -> bool : 'S + + > MEM / x : {} : S => false : S + > MEM / x : { hd ; } : S => r : S + iff COMPARE / x : hd : [] => 1 : [] + where MEM / x : { } : S => r : S + > MEM / x : { hd ; } : S => true : S + iff COMPARE / x : hd : [] => 0 : [] + > MEM / x : { hd ; } : S => false : S + iff COMPARE / x : hd : [] => -1 : [] + +- ``UPDATE``: Inserts or removes an element in a set, replacing a + previous value. + +:: + + :: 'elt : bool : set 'elt : 'S -> set 'elt : 'S + + > UPDATE / x : false : {} : S => {} : S + > UPDATE / x : true : {} : S => { x } : S + > UPDATE / x : v : { hd ; } : S => { hd ; } : S + iff COMPARE / x : hd : [] => 1 : [] + where UPDATE / x : v : { } : S => { } : S + > UPDATE / x : false : { hd ; } : S => { } : S + iff COMPARE / x : hd : [] => 0 : [] + > UPDATE / x : true : { hd ; } : S => { hd ; } : S + iff COMPARE / x : hd : [] => 0 : [] + > UPDATE / x : false : { hd ; } : S => { hd ; } : S + iff COMPARE / x : hd : [] => -1 : [] + > UPDATE / x : true : { hd ; } : S => { x ; hd ; } : S + iff COMPARE / x : hd : [] => -1 : [] + +- ``ITER body``: Apply the body expression to each element of a set. + The body sequence has access to the stack. + +:: + + :: (set 'elt) : 'A -> 'A + iff body :: [ 'elt : 'A -> 'A ] + + > ITER body / {} : S => S + > ITER body / { hd ; } : S => ITER body / { } : S' + iff body / hd : S => S' + + +- ``SIZE``: Get the cardinality of the set. + +:: + + :: set 'elt : 'S -> nat : 'S + + > SIZE / {} : S => 0 : S + > SIZE / { _ ; } : S => 1 + s : S + where SIZE / { } : S => s : S + +Operations on maps +~~~~~~~~~~~~~~~~~~ + +- ``EMPTY_MAP 'key 'val``: Build a new, empty map from keys of a + given type to values of another given type. + + The ``'key`` type must be comparable (the ``COMPARE`` primitive must + be defined over it). + +:: + + :: 'S -> map 'key 'val : 'S + + > EMPTY_MAP _ _ / S => {} : S + + +- ``GET``: Access an element in a map, returns an optional value to be + checked with ``IF_SOME``. + +:: + + :: 'key : map 'key 'val : 'S -> option 'val : 'S + + > GET / x : {} : S => None : S + > GET / x : { Elt k v ; } : S => opt_y : S + iff COMPARE / x : k : [] => 1 : [] + where GET / x : { } : S => opt_y : S + > GET / x : { Elt k v ; } : S => Some v : S + iff COMPARE / x : k : [] => 0 : [] + > GET / x : { Elt k v ; } : S => None : S + iff COMPARE / x : k : [] => -1 : [] + +- ``MEM``: Check for the presence of a binding for a key in a map. + +:: + + :: 'key : map 'key 'val : 'S -> bool : 'S + + > MEM / x : {} : S => false : S + > MEM / x : { Elt k v ; } : S => r : S + iff COMPARE / x : k : [] => 1 : [] + where MEM / x : { } : S => r : S + > MEM / x : { Elt k v ; } : S => true : S + iff COMPARE / x : k : [] => 0 : [] + > MEM / x : { Elt k v ; } : S => false : S + iff COMPARE / x : k : [] => -1 : [] + +- ``UPDATE``: Assign or remove an element in a map. + +:: + + :: 'key : option 'val : map 'key 'val : 'S -> map 'key 'val : 'S + + > UPDATE / x : None : {} : S => {} : S + > UPDATE / x : Some y : {} : S => { Elt x y } : S + > UPDATE / x : opt_y : { Elt k v ; } : S => { Elt k v ; } : S + iff COMPARE / x : k : [] => 1 : [] + where UPDATE / x : opt_y : { } : S => { } : S + > UPDATE / x : None : { Elt k v ; } : S => { } : S + iff COMPARE / x : k : [] => 0 : [] + > UPDATE / x : Some y : { Elt k v ; } : S => { Elt k y ; } : S + iff COMPARE / x : k : [] => 0 : [] + > UPDATE / x : None : { Elt k v ; } : S => { Elt k v ; } : S + iff COMPARE / x : k : [] => -1 : [] + > UPDATE / x : Some y : { Elt k v ; } : S => { Elt x y ; Elt k v ; } : S + iff COMPARE / x : k : [] => -1 : [] + +- ``GET_AND_UPDATE``: A combination of the ``GET`` and ``UPDATE`` instructions. + +:: + + :: 'key : option 'val : map 'key 'val : 'S -> option 'val : map 'key 'val : 'S + +This instruction is similar to ``UPDATE`` but it also returns the +value that was previously stored in the ``map`` at the same key as +``GET`` would. + +:: + + > GET_AND_UPDATE / x : None : {} : S => None : {} : S + > GET_AND_UPDATE / x : Some y : {} : S => None : { Elt x y } : S + > GET_AND_UPDATE / x : opt_y : { Elt k v ; } : S => opt_y' : { Elt k v ; } : S + iff COMPARE / x : k : [] => 1 : [] + where GET_AND_UPDATE / x : opt_y : { } : S => opt_y' : { } : S + > GET_AND_UPDATE / x : None : { Elt k v ; } : S => Some v : { } : S + iff COMPARE / x : k : [] => 0 : [] + > GET_AND_UPDATE / x : Some y : { Elt k v ; } : S => Some v : { Elt k y ; } : S + iff COMPARE / x : k : [] => 0 : [] + > GET_AND_UPDATE / x : None : { Elt k v ; } : S => None : { Elt k v ; } : S + iff COMPARE / x : k : [] => -1 : [] + > GET_AND_UPDATE / x : Some y : { Elt k v ; } : S => None : { Elt x y ; Elt k v ; } : S + iff COMPARE / x : k : [] => -1 : [] + +- ``MAP body``: Apply the body expression to each element of a map. The + body sequence has access to the stack. + +:: + + :: (map 'key 'val) : 'A -> (map 'key 'b) : 'A + iff body :: [ (pair 'key 'val) : 'A -> 'b : 'A ] + + > MAP body / {} : S => {} : S + > MAP body / { Elt k v ; } : S => { Elt k v' ; } : S'' + where body / Pair k v : S => v' : S' + and MAP body / { } : S' => { } : S'' + +- ``ITER body``: Apply the body expression to each element of a map. + The body sequence has access to the stack. + +:: + + :: (map 'elt 'val) : 'A -> 'A + iff body :: [ (pair 'elt 'val : 'A) -> 'A ] + + > ITER body / {} : S => S + > ITER body / { Elt k v ; } : S => ITER body / { } : S' + iff body / (Pair k v) : S => S' + +- ``SIZE``: Get the cardinality of the map. + +:: + + :: map 'key 'val : 'S -> nat : 'S + + > SIZE / {} : S => 0 : S + > SIZE / { _ ; } : S => 1 + s : S + where SIZE / { } : S => s : S + + +Operations on ``big_maps`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _OperationsOnBigMaps_012: + +Big maps have three possible representations. A map literal is always +a valid representation for a big map. Big maps can also be represented +by integers called big-map identifiers. Finally, big maps can be +represented as pairs of a big-map identifier (an integer) and a +big-map diff (written in the same syntax as a map whose values are +options). + +So for example, ``{ Elt "bar" True ; Elt "foo" False }``, ``42``, and +``Pair 42 { Elt "foo" (Some False) }`` are all valid representations +of type ``big_map string bool``. + +The behavior of big-map operations is the same as if they were normal +maps, except that under the hood, the elements are loaded and +deserialized on demand. + +- ``EMPTY_BIG_MAP 'key 'val``: Build a new, empty big map from keys of a + given type to values of another given type. + + The ``'key`` type must be comparable (the ``COMPARE`` primitive must + be defined over it). + +:: + + :: 'S -> map 'key 'val : 'S + +- ``GET``: Access an element in a ``big_map``, returns an optional value to be + checked with ``IF_SOME``. + +:: + + :: 'key : big_map 'key 'val : 'S -> option 'val : 'S + +- ``MEM``: Check for the presence of an element in a ``big_map``. + +:: + + :: 'key : big_map 'key 'val : 'S -> bool : 'S + +- ``UPDATE``: Assign or remove an element in a ``big_map``. + +:: + + :: 'key : option 'val : big_map 'key 'val : 'S -> big_map 'key 'val : 'S + + +- ``GET_AND_UPDATE``: A combination of the ``GET`` and ``UPDATE`` instructions. + +:: + + :: 'key : option 'val : big_map 'key 'val : 'S -> option 'val : big_map 'key 'val : 'S + +This instruction is similar to ``UPDATE`` but it also returns the +value that was previously stored in the ``big_map`` at the same key as +``GET`` would. + + +Operations on optional values +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- ``SOME``: Pack a value as an optional value. + +:: + + :: 'a : 'S -> option 'a : 'S + + > SOME / v : S => (Some v) : S + +- ``NONE 'a``: The absent optional value. + +:: + + :: 'S -> option 'a : 'S + + > NONE / S => None : S + +- ``IF_NONE bt bf``: Inspect an optional value. + +:: + + :: option 'a : 'A -> 'B + iff bt :: [ 'A -> 'B] + bf :: [ 'a : 'A -> 'B] + + > IF_NONE bt bf / (None) : S => bt / S + > IF_NONE bt bf / (Some a) : S => bf / a : S + +- ``COMPARE``: Optional values comparison + +:: + + :: option 'a : option 'a : 'S -> int : 'S + + > COMPARE / None : None : S => 0 : S + > COMPARE / None : (Some _) : S => -1 : S + > COMPARE / (Some _) : None : S => 1 : S + > COMPARE / (Some a) : (Some b) : S => COMPARE / a : b : S + +- ``MAP body``: Apply the body expression to the value inside the option if there is one. + +:: + + :: option 'a : 'S -> option 'b : 'S + iff body :: [ 'a : 'S -> 'b : 'S ] + + > MAP body / None : S => None : S + > MAP body / (Some a) : S => (Some b) : S' + where body / a : S => b : S' + +Operations on unions +~~~~~~~~~~~~~~~~~~~~ + +- ``LEFT 'b``: Pack a value in a union (left case). + +:: + + :: 'a : 'S -> or 'a 'b : 'S + + > LEFT / v : S => (Left v) : S + +- ``RIGHT 'a``: Pack a value in a union (right case). + +:: + + :: 'b : 'S -> or 'a 'b : 'S + + > RIGHT / v : S => (Right v) : S + +- ``IF_LEFT bt bf``: Inspect a value of a union. + +:: + + :: or 'a 'b : 'A -> 'B + iff bt :: [ 'a : 'A -> 'B] + bf :: [ 'b : 'A -> 'B] + + > IF_LEFT bt bf / (Left a) : S => bt / a : S + > IF_LEFT bt bf / (Right b) : S => bf / b : S + +- ``COMPARE``: Unions comparison + +:: + + :: or 'a 'b : or 'a 'b : 'S -> int : 'S + + > COMPARE / (Left a) : (Left b) : S => COMPARE / a : b : S + > COMPARE / (Left _) : (Right _) : S => -1 : S + > COMPARE / (Right _) : (Left _) : S => 1 : S + > COMPARE / (Right a) : (Right b) : S => COMPARE / a : b : S + +Operations on lists +~~~~~~~~~~~~~~~~~~~ + +- ``CONS``: Prepend an element to a list. + +:: + + :: 'a : list 'a : 'S -> list 'a : 'S + + > CONS / a : { } : S => { a ; } : S + +- ``NIL 'a``: The empty list. + +:: + + :: 'S -> list 'a : 'S + + > NIL / S => {} : S + +- ``IF_CONS bt bf``: Inspect a list. + +:: + + :: list 'a : 'A -> 'B + iff bt :: [ 'a : list 'a : 'A -> 'B] + bf :: [ 'A -> 'B] + + > IF_CONS bt bf / { a ; } : S => bt / a : { } : S + > IF_CONS bt bf / {} : S => bf / S + +- ``MAP body``: Apply the body expression to each element of the list. + The body sequence has access to the stack. + +:: + + :: (list 'elt) : 'A -> (list 'b) : 'A + iff body :: [ 'elt : 'A -> 'b : 'A ] + + > MAP body / {} : S => {} : S + > MAP body / { a ; } : S => { b ; } : S'' + where body / a : S => b : S' + and MAP body / { } : S' => { } : S'' + +- ``SIZE``: Get the number of elements in the list. + +:: + + :: list 'elt : 'S -> nat : 'S + + > SIZE / { _ ; } : S => 1 + s : S + where SIZE / { } : S => s : S + > SIZE / {} : S => 0 : S + + +- ``ITER body``: Apply the body expression to each element of a list. + The body sequence has access to the stack. + +:: + + :: (list 'elt) : 'A -> 'A + iff body :: [ 'elt : 'A -> 'A ] + > ITER body / {} : S => S + > ITER body / { a ; } : S => ITER body / { } : S' + iff body / a : S => S' + + +Domain specific data types +-------------------------- + +- ``timestamp``: Dates in the real world. + +- ``mutez``: A specific type for manipulating tokens. + +- ``address``: An untyped address (implicit account or smart contract). + +- ``contract 'param``: A contract, with the type of its code, + ``contract unit`` for implicit accounts. + +- ``operation``: An internal operation emitted by a contract. + +- ``key``: A public cryptographic key. + +- ``key_hash``: The hash of a public cryptographic key. + +- ``signature``: A cryptographic signature. + +- ``chain_id``: An identifier for a chain, used to distinguish the test and the main chains. + +- ``bls12_381_g1``, ``bls12_381_g2`` : Points on the BLS12-381 curves G\ :sub:`1`\ and G\ :sub:`2`\ , respectively. + +- ``bls12_381_fr`` : An element of the scalar field F\ :sub:`r`\ , used for scalar multiplication on the BLS12-381 curves G\ :sub:`1`\ and G\ :sub:`2`\ . + +- ``sapling_transaction ms``: A :doc:`Sapling ` transaction + +- ``sapling_state ms``: A :doc:`Sapling ` state + +- ``ticket (t)``: A ticket used to authenticate information of type ``(t)`` on-chain. + +- ``chest``: a timelocked chest containing bytes and information to open it. + see :doc:`Timelock ` . + +- ``chest_key``: used to open a chest, also contains a proof + to check the correctness of the opening. see :doc:`Timelock ` . + + +Domain specific operations +-------------------------- + +Operations on timestamps +~~~~~~~~~~~~~~~~~~~~~~~~ + +Timestamps can be obtained by the ``NOW`` operation, or retrieved from +script parameters or globals. + +- ``ADD`` Increment / decrement a timestamp of the given number of + seconds. + +:: + + :: timestamp : int : 'S -> timestamp : 'S + :: int : timestamp : 'S -> timestamp : 'S + + > ADD / seconds : nat (t) : S => (seconds + t) : S + > ADD / nat (t) : seconds : S => (t + seconds) : S + +- ``SUB`` Subtract a number of seconds from a timestamp. + +:: + + :: timestamp : int : 'S -> timestamp : 'S + + > SUB / seconds : nat (t) : S => (seconds - t) : S + +- ``SUB`` Subtract two timestamps. + +:: + + :: timestamp : timestamp : 'S -> int : 'S + + > SUB / seconds(t1) : seconds(t2) : S => (t1 - t2) : S + +- ``COMPARE``: Timestamp comparison. + +:: + + :: timestamp : timestamp : 'S -> int : 'S + + > COMPARE / seconds(t1) : seconds(t2) : S => -1 : S + iff t1 < t2 + > COMPARE / seconds(t1) : seconds(t2) : S => 0 : S + iff t1 = t2 + > COMPARE / seconds(t1) : seconds(t2) : S => 1 : S + iff t1 > t2 + + +Operations on Mutez +~~~~~~~~~~~~~~~~~~~ + +Mutez (micro-Tez) are internally represented by a 64 bit signed +integers. There are restrictions to prevent creating a negative amount +of mutez. Operations are limited to prevent overflow and mixing them +with other numerical types by mistake. They are also mandatory checked +for under/overflows. + +- ``ADD`` + +:: + + :: mutez : mutez : 'S -> mutez : 'S + + > ADD / x : y : S => [FAILED] on overflow + > ADD / x : y : S => (x + y) : S + +- ``SUB_MUTEZ`` + +:: + + :: mutez : mutez : 'S -> option mutez : 'S + + > SUB_MUTEZ / x : y : S => None + iff x < y + > SUB_MUTEZ / x : y : S => Some (x - y) : S + +- ``MUL`` + +:: + + :: mutez : nat : 'S -> mutez : 'S + :: nat : mutez : 'S -> mutez : 'S + + > MUL / x : y : S => [FAILED] on overflow + > MUL / x : y : S => (x * y) : S + +- ``EDIV`` + +:: + + :: mutez : nat : 'S -> option (pair mutez mutez) : 'S + :: mutez : mutez : 'S -> option (pair nat mutez) : 'S + + > EDIV / x : 0 : S => None + > EDIV / x : y : S => Some (Pair (x / y) (x % y)) : S + iff y <> 0 + +- ``COMPARE``: Mutez comparison + +:: + + :: mutez : mutez : 'S -> int : 'S + + > COMPARE / x : y : S => -1 : S + iff x < y + > COMPARE / x : y : S => 0 : S + iff x = y + > COMPARE / x : y : S => 1 : S + iff x > y + +Operations on contracts +~~~~~~~~~~~~~~~~~~~~~~~ + +- ``CREATE_CONTRACT { storage 'g ; parameter 'p ; code ... }``: + Forge a new contract from a literal. + +:: + + :: option key_hash : mutez : 'g : 'S + -> operation : address : 'S + +Originate a contract based on a literal. The parameters are the +optional delegate, the initial amount taken from the current +contract, and the initial storage of the originated contract. +The contract is returned as a first class value (to be dropped, passed +as parameter or stored). The ``CONTRACT 'p`` instruction will fail +until it is actually originated. + +- ``TRANSFER_TOKENS``: Forge a transaction. + +:: + + :: 'p : mutez : contract 'p : 'S -> operation : 'S + +The parameter must be consistent with the one expected by the +contract, unit for an account. + +.. _MichelsonSetDelegate_012: + +- ``SET_DELEGATE``: Set or withdraw the contract's delegation. + +:: + + :: option key_hash : 'S -> operation : 'S + +Using this instruction is the only way to modify the delegation of a +smart contract. If the parameter is ``None`` then the delegation of the +current contract is withdrawn; if it is ``Some kh`` where ``kh`` is the +key hash of a registered delegate that is not the current delegate of +the contract, then this operation sets the delegate of the contract to +this registered delegate. The operation fails if ``kh`` is the current +delegate of the contract or if ``kh`` is not a registered delegate. + +- ``BALANCE``: Push the current amount of mutez held by the executing + contract, including any mutez added by the calling transaction. + +:: + + :: 'S -> mutez : 'S + +- ``ADDRESS``: Cast the contract to its address. + +:: + + :: contract _ : 'S -> address : 'S + + > ADDRESS / addr : S => addr : S + +- ``CONTRACT 'p``: Cast the address to the given contract type if possible. + +:: + + :: address : 'S -> option (contract 'p) : 'S + + > CONTRACT / addr : S => Some addr : S + iff addr exists and is a contract of parameter type 'p + > CONTRACT / addr : S => Some addr : S + iff 'p = unit and addr is an implicit contract + > CONTRACT / addr : S => None : S + otherwise + +- ``SOURCE``: Push the contract that initiated the current + transaction, i.e. the contract that paid the fees and + storage cost, and whose manager signed the operation + that was sent on the blockchain. Note that since + ``TRANSFER_TOKENS`` instructions can be chained, + ``SOURCE`` and ``SENDER`` are not necessarily the same. + +:: + + :: 'S -> address : 'S + +- ``SENDER``: Push the contract that initiated the current + internal transaction. It may be the ``SOURCE``, but may + also be different if the source sent an order to an intermediate + smart contract, which then called the current contract. + +:: + + :: 'S -> address : 'S + +- ``SELF``: Push the current contract. + +:: + + :: 'S -> contract 'p : 'S + where contract 'p is the type of the current contract + +Note that ``SELF`` is forbidden in lambdas because it cannot be +type-checked; the type of the contract executing the lambda cannot be +known at the point of type-checking the lambda's body. + +- ``SELF_ADDRESS``: Push the address of the current contract. This is + equivalent to ``SELF; ADDRESS`` except that it is allowed in + lambdas. + +:: + + :: 'S -> address : 'S + +Note that ``SELF_ADDRESS`` inside a lambda returns the address of the +contract executing the lambda, which can be different from the address +of the contract in which the ``SELF_ADDRESS`` instruction is written. + +- ``AMOUNT``: Push the amount of the current transaction. + +:: + + :: 'S -> mutez : 'S + +- ``IMPLICIT_ACCOUNT``: Return a default contract with the given + public/private key pair. Any funds deposited in this contract can + immediately be spent by the holder of the private key. This contract + cannot execute Michelson code and will always exist on the + blockchain. + +:: + + :: key_hash : 'S -> contract unit : 'S + +- ``VOTING_POWER``: Return the voting power of a given contract. This voting power + coincides with the weight of the contract in the voting listings (i.e., the rolls + count) which is calculated at the beginning of every voting period. + +:: + + :: key_hash : 'S -> nat : 'S + +Special operations +~~~~~~~~~~~~~~~~~~ + +- ``NOW``: Push the minimal injection time for the current block, + namely the block whose validation triggered this execution. The + minimal injection time is 60 seconds after the timestamp of the + predecessor block. This value does not change during the execution + of the contract. + +:: + + :: 'S -> timestamp : 'S + +- ``CHAIN_ID``: Push the chain identifier. + +:: + + :: 'S -> chain_id : 'S + +- ``COMPARE``: Chain identifier comparison + +:: + + :: chain_id : chain_id : 'S -> int : 'S + + > COMPARE / x : y : S => -1 : S + iff x < y + > COMPARE / x : y : S => 0 : S + iff x = y + > COMPARE / x : y : S => 1 : S + iff x > y + +- ``LEVEL``: Push the level of the current transaction's block. + +:: + + :: 'S -> nat : 'S + +- ``TOTAL_VOTING_POWER``: Return the total voting power of all contracts. The total + voting power coincides with the sum of the rolls count of every contract in the voting + listings. The voting listings is calculated at the beginning of every voting period. + +:: + + :: 'S -> nat : 'S + +Operations on bytes +~~~~~~~~~~~~~~~~~~~ + +Bytes are used for serializing data, in order to check signatures and +compute hashes on them. They can also be used to incorporate data from +the wild and untyped outside world. + +- ``PACK``: Serializes a piece of data to its optimized + binary representation. + +:: + + :: 'a : 'S -> bytes : 'S + +- ``UNPACK 'a``: Deserializes a piece of data, if valid. + +:: + + :: bytes : 'S -> option 'a : 'S + +- ``CONCAT``: Byte sequence concatenation. + +:: + + :: bytes : bytes : 'S -> bytes : 'S + + > CONCAT / s : t : S => (s ^ t) : S + + :: bytes list : 'S -> bytes : 'S + + > CONCAT / {} : S => 0x : S + > CONCAT / { s ; } : S => (s ^ r) : S + where CONCAT / { } : S => r : S + +- ``SIZE``: size of a sequence of bytes. + +:: + + :: bytes : 'S -> nat : 'S + +- ``SLICE``: Bytes access. + +:: + + :: nat : nat : bytes : 'S -> option bytes : 'S + + > SLICE / offset : length : s : S => Some ss : S + where ss is the substring of s at the given offset and of the given length + iff offset and (offset + length) are in bounds + > SLICE / offset : length : s : S => None : S + iff offset or (offset + length) are out of bounds + +- ``COMPARE``: Lexicographic comparison. + +:: + + :: bytes : bytes : 'S -> int : 'S + + > COMPARE / s : t : S => -1 : S + iff s < t + > COMPARE / s : t : S => 0 : S + iff s = t + > COMPARE / s : t : S => 1 : S + iff s > t + + +Cryptographic primitives +~~~~~~~~~~~~~~~~~~~~~~~~ + +- ``HASH_KEY``: Compute the b58check of a public key. + +:: + + :: key : 'S -> key_hash : 'S + +- ``BLAKE2B``: Compute a cryptographic hash of the value contents using the + Blake2b-256 cryptographic hash function. + +:: + + :: bytes : 'S -> bytes : 'S + +- ``KECCAK``: Compute a cryptographic hash of the value contents using the + Keccak-256 cryptographic hash function. + +:: + + :: bytes : 'S -> bytes : 'S + +- ``SHA256``: Compute a cryptographic hash of the value contents using the + Sha256 cryptographic hash function. + +:: + + :: bytes : 'S -> bytes : 'S + +- ``SHA512``: Compute a cryptographic hash of the value contents using the + Sha512 cryptographic hash function. + +:: + + :: bytes : 'S -> bytes : 'S + +- ``SHA3``: Compute a cryptographic hash of the value contents using the + SHA3-256 cryptographic hash function. + +:: + + :: bytes : 'S -> bytes : 'S + +- ``CHECK_SIGNATURE``: Check that a sequence of bytes has been signed + with a given key. + +:: + + :: key : signature : bytes : 'S -> bool : 'S + +- ``COMPARE``: Key hash, key and signature comparison + +:: + + :: key_hash : key_hash : 'S -> int : 'S + :: key : key : 'S -> int : 'S + :: signature : signature : 'S -> int : 'S + + > COMPARE / x : y : S => -1 : S + iff x < y + > COMPARE / x : y : S => 0 : S + iff x = y + > COMPARE / x : y : S => 1 : S + iff x > y + +BLS12-381 primitives +~~~~~~~~~~~~~~~~~~~~~~~~ + +- ``NEG``: Negate a curve point or field element. + +:: + + :: bls12_381_g1 : 'S -> bls12_381_g1 : 'S + :: bls12_381_g2 : 'S -> bls12_381_g2 : 'S + :: bls12_381_fr : 'S -> bls12_381_fr : 'S + +- ``ADD``: Add two curve points or field elements. + +:: + + :: bls12_381_g1 : bls12_381_g1 : 'S -> bls12_381_g1 : 'S + :: bls12_381_g2 : bls12_381_g2 : 'S -> bls12_381_g2 : 'S + :: bls12_381_fr : bls12_381_fr : 'S -> bls12_381_fr : 'S + +- ``MUL``: Multiply a curve point or field element by a scalar field element. Fr + elements can be built from naturals by multiplying by the unit of Fr using ``PUSH bls12_381_fr 1; MUL``. Note + that the multiplication will be computed using the natural modulo the order + of Fr. + +:: + + :: bls12_381_g1 : bls12_381_fr : 'S -> bls12_381_g1 : 'S + :: bls12_381_g2 : bls12_381_fr : 'S -> bls12_381_g2 : 'S + :: bls12_381_fr : bls12_381_fr : 'S -> bls12_381_fr : 'S + :: nat : bls12_381_fr : 'S -> bls12_381_fr : 'S + :: int : bls12_381_fr : 'S -> bls12_381_fr : 'S + :: bls12_381_fr : nat : 'S -> bls12_381_fr : 'S + :: bls12_381_fr : int : 'S -> bls12_381_fr : 'S + +- ``INT``: Convert a field element to type ``int``. The returned value is always between ``0`` (inclusive) and the order of Fr (exclusive). + +:: + + :: bls12_381_fr : 'S -> int : 'S + +- ``PAIRING_CHECK``: + Verify that the product of pairings of the given list of points is equal to 1 in Fq12. Returns ``true`` if the list is empty. + Can be used to verify if two pairings P1 and P2 are equal by verifying P1 * P2^(-1) = 1. + +:: + + :: list (pair bls12_381_g1 bls12_381_g2) : 'S -> bool : 'S + + +Sapling operations +~~~~~~~~~~~~~~~~~~ + +Please see the :doc:`Sapling integration` page for a more +comprehensive description of the Sapling protocol. + +- ``SAPLING_VERIFY_UPDATE``: verify and apply a transaction on a Sapling state. + +:: + + :: sapling_transaction ms : sapling_state ms : 'S -> option (pair int (sapling_state ms)): 'S + + > SAPLING_VERIFY_UPDATE / t : s : S => Some (Pair b s') : S + iff the transaction t successfully applied on state s resulting + in balance b and an updated state s' + > SAPLING_VERIFY_UPDATE / t : s : S => None : S + iff the transaction t is invalid with respect to the state + +- ``SAPLING_EMPTY_STATE ms``: Pushes an empty state on the stack. + + :: + + :: 'S -> sapling_state ms: 'S + + > SAPLING_EMPTY_STATE ms / S => sapling_state ms : S + with `sapling_state ms` being the empty state (ie. no one can spend tokens from it) + with memo_size `ms` + + +.. _MichelsonTickets_012: + +Operations on tickets +~~~~~~~~~~~~~~~~~~~~~ + +The following operations deal with tickets. Tickets are a way for smart-contracts +to authenticate data with respect to a Tezos address. This authentication can +then be used to build composable permission systems. + +A contract can create a ticket from a value and an amount. The ticket, when +inspected reveals the value, the amount, and the address of the ticketer (the contract that created the ticket). It is +impossible for a contract to “forge” a ticket that appears to have been created +by another ticketer. + +The amount is a meta-data that can be used to implement UTXOs. + +Tickets cannot be duplicated using the ``DUP`` instruction. + +For example, a ticket could represent a Non Fungible Token (NFT) or a Unspent +Transaction Output (UTXO) which can then be passed around and behave like a value. +This process can happen without the need to interact with a centralized NFT contract, +simplifying the code. + +- ``TICKET``: Create a ticket with the given content and amount. The ticketer is the address + of `SELF`. + +:: + + :: 'a : nat : 'S -> ticket 'a : 'S + +Type ``'a`` must be comparable (the ``COMPARE`` primitive must be defined over it). + +- ``READ_TICKET``: Retrieve the information stored in a ticket. Also return the ticket. + +:: + + :: ticket 'a : 'S -> pair address 'a nat : ticket 'a : 'S + +- ``SPLIT_TICKET``: Delete the given ticket and create two tickets with the + same content and ticketer as the original, but with the new provided amounts. + (This can be used to easily implement UTXOs.) + Return None iff the ticket's original amount is not equal to the sum of the + provided amounts. + +:: + + :: ticket 'a : (pair nat nat) : 'S -> + option (pair (ticket 'a) (ticket 'a)) : 'S + +- ``JOIN_TICKETS``: The inverse of ``SPLIT_TICKET``. Delete the given tickets and create a ticket with an amount equal to the + sum of the amounts of the input tickets. + (This can be used to consolidate UTXOs.) + Return None iff the input tickets have a different ticketer or content. + +:: + + :: (pair (ticket 'a) (ticket 'a)) : 'S -> + option (ticket 'a) : 'S + +Operations on timelock +~~~~~~~~~~~~~~~~~~~~~~ + +- ``OPEN_CHEST``: opens a timelocked chest given its key and the time. The results can be bytes + if the opening is correct, or a boolean indicating whether the chest was incorrect, + or its opening was. See :doc:`Timelock ` for more information. + +:: + + :: chest_key : chest : nat : 'S -> or bytes bool : 'S + + + +Removed instructions +~~~~~~~~~~~~~~~~~~~~ + +:doc:`../protocols/005_babylon` deprecated the following instructions. Because no smart +contract used these on Mainnet before they got deprecated, they have been +removed. The Michelson type-checker will reject any contract using them. + +- ``CREATE_CONTRACT { storage 'g ; parameter 'p ; code ... }``: + Forge a new contract from a literal. + +:: + + :: key_hash : option key_hash : bool : bool : mutez : 'g : 'S + -> operation : address : 'S + +See the documentation of the new ``CREATE_CONTRACT`` instruction. The +first, third, and fourth parameters are ignored. + +- ``CREATE_ACCOUNT``: Forge an account creation operation. + +:: + + :: key_hash : option key_hash : bool : mutez : 'S + -> operation : address : 'S + +Takes as argument the manager, optional delegate, the delegatable flag +and finally the initial amount taken from the currently executed +contract. This instruction originates a contract with two entrypoints; +``%default`` of type ``unit`` that does nothing and ``%do`` of type +``lambda unit (list operation)`` that executes and returns the +parameter if the sender is the contract's manager. + +- ``STEPS_TO_QUOTA``: Push the remaining steps before the contract + execution must terminate. + +:: + + :: 'S -> nat : 'S + +.. _MichelsonViews_012: + +Operations on views +~~~~~~~~~~~~~~~~~~~~ + +Views are a mechanism for contract calls that: + +- are read-only: they may depend on the storage of the contract declaring the view but cannot modify it nor emit operations (but they can call other views), +- take arguments as input in addition to the contract storage, +- return results as output, +- are synchronous: the result is immediately available on the stack of the caller contract. + +In other words, the execution of a view is included in the operation of caller's contract, but accesses the storage of the declarer's contract, in read-only mode. +Thus, in terms of execution, views are more like lambda functions rather than contract entrypoints, +Here is an example: + +:: + + code { + ...; + TRANSFER_TOKENS; + ...; + VIEW "view_ex" unit; + ...; + }; + +This contract calls a contract ``TRANSFER_TOKENS``, and, later on, a view called "view_ex". +No matter if the callee "view_ex" is defined in the same contract with this caller contract or not, +this view will be executed immediately in the current operation, +while the operations emitted by ``TRANSFER_TOKENS`` will be executed later on. +As a result, although it may seem that "view_ex" receives the storage modified by ``TRANSFER_TOKENS``, +this is not the case. +In other words, the storage of the view is the same as when the current contract was called. +In particular, in case of re-entrance, i.e., if a contract A calls a contract B that calls a view on A, the storage of the view will be the same as when B started, not when A started. + +Views are **declared** at the toplevel of the script of the contract on which they operate, +alongside the contract parameter type, storage type, and code. +To declare a view, the ``view`` keyword is used; its syntax is +``view name 'arg 'return { instr; ... }`` where: + +- ``name`` is a string of at most 31 characters matching the regular expression ``[a-zA-Z0-9_.%@]*``; it is used to identify the view, hence it must be different from the names of the other views declared in the same script; +- ``'arg`` is the type of the argument of the view; +- ``'return`` is the type of the result returned by the view; +- ``{ instr; ... }`` is a sequence of instructions of type ``lambda (pair 'arg 'storage_ty) 'return`` where ``'storage_ty`` is the type of the storage of the current contract. Certain specific instructions have different semantics in ``view``: ``BALANCE`` represents the current amount of mutez held by the contract where ``view`` is; ``SENDER`` represents the contract which is the caller of ``view``; ``SELF_ADDRESS`` represents the contract where ``view`` is; ``AMOUNT`` is always 0 mutez. + +Note that in both view input (type ``'arg``) and view output (type ``'return``), the following types are forbidden: ``ticket``, ``operation``, ``big_map`` and ``sapling_state``. + +Views are **called** using the following Michelson instruction: + +- ``VIEW name 'return``: Call the view named ``name`` from the contract whose address is the second element of the stack, sending it as input the top element of the stack. + +:: + + :: 'arg : address : 'S -> option 'return : 'S + + > VIEW name 'return / x : addr : S => Some y : S + iff addr is the address of a smart contract c with storage s + where c has a toplevel declaration of the form "view name 'arg 'return { code }" + and code / Pair x s : [] => y : [] + + > VIEW name 'return / _ : _ : S => None : S + otherwise + + + +If the given address is nonexistent or if the contract at that address does not have a view of the expected name and type, +``None`` will be returned. +Otherwise, ``Some a`` will be returned where ``a`` is the result of the view call. +Note that if a contract address containing an entrypoint ``address%entrypoint`` is provided, +only the ``address`` part will be taken. +``operation``, ``big_map`` and ``sapling_state`` and ``ticket`` types are forbidden for the ``'return`` type. + + +Here is an example using views, consisting of two contracts. +The first contract defines two views at toplevel that are named ``add_v`` and ``mul_v``. + +:: + + { parameter nat; + storage nat; + code { CAR; NIL operation ; PAIR }; + view "add_v" nat nat { UNPAIR; ADD }; + view "mul_v" nat nat { UNPAIR; MUL }; + } + + +The second contract calls the ``add_v`` view of the above contract and obtains a result immediately. + +:: + + { parameter (pair nat address) ; + storage nat ; + code { CAR ; UNPAIR; VIEW "add_v" nat ; + IF_SOME { } { FAIL }; NIL operation; PAIR }; } + +Macros +------ + +In addition to the operations above, several extensions have been added +to the language's concrete syntax. If you are interacting with the node +via RPC, bypassing the client, which expands away these macros, you will +need to desugar them yourself. + +These macros are designed to be unambiguous and reversible, meaning that +errors are reported in terms of desugared syntax. Below you'll see +these macros defined in terms of other syntactic forms. That is how +these macros are seen by the node. + +Compare +~~~~~~~ + +Syntactic sugar exists for merging ``COMPARE`` and comparison +combinators, and also for branching. + +- ``CMP{EQ|NEQ|LT|GT|LE|GE}`` + +:: + + > CMP(\op) / S => COMPARE ; (\op) / S + +- ``IF{EQ|NEQ|LT|GT|LE|GE} bt bf`` + +:: + + > IF(\op) bt bf / S => (\op) ; IF bt bf / S + +- ``IFCMP{EQ|NEQ|LT|GT|LE|GE} bt bf`` + +:: + + > IFCMP(\op) / S => COMPARE ; (\op) ; IF bt bf / S + +Fail +~~~~ + +The ``FAIL`` macros is equivalent to ``UNIT; FAILWITH`` and is callable +in any context since it does not use its input stack. + +- ``FAIL`` + +:: + + > FAIL / S => UNIT; FAILWITH / S + +Assertion macros +~~~~~~~~~~~~~~~~ + +All assertion operations are syntactic sugar for conditionals with a +``FAIL`` instruction in the appropriate branch. When possible, use them +to increase clarity about illegal states. + +- ``ASSERT`` + +:: + + > ASSERT => IF {} {FAIL} + +- ``ASSERT_{EQ|NEQ|LT|LE|GT|GE}`` + +:: + + > ASSERT_(\op) => IF(\op) {} {FAIL} + +- ``ASSERT_CMP{EQ|NEQ|LT|LE|GT|GE}`` + +:: + + > ASSERT_CMP(\op) => IFCMP(\op) {} {FAIL} + +- ``ASSERT_NONE`` + +:: + + > ASSERT_NONE => IF_NONE {} {FAIL} + +- ``ASSERT_SOME`` + +:: + + > ASSERT_SOME @x => IF_NONE {FAIL} {RENAME @x} + +- ``ASSERT_LEFT`` + +:: + + > ASSERT_LEFT @x => IF_LEFT {RENAME @x} {FAIL} + +- ``ASSERT_RIGHT`` + +:: + + > ASSERT_RIGHT @x => IF_LEFT {FAIL} {RENAME @x} + +Syntactic Conveniences +~~~~~~~~~~~~~~~~~~~~~~ + +These macros are simply more convenient syntax for various common +operations. + +- ``P(\left=A|P(\left)(\right))(\right=I|P(\left)(\right))R``: A syntactic sugar + for building nested pairs. In the case of right combs, `PAIR n` is more efficient. + +:: + + > PA(\right)R / S => DIP ((\right)R) ; PAIR / S + > P(\left)IR / S => (\left)R ; PAIR / S + > P(\left)(\right)R => (\left)R ; DIP ((\right)R) ; PAIR / S + +A good way to quickly figure which macro to use is to mentally parse the +macro as ``P`` for pair constructor, ``A`` for left leaf and ``I`` for +right leaf. The macro takes as many elements on the stack as there are +leaves and constructs a nested pair with the shape given by its name. + +Take the macro ``PAPPAIIR`` for instance: + +:: + + P A P P A I I R + ( l, ( ( l, r ), r )) + +A typing rule can be inferred: + +:: + + PAPPAIIR + :: 'a : 'b : 'c : 'd : 'S -> (pair 'a (pair (pair 'b 'c) 'd)) + +- ``UNP(\left=A|P(\left)(\right))(\right=I|P(\left)(\right))R``: A syntactic sugar + for destructing nested pairs. These macros follow the same convention + as the previous one. + +:: + + > UNPA(\right)R / S => UNPAIR ; DIP (UN(\right)R) / S + > UNP(\left)IR / S => UNPAIR ; UN(\left)R / S + > UNP(\left)(\right)R => UNPAIR ; DIP (UN(\right)R) ; UN(\left)R / S + +- ``C[AD]+R``: A syntactic sugar for accessing fields in nested pairs. In the case of right combs, ``CAR k`` and ``CDR k`` are more efficient. + +:: + + > CA(\rest=[AD]+)R / S => CAR ; C(\rest)R / S + > CD(\rest=[AD]+)R / S => CDR ; C(\rest)R / S + +- ``CAR k``: Access the ``k`` -th part of a right comb of size ``n > k + 1``. ``CAR 0`` is equivalent to ``CAR`` and in general ``CAR k`` is equivalent to ``k`` times the ``CDR`` instruction followed by once the ``CAR`` instruction. Note that this instruction cannot access the last element of a right comb; ``CDR k`` should be used for that. + +:: + + > CAR n / S => GET (2n+1) / S + +- ``CDR k``: Access the rightmost element of a right comb of size ``k``. ``CDR 0`` is a no-op, ``CDR 1`` is equivalent to ``CDR`` and in general ``CDR k`` is equivalent to ``k`` times the ``CDR`` instruction. Note that on a right comb of size ``n > k >= 2``, ``CDR k`` will return the right comb composed of the same elements but the ``k`` leftmost ones. + +:: + + > CDR n / S => GET (2n) / S + +- ``IF_SOME bt bf``: Inspect an optional value. + +:: + + > IF_SOME bt bf / S => IF_NONE bf bt / S + +- ``IF_RIGHT bt bf``: Inspect a value of a union. + +:: + + > IF_RIGHT bt bf / S => IF_LEFT bf bt / S + +- ``SET_CAR``: Set the left field of a pair. This is equivalent to ``SWAP; UPDATE 1``. + +:: + + > SET_CAR => CDR ; SWAP ; PAIR + +- ``SET_CDR``: Set the right field of a pair. This is equivalent to ``SWAP; UPDATE 2``. + +:: + + > SET_CDR => CAR ; PAIR + +- ``SET_C[AD]+R``: A syntactic sugar for setting fields in nested + pairs. In the case of right combs, `UPDATE n` is more efficient. + +:: + + > SET_CA(\rest=[AD]+)R / S => + { DUP ; DIP { CAR ; SET_C(\rest)R } ; CDR ; SWAP ; PAIR } / S + > SET_CD(\rest=[AD]+)R / S => + { DUP ; DIP { CDR ; SET_C(\rest)R } ; CAR ; PAIR } / S + +- ``MAP_CAR`` code: Transform the left field of a pair. + +:: + + > MAP_CAR code => DUP ; CDR ; DIP { CAR ; code } ; SWAP ; PAIR + +- ``MAP_CDR`` code: Transform the right field of a pair. + +:: + + > MAP_CDR code => DUP ; CDR ; code ; SWAP ; CAR ; PAIR + +- ``MAP_C[AD]+R`` code: A syntactic sugar for transforming fields in + nested pairs. + +:: + + > MAP_CA(\rest=[AD]+)R code / S => + { DUP ; DIP { CAR ; MAP_C(\rest)R code } ; CDR ; SWAP ; PAIR } / S + > MAP_CD(\rest=[AD]+)R code / S => + { DUP ; DIP { CDR ; MAP_C(\rest)R code } ; CAR ; PAIR } / S + +Concrete syntax +--------------- +.. _ConcreteSyntax_012: + +The concrete language is very close to the formal notation of the +specification. Its structure is extremely simple: an expression in the +language can only be one of the five following constructs. + +1. An integer in decimal notation. +2. A character string. +3. A byte sequence in hexadecimal notation prefixed by ``0x``. +4. The application of a primitive to a sequence of expressions. +5. A sequence of expressions. + +This simple five cases notation is called :doc:`../shell/micheline`. + +In the Tezos protocol, the primitive ``constant`` with a single +character string applied has special meaning. See +:doc:`global_constants`. + +Constants +~~~~~~~~~ + +There are three kinds of constants: + +1. Integers or naturals in decimal notation. +2. Strings, with some usual escape sequences: ``\n``, ``\\``, + ``\"``. Unescaped line-breaks (both ``\n`` and ``\r``) cannot + appear in a Michelson string. Moreover, the current version of + Michelson restricts strings to be the printable subset of 7-bit + ASCII, namely characters with codes from within `[32, 126]` range, + plus the escaped characters mentioned above. +3. Byte sequences in hexadecimal notation, prefixed with ``0x``. + +Differences with the formal notation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The concrete syntax follows the same lexical conventions as the +specification: instructions are represented by uppercase identifiers, +type constructors by lowercase identifiers, and constant constructors +are capitalized. + +All domain specific constants are Micheline constants with specific +formats. Some have two variants accepted by the data type checker: a +readable one in a string and an optimized. + +- ``mutez`` amounts are written as naturals. +- ``timestamp``\ s are written either using ``RFC3339`` notation + in a string (readable), or as the number of seconds since Epoch + in a natural (optimized). +- ``contract``\ s, ``address``\ es, ``key``\ s and ``signature``\ s + are written as strings, in their usual Base58 encoded versions + (readable), or as their raw bytes (optimized). +- ``bls12_381_g1``\ s and ``bls12_381_g2``\ s are written as their raw bytes, using a big-endian point encoding, `as specified here `__. +- ``bls12_381_fr``\ s are written as their raw bytes, using a little-endian encoding. + +The optimized versions should not reach the RPCs, the protocol code +will convert to optimized by itself when forging operations, storing +to the database, and before hashing to get a canonical representation +of a datum for a given type. + +To prevent errors, control flow primitives that take instructions as +parameters require sequences in the concrete syntax. + +:: + + IF { instr1_true ; instr2_true ; ... } + { instr1_false ; instr2_false ; ... } + +Main program structure +~~~~~~~~~~~~~~~~~~~~~~ + +The toplevel of a smart contract file must be an un-delimited sequence +of three primitive applications (in no particular order) that provide its +``code``, ``parameter`` and ``storage`` fields. + +See the next section for a concrete example. + +Annotations +----------- + +The annotation mechanism of Michelson provides ways to better track +data on the stack and to give additional type constraints. Except for +a single exception specified just after, annotations are only here to +add constraints, *i.e.* they cannot turn an otherwise rejected program +into an accepted one. The notable exception to this rule is for +entrypoints: the semantics of the `CONTRACT` and `SELF` instructions vary depending on +their constructor annotations, and some contract origination may fail due +to invalid entrypoint constructor annotations. + +Stack visualization tools like the Michelson's Emacs mode print +annotations associated with each type in the program, as propagated by +the typechecker as well as variable annotations on the types of elements +in the stack. This is useful as a debugging aid. + +We distinguish three kinds of annotations: + +- type annotations, written ``:type_annot``, +- variable annotations, written ``@var_annot``, +- and field or constructors annotations, written ``%field_annot``. + +Type annotations +~~~~~~~~~~~~~~~~ + +Each type can be annotated with at most one type annotation. They are +used to give names to types. For types to be equal, their unnamed +version must be equal and their names must be the same or at least one +type must be unnamed. + +For instance, the following Michelson program which put its integer +parameter in the storage is not well typed: + +.. code-block:: michelson + + parameter (int :p) ; + storage (int :s) ; + code { UNPAIR ; SWAP ; DROP ; NIL operation ; PAIR } + +Whereas this one is: + +.. code-block:: michelson + + parameter (int :p) ; + storage int ; + code { UNPAIR ; SWAP ; DROP ; NIL operation ; PAIR } + +Inner components of composed typed can also be named. + +:: + + (pair :point (int :x_pos) (int :y_pos)) + +Push-like instructions, that act as constructors, can also be given a +type annotation. The stack type will then have on top a type with a corresponding name. + +:: + + UNIT :t + :: 'A -> (unit :t) : 'A + + PAIR :t + :: 'a : 'b : 'S -> (pair :t 'a 'b) : 'S + + SOME :t + :: 'a : 'S -> (option :t 'a) : 'S + + NONE :t 'a + :: 'S -> (option :t 'a) : 'S + + LEFT :t 'b + :: 'a : 'S -> (or :t 'a 'b) : 'S + + RIGHT :t 'a + :: 'b : 'S -> (or :t 'a 'b) : 'S + + NIL :t 'a + :: 'S -> (list :t 'a) : 'S + + EMPTY_SET :t 'elt + :: 'S -> (set :t 'elt) : 'S + + EMPTY_MAP :t 'key 'val + :: 'S -> (map :t 'key 'val) : 'S + + EMPTY_BIG_MAP :t 'key 'val + :: 'S -> (big_map :t 'key 'val) : 'S + + +A no-op instruction ``CAST`` ensures the top of the stack has the +specified type, and change its type if it is compatible. In particular, +this allows to change or remove type names explicitly. + +:: + + CAST 'b + :: 'a : 'S -> 'b : 'S + iff 'a = 'b + + > CAST t / a : S => a : S + + +Variable annotations +~~~~~~~~~~~~~~~~~~~~ + +Variable annotations can only be used on instructions that produce +elements on the stack. An instruction that produces ``n`` elements on +the stack can be given at most ``n`` variable annotations. + +The stack type contains both the types of each element in the stack, as +well as an optional variable annotation for each element. In this +sub-section we note: + +- ``[]`` for the empty stack, +- ``@annot (top) : (rest)`` for the stack whose first value has type ``(top)`` and is annotated with variable annotation ``@annot`` and whose queue has stack type ``(rest)``. + +The instructions which do not accept any variable annotations are: + +:: + + DROP + SWAP + DIG + DUG + IF_NONE + IF_LEFT + IF_CONS + ITER + IF + LOOP + LOOP_LEFT + DIP + FAILWITH + +The instructions which accept at most one variable annotation are: + +:: + + DUP + PUSH + UNIT + SOME + NONE + PAIR + CAR + CDR + LEFT + RIGHT + NIL + CONS + SIZE + MAP + MEM + EMPTY_SET + EMPTY_MAP + EMPTY_BIG_MAP + UPDATE + GET + LAMBDA + EXEC + ADD + SUB + CONCAT + MUL + OR + AND + XOR + NOT + ABS + ISNAT + INT + NEG + EDIV + LSL + LSR + COMPARE + EQ + NEQ + LT + GT + LE + GE + ADDRESS + CONTRACT + SET_DELEGATE + IMPLICIT_ACCOUNT + NOW + LEVEL + AMOUNT + BALANCE + HASH_KEY + CHECK_SIGNATURE + BLAKE2B + SOURCE + SENDER + SELF + SELF_ADDRESS + CAST + RENAME + CHAIN_ID + +The instructions which accept at most two variable annotations are: + +:: + + UNPAIR + CREATE_CONTRACT + +Annotations on instructions that produce multiple elements on the stack +will be used in order, where the first variable annotation is given to +the top-most element on the resulting stack. Instructions that produce +``n`` elements on the stack but are given less than ``n`` variable +annotations will see only their top-most stack type elements annotated. + +:: + + UNPAIR @fist @second + :: pair 'a 'b : 'S + -> @first 'a : @second 'b : 'S + + UNPAIR @first + :: pair 'a 'b : 'S + -> @first 'a : 'b : 'S + +A no-op instruction ``RENAME`` allows to rename variables in the stack +or to erase variable annotations in the stack. + +:: + + RENAME @new + :: @old 'a ; 'S -> @new 'a : 'S + + RENAME + :: @old 'a ; 'S -> 'a : 'S + + +Field and constructor annotations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Components of pair types, option types and or types can be annotated +with a field or constructor annotation. This feature is useful to encode +records fields and constructors of sum types. + +:: + + (pair :point + (int %x) + (int %y)) + +The previous Michelson type can be used as visual aid to represent the +record type (given in OCaml-like syntax): + +:: + + type point = { x : int ; y : int } + +Similarly, + +:: + + (or :t + (int %A) + (or + (bool %B) + (pair %C + (nat %n1) + (nat %n2)))) + +can be used to represent the algebraic data type (in OCaml-like syntax): + +:: + + type t = + | A of int + | B of bool + | C of { n1 : nat ; n2 : nat } + + +Field annotations are part of the type (at the same level as type name +annotations), and so types with differing field names (if present) are +not considered equal. + +Instructions that construct elements of composed types can also be +annotated with one or multiple field annotations (in addition to type +and variable annotations). + +:: + + PAIR %fst %snd + :: 'a : 'b : 'S -> (pair ('a %fst) ('b %snd)) : 'S + + LEFT %left %right 'b + :: 'a : 'S -> (or ('a %left) ('b %right)) : 'S + + RIGHT %left %right 'a + :: 'b : 'S -> (or ('a %left) ('b %right)) : 'S + +To improve readability and robustness, instructions ``CAR`` and ``CDR`` +accept one field annotation. For the contract to type check, the name of +the accessed field in the destructed pair must match the one given here. + +:: + + CAR %fst + :: (pair ('a %fst) 'b) : S -> 'a : 'S + + CDR %snd + :: (pair 'a ('b %snd)) : S -> 'b : 'S + + +Syntax +~~~~~~ + +Primitive applications can receive one or many annotations. + +An annotation is a sequence of characters that matches the regular +expression ``@%|@%%|%@|[@:%][_0-9a-zA-Z][_0-9a-zA-Z\.%@]*``. +Note however that ``@%``, ``@%%`` and ``%@`` are +:ref:`special annotations ` and are not allowed everywhere. + +Annotations come after the primitive name and before its potential arguments. + +:: + + (prim @v :t %x arg1 arg2 ...) + + +Ordering between different kinds of annotations is not significant, but +ordering among annotations of the same kind is. Annotations of the same +kind must be grouped together. + +For instance these two annotated instructions are equivalent: + +:: + + PAIR :t @my_pair %x %y + + PAIR %x %y :t @my_pair + +An annotation can be empty, in this case it will mean *no annotation* +and can be used as a wildcard. For instance, it is useful to annotate +only the right field of a pair instruction ``PAIR % %right`` or to +ignore field access constraints, *e.g.* in the macro ``UNPPAIPAIR %x1 % +%x3 %x4``. + +Annotations and macros +~~~~~~~~~~~~~~~~~~~~~~ + +Macros also support annotations, which are propagated on their expanded +forms. As with instructions, macros that produce ``n`` values on the +stack accept ``n`` variable annotations. + +:: + + DUU+P @annot + > DUU(\rest=U*)P @annot / S => DIP (DU(\rest)P @annot) ; SWAP / S + + C[AD]+R @annot %field_name + > CA(\rest=[AD]+)R @annot %field_name / S => CAR ; C(\rest)R @annot %field_name / S + > CD(\rest=[AD]+)R @annot %field_name / S => CDR ; C(\rest)R @annot %field_name / S + + CMP{EQ|NEQ|LT|GT|LE|GE} @annot + > CMP(\op) @annot / S => COMPARE ; (\op) @annot / S + +The variable annotation on ``SET_C[AD]+R`` and ``MAP_C[AD]+R`` annotates +the resulting toplevel pair while its field annotation is used to check +that the modified field is the expected one. + +:: + + SET_C[AD]+R @var %field + > SET_CAR @var %field => CDR %field ; SWAP ; PAIR @var + > SET_CDR @var %field => CAR %field ; PAIR @var + > SET_CA(\rest=[AD]+)R @var %field / S => + { DUP ; DIP { CAR ; SET_C(\rest)R %field } ; CDR ; SWAP ; PAIR @var } / S + > SET_CD(\rest=[AD]+)R @var %field/ S => + { DUP ; DIP { CDR ; SET_C(\rest)R %field } ; CAR ; PAIR @var } / S + + MAP_C[AD]+R @var %field code + > MAP_CAR code => DUP ; CDR ; DIP { CAR %field ; code } ; SWAP ; PAIR @var + > MAP_CDR code => DUP ; CDR %field ; code ; SWAP ; CAR ; PAIR @var + > MAP_CA(\rest=[AD]+)R @var %field code / S => + { DUP ; DIP { CAR ; MAP_C(\rest)R %field code } ; CDR ; SWAP ; PAIR @var} / S + > MAP_CD(\rest=[AD]+)R @var %field code / S => + { DUP ; DIP { CDR ; MAP_C(\rest)R %field code } ; CAR ; PAIR @var} / S + +Macros for nested ``PAIR`` accept multiple annotations. Field +annotations for ``PAIR`` give names to leaves of the constructed +nested pair, in order. This next snippet gives examples instead of +generic rewrite rules for readability purposes. + +:: + + PAPPAIIR @p %x1 %x2 %x3 %x4 + :: 'a : 'b : 'c : 'd : 'S + -> @p (pair ('a %x1) (pair (pair ('b %x) ('c %x3)) ('d %x4))) : 'S + + PAPAIR @p %x1 %x2 %x3 + :: 'a : 'b : 'c : 'S -> @p (pair ('a %x1) (pair ('b %x) ('c %x3))) : 'S + +Annotations for nested ``UNPAIR`` are deprecated. + +Automatic variable and field annotations inferring +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When no annotation is provided by the Michelson programmer, the +typechecker infers some annotations in specific cases. This greatly +helps users track information in the stack for bare contracts. + +For unannotated accesses with ``CAR`` and ``CDR`` to fields that are +named will be appended (with an additional ``.`` character) to the pair +variable annotation. + +:: + + CDAR + :: @p (pair ('a %foo) (pair %bar ('b %x) ('c %y))) : 'S -> @p.bar.x 'b : 'S + +If fields are not named but the pair is still named in the stack then +``.car`` or ``.cdr`` will be appended. + +:: + + CDAR + :: @p (pair 'a (pair 'b 'c)) : 'S -> @p.cdr.car 'b : 'S + +If the original pair is not named in the stack, but a field annotation +is present in the pair type the accessed value will be annotated with a +variable annotation corresponding to the field annotation alone. + +:: + + CDAR + :: (pair ('a %foo) (pair %bar ('b %x) ('c %y))) : 'S -> @bar.x 'b : 'S + +A similar mechanism is used for context dependent instructions: + +:: + + ADDRESS :: @c contract _ : 'S -> @c.address address : 'S + + CONTRACT 'p :: @a address : 'S -> @a.contract contract 'p : 'S + + BALANCE :: 'S -> @balance mutez : 'S + + SOURCE :: 'S -> @source address : 'S + + SENDER :: 'S -> @sender address : 'S + + SELF :: 'S -> @self contract 'p : 'S + + SELF_ADDRESS :: 'S -> @self address : 'S + + AMOUNT :: 'S -> @amount mutez : 'S + + NOW :: 'S -> @now timestamp : 'S + + LEVEL :: 'S -> @level nat : 'S + +Inside nested code blocks, bound items on the stack will be given a +default variable name annotation depending on the instruction and stack +type (which can be changed). For instance the annotated typing rule for +``ITER`` on lists is: + +:: + + ITER body + :: @l (list 'e) : 'A -> 'A + iff body :: [ @l.elt e' : 'A -> 'A ] + +Special annotations +~~~~~~~~~~~~~~~~~~~ +.. _SpecialAnnotations_012: + +The special variable annotations ``@%`` and ``@%%`` can be used on instructions +``CAR``, ``CDR``, and ``UNPAIR``. It means to use the accessed field name (if any) as +a name for the value on the stack. The following typing rule +demonstrates their use for instruction ``CAR``. + +:: + + CAR @% + :: @p (pair ('a %fst) ('b %snd)) : 'S -> @fst 'a : 'S + + CAR @%% + :: @p (pair ('a %fst) ('b %snd)) : 'S -> @p.fst 'a : 'S + +The special field annotation ``%@`` can be used on instructions +``PAIR``, ``LEFT`` and ``RIGHT``. It means to use the variable +name annotation in the stack as a field name for the constructed +element. Two examples with ``PAIR`` follows, notice the special +treatment of annotations with ``.``. + +:: + + PAIR %@ %@ + :: @x 'a : @y 'b : 'S -> (pair ('a %x) ('b %y)) : 'S + + PAIR %@ %@ + :: @p.x 'a : @p.y 'b : 'S -> @p (pair ('a %x) ('b %y)) : 'S + :: @p.x 'a : @q.y 'b : 'S -> (pair ('a %x) ('b %y)) : 'S + +Entrypoints +----------- + +The specification up to this point has been mostly ignoring existence +of entrypoints: a mechanism of contract level polymorphism. This +mechanism is optional, non intrusive, and transparent to smart +contracts that don't use them. This section is to be read as a patch +over the rest of the specification, introducing rules that apply only +in presence of contracts that make use of entrypoints. + +Defining and calling entrypoints +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Entrypoints piggyback on the constructor annotations. A contract with +entrypoints is basically a contract that takes a disjunctive type (a +nesting of ``or`` types) as the root of its input parameter, decorated +with constructor annotations. An extra check is performed on these +constructor annotations: a contract cannot define two entrypoints with +the same name. + +An external transaction can include an entrypoint name alongside the +parameter value. In that case, if there is a constructor annotation +with this name at any position in the nesting of ``or`` types, the +value is automatically wrapped into the according constructors. If the +transaction specifies an entrypoint, but there is no such constructor +annotation, the transaction fails. + +For instance, suppose the following input type. + +``parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))`` + +The input values will be wrapped as in the following examples. + +:: + + +------------+-----------+---------------------------------+ + | entrypoint | input | wrapped input | + +------------+-----------+---------------------------------+ + | %A | 3 | Left (Left 3) | + | %B | False | Left (Right False) | + | %C | "bob" | Right (Right "bob") | + | %Z | Unit | Right (Left Unit) | + | %maybe_C | Right "x" | Right (Right "x") | + | %maybe_C | Left Unit | Right (Left Unit) | + +------------+-----------+---------------------------------+ + | not given | value | value (untouched) | + | %BAD | _ | failure, contract not called | + +------------+-----------+---------------------------------+ + +The ``default`` entrypoint +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A special semantics is assigned to the ``default`` entrypoint. If the +contract does not explicitly declare a ``default`` entrypoint, then it +is automatically assigned to the root of the parameter +type. Conversely, if the contract is called without specifying an +entrypoint, then it is assumed to be called with the ``default`` +entrypoint. This behaviour makes the entrypoint system completely +transparent to contracts that do not use it. + +This is the case for the previous example, for instance. If a value is +passed to such a contract specifying entrypoint ``default``, then the +value is fed to the contract untouched, exactly as if no entrypoint +was given. + +A non enforced convention is to make the entrypoint ``default`` of +type unit, and to implement the crediting operation (just receive the +transferred tokens). + +A consequence of this semantics is that if the contract uses the +entrypoint system and defines a ``default`` entrypoint somewhere else +than at the root of the parameter type, then it must provide an +entrypoint for all the paths in the toplevel disjunction. Otherwise, +some parts of the contracts would be dead code. + +Another consequence of setting the entrypoint somewhere else than at +the root is that it makes it impossible to send the raw values of the +full parameter type to a contract. A trivial solution for that is to +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))`` + +The input values will be wrapped as in the following examples. + +:: + + +------------+---------------------+-----------------------+ + | entrypoint | input | wrapped input | + +------------+---------------------+-----------------------+ + | %A | 3 | Left (Left 3) | + | %B | False | Left (Right False) | + | %default | Unit | Right (Left Unit) | + | %root | Right (Right "bob") | Right (Right "bob") | + +------------+---------------------+-----------------------+ + | not given | Unit | Right (Left Unit) | + | %BAD | _ | failure, contract not | + +------------+---------------------+-----------------------+ + +Calling entrypoints from Michelson +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Michelson code can also produce transactions to a specific entrypoint. + +For this, both types ``address`` and ``contract`` have the ability to +denote not just an address, but a pair of an address and an +entrypoint. The concrete notation is ``"address%entrypoint"``. +Note that ``"address"`` is strictly equivalent to ``"address%default"``, +and for clarity, the second variant is forbidden in the concrete syntax. + +When the ``TRANSFER_TOKENS`` instruction is called, it places the +entrypoint provided in the contract handle in the transaction. + +The ``CONTRACT t`` instruction has a variant ``CONTRACT %entrypoint +t``, that works as follows. Note that ``CONTRACT t`` is strictly +equivalent to ``CONTRACT %default t``, and for clarity, the second +variant is forbidden in the concrete syntax. + +:: + + +---------------+---------------------+------------------------------------------+ + | input address | instruction | output contract | + +---------------+---------------------+------------------------------------------+ + | "addr" | CONTRACT t | (Some "addr") if contract exists, has a | + | | | default entrypoint of type t, or has no | + | | | default entrypoint and parameter type t | + +---------------+---------------------+------------------------------------------+ + | "addr%name" | CONTRACT t | (Some "addr%name") if addr exists and | + +---------------+---------------------+ has an entrypoint %name of type t | + | "addr" | CONTRACT %name t | | + +---------------+---------------------+------------------------------------------+ + | "addr%_" | CONTRACT %_ t | None | + +---------------+---------------------+------------------------------------------+ + +Similarly, the ``SELF`` instruction has a variant ``SELF %entrypoint``, +that is only well-typed if the current contract has an entrypoint named ``%entrypoint``. + +- ``SELF %entrypoint`` + +:: + + :: 'S -> contract 'p : 'S + where contract 'p is the type of the entrypoint %entrypoint of the current contract + +Implicit accounts are considered to have a single ``default`` +entrypoint of type ``Unit``. + +JSON syntax +----------- + +Micheline expressions are encoded in JSON like this: + +- An integer ``N`` is an object with a single field ``"int"`` whose + value is the decimal representation as a string. + + ``{ "int": "N" }`` + +- A string ``"contents"`` is an object with a single field ``"string"`` + whose value is the decimal representation as a string. + + ``{ "string": "contents" }`` + +- A sequence is a JSON array. + + ``[ expr, ... ]`` + +- A primitive application is an object with two fields ``"prim"`` for + the primitive name and ``"args"`` for the arguments (that must + contain an array). A third optional field ``"annots"`` contains a + list of annotations, including their leading ``@``, ``%`` or ``:`` + sign. + + ``{ "prim": "pair", "args": [ { "prim": "nat", "args": [] }, { "prim": "nat", "args": [] } ], "annots": [":t"] }`` + +As in the concrete syntax, all domain specific constants are encoded as +strings. + +Examples +--------- + +Contracts in the system are stored as a piece of code and a global data +storage. The type of the global data of the storage is fixed for each +contract at origination time. This is ensured statically by checking on +origination that the code preserves the type of the global data. For +this, the code of the contract is checked to be of type +``lambda (pair 'arg 'global) -> (pair (list operation) 'global)`` where +``'global`` is the type of the original global store given on origination. +The contract also takes a parameter and returns a list of internal operations, +hence the complete calling convention above. The internal operations are +queued for execution when the contract returns. + +Empty contract +~~~~~~~~~~~~~~ + +The simplest contract is the contract for which the ``parameter`` and +``storage`` are all of type ``unit``. This contract is as follows: + +.. code-block:: michelson + + code { CDR ; # keep the storage + NIL operation ; # return no internal operation + PAIR }; # respect the calling convention + storage unit; + parameter unit; + + +Example contract with entrypoints +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following contract maintains a number in its storage. It has two +entrypoints ``add`` and ``sub`` to modify it, and the default +entrypoint, of type ``unit`` will reset it to ``0``. + +:: + + { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; + storage int ; + code { AMOUNT ; PUSH mutez 0 ; ASSERT_CMPEQ ; UNPAIR ; + IF_LEFT + { IF_LEFT { ADD } { SWAP ; SUB } } + { DROP ; DROP ; PUSH int 0 } ; + NIL operation ; PAIR } } + +Multisig contract +~~~~~~~~~~~~~~~~~ + +The multisig is a typical access control contract. The ownership of +the multisig contract is shared between ``N`` participants represented +by their public keys in the contract's storage. Any action on the +multisig contract needs to be signed by ``K`` participants where the +threshold ``K`` is also stored in the storage. + +To avoid replay of the signatures sent to the contract, the signed +data include not only a description of the action to perform but also +the address of the multisig contract and a counter that gets +incremented at each successful call to the contract. + +The multisig commands of :ref:`Tezos command line client ` +use this +smart contract. Moreover, `functional correctness of this contract has +been verified +`__ +using the Coq proof assistant. + + +.. code-block:: michelson + + parameter (pair + (pair :payload + (nat %counter) # counter, used to prevent replay attacks + (or :action # payload to sign, represents the requested action + (pair :transfer # transfer tokens + (mutez %amount) # amount to transfer + (contract %dest unit)) # destination to transfer to + (or + (option %delegate key_hash) # change the delegate to this address + (pair %change_keys # change the keys controlling the multisig + (nat %threshold) # new threshold + (list %keys key))))) # new list of keys + (list %sigs (option signature))); # signatures + + storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; + + code + { + UNPAIR ; SWAP ; DUP ; DIP { SWAP } ; + DIP + { + UNPAIR ; + # pair the payload with the current contract address, to ensure signatures + # can't be replayed across different contracts if a key is reused. + DUP ; SELF ; ADDRESS ; CHAIN_ID ; PAIR ; PAIR ; + PACK ; # form the binary payload that we expect to be signed + DIP { UNPAIR @counter ; DIP { SWAP } } ; SWAP + } ; + + # Check that the counters match + UNPAIR @stored_counter; DIP { SWAP }; + ASSERT_CMPEQ ; + + # Compute the number of valid signatures + DIP { SWAP } ; UNPAIR @threshold @keys; + DIP + { + # Running count of valid signatures + PUSH @valid nat 0; SWAP ; + ITER + { + DIP { SWAP } ; SWAP ; + IF_CONS + { + IF_SOME + { SWAP ; + DIP + { + SWAP ; DIIP { DIP { DUP } ; SWAP } ; + # Checks signatures, fails if invalid + CHECK_SIGNATURE ; ASSERT ; + PUSH nat 1 ; ADD @valid } } + { SWAP ; DROP } + } + { + # There were fewer signatures in the list + # than keys. Not all signatures must be present, but + # they should be marked as absent using the option type. + FAIL + } ; + SWAP + } + } ; + # Assert that the threshold is less than or equal to the + # number of valid signatures. + ASSERT_CMPLE ; + DROP ; DROP ; + + # Increment counter and place in storage + DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR} ; + + # We have now handled the signature verification part, + # produce the operation requested by the signers. + NIL operation ; SWAP ; + IF_LEFT + { # Transfer tokens + UNPAIR ; UNIT ; TRANSFER_TOKENS ; CONS } + { IF_LEFT { + # Change delegate + SET_DELEGATE ; CONS } + { + # Change set of signatures + DIP { SWAP ; CAR } ; SWAP ; PAIR ; SWAP }} ; + PAIR } + + + +Full grammar +------------ + +:: + + ::= + | + | + | + | Unit + | True + | False + | Pair ... + | Left + | Right + | Some + | None + | { ; ... } + | { Elt ; ... } + | instruction + ::= + | [0-9]+ + ::= + | + | - + ::= + | "*" + ::= + | \" + | \r + | \n + | \t + | \b + | \\ + | [^"\] + ::= + | 0x[0-9a-fA-F]+ + ::= + | { ... } + | DROP + | DROP + | DUP + | DUP + | SWAP + | DIG + | DUG + | PUSH + | SOME + | NONE + | UNIT + | NEVER + | IF_NONE { ... } { ... } + | PAIR + | PAIR + | CAR + | CDR + | UNPAIR + | UNPAIR + | LEFT + | RIGHT + | IF_LEFT { ... } { ... } + | NIL + | CONS + | IF_CONS { ... } { ... } + | SIZE + | EMPTY_SET + | EMPTY_MAP + | EMPTY_BIG_MAP + | MAP { ... } + | ITER { ... } + | MEM + | GET + | GET + | UPDATE + | UPDATE + | IF { ... } { ... } + | LOOP { ... } + | LOOP_LEFT { ... } + | LAMBDA { ... } + | EXEC + | APPLY + | DIP { ... } + | DIP { ... } + | FAILWITH + | CAST + | RENAME + | CONCAT + | SLICE + | PACK + | UNPACK + | ADD + | SUB + | MUL + | EDIV + | ABS + | ISNAT + | INT + | NEG + | LSL + | LSR + | OR + | AND + | XOR + | NOT + | COMPARE + | EQ + | NEQ + | LT + | GT + | LE + | GE + | SELF + | SELF_ADDRESS + | CONTRACT + | TRANSFER_TOKENS + | SET_DELEGATE + | CREATE_CONTRACT { ... } + | IMPLICIT_ACCOUNT + | VOTING_POWER + | NOW + | LEVEL + | AMOUNT + | BALANCE + | CHECK_SIGNATURE + | BLAKE2B + | KECCAK + | SHA3 + | SHA256 + | SHA512 + | HASH_KEY + | SOURCE + | SENDER + | ADDRESS + | CHAIN_ID + | TOTAL_VOTING_POWER + | PAIRING_CHECK + | SAPLING_EMPTY_STATE + | SAPLING_VERIFY_UPDATE + | TICKET + | READ_TICKET + | SPLIT_TICKET + | JOIN_TICKETS + | OPEN_CHEST + ::= + | + | option + | list + | set + | operation + | contract + | ticket + | pair ... + | or + | lambda + | map + | big_map + | bls12_381_g1 + | bls12_381_g2 + | bls12_381_fr + | sapling_transaction + | sapling_state + | chest + | chest_key + ::= + | unit + | never + | bool + | int + | nat + | string + | chain_id + | bytes + | mutez + | key_hash + | key + | signature + | timestamp + | address + | option + | or + | pair ... + + +Reference implementation +------------------------ + +The language is implemented in OCaml as follows: + +- The lower internal representation is written as a GADT whose type + parameters encode exactly the typing rules given in this + specification. In other words, if a program written in this + representation is accepted by OCaml's typechecker, it is guaranteed + type-safe. This is of course also valid for programs not + handwritten but generated by OCaml code, so we are sure that any + manipulated code is type-safe. + + In the end, what remains to be checked is the encoding of the typing + rules as OCaml types, which boils down to half a line of code for + each instruction. Everything else is left to the venerable and well + trusted OCaml. + +- The interpreter is basically the direct transcription of the + rewriting rules presented above. It takes an instruction, a stack and + transforms it. OCaml's typechecker ensures that the transformation + respects the pre and post stack types declared by the GADT case for + each instruction. + + The only things that remain to be reviewed are value dependent + choices, such as we did not swap true and false when + interpreting the IF instruction. + +- The input, untyped internal representation is an OCaml ADT with + only 5 grammar constructions: ``String``, ``Int``, ``Bytes``, ``Seq`` and + ``Prim``. It is the target language for the parser, since not all + parsable programs are well typed, and thus could simply not be + constructed using the GADT. + +- The typechecker is a simple function that recognizes the abstract + grammar described in section X by pattern matching, producing the + well-typed, corresponding GADT expressions. It is mostly a checker, + not a full inferrer, and thus takes some annotations (basically the + input and output of the program, of lambdas and of uninitialized maps + and sets). It works by performing a symbolic evaluation of the + program, transforming a symbolic stack. It only needs one pass over + the whole program. + + Here again, OCaml does most of the checking, the structure of the + function is very simple, what we have to check is that we transform a + ``Prim ("If", ...)`` into an ``If``, a ``Prim ("Dup", ...)`` into a + ``Dup``, etc. diff --git a/docs/012/plugins.rst b/docs/012/plugins.rst new file mode 100644 index 000000000000..770b75c55b4b --- /dev/null +++ b/docs/012/plugins.rst @@ -0,0 +1,53 @@ +Protocol plugins +================ + +Protocol plugins implement extra APIs needed by the shell in order to interact with the economic protocol, beyond the one provided by the protocol environment. +This code is not strictly speaking part of the protocol code base, so this is not subject to on-chain governance (see :doc:`voting procedure `), but it is still protocol-dependent, which means that it may vary with different protocols. +For instance, the plugin code for protocol Alpha is located in file :src:`src/proto_012_PsiThaCa/lib_plugin/plugin.ml`. +Thus, a specific version is included in the Octez node for each protocol version (recall that a new release of Octez is usually delivered for each new protocol proposal, see :doc:`../releases/releases`) + +So what kind of features may a protocol plugin provide? +For instance, protocol plugins do not define the context, or restrict the validity of operations. +In turn protocol plugins may, for example: + +- be adjacent enough to the protocol code that it needs to have access to the protocol's internal representations for certain structures: e.g., it has some RPCs that can introspect on the protocol dependent content for certain operations; +- implement some common operations that are customized for each protocol (e.g., :ref:`prevalidator_filters`). + +.. _prevalidator_filters_012: + +Prevalidator filters +~~~~~~~~~~~~~~~~~~~~ + +The :ref:`prevalidator component ` of the shell is responsible for disseminating operations over the peer-to-peer network, that may be included in next blocks. +To prevent spam, the prevalidator implements built-in filtering mechanisms that limit to some extent the risk of flooding the network with invalid operations. +However, these selection mechanisms remain rather laxist to protect from DOS attacks. +In particular, a very affordable technique for attackers is based on flooding the network with, valid but useless, zero-fees operations. +This is why an additional and more flexible selection mechanism is included in the Octez node: *prevalidator filters*. + +Prevalidator filters thus serve at further restricting the operations to propapate by the node to the network. +Filters are implemented as a node plugin and a specific filter is delivererd with each protocol version. +When the chain switches to a new protocol, the node installs its corresponding filter, *in lieu of* the filter of the previous protocol. + +The prevalidator filter is based on restricting operations based on their associated fees, to reject "too cheap" or "zero-fees" operations. +However, the filters could also be used to restrict the propagation of consensus operations (e.g. endorsements). + +The filter is tunable by several parameters, whose values can be retrieved and changed by users via the following RPC calls, respectively: + +- ``rpc get /chains//mempool/filter`` +- ``rpc post /chains//mempool/filter`` + +The following parameters can be thus inspected and modified: + +- ``minimal_fees``: type ``int``, default ``100`` +- ``minimal_nanotez_per_gas_unit``: type ``int``, default ``100`` +- ``minimal_nanotez_per_byte``: type ``int``, default ``1000`` +- ``allow_script_failure``: type ``bool``, default ``true`` + +For example, the following command modifies the ``minimal_fees`` parameter (and resets all the other parameters to their default values):: + + tezos-client rpc post /chains/main/mempool/filter with '{ "minimal_fees": "42" }' + +See also: + +- The `mempool plugin API `__ +- MR :gl:`!3118` show defaults in RPC get mempool/filter diff --git a/docs/012/proof_of_stake.rst b/docs/012/proof_of_stake.rst new file mode 100644 index 000000000000..5366a3e28731 --- /dev/null +++ b/docs/012/proof_of_stake.rst @@ -0,0 +1,171 @@ +Proof-of-stake +============== + +Overview +-------- + +:doc:`The consensus algorithm ` in Tezos is based on the +*proof-of-stake* mechanism. Proof-of-stake means that participants +in the consensus algorithm are chosen in function of their stake (the +amount of tokens a participant has). The same mechanism is used in the +Tezos :doc:`governance `. + +If one does not have enough stake to participate on its own or does not want to +set up the needed infrastructure, (s)he can use :ref:`delegation +`. Therefore, in Tezos, it is the :ref:`delegates` +that may participate in consensus. Delegates' rights to participate are +determined by a `follow-the-coin strategy +`_. This +procedure is random, in that its result cannot be predicted too much in advance. +The :ref:`randomness` is obtained from information already found on the +blockchain. Thus, the procedure is also deterministic: delegates' rights are +uniquely determined from the random element. + +Delegation +---------- + +A *delegate* is any :ref:`implicit account ` registered as +such by emitting a delegate registration operation. + +Any :ref:`accounts ` (implicit or originated) can specify a delegate +through a delegation operation. + +Any account can change or revoke its delegate at any time. However, the change +only becomes effective after ``PRESERVED_CYCLES + 2`` :ref:`cycles `. +The value ``PRESERVED_CYCLES`` is a +:ref:`protocol constant `. + +A delegate participates in consensus and in governance with a weight +proportional with their delegated stake, which includes the balances +of all the accounts that delegate to it, and also the balance of the +delegate itself. To participate in consensus or in governance, a +delegate needs to have at least a minimal stake, which is given by the +``TOKENS_PER_ROLL`` :ref:`protocol constant +`. + +Delegates place security deposits that may be forfeited in case they do not +follow (some particular rules of) the protocol. Security deposits are deduced +from the delegates' own balance. + + +Active and passive delegates +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _active_delegate_012: + +A delegate can be marked as either active or passive. A passive +delegate cannot participate in the consensus algorithm. + +A delegate is marked as active at its registration. + +A delegate becomes passive for cycle ``n`` when they +fail to participate in the consensus algorithm in +the past ``PRESERVED_CYCLES`` cycles, that is, in cycles ``n-1``, +``n-2``, ..., ``n - PRESERVED_CYCLES``. + +Delegates' rights selection +--------------------------- + +Tezos being proof-of-stake, the delegates' rights are selected at random based on their +stake. + +.. _random_seed_012: + +Random seed +^^^^^^^^^^^ + +Each cycle ``n`` is associated with a random seed. The random seed for cycle +``n`` is a 256-bit number generated at the very end of cycle ``n-1`` from +*nonces* to which delegates commit during cycle ``n-2``. One block out of every +``BLOCKS_PER_COMMITMENT`` can contain a commitment. A commitment is the hash of +a nonce. The commitment is generated by the block proposer and is included in +the block header. + +The committed nonce must be revealed by the original block proposer during cycle +``n-1`` under penalty of forfeiting the rewards and fees of the block that +included the commitment. The associated security deposit is not forfeited. + +A *nonce revelation* is an operation and multiple nonce revelations can thus be +included in a block. A reward ``SEED_NONCE_REVELATION_TIP`` is given for +including a revelation. Revelations are free operations which do not compete +with transactions for block space. Up to ``MAX_ANON_OPS_PER_BLOCK`` revelations, +wallet activations and denunciations can be contained in any given block. + +The seed for cycle ``n`` is obtained as follows: the seed of cycle ``n-1`` is +hashed with a constant and then with each nonce revealed in cycle ``n-1``. + +.. _rights_012: + +Slot selection +^^^^^^^^^^^^^^ + +To return to the rights selection mechanism, we first introduce a new +terminology, *stake snapshot*, to denote the stored (in the +:ref:`context `) stake distribution for a given block. Stake +snapshots are taken (and stored) every ``BLOCKS_PER_STAKE_SNAPSHOT`` +blocks. + +The delegates' rights at a given level and for a particular role in +the protocol are expressed in terms of *slots* that the delegate +receives for that role. The slot owner is obtained by running a PRNG +(pseudo-random number generator) with the following input: + +- the level +- the role (a string) +- the slot (a non-negative integer) + +Let `n` be the cycle the level belongs to. +The seed of the PRNG is the :ref:`random seed ` associated with cycle ``n-PRESERVED_CYCLES``. +The PRNG selects a snapshot from cycle ``n-PRESERVED_CYCLES-2`` and then it selects a stake in the selected snapshot. +The slot owner is then the stake owner. + +.. _protocol_constants_012: + +Protocol constants +------------------ + +Protocols are parameterized by several parameters called *protocol constants*, which may vary from one protocol to another or from one network to another (for instance, test networks move faster). + +The list of protocol constants can be found in the API of the `Constants module `__. + +The values of protocol constants can be found using a :ref:`specific RPC call `, as shown in :ref:`this example `. + +In particular, the protocol constants related to the proof-of-stake mechanism are detailed below. + +.. _ps_constants_012: + +Proof-of-stake parameters +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :widths: 55 25 + :header-rows: 1 + + * - Parameter name + - Parameter value + * - ``BLOCKS_PER_CYCLE`` + - 8192 blocks + * - ``PRESERVED_CYCLES`` + - 5 cycles + * - ``BLOCKS_PER_COMMITMENT`` + - 64 blocks + * - ``MAX_ANON_OPS_PER_BLOCK`` + - 132 revelations + * - ``SEED_NONCE_REVELATION_TIP`` + - 1/8 ꜩ + * - ``TOKENS_PER_ROLL`` + - 6,000 ꜩ + * - ``BLOCKS_PER_STAKE_SNAPSHOT`` + - 512 blocks + + +Further External Resources +-------------------------- + +The original design of the proof-of-stake mechanism in Tezos can be +found in the `whitepaper +`_. + +Another presentation of the Tezos' proof-of-stake mechanism can be +found in the `Tezos agora wiki entry +`_. diff --git a/docs/012/protocol.rst b/docs/012/protocol.rst new file mode 100644 index 000000000000..a49f35ea036b --- /dev/null +++ b/docs/012/protocol.rst @@ -0,0 +1,62 @@ +The economic protocol +===================== + +The economic protocol provides the rules for checking the validity of the blocks and operations, and for updating the blockchain state accordingly, by applying new valid blocks and operations on the current blockchain state. These rules can be changed through voting. +Thus, the +economic protocol represents the amendable part of Tezos. + +This page groups the documentation helping developers and users in +understanding the basic concepts of the economic protocol +(proof-of-stake, consensus, voting, etc), its features (Michelson, +Sapling, etc), and some details about its implementation. + + +.. toctree:: + :maxdepth: 2 + + protocol_overview + +.. toctree:: + :maxdepth: 2 + + consensus + +.. toctree:: + :maxdepth: 2 + + proof_of_stake + +.. toctree:: + :maxdepth: 2 + + voting + +.. toctree:: + :maxdepth: 2 + + michelson + +.. toctree:: + :maxdepth: 2 + + timelock + +.. toctree:: + :maxdepth: 2 + + sapling + +.. toctree:: + :maxdepth: 2 + + liquidity_baking + +.. toctree:: + :maxdepth: 2 + + global_constants + +.. toctree:: + :maxdepth: 2 + + plugins diff --git a/docs/012/protocol_overview.rst b/docs/012/protocol_overview.rst new file mode 100644 index 000000000000..405fcf93ed8f --- /dev/null +++ b/docs/012/protocol_overview.rst @@ -0,0 +1,112 @@ +Overview of the economic protocol +================================= + +Tezos overview +~~~~~~~~~~~~~~ + +Tezos is a distributed system in which nodes agree upon a chain of blocks of +operations. Tezos is also an account-based crypto-ledger, where an account is +associated to a public-private key pair, and has a balance, that is, a number of +tokens. Tezos is a :doc:`proof-of-stake` system in which any +account that has a minimal stake amount has the right to produce blocks, in +proportion to their balance. + +A Tezos node has mainly three roles: it validates blocks and operations, it +broadcasts them to (and retrieves them from) other nodes, and it maintains a +main chain and its associated state (i.e. the ledger), which includes accounts +and their balances, among other things. Note that, as blocks only specify a +predecessor block, exchanged blocks do not necessarily form a chain, but rather +a tree. Nodes communicate over :doc:`a gossip network<../shell/p2p>`. + +A Tezos node acts as a server, which responds to queries and requests from +clients. Such queries and requests are implemented via :doc:`RPC +calls<../developer/rpc>`. A client can query the chain’s state and can inject +blocks and operations into a node. One particular client is the :ref:`baker daemon `, +which is associated to an account. In particular the baker has access to the +account’s private key and thus can sign blocks and operations. + +The main reason for using such a client-server architecture is safety: to insulate +the component that has access to the client keys, i.e. the baker, from the +component which is exposed to the internet, i.e. the node. Indeed, the node and +the baker can sit on different computers and the baker does not need to be +exposed to the internet. So nodes manage communication and shield bakers from +network attacks, and bakers hold secrets and bake blocks into the blockchain. + +Another advantage of this architecture is that bakers can more easily have +different implementations, and this is important, for instance because different bakers may want +to implement different transaction selection strategies. + +Tezos is a self-amending blockchain, in that a large part of Tezos can be +changed through a so-called amendement procedure. To this end, as mentioned in +:doc:`the big picture<../shell/the_big_picture>`, a Tezos node consists of two +components: + +- the shell, which comprises the network and storage layer, and embeds +- the economic protocol component, which is the part that can be changed through amendment. + +The role of the protocol +~~~~~~~~~~~~~~~~~~~~~~~~ + +At a very high level, a protocol must: + +- implement protocol-specific types, such as the type of operations or protocol-specific block header data (in addition to the shell generic header), +- define under which conditions a block is a valid extension of the current blockchain, and define an ordering on blocks to arbitrate between concurrent extensions. + +Validity conditions are implemented in the ``apply`` function which is called +whenever the node processes a block. The ``apply`` function takes as arguments a +*context* and a block. The context represents the *protocol state* and is +therefore protocol specific. The context may contain, for instance, a list of +accounts and their balances. More generally, the context must provide enough +information to determine the validity of a block. Given a context and a block, +the ``apply`` function returns the updated context if the block is valid and has +a higher :ref:`fitness`. The fitness determines a total ordering between blocks. + +.. _shell_proto_interact_012: + +Shell-protocol interaction +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:doc:`Recall<../shell/the_big_picture>` that the economic protocol and the shell interact in order to ensure that the blocks being appended to the blockchain are valid. There are mainly two rules that the shell uses when receiving a new block: + +- The shell does not accept a branch whose fork point is in a cycle more than ``PRESERVED_CYCLES`` in the past. More precisely, if ``n`` is the current cycle, :ref:`the last allowed fork point` is the first level of cycle ``n-PRESERVED_CYCLES``. The parameter ``PRESERVED_CYCLES`` therefore plays a central role in Tezos: any block before the last allowed fork level is immutable. +- The shell changes the head of the chain to this new block only if the block is :doc:`valid<../shell/validation>` and has a higher fitness than the current head; a block is valid if the operations it includes are valid. + + +Blocks +~~~~~~ + +A block consists of a header and operations. A block's header is +composed of two parts: :ref:`the protocol-agnostic part` +and :ref:`the protocol-specific part`. +This separation enables the shell to interact with different +protocols. + +Operations +~~~~~~~~~~ + +The different kinds of operations are grouped in classes, such that operations belonging to different classes may be validated independently, and/or with different priorities. +Each class has an associated index, called a :ref:`validation pass`. +There are four classes of operations: :doc:`consensus ` operations, :doc:`voting ` operations, anonymous operations, manager operations. + +Consensus operations are endorsements, while `voting ` operations are ballot and proposal. + +Anonymous operations are operations which are not signed. There are three anonymous operations: seed nonce revelation, double baking evidence, and double endorsing evidence. The evidence for double baking and double endorsing is included in a block by the so-called accuser (see :ref:`slashing`). + +Manager operations are activation, origination (see :doc:`smart contracts`), transaction, reveal, and delegation (see :doc:`proof of stake `). Manager operations are the only fee-paying operations. + +Recall that users have associated :ref:`accounts ` which they activate before being able to participate. By means of the operation :ref:`origination`, accounts can be further associated with smart contracts in which they are called :ref:`originated accounts`. :ref:`Transactions` are used to either transfer tez between two accounts or run the code of a smart contract. Transactions are signed by an account's private key. Before making a transaction, a user must reveal her public key so that other users (not being aware of this public key) can effectively check the signature of the transaction. + +Manager operations can be grouped into batches forming a so-called group operation. A group operation satisfies: + +- atomicity: either all the operations in the batch succeed or none is applied +- efficiency: the whole batch is signed only once (by the same implicit account), thus it is much more efficient to check, and it requires much less gas +- usability: the batch only increments the counter of the signer account by one; for this reason it is easier for tools to provide sending several operations per block using operation batches than tracking counter changes. + +The list of operations can be obtained with :ref:`this rpc `. + +See also +~~~~~~~~ + +An in-depth description of the inners of a protocol can be found in the blog +post `How to write a Tezos protocol +`_. diff --git a/docs/012/sapling.rst b/docs/012/sapling.rst new file mode 100644 index 000000000000..86ee0e7da81a --- /dev/null +++ b/docs/012/sapling.rst @@ -0,0 +1,496 @@ +**The features described in this page are experimental and have not undergone any security review.** + +Sapling integration +=================== + +Sapling is a protocol enabling privacy-preserving transactions of fungible +tokens in a decentralised +environment. It was designed and implemented by the Electric Coin +Company as the last iteration over a series of previous protocols and +academic works starting with the `Zerocoin seminal +paper `_. + +The reference implementation of Sapling, +`librustzcash `_, was +integrated in the Tezos codebase during 2019. It will be proposed as +part of a protocol amendment during 2020. + +Librustzcash and the Tezos integration implement the protocol +described in this `specification +`_, version 2020.1.0. + + +Sapling +------- + +Keys +~~~~ + +Sapling offers a rich set of keys, each allowing different operations. +A `spending key` allows to spend tokens so if it is lost or +compromised the tokens could remain locked or be stolen. +From a spending key it is possible to derive a corresponding `viewing +key` which allows to view all incoming and outgoing transactions. +The viewing key allows the owner of the tokens to check their balance +and transaction history so if compromised there is a complete loss of +privacy. +On the other hand a viewing key can willingly be shared with a third +party, for example with an auditor for regulatory compliance purposes. + +A viewing key can also derive several diversified `addresses`. +An address can be used to receive funds, much like the address of an +implicit account. + +Additionally `proving keys` can be used to allow the creation of proofs, +thus revealing private information, without being able to spend funds. +They are useful for example in case the spending key is stored in a +hardware wallet but we'd like to use our laptop to craft the +transaction and produce the zero-knowledge proofs, which are +computationally too intensive for an embedded device. + +More details can be found in the `specification document +`_. + +Shielded transactions +~~~~~~~~~~~~~~~~~~~~~ + +Transactions use Bitcoin's UTXO model with the important difference that each +input and output, instead of containing an amount and an address, +are just cryptographic `commitments`. +In order to avoid double spends, it's important to be able to check +that a commitment has not already been spent. In Bitcoin we just need to +check if an output is also later used as an input to verify if it's +already spent. In Sapling however we can't know because inputs are not +linked to outputs. +For this reason for each input of a transaction, the owner must also +publish a `nullifier`, which invalidates it. The nullifier can only be +produced by the owner of a commitment and it's deterministic so that +everybody can check that it hasn't been already published. +Note however that it is not possible to infer which commitment has +been nullified. +Transactions of this form are privacy preserving and are referred to +as `shielded`, because they reveal neither the amount, the sender nor +the receiver. + +The existing set of transactions is referred to as the `shielded pool`. +Unlike Bitcoin, where everybody can compute the set of unspent +outputs of every user, in Sapling only the owner of a viewing key can +find their outputs and verify that they are not already spent. +For this reason, to an external +observer, the shielded pool is always increasing in size and the more +transactions are added the harder it is to pinpoint the commitments +belonging to a user. + +When we spend a commitment there is some additional information that +we need to transmit to the recipient in order for them to spend the +corresponding output. +This data is encrypted under a symmetric key resulting from a +Diffie-Hellman key exchange using the recipient address and an +ephemeral key. +In principle this `ciphertext` can be transmitted off-chain as it's +not needed to verify the integrity of the pool. For convenience, in +Tezos, it is stored together with the commitment and the nullifier on +chain. + +For reasons of efficiency the commitments are stored in an incremental +`Merkle tree `_ which +allows for compact proofs of membership. The root of the tree is all +that is needed to refer to a certain state of the shielded pool. + +In order to ensure the correctness of a transaction, given that there +is information that we wish to remain secret, the spender must also +generate proofs that various good properties are true. +Thanks to the use of `SNARKs `_ +these proofs are very succinct in size, fast to verify and they don't +reveal any private information. + +This model of transaction adapts elegantly to the case when we need to +mint or burn tokens, which is needed to shield or unshield from a +transparent token. +It suffices to add more values in the outputs than in the inputs +to mint and to have more in inputs than outputs to burn. + +Privacy guarantees +~~~~~~~~~~~~~~~~~~ + +We explained that the shielded pool contains one commitment for each +input (spent or not), and one nullifier for each spent input. +These cryptographic commitments hide the amount and the owner of the +tokens they represent. +Additionally commitments are unlinkable meaning that we can not deduce +which input is spent to create an output. + +It should be noted that the number of inputs and outputs of a +transaction is public, which could help link a class of +transactions. This problem can be mitigated by adding any number of +dummy inputs or outputs at the cost of wasting some space. + +The shielded pool communicates with the public ledger by minting and +burning shielded tokens in exchange for public coins. +Therefore going in and out of the shielded pool is public: we know +which address shielded or unshielded and how much. +We can among other things infer the total number of shielded coins. + +Timing and network information can also help to deduce some private +information. +For example by observing the gossip network we might learn the IP +address of somebody that is submitting a shielded transaction. +This can be mitigated by using `TOR +`_. + +Good practices +~~~~~~~~~~~~~~ + +When blending in a group of people, one should always pay attention to +the size and the variety of the group. + +We recommend two good practices. First, do not originate a second +contract if another one has the same functionalities, it will split +the anonymity set. + +Second, remember that shielding and unshielding are public operations. +A typical anti-pattern is to shield from tz1-alice 15.3 tez, and then +unshield 15.3 tez to tz1-bob. It's fairly clear from timing and +amounts that Alice transferred 15.3 tez to Bob. +To decorrelate the two transfers it is important to change the +amounts, let some time pass between the two and perform the +transactions when there is traffic in the pool. +Similar problems exist in Zcash and they are illustrated in this +introductory `blog post +`_. + +There are a number of more sophisticated techniques to deanonymise +users using timing of operations, network monitoring, side-channels on +clients and analysis of number of inputs/outputs just to mention a few +(`A fistful of Bitcoins +`_ is a good +first read). +We advice users to be familiar with the use of the TOR network and to +use clients developed specifically to protect their privacy. + + +Tezos integration +----------------- + +Michelson: verify update +~~~~~~~~~~~~~~~~~~~~~~~~ + +We introduce two new Michelson types `sapling_state` and +`sapling_transaction`, and two instructions called +`SAPLING_VERIFY_UPDATE` and `SAPLING_EMPTY_STATE` +(see the :doc:`Michelson reference` +for more details). +`SAPLING_EMPTY_STATE` pushes an empty `sapling_state` on the stack. +`SAPLING_VERIFY_UPDATE` takes a transaction and a state and returns an +option type which is Some (updated +state and a balance) if the transaction is correct, None otherwise. +A transaction has a list of inputs, outputs, a signature, a balance, +and the root of the Merkle tree containing its inputs. +The verification part checks the zero-knowledge proofs of all inputs +and outputs of the transaction, which guarantee several properties of +correctness. +It also checks a (randomised) signature associated with each input +(which guarantees that the owner forged the transaction), and the +signature that binds the whole transaction together and guarantees the +correctness of the balance. +All the signatures are over the hash of the data that we wish to sign +and the hash function used is Blake2-b, prefixed with the anti-replay string. +The anti-replay string is the the concatenation of the chain id and +the smart contract address. The same string has to be used by the client for +signing. + +Verify_update also checks that the root of the Merkle tree appears in +one of the past states and that the nullifiers are not already +present (i.e. no double spending is happening). +If one of the checks fails the instruction returns None. + +Otherwise the function adds to the new state the nullifiers given with each inputs +and adds the outputs to the Merkle tree, which will produce a new root. +It should be noted that it is possible to generate transactions +referring to an old root, as long as the inputs used were present in +the Merkle tree with that root and were not spent after. +In particular the protocol keeps 120 previous roots and guarantees +that roots are updated only once per block. +Considering 1 block per minute and that each block contains at least +one call to the same contract, a client has 2 hours to have its +transaction accepted before it is considered invalid. + +The nullifiers are stored in a set. The ciphertexts and other relevant +information linked to the commitment of the Merkle tree are +stored in a map indexed by the position of the commitment in the +Merkle tree. + +Lastly the instruction pushes the updated state and the balance as an option +on the stack. + +Example contracts +~~~~~~~~~~~~~~~~~ + +Shielded tez +^^^^^^^^^^^^ + +An example contract to have a shielded tez with a 1 to 1 conversion to +tez is available in the tests of `lib_sapling`. + +Simple Vote Contract +^^^^^^^^^^^^^^^^^^^^ + +One might think to use Sapling to do private voting. +It is possible to adapt shielded transactions to express preferences. +**Note that this is not what Sapling is designed for and it doesn't provide the same properties as an actual private voting protocol.** +A natural naive idea is the following. +Suppose we want a set of users to express a preference for option A or +B, we can generate two Sapling keys with two addresses that are +published and represent the two options. +The contract lets each user create a token which represents one vote +that can then be transferred to address A or B. +Using the published viewing keys everyone can check the outcome of the +vote. +**However note that a transaction can be replayed and we can see the balance of A or B going up. +This system does not offer ballot privacy. +Therefore one should ensure that the vote he is casting cannot be linked to him. +It is possible that the practical situation makes this usable but we recommend in general not to use +it for any important vote.** +Note that using a random elliptic curve element as incoming viewing key allows to generate a +dummy address that cannot be spent. This eases the counting of the votes. +To ensure that the ivk does not correspond to a normal address with spending key, one +can use the Fiat-Shamir heuristic. + + +Fees issue +~~~~~~~~~~ + +We have an additional privacy issue that Z-cash doesn't have. When +interacting with a shielded pool we interact with a smart contract +with a normal transaction and therefore have to pay fees from an +implicit account. +One could guess that private transactions whose fees are paid by the +same implicit account are from the same user. +This can be mitigated by making a service that act as a proxy by +forwarding the user transactions and paying it fees. The user would +then include in the transaction a shielded output for the service that +covers the fees plus a small bonus to pay the service. +This output can be open by the service before sending the transaction +to check that there is enough money to cover its fees. As for Z-cash, +users interacting with the proxy should use TOR or mitigate network +analysis as they wish. + +Gas, storage and costs +~~~~~~~~~~~~~~~~~~~~~~ + +Gas evaluation is not yet done. + +RPCs +~~~~ + +There are two Sapling RPCs under the prefix `context/sapling`. +`get_size` returns a pair with the size of the set of commitments +and the size of the set of nullifiers. +`get_diff` takes two optional starting offsets `cm_from` and `nf_from` +and returns the sapling state that was added from the offsets to the +current size. In particular it returns three lists, commitments, +ciphertexts from position `cm_from` up to the last one added and +nullifiers, from `nf_from` to the last one added. +Additionally it returns the last computed root of the merkle tree so +that a client updating its tree using the diff can verify the +correctness of the result. + +Client +~~~~~~ + +Wallet +^^^^^^ + +tezos-client supports Sapling keys and can send +shielded transactions to smart contracts. + +The client supports two ways to generate a new Sapling spending key. +It can be generated from a mnemonic using `BIP39 +`_, so +that it can be recovered in case of loss using the mnemonic. +Alternatively it is possible to derive new keys from existing ones +using `ZIP32 +`_, a Sapling +variant of `BIP32 +`_ for +hierarchical deterministic wallets. As usual, in this case it is +important to note the derivation path of the key to be able to recover +it in case of loss. +At the moment there is no hardware wallet support, keys are stored in +`~/.tezos-client/sapling_keys` by default encrypted with a password. +**Users should take care to backup this file.** + +The client can also derive addresses from viewing keys. +By default addresses are generated using an increasing counter called +the address index. Not all indexes correspond to valid addresses for +each key so it is normal to see an increasing counter that +occasionally skips a few positions. + +Because for now the only support for Sapling keys is to interact with +smart contracts, the client binds each newly generated key to a +specific smart contract address. + +Operations +^^^^^^^^^^ + +The client also facilitates the creation of shielded transactions and +their transfer as arguments of smart contracts. +For now there is seamless integration to send transactions to the +reference shielded-tez contract and we are planning to support a +larger class of contracts. + +For the shielded-tez smart contract, the client supports shielding, +unshielding and shielded transactions. +In the case of shielded transactions there are two commands, one to +forge a transaction and save it to file and one to submit it to the +smart contract. +The idea is that a user should not use their own transparent tz{1,2,3} +address to submit a shielded address but rather have a third party +inject it. + +Message argument +^^^^^^^^^^^^^^^^ +Sapling also allows to send an arbitrary encrypted message attached +to an output. +The message size has to be fixed by pool for privacy reasons. +For now it is fixed overall at eight bytes. An incorrect message length +will raise a failure in our client and the protocol will reject the +transaction. Our client adds a default zero's filled message of the +right length. If a message is provided with the --message option, +the client will pad it or truncate it if necessary. A warning message +is printed only if the user's message is truncated. + + +Code base +~~~~~~~~~ + +The current code-base is organized in three main components. +There is a core library called `lib_sapling` which binds `librustzcash`, +adds all the data structures necessary to run the sapling +protocol and includes a simple client and baker. +Under the protocol directory there is a `lib_client_sapling` library +which implements a full client capable of handling Sapling keys and +forging transactions. +Lastly in the protocol there is a efficient implementation of the +Sapling storage, in the spirit of `big_map`s, and the integration of +`SAPLING_VERIFY_UPDATE` in the Michelson interpreter. + +Protocol +^^^^^^^^ + +In order to export the Sapling library to the protocol we first need +to expose it through the environment that sandboxes the protocol. +The changes under `src/lib_protocol_environment` are simple but very +relevant as any change of the environment requires a manual update of the +Tezos node. These changes are part of version V1 of the environment +while protocols 000 to 006 depends on version V0. + +There are two main changes to Tezos' economic protocol, the storage +for Sapling and the addition of `SAPLING_VERIFY_UPDATE` to the Michelson +interpreter. + +Given that the storage of a Sapling contract can be substantially +large, it is important to provide an efficient implementation. +Similarly to what it's done for big_maps, the storage of Sapling can't +be entirely deserialized and modified in memory but only a diff of the +changes is kept by the interpreter and applied at the end of each +smart contract call. + +In the Michelson interpreter two new types are added, `sapling_state` and +`sapling_transaction`, and the instruction `SAPLING_VERIFY_UPDATE`. + +Client +^^^^^^ + +Under `lib_client_sapling` there is the client integration +with the support for Sapling keys and forging of transactions. +The main difference from the existing Tezos client is the need for the +Sapling client to keep an additional state, for each contract. +Because Sapling uses a UTXO model it is necessary for a client to +compute the set of unspent outputs in order to forge new transactions. +Computing this set requires scanning all the state of a contract which +can be expensive. +For this reason the client keeps a local state of the unspent outputs +after the last synchronization and updates it before performing any +Sapling command. +The update is done using the RPCs to recover the new updates since the +last known position. + +The state of all sapling contracts is stored in +`~/.tezos-client/sapling_states`. This file can be regenerated from +the chain in case of loss. However disclosure of this file will reveal +the balance and the unspent outputs of all viewing keys. + +Memo +^^^^^^ + +Sapling offers the possibility to add an arbitrary memo to any +created output. The memo is encrypted and available to anyone +owning the outgoing viewing key or the spending key. +For privacy reasons the size of the memo is fixed per contract +and it is chosen at origination time. +A transaction containing an output with a different memo-size +will be rejected. + +Sandbox tutorial +~~~~~~~~~~~~~~~~ + +As usual it's possible to test the system end-to-end using the +:doc:`../user/sandbox`. +After having set up the sandbox and originated the contract, a good +way to get familiar with the system is to generate keys and then +perform the full cycle of shielding, shielded transfer and +unshielding. + +:: + + # set up the sandbox + ./src/bin_node/tezos-sandboxed-node.sh 1 --connections 0 & + eval `./src/bin_client/tezos-init-sandboxed-client.sh 1` + tezos-activate-alpha + + # originate the contract with its initial empty sapling storage, + # bake a block to include it. + # { } represents an empty Sapling state. + tezos-client originate contract shielded-tez transferring 0 from bootstrap1 \ + running src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract.tz \ + --init '{ }' --burn-cap 3 & + tezos-client bake for bootstrap1 + + # as usual you can check the tezos-client manual + tezos-client sapling man + + # generate two shielded keys for Alice and Bob and use them for the shielded-tez contract + # the memo size has to be indicated + tezos-client sapling gen key alice + tezos-client sapling use key alice for contract shielded-tez --memo-size 8 + tezos-client sapling gen key bob + tezos-client sapling use key bob for contract shielded-tez --memo-size 8 + + # generate an address for Alice to receive shielded tokens. + tezos-client sapling gen address alice + zet1AliceXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Alice's address + + + # shield 10 tez from bootstrap1 to alice + tezos-client sapling shield 10 from bootstrap1 to zet1AliceXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX using shielded-tez --burn-cap 2 & + tezos-client bake for bootstrap1 + tezos-client sapling get balance for alice in contract shielded-tez + + # generate an address for Bob to receive shielded tokens. + tezos-client sapling gen address bob + zet1BobXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Bob's address + + # forge a shielded transaction from alice to bob that is saved to a file + tezos-client sapling forge transaction 10 from alice to zet1BobXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX using shielded-tez + + # submit the shielded transaction from any transparent account + tezos-client sapling submit sapling_transaction from bootstrap2 using shielded-tez --burn-cap 1 & + tezos-client bake for bootstrap1 + tezos-client sapling get balance for bob in contract shielded-tez + + # unshield from bob to any transparent account + tezos-client sapling unshield 10 from bob to bootstrap1 using shielded-tez --burn-cap 1 + ctrl+z # to put the process in background + tezos-client bake for bootstrap1 + fg # to put resume the transfer diff --git a/docs/012/timelock.rst b/docs/012/timelock.rst new file mode 100644 index 000000000000..9083bfa1c44e --- /dev/null +++ b/docs/012/timelock.rst @@ -0,0 +1,129 @@ +Time locked Michelson against Block Producer Extractable Value +============================================================== + + +Block Producer Extractable Value +-------------------------------- + +We aim at tackling the issue known through +the unfortunate misnomer of "generalized front running", described +for instance in `here `__. + +Observing a transaction before it is actually included in the chain +can give an advantage to a trader against another one. Ultimately, +this means block producers can extract a rent from the system +as they have the ability to choose and order transactions in a block. +This is sometimes referred to, in proof-of-work networks like Ethereum as +`Miner Extractable Value `_ or MEV for shorts. +We refer to it as BPEV, for "Block producer extractable value" +or "Baker pecuniary extractable value", at the reader's preference. +We also note that the term "front-running" is regrettable as it can mislead people +into thinking there is a fiduciary relationship between block producers +and transaction emitters where, in fact, none exists unless explicitly contracted into. + +For example, upon receiving a transaction, a baker could craft a block including +this transaction and one of his such that the sequential execution of these +two transactions guarantees a gain to the baker. + +Timelock +-------- + +We propose a solution to alleviate this issue which is relatively easy to implement +and is based on time lock encryption +(see +`Timelock puzzles and timed release Crypto `_ +for more details). + +Time lock encryption allows to encrypt a message such that it can be +decrypted in two ways. +Either the author of the ciphertext produces a plaintext +(and a proof of correct decryption) +by providing a secret trapdoor (the factorization of an RSA modulus in our case). +Otherwise a sequential computation can decrypt the ciphertext after a computation +requiring ``T`` sequential operations (modular squaring in our case), +for some pre-determined constant ``T``. + +In addition, a proof of the correctness of the decryption can also be produced and checked in sub linear time (``log T`` in our case). + +By experimentally measuring the time the sequential operation takes +on available hardware using optimized implementation, we can estimate +a rough conversion (or a bound in our case) between the constant ``T`` and +wall clock time. +We also note that the `VDF alliance `_ has been working on producing an ASIC for squaring in an RSA group to +ensure a level playing field in terms of computational speed. + +An implementation of the timelock puzzle +and proof scheme is available in :src:`src/lib_crypto/timelock.mli` inspired from +a proof of concept available +`here `__. + +General principle +----------------- + +To limit BPEV, we introduce in Michelson an opcode (``OPEN_CHEST``) and two types (``chest`` and ``chest_key``) allowing +timelock-encrypted values to be used inside a Michelson contract. + +The typical usage pattern would be as follows: + +1. In a first period, a contract collects user-submitted and timelock encrypted Michelson values along with some valuable deposit, such as tez. +2. In a second period, after the values are collected, the contract collects from users a decryption of the value they submitted alongside with a proof that the decryption is correct. +3. In a third period, if any value remains undecrypted, anyone can claim part of the deposit by submitting a decryption of the value, with the other part of the deposit being burnt. Different penalties can be assessed depending on whether the user merely failed to submit a decryption for their value, or if they also intentionally encrypted invalid data. Different rewards can be distributed for submitting a correct decryption. The third period needs to be long enough so that people have enough time to perform the timelock decryption. +4. Finally, the contract can compute some function of all the decrypted data. + +There is generally no incentive for users not to provide +the decryption of their data and thus the third period generally does not need +to take place. However, the second period needs to be long enough so that bakers +cannot easily censor submission of the decryption in a bid to later claim the reward. +Burning a part of the deposit also limits grieving attacks where a user gets back +their whole deposit by providing the decryption, but in a way that delays everyone else. + +Cryptographic principles +------------------------ + +Users first generate a RSA modulus and a symmetric encryption key. +They use authenticated encryption to encrypt a packed Michelson value (an array of bytes computed with ``PACK``) +and encrypt that encryption key using a timelock puzzle. +They then combine the RSA modulus, the timelocked symmetric key, the constant ``T`` +and the encrypted value as a single value as well (called chest in our library in :src:`src/lib_crypto`). + +A proof of decryption can be the symmetric key itself. +However, a malicious user could propose an authenticated ciphertext that does yield a valid value +even when decrypted with the symmetric key that was indeed time locked. +To avoid this threat, an opening (called +the chest_key in our library) includes the symmetric key and +a proof that the symmetric key proposed is indeed the one hidden in the timelock puzzle. +In this way we can differentiate whether the chest or the chest key was proposed by a +malicious user. + +Finally, our library exposes an ``open_chest`` function taking a chest, a chest key and +produces either the underlying plaintext or indicates that the chest or the chest key is +malicious. + +Proposed opcode and types +--------------------------- + +To expose the features added by our library, we introduce the following Michelson types: + +- ``chest``, which represents timelocked arbitrary bytes with the + necessary public parameters to open it. +- ``chest_key``, which represents the decryption key, + alongside with a proof that the key is correct. + +and the following opcode: + +``unlock :: chest_key → chest → time →or (bytes, bool)`` + +If everything is correct it pushes +``Left bytes`` on top of the stack where bytes are +cryptographically guaranteed to be the bytes the chest provider timelocked. +If the ciphertext does not decrypt under the symmetric key that was timelocked, it pushes on the stack +``Right False`` +If the provided symmetric key was not the one timelocked +(which we detect thanks to the timelock proof), +it pushes on the stack ``Right True``. +Note that we are using an authenticated encryption scheme, +so we can detect if someone provides a wrong key while fooling the time lock proof. +This is doable only by someone knowing the factorisation of the RSA modulus. +However, this cannot prevent someone from encrypting a wrong key, or putting +a wrong message authentication code, +so this is why we still need the proof of correctness. diff --git a/docs/012/voting.rst b/docs/012/voting.rst new file mode 100644 index 000000000000..b75bf0bd5867 --- /dev/null +++ b/docs/012/voting.rst @@ -0,0 +1,331 @@ +The Amendment (and Voting) Process +================================== + +In the Tezos blockchain, the *economic protocol* can be amended. Specifically, +there is an on-chain mechanism to propose changes to the economic protocol, to +vote for-or-against these proposed changes, and, depending on the result of the +vote, to activate these changes or not. + +Note that the proposal, voting and activation processes are part of the economic +protocol itself. Consequently the amendment rules themselves are subject to +amendments. + +The rest of this page gives more details about the amendment and voting process. + +Periods +------- + +The amendment process consists of five *periods*. Each period lasts for 40960 +blocks (5 cycles) (or approximately two weeks). The periods (listed below) +typically succeed one another for a total duration of approximately 2 months and +a half, after which the whole amendment process starts again. + +The five periods are as follows: + +- *Proposal period*: During this period, delegates can + + - submit *protocol amendment proposals* (or, simply, *proposals*) using the + ``Proposals`` operation (see below), + - support a proposal using the ``Ballot`` operation (see below). + + Each delegate can submit a maximum of 20 proposals. Duplicates count towards + this total. + + At the end of a **proposal period**, the proposal with most support is + selected and we move to an **exploration period**. Note that support is + measured in the cumulated number of :ref:`rolls ` that delegates supporting the + proposal have. E.g., a proposal supported by a single delegate with 100 rolls + has more support than a proposal supported by two delegates with 20 rolls + each. + + If there are no proposals, or a tie between two or more proposals, the process + moves back to a new **proposal period**. + +- *Exploration period*: During this period delegates can cast one + Yay, Nay, or Pass ballot on the selected proposal. They do so using the + ``Ballot`` operation. + + If the voting participation reaches *quorum* and there is a *super-majority* + of Yay, the process moves to the **cooldown period**. (See below for details + on participation, quorum, and super-majority.) + + Otherwise the process moves back to the **proposal period**. + +- *Cooldown period*: On-chain nothing specific happens during this period. + Off-chain the delegates can read the proposal with more scrutiny, the + community can discuss finer points of the proposal, the developers can + perform additional tests, etc. + + At the end of this period, the process moves to the **promotion period**. + +- *Promotion period*: During this period, delegates can cast a Yay, Nay, or Pass + ballots using the ``Ballot`` operation. + + If the voting participation reaches *quorum* and there is a super-majority of + Yay, the process moves to the **adoption period**. + + Otherwise the process moves back to the **proposal period**. + +- *Adoption period*: On-chain nothing specific happens during this period except + on the very last block (see below). + + Off-chain the developers release tools that include support for the + soon-to-be activated protocol, other actors (bakers, indexers, etc.) update + their infrastructure to support the newly released tools, smart-contract + developers start working with soon-to-be-available features, etc. + + At the very end of the period, the proposal is *activated*. This means that + the last block of the period is still interpreted by the current economic + protocol, but the first block after the period is interpreted by the new + economic protocol (the one that was voted in). + + And a new **proposal period** starts. + + +Activation +---------- + +After the activation step, the blocks added to the chain are interpreted in the +newly activated protocol. As a result gas costs may differ, new operations may +be available, contracts using new opcodes may be injected, etc. + +Because the amendment process is also part of the economic protocol, the +amendment process now unfolds according to the rules of the newly activated +protocol. As a result the periods may be lengthened or shortened, a new period +might be introduced, a different selection mechanism may be used, the quorum +requirement might differ, etc. + + +Voting Power +------------ + +When supporting a proposal or casting a Yay, Nay, or Pass ballot, each delegate +has voting power equal to its *stake*. The stake is always measured in +**number of rolls**. + +Note that the stake of each delegate is computed at the beginning of each +period. + + +Super-majority and Quorum +------------------------- + +As mentioned above, during either of the **proposal** or **promotion** periods, +delegates can cast ballots using the ``Ballot`` operation (see below). +In both cases, delegates can cast a single Yay, Nay, or Pass ballot. A ballot +has a weight equal to the delegate's stake as detailed above. + +For either of these two periods, the process continues to the next period if the +*vote participation* reaches *quorum* and there is a *super-majority* of +Yay. + +The *vote participation* is the ratio of all the cumulated stake of cast ballots +(including Pass ballots) to the total stake. + +For the first voting period, the *quorum* started at 80% of stake. The quorum is +adjusted after each vote as detailed below. This adjustment is necessary to +ensure that the amendment process can continue even if some delegates stop +participating. After each vote the new quorum is updated based on the old quorum +and the **vote participation** with the following coefficients:: + + new-quorum = 0.8 × old-quorum + 0.2 × participation + +The *super-majority* is reached if the cumulated stake of Yay ballots is +greater than 8/10 of the cumulated stake of Yay and Nay ballots. + +Note that Pass ballots do not count towards or against the super-majority; +they still counts towards participation and quorum. + +More details can be found in the file +:src:`src/proto_012_PsiThaCa/lib_protocol/amendment.ml`. + + +The Hash and the Protocol +------------------------- + +On the one hand, the voting part of the process revolves around the +**hash of a protocol**. Specifically, a delegate submits a hash of a +protocol, and all the delegates cast ballots on the proposed hash. +The *hash of a protocol* is the hash of the files that constitute the source +code of the protocol. + +On the other hand, the **protocol activation** (at the end of the +**adoption period**) revolves around the compiled sources of the protocol. + +Basically, the voting process works on an identifier of the protocol whilst the +activation step works on the protocol itself. Consequently, if a protocol hash +is voted in and the protocol it identifies is invalid, the activation step +fails. + +.. sidebar:: Checking a hash is of a valid protocol + + When a hash is proposed by a delegate, it is usually accompanied by some + blogposts and forum threads on :ref:`community websites `. + These should include directions for testing the proposed protocols. If you + cannot find such directions, do not hesitate to ask. + +.. sidebar:: Localised failures + + It is possible that the activation step fails on a single node or a few nodes + of the network, but succeed on the others. In this case the nodes with the + failure are stuck, but the network as a whole continues. + + The most likely cause for this is nodes that have not been updated and do not + include a new protocol environment version. + + If your node becomes stuck, you should start a fresh up-to-date node. + +A protocol is *invalid* if its code cannot be compiled (e.g., if the code is not +valid source code), if its code uses functions not present in the +:doc:`protocol environment <../developer/protocol_environment>`, or if it +downgrades the protocol environment version. + +If an invalid protocol is voted in, then the activation fails for all the nodes, +and then the chain becomes stuck. This is why it is important to vote for hashes +that designate valid protocols: ones with sources that are available and that +can be compiled. + +Operations +---------- + +There are two operations used by the delegates: **proposals** and **ballot**. + +A *proposals* operation can only be injected during a proposal period. + +:: + + Proposals : { + source: Signature.Public_key_hash.t ; + period: Voting_period_repr.t ; + proposals: Protocol_hash.t list ; } + +The ``source`` is the public key hash of the delegate, ``period`` is the unique +identifier of each voting period and ``proposals`` is a non-empty list of +maximum 20 protocol hashes. +The operation can be submitted more than once but only as long as the +cumulative length of the proposals lists is less than 20. +Duplicate proposals from the same delegate are accounted for in the +maximum number of proposals for that delegate. +However duplicates from the same delegate are not tallied at the end +of the proposal period. + +For example, a delegate submits a *proposals* operation for protocols A +and B early in the proposal period, later a new protocol C is revealed +and the delegate submits another *proposals* operation for protocols B +and C. +The list of submissions that will be tallied is [A,B,C]. + +A *ballot* operation can only be submitted during one of the voting +periods, and only once per period. + +:: + + Ballot : { + source: Signature.Public_key_hash.t ; + period: Voting_period_repr.t ; + proposal: Protocol_hash.t ; + ballot: Vote_repr.ballot ; } + +The fields ``source`` and ``period`` are the same as above, while ``proposal`` +is the currently selected proposal and ``ballot`` is one of ``Yay``, ``Nay`` or +``Pass``. +The ``Pass`` vote allows a delegate to contribute towards the quorum without +contributing towards the super-majority. This is important because, as detailed +above, the quorum is adaptive and that low participation would lower the +quorum of the next vote. + +More details on the operations can be found in +:src:`src/proto_012_PsiThaCa/lib_protocol/operation_repr.ml`. +The binary format is described by +``tezos-client describe unsigned operation``. + +Client Commands +--------------- + +The Octez client, ``tezos-client``, provides commands for basic exploration and +interaction with the amendment and voting process. + + +Show +~~~~ + +Tezos' client provides a command to show the status of a voting period. +It displays different information for different kind of periods, as +in the following samples:: + + $ tezos-client show voting period + Current period: "proposal" + Blocks remaining until end of period: 59 + Current proposals: + PsNa6jTtsRfbGaNSoYXNTNM5A7c3Lji22Yf2ZhpFUjQFC17iZVp 400 + + $ tezos-client show voting period + Current period: "exploration" + Blocks remaining until end of period: 63 + Current proposal: PsNa6jTtsRfbGaNSoYXNTNM5A7c3Lji22Yf2ZhpFUjQFC17iZVp + Ballots: { "yay": 400, "nay": 0, "pass": 0 } + Current participation 20.00%, necessary quorum 80.00% + Current in favor 400, needed supermajority 320 + + $ tezos-client show voting period + Current period: "cooldown" + Blocks remaining until end of period: 64 + Current proposal: PsNa6jTtsRfbGaNSoYXNTNM5A7c3Lji22Yf2ZhpFUjQFC17iZVp + +It should be noted that the ballot number 400 above is the stake counted in +number of rolls. +The proposal has a total stake of 400 rolls, which may come from a single ballot +from a delegate having 400 rolls, or it may come from multiple ballots from +delegates with a combined stake of 400 rolls. + + +Submit proposals +~~~~~~~~~~~~~~~~ + +During a proposal period, a list of proposals can be submitted with:: + + tezos-client submit proposals for ... + +Remember that each delegate can submit a maximum of 20 protocol +hashes and that duplicates count towards this total. +Moreover each proposal is accepted only if it meets one of the +following two conditions: + +- the protocol hash was already proposed on the network. In this case + we can submit an additional proposal that "upvotes" an existing one + and our rolls are added to the ones already supporting the proposal. +- the protocol is known by the node. In particular the first proposer + of a protocol should be able to successfully inject the protocol in + its node which performs some checks, compiles and loads the + protocol. + +These are protection measures that the Octez client takes to prevent the +accidental injection of invalid protocols. As mentioned above, it is still +important to check the validity of the protocols that you vote for as they may +have been injected via different means. + + +Submit ballots +~~~~~~~~~~~~~~ + +During either of the **exploration** or **promotion** periods, +ballots can be submitted once with:: + + tezos-client submit ballot for + +Further External Resources +-------------------------- + +Further details and explanations on the voting procedure can be found at: + +- `Governance on-chain `_ on Open Tezos +- `Tezos Governance `_ on Tezos Agora. + +For more details on the client commands refer to the manual at +:ref:`client_manual_012`. + +For vote related RPCs check the :doc:`rpc` under the prefix +``votes/``. + +For Ledger support refer to Obsidian Systems' `documentation +`__. diff --git a/docs/index.rst b/docs/index.rst index f46bdb6a9f33..b0d2a5d9c0a1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -160,6 +160,15 @@ in the :ref:`introduction `. active/cli-commands active/rpc +.. toctree:: + :maxdepth: 2 + :caption: 012 Ithaca Protocol doc: + + 012/protocol + 012/glossary + 012/cli-commands + 012/rpc + .. toctree:: :maxdepth: 2 :caption: Alpha Development Protocol doc: @@ -208,6 +217,7 @@ in the :ref:`introduction `. protocols/009_florence protocols/010_granada protocols/011_hangzhou + protocols/012_ithaca protocols/alpha .. toctree:: diff --git a/docs/protocols/012_ithaca.rst b/docs/protocols/012_ithaca.rst new file mode 100644 index 000000000000..f6e4cc5eeb34 --- /dev/null +++ b/docs/protocols/012_ithaca.rst @@ -0,0 +1,160 @@ +Protocol Alpha +============== + +This page contains all the relevant information for protocol Alpha +(see :ref:`naming_convention`). + +The code can be found in the :src:`src/proto_012_PsiThaCa` directory of the +``master`` branch of Tezos. + +This page documents the changes brought by protocol Alpha with respect +to Hangzhou. + +.. contents:: + +New Environment Version (V4) +---------------------------- + +This protocol requires a different protocol environment than Hangzhou. +It requires protocol environment V4, compared to V3 for Hangzhou. +(MRs :gl:`!3379`, :gl:`!3468`) + +- Move BLS12-381 to blst backend. (MR :gl:`!3296`) + +- Expose BLS signature module. (MR :gl:`!3470`) + +- Remove Error-monad compat layer. (MR :gl:`!3575`) + +- Allow different type of error categories in the different error monads. + (MR :gl:`!3664`) + +- Fix interface of Hex. (MR :gl:`!3267`) + +- Fix use of Micheline canonical encoding. (MR :gl:`!3764`) + +- Add concat_map. (MR :gl:`!3801`) + +- Make Micheline.canonical_location abstract. (MR :gl:`!3744`) + +- Error_monad: better tracing primitives. (MR :gl:`!3589`) + +- Error-monad: simpler trace_eval. (MR :gl:`!3869`) + +- Add missing functions from Lwtreslib. (MR :gl:`!3905`) + +- Expose an order for folding over the context. (MR :gl:`!3910`) + +Tenderbake +---------- + +- Tenderbake is a new consensus algorithm replacing Emmy* in order to provide deterministic finality. (MR :gl:`!3738`) + +- The list of breaking changes related to Tenderbake are described in a separate :doc:`change log`. + +- Further, related changes after the main MR has been merged: + + - Export participation RPC. (MR :gl:`!3822`) + + - Rename Bonds to Deposits. (MR :gl:`!3832`) + + - Fix issues related to token management in Tenderbake. (MR :gl:`!3811`) + + - Inherit block times. (MR :gl:`!3850`) + + - Address comments on Tenderbake. (MR :gl:`!3906`) + + - Small updates to the ``../delegates//..`` RPCs. (MR :gl:`!3977`) + +- Fix issues with receipts (MR :gl:`!3987`) + +Tickets Hardening +----------------- + +- Add ticket-balance storage module. (MR :gl:`!3495`) + +- Add API for scanning values for tickets. (MR :gl:`!3591`) + +- Add API for generating ticket-balance key hashes. (MR :gl:`!3788`) + +Michelson +--------- + +- A new ``SUB_MUTEZ`` instruction has been added, it is similar to the + ``mutez`` case of the ``SUB`` instruction but its return type is + ``option mutez`` instead of ``mutez``. This allows subtracting + ``mutez`` values without failing in case of underflow. (MR :gl:`!3079`) + +- The ``SUB`` instruction on type ``mutez`` is deprecated. It can be + replaced by ``SUB_MUTEZ; ASSERT_SOME`` (and ``SUB; DROP`` can be + replaced by ``ASSERT_CMPGE``). (MR :gl:`!3079`) + +- The ``MAP`` instruction can now also be applied to values of type ``option + a``. In this case the block of code given is executed if and only if the value + at the top of the stack is ``Some a``. It should map the value at the top of + the stack into a value of any type ``b``. The block has access to the + remainder of the stack also, but its type should remain unchanged. The result + of the instruction is the stack returned by the applied block of code, where + the value at the top is wrapped in ``Some`` again. If the value at the top of + input stack is ``None``, the instruction does nothing. (MR :gl:`!3574`) + +Precheck of operations +---------------------- + +- Expose `precheck_manager` and `check_manager_signature` (MR :gl:`!3872`) + +- Remove the gas block limit for prevalidator mode. (MR :gl:`!3802`) + +Bug Fixes +--------- + +- Use Cache_costs.cache_find in cache find. (MR :gl:`!3752`) + +- Fix gas accounting for the deserialization of Michelson arguments in + operations. (MR :gl:`!3930`) + +Minor Changes +------------- + +- Update and simplify fixed constants. (MR :gl:`!3454`) + +- Simplify pack cost. (MR :gl:`!3620`) + +- Do not play with locations inside protocol. (MR :gl:`!3667`) + +- Remove the optional entrypoint in ticketer address. (MR :gl:`!3570`) + +- Make delegate optional for bootstrap contracts. (MR :gl:`!3584`) + +- Fix interface of Hex. (MR :gl:`!3267`) + +- Update migration for protocol "I". (MR :gl:`!3668`) + +- Make `max_operations_ttl` a parametric constant of the protocol, now called + `max_operations_time_to_live`. (MR :gl:`!3709`) + +- ``NOW`` and ``LEVEL`` are now passed to the Michelson interpreter as + step constants instead of being read from the context each time + these instructions are executed. (MR :gl:`!3524`) + +- The RPC ``../helpers/current_level`` does not support anymore a + negative ``offset`` argument. The level which used to be returned by + ``..//helpers/current_level?offset=-`` can still be obtained by + ``..//helpers/current_level``. (MR :gl:`!3808`) + +- Ensure annotations are non-empty. (MR :gl:`!3746`) + +- Only allow positive depth in context query RPC and other RPC. + (MR :gl:`!3564`) + +- Liquidity Baking: postpone the sunset level by 819,200 blocks and + decrease the escape hatch threshold from one half to one third. + (MR :gl:`!3911`) + +- Bump up bls12-381.1.1.0. (MRs :gl:`!3914`, :gl:`!3942`) + +- Other internal refactorings or documentation. (MRs :gl:`!3506`, :gl:`!3550`, + :gl:`!3593`, :gl:`!3552`, :gl:`!3588`, :gl:`!3612`, :gl:`!3575`, + :gl:`!3622`, :gl:`!3631`, :gl:`!3630`, :gl:`!3707`, :gl:`!3644`, + :gl:`!3529`, :gl:`!3739`, :gl:`!3741`, :gl:`!3695`, :gl:`!3763`, + :gl:`!3779`, :gl:`!3745`, :gl:`!3256`, :gl:`!3326`, :gl:`!3812`, + :gl:`!3920`, :gl:`!3929`) diff --git a/src/lib_protocol_compiler/final_protocol_versions b/src/lib_protocol_compiler/final_protocol_versions index 102e0e09a1fa..657c36b1c8a9 100644 --- a/src/lib_protocol_compiler/final_protocol_versions +++ b/src/lib_protocol_compiler/final_protocol_versions @@ -11,4 +11,5 @@ PtEdoTezd3RHSC31mpxxo1npxFjoWWcFgQtxapi51Z8TLu6v6Uq PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i PtGRANADsDU8R9daYKAgWnQYAJ64omN1o3KMGVCykShA97vQbvV -PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx \ No newline at end of file +PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx +PsiThaCaT47Zboaw71QWScM8sXeMM7bbQFncK9FLqYc6EKdpjVP \ No newline at end of file diff --git a/src/proto_012_PsiThaCa/bin_accuser/.ocamlformat b/src/proto_012_PsiThaCa/bin_accuser/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_accuser/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/bin_accuser/dune b/src/proto_012_PsiThaCa/bin_accuser/dune new file mode 100644 index 000000000000..2c93b1f051a2 --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_accuser/dune @@ -0,0 +1,20 @@ +; build static executable with --profile static +(env + (static + (flags (:standard + -ccopt -static)))) + +(executable + (name main_accuser_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-accuser-012-PsiThaCa) + (libraries tezos-client-base-unix + tezos-client-commands + tezos-baking-012-PsiThaCa-commands) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -open Tezos_client_012_PsiThaCa + -open Tezos_client_commands + -open Tezos_baking_012_PsiThaCa_commands + -open Tezos_stdlib_unix + -open Tezos_client_base_unix))) diff --git a/src/proto_012_PsiThaCa/bin_accuser/dune-project b/src/proto_012_PsiThaCa/bin_accuser/dune-project new file mode 100644 index 000000000000..97aa51842c2f --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_accuser/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-accuser-alpha) diff --git a/src/proto_012_PsiThaCa/bin_accuser/main_accuser_012_PsiThaCa.ml b/src/proto_012_PsiThaCa/bin_accuser/main_accuser_012_PsiThaCa.ml new file mode 100644 index 000000000000..2b995988014a --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_accuser/main_accuser_012_PsiThaCa.ml @@ -0,0 +1,38 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let () = + Client_commands.register Protocol.hash @@ fun _network -> + List.map (Clic.map_command (new Protocol_client_context.wrap_full)) + @@ Baking_commands.accuser_commands () + +let select_commands _ _ = + return + (List.map + (Clic.map_command (new Protocol_client_context.wrap_full)) + (Baking_commands.accuser_commands ())) + +let () = Client_main_run.run (module Daemon_config) ~select_commands diff --git a/src/proto_012_PsiThaCa/bin_accuser/tezos-accuser-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/bin_accuser/tezos-accuser-012-PsiThaCa.opam new file mode 100644 index 000000000000..af2698e09813 --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_accuser/tezos-accuser-012-PsiThaCa.opam @@ -0,0 +1,20 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-client-012-PsiThaCa" + "tezos-client-commands" + "tezos-baking-012-PsiThaCa-commands" + "tezos-client-base-unix" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: accuser binary" diff --git a/src/proto_012_PsiThaCa/bin_baker/.ocamlformat b/src/proto_012_PsiThaCa/bin_baker/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_baker/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/bin_baker/dune b/src/proto_012_PsiThaCa/bin_baker/dune new file mode 100644 index 000000000000..9c8f57185f45 --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_baker/dune @@ -0,0 +1,20 @@ +; build static executable with --profile static +(env + (static + (flags (:standard + -ccopt -static)))) + +(executable + (name main_baker_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-baker-012-PsiThaCa) + (libraries tezos-client-base-unix + tezos-client-commands + tezos-baking-012-PsiThaCa-commands) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -open Tezos_client_012_PsiThaCa + -open Tezos_client_commands + -open Tezos_baking_012_PsiThaCa_commands + -open Tezos_stdlib_unix + -open Tezos_client_base_unix))) diff --git a/src/proto_012_PsiThaCa/bin_baker/dune-project b/src/proto_012_PsiThaCa/bin_baker/dune-project new file mode 100644 index 000000000000..5fab06455dee --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_baker/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-baker-alpha) diff --git a/src/proto_012_PsiThaCa/bin_baker/main_baker_012_PsiThaCa.ml b/src/proto_012_PsiThaCa/bin_baker/main_baker_012_PsiThaCa.ml new file mode 100644 index 000000000000..3115253b9427 --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_baker/main_baker_012_PsiThaCa.ml @@ -0,0 +1,38 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let () = + Client_commands.register Protocol.hash @@ fun _network -> + List.map (Clic.map_command (new Protocol_client_context.wrap_full)) + @@ Baking_commands.baker_commands () + +let select_commands _ _ = + return + (List.map + (Clic.map_command (new Protocol_client_context.wrap_full)) + (Baking_commands.baker_commands ())) + +let () = Client_main_run.run (module Daemon_config) ~select_commands diff --git a/src/proto_012_PsiThaCa/bin_baker/tezos-baker-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/bin_baker/tezos-baker-012-PsiThaCa.opam new file mode 100644 index 000000000000..6a7e5af4c69f --- /dev/null +++ b/src/proto_012_PsiThaCa/bin_baker/tezos-baker-012-PsiThaCa.opam @@ -0,0 +1,20 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-client-012-PsiThaCa" + "tezos-client-commands" + "tezos-baking-012-PsiThaCa-commands" + "tezos-client-base-unix" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: baker binary" diff --git a/src/proto_012_PsiThaCa/lib_benchmark/.ocamlformat b/src/proto_012_PsiThaCa/lib_benchmark/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_benchmark/README.md b/src/proto_012_PsiThaCa/lib_benchmark/README.md new file mode 100644 index 000000000000..8adba76cbf90 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/README.md @@ -0,0 +1,42 @@ +# `Tezos_benchmark_alpha` + +This library is dedicated to sampling Michelson values and in particular +Michelson programs. + +## Architecture + +This library provides a sampling-based interface for well-typed +Michelson generation. Internally, this library is built on a sampler for an +intermediate language called Mikhailsky post-composed with a function to +map Mikhailsky terms to Michelson ones. + +### Layer 1: Mikhailsky + Mikhailsky corresponds to "Michelson with typed holes". Mikhailsky terms + are encoded inside Micheline. The library `lib_benchmark_type_inference` + provides the language definition as well as a type inference engine. + +### Layer 2: Sampling Mikhailsky terms + We sample Mikhailsky terms using a Markov chain where transitions correspond + to local rewriting rules. The state space of the Markov chain is defined + in `State_space` module. The rewriting infrastructure is provided in the + `Kernel` module by instantiating `lib_micheline_rewriting`. + Rewrites are checked to preserved well-typedness in the Mikhailsky sense + using the type inference engine provided with Mikhailsky. The `Rules` + module defines all rewriting rules, for both Mikhailsky _programs_ + (submodule `Rules.Instruction`) and _data_ + (submodule `Rules.Data_rewrite_leaves`). The function `Rules.rewriting` + performs the enumeration of possible rewritings. + + The Markov chain is biased to sample terms of a specified + size using the Metropolis-Hasting functors provided by `StaTz`. + The instantiation of this Markov chain is defined in the `Sampler` + module. + +### Layer 3: + Once we can sample Mikhaislky terms of a specified size, we need + to convert them to Michelson ones. This is performed in two steps. + - In the first step, we use the `Autocomplete` module to fill holes + in Mikhailsky terms (resp. data) with well-typed code (resp. data). + This is a relatively ad-hoc process. + - The last step is to convert Mikhaislky to Michelson using the + `Michelson` module. diff --git a/src/proto_012_PsiThaCa/lib_benchmark/autocomp.ml b/src/proto_012_PsiThaCa/lib_benchmark/autocomp.ml new file mode 100644 index 000000000000..1a44dc9826f7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/autocomp.ml @@ -0,0 +1,382 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Autocompletion functions (removing holes from Mikhailsky terms). *) + +open Sampling_helpers + +(* ------------------------------------------------------------------------- *) +(* Helpers *) + +let rec stack_length (stack : Type.Stack.t) acc = + match stack.node with + | Empty_t -> acc + | Stack_var_t _ -> acc + 1 + | Item_t (_, tl) -> stack_length tl (acc + 1) + +(* We need to sort and remove duplicate elements + of sets and maps to make them Michelson-compatible. *) +let sort_set_elements elements = + List.sort_uniq + (Structural_compare.compare + ~prim_compare:Mikhailsky.Mikhailsky_signature.compare) + elements + +let sort_map_elements elements = + let open Micheline in + List.sort_uniq + (fun node1 node2 -> + match (node1, node2) with + | ( Prim (_, Mikhailsky_prim.D_Elt, [k1; _v1], _), + Prim (_, Mikhailsky_prim.D_Elt, [k2; _v2], _) ) -> + Structural_compare.compare + ~prim_compare:Mikhailsky.Mikhailsky_signature.compare + k1 + k2 + | _ -> Stdlib.failwith "Autocomp.sort_map_elements: invalid Michelson map") + elements + +(* ------------------------------------------------------------------------- *) +(* Error handling *) + +type error_case = + | Cannot_complete_data of Mikhailsky.node * Kernel.Path.t + | Cannot_complete_code of Mikhailsky.node * Kernel.Path.t + +exception Autocompletion_error of error_case + +let cannot_complete_data node path = + raise (Autocompletion_error (Cannot_complete_data (node, path))) + +let cannot_complete_code node path = + raise (Autocompletion_error (Cannot_complete_code (node, path))) + +(* ------------------------------------------------------------------------- *) +(* Code & data autocompletion *) + +(* By default, comparable values are unit. *) +let default_comparable_type = Type.unit + +let generate_comparable _sp = Mikhailsky.Data.unit + +(* Instantiates variables in a base type, remaining variables + are mapped to some consistent choice of ground type + (this is made complicated by comparability constraints) *) +let rec instantiate_and_set ty = + let open Inference.M in + Inference.instantiate_base ty >>= fun ty -> replace_vars ty + +and replace_vars (ty : Type.Base.t) = + let open Inference.M in + let node = ty.node in + match node with + | Type.Base.Unit_t | Type.Base.Int_t | Type.Base.Nat_t | Type.Base.Bool_t + | Type.Base.String_t | Type.Base.Bytes_t | Type.Base.Key_hash_t + | Type.Base.Timestamp_t | Type.Base.Mutez_t | Type.Base.Key_t -> + return ty + | Type.Base.Var_t v -> ( + get_repr_exn v >>= fun repr -> + match repr with + | Inference.Stack_type _ -> assert false + | Inference.Base_type {comparable = _; repr = Some _} -> assert false + | Inference.Base_type {comparable; repr = None} -> ( + match comparable with + | Inference.Comparable -> return default_comparable_type + | Inference.Unconstrained | Inference.Not_comparable -> + return Type.unit)) + | Type.Base.Option_t ty -> + replace_vars ty >>= fun ty -> return (Type.option ty) + | Type.Base.Pair_t (lt, rt) -> + replace_vars lt >>= fun lt -> + replace_vars rt >>= fun rt -> return (Type.pair lt rt) + | Type.Base.Union_t (lt, rt) -> + replace_vars lt >>= fun lt -> + replace_vars rt >>= fun rt -> return (Type.union lt rt) + | Type.Base.List_t ty -> replace_vars ty >>= fun ty -> return (Type.list ty) + | Type.Base.Set_t ty -> replace_vars ty >>= fun ty -> return (Type.set ty) + | Type.Base.Map_t (k, v) -> + replace_vars k >>= fun k -> + replace_vars v >>= fun v -> return (Type.map k v) + | Type.Base.Lambda_t (dom, range) -> + replace_vars dom >>= fun dom -> + replace_vars range >>= fun range -> return (Type.lambda dom range) + +let rec instantiate_and_set_stack (stack_ty : Type.Stack.t) = + let open Inference.M in + let node = stack_ty.node in + match node with + | Type.Stack.Empty_t -> return Type.empty + | Type.Stack.Stack_var_t _ -> return Type.empty + | Type.Stack.Item_t (hd, tl) -> + instantiate_and_set hd >>= fun hd -> + instantiate_and_set_stack tl >>= fun tl -> return (Type.item hd tl) + +(* In the following we perform computations in the composite monad + (sampler o Inference.M.t), it is convenient to define the bind and return + explicitly. *) +module SM = struct + type 'a t = 'a Inference.M.t sampler + + let ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t = + fun m f rng_state s -> + let (x, s) = m rng_state s in + f x rng_state s + [@@inline] + + let sample : 'a sampler -> 'a Inference.M.t sampler = + fun x rng_state st -> (x rng_state, st) + [@@inline] + + let deterministic : 'a Inference.M.t -> 'a t = fun x _rng_state -> x + + let return x _ s = (x, s) [@@inline] +end + +module Make + (Michelson_base : Michelson_samplers_base.S) + (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) = +struct + (* Generates minimally sized random data of specified type. + Used in autocompletion. *) + (* /!\ Always call [instantiate_and_set] on the type argument of + [generate_data]. /!\ *) + let rec generate_data : Type.Base.t -> Mikhailsky.node SM.t = + fun ty -> + let open SM in + let open Type.Base in + let desc = ty.node in + match desc with + | Var_t _v -> assert false + | Unit_t -> return Mikhailsky.Data.unit + | Int_t -> + sample @@ Michelson_base.int >>= fun i -> + let i = Protocol.Script_int_repr.to_zint i in + return (Mikhailsky.Data.big_integer i) + | Nat_t -> + sample @@ Michelson_base.nat >>= fun n -> + let n = Protocol.Script_int_repr.to_zint n in + return (Mikhailsky.Data.big_natural n) + | Bool_t -> + sample Base_samplers.uniform_bool >>= fun b -> + if b then return Mikhailsky.Data.true_ + else return Mikhailsky.Data.false_ + | String_t -> + sample Michelson_base.string >>= fun str -> + let str = Protocol.Script_string_repr.to_string str in + return (Mikhailsky.Data.string str) + | Bytes_t -> + sample Michelson_base.bytes >>= fun bytes -> + return (Mikhailsky.Data.bytes bytes) + | Key_hash_t -> + sample Crypto_samplers.pkh >>= fun pkh -> + return (Mikhailsky.Data.key_hash pkh) + | Timestamp_t -> + sample Michelson_base.timestamp >>= fun tstamp -> + return (Mikhailsky.Data.timestamp tstamp) + | Mutez_t -> + sample Michelson_base.tez >>= fun tz -> + return (Mikhailsky.Data.mutez tz) + | Key_t -> + sample Crypto_samplers.pk >>= fun pk -> return (Mikhailsky.Data.key pk) + | Option_t ty -> + sample Base_samplers.uniform_bool >>= fun b -> + if b then return Mikhailsky.Data.none + else generate_data ty >>= fun res -> return (Mikhailsky.Data.some res) + | Pair_t (lty, rty) -> + generate_data lty >>= fun lv -> + generate_data rty >>= fun rv -> return (Mikhailsky.Data.pair lv rv) + | Union_t (lty, rty) -> + sample Base_samplers.uniform_bool >>= fun b -> + if b then generate_data lty >>= fun v -> return (Mikhailsky.Data.left v) + else generate_data rty >>= fun v -> return (Mikhailsky.Data.right v) + | List_t _ty -> return (Mikhailsky.Data.list []) + | Set_t _ty -> return (Mikhailsky.Data.set []) + | Map_t (_kty, _vty) -> return (Mikhailsky.Data.map []) + | Lambda_t (dom, range) -> + invent_term Type.(item dom empty) Type.(item range empty) + >>= fun code -> return (Mikhailsky.Data.lambda code) + + and invent_term (bef : Type.Stack.t) (aft : Type.Stack.t) : + Mikhailsky.node list SM.t = + let open SM in + install_dummy_stack aft [] >>= fun code -> + let terms = drop_stack bef code in + return terms + + and drop_stack (stack : Type.Stack.t) code = + Mikhailsky.Instructions.dropn (stack_length stack 0) :: code + + and install_dummy_stack (stack : Type.Stack.t) (acc : Mikhailsky.node list) = + let open SM in + match stack.node with + | Empty_t -> return acc + | Stack_var_t _ -> + let acc = Mikhailsky.(Instructions.push unit_ty Data.unit) :: acc in + return acc + | Item_t (hd, tl) -> + deterministic @@ instantiate_and_set hd >>= fun hd -> + (match hd.node with + | Lambda_t (dom, range) -> + invent_term Type.(item dom empty) Type.(item range empty) + >>= fun code -> + let instr = Mikhailsky.(prim I_LAMBDA [seq code] []) in + return instr + | _ -> + generate_data hd >>= fun term -> + let ty = Mikhailsky.unparse_ty_exn hd in + return (Mikhailsky.Instructions.push ty term)) + >>= fun instr -> install_dummy_stack tl (instr :: acc) + + (* Autocomplete Mikhailsky data. + When encountering a hole, we lookup its type and instantiate + some random data of the specified type. *) + let rec complete_data : + Mikhailsky.node -> Kernel.Path.t -> Mikhailsky.node SM.t = + let open SM in + fun node path -> + match node with + | Micheline.Int (_, _) | Micheline.String (_, _) | Micheline.Bytes (_, _) + -> + return node + | Micheline.Prim (_, D_Hole, _, _) -> ( + deterministic @@ Inference.M.get_data_annot path >>= fun ty_opt -> + match ty_opt with + | None -> cannot_complete_data node path + | Some ty -> + deterministic @@ instantiate_and_set ty >>= fun ty -> + generate_data ty) + | Micheline.Prim (_, A_Set, [Micheline.Seq (_, elements)], _) -> + complete_data_list (Kernel.Path.at_index 0 path) 0 elements [] + >>= fun elements -> + let elements = sort_set_elements elements in + return (Mikhailsky.Data.set elements) + | Micheline.Prim (_, A_Map, [Micheline.Seq (_, elements)], _) -> + complete_data_list (Kernel.Path.at_index 0 path) 0 elements [] + >>= fun elements -> + let elements = sort_map_elements elements in + return (Mikhailsky.Data.map elements) + | Micheline.Prim (_, prim, subterms, _) -> + complete_data_list path 0 subterms [] >>= fun subterms -> + return (Mikhailsky.prim prim subterms []) + | Micheline.Seq (_, subterms) -> + complete_data_list path 0 subterms [] >>= fun subterms -> + return (Mikhailsky.seq subterms) + + and complete_data_list path i subterms acc = + let open SM in + match subterms with + | [] -> return (List.rev acc) + | subterm :: tl -> + let path' = Kernel.Path.at_index i path in + complete_data subterm path' >>= fun term -> + complete_data_list path (i + 1) tl (term :: acc) + + let complete_data typing node rng_state = + let (root_type_opt, _) = + Inference.M.get_data_annot Kernel.Path.root typing + in + match root_type_opt with + | None -> Stdlib.failwith "Autocomp.complete_data: cannot get type of expr" + | Some ty -> + let (_, typing) = Inference.instantiate_base ty typing in + let (result, _) = + try complete_data node Kernel.Path.root rng_state typing + with Autocompletion_error (Cannot_complete_data (subterm, path)) -> + Format.eprintf "Cannot complete data@." ; + Format.eprintf "at path %s@." (Kernel.Path.to_string path) ; + Format.eprintf "%a@." Mikhailsky.pp subterm ; + Stdlib.failwith "in autocomp.ml: unrecoverable failure" + in + let (typ, _typing) = + try Inference.infer_data_with_state result + with Inference.Ill_typed_script error -> + Format.eprintf "%a@." Inference.pp_inference_error error ; + Format.eprintf "%a@." Mikhailsky.pp result ; + assert false + in + (result, typ) + + (* Autocomplete Mikhailsky code. *) + + let rec complete_code : + Mikhailsky.node -> Kernel.Path.t -> Mikhailsky.node SM.t = + let open SM in + fun node path -> + match node with + | Micheline.Int (_, _) | Micheline.String (_, _) | Micheline.Bytes (_, _) + -> + return node + | Micheline.Prim (_, I_Hole, _, _) -> ( + deterministic @@ Inference.M.get_instr_annot path >>= function + | None -> cannot_complete_code node path + | Some {bef; aft} -> + deterministic @@ Inference.instantiate bef >>= fun bef -> + deterministic @@ Inference.instantiate aft >>= fun aft -> + invent_term bef aft >>= fun code -> return (Mikhailsky.seq code)) + | Micheline.Prim (_, prim, subterms, _) -> + complete_code_list path 0 subterms [] >>= fun subterms -> + return (Mikhailsky.prim prim subterms []) + | Micheline.Seq (_, subterms) -> + complete_code_list path 0 subterms [] >>= fun subterms -> + return (Mikhailsky.seq subterms) + + and complete_code_list path i subterms acc = + let open SM in + match subterms with + | [] -> return (List.rev acc) + | subterm :: tl -> + let path' = Kernel.Path.at_index i path in + complete_code subterm path' >>= fun term -> + complete_code_list path (i + 1) tl (term :: acc) + + let complete_code typing node rng_state = + let (root_type_opt, _) = + Inference.M.get_instr_annot Kernel.Path.root typing + in + match root_type_opt with + | None -> Stdlib.failwith "Autocomp.complete_code: cannot get type of expr" + | Some {bef; aft} -> + let (_, typing) = Inference.instantiate bef typing in + let (_, typing) = Inference.instantiate aft typing in + let (result, _) = + try complete_code node Kernel.Path.root rng_state typing with + | Autocompletion_error (Cannot_complete_code (subterm, path)) -> + Format.eprintf "Cannot complete code@." ; + Format.eprintf "at path %s@." (Kernel.Path.to_string path) ; + Format.eprintf "%a@." Mikhailsky.pp subterm ; + Stdlib.failwith "in autocomp.ml: unrecoverable failure" + | _ -> assert false + in + let ((bef, aft), typing) = + try Inference.infer_with_state result + with Inference.Ill_typed_script error -> + Format.eprintf "%a@." Inference.pp_inference_error error ; + Format.eprintf "%a@." Mikhailsky.pp result ; + assert false + in + let (bef, typing) = instantiate_and_set_stack bef typing in + let (aft, typing) = instantiate_and_set_stack aft typing in + (result, (bef, aft), typing) +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/dune b/src/proto_012_PsiThaCa/lib_benchmark/dune new file mode 100644 index 000000000000..4ee550cb1d11 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/dune @@ -0,0 +1,27 @@ +(library + (name tezos_benchmark_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-benchmark-012-PsiThaCa) + (libraries + tezos-base + tezos-protocol-012-PsiThaCa + tezos-protocol-012-PsiThaCa-parameters + tezos-micheline-rewriting + tezos-benchmark + tezos-benchmark-type-inference-012-PsiThaCa + hashcons + benchmark-utils + tezos-012-PsiThaCa-test-helpers + prbnmcn-stats) + (library_flags (:standard -linkall)) + (private_modules kernel rules state_space) + (flags (:standard -open Tezos_stdlib + -open Tezos_base + -open Tezos_error_monad + -open Tezos_micheline + -open Tezos_micheline_rewriting + -open Tezos_benchmark + -open Tezos_benchmark_type_inference_012_PsiThaCa + -open Tezos_protocol_012_PsiThaCa + -open Tezos_crypto + -open Tezos_012_PsiThaCa_test_helpers))) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/dune-project b/src/proto_012_PsiThaCa/lib_benchmark/dune-project new file mode 100644 index 000000000000..cb4adad038dd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-benchmark-alpha) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/execution_context.ml b/src/proto_012_PsiThaCa/lib_benchmark/execution_context.ml new file mode 100644 index 000000000000..74a60d5bd405 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/execution_context.ml @@ -0,0 +1,84 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Error_monad + +type context = Alpha_context.context * Script_interpreter.step_constants + +let context_init_memory ~rng_state = + Context.init + ~rng_state + ~initial_balances: + [ + 4_000_000_000_000L; + 4_000_000_000_000L; + 4_000_000_000_000L; + 4_000_000_000_000L; + 4_000_000_000_000L; + ] + 5 + >>=? fun (block, accounts) -> + match accounts with + | [bs1; bs2; bs3; bs4; bs5] -> + return (`Mem_block (block, (bs1, bs2, bs3, bs4, bs5))) + | _ -> assert false + +let context_init ~rng_state = context_init_memory ~rng_state + +let make ~rng_state = + context_init_memory ~rng_state >>=? fun context -> + let amount = Alpha_context.Tez.one in + let chain_id = Chain_id.zero in + let now = Alpha_context.Script_timestamp.of_zint Z.zero in + let level = Alpha_context.Script_int.zero_n in + let open Script_interpreter in + (match context with + | `Mem_block (block, (bs1, bs2, bs3, _, _)) -> + let source = bs1 in + let payer = bs2 in + let self = bs3 in + let step_constants = + {source; payer; self; amount; chain_id; now; level} + in + return (block, step_constants) + | `Disk_block (block, source) -> + let step_constants = + {source; payer = source; self = source; amount; chain_id; now; level} + in + return (block, step_constants)) + >>=? fun (block, step_constants) -> + Incremental.begin_construction + ~timestamp:(Time.Protocol.add block.header.shell.timestamp 30L) + block + >>=? fun vs -> + let ctxt = Incremental.alpha_ctxt vs in + let ctxt = + (* Required for eg Create_contract *) + Protocol.Alpha_context.Contract.init_origination_nonce + ctxt + Operation_hash.zero + in + return (ctxt, step_constants) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/kernel.ml b/src/proto_012_PsiThaCa/lib_benchmark/kernel.ml new file mode 100644 index 000000000000..0932302aa20b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/kernel.ml @@ -0,0 +1,39 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* ------------------------------------------------------------------------- *) +(* Instantiate rewriting subsystem *) + +module Lang = + Micheline_with_hash_consing.Make + (Mikhailsky.Mikhailsky_signature) + (struct + let initial_size = None + end) + +module Path = Mikhailsky.Path +module Patt = Pattern.Make (Mikhailsky.Mikhailsky_signature) (Lang) (Path) +module Rewriter = + Rewrite.Make (Mikhailsky.Mikhailsky_signature) (Lang) (Path) (Patt) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/.ocamlformat b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/dune b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/dune new file mode 100644 index 000000000000..aa61df0fd5ba --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/dune @@ -0,0 +1,17 @@ +(library + (name tezos_benchmark_type_inference_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-benchmark-type-inference-012-PsiThaCa) + (libraries + tezos-stdlib + tezos-error-monad + tezos-crypto + tezos-micheline + tezos-protocol-012-PsiThaCa + tezos-micheline-rewriting + hashcons) + (flags (:standard -open Tezos_stdlib + -open Tezos_error_monad + -open Tezos_micheline + -open Tezos_micheline_rewriting + -open Tezos_protocol_012_PsiThaCa))) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/dune-project b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/dune-project new file mode 100644 index 000000000000..c0b5d472accd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(name tezos-benchmark-type-inference-alpha) +(formatting (enabled_for ocaml)) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/inference.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/inference.ml new file mode 100644 index 000000000000..72dc6c1ef4be --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/inference.ml @@ -0,0 +1,1150 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Micheline +module UF = Uf.UF + +(* The domain of comparability: + * + * Comparable Not_comparable + * ^ ^ + * \ / + * \ / + * Unconstrained + * + * The higher we go, the more information we have. + * This domain admits all glbs but not all lubs. + *) + +type comparability = Comparable | Not_comparable | Unconstrained + +let pp_comparability fmtr (cmp : comparability) = + match cmp with + | Comparable -> Format.fprintf fmtr "Comparable" + | Not_comparable -> Format.fprintf fmtr "Not_comparable" + | Unconstrained -> Format.fprintf fmtr "Unconstrained" + +let sup_comparability (c1 : comparability) (c2 : comparability) = + match (c1, c2) with + | (Unconstrained, c) | (c, Unconstrained) -> Some c + | (Comparable, Comparable) -> Some Comparable + | (Not_comparable, Not_comparable) -> Some Not_comparable + | (Comparable, Not_comparable) | (Not_comparable, Comparable) -> None + +type michelson_type = + | Base_type of {repr : Type.Base.t option; comparable : comparability} + | Stack_type of Type.Stack.t option + +type transformer = {bef : Type.Stack.t; aft : Type.Stack.t} + +let michelson_type_to_string (x : michelson_type) = + match x with + | Base_type {repr = None; comparable} -> + Format.asprintf "?::[%a]" pp_comparability comparable + | Base_type {repr = Some ty; comparable} -> + Format.asprintf "%a::[%a]" Type.Base.pp ty pp_comparability comparable + | Stack_type None -> "" + | Stack_type (Some sty) -> Format.asprintf "%a" Type.Stack.pp sty + +(* ------------------------------------------------------------------------- *) +(* Typechecking errors *) + +type inference_error = + (* | Expected_data_with_ground_type of Mikhailsky.Path.t * Mikhailsky.node *) + | Unhandled_micheline of Mikhailsky.Path.t * Mikhailsky.node + | Expected_micheline_prim + | Unsatisfiable_comparability_constraint of comparability_error_witness + | Base_types_incompatible of Type.Base.t * Type.Base.t + | Stack_types_incompatible of Type.Stack.t * Type.Stack.t + | Badly_typed_arithmetic of Mikhailsky_prim.prim * Type.Base.t * Type.Base.t + | Ill_formed_arithmetic of Mikhailsky.Path.t * Mikhailsky.node + | Cyclic_stack_type + | Cyclic_base_type + | Invalid_ast of string option * Mikhailsky.Path.t * Mikhailsky.node + +and comparability_error_witness = + | Comparability_error_types of michelson_type * michelson_type + | Comparability_error_tags of Type.Base.t * comparability * comparability + +let pp_inference_error fmtr (err : inference_error) = + match err with + (* | Expected_data_with_ground_type (path, node) -> + * let path = Mikhailsky.Path.to_string path in + * let node = Mikhailsky.to_string node in + * Format.fprintf fmtr "Expected data with ground type: %s at path %s" node path *) + | Unhandled_micheline (path, node) -> + let path = Mikhailsky.Path.to_string path in + let node = Mikhailsky.to_string node in + Format.fprintf fmtr "Unhandled micheline: %s at path %s" node path + | Expected_micheline_prim -> + Format.fprintf fmtr "%s" "Expected_micheline_prim" + | Unsatisfiable_comparability_constraint + (Comparability_error_types (ty1, ty2)) -> + let ty1 = michelson_type_to_string ty1 in + let ty2 = michelson_type_to_string ty2 in + Format.fprintf + fmtr + "Unsatisfiable comparability constraint: %s # %s" + ty1 + ty2 + | Unsatisfiable_comparability_constraint + (Comparability_error_tags (ty, cmp1, cmp2)) -> + Format.fprintf + fmtr + "Unsatisfiable comparability constraint: %a :: %a # %a" + Type.Base.pp + ty + pp_comparability + cmp1 + pp_comparability + cmp2 + | Base_types_incompatible (ty1, ty2) -> + Format.fprintf + fmtr + "Base types incompatible: %a %a" + Type.Base.pp + ty1 + Type.Base.pp + ty2 + | Stack_types_incompatible (sty1, sty2) -> + Format.fprintf + fmtr + "Stack types incompatible: %a %a" + Type.Stack.pp + sty1 + Type.Stack.pp + sty2 + | Badly_typed_arithmetic (prim, ty1, ty2) -> + Format.fprintf + fmtr + "Badly typed arithmetic: %a(%a, %a)" + Mikhailsky_prim.pp + prim + Type.Base.pp + ty1 + Type.Base.pp + ty2 + | Ill_formed_arithmetic (path, node) -> + let path = Mikhailsky.Path.to_string path in + let node = Mikhailsky.to_string node in + Format.fprintf fmtr "Ill formed arithmetic: %s at path %s" node path + | Cyclic_stack_type -> Format.fprintf fmtr "Cyclic stack type" + | Cyclic_base_type -> Format.fprintf fmtr "Cyclic base type" + | Invalid_ast (msg_opt, path, node) -> ( + let path = Mikhailsky.Path.to_string path in + let node = Mikhailsky.to_string node in + match msg_opt with + | None -> Format.fprintf fmtr "Invalid ast: %s at path %s" node path + | Some msg -> + Format.fprintf fmtr "Invalid ast: %s at path %s (%s)" node path msg) + +exception Ill_typed_script of inference_error + +let unsatisfiable_comparability ty cmp1 cmp2 = + raise + (Ill_typed_script + (Unsatisfiable_comparability_constraint + (Comparability_error_tags (ty, cmp1, cmp2)))) + +let invalid_ast ?msg path node = + raise (Ill_typed_script (Invalid_ast (msg, path, node))) + +let () = + Printexc.register_printer (fun exn -> + match exn with + | Ill_typed_script error -> + Some (Format.asprintf "%a" pp_inference_error error) + | _ -> None) + +(* ------------------------------------------------------------------------- *) + +module Repr_store = + Stores.Map + (Int_map) + (struct + type key = int + + type value = michelson_type + + let key_to_string = string_of_int + + let value_to_string = michelson_type_to_string + end) + +module Repr_sm = Monads.Make_state_monad (Repr_store) +module Path_map = Map.Make (Mikhailsky.Path) + +module Annot_instr_store = + Stores.Map + (Path_map) + (struct + type key = Mikhailsky.Path.t + + type value = transformer + + let key_to_string = Mikhailsky.Path.to_string + + let value_to_string {bef; aft} = + Format.asprintf "%a => %a" Type.Stack.pp bef Type.Stack.pp aft + end) + +module Annot_instr_sm = Monads.Make_state_monad (Annot_instr_store) + +module Annot_data_store = + Stores.Map + (Path_map) + (struct + type key = Mikhailsky.Path.t + + type value = Type.Base.t + + let key_to_string = Mikhailsky.Path.to_string + + let value_to_string ty = Format.asprintf "%a" Type.Base.pp ty + end) + +module Annot_data_sm = Monads.Make_state_monad (Annot_data_store) + +type state = { + uf : UF.M.state; + repr : Repr_sm.state; + annot_instr : Annot_instr_sm.state; + annot_data : Annot_data_sm.state; +} + +module M = struct + type 'a t = state -> 'a * state + + let empty : unit -> state = + fun () -> + { + uf = UF.M.empty (); + repr = Repr_sm.empty (); + annot_instr = Annot_instr_sm.empty (); + annot_data = Annot_data_sm.empty (); + } + + let ( >>= ) m f s = + let (x, s) = m s in + f x s + [@@inline] + + let return x s = (x, s) + + (* let run m = fst (m (empty ())) *) + + let uf_lift : 'a UF.M.t -> 'a t = + fun computation state -> + let (res, uf) = computation state.uf in + (res, {state with uf}) + [@@inline] + + let repr_lift : 'a Repr_sm.t -> 'a t = + fun computation state -> + let (res, repr) = computation state.repr in + (res, {state with repr}) + [@@inline] + + let annot_instr_lift : 'a Annot_instr_sm.t -> 'a t = + fun computation state -> + let (res, annot_instr) = computation state.annot_instr in + (res, {state with annot_instr}) + [@@inline] + + let annot_data_lift : 'a Annot_data_sm.t -> 'a t = + fun computation state -> + let (res, annot_data) = computation state.annot_data in + (res, {state with annot_data}) + [@@inline] + + let set_repr k v = repr_lift (Repr_sm.set k v) [@@inline] + + let get_repr_exn k = + repr_lift (Repr_sm.get k) >>= function + | None -> Stdlib.failwith "get_repr_exn" + | Some res -> return res + [@@inline] + + let set_instr_annot k v = annot_instr_lift (Annot_instr_sm.set k v) [@@inline] + + let get_instr_annot k = annot_instr_lift (Annot_instr_sm.get k) [@@inline] + + let set_data_annot k v = annot_data_lift (Annot_data_sm.set k v) [@@inline] + + let get_data_annot k = annot_data_lift (Annot_data_sm.get k) [@@inline] + + let get_state state = (state, state) +end + +module S = Set.Make (Int) + +let rec instantiate (encountered : S.t) (stack_ty : Type.Stack.t) : + Type.Stack.t M.t = + let open Type.Stack in + let open M in + if S.mem stack_ty.tag encountered then + raise (Ill_typed_script Cyclic_stack_type) + else + let encountered = S.add stack_ty.tag encountered in + match stack_ty.node with + | Empty_t -> return stack_ty + | Stack_var_t x -> ( + uf_lift (UF.find x) >>= fun root -> + get_repr_exn root >>= function + | Stack_type None -> return (Type.stack_var root) + | Stack_type (Some ty) -> instantiate encountered ty + | _ -> assert false) + | Item_t (head, tail) -> + instantiate_base S.empty head >>= fun head -> + instantiate encountered tail >>= fun tail -> + return (Type.item head tail) + +and instantiate_base (encountered : S.t) (ty : Type.Base.t) : Type.Base.t M.t = + let open Type.Base in + let open M in + if S.mem ty.tag encountered then raise (Ill_typed_script Cyclic_base_type) + else + let encountered = S.add ty.tag encountered in + match ty.node with + | Unit_t | Int_t | Nat_t | Bool_t | String_t | Bytes_t | Key_hash_t | Key_t + | Timestamp_t | Mutez_t -> + return ty + | Option_t ty -> + instantiate_base encountered ty >>= fun ty -> return (Type.option ty) + | List_t ty -> + instantiate_base encountered ty >>= fun ty -> return (Type.list ty) + | Set_t ty -> + instantiate_base encountered ty >>= fun ty -> return (Type.set ty) + | Map_t (kty, vty) -> + instantiate_base encountered kty >>= fun kty -> + instantiate_base encountered vty >>= fun vty -> + return (Type.map kty vty) + | Pair_t (lty, rty) -> + instantiate_base encountered lty >>= fun lty -> + instantiate_base encountered rty >>= fun rty -> + return (Type.pair lty rty) + | Union_t (lty, rty) -> + instantiate_base encountered lty >>= fun lty -> + instantiate_base encountered rty >>= fun rty -> + return (Type.union lty rty) + | Lambda_t (dom, range) -> + instantiate_base encountered dom >>= fun dom -> + instantiate_base encountered range >>= fun range -> + return (Type.lambda dom range) + | Var_t x -> ( + uf_lift (UF.find x) >>= fun root -> + get_repr_exn root >>= function + | Base_type {repr = None; _} -> return (Type.var root) + | Base_type {repr = Some ty; _} -> instantiate_base encountered ty + | _ -> assert false) + +let instantiate_base base_ty = instantiate_base S.empty base_ty + +let instantiate stack_ty = instantiate S.empty stack_ty + +let rec unify (x : Type.Stack.t) (y : Type.Stack.t) : unit M.t = + let open Type.Stack in + let open M in + let unify_single_stack v x = + (match Type.Stack.vars x with + | None -> return () + | Some v' -> + if v = v' then raise (Ill_typed_script Cyclic_stack_type) else return ()) + >>= fun () -> + M.uf_lift (UF.find v) >>= fun root -> + get_repr_exn root >>= fun repr -> + merge_reprs (Stack_type (Some x)) repr >>= fun repr -> set_repr root repr + in + if x.tag = y.tag then return () + else + match (x.node, y.node) with + | (Empty_t, Empty_t) -> return () + | (Stack_var_t x, Stack_var_t y) -> + M.uf_lift (UF.find x) >>= fun root_x -> + M.uf_lift (UF.find y) >>= fun root_y -> + get_repr_exn root_x >>= fun repr_x -> + get_repr_exn root_y >>= fun repr_y -> + M.uf_lift (UF.union x y) >>= fun root -> + merge_reprs repr_x repr_y >>= fun repr -> set_repr root repr + | (Stack_var_t v, _) -> unify_single_stack v y + | (_, Stack_var_t v) -> unify_single_stack v x + | (Item_t (ty1, tail1), Item_t (ty2, tail2)) -> + unify_base ty1 ty2 >>= fun () -> + unify tail1 tail2 >>= fun () -> return () + | _ -> raise (Ill_typed_script (Stack_types_incompatible (x, y))) + +and unify_base (x : Type.Base.t) (y : Type.Base.t) : unit M.t = + let open Type.Base in + let open M in + let unify_single_var v x = + (if List.mem v (Type.Base.vars x) then + raise (Ill_typed_script Cyclic_base_type) + else return ()) + >>= fun () -> + M.uf_lift (UF.find v) >>= fun root -> + get_repr_exn root >>= fun repr -> + get_comparability x >>= fun comparable -> + merge_reprs (Base_type {repr = Some x; comparable}) repr >>= fun repr -> + set_repr root repr + in + if x.tag = y.tag then return () + else + match (x.node, y.node) with + | (Unit_t, Unit_t) + | (Int_t, Int_t) + | (Nat_t, Nat_t) + | (Bool_t, Bool_t) + | (String_t, String_t) + | (Bytes_t, Bytes_t) + | (Key_hash_t, Key_hash_t) + | (Timestamp_t, Timestamp_t) + | (Mutez_t, Mutez_t) + | (Key_t, Key_t) -> + return () + | (Option_t x, Option_t y) -> unify_base x y + | (List_t x, List_t y) -> unify_base x y + | (Set_t x, Set_t y) -> unify_base x y + | (Map_t (kx, vx), Map_t (ky, vy)) -> + unify_base kx ky >>= fun () -> unify_base vx vy + | (Pair_t (x, x'), Pair_t (y, y')) -> + unify_base x y >>= fun () -> unify_base x' y' + | (Union_t (x, x'), Union_t (y, y')) -> + unify_base x y >>= fun () -> unify_base x' y' + | (Lambda_t (x, x'), Lambda_t (y, y')) -> + unify_base x y >>= fun () -> unify_base x' y' + | (Var_t x, Var_t y) -> + M.uf_lift (UF.find x) >>= fun root_x -> + M.uf_lift (UF.find y) >>= fun root_y -> + get_repr_exn root_x >>= fun repr_x -> + get_repr_exn root_y >>= fun repr_y -> + M.uf_lift (UF.union x y) >>= fun root -> + merge_reprs repr_x repr_y >>= fun repr -> set_repr root repr + | (Var_t v, _) -> unify_single_var v y + | (_, Var_t v) -> unify_single_var v x + | _ -> + instantiate_base x >>= fun x -> + instantiate_base y >>= fun y -> + raise (Ill_typed_script (Base_types_incompatible (x, y))) + +and merge_reprs (repr1 : michelson_type) (repr2 : michelson_type) : + michelson_type M.t = + let open M in + match (repr1, repr2) with + | ((Stack_type None as repr), Stack_type None) + | ((Stack_type (Some _) as repr), Stack_type None) + | (Stack_type None, (Stack_type (Some _) as repr)) -> + return repr + | ((Stack_type (Some sty1) as repr), Stack_type (Some sty2)) -> + unify sty1 sty2 >>= fun () -> return repr + | ( Base_type {repr = opt1; comparable = cmp1}, + Base_type {repr = opt2; comparable = cmp2} ) -> ( + let comparable_opt = sup_comparability cmp1 cmp2 in + match comparable_opt with + | None -> + raise + (Ill_typed_script + (Unsatisfiable_comparability_constraint + (Comparability_error_types (repr1, repr2)))) + | Some comparable -> ( + match (opt1, opt2) with + | (None, None) -> return (Base_type {repr = None; comparable}) + | ((Some ty as repr), None) -> + assert_comparability comparable ty >>= fun () -> + return (Base_type {repr; comparable}) + | (None, (Some ty as repr)) -> + assert_comparability comparable ty >>= fun () -> + return (Base_type {repr; comparable}) + | (Some ty1, Some ty2) -> + unify_base ty1 ty2 >>= fun () -> + assert_comparability comparable ty1 >>= fun () -> + assert_comparability comparable ty2 >>= fun () -> + return (Base_type {repr = opt1; comparable}))) + | _ -> assert false + +and assert_comparability comparable ty = + assert_comparability_aux comparable ty [] + +and assert_comparability_aux lower_bound (ty : Type.Base.t) + (encountered : int list) : unit M.t = + let open M in + if List.mem ty.tag encountered then raise (Ill_typed_script Cyclic_base_type) + else + let encountered = ty.tag :: encountered in + match ty.node with + | Var_t v -> ( + uf_lift (UF.find v) >>= fun root -> + get_repr_exn root >>= fun repr -> + match repr with + | Base_type {repr = None; comparable} -> ( + match sup_comparability comparable lower_bound with + | None -> unsatisfiable_comparability ty comparable lower_bound + | Some comparable -> + set_repr root (Base_type {repr = None; comparable})) + | Base_type {repr = Some ty; comparable} -> ( + match sup_comparability comparable lower_bound with + | None -> unsatisfiable_comparability ty comparable lower_bound + | Some comparable -> + assert_comparability_aux lower_bound ty encountered + >>= fun () -> + set_repr root (Base_type {repr = Some ty; comparable})) + | Stack_type _ -> assert false) + | List_t _ | Set_t _ | Map_t _ | Lambda_t _ | Key_t -> ( + match lower_bound with + | Unconstrained | Not_comparable -> return () + | Comparable -> unsatisfiable_comparability ty Unconstrained lower_bound + ) + | Unit_t | Int_t | Nat_t | Bool_t | String_t | Bytes_t | Key_hash_t + | Timestamp_t | Mutez_t -> + (* if not (le_comparability lower_bound Comparable) then + * unsatisfiable_comparability ty Comparable lower_bound + * else *) + return () + | Option_t ty -> ( + match lower_bound with + | Comparable -> assert_comparability_aux Comparable ty encountered + | Not_comparable | Unconstrained -> return ()) + | Pair_t (l, r) -> ( + match lower_bound with + | Comparable -> + assert_comparability_aux Comparable l encountered >>= fun () -> + assert_comparability_aux Comparable r encountered + | Unconstrained | Not_comparable -> return ()) + | Union_t (l, r) -> ( + match lower_bound with + | Comparable -> + assert_comparability_aux Comparable l encountered >>= fun () -> + assert_comparability_aux Comparable r encountered + | Unconstrained | Not_comparable -> return ()) + +and get_comparability (ty : Type.Base.t) : comparability M.t = + let open M in + match ty.node with + | Var_t v -> ( + get_repr_exn v >>= fun repr -> + match repr with + | Stack_type _ -> assert false + | Base_type {comparable; _} -> return comparable) + | Unit_t | Int_t | Nat_t | Bool_t | String_t | Bytes_t | Key_hash_t + | Timestamp_t | Mutez_t -> + return Comparable + | List_t _ | Set_t _ | Map_t _ | Lambda_t _ | Key_t -> return Not_comparable + | Option_t ty -> get_comparability ty + | Union_t (lt, rt) | Pair_t (lt, rt) -> ( + get_comparability lt >>= fun lc -> + get_comparability rt >>= fun rc -> + match (lc, rc) with + | (Comparable, Comparable) -> return Comparable + | _ -> return Unconstrained) + +let fresh = + let x = ref ~-1 in + fun () -> + incr x ; + !x + +let exists_stack : unit -> Type.Stack.t M.t = + let open M in + fun () -> + let fresh = fresh () in + uf_lift (UF.add fresh) >>= fun () -> + set_repr fresh (Stack_type None) >>= fun () -> return (Type.stack_var fresh) + +let exists : unit -> Type.Base.t M.t = + let open M in + fun () -> + let fresh = fresh () in + uf_lift (UF.add fresh) >>= fun () -> + set_repr fresh (Base_type {repr = None; comparable = Unconstrained}) + >>= fun () -> return (Type.var fresh) + +let exists_cmp : unit -> Type.Base.t M.t = + let open M in + fun () -> + let fresh = fresh () in + uf_lift (UF.add fresh) >>= fun () -> + set_repr fresh (Base_type {repr = None; comparable = Comparable}) + >>= fun () -> return (Type.var fresh) + +(* Adapted from [script_ir_translator] *) +let parse_uint30 n : int = + let max_uint30 = 0x3fffffff in + match n with + | Micheline.Int (_, n') + when Compare.Z.(Z.zero <= n') && Compare.Z.(n' <= Z.of_int max_uint30) -> + Z.to_int n' + | _ -> assert false + +(* encodes the per-instruction relationship between input and output types + of binary arithmetic operations. *) +let arith_type (instr : Mikhailsky_prim.prim) (ty1 : Type.Base.t) + (ty2 : Type.Base.t) : Type.Base.t option = + match (instr, ty1.node, ty2.node) with + | ((I_ADD | I_MUL), Int_t, Int_t) + | ((I_ADD | I_MUL), Int_t, Nat_t) + | ((I_ADD | I_MUL), Nat_t, Int_t) -> + Some Type.int + | ((I_ADD | I_MUL), Nat_t, Nat_t) -> Some Type.nat + | (I_SUB, Int_t, Int_t) + | (I_SUB, Int_t, Nat_t) + | (I_SUB, Nat_t, Int_t) + | (I_SUB, Nat_t, Nat_t) + | (I_SUB, Timestamp_t, Timestamp_t) -> + Some Type.int + | (I_EDIV, Int_t, Int_t) + | (I_EDIV, Int_t, Nat_t) + | (I_EDIV, Nat_t, Int_t) + | (I_EDIV, Nat_t, Nat_t) -> + Some Type.(option (pair nat nat)) + (* Timestamp *) + | (I_ADD, Timestamp_t, Int_t) + | (I_ADD, Int_t, Timestamp_t) + | (I_SUB, Timestamp_t, Int_t) -> + Some Type.timestamp + (* Mutez *) + | (I_ADD, Mutez_t, Mutez_t) + | (I_SUB, Mutez_t, Mutez_t) + | (I_MUL, Mutez_t, Nat_t) + | (I_MUL, Nat_t, Mutez_t) -> + Some Type.mutez + | (I_EDIV, Mutez_t, Nat_t) -> Some Type.(option (pair mutez mutez)) + | (I_EDIV, Mutez_t, Mutez_t) -> Some Type.(option (pair nat mutez)) + | _ -> None + +let rec generate_constraints (path : Mikhailsky.Path.t) (node : Mikhailsky.node) + (bef : Type.Stack.t) (aft : Type.Stack.t) : unit M.t = + let open M in + set_instr_annot path {bef; aft} >>= fun () -> + match node with + | Int (_, _) -> + assert false (* Ints should always be guarded by annotations *) + | String (_, _) | Bytes (_, _) -> + raise (Ill_typed_script Expected_micheline_prim) + (* Hole *) + | Prim (_, I_Hole, [], _) -> return () + (* Stack ops - simple cases *) + | Prim (_loc, I_DROP, [], _annot) -> + exists () >>= fun top -> unify bef (Type.item top aft) + | Prim (_loc, I_DROP, [n], _annot) -> + let n = parse_uint30 n in + generate_constraints_dropn n bef aft + | Prim (_loc, I_DUP, [], _annot) -> + exists () >>= fun top -> + exists_stack () >>= fun rest -> + unify bef Type.(item top rest) >>= fun () -> + unify aft Type.(item top (item top rest)) + | Prim (_loc, I_SWAP, [], _annot) -> + exists () >>= fun a -> + exists () >>= fun b -> + exists_stack () >>= fun rest -> + unify bef Type.(item a (item b rest)) >>= fun () -> + unify aft Type.(item b (item a rest)) + | Prim (_loc, I_PUSH, [t; d], _annot) -> + let ty = + Mikhailsky.parse_ty + ~allow_big_map:false + ~allow_operation:false + ~allow_contract:false + t + in + generate_constraints_data (Mikhailsky.Path.at_index 1 path) d ty + >>= fun () -> + (* assert_data_has_ground_type (Mikhailsky.Path.at_index 1 path) d ty >>= fun () -> *) + unify aft Type.(item ty bef) + | Prim (_loc, I_UNIT, [], _annot) -> unify aft Type.(item unit bef) + | Prim (_loc, I_DIP, [code], _annot) -> + exists () >>= fun top -> + exists_stack () >>= fun bef_rest -> + exists_stack () >>= fun aft_rest -> + unify bef Type.(item top bef_rest) >>= fun () -> + unify aft Type.(item top aft_rest) >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 0 path) + code + bef_rest + aft_rest + (* TODO: DIGn, etc *) + (* Option-related instructions *) + | Prim (_, I_SOME, [], _) -> + exists () >>= fun top -> + exists_stack () >>= fun rest -> + unify bef Type.(item top rest) >>= fun () -> + unify aft Type.(item (option top) rest) + | Prim (_, I_NONE, [t], _) -> + let ty = + Mikhailsky.parse_ty + ~allow_big_map:true + ~allow_operation:true + ~allow_contract:true + t + in + unify aft Type.(item (option ty) bef) + | Prim (_, I_IF_NONE, [bt; bf], _) -> + exists () >>= fun a -> + exists_stack () >>= fun rest -> + unify bef Type.(item (option a) rest) >>= fun () -> + generate_constraints (Mikhailsky.Path.at_index 0 path) bt rest aft + >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 1 path) + bf + Type.(item a rest) + aft + (* bool-based control flow *) + | Prim (_, I_IF, [bt; bf], _) -> + exists_stack () >>= fun rest -> + unify bef Type.(item bool rest) >>= fun () -> + generate_constraints (Mikhailsky.Path.at_index 0 path) bt rest aft + >>= fun () -> + generate_constraints (Mikhailsky.Path.at_index 1 path) bf rest aft + | Prim (_, I_LOOP, [body], _) -> + unify bef Type.(item bool aft) >>= fun () -> + generate_constraints (Mikhailsky.Path.at_index 0 path) body aft bef + (* Boolean binops *) + | Prim (_, I_AND, [], _) | Prim (_, I_OR, [], _) | Prim (_, I_XOR, [], _) -> + exists_stack () >>= fun rest -> + unify bef Type.(item bool (item bool rest)) >>= fun () -> + unify aft Type.(item bool rest) + (* Arithmetic *) + | Prim (_, ((I_ADD | I_SUB | I_MUL | I_EDIV) as instr), [ty1; ty2], _) -> ( + let ty1 = + Mikhailsky.parse_ty + ~allow_big_map:false + ~allow_operation:false + ~allow_contract:false + ty1 + in + let ty2 = + Mikhailsky.parse_ty + ~allow_big_map:false + ~allow_operation:false + ~allow_contract:false + ty2 + in + match arith_type instr ty1 ty2 with + | None -> + raise (Ill_typed_script (Badly_typed_arithmetic (instr, ty1, ty2))) + | Some ret -> + exists_stack () >>= fun rest -> + unify bef Type.(item ty1 (item ty2 rest)) >>= fun () -> + unify aft Type.(item ret rest)) + | Prim (_, (I_ADD | I_SUB | I_MUL | I_EDIV), _, _) -> + raise (Ill_typed_script (Ill_formed_arithmetic (path, node))) + | Prim (_, I_COMPARE, [], _) -> + exists_cmp () >>= fun a -> + exists_stack () >>= fun rest -> + unify bef Type.(item a (item a rest)) >>= fun () -> + unify aft Type.(item int rest) + | Prim (_, I_ABS, [], _) -> + exists_stack () >>= fun rest -> + unify bef Type.(item int rest) >>= fun () -> + unify aft Type.(item nat rest) + | Prim (_, I_GT, [], _) -> + exists_stack () >>= fun rest -> + unify bef Type.(item int rest) >>= fun () -> + unify aft Type.(item bool rest) + (* Strings/bytes *) + | Prim (_, I_CONCAT, [], _) -> + exists_stack () >>= fun rest -> + unify bef Type.(item string (item string rest)) >>= fun () -> + unify aft Type.(item string rest) + | Prim (_, I_SIZE_STRING, [], _) -> + exists_stack () >>= fun rest -> + unify bef Type.(item string rest) >>= fun () -> + unify aft Type.(item nat rest) + | Prim (_, I_SIZE_BYTES, [], _) -> + exists_stack () >>= fun rest -> + unify bef Type.(item bytes rest) >>= fun () -> + unify aft Type.(item nat rest) + (* Crypto *) + | Prim (_, I_SHA256, [], _) + | Prim (_, I_SHA512, [], _) + | Prim (_, I_BLAKE2B, [], _) -> + exists_stack () >>= fun rest -> + unify bef Type.(item bytes rest) >>= fun () -> + unify aft Type.(item bytes rest) + | Prim (_, I_HASH_KEY, [], _) -> + exists_stack () >>= fun rest -> + unify bef Type.(item key rest) >>= fun () -> + unify aft Type.(item key_hash rest) + (* sets *) + | Prim (_, I_EMPTY_SET, [], _) -> + exists_cmp () >>= fun cmpty -> unify aft Type.(item (set cmpty) bef) + | Prim (_, I_UPDATE_SET, [], _) -> + exists_cmp () >>= fun cty -> + exists_stack () >>= fun rest -> + unify bef Type.(item cty (item bool (item (set cty) rest))) >>= fun () -> + unify aft Type.(item (set cty) rest) + | Prim (_, I_SIZE_SET, [], _) -> + exists_cmp () >>= fun cmpty -> + exists_stack () >>= fun rest -> + unify bef Type.(item (set cmpty) rest) >>= fun () -> + unify aft Type.(item nat rest) + | Prim (_, I_ITER_SET, [code], _) -> + exists_cmp () >>= fun cmpty -> + unify bef Type.(item (set cmpty) aft) >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 0 path) + code + Type.(item cmpty aft) + aft + | Prim (_, I_MEM_SET, [], _) -> + exists_cmp () >>= fun cmpty -> + exists_stack () >>= fun rest -> + unify bef Type.(item cmpty (item (set cmpty) rest)) >>= fun () -> + unify aft Type.(item bool rest) + (* maps *) + | Prim (_, I_EMPTY_MAP, [], _) -> + exists_cmp () >>= fun kty -> + exists () >>= fun vty -> unify aft Type.(item (map kty vty) bef) + | Prim (_, I_UPDATE_MAP, [], _) -> + exists_cmp () >>= fun kty -> + exists () >>= fun vty -> + exists_stack () >>= fun rest -> + unify bef Type.(item kty (item (option vty) (item (map kty vty) rest))) + >>= fun () -> unify aft Type.(item (map kty vty) rest) + | Prim (_, I_SIZE_MAP, [], _) -> + exists_cmp () >>= fun kty -> + exists () >>= fun vty -> + exists_stack () >>= fun rest -> + unify bef Type.(item (map kty vty) rest) >>= fun () -> + unify aft Type.(item nat rest) + | Prim (_, I_ITER_MAP, [code], _) -> + exists_cmp () >>= fun kty -> + exists () >>= fun vty -> + unify bef Type.(item (map kty vty) aft) >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 0 path) + code + Type.(item (pair kty vty) aft) + aft + | Prim (_, I_MAP_MAP, [code], _) -> + exists_cmp () >>= fun kty -> + exists () >>= fun vty1 -> + exists () >>= fun vty2 -> + exists_stack () >>= fun rest -> + unify bef Type.(item (map kty vty1) rest) >>= fun () -> + unify aft Type.(item (map kty vty2) rest) >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 0 path) + code + Type.(item (pair kty vty1) rest) + Type.(item vty2 rest) + | Prim (_, I_MEM_MAP, [], _) -> + exists_cmp () >>= fun kty -> + exists () >>= fun vty -> + exists_stack () >>= fun rest -> + unify bef Type.(item kty (item (map kty vty) rest)) >>= fun () -> + unify aft Type.(item bool rest) + | Prim (_, I_GET_MAP, [], _) -> + exists_cmp () >>= fun kty -> + exists () >>= fun vty -> + exists_stack () >>= fun rest -> + unify bef Type.(item kty (item (map kty vty) rest)) >>= fun () -> + unify aft Type.(item (option vty) rest) + (* Pairs *) + | Prim (_, I_PAIR, [], _) -> + exists () >>= fun a -> + exists () >>= fun b -> + exists_stack () >>= fun rest -> + unify bef Type.(item a (item b rest)) >>= fun () -> + unify aft Type.(item (pair a b) rest) + | Prim (_, I_CAR, [], _) -> + exists () >>= fun a -> + exists () >>= fun b -> + exists_stack () >>= fun rest -> + unify bef Type.(item (pair a b) rest) >>= fun () -> + unify aft Type.(item a rest) + | Prim (_, I_CDR, [], _) -> + exists () >>= fun a -> + exists () >>= fun b -> + exists_stack () >>= fun rest -> + unify bef Type.(item (pair a b) rest) >>= fun () -> + unify aft Type.(item b rest) + (* Unions *) + | Prim (_, I_LEFT, [], _) -> + exists () >>= fun lt -> + exists () >>= fun rt -> + exists_stack () >>= fun rest -> + unify bef (Type.item lt rest) >>= fun () -> + unify aft Type.(item (union lt rt) rest) >>= fun res -> return res + | Prim (_, I_RIGHT, [], _) -> + exists () >>= fun lt -> + exists () >>= fun rt -> + exists_stack () >>= fun rest -> + unify bef Type.(item rt rest) >>= fun () -> + unify aft Type.(item (union lt rt) rest) + | Prim (_, (I_LEFT | I_RIGHT), _ :: _, _) -> + invalid_ast ~msg:__LOC__ path node + | Prim (_, I_LOOP_LEFT, [body], _) -> + exists () >>= fun l -> + exists () >>= fun r -> + exists_stack () >>= fun rest -> + unify bef Type.(item (union l r) rest) >>= fun () -> + unify aft Type.(item r rest) >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 0 path) + body + Type.(item l rest) + bef + | Prim (_, I_IF_LEFT, [bt; bf], _) -> + exists () >>= fun a -> + exists () >>= fun b -> + exists_stack () >>= fun rest -> + unify bef Type.(item (union a b) rest) >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 0 path) + bt + (Type.item a rest) + aft + >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 1 path) + bf + (Type.item b rest) + aft + (* lambdas *) + | Prim (_, I_LAMBDA, [code], _) -> + exists () >>= fun dom -> + exists () >>= fun range -> + unify aft Type.(item (lambda dom range) bef) >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 0 path) + code + Type.(item dom empty) + Type.(item range empty) + | Prim (_, I_LAMBDA, _, _) -> invalid_ast ~msg:__LOC__ path node + | Prim (_, I_APPLY, [], _) -> + exists () >>= fun a -> + exists () >>= fun b -> + exists () >>= fun ret -> + exists_stack () >>= fun rest -> + unify bef Type.(item a (item (lambda (pair a b) ret) rest)) >>= fun () -> + unify aft Type.(item (lambda b ret) rest) + | Prim (_, I_EXEC, [], _) -> + exists () >>= fun a -> + exists () >>= fun ret -> + exists_stack () >>= fun rest -> + unify bef Type.(item a (item (lambda a ret) rest)) >>= fun () -> + unify aft Type.(item ret rest) + (* lists *) + | Prim (_, I_NIL, [], _) -> + exists () >>= fun a -> unify aft Type.(item (list a) bef) + | Prim (_, I_CONS, [], _) -> + exists () >>= fun a -> + exists_stack () >>= fun rest -> + unify bef Type.(item a (item (list a) rest)) >>= fun () -> + unify aft Type.(item (list a) rest) + | Prim (_, I_SIZE_LIST, [], _) -> + exists () >>= fun ty -> + exists_stack () >>= fun rest -> + unify bef Type.(item (list ty) rest) >>= fun () -> + unify aft Type.(item nat rest) + | Prim (_, I_ITER_LIST, [code], _) -> + exists () >>= fun ty -> + unify bef Type.(item (list ty) aft) >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 0 path) + code + Type.(item ty aft) + aft + | Prim (_, I_MAP_LIST, [code], _) -> + exists () >>= fun ty1 -> + exists () >>= fun ty2 -> + exists_stack () >>= fun rest -> + unify bef Type.(item (list ty1) rest) >>= fun () -> + unify aft Type.(item (list ty2) rest) >>= fun () -> + generate_constraints + (Mikhailsky.Path.at_index 0 path) + code + Type.(item ty1 rest) + Type.(item ty2 rest) + (* pack/unpack*) + | Prim (_, I_PACK, [], _) -> + exists () >>= fun ty -> + exists_stack () >>= fun rest -> + unify bef Type.(item ty rest) >>= fun () -> + unify aft Type.(item bytes rest) + | Prim (_, I_UNPACK, [], _) -> + exists () >>= fun ty -> + exists_stack () >>= fun rest -> + unify bef Type.(item bytes rest) >>= fun () -> + unify aft Type.(item (option ty) rest) + (* Others *) + | Seq (_, []) -> unify bef aft + | Seq (_, [single]) -> + generate_constraints (Mikhailsky.Path.at_index 0 path) single bef aft + | Seq (_, instrs) -> generate_constraints_seq path 0 instrs bef aft + | _ -> raise (Ill_typed_script (Unhandled_micheline (path, node))) + +and generate_constraints_seq path index instrs bef aft = + let open M in + match instrs with + | [] -> assert false + | [single] -> + generate_constraints (Mikhailsky.Path.at_index index path) single bef aft + | hd :: tl -> + exists_stack () >>= fun stack_ty -> + generate_constraints (Mikhailsky.Path.at_index index path) hd bef stack_ty + >>= fun () -> generate_constraints_seq path (index + 1) tl stack_ty aft + +and generate_constraints_data (path : Mikhailsky.Path.t) + (node : Mikhailsky.node) (ty : Type.Base.t) : unit M.t = + let open M in + set_data_annot path ty >>= fun () -> + match node with + | Prim (_, D_Hole, [], _) -> return () + | Prim (_, D_Unit, [], _) -> unify_base ty Type.unit + | Prim (_, D_True, [], _) | Prim (_, D_False, [], _) -> + unify_base ty Type.bool + | String _ -> unify_base ty Type.string + | Bytes _ -> unify_base ty Type.bytes + | Prim (_, D_Pair, [vl; vr], _) -> + exists () >>= fun lty -> + exists () >>= fun rty -> + generate_constraints_data (Mikhailsky.Path.at_index 0 path) vl lty + >>= fun () -> + generate_constraints_data (Mikhailsky.Path.at_index 1 path) vr rty + >>= fun () -> unify_base ty (Type.pair lty rty) + | Prim (_, D_Left, [term], _) -> + exists () >>= fun lty -> + exists () >>= fun rty -> + generate_constraints_data (Mikhailsky.Path.at_index 0 path) term lty + >>= fun () -> unify_base ty (Type.union lty rty) + | Prim (_, D_Right, [term], _) -> + exists () >>= fun lty -> + exists () >>= fun rty -> + generate_constraints_data (Mikhailsky.Path.at_index 0 path) term rty + >>= fun () -> unify_base ty (Type.union lty rty) + | Prim (_, D_None, [], _) -> + exists () >>= fun elt_ty -> unify_base ty (Type.option elt_ty) + | Prim (_, D_Some, [v], _) -> + exists () >>= fun elt_ty -> + generate_constraints_data (Mikhailsky.Path.at_index 0 path) v elt_ty + >>= fun () -> unify_base ty (Type.option elt_ty) + | Prim (_, A_Int, [Int (_, _)], _) -> unify_base ty Type.int + | Prim (_, A_Nat, [Int (_, _)], _) -> unify_base ty Type.nat + | Prim (_, A_Timestamp, [Int (_, _)], _) -> unify_base ty Type.timestamp + | Prim (_, A_Mutez, [Int (_, _)], _) -> unify_base ty Type.mutez + | Prim (_, A_Key_hash, [Bytes (_, _)], _) -> unify_base ty Type.key_hash + | Prim (_, A_Key, [Bytes (_, _)], _) -> unify_base ty Type.key + | Prim (_, A_List, [Seq (_, subterms)], _) -> + exists () >>= fun elt_ty -> + unify_base ty Type.(list elt_ty) >>= fun () -> + (* path' accounts for the fact that the Seq is hidden under an annot. *) + let path' = Mikhailsky.Path.at_index 0 path in + generate_constraints_data_list path' 0 subterms elt_ty + | Prim (_, A_Set, [Seq (_, subterms)], _) -> + exists_cmp () >>= fun elt_ty -> + unify_base ty Type.(set elt_ty) >>= fun () -> + (* path' accounts for the fact that the Seq is hidden under an annot. *) + let path' = Mikhailsky.Path.at_index 0 path in + generate_constraints_data_set path' 0 subterms elt_ty + | Prim (_, A_Map, [Seq (_, subterms)], _) -> + exists_cmp () >>= fun k_ty -> + exists () >>= fun v_ty -> + unify_base ty Type.(map k_ty v_ty) >>= fun () -> + (* path' accounts for the fact that the Seq is hidden under an annot. *) + let path' = Mikhailsky.Path.at_index 0 path in + generate_constraints_data_map path' 0 subterms k_ty v_ty + | Prim (_, A_Lambda, [(Seq (_, _) as node)], _) -> + exists () >>= fun dom -> + exists () >>= fun range -> + unify_base ty Type.(lambda dom range) >>= fun () -> + let path' = Mikhailsky.Path.at_index 0 path in + let bef = Type.(item dom empty) in + let aft = Type.(item range empty) in + generate_constraints path' node bef aft + | Prim (_, (A_Int | A_Nat | A_List), _, _) -> + invalid_ast ~msg:__LOC__ path node + | Int _ + (* Ints should always be guarded by annotations *) + | Seq (_, _) + (* Lists, sets, maps, lambdas, should always be guarded by annotations *) + | _ -> + invalid_ast ~msg:__LOC__ path node + +(* raise (Ill_typed_script (Invalid_ast (path, node))) *) +and generate_constraints_data_list path index data ty = + let open M in + match data with + | [] -> return () + | hd :: tl -> + let hd_path = Mikhailsky.Path.at_index index path in + generate_constraints_data hd_path hd ty >>= fun () -> + generate_constraints_data_list path (index + 1) tl ty + +and generate_constraints_data_set path index data ty = + let open M in + match data with + | [] -> return () + | hd :: tl -> + let hd_path = Mikhailsky.Path.at_index index path in + generate_constraints_data hd_path hd ty >>= fun () -> + generate_constraints_data_list path (index + 1) tl ty + +and generate_constraints_data_map path index data k_ty v_ty = + let open M in + match data with + | [] -> return () + | elt :: tl -> ( + let elt_path = Mikhailsky.Path.at_index index path in + match elt with + | Prim (_, D_Elt, [k; v], _) -> + let k_path = Mikhailsky.Path.at_index 0 elt_path in + generate_constraints_data k_path k k_ty >>= fun () -> + let v_path = Mikhailsky.Path.at_index 1 elt_path in + generate_constraints_data v_path v v_ty >>= fun () -> + generate_constraints_data_map path (index + 1) tl k_ty v_ty + | _ -> invalid_ast ~msg:__LOC__ elt_path elt) + +and generate_constraints_dropn n bef aft = + let open M in + if n = 0 then unify bef aft + else + exists () >>= fun top -> + generate_constraints_dropn (n - 1) bef (Type.item top aft) + +let infer_with_state (node : Mikhailsky.node) : + (Type.Stack.t * Type.Stack.t) * state = + let open M in + ( exists_stack () >>= fun bef -> + exists_stack () >>= fun aft -> + generate_constraints Mikhailsky.Path.root node bef aft >>= fun () -> + instantiate bef >>= fun bef -> + instantiate aft >>= fun aft -> return (bef, aft) ) + (M.empty ()) + +let infer (node : Mikhailsky.node) : Type.Stack.t * Type.Stack.t = + fst (infer_with_state node) + +let infer_data_with_state (node : Mikhailsky.node) : Type.Base.t * state = + let open M in + ( exists () >>= fun ty -> + generate_constraints_data Mikhailsky.Path.root node ty >>= fun () -> + instantiate_base ty >>= fun ty -> return ty ) + (M.empty ()) + +let infer_data (node : Mikhailsky.node) : Type.Base.t = + fst (infer_data_with_state node) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/inference.mli b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/inference.mli new file mode 100644 index 000000000000..e44d83fab069 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/inference.mli @@ -0,0 +1,145 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Errors and their pretty-printing function *) +type inference_error + +exception Ill_typed_script of inference_error + +val pp_inference_error : Format.formatter -> inference_error -> unit + +(** Comparability tag. *) +type comparability = Comparable | Not_comparable | Unconstrained + +(** Michelson types. *) +type michelson_type = + | Base_type of {repr : Type.Base.t option; comparable : comparability} + | Stack_type of Type.Stack.t option + +type transformer = {bef : Type.Stack.t; aft : Type.Stack.t} + +(** State of the type inference module *) + +(** Store implementation for type representatives *) +module Repr_store : Stores.S with type key = int and type value = michelson_type + +(** State monad built on [Repr_store] *) +module Repr_sm : + Monads.State_sig + with type state = Repr_store.state + and type key = int + and type value = michelson_type + +(** Store implementation for instruction type representatives *) +module Annot_instr_store : + Stores.S with type key = Mikhailsky.Path.t and type value = transformer + +(** State monad handling annotations on instructions *) +module Annot_instr_sm : + Monads.State_sig + with type state = Annot_instr_store.state + and type value = transformer + and type key = Mikhailsky.Path.t + +(** Store implementation for data type representatives *) +module Annot_data_store : + Stores.S with type key = Mikhailsky.Path.t and type value = Type.Base.t + +(** State monad handling annotations on data *) +module Annot_data_sm : + Monads.State_sig + with type state = Annot_data_store.state + and type value = Type.Base.t + and type key = Mikhailsky.Path.t + +(** State of the inference module *) +type state = { + uf : Uf.UF.M.state; + repr : Repr_sm.state; + annot_instr : Annot_instr_sm.state; + annot_data : Annot_data_sm.state; +} + +(** State monad of the inference module. *) +module M : sig + type 'a t = state -> 'a * state + + val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t + + val empty : unit -> state + + val return : 'a -> 'a t + + val set_repr : int -> michelson_type -> unit t + + val get_repr_exn : int -> michelson_type t + + val get_instr_annot : Annot_data_sm.key -> transformer option t + + val get_data_annot : Annot_data_sm.key -> Type.Base.t option t + + val uf_lift : 'a Uf.UF.M.t -> 'a t + + val repr_lift : 'a Repr_sm.t -> 'a t + + val annot_instr_lift : 'a Annot_instr_sm.t -> 'a t + + val annot_data_lift : 'a Annot_data_sm.t -> 'a t + + val get_state : state t +end + +(** Unifies two stack types. *) +val unify : Type.Stack.t -> Type.Stack.t -> unit M.t + +(** Unifies two base types. *) +val unify_base : Type.Base.t -> Type.Base.t -> unit M.t + +(** Instantiate type variables with the associated terms in a base type. *) +val instantiate_base : Type.Base.t -> Type.Base.t M.t + +(** Instantiate type variables with the associated terms in a stack type. *) +val instantiate : Type.Stack.t -> Type.Stack.t M.t + +(** Get comparability flag for a base type. *) +val get_comparability : Type.Base.t -> comparability M.t + +(** Performs inference on the given Mikhailsky term and returns + its type (as a pair of [before] and [after] stack) as well as the + inference engine state. *) +val infer_with_state : Mikhailsky.node -> (Type.Stack.t * Type.Stack.t) * state + +(** Performs inference on the given Mikhailsky term and throws + the inference engine state away. *) +val infer : Mikhailsky.node -> Type.Stack.t * Type.Stack.t + +(** Performs inference on a piece of Mikhailsky [data] and + returns the inference engine state along the inferred type. *) +val infer_data_with_state : Mikhailsky.node -> Type.Base.t * state + +(** Performs inference on a piece of Mikhailsky [data] and + returns the inferred type, throwing the inference engine + state away. *) +val infer_data : Mikhailsky.node -> Type.Base.t diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/int_map.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/int_map.ml new file mode 100644 index 000000000000..e9b05fe91caa --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/int_map.ml @@ -0,0 +1,26 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Map.Make (Compare.Int) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky.ml new file mode 100644 index 000000000000..a015381180a0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky.ml @@ -0,0 +1,422 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +exception Term_contains_holes + +module Mikhailsky_signature : Signature.S with type t = Mikhailsky_prim.prim = +struct + type t = Mikhailsky_prim.prim + + let compare (x : t) (y : t) = Stdlib.compare x y + + let hash (x : t) = Hashtbl.hash x + + let pp = Mikhailsky_prim.pp +end + +include + Micheline_with_hash_consing.Make + (Mikhailsky_signature) + (struct + let initial_size = None + end) + +module Path = Path.With_hash_consing (struct + let initial_size = None +end) + +(* Prints a Mikhailsky term. *) +let pp fmt node = + let canonical = Micheline.strip_locations node in + let printable = + Micheline_printer.printable Mikhailsky_prim.string_of_prim canonical + in + Micheline_printer.print_expr fmt printable + +let to_string node = + pp Format.str_formatter node ; + Format.flush_str_formatter () + +(* Adapted from Script_ir_translator.parse_ty *) +let rec parse_ty : + allow_big_map:bool -> + allow_operation:bool -> + allow_contract:bool -> + node -> + Type.Base.t = + fun ~allow_big_map ~allow_operation ~allow_contract node -> + match node with + | Prim (_loc, T_unit, [], _annot) -> Type.unit + | Prim (_loc, T_int, [], _annot) -> Type.int + | Prim (_loc, T_nat, [], _annot) -> Type.nat + | Prim (_loc, T_string, [], _annot) -> Type.string + | Prim (_loc, T_bytes, [], _annot) -> Type.bytes + | Prim (_loc, T_bool, [], _annot) -> Type.bool + | Prim (_loc, T_key_hash, [], _annot) -> Type.key_hash + | Prim (_loc, T_timestamp, [], _annot) -> Type.timestamp + | Prim (_loc, T_mutez, [], _annot) -> Type.mutez + | Prim (_loc, T_option, [ut], _annot) -> + let ty = parse_ty ~allow_big_map ~allow_operation ~allow_contract ut in + Type.option ty + | Prim (_loc, T_pair, [utl; utr], _annot) -> + let lty = parse_ty ~allow_big_map ~allow_operation ~allow_contract utl in + let rty = parse_ty ~allow_big_map ~allow_operation ~allow_contract utr in + Type.pair lty rty + | Prim (_loc, T_or, [utl; utr], _annot) -> + let lty = parse_ty ~allow_big_map ~allow_operation ~allow_contract utl in + let rty = parse_ty ~allow_big_map ~allow_operation ~allow_contract utr in + Type.union lty rty + | Prim (_loc, T_set, [ut], _annot) -> + let ut = parse_ty ~allow_big_map ~allow_operation ~allow_contract ut in + Type.set ut + | Prim (_loc, T_map, [uta; utb], _annot) -> + let uta = parse_ty ~allow_big_map ~allow_operation ~allow_contract uta in + let utb = parse_ty ~allow_big_map ~allow_operation ~allow_contract utb in + Type.map uta utb + | Prim (_loc, T_lambda, [dom; range], _annot) -> + let dom = parse_ty ~allow_big_map ~allow_operation ~allow_contract dom in + let range = + parse_ty ~allow_big_map ~allow_operation ~allow_contract range + in + Type.lambda dom range + | Prim (_loc, T_list, [elt], _annot) -> + let elt = parse_ty ~allow_big_map ~allow_operation ~allow_contract elt in + Type.list elt + | _ -> + let s = to_string node in + Stdlib.failwith ("Mikhailsky.parse_ty: could not parse " ^ s) + +exception Term_has_variables + +exception Ill_formed_mikhailsky + +let rec map_var f (x : Type.Base.t) = + match x.node with + | Unit_t -> prim T_unit [] [] + | Var_t v -> f v + | Int_t -> prim T_int [] [] + | Nat_t -> prim T_nat [] [] + | Bool_t -> prim T_bool [] [] + | String_t -> prim T_string [] [] + | Bytes_t -> prim T_bytes [] [] + | Key_hash_t -> prim T_key_hash [] [] + | Timestamp_t -> prim T_timestamp [] [] + | Mutez_t -> prim T_mutez [] [] + | Key_t -> prim T_key [] [] + | Option_t ty -> + let mty = map_var f ty in + prim T_option [mty] [] + | Pair_t (lty, rty) -> + let lty = map_var f lty in + let rty = map_var f rty in + prim T_pair [lty; rty] [] + | Union_t (lty, rty) -> + let lty = map_var f lty in + let rty = map_var f rty in + prim T_or [lty; rty] [] + | List_t ty -> + let mty = map_var f ty in + prim T_list [mty] [] + | Set_t ty -> + let mty = map_var f ty in + prim T_set [mty] [] + | Map_t (kty, vty) -> + let mkty = map_var f kty in + let mvty = map_var f vty in + prim T_map [mkty; mvty] [] + | Lambda_t (dom, range) -> + let dom = map_var f dom in + let range = map_var f range in + prim T_lambda [dom; range] [] + +let unparse_ty_exn (x : Type.Base.t) = + map_var (fun _ -> raise Term_has_variables) x + +let unparse_ty (x : Type.Base.t) = + try Some (unparse_ty_exn x) with Term_has_variables -> None + +(* Exports a Mikhailsky term to Michelson. Fails if term contains holes. + Erases annotations, introduces types where missing. *) +let rec to_michelson (n : node) = + match n with + | Micheline.Int (_, i) -> Micheline.Int (0, i) + | Micheline.Prim (_, head, [term], _) + when Mikhailsky_prim.kind head = Annot_kind && head <> A_Lambda -> + to_michelson term + | Micheline.Prim (_, I_Hole, _, _) -> raise Term_contains_holes + | Micheline.Prim (_, D_Hole, _, _) -> raise Term_contains_holes + | Micheline.Prim (_, head, subterms, annots) -> + let head = Mikhailsky_prim.to_michelson head in + Micheline.Prim (0, head, List.map to_michelson subterms, annots) + | Micheline.String (_, s) -> Micheline.String (0, s) + | Micheline.Bytes (_, b) -> Micheline.Bytes (0, b) + | Micheline.Seq (_, subterms) -> + Micheline.Seq (0, List.map to_michelson subterms) + +let to_michelson (n : node) : Script_repr.expr = + Micheline.strip_locations (to_michelson n) + +let rec size : node -> int = + fun node -> + match node with + | Micheline.Int (_, _) -> 1 + | Micheline.String (_, _) -> 1 + | Micheline.Bytes (_, _) -> 1 + | Micheline.Prim (_, _, subterms, _) -> + List.fold_left (fun acc n -> acc + size n) 1 subterms + | Micheline.Seq (_, subterms) -> + List.fold_left (fun acc n -> acc + size n) 1 subterms + +let instr_hole = prim I_Hole [] [] + +let data_hole = prim D_Hole [] [] + +(* types *) +let unit_ty = prim T_unit [] [] + +let bool_ty = prim T_bool [] [] + +let int_ty = prim T_int [] [] + +let nat_ty = prim T_nat [] [] + +let string_ty = prim T_string [] [] + +let bytes_ty = prim T_bytes [] [] + +let key_hash_ty = prim T_key_hash [] [] + +let option_ty x = prim T_option [x] [] + +let list_ty x = prim T_list [x] [] + +(* Unique identifier provided by hash-consing Micheline terms. *) +let tag node = + let l = label node in + l.tag + +(* hash of term *) +let hash node = + let l = label node in + l.hash + +module Instructions = struct + (* arithmetic *) + + let add ty1 ty2 = prim I_ADD [ty1; ty2] [] + + let sub ty1 ty2 = prim I_SUB [ty1; ty2] [] + + let mul ty1 ty2 = prim I_MUL [ty1; ty2] [] + + let ediv ty1 ty2 = prim I_EDIV [ty1; ty2] [] + + let abs = prim I_ABS [] [] + + let gt = prim I_GT [] [] + + (* stack ops *) + let push ty v = prim I_PUSH [ty; v] [] + + let dip code = prim I_DIP [seq [code]] [] + + let dup = prim I_DUP [] [] + + let drop = prim I_DROP [] [] + + let dropn n = prim I_DROP [int (Z.of_int n)] [] + + let swap = prim I_SWAP [] [] + + (* crypto *) + let blake2b = prim I_BLAKE2B [] [] + + let sha256 = prim I_SHA256 [] [] + + let sha512 = prim I_SHA512 [] [] + + let hash_key = prim I_HASH_KEY [] [] + + (* control *) + let if_ bt bf = prim I_IF [seq [bt]; seq [bf]] [] + + let if_left bt bf = prim I_IF_LEFT [seq [bt]; seq [bf]] [] + + let if_none bt bf = prim I_IF_NONE [seq [bt]; seq [bf]] [] + + let loop b = prim I_LOOP [seq [b]] [] + + let loop_left b = prim I_LOOP_LEFT [seq [b]] [] + + (* pairs *) + let car = prim I_CAR [] [] + + let cdr = prim I_CDR [] [] + + let pair = prim I_PAIR [] [] + + (* unions *) + + let left = prim I_LEFT [] [] + + let right = prim I_RIGHT [] [] + + (* boolean *) + let and_ = prim I_AND [] [] + + (* compare *) + let compare = prim I_COMPARE [] [] + + (* map/set *) + let empty_set = prim I_EMPTY_SET [] [] + + let update_set = prim I_UPDATE_SET [] [] + + let size_set = prim I_SIZE_SET [] [] + + let iter_set code = prim I_ITER_SET [seq code] [] + + let mem_set = prim I_MEM_SET [] [] + + let empty_map = prim I_EMPTY_MAP [] [] + + let update_map = prim I_UPDATE_MAP [] [] + + let size_map = prim I_SIZE_MAP [] [] + + let iter_map code = prim I_ITER_MAP [seq code] [] + + let map_map code = prim I_MAP_MAP [seq code] [] + + let get_map = prim I_GET_MAP [] [] + + let mem_map = prim I_MEM_MAP [] [] + + (* lists*) + let nil = prim I_NIL [] [] + + let cons = prim I_CONS [] [] + + let size_list = prim I_SIZE_LIST [] [] + + let iter_list code = prim I_ITER_LIST [seq code] [] + + let map_list code = prim I_MAP_LIST [seq code] [] + + (* strings *) + let concat = prim I_CONCAT [] [] + + let size_string = prim I_SIZE_STRING [] [] + + let size_bytes = prim I_SIZE_BYTES [] [] + + (* Lambdas *) + let lambda code = prim I_LAMBDA [seq code] [] + + let exec = prim I_EXEC [] [] + + let apply = prim I_APPLY [] [] + + (* pack/unpack *) + let pack = prim I_PACK [] [] + + let unpack = prim I_UNPACK [] [] + + (* hole *) + let hole = instr_hole +end + +(* value constructors *) +module Data = struct + let unit = prim D_Unit [] [] + + let false_ = prim D_False [] [] + + let true_ = prim D_True [] [] + + let none = prim D_None [] [] + + let some x = prim D_Some [x] [] + + let pair x y = prim D_Pair [x; y] [] + + let left x = prim D_Left [x] [] + + let right x = prim D_Right [x] [] + + let list elts = prim A_List [seq elts] [] + + let set elts = prim A_Set [seq elts] [] + + let map_elt k v = prim D_Elt [k; v] [] + + let map elts = prim A_Map [seq elts] [] + + let timestamp ts = + let z = Protocol.Alpha_context.Script_timestamp.to_zint ts in + prim A_Timestamp [int z] [] + + let mutez (tz : Protocol.Alpha_context.Tez.tez) = + let i = Protocol.Alpha_context.Tez.to_mutez tz in + prim A_Mutez [int (Z.of_int64 i)] [] + + let key_hash kh = + let b = + Data_encoding.Binary.to_bytes_exn + Tezos_crypto.Signature.Public_key_hash.encoding + kh + in + prim A_Key_hash [bytes b] [] + + let key k = + let b = + Data_encoding.Binary.to_bytes_exn + Tezos_crypto.Signature.Public_key.encoding + k + in + prim A_Key [bytes b] [] + + let integer (i : int) = prim A_Int [int (Z.of_int i)] [] + + let natural (i : int) = + assert (i >= 0) ; + prim A_Nat [int (Z.of_int i)] [] + + let big_integer (i : Z.t) = prim A_Int [int i] [] + + let big_natural (i : Z.t) = + assert (Z.geq i Z.zero) ; + prim A_Nat [int i] [] + + let string = string + + let bytes = bytes + + let lambda code = prim A_Lambda [seq code] [] + + let hole = data_hole +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky.mli b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky.mli new file mode 100644 index 000000000000..6285f6a39555 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky.mli @@ -0,0 +1,330 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** Mikhailsky: Michelson in Micheline form, with typed holes and annotations. + Mikhailsky terms are hash-consed. *) + +(** + Michelson code is a hard to type-check and generate incrementally due to + the presence of ambiguous constructs, such as literals + like [{ 1 ; 2 ; 3 }]. Is it a list of ints? of nats? of tez? Or a set? + + Thus, we will work with Mikhailsky, a better behaved version of Michelson + allowing local reconstruction of types. + + Differences wrt Michelson: + + 1. non string/byte literals are explicitly annotated with their head type constructor. + Here is an int i: Prim (_, D_int, [Int i], _) + Here is an nat n: Prim (_, D_nat, [Int i], _) + Here is an list of something: Prim (_, D_list, michelson_list, _) + Here is a set: Prim (_, D_set, michelson_set, _) + Here is a map: Prim (_, D_map, michelson_map, _) + etc. + Projecting back from this language to Michelson is trivial. + + 2. Instructions `LEFT/RIGHT` do not need to carry the type of the other + component of the disjunction. These has to be filled in back when + generating Michelson from Mikhailsky. + + 4. The same holds for the input/output type of a lambda as specified in the + `LAMBDA` instruction. + + 3. Some instructions are annotated with the type on which they operate. + Eg if Prim (_, I_ADD, [], []) is the (ad-hoc polymorphic) addition in Michelson, + we will have the following variants in Mikhailsky: + - Prim (_, I_ADD, [ Prim (_, T_mutez, [], []), + Prim (_, T_mutez, [], []) ], []) for mutez addition + - Prim (_, I_ADD, [ Prim (_, T_int, [], []), + Prim (_, T_nat, [], []) ], []) for int+nat addition + etc. +*) + +(** The signature of Mikhailsky terms. *) +module Mikhailsky_signature : Signature.S with type t = Mikhailsky_prim.prim + +(** Elements of type [Path.t] allow to index subterms of Mikhailsky terms. *) +module Path : Path.S + +(** The following types correspond to those provided when instantiating the + functor [Micheline_with_hash_consing.Make] on [Mikhailsky_signature]. *) +type label = Micheline_with_hash_consing.hcons_info + +type head = Mikhailsky_signature.t + +type node = (label, head) Micheline.node + +exception Term_contains_holes + +exception Ill_formed_mikhailsky + +(** [parse_ty] returns a type from a Mikhailsky term. *) +val parse_ty : + allow_big_map:bool -> + allow_operation:bool -> + allow_contract:bool -> + node -> + Type.Base.t + +(** [map_var f x] maps the function f on all variables contained + in the type [x]. *) +val map_var : (int -> node) -> Type.Base.t -> node + +(** [unparse_ty] returns a Mikhailsky term representing a type. *) +val unparse_ty_exn : Type.Base.t -> node + +val unparse_ty : Type.Base.t -> node option + +(** Extracts a Michelson term from a Mikhailsky one. Raises + [Term_contains_holes] if it cannot be done. *) +val to_michelson : node -> Script_repr.expr + +(** Pretty printer. *) +val pp : Format.formatter -> node -> unit + +val to_string : node -> string + +(** Returns the number of nodes of a Mikhailsky term. *) +val size : node -> int + +(** Micheline generic constructors *) +val prim : Mikhailsky_prim.prim -> node list -> string list -> node + +val seq : node list -> node + +val string : string -> node + +val bytes : Bytes.t -> node + +(** Mikhailsky smart constructors*) + +(** Holes *) +val instr_hole : node + +val data_hole : node + +(** Types *) +val unit_ty : node + +val int_ty : node + +val nat_ty : node + +val bool_ty : node + +val string_ty : node + +val bytes_ty : node + +val key_hash_ty : node + +val option_ty : node -> node + +val list_ty : node -> node + +(** Project unique tag out of Mikhailsky node *) +val tag : node -> int + +(** Project hash out of Mikhailsky node *) +val hash : node -> int + +(** Instructions *) +module Instructions : sig + (** Arithmetic. Binary operations take the input types as extra arguments. *) + val add : node -> node -> node + + val sub : node -> node -> node + + val mul : node -> node -> node + + val ediv : node -> node -> node + + val abs : node + + val gt : node + + (** Stack *) + val push : node -> node -> node + + val dip : node -> node + + val dup : node + + val drop : node + + val dropn : int -> node + + val swap : node + + (** Crypto *) + val blake2b : node + + val sha256 : node + + val sha512 : node + + val hash_key : node + + (** Control *) + val if_ : node -> node -> node + + val if_left : node -> node -> node + + val if_none : node -> node -> node + + val loop : node -> node + + val loop_left : node -> node + + (** Pairs *) + val car : node + + val cdr : node + + val pair : node + + (** Unions *) + val left : node + + val right : node + + (** Booleans *) + val and_ : node + + (** Compare *) + val compare : node + + (** Set/Map *) + val empty_set : node + + val update_set : node + + val size_set : node + + val iter_set : node list -> node + + val mem_set : node + + val empty_map : node + + val update_map : node + + val size_map : node + + val iter_map : node list -> node + + val map_map : node list -> node + + val get_map : node + + val mem_map : node + + (** Lists *) + val nil : node + + val cons : node + + val size_list : node + + val iter_list : node list -> node + + val map_list : node list -> node + + (** Strings/bytes *) + val concat : node + + val size_string : node + + val size_bytes : node + + (** Lambdas *) + val lambda : node list -> node + + val exec : node + + val apply : node + + (** pack/unpack *) + + val pack : node + + val unpack : node + + (** Hole *) + val hole : node +end + +(** data *) +module Data : sig + val unit : node + + val false_ : node + + val true_ : node + + val none : node + + val some : node -> node + + val pair : node -> node -> node + + val left : node -> node + + val right : node -> node + + val list : node list -> node + + val set : node list -> node + + val map_elt : node -> node -> node + + val map : node list -> node + + val timestamp : Alpha_context.Script_timestamp.t -> node + + val mutez : Alpha_context.Tez.t -> node + + val key_hash : Tezos_crypto.Signature.Public_key_hash.t -> node + + val key : Tezos_crypto.Signature.Public_key.t -> node + + val integer : int -> node + + val natural : int -> node + + val big_integer : Z.t -> node + + val big_natural : Z.t -> node + + val string : string -> node + + val bytes : Bytes.t -> node + + val lambda : node list -> node + + val hole : node +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky_prim.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky_prim.ml new file mode 100644 index 000000000000..b1b2fb140616 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/mikhailsky_prim.ml @@ -0,0 +1,570 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** Mikhailsky primitives correspond to Michelson primitives plus special + "holes" for instructions and data. *) + +type prim = + | K_parameter + | K_storage + | K_code + | D_False + | D_Elt + | D_Left + | D_None + | D_Pair + | D_Right + | D_Some + | D_True + | D_Unit + | I_PACK + | I_UNPACK + | I_BLAKE2B + | I_SHA256 + | I_SHA512 + | I_ABS + | I_ADD + | I_AMOUNT + | I_AND + | I_BALANCE + | I_CAR + | I_CDR + | I_CHAIN_ID + | I_CHECK_SIGNATURE + | I_COMPARE + | I_CONCAT + | I_CONS + | I_CREATE_ACCOUNT + | I_CREATE_CONTRACT + | I_IMPLICIT_ACCOUNT + | I_DIP + | I_DROP + | I_DUP + | I_EDIV + | I_EMPTY_BIG_MAP + | I_EMPTY_MAP + | I_EMPTY_SET + | I_EQ + | I_EXEC + | I_APPLY + | I_FAILWITH + | I_GE + | I_GET_MAP + | I_GET_AND_UPDATE_MAP + | I_GT + | I_HASH_KEY + | I_IF + | I_IF_CONS + | I_IF_LEFT + | I_IF_NONE + | I_INT + | I_LAMBDA + | I_LE + | I_LEFT + | I_LOOP + | I_LSL + | I_LSR + | I_LT + | I_MAP_MAP + | I_MAP_LIST + | I_MEM_SET + | I_MEM_MAP + | I_MUL + | I_NEG + | I_NEQ + | I_NIL + | I_NONE + | I_NOT + | I_NOW + | I_OR + | I_PAIR + | I_UNPAIR + | I_PUSH + | I_RIGHT + | I_SIZE_SET + | I_SIZE_MAP + | I_SIZE_LIST + | I_SIZE_STRING + | I_SIZE_BYTES + | I_SOME + | I_SOURCE + | I_SENDER + | I_SELF + | I_SLICE + | I_STEPS_TO_QUOTA + | I_SUB + | I_SWAP + | I_TRANSFER_TOKENS + | I_SET_DELEGATE + | I_UNIT + | I_UPDATE_SET + | I_UPDATE_MAP + | I_XOR + | I_ITER_MAP + | I_ITER_LIST + | I_ITER_SET + | I_LOOP_LEFT + | I_ADDRESS + | I_CONTRACT + | I_ISNAT + | I_CAST + | I_RENAME + | I_DIG + | I_DUG + | I_LEVEL + | I_SELF_ADDRESS + | I_NEVER + | I_SAPLING_EMPTY_STATE + | I_SAPLING_VERIFY_UPDATE + | I_VOTING_POWER + | I_TOTAL_VOTING_POWER + | I_KECCAK + | I_SHA3 + | I_PAIRING_CHECK + | I_TICKET + | I_READ_TICKET + | I_SPLIT_TICKET + | I_JOIN_TICKETS + | T_bool + | T_contract + | T_int + | T_key + | T_key_hash + | T_lambda + | T_list + | T_map + | T_big_map + | T_nat + | T_option + | T_or + | T_pair + | T_set + | T_signature + | T_string + | T_bytes + | T_mutez + | T_timestamp + | T_unit + | T_operation + | T_address + | T_chain_id + | T_never + | T_sapling_state + | T_sapling_transaction + | T_bls12_381_g1 + | T_bls12_381_g2 + | T_bls12_381_fr + | T_ticket + (* Holes in programs and data. *) + | I_Hole + | D_Hole + (* Annotations. *) + | A_Int + | A_Nat + | A_Timestamp + | A_Mutez + | A_Key_hash + | A_Key + | A_List + | A_Set + | A_Map + | A_Lambda + +let relation = + [ + (K_parameter, Michelson_v1_primitives.K_parameter); + (K_storage, Michelson_v1_primitives.K_storage); + (K_code, Michelson_v1_primitives.K_code); + (D_False, Michelson_v1_primitives.D_False); + (D_Elt, Michelson_v1_primitives.D_Elt); + (D_Left, Michelson_v1_primitives.D_Left); + (D_None, Michelson_v1_primitives.D_None); + (D_Pair, Michelson_v1_primitives.D_Pair); + (D_Right, Michelson_v1_primitives.D_Right); + (D_Some, Michelson_v1_primitives.D_Some); + (D_True, Michelson_v1_primitives.D_True); + (D_Unit, Michelson_v1_primitives.D_Unit); + (I_PACK, Michelson_v1_primitives.I_PACK); + (I_UNPACK, Michelson_v1_primitives.I_UNPACK); + (I_BLAKE2B, Michelson_v1_primitives.I_BLAKE2B); + (I_SHA256, Michelson_v1_primitives.I_SHA256); + (I_SHA512, Michelson_v1_primitives.I_SHA512); + (I_ABS, Michelson_v1_primitives.I_ABS); + (I_ADD, Michelson_v1_primitives.I_ADD); + (I_AMOUNT, Michelson_v1_primitives.I_AMOUNT); + (I_AND, Michelson_v1_primitives.I_AND); + (I_BALANCE, Michelson_v1_primitives.I_BALANCE); + (I_CAR, Michelson_v1_primitives.I_CAR); + (I_CDR, Michelson_v1_primitives.I_CDR); + (I_CHAIN_ID, Michelson_v1_primitives.I_CHAIN_ID); + (I_CHECK_SIGNATURE, Michelson_v1_primitives.I_CHECK_SIGNATURE); + (I_COMPARE, Michelson_v1_primitives.I_COMPARE); + (I_CONCAT, Michelson_v1_primitives.I_CONCAT); + (I_CONS, Michelson_v1_primitives.I_CONS); + (I_CREATE_ACCOUNT, Michelson_v1_primitives.I_CREATE_ACCOUNT); + (I_CREATE_CONTRACT, Michelson_v1_primitives.I_CREATE_CONTRACT); + (I_IMPLICIT_ACCOUNT, Michelson_v1_primitives.I_IMPLICIT_ACCOUNT); + (I_DIP, Michelson_v1_primitives.I_DIP); + (I_DROP, Michelson_v1_primitives.I_DROP); + (I_DUP, Michelson_v1_primitives.I_DUP); + (I_EDIV, Michelson_v1_primitives.I_EDIV); + (I_EMPTY_BIG_MAP, Michelson_v1_primitives.I_EMPTY_BIG_MAP); + (I_EMPTY_MAP, Michelson_v1_primitives.I_EMPTY_MAP); + (I_EMPTY_SET, Michelson_v1_primitives.I_EMPTY_SET); + (I_EQ, Michelson_v1_primitives.I_EQ); + (I_EXEC, Michelson_v1_primitives.I_EXEC); + (I_APPLY, Michelson_v1_primitives.I_APPLY); + (I_FAILWITH, Michelson_v1_primitives.I_FAILWITH); + (I_GE, Michelson_v1_primitives.I_GE); + (I_GET_MAP, Michelson_v1_primitives.I_GET); + (I_GET_AND_UPDATE_MAP, Michelson_v1_primitives.I_GET_AND_UPDATE); + (I_GT, Michelson_v1_primitives.I_GT); + (I_HASH_KEY, Michelson_v1_primitives.I_HASH_KEY); + (I_IF, Michelson_v1_primitives.I_IF); + (I_IF_CONS, Michelson_v1_primitives.I_IF_CONS); + (I_IF_LEFT, Michelson_v1_primitives.I_IF_LEFT); + (I_IF_NONE, Michelson_v1_primitives.I_IF_NONE); + (I_INT, Michelson_v1_primitives.I_INT); + (I_LAMBDA, Michelson_v1_primitives.I_LAMBDA); + (I_LE, Michelson_v1_primitives.I_LE); + (I_LEFT, Michelson_v1_primitives.I_LEFT); + (I_LEVEL, Michelson_v1_primitives.I_LEVEL); + (I_LOOP, Michelson_v1_primitives.I_LOOP); + (I_LSL, Michelson_v1_primitives.I_LSL); + (I_LSR, Michelson_v1_primitives.I_LSR); + (I_LT, Michelson_v1_primitives.I_LT); + (I_MAP_MAP, Michelson_v1_primitives.I_MAP); + (I_MAP_LIST, Michelson_v1_primitives.I_MAP); + (I_MEM_SET, Michelson_v1_primitives.I_MEM); + (I_MEM_MAP, Michelson_v1_primitives.I_MEM); + (I_MUL, Michelson_v1_primitives.I_MUL); + (I_NEG, Michelson_v1_primitives.I_NEG); + (I_NEQ, Michelson_v1_primitives.I_NEQ); + (I_NIL, Michelson_v1_primitives.I_NIL); + (I_NONE, Michelson_v1_primitives.I_NONE); + (I_NOT, Michelson_v1_primitives.I_NOT); + (I_NOW, Michelson_v1_primitives.I_NOW); + (I_OR, Michelson_v1_primitives.I_OR); + (I_PAIR, Michelson_v1_primitives.I_PAIR); + (I_UNPAIR, Michelson_v1_primitives.I_UNPAIR); + (I_PUSH, Michelson_v1_primitives.I_PUSH); + (I_RIGHT, Michelson_v1_primitives.I_RIGHT); + (I_SIZE_SET, Michelson_v1_primitives.I_SIZE); + (I_SIZE_MAP, Michelson_v1_primitives.I_SIZE); + (I_SIZE_LIST, Michelson_v1_primitives.I_SIZE); + (I_SIZE_STRING, Michelson_v1_primitives.I_SIZE); + (I_SIZE_BYTES, Michelson_v1_primitives.I_SIZE); + (I_SOME, Michelson_v1_primitives.I_SOME); + (I_SOURCE, Michelson_v1_primitives.I_SOURCE); + (I_SENDER, Michelson_v1_primitives.I_SENDER); + (I_SELF, Michelson_v1_primitives.I_SELF); + (I_SELF_ADDRESS, Michelson_v1_primitives.I_SELF_ADDRESS); + (I_SLICE, Michelson_v1_primitives.I_SLICE); + (I_STEPS_TO_QUOTA, Michelson_v1_primitives.I_STEPS_TO_QUOTA); + (I_SUB, Michelson_v1_primitives.I_SUB); + (I_SWAP, Michelson_v1_primitives.I_SWAP); + (I_TRANSFER_TOKENS, Michelson_v1_primitives.I_TRANSFER_TOKENS); + (I_SET_DELEGATE, Michelson_v1_primitives.I_SET_DELEGATE); + (I_UNIT, Michelson_v1_primitives.I_UNIT); + (I_UPDATE_SET, Michelson_v1_primitives.I_UPDATE); + (I_UPDATE_MAP, Michelson_v1_primitives.I_UPDATE); + (I_XOR, Michelson_v1_primitives.I_XOR); + (I_ITER_MAP, Michelson_v1_primitives.I_ITER); + (I_ITER_LIST, Michelson_v1_primitives.I_ITER); + (I_ITER_SET, Michelson_v1_primitives.I_ITER); + (I_LOOP_LEFT, Michelson_v1_primitives.I_LOOP_LEFT); + (I_ADDRESS, Michelson_v1_primitives.I_ADDRESS); + (I_CONTRACT, Michelson_v1_primitives.I_CONTRACT); + (I_ISNAT, Michelson_v1_primitives.I_ISNAT); + (I_CAST, Michelson_v1_primitives.I_CAST); + (I_RENAME, Michelson_v1_primitives.I_RENAME); + (I_SAPLING_EMPTY_STATE, Michelson_v1_primitives.I_SAPLING_EMPTY_STATE); + (I_SAPLING_VERIFY_UPDATE, Michelson_v1_primitives.I_SAPLING_VERIFY_UPDATE); + (I_DIG, Michelson_v1_primitives.I_DIG); + (I_DUG, Michelson_v1_primitives.I_DUG); + (I_NEVER, Michelson_v1_primitives.I_NEVER); + (I_VOTING_POWER, Michelson_v1_primitives.I_VOTING_POWER); + (I_TOTAL_VOTING_POWER, Michelson_v1_primitives.I_TOTAL_VOTING_POWER); + (I_KECCAK, Michelson_v1_primitives.I_KECCAK); + (I_SHA3, Michelson_v1_primitives.I_SHA3); + (I_PAIRING_CHECK, Michelson_v1_primitives.I_PAIRING_CHECK); + (I_TICKET, Michelson_v1_primitives.I_TICKET); + (I_READ_TICKET, Michelson_v1_primitives.I_READ_TICKET); + (I_SPLIT_TICKET, Michelson_v1_primitives.I_SPLIT_TICKET); + (I_JOIN_TICKETS, Michelson_v1_primitives.I_JOIN_TICKETS); + (T_bool, Michelson_v1_primitives.T_bool); + (T_contract, Michelson_v1_primitives.T_contract); + (T_int, Michelson_v1_primitives.T_int); + (T_key, Michelson_v1_primitives.T_key); + (T_key_hash, Michelson_v1_primitives.T_key_hash); + (T_lambda, Michelson_v1_primitives.T_lambda); + (T_list, Michelson_v1_primitives.T_list); + (T_map, Michelson_v1_primitives.T_map); + (T_big_map, Michelson_v1_primitives.T_big_map); + (T_nat, Michelson_v1_primitives.T_nat); + (T_option, Michelson_v1_primitives.T_option); + (T_or, Michelson_v1_primitives.T_or); + (T_pair, Michelson_v1_primitives.T_pair); + (T_set, Michelson_v1_primitives.T_set); + (T_signature, Michelson_v1_primitives.T_signature); + (T_string, Michelson_v1_primitives.T_string); + (T_bytes, Michelson_v1_primitives.T_bytes); + (T_mutez, Michelson_v1_primitives.T_mutez); + (T_timestamp, Michelson_v1_primitives.T_timestamp); + (T_unit, Michelson_v1_primitives.T_unit); + (T_operation, Michelson_v1_primitives.T_operation); + (T_address, Michelson_v1_primitives.T_address); + (T_sapling_transaction, Michelson_v1_primitives.T_sapling_transaction); + (T_sapling_state, Michelson_v1_primitives.T_sapling_state); + (T_chain_id, Michelson_v1_primitives.T_chain_id); + (T_never, Michelson_v1_primitives.T_never); + (T_bls12_381_g1, Michelson_v1_primitives.T_bls12_381_g1); + (T_bls12_381_g2, Michelson_v1_primitives.T_bls12_381_g2); + (T_bls12_381_fr, Michelson_v1_primitives.T_bls12_381_fr); + (T_ticket, Michelson_v1_primitives.T_ticket); + ] + +let relation_table = + let table = Hashtbl.create 269 in + List.iter + (fun (mikhailsky, michelson) -> Hashtbl.add table mikhailsky michelson) + relation ; + table + +exception Primitive_cannot_be_cast_back_to_Michelson of prim + +let to_michelson prim = + match Hashtbl.find relation_table prim with + | exception Not_found -> + raise (Primitive_cannot_be_cast_back_to_Michelson prim) + | res -> res + +let string_of_prim prim = + match prim with + | K_parameter -> "K_parameter" + | K_storage -> "K_storage" + | K_code -> "K_code" + | D_False -> "D_False" + | D_Elt -> "D_Elt" + | D_Left -> "D_Left" + | D_None -> "D_None" + | D_Pair -> "D_Pair" + | D_Right -> "D_Right" + | D_Some -> "D_Some" + | D_True -> "D_True" + | D_Unit -> "D_Unit" + | I_PACK -> "I_PACK" + | I_UNPACK -> "I_UNPACK" + | I_BLAKE2B -> "I_BLAKE2B" + | I_SHA256 -> "I_SHA256" + | I_SHA512 -> "I_SHA512" + | I_ABS -> "I_ABS" + | I_ADD -> "I_ADD" + | I_AMOUNT -> "I_AMOUNT" + | I_AND -> "I_AND" + | I_BALANCE -> "I_BALANCE" + | I_CAR -> "I_CAR" + | I_CDR -> "I_CDR" + | I_CHAIN_ID -> "I_CHAIN_ID" + | I_CHECK_SIGNATURE -> "I_CHECK_SIGNATURE" + | I_COMPARE -> "I_COMPARE" + | I_CONCAT -> "I_CONCAT" + | I_CONS -> "I_CONS" + | I_CREATE_ACCOUNT -> "I_CREATE_ACCOUNT" + | I_CREATE_CONTRACT -> "I_CREATE_CONTRACT" + | I_IMPLICIT_ACCOUNT -> "I_IMPLICIT_ACCOUNT" + | I_DIP -> "I_DIP" + | I_DROP -> "I_DROP" + | I_DUP -> "I_DUP" + | I_EDIV -> "I_EDIV" + | I_EMPTY_BIG_MAP -> "I_EMPTY_BIG_MAP" + | I_EMPTY_MAP -> "I_EMPTY_MAP" + | I_EMPTY_SET -> "I_EMPTY_SET" + | I_EQ -> "I_EQ" + | I_EXEC -> "I_EXEC" + | I_APPLY -> "I_APPLY" + | I_FAILWITH -> "I_FAILWITH" + | I_GE -> "I_GE" + | I_GET_MAP -> "I_GET_MAP" + | I_GET_AND_UPDATE_MAP -> "I_GET_AND_UPDATE_MAP" + | I_GT -> "I_GT" + | I_HASH_KEY -> "I_HASH_KEY" + | I_IF -> "I_IF" + | I_IF_CONS -> "I_IF_CONS" + | I_IF_LEFT -> "I_IF_LEFT" + | I_IF_NONE -> "I_IF_NONE" + | I_INT -> "I_INT" + | I_LAMBDA -> "I_LAMBDA" + | I_LE -> "I_LE" + | I_LEFT -> "I_LEFT" + | I_LOOP -> "I_LOOP" + | I_LSL -> "I_LSL" + | I_LSR -> "I_LSR" + | I_LT -> "I_LT" + | I_MAP_MAP -> "I_MAP_MAP" + | I_MAP_LIST -> "I_MAP_LIST" + | I_MEM_SET -> "I_MEM_SET" + | I_MEM_MAP -> "I_MEM_MAP" + | I_MUL -> "I_MUL" + | I_NEG -> "I_NEG" + | I_NEQ -> "I_NEQ" + | I_NIL -> "I_NIL" + | I_NONE -> "I_NONE" + | I_NOT -> "I_NOT" + | I_NOW -> "I_NOW" + | I_OR -> "I_OR" + | I_PAIR -> "I_PAIR" + | I_UNPAIR -> "I_UNPAIR" + | I_PUSH -> "I_PUSH" + | I_RIGHT -> "I_RIGHT" + | I_SIZE_SET -> "I_SIZE_SET" + | I_SIZE_MAP -> "I_SIZE_MAP" + | I_SIZE_LIST -> "I_SIZE_LIST" + | I_SIZE_STRING -> "I_SIZE_STRING" + | I_SIZE_BYTES -> "I_SIZE_BYTES" + | I_SOME -> "I_SOME" + | I_SOURCE -> "I_SOURCE" + | I_SENDER -> "I_SENDER" + | I_SELF -> "I_SELF" + | I_SLICE -> "I_SLICE" + | I_STEPS_TO_QUOTA -> "I_STEPS_TO_QUOTA" + | I_SUB -> "I_SUB" + | I_SWAP -> "I_SWAP" + | I_TRANSFER_TOKENS -> "I_TRANSFER_TOKENS" + | I_SET_DELEGATE -> "I_SET_DELEGATE" + | I_UNIT -> "I_UNIT" + | I_UPDATE_SET -> "I_UPDATE_SET" + | I_UPDATE_MAP -> "I_UPDATE_MAP" + | I_XOR -> "I_XOR" + | I_ITER_MAP -> "I_ITER_MAP" + | I_ITER_LIST -> "I_ITER_LIST" + | I_ITER_SET -> "I_ITER_SET" + | I_LOOP_LEFT -> "I_LOOP_LEFT" + | I_ADDRESS -> "I_ADDRESS" + | I_CONTRACT -> "I_CONTRACT" + | I_ISNAT -> "I_ISNAT" + | I_CAST -> "I_CAST" + | I_RENAME -> "I_RENAME" + | I_DIG -> "I_DIG" + | I_DUG -> "I_DUG" + | I_LEVEL -> "I_LEVEL" + | I_SELF_ADDRESS -> "I_SELF_ADDRESS" + | I_NEVER -> "I_NEVER" + | I_SAPLING_EMPTY_STATE -> "I_SAPLING_EMPTY_STATE" + | I_SAPLING_VERIFY_UPDATE -> "I_SAPLING_VERIFY_UPDATE" + | I_VOTING_POWER -> "I_VOTING_POWER" + | I_TOTAL_VOTING_POWER -> "I_TOTAL_VOTING_POWER" + | I_KECCAK -> "I_KECCAK" + | I_SHA3 -> "I_SHA3" + | I_PAIRING_CHECK -> "I_PAIRING_CHECK" + | I_TICKET -> "I_TICKET" + | I_READ_TICKET -> "I_READ_TICKET" + | I_SPLIT_TICKET -> "I_SPLIT_TICKET" + | I_JOIN_TICKETS -> "I_JOIN_TICKETS" + | T_bool -> "T_bool" + | T_contract -> "T_contract" + | T_int -> "T_int" + | T_key -> "T_key" + | T_key_hash -> "T_key_hash" + | T_lambda -> "T_lambda" + | T_list -> "T_list" + | T_map -> "T_map" + | T_big_map -> "T_big_map" + | T_nat -> "T_nat" + | T_option -> "T_option" + | T_or -> "T_or" + | T_pair -> "T_pair" + | T_set -> "T_set" + | T_signature -> "T_signature" + | T_string -> "T_string" + | T_bytes -> "T_bytes" + | T_mutez -> "T_mutez" + | T_timestamp -> "T_timestamp" + | T_unit -> "T_unit" + | T_operation -> "T_operation" + | T_address -> "T_address" + | T_chain_id -> "T_chain_id" + | T_never -> "T_never" + | T_sapling_state -> "T_sapling_state" + | T_sapling_transaction -> "T_sapling_transaction" + | T_bls12_381_g1 -> "T_bls12_381_g1" + | T_bls12_381_g2 -> "T_bls12_381_g2" + | T_bls12_381_fr -> "T_bls12_381_fr" + | T_ticket -> "T_ticket" + | I_Hole -> "I_Hole" + | D_Hole -> "D_Hole" + | A_Int -> "A_Int" + | A_Nat -> "A_Nat" + | A_Timestamp -> "A_Timestamp" + | A_Mutez -> "A_Mutez" + | A_Key_hash -> "A_Key_hash" + | A_Key -> "A_Key" + | A_List -> "A_List" + | A_Set -> "A_Set" + | A_Map -> "A_Map" + | A_Lambda -> "A_Lambda" + +let pp fmtr prim = Format.fprintf fmtr "%s" (string_of_prim prim) + +type kind = Data_kind | Instr_kind | Type_kind | Keyword_kind | Annot_kind + +let kind (x : prim) = + match x with + | K_parameter | K_storage | K_code -> Keyword_kind + | D_Hole | D_False | D_Elt | D_Left | D_None | D_Pair | D_Right | D_Some + | D_True | D_Unit -> + Data_kind + | I_PACK | I_UNPACK | I_BLAKE2B | I_SHA256 | I_SHA512 | I_ABS | I_ADD + | I_AMOUNT | I_AND | I_BALANCE | I_CAR | I_CDR | I_CHAIN_ID + | I_CHECK_SIGNATURE | I_COMPARE | I_CONCAT | I_CONS | I_CREATE_ACCOUNT + | I_CREATE_CONTRACT | I_IMPLICIT_ACCOUNT | I_DIP | I_DROP | I_DUP | I_EDIV + | I_EMPTY_BIG_MAP | I_EMPTY_MAP | I_EMPTY_SET | I_EQ | I_EXEC | I_APPLY + | I_FAILWITH | I_GE | I_GET_MAP | I_GET_AND_UPDATE_MAP | I_GT | I_HASH_KEY + | I_IF | I_IF_CONS | I_IF_LEFT | I_IF_NONE | I_INT | I_LAMBDA | I_LE | I_LEFT + | I_LOOP | I_LSL | I_LSR | I_LT | I_MAP_MAP | I_MAP_LIST | I_MEM_SET + | I_MEM_MAP | I_MUL | I_NEG | I_NEQ | I_NIL | I_NONE | I_NOT | I_NOW | I_OR + | I_PAIR | I_UNPAIR | I_PUSH | I_RIGHT | I_SIZE_SET | I_SIZE_MAP | I_SIZE_LIST + | I_SIZE_STRING | I_SIZE_BYTES | I_SOME | I_SOURCE | I_SENDER | I_SELF + | I_SLICE | I_STEPS_TO_QUOTA | I_SUB | I_SWAP | I_TRANSFER_TOKENS + | I_SET_DELEGATE | I_UNIT | I_UPDATE_SET | I_UPDATE_MAP | I_XOR | I_ITER_MAP + | I_ITER_LIST | I_ITER_SET | I_LOOP_LEFT | I_ADDRESS | I_CONTRACT | I_ISNAT + | I_CAST | I_RENAME | I_DIG | I_DUG | I_LEVEL | I_SELF_ADDRESS | I_NEVER + | I_SAPLING_EMPTY_STATE | I_SAPLING_VERIFY_UPDATE | I_VOTING_POWER + | I_TOTAL_VOTING_POWER | I_KECCAK | I_SHA3 | I_PAIRING_CHECK | I_TICKET + | I_READ_TICKET | I_SPLIT_TICKET | I_JOIN_TICKETS | I_Hole -> + Instr_kind + | T_bool | T_contract | T_int | T_key | T_key_hash | T_lambda | T_list | T_map + | T_big_map | T_nat | T_option | T_or | T_pair | T_set | T_signature + | T_string | T_bytes | T_mutez | T_timestamp | T_unit | T_operation + | T_address | T_chain_id | T_never | T_sapling_state | T_sapling_transaction + | T_bls12_381_g1 | T_bls12_381_g2 | T_bls12_381_fr | T_ticket -> + Type_kind + (* Holes in programs and data. *) + (* Annotations. *) + | A_Int | A_Nat | A_Timestamp | A_Mutez | A_Key_hash | A_Key | A_List | A_Set + | A_Map | A_Lambda -> + Annot_kind diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/monads.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/monads.ml new file mode 100644 index 000000000000..d0939011cb5e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/monads.ml @@ -0,0 +1,83 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Widely used module types. *) + +module type S = sig + type 'a t + + val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t + + val return : 'a -> 'a t + + val run : 'a t -> 'a +end + +(* Signature of a state monad. *) +module type State_sig = sig + type state + + type key + + type value + + include S with type 'a t = state -> 'a * state + + val empty : unit -> state + + val set : key -> value -> unit t + + val get : key -> value option t + + val iter_list : ('a -> unit t) -> 'a list -> unit t +end + +module Make_state_monad (X : Stores.S) : + State_sig + with type state = X.state + and type key = X.key + and type value = X.value + and type 'a t = X.state -> 'a * X.state = struct + include X + + type 'a t = state -> 'a * state + + let ( >>= ) m f s = + let (x, s) = m s in + f x s + + let return x s = (x, s) + + let run m = fst (m (empty ())) + + let set k v s = ((), set k v s) + + let get k s = (get k s, s) + + let rec iter_list (f : 'a -> unit t) (l : 'a list) = + match l with + | [] -> return () + | elt :: tl -> f elt >>= fun () -> iter_list f tl +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/stores.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/stores.ml new file mode 100644 index 000000000000..dff87824d1b4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/stores.ml @@ -0,0 +1,85 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Various implementations of Monads.Store_sig *) + +(* Signature of a persistent store. *) +module type S = sig + type state + + type key + + type value + + val empty : unit -> state + + val set : key -> value -> state -> state + + val get : key -> state -> value option + + val map : (value -> value) -> state -> state + + val to_string : state -> string +end + +module type Map_store_param_sig = sig + type key + + type value + + val key_to_string : key -> string + + val value_to_string : value -> string +end + +(* An implemention of [S] using maps. *) +module Map (M : Map.S) (V : Map_store_param_sig with type key = M.key) : + S with type state = V.value M.t and type key = M.key and type value = V.value = +struct + type state = V.value M.t + + type key = M.key + + type value = V.value + + let empty () = M.empty + + let set = M.add + + let get = M.find_opt + + let map = M.map + + let to_string s = + M.fold + (fun key node acc -> + Printf.sprintf + "%s\n%s |-> %s" + acc + (V.key_to_string key) + (V.value_to_string node)) + s + "" +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/.ocamlformat b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/dune b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/dune new file mode 100644 index 000000000000..5d8519e98cf4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/dune @@ -0,0 +1,10 @@ +(tests + (names test_uf + test_inference) + (package tezos-benchmark-type-inference-012-PsiThaCa) + (libraries tezos-micheline tezos-micheline-rewriting + tezos-benchmark-type-inference-012-PsiThaCa tezos-protocol-012-PsiThaCa + tezos-error-monad tezos-client-012-PsiThaCa) + (flags + (:standard -open Tezos_micheline + -open Tezos_benchmark_type_inference_012_PsiThaCa))) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/test_inference.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/test_inference.ml new file mode 100644 index 000000000000..93aa25022308 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/test_inference.ml @@ -0,0 +1,615 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* open Tezos_rewriting *) +open Mikhailsky + +let unopt x = match x with Some x -> x | None -> assert false + +let time f = + let now = Unix.gettimeofday () in + let res = f () in + let later = Unix.gettimeofday () in + (later -. now, res) + +let add_ii = Instructions.(add Mikhailsky.int_ty Mikhailsky.int_ty) + +let add_in = Instructions.(add Mikhailsky.int_ty Mikhailsky.nat_ty) + +let mul_ii = Instructions.(mul Mikhailsky.int_ty Mikhailsky.int_ty) + +let push_int = Instructions.push int_ty (Data.big_integer (Z.of_int 100)) + +let push_nat = Instructions.push nat_ty (Data.big_natural (Z.of_int 100)) + +module Test1 = struct + open Data + open Instructions + + let program = seq [add_ii; push bool_ty false_; dip instr_hole; dip swap] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test2 = struct + open Instructions + + let program = seq [loop swap; and_] + + let () = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING FAILURE\n" ; + Format.printf "Program: %a\n" Mikhailsky.pp program ; + let exception Test_failed in + try + ignore + ( time @@ fun () -> + ignore @@ Inference.infer program ; + raise Test_failed ) + with + | Inference.Ill_typed_script error -> + Format.printf "Error:\n" ; + Format.printf "%a\n" Inference.pp_inference_error error + | Test_failed -> Format.printf "No type error: Test failed!" + + let _ = print_newline () +end + +module Test3 = struct + open Instructions + + let program = + seq + [ + dip (seq [swap; dup]); + swap; + dip cdr; + loop (seq [dip instr_hole; cdr; loop instr_hole]); + car; + car; + push int_ty (Data.integer 10); + compare; + ] + + let _ = + Format.printf "Testing rewriting and type inference\n" ; + Format.printf "Source program: %a\n" Mikhailsky.pp program + + open Tezos_micheline_rewriting + + module Lang = + Micheline_with_hash_consing.Make + (Mikhailsky.Mikhailsky_signature) + (struct + let initial_size = None + end) + + module Path = Mikhailsky.Path + module Patt = Pattern.Make (Mikhailsky.Mikhailsky_signature) (Lang) (Path) + module Rewriter = + Rewrite.Make (Mikhailsky.Mikhailsky_signature) (Lang) (Path) (Patt) + + let (timing, ((bef, aft), state)) = + try time @@ fun () -> Inference.infer_with_state program + with Inference.Ill_typed_script error -> + let s = Mikhailsky.to_string program in + Format.printf + "Ill-typed script:%a\n%s\n" + Inference.pp_inference_error + error + s ; + Format.printf "Test failed\n" ; + exit 1 + + let () = + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft + + let () = + try + ignore + ((let open Inference in + let open M in + M.uf_lift Uf.UF.show >>= fun uf_state -> + Inference.M.repr_lift (fun s -> (Inference.Repr_store.to_string s, s)) + >>= fun repr_state -> + Printf.printf "uf_state:\n%s\n" uf_state ; + Printf.printf "repr_state:\n%s\n" repr_state ; + let path = + Path.(at_index 2 (at_index 0 (at_index 0 (at_index 3 root)))) + in + let subterm = Rewriter.get_subterm ~term:program ~path in + Format.printf + "subterm at path %s:\n%a\n" + (Path.to_string path) + Mikhailsky.pp + subterm ; + Inference.M.annot_instr_lift (Inference.Annot_instr_sm.get path) + >>= fun typ -> + (match typ with + | None -> assert false + | Some {bef; aft} -> + Inference.instantiate bef >>= fun bef -> + Inference.instantiate aft >>= fun aft -> + Format.printf "Type of subterm:\n" ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + return ()) + >>= fun () -> return ()) + state) + with Inference.Ill_typed_script error -> + let s = Mikhailsky.to_string program in + Format.printf + "Ill-typed script:\n%a\n%s\n" + Inference.pp_inference_error + error + s + + let _ = print_newline () +end + +module Test4 = struct + open Instructions + + let program = + seq + [ + empty_set; + push Type.(unopt (unparse_ty bool)) Data.true_; + push + Type.(unopt (unparse_ty (pair int int))) + Data.(pair (integer 0) (integer 0)); + update_set; + ] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test5 = struct + open Instructions + + let unopt x = match x with Some x -> x | None -> assert false + + let program = + seq + [ + empty_map; + push Type.(unopt (unparse_ty (option (set int)))) Data.none; + push + Type.(unopt (unparse_ty (pair int int))) + Data.(pair (integer 0) (integer 0)); + update_map; + ] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () + + let program = + seq + [ + push + Type.(unopt (unparse_ty (map (pair int int) (set int)))) + Data.( + map + [ + map_elt + (pair (integer 0) (integer 1)) + (set [integer 42; integer 44]); + map_elt + (pair (integer 1) (integer 2)) + (set [integer 42; integer 48]); + ]); + ] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test6 = struct + open Instructions + + (* We remove a chunk from a well-typed program to make it ill-typed, and + expect the type inference to fail *) + let program = + seq + [ + push int_ty (Data.integer 0); + push int_ty (Data.integer 100); + swap; + drop; + drop; + drop; + push unit_ty Data.unit; + push bool_ty Data.false_; + push unit_ty Data.unit; + push int_ty (Data.integer 4073851221413541140); + push string_ty (string "n"); + push string_ty (string "k"); + push int_ty (Data.integer 1391989767887046289); + (* push int_ty (integer 100); + * abs; + * drop; *) + dip (prim I_CONCAT [] []); + compare; + ] + + let () = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING FAILURE\n" ; + Format.printf "Program: %a\n" Mikhailsky.pp program ; + let exception Test_failed in + try + ignore (Inference.infer program) ; + raise Test_failed + with + | Inference.Ill_typed_script error -> + Format.printf "Got error, as expected:\n" ; + Format.printf "%a@." Inference.pp_inference_error error + | Test_failed -> + Format.printf "No type error: Test failed!" ; + exit 1 +end + +module Test7 = struct + open Instructions + + let program = + seq + [ + push int_ty (Data.integer 42); + left; + push string_ty (Data.string "forty-two"); + right; + pair; + left; + ] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test8 = struct + open Instructions + + let program = + seq + [ + hole; + add_ii; + push int_ty (Data.big_integer (Z.of_int 100)); + abs; + right; + dup; + push int_ty (Data.big_integer (Z.of_int 100)); + dip (loop_left hole); + push_int; + hole; + mul_ii; + hole; + loop_left left; + sha512; + push_int; + dup; + add_ii; + right; + swap; + hole; + drop; + compare; + mul_ii; + push_int; + ] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test9 = struct + open Instructions + + let program = seq [car; if_none hole hole] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test10 = struct + open Instructions + + let program = seq [hash_key] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test11 = struct + open Instructions + + let program = + seq [lambda [dup; car; dip cdr; add_in]; push_int; apply; push_nat; exec] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test12 = struct + open Instructions + + let program = seq [dup; dup; if_none hole (seq [drop]); dup; compare] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test13 = struct + open Instructions + + let program = + seq [push Type.(unparse_ty_exn (lambda int int)) (Data.lambda [])] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test14 = struct + open Instructions + + let program = seq [nil; push_int; cons] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test15 = struct + open Instructions + + let program = seq [empty_set; size_set; empty_map; size_map; nil; size_list] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test16 = struct + open Instructions + + let program = + seq + [ + empty_set; + push bool_ty Data.true_; + push_int; + update_set; + iter_set [dup; add_ii; add_ii]; + ] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test17 = struct + open Instructions + + let program = + seq + [ + empty_map; + push (option_ty (list_ty bool_ty)) Data.(some (list [false_; true_])); + push_int; + update_map; + map_map + [ + cdr; + map_list + [ + if_ + (seq [push bool_ty Data.false_]) + (seq [push bool_ty Data.true_]); + ]; + ]; + ] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end + +module Test18 = struct + open Instructions + + let program = + seq + [ + empty_map; + push (option_ty (list_ty bool_ty)) Data.(some (list [false_; true_])); + push_int; + update_map; + map_map + [ + cdr; + map_list + [ + if_ + (seq [push bool_ty Data.false_]) + (seq [push bool_ty Data.true_]); + ]; + ]; + dup; + dip push_int; + push_int; + mem_map; + if_ + (seq [get_map]) + (seq [drop; drop; push (option_ty (list_ty bool_ty)) Data.none]); + ] + + let (timing, (bef, aft)) = time @@ fun () -> Inference.infer program + + let _ = + Format.printf "Testing type inference\n" ; + Format.printf "EXPECTING SUCCESS\n" ; + Format.printf "Program\n" ; + Format.printf "%a\n" Mikhailsky.pp program ; + Format.printf "In %f seconds:\n" timing ; + Format.printf "bef: %a@." Type.Stack.pp bef ; + Format.printf "aft: %a@." Type.Stack.pp aft ; + print_newline () +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/test_uf.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/test_uf.ml new file mode 100644 index 000000000000..84fdd856e9ba --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/test/test_uf.ml @@ -0,0 +1,63 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let _ = + print_newline () ; + Printf.printf "Testing union-find algorithm\n" + +module UF = Uf.UF + +let test = + let open UF.M in + UF.add 0 >>= fun () -> + UF.add 1 >>= fun () -> + UF.add 2 >>= fun () -> + UF.add 3 >>= fun () -> + UF.add 4 >>= fun () -> + UF.find 0 >>= fun v0_repr -> + UF.find 1 >>= fun v1_repr -> + assert (v0_repr <> v1_repr) ; + UF.union 0 1 >>= fun _ -> + UF.find 0 >>= fun v0_repr -> + UF.find 1 >>= fun v1_repr -> + UF.find 2 >>= fun v2_repr -> + assert (v0_repr = v1_repr) ; + assert (v0_repr <> v2_repr) ; + UF.union 2 3 >>= fun _ -> + UF.union 0 3 >>= fun _ -> + UF.find 1 >>= fun v1_repr -> + UF.find 2 >>= fun v2_repr -> + UF.find 3 >>= fun v3_repr -> + UF.find 4 >>= fun v4_repr -> + assert (v1_repr = v2_repr) ; + UF.union 4 4 >>= fun _ -> + assert (v3_repr <> v4_repr) ; + UF.show >>= fun s -> + Printf.printf "UF state:%s\n" s ; + return () + +let () = UF.M.run test + +let _ = Printf.printf "Success.\n" diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/tezos-benchmark-type-inference-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/tezos-benchmark-type-inference-012-PsiThaCa.opam new file mode 100644 index 000000000000..4d0290ddcd4c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/tezos-benchmark-type-inference-012-PsiThaCa.opam @@ -0,0 +1,24 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "tezos-tooling" { with-test } + "tezos-client-012-PsiThaCa" { with-test } + "dune" { >= "1.11" } + "tezos-stdlib" + "tezos-error-monad" + "tezos-crypto" + "tezos-protocol-012-PsiThaCa" + "tezos-micheline" + "tezos-micheline-rewriting" + "hashcons" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos: type inference for partial Michelson expressions" diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/type.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/type.ml new file mode 100644 index 000000000000..dacd2ac7f8fd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/type.ml @@ -0,0 +1,201 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Michelson types. *) + +module Base = struct + type comparable_tag = Comparable | Maybe_not_comparable + + type t = t_node Hashcons.hash_consed + + and t_node = + | Unit_t + | Var_t of int + | Int_t + | Nat_t + | Bool_t + | String_t + | Bytes_t + | Key_hash_t + | Timestamp_t + | Mutez_t + | Key_t + | Option_t of t + | Pair_t of t * t + | Union_t of t * t + | List_t of t + | Set_t of t + | Map_t of t * t + | Lambda_t of t * t + + module Hashed = struct + type t = t_node + + let equal (t1 : t) (t2 : t) = + match (t1, t2) with + | (Var_t v1, Var_t v2) -> v1 = v2 + | (Unit_t, Unit_t) + | (Int_t, Int_t) + | (Nat_t, Nat_t) + | (Bool_t, Bool_t) + | (String_t, String_t) + | (Bytes_t, Bytes_t) + | (Key_hash_t, Key_hash_t) + | (Timestamp_t, Timestamp_t) + | (Mutez_t, Mutez_t) + | (Key_t, Key_t) -> + true + | (Option_t ty1, Option_t ty2) -> ty1.tag = ty2.tag + | (Pair_t (l1, r1), Pair_t (l2, r2)) -> l1.tag = l2.tag && r1.tag = r2.tag + | (Union_t (l1, r1), Union_t (l2, r2)) -> + l1.tag = l2.tag && r1.tag = r2.tag + | (List_t ty1, List_t ty2) -> ty1.tag = ty2.tag + | (Set_t ty1, Set_t ty2) -> ty1.tag = ty2.tag + | (Map_t (kty1, vty1), Map_t (kty2, vty2)) -> + kty1.tag = kty2.tag && vty1.tag = vty2.tag + | (Lambda_t (dom1, range1), Lambda_t (dom2, range2)) -> + dom1.tag = dom2.tag && range1.tag = range2.tag + | _ -> false + + let hash (t : t) = Hashtbl.hash t + end + + module Table = Hashcons.Make (Hashed) + + let table = Table.create 101 + + let rec pp fmtr x = + match x.Hashcons.node with + | Unit_t -> Format.pp_print_string fmtr "unit" + | Var_t v -> Format.fprintf fmtr "%d" v + | Int_t -> Format.pp_print_string fmtr "int" + | Nat_t -> Format.pp_print_string fmtr "nat" + | Bool_t -> Format.pp_print_string fmtr "bool" + | String_t -> Format.pp_print_string fmtr "string" + | Bytes_t -> Format.pp_print_string fmtr "bytes" + | Key_hash_t -> Format.pp_print_string fmtr "key_hash" + | Timestamp_t -> Format.pp_print_string fmtr "timestamp" + | Mutez_t -> Format.pp_print_string fmtr "mutez" + | Key_t -> Format.pp_print_string fmtr "key" + | Option_t ty -> Format.fprintf fmtr "(option %a)" pp ty + | List_t ty -> Format.fprintf fmtr "(list %a)" pp ty + | Pair_t (lty, rty) -> Format.fprintf fmtr "(pair %a %a)" pp lty pp rty + | Union_t (lty, rty) -> Format.fprintf fmtr "(union %a %a)" pp lty pp rty + | Set_t ty -> Format.fprintf fmtr "(set %a)" pp ty + | Map_t (kty, vty) -> Format.fprintf fmtr "(map %a %a)" pp kty pp vty + | Lambda_t (dom, range) -> + Format.fprintf fmtr "(lambda %a %a)" pp dom pp range + + let rec vars x acc = + match x.Hashcons.node with + | Unit_t | Int_t | Nat_t | Bool_t | String_t | Bytes_t | Key_hash_t + | Timestamp_t | Mutez_t | Key_t -> + acc + | Var_t v -> v :: acc + | Option_t ty | List_t ty | Set_t ty -> vars ty acc + | Pair_t (lty, rty) | Union_t (lty, rty) -> vars lty (vars rty acc) + | Map_t (kty, vty) -> vars kty (vars vty acc) + | Lambda_t (dom, range) -> vars dom (vars range acc) + + let vars x = vars x [] +end + +module Stack = struct + type t = t_node Hashcons.hash_consed + + and t_node = Empty_t | Stack_var_t of int | Item_t of Base.t * t + + module Hashed = struct + type t = t_node + + let equal (t1 : t) (t2 : t) = + match (t1, t2) with + | (Empty_t, Empty_t) -> true + | (Stack_var_t v1, Stack_var_t v2) -> v1 = v2 + | (Item_t (h1, tl1), Item_t (h2, tl2)) -> h1 == h2 && tl1 == tl2 + | _ -> false + + let hash (t : t) = Hashtbl.hash t + end + + module Table = Hashcons.Make (Hashed) + + let table = Table.create 101 + + let rec pp fmtr x = + match x.Hashcons.node with + | Empty_t -> Format.pp_print_string fmtr "[]" + | Stack_var_t v -> Format.fprintf fmtr "<%d>" v + | Item_t (head, tail) -> Format.fprintf fmtr "%a :: %a" Base.pp head pp tail + + let rec vars x = + match x.Hashcons.node with + | Empty_t -> None + | Stack_var_t v -> Some v + | Item_t (_head, tail) -> vars tail +end + +let unit = Base.Table.hashcons Base.table Unit_t + +let var x = Base.Table.hashcons Base.table (Var_t x) + +let int = Base.Table.hashcons Base.table Int_t + +let nat = Base.Table.hashcons Base.table Nat_t + +let bool = Base.Table.hashcons Base.table Bool_t + +let string = Base.Table.hashcons Base.table String_t + +let bytes = Base.Table.hashcons Base.table Bytes_t + +let key_hash = Base.Table.hashcons Base.table Key_hash_t + +let timestamp = Base.Table.hashcons Base.table Timestamp_t + +let mutez = Base.Table.hashcons Base.table Mutez_t + +let key = Base.Table.hashcons Base.table Key_t + +let option ty = Base.Table.hashcons Base.table (Option_t ty) + +let pair lty rty = Base.Table.hashcons Base.table (Pair_t (lty, rty)) + +let union lty rty = Base.Table.hashcons Base.table (Union_t (lty, rty)) + +let list ty = Base.Table.hashcons Base.table (List_t ty) + +let set ty = Base.Table.hashcons Base.table (Set_t ty) + +let map kty vty = Base.Table.hashcons Base.table (Map_t (kty, vty)) + +let lambda dom range = Base.Table.hashcons Base.table (Lambda_t (dom, range)) + +(* Stack smart constructors *) +let empty = Stack.Table.hashcons Stack.table Empty_t + +let stack_var x = Stack.Table.hashcons Stack.table (Stack_var_t x) + +let item head tail = Stack.Table.hashcons Stack.table (Item_t (head, tail)) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/type.mli b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/type.mli new file mode 100644 index 000000000000..168ba97e4d21 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/type.mli @@ -0,0 +1,111 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Michelson types, hash-consed. *) + +(** Base types *) +module Base : sig + type comparable_tag = Comparable | Maybe_not_comparable + + type t = t_node Hashcons.hash_consed + + and t_node = private + | Unit_t + | Var_t of int + | Int_t + | Nat_t + | Bool_t + | String_t + | Bytes_t + | Key_hash_t + | Timestamp_t + | Mutez_t + | Key_t + | Option_t of t + | Pair_t of t * t + | Union_t of t * t + | List_t of t + | Set_t of t + | Map_t of t * t + | Lambda_t of t * t + + val pp : Format.formatter -> t -> unit + + val vars : t -> int list +end + +(** Stack types *) +module Stack : sig + type t = t_node Hashcons.hash_consed + + and t_node = private Empty_t | Stack_var_t of int | Item_t of Base.t * t + + val pp : Format.formatter -> t -> unit + + val vars : t -> int option +end + +(** Smart constructors *) +val unit : Base.t + +val var : int -> Base.t + +val int : Base.t + +val nat : Base.t + +val bool : Base.t + +val string : Base.t + +val bytes : Base.t + +val key_hash : Base.t + +val timestamp : Base.t + +val mutez : Base.t + +val key : Base.t + +val option : Base.t -> Base.t + +val pair : Base.t -> Base.t -> Base.t + +val union : Base.t -> Base.t -> Base.t + +val list : Base.t -> Base.t + +val set : Base.t -> Base.t + +val map : Base.t -> Base.t -> Base.t + +val lambda : Base.t -> Base.t -> Base.t + +val empty : Stack.t + +val stack_var : int -> Stack.t + +val item : Base.t -> Stack.t -> Stack.t diff --git a/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/uf.ml b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/uf.ml new file mode 100644 index 000000000000..f14a166939a7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference/uf.ml @@ -0,0 +1,99 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* ------------------------------------------------------------------------- *) +(* Union find parameterized over a persistent store. *) + +module type S = sig + module M : Monads.State_sig + + type key = int + + val add : key -> unit M.t + + val find : key -> key M.t + + val union : key -> key -> key M.t + + val show : string M.t +end + +module UF : S = struct + type node = T of {rank : int} | Ptr of key + + and key = int + + module S = + Stores.Map + (Int_map) + (struct + type key = int + + type value = node + + let key_to_string = string_of_int + + let value_to_string (x : value) = + match x with + | T {rank} -> Printf.sprintf "[%d]" rank + | Ptr k -> Printf.sprintf "ptr(%d)" k + end) + + module M = Monads.Make_state_monad (S) + + let add (k : key) = + let open M in + set k (T {rank = 1}) + + let rec get_root (k : key) (acc : key list) = + let open M in + get k >>= function + | None -> + let msg = Printf.sprintf "UF.get_root: invalid key %d" k in + Stdlib.failwith msg + | Some (T {rank}) -> + let ptr_to_root = Ptr k in + iter_list (fun key -> set key ptr_to_root) acc >>= fun () -> + return (k, rank) + | Some (Ptr k') -> get_root k' (k :: acc) + + let find (k : key) = + let open M in + get_root k [] >>= fun (res, _) -> return res + + let union k1 k2 = + let open M in + get_root k1 [] >>= fun (k1, rank1) -> + get_root k2 [] >>= fun (k2, rank2) -> + if k1 = k2 then return k1 + else if rank1 < rank2 then set k1 (Ptr k2) >>= fun () -> return k2 + else if rank1 > rank2 then set k2 (Ptr k1) >>= fun () -> return k1 + else + let new_root = T {rank = rank1 + 1} in + set k2 (Ptr k1) >>= fun () -> + set k1 new_root >>= fun () -> return k1 + + let show s = (S.to_string s, s) +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/micheline_sampler.ml b/src/proto_012_PsiThaCa/lib_benchmark/micheline_sampler.ml new file mode 100644 index 000000000000..1e4778f856f0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/micheline_sampler.ml @@ -0,0 +1,110 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Micheline sampling. *) + +type width_function = depth:int -> int Base_samplers.sampler + +(** [Base_samplers] specifies samplers for leaves, primitives and annotations. *) +module type Base_samplers = sig + (** The type of primitives. *) + type prim + + val sample_prim : prim Base_samplers.sampler + + val sample_annots : string list Base_samplers.sampler + + val sample_string : string Base_samplers.sampler + + val sample_bytes : Bytes.t Base_samplers.sampler + + val sample_z : Z.t Base_samplers.sampler + + val width_function : width_function +end + +module type S = sig + type prim + + val sample : (int, prim) Micheline.node Base_samplers.sampler +end + +type node_kind = Int_node | String_node | Bytes_node | Seq_node | Prim_node + +(* The distribution can be skewed towards non-leaf nodes by repeating their + relevant kind in the array below. *) +let all_kinds = [|Int_node; String_node; Bytes_node; Seq_node; Prim_node|] + +let sample_kind : node_kind Base_samplers.sampler = + fun rng_state -> + let i = Random.State.int rng_state (Array.length all_kinds) in + all_kinds.(i) + +let reasonable_width_function ~depth rng_state = + (* Entirely ad-hoc *) + Base_samplers.( + sample_in_interval + ~range:{min = 0; max = 20 / (Bits.numbits depth + 1)} + rng_state) + +module Make (P : Base_samplers) : S with type prim = P.prim = struct + type prim = P.prim + + let sample (w : width_function) rng_state = + let rec sample depth rng_state k = + match sample_kind rng_state with + | Int_node -> k (Micheline.Int (0, P.sample_z rng_state)) + | String_node -> k (Micheline.String (0, P.sample_string rng_state)) + | Bytes_node -> k (Micheline.Bytes (0, P.sample_bytes rng_state)) + | Seq_node -> + let width = w ~depth rng_state in + sample_list + depth + width + [] + (fun terms -> k (Micheline.Seq (0, terms))) + rng_state + | Prim_node -> + let prim = P.sample_prim rng_state in + let annots = P.sample_annots rng_state in + let width = w ~depth rng_state in + sample_list + depth + width + [] + (fun terms -> k (Micheline.Prim (0, prim, terms, annots))) + rng_state + and sample_list depth width acc k rng_state = + if width < 0 then invalid_arg "sample_list: negative width" + else if width = 0 then k (List.rev acc) + else + sample (depth + 1) rng_state (fun x -> + sample_list depth (width - 1) (x :: acc) k rng_state) + in + sample 0 rng_state (fun x -> x) + + let sample rng_state = sample P.width_function rng_state +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/micheline_sampler.mli b/src/proto_012_PsiThaCa/lib_benchmark/micheline_sampler.mli new file mode 100644 index 000000000000..97e3d4ec1e12 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/micheline_sampler.mli @@ -0,0 +1,70 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Micheline sampling. *) + +(** A [width_function] specifies the distribution of node degree as a function + of [depth]. A [width_function] {e must} be supported by the nonnegative + integers. + + Note that picking a [width_function] which doesn't converge fast enough to + the singular distribution on 0 could yield very large terms. *) +type width_function = depth:int -> int Base_samplers.sampler + +(** [reasonable_width_function] is a width function which works well + empirically. *) +val reasonable_width_function : width_function + +(** [Base_samplers] specifies samplers for leaves, primitives and annotations. *) +module type Base_samplers = sig + (** The type of primitives. *) + type prim + + val sample_prim : prim Base_samplers.sampler + + val sample_annots : string list Base_samplers.sampler + + val sample_string : string Base_samplers.sampler + + val sample_bytes : Bytes.t Base_samplers.sampler + + val sample_z : Z.t Base_samplers.sampler + + val width_function : width_function +end + +(** Applying the [Make] functor below yields a module with the following + type. *) +module type S = sig + type prim + + (** [sample w] is a Micheline sampler for the prescribed primitive + type. The sampler uses the provided width function [w]. *) + val sample : (int, prim) Micheline.node Base_samplers.sampler +end + +(** [Make] instantiates a micheline sampler. *) +module Make (P : Base_samplers) : S with type prim = P.prim diff --git a/src/proto_012_PsiThaCa/lib_benchmark/michelson_mcmc_samplers.ml b/src/proto_012_PsiThaCa/lib_benchmark/michelson_mcmc_samplers.ml new file mode 100644 index 000000000000..d8064150cb34 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/michelson_mcmc_samplers.ml @@ -0,0 +1,337 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** MCMC-based Michelson data and code samplers. *) + +open Protocol +open Stats + +type michelson_code = { + term : Script_repr.expr; + bef : Script_repr.expr list; + aft : Script_repr.expr list; +} + +type michelson_data = {term : Script_repr.expr; typ : Script_repr.expr} + +type michelson_sample = Code of michelson_code | Data of michelson_data + +let michelson_sample_list_encoding = + let open Data_encoding in + let e = Script_repr.expr_encoding in + list + @@ union + [ + case + ~title:"Code" + (Tag 0) + (tup3 e (list e) (list e)) + (function + | Code {term; bef; aft} -> Some (term, bef, aft) | _ -> None) + (fun (term, bef, aft) -> Code {term; bef; aft}); + case + ~title:"Data" + (Tag 1) + (tup2 e e) + (function Data {term; typ} -> Some (term, typ) | _ -> None) + (fun (term, typ) -> Data {term; typ}); + ] + +let save ~filename ~terms = + let str = + match + Data_encoding.Binary.to_string michelson_sample_list_encoding terms + with + | Error err -> + Format.eprintf + "Michelson_mcmc_samplers.save: encoding failed (%a); exiting" + Data_encoding.Binary.pp_write_error + err ; + exit 1 + | Ok res -> res + in + try Lwt_main.run @@ Tezos_stdlib_unix.Lwt_utils_unix.create_file filename str + with exn -> + Format.eprintf + "Michelson_mcmc_samplers.save: create_file failed (%s); exiting" + (Printexc.to_string exn) ; + exit 1 + +let load ~filename = + let open TzPervasives in + let string = + try Lwt_main.run @@ Tezos_stdlib_unix.Lwt_utils_unix.read_file filename + with exn -> + Format.eprintf + "Michelson_mcmc_samplers.load: read_file failed (%s); exiting" + (Printexc.to_string exn) ; + exit 1 + in + let bytes = Bytes.of_string string in + match Data_encoding.Binary.of_bytes michelson_sample_list_encoding bytes with + | Ok result -> result + | Error err -> + Format.eprintf + "Michelson_mcmc_samplers.load: decoding failed (%a); exiting" + Data_encoding.Binary.pp_read_error + err ; + exit 1 + +(* Helpers *) + +let base_type_to_michelson_type (typ : Type.Base.t) = + let typ = Mikhailsky.map_var (fun _ -> Mikhailsky.unit_ty) typ in + Mikhailsky.to_michelson typ + +module type Sampler_parameters_sig = sig + val initial : State_space.t + + val energy : State_space.t -> float + + val rules : Rules.rule_set list + + val infer : Mikhailsky.node -> Inference.state + + val verbosity : [`Silent | `Progress | `Trace] +end + +(* The Markov chain in state [state] *) +type mc_state = { + state : State_space.t; + jump : State_space.t Fin.Float.prb Lazy.t; +} + +module State_multiset = + Basic_structures.Basic_impl.Free_module.Float_valued.Make_with_map + (State_space) + +(** Generic MCMC michelson sampler (can be used for code and data) *) +module Make_generic (P : Sampler_parameters_sig) = struct + let uniform (l : State_space.t list) : State_space.t Fin.Float.prb = + match l with + | [] -> + (* This can only happen is the MCMC was driven to a coffin state, + which means that it's not reversible (this is a bug) *) + assert false + | _ -> + let arr = Array.of_list l in + let emp = Emp.of_raw_data arr in + Fin.Float.counts_of_empirical (module State_multiset) emp + |> Fin.Float.normalize + + let unrecoverable_failure err current result = + Format.eprintf "Error when typechecking term:@." ; + Format.eprintf "%a@." Inference.pp_inference_error err ; + Format.eprintf "Original state: @[%a@]@." State_space.pp current ; + Format.eprintf "Erroneous term: %a@." Mikhailsky.pp result ; + Stdlib.failwith "in sampler.ml: unrecoverable failure." + + let of_state : State_space.t -> mc_state = + fun state -> + { + state; + jump = + Lazy.from_fun (fun () -> + let current = state in + let rewriting_options = Rules.rewriting current P.rules in + let term = current.term in + let rewritings = + List.fold_left + (fun rewritings (path, replacement) -> + let result = Kernel.Rewriter.subst ~term ~path ~replacement in + let typing = + Lazy.from_fun (fun () -> + try P.infer result + with Inference.Ill_typed_script err -> + unrecoverable_failure err current result) + in + {State_space.typing; term = result} :: rewritings) + [] + rewriting_options + in + uniform rewritings); + } + + module MH_params : Mh.MH_parameters with type t = mc_state = struct + type t = mc_state + + let pp fmtr {state; jump = _} = State_space.pp fmtr state + + let trace state = + match P.verbosity with + | `Silent | `Progress -> () + | `Trace -> + Format.eprintf "@." ; + Format.eprintf "%a" State_space.pp state ; + Format.eprintf "energy:@." ; + Format.eprintf "%f:@." (P.energy state) + + let proposal_log_density s1 s2 = + let jump = Lazy.force s1.jump in + Log_space.of_float (Fin.Float.eval_prb jump s2.state) + + let proposal mcmc_state rng_state = + trace mcmc_state.state ; + let dist = Lazy.force mcmc_state.jump in + let next = Fin.Float.sample (Fin.as_measure dist) rng_state in + of_state next + + let log_weight state = Log_space.unsafe_cast (-.P.energy state.state) + end + + module Sampler = Mh.Make (MH_params) + + let generator ~burn_in = + P.(Sampler.mcmc ~verbosity ~initial:(of_state initial) ~burn_in) +end + +module Make_code_sampler + (Michelson_base : Michelson_samplers_base.S) + (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) (X : sig + val rng_state : Random.State.t + + val target_size : int + + val verbosity : [`Silent | `Progress | `Trace] + end) = +struct + module Autocomp = Autocomp.Make (Michelson_base) (Crypto_samplers) + + module MCMC = Make_generic (struct + let initial = + let term = Mikhailsky.Instructions.hole in + let typing = Lazy.from_val @@ snd (Inference.infer_with_state term) in + {State_space.term; typing} + + let energy state = + let stats = State_space.statistics state in + let size_deficit = + abs_float + (float_of_int X.target_size -. float_of_int stats.State_space.size) + in + let holes_proportion = float stats.holes /. float stats.size in + let holes_deficit = + (* we want at least 1% of holes, above is ok *) + if holes_proportion < 0.01 then + (0.01 -. holes_proportion) *. size_deficit + else 0.0 + in + size_deficit +. holes_deficit + + let rules = Rules.Instruction.rules + + let infer term = snd (Inference.infer_with_state term) + + let verbosity = X.verbosity + end) + + let to_michelson {state = ({typing; term} : State_space.t); jump = _} = + let typing = Lazy.force typing in + let (node, (bef, aft), state) = + Autocomp.complete_code typing term X.rng_state + in + let node = + Micheline.strip_locations @@ Mikhailsky_to_michelson.convert node state + in + { + term = node; + bef = Type_helpers.stack_type_to_michelson_type_list bef; + aft = Type_helpers.stack_type_to_michelson_type_list aft; + } + + let generator ~burn_in = + Gen.map (MCMC.generator ~burn_in) @@ fun after_burn_in -> + Gen.map after_burn_in to_michelson +end + +module Make_data_sampler + (Michelson_base : Michelson_samplers_base.S) + (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) (X : sig + val rng_state : Random.State.t + + val target_size : int + + val verbosity : [`Silent | `Progress | `Trace] + end) = +struct + module Autocomp = Autocomp.Make (Michelson_base) (Crypto_samplers) + module Rewrite_rules = + Rules.Data_rewrite_leaves (Michelson_base) (Crypto_samplers) + + module MCMC = Make_generic (struct + let initial = + let term = Mikhailsky.Data.hole in + let typing = + Lazy.from_val @@ snd (Inference.infer_data_with_state term) + in + {State_space.term; typing} + + let energy state = + let stats = State_space.statistics state in + let size_deficit = + abs_float + (float_of_int X.target_size -. float_of_int stats.State_space.size) + in + let holes_proportion = + float_of_int stats.holes /. float_of_int stats.size + in + let holes_deficit = + (* we want at least 10% of holes, above is ok *) + if holes_proportion < 0.5 then (0.5 -. holes_proportion) *. size_deficit + else 0.0 + in + let depth_deficit = + abs_float + ((0.1 *. float_of_int X.target_size) -. float_of_int stats.depth) + in + size_deficit +. holes_deficit +. depth_deficit + + let rules = Rewrite_rules.rules X.rng_state + + let infer term = snd (Inference.infer_data_with_state term) + + let verbosity = X.verbosity + end) + + let to_michelson {state = ({typing; term} : State_space.t); jump = _} = + let typing = Lazy.force typing in + let (node, _) = Autocomp.complete_data typing term X.rng_state in + let (typ, state) = + try Inference.infer_data_with_state node + with _ -> + Format.eprintf "Bug found!@." ; + Format.eprintf "Ill-typed autocompletion. Resulting term:@." ; + Format.eprintf "%a@." Mikhailsky.pp node ; + Stdlib.failwith "in generators.ml: unrecoverable failure" + in + let node = + Micheline.strip_locations @@ Mikhailsky_to_michelson.convert node state + in + {term = node; typ = base_type_to_michelson_type typ} + + let generator ~burn_in = + Gen.map (MCMC.generator ~burn_in) @@ fun after_burn_in -> + Gen.map after_burn_in to_michelson +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/michelson_mcmc_samplers.mli b/src/proto_012_PsiThaCa/lib_benchmark/michelson_mcmc_samplers.mli new file mode 100644 index 000000000000..bd67d13e3c16 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/michelson_mcmc_samplers.mli @@ -0,0 +1,115 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** MCMC-based Michelson data and code samplers. *) + +open Protocol + +(** MCMC samplers can either produce data or code. Note that the samplers + natively produce data and code in Micheline (ie untyped) form. *) + +type michelson_code = { + term : Script_repr.expr; + (** [term] is a typeable Michelson program in Micheline form. *) + bef : Script_repr.expr list; + (** [bef] is an input stack type for which [term] is a well-typed script. *) + aft : Script_repr.expr list; + (** [aft] is the stack type corresponding to the execution of [term] + on a stack of type [bef]. *) +} + +type michelson_data = { + term : Script_repr.expr; + (** [term] is a typeable Michelson data in Micheline form. *) + typ : Script_repr.expr; (** [typ] is the type of [term]. *) +} + +(** A [michelson_sample] is either a code sample or a data sample. *) +type michelson_sample = Code of michelson_code | Data of michelson_data + +(** Encoding used for saving or loading data. *) +val michelson_sample_list_encoding : michelson_sample list Data_encoding.t + +(** Saving a list of samples to a file. + Exits with code 1 if an error arises during encoding or file manipulation. *) +val save : filename:string -> terms:michelson_sample list -> unit + +(** Loading a list of samples from a file. + Exits with code 1 if an error arises during decoding or file manipulation. *) +val load : filename:string -> michelson_sample list + +(** [Make_code_sampler] produces a sampler for well-typed Michelson code. + The parameters of the functor are: + - a module [Michelson_base] implementing samplers for basic values + - a module [Crypto_samplers] implementing samplers for pk/pkh/sk triplets + - a module [X] containing some parameters to the Markov chain sampler: + - [rng_state] is the mutable state that will be used during sampling + - [target_size] specifies the size, in terms of Micheline nodes, of the + terms that the sampler should try to produce + - [verbosity] specifies how much information should be written on stdout + during the sampling process. + + The outcome is a [michelson_code] [generator]. The [burn_in] parameter + specifies how much samples should be thrown away before starting to + produce sample (this is used to let the underlying Markov chain reach + its stationary distribution - the value should be commensurate with + the [target_size]. + *) +module Make_code_sampler : functor + (Michelson_base : Michelson_samplers_base.S) + (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) + (X : sig + val rng_state : Random.State.t + + val target_size : int + + val verbosity : [`Progress | `Silent | `Trace] + end) + -> sig + (** [generator ~burn_in rng_state] performs a burn-in phase consisting of sampling [burn_in] times, + throwing the results away and returns a michelson term sampler. The goal of burn-in is + to drive the underlying Markov chain to its stationary distribution, ie to sample + terms around the specified [X.target_size]. *) + val generator : burn_in:int -> Random.State.t -> michelson_code Stats.Gen.t +end + +(** See documentation for [Make_code_sampler] *) +module Make_data_sampler : functor + (Michelson_base : Michelson_samplers_base.S) + (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) + (X : sig + val rng_state : Random.State.t + + val target_size : int + + val verbosity : [`Progress | `Silent | `Trace] + end) + -> sig + (** [generator ~burn_in rng_state] performs a burn-in phase consisting of sampling [burn_in] times, + throwing the results away and returns a michelson term sampler. The goal of burn-in is + to drive the underlying Markov chain to its stationary distribution, ie to sample + terms around the specified [X.target_size]. *) + val generator : burn_in:int -> Random.State.t -> michelson_data Stats.Gen.t +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers.ml b/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers.ml new file mode 100644 index 000000000000..16014d6df65a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers.ml @@ -0,0 +1,727 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Script_typed_ir + +type parameters = { + base_parameters : Michelson_samplers_base.parameters; + list_size : Base_samplers.range; + set_size : Base_samplers.range; + map_size : Base_samplers.range; +} + +let parameters_encoding = + let open Data_encoding in + let range_encoding = Base_samplers.range_encoding in + conv + (fun {base_parameters; list_size; set_size; map_size} -> + (base_parameters, (list_size, set_size, map_size))) + (fun (base_parameters, (list_size, set_size, map_size)) -> + {base_parameters; list_size; set_size; map_size}) + (merge_objs + Michelson_samplers_base.parameters_encoding + (obj3 + (req "list_size" range_encoding) + (req "set_size" range_encoding) + (req "map_size" range_encoding))) + +(* ------------------------------------------------------------------------- *) +(* Helpers. *) + +let comparable_downcast = Script_ir_translator.ty_of_comparable_ty + +(* ------------------------------------------------------------------------- *) +(* Type names. *) + +(* We only want to generated inhabited types, hence Never is not included. *) + +type type_name = + [ `TUnit + | `TInt + | `TNat + | `TSignature + | `TString + | `TBytes + | `TMutez + | `TKey_hash + | `TKey + | `TTimestamp + | `TAddress + | `TBool + | `TPair + | `TUnion + | `TLambda + | `TOption + | `TList + | `TSet + | `TMap + | `TBig_map + | `TContract + | `TSapling_transaction + | `TSapling_state + | `TOperation + | `TChain_id + | `TBls12_381_g1 + | `TBls12_381_g2 + | `TBls12_381_fr + | `TTicket ] + +type atomic_type_name = + [ `TUnit + | `TInt + | `TNat + | `TSignature + | `TString + | `TBytes + | `TMutez + | `TKey_hash + | `TKey + | `TTimestamp + | `TAddress + | `TBool + | `TSapling_transaction + | `TSapling_state + | `TChain_id + | `TBls12_381_g1 + | `TBls12_381_g2 + | `TBls12_381_fr ] + +type non_atomic_type_name = + [ `TPair + | `TUnion + | `TLambda + | `TOption + | `TList + | `TSet + | `TMap + | `TBig_map + | `TContract + | `TTicket ] + +(* Ensure inclusion of atomic_type_name in type_name *) +let (_ : atomic_type_name -> type_name) = fun x -> (x :> type_name) + +(* Ensure inclusion of non_atomic_type_name in type_name *) +let (_ : non_atomic_type_name -> type_name) = fun x -> (x :> type_name) + +let all_atomic_type_names : atomic_type_name array = + [| + `TUnit; + `TInt; + `TNat; + `TSignature; + `TString; + `TBytes; + `TMutez; + `TKey_hash; + `TKey; + `TTimestamp; + `TAddress; + `TBool; + `TSapling_transaction; + `TSapling_state; + `TChain_id; + `TBls12_381_g1; + `TBls12_381_g2; + `TBls12_381_fr; + |] + +let all_non_atomic_type_names : non_atomic_type_name array = + [| + `TPair; + `TUnion; + `TLambda; + `TOption; + `TList; + `TSet; + `TMap; + `TBig_map; + `TContract; + `TTicket; + |] + +type comparable_type_name = + [ `TUnit + | `TInt + | `TNat + | `TSignature + | `TString + | `TBytes + | `TMutez + | `TBool + | `TKey_hash + | `TKey + | `TTimestamp + | `TChain_id + | `TAddress + | `TPair + | `TUnion + | `TOption ] + +(* Ensure inclusion of comparable_type_name in type_name *) +let (_ : comparable_type_name -> type_name) = fun x -> (x :> type_name) + +type 'a comparable_and_atomic = 'a + constraint 'a = [< comparable_type_name] constraint 'a = [< atomic_type_name] + +let all_comparable_atomic_type_names : 'a comparable_and_atomic array = + [| + `TUnit; + `TInt; + `TNat; + `TSignature; + `TString; + `TBytes; + `TMutez; + `TBool; + `TKey_hash; + `TKey; + `TTimestamp; + `TChain_id; + `TAddress; + |] + +type 'a comparable_and_non_atomic = 'a + constraint 'a = [< comparable_type_name] + constraint 'a = [< non_atomic_type_name] + +let all_comparable_non_atomic_type_names : 'a comparable_and_non_atomic array = + [|`TPair; `TUnion; `TOption|] + +(* Ensure inclusion of comparable_and_atomic in type_name *) +let (_ : 'a comparable_and_atomic -> type_name) = fun x -> (x :> type_name) + +(* ------------------------------------------------------------------------- *) +(* Uniform type name generators *) + +open Sampling_helpers + +let uniform : 'a array -> 'a sampler = + fun arr rng_state -> + let i = Random.State.int rng_state (Array.length arr) in + arr.(i) + +let uniform_atomic_type_name : atomic_type_name sampler = + uniform all_atomic_type_names + +let uniform_comparable_atomic_type_name : 'a comparable_and_atomic sampler = + uniform all_comparable_atomic_type_names + +let uniform_comparable_non_atomic_type_name : + 'a comparable_and_non_atomic sampler = + uniform all_comparable_non_atomic_type_names + +(* ------------------------------------------------------------------------- *) +(* Random generation functor. *) + +module type S = sig + module Michelson_base : Michelson_samplers_base.S + + module Random_type : sig + val m_type : size:int -> Script_ir_translator.ex_ty sampler + + val m_comparable_type : + size:int -> Script_ir_translator.ex_comparable_ty sampler + end + + module rec Random_value : sig + val value : 'a Script_typed_ir.ty -> 'a sampler + + val comparable : 'a Script_typed_ir.comparable_ty -> 'a sampler + + val stack : ('a, 'b) Script_typed_ir.stack_ty -> ('a * 'b) sampler + end +end + +exception SamplingError of string + +let fail_sampling error = raise (SamplingError error) + +module Make (P : sig + val parameters : parameters +end) +(Crypto_samplers : Crypto_samplers.Finite_key_pool_S) : S = struct + module Michelson_base = Michelson_samplers_base.Make (struct + let parameters = P.parameters.base_parameters + end) + + let memo_size = + Alpha_context.Sapling.Memo_size.parse_z Z.zero |> Result.get_ok + + (* [pick_split x] randomly splits the integer [x] into two integers [left] + and [right] such that [1 <= left], [1 <= right], and [left + right = x]. + Expects [x >= 2]. *) + let pick_split : int -> (int * int) sampler = + fun x rng_state -> + if x < 2 then invalid_arg "pick_split" + else + (* x >= 2 *) + let left = 1 + Random.State.int rng_state (x - 1) in + let right = x - left in + assert (left + right = x) ; + (left, right) + + (* Random generation of Michelson types. *) + module Random_type = struct + let type_of_atomic_type_name (at_tn : atomic_type_name) : + Script_ir_translator.ex_ty = + match at_tn with + | `TString -> Ex_ty (string_t ~annot:None) + | `TNat -> Ex_ty (nat_t ~annot:None) + | `TKey -> Ex_ty (key_t ~annot:None) + | `TBytes -> Ex_ty (bytes_t ~annot:None) + | `TBool -> Ex_ty (bool_t ~annot:None) + | `TAddress -> Ex_ty (address_t ~annot:None) + | `TTimestamp -> Ex_ty (timestamp_t ~annot:None) + | `TKey_hash -> Ex_ty (key_hash_t ~annot:None) + | `TMutez -> Ex_ty (mutez_t ~annot:None) + | `TSignature -> Ex_ty (signature_t ~annot:None) + | `TUnit -> Ex_ty (unit_t ~annot:None) + | `TInt -> Ex_ty (int_t ~annot:None) + | `TSapling_state -> Ex_ty (sapling_state_t ~memo_size ~annot:None) + | `TSapling_transaction -> + Ex_ty (sapling_transaction_t ~memo_size ~annot:None) + | `TChain_id -> Ex_ty (chain_id_t ~annot:None) + | `TBls12_381_g1 -> Ex_ty (bls12_381_g1_t ~annot:None) + | `TBls12_381_g2 -> Ex_ty (bls12_381_g2_t ~annot:None) + | `TBls12_381_fr -> Ex_ty (bls12_381_fr_t ~annot:None) + + let comparable_type_of_comparable_atomic_type_name + (cmp_tn : 'a comparable_and_atomic) : + Script_ir_translator.ex_comparable_ty = + match cmp_tn with + | `TString -> Ex_comparable_ty (string_key ~annot:None) + | `TNat -> Ex_comparable_ty (nat_key ~annot:None) + | `TBytes -> Ex_comparable_ty (bytes_key ~annot:None) + | `TBool -> Ex_comparable_ty (bool_key ~annot:None) + | `TAddress -> Ex_comparable_ty (address_key ~annot:None) + | `TTimestamp -> Ex_comparable_ty (timestamp_key ~annot:None) + | `TKey_hash -> Ex_comparable_ty (key_hash_key ~annot:None) + | `TMutez -> Ex_comparable_ty (mutez_key ~annot:None) + | `TInt -> Ex_comparable_ty (int_key ~annot:None) + | `TUnit -> Ex_comparable_ty (unit_key ~annot:None) + | `TSignature -> Ex_comparable_ty (signature_key ~annot:None) + | `TKey -> Ex_comparable_ty (key_key ~annot:None) + | `TChain_id -> Ex_comparable_ty (chain_id_key ~annot:None) + + let rec m_type ~size : Script_ir_translator.ex_ty sampler = + let open Script_ir_translator in + let open M in + if size <= 0 then Stdlib.failwith "m_type: size <= 0" + else if size = 1 then + (* only atomic types can have size 1 *) + let* at_tn = uniform_atomic_type_name in + return (type_of_atomic_type_name at_tn) + else if size = 2 then + bind (uniform [|`TOption; `TList; `TSet; `TTicket; `TContract|]) + @@ function + | `TOption -> ( + let* (Ex_ty t) = m_type ~size:1 in + match option_t (-1) t ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TList -> ( + let* (Ex_ty t) = m_type ~size:1 in + match list_t (-1) t ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TSet -> ( + let* (Ex_comparable_ty t) = m_comparable_type ~size:1 in + match set_t (-1) t ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TTicket -> ( + let* (Ex_comparable_ty contents) = m_comparable_type ~size:1 in + match ticket_t (-1) contents ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TContract -> ( + let* (Ex_ty t) = m_type ~size:1 in + match contract_t (-1) t ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + else + bind (uniform all_non_atomic_type_names) @@ function + | `TPair -> ( + let* (lsize, rsize) = pick_split (size - 1) in + let* (Ex_ty left) = m_type ~size:lsize in + let* (Ex_ty right) = m_type ~size:rsize in + match + pair_t (-1) (left, None, None) (right, None, None) ~annot:None + with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TLambda -> ( + let* (lsize, rsize) = pick_split (size - 1) in + let* (Ex_ty domain) = m_type ~size:lsize in + let* (Ex_ty range) = m_type ~size:rsize in + match lambda_t (-1) domain range ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TUnion -> ( + let* (lsize, rsize) = pick_split (size - 1) in + let* (Ex_ty left) = m_type ~size:lsize in + let* (Ex_ty right) = m_type ~size:rsize in + match union_t (-1) (left, None) (right, None) ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TOption -> ( + let* (Ex_ty t) = m_type ~size:(size - 1) in + match option_t (-1) t ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TMap -> ( + let* (lsize, rsize) = pick_split (size - 1) in + let* (Ex_comparable_ty key) = m_comparable_type ~size:lsize in + let* (Ex_ty elt) = m_type ~size:rsize in + match map_t (-1) key elt ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TSet -> ( + let* (Ex_comparable_ty key_ty) = + m_comparable_type ~size:(size - 1) + in + match set_t (-1) key_ty ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TList -> ( + let* (Ex_ty elt) = m_type ~size:(size - 1) in + match list_t (-1) elt ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TTicket -> ( + let* (Ex_comparable_ty contents) = + m_comparable_type ~size:(size - 1) + in + match ticket_t (-1) contents ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TContract -> ( + let* (Ex_ty t) = m_type ~size:(size - 1) in + match contract_t (-1) t ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_ty res_ty) + | `TBig_map -> + (* Don't know what to do with theses. Redraw. *) + m_type ~size + + and m_comparable_type ~size : Script_ir_translator.ex_comparable_ty sampler + = + let open M in + let open Script_ir_translator in + let atomic_case () = + let* at_tn = uniform_comparable_atomic_type_name in + return (comparable_type_of_comparable_atomic_type_name at_tn) + in + let option_case size = + let size = size - 1 in + let* (Ex_comparable_ty t) = m_comparable_type ~size in + match option_key (-1) t ~annot:None with + | Error _ -> (* what should be done here? *) assert false + | Ok res_ty -> return @@ Ex_comparable_ty res_ty + in + let pair_case size = + let size = size - 1 in + let* size_left = + Base_samplers.sample_in_interval ~range:{min = 1; max = size - 1} + in + let size_right = size - size_left in + let* (Ex_comparable_ty l) = m_comparable_type ~size:size_left in + let* (Ex_comparable_ty r) = m_comparable_type ~size:size_right in + match pair_key (-1) (l, None) (r, None) ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_comparable_ty res_ty + in + let union_case size = + let size = size - 1 in + let* size_left = + Base_samplers.sample_in_interval ~range:{min = 1; max = size - 1} + in + let size_right = size - size_left in + let* (Ex_comparable_ty l) = m_comparable_type ~size:size_left in + let* (Ex_comparable_ty r) = m_comparable_type ~size:size_right in + match union_key (-1) (l, None) (r, None) ~annot:None with + | Error _ -> assert false + | Ok res_ty -> return @@ Ex_comparable_ty res_ty + in + + if size <= 1 then atomic_case () + else if size = 2 then option_case size + else + let* cmp_tn = uniform_comparable_non_atomic_type_name in + match cmp_tn with + | `TPair -> pair_case size + | `TUnion -> union_case size + | `TOption -> option_case size + end + + (* Type-directed generation of random values. *) + module rec Random_value : sig + val value : 'a Script_typed_ir.ty -> 'a sampler + + val comparable : 'a Script_typed_ir.comparable_ty -> 'a sampler + + val stack : ('a, 'b) Script_typed_ir.stack_ty -> ('a * 'b) sampler + end = struct + let address rng_state = + if Base_samplers.uniform_bool rng_state then + ( Alpha_context.Contract.implicit_contract + (Crypto_samplers.pkh rng_state), + "default" ) + else + (* For a description of the format, see + tezos-codec describe alpha.contract binary encoding *) + let string = + "\001" ^ Base_samplers.uniform_string ~nbytes:20 rng_state ^ "\000" + in + let contract = + Data_encoding.Binary.of_string_exn + Alpha_context.Contract.encoding + string + in + let ep = Base_samplers.string ~size:{min = 1; max = 31} rng_state in + (contract, ep) + + let chain_id rng_state = + let string = Base_samplers.uniform_string ~nbytes:4 rng_state in + Data_encoding.Binary.of_string_exn Chain_id.encoding string + + let rec value : type a. a Script_typed_ir.ty -> a sampler = + let open Script_typed_ir in + fun typ -> + match typ with + | Never_t _ -> assert false + | Unit_t _ -> M.return () + | Int_t _ -> Michelson_base.int + | Nat_t _ -> Michelson_base.nat + | Signature_t _ -> Michelson_base.signature + | String_t _ -> Michelson_base.string + | Bytes_t _ -> Michelson_base.bytes + | Mutez_t _ -> Michelson_base.tez + | Key_hash_t _ -> Crypto_samplers.pkh + | Key_t _ -> Crypto_samplers.pk + | Timestamp_t _ -> Michelson_base.timestamp + | Bool_t _ -> Base_samplers.uniform_bool + | Address_t _ -> address + | Pair_t ((left_t, _, _), (right_t, _, _), _) -> + M.( + let* left_v = value left_t in + let* right_v = value right_t in + return (left_v, right_v)) + | Union_t ((left_t, _), (right_t, _), _) -> + fun rng_state -> + if Base_samplers.uniform_bool rng_state then + L (value left_t rng_state) + else R (value right_t rng_state) + | Lambda_t (arg_ty, ret_ty, _) -> generate_lambda arg_ty ret_ty + | Option_t (ty, _) -> + fun rng_state -> + if Base_samplers.uniform_bool rng_state then None + else Some (value ty rng_state) + | List_t (elt_ty, _) -> generate_list elt_ty + | Set_t (elt_ty, _) -> generate_set elt_ty + | Map_t (key_ty, val_ty, _) -> generate_map key_ty val_ty + | Contract_t (arg_ty, _) -> generate_contract arg_ty + | Operation_t _ -> generate_operation + | Big_map_t (key_ty, val_ty, _) -> generate_big_map key_ty val_ty + | Chain_id_t _ -> chain_id + | Bls12_381_g1_t _ -> generate_bls12_381_g1 + | Bls12_381_g2_t _ -> generate_bls12_381_g2 + | Bls12_381_fr_t _ -> generate_bls12_381_fr + | Ticket_t (contents_ty, _) -> + let ty = comparable_downcast contents_ty in + generate_ticket ty + | Sapling_transaction_t _ -> + fail_sampling + "Michelson_samplers: sapling transactions not handled yet" + | Sapling_state_t _ -> + fail_sampling "Michelson_samplers: sapling state not handled yet" + | Chest_key_t _ -> + fail_sampling "Michelson_samplers: chest key not handled yet" + | Chest_t _ -> fail_sampling "Michelson_samplers: chest not handled yet" + + and generate_lambda : + type arg ret. + arg Script_typed_ir.ty -> + ret Script_typed_ir.ty -> + (arg, ret) Script_typed_ir.lambda sampler = + fun _arg_ty _ret_ty _rng_state -> + fail_sampling "Michelson_samplers: lambda not handled yet" + + and generate_list : + type elt. + elt Script_typed_ir.ty -> elt Script_typed_ir.boxed_list sampler = + fun elt_type -> + let open M in + let* (length, elements) = + Structure_samplers.list + ~range:P.parameters.list_size + ~sampler:(value elt_type) + in + return Script_typed_ir.{elements; length} + + (* Note that we might very well generate sets smaller than the specified range (consider the + case of a set of type [unit]). *) + and generate_set : + type elt. + elt Script_typed_ir.comparable_ty -> elt Script_typed_ir.set sampler = + fun elt_ty -> + let open M in + let ety = comparable_downcast elt_ty in + let* (_, elements) = + Structure_samplers.list + ~range:P.parameters.set_size + ~sampler:(value ety) + in + return + @@ List.fold_left + (fun set x -> Script_set.update x true set) + (Script_set.empty elt_ty) + elements + + and generate_map : + type key elt. + key Script_typed_ir.comparable_ty -> + elt Script_typed_ir.ty -> + (key, elt) Script_typed_ir.map sampler = + fun key_ty elt_ty rng_state -> + let size = + Base_samplers.sample_in_interval rng_state ~range:P.parameters.map_size + in + let kty = comparable_downcast key_ty in + let keys = List.init size (fun _ -> value kty rng_state) in + let elts = List.init size (fun _ -> value elt_ty rng_state) in + List.fold_left2 + (fun map key elt -> Script_map.update key (Some elt) map) + (Script_map.empty key_ty) + keys + elts + + and generate_big_map : + type key elt. + key Script_typed_ir.comparable_ty -> + elt Script_typed_ir.ty -> + (key, elt) Script_typed_ir.big_map sampler = + let open Script_typed_ir in + fun key_ty elt_ty rng_state -> + let open TzPervasives in + let result = + Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + let big_map = Script_ir_translator.empty_big_map key_ty elt_ty in + (* Cannot have big maps under big maps *) + option_t (-1) elt_ty ~annot:None |> Environment.wrap_tzresult + >>?= fun opt_elt_ty -> + let map = generate_map key_ty opt_elt_ty rng_state in + Script_map.fold + (fun k v acc -> + acc >>=? fun (bm, ctxt_acc) -> + Script_ir_translator.big_map_update ctxt_acc k v bm) + map + (return (big_map, ctxt)) + >|= Environment.wrap_tzresult + >>=? fun (big_map, _) -> return big_map ) + in + match result with + | Ok x -> x + | Error e -> + Format.eprintf + "%a@." + (Error_monad.TzTrace.pp_print Error_monad.pp) + e ; + fail_sampling "raise_if_error" + + and generate_contract : + type arg. + arg Script_typed_ir.ty -> arg Script_typed_ir.typed_contract sampler = + fun arg_ty -> + let open M in + let* addr = value (address_t ~annot:None) in + return (arg_ty, addr) + + and generate_operation : + (Alpha_context.packed_internal_operation + * Alpha_context.Lazy_storage.diffs option) + sampler = + fun rng_state -> + let transfer = generate_transfer_tokens rng_state in + (transfer, None) + + and generate_transfer_tokens : + Alpha_context.packed_internal_operation sampler = + fun _rng_state -> fail_sampling "generate_transfer_tokens: unimplemented" + + and generate_bls12_381_g1 : Environment.Bls12_381.G1.t sampler = + fun rng_state -> + let b = Bls12_381.G1.(to_bytes (random ~state:rng_state ())) in + match Environment.Bls12_381.G1.of_bytes_opt b with + | Some x -> x + | None -> assert false + + and generate_bls12_381_g2 : Environment.Bls12_381.G2.t sampler = + fun rng_state -> + let b = Bls12_381.G2.(to_bytes (random ~state:rng_state ())) in + match Environment.Bls12_381.G2.of_bytes_opt b with + | Some x -> x + | None -> assert false + + and generate_bls12_381_fr : Environment.Bls12_381.Fr.t sampler = + fun rng_state -> + let b = Bls12_381.Fr.(to_bytes (random ~state:rng_state ())) in + match Environment.Bls12_381.Fr.of_bytes_opt b with + | Some x -> x + | None -> assert false + + and generate_ticket : + type a. a Script_typed_ir.ty -> a Script_typed_ir.ticket sampler = + fun ty rng_state -> + let contents = value ty rng_state in + let ticketer = + Alpha_context.Contract.implicit_contract (Crypto_samplers.pkh rng_state) + in + let amount = Michelson_base.nat rng_state in + Script_typed_ir.{ticketer; contents; amount} + + let comparable ty = value (comparable_downcast ty) + + (* Random stack generation. *) + let rec stack : type a b. (a, b) Script_typed_ir.stack_ty -> (a * b) sampler + = + let open M in + let open Script_typed_ir in + fun stack_ty -> + match stack_ty with + | Item_t (ty, tl, _) -> + let* elt = value ty in + let* tl = stack tl in + return ((elt, tl) : a * b) + | Bot_t -> return (EmptyCell, EmptyCell) + end +end + +module Internal_for_tests = struct + type nonrec type_name = type_name +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers.mli b/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers.mli new file mode 100644 index 000000000000..813638f3cab2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers.mli @@ -0,0 +1,131 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Sampling various Michelson values. *) + +open Protocol +open Base_samplers + +(** This module exposes a functor implementing various samplers for Michelson. + These allow to sample: + - types and comparable types (given a target size), + - values and comparable values of a given Michelson type (given some more + parameters fixed at functor instantiation time) + - stacks + + Note that some kind of values might not be supported. At the time of writing, + the value sampler doesn't handle the following types: + - Sapling transaction and states + - Timelock chests and chest keys + - Operations + - Lambdas (ie code) + + For the latter, consider using the samplers in {!Michelson_mcmc_samplers}. +*) + +(** Parameters for the Michelson samplers. *) +type parameters = { + base_parameters : Michelson_samplers_base.parameters; + list_size : Base_samplers.range; + (** The range of the size, measured in number of elements, in which lists must be sampled.*) + set_size : Base_samplers.range; + (** The range of the size, measured in number of elements, in which sets must be sampled.*) + map_size : Base_samplers.range; + (** The range of the size, measured in number of bindings, in which maps must be sampled.*) +} + +(** Encoding for sampler prameters. *) +val parameters_encoding : parameters Data_encoding.t + +(** The module type produced by the [Make] functor. *) +module type S = sig + (** Basic Michelson samplers, re-exported for convenience by the functor. *) + module Michelson_base : Michelson_samplers_base.S + + (** Samplers for random Michelson types. *) + module Random_type : sig + (** [m_type ~size] samples a type containing exactly [size] constructors. *) + val m_type : size:int -> Script_ir_translator.ex_ty sampler + + (** [m_comparable_type ~size] samples a comparable type containing + exactly [size] constructors. *) + val m_comparable_type : + size:int -> Script_ir_translator.ex_comparable_ty sampler + end + + (** Samplers for random Michelson values. Restrictions apply on the + supported types as listed at the beginning of this file. *) + module rec Random_value : sig + (** Sample a value given its type. *) + val value : 'a Script_typed_ir.ty -> 'a sampler + + (** Sample a comparable value given its type. *) + val comparable : 'a Script_typed_ir.comparable_ty -> 'a sampler + + (** Sample a stack given its type. *) + val stack : ('a, 'b) Script_typed_ir.stack_ty -> ('a * 'b) sampler + end +end + +(** Instantiate a module of type {!S}. *) +module Make : functor + (P : sig + val parameters : parameters + end) + (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) + -> S + +module Internal_for_tests : sig + type type_name = + [ `TAddress + | `TBig_map + | `TBls12_381_fr + | `TBls12_381_g1 + | `TBls12_381_g2 + | `TBool + | `TBytes + | `TChain_id + | `TContract + | `TInt + | `TKey + | `TKey_hash + | `TLambda + | `TList + | `TMap + | `TMutez + | `TNat + | `TOperation + | `TOption + | `TPair + | `TSapling_state + | `TSapling_transaction + | `TSet + | `TSignature + | `TString + | `TTicket + | `TTimestamp + | `TUnion + | `TUnit ] +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers_base.ml b/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers_base.ml new file mode 100644 index 000000000000..c772d60f1008 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers_base.ml @@ -0,0 +1,127 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Sampling_helpers + +(** Parameters for basic samplers *) +type parameters = { + int_size : Base_samplers.range; + string_size : Base_samplers.range; + bytes_size : Base_samplers.range; +} + +(** Encoding for basic samplers parameters *) +let parameters_encoding = + let open Data_encoding in + let range = Base_samplers.range_encoding in + conv + (fun {int_size; string_size; bytes_size} -> + (int_size, string_size, bytes_size)) + (fun (int_size, string_size, bytes_size) -> + {int_size; string_size; bytes_size}) + (obj3 + (req "int_size" range) + (req "string_size" range) + (req "bytes_size" range)) + +(** A module of type [S] packs samplers used to construct basic Michelson values. *) +module type S = sig + val int : Alpha_context.Script_int.z Alpha_context.Script_int.num sampler + + val nat : Alpha_context.Script_int.n Alpha_context.Script_int.num sampler + + val signature : Tezos_crypto.Signature.t sampler + + val string : Alpha_context.Script_string.t sampler + + val bytes : bytes sampler + + val tez : Alpha_context.Tez.tez sampler + + val timestamp : Alpha_context.Script_timestamp.t sampler +end + +(* Samplers for basic Michelson types. *) + +module Make (P : sig + val parameters : parameters +end) : S = struct + let int rng_state = + let i = Base_samplers.int ~size:P.parameters.int_size rng_state in + Alpha_context.Script_int.of_zint i + + let nat rng_state = + let i = Base_samplers.nat ~size:P.parameters.int_size rng_state in + Alpha_context.Script_int.abs (Alpha_context.Script_int.of_zint i) + + let signature rng_state = + let i = Random.State.int rng_state 4 in + match i with + | 0 -> ( + let open Ed25519 in + let bytes = Base_samplers.uniform_bytes ~nbytes:size rng_state in + match of_bytes_opt bytes with + | None -> assert false + | Some s -> Signature.of_ed25519 s) + | 1 -> ( + let open Secp256k1 in + let bytes = Base_samplers.uniform_bytes ~nbytes:size rng_state in + match of_bytes_opt bytes with + | None -> assert false + | Some s -> Signature.of_secp256k1 s) + | 2 -> ( + let open P256 in + let bytes = Base_samplers.uniform_bytes ~nbytes:size rng_state in + match of_bytes_opt bytes with + | None -> assert false + | Some s -> Signature.of_p256 s) + | _ -> ( + let open Signature in + let bytes = Base_samplers.uniform_bytes ~nbytes:size rng_state in + match of_bytes_opt bytes with None -> assert false | Some s -> s) + + let string rng_state = + let s = + Base_samplers.readable_ascii_string + ~size:P.parameters.string_size + rng_state + in + match Protocol.Alpha_context.Script_string.of_string s with + | Ok s -> s + | Error _ -> assert false + + let bytes = Base_samplers.bytes ~size:P.parameters.bytes_size + + let tez rng_state = + let i = Random.State.int64 rng_state (Int64.of_int max_int) in + match Protocol.Alpha_context.Tez.of_mutez i with + | Some res -> res + | None -> assert false + + let timestamp rng_state = + let i = Base_samplers.int ~size:P.parameters.int_size rng_state in + Protocol.Alpha_context.Script_timestamp.of_zint i +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers_base.mli b/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers_base.mli new file mode 100644 index 000000000000..975dd002bc1f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/michelson_samplers_base.mli @@ -0,0 +1,67 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Samplers for basic Michelson values (not including pairs, unions, tickets, big maps, etc) *) + +open Protocol +open Base_samplers + +(** Parameters for basic samplers *) +type parameters = { + int_size : Base_samplers.range; + (** The range of the size, measured in bytes, in which big integers must be sampled.*) + string_size : Base_samplers.range; + (** The range of the size, measured in bytes, in which strings must be sampled.*) + bytes_size : Base_samplers.range; + (** The range of the size, measured in bytes, in which [bytes] must be sampled.*) +} + +(** Encoding for [parameters] *) +val parameters_encoding : parameters Data_encoding.t + +(** A module of type [S] packs samplers used to construct basic Michelson values. *) +module type S = sig + val int : Alpha_context.Script_int.z Alpha_context.Script_int.num sampler + + val nat : Alpha_context.Script_int.n Alpha_context.Script_int.num sampler + + val signature : Tezos_crypto.Signature.t sampler + + val string : Alpha_context.Script_string.t sampler + + val bytes : bytes sampler + + val tez : Alpha_context.Tez.tez sampler + + val timestamp : Alpha_context.Script_timestamp.t sampler +end + +(** The [Make] functor instantiates a module of type [S], where the + samplers satisfy the given parameters. *) +module Make : functor + (P : sig + val parameters : parameters + end) + -> S diff --git a/src/proto_012_PsiThaCa/lib_benchmark/mikhailsky_to_michelson.ml b/src/proto_012_PsiThaCa/lib_benchmark/mikhailsky_to_michelson.ml new file mode 100644 index 000000000000..dbe7dd24789f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/mikhailsky_to_michelson.ml @@ -0,0 +1,229 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +exception Cannot_get_type of Mikhailsky.node * Kernel.Path.t + +exception Unexpected_stack_type of string + +exception Unexpected_base_type + +let unparse_type = Mikhailsky.map_var (fun _ -> Mikhailsky.prim T_unit [] []) + +let project_top (aft : Type.Stack.t) = + match aft.node with + | Type.Stack.Empty_t -> raise (Unexpected_stack_type "empty") + | Type.Stack.Stack_var_t _ -> raise (Unexpected_stack_type "var") + | Type.Stack.Item_t (top, _) -> top + +let project_union (aft : Type.Stack.t) = + let top = project_top aft in + match top.node with + | Type.Base.Union_t (l, r) -> (l, r) + | _ -> raise Unexpected_base_type + +let project_lambda (aft : Type.Stack.t) = + let top = project_top aft in + match top.node with + | Type.Base.Lambda_t (dom, range) -> (dom, range) + | _ -> raise Unexpected_base_type + +let project_list (aft : Type.Stack.t) = + let top = project_top aft in + match top.node with + | Type.Base.List_t t -> t + | _ -> raise Unexpected_base_type + +let project_set (aft : Type.Stack.t) = + let top = project_top aft in + match top.node with Type.Base.Set_t t -> t | _ -> raise Unexpected_base_type + +let project_map (aft : Type.Stack.t) = + let top = project_top aft in + match top.node with + | Type.Base.Map_t (k, v) -> (k, v) + | _ -> raise Unexpected_base_type + +let project_option (aft : Type.Stack.t) = + let top = project_top aft in + match top.node with + | Type.Base.Option_t t -> t + | _ -> raise Unexpected_base_type + +let rec convert_raw : Mikhailsky.node -> (int, 'a) Micheline.node = + fun node -> + match node with + | Micheline.Int (_, i) -> Micheline.Int (0, i) + | Micheline.Prim (_, head, subterms, annots) -> + let head = Mikhailsky_prim.to_michelson head in + Micheline.Prim (0, head, List.map convert_raw subterms, annots) + | Micheline.String (_, s) -> Micheline.String (0, s) + | Micheline.Bytes (_, b) -> Micheline.Bytes (0, b) + | Micheline.Seq (_, subterms) -> + Micheline.Seq (0, List.map convert_raw subterms) + +(* We assume that the term has been completed. *) +let rec convert : + Mikhailsky.node -> Kernel.Path.t -> (int, 'a) Micheline.node Inference.M.t = + fun node path -> + let open Inference.M in + match node with + | Micheline.Int (_, i) -> return (Micheline.Int (0, i)) + | Micheline.String (_, s) -> return (Micheline.String (0, s)) + | Micheline.Bytes (_, b) -> return (Micheline.Bytes (0, b)) + (* Remove annotations *) + | Micheline.Prim (_, prim, [term], _) + when Mikhailsky_prim.kind prim = Annot_kind -> + let path = Kernel.Path.at_index 0 path in + convert term path + (* Fail on holes *) + | Micheline.Prim (_, I_Hole, _, _) | Micheline.Prim (_, D_Hole, _, _) -> + raise Mikhailsky.Term_contains_holes + (* Add type information to union injections *) + | Micheline.Prim (_, I_LEFT, [], annots) -> ( + get_instr_annot path >>= fun ty_opt -> + match ty_opt with + | None -> raise (Cannot_get_type (node, path)) + | Some {aft; _} -> + Inference.instantiate aft >>= fun aft -> + let (_, r) = project_union aft in + Inference.instantiate_base r >>= fun r -> + Autocomp.replace_vars r >>= fun r -> + let r = unparse_type r in + let head = Mikhailsky_prim.to_michelson I_LEFT in + return (Micheline.Prim (0, head, [convert_raw r], annots))) + | Micheline.Prim (_, I_RIGHT, [], annots) -> ( + get_instr_annot path >>= fun ty_opt -> + match ty_opt with + | None -> raise (Cannot_get_type (node, path)) + | Some {aft; _} -> + Inference.instantiate aft >>= fun aft -> + let (l, _) = project_union aft in + Inference.instantiate_base l >>= fun l -> + Autocomp.replace_vars l >>= fun l -> + let l = unparse_type l in + let head = Mikhailsky_prim.to_michelson I_RIGHT in + return (Micheline.Prim (0, head, [convert_raw l], annots))) + | Micheline.Prim (_, (I_LEFT | I_RIGHT), _, _) -> + raise Mikhailsky.Ill_formed_mikhailsky + (* Add type information for lambdas *) + | Micheline.Prim (_, I_LAMBDA, [code], annots) -> ( + convert code (Kernel.Path.at_index 0 path) >>= fun code -> + get_instr_annot path >>= fun ty_opt -> + match ty_opt with + | None -> raise (Cannot_get_type (node, path)) + | Some {aft; _} -> + Inference.instantiate aft >>= fun aft -> + let (dom, range) = project_lambda aft in + Inference.instantiate_base dom >>= fun dom -> + Autocomp.replace_vars dom >>= fun dom -> + Inference.instantiate_base range >>= fun range -> + Autocomp.replace_vars range >>= fun range -> + let dom = unparse_type dom in + let range = unparse_type range in + let head = Mikhailsky_prim.to_michelson I_LAMBDA in + return + (Micheline.Prim + (0, head, [convert_raw dom; convert_raw range; code], annots))) + (* Add type information for empty_set, empty_map *) + | Micheline.Prim (_, I_EMPTY_SET, [], annots) -> ( + get_instr_annot path >>= fun ty_opt -> + match ty_opt with + | None -> raise (Cannot_get_type (node, path)) + | Some {aft; _} -> + Inference.instantiate aft >>= fun aft -> + let elt = project_set aft in + Inference.instantiate_base elt >>= fun elt -> + Autocomp.replace_vars elt >>= fun elt -> + let elt = unparse_type elt in + let head = Mikhailsky_prim.to_michelson I_EMPTY_SET in + return (Micheline.Prim (0, head, [convert_raw elt], annots))) + | Micheline.Prim (_, I_EMPTY_MAP, [], annots) -> ( + get_instr_annot path >>= fun ty_opt -> + match ty_opt with + | None -> raise (Cannot_get_type (node, path)) + | Some {aft; _} -> + Inference.instantiate aft >>= fun aft -> + let (k, v) = project_map aft in + Inference.instantiate_base k >>= fun k -> + Autocomp.replace_vars k >>= fun k -> + Inference.instantiate_base v >>= fun v -> + Autocomp.replace_vars v >>= fun v -> + let k = convert_raw (unparse_type k) in + let v = convert_raw (unparse_type v) in + let head = Mikhailsky_prim.to_michelson I_EMPTY_MAP in + return (Micheline.Prim (0, head, [k; v], annots))) + (* Add type information for UNPACK *) + | Micheline.Prim (_, I_UNPACK, [], annots) -> ( + get_instr_annot path >>= fun ty_opt -> + match ty_opt with + | None -> raise (Cannot_get_type (node, path)) + | Some {aft; _} -> + Inference.instantiate aft >>= fun aft -> + let elt = project_option aft in + Inference.instantiate_base elt >>= fun elt -> + Autocomp.replace_vars elt >>= fun elt -> + let elt = unparse_type elt in + let head = Mikhailsky_prim.to_michelson I_UNPACK in + return (Micheline.Prim (0, head, [convert_raw elt], annots))) + (* Add type information for NIL *) + | Micheline.Prim (_, I_NIL, [], annots) -> ( + get_instr_annot path >>= fun ty_opt -> + match ty_opt with + | None -> raise (Cannot_get_type (node, path)) + | Some {aft; _} -> + Inference.instantiate aft >>= fun aft -> + let elt = project_list aft in + Inference.instantiate_base elt >>= fun elt -> + Autocomp.replace_vars elt >>= fun elt -> + let elt = unparse_type elt in + let head = Mikhailsky_prim.to_michelson I_NIL in + return (Micheline.Prim (0, head, [convert_raw elt], annots))) + | Micheline.Prim (_, I_NIL, _, _) -> raise Mikhailsky.Ill_formed_mikhailsky + (* Project out type information from arithmetic ops *) + | Prim (_, ((I_ADD | I_SUB | I_MUL | I_EDIV) as instr), [_ty1; _ty2], annots) + -> + let head = Mikhailsky_prim.to_michelson instr in + return (Micheline.Prim (0, head, [], annots)) + | Prim (_, (I_ADD | I_SUB | I_MUL | I_EDIV), _, _) -> + raise Mikhailsky.Ill_formed_mikhailsky + (* Base case *) + | Micheline.Prim (_, head, subterms, annots) -> + let head = Mikhailsky_prim.to_michelson head in + convert_list path 0 subterms [] >>= fun subterms -> + return (Micheline.Prim (0, head, subterms, annots)) + | Micheline.Seq (_, subterms) -> + convert_list path 0 subterms [] >>= fun subterms -> + return (Micheline.Seq (0, subterms)) + +and convert_list path i subterms acc = + let open Inference.M in + match subterms with + | [] -> return (List.rev acc) + | subterm :: tl -> + let path' = Kernel.Path.at_index i path in + convert subterm path' >>= fun term -> + convert_list path (i + 1) tl (term :: acc) + +let convert node state = fst (convert node Kernel.Path.root state) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/rules.ml b/src/proto_012_PsiThaCa/lib_benchmark/rules.ml new file mode 100644 index 000000000000..ff66cf05c7c4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/rules.ml @@ -0,0 +1,975 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Kernel + +type rule_set = {rule_patt : pattern; replacements : guarded_replacement list} + +and guarded_replacement = { + type_constraint : type_constraint; + replacement : replacement list; +} + +and type_constraint = + | No_cnstrnt + | Data_cnstrnt of {cnstrnt : Type.Base.t; fresh : int list} + | Instr_cnstrnt of { + cnstrnt : Inference.transformer; + fresh : var list; + fresh_stack : int list; + } + +and replacement = + | Context_aware of (Mikhailsky.node -> Mikhailsky.node) + | Context_blind of (unit -> Mikhailsky.node) + +and pattern = Pattern of Patt.t | Root + +and var = Plain of int | Cmp of int + +let stack_repr = Inference.Stack_type None + +let base_repr = + Inference.Base_type {repr = None; comparable = Inference.Unconstrained} + +let cmp_repr = + Inference.Base_type {repr = None; comparable = Inference.Comparable} + +let rec add_fresh_stack_variables vars = + let open Inference.M in + match vars with + | [] -> return () + | fresh :: tl -> + uf_lift (Uf.UF.add fresh) >>= fun () -> + set_repr fresh stack_repr >>= fun () -> add_fresh_stack_variables tl + +let rec add_fresh_data_variables vars = + let open Inference.M in + match vars with + | [] -> return () + | fresh :: tl -> + uf_lift (Uf.UF.add fresh) >>= fun () -> + set_repr fresh base_repr >>= fun () -> add_fresh_data_variables tl + +let rec add_fresh_variables vars plain_repr cmp_repr = + let open Inference.M in + match vars with + | [] -> return () + | Plain fresh :: tl -> + uf_lift (Uf.UF.add fresh) >>= fun () -> + set_repr fresh plain_repr >>= fun () -> + add_fresh_variables tl plain_repr cmp_repr + | Cmp fresh :: tl -> + uf_lift (Uf.UF.add fresh) >>= fun () -> + set_repr fresh cmp_repr >>= fun () -> + add_fresh_variables tl plain_repr cmp_repr + +let evaluate_guard_monadic guard path = + let open Inference.M in + match guard with + | No_cnstrnt -> return () + | Data_cnstrnt {cnstrnt = base_type_constraint; fresh} -> ( + add_fresh_data_variables fresh >>= fun () -> + get_data_annot path >>= fun res_opt -> + match res_opt with + | None -> assert false + | Some type_of_expr -> + Inference.unify_base type_of_expr base_type_constraint >>= fun () -> + Inference.instantiate_base type_of_expr >>= fun _ -> return ()) + | Instr_cnstrnt {cnstrnt = {bef = pre; aft = post}; fresh; fresh_stack} -> ( + (* Add base fresh type variables *) + add_fresh_variables fresh base_repr cmp_repr + >>= fun () -> + add_fresh_stack_variables fresh_stack >>= fun () -> + get_instr_annot path >>= fun res_opt -> + match res_opt with + | None -> assert false + | Some {bef; aft} -> + Inference.unify pre bef >>= fun () -> + Inference.unify post aft >>= fun () -> + Inference.instantiate bef >>= fun _bef -> + Inference.instantiate aft >>= fun _aft -> return ()) + +let evaluate_guard typing guard path = + try + let _ = evaluate_guard_monadic guard path typing in + true + with Inference.Ill_typed_script _ -> false + +let filter_matches typing guard matches = + List.filter (evaluate_guard typing guard) matches + +(* Provides a speedup but should better be done in the + rewriting module (so that not only top matches are hash-consed). *) +let matches_with_hash_consing = + let match_table : (int * int, Kernel.Path.t list) Hashtbl.t = + Hashtbl.create 97 + in + fun pattern term -> + match pattern with + | Root -> [Path.root] + | Pattern patt -> ( + let key = (Kernel.Patt.uid patt, Mikhailsky.tag term) in + match Hashtbl.find_opt match_table key with + | None -> + let res = Rewriter.all_matches patt term in + Hashtbl.add match_table key res ; + res + | Some res -> res) + +let matches_without_consing pattern term = + match pattern with + | Root -> [Path.root] + | Pattern patt -> Rewriter.all_matches patt term + +let rewriting (state : State_space.t) (rules : rule_set list) = + List.fold_left + (fun acc rule -> + let matches = matches_without_consing rule.rule_patt state.term in + List.fold_left + (fun acc guarded_replacement -> + let matches = + filter_matches + (Lazy.force state.typing) + guarded_replacement.type_constraint + matches + in + List.fold_left + (fun acc replacement -> + match replacement with + | Context_blind term -> + List.fold_left + (fun acc path -> (path, term ()) :: acc) + acc + matches + | Context_aware f -> + List.fold_left + (fun acc path -> + let term = Rewriter.get_subterm ~term:state.term ~path in + (path, f term) :: acc) + acc + matches) + acc + guarded_replacement.replacement) + acc + rule.replacements) + [] + rules + +module Instruction = struct + (* ----------------------------------------------------------------------- *) + (* Rule: replace instruction by hole. *) + + (* Matches instructions *) + let match_any_instr = + let open Patt in + Pattern + (focus + (prim_pred + (fun prim -> Mikhailsky_prim.kind prim = Mikhailsky_prim.Instr_kind) + list_any)) + + let replace_any_instr_by_hole = + let replace_by_hole = + { + type_constraint = No_cnstrnt; + replacement = [Context_blind (fun () -> Mikhailsky.instr_hole)]; + } + in + {rule_patt = match_any_instr; replacements = [replace_by_hole]} + + (* ----------------------------------------------------------------------- *) + (* Rule: replace instruction hole by instruction satisfying typing + constraints. *) + + (* Matches instruction holes *) + let match_instr_hole = + let open Patt in + Pattern (focus (prim I_Hole list_any)) + + let replacement ?(fresh = []) ?(fresh_stack = []) ~bef ~aft ~replacement () : + guarded_replacement = + { + type_constraint = Instr_cnstrnt {cnstrnt = {bef; aft}; fresh; fresh_stack}; + replacement; + } + + let instructions = + let open Type in + let module M = Mikhailsky in + let module I = Inference in + let alpha = ~-1 in + let beta = ~-2 in + let gamma = ~-3 in + let delta = ~-4 in + [ + replacement + ~fresh_stack:[alpha] + ~bef:(item bytes (stack_var alpha)) + ~aft:(item bytes (stack_var alpha)) + ~replacement: + [ + Context_blind (fun () -> M.Instructions.blake2b); + Context_blind (fun () -> M.Instructions.sha256); + Context_blind (fun () -> M.Instructions.sha512); + ] + (); + replacement + ~fresh_stack:[alpha] + ~bef:(item int (stack_var alpha)) + ~aft:(item bool (stack_var alpha)) + ~replacement:[Context_blind (fun () -> M.Instructions.gt)] + (); + replacement + ~fresh_stack:[alpha] + ~bef:(item int (stack_var alpha)) + ~aft:(item nat (stack_var alpha)) + ~replacement:[Context_blind (fun () -> M.Instructions.abs)] + (); + replacement + ~fresh_stack:[alpha] + ~bef:(item int (item int (stack_var alpha))) + ~aft:(item int (stack_var alpha)) + ~replacement: + [ + Context_blind (fun () -> M.Instructions.add M.int_ty M.int_ty); + Context_blind (fun () -> M.Instructions.mul M.int_ty M.int_ty); + ] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(item (pair (var alpha) (var beta)) (stack_var gamma)) + ~aft:(item (var alpha) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.car)] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(item (pair (var alpha) (var beta)) (stack_var gamma)) + ~aft:(item (var beta) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.cdr)] + (); + replacement + ~fresh:[Cmp alpha] + ~fresh_stack:[gamma] + ~bef:(item (var alpha) (item (var alpha) (stack_var gamma))) + ~aft:(item int (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.compare)] + (); + replacement + ~fresh_stack:[gamma] + ~bef:(item string (item string (stack_var gamma))) + ~aft:(item string (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.concat)] + (); + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[beta; gamma] + ~bef:(item (var alpha) (stack_var beta)) + ~aft:(item (var alpha) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.(dip hole))] + (); + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[beta] + ~bef:(item (var alpha) (stack_var beta)) + ~aft:(stack_var beta) + ~replacement:[Context_blind (fun () -> M.Instructions.drop)] + (); + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[beta] + ~bef:(item (var alpha) (stack_var beta)) + ~aft:(item (var alpha) (item (var alpha) (stack_var beta))) + ~replacement:[Context_blind (fun () -> M.Instructions.dup)] + (); + replacement + ~fresh:[] + ~fresh_stack:[alpha] + ~bef:(stack_var alpha) + ~aft:(item int (stack_var alpha)) + ~replacement: + [ + (* TODO : push random integer? *) + Context_blind + (fun () -> M.Instructions.push M.int_ty (M.Data.integer 100)); + ] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(item (var alpha) (item (var beta) (stack_var gamma))) + ~aft:(item (var beta) (item (var alpha) (stack_var gamma))) + ~replacement:[Context_blind (fun () -> M.Instructions.swap)] + (); + (* control *) + replacement + ~fresh_stack:[alpha] + ~bef:(item bool (stack_var alpha)) + ~aft:(stack_var alpha) + ~replacement:[Context_blind (fun () -> M.Instructions.(loop hole))] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(item (union (var alpha) (var beta)) (stack_var gamma)) + ~aft:(item (var beta) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.(loop_left hole))] + (); + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[beta; gamma] + ~bef:(item (option (var alpha)) (stack_var beta)) + ~aft:(stack_var gamma) + ~replacement: + [Context_blind (fun () -> M.Instructions.(if_none hole hole))] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma; delta] + ~bef:(item (union (var alpha) (var beta)) (stack_var gamma)) + ~aft:(stack_var delta) + ~replacement: + [Context_blind (fun () -> M.Instructions.(if_left hole hole))] + (); + replacement + ~fresh:[] + ~fresh_stack:[alpha; beta] + ~bef:(item bool (stack_var alpha)) + ~aft:(stack_var beta) + ~replacement:[Context_blind (fun () -> M.Instructions.(if_ hole hole))] + (); + replacement + ~fresh_stack:[alpha; beta] + ~bef:(stack_var alpha) + ~aft:(stack_var beta) + ~replacement: + [ + Context_blind + (fun () -> M.seq [M.Instructions.hole; M.Instructions.hole]); + ] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(item (var alpha) (stack_var gamma)) + ~aft:(item (union (var alpha) (var beta)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.left)] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(item (var beta) (stack_var gamma)) + ~aft:(item (union (var alpha) (var beta)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.right)] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(stack_var gamma) + ~aft:(item (lambda (var alpha) (var beta)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.(lambda [hole]))] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(stack_var gamma) + ~aft:(item (lambda (var alpha) (var beta)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.(lambda [hole]))] + (); + (* set/map/list*) + replacement + ~fresh:[Cmp alpha] + ~fresh_stack:[gamma] + ~bef: + (item + (var alpha) + (item bool (item (set (var alpha)) (stack_var gamma)))) + ~aft:(item (set (var alpha)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.update_set)] + (); + replacement + ~fresh:[Cmp alpha] + ~fresh_stack:[gamma] + ~bef:(stack_var gamma) + ~aft:(item (set (var alpha)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.empty_set)] + (); + replacement + ~fresh:[Cmp alpha] + ~fresh_stack:[gamma] + ~bef:(item (set (var alpha)) (stack_var gamma)) + ~aft:(stack_var gamma) + ~replacement: + [Context_blind (fun () -> M.Instructions.(iter_set [hole]))] + (); + replacement + ~fresh:[Cmp alpha] + ~fresh_stack:[gamma] + ~bef:(item (var alpha) (item (set (var alpha)) (stack_var gamma))) + ~aft:(item bool (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.mem_set)] + (); + replacement + ~fresh:[Cmp alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef: + (item + (var alpha) + (item + (option (var beta)) + (item (map (var alpha) (var beta)) (stack_var gamma)))) + ~aft:(item (map (var alpha) (var beta)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.update_map)] + (); + replacement + ~fresh:[Cmp alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(stack_var gamma) + ~aft:(item (map (var alpha) (var beta)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.empty_map)] + (); + replacement + ~fresh:[Cmp alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(item (map (var alpha) (var beta)) (stack_var gamma)) + ~aft:(stack_var gamma) + ~replacement: + [Context_blind (fun () -> M.Instructions.(iter_map [hole]))] + (); + replacement + ~fresh:[Cmp alpha; Plain beta; Plain delta] + ~fresh_stack:[gamma] + ~bef:(item (map (var alpha) (var beta)) (stack_var gamma)) + ~aft:(item (map (var alpha) (var delta)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.(map_map [hole]))] + (); + replacement + ~fresh:[Cmp alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef: + (item + (var alpha) + (item (map (var alpha) (var beta)) (stack_var gamma))) + ~aft:(item bool (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.mem_map)] + (); + replacement + ~fresh:[Cmp alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef: + (item + (var alpha) + (item (map (var alpha) (var beta)) (stack_var gamma))) + ~aft:(item (option (var beta)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.get_map)] + (); + (* lists *) + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[gamma] + ~bef:(stack_var gamma) + ~aft:(item (list (var alpha)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.nil)] + (); + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[gamma] + ~bef:(item (var alpha) (item (list (var alpha)) (stack_var gamma))) + ~aft:(item (list (var alpha)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.cons)] + (); + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[gamma] + ~bef:(item (list (var alpha)) (stack_var gamma)) + ~aft:(stack_var gamma) + ~replacement: + [Context_blind (fun () -> M.Instructions.(iter_list [hole]))] + (); + replacement + ~fresh:[Plain alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(item (list (var alpha)) (stack_var gamma)) + ~aft:(item (list (var beta)) (stack_var gamma)) + ~replacement: + [Context_blind (fun () -> M.Instructions.(map_list [hole]))] + (); + (* sizes *) + replacement + ~fresh:[Cmp alpha] + ~fresh_stack:[gamma] + ~bef:(item (set (var alpha)) (stack_var gamma)) + ~aft:(item nat (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.size_set)] + (); + replacement + ~fresh:[Cmp alpha; Plain beta] + ~fresh_stack:[gamma] + ~bef:(item (map (var alpha) (var beta)) (stack_var gamma)) + ~aft:(item nat (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.size_map)] + (); + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[gamma] + ~bef:(item (list (var alpha)) (stack_var gamma)) + ~aft:(item nat (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.size_list)] + (); + replacement + ~fresh:[] + ~fresh_stack:[gamma] + ~bef:(item string (stack_var gamma)) + ~aft:(item nat (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.size_string)] + (); + replacement + ~fresh:[] + ~fresh_stack:[gamma] + ~bef:(item bytes (stack_var gamma)) + ~aft:(item nat (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.size_bytes)] + (); + (* pack/unpack *) + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[gamma] + ~bef:(item (var alpha) (stack_var gamma)) + ~aft:(item bytes (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.pack)] + (); + replacement + ~fresh:[Plain alpha] + ~fresh_stack:[gamma] + ~bef:(item bytes (stack_var gamma)) + ~aft:(item (option (var alpha)) (stack_var gamma)) + ~replacement:[Context_blind (fun () -> M.Instructions.unpack)] + (); + ] + + let rules = + [ + replace_any_instr_by_hole; + {rule_patt = match_instr_hole; replacements = instructions}; + ] +end + +module Data_rewrite_leaves + (Michelson_base : Michelson_samplers_base.S) + (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) = +struct + let hole_patt = + let open Patt in + prim_pred (fun prim -> prim = D_Hole) list_empty + + (* Matches a data hole *) + let match_hole = + let open Patt in + Pattern (focus hole_patt) + + (* Matches an integer literal *) + let match_int = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = A_Int) list_any)) + + (* Matches a list literal *) + let match_list = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = A_List) list_any)) + + (* Matches a set literal *) + let match_set = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = A_Set) list_any)) + + (* Matches a map literal *) + let match_map = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = A_Map) list_any)) + + (* Matches a timestamp literal *) + let match_timestamp = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = A_Timestamp) list_any)) + + (* Matches a mutez literal *) + let match_mutez = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = A_Mutez) list_any)) + + (* Matches a key_hash literal *) + let match_key_hash = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = A_Key_hash) list_any)) + + let match_int_mutez_timestamp_key_hash_key_or_none = + let open Patt in + Pattern + (focus + (prim_pred + (function + | A_Int | A_Nat | A_Mutez | A_Timestamp | A_Key_hash | A_Key + | D_None -> + true + | _ -> false) + list_any)) + + (* Matches an empty list, set or map literal *) + let match_empty_list_set_or_map = + let open Patt in + Pattern + (focus + (prim_pred + (function A_List | A_Set | A_Map -> true | _ -> false) + (list_cons (seq list_empty) list_empty))) + + (* Matches a pair containing two holes*) + let match_empty_pair = + let open Patt in + Pattern + (focus + (prim_pred + (fun prim -> prim = D_Pair) + (list_cons hole_patt (list_cons hole_patt list_empty)))) + + (* Match a Some, Left or Right containing a hole *) + let match_empty_some_left_or_right = + let open Patt in + Pattern + (focus + (prim_pred + (function D_Left | D_Right | D_Some -> true | _ -> false) + (list_cons hole_patt list_empty))) + + (* Match a None constructor *) + let match_none = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = D_None) list_empty)) + + (* rules *) + + (* fresh type variables *) + let (alpha, beta) = (-1, -2) + + let replacement ~fresh ~typ ~replacement = + { + type_constraint = Data_cnstrnt {cnstrnt = typ; fresh}; + replacement = [Context_blind (fun () -> replacement)]; + } + + let replacement_gen ~fresh ~typ ~replacement = + { + type_constraint = Data_cnstrnt {cnstrnt = typ; fresh}; + replacement = [Context_blind replacement]; + } + + let fill_in_hole rng_state = + let replace_by_singleton_list = + replacement + ~fresh:[alpha] + ~typ:Type.(list (var alpha)) + ~replacement:Mikhailsky.Data.(list [hole]) + in + let replace_by_empty_pair = + replacement + ~fresh:[alpha; beta] + ~typ:Type.(pair (var alpha) (var beta)) + ~replacement:Mikhailsky.Data.(pair hole hole) + in + let replace_by_singleton_set = + replacement + ~fresh:[alpha] + ~typ:Type.(set (var alpha)) + ~replacement:Mikhailsky.Data.(set [hole]) + in + let replace_by_singleton_map = + replacement + ~fresh:[alpha; beta] + ~typ:Type.(map (var alpha) (var beta)) + ~replacement:Mikhailsky.Data.(map [map_elt hole hole]) + in + let replace_by_random_int rng_state = + let type_constraint = Data_cnstrnt {cnstrnt = Type.int; fresh = []} in + let replacement = + Context_blind + (fun () -> + Mikhailsky.Data.big_integer + (Protocol.Script_int_repr.to_zint (Michelson_base.int rng_state))) + in + {type_constraint; replacement = [replacement]} + in + let replace_by_left = + replacement + ~fresh:[alpha; beta] + ~typ:Type.(union (var alpha) (var beta)) + ~replacement:Mikhailsky.Data.(left hole) + in + let replace_by_right = + replacement + ~fresh:[alpha; beta] + ~typ:Type.(union (var alpha) (var beta)) + ~replacement:Mikhailsky.Data.(right hole) + in + let replace_by_some = + replacement + ~fresh:[alpha] + ~typ:Type.(option (var alpha)) + ~replacement:Mikhailsky.Data.(some hole) + in + let replace_by_none = + replacement + ~fresh:[alpha] + ~typ:Type.(option (var alpha)) + ~replacement:Mikhailsky.Data.none + in + let replace_by_mutez rng_state = + replacement_gen ~fresh:[] ~typ:Type.mutez ~replacement:(fun () -> + Mikhailsky.Data.mutez (Michelson_base.tez rng_state)) + in + let replace_by_key_hash rng_state = + replacement_gen ~fresh:[] ~typ:Type.key_hash ~replacement:(fun () -> + Mikhailsky.Data.key_hash (Crypto_samplers.pkh rng_state)) + in + let replace_by_key rng_state = + replacement_gen ~fresh:[] ~typ:Type.key ~replacement:(fun () -> + Mikhailsky.Data.key (Crypto_samplers.pk rng_state)) + in + { + rule_patt = match_hole; + replacements = + [ + replace_by_singleton_list; + replace_by_empty_pair; + replace_by_singleton_set; + replace_by_singleton_map; + replace_by_random_int rng_state; + replace_by_left; + replace_by_right; + replace_by_some; + replace_by_none; + replace_by_mutez rng_state; + replace_by_key_hash rng_state; + replace_by_key rng_state; + ]; + } + + let kill_empty_pair = + { + rule_patt = match_empty_pair; + replacements = + [ + { + type_constraint = No_cnstrnt; + replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; + }; + ]; + } + + let kill_int_mutez_timestamp_key_hash_none = + { + rule_patt = match_int_mutez_timestamp_key_hash_key_or_none; + replacements = + [ + { + type_constraint = No_cnstrnt; + replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; + }; + ]; + } + + let kill_empty_list_set_or_map = + { + rule_patt = match_empty_list_set_or_map; + replacements = + [ + { + type_constraint = No_cnstrnt; + replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; + }; + ]; + } + + let kill_empty_some_left_or_right = + { + rule_patt = match_empty_some_left_or_right; + replacements = + [ + { + type_constraint = No_cnstrnt; + replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; + }; + ]; + } + + let modify_set = + let grow_ungrow_set = + { + type_constraint = No_cnstrnt; + replacement = + [ + Context_aware + (fun set -> + match set with + | Micheline.Prim (_, A_Set, [Micheline.Seq (_, elements)], _) -> + Mikhailsky.Data.(set (hole :: elements)) + | _ -> assert false); + Context_aware + (fun set -> + match set with + | Micheline.Prim (_, A_Set, [Micheline.Seq (_, elements)], _) + -> ( + match elements with + | [] -> Mikhailsky.Data.hole + | _ :: tl -> Mikhailsky.Data.set tl) + | _ -> assert false); + ]; + } + in + {rule_patt = match_set; replacements = [grow_ungrow_set]} + + let modify_map = + let grow_ungrow_map = + { + type_constraint = No_cnstrnt; + replacement = + [ + Context_aware + (fun set -> + match set with + | Micheline.Prim (_, A_Map, [Micheline.Seq (_, elements)], _) -> + Mikhailsky.Data.(map (map_elt hole hole :: elements)) + | _ -> assert false); + Context_aware + (fun set -> + match set with + | Micheline.Prim (_, A_Map, [Micheline.Seq (_, elements)], _) + -> ( + match elements with + | [] -> Mikhailsky.Data.hole + | _ :: tl -> Mikhailsky.Data.map tl) + | _ -> assert false); + ]; + } + in + {rule_patt = match_map; replacements = [grow_ungrow_map]} + + let modify_list = + let grow_ungrow_list = + { + type_constraint = No_cnstrnt; + replacement = + [ + Context_aware + (fun list -> + match list with + | Micheline.Prim (_, A_List, [Micheline.Seq (_, terms)], _) -> + Mikhailsky.Data.(list (hole :: terms)) + | _ -> assert false); + Context_aware + (fun list -> + match list with + | Micheline.Prim (_, A_List, [Micheline.Seq (_, terms)], _) -> ( + match terms with + | [] -> Mikhailsky.Data.hole + | _ :: tl -> Mikhailsky.Data.list tl) + | _ -> assert false); + ]; + } + in + {rule_patt = match_list; replacements = [grow_ungrow_list]} + + let rules rng_state = + [ + fill_in_hole rng_state; + kill_empty_pair; + kill_empty_list_set_or_map; + kill_empty_some_left_or_right; + kill_int_mutez_timestamp_key_hash_none; + modify_list; + modify_set; + modify_map; + ] +end + +module Data + (Michelson_base : Michelson_samplers_base.S) + (Crypto_samplers : Crypto_samplers.Finite_key_pool_S) = +struct + let match_data_node = + let open Patt in + Pattern + (focus + (prim_pred + (function + | Mikhailsky_prim.D_Elt | D_Hole -> false + | D_False | D_Left | D_None | D_Pair | D_Right | D_Some | D_True + | D_Unit | A_Int | A_Nat | A_Set | A_List | A_Map | A_Key_hash + | A_Mutez | A_Timestamp | A_Key -> + true + | _ -> false) + list_any)) + + let match_list = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = A_List) list_any)) + + let match_data_hole = + let open Patt in + Pattern (focus (prim_pred (fun prim -> prim = D_Hole) list_any)) + + let replace_by_hole = + let replace_by_hole = + { + type_constraint = No_cnstrnt; + replacement = [Context_blind (fun () -> Mikhailsky.Data.hole)]; + } + in + {rule_patt = match_data_node; replacements = [replace_by_hole]} + + let pack_root = + let replacement = + [ + Context_aware (fun node -> Mikhailsky.Data.list [node]); + Context_aware (fun node -> Mikhailsky.Data.(pair node hole)); + Context_aware (fun node -> Mikhailsky.Data.(pair hole node)); + ] + in + let guarded_replacements = [{type_constraint = No_cnstrnt; replacement}] in + {rule_patt = Root; replacements = guarded_replacements} + + module Data_rewrite_leaves_rules = + Data_rewrite_leaves (Michelson_base) (Crypto_samplers) + + let rules rng_state = + [ + Data_rewrite_leaves_rules.fill_in_hole rng_state; + replace_by_hole; + Data_rewrite_leaves_rules.modify_list; + Data_rewrite_leaves_rules.modify_map; + Data_rewrite_leaves_rules.modify_set; + ] +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/sampling_helpers.ml b/src/proto_012_PsiThaCa/lib_benchmark/sampling_helpers.ml new file mode 100644 index 000000000000..8b36fc09e0bf --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/sampling_helpers.ml @@ -0,0 +1,41 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* ------------------------------------------------------------------------- *) + +(* TODO: use Statz's def. of sampler once upstreamed. *) +type 'a sampler = Random.State.t -> 'a + +module M = struct + let ( let* ) : 'a sampler -> ('a -> 'b sampler) -> 'b sampler = + fun sampler f rng_state -> + let x = sampler rng_state in + f x rng_state + [@@inline] + + let bind = ( let* ) + + let return x _ = x +end diff --git a/src/proto_012_PsiThaCa/lib_benchmark/state_space.ml b/src/proto_012_PsiThaCa/lib_benchmark/state_space.ml new file mode 100644 index 000000000000..60d14970e610 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/state_space.ml @@ -0,0 +1,78 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* The state of rewriting is a typed term *) +type t = {typing : Inference.state lazy_t; term : Mikhailsky.node} + +let compare (term1 : t) (term2 : t) = + let tag1 = Mikhailsky.tag term1.term in + let tag2 = Mikhailsky.tag term2.term in + if tag1 < tag2 then -1 else if tag1 > tag2 then 1 else 0 + +let equal (term1 : t) (term2 : t) = + let tag1 = Mikhailsky.tag term1.term in + let tag2 = Mikhailsky.tag term2.term in + tag1 = tag2 + +let hash (t : t) = Mikhailsky.hash t.term + +type node_statistics = { + mutable size : int; + mutable bytes : int; + mutable holes : int; + mutable depth : int; +} + +let pp_statistics fmtr stats = + Format.fprintf + fmtr + "{ size = %d ; bytes = %d ; holes = %d }" + stats.size + stats.bytes + stats.holes + +let rec statistics stats depth (n : Mikhailsky.node) = + stats.size <- stats.size + 1 ; + stats.depth <- max depth stats.depth ; + match n with + | Micheline.Int (_, z) -> stats.bytes <- stats.bytes + (Z.numbits z / 8) + | Micheline.String (_, s) -> stats.bytes <- stats.bytes + String.length s + | Micheline.Bytes (_, b) -> stats.bytes <- stats.bytes + Bytes.length b + | Micheline.Prim (_, Mikhailsky_prim.I_Hole, _, _) + | Micheline.Prim (_, Mikhailsky_prim.D_Hole, _, _) -> + stats.holes <- stats.holes + 1 + | Micheline.Prim (_, _, subterms, _) | Micheline.Seq (_, subterms) -> + List.iter (statistics stats (depth + 1)) subterms + +let statistics {term; _} = + let stats = {size = 0; bytes = 0; holes = 0; depth = 0} in + statistics stats 0 term ; + stats + +let pp fmtr (state : t) = + Format.fprintf fmtr "current term:@." ; + Format.fprintf fmtr "%a@." Mikhailsky.pp state.term ; + Format.fprintf fmtr "stats:@." ; + Format.fprintf fmtr "%a:@." pp_statistics (statistics state) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/test/.ocamlformat b/src/proto_012_PsiThaCa/lib_benchmark/test/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/test/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_benchmark/test/dune b/src/proto_012_PsiThaCa/lib_benchmark/test/dune new file mode 100644 index 000000000000..89d44539b809 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/test/dune @@ -0,0 +1,41 @@ +(executables + (names test_sampling_data test_sampling_code test_autocompletion test_distribution) + (libraries tezos-micheline + tezos-micheline-rewriting + tezos-benchmark-type-inference-012-PsiThaCa + tezos-benchmark + tezos-benchmark-012-PsiThaCa + tezos-protocol-012-PsiThaCa + tezos-012-PsiThaCa-test-helpers + tezos-error-monad + alcotest-lwt + prbnmcn-stats) +;; uncomment to enable gprof profiling +;; (ocamlopt_flags (:standard -p -ccopt -no-pie)) + (flags (:standard + -open Tezos_micheline + -open Tezos_protocol_012_PsiThaCa + -open Tezos_benchmark + -open Tezos_benchmark_type_inference_012_PsiThaCa + -open Tezos_benchmark_012_PsiThaCa + -open Tezos_012_PsiThaCa_test_helpers))) + +(alias + (name buildtest) + (deps test_sampling_data.exe test_sampling_code.exe)) + +(rule + (alias runtest_micheline_rewriting_data) + (action (run %{exe:test_sampling_data.exe} 1234))) + +(rule + (alias runtest_micheline_rewriting_code) + (action (run %{exe:test_sampling_code.exe} 1234))) + + +(alias + (name runtest) + (package tezos-benchmark-012-PsiThaCa) + (deps (alias runtest_micheline_rewriting_data) + (alias runtest_micheline_rewriting_code) + )) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/test/test_autocompletion.ml b/src/proto_012_PsiThaCa/lib_benchmark/test/test_autocompletion.ml new file mode 100644 index 000000000000..5d5d65fdee01 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/test/test_autocompletion.ml @@ -0,0 +1,120 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let rng_state = Random.State.make [|42; 987897; 54120|] + +module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct + let algo = `Default + + let size = 16 +end) + +module Michelson_base_samplers = Michelson_samplers_base.Make (struct + let parameters = + let size = {Base_samplers.min = 4; max = 32} in + { + Michelson_samplers_base.int_size = size; + string_size = size; + bytes_size = size; + } +end) + +module Autocomp = Autocomp.Make (Michelson_base_samplers) (Crypto_samplers) + +let () = Format.eprintf "===============================@.%!" + +let () = Format.eprintf "Testing dummy program generator@.%!" + +let run x = x rng_state (Inference.M.empty ()) + +let invent_term bef aft = + let (term, _state) = run (Autocomp.invent_term bef aft) in + Mikhailsky.seq term + +let invent_term bef aft = + Format.eprintf + "requested type: %a => %a@." + Type.Stack.pp + bef + Type.Stack.pp + aft ; + let term = invent_term bef aft in + let (bef', aft') = Inference.infer term in + Format.eprintf + "generated type: %a => %a@." + Type.Stack.pp + bef' + Type.Stack.pp + aft' ; + Format.eprintf "%a@." Mikhailsky.pp term + +module T = Type + +let bef = T.(item unit (item unit (item unit empty))) + +let aft = T.(item int (item unit (item (pair nat nat) empty))) + +let () = invent_term bef aft + +let () = Format.eprintf "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@.%!" + +let () = invent_term bef aft + +let () = Format.eprintf "===============================@.%!" + +let () = Format.eprintf "Testing completion@.%!" + +let complete term = + Format.eprintf "term: %a@." Mikhailsky.pp term ; + let ((bef, aft), state) = Inference.infer_with_state term in + Format.eprintf "Inferred type: %a => %a@." Type.Stack.pp bef Type.Stack.pp aft ; + let (term, (bef', aft'), _state) = + Autocomp.complete_code state term rng_state + in + Format.eprintf "completed: %a@." Mikhailsky.pp term ; + Format.eprintf + "Inferred type after generation: %a => %a@." + Type.Stack.pp + bef' + Type.Stack.pp + aft' ; + let node = + Micheline.strip_locations @@ Mikhailsky_to_michelson.convert term state + in + let bef' = Type_helpers.stack_type_to_michelson_type_list bef' in + Test_helpers.typecheck_by_tezos bef' node + +open Mikhailsky +open Instructions + +let push_int = Instructions.push int_ty (Data.big_integer (Z.of_int 100)) + +let add_ii = Instructions.(add Mikhailsky.int_ty Mikhailsky.int_ty) + +let () = complete (lambda [if_left right (dip (seq [push_int; hole]))]) + +let () = Format.eprintf "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@.%!" + +let () = complete (seq [push_int; add_ii; lambda [dip (seq [dup; dip hole])]]) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/test/test_distribution.ml b/src/proto_012_PsiThaCa/lib_benchmark/test/test_distribution.ml new file mode 100644 index 000000000000..42bbfbc0638c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/test/test_distribution.ml @@ -0,0 +1,182 @@ +open Tezos_benchmark +open Michelson_samplers +open Protocol +open Internal_for_tests + +let pp_type_name fmtr (t : type_name) = + Format.pp_print_string fmtr + @@ + match t with + | `TString -> "string" + | `TNat -> "nat" + | `TPair -> "pair" + | `TKey -> "key" + | `TLambda -> "lambda" + | `TUnion -> "union" + | `TOperation -> "operation" + | `TOption -> "option" + | `TSapling_state -> "sapling_state" + | `TBytes -> "bytes" + | `TChain_id -> "chain_id" + | `TBool -> "bool" + | `TBls12_381_g2 -> "bls12_381_g2" + | `TTicket -> "ticket" + | `TMap -> "map" + | `TAddress -> "address" + | `TContract -> "contract" + | `TBls12_381_fr -> "bls12_381_fr" + | `TSapling_transaction -> "sapling_transaction" + | `TTimestamp -> "timestamp" + | `TKey_hash -> "key_hash" + | `TBig_map -> "big_map" + | `TSet -> "set" + | `TBls12_381_g1 -> "bls12_381_g1" + | `TList -> "list" + | `TMutez -> "mutez" + | `TSignature -> "signature" + | `TUnit -> "unit" + | `TInt -> "int" + +module Type_name = struct + type t = type_name + + let compare (x : t) (y : t) = Stdlib.compare x y + + let equal (x : t) (y : t) = x = y + + let pp = pp_type_name + + let hash = Stdlib.Hashtbl.hash +end + +module Type_name_multiset = + Basic_structures.Basic_impl.Free_module.Float_valued.Make_with_map (Type_name) + +let rec tnames_of_type : + type a. a Script_typed_ir.ty -> type_name list -> type_name list = + fun t acc -> + match t with + | Script_typed_ir.Unit_t _ -> `TUnit :: acc + | Script_typed_ir.Int_t _ -> `TInt :: acc + | Script_typed_ir.Nat_t _ -> `TNat :: acc + | Script_typed_ir.Signature_t _ -> `TSignature :: acc + | Script_typed_ir.String_t _ -> `TString :: acc + | Script_typed_ir.Bytes_t _ -> `TBytes :: acc + | Script_typed_ir.Mutez_t _ -> `TMutez :: acc + | Script_typed_ir.Key_hash_t _ -> `TKey_hash :: acc + | Script_typed_ir.Key_t _ -> `TKey :: acc + | Script_typed_ir.Timestamp_t _ -> `TTimestamp :: acc + | Script_typed_ir.Address_t _ -> `TAddress :: acc + | Script_typed_ir.Bool_t _ -> `TBool :: acc + | Script_typed_ir.Pair_t ((lty, _, _), (rty, _, _), _) -> + tnames_of_type lty (tnames_of_type rty (`TPair :: acc)) + | Script_typed_ir.Union_t ((lty, _), (rty, _), _) -> + tnames_of_type lty (tnames_of_type rty (`TUnion :: acc)) + | Script_typed_ir.Lambda_t (dom, range, _) -> + tnames_of_type dom (tnames_of_type range (`TLambda :: acc)) + | Script_typed_ir.Option_t (ty, _) -> tnames_of_type ty (`TOption :: acc) + | Script_typed_ir.List_t (ty, _) -> tnames_of_type ty (`TList :: acc) + | Script_typed_ir.Set_t (ty, _) -> tnames_of_comparable_type ty (`TSet :: acc) + | Script_typed_ir.Map_t (kty, vty, _) -> + tnames_of_comparable_type kty (tnames_of_type vty (`TMap :: acc)) + | Script_typed_ir.Big_map_t (kty, vty, _) -> + tnames_of_comparable_type kty (tnames_of_type vty (`TBig_map :: acc)) + | Script_typed_ir.Contract_t (ty, _) -> tnames_of_type ty (`TContract :: acc) + | Script_typed_ir.Sapling_transaction_t (_, _) -> `TSapling_transaction :: acc + | Script_typed_ir.Sapling_state_t (_, _) -> `TSapling_state :: acc + | Script_typed_ir.Operation_t _ -> `TOperation :: acc + | Script_typed_ir.Chain_id_t _ -> `TChain_id :: acc + | Script_typed_ir.Never_t _ -> assert false + | Script_typed_ir.Bls12_381_g1_t _ -> `TBls12_381_g1 :: acc + | Script_typed_ir.Bls12_381_g2_t _ -> `TBls12_381_g2 :: acc + | Script_typed_ir.Bls12_381_fr_t _ -> `TBls12_381_fr :: acc + | Script_typed_ir.Ticket_t (ty, _) -> + tnames_of_comparable_type ty (`TTicket :: acc) + | Script_typed_ir.Chest_key_t _ -> assert false + | Script_typed_ir.Chest_t _ -> assert false + +and tnames_of_comparable_type : + type a. a Script_typed_ir.comparable_ty -> type_name list -> type_name list + = + fun t acc -> + match t with + | Script_typed_ir.Unit_key _ -> `TUnit :: acc + | Script_typed_ir.Never_key _ -> assert false + | Script_typed_ir.Int_key _ -> `TInt :: acc + | Script_typed_ir.Nat_key _ -> `TNat :: acc + | Script_typed_ir.Signature_key _ -> `TSignature :: acc + | Script_typed_ir.String_key _ -> `TString :: acc + | Script_typed_ir.Bytes_key _ -> `TBytes :: acc + | Script_typed_ir.Mutez_key _ -> `TMutez :: acc + | Script_typed_ir.Bool_key _ -> `TBool :: acc + | Script_typed_ir.Key_hash_key _ -> `TKey_hash :: acc + | Script_typed_ir.Key_key _ -> `TKey :: acc + | Script_typed_ir.Timestamp_key _ -> `TTimestamp :: acc + | Script_typed_ir.Chain_id_key _ -> `TChain_id :: acc + | Script_typed_ir.Address_key _ -> `TAddress :: acc + | Script_typed_ir.Pair_key ((lty, _), (rty, _), _) -> + tnames_of_comparable_type + lty + (tnames_of_comparable_type rty (`TPair :: acc)) + | Script_typed_ir.Union_key ((lty, _), (rty, _), _) -> + tnames_of_comparable_type + lty + (tnames_of_comparable_type rty (`TUnion :: acc)) + | Script_typed_ir.Option_key (ty, _) -> + tnames_of_comparable_type ty (`TOption :: acc) + +module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct + let algo = `Default + + let size = 16 +end) + +module Sampler = + Michelson_samplers.Make + (struct + let parameters = + { + base_parameters = + { + Michelson_samplers_base.int_size = {min = 8; max = 32}; + string_size = {min = 8; max = 128}; + bytes_size = {min = 8; max = 128}; + }; + list_size = {min = 10; max = 1000}; + set_size = {min = 10; max = 1000}; + map_size = {min = 10; max = 1000}; + } + end) + (Crypto_samplers) + +open Stats + +let tnames_dist : type_name list -> type_name Fin.Float.prb = + fun tnames -> + Emp.of_raw_data (Array.of_list tnames) + |> Fin.Float.counts_of_empirical (module Type_name_multiset) + |> Fin.Float.normalize + +let rec sample nsamples acc = + let open Sampling_helpers.M in + if nsamples = 0 then return acc + else + let* size = + Base_samplers.(sample_in_interval ~range:{min = 1; max = 1000}) + in + let* (Ex_ty ty) = Sampler.Random_type.m_type ~size in + let* acc = sample (nsamples - 1) acc in + return (tnames_of_type ty acc) + +let sample nsamples = sample nsamples [] + +let dist nsamples = + let open Sampling_helpers.M in + let* samples = sample nsamples in + return (tnames_dist samples) + +let () = + Format.printf + "stats:@.%a@." + Fin.Float.pp_fin_mes + (Fin.as_measure (dist 500 (Random.State.make [|0x1337; 0x533D|]))) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/test/test_helpers.ml b/src/proto_012_PsiThaCa/lib_benchmark/test/test_helpers.ml new file mode 100644 index 000000000000..a27aed6768b6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/test/test_helpers.ml @@ -0,0 +1,83 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Tezos_error_monad.Error_monad + +let rng_state = Random.State.make [|42; 987897; 54120|] + +let print_script_expr fmtr (expr : Protocol.Script_repr.expr) = + Micheline_printer.print_expr + fmtr + (Micheline_printer.printable + Protocol.Michelson_v1_primitives.string_of_prim + expr) + +let print_script_expr_list fmtr (exprs : Protocol.Script_repr.expr list) = + Format.pp_print_list + ~pp_sep:(fun fmtr () -> Format.fprintf fmtr " :: ") + print_script_expr + fmtr + exprs + +let typecheck_by_tezos = + let context_init_memory ~rng_state = + Context.init + ~rng_state + ~initial_balances: + [ + 4_000_000_000_000L; + 4_000_000_000_000L; + 4_000_000_000_000L; + 4_000_000_000_000L; + 4_000_000_000_000L; + ] + 5 + >>=? fun (block, _accounts) -> + Incremental.begin_construction + ~timestamp:(Tezos_base.Time.Protocol.add block.header.shell.timestamp 30L) + block + >>=? fun vs -> + let ctxt = Incremental.alpha_ctxt vs in + (* Required for eg Create_contract *) + return + @@ Protocol.Alpha_context.Contract.init_origination_nonce + ctxt + Tezos_crypto.Operation_hash.zero + in + fun bef node -> + Stdlib.Result.get_ok + (Lwt_main.run + ( context_init_memory ~rng_state >>=? fun ctxt -> + let (Protocol.Script_ir_translator.Ex_stack_ty bef) = + Type_helpers.michelson_type_list_to_ex_stack_ty bef ctxt + in + Protocol.Script_ir_translator.parse_instr + Protocol.Script_ir_translator.Lambda + ctxt + ~legacy:false + (Micheline.root node) + bef + >|= Protocol.Environment.wrap_tzresult + >>=? fun _ -> return_unit )) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/test/test_sampling_code.ml b/src/proto_012_PsiThaCa/lib_benchmark/test/test_sampling_code.ml new file mode 100644 index 000000000000..c637d3944e1f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/test/test_sampling_code.ml @@ -0,0 +1,98 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Tezos_benchmark + +(* Input parameter parsing *) + +let verbose = + if Array.length Sys.argv < 2 then ( + Format.eprintf "Executable expects random seed on input\n%!" ; + exit 1) + else + (Random.init (int_of_string Sys.argv.(1)) ; + List.exists (( = ) "-v")) + (Array.to_list Sys.argv) + +(* ------------------------------------------------------------------------- *) +(* Base sampler parameters *) + +let state = Random.State.make [|42; 987897; 54120|] + +module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct + let algo = `Default + + let size = 16 +end) + +module Michelson_base_samplers = Michelson_samplers_base.Make (struct + let parameters = + let size = {Base_samplers.min = 4; max = 32} in + { + Michelson_samplers_base.int_size = size; + string_size = size; + bytes_size = size; + } +end) + +(* ------------------------------------------------------------------------- *) +(* MCMC instantiation *) + +module Code = + Michelson_mcmc_samplers.Make_code_sampler + (Michelson_base_samplers) + (Crypto_samplers) + (struct + let rng_state = state + + let target_size = 500 + + let verbosity = if verbose then `Trace else `Silent + end) + +let start = Unix.gettimeofday () + +let generator = Code.generator ~burn_in:(500 * 7) state + +let stop = Unix.gettimeofday () + +let () = Format.printf "Burn in time: %f seconds@." (stop -. start) + +let _ = + for i = 1 to 1000 do + let Michelson_mcmc_samplers.{term = michelson; bef; aft} = + generator state + in + Test_helpers.typecheck_by_tezos bef michelson ; + if verbose then ( + Format.eprintf "result %d/1000:@." i ; + Format.eprintf + "type: %a => %a@." + Test_helpers.print_script_expr_list + bef + Test_helpers.print_script_expr_list + aft ; + Format.eprintf "%a@." Test_helpers.print_script_expr michelson) + done diff --git a/src/proto_012_PsiThaCa/lib_benchmark/test/test_sampling_data.ml b/src/proto_012_PsiThaCa/lib_benchmark/test/test_sampling_data.ml new file mode 100644 index 000000000000..a93671d4e102 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/test/test_sampling_data.ml @@ -0,0 +1,87 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Tezos_benchmark + +(* Input parameter parsing *) + +let verbose = + if Array.length Sys.argv < 2 then ( + Format.eprintf "Executable expects random seed on input\n%!" ; + exit 1) + else + (Random.init (int_of_string Sys.argv.(1)) ; + List.exists (( = ) "-v")) + (Array.to_list Sys.argv) + +(* ------------------------------------------------------------------------- *) +(* MCMC instantiation *) + +let state = Random.State.make [|42; 987897; 54120|] + +module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct + let algo = `Default + + let size = 16 +end) + +module Michelson_base_samplers = Michelson_samplers_base.Make (struct + let parameters = + let size = {Base_samplers.min = 4; max = 32} in + { + Michelson_samplers_base.int_size = size; + string_size = size; + bytes_size = size; + } +end) + +module Data = + Michelson_mcmc_samplers.Make_data_sampler + (Michelson_base_samplers) + (Crypto_samplers) + (struct + let rng_state = state + + let target_size = 500 + + let verbosity = if verbose then `Trace else `Silent + end) + +let start = Unix.gettimeofday () + +let generator = Data.generator ~burn_in:(200 * 7) state + +let stop = Unix.gettimeofday () + +let () = Format.printf "Burn in time: %f seconds@." (stop -. start) + +let _ = + for _i = 0 to 1000 do + let Michelson_mcmc_samplers.{term = michelson; typ} = generator state in + if verbose then ( + Format.eprintf "result:@." ; + Format.eprintf "type: %a@." Test_helpers.print_script_expr typ ; + Format.eprintf "%a@." Test_helpers.print_script_expr michelson) + done diff --git a/src/proto_012_PsiThaCa/lib_benchmark/tezos-benchmark-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_benchmark/tezos-benchmark-012-PsiThaCa.opam new file mode 100644 index 000000000000..3ff53fdcbb03 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/tezos-benchmark-012-PsiThaCa.opam @@ -0,0 +1,32 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "tezos-tooling" { with-test } + "dune" { >= "2.9" } + "tezos-base" + "tezos-benchmark" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-012-PsiThaCa-test-helpers" + "tezos-protocol-012-PsiThaCa-parameters" + "tezos-micheline-rewriting" + "tezos-benchmark-type-inference-012-PsiThaCa" + "hashcons" + "benchmark-utils" + "tezos-012-PsiThaCa-test-helpers" + "prbnmcn-stats" { = "0.0.2" } + "tezos-micheline" { with-test } + "tezos-error-monad" { with-test } + "alcotest-lwt" { with-test } + +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: library for writing benchmarks (protocol-specific part)" diff --git a/src/proto_012_PsiThaCa/lib_benchmark/type_helpers.ml b/src/proto_012_PsiThaCa/lib_benchmark/type_helpers.ml new file mode 100644 index 000000000000..eea9a26d70ef --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/type_helpers.ml @@ -0,0 +1,88 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Type conversion helpers *) + +open Protocol + +exception Type_helpers_error of string + +let helpers_error msg = raise (Type_helpers_error msg) + +(* Convert a Micheline-encoded type to its internal GADT format. *) +let michelson_type_to_ex_ty (typ : Alpha_context.Script.expr) + (ctxt : Alpha_context.t) = + Script_ir_translator.parse_ty + ctxt + ~legacy:false + ~allow_lazy_storage:false + ~allow_operation:false + ~allow_contract:false + ~allow_ticket:false + (Micheline.root typ) + |> Environment.wrap_tzresult + |> function + | Ok (ex_ty, _ctxt) -> ex_ty + | Error errs -> + let msg = + Format.asprintf + "Michelson_generation.michelson_type_to_ex_ty (%a)" + Error_monad.pp_print_trace + errs + in + helpers_error msg + +(* Convert a list of Micheline-encoded Michelson types to the + internal GADT format. *) +let rec michelson_type_list_to_ex_stack_ty + (stack_ty : Alpha_context.Script.expr list) ctxt = + let open Script_ir_translator in + let open Script_typed_ir in + match stack_ty with + | [] -> Ex_stack_ty Bot_t + | hd :: tl -> ( + let ex_ty = michelson_type_to_ex_ty hd ctxt in + match ex_ty with + | Ex_ty ty -> ( + let ex_stack_ty = michelson_type_list_to_ex_stack_ty tl ctxt in + match ex_stack_ty with + | Ex_stack_ty tl -> Ex_stack_ty (Item_t (ty, tl, None)))) + +let base_type_to_michelson_type (typ : Type.Base.t) = + let typ = Mikhailsky.map_var (fun _ -> Mikhailsky.unit_ty) typ in + Mikhailsky.to_michelson typ + +(* Convert a Mikhailsky stack to a list of Micheline-encoded types *) +let rec stack_type_to_michelson_type_list (typ : Type.Stack.t) = + let node = typ.node in + match node with + | Type.Stack.Stack_var_t _ -> + helpers_error "stack_type_to_michelson_type_list: bug found" + | Type.Stack.Empty_t -> [] + | Type.Stack.Item_t (ty, tl) -> + base_type_to_michelson_type ty :: stack_type_to_michelson_type_list tl + +let base_type_to_ex_ty ty = + michelson_type_to_ex_ty (base_type_to_michelson_type ty) diff --git a/src/proto_012_PsiThaCa/lib_benchmark/type_helpers.mli b/src/proto_012_PsiThaCa/lib_benchmark/type_helpers.mli new file mode 100644 index 000000000000..1a041e001459 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmark/type_helpers.mli @@ -0,0 +1,58 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Type conversion helpers *) + +open Protocol + +(** Exception raised in case an error occurs in this module. *) +exception Type_helpers_error of string + +(** [michelson_type_list_to_ex_stack_ty] converts a list of types in + Micheline form to a stack type in IR form. + + @raise Type_helpers_error if parsing the Michelson type fails. + *) +val michelson_type_list_to_ex_stack_ty : + Alpha_context.Script.expr list -> + Alpha_context.t -> + Script_ir_translator.ex_stack_ty + +(** [michelson_type_to_ex_ty ty ctxt] parses the type [ty]. + + @raise Type_helpers_error if an error arises during parsing. *) +val michelson_type_to_ex_ty : + Alpha_context.Script.expr -> Alpha_context.t -> Script_ir_translator.ex_ty + +(** [stack_type_to_michelson_type_list] converts a Mikhailsky stack type + to a stack represented as a list of Micheline expressions, each + element denoting a type on the stack type. + + @raise Type_helpers_error if the stack type contains variables. *) +val stack_type_to_michelson_type_list : Type.Stack.t -> Script_repr.expr list + +(** [base_type_to_ex_ty] converts a Mikhailsky type to a Michelson one. *) +val base_type_to_ex_ty : + Type.Base.t -> Alpha_context.t -> Script_ir_translator.ex_ty diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/.ocamlformat b/src/proto_012_PsiThaCa/lib_benchmarks_proto/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/cache_benchmarks.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/cache_benchmarks.ml new file mode 100644 index 000000000000..3d96c3976834 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/cache_benchmarks.ml @@ -0,0 +1,195 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** {2 [Alpha_context.Cache]-related benchmarks} *) + +let assert_ok_lwt x = + match Lwt_main.run x with Ok x -> x | Error _ -> assert false + +let assert_ok = function Ok x -> x | Error _ -> assert false + +module Admin = Alpha_context.Cache.Admin + +(** We can't construct a dummy cache client from outside the protocol. + We'll have to benchmark the {!Environment_cache} through the interface + exposed by {!Script_cache}. *) +module Cache = Script_cache + +(** { 2 Constructing a dummy cached value. } *) + +let make_context ~rng_state = + Execution_context.make ~rng_state |> assert_ok_lwt |> fst + +let throwaway_context = + let rng_state = Random.State.make [|0x1337; 0x533D|] in + make_context ~rng_state + +let dummy_script : Cache.cached_contract = + let str = "{ parameter unit; storage unit; code FAILWITH }" in + let storage = + let (parsed, _) = Michelson_v1_parser.parse_expression "Unit" in + Alpha_context.Script.lazy_expr parsed.expanded + in + let code = + let (parsed, _) = Michelson_v1_parser.parse_expression ~check:false str in + Alpha_context.Script.lazy_expr parsed.expanded + in + let script = Alpha_context.Script.{code; storage} in + let (ex_script, _) = + Script_ir_translator.parse_script + throwaway_context + ~legacy:true + ~allow_forged_in_storage:false + script + |> assert_ok_lwt + in + (script, ex_script) + +(** {2 Creating dummy cache value identifiers.} *) + +(** Configuration shared among all cache benchmarks. *) +module Cache_shared_config = struct + type config = unit + + let config_encoding = Data_encoding.unit + + let default_config = () + + type workload = {cache_cardinal : int} + + let workload_encoding = + let open Data_encoding in + conv + (fun {cache_cardinal} -> cache_cardinal) + (fun cache_cardinal -> {cache_cardinal}) + (obj1 (req "cache_cardinal" int31)) + + let tags = [Tags.cache] + + let workload_to_vector {cache_cardinal} = + Sparse_vec.String.of_list [("cache_cardinal", float_of_int cache_cardinal)] +end + +(* We can't produce a Script_cache.identifier without calling [Script_cache.find]. *) +let identifier_of_contract (c : Alpha_context.Contract.t) : Cache.identifier = + let (_, id, _) = Cache.find throwaway_context c |> assert_ok_lwt in + id + +let contract_of_int i : Alpha_context.Contract.t = + Alpha_context.Contract.of_b58check + Contract_hash.(to_b58check (hash_string [string_of_int i])) + |> assert_ok + +let identifier_of_int i = identifier_of_contract @@ contract_of_int i + +(** Prepare a context with a cache of the prescribed cardinality. A key in the domain of + the cache is returned along the context: this key is used to benchmark + (successful) cache accesses. *) +let prepare_context rng_state cache_cardinal = + assert (cache_cardinal > 0) ; + let ctxt = make_context ~rng_state in + let some_key_in_domain = identifier_of_int 0 in + let rec loop i ctxt = + if Compare.Int.(i = cache_cardinal) then ctxt + else + let key = identifier_of_int i in + loop (i + 1) (Cache.update ctxt key dummy_script 1 |> assert_ok) + in + (loop 0 ctxt, some_key_in_domain) + +(** Benchmark {!Script_cache.update}. This almost directly calls {!Environment_cache.update}. + We also use the result of this benchmark to assign a cost to {!Environment_cache.find}, + which alas can't be directly benchmarked from the interface provided by {!Script_cache}. *) +module Cache_update_benchmark : Benchmark.S = struct + include Cache_shared_config + + let name = "CACHE_UPDATE" + + let info = "Benchmarking the time it takes to update a key in the cache" + + (** It is expected that cache keys are non-adversarial, + ie do not share a long common prefix. This is the case for [Script_cache], + for which the keys are B58-encoded contract hashes. + + To rephrase: with high probability, comparing two keys in the domain of the cache is + a constant-time operation (two keys will differ after the first few characters). + We therefore do not take into account the length of the key in the model. *) + let model = + let affine_logn ~intercept ~coeff = + let open Model in + let module M = struct + type arg_type = int * unit + + module Def (X : Costlang.S) = struct + open X + + type model_type = size -> size + + let arity = arity_1 + + let model = + lam ~name:"size" @@ fun size -> + free ~name:intercept + (free ~name:coeff * log2 (int 1 + size)) + end + end in + (module M : Model_impl with type arg_type = int * unit) + in + (* Looking at the plots, it looks like this benchmark underestimates the constant term. + In the interpreter, this would warrant a dedicated benchmark for the intercept. *) + let intercept_variable = + Free_variable.of_string (Format.asprintf "%s_const" name) + in + let coeff_variable = + Free_variable.of_string (Format.asprintf "%s_coeff" name) + in + Model.make + ~conv:(function {cache_cardinal} -> (cache_cardinal, ())) + ~model:(affine_logn ~intercept:intercept_variable ~coeff:coeff_variable) + + let models = [("cache_model", model)] + + let cache_update_benchmark ctxt some_key_in_domain cache_cardinal = + let workload = {cache_cardinal} in + let closure () = + ignore (Cache.update ctxt some_key_in_domain dummy_script 1) + in + Generator.Plain {workload; closure} + + (** At the time of writing (Protocol H) the worst case execution path for + [Cache.update] is to update a key which is already present. *) + let make_bench rng_state _cfg () = + let cache_cardinal = + Base_samplers.sample_in_interval ~range:{min = 1; max = 100_000} rng_state + in + let (ctxt, some_key_in_domain) = prepare_context rng_state cache_cardinal in + cache_update_benchmark ctxt some_key_in_domain cache_cardinal + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Cache_update_benchmark) diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/dune b/src/proto_012_PsiThaCa/lib_benchmarks_proto/dune new file mode 100644 index 000000000000..c69fc009bd36 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/dune @@ -0,0 +1,31 @@ +(library + (name tezos_benchmarks_proto_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-benchmarks-proto-012-PsiThaCa) + (libraries + tezos-base + tezos-protocol-012-PsiThaCa + tezos-protocol-012-PsiThaCa-parameters + tezos-benchmark + tezos-benchmark-012-PsiThaCa + tezos-shell-benchmarks + tezos-micheline + tezos-012-PsiThaCa-test-helpers + tezos-sapling + tezos-client-012-PsiThaCa +) + (library_flags (:standard -linkall)) + (flags (:standard -open Tezos_stdlib + -open Tezos_base + -open Tezos_base__TzPervasives + -open Tezos_error_monad + -open Tezos_benchmark + -open Tezos_benchmark_012_PsiThaCa + -open Tezos_benchmark_type_inference_012_PsiThaCa + -open Tezos_protocol_012_PsiThaCa + -open Tezos_raw_protocol_012_PsiThaCa + -open Tezos_client_012_PsiThaCa + -open Tezos_crypto + -open Tezos_micheline + -open Tezos_012_PsiThaCa_test_helpers + -open Tezos_client_012_PsiThaCa))) diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/dune-project b/src/proto_012_PsiThaCa/lib_benchmarks_proto/dune-project new file mode 100644 index 000000000000..b0ebb71b4a03 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(name tezos-benchmarks-proto-alpha) +(formatting (enabled_for ocaml)) diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/encodings_benchmarks.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/encodings_benchmarks.ml new file mode 100644 index 000000000000..0dc9f3212bc4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/encodings_benchmarks.ml @@ -0,0 +1,432 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +module Micheline_common = struct + let make_printable node = + Micheline_printer.printable + Michelson_v1_primitives.string_of_prim + (Micheline.strip_locations node) + + type phase = Trace_production | In_protocol | Global + + type error = + | Bad_micheline of { + benchmark_name : string; + micheline : Alpha_context.Script.node; + phase : phase; + } + + exception Micheline_benchmark of error + + let pp_phase fmtr (phase : phase) = + match phase with + | Trace_production -> Format.fprintf fmtr "trace production" + | In_protocol -> Format.fprintf fmtr "in protocol" + | Global -> Format.fprintf fmtr "global" + + let pp_error fmtr = function + | Bad_micheline {benchmark_name; micheline; phase} -> + Format.open_vbox 1 ; + Format.fprintf fmtr "Bad micheline:@," ; + Format.fprintf fmtr "benchmark = %s@," benchmark_name ; + Format.fprintf + fmtr + "expression = @[%a@]@," + Micheline_printer.print_expr + (make_printable micheline) ; + Format.fprintf fmtr "phase = %a@," pp_phase phase ; + Format.close_box () + + let bad_micheline benchmark_name micheline phase = + raise + (Micheline_benchmark (Bad_micheline {benchmark_name; micheline; phase})) + + type workload = {size : Size.micheline_size; bytes : int} + + let workload_encoding = + let open Data_encoding in + def "encoding_micheline_trace" + @@ conv + (fun {size; bytes} -> (size, bytes)) + (fun (size, bytes) -> {size; bytes}) + (obj2 + (req "micheline_size" Size.micheline_size_encoding) + (req "micheline_bytes" Size.encoding)) + + let workload_to_vector (workload : workload) = + let keys = + [ + ("encoding_micheline_traversal", Size.to_float workload.size.traversal); + ("encoding_micheline_int_bytes", Size.to_float workload.size.int_bytes); + ( "encoding_micheline_string_bytes", + Size.to_float workload.size.string_bytes ); + ("encoding_micheline_bytes", Size.to_float workload.bytes); + ] + in + Sparse_vec.String.of_list keys + + let tags = [Tags.encoding] + + let model_size name = + Model.make + ~conv:(fun {size = {Size.traversal; int_bytes; string_bytes}; _} -> + (traversal, (int_bytes, (string_bytes, ())))) + ~model: + (Model.trilinear + ~coeff1: + (Free_variable.of_string + (Format.asprintf "%s_micheline_traversal" name)) + ~coeff2: + (Free_variable.of_string + (Format.asprintf "%s_micheline_int_bytes" name)) + ~coeff3: + (Free_variable.of_string + (Format.asprintf "%s_micheline_string_bytes" name))) + + let model_bytes name = + Model.make + ~conv:(fun {bytes; _} -> (bytes, ())) + ~model: + (Model.linear + ~coeff: + (Free_variable.of_string + (Format.asprintf "%s_micheline_bytes" name))) + + let models name = + [("micheline", model_size name); ("micheline_bytes", model_bytes name)] +end + +module Encoding_micheline : Benchmark.S = struct + include Translator_benchmarks.Config + include Micheline_common + + let name = "ENCODING_MICHELINE" + + let info = "Benchmarking strip_location + encoding of Micheline to bytes" + + let micheline_serialization_trace (micheline_node : Alpha_context.Script.node) + = + match + Data_encoding.Binary.to_string + Protocol.Script_repr.expr_encoding + (Micheline.strip_locations micheline_node) + with + | Error err -> + Format.eprintf + "micheline_serialization_trace: %a@." + Data_encoding.Binary.pp_write_error + err ; + None + | Ok str -> + let micheline_size = Size.of_micheline micheline_node in + Some {size = micheline_size; bytes = Size.string str} + + let encoding_micheline_benchmark (node : Protocol.Script_repr.expr) = + let node = Micheline.root node in + let workload = + match micheline_serialization_trace node with + | None -> Micheline_common.bad_micheline name node Trace_production + | Some trace -> trace + in + let closure () = + try + ignore + (Data_encoding.Binary.to_string_exn + Protocol.Script_repr.expr_encoding + (Micheline.strip_locations node)) + with _ -> Micheline_common.bad_micheline name node In_protocol + in + Generator.Plain {workload; closure} + + let make_bench rng_state cfg () = + let Michelson_mcmc_samplers.{term; typ = _} = + Michelson_generation.make_data_sampler rng_state cfg.generator_config + in + encoding_micheline_benchmark term + + let create_benchmarks ~rng_state ~bench_num config = + match config.michelson_terms_file with + | Some file -> + Format.eprintf "Loading terms from %s@." file ; + let terms = Michelson_mcmc_samplers.load ~filename:file in + List.map + (function + | Michelson_mcmc_samplers.Data {term; typ = _} + | Michelson_mcmc_samplers.Code {term; bef = _; aft = _} -> + fun () -> encoding_micheline_benchmark term) + terms + | None -> List.repeat bench_num (make_bench rng_state config) + + let models = models name +end + +let () = Registration_helpers.register (module Encoding_micheline) + +module Decoding_micheline : Benchmark.S = struct + include Translator_benchmarks.Config + include Micheline_common + + let name = "DECODING_MICHELINE" + + let info = "Decoding of bytes to Micheline" + + let micheline_deserialization_trace (micheline_str : string) = + match + Data_encoding.Binary.of_string + Protocol.Script_repr.expr_encoding + micheline_str + with + | Error err -> + Format.eprintf + "micheline_deserialization_trace: %a@." + Data_encoding.Binary.pp_read_error + err ; + None + | Ok micheline_node -> + let micheline_size = + Size.of_micheline (Micheline.root micheline_node) + in + Some {size = micheline_size; bytes = Size.string micheline_str} + + let decoding_micheline_benchmark (node : Protocol.Script_repr.expr) = + let encoded = + Data_encoding.Binary.to_string_exn Protocol.Script_repr.expr_encoding node + in + let node = Micheline.root node in + let workload = + match micheline_deserialization_trace encoded with + | None -> bad_micheline name node Trace_production + | Some trace -> trace + in + let closure () = + try + ignore + (Data_encoding.Binary.of_string_exn + Protocol.Script_repr.expr_encoding + encoded) + with _ -> bad_micheline name node In_protocol + in + Generator.Plain {workload; closure} + + let make_bench rng_state cfg () = + let Michelson_mcmc_samplers.{term; typ = _} = + Michelson_generation.make_data_sampler rng_state cfg.generator_config + in + decoding_micheline_benchmark term + + let create_benchmarks ~rng_state ~bench_num config = + match config.michelson_terms_file with + | Some file -> + Format.eprintf "Loading terms from %s@." file ; + let terms = Michelson_mcmc_samplers.load ~filename:file in + List.map + (function + | Michelson_mcmc_samplers.Data {term; typ = _} + | Michelson_mcmc_samplers.Code {term; bef = _; aft = _} -> + fun () -> decoding_micheline_benchmark term) + terms + | None -> List.repeat bench_num (make_bench rng_state config) + + let models = models name +end + +let () = Registration_helpers.register (module Decoding_micheline) + +(* TODO: benchmark timestamps with big values (>64 bits) *) +module Timestamp = struct + let () = + Registration_helpers.register + @@ + let open Tezos_shell_benchmarks.Encoding_benchmarks_helpers in + fixed_size_shared + ~name:"TIMESTAMP_READABLE_ENCODING" + ~generator:(fun rng_state -> + let seconds_in_year = 30_000_000 in + let offset = Random.State.int rng_state seconds_in_year in + Alpha_context.Script_timestamp.of_zint (Z.of_int (1597764116 + offset))) + ~make_bench:(fun generator () -> + let tstamp_string = generator () in + let closure () = + ignore (Alpha_context.Script_timestamp.to_string tstamp_string) + in + Generator.Plain {workload = (); closure}) + + let () = + Registration_helpers.register + @@ + let open Tezos_shell_benchmarks.Encoding_benchmarks_helpers in + fixed_size_shared + ~name:"TIMESTAMP_READABLE_DECODING" + ~generator:(fun rng_state -> + let seconds_in_year = 30_000_000 in + let offset = Random.State.int rng_state seconds_in_year in + let tstamp = + Alpha_context.Script_timestamp.of_zint + (Z.of_int (1597764116 + offset)) + in + Alpha_context.Script_timestamp.to_string tstamp) + ~make_bench:(fun generator () -> + let tstamp_string = generator () in + let closure () = + ignore (Alpha_context.Script_timestamp.of_string tstamp_string) + in + Generator.Plain {workload = (); closure}) +end + +(* when benchmarking, compile bls12-381-unix without ADX, see + https://gitlab.com/dannywillems/ocaml-bls12-381/-/blob/71d0b4d467fbfaa6452d702fcc408d7a70916a80/README.md#install +*) +module BLS = struct + open Tezos_shell_benchmarks.Encoding_benchmarks_helpers + + let () = + Registration_helpers.register + @@ make_encode_fixed_size_to_bytes + ~name:"ENCODING_BLS_FR" + ~to_bytes:Bls12_381.Fr.to_bytes + ~generator:(fun rng_state -> Bls12_381.Fr.random ~state:rng_state ()) + + let () = + Registration_helpers.register + @@ make_encode_fixed_size_to_bytes + ~name:"ENCODING_BLS_G1" + ~to_bytes:Bls12_381.G1.to_bytes + ~generator:(fun rng_state -> Bls12_381.G1.random ~state:rng_state ()) + + let () = + Registration_helpers.register + @@ make_encode_fixed_size_to_bytes + ~name:"ENCODING_BLS_G2" + ~to_bytes:Bls12_381.G2.to_bytes + ~generator:(fun rng_state -> Bls12_381.G2.random ~state:rng_state ()) + + let () = + Registration_helpers.register + @@ make_decode_fixed_size_from_bytes + ~name:"DECODING_BLS_FR" + ~to_bytes:Bls12_381.Fr.to_bytes + ~from_bytes:Bls12_381.Fr.of_bytes_exn + ~generator:(fun rng_state -> Bls12_381.Fr.random ~state:rng_state ()) + + let () = + Registration_helpers.register + @@ make_decode_fixed_size_from_bytes + ~name:"DECODING_BLS_G1" + ~to_bytes:Bls12_381.G1.to_bytes + ~from_bytes:Bls12_381.G1.of_bytes_exn + ~generator:(fun rng_state -> Bls12_381.G1.random ~state:rng_state ()) + + let () = + Registration_helpers.register + @@ make_decode_fixed_size_from_bytes + ~name:"DECODING_BLS_G2" + ~to_bytes:Bls12_381.G2.to_bytes + ~from_bytes:Bls12_381.G2.of_bytes_exn + ~generator:(fun rng_state -> Bls12_381.G2.random ~state:rng_state ()) + + let () = + Registration_helpers.register + @@ fixed_size_shared + ~name:"BLS_FR_FROM_Z" + ~generator:(fun rng_state -> Bls12_381.Fr.random ~state:rng_state ()) + ~make_bench:(fun generator () -> + let generated = generator () in + let z = Bls12_381.Fr.to_z generated in + let closure () = ignore (Bls12_381.Fr.of_z z) in + Generator.Plain {workload = (); closure}) + + let () = + Registration_helpers.register + @@ fixed_size_shared + ~name:"BLS_FR_TO_Z" + ~generator:(fun rng_state -> Bls12_381.Fr.random ~state:rng_state ()) + ~make_bench:(fun generator () -> + let generated = generator () in + let closure () = ignore (Bls12_381.Fr.to_z generated) in + Generator.Plain {workload = (); closure}) +end + +module Timelock = struct + open Tezos_shell_benchmarks.Encoding_benchmarks_helpers + + let generator rng_state = + let log_time = + Base_samplers.sample_in_interval ~range:{min = 0; max = 29} rng_state + in + let time = Random.State.int rng_state (Int.shift_left 1 log_time) in + let plaintext_size = + Base_samplers.sample_in_interval ~range:{min = 1; max = 10000} rng_state + in + let (chest, chest_key) = + Timelock.chest_sampler ~plaintext_size ~time ~rng_state + in + ((chest, chest_key), plaintext_size) + + let () = + Registration_helpers.register + @@ make_encode_variable_size_to_string + ~name:"ENCODING_Chest" + ~to_string:(Data_encoding.Binary.to_string_exn Timelock.chest_encoding) + ~generator:(fun rng_state -> + let ((chest, _), plaintext_size) = generator rng_state in + (chest, {bytes = plaintext_size})) + + let () = + Registration_helpers.register + @@ make_encode_fixed_size_to_string + ~name:"ENCODING_Chest_key" + ~to_string: + (Data_encoding.Binary.to_string_exn Timelock.chest_key_encoding) + ~generator:(fun rng_state -> + let ((_, chest_key), _w) = generator rng_state in + chest_key) + + let () = + Registration_helpers.register + @@ make_decode_variable_size_from_bytes + ~name:"DECODING_Chest" + ~to_bytes:(Data_encoding.Binary.to_bytes_exn Timelock.chest_encoding) + ~from_bytes:(Data_encoding.Binary.of_bytes_exn Timelock.chest_encoding) + ~generator:(fun rng_state -> + let ((chest, _), _) = generator rng_state in + let b = + Data_encoding.Binary.to_bytes_exn Timelock.chest_encoding chest + in + (chest, {bytes = Bytes.length b})) + + let () = + Registration_helpers.register + @@ make_decode_fixed_size_from_bytes + ~name:"DECODING_Chest_key" + ~to_bytes: + (Data_encoding.Binary.to_bytes_exn Timelock.chest_key_encoding) + ~from_bytes: + (Data_encoding.Binary.of_bytes_exn Timelock.chest_key_encoding) + ~generator:(fun rng_state -> + let ((_, chest_key), _w) = generator rng_state in + chest_key) +end diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/gas_helpers.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/gas_helpers.ml new file mode 100644 index 000000000000..bf8bcde60256 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/gas_helpers.ml @@ -0,0 +1,36 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +let set_limit ctxt = + Alpha_context.Gas.set_limit + ctxt + (Alpha_context.Gas.Arith.integral_of_int_exn 999_999_999_999) + +let fp_to_z (fp : Alpha_context.Gas.Arith.fp) = + let open Data_encoding in + Binary.to_bytes_exn Alpha_context.Gas.Arith.z_fp_encoding fp + |> Binary.of_bytes_exn z diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/global_constants_storage_benchmarks.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/global_constants_storage_benchmarks.ml new file mode 100644 index 000000000000..bb8fc4e2c898 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/global_constants_storage_benchmarks.ml @@ -0,0 +1,727 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* This module includes benchmarks for [Global_constants_storage.expand] + and [Global_constants_storage.Internal_for_tests.expr_to_address_in_context]. + The other main function exported by [Global_constants_storage] is [register]; + however, [register] calls [expand] and does little else, and thus does + not need to be further carbonated. + + In the process of creating these benchmarks, we benchmarked several OCaml + stdlib functions and [Script_expr_hash.of_b58check_opt]. While these cost + models are not used in the protocol, they are kept here to ensure the + assumptions underlying [register] and [expand] don't change out + from under us.*) + +open Tezos_benchmark +open Tezos_micheline +open Protocol + +let assert_ok_lwt x = + match Lwt_main.run x with + | Ok x -> x + | Error errs -> + Format.eprintf "%a" pp_print_trace errs ; + exit 1 + +let assert_ok = function + | Ok x -> x + | Error errs -> + Format.eprintf "%a" pp_print_trace errs ; + exit 1 + +(** [seq_of_n_constants n hash] generates a Seq filled + with [n] constant primitives containing [hash] *) +let seq_of_n_constants n hash = + let open Micheline in + Seq + ( -1, + Stdlib.List.init n (fun _ -> + Prim (-1, Michelson_v1_primitives.H_constant, [String (-1, hash)], [])) + ) + +(** Computes the b58check hash of a Micheline node as a string. *) +let node_to_hash node = + let expr_bytes = + Micheline.strip_locations node + |> Script_repr.lazy_expr |> Script_repr.force_bytes |> Stdlib.Result.get_ok + in + Script_expr_hash.hash_bytes [expr_bytes] |> Script_expr_hash.to_b58check + +(* An ad-hoc sampler for Micheline values. Boltzmann sampling would do well + here. + + Copied from lib_micheline and modified to use [Michelson_v1_primitives.prim]. *) +module Micheline_sampler = struct + type node = Alpha_context.Script.node + + let prims = + let open Protocol.Michelson_v1_primitives in + [| + K_parameter; + K_storage; + K_code; + D_False; + D_Elt; + D_Left; + D_None; + D_Pair; + D_Right; + D_Some; + D_True; + D_Unit; + I_PACK; + I_UNPACK; + I_BLAKE2B; + I_SHA256; + I_SHA512; + I_ABS; + I_ADD; + I_AMOUNT; + I_AND; + I_BALANCE; + I_CAR; + I_CDR; + I_CHAIN_ID; + I_CHECK_SIGNATURE; + I_COMPARE; + I_CONCAT; + I_CONS; + I_CREATE_ACCOUNT; + I_CREATE_CONTRACT; + I_IMPLICIT_ACCOUNT; + I_DIP; + I_DROP; + I_DUP; + I_EDIV; + I_EMPTY_BIG_MAP; + I_EMPTY_MAP; + I_EMPTY_SET; + I_EQ; + I_EXEC; + I_APPLY; + I_FAILWITH; + I_GE; + I_GET; + I_GET_AND_UPDATE; + I_GT; + I_HASH_KEY; + I_IF; + I_IF_CONS; + I_IF_LEFT; + I_IF_NONE; + I_INT; + I_LAMBDA; + I_LE; + I_LEFT; + I_LEVEL; + I_LOOP; + I_LSL; + I_LSR; + I_LT; + I_MAP; + I_MEM; + I_MUL; + I_NEG; + I_NEQ; + I_NIL; + I_NONE; + I_NOT; + I_NOW; + I_OR; + I_PAIR; + I_UNPAIR; + I_PUSH; + I_RIGHT; + I_SIZE; + I_SOME; + I_SOURCE; + I_SENDER; + I_SELF; + I_SELF_ADDRESS; + I_SLICE; + I_STEPS_TO_QUOTA; + I_SUB; + I_SWAP; + I_TRANSFER_TOKENS; + I_SET_DELEGATE; + I_UNIT; + I_UPDATE; + I_XOR; + I_ITER; + I_LOOP_LEFT; + I_ADDRESS; + I_CONTRACT; + I_ISNAT; + I_CAST; + I_RENAME; + I_SAPLING_EMPTY_STATE; + I_SAPLING_VERIFY_UPDATE; + I_DIG; + I_DUG; + I_NEVER; + I_VOTING_POWER; + I_TOTAL_VOTING_POWER; + I_KECCAK; + I_SHA3; + I_PAIRING_CHECK; + I_TICKET; + I_READ_TICKET; + I_SPLIT_TICKET; + I_JOIN_TICKETS; + T_bool; + T_contract; + T_int; + T_key; + T_key_hash; + T_lambda; + T_list; + T_map; + T_big_map; + T_nat; + T_option; + T_or; + T_pair; + T_set; + T_signature; + T_string; + T_bytes; + T_mutez; + T_timestamp; + T_unit; + T_operation; + T_address; + T_sapling_transaction; + T_sapling_state; + T_chain_id; + T_never; + T_bls12_381_g1; + T_bls12_381_g2; + T_bls12_381_fr; + T_ticket + (* We don't want constants in our generator, else the constants + functions might fail because it's ill-formed. *) + (* H_constant; *); + |] + + module Sampler = Micheline_sampler.Make (struct + type prim = Michelson_v1_primitives.prim + + let sample_prim : Michelson_v1_primitives.prim Base_samplers.sampler = + fun rng_state -> + let i = Random.State.int rng_state (Array.length prims) in + prims.(i) + + let sample_annots : string list Base_samplers.sampler = fun _rng_state -> [] + + let sample_string _ = "" + + let sample_bytes _ = Bytes.empty + + let sample_z _ = Z.zero + + let width_function = Micheline_sampler.reasonable_width_function + end) + + let sample = Sampler.sample + + type size = {nodes : int; bytes : int} + + let int z = {nodes = 1; bytes = (Z.numbits z + 7) / 8} + + let string s = {nodes = 1; bytes = String.length s} + + let bytes b = {nodes = 1; bytes = Bytes.length b} + + let node = {nodes = 1; bytes = 0} + + let ( @+ ) x y = {nodes = x.nodes + y.nodes; bytes = x.bytes + y.bytes} + + let micheline_size (n : node) = + let rec micheline_size n acc = + let open Micheline in + match n with + | Int (_, i) -> acc @+ int i + | String (_, s) -> acc @+ string s + | Bytes (_, b) -> acc @+ bytes b + | Seq (_, terms) -> + List.fold_left + (fun acc term -> micheline_size term acc) + (acc @+ node) + terms + | Prim (_, _, terms, _) -> + List.fold_left + (fun acc term -> micheline_size term acc) + (acc @+ node) + terms + in + micheline_size n {nodes = 0; bytes = 0} +end + +(** Cost model and benchmarks for set element addition from the + OCaml stdlib. + + The cost model is not currently used + in the protocol, but we include the benchmarks to validate our + assumptions about functions that use this. *) +module Set_add : Benchmark.S = struct + let name = "Set_add" + + let info = + "Benchmarks and cost model for set element addition from OCaml stdlib." + + let tags = ["global_constants"] + + type config = unit + + let config_encoding = Data_encoding.unit + + let default_config = () + + type workload = int + + let workload_encoding = Data_encoding.int31 + + let workload_to_vector : workload -> Sparse_vec.String.t = + fun size -> Sparse_vec.String.of_list [("size", float_of_int size)] + + (* As an OCaml set is a balanced binary tree, complexity is O(log n). *) + let models = + [ + ( "Set_add", + Model.( + make + ~conv:(fun size -> (size, ())) + ~model:(logn ~coeff:(Free_variable.of_string "size"))) ); + ] + + module Int_set = Set.Make (Int) + + let create_benchmark rng_state _config () = + let range : Base_samplers.range = {min = 0; max = 10_000} in + let size = Base_samplers.sample_in_interval ~range rng_state in + let set = Stdlib.List.init size Fun.id |> Int_set.of_list in + let closure () = ignore (Int_set.add (size + 1) set) in + Generator.Plain {workload = size; closure} + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (create_benchmark rng_state config) +end + +let () = + Registration_helpers.register (module Set_add) ; + Registration_helpers.register_for_codegen + "Set_add" + (Model.For_codegen + (WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc ~equal:String.equal "Set_add" Set_add.models)) + +(** Cost model and benchmarks for set elements from the + OCaml stdlib. + + The cost model is not currently used + in the protocol, but we include the benchmarks to validate our + assumptions about functions that use this. *) +module Set_elements : Benchmark.S = struct + let name = "Set_elements" + + let info = "Benchmarks and cost model for set elements from OCaml stdlib." + + let tags = ["global_constants"] + + type config = unit + + let config_encoding = Data_encoding.unit + + let default_config = () + + type workload = int + + let workload_encoding = Data_encoding.int31 + + let workload_to_vector : workload -> Sparse_vec.String.t = + fun size -> Sparse_vec.String.of_list [("size", float_of_int size)] + + (* Cost of retrieving all elements from the set is linear with the size + of the set.*) + let models = + [ + ( "Set_elements", + Model.( + make + ~conv:(fun size -> (size, ())) + ~model:(linear ~coeff:(Free_variable.of_string "size"))) ); + ] + + module Int_set = Set.Make (Int) + + let create_benchmark rng_state _config () = + let range : Base_samplers.range = {min = 0; max = 10_000} in + let size = Base_samplers.sample_in_interval ~range rng_state in + let set = Stdlib.List.init size (fun x -> x) |> Int_set.of_list in + let closure () = ignore (Int_set.elements set) in + Generator.Plain {workload = size; closure} + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (create_benchmark rng_state config) +end + +let () = + Registration_helpers.register (module Set_elements) ; + Registration_helpers.register_for_codegen + "Set_elements" + (Model.For_codegen + (WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc ~equal:String.equal "Set_elements" Set_elements.models)) + +(** Cost model and benchmarks for [Script_expr_hash.of_b58_check_opt]. + Under the hood this function uses the [Blake2b] functor, which uses + the HACL* crypto library. + + The cost model is not currently used + in the protocol, but we include the benchmarks to validate our + assumptions about functions that use this. *) +module Script_expr_hash_of_b58check_opt : Benchmark.S = struct + let name = "Script_expr_hash_of_b58check_opt" + + let info = "Benchmark for Script_expr_hash.of_b58check_opt" + + let tags = ["global_constants"] + + type config = unit + + let config_encoding = Data_encoding.unit + + let default_config = () + + type workload = Micheline_sampler.size + + let workload_encoding = + let open Data_encoding in + conv + (fun Micheline_sampler.{nodes; bytes} -> (nodes, bytes)) + (fun (nodes, bytes) -> {nodes; bytes}) + (obj2 (req "nodes" int31) (req "bytes" int31)) + + let workload_to_vector Micheline_sampler.{nodes; bytes} = + Sparse_vec.String.of_list + [("nodes", float_of_int nodes); ("bytes", float_of_int bytes)] + + (* On testing we found that this function is a constant + time operation. However, to test this, we use an affine model. If + our assumption holds, the coefficient should be near zero. *) + let models = + [ + ( "Script_expr_hash_of_b58check_opt", + Model.( + make + ~conv:(fun Micheline_sampler.{nodes; _} -> (nodes, ())) + ~model: + (Model.affine + ~intercept:(Free_variable.of_string "b58_check_cost") + ~coeff:(Free_variable.of_string "size"))) ); + ] + + (* To create realistic benchmarks, we generate a random Micheline expression, + hash it, then benchmark the cost of validating the hash. *) + let create_benchmark rng_state _config () = + let open Protocol in + let term = Micheline_sampler.sample rng_state in + let size = Micheline_sampler.micheline_size term in + let expr_encoding = Alpha_context.Script.expr_encoding in + let lazy_expr = + Data_encoding.make_lazy expr_encoding (Micheline.strip_locations term) + in + let expr_bytes = Data_encoding.force_bytes lazy_expr in + let hash = Script_expr_hash.hash_bytes [expr_bytes] in + let hash_str = Script_expr_hash.to_b58check hash in + let closure () = ignore (Script_expr_hash.of_b58check_opt hash_str) in + Generator.Plain {workload = size; closure} + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (create_benchmark rng_state config) +end + +let () = + Registration_helpers.register (module Script_expr_hash_of_b58check_opt) ; + Registration_helpers.register_for_codegen + "Script_expr_hash_of_b58check_opt" + (Model.For_codegen + (WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc + ~equal:String.equal + "Script_expr_hash_of_b58check_opt" + Script_expr_hash_of_b58check_opt.models)) + +module Global_constants_storage_expr_to_address_in_context : Benchmark.S = +struct + let name = "Global_constants_storage_expr_to_address_in_context" + + let info = + "Benchmark for the \ + Global_constants_storage.Internal_for_tests.expr_to_address_in_context \ + function" + + let tags = ["global_constants"] + + type config = unit + + let config_encoding = Data_encoding.unit + + let default_config = () + + type workload = int + + let workload_encoding = Data_encoding.int31 + + let workload_to_vector : workload -> Sparse_vec.String.t = + fun size -> Sparse_vec.String.of_list [("size", float_of_int size)] + + (** The cost of a Blake2b hashing function is linear with the size of the input *) + let models = + [ + ( "Global_constants_storage_expr_to_address_in_context", + Model.( + make + ~conv:(fun size -> (size, ())) + ~model:(linear ~coeff:(Free_variable.of_string "size"))) ); + ] + + let create_benchmark rng_state _config () = + let open Micheline in + let expr = Micheline_sampler.sample rng_state |> strip_locations in + let b = + Script_repr.lazy_expr expr |> Script_repr.force_bytes + |> Environment.wrap_tzresult |> assert_ok + in + let size = Bytes.length b in + + let closure () = ignore (Script_expr_hash.hash_bytes [b]) in + Generator.Plain {workload = size; closure} + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (create_benchmark rng_state config) +end + +let () = + Registration_helpers.register + (module Global_constants_storage_expr_to_address_in_context) ; + Registration_helpers.register_for_codegen + "Global_constants_storage_expr_to_address_in_context" + (Model.For_codegen + (WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc + ~equal:String.equal + "Global_constants_storage_expr_to_address_in_context" + Global_constants_storage_expr_to_address_in_context.models)) + +(** [Global_constants_storage.expand] traverses a Micheline node, + searching for constants and replacing them with their values + retrieved from storage. + + There are three branches in the iterations of [Global_constants_storage.expand] + can take, each with different costs: + - Branch 1: The first time a particular constant is found, the hash is parsed with + [Script_expr_hash.of_b58check_opt], and its value is retrieved + from storage. This storage call (implemented [Global_constants_storage.get]) + is already carbonated and dominates the cost in this case, so do not need to + benchmark Branch 1 - the benchmarks for storage access are sufficient. + - Branch 2: If the same constant is found a subsequent time, its value is looked up + in a map. On testing we determined that the cost of [Script_expr_hash.of_b58check_opt] + dominates the cost of this branch - the cost of an OCaml map lookup is O(log 2 n), and + n has to be unreasonably large to catch up to the constant time cost of validating the + hash. + - Branch 3: When no constant is found, the cost is merely that of pattern matching + and calling the continuation (similar to that of [Micheline.strip_locations]). + + Because we don't know the full size of node being traversed ahead of time (because they + are retrieved from storage), it is impossible to calculate the full gas cost upfront. + However, each time we find a new expression to traverse, we can calculate its size upfront + and charge the cost of all Branch 3 cases. We can then do an additional charge for Branch 2 + each time we find a constant, and let storage handle charging for Branch 1. + + Below are models for Branch 2 and 3 respectively. + *) +module Global_constants_storage_expand_models = struct + module Global_constants_storage_expand_constant_branch : Benchmark.S = struct + let name = "Global_constants_storage_expand_constant_branch" + + let info = + "Benchmark for the constant branch Global_constants_storage.expand \ + function" + + let tags = ["global_constants"] + + type config = unit + + let config_encoding = Data_encoding.unit + + let default_config = () + + type workload = int + + let workload_encoding = Data_encoding.int31 + + let workload_to_vector : workload -> Sparse_vec.String.t = + fun constants -> + Sparse_vec.String.of_list + [("number of constants", float_of_int constants)] + + (** The cost of Branch 2 is linear to the number of constants in the expression. As + discussed above, the constant time operation [Script_expr_hash.of_b58check_opt] + dominates the cost of each iteration. *) + let models = + [ + ( "Global_constants_storage_expand_constant_branch", + Model.( + make + ~conv:(fun size -> (size, ())) + ~model: + (linear ~coeff:(Free_variable.of_string "number of constants"))) + ); + ] + + (* To test Branch 2 as nearly as possible, we generate a Micheline Seq + consisting of the same constant repeated n times. As n increases, + the benchmark more closely approximates the true cost of Branch 2. *) + let create_benchmark rng_state _config () = + let open Micheline in + let node = Micheline_sampler.sample rng_state in + let size = (Micheline_sampler.micheline_size node).nodes in + let registered_constant = Int (-1, Z.of_int 1) in + let hash = registered_constant |> node_to_hash in + let (context, _) = Execution_context.make ~rng_state |> assert_ok_lwt in + let (context, _, _) = + Alpha_context.Global_constants_storage.register + context + (strip_locations registered_constant) + >|= Environment.wrap_tzresult |> assert_ok_lwt + in + let node = seq_of_n_constants size hash in + let closure () = + ignore + (Lwt_main.run + @@ Alpha_context.Global_constants_storage.expand + context + (strip_locations node)) + in + Generator.Plain {workload = size; closure} + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (create_benchmark rng_state config) + end + + let () = + Registration_helpers.register + (module Global_constants_storage_expand_constant_branch) ; + Registration_helpers.register_for_codegen + "Global_constants_storage_expand_constant_branch" + (Model.For_codegen + (WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc + ~equal:String.equal + "Global_constants_storage_expand_constant_branch" + Global_constants_storage_expand_constant_branch.models)) + + module Global_constants_storage_expand_no_constant_branch : Benchmark.S = + struct + let name = "Global_constants_storage_expand_no_constant_branch" + + let info = + "Benchmark for the Global_constants_storage.expand function on the case \ + without constants" + + let tags = ["global_constants"] + + type config = unit + + let config_encoding = Data_encoding.unit + + let default_config = () + + type workload = int + + let workload_encoding = Data_encoding.int31 + + let workload_to_vector : workload -> Sparse_vec.String.t = + fun size -> + Sparse_vec.String.of_list [("number of nodes", float_of_int size)] + + (* The cost of Branch 3 is the cost of traversing a single node. It + is therefore linear to the number of nodes being traversed. This is + very similar to [Micheline.strip_locations]. + + On testing I observed that while the linear model was accurate + for small numbers of nodes, after 1000 nodes the cost seems to increase more + than linearly. I think I would have to fine tune the sampler to better test + past this amount; however, I don't think it's necessary - to get large orders + of nodes, you need to use constants, in which case the cost of + [Script_expr_hash.of_b58check_opt] will dominate. A n*log(n) model seems + accurate enough for the range of values tested. + *) + let models = + [ + ( "Global_constants_storage_expand_no_constant_branch", + Model.( + make + ~conv:(fun size -> (size, ())) + ~model: + (nlogn + ~intercept:(Free_variable.of_string "cst") + ~coeff:(Free_variable.of_string "number of nodes"))) ); + ] + + (** We benchmark this by generating a random Micheline expression without constants + and calling [expand] on it. This causes the function to spend all its time in + Branch 3. *) + let create_benchmark rng_state _config () = + let open Micheline in + let node = Micheline_sampler.sample rng_state in + let size = (Micheline_sampler.micheline_size node).nodes in + let (context, _) = Execution_context.make ~rng_state |> assert_ok_lwt in + let expr = strip_locations node in + let closure () = + ignore + (Lwt_main.run + @@ Alpha_context.Global_constants_storage.expand context expr) + in + Generator.Plain {workload = size; closure} + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (create_benchmark rng_state config) + end + + let () = + Registration_helpers.register + (module Global_constants_storage_expand_no_constant_branch) ; + Registration_helpers.register_for_codegen + "Global_constants_storage_expand_no_constant_branch" + (Model.For_codegen + (WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc + ~equal:String.equal + "Global_constants_storage_expand_no_constant_branch" + Global_constants_storage_expand_no_constant_branch.models)) +end diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_benchmarks.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_benchmarks.ml new file mode 100644 index 000000000000..abb7b1e42e2b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_benchmarks.ml @@ -0,0 +1,3139 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(* ------------------------------------------------------------------------- *) + +type ex_stack_and_kinstr = + | Ex_stack_and_kinstr : { + stack : 'a * 'b; + kinstr : ('a, 'b, 'c, 'd) Script_typed_ir.kinstr; + } + -> ex_stack_and_kinstr + +type ex_stack_and_continuation = + | Ex_stack_and_cont : { + stack : 'a * 'b; + cont : ('a, 'b, 'c, 'd) Script_typed_ir.continuation; + } + -> ex_stack_and_continuation + +type ex_value = + | Ex_value : {value : 'a; ty : 'a Script_typed_ir.ty} -> ex_value + +(* ------------------------------------------------------------------------- *) + +let sf = Printf.sprintf + +(* End of Stack *) +let eos = Script_typed_ir.(EmptyCell, EmptyCell) + +let info_and_name ~intercept ?(salt = "") s = + let s = s ^ salt in + if intercept then (sf "Benchmark %s (intercept case)" s, s ^ "_intercept") + else (sf "Benchmark %s" s, s) + +module Default_boilerplate = struct + type workload = Interpreter_workload.t + + let workload_encoding = Interpreter_workload.encoding + + let workload_to_vector = Interpreter_workload.trace_to_sparse_vec + + let tags = [Tags.interpreter] +end + +module Default_config = struct + (* Configuration specific to sapling benchmarks *) + type sapling_config = {sapling_txs_file : string; seed : int option} + + (* Configuration specific to benchmarking Dign/Dipn/Dupn/Dropn/Combs *) + type comb_config = {max_depth : int} + + (* Configuration specific to benchmarking ICompare *) + type compare_config = {type_size : Base_samplers.range} + + type config = { + sampler : Michelson_samplers.parameters; + sapling : sapling_config; + comb : comb_config; + compare : compare_config; + } + + let default_config = + let open Michelson_samplers in + let open Michelson_samplers_base in + let sampler = + { + base_parameters = + { + int_size = {min = 8; max = 100_000}; + string_size = {min = 1 lsl 10; max = 1 lsl 17}; + bytes_size = {min = 1 lsl 10; max = 1 lsl 17}; + }; + list_size = {min = 10; max = 1000}; + set_size = {min = 10; max = 1000}; + map_size = {min = 10; max = 1000}; + } + in + { + sampler; + sapling = {sapling_txs_file = {|/no/such/file|}; seed = None}; + comb = {max_depth = 1000}; + compare = {type_size = {min = 1; max = 15}}; + } + + let sapling_config_encoding = + let open Data_encoding in + conv + (fun {sapling_txs_file; seed} -> (sapling_txs_file, seed)) + (fun (sapling_txs_file, seed) -> {sapling_txs_file; seed}) + (obj2 (req "sapling_txs_file" string) (req "seed" (option int31))) + + let comb_config_encoding = + let open Data_encoding in + conv + (fun {max_depth} -> max_depth) + (fun max_depth -> {max_depth}) + (obj1 (req "max_depth" int31)) + + let compare_config_encoding = + let open Data_encoding in + conv + (fun {type_size} -> type_size) + (fun type_size -> {type_size}) + (obj1 (req "type_size" Base_samplers.range_encoding)) + + let config_encoding = + let open Data_encoding in + conv + (fun {sampler; sapling; comb; compare} -> + (sampler, sapling, comb, compare)) + (fun (sampler, sapling, comb, compare) -> + {sampler; sapling; comb; compare}) + (obj4 + (req "sampler" Michelson_samplers.parameters_encoding) + (req "sapling" sapling_config_encoding) + (req "comb" comb_config_encoding) + (req "compare" compare_config_encoding)) +end + +let make_default_samplers ?(algo = `Default) cfg : + (module Crypto_samplers.Finite_key_pool_S) * (module Michelson_samplers.S) = + let module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct + let size = 16 + + let algo = algo + end) in + let module Michelson_samplers = + Michelson_samplers.Make + (struct + let parameters = cfg + end) + (Crypto_samplers) + in + ((module Crypto_samplers), (module Michelson_samplers)) + +(* ------------------------------------------------------------------------- *) +(* Helpers for creating benchmarks for the interpreter *) + +let benchmark_from_kinstr_and_stack : + ?amplification:int -> + Alpha_context.context -> + Protocol.Script_interpreter.step_constants -> + ex_stack_and_kinstr -> + Interpreter_workload.ir_sized_step list Generator.benchmark = + fun ?amplification ctxt step_constants stack_kinstr -> + let ctxt = Gas_helpers.set_limit ctxt in + match stack_kinstr with + | Ex_stack_and_kinstr {stack = (bef_top, bef); kinstr} -> + let (workload, closure) = + match amplification with + | None -> + let workload = + Interpreter_workload.extract_deps + ctxt + step_constants + kinstr + (bef_top, bef) + in + let outdated_ctxt = + Script_interpreter.Internals.OutDatedContext ctxt + in + let closure () = + ignore + (* Lwt_main.run *) + (Script_interpreter.Internals.step + (outdated_ctxt, step_constants) + 9_999_999_999 + kinstr + bef_top + bef) + in + (workload, closure) + | Some amplification_factor -> + assert (amplification_factor > 0) ; + let workload = + Interpreter_workload.extract_deps + ctxt + step_constants + kinstr + (bef_top, bef) + in + let workload = + List.repeat amplification_factor workload |> List.flatten + in + let outdated_ctxt = + Script_interpreter.Internals.OutDatedContext ctxt + in + let closure () = + for _i = 1 to amplification_factor do + ignore + (* Lwt_main.run *) + (Script_interpreter.Internals.step + (outdated_ctxt, step_constants) + 9_999_999_999 + kinstr + bef_top + bef) + done + in + (workload, closure) + in + Generator.Plain {workload; closure} + +let make_benchmark : + ?amplification:int -> + ?intercept:bool -> + ?salt:string -> + ?more_tags:string list -> + name:Interpreter_workload.instruction_name -> + kinstr_and_stack_sampler: + (Default_config.config -> Random.State.t -> unit -> ex_stack_and_kinstr) -> + unit -> + Benchmark.t = + fun ?amplification + ?(intercept = false) + ?salt + ?(more_tags = []) + ~name + ~kinstr_and_stack_sampler + () -> + let module B : Benchmark.S = struct + include Default_config + include Default_boilerplate + + let tags = tags @ more_tags + + let models = + (* [intercept = true] implies there's a benchmark with [intercept = false]. + No need to register the model twice. *) + Interpreter_model.make_model + ?amplification + (if intercept then None else Some (Instr_name name)) + + let (info, name) = + info_and_name + ~intercept + ?salt + (Interpreter_workload.string_of_instruction_name name) + + let benchmark kinstr_and_stack_sampler ctxt step_constants () = + let stack_instr = kinstr_and_stack_sampler () in + benchmark_from_kinstr_and_stack + ?amplification + ctxt + step_constants + stack_instr + + let create_benchmarks ~rng_state ~bench_num (config : config) = + match Lwt_main.run (Execution_context.make ~rng_state) with + | Error _errs -> assert false + | Ok (ctxt, step_constants) -> + let kinstr_and_stack_sampler = + kinstr_and_stack_sampler config rng_state + in + List.repeat + bench_num + (benchmark kinstr_and_stack_sampler ctxt step_constants) + end in + (module B : Benchmark.S) + +let make_simple_benchmark : + type bef_top bef res_top res. + ?amplification:int -> + ?intercept:bool -> + ?more_tags:string list -> + ?salt:string -> + name:Interpreter_workload.instruction_name -> + kinstr:(bef_top, bef, res_top, res) Script_typed_ir.kinstr -> + unit -> + Benchmark.t = + fun ?amplification ?intercept ?more_tags ?salt ~name ~kinstr () -> + let kinfo = Script_typed_ir.kinfo_of_kinstr kinstr in + let stack_ty = kinfo.kstack_ty in + let kinstr_and_stack_sampler config rng_state = + let (_, (module Samplers)) = + make_default_samplers config.Default_config.sampler + in + fun () -> + Ex_stack_and_kinstr + {stack = Samplers.Random_value.stack stack_ty rng_state; kinstr} + in + make_benchmark + ?amplification + ?intercept + ?more_tags + ?salt + ~name + ~kinstr_and_stack_sampler + () + +let benchmark ?amplification ?intercept ?more_tags ?salt ~name + ~kinstr_and_stack_sampler () = + let bench = + make_benchmark + ?amplification + ?intercept + ?more_tags + ?salt + ~name + ~kinstr_and_stack_sampler + () + in + Registration_helpers.register bench + +let benchmark_with_stack_sampler ?amplification ?intercept ?more_tags ?salt + ~name ~kinstr ~stack_sampler () = + let kinstr_and_stack_sampler config rng_state = + let stack_sampler = stack_sampler config rng_state in + fun () -> Ex_stack_and_kinstr {stack = stack_sampler (); kinstr} + in + let bench = + make_benchmark + ?amplification + ?intercept + ?more_tags + ?salt + ~name + ~kinstr_and_stack_sampler + () + in + Registration_helpers.register bench + +let benchmark_with_fixed_stack ?amplification ?intercept ?more_tags ?salt ~name + ~stack ~kinstr () = + benchmark_with_stack_sampler + ?amplification + ?intercept + ?more_tags + ?salt + ~name + ~kinstr + ~stack_sampler:(fun _cfg _rng_state () -> stack) + () + +let simple_benchmark_with_stack_sampler ?amplification ?intercept_stack ?salt + ?more_tags ~name ~kinstr ~stack_sampler () = + benchmark_with_stack_sampler + ?amplification + ~intercept:false + ?salt + ?more_tags + ~name + ~kinstr + ~stack_sampler + () ; + Option.iter + (fun stack -> + benchmark_with_fixed_stack + ?amplification + ~intercept:true + ?more_tags + ?salt + ~name + ~stack + ~kinstr + ()) + intercept_stack + +let simple_benchmark ?amplification ?intercept_stack ?more_tags ?salt ~name + ~kinstr () = + let bench = + make_simple_benchmark + ?amplification + ~intercept:false + ?more_tags + ?salt + ~name + ~kinstr + () + in + Registration_helpers.register bench ; + Option.iter + (fun stack -> + benchmark_with_fixed_stack + ?amplification + ~intercept:true + ?more_tags + ?salt + ~name + ~stack + ~kinstr + ()) + intercept_stack + +(* ------------------------------------------------------------------------- *) +(* Helpers for creating benchmarks for [Script_interpreter.next] *) + +let benchmark_from_continuation : + ?amplification:int -> + Alpha_context.context -> + Protocol.Script_interpreter.step_constants -> + ex_stack_and_continuation -> + Interpreter_workload.ir_sized_step list Generator.benchmark = + fun ?amplification ctxt step_constants stack_cont -> + let ctxt = Gas_helpers.set_limit ctxt in + match stack_cont with + | Ex_stack_and_cont {stack = (bef_top, bef); cont} -> + let (workload, closure) = + match amplification with + | None -> + let workload = + Interpreter_workload.extract_deps_continuation + ctxt + step_constants + cont + (bef_top, bef) + in + let outdated_ctxt = + Script_interpreter.Internals.OutDatedContext ctxt + in + let closure () = + ignore + (* Lwt_main.run *) + (Script_interpreter.Internals.next + None + (outdated_ctxt, step_constants) + 9_999_999_999 + cont + bef_top + bef) + in + (workload, closure) + | Some amplification_factor -> + assert (amplification_factor > 0) ; + let workload = + Interpreter_workload.extract_deps_continuation + ctxt + step_constants + cont + (bef_top, bef) + in + let workload = + List.repeat amplification_factor workload |> List.flatten + in + let outdated_ctxt = + Script_interpreter.Internals.OutDatedContext ctxt + in + let closure () = + for _i = 1 to amplification_factor do + ignore + (* Lwt_main.run *) + (Script_interpreter.Internals.next + None + (outdated_ctxt, step_constants) + 9_999_999_999 + cont + bef_top + bef) + done + in + (workload, closure) + in + Generator.Plain {workload; closure} + +let make_continuation_benchmark : + ?amplification:int -> + ?intercept:bool -> + ?salt:string -> + ?more_tags:string list -> + name:Interpreter_workload.continuation_name -> + cont_and_stack_sampler: + (Default_config.config -> + Random.State.t -> + unit -> + ex_stack_and_continuation) -> + unit -> + Benchmark.t = + fun ?amplification + ?(intercept = false) + ?salt + ?(more_tags = []) + ~name + ~cont_and_stack_sampler + () -> + let module B : Benchmark.S = struct + include Default_config + include Default_boilerplate + + let tags = tags @ more_tags + + let models = + Interpreter_model.make_model + ?amplification + (if intercept then None else Some (Cont_name name)) + + let (info, name) = + info_and_name + ~intercept + ?salt + (Interpreter_workload.string_of_continuation_name name) + + let benchmark cont_and_stack_sampler ctxt step_constants () = + let stack_instr = cont_and_stack_sampler () in + benchmark_from_continuation ?amplification ctxt step_constants stack_instr + + let create_benchmarks ~rng_state ~bench_num (config : config) = + match Lwt_main.run (Execution_context.make ~rng_state) with + | Error _errs -> assert false + | Ok (ctxt, step_constants) -> + let cont_and_stack_sampler = + cont_and_stack_sampler config rng_state + in + List.repeat + bench_num + (benchmark cont_and_stack_sampler ctxt step_constants) + end in + (module B : Benchmark.S) + +let continuation_benchmark ?amplification ?intercept ?salt ?more_tags ~name + ~cont_and_stack_sampler () = + let bench = + make_continuation_benchmark + ?amplification + ?intercept + ?salt + ?more_tags + ~name + ~cont_and_stack_sampler + () + in + Registration_helpers.register bench + +(* ------------------------------------------------------------------------- *) +(* Sampling helpers *) + +let nat_of_positive_int (i : int) = + let open Alpha_context.Script_int in + match is_nat (of_int i) with None -> assert false | Some x -> x + +let adversarial_ints rng_state (cfg : Default_config.config) n = + let (_common_prefix, ls) = + Base_samplers.Adversarial.integers + ~prefix_size:cfg.sampler.base_parameters.int_size + ~card:n + rng_state + in + List.map Script_int_repr.of_zint ls + +(* ------------------------------------------------------------------------- *) +(* Error helpers *) + +let raise_if_error = function + | Ok x -> x + | Error e -> + Format.eprintf "%a@." (Error_monad.TzTrace.pp_print Error_monad.pp) e ; + Stdlib.failwith "raise_if_error" + +(* ------------------------------------------------------------------------- *) + +(** [Registration_section] contains all interpreter benchmarks. The goal of + a benchmark is to gather enough data to reliably estimate the parameters + of the cost model associated to each instruction. In general, it can + take several distinct benchmarks to properly cover all the execution + paths. + + In particular, for affine cost model, it is often worth estimating the + intercept separately from the size-dependent coefficients. + *) + +module Registration_section = struct + open Script_typed_ir + open Michelson_types + + let sf = Printf.sprintf + + let kinfo kstack_ty = {iloc = 0; kstack_ty} + + let halt stack_ty = IHalt (kinfo stack_ty) + + let halt_unit = halt (unit @$ bot) + + let halt_unitunit = halt (unit @$ unit @$ bot) + + let kinfo_unit = kinfo (unit @$ bot) + + let kinfo_unitunit = kinfo (unit @$ unit @$ bot) + + let () = + (* KHalt *) + simple_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_IHalt + ~kinstr:halt_unit + () + + module Amplification = struct + module Loop : Benchmark.S = struct + let name = "amplification_loop" + + let info = "Benchmarking the cost of an empty loop" + + let tags = [Tags.interpreter] + + type config = {max_iterations : int} + + let config_encoding = + let open Data_encoding in + conv + (fun {max_iterations} -> max_iterations) + (fun max_iterations -> {max_iterations}) + (obj1 (req "max_iterations" int31)) + + let default_config = {max_iterations = 100000} + + type workload = int + + let workload_encoding = Data_encoding.int31 + + let workload_to_vector n = + Sparse_vec.String.of_list [("iterations", float_of_int n)] + + let models = [("interpreter", Interpreter_model.amplification_loop_model)] + + let benchmark rng_state config () = + let workload = Random.State.int rng_state config.max_iterations in + let closure () = + for _i = 1 to workload do + Sys.opaque_identity () + done + in + Generator.Plain {workload; closure} + + let create_benchmarks ~rng_state ~bench_num (config : config) = + List.repeat bench_num (benchmark rng_state config) + end + end + + let () = Registration_helpers.register (module Amplification.Loop) + + module Stack = struct + let () = + (* KDrop ; KHalt *) + simple_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_IDrop + ~kinstr:(IDrop (kinfo_unitunit, halt_unit)) + () + + let () = + (* IDup ; IHalt *) + simple_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_IDup + ~kinstr:(IDup (kinfo_unit, halt_unitunit)) + () + + let () = + simple_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_ISwap + ~kinstr:(ISwap (kinfo_unitunit, halt_unitunit)) + () + + let () = + simple_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_IConst + ~kinstr:(IConst (kinfo_unit, (), halt_unitunit)) + () + + (* deep stack manipulation *) + + (* Constructing these instructions is made especially painful by the + fact that they include "stack preservation witnesses", which are not + exposed in Script_ir_translator. + We must go through [Script_ir_translator.parse_instr] to construct + the corresponding terms. *) + type ex_stack = + | Ex_stack : ('a, 'b) Script_typed_ir.stack_ty * ('a * 'b) -> ex_stack + + let rec make_stack (depth : int) = + if depth = 0 then assert false + else if depth = 1 then Ex_stack (unit @$ Script_typed_ir.Bot_t, ((), eos)) + else + let stack = make_stack (depth - 1) in + match stack with + | Ex_stack (stack_ty, stack) -> Ex_stack (unit @$ stack_ty, ((), stack)) + + let parse_instr rng_state node stack = + match stack with + | Ex_stack (stack_ty, stack) -> + raise_if_error + (Lwt_main.run + ( Execution_context.make ~rng_state + >>=? fun (ctxt, _step_constants) -> + Script_ir_translator.parse_instr + Script_ir_translator.Lambda + ctxt + ~legacy:false + node + stack_ty + >|= Environment.wrap_tzresult + >>=? fun (judgement, _) -> + match judgement with + | Script_ir_translator.Typed descr -> + let kinfo = {iloc = 0; kstack_ty = descr.bef} in + let kinfo' = {iloc = 0; kstack_ty = descr.aft} in + let kinstr = descr.instr.apply kinfo (IHalt kinfo') in + return (Ex_stack_and_kinstr {stack; kinstr}) + | Script_ir_translator.Failed _ -> assert false )) + + open Protocol.Michelson_v1_primitives + + (* The size parameter of a deep stack instruction must fit on 10 bits. See + [Script_ir_translator.parse_uint10]. *) + let stack_size = 1023 + + let long_stack = make_stack stack_size + + let sample_depth rng_state = + Base_samplers.( + sample_in_interval rng_state ~range:{min = 0; max = stack_size - 2}) + + let () = + let dig = Micheline.(Prim (0, I_DIG, [Int (0, Z.of_int 0)], [])) in + benchmark + ~amplification:100 + ~intercept:true + ~name:Interpreter_workload.N_IDig + ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> + let node = dig in + parse_instr rng_state node long_stack) + () + + let () = + let dig n = Micheline.(Prim (0, I_DIG, [Int (0, Z.of_int n)], [])) in + benchmark + ~name:Interpreter_workload.N_IDig + ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> + let node = dig (sample_depth rng_state) in + parse_instr rng_state node long_stack) + () + + let () = + let dug = Micheline.(Prim (0, I_DUG, [Int (0, Z.of_int 0)], [])) in + benchmark + ~intercept:true + ~name:Interpreter_workload.N_IDug + ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> + let node = dug in + parse_instr rng_state node long_stack) + () + + let () = + let dug n = Micheline.(Prim (0, I_DUG, [Int (0, Z.of_int n)], [])) in + benchmark + ~name:Interpreter_workload.N_IDug + ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> + let node = dug (sample_depth rng_state) in + parse_instr rng_state node long_stack) + () + + let () = + let nop = Micheline.Seq (0, []) in + let dip = Micheline.(Prim (0, I_DIP, [Int (0, Z.of_int 0); nop], [])) in + benchmark + ~intercept:true + ~name:Interpreter_workload.N_IDipN + ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> + let node = dip in + parse_instr rng_state node long_stack) + () + + let () = + let nop = Micheline.Seq (0, []) in + let dip n = Micheline.(Prim (0, I_DIP, [Int (0, Z.of_int n); nop], [])) in + benchmark + ~name:Interpreter_workload.N_IDipN + ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> + let node = dip (sample_depth rng_state) in + parse_instr rng_state node long_stack) + () + + let () = + let drop = Micheline.(Prim (0, I_DROP, [Int (0, Z.of_int 0)], [])) in + benchmark + ~intercept:true + ~name:Interpreter_workload.N_IDropN + ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> + let node = drop in + parse_instr rng_state node long_stack) + () + + let () = + let drop n = Micheline.(Prim (0, I_DROP, [Int (0, Z.of_int n)], [])) in + benchmark + ~name:Interpreter_workload.N_IDropN + ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> + let node = drop (sample_depth rng_state) in + parse_instr rng_state node long_stack) + () + + let () = + let pair n = Micheline.(Prim (0, I_PAIR, [Int (0, Z.of_int n)], [])) in + benchmark + ~name:Interpreter_workload.N_IComb + ~kinstr_and_stack_sampler:(fun cfg rng_state () -> + let width = + Base_samplers.( + sample_in_interval + rng_state + ~range:{min = 2; max = cfg.comb.max_depth}) + in + let node = pair width in + parse_instr rng_state node long_stack) + () + + let rec make_comb_stack (comb_width : int) (depth : int) acc = + if depth = 0 then + match acc with + | Ex_stack (stack_ty, stack) -> ( + match make_comb comb_width (Ex_value {value = (); ty = unit}) with + | Ex_value {value; ty} -> Ex_stack (ty @$ stack_ty, (value, stack))) + else + match acc with + | Ex_stack (stack_ty, stack) -> + make_comb_stack + comb_width + (depth - 1) + (Ex_stack (unit @$ stack_ty, ((), stack))) + + and make_comb comb_width comb_acc = + if comb_width = 0 then assert false + else if comb_width = 1 then comb_acc + else + match comb_acc with + | Ex_value {value; ty} -> + make_comb + (comb_width - 1) + (Ex_value {value = ((), value); ty = pair unit ty}) + + let () = + let unpair n = + Micheline.(Prim (0, I_UNPAIR, [Int (0, Z.of_int n)], [])) + in + benchmark + ~name:Interpreter_workload.N_IUncomb + ~kinstr_and_stack_sampler:(fun cfg rng_state () -> + let width = + Base_samplers.( + sample_in_interval + rng_state + ~range:{min = 2; max = cfg.comb.max_depth - 2}) + in + let node = unpair width in + let stack = + make_comb_stack width 1 (Ex_stack (unit @$ bot, ((), eos))) + in + parse_instr rng_state node stack) + () + + let () = + let comb_get n = Micheline.(Prim (0, I_GET, [Int (0, Z.of_int n)], [])) in + benchmark + ~name:Interpreter_workload.N_IComb_get + ~kinstr_and_stack_sampler:(fun cfg rng_state () -> + let width = + Base_samplers.( + sample_in_interval + rng_state + ~range:{min = 2; max = cfg.comb.max_depth - 2}) + in + let index = + Base_samplers.( + sample_in_interval rng_state ~range:{min = 0; max = width}) + in + let node = comb_get index in + let stack = + make_comb_stack width 1 (Ex_stack (unit @$ bot, ((), eos))) + in + parse_instr rng_state node stack) + () + + let () = + let comb_set n = + Micheline.(Prim (0, I_UPDATE, [Int (0, Z.of_int n)], [])) + in + benchmark + ~name:Interpreter_workload.N_IComb_set + ~kinstr_and_stack_sampler:(fun cfg rng_state () -> + let width = + Base_samplers.( + sample_in_interval + rng_state + ~range:{min = 2; max = cfg.comb.max_depth - 2}) + in + let index = + Base_samplers.( + sample_in_interval rng_state ~range:{min = 0; max = width}) + in + let node = comb_set index in + let stack = + let (Ex_stack (stack_ty, stack)) = + make_comb_stack width 1 (Ex_stack (unit @$ bot, ((), eos))) + in + Ex_stack (unit @$ stack_ty, ((), stack)) + in + parse_instr rng_state node stack) + () + + let () = + let dup n = Micheline.(Prim (0, I_DUP, [Int (0, Z.of_int n)], [])) in + benchmark + ~name:Interpreter_workload.N_IDupN + ~kinstr_and_stack_sampler:(fun _cfg rng_state () -> + let node = dup (1 + sample_depth rng_state) in + parse_instr rng_state node long_stack) + () + end + + module Pairs = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_ICons_pair + ~kinstr:(ICons_pair (kinfo_unitunit, halt (pair unit unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ICar + ~kinstr:(ICar (kinfo (pair unit unit @$ bot), halt_unit)) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ICdr + ~kinstr:(ICdr (kinfo (pair unit unit @$ bot), halt_unit)) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IUnpair + ~kinstr:(IUnpair (kinfo (pair unit unit @$ bot), halt_unitunit)) + () + end + + module Options = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_ICons_some + ~kinstr:(ICons_some (kinfo_unit, halt (option unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ICons_none + ~kinstr:(ICons_none (kinfo_unit, halt (option unit @$ unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IIf_none + ~kinstr: + (IIf_none + { + kinfo = kinfo (option unit @$ unit @$ bot); + branch_if_none = halt_unit; + branch_if_some = IDrop (kinfo_unitunit, halt_unit); + k = halt_unit; + }) + () + + let () = + benchmark_with_fixed_stack + ~name:Interpreter_workload.N_IOpt_map + ~salt:"none" + ~stack:(None, ((), eos)) + ~kinstr: + (IOpt_map + { + kinfo = kinfo (option unit @$ unit @$ bot); + body = halt_unitunit; + k = halt (option unit @$ unit @$ bot); + }) + () + + let () = + benchmark_with_fixed_stack + ~name:Interpreter_workload.N_IOpt_map + ~salt:"some" + ~stack:(Some (), ((), eos)) + ~kinstr: + (IOpt_map + { + kinfo = kinfo (option unit @$ unit @$ bot); + body = halt_unitunit; + k = halt (option unit @$ unit @$ bot); + }) + () + end + + module Unions = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_ILeft + ~kinstr:(ICons_left (kinfo_unit, halt (union unit unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IRight + ~kinstr:(ICons_right (kinfo_unit, halt (union unit unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IIf_left + ~kinstr: + (IIf_left + { + kinfo = kinfo (union unit unit @$ bot); + branch_if_left = halt_unit; + branch_if_right = halt_unit; + k = halt_unit; + }) + () + end + + module Lists = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_ICons_list + ~kinstr: + (ICons_list (kinfo (unit @$ list unit @$ bot), halt (list unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_INil + ~kinstr:(INil (kinfo_unit, halt (list unit @$ unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IIf_cons + ~kinstr: + (IIf_cons + { + kinfo = kinfo (list unit @$ unit @$ bot); + branch_if_cons = + IDrop + ( kinfo (unit @$ list unit @$ unit @$ bot), + IDrop (kinfo (list unit @$ unit @$ bot), halt_unit) ); + branch_if_nil = halt_unit; + k = halt_unit; + }) + () + + module Mapping = struct + let kinfo_enter_body = kinfo_unit + + let kinfo_exit_body = kinfo_unitunit + + let () = + (* + IList_map -> + IList_enter_body (empty case) -> + IHalt + *) + benchmark_with_fixed_stack + ~name:Interpreter_workload.N_IList_map + ~stack:(Script_list.empty, ((), eos)) + ~kinstr: + (IList_map + ( kinfo (list unit @$ unit @$ bot), + halt_unitunit, + halt (list unit @$ unit @$ bot) )) + () + end + + let () = + let kinfo = kinfo (list unit @$ bot) in + simple_benchmark + ~name:Interpreter_workload.N_IList_size + ~kinstr:(IList_size (kinfo, halt (nat @$ bot))) + () + + let () = + (* + IList_iter -> + IIter (empty case) -> + IHalt + *) + let kinfo1 = kinfo (list unit @$ unit @$ bot) in + benchmark_with_fixed_stack + ~name:Interpreter_workload.N_IList_iter + ~stack:(Script_list.empty, ((), eos)) + ~kinstr: + (IList_iter (kinfo1, IDrop (kinfo_unitunit, halt_unit), halt_unit)) + () + end + + module Sets = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_IEmpty_set + ~kinstr: + (IEmpty_set (kinfo_unit, unit_cmp, halt (set unit_cmp @$ unit @$ bot))) + () + + let set_iter_code = + ISet_iter + ( kinfo (set int_cmp @$ unit @$ bot), + IDrop (kinfo (int @$ unit @$ bot), halt_unit), + halt_unit ) + + let () = + (* + ISet_iter -> + (List.rev (set_fold)) -> + { + IIter -> + IDrop -> + ICons -> + ... + } + *) + simple_benchmark + ~name:Interpreter_workload.N_ISet_iter + ~intercept_stack:(Script_set.empty int_cmp, ((), eos)) + ~kinstr:set_iter_code + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_ISet_mem + ~kinstr: + (ISet_mem + ( kinfo (int @$ set int_cmp @$ unit @$ bot), + halt (bool @$ unit @$ bot) )) + ~intercept_stack: + (Alpha_context.Script_int.zero, (Script_set.empty int_cmp, ((), eos))) + ~stack_sampler:(fun cfg rng_state () -> + assert (cfg.sampler.set_size.min >= 1) ; + let n = + Base_samplers.sample_in_interval + rng_state + ~range:cfg.sampler.set_size + in + let elts = adversarial_ints rng_state cfg n in + let set = + List.fold_left + (fun set elt -> Script_set.update elt true set) + (Script_set.empty int_cmp) + elts + in + let elt = + List.nth_opt elts (Random.State.int rng_state n) + |> WithExceptions.Option.get ~loc:__LOC__ + in + (elt, (set, ((), eos)))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_ISet_update + ~kinstr: + (ISet_update + ( kinfo (int @$ bool @$ set int_cmp @$ bot), + halt (set int_cmp @$ bot) )) + ~intercept_stack: + ( Alpha_context.Script_int.zero, + (false, (Script_set.empty int_cmp, eos)) ) + ~stack_sampler:(fun cfg rng_state () -> + assert (cfg.sampler.set_size.min >= 2) ; + let n = + Base_samplers.sample_in_interval + rng_state + ~range:cfg.sampler.set_size + in + let elts = adversarial_ints rng_state cfg (n + 1) in + let (out_of_set, in_set) = + match elts with [] -> assert false | hd :: tl -> (hd, tl) + in + let set = + List.fold_left + (fun set elt -> Script_set.update elt true set) + (Script_set.empty int_cmp) + in_set + in + let stack = + let flip = Random.State.bool rng_state in + if flip then + (* add an element not in the set *) + (out_of_set, (true, (set, eos))) + else + (* remove an element in the set *) + let elt = out_of_set in + let set = Script_set.update elt true set in + (elt, (flip, (set, eos))) + in + stack) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISet_size + ~kinstr:(ISet_size (kinfo (set unit_cmp @$ bot), halt (nat @$ bot))) + () + end + + module Maps = struct + let generate_map_and_key_in_map (cfg : Default_config.config) rng_state = + let n = + Base_samplers.sample_in_interval rng_state ~range:cfg.sampler.set_size + in + let keys = adversarial_ints rng_state cfg n in + let map = + List.fold_left + (fun map i -> Script_map.update i (Some ()) map) + (Script_map.empty int_cmp) + keys + in + let (module M) = map in + let key = + M.OPS.fold (fun k _ -> function None -> Some k | x -> x) M.boxed None + |> WithExceptions.Option.get ~loc:__LOC__ + in + (key, map) + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IEmpty_map + ~kinstr: + (IEmpty_map + (kinfo_unit, unit_cmp, halt (map unit_cmp unit @$ unit @$ bot))) + () + + (* + let map_map_code = + IMap_map + ( kinfo (map int_cmp unit @$ unit @$ bot), + ICdr (kinfo (pair int unit @$ unit @$ bot), halt_unitunit), + halt (map int_cmp unit @$ unit @$ bot) ) + *) + + let map_map_code = + IMap_map + ( kinfo (map int_cmp unit @$ unit @$ bot), + IFailwith (kinfo (pair int unit @$ unit @$ bot), 0, pair int unit), + halt (map int_cmp unit @$ unit @$ bot) ) + + let () = + (* + Map_map (nonempty case) -> + (List.rev (map_fold nonempty_map)) -> + KMap_enter_body (nonempty case) -> + fail (early interruption) + *) + simple_benchmark + ~name:Interpreter_workload.N_IMap_map + ~intercept_stack: + (let map = Script_map.empty int_cmp in + (map, ((), eos))) + ~kinstr:map_map_code + () + + let kmap_iter_code = + IMap_iter + ( kinfo (map int_cmp unit @$ unit @$ bot), + IDrop (kinfo (pair int unit @$ unit @$ bot), halt_unit), + halt_unit ) + + let () = + (* + IMap_iter (nonempty case) -> + (List.rev (map_fold (nonempty))) -> + IIter (nonempty case) -> + ... + *) + simple_benchmark + ~name:Interpreter_workload.N_IMap_iter + ~intercept_stack: + (let map = Script_map.empty int_cmp in + (map, ((), eos))) + ~kinstr:kmap_iter_code + () + + let () = + (* + IMap_mem -> + (map_mem) -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IMap_mem + ~kinstr: + (IMap_mem + ( kinfo (int @$ map int_cmp unit @$ unit @$ bot), + halt (bool @$ unit @$ bot) )) + ~intercept_stack: + (let map = Script_map.empty int_cmp in + (Alpha_context.Script_int.zero, (map, ((), eos)))) + ~stack_sampler:(fun cfg rng_state () -> + let (key, map) = generate_map_and_key_in_map cfg rng_state in + (key, (map, ((), eos)))) + () + + let () = + (* + IMap_get -> + (map_get) -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IMap_get + ~kinstr: + (IMap_get + ( kinfo (int @$ map int_cmp unit @$ unit @$ bot), + halt (option unit @$ unit @$ bot) )) + ~intercept_stack: + (let map = Script_map.empty int_cmp in + (Alpha_context.Script_int.zero, (map, ((), eos)))) + ~stack_sampler:(fun cfg rng_state () -> + let (key, map) = generate_map_and_key_in_map cfg rng_state in + (key, (map, ((), eos)))) + () + + let () = + (* + IMap_update -> + (map_update) -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IMap_update + ~kinstr: + (IMap_update + ( kinfo (int @$ option unit @$ map int_cmp unit @$ bot), + halt (map int_cmp unit @$ bot) )) + ~intercept_stack: + (let map = Script_map.empty int_cmp in + (Alpha_context.Script_int.zero, (None, (map, eos)))) + ~stack_sampler:(fun cfg rng_state () -> + let (key, map) = generate_map_and_key_in_map cfg rng_state in + (key, (Some (), (map, eos)))) + () + + let () = + (* + IMap_get_and_update -> + (map_update) -> + (map_get) -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IMap_get_and_update + ~kinstr: + (IMap_get_and_update + ( kinfo (int @$ option unit @$ map int_cmp unit @$ bot), + halt (option unit @$ map int_cmp unit @$ bot) )) + ~intercept_stack: + (let map = Script_map.empty int_cmp in + (Alpha_context.Script_int.zero, (None, (map, eos)))) + ~stack_sampler:(fun cfg rng_state () -> + let (key, map) = generate_map_and_key_in_map cfg rng_state in + (key, (Some (), (map, eos)))) + () + + let () = + (* + IMap_size -> + (map_update) -> + (map_get) -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IMap_size + ~kinstr:(IMap_size (kinfo (map int_cmp unit @$ bot), halt (nat @$ bot))) + ~stack_sampler:(fun _cfg _rng_state -> + let map = Script_map.empty int_cmp in + fun () -> (map, eos)) + () + end + + module Big_maps = struct + let generate_big_map_and_key_in_map (cfg : Default_config.config) rng_state + = + let n = + Base_samplers.sample_in_interval rng_state ~range:cfg.sampler.set_size + in + let keys = adversarial_ints rng_state cfg n in + let map = + List.fold_left + (fun map i -> Script_map.update i (Some (Some ())) map) + (Script_map.empty int_cmp) + keys + in + let (module M) = map in + let key = + M.OPS.fold (fun k _ -> function None -> Some k | x -> x) M.boxed None + |> WithExceptions.Option.get ~loc:__LOC__ + in + let big_map = + raise_if_error + (Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + let big_map = + Script_ir_translator.empty_big_map int_cmp (unit_t ~annot:None) + in + Script_map.fold + (fun k v acc -> + acc >>=? fun (bm, ctxt_acc) -> + Script_ir_translator.big_map_update ctxt_acc k v bm) + map + (return (big_map, ctxt)) + >|= Environment.wrap_tzresult + >>=? fun (big_map, _) -> return big_map )) + in + (key, big_map) + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IEmpty_big_map + ~kinstr: + (IEmpty_big_map + ( kinfo_unit, + unit_cmp, + unit, + halt (big_map unit_cmp unit @$ unit @$ bot) )) + () + + let () = + (* + IBig_map_mem -> + (update context with gas) + (big_map_mem) -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IBig_map_mem + ~kinstr: + (IBig_map_mem + ( kinfo (int @$ big_map int_cmp unit @$ unit @$ bot), + halt (bool @$ unit @$ bot) )) + ~stack_sampler:(fun cfg rng_state () -> + let (key, map) = generate_big_map_and_key_in_map cfg rng_state in + (key, (map, ((), eos)))) + () + + let () = + (* + IBig_map_get -> + (big_map_get) -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IBig_map_get + ~kinstr: + (IBig_map_get + ( kinfo (int @$ big_map int_cmp unit @$ unit @$ bot), + halt (option unit @$ unit @$ bot) )) + ~intercept_stack: + (let map = Script_ir_translator.empty_big_map int_cmp unit in + (Alpha_context.Script_int.zero, (map, ((), eos)))) + ~stack_sampler:(fun cfg rng_state () -> + let (key, map) = generate_big_map_and_key_in_map cfg rng_state in + (key, (map, ((), eos)))) + () + + let () = + (* + IBig_map_update -> + (big_map_update) -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IBig_map_update + ~kinstr: + (IBig_map_update + ( kinfo (int @$ option unit @$ big_map int_cmp unit @$ bot), + halt (big_map int_cmp unit @$ bot) )) + ~intercept_stack: + (let map = Script_ir_translator.empty_big_map int_cmp unit in + (Alpha_context.Script_int.zero, (None, (map, eos)))) + ~stack_sampler:(fun cfg rng_state () -> + let (key, map) = generate_big_map_and_key_in_map cfg rng_state in + (key, (Some (), (map, eos)))) + () + + let () = + (* + IBig_map_get_and_update -> + (big_map_update) -> + (big_map_get) -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IBig_map_get_and_update + ~kinstr: + (IBig_map_get_and_update + ( kinfo (int @$ option unit @$ big_map int_cmp unit @$ bot), + halt (option unit @$ big_map int_cmp unit @$ bot) )) + ~intercept_stack: + (let map = Script_ir_translator.empty_big_map int_cmp unit in + (Alpha_context.Script_int.zero, (None, (map, eos)))) + ~stack_sampler:(fun cfg rng_state () -> + let (key, map) = generate_big_map_and_key_in_map cfg rng_state in + (key, (Some (), (map, eos)))) + () + end + + module Strings = struct + open Alpha_context.Script_string + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IConcat_string + ~intercept_stack:(Script_list.empty, eos) + ~kinstr: + (IConcat_string (kinfo (list string @$ bot), halt (string @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IConcat_string_pair + ~intercept_stack:(empty, (empty, eos)) + ~kinstr: + (IConcat_string_pair + (kinfo (string @$ string @$ bot), halt (string @$ bot))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_ISlice_string + ~kinstr: + (ISlice_string + (kinfo (nat @$ nat @$ string @$ bot), halt (option string @$ bot))) + ~intercept_stack: + (let z = Alpha_context.Script_int.zero_n in + (z, (z, (empty, eos)))) + ~stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = make_default_samplers cfg.sampler in + fun () -> + let string = + Samplers.Random_value.value + Script_typed_ir.(string_t ~annot:None) + rng_state + in + let len = nat_of_positive_int (length string) in + (* worst case: offset = 0 *) + (nat_of_positive_int 0, (len, (string, eos)))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IString_size + ~kinstr:(IString_size (kinfo (string @$ bot), halt (nat @$ bot))) + () + end + + module Bytes = struct + (* Copy of [String] modulo renaming string to bytes. *) + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IConcat_bytes + ~intercept_stack:(Script_list.empty, eos) + ~kinstr:(IConcat_bytes (kinfo (list bytes @$ bot), halt (bytes @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IConcat_bytes_pair + ~intercept_stack:(Bytes.empty, (Bytes.empty, eos)) + ~kinstr: + (IConcat_bytes_pair + (kinfo (bytes @$ bytes @$ bot), halt (bytes @$ bot))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_ISlice_bytes + ~kinstr: + (ISlice_bytes + (kinfo (nat @$ nat @$ bytes @$ bot), halt (option bytes @$ bot))) + ~intercept_stack: + (let z = Alpha_context.Script_int.zero_n in + (z, (z, (Bytes.empty, eos)))) + ~stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = make_default_samplers cfg.sampler in + fun () -> + let bytes = + Samplers.Random_value.value + Script_typed_ir.(bytes_t ~annot:None) + rng_state + in + let len = nat_of_positive_int (Bytes.length bytes) in + (* worst case: offset = 0 *) + (nat_of_positive_int 0, (len, (bytes, eos)))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IBytes_size + ~kinstr:(IBytes_size (kinfo (bytes @$ bot), halt (nat @$ bot))) + () + end + + module Timestamps = struct + let zero_timestamp = Alpha_context.Script_timestamp.of_zint Z.zero + + let zero_int = Alpha_context.Script_int.zero + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAdd_seconds_to_timestamp + ~intercept_stack:(zero_int, (zero_timestamp, eos)) + ~kinstr: + (IAdd_seconds_to_timestamp + (kinfo (int @$ timestamp @$ bot), halt (timestamp @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAdd_timestamp_to_seconds + ~intercept_stack:(zero_timestamp, (zero_int, eos)) + ~kinstr: + (IAdd_timestamp_to_seconds + (kinfo (timestamp @$ int @$ bot), halt (timestamp @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISub_timestamp_seconds + ~intercept_stack:(zero_timestamp, (zero_int, eos)) + ~kinstr: + (ISub_timestamp_seconds + (kinfo (timestamp @$ int @$ bot), halt (timestamp @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IDiff_timestamps + ~intercept_stack:(zero_timestamp, (zero_timestamp, eos)) + ~kinstr: + (IDiff_timestamps + (kinfo (timestamp @$ timestamp @$ bot), halt (int @$ bot))) + () + end + + module Tez = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAdd_tez + ~kinstr:(IAdd_tez (kinfo (mutez @$ mutez @$ bot), halt (mutez @$ bot))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_ISub_tez + ~kinstr: + (ISub_tez (kinfo (mutez @$ mutez @$ bot), halt (option mutez @$ bot))) + ~stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = + make_default_samplers cfg.Default_config.sampler + in + fun () -> + let a = Samplers.Random_value.value mutez rng_state in + let b = + match Alpha_context.Tez.(a /? 2L) with + | Error _ -> assert false + | Ok x -> x + in + (a, (b, eos))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_ISub_tez_legacy + ~kinstr: + (ISub_tez_legacy (kinfo (mutez @$ mutez @$ bot), halt (mutez @$ bot))) + ~stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = + make_default_samplers cfg.Default_config.sampler + in + fun () -> + let a = Samplers.Random_value.value mutez rng_state in + let b = + match Alpha_context.Tez.(a /? 2L) with + | Error _ -> assert false + | Ok x -> x + in + (a, (b, eos))) + () + + let sample_tez_nat (module Samplers : Michelson_samplers.S) rng_state = + let mutez = Samplers.Random_value.value mutez rng_state in + let mutez_int64 = Alpha_context.Tez.to_mutez mutez in + let int64 = Int64.(div max_int (mul mutez_int64 2L)) in + let nat = + match Alpha_context.Script_int.(is_nat (of_int64 int64)) with + | None -> assert false + | Some nat -> nat + in + (mutez, nat) + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IMul_teznat + ~kinstr:(IMul_teznat (kinfo (mutez @$ nat @$ bot), halt (mutez @$ bot))) + ~stack_sampler:(fun cfg rng_state -> + let (_, samplers) = make_default_samplers cfg.sampler in + fun () -> + let (mutez, nat) = sample_tez_nat samplers rng_state in + (mutez, (nat, eos))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IMul_nattez + ~kinstr:(IMul_nattez (kinfo (nat @$ mutez @$ bot), halt (mutez @$ bot))) + ~stack_sampler:(fun cfg rng_state -> + let (_, samplers) = make_default_samplers cfg.sampler in + fun () -> + let (mutez, nat) = sample_tez_nat samplers rng_state in + (nat, (mutez, eos))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IEdiv_teznat + ~intercept_stack: + (Alpha_context.Tez.zero, (Alpha_context.Script_int.zero_n, eos)) + ~kinstr: + (IEdiv_teznat + ( kinfo (mutez @$ nat @$ bot), + halt (option (pair mutez mutez) @$ bot) )) + ~stack_sampler:(fun cfg rng_state -> + let (_, samplers) = make_default_samplers cfg.sampler in + fun () -> + let (mutez, nat) = sample_tez_nat samplers rng_state in + (mutez, (nat, eos))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IEdiv_tez + ~intercept_stack:(Alpha_context.Tez.zero, (Alpha_context.Tez.zero, eos)) + ~kinstr: + (IEdiv_tez + ( kinfo (mutez @$ mutez @$ bot), + halt (option (pair nat mutez) @$ bot) )) + () + end + + module Booleans = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_IOr + ~kinstr:(IOr (kinfo (bool @$ bool @$ bot), halt (bool @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAnd + ~kinstr:(IAnd (kinfo (bool @$ bool @$ bot), halt (bool @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IXor + ~kinstr:(IXor (kinfo (bool @$ bool @$ bot), halt (bool @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_INot + ~kinstr:(INot (kinfo (bool @$ bot), halt (bool @$ bot))) + () + end + + module Integers = struct + let zero = Alpha_context.Script_int.zero + + let zero_n = Alpha_context.Script_int.zero_n + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IIs_nat + ~intercept_stack:(zero, eos) + ~kinstr:(IIs_nat (kinfo (int @$ bot), halt (option nat @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_INeg + ~intercept_stack:(zero, eos) + ~kinstr:(INeg (kinfo (int @$ bot), halt (int @$ bot))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IAbs_int + ~kinstr:(IAbs_int (kinfo (int @$ bot), halt (nat @$ bot))) + ~intercept_stack:(zero, eos) + ~stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = make_default_samplers cfg.sampler in + fun () -> + let x = Samplers.Michelson_base.nat rng_state in + let neg_x = Alpha_context.Script_int.neg x in + (neg_x, eos)) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IInt_nat + ~intercept_stack:(zero_n, eos) + ~kinstr:(IInt_nat (kinfo (nat @$ bot), halt (int @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAdd_int + ~intercept_stack:(zero, (zero, eos)) + ~kinstr:(IAdd_int (kinfo (int @$ int @$ bot), halt (int @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAdd_nat + ~intercept_stack:(zero_n, (zero_n, eos)) + ~kinstr:(IAdd_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISub_int + ~intercept_stack:(zero, (zero, eos)) + ~kinstr:(ISub_int (kinfo (int @$ int @$ bot), halt (int @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IMul_int + ~intercept_stack:(zero, (zero, eos)) + ~kinstr:(IMul_int (kinfo (int @$ int @$ bot), halt (int @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IMul_nat + ~intercept_stack:(zero_n, (zero, eos)) + ~kinstr:(IMul_nat (kinfo (nat @$ int @$ bot), halt (int @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IEdiv_int + ~intercept_stack:(zero, (zero, eos)) + ~kinstr: + (IEdiv_int + (kinfo (int @$ int @$ bot), halt (option (pair int nat) @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IEdiv_nat + ~intercept_stack:(zero_n, (zero, eos)) + ~kinstr: + (IEdiv_nat + (kinfo (nat @$ int @$ bot), halt (option (pair int nat) @$ bot))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_ILsl_nat + ~intercept_stack:(zero_n, (zero_n, eos)) + ~kinstr:(ILsl_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) + ~stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = make_default_samplers cfg.sampler in + fun () -> + let x = Samplers.Michelson_base.nat rng_state in + (* shift must be in [0;256]: 1 byte max *) + let shift = + Script_int_repr.(abs (of_int (Random.State.int rng_state 256))) + in + (x, (shift, eos))) + () + + let () = + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_ILsr_nat + ~intercept_stack:(zero_n, (zero_n, eos)) + ~kinstr:(ILsr_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) + ~stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = make_default_samplers cfg.sampler in + fun () -> + let x = Samplers.Michelson_base.nat rng_state in + (* shift must be in [0;256]: 1 byte max *) + let shift = + Script_int_repr.(abs (of_int (Random.State.int rng_state 256))) + in + (x, (shift, eos))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IOr_nat + ~intercept_stack:(zero_n, (zero_n, eos)) + ~kinstr:(IOr_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAnd_nat + ~intercept_stack:(zero_n, (zero_n, eos)) + ~kinstr:(IAnd_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAnd_int_nat + ~intercept_stack:(zero, (zero_n, eos)) + ~kinstr:(IAnd_int_nat (kinfo (int @$ nat @$ bot), halt (nat @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IXor_nat + ~intercept_stack:(zero_n, (zero_n, eos)) + ~kinstr:(IXor_nat (kinfo (nat @$ nat @$ bot), halt (nat @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_INot_int + ~intercept_stack:(zero, eos) + ~kinstr:(INot_int (kinfo (int @$ bot), halt (int @$ bot))) + () + end + + module Control = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_IIf + ~kinstr: + (IIf + { + kinfo = kinfo (bool @$ unit @$ bot); + branch_if_true = halt_unit; + branch_if_false = halt_unit; + k = halt_unit; + }) + () + + let () = + (* + ILoop -> + either + - IHalt (false on top of stack) + - IConst false ; IHalt (true on top of stack) + *) + let push_false = IConst (kinfo_unit, false, halt (bool @$ unit @$ bot)) in + simple_benchmark + ~name:Interpreter_workload.N_ILoop + ~kinstr:(ILoop (kinfo (bool @$ unit @$ bot), push_false, halt_unit)) + () + + let () = + (* + ILoop_left -> + ICons_right -> + IHalt + *) + let cons_r = ICons_right (kinfo_unit, halt (union unit unit @$ bot)) in + simple_benchmark + ~name:Interpreter_workload.N_ILoop_left + ~kinstr:(ILoop_left (kinfo (union unit unit @$ bot), cons_r, halt_unit)) + () + + let () = + (* + IDip -> + IHalt -> + IConst -> + IHalt + *) + simple_benchmark + ~name:Interpreter_workload.N_IDip + ~kinstr:(IDip (kinfo (unit @$ unit @$ bot), halt_unit, halt_unitunit)) + () + + let dummy_lambda = + let open Script_typed_ir in + let descr = + {kloc = 0; kbef = unit @$ bot; kaft = unit @$ bot; kinstr = halt_unit} + in + Lam (descr, Micheline.Int (0, Z.zero)) + + let () = + (* + IExec -> + (switch to in-context gas-counting) -> + interp lambda code -> + IHalt + *) + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IExec + ~kinstr:(IExec (kinfo (unit @$ lambda unit unit @$ bot), halt_unit)) + ~stack_sampler:(fun _cfg _rng_state () -> ((), (dummy_lambda, eos))) + () + + let () = + (* + IApply -> + unparse unit -> + unparse unit_ty -> + construct term -> + IHalt + *) + let code = + let open Script_typed_ir in + let descr = + { + kloc = 0; + kbef = pair unit unit @$ bot; + kaft = unit @$ bot; + kinstr = ICdr (kinfo (pair unit unit @$ bot), halt_unit); + } + in + Lam (descr, Micheline.Int (0, Z.zero)) + in + simple_benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IApply + ~kinstr: + (IApply + ( kinfo (unit @$ lambda (pair unit unit) unit @$ bot), + unit, + halt (lambda unit unit @$ bot) )) + ~stack_sampler:(fun _cfg _rng_state () -> ((), (code, eos))) + () + + let () = + (* + ILambda -> + IHalt + *) + simple_benchmark + ~name:Interpreter_workload.N_ILambda + ~kinstr: + (ILambda + (kinfo_unit, dummy_lambda, halt (lambda unit unit @$ unit @$ bot))) + () + + let () = + (* + IFailwith -> + (unparse_data Unit) -> + (strip_locations) -> + fail + *) + simple_benchmark + ~name:Interpreter_workload.N_IFailwith + ~amplification:100 + ~kinstr:(IFailwith (kinfo_unit, 0, unit)) + () + end + + module Comparison = struct + let () = + benchmark + ~name:Interpreter_workload.N_ICompare + ~kinstr_and_stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = make_default_samplers cfg.sampler in + fun () -> + let size = + Base_samplers.sample_in_interval + rng_state + ~range:cfg.compare.type_size + in + let (Script_ir_translator.Ex_comparable_ty cmp_ty) = + Samplers.Random_type.m_comparable_type ~size rng_state + in + let ty = Script_ir_translator.ty_of_comparable_ty cmp_ty in + let value = Samplers.Random_value.comparable cmp_ty rng_state in + let kinstr = + ICompare (kinfo (ty @$ ty @$ bot), cmp_ty, halt (int @$ bot)) + in + Ex_stack_and_kinstr {stack = (value, (value, eos)); kinstr}) + () + end + + module Comparators = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_IEq + ~kinstr:(IEq (kinfo (int @$ bot), halt (bool @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_INeq + ~kinstr:(INeq (kinfo (int @$ bot), halt (bool @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ILt + ~kinstr:(ILt (kinfo (int @$ bot), halt (bool @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IGt + ~kinstr:(IGt (kinfo (int @$ bot), halt (bool @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ILe + ~kinstr:(ILe (kinfo (int @$ bot), halt (bool @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IGe + ~kinstr:(IGe (kinfo (int @$ bot), halt (bool @$ bot))) + () + end + + module Proto = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAddress + ~kinstr:(IAddress (kinfo (contract unit @$ bot), halt (address @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IContract + ~kinstr: + (IContract + ( kinfo (address @$ bot), + unit, + "default", + halt (option (contract unit) @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ITransfer_tokens + ~kinstr: + (ITransfer_tokens + ( kinfo (unit @$ mutez @$ contract unit @$ bot), + halt (operation @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IImplicit_account + ~kinstr: + (IImplicit_account + (kinfo (key_hash @$ bot), halt (contract unit @$ bot))) + () + + let () = + let lambda = + let open Script_typed_ir in + let descr = + { + kloc = 0; + kbef = pair unit unit @$ bot; + kaft = pair (list operation) unit @$ bot; + kinstr = + ICdr + ( kinfo (pair unit unit @$ bot), + INil + ( kinfo (unit @$ bot), + ICons_pair + ( kinfo (list operation @$ unit @$ bot), + IHalt (kinfo (pair (list operation) unit @$ bot)) ) ) + ); + } + in + Lam (descr, Micheline.Int (0, Z.zero)) + in + simple_benchmark + ~name:Interpreter_workload.N_ICreate_contract + ~kinstr: + (ICreate_contract + { + kinfo = kinfo (option key_hash @$ mutez @$ unit @$ bot); + storage_type = unit; + arg_type = unit; + lambda; + views = SMap.empty; + root_name = None; + k = halt (operation @$ address @$ bot); + }) + () + + let () = + let name = + match Protocol.Alpha_context.Script_string.of_string "view" with + | Ok s -> s + | Error _ -> assert false + in + simple_benchmark + ~name:Interpreter_workload.N_IView + ~kinstr: + (IView + ( kinfo (unit @$ address @$ bot), + View_signature {name; input_ty = unit; output_ty = unit}, + halt (option unit @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISet_delegate + ~kinstr: + (ISet_delegate + (kinfo (option key_hash @$ bot), halt (operation @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_INow + ~kinstr:(INow (kinfo (unit @$ bot), halt (timestamp @$ unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IBalance + ~kinstr:(IBalance (kinfo (unit @$ bot), halt (mutez @$ unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ILevel + ~kinstr:(ILevel (kinfo (unit @$ bot), halt (nat @$ unit @$ bot))) + () + + let check_signature (algo : Signature.algo) ~for_intercept = + let name = + match algo with + | Signature.Ed25519 -> Interpreter_workload.N_ICheck_signature_ed25519 + | Signature.Secp256k1 -> + Interpreter_workload.N_ICheck_signature_secp256k1 + | Signature.P256 -> Interpreter_workload.N_ICheck_signature_p256 + in + benchmark_with_stack_sampler + ~intercept:for_intercept + ~name + ~kinstr: + (ICheck_signature + ( kinfo (public_key @$ signature @$ bytes @$ bot), + halt (bool @$ bot) )) + ~stack_sampler:(fun cfg rng_state -> + let ((module Crypto_samplers), (module Samplers)) = + make_default_samplers ~algo:(`Algo algo) cfg.Default_config.sampler + in + fun () -> + let (_pkh, pk, sk) = Crypto_samplers.all rng_state in + let unsigned_message = + if for_intercept then Environment.Bytes.empty + else + Samplers.Random_value.value + Script_typed_ir.(bytes_t ~annot:None) + rng_state + in + let signed_message = Signature.sign sk unsigned_message in + (pk, (signed_message, (unsigned_message, eos)))) + () + + let check_signature algo = + check_signature algo ~for_intercept:true ; + check_signature algo ~for_intercept:false + + let () = check_signature Signature.Ed25519 + + let () = check_signature Signature.Secp256k1 + + let () = check_signature Signature.P256 + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IHash_key + ~kinstr:(IHash_key (kinfo (public_key @$ bot), halt (key_hash @$ bot))) + () + + let () = + benchmark + ~name:Interpreter_workload.N_IPack + ~kinstr_and_stack_sampler:(fun _cfg _rng_state -> + let kinstr = IPack (kinfo (unit @$ bot), unit, halt (bytes @$ bot)) in + fun () -> Ex_stack_and_kinstr {stack = ((), eos); kinstr}) + () + + let () = + benchmark + ~name:Interpreter_workload.N_IUnpack + ~kinstr_and_stack_sampler:(fun _cfg rng_state -> + let b = + raise_if_error + (Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + Script_ir_translator.pack_data ctxt unit () + >|= Environment.wrap_tzresult + >>=? fun (bytes, _) -> return bytes )) + in + let kinstr = + IUnpack (kinfo (bytes @$ bot), unit, halt (option unit @$ bot)) + in + fun () -> Ex_stack_and_kinstr {stack = (b, eos); kinstr}) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IBlake2b + ~intercept_stack:(Environment.Bytes.empty, eos) + ~kinstr:(IBlake2b (kinfo (bytes @$ bot), halt (bytes @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISha256 + ~intercept_stack:(Environment.Bytes.empty, eos) + ~kinstr:(ISha256 (kinfo (bytes @$ bot), halt (bytes @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISha512 + ~intercept_stack:(Environment.Bytes.empty, eos) + ~kinstr:(ISha512 (kinfo (bytes @$ bot), halt (bytes @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IKeccak + ~intercept_stack:(Environment.Bytes.empty, eos) + ~kinstr:(IKeccak (kinfo (bytes @$ bot), halt (bytes @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISha3 + ~intercept_stack:(Environment.Bytes.empty, eos) + ~kinstr:(ISha3 (kinfo (bytes @$ bot), halt (bytes @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISource + ~kinstr:(ISource (kinfo (unit @$ bot), halt (address @$ unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISender + ~kinstr:(ISender (kinfo (unit @$ bot), halt (address @$ unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISelf + ~kinstr: + (ISelf + ( kinfo (unit @$ bot), + unit, + "default", + halt (contract unit @$ unit @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ISelf_address + ~kinstr: + (ISelf_address (kinfo (unit @$ bot), halt (address @$ unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAmount + ~kinstr:(IAmount (kinfo (unit @$ bot), halt (mutez @$ unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IChainId + ~kinstr:(IChainId (kinfo (unit @$ bot), halt (chain_id @$ unit @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IVoting_power + ~kinstr:(IVoting_power (kinfo (key_hash @$ bot), halt (nat @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_ITotal_voting_power + ~kinstr: + (ITotal_voting_power (kinfo (unit @$ bot), halt (nat @$ unit @$ bot))) + () + end + + module Sapling = struct + let () = + let memo_size = + match Alpha_context.Sapling.Memo_size.parse_z Z.zero with + | Error _ -> assert false + | Ok sz -> sz + in + simple_benchmark + ~name:Interpreter_workload.N_ISapling_empty_state + ~kinstr: + (ISapling_empty_state + ( kinfo (unit @$ bot), + memo_size, + halt (sapling_state memo_size @$ unit @$ bot) )) + () + + let () = + (* Note that memo_size is hardcoded to 0 in module [Sapling_generation]. *) + let memo_size = + match Alpha_context.Sapling.Memo_size.parse_z Z.zero with + | Error _ -> assert false + | Ok sz -> sz + in + let (info, name) = + info_and_name ~intercept:false "ISapling_verify_update" + in + let module B : Benchmark.S = struct + let name = name + + let info = info + + include Default_config + include Default_boilerplate + + let models = + Interpreter_model.make_model + (Some (Instr_name Interpreter_workload.N_ISapling_verify_update)) + + let kinstr = + let spl_state = sapling_state memo_size in + let spl_tx = sapling_transaction memo_size in + ISapling_verify_update + ( kinfo (spl_tx @$ spl_state @$ bot), + halt (option (pair int spl_state) @$ bot) ) + + let prepare_sapling_execution_environment sapling_forge_rng_seed + sapling_transition = + let sapling_forge_rng_state = + Random.State.make + @@ Option.fold + ~none:Sapling_generation.shared_seed + ~some:(fun seed -> [|seed|]) + sapling_forge_rng_seed + in + (* Prepare context. We _must_ reuse the same seed as the one used for + the context when generating the transactions. This ensures that the + bootstrap account match and that the transactions can be replayed. *) + let result = + Lwt_main.run + ( Execution_context.make ~rng_state:sapling_forge_rng_state + >>=? fun (ctxt, step_constants) -> + (* Prepare a sapling state able to replay the transition. *) + Sapling_generation.prepare_seeded_state sapling_transition ctxt + >>=? fun (_, _, _, _, ctxt, state_id) -> + Alpha_context.Sapling.(state_from_id ctxt (Id.parse_z state_id)) + >|= Environment.wrap_tzresult + >>=? fun (state, ctxt) -> return (ctxt, state, step_constants) + ) + in + match result with + | Ok r -> r + | Error _ -> + Format.eprintf + "Error in prepare_sapling_execution_environment, aborting@." ; + Stdlib.failwith "prepare_sapling_execution_environment" + + let create_benchmarks ~rng_state ~bench_num (config : config) = + ignore rng_state ; + match config.sapling with + | {sapling_txs_file; seed} -> + let transitions = + Sapling_generation.load ~filename:sapling_txs_file + in + let length = List.length transitions in + if length < bench_num then + Format.eprintf + "ISapling_verify_update: warning, only %d available \ + transactions (requested %d)@." + length + bench_num ; + let transitions = + List.take_n (min bench_num length) transitions + in + List.map + (fun (_, transition) () -> + let (ctxt, state, step_constants) = + prepare_sapling_execution_environment seed transition + in + let stack_instr = + Ex_stack_and_kinstr + {stack = (transition.sapling_tx, (state, eos)); kinstr} + in + benchmark_from_kinstr_and_stack + ctxt + step_constants + stack_instr) + transitions + end in + Registration_helpers.register (module B) + end + + (* when benchmarking, compile bls12-381-unix without ADX, see + https://gitlab.com/dannywillems/ocaml-bls12-381/-/blob/71d0b4d467fbfaa6452d702fcc408d7a70916a80/README.md#install + *) + module Bls12_381 = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAdd_bls12_381_g1 + ~kinstr: + (IAdd_bls12_381_g1 + ( kinfo (bls12_381_g1 @$ bls12_381_g1 @$ bot), + halt (bls12_381_g1 @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAdd_bls12_381_g2 + ~kinstr: + (IAdd_bls12_381_g2 + ( kinfo (bls12_381_g2 @$ bls12_381_g2 @$ bot), + halt (bls12_381_g2 @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IAdd_bls12_381_fr + ~kinstr: + (IAdd_bls12_381_fr + ( kinfo (bls12_381_fr @$ bls12_381_fr @$ bot), + halt (bls12_381_fr @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IMul_bls12_381_g1 + ~kinstr: + (IMul_bls12_381_g1 + ( kinfo (bls12_381_g1 @$ bls12_381_fr @$ bot), + halt (bls12_381_g1 @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IMul_bls12_381_g2 + ~kinstr: + (IMul_bls12_381_g2 + ( kinfo (bls12_381_g2 @$ bls12_381_fr @$ bot), + halt (bls12_381_g2 @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IMul_bls12_381_fr + ~kinstr: + (IMul_bls12_381_fr + ( kinfo (bls12_381_fr @$ bls12_381_fr @$ bot), + halt (bls12_381_fr @$ bot) )) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IMul_bls12_381_z_fr + ~kinstr: + (IMul_bls12_381_z_fr + (kinfo (bls12_381_fr @$ int @$ bot), halt (bls12_381_fr @$ bot))) + () + + let () = + benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IMul_bls12_381_z_fr + ~intercept:true + ~kinstr: + (IMul_bls12_381_z_fr + (kinfo (bls12_381_fr @$ int @$ bot), halt (bls12_381_fr @$ bot))) + ~stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = make_default_samplers cfg.sampler in + let fr_sampler = Samplers.Random_value.value bls12_381_fr in + let zero = Alpha_context.Script_int.zero in + fun () -> (fr_sampler rng_state, (zero, eos))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IMul_bls12_381_fr_z + ~kinstr: + (IMul_bls12_381_fr_z + (kinfo (int @$ bls12_381_fr @$ bot), halt (bls12_381_fr @$ bot))) + () + + let () = + benchmark_with_stack_sampler + ~name:Interpreter_workload.N_IMul_bls12_381_fr_z + ~intercept:true + ~kinstr: + (IMul_bls12_381_fr_z + (kinfo (int @$ bls12_381_fr @$ bot), halt (bls12_381_fr @$ bot))) + ~stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = make_default_samplers cfg.sampler in + let fr_sampler = Samplers.Random_value.value bls12_381_fr in + let zero = Alpha_context.Script_int.zero in + fun () -> (zero, (fr_sampler rng_state, eos))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IInt_bls12_381_z_fr + ~kinstr: + (IInt_bls12_381_fr (kinfo (bls12_381_fr @$ bot), halt (int @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_INeg_bls12_381_g1 + ~kinstr: + (INeg_bls12_381_g1 + (kinfo (bls12_381_g1 @$ bot), halt (bls12_381_g1 @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_INeg_bls12_381_g2 + ~kinstr: + (INeg_bls12_381_g2 + (kinfo (bls12_381_g2 @$ bot), halt (bls12_381_g2 @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_INeg_bls12_381_fr + ~kinstr: + (INeg_bls12_381_fr + (kinfo (bls12_381_fr @$ bot), halt (bls12_381_fr @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IPairing_check_bls12_381 + ~kinstr: + (IPairing_check_bls12_381 + ( kinfo (list (pair bls12_381_g1 bls12_381_g2) @$ bot), + halt (bool @$ bot) )) + () + end + + module Tickets = struct + let () = + simple_benchmark + ~name:Interpreter_workload.N_ITicket + ~kinstr: + (ITicket (kinfo (unit @$ nat @$ bot), halt (ticket unit_cmp @$ bot))) + () + + let () = + simple_benchmark + ~name:Interpreter_workload.N_IRead_ticket + ~kinstr: + (IRead_ticket + ( kinfo (ticket unit_cmp @$ bot), + halt (pair address (pair unit nat) @$ ticket unit_cmp @$ bot) )) + () + + let split_ticket_instr = + ISplit_ticket + ( kinfo (ticket unit_cmp @$ pair nat nat @$ bot), + halt (option (pair (ticket unit_cmp) (ticket unit_cmp)) @$ bot) ) + + let () = + let zero = Alpha_context.Script_int.zero_n in + let ticket = + { + ticketer = + Alpha_context.Contract.implicit_contract + Environment.Signature.Public_key_hash.zero; + contents = (); + amount = zero; + } + in + benchmark_with_fixed_stack + ~intercept:true + ~name:Interpreter_workload.N_ISplit_ticket + ~stack:(ticket, ((zero, zero), eos)) + ~kinstr:split_ticket_instr + () + + let () = + benchmark + ~name:Interpreter_workload.N_ISplit_ticket + ~kinstr_and_stack_sampler:(fun config rng_state -> + let (_, (module Samplers)) = + make_default_samplers config.Default_config.sampler + in + fun () -> + let half_amount = Samplers.Random_value.value nat rng_state in + let amount = + Alpha_context.Script_int.add_n half_amount half_amount + in + let ticket = + Samplers.Random_value.value (ticket unit_cmp) rng_state + in + let ticket = {ticket with amount} in + Ex_stack_and_kinstr + { + stack = (ticket, ((half_amount, half_amount), eos)); + kinstr = split_ticket_instr; + }) + () + + let join_tickets_instr = + IJoin_tickets + ( kinfo (pair (ticket string_cmp) (ticket string_cmp) @$ bot), + string_cmp, + halt (option (ticket string_cmp) @$ bot) ) + + let () = + benchmark + ~intercept:true + ~name:Interpreter_workload.N_IJoin_tickets + ~kinstr_and_stack_sampler:(fun config rng_state -> + let (_, (module Samplers)) = + make_default_samplers config.Default_config.sampler + in + fun () -> + let ticket = + Samplers.Random_value.value (ticket string_cmp) rng_state + in + let ticket = + { + ticket with + contents = Alpha_context.Script_string.empty; + amount = Script_int_repr.zero_n; + } + in + Ex_stack_and_kinstr + {stack = ((ticket, ticket), eos); kinstr = join_tickets_instr}) + () + + let () = + benchmark + ~name:Interpreter_workload.N_IJoin_tickets + ~kinstr_and_stack_sampler:(fun config rng_state -> + let (_, (module Samplers)) = + make_default_samplers config.Default_config.sampler + in + fun () -> + let ticket = + Samplers.Random_value.value (ticket string_cmp) rng_state + in + let alt_amount = Samplers.Random_value.value nat rng_state in + let ticket' = {ticket with amount = alt_amount} in + Ex_stack_and_kinstr + {stack = ((ticket, ticket'), eos); kinstr = join_tickets_instr}) + () + end + + module Timelock = struct + let name = Interpreter_workload.N_IOpen_chest + + let kinstr = + IOpen_chest + ( kinfo + (Michelson_types.chest_key @$ Michelson_types.chest @$ nat @$ bot), + halt (union bytes bool @$ bot) ) + + let resulting_stack chest chest_key time = + ( chest_key, + ( chest, + ( Script_int_repr.is_nat (Script_int_repr.of_int time) + |> WithExceptions.Option.get ~loc:"Timelock:gas benchmarks", + eos ) ) ) + + let () = + benchmark_with_stack_sampler + ~intercept:true + ~name + ~kinstr + ~stack_sampler:(fun _ rng_state () -> + let (chest, chest_key) = + Timelock.chest_sampler ~plaintext_size:1 ~time:0 ~rng_state + in + resulting_stack chest chest_key 0) + () + + let () = + benchmark_with_stack_sampler + ~name + ~kinstr + ~stack_sampler:(fun _ rng_state () -> + let log_time = + Base_samplers.sample_in_interval + ~range:{min = 0; max = 29} + rng_state + in + let time = Random.State.int rng_state (Int.shift_left 1 log_time) in + let plaintext_size = + Base_samplers.sample_in_interval + ~range:{min = 1; max = 10000} + rng_state + in + + let (chest, chest_key) = + Timelock.chest_sampler ~plaintext_size ~time ~rng_state + in + resulting_stack chest chest_key time) + () + end + + module Continuations = struct + let () = + (* + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KNil + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let cont = KNil in + let stack = eos in + fun () -> Ex_stack_and_cont {stack; cont}) + () + + let () = + (* + KCons -> step + KHalt -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KCons + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let cont = KCons (halt_unit, KNil) in + let stack = ((), eos) in + fun () -> Ex_stack_and_cont {stack; cont}) + () + + let () = + (* + KReturn -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KReturn + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let cont = KReturn (halt_unit, KNil) in + let stack = ((), eos) in + fun () -> Ex_stack_and_cont {stack; cont}) + () + + let () = + (* + KView_exit -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KView_exit + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let open Script_typed_ir in + let open Alpha_context in + let zero = + Contract.implicit_contract Signature.Public_key_hash.zero + in + let step_constants = + { + source = zero; + payer = zero; + self = zero; + amount = Tez.zero; + chain_id = Chain_id.zero; + now = Script_timestamp.of_zint Z.zero; + level = Script_int.zero_n; + } + in + let cont = KView_exit (step_constants, KNil) in + let stack = ((), eos) in + fun () -> Ex_stack_and_cont {stack; cont}) + () + + let () = + (* + KLoop_in -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KLoop_in + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let cont = + KLoop_in + (IConst (kinfo_unit, false, halt (bool @$ unit @$ bot)), KNil) + in + let stack = (false, ((), eos)) in + fun () -> Ex_stack_and_cont {stack; cont}) + () + + let () = + (* + KLoop_in_left -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KLoop_in_left + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let cont = + KLoop_in_left + (ICons_right (kinfo_unit, halt (union unit unit @$ bot)), KNil) + in + let stack = (R (), eos) in + fun () -> Ex_stack_and_cont {stack; cont}) + () + + let () = + (* + KUndip -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KUndip + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let cont = KUndip ((), KNil) in + let stack = eos in + fun () -> Ex_stack_and_cont {stack; cont}) + () + + let () = + (* + KIter (empty case) -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KIter + ~salt:"_empty" + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let cont = KIter (IDrop (kinfo_unitunit, halt_unit), [], KNil) in + let stack = ((), eos) in + fun () -> Ex_stack_and_cont {stack; cont}) + () + + let () = + (* + KIter (nonempty case) -> step + KDrop -> step + KHalt -> next + KIter (empty case) -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KIter + ~salt:"_nonempty" + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let cont = KIter (IDrop (kinfo_unitunit, halt_unit), [()], KNil) in + let stack = ((), eos) in + fun () -> Ex_stack_and_cont {stack; cont}) + () + + let () = + (* + KList_enter_body ([()], bot accumulator case) -> step + KHalt -> next + KList_exit_body ([], []) -> + KList_enter_body ([], [()] -> + List.rev singleton + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KList_enter_body + ~salt:"_singleton_list" + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let kbody = halt_unitunit in + fun () -> + let cont = KList_enter_body (kbody, [()], [], 1, KNil) in + Ex_stack_and_cont {stack = ((), eos); cont}) + () + + let () = + (* + KList_enter_body (empty list, nonempty accumulator case) -> + {List.rev n elements} -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KList_enter_body + ~salt:"_terminal" + ~cont_and_stack_sampler:(fun cfg rng_state -> + let (_, (module Samplers)) = make_default_samplers cfg.sampler in + let kbody = halt_unitunit in + fun () -> + let ys = Samplers.Random_value.value (list unit) rng_state in + let cont = + KList_enter_body (kbody, [], ys.elements, ys.length, KNil) + in + Ex_stack_and_cont {stack = ((), eos); cont}) + () + + let () = + (* + KList_enter_body (empty list, bot accumulator case) -> + {List.rev singleton} -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~intercept:true + ~name:Interpreter_workload.N_KList_enter_body + ~salt:"_terminal" + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let kbody = halt_unitunit in + fun () -> + let cont = KList_enter_body (kbody, [], [], 1, KNil) in + Ex_stack_and_cont {stack = ((), eos); cont}) + () + + let () = + (* + KList_exit_body (empty list) -> next + KList_enter_body -> + {List.rev 1 element} -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~intercept:true + ~name:Interpreter_workload.N_KList_exit_body + ~salt:"_terminal" + ~cont_and_stack_sampler:(fun _cfg _rng_state -> + let kbody = halt_unitunit in + let cont = KList_exit_body (kbody, [], [], 1, KNil) in + fun () -> Ex_stack_and_cont {stack = ((), ((), eos)); cont}) + () + + let map_enter_body_code = + let kbody = ICdr (kinfo (pair int unit @$ unit @$ bot), halt_unitunit) in + fun accu -> KMap_enter_body (kbody, accu, Script_map.empty int_cmp, KNil) + + let () = + (* + KMap_enter_body (empty case) -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~salt:"_empty" + ~name:Interpreter_workload.N_KMap_enter_body + ~cont_and_stack_sampler:(fun _cfg _rng_state () -> + Ex_stack_and_cont {stack = ((), eos); cont = map_enter_body_code []}) + () + + let () = + (* + KMap_enter_body (singleton case) -> step + KCdr -> step + KHalt -> next + KMap_exit_body -> next + (map_update) + KMap_enter_body (empty case) -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~salt:"_singleton" + ~name:Interpreter_workload.N_KMap_enter_body + ~cont_and_stack_sampler:(fun _cfg _rng_state () -> + Ex_stack_and_cont + { + stack = ((), eos); + cont = map_enter_body_code [(Script_int_repr.zero, ())]; + }) + () + + let () = + (* + KMap_exit_body -> + (map_update) -> next + KMap_enter_body (empty case) -> next + KNil + *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KMap_exit_body + ~cont_and_stack_sampler:(fun cfg rng_state -> + let kbody = + ICdr (kinfo (pair int unit @$ unit @$ bot), halt_unitunit) + in + fun () -> + let (key, map) = Maps.generate_map_and_key_in_map cfg rng_state in + let cont = KMap_exit_body (kbody, [], map, key, KNil) in + Ex_stack_and_cont {stack = ((), ((), eos)); cont}) + () + + let () = + (* KMap_head -> KNil *) + continuation_benchmark + ~amplification:100 + ~name:Interpreter_workload.N_KMap_head + ~cont_and_stack_sampler:(fun _cfg _rng_state () -> + let cont = KMap_head (Option.some, KNil) in + Ex_stack_and_cont {stack = ((), ((), eos)); cont}) + () + end +end diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_model.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_model.ml new file mode 100644 index 000000000000..9231a9156768 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_model.ml @@ -0,0 +1,538 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* ------------------------------------------------------------------------- *) + +let trace_error expected given = + let open Interpreter_workload in + let exp = string_of_instr_or_cont expected in + let given = string_of_instr_or_cont given in + let msg = + Format.asprintf + "Interpreter_model: trace error, expected %s, given %s" + exp + given + in + Stdlib.failwith msg + +let arity_error instr expected given = + let open Interpreter_workload in + let s = string_of_instr_or_cont instr in + let msg = + Format.asprintf + "Interpreter_model: arity error (%s), expected %d, given %a" + s + expected + Interpreter_workload.pp_args + given + in + Stdlib.failwith msg + +(* ------------------------------------------------------------------------- *) + +let model_0 instr model = + let open Interpreter_workload in + Model.make + ~conv:(function + | {name; args = []} -> if name = instr then () else trace_error instr name + | {args; _} -> arity_error instr 0 args) + ~model + +let model_1 instr model = + let open Interpreter_workload in + Model.make + ~conv:(function + | {name; args = [{name = _; arg}]} -> + if name = instr then (arg, ()) else trace_error instr name + | {args; _} -> arity_error instr 1 args) + ~model + +let model_2 instr model = + let open Interpreter_workload in + Model.make + ~conv:(function + | {name; args = [{name = _; arg = x}; {name = _; arg = y}]} -> + if name = instr then (x, (y, ())) else trace_error instr name + | {args; _} -> arity_error instr 2 args) + ~model + +let model_3 instr model = + let open Interpreter_workload in + Model.make + ~conv:(function + | { + name; + args = [{name = _; arg = x}; {name = _; arg = y}; {name = _; arg = z}]; + } -> + if name = instr then (x, (y, (z, ()))) else trace_error instr name + | {args; _} -> arity_error instr 3 args) + ~model + +let model_4 instr model = + let open Interpreter_workload in + Model.make + ~conv:(function + | { + name; + args = + [ + {name = _; arg = w}; + {name = _; arg = x}; + {name = _; arg = y}; + {name = _; arg = z}; + ]; + } -> + if name = instr then (w, (x, (y, (z, ())))) + else trace_error instr name + | {args; _} -> arity_error instr 4 args) + ~model + +let fv = Free_variable.of_string + +let sf = Format.asprintf + +let division_cost name = + let const = fv (sf "%s_const" name) in + let coeff = fv (sf "%s_coeff" name) in + let module M = struct + type arg_type = int * (int * unit) + + module Def (X : Costlang.S) = struct + open X + + type model_type = size -> size -> size + + let arity = Model.arity_2 + + let model = + lam ~name:"size1" @@ fun size1 -> + lam ~name:"size2" @@ fun size2 -> + let_ ~name:"q" (size1 - size2) @@ fun q -> + (free ~name:coeff * if_ (lt size2 size1) (q * size2) (int 0)) + + free ~name:const + end + end in + (module M : Model.Model_impl with type arg_type = int * (int * unit)) + +let addlogadd name = + let const = fv (sf "%s_const" name) in + let coeff = fv (sf "%s_coeff" name) in + let module M = struct + type arg_type = int * (int * unit) + + module Def (X : Costlang.S) = struct + open X + + type model_type = size -> size -> size + + let arity = Model.arity_2 + + let model = + lam ~name:"size1" @@ fun size1 -> + lam ~name:"size2" @@ fun size2 -> + let_ ~name:"a" (size1 + size2) @@ fun a -> + (free ~name:coeff * (a * log2 (int 1 + a))) + free ~name:const + end + end in + (module M : Model.Model_impl with type arg_type = int * (int * unit)) + +(* Some instructions are oveloaded (eg COMPARE). In order to generate distinct + models at different types, we must specialize these models. The [specialization] + parameter acts as a mangling scheme to produce distinct models. *) +let name_of_instr_or_cont ?specialization instr_or_cont = + let spec = Option.fold ~none:"" ~some:(fun s -> "_" ^ s) specialization in + Interpreter_workload.string_of_instr_or_cont instr_or_cont ^ spec + +module Models = struct + let const1_model name = + (* For constant-time instructions *) + Model.unknown_const1 ~const:(fv (sf "%s_const" name)) + + let affine_model name = + (* For instructions with cost function + [\lambda size. const + coeff * size] *) + Model.affine + ~intercept:(fv (sf "%s_const" name)) + ~coeff:(fv (sf "%s_coeff" name)) + + let break_model name break = + Model.breakdown + ~coeff1:(fv (sf "%s_coeff1" name)) + ~coeff2:(fv (sf "%s_coeff2" name)) + ~break + + let break_model_2 name break1 break2 = + Model.breakdown2 + ~coeff1:(fv (sf "%s_coeff1" name)) + ~coeff2:(fv (sf "%s_coeff2" name)) + ~coeff3:(fv (sf "%s_coeff3" name)) + ~break1 + ~break2 + + let break_model_2_const name break1 break2 = + Model.breakdown2_const + ~coeff1:(fv (sf "%s_coeff1" name)) + ~coeff2:(fv (sf "%s_coeff2" name)) + ~coeff3:(fv (sf "%s_coeff3" name)) + ~const:(fv (sf "%s_const" name)) + ~break1 + ~break2 + + let nlogm_model name = + (* For instructions with cost function + [\lambda size1. \lambda size2. const + coeff * size1 log2(size2)] *) + Model.nlogm + ~intercept:(fv (sf "%s_const" name)) + ~coeff:(fv (sf "%s_coeff" name)) + + let concat_model name = + Model.bilinear_affine + ~intercept:(fv (sf "%s_const" name)) + ~coeff1:(fv (sf "%s_total_bytes" name)) + ~coeff2:(fv (sf "%s_list_length" name)) + + let concat_pair_model name = + Model.linear_sum + ~intercept:(fv (sf "%s_const" name)) + ~coeff:(fv (sf "%s_coeff" name)) + + let linear_max_model name = + (* For instructions with cost function + [\lambda size1. \lambda size2. const + coeff * max(size1,size2)] *) + Model.linear_max + ~intercept:(fv (sf "%s_const" name)) + ~coeff:(fv (sf "%s_coeff" name)) + + let linear_min_model name = + (* For instructions with cost function + [\lambda size1. \lambda size2. const + coeff * min(size1,size2)] *) + Model.linear_min + ~intercept:(fv (sf "%s_const" name)) + ~coeff:(fv (sf "%s_coeff" name)) + + let pack_model name = + Model.trilinear + ~coeff1:(fv (sf "%s_micheline_nodes" name)) + ~coeff2:(fv (sf "%s_micheline_int_bytes" name)) + ~coeff3:(fv (sf "%s_micheline_string_bytes" name)) + + let split_ticket_model name = + let module M = struct + type arg_type = int * (int * unit) + + module Def (X : Costlang.S) = struct + open X + + type model_type = size -> size -> size + + let arity = Model.arity_2 + + let model = + lam ~name:"size1" @@ fun size1 -> + lam ~name:"size2" @@ fun size2 -> + free ~name:(fv (sf "%s_const" name)) + + (free ~name:(fv (sf "%s_add_coeff" name)) * max size1 size2) + + (free ~name:(fv (sf "%s_cmp_coeff" name)) * min size1 size2) + end + end in + (module M : Model.Model_impl with type arg_type = int * (int * unit)) + + let open_chest_model name = + let module M = struct + type arg_type = int * (int * unit) + + module Def (X : Costlang.S) = struct + open X + + type model_type = size -> size -> size + + let arity = Model.arity_2 + + let model = + lam ~name:"size1" @@ fun size1 -> + lam ~name:"size2" @@ fun size2 -> + free ~name:(fv (sf "%s_const" name)) + + (free ~name:(fv (sf "%s_log_time_coeff" name)) * size1) + + (free ~name:(fv (sf "%s_plaintext_coeff" name)) * size2) + end + end in + (module M : Model.Model_impl with type arg_type = int * (int * unit)) + + let verify_update_model name = + Model.bilinear_affine + ~intercept:(fv (sf "%s_const" name)) + ~coeff1:(fv (sf "%s_inputs" name)) + ~coeff2:(fv (sf "%s_ouputs" name)) + + let list_enter_body_model name = + let module M = struct + type arg_type = int * (int * unit) + + module Def (X : Costlang.S) = struct + open X + + type model_type = size -> size -> size + + let arity = Model.arity_2 + + let model = + lam ~name:"size_xs" @@ fun size_xs -> + lam ~name:"size_ys" @@ fun size_ys -> + if_ + (eq size_xs (int 0)) + (free ~name:(fv (sf "%s_const" name)) + + (free ~name:(fv (sf "%s_coeff" name)) * size_ys)) + (free ~name:(fv (sf "%s_iter" name))) + end + end in + (module M : Model.Model_impl with type arg_type = int * (int * unit)) + + let branching_model name = + let module M = struct + type arg_type = int * unit + + module Def (X : Costlang.S) = struct + open X + + type model_type = size -> size + + let arity = Model.arity_1 + + let model = + lam ~name:"size" @@ fun size -> + if_ + (eq size (int 0)) + (free ~name:(fv (sf "%s_empty" name))) + (free ~name:(fv (sf "%s_nonempty" name))) + end + end in + (module M : Model.Model_impl with type arg_type = int * unit) + + let join_tickets_model name = + let module M = struct + type arg_type = int * (int * (int * (int * unit))) + + module Def (X : Costlang.S) = struct + open X + + type model_type = size -> size -> size -> size -> size + + let arity = Model.Succ_arity Model.arity_3 + + let model = + lam ~name:"content_size_x" @@ fun content_size_x -> + lam ~name:"content_size_y" @@ fun content_size_y -> + lam ~name:"amount_size_x" @@ fun amount_size_x -> + lam ~name:"amount_size_y" @@ fun amount_size_y -> + free ~name:(fv (sf "%s_const" name)) + + free ~name:(fv (sf "%s_compare_coeff" name)) + * min content_size_x content_size_y + + free ~name:(fv (sf "%s_add_coeff" name)) + * max amount_size_x amount_size_y + end + end in + (module M : Model.Model_impl + with type arg_type = int * (int * (int * (int * unit)))) +end + +let ir_model ?specialization instr_or_cont = + let open Interpreter_workload in + let open Models in + let name = name_of_instr_or_cont ?specialization instr_or_cont in + match instr_or_cont with + | Instr_name instr -> ( + match instr with + | N_IDrop | N_IDup | N_ISwap | N_IConst | N_ICons_pair | N_ICar | N_ICdr + | N_ICons_some | N_ICons_none | N_IIf_none | N_IOpt_map | N_ILeft + | N_IRight | N_IIf_left | N_ICons_list | N_INil | N_IIf_cons + | N_IEmpty_set | N_IEmpty_map | N_IEmpty_big_map | N_IOr | N_IAnd | N_IXor + | N_INot | N_IIf | N_ILoop | N_ILoop_left | N_IDip | N_IExec | N_IView + | N_ILambda | N_IFailwith | N_IAddress | N_ICreate_contract + | N_ISet_delegate | N_INow | N_IBalance | N_IHash_key | N_IUnpack + | N_ISource | N_ISender | N_ISelf | N_IAmount | N_IChainId | N_ILevel + | N_ISelf_address | N_INever | N_IUnpair | N_IVoting_power + | N_ITotal_voting_power | N_IList_size | N_ISet_size | N_IMap_size + | N_ISapling_empty_state -> + model_0 instr_or_cont (const1_model name) + | N_ISet_mem | N_ISet_update | N_IMap_mem | N_IMap_get | N_IMap_update + | N_IBig_map_mem | N_IBig_map_get | N_IBig_map_update + | N_IMap_get_and_update | N_IBig_map_get_and_update -> + model_2 instr_or_cont (nlogm_model name) + | N_IConcat_string -> model_2 instr_or_cont (concat_model name) + | N_IConcat_string_pair -> model_2 instr_or_cont (concat_pair_model name) + | N_ISlice_string -> model_1 instr_or_cont (affine_model name) + | N_IString_size -> model_0 instr_or_cont (const1_model name) + | N_IConcat_bytes -> model_2 instr_or_cont (concat_model name) + | N_IConcat_bytes_pair -> model_2 instr_or_cont (concat_pair_model name) + | N_ISlice_bytes -> model_1 instr_or_cont (affine_model name) + | N_IBytes_size -> model_0 instr_or_cont (const1_model name) + | N_IAdd_seconds_to_timestamp | N_IAdd_timestamp_to_seconds + | N_ISub_timestamp_seconds | N_IDiff_timestamps -> + model_2 instr_or_cont (linear_max_model name) + | N_IAdd_tez | N_ISub_tez | N_ISub_tez_legacy | N_IEdiv_tez -> + model_0 instr_or_cont (const1_model name) + | N_IMul_teznat | N_IMul_nattez -> + model_1 instr_or_cont (affine_model name) + | N_IEdiv_teznat -> model_2 instr_or_cont (division_cost name) + | N_IIs_nat -> model_0 instr_or_cont (const1_model name) + | N_INeg -> model_1 instr_or_cont (affine_model name) + | N_IAbs_int -> model_1 instr_or_cont (affine_model name) + | N_IInt_nat -> model_0 instr_or_cont (const1_model name) + | N_IAdd_int -> model_2 instr_or_cont (linear_max_model name) + | N_IAdd_nat -> model_2 instr_or_cont (linear_max_model name) + | N_ISub_int -> model_2 instr_or_cont (linear_max_model name) + | N_IMul_int -> model_2 instr_or_cont (addlogadd name) + | N_IMul_nat -> model_2 instr_or_cont (addlogadd name) + | N_IEdiv_int -> model_2 instr_or_cont (division_cost name) + | N_IEdiv_nat -> model_2 instr_or_cont (division_cost name) + | N_ILsl_nat -> model_1 instr_or_cont (affine_model name) + | N_ILsr_nat -> model_1 instr_or_cont (affine_model name) + | N_IOr_nat -> model_2 instr_or_cont (linear_max_model name) + | N_IAnd_nat -> model_2 instr_or_cont (linear_min_model name) + | N_IAnd_int_nat -> model_2 instr_or_cont (linear_min_model name) + | N_IXor_nat -> model_2 instr_or_cont (linear_max_model name) + | N_INot_int -> model_1 instr_or_cont (affine_model name) + | N_ICompare -> model_2 instr_or_cont (linear_min_model name) + | N_IEq | N_INeq | N_ILt | N_IGt | N_ILe | N_IGe -> + model_0 instr_or_cont (const1_model name) + | N_IPack -> model_3 instr_or_cont (pack_model name) + | N_IBlake2b | N_ISha256 | N_ISha512 | N_IKeccak | N_ISha3 -> + model_1 instr_or_cont (affine_model name) + | N_ICheck_signature_ed25519 | N_ICheck_signature_secp256k1 + | N_ICheck_signature_p256 -> + model_1 instr_or_cont (affine_model name) + | N_IContract | N_ITransfer_tokens | N_IImplicit_account -> + model_0 instr_or_cont (const1_model name) + (* The following two instructions are expected to have an affine model. However, + we observe 3 affine parts, on [0;300], [300;400] and [400;\inf[. *) + | N_IDupN -> model_1 instr_or_cont (break_model_2 name 300 400) + | N_IDropN -> model_1 instr_or_cont (break_model_2_const name 300 400) + | N_IDig | N_IDug | N_IDipN -> model_1 instr_or_cont (affine_model name) + | N_IAdd_bls12_381_g1 | N_IAdd_bls12_381_g2 | N_IAdd_bls12_381_fr + | N_IMul_bls12_381_g1 | N_IMul_bls12_381_g2 | N_IMul_bls12_381_fr + | N_INeg_bls12_381_g1 | N_INeg_bls12_381_g2 | N_INeg_bls12_381_fr + | N_IInt_bls12_381_z_fr -> + model_0 instr_or_cont (const1_model name) + | N_IMul_bls12_381_fr_z | N_IMul_bls12_381_z_fr + | N_IPairing_check_bls12_381 -> + model_1 instr_or_cont (affine_model name) + | N_IComb_get | N_IComb | N_IComb_set | N_IUncomb -> + model_1 instr_or_cont (affine_model name) + | N_ITicket | N_IRead_ticket -> model_0 instr_or_cont (const1_model name) + | N_ISplit_ticket -> model_2 instr_or_cont (split_ticket_model name) + | N_IJoin_tickets -> model_4 instr_or_cont (join_tickets_model name) + | N_ISapling_verify_update -> + model_2 instr_or_cont (verify_update_model name) + | N_IList_map -> model_0 instr_or_cont (const1_model name) + | N_IList_iter -> model_0 instr_or_cont (const1_model name) + | N_IIter -> model_0 instr_or_cont (const1_model name) + | N_IMap_map -> model_1 instr_or_cont (affine_model name) + | N_IMap_iter -> model_1 instr_or_cont (affine_model name) + | N_ISet_iter -> model_1 instr_or_cont (affine_model name) + | N_IHalt -> model_0 instr_or_cont (const1_model name) + | N_IApply -> model_0 instr_or_cont (const1_model name) + | N_ILog -> model_0 instr_or_cont (const1_model name) + | N_IOpen_chest -> model_2 instr_or_cont (open_chest_model name)) + | Cont_name cont -> ( + match cont with + | N_KNil -> model_0 instr_or_cont (const1_model name) + | N_KCons -> model_0 instr_or_cont (const1_model name) + | N_KReturn -> model_0 instr_or_cont (const1_model name) + | N_KView_exit -> model_0 instr_or_cont (const1_model name) + | N_KMap_head -> model_0 instr_or_cont (const1_model name) + | N_KUndip -> model_0 instr_or_cont (const1_model name) + | N_KLoop_in -> model_0 instr_or_cont (const1_model name) + | N_KLoop_in_left -> model_0 instr_or_cont (const1_model name) + | N_KIter -> model_1 instr_or_cont (branching_model name) + | N_KList_enter_body -> model_2 instr_or_cont (list_enter_body_model name) + | N_KList_exit_body -> model_0 instr_or_cont (const1_model name) + | N_KMap_enter_body -> model_1 instr_or_cont (branching_model name) + | N_KMap_exit_body -> model_2 instr_or_cont (nlogm_model name) + | N_KLog -> model_0 instr_or_cont (const1_model name)) + +let amplification_loop_iteration = fv "amplification_loop_iteration" + +let amplification_loop_model = + Model.make + ~conv:(fun iterations -> (iterations, ())) + ~model:(Model.linear ~coeff:amplification_loop_iteration) + +(* The following model stitches together the per-instruction models and + adds a term corresponding to the latency induced by the timer itself. *) +let interpreter_model ?amplification ?specialization () = + Model.make_preapplied ~model:(fun trace -> + let module Def (X : Costlang.S) = struct + let applied = + let (module Timer_applied) = + Model.apply Tezos_benchmark.Builtin_benchmarks.timer_model () + in + let module Timer_result = Timer_applied (X) in + let initial = + match amplification with + | None -> Timer_result.applied + | Some amplification_factor -> + let (module Amplification_applied) = + Model.apply amplification_loop_model amplification_factor + in + let module Amplification_result = Amplification_applied (X) in + X.(Timer_result.applied + Amplification_result.applied) + in + List.fold_left + (fun (acc : X.size X.repr) instr_trace -> + let (module Applied_instr) = + Model.apply + (ir_model + ?specialization + instr_trace.Interpreter_workload.name) + instr_trace + in + let module R = Applied_instr (X) in + X.(acc + R.applied)) + initial + trace + end in + ((module Def) : Model.applied)) + +let make_model ?amplification ?specialization instr_name_opt = + match instr_name_opt with + | None -> + [("interpreter", interpreter_model ?amplification ?specialization ())] + | Some name -> + (* When generating code, we don't want to consider the terms specific to + Lwt and to the timer latency. Also, we restrict to single instructions. *) + let ir_model = ir_model ?specialization name in + let name = name_of_instr_or_cont ?specialization name in + Registration_helpers.register_for_codegen + name + (Model.For_codegen ir_model) ; + let ir_model = + Model.precompose + (function [sized_step] -> sized_step | _ -> assert false) + ir_model + in + [ + ("interpreter", interpreter_model ?amplification ?specialization ()); + ("codegen", ir_model); + ] diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_workload.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_workload.ml new file mode 100644 index 000000000000..7f48a5271d5b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/interpreter_workload.ml @@ -0,0 +1,1562 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(* ------------------------------------------------------------------------- *) + +type id = string + +let pp_id = Format.pp_print_string + +let equal_id = String.equal + +(* ------------------------------------------------------------------------- *) +(* Names of IR instructions together with sizes of their operands as + encountered during evaluation. *) + +type instruction_name = + (* stack ops *) + | N_IDrop + | N_IDup + | N_ISwap + | N_IConst + (* pairs *) + | N_ICons_pair + | N_ICar + | N_ICdr + | N_IUnpair + (* options *) + | N_ICons_some + | N_ICons_none + | N_IIf_none + | N_IOpt_map + (* unions *) + | N_ILeft + | N_IRight + | N_IIf_left + (* lists *) + | N_ICons_list + | N_INil + | N_IIf_cons + | N_IList_map + | N_IList_iter + | N_IIter + | N_IList_size + (* sets *) + | N_IEmpty_set + | N_ISet_iter + | N_ISet_mem + | N_ISet_update + | N_ISet_size + (* maps *) + | N_IEmpty_map + | N_IMap_map + | N_IMap_iter + | N_IMap_mem + | N_IMap_get + | N_IMap_update + | N_IMap_get_and_update + | N_IMap_size + (* big maps *) + | N_IEmpty_big_map + | N_IBig_map_mem + | N_IBig_map_get + | N_IBig_map_update + | N_IBig_map_get_and_update + (* string operations *) + | N_IConcat_string + | N_IConcat_string_pair + | N_ISlice_string + | N_IString_size + (* bytes operations *) + | N_IConcat_bytes + | N_IConcat_bytes_pair + | N_ISlice_bytes + | N_IBytes_size + (* timestamp operations *) + | N_IAdd_seconds_to_timestamp + | N_IAdd_timestamp_to_seconds + | N_ISub_timestamp_seconds + | N_IDiff_timestamps + (* currency operations *) + | N_IAdd_tez + | N_ISub_tez + | N_ISub_tez_legacy + | N_IMul_teznat + | N_IMul_nattez + | N_IEdiv_teznat + | N_IEdiv_tez + (* boolean operations - assumed O(1) *) + | N_IOr + | N_IAnd + | N_IXor + | N_INot + (* integer operations *) + | N_IIs_nat + | N_INeg + | N_IAbs_int + | N_IInt_nat + | N_IAdd_int + | N_IAdd_nat + | N_ISub_int + | N_IMul_int + | N_IMul_nat + | N_IEdiv_int + | N_IEdiv_nat + | N_ILsl_nat + | N_ILsr_nat + | N_IOr_nat + | N_IAnd_nat + | N_IAnd_int_nat + | N_IXor_nat + | N_INot_int + (* control *) + | N_IIf + | N_ILoop + | N_ILoop_left + | N_IDip + | N_IExec + | N_IApply + | N_ILambda + | N_IFailwith + (* comparison, warning: ad-hoc polymorphic instruction *) + | N_ICompare + (* comparators *) + | N_IEq + | N_INeq + | N_ILt + | N_IGt + | N_ILe + | N_IGe + (* protocol *) + | N_IAddress + | N_IContract + | N_ITransfer_tokens + | N_IImplicit_account + | N_ICreate_contract + | N_ISet_delegate + | N_INow + | N_IBalance + | N_ILevel + | N_IView + (* We specialize the check-signature instruction for each crypto scheme. *) + | N_ICheck_signature_ed25519 + | N_ICheck_signature_secp256k1 + | N_ICheck_signature_p256 + | N_IHash_key + | N_IPack + | N_IUnpack + | N_IBlake2b + | N_ISha256 + | N_ISha512 + | N_ISource + | N_ISender + | N_ISelf + | N_ISelf_address + | N_IAmount + | N_ISapling_empty_state + | N_ISapling_verify_update + | N_IDig + | N_IDug + | N_IDipN + | N_IDropN + | N_IChainId + | N_INever + | N_IVoting_power + | N_ITotal_voting_power + | N_IKeccak + | N_ISha3 + (* Elliptic curves *) + | N_IAdd_bls12_381_g1 + | N_IAdd_bls12_381_g2 + | N_IAdd_bls12_381_fr + | N_IMul_bls12_381_g1 + | N_IMul_bls12_381_g2 + | N_IMul_bls12_381_fr + | N_INeg_bls12_381_g1 + | N_INeg_bls12_381_g2 + | N_INeg_bls12_381_fr + | N_IMul_bls12_381_fr_z + | N_IMul_bls12_381_z_fr + | N_IInt_bls12_381_z_fr + | N_IPairing_check_bls12_381 + (* Combs *) + | N_IComb + | N_IUncomb + | N_IComb_get + | N_IComb_set + | N_IDupN + (* Tickets *) + | N_ITicket + | N_IRead_ticket + | N_ISplit_ticket + | N_IJoin_tickets + (* Misc *) + | N_IHalt + | N_ILog + (* Timelock*) + | N_IOpen_chest + +type continuation_name = + | N_KNil + | N_KCons + | N_KReturn + | N_KView_exit + | N_KMap_head + | N_KUndip + | N_KLoop_in + | N_KLoop_in_left + | N_KIter + | N_KList_enter_body + | N_KList_exit_body + | N_KMap_enter_body + | N_KMap_exit_body + | N_KLog + +and instr_or_cont_name = + | Instr_name of instruction_name + | Cont_name of continuation_name + +(* ------------------------------------------------------------------------- *) +(* Code that ought to be auto-generated *) + +let string_of_instruction_name : instruction_name -> string = + fun ir -> + match ir with + | N_IDrop -> "N_IDrop" + | N_IDup -> "N_IDup" + | N_ISwap -> "N_ISwap" + | N_IConst -> "N_IConst" + | N_ICons_pair -> "N_ICons_pair" + | N_ICar -> "N_ICar" + | N_ICdr -> "N_ICdr" + | N_ICons_some -> "N_ICons_some" + | N_ICons_none -> "N_ICons_none" + | N_IIf_none -> "N_IIf_none" + | N_IOpt_map -> "N_IOpt_map" + | N_ILeft -> "N_ILeft" + | N_IRight -> "N_IRight" + | N_IIf_left -> "N_IIf_left" + | N_ICons_list -> "N_ICons_list" + | N_INil -> "N_INil" + | N_IIf_cons -> "N_IIf_cons" + | N_IList_map -> "N_IList_map" + | N_IList_iter -> "N_IList_iter" + | N_IIter -> "N_IIter" + | N_IList_size -> "N_IList_size" + | N_IEmpty_set -> "N_IEmpty_set" + | N_ISet_iter -> "N_ISet_iter" + | N_ISet_mem -> "N_ISet_mem" + | N_ISet_update -> "N_ISet_update" + | N_ISet_size -> "N_ISet_size" + | N_IEmpty_map -> "N_IEmpty_map" + | N_IMap_map -> "N_IMap_map" + | N_IMap_iter -> "N_IMap_iter" + | N_IMap_mem -> "N_IMap_mem" + | N_IMap_get -> "N_IMap_get" + | N_IMap_update -> "N_IMap_update" + | N_IMap_size -> "N_IMap_size" + | N_IEmpty_big_map -> "N_IEmpty_big_map" + | N_IBig_map_mem -> "N_IBig_map_mem" + | N_IBig_map_get -> "N_IBig_map_get" + | N_IBig_map_update -> "N_IBig_map_update" + | N_IConcat_string -> "N_IConcat_string" + | N_IConcat_string_pair -> "N_IConcat_string_pair" + | N_ISlice_string -> "N_ISlice_string" + | N_IString_size -> "N_IString_size" + | N_IConcat_bytes -> "N_IConcat_bytes" + | N_IConcat_bytes_pair -> "N_IConcat_bytes_pair" + | N_ISlice_bytes -> "N_ISlice_bytes" + | N_IBytes_size -> "N_IBytes_size" + | N_IAdd_seconds_to_timestamp -> "N_IAdd_seconds_to_timestamp" + | N_IAdd_timestamp_to_seconds -> "N_IAdd_timestamp_to_seconds" + | N_ISub_timestamp_seconds -> "N_ISub_timestamp_seconds" + | N_IDiff_timestamps -> "N_IDiff_timestamps" + | N_IAdd_tez -> "N_IAdd_tez" + | N_ISub_tez -> "N_ISub_tez" + | N_ISub_tez_legacy -> "N_ISub_tez_legacy" + | N_IMul_teznat -> "N_IMul_teznat" + | N_IMul_nattez -> "N_IMul_nattez" + | N_IEdiv_teznat -> "N_IEdiv_teznat" + | N_IEdiv_tez -> "N_IEdiv_tez" + | N_IOr -> "N_IOr" + | N_IAnd -> "N_IAnd" + | N_IXor -> "N_IXor" + | N_INot -> "N_INot" + | N_IIs_nat -> "N_IIs_nat" + | N_INeg -> "N_INeg" + | N_IAbs_int -> "N_IAbs_int" + | N_IInt_nat -> "N_IInt_nat" + | N_IAdd_int -> "N_IAdd_int" + | N_IAdd_nat -> "N_IAdd_nat" + | N_ISub_int -> "N_ISub_int" + | N_IMul_int -> "N_IMul_int" + | N_IMul_nat -> "N_IMul_nat" + | N_IEdiv_int -> "N_IEdiv_int" + | N_IEdiv_nat -> "N_IEdiv_nat" + | N_ILsl_nat -> "N_ILsl_nat" + | N_ILsr_nat -> "N_ILsr_nat" + | N_IOr_nat -> "N_IOr_nat" + | N_IAnd_nat -> "N_IAnd_nat" + | N_IAnd_int_nat -> "N_IAnd_int_nat" + | N_IXor_nat -> "N_IXor_nat" + | N_INot_int -> "N_INot_int" + | N_IIf -> "N_IIf" + | N_ILoop -> "N_ILoop" + | N_ILoop_left -> "N_ILoop_left" + | N_IDip -> "N_IDip" + | N_IExec -> "N_IExec" + | N_IApply -> "N_IApply" + | N_ILambda -> "N_ILambda" + | N_IFailwith -> "N_IFailwith" + | N_ICompare -> "N_ICompare" + | N_IEq -> "N_IEq" + | N_INeq -> "N_INeq" + | N_ILt -> "N_ILt" + | N_IGt -> "N_IGt" + | N_ILe -> "N_ILe" + | N_IGe -> "N_IGe" + | N_IAddress -> "N_IAddress" + | N_IContract -> "N_IContract" + | N_ITransfer_tokens -> "N_ITransfer_tokens" + | N_IImplicit_account -> "N_IImplicit_account" + | N_ICreate_contract -> "N_ICreate_contract" + | N_ISet_delegate -> "N_ISet_delegate" + | N_INow -> "N_INow" + | N_IBalance -> "N_IBalance" + | N_ICheck_signature_ed25519 -> "N_ICheck_signature_ed25519" + | N_ICheck_signature_secp256k1 -> "N_ICheck_signature_secp256k1" + | N_ICheck_signature_p256 -> "N_ICheck_signature_p256" + | N_IHash_key -> "N_IHash_key" + | N_IPack -> "N_IPack" + | N_IUnpack -> "N_IUnpack" + | N_IBlake2b -> "N_IBlake2b" + | N_ISha256 -> "N_ISha256" + | N_ISha512 -> "N_ISha512" + | N_ISource -> "N_ISource" + | N_ISender -> "N_ISender" + | N_ISelf -> "N_ISelf" + | N_IAmount -> "N_IAmount" + | N_IDig -> "N_IDig" + | N_IDug -> "N_IDug" + | N_IDipN -> "N_IDipN" + | N_IDropN -> "N_IDropN" + | N_IDupN -> "N_IDupN" + | N_IChainId -> "N_IChainId" + | N_ILevel -> "N_ILevel" + | N_IView -> "N_IView" + | N_ISelf_address -> "N_ISelf_address" + | N_INever -> "N_INever" + | N_IUnpair -> "N_IUnpair" + | N_IVoting_power -> "N_IVoting_power" + | N_ITotal_voting_power -> "N_ITotal_voting_power" + | N_IKeccak -> "N_IKeccak" + | N_ISha3 -> "N_ISha3" + | N_IAdd_bls12_381_g1 -> "N_IAdd_bls12_381_g1" + | N_IAdd_bls12_381_g2 -> "N_IAdd_bls12_381_g2" + | N_IAdd_bls12_381_fr -> "N_IAdd_bls12_381_fr" + | N_IMul_bls12_381_g1 -> "N_IMul_bls12_381_g1" + | N_IMul_bls12_381_g2 -> "N_IMul_bls12_381_g2" + | N_IMul_bls12_381_fr -> "N_IMul_bls12_381_fr" + | N_INeg_bls12_381_g1 -> "N_INeg_bls12_381_g1" + | N_INeg_bls12_381_g2 -> "N_INeg_bls12_381_g2" + | N_INeg_bls12_381_fr -> "N_INeg_bls12_381_fr" + | N_IPairing_check_bls12_381 -> "N_IPairing_check_bls12_381" + | N_IMul_bls12_381_fr_z -> "N_IMul_bls12_381_fr_z" + | N_IMul_bls12_381_z_fr -> "N_IMul_bls12_381_z_fr" + | N_IInt_bls12_381_z_fr -> "N_IInt_bls12_381_z_fr" + | N_IComb -> "N_IComb" + | N_IUncomb -> "N_IUncomb" + | N_IComb_get -> "N_IComb_get" + | N_IComb_set -> "N_IComb_set" + | N_ITicket -> "N_ITicket" + | N_IRead_ticket -> "N_IRead_ticket" + | N_ISplit_ticket -> "N_ISplit_ticket" + | N_IJoin_tickets -> "N_IJoin_tickets" + | N_ISapling_empty_state -> "N_ISapling_empty_state" + | N_ISapling_verify_update -> "N_ISapling_verify_update" + | N_IMap_get_and_update -> "N_IMap_get_and_update" + | N_IBig_map_get_and_update -> "N_IBig_map_get_and_update" + | N_IHalt -> "N_IHalt" + | N_ILog -> "N_ILog" + | N_IOpen_chest -> "N_IOpen_chest" + +let string_of_continuation_name : continuation_name -> string = + fun c -> + match c with + | N_KNil -> "N_KNil" + | N_KCons -> "N_KCons" + | N_KReturn -> "N_KReturn" + | N_KView_exit -> "N_KView_exit" + | N_KMap_head -> "N_KMap_head" + | N_KUndip -> "N_KUndip" + | N_KLoop_in -> "N_KLoop_in" + | N_KLoop_in_left -> "N_KLoop_in_left" + | N_KIter -> "N_KIter" + | N_KList_enter_body -> "N_KList_enter_body" + | N_KList_exit_body -> "N_KList_exit_body" + | N_KMap_enter_body -> "N_KMap_enter_body" + | N_KMap_exit_body -> "N_KMap_exit_body" + | N_KLog -> "N_KLog" + +let string_of_instr_or_cont name = + match name with + | Instr_name instr_name -> string_of_instruction_name instr_name + | Cont_name cont_name -> string_of_continuation_name cont_name + +(* ------------------------------------------------------------------------- *) + +type args = arg list + +and arg = {name : id; arg : Size.t} + +let nullary : args = [] + +let unary xn x : args = [{name = xn; arg = x}] + +let binary xn x yn y : args = {name = xn; arg = x} :: unary yn y + +let ternary xn x yn y zn z : args = {name = xn; arg = x} :: binary yn y zn z + +let quaternary wn w xn x yn y zn z : args = + {name = wn; arg = w} :: ternary xn x yn y zn z + +let pp_arg fmtr {name; arg} = Format.fprintf fmtr "%s = %a" name Size.pp arg + +let pp_args fmtr args = + Format.pp_print_list + ~pp_sep:(fun fmtr () -> Format.fprintf fmtr ";") + pp_arg + fmtr + args + +type ir_sized_step = {name : instr_or_cont_name; args : args} + +type t = ir_sized_step list + +let ir_sized_step instr_name args = {name = Instr_name instr_name; args} + +let cont_sized_step cont_name args = {name = Cont_name cont_name; args} + +(* ------------------------------------------------------------------------- *) + +let all_instructions = + [ + N_IDrop; + N_IDup; + N_ISwap; + N_IConst; + N_ICons_pair; + N_ICar; + N_ICdr; + N_ICons_some; + N_ICons_none; + N_IIf_none; + N_IOpt_map; + N_ILeft; + N_IRight; + N_IIf_left; + N_ICons_list; + N_INil; + N_IIf_cons; + N_IList_map; + N_IList_iter; + N_IIter; + N_IList_size; + N_IEmpty_set; + N_ISet_iter; + N_ISet_mem; + N_ISet_update; + N_ISet_size; + N_IEmpty_map; + N_IMap_map; + N_IMap_iter; + N_IMap_mem; + N_IMap_get; + N_IMap_update; + N_IMap_size; + N_IEmpty_big_map; + N_IBig_map_mem; + N_IBig_map_get; + N_IBig_map_update; + N_IConcat_string; + N_IConcat_string_pair; + N_ISlice_string; + N_IString_size; + N_IConcat_bytes; + N_IConcat_bytes_pair; + N_ISlice_bytes; + N_IBytes_size; + N_IAdd_seconds_to_timestamp; + N_IAdd_timestamp_to_seconds; + N_ISub_timestamp_seconds; + N_IDiff_timestamps; + N_IAdd_tez; + N_ISub_tez; + N_ISub_tez_legacy; + N_IMul_teznat; + N_IMul_nattez; + N_IEdiv_teznat; + N_IEdiv_tez; + N_IOr; + N_IAnd; + N_IXor; + N_INot; + N_IIs_nat; + N_INeg; + N_IAbs_int; + N_IInt_nat; + N_IAdd_int; + N_IAdd_nat; + N_ISub_int; + N_IMul_int; + N_IMul_nat; + N_IEdiv_int; + N_IEdiv_nat; + N_ILsl_nat; + N_ILsr_nat; + N_IOr_nat; + N_IAnd_nat; + N_IAnd_int_nat; + N_IXor_nat; + N_INot_int; + N_IIf; + N_ILoop; + N_ILoop_left; + N_IDip; + N_IExec; + N_IApply; + N_ILambda; + N_IFailwith; + N_ICompare; + N_IEq; + N_INeq; + N_ILt; + N_IGt; + N_ILe; + N_IGe; + N_IAddress; + N_IContract; + N_ITransfer_tokens; + N_IImplicit_account; + N_ICreate_contract; + N_ISet_delegate; + N_INow; + N_IBalance; + N_ICheck_signature_ed25519; + N_ICheck_signature_secp256k1; + N_ICheck_signature_p256; + N_IHash_key; + N_IPack; + N_IUnpack; + N_IBlake2b; + N_ISha256; + N_ISha512; + N_ISource; + N_ISender; + N_ISelf; + N_IAmount; + N_IDig; + N_IDug; + N_IDipN; + N_IDropN; + N_IDupN; + N_IChainId; + N_ILevel; + N_IView; + N_ISelf_address; + N_INever; + N_IUnpair; + N_IVoting_power; + N_ITotal_voting_power; + N_IKeccak; + N_ISha3; + N_IAdd_bls12_381_g1; + N_IAdd_bls12_381_g2; + N_IAdd_bls12_381_fr; + N_IMul_bls12_381_g1; + N_IMul_bls12_381_g2; + N_IMul_bls12_381_fr; + N_INeg_bls12_381_g1; + N_INeg_bls12_381_g2; + N_INeg_bls12_381_fr; + N_IPairing_check_bls12_381; + N_IMul_bls12_381_fr_z; + N_IMul_bls12_381_z_fr; + N_IInt_bls12_381_z_fr; + N_IComb; + N_IUncomb; + N_IComb_get; + N_IComb_set; + N_ITicket; + N_IRead_ticket; + N_ISplit_ticket; + N_IJoin_tickets; + N_ISapling_empty_state; + N_ISapling_verify_update; + N_IMap_get_and_update; + N_IBig_map_get_and_update; + N_IHalt; + N_ILog; + N_IOpen_chest; + ] + +let all_continuations = + [ + N_KNil; + N_KCons; + N_KReturn; + N_KView_exit; + N_KMap_head; + N_KUndip; + N_KLoop_in; + N_KLoop_in_left; + N_KIter; + N_KList_enter_body; + N_KList_exit_body; + N_KMap_enter_body; + N_KMap_exit_body; + N_KLog; + ] + +let instruction_name_encoding = + let open Data_encoding in + def "instruction_name_encoding" + @@ string_enum + (List.map + (fun instr_name -> + (string_of_instruction_name instr_name, instr_name)) + all_instructions) + +let continuation_name_encoding = + let open Data_encoding in + def "continuation_name_encoding" + @@ string_enum + (List.map + (fun cont_name -> (string_of_continuation_name cont_name, cont_name)) + all_continuations) + +let args_encoding = + let open Data_encoding in + def "args_encoding" + @@ list + (conv + (fun {name; arg} -> (name, arg)) + (fun (name, arg) -> {name; arg}) + (tup2 string Size.encoding)) + +let instr_or_cont_name_encoding = + let open Data_encoding in + def "instr_or_cont_name" + @@ union + [ + case + ~title:"instr_name" + (Tag 0) + instruction_name_encoding + (function Instr_name name -> Some name | _ -> None) + (fun name -> Instr_name name); + case + ~title:"cont_name" + (Tag 1) + continuation_name_encoding + (function Cont_name name -> Some name | _ -> None) + (fun name -> Cont_name name); + ] + +let ir_sized_step_encoding = + let open Data_encoding in + def "ir_sized_step_encoding" + @@ conv + (fun {name; args} -> (name, args)) + (fun (name, args) -> {name; args}) + (tup2 instr_or_cont_name_encoding args_encoding) + +let encoding = + let open Data_encoding in + def "interpreter_trace_encoding" @@ list ir_sized_step_encoding + +(* ------------------------------------------------------------------------- *) + +module Instructions = struct + let drop = ir_sized_step N_IDrop nullary + + let dup = ir_sized_step N_IDup nullary + + let swap = ir_sized_step N_ISwap nullary + + let const = ir_sized_step N_IConst nullary + + let cons_pair = ir_sized_step N_ICons_pair nullary + + let car = ir_sized_step N_ICar nullary + + let cdr = ir_sized_step N_ICdr nullary + + let cons_some = ir_sized_step N_ICons_some nullary + + let cons_none = ir_sized_step N_ICons_none nullary + + let if_none = ir_sized_step N_IIf_none nullary + + let opt_map = ir_sized_step N_IOpt_map nullary + + let left = ir_sized_step N_ILeft nullary + + let right = ir_sized_step N_IRight nullary + + let if_left = ir_sized_step N_IIf_left nullary + + let cons_list = ir_sized_step N_ICons_list nullary + + let nil = ir_sized_step N_INil nullary + + let if_cons = ir_sized_step N_IIf_cons nullary + + let list_map = ir_sized_step N_IList_map nullary + + let list_iter = ir_sized_step N_IList_iter nullary + + let iter = ir_sized_step N_IIter nullary + + let list_size _list = ir_sized_step N_IList_size nullary + + let empty_set = ir_sized_step N_IEmpty_set nullary + + let set_iter set = ir_sized_step N_ISet_iter (unary "set" set) + + let set_mem elt set = ir_sized_step N_ISet_mem (binary "elt" elt "set" set) + + let set_update elt set = + ir_sized_step N_ISet_update (binary "elt" elt "set" set) + + let set_size _set = ir_sized_step N_ISet_size nullary + + let empty_map = ir_sized_step N_IEmpty_map nullary + + let map_map map = ir_sized_step N_IMap_map (unary "map" map) + + let map_iter map = ir_sized_step N_IMap_iter (unary "map" map) + + let map_mem key map = ir_sized_step N_IMap_mem (binary "key" key "map" map) + + let map_get key map = ir_sized_step N_IMap_get (binary "key" key "map" map) + + let map_update key map = + ir_sized_step N_IMap_update (binary "key" key "map" map) + + let map_size _map = ir_sized_step N_IMap_size nullary + + let empty_big_map = ir_sized_step N_IEmpty_big_map nullary + + let big_map_mem key big_map = + ir_sized_step N_IBig_map_mem (binary "key" key "big_map" big_map) + + let big_map_get key big_map = + ir_sized_step N_IBig_map_get (binary "key" key "big_map" big_map) + + let big_map_update key big_map = + ir_sized_step N_IBig_map_update (binary "key" key "big_map" big_map) + + let big_map_get_and_update key big_map = + ir_sized_step N_IBig_map_get_and_update (binary "key" key "big_map" big_map) + + let concat_string total_bytes list = + ir_sized_step + N_IConcat_string + (binary "total_bytes" total_bytes "list" list) + + let concat_string_pair str1 str2 = + ir_sized_step N_IConcat_string_pair (binary "str1" str1 "str2" str2) + + let slice_string string = + ir_sized_step N_ISlice_string (unary "string" string) + + let string_size _string = ir_sized_step N_IString_size nullary + + let concat_bytes total_bytes list = + ir_sized_step N_IConcat_bytes (binary "total_bytes" total_bytes "list" list) + + let concat_bytes_pair str1 str2 = + ir_sized_step N_IConcat_bytes_pair (binary "str1" str1 "str2" str2) + + let slice_bytes bytes = ir_sized_step N_ISlice_bytes (unary "bytes" bytes) + + let bytes_size = ir_sized_step N_IBytes_size nullary + + let add_seconds_to_timestamp seconds tstamp = + ir_sized_step + N_IAdd_seconds_to_timestamp + (binary "seconds" seconds "tstamp" tstamp) + + let add_timestamp_to_seconds tstamp seconds = + ir_sized_step + N_IAdd_timestamp_to_seconds + (binary "tstamp" tstamp "seconds" seconds) + + let sub_timestamp_seconds tstamp seconds = + ir_sized_step + N_ISub_timestamp_seconds + (binary "tstamp" tstamp "seconds" seconds) + + let diff_timestamps tstamp1 tstamp2 = + ir_sized_step + N_IDiff_timestamps + (binary "tstamp1" tstamp1 "tstamp2" tstamp2) + + let add_tez _tez1 _tez2 = ir_sized_step N_IAdd_tez nullary + + let sub_tez _tez1 _tez2 = ir_sized_step N_ISub_tez nullary + + let sub_tez_legacy _tez1 _tez2 = ir_sized_step N_ISub_tez_legacy nullary + + let mul_teznat _tez nat = ir_sized_step N_IMul_teznat (unary "nat" nat) + + let mul_nattez nat _tez = ir_sized_step N_IMul_nattez (unary "nat" nat) + + let ediv_teznat tez nat = + ir_sized_step N_IEdiv_teznat (binary "tez" tez "nat" nat) + + let ediv_tez _tez1 _tez2 = ir_sized_step N_IEdiv_tez nullary + + let or_ = ir_sized_step N_IOr nullary + + let and_ = ir_sized_step N_IAnd nullary + + let xor_ = ir_sized_step N_IXor nullary + + let not_ = ir_sized_step N_INot nullary + + let is_nat _int = ir_sized_step N_IIs_nat nullary + + let neg int = ir_sized_step N_INeg (unary "int" int) + + let abs_int int = ir_sized_step N_IAbs_int (unary "int" int) + + let int_nat _nat = ir_sized_step N_IInt_nat nullary + + let add_int int1 int2 = + ir_sized_step N_IAdd_int (binary "int1" int1 "int2" int2) + + let add_nat nat1 nat2 = + ir_sized_step N_IAdd_nat (binary "nat1" nat1 "nat2" nat2) + + let sub_int int1 int2 = + ir_sized_step N_ISub_int (binary "int1" int1 "int2" int2) + + let mul_int int1 int2 = + ir_sized_step N_IMul_int (binary "int1" int1 "int2" int2) + + let mul_nat nat int = ir_sized_step N_IMul_nat (binary "nat" nat "int" int) + + let ediv_int int1 int2 = + ir_sized_step N_IEdiv_int (binary "int1" int1 "int2" int2) + + let ediv_nat nat int = ir_sized_step N_IEdiv_nat (binary "nat" nat "int" int) + + let lsl_nat nat1 _shift = ir_sized_step N_ILsl_nat (unary "nat" nat1) + + let lsr_nat nat1 _shift = ir_sized_step N_ILsr_nat (unary "nat" nat1) + + let or_nat nat1 nat2 = + ir_sized_step N_IOr_nat (binary "nat1" nat1 "nat2" nat2) + + let and_nat nat1 nat2 = + ir_sized_step N_IAnd_nat (binary "nat1" nat1 "nat2" nat2) + + let and_int_nat int nat = + ir_sized_step N_IAnd_int_nat (binary "int" int "nat" nat) + + let xor_nat nat1 nat2 = + ir_sized_step N_IXor_nat (binary "nat1" nat1 "nat2" nat2) + + let not_int int = ir_sized_step N_INot_int (unary "int" int) + + let if_ = ir_sized_step N_IIf nullary + + let loop = ir_sized_step N_ILoop nullary + + let loop_left = ir_sized_step N_ILoop_left nullary + + let dip = ir_sized_step N_IDip nullary + + let exec = ir_sized_step N_IExec nullary + + let apply = ir_sized_step N_IApply nullary + + let lambda = ir_sized_step N_ILambda nullary + + let failwith_ = ir_sized_step N_IFailwith nullary + + let compare arg1 arg2 = + ir_sized_step N_ICompare (binary "arg1" arg1 "arg2" arg2) + + let eq = ir_sized_step N_IEq nullary + + let neq = ir_sized_step N_INeq nullary + + let lt = ir_sized_step N_ILt nullary + + let gt = ir_sized_step N_IGt nullary + + let le = ir_sized_step N_ILe nullary + + let ge = ir_sized_step N_IGe nullary + + let address = ir_sized_step N_IAddress nullary + + let contract = ir_sized_step N_IContract nullary + + let transfer_tokens = ir_sized_step N_ITransfer_tokens nullary + + let implicit_account = ir_sized_step N_IImplicit_account nullary + + let create_contract = ir_sized_step N_ICreate_contract nullary + + let set_delegate = ir_sized_step N_ISet_delegate nullary + + let now = ir_sized_step N_INow nullary + + let balance = ir_sized_step N_IBalance nullary + + let check_signature_ed25519 _pk _signature message = + ir_sized_step N_ICheck_signature_ed25519 (unary "message" message) + + let check_signature_secp256k1 _pk _signature message = + ir_sized_step N_ICheck_signature_secp256k1 (unary "message" message) + + let check_signature_p256 _pk _signature message = + ir_sized_step N_ICheck_signature_p256 (unary "message" message) + + let hash_key = ir_sized_step N_IHash_key nullary + + let pack (micheline_size : Size.micheline_size) = + ir_sized_step + N_IPack + (ternary + "micheline_nodes" + micheline_size.traversal + "micheline_int_bytes" + micheline_size.int_bytes + "micheline_string_bytes" + micheline_size.string_bytes) + + let unpack = ir_sized_step N_IUnpack nullary + + let blake2b bytes = ir_sized_step N_IBlake2b (unary "bytes" bytes) + + let sha256 bytes = ir_sized_step N_ISha256 (unary "bytes" bytes) + + let sha512 bytes = ir_sized_step N_ISha512 (unary "bytes" bytes) + + let source = ir_sized_step N_ISource nullary + + let sender = ir_sized_step N_ISender nullary + + let self = ir_sized_step N_ISelf nullary + + let amount = ir_sized_step N_IAmount nullary + + let dig depth = ir_sized_step N_IDig (unary "depth" depth) + + let dug depth = ir_sized_step N_IDug (unary "depth" depth) + + let dipn depth = ir_sized_step N_IDipN (unary "depth" depth) + + let dropn depth = ir_sized_step N_IDropN (unary "depth" depth) + + let dupn depth = ir_sized_step N_IDupN (unary "depth" depth) + + let chain_id = ir_sized_step N_IChainId nullary + + let level = ir_sized_step N_ILevel nullary + + let view = ir_sized_step N_IView nullary + + let self_address = ir_sized_step N_ISelf_address nullary + + let never = ir_sized_step N_INever nullary + + let unpair = ir_sized_step N_IUnpair nullary + + let voting_power = ir_sized_step N_IVoting_power nullary + + let total_voting_power = ir_sized_step N_ITotal_voting_power nullary + + let keccak bytes = ir_sized_step N_IKeccak (unary "bytes" bytes) + + let sha3 bytes = ir_sized_step N_ISha3 (unary "bytes" bytes) + + let add_bls12_381_g1 = ir_sized_step N_IAdd_bls12_381_g1 nullary + + let add_bls12_381_g2 = ir_sized_step N_IAdd_bls12_381_g2 nullary + + let add_bls12_381_fr = ir_sized_step N_IAdd_bls12_381_fr nullary + + let mul_bls12_381_g1 = ir_sized_step N_IMul_bls12_381_g1 nullary + + let mul_bls12_381_g2 = ir_sized_step N_IMul_bls12_381_g2 nullary + + let mul_bls12_381_fr = ir_sized_step N_IMul_bls12_381_fr nullary + + let neg_bls12_381_g1 = ir_sized_step N_INeg_bls12_381_g1 nullary + + let neg_bls12_381_g2 = ir_sized_step N_INeg_bls12_381_g2 nullary + + let neg_bls12_381_fr = ir_sized_step N_INeg_bls12_381_fr nullary + + let pairing_check_bls12_381 length = + ir_sized_step N_IPairing_check_bls12_381 (unary "length" length) + + let mul_bls12_381_fr_z nat = + ir_sized_step N_IMul_bls12_381_fr_z (unary "nat" nat) + + let mul_bls12_381_z_fr nat = + ir_sized_step N_IMul_bls12_381_z_fr (unary "nat" nat) + + let int_bls12_381_z_fr = ir_sized_step N_IInt_bls12_381_z_fr nullary + + let comb depth = ir_sized_step N_IComb (unary "depth" depth) + + let uncomb depth = ir_sized_step N_IUncomb (unary "depth" depth) + + let comb_get key = ir_sized_step N_IComb_get (unary "key" key) + + let comb_set key = ir_sized_step N_IComb_set (unary "key" key) + + let ticket = ir_sized_step N_ITicket nullary + + let read_ticket = ir_sized_step N_IRead_ticket nullary + + let split_ticket nat1 nat2 = + ir_sized_step N_ISplit_ticket (binary "nat1" nat1 "nat2" nat2) + + let join_tickets size1 size2 size3 size4 = + ir_sized_step + N_IJoin_tickets + (quaternary + "contents1" + size1 + "contents2" + size2 + "amount1" + size3 + "amount2" + size4) + + let sapling_empty_state = ir_sized_step N_ISapling_empty_state nullary + + let sapling_verify_update inputs outputs _state = + ir_sized_step + N_ISapling_verify_update + (binary "inputs" inputs "outputs" outputs) + + let map_get_and_update key_size map_size = + ir_sized_step + N_IMap_get_and_update + (binary "key_size" key_size "map_size" map_size) + + let halt = ir_sized_step N_IHalt nullary + + let log = ir_sized_step N_ILog nullary + + let open_chest log_time size = + ir_sized_step N_IOpen_chest (binary "log_time" log_time "size" size) +end + +module Control = struct + let nil = cont_sized_step N_KNil nullary + + let cons = cont_sized_step N_KCons nullary + + let return = cont_sized_step N_KReturn nullary + + let view_exit = cont_sized_step N_KView_exit nullary + + let map_head = cont_sized_step N_KMap_head nullary + + let undip = cont_sized_step N_KUndip nullary + + let loop_in = cont_sized_step N_KLoop_in nullary + + let loop_in_left = cont_sized_step N_KLoop_in_left nullary + + let iter size = cont_sized_step N_KIter (unary "size" size) + + let list_enter_body xs_size ys_size = + cont_sized_step + N_KList_enter_body + (binary "xs_size" xs_size "ys_size" ys_size) + + let list_exit_body = cont_sized_step N_KList_exit_body nullary + + let map_enter_body size = + cont_sized_step N_KMap_enter_body (unary "size" size) + + let map_exit_body key_size map_size = + cont_sized_step N_KMap_exit_body (binary "key" key_size "map" map_size) + + let log = cont_sized_step N_KLog nullary +end + +(* ------------------------------------------------------------------------- *) + +open Script_typed_ir + +let rec size_of_comparable_value : type a. a comparable_ty -> a -> Size.t = + fun (type a) (wit : a comparable_ty) (v : a) -> + match wit with + | Never_key _ -> Size.zero + | Unit_key _ -> Size.unit + | Int_key _ -> Size.integer v + | Nat_key _ -> Size.integer v + | String_key _ -> Size.script_string v + | Bytes_key _ -> Size.bytes v + | Mutez_key _ -> Size.mutez v + | Bool_key _ -> Size.bool v + | Key_hash_key _ -> Size.key_hash v + | Timestamp_key _ -> Size.timestamp v + | Address_key _ -> Size.address v + | Pair_key ((leaf, _), (node, _), _) -> + let (lv, rv) = v in + let size = + Size.add + (size_of_comparable_value leaf lv) + (size_of_comparable_value node rv) + in + Size.add size Size.one + | Union_key ((left, _), (right, _), _) -> + let size = + match v with + | L v -> size_of_comparable_value left v + | R v -> size_of_comparable_value right v + in + Size.add size Size.one + | Option_key (ty, _) -> ( + match v with + | None -> Size.one + | Some x -> Size.add (size_of_comparable_value ty x) Size.one) + | Signature_key _ -> Size.signature v + | Key_key _ -> Size.public_key v + | Chain_id_key _ -> Size.chain_id v + +let extract_compare_sized_step : + type a. a comparable_ty -> a -> a -> ir_sized_step = + fun comparable_ty x y -> + Instructions.compare + (size_of_comparable_value comparable_ty x) + (size_of_comparable_value comparable_ty y) + +let extract_ir_sized_step : + type bef_top bef res_top res. + Alpha_context.t -> + (bef_top, bef, res_top, res) Script_typed_ir.kinstr -> + bef_top * bef -> + ir_sized_step = + fun ctxt instr stack -> + let open Script_typed_ir in + match (instr, stack) with + | (IDrop (_, _), _) -> Instructions.drop + | (IDup (_, _), _) -> Instructions.dup + | (ISwap (_, _), _) -> Instructions.swap + | (IConst (_, _, _), _) -> Instructions.const + | (ICons_pair (_, _), _) -> Instructions.cons_pair + | (ICar (_, _), _) -> Instructions.car + | (ICdr (_, _), _) -> Instructions.cdr + | (IUnpair (_, _), _) -> Instructions.unpair + | (ICons_some (_, _), _) -> Instructions.cons_some + | (ICons_none (_, _), _) -> Instructions.cons_none + | (IIf_none _, _) -> Instructions.if_none + | (IOpt_map _, _) -> Instructions.opt_map + | (ICons_left (_, _), _) -> Instructions.left + | (ICons_right (_, _), _) -> Instructions.right + | (IIf_left _, _) -> Instructions.if_left + | (ICons_list (_, _), _) -> Instructions.cons_list + | (INil (_, _), _) -> Instructions.nil + | (IIf_cons _, _) -> Instructions.if_cons + | (IList_iter (_, _, _), _) -> Instructions.list_iter + | (IList_map (_, _, _), _) -> Instructions.list_map + | (IList_size (_, _), (list, _)) -> Instructions.list_size (Size.list list) + | (IEmpty_set (_, _, _), _) -> Instructions.empty_set + | (ISet_iter _, (set, _)) -> Instructions.set_iter (Size.set set) + | (ISet_mem (_, _), (v, (set, _))) -> + let (module S) = set in + let sz = size_of_comparable_value S.elt_ty v in + Instructions.set_mem sz (Size.set set) + | (ISet_update (_, _), (v, (_flag, (set, _)))) -> + let (module S) = set in + let sz = size_of_comparable_value S.elt_ty v in + Instructions.set_update sz (Size.set set) + | (ISet_size (_, _), (set, _)) -> Instructions.set_size (Size.set set) + | (IEmpty_map (_, _, _), _) -> Instructions.empty_map + | (IMap_map _, (map, _)) -> Instructions.map_map (Size.map map) + | (IMap_iter _, (map, _)) -> Instructions.map_iter (Size.map map) + | (IMap_mem (_, _), (v, (((module Map) as map), _))) -> + let key_size = size_of_comparable_value Map.key_ty v in + Instructions.map_mem key_size (Size.map map) + | (IMap_get (_, _), (v, (((module Map) as map), _))) -> + let key_size = size_of_comparable_value Map.key_ty v in + Instructions.map_get key_size (Size.map map) + | (IMap_update (_, _), (v, (_elt_opt, (((module Map) as map), _)))) -> + let key_size = size_of_comparable_value Map.key_ty v in + Instructions.map_update key_size (Size.map map) + | (IMap_get_and_update (_, _), (v, (_elt_opt, (((module Map) as map), _)))) -> + let key_size = size_of_comparable_value Map.key_ty v in + Instructions.map_get_and_update key_size (Size.map map) + | (IMap_size (_, _), (map, _)) -> Instructions.map_size (Size.map map) + | (IEmpty_big_map (_, _, _, _), _) -> Instructions.empty_big_map + | (IBig_map_mem (_, _), (v, ({diff = {size; _}; key_type; _}, _))) -> + let key_size = size_of_comparable_value key_type v in + Instructions.big_map_mem key_size size + | (IBig_map_get (_, _), (v, ({diff = {size; _}; key_type; _}, _))) -> + let key_size = size_of_comparable_value key_type v in + Instructions.big_map_get key_size size + | (IBig_map_update (_, _), (v, (_, ({diff = {size; _}; key_type; _}, _)))) -> + let key_size = size_of_comparable_value key_type v in + Instructions.big_map_update key_size size + | ( IBig_map_get_and_update (_, _), + (v, (_, ({diff = {size; _}; key_type; _}, _))) ) -> + let key_size = size_of_comparable_value key_type v in + Instructions.big_map_get_and_update key_size size + | (IConcat_string (_, _), (ss, _)) -> + let list_size = Size.list ss in + let total_bytes = + List.fold_left + (fun x s -> Size.(add x (script_string s))) + Size.zero + ss.elements + in + Instructions.concat_string list_size total_bytes + | (IConcat_string_pair (_, _), (s1, (s2, _))) -> + Instructions.concat_string_pair + (Size.script_string s1) + (Size.script_string s2) + | (ISlice_string (_, _), (_off, (_len, (s, _)))) -> + Instructions.slice_string (Size.script_string s) + | (IString_size (_, _), (s, _)) -> + Instructions.string_size (Size.script_string s) + | (IConcat_bytes (_, _), (ss, _)) -> + let list_size = Size.list ss in + let total_bytes = + List.fold_left (fun x s -> Size.(add x (bytes s))) Size.zero ss.elements + in + Instructions.concat_bytes list_size total_bytes + | (IConcat_bytes_pair (_, _), (s1, (s2, _))) -> + Instructions.concat_bytes_pair (Size.bytes s1) (Size.bytes s2) + | (ISlice_bytes (_, _), (_off, (_len, (s, _)))) -> + Instructions.slice_bytes (Size.bytes s) + | (IBytes_size (_, _), _) -> Instructions.bytes_size + | (IAdd_seconds_to_timestamp (_, _), (s, (t, _))) -> + Instructions.add_seconds_to_timestamp (Size.timestamp t) (Size.integer s) + | (IAdd_timestamp_to_seconds (_, _), (t, (s, _))) -> + Instructions.add_timestamp_to_seconds (Size.timestamp t) (Size.integer s) + | (ISub_timestamp_seconds (_, _), (t, (s, _))) -> + Instructions.sub_timestamp_seconds (Size.timestamp t) (Size.integer s) + | (IDiff_timestamps (_, _), (t1, (t2, _))) -> + Instructions.diff_timestamps (Size.timestamp t1) (Size.timestamp t2) + | (IAdd_tez (_, _), (x, (y, _))) -> + Instructions.add_tez (Size.mutez x) (Size.mutez y) + | (ISub_tez (_, _), (x, (y, _))) -> + Instructions.sub_tez (Size.mutez x) (Size.mutez y) + | (ISub_tez_legacy (_, _), (x, (y, _))) -> + Instructions.sub_tez_legacy (Size.mutez x) (Size.mutez y) + | (IMul_teznat (_, _), (x, (y, _))) -> + Instructions.mul_teznat (Size.mutez x) (Size.integer y) + | (IMul_nattez (_, _), (x, (y, _))) -> + Instructions.mul_nattez (Size.integer x) (Size.mutez y) + | (IEdiv_teznat (_, _), (x, (y, _))) -> + Instructions.ediv_teznat (Size.mutez x) (Size.integer y) + | (IEdiv_tez (_, _), (x, (y, _))) -> + Instructions.ediv_tez (Size.mutez x) (Size.mutez y) + | (IOr (_, _), _) -> Instructions.or_ + | (IAnd (_, _), _) -> Instructions.and_ + | (IXor (_, _), _) -> Instructions.xor_ + | (INot (_, _), _) -> Instructions.not_ + | (IIs_nat (_, _), (x, _)) -> Instructions.is_nat (Size.integer x) + | (INeg (_, _), (x, _)) -> Instructions.neg (Size.integer x) + | (IAbs_int (_, _), (x, _)) -> Instructions.abs_int (Size.integer x) + | (IInt_nat (_, _), (x, _)) -> Instructions.int_nat (Size.integer x) + | (IAdd_int (_, _), (x, (y, _))) -> + Instructions.add_int (Size.integer x) (Size.integer y) + | (IAdd_nat (_, _), (x, (y, _))) -> + Instructions.add_nat (Size.integer x) (Size.integer y) + | (ISub_int (_, _), (x, (y, _))) -> + Instructions.sub_int (Size.integer x) (Size.integer y) + | (IMul_int (_, _), (x, (y, _))) -> + Instructions.mul_int (Size.integer x) (Size.integer y) + | (IMul_nat (_, _), (x, (y, _))) -> + Instructions.mul_nat (Size.integer x) (Size.integer y) + | (IEdiv_int (_, _), (x, (y, _))) -> + Instructions.ediv_int (Size.integer x) (Size.integer y) + | (IEdiv_nat (_, _), (x, (y, _))) -> + Instructions.ediv_nat (Size.integer x) (Size.integer y) + | (ILsl_nat (_, _), (x, (y, _))) -> + Instructions.lsl_nat (Size.integer x) (Size.integer y) + | (ILsr_nat (_, _), (x, (y, _))) -> + Instructions.lsr_nat (Size.integer x) (Size.integer y) + | (IOr_nat (_, _), (x, (y, _))) -> + Instructions.or_nat (Size.integer x) (Size.integer y) + | (IAnd_nat (_, _), (x, (y, _))) -> + Instructions.and_nat (Size.integer x) (Size.integer y) + | (IAnd_int_nat (_, _), (x, (y, _))) -> + Instructions.and_int_nat (Size.integer x) (Size.integer y) + | (IXor_nat (_, _), (x, (y, _))) -> + Instructions.xor_nat (Size.integer x) (Size.integer y) + | (INot_int (_, _), (x, _)) -> Instructions.not_int (Size.integer x) + | (IIf _, _) -> Instructions.if_ + | (ILoop (_, _, _), _) -> Instructions.loop + | (ILoop_left (_, _, _), _) -> Instructions.loop_left + | (IDip (_, _, _), _) -> Instructions.dip + | (IExec (_, _), _) -> Instructions.exec + | (IApply (_, _, _), _) -> Instructions.apply + | (ILambda (_, _, _), _) -> Instructions.lambda + | (IFailwith (_, _, _), _) -> Instructions.failwith_ + | (ICompare (_, cmp_ty, _), (a, (b, _))) -> + extract_compare_sized_step cmp_ty a b + | (IEq (_, _), _) -> Instructions.eq + | (INeq (_, _), _) -> Instructions.neq + | (ILt (_, _), _) -> Instructions.lt + | (IGt (_, _), _) -> Instructions.gt + | (ILe (_, _), _) -> Instructions.le + | (IGe (_, _), _) -> Instructions.ge + | (IAddress (_, _), _) -> Instructions.address + | (IContract (_, _, _, _), _) -> Instructions.contract + | (ITransfer_tokens (_, _), _) -> Instructions.transfer_tokens + | (IView (_, _, _), _) -> Instructions.view + | (IImplicit_account (_, _), _) -> Instructions.implicit_account + | (ICreate_contract _, _) -> Instructions.create_contract + | (ISet_delegate (_, _), _) -> Instructions.set_delegate + | (INow (_, _), _) -> Instructions.now + | (IBalance (_, _), _) -> Instructions.balance + | (ILevel (_, _), _) -> Instructions.level + | (ICheck_signature (_, _), (public_key, (_signature, (message, _)))) -> ( + match public_key with + | Signature.Ed25519 _pk -> + let pk = Size.of_int Ed25519.size in + let signature = Size.of_int Signature.size in + let message = Size.bytes message in + Instructions.check_signature_ed25519 pk signature message + | Signature.Secp256k1 _pk -> + let pk = Size.of_int Secp256k1.size in + let signature = Size.of_int Signature.size in + let message = Size.bytes message in + Instructions.check_signature_secp256k1 pk signature message + | Signature.P256 _pk -> + let pk = Size.of_int P256.size in + let signature = Size.of_int Signature.size in + let message = Size.bytes message in + Instructions.check_signature_p256 pk signature message) + | (IHash_key (_, _), _) -> Instructions.hash_key + | (IPack (_, ty, _), (v, _)) -> + let encoding_size = Size.of_encoded_value ctxt ty v in + Instructions.pack encoding_size + | (IUnpack (_, _, _), _) -> Instructions.unpack + | (IBlake2b (_, _), (bytes, _)) -> Instructions.blake2b (Size.bytes bytes) + | (ISha256 (_, _), (bytes, _)) -> Instructions.sha256 (Size.bytes bytes) + | (ISha512 (_, _), (bytes, _)) -> Instructions.sha512 (Size.bytes bytes) + | (ISource (_, _), _) -> Instructions.source + | (ISender (_, _), _) -> Instructions.sender + | (ISelf (_, _, _, _), _) -> Instructions.self + | (ISelf_address (_, _), _) -> Instructions.self_address + | (IAmount (_, _), _) -> Instructions.amount + | (ISapling_empty_state (_, _, _), _) -> Instructions.sapling_empty_state + | (ISapling_verify_update (_, _), (transaction, (_state, _))) -> + let inputs = Size.sapling_transaction_inputs transaction in + let outputs = Size.sapling_transaction_outputs transaction in + let state = Size.zero in + Instructions.sapling_verify_update inputs outputs state + | (IDig (_, n, _, _), _) -> Instructions.dig n + | (IDug (_, n, _, _), _) -> Instructions.dug n + | (IDipn (_, n, _, _, _), _) -> Instructions.dipn n + | (IDropn (_, n, _, _), _) -> Instructions.dropn n + | (IChainId (_, _), _) -> Instructions.chain_id + | (INever _, _) -> . + | (IVoting_power (_, _), _) -> Instructions.voting_power + | (ITotal_voting_power (_, _), _) -> Instructions.total_voting_power + | (IKeccak (_, _), (bytes, _)) -> Instructions.keccak (Size.bytes bytes) + | (ISha3 (_, _), (bytes, _)) -> Instructions.sha3 (Size.bytes bytes) + | (IAdd_bls12_381_g1 (_, _), _) -> Instructions.add_bls12_381_g1 + | (IAdd_bls12_381_g2 (_, _), _) -> Instructions.add_bls12_381_g2 + | (IAdd_bls12_381_fr (_, _), _) -> Instructions.add_bls12_381_fr + | (IMul_bls12_381_g1 (_, _), _) -> Instructions.mul_bls12_381_g1 + | (IMul_bls12_381_g2 (_, _), _) -> Instructions.mul_bls12_381_g2 + | (IMul_bls12_381_fr (_, _), _) -> Instructions.mul_bls12_381_fr + | (IMul_bls12_381_z_fr (_, _), (_fr, (z, _))) -> + Instructions.mul_bls12_381_z_fr (Size.integer z) + | (IMul_bls12_381_fr_z (_, _), (z, _)) -> + Instructions.mul_bls12_381_fr_z (Size.integer z) + | (IInt_bls12_381_fr (_, _), _) -> Instructions.int_bls12_381_z_fr + | (INeg_bls12_381_g1 (_, _), _) -> Instructions.neg_bls12_381_g1 + | (INeg_bls12_381_g2 (_, _), _) -> Instructions.neg_bls12_381_g2 + | (INeg_bls12_381_fr (_, _), _) -> Instructions.neg_bls12_381_fr + | (IPairing_check_bls12_381 (_, _), (list, _)) -> + Instructions.pairing_check_bls12_381 (Size.list list) + | (IComb (_, n, _, _), _) -> Instructions.comb (Size.of_int n) + | (IUncomb (_, n, _, _), _) -> Instructions.uncomb (Size.of_int n) + | (IComb_get (_, n, _, _), _) -> Instructions.comb_get (Size.of_int n) + | (IComb_set (_, n, _, _), _) -> Instructions.comb_set (Size.of_int n) + | (IDup_n (_, n, _, _), _) -> Instructions.dupn (Size.of_int n) + | (ITicket (_, _), _) -> Instructions.ticket + | (IRead_ticket (_, _), _) -> Instructions.read_ticket + | (ISplit_ticket (_, _), (_ticket, ((amount_a, amount_b), _))) -> + Instructions.split_ticket (Size.integer amount_a) (Size.integer amount_b) + | (IJoin_tickets (_, cmp_ty, _), ((ticket1, ticket2), _)) -> + let size1 = size_of_comparable_value cmp_ty ticket1.contents in + let size2 = size_of_comparable_value cmp_ty ticket2.contents in + let tez1 = Size.integer ticket1.amount in + let tez2 = Size.integer ticket2.amount in + Instructions.join_tickets size1 size2 tez1 tez2 + | (IHalt _, _) -> Instructions.halt + | (ILog _, _) -> Instructions.log + | (IOpen_chest (_, _), (_, (chest, (time, _)))) -> + let plaintext_size = Timelock.get_plaintext_size chest - 1 in + let log_time = Z.log2 Z.(one + Script_int_repr.to_zint time) in + Instructions.open_chest log_time plaintext_size + +let extract_control_trace (type bef_top bef aft_top aft) + (cont : (bef_top, bef, aft_top, aft) Script_typed_ir.continuation) = + match cont with + | KNil -> Control.nil + | KCons _ -> Control.cons + | KReturn _ -> Control.return + | KMap_head (_, _) -> Control.map_head + | KUndip _ -> Control.undip + | KLoop_in _ -> Control.loop_in + | KLoop_in_left _ -> Control.loop_in_left + | KIter (_, xs, _) -> Control.iter (Size.of_int (List.length xs)) + | KList_enter_body (_, xs, ys, _, _) -> + Control.list_enter_body + (Size.of_int (List.length xs)) + (Size.of_int (List.length ys)) + | KList_exit_body (_, _, _, _, _) -> Control.list_exit_body + | KMap_enter_body (_, xs, _, _) -> + Control.map_enter_body (Size.of_int (List.length xs)) + | KMap_exit_body (_, _, ((module Map) as map), k, _) -> + let key_size = size_of_comparable_value Map.key_ty k in + Control.map_exit_body key_size (Size.map map) + | KView_exit _ -> Control.view_exit + | KLog _ -> Control.log + +(** [Stop_bench] gets raised when a [IFailwith] would be the next instruction. + This allows us to recover the full execution trace, including the trace of + the [IFailwith]. + + The actual benchmark will follow the same execution branch, but instead will + raise an [error] which will be ignored. Thus it is safe to end a benchmark + with [IFailwith], but timings are expected to be different from ending with + [IHalt]. This means that, if we choose to include this behavior in any + benchmark, [IFailwith] must be benched. *) +exception Stop_bench + +let extract_deps (type bef_top bef aft_top aft) ctxt step_constants + (kinstr : (bef_top, bef, aft_top, aft) Script_typed_ir.kinstr) + (stack : bef_top * bef) = + let trace = ref [] in + (* Logger definition *) + let log_interp _instr _ctxt _log _stack_ty _stack = () in + let log_entry : + type a s b f. (a, s, b, f, a, s) Script_typed_ir.logging_function = + fun kinstr ctxt _loc _stack_ty stack -> + trace := extract_ir_sized_step ctxt kinstr stack :: !trace ; + match kinstr with IFailwith _ -> raise Stop_bench | _ -> () + in + let log_control kont = trace := extract_control_trace kont :: !trace in + let log_exit _instr _ctxt _log _stack_ty _stack = () in + let get_log () = Environment.Error_monad.return_none in + let logger = {log_interp; log_entry; log_control; log_exit; get_log} in + try + let res = + Lwt_main.run + (Script_interpreter.kstep + (Some logger) + ctxt + step_constants + kinstr + (fst stack) + (snd stack)) + in + match Environment.wrap_tzresult res with + | Error errs -> + Format.eprintf "%a@." Error_monad.pp_print_trace errs ; + raise (Failure "Interpreter_workload.extract_deps: error in step") + | Ok (_aft_top, _aft, _ctxt) -> + (* ((aft_top, aft), List.rev !trace, ctxt) *) + List.rev !trace + with Stop_bench -> List.rev !trace + +let extract_deps_continuation (type bef_top bef aft_top aft) ctxt step_constants + (cont : (bef_top, bef, aft_top, aft) Script_typed_ir.continuation) + (stack : bef_top * bef) = + let trace = ref [] in + (* Logger definition *) + let log_interp _instr _ctxt _log _stack_ty _stack = () in + let log_entry : + type a s b f. (a, s, b, f, a, s) Script_typed_ir.logging_function = + fun kinstr ctxt _loc _stack_ty stack -> + trace := extract_ir_sized_step ctxt kinstr stack :: !trace ; + match kinstr with IFailwith _ -> raise Stop_bench | _ -> () + in + let log_control kont = trace := extract_control_trace kont :: !trace in + let log_exit _instr _ctxt _log _stack_ty _stack = () in + let get_log () = Environment.Error_monad.return_none in + let logger = {log_interp; log_entry; log_control; log_exit; get_log} in + try + let res = + Lwt_main.run + (Script_interpreter.Internals.next + (Some logger) + (Script_interpreter.Internals.OutDatedContext ctxt, step_constants) + 0xFF_FF_FF_FF + cont + (fst stack) + (snd stack)) + in + match Environment.wrap_tzresult res with + | Error errs -> + Format.eprintf "%a@." Error_monad.pp_print_trace errs ; + raise (Failure "Interpreter_workload.extract_deps: error in step") + | Ok (_aft_top, _aft, _outdated_ctxt, _gas) -> + (* ((aft_top, aft), List.rev !trace, outdated_ctxt, gas) *) + List.rev !trace + with Stop_bench -> List.rev !trace + +let sized_step_to_sparse_vec {name; args} = + let s = string_of_instr_or_cont name in + match args with + | [] -> Sparse_vec.String.of_list [(s, float_of_int 1)] + | _ -> + List.fold_left + (fun acc {name; arg} -> + Sparse_vec.String.( + add acc (of_list [(s ^ "_" ^ name, float_of_int arg)]))) + Sparse_vec.String.zero + args + +let trace_to_sparse_vec trace = + List.fold_left + (fun acc step -> Sparse_vec.String.add acc (sized_step_to_sparse_vec step)) + Sparse_vec.String.zero + trace diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_commands.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_commands.ml new file mode 100644 index 000000000000..13cf634827ec --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_commands.ml @@ -0,0 +1,202 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Michelson_generation + +let group = + { + Clic.name = "Michelson generation"; + title = "Command for generating random Michelson code and data"; + } + +module Michelson_concat_cmd = struct + let handler () file1 file2 file3 () = + let trace1 = Michelson_mcmc_samplers.load ~filename:file1 in + let trace2 = Michelson_mcmc_samplers.load ~filename:file2 in + let terms = trace1 @ trace2 in + let l1 = List.length trace1 in + let l2 = List.length trace2 in + Format.eprintf + "Loaded %d terms from %s, %d terms from %s, total %d@." + l1 + file1 + l2 + file2 + (l1 + l2) ; + Michelson_mcmc_samplers.save ~filename:file3 ~terms ; + return_unit + + let params = + Clic.( + prefixes [Protocol.name; "michelson"; "concat"; "files"] + @@ string ~name:"FILENAME" ~desc:"First file" + @@ prefixes ["and"] + @@ string ~name:"FILENAME" ~desc:"Second file" + @@ prefixes ["into"] + @@ string ~name:"FILENAME" ~desc:"Target file" + @@ stop) + + let command = + Clic.command + ~group + ~desc:"Michelson generation" + Clic.no_options + params + handler +end + +let () = Registration.add_command Michelson_concat_cmd.command + +module Michelson_gen_cmd = struct + let lift_opt f opt_arg state = + match opt_arg with None -> state | Some arg -> f arg state + + let handler (min_size, max_size, burn_in, seed) terms_count terms_kind + filename () = + let default = Michelson_generation.default_generator_config in + let min = Option.value ~default:default.target_size.min min_size in + let max = Option.value ~default:default.target_size.max max_size in + let burn_in_multiplier = + Option.value ~default:default.burn_in_multiplier burn_in + in + let rng_state = + match seed with + | None -> + Format.eprintf "Self-initialization of PRNG@." ; + let state = Random.State.make_self_init () in + Format.(eprintf "PRNG state hash: %d@." (Hashtbl.hash state)) ; + state + | Some seed -> + Format.eprintf "PRNG initialized with seed %d@." seed ; + Random.State.make [|seed|] + in + let cfg = + {Michelson_generation.target_size = {min; max}; burn_in_multiplier} + in + let terms_count = + match int_of_string terms_count with + | exception Failure _ -> + Format.eprintf "TERMS-COUNT must be an integer, exiting@." ; + exit 1 + | terms_count -> + if terms_count <= 0 then ( + Format.eprintf "TERMS-COUNT must be strictly positive, exiting@." ; + exit 1) + else terms_count + in + let progress = + Benchmark_helpers.make_progress_printer + Format.err_formatter + terms_count + "Generating term" + in + let terms = + match terms_kind with + | "data" -> + Stdlib.List.init terms_count (fun _i -> + progress () ; + Michelson_mcmc_samplers.Data + (Michelson_generation.make_data_sampler rng_state cfg)) + | "code" -> + Stdlib.List.init terms_count (fun _i -> + progress () ; + Michelson_mcmc_samplers.Code + (Michelson_generation.make_code_sampler rng_state cfg)) + | _ -> + Format.eprintf "Term kind must be either \"data\" or \"code\"@." ; + exit 1 + in + Michelson_mcmc_samplers.save ~filename ~terms ; + return_unit + + let min_size_arg = + let min_size = + Clic.parameter (fun (_ : unit) parsed -> + try return (int_of_string parsed) + with _ -> + Printf.eprintf "Error while parsing --min-size argument." ; + exit 1) + in + Clic.arg + ~doc:"Lower bound for target size of terms" + ~long:"min-size" + ~placeholder:"int" + min_size + + let max_size_arg = + let max_size = + Clic.parameter (fun (_ : unit) parsed -> + try return (int_of_string parsed) + with _ -> + Printf.eprintf "Error while parsing --max-size argument." ; + exit 1) + in + Clic.arg + ~doc:"Lower bound for target size of terms" + ~long:"max-size" + ~placeholder:"int" + max_size + + let burn_in_arg = + let target_size = + Clic.parameter (fun (_ : unit) parsed -> + try return (int_of_string parsed) + with _ -> + Printf.eprintf "Error while parsing --burn-in argument." ; + exit 1) + in + Clic.arg + ~doc:"Burn-in multiplier" + ~long:"burn-in" + ~placeholder:"int" + target_size + + let seed_arg = + let seed = + Clic.parameter (fun (_ : unit) parsed -> + try return (int_of_string parsed) + with _ -> + Printf.eprintf "Error while parsing --seed argument." ; + exit 1) + in + Clic.arg ~doc:"RNG seed" ~long:"seed" ~placeholder:"int" seed + + let options = Clic.args4 min_size_arg max_size_arg burn_in_arg seed_arg + + let params = + Clic.( + prefixes [Protocol.name; "michelson"; "generate"] + @@ string ~name:"TERMS-COUNT" ~desc:"Number of terms to generate" + @@ prefixes ["terms"; "of"; "kind"] + @@ string ~name:"{data|code}" ~desc:"Kind of term to generate" + @@ prefixes ["in"] + @@ string ~name:"FILENAME" ~desc:"File where to save Michelson terms" + @@ stop) + + let command = + Clic.command ~group ~desc:"Michelson generation" options params handler +end + +let () = Registration.add_command Michelson_gen_cmd.command diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_generation.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_generation.ml new file mode 100644 index 000000000000..d1422930010a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_generation.ml @@ -0,0 +1,113 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type generator_config = { + target_size : Base_samplers.range; + burn_in_multiplier : int; +} + +let default_generator_config = + {target_size = {Base_samplers.min = 100; max = 1000}; burn_in_multiplier = 5} + +let generator_config_encoding = + let open Data_encoding in + conv + (fun {target_size; burn_in_multiplier} -> (target_size, burn_in_multiplier)) + (fun (target_size, burn_in_multiplier) -> {target_size; burn_in_multiplier}) + (obj2 + (req "target_size" Base_samplers.range_encoding) + (req "burn_in_multiplier" int31)) + +(* ----------------------------------------------------------------------- *) + +(* ----------------------------------------------------------------------- *) + +module Crypto_samplers = Crypto_samplers.Make_finite_key_pool (struct + let size = 16 + + let algo = `Default +end) + +module Samplers = + Michelson_samplers.Make + (struct + let parameters = + { + Michelson_samplers.base_parameters = + { + int_size = {min = 8; max = 32}; + string_size = {min = 8; max = 128}; + bytes_size = {min = 8; max = 128}; + }; + list_size = {min = 0; max = 1000}; + set_size = {min = 0; max = 1000}; + map_size = {min = 0; max = 1000}; + } + end) + (Crypto_samplers) + +module Michelson_base_samplers = Samplers.Michelson_base + +(* ----------------------------------------------------------------------- *) + +let make_data_sampler rng_state config = + let target_size = + Base_samplers.sample_in_interval rng_state ~range:config.target_size + in + let module Data = + Michelson_mcmc_samplers.Make_data_sampler + (Michelson_base_samplers) + (Crypto_samplers) + (struct + let rng_state = rng_state + + let target_size = target_size + + let verbosity = `Silent + end) + in + let burn_in = target_size * config.burn_in_multiplier in + let generator = Data.generator ~burn_in rng_state in + generator rng_state + +let make_code_sampler rng_state config = + let target_size = + Base_samplers.sample_in_interval rng_state ~range:config.target_size + in + let module Code = + Michelson_mcmc_samplers.Make_code_sampler + (Michelson_base_samplers) + (Crypto_samplers) + (struct + let rng_state = rng_state + + let target_size = target_size + + let verbosity = `Silent + end) + in + let burn_in = target_size * config.burn_in_multiplier in + let generator = Code.generator ~burn_in rng_state in + generator rng_state diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_generation.mli b/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_generation.mli new file mode 100644 index 000000000000..89868e6f58b1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_generation.mli @@ -0,0 +1,61 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** {2 Wrappers around some Michelson generators and related helpers} *) + +(** [generator_config] specifies some parameters to the + {!Tezos_benchmark_alpha.Michelson_mcmc_samplers} Michelson code and data generators. *) +type generator_config = { + target_size : Base_samplers.range; + (** The target size of the terms, in number of nodes, is sampled uniformly + in [target_size]. *) + burn_in_multiplier : int; + (** The generators are based on a Markov chain, which must be + "heated-up" until it reaches its stationary state. A prefix of samples + are therefore thrown away: this is called the {e burn-in} phase. + The number of thrown away terms is proportional to [burn_in_multiplier] + and [target_size]. *) +} + +(** Default configuration for the generators. *) +val default_generator_config : generator_config + +val generator_config_encoding : generator_config Data_encoding.t + +(** Samplers *) + +(** [make_data_sampler] constructs a Michelson data sampler based on the + infrastructure available in {!Tezos_benchmark_alpha.Michelson_mcmc_samplers}. *) +val make_data_sampler : + Random.State.t -> generator_config -> Michelson_mcmc_samplers.michelson_data + +(** [make_code_sampler] constructs a Michelson code sampler based on the + infrastructure available in {!Tezos_benchmark_alpha.Michelson_mcmc_samplers}. *) +val make_code_sampler : + Random.State.t -> generator_config -> Michelson_mcmc_samplers.michelson_code + +(** [Samplers] is an instance of the direct-style (non-MCMC based) samplers + implemented in {!Tezos_benchmark_alpha.Michelson_samplers}. *) +module Samplers : Michelson_samplers.S diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_types.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_types.ml new file mode 100644 index 000000000000..047097c932e2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/michelson_types.ml @@ -0,0 +1,138 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Script_typed_ir + +[@@@ocaml.warning "-32"] + +let ( @$ ) x y = Item_t (x, y, None) + +let bot = Bot_t + +let unit = unit_t ~annot:None + +let unit_cmp = unit_key ~annot:None + +let int_cmp = int_key ~annot:None + +let string_cmp = string_key ~annot:None + +(* the type of integers *) +let int = int_t ~annot:None + +(* the type of naturals *) +let nat = nat_t ~annot:None + +(* the type of strings *) +let string = string_t ~annot:None + +(* the type of bytes *) +let bytes = bytes_t ~annot:None + +(* the type of booleans *) +let bool = bool_t ~annot:None + +(* the type of mutez *) +let mutez = mutez_t ~annot:None + +(* the type of public key *) +let public_key = key_t ~annot:None + +(* the type of key hashes *) +let key_hash = key_hash_t ~annot:None + +(* the type of signatures *) +let signature = signature_t ~annot:None + +(* the type of addresses *) +let address = address_t ~annot:None + +(* the type of chain ids *) +let chain_id = chain_id_t ~annot:None + +(* the type of timestamps *) +let timestamp = timestamp_t ~annot:None + +(* list type constructor *) +let list x = + match list_t (-1) x ~annot:None with Error _ -> assert false | Ok t -> t + +(* option type constructor *) +let option x = + match option_t (-1) x ~annot:None with Error _ -> assert false | Ok t -> t + +(* map type constructor*) +let map k v = + match map_t (-1) k v ~annot:None with Error _ -> assert false | Ok t -> t + +(* map type constructor*) +let big_map k v = + match big_map_t (-1) k v ~annot:None with + | Error _ -> assert false + | Ok t -> t + +(* set type constructor*) +let set k = + match set_t (-1) k ~annot:None with Error _ -> assert false | Ok t -> t + +(* pair type constructor*) +let pair k1 k2 = + match pair_t (-1) (k1, None, None) (k2, None, None) ~annot:None with + | Error _ -> assert false + | Ok t -> t + +(* union type constructor*) +let union k1 k2 = + match union_t (-1) (k1, None) (k2, None) ~annot:None with + | Error _ -> assert false + | Ok t -> t + +let lambda x y = + match lambda_t (-1) x y ~annot:None with Error _ -> assert false | Ok t -> t + +let contract arg_ty = + match contract_t (-1) arg_ty ~annot:None with + | Error _ -> assert false + | Ok t -> t + +let operation = operation_t ~annot:None + +let sapling_state memo_size = sapling_state_t ~memo_size ~annot:None + +let sapling_transaction memo_size = sapling_transaction_t ~memo_size ~annot:None + +let bls12_381_g1 = bls12_381_g1_t ~annot:None + +let bls12_381_g2 = bls12_381_g2_t ~annot:None + +let bls12_381_fr = bls12_381_fr_t ~annot:None + +let ticket ty = + match ticket_t (-1) ty ~annot:None with Error _ -> assert false | Ok t -> t + +let chest_key = chest_key_t ~annot:None + +let chest = chest_t ~annot:None diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/registration_helpers.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/registration_helpers.ml new file mode 100644 index 000000000000..81a84d090420 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/registration_helpers.ml @@ -0,0 +1,37 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let register ((module Bench) : Benchmark.t) = + let module B : Benchmark.S = struct + include Bench + + let name = name ^ "_" ^ Protocol.name + + let tags = Protocol.name :: tags + end in + Registration.register (module B) + +let register_for_codegen name model = + Registration.register_for_codegen (name ^ "_" ^ Protocol.name) model diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_benchmarks.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_benchmarks.ml new file mode 100644 index 000000000000..5ce5c4ff0693 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_benchmarks.ml @@ -0,0 +1,152 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +module Apply_diff_bench : Benchmark.S = struct + include Interpreter_benchmarks.Default_config + include Interpreter_benchmarks.Default_boilerplate + + let name = "SAPLING_APPLY_DIFF" + + let info = "Benchmarking SAPLING_APPLY_DIFF" + + let tags = ["sapling"] + + let diff_from_tx (tx : Alpha_context.Sapling.transaction) = + let open Environment.Sapling.UTXO in + let commitments_and_ciphertexts = + List.map (fun x -> (x.cm, x.ciphertext)) tx.outputs + in + { + Protocol.Sapling_repr.commitments_and_ciphertexts; + nullifiers = List.map (fun (x : input) -> x.nf) tx.inputs; + } + + type workload = {nb_input : int; nb_output : int; nb_cm : int; nb_nf : int} + + let workload_encoding : workload Data_encoding.t = + let open Data_encoding in + def "diff_arg_encoding" + @@ conv + (fun {nb_input; nb_output; nb_cm; nb_nf} -> + (nb_input, nb_output, nb_cm, nb_nf)) + (fun (nb_input, nb_output, nb_cm, nb_nf) -> + {nb_input; nb_output; nb_cm; nb_nf}) + (tup4 Size.encoding Size.encoding Size.encoding Size.encoding) + + let workload_to_vector {nb_input; nb_output; nb_cm = _; nb_nf = _} = + let l = + [ + ("nb_input", float_of_int nb_input); + ("nb_output", float_of_int nb_output); + ] + in + Sparse_vec.String.of_list l + + let model = + Model.make + ~conv:(fun {nb_input; nb_output; _} -> (nb_input, (nb_output, ()))) + ~model: + (Model.bilinear_affine + ~intercept:(Free_variable.of_string "apply_diff_const") + ~coeff1:(Free_variable.of_string "apply_diff_inputs") + ~coeff2:(Free_variable.of_string "apply_diff_outputs")) + + let models = [("apply_diff", model)] + + let benchmark_apply_diff seed sapling_transition () = + let sapling_forge_rng_state = + Random.State.make + @@ Option.fold + ~none:Sapling_generation.shared_seed + ~some:(fun seed -> [|seed|]) + seed + in + Lwt_main.run + ( Execution_context.make ~rng_state:sapling_forge_rng_state + >>=? fun (ctxt, step_constants) -> + Sapling_generation.prepare_seeded_state sapling_transition ctxt + >>=? fun (_, _, _, _, ctxt, state_id) -> + let external_state_id = Alpha_context.Sapling.Id.parse_z state_id in + let internal_state_id = + Lazy_storage_kind.Sapling_state.Id.parse_z state_id + in + Alpha_context.Sapling.(state_from_id ctxt external_state_id) + >|= Protocol.Environment.wrap_tzresult + >>=? fun (state, ctxt) -> + Format.eprintf "state hash: %d@." (Hashtbl.hash state.diff) ; + Format.eprintf + "tx hash: %d@." + (Hashtbl.hash sapling_transition.sapling_tx) ; + let address = Alpha_context.Contract.to_b58check step_constants.self in + let chain_id = + Environment.Chain_id.to_b58check step_constants.chain_id + in + let anti_replay = address ^ chain_id in + Format.eprintf "anti-replay: %s@." anti_replay ; + let diff = diff_from_tx sapling_transition.sapling_tx in + let closure () = + ignore + (Lwt_main.run + (Sapling_generation.apply_diff ctxt internal_state_id diff)) + in + let workload = + { + nb_input = List.length sapling_transition.sapling_tx.inputs; + nb_output = List.length sapling_transition.sapling_tx.outputs; + nb_cm = Int64.to_int sapling_transition.commitment_count; + nb_nf = Int64.to_int sapling_transition.nullifier_count; + } + in + return (Generator.Plain {workload; closure}) ) + |> function + | Ok closure -> closure + | Error errs -> + Format.eprintf + "Runner.benchmarkable_from_instr_str:\n%a@." + (Format.pp_print_list Error_monad.pp) + errs ; + exit 1 + + let create_benchmarks ~rng_state ~bench_num config = + ignore rng_state ; + match config.sapling with + | {sapling_txs_file; seed} -> + let transitions = Sapling_generation.load ~filename:sapling_txs_file in + let length = List.length transitions in + if length < bench_num then + Format.eprintf + "KSapling_verify_update: warning, only %d available transactions \ + (requested %d)@." + length + bench_num ; + let transitions = List.take_n (min bench_num length) transitions in + List.map + (fun (_filename, tx) -> benchmark_apply_diff seed tx) + transitions +end + +let () = Registration_helpers.register (module Apply_diff_bench) diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_commands.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_commands.ml new file mode 100644 index 000000000000..77b42a0b848b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_commands.ml @@ -0,0 +1,134 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Sapling_gen_cmd = struct + let lift_opt f opt_arg state = + match opt_arg with None -> state | Some arg -> f arg state + + (* ----------------------------------------------------------------------- *) + (* Handling options for the "generate sapling transactions" command *) + + (* Generic max-%s argument *) + let max name = + Clic.arg + ~doc:(Printf.sprintf "Maximum number of %s" name) + ~long:(Printf.sprintf "max-%s" name) + ~placeholder:"integer" + (Clic.parameter (fun (_ : unit) parsed -> + match int_of_string parsed with + | exception Failure _ -> + Format.eprintf + "Ill-formatted --max-%s option (expected integer), exiting" + name ; + exit 1 + | res when res <= 0 -> + Format.eprintf + "--max-%s should be a strictly positive integer, exiting" + name ; + exit 1 + | res -> return res)) + + (* Integer argument --seed *) + let seed_arg = + let seed = + Clic.parameter (fun (_ : unit) parsed -> + try return (int_of_string parsed) + with _ -> + Printf.eprintf "Error while parsing --seed argument." ; + exit 1) + in + Clic.arg ~doc:"RNG seed" ~long:"seed" ~placeholder:"int" seed + + let positive_param = + Clic.parameter (fun _ s -> + match int_of_string_opt s with + | Some i when i > 0 -> return i + | _ -> failwith "Parameter should be a positive integer literal") + + open Sapling_generation + + let set_max_inputs max_inputs options = {options with max_inputs} + + let set_max_outputs max_outputs options = {options with max_outputs} + + let set_max_nullifiers max_nullifiers options = {options with max_nullifiers} + + let set_max_additional_commitments max_additional_commitments options = + {options with max_additional_commitments} + + let set_seed seed (options : sapling_gen_options) = + {options with seed = Some seed} + + let sapling_handler + (max_inputs, max_outputs, max_nullifiers, max_additional_commitments, seed) + tx_count save_to () = + let sapling_gen_options = + default_sapling_gen_options + |> lift_opt set_max_inputs max_inputs + |> lift_opt set_max_outputs max_outputs + |> lift_opt set_max_nullifiers max_nullifiers + |> lift_opt set_max_additional_commitments max_additional_commitments + |> lift_opt set_seed seed + in + generate save_to tx_count sapling_gen_options ; + return () + + let options = + Clic.args5 + (max "inputs") + (max "outputs") + (max "nullifiers") + (max "additional-commitments") + seed_arg + + let params = + Clic.( + prefixes [Protocol.name; "sapling"; "generate"] + @@ param + ~name:"SAPLING-TX-COUNT" + ~desc:"Number of sapling transactions to generate" + positive_param + @@ prefixes ["transactions"; "in"] + @@ string + ~name:"SAPLING-TX-FILE" + ~desc:"File containing sapling transactions" + @@ stop) + + let group = + { + Clic.name = "Sapling tx generation"; + title = "Command for generating random sapling transactions"; + } + + let command = + Clic.command + ~group + ~desc:"Sapling transaction generation" + options + params + sapling_handler +end + +let () = Registration.add_command Sapling_gen_cmd.command diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_generation.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_generation.ml new file mode 100644 index 000000000000..79059417911e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/sapling_generation.ml @@ -0,0 +1,560 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(* ------------------------------------------------------------------------- *) +type sapling_gen_options = { + max_inputs : int; + max_outputs : int; + max_nullifiers : int; + max_additional_commitments : int; + seed : int option; +} + +let default_sapling_gen_options = + { + max_inputs = 100; + max_outputs = 100; + max_nullifiers = 100; + max_additional_commitments = 50; + seed = None; + } + +(* ------------------------------------------------------------------------- *) +(* Evil incantations *) + +(* We have to break the protocol abstraction boundary quite often in this + module. Props to whoever finds a way to avoid these calls. *) + +let alpha_to_raw (x : Alpha_context.t) : Raw_context.t = Obj.magic x + +let raw_to_alpha (x : Raw_context.t) : Alpha_context.t = Obj.magic x + +(* ------------------------------------------------------------------------- *) +(* Helpers *) + +(* sample a random permutation of [0 ; ... ; n-1] *) +let fisher_yates n state = + let a = Array.init n (fun i -> i) in + for i = 0 to Array.length a - 1 do + let j = Random.State.int state (i + 1) in + let tmp = a.(j) in + a.(j) <- a.(i) ; + a.(i) <- tmp + done ; + a + +(* sample a random injection of [0 ; ... ; m-1 ] in [0 ; ... ; n - 1] *) +let random_injection m n state = + if m > n then invalid_arg "random_injection" + else + let a = fisher_yates n state in + Array.sub a 0 m + +(* ------------------------------------------------------------------------- *) +(* Sapling generation *) + +(* Sapling state spec + sapling transaction valid for that state. *) +type sapling_transition = { + state_seed : int64; + nullifier_count : int64; + commitment_count : int64; + sapling_tx : Alpha_context.Sapling.transaction; +} + +type forge_info = { + rcm : Tezos_sapling.Core.Client.Rcm.t; + position : int64; + amount : int64; + address : Tezos_sapling.Core.Client.Viewing_key.address; + nf : Tezos_sapling.Core.Client.Nullifier.t; +} + +let random_amount sum = + Random.int64 (Int64.sub Tezos_sapling.Core.Validator.UTXO.max_amount sum) + +let reverse diff = + Protocol.Sapling_repr. + { + diff with + commitments_and_ciphertexts = List.rev diff.commitments_and_ciphertexts; + } + +let pp_rpc_diff fmtr (diff : Protocol.Sapling_repr.diff) = + let json = + Data_encoding.Json.construct Protocol.Sapling_repr.diff_encoding diff + in + Format.fprintf fmtr "%a" Data_encoding.Json.pp json + +let random_bytes state size = + Bytes.init size (fun _ -> Char.chr (Random.State.int state 256)) + +let rec gen_rcm state = + let rcm = + Data_encoding.Binary.of_bytes_exn + Tezos_sapling.Core.Client.Rcm.encoding + (random_bytes state 32) + in + try + Tezos_sapling.Core.Client.Rcm.assert_valid rcm ; + rcm + with _ -> gen_rcm state + +(* Adds a commitment, ciphertext, cv to an rpc_diff *) +let add_input diff vk index position sum state = + let rcm = gen_rcm state in + let amount = random_amount sum in + let (new_idx, address) = + Tezos_sapling.Core.Client.Viewing_key.new_address vk index + in + let cv = + Tezos_sapling.Core.Client.CV.of_bytes (random_bytes state 32) + |> WithExceptions.Option.get ~loc:__LOC__ + in + let (ciphertext, cm) = + Tezos_sapling.Core.Client.Forge.Output.to_ciphertext + Tezos_sapling.Core.Client.Forge.Output. + {address; amount; memo = Bytes.empty} + cv + vk + rcm + (Tezos_sapling.Core.Client.DH.esk_random ()) + in + let nf = + Tezos_sapling.Core.Client.Nullifier.compute address vk ~amount rcm ~position + in + let diff = + Protocol.Sapling_repr. + { + diff with + commitments_and_ciphertexts = + (cm, ciphertext) :: diff.commitments_and_ciphertexts; + } + in + return (diff, {rcm; position; amount; address; nf}, new_idx) + +let generate_commitments ~vk ~nb_input ~nb_cm ~nb_nf ~diff ~index state = + let inj = random_injection nb_input nb_cm state in + let use_for_input i = Array.exists (fun k -> k = i) inj in + let rec loop i cm_index nb_nf diff to_forge sum = + if i = nb_cm then return (reverse diff, to_forge) + else if use_for_input i then + (* create commitment for input *) + add_input diff vk cm_index (Int64.of_int i) sum state + >>=? fun (diff, forge_info, next_index) -> + let sum = Int64.add sum forge_info.amount in + loop (i + 1) next_index nb_nf diff (forge_info :: to_forge) sum + else + (* create commitment (not for input) *) + add_input diff vk cm_index (Int64.of_int i) sum state + >>=? fun (diff, {nf; _}, next_index) -> + (* can we use a nullifier? *) + if nb_nf = 0 then (* No. *) + loop (i + 1) next_index nb_nf diff to_forge sum + else + (* Yes! Grab it. *) + let diff = + Protocol.Sapling_repr.{diff with nullifiers = nf :: diff.nullifiers} + in + loop (i + 1) next_index (nb_nf - 1) diff to_forge sum + in + loop 0 index nb_nf diff [] 0L + +(* Add roots to the storage. One cm has to be added for every root. *) +let rec add_root nb_root ctxt id vk index size diff state = + if nb_root > 0 then + add_input Protocol.Sapling_storage.empty_diff vk index size 0L state + >>=? fun (diff_to_add, {position = size; _}, new_idx) -> + Protocol.Sapling_storage.apply_diff ctxt id diff_to_add + >|= Protocol.Environment.wrap_tzresult + >>=? fun (ctxt, _) -> + (* We call it nb_root -1 because one root is already present*) + add_root + (nb_root - 1) + ctxt + id + vk + new_idx + (Int64.succ size) + Protocol.Sapling_repr. + { + diff with + commitments_and_ciphertexts = + diff.commitments_and_ciphertexts + @ diff_to_add.commitments_and_ciphertexts; + } + state + else return (ctxt, diff) + +(* Compute a state as an OCaml object to compute the witness *) +let state_from_rpc_diff rpc_diff = + Tezos_sapling.Storage.add + (Tezos_sapling.Storage.empty ~memo_size:0) + rpc_diff.Protocol.Sapling_repr.commitments_and_ciphertexts + +(* Create an (unspendable) output from a proving context and a vk *) +let output proving_ctx vk sum = + let address = Tezos_sapling.Core.Client.Viewing_key.dummy_address () in + let amount = random_amount sum in + let rcm = Tezos_sapling.Core.Client.Rcm.random () in + let esk = Tezos_sapling.Core.Client.DH.esk_random () in + let (cv_o, proof_o) = + Tezos_sapling.Core.Client.Proving.output_proof + proving_ctx + esk + address + rcm + ~amount + in + let (ciphertext, cm) = + Tezos_sapling.Core.Client.Forge.Output.to_ciphertext + Tezos_sapling.Core.Client.Forge.Output. + {address; amount; memo = Bytes.empty} + cv_o + vk + rcm + esk + in + (Tezos_sapling.Core.Validator.UTXO.{cm; proof_o; ciphertext}, amount) + +(* Returns a list of outputs and the sum of their amount *) +let outputs nb_output proving_ctx vk = + let rec aux output_amount list_outputs nb_output sum = + match nb_output with + | 0 -> (output_amount, list_outputs) + | nb_output -> + let (output, amount) = output proving_ctx vk sum in + assert ( + Int64.compare + amount + (Int64.sub + Int64.max_int + Tezos_sapling.Core.Validator.UTXO.max_amount) + < 0) ; + aux + (Int64.add output_amount amount) + (output :: list_outputs) + (nb_output - 1) + (Int64.add sum amount) + in + aux 0L [] nb_output 0L + +(* Create the list of inputs. To use once the merkle tree is completed. *) +let make_inputs to_forge local_state proving_ctx sk vk root anti_replay = + List.map_ep + (fun {rcm; position; amount; address; nf} -> + let witness = Tezos_sapling.Storage.get_witness local_state position in + let ar = Tezos_sapling.Core.Client.Proving.ar_random () in + let (cv, rk, proof) = + Tezos_sapling.Core.Client.Proving.spend_proof + proving_ctx + vk + sk + address + rcm + ar + ~amount + ~root + ~witness + in + let signature = + Tezos_sapling.Core.Client.Proving.spend_sig + sk + ar + cv + nf + rk + proof + anti_replay + in + return + Tezos_sapling.Core.Validator.UTXO. + {cv; nf; rk; proof_i = proof; signature}) + to_forge + +let init_fresh_sapling_state ctxt = + let open Protocol.Environment.Error_monad in + Protocol.Lazy_storage_diff.fresh + Protocol.Lazy_storage_kind.Sapling_state + ~temporary:false + ctxt + >>=? fun (ctxt, id) -> + Protocol.Sapling_storage.init ctxt id ~memo_size:0 + (* TODO CHECK *) + >>=? fun ctxt -> return (ctxt, id) + +let generate_spending_and_viewing_keys state = + let sk = + Tezos_sapling.Core.Client.Spending_key.of_seed (random_bytes state 32) + in + let vk = Tezos_sapling.Core.Client.Viewing_key.of_sk sk in + (sk, vk) + +let prepare_seeded_state_internal ~(nb_input : int) ~(nb_nf : int) + ~(nb_cm : int) (ctxt : Raw_context.t) (state : Random.State.t) : + (Sapling_repr.diff + * forge_info list + * Tezos_sapling.Core.Client.Spending_key.t + * Tezos_sapling.Core.Client.Viewing_key.t + * Raw_context.t + * Protocol.Lazy_storage_kind.Sapling_state.Id.t) + tzresult + Lwt.t = + init_fresh_sapling_state ctxt >|= Protocol.Environment.wrap_tzresult + >>=? fun (ctxt, id) -> + let index_start = Tezos_sapling.Core.Client.Viewing_key.default_index in + let (sk, vk) = generate_spending_and_viewing_keys state in + generate_commitments + ~vk + ~nb_input + ~nb_cm + ~nb_nf + ~diff:Protocol.Sapling_storage.empty_diff + ~index:index_start + state + >>=? fun (diff, to_forge) -> + Protocol.Sapling_storage.apply_diff ctxt id diff + >|= Protocol.Environment.wrap_tzresult + >>=? fun (ctxt, _size) -> return (diff, to_forge, sk, vk, ctxt, id) + +let prepare_seeded_state + {state_seed; nullifier_count; commitment_count; sapling_tx} ctxt = + let rng_state = Random.State.make [|Int64.to_int state_seed|] in + prepare_seeded_state_internal + ~nb_input:(List.length sapling_tx.inputs) + ~nb_nf:(Int64.to_int nullifier_count) + ~nb_cm:(Int64.to_int commitment_count) + (alpha_to_raw ctxt) + rng_state + >>=? fun (diff, forge_info, spending_key, viewing_key, raw_ctxt, raw_id) -> + let id = Protocol.Lazy_storage_kind.Sapling_state.Id.unparse_to_z raw_id in + return (diff, forge_info, spending_key, viewing_key, raw_to_alpha raw_ctxt, id) + +let generate ~(nb_input : int) ~(nb_output : int) ~(nb_nf : int) ~(nb_cm : int) + ~(anti_replay : string) ~ctxt state = + assert (nb_input <= nb_cm) ; + assert (nb_nf <= nb_cm - nb_input) ; + prepare_seeded_state_internal ~nb_input ~nb_nf ~nb_cm ctxt state + >>=? fun (diff, to_forge, sk, vk, ctxt, id) -> + let local_state = state_from_rpc_diff diff in + let root = Tezos_sapling.Storage.get_root local_state in + Tezos_sapling.Core.Client.Proving.with_proving_ctx (fun proving_ctx -> + make_inputs to_forge local_state proving_ctx sk vk root anti_replay + >>=? fun inputs -> + let (output_amount, outputs) = outputs nb_output proving_ctx vk in + let input_amount = + List.fold_left + (fun sum {amount; _} -> + assert ( + Int64.compare + sum + (Int64.sub + Int64.max_int + Tezos_sapling.Core.Validator.UTXO.max_amount) + < 0) ; + Int64.add sum amount) + 0L + to_forge + in + let balance = Int64.sub input_amount output_amount in + let binding_sig = + Tezos_sapling.Core.Client.Proving.make_binding_sig + proving_ctx + inputs + outputs + ~balance + anti_replay + in + let transaction = + Tezos_sapling.Core.Validator.UTXO. + {inputs; outputs; binding_sig; balance; root} + in + return transaction) + >>=? fun transaction -> + assert (Compare.List_length_with.(transaction.inputs = nb_input)) ; + assert (Compare.List_length_with.(transaction.outputs = nb_output)) ; + return (transaction, (ctxt, id)) + +(* ------------------------------------------------------------------------- *) +(* Nicely packaging sapling generation for snoop *) + +let sapling_transition_encoding = + let open Data_encoding in + conv + (fun {state_seed; nullifier_count; commitment_count; sapling_tx} -> + (state_seed, nullifier_count, commitment_count, sapling_tx)) + (fun (state_seed, nullifier_count, commitment_count, sapling_tx) -> + {state_seed; nullifier_count; commitment_count; sapling_tx}) + (obj4 + (req "state_seed" int64) + (req "nullifier_count" int64) + (req "commitment_count" int64) + (req "sapling_tx" Alpha_context.Sapling.transaction_encoding)) + +let sapling_dataset_encoding = Data_encoding.list sapling_transition_encoding + +let save ~filename ~txs = + let str = + match Data_encoding.Binary.to_string sapling_dataset_encoding txs with + | Error err -> + Format.eprintf + "Sapling_generation.save: encoding failed (%a); exiting" + Data_encoding.Binary.pp_write_error + err ; + exit 1 + | Ok res -> res + in + ignore (* TODO handle error *) + (Lwt_main.run @@ Tezos_stdlib_unix.Lwt_utils_unix.create_file filename str) + +let load_file filename = + Lwt_main.run + @@ ( Tezos_stdlib_unix.Lwt_utils_unix.read_file filename >>= fun str -> + Format.eprintf "Sapling_generation.load: loaded %s@." filename ; + match Data_encoding.Binary.of_string sapling_dataset_encoding str with + | Ok result -> + let result = List.map (fun tx -> (filename, tx)) result in + Lwt.return result + | Error err -> + Format.eprintf + "Sapling_generation.load: can't load file (%a); exiting" + Data_encoding.Binary.pp_read_error + err ; + exit 1 ) + +let get_all_sapling_data_files directory = + let is_sapling_data file = + let regexp = Str.regexp ".*\\.sapling" in + Str.string_match regexp file 0 + in + let lift file = directory ^ "/" ^ file in + let handle = Unix.opendir directory in + let rec loop acc = + match Unix.readdir handle with + | file -> if is_sapling_data file then loop (lift file :: acc) else loop acc + | exception End_of_file -> + Unix.closedir handle ; + acc + in + loop [] + +let load ~filename = + if not (Sys.file_exists filename) then ( + Format.eprintf "Sapling_generation.load: file does not exist@." ; + Stdlib.failwith "Sapling_generation.load") + else if Sys.is_directory filename then + let () = + Format.eprintf + "Sapling_generation.load: loading all .sapling files from directory \ + %s@." + filename + in + let files = get_all_sapling_data_files filename in + List.concat (List.map load_file files) + else load_file filename + +let shared_seed = [|9798798; 217861209; 876786|] + +let generate (save_to : string) (tx_count : int) + (sapling_gen_options : sapling_gen_options) = + let result = + Lwt_main.run + (let { + max_inputs; + max_outputs; + max_nullifiers; + max_additional_commitments; + seed; + } = + sapling_gen_options + in + let rng_state = + (* /!\ This must match the seed used at benchmark time, + defined in Runner.benchmark_sapling. /!\ *) + Random.State.make + @@ Option.fold ~none:shared_seed ~some:(fun seed -> [|seed|]) seed + in + Execution_context.make ~rng_state >>=? fun (ctxt, step_constants) -> + let address = Alpha_context.Contract.to_b58check step_constants.self in + let chain_id = + Environment.Chain_id.to_b58check step_constants.chain_id + in + let anti_replay = address ^ chain_id in + let ctxt = alpha_to_raw ctxt in + (match sapling_gen_options.seed with + | None -> Random.self_init () + | Some seed -> Random.init seed) ; + let seeds = + Stdlib.List.init tx_count (fun i -> (i, Random.int 0x3FFFFFFF)) + in + let rec loop seeds acc = + match seeds with + | [] -> return acc + | (i, seed) :: tl -> + let nb_input = 1 + Random.int max_inputs in + let nb_output = 1 + Random.int max_outputs in + let nb_nf = 1 + Random.int max_nullifiers in + let nb_cm = + nb_input + nb_nf + Random.int max_additional_commitments + in + let () = + Format.eprintf "@." ; + Format.eprintf "generating sapling tx %i/%d@." (i + 1) tx_count ; + Format.eprintf "saving to file %s@." save_to ; + Format.eprintf "nb_input = %d@." nb_input ; + Format.eprintf "nb_output = %d@." nb_output ; + Format.eprintf "nb_nf = %d@." nb_nf ; + Format.eprintf "nb_cm = %d@." nb_cm ; + Format.eprintf "anti_replay = %s@." anti_replay + in + let state = Random.State.make [|seed|] in + generate + ~nb_input + ~nb_output + ~nb_nf + ~nb_cm + ~anti_replay + ~ctxt + state + >>=? fun (tx, (_ctxt, _state_id)) -> + let result = + { + state_seed = Int64.of_int seed; + nullifier_count = Int64.of_int nb_nf; + commitment_count = Int64.of_int nb_cm; + sapling_tx = Obj.magic tx; + } + in + loop tl (result :: acc) + in + loop seeds []) + in + match result with Ok txs -> save ~filename:save_to ~txs | Error _ -> () + +let apply_diff ctxt id diff = + let open Protocol.Environment.Error_monad in + Sapling_storage.apply_diff (alpha_to_raw ctxt) id diff + >>=? fun (ctxt, size) -> return (raw_to_alpha ctxt, size) diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/script_repr_benchmarks.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/script_repr_benchmarks.ml new file mode 100644 index 000000000000..8409dac0da8f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/script_repr_benchmarks.ml @@ -0,0 +1,143 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** {2 [Script_repr] benchmarks} *) + +module Script_repr_shared_config = struct + type config = unit + + let config_encoding = Data_encoding.unit + + let default_config = () + + type workload = {micheline_nodes : int} + + let workload_encoding = + let open Data_encoding in + conv + (fun {micheline_nodes} -> micheline_nodes) + (fun micheline_nodes -> {micheline_nodes}) + (obj1 (req "micheline_nodes" int31)) + + let tags = [Tags.translator] + + let workload_to_vector {micheline_nodes} = + Sparse_vec.String.of_list [("nodes", float_of_int micheline_nodes)] +end + +module Sampler = Micheline_sampler.Make (struct + type prim = Michelson_v1_primitives.prim + + (* The runtime of the functions in [Script_repr] do not depend on the primitives. *) + let sample_prim : Michelson_v1_primitives.prim Base_samplers.sampler = + fun _rng_state -> I_ADD + + let sample_annots : string list Base_samplers.sampler = fun _rng_state -> [] + + let sample_string = Base_samplers.uniform_string ~nbytes:4 + + let sample_bytes = Base_samplers.uniform_bytes ~nbytes:4 + + let sample_z = Base_samplers.int ~size:{min = 1; max = 8} + + let width_function = Micheline_sampler.reasonable_width_function +end) + +module Micheline_nodes_benchmark : Benchmark.S = struct + include Script_repr_shared_config + + let name = "MICHELINE_NODES" + + let info = + "Benchmarking the time it takes to compute the number of nodes of a \ + Micheline term" + + let size_based_model = + Model.make + ~conv:(function {micheline_nodes} -> (micheline_nodes, ())) + ~model: + (Model.affine + ~intercept: + (Free_variable.of_string (Format.asprintf "%s_const" name)) + ~coeff: + (Free_variable.of_string + (Format.asprintf "%s_ns_per_node_coeff" name))) + + let () = + Registration_helpers.register_for_codegen + name + (Model.For_codegen size_based_model) + + let models = [("size_translator_model", size_based_model)] + + let micheline_nodes_benchmark node = + let nodes = Script_repr.micheline_nodes node in + let workload = {micheline_nodes = nodes} in + let closure () = ignore (Script_repr.micheline_nodes node) in + Generator.Plain {workload; closure} + + let make_bench rng_state _cfg () = + let term = Sampler.sample rng_state in + micheline_nodes_benchmark term + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Micheline_nodes_benchmark) + +module Script_repr_strip_annotations : Benchmark.S = struct + include Script_repr_shared_config + + let name = "strip_annotations" + + let info = "Benchmarking Script_repr.strip_annotations" + + let strip_annotations_model = + Model.( + make + ~conv:(fun {micheline_nodes} -> (micheline_nodes, ())) + ~model:(linear ~coeff:(Free_variable.of_string "nodes"))) + + let () = + Registration_helpers.register_for_codegen + name + (Model.For_codegen strip_annotations_model) + + let models = [("strip_annotations_model", strip_annotations_model)] + + let create_benchmark rng_state () = + let node = Sampler.sample rng_state in + let closure () = ignore @@ Script_repr.strip_annotations node in + let micheline_nodes = Script_repr.micheline_nodes node in + Generator.Plain {workload = {micheline_nodes}; closure} + + let create_benchmarks ~rng_state ~bench_num _cfg = + List.repeat bench_num (create_benchmark rng_state) +end + +let () = Registration_helpers.register (module Script_repr_strip_annotations) diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/script_typed_ir_size_benchmarks.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/script_typed_ir_size_benchmarks.ml new file mode 100644 index 000000000000..69995389360c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/script_typed_ir_size_benchmarks.ml @@ -0,0 +1,338 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** {2 {!Script_typed_ir_size}-related benchmarks} *) + +(** Benchmarking {!Script_typed_ir_size.value_size}. *) + +let model_name = "ir_size_model" + +module Size_benchmarks_shared_config = struct + include Translator_benchmarks.Config + + type workload = {size : int} + + let workload_encoding : workload Data_encoding.t = + let open Data_encoding in + def "size_encoding" + @@ conv (fun {size} -> size) (fun size -> {size}) (obj1 (req "size" int31)) + + let workload_to_vector {size} = + Sparse_vec.String.of_list [("size", float_of_int size)] + + let tags = [Tags.translator] + + let size_based_model name = + let intercept_variable = + Free_variable.of_string (Format.asprintf "%s_const" name) + in + let coeff_variable = + Free_variable.of_string (Format.asprintf "%s_size_coeff" name) + in + Model.make + ~conv:(function {size} -> (size, ())) + ~model:(Model.affine ~intercept:intercept_variable ~coeff:coeff_variable) +end + +module Value_size_benchmark : sig + include Tezos_benchmark.Benchmark.S + + val size_based_model : string -> workload Model.t +end = struct + include Size_benchmarks_shared_config + + let name = "VALUE_SIZE" + + let models = [(model_name, size_based_model name)] + + let info = "Benchmarking Script_typed_ir_size.value_size" + + let value_size_benchmark rng_state (node : Protocol.Script_repr.expr) + (michelson_type : Script_repr.expr) = + (* FIXME: cleanup and factorize this code between translator benches and these ones. *) + let open Translator_benchmarks in + Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + let ex_ty = Type_helpers.michelson_type_to_ex_ty michelson_type ctxt in + match ex_ty with + | Script_ir_translator.Ex_ty ty -> ( + match + Lwt_main.run + (Script_ir_translator.parse_data + ctxt + ~legacy:false + ~allow_forged:false + ty + (Micheline.root node)) + with + | Error _ | (exception _) -> + bad_data name node michelson_type In_protocol + | Ok (value, _) -> + let open Script_typed_ir_size in + let open Cache_memory_helpers in + let size = Nodes.(to_int (fst (value_size ty value))) in + let workload = {size} in + let closure () = ignore (value_size ty value) in + return (Generator.Plain {workload; closure})) ) + |> function + | Ok closure -> closure + | Error errs -> global_error name errs + + let make_bench rng_state cfg () = + let Michelson_mcmc_samplers.{term; typ} = + Michelson_generation.make_data_sampler rng_state cfg.generator_config + in + value_size_benchmark rng_state term typ + + let create_benchmarks ~rng_state ~bench_num config = + match config.michelson_terms_file with + | Some file -> + Format.eprintf "Loading terms from %s@." file ; + let terms = Michelson_mcmc_samplers.load ~filename:file in + List.filter_map + (function + | Michelson_mcmc_samplers.Data {term; typ} -> + Some (fun () -> value_size_benchmark rng_state term typ) + | _ -> None) + terms + | None -> + Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Value_size_benchmark) + +(** Benchmarking {!Script_typed_ir_size.ty_size}. *) + +module Type_size_benchmark : Tezos_benchmark.Benchmark.S = struct + include Size_benchmarks_shared_config + + type config = unit + + let config_encoding = Data_encoding.unit + + let default_config = () + + let name = "TYPE_SIZE" + + let info = + "Benchmarking the time it takes to compute Script_typed_ir_size.ty_size" + + let models = [(model_name, size_based_model name)] + + let type_size_benchmark (Script_ir_translator.Ex_ty ty) = + let open Script_typed_ir_size in + let open Cache_memory_helpers in + let size = Nodes.(to_int (fst (ty_size ty))) in + let workload = {size} in + let closure () = ignore (ty_size ty) in + Generator.Plain {workload; closure} + + let make_bench rng_state _cfg () = + (* The [size] here is a parameter to the random sampler and does not + match the [size] returned by [type_size]. *) + let size = + Base_samplers.sample_in_interval ~range:{min = 1; max = 1000} rng_state + in + let ex_ty = + Michelson_generation.Samplers.Random_type.m_type ~size rng_state + in + type_size_benchmark ex_ty + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Type_size_benchmark) + +(** Benchmarking {!Script_typed_ir_size.comparable_ty_size}. *) + +module Comparable_type_size_benchmark : Tezos_benchmark.Benchmark.S = struct + include Size_benchmarks_shared_config + + let name = "COMPARABLE_TYPE_SIZE" + + let info = + "Benchmarking the time it takes to compute \ + Script_typed_ir_size.comparable_ty_size" + + let models = [(model_name, size_based_model name)] + + let type_size_benchmark (Script_ir_translator.Ex_comparable_ty ty) = + let workload = + let open Script_typed_ir_size in + let open Cache_memory_helpers in + {size = Nodes.to_int @@ fst @@ comparable_ty_size ty} + in + let closure () = ignore (Script_typed_ir_size.comparable_ty_size ty) in + Generator.Plain {workload; closure} + + let make_bench rng_state _cfg () = + (* The [size] here is a parameter to the random sampler and does not + match the [size] returned by [type_size]. *) + let size = + Base_samplers.sample_in_interval ~range:{min = 1; max = 1000} rng_state + in + let ex_ty = + Michelson_generation.Samplers.Random_type.m_comparable_type + ~size + rng_state + in + type_size_benchmark ex_ty + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Comparable_type_size_benchmark) + +(** Benchmarking {!Script_typed_ir_size.kinstr_size}. *) + +module Kinstr_size_benchmark : sig + include Tezos_benchmark.Benchmark.S + + val size_based_model : string -> workload Model.t +end = struct + include Size_benchmarks_shared_config + + let name = "KINSTR_SIZE" + + let models = [(model_name, size_based_model name)] + + let info = "Benchmarking Script_typed_ir_size.kinstr_size" + + let kinstr_size_benchmark rng_state (expr : Protocol.Script_repr.expr) + (stack : Script_repr.expr list) = + (* FIXME: cleanup and factorize this code between translator benches and these ones. *) + let open Translator_benchmarks in + Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + let ex_stack_ty = + Type_helpers.michelson_type_list_to_ex_stack_ty stack ctxt + in + let (Script_ir_translator.Ex_stack_ty bef) = ex_stack_ty in + let node = Micheline.root expr in + match + Lwt_main.run + (Script_ir_translator.parse_instr + Script_ir_translator.Lambda + ctxt + ~legacy:false + node + bef) + with + | Error _ | (exception _) -> bad_code name expr stack In_protocol + | Ok (Failed {descr}, _) -> + let kdescr = Script_ir_translator.close_descr (descr Bot_t) in + let kinstr = kdescr.kinstr in + let workload = + let open Script_typed_ir_size in + let open Cache_memory_helpers in + {size = Nodes.to_int @@ fst @@ kinstr_size kinstr} + in + let closure () = ignore (Script_typed_ir_size.kinstr_size kinstr) in + return (Generator.Plain {workload; closure}) + | Ok (Typed descr, _) -> + let kdescr = Script_ir_translator.close_descr descr in + let kinstr = kdescr.kinstr in + let workload = + let open Script_typed_ir_size in + let open Cache_memory_helpers in + {size = Nodes.to_int @@ fst @@ kinstr_size kinstr} + in + let closure () = ignore (Script_typed_ir_size.kinstr_size kinstr) in + return (Generator.Plain {workload; closure}) ) + |> function + | Ok closure -> closure + | Error errs -> global_error name errs + + let make_bench rng_state cfg () = + let Michelson_mcmc_samplers.{term; bef; aft = _} = + Michelson_generation.make_code_sampler rng_state cfg.generator_config + in + kinstr_size_benchmark rng_state term bef + + let create_benchmarks ~rng_state ~bench_num config = + match config.michelson_terms_file with + | Some file -> + Format.eprintf "Loading terms from %s@." file ; + let terms = Michelson_mcmc_samplers.load ~filename:file in + List.filter_map + (function + | Michelson_mcmc_samplers.Code {term; bef; aft = _} -> + Some (fun () -> kinstr_size_benchmark rng_state term bef) + | _ -> None) + terms + | None -> + Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Kinstr_size_benchmark) + +module Node_size_benchmark : Benchmark.S = struct + include Script_repr_benchmarks.Script_repr_shared_config + + let name = "NODE_SIZE" + + let info = + "Benchmarking the time it takes to compute Script_typed_ir_size.node_size" + + let size_based_model = + Model.make + ~conv:(function {micheline_nodes} -> (micheline_nodes, ())) + ~model: + (Model.affine + ~intercept: + (Free_variable.of_string (Format.asprintf "%s_const" name)) + ~coeff: + (Free_variable.of_string + (Format.asprintf "%s_ns_per_node_coeff" name))) + + let () = + Registration_helpers.register_for_codegen + name + (Model.For_codegen size_based_model) + + let models = [(model_name, size_based_model)] + + let micheline_nodes_benchmark node = + let open Cache_memory_helpers in + let nodes = Nodes.to_int @@ fst @@ node_size node in + let workload = {micheline_nodes = nodes} in + let closure () = ignore (Script_typed_ir_size.node_size node) in + Generator.Plain {workload; closure} + + let make_bench rng_state _cfg () = + let term = Script_repr_benchmarks.Sampler.sample rng_state in + micheline_nodes_benchmark term + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Node_size_benchmark) diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/size.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/size.ml new file mode 100644 index 000000000000..5549702e9aa9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/size.ml @@ -0,0 +1,206 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +type t = int + +type micheline_size = {traversal : t; int_bytes : t; string_bytes : t} + +(* ------------------------------------------------------------------------- *) +(* encoding *) + +let encoding : t Data_encoding.encoding = + let open Data_encoding in + conv (fun i -> Int64.of_int i) (fun l -> Int64.to_int l) int64 + +let micheline_size_encoding : micheline_size Data_encoding.encoding = + let open Data_encoding in + conv + (fun {traversal; int_bytes; string_bytes} -> + (traversal, int_bytes, string_bytes)) + (fun (traversal, int_bytes, string_bytes) -> + {traversal; int_bytes; string_bytes}) + (tup3 encoding encoding encoding) + +(* ------------------------------------------------------------------------- *) + +let zero = 0 + +let one = 1 + +let add = ( + ) + +let sub = ( - ) + +let mul = ( * ) + +let div = ( / ) + +let max x y = if x < y then y else x + +let min x y = if x < y then x else y + +(* can't be bothered to do it well *) +let rec pow x i = if i = 0 then 1 else x * pow x (i - 1) + +module Ops = struct + let ( * ) = mul + + let ( / ) = div + + let ( + ) = add + + let ( - ) = sub + + let ( ** ) = pow +end + +let compare = Stdlib.compare + +let equal = ( = ) + +let lt = ( < ) + +let leq = ( <= ) + +let pp = Format.pp_print_int + +let pp_micheline_size fmtr {traversal; int_bytes; string_bytes} = + Format.fprintf + fmtr + "@[{ traversal = %a;@; int_bytes = %a;@; string_bytes = %a;@,}@]" + pp + traversal + pp + int_bytes + pp + string_bytes + +let show = string_of_int + +let to_float = float_of_int + +let of_float = int_of_float + +let to_int x = x + +let of_int x = x + +let log2 x = Z.log2 (Z.of_int x) + +let unit : t = 1 + +let integer (i : 'a Alpha_context.Script_int.num) : t = + Z.numbits (Alpha_context.Script_int.to_zint i) / 8 + +let string = String.length + +let script_string = Alpha_context.Script_string.length + +let bytes (b : Bytes.t) : t = Bytes.length b + +let mutez (_tez : Alpha_context.Tez.tez) : t = + (* Up to now, mutez are stored on 8 bytes (int64). *) + 8 + +let bool (_ : bool) : t = 1 + +let signature (_signature : Signature.t) : t = Signature.size + +let key_hash (_keyhash : Signature.public_key_hash) : t = + Signature.Public_key_hash.size + +let public_key (public_key : Signature.public_key) : t = + Signature.Public_key.size public_key + +let chain_id (_chain_id : Chain_id.t) : t = Chain_id.size + +let address (addr : Script_typed_ir.address) : t = + let (_contract, entrypoint) = addr in + Signature.Public_key_hash.size + String.length entrypoint + +let list (list : 'a Script_typed_ir.boxed_list) : t = + list.Script_typed_ir.length + +let set (set : 'a Script_typed_ir.set) : t = + let res = Alpha_context.Script_int.to_int (Script_set.size set) in + match res with None -> assert false | Some x -> x + +let map (map : ('a, 'b) Script_typed_ir.map) : t = + let res = Alpha_context.Script_int.to_int (Script_map.size map) in + match res with None -> assert false | Some x -> x + +let timestamp (tstamp : Alpha_context.Script_timestamp.t) : t = + Z.numbits (Alpha_context.Script_timestamp.to_zint tstamp) / 8 + +(* ------------------------------------------------------------------------- *) +(* Micheline/Michelson-related *) + +let micheline_zero = {traversal = 0; int_bytes = 0; string_bytes = 0} + +let ( ++ ) x y = + { + traversal = Ops.(x.traversal + y.traversal); + int_bytes = Ops.(x.int_bytes + y.int_bytes); + string_bytes = Ops.(x.string_bytes + y.string_bytes); + } + +let node leaves = + let r = List.fold_left ( ++ ) micheline_zero leaves in + {r with traversal = Ops.(r.traversal + 1)} + +let rec of_micheline (x : ('a, 'b) Micheline.node) = + match x with + | Micheline.Int (_loc, z) -> + let int_bytes = integer (Alpha_context.Script_int.of_zint z) in + {traversal = 1; int_bytes; string_bytes = 0} + | Micheline.String (_loc, s) -> + let string_bytes = String.length s in + {traversal = 1; int_bytes = 0; string_bytes} + | Micheline.Bytes (_loc, b) -> + let string_bytes = bytes b in + {traversal = 1; int_bytes = 0; string_bytes} + | Micheline.Prim (_loc, _prim, subterms, _annot) -> + node (List.map of_micheline subterms) + | Micheline.Seq (_loc, subterms) -> node (List.map of_micheline subterms) + +let of_encoded_value : + type a. Alpha_context.t -> a Script_typed_ir.ty -> a -> micheline_size = + fun (type a) ctxt (ty : a Script_typed_ir.ty) (v : a) -> + let open Script_ir_translator in + let script_res = Lwt_main.run (unparse_data ctxt Optimized ty v) in + match script_res with + | Ok (node, _ctxt) -> of_micheline node + | Error _ -> Stdlib.failwith "sizeof: could not unparse" + +(* ------------------------------------------------------------------------- *) +(* Sapling-related *) + +let sapling_transaction_inputs : Alpha_context.Sapling.transaction -> t = + fun tx -> List.length tx.Tezos_sapling.Core.Client.UTXO.inputs + +let sapling_transaction_outputs : Alpha_context.Sapling.transaction -> t = + fun tx -> List.length tx.Tezos_sapling.Core.Client.UTXO.outputs diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/tags.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/tags.ml new file mode 100644 index 000000000000..2748e3551ccd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/tags.ml @@ -0,0 +1,32 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let interpreter = "interpreter" + +let translator = "translator" + +let encoding = "encoding" + +let cache = "cache" diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/tezos-benchmarks-proto-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_benchmarks_proto/tezos-benchmarks-proto-012-PsiThaCa.opam new file mode 100644 index 000000000000..f527ccccda6f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/tezos-benchmarks-proto-012-PsiThaCa.opam @@ -0,0 +1,28 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "tezos-tooling" { with-test } + "dune" { >= "2.9" } + "tezos-base" + "tezos-benchmark" + "tezos-benchmark-012-PsiThaCa" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-protocol-012-PsiThaCa-parameters" + "tezos-shell-benchmarks" + "tezos-micheline" + "tezos-012-PsiThaCa-test-helpers" + "tezos-sapling" + "tezos-client-012-PsiThaCa" + +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol benchmarks" diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_benchmarks.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_benchmarks.ml new file mode 100644 index 000000000000..e4a3da4cc86a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_benchmarks.ml @@ -0,0 +1,854 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** {2 [Script_ir_translator] benchmarks} *) + +module Config = struct + type config = { + generator_config : Michelson_generation.generator_config; + michelson_terms_file : string option; + } + + let default_config = + { + generator_config = Michelson_generation.default_generator_config; + michelson_terms_file = None; + } + + let config_encoding = + let open Data_encoding in + conv + (fun {generator_config; michelson_terms_file} -> + (generator_config, michelson_terms_file)) + (fun (generator_config, michelson_terms_file) -> + {generator_config; michelson_terms_file}) + (obj2 + (req "generator_config" Michelson_generation.generator_config_encoding) + (opt "michelson_terms_file" string)) +end + +module Default_boilerplate = struct + type workload = Translator_workload.t + + let workload_encoding = Translator_workload.encoding + + let workload_to_vector = Translator_workload.workload_to_sparse_vec + + let tags = [Tags.translator] + + let make_models t_kind code_or_data = + [ + ( "gas_translator_model", + Translator_model.gas_based_model t_kind code_or_data ); + ( "size_translator_model", + Translator_model.size_based_model t_kind code_or_data ); + ] +end + +(* ----------------------------------------------------------------------- *) +(* Error handling *) + +type phase = Workload_production | In_protocol | Global + +type error_kind = + | Global_error of { + benchmark_name : string; + workload : Tezos_base.TzPervasives.tztrace; + } + | Bad_data of { + benchmark_name : string; + micheline : Alpha_context.Script.expr; + expected_type : Alpha_context.Script.expr; + phase : phase; + } + | Bad_code of { + benchmark_name : string; + micheline : Alpha_context.Script.expr; + expected_stack_type : Alpha_context.Script.expr list; + phase : phase; + } + +let pp_phase fmtr (phase : phase) = + match phase with + | Workload_production -> Format.fprintf fmtr "workload production" + | In_protocol -> Format.fprintf fmtr "in protocol" + | Global -> Format.fprintf fmtr "global" + +let report_michelson_errors fmtr errs = + Michelson_v1_error_reporter.report_errors + ~details:true + ~show_source:true + fmtr + errs + +let make_printable node = + Micheline_printer.printable Michelson_v1_primitives.string_of_prim node + +let pp_error_kind fmtr (error_kind : error_kind) = + match error_kind with + | Global_error {benchmark_name; workload} -> + Format.open_vbox 1 ; + Format.fprintf fmtr "Global error:@," ; + Format.fprintf fmtr "benchmark = %s@," benchmark_name ; + Format.fprintf fmtr "workload:@," ; + report_michelson_errors fmtr workload ; + Format.close_box () + | Bad_data {benchmark_name; micheline; expected_type; phase} -> + Format.open_vbox 1 ; + Format.fprintf fmtr "Bad data:@," ; + Format.fprintf fmtr "benchmark = %s@," benchmark_name ; + Format.fprintf + fmtr + "expression = @[%a@]@," + Micheline_printer.print_expr + (make_printable micheline) ; + Format.fprintf + fmtr + "expected type = @[%a@]@," + Micheline_printer.print_expr + (make_printable expected_type) ; + Format.fprintf fmtr "phase = %a@," pp_phase phase ; + Format.close_box () + | Bad_code {benchmark_name; micheline; expected_stack_type; phase} -> + Format.open_vbox 1 ; + Format.fprintf fmtr "Bad code:@," ; + Format.fprintf fmtr "benchmark = %s@," benchmark_name ; + Format.fprintf + fmtr + "expression = @[%a@]@," + Micheline_printer.print_expr + (make_printable micheline) ; + Format.fprintf + fmtr + "expected stack = @[%a@]@," + (Format.pp_print_list + ~pp_sep:(fun fmtr () -> Format.fprintf fmtr "::") + (fun fmtr node -> + let printable = make_printable node in + Format.fprintf fmtr "%a" Micheline_printer.print_expr printable)) + expected_stack_type ; + Format.fprintf fmtr "phase = %a@," pp_phase phase ; + Format.close_box () + +exception Translator_benchmark_error of error_kind + +let () = + Printexc.register_printer (function + | Translator_benchmark_error err -> + Some (Format.asprintf "%a" pp_error_kind err) + | _ -> None) + +let global_error benchmark_name workload = + raise (Translator_benchmark_error (Global_error {benchmark_name; workload})) + +let bad_data benchmark_name micheline expected_type phase = + raise + (Translator_benchmark_error + (Bad_data {benchmark_name; micheline; expected_type; phase})) + +let bad_code benchmark_name micheline expected_stack_type phase = + raise + (Translator_benchmark_error + (Bad_code {benchmark_name; micheline; expected_stack_type; phase})) + +(* ----------------------------------------------------------------------- *) +(* Typechecking data (Micheline data -> typed data) *) + +module Typechecking_data : Benchmark.S = struct + include Config + include Default_boilerplate + + let models = make_models Translator_workload.Parsing Translator_workload.Data + + let name = "TYPECHECKING_DATA" + + let info = "Benchmarking typechecking of data" + + let typechecking_data_benchmark rng_state (node : Protocol.Script_repr.expr) + (michelson_type : Script_repr.expr) = + Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + let ex_ty = Type_helpers.michelson_type_to_ex_ty michelson_type ctxt in + let workload = + match + Translator_workload.data_typechecker_workload + ctxt + Translator_workload.Parsing + (Micheline.root node) + ex_ty + with + | None -> bad_data name node michelson_type Workload_production + | Some workload -> workload + in + match ex_ty with + | Script_ir_translator.Ex_ty ty -> + let closure () = + match + Lwt_main.run + (Script_ir_translator.parse_data + ctxt + ~legacy:false + ~allow_forged:false + ty + (Micheline.root node)) + with + | Error _ | (exception _) -> + bad_data name node michelson_type In_protocol + | Ok _ -> () + in + return (Generator.Plain {workload; closure}) ) + |> function + | Ok closure -> closure + | Error errs -> global_error name errs + + let make_bench rng_state cfg () = + let Michelson_mcmc_samplers.{term; typ} = + Michelson_generation.make_data_sampler rng_state cfg.generator_config + in + typechecking_data_benchmark rng_state term typ + + let create_benchmarks ~rng_state ~bench_num config = + match config.michelson_terms_file with + | Some file -> + Format.eprintf "Loading terms from %s@." file ; + let terms = Michelson_mcmc_samplers.load ~filename:file in + List.filter_map + (function + | Michelson_mcmc_samplers.Data {term; typ} -> + Some (fun () -> typechecking_data_benchmark rng_state term typ) + | _ -> None) + terms + | None -> + Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Typechecking_data) + +module Unparsing_data : Benchmark.S = struct + include Config + include Default_boilerplate + + let models = + make_models Translator_workload.Unparsing Translator_workload.Data + + let name = "UNPARSING_DATA" + + let info = "Benchmarking unparsing of data" + + let unparsing_data_benchmark rng_state (node : Protocol.Script_repr.expr) + (michelson_type : Protocol.Script_repr.expr) = + Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + let ex_ty = Type_helpers.michelson_type_to_ex_ty michelson_type ctxt in + let workload = + match + Translator_workload.data_typechecker_workload + ctxt + Translator_workload.Unparsing + (Micheline.root node) + ex_ty + with + | None -> bad_data name node michelson_type Workload_production + | Some workload -> workload + in + match ex_ty with + | Script_ir_translator.Ex_ty ty -> + Script_ir_translator.parse_data + ctxt + ~legacy:false + ~allow_forged:false + ty + (Micheline.root node) + >|= Environment.wrap_tzresult + >>=? fun (typed, ctxt) -> + let closure () = + match + Lwt_main.run + (Script_ir_translator.unparse_data + ctxt + Script_ir_translator.Optimized + ty + typed) + with + | Error _ | (exception _) -> + bad_data name node michelson_type In_protocol + | Ok _ -> () + in + return (Generator.Plain {workload; closure}) ) + |> function + | Ok closure -> closure + | Error errs -> global_error name errs + + let make_bench rng_state cfg () = + let Michelson_mcmc_samplers.{term; typ} = + Michelson_generation.make_data_sampler rng_state cfg.generator_config + in + unparsing_data_benchmark rng_state term typ + + let create_benchmarks ~rng_state ~bench_num config = + match config.michelson_terms_file with + | Some file -> + Format.eprintf "Loading terms from %s@." file ; + let terms = Michelson_mcmc_samplers.load ~filename:file in + List.filter_map + (function + | Michelson_mcmc_samplers.Data {term; typ} -> + Some (fun () -> unparsing_data_benchmark rng_state term typ) + | _ -> None) + terms + | None -> + Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Unparsing_data) + +module Typechecking_code : Benchmark.S = struct + include Config + include Default_boilerplate + + let models = make_models Translator_workload.Parsing Translator_workload.Code + + let name = "TYPECHECKING_CODE" + + let info = "Benchmarking typechecking of code" + + let typechecking_code_benchmark rng_state (node : Protocol.Script_repr.expr) + (stack : Script_repr.expr list) = + Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + let ex_stack_ty = + Type_helpers.michelson_type_list_to_ex_stack_ty stack ctxt + in + let workload = + match + Translator_workload.code_typechecker_workload + ctxt + Translator_workload.Parsing + (Micheline.root node) + ex_stack_ty + with + | None -> bad_code name node stack Workload_production + | Some workload -> workload + in + let (Script_ir_translator.Ex_stack_ty bef) = ex_stack_ty in + let closure () = + let result = + Lwt_main.run + (Script_ir_translator.parse_instr + Script_ir_translator.Lambda + ctxt + ~legacy:false + (Micheline.root node) + bef) + in + match Environment.wrap_tzresult result with + | Error errs -> + Format.eprintf "%a@." Error_monad.pp_print_trace errs ; + bad_code name node stack In_protocol + | Ok _ -> () + in + return (Generator.Plain {workload; closure}) ) + |> function + | Ok closure -> closure + | Error errs -> global_error name errs + + let make_bench rng_state (cfg : Config.config) () = + let open Michelson_generation in + let Michelson_mcmc_samplers.{term; bef; aft = _} = + make_code_sampler rng_state cfg.generator_config + in + typechecking_code_benchmark rng_state term bef + + let create_benchmarks ~rng_state ~bench_num config = + match config.michelson_terms_file with + | Some file -> + Format.eprintf "Loading terms from %s@." file ; + let terms = Michelson_mcmc_samplers.load ~filename:file in + List.filter_map + (function + | Michelson_mcmc_samplers.Code {term; bef; aft = _} -> + Some (fun () -> typechecking_code_benchmark rng_state term bef) + | _ -> None) + terms + | None -> + Format.eprintf "No michelson_terms_file given, generating on-the-fly@." ; + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Typechecking_code) + +module Unparsing_code : Benchmark.S = struct + include Config + include Default_boilerplate + + let models = + make_models Translator_workload.Unparsing Translator_workload.Code + + let name = "UNPARSING_CODE" + + let info = "Benchmarking unparsing of code" + + let unparsing_code_benchmark rng_state (node : Protocol.Script_repr.expr) + (stack : Script_repr.expr list) = + Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + let ex_stack_ty = + Type_helpers.michelson_type_list_to_ex_stack_ty stack ctxt + in + let workload = + match + Translator_workload.code_typechecker_workload + ctxt + Translator_workload.Unparsing + (Micheline.root node) + ex_stack_ty + with + | None -> bad_code name node stack Workload_production + | Some workload -> workload + in + let (Script_ir_translator.Ex_stack_ty bef) = ex_stack_ty in + (* We parse the code just to check it is well-typed. *) + Script_ir_translator.parse_instr + Script_ir_translator.Lambda + ctxt + ~legacy:false + (Micheline.root node) + bef + >|= Environment.wrap_tzresult + >>=? fun (_typed, ctxt) -> + let closure () = + let result = + Lwt_main.run + (Script_ir_translator.unparse_code + ctxt + Optimized + (Micheline.root node)) + in + match Environment.wrap_tzresult result with + | Error errs -> + Format.eprintf "%a@." Error_monad.pp_print_trace errs ; + bad_code name node stack In_protocol + | Ok _ -> () + in + return (Generator.Plain {workload; closure}) ) + |> function + | Ok closure -> closure + | Error errs -> global_error name errs + + let make_bench rng_state (cfg : Config.config) () = + let open Michelson_generation in + let Michelson_mcmc_samplers.{term; bef; aft = _} = + make_code_sampler rng_state cfg.generator_config + in + unparsing_code_benchmark rng_state term bef + + let create_benchmarks ~rng_state ~bench_num config = + match config.michelson_terms_file with + | Some file -> + Format.eprintf "Loading terms from %s@." file ; + let terms = Michelson_mcmc_samplers.load ~filename:file in + List.filter_map + (function + | Michelson_mcmc_samplers.Code {term; bef; aft = _} -> + Some (fun () -> unparsing_code_benchmark rng_state term bef) + | _ -> None) + terms + | None -> List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Unparsing_code) + +let rec check_printable_ascii v i = + if Compare.Int.(i < 0) then true + else + match v.[i] with + | '\n' | '\x20' .. '\x7E' -> check_printable_ascii v (i - 1) + | _ -> false + +let check_printable_benchmark = + let open Tezos_shell_benchmarks.Encoding_benchmarks_helpers in + linear_shared + ~name:"CHECK_PRINTABLE" + ~generator:(fun rng_state -> + let open Base_samplers in + let string = + readable_ascii_string rng_state ~size:{min = 1; max = 1024} + in + (string, {Shared_linear.bytes = String.length string})) + ~make_bench:(fun generator () -> + let (generated, workload) = generator () in + let closure () = + ignore (check_printable_ascii generated (String.length generated - 1)) + in + Generator.Plain {workload; closure}) + +let () = Registration_helpers.register check_printable_benchmark + +module Merge_types : Benchmark.S = struct + type config = {max_size : int} + + let config_encoding = + let open Data_encoding in + conv + (fun {max_size} -> max_size) + (fun max_size -> {max_size}) + (obj1 (req "max_size" int31)) + + let default_config = {max_size = 64} + + type workload = Merge_types_workload of {nodes : int; consumed : Size.t} + + let workload_encoding = + let open Data_encoding in + conv + (function Merge_types_workload {nodes; consumed} -> (nodes, consumed)) + (fun (nodes, consumed) -> Merge_types_workload {nodes; consumed}) + (obj2 (req "nodes" int31) (req "consumed" int31)) + + let workload_to_vector = function + | Merge_types_workload {nodes; consumed} -> + Sparse_vec.String.of_list + [("nodes", float_of_int nodes); ("consumed", float_of_int consumed)] + + let name = "MERGE_TYPES" + + let info = "Benchmarking merging of types" + + let tags = [Tags.translator] + + let intercept_var = Free_variable.of_string (Format.asprintf "%s_const" name) + + let coeff_var = Free_variable.of_string (Format.asprintf "%s_coeff" name) + + let size_model = + Model.make + ~conv:(function Merge_types_workload {nodes; _} -> (nodes, ())) + ~model: + (Model.affine_split_const + ~intercept1:Builtin_benchmarks.timer_variable + ~intercept2:intercept_var + ~coeff:coeff_var) + + let codegen_model = + Model.make + ~conv:(function Merge_types_workload {nodes; _} -> (nodes, ())) + ~model:(Model.affine ~intercept:intercept_var ~coeff:coeff_var) + + let () = + Registration_helpers.register_for_codegen + name + (Model.For_codegen codegen_model) + + let models = + [("size_translator_model", size_model); ("codegen", codegen_model)] + + let merge_type_benchmark rng_state nodes (ty : Script_ir_translator.ex_ty) = + let open Error_monad in + Lwt_main.run + ( Execution_context.make ~rng_state >>=? fun (ctxt, _) -> + let ctxt = Gas_helpers.set_limit ctxt in + match ty with + | Ex_ty ty -> + let dummy_loc = 0 in + Lwt.return (Script_ir_translator.ty_eq ctxt dummy_loc ty ty) + >|= Environment.wrap_tzresult + >>=? fun (_, ctxt') -> + let consumed = + Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt' + in + let workload = + Merge_types_workload + {nodes; consumed = Z.to_int (Gas_helpers.fp_to_z consumed)} + in + let closure () = ignore (Script_ir_translator.ty_eq ctxt 0 ty ty) in + return (Generator.Plain {workload; closure}) ) + |> function + | Ok closure -> closure + | Error errs -> global_error name errs + + let make_bench rng_state (cfg : config) () = + let nodes = + Base_samplers.( + sample_in_interval ~range:{min = 1; max = cfg.max_size} rng_state) + in + let ty = + Michelson_generation.Samplers.Random_type.m_type ~size:nodes rng_state + in + merge_type_benchmark rng_state nodes ty + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Merge_types) + +(* A dummy type generator, sampling linear terms of a given size. + The generator always returns types of the shape: + + [pair unit (pair unit (pair unit ...))] + + This structure is the worse-case of the unparsing function for types because + an extra test is performed to determine if the comb type needs to be folded. + *) +let rec dummy_type_generator size = + let open Script_ir_translator in + let open Script_typed_ir in + if size <= 1 then Ex_ty (unit_t ~annot:None) + else + match dummy_type_generator (size - 2) with + | Ex_ty r -> + let l = unit_t ~annot:None in + Ex_ty + (match pair_t (-1) (l, None, None) (r, None, None) ~annot:None with + | Error _ -> assert false + | Ok t -> t) + +(* A dummy comparable type generator, sampling linear terms of a given size. *) +let rec dummy_comparable_type_generator size = + let open Script_ir_translator in + let open Script_typed_ir in + if size <= 0 then Ex_comparable_ty (unit_key ~annot:None) + else + match dummy_comparable_type_generator (size - 2) with + | Ex_comparable_ty r -> + let l = unit_key ~annot:None in + Ex_comparable_ty + (match pair_key (-1) (l, None) (r, None) ~annot:None with + | Error _ -> assert false + | Ok t -> t) + +module Parse_type_shared = struct + type config = {max_size : int} + + let default_config = {max_size = Constants_repr.michelson_maximum_type_size} + + let config_encoding = + let open Data_encoding in + conv + (fun {max_size} -> max_size) + (fun max_size -> {max_size}) + (obj1 (req "max_size" int31)) + + type workload = Type_workload of {nodes : int; consumed : Size.t} + + let workload_encoding = + let open Data_encoding in + conv + (function Type_workload {nodes; consumed} -> (nodes, consumed)) + (fun (nodes, consumed) -> Type_workload {nodes; consumed}) + (obj2 (req "nodes" int31) (req "consumed" int31)) + + let workload_to_vector = function + | Type_workload {nodes; consumed} -> + Sparse_vec.String.of_list + [("nodes", float_of_int nodes); ("consumed", float_of_int consumed)] + + let tags = [Tags.translator] +end + +let parse_ty ctxt node = + Script_ir_translator.parse_ty + ctxt + ~legacy:true + ~allow_lazy_storage:true + ~allow_operation:true + ~allow_contract:true + ~allow_ticket:true + node + +let unparse_ty ctxt ty = Script_ir_translator.unparse_ty ~loc:(-1) ctxt ty + +module Parse_type_benchmark : Benchmark.S = struct + include Parse_type_shared + + let name = "PARSE_TYPE" + + let info = "Benchmarking parse_ty" + + let make_bench rng_state config () = + let open Error_monad in + ( Lwt_main.run (Execution_context.make ~rng_state) >>? fun (ctxt, _) -> + let ctxt = Gas_helpers.set_limit ctxt in + let size = Random.State.int rng_state config.max_size in + let ty = dummy_type_generator size in + match ty with + | Ex_ty ty -> + Environment.wrap_tzresult @@ unparse_ty ctxt ty + >>? fun (unparsed, _) -> + Environment.wrap_tzresult @@ parse_ty ctxt unparsed + >>? fun (_, ctxt') -> + let consumed = + Z.to_int + (Gas_helpers.fp_to_z + (Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt')) + in + let nodes = + let x = Script_typed_ir.ty_size ty in + Saturation_repr.to_int @@ Script_typed_ir.Type_size.to_int x + in + let workload = Type_workload {nodes; consumed} in + let closure () = ignore (parse_ty ctxt unparsed) in + ok (Generator.Plain {workload; closure}) ) + |> function + | Ok closure -> closure + | Error errs -> global_error name errs + + let size_model = + Model.make + ~conv:(function Type_workload {nodes; consumed = _} -> (nodes, ())) + ~model: + (Model.affine + ~intercept: + (Free_variable.of_string (Format.asprintf "%s_const" name)) + ~coeff:(Free_variable.of_string (Format.asprintf "%s_coeff" name))) + + let models = [("size_translator_model", size_model)] + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (make_bench rng_state config) +end + +let () = Registration_helpers.register (module Parse_type_benchmark) + +module Unparse_type_benchmark : Benchmark.S = struct + include Parse_type_shared + + let name = "UNPARSE_TYPE" + + let info = "Benchmarking unparse_ty" + + let make_bench rng_state config () = + let open Error_monad in + ( Lwt_main.run (Execution_context.make ~rng_state) >>? fun (ctxt, _) -> + let ctxt = Gas_helpers.set_limit ctxt in + let size = Random.State.int rng_state config.max_size in + let ty = dummy_type_generator size in + match ty with + | Ex_ty ty -> + Environment.wrap_tzresult @@ unparse_ty ctxt ty >>? fun (_, ctxt') -> + let consumed = + Z.to_int + (Gas_helpers.fp_to_z + (Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt')) + in + let nodes = + let x = Script_typed_ir.ty_size ty in + Saturation_repr.to_int @@ Script_typed_ir.Type_size.to_int x + in + let workload = Type_workload {nodes; consumed} in + let closure () = ignore (unparse_ty ctxt ty) in + ok (Generator.Plain {workload; closure}) ) + |> function + | Ok closure -> closure + | Error errs -> global_error name errs + + let size_model = + Model.make + ~conv:(function Type_workload {nodes; consumed = _} -> (nodes, ())) + ~model: + (Model.affine + ~intercept: + (Free_variable.of_string (Format.asprintf "%s_const" name)) + ~coeff:(Free_variable.of_string (Format.asprintf "%s_coeff" name))) + + let models = [("size_translator_model", size_model)] + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (make_bench rng_state config) + + let () = + Registration_helpers.register_for_codegen + name + (Model.For_codegen size_model) +end + +let () = Registration_helpers.register (module Unparse_type_benchmark) + +module Unparse_comparable_type_benchmark : Benchmark.S = struct + include Parse_type_shared + + let name = "UNPARSE_COMPARABLE_TYPE" + + let info = "Benchmarking unparse_comparable_ty" + + let make_bench rng_state config () = + let open Error_monad in + let res = + Lwt_main.run (Execution_context.make ~rng_state) >>? fun (ctxt, _) -> + let ctxt = Gas_helpers.set_limit ctxt in + let size = Random.State.int rng_state config.max_size in + let ty = dummy_comparable_type_generator size in + let nodes = + let (Script_ir_translator.Ex_comparable_ty ty) = ty in + let x = Script_typed_ir.comparable_ty_size ty in + Saturation_repr.to_int @@ Script_typed_ir.Type_size.to_int x + in + match ty with + | Ex_comparable_ty comp_ty -> + Environment.wrap_tzresult + @@ Script_ir_translator.unparse_comparable_ty ~loc:() ctxt comp_ty + >>? fun (_, ctxt') -> + let consumed = + Z.to_int + (Gas_helpers.fp_to_z + (Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt')) + in + let workload = Type_workload {nodes; consumed} in + let closure () = + ignore + (Script_ir_translator.unparse_comparable_ty ~loc:() ctxt comp_ty) + in + ok (Generator.Plain {workload; closure}) + in + match res with + | Ok closure -> closure + | Error errs -> global_error name errs + + let size_model = + Model.make + ~conv:(function Type_workload {nodes; consumed = _} -> (nodes, ())) + ~model: + (Model.affine + ~intercept: + (Free_variable.of_string (Format.asprintf "%s_const" name)) + ~coeff:(Free_variable.of_string (Format.asprintf "%s_coeff" name))) + + let () = + Registration_helpers.register_for_codegen + name + (Model.For_codegen size_model) + + let models = [("size_translator_model", size_model)] + + let create_benchmarks ~rng_state ~bench_num config = + List.repeat bench_num (make_bench rng_state config) +end + +let () = + Registration_helpers.register (module Unparse_comparable_type_benchmark) diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_model.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_model.ml new file mode 100644 index 000000000000..0bcf6c3b8a20 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_model.ml @@ -0,0 +1,68 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let gas_full t_kind code_or_data = + let name = + Format.asprintf + "%a_%a" + Translator_workload.pp_kind + t_kind + Translator_workload.pp_code_or_data + code_or_data + in + let intercept = Free_variable.of_string (Format.asprintf "%s_const" name) in + let coeff = Free_variable.of_string (Format.asprintf "%s_coeff" name) in + Model.affine ~intercept ~coeff + +let size_full t_kind code_or_data = + let name = + Format.asprintf + "%a_%a" + Translator_workload.pp_kind + t_kind + Translator_workload.pp_code_or_data + code_or_data + in + let coeff1 = Free_variable.of_string (Format.asprintf "%s_traversal" name) in + let coeff2 = Free_variable.of_string (Format.asprintf "%s_int_bytes" name) in + let coeff3 = + Free_variable.of_string (Format.asprintf "%s_string_bytes" name) + in + Model.trilinear ~coeff1 ~coeff2 ~coeff3 + +let gas_based_model t_kind code_or_data = + Model.make + ~conv:(function + | Translator_workload.Typechecker_workload {consumed; _} -> (consumed, ())) + ~model:(gas_full t_kind code_or_data) + +let size_based_model t_kind code_or_data = + Model.make + ~conv:(function + | Translator_workload.Typechecker_workload {micheline_size; _} -> ( + match micheline_size with + | {traversal; int_bytes; string_bytes} -> + (traversal, (int_bytes, (string_bytes, ()))))) + ~model:(size_full t_kind code_or_data) diff --git a/src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_workload.ml b/src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_workload.ml new file mode 100644 index 000000000000..1ba338327374 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_benchmarks_proto/translator_workload.ml @@ -0,0 +1,186 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type kind = Parsing | Unparsing + +type code_or_data = Code | Data + +type t = + | Typechecker_workload of { + t_kind : kind; + code_or_data : code_or_data; + micheline_size : Size.micheline_size; + consumed : Size.t; + } + +let kind_encoding : kind Data_encoding.t = + let open Data_encoding in + def "kind_encoding" + @@ string_enum [("parsing", Parsing); ("unparsing", Unparsing)] + +let code_or_data_encoding : code_or_data Data_encoding.t = + let open Data_encoding in + def "code_or_data_encoding" @@ string_enum [("code", Code); ("data", Data)] + +let encoding : t Data_encoding.t = + let open Data_encoding in + def "translator_trace_encoding" + @@ conv + (function + | Typechecker_workload {t_kind; code_or_data; micheline_size; consumed} + -> + (t_kind, code_or_data, micheline_size, consumed)) + (fun (t_kind, code_or_data, micheline_size, consumed) -> + Typechecker_workload {t_kind; code_or_data; micheline_size; consumed}) + (tup4 + kind_encoding + code_or_data_encoding + Size.micheline_size_encoding + Size.encoding) + +let pp_kind fmtr (kind : kind) = + match kind with + | Parsing -> Format.pp_print_string fmtr "Parsing" + | Unparsing -> Format.pp_print_string fmtr "Unparsing" + +let pp_code_or_data fmtr (x : code_or_data) = + match x with + | Code -> Format.pp_print_string fmtr "Code" + | Data -> Format.pp_print_string fmtr "Data" + +let pp fmtr (trace : t) = + match trace with + | Typechecker_workload {t_kind; code_or_data; micheline_size; consumed} -> + Format.fprintf + fmtr + "typechecker_trace { %a; %a; %a; %a }" + pp_kind + t_kind + pp_code_or_data + code_or_data + Size.pp_micheline_size + micheline_size + Size.pp + consumed + +let workload_to_sparse_vec (trace : t) = + let (name, {Size.traversal; int_bytes; string_bytes}, consumed) = + match trace with + | Typechecker_workload {t_kind; code_or_data; micheline_size; consumed} -> + let name = + Format.asprintf "%a_%a" pp_kind t_kind pp_code_or_data code_or_data + in + (name, micheline_size, consumed) + in + let n s = name ^ "_" ^ s in + let vars = + [ + (n "traversal", Size.to_float traversal); + (n "int_bytes", Size.to_float int_bytes); + (n "string_bytes", Size.to_float string_bytes); + (n "gas", Size.to_float consumed); + ] + in + Sparse_vec.String.of_list vars + +let data_typechecker_workload ctxt t_kind micheline_node ex_ty = + let open Protocol in + match ex_ty with + | Script_ir_translator.Ex_ty ty -> + let ctxt = Gas_helpers.set_limit ctxt in + Lwt_main.run + ( Script_ir_translator.parse_data + ctxt + ~legacy:false + ~allow_forged:false + ty + micheline_node + |> Lwt.map Environment.wrap_tzresult + >>= fun res -> + match res with + | Ok (_res, ctxt_after) -> + let micheline_size = Size.of_micheline micheline_node in + let consumed = + Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt_after + in + let trace = + Typechecker_workload + { + t_kind; + code_or_data = Data; + micheline_size; + consumed = + Size.of_int (Z.to_int (Gas_helpers.fp_to_z consumed)); + } + in + Lwt.return (Some trace) + | Error errors -> + Michelson_v1_error_reporter.report_errors + ~details:true + ~show_source:true + Format.err_formatter + errors ; + Format.eprintf "@." ; + Lwt.return None ) + +let code_typechecker_workload (ctxt : Protocol.Alpha_context.context) + (t_kind : kind) (code : Protocol.Alpha_context.Script.node) + (bef : Protocol.Script_ir_translator.ex_stack_ty) = + let open Protocol in + let ctxt = Gas_helpers.set_limit ctxt in + let (Script_ir_translator.Ex_stack_ty stack_ty) = bef in + Lwt_main.run + ( Script_ir_translator.parse_instr + Script_ir_translator.Lambda + ctxt + ~legacy:false + code + stack_ty + |> Lwt.map Environment.wrap_tzresult + >>= fun res -> + match res with + | Ok (_res, ctxt_after) -> + let micheline_size = Size.of_micheline code in + let consumed = + Alpha_context.Gas.consumed ~since:ctxt ~until:ctxt_after + in + let trace = + Typechecker_workload + { + t_kind; + code_or_data = Code; + micheline_size; + consumed = Size.of_int (Z.to_int (Gas_helpers.fp_to_z consumed)); + } + in + Lwt.return (Some trace) + | Error errs -> + Michelson_v1_error_reporter.report_errors + ~details:true + ~show_source:true + Format.err_formatter + errs ; + Format.eprintf "@." ; + Lwt.return None ) diff --git a/src/proto_012_PsiThaCa/lib_client/.ocamlformat b/src/proto_012_PsiThaCa/lib_client/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_client/annotated_manager_operation.ml b/src/proto_012_PsiThaCa/lib_client/annotated_manager_operation.ml new file mode 100644 index 000000000000..96ce163f5295 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/annotated_manager_operation.ml @@ -0,0 +1,123 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2018-2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type _ t = + | Manager_info : { + source : Alpha_context.public_key_hash option; + fee : Tez.t Limit.t; + gas_limit : Gas.Arith.integral Limit.t; + storage_limit : Z.t Limit.t; + counter : Z.t option; + operation : 'kind manager_operation; + } + -> 'kind t + +type packed = Annotated_manager_operation : 'kind t -> packed + +type _ annotated_list = + | Single_manager : 'kind t -> 'kind annotated_list + | Cons_manager : + 'kind t * 'rest annotated_list + -> ('kind * 'rest) annotated_list + +type packed_annotated_list = + | Manager_list : 'kind annotated_list -> packed_annotated_list + +let rec manager_to_list = function + | Manager_list (Single_manager o) -> [Annotated_manager_operation o] + | Manager_list (Cons_manager (o, os)) -> + Annotated_manager_operation o :: manager_to_list (Manager_list os) + +let rec manager_of_list = function + | [] -> assert false + | [Annotated_manager_operation o] -> Manager_list (Single_manager o) + | Annotated_manager_operation o :: os -> + let (Manager_list os) = manager_of_list os in + Manager_list (Cons_manager (o, os)) + +let join_fee fee operation = + let (Manager_info c) = operation in + Limit.join ~where:__LOC__ Tez.equal fee c.fee >|? fun fee -> + Manager_info {c with fee} + +let set_fee fee (Manager_info c) = Manager_info {c with fee} + +let join_gas_limit gas_limit operation = + let (Manager_info c) = operation in + Limit.join ~where:__LOC__ Gas.Arith.equal gas_limit c.gas_limit + >|? fun gas_limit -> Manager_info {c with gas_limit} + +let set_gas_limit gas_limit (Manager_info c) = Manager_info {c with gas_limit} + +let join_storage_limit storage_limit (Manager_info c) = + Limit.join ~where:__LOC__ Z.equal storage_limit c.storage_limit + >|? fun storage_limit -> Manager_info {c with storage_limit} + +let set_storage_limit storage_limit (Manager_info c) = + Manager_info {c with storage_limit} + +let set_counter counter (Manager_info c) = + match c.counter with + | Some _ -> error_with "set_counter_annot: already set" + | None -> ok (Manager_info {c with counter = Some counter}) + +let set_source source (Manager_info c) = + match c.source with + | Some _ -> error_with "set_source_annot: already set" + | None -> ok (Manager_info {c with source = Some source}) + +let manager_from_annotated operation = + let (Manager_info {source; fee; gas_limit; storage_limit; counter; operation}) + = + operation + in + Limit.get ~when_unknown:"unknown fee" fee >>? fun fee -> + Limit.get ~when_unknown:"unknown gas limit" gas_limit >>? fun gas_limit -> + Limit.get ~when_unknown:"unknown storage limit" storage_limit + >>? fun storage_limit -> + Option.fold + ~some:ok + ~none:(error_with "manager_from_annotated: source not set") + source + >>? fun source -> + Option.fold + ~some:ok + ~none:(error_with "manager_from_annotated: counter not set") + counter + >|? fun counter -> + Manager_operation {source; fee; counter; gas_limit; storage_limit; operation} + +let rec manager_list_from_annotated : + type kind. kind annotated_list -> kind Kind.manager contents_list tzresult = + function + | Single_manager operation -> + manager_from_annotated operation >|? fun op -> Single op + | Cons_manager (operation, rest) -> + manager_list_from_annotated rest >>? fun rest -> + manager_from_annotated operation >|? fun op -> Cons (op, rest) diff --git a/src/proto_012_PsiThaCa/lib_client/annotated_manager_operation.mli b/src/proto_012_PsiThaCa/lib_client/annotated_manager_operation.mli new file mode 100644 index 000000000000..4eebe07b7a59 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/annotated_manager_operation.mli @@ -0,0 +1,98 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2018 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Annotated manager operations are wrappers used to accumulate information + (especially about limits) on the operation prior to the injection. *) + +open Protocol +open Alpha_context + +type _ t = + | Manager_info : { + source : Alpha_context.public_key_hash option; + fee : Tez.t Limit.t; + gas_limit : Gas.Arith.integral Limit.t; + storage_limit : Z.t Limit.t; + counter : Z.t option; + operation : 'kind manager_operation; + } + -> 'kind t + +type packed = Annotated_manager_operation : 'kind t -> packed + +(** The [annotated_list] type helps making + [contents_list] from a list of [manager_operation]s. + Its construction mimics [contents_list] in order to keep + consistent types when calling [inject_manager_operation] + and [inject_operation].*) +type _ annotated_list = + | Single_manager : 'kind t -> 'kind annotated_list + | Cons_manager : + 'kind t * 'rest annotated_list + -> ('kind * 'rest) annotated_list + +type packed_annotated_list = + | Manager_list : 'kind annotated_list -> packed_annotated_list + +(** Convert a list of annotated operations to a list of packed annotated + operations *) +val manager_to_list : packed_annotated_list -> packed list + +(** Converse of [manager_to_list] *) +val manager_of_list : packed list -> packed_annotated_list + +(** [join_fee fee op] updates [op.fee] to [Limit.join op.fee fee] and + fails if the join fails *) +val join_fee : Tez.t Limit.t -> 'a t -> 'a t tzresult + +(** [set_fee fee op] updates [op.fee] to [fee] *) +val set_fee : Tez.t Limit.t -> 'a t -> 'a t + +(** See [join_fee] *) +val join_gas_limit : Gas.Arith.integral Limit.t -> 'a t -> 'a t tzresult + +(** See [set_fee] *) +val set_gas_limit : Gas.Arith.integral Limit.t -> 'a t -> 'a t + +(** See [join_fee] *) +val join_storage_limit : Z.t Limit.t -> 'a t -> 'a t tzresult + +(** See [set_fee] *) +val set_storage_limit : Z.t Limit.t -> 'a t -> 'a t + +(** Set the counter of the annotated operation. Fail if the counter + is already set. *) +val set_counter : counter -> 'a t -> 'a t tzresult + +(** Set the source of the operation. Fail if the source is already set. *) +val set_source : public_key_hash -> 'a t -> 'a t tzresult + +(** Convert an annotated manager operation to a proper manager operation. + Fail if some fields in the annotated operation are not set. *) +val manager_from_annotated : 'a t -> 'a Kind.manager contents tzresult + +val manager_list_from_annotated : + 'kind annotated_list -> 'kind Kind.manager contents_list tzresult diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_args.ml b/src/proto_012_PsiThaCa/lib_client/client_proto_args.ml new file mode 100644 index 000000000000..ef75fd573aa6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_args.ml @@ -0,0 +1,573 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol_client_context +open Protocol +open Alpha_context +open Clic + +type error += Bad_tez_arg of string * string (* Arg_name * value *) + +type error += Bad_max_priority of string + +type error += Bad_minimal_fees of string + +type error += Bad_max_waiting_time of string + +type error += Bad_endorsement_delay of string + +type error += Bad_preserved_levels of string + +let () = + register_error_kind + `Permanent + ~id:"badTezArg" + ~title:"Bad Tez Arg" + ~description:"Invalid \xEA\x9C\xA9 notation in parameter." + ~pp:(fun ppf (arg_name, literal) -> + Format.fprintf + ppf + "Invalid \xEA\x9C\xA9 notation in parameter %s: '%s'" + arg_name + literal) + Data_encoding.(obj2 (req "parameter" string) (req "literal" string)) + (function + | Bad_tez_arg (parameter, literal) -> Some (parameter, literal) + | _ -> None) + (fun (parameter, literal) -> Bad_tez_arg (parameter, literal)) ; + register_error_kind + `Permanent + ~id:"badMaxPriorityArg" + ~title:"Bad -max-priority arg" + ~description:"invalid priority in -max-priority" + ~pp:(fun ppf literal -> + Format.fprintf ppf "invalid priority '%s' in -max-priority" literal) + Data_encoding.(obj1 (req "parameter" string)) + (function Bad_max_priority parameter -> Some parameter | _ -> None) + (fun parameter -> Bad_max_priority parameter) ; + register_error_kind + `Permanent + ~id:"badMinimalFeesArg" + ~title:"Bad -minimal-fees arg" + ~description:"invalid fee threshold in -fee-threshold" + ~pp:(fun ppf literal -> + Format.fprintf ppf "invalid minimal fees '%s'" literal) + Data_encoding.(obj1 (req "parameter" string)) + (function Bad_minimal_fees parameter -> Some parameter | _ -> None) + (fun parameter -> Bad_minimal_fees parameter) ; + register_error_kind + `Permanent + ~id:"badMaxWaitingTimeArg" + ~title:"Bad -max-waiting-time arg" + ~description:"invalid duration in -max-waiting-time" + ~pp:(fun ppf literal -> + Format.fprintf + ppf + "Bad argument value for -max-waiting-time. Expected an integer, but \ + given '%s'" + literal) + Data_encoding.(obj1 (req "parameter" string)) + (function Bad_max_waiting_time parameter -> Some parameter | _ -> None) + (fun parameter -> Bad_max_waiting_time parameter) ; + register_error_kind + `Permanent + ~id:"badEndorsementDelayArg" + ~title:"Bad -endorsement-delay arg" + ~description:"invalid duration in -endorsement-delay" + ~pp:(fun ppf literal -> + Format.fprintf + ppf + "Bad argument value for -endorsement-delay. Expected an integer, but \ + given '%s'" + literal) + Data_encoding.(obj1 (req "parameter" string)) + (function Bad_endorsement_delay parameter -> Some parameter | _ -> None) + (fun parameter -> Bad_endorsement_delay parameter) ; + register_error_kind + `Permanent + ~id:"badPreservedLevelsArg" + ~title:"Bad -preserved-levels arg" + ~description:"invalid number of levels in -preserved-levels" + ~pp:(fun ppf literal -> + Format.fprintf + ppf + "Bad argument value for -preserved_levels. Expected a positive \ + integer, but given '%s'" + literal) + Data_encoding.(obj1 (req "parameter" string)) + (function Bad_preserved_levels parameter -> Some parameter | _ -> None) + (fun parameter -> Bad_preserved_levels parameter) + +let tez_sym = "\xEA\x9C\xA9" + +let string_parameter = parameter (fun _ x -> return x) + +let int_parameter = + parameter (fun _ p -> + try return (int_of_string p) with _ -> failwith "Cannot read int") + +let uri_parameter = parameter (fun _ x -> return (Uri.of_string x)) + +let bytes_of_prefixed_string s = + match + if String.length s < 2 || s.[0] <> '0' || s.[1] <> 'x' then None + else Hex.to_bytes (`Hex (String.sub s 2 (String.length s - 2))) + with + | Some s -> return s + | None -> + failwith "Invalid bytes, expecting hexadecimal notation (e.g. 0x1234abcd)" + +let bytes_parameter = parameter (fun _ s -> bytes_of_prefixed_string s) + +let data_parameter = + parameter (fun _ data -> + Lwt.return @@ Tezos_micheline.Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression data) + +let init_arg = + default_arg + ~long:"init" + ~placeholder:"data" + ~doc:"initial value of the contract's storage" + ~default:"Unit" + string_parameter + +let global_constant_param ~name ~desc next = + Clic.param ~name ~desc string_parameter next + +let arg_arg = + arg + ~long:"arg" + ~placeholder:"data" + ~doc:"argument passed to the contract's script, if needed" + string_parameter + +let default_arg_arg = + arg + ~long:"default-arg" + ~placeholder:"data" + ~doc:"default argument passed to each contract's script, if needed" + string_parameter + +let delegate_arg = + Client_keys.Public_key_hash.source_arg + ~long:"delegate" + ~placeholder:"address" + ~doc:"delegate of the contract\nMust be a known address." + () + +let source_arg = + arg + ~long:"source" + ~placeholder:"address" + ~doc:"source of the deposits to be paid\nMust be a known address." + string_parameter + +let entrypoint_arg = + arg + ~long:"entrypoint" + ~placeholder:"name" + ~doc:"entrypoint of the smart contract" + string_parameter + +let default_entrypoint_arg = + arg + ~long:"default-entrypoint" + ~placeholder:"name" + ~doc:"default entrypoint of the smart contracts" + string_parameter + +let force_switch = + switch + ~long:"force" + ~short:'f' + ~doc: + "disables the node's injection checks\n\ + Force the injection of branch-invalid operation or force the injection \ + of block without a fitness greater than the current head." + () + +let no_endorse_switch = + switch + ~long:"no-endorse" + ~doc:"Do not let the client automatically endorse a block that it baked." + () + +let minimal_timestamp_switch = + switch + ~long:"minimal-timestamp" + ~doc: + "Use the minimal timestamp instead of the current date as timestamp of \ + the baked block." + () + +let tez_format = + "Text format: `DDDDDDD.DDDDDD`.\n\ + Tez and mutez and separated by a period sign. Trailing and pending zeroes \ + are allowed." + +let tez_parameter param = + parameter (fun _ s -> + match Tez.of_string s with + | Some tez -> return tez + | None -> fail (Bad_tez_arg (param, s))) + +let tez_arg ~default ~parameter ~doc = + default_arg + ~long:parameter + ~placeholder:"amount" + ~doc + ~default + (tez_parameter ("--" ^ parameter)) + +let tez_param ~name ~desc next = + Clic.param + ~name + ~desc:(desc ^ " in \xEA\x9C\xA9\n" ^ tez_format) + (tez_parameter name) + next + +let fee_arg = + arg + ~long:"fee" + ~placeholder:"amount" + ~doc:"fee in \xEA\x9C\xA9 to pay to the baker" + (tez_parameter "--fee") + +let default_fee_arg = + arg + ~long:"default-fee" + ~placeholder:"amount" + ~doc:"default fee in \xEA\x9C\xA9 to pay to the baker for each transaction" + (tez_parameter "--default-fee") + +let level_kind = + parameter (fun _ s -> + match Option.bind (Script_int.of_string s) Script_int.is_nat with + | Some n -> return n + | None -> failwith "invalid level (must be a positive number)") + +let level_arg = + arg + ~long:"level" + ~placeholder:"level" + ~doc:"Set the level to be returned by the LEVEL instruction" + level_kind + +let timestamp_parameter = + parameter (fun _ s -> + match Script_timestamp.of_string s with + | Some time -> return time + | None -> + failwith + "invalid timestamp, must be either a RFC 3339 string or a number \ + of seconds since epoch.") + +let now_arg = + arg + ~long:"now" + ~placeholder:"timestamp" + ~doc: + "Set the timestamp to be returned by the NOW instruction. Allowed format \ + are RFC 3339 (YYYY-MM-DDTHH:MM:SSZ) or number of seconds since epoch." + timestamp_parameter + +let gas_limit_kind = + parameter (fun _ s -> + try + let v = Z.of_string s in + return (Gas.Arith.integral_exn v) + with _ -> failwith "invalid gas limit (must be a positive number)") + +let gas_limit_arg = + arg + ~long:"gas-limit" + ~short:'G' + ~placeholder:"amount" + ~doc: + "Set the gas limit of the transaction instead of letting the client \ + decide based on a simulation" + gas_limit_kind + +let default_gas_limit_arg = + arg + ~long:"default-gas-limit" + ~short:'G' + ~placeholder:"amount" + ~doc: + "Set the default gas limit for each transaction instead of letting the \ + client decide based on a simulation" + gas_limit_kind + +let run_gas_limit_arg = + arg + ~long:"gas" + ~short:'G' + ~doc:"Initial quantity of gas for typechecking and execution" + ~placeholder:"gas" + gas_limit_kind + +let storage_limit_kind = + parameter (fun _ s -> + try + let v = Z.of_string s in + assert (Compare.Z.(v >= Z.zero)) ; + return v + with _ -> + failwith "invalid storage limit (must be a positive number of bytes)") + +let storage_limit_arg = + arg + ~long:"storage-limit" + ~short:'S' + ~placeholder:"amount" + ~doc: + "Set the storage limit of the transaction instead of letting the client \ + decide based on a simulation" + storage_limit_kind + +let default_storage_limit_arg = + arg + ~long:"default-storage-limit" + ~short:'S' + ~placeholder:"amount" + ~doc: + "Set the default storage limit for each transaction instead of letting \ + the client decide based on a simulation" + storage_limit_kind + +let counter_arg = + arg + ~long:"counter" + ~short:'C' + ~placeholder:"counter" + ~doc:"Set the counter to be used by the transaction" + (parameter (fun _ s -> + try + let v = Z.of_string s in + assert (Compare.Z.(v >= Z.zero)) ; + return v + with _ -> + failwith "invalid counter (must be a positive number of bytes)")) + +let max_priority_arg = + arg + ~long:"max-priority" + ~placeholder:"slot" + ~doc:"maximum allowed baking slot" + (parameter (fun _ s -> + try return (int_of_string s) with _ -> fail (Bad_max_priority s))) + +let default_minimal_fees = + match Tez.of_mutez 100L with None -> assert false | Some t -> t + +let default_minimal_nanotez_per_gas_unit = Q.of_int 100 + +let default_minimal_nanotez_per_byte = Q.of_int 1000 + +let minimal_fees_arg = + default_arg + ~long:"minimal-fees" + ~placeholder:"amount" + ~doc:"exclude operations with fees lower than this threshold (in tez)" + ~default:(Tez.to_string default_minimal_fees) + (parameter (fun _ s -> + match Tez.of_string s with + | Some t -> return t + | None -> fail (Bad_minimal_fees s))) + +let minimal_nanotez_per_gas_unit_arg = + default_arg + ~long:"minimal-nanotez-per-gas-unit" + ~placeholder:"amount" + ~doc: + "exclude operations with fees per gas lower than this threshold (in \ + nanotez)" + ~default:(Q.to_string default_minimal_nanotez_per_gas_unit) + (parameter (fun _ s -> + try return (Q.of_string s) with _ -> fail (Bad_minimal_fees s))) + +let minimal_nanotez_per_byte_arg = + default_arg + ~long:"minimal-nanotez-per-byte" + ~placeholder:"amount" + ~default:(Q.to_string default_minimal_nanotez_per_byte) + ~doc: + "exclude operations with fees per byte lower than this threshold (in \ + nanotez)" + (parameter (fun _ s -> + try return (Q.of_string s) with _ -> fail (Bad_minimal_fees s))) + +let force_low_fee_arg = + switch + ~long:"force-low-fee" + ~doc:"Don't check that the fee is lower than the estimated default value" + () + +let fee_cap_arg = + default_arg + ~long:"fee-cap" + ~placeholder:"amount" + ~default:"1.0" + ~doc:"Set the fee cap" + (parameter (fun _ s -> + match Tez.of_string s with + | Some t -> return t + | None -> failwith "Bad fee cap")) + +let burn_cap_arg = + default_arg + ~long:"burn-cap" + ~placeholder:"amount" + ~default:"0" + ~doc:"Set the burn cap" + (parameter (fun _ s -> + match Tez.of_string s with + | Some t -> return t + | None -> failwith "Bad burn cap")) + +let no_waiting_for_endorsements_arg = + switch + ~long:"no-waiting-for-late-endorsements" + ~doc:"Disable waiting for late endorsements" + () + +let await_endorsements_arg = + switch + ~long:"await-late-endorsements" + ~doc:"Await late endorsements when baking a block" + () + +let endorsement_delay_arg = + default_arg + ~long:"endorsement-delay" + ~placeholder:"seconds" + ~doc: + "delay before endorsing blocks\n\ + Delay between notifications of new blocks from the node and production \ + of endorsements for these blocks." + ~default:"0" + (parameter (fun _ s -> + try + let i = int_of_string s in + fail_when (i < 0) (Bad_endorsement_delay s) >>=? fun () -> + return (int_of_string s) + with _ -> fail (Bad_endorsement_delay s))) + +let preserved_levels_arg = + arg + ~long:"preserved-levels" + ~placeholder:"threshold" + ~doc:"Number of effective levels kept in the accuser's memory" + (parameter (fun _ s -> + try + let preserved_cycles = int_of_string s in + if preserved_cycles < 0 then fail (Bad_preserved_levels s) + else return preserved_cycles + with _ -> fail (Bad_preserved_levels s))) + +let no_print_source_flag = + switch + ~long:"no-print-source" + ~short:'q' + ~doc: + "don't print the source code\n\ + If an error is encountered, the client will print the contract's source \ + code by default.\n\ + This option disables this behaviour." + () + +let no_confirmation = + switch + ~long:"no-confirmation" + ~doc:"don't print wait for the operation to be confirmed." + () + +let signature_parameter = + parameter (fun _cctxt s -> + match Signature.of_b58check_opt s with + | Some s -> return s + | None -> failwith "Not given a valid signature") + +let unparsing_mode_parameter = + parameter + ~autocomplete:(fun _cctxt -> + return ["Readable"; "Optimized"; "Optimized_legacy"]) + (fun _cctxt s -> + match s with + | "Readable" -> return Script_ir_translator.Readable + | "Optimized" -> return Script_ir_translator.Optimized + | "Optimized_legacy" -> return Script_ir_translator.Optimized_legacy + | _ -> failwith "Unknown unparsing mode %s" s) + +let unparsing_mode_arg ~default = + default_arg + ~long:"unparsing-mode" + ~placeholder:"mode" + ~doc: + "Unparsing mode to use\n\ + One of \"Readable\", \"Optimized\", or \"Optimized_legacy\".\n\ + This option affects the way the values of the following Michelson types \ + are represented:\n\ + - timestamp: the Readable representation is a RFC3339 string, the \ + Optimized and Optimized_legacy representations are the number of \ + seconds since Epoch\n\ + - key, signature, key_hash, address, contract, chain_id: the Readable \ + representation is a Base58Check string, the Optimized and \ + Optimized_legacy representations are byte sequences\n\ + - nested pairs: in Readable mode, the Pair constructor is used even \ + with arity bigger than 2 such as in Pair 0 1 2; in Optimized_legacy \ + mode, the Pair constructor is always use with arity 2 such as in Pair 0 \ + (Pair 1 2); in Optimized mode, a sequence is used if there are at least \ + 4 elements and the behavior is the same as in Optimized_legacy mode \ + otherwise.\n" + ~default + unparsing_mode_parameter + +let enforce_indentation_flag = + switch + ~long:"enforce-indentation" + ~doc: + "Check that the Micheline expression passed to this command is \ + well-indented." + () + +let display_names_flag = + switch + ~long:"display-names" + ~doc:"Print names of scripts passed to this command" + () + +module Daemon = struct + let baking_switch = + switch ~long:"baking" ~short:'B' ~doc:"run the baking daemon" () + + let endorsement_switch = + switch ~long:"endorsement" ~short:'E' ~doc:"run the endorsement daemon" () + + let denunciation_switch = + switch ~long:"denunciation" ~short:'D' ~doc:"run the denunciation daemon" () +end diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_args.mli b/src/proto_012_PsiThaCa/lib_client/client_proto_args.mli new file mode 100644 index 000000000000..0a57c66874ac --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_args.mli @@ -0,0 +1,141 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Protocol_client_context + +val tez_sym : string + +val init_arg : (string, full) Clic.arg + +val fee_arg : (Tez.t option, full) Clic.arg + +val default_fee_arg : (Tez.t option, full) Clic.arg + +val counter_arg : (Z.t option, full) Clic.arg + +val gas_limit_arg : (Gas.Arith.integral option, full) Clic.arg + +val default_gas_limit_arg : (Gas.Arith.integral option, full) Clic.arg + +val run_gas_limit_arg : (Gas.Arith.integral option, full) Clic.arg + +val storage_limit_arg : (Z.t option, full) Clic.arg + +val default_storage_limit_arg : (Z.t option, full) Clic.arg + +val arg_arg : (string option, full) Clic.arg + +val default_arg_arg : (string option, full) Clic.arg + +val source_arg : (string option, full) Clic.arg + +val entrypoint_arg : (string option, full) Clic.arg + +val default_entrypoint_arg : (string option, full) Clic.arg + +val delegate_arg : (Signature.Public_key_hash.t option, full) Clic.arg + +val max_priority_arg : (int option, full) Clic.arg + +val minimal_fees_arg : (Tez.tez, full) Clic.arg + +val minimal_nanotez_per_gas_unit_arg : (Q.t, full) Clic.arg + +val minimal_nanotez_per_byte_arg : (Q.t, full) Clic.arg + +val force_low_fee_arg : (bool, full) Clic.arg + +val fee_cap_arg : (Tez.t, full) Clic.arg + +val burn_cap_arg : (Tez.t, full) Clic.arg + +val no_waiting_for_endorsements_arg : (bool, full) Clic.arg + +val await_endorsements_arg : (bool, full) Clic.arg + +val force_switch : (bool, full) Clic.arg + +val no_endorse_switch : (bool, full) Clic.arg + +val minimal_timestamp_switch : (bool, full) Clic.arg + +val endorsement_delay_arg : (int, full) Clic.arg + +val preserved_levels_arg : (int option, full) Clic.arg + +val no_print_source_flag : (bool, full) Clic.arg + +val no_confirmation : (bool, full) Clic.arg + +val tez_arg : + default:string -> parameter:string -> doc:string -> (Tez.t, full) Clic.arg + +val tez_param : + name:string -> + desc:string -> + ('a, full) Clic.params -> + (Tez.t -> 'a, full) Clic.params + +val global_constant_param : + name:string -> + desc:string -> + ('a, full) Clic.params -> + (string -> 'a, full) Clic.params + +val signature_parameter : (Signature.t, full) Clic.parameter + +module Daemon : sig + val baking_switch : (bool, full) Clic.arg + + val endorsement_switch : (bool, full) Clic.arg + + val denunciation_switch : (bool, full) Clic.arg +end + +val int_parameter : (int, full) Clic.parameter + +val uri_parameter : (Uri.t, full) Clic.parameter + +val string_parameter : (string, full) Clic.parameter + +val bytes_of_prefixed_string : string -> Bytes.t tzresult Lwt.t + +val bytes_parameter : (Bytes.t, full) Clic.parameter + +val data_parameter : (Michelson_v1_parser.parsed, full) Clic.parameter + +val unparsing_mode_arg : + default:string -> (Script_ir_translator.unparsing_mode, full) Clic.arg + +val enforce_indentation_flag : (bool, full) Clic.arg + +val display_names_flag : (bool, full) Clic.arg + +val level_arg : (Script_int.n Script_int.num option, full) Clic.arg + +val now_arg : (Script_timestamp.t option, full) Clic.arg diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_context.ml b/src/proto_012_PsiThaCa/lib_client/client_proto_context.ml new file mode 100644 index 000000000000..d55e8eb9f321 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_context.ml @@ -0,0 +1,747 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Protocol_client_context +open Tezos_micheline +open Client_proto_contracts +open Client_keys + +let get_balance (rpc : #rpc_context) ~chain ~block contract = + Alpha_services.Contract.balance rpc (chain, block) contract + +let get_storage (rpc : #rpc_context) ~chain ~block ~unparsing_mode contract = + Plugin.RPC.Contract.get_storage_normalized + rpc + (chain, block) + ~unparsing_mode + ~contract + +let get_big_map_value (rpc : #rpc_context) ~chain ~block ~unparsing_mode id key + = + Plugin.RPC.Big_map.big_map_get_normalized + rpc + (chain, block) + ~unparsing_mode + id + key + +let get_contract_big_map_value (rpc : #rpc_context) ~chain ~block contract key = + Alpha_services.Contract.contract_big_map_get_opt + rpc + (chain, block) + contract + key + +let get_script (rpc : #rpc_context) ~chain ~block ~unparsing_mode contract = + Plugin.RPC.Contract.get_script_normalized + rpc + (chain, block) + ~unparsing_mode + ~contract + +let get_script_hash (rpc : #rpc_context) ~chain ~block contract = + Alpha_services.Contract.script_opt rpc (chain, block) contract + >>=? fun script_opt -> + Lwt.return @@ Environment.wrap_tzresult + @@ Option.map_e + (fun {Script.code; storage = _} -> + Script_repr.force_decode code >>? fun code -> + let bytes = + Data_encoding.Binary.to_bytes_exn Script.expr_encoding code + in + let hash = Script_expr_hash.hash_bytes [bytes] in + ok hash) + script_opt + +let get_frozen_deposits_limit (rpc : #rpc_context) ~chain ~block delegate = + Alpha_services.Delegate.frozen_deposits_limit rpc (chain, block) delegate + +let parse_expression arg = + Lwt.return + (Micheline_parser.no_parsing_error + (Michelson_v1_parser.parse_expression arg)) + +let parse_arg_transfer arg = + (match arg with + | Some arg -> + parse_expression arg >>=? fun {expanded = arg; _} -> return_some arg + | None -> return_none) + >>=? fun parameters -> + return + (Option.fold ~some:Script.lazy_expr ~none:Script.unit_parameter parameters) + +let build_transaction_operation ~amount ~parameters ?(entrypoint = "default") + ?fee ?gas_limit ?storage_limit destination = + let operation = Transaction {amount; parameters; destination; entrypoint} in + Injection.prepare_manager_operation + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + operation + +let transfer (cctxt : #full) ~chain ~block ?confirmations ?dry_run + ?verbose_signing ?simulation ?branch ~source ~src_pk ~src_sk ~destination + ?(entrypoint = "default") ?arg ~amount ?fee ?gas_limit ?storage_limit + ?counter ~fee_parameter () = + parse_arg_transfer arg >>=? fun parameters -> + let contents = + build_transaction_operation + ~amount + ~parameters + ~entrypoint + ?fee + ?gas_limit + ?storage_limit + destination + in + let contents = Annotated_manager_operation.Single_manager contents in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?simulation + ?branch + ~source + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + ?counter + ~src_pk + ~src_sk + ~fee_parameter + contents + >>=? fun (oph, op, result) -> + Lwt.return (Injection.originated_contracts result) >>=? fun contracts -> + match Apply_results.pack_contents_list op result with + | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> + return ((oph, op, result), contracts) + +let build_reveal_operation ?fee ?gas_limit ?storage_limit pk = + let operation = Reveal pk in + Injection.prepare_manager_operation + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + operation + +let reveal cctxt ~chain ~block ?confirmations ?dry_run ?verbose_signing ?branch + ~source ~src_pk ~src_sk ?fee ~fee_parameter () = + let contents = + Annotated_manager_operation.Single_manager + (build_reveal_operation ?fee ~storage_limit:Z.zero src_pk) + in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?branch + ~source + ~fee:(Limit.of_option fee) + ~gas_limit:Limit.unknown + ~storage_limit:Limit.unknown + ~src_pk + ~src_sk + ~fee_parameter + contents + >>=? fun (oph, op, result) -> + match Apply_results.pack_contents_list op result with + | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> + return (oph, op, result) + +let build_delegate_operation ?fee ?gas_limit ?storage_limit delegate_opt = + let operation = Delegation delegate_opt in + Injection.prepare_manager_operation + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + operation + +let delegate_contract cctxt ~chain ~block ?branch ?confirmations ?dry_run + ?verbose_signing ?simulation ~source ~src_pk ~src_sk ?fee ~fee_parameter + delegate_opt = + let operation = + Annotated_manager_operation.Single_manager + (build_delegate_operation ?fee delegate_opt) + in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?simulation + ?branch + ~source + ~fee:(Limit.of_option fee) + ~gas_limit:Limit.unknown + ~storage_limit:Limit.unknown + ~src_pk + ~src_sk + ~fee_parameter + operation + >>=? fun (oph, op, result) -> + match Apply_results.pack_contents_list op result with + | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> + return (oph, op, result) + +let list_contract_labels cctxt ~chain ~block = + Alpha_services.Contract.list cctxt (chain, block) >>=? fun contracts -> + List.rev_map_es + (fun h -> + (match Contract.is_implicit h with + | Some m -> ( + Public_key_hash.rev_find cctxt m >>=? function + | None -> return "" + | Some nm -> ( + RawContractAlias.find_opt cctxt nm >>=? function + | None -> return (" (known as " ^ nm ^ ")") + | Some _ -> return (" (known as key:" ^ nm ^ ")"))) + | None -> ( + RawContractAlias.rev_find cctxt h >>=? function + | None -> return "" + | Some nm -> return (" (known as " ^ nm ^ ")"))) + >>=? fun nm -> + let kind = + match Contract.is_implicit h with Some _ -> " (implicit)" | None -> "" + in + let h_b58 = Contract.to_b58check h in + return (nm, h_b58, kind)) + contracts + >|=? List.rev + +let message_added_contract (cctxt : #full) name = + cctxt#message "Contract memorized as %s." name + +let set_delegate cctxt ~chain ~block ?confirmations ?dry_run ?verbose_signing + ?simulation ?fee contract ~src_pk ~manager_sk ~fee_parameter opt_delegate = + delegate_contract + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?simulation + ~source:contract + ~src_pk + ~src_sk:manager_sk + ?fee + ~fee_parameter + opt_delegate + +let register_as_delegate cctxt ~chain ~block ?confirmations ?dry_run + ?verbose_signing ?fee ~manager_sk ~fee_parameter src_pk = + let source = Signature.Public_key.hash src_pk in + delegate_contract + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ~source + ~src_pk + ~src_sk:manager_sk + ?fee + ~fee_parameter + (Some source) + +let set_deposits_limit cctxt ~chain ~block ?confirmations ?dry_run + ?verbose_signing ?simulation ?fee contract ~src_pk ~manager_sk + ~fee_parameter limit_opt = + let operation = Set_deposits_limit limit_opt in + let operation = + Injection.prepare_manager_operation + ~fee:(Limit.of_option fee) + ~gas_limit:Limit.unknown + ~storage_limit:Limit.unknown + operation + in + let operation = Annotated_manager_operation.Single_manager operation in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?simulation + ~source:contract + ~fee:(Limit.of_option fee) + ~gas_limit:Limit.unknown + ~storage_limit:Limit.unknown + ~src_pk + ~src_sk:manager_sk + ~fee_parameter + operation + >>=? fun (oph, op, result) -> + match Apply_results.pack_contents_list op result with + | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> + return (oph, op, result) + +let save_contract ~force cctxt alias_name contract = + RawContractAlias.add ~force cctxt alias_name contract >>=? fun () -> + message_added_contract cctxt alias_name >>= fun () -> return_unit + +let build_origination_operation ?fee ?gas_limit ?storage_limit ~initial_storage + ~code ~delegate ~balance () = + (* With the change of making implicit accounts delegatable, the following + 3 arguments are being defaulted before they can be safely removed. *) + Lwt.return (Michelson_v1_parser.parse_expression initial_storage) + >>= fun result -> + Lwt.return (Micheline_parser.no_parsing_error result) + >>=? fun {Michelson_v1_parser.expanded = storage; _} -> + let code = Script.lazy_expr code and storage = Script.lazy_expr storage in + let origination = + Origination + { + delegate; + script = {code; storage}; + credit = balance; + preorigination = None; + } + in + return + (Injection.prepare_manager_operation + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + origination) + +let originate_contract (cctxt : #full) ~chain ~block ?confirmations ?dry_run + ?verbose_signing ?branch ?fee ?gas_limit ?storage_limit ~delegate + ~initial_storage ~balance ~source ~src_pk ~src_sk ~code ~fee_parameter () = + build_origination_operation + ?fee + ?gas_limit + ?storage_limit + ~initial_storage + ~code + ~delegate + ~balance + () + >>=? fun origination -> + let origination = Annotated_manager_operation.Single_manager origination in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?branch + ~source + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + ~src_pk + ~src_sk + ~fee_parameter + origination + >>=? fun (oph, op, result) -> + (match Apply_results.pack_contents_list op result with + | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> + return (oph, op, result)) + >>=? fun res -> + Lwt.return (Injection.originated_contracts result) >>=? function + | [contract] -> return (res, contract) + | contracts -> + failwith + "The origination introduced %d contracts instead of one." + (List.length contracts) + +let michelson_expression_of_string str = + Michelson_v1_parser.parse_expression str |> Micheline_parser.no_parsing_error + >>? fun {Michelson_v1_parser.expanded = v; _} -> ok @@ Script.lazy_expr v + +let build_register_global_constant ?fee ?gas_limit ?storage_limit value = + michelson_expression_of_string value >>? fun value -> + let op = Register_global_constant {value} in + ok + (Injection.prepare_manager_operation + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + op) + +let register_global_constant (cctxt : #full) ~chain ~block ?confirmations + ?dry_run ?verbose_signing ?simulation ?fee ?gas_limit ?storage_limit + ?counter ~source ~src_pk ~src_sk ~fee_parameter ~constant () = + build_register_global_constant ?fee ?storage_limit ?gas_limit constant + >>?= fun op -> + let op = Annotated_manager_operation.Single_manager op in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?simulation + ?counter + ~source + ~fee:(Limit.of_option fee) + ~storage_limit:(Limit.of_option storage_limit) + ~gas_limit:(Limit.of_option gas_limit) + ~src_pk + ~src_sk + ~fee_parameter + op + >>=? fun (oph, op, result) -> + match Apply_results.pack_contents_list op result with + | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> + return (oph, op, result) + +type activation_key = { + pkh : Ed25519.Public_key_hash.t; + amount : Tez.t; + activation_code : Blinded_public_key_hash.activation_code; + mnemonic : string list; + password : string; + email : string; +} + +let raw_activation_key_encoding = + let open Data_encoding in + obj6 + (req "pkh" Ed25519.Public_key_hash.encoding) + (req "amount" Tez.encoding) + (req "activation_code" Blinded_public_key_hash.activation_code_encoding) + (req "mnemonic" (list string)) + (req "password" string) + (req "email" string) + +let activation_key_encoding = + (* Hack: allow compatibility with older encoding *) + let open Data_encoding in + conv + (fun {pkh; amount; activation_code; mnemonic; password; email} -> + (pkh, amount, activation_code, mnemonic, password, email)) + (fun (pkh, amount, activation_code, mnemonic, password, email) -> + {pkh; amount; activation_code; mnemonic; password; email}) + @@ splitted + ~binary:raw_activation_key_encoding + ~json: + (union + [ + case + ~title:"Activation" + Json_only + raw_activation_key_encoding + (fun x -> Some x) + (fun x -> x); + case + ~title:"Deprecated_activation" + Json_only + (obj6 + (req "pkh" Ed25519.Public_key_hash.encoding) + (req "amount" Tez.encoding) + (req + "secret" + Blinded_public_key_hash.activation_code_encoding) + (req "mnemonic" (list string)) + (req "password" string) + (req "email" string)) + (fun _ -> None) + (fun x -> x); + ]) + +type batch_transfer_operation = { + destination : string; + fee : string option; + gas_limit : Gas.Arith.integral option; + storage_limit : Z.t option; + amount : string; + arg : string option; + entrypoint : string option; +} + +let batch_transfer_operation_encoding = + let open Data_encoding in + conv + (fun {destination; fee; gas_limit; storage_limit; amount; arg; entrypoint} -> + (destination, fee, gas_limit, storage_limit, amount, arg, entrypoint)) + (fun (destination, fee, gas_limit, storage_limit, amount, arg, entrypoint) -> + {destination; fee; gas_limit; storage_limit; amount; arg; entrypoint}) + (obj7 + (req "destination" string) + (opt "fee" string) + (opt "gas-limit" Gas.Arith.n_integral_encoding) + (opt "storage-limit" z) + (req "amount" string) + (opt "arg" string) + (opt "entrypoint" string)) + +let read_key key = + match Bip39.of_words key.mnemonic with + | None -> failwith "" + | Some t -> + (* TODO: unicode normalization (NFKD)... *) + let passphrase = + Bytes.(cat (of_string key.email) (of_string key.password)) + in + let sk = Bip39.to_seed ~passphrase t in + let sk = Bytes.sub sk 0 32 in + let sk : Signature.Secret_key.t = + Ed25519 + (Data_encoding.Binary.of_bytes_exn Ed25519.Secret_key.encoding sk) + in + let pk = Signature.Secret_key.to_public_key sk in + let pkh = Signature.Public_key.hash pk in + return (pkh, pk, sk) + +let inject_activate_operation cctxt ~chain ~block ?confirmations ?dry_run alias + pkh activation_code = + let contents = Single (Activate_account {id = pkh; activation_code}) in + Injection.inject_operation + cctxt + ?confirmations + ?dry_run + ~chain + ~block + ~fee_parameter:Injection.dummy_fee_parameter + contents + >>=? fun (oph, op, result) -> + (match confirmations with + | None -> return_unit + | Some _confirmations -> + Alpha_services.Contract.balance + cctxt + (chain, block) + (Contract.implicit_contract (Ed25519 pkh)) + >>=? fun balance -> + cctxt#message + "Account %s (%a) activated with %s%a." + alias + Ed25519.Public_key_hash.pp + pkh + Client_proto_args.tez_sym + Tez.pp + balance + >>= fun () -> return_unit) + >>=? fun () -> + match Apply_results.pack_contents_list op result with + | Apply_results.Single_and_result ((Activate_account _ as op), result) -> + return (oph, op, result) + +let activate_account (cctxt : #full) ~chain ~block ?confirmations ?dry_run + ?(encrypted = false) ?force key name = + read_key key >>=? fun (pkh, pk, sk) -> + fail_unless + (Signature.Public_key_hash.equal pkh (Ed25519 key.pkh)) + (error_of_fmt + "@[Inconsistent activation key:@ Computed pkh: %a@ Embedded pkh: \ + %a @]" + Signature.Public_key_hash.pp + pkh + Ed25519.Public_key_hash.pp + key.pkh) + >>=? fun () -> + Tezos_signer_backends.Unencrypted.make_pk pk >>?= fun pk_uri -> + (if encrypted then + Tezos_signer_backends.Encrypted.prompt_twice_and_encrypt cctxt sk + else Tezos_signer_backends.Unencrypted.make_sk sk >>?= return) + >>=? fun sk_uri -> + Client_keys.register_key cctxt ?force (pkh, pk_uri, sk_uri) name + >>=? fun () -> + inject_activate_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + name + key.pkh + key.activation_code + +let activate_existing_account (cctxt : #full) ~chain ~block ?confirmations + ?dry_run alias activation_code = + Client_keys.alias_keys cctxt alias >>=? function + | Some (Ed25519 pkh, _, _) -> + inject_activate_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + alias + pkh + activation_code + | Some _ -> failwith "Only Ed25519 accounts can be activated" + | None -> failwith "Unknown account" + +type period_info = { + current_period_kind : Voting_period.kind; + position : Int32.t; + remaining : Int32.t; + current_proposal : Protocol_hash.t option; +} + +type ballots_info = { + current_quorum : Int32.t; + participation : Int32.t; + supermajority : Int32.t; + ballots : Vote.ballots; +} + +let get_ballots_info (cctxt : #full) ~chain ~block = + (* Get the next level, not the current *) + let cb = (chain, block) in + Alpha_services.Voting.ballots cctxt cb >>=? fun ballots -> + Alpha_services.Voting.current_quorum cctxt cb >>=? fun current_quorum -> + Alpha_services.Voting.listings cctxt cb >>=? fun listings -> + let max_participation = + List.fold_left (fun acc (_, w) -> Int32.add w acc) 0l listings + in + let all_votes = Int32.(add (add ballots.yay ballots.nay) ballots.pass) in + let participation = Int32.(div (mul all_votes 100_00l) max_participation) in + let supermajority = Int32.(div (mul 8l (add ballots.yay ballots.nay)) 10l) in + return {current_quorum; participation; supermajority; ballots} + +let get_period_info ?(successor = false) (cctxt : #full) ~chain ~block = + let cb = (chain, block) in + (if successor then Alpha_services.Voting.successor_period + else Alpha_services.Voting.current_period) + cctxt + cb + >>=? fun voting_period -> + Alpha_services.Voting.current_proposal cctxt cb >>=? fun current_proposal -> + return + { + current_period_kind = voting_period.voting_period.kind; + position = voting_period.position; + remaining = voting_period.remaining; + current_proposal; + } + +let get_proposals (cctxt : #full) ~chain ~block = + let cb = (chain, block) in + Alpha_services.Voting.proposals cctxt cb + +let submit_proposals ?dry_run ?verbose_signing (cctxt : #full) ~chain ~block + ?confirmations ~src_sk source proposals = + Alpha_services.Voting.successor_period cctxt (chain, block) + >>=? fun {voting_period = {index; _}; _} -> + let contents = Single (Proposals {source; period = index; proposals}) in + Injection.inject_operation + cctxt + ~chain + ~block + ?confirmations + ~fee_parameter:Injection.dummy_fee_parameter + ?dry_run + ~src_sk + contents + ?verbose_signing + +let submit_ballot ?dry_run ?verbose_signing (cctxt : #full) ~chain ~block + ?confirmations ~src_sk source proposal ballot = + (* The user must provide the proposal explicitly to make himself sure + for what he is voting. *) + Alpha_services.Voting.successor_period cctxt (chain, block) + >>=? fun {voting_period = {index; _}; _} -> + let contents = Single (Ballot {source; period = index; proposal; ballot}) in + Injection.inject_operation + cctxt + ~chain + ~block + ?confirmations + ~fee_parameter:Injection.dummy_fee_parameter + ?dry_run + ~src_sk + contents + ?verbose_signing + +let pp_operation formatter (a : Alpha_block_services.operation) = + match (a.receipt, a.protocol_data) with + | (Some (Apply_results.Operation_metadata omd), Operation_data od) -> ( + match Apply_results.kind_equal_list od.contents omd.contents with + | Some Apply_results.Eq -> + Operation_result.pp_operation_result + formatter + (od.contents, omd.contents) + | None -> Stdlib.failwith "Unexpected result.") + | (None, _) -> + Stdlib.failwith + "Pruned metadata: the operation receipt was removed accordingly to the \ + node's history mode." + | _ -> Stdlib.failwith "Unexpected result." + +let get_operation_from_block (cctxt : #full) ~chain predecessors operation_hash + = + Client_confirmations.lookup_operation_in_previous_blocks + cctxt + ~chain + ~predecessors + operation_hash + >>=? function + | None -> return_none + | Some (block, i, j) -> + cctxt#message + "Operation found in block: %a (pass: %d, offset: %d)" + Block_hash.pp + block + i + j + >>= fun () -> + Protocol_client_context.Alpha_block_services.Operations.operation + cctxt + ~chain + ~block:(`Hash (block, 0)) + i + j + >>=? fun op' -> return_some op' + +let display_receipt_for_operation (cctxt : #full) ~chain ?(predecessors = 10) + operation_hash = + get_operation_from_block cctxt ~chain predecessors operation_hash + >>=? function + | None -> failwith "Couldn't find operation" + | Some op -> cctxt#message "%a" pp_operation op >>= fun () -> return_unit + +let cached_contracts cctxt ~chain ~block = + let cb = (chain, block) in + Alpha_services.Cache.cached_contracts cctxt cb + +let contract_rank cctxt ~chain ~block contract = + let cb = (chain, block) in + Alpha_services.Cache.contract_rank cctxt cb contract + +let contract_cache_size cctxt ~chain ~block = + let cb = (chain, block) in + Alpha_services.Cache.contract_cache_size cctxt cb + +let contract_cache_size_limit cctxt ~chain ~block = + let cb = (chain, block) in + Alpha_services.Cache.contract_cache_size_limit cctxt cb diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_context.mli b/src/proto_012_PsiThaCa/lib_client/client_proto_context.mli new file mode 100644 index 000000000000..05d01ac753ef --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_context.mli @@ -0,0 +1,386 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +val list_contract_labels : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + (string * string * string) list tzresult Lwt.t + +val get_storage : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + unparsing_mode:Script_ir_translator.unparsing_mode -> + Contract.t -> + Script.expr option tzresult Lwt.t + +val get_contract_big_map_value : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Contract.t -> + Script.expr * Script.expr -> + Script.expr option tzresult Lwt.t + +val register_global_constant : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?simulation:bool -> + ?fee:Tez.tez -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + ?counter:Z.t -> + source:Signature.public_key_hash -> + src_pk:Signature.public_key -> + src_sk:Client_keys.sk_uri -> + fee_parameter:Injection.fee_parameter -> + constant:string -> + unit -> + (Kind.register_global_constant Kind.manager Injection.result, tztrace) result + Lwt.t + +val get_big_map_value : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + unparsing_mode:Script_ir_translator.unparsing_mode -> + Big_map.Id.t -> + Script_expr_hash.t -> + Script.expr tzresult Lwt.t + +val get_script : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + unparsing_mode:Script_ir_translator.unparsing_mode -> + Contract.t -> + Script.t option tzresult Lwt.t + +val get_script_hash : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Contract.t -> + Script_expr_hash.t option tzresult Lwt.t + +val get_balance : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Contract.t -> + Tez.t tzresult Lwt.t + +val get_frozen_deposits_limit : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Signature.Public_key_hash.t -> + Tez.t option tzresult Lwt.t + +val build_delegate_operation : + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + public_key_hash option -> + Kind.delegation Annotated_manager_operation.t + +val set_delegate : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?simulation:bool -> + ?fee:Tez.tez -> + public_key_hash -> + src_pk:public_key -> + manager_sk:Client_keys.sk_uri -> + fee_parameter:Injection.fee_parameter -> + public_key_hash option -> + Kind.delegation Kind.manager Injection.result tzresult Lwt.t + +val set_deposits_limit : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?simulation:bool -> + ?fee:Tez.tez -> + public_key_hash -> + src_pk:public_key -> + manager_sk:Client_keys.sk_uri -> + fee_parameter:Injection.fee_parameter -> + Tez.t option -> + Kind.set_deposits_limit Kind.manager Injection.result tzresult Lwt.t + +val register_as_delegate : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?fee:Tez.tez -> + manager_sk:Client_keys.sk_uri -> + fee_parameter:Injection.fee_parameter -> + public_key -> + Kind.delegation Kind.manager Injection.result tzresult Lwt.t + +val save_contract : + force:bool -> + #Protocol_client_context.full -> + string -> + Contract.t -> + unit tzresult Lwt.t + +val originate_contract : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?branch:int -> + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + delegate:public_key_hash option -> + initial_storage:string -> + balance:Tez.t -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + code:Script.expr -> + fee_parameter:Injection.fee_parameter -> + unit -> + (Kind.origination Kind.manager Injection.result * Contract.t) tzresult Lwt.t + +val parse_arg_transfer : string option -> Script.lazy_expr tzresult Lwt.t + +val build_transaction_operation : + amount:Tez.t -> + parameters:Script.lazy_expr -> + ?entrypoint:string -> + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + Contract.t -> + Kind.transaction Annotated_manager_operation.t + +val transfer : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?simulation:bool -> + ?branch:int -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + destination:Contract.t -> + ?entrypoint:string -> + ?arg:string -> + amount:Tez.t -> + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + ?counter:Z.t -> + fee_parameter:Injection.fee_parameter -> + unit -> + (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult + Lwt.t + +val build_reveal_operation : + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + public_key -> + Kind.reveal Annotated_manager_operation.t + +val reveal : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?branch:int -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + ?fee:Tez.t -> + fee_parameter:Injection.fee_parameter -> + unit -> + Kind.reveal Kind.manager Injection.result tzresult Lwt.t + +type activation_key = { + pkh : Ed25519.Public_key_hash.t; + amount : Tez.t; + activation_code : Blinded_public_key_hash.activation_code; + mnemonic : string list; + password : string; + email : string; +} + +val activation_key_encoding : activation_key Data_encoding.t + +type batch_transfer_operation = { + destination : string; + fee : string option; + gas_limit : Gas.Arith.integral option; + storage_limit : Z.t option; + amount : string; + arg : string option; + entrypoint : string option; +} + +val batch_transfer_operation_encoding : batch_transfer_operation Data_encoding.t + +val activate_account : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?encrypted:bool -> + ?force:bool -> + activation_key -> + string -> + Kind.activate_account Injection.result tzresult Lwt.t + +val activate_existing_account : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + string -> + Blinded_public_key_hash.activation_code -> + Kind.activate_account Injection.result tzresult Lwt.t + +type period_info = { + current_period_kind : Voting_period.kind; + position : Int32.t; + remaining : Int32.t; + current_proposal : Protocol_hash.t option; +} + +type ballots_info = { + current_quorum : Int32.t; + participation : Int32.t; + supermajority : Int32.t; + ballots : Vote.ballots; +} + +val get_period_info : + ?successor:bool -> + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + period_info tzresult Lwt.t + +val get_ballots_info : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ballots_info tzresult Lwt.t + +val get_proposals : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Int32.t Environment.Protocol_hash.Map.t tzresult Lwt.t + +val submit_proposals : + ?dry_run:bool -> + ?verbose_signing:bool -> + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + src_sk:Client_keys.sk_uri -> + public_key_hash -> + Protocol_hash.t list -> + Kind.proposals Injection.result_list tzresult Lwt.t + +val submit_ballot : + ?dry_run:bool -> + ?verbose_signing:bool -> + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + src_sk:Client_keys.sk_uri -> + public_key_hash -> + Protocol_hash.t -> + Vote.ballot -> + Kind.ballot Injection.result_list tzresult Lwt.t + +(** lookup an operation in [predecessors] previous blocks, and print the + receipt if found *) +val display_receipt_for_operation : + #Protocol_client_context.full -> + chain:Block_services.chain -> + ?predecessors:int -> + Operation_list_hash.elt -> + unit tzresult Lwt.t + +val cached_contracts : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + (Contract.t * int) list tzresult Lwt.t + +val contract_rank : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Contract.t -> + int option tzresult Lwt.t + +val contract_cache_size : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + int tzresult Lwt.t + +val contract_cache_size_limit : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + int tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_contracts.ml b/src/proto_012_PsiThaCa/lib_client/client_proto_contracts.ml new file mode 100644 index 000000000000..903e0ddd0968 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_contracts.ml @@ -0,0 +1,156 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +module ContractEntity = struct + include Contract (* t, Compare, encoding *) + + let of_source s = + Contract.of_b58check s |> Environment.wrap_tzresult + |> record_trace_eval (fun () -> error_of_fmt "bad contract notation") + |> Lwt.return + + let to_source s = return (Contract.to_b58check s) + + let name = "contract" +end + +module RawContractAlias = Client_aliases.Alias (ContractEntity) + +module ContractAlias = struct + let find cctxt s = + RawContractAlias.find_opt cctxt s >>=? function + | Some v -> return (s, v) + | None -> ( + Client_keys.Public_key_hash.find_opt cctxt s >>=? function + | Some v -> return (s, Contract.implicit_contract v) + | None -> failwith "no contract or key named %s" s) + + let find_key cctxt name = + Client_keys.Public_key_hash.find cctxt name >>=? fun v -> + return (name, Contract.implicit_contract v) + + let rev_find cctxt c = + match Contract.is_implicit c with + | Some hash -> ( + Client_keys.Public_key_hash.rev_find cctxt hash >>=? function + | Some name -> return_some ("key:" ^ name) + | None -> return_none) + | None -> RawContractAlias.rev_find cctxt c + + let get_contract cctxt s = + match String.split ~limit:1 ':' s with + | ["key"; key] -> find_key cctxt key + | _ -> find cctxt s + + let autocomplete cctxt = + Client_keys.Public_key_hash.autocomplete cctxt >>=? fun keys -> + RawContractAlias.autocomplete cctxt >>=? fun contracts -> + return (List.map (( ^ ) "key:") keys @ contracts) + + let alias_param ?(name = "name") ?(desc = "existing contract alias") next = + let desc = + desc ^ "\n" + ^ "Can be a contract alias or a key alias (autodetected in order).\n\ + Use 'key:name' to force the later." + in + Clic.( + param + ~name + ~desc + (parameter ~autocomplete (fun cctxt p -> get_contract cctxt p)) + next) + + let find_destination cctxt s = + match String.split ~limit:1 ':' s with + | ["alias"; alias] -> find cctxt alias + | ["key"; text] -> + Client_keys.Public_key_hash.find cctxt text >>=? fun v -> + return (s, Contract.implicit_contract v) + | _ -> ( + find cctxt s >>= function + | Ok v -> return v + | Error k_errs -> ( + ContractEntity.of_source s >>= function + | Ok v -> return (s, v) + | Error c_errs -> Lwt.return_error (k_errs @ c_errs))) + + let destination_parameter () = + Clic.parameter + ~autocomplete:(fun cctxt -> + autocomplete cctxt >>=? fun list1 -> + Client_keys.Public_key_hash.autocomplete cctxt >>=? fun list2 -> + return (list1 @ list2)) + find_destination + + let destination_param ?(name = "dst") ?(desc = "destination contract") next = + let desc = + String.concat + "\n" + [ + desc; + "Can be an alias, a key, or a literal (autodetected in order).\n\ + Use 'text:literal', 'alias:name', 'key:name' to force."; + ] + in + Clic.param ~name ~desc (destination_parameter ()) next + + let destination_arg ?(name = "dst") ?(doc = "destination contract") () = + let doc = + String.concat + "\n" + [ + doc; + "Can be an alias, a key, or a literal (autodetected in order).\n\ + Use 'text:literal', 'alias:name', 'key:name' to force."; + ] + in + Clic.arg ~long:name ~doc ~placeholder:name (destination_parameter ()) + + let name cctxt contract = + rev_find cctxt contract >>=? function + | None -> return (Contract.to_b58check contract) + | Some name -> return name +end + +let list_contracts cctxt = + RawContractAlias.load cctxt >>=? fun raw_contracts -> + List.map_s (fun (n, v) -> Lwt.return ("", n, v)) raw_contracts + >>= fun contracts -> + Client_keys.Public_key_hash.load cctxt >>=? fun keys -> + (* List accounts (implicit contracts of identities) *) + List.map_es + (fun (n, v) -> + RawContractAlias.mem cctxt n >>=? fun mem -> + let p = if mem then "key:" else "" in + let v' = Contract.implicit_contract v in + return (p, n, v')) + keys + >>=? fun accounts -> return (contracts @ accounts) + +let get_delegate cctxt ~chain ~block source = + Alpha_services.Contract.delegate_opt cctxt (chain, block) source diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_contracts.mli b/src/proto_012_PsiThaCa/lib_client/client_proto_contracts.mli new file mode 100644 index 000000000000..fcef44b21f11 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_contracts.mli @@ -0,0 +1,74 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Clic + +module RawContractAlias : Client_aliases.Alias with type t = Contract.t + +module ContractAlias : sig + val get_contract : + #Client_context.wallet -> string -> (string * Contract.t) tzresult Lwt.t + + val alias_param : + ?name:string -> + ?desc:string -> + ('a, (#Client_context.wallet as 'wallet)) params -> + (string * Contract.t -> 'a, 'wallet) params + + val find_destination : + #Client_context.wallet -> string -> (string * Contract.t) tzresult Lwt.t + + val destination_param : + ?name:string -> + ?desc:string -> + ('a, (#Client_context.wallet as 'wallet)) params -> + (string * Contract.t -> 'a, 'wallet) params + + val destination_arg : + ?name:string -> + ?doc:string -> + unit -> + ((string * Contract.t) option, #Client_context.wallet) Clic.arg + + val rev_find : + #Client_context.wallet -> Contract.t -> string option tzresult Lwt.t + + val name : #Client_context.wallet -> Contract.t -> string tzresult Lwt.t + + val autocomplete : #Client_context.wallet -> string list tzresult Lwt.t +end + +val list_contracts : + #Client_context.wallet -> + (string * string * RawContractAlias.t) list tzresult Lwt.t + +val get_delegate : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Contract.t -> + public_key_hash option tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_fa12.ml b/src/proto_012_PsiThaCa/lib_client/client_proto_fa12.ml new file mode 100644 index 000000000000..fb7e31dc856b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_fa12.ml @@ -0,0 +1,975 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol_client_context +open Protocol +open Alpha_context +open Tezos_micheline + +type error += Contract_has_no_script of Contract.t + +type error += Contract_has_no_storage of Contract.t + +type error += Entrypoint_mismatch of string * (Script.expr * Script.expr) option + +type error += Action_unwrapping_error of string * Script.expr + +type error += Not_a_viewable_entrypoint of string + +type error += Not_an_entrypoint of Script.expr + +type error += Not_enough_balance of Z.t * Z.t + +type error += Not_enough_allowance of Z.t * Z.t + +type error += Unsafe_allowance_change of Z.t + +type error += Unexpected_error of Script.location * Script.expr + +let entrypoint_mismatch_explanation ppf (name, ty) = + match ty with + | None -> Format.fprintf ppf "Entrypoint %s is missing" name + | Some (ty, expected) -> + Format.fprintf + ppf + "Entrypoint \"%s\" has type @[%a@], but should have type @[%a@]" + name + Michelson_v1_printer.print_expr + ty + Michelson_v1_printer.print_expr + expected + +let () = + register_error_kind + `Permanent + ~id:"fa12ContractHasNoScript" + ~title:"The given contract is not a smart contract" + ~description:"An FA1.2 command has referenced a scriptless contract." + ~pp:(fun ppf contract -> + Format.fprintf + ppf + "Contract %a is not a smart contract, it has no script." + Contract.pp + contract) + Data_encoding.(obj1 (req "contract" Contract.encoding)) + (function Contract_has_no_script c -> Some c | _ -> None) + (fun c -> Contract_has_no_script c) ; + register_error_kind + `Permanent + ~id:"fa12ContractHasNoStorage" + ~title:"The given contract has no storage" + ~description: + "An FA1.2 command made a call on a contract that has no storage." + ~pp:(fun ppf contract -> + Format.fprintf ppf "Contract %a has no storage." Contract.pp contract) + Data_encoding.(obj1 (req "contract" Contract.encoding)) + (function Contract_has_no_storage c -> Some c | _ -> None) + (fun c -> Contract_has_no_storage c) ; + register_error_kind + `Permanent + ~id:"entrypointMismatch" + ~title:"The given contract does not implement the FA1.2 interface" + ~description: + "An FA1.2 command has referenced a smart contract whose script does not \ + implement at least one FA1.2 entrypoint, or with an incompatible type. \ + See TZIP-7 \ + (https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-7/tzip-7.md) \ + for documentation on FA1.2." + ~pp:(fun ppf (name, ty) -> + Format.fprintf + ppf + "Not a supported FA1.2 contract.@\n%a." + entrypoint_mismatch_explanation + (name, ty)) + Data_encoding.( + obj2 + (req "name" string) + (req "type" (option (tup2 Script.expr_encoding Script.expr_encoding)))) + (function Entrypoint_mismatch (n, t) -> Some (n, t) | _ -> None) + (fun (n, t) -> Entrypoint_mismatch (n, t)) ; + register_error_kind + `Permanent + ~id:"actionUnwrappingError" + ~title:"The argument is not for an FA1.2 parameter" + ~description: + "The argument's type does not correspond to that of the corresponding \ + FA1.2 entrypoint." + ~pp:(fun ppf (entrypoint, expr) -> + Format.fprintf + ppf + "Not a supported FA1.2 entrypoint argument.@\nEntrypoint: %s@\n%a." + entrypoint + Michelson_v1_printer.print_expr + expr) + Data_encoding.( + obj2 (req "entrypoint" string) (req "expr" Script.expr_encoding)) + (function Action_unwrapping_error (s, e) -> Some (s, e) | _ -> None) + (fun (s, e) -> Action_unwrapping_error (s, e)) ; + register_error_kind + `Permanent + ~id:"notAViewableEntrypoint" + ~title:"The entrypoint is not viewable" + ~description: + "A transaction made a call on an entrypoint expecting it to implement \ + the 'view' type." + ~pp:(fun ppf entrypoint -> + Format.fprintf ppf "Entrypoint %s is not viewable." entrypoint) + Data_encoding.(obj1 (req "entrypoint" string)) + (function Not_a_viewable_entrypoint e -> Some e | _ -> None) + (fun e -> Not_a_viewable_entrypoint e) ; + register_error_kind + `Permanent + ~id:"notAnEntrypoint" + ~title:"The expression is not for an entrypoint" + ~description: + "The parameter value of the contract call refers to a non-existing \ + entrypoint." + ~pp:(fun ppf param -> + Format.fprintf + ppf + "Not a parameter for an entrypoint.@\n%a." + Michelson_v1_printer.print_expr + param) + Data_encoding.(obj1 (req "param" Script.expr_encoding)) + (function Not_an_entrypoint e -> Some e | _ -> None) + (fun e -> Not_an_entrypoint e) ; + register_error_kind + `Permanent + ~id:"notEnoughBalance" + ~title:"The sender does not have enough balance" + ~description: + "An FA1.2 transfer failed because the sender does not have enough \ + balance." + ~pp:(fun ppf (required, present) -> + Format.fprintf + ppf + "Not enough balance.@\nRequired: %a.@\nPresent: %a." + Z.pp_print + required + Z.pp_print + present) + Data_encoding.(obj2 (req "present" n) (req "required" n)) + (function Not_enough_balance (p, r) -> Some (p, r) | _ -> None) + (fun (p, r) -> Not_enough_balance (p, r)) ; + register_error_kind + `Permanent + ~id:"notEnoughAllowance" + ~title:"The sender does not have enough allowance" + ~description: + "An FA1.2 transfer failed because the receiver does not have enough \ + allowance to ask for a transfer from the sender." + ~pp:(fun ppf (required, present) -> + Format.fprintf + ppf + "Not enough allowance.@\nRequired: %a.@\nPresent: %a." + Z.pp_print + required + Z.pp_print + present) + Data_encoding.(obj2 (req "present" n) (req "required" n)) + (function Not_enough_allowance (p, r) -> Some (p, r) | _ -> None) + (fun (p, r) -> Not_enough_allowance (p, r)) ; + register_error_kind + `Permanent + ~id:"unsafeAllowanceChange" + ~title:"The allowance change is unsafe" + ~description: + "An FA1.2 non-zero allowance change failed because the current allowance \ + is non-zero. For more explanation on why such allowance change is \ + unsafe, please look at TZIP-7 \ + (https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-7/tzip-7.md#approve)." + ~pp:(fun ppf previous -> + Format.fprintf + ppf + "Unsafe allowance change@\nPrevious: %a." + Z.pp_print + previous) + Data_encoding.(obj1 (req "previous" n)) + (function Unsafe_allowance_change p -> Some p | _ -> None) + (fun p -> Unsafe_allowance_change p) ; + register_error_kind + `Permanent + ~id:"fa12UnexpectedError" + ~title:"Unexpected error during FA1.2 contract interpretation" + ~description: + "An unexpected Michelson error was reached during the interpretation of \ + an FA1.2 contract." + ~pp:(fun ppf (loc, expr) -> + Format.fprintf + ppf + "An unexpected error was reached at location %d with: %a." + loc + Michelson_v1_printer.print_expr + expr) + Data_encoding.( + obj2 + (req "location" Script.location_encoding) + (req "value" Script.expr_encoding)) + (function Unexpected_error (loc, expr) -> Some (loc, expr) | _ -> None) + (fun (loc, expr) -> Unexpected_error (loc, expr)) + +let callback_encoding = + Data_encoding.( + conv + (fun (c, e) -> (c, Option.value ~default:"" e)) + (fun (c, e) -> (c, if String.equal e "" then None else Some e)) + (tup2 Contract.encoding Variable.string)) + +(** Michelson combinators *) + +let pair ~loc a b = Micheline.Prim (loc, Script.D_Pair, [a; b], []) + +let nat ~loc i = Micheline.Int (loc, i) + +let unit ~loc = Micheline.Prim (loc, Script.D_Unit, [], []) + +let bytes ~loc b = Micheline.Bytes (loc, b) + +let address ~loc addr = + bytes ~loc (Data_encoding.Binary.to_bytes_exn Contract.encoding addr) + +let callback ~loc ?entrypoint addr = + bytes + ~loc + (Data_encoding.Binary.to_bytes_exn callback_encoding (addr, entrypoint)) + +(** Types *) + +(** Michelson type combinators: produce a Michelson node of the + expected type, and a function to check another node is + syntactically equivalent. *) +type type_eq_combinator = Script.node * (Script.node -> bool) + +(** [t_pair ~loc l] takes a list of types and respective equivalence + check functions, and returns a type of n-ary pair of such types and + a function checking syntactical equivalence with another node. *) +let t_pair ~loc l : type_eq_combinator = + let (values, are_ty) = List.split l in + let is_pair p = + match p with + | Micheline.Prim (_, Script.T_pair, l, _) -> ( + let res = + List.for_all2 + ~when_different_lengths:() + (fun is_ty v -> is_ty v) + are_ty + l + in + match res with Ok b -> b | Error () -> false) + | _ -> false + in + (Micheline.Prim (loc, Script.T_pair, values, []), is_pair) + +(** [t_unit ~loc] returns a Micheline node for the `unit` type, and + a function checking another node is syntactically equivalent. *) +let t_unit ~loc : type_eq_combinator = + let is_unit p = + match p with Micheline.Prim (_, Script.T_unit, [], _) -> true | _ -> false + in + (Micheline.Prim (loc, Script.T_unit, [], []), is_unit) + +(** [t_nat ~loc] returns a Micheline node for the `nat` type, and + a function checking another node is syntactically equivalent. *) +let t_nat ~loc : type_eq_combinator = + let is_nat p = + match p with Micheline.Prim (_, Script.T_nat, [], _) -> true | _ -> false + in + (Micheline.Prim (loc, Script.T_nat, [], []), is_nat) + +(** [t_address ~loc] returns a Micheline node for the `address` + type, and a function checking another node is syntactically + equivalent. *) +let t_address ~loc : type_eq_combinator = + let is_address p = + match p with + | Micheline.Prim (_, Script.T_address, [], _) -> true + | _ -> false + in + (Micheline.Prim (loc, Script.T_address, [], []), is_address) + +(** [t_contract ~loc (c, is_c)] takes a node representing a Michelson + type and its own syntactical equivalence checker, and returns a + Micheline node for the type `contract c`, and a function checking + another node is syntactically equivalent. *) +let t_contract ~loc (a, is_a) : type_eq_combinator = + let is_contract c = + match c with + | Micheline.Prim (_, Script.T_contract, [a], _) -> is_a a + | _ -> false + in + (Micheline.Prim (loc, Script.T_contract, [a], []), is_contract) + +(** [t_view ~loc a b] takes two node [a] and [b] and their syntactical + equivalence checking functions, and returns a Micheline node for + the `view a b` type, and a function checking another node is + syntactically equivalent. The view type is defined by + [TZIP4](https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-4/tzip-4.md). + *) +let t_view ~loc a b : type_eq_combinator = t_pair ~loc [a; t_contract ~loc b] + +(** * Actions *) + +(** Corresponds to + [TZIP7](https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-7/tzip-7.md) + entrypoints. *) + +(** A callback from a view can be on a specific entrypoint of the + contract, or the default one if not specified. *) +type callback_contract = Contract.t * string option + +type action = + | Transfer of Contract.t * Contract.t * Z.t + | Approve of Contract.t * Z.t + | Get_allowance of Contract.t * Contract.t * callback_contract + | Get_balance of Contract.t * callback_contract + | Get_total_supply of callback_contract + +let print_callback_contract ppf (c, etp) = + Format.fprintf + ppf + "%a%s" + Contract.pp + c + (match etp with None | Some "" -> "" | Some etp -> "%" ^ etp) + +let print_action ppf = function + | Transfer (src, dst, amount) -> + Format.fprintf + ppf + "Transfer (%a, %a, %a)" + Contract.pp + src + Contract.pp + dst + Z.pp_print + amount + | Approve (addr, amount) -> + Format.fprintf ppf "Approve (%a, %a)" Contract.pp addr Z.pp_print amount + | Get_allowance (src, dst, callback) -> + Format.fprintf + ppf + "Get_allowance (%a, %a, %a)" + Contract.pp + src + Contract.pp + dst + print_callback_contract + callback + | Get_balance (addr, callback) -> + Format.fprintf + ppf + "Get_balance (%a, %a)" + Contract.pp + addr + print_callback_contract + callback + | Get_total_supply callback -> + Format.fprintf + ppf + "Get_total_supply (%a)" + print_callback_contract + callback + +let transfer_encoding = + Data_encoding.( + case + ~title:"transfer" + (Tag 0) + (obj3 + (req "transfer_source" Contract.encoding) + (req "transfer_destination" Contract.encoding) + (req "transfer_amount" n)) + (function + | Transfer (src, dst, amount) -> Some (src, dst, amount) | _ -> None) + (fun (src, dst, amount) -> Transfer (src, dst, amount))) + +let approve_encoding = + Data_encoding.( + case + ~title:"approve" + (Tag 1) + (obj2 (req "approve_address" Contract.encoding) (req "approve_amount" n)) + (function Approve (addr, amount) -> Some (addr, amount) | _ -> None) + (fun (addr, amount) -> Approve (addr, amount))) + +let getBalance_encoding = + Data_encoding.( + case + ~title:"getBalance" + (Tag 2) + (obj2 + (req "getBalance_address" Contract.encoding) + (req "getBalance_callback" callback_encoding)) + (function + | Get_balance (addr, callback) -> Some (addr, callback) | _ -> None) + (fun (addr, callback) -> Get_balance (addr, callback))) + +let getAllowance_encoding = + Data_encoding.( + case + ~title:"getAllowance" + (Tag 3) + (obj3 + (req "getAllowance_source" Contract.encoding) + (req "getAllowance_destination" Contract.encoding) + (req "getAllowance_callback" callback_encoding)) + (function + | Get_allowance (src, dst, callback) -> Some (src, dst, callback) + | _ -> None) + (fun (src, dst, callback) -> Get_allowance (src, dst, callback))) + +let getTotalSupply_encoding = + Data_encoding.( + case + ~title:"getTotalSupply" + (Tag 4) + (obj1 (req "getTotalSupply_callback" callback_encoding)) + (function Get_total_supply callback -> Some callback | _ -> None) + (fun callback -> Get_total_supply callback)) + +let action_encoding = + Data_encoding.union + [ + transfer_encoding; + approve_encoding; + getBalance_encoding; + getAllowance_encoding; + getTotalSupply_encoding; + ] + +let transfer_type ~loc = + t_pair ~loc [t_address ~loc; t_address ~loc; t_nat ~loc] + +let approve_type ~loc = t_pair ~loc [t_address ~loc; t_nat ~loc] + +let getAllowance_type ~loc = + t_view ~loc (t_pair ~loc [t_address ~loc; t_address ~loc]) (t_nat ~loc) + +let getBalance_type ~loc = t_view ~loc (t_address ~loc) (t_nat ~loc) + +let getTotalSupply_type ~loc = t_view ~loc (t_unit ~loc) (t_nat ~loc) + +let standard_entrypoints = + let loc = -1 in + [ + ("transfer", transfer_type ~loc); + ("approve", approve_type ~loc); + ("getAllowance", getAllowance_type ~loc); + ("getBalance", getBalance_type ~loc); + ("getTotalSupply", getTotalSupply_type ~loc); + ] + +let view_input ~loc action = + match action with + | Get_allowance (source, destination, _) -> + pair ~loc (address ~loc source) (address ~loc destination) + | Get_balance (addr, _) -> address ~loc addr + | Get_total_supply _ -> unit ~loc + | _ -> unit ~loc + +let action_to_expr ~loc action = + match action with + | Transfer (source, destination, amount) -> + pair + ~loc + (address ~loc source) + (pair ~loc (address ~loc destination) (nat ~loc amount)) + | Approve (addr, amount) -> pair ~loc (address ~loc addr) (nat ~loc amount) + | Get_allowance (_, _, (cb, entrypoint)) -> + let input = view_input ~loc action in + pair ~loc input (callback ~loc ?entrypoint cb) + | Get_balance (_, (cb, entrypoint)) -> + let input = view_input ~loc action in + pair ~loc input (callback ~loc ?entrypoint cb) + | Get_total_supply (cb, entrypoint) -> + let input = view_input ~loc action in + pair ~loc input (callback ~loc ?entrypoint cb) + +let parse_address error = function + | Micheline.Bytes (_, b) -> + ok @@ Data_encoding.Binary.of_bytes_exn Contract.encoding b + | String (_, s) -> ( + match Contract.of_b58check s with Ok c -> ok c | Error _ -> error ()) + | _ -> error () + +let parse_callback error expr = + let of_b58_check (c, entrypoint) = + match Contract.of_b58check c with + | Ok c -> ok (c, entrypoint) + | Error _ -> error () + in + match expr with + | Micheline.Bytes (_, b) -> ( + match Data_encoding.Binary.of_bytes callback_encoding b with + | Ok (c, entrypoint) -> ok (c, entrypoint) + | Error _ -> error ()) + | String (_, s) -> ( + match String.index_opt s '%' with + | None -> of_b58_check (s, None) + | Some pos -> ( + let len = String.length s - pos - 1 in + let name = String.sub s (pos + 1) len in + match (String.sub s 0 pos, name) with + | (addr, "default") -> of_b58_check (addr, None) + | (addr, name) -> of_b58_check (addr, Some name))) + | _ -> error () + +let action_of_expr ~entrypoint expr = + let open Micheline in + let error () = + error (Action_unwrapping_error (entrypoint, Micheline.strip_locations expr)) + in + match (entrypoint, expr) with + (* Transfer operation before comb pairs. *) + | ( "transfer", + Prim + ( _, + Script.D_Pair, + [ + ((Bytes (_, _) | String (_, _)) as source); + Prim + ( _, + Script.D_Pair, + [ + ((Bytes (_, _) | String (_, _)) as destination); + Int (_, amount); + ], + _ ); + ], + _ ) ) + (* Transfer operation since Edo comb pairs are now directly interpreted as a + tuple of 3 elements instead of a pair inside a pair. *) + | ( "transfer", + Prim + ( _, + Script.D_Pair, + [ + ((Bytes (_, _) | String (_, _)) as source); + ((Bytes (_, _) | String (_, _)) as destination); + Int (_, amount); + ], + _ ) ) -> + parse_address error source >>? fun source -> + parse_address error destination >>? fun destination -> + ok (Transfer (source, destination, amount)) + | ( "approve", + Prim + ( _, + Script.D_Pair, + [((Bytes (_, _) | String (_, _)) as addr); Int (_, amount)], + _ ) ) -> + parse_address error addr >>? fun addr -> ok (Approve (addr, amount)) + | ( "getBalance", + Prim + ( _, + Script.D_Pair, + [ + ((Bytes (_, _) | String (_, _)) as addr); + ((Bytes (_, _) | String (_, _)) as cb); + ], + _ ) ) -> + parse_address error addr >>? fun addr -> + parse_callback error cb >>? fun callback -> + ok (Get_balance (addr, callback)) + | ( "getAllowance", + Prim + ( _, + Script.D_Pair, + [ + Prim + ( _, + Script.D_Pair, + [ + ((Bytes (_, _) | String (_, _)) as source); + ((Bytes (_, _) | String (_, _)) as destination); + ], + _ ); + ((Bytes (_, _) | String (_, _)) as contract); + ], + _ ) ) -> + parse_address error source >>? fun source -> + parse_address error destination >>? fun destination -> + parse_callback error contract >>? fun callback -> + ok (Get_allowance (source, destination, callback)) + | ( "getTotalSupply", + Prim + ( _, + Script.D_Pair, + [ + Prim (_, Script.D_Unit, [], _); + ((Bytes (_, _) | String (_, _)) as contract); + ], + _ ) ) -> + parse_callback error contract >>? fun callback -> + ok (Get_total_supply callback) + | _ -> error () + +let find_entrypoint_in_annot error annots expr = + match List.find_opt (fun annot -> annot.[0] = '%') annots with + | Some entrypoint -> + action_of_expr + ~entrypoint:(String.sub entrypoint 1 (String.length entrypoint - 1)) + expr + | None -> error () + +let derive_action expr t_param = + let error () = error (Not_an_entrypoint (Micheline.strip_locations expr)) in + let rec derive expr t_param = + match (expr, t_param) with + | ( Micheline.Prim (_, Script.D_Left, [left], _), + Micheline.Prim (_, Script.T_or, [t_left; _], _) ) -> + derive left t_left + | ( Micheline.Prim (_, Script.D_Right, [right], _), + Micheline.Prim (_, Script.T_or, [_; t_right], _) ) -> + derive right t_right + | (_, Micheline.Prim (_, _, _, annots)) -> + find_entrypoint_in_annot error annots expr + | _ -> error () + in + derive expr t_param + +let extract_parameter contract = function + | Micheline.Seq (_, l) -> ( + List.filter_map + (function + | Micheline.Prim (_, Script.K_parameter, [param], _) -> Some param + | _ -> None) + l + |> function + | param :: _ -> ok param + | _ -> error (Contract_has_no_script contract)) + | _ -> error (Contract_has_no_script contract) + +let get_contract_parameter cctxt ~chain ~block contract = + Client_proto_context.get_script + cctxt + ~chain + ~block + contract + ~unparsing_mode:Optimized + >>=? function + | None -> fail (Contract_has_no_script contract) + | Some {code; _} -> ( + match Script_repr.force_decode code with + | Error _ -> fail (Contract_has_no_script contract) + | Ok code -> Lwt.return (extract_parameter contract (Micheline.root code)) + ) + +let convert_wrapped_parameter_into_action cctxt ~chain ~block contract param = + get_contract_parameter cctxt ~chain ~block contract >>=? fun parameter -> + Lwt.return (derive_action param parameter) + +let check_entrypoint entrypoints (name, (expected_ty, check)) = + match List.assoc_opt ~equal:String.equal name entrypoints with + | None -> error (Entrypoint_mismatch (name, None)) + | Some ty -> + if not (check (Micheline.root ty)) then + error + (Entrypoint_mismatch + (name, Some (ty, Micheline.strip_locations expected_ty))) + else Ok () + +let action_to_entrypoint = function + | Transfer (_, _, _) -> "transfer" + | Approve (_, _) -> "approve" + | Get_allowance (_, _, _) -> "getAllowance" + | Get_balance (_, _) -> "getBalance" + | Get_total_supply _ -> "getTotalSupply" + +let contract_has_fa12_interface : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + contract:Alpha_context.Contract.t -> + unit -> + unit tzresult Lwt.t = + fun cctxt ~chain ~block ~contract () -> + match Contract.is_implicit contract with + | Some _ -> fail (Contract_has_no_script contract) + | None -> + Michelson_v1_entrypoints.list_contract_entrypoints + cctxt + ~chain + ~block + ~contract + >>=? fun entrypoints -> + List.iter_e (check_entrypoint entrypoints) standard_entrypoints + |> Lwt.return + +let translate_action_to_argument action = + let entrypoint = action_to_entrypoint action in + let expr = Micheline.strip_locations (action_to_expr ~loc:() action) in + (entrypoint, Format.asprintf "%a" Michelson_v1_printer.print_expr expr) + +let parse_error = + let open Micheline in + function + | ( "NotEnoughBalance", + Prim (_, Script.D_Pair, [Int (_, required); Int (_, present)], _) ) -> + Some (Not_enough_balance (required, present)) + | ( "NotEnoughAllowance", + Prim (_, Script.D_Pair, [Int (_, required); Int (_, present)], _) ) -> + Some (Not_enough_allowance (required, present)) + | ("UnsafeAllowanceChange", Int (_, previous)) -> + Some (Unsafe_allowance_change previous) + | _ -> None + +let extract_error trace = + let open Micheline in + TzTrace.fold + (fun _ error -> + match error with + | Environment.Ecoproto_error (Script_interpreter.Reject (loc, param, _)) + -> ( + match root param with + | Prim (_, Script.D_Pair, [String (_, error); res], _) -> + parse_error (error, res) + | _ -> Some (Unexpected_error (loc, param))) + | _ -> None) + None + trace + +let call_contract (cctxt : #Protocol_client_context.full) ~chain ~block + ?confirmations ?dry_run ?verbose_signing ?branch ~source ~src_pk ~src_sk + ~contract ~action ~tez_amount ?fee ?gas_limit ?storage_limit ?counter + ~fee_parameter () = + contract_has_fa12_interface cctxt ~chain ~block ~contract () >>=? fun () -> + let (entrypoint, arg) = translate_action_to_argument action in + Client_proto_context.transfer + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?branch + ~source + ~src_pk + ~src_sk + ~destination:contract + ~arg + ~amount:tez_amount + ~entrypoint + ?fee + ?gas_limit + ?storage_limit + ?counter + ~fee_parameter + ?verbose_signing + () + >>= function + | Ok res -> return res + | Error trace -> ( + match extract_error trace with + | None -> Lwt.return (Error trace) + | Some error -> fail error) + +type token_transfer = { + token_contract : string; + destination : string; + amount : Z.t; + tez_amount : string option; + fee : string option; + gas_limit : Gas.Arith.integral option; + storage_limit : Z.t option; +} + +let token_transfer_encoding = + let open Data_encoding in + conv + (fun { + token_contract; + destination; + amount; + tez_amount; + fee; + gas_limit; + storage_limit; + } -> + ( token_contract, + destination, + amount, + tez_amount, + fee, + gas_limit, + storage_limit )) + (fun ( token_contract, + destination, + amount, + tez_amount, + fee, + gas_limit, + storage_limit ) -> + { + token_contract; + destination; + amount; + tez_amount; + fee; + gas_limit; + storage_limit; + }) + (obj7 + (req "token_contract" string) + (req "destination" string) + (req "amount" z) + (opt "tez-amount" string) + (opt "fee" string) + (opt "gas-limit" Gas.Arith.n_integral_encoding) + (opt "storage-limit" z)) + +let tez_of_string_exn index field s = + match Tez.of_string s with + | Some t -> ok t + | None -> + error_with + "Invalid %s notation at entry %i, field \"%s\": %s" + Client_proto_args.tez_sym + index + field + s + +let tez_of_opt_string_exn index field s = + Option.map_e (tez_of_string_exn index field) s + +let build_transaction_operation ?(tez_amount = Tez.zero) ?fee ?gas_limit + ?storage_limit token action = + let entrypoint = action_to_entrypoint action in + let parameters = + Script.lazy_expr (Micheline.strip_locations (action_to_expr ~loc:() action)) + in + let operation = + Transaction + {amount = tez_amount; parameters; destination = token; entrypoint} + in + Injection.prepare_manager_operation + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + operation + +let prepare_single_token_transfer cctxt ?default_fee ?default_gas_limit + ?default_storage_limit ~chain ~block src index transfer = + Client_proto_contracts.ContractAlias.find_destination + cctxt + transfer.token_contract + >>=? fun (_, token) -> + contract_has_fa12_interface cctxt ~chain ~block ~contract:token () + >>=? fun () -> + Client_proto_contracts.ContractAlias.find_destination + cctxt + transfer.destination + >>=? fun (_, dest) -> + tez_of_opt_string_exn index "tez_amount" transfer.tez_amount + >>?= fun tez_amount -> + tez_of_opt_string_exn index "fee" transfer.fee >>?= fun transfer_fee -> + let fee = Option.either transfer_fee default_fee in + let gas_limit = Option.either transfer.gas_limit default_gas_limit in + let storage_limit = + Option.either transfer.storage_limit default_storage_limit + in + let action = Transfer (src, dest, transfer.amount) in + let operation = + build_transaction_operation + ?tez_amount + ?fee + ?gas_limit + ?storage_limit + token + action + in + return (Annotated_manager_operation.Annotated_manager_operation operation) + +let inject_token_transfer_batch (cctxt : #Protocol_client_context.full) ~chain + ~block ?confirmations ?dry_run ?verbose_signing ~sender ~source ~src_pk + ~src_sk ~token_transfers ~fee_parameter ?counter ?default_fee + ?default_gas_limit ?default_storage_limit () = + List.mapi_ep + (prepare_single_token_transfer + cctxt + ?default_fee + ?default_gas_limit + ?default_storage_limit + ~chain + ~block + sender) + token_transfers + >>=? fun contents -> + let (Manager_list contents) = + Annotated_manager_operation.manager_of_list contents + in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ~source + ~fee:(Limit.of_option default_fee) + ~gas_limit:(Limit.of_option default_gas_limit) + ~storage_limit:(Limit.of_option default_storage_limit) + ?counter + ~src_pk + ~src_sk + ~fee_parameter + contents + >>= function + | Ok _ -> return () + | Error trace -> ( + match extract_error trace with + | None -> Lwt.return (Error trace) + | Some error -> fail error) + +let is_viewable_action action = + match action with + | Get_balance (_, _) | Get_allowance (_, _, _) | Get_total_supply _ -> + return () + | _ -> fail (Not_a_viewable_entrypoint (action_to_entrypoint action)) + +let run_view_action (cctxt : #Protocol_client_context.full) ~chain ~block + ?source ~contract ~action ?payer ?gas ~unparsing_mode () = + is_viewable_action action >>=? fun () -> + contract_has_fa12_interface cctxt ~chain ~block ~contract () >>=? fun () -> + let entrypoint = action_to_entrypoint action in + let input = Micheline.strip_locations (view_input ~loc:() action) in + Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> + Plugin.RPC.Scripts.run_view + cctxt + (chain, block) + ~contract + ~input + ~chain_id + ?source + ?payer + ?gas + ~entrypoint + ~unparsing_mode + ~now:None + ~level:None + +let () = + Data_encoding.( + Registration.register + @@ def (Protocol.name ^ ".fa1.2.token_transfer") token_transfer_encoding) diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_fa12.mli b/src/proto_012_PsiThaCa/lib_client/client_proto_fa12.mli new file mode 100644 index 000000000000..8022bd2d7986 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_fa12.mli @@ -0,0 +1,161 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** [Client_proto_fa12] implements built-in support for the + {{:https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-7/tzip-7.md} + FA1.2} standard. This module features functions to check whether a + contract implements the standard interface and to interact with + such contracts using high-level [actions] that model the entrypoint + calls. + + This module also provides functions to unwrap [Micheline] values + into [actions], which can be useful for indexers or applications + using this module to interpret transactions on FA1.2 contracts as + FA1.2 operations. *) + +open Protocol +open Alpha_context +open Protocol_client_context + +(** A callback contract is represented by an address and a possible + entrypoint on which the transaction is done. *) +type callback_contract = Contract.t * string option + +type action = + | Transfer of Contract.t * Contract.t * Z.t + | Approve of Contract.t * Z.t + | Get_allowance of Contract.t * Contract.t * callback_contract + | Get_balance of Contract.t * callback_contract + | Get_total_supply of callback_contract + +val print_action : Format.formatter -> action -> unit + +val action_encoding : action Data_encoding.encoding + +val action_to_expr : + loc:'loc -> action -> ('loc, Script.prim) Tezos_micheline.Micheline.node + +val action_of_expr : + entrypoint:string -> + (_, Script.prim) Tezos_micheline.Micheline.node -> + action tzresult + +(** [convert_wrapped_parameter_into_action ccctx ~chain ~block + ~contract parameter] converts a wrapped FA1.2 contract [parameter] + into the corresponding FA1.2 [action]. + + That is, it takes a contract parameter on the form [C_1 .. (C_n + ... ))] where [C_1 ... C_n] is a sequence of + [Left]/[Right] constructors. It finds the entrypoint corresponding + to that path in [contract]'s interface. The result of the function + is the [] applied to the [action] + corresponding to that entrypoint. *) +val convert_wrapped_parameter_into_action : + full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Contract.t -> + Script.node -> + action tzresult Lwt.t + +(** Check whether a contract has an FA1.2 interface. *) +val contract_has_fa12_interface : + full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + contract:Alpha_context.Contract.t -> + unit -> + unit tzresult Lwt.t + +val call_contract : + full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?branch:int -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + contract:Contract.t -> + action:action -> + tez_amount:Tez.t -> + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + ?counter:Z.t -> + fee_parameter:Injection.fee_parameter -> + unit -> + (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult + Lwt.t + +(** Single transfer operation. *) +type token_transfer = { + token_contract : string; + destination : string; + amount : Z.t; + tez_amount : string option; + fee : string option; + gas_limit : Gas.Arith.integral option; + storage_limit : Z.t option; +} + +val token_transfer_encoding : token_transfer Data_encoding.t + +(** Inject a batch of token transfers. *) +val inject_token_transfer_batch : + full -> + chain:Chain_services.chain -> + block:Block_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + sender:Contract.t -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + token_transfers:token_transfer list -> + fee_parameter:Injection.fee_parameter -> + ?counter:counter -> + ?default_fee:Tez.t -> + ?default_gas_limit:Gas.Arith.integral -> + ?default_storage_limit:counter -> + unit -> + unit tzresult Lwt.t + +(** Run the action without injecting it. Only for views. *) +val run_view_action : + full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?source:Contract.t -> + contract:Contract.t -> + action:action -> + ?payer:Contract.t -> + ?gas:Gas.Arith.integral -> + unparsing_mode:Script_ir_translator.unparsing_mode -> + unit -> + Script.expr tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_multisig.ml b/src/proto_012_PsiThaCa/lib_client/client_proto_multisig.ml new file mode 100644 index 000000000000..7ffb4f883006 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_multisig.ml @@ -0,0 +1,1210 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol_client_context +open Protocol +open Alpha_context +open Michelson_v1_helpers + +type error += Contract_has_no_script of Contract.t + +type error += Not_a_supported_multisig_contract of Script_expr_hash.t + +type error += Contract_has_no_storage of Contract.t + +type error += Contract_has_unexpected_storage of Contract.t + +type error += Invalid_signature of signature + +type error += Not_enough_signatures of int * int + +type error += Action_deserialisation_error of Script.expr + +type error += Bytes_deserialisation_error of Bytes.t + +type error += Bad_deserialized_contract of (Contract.t * Contract.t) + +type error += Bad_deserialized_counter of (counter * counter) + +type error += Non_positive_threshold of int + +type error += Threshold_too_high of int * int + +type error += Unsupported_feature_generic_call of Script.expr + +type error += Unsupported_feature_generic_call_ty of Script.expr + +type error += Unsupported_feature_lambda of string + +type error += + | Ill_typed_argument of Contract.t * string * Script.expr * Script.expr + +type error += Ill_typed_lambda of Script.expr * Script.expr + +let () = + register_error_kind + `Permanent + ~id:"contractHasNoScript" + ~title: + "The given contract is not a multisig contract because it has no script" + ~description: + "A multisig command has referenced a scriptless smart contract instead \ + of a multisig smart contract." + ~pp:(fun ppf contract -> + Format.fprintf ppf "Contract has no script %a." Contract.pp contract) + Data_encoding.(obj1 (req "contract" Contract.encoding)) + (function Contract_has_no_script c -> Some c | _ -> None) + (fun c -> Contract_has_no_script c) ; + register_error_kind + `Permanent + ~id:"notASupportedMultisigContract" + ~title:"The given contract is not one of the supported contracts" + ~description: + "A multisig command has referenced a smart contract whose script is not \ + one of the known multisig contract scripts." + ~pp:(fun ppf hash -> + Format.fprintf + ppf + "Not a supported multisig contract.@\n\ + The hash of this script is %a, it was not found among in the list of \ + known multisig script hashes." + Script_expr_hash.pp + hash) + Data_encoding.(obj1 (req "hash" Script_expr_hash.encoding)) + (function Not_a_supported_multisig_contract h -> Some h | _ -> None) + (fun h -> Not_a_supported_multisig_contract h) ; + register_error_kind + `Permanent + ~id:"contractHasNoStorage" + ~title: + "The given contract is not a multisig contract because it has no storage" + ~description: + "A multisig command has referenced a smart contract without storage \ + instead of a multisig smart contract." + ~pp:(fun ppf contract -> + Format.fprintf ppf "Contract has no storage %a." Contract.pp contract) + Data_encoding.(obj1 (req "contract" Contract.encoding)) + (function Contract_has_no_storage c -> Some c | _ -> None) + (fun c -> Contract_has_no_storage c) ; + register_error_kind + `Permanent + ~id:"contractHasUnexpectedStorage" + ~title: + "The storage of the given contract is not of the shape expected for a \ + multisig contract" + ~description: + "A multisig command has referenced a smart contract whose storage is of \ + a different shape than the expected one." + ~pp:(fun ppf contract -> + Format.fprintf + ppf + "Contract has unexpected storage %a." + Contract.pp + contract) + Data_encoding.(obj1 (req "contract" Contract.encoding)) + (function Contract_has_unexpected_storage c -> Some c | _ -> None) + (fun c -> Contract_has_unexpected_storage c) ; + register_error_kind + `Permanent + ~id:"invalidSignature" + ~title: + "The following signature did not match a public key in the given \ + multisig contract" + ~description: + "A signature was given for a multisig contract that matched none of the \ + public keys of the contract signers" + ~pp:(fun ppf s -> + Format.fprintf ppf "Invalid signature %s." (Signature.to_b58check s)) + Data_encoding.(obj1 (req "invalid_signature" Signature.encoding)) + (function Invalid_signature s -> Some s | _ -> None) + (fun s -> Invalid_signature s) ; + register_error_kind + `Permanent + ~id:"notEnoughSignatures" + ~title:"Not enough signatures were provided for this multisig action" + ~description: + "To run an action on a multisig contract, you should provide at least as \ + many signatures as indicated by the threshold stored in the multisig \ + contract." + ~pp:(fun ppf (threshold, nsigs) -> + Format.fprintf + ppf + "Not enough signatures: only %d signatures were given but the \ + threshold is currently %d" + nsigs + threshold) + Data_encoding.(obj1 (req "threshold_nsigs" (tup2 int31 int31))) + (function + | Not_enough_signatures (threshold, nsigs) -> Some (threshold, nsigs) + | _ -> None) + (fun (threshold, nsigs) -> Not_enough_signatures (threshold, nsigs)) ; + register_error_kind + `Permanent + ~id:"actionDeserialisation" + ~title:"The expression is not a valid multisig action" + ~description: + "When trying to deserialise an action from a sequence of bytes, we got \ + an expression that does not correspond to a known multisig action" + ~pp:(fun ppf e -> + Format.fprintf + ppf + "Action deserialisation error %a." + Michelson_v1_printer.print_expr + e) + Data_encoding.(obj1 (req "expr" Script.expr_encoding)) + (function Action_deserialisation_error e -> Some e | _ -> None) + (fun e -> Action_deserialisation_error e) ; + register_error_kind + `Permanent + ~id:"bytesDeserialisation" + ~title:"The byte sequence is not a valid multisig action" + ~description: + "When trying to deserialise an action from a sequence of bytes, we got \ + an error" + ~pp:(fun ppf b -> + Format.fprintf ppf "Bytes deserialisation error %s." (Bytes.to_string b)) + Data_encoding.(obj1 (req "expr" bytes)) + (function Bytes_deserialisation_error b -> Some b | _ -> None) + (fun b -> Bytes_deserialisation_error b) ; + register_error_kind + `Permanent + ~id:"badDeserializedContract" + ~title:"The byte sequence is not for the given multisig contract" + ~description: + "When trying to deserialise an action from a sequence of bytes, we got \ + an action for another multisig contract" + ~pp:(fun ppf (received, expected) -> + Format.fprintf + ppf + "Bad deserialized contract, received %a expected %a." + Contract.pp + received + Contract.pp + expected) + Data_encoding.( + obj1 (req "received_expected" (tup2 Contract.encoding Contract.encoding))) + (function Bad_deserialized_contract b -> Some b | _ -> None) + (fun b -> Bad_deserialized_contract b) ; + register_error_kind + `Permanent + ~id:"Bad deserialized counter" + ~title:"Deserialized counter does not match the stored one" + ~description: + "The byte sequence references a multisig counter that does not match the \ + one currently stored in the given multisig contract" + ~pp:(fun ppf (received, expected) -> + Format.fprintf + ppf + "Bad deserialized counter, received %d expected %d." + received + expected) + Data_encoding.(obj1 (req "received_expected" (tup2 int31 int31))) + (function + | Bad_deserialized_counter (c1, c2) -> Some (Z.to_int c1, Z.to_int c2) + | _ -> None) + (fun (c1, c2) -> Bad_deserialized_counter (Z.of_int c1, Z.of_int c2)) ; + register_error_kind + `Permanent + ~id:"thresholdTooHigh" + ~title:"Given threshold is too high" + ~description: + "The given threshold is higher than the number of keys, this would lead \ + to a frozen multisig contract" + ~pp:(fun ppf (threshold, nkeys) -> + Format.fprintf + ppf + "Threshold too high: %d expected at most %d." + threshold + nkeys) + Data_encoding.(obj1 (req "received_expected" (tup2 int31 int31))) + (function Threshold_too_high (c1, c2) -> Some (c1, c2) | _ -> None) + (fun (c1, c2) -> Threshold_too_high (c1, c2)) ; + register_error_kind + `Permanent + ~id:"nonPositiveThreshold" + ~title:"Given threshold is not positive" + ~description:"A multisig threshold should be a positive number" + ~pp:(fun ppf threshold -> + Format.fprintf ppf "Multisig threshold %d should be positive." threshold) + Data_encoding.(obj1 (req "threshold" int31)) + (function Non_positive_threshold t -> Some t | _ -> None) + (fun t -> Non_positive_threshold t) ; + register_error_kind + `Permanent + ~id:"unsupportedGenericMultisigFeature" + ~title:"Unsupported multisig feature: generic call" + ~description: + "This multisig contract does not feature calling contracts with arguments" + ~pp:(fun ppf arg -> + Format.fprintf + ppf + "This multisig contract can only transfer tokens to contracts of type \ + unit; calling a contract with argument %a is not supported." + Michelson_v1_printer.print_expr + arg) + Data_encoding.(obj1 (req "arg" Script.expr_encoding)) + (function Unsupported_feature_generic_call arg -> Some arg | _ -> None) + (fun arg -> Unsupported_feature_generic_call arg) ; + register_error_kind + `Permanent + ~id:"unsupportedGenericMultisigFeatureTy" + ~title:"Unsupported multisig feature: generic call to non-unit entrypoint" + ~description: + "This multisig contract does not feature calling contracts with arguments" + ~pp:(fun ppf ty -> + Format.fprintf + ppf + "This multisig contract can only transfer tokens to contracts of type \ + unit; calling a contract of type %a is not supported." + Michelson_v1_printer.print_expr + ty) + Data_encoding.(obj1 (req "ty" Script.expr_encoding)) + (function Unsupported_feature_generic_call_ty ty -> Some ty | _ -> None) + (fun ty -> Unsupported_feature_generic_call_ty ty) ; + register_error_kind + `Permanent + ~id:"unsupportedGenericMultisigLambda" + ~title:"Unsupported multisig feature: running lambda" + ~description:"This multisig contract does not feature running lambdas" + ~pp:(fun ppf lam -> + Format.fprintf + ppf + "This multisig contract has a fixed set of actions, it cannot run the \ + following lambda: %s." + lam) + Data_encoding.(obj1 (req "lam" string)) + (function Unsupported_feature_lambda lam -> Some lam | _ -> None) + (fun lam -> Unsupported_feature_lambda lam) ; + register_error_kind + `Permanent + ~id:"illTypedArgumentForMultisig" + ~title:"Ill-typed argument in multi-signed transfer" + ~description: + "The provided argument for a transfer from a multisig contract is \ + ill-typed" + ~pp:(fun ppf (destination, entrypoint, parameter_ty, parameter) -> + Format.fprintf + ppf + "The entrypoint %s of contract %a called from a multisig contract is \ + of type %a; the provided parameter %a is ill-typed." + entrypoint + Contract.pp + destination + Michelson_v1_printer.print_expr + parameter_ty + Michelson_v1_printer.print_expr + parameter) + Data_encoding.( + obj4 + (req "destination" Contract.encoding) + (req "entrypoint" string) + (req "parameter_ty" Script.expr_encoding) + (req "parameter" Script.expr_encoding)) + (function + | Ill_typed_argument (destination, entrypoint, parameter_ty, parameter) -> + Some (destination, entrypoint, parameter_ty, parameter) + | _ -> None) + (fun (destination, entrypoint, parameter_ty, parameter) -> + Ill_typed_argument (destination, entrypoint, parameter_ty, parameter)) ; + register_error_kind + `Permanent + ~id:"illTypedLambdaForMultisig" + ~title:"Ill-typed lambda for multi-signed transfer" + ~description: + "The provided lambda for a transfer from a multisig contract is ill-typed" + ~pp:(fun ppf (lam, exp) -> + Format.fprintf + ppf + "The provided lambda %a for multisig contract is ill-typed; %a is \ + expected." + Michelson_v1_printer.print_expr + lam + Michelson_v1_printer.print_expr + exp) + Data_encoding.( + obj2 (req "lam" Script.expr_encoding) (req "exp" Script.expr_encoding)) + (function Ill_typed_lambda (lam, exp) -> Some (lam, exp) | _ -> None) + (fun (lam, exp) -> Ill_typed_lambda (lam, exp)) + +(* The multisig contract script written by Arthur Breitman + https://github.com/murbard/smart-contracts/blob/abdb582d8f1fe7ba7eb15975867d8862cb70acfe/multisig/michelson/generic.tz *) +let multisig_script_string = + {| +parameter (or (unit %default) + (pair %main + (pair :payload + (nat %counter) # counter, used to prevent replay attacks + (or :action # payload to sign, represents the requested action + (lambda %operation unit (list operation)) + (pair %change_keys # change the keys controlling the multisig + (nat %threshold) # new threshold + (list %keys key)))) # new list of keys + (list %sigs (option signature)))); # signatures + +storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; + +code + { + UNPAIR ; + IF_LEFT + { # Default entry point: do nothing + # This entry point can be used to send tokens to this contract + DROP ; NIL operation ; PAIR } + { # Main entry point + # Assert no token was sent: + # to send tokens, the default entry point should be used + PUSH mutez 0 ; AMOUNT ; ASSERT_CMPEQ ; + SWAP ; DUP ; DIP { SWAP } ; + DIP + { + UNPAIR ; + # pair the payload with the current contract address, to ensure signatures + # can't be replayed accross different contracts if a key is reused. + DUP ; SELF ; ADDRESS ; CHAIN_ID ; PAIR ; PAIR ; + PACK ; # form the binary payload that we expect to be signed + DIP { UNPAIR @counter ; DIP { SWAP } } ; SWAP + } ; + + # Check that the counters match + UNPAIR @stored_counter; DIP { SWAP }; + ASSERT_CMPEQ ; + + # Compute the number of valid signatures + DIP { SWAP } ; UNPAIR @threshold @keys; + DIP + { + # Running count of valid signatures + PUSH @valid nat 0; SWAP ; + ITER + { + DIP { SWAP } ; SWAP ; + IF_CONS + { + IF_SOME + { SWAP ; + DIP + { + SWAP ; DIIP { DUUP } ; + # Checks signatures, fails if invalid + { DUUUP; DIP {CHECK_SIGNATURE}; SWAP; IF {DROP} {FAILWITH} }; + PUSH nat 1 ; ADD @valid } } + { SWAP ; DROP } + } + { + # There were fewer signatures in the list + # than keys. Not all signatures must be present, but + # they should be marked as absent using the option type. + FAIL + } ; + SWAP + } + } ; + # Assert that the threshold is less than or equal to the + # number of valid signatures. + ASSERT_CMPLE ; + # Assert no unchecked signature remains + IF_CONS {FAIL} {} ; + DROP ; + + # Increment counter and place in storage + DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR} ; + + # We have now handled the signature verification part, + # produce the operation requested by the signers. + IF_LEFT + { # Get operation + UNIT ; EXEC + } + { + # Change set of signatures + DIP { CAR } ; SWAP ; PAIR ; NIL operation + }; + PAIR } + } +|} + +(* Client_proto_context.originate expects the contract script as a Script.expr *) +let multisig_script : Script.expr = + Michelson_v1_parser.parse_toplevel ?check:(Some true) multisig_script_string + |> Tezos_micheline.Micheline_parser.no_parsing_error + |> function + | Error _ -> + assert false + (* This is a top level assertion, it is asserted when the client's process runs. *) + | Ok parsing_result -> parsing_result.Michelson_v1_parser.expanded + +let multisig_script_hash = + let bytes = + Data_encoding.Binary.to_bytes_exn Script.expr_encoding multisig_script + in + Script_expr_hash.hash_bytes [bytes] + +(* The previous multisig script is the only one that the client can + originate but the client knows how to interact with several + versions of the multisig contract. For each version, the description + indicates which features are available and how to interact with + the contract. *) + +type multisig_contract_description = { + hash : Script_expr_hash.t; + (* The hash of the contract script *) + requires_chain_id : bool; + (* The signatures should contain the chain identifier *) + main_entrypoint : string option; + (* name of the main entrypoint of the multisig contract, None means use the default entrypoint *) + generic : bool; + (* False means that the contract uses a custom action type, true + means that the contract expects the action as a (lambda unit + (list operation)). *) +} + +(* List of known multisig contracts hashes with their kinds *) +let known_multisig_contracts : multisig_contract_description list = + [ + { + (* First supported version of the generic multisig contract. Supports incoming + transfers from unauthenticated senders and outgoing transfers of + arbitrary operation lists. + + See docs/user/multisig.rst for more details. *) + hash = multisig_script_hash; + requires_chain_id = true; + main_entrypoint = Some "main"; + generic = true; + }; + { + (* Fourth supported version of the legacy multisig contract. This script is + functionally equivalent to the third version but uses the [DUP 2] + instruction introduced in Edo instead of the macro for [DIG 2; DUP; DUG 3]. *) + hash = + Script_expr_hash.of_b58check_exn + "exprutz4BVGJ3Qms6qjmqvUF8sEk27H1cfqhRT17qpTdhEs5hEjbWm"; + requires_chain_id = true; + main_entrypoint = None; + generic = false; + }; + { + (* Third supported version of the legacy multisig contract. This script is + functionally equivalent to the second version but uses the [DIP 2] + instruction introduced in Babylon instead of the [DIIP] macro. *) + hash = + Script_expr_hash.of_b58check_exn + "exprumpS39YZd26Cn4kyKUK5ezTR3at838iGWg7i6uETv8enDeAnfb"; + requires_chain_id = true; + main_entrypoint = None; + generic = false; + }; + { + (* Second supported version of the legacy multisig contract. This script + is the one resulting from the stitching of the Babylon protocol, the + only difference with the first version is that the chain id is part of + the data to sign. *) + hash = + Script_expr_hash.of_b58check_exn + "exprtw1v4KvQN414oEXdGuA1U3eQizuCdS8cipx8QGK8TbNLRwc3qL"; + requires_chain_id = true; + main_entrypoint = None; + generic = false; + }; + { + (* First supported version of the legacy multisig contract. This script should not + be used anymore because it is subject to a small replay attack: when + the test chain is forked both instances have the same address and + counter so whatever happens on the test chain can be replayed on the + main chain. The script has been fixed during the activation of the + Babylon protocol. *) + hash = + Script_expr_hash.of_b58check_exn + "expru4Ju9kf6MQ216FxUEsb9P6j8UhkPtsFcYP8r9XhQSRb47FZGfM"; + requires_chain_id = false; + main_entrypoint = None; + generic = false; + }; + ] + +let known_multisig_hashes = + List.map (fun descr -> descr.hash) known_multisig_contracts + +let check_multisig_script_hash hash : + multisig_contract_description tzresult Lwt.t = + match + List.find_opt + (fun d -> Script_expr_hash.(d.hash = hash)) + known_multisig_contracts + with + | None -> fail (Not_a_supported_multisig_contract hash) + | Some d -> return d + +(* Returns [Ok ()] if [~contract] is an originated contract whose code + is [multisig_script] *) +let check_multisig_contract (cctxt : #Protocol_client_context.full) ~chain + ~block contract = + Client_proto_context.get_script_hash cctxt ~chain ~block contract + >>=? function + | None -> fail (Contract_has_no_script contract) + | Some hash -> check_multisig_script_hash hash + +(* Some Michelson building functions, specific to the needs of the multisig + interface.*) + +(* The type of the lambdas consumed by the generic script *) +let lambda_action_t ~loc = lambda_t ~loc (unit_t ~loc) (operations_t ~loc) + +(* Conversion functions from common types to Script_expr using the optimized representation *) +let mutez ~loc (amount : Tez.t) = int ~loc (Z.of_int64 (Tez.to_mutez amount)) + +let optimized_key_hash ~loc (key_hash : Signature.Public_key_hash.t) = + bytes + ~loc + (Data_encoding.Binary.to_bytes_exn + Signature.Public_key_hash.encoding + key_hash) + +let optimized_address ~loc ~(address : Contract.t) ~(entrypoint : string) = + let entrypoint = match entrypoint with "default" -> "" | name -> name in + bytes + ~loc + (Data_encoding.Binary.to_bytes_exn + Data_encoding.(tup2 Contract.encoding Variable.string) + (address, entrypoint)) + +let optimized_key ~loc (key : Signature.Public_key.t) = + bytes + ~loc + (Data_encoding.Binary.to_bytes_exn Signature.Public_key.encoding key) + +(** * Actions *) + +type multisig_action = + | Transfer of { + amount : Tez.t; + destination : Contract.t; + entrypoint : string; + parameter_type : Script.expr; + parameter : Script.expr; + } + | Change_delegate of public_key_hash option + | Lambda of Script.expr + | Change_keys of Z.t * public_key list + +let action_to_expr_generic ~loc = function + | Transfer {amount; destination; entrypoint; parameter_type; parameter} -> ( + match Contract.is_implicit destination with + | Some destination -> + lambda_from_string + @@ Managed_contract.build_lambda_for_transfer_to_implicit + ~destination + ~amount + >|? left ~loc + | None -> + lambda_from_string + @@ Managed_contract.build_lambda_for_transfer_to_originated + ~destination + ~entrypoint + ~parameter_type + ~parameter + ~amount + >|? left ~loc) + | Lambda code -> + Error_monad.ok Tezos_micheline.Micheline.(left ~loc (root code)) + | Change_delegate delegate -> + lambda_from_string + @@ Managed_contract.build_lambda_for_set_delegate ~delegate + >|? left ~loc + | Change_keys (threshold, keys) -> + let optimized_keys = seq ~loc (List.map (optimized_key ~loc) keys) in + let expr = right ~loc (pair ~loc (int ~loc threshold) optimized_keys) in + Error_monad.ok expr + +let action_to_expr_legacy ~loc = function + | Transfer {amount; destination; entrypoint; parameter_type; parameter} -> + if parameter <> Tezos_micheline.Micheline.strip_locations (unit ~loc:()) + then Error_monad.error @@ Unsupported_feature_generic_call parameter + else if + parameter_type + <> Tezos_micheline.Micheline.strip_locations (unit_t ~loc:()) + then + Error_monad.error @@ Unsupported_feature_generic_call_ty parameter_type + else + Error_monad.ok + @@ left + ~loc + (pair + ~loc + (mutez ~loc amount) + (optimized_address ~loc ~address:destination ~entrypoint)) + | Lambda _ -> Error_monad.error @@ Unsupported_feature_lambda "" + | Change_delegate delegate -> + let delegate_opt = + match delegate with + | None -> none ~loc () + | Some delegate -> some ~loc (optimized_key_hash ~loc delegate) + in + Error_monad.ok @@ right ~loc (left ~loc delegate_opt) + | Change_keys (threshold, keys) -> + let optimized_keys = seq ~loc (List.map (optimized_key ~loc) keys) in + let expr = right ~loc (pair ~loc (int ~loc threshold) optimized_keys) in + Error_monad.ok (right ~loc expr) + +let action_to_expr ~loc ~generic action = + if generic then action_to_expr_generic ~loc action + else action_to_expr_legacy ~loc action + +let action_of_expr_generic e = + let fail () = + Error_monad.fail + (Action_deserialisation_error + (Tezos_micheline.Micheline.strip_locations e)) + in + match e with + | Tezos_micheline.Micheline.Prim (_, Script.D_Left, [lam], []) -> + return @@ Lambda (Tezos_micheline.Micheline.strip_locations lam) + | Tezos_micheline.Micheline.Prim + ( _, + Script.D_Right, + [ + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [ + Tezos_micheline.Micheline.Int (_, threshold); + Tezos_micheline.Micheline.Seq (_, key_bytes); + ], + [] ); + ], + [] ) -> + List.map_es + (function + | Tezos_micheline.Micheline.Bytes (_, s) -> + return + @@ Data_encoding.Binary.of_bytes_exn + Signature.Public_key.encoding + s + | _ -> fail ()) + key_bytes + >>=? fun keys -> return @@ Change_keys (threshold, keys) + | _ -> fail () + +let action_of_expr_not_generic e = + let fail () = + Error_monad.fail + (Action_deserialisation_error + (Tezos_micheline.Micheline.strip_locations e)) + in + match e with + | Tezos_micheline.Micheline.Prim + ( _, + Script.D_Left, + [ + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [ + Tezos_micheline.Micheline.Int (_, i); + Tezos_micheline.Micheline.Bytes (_, s); + ], + [] ); + ], + [] ) -> ( + match Tez.of_mutez (Z.to_int64 i) with + | None -> fail () + | Some amount -> + return + @@ Transfer + { + amount; + destination = + Data_encoding.Binary.of_bytes_exn Contract.encoding s; + entrypoint = "default"; + parameter_type = + Tezos_micheline.Micheline.strip_locations @@ unit_t ~loc:(); + parameter = + Tezos_micheline.Micheline.strip_locations @@ unit ~loc:(); + }) + | Tezos_micheline.Micheline.Prim + ( _, + Script.D_Right, + [ + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Left, + [Tezos_micheline.Micheline.Prim (_, Script.D_None, [], [])], + [] ); + ], + [] ) -> + return @@ Change_delegate None + | Tezos_micheline.Micheline.Prim + ( _, + Script.D_Right, + [ + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Left, + [ + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Some, + [Tezos_micheline.Micheline.Bytes (_, s)], + [] ); + ], + [] ); + ], + [] ) -> + return + @@ Change_delegate + (Some + (Data_encoding.Binary.of_bytes_exn + Signature.Public_key_hash.encoding + s)) + | Tezos_micheline.Micheline.Prim + ( _, + Script.D_Right, + [ + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Right, + [ + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [ + Tezos_micheline.Micheline.Int (_, threshold); + Tezos_micheline.Micheline.Seq (_, key_bytes); + ], + [] ); + ], + [] ); + ], + [] ) -> + List.map_es + (function + | Tezos_micheline.Micheline.Bytes (_, s) -> + return + @@ Data_encoding.Binary.of_bytes_exn + Signature.Public_key.encoding + s + | _ -> fail ()) + key_bytes + >>=? fun keys -> return @@ Change_keys (threshold, keys) + | _ -> fail () + +let action_of_expr ~generic = + if generic then action_of_expr_generic else action_of_expr_not_generic + +type key_list = Signature.Public_key.t list + +(* The relevant information that we can get about a multisig smart contract *) +type multisig_contract_information = { + counter : Z.t; + threshold : Z.t; + keys : key_list; +} + +let multisig_get_information (cctxt : #Protocol_client_context.full) ~chain + ~block contract = + let open Client_proto_context in + let open Tezos_micheline.Micheline in + get_storage cctxt ~chain ~block ~unparsing_mode:Readable contract + >>=? fun storage_opt -> + match storage_opt with + | None -> fail (Contract_has_no_storage contract) + | Some storage -> ( + match root storage with + | Prim + ( _, + D_Pair, + [Int (_, counter); Int (_, threshold); Seq (_, key_nodes)], + _ ) -> + List.map_es + (function + | String (_, key_str) -> + return @@ Signature.Public_key.of_b58check_exn key_str + | _ -> fail (Contract_has_unexpected_storage contract)) + key_nodes + >>=? fun keys -> return {counter; threshold; keys} + | _ -> fail (Contract_has_unexpected_storage contract)) + +let multisig_create_storage ~counter ~threshold ~keys () : + Script.expr tzresult Lwt.t = + let loc = Tezos_micheline.Micheline_parser.location_zero in + let open Tezos_micheline.Micheline in + List.map_es + (fun key -> + let key_str = Signature.Public_key.to_b58check key in + return (String (loc, key_str))) + keys + >>=? fun l -> + return @@ strip_locations + @@ pair ~loc (int ~loc counter) (pair ~loc (int ~loc threshold) (seq ~loc l)) + +(* Client_proto_context.originate expects the initial storage as a string *) +let multisig_storage_string ~counter ~threshold ~keys () = + multisig_create_storage ~counter ~threshold ~keys () >>=? fun expr -> + return @@ Format.asprintf "%a" Michelson_v1_printer.print_expr expr + +let multisig_create_param ~counter ~generic ~action ~optional_signatures () : + Script.expr tzresult Lwt.t = + let loc = 0 in + let open Tezos_micheline.Micheline in + List.map_es + (fun sig_opt -> + match sig_opt with + | None -> return @@ none ~loc () + | Some signature -> + return @@ some ~loc (String (loc, Signature.to_b58check signature))) + optional_signatures + >>=? fun l -> + Lwt.return @@ action_to_expr ~loc ~generic action >>=? fun expr -> + return @@ strip_locations + @@ pair ~loc (pair ~loc (int ~loc counter) expr) (Seq (loc, l)) + +let multisig_param_string ~counter ~action ~optional_signatures ~generic () = + multisig_create_param ~counter ~action ~optional_signatures ~generic () + >>=? fun expr -> + return @@ Format.asprintf "%a" Michelson_v1_printer.print_expr expr + +let get_contract_address_maybe_chain_id ~descr ~loc ~chain_id contract = + let address = + bytes ~loc (Data_encoding.Binary.to_bytes_exn Contract.encoding contract) + in + if descr.requires_chain_id then + let chain_id_bytes = + bytes ~loc (Data_encoding.Binary.to_bytes_exn Chain_id.encoding chain_id) + in + pair ~loc chain_id_bytes address + else address + +let multisig_bytes ~counter ~action ~contract ~chain_id ~descr () = + let loc = 0 in + Lwt.return @@ action_to_expr ~loc ~generic:descr.generic action + >>=? fun expr -> + let triple = + pair + ~loc + (get_contract_address_maybe_chain_id ~descr ~loc ~chain_id contract) + (pair ~loc (int ~loc counter) expr) + in + let bytes = + Data_encoding.Binary.to_bytes_exn Script.expr_encoding + @@ Tezos_micheline.Micheline.strip_locations @@ triple + in + return @@ Bytes.cat (Bytes.of_string "\005") bytes + +let check_threshold ~threshold ~keys () = + let threshold = Z.to_int threshold in + if Compare.List_length_with.(keys < threshold) then + fail (Threshold_too_high (threshold, List.length keys)) + else if Compare.Int.(threshold <= 0) then + fail (Non_positive_threshold threshold) + else return_unit + +let originate_multisig (cctxt : #Protocol_client_context.full) ~chain ~block + ?confirmations ?dry_run ?branch ?fee ?gas_limit ?storage_limit + ?verbose_signing ~delegate ~threshold ~keys ~balance ~source ~src_pk ~src_sk + ~fee_parameter () = + multisig_storage_string ~counter:Z.zero ~threshold ~keys () + >>=? fun initial_storage -> + check_threshold ~threshold ~keys () >>=? fun () -> + Client_proto_context.originate_contract + cctxt + ~chain + ~block + ?branch + ?confirmations + ?dry_run + ?fee + ?gas_limit + ?storage_limit + ?verbose_signing + ~delegate + ~initial_storage + ~balance + ~source + ~src_pk + ~src_sk + ~code:multisig_script + ~fee_parameter + () + +type multisig_prepared_action = { + bytes : Bytes.t; + threshold : Z.t; + keys : public_key list; + counter : Z.t; + entrypoint : string option; + generic : bool; +} + +let check_parameter_type (cctxt : #Protocol_client_context.full) ?gas ?legacy + ~destination ~entrypoint ~parameter_type ~parameter () = + trace + (Ill_typed_argument (destination, entrypoint, parameter_type, parameter)) + @@ Plugin.RPC.Scripts.typecheck_data + cctxt + (cctxt#chain, cctxt#block) + ~data:parameter + ~ty:parameter_type + ?gas + ?legacy + >>=? fun _ -> return_unit + +let check_action (cctxt : #Protocol_client_context.full) ~action ~balance ?gas + ?legacy () = + match action with + | Change_keys (threshold, keys) -> + check_threshold ~threshold ~keys () >>=? fun () -> return_unit + | Transfer {amount; destination; entrypoint; parameter_type; parameter} -> + check_parameter_type + cctxt + ~destination + ~entrypoint + ~parameter_type + ~parameter + () + >>=? fun () -> + if Tez.(amount > balance) then + (* This is warning only because the contract can be filled + before sending the signatures or even in the same + transaction *) + Format.eprintf + "Transferred amount is bigger than current multisig balance" ; + return_unit + | Lambda code -> + let action_t = + Tezos_micheline.Micheline.strip_locations (lambda_action_t ~loc:()) + in + trace (Ill_typed_lambda (code, action_t)) + @@ Plugin.RPC.Scripts.typecheck_data + cctxt + (cctxt#chain, cctxt#block) + ~data:code + ~ty:action_t + ?gas + ?legacy + >>=? fun _remaining_gas -> return_unit + | _ -> return_unit + +let prepare_multisig_transaction (cctxt : #Protocol_client_context.full) ~chain + ~block ~multisig_contract ~action () = + let contract = multisig_contract in + check_multisig_contract cctxt ~chain ~block contract >>=? fun descr -> + multisig_get_information cctxt ~chain ~block contract + >>=? fun {counter; threshold; keys} -> + Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> + multisig_bytes ~counter ~action ~contract ~descr ~chain_id () + >>=? fun bytes -> + Client_proto_context.get_balance + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + contract + >>=? fun balance -> + check_action cctxt ~action ~balance () >>=? fun () -> + return + { + bytes; + threshold; + keys; + counter; + entrypoint = descr.main_entrypoint; + generic = descr.generic; + } + +let check_multisig_signatures ~bytes ~threshold ~keys signatures = + let key_array = Array.of_list keys in + let nkeys = Array.length key_array in + let opt_sigs_arr = Array.make nkeys None in + let matching_key_found = ref false in + let check_signature_against_key_number signature i key = + if Signature.check key signature bytes then ( + matching_key_found := true ; + opt_sigs_arr.(i) <- Some signature) + in + List.iter_ep + (fun signature -> + matching_key_found := false ; + List.iteri (check_signature_against_key_number signature) keys ; + fail_unless !matching_key_found (Invalid_signature signature)) + signatures + >>=? fun () -> + let opt_sigs = Array.to_list opt_sigs_arr in + let signature_count = + List.fold_left + (fun n sig_opt -> match sig_opt with Some _ -> n + 1 | None -> n) + 0 + opt_sigs + in + let threshold_int = Z.to_int threshold in + if signature_count >= threshold_int then return opt_sigs + else fail (Not_enough_signatures (threshold_int, signature_count)) + +let call_multisig (cctxt : #Protocol_client_context.full) ~chain ~block + ?confirmations ?dry_run ?verbose_signing ?branch ~source ~src_pk ~src_sk + ~multisig_contract ~action ~signatures ~amount ?fee ?gas_limit + ?storage_limit ?counter ~fee_parameter () = + prepare_multisig_transaction cctxt ~chain ~block ~multisig_contract ~action () + >>=? fun { + bytes; + threshold; + keys; + counter = stored_counter; + entrypoint; + generic; + } -> + check_multisig_signatures ~bytes ~threshold ~keys signatures + >>=? fun optional_signatures -> + multisig_param_string + ~counter:stored_counter + ~action + ~optional_signatures + ~generic + () + >>=? fun arg -> + Client_proto_context.transfer + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?branch + ~source + ~src_pk + ~src_sk + ~destination:multisig_contract + ?entrypoint + ~arg + ~amount + ?fee + ?gas_limit + ?storage_limit + ?counter + ~fee_parameter + ?verbose_signing + () + +let action_of_bytes ~multisig_contract ~stored_counter ~descr ~chain_id bytes = + if + Compare.Int.(Bytes.length bytes >= 1) + && Compare.Int.(TzEndian.get_uint8 bytes 0 = 0x05) + then + let nbytes = Bytes.sub bytes 1 (Bytes.length bytes - 1) in + match Data_encoding.Binary.of_bytes_opt Script.expr_encoding nbytes with + | None -> fail (Bytes_deserialisation_error bytes) + | Some e -> ( + match Tezos_micheline.Micheline.root e with + | Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [ + Tezos_micheline.Micheline.Bytes (_, contract_bytes); + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [Tezos_micheline.Micheline.Int (_, counter); e], + [] ); + ], + [] ) + when not descr.requires_chain_id -> + let contract = + Data_encoding.Binary.of_bytes_exn Contract.encoding contract_bytes + in + if counter = stored_counter then + if Contract.(multisig_contract = contract) then + action_of_expr ~generic:descr.generic e + else + fail (Bad_deserialized_contract (contract, multisig_contract)) + else fail (Bad_deserialized_counter (counter, stored_counter)) + | Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [ + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [ + Tezos_micheline.Micheline.Bytes (_, chain_id_bytes); + Tezos_micheline.Micheline.Bytes (_, contract_bytes); + ], + [] ); + Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [Tezos_micheline.Micheline.Int (_, counter); e], + [] ); + ], + [] ) + when descr.requires_chain_id -> + let contract = + Data_encoding.Binary.of_bytes_exn Contract.encoding contract_bytes + in + let cid = + Data_encoding.Binary.of_bytes_exn Chain_id.encoding chain_id_bytes + in + if counter = stored_counter then + if multisig_contract = contract && chain_id = cid then + action_of_expr ~generic:descr.generic e + else + fail (Bad_deserialized_contract (contract, multisig_contract)) + else fail (Bad_deserialized_counter (counter, stored_counter)) + | _ -> fail (Bytes_deserialisation_error bytes)) + else fail (Bytes_deserialisation_error bytes) + +let call_multisig_on_bytes (cctxt : #Protocol_client_context.full) ~chain ~block + ?confirmations ?dry_run ?verbose_signing ?branch ~source ~src_pk ~src_sk + ~multisig_contract ~bytes ~signatures ~amount ?fee ?gas_limit ?storage_limit + ?counter ~fee_parameter () = + multisig_get_information cctxt ~chain ~block multisig_contract + >>=? fun info -> + check_multisig_contract cctxt ~chain ~block multisig_contract + >>=? fun descr -> + Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> + action_of_bytes + ~multisig_contract + ~stored_counter:info.counter + ~chain_id + ~descr + bytes + >>=? fun action -> + call_multisig + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?branch + ~source + ~src_pk + ~src_sk + ~multisig_contract + ~action + ~signatures + ~amount + ?fee + ?gas_limit + ?storage_limit + ?counter + ~fee_parameter + ?verbose_signing + () diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_multisig.mli b/src/proto_012_PsiThaCa/lib_client/client_proto_multisig.mli new file mode 100644 index 000000000000..ad4a6306d60c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_multisig.mli @@ -0,0 +1,150 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Protocol_client_context + +(* The script of the recommended version of the multisig contract. + This is the script originated by [originate_multisig]. *) +val multisig_script : Script.expr + +(* A description of the possible actions that a multisig contract can run. *) +type multisig_action = + | Transfer of { + amount : Tez.t; + destination : Contract.t; + entrypoint : string; + parameter_type : Script.expr; + parameter : Script.expr; + } + | Change_delegate of public_key_hash option + | Lambda of Script.expr + | Change_keys of Z.t * public_key list + +(* A prepared action is the byte sequence that needs to be signed to run the + action together with some data that can be useful for the user and to call + the multisig contracts once enough signatures are provided. *) +type multisig_prepared_action = { + (* The sequence of bytes to be signed. *) + bytes : Bytes.t; + (* Information reported to the user so that she knows who can sign and how + many signatures are required. *) + threshold : Z.t; + keys : public_key list; + (* Information needed to execute the action ones enough signatures have been + gathered. *) + counter : Z.t; + entrypoint : string option; + generic : bool; +} + +(* The client will refuse to interact with a multisig contract if the hash of + its script is not in this list. *) +val known_multisig_hashes : Script_expr_hash.t list + +(* Originate a new multisig contract *) +val originate_multisig : + full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?branch:int -> + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + ?verbose_signing:bool -> + delegate:public_key_hash option -> + threshold:Z.t -> + keys:public_key list -> + balance:Tez.t -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + fee_parameter:Injection.fee_parameter -> + unit -> + (Kind.origination Kind.manager Injection.result * Contract.t) tzresult Lwt.t + +(* Prepare an action, see [multisig_prepared_action]. *) +val prepare_multisig_transaction : + full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + multisig_contract:Contract.t -> + action:multisig_action -> + unit -> + multisig_prepared_action tzresult Lwt.t + +(* Call a multisig contract, requesting it to run an action. *) +val call_multisig : + full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?branch:int -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + multisig_contract:Contract.t -> + action:multisig_action -> + signatures:Signature.t list -> + amount:Tez.t -> + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + ?counter:Z.t -> + fee_parameter:Injection.fee_parameter -> + unit -> + (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult + Lwt.t + +(* Same as [call_multisig] but the action to be performed is reconstructed from + the byte sequence that was signed. *) +val call_multisig_on_bytes : + full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?branch:int -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + multisig_contract:Contract.t -> + bytes:Bytes.t -> + signatures:Signature.t list -> + amount:Tez.t -> + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + ?counter:Z.t -> + fee_parameter:Injection.fee_parameter -> + unit -> + (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult + Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_programs.ml b/src/proto_012_PsiThaCa/lib_client/client_proto_programs.ml new file mode 100644 index 000000000000..b0b1b295e529 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_programs.ml @@ -0,0 +1,344 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Tezos_micheline +open Michelson_v1_printer + +module Program = Client_aliases.Alias (struct + type t = Michelson_v1_parser.parsed Micheline_parser.parsing_result + + include Compare.Make (struct + type nonrec t = t + + let compare = Micheline_parser.compare Michelson_v1_parser.compare_parsed + end) + + let encoding = + Data_encoding.conv + (fun ({Michelson_v1_parser.source; _}, _) -> source) + (fun source -> Michelson_v1_parser.parse_toplevel source) + Data_encoding.string + + let of_source source = return (Michelson_v1_parser.parse_toplevel source) + + let to_source ({Michelson_v1_parser.source; _}, _) = return source + + let name = "script" +end) + +let print_errors ?parsed (cctxt : #Client_context.printer) errs ~show_source = + cctxt#warning + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:false + ?parsed + ~show_source) + errs + >>= fun () -> + cctxt#error "error running script" >>= fun () -> return_unit + +let print_view_result (cctxt : #Client_context.printer) = function + | Ok expr -> cctxt#message "%a" print_expr expr >>= fun () -> return_unit + | Error errs -> print_errors cctxt ~show_source:false errs + +let print_run_result (cctxt : #Client_context.printer) ~show_source ~parsed = + function + | Ok (storage, operations, maybe_lazy_storage_diff) -> + cctxt#message + "@[@[storage@,\ + %a@]@,\ + @[emitted operations@,\ + %a@]@,\ + @[big_map diff@,\ + %a@]@]@." + print_expr + storage + (Format.pp_print_list Operation_result.pp_internal_operation) + operations + (fun ppf -> function + | None -> () + | Some diff -> print_big_map_diff ppf diff) + maybe_lazy_storage_diff + >>= fun () -> return_unit + | Error errs -> print_errors cctxt errs ~show_source ~parsed + +let print_trace_result (cctxt : #Client_context.printer) ~show_source ~parsed = + function + | Ok (storage, operations, trace, maybe_lazy_storage_diff) -> + cctxt#message + "@[@[storage@,\ + %a@]@,\ + @[emitted operations@,\ + %a@]@,\ + @[big_map diff@,\ + %a@]@,\ + @[trace@,\ + %a@]@]@." + print_expr + storage + (Format.pp_print_list Operation_result.pp_internal_operation) + operations + (fun ppf -> function + | None -> () + | Some diff -> print_big_map_diff ppf diff) + maybe_lazy_storage_diff + print_execution_trace + trace + >>= fun () -> return_unit + | Error errs -> print_errors cctxt errs ~show_source ~parsed + +type simulation_params = { + input : Michelson_v1_parser.parsed; + unparsing_mode : Script_ir_translator.unparsing_mode; + now : Script_timestamp.t option; + level : Script_int.n Script_int.num option; + source : Contract.t option; + payer : Contract.t option; + gas : Gas.Arith.integral option; +} + +type run_view_params = { + shared_params : simulation_params; + contract : Contract.t; + entrypoint : string; +} + +type run_params = { + shared_params : simulation_params; + amount : Tez.t option; + balance : Tez.t; + program : Michelson_v1_parser.parsed; + storage : Michelson_v1_parser.parsed; + entrypoint : string option; +} + +let run_view (cctxt : #Protocol_client_context.rpc_context) + ~(chain : Chain_services.chain) ~block (params : run_view_params) = + let { + shared_params = {input; unparsing_mode; now; level; source; payer; gas}; + contract; + entrypoint; + } = + params + in + Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> + Plugin.RPC.Scripts.run_view + cctxt + (chain, block) + ?gas + ~contract + ~entrypoint + ~input:input.expanded + ~chain_id + ?source + ?payer + ~unparsing_mode + ~now + ~level + +let run (cctxt : #Protocol_client_context.rpc_context) + ~(chain : Chain_services.chain) ~block (params : run_params) = + Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> + let { + shared_params = {input; unparsing_mode; now; level; source; payer; gas}; + program; + amount; + balance; + storage; + entrypoint; + } = + params + in + let amount = Option.value ~default:Tez.fifty_cents amount in + Plugin.RPC.Scripts.run_code + cctxt + (chain, block) + ?gas + ?entrypoint + ~unparsing_mode + ~script:program.expanded + ~storage:storage.expanded + ~input:input.expanded + ~amount + ~balance + ~chain_id + ~source + ~payer + ~now + ~level + +let trace (cctxt : #Protocol_client_context.rpc_context) + ~(chain : Chain_services.chain) ~block (params : run_params) = + Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> + let { + shared_params = {input; unparsing_mode; now; level; source; payer; gas}; + program; + amount; + balance; + storage; + entrypoint; + } = + params + in + let amount = Option.value ~default:Tez.fifty_cents amount in + Plugin.RPC.Scripts.trace_code + cctxt + (chain, block) + ?gas + ?entrypoint + ~unparsing_mode + ~script:program.expanded + ~storage:storage.expanded + ~input:input.expanded + ~amount + ~balance + ~chain_id + ~source + ~payer + ~now + ~level + +let typecheck_data cctxt ~(chain : Chain_services.chain) ~block ?gas ?legacy + ~(data : Michelson_v1_parser.parsed) ~(ty : Michelson_v1_parser.parsed) () = + Plugin.RPC.Scripts.typecheck_data + cctxt + (chain, block) + ?gas + ?legacy + ~data:data.expanded + ~ty:ty.expanded + +let typecheck_program cctxt ~(chain : Chain_services.chain) ~block ?gas ?legacy + ~show_types (program : Michelson_v1_parser.parsed) = + Plugin.RPC.Scripts.typecheck_code + cctxt + (chain, block) + ?gas + ?legacy + ~script:program.expanded + ~show_types + +let script_size cctxt ~(chain : Chain_services.chain) ~block ?gas ?legacy + ~(program : Michelson_v1_parser.parsed) + ~(storage : Michelson_v1_parser.parsed) () = + Plugin.RPC.Scripts.script_size + cctxt + (chain, block) + ?gas + ?legacy + ~script:program.expanded + ~storage:storage.expanded + +let print_typecheck_result ~emacs ~show_types ~print_source_on_error program res + (cctxt : #Client_context.printer) = + if emacs then + let (type_map, errs, _gas) = + match res with + | Ok (type_map, gas) -> (type_map, [], Some gas) + | Error + (Environment.Ecoproto_error + (Script_tc_errors.Ill_typed_contract (_, type_map)) + :: _ as errs) -> + (type_map, errs, None) + | Error errs -> ([], errs, None) + in + cctxt#message + "(@[(types . %a)@ (errors . %a)@])" + Michelson_v1_emacs.print_type_map + (program, type_map) + Michelson_v1_emacs.report_errors + (program, errs) + >>= fun () -> return_unit + else + match res with + | Ok (type_map, gas) -> + let program = Michelson_v1_printer.inject_types type_map program in + cctxt#message "@[Well typed@,Gas remaining: %a@]" Gas.pp gas + >>= fun () -> + if show_types then + cctxt#message "%a" Micheline_printer.print_expr program >>= fun () -> + return_unit + else return_unit + | Error errs -> + cctxt#warning + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:show_types + ~show_source:print_source_on_error + ~parsed:program) + errs + >>= fun () -> cctxt#error "ill-typed script" + +let entrypoint_type cctxt ~(chain : Chain_services.chain) ~block + (program : Michelson_v1_parser.parsed) ~entrypoint = + Michelson_v1_entrypoints.script_entrypoint_type + cctxt + ~chain + ~block + program.expanded + ~entrypoint + +let print_entrypoint_type (cctxt : #Client_context.printer) ~emacs ?script_name + ~show_source ~parsed ~entrypoint ty = + Michelson_v1_entrypoints.print_entrypoint_type + cctxt + ~entrypoint + ~emacs + ?script_name + ~on_errors:(print_errors cctxt ~show_source ~parsed) + ty + +let list_entrypoints cctxt ~(chain : Chain_services.chain) ~block + (program : Michelson_v1_parser.parsed) = + Michelson_v1_entrypoints.list_entrypoints cctxt ~chain ~block program.expanded + +let print_entrypoints_list (cctxt : #Client_context.printer) ~emacs ?script_name + ~show_source ~parsed ty = + Michelson_v1_entrypoints.print_entrypoints_list + cctxt + ~emacs + ?script_name + ~on_errors:(print_errors cctxt ~show_source ~parsed) + ty + +let list_unreachables cctxt ~(chain : Chain_services.chain) ~block + (program : Michelson_v1_parser.parsed) = + Michelson_v1_entrypoints.list_unreachables + cctxt + ~chain + ~block + program.expanded + +let print_unreachables (cctxt : #Client_context.printer) ~emacs ?script_name + ~show_source ~parsed ty = + Michelson_v1_entrypoints.print_unreachables + cctxt + ~emacs + ?script_name + ~on_errors:(print_errors cctxt ~show_source ~parsed) + ty diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_programs.mli b/src/proto_012_PsiThaCa/lib_client/client_proto_programs.mli new file mode 100644 index 000000000000..16c9a45acfff --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_programs.mli @@ -0,0 +1,204 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Tezos_micheline + +module Program : + Client_aliases.Alias + with type t = Michelson_v1_parser.parsed Micheline_parser.parsing_result + +(* Parameters shared by both simulations (views, and contracts). *) +type simulation_params = { + input : Michelson_v1_parser.parsed; + unparsing_mode : Script_ir_translator.unparsing_mode; + now : Script_timestamp.t option; + level : Script_int.n Script_int.num option; + source : Contract.t option; + payer : Contract.t option; + gas : Gas.Arith.integral option; +} + +(* Parameters specific to simulations of views *) +type run_view_params = { + shared_params : simulation_params; + contract : Contract.t; + entrypoint : string; +} + +(* Parameters specific to simulations of contract calls *) +type run_params = { + shared_params : simulation_params; + amount : Tez.t option; + balance : Tez.t; + program : Michelson_v1_parser.parsed; + storage : Michelson_v1_parser.parsed; + entrypoint : string option; +} + +val run_view : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + run_view_params -> + Script.expr tzresult Lwt.t + +val run : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + run_params -> + (Script.expr * packed_internal_operation list * Lazy_storage.diffs option) + tzresult + Lwt.t + +val trace : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + run_params -> + (Script.expr + * packed_internal_operation list + * Script_typed_ir.execution_trace + * Lazy_storage.diffs option) + tzresult + Lwt.t + +val print_view_result : + #Client_context.printer -> Script_repr.expr tzresult -> unit tzresult Lwt.t + +val print_run_result : + #Client_context.printer -> + show_source:bool -> + parsed:Michelson_v1_parser.parsed -> + (Script_repr.expr + * packed_internal_operation list + * Lazy_storage.diffs option) + tzresult -> + unit tzresult Lwt.t + +val print_trace_result : + #Client_context.printer -> + show_source:bool -> + parsed:Michelson_v1_parser.parsed -> + (Script_repr.expr + * packed_internal_operation list + * Script_typed_ir.execution_trace + * Lazy_storage.diffs option) + tzresult -> + unit tzresult Lwt.t + +val typecheck_data : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?gas:Gas.Arith.integral -> + ?legacy:bool -> + data:Michelson_v1_parser.parsed -> + ty:Michelson_v1_parser.parsed -> + unit -> + Gas.t tzresult Lwt.t + +val typecheck_program : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?gas:Gas.Arith.integral -> + ?legacy:bool -> + show_types:bool -> + Michelson_v1_parser.parsed -> + (Script_tc_errors.type_map * Gas.t) tzresult Lwt.t + +val print_typecheck_result : + emacs:bool -> + show_types:bool -> + print_source_on_error:bool -> + Michelson_v1_parser.parsed -> + (Script_tc_errors.type_map * Gas.t) tzresult -> + #Client_context.printer -> + unit tzresult Lwt.t + +val script_size : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?gas:Gas.Arith.integral -> + ?legacy:bool -> + program:Michelson_v1_parser.parsed -> + storage:Michelson_v1_parser.parsed -> + unit -> + int tzresult Lwt.t + +val entrypoint_type : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Michelson_v1_parser.parsed -> + entrypoint:string -> + Script.expr option tzresult Lwt.t + +val print_entrypoint_type : + #Client_context.printer -> + emacs:bool -> + ?script_name:string -> + show_source:bool -> + parsed:Michelson_v1_parser.parsed -> + entrypoint:string -> + Script_repr.expr option tzresult -> + unit tzresult Lwt.t + +val list_entrypoints : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Michelson_v1_parser.parsed -> + (string * Script.expr) list tzresult Lwt.t + +val print_entrypoints_list : + #Client_context.printer -> + emacs:bool -> + ?script_name:string -> + show_source:bool -> + parsed:Michelson_v1_parser.parsed -> + (string * Script.expr) list tzresult -> + unit tzresult Lwt.t + +val list_unreachables : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Michelson_v1_parser.parsed -> + Michelson_v1_primitives.prim list list tzresult Lwt.t + +val print_unreachables : + #Client_context.printer -> + emacs:bool -> + ?script_name:string -> + show_source:bool -> + parsed:Michelson_v1_parser.parsed -> + Michelson_v1_primitives.prim list list tzresult -> + unit tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_utils.ml b/src/proto_012_PsiThaCa/lib_client/client_proto_utils.ml new file mode 100644 index 000000000000..27fec54d342a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_utils.ml @@ -0,0 +1,55 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Protocol_client_context + +let to_json_and_bytes branch message = + let op = + ( Environment.Operation.{branch}, + Contents_list (Single (Failing_noop message)) ) + in + let encoding = Operation.unsigned_encoding in + ( Data_encoding.Json.construct encoding op, + Data_encoding.Binary.to_bytes_exn encoding op ) + +let sign_message (cctxt : #full) ~src_sk ~block ~message = + let (json, bytes) = to_json_and_bytes block message in + cctxt#message "signed content: @[%a@]" Data_encoding.Json.pp json + >>= fun () -> + Client_keys.sign cctxt ~watermark:Signature.Generic_operation src_sk bytes + +let check_message (cctxt : #full) ~block ~key_locator ~quiet ~message ~signature + = + let (json, bytes) = to_json_and_bytes block message in + (if quiet then Lwt.return_unit + else cctxt#message "checked content: @[%a@]" Data_encoding.Json.pp json) + >>= fun () -> + Client_keys.check + ~watermark:Signature.Generic_operation + key_locator + signature + bytes diff --git a/src/proto_012_PsiThaCa/lib_client/client_proto_utils.mli b/src/proto_012_PsiThaCa/lib_client/client_proto_utils.mli new file mode 100644 index 000000000000..c535e4b24ecb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/client_proto_utils.mli @@ -0,0 +1,40 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val sign_message : + #Protocol_client_context.full -> + src_sk:Client_keys.sk_uri -> + block:Block_hash.t -> + message:string -> + Signature.t tzresult Lwt.t + +val check_message : + #Protocol_client_context.full -> + block:Block_hash.t -> + key_locator:Client_keys.pk_uri -> + quiet:bool -> + message:string -> + signature:Signature.t -> + bool tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_client/dune b/src/proto_012_PsiThaCa/lib_client/dune new file mode 100644 index 000000000000..fba74831c2ab --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/dune @@ -0,0 +1,24 @@ +(library + (name tezos_client_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-client-012-PsiThaCa) + (libraries tezos-base + tezos-protocol-012-PsiThaCa + tezos-shell-services + tezos-client-base + tezos-mockup-registration + tezos-proxy + tezos-rpc + tezos-signer-backends + tezos-protocol-012-PsiThaCa-parameters + tezos-protocol-plugin-012-PsiThaCa) + (inline_tests) + (preprocess (pps ppx_inline_test)) + (library_flags (:standard -linkall)) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_shell_services + -open Tezos_client_base + -open Tezos_protocol_012_PsiThaCa + -open Tezos_protocol_plugin_012_PsiThaCa + -open Tezos_protocol_012_PsiThaCa_parameters + -open Tezos_rpc))) diff --git a/src/proto_012_PsiThaCa/lib_client/dune-project b/src/proto_012_PsiThaCa/lib_client/dune-project new file mode 100644 index 000000000000..e8836f1257a0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-client-alpha) diff --git a/src/proto_012_PsiThaCa/lib_client/injection.ml b/src/proto_012_PsiThaCa/lib_client/injection.ml new file mode 100644 index 000000000000..fff28c8f3e2b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/injection.ml @@ -0,0 +1,1071 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2018 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Apply_results +open Protocol_client_context + +let get_branch (rpc_config : #Protocol_client_context.full) ~chain + ~(block : Block_services.block) branch = + (* The default branch is set to HEAD~2, because with Tenderbake the + same transaction may be included again in another block candidate + at the same level, so the operation branch should not point to + the current head. It's not a good idea if it points to the head's + predecessor as well, as the predecessor hash may still change + because of potential reorgs (only the predecessor payload is + finalized, not the whole block). *) + let branch = Option.value ~default:0 branch in + (* TODO export parameter *) + (match block with + | `Head 0 -> + (* Default client's block value: we branch to head's grandfather *) + return (`Head (2 + branch)) + | `Head n -> return (`Head (n + branch)) + | `Hash (h, n) -> return (`Hash (h, n + branch)) + | `Alias (a, n) -> return (`Alias (a, n)) + | `Genesis -> return `Genesis + | `Level i -> return (`Level i)) + >>=? fun block -> + Shell_services.Blocks.hash rpc_config ~chain ~block () >>=? fun hash -> + Shell_services.Chain.chain_id rpc_config ~chain () >>=? fun chain_id -> + return (chain_id, hash) + +type 'kind preapply_result = + Operation_hash.t * 'kind operation * 'kind operation_metadata + +type 'kind result_list = + Operation_hash.t * 'kind contents_list * 'kind contents_result_list + +type 'kind result = Operation_hash.t * 'kind contents * 'kind contents_result + +let get_manager_operation_gas_and_fee contents = + let open Operation in + let l = to_list (Contents_list contents) in + List.fold_left + (fun acc -> function + | Contents (Manager_operation {fee; gas_limit; _}) -> ( + match acc with + | Error _ as e -> e + | Ok (total_fee, total_gas) -> ( + match Tez.(total_fee +? fee) with + | Ok total_fee -> Ok (total_fee, Gas.Arith.add total_gas gas_limit) + | Error _ as e -> e)) + | _ -> acc) + (Ok (Tez.zero, Gas.Arith.zero)) + l + +type fee_parameter = { + minimal_fees : Tez.t; + minimal_nanotez_per_byte : Q.t; + minimal_nanotez_per_gas_unit : Q.t; + force_low_fee : bool; + fee_cap : Tez.t; + burn_cap : Tez.t; +} + +let dummy_fee_parameter = + { + minimal_fees = Tez.zero; + minimal_nanotez_per_byte = Q.zero; + minimal_nanotez_per_gas_unit = Q.zero; + force_low_fee = false; + fee_cap = Tez.one; + burn_cap = Tez.zero; + } + +(* Rounding up (see Z.cdiv) *) +let z_mutez_of_q_nanotez (ntz : Q.t) = + let q_mutez = Q.div ntz (Q.of_int 1000) in + Z.cdiv q_mutez.Q.num q_mutez.Q.den + +let check_fees : + type t. + #Protocol_client_context.full -> + fee_parameter -> + t contents_list -> + int -> + unit Lwt.t = + fun cctxt config op size -> + match get_manager_operation_gas_and_fee op with + | Error _ -> assert false (* FIXME *) + | Ok (fee, gas) -> + if Tez.compare fee config.fee_cap > 0 then + cctxt#error + "The proposed fee (%s%a) are higher than the configured fee cap \ + (%s%a).@\n\ + \ Use `--fee-cap %a` to emit this operation anyway." + Client_proto_args.tez_sym + Tez.pp + fee + Client_proto_args.tez_sym + Tez.pp + config.fee_cap + Tez.pp + fee + >>= fun () -> exit 1 + else + let fees_in_nanotez = + Q.mul (Q.of_int64 (Tez.to_mutez fee)) (Q.of_int 1000) + in + let minimal_fees_in_nanotez = + Q.mul (Q.of_int64 (Tez.to_mutez config.minimal_fees)) (Q.of_int 1000) + in + let minimal_fees_for_gas_in_nanotez = + Q.mul + config.minimal_nanotez_per_gas_unit + (Q.of_bigint (Gas.Arith.integral_to_z gas)) + in + let minimal_fees_for_size_in_nanotez = + Q.mul config.minimal_nanotez_per_byte (Q.of_int size) + in + let estimated_fees_in_nanotez = + Q.add + minimal_fees_in_nanotez + (Q.add + minimal_fees_for_gas_in_nanotez + minimal_fees_for_size_in_nanotez) + in + let estimated_fees_in_mutez = + z_mutez_of_q_nanotez estimated_fees_in_nanotez + in + let estimated_fees = + match Tez.of_mutez (Z.to_int64 estimated_fees_in_mutez) with + | None -> assert false + | Some fee -> fee + in + if + (not config.force_low_fee) + && Q.compare fees_in_nanotez estimated_fees_in_nanotez < 0 + then + cctxt#error + "The proposed fee (%s%a) are lower than the fee that baker expect \ + by default (%s%a).@\n\ + \ Use `--force-low-fee` to emit this operation anyway." + Client_proto_args.tez_sym + Tez.pp + fee + Client_proto_args.tez_sym + Tez.pp + estimated_fees + >>= fun () -> exit 1 + else Lwt.return_unit + +let print_for_verbose_signing ppf ~watermark ~bytes ~branch ~contents = + let open Format in + pp_open_vbox ppf 0 ; + let item f = + pp_open_hovbox ppf 4 ; + pp_print_string ppf " * " ; + f ppf () ; + pp_close_box ppf () ; + pp_print_cut ppf () + in + let hash_pp l = + fprintf ppf "%s" (Base58.raw_encode Blake2B.(hash_bytes l |> to_string)) + in + item (fun ppf () -> + pp_print_text ppf "Branch: " ; + Block_hash.pp ppf branch) ; + item (fun ppf () -> + fprintf + ppf + "Watermark: `%a` (0x%s)" + Signature.pp_watermark + watermark + (Hex.of_bytes (Signature.bytes_of_watermark watermark) |> Hex.show)) ; + item (fun ppf () -> + pp_print_text ppf "Operation bytes: " ; + TzString.fold_left (* We split the bytes into lines for display: *) + (fun n c -> + pp_print_char ppf c ; + if + n < 72 + (* is the email-body standard width, ideal for copy-pasting. *) + then n + 1 + else ( + pp_print_space ppf () ; + 0)) + 0 + (Hex.of_bytes bytes |> Hex.show) + |> ignore) ; + item (fun ppf () -> + pp_print_text ppf "Blake 2B Hash (raw): " ; + hash_pp [bytes]) ; + item (fun ppf () -> + pp_print_text + ppf + "Blake 2B Hash (ledger-style, with operation watermark): " ; + hash_pp [Signature.bytes_of_watermark watermark; bytes]) ; + let json = + Data_encoding.Json.construct + Operation.unsigned_encoding + ({branch}, Contents_list contents) + in + item (fun ppf () -> + pp_print_text ppf "JSON encoding: " ; + Data_encoding.Json.pp ppf json) ; + pp_close_box ppf () + +let preapply (type t) (cctxt : #Protocol_client_context.full) ~chain ~block + ?(verbose_signing = false) ?fee_parameter ?branch ?src_sk + (contents : t contents_list) = + get_branch cctxt ~chain ~block branch >>=? fun (_chain_id, branch) -> + let bytes = + Data_encoding.Binary.to_bytes_exn + Operation.unsigned_encoding + ({branch}, Contents_list contents) + in + (match src_sk with + | None -> return_none + | Some src_sk -> + let watermark = + match contents with + (* TODO-TB sign endosrement? *) + | _ -> Signature.Generic_operation + in + (if verbose_signing then + cctxt#message + "Pre-signature information (verbose signing):@.%t%!" + (print_for_verbose_signing ~watermark ~bytes ~branch ~contents) + else Lwt.return_unit) + >>= fun () -> + Client_keys.sign cctxt ~watermark src_sk bytes >>=? fun signature -> + return_some signature) + >>=? fun signature -> + let op : _ Operation.t = + {shell = {branch}; protocol_data = {contents; signature}} + in + let oph = Operation.hash op in + let size = Bytes.length bytes + Signature.size in + (match fee_parameter with + | Some fee_parameter -> check_fees cctxt fee_parameter contents size + | None -> Lwt.return_unit) + >>= fun () -> + Protocol_client_context.Alpha_block_services.Helpers.Preapply.operations + cctxt + ~chain + ~block + [Operation.pack op] + >>=? function + | [(Operation_data op', Operation_metadata result)] -> ( + match + ( Operation.equal op {shell = {branch}; protocol_data = op'}, + Apply_results.kind_equal_list contents result.contents ) + with + | (Some Operation.Eq, Some Apply_results.Eq) -> + return ((oph, op, result) : t preapply_result) + | _ -> failwith "Unexpected result") + | _ -> failwith "Unexpected result" + +let simulate (type t) (cctxt : #Protocol_client_context.full) ~chain ~block + ?branch ?(latency = Plugin.default_operation_inclusion_latency) + (contents : t contents_list) = + get_branch cctxt ~chain ~block branch >>=? fun (_chain_id, branch) -> + let op : _ Operation.t = + {shell = {branch}; protocol_data = {contents; signature = None}} + in + let oph = Operation.hash op in + Chain_services.chain_id cctxt ~chain () >>=? fun chain_id -> + Plugin.RPC.Scripts.simulate_operation + cctxt + (chain, block) + ~op:(Operation.pack op) + ~chain_id + ~latency + >>=? function + | (Operation_data op', Operation_metadata result) -> ( + match + ( Operation.equal op {shell = {branch}; protocol_data = op'}, + Apply_results.kind_equal_list contents result.contents ) + with + | (Some Operation.Eq, Some Apply_results.Eq) -> + return ((oph, op, result) : t preapply_result) + | _ -> failwith "Unexpected result") + | _ -> failwith "Unexpected result" + +let estimated_gas_single (type kind) + (Manager_operation_result {operation_result; internal_operation_results; _} : + kind Kind.manager contents_result) = + let consumed_gas (type kind) (result : kind manager_operation_result) = + match result with + | Applied (Transaction_result {consumed_gas; _}) -> Ok consumed_gas + | Applied (Origination_result {consumed_gas; _}) -> Ok consumed_gas + | Applied (Reveal_result {consumed_gas}) -> Ok consumed_gas + | Applied (Delegation_result {consumed_gas}) -> Ok consumed_gas + | Applied (Register_global_constant_result {consumed_gas; _}) -> + Ok consumed_gas + | Applied (Set_deposits_limit_result {consumed_gas}) -> Ok consumed_gas + | Skipped _ -> assert false + | Backtracked (_, None) -> + Ok Gas.Arith.zero (* there must be another error for this to happen *) + | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) + | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) + in + List.fold_left + (fun acc (Internal_operation_result (_, r)) -> + acc >>? fun acc -> + consumed_gas r >>? fun gas -> Ok (Gas.Arith.add acc gas)) + (consumed_gas operation_result) + internal_operation_results + +let estimated_storage_single (type kind) origination_size + (Manager_operation_result {operation_result; internal_operation_results; _} : + kind Kind.manager contents_result) = + let storage_size_diff (type kind) (result : kind manager_operation_result) = + match result with + | Applied + (Transaction_result + {paid_storage_size_diff; allocated_destination_contract; _}) -> + if allocated_destination_contract then + Ok (Z.add paid_storage_size_diff origination_size) + else Ok paid_storage_size_diff + | Applied (Origination_result {paid_storage_size_diff; _}) -> + Ok (Z.add paid_storage_size_diff origination_size) + | Applied (Reveal_result _) -> Ok Z.zero + | Applied (Delegation_result _) -> Ok Z.zero + | Applied (Register_global_constant_result {size_of_constant; _}) -> + Ok size_of_constant + | Applied (Set_deposits_limit_result _) -> Ok Z.zero + | Skipped _ -> assert false + | Backtracked (_, None) -> + Ok Z.zero (* there must be another error for this to happen *) + | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) + | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) + in + List.fold_left + (fun acc (Internal_operation_result (_, r)) -> + acc >>? fun acc -> + storage_size_diff r >>? fun storage -> Ok (Z.add acc storage)) + (storage_size_diff operation_result) + internal_operation_results + +let estimated_storage origination_size res = + let rec estimated_storage : type kind. kind contents_result_list -> _ = + function + | Single_result (Manager_operation_result _ as res) -> + estimated_storage_single origination_size res + | Single_result _ -> Ok Z.zero + | Cons_result (res, rest) -> + estimated_storage_single origination_size res >>? fun storage1 -> + estimated_storage rest >>? fun storage2 -> Ok (Z.add storage1 storage2) + in + estimated_storage res >>? fun diff -> Ok (Z.max Z.zero diff) + +let originated_contracts_single (type kind) + (Manager_operation_result {operation_result; internal_operation_results; _} : + kind Kind.manager contents_result) = + let originated_contracts (type kind) (result : kind manager_operation_result) + = + match result with + | Applied (Transaction_result {originated_contracts; _}) -> + Ok originated_contracts + | Applied (Origination_result {originated_contracts; _}) -> + Ok originated_contracts + | Applied (Register_global_constant_result _) -> Ok [] + | Applied (Reveal_result _) -> Ok [] + | Applied (Delegation_result _) -> Ok [] + | Applied (Set_deposits_limit_result _) -> Ok [] + | Skipped _ -> assert false + | Backtracked (_, None) -> + Ok [] (* there must be another error for this to happen *) + | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) + | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) + in + List.fold_left + (fun acc (Internal_operation_result (_, r)) -> + acc >>? fun acc -> + originated_contracts r >>? fun contracts -> + Ok (List.rev_append contracts acc)) + (originated_contracts operation_result >|? List.rev) + internal_operation_results + +let rec originated_contracts : type kind. kind contents_result_list -> _ = + function + | Single_result (Manager_operation_result _ as res) -> + originated_contracts_single res >|? List.rev + | Single_result _ -> Ok [] + | Cons_result (res, rest) -> + originated_contracts_single res >>? fun contracts1 -> + originated_contracts rest >>? fun contracts2 -> + Ok (List.rev_append contracts1 contracts2) + +let detect_script_failure : type kind. kind operation_metadata -> _ = + let rec detect_script_failure : type kind. kind contents_result_list -> _ = + let detect_script_failure_single (type kind) + (Manager_operation_result + {operation_result; internal_operation_results; _} : + kind Kind.manager contents_result) = + let detect_script_failure (type kind) + (result : kind manager_operation_result) = + match result with + | Applied _ -> Ok () + | Skipped _ -> assert false + | Backtracked (_, None) -> + (* there must be another error for this to happen *) + Ok () + | Backtracked (_, Some errs) -> + record_trace + (error_of_fmt "The transfer simulation failed.") + (Error (Environment.wrap_tztrace errs)) + | Failed (_, errs) -> + record_trace + (error_of_fmt "The transfer simulation failed.") + (Error (Environment.wrap_tztrace errs)) + in + List.fold_left + (fun acc (Internal_operation_result (_, r)) -> + acc >>? fun () -> detect_script_failure r) + (detect_script_failure operation_result) + internal_operation_results + in + function + | Single_result (Manager_operation_result _ as res) -> + detect_script_failure_single res + | Single_result _ -> Ok () + | Cons_result (res, rest) -> + detect_script_failure_single res >>? fun () -> + detect_script_failure rest + in + fun {contents} -> detect_script_failure contents + +(* This value is used as a safety guard for gas limit. *) +let safety_guard = Gas.Arith.(integral_of_int_exn 100) + +(* + + {2 High-level description of the automatic gas patching algorithm} + + When the user wants to inject a list of operations, some of which + might have unspecified gas, fees or storage limit, the client + performs a {e simulation} to estimate those limits and assign + sensible values to them. + + The simulation works as follows: + 1. limits are assigned to dummy, high values to ensure that the operations + can be simulated + - 1.a) when a list of operations is partially specified, the algorithm + allocates to each unspecified operation an equal portion of the + maximum gas per block minus the gas consumed by the operations that + do specify their limit + 2. the algorithm retrieves the effectively consumed gas and storage from the + receipt + 3. the algorithm assigns slight overapproximations to the operation + 4. a default fee is computed and set + +*) + +let may_patch_limits (type kind) (cctxt : #Protocol_client_context.full) + ~fee_parameter ~chain ~block ?branch + (annotated_contents : kind Annotated_manager_operation.annotated_list) : + kind Kind.manager contents_list tzresult Lwt.t = + Tezos_client_base.Client_confirmations.wait_for_bootstrapped cctxt + >>=? fun () -> + Alpha_services.Constants.all cctxt (chain, block) + >>=? fun { + parametric = + { + hard_gas_limit_per_operation; + hard_gas_limit_per_block; + hard_storage_limit_per_operation; + origination_size; + cost_per_byte; + _; + }; + _; + } -> + let user_gas_limit_needs_patching user_gas_limit = + Limit.fold user_gas_limit ~unknown:true ~known:(fun user_gas_limit -> + Gas.Arith.( + user_gas_limit < zero || hard_gas_limit_per_operation < user_gas_limit)) + in + let user_storage_limit_needs_patching user_storage_limit = + Limit.fold + user_storage_limit + ~unknown:true + ~known:(fun user_storage_limit -> + Z.Compare.( + user_storage_limit < Z.zero + || hard_storage_limit_per_operation < user_storage_limit)) + in + let gas_patching_stats (Annotated_manager_operation.Manager_info c) + need_patching gas_consumed = + if user_gas_limit_needs_patching c.gas_limit then + (need_patching + 1, gas_consumed) + else + ( need_patching, + Gas.Arith.add + gas_consumed + (Limit.value ~when_unknown:Gas.Arith.zero c.gas_limit) ) + in + let rec gas_patching_stats_list : + type kind. + kind Annotated_manager_operation.annotated_list -> + int -> + Saturation_repr.may_saturate Saturation_repr.t -> + int * Saturation_repr.may_saturate Saturation_repr.t = + fun op need_patching gas_consumed -> + match op with + | Single_manager minfo -> + gas_patching_stats minfo need_patching gas_consumed + | Cons_manager (minfo, rest) -> + let (need_patching, gas_consumed) = + gas_patching_stats minfo need_patching gas_consumed + in + gas_patching_stats_list rest need_patching gas_consumed + in + let may_need_patching_single : + type kind. + Gas.Arith.integral -> + kind Annotated_manager_operation.t -> + kind Annotated_manager_operation.t option = + fun gas_limit_per_patched_op op -> + match op with + | Manager_info c -> + let needs_patching = + Limit.is_unknown c.fee + || user_gas_limit_needs_patching c.gas_limit + || user_storage_limit_needs_patching c.storage_limit + in + if not needs_patching then None + else + (* Set limits for simulation purposes *) + let gas_limit = + if user_gas_limit_needs_patching c.gas_limit then + Limit.known gas_limit_per_patched_op + else c.gas_limit + in + let storage_limit = + if user_storage_limit_needs_patching c.storage_limit then + Limit.known hard_storage_limit_per_operation + else c.storage_limit + in + let fee = Limit.value ~when_unknown:Tez.zero c.fee in + Some + (Manager_info + {c with gas_limit; storage_limit; fee = Limit.known fee}) + in + let may_need_patching gas_limit_per_patched_op ops = + let rec loop : + type kind. + kind Annotated_manager_operation.annotated_list -> + kind Annotated_manager_operation.annotated_list option = function + | Single_manager annotated_op -> + Option.map (fun op -> Annotated_manager_operation.Single_manager op) + @@ may_need_patching_single gas_limit_per_patched_op annotated_op + | Cons_manager (annotated_op, rest) -> ( + let annotated_op_opt = + may_need_patching_single gas_limit_per_patched_op annotated_op + in + let rest_opt = loop rest in + match (annotated_op_opt, rest_opt) with + | (None, None) -> None + | _ -> + let op = Option.value ~default:annotated_op annotated_op_opt in + let rest = Option.value ~default:rest rest_opt in + Some (Cons_manager (op, rest))) + in + loop ops + in + (* + The recursion here handles the case where an increased fee might increase the + size of the operation, and so require a recalculation of the gas costs. + Rationale for termination: + - the fee for size increases linearly with the size of the operation. + - however, when the size of the operation increase to make space for an + increased fee, the amount of new fee that can be added without increasing + the size of the block again increases exponentially. + - hence, there will eventually be a increase of size that will fit any new + fee without having to increase the size of the operation again. + *) + let rec patch_fee : type kind. first:bool -> kind contents -> kind contents = + fun ~first -> function + | Manager_operation c as op -> ( + let size = + if first then + (WithExceptions.Option.get ~loc:__LOC__ + @@ Data_encoding.Binary.fixed_length + Tezos_base.Operation.shell_header_encoding) + + Data_encoding.Binary.length + Operation.contents_encoding + (Contents op) + + Signature.size + else + Data_encoding.Binary.length + Operation.contents_encoding + (Contents op) + in + let minimal_fees_in_nanotez = + Q.mul + (Q.of_int64 (Tez.to_mutez fee_parameter.minimal_fees)) + (Q.of_int 1000) + in + let minimal_fees_for_gas_in_nanotez = + Q.mul + fee_parameter.minimal_nanotez_per_gas_unit + (Q.of_bigint @@ Gas.Arith.integral_to_z c.gas_limit) + in + let minimal_fees_for_size_in_nanotez = + Q.mul fee_parameter.minimal_nanotez_per_byte (Q.of_int size) + in + let fees_in_nanotez = + Q.add minimal_fees_in_nanotez + @@ Q.add + minimal_fees_for_gas_in_nanotez + minimal_fees_for_size_in_nanotez + in + let fees_in_mutez = z_mutez_of_q_nanotez fees_in_nanotez in + match Tez.of_mutez (Z.to_int64 fees_in_mutez) with + | None -> assert false + | Some fee -> + if Tez.(fee <= c.fee) then op + else patch_fee ~first (Manager_operation {c with fee})) + | c -> c + in + let patch : + type kind. + first:bool -> + kind Annotated_manager_operation.t * kind Kind.manager contents_result -> + kind Kind.manager contents tzresult Lwt.t = + fun ~first -> function + | ((Manager_info c as op), (Manager_operation_result _ as result)) -> + (if user_gas_limit_needs_patching c.gas_limit then + Lwt.return (estimated_gas_single result) >>=? fun gas -> + if Gas.Arith.(gas = zero) then + cctxt#message "Estimated gas: none" >>= fun () -> + return + (Annotated_manager_operation.set_gas_limit + (Limit.known Gas.Arith.zero) + op) + else + cctxt#message + "Estimated gas: %a units (will add 100 for safety)" + Gas.Arith.pp + gas + >>= fun () -> + let safe_gas = Gas.Arith.(add (ceil gas) safety_guard) in + let patched_gas = + Gas.Arith.min safe_gas hard_gas_limit_per_operation + in + return + (Annotated_manager_operation.set_gas_limit + (Limit.known patched_gas) + op) + else return op) + >>=? fun op -> + (if user_storage_limit_needs_patching c.storage_limit then + Lwt.return + (estimated_storage_single (Z.of_int origination_size) result) + >>=? fun storage -> + if Z.equal storage Z.zero then + cctxt#message "Estimated storage: no bytes added" >>= fun () -> + return + (Annotated_manager_operation.set_storage_limit + (Limit.known Z.zero) + op) + else + cctxt#message + "Estimated storage: %s bytes added (will add 20 for safety)" + (Z.to_string storage) + >>= fun () -> + let storage_limit = + Z.min + (Z.add storage (Z.of_int 20)) + hard_storage_limit_per_operation + in + return + (Annotated_manager_operation.set_storage_limit + (Limit.known storage_limit) + op) + else return op) + >>=? fun op -> + if Limit.is_unknown c.fee then + (* Setting a dummy fee is required for converting to manager op *) + let op = + Annotated_manager_operation.set_fee (Limit.known Tez.zero) op + in + Annotated_manager_operation.manager_from_annotated op >>?= fun cm -> + return (patch_fee ~first cm) + else Lwt.return (Annotated_manager_operation.manager_from_annotated op) + in + let rec patch_list : + type kind. + bool -> + kind Annotated_manager_operation.annotated_list -> + kind Kind.manager contents_result_list -> + kind Kind.manager contents_list tzresult Lwt.t = + fun first annotated_list result_list -> + match (annotated_list, result_list) with + | (Single_manager annotated, Single_result res) -> + patch ~first (annotated, res) >>=? fun op -> return (Single op) + | (Cons_manager (annotated, annotated_rest), Cons_result (res, res_rest)) -> + patch ~first (annotated, res) >>=? fun op -> + patch_list false annotated_rest res_rest >>=? fun rest -> + return (Cons (op, rest)) + | _ -> assert false + in + let gas_limit_per_patched_op = + let (need_gas_patching, gas_consumed) = + gas_patching_stats_list annotated_contents 0 Gas.Arith.zero + in + if need_gas_patching = 0 then hard_gas_limit_per_operation + else + let remaining_gas = Gas.Arith.sub hard_gas_limit_per_block gas_consumed in + let average_per_operation_gas = + Gas.Arith.integral_exn + @@ Z.div + (Gas.Arith.integral_to_z remaining_gas) + (Z.of_int need_gas_patching) + in + Gas.Arith.min hard_gas_limit_per_operation average_per_operation_gas + in + match may_need_patching gas_limit_per_patched_op annotated_contents with + | Some annotated_for_simulation -> + Lwt.return + (Annotated_manager_operation.manager_list_from_annotated + annotated_for_simulation) + >>=? fun contents_for_simulation -> + simulate cctxt ~chain ~block ?branch contents_for_simulation + >>=? fun (_, _, result) -> + (match detect_script_failure result with + | Ok () -> return_unit + | Error _ -> + cctxt#message + "@[This simulation failed:@,%a@]" + Operation_result.pp_operation_result + (contents_for_simulation, result.contents) + >>= fun () -> return_unit) + >>=? fun () -> + ( Lwt.return + (estimated_storage (Z.of_int origination_size) result.contents) + >>=? fun storage -> + Lwt.return + (Environment.wrap_tzresult Tez.(cost_per_byte *? Z.to_int64 storage)) + >>=? fun burn -> + if Tez.(burn > fee_parameter.burn_cap) then + cctxt#error + "The operation will burn %s%a which is higher than the configured \ + burn cap (%s%a).@\n\ + \ Use `--burn-cap %a` to emit this operation." + Client_proto_args.tez_sym + Tez.pp + burn + Client_proto_args.tez_sym + Tez.pp + fee_parameter.burn_cap + Tez.pp + burn + >>= fun () -> exit 1 + else return_unit ) + >>=? fun () -> patch_list true annotated_contents result.contents + | None -> + Lwt.return + (Annotated_manager_operation.manager_list_from_annotated + annotated_contents) + +let tenderbake_finality_confirmations = 1 + +let tenderbake_adjust_confirmations (cctxt : #Client_context.full) = function + | None -> Lwt.return_none + | Some cli_confirmations -> + if cli_confirmations > tenderbake_finality_confirmations then + cctxt#message + "Tenderbake needs at most %d confirmations for finality (%d given). \ + Using %d confirmations." + tenderbake_finality_confirmations + cli_confirmations + tenderbake_finality_confirmations + >>= fun () -> Lwt.return_some tenderbake_finality_confirmations + else Lwt.return_some cli_confirmations + +(* For Tenderbake we restrain the interval of confirmations to be [0, + tenderbake_finality_confirmations] + + Any value greater than the tenderbake_finality_confirmations is treated as if it + were tenderbake_finality_confirmations. + *) +let inject_operation_internal (type kind) cctxt ~chain ~block ?confirmations + ?(dry_run = false) ?(simulation = false) ?branch ?src_sk ?verbose_signing + ~fee_parameter (contents : kind contents_list) = + (if simulation then simulate cctxt ~chain ~block ?branch contents + else + preapply + cctxt + ~chain + ~block + ~fee_parameter + ?verbose_signing + ?branch + ?src_sk + contents) + >>=? fun (_oph, op, result) -> + (match detect_script_failure result with + | Ok () -> return_unit + | Error _ as res -> + cctxt#message + "@[This simulation failed:@,%a@]" + Operation_result.pp_operation_result + (op.protocol_data.contents, result.contents) + >>= fun () -> Lwt.return res) + >>=? fun () -> + let bytes = + Data_encoding.Binary.to_bytes_exn Operation.encoding (Operation.pack op) + in + if dry_run || simulation then + let oph = Operation_hash.hash_bytes [bytes] in + cctxt#message + "@[Operation: 0x%a@,Operation hash is '%a'@]" + Hex.pp + (Hex.of_bytes bytes) + Operation_hash.pp + oph + >>= fun () -> + cctxt#message + "@[Simulation result:@,%a@]" + Operation_result.pp_operation_result + (op.protocol_data.contents, result.contents) + >>= fun () -> return (oph, op.protocol_data.contents, result.contents) + else + Shell_services.Injection.operation cctxt ~chain bytes >>=? fun oph -> + cctxt#message "Operation successfully injected in the node." >>= fun () -> + cctxt#message "Operation hash is '%a'" Operation_hash.pp oph >>= fun () -> + (* Adjust user-provided confirmations with respect to Alpha protocol finality properties *) + tenderbake_adjust_confirmations cctxt confirmations >>= fun confirmations -> + (match confirmations with + | None -> + cctxt#message + "@[NOT waiting for the operation to be included.@,\ + Use command@,\ + \ tezos-client wait for %a to be included --confirmations %d \ + --branch %a@,\ + and/or an external block explorer to make sure that it has been \ + included.@]" + Operation_hash.pp + oph + tenderbake_finality_confirmations + Block_hash.pp + op.shell.branch + >>= fun () -> return result + | Some confirmations -> ( + cctxt#message "Waiting for the operation to be included..." + >>= fun () -> + Client_confirmations.wait_for_operation_inclusion + ~branch:op.shell.branch + ~confirmations + cctxt + ~chain + oph + >>=? fun (h, i, j) -> + Alpha_block_services.Operations.operation + cctxt + ~chain + ~block:(`Hash (h, 0)) + i + j + >>=? fun op' -> + match op'.receipt with + | None -> failwith "Internal error: pruned metadata." + | Some No_operation_metadata -> + failwith "Internal error: unexpected receipt." + | Some (Operation_metadata receipt) -> ( + match Apply_results.kind_equal_list contents receipt.contents with + | Some Apply_results.Eq -> + return (receipt : kind operation_metadata) + | None -> failwith "Internal error: unexpected receipt."))) + >>=? fun result -> + cctxt#message + "@[This sequence of operations was run:@,%a@]" + Operation_result.pp_operation_result + (op.protocol_data.contents, result.contents) + >>= fun () -> + Lwt.return (originated_contracts result.contents) >>=? fun contracts -> + List.iter_s + (fun c -> cctxt#message "New contract %a originated." Contract.pp c) + contracts + >>= fun () -> + (match confirmations with + | None -> Lwt.return_unit + | Some number -> + if number >= tenderbake_finality_confirmations then + cctxt#message + "The operation was included in a block %d blocks ago." + number + else + cctxt#message + "@[The operation has only been included %d blocks ago.@,\ + We recommend to wait more.@,\ + Use command@,\ + \ tezos-client wait for %a to be included --confirmations %d \ + --branch %a@,\ + and/or an external block explorer.@]" + number + Operation_hash.pp + oph + tenderbake_finality_confirmations + Block_hash.pp + op.shell.branch) + >>= fun () -> return (oph, op.protocol_data.contents, result.contents) + +let inject_operation (type kind) cctxt ~chain ~block ?confirmations + ?(dry_run = false) ?(simulation = false) ?branch ?src_sk ?verbose_signing + ~fee_parameter (contents : kind contents_list) = + Tezos_client_base.Client_confirmations.wait_for_bootstrapped cctxt + >>=? fun () -> + inject_operation_internal + cctxt + ~chain + ~block + ?confirmations + ~dry_run + ~simulation + ?branch + ?src_sk + ?verbose_signing + ~fee_parameter + (contents : kind contents_list) + +let prepare_manager_operation ~fee ~gas_limit ~storage_limit operation = + Annotated_manager_operation.Manager_info + {source = None; fee; gas_limit; storage_limit; counter = None; operation} + +(* [gas_limit] must correspond to + [Michelson_v1_gas.Cost_of.manager_operation] *) +let cost_of_manager_operation = Gas.Arith.integral_of_int_exn 1_000 + +let reveal_error_message = + "Requested operation requires to perform a public key revelation beforehand.\n\ + This cannot be done automatically when a custom fee or storage limit is \ + given.\n\ + If you wish to use a custom fee or storage limit, please first perform the \ + reveal operation separately using the dedicated command.\n\ + Otherwise, please do not specify custom fee or storage parameters." + +let reveal_error (cctxt : #Protocol_client_context.full) = + cctxt#error "%s" reveal_error_message + +let inject_manager_operation cctxt ~chain ~block ?branch ?confirmations ?dry_run + ?verbose_signing ?simulation ~source ~src_pk ~src_sk ~fee ~gas_limit + ~storage_limit ?counter ~fee_parameter (type kind) + (operations : kind Annotated_manager_operation.annotated_list) : + (Operation_hash.t + * kind Kind.manager contents_list + * kind Kind.manager contents_result_list) + tzresult + Lwt.t = + (match counter with + | None -> + Alpha_services.Contract.counter cctxt (chain, block) source + >>=? fun pcounter -> + let counter = Z.succ pcounter in + return counter + | Some counter -> return counter) + >>=? fun counter -> + Alpha_services.Contract.manager_key cctxt (chain, block) source + >>=? fun key -> + (* [has_reveal] assumes that a Reveal operation only appears as the first of a batch *) + let has_reveal : + type kind. kind Annotated_manager_operation.annotated_list -> bool = + function + | Single_manager (Manager_info {operation = Reveal _; _}) -> true + | Cons_manager (Manager_info {operation = Reveal _; _}, _) -> true + | _ -> false + in + let apply_specified_options counter op = + Annotated_manager_operation.set_source source op >>? fun op -> + Annotated_manager_operation.set_counter counter op >>? fun op -> + Annotated_manager_operation.join_fee fee op >>? fun op -> + Annotated_manager_operation.join_gas_limit gas_limit op >>? fun op -> + Annotated_manager_operation.join_storage_limit storage_limit op + in + let rec build_contents : + type kind. + Z.t -> + kind Annotated_manager_operation.annotated_list -> + kind Annotated_manager_operation.annotated_list tzresult = + fun counter -> function + | Single_manager op -> + apply_specified_options counter op >|? fun op -> + Annotated_manager_operation.Single_manager op + | Cons_manager (op, rest) -> + apply_specified_options counter op >>? fun op -> + build_contents (Z.succ counter) rest >|? fun rest -> + Annotated_manager_operation.Cons_manager (op, rest) + in + match key with + | None when not (has_reveal operations) -> ( + (if not (Limit.is_unknown fee && Limit.is_unknown storage_limit) then + reveal_error cctxt + else return_unit) + >>=? fun () -> + let reveal = + prepare_manager_operation + ~fee:Limit.unknown + ~gas_limit:(Limit.known cost_of_manager_operation) + ~storage_limit:Limit.unknown + (Reveal src_pk) + in + Annotated_manager_operation.set_source source reveal >>?= fun reveal -> + Annotated_manager_operation.set_counter counter reveal >>?= fun reveal -> + build_contents (Z.succ counter) operations >>?= fun rest -> + let contents = Annotated_manager_operation.Cons_manager (reveal, rest) in + may_patch_limits cctxt ~fee_parameter ~chain ~block ?branch contents + >>=? fun contents -> + inject_operation_internal + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?simulation + ~fee_parameter + ?verbose_signing + ?branch + ~src_sk + contents + >>=? fun (oph, op, result) -> + match pack_contents_list op result with + | Cons_and_result (_, _, rest) -> + let (op, result) = unpack_contents_list rest in + return (oph, op, result) + | _ -> assert false) + | Some _ when has_reveal operations -> + failwith "The manager key was previously revealed." + | _ -> + build_contents counter operations >>?= fun contents -> + may_patch_limits cctxt ~fee_parameter ~chain ~block ?branch contents + >>=? fun contents -> + inject_operation_internal + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?simulation + ~fee_parameter + ?branch + ~src_sk + contents diff --git a/src/proto_012_PsiThaCa/lib_client/injection.mli b/src/proto_012_PsiThaCa/lib_client/injection.mli new file mode 100644 index 000000000000..d8f99d620510 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/injection.mli @@ -0,0 +1,105 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Apply_results + +type 'kind preapply_result = + Operation_hash.t * 'kind operation * 'kind operation_metadata + +type fee_parameter = { + minimal_fees : Tez.t; + minimal_nanotez_per_byte : Q.t; + minimal_nanotez_per_gas_unit : Q.t; + force_low_fee : bool; + fee_cap : Tez.t; + burn_cap : Tez.t; +} + +val dummy_fee_parameter : fee_parameter + +val preapply : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?verbose_signing:bool -> + ?fee_parameter:fee_parameter -> + ?branch:int -> + ?src_sk:Client_keys.sk_uri -> + 'kind contents_list -> + 'kind preapply_result tzresult Lwt.t + +type 'kind result_list = + Operation_hash.t * 'kind contents_list * 'kind contents_result_list + +(** /!\ [inject_operation] does not perform automatic patching of + gas, storage and fees; use [inject_manager_operation] to inject + manager operations. *) +val inject_operation : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?simulation:bool -> + ?branch:int -> + ?src_sk:Client_keys.sk_uri -> + ?verbose_signing:bool -> + fee_parameter:fee_parameter -> + 'kind contents_list -> + 'kind result_list tzresult Lwt.t + +type 'kind result = Operation_hash.t * 'kind contents * 'kind contents_result + +val prepare_manager_operation : + fee:Tez.t Limit.t -> + gas_limit:Gas.Arith.integral Limit.t -> + storage_limit:Z.t Limit.t -> + 'kind manager_operation -> + 'kind Annotated_manager_operation.t + +val inject_manager_operation : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + block:Shell_services.block -> + ?branch:int -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?simulation:bool -> + source:Signature.Public_key_hash.t -> + src_pk:Signature.public_key -> + src_sk:Client_keys.sk_uri -> + fee:Tez.t Limit.t -> + gas_limit:Gas.Arith.integral Limit.t -> + storage_limit:Z.t Limit.t -> + ?counter:Z.t -> + fee_parameter:fee_parameter -> + 'kind Annotated_manager_operation.annotated_list -> + 'kind Kind.manager result_list tzresult Lwt.t + +val originated_contracts : + 'kind contents_result_list -> Contract.t list tzresult diff --git a/src/proto_012_PsiThaCa/lib_client/light.ml b/src/proto_012_PsiThaCa/lib_client/light.ml new file mode 100644 index 000000000000..038624664ec0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/light.ml @@ -0,0 +1,37 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module M : Tezos_proxy.Light_proto.PROTO_RPCS = struct + let merkle_tree (pgi : Tezos_proxy.Proxy.proxy_getter_input) key leaf_kind = + Protocol_client_context.Alpha_block_services.Context.merkle_tree + pgi.rpc_context + ~chain:pgi.chain + ~block:pgi.block + ~holey: + (match leaf_kind with + | Tezos_shell_services.Block_services.Hole -> true + | Tezos_shell_services.Block_services.Raw_context -> false) + key +end diff --git a/src/proto_012_PsiThaCa/lib_client/limit.ml b/src/proto_012_PsiThaCa/lib_client/limit.ml new file mode 100644 index 000000000000..3f3c798c02b6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/limit.ml @@ -0,0 +1,64 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type 'a t = 'a option + +let unknown = None + +let known x = Some x + +let of_option = Fun.id + +let is_unknown = Option.is_none + +let join (type a) ~where eq (l1 : a t) (l2 : a t) = + match (l1, l2) with + | (None, None) -> Result.return_none + | (Some x, None) | (None, Some x) -> Result.return_some x + | (Some x, Some y) -> + if eq x y then Result.return_some x + else error_with "Limit.join: error (%s)" where + +let%test "join" = + let check res y = + match res with Ok x -> Option.equal Bool.equal x y | Error _ -> false + in + check (join ~where:__LOC__ Bool.equal (Some true) (Some true)) (Some true) + && check (join ~where:__LOC__ Bool.equal None None) None + && check (join ~where:__LOC__ Bool.equal None (Some true)) (Some true) + && check (join ~where:__LOC__ Bool.equal (Some true) None) (Some true) + && not + (Result.is_ok (join ~where:__LOC__ Bool.equal (Some true) (Some false))) + +let get ~when_unknown = function + | None -> error_with "Limit.get: %s" when_unknown + | Some x -> ok x + +let%test "get" = + match get ~when_unknown:"" (Some true) with Ok true -> true | _ -> false + +let fold ~unknown ~known x = match x with None -> unknown | Some x -> known x + +let value ~when_unknown = function None -> when_unknown | Some x -> x diff --git a/src/proto_012_PsiThaCa/lib_client/limit.mli b/src/proto_012_PsiThaCa/lib_client/limit.mli new file mode 100644 index 000000000000..3ce610e3450c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/limit.mli @@ -0,0 +1,49 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This helper module allows to handle partially specified limits during the + injection process. *) + +(** A value of type ['a t] is either [unknown] of [known]. *) +type 'a t + +val unknown : 'a t + +val known : 'a -> 'a t + +val of_option : 'a option -> 'a t + +val is_unknown : 'a t -> bool + +(** [join ~where eq x y] computes the order-theoretic union of [x] and [y]. + If both [x] and [y] are not [Unknown], the function fails iff their + contents are not equal according to [eq]. *) +val join : where:string -> ('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t tzresult + +val fold : unknown:'a -> known:('b -> 'a) -> 'b t -> 'a + +val get : when_unknown:string -> 'a t -> 'a tzresult + +val value : when_unknown:'a -> 'a t -> 'a diff --git a/src/proto_012_PsiThaCa/lib_client/managed_contract.ml b/src/proto_012_PsiThaCa/lib_client/managed_contract.ml new file mode 100644 index 000000000000..29bb3d976b63 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/managed_contract.ml @@ -0,0 +1,321 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +open Protocol +open Alpha_context +open Protocol_client_context +open Tezos_micheline + +let return_single_manager_result (oph, op, result) = + match Apply_results.pack_contents_list op result with + | Apply_results.Single_and_result ((Manager_operation _ as op), result) -> + return (oph, op, result) + | _ -> assert false + +let get_contract_manager (cctxt : #full) contract = + let open Micheline in + let open Michelson_v1_primitives in + Client_proto_context.get_storage + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~unparsing_mode:Optimized + contract + >>=? function + | None -> cctxt#error "This is not a smart contract." + | Some storage -> ( + match root storage with + | Prim (_, D_Pair, Bytes (_, bytes) :: _, _) | Bytes (_, bytes) -> ( + match + Data_encoding.Binary.of_bytes_opt + Signature.Public_key_hash.encoding + bytes + with + | Some k -> return k + | None -> + cctxt#error + "Cannot find a manager key in contracts storage (decoding \ + bytes failed).\n\ + Transfer from scripted contract are currently only supported \ + for \"manager\" contract.") + | Prim (_, D_Pair, String (_, value) :: _, _) | String (_, value) -> ( + match Signature.Public_key_hash.of_b58check_opt value with + | Some k -> return k + | None -> + cctxt#error + "Cannot find a manager key in contracts storage (\"%s\" is not \ + a valid key).\n\ + Transfer from scripted contract are currently only supported \ + for \"manager\" contract." + value) + | _raw_storage -> + cctxt#error + "Cannot find a manager key in contracts storage (wrong storage \ + format : @[%a@]).\n\ + Transfer from scripted contract are currently only supported for \ + \"manager\" contract." + Michelson_v1_printer.print_expr + storage) + +let parse code = + Lwt.return + ( Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression code + >>? fun exp -> + Error_monad.ok @@ Script.lazy_expr Michelson_v1_parser.(exp.expanded) ) + +let build_lambda_for_set_delegate ~delegate = + match delegate with + | Some delegate -> + let (`Hex delegate) = Signature.Public_key_hash.to_hex delegate in + Format.asprintf + "{ DROP ; NIL operation ; PUSH key_hash 0x%s ; SOME ; SET_DELEGATE ; \ + CONS }" + delegate + | None -> "{ DROP ; NIL operation ; NONE key_hash ; SET_DELEGATE ; CONS }" + +let build_delegate_operation (cctxt : #full) ~chain ~block ?fee + contract (* the KT1 to delegate *) + (delegate : Signature.public_key_hash option) = + let entrypoint = "do" in + (Michelson_v1_entrypoints.contract_entrypoint_type + cctxt + ~chain + ~block + ~contract + ~entrypoint + >>=? function + | Some _ -> + (* their is a "do" entrypoint (we could check its type here)*) + parse @@ build_lambda_for_set_delegate ~delegate >>=? fun param -> + return (param, entrypoint) + | None -> ( + (* their is no "do" entrypoint trying "set/remove_delegate" *) + let entrypoint = + match delegate with + | Some _ -> "set_delegate" + | None -> "remove_delegate" + in + Michelson_v1_entrypoints.contract_entrypoint_type + cctxt + ~chain + ~block + ~contract + ~entrypoint + >>=? function + | Some _ -> + (* their is a "set/remove_delegate" entrypoint *) + let delegate_data = + match delegate with + | Some delegate -> + let (`Hex delegate) = + Signature.Public_key_hash.to_hex delegate + in + "0x" ^ delegate + | None -> "Unit" + in + parse delegate_data >>=? fun param -> return (param, entrypoint) + | None -> + cctxt#error + "Cannot find a %%do or %%set_delegate entrypoint in contract@.")) + >>=? fun (parameters, entrypoint) -> + return + (Client_proto_context.build_transaction_operation + ~amount:Tez.zero + ~parameters + ~entrypoint + ?fee + contract) + +let set_delegate (cctxt : #full) ~chain ~block ?confirmations ?dry_run + ?verbose_signing ?simulation ?branch ~fee_parameter ?fee ~source ~src_pk + ~src_sk contract (* the KT1 to delegate *) + (delegate : Signature.public_key_hash option) = + build_delegate_operation cctxt ~chain ~block ?fee contract delegate + >>=? fun operation -> + let operation = Annotated_manager_operation.Single_manager operation in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?simulation + ?branch + ~source + ~fee:(Limit.of_option fee) + ~gas_limit:Limit.unknown + ~storage_limit:(Limit.known Z.zero) + ~src_pk + ~src_sk + ~fee_parameter + operation + >>=? return_single_manager_result + +let d_unit = + Micheline.strip_locations (Prim (0, Michelson_v1_primitives.D_Unit, [], [])) + +let t_unit = + Micheline.strip_locations (Prim (0, Michelson_v1_primitives.T_unit, [], [])) + +let build_lambda_for_transfer_to_implicit ~destination ~amount = + let (`Hex destination) = Signature.Public_key_hash.to_hex destination in + Format.asprintf + "{ DROP ; NIL operation ;PUSH key_hash 0x%s; IMPLICIT_ACCOUNT;PUSH mutez \ + %Ld ;UNIT;TRANSFER_TOKENS ; CONS }" + destination + (Tez.to_mutez amount) + +let build_lambda_for_transfer_to_originated ~destination ~entrypoint ~amount + ~parameter_type ~parameter = + let destination = + Data_encoding.Binary.to_bytes_exn Contract.encoding destination + in + let amount = Tez.to_mutez amount in + let (`Hex destination) = Hex.of_bytes destination in + let entrypoint = match entrypoint with "default" -> "" | s -> "%" ^ s in + if parameter_type = t_unit then + Format.asprintf + "{ DROP ; NIL operation ;PUSH address 0x%s; CONTRACT %s %a; \ + ASSERT_SOME;PUSH mutez %Ld ;UNIT;TRANSFER_TOKENS ; CONS }" + destination + entrypoint + Michelson_v1_printer.print_expr + parameter_type + amount + else + Format.asprintf + "{ DROP ; NIL operation ;PUSH address 0x%s; CONTRACT %s %a; \ + ASSERT_SOME;PUSH mutez %Ld ;PUSH %a %a;TRANSFER_TOKENS ; CONS }" + destination + entrypoint + Michelson_v1_printer.print_expr + parameter_type + amount + Michelson_v1_printer.print_expr + parameter_type + Michelson_v1_printer.print_expr + parameter + +let build_transaction_operation (cctxt : #full) ~chain ~block ~contract + ~destination ?(entrypoint = "default") ?arg ~amount ?fee ?gas_limit + ?storage_limit () = + (match Alpha_context.Contract.is_implicit destination with + | Some destination when entrypoint = "default" -> + return @@ build_lambda_for_transfer_to_implicit ~destination ~amount + | Some _ -> + cctxt#error + "Implicit accounts have no entrypoints. (targeted entrypoint %%%s on \ + contract %a)" + entrypoint + Contract.pp + destination + | None -> + (Michelson_v1_entrypoints.contract_entrypoint_type + cctxt + ~chain + ~block + ~contract:destination + ~entrypoint + >>=? function + | None -> + cctxt#error + "Contract %a has no entrypoint named %s" + Contract.pp + destination + entrypoint + | Some parameter_type -> return parameter_type) + >>=? fun parameter_type -> + (match arg with + | Some arg -> + Lwt.return @@ Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression arg + >>=? fun {expanded = arg; _} -> return_some arg + | None -> return_none) + >>=? fun parameter -> + let parameter = Option.value ~default:d_unit parameter in + return + @@ build_lambda_for_transfer_to_originated + ~destination + ~entrypoint + ~amount + ~parameter_type + ~parameter) + >>=? fun lambda -> + parse lambda >>=? fun parameters -> + let entrypoint = "do" in + return + (Client_proto_context.build_transaction_operation + ~amount:Tez.zero + ~parameters + ~entrypoint + ?fee + ?gas_limit + ?storage_limit + contract) + +let transfer (cctxt : #full) ~chain ~block ?confirmations ?dry_run + ?verbose_signing ?simulation ?branch ~source ~src_pk ~src_sk ~contract + ~destination ?(entrypoint = "default") ?arg ~amount ?fee ?gas_limit + ?storage_limit ?counter ~fee_parameter () : + (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult + Lwt.t = + build_transaction_operation + cctxt + ~chain + ~block + ~contract + ~destination + ~entrypoint + ?arg + ~amount + ?fee + ?gas_limit + ?storage_limit + () + >>=? fun operation -> + let operation = Annotated_manager_operation.Single_manager operation in + Injection.inject_manager_operation + cctxt + ~chain + ~block + ?confirmations + ?dry_run + ?verbose_signing + ?simulation + ?branch + ~source + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + ?counter + ~src_pk + ~src_sk + ~fee_parameter + operation + >>=? fun (oph, op, result) -> + Lwt.return (Injection.originated_contracts result) >>=? fun contracts -> + return_single_manager_result (oph, op, result) >>=? fun res -> + return (res, contracts) diff --git a/src/proto_012_PsiThaCa/lib_client/managed_contract.mli b/src/proto_012_PsiThaCa/lib_client/managed_contract.mli new file mode 100644 index 000000000000..ae532c986987 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/managed_contract.mli @@ -0,0 +1,125 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +open Protocol +open Alpha_context +open Protocol_client_context + +(** Retrieve the manager key in a contract storage. + The storage has to be of type `pair key_hash 'a`. +*) +val get_contract_manager : #full -> Contract.t -> public_key_hash tzresult Lwt.t + +(** Builds a delegation operation ready for injection *) +val build_delegate_operation : + #Protocol_client_context.full -> + chain:Chain_services.chain -> + block:Block_services.block -> + ?fee:Tez.t -> + Contract.t -> + public_key_hash option -> + Kind.transaction Annotated_manager_operation.t tzresult Lwt.t + +(** Set the delegate of a manageable contract. + For a contract with a `do`entrypoint, it builds the lambda that set + the provided delegate. + `~source` has to be the registered manager of the contract. +*) +val set_delegate : + #Protocol_client_context.full -> + chain:Chain_services.chain -> + block:Block_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?simulation:bool -> + ?branch:int -> + fee_parameter:Injection.fee_parameter -> + ?fee:Tez.t -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + Contract.t -> + public_key_hash option -> + Kind.transaction Kind.manager Injection.result tzresult Lwt.t + +(** Builds a transaction operation ready for injection *) +val build_transaction_operation : + #Protocol_client_context.full -> + chain:Chain_services.chain -> + block:Block_services.block -> + contract:Contract.t -> + destination:Contract.t -> + ?entrypoint:string -> + ?arg:string -> + amount:Tez.t -> + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:counter -> + unit -> + Kind.transaction Annotated_manager_operation.t tzresult Lwt.t + +(** Perform a transfer on behalf of a managed contract . + For a contract with a `do`entrypoint, it builds the lambda that + does the requested operation. + `~source` has to be the registered manager of the contract. +*) +val transfer : + #Protocol_client_context.full -> + chain:Chain_services.chain -> + block:Block_services.block -> + ?confirmations:int -> + ?dry_run:bool -> + ?verbose_signing:bool -> + ?simulation:bool -> + ?branch:int -> + source:public_key_hash -> + src_pk:public_key -> + src_sk:Client_keys.sk_uri -> + contract:Contract.t -> + destination:Contract.t -> + ?entrypoint:string -> + ?arg:string -> + amount:Tez.t -> + ?fee:Tez.t -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:counter -> + ?counter:counter -> + fee_parameter:Injection.fee_parameter -> + unit -> + (Kind.transaction Kind.manager Injection.result * Contract.t list) tzresult + Lwt.t + +val build_lambda_for_set_delegate : delegate:public_key_hash option -> string + +val build_lambda_for_transfer_to_implicit : + destination:public_key_hash -> amount:Tez.t -> string + +val build_lambda_for_transfer_to_originated : + destination:Contract.t -> + entrypoint:string -> + amount:Tez.t -> + parameter_type:Script.expr -> + parameter:Script.expr -> + string diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_emacs.ml b/src/proto_012_PsiThaCa/lib_client/michelson_v1_emacs.ml new file mode 100644 index 000000000000..2721fa702d46 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_emacs.ml @@ -0,0 +1,234 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Tezos_micheline +open Micheline + +let print_expr ppf expr = + let print_annot ppf = function + | [] -> () + | annots -> Format.fprintf ppf " %s" (String.concat " " annots) + in + let rec print_expr ppf = function + | Int (_, value) -> Format.fprintf ppf "%s" (Z.to_string value) + | String (_, value) -> Micheline_printer.print_string ppf value + | Bytes (_, value) -> Format.fprintf ppf "0x%a" Hex.pp (Hex.of_bytes value) + | Seq (_, items) -> + Format.fprintf + ppf + "(seq %a)" + (Format.pp_print_list ~pp_sep:Format.pp_print_space print_expr) + items + | Prim (_, name, [], []) -> Format.fprintf ppf "%s" name + | Prim (_, name, items, annot) -> + Format.fprintf + ppf + "(%s%a%s%a)" + name + print_annot + annot + (if items = [] then "" else " ") + (Format.pp_print_list ~pp_sep:Format.pp_print_space print_expr) + items + in + let root = root (Michelson_v1_primitives.strings_of_prims expr) in + Format.fprintf ppf "@[%a@]" print_expr root + +let print_var_annots ppf = List.iter (Format.fprintf ppf "%s ") + +let print_annot_expr ppf (expr, annot) = + Format.fprintf ppf "(%a%a)" print_var_annots annot print_expr expr + +open Micheline_parser +open Script_tc_errors + +let print_type_map ppf (parsed, type_map) = + let rec print_expr_types ppf = function + | Seq (loc, []) + | Prim (loc, _, [], _) + | Int (loc, _) + | Bytes (loc, _) + | String (loc, _) -> + print_item ppf loc + | Seq (loc, items) | Prim (loc, _, items, _) -> + print_item ppf loc ; + List.iter (print_expr_types ppf) items + and print_stack ppf items = + Format.fprintf + ppf + "(%a)" + (Format.pp_print_list ~pp_sep:Format.pp_print_space print_annot_expr) + items + and print_item ppf loc = + (let ( >?? ) = Option.bind in + List.assoc ~equal:Int.equal loc parsed.Michelson_v1_parser.expansion_table + >?? fun ({start = {point = s; _}; stop = {point = e; _}}, locs) -> + let locs = List.sort Stdlib.compare locs in + List.hd locs >?? fun hd_loc -> + List.assoc ~equal:Int.equal hd_loc type_map >?? fun (bef, aft) -> + Some (s, e, bef, aft)) + |> Option.iter (fun (s, e, bef, aft) -> + Format.fprintf + ppf + "(@[%d %d %a %a@])@," + s + e + print_stack + bef + print_stack + aft) + in + Format.fprintf ppf "(@[%a@])" print_expr_types (root parsed.unexpanded) + +let first_error_location errs = + let rec find = function + | [] -> 0 + | ( Inconsistent_type_annotations (loc, _, _) + | Unexpected_annotation loc + | Ill_formed_type (_, _, loc) + | Invalid_arity (loc, _, _, _) + | Invalid_seq_arity (loc, _, _) + | Invalid_namespace (loc, _, _, _) + | Invalid_primitive (loc, _, _) + | Invalid_kind (loc, _, _) + | Invalid_never_expr loc + | Fail_not_in_tail_position loc + | Undefined_binop (loc, _, _, _) + | Undefined_unop (loc, _, _) + | Bad_return (loc, _, _) + | Bad_stack (loc, _, _, _) + | Unmatched_branches (loc, _, _) + | Invalid_constant (loc, _, _) + | Invalid_syntactic_constant (loc, _, _) + | Invalid_contract (loc, _) + | Comparable_type_expected (loc, _) + | Michelson_v1_primitives.Invalid_primitive_name (_, loc) ) + :: _ -> + loc + | _ :: rest -> find rest + in + find errs + +let report_errors ppf (parsed, errs) = + let (eco, out) = + List.fold_left + (fun (eco, out) -> function + | Environment.Ecoproto_error err -> (err :: eco, out) + | err -> (eco, err :: out)) + ([], []) + errs + in + let (eco, out) = (List.rev eco, List.rev out) in + Format.fprintf + ppf + "(@[%a@,%a@])" + (fun ppf errs -> + let find_location loc = + let oloc = + WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc + ~equal:Int.equal + loc + parsed.Michelson_v1_parser.unexpansion_table + in + fst + (WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc ~equal:Int.equal oloc parsed.expansion_table) + in + match errs with + | top :: errs -> + let (errs, loc) = + ( List.map (fun e -> Environment.Ecoproto_error e) (top :: errs), + match top with + | Ill_typed_contract (expr, _) | Ill_typed_data (_, expr, _) -> + if expr = parsed.expanded then + find_location (first_error_location (top :: errs)) + else find_location 0 + | Michelson_v1_primitives.Invalid_primitive_name (expr, loc) -> + if + Micheline.strip_locations + (Michelson_v1_macros.unexpand_rec (Micheline.root expr)) + = parsed.Michelson_v1_parser.unexpanded + then find_location loc + else find_location 0 + | _ -> find_location 0 ) + in + let message = + Format.asprintf + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:false + ~show_source:false + ~parsed) + errs + in + let {start = {point = s; _}; stop = {point = e; _}} = loc in + Format.fprintf ppf "(%d %d %S)" (s + 1) (e + 1) message + | [] -> ()) + eco + (Format.pp_print_list (fun ppf err -> + let find_location loc = + let oloc = + WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc + ~equal:Int.equal + loc + parsed.Michelson_v1_parser.unexpansion_table + in + fst + (WithExceptions.Option.get ~loc:__LOC__ + @@ List.assoc ~equal:Int.equal oloc parsed.expansion_table) + in + let loc = + match err with + | Invalid_utf8_sequence (point, _) + | Unexpected_character (point, _) + | Undefined_escape_sequence (point, _) + | Missing_break_after_number point -> + {start = point; stop = point} + | Unterminated_string loc + | Unterminated_integer loc + | Unterminated_comment loc + | Invalid_hex_bytes loc + | Unclosed {loc; _} + | Unexpected {loc; _} + | Extra {loc; _} -> + loc + | Misaligned node -> location node + | _ -> find_location 0 + in + let message = + Format.asprintf + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:false + ~show_source:false + ~parsed) + [err] + in + let {start = {point = s; _}; stop = {point = e; _}} = loc in + Format.fprintf ppf "(%d %d %S)" (s + 1) (e + 1) message)) + out diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_emacs.mli b/src/proto_012_PsiThaCa/lib_client/michelson_v1_emacs.mli new file mode 100644 index 000000000000..6694308d4b02 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_emacs.mli @@ -0,0 +1,39 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +val print_expr : Format.formatter -> Script.expr -> unit + +val print_type_map : + Format.formatter -> + Michelson_v1_parser.parsed * Script_tc_errors.type_map -> + unit + +val report_errors : + Format.formatter -> + Michelson_v1_parser.parsed * Error_monad.error list -> + unit diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_entrypoints.ml b/src/proto_012_PsiThaCa/lib_client/michelson_v1_entrypoints.ml new file mode 100644 index 000000000000..9d6f08221e8b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_entrypoints.ml @@ -0,0 +1,216 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Protocol_client_context +open Alpha_context + +type error += Contract_without_code of Contract.t + +let () = + register_error_kind + `Permanent + ~id:"contractWithoutCode" + ~title:"The given contract has no code" + ~description: + "Attempt to get the code of a contract failed because it has nocode. No \ + scriptless contract should remain." + ~pp:(fun ppf contract -> + Format.fprintf ppf "Contract has no code %a." Contract.pp contract) + Data_encoding.(obj1 (req "contract" Contract.encoding)) + (function Contract_without_code c -> Some c | _ -> None) + (fun c -> Contract_without_code c) + +let print_errors (cctxt : #Client_context.printer) errs = + cctxt#error "%a" Error_monad.pp_print_trace errs >>= fun () -> return_unit + +let script_entrypoint_type cctxt ~(chain : Chain_services.chain) ~block + (program : Script.expr) ~entrypoint = + Plugin.RPC.Scripts.entrypoint_type + cctxt + (chain, block) + ~script:program + ~entrypoint + >>= function + | Ok ty -> return_some ty + | Error + (Environment.Ecoproto_error (Script_tc_errors.No_such_entrypoint _) :: _) + -> + return None + | Error _ as err -> Lwt.return err + +let contract_entrypoint_type cctxt ~(chain : Chain_services.chain) ~block + ~contract ~entrypoint = + Alpha_services.Contract.entrypoint_type + cctxt + (chain, block) + contract + entrypoint + >>= function + | Ok ty -> return_some ty + | Error (RPC_context.Not_found _ :: _) -> return None + | Error _ as err -> Lwt.return err + +let print_entrypoint_type (cctxt : #Client_context.printer) + ?(on_errors = print_errors cctxt) ~emacs ?contract ?script_name ~entrypoint + = function + | Ok (Some ty) -> + (if emacs then + cctxt#message + "@[((entrypoint . %s) (type . %a))@]@." + entrypoint + Michelson_v1_emacs.print_expr + ty + else + cctxt#message + "@[Entrypoint %s: %a@]@." + entrypoint + Michelson_v1_printer.print_expr + ty) + >>= fun () -> return_unit + | Ok None -> + cctxt#message + "@[No entrypoint named %s%a%a@]@." + entrypoint + (Format.pp_print_option (fun ppf -> + Format.fprintf ppf " for contract %a" Contract.pp)) + contract + (Format.pp_print_option (fun ppf -> Format.fprintf ppf " for script %s")) + script_name + >>= fun () -> return_unit + | Error errs -> on_errors errs + +let list_contract_unreachables_and_entrypoints cctxt ~chain ~block ~contract = + Alpha_services.Contract.list_entrypoints cctxt (chain, block) contract + +let list_contract_unreachables cctxt ~chain ~block ~contract = + list_contract_unreachables_and_entrypoints cctxt ~chain ~block ~contract + >>=? fun (unreachables, _) -> return unreachables + +let list_contract_entrypoints cctxt ~chain ~block ~contract = + list_contract_unreachables_and_entrypoints cctxt ~chain ~block ~contract + >>=? fun (_, entrypoints) -> + if not @@ List.mem_assoc ~equal:String.equal "default" entrypoints then + contract_entrypoint_type cctxt ~chain ~block ~contract ~entrypoint:"default" + >>= function + | Ok (Some ty) -> return (("default", ty) :: entrypoints) + | Ok None -> return entrypoints + | Error _ as err -> Lwt.return err + else return entrypoints + +let list_unreachables cctxt ~chain ~block (program : Script.expr) = + Plugin.RPC.Scripts.list_entrypoints cctxt (chain, block) ~script:program + >>=? fun (unreachables, _) -> return unreachables + +let list_entrypoints cctxt ~chain ~block (program : Script.expr) = + Plugin.RPC.Scripts.list_entrypoints cctxt (chain, block) ~script:program + >>=? fun (_, entrypoints) -> + if not @@ List.mem_assoc ~equal:String.equal "default" entrypoints then + script_entrypoint_type cctxt ~chain ~block program ~entrypoint:"default" + >>= function + | Ok (Some ty) -> return (("default", ty) :: entrypoints) + | Ok None -> return entrypoints + | Error _ as err -> Lwt.return err + else return entrypoints + +let print_entrypoints_list (cctxt : #Client_context.printer) + ?(on_errors = print_errors cctxt) ~emacs ?contract ?script_name = function + | Ok entrypoint_list -> + (if emacs then + cctxt#message + "@[(@[%a@])@." + (Format.pp_print_list + ~pp_sep:Format.pp_print_cut + (fun ppf (entrypoint, ty) -> + Format.fprintf + ppf + "@[( ( entrypoint . %s ) ( type . @[%a@]))@]" + entrypoint + Michelson_v1_emacs.print_expr + ty)) + entrypoint_list + else + cctxt#message + "@[Entrypoints%a%a: @,%a@]@." + (Format.pp_print_option (fun ppf -> + Format.fprintf ppf " for contract %a" Contract.pp)) + contract + (Format.pp_print_option (fun ppf -> + Format.fprintf ppf " for script %s")) + script_name + (Format.pp_print_list + ~pp_sep:Format.pp_print_cut + (fun ppf (entrypoint, ty) -> + Format.fprintf + ppf + "@[%s: @[%a@]@]" + entrypoint + Michelson_v1_printer.print_expr + ty)) + entrypoint_list) + >>= fun () -> return_unit + | Error errs -> on_errors errs + +let print_unreachables (cctxt : #Client_context.printer) + ?(on_errors = print_errors cctxt) ~emacs ?contract ?script_name = function + | Ok unreachable -> + (if emacs then + cctxt#message + "@[(@[%a@])@." + (Format.pp_print_list ~pp_sep:Format.pp_print_cut (fun ppf path -> + Format.fprintf + ppf + "@[( unreachable-path . %a )@]" + (Format.pp_print_list + ~pp_sep:Format.pp_print_space + (fun ppf prim -> + Format.pp_print_string ppf + @@ Michelson_v1_primitives.string_of_prim prim)) + path)) + unreachable + else + match unreachable with + | [] -> cctxt#message "@[None.@]@." + | _ -> + cctxt#message + "@[Unreachable paths in the argument%a%a: @[%a@]@." + (Format.pp_print_option (fun ppf -> + Format.fprintf ppf " of contract %a" Contract.pp)) + contract + (Format.pp_print_option (fun ppf -> + Format.fprintf ppf " of script %s")) + script_name + (Format.pp_print_list ~pp_sep:Format.pp_print_cut (fun ppf -> + Format.fprintf + ppf + "@[ %a @]" + (Format.pp_print_list + ~pp_sep:(fun ppf _ -> Format.pp_print_string ppf "/") + (fun ppf prim -> + Format.pp_print_string ppf + @@ Michelson_v1_primitives.string_of_prim prim)))) + unreachable) + >>= fun () -> return_unit + | Error errs -> on_errors errs diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_entrypoints.mli b/src/proto_012_PsiThaCa/lib_client/michelson_v1_entrypoints.mli new file mode 100644 index 000000000000..96d3ad82c2f0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_entrypoints.mli @@ -0,0 +1,108 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** Returns [Some type] if the contract has an entrypoint of type [type]. None if it does not exists. *) +val script_entrypoint_type : + #Protocol_client_context.rpc_context -> + chain:Chain_services.chain -> + block:Block_services.block -> + Alpha_context.Script.expr -> + entrypoint:string -> + Alpha_context.Script.expr option tzresult Lwt.t + +(** Returns [Some type] if the script has an entrypoint of type [type]. None if it does not exists. *) +val contract_entrypoint_type : + #Protocol_client_context.rpc_context -> + chain:Chain_services.chain -> + block:Block_services.block -> + contract:Alpha_context.Contract.t -> + entrypoint:string -> + Alpha_context.Script.expr option tzresult Lwt.t + +val print_entrypoint_type : + #Client_context.printer -> + ?on_errors:(error list -> unit tzresult Lwt.t) -> + emacs:bool -> + ?contract:Alpha_context.Contract.t -> + ?script_name:string -> + entrypoint:string -> + Alpha_context.Script.expr option tzresult -> + unit tzresult Lwt.t + +(** List paths of unreachable parameters. + Only useful to test the stitching, as no such parameter should be + allowed in originated contracts. *) +val list_contract_unreachables : + #Protocol_client_context.rpc_context -> + chain:Chain_services.chain -> + block:Block_services.block -> + contract:Alpha_context.Contract.t -> + Michelson_v1_primitives.prim list list tzresult Lwt.t + +val list_unreachables : + #Protocol_client_context.rpc_context -> + chain:Chain_services.chain -> + block:Block_services.block -> + Alpha_context.Script.expr -> + Michelson_v1_primitives.prim list list tzresult Lwt.t + +val print_unreachables : + #Client_context.printer -> + ?on_errors:(error list -> unit tzresult Lwt.t) -> + emacs:bool -> + ?contract:Alpha_context.Contract.t -> + ?script_name:string -> + Michelson_v1_primitives.prim list list tzresult -> + unit tzresult Lwt.t + +(** List the contract entrypoints with their types. + If their is no explicit default, th type of default entrypoint will still be given. +*) +val list_contract_entrypoints : + #Protocol_client_context.rpc_context -> + chain:Chain_services.chain -> + block:Block_services.block -> + contract:Alpha_context.Contract.t -> + (string * Alpha_context.Script.expr) list tzresult Lwt.t + +(** List the script entrypoints with their types. *) +val list_entrypoints : + #Protocol_client_context.rpc_context -> + chain:Chain_services.chain -> + block:Block_services.block -> + Alpha_context.Script.expr -> + (string * Alpha_context.Script.expr) list tzresult Lwt.t + +(** Print the contract entrypoints with their types. *) +val print_entrypoints_list : + #Client_context.printer -> + ?on_errors:(error list -> unit tzresult Lwt.t) -> + emacs:bool -> + ?contract:Alpha_context.Contract.t -> + ?script_name:string -> + (string * Alpha_context.Script.expr) list tzresult -> + unit tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_error_reporter.ml b/src/proto_012_PsiThaCa/lib_client/michelson_v1_error_reporter.ml new file mode 100644 index 000000000000..fcbfb443c7a2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_error_reporter.ml @@ -0,0 +1,767 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Tezos_micheline +open Script_tc_errors +open Script_interpreter +open Michelson_v1_printer + +let print_ty ppf ty = Michelson_v1_printer.print_expr_unwrapped ppf ty + +let print_var_annot ppf annot = List.iter (Format.fprintf ppf "@ %s") annot + +let print_stack_ty ?(depth = max_int) ppf s = + let rec loop depth ppf = function + | [] -> () + | _ when depth <= 0 -> Format.fprintf ppf "..." + | [(last, annot)] -> + Format.fprintf ppf "%a%a" print_ty last print_var_annot annot + | (last, annot) :: rest -> + Format.fprintf + ppf + "%a%a@ :@ %a" + print_ty + last + print_var_annot + annot + (loop (depth - 1)) + rest + in + match s with + | [] -> Format.fprintf ppf "[]" + | sty -> Format.fprintf ppf "@[[ %a ]@]" (loop depth) sty + +let rec print_enumeration ppf = function + | [single] -> Format.fprintf ppf "%a" Format.pp_print_text single + | [prev; last] -> + Format.fprintf + ppf + "%a@ or@ %a" + Format.pp_print_text + prev + Format.pp_print_text + last + | first :: rest -> + Format.fprintf + ppf + "%a,@ %a" + Format.pp_print_text + first + print_enumeration + rest + | [] -> assert false + +let collect_error_locations errs = + let rec collect acc = function + | Environment.Ecoproto_error + ( Ill_formed_type (_, _, _) + | No_such_entrypoint _ | Duplicate_entrypoint _ + | Unreachable_entrypoint _ + | Runtime_contract_error (_, _) + | Michelson_v1_primitives.Invalid_primitive_name (_, _) + | Ill_typed_data (_, _, _) + | Ill_typed_contract (_, _) ) + :: _ + | [] -> + acc + | Environment.Ecoproto_error + ( Invalid_arity (loc, _, _, _) + | Invalid_seq_arity (loc, _, _) + | Inconsistent_type_annotations (loc, _, _) + | Unexpected_annotation loc + | Ungrouped_annotations loc + | Type_too_large (loc, _) + | Invalid_namespace (loc, _, _, _) + | Invalid_primitive (loc, _, _) + | Invalid_kind (loc, _, _) + | Invalid_never_expr loc + | Duplicate_field (loc, _) + | Unexpected_lazy_storage loc + | Unexpected_operation loc + | Fail_not_in_tail_position loc + | Undefined_binop (loc, _, _, _) + | Undefined_unop (loc, _, _) + | Bad_return (loc, _, _) + | Bad_stack (loc, _, _, _) + | Unmatched_branches (loc, _, _) + | Self_in_lambda loc + | Invalid_constant (loc, _, _) + | Invalid_syntactic_constant (loc, _, _) + | Invalid_contract (loc, _) + | Comparable_type_expected (loc, _) + | Overflow (loc, _) + | Reject (loc, _, _) + | Pair_bad_argument loc + | Unpair_bad_argument loc + | Dup_n_bad_argument loc ) + :: rest -> + collect (loc :: acc) rest + | _ :: rest -> collect acc rest + in + collect [] errs + +let report_errors ~details ~show_source ?parsed ppf errs = + let rec print_trace locations errs = + let print_loc ppf loc = + match locations loc with + | None -> Format.fprintf ppf "At (unshown) location %d, " loc + | Some loc -> + Format.fprintf + ppf + "%s,@ " + (String.capitalize_ascii + (Format.asprintf "%a" Micheline_parser.print_location loc)) + in + let parsed_locations parsed loc = + let ( >?? ) = Option.bind in + List.assoc + ~equal:Int.equal + loc + parsed.Michelson_v1_parser.unexpansion_table + >?? fun oloc -> + List.assoc ~equal:Int.equal oloc parsed.expansion_table + >?? fun (ploc, _) -> Some ploc + in + let print_source ppf (parsed, _hilights) (* TODO *) = + let lines = String.split_on_char '\n' parsed.Michelson_v1_parser.source in + let cols = String.length (string_of_int (List.length lines)) in + Format.fprintf + ppf + "@[%a@]" + (Format.pp_print_list (fun ppf (i, l) -> + Format.fprintf ppf "%0*d: %s" cols i l)) + (List.rev_mapi (fun i x -> (i + 1, x)) lines |> List.rev) + in + match errs with + | [] -> () + | Environment.Ecoproto_error + (Michelson_v1_primitives.Invalid_primitive_name (expr, loc)) + :: rest -> + let parsed = + match parsed with + | Some parsed -> + if + Micheline.strip_locations + (Michelson_v1_macros.unexpand_rec (Micheline.root expr)) + = parsed.Michelson_v1_parser.unexpanded + then parsed + else Michelson_v1_printer.unparse_invalid expr + | None -> Michelson_v1_printer.unparse_invalid expr + in + let hilights = loc :: collect_error_locations rest in + if show_source then + Format.fprintf + ppf + "@[@[Invalid primitive:@ %a@]@]" + print_source + (parsed, hilights) + else Format.fprintf ppf "Invalid primitive." ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace (parsed_locations parsed) rest + | Environment.Ecoproto_error (Ill_typed_data (name, expr, ty)) :: rest -> + let parsed = + match parsed with + | Some parsed when expr = parsed.Michelson_v1_parser.expanded -> + parsed + | Some _ | None -> Michelson_v1_printer.unparse_expression expr + in + let hilights = collect_error_locations rest in + Format.fprintf + ppf + "@[@[Ill typed %adata:@ %a@]@ @[is not an \ + expression of type@ %a@]@]" + (fun ppf -> function + | None -> () + | Some s -> Format.fprintf ppf "%s " s) + name + print_source + (parsed, hilights) + print_ty + ty ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace (parsed_locations parsed) rest + | Environment.Ecoproto_error (No_such_entrypoint entrypoint) :: rest -> + Format.fprintf ppf "Contract has no entrypoint named %s" entrypoint ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Duplicate_entrypoint entrypoint) :: rest -> + Format.fprintf ppf "Contract has two entrypoints named %s" entrypoint ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Unreachable_entrypoint path) :: rest -> + let path = + String.concat + "/" + (List.map Michelson_v1_primitives.string_of_prim path) + in + Format.fprintf ppf "Entrypoint at path %s is not reachable" path ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Ill_formed_type (_, expr, loc)) :: rest -> + let parsed = + match parsed with + | Some parsed when expr = parsed.Michelson_v1_parser.expanded -> + parsed + | Some _ | None -> Michelson_v1_printer.unparse_expression expr + in + let hilights = loc :: collect_error_locations errs in + if show_source then + Format.fprintf + ppf + "@[%aill formed type:@ %a@]" + print_loc + loc + print_source + (parsed, hilights) + else Format.fprintf ppf "Ill formed type." ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace (parsed_locations parsed) rest + | Environment.Ecoproto_error (Ill_typed_contract (expr, type_map)) :: rest + -> + let parsed = + match parsed with + | Some parsed + when (not details) && expr = parsed.Michelson_v1_parser.expanded -> + parsed + | Some _ | None -> + Michelson_v1_printer.unparse_toplevel ~type_map expr + in + let hilights = collect_error_locations rest in + if show_source then + Format.fprintf + ppf + "@[Ill typed contract:@, %a@]" + print_source + (parsed, hilights) + else Format.fprintf ppf "Ill typed contract." ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace (parsed_locations parsed) rest + | Environment.Ecoproto_error Apply.Gas_quota_exceeded_init_deserialize + :: rest -> + Format.fprintf + ppf + "@[Not enough gas to deserialize the operation.@,\ + Injecting such a transaction could have you banned from mempools.@]" ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Deprecated_instruction prim) :: rest -> + Format.fprintf + ppf + "@[Use of deprecated instruction: %s@]" + (Michelson_v1_primitives.string_of_prim prim) ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error Cannot_serialize_storage :: rest -> + Format.fprintf + ppf + "Cannot serialize the resulting storage value within the provided \ + gas bounds." ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Missing_field prim) :: rest -> + Format.fprintf + ppf + "@[Missing contract field: %s@]" + (Michelson_v1_primitives.string_of_prim prim) ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Duplicate_field (loc, prim)) :: rest -> + Format.fprintf + ppf + "@[%aduplicate contract field: %s@]" + print_loc + loc + (Michelson_v1_primitives.string_of_prim prim) ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Unexpected_lazy_storage loc) :: rest -> + Format.fprintf + ppf + "%abig_map or sapling_state type not expected here" + print_loc + loc ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Unexpected_operation loc) :: rest -> + Format.fprintf + ppf + "%aoperation type forbidden in parameter, storage and constants" + print_loc + loc ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Unexpected_contract loc) :: rest -> + Format.fprintf + ppf + "%acontract type forbidden in storage and constants" + print_loc + loc ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error (Runtime_contract_error (contract, expr)) + :: rest -> + let parsed = + match parsed with + | Some parsed when expr = parsed.Michelson_v1_parser.expanded -> + parsed + | Some _ | None -> Michelson_v1_printer.unparse_toplevel expr + in + let hilights = collect_error_locations rest in + Format.fprintf + ppf + "@[Runtime error in contract %a:@ %a@]" + Contract.pp + contract + print_source + (parsed, hilights) ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace (parsed_locations parsed) rest + | Environment.Ecoproto_error (Apply.Internal_operation_replay op) :: rest -> + Format.fprintf + ppf + "@[Internal operation replay attempt:@,%a@]" + Operation_result.pp_internal_operation + op ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error Gas.Gas_limit_too_high :: rest -> + Format.fprintf + ppf + "Gas limit for the operation is out of the protocol hard bounds." ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error Gas.Block_quota_exceeded :: rest -> + Format.fprintf + ppf + "Gas limit for the block exceeded during typechecking or execution." ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error Gas.Operation_quota_exceeded :: rest -> + Format.fprintf + ppf + "@[Gas limit exceeded during typechecking or execution.@,\ + Try again with a higher gas limit.@]" ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | Environment.Ecoproto_error Fees.Operation_quota_exceeded :: rest -> + Format.fprintf + ppf + "@[Storage limit exceeded during typechecking or execution.@,\ + Try again with a higher storage limit.@]" ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | [Environment.Ecoproto_error (Script_interpreter.Bad_contract_parameter c)] + -> + Format.fprintf + ppf + "@[Account %a is not a smart contract, it does not take \ + arguments.@,\ + The `-arg' flag should not be used when transferring to an \ + account.@]" + Contract.pp + c + | Environment.Ecoproto_error err :: rest -> + (match err with + | Bad_contract_parameter c -> + Format.fprintf + ppf + "Invalid argument passed to contract %a." + Contract.pp + c + | Invalid_arity (loc, name, exp, got) -> + Format.fprintf + ppf + "%aprimitive %s expects %d arguments but is given %d." + print_loc + loc + (Michelson_v1_primitives.string_of_prim name) + exp + got + | Invalid_seq_arity (loc, exp, got) -> + Format.fprintf + ppf + "%asequence expects at least %d elements but is given %d." + print_loc + loc + exp + got + | Invalid_namespace (loc, name, exp, got) -> + let human_namespace = function + | Michelson_v1_primitives.Instr_namespace -> ("an", "instruction") + | Type_namespace -> ("a", "type name") + | Constant_namespace -> ("a", "constant constructor") + | Keyword_namespace -> ("a", "keyword") + | Constant_hash_namespace -> ("a", "constant hash") + in + Format.fprintf + ppf + "@[%aunexpected %s %s, only %s %s can be used here." + print_loc + loc + (snd (human_namespace got)) + (Michelson_v1_primitives.string_of_prim name) + (fst (human_namespace exp)) + (snd (human_namespace exp)) + | Invalid_primitive (loc, exp, got) -> + Format.fprintf + ppf + "@[%ainvalid primitive %s, only %a can be used here." + print_loc + loc + (Michelson_v1_primitives.string_of_prim got) + print_enumeration + (List.map Michelson_v1_primitives.string_of_prim exp) + | Invalid_kind (loc, exp, got) -> + let human_kind = function + | Seq_kind -> ("a", "sequence") + | Prim_kind -> ("a", "primitive") + | Int_kind -> ("an", "int") + | String_kind -> ("a", "string") + | Bytes_kind -> ("a", "byte sequence") + in + Format.fprintf + ppf + "@[%aunexpected %s, only@ %a@ can be used here." + print_loc + loc + (snd (human_kind got)) + print_enumeration + (List.map + (fun k -> + let (a, n) = human_kind k in + a ^ " " ^ n) + exp) + | Invalid_never_expr loc -> + Format.fprintf + ppf + "@[%athis expression should have type never but type never has \ + no inhabitant." + print_loc + loc + | Duplicate_map_keys (_, expr) -> + Format.fprintf + ppf + "@[Map literals cannot contain duplicate keys, however a \ + duplicate key was found:@ @[%a@]" + print_expr + expr + | Unordered_map_keys (_, expr) -> + Format.fprintf + ppf + "@[Keys in a map literal must be in strictly ascending \ + order, but they were unordered in literal:@ @[%a@]" + print_expr + expr + | Duplicate_set_values (_, expr) -> + Format.fprintf + ppf + "@[Set literals cannot contain duplicate values, however a \ + duplicate value was found:@ @[%a@]" + print_expr + expr + | Unordered_set_values (_, expr) -> + Format.fprintf + ppf + "@[Values in a set literal must be in strictly ascending \ + order, but they were unordered in literal:@ @[%a@]" + print_expr + expr + | Fail_not_in_tail_position loc -> + Format.fprintf + ppf + "%aThe FAIL instruction must appear in a tail position." + print_loc + loc + | Undefined_binop (loc, name, tya, tyb) -> + Format.fprintf + ppf + "@[@[%aoperator %s is undefined between@ %a@]@ \ + @[and@ %a.@]@]" + print_loc + loc + (Michelson_v1_primitives.string_of_prim name) + print_ty + tya + print_ty + tyb + | Undefined_unop (loc, name, ty) -> + Format.fprintf + ppf + "@[@[%aoperator %s is undefined on@ %a@]@]" + print_loc + loc + (Michelson_v1_primitives.string_of_prim name) + print_ty + ty + | Bad_return (loc, got, exp) -> + Format.fprintf + ppf + "@[%awrong stack type at end of body:@,\ + - @[expected return stack type:@ %a,@]@,\ + - @[actual stack type:@ %a.@]@]" + print_loc + loc + (fun ppf -> print_stack_ty ppf) + [(exp, [])] + (fun ppf -> print_stack_ty ppf) + got + | Bad_stack (loc, name, depth, sty) -> + Format.fprintf + ppf + "@[%awrong stack type for instruction %s:@ %a.@]" + print_loc + loc + (Michelson_v1_primitives.string_of_prim name) + (print_stack_ty ~depth) + sty + | Unmatched_branches (loc, sta, stb) -> + Format.fprintf + ppf + "@[%atwo branches don't end with the same stack type:@,\ + - @[first stack type:@ %a,@]@,\ + - @[other stack type:@ %a.@]@]" + print_loc + loc + (fun ppf -> print_stack_ty ppf) + sta + (fun ppf -> print_stack_ty ppf) + stb + | Bad_view_name loc -> + Format.fprintf + ppf + "@[%athe name of view should be of type string @]" + print_loc + loc + | Duplicated_view_name loc -> + Format.fprintf + ppf + "@[%athe name of view in toplevel should be unique @]" + print_loc + loc + | Ill_typed_view {loc; actual; expected} -> + Format.fprintf + ppf + "@[%athe return of a view block did not match the expected \ + type.@,\ + - @[resulted view stack type:@ %a,@]@,\ + - @[expected view stack type:@ %a.@]@]" + print_loc + loc + (fun ppf -> print_stack_ty ppf) + actual + (fun ppf -> print_stack_ty ppf) + expected + | View_name_too_long name -> + Format.fprintf + ppf + "@[ A view name, \"%s\", exceeds the maximum length of 31 \ + characters." + name + | Inconsistent_annotations (annot1, annot2) -> + Format.fprintf + ppf + "@[The two annotations do not match:@,\ + - @[%s@]@,\ + - @[%s@]@]" + annot1 + annot2 + | Inconsistent_field_annotations (annot1, annot2) -> + Format.fprintf + ppf + "@[The field access annotation does not match:@,\ + - @[%s@]@,\ + - @[%s@]@]" + annot1 + annot2 + | Inconsistent_type_annotations (loc, ty1, ty2) -> + Format.fprintf + ppf + "@[%athe two types contain incompatible annotations:@,\ + - @[%a@]@,\ + - @[%a@]@]" + print_loc + loc + print_ty + ty1 + print_ty + ty2 + | Inconsistent_type_sizes (size1, size2) -> + Format.fprintf + ppf + "@[The two types have different sizes, the first one is of \ + size %d while the other one is of size %d@]" + size1 + size2 + | Unexpected_annotation loc -> + Format.fprintf ppf "@[%aunexpected annotation." print_loc loc + | Ungrouped_annotations loc -> + Format.fprintf + ppf + "@[%aAnnotations of the same kind must be grouped." + print_loc + loc + | Type_too_large (loc, maximum_size) -> + Format.fprintf + ppf + "@[%atype exceeded maximum type size (%d)." + print_loc + loc + maximum_size + | Pair_bad_argument loc -> + Format.fprintf + ppf + "%aPAIR expects an argument of at least 2." + print_loc + loc + | Unpair_bad_argument loc -> + Format.fprintf + ppf + "%aUNPAIR expects an argument of at least 2." + print_loc + loc + | Dup_n_bad_argument loc -> + Format.fprintf + ppf + "%aDUP n expects an argument of at least 1 (passed 0)." + print_loc + loc + | Self_in_lambda loc -> + Format.fprintf + ppf + "%aThe SELF instruction cannot appear in a lambda." + print_loc + loc + | Non_dupable_type (loc, ty) -> + Format.fprintf + ppf + "%atype %a cannot be used here because it is not duplicable. \ + Only duplicable types can be used with the DUP instruction and \ + as view inputs and outputs." + print_loc + loc + print_ty + ty + | Unexpected_ticket loc -> + Format.fprintf + ppf + "%aTicket in unauthorized position (type error)." + print_loc + loc + | Bad_stack_length -> Format.fprintf ppf "Bad stack length." + | Bad_stack_item lvl -> Format.fprintf ppf "Bad stack item %d." lvl + | Unexpected_forged_value loc -> + Format.fprintf ppf "%aUnexpected forged value." print_loc loc + | Invalid_constant (loc, got, exp) -> + Format.fprintf + ppf + "@[@[%avalue@ %a@]@ @[is invalid for type@ \ + %a.@]@]" + print_loc + loc + print_expr + got + print_ty + exp + | Invalid_syntactic_constant (loc, got, exp) -> + Format.fprintf + ppf + "@[@[%avalue@ %a@]@ @[is invalid, expected@ \ + %s@]@]" + print_loc + loc + print_expr + got + exp + | Invalid_contract (loc, contract) -> + Format.fprintf + ppf + "%ainvalid contract %a." + print_loc + loc + Contract.pp + contract + | Comparable_type_expected (loc, ty) -> + Format.fprintf ppf "%acomparable type expected." print_loc loc ; + Format.fprintf + ppf + "@[@[Type@ %a@]@ is not comparable.@]" + print_ty + ty + | Inconsistent_types (opt_loc, tya, tyb) -> + Format.fprintf + ppf + "@[@[%aType@ %a@]@ @[is not compatible with \ + type@ %a.@]@]" + (fun fmt -> function None -> () | Some loc -> print_loc fmt loc) + opt_loc + print_ty + tya + print_ty + tyb + | Reject (loc, v, trace) -> + Format.fprintf + ppf + "%ascript reached FAILWITH instruction@ @[with@ %a@]%a" + print_loc + loc + print_expr + v + (fun ppf -> function + | None -> () + | Some trace -> + Format.fprintf + ppf + "@,@[trace@,%a@]" + print_execution_trace + trace) + trace + | Overflow (loc, trace) -> + Format.fprintf + ppf + "%aunexpected arithmetic overflow%a" + print_loc + loc + (fun ppf -> function + | None -> () + | Some trace -> + Format.fprintf + ppf + "@,@[trace@,%a@]" + print_execution_trace + trace) + trace + | err -> Format.fprintf ppf "%a" Environment.Error_monad.pp err) ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + | err :: rest -> + Format.fprintf ppf "%a" Error_monad.pp err ; + if rest <> [] then Format.fprintf ppf "@," ; + print_trace locations rest + in + Format.fprintf ppf "@[" ; + print_trace (fun _ -> None) errs ; + Format.fprintf ppf "@]" diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_error_reporter.mli b/src/proto_012_PsiThaCa/lib_client/michelson_v1_error_reporter.mli new file mode 100644 index 000000000000..e1bbea6eb12c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_error_reporter.mli @@ -0,0 +1,32 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val report_errors : + details:bool -> + show_source:bool -> + ?parsed:Michelson_v1_parser.parsed -> + Format.formatter -> + Error_monad.error list -> + unit diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_helpers.ml b/src/proto_012_PsiThaCa/lib_client/michelson_v1_helpers.ml new file mode 100644 index 000000000000..40d1698fff37 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_helpers.ml @@ -0,0 +1,60 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Generic Michelson building functions *) + +open Tezos_micheline.Micheline +open Protocol.Alpha_context.Script + +let seq ~loc l = Seq (loc, l) + +let pair ~loc a b = Prim (loc, D_Pair, [a; b], []) + +let none ~loc () = Prim (loc, D_None, [], []) + +let some ~loc a = Prim (loc, D_Some, [a], []) + +let left ~loc a = Prim (loc, D_Left, [a], []) + +let right ~loc b = Prim (loc, D_Right, [b], []) + +let int ~loc i = Int (loc, i) + +let bytes ~loc s = Bytes (loc, s) + +let unit_t ~loc = Prim (loc, T_unit, [], []) + +let unit ~loc = Prim (loc, D_Unit, [], []) + +let lambda_from_string code = + Tezos_micheline.Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression code + >|? fun parsed -> root Michelson_v1_parser.(parsed.expanded) + +let lambda_t ~loc param res = Prim (loc, T_lambda, [param; res], []) + +let operation_t ~loc = Prim (loc, T_operation, [], []) + +let operations_t ~loc = Prim (loc, T_list, [operation_t ~loc], []) diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_macros.ml b/src/proto_012_PsiThaCa/lib_client/michelson_v1_macros.ml new file mode 100644 index 000000000000..448bd000108e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_macros.ml @@ -0,0 +1,1519 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol_client_context +open Tezos_micheline +open Micheline +module IntMap = Map.Make (Compare.Int) + +type 'l node = ('l, string) Micheline.node + +type error += Unexpected_macro_annotation of string + +type error += Sequence_expected of string + +type error += Invalid_arity of string * int * int + +let rec check_letters str i j f = + i > j || (f str.[i] && check_letters str (i + 1) j f) + +let expand_caddadr original = + match original with + | Prim (loc, str, args, annot) -> + let len = String.length str in + if + len > 3 + && str.[0] = 'C' + && str.[len - 1] = 'R' + && check_letters str 1 (len - 2) (function + | 'A' | 'D' -> true + | _ -> false) + then + (match args with + | [] -> ok () + | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) + >>? fun () -> + let path_annot = + List.filter (function "@%" | "@%%" -> true | _ -> false) annot + in + let rec parse i acc = + if i = 0 then Seq (loc, acc) + else + let annot = if i = len - 2 then annot else path_annot in + match str.[i] with + | 'A' -> parse (i - 1) (Prim (loc, "CAR", [], annot) :: acc) + | 'D' -> parse (i - 1) (Prim (loc, "CDR", [], annot) :: acc) + | _ -> assert false + in + ok (Some (parse (len - 2) [])) + else ok None + | _ -> ok None + +let expand_carn original = + match original with + | Prim (loc, "CAR", [Int (loc2, n)], annot) -> + ok + (Some + (Seq + ( loc, + [ + Prim + ( loc, + "GET", + [Int (loc2, Z.(of_int 1 + (n * of_int 2)))], + annot ); + ] ))) + | _ -> ok None + +let expand_cdrn original = + match original with + | Prim (loc, "CDR", [Int (loc2, n)], annot) -> + ok + (Some + (Seq (loc, [Prim (loc, "GET", [Int (loc2, Z.(n * of_int 2))], annot)]))) + | _ -> ok None + +let extract_field_annots annot = + List.partition + (fun a -> + match a.[0] with + | '%' -> true + | _ -> false + | exception Invalid_argument _ -> false) + annot + +let expand_set_caddadr original = + match original with + | Prim (loc, str, args, annot) -> + let len = String.length str in + if + len >= 7 + && String.sub str 0 5 = "SET_C" + && str.[len - 1] = 'R' + && check_letters str 5 (len - 2) (function + | 'A' | 'D' -> true + | _ -> false) + then + (match args with + | [] -> ok () + | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) + >>? fun () -> + (match extract_field_annots annot with + | ([], annot) -> ok (None, annot) + | ([f], annot) -> ok (Some f, annot) + | (_, _) -> error (Unexpected_macro_annotation str)) + >>? fun (field_annot, annot) -> + let rec parse i acc = + if i = 4 then acc + else + let annot = if i = 5 then annot else [] in + match str.[i] with + | 'A' -> + let acc = + Seq + ( loc, + [ + Prim (loc, "DUP", [], []); + Prim + ( loc, + "DIP", + [Seq (loc, [Prim (loc, "CAR", [], ["@%%"]); acc])], + [] ); + Prim (loc, "CDR", [], ["@%%"]); + Prim (loc, "SWAP", [], []); + Prim (loc, "PAIR", [], "%@" :: "%@" :: annot); + ] ) + in + parse (i - 1) acc + | 'D' -> + let acc = + Seq + ( loc, + [ + Prim (loc, "DUP", [], []); + Prim + ( loc, + "DIP", + [Seq (loc, [Prim (loc, "CDR", [], ["@%%"]); acc])], + [] ); + Prim (loc, "CAR", [], ["@%%"]); + Prim (loc, "PAIR", [], "%@" :: "%@" :: annot); + ] ) + in + parse (i - 1) acc + | _ -> assert false + in + match str.[len - 2] with + | 'A' -> + let access_check = + match field_annot with + | None -> [] + | Some f -> + [ + Prim (loc, "DUP", [], []); + Prim (loc, "CAR", [], [f]); + Prim (loc, "DROP", [], []); + ] + in + let encoding = + [Prim (loc, "CDR", [], ["@%%"]); Prim (loc, "SWAP", [], [])] + in + let pair = + [ + Prim + ( loc, + "PAIR", + [], + [Option.value field_annot ~default:"%"; "%@"] ); + ] + in + let init = Seq (loc, access_check @ encoding @ pair) in + ok (Some (parse (len - 3) init)) + | 'D' -> + let access_check = + match field_annot with + | None -> [] + | Some f -> + [ + Prim (loc, "DUP", [], []); + Prim (loc, "CDR", [], [f]); + Prim (loc, "DROP", [], []); + ] + in + let encoding = [Prim (loc, "CAR", [], ["@%%"])] in + let pair = + [ + Prim + ( loc, + "PAIR", + [], + ["%@"; Option.value field_annot ~default:"%"] ); + ] + in + let init = Seq (loc, access_check @ encoding @ pair) in + ok (Some (parse (len - 3) init)) + | _ -> assert false + else ok None + | _ -> ok None + +let expand_map_caddadr original = + match original with + | Prim (loc, str, args, annot) -> + let len = String.length str in + if + len >= 7 + && String.sub str 0 5 = "MAP_C" + && str.[len - 1] = 'R' + && check_letters str 5 (len - 2) (function + | 'A' | 'D' -> true + | _ -> false) + then + (match args with + | [(Seq _ as code)] -> ok code + | [_] -> error (Sequence_expected str) + | [] | _ :: _ :: _ -> error (Invalid_arity (str, List.length args, 1))) + >>? fun code -> + (match extract_field_annots annot with + | ([], annot) -> ok (None, annot) + | ([f], annot) -> ok (Some f, annot) + | (_, _) -> error (Unexpected_macro_annotation str)) + >>? fun (field_annot, annot) -> + let rec parse i acc = + if i = 4 then acc + else + let annot = if i = 5 then annot else [] in + match str.[i] with + | 'A' -> + let acc = + Seq + ( loc, + [ + Prim (loc, "DUP", [], []); + Prim + ( loc, + "DIP", + [Seq (loc, [Prim (loc, "CAR", [], ["@%%"]); acc])], + [] ); + Prim (loc, "CDR", [], ["@%%"]); + Prim (loc, "SWAP", [], []); + Prim (loc, "PAIR", [], "%@" :: "%@" :: annot); + ] ) + in + parse (i - 1) acc + | 'D' -> + let acc = + Seq + ( loc, + [ + Prim (loc, "DUP", [], []); + Prim + ( loc, + "DIP", + [Seq (loc, [Prim (loc, "CDR", [], ["@%%"]); acc])], + [] ); + Prim (loc, "CAR", [], ["@%%"]); + Prim (loc, "PAIR", [], "%@" :: "%@" :: annot); + ] ) + in + parse (i - 1) acc + | _ -> assert false + in + let cr_annot = + match field_annot with + | None -> [] + | Some f -> ["@" ^ String.sub f 1 (String.length f - 1)] + in + match str.[len - 2] with + | 'A' -> + let init = + Seq + ( loc, + [ + Prim (loc, "DUP", [], []); + Prim (loc, "CDR", [], ["@%%"]); + Prim + ( loc, + "DIP", + [Seq (loc, [Prim (loc, "CAR", [], cr_annot); code])], + [] ); + Prim (loc, "SWAP", [], []); + Prim + ( loc, + "PAIR", + [], + [Option.value field_annot ~default:"%"; "%@"] ); + ] ) + in + ok (Some (parse (len - 3) init)) + | 'D' -> + let init = + Seq + ( loc, + [ + Prim (loc, "DUP", [], []); + Prim (loc, "CDR", [], cr_annot); + code; + Prim (loc, "SWAP", [], []); + Prim (loc, "CAR", [], ["@%%"]); + Prim + ( loc, + "PAIR", + [], + ["%@"; Option.value field_annot ~default:"%"] ); + ] ) + in + ok (Some (parse (len - 3) init)) + | _ -> assert false + else ok None + | _ -> ok None + +exception Not_a_roman + +let decimal_of_roman roman = + (* http://rosettacode.org/wiki/Roman_numerals/Decode#OCaml *) + let arabic = ref 0 in + let lastval = ref 0 in + for i = String.length roman - 1 downto 0 do + let n = + match roman.[i] with + | 'M' -> 1000 + | 'D' -> 500 + | 'C' -> 100 + | 'L' -> 50 + | 'X' -> 10 + | 'V' -> 5 + | 'I' -> 1 + | _ -> raise_notrace Not_a_roman + in + if Compare.Int.(n < !lastval) then arabic := !arabic - n + else arabic := !arabic + n ; + lastval := n + done ; + !arabic + +let dip ~loc ?(annot = []) depth instr = + assert (depth >= 0) ; + if depth = 1 then Prim (loc, "DIP", [instr], annot) + else Prim (loc, "DIP", [Int (loc, Z.of_int depth); instr], annot) + +let expand_deprecated_dxiiivp original = + (* transparently expands deprecated macro [DI...IP] to instruction [DIP n] *) + match original with + | Prim (loc, str, args, annot) -> + let len = String.length str in + if len > 3 && str.[0] = 'D' && str.[len - 1] = 'P' then + try + let depth = decimal_of_roman (String.sub str 1 (len - 2)) in + match args with + | [(Seq (_, _) as arg)] -> ok @@ Some (dip ~loc ~annot depth arg) + | [_] -> error (Sequence_expected str) + | [] | _ :: _ :: _ -> error (Invalid_arity (str, List.length args, 1)) + with Not_a_roman -> ok None + else ok None + | _ -> ok None + +exception Not_a_pair + +type pair_item = A | I | P of int * pair_item * pair_item + +let parse_pair_substr str ~len start = + let rec parse ?left i = + if i = len - 1 then raise_notrace Not_a_pair + else if str.[i] = 'P' then + let (next_i, l) = parse ~left:true (i + 1) in + let (next_i, r) = parse ~left:false next_i in + (next_i, P (i, l, r)) + else if str.[i] = 'A' && left = Some true then (i + 1, A) + else if str.[i] = 'I' && left <> Some true then (i + 1, I) + else raise_notrace Not_a_pair + in + let (last, ast) = parse start in + if last <> len - 1 then raise_notrace Not_a_pair else ast + +let unparse_pair_item ast = + let rec unparse ast acc = + match ast with + | P (_, l, r) -> unparse r (unparse l ("P" :: acc)) + | A -> "A" :: acc + | I -> "I" :: acc + in + List.rev ("R" :: unparse ast []) |> String.concat "" + +let pappaiir_annots_pos ast annot = + let rec find_annots_pos p_pos ast annots acc = + match (ast, annots) with + | (_, []) -> (annots, acc) + | (P (i, left, right), _) -> + let (annots, acc) = find_annots_pos i left annots acc in + find_annots_pos i right annots acc + | (A, a :: annots) -> + let pos = + match IntMap.find p_pos acc with + | None -> ([a], []) + | Some (_, cdr) -> ([a], cdr) + in + (annots, IntMap.add p_pos pos acc) + | (I, a :: annots) -> + let pos = + match IntMap.find p_pos acc with + | None -> ([], [a]) + | Some (car, _) -> (car, [a]) + in + (annots, IntMap.add p_pos pos acc) + in + snd (find_annots_pos 0 ast annot IntMap.empty) + +let expand_pappaiir original = + match original with + | Prim (loc, str, args, annot) -> + let len = String.length str in + if + len > 4 + && str.[0] = 'P' + && str.[len - 1] = 'R' + && check_letters str 1 (len - 2) (function + | 'P' | 'A' | 'I' -> true + | _ -> false) + then + try + let (field_annots, annot) = extract_field_annots annot in + let ast = parse_pair_substr str ~len 0 in + let field_annots_pos = pappaiir_annots_pos ast field_annots in + let rec parse p (depth, acc) = + match p with + | P (i, left, right) -> + let annot = + match (i, IntMap.find i field_annots_pos) with + | (0, None) -> annot + | (_, None) -> [] + | (0, Some ([], cdr_annot)) -> "%" :: cdr_annot @ annot + | (_, Some ([], cdr_annot)) -> "%" :: cdr_annot + | (0, Some (car_annot, cdr_annot)) -> + car_annot @ cdr_annot @ annot + | (_, Some (car_annot, cdr_annot)) -> car_annot @ cdr_annot + in + let acc = + if depth = 0 then Prim (loc, "PAIR", [], annot) :: acc + else + dip ~loc depth (Seq (loc, [Prim (loc, "PAIR", [], annot)])) + :: acc + in + (depth, acc) |> parse left |> parse right + | A | I -> (depth + 1, acc) + in + let (_, expanded) = parse ast (0, []) in + (match args with + | [] -> ok () + | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) + >>? fun () -> ok (Some (Seq (loc, expanded))) + with Not_a_pair -> ok None + else ok None + | _ -> ok None + +let expand_unpappaiir original = + match original with + | Prim (loc, str, args, _annot) -> + let len = String.length str in + if + len > 6 + && String.sub str 0 3 = "UNP" + && str.[len - 1] = 'R' + && check_letters str 3 (len - 2) (function + | 'P' | 'A' | 'I' -> true + | _ -> false) + then + try + let unpair = Prim (loc, "UNPAIR", [], []) in + let ast = parse_pair_substr str ~len 2 in + let rec parse p (depth, acc) = + match p with + | P (_i, left, right) -> + let acc = + if depth = 0 then unpair :: acc + else dip ~loc depth (Seq (loc, [unpair])) :: acc + in + (depth, acc) |> parse left |> parse right + | A | I -> (depth + 1, acc) + in + let (_, rev_expanded) = parse ast (0, []) in + let expanded = Seq (loc, List.rev rev_expanded) in + (match args with + | [] -> ok () + | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) + >>? fun () -> ok (Some expanded) + with Not_a_pair -> ok None + else ok None + | _ -> ok None + +exception Not_a_dup + +let expand_deprecated_duuuuup original = + (* transparently expands deprecated macro [DU...UP] to [{ DUP n }] *) + match original with + | Prim (loc, str, args, annot) -> + let len = String.length str in + if + len > 3 + && str.[0] = 'D' + && str.[len - 1] = 'P' + && check_letters str 1 (len - 2) (( = ) 'U') + then + (match args with + | [] -> ok () + | _ :: _ -> error (Invalid_arity (str, List.length args, 0))) + >>? fun () -> + try + let rec parse i = + if i = 1 then + Prim (loc, "DUP", [Int (loc, Z.of_int (len - 2))], annot) + else if str.[i] = 'U' then parse (i - 1) + else raise_notrace Not_a_dup + in + ok (Some (parse (len - 2))) + with Not_a_dup -> ok None + else ok None + | _ -> ok None + +let expand_compare original = + let cmp loc is annot = + let is = + match List.rev_map (fun i -> Prim (loc, i, [], [])) is with + | Prim (loc, i, args, _) :: r -> + List.rev (Prim (loc, i, args, annot) :: r) + | is -> List.rev is + in + ok (Some (Seq (loc, is))) + in + let ifcmp loc is l r annot = + let is = + List.map (fun i -> Prim (loc, i, [], [])) is + @ [Prim (loc, "IF", [l; r], annot)] + in + ok (Some (Seq (loc, is))) + in + match original with + | Prim (loc, "CMPEQ", [], annot) -> cmp loc ["COMPARE"; "EQ"] annot + | Prim (loc, "CMPNEQ", [], annot) -> cmp loc ["COMPARE"; "NEQ"] annot + | Prim (loc, "CMPLT", [], annot) -> cmp loc ["COMPARE"; "LT"] annot + | Prim (loc, "CMPGT", [], annot) -> cmp loc ["COMPARE"; "GT"] annot + | Prim (loc, "CMPLE", [], annot) -> cmp loc ["COMPARE"; "LE"] annot + | Prim (loc, "CMPGE", [], annot) -> cmp loc ["COMPARE"; "GE"] annot + | Prim + ( _, + (("CMPEQ" | "CMPNEQ" | "CMPLT" | "CMPGT" | "CMPLE" | "CMPGE") as str), + args, + [] ) -> + error (Invalid_arity (str, List.length args, 0)) + | Prim (loc, "IFCMPEQ", [l; r], annot) -> + ifcmp loc ["COMPARE"; "EQ"] l r annot + | Prim (loc, "IFCMPNEQ", [l; r], annot) -> + ifcmp loc ["COMPARE"; "NEQ"] l r annot + | Prim (loc, "IFCMPLT", [l; r], annot) -> + ifcmp loc ["COMPARE"; "LT"] l r annot + | Prim (loc, "IFCMPGT", [l; r], annot) -> + ifcmp loc ["COMPARE"; "GT"] l r annot + | Prim (loc, "IFCMPLE", [l; r], annot) -> + ifcmp loc ["COMPARE"; "LE"] l r annot + | Prim (loc, "IFCMPGE", [l; r], annot) -> + ifcmp loc ["COMPARE"; "GE"] l r annot + | Prim (loc, "IFEQ", [l; r], annot) -> ifcmp loc ["EQ"] l r annot + | Prim (loc, "IFNEQ", [l; r], annot) -> ifcmp loc ["NEQ"] l r annot + | Prim (loc, "IFLT", [l; r], annot) -> ifcmp loc ["LT"] l r annot + | Prim (loc, "IFGT", [l; r], annot) -> ifcmp loc ["GT"] l r annot + | Prim (loc, "IFLE", [l; r], annot) -> ifcmp loc ["LE"] l r annot + | Prim (loc, "IFGE", [l; r], annot) -> ifcmp loc ["GE"] l r annot + | Prim + ( _, + (( "IFCMPEQ" | "IFCMPNEQ" | "IFCMPLT" | "IFCMPGT" | "IFCMPLE" + | "IFCMPGE" | "IFEQ" | "IFNEQ" | "IFLT" | "IFGT" | "IFLE" | "IFGE" ) as + str), + args, + [] ) -> + error (Invalid_arity (str, List.length args, 2)) + | Prim + ( _, + (( "IFCMPEQ" | "IFCMPNEQ" | "IFCMPLT" | "IFCMPGT" | "IFCMPLE" + | "IFCMPGE" | "IFEQ" | "IFNEQ" | "IFLT" | "IFGT" | "IFLE" | "IFGE" ) as + str), + [], + _ :: _ ) -> + error (Unexpected_macro_annotation str) + | _ -> ok None + +let expand_asserts original = + let may_rename loc = function + | [] -> Seq (loc, []) + | annot -> Seq (loc, [Prim (loc, "RENAME", [], annot)]) + in + let fail_false ?(annot = []) loc = + [may_rename loc annot; Seq (loc, [Prim (loc, "FAIL", [], [])])] + in + let fail_true ?(annot = []) loc = + [Seq (loc, [Prim (loc, "FAIL", [], [])]); may_rename loc annot] + in + match original with + | Prim (loc, "ASSERT", [], []) -> + ok @@ Some (Seq (loc, [Prim (loc, "IF", fail_false loc, [])])) + | Prim (loc, "ASSERT_NONE", [], []) -> + ok @@ Some (Seq (loc, [Prim (loc, "IF_NONE", fail_false loc, [])])) + | Prim (loc, "ASSERT_SOME", [], annot) -> + ok @@ Some (Seq (loc, [Prim (loc, "IF_NONE", fail_true ~annot loc, [])])) + | Prim (loc, "ASSERT_LEFT", [], annot) -> + ok @@ Some (Seq (loc, [Prim (loc, "IF_LEFT", fail_false ~annot loc, [])])) + | Prim (loc, "ASSERT_RIGHT", [], annot) -> + ok @@ Some (Seq (loc, [Prim (loc, "IF_LEFT", fail_true ~annot loc, [])])) + | Prim + ( _, + (( "ASSERT" | "ASSERT_NONE" | "ASSERT_SOME" | "ASSERT_LEFT" + | "ASSERT_RIGHT" ) as str), + args, + [] ) -> + error (Invalid_arity (str, List.length args, 0)) + | Prim (_, (("ASSERT" | "ASSERT_NONE") as str), [], _ :: _) -> + error (Unexpected_macro_annotation str) + | Prim (loc, s, args, annot) + when String.(length s > 7 && equal (sub s 0 7) "ASSERT_") -> ( + (match args with + | [] -> ok () + | _ :: _ -> error (Invalid_arity (s, List.length args, 0))) + >>? fun () -> + (match annot with + | _ :: _ -> error (Unexpected_macro_annotation s) + | [] -> ok ()) + >>? fun () -> + let remaining = String.(sub s 7 (length s - 7)) in + let remaining_prim = Prim (loc, remaining, [], []) in + match remaining with + | "EQ" | "NEQ" | "LT" | "LE" | "GE" | "GT" -> + ok + @@ Some + (Seq (loc, [remaining_prim; Prim (loc, "IF", fail_false loc, [])])) + | _ -> ( + expand_compare remaining_prim >|? function + | None -> None + | Some seq -> + Some (Seq (loc, [seq; Prim (loc, "IF", fail_false loc, [])])))) + | _ -> ok None + +let expand_if_some = function + | Prim (loc, "IF_SOME", [right; left], annot) -> + ok @@ Some (Seq (loc, [Prim (loc, "IF_NONE", [left; right], annot)])) + | Prim (_, "IF_SOME", args, _annot) -> + error (Invalid_arity ("IF_SOME", List.length args, 2)) + | _ -> ok @@ None + +let expand_if_right = function + | Prim (loc, "IF_RIGHT", [right; left], annot) -> + ok @@ Some (Seq (loc, [Prim (loc, "IF_LEFT", [left; right], annot)])) + | Prim (_, "IF_RIGHT", args, _annot) -> + error (Invalid_arity ("IF_RIGHT", List.length args, 2)) + | _ -> ok @@ None + +let expand_fail = function + | Prim (loc, "FAIL", [], []) -> + ok + @@ Some + (Seq + (loc, [Prim (loc, "UNIT", [], []); Prim (loc, "FAILWITH", [], [])])) + | _ -> ok @@ None + +let expand original = + let rec try_expansions = function + | [] -> ok @@ original + | expander :: expanders -> ( + expander original >>? function + | None -> try_expansions expanders + | Some rewritten -> ok rewritten) + in + try_expansions + [ + expand_carn; + expand_cdrn; + expand_caddadr; + expand_set_caddadr; + expand_map_caddadr; + expand_deprecated_dxiiivp; + (* expand_paaiair ; *) + expand_pappaiir; + (* expand_unpaaiair ; *) + expand_unpappaiir; + expand_deprecated_duuuuup; + expand_compare; + expand_asserts; + expand_if_some; + expand_if_right; + expand_fail; + ] + +let expand_rec expr = + let rec error_map (expanded, errors) f = function + | [] -> (List.rev expanded, List.rev errors) + | hd :: tl -> + let (new_expanded, new_errors) = f hd in + error_map + (new_expanded :: expanded, List.rev_append new_errors errors) + f + tl + in + let error_map = error_map ([], []) in + let rec expand_rec expr = + match expand expr with + | Ok expanded -> ( + match expanded with + | Seq (loc, items) -> + let (items, errors) = error_map expand_rec items in + (Seq (loc, items), errors) + | Prim (loc, name, args, annot) -> + let (args, errors) = error_map expand_rec args in + (Prim (loc, name, args, annot), errors) + | (Int _ | String _ | Bytes _) as atom -> (atom, [])) + | Error errors -> (expr, errors) + in + expand_rec expr + +let unexpand_carn_and_cdrn expanded = + match expanded with + | Seq (loc, [Prim (_, "GET", [Int (locn, n)], annot)]) -> + let (half, parity) = Z.ediv_rem n (Z.of_int 2) in + if Z.(parity = zero) then + Some (Prim (loc, "CDR", [Int (locn, half)], annot)) + else Some (Prim (loc, "CAR", [Int (locn, half)], annot)) + | _ -> None + +let unexpand_caddadr expanded = + let rec rsteps acc = function + | [] -> Some acc + | Prim (_, "CAR", [], []) :: rest -> rsteps ("A" :: acc) rest + | Prim (_, "CDR", [], []) :: rest -> rsteps ("D" :: acc) rest + | _ -> None + in + match expanded with + | Seq (loc, (Prim (_, "CAR", [], []) :: _ as nodes)) + | Seq (loc, (Prim (_, "CDR", [], []) :: _ as nodes)) -> ( + match rsteps [] nodes with + | Some steps -> + let name = String.concat "" ("C" :: List.rev ("R" :: steps)) in + Some (Prim (loc, name, [], [])) + | None -> None) + | _ -> None + +let unexpand_set_caddadr expanded = + let rec steps acc annots = function + | Seq + ( loc, + [ + Prim (_, "CDR", [], _); + Prim (_, "SWAP", [], _); + Prim (_, "PAIR", [], _); + ] ) -> + Some (loc, "A" :: acc, annots) + | Seq + ( loc, + [ + Prim (_, "DUP", [], []); + Prim (_, "CAR", [], [field_annot]); + Prim (_, "DROP", [], []); + Prim (_, "CDR", [], _); + Prim (_, "SWAP", [], []); + Prim (_, "PAIR", [], _); + ] ) -> + Some (loc, "A" :: acc, field_annot :: annots) + | Seq (loc, [Prim (_, "CAR", [], _); Prim (_, "PAIR", [], _)]) -> + Some (loc, "D" :: acc, annots) + | Seq + ( loc, + [ + Prim (_, "DUP", [], []); + Prim (_, "CDR", [], [field_annot]); + Prim (_, "DROP", [], []); + Prim (_, "CAR", [], _); + Prim (_, "PAIR", [], _); + ] ) -> + Some (loc, "D" :: acc, field_annot :: annots) + | Seq + ( _, + [ + Prim (_, "DUP", [], []); + Prim (_, "DIP", [Seq (_, [Prim (_, "CAR", [], _); sub])], []); + Prim (_, "CDR", [], _); + Prim (_, "SWAP", [], []); + Prim (_, "PAIR", [], pair_annots); + ] ) -> + let (_, pair_annots) = extract_field_annots pair_annots in + steps ("A" :: acc) (List.rev_append pair_annots annots) sub + | Seq + ( _, + [ + Prim (_, "DUP", [], []); + Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], _); sub])], []); + Prim (_, "CAR", [], _); + Prim (_, "PAIR", [], pair_annots); + ] ) -> + let (_, pair_annots) = extract_field_annots pair_annots in + steps ("D" :: acc) (List.rev_append pair_annots annots) sub + | _ -> None + in + match steps [] [] expanded with + | Some (loc, steps, annots) -> + let name = String.concat "" ("SET_C" :: List.rev ("R" :: steps)) in + Some (Prim (loc, name, [], List.rev annots)) + | None -> None + +let unexpand_map_caddadr expanded = + let rec steps acc annots = function + | Seq + ( loc, + [ + Prim (_, "DUP", [], []); + Prim (_, "CDR", [], _); + Prim (_, "SWAP", [], []); + Prim (_, "DIP", [Seq (_, [Prim (_, "CAR", [], []); code])], []); + Prim (_, "PAIR", [], _); + ] ) -> + Some (loc, "A" :: acc, annots, code) + | Seq + ( loc, + [ + Prim (_, "DUP", [], []); + Prim (_, "CDR", [], _); + Prim (_, "SWAP", [], []); + Prim + ( _, + "DIP", + [Seq (_, [Prim (_, "CAR", [], [field_annot]); code])], + [] ); + Prim (_, "PAIR", [], _); + ] ) -> + Some (loc, "A" :: acc, field_annot :: annots, code) + | Seq + ( loc, + [ + Prim (_, "DUP", [], []); + Prim (_, "CDR", [], []); + code; + Prim (_, "SWAP", [], []); + Prim (_, "CAR", [], _); + Prim (_, "PAIR", [], _); + ] ) -> + Some (loc, "D" :: acc, annots, code) + | Seq + ( loc, + [ + Prim (_, "DUP", [], []); + Prim (_, "CDR", [], [field_annot]); + code; + Prim (_, "SWAP", [], []); + Prim (_, "CAR", [], _); + Prim (_, "PAIR", [], _); + ] ) -> + Some (loc, "D" :: acc, field_annot :: annots, code) + | Seq + ( _, + [ + Prim (_, "DUP", [], []); + Prim (_, "DIP", [Seq (_, [Prim (_, "CAR", [], _); sub])], []); + Prim (_, "CDR", [], _); + Prim (_, "SWAP", [], []); + Prim (_, "PAIR", [], pair_annots); + ] ) -> + let (_, pair_annots) = extract_field_annots pair_annots in + steps ("A" :: acc) (List.rev_append pair_annots annots) sub + | Seq + ( _, + [ + Prim (_, "DUP", [], []); + Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], []); sub])], []); + Prim (_, "CAR", [], []); + Prim (_, "PAIR", [], pair_annots); + ] ) -> + let (_, pair_annots) = extract_field_annots pair_annots in + steps ("D" :: acc) (List.rev_append pair_annots annots) sub + | _ -> None + in + match steps [] [] expanded with + | Some (loc, steps, annots, code) -> + let name = String.concat "" ("MAP_C" :: List.rev ("R" :: steps)) in + Some (Prim (loc, name, [code], List.rev annots)) + | None -> None + +let unexpand_deprecated_dxiiivp expanded = + (* transparently turn the old expansion of deprecated [DI...IP] to [DIP n] *) + match expanded with + | Seq + ( loc, + [Prim (_, "DIP", [(Seq (_, [Prim (_, "DIP", [_], [])]) as sub)], [])] ) + -> + let rec count acc = function + | Seq (_, [Prim (_, "DIP", [sub], [])]) -> count (acc + 1) sub + | sub -> (acc, sub) + in + let (depth, sub) = count 1 sub in + Some (Prim (loc, "DIP", [Int (loc, Z.of_int depth); sub], [])) + | _ -> None + +let unexpand_dupn expanded = + match expanded with + | Seq + ( loc, + [ + Prim + (_, "DIP", [Int (_, np); Seq (_, [Prim (_, "DUP", [], annot)])], []); + Prim (_, "DIG", [Int (nloc, ng)], []); + ] ) + when Z.equal np (Z.pred ng) -> + Some (Prim (loc, "DUP", [Int (nloc, ng)], annot)) + | _ -> None + +let unexpand_deprecated_duuuuup expanded = + (* transparently turn the old expansion of deprecated [DU...UP] to [DUP n] *) + let rec expand n = function + | Seq (loc, [Prim (nloc, "DUP", [], annot)]) -> + if n = 1 then None + else Some (Prim (loc, "DUP", [Int (nloc, Z.of_int n)], annot)) + | Seq (_, [Prim (_, "DIP", [expanded'], []); Prim (_, "SWAP", [], [])]) -> + expand (n + 1) expanded' + | _ -> None + in + expand 1 expanded + +let rec normalize_pair_item ?(right = false) = function + | P (i, a, b) -> + P (i, normalize_pair_item a, normalize_pair_item ~right:true b) + | A when right -> I + | A -> A + | I -> I + +let unexpand_pappaiir expanded = + match expanded with + | Seq (_, [Prim (_, "PAIR", [], [])]) -> Some expanded + | Seq (loc, (_ :: _ as nodes)) -> ( + let rec exec stack nodes = + match (nodes, stack) with + | ([], _) -> stack + (* support new expansion using [DIP n] *) + | ( Prim (ploc, "DIP", [Int (loc, n); Seq (sloc, sub)], []) :: rest, + a :: rstack ) + when Z.to_int n > 1 -> + exec + (a + :: + exec + rstack + [ + Prim (ploc, "DIP", [Int (loc, Z.pred n); Seq (sloc, sub)], []); + ]) + rest + | (Prim (_, "DIP", [Int (_, n); Seq (_, sub)], []) :: rest, a :: rstack) + when Z.to_int n = 1 -> + exec (a :: exec rstack sub) rest + | (Prim (ploc, "DIP", [Int (loc, n); Seq (sloc, sub)], []) :: rest, []) + when Z.to_int n > 1 -> + exec + (A + :: + exec + [] + [ + Prim (ploc, "DIP", [Int (loc, Z.pred n); Seq (sloc, sub)], []); + ]) + rest + | (Prim (_, "DIP", [Int (_, n); Seq (_, sub)], []) :: rest, []) + when Z.to_int n = 1 -> + exec (A :: exec [] sub) rest + (* support old expansion using [DIP] *) + | (Prim (_, "DIP", [Seq (_, sub)], []) :: rest, a :: rstack) -> + exec (a :: exec rstack sub) rest + | (Prim (_, "DIP", [Seq (_, sub)], []) :: rest, []) -> + exec (A :: exec [] sub) rest + | (Prim (_, "PAIR", [], []) :: rest, a :: b :: rstack) -> + exec (P (0, a, b) :: rstack) rest + | (Prim (_, "PAIR", [], []) :: rest, [a]) -> exec [P (0, a, I)] rest + | (Prim (_, "PAIR", [], []) :: rest, []) -> exec [P (0, A, I)] rest + | _ -> raise_notrace Not_a_pair + in + match exec [] nodes with + | [] -> None + | res :: _ -> + let res = normalize_pair_item res in + let name = unparse_pair_item res in + Some (Prim (loc, name, [], [])) + | exception Not_a_pair -> None) + | _ -> None + +let unexpand_unpappaiir expanded = + match expanded with + | Seq (loc, (_ :: _ as nodes)) -> ( + let rec exec stack nodes = + match (nodes, stack) with + | ([], _) -> stack + (* support new expansion using [DIP n] *) + | ( Prim (ploc, "DIP", [Int (loc, n); Seq (sloc, sub)], []) :: rest, + a :: rstack ) + when Z.to_int n > 1 -> + exec + (a + :: + exec + rstack + [ + Prim (ploc, "DIP", [Int (loc, Z.pred n); Seq (sloc, sub)], []); + ]) + rest + | (Prim (_, "DIP", [Int (_, n); Seq (_, sub)], []) :: rest, a :: rstack) + when Z.to_int n = 1 -> + exec (a :: exec rstack sub) rest + | (Prim (ploc, "DIP", [Int (loc, n); Seq (sloc, sub)], []) :: rest, []) + when Z.to_int n > 1 -> + exec + (A + :: + exec + [] + [ + Prim (ploc, "DIP", [Int (loc, Z.pred n); Seq (sloc, sub)], []); + ]) + rest + | (Prim (_, "DIP", [Int (_, n); Seq (_, sub)], []) :: rest, []) + when Z.to_int n = 1 -> + exec (A :: exec [] sub) rest + (* support old expansion using [DIP] *) + | (Prim (_, "DIP", [Seq (_, sub)], []) :: rest, a :: rstack) -> + exec (a :: exec rstack sub) rest + | (Prim (_, "DIP", [Seq (_, sub)], []) :: rest, []) -> + exec (A :: exec [] sub) rest + | ( Seq + ( _, + [ + Prim (_, "DUP", [], []); + Prim (_, "CAR", [], []); + Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], [])])], []); + ] ) + :: rest, + a :: b :: rstack ) -> + exec (P (0, a, b) :: rstack) rest + | ( Seq + ( _, + [ + Prim (_, "DUP", [], []); + Prim (_, "CAR", [], []); + Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], [])])], []); + ] ) + :: rest, + [a] ) -> + exec [P (0, a, I)] rest + | ( Seq + ( _, + [ + Prim (_, "DUP", [], []); + Prim (_, "CAR", [], []); + Prim (_, "DIP", [Seq (_, [Prim (_, "CDR", [], [])])], []); + ] ) + :: rest, + [] ) -> + exec [P (0, A, I)] rest + | _ -> raise_notrace Not_a_pair + in + match exec [] (List.rev nodes) with + | [] -> None + | res :: _ -> + let res = normalize_pair_item res in + let name = "UN" ^ unparse_pair_item res in + Some (Prim (loc, name, [], [])) + | exception Not_a_pair -> None) + | _ -> None + +let unexpand_compare expanded = + match expanded with + | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "EQ", [], annot)]) -> + Some (Prim (loc, "CMPEQ", [], annot)) + | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "NEQ", [], annot)]) -> + Some (Prim (loc, "CMPNEQ", [], annot)) + | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "LT", [], annot)]) -> + Some (Prim (loc, "CMPLT", [], annot)) + | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "GT", [], annot)]) -> + Some (Prim (loc, "CMPGT", [], annot)) + | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "LE", [], annot)]) -> + Some (Prim (loc, "CMPLE", [], annot)) + | Seq (loc, [Prim (_, "COMPARE", [], _); Prim (_, "GE", [], annot)]) -> + Some (Prim (loc, "CMPGE", [], annot)) + | Seq + ( loc, + [ + Prim (_, "COMPARE", [], _); + Prim (_, "EQ", [], _); + Prim (_, "IF", args, annot); + ] ) -> + Some (Prim (loc, "IFCMPEQ", args, annot)) + | Seq + ( loc, + [ + Prim (_, "COMPARE", [], _); + Prim (_, "NEQ", [], _); + Prim (_, "IF", args, annot); + ] ) -> + Some (Prim (loc, "IFCMPNEQ", args, annot)) + | Seq + ( loc, + [ + Prim (_, "COMPARE", [], _); + Prim (_, "LT", [], _); + Prim (_, "IF", args, annot); + ] ) -> + Some (Prim (loc, "IFCMPLT", args, annot)) + | Seq + ( loc, + [ + Prim (_, "COMPARE", [], _); + Prim (_, "GT", [], _); + Prim (_, "IF", args, annot); + ] ) -> + Some (Prim (loc, "IFCMPGT", args, annot)) + | Seq + ( loc, + [ + Prim (_, "COMPARE", [], _); + Prim (_, "LE", [], _); + Prim (_, "IF", args, annot); + ] ) -> + Some (Prim (loc, "IFCMPLE", args, annot)) + | Seq + ( loc, + [ + Prim (_, "COMPARE", [], _); + Prim (_, "GE", [], _); + Prim (_, "IF", args, annot); + ] ) -> + Some (Prim (loc, "IFCMPGE", args, annot)) + | Seq (loc, [Prim (_, "EQ", [], _); Prim (_, "IF", args, annot)]) -> + Some (Prim (loc, "IFEQ", args, annot)) + | Seq (loc, [Prim (_, "NEQ", [], _); Prim (_, "IF", args, annot)]) -> + Some (Prim (loc, "IFNEQ", args, annot)) + | Seq (loc, [Prim (_, "LT", [], _); Prim (_, "IF", args, annot)]) -> + Some (Prim (loc, "IFLT", args, annot)) + | Seq (loc, [Prim (_, "GT", [], _); Prim (_, "IF", args, annot)]) -> + Some (Prim (loc, "IFGT", args, annot)) + | Seq (loc, [Prim (_, "LE", [], _); Prim (_, "IF", args, annot)]) -> + Some (Prim (loc, "IFLE", args, annot)) + | Seq (loc, [Prim (_, "GE", [], _); Prim (_, "IF", args, annot)]) -> + Some (Prim (loc, "IFGE", args, annot)) + | _ -> None + +let unexpand_asserts expanded = + match expanded with + | Seq + ( loc, + [ + Prim + ( _, + "IF", + [ + Seq (_, []); + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT", [], [])) + | Seq + ( loc, + [ + Seq (_, [Prim (_, "COMPARE", [], []); Prim (_, comparison, [], [])]); + Prim + ( _, + "IF", + [ + Seq (_, []); + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_CMP" ^ comparison, [], [])) + | Seq + ( loc, + [ + Prim (_, comparison, [], []); + Prim + ( _, + "IF", + [ + Seq (_, []); + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_" ^ comparison, [], [])) + | Seq + ( loc, + [ + Prim + ( _, + "IF_NONE", + [ + Seq (_, [Prim (_, "RENAME", [], annot)]); + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_NONE", [], annot)) + | Seq + ( loc, + [ + Prim + ( _, + "IF_NONE", + [ + Seq (_, []); + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_NONE", [], [])) + | Seq + ( loc, + [ + Prim + ( _, + "IF_NONE", + [ + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + Seq (_, []); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_SOME", [], [])) + | Seq + ( loc, + [ + Prim + ( _, + "IF_NONE", + [ + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + Seq (_, [Prim (_, "RENAME", [], annot)]); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_SOME", [], annot)) + | Seq + ( loc, + [ + Prim + ( _, + "IF_LEFT", + [ + Seq (_, []); + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_LEFT", [], [])) + | Seq + ( loc, + [ + Prim + ( _, + "IF_LEFT", + [ + Seq (_, [Prim (_, "RENAME", [], annot)]); + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_LEFT", [], annot)) + | Seq + ( loc, + [ + Prim + ( _, + "IF_LEFT", + [ + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + Seq (_, []); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_RIGHT", [], [])) + | Seq + ( loc, + [ + Prim + ( _, + "IF_LEFT", + [ + Seq + ( _, + [ + Seq + ( _, + [ + Prim (_, "UNIT", [], []); + Prim (_, "FAILWITH", [], []); + ] ); + ] ); + Seq (_, [Prim (_, "RENAME", [], annot)]); + ], + [] ); + ] ) -> + Some (Prim (loc, "ASSERT_RIGHT", [], annot)) + | _ -> None + +let unexpand_if_some = function + | Seq (loc, [Prim (_, "IF_NONE", [left; right], annot)]) -> + Some (Prim (loc, "IF_SOME", [right; left], annot)) + | _ -> None + +let unexpand_if_right = function + | Seq (loc, [Prim (_, "IF_LEFT", [left; right], annot)]) -> + Some (Prim (loc, "IF_RIGHT", [right; left], annot)) + | _ -> None + +let unexpand_fail = function + | Seq (loc, [Prim (_, "UNIT", [], []); Prim (_, "FAILWITH", [], [])]) -> + Some (Prim (loc, "FAIL", [], [])) + | _ -> None + +let unexpand original = + let try_unexpansions unexpanders = + Option.value + ~default:original + (List.fold_left + (fun acc f -> Option.either_f acc (fun () -> f original)) + None + unexpanders) + in + try_unexpansions + [ + unexpand_asserts; + unexpand_carn_and_cdrn; + unexpand_caddadr; + unexpand_set_caddadr; + unexpand_map_caddadr; + unexpand_deprecated_dxiiivp; + unexpand_pappaiir; + unexpand_unpappaiir; + unexpand_deprecated_duuuuup; + unexpand_dupn; + unexpand_compare; + unexpand_if_some; + unexpand_if_right; + unexpand_fail; + ] + +(* + If an argument of Prim is a sequence, we do not want to unexpand + its root in case the source already contains an expanded macro. In + which case unexpansion would remove surrounding braces and generate + ill-formed code. + + For example, DIIP { DIP { DUP }; SWAP } is not unexpandable but + DIIP {{ DIP { DUP }; SWAP }} (note the double braces) is unexpanded + to DIIP { DUUP }. + + unexpand_rec_but_root is the same as unexpand_rec but does not try + to unexpand at root *) + +let rec unexpand_rec expr = unexpand_rec_but_root (unexpand expr) + +and unexpand_rec_but_root = function + | Seq (loc, items) -> Seq (loc, List.map unexpand_rec items) + | Prim (loc, name, args, annot) -> + Prim (loc, name, List.map unexpand_rec_but_root args, annot) + | (Int _ | String _ | Bytes _) as atom -> atom + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"michelson.macros.unexpected_annotation" + ~title:"Unexpected annotation" + ~description: + "A macro had an annotation, but no annotation was permitted on this \ + macro." + ~pp:(fun ppf -> Format.fprintf ppf "Unexpected annotation on macro %s.") + (obj1 (req "macro_name" string)) + (function Unexpected_macro_annotation str -> Some str | _ -> None) + (fun s -> Unexpected_macro_annotation s) ; + register_error_kind + `Permanent + ~id:"michelson.macros.sequence_expected" + ~title:"Macro expects a sequence" + ~description:"An macro expects a sequence, but a sequence was not provided" + ~pp:(fun ppf name -> + Format.fprintf + ppf + "Macro %s expects a sequence, but did not receive one." + name) + (obj1 (req "macro_name" string)) + (function Sequence_expected name -> Some name | _ -> None) + (fun name -> Sequence_expected name) ; + register_error_kind + `Permanent + ~id:"michelson.macros.bas_arity" + ~title:"Wrong number of arguments to macro" + ~description:"A wrong number of arguments was provided to a macro" + ~pp:(fun ppf (name, got, exp) -> + Format.fprintf + ppf + "Macro %s expects %d arguments, was given %d." + name + exp + got) + (obj3 + (req "macro_name" string) + (req "given_number_of_arguments" uint16) + (req "expected_number_of_arguments" uint16)) + (function + | Invalid_arity (name, got, exp) -> Some (name, got, exp) | _ -> None) + (fun (name, got, exp) -> Invalid_arity (name, got, exp)) diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_macros.mli b/src/proto_012_PsiThaCa/lib_client/michelson_v1_macros.mli new file mode 100644 index 000000000000..352a59b00a9e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_macros.mli @@ -0,0 +1,86 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Tezos_micheline + +type 'l node = ('l, string) Micheline.node + +type error += Unexpected_macro_annotation of string + +type error += Sequence_expected of string + +type error += Invalid_arity of string * int * int + +val expand : 'l node -> 'l node tzresult + +val expand_rec : 'l node -> 'l node * error list + +val expand_caddadr : 'l node -> 'l node option tzresult + +val expand_set_caddadr : 'l node -> 'l node option tzresult + +val expand_map_caddadr : 'l node -> 'l node option tzresult + +val expand_deprecated_dxiiivp : 'l node -> 'l node option tzresult + +val expand_pappaiir : 'l node -> 'l node option tzresult + +val expand_deprecated_duuuuup : 'l node -> 'l node option tzresult + +val expand_compare : 'l node -> 'l node option tzresult + +val expand_asserts : 'l node -> 'l node option tzresult + +val expand_unpappaiir : 'l node -> 'l node option tzresult + +val expand_if_some : 'l node -> 'l node option tzresult + +val expand_if_right : 'l node -> 'l node option tzresult + +val unexpand : 'l node -> 'l node + +val unexpand_rec : 'l node -> 'l node + +val unexpand_caddadr : 'l node -> 'l node option + +val unexpand_set_caddadr : 'l node -> 'l node option + +val unexpand_map_caddadr : 'l node -> 'l node option + +val unexpand_deprecated_dxiiivp : 'l node -> 'l node option + +val unexpand_pappaiir : 'l node -> 'l node option + +val unexpand_deprecated_duuuuup : 'l node -> 'l node option + +val unexpand_compare : 'l node -> 'l node option + +val unexpand_asserts : 'l node -> 'l node option + +val unexpand_unpappaiir : 'l node -> 'l node option + +val unexpand_if_some : 'l node -> 'l node option + +val unexpand_if_right : 'l node -> 'l node option diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_parser.ml b/src/proto_012_PsiThaCa/lib_client/michelson_v1_parser.ml new file mode 100644 index 000000000000..2f44d22c1fca --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_parser.ml @@ -0,0 +1,103 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Tezos_micheline +open Micheline_parser +open Micheline + +type parsed = { + source : string; + unexpanded : string canonical; + expanded : Michelson_v1_primitives.prim canonical; + expansion_table : (int * (Micheline_parser.location * int list)) list; + unexpansion_table : (int * int) list; +} + +let compare_parsed = Stdlib.compare + +(* Unexpanded toplevel expression should be a sequence *) +let expand_all source ast errors = + let (unexpanded, loc_table) = extract_locations ast in + let (expanded, expansion_errors) = + Michelson_v1_macros.expand_rec (root unexpanded) + in + let (expanded, unexpansion_table) = extract_locations expanded in + let expansion_table = + let sorted = + List.sort (fun (_, a) (_, b) -> Stdlib.compare a b) unexpansion_table + in + let grouped = + let rec group = function + | (acc, []) -> acc + | ([], (u, e) :: r) -> group ([(e, [u])], r) + | (((pe, us) :: racc as acc), (u, e) :: r) -> + if e = pe then group ((e, u :: us) :: racc, r) + else group ((e, [u]) :: acc, r) + in + group ([], sorted) + in + match + List.map2 + ~when_different_lengths:() + (fun (l, ploc) (l', elocs) -> + assert (l = l') ; + (l, (ploc, elocs))) + (List.sort Stdlib.compare loc_table) + (List.sort Stdlib.compare grouped) + with + | Ok v -> v + | Error () -> invalid_arg "Michelson_v1_parser.expand_all" + in + match Michelson_v1_primitives.prims_of_strings expanded with + | Ok expanded -> + ( {source; unexpanded; expanded; expansion_table; unexpansion_table}, + errors @ expansion_errors ) + | Error errs -> + let errs = Environment.wrap_tztrace errs in + ( { + source; + unexpanded; + expanded = Micheline.strip_locations (Seq ((), [])); + expansion_table; + unexpansion_table; + }, + errors @ expansion_errors @ errs ) + +let parse_toplevel ?check source = + let (tokens, lexing_errors) = Micheline_parser.tokenize source in + let (asts, parsing_errors) = Micheline_parser.parse_toplevel ?check tokens in + let ast = + let start = min_point asts and stop = max_point asts in + Seq ({start; stop}, asts) + in + expand_all source ast (lexing_errors @ parsing_errors) + +let parse_expression ?check source = + let (tokens, lexing_errors) = Micheline_parser.tokenize source in + let (ast, parsing_errors) = Micheline_parser.parse_expression ?check tokens in + expand_all source ast (lexing_errors @ parsing_errors) + +let expand_all ~source ~original = expand_all source original [] diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_parser.mli b/src/proto_012_PsiThaCa/lib_client/michelson_v1_parser.mli new file mode 100644 index 000000000000..6aa29676741a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_parser.mli @@ -0,0 +1,55 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Tezos_micheline + +(** The result of parsing and expanding a Michelson V1 script or data. *) +type parsed = { + source : string; (** The original source code. *) + unexpanded : string Micheline.canonical; + (** Original expression with macros. *) + expanded : Script.expr; (** Expression with macros fully expanded. *) + expansion_table : (int * (Micheline_parser.location * int list)) list; + (** Associates unexpanded nodes to their parsing locations and + the nodes expanded from it in the expanded expression. *) + unexpansion_table : (int * int) list; + (** Associates an expanded node to its source in the unexpanded + expression. *) +} + +val compare_parsed : parsed -> parsed -> int + +val parse_toplevel : + ?check:bool -> string -> parsed Micheline_parser.parsing_result + +val parse_expression : + ?check:bool -> string -> parsed Micheline_parser.parsing_result + +val expand_all : + source:string -> + original:Micheline_parser.node -> + parsed Micheline_parser.parsing_result diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_printer.ml b/src/proto_012_PsiThaCa/lib_client/michelson_v1_printer.ml new file mode 100644 index 000000000000..5eeb4e1fd88c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_printer.ml @@ -0,0 +1,241 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Tezos_micheline +open Micheline +open Micheline_printer + +let anon = {comment = None} + +let print_expr ppf expr = + expr |> Michelson_v1_primitives.strings_of_prims + |> Micheline.inject_locations (fun _ -> anon) + |> print_expr ppf + +let print_expr_unwrapped ppf expr = + expr |> Michelson_v1_primitives.strings_of_prims + |> Micheline.inject_locations (fun _ -> anon) + |> print_expr_unwrapped ppf + +let print_var_annots ppf = List.iter (Format.fprintf ppf "%s ") + +let print_annot_expr_unwrapped ppf (expr, annot) = + Format.fprintf ppf "%a%a" print_var_annots annot print_expr_unwrapped expr + +let print_stack ppf = function + | [] -> Format.fprintf ppf "[]" + | more -> + Format.fprintf + ppf + "@[[ %a ]@]" + (Format.pp_print_list + ~pp_sep:(fun ppf () -> Format.fprintf ppf "@ : ") + print_annot_expr_unwrapped) + more + +let print_execution_trace ppf trace = + Format.pp_print_list + (fun ppf (loc, gas, stack) -> + Format.fprintf + ppf + "- @[location: %d (remaining gas: %a)@,[ @[%a ]@]@]" + loc + Gas.pp + gas + (Format.pp_print_list (fun ppf (e, annot) -> + Format.fprintf + ppf + "@[%a \t%s@]" + print_expr + e + (match annot with None -> "" | Some a -> a))) + stack) + ppf + trace + +let print_big_map_diff ppf lazy_storage_diff = + let diff = + Contract.Legacy_big_map_diff.of_lazy_storage_diff lazy_storage_diff + in + let pp_map ppf id = + if Compare.Z.(id < Z.zero) then + Format.fprintf ppf "temp(%s)" (Z.to_string (Z.neg id)) + else Format.fprintf ppf "map(%s)" (Z.to_string id) + in + Format.fprintf + ppf + "@[%a@]" + (Format.pp_print_list ~pp_sep:Format.pp_print_space (fun ppf -> function + | Contract.Legacy_big_map_diff.Clear id -> + Format.fprintf ppf "Clear %a" pp_map id + | Contract.Legacy_big_map_diff.Alloc {big_map; key_type; value_type} -> + Format.fprintf + ppf + "New %a of type (big_map %a %a)" + pp_map + big_map + print_expr + key_type + print_expr + value_type + | Contract.Legacy_big_map_diff.Copy {src; dst} -> + Format.fprintf ppf "Copy %a to %a" pp_map src pp_map dst + | Contract.Legacy_big_map_diff.Update {big_map; diff_key; diff_value; _} + -> + Format.fprintf + ppf + "%s %a[%a]%a" + (match diff_value with None -> "Unset" | Some _ -> "Set") + pp_map + big_map + print_expr + diff_key + (fun ppf -> function + | None -> () + | Some x -> Format.fprintf ppf " to %a" print_expr x) + diff_value)) + (diff :> Contract.Legacy_big_map_diff.item list) + +let inject_types type_map parsed = + let rec inject_expr = function + | Seq (loc, items) -> + Seq (inject_loc `before loc, List.map inject_expr items) + | Prim (loc, name, items, annot) -> + Prim (inject_loc `after loc, name, List.map inject_expr items, annot) + | Int (loc, value) -> Int (inject_loc `after loc, value) + | String (loc, value) -> String (inject_loc `after loc, value) + | Bytes (loc, value) -> Bytes (inject_loc `after loc, value) + and inject_loc which loc = + let comment = + let ( >?? ) = Option.bind in + List.assoc ~equal:Int.equal loc parsed.Michelson_v1_parser.expansion_table + >?? fun (_, locs) -> + let locs = List.sort compare locs in + List.hd locs >?? fun head_loc -> + List.assoc ~equal:Int.equal head_loc type_map >?? fun (bef, aft) -> + let stack = match which with `before -> bef | `after -> aft in + Some (Format.asprintf "%a" print_stack stack) + in + {comment} + in + inject_expr (root parsed.unexpanded) + +let unparse ?type_map parse expanded = + let source = + match type_map with + | Some type_map -> + let (unexpanded, unexpansion_table) = + expanded |> Michelson_v1_primitives.strings_of_prims |> root + |> Michelson_v1_macros.unexpand_rec |> Micheline.extract_locations + in + let rec inject_expr = function + | Seq (loc, items) -> + Seq (inject_loc `before loc, List.map inject_expr items) + | Prim (loc, name, items, annot) -> + Prim + (inject_loc `after loc, name, List.map inject_expr items, annot) + | Int (loc, value) -> Int (inject_loc `after loc, value) + | String (loc, value) -> String (inject_loc `after loc, value) + | Bytes (loc, value) -> Bytes (inject_loc `after loc, value) + and inject_loc which loc = + let comment = + let ( >?? ) = Option.bind in + List.assoc ~equal:Int.equal loc unexpansion_table >?? fun loc -> + List.assoc ~equal:Int.equal loc type_map >?? fun (bef, aft) -> + let stack = match which with `before -> bef | `after -> aft in + Some (Format.asprintf "%a" print_stack stack) + in + {comment} + in + unexpanded |> root |> inject_expr + |> Format.asprintf "%a" Micheline_printer.print_expr + | None -> + expanded |> Michelson_v1_primitives.strings_of_prims |> root + |> Michelson_v1_macros.unexpand_rec |> Micheline.strip_locations + |> Micheline_printer.printable (fun n -> n) + |> Format.asprintf "%a" Micheline_printer.print_expr + in + match parse source with + | (res, []) -> res + | (_, _ :: _) -> Stdlib.failwith "Michelson_v1_printer.unparse" + +let unparse_toplevel ?type_map = + unparse ?type_map Michelson_v1_parser.parse_toplevel + +let unparse_expression = unparse Michelson_v1_parser.parse_expression + +let unparse_invalid expanded = + let source = + expanded |> root |> Michelson_v1_macros.unexpand_rec + |> Micheline.strip_locations + |> Micheline_printer.printable (fun n -> n) + |> Format.asprintf "%a" Micheline_printer.print_expr_unwrapped + in + fst (Michelson_v1_parser.parse_toplevel source) + +let ocaml_constructor_of_prim prim = + (* Assuming all the prim constructor prefixes match the + [[Michelson_v1_primitives.namespace]]. *) + let prefix = + Michelson_v1_primitives.(namespace prim |> string_of_namespace) + in + Format.asprintf "%s_%s" prefix @@ Michelson_v1_primitives.string_of_prim prim + +let micheline_string_of_expression ~zero_loc expression = + let string_of_list : string list -> string = + fun xs -> String.concat "; " xs |> Format.asprintf "[%s]" + in + let show_loc loc = if zero_loc then 0 else loc in + let rec string_of_node = function + | Int (loc, i) -> + let z = + match Z.to_int i with + | 0 -> "Z.zero" + | 1 -> "Z.one" + | i -> Format.asprintf "Z.of_int %d" i + in + Format.asprintf "Int (%d, %s)" (show_loc loc) z + | String (loc, s) -> Format.asprintf "String (%d, \"%s\")" (show_loc loc) s + | Bytes (loc, b) -> + Format.asprintf + "Bytes (%d, Bytes.of_string \"%s\")" + (show_loc loc) + Bytes.(escaped b |> to_string) + | Prim (loc, prim, nodes, annot) -> + Format.asprintf + "Prim (%d, %s, %s, %s)" + (show_loc loc) + (ocaml_constructor_of_prim prim) + (string_of_list @@ List.map string_of_node nodes) + (string_of_list @@ List.map (Format.asprintf "\"%s\"") annot) + | Seq (loc, nodes) -> + Format.asprintf + "Seq (%d, %s)" + (show_loc loc) + (string_of_list @@ List.map string_of_node nodes) + in + string_of_node (root expression) diff --git a/src/proto_012_PsiThaCa/lib_client/michelson_v1_printer.mli b/src/proto_012_PsiThaCa/lib_client/michelson_v1_printer.mli new file mode 100644 index 000000000000..07cb29ae8556 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/michelson_v1_printer.mli @@ -0,0 +1,65 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Tezos_micheline + +val print_expr : Format.formatter -> Script_repr.expr -> unit + +val print_expr_unwrapped : Format.formatter -> Script_repr.expr -> unit + +val print_execution_trace : + Format.formatter -> + (Script.location * Gas.t * (Script.expr * string option) list) list -> + unit + +val print_big_map_diff : Format.formatter -> Lazy_storage.diffs -> unit + +(** Insert the type map returned by the typechecker as comments in a + printable Micheline AST. *) +val inject_types : + Script_tc_errors.type_map -> + Michelson_v1_parser.parsed -> + Micheline_printer.node + +(** Unexpand the macros and produce the result of parsing an + intermediate pretty printed source. Useful when working with + contracts extracted from the blockchain and not local files. *) +val unparse_toplevel : + ?type_map:Script_tc_errors.type_map -> + Script.expr -> + Michelson_v1_parser.parsed + +val unparse_expression : Script.expr -> Michelson_v1_parser.parsed + +(** Unexpand the macros and produce the result of parsing an + intermediate pretty printed source. Works on generic trees,for + programs that fail to be converted to a specific script version. *) +val unparse_invalid : string Micheline.canonical -> Michelson_v1_parser.parsed + +val ocaml_constructor_of_prim : Michelson_v1_primitives.prim -> string + +val micheline_string_of_expression : zero_loc:bool -> Script.expr -> string diff --git a/src/proto_012_PsiThaCa/lib_client/mockup.ml b/src/proto_012_PsiThaCa/lib_client/mockup.ml new file mode 100644 index 000000000000..f6abdf46bd2c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/mockup.ml @@ -0,0 +1,1158 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol.Alpha_context + +(* ------------------------------------------------------------------------- *) +(* Mockup protocol parameters *) + +(** Protocol constants overriding logic. *) +module Protocol_constants_overrides = struct + (** Equivalent of [Constants.parametric] with additionally [chain_id] and [timestamp] but each field is wrapped in an [option]. + [Some] is an override, [None] means "Use the default value". + *) + type t = { + preserved_cycles : int option; + blocks_per_cycle : int32 option; + blocks_per_commitment : int32 option; + blocks_per_stake_snapshot : int32 option; + blocks_per_voting_period : int32 option; + hard_gas_limit_per_operation : Gas.Arith.integral option; + hard_gas_limit_per_block : Gas.Arith.integral option; + proof_of_work_threshold : int64 option; + tokens_per_roll : Tez.t option; + seed_nonce_revelation_tip : Tez.t option; + origination_size : int option; + baking_reward_fixed_portion : Tez.t option; + baking_reward_bonus_per_slot : Tez.t option; + endorsing_reward_per_slot : Tez.t option; + cost_per_byte : Tez.t option; + hard_storage_limit_per_operation : Z.t option; + quorum_min : int32 option; + quorum_max : int32 option; + min_proposal_quorum : int32 option; + liquidity_baking_subsidy : Tez.t option; + liquidity_baking_sunset_level : int32 option; + liquidity_baking_escape_ema_threshold : int32 option; + max_operations_time_to_live : int option; + minimal_block_delay : Period.t option; + delay_increment_per_round : Period.t option; + minimal_participation_ratio : Constants.ratio option; + consensus_committee_size : int option; + consensus_threshold : int option; + delegate_selection : Constants.delegate_selection option; + max_slashing_period : int option; + frozen_deposits_percentage : int option; + double_baking_punishment : Tez.t option; + ratio_of_frozen_deposits_slashed_per_double_endorsement : + Constants.ratio option; + (* Additional, "bastard" parameters (they are not protocol constants but partially treated the same way). *) + chain_id : Chain_id.t option; + timestamp : Time.Protocol.t option; + } + + (** Shamefully copied from [Constants_repr.parametric_encoding] and adapted ([opt] instead of [req]). *) + let encoding = + let open Data_encoding in + conv + (fun c -> + ( ( c.preserved_cycles, + c.blocks_per_cycle, + c.blocks_per_commitment, + c.blocks_per_stake_snapshot, + c.blocks_per_voting_period, + c.hard_gas_limit_per_operation, + c.hard_gas_limit_per_block, + c.proof_of_work_threshold, + c.tokens_per_roll ), + ( ( c.seed_nonce_revelation_tip, + c.origination_size, + c.baking_reward_fixed_portion, + c.baking_reward_bonus_per_slot, + c.endorsing_reward_per_slot, + c.cost_per_byte, + c.hard_storage_limit_per_operation, + c.quorum_min ), + ( ( c.quorum_max, + c.min_proposal_quorum, + c.liquidity_baking_subsidy, + c.liquidity_baking_sunset_level, + c.liquidity_baking_escape_ema_threshold, + c.max_operations_time_to_live, + c.minimal_block_delay, + c.delay_increment_per_round, + c.consensus_committee_size, + c.consensus_threshold ), + ( c.delegate_selection, + c.minimal_participation_ratio, + c.max_slashing_period, + c.frozen_deposits_percentage, + c.double_baking_punishment, + c.ratio_of_frozen_deposits_slashed_per_double_endorsement, + c.chain_id, + c.timestamp ) ) ) )) + (fun ( ( preserved_cycles, + blocks_per_cycle, + blocks_per_commitment, + blocks_per_stake_snapshot, + blocks_per_voting_period, + hard_gas_limit_per_operation, + hard_gas_limit_per_block, + proof_of_work_threshold, + tokens_per_roll ), + ( ( seed_nonce_revelation_tip, + origination_size, + baking_reward_fixed_portion, + baking_reward_bonus_per_slot, + endorsing_reward_per_slot, + cost_per_byte, + hard_storage_limit_per_operation, + quorum_min ), + ( ( quorum_max, + min_proposal_quorum, + liquidity_baking_subsidy, + liquidity_baking_sunset_level, + liquidity_baking_escape_ema_threshold, + max_operations_time_to_live, + minimal_block_delay, + delay_increment_per_round, + consensus_committee_size, + consensus_threshold ), + ( delegate_selection, + minimal_participation_ratio, + max_slashing_period, + frozen_deposits_percentage, + double_baking_punishment, + ratio_of_frozen_deposits_slashed_per_double_endorsement, + chain_id, + timestamp ) ) ) ) -> + { + preserved_cycles; + blocks_per_cycle; + blocks_per_commitment; + blocks_per_stake_snapshot; + blocks_per_voting_period; + hard_gas_limit_per_operation; + hard_gas_limit_per_block; + proof_of_work_threshold; + tokens_per_roll; + seed_nonce_revelation_tip; + origination_size; + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + cost_per_byte; + hard_storage_limit_per_operation; + quorum_min; + quorum_max; + min_proposal_quorum; + liquidity_baking_subsidy; + liquidity_baking_sunset_level; + liquidity_baking_escape_ema_threshold; + max_operations_time_to_live; + minimal_block_delay; + delay_increment_per_round; + minimal_participation_ratio; + max_slashing_period; + frozen_deposits_percentage; + consensus_committee_size; + consensus_threshold; + delegate_selection; + double_baking_punishment; + ratio_of_frozen_deposits_slashed_per_double_endorsement; + chain_id; + timestamp; + }) + (merge_objs + (obj9 + (opt "preserved_cycles" uint8) + (opt "blocks_per_cycle" int32) + (opt "blocks_per_commitment" int32) + (opt "blocks_per_stake_snapshot" int32) + (opt "blocks_per_voting_period" int32) + (opt "hard_gas_limit_per_operation" Gas.Arith.z_integral_encoding) + (opt "hard_gas_limit_per_block" Gas.Arith.z_integral_encoding) + (opt "proof_of_work_threshold" int64) + (opt "tokens_per_roll" Tez.encoding)) + (merge_objs + (obj8 + (opt "seed_nonce_revelation_tip" Tez.encoding) + (opt "origination_size" int31) + (opt "baking_reward_fixed_portion" Tez.encoding) + (opt "baking_reward_bonus_per_slot" Tez.encoding) + (opt "endorsing_reward_per_slot" Tez.encoding) + (opt "cost_per_byte" Tez.encoding) + (opt "hard_storage_limit_per_operation" z) + (opt "quorum_min" int32)) + (merge_objs + (obj10 + (opt "quorum_max" int32) + (opt "min_proposal_quorum" int32) + (opt "liquidity_baking_subsidy" Tez.encoding) + (opt "liquidity_baking_sunset_level" int32) + (opt "liquidity_baking_escape_ema_threshold" int32) + (opt "max_operations_time_to_live" int16) + (opt "minimal_block_delay" Period.encoding) + (opt "delay_increment_per_round" Period.encoding) + (opt "consensus_committee_size" int31) + (opt "consensus_threshold" int31)) + (obj8 + (opt + "delegate_selection" + Constants.delegate_selection_encoding) + (opt "minimal_participation_ratio" Constants.ratio_encoding) + (opt "max_slashing_period" int31) + (opt "frozen_deposits_percentage" int31) + (opt "double_baking_punishment" Tez.encoding) + (opt + "ratio_of_frozen_deposits_slashed_per_double_endorsement" + Constants.ratio_encoding) + (opt "chain_id" Chain_id.encoding) + (opt "initial_timestamp" Time.Protocol.encoding))))) + + let default_value (cctxt : Tezos_client_base.Client_context.full) : + t tzresult Lwt.t = + let cpctxt = new Protocol_client_context.wrap_full cctxt in + Protocol.Constants_services.all cpctxt (cpctxt#chain, cpctxt#block) + >>=? fun {parametric; _} -> + let to_chain_id_opt = function `Hash c -> Some c | _ -> None in + Shell_services.Blocks.Header.shell_header + cpctxt + ~chain:cpctxt#chain + ~block:cpctxt#block + () + >>=? fun header -> + return + { + preserved_cycles = Some parametric.preserved_cycles; + blocks_per_cycle = Some parametric.blocks_per_cycle; + blocks_per_commitment = Some parametric.blocks_per_commitment; + blocks_per_stake_snapshot = Some parametric.blocks_per_stake_snapshot; + blocks_per_voting_period = Some parametric.blocks_per_voting_period; + hard_gas_limit_per_operation = + Some parametric.hard_gas_limit_per_operation; + hard_gas_limit_per_block = Some parametric.hard_gas_limit_per_block; + proof_of_work_threshold = Some parametric.proof_of_work_threshold; + tokens_per_roll = Some parametric.tokens_per_roll; + seed_nonce_revelation_tip = Some parametric.seed_nonce_revelation_tip; + origination_size = Some parametric.origination_size; + baking_reward_fixed_portion = + Some parametric.baking_reward_fixed_portion; + baking_reward_bonus_per_slot = + Some parametric.baking_reward_bonus_per_slot; + endorsing_reward_per_slot = Some parametric.endorsing_reward_per_slot; + cost_per_byte = Some parametric.cost_per_byte; + hard_storage_limit_per_operation = + Some parametric.hard_storage_limit_per_operation; + quorum_min = Some parametric.quorum_min; + quorum_max = Some parametric.quorum_max; + min_proposal_quorum = Some parametric.min_proposal_quorum; + liquidity_baking_subsidy = Some parametric.liquidity_baking_subsidy; + liquidity_baking_sunset_level = + Some parametric.liquidity_baking_sunset_level; + liquidity_baking_escape_ema_threshold = + Some parametric.liquidity_baking_escape_ema_threshold; + max_operations_time_to_live = + Some parametric.max_operations_time_to_live; + minimal_block_delay = Some parametric.minimal_block_delay; + delay_increment_per_round = Some parametric.delay_increment_per_round; + minimal_participation_ratio = + Some parametric.minimal_participation_ratio; + consensus_committee_size = Some parametric.consensus_committee_size; + (* mockup mode does not support endorsing commands *) + consensus_threshold = Some 0; + delegate_selection = Some Random; + max_slashing_period = Some parametric.max_slashing_period; + frozen_deposits_percentage = Some parametric.frozen_deposits_percentage; + double_baking_punishment = Some parametric.double_baking_punishment; + ratio_of_frozen_deposits_slashed_per_double_endorsement = + Some + parametric.ratio_of_frozen_deposits_slashed_per_double_endorsement; + (* Bastard additional parameters. *) + chain_id = to_chain_id_opt cpctxt#chain; + timestamp = Some header.timestamp; + } + + let no_overrides : t = + { + preserved_cycles = None; + blocks_per_cycle = None; + blocks_per_commitment = None; + blocks_per_stake_snapshot = None; + blocks_per_voting_period = None; + hard_gas_limit_per_operation = None; + hard_gas_limit_per_block = None; + proof_of_work_threshold = None; + tokens_per_roll = None; + seed_nonce_revelation_tip = None; + origination_size = None; + baking_reward_fixed_portion = None; + baking_reward_bonus_per_slot = None; + endorsing_reward_per_slot = None; + cost_per_byte = None; + hard_storage_limit_per_operation = None; + quorum_min = None; + quorum_max = None; + min_proposal_quorum = None; + liquidity_baking_subsidy = None; + liquidity_baking_sunset_level = None; + liquidity_baking_escape_ema_threshold = None; + max_operations_time_to_live = None; + minimal_block_delay = None; + delay_increment_per_round = None; + minimal_participation_ratio = None; + consensus_committee_size = None; + (* Let consensus threshold be overridable for Tenderbake mockup + simulator tests. *) + consensus_threshold = None; + delegate_selection = None; + max_slashing_period = None; + frozen_deposits_percentage = None; + double_baking_punishment = None; + ratio_of_frozen_deposits_slashed_per_double_endorsement = None; + chain_id = None; + timestamp = None; + } + + (** Existential wrapper to support heterogeneous lists/maps. *) + type field = + | O : { + name : string; + override_value : 'a option; + pp : Format.formatter -> 'a -> unit; + } + -> field + + let field_pp ppf (O {name; override_value; pp; _}) = + match override_value with + | None -> () + | Some value -> Format.fprintf ppf "@[%s: %a@]" name pp value + + let apply_overrides (cctxt : Tezos_client_base.Client_context.printer) (o : t) + (c : Constants.parametric) : Constants.parametric tzresult Lwt.t = + let open Format in + let pp_print_int32 ppf i = fprintf ppf "%li" i in + let pp_print_int64 ppf i = fprintf ppf "%Li" i in + let fields : field list = + [ + O + { + name = "preserved_cycles"; + override_value = o.preserved_cycles; + pp = pp_print_int; + }; + O + { + name = "blocks_per_cycle"; + override_value = o.blocks_per_cycle; + pp = pp_print_int32; + }; + O + { + name = "blocks_per_commitment"; + override_value = o.blocks_per_commitment; + pp = pp_print_int32; + }; + O + { + name = "blocks_per_stake_snapshot"; + override_value = o.blocks_per_stake_snapshot; + pp = pp_print_int32; + }; + O + { + name = "blocks_per_voting_period"; + override_value = o.blocks_per_voting_period; + pp = pp_print_int32; + }; + O + { + name = "hard_gas_limit_per_operation"; + override_value = o.hard_gas_limit_per_operation; + pp = Gas.Arith.pp_integral; + }; + O + { + name = "hard_gas_limit_per_block"; + override_value = o.hard_gas_limit_per_block; + pp = Gas.Arith.pp_integral; + }; + O + { + name = "proof_of_work_threshold"; + override_value = o.proof_of_work_threshold; + pp = pp_print_int64; + }; + O + { + name = "tokens_per_roll"; + override_value = o.tokens_per_roll; + pp = Tez.pp; + }; + O + { + name = "seed_nonce_revelation_tip"; + override_value = o.seed_nonce_revelation_tip; + pp = Tez.pp; + }; + O + { + name = "origination_size"; + override_value = o.origination_size; + pp = pp_print_int; + }; + O + { + name = "baking_reward_fixed_portion"; + override_value = o.baking_reward_fixed_portion; + pp = Tez.pp; + }; + O + { + name = "baking_reward_bonus_per_slot"; + override_value = o.baking_reward_bonus_per_slot; + pp = Tez.pp; + }; + O + { + name = "endorsing_reward_per_slot"; + override_value = o.endorsing_reward_per_slot; + pp = Tez.pp; + }; + O + { + name = "cost_per_byte"; + override_value = o.cost_per_byte; + pp = Tez.pp; + }; + O + { + name = "hard_storage_limit_per_operation"; + override_value = o.hard_storage_limit_per_operation; + pp = Z.pp_print; + }; + O + { + name = "quorum_min"; + override_value = o.quorum_min; + pp = pp_print_int32; + }; + O + { + name = "quorum_max"; + override_value = o.quorum_max; + pp = pp_print_int32; + }; + O + { + name = "min_proposal_quorum"; + override_value = o.min_proposal_quorum; + pp = pp_print_int32; + }; + O + { + name = "liquidity_baking_subsidy"; + override_value = o.liquidity_baking_subsidy; + pp = Tez.pp; + }; + O + { + name = "liquidity_baking_sunset_level"; + override_value = o.liquidity_baking_sunset_level; + pp = pp_print_int32; + }; + O + { + name = "liquidity_baking_escape_ema_threshold"; + override_value = o.liquidity_baking_escape_ema_threshold; + pp = pp_print_int32; + }; + O + { + name = "minimal_block_delay"; + override_value = o.minimal_block_delay; + pp = Period.pp; + }; + O + { + name = "delay_increment_per_round"; + override_value = o.delay_increment_per_round; + pp = Period.pp; + }; + O + { + name = "minimal_participation_ratio"; + override_value = o.minimal_participation_ratio; + pp = Constants.pp_ratio; + }; + O + { + name = "consensus_committee_size"; + override_value = o.consensus_committee_size; + pp = pp_print_int; + }; + O + { + name = "consensus_threshold"; + override_value = o.consensus_threshold; + pp = pp_print_int; + }; + O + { + name = "max_slashing_period"; + override_value = o.max_slashing_period; + pp = pp_print_int; + }; + O + { + name = "frozen_deposits_percentage"; + override_value = o.frozen_deposits_percentage; + pp = pp_print_int; + }; + O + { + name = "double_baking_punishment"; + override_value = o.double_baking_punishment; + pp = Tez.pp; + }; + O + { + name = "ratio_of_frozen_deposits_slashed_per_double_endorsement"; + override_value = + o.ratio_of_frozen_deposits_slashed_per_double_endorsement; + pp = Constants.pp_ratio; + }; + O {name = "chain_id"; override_value = o.chain_id; pp = Chain_id.pp}; + O + { + name = "timestamp"; + override_value = o.timestamp; + pp = Time.Protocol.pp_hum; + }; + ] + in + let fields_with_override = + fields + |> List.filter (fun (O {override_value; _}) -> + Option.is_some override_value) + in + (if fields_with_override <> [] then + cctxt#message + "@[mockup client uses protocol overrides:@,%a@]@?" + (pp_print_list field_pp) + fields_with_override + else Lwt.return_unit) + >>= fun () -> + return + ({ + minimal_block_delay = + Option.value ~default:c.minimal_block_delay o.minimal_block_delay; + delay_increment_per_round = + Option.value + ~default:c.delay_increment_per_round + o.delay_increment_per_round; + consensus_committee_size = + Option.value + ~default:c.consensus_committee_size + o.consensus_committee_size; + consensus_threshold = + Option.value ~default:c.consensus_threshold o.consensus_threshold; + delegate_selection = + Option.value ~default:c.delegate_selection o.delegate_selection; + preserved_cycles = + Option.value ~default:c.preserved_cycles o.preserved_cycles; + blocks_per_cycle = + Option.value ~default:c.blocks_per_cycle o.blocks_per_cycle; + blocks_per_commitment = + Option.value ~default:c.blocks_per_commitment o.blocks_per_commitment; + blocks_per_stake_snapshot = + Option.value + ~default:c.blocks_per_stake_snapshot + o.blocks_per_stake_snapshot; + blocks_per_voting_period = + Option.value + ~default:c.blocks_per_voting_period + o.blocks_per_voting_period; + hard_gas_limit_per_operation = + Option.value + ~default:c.hard_gas_limit_per_operation + o.hard_gas_limit_per_operation; + hard_gas_limit_per_block = + Option.value + ~default:c.hard_gas_limit_per_block + o.hard_gas_limit_per_block; + proof_of_work_threshold = + Option.value + ~default:c.proof_of_work_threshold + o.proof_of_work_threshold; + tokens_per_roll = + Option.value ~default:c.tokens_per_roll o.tokens_per_roll; + seed_nonce_revelation_tip = + Option.value + ~default:c.seed_nonce_revelation_tip + o.seed_nonce_revelation_tip; + origination_size = + Option.value ~default:c.origination_size o.origination_size; + baking_reward_fixed_portion = + Option.value + ~default:c.baking_reward_fixed_portion + o.baking_reward_fixed_portion; + baking_reward_bonus_per_slot = + Option.value + ~default:c.baking_reward_bonus_per_slot + o.baking_reward_bonus_per_slot; + endorsing_reward_per_slot = + Option.value + ~default:c.endorsing_reward_per_slot + o.endorsing_reward_per_slot; + cost_per_byte = Option.value ~default:c.cost_per_byte o.cost_per_byte; + hard_storage_limit_per_operation = + Option.value + ~default:c.hard_storage_limit_per_operation + o.hard_storage_limit_per_operation; + quorum_min = Option.value ~default:c.quorum_min o.quorum_min; + quorum_max = Option.value ~default:c.quorum_max o.quorum_max; + min_proposal_quorum = + Option.value ~default:c.min_proposal_quorum o.min_proposal_quorum; + liquidity_baking_subsidy = + Option.value + ~default:c.liquidity_baking_subsidy + o.liquidity_baking_subsidy; + liquidity_baking_sunset_level = + Option.value + ~default:c.liquidity_baking_sunset_level + o.liquidity_baking_sunset_level; + liquidity_baking_escape_ema_threshold = + Option.value + ~default:c.liquidity_baking_escape_ema_threshold + o.liquidity_baking_escape_ema_threshold; + max_operations_time_to_live = + Option.value + ~default:c.max_operations_time_to_live + o.max_operations_time_to_live; + minimal_participation_ratio = + Option.value + ~default:c.minimal_participation_ratio + o.minimal_participation_ratio; + max_slashing_period = + Option.value ~default:c.max_slashing_period o.max_slashing_period; + frozen_deposits_percentage = + Option.value + ~default:c.frozen_deposits_percentage + o.frozen_deposits_percentage; + double_baking_punishment = + Option.value + ~default:c.double_baking_punishment + o.double_baking_punishment; + ratio_of_frozen_deposits_slashed_per_double_endorsement = + Option.value + ~default:c.ratio_of_frozen_deposits_slashed_per_double_endorsement + o.ratio_of_frozen_deposits_slashed_per_double_endorsement + (* Notice that the chain_id and the timestamp are not used here + as they are not protocol constants... *); + } + : Constants.parametric) +end + +module Parsed_account = struct + type t = {name : string; sk_uri : Client_keys.sk_uri; amount : Tez.t} + + let pp ppf account = + let open Format in + let format_amount ppf value = fprintf ppf "amount:%a" Tez.pp value in + fprintf + ppf + "@[name:%s@,sk_uri:%s@,%a@]" + account.name + (Uri.to_string (account.sk_uri :> Uri.t)) + format_amount + account.amount + + let encoding = + let open Data_encoding in + conv + (fun p -> (p.name, p.sk_uri, p.amount)) + (fun (name, sk_uri, amount) -> {name; sk_uri; amount}) + (obj3 + (req "name" string) + (req "sk_uri" Client_keys.Secret_key.encoding) + (req "amount" Tez.encoding)) + + let to_bootstrap_account repr = + Tezos_client_base.Client_keys.neuterize repr.sk_uri >>=? fun pk_uri -> + Tezos_client_base.Client_keys.public_key pk_uri >>=? fun public_key -> + let public_key_hash = Signature.Public_key.hash public_key in + return + Parameters. + {public_key_hash; public_key = Some public_key; amount = repr.amount} + + let default_to_json (cctxt : Tezos_client_base.Client_context.full) : + string tzresult Lwt.t = + let rpc_context = new Protocol_client_context.wrap_full cctxt in + let wallet = (cctxt :> Client_context.wallet) in + let parsed_account_reprs = ref [] in + let errors = ref [] in + Client_keys.list_keys wallet >>=? fun all_keys -> + List.iter_s + (function + | (name, pkh, _pk_opt, Some sk_uri) -> ( + let contract = Contract.implicit_contract pkh in + Client_proto_context.get_balance + rpc_context + ~chain:cctxt#chain + ~block:cctxt#block + contract + >>= fun tz_balance -> + match tz_balance with + | Ok balance -> ( + let tez_repr = Tez.of_mutez @@ Tez.to_mutez balance in + match tez_repr with + | None -> + (* we're reading the wallet, it's content MUST be valid *) + assert false + | Some amount -> + parsed_account_reprs := + {name; sk_uri; amount} :: !parsed_account_reprs ; + Lwt.return_unit) + | Error err -> + errors := err :: !errors ; + Lwt.return_unit) + | _ -> Lwt.return_unit) + all_keys + >>= fun () -> + match !errors with + | [] -> + let json = + Data_encoding.Json.construct + (Data_encoding.list encoding) + !parsed_account_reprs + in + return @@ Data_encoding.Json.to_string json + | errs -> Lwt.return_error @@ List.concat errs +end + +module Bootstrap_account = struct + let encoding : Parameters.bootstrap_account Data_encoding.t = + let open Data_encoding in + let open Parameters in + conv + (fun {public_key_hash; public_key; amount} -> + (public_key_hash, public_key, amount)) + (fun (public_key_hash, public_key, amount) -> + {public_key_hash; public_key; amount}) + (obj3 + (req "public_key_hash" Signature.Public_key_hash.encoding) + (opt "public_key" Signature.Public_key.encoding) + (req "amount" Tez.encoding)) +end + +module Bootstrap_contract = struct + let encoding : Parameters.bootstrap_contract Data_encoding.t = + let open Data_encoding in + let open Parameters in + conv + (fun {delegate; amount; script} -> (delegate, amount, script)) + (fun (delegate, amount, script) -> {delegate; amount; script}) + (obj3 + (opt "delegate" Signature.Public_key_hash.encoding) + (req "amount" Tez.encoding) + (req "script" Script.encoding)) +end + +module Protocol_parameters = struct + type t = { + initial_timestamp : Time.Protocol.t; + bootstrap_accounts : Parameters.bootstrap_account list; + bootstrap_contracts : Parameters.bootstrap_contract list; + constants : Constants.parametric; + } + + let encoding : t Data_encoding.t = + let open Data_encoding in + conv + (fun p -> + ( p.initial_timestamp, + p.bootstrap_accounts, + p.bootstrap_contracts, + p.constants )) + (fun ( initial_timestamp, + bootstrap_accounts, + bootstrap_contracts, + constants ) -> + {initial_timestamp; bootstrap_accounts; bootstrap_contracts; constants}) + (obj4 + (req "initial_timestamp" Time.Protocol.encoding) + (req "bootstrap_accounts" (list Bootstrap_account.encoding)) + (req "bootstrap_contracts" (list Bootstrap_contract.encoding)) + (req "constants" Constants.parametric_encoding)) + + let default_value : t = + let parameters = + Default_parameters.parameters_of_constants + Default_parameters.constants_sandbox + in + { + initial_timestamp = Time.Protocol.epoch; + bootstrap_accounts = parameters.bootstrap_accounts; + bootstrap_contracts = parameters.bootstrap_contracts; + constants = parameters.constants; + } +end + +(* This encoding extends [Protocol_constants_overrides.encoding] to allow + reading json files as produced by lib_parameters. Sadly, this require + copying partially [bootstrap_account_encoding], which is not exposed + in parameters_repr.ml. *) +let lib_parameters_json_encoding = + let bootstrap_account_encoding = + let open Data_encoding in + conv + (function + | {Parameters.public_key; amount; _} -> ( + match public_key with + | None -> assert false + | Some pk -> (pk, amount))) + (fun (pk, amount) -> + { + Parameters.public_key = Some pk; + public_key_hash = Signature.Public_key.hash pk; + amount; + }) + (tup2 Signature.Public_key.encoding Tez.encoding) + in + Data_encoding.( + merge_objs + (obj2 + (opt "bootstrap_accounts" (list bootstrap_account_encoding)) + (opt "commitments" (list Commitment.encoding))) + Protocol_constants_overrides.encoding) + +(* ------------------------------------------------------------------------- *) +(* Blocks *) + +type block = { + hash : Block_hash.t; + header : Block_header.t; + operations : Operation.packed list; + context : Protocol.Environment.Context.t; +} + +module Forge = struct + let default_proof_of_work_nonce = + Bytes.create Constants.proof_of_work_nonce_size + + let make_shell ~level ~predecessor ~timestamp ~fitness ~operations_hash = + Tezos_base.Block_header. + { + level; + predecessor; + timestamp; + fitness; + operations_hash; + proto_level = 0; + validation_passes = 0; + context = Context_hash.zero; + } +end + +(* ------------------------------------------------------------------------- *) +(* RPC context *) +let genesis_block_hash = + Block_hash.of_b58check_exn + "BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU" + +let endorsement_branch_data_encoding = + let open Data_encoding in + conv + (fun (block_hash, block_payload_hash) -> (block_hash, block_payload_hash)) + (fun (block_hash, block_payload_hash) -> (block_hash, block_payload_hash)) + (obj2 + (req "block_hash" Block_hash.encoding) + (req "block_payload_hash" Protocol.Block_payload_hash.encoding)) + +let initial_context chain_id (header : Block_header.shell_header) + ({bootstrap_accounts; bootstrap_contracts; constants; _} : + Protocol_parameters.t) = + let parameters = + Default_parameters.parameters_of_constants + ~bootstrap_accounts + ~bootstrap_contracts + ~commitments:[] + constants + in + let json = Default_parameters.json_of_parameters parameters in + let proto_params = + Data_encoding.Binary.to_bytes_exn Data_encoding.json json + in + Tezos_protocol_environment.Context.( + let empty = Memory_context.empty in + add empty ["version"] (Bytes.of_string "genesis") >>= fun ctxt -> + add ctxt ["protocol_parameters"] proto_params) + >>= fun ctxt -> + Protocol.Main.init ctxt header >|= Protocol.Environment.wrap_tzresult + >>=? fun {context; _} -> + let ({ + timestamp = predecessor_timestamp; + level = predecessor_level; + fitness = predecessor_fitness; + _; + } + : Block_header.shell_header) = + header + in + let timestamp = + Time.System.to_protocol (Tezos_stdlib_unix.Systime_os.now ()) + in + (* + + We need to forge a predecessor hash to pass it to [value_of_key]. + This initial context is used for RPC, hence this piece of + information is not important and does not have to be meaningful + + *) + let predecessor = + Tezos_base.Block_header.hash {shell = header; protocol_data = Bytes.empty} + in + Protocol.Main.value_of_key + ~chain_id + ~predecessor_context:context + ~predecessor_timestamp + ~predecessor_level + ~predecessor_fitness + ~predecessor + ~timestamp + >|= Protocol.Environment.wrap_tzresult + >>=? fun value_of_key -> + (* + In the mockup mode, reactivity is important and there are + no constraints to be consistent with other nodes. For this + reason, the mockup mode loads the cache lazily. + See {!Environment_context.source_of_cache}. + *) + Tezos_protocol_environment.Context.load_cache + predecessor + context + `Lazy + (fun key -> value_of_key key >|= Protocol.Environment.wrap_tzresult) + >>=? fun context -> return context + +let mem_init : + cctxt:Tezos_client_base.Client_context.printer -> + parameters:Protocol_parameters.t -> + constants_overrides_json:Data_encoding.json option -> + bootstrap_accounts_json:Data_encoding.json option -> + Tezos_mockup_registration.Registration.mockup_context tzresult Lwt.t = + fun ~cctxt ~parameters ~constants_overrides_json ~bootstrap_accounts_json -> + let hash = genesis_block_hash in + (* Need to read this Json file before since timestamp modification may be in + there *) + (match constants_overrides_json with + | None -> return Protocol_constants_overrides.no_overrides + | Some json -> ( + match Data_encoding.Json.destruct lib_parameters_json_encoding json with + | (_, x) -> return x + | exception error -> + failwith + "cannot read protocol constants overrides: %a" + (Data_encoding.Json.print_error ?print_unknown:None) + error)) + >>=? fun protocol_overrides -> + let default = parameters.initial_timestamp in + let timestamp = Option.value ~default protocol_overrides.timestamp in + (if not @@ Time.Protocol.equal default timestamp then + cctxt#message "@[initial_timestamp: %a@]" Time.Protocol.pp_hum timestamp + else Lwt.return_unit) + >>= fun () -> + let fitness = + Protocol.Alpha_context.( + Fitness.create_without_locked_round + ~level:Raw_level.root + ~predecessor_round:Round.zero + ~round:Round.zero + |> Fitness.to_raw) + in + let shell_header = + Forge.make_shell + ~level:0l + ~predecessor:hash + ~timestamp + ~fitness + ~operations_hash:Operation_list_list_hash.zero + in + Protocol_constants_overrides.apply_overrides + (cctxt :> Tezos_client_base.Client_context.printer) + protocol_overrides + parameters.constants + >>=? fun protocol_custom -> + (match bootstrap_accounts_json with + | None -> return None + | Some json -> ( + match + Data_encoding.Json.destruct + (Data_encoding.list Parsed_account.encoding) + json + with + | accounts -> + cctxt#message "@[mockup client uses custom bootstrap accounts:@]" + >>= fun () -> + let open Format in + cctxt#message + "@[%a@]" + (pp_print_list + ~pp_sep:(fun ppf () -> fprintf ppf ";@ ") + Parsed_account.pp) + accounts + >>= fun () -> + List.map_es Parsed_account.to_bootstrap_account accounts + >>=? fun bootstrap_accounts -> return (Some bootstrap_accounts) + | exception error -> + failwith + "cannot read definitions of bootstrap accounts: %a" + (Data_encoding.Json.print_error ?print_unknown:None) + error)) + >>=? fun bootstrap_accounts_custom -> + let chain_id = + Tezos_mockup_registration.Mockup_args.Chain_id.choose + ~from_config_file:protocol_overrides.chain_id + in + initial_context + chain_id + shell_header + { + parameters with + bootstrap_accounts = + Option.value + ~default:parameters.bootstrap_accounts + bootstrap_accounts_custom; + constants = protocol_custom; + } + >>=? fun context -> + let chain_id = + Tezos_mockup_registration.Mockup_args.Chain_id.choose + ~from_config_file:protocol_overrides.chain_id + in + let protocol_data = + let payload_hash = + Protocol.Block_payload_hash.hash_bytes + [Block_hash.to_bytes hash; Operation_list_hash.(to_bytes @@ compute [])] + in + let open Protocol.Alpha_context.Block_header in + let (_, _, sk) = Signature.generate_key () in + let proof_of_work_nonce = + Bytes.create Protocol.Alpha_context.Constants.proof_of_work_nonce_size + in + let contents = + { + payload_round = Round.zero; + payload_hash; + seed_nonce_hash = None; + proof_of_work_nonce; + (* following Baking_configuration.escape_votes in lib_delegate *) + liquidity_baking_escape_vote = false; + } + in + let unsigned_bytes = + Data_encoding.Binary.to_bytes_exn + Block_header.unsigned_encoding + (shell_header, contents) + in + let signature = + Signature.sign + ~watermark: + Protocol.Alpha_context.Block_header.( + to_watermark (Block_header chain_id)) + sk + unsigned_bytes + in + Data_encoding.Binary.to_bytes_exn + Protocol.block_header_data_encoding + {contents; signature} + in + return + Tezos_mockup_registration.Registration_intf. + { + chain = chain_id; + rpc_context = + Tezos_protocol_environment. + {block_hash = hash; block_header = shell_header; context}; + protocol_data; + } + +let migrate : + Tezos_mockup_registration.Registration.mockup_context -> + Tezos_mockup_registration.Registration.mockup_context tzresult Lwt.t = + fun {chain; rpc_context; protocol_data} -> + let Tezos_protocol_environment.{block_hash; context; block_header} = + rpc_context + in + Protocol.Main.init context block_header >|= Protocol.Environment.wrap_tzresult + >>=? fun {context; _} -> + let rpc_context = + Tezos_protocol_environment.{block_hash; block_header; context} + in + return + Tezos_mockup_registration.Registration_intf. + {chain; rpc_context; protocol_data} + +(* ------------------------------------------------------------------------- *) +(* Register mockup *) + +module M : + Tezos_mockup_registration.Registration_intf.MOCKUP + with module Protocol = Protocol_client_context.Lifted_protocol = struct + type parameters = Protocol_parameters.t + + type protocol_constants = Protocol_constants_overrides.t + + let parameters_encoding = Protocol_parameters.encoding + + let default_parameters = Protocol_parameters.default_value + + let protocol_constants_encoding = Protocol_constants_overrides.encoding + + let default_protocol_constants = Protocol_constants_overrides.default_value + + let default_bootstrap_accounts = Parsed_account.default_to_json + + let protocol_hash = Protocol.hash + + module Protocol = Protocol_client_context.Lifted_protocol + module Block_services = Protocol_client_context.Alpha_block_services + + let directory = Plugin.RPC.rpc_services + + let init ~cctxt ~parameters ~constants_overrides_json ~bootstrap_accounts_json + = + mem_init + ~cctxt:(cctxt :> Tezos_client_base.Client_context.printer) + ~parameters + ~constants_overrides_json + ~bootstrap_accounts_json + + let migrate = migrate +end + +let () = + Tezos_mockup_registration.Registration.register_mockup_environment (module M) diff --git a/src/proto_012_PsiThaCa/lib_client/operation_result.ml b/src/proto_012_PsiThaCa/lib_client/operation_result.ml new file mode 100644 index 000000000000..af99cf5b7e9b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/operation_result.ml @@ -0,0 +1,666 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Apply_results + +let pp_manager_operation_content (type kind) source internal pp_result ppf + ((operation, result) : kind manager_operation * _) = + Format.fprintf ppf "@[" ; + (match operation with + | Transaction {destination; amount; parameters; entrypoint} -> + Format.fprintf + ppf + "@[%s:@,Amount: %s%a@,From: %a@,To: %a" + (if internal then "Internal transaction" else "Transaction") + Client_proto_args.tez_sym + Tez.pp + amount + Contract.pp + source + Contract.pp + destination ; + (match entrypoint with + | "default" -> () + | _ -> Format.fprintf ppf "@,Entrypoint: %s" entrypoint) ; + (if not (Script_repr.is_unit_parameter parameters) then + let expr = + WithExceptions.Option.to_exn + ~none:(Failure "ill-serialized argument") + (Data_encoding.force_decode parameters) + in + Format.fprintf + ppf + "@,Parameter: @[%a@]" + Michelson_v1_printer.print_expr + expr) ; + pp_result ppf result ; + Format.fprintf ppf "@]" + | Origination {delegate; credit; script = {code; storage}; preorigination = _} + -> + Format.fprintf + ppf + "@[%s:@,From: %a@,Credit: %s%a" + (if internal then "Internal origination" else "Origination") + Contract.pp + source + Client_proto_args.tez_sym + Tez.pp + credit ; + let code = + WithExceptions.Option.to_exn + ~none:(Failure "ill-serialized code") + (Data_encoding.force_decode code) + and storage = + WithExceptions.Option.to_exn + ~none:(Failure "ill-serialized storage") + (Data_encoding.force_decode storage) + in + let {Michelson_v1_parser.source; _} = + Michelson_v1_printer.unparse_toplevel code + in + Format.fprintf + ppf + "@,@[Script:@ @[%a@]@,@[Initial storage:@ %a@]" + Format.pp_print_text + source + Michelson_v1_printer.print_expr + storage ; + (match delegate with + | None -> Format.fprintf ppf "@,No delegate for this contract" + | Some delegate -> + Format.fprintf + ppf + "@,Delegate: %a" + Signature.Public_key_hash.pp + delegate) ; + pp_result ppf result ; + Format.fprintf ppf "@]" + | Reveal key -> + Format.fprintf + ppf + "@[%s of manager public key:@,Contract: %a@,Key: %a%a@]" + (if internal then "Internal revelation" else "Revelation") + Contract.pp + source + Signature.Public_key.pp + key + pp_result + result + | Delegation None -> + Format.fprintf + ppf + "@[%s:@,Contract: %a@,To: nobody%a@]" + (if internal then "Internal Delegation" else "Delegation") + Contract.pp + source + pp_result + result + | Delegation (Some delegate) -> + Format.fprintf + ppf + "@[%s:@,Contract: %a@,To: %a%a@]" + (if internal then "Internal Delegation" else "Delegation") + Contract.pp + source + Signature.Public_key_hash.pp + delegate + pp_result + result + | Register_global_constant {value = lazy_value} -> + let value = + WithExceptions.Option.to_exn + ~none:(Failure "ill-serialized value") + (Data_encoding.force_decode lazy_value) + in + Format.fprintf + ppf + "Register Global:@,@[ Value: %a%a@]" + Michelson_v1_printer.print_expr + value + pp_result + result + | Set_deposits_limit None -> + Format.fprintf + ppf + "@[%s:@,Delegate: %a@,Unlimited deposits%a@]" + (if internal then "Internal set deposits limit" + else "Set deposits limit") + Contract.pp + source + pp_result + result + | Set_deposits_limit (Some limit) -> + Format.fprintf + ppf + "@[%s:@,Delegate: %a@,Limit: %a%a@]" + (if internal then "Internal set deposits limit" + else "Set deposits limit") + Contract.pp + source + Tez.pp + limit + pp_result + result) ; + Format.fprintf ppf "@]" + +let pp_balance_updates ppf = function + | [] -> () + | balance_updates -> + let open Receipt in + (* For dry runs, the baker's key is zero + (tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU). Instead of printing this + key hash, we want to make the result more informative. *) + let pp_baker ppf baker = + if Signature.Public_key_hash.equal baker Signature.Public_key_hash.zero + then Format.fprintf ppf "the baker who will include this operation" + else Signature.Public_key_hash.pp ppf baker + in + let balance_updates = + List.map + (fun (balance, update, origin) -> + let balance = + match balance with + | Contract c -> Format.asprintf "%a" Contract.pp c + | Legacy_rewards (pkh, l) -> + Format.asprintf + "legacy_rewards(%a,%a)" + pp_baker + pkh + Cycle.pp + l + | Block_fees -> "payload fees(the block proposer)" + | Legacy_deposits (pkh, l) -> + Format.asprintf + "legacy_deposits(%a,%a)" + pp_baker + pkh + Cycle.pp + l + | Deposits pkh -> Format.asprintf "deposits(%a)" pp_baker pkh + | Nonce_revelation_rewards -> "nonce revelation rewards" + | Double_signing_evidence_rewards -> + "double signing evidence rewards" + | Endorsing_rewards -> "endorsing rewards" + | Baking_rewards -> "baking rewards" + | Baking_bonuses -> "baking bonuses" + | Legacy_fees (pkh, c) -> + Format.asprintf "legacy_fees(%a,%a)" pp_baker pkh Cycle.pp c + | Storage_fees -> "storage fees" + | Double_signing_punishments -> "double signing punishments" + | Lost_endorsing_rewards (pkh, p, r) -> + let reason = + match (p, r) with + | (false, false) -> "" + | (false, true) -> ",revelation" + | (true, false) -> ",participation" + | (true, true) -> ",participation,revelation" + in + Format.asprintf + "lost endorsing rewards(%a%s)" + pp_baker + pkh + reason + | Liquidity_baking_subsidies -> "liquidity baking subsidies" + | Burned -> "burned" + | Commitments bpkh -> + Format.asprintf + "commitment(%a)" + Blinded_public_key_hash.pp + bpkh + | Bootstrap -> "bootstrap" + | Invoice -> "invoices" + | Initial_commitments -> "initial commitments" + | Minted -> "minted" + in + let balance = + match origin with + | Block_application -> balance + | Protocol_migration -> Format.asprintf "migration %s" balance + | Subsidy -> Format.asprintf "subsidy %s" balance + | Simulation -> Format.asprintf "simulation %s" balance + in + (balance, update)) + balance_updates + in + let column_size = + List.fold_left + (fun acc (balance, _) -> Compare.Int.max acc (String.length balance)) + 0 + balance_updates + in + let pp_update ppf = function + | Credited amount -> + Format.fprintf ppf "+%s%a" Client_proto_args.tez_sym Tez.pp amount + | Debited amount -> + Format.fprintf ppf "-%s%a" Client_proto_args.tez_sym Tez.pp amount + in + let pp_one ppf (balance, update) = + let to_fill = column_size + 3 - String.length balance in + let filler = String.make to_fill '.' in + Format.fprintf ppf "%s %s %a" balance filler pp_update update + in + Format.fprintf + ppf + "@[%a@]" + (Format.pp_print_list pp_one) + balance_updates + +let pp_manager_operation_contents_and_result ppf + ( Manager_operation + {source; fee; operation; counter; gas_limit; storage_limit}, + Manager_operation_result + {balance_updates; operation_result; internal_operation_results} ) = + let pp_lazy_storage_diff = function + | None -> () + | Some lazy_storage_diff -> ( + let big_map_diff = + Contract.Legacy_big_map_diff.of_lazy_storage_diff lazy_storage_diff + in + match (big_map_diff :> Contract.Legacy_big_map_diff.item list) with + | [] -> () + | _ :: _ -> + (* TODO: print all lazy storage diff *) + Format.fprintf + ppf + "@,@[Updated big_maps:@ %a@]" + Michelson_v1_printer.print_big_map_diff + lazy_storage_diff) + in + let pp_transaction_result + (Transaction_result + { + balance_updates; + consumed_gas; + storage; + originated_contracts; + storage_size; + paid_storage_size_diff; + lazy_storage_diff; + allocated_destination_contract = _; + }) = + (match originated_contracts with + | [] -> () + | contracts -> + Format.fprintf + ppf + "@,@[Originated contracts:@,%a@]" + (Format.pp_print_list Contract.pp) + contracts) ; + (match storage with + | None -> () + | Some expr -> + Format.fprintf + ppf + "@,@[Updated storage:@ %a@]" + Michelson_v1_printer.print_expr + expr) ; + pp_lazy_storage_diff lazy_storage_diff ; + if storage_size <> Z.zero then + Format.fprintf ppf "@,Storage size: %s bytes" (Z.to_string storage_size) ; + if paid_storage_size_diff <> Z.zero then + Format.fprintf + ppf + "@,Paid storage size diff: %s bytes" + (Z.to_string paid_storage_size_diff) ; + Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas ; + match balance_updates with + | [] -> () + | balance_updates -> + Format.fprintf + ppf + "@,Balance updates:@, %a" + pp_balance_updates + balance_updates + in + let pp_origination_result + (Origination_result + { + lazy_storage_diff; + balance_updates; + consumed_gas; + originated_contracts; + storage_size; + paid_storage_size_diff; + }) = + (match originated_contracts with + | [] -> () + | contracts -> + Format.fprintf + ppf + "@,@[Originated contracts:@,%a@]" + (Format.pp_print_list Contract.pp) + contracts) ; + if storage_size <> Z.zero then + Format.fprintf ppf "@,Storage size: %s bytes" (Z.to_string storage_size) ; + pp_lazy_storage_diff lazy_storage_diff ; + if paid_storage_size_diff <> Z.zero then + Format.fprintf + ppf + "@,Paid storage size diff: %s bytes" + (Z.to_string paid_storage_size_diff) ; + Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas ; + match balance_updates with + | [] -> () + | balance_updates -> + Format.fprintf + ppf + "@,Balance updates:@, %a" + pp_balance_updates + balance_updates + in + let pp_register_global_constant_result + (Register_global_constant_result + {balance_updates; consumed_gas; size_of_constant; global_address}) = + (match balance_updates with + | [] -> + (* Not possible - register global constant operation always returns + balance updates. *) + assert false + | balance_updates -> + Format.fprintf + ppf + "@,Balance updates:@, %a" + pp_balance_updates + balance_updates) ; + Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas ; + Format.fprintf ppf "@,Storage size: %s bytes" (Z.to_string size_of_constant) ; + Format.fprintf ppf "@,Global address: %a" Script_expr_hash.pp global_address + in + let pp_result (type kind) ppf (result : kind manager_operation_result) = + Format.fprintf ppf "@," ; + match result with + | Skipped _ -> Format.fprintf ppf "This operation was skipped" + | Failed (_, _errs) -> Format.fprintf ppf "This operation FAILED." + | Applied (Reveal_result {consumed_gas}) -> + Format.fprintf ppf "This revelation was successfully applied" ; + Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas + | Backtracked (Reveal_result _, _) -> + Format.fprintf + ppf + "@[This revelation was BACKTRACKED, its expected effects were \ + NOT applied.@]" + | Applied (Delegation_result {consumed_gas}) -> + Format.fprintf ppf "This delegation was successfully applied" ; + Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas + | Backtracked (Delegation_result _, _) -> + Format.fprintf + ppf + "@[This delegation was BACKTRACKED, its expected effects were \ + NOT applied.@]" + | Applied (Set_deposits_limit_result {consumed_gas}) -> + Format.fprintf ppf "The deposits limit was successfully set" ; + Format.fprintf ppf "@,Consumed gas: %a" Gas.Arith.pp consumed_gas + | Backtracked (Set_deposits_limit_result _, _) -> + Format.fprintf + ppf + "@[This deposits limit modification was BACKTRACKED, its \ + expected effects were NOT applied.@]" + | Applied (Transaction_result _ as tx) -> + Format.fprintf ppf "This transaction was successfully applied" ; + pp_transaction_result tx + | Backtracked ((Transaction_result _ as tx), _errs) -> + Format.fprintf + ppf + "@[This transaction was BACKTRACKED, its expected effects (as \ + follow) were NOT applied.@]" ; + pp_transaction_result tx + | Applied (Origination_result _ as op) -> + Format.fprintf ppf "This origination was successfully applied" ; + pp_origination_result op + | Backtracked ((Origination_result _ as op), _errs) -> + Format.fprintf + ppf + "@[This origination was BACKTRACKED, its expected effects (as \ + follow) were NOT applied.@]" ; + pp_origination_result op + | Applied (Register_global_constant_result _ as op) -> + Format.fprintf + ppf + "This global constant registration was successfully applied" ; + pp_register_global_constant_result op + | Backtracked ((Register_global_constant_result _ as op), _errs) -> + Format.fprintf + ppf + "@[This registration of a global constant was BACKTRACKED, its \ + expected effects (as follow) were NOT applied.@]" ; + pp_register_global_constant_result op + in + Format.fprintf + ppf + "@[@[Manager signed operations:@,\ + From: %a@,\ + Fee to the baker: %s%a@,\ + Expected counter: %s@,\ + Gas limit: %a@,\ + Storage limit: %s bytes" + Signature.Public_key_hash.pp + source + Client_proto_args.tez_sym + Tez.pp + fee + (Z.to_string counter) + Gas.Arith.pp_integral + gas_limit + (Z.to_string storage_limit) ; + (match balance_updates with + | [] -> () + | balance_updates -> + Format.fprintf + ppf + "@,Balance updates:@, %a" + pp_balance_updates + balance_updates) ; + Format.fprintf + ppf + "@,%a" + (pp_manager_operation_content + (Contract.implicit_contract source) + false + pp_result) + (operation, operation_result) ; + (match internal_operation_results with + | [] -> () + | _ :: _ -> + Format.fprintf + ppf + "@,@[Internal operations:@ %a@]" + (Format.pp_print_list (fun ppf (Internal_operation_result (op, res)) -> + pp_manager_operation_content + op.source + false + pp_result + ppf + (op.operation, res))) + internal_operation_results) ; + Format.fprintf ppf "@]" + +let rec pp_contents_and_result_list : + type kind. Format.formatter -> kind contents_and_result_list -> unit = + fun ppf -> function + | Single_and_result + (Seed_nonce_revelation {level; nonce}, Seed_nonce_revelation_result bus) + -> + Format.fprintf + ppf + "@[Seed nonce revelation:@,\ + Level: %a@,\ + Nonce (hash): %a@,\ + Balance updates:@,\ + %a@]" + Raw_level.pp + level + Nonce_hash.pp + (Nonce.hash nonce) + pp_balance_updates + bus + | Single_and_result + (Double_baking_evidence {bh1; bh2}, Double_baking_evidence_result bus) -> + Format.fprintf + ppf + "@[Double baking evidence:@,\ + Exhibit A: %a@,\ + Exhibit B: %a@,\ + Balance updates:@,\ + %a@]" + Block_hash.pp + (Block_header.hash bh1) + Block_hash.pp + (Block_header.hash bh2) + pp_balance_updates + bus + | Single_and_result + ( Preendorsement {level; _}, + Preendorsement_result {balance_updates; delegate; preendorsement_power} + ) -> + Format.fprintf + ppf + "@[Preendorsement:@,\ + Level: %a@,\ + Balance updates:%a@,\ + Delegate: %a@,\ + Preendorsement Power: %d@]" + Raw_level.pp + level + pp_balance_updates + balance_updates + Signature.Public_key_hash.pp + delegate + preendorsement_power + | Single_and_result + ( Endorsement {level; _}, + Endorsement_result {balance_updates; delegate; endorsement_power} ) -> + Format.fprintf + ppf + "@[Endorsement:@,\ + Level: %a@,\ + Balance updates:%a@,\ + Delegate: %a@,\ + Endorsement power: %d@]" + Raw_level.pp + level + pp_balance_updates + balance_updates + Signature.Public_key_hash.pp + delegate + endorsement_power + | Single_and_result + ( Double_endorsement_evidence {op1; op2}, + Double_endorsement_evidence_result bus ) -> + Format.fprintf + ppf + "@[Double endorsement evidence:@,\ + Exhibit A: %a@,\ + Exhibit B: %a@,\ + Balance updates:@,\ + \ %a@]" + Operation_hash.pp + (Operation.hash op1) + Operation_hash.pp + (Operation.hash op2) + pp_balance_updates + bus + | Single_and_result + ( Double_preendorsement_evidence {op1; op2}, + Double_preendorsement_evidence_result bus ) -> + Format.fprintf + ppf + "@[Double preendorsement evidence:@,\ + Exhibit A: %a@,\ + Exhibit B: %a@,\ + Balance updates:@,\ + \ %a@]" + Operation_hash.pp + (Operation.hash op1) + Operation_hash.pp + (Operation.hash op2) + pp_balance_updates + bus + | Single_and_result (Activate_account {id; _}, Activate_account_result bus) -> + Format.fprintf + ppf + "@[Genesis account activation:@,\ + Account: %a@,\ + Balance updates:@,\ + \ %a@]" + Ed25519.Public_key_hash.pp + id + pp_balance_updates + bus + | Single_and_result (Proposals {source; period; proposals}, Proposals_result) + -> + Format.fprintf + ppf + "@[Proposals:@,From: %a@,Period: %ld@,Protocols:@, @[%a@]@]" + Signature.Public_key_hash.pp + source + period + (Format.pp_print_list Protocol_hash.pp) + proposals + | Single_and_result (Ballot {source; period; proposal; ballot}, Ballot_result) + -> + Format.fprintf + ppf + "@[Ballot:@,From: %a@,Period: %ld@,Protocol: %a@,Vote: %a@]" + Signature.Public_key_hash.pp + source + period + Protocol_hash.pp + proposal + Data_encoding.Json.pp + (Data_encoding.Json.construct Vote.ballot_encoding ballot) + | Single_and_result (Failing_noop _arbitrary, _) -> + (* the Failing_noop operation always fails and can't have result *) + . + | Single_and_result + ((Manager_operation _ as op), (Manager_operation_result _ as res)) -> + Format.fprintf ppf "%a" pp_manager_operation_contents_and_result (op, res) + | Cons_and_result + ((Manager_operation _ as op), (Manager_operation_result _ as res), rest) + -> + Format.fprintf + ppf + "%a@\n%a" + pp_manager_operation_contents_and_result + (op, res) + pp_contents_and_result_list + rest + +let pp_operation_result ppf + ((op, res) : 'kind contents_list * 'kind contents_result_list) = + Format.fprintf ppf "@[" ; + let contents_and_result_list = Apply_results.pack_contents_list op res in + pp_contents_and_result_list ppf contents_and_result_list ; + Format.fprintf ppf "@]@." + +let pp_internal_operation ppf + (Internal_operation {source; operation; nonce = _}) = + pp_manager_operation_content + source + true + (fun _ppf () -> ()) + ppf + (operation, ()) diff --git a/src/proto_012_PsiThaCa/lib_client/operation_result.mli b/src/proto_012_PsiThaCa/lib_client/operation_result.mli new file mode 100644 index 000000000000..cc03abfcd36b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/operation_result.mli @@ -0,0 +1,35 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +val pp_internal_operation : + Format.formatter -> packed_internal_operation -> unit + +val pp_operation_result : + Format.formatter -> + 'kind contents_list * 'kind Apply_results.contents_result_list -> + unit diff --git a/src/proto_012_PsiThaCa/lib_client/protocol_client_context.ml b/src/proto_012_PsiThaCa/lib_client/protocol_client_context.ml new file mode 100644 index 000000000000..1d2fc145eeb6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/protocol_client_context.ml @@ -0,0 +1,272 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Lifted_protocol = struct + include Protocol.Environment.Lift (Protocol) + + let hash = Protocol.hash +end + +module Alpha_block_services = + Block_services.Make (Lifted_protocol) (Lifted_protocol) + +(** Client RPC context *) +class type rpc_context = + object + inherit RPC_context.json + + inherit + [Shell_services.chain * Shell_services.block] Protocol.Environment + .RPC_context + .simple + end + +(** The class [wrap_rpc_context] is a wrapper class used by the proxy + mode clients. From a general-purpose RPC_context.json [t], the + class is augmented with shell services to provide RPC calls that + are protocol-dependent. *) +class wrap_rpc_context (t : RPC_context.json) : rpc_context = + object + method base : Uri.t = t#base + + method generic_json_call = t#generic_json_call + + method generic_media_type_call = t#generic_media_type_call + + method call_service + : 'm 'p 'q 'i 'o. + (([< Resto.meth] as 'm), unit, 'p, 'q, 'i, 'o) RPC_service.t -> + 'p -> + 'q -> + 'i -> + 'o tzresult Lwt.t = + t#call_service + + method call_streamed_service + : 'm 'p 'q 'i 'o. + (([< Resto.meth] as 'm), unit, 'p, 'q, 'i, 'o) RPC_service.t -> + on_chunk:('o -> unit) -> + on_close:(unit -> unit) -> + 'p -> + 'q -> + 'i -> + (unit -> unit) tzresult Lwt.t = + t#call_streamed_service + + (** Abstracts variables and in protocol RPCs + prefixed by "/chains//blocks//...". *) + inherit + [Shell_services.chain, Shell_services.block] Protocol.Environment + .proto_rpc_context + (t :> RPC_context.t) + Shell_services.Blocks.path + end + +(** The class type [full] allows to create contexts that are + explicitly used by low-level shell functions, while containing + various information (I/O services, RPCs...). Then, depending on the + usage, the type may be coerced into one of its following ascendants + to serve for explicit operations on blocks, chain or daemon for + instance. *) +class type full = + object + (** The class Client_context.full provides I/O services for the + client, the wallet, etc. *) + inherit Client_context.full + + (** Base interface provided to call RPCs, i.e., communication + with the node. A client context is defined by mapping all + RPCs protocol-generic to a specific procotol. *) + inherit + [Shell_services.chain * Shell_services.block] Protocol.Environment + .RPC_context + .simple + + (** Protocol RPCs exposed through the environment (using + an additional chainpath). *) + inherit + [Shell_services.chain, Shell_services.block] Protocol.Environment + .proto_rpc_context + end + +(** From a [Client_context.full], the class allows to call RPCs from + the node and those defined by the protocol. *) +class wrap_full (t : Client_context.full) : full = + object + inherit Client_context.proxy_context t + + inherit + [Shell_services.chain, Shell_services.block] Protocol.Environment + .proto_rpc_context + (t :> RPC_context.t) + Shell_services.Blocks.path + end + +let register_error_kind category ~id ~title ~description ?pp encoding from_error + to_error = + let id = "client." ^ Protocol.name ^ "." ^ id in + register_error_kind + category + ~id + ~title + ~description + ?pp + encoding + from_error + to_error + +(** Initialization calls that run on start-up. Register the various + protocol encodings. *) +let () = + let open Data_encoding.Registration in + register Protocol.Alpha_context.Lazy_storage.encoding ; + register ~pp:Protocol.Alpha_context.Fitness.pp + @@ Protocol.Alpha_context.Fitness.encoding ; + (* These encodings are missing a def field which we add before registering them. + These defs should be moved inside their encodings in the protocol code. *) + let def id ids ?title ?description encoding = + Data_encoding.def + (String.concat "." (Protocol.name :: id :: ids)) + ?title + ?description + encoding + in + register @@ def "parameters" [] Protocol.Parameters_repr.encoding ; + register ~pp:Protocol.Alpha_context.Tez.pp + @@ def "tez" [] Protocol.Alpha_context.Tez.encoding ; + register ~pp:Protocol.Alpha_context.Timestamp.pp + @@ def "timestamp" [] Protocol.Alpha_context.Timestamp.encoding ; + register ~pp:Protocol.Alpha_context.Raw_level.pp + @@ def "raw_level" [] Protocol.Alpha_context.Raw_level.encoding ; + register @@ def "vote" ["ballot"] Protocol.Alpha_context.Vote.ballot_encoding ; + register + @@ def "vote" ["ballots"] Protocol.Alpha_context.Vote.ballots_encoding ; + register + @@ def "vote" ["listings"] Protocol.Alpha_context.Vote.listings_encoding ; + register @@ def "seed" [] Protocol.Alpha_context.Seed.seed_encoding ; + register ~pp:Protocol.Alpha_context.Gas.pp + @@ def "gas" [] Protocol.Alpha_context.Gas.encoding ; + register ~pp:Protocol.Alpha_context.Gas.pp_cost + @@ def "gas" ["cost"] Protocol.Alpha_context.Gas.cost_encoding ; + register @@ def "script" [] Protocol.Alpha_context.Script.encoding ; + register @@ def "script" ["expr"] Protocol.Alpha_context.Script.expr_encoding ; + register @@ def "script" ["prim"] Protocol.Alpha_context.Script.prim_encoding ; + register + @@ def "script" ["lazy_expr"] Protocol.Alpha_context.Script.lazy_expr_encoding ; + register + @@ def "script" ["loc"] Protocol.Alpha_context.Script.location_encoding ; + register ~pp:Protocol.Alpha_context.Contract.pp + @@ def "contract" [] Protocol.Alpha_context.Contract.encoding ; + register + @@ def + "contract" + ["big_map_diff"] + Protocol.Alpha_context.Lazy_storage.legacy_big_map_diff_encoding ; + register + @@ def + "receipt" + ["balance_updates"] + Protocol.Alpha_context.Receipt.balance_updates_encoding ; + register ~pp:Protocol.Alpha_context.Level.pp_full + @@ def "level" [] Protocol.Alpha_context.Level.encoding ; + register @@ def "operation" [] Protocol.Alpha_context.Operation.encoding ; + register + @@ def + "operation" + ["contents"] + Protocol.Alpha_context.Operation.contents_encoding ; + register + @@ def + "operation" + ["contents_list"] + Protocol.Alpha_context.Operation.contents_list_encoding ; + register + @@ def + "operation" + ["protocol_data"] + Protocol.Alpha_context.Operation.protocol_data_encoding ; + register + @@ def "operation" ["raw"] Protocol.Alpha_context.Operation.raw_encoding ; + register + @@ def + "operation" + ["internal"] + Protocol.Alpha_context.Operation.internal_operation_encoding ; + register + @@ def + "operation" + ["unsigned"] + Protocol.Alpha_context.Operation.unsigned_encoding ; + register ~pp:Protocol.Alpha_context.Period.pp + @@ def "period" [] Protocol.Alpha_context.Period.encoding ; + register ~pp:Protocol.Alpha_context.Cycle.pp + @@ def "cycle" [] Protocol.Alpha_context.Cycle.encoding ; + register @@ def "constants" [] Protocol.Alpha_context.Constants.encoding ; + register + @@ def "constants" ["fixed"] Protocol.Alpha_context.Constants.fixed_encoding ; + register + @@ def + "constants" + ["parametric"] + Protocol.Alpha_context.Constants.parametric_encoding ; + register @@ def "nonce" [] Protocol.Alpha_context.Nonce.encoding ; + register @@ def "block_header" [] Protocol.Alpha_context.Block_header.encoding ; + register + @@ def + "block_header" + ["unsigned"] + Protocol.Alpha_context.Block_header.unsigned_encoding ; + register + @@ def "block_header" ["raw"] Protocol.Alpha_context.Block_header.raw_encoding ; + register + @@ def + "block_header" + ["contents"] + Protocol.Alpha_context.Block_header.contents_encoding ; + register + @@ def + "block_header" + ["shell_header"] + Protocol.Alpha_context.Block_header.shell_header_encoding ; + register + @@ def + "block_header" + ["protocol_data"] + Protocol.Alpha_context.Block_header.protocol_data_encoding ; + register ~pp:Protocol.Alpha_context.Voting_period.pp + @@ def "voting_period" [] Protocol.Alpha_context.Voting_period.encoding ; + register + @@ def + "voting_period" + ["kind"] + Protocol.Alpha_context.Voting_period.kind_encoding ; + register + @@ def + "errors" + [] + ~description: + "The full list of RPC errors would be too long to include.It is\n\ + available through the RPC `/errors` (GET)." + error_encoding diff --git a/src/proto_012_PsiThaCa/lib_client/proxy.ml b/src/proto_012_PsiThaCa/lib_client/proxy.ml new file mode 100644 index 000000000000..460985950e1f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/proxy.ml @@ -0,0 +1,184 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module L = (val Tezos_proxy.Logger.logger ~protocol_name:Protocol.name + : Tezos_proxy.Logger.S) + +let proxy_block_header (rpc_context : RPC_context.json) + (chain : Tezos_shell_services.Block_services.chain) + (block : Tezos_shell_services.Block_services.block) = + let rpc_context = new Protocol_client_context.wrap_rpc_context rpc_context in + L.emit + L.proxy_block_header + ( Tezos_shell_services.Block_services.chain_to_string chain, + Tezos_shell_services.Block_services.to_string block ) + >>= fun () -> + Protocol_client_context.Alpha_block_services.header + rpc_context + ~chain + ~block + () + +module ProtoRpc : Tezos_proxy.Proxy_proto.PROTO_RPC = struct + (** Split done only when the mode is [Tezos_proxy.Proxy.server]. Getting + an entire big map at once is useful for dapp developers that + iterate a lot on big maps and that use proxy servers in their + internal infra. *) + let split_server key = + match key with + (* matches paths like: + big_maps/index/i/contents/tail *) + | "big_maps" :: "index" :: i :: "contents" :: tail -> + Some (["big_maps"; "index"; i; "contents"], tail) + | _ -> None + + (** Split that is always done, no matter the mode *) + let split_always key = + match key with + (* matches paths like: + contracts/index/000002298c03ed7d454a101eb7022bc95f7e5f41ac78/tail *) + | "contracts" :: "index" :: i :: tail -> + Some (["contracts"; "index"; i], tail) + | "cycle" :: i :: tail -> Some (["cycle"; i], tail) + (* matches paths like: + rolls/owner/snapshot/19/1/tail *) + | "rolls" :: "owner" :: "snapshot" :: i :: j :: tail -> + Some (["rolls"; "owner"; "snapshot"; i; j], tail) + | "v1" :: tail -> Some (["v1"], tail) + | _ -> None + + let split_key (mode : Tezos_proxy.Proxy.mode) (key : Proxy_context.M.key) : + (Proxy_context.M.key * Proxy_context.M.key) option = + match split_always key with + | Some _ as res -> + res (* No need to inspect the mode, this split is always done *) + | None -> ( + match mode with + | Client -> + (* There are strictly less splits in Client mode: return immediately *) + None + | Server -> split_server key) + + let failure_is_permanent = function + | ["pending_migration_balance_updates"] + | ["pending_migration_operation_results"] -> + true + | _ -> false + + let do_rpc (pgi : Tezos_proxy.Proxy.proxy_getter_input) + (key : Proxy_context.M.key) = + let chain = pgi.chain in + let block = pgi.block in + L.emit + L.proxy_block_rpc + ( Tezos_shell_services.Block_services.chain_to_string chain, + Tezos_shell_services.Block_services.to_string block, + key ) + >>= fun () -> + Protocol_client_context.Alpha_block_services.Context.read + pgi.rpc_context + ~chain + ~block + key + >>=? fun (raw_context : Block_services.raw_context) -> + L.emit L.tree_received + @@ Int64.of_int (Tezos_proxy.Proxy_getter.raw_context_size raw_context) + >>= fun () -> return raw_context +end + +let initial_context + (proxy_builder : + Tezos_proxy.Proxy_proto.proto_rpc -> + Tezos_proxy.Proxy_getter.proxy_m Lwt.t) (rpc_context : RPC_context.json) + (mode : Tezos_proxy.Proxy.mode) + (chain : Tezos_shell_services.Block_services.chain) + (block : Tezos_shell_services.Block_services.block) : + Environment_context.Context.t Lwt.t = + let p_rpc = (module ProtoRpc : Tezos_proxy.Proxy_proto.PROTO_RPC) in + proxy_builder p_rpc >>= fun (module M) -> + L.emit + L.proxy_getter_created + ( Tezos_shell_services.Block_services.chain_to_string chain, + Tezos_shell_services.Block_services.to_string block ) + >>= fun () -> + let pgi : Tezos_proxy.Proxy.proxy_getter_input = + {rpc_context = (rpc_context :> RPC_context.simple); mode; chain; block} + in + let module N : Proxy_context.M.ProxyDelegate = struct + let proxy_dir_mem = M.proxy_dir_mem pgi + + let proxy_get = M.proxy_get pgi + + let proxy_mem = M.proxy_mem pgi + end in + let empty = Proxy_context.empty @@ Some (module N) in + let version_value = "ithaca_012" in + Tezos_protocol_environment.Context.add + empty + ["version"] + (Bytes.of_string version_value) + >>= fun ctxt -> Protocol.Main.init_cache ctxt + +let round_durations (rpc_context : RPC_context.json) + (chain : Tezos_shell_services.Block_services.chain) + (block : Tezos_shell_services.Block_services.block) = + let open Protocol in + let rpc_context = new Protocol_client_context.wrap_rpc_context rpc_context in + Constants_services.all rpc_context (chain, block) >>=? fun constants -> + (* Return the duration of block 0 *) + return_some + (Alpha_context.Period.to_seconds constants.parametric.minimal_block_delay) + +let init_env_rpc_context (_printer : Tezos_client_base.Client_context.printer) + (proxy_builder : + Tezos_proxy.Proxy_proto.proto_rpc -> + Tezos_proxy.Proxy_getter.proxy_m Lwt.t) (rpc_context : RPC_context.json) + (mode : Tezos_proxy.Proxy.mode) + (chain : Tezos_shell_services.Block_services.chain) + (block : Tezos_shell_services.Block_services.block) : + Tezos_protocol_environment.rpc_context tzresult Lwt.t = + proxy_block_header rpc_context chain block >>=? fun {shell; hash; _} -> + let block_hash = hash in + initial_context proxy_builder rpc_context mode chain block >>= fun context -> + return {Tezos_protocol_environment.block_hash; block_header = shell; context} + +let () = + let open Tezos_proxy.Registration in + let module M : Proxy_sig = struct + module Protocol = Protocol_client_context.Lifted_protocol + + let protocol_hash = Protocol.hash + + let directory = Plugin.RPC.rpc_services + + let hash = Protocol_client_context.Alpha_block_services.hash + + let init_env_rpc_context = init_env_rpc_context + + let time_between_blocks = round_durations + + include Light.M + end in + register_proxy_context (module M) diff --git a/src/proto_012_PsiThaCa/lib_client/test/.ocamlformat b/src/proto_012_PsiThaCa/lib_client/test/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/test/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_client/test/assert.ml b/src/proto_012_PsiThaCa/lib_client/test/assert.ml new file mode 100644 index 000000000000..3d414c2eafa9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/test/assert.ml @@ -0,0 +1,37 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let fail expected given msg = + Format.kasprintf + Stdlib.failwith + "@[%s@ expected: %s@ got: %s@]" + msg + expected + given + +let default_printer _ = "" + +let equal ?(eq = ( = )) ?(print = default_printer) ?(msg = "") x y = + if not (eq x y) then fail (print x) (print y) msg diff --git a/src/proto_012_PsiThaCa/lib_client/test/dune b/src/proto_012_PsiThaCa/lib_client/test/dune new file mode 100644 index 000000000000..189ac793a8c9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/test/dune @@ -0,0 +1,17 @@ +(tests + (names test_michelson_v1_macros test_client_proto_contracts test_client_proto_context test_proxy) + (libraries tezos-base + tezos-micheline + tezos-protocol-012-PsiThaCa + tezos-client-012-PsiThaCa + tezos-base-test-helpers + tezos-test-helpers + alcotest-lwt + qcheck-alcotest) + (package tezos-client-012-PsiThaCa) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_micheline + -open Tezos_client_012_PsiThaCa + -open Tezos_protocol_012_PsiThaCa + -open Tezos_base_test_helpers + -open Lib_test))) diff --git a/src/proto_012_PsiThaCa/lib_client/test/test_client_proto_context.ml b/src/proto_012_PsiThaCa/lib_client/test/test_client_proto_context.ml new file mode 100644 index 000000000000..ee5786be4739 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/test/test_client_proto_context.ml @@ -0,0 +1,71 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Testing + ------- + Component: Client + Invocation: dune exec src/proto_alpha/lib_client/test/test_client_proto_context.exe + Subject: Tests roundtrips of batch_transfer_operation_encoding +*) + +open Protocol +open Alpha_context +open Qcheck_helpers + +let binary_roundtrip ?pp encoding t = + let b = Data_encoding.Binary.to_bytes_exn encoding t in + let actual = Data_encoding.Binary.of_bytes_exn encoding b in + qcheck_eq' ?pp ~expected:t ~actual () + +let arb_batch_transfer_operation_encoding : + Client_proto_context.batch_transfer_operation QCheck.arbitrary = + let open QCheck.Gen in + let gen_z = sized @@ fun n -> map Z.of_bits (string_size (return n)) in + let gen_gas_arith_integral = + map Gas.Arith.integral_of_int_exn (int_range 0 (Int.div Int.max_int 1000)) + in + let gen_batch_transfer_operation_encoding = + let* destination = string ?gen:None in + let* fee = opt string in + let* gas_limit = opt gen_gas_arith_integral in + let* storage_limit = opt gen_z in + let* amount = string ?gen:None in + let* arg = opt string in + let* entrypoint = opt string in + return + Client_proto_context. + {destination; fee; gas_limit; storage_limit; amount; arg; entrypoint} + in + QCheck.make gen_batch_transfer_operation_encoding + +let tests = + [ + QCheck.Test.make + ~name:"test_batch_transfer_operation_encoding_roundtrip" + arb_batch_transfer_operation_encoding + (binary_roundtrip Client_proto_context.batch_transfer_operation_encoding); + ] + +let () = Alcotest.run "Client proto context" [("Encodings", qcheck_wrap tests)] diff --git a/src/proto_012_PsiThaCa/lib_client/test/test_client_proto_contracts.ml b/src/proto_012_PsiThaCa/lib_client/test/test_client_proto_contracts.ml new file mode 100644 index 000000000000..a89e6d5694ae --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/test/test_client_proto_contracts.ml @@ -0,0 +1,94 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Client + Invocation: dune exec src/proto_alpha/lib_client/test/test_client_proto_contracts.exe + Subject: Unit tests for Client_proto_contracts +*) + +(** [mock_wallet entities] is a mock of the + [Tezos_client_base.Client_context.wallet] class that only + implements the [load] method. This methods returns a key-value + association as given by the json string [entities] that should have + the form: ["[{"name": "alias", "value": "key" }, <...>]"]. *) +class mock_wallet (entities : string) : Tezos_client_base.Client_context.wallet + = + object + method load_passwords = None + + method read_file _path = failwith "mock_wallet:read_file" + + method get_base_dir = assert false + + method with_lock : type a. (unit -> a Lwt.t) -> a Lwt.t = fun _f -> _f () + + method load : type a. + string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t = + fun _alias_name ~default:_default _encoding -> + let json = (Ezjsonm.from_string entities :> Data_encoding.json) in + return @@ Data_encoding.Json.destruct _encoding json + + method write : type a. + string -> a -> a Data_encoding.encoding -> unit tzresult Lwt.t = + fun _alias_name _list _encoding -> failwith "mock_wallet:write" + end + +(** + Test. + Tests different lookups of + [Client_proto_contracts.ContractAlias.find_destination]. +*) +let test_find_destination _ = + let bootstrap1 = "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" in + let wallet_json = + Format.asprintf {| [{"name": "test_alias", "value": "%s" }] |} bootstrap1 + in + let w = new mock_wallet wallet_json in + let test msg key exp_source = + Client_proto_contracts.ContractAlias.find_destination w key + >>=? fun (_, contract) -> + Client_proto_contracts.RawContractAlias.to_source contract + >>=? fun source -> + (* Alcotest equality assertion *) + Alcotest.(check string msg source exp_source) ; + return_unit + in + test "Expected alias:test_alias = bootstrap1" "alias:test_alias" bootstrap1 + >>=? fun () -> + test "Expected key:test_alias = bootstrap1" "key:test_alias" bootstrap1 + >>=? fun () -> + test "Expected bootstrap1 = bootstrap1" bootstrap1 bootstrap1 >>=? fun () -> + test "Expected test_alias bootstrap1" "test_alias" bootstrap1 + +let () = + Alcotest_lwt.run + "tezos-lib-client-proto-contracts" + [ + ( "client_proto_contracts", + [Tztest.tztest "test_find_destination" `Quick test_find_destination] ); + ] + |> Lwt_main.run diff --git a/src/proto_012_PsiThaCa/lib_client/test/test_michelson_v1_macros.ml b/src/proto_012_PsiThaCa/lib_client/test/test_michelson_v1_macros.ml new file mode 100644 index 000000000000..75316f163dfa --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/test/test_michelson_v1_macros.ml @@ -0,0 +1,1345 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Client + Invocation: dune build @src/proto_alpha/lib_client/runtest + Dependencies: src/proto_alpha/lib_client/test/assert.ml + Subject: Expansion and unexpansion of Micheline terms. +*) + +open Protocol + +let print expr : string = + expr + |> Micheline_printer.printable (fun s -> s) + |> Format.asprintf "%a" Micheline_printer.print_expr + +(* expands : expression with macros fully expanded *) + +let assert_expands + (original : (Micheline_parser.location, string) Micheline.node) + (expanded : (Micheline_parser.location, string) Micheline.node) = + let ({Michelson_v1_parser.expanded = expansion; _}, errors) = + let source = print (Micheline.strip_locations original) in + Michelson_v1_parser.expand_all ~source ~original + in + match errors with + | [] -> + Assert.equal + ~print + (Michelson_v1_primitives.strings_of_prims expansion) + (Micheline.strip_locations expanded) ; + ok () + | errors -> Error errors + +(****************************************************************************) + +open Micheline + +let zero_loc = Micheline_parser.location_zero + +let left_branch = Seq (zero_loc, [Prim (zero_loc, "SWAP", [], [])]) + +let right_branch = Seq (zero_loc, []) + +(***************************************************************************) +(* Test expands *) +(***************************************************************************) + +(** [prim_name] is the syntactic sugar to be expanded, while [compare_name] + is syntactic atom. *) +let assert_compare_macro prim_name compare_name = + assert_expands + (Prim (zero_loc, prim_name, [], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "COMPARE", [], []); + Prim (zero_loc, compare_name, [], []); + ] )) + +(** Expand "COMP{EQ|NEQ|LT|GT|LE|GE}" + into "COMPARE ; {EQ|NEQ|LT|GT|LE|GE}". +*) +let test_compare_marco_expansion () = + assert_compare_macro "CMPEQ" "EQ" >>? fun () -> + assert_compare_macro "CMPNEQ" "NEQ" >>? fun () -> + assert_compare_macro "CMPLT" "LT" >>? fun () -> + assert_compare_macro "CMPGT" "GT" >>? fun () -> + assert_compare_macro "CMPLE" "LE" >>? fun () -> + assert_compare_macro "CMPGE" "GE" + +let assert_if_macro prim_name compare_name = + assert_expands + (Prim (zero_loc, prim_name, [left_branch; right_branch], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, compare_name, [], []); + Prim (zero_loc, "IF", [left_branch; right_branch], []); + ] )) + +(** Expand "IF{EQ|NEQ|LT|GT|LE|GE}" + into "{EQ|NEQ|LT|GT|LE|GE} ; IF" +*) +let test_if_compare_macros_expansion () = + assert_if_macro "IFEQ" "EQ" >>? fun () -> + assert_if_macro "IFNEQ" "NEQ" >>? fun () -> + assert_if_macro "IFLT" "LT" >>? fun () -> + assert_if_macro "IFGT" "GT" >>? fun () -> + assert_if_macro "IFLE" "LE" >>? fun () -> assert_if_macro "IFGE" "GE" + +let assert_if_cmp_macros prim_name compare_name = + assert_expands + (Prim (zero_loc, prim_name, [left_branch; right_branch], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "COMPARE", [], []); + Prim (zero_loc, compare_name, [], []); + Prim (zero_loc, "IF", [left_branch; right_branch], []); + ] )) + +(** Expand "IF{EQ|NEQ|LT|GT|LE|GE}" + into "{EQ|NEQ|LT|GT|LE|GE} ; IF" +*) +let test_if_cmp_macros_expansion () = + assert_if_cmp_macros "IFCMPEQ" "EQ" >>? fun () -> + assert_if_cmp_macros "IFCMPNEQ" "NEQ" >>? fun () -> + assert_if_cmp_macros "IFCMPLT" "LT" >>? fun () -> + assert_if_cmp_macros "IFCMPGT" "GT" >>? fun () -> + assert_if_cmp_macros "IFCMPLE" "LE" >>? fun () -> + assert_if_cmp_macros "IFCMPGE" "GE" + +(****************************************************************************) +(* Fail *) + +(** Expand "FAIL" + into "UNIT ; FAILWITH" +*) +let test_fail_expansion () = + assert_expands + (Prim (zero_loc, "FAIL", [], [])) + (Seq + ( zero_loc, + [Prim (zero_loc, "UNIT", [], []); Prim (zero_loc, "FAILWITH", [], [])] + )) + +(**********************************************************************) +(* assertion *) + +let seq_unit_failwith = + Seq + ( zero_loc, + [Prim (zero_loc, "UNIT", [], []); Prim (zero_loc, "FAILWITH", [], [])] ) + +(* {} {FAIL} *) +let fail_false = [Seq (zero_loc, []); Seq (zero_loc, [seq_unit_failwith])] + +(* {FAIL} {} *) +let fail_true = [Seq (zero_loc, [seq_unit_failwith]); Seq (zero_loc, [])] + +(** Expand "ASSERT" + into "IF {} {FAIL}" +*) +let test_assert_expansion () = + assert_expands + (Prim (zero_loc, "ASSERT", [], [])) + (Seq (zero_loc, [Prim (zero_loc, "IF", fail_false, [])])) + +let assert_assert_if_compare prim_name compare_name = + assert_expands + (Prim (zero_loc, prim_name, [], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, compare_name, [], []); + Prim (zero_loc, "IF", fail_false, []); + ] )) + +(** Expand "ASSERT_{EQ|NEQ|LT|GT|LE|GE}" + into "{EQ|NEQ|LT|GT|LE|GE} ; IF {} {FAIL}" +*) +let test_assert_if () = + assert_assert_if_compare "ASSERT_EQ" "EQ" >>? fun () -> + assert_assert_if_compare "ASSERT_NEQ" "NEQ" >>? fun () -> + assert_assert_if_compare "ASSERT_LT" "LT" >>? fun () -> + assert_assert_if_compare "ASSERT_LE" "LE" >>? fun () -> + assert_assert_if_compare "ASSERT_GT" "GT" >>? fun () -> + assert_assert_if_compare "ASSERT_GE" "GE" + +let assert_cmp_if prim_name compare_name = + assert_expands + (Prim (zero_loc, prim_name, [], [])) + (Seq + ( zero_loc, + [ + Seq + ( zero_loc, + [ + Prim (zero_loc, "COMPARE", [], []); + Prim (zero_loc, compare_name, [], []); + ] ); + Prim (zero_loc, "IF", fail_false, []); + ] )) + +(** Expand "ASSERT_CMP{EQ|NEQ|LT|GT|LE|GE}" + into "COMPARE ; {EQ|NEQ|LT|GT|LE|GE} ; IF {} {FAIL}" +*) +let test_assert_cmp_if () = + assert_cmp_if "ASSERT_CMPEQ" "EQ" >>? fun () -> + assert_cmp_if "ASSERT_CMPNEQ" "NEQ" >>? fun () -> + assert_cmp_if "ASSERT_CMPLT" "LT" >>? fun () -> + assert_cmp_if "ASSERT_CMPLE" "LE" >>? fun () -> + assert_cmp_if "ASSERT_CMPGT" "GT" >>? fun () -> + assert_cmp_if "ASSERT_CMPGE" "GE" + +(* The work of merge request !628 + > ASSERT_LEFT @x => IF_LEFT {RENAME @x} {FAIL} + > ASSERT_RIGHT @x => IF_LEFT {FAIL} {RENAME @x} + > ASSERT_SOME @x => IF_NONE {FAIL} {RENAME @x} +*) + +let may_rename annot = Seq (zero_loc, [Prim (zero_loc, "RENAME", [], annot)]) + +let fail_false_may_rename = + [ + may_rename ["@annot"]; + Seq + ( zero_loc, + [ + Seq + ( zero_loc, + [ + Prim (zero_loc, "UNIT", [], []); + Prim (zero_loc, "FAILWITH", [], []); + ] ); + ] ); + ] + +let fail_true_may_rename = + [ + Seq + ( zero_loc, + [ + Seq + ( zero_loc, + [ + Prim (zero_loc, "UNIT", [], []); + Prim (zero_loc, "FAILWITH", [], []); + ] ); + ] ); + may_rename ["@annot"]; + ] + +(** Expand "ASSERT_SOME @annot" + into "IF_NONE { } {UNIT;FAILWITH}" + using variable annotation "@annot" +*) +let test_assert_some_annot () = + assert_expands + (Prim (zero_loc, "ASSERT_SOME", [], ["@annot"])) + (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_true_may_rename, [])])) + +(** Expand "ASSERT_SOME" + into "IF_NONE { UNIT;FAILWITH } { }" +*) +let test_assert_some () = + assert_expands + (Prim (zero_loc, "ASSERT_SOME", [], [])) + (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_true, [])])) + +(** Expand "ASSERT_LEFT @annot" + into "IF_LEFT { } {UNIT;FAILWITH}" + using variable annotation "@annot" +*) +let test_assert_left_annot () = + assert_expands + (Prim (zero_loc, "ASSERT_LEFT", [], ["@annot"])) + (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_false_may_rename, [])])) + +(** Expand "ASSERT_LEFT" + into "IF_LEFT { } {UNIT;FAILWITH}" +*) +let test_assert_left () = + assert_expands + (Prim (zero_loc, "ASSERT_LEFT", [], [])) + (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_false, [])])) + +(** Expand "ASSERT_RIGHT @annot" + into "IF_LEFT {UNIT;FAILWITH} { }" + using variable annotation "@annot" +*) +let test_assert_right_annot () = + assert_expands + (Prim (zero_loc, "ASSERT_RIGHT", [], ["@annot"])) + (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_true_may_rename, [])])) + +(** Expand "ASSERT_RIGHT" + into "IF_LEFT {UNIT;FAILWITH} { }" +*) +let test_assert_right () = + assert_expands + (Prim (zero_loc, "ASSERT_RIGHT", [], [])) + (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_true, [])])) + +(** Expand "ASSERT_NONE" + into "IF_NONE { } { UNIT;FAILWITH }" +*) +let test_assert_none () = + assert_expands + (Prim (zero_loc, "ASSERT_NONE", [], [])) + (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_false, [])])) + +(***********************************************************************) +(*Syntactic Conveniences*) + +(* diip *) + +(** Expand "DIP" into "DIP". + Expand "DIIIIIIIIP" into "DIP 8". + Expand "DIIP" into "DIP 2". +*) +let test_diip () = + let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in + assert_expands + (Prim (zero_loc, "DIP", [code], [])) + (Prim (zero_loc, "DIP", [code], [])) + >>? fun () -> + assert_expands + (Prim (zero_loc, "DIIIIIIIIP", [code], [])) + (Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 8); code], [])) + >>? fun () -> + assert_expands + (Prim (zero_loc, "DIIP", [code], [])) + (Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 2); code], [])) + +(* pair *) + +(** Expand "PAIR" + into "PAIR" +*) +let test_pair () = + assert_expands + (Prim (zero_loc, "PAIR", [], [])) + (Prim (zero_loc, "PAIR", [], [])) + +(** Expand "PAPPAIIR" + into "DIP {PAIR}; DIP {PAIR}; PAIR" +*) +let test_pappaiir () = + let pair = Prim (zero_loc, "PAIR", [], []) in + assert_expands + (Prim (zero_loc, "PAPPAIIR", [], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DIP", [Seq (zero_loc, [pair])], []); + Prim (zero_loc, "DIP", [Seq (zero_loc, [pair])], []); + pair; + ] )) + +(* unpair *) + +(** Expand "UNPAIR" + into "DUP ; CAR ; DIP {CDR}" +*) +let test_unpair () = + assert_expands + (Prim (zero_loc, "UNPAIR", [], [])) + (Prim (zero_loc, "UNPAIR", [], [])) + +(* duup *) + +(** Expand "DUUP" + into "DIP {DUP} ; SWAP" +*) +let test_duup () = + assert_expands + (Prim (zero_loc, "DUUP", [], [])) + (Prim (zero_loc, "DUP", [Int (zero_loc, Z.of_int 2)], [])) + +(* car/cdr *) + +(** Expand "CAR" into "CAR" + Expand "CDR" into "CDR" + Expand "CADR" into "CAR ; CDR" + Expand "CDAR" into "CDR ; CAR" +*) +let test_caddadr_expansion () = + let car = Prim (zero_loc, "CAR", [], []) in + assert_expands (Prim (zero_loc, "CAR", [], [])) car >>? fun () -> + let cdr = Prim (zero_loc, "CDR", [], []) in + assert_expands (Prim (zero_loc, "CDR", [], [])) cdr >>? fun () -> + assert_expands (Prim (zero_loc, "CADR", [], [])) (Seq (zero_loc, [car; cdr])) + >>? fun () -> + assert_expands (Prim (zero_loc, "CDAR", [], [])) (Seq (zero_loc, [cdr; car])) + +let test_carn_cdrn_expansion () = + let car n = Prim (zero_loc, "CAR", [Int (zero_loc, Z.of_int n)], []) in + let cdr n = Prim (zero_loc, "CDR", [Int (zero_loc, Z.of_int n)], []) in + let get n = + Seq (zero_loc, [Prim (zero_loc, "GET", [Int (zero_loc, Z.of_int n)], [])]) + in + assert_expands (cdr 0) (get 0) >>? fun () -> + assert_expands (car 0) (get 1) >>? fun () -> + assert_expands (cdr 1) (get 2) >>? fun () -> + assert_expands (car 1) (get 3) >>? fun () -> assert_expands (cdr 2) (get 4) + +(* if_some *) + +(** Expand "IF_SOME { 1 } { 2 }" + into "IF_NONE { 2 } { 1 }" +*) +let test_if_some () = + assert_expands + (Prim (zero_loc, "IF_SOME", [right_branch; left_branch], [])) + (Seq + (zero_loc, [Prim (zero_loc, "IF_NONE", [left_branch; right_branch], [])])) + +(*set_caddadr*) + +(** Expand "SET_CAR" + into "CDR; SWAP; PAIR" +*) +let test_set_car_expansion () = + assert_expands + (Prim (zero_loc, "SET_CAR", [], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%"; "%@"]); + ] )) + +(** Expand "SET_CDR" + into "CAR; PAIR" +*) +let test_set_cdr_expansion () = + assert_expands + (Prim (zero_loc, "SET_CDR", [], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%"]); + ] )) + +(** Expand "SET_CADR" + into "DUP; DIP {CAR; { CAR; PAIR }}; CDR; SWAP; PAIR" +*) +let test_set_cadr_expansion () = + let set_car = + Seq + ( zero_loc, + [ + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%"]); + ] ) + in + assert_expands + (Prim (zero_loc, "SET_CADR", [], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); set_car])], + [] ); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] )) + +(** Expand "SET_CDAR" + into "DUP; DIP {CDR; { CDR; SWAP; PAIR }}; CAR; PAIR" +*) +let test_set_cdar_expansion () = + let set_cdr = + Seq + ( zero_loc, + [ + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%"; "%@"]); + ] ) + in + assert_expands + (Prim (zero_loc, "SET_CDAR", [], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CDR", [], ["@%%"]); set_cdr])], + [] ); + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] )) + +(* TO BE CHANGE IN THE DOCUMENTATION: @MR!791 + FROM: + > MAP_CAR code => DUP ; CDR ; DIP { CAR ; code } ; SWAP ; PAIR + TO: + > MAP_CAR code => DUP ; CDR ; DIP { CAR ; {code} } ; SWAP ; PAIR +*) + +(** Expand "MAP_CAR {CAR}" + into "DUP; CDR; DIP {CAR; CAR}; SWAP; PAIR" +*) +let test_map_car () = + (* code is a sequence *) + let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in + assert_expands + (Prim (zero_loc, "MAP_CAR", [code], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CAR", [], []); code])], + [] ); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%"; "%@"]); + ] )) + +(** Expand "MAP_CDR {CAR}" + into "DUP; CDR; CAR; SWAP; CAR; PAIR" +*) +let test_map_cdr () = + let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in + assert_expands + (Prim (zero_loc, "MAP_CDR", [code], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CDR", [], []); + code; + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%"]); + ] )) + +(** Expand "MAP_CAADR {CAR}" + into "DUP; + DIP { CAR; + DUP; + DIP { CAR; + DUP; + CDR; + CAR; + SWAP; + CAR; + PAIR + } + CDR; + SWAP; + PAIR + }; + CDR; + SWAP; + PAIR" +*) +let test_map_caadr () = + let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in + let map_cdr = + Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CDR", [], []); + code; + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%"]); + ] ) + in + let map_cadr = + Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); map_cdr])], + [] ); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] ) + in + assert_expands + (Prim (zero_loc, "MAP_CAADR", [code], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); map_cadr])], + [] ); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] )) + +(** Expand "MAP_CDADR" + into "DUP; + DIP { CDR; + DUP; + DIP { CAR; + DUP; + CDR; + CAR; + SWAP; + CAR; + PAIR + }; + CDR; + CAR; + PAIR + }; + CAR; + PAIR" +*) +let test_map_cdadr () = + let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in + let map_cdr = + Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CDR", [], []); + code; + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%"]); + ] ) + in + let map_cadr = + Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); map_cdr])], + [] ); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] ) + in + assert_expands + (Prim (zero_loc, "MAP_CDADR", [code], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CDR", [], ["@%%"]); map_cadr])], + [] ); + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] )) + +(****************************************************************************) +(* Unexpand tests *) +(****************************************************************************) + +(** Asserts that unexpanding the expression [original] conforms with + the canonical form of [ex]. + [unparse.Michelson_v1_parser.unexpanded] contains the original + expression with macros *) +let assert_unexpansion original ex = + let ({Michelson_v1_parser.expanded; _}, errors) = + let source = print (Micheline.strip_locations original) in + Michelson_v1_parser.expand_all ~source ~original + in + let unparse = Michelson_v1_printer.unparse_expression expanded in + match errors with + | [] -> + Assert.equal + ~print + unparse.Michelson_v1_parser.unexpanded + (Micheline.strip_locations ex) ; + ok () + | _ :: _ -> Error errors + +(** Unexpanding "UNIT; FAILWITH" + yields "FAIL" +*) +let test_unexpand_fail () = + assert_unexpansion + (Seq + ( zero_loc, + [Prim (zero_loc, "UNIT", [], []); Prim (zero_loc, "FAILWITH", [], [])] + )) + (Prim (zero_loc, "FAIL", [], [])) + +(** Unexpanding "IF_LEFT { 1 } { 2 }" + yields "IF_RIGHT { 2 } { 1 }" +*) +let test_unexpand_if_right () = + assert_unexpansion + (Seq + (zero_loc, [Prim (zero_loc, "IF_LEFT", [left_branch; right_branch], [])])) + (Prim (zero_loc, "IF_RIGHT", [right_branch; left_branch], [])) + +(** IF_NONE + Unexpanding "IF_NONE { 1 } { 2 }" + yields "IF_SOME { 2 } { 1 }" +*) +let test_unexpand_if_some () = + assert_unexpansion + (Seq + (zero_loc, [Prim (zero_loc, "IF_NONE", [left_branch; right_branch], [])])) + (Prim (zero_loc, "IF_SOME", [right_branch; left_branch], [])) + +(** Unexpanding "IF {} { UNIT; FAILWITH }" + yields "ASSERT" +*) +let test_unexpand_assert () = + assert_unexpansion + (Seq (zero_loc, [Prim (zero_loc, "IF", fail_false, [])])) + (Prim (zero_loc, "ASSERT", [], [])) + +let assert_unexpansion_assert_if_compare compare_name prim_name = + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim (zero_loc, compare_name, [], []); + Prim (zero_loc, "IF", fail_false, []); + ] )) + (Prim (zero_loc, prim_name, [], [])) + +(** Unexpanding "{EQ|NEQ|LT|LE|GT|GE} ; IF {} {FAIL}" + yields "ASSERT_{EQ|NEQ|LT|LE|GT|GE}" +*) +let test_unexpand_assert_if () = + assert_unexpansion_assert_if_compare "EQ" "ASSERT_EQ" >>? fun () -> + assert_unexpansion_assert_if_compare "NEQ" "ASSERT_NEQ" >>? fun () -> + assert_unexpansion_assert_if_compare "LT" "ASSERT_LT" >>? fun () -> + assert_unexpansion_assert_if_compare "LE" "ASSERT_LE" >>? fun () -> + assert_unexpansion_assert_if_compare "GT" "ASSERT_GT" >>? fun () -> + assert_unexpansion_assert_if_compare "GE" "ASSERT_GE" + +let assert_unexpansion_assert_cmp_if_compare compare_name prim_name = + assert_unexpansion + (Seq + ( zero_loc, + [ + Seq + ( zero_loc, + [ + Prim (zero_loc, "COMPARE", [], []); + Prim (zero_loc, compare_name, [], []); + ] ); + Prim (zero_loc, "IF", fail_false, []); + ] )) + (Prim (zero_loc, prim_name, [], [])) + +(** Unexpanding "COMPARE; {EQ|NEQ|LT|LE|GT|GE}; IF {} {FAIL}" + yields "ASSERT_CMP{EQ|NEQ|LT|LE|GT|GE}" +*) +let test_unexpansion_assert_cmp_if () = + assert_unexpansion_assert_cmp_if_compare "EQ" "ASSERT_CMPEQ" >>? fun () -> + assert_unexpansion_assert_cmp_if_compare "NEQ" "ASSERT_CMPNEQ" >>? fun () -> + assert_unexpansion_assert_cmp_if_compare "LT" "ASSERT_CMPLT" >>? fun () -> + assert_unexpansion_assert_cmp_if_compare "LE" "ASSERT_CMPLE" >>? fun () -> + assert_unexpansion_assert_cmp_if_compare "GT" "ASSERT_CMPGT" >>? fun () -> + assert_unexpansion_assert_cmp_if_compare "GE" "ASSERT_CMPGE" + +(** Unexpanding "IF_NONE { FAIL } { RENAME @annot }" + yields "ASSERT_SOME @annot" +*) +let test_unexpand_assert_some_annot () = + assert_unexpansion + (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_true_may_rename, [])])) + (Prim (zero_loc, "ASSERT_SOME", [], ["@annot"])) + +(** Unexpanding "IF_LEFT { RENAME @annot } { FAIL }" + yields "ASSERT_LEFT @annot" +*) +let test_unexpand_assert_left_annot () = + assert_unexpansion + (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_false_may_rename, [])])) + (Prim (zero_loc, "ASSERT_LEFT", [], ["@annot"])) + +(** Unexpanding "IF_LEFT { FAIL } { RENAME @annot }" + yields "ASSERT_RIGHT @annot" +*) +let test_unexpand_assert_right_annot () = + assert_unexpansion + (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_true_may_rename, [])])) + (Prim (zero_loc, "ASSERT_RIGHT", [], ["@annot"])) + +(** Unexpanding "IF_NONE {} { FAIL }" + yields "ASSERT_NONE" +*) +let test_unexpand_assert_none () = + assert_unexpansion + (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_false, [])])) + (Prim (zero_loc, "ASSERT_NONE", [], [])) + +(** Unexpanding "IF_NONE { FAIL } {}" + yields "ASSERT_SOME" +*) +let test_unexpand_assert_some () = + assert_unexpansion + (Seq (zero_loc, [Prim (zero_loc, "IF_NONE", fail_true, [])])) + (Prim (zero_loc, "ASSERT_SOME", [], [])) + +(** Unexpanding "IF_LEFT {} { FAIL }" + yields "ASSERT_LEFT" +*) +let test_unexpand_assert_left () = + assert_unexpansion + (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_false, [])])) + (Prim (zero_loc, "ASSERT_LEFT", [], [])) + +(** Unexpanding "IF_LEFT { FAIL } {}" + yields "ASSERT_RIGHT" +*) +let test_unexpand_assert_right () = + assert_unexpansion + (Seq (zero_loc, [Prim (zero_loc, "IF_LEFT", fail_true, [])])) + (Prim (zero_loc, "ASSERT_RIGHT", [], [])) + +(** Unexpanding "DUP; CAR; DIP { CDR }" + yields "UNPAIR" +*) +let test_unexpand_unpair () = + assert_unexpansion + (Prim (zero_loc, "UNPAIR", [], [])) + (Prim (zero_loc, "UNPAIR", [], [])) + +(** Unexpanding "PAIR" + yields "PAIR" +*) +let test_unexpand_pair () = + assert_unexpansion + (Prim (zero_loc, "PAIR", [], [])) + (Prim (zero_loc, "PAIR", [], [])) + +(** Unexpanding "DIP { PAIR }; DIP { PAIR }; PAIR" + yields "PAPPAIIR" +*) +let test_unexpand_pappaiir () = + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "PAIR", [], [])])], + [] ); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "PAIR", [], [])])], + [] ); + Prim (zero_loc, "PAIR", [], []); + ] )) + (Prim (zero_loc, "PAPPAIIR", [], [])) + +(** Unexpanding "DIP { DUP }; SWAP" + yields "DUP 2" +*) +let test_unexpand_duup () = + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "DUP", [], [])])], + [] ); + Prim (zero_loc, "SWAP", [], []); + ] )) + (Prim (zero_loc, "DUP", [Int (zero_loc, Z.of_int 2)], [])) + +(** Unexpanding "CAR" yields "CAR" + Unexpanding "CDR" yields "CDR" + Unexpanding "CAR; CDR" yields "CADR" + Unexpanding "CDR; CAR" yields "CDAR" +*) +let test_unexpand_caddadr () = + let car = Prim (zero_loc, "CAR", [], []) in + let cdr = Prim (zero_loc, "CDR", [], []) in + assert_unexpansion (Seq (zero_loc, [car])) car >>? fun () -> + assert_unexpansion (Seq (zero_loc, [cdr])) cdr >>? fun () -> + assert_unexpansion + (Seq (zero_loc, [car; cdr])) + (Prim (zero_loc, "CADR", [], [])) + >>? fun () -> + assert_unexpansion + (Seq (zero_loc, [cdr; car])) + (Prim (zero_loc, "CDAR", [], [])) + +let test_unexpand_carn_cdrn () = + let car n = Prim (zero_loc, "CAR", [Int (zero_loc, Z.of_int n)], []) in + let cdr n = Prim (zero_loc, "CDR", [Int (zero_loc, Z.of_int n)], []) in + let get n = + Seq (zero_loc, [Prim (zero_loc, "GET", [Int (zero_loc, Z.of_int n)], [])]) + in + assert_unexpansion (get 0) (cdr 0) >>? fun () -> + assert_unexpansion (get 1) (car 0) >>? fun () -> + assert_unexpansion (get 2) (cdr 1) >>? fun () -> + assert_unexpansion (get 3) (car 1) >>? fun () -> + assert_unexpansion (get 4) (cdr 2) + +(** Unexpanding "CDR; SWAP; PAIR" + yields "SET_CAR" +*) +let test_unexpand_set_car () = + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%"; "%@"]); + ] )) + (Prim (zero_loc, "SET_CAR", [], [])) + +(** Unexpanding "CAR; PAIR" + yields "SET_CDR" +*) +let test_unexpand_set_cdr () = + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%"]); + ] )) + (Prim (zero_loc, "SET_CDR", [], [])) + +(** Unexpanding "DUP; CAR; DROP; CDR; SWAP; PAIR" + yields "SET_CAR" +*) +let test_unexpand_set_car_annot () = + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CAR", [], ["%@"]); + Prim (zero_loc, "DROP", [], []); + Prim (zero_loc, "CDR", [], []); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], []); + ] )) + (Prim (zero_loc, "SET_CAR", [], ["%@"])) + +(** Unexpanding "DUP; CDR; DROP; CAR; PAIR" + yields "SET_CDR" +*) +let test_unexpand_set_cdr_annot () = + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CDR", [], ["%@"]); + Prim (zero_loc, "DROP", [], []); + Prim (zero_loc, "CAR", [], []); + Prim (zero_loc, "PAIR", [], []); + ] )) + (Prim (zero_loc, "SET_CDR", [], ["%@"])) + +(** Unexpanding "DUP; DIP { CAR; CAR; PAIR }; CDR; SWAP; PAIR" + yields "SET_CADR" +*) +let test_unexpand_set_cadr () = + let set_car = + Seq + ( zero_loc, + [ + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%"]); + ] ) + in + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); set_car])], + [] ); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] )) + (Prim (zero_loc, "SET_CADR", [], [])) + +let test_unexpand_set_cdar () = + let set_cdr = + Seq + ( zero_loc, + [ + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%"; "%@"]); + ] ) + in + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CDR", [], ["@%%"]); set_cdr])], + [] ); + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] )) + (Prim (zero_loc, "SET_CDAR", [], [])) + +(* FIXME: Seq()(Prim): does not parse, raise an error unparse *) +let test_unexpand_map_car () = + let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in + assert_unexpansion + (Prim (zero_loc, "MAP_CAR", [code], [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim + ( zero_loc, + "DIP", + [ + Seq + ( zero_loc, + [ + Prim (zero_loc, "CAR", [], []); + Prim (zero_loc, "CAR", [], []); + ] ); + ], + [] ); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%"; "%@"]); + ] )) + +(***********************************************************************) +(*BUG: the test with MAP_CDR or any map with "D" inside fail *) + +let _test_unexpand_map_cdr () = + let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CDR", [], []); + code; + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "CAR", [], []); + Prim (zero_loc, "PAIR", [], []); + ] )) + (Prim (zero_loc, "MAP_CDR", [code], [])) + +let _test_unexpand_map_caadr () = + let code = [Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])])] in + let map_cdr = + Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [ + Seq + ( zero_loc, + [ + Prim (zero_loc, "CAR", [], ["@%%"]); + Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CDR", [], []); + Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%"]); + ] ); + ] ); + ], + [] ); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] ) + in + assert_unexpansion + (Prim (zero_loc, "MAP_CAAR", code, [])) + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CAR", [], ["@%%"]); map_cdr])], + [] ); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] )) + +let _test_unexpand_map_cdadr () = + let code = [Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])])] in + let map_cdr = + Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [ + Seq + ( zero_loc, + [ + Prim (zero_loc, "CAR", [], ["@%%"]); + Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim (zero_loc, "CDR", [], []); + Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%"]); + ] ); + ] ); + ], + [] ); + Prim (zero_loc, "CDR", [], ["@%%"]); + Prim (zero_loc, "SWAP", [], []); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] ) + in + assert_unexpansion + (Seq + ( zero_loc, + [ + Prim (zero_loc, "DUP", [], []); + Prim + ( zero_loc, + "DIP", + [Seq (zero_loc, [Prim (zero_loc, "CDR", [], ["@%%"]); map_cdr])], + [] ); + Prim (zero_loc, "CAR", [], ["@%%"]); + Prim (zero_loc, "PAIR", [], ["%@"; "%@"]); + ] )) + (Prim (zero_loc, "MAP_CDADR", code, [])) + +let test_unexpand_diip () = + let code = Seq (zero_loc, [Prim (zero_loc, "CAR", [], [])]) in + assert_unexpansion + (Prim (zero_loc, "DIIP", [code], [])) + (Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 2); code], [])) + +(** Unexpanding "DIP { DIP { DIP { DUP }; SWAP" + yields "DIIP { DIP { DUP }; SWAP }" +*) +let test_unexpand_diip_duup1 () = + let single code = Seq (zero_loc, [code]) in + let cst str = Prim (zero_loc, str, [], []) in + let app str code = Prim (zero_loc, str, [code], []) in + let dip = app "DIP" in + let diip code = + Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 2); code], []) + in + let dup = cst "DUP" in + let swap = cst "SWAP" in + let dip_dup_swap = Seq (zero_loc, [dip (single dup); swap]) in + assert_unexpansion + (* { DIP { DIP { DIP { DUP }; SWAP }}} *) + (single (dip (single (dip dip_dup_swap)))) + (* DIIP { DIP { DUP }; SWAP } *) + (diip dip_dup_swap) + +(** Unexpanding "DIP { DIP {{ DIP { DUP }; SWAP" + yields "DIIP { DUUP }" +*) +let test_unexpand_diip_duup2 () = + let single code = Seq (zero_loc, [code]) in + let cst str = Prim (zero_loc, str, [], []) in + let app str code = Prim (zero_loc, str, [code], []) in + let dip = app "DIP" in + let diip code = + Prim (zero_loc, "DIP", [Int (zero_loc, Z.of_int 2); code], []) + in + let dup = cst "DUP" in + let duup = Prim (zero_loc, "DUP", [Int (zero_loc, Z.of_int 2)], []) in + let swap = cst "SWAP" in + let dip_dup_swap = Seq (zero_loc, [dip (single dup); swap]) in + assert_unexpansion + (* { DIP { DIP {{ DIP { DUP }; SWAP }}}} *) + (single (dip (single (dip (single dip_dup_swap))))) + (* DIIP { DUUP } *) + (diip (single duup)) + +(*****************************************************************************) +(* Test *) +(*****************************************************************************) + +let tests = + [ + (*compare*) + ("compare expansion", fun _ -> Lwt.return (test_compare_marco_expansion ())); + ( "if compare expansion", + fun _ -> Lwt.return (test_if_compare_macros_expansion ()) ); + ( "if compare expansion: IFCMP", + fun _ -> Lwt.return (test_if_cmp_macros_expansion ()) ); + (*fail*) + ("fail expansion", fun _ -> Lwt.return (test_fail_expansion ())); + (*assertion*) + ("assert expansion", fun _ -> Lwt.return (test_assert_expansion ())); + ("assert if expansion", fun _ -> Lwt.return (test_assert_if ())); + ("assert cmpif expansion", fun _ -> Lwt.return (test_assert_cmp_if ())); + ("assert none expansion", fun _ -> Lwt.return (test_assert_none ())); + ("assert some expansion", fun _ -> Lwt.return (test_assert_some ())); + ("assert left expansion", fun _ -> Lwt.return (test_assert_left ())); + ("assert right expansion", fun _ -> Lwt.return (test_assert_right ())); + ( "assert some annot expansion", + fun _ -> Lwt.return (test_assert_some_annot ()) ); + ( "assert left annot expansion", + fun _ -> Lwt.return (test_assert_left_annot ()) ); + ( "assert right annot expansion", + fun _ -> Lwt.return (test_assert_right_annot ()) ); + (*syntactic conveniences*) + ("diip expansion", fun _ -> Lwt.return (test_diip ())); + ("duup expansion", fun _ -> Lwt.return (test_duup ())); + ("pair expansion", fun _ -> Lwt.return (test_pair ())); + ("pappaiir expansion", fun _ -> Lwt.return (test_pappaiir ())); + ("unpair expansion", fun _ -> Lwt.return (test_unpair ())); + ("caddadr expansion", fun _ -> Lwt.return (test_caddadr_expansion ())); + ( "carn and cdrn expansion", + fun _ -> Lwt.return (test_carn_cdrn_expansion ()) ); + ("if_some expansion", fun _ -> Lwt.return (test_if_some ())); + ("set_car expansion", fun _ -> Lwt.return (test_set_car_expansion ())); + ("set_cdr expansion", fun _ -> Lwt.return (test_set_cdr_expansion ())); + ("set_cadr expansion", fun _ -> Lwt.return (test_set_cadr_expansion ())); + ("set_cdar expansion", fun _ -> Lwt.return (test_set_cdar_expansion ())); + ("map_car expansion", fun _ -> Lwt.return (test_map_car ())); + ("map_cdr expansion", fun _ -> Lwt.return (test_map_cdr ())); + ("map_caadr expansion", fun _ -> Lwt.return (test_map_caadr ())); + ("map_cdadr expansion", fun _ -> Lwt.return (test_map_cdadr ())); + (*Unexpand*) + ("fail unexpansion", fun _ -> Lwt.return (test_unexpand_fail ())); + ("if_right unexpansion", fun _ -> Lwt.return (test_unexpand_if_right ())); + ("if_some unexpansion", fun _ -> Lwt.return (test_unexpand_if_some ())); + ("assert unexpansion", fun _ -> Lwt.return (test_unexpand_assert ())); + ("assert_if unexpansion", fun _ -> Lwt.return (test_unexpand_assert_if ())); + ( "assert_cmp_if unexpansion", + fun _ -> Lwt.return (test_unexpansion_assert_cmp_if ()) ); + ( "assert_none unexpansion", + fun _ -> Lwt.return (test_unexpand_assert_none ()) ); + ( "assert_some unexpansion", + fun _ -> Lwt.return (test_unexpand_assert_some ()) ); + ( "assert_left unexpansion", + fun _ -> Lwt.return (test_unexpand_assert_left ()) ); + ( "assert_right unexpansion", + fun _ -> Lwt.return (test_unexpand_assert_right ()) ); + ( "assert_some annot unexpansion", + fun _ -> Lwt.return (test_unexpand_assert_some_annot ()) ); + ( "assert_left annot unexpansion", + fun _ -> Lwt.return (test_unexpand_assert_left_annot ()) ); + ( "assert_right annot unexpansion", + fun _ -> Lwt.return (test_unexpand_assert_right_annot ()) ); + ("unpair unexpansion", fun _ -> Lwt.return (test_unexpand_unpair ())); + ("pair unexpansion", fun _ -> Lwt.return (test_unexpand_pair ())); + ("pappaiir unexpansion", fun _ -> Lwt.return (test_unexpand_pappaiir ())); + ("duup unexpansion", fun _ -> Lwt.return (test_unexpand_duup ())); + ("caddadr unexpansion", fun _ -> Lwt.return (test_unexpand_caddadr ())); + ( "carn and cdrn unexpansion", + fun _ -> Lwt.return (test_unexpand_carn_cdrn ()) ); + ("set_car unexpansion", fun _ -> Lwt.return (test_unexpand_set_car ())); + ("set_cdr unexpansion", fun _ -> Lwt.return (test_unexpand_set_cdr ())); + ("set_cdar unexpansion", fun _ -> Lwt.return (test_unexpand_set_cdar ())); + ("set_cadr unexpansion", fun _ -> Lwt.return (test_unexpand_set_cadr ())); + ( "set_car annot unexpansion", + fun _ -> Lwt.return (test_unexpand_set_car_annot ()) ); + ( "set_cdr annot unexpansion", + fun _ -> Lwt.return (test_unexpand_set_cdr_annot ()) ); + ("map_car unexpansion", fun _ -> Lwt.return (test_unexpand_map_car ())); + ("diip unexpansion", fun _ -> Lwt.return (test_unexpand_diip ())); + ("diip_duup1 unexpansion", fun _ -> Lwt.return (test_unexpand_diip_duup1 ())); + ("diip_duup2 unexpansion", fun _ -> Lwt.return (test_unexpand_diip_duup2 ())); + (***********************************************************************) + (*BUG + the function in Michelson_v1_macros.unexpand_map_caddadr + failed to test the case with the character "D". + It returns an empty {} for the expand *) + (*"diip unexpansion", (fun _ -> Lwt.return (test_unexpand_diip ())) ;*) + (*"map_cdr unexpansion", (fun _ -> Lwt.return (test_unexpand_map_cdr ())) ;*) + (*"map_caadr unexpansion", (fun _ -> Lwt.return (test_unexpand_map_caadr ())) ;*) + (*"map_cdadr unexpansion", (fun _ -> Lwt.return (test_unexpand_map_cdadr ())) ;*) + ] + +let wrap (n, f) = + Alcotest_lwt.test_case n `Quick (fun _ () -> + f () >>= function + | Ok () -> Lwt.return_unit + | Error error -> + Format.kasprintf Stdlib.failwith "%a" pp_print_trace error) + +let () = + Alcotest_lwt.run + ~argv:[|""|] + "tezos-lib-client" + [("micheline v1 macros", List.map wrap tests)] + |> Lwt_main.run diff --git a/src/proto_012_PsiThaCa/lib_client/test/test_proxy.ml b/src/proto_012_PsiThaCa/lib_client/test/test_proxy.ml new file mode 100644 index 000000000000..d6973017918b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/test/test_proxy.ml @@ -0,0 +1,89 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Client + Invocation: dune build @src/proto_alpha/lib_client/runtest + Subject: Test of --mode proxy and tezos-proxy-server heuristic +*) + +let proxy_mode_arb = + QCheck.make (QCheck.Gen.oneofl Tezos_proxy.Proxy.[Client; Server]) + +let key_gen : string list QCheck.Gen.t = + (* Segments taken from the implementation of split_key in src/proto_alpha/lib_client/proxy.ml *) + let keys = + QCheck.Gen.oneofl + [ + "big_maps"; + "index"; + "contents"; + "contracts"; + "cycle"; + "cycle"; + "rolls"; + "owner"; + "snapshot"; + "v1"; + ] + |> QCheck.Gen.list + in + QCheck.Gen.frequency QCheck.Gen.[(9, keys); (1, list string)] + +(** Whether [t1] is a prefix of [t2] *) +let rec is_prefix t1 t2 = + match (t1, t2) with + | ([], _) -> true + | (_, []) -> false + | (x1 :: rest1, x2 :: rest2) when x1 = x2 -> is_prefix rest1 rest2 + | _ -> false + +let test_split_key = + let fmt = + let pp_sep fmt () = Format.fprintf fmt "/" in + Format.pp_print_list ~pp_sep Format.pp_print_string + in + QCheck.Test.make + ~name:"[fst (split_key s)] is a prefix of [s]" + QCheck.(pair proxy_mode_arb (QCheck.make key_gen)) + @@ fun (mode, key) -> + match Proxy.ProtoRpc.split_key mode key with + | None -> true + | Some (shorter, _) -> + if is_prefix shorter key then true + else + QCheck.Test.fail_reportf + "Expected result of split_key to be a prefix of the input key. But \ + %a is not a prefix of %a." + fmt + shorter + fmt + key + +let () = + Alcotest.run + "tezos-lib-client-proxy" + [("proxy", Lib_test.Qcheck_helpers.qcheck_wrap [test_split_key])] diff --git a/src/proto_012_PsiThaCa/lib_client/tezos-client-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_client/tezos-client-012-PsiThaCa.opam new file mode 100644 index 000000000000..461dbca438c9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client/tezos-client-012-PsiThaCa.opam @@ -0,0 +1,31 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-shell-services" + "tezos-client-base-unix" + "tezos-mockup-registration" + "tezos-proxy" + "tezos-signer-backends" + "tezos-protocol-012-PsiThaCa-parameters" + "tezos-protocol-plugin-012-PsiThaCa" + "alcotest-lwt" { with-test & >= "1.1.0" } + "tezos-test-helpers" { with-test } + "tezos-base-test-helpers" { with-test } + "ppx_inline_test" + "qcheck-alcotest" { with-test } + "tezos-test-helpers" { with-test } +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol specific library for `tezos-client`" diff --git a/src/proto_012_PsiThaCa/lib_client_commands/.ocamlformat b/src/proto_012_PsiThaCa/lib_client_commands/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_client_commands/alpha_commands_registration.ml b/src/proto_012_PsiThaCa/lib_client_commands/alpha_commands_registration.ml new file mode 100644 index 000000000000..9d4231dc9a12 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/alpha_commands_registration.ml @@ -0,0 +1,38 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let () = + Client_commands.register Protocol.hash @@ fun network -> + List.map (Clic.map_command (new Protocol_client_context.wrap_full)) + @@ Client_proto_programs_commands.commands () + @ Client_proto_contracts_commands.commands () + @ Client_proto_context_commands.commands network () + @ Client_proto_multisig_commands.commands () + @ Client_proto_mockup_commands.commands () + @ Client_sapling_commands.commands () + @ Client_proto_utils_commands.commands () + @ Client_proto_stresstest_commands.commands network () + @ Client_proto_fa12_commands.commands () diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_context_commands.ml b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_context_commands.ml new file mode 100644 index 000000000000..077fadc50d62 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_context_commands.ml @@ -0,0 +1,1958 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Client_proto_context +open Client_proto_contracts +open Client_keys +open Client_proto_args + +let encrypted_switch = + Clic.switch ~long:"encrypted" ~doc:"encrypt the key on-disk" () + +let report_michelson_errors ?(no_print_source = false) ~msg + (cctxt : #Client_context.printer) = function + | Error errs -> + cctxt#warning + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:(not no_print_source) + ~show_source:(not no_print_source) + ?parsed:None) + errs + >>= fun () -> + cctxt#error "%s" msg >>= fun () -> Lwt.return_none + | Ok data -> Lwt.return_some data + +let json_file_or_text_parameter = + Clic.parameter (fun _ p -> + match String.split ~limit:1 ':' p with + | ["text"; text] -> return (Ezjsonm.from_string text) + | ["file"; path] -> Lwt_utils_unix.Json.read_file path + | _ -> ( + if Sys.file_exists p then Lwt_utils_unix.Json.read_file p + else + try return (Ezjsonm.from_string p) + with Ezjsonm.Parse_error _ -> + failwith "Neither an existing file nor valid JSON: '%s'" p)) + +let non_negative_param = + Clic.parameter (fun _ s -> + match int_of_string_opt s with + | Some i when i >= 0 -> return i + | _ -> failwith "Parameter should be a non-negative integer literal") + +let block_hash_param = + Clic.parameter (fun _ s -> + try return (Block_hash.of_b58check_exn s) + with _ -> failwith "Parameter '%s' is an invalid block hash" s) + +let group = + { + Clic.name = "context"; + title = "Block contextual commands (see option -block)"; + } + +let alphanet = {Clic.name = "alphanet"; title = "Alphanet only commands"} + +let binary_description = + {Clic.name = "description"; title = "Binary Description"} + +let tez_of_string_exn index field s = + match Tez.of_string s with + | Some t -> return t + | None -> + failwith + "Invalid \xEA\x9C\xA9 notation at entry %i, field \"%s\": %s" + index + field + s + +let tez_of_opt_string_exn index field s = + match s with + | None -> return None + | Some s -> tez_of_string_exn index field s >>=? fun s -> return (Some s) + +let commands_ro () = + let open Clic in + [ + command + ~group + ~desc:"Access the timestamp of the block." + (args1 + (switch ~doc:"output time in seconds" ~short:'s' ~long:"seconds" ())) + (fixed ["get"; "timestamp"]) + (fun seconds (cctxt : Protocol_client_context.full) -> + Shell_services.Blocks.Header.shell_header + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + () + >>=? fun {timestamp = v; _} -> + (if seconds then cctxt#message "%Ld" (Time.Protocol.to_seconds v) + else cctxt#message "%s" (Time.Protocol.to_notation v)) + >>= fun () -> return_unit); + command + ~group + ~desc:"Lists all non empty contracts of the block." + no_options + (fixed ["list"; "contracts"]) + (fun () (cctxt : Protocol_client_context.full) -> + list_contract_labels cctxt ~chain:cctxt#chain ~block:cctxt#block + >>=? fun contracts -> + List.iter_s + (fun (alias, hash, kind) -> cctxt#message "%s%s%s" hash kind alias) + contracts + >>= fun () -> return_unit); + command + ~group + ~desc:"Lists cached contracts and their age in LRU ordering." + no_options + (prefixes ["list"; "cached"; "contracts"] @@ stop) + (fun () (cctxt : Protocol_client_context.full) -> + cached_contracts cctxt ~chain:cctxt#chain ~block:cctxt#block + >>=? fun keys -> + List.iter_s + (fun (key, size) -> + cctxt#message "%a %d" Alpha_context.Contract.pp key size) + keys + >>= fun () -> return_unit); + command + ~group + ~desc:"Get the key rank of a cache key." + no_options + (prefixes ["get"; "cached"; "contract"; "rank"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"contract" + @@ stop) + (fun () (_, contract) (cctxt : Protocol_client_context.full) -> + contract_rank cctxt ~chain:cctxt#chain ~block:cctxt#block contract + >>=? fun rank -> + match rank with + | None -> + cctxt#error + "Invalid contract: %a" + Alpha_context.Contract.pp + contract + >>= fun () -> return_unit + | Some rank -> cctxt#message "%d" rank >>= fun () -> return_unit); + command + ~group + ~desc:"Get cache contract size." + no_options + (prefixes ["get"; "cache"; "contract"; "size"] @@ stop) + (fun () (cctxt : Protocol_client_context.full) -> + contract_cache_size cctxt ~chain:cctxt#chain ~block:cctxt#block + >>=? fun t -> + cctxt#message "%d" t >>= fun () -> return_unit); + command + ~group + ~desc:"Get cache contract size limit." + no_options + (prefixes ["get"; "cache"; "contract"; "size"; "limit"] @@ stop) + (fun () (cctxt : Protocol_client_context.full) -> + contract_cache_size_limit cctxt ~chain:cctxt#chain ~block:cctxt#block + >>=? fun t -> + cctxt#message "%d" t >>= fun () -> return_unit); + command + ~group + ~desc:"Get the balance of a contract." + no_options + (prefixes ["get"; "balance"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun () (_, contract) (cctxt : Protocol_client_context.full) -> + get_balance cctxt ~chain:cctxt#chain ~block:cctxt#block contract + >>=? fun amount -> + cctxt#answer "%a %s" Tez.pp amount Client_proto_args.tez_sym + >>= fun () -> return_unit); + command + ~group + ~desc:"Get the storage of a contract." + (args1 (unparsing_mode_arg ~default:"Readable")) + (prefixes ["get"; "contract"; "storage"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun unparsing_mode (_, contract) (cctxt : Protocol_client_context.full) -> + get_storage + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~unparsing_mode + contract + >>=? function + | None -> cctxt#error "This is not a smart contract." + | Some storage -> + cctxt#answer "%a" Michelson_v1_printer.print_expr_unwrapped storage + >>= fun () -> return_unit); + command + ~group + ~desc: + "Get the value associated to a key in the big map storage of a \ + contract (deprecated)." + no_options + (prefixes ["get"; "big"; "map"; "value"; "for"] + @@ Clic.param ~name:"key" ~desc:"the key to look for" data_parameter + @@ prefixes ["of"; "type"] + @@ Clic.param ~name:"type" ~desc:"type of the key" data_parameter + @@ prefix "in" + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun () key key_type (_, contract) (cctxt : Protocol_client_context.full) -> + get_contract_big_map_value + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + contract + (key.expanded, key_type.expanded) + >>=? function + | None -> cctxt#error "No value associated to this key." + | Some value -> + cctxt#answer "%a" Michelson_v1_printer.print_expr_unwrapped value + >>= fun () -> return_unit); + command + ~group + ~desc:"Get a value in a big map." + (args1 (unparsing_mode_arg ~default:"Readable")) + (prefixes ["get"; "element"] + @@ Clic.param + ~name:"key" + ~desc:"the key to look for" + (Clic.parameter (fun _ s -> + return (Script_expr_hash.of_b58check_exn s))) + @@ prefixes ["of"; "big"; "map"] + @@ Clic.param + ~name:"big_map" + ~desc:"identifier of the big_map" + int_parameter + @@ stop) + (fun unparsing_mode key id (cctxt : Protocol_client_context.full) -> + get_big_map_value + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~unparsing_mode + (Big_map.Id.parse_z (Z.of_int id)) + key + >>=? fun value -> + cctxt#answer "%a" Michelson_v1_printer.print_expr_unwrapped value + >>= fun () -> return_unit); + command + ~group + ~desc:"Get the code of a contract." + (args1 (unparsing_mode_arg ~default:"Readable")) + (prefixes ["get"; "contract"; "code"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun unparsing_mode (_, contract) (cctxt : Protocol_client_context.full) -> + get_script + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~unparsing_mode + contract + >>=? function + | None -> cctxt#error "This is not a smart contract." + | Some {code; storage = _} -> ( + match Script_repr.force_decode code with + | Error errs -> + cctxt#error "%a" Environment.Error_monad.pp_trace errs + | Ok code -> + let {Michelson_v1_parser.source; _} = + Michelson_v1_printer.unparse_toplevel code + in + cctxt#answer "%s" source >>= return)); + command + ~group + ~desc:"Get the `BLAKE2B` script hash of a contract." + no_options + (prefixes ["get"; "contract"; "script"; "hash"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun () (_, contract) (cctxt : Protocol_client_context.full) -> + get_script_hash cctxt ~chain:cctxt#chain ~block:cctxt#block contract + >>= function + | Error errs -> cctxt#error "%a" pp_print_trace errs + | Ok None -> cctxt#error "This is not a smart contract." + | Ok (Some hash) -> cctxt#answer "%a" Script_expr_hash.pp hash >|= ok); + command + ~group + ~desc:"Get the type of an entrypoint of a contract." + no_options + (prefixes ["get"; "contract"; "entrypoint"; "type"; "of"] + @@ Clic.string ~name:"entrypoint" ~desc:"the entrypoint to describe" + @@ prefixes ["for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun () entrypoint (_, contract) (cctxt : Protocol_client_context.full) -> + Michelson_v1_entrypoints.contract_entrypoint_type + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + ~entrypoint + >>= Michelson_v1_entrypoints.print_entrypoint_type + cctxt + ~emacs:false + ~contract + ~entrypoint); + command + ~group + ~desc:"Get the entrypoint list of a contract." + no_options + (prefixes ["get"; "contract"; "entrypoints"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun () (_, contract) (cctxt : Protocol_client_context.full) -> + Michelson_v1_entrypoints.list_contract_entrypoints + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + >>= Michelson_v1_entrypoints.print_entrypoints_list + cctxt + ~emacs:false + ~contract); + command + ~group + ~desc:"Get the list of unreachable paths in a contract's parameter type." + no_options + (prefixes ["get"; "contract"; "unreachable"; "paths"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun () (_, contract) (cctxt : Protocol_client_context.full) -> + Michelson_v1_entrypoints.list_contract_unreachables + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + >>= Michelson_v1_entrypoints.print_unreachables + cctxt + ~emacs:false + ~contract); + command + ~group + ~desc:"Get the delegate of a contract." + no_options + (prefixes ["get"; "delegate"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun () (_, contract) (cctxt : Protocol_client_context.full) -> + Client_proto_contracts.get_delegate + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + contract + >>=? function + | None -> cctxt#message "none" >>= fun () -> return_unit + | Some delegate -> + Public_key_hash.rev_find cctxt delegate >>=? fun mn -> + Public_key_hash.to_source delegate >>=? fun m -> + cctxt#message + "%s (%s)" + m + (match mn with None -> "unknown" | Some n -> "known as " ^ n) + >>= fun () -> return_unit); + command + ~desc:"Get receipt for past operation" + (args1 + (default_arg + ~long:"check-previous" + ~placeholder:"num_blocks" + ~doc:"number of previous blocks to check" + ~default:"10" + non_negative_param)) + (prefixes ["get"; "receipt"; "for"] + @@ param + ~name:"operation" + ~desc:"Operation to be looked up" + (parameter (fun _ x -> + match Operation_hash.of_b58check_opt x with + | None -> Error_monad.failwith "Invalid operation hash: '%s'" x + | Some hash -> return hash)) + @@ stop) + (fun predecessors operation_hash (ctxt : Protocol_client_context.full) -> + display_receipt_for_operation + ctxt + ~chain:ctxt#chain + ~predecessors + operation_hash + >>=? fun _ -> return_unit); + command + ~group + ~desc:"Summarize the current voting period" + no_options + (fixed ["show"; "voting"; "period"]) + (fun () (cctxt : Protocol_client_context.full) -> + get_period_info ~chain:cctxt#chain ~block:cctxt#block cctxt + >>=? fun info -> + cctxt#message + "Current period: %a\nBlocks remaining until end of period: %ld" + Data_encoding.Json.pp + (Data_encoding.Json.construct + Alpha_context.Voting_period.kind_encoding + info.current_period_kind) + info.remaining + >>= fun () -> + Shell_services.Protocol.list cctxt >>=? fun known_protos -> + get_proposals ~chain:cctxt#chain ~block:cctxt#block cctxt + >>=? fun props -> + let ranks = + Environment.Protocol_hash.Map.bindings props + |> List.sort (fun (_, v1) (_, v2) -> Int32.(compare v2 v1)) + in + let print_proposal = function + | None -> + cctxt#message "The current proposal has already been cleared." + (* The proposal is cleared on the last block of adoption period, and + also on the last block of the exploration and promotion + periods when the proposal is not approved *) + | Some proposal -> + cctxt#message "Current proposal: %a" Protocol_hash.pp proposal + in + match info.current_period_kind with + | Proposal -> + (* the current proposals are cleared on the last block of the + proposal period *) + if info.remaining <> 0l then + cctxt#answer + "Current proposals:%t" + Format.( + fun ppf -> + pp_print_cut ppf () ; + pp_open_vbox ppf 0 ; + List.iter + (fun (p, w) -> + fprintf + ppf + "* %a %ld (%sknown by the node)@." + Protocol_hash.pp + p + w + (if List.mem ~equal:Protocol_hash.equal p known_protos + then "" + else "not ")) + ranks ; + pp_close_box ppf ()) + >>= fun () -> return_unit + else + cctxt#message "The proposals have already been cleared." + >>= fun () -> return_unit + | Exploration | Promotion -> + print_proposal info.current_proposal >>= fun () -> + (* the ballots are cleared on the last block of these periods *) + if info.remaining <> 0l then + get_ballots_info ~chain:cctxt#chain ~block:cctxt#block cctxt + >>=? fun ballots_info -> + cctxt#answer + "Ballots: %a@,\ + Current participation %.2f%%, necessary quorum %.2f%%@,\ + Current in favor %ld, needed supermajority %ld" + Data_encoding.Json.pp + (Data_encoding.Json.construct + Vote.ballots_encoding + ballots_info.ballots) + (Int32.to_float ballots_info.participation /. 100.) + (Int32.to_float ballots_info.current_quorum /. 100.) + ballots_info.ballots.yay + ballots_info.supermajority + >>= fun () -> return_unit + else + cctxt#message "The ballots have already been cleared." + >>= fun () -> return_unit + | Cooldown -> + print_proposal info.current_proposal >>= fun () -> return_unit + | Adoption -> + print_proposal info.current_proposal >>= fun () -> return_unit); + command + ~group:binary_description + ~desc:"Describe unsigned block header" + no_options + (fixed ["describe"; "unsigned"; "block"; "header"]) + (fun () (cctxt : Protocol_client_context.full) -> + cctxt#message + "%a" + Data_encoding.Binary_schema.pp + (Data_encoding.Binary.describe + Alpha_context.Block_header.unsigned_encoding) + >>= fun () -> return_unit); + command + ~group:binary_description + ~desc:"Describe unsigned operation" + no_options + (fixed ["describe"; "unsigned"; "operation"]) + (fun () (cctxt : Protocol_client_context.full) -> + cctxt#message + "%a" + Data_encoding.Binary_schema.pp + (Data_encoding.Binary.describe + Alpha_context.Operation.unsigned_encoding) + >>= fun () -> return_unit); + command + ~group + ~desc:"Get the frozen deposits limit of a delegate." + no_options + (prefixes ["get"; "deposits"; "limit"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source delegate" + @@ stop) + (fun () (_, contract) (cctxt : Protocol_client_context.full) -> + match Contract.is_implicit contract with + | None -> + cctxt#error + "Cannot change deposits limit on contract %a. This operation is \ + invalid on originated contracts." + Contract.pp + contract + | Some delegate -> ( + get_frozen_deposits_limit + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + delegate + >>=? function + | None -> cctxt#answer "unlimited" >>= return + | Some limit -> + cctxt#answer "%a %s" Tez.pp limit Client_proto_args.tez_sym + >>= return)); + ] + +(* ----------------------------------------------------------------------------*) +(* After the activation of a new version of the protocol, the older protocols + are only kept in the code base to replay the history of the chain and to query + old states. + + The commands that are not useful anymore in the old protocols are removed, + this is called protocol freezing. The commands below are those that can be + removed during protocol freezing. + + The rule of thumb to know if a command should be kept at freezing is that all + commands that modify the state of the chain should be removed and conversely + all commands that are used to query the context should be kept. For this + reason, we call read-only (or RO for short) the commands that are kept and + read-write (or RW for short) the commands that are removed. + + There are some exceptions to this rule however, for example the command + "tezos-client wait for to be included" is classified as RW despite having + no effect on the context because it has no use case once all RW commands are + removed. + + Keeping this in mind, the developer should decide where to add a new command. + At the end of the file, RO and RW commands are concatenated into one list that + is then exported in the mli file. *) +(* ----------------------------------------------------------------------------*) + +let dry_run_switch = + Clic.switch + ~long:"dry-run" + ~short:'D' + ~doc:"don't inject the operation, just display it" + () + +let verbose_signing_switch = + Clic.switch + ~long:"verbose-signing" + ~doc:"display extra information before signing the operation" + () + +let simulate_switch = + Clic.switch + ~long:"simulation" + ~doc: + "Simulate the execution of the command, without needing any signatures." + () + +let transfer_command amount source destination cctxt + ( fee, + dry_run, + verbose_signing, + simulation, + gas_limit, + storage_limit, + counter, + arg, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap, + entrypoint ) = + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + (match Contract.is_implicit source with + | None -> + let contract = source in + Managed_contract.get_contract_manager cctxt source >>=? fun source -> + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + Managed_contract.transfer + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~simulation + ~fee_parameter + ?fee + ~contract + ~source + ~src_pk + ~src_sk + ~destination + ?entrypoint + ?arg + ~amount + ?gas_limit + ?storage_limit + ?counter + () + | Some source -> + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + transfer + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~simulation + ~verbose_signing + ~fee_parameter + ~source + ?fee + ~src_pk + ~src_sk + ~destination + ?entrypoint + ?arg + ~amount + ?gas_limit + ?storage_limit + ?counter + ()) + >>= report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit + +let prepare_batch_operation cctxt ?arg ?fee ?gas_limit ?storage_limit + ?entrypoint source index batch = + Client_proto_contracts.ContractAlias.find_destination cctxt batch.destination + >>=? fun (_, destination) -> + tez_of_string_exn index "amount" batch.amount >>=? fun amount -> + tez_of_opt_string_exn index "fee" batch.fee >>=? fun batch_fee -> + let fee = Option.either batch_fee fee in + let arg = Option.either batch.arg arg in + let gas_limit = Option.either batch.gas_limit gas_limit in + let storage_limit = Option.either batch.storage_limit storage_limit in + let entrypoint = Option.either batch.entrypoint entrypoint in + parse_arg_transfer arg >>=? fun parameters -> + (match Contract.is_implicit source with + | None -> + Managed_contract.build_transaction_operation + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract:source + ~destination + ?entrypoint + ?arg + ~amount + ?fee + ?gas_limit + ?storage_limit + () + | Some _ -> + return + (build_transaction_operation + ~amount + ~parameters + ?entrypoint + ?fee + ?gas_limit + ?storage_limit + destination)) + >>=? fun operation -> + return (Annotated_manager_operation.Annotated_manager_operation operation) + +let commands_network network () = + let open Clic in + match network with + | Some `Testnet | None -> + [ + command + ~group + ~desc:"Register and activate an Alphanet/Zeronet faucet account." + (args2 (Secret_key.force_switch ()) encrypted_switch) + (prefixes ["activate"; "account"] + @@ Secret_key.fresh_alias_param + @@ prefixes ["with"] + @@ param + ~name:"activation_key" + ~desc: + "Activate an Alphanet/Zeronet faucet account from the JSON \ + (file or directly inlined)." + json_file_or_text_parameter + @@ stop) + (fun (force, encrypted) name activation_json cctxt -> + Secret_key.of_fresh cctxt force name >>=? fun name -> + match + Data_encoding.Json.destruct + Client_proto_context.activation_key_encoding + activation_json + with + | exception (Data_encoding.Json.Cannot_destruct _ as exn) -> + Format.kasprintf + (fun s -> failwith "%s" s) + "Invalid activation file: %a %a" + (fun ppf -> Data_encoding.Json.print_error ppf) + exn + Data_encoding.Json.pp + activation_json + | key -> + activate_account + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~encrypted + ~force + key + name + >>=? fun _res -> return_unit); + ] + | Some `Mainnet -> + [ + command + ~group + ~desc:"Activate a fundraiser account." + (args1 dry_run_switch) + (prefixes ["activate"; "fundraiser"; "account"] + @@ Public_key_hash.alias_param + @@ prefixes ["with"] + @@ param + ~name:"code" + (Clic.parameter (fun _ctx code -> + match + Blinded_public_key_hash.activation_code_of_hex code + with + | Some c -> return c + | None -> failwith "Hexadecimal parsing failure")) + ~desc:"Activation code obtained from the Tezos foundation." + @@ stop) + (fun dry_run (name, _pkh) code cctxt -> + activate_existing_account + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + name + code + >>=? fun _res -> return_unit); + ] + +let commands_rw () = + let open Client_proto_programs in + let open Tezos_micheline in + let open Clic in + [ + command + ~group + ~desc:"Set the delegate of a contract." + (args10 + fee_arg + dry_run_switch + verbose_signing_switch + simulate_switch + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["set"; "delegate"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ prefix "to" + @@ Public_key_hash.source_param + ~name:"dlgt" + ~desc:"new delegate of the contract" + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + simulation, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, contract) + delegate + (cctxt : Protocol_client_context.full) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + match Contract.is_implicit contract with + | None -> + Managed_contract.get_contract_manager cctxt contract + >>=? fun source -> + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + Managed_contract.set_delegate + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~simulation + ~fee_parameter + ?fee + ~source + ~src_pk + ~src_sk + contract + (Some delegate) + >>= fun errors -> + report_michelson_errors + ~no_print_source:true + ~msg:"Setting delegate through entrypoints failed." + cctxt + errors + >>= fun _ -> return_unit + | Some mgr -> + Client_keys.get_key cctxt mgr >>=? fun (_, src_pk, manager_sk) -> + set_delegate + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~simulation + ~fee_parameter + ?fee + mgr + (Some delegate) + ~src_pk + ~manager_sk + >>=? fun _ -> return_unit); + command + ~group + ~desc:"Withdraw the delegate from a contract." + (args9 + fee_arg + dry_run_switch + verbose_signing_switch + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["withdraw"; "delegate"; "from"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, contract) + (cctxt : Protocol_client_context.full) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + match Contract.is_implicit contract with + | None -> + Managed_contract.get_contract_manager cctxt contract + >>=? fun source -> + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + Managed_contract.set_delegate + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~fee_parameter + ?fee + ~source + ~src_pk + ~src_sk + contract + None + >>= fun errors -> + report_michelson_errors + ~no_print_source:true + ~msg:"Withdrawing delegate through entrypoints failed." + cctxt + errors + >>= fun _ -> return_unit + | Some mgr -> + Client_keys.get_key cctxt mgr >>=? fun (_, src_pk, manager_sk) -> + set_delegate + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~fee_parameter + mgr + None + ?fee + ~src_pk + ~manager_sk + >>= fun _ -> return_unit); + command + ~group + ~desc:"Launch a smart contract on the blockchain." + (args15 + fee_arg + dry_run_switch + verbose_signing_switch + gas_limit_arg + storage_limit_arg + delegate_arg + (Client_keys.force_switch ()) + init_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["originate"; "contract"] + @@ RawContractAlias.fresh_alias_param + ~name:"new" + ~desc:"name of the new contract" + @@ prefix "transferring" + @@ tez_param ~name:"qty" ~desc:"amount taken from source" + @@ prefix "from" + @@ ContractAlias.destination_param + ~name:"src" + ~desc:"name of the source contract" + @@ prefix "running" + @@ Program.source_param + ~name:"prg" + ~desc: + "script of the account\n\ + Combine with -init if the storage type is not unit." + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + delegate, + force, + initial_storage, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + alias_name + balance + (_, source) + program + (cctxt : Protocol_client_context.full) -> + RawContractAlias.of_fresh cctxt force alias_name >>=? fun alias_name -> + Lwt.return (Micheline_parser.no_parsing_error program) + >>=? fun {expanded = code; _} -> + match Contract.is_implicit source with + | None -> + failwith + "only implicit accounts can be the source of an origination" + | Some source -> ( + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + originate_contract + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ?fee + ?gas_limit + ?storage_limit + ~delegate + ~initial_storage + ~balance + ~source + ~src_pk + ~src_sk + ~code + ~fee_parameter + () + >>= fun errors -> + report_michelson_errors + ~no_print_source + ~msg:"origination simulation failed" + cctxt + errors + >>= function + | None -> return_unit + | Some (_res, contract) -> + if dry_run then return_unit + else + save_contract ~force cctxt alias_name contract >>=? fun () -> + return_unit)); + command + ~group + ~desc: + "Execute multiple transfers from a single source account.\n\ + If one of the transfers fails, none of them get executed." + (args16 + default_fee_arg + dry_run_switch + verbose_signing_switch + simulate_switch + default_gas_limit_arg + default_storage_limit_arg + counter_arg + default_arg_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg + default_entrypoint_arg) + (prefixes ["multiple"; "transfers"; "from"] + @@ ContractAlias.destination_param + ~name:"src" + ~desc:"name of the source contract" + @@ prefix "using" + @@ param + ~name:"transfers.json" + ~desc: + "List of operations originating from the source contract in JSON \ + format (from a file or directly inlined). The input JSON must be \ + an array of objects of the form: '[ {\"destination\": dst, \ + \"amount\": qty (, : ...) } (, ...) ]', where an \ + optional can either be \"fee\", \"gas-limit\", \ + \"storage-limit\", \"arg\", or \"entrypoint\"." + json_file_or_text_parameter + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + simulation, + gas_limit, + storage_limit, + counter, + arg, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap, + entrypoint ) + (_, source) + operations_json + cctxt -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + let prepare i = + prepare_batch_operation + cctxt + ?arg + ?fee + ?gas_limit + ?storage_limit + ?entrypoint + source + i + in + match + Data_encoding.Json.destruct + (Data_encoding.list + Client_proto_context.batch_transfer_operation_encoding) + operations_json + with + | [] -> failwith "Empty operation list" + | operations -> + (match Contract.is_implicit source with + | None -> + Managed_contract.get_contract_manager cctxt source + >>=? fun source -> + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + return (source, src_pk, src_sk) + | Some source -> + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + return (source, src_pk, src_sk)) + >>=? fun (source, src_pk, src_sk) -> + List.mapi_ep prepare operations >>=? fun contents -> + let (Manager_list contents) = + Annotated_manager_operation.manager_of_list contents + in + Injection.inject_manager_operation + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~simulation + ~source + ~fee:(Limit.of_option fee) + ~gas_limit:(Limit.of_option gas_limit) + ~storage_limit:(Limit.of_option storage_limit) + ?counter + ~src_pk + ~src_sk + ~fee_parameter + contents + >>= report_michelson_errors + ~no_print_source + ~msg:"multiple transfers simulation failed" + cctxt + >>= fun _ -> return_unit + | exception (Data_encoding.Json.Cannot_destruct (path, exn2) as exn) + -> ( + match (path, operations_json) with + | ([`Index n], `A lj) -> ( + match List.nth_opt lj n with + | Some j -> + failwith + "Invalid transfer at index %i: %a %a" + n + (fun ppf -> Data_encoding.Json.print_error ppf) + exn2 + Data_encoding.Json.pp + j + | _ -> + failwith + "Invalid transfer at index %i: %a" + n + (fun ppf -> Data_encoding.Json.print_error ppf) + exn2) + | _ -> + failwith + "Invalid transfer file: %a %a" + (fun ppf -> Data_encoding.Json.print_error ppf) + exn + Data_encoding.Json.pp + operations_json)); + command + ~group + ~desc:"Transfer tokens / call a smart contract." + (args16 + fee_arg + dry_run_switch + verbose_signing_switch + simulate_switch + gas_limit_arg + storage_limit_arg + counter_arg + arg_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg + entrypoint_arg) + (prefixes ["transfer"] + @@ tez_param ~name:"qty" ~desc:"amount taken from source" + @@ prefix "from" + @@ ContractAlias.destination_param + ~name:"src" + ~desc:"name of the source contract" + @@ prefix "to" + @@ ContractAlias.destination_param + ~name:"dst" + ~desc:"name/literal of the destination contract" + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + simulation, + gas_limit, + storage_limit, + counter, + arg, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap, + entrypoint ) + amount + (_, source) + (_, destination) + cctxt -> + transfer_command + amount + source + destination + cctxt + ( fee, + dry_run, + verbose_signing, + simulation, + gas_limit, + storage_limit, + counter, + arg, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap, + entrypoint )); + command + ~group + ~desc:"Register a global constant" + (args12 + fee_arg + dry_run_switch + verbose_signing_switch + simulate_switch + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + storage_limit_arg + counter_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["register"; "global"; "constant"] + @@ global_constant_param + ~name:"expression" + ~desc: + "Michelson expression to register. Note the value is not \ + typechecked before registration." + @@ prefix "from" + @@ ContractAlias.destination_param + ~name:"src" + ~desc:"name of the account registering the global constant" + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + simulation, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + storage_limit, + counter, + force_low_fee, + fee_cap, + burn_cap ) + global_constant_str + (_, source) + cctxt -> + match Contract.is_implicit source with + | None -> + failwith "Only implicit accounts can register global constants" + | Some source -> + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + register_global_constant + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?dry_run:(Some dry_run) + ?verbose_signing:(Some verbose_signing) + ?fee + ?storage_limit + ?counter + ?confirmations:cctxt#confirmations + ~simulation + ~source + ~src_pk + ~src_sk + ~fee_parameter + ~constant:global_constant_str + () + >>= fun errors -> + report_michelson_errors + ~no_print_source:false + ~msg:"register global constant simulation failed" + cctxt + errors + >>= fun _ -> return_unit); + command + ~group + ~desc:"Call a smart contract (same as 'transfer 0')." + (args16 + fee_arg + dry_run_switch + verbose_signing_switch + simulate_switch + gas_limit_arg + storage_limit_arg + counter_arg + arg_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg + entrypoint_arg) + (prefixes ["call"] + @@ ContractAlias.destination_param + ~name:"dst" + ~desc:"name/literal of the destination contract" + @@ prefix "from" + @@ ContractAlias.destination_param + ~name:"src" + ~desc:"name of the source contract" + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + simulation, + gas_limit, + storage_limit, + counter, + arg, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap, + entrypoint ) + (_, destination) + (_, source) + cctxt -> + let amount = Tez.zero in + transfer_command + amount + source + destination + cctxt + ( fee, + dry_run, + verbose_signing, + simulation, + gas_limit, + storage_limit, + counter, + arg, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap, + entrypoint )); + command + ~group + ~desc:"Reveal the public key of the contract manager." + (args9 + fee_arg + dry_run_switch + verbose_signing_switch + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["reveal"; "key"; "for"] + @@ ContractAlias.alias_param + ~name:"src" + ~desc:"name of the source contract" + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, source) + cctxt -> + match Contract.is_implicit source with + | None -> failwith "only implicit accounts can be revealed" + | Some source -> + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + reveal + cctxt + ~dry_run + ~verbose_signing + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~source + ?fee + ~src_pk + ~src_sk + ~fee_parameter + () + >>=? fun _res -> return_unit); + command + ~group + ~desc:"Register the public key hash as a delegate." + (args9 + fee_arg + dry_run_switch + verbose_signing_switch + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["register"; "key"] + @@ Public_key_hash.source_param ~name:"mgr" ~desc:"the delegate key" + @@ prefixes ["as"; "delegate"] + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + src_pkh + cctxt -> + Client_keys.get_key cctxt src_pkh >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + register_as_delegate + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~fee_parameter + ~verbose_signing + ?fee + ~manager_sk:src_sk + src_pk + >>= function + | Ok _ -> return_unit + | Error [Environment.Ecoproto_error Delegate_storage.Active_delegate] -> + cctxt#message "Delegate already activated." >>= fun () -> + return_unit + | Error el -> Lwt.return_error el); + command + ~desc:"Wait until an operation is included in a block" + (args3 + (default_arg + ~long:"confirmations" + ~placeholder:"num_blocks" + ~doc: + "wait until 'N' additional blocks after the operation appears in \ + the considered chain" + ~default:"0" + non_negative_param) + (default_arg + ~long:"check-previous" + ~placeholder:"num_blocks" + ~doc:"number of previous blocks to check" + ~default:"10" + non_negative_param) + (arg + ~long:"branch" + ~placeholder:"block_hash" + ~doc: + "hash of the oldest block where we should look for the operation" + block_hash_param)) + (prefixes ["wait"; "for"] + @@ param + ~name:"operation" + ~desc:"Operation to be included" + (parameter (fun _ x -> + match Operation_hash.of_b58check_opt x with + | None -> Error_monad.failwith "Invalid operation hash: '%s'" x + | Some hash -> return hash)) + @@ prefixes ["to"; "be"; "included"] + @@ stop) + (fun (confirmations, predecessors, branch) + operation_hash + (ctxt : Protocol_client_context.full) -> + Client_confirmations.wait_for_operation_inclusion + ctxt + ~chain:ctxt#chain + ~confirmations + ~predecessors + ?branch + operation_hash + >>=? fun _ -> return_unit); + command + ~group + ~desc:"Submit protocol proposals" + (args3 + dry_run_switch + verbose_signing_switch + (switch + ~doc: + "Do not fail when the checks that try to prevent the user from \ + shooting themselves in the foot do." + ~long:"force" + ())) + (prefixes ["submit"; "proposals"; "for"] + @@ ContractAlias.destination_param + ~name:"delegate" + ~desc:"the delegate who makes the proposal" + @@ seq_of_param + (param + ~name:"proposal" + ~desc:"the protocol hash proposal to be submitted" + (parameter (fun _ x -> + match Protocol_hash.of_b58check_opt x with + | None -> + Error_monad.failwith "Invalid proposal hash: '%s'" x + | Some hash -> return hash)))) + (fun (dry_run, verbose_signing, force) + (_name, source) + proposals + (cctxt : Protocol_client_context.full) -> + match Contract.is_implicit source with + | None -> failwith "only implicit accounts can submit proposals" + | Some src_pkh -> ( + Client_keys.get_key cctxt src_pkh + >>=? fun (src_name, _src_pk, src_sk) -> + get_period_info + (* Find period info of the successor, because the operation will + be injected on the next block at the earliest *) + ~successor:true + ~chain:cctxt#chain + ~block:cctxt#block + cctxt + >>=? fun info -> + (match info.current_period_kind with + | Proposal -> return_unit + | _ -> cctxt#error "Not in a proposal period") + >>=? fun () -> + Shell_services.Protocol.list cctxt >>=? fun known_protos -> + get_proposals ~chain:cctxt#chain ~block:cctxt#block cctxt + >>=? fun known_proposals -> + Alpha_services.Voting.listings cctxt (cctxt#chain, cctxt#block) + >>=? fun listings -> + (* for a proposal to be valid it must either a protocol that was already + proposed by somebody else or a protocol known by the node, because + the user is the first proposer and just injected it with + tezos-admin-client *) + let check_proposals proposals : bool tzresult Lwt.t = + let errors = ref [] in + let error ppf = + Format.kasprintf (fun s -> errors := s :: !errors) ppf + in + if proposals = [] then error "Empty proposal list." ; + if + Compare.List_length_with.( + proposals > Constants.max_proposals_per_delegate) + then + error + "Too many proposals: %d > %d." + (List.length proposals) + Constants.max_proposals_per_delegate ; + (match + Base.List.find_all_dups + ~compare:Protocol_hash.compare + proposals + with + | [] -> () + | dups -> + error + "There %s: %a." + (if Compare.List_length_with.(dups = 1) then + "is a duplicate proposal" + else "are duplicate proposals") + Format.( + pp_print_list + ~pp_sep:(fun ppf () -> pp_print_string ppf ", ") + Protocol_hash.pp) + dups) ; + List.iter + (fun (p : Protocol_hash.t) -> + if + List.mem ~equal:Protocol_hash.equal p known_protos + || Environment.Protocol_hash.Map.mem p known_proposals + then () + else + error + "Protocol %a is not a known proposal." + Protocol_hash.pp + p) + proposals ; + if + not + (List.exists + (fun (pkh, _) -> + Signature.Public_key_hash.equal pkh src_pkh) + listings) + then + error + "Public-key-hash `%a` from account `%s` does not appear to \ + have voting rights." + Signature.Public_key_hash.pp + src_pkh + src_name ; + if !errors <> [] then + cctxt#message + "There %s with the submission:%t" + (if Compare.List_length_with.(!errors = 1) then "is an issue" + else "are issues") + Format.( + fun ppf -> + pp_print_cut ppf () ; + pp_open_vbox ppf 0 ; + List.iter + (fun msg -> + pp_open_hovbox ppf 2 ; + pp_print_string ppf "* " ; + pp_print_text ppf msg ; + pp_close_box ppf () ; + pp_print_cut ppf ()) + !errors ; + pp_close_box ppf ()) + >>= fun () -> return_false + else return_true + in + check_proposals proposals >>=? fun all_valid -> + (if all_valid then cctxt#message "All proposals are valid." + else if force then + cctxt#message + "Some proposals are not valid, but `--force` was used." + else cctxt#error "Submission failed because of invalid proposals.") + >>= fun () -> + submit_proposals + ~dry_run + ~verbose_signing + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~src_sk + src_pkh + proposals + >>= function + | Ok _res -> return_unit + | Error errs -> + (match errs with + | [ + Unregistered_error + (`O [("kind", `String "generic"); ("error", `String msg)]); + ] -> + cctxt#message + "Error:@[@.%a@]" + Format.pp_print_text + (String.split_on_char ' ' msg + |> List.filter (function "" | "\n" -> false | _ -> true) + |> String.concat " " + |> String.map (function '\n' | '\t' -> ' ' | c -> c)) + | el -> cctxt#message "Error:@ %a" pp_print_trace el) + >>= fun () -> failwith "Failed to submit proposals")); + command + ~group + ~desc:"Submit a ballot" + (args2 verbose_signing_switch dry_run_switch) + (prefixes ["submit"; "ballot"; "for"] + @@ ContractAlias.destination_param + ~name:"delegate" + ~desc:"the delegate who votes" + @@ param + ~name:"proposal" + ~desc:"the protocol hash proposal to vote for" + (parameter (fun _ x -> + match Protocol_hash.of_b58check_opt x with + | None -> failwith "Invalid proposal hash: '%s'" x + | Some hash -> return hash)) + @@ param + ~name:"ballot" + ~desc:"the ballot value (yea/yay, nay, or pass)" + (parameter + ~autocomplete:(fun _ -> return ["yea"; "nay"; "pass"]) + (fun _ s -> + (* We should have [Vote.of_string]. *) + match String.lowercase_ascii s with + | "yay" | "yea" -> return Vote.Yay + | "nay" -> return Vote.Nay + | "pass" -> return Vote.Pass + | s -> failwith "Invalid ballot: '%s'" s)) + @@ stop) + (fun (verbose_signing, dry_run) + (_name, source) + proposal + ballot + (cctxt : Protocol_client_context.full) -> + match Contract.is_implicit source with + | None -> failwith "only implicit accounts can submit ballot" + | Some src_pkh -> + Client_keys.get_key cctxt src_pkh + >>=? fun (_src_name, _src_pk, src_sk) -> + get_period_info + (* Find period info of the successor, because the operation will + be injected on the next block at the earliest *) + ~successor:true + ~chain:cctxt#chain + ~block:cctxt#block + cctxt + >>=? fun info -> + (match info.current_period_kind with + | Exploration | Promotion -> return_unit + | _ -> cctxt#error "Not in Exploration or Promotion period") + >>=? fun () -> + submit_ballot + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~src_sk + src_pkh + ~verbose_signing + ~dry_run + proposal + ballot + >>=? fun _res -> return_unit); + command + ~group + ~desc:"Set the deposits limit of a registered delegate." + (args10 + fee_arg + dry_run_switch + verbose_signing_switch + simulate_switch + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["set"; "deposits"; "limit"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ prefix "to" + @@ tez_param + ~name:"deposits limit" + ~desc:"the maximum amount of frozen deposits" + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + simulation, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, contract) + limit + (cctxt : Protocol_client_context.full) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + match Contract.is_implicit contract with + | None -> + cctxt#error + "Cannot change deposits limit on contract %a. This operation is \ + invalid on originated contracts or unregistered delegate \ + contracts." + Contract.pp + contract + | Some mgr -> + Client_keys.get_key cctxt mgr >>=? fun (_, src_pk, manager_sk) -> + set_deposits_limit + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~simulation + ~fee_parameter + ?fee + mgr + ~src_pk + ~manager_sk + (Some limit) + >>=? fun _ -> return_unit); + command + ~group + ~desc:"Remove the deposits limit of a registered delegate." + (args10 + fee_arg + dry_run_switch + verbose_signing_switch + simulate_switch + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["unset"; "deposits"; "limit"; "for"] + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + simulation, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, contract) + (cctxt : Protocol_client_context.full) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + match Contract.is_implicit contract with + | None -> + cctxt#error + "Cannot change deposits limit on contract %a. This operation is \ + invalid on originated contracts or unregistered delegate \ + contracts." + Contract.pp + contract + | Some mgr -> + Client_keys.get_key cctxt mgr >>=? fun (_, src_pk, manager_sk) -> + set_deposits_limit + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~simulation + ~fee_parameter + ?fee + mgr + ~src_pk + ~manager_sk + None + >>=? fun _ -> return_unit); + ] + +let commands network () = + commands_rw () @ commands_network network () @ commands_ro () diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_contracts_commands.ml b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_contracts_commands.ml new file mode 100644 index 000000000000..e23e8ad821e2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_contracts_commands.ml @@ -0,0 +1,87 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Client_proto_contracts + +let group = + { + Clic.name = "contracts"; + title = "Commands for managing the record of known contracts"; + } + +let commands () = + let open Clic in + [ + command + ~group + ~desc:"Add a contract to the wallet." + (args1 (RawContractAlias.force_switch ())) + (prefixes ["remember"; "contract"] + @@ RawContractAlias.fresh_alias_param @@ RawContractAlias.source_param + @@ stop) + (fun force name hash cctxt -> + RawContractAlias.of_fresh cctxt force name >>=? fun name -> + RawContractAlias.add ~force cctxt name hash); + command + ~group + ~desc:"Remove a contract from the wallet." + no_options + (prefixes ["forget"; "contract"] @@ RawContractAlias.alias_param @@ stop) + (fun () (name, _) cctxt -> RawContractAlias.del cctxt name); + command + ~group + ~desc:"Lists all known contracts in the wallet." + no_options + (fixed ["list"; "known"; "contracts"]) + (fun () (cctxt : Protocol_client_context.full) -> + list_contracts cctxt >>=? fun contracts -> + List.iter_es + (fun (prefix, alias, contract) -> + cctxt#message + "%s%s: %s" + prefix + alias + (Contract.to_b58check contract) + >>= return) + contracts); + command + ~group + ~desc:"Forget the entire wallet of known contracts." + (args1 (RawContractAlias.force_switch ())) + (fixed ["forget"; "all"; "contracts"]) + (fun force cctxt -> + fail_unless force (error_of_fmt "this can only used with option -force") + >>=? fun () -> RawContractAlias.set cctxt []); + command + ~group + ~desc:"Display a contract from the wallet." + no_options + (prefixes ["show"; "known"; "contract"] + @@ RawContractAlias.alias_param @@ stop) + (fun () (_, contract) (cctxt : Protocol_client_context.full) -> + cctxt#message "%a\n%!" Contract.pp contract >>= fun () -> return_unit); + ] diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_fa12_commands.ml b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_fa12_commands.ml new file mode 100644 index 000000000000..fe6703bbb7fa --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_fa12_commands.ml @@ -0,0 +1,764 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Client_proto_args + +let group = + { + Clic.name = "tokens"; + title = "Commands for managing FA1.2-compatible smart contracts"; + } + +let alias_param = Client_proto_contracts.ContractAlias.destination_param + +let token_contract_param () = + alias_param + ~name:"contract" + ~desc:"name or address of the FA1.2-compatible contract" + +let from_param () = + alias_param ~name:"from" ~desc:"name or address of the sender" + +let to_param () = alias_param ~name:"to" ~desc:"name or address of the receiver" + +let amount_param () = + Clic.param + ~name:"amount" + ~desc:"number of tokens" + (Clic.parameter (fun _ s -> + try + let v = Z.of_string s in + assert (Compare.Z.(v >= Z.zero)) ; + return v + with _ -> failwith "invalid amount (must be a non-negative number)")) + +let tez_amount_arg = + tez_arg ~default:"0" ~parameter:"tez-amount" ~doc:"amount in \xEA\x9C\xA9" + +let as_arg = + Client_proto_contracts.ContractAlias.destination_arg + ~name:"as" + ~doc:"name or address of the caller of the contract" + () + +let payer_arg = + Client_proto_contracts.ContractAlias.destination_arg + ~name:"payer" + ~doc:"name of the payer (i.e. SOURCE) contract for the transaction" + () + +let callback_entrypoint_arg = + Clic.arg + ~doc:"Entrypoint the view should use to callback to" + ~long:"callback-entrypoint" + ~placeholder:"name" + string_parameter + +let contract_call_options = + Clic.args14 + tez_amount_arg + fee_arg + Client_proto_context_commands.dry_run_switch + Client_proto_context_commands.verbose_signing_switch + gas_limit_arg + storage_limit_arg + counter_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg + +let contract_view_options = + Clic.args15 + callback_entrypoint_arg + tez_amount_arg + fee_arg + Client_proto_context_commands.dry_run_switch + Client_proto_context_commands.verbose_signing_switch + gas_limit_arg + storage_limit_arg + counter_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg + +let view_options = + Clic.args3 + run_gas_limit_arg + payer_arg + (unparsing_mode_arg ~default:"Readable") + +let dummy_callback = Contract.implicit_contract Signature.Public_key_hash.zero + +let get_contract_caller_keys cctxt caller = + match Contract.is_implicit caller with + | None -> + failwith "only implicit accounts can be the source of a contract call" + | Some source -> + Client_keys.get_key cctxt source >>=? fun (_, caller_pk, caller_sk) -> + return (source, caller_pk, caller_sk) + +let commands_ro () : #Protocol_client_context.full Clic.command list = + Clic. + [ + command + ~group + ~desc:"Check that a contract is FA1.2-compatible." + no_options + (prefixes ["check"; "contract"] + @@ token_contract_param () + @@ prefixes ["implements"; "fa1.2"] + @@ stop) + (fun () (_, contract) (cctxt : #Protocol_client_context.full) -> + Client_proto_fa12.contract_has_fa12_interface + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + () + >>=? fun _ -> + Format.printf + "Contract %a has an FA1.2 interface.\n%!" + Contract.pp + contract ; + return_unit); + command + ~group + ~desc:"Ask for an address's balance offchain" + view_options + (prefixes ["from"; "fa1.2"; "contract"] + @@ token_contract_param () + @@ prefixes ["get"; "balance"; "for"] + @@ alias_param + ~name:"from" + ~desc: + "name or address of the account to lookup (also the source \ + contract)" + @@ stop) + (fun (gas, payer, unparsing_mode) + (_, contract) + (_, addr) + (cctxt : #Protocol_client_context.full) -> + let action = + Client_proto_fa12.Get_balance (addr, (dummy_callback, None)) + in + let payer = Option.map snd payer in + Client_proto_fa12.run_view_action + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + ~action + ~source:addr + ?gas + ?payer + ~unparsing_mode + () + >>= fun res -> Client_proto_programs.print_view_result cctxt res); + command + ~group + ~desc:"Ask for an address's allowance offchain" + view_options + (prefixes ["from"; "fa1.2"; "contract"] + @@ token_contract_param () + @@ prefixes ["get"; "allowance"; "on"] + @@ alias_param + ~name:"owner" + ~desc:"name or address of the account giving the allowance" + @@ prefix "as" + @@ alias_param + ~name:"operator" + ~desc:"name or address of the account receiving the allowance" + @@ stop) + (fun (gas, payer, unparsing_mode) + (_, contract) + (_, source) + (_, destination) + (cctxt : #Protocol_client_context.full) -> + let action = + Client_proto_fa12.Get_allowance + (source, destination, (dummy_callback, None)) + in + let payer = Option.map snd payer in + Client_proto_fa12.run_view_action + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + ~action + ~source + ?gas + ?payer + ~unparsing_mode + () + >>= fun res -> Client_proto_programs.print_view_result cctxt res); + command + ~group + ~desc:"Ask for the contract's total token supply offchain" + view_options + (prefixes ["from"; "fa1.2"; "contract"] + @@ token_contract_param () + @@ prefixes ["get"; "total"; "supply"] + @@ stop) + (fun (gas, payer, unparsing_mode) + (_, contract) + (cctxt : #Protocol_client_context.full) -> + let action = + Client_proto_fa12.Get_total_supply (dummy_callback, None) + in + let payer = Option.map snd payer in + Client_proto_fa12.run_view_action + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + ~action + ?gas + ?payer + ~unparsing_mode + () + >>= fun res -> Client_proto_programs.print_view_result cctxt res); + command + ~group + ~desc:"Ask for an address's balance using a callback contract" + contract_view_options + (prefixes ["from"; "fa1.2"; "contract"] + @@ token_contract_param () + @@ prefixes ["get"; "balance"; "for"] + @@ alias_param + ~name:"from" + ~desc: + "name or address of the account to lookup (also the source \ + contract)" + @@ prefixes ["callback"; "on"] + @@ alias_param + ~name:"callback" + ~desc:"name or address of the callback contract" + @@ stop) + (fun ( callback_entrypoint, + tez_amount, + fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, contract) + (_, addr) + (_, callback) + (cctxt : #Protocol_client_context.full) -> + get_contract_caller_keys cctxt addr + >>=? fun (source, src_pk, src_sk) -> + let action = + Client_proto_fa12.Get_balance (addr, (callback, callback_entrypoint)) + in + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_fa12.call_contract + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + ~action + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ?fee + ~source + ~src_pk + ~src_sk + ~tez_amount + ?gas_limit + ?storage_limit + ?counter + ~fee_parameter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= fun _ -> return_unit); + command + ~group + ~desc:"Ask for an address's allowance using a callback contract" + contract_view_options + (prefixes ["from"; "fa1.2"; "contract"] + @@ token_contract_param () + @@ prefixes ["get"; "allowance"; "on"] + @@ alias_param + ~name:"from" + ~desc:"name or address of the account giving the allowance" + @@ prefix "as" + @@ alias_param + ~name:"to" + ~desc:"name or address of the account receiving the allowance" + @@ prefixes ["callback"; "on"] + @@ alias_param + ~name:"callback" + ~desc:"name or address of the callback contract" + @@ stop) + (fun ( callback_entrypoint, + tez_amount, + fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, contract) + (_, src) + (_, dst) + (_, callback) + (cctxt : #Protocol_client_context.full) -> + get_contract_caller_keys cctxt src + >>=? fun (source, src_pk, src_sk) -> + let action = + Client_proto_fa12.Get_allowance + (src, dst, (callback, callback_entrypoint)) + in + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_fa12.call_contract + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + ~action + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ?fee + ~source + ~src_pk + ~src_sk + ~tez_amount + ?gas_limit + ?storage_limit + ?counter + ~fee_parameter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= fun _ -> return_unit); + command + ~group + ~desc: + "Ask for a contract's total token supply using a callback contract" + contract_view_options + (prefixes ["from"; "fa1.2"; "contract"] + @@ token_contract_param () + @@ prefixes ["get"; "total"; "supply"; "as"] + @@ alias_param + ~name:"from" + ~desc:"name or address of the source account" + @@ prefixes ["callback"; "on"] + @@ alias_param + ~name:"callback" + ~desc:"name or address of the callback contract" + @@ stop) + (fun ( callback_entrypoint, + tez_amount, + fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, contract) + (_, addr) + (_, callback) + (cctxt : #Protocol_client_context.full) -> + get_contract_caller_keys cctxt addr + >>=? fun (source, src_pk, src_sk) -> + let action = + Client_proto_fa12.Get_total_supply (callback, callback_entrypoint) + in + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_fa12.call_contract + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + ~action + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ?fee + ~source + ~src_pk + ~src_sk + ~tez_amount + ?gas_limit + ?storage_limit + ?counter + ~fee_parameter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= fun _ -> return_unit); + ] + +let commands_rw () : #Protocol_client_context.full Clic.command list = + let open Client_proto_args in + Clic. + [ + command + ~group + ~desc:"Transfer tokens between two given accounts" + (Clic.args15 + as_arg + tez_amount_arg + fee_arg + Client_proto_context_commands.dry_run_switch + Client_proto_context_commands.verbose_signing_switch + gas_limit_arg + storage_limit_arg + counter_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["from"; "fa1.2"; "contract"] + @@ token_contract_param () @@ prefix "transfer" @@ amount_param () + @@ prefix "from" @@ from_param () @@ prefix "to" @@ to_param () @@ stop + ) + (fun ( as_address, + tez_amount, + fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, contract) + amount + src + (_, dst) + (cctxt : #Protocol_client_context.full) -> + let (_, caller) = Option.value ~default:src as_address in + get_contract_caller_keys cctxt caller + >>=? fun (source, caller_pk, caller_sk) -> + let action = Client_proto_fa12.Transfer (snd src, dst, amount) in + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_fa12.call_contract + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + ~action + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ?fee + ~source + ~src_pk:caller_pk + ~src_sk:caller_sk + ~tez_amount + ?gas_limit + ?storage_limit + ?counter + ~fee_parameter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= fun _ -> return_unit); + command + ~group + ~desc:"Allow account to transfer an amount of token" + contract_call_options + (prefixes ["from"; "fa1.2"; "contract"] + @@ token_contract_param () @@ prefix "as" + @@ alias_param ~name:"as" ~desc:"name or address of the sender" + @@ prefix "approve" @@ amount_param () @@ prefix "from" + @@ alias_param + ~name:"from" + ~desc:"name or address to approve withdrawal" + @@ stop) + (fun ( tez_amount, + fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, contract) + (_, source) + amount + (_, dst) + (cctxt : #Protocol_client_context.full) -> + get_contract_caller_keys cctxt source + >>=? fun (source, src_pk, src_sk) -> + let action = Client_proto_fa12.Approve (dst, amount) in + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_fa12.call_contract + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract + ~action + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ?fee + ~source + ~src_pk + ~src_sk + ~tez_amount + ?gas_limit + ?storage_limit + ?counter + ~fee_parameter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= fun _ -> return_unit); + command + ~group + ~desc: + "Execute multiple token transfers from a single source account. If \ + one of the token transfers fails, none of them are executed." + (args14 + default_fee_arg + as_arg + Client_proto_context_commands.dry_run_switch + Client_proto_context_commands.verbose_signing_switch + default_gas_limit_arg + default_storage_limit_arg + counter_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["multiple"; "fa1.2"; "transfers"; "from"] + @@ alias_param + ~name:"src" + ~desc:"name or address of the source of the transfers" + @@ prefix "using" + @@ param + ~name:"transfers.json" + ~desc: + (Format.sprintf + "List of token transfers to inject from the source contract \ + in JSON format (as a file or string). The JSON must be an \ + array of objects of the form: '[ {\"token_contract\": \ + address or alias, \"destination\": address or alias, \ + \"amount\": non-negative integer (, : ...) } \ + (, ...) ]', where an optional can either be \ + \"tez-amount\", \"fee\", \"gas-limit\" or \ + \"storage-limit\". The complete schema can be inspected via \ + `tezos-codec describe %s.fa1.2.token_transfer json schema`." + Protocol.name) + Client_proto_context_commands.json_file_or_text_parameter + @@ stop) + (fun ( fee, + as_address, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + src + operations_json + cctxt -> + let (_, caller) = Option.value ~default:src as_address in + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + match + Data_encoding.Json.destruct + (Data_encoding.list Client_proto_fa12.token_transfer_encoding) + operations_json + with + | [] -> failwith "Empty operation list" + | operations -> + get_contract_caller_keys cctxt caller + >>=? fun (source, src_pk, src_sk) -> + Client_proto_fa12.inject_token_transfer_batch + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~sender:(snd src) + ~source + ~src_pk + ~src_sk + ~token_transfers:operations + ~fee_parameter + ?counter + ?default_fee:fee + ?default_gas_limit:gas_limit + ?default_storage_limit:storage_limit + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"multiple transfers simulation failed" + cctxt + >>= fun _ -> return_unit + | exception (Data_encoding.Json.Cannot_destruct (path, exn2) as exn) + -> ( + match (path, operations_json) with + | ([`Index n], `A lj) -> ( + match List.nth_opt lj n with + | Some j -> + failwith + "Invalid transfer at index %i: %a %a" + n + (fun ppf -> Data_encoding.Json.print_error ppf) + exn2 + Data_encoding.Json.pp + j + | _ -> + failwith + "Invalid transfer at index %i: %a" + n + (fun ppf -> Data_encoding.Json.print_error ppf) + exn2) + | _ -> + failwith + "Invalid transfer file: %a %a" + (fun ppf -> Data_encoding.Json.print_error ppf) + exn + Data_encoding.Json.pp + operations_json)); + ] + +let commands () = commands_ro () @ commands_rw () diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_mockup_commands.ml b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_mockup_commands.ml new file mode 100644 index 000000000000..47c00a38eebf --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_mockup_commands.ml @@ -0,0 +1,81 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Tezos_clic + +let protocol_constants_arg = + Clic.arg + ~doc:"a JSON file that contains protocol constants to set." + ~long:"protocol-constants" + ~placeholder:"path" + (Clic.parameter (fun _ x -> return x)) + +let bootstrap_accounts_arg = + Clic.arg + ~doc: + "a JSON file that contains definitions of bootstrap accounts to create." + ~long:"bootstrap-accounts" + ~placeholder:"path" + (Clic.parameter (fun _ x -> return x)) + +let asynchronous_flag = + Clic.switch + ~long:"asynchronous" + ~doc:"put operations in mempool and require baking to include in the chain" + () + +let load_json_file (cctxt : Protocol_client_context.full) json_file = + match json_file with + | None -> return None + | Some filename -> + cctxt#read_file filename >>=? fun json_string -> + return (Some (Ezjsonm.from_string json_string :> Data_encoding.json)) + +let create_mockup_command_handler + (constants_overrides_file, bootstrap_accounts_file, asynchronous) + (cctxt : Protocol_client_context.full) = + load_json_file cctxt constants_overrides_file + >>=? fun constants_overrides_json -> + load_json_file cctxt bootstrap_accounts_file + >>=? fun bootstrap_accounts_json -> + Tezos_mockup.Persistence.create_mockup + ~cctxt:(cctxt :> Tezos_client_base.Client_context.full) + ~protocol_hash:Protocol.hash + ~constants_overrides_json + ~bootstrap_accounts_json + ~asynchronous + >>=? fun () -> + Tezos_mockup_commands.Mockup_wallet.populate cctxt bootstrap_accounts_file + +let create_mockup_command : Protocol_client_context.full Clic.command = + let open Clic in + command + ~group:Tezos_mockup_commands.Mockup_commands.group + ~desc:"Create a mockup environment." + (args3 protocol_constants_arg bootstrap_accounts_arg asynchronous_flag) + (prefixes ["create"; "mockup"] @@ stop) + create_mockup_command_handler + +let commands () = [create_mockup_command] diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_mockup_commands.mli b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_mockup_commands.mli new file mode 100644 index 000000000000..765437d4365e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_mockup_commands.mli @@ -0,0 +1,26 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_multisig_commands.ml b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_multisig_commands.ml new file mode 100644 index 000000000000..db58555539ee --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_multisig_commands.ml @@ -0,0 +1,1136 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Client_proto_args +open Tezos_micheline + +let group = + { + Clic.name = "multisig"; + title = "Commands for managing a multisig smart contract"; + } + +let threshold_param () = + Clic.param + ~name:"threshold" + ~desc:"Number of required signatures" + Client_proto_args.int_parameter + +let public_key_param () = + Client_keys.Public_key.source_param + ~name:"key" + ~desc:"Each signer of the multisig contract" + +let secret_key_param () = + Client_keys.Secret_key.source_param + ~name:"key" + ~desc: + "Secret key corresponding to one of the public keys stored on the \ + multisig contract" + +let signature_param () = + Clic.param + ~name:"signature" + ~desc:"Each signer of the multisig contract" + Client_proto_args.signature_parameter + +let lambda_param () = + Clic.param + ~name:"lambda" + ~desc:"the lambda to execute, of type lambda unit (list operation)" + string_parameter + +let bytes_only_switch = + Clic.switch + ~long:"bytes-only" + ~doc:"return only the byte sequence to be signed" + () + +let bytes_param ~name ~desc = + Clic.param ~name ~desc Client_proto_args.bytes_parameter + +let transfer_options = + Clic.args15 + Client_proto_args.fee_arg + Client_proto_context_commands.dry_run_switch + Client_proto_context_commands.verbose_signing_switch + Client_proto_args.gas_limit_arg + Client_proto_args.storage_limit_arg + Client_proto_args.counter_arg + Client_proto_args.arg_arg + Client_proto_args.no_print_source_flag + Client_proto_args.minimal_fees_arg + Client_proto_args.minimal_nanotez_per_byte_arg + Client_proto_args.minimal_nanotez_per_gas_unit_arg + Client_proto_args.force_low_fee_arg + Client_proto_args.fee_cap_arg + Client_proto_args.burn_cap_arg + Client_proto_args.entrypoint_arg + +let non_transfer_options = + Clic.args13 + Client_proto_args.fee_arg + Client_proto_context_commands.dry_run_switch + Client_proto_context_commands.verbose_signing_switch + Client_proto_args.gas_limit_arg + Client_proto_args.storage_limit_arg + Client_proto_args.counter_arg + Client_proto_args.no_print_source_flag + Client_proto_args.minimal_fees_arg + Client_proto_args.minimal_nanotez_per_byte_arg + Client_proto_args.minimal_nanotez_per_gas_unit_arg + Client_proto_args.force_low_fee_arg + Client_proto_args.fee_cap_arg + Client_proto_args.burn_cap_arg + +let prepare_command_display prepared_command bytes_only = + if bytes_only then + Format.printf + "0x%a@." + Hex.pp + (Hex.of_bytes prepared_command.Client_proto_multisig.bytes) + else + Format.printf + "%a@.%a@.%a@.%a@." + (fun ppf x -> + Format.fprintf ppf "Bytes to sign: '0x%a'" Hex.pp (Hex.of_bytes x)) + prepared_command.Client_proto_multisig.bytes + (fun ppf x -> + Format.fprintf + ppf + "Blake 2B Hash: '%s'" + (Base58.raw_encode Blake2B.(hash_bytes [x] |> to_string))) + prepared_command.Client_proto_multisig.bytes + (fun ppf z -> + Format.fprintf + ppf + "Threshold (number of signatures required): %s" + (Z.to_string z)) + prepared_command.Client_proto_multisig.threshold + (fun ppf -> + Format.fprintf + ppf + "@[<2>Public keys of the signers:@ %a@]" + (Format.pp_print_list + ~pp_sep:(fun ppf () -> Format.fprintf ppf "@ ") + Signature.Public_key.pp)) + prepared_command.Client_proto_multisig.keys + +let get_parameter_type (cctxt : #Protocol_client_context.full) ~destination + ~entrypoint = + match Contract.is_implicit destination with + | Some _ -> + let open Micheline in + return @@ strip_locations @@ Prim (0, Script.T_unit, [], []) + | None -> ( + Michelson_v1_entrypoints.contract_entrypoint_type + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~contract:destination + ~entrypoint + >>=? function + | None -> + cctxt#error + "Contract %a has no entrypoint named %s" + Contract.pp + destination + entrypoint + | Some parameter_type -> return parameter_type) + +let commands_ro () : #Protocol_client_context.full Clic.command list = + Clic. + [ + command + ~group + ~desc:"Show the hashes of the supported multisig contracts." + no_options + (fixed ["show"; "supported"; "multisig"; "hashes"]) + (fun () _cctxt -> + Format.printf "Hashes of supported multisig contracts:@." ; + List.iter + (fun h -> Format.printf "%a@." Script_expr_hash.pp h) + Client_proto_multisig.known_multisig_hashes ; + return_unit); + command + ~group + ~desc:"Show the script of the recommended multisig contract." + no_options + (fixed ["show"; "multisig"; "script"]) + (fun () _cctxt -> + let {Michelson_v1_parser.source; _} = + Michelson_v1_printer.unparse_toplevel + Client_proto_multisig.multisig_script + in + Format.printf "%s@." source ; + return_unit); + ] + +let commands_rw () : #Protocol_client_context.full Clic.command list = + Clic. + [ + command + ~group + ~desc:"Originate a new multisig contract." + (args14 + Client_proto_args.fee_arg + Client_proto_context_commands.dry_run_switch + Client_proto_args.gas_limit_arg + Client_proto_args.storage_limit_arg + Client_proto_args.delegate_arg + (Client_keys.force_switch ()) + Client_proto_args.no_print_source_flag + Client_proto_args.minimal_fees_arg + Client_proto_args.minimal_nanotez_per_byte_arg + Client_proto_args.minimal_nanotez_per_gas_unit_arg + Client_proto_args.force_low_fee_arg + Client_proto_args.fee_cap_arg + Client_proto_context_commands.verbose_signing_switch + Client_proto_args.burn_cap_arg) + (prefixes ["deploy"; "multisig"] + @@ Client_proto_contracts.RawContractAlias.fresh_alias_param + ~name:"new_multisig" + ~desc:"name of the new multisig contract" + @@ prefix "transferring" + @@ Client_proto_args.tez_param + ~name:"qty" + ~desc:"amount taken from source" + @@ prefix "from" + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"src" + ~desc:"name of the source contract" + @@ prefixes ["with"; "threshold"] + @@ threshold_param () + @@ prefixes ["on"; "public"; "keys"] + @@ seq_of_param (public_key_param ())) + (fun ( fee, + dry_run, + gas_limit, + storage_limit, + delegate, + force, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + verbose_signing, + burn_cap ) + alias_name + balance + (_, source) + threshold + keys + (cctxt : #Protocol_client_context.full) -> + Client_proto_contracts.RawContractAlias.of_fresh + cctxt + force + alias_name + >>=? fun alias_name -> + match Contract.is_implicit source with + | None -> + failwith + "only implicit accounts can be the source of an origination" + | Some source -> ( + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + List.map_es + (fun (pk_uri, _) -> Client_keys.public_key pk_uri) + keys + >>=? fun keys -> + Client_proto_multisig.originate_multisig + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ?fee + ?gas_limit + ?storage_limit + ~verbose_signing + ~delegate + ~threshold:(Z.of_int threshold) + ~keys + ~balance + ~source + ~src_pk + ~src_sk + ~fee_parameter + () + >>= fun errors -> + Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"multisig origination simulation failed" + cctxt + errors + >>= function + | None -> return_unit + | Some (_res, contract) -> + if dry_run then return_unit + else + Client_proto_context.save_contract + ~force + cctxt + alias_name + contract + >>=? fun () -> return_unit)); + command + ~group + ~desc:"Sign a transaction for a multisig contract." + (args2 arg_arg entrypoint_arg) + (prefixes ["sign"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefix "transferring" + @@ Client_proto_args.tez_param + ~name:"qty" + ~desc:"amount taken from source" + @@ prefix "to" + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"dst" + ~desc:"name/literal of the destination contract" + @@ prefixes ["using"; "secret"; "key"] + @@ secret_key_param () @@ stop) + (fun (parameter, entrypoint) + (_, multisig_contract) + amount + (_, destination) + sk + (cctxt : #Protocol_client_context.full) -> + let entrypoint = Option.value ~default:"default" entrypoint in + let parameter = Option.value ~default:"Unit" parameter in + Lwt.return @@ Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression parameter + >>=? fun {expanded = parameter; _} -> + get_parameter_type cctxt ~destination ~entrypoint + >>=? fun parameter_type -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action: + (Client_proto_multisig.Transfer + {amount; destination; entrypoint; parameter_type; parameter}) + () + >>=? fun prepared_command -> + Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> + return @@ Format.printf "%a@." Signature.pp signature); + command + ~group + ~desc:"Sign a lambda for a generic multisig contract." + no_options + (prefixes ["sign"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["running"; "lambda"] + @@ lambda_param () + @@ prefixes ["using"; "secret"; "key"] + @@ secret_key_param () @@ stop) + (fun () + (_, multisig_contract) + lambda + sk + (cctxt : #Protocol_client_context.full) -> + Lwt.return @@ Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression lambda + >>=? fun {expanded = lambda; _} -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action:(Lambda lambda) + () + >>=? fun prepared_command -> + Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> + return @@ Format.printf "%a@." Signature.pp signature); + command + ~group + ~desc:"Sign a delegate change for a multisig contract." + no_options + (prefixes ["sign"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["setting"; "delegate"; "to"] + @@ Client_keys.Public_key_hash.source_param + ~name:"dlgt" + ~desc:"new delegate of the new multisig contract" + @@ prefixes ["using"; "secret"; "key"] + @@ secret_key_param () @@ stop) + (fun () + (_, multisig_contract) + delegate + sk + (cctxt : #Protocol_client_context.full) -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action:(Client_proto_multisig.Change_delegate (Some delegate)) + () + >>=? fun prepared_command -> + Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> + return @@ Format.printf "%a@." Signature.pp signature); + command + ~group + ~desc:"Sign a delegate withdraw for a multisig contract." + no_options + (prefixes ["sign"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["withdrawing"; "delegate"] + @@ prefixes ["using"; "secret"; "key"] + @@ secret_key_param () @@ stop) + (fun () + (_, multisig_contract) + sk + (cctxt : #Protocol_client_context.full) -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action:(Client_proto_multisig.Change_delegate None) + () + >>=? fun prepared_command -> + Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> + return @@ Format.printf "%a@." Signature.pp signature); + command + ~group + ~desc: + "Sign a change of public keys and threshold for a multisig contract." + no_options + (prefixes ["sign"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["using"; "secret"; "key"] + @@ secret_key_param () + @@ prefixes ["setting"; "threshold"; "to"] + @@ threshold_param () + @@ prefixes ["and"; "public"; "keys"; "to"] + @@ seq_of_param (public_key_param ())) + (fun () + (_, multisig_contract) + sk + new_threshold + new_keys + (cctxt : #Protocol_client_context.full) -> + List.map_es + (fun (pk_uri, _) -> Client_keys.public_key pk_uri) + new_keys + >>=? fun keys -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action: + (Client_proto_multisig.Change_keys (Z.of_int new_threshold, keys)) + () + >>=? fun prepared_command -> + Client_keys.sign cctxt sk prepared_command.bytes >>=? fun signature -> + return @@ Format.printf "%a@." Signature.pp signature); + command + ~group + ~desc:"Transfer tokens using a multisig contract." + transfer_options + (prefixes ["from"; "multisig"; "contract"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name/literal of the multisig contract" + @@ prefix "transfer" + @@ Client_proto_args.tez_param + ~name:"qty" + ~desc:"amount taken from the multisig contract" + @@ prefix "to" + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"dst" + ~desc:"name/literal of the destination contract" + @@ prefixes ["on"; "behalf"; "of"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"src" + ~desc:"source calling the multisig contract" + @@ prefixes ["with"; "signatures"] + @@ seq_of_param (signature_param ())) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + parameter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap, + entrypoint ) + (_, multisig_contract) + amount + (_, destination) + (_, source) + signatures + (cctxt : #Protocol_client_context.full) -> + let entrypoint = Option.value ~default:"default" entrypoint in + let parameter = Option.value ~default:"Unit" parameter in + Lwt.return @@ Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression parameter + >>=? fun {expanded = parameter; _} -> + get_parameter_type cctxt ~destination ~entrypoint + >>=? fun parameter_type -> + match Contract.is_implicit source with + | None -> + failwith + "only implicit accounts can be the source of a contract call" + | Some source -> ( + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_multisig.call_multisig + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~fee_parameter + ~source + ?fee + ~src_pk + ~src_sk + ~multisig_contract + ~action: + (Client_proto_multisig.Transfer + { + amount; + destination; + entrypoint; + parameter_type; + parameter; + }) + ~signatures + ~amount:Tez.zero + ?gas_limit + ?storage_limit + ?counter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit)); + command + ~group + ~desc:"Run a lambda on a generic multisig contract." + non_transfer_options + (prefixes ["from"; "multisig"; "contract"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name/literal of the multisig contract" + @@ prefixes ["run"; "lambda"] + @@ lambda_param () + @@ prefixes ["on"; "behalf"; "of"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"src" + ~desc:"source calling the multisig contract" + @@ prefixes ["with"; "signatures"] + @@ seq_of_param (signature_param ())) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, multisig_contract) + lambda + (_, source) + signatures + (cctxt : #Protocol_client_context.full) -> + match Contract.is_implicit source with + | None -> + failwith + "only implicit accounts can be the source of a contract call" + | Some source -> ( + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Lwt.return @@ Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression lambda + >>=? fun {expanded = lambda; _} -> + Client_proto_multisig.call_multisig + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~fee_parameter + ~source + ?fee + ~src_pk + ~src_sk + ~multisig_contract + ~action:(Client_proto_multisig.Lambda lambda) + ~signatures + ~amount:Tez.zero + ?gas_limit + ?storage_limit + ?counter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit)); + command + ~group + ~desc:"Change the delegate of a multisig contract." + non_transfer_options + (prefixes ["set"; "delegate"; "of"; "multisig"; "contract"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefix "to" + @@ Client_keys.Public_key_hash.source_param + ~name:"dlgt" + ~desc:"new delegate of the new multisig contract" + @@ prefixes ["on"; "behalf"; "of"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"src" + ~desc:"source calling the multisig contract" + @@ prefixes ["with"; "signatures"] + @@ seq_of_param (signature_param ())) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, multisig_contract) + delegate + (_, source) + signatures + (cctxt : #Protocol_client_context.full) -> + match Contract.is_implicit source with + | None -> + failwith + "only implicit accounts can be the source of a contract call" + | Some source -> ( + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_multisig.call_multisig + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~fee_parameter + ~source + ?fee + ~src_pk + ~src_sk + ~multisig_contract + ~action:(Client_proto_multisig.Change_delegate (Some delegate)) + ~signatures + ~amount:Tez.zero + ?gas_limit + ?storage_limit + ?counter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit)); + command + ~group + ~desc:"Withdraw the delegate of a multisig contract." + non_transfer_options + (prefixes ["withdraw"; "delegate"; "of"; "multisig"; "contract"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["on"; "behalf"; "of"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"src" + ~desc:"source calling the multisig contract" + @@ prefixes ["with"; "signatures"] + @@ seq_of_param (signature_param ())) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, multisig_contract) + (_, source) + signatures + (cctxt : #Protocol_client_context.full) -> + match Contract.is_implicit source with + | None -> + failwith + "only implicit accounts can be the source of a contract call" + | Some source -> ( + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_multisig.call_multisig + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~fee_parameter + ~source + ?fee + ~src_pk + ~src_sk + ~multisig_contract + ~action:(Client_proto_multisig.Change_delegate None) + ~signatures + ~amount:Tez.zero + ?gas_limit + ?storage_limit + ?counter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit)); + command + ~group + ~desc:"Change public keys and threshold for a multisig contract." + non_transfer_options + (prefixes ["set"; "threshold"; "of"; "multisig"; "contract"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["to"] + @@ threshold_param () + @@ prefixes ["and"; "public"; "keys"; "to"] + @@ non_terminal_seq (public_key_param ()) ~suffix:["on"; "behalf"; "of"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"src" + ~desc:"source calling the multisig contract" + @@ prefixes ["with"; "signatures"] + @@ seq_of_param (signature_param ())) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + (_, multisig_contract) + new_threshold + new_keys + (_, source) + signatures + (cctxt : #Protocol_client_context.full) -> + match Contract.is_implicit source with + | None -> + failwith + "only implicit accounts can be the source of a contract call" + | Some source -> ( + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + List.map_es + (fun (pk_uri, _) -> Client_keys.public_key pk_uri) + new_keys + >>=? fun keys -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_multisig.call_multisig + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~fee_parameter + ~source + ?fee + ~src_pk + ~src_sk + ~multisig_contract + ~action: + (Client_proto_multisig.Change_keys + (Z.of_int new_threshold, keys)) + ~signatures + ~amount:Tez.zero + ?gas_limit + ?storage_limit + ?counter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit)); + (* This command is no longer necessary as Clic now supports non terminal + lists of parameters, however, it is kept for compatibility. *) + command + ~group + ~desc: + "Run a transaction described by a sequence of bytes on a multisig \ + contract." + non_transfer_options + (prefixes ["run"; "transaction"] + @@ bytes_param + ~name:"bytes" + ~desc: + "the sequence of bytes to deserialize as a multisig action, can \ + be obtained by one of the \"prepare multisig transaction\" \ + commands" + @@ prefixes ["on"; "multisig"; "contract"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["on"; "behalf"; "of"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"src" + ~desc:"source calling the multisig contract" + @@ prefixes ["with"; "signatures"] + @@ seq_of_param (signature_param ())) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + bytes + (_, multisig_contract) + (_, source) + signatures + (cctxt : #Protocol_client_context.full) -> + match Contract.is_implicit source with + | None -> + failwith + "only implicit accounts can be the source of a contract call" + | Some source -> ( + Client_keys.get_key cctxt source >>=? fun (_, src_pk, src_sk) -> + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_multisig.call_multisig_on_bytes + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ?confirmations:cctxt#confirmations + ~dry_run + ~verbose_signing + ~fee_parameter + ~source + ?fee + ~src_pk + ~src_sk + ~multisig_contract + ~bytes + ~signatures + ~amount:Tez.zero + ?gas_limit + ?storage_limit + ?counter + () + >>= Client_proto_context_commands.report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit)); + command + ~group + ~desc: + "Display the threshold, public keys, and byte sequence to sign for a \ + multisigned transfer." + (args3 bytes_only_switch arg_arg entrypoint_arg) + (prefixes ["prepare"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefix "transferring" + @@ Client_proto_args.tez_param + ~name:"qty" + ~desc:"amount taken from source" + @@ prefix "to" + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"dst" + ~desc:"name/literal of the destination contract" + @@ stop) + (fun (bytes_only, parameter, entrypoint) + (_, multisig_contract) + amount + (_, destination) + (cctxt : #Protocol_client_context.full) -> + let entrypoint = Option.value ~default:"default" entrypoint in + let parameter = Option.value ~default:"Unit" parameter in + Lwt.return @@ Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression parameter + >>=? fun {expanded = parameter; _} -> + get_parameter_type cctxt ~destination ~entrypoint + >>=? fun parameter_type -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action: + (Client_proto_multisig.Transfer + {amount; destination; entrypoint; parameter_type; parameter}) + () + >>=? fun prepared_command -> + return @@ prepare_command_display prepared_command bytes_only); + command + ~group + ~desc: + "Display the threshold, public keys, and byte sequence to sign for a \ + multisigned lambda execution in a generic multisig contract." + (args1 bytes_only_switch) + (prefixes ["prepare"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["running"; "lambda"] + @@ lambda_param () @@ stop) + (fun bytes_only + (_, multisig_contract) + lambda + (cctxt : #Protocol_client_context.full) -> + Lwt.return @@ Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression lambda + >>=? fun {expanded = lambda; _} -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action:(Client_proto_multisig.Lambda lambda) + () + >>=? fun prepared_command -> + return @@ prepare_command_display prepared_command bytes_only); + command + ~group + ~desc: + "Display the threshold, public keys, and byte sequence to sign for a \ + multisigned delegate change." + (args1 bytes_only_switch) + (prefixes ["prepare"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["setting"; "delegate"; "to"] + @@ Client_keys.Public_key_hash.source_param + ~name:"dlgt" + ~desc:"new delegate of the new multisig contract" + @@ stop) + (fun bytes_only + (_, multisig_contract) + new_delegate + (cctxt : #Protocol_client_context.full) -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action:(Client_proto_multisig.Change_delegate (Some new_delegate)) + () + >>=? fun prepared_command -> + return @@ prepare_command_display prepared_command bytes_only); + command + ~group + ~desc: + "Display the threshold, public keys, and byte sequence to sign for a \ + multisigned delegate withdraw." + (args1 bytes_only_switch) + (prefixes ["prepare"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["withdrawing"; "delegate"] + @@ stop) + (fun bytes_only + (_, multisig_contract) + (cctxt : #Protocol_client_context.full) -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action:(Client_proto_multisig.Change_delegate None) + () + >>=? fun prepared_command -> + return @@ prepare_command_display prepared_command bytes_only); + command + ~group + ~desc: + "Display the threshold, public keys, and byte sequence to sign for a \ + multisigned change of keys and threshold." + (args1 bytes_only_switch) + (prefixes ["prepare"; "multisig"; "transaction"; "on"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"multisig" + ~desc:"name or address of the originated multisig contract" + @@ prefixes ["setting"; "threshold"; "to"] + @@ threshold_param () + @@ prefixes ["and"; "public"; "keys"; "to"] + @@ seq_of_param (public_key_param ())) + (fun bytes_only + (_, multisig_contract) + new_threshold + new_keys + (cctxt : #Protocol_client_context.full) -> + List.map_es + (fun (pk_uri, _) -> Client_keys.public_key pk_uri) + new_keys + >>=? fun keys -> + Client_proto_multisig.prepare_multisig_transaction + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~multisig_contract + ~action: + (Client_proto_multisig.Change_keys (Z.of_int new_threshold, keys)) + () + >>=? fun prepared_command -> + return @@ prepare_command_display prepared_command bytes_only); + ] + +let commands () = commands_ro () @ commands_rw () diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_multisig_commands.mli b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_multisig_commands.mli new file mode 100644 index 000000000000..c328ace47c3f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_multisig_commands.mli @@ -0,0 +1,26 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_programs_commands.ml b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_programs_commands.ml new file mode 100644 index 000000000000..e0bc75fb83ab --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_programs_commands.ml @@ -0,0 +1,966 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +let group = + { + Clic.name = "scripts"; + title = "Commands for managing the library of known scripts"; + } + +open Tezos_micheline +open Client_proto_programs +open Client_proto_args +open Client_proto_contracts + +let safe_decode_json (cctxt : Protocol_client_context.full) encoding json = + match Data_encoding.Json.destruct encoding json with + | exception Data_encoding.Json.Cannot_destruct (_, exc) -> + cctxt#error + "could not decode json (%a)" + (Data_encoding.Json.print_error ~print_unknown:(fun fmt exc -> + Format.fprintf fmt "%s" (Printexc.to_string exc))) + exc + | exception ((Stack_overflow | Out_of_memory) as exc) -> raise exc + | exception exc -> + cctxt#error "could not decode json (%s)" (Printexc.to_string exc) + | expr -> return expr + +let commands () = + let open Clic in + let show_types_switch = + switch + ~long:"details" + ~short:'v' + ~doc:"show the types of each instruction" + () + in + let emacs_mode_switch = + switch + ~long:"emacs" + ?short:None + ~doc:"output in `michelson-mode.el` compatible format" + () + in + let trace_stack_switch = + switch ~long:"trace-stack" ~doc:"show the stack after each step" () + in + let zero_loc_switch = + switch ~short:'z' ~long:"zero-loc" ~doc:"replace location with \"0\"" () + in + let legacy_switch = + switch + ~long:"legacy" + ~doc:"typecheck in legacy mode as if the data was taken from the chain" + () + in + let amount_arg = + Client_proto_args.tez_arg + ~parameter:"amount" + ~doc:"amount of the transfer in \xEA\x9C\xA9" + ~default:"0.05" + in + let source_arg = + ContractAlias.destination_arg + ~name:"source" + ~doc:"name of the source (i.e. SENDER) contract for the transaction" + () + in + let payer_arg = + ContractAlias.destination_arg + ~name:"payer" + ~doc:"name of the payer (i.e. SOURCE) contract for the transaction" + () + in + let balance_arg = + Client_proto_args.tez_arg + ~parameter:"balance" + ~doc:"balance of run contract in \xEA\x9C\xA9" + ~default:"4_000_000" + in + let now_arg = Client_proto_args.now_arg in + let level_arg = Client_proto_args.level_arg in + let resolve_max_gas cctxt block = function + | None -> + Alpha_services.Constants.all cctxt (cctxt#chain, block) + >>=? fun {parametric = {hard_gas_limit_per_operation; _}; _} -> + return hard_gas_limit_per_operation + | Some gas -> return gas + in + let parse_expr expr = + Lwt.return @@ Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression expr + in + let data_type_arg = + arg + ~doc:"the given data will be type-checked against this type" + ~short:'t' + ~long:"type" + ~placeholder:"unit" + data_parameter + in + let bytes_parameter ~name ~desc = + param ~name ~desc Client_proto_args.bytes_parameter + in + let signature_parameter = + parameter (fun _cctxt s -> + match Signature.of_b58check_opt s with + | Some s -> return s + | None -> failwith "Not given a valid signature") + in + let convert_input_format_param = + param + ~name:"input_format" + ~desc:"format of the input for conversion" + (parameter + ~autocomplete:(fun _ -> return ["michelson"; "json"; "binary"]) + (fun _ s -> + match String.lowercase_ascii s with + | "michelson" -> return `Michelson + | "json" -> return `JSON + | "binary" -> return `Binary + | _ -> + failwith + "invalid input format, expecting one of \"michelson\", \ + \"json\" or \"binary\".")) + in + let convert_output_format_param = + param + ~name:"output_format" + ~desc:"format of the conversion output" + (parameter + ~autocomplete:(fun _ -> + return ["michelson"; "json"; "binary"; "ocaml"]) + (fun _ s -> + match String.lowercase_ascii s with + | "michelson" -> return `Michelson + | "json" -> return `JSON + | "binary" -> return `Binary + | "ocaml" -> return `OCaml + | _ -> + failwith + "invalid output format, expecting one of \"michelson\", \ + \"json\", \"binary\" or \"ocaml\".")) + in + let file_or_literal_param () = + param + ~name:"source" + ~desc:"literal or a path to a file" + (parameter (fun cctxt s -> + cctxt#read_file s >>= function + | Ok v -> return (Some s, v) + | Error _ -> return (None, s))) + in + let handle_parsing_error label (cctxt : Protocol_client_context.full) + (emacs_mode, no_print_source) program body = + match program with + | (program, []) -> body program + | res_with_errors when emacs_mode -> + cctxt#message + "(@[(%s . ())@ (errors . %a)@])" + label + Michelson_v1_emacs.report_errors + res_with_errors + >>= fun () -> return_unit + | (parsed, errors) -> + cctxt#message + "%a" + (fun ppf () -> + Michelson_v1_error_reporter.report_errors + ~details:(not no_print_source) + ~parsed + ~show_source:(not no_print_source) + ppf + errors) + () + >>= fun () -> cctxt#error "syntax error in program" + in + [ + command + ~group + ~desc:"Lists all scripts in the library." + no_options + (fixed ["list"; "known"; "scripts"]) + (fun () (cctxt : Protocol_client_context.full) -> + Program.load cctxt >>=? fun list -> + List.iter_s (fun (n, _) -> cctxt#message "%s" n) list >>= fun () -> + return_unit); + command + ~group + ~desc:"Add a script to the library." + (args1 (Program.force_switch ())) + (prefixes ["remember"; "script"] + @@ Program.fresh_alias_param @@ Program.source_param @@ stop) + (fun force name hash cctxt -> + Program.of_fresh cctxt force name >>=? fun name -> + Program.add ~force cctxt name hash); + command + ~group + ~desc:"Remove a script from the library." + no_options + (prefixes ["forget"; "script"] @@ Program.alias_param @@ stop) + (fun () (name, _) cctxt -> Program.del cctxt name); + command + ~group + ~desc:"Display a script from the library." + no_options + (prefixes ["show"; "known"; "script"] @@ Program.alias_param @@ stop) + (fun () (_, program) (cctxt : Protocol_client_context.full) -> + Program.to_source program >>=? fun source -> + cctxt#message "%s\n" source >>= fun () -> return_unit); + command + ~group + ~desc:"Ask the node to run a script." + (args11 + trace_stack_switch + amount_arg + balance_arg + source_arg + payer_arg + no_print_source_flag + run_gas_limit_arg + entrypoint_arg + (unparsing_mode_arg ~default:"Readable") + now_arg + level_arg) + (prefixes ["run"; "script"] + @@ Program.source_param + @@ prefixes ["on"; "storage"] + @@ param ~name:"storage" ~desc:"the storage data" data_parameter + @@ prefixes ["and"; "input"] + @@ param ~name:"input" ~desc:"the input data" data_parameter + @@ stop) + (fun ( trace_exec, + amount, + balance, + source, + payer, + no_print_source, + gas, + entrypoint, + unparsing_mode, + now, + level ) + program + storage + input + cctxt -> + let source = Option.map snd source in + let payer = Option.map snd payer in + Lwt.return @@ Micheline_parser.no_parsing_error program + >>=? fun program -> + let show_source = not no_print_source in + if trace_exec then + trace + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + { + amount = Some amount; + balance; + program; + storage; + shared_params = + {input; unparsing_mode; now; level; source; payer; gas}; + entrypoint; + } + >>= fun res -> + print_trace_result cctxt ~show_source ~parsed:program res + else + run + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + { + amount = Some amount; + balance; + program; + storage; + shared_params = + {input; unparsing_mode; now; level; source; payer; gas}; + entrypoint; + } + >>= fun res -> print_run_result cctxt ~show_source ~parsed:program res); + command + ~group + ~desc:"Ask the node to compute the size of a script." + (args4 + emacs_mode_switch + no_print_source_flag + run_gas_limit_arg + legacy_switch) + (prefixes ["compute"; "size"; "for"; "script"] + @@ Program.source_param + @@ prefixes ["on"; "storage"] + @@ param ~name:"storage" ~desc:"the storage data" data_parameter + @@ stop) + (fun (emacs_mode, no_print_source, original_gas, legacy) + program + storage + cctxt -> + let setup = (emacs_mode, no_print_source) in + resolve_max_gas cctxt cctxt#block original_gas >>=? fun original_gas -> + handle_parsing_error "size" cctxt setup program @@ fun program -> + script_size + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~gas:original_gas + ~legacy + ~program + ~storage + () + >>=? fun code_size -> + cctxt#message "%d" code_size >>= fun _ -> return ()); + command + ~group + ~desc:"Ask the node to typecheck a script." + (args5 + show_types_switch + emacs_mode_switch + no_print_source_flag + run_gas_limit_arg + legacy_switch) + (prefixes ["typecheck"; "script"] @@ Program.source_param @@ stop) + (fun (show_types, emacs_mode, no_print_source, original_gas, legacy) + program + cctxt -> + let setup = (emacs_mode, no_print_source) in + handle_parsing_error "types" cctxt setup program @@ fun program -> + resolve_max_gas cctxt cctxt#block original_gas >>=? fun original_gas -> + typecheck_program + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~gas:original_gas + ~legacy + ~show_types + program + >>= fun res -> + print_typecheck_result + ~emacs:emacs_mode + ~show_types + ~print_source_on_error:(not no_print_source) + program + res + cctxt); + command + ~group + ~desc:"Ask the node to typecheck a data expression." + (args3 no_print_source_flag run_gas_limit_arg legacy_switch) + (prefixes ["typecheck"; "data"] + @@ param ~name:"data" ~desc:"the data to typecheck" data_parameter + @@ prefixes ["against"; "type"] + @@ param ~name:"type" ~desc:"the expected type" data_parameter + @@ stop) + (fun (no_print_source, custom_gas, legacy) data ty cctxt -> + resolve_max_gas cctxt cctxt#block custom_gas >>=? fun original_gas -> + Client_proto_programs.typecheck_data + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~gas:original_gas + ~legacy + ~data + ~ty + () + >>= function + | Ok gas -> + cctxt#message + "@[Well typed@,Gas remaining: %a@]" + Alpha_context.Gas.pp + gas + >>= fun () -> return_unit + | Error errs -> + cctxt#warning + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:false + ~show_source:(not no_print_source) + ?parsed:None) + errs + >>= fun () -> cctxt#error "ill-typed data"); + command + ~group + ~desc: + "Ask the node to pack a data expression.\n\ + The returned hash is the same as what Michelson instruction `PACK` \ + would have produced.\n\ + Also displays the result of hashing this packed data with `BLAKE2B`, \ + `SHA256` or `SHA512` instruction." + (args2 run_gas_limit_arg (Tezos_clic_unix.Scriptable.clic_arg ())) + (prefixes ["hash"; "data"] + @@ param ~name:"data" ~desc:"the data to hash" data_parameter + @@ prefixes ["of"; "type"] + @@ param ~name:"type" ~desc:"type of the data" data_parameter + @@ stop) + (fun (custom_gas, scriptable) data typ cctxt -> + resolve_max_gas cctxt cctxt#block custom_gas >>=? fun original_gas -> + Plugin.RPC.Scripts.pack_data + cctxt + (cctxt#chain, cctxt#block) + ~gas:original_gas + ~data:data.expanded + ~ty:typ.expanded + >>= function + | Ok (bytes, remaining_gas) -> + let hash = Script_expr_hash.hash_bytes [bytes] in + let name_value_rows = + Format. + [ + ( "Raw packed data", + asprintf "0x%a" Hex.pp (Hex.of_bytes bytes) ); + ( "Script-expression-ID-Hash", + asprintf "%a" Script_expr_hash.pp hash ); + ( "Raw Script-expression-ID-Hash", + asprintf + "0x%a" + Hex.pp + (Hex.of_bytes (Script_expr_hash.to_bytes hash)) ); + ( "Ledger Blake2b hash", + Base58.raw_encode Blake2B.(hash_bytes [bytes] |> to_string) + ); + ( "Raw Sha256 hash", + asprintf + "0x%a" + Hex.pp + (Hex.of_bytes (Environment.Raw_hashes.sha256 bytes)) ); + ( "Raw Sha512 hash", + asprintf + "0x%a" + Hex.pp + (Hex.of_bytes (Environment.Raw_hashes.sha512 bytes)) ); + ( "Gas remaining", + asprintf "%a" Alpha_context.Gas.pp remaining_gas ); + ] + in + Tezos_clic_unix.Scriptable.output + scriptable + ~for_human:(fun () -> + List.iter_s + (fun (name, value) -> cctxt#message "%s: %s" name value) + name_value_rows + >|= ok) + ~for_script:(fun () -> + name_value_rows |> List.map (fun (name, value) -> [name; value])) + | Error errs -> + cctxt#warning + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:false + ~show_source:false + ?parsed:None) + errs + >>= fun () -> cctxt#error "ill-formed data"); + command + ~group + ~desc:"Ask the node to hash a Michelson script with `BLAKE2B`." + (args3 + enforce_indentation_flag + display_names_flag + (Tezos_clic_unix.Scriptable.clic_arg ())) + (prefixes ["hash"; "script"] @@ seq_of_param @@ file_or_literal_param ()) + (fun (check, display_names, scriptable) + expr_strings + (cctxt : Protocol_client_context.full) -> + if List.length expr_strings == 0 then + cctxt#warning "No scripts were specified on the command line" >|= ok + else + List.mapi_ep + (fun i (src, expr_string) -> + let program = + Michelson_v1_parser.parse_toplevel ~check expr_string + in + Micheline_parser.no_parsing_error program >>?= fun program -> + let code = program.expanded in + let bytes = + Data_encoding.Binary.to_bytes_exn + Alpha_context.Script.expr_encoding + code + in + let hash = + Format.asprintf + "%a" + Script_expr_hash.pp + (Script_expr_hash.hash_bytes [bytes]) + in + let name = + Option.value + src + ~default:("Literal script " ^ string_of_int (i + 1)) + in + return (hash, name)) + expr_strings + >>=? fun hash_name_rows -> + Tezos_clic_unix.Scriptable.output + scriptable + ~for_human:(fun () -> + List.iter_s + (fun (hash, name) -> + if display_names then cctxt#answer "%s\t%s" hash name + else cctxt#answer "%s" hash) + hash_name_rows + >|= ok) + ~for_script:(fun () -> + List.map + (fun (hash, name) -> + if display_names then [hash; name] else [hash]) + hash_name_rows)); + command + ~group + ~desc: + "Parse a byte sequence (in hexadecimal notation) as a data expression, \ + as per Michelson instruction `UNPACK`." + no_options + (prefixes ["unpack"; "michelson"; "data"] + @@ bytes_parameter ~name:"bytes" ~desc:"the packed data to parse" + @@ stop) + (fun () bytes cctxt -> + (if Bytes.get bytes 0 != '\005' then + failwith + "Not a piece of packed Michelson data (must start with `0x05`)" + else return_unit) + >>=? fun () -> + (* Remove first byte *) + let bytes = Bytes.sub bytes 1 (Bytes.length bytes - 1) in + match + Data_encoding.Binary.of_bytes_opt + Alpha_context.Script.expr_encoding + bytes + with + | None -> failwith "Could not decode bytes" + | Some expr -> + cctxt#message "%a" Michelson_v1_printer.print_expr_unwrapped expr + >>= fun () -> return_unit); + command + ~group + ~desc:"Ask the node to normalize a script." + (args1 (unparsing_mode_arg ~default:"Readable")) + (prefixes ["normalize"; "script"] @@ Program.source_param @@ stop) + (fun unparsing_mode program cctxt -> + Lwt.return @@ Micheline_parser.no_parsing_error program + >>=? fun program -> + Plugin.RPC.Scripts.normalize_script + cctxt + (cctxt#chain, cctxt#block) + ~script:program.expanded + ~unparsing_mode + >>= function + | Ok program -> + cctxt#message + "%a" + (fun ppf () : unit -> + Michelson_v1_printer.print_expr_unwrapped ppf program) + () + >>= fun () -> return_unit + | Error errs -> + cctxt#warning + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:false + ~show_source:false + ?parsed:None) + errs + >>= fun () -> cctxt#error "ill-typed script"); + command + ~group + ~desc:"Ask the node to normalize a data expression." + (args2 (unparsing_mode_arg ~default:"Readable") legacy_switch) + (prefixes ["normalize"; "data"] + @@ param + ~name:"data" + ~desc:"the data expression to normalize" + data_parameter + @@ prefixes ["of"; "type"] + @@ param ~name:"type" ~desc:"type of the data expression" data_parameter + @@ stop) + (fun (unparsing_mode, legacy) data typ cctxt -> + Plugin.RPC.Scripts.normalize_data + cctxt + (cctxt#chain, cctxt#block) + ~legacy + ~data:data.expanded + ~ty:typ.expanded + ~unparsing_mode + >>= function + | Ok expr -> + cctxt#message "%a" Michelson_v1_printer.print_expr_unwrapped expr + >>= fun () -> return_unit + | Error errs -> + cctxt#warning + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:false + ~show_source:false + ?parsed:None) + errs + >>= fun () -> cctxt#error "ill-typed data expression"); + command + ~group + ~desc:"Ask the node to normalize a type." + no_options + (prefixes ["normalize"; "type"] + @@ param + ~name:"typ" + ~desc:"the Michelson type to normalize" + data_parameter + @@ stop) + (fun () typ cctxt -> + Plugin.RPC.Scripts.normalize_type + cctxt + (cctxt#chain, cctxt#block) + ~ty:typ.expanded + >>= function + | Ok expr -> + cctxt#message "%a" Michelson_v1_printer.print_expr_unwrapped expr + >>= fun () -> return_unit + | Error errs -> + cctxt#warning + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:false + ~show_source:false + ?parsed:None) + errs + >>= fun () -> cctxt#error "ill-formed type"); + command + ~group + ~desc: + "Sign a raw sequence of bytes and display it using the format expected \ + by Michelson instruction `CHECK_SIGNATURE`." + no_options + (prefixes ["sign"; "bytes"] + @@ bytes_parameter ~name:"data" ~desc:"the raw data to sign" + @@ prefixes ["for"] + @@ Client_keys.Secret_key.source_param @@ stop) + (fun () bytes sk cctxt -> + Client_keys.sign cctxt sk bytes >>=? fun signature -> + cctxt#message "Signature: %a" Signature.pp signature >>= fun () -> + return_unit); + command + ~group + ~desc: + "Check the signature of a byte sequence as per Michelson instruction \ + `CHECK_SIGNATURE`." + (args1 (switch ~doc:"Use only exit codes" ~short:'q' ~long:"quiet" ())) + (prefixes ["check"; "that"; "bytes"] + @@ bytes_parameter ~name:"bytes" ~desc:"the signed data" + @@ prefixes ["were"; "signed"; "by"] + @@ Client_keys.Public_key.alias_param ~name:"key" + @@ prefixes ["to"; "produce"] + @@ param + ~name:"signature" + ~desc:"the signature to check" + signature_parameter + @@ stop) + (fun quiet + bytes + (_, (key_locator, _)) + signature + (cctxt : #Protocol_client_context.full) -> + Client_keys.check key_locator signature bytes >>=? function + | false -> cctxt#error "invalid signature" + | true -> + if quiet then return_unit + else + cctxt#message "Signature check successful." >>= fun () -> + return_unit); + command + ~group + ~desc:"Ask the type of an entrypoint of a script." + (args2 emacs_mode_switch no_print_source_flag) + (prefixes ["get"; "script"; "entrypoint"; "type"; "of"] + @@ string ~name:"entrypoint" ~desc:"the entrypoint to describe" + @@ prefixes ["for"] + @@ Program.source_param @@ stop) + (fun ((emacs_mode, no_print_source) as setup) entrypoint program cctxt -> + handle_parsing_error "entrypoint" cctxt setup program @@ fun program -> + entrypoint_type + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + program + ~entrypoint + >>= fun entrypoint_type -> + print_entrypoint_type + ~emacs:emacs_mode + ~show_source:(not no_print_source) + ~parsed:program + ~entrypoint + cctxt + entrypoint_type); + command + ~group + ~desc:"Ask the node to list the entrypoints of a script." + (args2 emacs_mode_switch no_print_source_flag) + (prefixes ["get"; "script"; "entrypoints"; "for"] + @@ Program.source_param @@ stop) + (fun ((emacs_mode, no_print_source) as setup) program cctxt -> + handle_parsing_error "entrypoints" cctxt setup program @@ fun program -> + list_entrypoints cctxt ~chain:cctxt#chain ~block:cctxt#block program + >>= fun entrypoints -> + print_entrypoints_list + ~emacs:emacs_mode + ~show_source:(not no_print_source) + ~parsed:program + cctxt + entrypoints); + command + ~group + ~desc: + "Ask the node to list the unreachable paths in a script's parameter \ + type." + (args2 emacs_mode_switch no_print_source_flag) + (prefixes ["get"; "script"; "unreachable"; "paths"; "for"] + @@ Program.source_param @@ stop) + (fun ((emacs_mode, no_print_source) as setup) program cctxt -> + handle_parsing_error "entrypoints" cctxt setup program @@ fun program -> + list_unreachables cctxt ~chain:cctxt#chain ~block:cctxt#block program + >>= fun entrypoints -> + print_unreachables + ~emacs:emacs_mode + ~show_source:(not no_print_source) + ~parsed:program + cctxt + entrypoints); + command + ~group + ~desc:"Ask the node to expand the Michelson macros in a script." + no_options + (prefixes ["expand"; "macros"; "in"] @@ Program.source_param @@ stop) + (fun () program (cctxt : Protocol_client_context.full) -> + Lwt.return @@ Micheline_parser.no_parsing_error program + >>=? fun program -> + cctxt#message + "%a" + (fun ppf () : unit -> + Michelson_v1_printer.print_expr_unwrapped ppf program.expanded) + () + >>= fun () -> return_unit); + command + ~desc: + "Conversion of Michelson script from Micheline, JSON or binary to \ + Micheline, JSON, binary or OCaml" + (args3 zero_loc_switch legacy_switch enforce_indentation_flag) + (prefixes ["convert"; "script"] + @@ file_or_literal_param () @@ prefix "from" @@ convert_input_format_param + @@ prefix "to" @@ convert_output_format_param @@ stop) + (fun (zero_loc, legacy, check) + (_, expr_string) + from_format + to_format + (cctxt : Protocol_client_context.full) -> + (match from_format with + | `Michelson -> + let program = + Michelson_v1_parser.parse_toplevel ~check expr_string + in + Lwt.return @@ Micheline_parser.no_parsing_error program + >>=? fun program -> + (typecheck_program + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~legacy + ~show_types:true + program + >>= function + | Error _ as res -> + print_typecheck_result + ~emacs:false + ~show_types:true + ~print_source_on_error:true + program + res + cctxt + | Ok _ -> return_unit) + >>=? fun () -> return program.expanded + | `JSON -> ( + match Data_encoding.Json.from_string expr_string with + | Error err -> cctxt#error "%s" err + | Ok json -> + safe_decode_json cctxt Alpha_context.Script.expr_encoding json) + | `Binary -> ( + bytes_of_prefixed_string expr_string >>=? fun bytes -> + match + Data_encoding.Binary.of_bytes_opt + Alpha_context.Script.expr_encoding + bytes + with + | None -> failwith "Could not decode bytes" + | Some expr -> return expr)) + >>=? fun (expression : Alpha_context.Script.expr) -> + let output = + match to_format with + | `Michelson -> + Micheline_printer.printable + Michelson_v1_primitives.string_of_prim + expression + |> Format.asprintf "%a" Micheline_printer.print_expr + | `JSON -> + Data_encoding.Json.( + construct Alpha_context.Script.expr_encoding expression + |> to_string) + | `Binary -> + Format.asprintf + "0x%s" + (Data_encoding.Binary.( + to_bytes_exn Alpha_context.Script.expr_encoding expression) + |> Hex.of_bytes |> Hex.show) + | `OCaml -> + Michelson_v1_printer.micheline_string_of_expression + ~zero_loc + expression + in + cctxt#message "%s" output >>= fun () -> return_unit); + command + ~desc: + "Conversion of Micheline expression from Micheline, JSON or binary to \ + Micheline, JSON, binary or OCaml" + (args2 zero_loc_switch data_type_arg) + (prefixes ["convert"; "data"] + @@ file_or_literal_param () @@ prefix "from" @@ convert_input_format_param + @@ prefix "to" @@ convert_output_format_param @@ stop) + (fun (zero_loc, data_ty) + (_, data_string) + from_format + to_format + (cctxt : Protocol_client_context.full) -> + let micheline_of_expr expr = + Micheline_printer.printable + Michelson_v1_primitives.string_of_prim + expr + |> Format.asprintf "%a" Micheline_printer.print_expr + in + let typecheck_parsed ~data ~ty = + Client_proto_programs.typecheck_data + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~data + ~ty + () + >>= function + | Error errs -> + failwith + "%a" + (Michelson_v1_error_reporter.report_errors + ~details:false + ~show_source:false + ?parsed:None) + errs + | Ok _gas -> return data.expanded + in + let typecheck_expr ~expr ~ty = + let data_string = micheline_of_expr expr in + parse_expr data_string >>=? fun data -> typecheck_parsed ~data ~ty + in + (match from_format with + | `Michelson -> ( + parse_expr data_string >>=? fun data -> + match data_ty with + | Some ty -> typecheck_parsed ~data ~ty + | None -> return data.expanded) + | `JSON -> ( + match Data_encoding.Json.from_string data_string with + | Error err -> cctxt#error "%s" err + | Ok json -> ( + safe_decode_json cctxt Alpha_context.Script.expr_encoding json + >>=? fun expr -> + match data_ty with + | None -> return expr + | Some ty -> typecheck_expr ~expr ~ty)) + | `Binary -> ( + bytes_of_prefixed_string data_string >>=? fun bytes -> + match + Data_encoding.Binary.of_bytes_opt + Alpha_context.Script.expr_encoding + bytes + with + | None -> failwith "Could not decode bytes" + | Some expr -> ( + match data_ty with + | None -> return expr + | Some ty -> typecheck_expr ~expr ~ty))) + >>=? fun (expression : Alpha_context.Script.expr) -> + let output = + match to_format with + | `Michelson -> micheline_of_expr expression + | `JSON -> + Data_encoding.Json.( + construct Alpha_context.Script.expr_encoding expression + |> to_string) + | `Binary -> + Format.asprintf + "0x%s" + (Data_encoding.Binary.( + to_bytes_exn Alpha_context.Script.expr_encoding expression) + |> Hex.of_bytes |> Hex.show) + | `OCaml -> + Michelson_v1_printer.micheline_string_of_expression + ~zero_loc + expression + in + cctxt#message "%s" output >>= fun () -> return_unit); + command + ~group + ~desc:"Ask the node to run a TZIP-4 view." + (args6 + source_arg + payer_arg + run_gas_limit_arg + (unparsing_mode_arg ~default:"Readable") + now_arg + level_arg) + (prefixes ["run"; "tzip4"; "view"] + @@ param ~name:"entrypoint" ~desc:"the name of the view" string_parameter + @@ prefixes ["on"; "contract"] + @@ ContractAlias.destination_param + ~name:"contract" + ~desc:"viewed contract" + @@ prefixes ["with"; "input"] + @@ param ~name:"input" ~desc:"the input data" data_parameter + @@ stop) + (fun (source, payer, gas, unparsing_mode, now, level) + entrypoint + (_, contract) + input + cctxt -> + let source = Option.map snd source in + let payer = Option.map snd payer in + Client_proto_programs.run_view + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + { + shared_params = + {input; unparsing_mode; now; level; source; payer; gas}; + contract; + entrypoint; + } + >>= fun res -> print_view_result cctxt res); + ] diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_programs_commands.mli b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_programs_commands.mli new file mode 100644 index 000000000000..6e352b98be7f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_programs_commands.mli @@ -0,0 +1,26 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_stresstest_commands.ml b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_stresstest_commands.ml new file mode 100644 index 000000000000..d302206a9834 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_stresstest_commands.ml @@ -0,0 +1,1004 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type transfer_strategy = + | Fixed_amount of {mutez : Tez.t} (** Amount to transfer *) + | Evaporation of {fraction : float} + (** Maximum fraction of current wealth to transfer. + Minimum amount is 1 mutez regardless of total wealth. *) + +type parameters = { + seed : int; + fresh_probability : float; + (** Per-transfer probability that the destination will be fresh *) + tps : float; (** Transaction per seconds target *) + strategy : transfer_strategy; + fee_mutez : Tez.t; (** fees for each transfer, in mutez *) + gas_limit : Gas.Arith.integral; (** gas limit per operation *) + storage_limit : Z.t; (** storage limit per operation *) + account_creation_storage : Z.t; + (** upper bound on bytes consumed when creating a tz1 account *) + total_transfers : int option; + (** total number of transfers to perform; unbounded if None *) + single_op_per_pkh_per_block : bool; + (** if true, a single operation will be injected by pkh by block to + improve the chance for the injected operations to be included in the + next block *) +} + +type origin = Explicit | Wallet_pkh | Wallet_alias of string + +type source = { + pkh : public_key_hash; + pk : public_key; + sk : Signature.secret_key; +} + +type input_source = + | Explicit of source + | Wallet_alias of string + | Wallet_pkh of public_key_hash + +type source_origin = {source : source; origin : origin} + +type transfer = { + src : source; + dst : public_key_hash; + fee : Tez.t; + amount : Tez.t; + counter : Z.t option; + fresh_dst : bool; +} + +type state = { + current_head_on_start : Block_hash.t; + counters : (Block_hash.t * Z.t) Signature.Public_key_hash.Table.t; + mutable pool : source_origin list; + mutable pool_size : int; + (** [Some l] if [single_op_per_pkh_per_block] is true *) + mutable shuffled_pool : source list option; + mutable revealed : Signature.Public_key_hash.Set.t; + mutable last_block : Block_hash.t; + new_block_condition : unit Lwt_condition.t; + injected_operations : Operation_hash.t list Block_hash.Table.t; +} + +let verbose = ref false + +let debug = ref false + +let debug_msg msg = if !debug then msg () else Lwt.return_unit + +let default_parameters = + { + seed = 0x533D; + fresh_probability = 0.001; + tps = 5.0; + strategy = Fixed_amount {mutez = Tez.one}; + fee_mutez = Tez.of_mutez_exn 2_000L; + gas_limit = Gas.Arith.integral_of_int_exn 1_600; + (* [gas_limit] corresponds to a slight overapproximation of the + gas needed to inject an operation. It was obtained by simulating + the operation using the client. *) + storage_limit = Z.zero; + account_creation_storage = Z.of_int 300; + (* [account_creation_storage] corresponds to a slight overapproximation + of the storage consumed when allocating a new implicit account. + It was obtained by simulating the operation using the client. *) + total_transfers = None; + single_op_per_pkh_per_block = false; + } + +let input_source_encoding = + let open Data_encoding in + union + [ + case + ~title:"explicit" + (Tag 0) + (obj3 + (req "pkh" Signature.Public_key_hash.encoding) + (req "pk" Signature.Public_key.encoding) + (req "sk" Signature.Secret_key.encoding)) + (function Explicit {pkh; pk; sk} -> Some (pkh, pk, sk) | _ -> None) + (fun (pkh, pk, sk) -> Explicit {pkh; pk; sk}); + case + ~title:"alias" + (Tag 1) + (obj1 (req "alias" Data_encoding.string)) + (function Wallet_alias alias -> Some alias | _ -> None) + (fun alias -> Wallet_alias alias); + case + ~title:"pkh" + (Tag 2) + (obj1 (req "pkh" Signature.Public_key_hash.encoding)) + (function Wallet_pkh pkh -> Some pkh | _ -> None) + (fun pkh -> Wallet_pkh pkh); + ] + +let input_source_list_encoding = Data_encoding.list input_source_encoding + +let injected_operations_encoding = + let open Data_encoding in + list + (obj2 + (req "block_hash_when_injected" Block_hash.encoding) + (req "operation_hashes" (list Operation_hash.encoding))) + +let parse_strategy s = + match String.split ~limit:1 ':' s with + | ["fixed"; parameter] -> ( + match int_of_string parameter with + | exception _ -> Error "invalid integer literal" + | mutez when mutez <= 0 -> Error "negative amount" + | mutez -> ( + match Tez.of_mutez (Int64.of_int mutez) with + | None -> Error "invalid mutez" + | Some mutez -> Ok (Fixed_amount {mutez}))) + | ["evaporation"; parameter] -> ( + match float_of_string parameter with + | exception _ -> Error "invalid float literal" + | fraction when fraction < 0.0 || fraction > 1.0 -> + Error "invalid evaporation rate" + | fraction -> Ok (Evaporation {fraction})) + | _ -> Error "invalid argument" + +(** This command uses two different data structures for sources: + - The in-output files one, + - The normalized one. + + The data structure used for in-output files does not directly contain the + data required to forge operations. For efficiency purposes, the sources are + converted into a normalized data structure that contains all the required + data to forge operations and the format originally used to be able to + revert this conversion. *) + +(** [normalize_source cctxt src] converts [src] from in-output data structure + to normalized one. If the conversion fails, [None] is returned and a + warning message is printed in [cctxt]. + + Only unencrypted and encrypted sources from the wallet of [cctxt] are + supported. *) +let normalize_source cctxt = + let sk_of_sk_uri sk_uri = + match + Signature.Secret_key.of_b58check + (Uri.path (sk_uri : Client_keys.sk_uri :> Uri.t)) + with + | Ok sk -> Lwt.return_some sk + | Error _ -> ( + Tezos_signer_backends.Encrypted.decrypt cctxt sk_uri >>= function + | Error _ -> Lwt.return_none + | Ok sk -> Lwt.return_some sk) + in + let key_from_alias alias = + let warning msg alias = + cctxt#warning msg alias >>= fun () -> Lwt.return_none + in + (Client_keys.alias_keys cctxt alias >>= function + | Error _ | Ok None -> warning "Alias \"%s\" not found in the wallet" alias + | Ok (Some (_, None, _)) | Ok (Some (_, _, None)) -> + warning + "Alias \"%s\" does not contain public or secret key and could not \ + be used for stresstest" + alias + | Ok (Some (pkh, Some pk, Some sk_uri)) -> ( + sk_of_sk_uri sk_uri >>= function + | None -> + warning + "Cannot extract the secret key form the alias \"%s\" of the \ + wallet" + alias + | Some sk -> + Lwt.return_some + {source = {pkh; pk; sk}; origin = Wallet_alias alias})) + >>= function + | None -> warning "Source given as alias \"%s\" ignored" alias + | key -> Lwt.return key + in + let key_from_wallet pkh = + let warning msg pkh = + cctxt#warning msg Signature.Public_key_hash.pp pkh >>= fun () -> + Lwt.return_none + in + (Client_keys.get_key cctxt pkh >>= function + | Error _ -> warning "Pkh \"%a\" not found in the wallet" pkh + | Ok (alias, pk, sk_uri) -> ( + sk_of_sk_uri sk_uri >>= function + | None -> + cctxt#warning + "Cannot extract the secret key form the pkh \"%a\" (alias: \ + \"%s\") of the wallet" + Signature.Public_key_hash.pp + pkh + alias + >>= fun () -> Lwt.return_none + | Some sk -> + Lwt.return_some {source = {pkh; pk; sk}; origin = Wallet_pkh})) + >>= function + | None -> warning "Source given as pkh \"%a\" ignored" pkh + | key -> Lwt.return key + in + function + | Explicit source -> Lwt.return_some {source; origin = Explicit} + | Wallet_alias alias -> key_from_alias alias + | Wallet_pkh pkh -> key_from_wallet pkh + +(** [unnormalize_source src_org] converts [src_org] from normalized data + structure to in-output one. *) +let unnormalize_source src_org = + match src_org.origin with + | Explicit -> Explicit src_org.source + | Wallet_pkh -> Wallet_pkh src_org.source.pkh + | Wallet_alias alias -> Wallet_alias alias + +(** Samples from [state.pool]. Used to generate the destination of a + transfer, and its source only when [state.shuffled_pool] is [None] + meaning that [--single-op-per-pkh-per-block] is not set. *) +let sample_any_source_from_pool state rng_state = + let idx = Random.State.int rng_state state.pool_size in + match List.nth state.pool idx with + | None -> assert false + | Some src_org -> Lwt.return src_org.source + +(** Generates the source of a transfer. If [state.shuffled_pool] has a + value (meaning that [--single-op-per-pkh-per-block] is active) then + it is sampled from there, otherwise from [state.pool]. *) +let rec sample_source_from_pool state rng_state + (cctxt : Protocol_client_context.full) = + match state.shuffled_pool with + | None -> sample_any_source_from_pool state rng_state + | Some (source :: l) -> + state.shuffled_pool <- Some l ; + debug_msg (fun () -> + cctxt#message + "sample_transfer: %d unused sources for the block next to %a" + (List.length l) + Block_hash.pp + state.last_block) + >>= fun () -> Lwt.return source + | Some [] -> + cctxt#message + "all available sources have been used for block next to %a" + Block_hash.pp + state.last_block + >>= fun () -> + Lwt_condition.wait state.new_block_condition >>= fun () -> + sample_source_from_pool state rng_state cctxt + +let random_seed rng_state = + Bytes.init 32 (fun _ -> Char.chr (Random.State.int rng_state 256)) + +let generate_fresh_source pool rng_state = + let seed = random_seed rng_state in + let (pkh, pk, sk) = Signature.generate_key ~seed () in + let fresh = {source = {pkh; pk; sk}; origin = Explicit} in + pool.pool <- fresh :: pool.pool ; + pool.pool_size <- pool.pool_size + 1 ; + fresh.source + +(* [on_new_head cctxt f] calls [f head] each time there is a new head + received by the streamed RPC /monitor/heads/main *) +let on_new_head (cctxt : Protocol_client_context.full) f = + Shell_services.Monitor.heads cctxt `Main >>=? fun (heads_stream, stopper) -> + Lwt_stream.iter_s f heads_stream >>= fun () -> + stopper () ; + return_unit + +(* We perform rejection sampling of valid sources. + We could maintain a local cache of existing contracts with sufficient balance. *) +let rec sample_transfer (cctxt : Protocol_client_context.full) chain block + (parameters : parameters) (state : state) rng_state = + sample_source_from_pool state rng_state cctxt >>= fun src -> + Alpha_services.Contract.balance + cctxt + (chain, block) + (Contract.implicit_contract src.pkh) + >>=? fun tez -> + if Tez.(tez = zero) then + debug_msg (fun () -> + cctxt#message + "sample_transfer: invalid balance %a" + Signature.Public_key_hash.pp + src.pkh) + >>= fun () -> + (* Sampled source has zero balance: the transfer that created that + address was not included yet. Retry *) + sample_transfer cctxt chain block parameters state rng_state + else + let fresh = + Random.State.float rng_state 1.0 < parameters.fresh_probability + in + (if fresh then Lwt.return (generate_fresh_source state rng_state) + else sample_any_source_from_pool state rng_state) + >>= fun dest -> + let amount = + match parameters.strategy with + | Fixed_amount {mutez} -> mutez + | Evaporation {fraction} -> + let mutez = Int64.to_float (Tez.to_mutez tez) in + let max_fraction = Int64.of_float (mutez *. fraction) in + let amount = + if max_fraction = 0L then 1L + else max 1L (Random.State.int64 rng_state max_fraction) + in + Tez.of_mutez_exn amount + in + let fee = parameters.fee_mutez in + return {src; dst = dest.pkh; fee; amount; counter = None; fresh_dst = fresh} + +let inject_contents (cctxt : Protocol_client_context.full) chain branch sk + contents = + let bytes = + Data_encoding.Binary.to_bytes_exn + Operation.unsigned_encoding + ({branch}, Contents_list contents) + in + let signature = + Some (Signature.sign ~watermark:Signature.Generic_operation sk bytes) + in + let op : _ Operation.t = + {shell = {branch}; protocol_data = {contents; signature}} + in + let bytes = + Data_encoding.Binary.to_bytes_exn Operation.encoding (Operation.pack op) + in + Shell_services.Injection.operation cctxt ~chain bytes + +(* counter _must_ be set before calling this function *) +let manager_op_of_transfer parameters + {src; dst; fee; amount; counter; fresh_dst} = + let source = src.pkh in + let gas_limit = parameters.gas_limit in + let storage_limit = + if fresh_dst then + Z.add parameters.account_creation_storage parameters.storage_limit + else parameters.storage_limit + in + let operation = + let parameters = + let open Tezos_micheline in + Script.lazy_expr + @@ Micheline.strip_locations + (Prim (0, Michelson_v1_primitives.D_Unit, [], [])) + in + let entrypoint = "default" in + let destination = Contract.implicit_contract dst in + Transaction {amount; parameters; entrypoint; destination} + in + match counter with + | None -> assert false + | Some counter -> + Manager_operation + {source; fee; counter; operation; gas_limit; storage_limit} + +let cost_of_manager_operation = Gas.Arith.integral_of_int_exn 1_000 + +let inject_transfer (cctxt : Protocol_client_context.full) parameters state + rng_state chain block transfer = + Alpha_services.Contract.counter cctxt (chain, block) transfer.src.pkh + >>=? fun pcounter -> + Shell_services.Blocks.hash cctxt ~chain ~block () >>=? fun branch -> + (* If there is a new block refresh the fresh_pool *) + if not (Block_hash.equal branch state.last_block) then ( + state.last_block <- branch ; + if Option.is_some state.shuffled_pool then + state.shuffled_pool <- + Some + (List.shuffle + ~rng_state + (List.map (fun src_org -> src_org.source) state.pool))) ; + let freshest_counter = + match + Signature.Public_key_hash.Table.find state.counters transfer.src.pkh + with + | None -> + (* This is the first operation we inject for this pkh: the counter given + by the RPC _must_ be the freshest one. *) + pcounter + | Some (previous_branch, previous_counter) -> + if Block_hash.equal branch previous_branch then + (* We already injected an operation on top of this block: the one stored + locally is the freshest one. *) + previous_counter + else + (* It seems the block changed since we last injected an operation: + this invalidates the previously stored counter. We return the counter + given by the RPC. *) + pcounter + in + (if Signature.Public_key_hash.Set.mem transfer.src.pkh state.revealed then + return true + else ( + (* Either the [manager_key] RPC tells us the key is already + revealed, or we immediately inject a reveal operation: in any + case the key is revealed in the end. *) + state.revealed <- + Signature.Public_key_hash.Set.add transfer.src.pkh state.revealed ; + Alpha_services.Contract.manager_key cctxt (chain, block) transfer.src.pkh + >>=? fun pk_opt -> return (Option.is_some pk_opt))) + >>=? fun already_revealed -> + (if not already_revealed then ( + let reveal_counter = Z.succ freshest_counter in + let transf_counter = Z.succ reveal_counter in + let reveal = + Manager_operation + { + source = transfer.src.pkh; + fee = Tez.zero; + counter = reveal_counter; + gas_limit = cost_of_manager_operation; + storage_limit = Z.zero; + operation = Reveal transfer.src.pk; + } + in + let manager_op = + manager_op_of_transfer + parameters + {transfer with counter = Some transf_counter} + in + let list = Cons (reveal, Single manager_op) in + Signature.Public_key_hash.Table.remove state.counters transfer.src.pkh ; + Signature.Public_key_hash.Table.add + state.counters + transfer.src.pkh + (branch, transf_counter) ; + (if !verbose then + cctxt#message + "injecting reveal+transfer from %a (counters=%a,%a) to %a" + Signature.Public_key_hash.pp + transfer.src.pkh + Z.pp_print + reveal_counter + Z.pp_print + transf_counter + Signature.Public_key_hash.pp + transfer.dst + else Lwt.return_unit) + >>= fun () -> + (* NB: regardless of our best efforts to keep track of counters, injection can fail with + "counter in the future" if a block switch happens in between the moment we + get the branch and the moment we inject, and the new block does not include + all the operations we injected. *) + inject_contents cctxt chain branch transfer.src.sk list) + else + let transf_counter = Z.succ freshest_counter in + let manager_op = + manager_op_of_transfer + parameters + {transfer with counter = Some transf_counter} + in + let list = Single manager_op in + Signature.Public_key_hash.Table.remove state.counters transfer.src.pkh ; + Signature.Public_key_hash.Table.add + state.counters + transfer.src.pkh + (branch, transf_counter) ; + (if !verbose then + cctxt#message + "injecting transfer from %a (counter=%a) to %a" + Signature.Public_key_hash.pp + transfer.src.pkh + Z.pp_print + transf_counter + Signature.Public_key_hash.pp + transfer.dst + else Lwt.return_unit) + >>= fun () -> + (* See comment above. *) + inject_contents cctxt chain branch transfer.src.sk list) + >>= function + | Ok op_hash -> + debug_msg (fun () -> + cctxt#message + "inject_transfer: op injected %a" + Operation_hash.pp + op_hash) + >>= fun () -> + let ops = + Option.value + ~default:[] + (Block_hash.Table.find state.injected_operations branch) + in + Block_hash.Table.replace state.injected_operations branch (op_hash :: ops) ; + return_unit + | Error e -> + debug_msg (fun () -> + cctxt#message + "inject_transfer: error, op not injected: %a" + Error_monad.pp_print_trace + e) + >>= fun () -> return_unit + +let save_injected_operations (cctxt : Protocol_client_context.full) state = + let json = + Data_encoding.Json.construct + injected_operations_encoding + (Block_hash.Table.fold + (fun k v acc -> (k, v) :: acc) + state.injected_operations + []) + in + let path = + Filename.temp_file "client-stresstest-injected_operations-" ".json" + in + cctxt#message "writing injected operations in file %s" path >>= fun () -> + Lwt_utils_unix.Json.write_file path json >>= function + | Error e -> + cctxt#message + "could not write injected operations json file: %a" + Error_monad.pp_print_trace + e + | Ok _ -> Lwt.return_unit + +let stat_on_exit (cctxt : Protocol_client_context.full) state = + let ratio_injected_included_op () = + Shell_services.Blocks.hash cctxt () >>=? fun current_head_on_exit -> + let inter_cardinal s1 s2 = + Operation_hash.Set.cardinal + (Operation_hash.Set.inter + (Operation_hash.Set.of_list s1) + (Operation_hash.Set.of_list s2)) + in + let get_included_ops older_block = + let rec get_included_ops block acc_included_ops = + if block = older_block then return acc_included_ops + else + Shell_services.Chain.Blocks.Operation_hashes.operation_hashes_in_pass + cctxt + ~chain:`Main + ~block:(`Hash (block, 0)) + 3 + >>=? fun included_ops -> + Shell_services.Blocks.list + cctxt + ~chain:`Main + ~heads:[block] + ~length:2 + () + >>=? function + | [[current; predecessor]] when current = block -> + get_included_ops + predecessor + (List.append acc_included_ops included_ops) + | _ -> cctxt#error "Error while computing stats: invalid block list" + in + get_included_ops current_head_on_exit [] + in + let injected_ops = + Block_hash.Table.fold + (fun k l acc -> + (* The operations injected during the last block are ignored because + they should not be currently included. *) + if current_head_on_exit <> k then List.append acc l else acc) + state.injected_operations + [] + in + get_included_ops state.current_head_on_start >>=? fun included_ops -> + let included_ops_count = inter_cardinal injected_ops included_ops in + debug_msg (fun () -> + cctxt#message + "injected : %a\nincluded: %a" + (Format.pp_print_list Operation_hash.pp) + injected_ops + (Format.pp_print_list Operation_hash.pp) + included_ops) + >>= fun () -> + let injected_ops_count = List.length injected_ops in + cctxt#message + "%s of the injected operations have been included (%d injected, %d \ + included). Note that the operations injected during the last block are \ + ignored because they should not be currently included." + (if Int.equal injected_ops_count 0 then "N/A" + else Format.sprintf "%d%%" (included_ops_count * 100 / injected_ops_count)) + injected_ops_count + included_ops_count + >>= fun () -> return_unit + in + ratio_injected_included_op () + +let launch (cctxt : Protocol_client_context.full) (parameters : parameters) + state rng_state save_pool_callback = + let injected = ref 0 in + let dt = 1. /. parameters.tps in + let terminated () = + match parameters.total_transfers with + | None -> false + | Some bound -> bound <= !injected + in + let rec loop () = + if terminated () then + save_pool_callback () >>= fun () -> + save_injected_operations cctxt state >>= fun () -> + stat_on_exit cctxt state + else + let start = Mtime_clock.elapsed () in + debug_msg (fun () -> cctxt#message "launch.loop: invoke sample_transfer") + >>= fun () -> + sample_transfer cctxt cctxt#chain cctxt#block parameters state rng_state + >>=? fun transfer -> + debug_msg (fun () -> cctxt#message "launch.loop: invoke inject_transfer") + >>= fun () -> + inject_transfer + cctxt + parameters + state + rng_state + cctxt#chain + cctxt#block + transfer + >>=? fun () -> + incr injected ; + let stop = Mtime_clock.elapsed () in + let elapsed = Mtime.Span.(to_s stop -. to_s start) in + let remaining = dt -. elapsed in + (if remaining <= 0.0 then + cctxt#warning + "warning: tps target could not be reached, consider using a lower \ + value for --tps" + else Lwt_unix.sleep remaining) + >>= loop + in + (* True, if and only if [single_op_per_pkh_per_block] is true. *) + if Option.is_some state.shuffled_pool then + dont_wait + (fun () -> + on_new_head cctxt (fun (block, _) -> + if not (Block_hash.equal block state.last_block) then ( + state.last_block <- block ; + state.shuffled_pool <- + Some + (List.shuffle + ~rng_state + (List.map (fun src_org -> src_org.source) state.pool))) ; + Lwt_condition.broadcast state.new_block_condition () ; + Lwt.return_unit)) + (fun trace -> + ignore + (cctxt#error + "an error while getting the new head has been returned: %a" + Error_monad.pp_print_trace + trace)) + (fun exn -> + ignore + (cctxt#error + "an exception while getting the new head has been raised: %s" + (Printexc.to_string exn))) ; + loop () + +let group = + Clic.{name = "stresstest"; title = "Commands for stress-testing the network"} + +type pool_source = + | From_string of {json : Ezjsonm.value} + | From_file of {path : string; json : Ezjsonm.value} + +let json_of_pool_source = function + | From_string {json} | From_file {json; _} -> json + +let json_file_or_text_parameter = + Clic.parameter (fun _ p -> + match String.split ~limit:1 ':' p with + | ["text"; text] -> return (From_string {json = Ezjsonm.from_string text}) + | ["file"; path] -> + Lwt_utils_unix.Json.read_file path >|=? fun json -> + From_file {path; json} + | _ -> ( + if Sys.file_exists p then + Lwt_utils_unix.Json.read_file p >|=? fun json -> + From_file {path = p; json} + else + try return (From_string {json = Ezjsonm.from_string p}) + with Ezjsonm.Parse_error _ -> + failwith "Neither an existing file nor valid JSON: '%s'" p)) + +let seed_arg = + let open Clic in + arg + ~long:"seed" + ~placeholder:"int" + ~doc:"random seed" + (parameter (fun (cctxt : Protocol_client_context.full) s -> + match int_of_string s with + | exception _ -> + cctxt#error + "While parsing --seed: could not convert argument to int" + | i -> return i)) + +let tps_arg = + let open Clic in + arg + ~long:"tps" + ~placeholder:"float" + ~doc:"transactions per seconds target" + (parameter (fun (cctxt : Protocol_client_context.full) s -> + match float_of_string s with + | exception _ -> + cctxt#error + "While parsing --tps: could not convert argument to float" + | f when f < 0.0 -> + cctxt#error "While parsing --tps: negative argument" + | f -> return f)) + +let fresh_probability_arg = + let open Clic in + arg + ~long:"fresh-probability" + ~placeholder:"float in [0;1]" + ~doc: + (Format.sprintf + "Probability for each transaction's destination to be a fresh \ + account. The default value is %g. This new account may then be used \ + as source or destination of subsequent transactions, just like the \ + accounts that were initially provided to the command. Note that when \ + [--single-op-per-pkh-per-block] is set, the new account will not be \ + used as source until the head changes." + default_parameters.fresh_probability) + (parameter (fun (cctxt : Protocol_client_context.full) s -> + match float_of_string s with + | exception _ -> + cctxt#error + "While parsing --fresh-probability: could not convert argument \ + to float" + | f when f < 0.0 || f > 1.0 -> + cctxt#error "While parsing --fresh-probability: invalid argument" + | f -> return f)) + +let strategy_arg = + let open Clic in + arg + ~long:"strategy" + ~placeholder:"fixed:mutez | evaporation:[0;1]" + ~doc:"wealth redistribution strategy" + (parameter (fun (cctxt : Protocol_client_context.full) s -> + match parse_strategy s with + | Error msg -> cctxt#error "While parsing --strategy: %s" msg + | Ok strategy -> return strategy)) + +let gas_limit_arg = + let open Clic in + let gas_limit_kind = + parameter (fun _ s -> + try + let v = Z.of_string s in + return (Gas.Arith.integral_exn v) + with _ -> failwith "invalid gas limit (must be a positive number)") + in + arg + ~long:"gas-limit" + ~short:'G' + ~placeholder:"amount" + ~doc: + (Format.asprintf + "Set the gas limit of the transaction instead of using the default \ + value of %a" + Gas.Arith.pp_integral + default_parameters.gas_limit) + gas_limit_kind + +let storage_limit_arg = + let open Clic in + let storage_limit_kind = + parameter (fun _ s -> + try + let v = Z.of_string s in + assert (Compare.Z.(v >= Z.zero)) ; + return v + with _ -> + failwith "invalid storage limit (must be a positive number of bytes)") + in + arg + ~long:"storage-limit" + ~short:'S' + ~placeholder:"amount" + ~doc: + (Format.asprintf + "Set the storage limit of the transaction instead of using the \ + default value of %a" + Z.pp_print + default_parameters.storage_limit) + storage_limit_kind + +let transfers_arg = + let open Clic in + arg + ~long:"transfers" + ~placeholder:"integer" + ~doc:"total number of transfers to perform, unbounded if not specified" + (parameter (fun (cctxt : Protocol_client_context.full) s -> + match int_of_string s with + | exception _ -> + cctxt#error "While parsing --transfers: invalid integer literal" + | i when i <= 0 -> + cctxt#error "While parsing --transfers: negative integer" + | i -> return i)) + +let single_op_per_pkh_per_block_arg = + Clic.switch + ~long:"single-op-per-pkh-per-block" + ~doc: + "ensure that the operations are not rejected by limiting the injection \ + to 1 operation per public_key_hash per block." + () + +let verbose_arg = + Clic.switch + ~long:"verbose" + ~doc:"Display detailed logs of the injected operations" + () + +let debug_arg = Clic.switch ~long:"debug" ~doc:"Display debug logs" () + +let set_option opt f x = Option.fold ~none:x ~some:(f x) opt + +let save_pool_callback (cctxt : Protocol_client_context.full) pool_source state + = + let json = + Data_encoding.Json.construct + input_source_list_encoding + (List.map unnormalize_source state.pool) + in + let catch_write_error = function + | Error e -> + cctxt#message + "could not write back json file: %a" + Error_monad.pp_print_trace + e + | Ok () -> Lwt.return_unit + in + match pool_source with + | From_string _ -> + (* If the initial pool was given directly as json, save pool to + a temp file. *) + let path = Filename.temp_file "client-stresstest-pool-" ".json" in + cctxt#message "writing back address pool in file %s" path >>= fun () -> + Lwt_utils_unix.Json.write_file path json >>= catch_write_error + | From_file {path; _} -> + (* If the pool specification was a json file, save pool to + the same file. *) + cctxt#message "writing back address pool in file %s" path >>= fun () -> + Lwt_utils_unix.Json.write_file path json >>= catch_write_error + +let generate_random_transactions = + let open Clic in + command + ~group + ~desc:"Generate random transactions" + (args11 + seed_arg + tps_arg + fresh_probability_arg + strategy_arg + Client_proto_args.fee_arg + gas_limit_arg + storage_limit_arg + transfers_arg + single_op_per_pkh_per_block_arg + verbose_arg + debug_arg) + (prefixes ["stresstest"; "transfer"; "using"] + @@ param + ~name:"sources.json" + ~desc: + {|List of accounts from which to perform transfers in JSON format. The input JSON must be an array of objects of the form {"pkh":"","pk":"","sk":""} or {"alias":""} or {"pkh":""} with the pkh, pk and sk encoded in B58 form."|} + json_file_or_text_parameter + @@ stop) + (fun ( seed, + tps, + freshp, + strat, + fee, + gas_limit, + storage_limit, + transfers, + single_op_per_pkh_per_block, + verbose_flag, + debug_flag ) + sources_json + (cctxt : Protocol_client_context.full) -> + verbose := verbose_flag ; + debug := debug_flag ; + let parameters = + default_parameters + |> set_option seed (fun parameter seed -> {parameter with seed}) + |> set_option tps (fun parameter tps -> {parameter with tps}) + |> set_option freshp (fun parameter fresh_probability -> + {parameter with fresh_probability}) + |> set_option strat (fun parameter strategy -> + {parameter with strategy}) + |> set_option fee (fun parameter fee_mutez -> + {parameter with fee_mutez}) + |> set_option gas_limit (fun parameter gas_limit -> + {parameter with gas_limit}) + |> set_option storage_limit (fun parameter storage_limit -> + {parameter with storage_limit}) + |> set_option transfers (fun parameter transfers -> + {parameter with total_transfers = Some transfers}) + |> fun parameter -> {parameter with single_op_per_pkh_per_block} + in + match + Data_encoding.Json.destruct + input_source_list_encoding + (json_of_pool_source sources_json) + with + | exception _ -> cctxt#error "Could not decode list of sources" + | [] -> cctxt#error "It is required to provide sources" + | sources -> + List.filter_map_p (normalize_source cctxt) sources >>= fun sources -> + let counters = Signature.Public_key_hash.Table.create 1023 in + let rng_state = Random.State.make [|parameters.seed|] in + Shell_services.Blocks.hash cctxt () >>=? fun current_head_on_start -> + let state = + { + current_head_on_start; + counters; + pool = sources; + pool_size = List.length sources; + shuffled_pool = + (if parameters.single_op_per_pkh_per_block then + Some + (List.shuffle + ~rng_state + (List.map (fun src_org -> src_org.source) sources)) + else None); + revealed = Signature.Public_key_hash.Set.empty; + last_block = current_head_on_start; + new_block_condition = Lwt_condition.create (); + injected_operations = Block_hash.Table.create 1023; + } + in + let exit_callback_id = + Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _retcode -> + stat_on_exit cctxt state >>= function + | Ok () -> Lwt.return_unit + | Error e -> + cctxt#message "Error: %a" Error_monad.pp_print_trace e) + in + let save_pool () = save_pool_callback cctxt sources_json state in + (* Register a callback for saving the pool when the tool is interrupted + through ctrl-c *) + let exit_callback_id = + Lwt_exit.register_clean_up_callback + ~loc:__LOC__ + ~after:[exit_callback_id] + (fun _retcode -> save_pool ()) + in + let save_injected_operations () = + save_injected_operations cctxt state + in + ignore + (Lwt_exit.register_clean_up_callback + ~loc:__LOC__ + ~after:[exit_callback_id] + (fun _retcode -> save_injected_operations ())) ; + launch cctxt parameters state rng_state save_pool) + +let commands network () = + match network with + | Some `Mainnet -> [] + | Some `Testnet | None -> [generate_random_transactions] diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_utils_commands.ml b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_utils_commands.ml new file mode 100644 index 000000000000..7f57941fb389 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_utils_commands.ml @@ -0,0 +1,162 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Client_proto_utils + +let group = {Clic.name = "utilities"; title = "Utility Commands"} + +let unsigned_block_header_param = + let open Clic in + param + ~name:"unsigned block header" + ~desc:"A hex or JSON encoded unsigned block header" + @@ parameter (fun _ s -> + let bytes_opt = `Hex s |> Hex.to_bytes in + let enc = Protocol.Alpha_context.Block_header.unsigned_encoding in + Option.bind bytes_opt (Data_encoding.Binary.of_bytes_opt enc) + |> function + | Some s -> return s + | None -> ( + let error = + Exn + (Failure + "Cannot decode unsigned block header: is it valid JSON or \ + hexadecimal?") + in + let open Data_encoding.Json in + from_string s |> function + | Error _ -> fail error + | Ok json -> ( + try destruct enc json |> return with _ -> fail error))) + +let commands () = + let open Clic in + let string_param ~name ~desc = + param ~name ~desc Client_proto_args.string_parameter + in + let block_arg = + default_arg + ~long:"branch" + ~short:'b' + ~placeholder:"hash|tag" + ~doc: + "Block hash used to create the no-op operation to sign (possible tags \ + are 'head' and 'genesis'). Defaults to 'genesis'. Note that the the \ + genesis block hash is network-dependent." + ~default:(Block_services.to_string `Genesis) + (Client_config.block_parameter ()) + in + [ + command + ~group + ~desc: + "Sign a message and display it using the failing_noop operation. This \ + operation is not executable in the protocol. Please note that \ + signing/checking an arbitrary message in itself is not sufficient to \ + verify a key ownership" + (args1 block_arg) + (prefixes ["sign"; "message"] + @@ string_param ~name:"message" ~desc:"message to sign" + @@ prefixes ["for"] + @@ Client_keys.Secret_key.source_param + ~name:"src" + ~desc:"name of the signer contract" + @@ stop) + (fun block_head message src_sk cctxt -> + Shell_services.Blocks.hash cctxt ~chain:cctxt#chain ~block:block_head () + >>=? fun block -> + sign_message cctxt ~src_sk ~block ~message >>=? fun signature -> + cctxt#message "Signature: %a" Signature.pp signature >>= fun () -> + return_unit); + command + ~group + ~desc: + "Check the signature of an arbitrary message using the failing_noop \ + operation. Please note that signing/checking an arbitrary message in \ + itself is not sufficient to verify a key ownership." + (args2 + block_arg + (switch ~doc:"Use only exit codes" ~short:'q' ~long:"quiet" ())) + (prefixes ["check"; "that"; "message"] + @@ string_param ~name:"message" ~desc:"signed message" + @@ prefixes ["was"; "signed"; "by"] + @@ Client_keys.Public_key.alias_param + ~name:"signer" + ~desc:"name of the signer contract" + @@ prefixes ["to"; "produce"] + @@ param + ~name:"signature" + ~desc:"the signature to check" + Client_proto_args.signature_parameter + @@ stop) + (fun (block_head, quiet) + message + (_, (key_locator, _)) + signature + (cctxt : #Protocol_client_context.full) -> + Shell_services.Blocks.hash cctxt ~chain:cctxt#chain ~block:block_head () + >>=? fun block -> + check_message cctxt ~key_locator ~block ~quiet ~message ~signature + >>=? function + | false -> cctxt#error "invalid signature" + | true -> + if quiet then return_unit + else + cctxt#message "Signature check successful" >>= fun () -> + return_unit); + command + ~group + ~desc: + "Sign an arbitrary unsigned block header for a given delegate and \ + return the signed block." + no_options + (prefixes ["sign"; "block"] + @@ unsigned_block_header_param + @@ prefixes ["for"] + @@ Client_keys.Public_key_hash.source_param + ~name:"delegate" + ~desc:"signing delegate" + @@ stop) + (fun () + unsigned_block_header + delegate + (cctxt : #Protocol_client_context.full) -> + let unsigned_header = + Data_encoding.Binary.to_bytes_exn + Protocol.Alpha_context.Block_header.unsigned_encoding + unsigned_block_header + in + Shell_services.Chain.chain_id cctxt ~chain:cctxt#chain () + >>=? fun chain_id -> + Client_keys.get_key cctxt delegate >>=? fun (_, _, sk) -> + Client_keys.sign + cctxt + ~watermark: + (Protocol.Alpha_context.Block_header.to_watermark + (Block_header chain_id)) + sk + unsigned_header + >>=? fun s -> cctxt#message "%a" Hex.pp (Signature.to_hex s) >>= return); + ] diff --git a/src/proto_012_PsiThaCa/lib_client_commands/client_proto_utils_commands.mli b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_utils_commands.mli new file mode 100644 index 000000000000..0d38cde9a251 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/client_proto_utils_commands.mli @@ -0,0 +1,26 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_PsiThaCa/lib_client_commands/dune b/src/proto_012_PsiThaCa/lib_client_commands/dune new file mode 100644 index 000000000000..25a169f2f9b5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/dune @@ -0,0 +1,57 @@ +(library + (name tezos_client_012_PsiThaCa_commands) + (instrumentation (backend bisect_ppx)) + (public_name tezos-client-012-PsiThaCa-commands) + (libraries tezos-base + tezos-stdlib-unix + tezos-protocol-012-PsiThaCa + tezos-protocol-environment + tezos-shell-services + tezos-mockup + tezos-mockup-registration + tezos-mockup-commands + tezos-client-base-unix + tezos-client-012-PsiThaCa + tezos-client-commands + tezos-rpc + tezos-protocol-plugin-012-PsiThaCa) + (library_flags (:standard -linkall)) + (modules (:standard \ alpha_commands_registration)) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -open Tezos_stdlib_unix + -open Tezos_shell_services + -open Tezos_client_base + -open Tezos_client_012_PsiThaCa + -open Tezos_client_commands + -open Tezos_rpc + -open Tezos_client_base_unix + -open Tezos_protocol_plugin_012_PsiThaCa))) + +(library + (name tezos_client_012_PsiThaCa_commands_registration) + (instrumentation (backend bisect_ppx)) + (public_name tezos-client-012-PsiThaCa-commands-registration) + (libraries tezos-base + tezos-protocol-012-PsiThaCa + tezos-protocol-environment + tezos-shell-services + tezos-client-base + tezos-client-012-PsiThaCa + tezos-client-commands + tezos-client-012-PsiThaCa-commands + tezos-client-sapling-012-PsiThaCa + tezos-rpc + tezos-protocol-plugin-012-PsiThaCa) + (library_flags (:standard -linkall)) + (modules alpha_commands_registration) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -open Tezos_shell_services + -open Tezos_client_base + -open Tezos_client_012_PsiThaCa + -open Tezos_client_commands + -open Tezos_client_012_PsiThaCa_commands + -open Tezos_client_sapling_012_PsiThaCa + -open Tezos_rpc + -open Tezos_protocol_plugin_012_PsiThaCa))) diff --git a/src/proto_012_PsiThaCa/lib_client_commands/dune-project b/src/proto_012_PsiThaCa/lib_client_commands/dune-project new file mode 100644 index 000000000000..7a9ba6f96d2b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-client-alpha-commands) diff --git a/src/proto_012_PsiThaCa/lib_client_commands/tezos-client-012-PsiThaCa-commands-registration.opam b/src/proto_012_PsiThaCa/lib_client_commands/tezos-client-012-PsiThaCa-commands-registration.opam new file mode 100644 index 000000000000..17660271d725 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/tezos-client-012-PsiThaCa-commands-registration.opam @@ -0,0 +1,24 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-shell-services" + "tezos-client-base" + "tezos-client-012-PsiThaCa" + "tezos-client-012-PsiThaCa-commands" + "tezos-client-sapling-012-PsiThaCa" + "tezos-client-commands" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol-specific commands for `tezos-client`" diff --git a/src/proto_012_PsiThaCa/lib_client_commands/tezos-client-012-PsiThaCa-commands.opam b/src/proto_012_PsiThaCa/lib_client_commands/tezos-client-012-PsiThaCa-commands.opam new file mode 100644 index 000000000000..fd9bfbb057ad --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_commands/tezos-client-012-PsiThaCa-commands.opam @@ -0,0 +1,22 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-shell-services" + "tezos-client-base-unix" + "tezos-client-012-PsiThaCa" + "tezos-client-commands" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol-specific commands for `tezos-client`" diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/.ocamlformat b/src/proto_012_PsiThaCa/lib_client_sapling/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/client_sapling_commands.ml b/src/proto_012_PsiThaCa/lib_client_sapling/client_sapling_commands.ml new file mode 100644 index 000000000000..3a268e4a37a3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/client_sapling_commands.ml @@ -0,0 +1,796 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Clic +open Client_keys +open Tezos_sapling.Core.Client + +let json_switch = switch ~long:"json" ~doc:"Use JSON format" () + +let save_json_to_file json file = + let output_channel = open_out_bin file in + let ppf = Format.formatter_of_out_channel output_channel in + Data_encoding.Json.pp ppf json ; + Format.pp_print_flush ppf () ; + close_out output_channel + +let group = + { + Clic.name = "sapling"; + title = "Commands for working with Sapling transactions"; + } + +let keys_of_implicit_account cctxt source = + match Protocol.Alpha_context.Contract.is_implicit source with + | None -> assert false + | Some src -> + Client_keys.get_key cctxt src >>=? fun (_, pk, sk) -> return (src, pk, sk) + +let viewing_key_of_string s = + let exception Unknown_sapling_address in + let encoding = Viewing_key.address_b58check_encoding in + WithExceptions.Option.to_exn + ~none:Unknown_sapling_address + (Base58.simple_decode encoding s) + +(** All signatures are done with an anti-replay string. + In Tezos' protocol this string is set to be chain_id + KT1. **) +let anti_replay cctxt contract = + Tezos_shell_services.Chain_services.chain_id cctxt ~chain:cctxt#chain () + >>=? fun chain_id -> + let address = Protocol.Alpha_context.Contract.to_b58check contract in + let chain_id = Chain_id.to_b58check chain_id in + return (address ^ chain_id) + +let do_unshield cctxt contract src_name stez dst = + anti_replay cctxt contract >>=? fun anti_replay -> + Wallet.new_address cctxt src_name None >>=? fun (src, _, backdst) -> + Context.Client_state.sync_and_scan cctxt contract >>=? fun contract_state -> + Lwt.return + @@ Context.unshield ~src ~dst ~backdst stez contract_state anti_replay + +let do_shield cctxt ?message contract utez dst = + anti_replay cctxt contract >>=? fun anti_replay -> + Context.Client_state.sync_and_scan cctxt contract >>=? fun contract_state -> + let dst = viewing_key_of_string dst in + Context.shield cctxt ~dst ?message utez contract_state anti_replay + +let do_sapling_transfer cctxt ?message contract src_name amount dst = + anti_replay cctxt contract >>=? fun anti_replay -> + Wallet.new_address cctxt src_name None >>=? fun (src, _, backdst) -> + Context.Client_state.sync_and_scan cctxt contract >>=? fun contract_state -> + let dst = viewing_key_of_string dst in + Context.transfer + cctxt + ~src + ~dst + ~backdst + ?message + amount + contract_state + anti_replay + +let message_arg = + let open Clic in + arg + ~long:"message" + ~placeholder:"" + ~doc:"Message for Sapling transaction" + (parameter (fun _ x -> return @@ Bytes.of_string x)) + +let memo_size_arg = + let open Clic in + arg + ~long:"memo-size" + ~placeholder:"memo-size" + ~doc:"Expected length for message of Sapling transaction" + (parameter (fun _ s -> + match + let i = int_of_string s in + assert (i >= 0 && i <= 65535) ; + i + with + | i -> return i + | exception _ -> + failwith "invalid memo-size (must be between 0 and 65535)")) + +let shield_cmd = + let open Client_proto_args in + let open Client_proto_context_commands in + let open Protocol.Alpha_context in + let open Client_proto_contracts in + command + ~group + ~desc:"Shield tokens from an implicit account to a Sapling address." + (args14 + fee_arg + dry_run_switch + verbose_signing_switch + gas_limit_arg + storage_limit_arg + counter_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg + message_arg) + (prefixes ["sapling"; "shield"] + @@ tez_param + ~name:"qty" + ~desc:"Amount taken from transparent wallet of source." + @@ prefix "from" + @@ ContractAlias.destination_param + ~name:"src-tz" + ~desc:"Transparent source account." + @@ prefix "to" + @@ Clic.string ~name:"dst-sap" ~desc:"Sapling address of destination." + @@ prefix "using" + @@ ContractAlias.destination_param + ~name:"sapling contract" + ~desc:"Smart contract to submit this transaction to." + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap, + message ) + amount + (_, source) + sapling_dst + (_contract_name, contract_dst) + cctxt -> + keys_of_implicit_account cctxt source >>=? fun (pkh, src_pk, src_sk) -> + let open Context in + cctxt#warning + "Shielding %a from %a to %s@ entails a loss of privacy@." + Tez.pp + amount + Contract.pp + source + sapling_dst + >>= fun () -> + do_shield cctxt ?message contract_dst amount sapling_dst + >>=? fun sapling_input -> + let arg = Shielded_tez_contract_input.as_arg sapling_input in + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_context.transfer + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~fee_parameter + ~amount + ~src_pk + ~src_sk + ~destination:contract_dst + ~source:pkh + ~arg + ?confirmations:cctxt#confirmations + ?fee + ~dry_run + ~verbose_signing + ?gas_limit + ?storage_limit + ?counter + () + >>= fun errors -> + report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + errors + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit) + +let unshield_cmd = + let open Client_proto_args in + let open Client_proto_context_commands in + let open Protocol.Alpha_context in + let open Client_proto_contracts in + command + ~group + ~desc:"Unshield tokens from a Sapling address to an implicit account." + (args13 + fee_arg + dry_run_switch + verbose_signing_switch + gas_limit_arg + storage_limit_arg + counter_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg) + (prefixes ["sapling"; "unshield"] + @@ tez_param + ~name:"qty" + ~desc:"Amount taken from shielded wallet of source." + @@ prefix "from" + @@ Sapling_key.alias_param + ~name:"src-sap" + ~desc:"Sapling account of source." + @@ prefix "to" + @@ ContractAlias.destination_param + ~name:"dst-tz" + ~desc:"Transparent destination account." + @@ prefix "using" + @@ ContractAlias.destination_param + ~name:"sapling contract" + ~desc:"Smart contract to submit this transaction to." + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap ) + amount + (name, _sapling_uri) + (_, tz_dst) + (_contract_name, contract_dst) + cctxt -> + let open Context in + let stez = Shielded_tez.of_tez amount in + cctxt#warning + "Unshielding %a from %s to %a@ entails a loss of privacy@." + Shielded_tez.pp + stez + name + Contract.pp + tz_dst + >>= fun () -> + keys_of_implicit_account cctxt tz_dst >>=? fun (source, src_pk, src_sk) -> + do_unshield cctxt contract_dst name stez source >>=? fun sapling_input -> + let arg = Shielded_tez_contract_input.as_arg sapling_input in + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_context.transfer + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + ~fee_parameter + ~amount:Tez.zero + ~src_pk + ~src_sk + ~destination:contract_dst + ~source + ~arg + ?confirmations:cctxt#confirmations + ?fee + ~dry_run + ~verbose_signing + ?gas_limit + ?storage_limit + ?counter + () + >>= fun errors -> + report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + errors + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit) + +(* Default name for Sapling transaction file *) +let sapling_transaction_file = "sapling_transaction" + +let file_arg default_filename = + let open Clic in + arg + ~long:"file" + ~placeholder:default_filename + ~doc:"file name" + (parameter (fun _ x -> return x)) + +(** Shielded transaction are first forged and printed in a file. + Then they are submitted with the next command. **) +let forge_shielded_cmd = + let open Client_proto_args in + let open Client_proto_context_commands in + let open Client_proto_contracts in + command + ~group + ~desc:"Forge a sapling transaction and save it to a file." + (args16 + fee_arg + dry_run_switch + verbose_signing_switch + gas_limit_arg + storage_limit_arg + counter_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg + message_arg + (file_arg sapling_transaction_file) + json_switch) + (prefixes ["sapling"; "forge"; "transaction"] + @@ tez_param + ~name:"qty" + ~desc:"Amount taken from shielded wallet of source." + @@ prefix "from" + @@ Sapling_key.alias_param + ~name:"src-sap" + ~desc:"Sapling account of source." + @@ prefix "to" + @@ Clic.string ~name:"dst-sap" ~desc:"Sapling address of destination." + @@ prefix "using" + @@ ContractAlias.destination_param + ~name:"sapling contract" + ~desc:"Smart contract to submit this transaction to." + @@ stop) + (fun ( _fee, + _dry_run, + _verbose_signing, + _gas_limit, + _storage_limit, + _counter, + _no_print_source, + _minimal_fees, + _minimal_nanotez_per_byte, + _minimal_nanotez_per_gas_unit, + _force_low_fee, + _fee_cap, + _burn_cap, + message, + file, + use_json_format ) + amount + (name, _sapling_uri) + destination + (_contract_name, contract_dst) + cctxt -> + let open Context in + let stez = Shielded_tez.of_tez amount in + do_sapling_transfer cctxt ?message contract_dst name stez destination + >>=? fun transaction -> + let file = Option.value ~default:sapling_transaction_file file in + cctxt#message "Writing transaction to %s@." file >>= fun () -> + (if use_json_format then + save_json_to_file + (Data_encoding.Json.construct UTXO.transaction_encoding transaction) + file + else + let bytes = + Hex.of_bytes + (Data_encoding.Binary.to_bytes_exn + UTXO.transaction_encoding + transaction) + in + let file = open_out_bin file in + Printf.fprintf file "0x%s" (Hex.show bytes) ; + close_out file) ; + return_unit) + +let submit_shielded_cmd = + let open Client_proto_context_commands in + let open Client_proto_args in + let open Client_proto_contracts in + command + ~group + ~desc:"Submit a forged sapling transaction." + (args14 + fee_arg + dry_run_switch + verbose_signing_switch + gas_limit_arg + storage_limit_arg + counter_arg + no_print_source_flag + minimal_fees_arg + minimal_nanotez_per_byte_arg + minimal_nanotez_per_gas_unit_arg + force_low_fee_arg + fee_cap_arg + burn_cap_arg + json_switch) + (prefixes ["sapling"; "submit"] + (* TODO: Add a dedicated abstracted Clic element to parse filenames, + potentially using Sys.file_exists *) + @@ Clic.string ~name:"file" ~desc:"Filename of the forged transaction." + @@ prefix "from" + @@ ContractAlias.destination_param + ~name:"alias-tz" + ~desc:"Transparent account paying the fees." + @@ prefix "using" + @@ ContractAlias.destination_param + ~name:"sapling contract" + ~desc:"Smart contract to submit this transaction to." + @@ stop) + (fun ( fee, + dry_run, + verbose_signing, + gas_limit, + storage_limit, + counter, + no_print_source, + minimal_fees, + minimal_nanotez_per_byte, + minimal_nanotez_per_gas_unit, + force_low_fee, + fee_cap, + burn_cap, + use_json_format ) + filename + (_, source) + (contract_name, destination) + (cctxt : Protocol_client_context.full) -> + cctxt#message + "Reading forge transaction from file %s -- sending it to %s@." + filename + contract_name + >>= fun () -> + let open Context in + (if use_json_format then + Lwt_utils_unix.Json.read_file filename >>=? fun json -> + return @@ Data_encoding.Json.destruct UTXO.transaction_encoding json + else + Lwt_utils_unix.read_file filename >>= fun hex -> + let hex = + (* remove 0x *) + String.sub hex 2 (String.length hex - 2) + in + return + @@ Data_encoding.Binary.of_bytes_exn + UTXO.transaction_encoding + Hex.(to_bytes_exn (`Hex hex))) + >>=? fun transaction -> + return Shielded_tez_contract_input.(as_arg (create transaction)) + >>=? fun contract_input -> + let chain = cctxt#chain and block = cctxt#block in + keys_of_implicit_account cctxt source >>=? fun (source, src_pk, src_sk) -> + let open Protocol.Alpha_context in + let fee_parameter = + { + Injection.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee; + fee_cap; + burn_cap; + } + in + Client_proto_context.transfer + cctxt + ~chain + ~block + ~fee_parameter + ~amount:Tez.zero + ~src_pk + ~src_sk + ~destination + ~source + ~arg:contract_input + ?confirmations:cctxt#confirmations + ?fee + ~dry_run + ~verbose_signing + ?gas_limit + ?storage_limit + ?counter + () + >>= fun errors -> + report_michelson_errors + ~no_print_source + ~msg:"transfer simulation failed" + cctxt + errors + >>= function + | None -> return_unit + | Some (_res, _contracts) -> return_unit) + +let for_contract_arg = + Client_proto_contracts.ContractAlias.destination_arg + ~name:"for-contract" + ~doc:"name of the contract to associate new key with" + () + +let unencrypted_switch () = + Clic.switch + ~long:"unencrypted" + ~doc:"Do not encrypt the key on-disk (for testing and debugging)." + () + +let generate_key_cmd = + command + ~group + ~desc:"Generate a new sapling key." + (args2 (Sapling_key.force_switch ()) (unencrypted_switch ())) + (prefixes ["sapling"; "gen"; "key"] @@ Sapling_key.fresh_alias_param @@ stop) + (fun (force, unencrypted) name (cctxt : Protocol_client_context.full) -> + Sapling_key.of_fresh cctxt force name >>=? fun name -> + let mnemonic = Wallet.Mnemonic.new_random in + cctxt#message + "It is important to save this mnemonic in a secure place:@\n\ + @\n\ + %a@\n\ + @\n\ + The mnemonic can be used to recover your spending key.@." + Wallet.Mnemonic.words_pp + (Bip39.to_words mnemonic) + >>= fun () -> + Wallet.register cctxt ~force ~unencrypted mnemonic name >>=? fun _vk -> + return_unit) + +let use_key_for_contract_cmd = + command + ~group + ~desc:"Use a sapling key for a contract." + (args1 memo_size_arg) + (prefixes ["sapling"; "use"; "key"] + @@ Sapling_key.alias_param + ~name:"sapling-key" + ~desc:"Sapling key to use for the contract." + @@ prefixes ["for"; "contract"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"contract" + ~desc:"Contract the key will be used on." + @@ stop) + (fun default_memo_size + (name, _sapling_uri) + (_contract_name, contract) + (cctxt : Protocol_client_context.full) -> + Wallet.find_vk cctxt name >>=? fun vk -> + Context.Client_state.register + cctxt + ~default_memo_size + ~force:false + contract + vk) + +let import_key_cmd = + command + ~group + ~desc:"Restore a sapling key from mnemonic." + (args3 + (Sapling_key.force_switch ()) + (unencrypted_switch ()) + (Clic.arg + ~long:"mnemonic" + ~placeholder:"mnemonic" + ~doc:"Mnemonic as an option, only used for testing and debugging." + Client_proto_args.string_parameter)) + (prefixes ["sapling"; "import"; "key"] + @@ Sapling_key.fresh_alias_param @@ stop) + (fun (force, unencrypted, mnemonic_opt) + fresh_name + (cctxt : Protocol_client_context.full) -> + (match mnemonic_opt with + | None -> + let rec loop_words (acc : string list) i = + if i > 23 then return (List.rev acc) + else + cctxt#prompt_password "Enter word %d: " i >>=? fun word_raw -> + let word = Bytes.to_string word_raw in + match Bip39.index_of_word word with + | None -> loop_words acc i + | Some _ -> loop_words (word :: acc) (succ i) + in + loop_words [] 0 + | Some mnemonic -> return (String.split_on_char ' ' mnemonic)) + >>=? fun words -> + match Bip39.of_words words with + | None -> failwith "Not a valid mnemonic" + | Some mnemonic -> + Sapling_key.of_fresh cctxt force fresh_name >>=? fun name -> + Wallet.register cctxt ~force ~unencrypted mnemonic name >>=? fun _ -> + return_unit) + +let commands () = + let child_index_param = + Clic.param + ~name:"child-index" + ~desc:"Index of the child to derive." + Client_proto_args.int_parameter + in + let index_arg = + Clic.arg + ~doc:"index of the address to generate" + ~long:"address-index" + ~placeholder:"idx" + Client_proto_args.int_parameter + in + [ + generate_key_cmd; + use_key_for_contract_cmd; + import_key_cmd; + command + ~group + ~desc:"Derive a key from an existing one using zip32." + (args4 + (Sapling_key.force_switch ()) + for_contract_arg + (unencrypted_switch ()) + memo_size_arg) + (prefixes ["sapling"; "derive"; "key"] + @@ Sapling_key.fresh_alias_param @@ prefix "from" + @@ Sapling_key.alias_param + @@ prefixes ["at"; "index"] + @@ child_index_param @@ stop) + (fun (force, contract_opt, unencrypted, default_memo_size) + fresh_name + (existing_name, _existing_uri) + child_index + (cctxt : Protocol_client_context.full) -> + Sapling_key.of_fresh cctxt force fresh_name >>=? fun new_name -> + Wallet.derive + cctxt + ~force + ~unencrypted + existing_name + new_name + child_index + >>=? fun (path, vk) -> + cctxt#message + "Derived new key %s from %s with path %s@." + new_name + existing_name + path + >>= fun () -> + (* TODO must pass contract address for now *) + let (_, contract) = + WithExceptions.Option.get ~loc:__LOC__ contract_opt + in + Context.Client_state.register + cctxt + ~default_memo_size + ~force + contract + vk); + command + ~group + ~desc:"Generate an address for a key referenced by alias." + (args1 index_arg) + (prefixes ["sapling"; "gen"; "address"] @@ Sapling_key.alias_param @@ stop) + (fun index_opt (name, _sapling_uri) (cctxt : Protocol_client_context.full) -> + Wallet.new_address cctxt name index_opt + >>=? fun (_, corrected_index, address) -> + let address_b58 = + Base58.simple_encode Viewing_key.address_b58check_encoding address + in + cctxt#message + "Generated address:@.%s@.at index %Ld" + address_b58 + (Viewing_key.index_to_int64 corrected_index) + >>= fun () -> return_unit); + command + ~group + ~desc:"Save a sapling viewing key in a JSON file." + no_options + (prefixes ["sapling"; "export"; "key"] + @@ Sapling_key.alias_param @@ prefix "in" + @@ Clic.param + ~name:"file" + ~desc:"Filename." + Client_proto_args.string_parameter + @@ stop) + (fun () (name, _sapling_uri) file (cctxt : Protocol_client_context.full) -> + Wallet.export_vk cctxt name >>=? fun vk_json -> + return (save_json_to_file vk_json file)); + command + ~group + ~desc:"Get balance associated with given sapling key and contract" + (args1 + (Clic.switch + ~doc:"Print the collection of non-spent inputs." + ~short:'v' + ~long:"verbose" + ())) + (prefixes ["sapling"; "get"; "balance"; "for"] + @@ Sapling_key.alias_param + ~name:"sapling-key" + ~desc:"Sapling key we get balance for." + @@ prefixes ["in"; "contract"] + @@ Client_proto_contracts.ContractAlias.destination_param + ~name:"contract" + ~desc:"Contract we get balance from." + @@ stop) + (fun verbose + (name, _sapling_uri) + (_contract_name, contract) + (cctxt : Protocol_client_context.full) -> + Wallet.find_vk cctxt name >>= function + | Error _ -> cctxt#error "Account %s not found" name + | Ok vk -> ( + Context.Client_state.sync_and_scan cctxt contract + >>=? fun contract_state -> + Context.Contract_state.find_account vk contract_state |> function + | None -> cctxt#error "Account %s not found" name + | Some account -> + (if verbose then + cctxt#answer + "@[Received Sapling transactions for %s@,@[%a@]@]" + name + Context.Account.pp_unspent + account + else Lwt.return_unit) + >>= fun () -> + cctxt#answer + "Total Sapling funds %a%s" + Context.Shielded_tez.pp + (Context.Account.balance account) + Client_proto_args.tez_sym + >>= fun () -> return_unit)); + command + ~group + ~desc:"List sapling keys." + no_options + (fixed ["sapling"; "list"; "keys"]) + (fun () (cctxt : Protocol_client_context.full) -> + Sapling_key.load cctxt >>=? fun l -> + List.iter_s + (fun (s, _) -> cctxt#message "%s" s) + (List.sort (fun (s1, _) (s2, _) -> String.compare s1 s2) l) + >>= fun () -> return_unit); + shield_cmd; + unshield_cmd; + forge_shielded_cmd; + submit_shielded_cmd; + ] diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/client_sapling_commands.mli b/src/proto_012_PsiThaCa/lib_client_sapling/client_sapling_commands.mli new file mode 100644 index 000000000000..769a4eac58e9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/client_sapling_commands.mli @@ -0,0 +1,23 @@ +(* The MIT License (MIT) + * + * Copyright (c) 2019-2020 Nomadic Labs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. *) + +val commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/context.ml b/src/proto_012_PsiThaCa/lib_client_sapling/context.ml new file mode 100644 index 000000000000..e12003adde36 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/context.ml @@ -0,0 +1,553 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Tezos_sapling.Core.Client + +let _ = Random.self_init () + +module Tez = Protocol.Alpha_context.Tez + +module Shielded_tez : sig + type t + + val encoding : t Data_encoding.t + + val pp : Format.formatter -> t -> unit + + val zero : t + + val of_mutez : int64 -> t option + + val to_mutez : t -> int64 + + val of_tez : Tez.t -> t + + val ( +? ) : t -> t -> t tzresult + + val ( -? ) : t -> t -> t tzresult +end = struct + include Tez + + let ( +? ) a b = a +? b |> Environment.wrap_tzresult + + let ( -? ) a b = a -? b |> Environment.wrap_tzresult + + let of_tez t = + let i = Tez.to_mutez t in + assert (UTXO.valid_amount i) ; + WithExceptions.Option.get ~loc:__LOC__ @@ of_mutez i +end + +module Shielded_tez_contract_input = struct + type t = UTXO.transaction * Signature.public_key_hash option + + let create ?pkh tr = (tr, pkh) + + let encoding = + let open Data_encoding in + obj2 + (req "transaction" UTXO.transaction_encoding) + (opt "pkh" Signature.Public_key_hash.encoding) + + let pp ppf t = + let open Data_encoding in + let json = Json.construct encoding t in + Json.pp ppf json + + let michelson (tr, pkopt) = + let open Tezos_micheline in + let open Protocol.Alpha_context in + let a = + Micheline.Bytes + (0, Data_encoding.Binary.to_bytes_exn UTXO.transaction_encoding tr) + in + let b = + match pkopt with + | None -> Micheline.Prim (0, Script.D_None, [], []) + | Some v -> + let value = + Micheline.Bytes + ( 0, + Data_encoding.Binary.to_bytes_exn + Signature.Public_key_hash.encoding + v ) + in + Micheline.Prim (0, Script.D_Some, [value], []) + in + Micheline.strip_locations + @@ Micheline.Seq (0, [Micheline.Prim (0, Script.D_Pair, [a; b], [])]) + + let pp_michelson ppf t = + let value = michelson t in + Michelson_v1_printer.print_expr ppf value + + let as_arg t = Format.asprintf "%a" pp_michelson t +end + +(** The inputs and outputs are shuffled to prevent meta-data analysis. **) +module Shuffle = struct + let list l = + let a = Array.of_list l in + let len = Array.length a in + for i = len downto 2 do + let idx = Random.int i in + let swp_idx = i - 1 in + let tmp = a.(swp_idx) in + a.(swp_idx) <- a.(idx) ; + a.(idx) <- tmp + done ; + Array.to_list a + + let pair x y = if Random.bool () then [y; x] else [x; y] +end + +type error += Balance_too_low of Shielded_tez.t * Shielded_tez.t + +let register_error_kind category ~id ~title ~description ?pp encoding from_error + to_error = + let id = "client_sapling." ^ Protocol.name ^ "." ^ id in + register_error_kind + category + ~id + ~title + ~description + ?pp + encoding + from_error + to_error + +let () = + register_error_kind + `Temporary + ~id:"balance_too_low" + ~title:"Balance too low" + ~description:"The sender contract does not have enough tokens." + ~pp:(fun ppf (balance, amount) -> + Format.fprintf + ppf + "@[Balance too low (%a) to spend %a@]" + Shielded_tez.pp + balance + Shielded_tez.pp + amount) + Data_encoding.( + obj2 + (req "actual_balance" Shielded_tez.encoding) + (req "amount" Shielded_tez.encoding)) + (function + | Balance_too_low (balance, amount) -> Some (balance, amount) | _ -> None) + (fun (balance, amount) -> Balance_too_low (balance, amount)) + +module Storage = Tezos_sapling.Storage +module F = Tezos_sapling.Forge + +module Input_set = struct + include Set.Make (F.Input) + + let to_list = elements + + let pp_f pp i = + Format.fprintf + pp + "@[%s %Ld@]" + (Base58.simple_encode + Viewing_key.address_b58check_encoding + (F.Input.address i)) + (F.Input.amount i) +end + +module Account = struct + type t = { + vk : Viewing_key.t; + unspents : Input_set.t; + balance : Shielded_tez.t; + } + + let encoding = + let open Data_encoding in + conv + (fun cs -> (cs.vk, Input_set.to_list cs.unspents, cs.balance)) + (fun (vk, unspents, balance) -> + {vk; unspents = Input_set.of_list unspents; balance}) + (obj3 + (req "vk" Viewing_key.encoding) + (req "unspents" (list F.Input.encoding)) + (req "balance" Shielded_tez.encoding)) + + let create vk = {vk; unspents = Input_set.empty; balance = Shielded_tez.zero} + + let balance c = c.balance + + let add_unspent c input = + let amount = + WithExceptions.Option.get ~loc:__LOC__ + @@ Shielded_tez.of_mutez (F.Input.amount input) + in + match Shielded_tez.(c.balance +? amount) with + | Error _ -> assert false (* overflow *) + | Ok balance -> + let unspents = Input_set.add input c.unspents in + {c with balance; unspents} + + let remove_unspent c input = + let amount = + WithExceptions.Option.get ~loc:__LOC__ + @@ Shielded_tez.of_mutez (F.Input.amount input) + in + match Shielded_tez.(c.balance -? amount) with + | Error _ -> assert false (* negative balance *) + | Ok balance -> + let unspents = Input_set.remove input c.unspents in + {c with balance; unspents} + + let filter_spent account storage = + Input_set.fold + (fun input acc -> + if F.Input.is_spent input storage account.vk then + remove_unspent acc input + else acc) + account.unspents + account + + let pick_input c = + let ( >?| ) x f = Option.map f x in + Input_set.choose c.unspents >?| fun unspent -> + let c = remove_unspent c unspent in + (unspent, c) + + let pp_unspent : Format.formatter -> t -> unit = + fun ppf a -> + (Format.pp_print_list ~pp_sep:Format.pp_print_cut Input_set.pp_f ppf) + (Input_set.elements a.unspents) +end + +module Contract_state = struct + module Accounts = struct + include Set.Make (struct + type t = Account.t + + let compare a b = + let open Account in + Bytes.compare (Viewing_key.to_bytes a.vk) (Viewing_key.to_bytes b.vk) + end) + + let replace a set = add a (remove a set) + + let find vk accounts = find (Account.create vk) accounts + end + + let accounts_encoding = + let open Data_encoding in + conv + Accounts.elements + (List.fold_left (fun m e -> Accounts.add e m) Accounts.empty) + (list Account.encoding) + + type t = {accounts : Accounts.t; storage : Storage.state} + + let encoding = + let open Data_encoding in + conv + (fun t -> (t.accounts, t.storage)) + (fun (accounts, storage) -> {accounts; storage}) + (obj2 + (req "accounts" accounts_encoding) + (req "storage" Storage.state_encoding)) + + let empty ~memo_size = + {accounts = Accounts.empty; storage = Storage.empty ~memo_size} + + let find_account vk contract_state = Accounts.find vk contract_state.accounts + + let init ~force vk state = + Accounts.find vk state.accounts |> function + | None -> + let accounts = Accounts.add (Account.create vk) state.accounts in + return {state with accounts} + | Some _ -> + if force then + let accounts = Accounts.add (Account.create vk) state.accounts in + return {state with accounts} + else failwith "vk already present" + + let add_unspent vk input accounts = + let account = + Accounts.find vk accounts |> WithExceptions.Option.get ~loc:__LOC__ + in + let account = Account.add_unspent account input in + Accounts.replace account accounts + + (** Scan the Sapling storage of a smart contract and update the accounts of + all known viewing keys for that contract *) + let scan state storage = + (* remove newly spent inputs *) + let accounts = + Accounts.map + (fun account -> Account.filter_spent account storage) + state.accounts + in + (* get all the vks that need to be scanned for *) + let vks = + Accounts.fold (fun account acc -> Account.(account.vk) :: acc) accounts [] + in + let (size, _) = Storage.size storage in + let rec aux pos accounts = + if pos < size then + (* try to decrypt each inputs with all vks *) + List.fold_left + (fun acc vk -> + match F.Input.get storage pos vk with + | None -> acc + | Some input -> (vk, input) :: acc) + [] + vks + |> function + | [] -> aux (Int64.succ pos) accounts + | [(vk, (_message, forge_input))] -> + let is_spent = F.Input.is_spent forge_input storage vk in + if is_spent then aux (Int64.succ pos) accounts + else aux (Int64.succ pos) (add_unspent vk forge_input accounts) + | _ -> assert false (* got more than one decrypting key *) + else accounts + in + let (current_size, _) = Storage.size state.storage in + let accounts = aux current_size accounts in + {accounts; storage} + + (** Update the Sapling storage of a smart contract using a diff, checking that + the resulting Merkle tree has a root equal to the one in the diff. *) + let update_storage contract_state (root, diff) = + let open Protocol.Alpha_context.Sapling in + let storage = + Tezos_sapling.Storage.add + contract_state.storage + diff.commitments_and_ciphertexts + in + let computed_root = Storage.get_root storage in + if computed_root <> root then + Stdlib.failwith "Commitment tree inconsistent wrt to node." + else + let storage = + List.fold_left + (fun s nf -> Storage.add_nullifier s nf) + storage + diff.nullifiers + in + scan contract_state storage +end + +module Client_state = struct + module Map = Map.Make (Protocol.Alpha_context.Contract) + + type t = Contract_state.t Map.t + + let encoding = + let open Data_encoding in + conv + Map.bindings + (List.fold_left (fun m (k, v) -> Map.add k v m) Map.empty) + (list + (obj2 + (req "contract" Protocol.Alpha_context.Contract.encoding) + (req "state" Contract_state.encoding))) + + let filename = "sapling_state" + + let load (cctxt : #Client_context.wallet) = + cctxt#load filename ~default:Map.empty encoding + + let write (cctxt : #Client_context.wallet) t = cctxt#write filename t encoding + + let get_or_init ~default_memo_size contract client_state = + Map.find contract client_state |> function + | None -> ( + match default_memo_size with + | None -> + failwith + "Unknown memo size for contract %s and none was provided in \ + options" + @@ Protocol.Alpha_context.Contract.to_b58check contract + | Some memo_size -> + let contract_state = Contract_state.empty ~memo_size in + let client_state = Map.add contract contract_state client_state in + return (contract_state, client_state)) + | Some contract_state -> return (contract_state, client_state) + + let register cctxt ~force ~default_memo_size contract vk = + load cctxt >>=? fun client_state -> + get_or_init ~default_memo_size contract client_state + >>=? fun (contract_state, client_state) -> + Contract_state.init ~force vk contract_state >>=? fun contract_state -> + let client_state = Map.add contract contract_state client_state in + write cctxt client_state + + let find (cctxt : #Client_context.full) contract state = + Map.find contract state |> function + | None -> + cctxt#error + "Contract %s not found" + (Protocol.Alpha_context.Contract.to_b58check contract) + | Some v -> return v + + (** Call the node RPC to obtain the storage diff of a contract *) + let get_diff cctxt contract offset_commitment offset_nullifier = + Protocol.Alpha_services.Contract.single_sapling_get_diff + cctxt + (cctxt#chain, cctxt#block) + contract + ~offset_commitment + ~offset_nullifier + () + + let sync_and_scan cctxt contract = + load cctxt >>=? fun state -> + find cctxt contract state >>=? fun contract_state -> + let (cm_pos, nf_pos) = Storage.size contract_state.storage in + get_diff cctxt contract cm_pos nf_pos >>=? fun diff -> + let contract_state = Contract_state.update_storage contract_state diff in + let state = Map.add contract contract_state state in + write cctxt state >>=? fun () -> return contract_state +end + +(** Truncate or pad the message to fit the memo_size *) +let adjust_message_length (cctxt : #Client_context.full) ?message memo_size = + match message with + | None -> + cctxt#warning + "no message provided, adding a zeroes filled message of the required \ + length: %d " + memo_size + >|= fun () -> Bytes.make memo_size '\000' + | Some message -> + let message_length = Bytes.length message in + if message_length = memo_size then Lwt.return message + else if message_length > memo_size then + cctxt#warning + "Your message is too long (%d bytes) and will therefore be truncated \ + to %d bytes" + message_length + memo_size + >|= fun () -> Bytes.sub message 0 memo_size + else + cctxt#warning + "Your message is too short (%d bytes) and will therefore be \ + right-padded with zero bytes to reach a %d-byte length" + message_length + memo_size + >|= fun () -> + Bytes.cat message (Bytes.make (memo_size - message_length) '\000') + +let create_payment ~message dst amount = + let amount = Shielded_tez.to_mutez amount in + F.make_output dst amount message + +(** Return a list of inputs belonging to an account sufficient to cover an + amount, together with the change remaining. *) +let get_shielded_amount amount account = + let balance = Account.balance account in + error_unless (balance >= amount) (Balance_too_low (balance, amount)) + >|? fun () -> + let to_pay = Shielded_tez.to_mutez amount in + let inputs_to_spend = [] in + let rec loop to_pay chosen_inputs account = + if Int64.(compare to_pay zero) > 0 then + Account.pick_input account |> function + | None -> + Stdlib.failwith "Not enough inputs" (* TODO raise a proper error *) + | Some (next_in, account) -> + let next_val = F.Input.amount next_in in + let rest_to_pay = Int64.sub to_pay next_val in + loop rest_to_pay (next_in :: chosen_inputs) account + else + let change = + WithExceptions.Option.get ~loc:__LOC__ + @@ Shielded_tez.of_mutez @@ Int64.abs to_pay + in + (chosen_inputs, change) + in + loop to_pay inputs_to_spend account + +let create_payback ~memo_size address amount = + let plaintext_message = Bytes.make memo_size '\000' in + let amount = Shielded_tez.to_mutez amount in + F.make_output address amount plaintext_message + +(* The caller should check that the account exists already *) +let unshield ~src ~dst ~backdst amount (state : Contract_state.t) anti_replay = + let vk = Viewing_key.of_sk src in + let account = + Contract_state.find_account vk state + |> WithExceptions.Option.get ~loc:__LOC__ + in + get_shielded_amount amount account >|? fun (inputs, change) -> + let memo_size = Storage.get_memo_size state.storage in + let payback = create_payback ~memo_size backdst change in + let sapling_transaction = + F.forge_transaction + (Shuffle.list inputs) + [payback] + src + anti_replay + state.storage + in + Shielded_tez_contract_input.create ~pkh:dst sapling_transaction + +let shield cctxt ~dst ?message amount (state : Contract_state.t) anti_replay = + let shielded_amount = Shielded_tez.of_tez amount in + let memo_size = Storage.get_memo_size Contract_state.(state.storage) in + adjust_message_length cctxt ?message memo_size >>= fun message -> + let payment = create_payment ~message dst shielded_amount in + let negative_amount = Int64.neg (Tez.to_mutez amount) in + let sapling_transaction = + F.forge_shield_transaction + [payment] + negative_amount + anti_replay + Contract_state.(state.storage) + in + return (Shielded_tez_contract_input.create sapling_transaction) + +(* The caller should check that the account exists already *) +let transfer cctxt ~src ~dst ~backdst ?message amount (state : Contract_state.t) + anti_replay = + let vk = Viewing_key.of_sk src in + let account = + Contract_state.find_account vk state + |> WithExceptions.Option.get ~loc:__LOC__ + in + let memo_size = Storage.get_memo_size state.storage in + adjust_message_length cctxt ?message memo_size >|= fun message -> + get_shielded_amount amount account >|? fun (inputs, change) -> + let payment = create_payment ~message dst amount in + let payback = create_payback ~memo_size backdst change in + let sapling_transaction = + F.forge_transaction + (Shuffle.list inputs) + (Shuffle.pair payback payment) + src + anti_replay + state.storage + in + sapling_transaction diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/context.mli b/src/proto_012_PsiThaCa/lib_client_sapling/context.mli new file mode 100644 index 000000000000..72963733eb7c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/context.mli @@ -0,0 +1,157 @@ +(* The MIT License (MIT) + * + * Copyright (c) 2019-2020 Nomadic Labs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. *) + +(** + This module allows the creation Sapling transactions: shield, unshield and + transfer. + Because Sapling uses an UTXO model, it is necessary for the client to + maintain locally the set of unspent outputs for each viewing key, for each + smart contract. This operation is called scanning. + This local cache is updated downloading from the node only the difference + from the last scanned state. +*) + +open Tezos_sapling.Core.Client + +module Tez : module type of Protocol.Alpha_context.Tez + +(** This module is used to represent any shielded token to avoid confusing it + with Tez. *) +module Shielded_tez : sig + type t + + val encoding : t Data_encoding.t + + val pp : Format.formatter -> t -> unit + + val zero : t + + val of_mutez : int64 -> t option + + val to_mutez : t -> int64 + + val of_tez : Tez.t -> t + + val ( +? ) : t -> t -> t tzresult +end + +(** Actual input to a smart contract handling Sapling transactions *) +module Shielded_tez_contract_input : sig + type t + + val create : ?pkh:Signature.Public_key_hash.t -> UTXO.transaction -> t + + val encoding : t Data_encoding.t + + val pp : Format.formatter -> t -> unit + + val as_arg : t -> string +end + +(** Account corresponding to a contract and a viewing key *) +module Account : sig + type t + + val balance : t -> Shielded_tez.t + + val pp_unspent : Format.formatter -> t -> unit +end + +(** State of a contract, potentially involving several viewing keys *) +module Contract_state : sig + type t + + val find_account : Viewing_key.t -> t -> Account.t option +end + +module Client_state : sig + type t + + val find : + Protocol_client_context.full -> + Protocol.Alpha_context.Contract.t -> + t -> + Contract_state.t tzresult Lwt.t + + val register : + Protocol_client_context.full -> + force:bool -> + default_memo_size:int option -> + Protocol.Alpha_context.Contract.t -> + Viewing_key.t -> + unit tzresult Lwt.t + + (** Synchronise our local state with the blockchain's. + The state must be recent enough to craft correct transactions. + The limit enforced by the protocol if 120 blocks. + Also scans, ie. checks for incoming payments and add + them to our balance. + **) + val sync_and_scan : + Protocol_client_context.full -> + Protocol.Alpha_context.Contract.t -> + Contract_state.t tzresult Lwt.t +end + +(** [shield ~message ~dst tez cstate anti-replay] returns a transaction + shielding [tez] tez to a sapling address [dst] using a sapling + storage [cstate] and the anti-replay string. *) +val shield : + #Client_context.full -> + dst:Viewing_key.address -> + ?message:bytes -> + Tez.t -> + Contract_state.t -> + string -> + Shielded_tez_contract_input.t tzresult Lwt.t + +(** [unshield ~src_name ~src ~dst ~backdst stez cstate storage] returns + a transaction unshielding [stez] shielded tokens from a sapling wallet + [src] to a transparent tezos address [dst], sending the change back to + [backdst] and using a Sapling storage [cstate] and a anti-replay string. + The transaction is refused if there is an insufficient amount of shielded + tez in the wallet [src], the error is raised with [src_name]. + *) +val unshield : + src:Spending_key.t -> + dst:Signature.public_key_hash -> + backdst:Viewing_key.address -> + Shielded_tez.t -> + Contract_state.t -> + string -> + Shielded_tez_contract_input.t tzresult + +(** [transfer ~message ~src ~dst ~backdst amount cstate anti-replay] creates a + Sapling transaction of [amount] shielded tez from Sapling wallet [src] to + Sapling address [dst], sending the change to [backdst], using a Sapling + storage [cstate] and a anti-replay string. + [~message] is a message that will be uploaded encrypted on chain. *) +val transfer : + #Client_context.full -> + src:Spending_key.t -> + dst:Viewing_key.address -> + backdst:Viewing_key.address -> + ?message:bytes -> + Shielded_tez.t -> + Contract_state.t -> + string -> + UTXO.transaction tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/dune b/src/proto_012_PsiThaCa/lib_client_sapling/dune new file mode 100644 index 000000000000..b57fcb2287ff --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/dune @@ -0,0 +1,19 @@ +(library + (name tezos_client_sapling_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-client-sapling-012-PsiThaCa) + (libraries tezos-base + tezos-crypto + tezos-client-base + tezos-signer-backends + tezos-client-012-PsiThaCa + tezos-client-012-PsiThaCa-commands + tezos-protocol-012-PsiThaCa) + (library_flags (:standard -linkall)) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_stdlib_unix + -open Tezos_client_base + -open Tezos_client_012_PsiThaCa + -open Tezos_client_012_PsiThaCa_commands + -open Tezos_protocol_012_PsiThaCa + -open Tezos_protocol_environment_012_PsiThaCa))) diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/dune-project b/src/proto_012_PsiThaCa/lib_client_sapling/dune-project new file mode 100644 index 000000000000..f0a33c2f223d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(name tezos-client-sapling) +(formatting (enabled_for ocaml)) diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/tezos-client-sapling-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_client_sapling/tezos-client-sapling-012-PsiThaCa.opam new file mode 100644 index 000000000000..e9c7916bdddb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/tezos-client-sapling-012-PsiThaCa.opam @@ -0,0 +1,24 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "ocamlfind" { build } + "dune" { >= "2.9" } + "tezos-base" + "tezos-clic" + "tezos-crypto" + "tezos-client-base" + "tezos-signer-backends" + "tezos-client-012-PsiThaCa" + "tezos-client-012-PsiThaCa-commands" + "tezos-protocol-012-PsiThaCa" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos: sapling support for `tezos-client`" diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/wallet.ml b/src/proto_012_PsiThaCa/lib_client_sapling/wallet.ml new file mode 100644 index 000000000000..e970fd0b2a8a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/wallet.ml @@ -0,0 +1,126 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Client_keys +open Tezos_sapling.Core.Client + +module Mnemonic = struct + let new_random = Bip39.of_entropy (Hacl.Rand.gen 32) + + let to_sapling_key mnemonic = + (* Z-cash needs 32 bytes and BIP-39 gives 64 bytes of entropy. + We xor the two halves in case the entropy is not well distributed. *) + let seed_64_to_seed_32 (seed_64 : bytes) : bytes = + assert (Bytes.length seed_64 = 64) ; + let first_32 = Bytes.sub seed_64 0 32 in + let second_32 = Bytes.sub seed_64 32 32 in + let seed_32 = Bytes.create 32 in + for i = 0 to 31 do + Bytes.set + seed_32 + i + (Char.chr + (Char.code (Bytes.get first_32 i) + lxor Char.code (Bytes.get second_32 i))) + done ; + seed_32 + in + Spending_key.of_seed (seed_64_to_seed_32 (Bip39.to_seed mnemonic)) + + let words_pp = Format.(pp_print_list ~pp_sep:pp_print_space pp_print_string) +end + +(* Transform a spending key to an uri, encrypted or not. *) +let to_uri unencrypted cctxt sapling_key = + if unencrypted then + Tezos_signer_backends.Unencrypted.make_sapling_key sapling_key >>?= return + else Tezos_signer_backends.Encrypted.encrypt_sapling_key cctxt sapling_key + +(** Transform an uri into a spending key, asking for a password if the uri was + encrypted. *) +let from_uri (cctxt : #Client_context.full) uri = + Tezos_signer_backends.Encrypted.decrypt_sapling_key cctxt uri + +let register (cctxt : #Client_context.full) ?(force = false) + ?(unencrypted = false) mnemonic name = + let sk = Mnemonic.to_sapling_key mnemonic in + to_uri unencrypted cctxt sk >>=? fun sk_uri -> + let key = + { + sk = sk_uri; + path = [Spending_key.child_index sk]; + address_index = Viewing_key.default_index; + } + in + Sapling_key.add ~force cctxt name key >>=? fun () -> + return @@ Viewing_key.of_sk sk + +let derive (cctxt : #Client_context.full) ?(force = false) + ?(unencrypted = false) src_name dst_name child_index = + Sapling_key.find cctxt src_name >>=? fun k -> + from_uri cctxt k.sk >>=? fun src_sk -> + let child_index = Int32.of_int child_index in + let dst_sk = Spending_key.derive_key src_sk child_index in + to_uri unencrypted cctxt dst_sk >>=? fun dst_sk_uri -> + let dst_key = + { + sk = dst_sk_uri; + path = child_index :: k.path; + address_index = Viewing_key.default_index; + } + in + (* TODO check this force *) + let _ = force in + Sapling_key.add ~force:true cctxt dst_name dst_key >>=? fun () -> + let path = + String.concat "/" (List.map Int32.to_string (List.rev dst_key.path)) + in + return (path, Viewing_key.of_sk dst_sk) + +let find_vk cctxt name = + Sapling_key.find cctxt name >>=? fun k -> + from_uri cctxt k.sk >>=? fun sk -> return (Viewing_key.of_sk sk) + +let new_address (cctxt : #Client_context.full) name index_opt = + Sapling_key.find cctxt name >>=? fun k -> + let index = + match index_opt with + | None -> k.address_index + | Some i -> Viewing_key.index_of_int64 (Int64.of_int i) + in + from_uri cctxt k.sk >>=? fun sk -> + return (Viewing_key.of_sk sk) >>=? fun vk -> + (* Viewing_key.new_address finds the smallest index greater or equal to + [index] that generates a correct address. *) + let (corrected_index, address) = Viewing_key.new_address vk index in + Sapling_key.update + cctxt + name + {k with address_index = Viewing_key.index_succ corrected_index} + >>=? fun () -> return (sk, corrected_index, address) + +let export_vk cctxt name = + find_vk cctxt name >>=? fun vk -> + return (Data_encoding.Json.construct Viewing_key.encoding vk) diff --git a/src/proto_012_PsiThaCa/lib_client_sapling/wallet.mli b/src/proto_012_PsiThaCa/lib_client_sapling/wallet.mli new file mode 100644 index 000000000000..17e0e59d0af4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_client_sapling/wallet.mli @@ -0,0 +1,75 @@ +(* The MIT License (MIT) + * + * Copyright (c) 2019-2020 Nomadic Labs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. *) + +open Tezos_sapling.Core.Client + +(** Mnemonic of 24 common english words from which a key can be derived. + The mnemonic follows the BIP-39 spec. *) +module Mnemonic : sig + val new_random : Bip39.t + + (** Pretty printer for printing a list of words of a mnemonic. *) + val words_pp : Format.formatter -> string list -> unit +end + +(** Add to the wallet a new spending key derived from a mnemonic and identified + by an alias. The wallet is updated and the corresponding viewing key is + returned. + If [force] it will overwrite an existing alias. *) +val register : + #Client_context.full -> + ?force:bool -> + ?unencrypted:bool -> + Bip39.t -> + string -> + Viewing_key.t tzresult Lwt.t + +(** [derive parent child index] derives a key with alias [child] from an + existing key with alias [parent] at [index] using ZIP32. + If a new index is required the state of the wallet is updated. + The path and viewing key corresponding to the generated key are returned. *) +val derive : + #Client_context.full -> + ?force:bool -> + ?unencrypted:bool -> + string -> + string -> + int -> + (string * Viewing_key.t) tzresult Lwt.t + +val find_vk : #Client_context.full -> string -> Viewing_key.t tzresult Lwt.t + +(** Generate a new address. + If an optional index is provided, try to derive the address at this index, + otherwise use the first viable one. + Not all indexes correspond to a valid address so successive ones are tried. + Once a valid index is found it is recorded in the wallet. + Return also the corresponding sk and vk to avoid asking the user multiple + times for the description password. *) +val new_address : + #Client_context.full -> + string -> + int option -> + (Spending_key.t * Viewing_key.index * Viewing_key.address) tzresult Lwt.t + +val export_vk : + #Client_context.full -> string -> Data_encoding.Json.json tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/.ocamlformat b/src/proto_012_PsiThaCa/lib_delegate/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_delegate/abstract_context_index.ml b/src/proto_012_PsiThaCa/lib_delegate/abstract_context_index.ml new file mode 100644 index 000000000000..c714c2515946 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/abstract_context_index.ml @@ -0,0 +1,35 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = { + checkout_fun : Context_hash.t -> Environment_context.Context.t option Lwt.t; + finalize_fun : unit -> unit Lwt.t; +} + +let abstract index = + { + checkout_fun = Shell_context.checkout index; + finalize_fun = (fun () -> Context.close index); + } diff --git a/src/proto_012_PsiThaCa/lib_delegate/abstract_context_index.mli b/src/proto_012_PsiThaCa/lib_delegate/abstract_context_index.mli new file mode 100644 index 000000000000..617739bd9124 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/abstract_context_index.mli @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = { + checkout_fun : Context_hash.t -> Environment_context.Context.t option Lwt.t; + finalize_fun : unit -> unit Lwt.t; +} + +val abstract : Context.index -> t diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_actions.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_actions.ml new file mode 100644 index 000000000000..83ed9d5d920d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_actions.ml @@ -0,0 +1,531 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Baking_state +module Events = Baking_events.Actions + +type block_kind = + | Fresh of Operation_pool.pool + | Reproposal of { + consensus_operations : packed_operation list; + payload_hash : Block_payload_hash.t; + payload_round : Round.t; + payload : Operation_pool.payload; + } + +type block_to_bake = { + predecessor : block_info; + round : Round.t; + delegate : Baking_state.delegate; + kind : block_kind; +} + +type action = + | Do_nothing + | Inject_block of {block_to_bake : block_to_bake; updated_state : state} + | Inject_preendorsements of { + preendorsements : (delegate * consensus_content) list; + updated_state : state; + } + | Inject_endorsements of { + endorsements : (delegate * consensus_content) list; + updated_state : state; + } + | Update_to_level of level_update + | Synchronize_round of round_update + +and level_update = { + new_level_proposal : proposal; + compute_new_state : + current_round:Round.t -> + delegate_slots:delegate_slots -> + next_level_delegate_slots:delegate_slots -> + (state * action) Lwt.t; +} + +and round_update = { + new_round_proposal : proposal; + handle_proposal : state -> (state * action) Lwt.t; +} + +type t = action + +let pp_action fmt = function + | Do_nothing -> Format.fprintf fmt "do nothing" + | Inject_block _ -> Format.fprintf fmt "inject block" + | Inject_preendorsements _ -> Format.fprintf fmt "inject preendorsements" + | Inject_endorsements _ -> Format.fprintf fmt "inject endorsements" + | Update_to_level _ -> Format.fprintf fmt "update to level" + | Synchronize_round _ -> Format.fprintf fmt "synchronize round" + +let generate_seed_nonce_hash config delegate level = + if level.Level.expected_commitment then + Baking_nonces.generate_seed_nonce config delegate level.level + >>=? fun seed_nonce -> return_some seed_nonce + else return_none + +let sign_block_header state proposer unsigned_block_header = + let cctxt = state.global_state.cctxt in + let chain_id = state.global_state.chain_id in + let force = state.global_state.config.force in + let {Block_header.shell; protocol_data = {contents; _}} = + unsigned_block_header + in + let unsigned_header = + Data_encoding.Binary.to_bytes_exn + Alpha_context.Block_header.unsigned_encoding + (shell, contents) + in + let level = shell.level in + Baking_state.round_of_shell_header shell >>?= fun round -> + let open Baking_highwatermarks in + cctxt#with_lock (fun () -> + let block_location = + Baking_files.resolve_location ~chain_id `Highwatermarks + in + may_sign_block + cctxt + block_location + ~delegate:proposer.public_key_hash + ~level + ~round + >>=? function + | true -> + record_block + cctxt + block_location + ~delegate:proposer.public_key_hash + ~level + ~round + >>=? fun () -> return_true + | false -> + Events.(emit potential_double_baking (level, round)) >>= fun () -> + return force) + >>=? function + | false -> fail (Block_previously_baked {level; round}) + | true -> + Client_keys.sign + cctxt + proposer.secret_key_uri + ~watermark:Block_header.(to_watermark (Block_header chain_id)) + unsigned_header + >>=? fun signature -> + return {Block_header.shell; protocol_data = {contents; signature}} + +let inject_block ~state_recorder state block_to_bake ~updated_state = + let {predecessor; round; delegate; kind} = block_to_bake in + let cctxt = state.global_state.cctxt in + let chain_id = state.global_state.chain_id in + let simulation_mode = state.global_state.validation_mode in + let round_durations = state.global_state.round_durations in + Environment.wrap_tzresult + (Round.timestamp_of_round + round_durations + ~predecessor_timestamp:predecessor.shell.timestamp + ~predecessor_round:predecessor.round + ~round) + >>?= fun timestamp -> + let (simulation_kind, payload_round) = + match kind with + | Fresh pool -> (Block_forge.Filter pool, round) + | Reproposal {consensus_operations; payload_hash; payload_round; payload} -> + ( Block_forge.Apply + { + ordered_pool = + Operation_pool.ordered_pool_of_payload + ~consensus_operations + payload; + payload_hash; + }, + payload_round ) + in + Events.( + emit forging_block (Int32.succ predecessor.shell.level, round, delegate)) + >>= fun () -> + Plugin.RPC.current_level + cctxt + ~offset:1l + (`Hash state.global_state.chain_id, `Hash (predecessor.hash, 0)) + >>=? fun injection_level -> + generate_seed_nonce_hash + state.global_state.config.Baking_configuration.nonce + delegate + injection_level + >>=? fun seed_nonce_opt -> + let seed_nonce_hash = Option.map fst seed_nonce_opt in + (* Set liquidity_baking_escape_vote for this block *) + let default = state.global_state.config.liquidity_baking_escape_vote in + (match state.global_state.config.per_block_vote_file with + | None -> Lwt.return default + | Some per_block_vote_file -> + Liquidity_baking_vote_file.read_liquidity_baking_escape_vote_no_fail + ~default + ~per_block_vote_file) + >>= fun liquidity_baking_escape_vote -> + Block_forge.forge + cctxt + ~chain_id + ~pred_info:predecessor + ~timestamp + ~seed_nonce_hash + ~payload_round + ~liquidity_baking_escape_vote + state.global_state.config.fees + simulation_mode + simulation_kind + state.global_state.constants.parametric + >>=? fun {unsigned_block_header; operations} -> + sign_block_header state delegate unsigned_block_header + >>=? fun signed_block_header -> + (match seed_nonce_opt with + | None -> + (* Nothing to do *) + return_unit + | Some (_, nonce) -> + let block_hash = Block_header.hash signed_block_header in + Baking_nonces.register_nonce cctxt ~chain_id block_hash nonce) + >>=? fun () -> + state_recorder ~new_state:updated_state >>=? fun () -> + Events.( + emit injecting_block (signed_block_header.shell.level, round, delegate)) + >>= fun () -> + Node_rpc.inject_block + cctxt + ~force:state.global_state.config.force + ~chain:(`Hash state.global_state.chain_id) + signed_block_header + operations + >>=? fun bh -> + Events.(emit block_injected (bh, delegate)) >>= fun () -> return updated_state + +let inject_preendorsements ~state_recorder state ~preendorsements ~updated_state + = + let cctxt = state.global_state.cctxt in + let chain_id = state.global_state.chain_id in + (* N.b. signing a lot of operations may take some time *) + (* Don't parallelize signatures: the signer might not be able to + handle concurrent requests *) + List.filter_map_es + (fun (delegate, consensus_content) -> + Events.(emit signing_preendorsement delegate) >>= fun () -> + let shell = + { + Tezos_base.Operation.branch = + state.level_state.latest_proposal.predecessor.hash; + } + in + let contents = Single (Preendorsement consensus_content) in + let level = Raw_level.to_int32 consensus_content.level in + let round = consensus_content.round in + cctxt#with_lock (fun () -> + let block_location = + Baking_files.resolve_location ~chain_id `Highwatermarks + in + Baking_highwatermarks.may_sign_preendorsement + cctxt + block_location + ~delegate:delegate.public_key_hash + ~level + ~round + >>=? function + | true -> + Baking_highwatermarks.record_preendorsement + cctxt + block_location + ~delegate:delegate.public_key_hash + ~level + ~round + >>=? fun () -> return_true + | false -> return state.global_state.config.force) + >>=? fun may_sign -> + (if may_sign then + let unsigned_operation = (shell, Contents_list contents) in + let watermark = Operation.(to_watermark (Preendorsement chain_id)) in + let unsigned_operation_bytes = + Data_encoding.Binary.to_bytes_exn + Operation.unsigned_encoding + unsigned_operation + in + (* TODO: do we want to reload the sk uri or not ? *) + Client_keys.get_key cctxt delegate.public_key_hash >>=? fun (_, _, sk) -> + Client_keys.sign cctxt ~watermark sk unsigned_operation_bytes + else + fail (Baking_highwatermarks.Block_previously_preendorsed {round; level})) + >>= function + | Error err -> + Events.(emit skipping_preendorsement (delegate, err)) >>= fun () -> + return_none + | Ok signature -> + let protocol_data = + Operation_data {contents; signature = Some signature} + in + let operation : Operation.packed = {shell; protocol_data} in + return_some (delegate, operation)) + preendorsements + >>=? fun signed_operations -> + state_recorder ~new_state:updated_state >>=? fun () -> + (* TODO: add a RPC to inject multiple operations *) + List.iter_ep + (fun (delegate, operation) -> + let encoded_op = + Data_encoding.Binary.to_bytes_exn Operation.encoding operation + in + protect + ~on_error:(fun err -> + Events.(emit failed_to_inject_preendorsement (delegate, err)) + >>= fun () -> return_unit) + (fun () -> + Shell_services.Injection.operation + cctxt + ~chain:(`Hash chain_id) + encoded_op + >>=? fun oph -> + Events.(emit preendorsement_injected (oph, delegate)) >>= fun () -> + return_unit)) + signed_operations + >>=? fun () -> return updated_state + +let sign_endorsements state endorsements = + let cctxt = state.global_state.cctxt in + let chain_id = state.global_state.chain_id in + (* N.b. signing a lot of operations may take some time *) + (* Don't parallelize signatures: the signer might not be able to + handle concurrent requests *) + List.filter_map_es + (fun (delegate, consensus_content) -> + Events.(emit signing_endorsement delegate) >>= fun () -> + let shell = + { + Tezos_base.Operation.branch = + state.level_state.latest_proposal.predecessor.hash; + } + in + let contents = + (* No preendorsements are included *) + Single (Endorsement consensus_content) + in + let level = Raw_level.to_int32 consensus_content.level in + let round = consensus_content.round in + cctxt#with_lock (fun () -> + let block_location = + Baking_files.resolve_location ~chain_id `Highwatermarks + in + Baking_highwatermarks.may_sign_endorsement + cctxt + block_location + ~delegate:delegate.public_key_hash + ~level + ~round + >>=? function + | true -> + Baking_highwatermarks.record_endorsement + cctxt + block_location + ~delegate:delegate.public_key_hash + ~level + ~round + >>=? fun () -> return_true + | false -> return state.global_state.config.force) + >>=? fun may_sign -> + (if may_sign then + let watermark = Operation.(to_watermark (Endorsement chain_id)) in + let unsigned_operation = (shell, Contents_list contents) in + let unsigned_operation_bytes = + Data_encoding.Binary.to_bytes_exn + Operation.unsigned_encoding + unsigned_operation + in + (* TODO: do we want to reload the sk uri or not ? *) + Client_keys.get_key cctxt delegate.public_key_hash >>=? fun (_, _, sk) -> + Client_keys.sign cctxt ~watermark sk unsigned_operation_bytes + else + fail (Baking_highwatermarks.Block_previously_preendorsed {round; level})) + >>= function + | Error err -> + Events.(emit skipping_endorsement (delegate, err)) >>= fun () -> + return_none + | Ok signature -> + let protocol_data = + Operation_data {contents; signature = Some signature} + in + let operation : Operation.packed = {shell; protocol_data} in + return_some (delegate, operation)) + endorsements + +let inject_endorsements ~state_recorder state ~endorsements ~updated_state = + let cctxt = state.global_state.cctxt in + let chain_id = state.global_state.chain_id in + sign_endorsements state endorsements >>=? fun signed_operations -> + state_recorder ~new_state:updated_state >>=? fun () -> + (* TODO: add a RPC to inject multiple operations *) + List.iter_ep + (fun (delegate, signed_operation) -> + let encoded_op = + Data_encoding.Binary.to_bytes_exn Operation.encoding signed_operation + in + Shell_services.Injection.operation + cctxt + ~chain:(`Hash chain_id) + encoded_op + >>=? fun oph -> + Events.(emit endorsement_injected (oph, delegate)) >>= fun () -> + return_unit) + signed_operations + >>=? fun () -> return updated_state + +let prepare_waiting_for_quorum state = + let consensus_threshold = + state.global_state.constants.parametric.consensus_threshold + in + let get_consensus_operation_voting_power ~slot = + match + SlotMap.find slot state.level_state.delegate_slots.all_delegate_slots + with + | None -> + (* cannot happen if the map is correctly populated *) + 0 + | Some {endorsing_power; _} -> endorsing_power + in + let latest_proposal = state.level_state.latest_proposal.block in + (* assert (latest_proposal.block.round = state.round_state.current_round) ; *) + let candidate = + { + Operation_worker.hash = latest_proposal.hash; + round_watched = latest_proposal.round; + payload_hash_watched = latest_proposal.payload_hash; + } + in + (consensus_threshold, get_consensus_operation_voting_power, candidate) + +let start_waiting_for_preendorsement_quorum state = + let (consensus_threshold, get_preendorsement_voting_power, candidate) = + prepare_waiting_for_quorum state + in + let operation_worker = state.global_state.operation_worker in + Operation_worker.monitor_preendorsement_quorum + operation_worker + ~consensus_threshold + ~get_preendorsement_voting_power + candidate + +let start_waiting_for_endorsement_quorum state = + let (consensus_threshold, get_endorsement_voting_power, candidate) = + prepare_waiting_for_quorum state + in + let operation_worker = state.global_state.operation_worker in + Operation_worker.monitor_endorsement_quorum + operation_worker + ~consensus_threshold + ~get_endorsement_voting_power + candidate + +let compute_round proposal round_durations = + let open Protocol in + let open Baking_state in + (* If our current proposal is the transition block, we suppose a + never ending round 0 *) + if Protocol_hash.(proposal.block.protocol <> proposal.block.next_protocol) + then ok Round.zero + else + let timestamp = Systime_os.now () |> Time.System.to_protocol in + let predecessor_block = proposal.predecessor in + Environment.wrap_tzresult + @@ Alpha_context.Round.round_of_timestamp + round_durations + ~predecessor_timestamp:predecessor_block.shell.timestamp + ~predecessor_round:predecessor_block.round + ~timestamp + +let update_to_level state level_update = + let {new_level_proposal; compute_new_state} = level_update in + let cctxt = state.global_state.cctxt in + let delegates = state.global_state.delegates in + let new_level = new_level_proposal.block.shell.level in + let chain = `Hash state.global_state.chain_id in + (if Int32.(new_level = succ state.level_state.current_level) then + return state.level_state.next_level_delegate_slots + else + Baking_state.compute_delegate_slots cctxt delegates ~level:new_level ~chain) + >>=? fun delegate_slots -> + Baking_state.compute_delegate_slots + cctxt + delegates + ~level:(Int32.succ new_level) + ~chain + >>=? fun next_level_delegate_slots -> + let round_durations = state.global_state.round_durations in + compute_round new_level_proposal round_durations >>?= fun current_round -> + compute_new_state ~current_round ~delegate_slots ~next_level_delegate_slots + >>= return + +let synchronize_round state {new_round_proposal; handle_proposal} = + Events.(emit synchronizing_round new_round_proposal.predecessor.hash) + >>= fun () -> + let round_durations = state.global_state.round_durations in + compute_round new_round_proposal round_durations >>?= fun current_round -> + if Round.(current_round < new_round_proposal.block.round) then + (* impossible *) + failwith + "synchronize_round: current round (%a) is behind the new proposal's \ + round (%a)" + Round.pp + current_round + Round.pp + new_round_proposal.block.round + else + let new_round_state = {current_round; current_phase = Idle} in + let new_state = {state with round_state = new_round_state} in + handle_proposal new_state >>= return + +let rec perform_action ~state_recorder state (action : action) = + match action with + | Do_nothing -> state_recorder ~new_state:state >>=? fun () -> return state + | Inject_block {block_to_bake; updated_state} -> + inject_block state ~state_recorder block_to_bake ~updated_state + | Inject_preendorsements {preendorsements; updated_state} -> + inject_preendorsements + ~state_recorder + state + ~preendorsements + ~updated_state + >>=? fun new_state -> + (* We wait for preendorsements to trigger the + [Prequorum_reached] event *) + start_waiting_for_preendorsement_quorum state >>= fun () -> + return new_state + | Inject_endorsements {endorsements; updated_state} -> + inject_endorsements ~state_recorder state ~endorsements ~updated_state + >>=? fun new_state -> + (* We wait for endorsements to trigger the [Quorum_reached] + event *) + start_waiting_for_endorsement_quorum state >>= fun () -> return new_state + | Update_to_level level_update -> + update_to_level state level_update >>=? fun (new_state, new_action) -> + perform_action ~state_recorder new_state new_action + | Synchronize_round round_update -> + synchronize_round state round_update >>=? fun (new_state, new_action) -> + perform_action ~state_recorder new_state new_action diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_actions.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_actions.mli new file mode 100644 index 000000000000..83789e84892f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_actions.mli @@ -0,0 +1,125 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Baking_state + +type block_kind = + | Fresh of Operation_pool.pool + | Reproposal of { + consensus_operations : packed_operation list; + payload_hash : Block_payload_hash.t; + payload_round : Round.t; + payload : Operation_pool.payload; + } + +type block_to_bake = { + predecessor : block_info; + round : Round.t; + delegate : delegate; + kind : block_kind; +} + +type action = + | Do_nothing + | Inject_block of {block_to_bake : block_to_bake; updated_state : state} + | Inject_preendorsements of { + preendorsements : (delegate * consensus_content) list; + updated_state : state; + } + | Inject_endorsements of { + endorsements : (delegate * consensus_content) list; + updated_state : state; + } + | Update_to_level of level_update + | Synchronize_round of round_update + +and level_update = { + new_level_proposal : proposal; + compute_new_state : + current_round:Round.t -> + delegate_slots:delegate_slots -> + next_level_delegate_slots:delegate_slots -> + (state * action) Lwt.t; +} + +and round_update = { + new_round_proposal : proposal; + handle_proposal : state -> (state * action) Lwt.t; +} + +type t = action + +val generate_seed_nonce_hash : + Baking_configuration.nonce_config -> + delegate -> + Level.t -> + (Nonce_hash.t * Nonce.t) option tzresult Lwt.t + +val inject_block : + state_recorder:(new_state:state -> unit tzresult Lwt.t) -> + state -> + block_to_bake -> + updated_state:state -> + state tzresult Lwt.t + +val inject_preendorsements : + state_recorder:(new_state:state -> unit tzresult Lwt.t) -> + state -> + preendorsements:(delegate * consensus_content) list -> + updated_state:state -> + state tzresult Lwt.t + +val sign_endorsements : + state -> + (delegate * consensus_content) list -> + (delegate * packed_operation) list tzresult Lwt.t + +val inject_endorsements : + state_recorder:(new_state:state -> unit tzresult Lwt.t) -> + state -> + endorsements:(delegate * consensus_content) list -> + updated_state:state -> + state tzresult Lwt.t + +val prepare_waiting_for_quorum : + state -> int * (slot:Slot.t -> int) * Operation_worker.candidate + +val start_waiting_for_preendorsement_quorum : state -> unit Lwt.t + +val start_waiting_for_endorsement_quorum : state -> unit Lwt.t + +val update_to_level : state -> level_update -> (state * t) tzresult Lwt.t + +val pp_action : Format.formatter -> t -> unit + +val compute_round : proposal -> Round.round_durations -> Round.t tzresult + +val perform_action : + state_recorder:(new_state:state -> unit tzresult Lwt.t) -> + state -> + t -> + state tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_cache.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_cache.ml new file mode 100644 index 000000000000..4ce45c7b7a9d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_cache.ml @@ -0,0 +1,85 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Cache structures used to memoize costly RPCs/computations. *) + +open Protocol.Alpha_context + +type round = Round.t + +module Block_cache = + (val Ringo.(map_maker ~replacement:LRU ~overflow:Strong ~accounting:Precise)) + (Block_hash) + +(** The [Timestamp_of_round_tbl] module allows to create memoization tables + to store function calls of [Round.timestamp_of_round]. *) +module Timestamp_of_round_cache = + (val Ringo.(map_maker ~replacement:LRU ~overflow:Strong ~accounting:Precise)) + (struct + (* The type of keys is a tuple that corresponds to the arguments + of [Round.timestamp_of_round]. *) + type t = Timestamp.time * round * round + + let hash k = Hashtbl.hash k + + let equal (ts, r1, r2) (ts', r1', r2') = + Timestamp.(ts = ts') && Round.(r1 = r1') && Round.(r2 = r2') + end) + +module Round_cache_key = struct + type ts_interval = Timestamp.time * Timestamp.time + + (** The values that are intended to be used here are the + arguments are: predecessor_timestamp * predecessor_round * + timestamp_interval *) + type t = { + predecessor_timestamp : Timestamp.time; + predecessor_round : round; + time_interval : ts_interval; + } + + let hash {predecessor_timestamp; predecessor_round; _} = + Stdlib.Hashtbl.hash (predecessor_timestamp, predecessor_round) + + let equal + { + predecessor_timestamp = pred_t; + predecessor_round = pred_r; + time_interval = (t_beg, t_end); + } + { + predecessor_timestamp = pred_t'; + predecessor_round = pred_r'; + time_interval = (t_beg', t_end'); + } = + Timestamp.(pred_t = pred_t') + && Round.(pred_r = pred_r') + && Timestamp.(t_beg' <= t_beg) + && Timestamp.(t_end < t_end') +end + +module Round_timestamp_interval_cache = + (val Ringo.(map_maker ~replacement:LRU ~overflow:Strong ~accounting:Precise)) + (Round_cache_key) diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_commands.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_commands.ml new file mode 100644 index 000000000000..c452ac7dbafd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_commands.ml @@ -0,0 +1,374 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Client_proto_args + +let pidfile_arg = + Clic.arg + ~doc:"write process id in file" + ~short:'P' + ~long:"pidfile" + ~placeholder:"filename" + (Clic.parameter (fun _ s -> return s)) + +let may_lock_pidfile pidfile_opt f = + match pidfile_opt with + | None -> f () + | Some pidfile -> + Lwt_lock_file.try_with_lock + ~when_locked:(fun () -> + failwith "Failed to create the pidfile: %s" pidfile) + ~filename:pidfile + f + +let http_headers = + match Sys.getenv_opt "TEZOS_REMOTE_MEMPOOL_HTTP_HEADERS" with + | None -> None + | Some contents -> + let lines = String.split_on_char '\n' contents in + Some + (List.fold_left + (fun acc line -> + match String.index_opt line ':' with + | None -> + Stdlib.failwith + "Http headers: invalid TEZOS_REMOTE_MEMPOOL_HTTP_HEADERS \ + environment variable, missing colon" + | Some pos -> + let header = String.trim (String.sub line 0 pos) in + let header = String.lowercase_ascii header in + if + header <> "host" + && (String.length header < 2 || String.sub header 0 2 <> "x-") + then + Stdlib.failwith + "Http headers: invalid TEZOS_REMOTE_MEMPOOL_HTTP_HEADERS \ + environment variable, only 'host' or 'x-' headers are \ + supported" ; + let value = + String.trim + (String.sub line (pos + 1) (String.length line - pos - 1)) + in + (header, value) :: acc) + [] + lines) + +let check_endpoint_validity uri = + match Uri.scheme uri with + | Some "http" | Some "https" -> () + | None -> + Stdlib.failwith "no scheme detected, http and https scheme are required" + | Some x -> + Printf.ksprintf + Stdlib.failwith + "invalid scheme '%s' only http and https endpoints are supported" + x + +let mempool_arg = + Clic.arg + ~long:"mempool" + ~placeholder:"file" + ~doc: + "When specified, the baker will try to fetch a mempool from this file \ + (or uri) and will try to include the retrieved operations in the block. \ + The expected format of the content is of the form of the \ + '/chains//mempool/pending_operations' RPC. Environment \ + variable 'TEZOS_REMOTE_MEMPOOL_HTTP_HEADERS' may also be specified to \ + add headers to the requests (only 'host' and custom 'x-...' headers are \ + supported)." + (Clic.map_parameter + ~f:(fun uri -> + let open Baking_configuration in + let path = Uri.to_string uri in + if Sys.file_exists path then Mempool.(Local {filename = path}) + else ( + check_endpoint_validity uri ; + Mempool.(Remote {uri; http_headers}))) + uri_parameter) + +let context_path_arg = + Clic.arg + ~long:"context" + ~placeholder:"path" + ~doc: + "When specified, the client will read in the local context at the \ + provided path in order to build the block, instead of relying on the \ + 'preapply' RPC." + string_parameter + +let endorsement_force_switch_arg = + Clic.switch + ~long:"force" + ~short:'f' + ~doc: + "Disable consistency, injection and double signature checks for \ + (pre)endorsements." + () + +let do_not_monitor_node_mempool_arg = + Clic.switch + ~long:"ignore-node-mempool" + ~doc: + "Ignore mempool operations from the node and do not subsequently monitor \ + them. Use in conjunction with --mempool option to restrict the observed \ + operations to those of the mempool file." + () + +let keep_alive_arg = + Clic.switch + ~doc: + "Keep the daemon process alive: when the connection with the node is \ + lost, the daemon periodically tries to reach it." + ~short:'K' + ~long:"keep-alive" + () + +let liquidity_baking_escape_vote_switch = + Clic.switch + ~doc:"Vote to end the liquidity baking subsidy." + ~long:"liquidity-baking-escape-vote" + () + +let get_delegates (cctxt : Protocol_client_context.full) + (pkhs : Signature.public_key_hash list) = + let proj_delegate (alias, public_key_hash, public_key, secret_key_uri) = + { + Baking_state.alias = Some alias; + public_key_hash; + public_key; + secret_key_uri; + } + in + (if pkhs = [] then + Client_keys.get_keys cctxt >>=? fun keys -> + List.map proj_delegate keys |> return + else + List.map_es + (fun pkh -> + Client_keys.get_key cctxt pkh >>=? function + | (alias, pk, sk_uri) -> return (proj_delegate (alias, pkh, pk, sk_uri))) + pkhs) + >>=? fun delegates -> + Tezos_signer_backends.Encrypted.decrypt_list + cctxt + (List.filter_map + (function + | {Baking_state.alias = Some alias; _} -> Some alias | _ -> None) + delegates) + >>=? fun () -> + let delegates_no_duplicates = List.sort_uniq compare delegates in + (if Compare.List_lengths.(delegates <> delegates_no_duplicates) then + cctxt#warning + "Warning: the list of public key hash aliases contains duplicate hashes, \ + which are ignored" + else Lwt.return ()) + >>= fun () -> return delegates_no_duplicates + +let sources_param = + Clic.seq_of_param + (Client_keys.Public_key_hash.source_param + ~name:"baker" + ~desc:"name of the delegate owning the endorsement right") + +let delegate_commands () : Protocol_client_context.full Clic.command list = + let open Clic in + let group = + {name = "delegate.client"; title = "Tenderbake client commands"} + in + [ + command + ~group + ~desc:"Forge and inject block using the delegates' rights." + (args8 + minimal_fees_arg + minimal_nanotez_per_gas_unit_arg + minimal_nanotez_per_byte_arg + minimal_timestamp_switch + force_switch + mempool_arg + context_path_arg + do_not_monitor_node_mempool_arg) + (prefixes ["bake"; "for"] @@ sources_param) + (fun ( minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + minimal_timestamp, + force, + mempool, + context_path, + do_not_monitor_node_mempool ) + pkhs + cctxt -> + get_delegates cctxt pkhs >>=? fun delegates -> + Baking_lib.bake + cctxt + ~minimal_nanotez_per_gas_unit + ~minimal_timestamp + ~minimal_nanotez_per_byte + ~minimal_fees + ~force + ~monitor_node_mempool:(not do_not_monitor_node_mempool) + ?mempool + ?context_path + delegates); + command + ~group + ~desc:"Forge and inject an endorsement operation." + (args1 endorsement_force_switch_arg) + (prefixes ["endorse"; "for"] @@ sources_param) + (fun force pkhs cctxt -> + get_delegates cctxt pkhs >>=? fun delegates -> + Baking_lib.endorse ~force cctxt delegates); + command + ~group + ~desc:"Forge and inject a preendorsement operation." + (args1 endorsement_force_switch_arg) + (prefixes ["preendorse"; "for"] @@ sources_param) + (fun force pkhs cctxt -> + get_delegates cctxt pkhs >>=? fun delegates -> + Baking_lib.preendorse ~force cctxt delegates); + command + ~group + ~desc:"Send a Tenderbake proposal" + (args7 + minimal_fees_arg + minimal_nanotez_per_gas_unit_arg + minimal_nanotez_per_byte_arg + minimal_timestamp_switch + force_switch + mempool_arg + context_path_arg) + (prefixes ["propose"; "for"] @@ sources_param) + (fun ( minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + minimal_timestamp, + force, + mempool, + context_path ) + sources + cctxt -> + get_delegates cctxt sources >>=? fun delegates -> + Baking_lib.propose + cctxt + ~minimal_nanotez_per_gas_unit + ~minimal_timestamp + ~minimal_nanotez_per_byte + ~minimal_fees + ~force + ?mempool + ?context_path + delegates); + ] + +let directory_parameter = + Clic.parameter (fun _ p -> + if not (Sys.file_exists p && Sys.is_directory p) then + failwith "Directory doesn't exist: '%s'" p + else return p) + +let per_block_vote_file_arg = + Clic.arg + ~doc:"read per block votes as json file" + ~short:'V' + ~long:"votefile" + ~placeholder:"filename" + (Clic.parameter (fun _ s -> return s)) + +let baker_commands () : Protocol_client_context.full Clic.command list = + let open Clic in + let group = + { + Clic.name = "delegate.baker"; + title = "Commands related to the baker daemon."; + } + in + [ + command + ~group + ~desc:"Launch the baker daemon." + (args7 + pidfile_arg + minimal_fees_arg + minimal_nanotez_per_gas_unit_arg + minimal_nanotez_per_byte_arg + keep_alive_arg + liquidity_baking_escape_vote_switch + per_block_vote_file_arg) + (prefixes ["run"; "with"; "local"; "node"] + @@ param + ~name:"node_data_path" + ~desc:"Path to the node data directory (e.g. $HOME/.tezos-node)" + directory_parameter + @@ sources_param) + (fun ( pidfile, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + keep_alive, + liquidity_baking_escape_vote, + per_block_vote_file ) + node_data_path + sources + cctxt -> + may_lock_pidfile pidfile @@ fun () -> + get_delegates cctxt sources >>=? fun delegates -> + let context_path = Filename.Infix.(node_data_path // "context") in + Client_daemon.Baker.run + cctxt + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + ~liquidity_baking_escape_vote + ?per_block_vote_file + ~chain:cctxt#chain + ~context_path + ~keep_alive + delegates); + ] + +let accuser_commands () = + let open Clic in + let group = + { + Clic.name = "delegate.accuser"; + title = "Commands related to the accuser daemon."; + } + in + [ + command + ~group + ~desc:"Launch the accuser daemon" + (args3 pidfile_arg Client_proto_args.preserved_levels_arg keep_alive_arg) + (prefixes ["run"] @@ stop) + (fun (pidfile, preserved_levels, keep_alive) cctxt -> + let preserved_levels = Option.value ~default:200 preserved_levels in + may_lock_pidfile pidfile @@ fun () -> + Client_daemon.Accuser.run + cctxt + ~chain:cctxt#chain + ~preserved_levels + ~keep_alive); + ] diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_commands.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_commands.mli new file mode 100644 index 000000000000..8c9f9ea45d06 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_commands.mli @@ -0,0 +1,30 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val delegate_commands : unit -> Protocol_client_context.full Clic.command list + +val baker_commands : unit -> Protocol_client_context.full Clic.command list + +val accuser_commands : unit -> Protocol_client_context.full Clic.command list diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_commands_registration.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_commands_registration.ml new file mode 100644 index 000000000000..1050a6901021 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_commands_registration.ml @@ -0,0 +1,29 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let () = + Client_commands.register Protocol.hash @@ fun _network -> + List.map (Clic.map_command (new Protocol_client_context.wrap_full)) + @@ Baking_commands.delegate_commands () diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_configuration.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_configuration.ml new file mode 100644 index 000000000000..bec18c12dcd2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_configuration.ml @@ -0,0 +1,310 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Mempool = struct + type t = + | Local of {filename : string} + | Remote of {uri : Uri.t; http_headers : (string * string) list option} + + let encoding = + let open Data_encoding in + union + ~tag_size:`Uint8 + [ + case + (Tag 1) + ~title:"Local" + (obj2 (req "filename" string) (req "kind" (constant "Local"))) + (function Local {filename} -> Some (filename, ()) | _ -> None) + (fun (filename, ()) -> Local {filename}); + case + (Tag 2) + ~title:"Remote" + (obj3 + (req "uri" string) + (opt "http_headers" (list (tup2 string string))) + (req "kind" (constant "Remote"))) + (function + | Remote {uri; http_headers} -> + Some (Uri.to_string uri, http_headers, ()) + | _ -> None) + (fun (uri_str, http_headers, ()) -> + Remote {uri = Uri.of_string uri_str; http_headers}); + ] +end + +open Protocol.Alpha_context + +type fees_config = { + minimal_fees : Tez.t; + minimal_nanotez_per_gas_unit : Q.t; + minimal_nanotez_per_byte : Q.t; +} + +type validation_config = + | Local of {context_path : string} + | Node + | ContextIndex of Abstract_context_index.t + +type nonce_config = Deterministic | Random + +type state_recorder_config = Filesystem | Disabled + +type t = { + fees : fees_config; + nonce : nonce_config; + validation : validation_config; + retries_on_failure : int; + user_activated_upgrades : (int32 * Protocol_hash.t) list; + liquidity_baking_escape_vote : bool; + per_block_vote_file : string option; + force : bool; + state_recorder : state_recorder_config; + initial_mempool : Mempool.t option; +} + +let default_fees_config = + { + minimal_fees = + (match Tez.of_mutez 100L with None -> assert false | Some t -> t); + minimal_nanotez_per_gas_unit = Q.of_int 100; + minimal_nanotez_per_byte = Q.of_int 1000; + } + +let default_validation_config = Node + +(* Unclear if determinist nonces, and more importantly, if + [supports_deterministic_nonces] is supported. *) +let default_nonce_config = Random + +let default_retries_on_failure_config = 5 + +let default_user_activated_upgrades = [] + +let default_liquidity_baking_escape_vote = false + +let default_force = false + +let default_state_recorder_config = Filesystem + +let default_initial_mempool = None + +let default_per_block_vote_file = None + +let default_config = + { + fees = default_fees_config; + nonce = default_nonce_config; + validation = default_validation_config; + retries_on_failure = default_retries_on_failure_config; + user_activated_upgrades = default_user_activated_upgrades; + liquidity_baking_escape_vote = default_liquidity_baking_escape_vote; + force = default_force; + state_recorder = default_state_recorder_config; + initial_mempool = default_initial_mempool; + per_block_vote_file = default_per_block_vote_file; + } + +let make ?(minimal_fees = default_fees_config.minimal_fees) + ?(minimal_nanotez_per_gas_unit = + default_fees_config.minimal_nanotez_per_gas_unit) + ?(minimal_nanotez_per_byte = default_fees_config.minimal_nanotez_per_byte) + ?(nonce = default_nonce_config) ?context_path + ?(retries_on_failure = default_retries_on_failure_config) + ?(user_activated_upgrades = default_user_activated_upgrades) + ?(liquidity_baking_escape_vote = default_liquidity_baking_escape_vote) + ?per_block_vote_file ?(force = default_force) + ?(state_recorder = default_state_recorder_config) ?initial_mempool () = + let fees = + {minimal_fees; minimal_nanotez_per_gas_unit; minimal_nanotez_per_byte} + in + let validation = + match context_path with + | None -> Node + | Some context_path -> Local {context_path} + in + { + fees; + validation; + nonce; + retries_on_failure; + user_activated_upgrades; + liquidity_baking_escape_vote; + per_block_vote_file; + force; + state_recorder; + initial_mempool; + } + +let fees_config_encoding : fees_config Data_encoding.t = + let open Data_encoding in + let q_encoding = + conv (fun q -> Q.to_string q) (fun s -> Q.of_string s) string + in + conv + (fun {minimal_fees; minimal_nanotez_per_gas_unit; minimal_nanotez_per_byte} -> + (minimal_fees, minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte)) + (fun (minimal_fees, minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte) -> + {minimal_fees; minimal_nanotez_per_gas_unit; minimal_nanotez_per_byte}) + (obj3 + (req "minimal_fees" Tez.encoding) + (req "minimal_nanotez_per_gas_unit" q_encoding) + (req "minimal_nanotez_per_byte" q_encoding)) + +let validation_config_encoding = + let open Data_encoding in + union + ~tag_size:`Uint8 + [ + case + ~title:"Local" + (Tag 0) + (obj1 (req "local" string)) + (function Local {context_path} -> Some context_path | _ -> None) + (fun context_path -> Local {context_path}); + case + ~title:"Node" + (Tag 1) + (constant "node") + (function Node -> Some () | _ -> None) + (fun () -> Node); + ] + +let nonce_config_encoding = + let open Data_encoding in + union + ~tag_size:`Uint8 + [ + case + ~title:"Deterministic" + (Tag 0) + (constant "deterministic") + (function Deterministic -> Some () | _ -> None) + (fun () -> Deterministic); + case + ~title:"Random" + (Tag 1) + (constant "Random") + (function Random -> Some () | _ -> None) + (fun () -> Random); + ] + +let retries_on_failure_config_encoding = Data_encoding.int31 + +let user_activate_upgrades_config_encoding = + let open Data_encoding in + list (tup2 int32 Protocol_hash.encoding) + +let liquidity_baking_escape_vote_config_encoding = Data_encoding.bool + +let force_config_encoding = Data_encoding.bool + +let state_recorder_config_encoding = + let open Data_encoding in + union + ~tag_size:`Uint8 + [ + case + ~title:"Filesystem" + (Tag 0) + (constant "filesystem") + (function Filesystem -> Some () | _ -> None) + (fun () -> Filesystem); + case + ~title:"Disabled" + (Tag 1) + (constant "disabled") + (function Disabled -> Some () | _ -> None) + (fun () -> Disabled); + ] + +let encoding : t Data_encoding.t = + let open Data_encoding in + def + (String.concat "." [Protocol.name; "baking_configuration"]) + ~title:"Baking configuration" + ~description:"Baking configuration" + @@ conv + (fun { + fees; + validation; + nonce; + retries_on_failure; + user_activated_upgrades; + liquidity_baking_escape_vote; + per_block_vote_file; + force; + state_recorder; + initial_mempool; + } -> + ( fees, + validation, + nonce, + retries_on_failure, + user_activated_upgrades, + liquidity_baking_escape_vote, + per_block_vote_file, + force, + state_recorder, + initial_mempool )) + (fun ( fees, + validation, + nonce, + retries_on_failure, + user_activated_upgrades, + liquidity_baking_escape_vote, + per_block_vote_file, + force, + state_recorder, + initial_mempool ) -> + { + fees; + validation; + nonce; + retries_on_failure; + user_activated_upgrades; + liquidity_baking_escape_vote; + per_block_vote_file; + force; + state_recorder; + initial_mempool; + }) + (obj10 + (req "fees" fees_config_encoding) + (req "validation" validation_config_encoding) + (req "nonce" nonce_config_encoding) + (req "retries_on_failure" retries_on_failure_config_encoding) + (req "user_activated_upgrades" user_activate_upgrades_config_encoding) + (req + "liquidity_baking_escape_vote" + liquidity_baking_escape_vote_config_encoding) + (opt "per_block_vote_file" Data_encoding.string) + (req "force" force_config_encoding) + (req "state_recorder" state_recorder_config_encoding) + (opt "initial_mempool" Mempool.encoding)) + +let pp fmt t = + let json = Data_encoding.Json.construct encoding t in + Format.fprintf fmt "%a" Data_encoding.Json.pp json diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_configuration.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_configuration.mli new file mode 100644 index 000000000000..3b8e98235331 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_configuration.mli @@ -0,0 +1,118 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +(** {1 Mempool abstraction} *) +module Mempool : sig + type t = + | Local of {filename : string} + (** local mempool resource located in [filename] *) + | Remote of {uri : Uri.t; http_headers : (string * string) list option} + (** remote resource located a [uri], with additional [http_headers] + parameters *) + + val encoding : t Data_encoding.t +end + +type fees_config = { + minimal_fees : Protocol.Alpha_context.Tez.t; + minimal_nanotez_per_gas_unit : Q.t; + minimal_nanotez_per_byte : Q.t; +} + +type validation_config = + | Local of {context_path : string} + | Node + | ContextIndex of Abstract_context_index.t + +type nonce_config = Deterministic | Random + +type state_recorder_config = Filesystem | Disabled + +type t = { + fees : fees_config; + nonce : nonce_config; + validation : validation_config; + retries_on_failure : int; + user_activated_upgrades : (int32 * Protocol_hash.t) list; + liquidity_baking_escape_vote : bool; + per_block_vote_file : string option; + force : bool; + state_recorder : state_recorder_config; + initial_mempool : Mempool.t option; +} + +val default_fees_config : fees_config + +val default_validation_config : validation_config + +val default_nonce_config : nonce_config + +val default_retries_on_failure_config : int + +val default_user_activated_upgrades : (int32 * Protocol_hash.t) list + +val default_liquidity_baking_escape_vote : bool + +val default_force : bool + +val default_state_recorder_config : state_recorder_config + +val default_initial_mempool : Mempool.t option + +val default_per_block_vote_file : string option + +val default_config : t + +val make : + ?minimal_fees:Protocol.Alpha_context.Tez.t -> + ?minimal_nanotez_per_gas_unit:Q.t -> + ?minimal_nanotez_per_byte:Q.t -> + ?nonce:nonce_config -> + ?context_path:string -> + ?retries_on_failure:int -> + ?user_activated_upgrades:(int32 * Protocol_hash.t) list -> + ?liquidity_baking_escape_vote:bool -> + ?per_block_vote_file:string -> + ?force:bool -> + ?state_recorder:state_recorder_config -> + ?initial_mempool:Mempool.t -> + unit -> + t + +val fees_config_encoding : fees_config Data_encoding.t + +val validation_config_encoding : validation_config Data_encoding.t + +val nonce_config_encoding : nonce_config Data_encoding.t + +val retries_on_failure_config_encoding : int Data_encoding.t + +val user_activate_upgrades_config_encoding : + (int32 * Protocol_hash.t) list Data_encoding.t + +val liquidity_baking_escape_vote_config_encoding : bool Data_encoding.t + +val encoding : t Data_encoding.t + +val pp : Format.formatter -> t -> unit diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_errors.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_errors.ml new file mode 100644 index 000000000000..0332e0b7e510 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_errors.ml @@ -0,0 +1,65 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += Cannot_open_context_index of {context_path : string} + +type error += Node_connection_lost + +type error += Cannot_load_local_file of string + +let make_id id = String.concat "." [Protocol.name; id] + +let () = + Error_monad.register_error_kind + `Temporary + ~id:(make_id "cannot_open_context_index") + ~title:"Cannot open context index" + ~description:"Failed to open the context index at the given location" + ~pp:(fun fmt path -> + Format.fprintf fmt "Cannot open context index at %s" path) + Data_encoding.(obj1 (req "cannot_open_context_index" Data_encoding.string)) + (function + | Cannot_open_context_index {context_path} -> Some context_path + | _ -> None) + (fun context_path -> Cannot_open_context_index {context_path}) ; + register_error_kind + `Temporary + ~id:(make_id "baking_scheduling.node_connection_lost") + ~title:"Node connection lost" + ~description:"The connection with the node was lost." + ~pp:(fun fmt () -> Format.fprintf fmt "Lost connection with the node") + Data_encoding.empty + (function Node_connection_lost -> Some () | _ -> None) + (fun () -> Node_connection_lost) ; + register_error_kind + `Temporary + ~id:(make_id "baking_scheduling.cannot_load_local_file") + ~title:"Cannot load local file" + ~description:"Cannot load local file." + ~pp:(fun fmt filename -> + Format.fprintf fmt "Cannot load the local file %s" filename) + Data_encoding.(obj1 (req "file" string)) + (function Cannot_load_local_file s -> Some s | _ -> None) + (fun s -> Cannot_load_local_file s) diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_events.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_events.ml new file mode 100644 index 000000000000..d36324e3adb8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_events.ml @@ -0,0 +1,789 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +let section = [Protocol.name; "baker"] + +let pp_int32 fmt n = Format.fprintf fmt "%ld" n + +let pp_int64 fmt n = Format.fprintf fmt "%Ld" n + +module State_transitions = struct + include Internal_event.Simple + + let section = section @ ["transitions"] + + let new_head_with_increasing_level = + declare_0 + ~section + ~name:"new_head_with_increasing_level" + ~level:Info + ~msg:"received new head with level increasing" + () + + let no_proposal_slot = + declare_1 + ~section + ~name:"no_proposal_slot" + ~level:Notice + ~msg:"no proposal slot at round {round}" + ~pp1:Round.pp + ("round", Round.encoding) + + let proposal_slot = + declare_2 + ~section + ~name:"proposal_slot" + ~level:Notice + ~msg:"proposal slot at round {round} for {delegate}" + ~pp1:Round.pp + ("round", Round.encoding) + ~pp2:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) + + let new_head_while_waiting_for_qc = + declare_0 + ~section + ~name:"new_head_while_waiting_for_qc" + ~level:Info + ~msg:"received new head while waiting for a quorum" + () + + let unexpected_proposal_round = + declare_2 + ~section + ~name:"unexpected_proposal_round" + ~level:Info + ~msg: + "unexpected proposal round, expected: {expected_round}, got: \ + {proposal_round}" + ~pp1:Round.pp + ("expected_round", Round.encoding) + ~pp2:Round.pp + ("proposal_round", Round.encoding) + + let proposal_for_round_already_seen = + declare_3 + ~section + ~name:"proposal_for_round_already_seen" + ~level:Warning + ~msg: + "proposal {new_proposal} for current round ({current_round}) has \ + already been seen {previous_proposal}" + ~pp1:Block_hash.pp + ("new_proposal", Block_hash.encoding) + ~pp2:Round.pp + ("current_round", Round.encoding) + ~pp3:Block_hash.pp + ("previous_proposal", Block_hash.encoding) + + let updating_latest_proposal = + declare_1 + ~section + ~name:"updating_latest_proposal" + ~msg:"updating latest proposal to {block_hash}" + ~level:Info + ~pp1:Block_hash.pp + ("block_hash", Block_hash.encoding) + + let baker_is_ahead_of_node = + declare_2 + ~section + ~name:"baker_is_ahead" + ~level:Info + ~msg: + "baker (level: {baker_level}) is ahead of the node (level: \ + {node_level})" + ~pp1:pp_int32 + ("baker_level", Data_encoding.int32) + ~pp2:pp_int32 + ("node_level", Data_encoding.int32) + + let new_proposal_is_on_another_branch = + declare_2 + ~section + ~name:"new_proposal_is_on_another_branch" + ~level:Info + ~msg: + "received a proposal on another branch - current: current \ + pred{current_branch}, new pred {new_branch}" + ~pp1:Block_hash.pp + ("current_branch", Block_hash.encoding) + ~pp2:Block_hash.pp + ("new_branch", Block_hash.encoding) + + let switching_branch = + declare_0 + ~section + ~name:"switching_branch" + ~level:Info + ~msg:"switching branch" + () + + let branch_proposal_has_better_fitness = + declare_0 + ~section + ~name:"branch_proposal_has_better_fitness" + ~level:Info + ~msg:"different branch proposal has a better fitness than us" + () + + let branch_proposal_has_no_prequorum = + declare_0 + ~section + ~name:"branch_proposal_has_no_prequorum" + ~level:Info + ~msg:"different branch proposal has no prequorum but we do" + () + + let branch_proposal_has_lower_prequorum = + declare_0 + ~section + ~name:"branch_proposal_has_lower_prequorum" + ~level:Info + ~msg:"different branch proposal has a lower prequorum than us" + () + + let branch_proposal_has_better_prequorum = + declare_0 + ~section + ~name:"branch_proposal_has_better_prequorum" + ~level:Info + ~msg:"different branch proposal has a better prequorum" + () + + let branch_proposal_has_same_prequorum = + declare_0 + ~section + ~name:"branch_proposal_has_same_prequorum" + ~level:Error + ~msg:"different branch proposal has the same prequorum" + () + + let preendorsing_proposal = + declare_1 + ~section + ~name:"preendorsing_proposal" + ~level:Info + ~msg:"preendorsing proposal {block_hash}" + ~pp1:Block_hash.pp + ("block_hash", Block_hash.encoding) + + let skipping_invalid_proposal = + declare_0 + ~section + ~name:"skipping_invalid_proposal" + ~level:Info + ~msg:"invalid proposal, skipping" + () + + let outdated_proposal = + declare_1 + ~section + ~name:"outdated_proposal" + ~level:Debug + ~msg:"outdated proposal {block_hash}" + ~pp1:Block_hash.pp + ("block_hash", Block_hash.encoding) + + let proposing_fresh_block = + declare_2 + ~section + ~name:"proposing_fresh_block" + ~level:Info + ~msg:"proposing fresh block for {delegate} at round {round}" + ~pp1:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) + ~pp2:Round.pp + ("round", Round.encoding) + + let no_endorsable_payload_fresh_block = + declare_0 + ~section + ~name:"no_endorsable_payload_fresh_block" + ~level:Info + ~msg:"no endorsable payload, proposing fresh block" + () + + let repropose_block = + declare_1 + ~section + ~name:"repropose_block" + ~level:Info + ~msg:"repropose block with payload {payload}" + ~pp1:Block_payload_hash.pp + ("payload", Block_payload_hash.encoding) + + let unexpected_prequorum_received = + declare_2 + ~section + ~name:"unexpected_prequorum_received" + ~level:Info + ~msg: + "unexpected prequorum received for {received_hash} instead of \ + {expected_hash}" + ~pp1:Block_hash.pp + ("received_hash", Block_hash.encoding) + ~pp2:Block_hash.pp + ("expected_hash", Block_hash.encoding) + + let unexpected_quorum_received = + declare_2 + ~section + ~name:"unexpected_quorum_received" + ~level:Info + ~msg: + "unexpected quorum received for {received_hash} instead of \ + {expected_hash}" + ~pp1:Block_hash.pp + ("received_hash", Block_hash.encoding) + ~pp2:Block_hash.pp + ("expected_hash", Block_hash.encoding) + + let step_current_phase = + declare_2 + ~section + ~name:"step_current_phase" + ~level:Debug + ~msg:"automaton step: current phase {phase}, event {event}" + ~pp1:Baking_state.pp_phase + ("phase", Baking_state.phase_encoding) + ~pp2:Baking_state.pp_event + ("event", Baking_state.event_encoding) +end + +module Node_rpc = struct + include Internal_event.Simple + + let section = section @ ["rpc"] + + let error_while_monitoring_heads = + declare_1 + ~section + ~name:"error_while_monitoring_heads" + ~level:Error + ~msg:"error while monitoring heads {trace}" + ~pp1:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let raw_info = + declare_2 + ~section + ~name:"raw_info" + ~level:Debug + ~msg:"raw info for {block_hash} at level {level}" + ~pp1:Block_hash.pp + ("block_hash", Block_hash.encoding) + ~pp2:pp_int32 + ("level", Data_encoding.int32) +end + +module Scheduling = struct + include Internal_event.Simple + + let section = section @ ["scheduling"] + + let error_while_baking = + declare_1 + ~section + ~name:"error_while_baking" + ~level:Warning + ~msg:"error while baking {trace}" + ~pp1:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let waiting_for_new_head = + declare_0 + ~section + ~name:"waiting_for_new_head" + ~level:Info + ~msg:"no possible timeout, waiting for a new head to arrive..." + () + + let compute_next_timeout_elected_block = + declare_2 + ~section + ~name:"compute_next_timeout_elected_block" + ~level:Debug + ~msg: + "found an elected block at level {level}, round {round}... checking \ + baking rights" + ~pp1:pp_int32 + ("level", Data_encoding.int32) + ~pp2:Round.pp + ("round", Round.encoding) + + let proposal_already_injected = + declare_0 + ~section + ~name:"proposal_already_injected" + ~level:Debug + ~msg:"proposal already injected for next level round, skipping..." + () + + let next_potential_slot = + declare_4 + ~section + ~name:"next_potential_slot" + ~level:Info + ~msg: + "next potential slot for level {level} is at round {round} at \ + {timestamp} for {delegate}" + ~pp1:pp_int32 + ("level", Data_encoding.int32) + ~pp2:Round.pp + ("round", Round.encoding) + ~pp3:Timestamp.pp + ("timestamp", Timestamp.encoding) + ~pp4:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) + + let waiting_end_of_round = + declare_3 + ~section + ~name:"waiting_end_of_round" + ~level:Info + ~msg:"waiting {timespan} until end of round {round} at {timestamp}" + ~pp1:Ptime.Span.pp + ("timespan", Time.System.Span.encoding) + ~pp2:pp_int32 + ("round", Data_encoding.int32) + ~pp3:Timestamp.pp + ("timestamp", Timestamp.encoding) + + let waiting_delayed_end_of_round = + declare_4 + ~section + ~name:"waiting_delayed_end_of_round" + ~level:Info + ~msg: + "waiting {timespan} until {timestamp} (end of round {round} plus \ + {delay}s delay)" + ~pp1:Ptime.Span.pp + ("timespan", Time.System.Span.encoding) + ~pp2:pp_int32 + ("round", Data_encoding.int32) + ~pp3:Timestamp.pp + ("timestamp", Timestamp.encoding) + ~pp4:pp_int64 + ("delay", Data_encoding.int64) + + let waiting_time_to_bake = + declare_2 + ~section + ~name:"waiting_time_to_bake" + ~level:Info + ~msg:"waiting {timespan} until it's time to bake at {timestamp}" + ~pp1:Ptime.Span.pp + ("timespan", Time.System.Span.encoding) + ~pp2:Timestamp.pp + ("timestamp", Timestamp.encoding) + + let no_need_to_wait_for_proposal = + declare_0 + ~section + ~name:"no_need_to_wait_for_proposal" + ~level:Info + ~msg:"no need to wait to propose a block" + () + + let state_synchronized_to_round = + declare_1 + ~section + ~name:"state_synchronized_to_round" + ~level:Debug + ~msg:"state synchronized to round {round}" + ~pp1:Round.pp + ("round", Round.encoding) + + let proposal_in_the_future = + declare_1 + ~section + ~name:"proposal_in_the_future" + ~level:Debug + ~msg:"received proposal in the future {block_hash}" + ~pp1:Block_hash.pp + ("block_hash", Block_hash.encoding) + + let process_proposal_in_the_future = + declare_1 + ~section + ~name:"process_proposal_in_the_future" + ~level:Debug + ~msg:"process proposal received in the future with hash {block_hash}" + ~pp1:Block_hash.pp + ("block_hash", Block_hash.encoding) +end + +module Lib = struct + include Internal_event.Simple + + let section = section @ ["lib"] + + let preendorsing_proposal = + declare_1 + ~section + ~name:"preendorsing_proposal" + ~level:Debug + ~msg:"preendorsing proposal {proposal}" + ~pp1:Baking_state.pp_proposal + ("proposal", Baking_state.proposal_encoding) + + let endorsing_proposal = + declare_1 + ~section + ~name:"endorsing_proposal" + ~level:Debug + ~msg:"endorsing proposal {proposal}" + ~pp1:Baking_state.pp_proposal + ("proposal", Baking_state.proposal_encoding) +end + +module Actions = struct + include Internal_event.Simple + + let section = section @ ["actions"] + + let skipping_preendorsement = + declare_2 + ~section + ~name:"skipping_preendorsement" + ~level:Error + ~msg:"skipping preendorsement for {delegate} -- {trace}" + ~pp1:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) + ~pp2:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let skipping_endorsement = + declare_2 + ~section + ~name:"skipping_endorsement" + ~level:Error + ~msg:"skipping endorsement for {delegate} -- {trace}" + ~pp1:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) + ~pp2:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let failed_to_inject_preendorsement = + declare_2 + ~section + ~name:"failed_to_inject_preendorsement" + ~level:Error + ~msg:"failed to inject preendorsement for {delegate} -- {trace}" + ~pp1:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) + ~pp2:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let potential_double_baking = + declare_2 + ~section + ~name:"potential_double_baking" + ~level:Warning + ~msg:"potential double baking detected at level {level}, round {round}" + ~pp1:pp_int32 + ~pp2:Round.pp + ("level", Data_encoding.int32) + ("round", Round.encoding) + + let preendorsement_injected = + declare_2 + ~section + ~name:"preendorsement_injected" + ~level:Info + ~msg:"injected preendorsement {ophash} for {delegate}" + ~pp1:Operation_hash.pp + ("ophash", Operation_hash.encoding) + ~pp2:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) + + let endorsement_injected = + declare_2 + ~section + ~name:"endorsement_injected" + ~level:Info + ~msg:"injected endorsement {ophash} for {delegate}" + ~pp1:Operation_hash.pp + ("ophash", Operation_hash.encoding) + ~pp2:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) + + let synchronizing_round = + declare_1 + ~section + ~name:"synchronizing_round" + ~level:Info + ~msg:"synchronizing round after block {block}" + ~pp1:Block_hash.pp + ("block", Block_hash.encoding) + + let forging_block = + declare_3 + ~section + ~name:"forging_block" + ~level:Info + ~msg: + "forging block at level {level}, round {round} for delegate {delegate}" + ~pp1:pp_int32 + ~pp2:Round.pp + ~pp3:Baking_state.pp_delegate + ("level", Data_encoding.int32) + ("round", Round.encoding) + ("delegate", Baking_state.delegate_encoding) + + let injecting_block = + declare_3 + ~section + ~name:"injecting_block" + ~level:Debug + ~msg: + "injecting block at level {level}, round {round} for delegate \ + {delegate}" + ~pp1:pp_int32 + ~pp2:Round.pp + ~pp3:Baking_state.pp_delegate + ("level", Data_encoding.int32) + ("round", Round.encoding) + ("delegate", Baking_state.delegate_encoding) + + let block_injected = + declare_2 + ~section + ~name:"block_injected" + ~level:Notice + ~msg:"block {block} injected for delegate {delegate}" + ~pp1:Block_hash.pp + ~pp2:Baking_state.pp_delegate + ("block", Block_hash.encoding) + ("delegate", Baking_state.delegate_encoding) + + let signing_preendorsement = + declare_1 + ~section + ~name:"signing_preendorsement" + ~level:Info + ~msg:"signing preendorsement for {delegate}" + ~pp1:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) + + let signing_endorsement = + declare_1 + ~section + ~name:"signing_endorsement" + ~level:Info + ~msg:"signing endorsement for {delegate}" + ~pp1:Baking_state.pp_delegate + ("delegate", Baking_state.delegate_encoding) +end + +module Nonces = struct + include Internal_event.Simple + + let section = section @ ["nonces"] + + let found_nonce_to_reveal = + declare_2 + ~section + ~name:"found_nonce_to_reveal" + ~level:Notice + ~msg:"found nonce to reveal for block {block}, level {level}" + ~pp1:Block_hash.pp + ("block", Block_hash.encoding) + ~pp2:pp_int32 + ("level", Data_encoding.int32) + + let revealing_nonce = + declare_3 + ~section + ~name:"revealing_nonce" + ~level:Notice + ~msg: + "revaling nonce of level {level} (chain {chain} with operation \ + {ophash})" + ~pp1:pp_int32 + ("level", Data_encoding.int32) + ~pp2:Format.pp_print_string + ("chain", Data_encoding.string) + ~pp3:Operation_hash.pp + ("ophash", Operation_hash.encoding) + + let cannot_fetch_chain_head_level = + declare_0 + ~section + ~name:"cannot_fetch_chain_head_level" + ~level:Error + ~msg:"cannot fetch chain head level, aborting nonces filtering" + () + + let incoherent_nonce = + declare_1 + ~section + ~name:"incoherent_nonce" + ~level:Error + ~msg:"incoherent nonce for level {level}" + ~pp1:pp_int32 + ("level", Data_encoding.int32) + + let cannot_read_nonces = + declare_1 + ~section + ~name:"cannot_read_nonces" + ~level:Error + ~msg:"cannot read nonces {trace}" + ~pp1:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let cannot_retrieve_unrevealed_nonces = + declare_1 + ~section + ~name:"cannot_retrieve_unrevealed_nonces" + ~level:Error + ~msg:"cannot retrieve unrevealed nonces {trace}" + ~pp1:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let cannot_inject_nonces = + declare_1 + ~section + ~name:"cannot_inject_nonces" + ~level:Error + ~msg:"cannot inject nonces {trace}" + ~pp1:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let cant_retrieve_block_header_for_nonce = + declare_2 + ~section + ~name:"cant_retrieve_block_header_for_nonce" + ~level:Warning + ~msg: + "cannot retrieved block header {header} associated with nonce {trace}" + ("header", Data_encoding.string) + ~pp2:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let too_many_nonces = + declare_1 + ~section + ~name:"too_many_nonces" + ~level:Warning + ~msg: + "too many nonces associated with blocks unknown by node in \ + '$TEZOS_CLIENT/{filename}'. After checking that these blocks were \ + never included in the chain (e.g., via a block explorer), consider \ + using `tezos-client filter orphan nonces` to clear them." + ("filename", Data_encoding.string) + + let registering_nonce = + declare_1 + ~section + ~name:"registering_nonce" + ~level:Info + ~msg:"registering nonce for block {block}" + ~pp1:Block_hash.pp + ("block", Block_hash.encoding) + + let nothing_to_reveal = + declare_1 + ~section + ~name:"nothing_to_reveal" + ~level:Info + ~msg:"nothing to reveal for block {block}" + ~pp1:Block_hash.pp + ("block", Block_hash.encoding) + + let revelation_worker_started = + declare_0 + ~section + ~name:"revelation_worker_started" + ~level:Info + ~msg:"revelation worker started" + () +end + +module Liquidity_baking = struct + include Internal_event.Simple + + let reading_per_block = + declare_1 + ~section + ~name:"reading_per_block" + ~level:Notice + ~msg:"reading per block vote file path: {path}" + ("path", Data_encoding.string) + + let per_block_vote_file_notice = + declare_1 + ~section + ~name:"per_block_vote_file_notice" + ~level:Notice + ~msg:"per block vote file {event}" + ("event", Data_encoding.string) + + let reading_liquidity_baking = + declare_0 + ~section + ~name:"reading_liquidity_baking" + ~level:Notice + ~msg:"reading liquidity baking escape vote" + () + + let liquidity_baking_escape_vote = + declare_1 + ~section + ~name:"liquidity_baking_escape_vote" + ~level:Notice + ~msg:"liquidity baking escape vote = {value}" + ("value", Data_encoding.bool) + + let per_block_vote_file_fail = + declare_1 + ~section + ~name:"per_block_vote_file_error" + ~level:Notice + ~msg:"Error reading the block vote file: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let liquidity_baking_escape = + declare_0 + ~section + ~name:"liquidity_baking_continue" + ~level:Notice + ~msg:"Will vote to escape Liquidity Baking" + () + + let liquidity_baking_continue = + declare_0 + ~section + ~name:"liquidity_baking_escape" + ~level:Notice + ~msg:"Will vote to continue Liquidity Baking" + () +end diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_files.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_files.ml new file mode 100644 index 000000000000..38339e2fe555 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_files.ml @@ -0,0 +1,37 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type _ location = string + +let resolve_location ~chain_id (kind : 'a) : 'a location = + let basename = + match kind with + | `Highwatermarks -> "highwatermark" + | `State -> "baker_state" + | `Nonce -> "nonce" + in + Format.asprintf "%a_%s" Chain_id.pp_short chain_id basename + +let filename x = x diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_files.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_files.mli new file mode 100644 index 000000000000..01146f7d0744 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_files.mli @@ -0,0 +1,33 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type _ location + +val resolve_location : + chain_id:Chain_id.t -> + ([< `Highwatermarks | `Nonce | `State] as 'kind) -> + 'kind location + +val filename : [< `Highwatermarks | `Nonce | `State] location -> string diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_highwatermarks.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_highwatermarks.ml new file mode 100644 index 000000000000..5a0b12d57345 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_highwatermarks.ml @@ -0,0 +1,230 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol_client_context +open Protocol.Alpha_context + +type highwatermark = {round : Round.t; level : int32} + +let highwatermark_encoding : highwatermark Data_encoding.t = + let open Data_encoding in + conv + (fun {round; level} -> (round, level)) + (fun (round, level) -> {round; level}) + (obj2 + (req "round" Protocol.Alpha_context.Round.encoding) + (req "level" int32)) + +let pp_highwatermark fmt {round; level} = + Format.fprintf fmt "round: %a, level: %ld" Round.pp round level + +type error += Block_previously_baked of highwatermark + +type error += Block_previously_preendorsed of highwatermark + +type error += Block_previously_endorsed of highwatermark + +let () = + register_error_kind + `Permanent + ~id:"highwatermarks.block_previously_baked" + ~title:"Block previously baked" + ~description:"Trying to bake a block at a level previously baked" + ~pp:(fun ppf highwatermark -> + Format.fprintf + ppf + "Block (%a) was previously baked" + pp_highwatermark + highwatermark) + highwatermark_encoding + (function + | Block_previously_baked highwatermark -> Some highwatermark | _ -> None) + (fun highwatermark -> Block_previously_baked highwatermark) ; + register_error_kind + `Permanent + ~id:"highwatermarks.block_previously_preendorsed" + ~title:"Block previously preendorsed" + ~description: + "Trying to preendorse a block at a level previously preendorsed" + ~pp:(fun ppf highwatermark -> + Format.fprintf + ppf + "Block %a was already preendorsed" + pp_highwatermark + highwatermark) + highwatermark_encoding + (function + | Block_previously_preendorsed highwatermark -> Some highwatermark + | _ -> None) + (fun highwatermark -> Block_previously_preendorsed highwatermark) ; + register_error_kind + `Permanent + ~id:"highwatermarks.block_previously_endorsed" + ~title:"Block previously endorsed" + ~description:"Trying to endorse a block at a level previously endorsed" + ~pp:(fun ppf highwatermark -> + Format.fprintf + ppf + "Block %a was previously endorsed" + pp_highwatermark + highwatermark) + highwatermark_encoding + (function + | Block_previously_endorsed highwatermark -> Some highwatermark + | _ -> None) + (fun highwatermark -> Block_previously_endorsed highwatermark) + +module DelegateMap = Map.Make (struct + type t = Signature.Public_key_hash.t + + let compare = Signature.Public_key_hash.compare +end) + +let highwatermark_delegate_map_encoding = + let open Data_encoding in + conv + DelegateMap.bindings + DelegateMap.( + fun l -> List.fold_left (fun map (k, v) -> add k v map) empty l) + (list + (obj2 + (req "delegate" Signature.Public_key_hash.encoding) + (req "highwatermark" highwatermark_encoding))) + +type highwatermarks = { + blocks : highwatermark DelegateMap.t; + preendorsements : highwatermark DelegateMap.t; + endorsements : highwatermark DelegateMap.t; +} + +type t = highwatermarks + +let encoding = + let open Data_encoding in + conv + (fun {blocks; preendorsements; endorsements} -> + (blocks, preendorsements, endorsements)) + (fun (blocks, preendorsements, endorsements) -> + {blocks; preendorsements; endorsements}) + (obj3 + (req "blocks" highwatermark_delegate_map_encoding) + (req "preendorsements" highwatermark_delegate_map_encoding) + (req "endorsements" highwatermark_delegate_map_encoding)) + +let empty = + { + blocks = DelegateMap.empty; + preendorsements = DelegateMap.empty; + endorsements = DelegateMap.empty; + } + +(* We do not lock these functions. The caller will be already locked. *) +let load (cctxt : #Protocol_client_context.full) location : t tzresult Lwt.t = + protect (fun () -> + cctxt#load (Baking_files.filename location) encoding ~default:empty) + +let save_highwatermarks (cctxt : #Protocol_client_context.full) filename + highwatermarks : unit tzresult Lwt.t = + protect (fun () -> + (* TODO: improve the backend so we don't write partial informations *) + cctxt#write filename highwatermarks encoding) + +let may_sign highwatermarks ~delegate ~level ~round = + match DelegateMap.find delegate highwatermarks with + | None -> true + | Some highwatermark -> + if Compare.Int32.(highwatermark.level < level) then true + else if Compare.Int32.(highwatermark.level = level) then + Round.(highwatermark.round < round) + else false + +let may_sign_block cctxt (location : [`Highwatermarks] Baking_files.location) + ~delegate ~level ~round = + load cctxt location >>=? fun all_highwatermarks -> + return @@ may_sign all_highwatermarks.blocks ~delegate ~level ~round + +let may_sign_preendorsement cctxt location ~delegate ~level ~round = + load cctxt location >>=? fun all_highwatermarks -> + return @@ may_sign all_highwatermarks.preendorsements ~delegate ~level ~round + +let may_sign_endorsement cctxt location ~delegate ~level ~round = + load cctxt location >>=? fun all_highwatermarks -> + return @@ may_sign all_highwatermarks.endorsements ~delegate ~level ~round + +let record map ~delegate ~new_level ~new_round = + DelegateMap.update + delegate + (function + | None -> Some {level = new_level; round = new_round} + | Some ({level; round} as prev) -> + if Compare.Int32.(new_level > level) then + Some {level = new_level; round = new_round} + else if Compare.Int32.(new_level = level) then + if Round.(new_round > round) then + Some {level = new_level; round = new_round} + else Some prev + else Some prev) + map + +let record_block (cctxt : #Protocol_client_context.full) location ~delegate + ~level ~round = + let filename = Baking_files.filename location in + load cctxt location >>=? fun highwatermarks -> + let new_blocks = + record highwatermarks.blocks ~delegate ~new_level:level ~new_round:round + in + save_highwatermarks cctxt filename {highwatermarks with blocks = new_blocks} + +let record_preendorsement (cctxt : #Protocol_client_context.full) location + ~delegate ~level ~round = + let filename = Baking_files.filename location in + load cctxt location >>=? fun highwatermarks -> + let new_preendorsements = + record + highwatermarks.preendorsements + ~delegate + ~new_level:level + ~new_round:round + in + save_highwatermarks + cctxt + filename + {highwatermarks with preendorsements = new_preendorsements} + +let record_endorsement (cctxt : #Protocol_client_context.full) location + ~delegate ~level ~round = + let filename = Baking_files.filename location in + load cctxt location >>=? fun highwatermarks -> + let new_endorsements = + record + highwatermarks.endorsements + ~delegate + ~new_level:level + ~new_round:round + in + save_highwatermarks + cctxt + filename + {highwatermarks with endorsements = new_endorsements} diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_highwatermarks.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_highwatermarks.mli new file mode 100644 index 000000000000..757b667c58bb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_highwatermarks.mli @@ -0,0 +1,91 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol.Alpha_context + +type highwatermark = {round : Round.t; level : int32} + +type error += Block_previously_baked of highwatermark + +type error += Block_previously_preendorsed of highwatermark + +type error += Block_previously_endorsed of highwatermark + +type t + +val encoding : t Data_encoding.t + +val load : + #Protocol_client_context.full -> + [`Highwatermarks] Baking_files.location -> + t tzresult Lwt.t + +val may_sign_block : + #Protocol_client_context.full -> + [`Highwatermarks] Baking_files.location -> + delegate:Signature.public_key_hash -> + level:int32 -> + round:Round.t -> + bool tzresult Lwt.t + +val may_sign_preendorsement : + #Protocol_client_context.full -> + [`Highwatermarks] Baking_files.location -> + delegate:Signature.public_key_hash -> + level:int32 -> + round:Round.t -> + bool tzresult Lwt.t + +val may_sign_endorsement : + #Protocol_client_context.full -> + [`Highwatermarks] Baking_files.location -> + delegate:Signature.public_key_hash -> + level:int32 -> + round:Round.t -> + bool tzresult Lwt.t + +val record_block : + #Protocol_client_context.full -> + [`Highwatermarks] Baking_files.location -> + delegate:Signature.public_key_hash -> + level:int32 -> + round:Round.t -> + unit tzresult Lwt.t + +val record_preendorsement : + #Protocol_client_context.full -> + [`Highwatermarks] Baking_files.location -> + delegate:Signature.public_key_hash -> + level:int32 -> + round:Round.t -> + unit tzresult Lwt.t + +val record_endorsement : + #Protocol_client_context.full -> + [`Highwatermarks] Baking_files.location -> + delegate:Signature.public_key_hash -> + level:int32 -> + round:Round.t -> + unit tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_lib.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_lib.ml new file mode 100644 index 000000000000..7528e873e6dd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_lib.ml @@ -0,0 +1,487 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Baking_state + +let create_state cctxt ?synchronize ?monitor_node_mempool ~config + ~current_proposal delegates = + let chain = cctxt#chain in + let monitor_node_operations = monitor_node_mempool in + let initial_mempool = config.Baking_configuration.initial_mempool in + Operation_worker.create ?initial_mempool ?monitor_node_operations cctxt + >>= fun operation_worker -> + Baking_scheduling.create_initial_state + cctxt + ?synchronize + ~chain + config + operation_worker + ~current_proposal + delegates + +let get_current_proposal cctxt = + Node_rpc.monitor_proposals cctxt ~chain:cctxt#chain () + >>=? fun (block_stream, _block_stream_stopper) -> + Lwt_stream.peek block_stream >>= function + | Some current_head -> return (block_stream, current_head) + | None -> failwith "head stream unexpectedly ended" + +module Events = Baking_events.Lib + +let preendorse (cctxt : Protocol_client_context.full) ?(force = false) delegates + = + let open State_transitions in + get_current_proposal cctxt >>=? fun (_, current_proposal) -> + let config = Baking_configuration.make ~force () in + create_state cctxt ~config ~current_proposal delegates >>=? fun state -> + let proposal = state.level_state.latest_proposal in + Events.(emit preendorsing_proposal state.level_state.latest_proposal) + >>= fun () -> + (if force then return_unit + else + is_acceptable_proposal_for_current_level state proposal >>= function + | Invalid -> cctxt#error "Cannot preendorse an invalid proposal" + | Outdated_proposal -> cctxt#error "Cannot preendorse an outdated proposal" + | Valid_proposal -> return_unit) + >>=? fun () -> + let consensus_list = make_consensus_list state proposal in + cctxt#message + "@[Preendorsing for:@ %a@]" + Format.(pp_print_list ~pp_sep:pp_print_space Baking_state.pp_delegate) + (List.map fst consensus_list) + >>= fun () -> + let state_recorder ~new_state = + Baking_state.may_record_new_state ~previous_state:state ~new_state + in + Baking_actions.inject_preendorsements + ~state_recorder + state + ~preendorsements:consensus_list + ~updated_state:state + >>=? fun _ -> return_unit + +let endorse (cctxt : Protocol_client_context.full) ?(force = false) delegates = + let open State_transitions in + get_current_proposal cctxt >>=? fun (_, current_proposal) -> + let config = Baking_configuration.make ~force () in + create_state cctxt ~config ~current_proposal delegates >>=? fun state -> + let proposal = state.level_state.latest_proposal in + Events.(emit endorsing_proposal state.level_state.latest_proposal) + >>= fun () -> + (if force then return_unit + else + is_acceptable_proposal_for_current_level state proposal >>= function + | Invalid -> cctxt#error "Cannot endorse an invalid proposal" + | Outdated_proposal -> cctxt#error "Cannot endorse an outdated proposal" + | Valid_proposal -> return_unit) + >>=? fun () -> + let consensus_list = make_consensus_list state proposal in + cctxt#message + "@[Endorsing for:@ %a@]" + Format.(pp_print_list ~pp_sep:pp_print_space Baking_state.pp_delegate) + (List.map fst consensus_list) + >>= fun () -> + let state_recorder ~new_state = + Baking_state.may_record_new_state ~previous_state:state ~new_state + in + Baking_actions.inject_endorsements + ~state_recorder + state + ~endorsements:consensus_list + ~updated_state:state + >>=? fun _ -> return_unit + +let bake_at_next_level state = + let cctxt = state.global_state.cctxt in + Baking_scheduling.compute_next_potential_baking_time_at_next_level state + >>= function + | None -> cctxt#error "No baking slot found for the delegates" + | Some (timestamp, round) -> + cctxt#message + "Waiting until %a for round %a" + Timestamp.pp + timestamp + Round.pp + round + >>= fun () -> + Option.value + ~default:Lwt.return_unit + (Baking_scheduling.sleep_until timestamp) + >>= fun () -> + return (Baking_state.Timeout (Time_to_bake_next_level {at_round = round})) + +(* Simulate the end of the current round to bootstrap the automaton + or endorse the block if necessary *) +let first_automaton_event state = + match state.level_state.elected_block with + | None -> Lwt.return (Baking_scheduling.compute_bootstrap_event state) + | Some _elected_block -> + (* If there is an elected block we can directly bake at next + level after waiting its date *) + bake_at_next_level state + +let endorsements_endorsing_power state endorsements = + let get_endorsement_voting_power {slot; _} = + match + SlotMap.find slot state.level_state.delegate_slots.all_delegate_slots + with + | None -> assert false + | Some {endorsing_power; _} -> endorsing_power + in + List.sort_uniq compare endorsements + |> List.fold_left + (fun power endorsement -> + power + get_endorsement_voting_power endorsement) + 0 + +let generic_endorsing_power (filter : packed_operation list -> 'a list) + (extract : 'a -> consensus_content) state = + let current_mempool = + Operation_worker.get_current_operations state.global_state.operation_worker + in + let latest_proposal = state.level_state.latest_proposal in + let block_round = latest_proposal.block.round in + let shell_level = latest_proposal.block.shell.level in + let endorsements = + filter (Operation_pool.OpSet.elements current_mempool.consensus) + in + let endorsements_in_mempool = + List.filter_map + (fun v -> + let consensus_content = extract v in + if + Round.(consensus_content.round = block_round) + && Compare.Int32.( + Raw_level.to_int32 consensus_content.level = shell_level) + then Some consensus_content + else None) + endorsements + in + let power = endorsements_endorsing_power state endorsements_in_mempool in + (power, endorsements) + +let state_endorsing_power = + generic_endorsing_power + Operation_pool.filter_endorsements + (fun + ({ + protocol_data = {contents = Single (Endorsement consensus_content); _}; + _; + } : + Kind.endorsement operation) + -> consensus_content) + +let do_action (state, action) = + let state_recorder ~new_state = + Baking_state.may_record_new_state ~previous_state:state ~new_state + in + Baking_actions.perform_action ~state_recorder state action + +let propose_at_next_level ~minimal_timestamp state = + let cctxt = state.global_state.cctxt in + assert (Option.is_some state.level_state.elected_block) ; + if minimal_timestamp then + (match + Baking_scheduling.first_potential_round_at_next_level + state + ~earliest_round:Round.zero + with + | None -> cctxt#error "No potential baking slot for the given delegates." + | Some first_potential_round -> return first_potential_round) + >>=? fun (minimal_round, delegate) -> + let pool = + Operation_worker.get_current_operations + state.global_state.operation_worker + in + let kind = Baking_actions.Fresh pool in + let block_to_bake : Baking_actions.block_to_bake = + { + Baking_actions.predecessor = state.level_state.latest_proposal.block; + round = minimal_round; + delegate; + kind; + } + in + let state_recorder ~new_state = + Baking_state.may_record_new_state ~previous_state:state ~new_state + in + Baking_actions.perform_action + ~state_recorder + state + (Inject_block {block_to_bake; updated_state = state}) + >>=? fun state -> + cctxt#message + "Proposed block at round %a on top of %a " + Round.pp + block_to_bake.round + Block_hash.pp + block_to_bake.predecessor.hash + >>= fun () -> return state + else + bake_at_next_level state >>=? fun event -> + State_transitions.step state event >>= do_action >>=? fun state -> + cctxt#message "Proposal injected" >>= fun () -> return state + +let endorsement_quorum state = + let (power, endorsements) = state_endorsing_power state in + if + Compare.Int.( + power >= state.global_state.constants.parametric.consensus_threshold) + then Some (power, endorsements) + else None + +(* Here's the sketch of the algorithm: + Do I have an endorsement quorum for the current block or an elected block? + - Yes :: wait and propose at next level + - No :: + Is the current proposal at the right round? + - Yes :: fail propose + - No :: + Is there a preendorsement quorum or does the last proposal contain a prequorum? + - Yes :: repropose block with right payload and preendorsements for current round + - No :: repropose fresh block for current round *) +let propose (cctxt : Protocol_client_context.full) ?minimal_fees + ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?force + ?(minimal_timestamp = false) ?mempool ?context_path delegates = + get_current_proposal cctxt >>=? fun (_block_stream, current_proposal) -> + let config = + let initial_mempool = mempool in + Baking_configuration.make + ?minimal_fees + ?minimal_nanotez_per_gas_unit + ?minimal_nanotez_per_byte + ?context_path + ?force + ?initial_mempool + () + in + create_state cctxt ~config ~current_proposal delegates >>=? fun state -> + (match state.level_state.elected_block with + | Some _ -> propose_at_next_level ~minimal_timestamp state + | None -> ( + match endorsement_quorum state with + | Some (voting_power, endorsement_qc) -> + let state = + { + state with + round_state = + { + state.round_state with + current_phase = Baking_state.Awaiting_endorsements; + }; + } + in + let latest_proposal = state.level_state.latest_proposal.block in + let candidate = + { + Operation_worker.hash = latest_proposal.hash; + round_watched = latest_proposal.round; + payload_hash_watched = latest_proposal.payload_hash; + } + in + State_transitions.step + state + (Baking_state.Quorum_reached + (candidate, voting_power, endorsement_qc)) + >>= do_action + (* this will register the elected block *) + >>=? fun state -> propose_at_next_level ~minimal_timestamp state + | None -> ( + Baking_scheduling.compute_bootstrap_event state >>?= fun event -> + State_transitions.step state event >>= fun (state, _action) -> + let latest_proposal = state.level_state.latest_proposal in + let open State_transitions in + let round = state.round_state.current_round in + is_acceptable_proposal_for_current_level state latest_proposal + >>= function + | Invalid | Outdated_proposal -> ( + let slotmap = + state.level_state.delegate_slots.own_delegate_slots + in + match State_transitions.round_proposer state slotmap round with + | Some (delegate, _) -> + State_transitions.repropose_block_action + state + delegate + round + state.level_state.latest_proposal + >>= fun action -> + do_action (state, action) >>=? fun state -> + cctxt#message + "Reproposed block at level %ld on round %a" + state.level_state.current_level + Round.pp + state.round_state.current_round + >>= fun () -> return state + | None -> cctxt#error "No slots for current round") + | Valid_proposal -> + cctxt#error + "Cannot propose: there's already a valid proposal for the \ + current round %a" + Round.pp + round))) + >>=? fun _ -> return_unit + +let bake_using_automaton config state block_stream = + let cctxt = state.global_state.cctxt in + first_automaton_event state >>=? fun initial_event -> + let current_level = state.level_state.latest_proposal.block.shell.level in + let loop_state = + Baking_scheduling.create_loop_state + block_stream + state.global_state.operation_worker + in + let stop_on_next_level_block = function + | New_proposal proposal -> + Compare.Int32.(proposal.block.shell.level >= Int32.succ current_level) + | _ -> false + in + Baking_scheduling.automaton_loop + ~stop_on_event:stop_on_next_level_block + ~config + ~on_error:(fun err -> Lwt.return (Error err)) + loop_state + state + initial_event + >>=? function + | Some (New_proposal proposal) -> + cctxt#message + "Block %a (%ld) injected" + Block_hash.pp + proposal.block.hash + proposal.block.shell.level + >>= fun () -> return_unit + | _ -> cctxt#error "Baking loop unexpectedly ended" + +(* endorse the latest proposal and bake with it *) +let baking_minimal_timestamp state = + let cctxt = state.global_state.cctxt in + let latest_proposal = state.level_state.latest_proposal in + let own_endorsements = + State_transitions.make_consensus_list state latest_proposal + in + let current_mempool = + Operation_worker.get_current_operations state.global_state.operation_worker + in + let endorsements_in_mempool = + Operation_pool.( + filter_endorsements (OpSet.elements current_mempool.consensus)) + |> List.filter_map + (fun + ({ + protocol_data = + {contents = Single (Endorsement consensus_content); _}; + _; + } : + Kind.endorsement operation) + -> + if + Round.(consensus_content.round = latest_proposal.block.round) + && Compare.Int32.( + Raw_level.to_int32 consensus_content.level + = latest_proposal.block.shell.level) + then Some consensus_content + else None) + in + let total_voting_power = + List.fold_left + (fun endorsements own -> snd own :: endorsements) + endorsements_in_mempool + own_endorsements + |> endorsements_endorsing_power state + in + let consensus_threshold = + state.global_state.constants.parametric.consensus_threshold + in + (if Compare.Int.(total_voting_power < consensus_threshold) then + cctxt#error + "Delegates do not have enough voting power. Only %d is available while %d \ + is required." + total_voting_power + consensus_threshold + else return_unit) + >>=? fun () -> + (match + Baking_scheduling.first_potential_round_at_next_level + state + ~earliest_round:Round.zero + with + | None -> cctxt#error "No potential baking slot for the given delegates." + | Some first_potential_round -> return first_potential_round) + >>=? fun (minimal_round, delegate) -> + Baking_actions.sign_endorsements state own_endorsements + >>=? fun signed_endorsements -> + let pool = + Operation_pool.add_operations + current_mempool + (List.map snd signed_endorsements) + in + let kind = Baking_actions.Fresh pool in + let block_to_bake : Baking_actions.block_to_bake = + { + Baking_actions.predecessor = latest_proposal.block; + round = minimal_round; + delegate; + kind; + } + in + let state_recorder ~new_state = + Baking_state.may_record_new_state ~previous_state:state ~new_state + in + Baking_actions.perform_action + ~state_recorder + state + (Inject_block {block_to_bake; updated_state = state}) + >>=? fun _ -> + cctxt#message "Injected block at minimal timestamp" >>= fun () -> return_unit + +let bake (cctxt : Protocol_client_context.full) ?minimal_fees + ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?force + ?(minimal_timestamp = false) ?mempool ?monitor_node_mempool ?context_path + delegates = + let config = + let initial_mempool = mempool in + Baking_configuration.make + ?minimal_fees + ?minimal_nanotez_per_gas_unit + ?minimal_nanotez_per_byte + ?context_path + ?force + ?initial_mempool + () + in + get_current_proposal cctxt >>=? fun (block_stream, current_proposal) -> + create_state + cctxt + ?monitor_node_mempool + ~synchronize:(not minimal_timestamp) + ~config + ~current_proposal + delegates + >>=? fun state -> + if not minimal_timestamp then bake_using_automaton config state block_stream + else baking_minimal_timestamp state diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_lib.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_lib.mli new file mode 100644 index 000000000000..d027ec19109e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_lib.mli @@ -0,0 +1,65 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol.Alpha_context + +(** {1 API} *) + +val bake : + Protocol_client_context.full -> + ?minimal_fees:Tez.t -> + ?minimal_nanotez_per_gas_unit:Q.t -> + ?minimal_nanotez_per_byte:Q.t -> + ?force:bool -> + ?minimal_timestamp:bool -> + ?mempool:Baking_configuration.Mempool.t -> + ?monitor_node_mempool:bool -> + ?context_path:string -> + Baking_state.delegate list -> + unit tzresult Lwt.t + +val preendorse : + Protocol_client_context.full -> + ?force:bool -> + Baking_state.delegate list -> + unit tzresult Lwt.t + +val endorse : + Protocol_client_context.full -> + ?force:bool -> + Baking_state.delegate list -> + unit tzresult Lwt.t + +val propose : + Protocol_client_context.full -> + ?minimal_fees:Tez.t -> + ?minimal_nanotez_per_gas_unit:Q.t -> + ?minimal_nanotez_per_byte:Q.t -> + ?force:bool -> + ?minimal_timestamp:bool -> + ?mempool:Baking_configuration.Mempool.t -> + ?context_path:string -> + Baking_state.delegate list -> + unit tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_nonces.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_nonces.ml new file mode 100644 index 000000000000..136c12ae2592 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_nonces.ml @@ -0,0 +1,321 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +module Events = Baking_events.Nonces + +type state = { + cctxt : Protocol_client_context.full; + chain : Chain_services.chain; + constants : Constants.t; + config : Baking_configuration.nonce_config; + nonces_location : [`Nonce] Baking_files.location; + mutable last_predecessor : Block_hash.t; +} + +type t = state + +type nonces = Nonce.t Block_hash.Map.t + +let empty = Block_hash.Map.empty + +let encoding = + let open Data_encoding in + def "seed_nonce" + @@ conv + (fun m -> + Block_hash.Map.fold (fun hash nonce acc -> (hash, nonce) :: acc) m []) + (fun l -> + List.fold_left + (fun map (hash, nonce) -> Block_hash.Map.add hash nonce map) + Block_hash.Map.empty + l) + @@ list (obj2 (req "block" Block_hash.encoding) (req "nonce" Nonce.encoding)) + +let may_migrate (wallet : Protocol_client_context.full) location = + let base_dir = wallet#get_base_dir in + let current_file = + Filename.Infix.((base_dir // Baking_files.filename location) ^ "s") + in + Lwt_unix.file_exists current_file >>= function + | true -> + (* Migration already occured *) + Lwt.return_unit + | false -> ( + let legacy_file = Filename.Infix.(base_dir // "nonces") in + Lwt_unix.file_exists legacy_file >>= function + | false -> + (* Do nothing *) + Lwt.return_unit + | true -> Lwt_utils_unix.copy_file ~src:legacy_file ~dst:current_file) + +let load (wallet : #Client_context.wallet) location = + wallet#load (Baking_files.filename location) ~default:empty encoding + +let save (wallet : #Client_context.wallet) location nonces = + wallet#write (Baking_files.filename location) nonces encoding + +let mem nonces hash = Block_hash.Map.mem hash nonces + +let find_opt nonces hash = Block_hash.Map.find hash nonces + +let add nonces hash nonce = Block_hash.Map.add hash nonce nonces + +let remove nonces hash = Block_hash.Map.remove hash nonces + +let remove_all nonces nonces_to_remove = + Block_hash.Map.fold + (fun hash _ acc -> remove acc hash) + nonces_to_remove + nonces + +let get_block_level_opt cctxt ~chain ~block = + Shell_services.Blocks.Header.shell_header cctxt ~chain ~block () >>= function + | Ok {level; _} -> Lwt.return_some level + | Error errs -> + Events.( + emit + cant_retrieve_block_header_for_nonce + (Block_services.to_string block, errs)) + >>= fun () -> Lwt.return_none + +let get_outdated_nonces {cctxt; constants; chain; _} nonces = + let {Constants.parametric = {blocks_per_cycle; preserved_cycles; _}; _} = + constants + in + get_block_level_opt cctxt ~chain ~block:(`Head 0) >>= function + | None -> + Events.(emit cannot_fetch_chain_head_level ()) >>= fun () -> + return (empty, empty) + | Some current_level -> + let current_cycle = Int32.(div current_level blocks_per_cycle) in + let is_older_than_preserved_cycles block_level = + let block_cycle = Int32.(div block_level blocks_per_cycle) in + Int32.sub current_cycle block_cycle > Int32.of_int preserved_cycles + in + Block_hash.Map.fold + (fun hash nonce acc -> + acc >>=? fun (orphans, outdated) -> + get_block_level_opt cctxt ~chain ~block:(`Hash (hash, 0)) >>= function + | Some level -> + if is_older_than_preserved_cycles level then + return (orphans, add outdated hash nonce) + else acc + | None -> return (add orphans hash nonce, outdated)) + nonces + (return (empty, empty)) + +let filter_outdated_nonces state nonces = + get_outdated_nonces state nonces >>=? fun (orphans, outdated_nonces) -> + when_ + (Block_hash.Map.cardinal orphans >= 50) + (fun () -> + Events.( + emit too_many_nonces (Baking_files.filename state.nonces_location ^ "s")) + >>= fun () -> return_unit) + >>=? fun () -> return (remove_all nonces outdated_nonces) + +let blocks_from_current_cycle {cctxt; chain; _} block ?(offset = 0l) () = + Shell_services.Blocks.hash cctxt ~chain ~block () >>=? fun hash -> + Shell_services.Blocks.Header.shell_header cctxt ~chain ~block () + >>=? fun {level; _} -> + Plugin.RPC.levels_in_current_cycle cctxt ~offset (chain, block) >>= function + | Error (RPC_context.Not_found _ :: _) -> return_nil + | Error _ as err -> Lwt.return err + | Ok (first, last) -> + (* FIXME: crappy algorithm, change this *) + let length = Int32.to_int (Int32.sub level (Raw_level.to_int32 first)) in + Shell_services.Blocks.list cctxt ~chain ~heads:[hash] ~length () + >>=? fun blocks -> + let head = Stdlib.List.hd blocks in + let blocks = + List.remove (length - Int32.to_int (Raw_level.diff last first)) head + in + if Int32.equal level (Raw_level.to_int32 last) then + return (hash :: blocks) + else return blocks + +let get_unrevealed_nonces ({cctxt; chain; _} as state) nonces = + blocks_from_current_cycle state (`Head 0) ~offset:(-1l) () >>=? fun blocks -> + List.filter_map_es + (fun hash -> + match find_opt nonces hash with + | None -> return_none + | Some nonce -> ( + get_block_level_opt cctxt ~chain ~block:(`Hash (hash, 0)) >>= function + | Some level -> ( + Lwt.return (Environment.wrap_tzresult (Raw_level.of_int32 level)) + >>=? fun level -> + Alpha_services.Nonce.get cctxt (chain, `Head 0) level + >>=? function + | Missing nonce_hash when Nonce.check_hash nonce nonce_hash -> + Events.( + emit found_nonce_to_reveal (hash, Raw_level.to_int32 level)) + >>= fun () -> return_some (level, nonce) + | Missing _nonce_hash -> + Events.(emit incoherent_nonce (Raw_level.to_int32 level)) + >>= fun () -> return_none + | Forgotten -> return_none + | Revealed _ -> return_none) + | None -> return_none)) + blocks + +(* Nonce creation *) + +let generate_seed_nonce (nonce_config : Baking_configuration.nonce_config) + (delegate : Baking_state.delegate) level = + (match nonce_config with + | Deterministic -> + let data = Data_encoding.Binary.to_bytes_exn Raw_level.encoding level in + Client_keys.deterministic_nonce delegate.secret_key_uri data + >>=? fun nonce -> + return (Data_encoding.Binary.of_bytes_exn Nonce.encoding nonce) + | Random -> ( + match Nonce.of_bytes (Rand.generate Constants.nonce_length) with + | Error _errs -> assert false + | Ok nonce -> return nonce)) + >>=? fun nonce -> return (Nonce.hash nonce, nonce) + +let register_nonce (cctxt : #Protocol_client_context.full) ~chain_id block_hash + nonce = + Events.(emit registering_nonce block_hash) >>= fun () -> + (* Register the nonce *) + let nonces_location = Baking_files.resolve_location ~chain_id `Nonce in + cctxt#with_lock @@ fun () -> + load cctxt nonces_location >>=? fun nonces -> + let nonces = add nonces block_hash nonce in + save cctxt nonces_location nonces >>=? fun () -> return_unit + +let inject_seed_nonce_revelation (cctxt : #Protocol_client_context.full) ~chain + ~block ~branch nonces = + match nonces with + | [] -> Events.(emit nothing_to_reveal branch) >>= fun () -> return_unit + | _ -> + List.iter_es + (fun (level, nonce) -> + Plugin.RPC.Forge.seed_nonce_revelation + cctxt + (chain, block) + ~branch + ~level + ~nonce + () + >>=? fun bytes -> + let bytes = Signature.concat bytes Signature.zero in + Shell_services.Injection.operation ~async:true cctxt ~chain bytes + >>=? fun oph -> + Events.( + emit + revealing_nonce + (Raw_level.to_int32 level, Chain_services.to_string chain, oph)) + >>= fun () -> return_unit) + nonces + +(** [reveal_potential_nonces] reveal registered nonces *) +let reveal_potential_nonces + ({cctxt; chain; nonces_location; last_predecessor; _} as state) new_proposal + = + let new_predecessor_hash = new_proposal.Baking_state.predecessor.hash in + if + Block_hash.(last_predecessor <> new_predecessor_hash) + && Protocol_hash.(new_proposal.predecessor.protocol = Protocol.hash) + then ( + (* only try revealing nonces when the proposal's predecessor is a new one *) + state.last_predecessor <- new_predecessor_hash ; + let block = `Head 0 in + let branch = new_predecessor_hash in + (* improve concurrency *) + cctxt#with_lock @@ fun () -> + load cctxt nonces_location >>= function + | Error err -> + Events.(emit cannot_read_nonces err) >>= fun () -> return_unit + | Ok nonces -> ( + get_unrevealed_nonces state nonces >>= function + | Error err -> + Events.(emit cannot_retrieve_unrevealed_nonces err) >>= fun () -> + return_unit + | Ok [] -> return_unit + | Ok nonces_to_reveal -> ( + inject_seed_nonce_revelation + cctxt + ~chain + ~block + ~branch + nonces_to_reveal + >>= function + | Error err -> + Events.(emit cannot_inject_nonces err) >>= fun () -> return_unit + | Ok () -> + (* If some nonces are to be revealed it means: + - We entered a new cycle and we can clear old nonces ; + - A revelation was not included yet in the cycle beginning. + So, it is safe to only filter outdated_nonces there *) + filter_outdated_nonces state nonces >>=? fun live_nonces -> + save cctxt nonces_location live_nonces >>=? fun () -> + return_unit))) + else return_unit + +(* We suppose that the block stream is cloned by the caller *) +let start_revelation_worker cctxt config chain_id constants block_stream = + let nonces_location = Baking_files.resolve_location ~chain_id `Nonce in + may_migrate cctxt nonces_location >>= fun () -> + let chain = `Hash chain_id in + let canceler = Lwt_canceler.create () in + let should_shutdown = ref false in + let state = + { + cctxt; + chain; + constants; + config; + nonces_location; + last_predecessor = Block_hash.zero; + } + in + let rec worker_loop () = + Lwt_canceler.on_cancel canceler (fun () -> + should_shutdown := true ; + Lwt.return_unit) ; + Lwt_stream.get block_stream >>= function + | None -> + (* The head stream closed meaning that the connection + with the node was interrupted: exit *) + return_unit + | Some new_proposal -> + if !should_shutdown then return_unit + else + reveal_potential_nonces state new_proposal >>=? fun () -> + worker_loop () + in + Lwt.dont_wait + (fun () -> + Lwt.finalize + (fun () -> + Events.(emit revelation_worker_started ()) >>= fun () -> + worker_loop () >>= fun _ -> (* never ending loop *) Lwt.return_unit) + (fun () -> (* TODO *) Lwt.return_unit)) + (fun _exn -> ()) ; + Lwt.return canceler diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_nonces.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_nonces.mli new file mode 100644 index 000000000000..baa6ebf23f18 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_nonces.mli @@ -0,0 +1,114 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type state = { + cctxt : Protocol_client_context.full; + chain : Chain_services.chain; + constants : Constants.t; + config : Baking_configuration.nonce_config; + nonces_location : [`Nonce] Baking_files.location; + mutable last_predecessor : Block_hash.t; +} + +type t = state + +type nonces = Nonce.t Block_hash.Map.t + +val empty : Nonce.t Block_hash.Map.t + +val encoding : Nonce.t Block_hash.Map.t Data_encoding.t + +val load : + #Client_context.wallet -> + [< `Highwatermarks | `Nonce | `State] Baking_files.location -> + Nonce.t Block_hash.Map.t tzresult Lwt.t + +val save : + #Client_context.wallet -> + [< `Highwatermarks | `Nonce | `State] Baking_files.location -> + Nonce.t Block_hash.Map.t -> + unit tzresult Lwt.t + +val mem : Nonce.t Block_hash.Map.t -> Block_hash.t -> bool + +val find_opt : Nonce.t Block_hash.Map.t -> Block_hash.t -> Nonce.t option + +val get_block_level_opt : + #RPC_context.simple -> + chain:Block_services.chain -> + block:Block_services.block -> + int32 option Lwt.t + +val get_outdated_nonces : + t -> + Nonce.t Block_hash.Map.t -> + (Nonce.t Block_hash.Map.t * Nonce.t Block_hash.Map.t) tzresult Lwt.t + +val filter_outdated_nonces : + t -> Nonce.t Block_hash.Map.t -> Nonce.t Block_hash.Map.t tzresult Lwt.t + +val blocks_from_current_cycle : + t -> + Block_services.block -> + ?offset:int32 -> + unit -> + Block_hash.t list tzresult Lwt.t + +val get_unrevealed_nonces : + t -> Nonce.t Block_hash.Map.t -> (Raw_level.t * Nonce.t) list tzresult Lwt.t + +val generate_seed_nonce : + Baking_configuration.nonce_config -> + Baking_state.delegate -> + Raw_level.t -> + (Nonce_hash.t * Nonce.t) tzresult Lwt.t + +val register_nonce : + #Protocol_client_context.full -> + chain_id:Chain_id.t -> + Block_hash.t -> + Nonce.t -> + unit tzresult Lwt.t + +val inject_seed_nonce_revelation : + #Protocol_client_context.full -> + chain:Chain_services.chain -> + block:Block_services.block -> + branch:Block_hash.t -> + (Raw_level.t * Nonce.t) list -> + unit tzresult Lwt.t + +val reveal_potential_nonces : t -> Baking_state.proposal -> unit tzresult Lwt.t + +val start_revelation_worker : + Protocol_client_context.full -> + Baking_configuration.nonce_config -> + Chain_id.t -> + Constants.t -> + Baking_state.proposal Lwt_stream.t -> + Lwt_canceler.t Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_pow.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_pow.ml new file mode 100644 index 000000000000..5637988fb52b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_pow.ml @@ -0,0 +1,85 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +let default_constant = "\x00\x00\x00\x05" + +let is_updated_constant = + let commit_hash = + match Hex.to_string (`Hex Tezos_version.Current_git_info.commit_hash) with + | None -> Tezos_version.Current_git_info.commit_hash + | Some s -> s + in + if String.length commit_hash >= 4 then String.sub commit_hash 0 4 + else default_constant + +let is_updated_constant_len = String.length is_updated_constant + +(* add a version to the pow *) +let init_proof_of_work_nonce () = + let buf = + Bytes.make Alpha_context.Constants.proof_of_work_nonce_size '\000' + in + Bytes.blit_string is_updated_constant 0 buf 0 is_updated_constant_len ; + let max_z_len = + Alpha_context.Constants.proof_of_work_nonce_size - is_updated_constant_len + in + let rec aux z = + let z_len = (Z.numbits z + 7) / 8 in + if z_len > max_z_len then Seq.Nil + else ( + Bytes.blit_string (Z.to_bits z) 0 buf is_updated_constant_len z_len ; + Seq.Cons (buf, fun () -> aux (Z.succ z))) + in + aux Z.zero + +(* This was used before November 2018 *) +(* (\* Random proof of work *\) + * let generate_proof_of_work_nonce () = + * Rand.generate Alpha_context.Constants.proof_of_work_nonce_size *) + +let empty_proof_of_work_nonce = + Bytes.make Constants_repr.proof_of_work_nonce_size '\000' + +let mine ~proof_of_work_threshold shell builder = + let rec loop nonce_seq = + match nonce_seq with + | Seq.Nil -> + failwith + "Client_baking_pow.mine: couldn't find nonce for required proof of \ + work" + | Seq.Cons (nonce, seq) -> + let block = builder nonce in + if + Alpha_context.Block_header.Proof_of_work + .check_header_proof_of_work_stamp + shell + block + proof_of_work_threshold + then return block + else loop (seq ()) + in + loop (init_proof_of_work_nonce ()) diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_pow.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_pow.mli new file mode 100644 index 000000000000..ad5975c9190c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_pow.mli @@ -0,0 +1,40 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** A null proof-of-work nonce. This should only be used to nonsensical blocks + of the correct size and shape. *) +val empty_proof_of_work_nonce : Bytes.t + +(** [mine ~proof_of_work_threshold chain block header builder] returns a block with a valid + proof-of-work nonce. The function [builder], provided by the caller, is used + to make the block. All the internal logic of generating nonces and checking + for the proof-of-work threshold is handled by [mine]. *) +val mine : + proof_of_work_threshold:int64 -> + Block_header.shell_header -> + (Bytes.t -> Alpha_context.Block_header.contents) -> + Alpha_context.Block_header.contents tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_scheduling.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_scheduling.ml new file mode 100644 index 000000000000..07efc9042412 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_scheduling.ml @@ -0,0 +1,787 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol.Alpha_context +module Events = Baking_events.Scheduling +open Baking_state + +type loop_state = { + block_stream : Baking_state.proposal Lwt_stream.t; + qc_stream : Operation_worker.event Lwt_stream.t; + future_block_stream : proposal Lwt_stream.t; + push_future_block : proposal -> unit; + mutable last_get_head_event : Baking_state.proposal option Lwt.t option; + mutable last_future_block_event : Baking_state.proposal Lwt.t option; + mutable last_get_qc_event : Operation_worker.event option Lwt.t option; +} + +let create_loop_state block_stream operation_worker = + let (future_block_stream, push_future_block) = Lwt_stream.create () in + { + block_stream; + qc_stream = Operation_worker.get_quorum_event_stream operation_worker; + future_block_stream; + push_future_block = (fun x -> push_future_block (Some x)); + last_get_head_event = None; + last_future_block_event = None; + last_get_qc_event = None; + } + +let find_in_known_round_intervals known_round_intervals ~predecessor_timestamp + ~predecessor_round ~now = + let open Baking_cache in + Round_timestamp_interval_cache.( + find_opt + known_round_intervals + {predecessor_timestamp; predecessor_round; time_interval = (now, now)}) + +(** Memoization wrapper for [Round.timestamp_of_round]. *) +let timestamp_of_round known_timestamps round_durations ~predecessor_timestamp + ~predecessor_round ~round = + let open Baking_cache in + match + Timestamp_of_round_cache.find_opt + known_timestamps + (predecessor_timestamp, predecessor_round, round) + with + (* Compute and register the timestamp if not already existing. *) + | None -> + Protocol.Alpha_context.Round.timestamp_of_round + round_durations + ~predecessor_timestamp + ~predecessor_round + ~round + >>? fun ts -> + Timestamp_of_round_cache.replace + known_timestamps + (predecessor_timestamp, predecessor_round, round) + ts ; + ok ts + (* If it already exists, just fetch from the memoization table. *) + | Some ts -> ok ts + +(** The function is blocking until it is [time]. *) +let sleep_until time = + (* Sleeping is a system op, baking is a protocol op, this is where we convert *) + let time = Time.System.of_protocol_exn time in + let delay = Ptime.diff time (Tezos_stdlib_unix.Systime_os.now ()) in + if Ptime.Span.compare delay Ptime.Span.zero < 0 then None + else Some (Lwt_unix.sleep (Ptime.Span.to_float_s delay)) + +let rec wait_next_event ~timeout loop_state = + (* TODO? should we prioritize head events/timeouts to resynchronize if needs be ? *) + let get_head_event () = + (* n.b. we should also consume the available elements in the + block_stream before starting baking. *) + match loop_state.last_get_head_event with + | None -> + let t = Lwt_stream.get loop_state.block_stream in + loop_state.last_get_head_event <- Some t ; + t + | Some t -> t + in + let get_future_block_event () = + (* n.b. we should also consume the available elements in the + block_stream before starting baking. *) + match loop_state.last_future_block_event with + | None -> + let t = + Lwt_stream.get loop_state.future_block_stream >>= function + | None -> + (* unreachable, we never close the stream *) + assert false + | Some proposal -> Lwt.return proposal + in + loop_state.last_future_block_event <- Some t ; + t + | Some t -> t + in + let get_qc_event () = + match loop_state.last_get_qc_event with + | None -> + let t = Lwt_stream.get loop_state.qc_stream in + loop_state.last_get_qc_event <- Some t ; + t + | Some t -> t + in + (* event construction *) + let open Baking_state in + Lwt.choose + [ + (Lwt_exit.clean_up_starts >|= fun _ -> `Termination); + (get_head_event () >|= fun e -> `New_proposal e); + (get_future_block_event () >|= fun e -> `New_future_block e); + (get_qc_event () >|= fun e -> `QC_reached e); + (timeout >|= fun e -> `Timeout e); + ] + >>= function + (* event matching *) + | `Termination -> + (* Exit the loop *) + return_none + | `New_proposal None -> + (* Node connection lost *) + loop_state.last_get_head_event <- None ; + fail Baking_errors.Node_connection_lost + | `QC_reached None -> + (* Not supposed to happen: exit the loop *) + loop_state.last_get_qc_event <- None ; + return_none + | `New_proposal (Some proposal) -> ( + loop_state.last_get_head_event <- None ; + (* Is the block in the future? *) + match sleep_until proposal.block.shell.timestamp with + | Some waiter -> + (* If so, wait until its timestamp is reached before advertising it *) + Events.(emit proposal_in_the_future proposal.block.hash) >>= fun () -> + Lwt.dont_wait + (fun () -> + waiter >>= fun () -> + loop_state.push_future_block proposal ; + Lwt.return_unit) + (fun _exn -> ()) ; + wait_next_event ~timeout loop_state + | None -> return_some (New_proposal proposal)) + | `New_future_block proposal -> + Events.(emit process_proposal_in_the_future proposal.block.hash) + >>= fun () -> + loop_state.last_future_block_event <- None ; + return_some (New_proposal proposal) + | `QC_reached + (Some + (Operation_worker.Prequorum_reached + (candidate, voting_power, preendorsement_qc))) -> + loop_state.last_get_qc_event <- None ; + (* TODO: pass the candidate to add a consistency check *) + return_some + (Prequorum_reached (candidate, voting_power, preendorsement_qc)) + | `QC_reached + (Some + (Operation_worker.Quorum_reached + (candidate, voting_power, endorsement_qc))) -> + loop_state.last_get_qc_event <- None ; + (* TODO: pass the candidate to add a consistency check *) + return_some (Quorum_reached (candidate, voting_power, endorsement_qc)) + | `Timeout e -> return_some (Timeout e) + +(** From the current [state], the function returns an optional + association pair, which consists of the next round timestamp and its + round. *) +let compute_next_round_time state = + let open Baking_state in + let proposal = + match state.level_state.endorsable_payload with + | None -> state.level_state.latest_proposal + | Some {proposal; _} -> proposal + in + if Protocol_hash.(proposal.predecessor.next_protocol <> Protocol.hash) then + None + else + match state.level_state.next_level_proposed_round with + | Some _proposed_round -> + (* TODO? do something, if we don't, we won't be able to + repropose a block at next level. *) + None + | None -> ( + let first_round_duration = + state.global_state.constants.parametric.minimal_block_delay + in + let delay_increment_per_round = + state.global_state.constants.parametric.delay_increment_per_round + in + match + Round.Durations.create_opt + ~first_round_duration + ~delay_increment_per_round + with + | Some round_durations -> ( + let predecessor_timestamp = proposal.predecessor.shell.timestamp in + let predecessor_round = proposal.predecessor.round in + let next_round = Round.succ state.round_state.current_round in + match + timestamp_of_round + state.global_state.cache.known_timestamps + round_durations + ~predecessor_timestamp + ~predecessor_round + ~round:next_round + with + | Ok timestamp -> Some (timestamp, next_round) + | _ -> assert false) + | None -> assert false) + +(** [first_potential_round_at_next_level state ~earliest_round] yields + an optional pair of the earliest possible round (at or after + [earliest_round]), along with the delegate having the slot to + propose. + + In particular when the required round value is higher than the + consensus committee size, an Euclidean division allows to + recycle. Then, the earliest round when it exists is extracted. This + is meant to be multiplied back again to find the round value. *) +let first_potential_round_at_next_level state ~earliest_round = + let open Baking_state in + let slots = state.level_state.next_level_delegate_slots.own_delegate_slots in + let rounds = + state.level_state.next_level_delegate_slots.all_slots_by_round + |> Array.to_seqi + |> Seq.fold_left + (fun acc (round, slot) -> + if SlotMap.mem slot slots then (round, slot) :: acc else acc) + [] + |> List.rev + in + match Round.to_int earliest_round with + | Error _ -> None + | Ok earliest_round -> ( + let consensus_committee_size = + state.global_state.constants.parametric.consensus_committee_size + in + let q = earliest_round / consensus_committee_size in + let r = earliest_round mod consensus_committee_size in + let first_round = List.find (fun (round, _) -> round >= r) rounds in + match first_round with + | None -> None + | Some (round, slot) -> ( + SlotMap.find slot slots |> function + | None -> None + | Some (delegate, _) -> ( + (* TODO? check with [Node_rpc.first_proposer_round] if we also need the q+1 *) + match Round.of_int ((q * consensus_committee_size) + round) with + | Error _ -> None + | Ok first_potential_round -> + Some (first_potential_round, delegate)))) + +(** From the current [state], the function returns an optional + association pair, which consists of the next baking timestamp and + its baking round. In that case, an elected block must exist. *) +let compute_next_potential_baking_time_at_next_level state = + let open Protocol.Alpha_context in + let open Baking_state in + match state.level_state.elected_block with + | None -> Lwt.return_none + | Some elected_block -> ( + Events.( + emit + compute_next_timeout_elected_block + ( elected_block.proposal.block.shell.level, + elected_block.proposal.block.round )) + >>= fun () -> + (* Do we have baking rights for the next level ? *) + (* Determine the round for the next level *) + let predecessor_timestamp = + elected_block.proposal.block.shell.timestamp + in + let predecessor_round = elected_block.proposal.block.round in + let now = Systime_os.now () |> Time.System.to_protocol in + (* Lookup the next slot information if already stored in the + memoization table [Round_timestamp_interval_tbl]. *) + match + find_in_known_round_intervals + state.global_state.cache.round_timestamps + ~predecessor_timestamp + ~predecessor_round + ~now + with + | Some (first_potential_baking_time, first_potential_round, delegate) -> ( + (* Check if we already have proposed something at next + level *) + match state.level_state.next_level_proposed_round with + | Some proposed_round + when Round.(proposed_round >= first_potential_round) -> + Events.(emit proposal_already_injected ()) >>= fun () -> + Lwt.return_none + | None | Some _ -> + Events.( + emit + next_potential_slot + ( Int32.succ state.level_state.current_level, + first_potential_round, + first_potential_baking_time, + delegate )) + >>= fun () -> + Lwt.return_some + (first_potential_baking_time, first_potential_round)) + | None -> ( + let round_durations = state.global_state.round_durations in + (* Compute the timestamp at which the new level will start at + round 0.*) + Round.timestamp_of_round + round_durations + ~predecessor_timestamp + ~predecessor_round + ~round:Round.zero + |> function + | Error _ -> Lwt.return_none + | Ok min_possible_time -> ( + (* If this timestamp exists and is not yet outdated, the + earliest round to bake is thereby 0. Otherwise, we + compute the round from the current timestamp. This + possibly means the baker has been late. *) + (if Time.Protocol.(now < min_possible_time) then ok Round.zero + else + Protocol.Environment.wrap_tzresult + @@ Round.round_of_timestamp + round_durations + ~predecessor_timestamp + ~predecessor_round + ~timestamp:now) + |> function + | Error _ -> Lwt.return_none + | Ok earliest_round -> ( + (* There does not necessarily exists a slot that is + equal to [earliest_round]. We must find the earliest + slot after this value for which a validator is + designated to propose. *) + match + first_potential_round_at_next_level state ~earliest_round + with + | None -> Lwt.return_none + | Some (first_potential_round, delegate) -> ( + (* Check if we already have proposed something at next + level. If so, we can skip. Otherwise, we recompute + the timestamp for the + [first_potential_round]. Finally, from this + [first_potential_baking_time], we can return. *) + match state.level_state.next_level_proposed_round with + | Some proposed_round + when Round.(proposed_round >= first_potential_round) -> + Events.(emit proposal_already_injected ()) + >>= fun () -> Lwt.return_none + | None | Some _ -> ( + timestamp_of_round + state.global_state.cache.known_timestamps + round_durations + ~predecessor_timestamp + ~predecessor_round + ~round:first_potential_round + |> function + | Error _ -> Lwt.return_none + | Ok first_potential_baking_time -> + Events.( + emit + next_potential_slot + ( Int32.succ state.level_state.current_level, + first_potential_round, + first_potential_baking_time, + delegate )) + >>= fun () -> + (* memoize this *) + let () = + let this_round_duration = + Round.round_duration + round_durations + first_potential_round + in + let end_first_potential_baking_time = + Timestamp.( + first_potential_baking_time + +? this_round_duration) + |> function + | Ok x -> x + | Error _ -> assert false + in + Baking_cache.( + Round_timestamp_interval_cache.replace + state.global_state.cache.round_timestamps + { + predecessor_timestamp; + predecessor_round; + time_interval = + ( first_potential_baking_time, + end_first_potential_baking_time ); + } + ( first_potential_baking_time, + first_potential_round, + delegate )) + in + Lwt.return_some + ( first_potential_baking_time, + first_potential_round ))))))) + +(** From the current [state], the function returns an Lwt promise that + fulfills once the nearest timeout is expired and at which the state + machine will react. + + Both subfunctions [wait_baking_time] and [wait_end_of_round] are + using the blocking function + [Baking_scheduling.sleep_until]. However, this call is binded into + a Lwt promise. Hence, it just won't get fulfilled until sleep time + has elapsed. Once the promise is fulfilled, + [Baking_scheduling.wait_next_event] handles with [Lwt.choose] to + react and trigger event [Timeout]. *) +let compute_next_timeout state : Baking_state.timeout_kind Lwt.t tzresult Lwt.t + = + (* FIXME: this function (may) try to instantly repropose a block *) + let open Baking_state in + let wait_end_of_round ?(delta = 0L) (next_round_time, next_round) = + let next_time = Time.Protocol.add next_round_time delta in + let now = Systime_os.now () in + let delay = Ptime.diff (Time.System.of_protocol_exn next_time) now in + let current_round = Int32.pred @@ Round.to_int32 next_round in + (if delta = 0L then + Events.(emit waiting_end_of_round (delay, current_round, next_time)) + else + Events.( + emit + waiting_delayed_end_of_round + (delay, current_round, next_time, delta))) + >>= fun () -> + let end_of_round = + Lwt.return + @@ End_of_round {ending_round = state.round_state.current_round} + in + match sleep_until next_time with + | None -> return end_of_round + | Some t -> return (t >>= fun () -> end_of_round) + in + let wait_baking_time_next_level (next_baking_time, next_baking_round) = + let now = Systime_os.now () in + let delay = Ptime.diff (Time.System.of_protocol_exn next_baking_time) now in + Events.(emit waiting_time_to_bake (delay, next_baking_time)) >>= fun () -> + match sleep_until next_baking_time with + | None -> + Events.(emit no_need_to_wait_for_proposal ()) >>= fun () -> + return + (Lwt.return (Time_to_bake_next_level {at_round = next_baking_round})) + | Some t -> + return + ( t >>= fun () -> + Lwt.return (Time_to_bake_next_level {at_round = next_baking_round}) + ) + in + let delay_next_round_timeout next_round = + (* we only delay if it's our turn to bake *) + match + State_transitions.round_proposer + state + state.level_state.delegate_slots.own_delegate_slots + (snd next_round) + with + | Some _ -> + let delta = + state.global_state.constants.parametric.minimal_block_delay + |> Period.to_seconds + |> fun d -> Int64.div d 5L + in + (* NB: this means 6 seconds delay, if the first round duration is + 30. *) + wait_end_of_round ~delta next_round + | None -> wait_end_of_round next_round + in + (* TODO: re-use what has been done in round_synchronizer.ml *) + (* Compute the timestamp of the next possible round. *) + let next_round = compute_next_round_time state in + compute_next_potential_baking_time_at_next_level state >>= fun next_baking -> + match (next_round, next_baking) with + | (None, None) -> + Events.(emit waiting_for_new_head ()) >>= fun () -> + return (Lwt_utils.never_ending () >>= fun () -> assert false) + (* We have no slot at the next level in the near future, we will + patiently wait for the next round. *) + | (Some next_round, None) -> ( + (* If there is an elected block, then we make the assumption + that the bakers at the next level have also received an + endorsement quorum, and we delay a bit injecting at the next + round, so that there are not two blocks injected at the same + time. *) + match state.level_state.elected_block with + | None -> wait_end_of_round next_round + | Some _elected_block -> delay_next_round_timeout next_round) + (* There is no timestamp for a successor round but there is for a + future baking slot, we will wait to bake. *) + | (None, Some next_baking) -> wait_baking_time_next_level next_baking + (* We choose the earliest timestamp between waiting to bake and + waiting for the next round. *) + | ( Some ((next_round_time, next_round) as next_round_info), + Some ((next_baking_time, _) as next_baking) ) -> + (* If we can bake at the next level before the end of the next + round, then do so. This is because the proposed block will have + a smaller timestamp than the earliest block at next level built + on top of the proposal made at the next round (at the current + level). *) + let round_durations = state.global_state.round_durations in + let next_round_duration = + Round.round_duration round_durations next_round |> Period.to_seconds + in + if + Time.Protocol.( + next_baking_time < add next_round_time next_round_duration) + then wait_baking_time_next_level next_baking + else + (* same observation is in the [(Some next_round, None)] case *) + delay_next_round_timeout next_round_info + +(* initialises endorsable_payload with the PQC included in the latest block + if there is one and if it's more recent than the one loaded from disk + if any *) +let may_initialise_with_latest_proposal_pqc state = + let p = state.level_state.latest_proposal in + match p.block.prequorum with + | None -> return state + | Some pqc -> ( + match state.level_state.endorsable_payload with + | Some ep when ep.prequorum.round >= pqc.round -> + (*do not change the endorsable_payload loaded from disk if it's + more recent *) + return state + | Some _ | None -> + return + { + state with + level_state = + { + state.level_state with + endorsable_payload = Some {prequorum = pqc; proposal = p}; + }; + }) + +let create_round_durations constants = + let first_round_duration = + constants.Constants.parametric.minimal_block_delay + in + let delay_increment_per_round = + constants.parametric.delay_increment_per_round + in + Protocol.Environment.wrap_tzresult + (Round.Durations.create ~first_round_duration ~delay_increment_per_round) + +let create_initial_state cctxt ?(synchronize = true) ~chain config + operation_worker ~(current_proposal : Baking_state.proposal) delegates = + (* FIXME? consider saved endorsable value *) + let open Protocol in + let open Baking_state in + Shell_services.Chain.chain_id cctxt ~chain () >>=? fun chain_id -> + Alpha_services.Constants.all cctxt (`Hash chain_id, `Head 0) + >>=? fun constants -> + create_round_durations constants >>?= fun round_durations -> + Baking_state.( + match config.Baking_configuration.validation with + | Node -> return Node + | Local {context_path} -> + Baking_simulator.load_context ~context_path >>=? fun index -> + return (Local index) + | ContextIndex index -> return (Local index)) + >>=? fun validation_mode -> + let cache = Baking_state.create_cache () in + let global_state = + { + cctxt; + chain_id; + config; + constants; + round_durations; + operation_worker; + validation_mode; + delegates; + cache; + } + in + let chain = `Hash chain_id in + let current_level = current_proposal.block.shell.level in + Baking_state.compute_delegate_slots + cctxt + delegates + ~level:current_level + ~chain + >>=? fun delegate_slots -> + Baking_state.compute_delegate_slots + cctxt + delegates + ~level:(Int32.succ current_level) + ~chain + >>=? fun next_level_delegate_slots -> + let elected_block = + if + Protocol_hash.( + current_proposal.block.protocol <> Protocol.hash + && current_proposal.block.next_protocol = Protocol.hash) + then + (* If the last block is a protocol transition, we admit it as a + final block *) + Some {proposal = current_proposal; endorsement_qc = []} + else None + in + let level_state = + { + current_level = current_proposal.block.shell.level; + latest_proposal = current_proposal; + locked_round = None; + endorsable_payload = None; + elected_block; + delegate_slots; + next_level_delegate_slots; + next_level_proposed_round = None; + } + in + (if synchronize then + let round_durations = + Stdlib.Option.get + @@ Round.Durations.create_opt + ~first_round_duration:constants.parametric.minimal_block_delay + ~delay_increment_per_round: + constants.parametric.delay_increment_per_round + in + Baking_actions.compute_round current_proposal round_durations + >>? fun current_round -> ok {current_round; current_phase = Idle} + else ok {Baking_state.current_round = Round.zero; current_phase = Idle}) + >>?= fun round_state -> + let state = {global_state; level_state; round_state} in + (* Try loading locked round and endorsable round from disk *) + Baking_state.may_load_endorsable_data state >>=? fun state -> + may_initialise_with_latest_proposal_pqc state + +let compute_bootstrap_event state = + let open Baking_state in + (* Check if we are in the current round *) + if + Round.( + state.level_state.latest_proposal.block.round + = state.round_state.current_round) + then + (* If so, then trigger the new proposal event to possibly preendorse *) + ok @@ Baking_state.New_proposal state.level_state.latest_proposal + else + (* Otherwise, trigger the end of round to check whether we + need to propose at this level or not *) + Protocol.Environment.wrap_tzresult + @@ Round.pred state.round_state.current_round + >>? fun ending_round -> + ok @@ Baking_state.Timeout (End_of_round {ending_round}) + +let rec automaton_loop ?(stop_on_event = fun _ -> false) ~config ~on_error + loop_state state event = + let state_recorder ~new_state = + match config.Baking_configuration.state_recorder with + | Baking_configuration.Filesystem -> + Baking_state.may_record_new_state ~previous_state:state ~new_state + | Baking_configuration.Disabled -> return_unit + in + State_transitions.step state event >>= fun (state', action) -> + (Baking_actions.perform_action ~state_recorder state' action >>= function + | Ok state'' -> return state'' + | Error error -> + on_error error >>=? fun () -> + (* Still try to record the intermediate state; ignore potential + errors. *) + state_recorder ~new_state:state' >>= fun _ -> return state') + >>=? fun state'' -> + compute_next_timeout state'' >>=? fun next_timeout -> + wait_next_event ~timeout:next_timeout loop_state >>=? function + | None -> + (* Termination *) + return_none + | Some event -> + if stop_on_event event then return_some event + else + automaton_loop ~stop_on_event ~config ~on_error loop_state state'' event + +let perform_sanity_check cctxt ~chain_id = + let open Baking_errors in + let prefix_base_dir f = Filename.Infix.(cctxt#get_base_dir // f) in + let nonces_location = Baking_files.resolve_location ~chain_id `Nonce in + Baking_nonces.load cctxt nonces_location + |> trace + (Cannot_load_local_file + (prefix_base_dir (Baking_files.filename nonces_location) ^ "s")) + >>=? fun _ -> + let highwatermarks_location = + Baking_files.resolve_location ~chain_id `Highwatermarks + in + Baking_highwatermarks.load cctxt highwatermarks_location + |> trace + (Cannot_load_local_file + (prefix_base_dir (Baking_files.filename highwatermarks_location) ^ "s")) + >>=? fun _ -> + let state_location = Baking_files.resolve_location ~chain_id `State in + Baking_state.load_endorsable_data cctxt state_location + |> trace + (Cannot_load_local_file + (prefix_base_dir (Baking_files.filename state_location))) + >>=? fun _ -> return_unit + +let run cctxt ?canceler ?(stop_on_event = fun _ -> false) + ?(on_error = fun _ -> return_unit) ~chain config delegates = + Shell_services.Chain.chain_id cctxt ~chain () >>=? fun chain_id -> + perform_sanity_check cctxt ~chain_id >>=? fun () -> + Node_rpc.monitor_proposals cctxt ~chain () + >>=? fun (block_stream, _block_stream_stopper) -> + (Lwt_stream.get block_stream >>= function + | Some current_head -> return current_head + | None -> failwith "head stream unexpectedly ended") + >>=? fun current_proposal -> + Operation_worker.create cctxt >>= fun operation_worker -> + Option.iter + (fun canceler -> + Lwt_canceler.on_cancel canceler (fun () -> + Operation_worker.shutdown_worker operation_worker >>= fun _ -> + Lwt.return_unit)) + canceler ; + create_initial_state + cctxt + ~chain + config + operation_worker + ~current_proposal + delegates + >>=? fun initial_state -> + let cloned_block_stream = Lwt_stream.clone block_stream in + Baking_nonces.start_revelation_worker + cctxt + initial_state.global_state.config.nonce + initial_state.global_state.chain_id + initial_state.global_state.constants + cloned_block_stream + >>= fun revelation_worker_canceler -> + Option.iter + (fun canceler -> + Lwt_canceler.on_cancel canceler (fun () -> + Lwt_canceler.cancel revelation_worker_canceler >>= fun _ -> + Lwt.return_unit)) + canceler ; + + let loop_state = + create_loop_state block_stream initial_state.global_state.operation_worker + in + let on_error err = + Events.(emit error_while_baking err) >>= fun () -> + (* TODO? retry a bounded number of time *) + (* let retries = config.Baking_configuration.retries_on_failure in *) + on_error err + in + compute_bootstrap_event initial_state >>?= fun initial_event -> + protect + ~on_error:(fun err -> + Option.iter_es Lwt_canceler.cancel canceler >>= fun _ -> + Lwt.return_error err) + (fun () -> + automaton_loop + ~stop_on_event + ~config + ~on_error + loop_state + initial_state + initial_event + >>=? fun _ignored_event -> return_unit) diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_scheduling.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_scheduling.mli new file mode 100644 index 000000000000..b42fbda8b20c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_scheduling.mli @@ -0,0 +1,83 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Baking_state +open Protocol.Alpha_context + +type loop_state + +val create_loop_state : + proposal Lwt_stream.t -> Operation_worker.t -> loop_state + +val sleep_until : Time.Protocol.t -> unit Lwt.t option + +(** An event monitor using the streams in [loop_state] (to create + promises) and a timeout promise [timeout]. The function reacts to a + promise being fulfilled by firing an event [Baking_state.event]. *) +val wait_next_event : + timeout:timeout_kind Lwt.t -> + loop_state -> + (event option, error trace) result Lwt.t + +val compute_next_round_time : state -> (Time.Protocol.t * Round.t) option + +val first_potential_round_at_next_level : + state -> earliest_round:Round.t -> (Round.t * delegate) option + +val compute_next_potential_baking_time_at_next_level : + state -> (Time.Protocol.t * Round.t) option Lwt.t + +val compute_next_timeout : state -> timeout_kind Lwt.t tzresult Lwt.t + +val create_initial_state : + Protocol_client_context.full -> + ?synchronize:bool -> + chain:Chain_services.chain -> + Baking_configuration.t -> + Operation_worker.t -> + current_proposal:proposal -> + delegate trace -> + state tzresult Lwt.t + +val compute_bootstrap_event : state -> event tzresult + +val automaton_loop : + ?stop_on_event:(event -> bool) -> + config:Baking_configuration.t -> + on_error:(tztrace -> (unit, tztrace) result Lwt.t) -> + loop_state -> + state -> + event -> + event option tzresult Lwt.t + +val run : + Protocol_client_context.full -> + ?canceler:Lwt_canceler.t -> + ?stop_on_event:(event -> bool) -> + ?on_error:(tztrace -> unit tzresult Lwt.t) -> + chain:Chain_services.chain -> + Baking_configuration.t -> + delegate trace -> + unit tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_simulator.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_simulator.ml new file mode 100644 index 000000000000..8188f673c123 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_simulator.ml @@ -0,0 +1,120 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol_client_context +open Protocol +open Alpha_context + +type error += Failed_to_checkout_context + +type error += Invalid_context + +let wrap_error_lwt x = x >>= fun x -> Lwt.return @@ Environment.wrap_tzresult x + +let ( >>=?? ) x k = wrap_error_lwt x >>=? k + +let () = + register_error_kind + `Permanent + ~id:"Client_baking_simulator.failed_to_checkout_context" + ~title:"Failed to checkout context" + ~description:"The given context hash does not exists in the context." + ~pp:(fun ppf () -> Format.fprintf ppf "Failed to checkout the context") + Data_encoding.unit + (function Failed_to_checkout_context -> Some () | _ -> None) + (fun () -> Failed_to_checkout_context) ; + register_error_kind + `Permanent + ~id:"Client_baking_simulator.invalid_context" + ~title:"Invalid context" + ~description:"Occurs when the context is inconsistent." + ~pp:(fun ppf () -> Format.fprintf ppf "The given context is invalid.") + Data_encoding.unit + (function Invalid_context -> Some () | _ -> None) + (fun () -> Invalid_context) + +type incremental = { + predecessor : Baking_state.block_info; + context : Tezos_protocol_environment.Context.t; + state : Protocol.validation_state; + rev_operations : Operation.packed list; + header : Tezos_base.Block_header.shell_header; +} + +let load_context ~context_path = + protect (fun () -> + Context.init ~readonly:true context_path >>= fun index -> + return (Abstract_context_index.abstract index)) + +let check_context_consistency (abstract_index : Abstract_context_index.t) + context_hash = + (* Hypothesis : the version key exists *) + let version_key = ["version"] in + abstract_index.checkout_fun context_hash >>= function + | None -> fail Failed_to_checkout_context + | Some context -> ( + Context_ops.mem context version_key >>= function + | true -> return_unit + | false -> fail Invalid_context) + +let begin_construction ~timestamp ?protocol_data + (abstract_index : Abstract_context_index.t) predecessor chain_id = + let {Baking_state.shell = pred_shell; hash = pred_hash; _} = predecessor in + abstract_index.checkout_fun pred_shell.context >>= function + | None -> fail Failed_to_checkout_context + | Some context -> + let header : Tezos_base.Block_header.shell_header = + Tezos_base.Block_header. + { + predecessor = pred_hash; + proto_level = pred_shell.proto_level; + validation_passes = 0; + fitness = pred_shell.fitness; + timestamp; + level = pred_shell.level; + context = Context_hash.zero (* fake context hash *); + operations_hash = Operation_list_list_hash.zero (* fake op hash *); + } + in + Lifted_protocol.begin_construction + ~chain_id + ~predecessor_context:context + ~predecessor_timestamp:pred_shell.timestamp + ~predecessor_fitness:pred_shell.fitness + ~predecessor_level:pred_shell.level + ~predecessor:pred_hash + ?protocol_data + ~timestamp + ~cache:`Lazy + () + >>=? fun state -> + return {predecessor; context; state; rev_operations = []; header} + +let add_operation st (op : Operation.packed) = + Protocol.apply_operation st.state op >>=?? fun (state, receipt) -> + return ({st with state; rev_operations = op :: st.rev_operations}, receipt) + +let finalize_construction inc = + Protocol.finalize_block inc.state (Some inc.header) >>=?? return diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_simulator.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_simulator.mli new file mode 100644 index 000000000000..582fbd3e2922 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_simulator.mli @@ -0,0 +1,61 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type incremental = { + predecessor : Baking_state.block_info; + context : Tezos_protocol_environment.Context.t; + state : validation_state; + rev_operations : Operation.packed list; + header : Tezos_base.Block_header.shell_header; +} + +val load_context : + context_path:string -> Abstract_context_index.t tzresult Lwt.t + +(** Make sure that the given context is consistent by trying to read in it *) +val check_context_consistency : + Abstract_context_index.t -> Context_hash.t -> unit tzresult Lwt.t + +val begin_construction : + timestamp:Time.Protocol.t -> + ?protocol_data:block_header_data -> + Abstract_context_index.t -> + Baking_state.block_info -> + Chain_id.t -> + incremental tzresult Lwt.t + +val add_operation : + incremental -> + Operation.packed -> + (incremental * operation_receipt) tzresult Lwt.t + +val finalize_construction : + incremental -> + (Tezos_protocol_environment.validation_result * block_header_metadata) + tzresult + Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_state.ml b/src/proto_012_PsiThaCa/lib_delegate/baking_state.ml new file mode 100644 index 000000000000..88a7f80e5b0b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_state.ml @@ -0,0 +1,847 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** A delegate (aka, a validator) is identified by its alias name, its + public key, its public key hash, and its secret key. *) +type delegate = { + alias : string option; + public_key : Signature.Public_key.t; + public_key_hash : Signature.Public_key_hash.t; + secret_key_uri : Client_keys.sk_uri; +} + +let delegate_encoding = + let open Data_encoding in + conv + (fun {alias; public_key; public_key_hash; secret_key_uri} -> + ( alias, + public_key, + public_key_hash, + Uri.to_string (secret_key_uri :> Uri.t) )) + (fun (alias, public_key, public_key_hash, secret_key_uri) -> + { + alias; + public_key; + public_key_hash; + secret_key_uri = + (match Client_keys.make_sk_uri (Uri.of_string secret_key_uri) with + | Ok sk -> sk + | Error e -> Format.kasprintf Stdlib.failwith "%a" pp_print_trace e); + }) + (obj4 + (req "alias" (option string)) + (req "public_key" Signature.Public_key.encoding) + (req "public_key_hash" Signature.Public_key_hash.encoding) + (req "secret_key_uri" string)) + +let pp_delegate fmt {alias; public_key_hash; _} = + match alias with + | None -> Format.fprintf fmt "%a" Signature.Public_key_hash.pp public_key_hash + | Some alias -> + Format.fprintf + fmt + "%s (%a)" + alias + Signature.Public_key_hash.pp + public_key_hash + +type validation_mode = Node | Local of Abstract_context_index.t + +type prequorum = { + level : int32; + round : Round.t; + block_payload_hash : Block_payload_hash.t; + preendorsements : Kind.preendorsement operation list; +} + +type block_info = { + hash : Block_hash.t; + shell : Block_header.shell_header; + payload_hash : Block_payload_hash.t; + payload_round : Round.t; + round : Round.t; + protocol : Protocol_hash.t; + next_protocol : Protocol_hash.t; + prequorum : prequorum option; + quorum : Kind.endorsement operation list; + payload : Operation_pool.payload; + live_blocks : Block_hash.Set.t; +} + +type cache = { + known_timestamps : Timestamp.time Baking_cache.Timestamp_of_round_cache.t; + round_timestamps : + (Timestamp.time * Round.t * delegate) + Baking_cache.Round_timestamp_interval_cache.t; +} + +type global_state = { + (* client context *) + cctxt : Protocol_client_context.full; + (* chain id *) + chain_id : Chain_id.t; + (* baker configuration *) + config : Baking_configuration.t; + (* protocol constants *) + constants : Constants.t; + (* round durations *) + round_durations : Round.round_durations; + (* worker that monitor and aggregates new operations *) + operation_worker : Operation_worker.t; + (* the validation mode used by the baker*) + validation_mode : validation_mode; + (* the delegates on behalf of which the baker is running *) + delegates : delegate list; + cache : cache; +} + +let prequorum_encoding = + let open Data_encoding in + conv + (fun {level; round; block_payload_hash; preendorsements} -> + (level, round, block_payload_hash, List.map Operation.pack preendorsements)) + (fun (level, round, block_payload_hash, preendorsements) -> + { + level; + round; + block_payload_hash; + preendorsements = + List.filter_map Operation_pool.unpack_preendorsement preendorsements; + }) + (obj4 + (req "level" int32) + (req "round" Round.encoding) + (req "block_payload_hash" Block_payload_hash.encoding) + (req "preendorsements" (list (dynamic_size Operation.encoding)))) + +let block_info_encoding = + let open Data_encoding in + conv + (fun { + hash; + shell; + payload_hash; + payload_round; + round; + protocol; + next_protocol; + prequorum; + quorum; + payload; + live_blocks; + } -> + ( ( hash, + shell, + payload_hash, + payload_round, + round, + protocol, + next_protocol, + prequorum, + List.map Operation.pack quorum, + payload ), + live_blocks )) + (fun ( ( hash, + shell, + payload_hash, + payload_round, + round, + protocol, + next_protocol, + prequorum, + quorum, + payload ), + live_blocks ) -> + { + hash; + shell; + payload_hash; + payload_round; + round; + protocol; + next_protocol; + prequorum; + quorum = List.filter_map Operation_pool.unpack_endorsement quorum; + payload; + live_blocks; + }) + (merge_objs + (obj10 + (req "hash" Block_hash.encoding) + (req "shell" Block_header.shell_header_encoding) + (req "payload_hash" Block_payload_hash.encoding) + (req "payload_round" Round.encoding) + (req "round" Round.encoding) + (req "protocol" Protocol_hash.encoding) + (req "next_protocol" Protocol_hash.encoding) + (req "prequorum" (option prequorum_encoding)) + (req "quorum" (list (dynamic_size Operation.encoding))) + (req "payload" Operation_pool.payload_encoding)) + (obj1 (req "live_blocks" Block_hash.Set.encoding))) + +let round_of_shell_header shell_header = + Environment.wrap_tzresult + @@ Fitness.from_raw shell_header.Tezos_base.Block_header.fitness + >>? fun fitness -> ok (Fitness.round fitness) + +module SlotMap : Map.S with type key = Slot.t = Map.Make (Slot) + +(** An endorsing slot consists of the public key hash of a delegate, a + list of slots (i.e., a list of position indexes in the slot map, in + other words the list of rounds when it will be the proposer), and + its endorsing power. *) +type endorsing_slot = { + delegate : Signature.Public_key_hash.t; + slots : Slot.t list; + endorsing_power : int; +} + +(* FIXME: determine if the slot map should contain all slots or just + the first one *) +(* We also use the delegate slots as proposal slots *) +(* TODO: make sure that this is correct *) +type delegate_slots = { + (* be careful not to duplicate endorsing slots with different slots + keys: always use the first slot in the slots list *) + own_delegate_slots : (delegate * endorsing_slot) SlotMap.t; + all_delegate_slots : endorsing_slot SlotMap.t; + all_slots_by_round : Slot.t array; +} + +type proposal = {block : block_info; predecessor : block_info} + +let proposal_encoding = + let open Data_encoding in + conv + (fun {block; predecessor} -> (block, predecessor)) + (fun (block, predecessor) -> {block; predecessor}) + (obj2 + (req "block" block_info_encoding) + (req "predecessor" block_info_encoding)) + +type locked_round = {payload_hash : Block_payload_hash.t; round : Round.t} + +let locked_round_encoding = + let open Data_encoding in + conv + (fun {payload_hash; round} -> (payload_hash, round)) + (fun (payload_hash, round) -> {payload_hash; round}) + (obj2 + (req "payload_hash" Block_payload_hash.encoding) + (req "round" Round.encoding)) + +type endorsable_payload = {proposal : proposal; prequorum : prequorum} + +let endorsable_payload_encoding = + let open Data_encoding in + conv + (fun {proposal; prequorum} -> (proposal, prequorum)) + (fun (proposal, prequorum) -> {proposal; prequorum}) + (obj2 + (req "proposal" proposal_encoding) + (req "prequorum" prequorum_encoding)) + +type elected_block = { + proposal : proposal; + endorsement_qc : Kind.endorsement Operation.t list; +} + +(* Updated only when we receive a block at a different level. + + N.B. it may be our own: implying that we should not update unless + we already baked a block *) +type level_state = { + current_level : int32; + latest_proposal : proposal; + (* Last proposal received where we injected an endorsement (thus we + have seen 2f+1 preendorsements) *) + locked_round : locked_round option; + (* Latest payload where we've seen a proposal reach 2f+1 preendorsements *) + endorsable_payload : endorsable_payload option; + (* Block for which we've seen 2f+1 endorsements and that we may bake onto *) + elected_block : elected_block option; + delegate_slots : delegate_slots; + next_level_delegate_slots : delegate_slots; + next_level_proposed_round : Round.t option; +} + +type phase = Idle | Awaiting_preendorsements | Awaiting_endorsements + +let phase_encoding = + let open Data_encoding in + union + ~tag_size:`Uint8 + [ + case + ~title:"Idle" + (Tag 0) + unit + (function Idle -> Some () | _ -> None) + (fun () -> Idle); + case + ~title:"Awaiting_preendorsements" + (Tag 1) + unit + (function Awaiting_preendorsements -> Some () | _ -> None) + (fun () -> Awaiting_preendorsements); + case + ~title:"Awaiting_endorsements" + (Tag 2) + unit + (function Awaiting_endorsements -> Some () | _ -> None) + (fun () -> Awaiting_endorsements); + ] + +type round_state = {current_round : Round.t; current_phase : phase} + +type state = { + global_state : global_state; + level_state : level_state; + round_state : round_state; +} + +type t = state + +type timeout_kind = + | End_of_round of {ending_round : Round.t} + | Time_to_bake_next_level of {at_round : Round.t} + +let timeout_kind_encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"End_of_round" + Round.encoding + (function + | End_of_round {ending_round} -> Some ending_round | _ -> None) + (fun ending_round -> End_of_round {ending_round}); + case + (Tag 1) + ~title:"Time_to_bake_next_level" + Round.encoding + (function + | Time_to_bake_next_level {at_round} -> Some at_round | _ -> None) + (fun at_round -> Time_to_bake_next_level {at_round}); + ] + +type voting_power = int + +type event = + | New_proposal of proposal + | Prequorum_reached of + Operation_worker.candidate + * voting_power + * Kind.preendorsement operation list + | Quorum_reached of + Operation_worker.candidate + * voting_power + * Kind.endorsement operation list + | Timeout of timeout_kind + +let event_encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"New_proposal" + proposal_encoding + (function New_proposal p -> Some p | _ -> None) + (fun p -> New_proposal p); + case + (Tag 1) + ~title:"Prequorum_reached" + (tup3 + Operation_worker.candidate_encoding + Data_encoding.int31 + (Data_encoding.list (dynamic_size Operation.encoding))) + (function + | Prequorum_reached (candidate, voting_power, ops) -> + Some (candidate, voting_power, List.map Operation.pack ops) + | _ -> None) + (fun (candidate, voting_power, ops) -> + Prequorum_reached + (candidate, voting_power, Operation_pool.filter_preendorsements ops)); + case + (Tag 2) + ~title:"Quorum_reached" + (tup3 + Operation_worker.candidate_encoding + Data_encoding.int31 + (Data_encoding.list (dynamic_size Operation.encoding))) + (function + | Quorum_reached (candidate, voting_power, ops) -> + Some (candidate, voting_power, List.map Operation.pack ops) + | _ -> None) + (fun (candidate, voting_power, ops) -> + Quorum_reached + (candidate, voting_power, Operation_pool.filter_endorsements ops)); + case + (Tag 3) + ~title:"Timeout" + timeout_kind_encoding + (function Timeout tk -> Some tk | _ -> None) + (fun tk -> Timeout tk); + ] + +(* Disk state *) + +type state_data = { + level_data : int32; + locked_round_data : locked_round option; + endorsable_payload_data : endorsable_payload option; +} + +let state_data_encoding = + let open Data_encoding in + conv + (fun {level_data; locked_round_data; endorsable_payload_data} -> + (level_data, locked_round_data, endorsable_payload_data)) + (fun (level_data, locked_round_data, endorsable_payload_data) -> + {level_data; locked_round_data; endorsable_payload_data}) + (obj3 + (req "level" int32) + (req "locked_round" (option locked_round_encoding)) + (req "endorsable_payload" (option endorsable_payload_encoding))) + +let record_state (state : state) = + let cctxt = state.global_state.cctxt in + let location = + Baking_files.resolve_location ~chain_id:state.global_state.chain_id `State + in + let filename = + Filename.Infix.(cctxt#get_base_dir // Baking_files.filename location) + in + protect @@ fun () -> + cctxt#with_lock @@ fun () -> + let level_data = state.level_state.current_level in + let locked_round_data = state.level_state.locked_round in + let endorsable_payload_data = state.level_state.endorsable_payload in + let bytes = + Data_encoding.Binary.to_bytes_exn + state_data_encoding + {level_data; locked_round_data; endorsable_payload_data} + in + let filename_tmp = filename ^ "_tmp" in + Lwt_io.with_file + ~flags:[Unix.O_CREAT; O_WRONLY; O_TRUNC; O_CLOEXEC; O_SYNC] + ~mode:Output + filename_tmp + (fun channel -> + Lwt_io.write_from_exactly channel bytes 0 (Bytes.length bytes)) + >>= fun () -> + Lwt_unix.rename filename_tmp filename >>= fun () -> return_unit + +let may_record_new_state ~previous_state ~new_state = + let { + current_level = previous_current_level; + locked_round = previous_locked_round; + endorsable_payload = previous_endorsable_payload; + _; + } = + previous_state.level_state + in + let { + current_level = new_current_level; + locked_round = new_locked_round; + endorsable_payload = new_endorsable_payload; + _; + } = + new_state.level_state + in + let is_new_state_consistent = + Compare.Int32.(new_current_level > previous_current_level) + || new_current_level = previous_current_level + && + if Compare.Int32.(new_current_level = previous_current_level) then + let is_new_locked_round_consistent = + match (new_locked_round, previous_locked_round) with + | (None, None) -> true + | (Some _, None) -> true + | (None, Some _) -> false + | (Some new_locked_round, Some previous_locked_round) -> + Round.(new_locked_round.round >= previous_locked_round.round) + in + let is_new_endorsable_payload_consistent = + match (new_endorsable_payload, previous_endorsable_payload) with + | (None, None) -> true + | (Some _, None) -> true + | (None, Some _) -> false + | (Some new_endorsable_payload, Some previous_endorsable_payload) -> + Round.( + new_endorsable_payload.proposal.block.round + >= previous_endorsable_payload.proposal.block.round) + in + is_new_locked_round_consistent && is_new_endorsable_payload_consistent + else true + in + (* TODO: proper error *) + fail_unless + is_new_state_consistent + (Exn (Failure "locked values invariant does not hold")) + >>=? fun () -> + let has_not_changed = + previous_state.level_state.current_level + == new_state.level_state.current_level + && previous_state.level_state.locked_round + == new_state.level_state.locked_round + && previous_state.level_state.endorsable_payload + == new_state.level_state.endorsable_payload + in + if has_not_changed then return_unit else record_state new_state + +let load_endorsable_data cctxt location = + protect (fun () -> + let filename = + Filename.Infix.(cctxt#get_base_dir // Baking_files.filename location) + in + Lwt_unix.file_exists filename >>= function + | false -> return_none + | true -> + Lwt_io.with_file + ~flags:[Unix.O_EXCL; O_RDONLY; O_CLOEXEC] + ~mode:Input + filename + (fun channel -> + Lwt_io.read channel >>= fun bytes -> + Lwt.return + (Data_encoding.Binary.of_bytes_exn + state_data_encoding + (Bytes.unsafe_of_string bytes))) + >>= return_some) + +let may_load_endorsable_data state = + let cctxt = state.global_state.cctxt in + let chain_id = state.global_state.chain_id in + let location = Baking_files.resolve_location ~chain_id `State in + protect ~on_error:(fun _ -> return state) @@ fun () -> + cctxt#with_lock @@ fun () -> + load_endorsable_data cctxt location >>=? function + | None -> return state + | Some {level_data; locked_round_data; endorsable_payload_data} -> + if Compare.Int32.(state.level_state.current_level = level_data) then + let loaded_level_state = + { + state.level_state with + locked_round = locked_round_data; + endorsable_payload = endorsable_payload_data; + } + in + return {state with level_state = loaded_level_state} + else return state + +(* Helpers *) + +module DelegateSet = struct + include Set.Make (struct + type t = delegate + + let compare {public_key_hash = pkh; _} {public_key_hash = pkh'; _} = + Signature.Public_key_hash.compare pkh pkh' + end) + + let find_pkh pkh s = + let exception Found of elt in + try + iter + (fun ({public_key_hash; _} as delegate) -> + if Signature.Public_key_hash.equal pkh public_key_hash then + raise (Found delegate) + else ()) + s ; + None + with Found d -> Some d +end + +let cache_size_limit = 100 + +let compute_delegate_slots (cctxt : Protocol_client_context.full) delegates + ~level ~chain = + let own_delegates = DelegateSet.of_list delegates in + Environment.wrap_tzresult (Raw_level.of_int32 level) >>?= fun level -> + (* FIXME? should we not take `Head 0 ? *) + Plugin.RPC.Validators.get cctxt (chain, `Head 0) ~levels:[level] + >>=? fun endorsing_rights -> + let (own_delegate_slots, all_delegate_slots) = + List.fold_left + (fun (own_map, all_map) slot -> + let {Plugin.RPC.Validators.delegate; slots; _} = slot in + let endorsing_slot = + {endorsing_power = List.length slots; delegate; slots} + in + let all_map = + List.fold_left + (fun all_map slot -> SlotMap.add slot endorsing_slot all_map) + all_map + slots + in + let own_map = + match DelegateSet.find_pkh delegate own_delegates with + | Some delegate -> + List.fold_left + (fun own_map slot -> + SlotMap.add slot (delegate, endorsing_slot) own_map) + own_map + slots + | None -> own_map + in + (own_map, all_map)) + (SlotMap.empty, SlotMap.empty) + endorsing_rights + in + let all_slots_by_round = + all_delegate_slots |> SlotMap.bindings |> List.split |> fst |> Array.of_list + in + return {own_delegate_slots; all_delegate_slots; all_slots_by_round} + +let create_cache () = + let open Baking_cache in + { + known_timestamps = Timestamp_of_round_cache.create cache_size_limit; + round_timestamps = Round_timestamp_interval_cache.create cache_size_limit; + } + +(* Pretty-printers *) + +let pp_validation_mode fmt = function + | Node -> Format.fprintf fmt "node" + | Local _ -> Format.fprintf fmt "local" + +let pp_global_state fmt {chain_id; config; validation_mode; delegates; _} = + Format.fprintf + fmt + "@[Global state:@ chain_id: %a@ @[config:@ %a@]@ \ + validation_mode: %a@ @[delegates:@ %a@]@]" + Chain_id.pp + chain_id + Baking_configuration.pp + config + pp_validation_mode + validation_mode + Format.(pp_print_list pp_delegate) + delegates + +let pp_option pp fmt = function + | None -> Format.fprintf fmt "none" + | Some v -> Format.fprintf fmt "%a" pp v + +let pp_prequorum fmt {level; round; block_payload_hash; preendorsements} = + Format.fprintf + fmt + "level: %ld, round: %a, payload_hash: %a, preendorsements: %d" + level + Round.pp + round + Block_payload_hash.pp_short + block_payload_hash + (List.length preendorsements) + +let pp_block_info fmt + { + hash; + shell; + payload_hash; + round; + protocol; + next_protocol; + prequorum; + quorum; + payload; + _; + } = + Format.fprintf + fmt + "@[Block:@ hash: %a@ payload_hash: %a@ level: %ld@ round: %a@ \ + protocol: %a@ next protocol: %a@ prequorum: %a@ quorum: %d endorsements@ \ + payload: %a@]" + Block_hash.pp + hash + Block_payload_hash.pp_short + payload_hash + shell.level + Round.pp + round + Protocol_hash.pp_short + protocol + Protocol_hash.pp_short + next_protocol + (pp_option pp_prequorum) + prequorum + (List.length quorum) + Operation_pool.pp_payload + payload + +let pp_proposal fmt {block; _} = pp_block_info fmt block + +let pp_locked_round fmt ({payload_hash; round} : locked_round) = + Format.fprintf + fmt + "payload hash: %a, round: %a" + Block_payload_hash.pp_short + payload_hash + Round.pp + round + +let pp_endorsable_payload fmt {proposal; prequorum} = + Format.fprintf + fmt + "proposal: %a, prequorum: %a" + Block_hash.pp + proposal.block.hash + pp_prequorum + prequorum + +let pp_elected_block fmt {proposal; endorsement_qc} = + Format.fprintf + fmt + "@[%a@ nb quorum endorsements: %d@]" + pp_block_info + proposal.block + (List.length endorsement_qc) + +let pp_endorsing_slot fmt (delegate, {delegate = _; slots; endorsing_power}) = + Format.fprintf + fmt + "slots: @[[%a]@],@ delegate: %a,@ endorsing_power: %d" + Format.(pp_print_list ~pp_sep:pp_print_space Slot.pp) + slots + pp_delegate + delegate + endorsing_power + +let pp_delegate_slots fmt {own_delegate_slots; _} = + Format.fprintf + fmt + "@[%a@]" + Format.( + pp_print_list ~pp_sep:pp_print_cut (fun fmt (slot, endorsing_slot) -> + Format.fprintf + fmt + "slot: %a, %a" + Slot.pp + slot + pp_endorsing_slot + endorsing_slot)) + (SlotMap.bindings own_delegate_slots) + +let pp_level_state fmt + { + current_level; + latest_proposal; + locked_round; + endorsable_payload; + elected_block; + delegate_slots; + next_level_delegate_slots; + next_level_proposed_round; + } = + Format.fprintf + fmt + "@[Level state:@ current level: %ld@ @[proposal:@ %a@]@ locked \ + round: %a@ endorsable payload: %a@ elected block: %a@ @[own delegate \ + slots:@ %a@]@ @[next level own delegate slots:@ %a@]@ next level \ + proposed round: %a@]" + current_level + pp_proposal + latest_proposal + (pp_option pp_locked_round) + locked_round + (pp_option pp_endorsable_payload) + endorsable_payload + (pp_option pp_elected_block) + elected_block + pp_delegate_slots + delegate_slots + pp_delegate_slots + next_level_delegate_slots + (pp_option Round.pp) + next_level_proposed_round + +let pp_phase fmt = function + | Idle -> Format.fprintf fmt "idle" + | Awaiting_preendorsements -> Format.fprintf fmt "awaiting preendorsements" + | Awaiting_endorsements -> Format.fprintf fmt "awaiting endorsements" + +let pp_round_state fmt {current_round; current_phase} = + Format.fprintf + fmt + "@[Round state:@ round: %a@ phase: %a@]" + Round.pp + current_round + pp_phase + current_phase + +let pp fmt {global_state; level_state; round_state} = + Format.fprintf + fmt + "@[State:@ %a@ %a@ %a@]" + pp_global_state + global_state + pp_level_state + level_state + pp_round_state + round_state + +let pp_timeout_kind fmt = function + | End_of_round {ending_round} -> + Format.fprintf fmt "end of round %a" Round.pp ending_round + | Time_to_bake_next_level {at_round} -> + Format.fprintf fmt "time to bake next level at round %a" Round.pp at_round + +let pp_event fmt = function + | New_proposal proposal -> + Format.fprintf + fmt + "new proposal received: %a" + pp_block_info + proposal.block + | Prequorum_reached (candidate, voting_power, preendos) -> + Format.fprintf + fmt + "pre-quorum reached with %d preendorsements (power: %d) for %a at \ + round %a" + (List.length preendos) + voting_power + Block_hash.pp + candidate.Operation_worker.hash + Round.pp + candidate.round_watched + | Quorum_reached (candidate, voting_power, endos) -> + Format.fprintf + fmt + "quorum reached with %d endorsements (power: %d) for %a at round %a" + (List.length endos) + voting_power + Block_hash.pp + candidate.Operation_worker.hash + Round.pp + candidate.round_watched + | Timeout kind -> + Format.fprintf fmt "timeout reached: %a" pp_timeout_kind kind diff --git a/src/proto_012_PsiThaCa/lib_delegate/baking_state.mli b/src/proto_012_PsiThaCa/lib_delegate/baking_state.mli new file mode 100644 index 000000000000..d745b67eabcc --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/baking_state.mli @@ -0,0 +1,226 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type delegate = { + alias : string option; + public_key : Signature.public_key; + public_key_hash : Signature.public_key_hash; + secret_key_uri : Client_keys.sk_uri; +} + +val delegate_encoding : delegate Data_encoding.t + +val pp_delegate : Format.formatter -> delegate -> unit + +type validation_mode = Node | Local of Abstract_context_index.t + +type prequorum = { + level : int32; + round : Round.t; + block_payload_hash : Block_payload_hash.t; + preendorsements : Kind.preendorsement operation list; +} + +type block_info = { + hash : Block_hash.t; + shell : Block_header.shell_header; + payload_hash : Block_payload_hash.t; + payload_round : Round.t; + round : Round.t; + protocol : Protocol_hash.t; + next_protocol : Protocol_hash.t; + prequorum : prequorum option; + quorum : Kind.endorsement operation list; + payload : Operation_pool.payload; + live_blocks : Block_hash.Set.t; + (** Set of live blocks for this block that is used to filter + old or too recent operations. *) +} + +type cache = { + known_timestamps : Timestamp.time Baking_cache.Timestamp_of_round_cache.t; + round_timestamps : + (Timestamp.time * Round.t * delegate) + Baking_cache.Round_timestamp_interval_cache.t; +} + +type global_state = { + cctxt : Protocol_client_context.full; + chain_id : Chain_id.t; + config : Baking_configuration.t; + constants : Constants.t; + round_durations : Round.round_durations; + operation_worker : Operation_worker.t; + validation_mode : validation_mode; + delegates : delegate list; + cache : cache; +} + +val block_info_encoding : block_info Data_encoding.t + +val round_of_shell_header : Block_header.shell_header -> Round.t tzresult + +module SlotMap : Map.S with type key = Slot.t + +type endorsing_slot = { + delegate : Signature.public_key_hash; + slots : Slot.t trace; + endorsing_power : int; +} + +type delegate_slots = { + own_delegate_slots : (delegate * endorsing_slot) SlotMap.t; + all_delegate_slots : endorsing_slot SlotMap.t; + all_slots_by_round : Slot.t array; +} + +type proposal = {block : block_info; predecessor : block_info} + +val proposal_encoding : proposal Data_encoding.t + +type locked_round = {payload_hash : Block_payload_hash.t; round : Round.t} + +val locked_round_encoding : locked_round Data_encoding.t + +type endorsable_payload = {proposal : proposal; prequorum : prequorum} + +val endorsable_payload_encoding : endorsable_payload Data_encoding.t + +type elected_block = { + proposal : proposal; + endorsement_qc : Kind.endorsement operation list; +} + +type level_state = { + current_level : int32; + latest_proposal : proposal; + locked_round : locked_round option; + endorsable_payload : endorsable_payload option; + elected_block : elected_block option; + delegate_slots : delegate_slots; + next_level_delegate_slots : delegate_slots; + next_level_proposed_round : Round.t option; +} + +type phase = Idle | Awaiting_preendorsements | Awaiting_endorsements + +val phase_encoding : phase Data_encoding.t + +type round_state = {current_round : Round.t; current_phase : phase} + +type state = { + global_state : global_state; + level_state : level_state; + round_state : round_state; +} + +type t = state + +type timeout_kind = + | End_of_round of {ending_round : Round.t} + | Time_to_bake_next_level of {at_round : Round.t} + +val timeout_kind_encoding : timeout_kind Data_encoding.t + +type voting_power = int + +type event = + | New_proposal of proposal + | Prequorum_reached of + Operation_worker.candidate + * voting_power + * Kind.preendorsement operation list + | Quorum_reached of + Operation_worker.candidate + * voting_power + * Kind.endorsement operation list + | Timeout of timeout_kind + +val event_encoding : event Data_encoding.t + +type state_data = { + level_data : int32; + locked_round_data : locked_round option; + endorsable_payload_data : endorsable_payload option; +} + +val state_data_encoding : state_data Data_encoding.t + +val record_state : t -> unit tzresult Lwt.t + +val may_record_new_state : + previous_state:t -> new_state:t -> unit tzresult Lwt.t + +val load_endorsable_data : + Protocol_client_context.full -> + [`State] Baking_files.location -> + state_data option tzresult Lwt.t + +val may_load_endorsable_data : t -> t tzresult Lwt.t + +val compute_delegate_slots : + Protocol_client_context.full -> + delegate trace -> + level:int32 -> + chain:Shell_services.chain -> + delegate_slots tzresult Lwt.t + +val create_cache : unit -> cache + +val pp_validation_mode : Format.formatter -> validation_mode -> unit + +val pp_global_state : Format.formatter -> global_state -> unit + +val pp_option : + (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a option -> unit + +val pp_block_info : Format.formatter -> block_info -> unit + +val pp_proposal : Format.formatter -> proposal -> unit + +val pp_locked_round : Format.formatter -> locked_round -> unit + +val pp_endorsable_payload : Format.formatter -> endorsable_payload -> unit + +val pp_elected_block : Format.formatter -> elected_block -> unit + +val pp_endorsing_slot : Format.formatter -> delegate * endorsing_slot -> unit + +val pp_delegate_slots : Format.formatter -> delegate_slots -> unit + +val pp_level_state : Format.formatter -> level_state -> unit + +val pp_phase : Format.formatter -> phase -> unit + +val pp_round_state : Format.formatter -> round_state -> unit + +val pp : Format.formatter -> t -> unit + +val pp_timeout_kind : Format.formatter -> timeout_kind -> unit + +val pp_event : Format.formatter -> event -> unit diff --git a/src/proto_012_PsiThaCa/lib_delegate/block_forge.ml b/src/proto_012_PsiThaCa/lib_delegate/block_forge.ml new file mode 100644 index 000000000000..35776a82ce7e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/block_forge.ml @@ -0,0 +1,360 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type unsigned_block = { + unsigned_block_header : Block_header.t; + operations : Tezos_base.Operation.t list list; +} + +type simulation_kind = + | Filter of Operation_pool.pool + | Apply of { + ordered_pool : Operation_pool.ordered_pool; + payload_hash : Block_payload_hash.t; + } + +type simulation_mode = Local of Context.index | Node + +let forge_faked_protocol_data ?(payload_hash = Block_payload_hash.zero) + ~payload_round ~seed_nonce_hash ~liquidity_baking_escape_vote () = + Block_header. + { + contents = + { + payload_hash; + payload_round; + seed_nonce_hash; + proof_of_work_nonce = Baking_pow.empty_proof_of_work_nonce; + liquidity_baking_escape_vote; + }; + signature = Signature.zero; + } + +let convert_operation (op : packed_operation) : Tezos_base.Operation.t = + { + shell = op.shell; + proto = + Data_encoding.Binary.to_bytes_exn + Alpha_context.Operation.protocol_data_encoding + op.protocol_data; + } + +(* Build the block header : mimics node prevalidation *) +let finalize_block_header shell_header timestamp validation_result + operations_hash predecessor_block_metadata_hash + predecessor_ops_metadata_hash = + let {Tezos_protocol_environment.context; fitness; message; _} = + validation_result + in + let validation_passes = List.length Main.validation_passes in + (Context_ops.get_test_chain context >>= function + | Not_running -> return context + | Running {expiration; _} -> + if Time.Protocol.(expiration <= timestamp) then + Context_ops.add_test_chain context Not_running >>= fun context -> + return context + else return context + | Forking _ -> assert false) + >>=? fun context -> + (match predecessor_block_metadata_hash with + | Some predecessor_block_metadata_hash -> + Context_ops.add_predecessor_block_metadata_hash + context + predecessor_block_metadata_hash + | None -> Lwt.return context) + >>= fun context -> + (match predecessor_ops_metadata_hash with + | Some predecessor_ops_metadata_hash -> + Context_ops.add_predecessor_ops_metadata_hash + context + predecessor_ops_metadata_hash + | None -> Lwt.return context) + >>= fun context -> + let context = Context_ops.hash ~time:timestamp ?message context in + let header = + Tezos_base.Block_header. + { + shell_header with + level = Int32.succ shell_header.level; + validation_passes; + operations_hash; + fitness; + context; + } + in + return header + +let retain_live_operations_only ~live_blocks operation_pool = + Operation_pool.filter_pool + (fun ({shell; _} : packed_operation) -> + Block_hash.Set.mem shell.branch live_blocks) + operation_pool + +let forge (cctxt : #Protocol_client_context.full) ~chain_id ~pred_info + ~timestamp ~liquidity_baking_escape_vote fees_config ~seed_nonce_hash + ~payload_round simulation_mode simulation_kind constants = + let predecessor_block = (pred_info : Baking_state.block_info) in + let hard_gas_limit_per_block = constants.Constants.hard_gas_limit_per_block in + let chain = `Hash chain_id in + let simulation_kind = + match simulation_kind with + | Filter operation_pool -> + (* We cannot include operations that are not live with respect + to our predecessor otherwise the node would reject the block. *) + let filtered_pool = + retain_live_operations_only + ~live_blocks:pred_info.live_blocks + operation_pool + in + Filter filtered_pool + | Apply _ as x -> x + in + (match (simulation_mode, simulation_kind) with + | (Baking_state.Node, Filter operation_pool) -> + let filtered_operations = + Operation_selection.filter_operations_without_simulation + fees_config + ~hard_gas_limit_per_block + operation_pool + in + let faked_protocol_data = + forge_faked_protocol_data + ~payload_round + ~seed_nonce_hash + ~liquidity_baking_escape_vote + () + in + Node_rpc.preapply_block + cctxt + ~chain + ~head:predecessor_block.hash + ~timestamp + ~protocol_data:faked_protocol_data + filtered_operations + >>=? fun (shell_header, preapply_result) -> + (* only retain valid operations *) + let operations = + List.map + (fun l -> List.map snd l.Preapply_result.applied) + preapply_result + in + let payload_hash = + let operation_list_hash = + Stdlib.List.tl operations |> List.flatten + |> List.map Tezos_base.Operation.hash + |> Operation_list_hash.compute + in + Block_payload.hash + ~predecessor:shell_header.predecessor + payload_round + operation_list_hash + in + return (shell_header, operations, payload_hash) + | (Node, Apply {ordered_pool; payload_hash}) -> + let operations = Operation_pool.ordered_to_list_list ordered_pool in + let faked_protocol_data = + forge_faked_protocol_data + ~seed_nonce_hash + ~liquidity_baking_escape_vote + ~payload_hash + ~payload_round + () + in + Node_rpc.preapply_block + cctxt + ~chain + ~head:predecessor_block.hash + ~timestamp + ~protocol_data:faked_protocol_data + operations + >>=? fun (shell_header, _preapply_result) -> + let operations = List.map (List.map convert_operation) operations in + return (shell_header, operations, payload_hash) + | (Local context_index, Filter operation_pool) -> + let faked_protocol_data = + forge_faked_protocol_data + ~payload_round + ~seed_nonce_hash + ~liquidity_baking_escape_vote + () + in + Baking_simulator.begin_construction + ~timestamp + ~protocol_data:faked_protocol_data + context_index + predecessor_block + chain_id + >>=? fun incremental -> + Operation_selection.filter_operations_with_simulation + incremental + fees_config + ~hard_gas_limit_per_block + operation_pool + >>=? fun { + Operation_selection.operations; + validation_result; + operations_hash; + _; + } -> + let _op_pool' = + Operation_pool.(add_operations empty (List.concat operations)) + in + protect + ~on_error:(fun _ -> return_none) + (fun () -> + Shell_services.Blocks.metadata_hash + cctxt + ~block:(`Hash (predecessor_block.hash, 0)) + ~chain + () + >>=? fun pred_block_metadata_hash -> + return (Some pred_block_metadata_hash)) + >>=? fun pred_block_metadata_hash -> + protect + ~on_error:(fun _ -> return_none) + (fun () -> + Shell_services.Blocks.Operation_metadata_hashes.root + cctxt + ~block:(`Hash (predecessor_block.hash, 0)) + ~chain + () + >>=? fun pred_op_metadata_hash -> return (Some pred_op_metadata_hash)) + >>=? fun pred_op_metadata_hash -> + finalize_block_header + incremental.header + timestamp + validation_result + operations_hash + pred_block_metadata_hash + pred_op_metadata_hash + >>=? fun shell_header -> + let operations = List.map (List.map convert_operation) operations in + let payload_hash = + let operation_list_hash = + Stdlib.List.tl operations |> List.flatten + |> List.map Tezos_base.Operation.hash + |> Operation_list_hash.compute + in + Block_payload.hash + ~predecessor:shell_header.predecessor + payload_round + operation_list_hash + in + return (shell_header, operations, payload_hash) + | (Local context_index, Apply {ordered_pool; payload_hash}) -> + let faked_protocol_data = + forge_faked_protocol_data + ~seed_nonce_hash + ~liquidity_baking_escape_vote + ~payload_hash + ~payload_round + () + in + Shell_services.Chain.chain_id cctxt ~chain () >>=? fun chain_id -> + Baking_simulator.begin_construction + ~timestamp + ~protocol_data:faked_protocol_data + context_index + predecessor_block + chain_id + >>=? fun incremental -> + let operations = Operation_pool.ordered_to_list_list ordered_pool in + (* We must make sure that the given consensus operations are + pre-checked/pre-filtered before calling this function, + otherwise, these will fail *) + List.fold_left_es + (fun inc op -> + Baking_simulator.add_operation inc op >>=? fun (inc, _) -> return inc) + incremental + (List.flatten operations) + >>=? fun incremental -> + let operations_hash = + Operation_list_list_hash.compute + (List.map + (fun sl -> + Operation_list_hash.compute (List.map Operation.hash_packed sl)) + operations) + in + (* We need to compute the final [operations_hash] before + finalizing the block because it will be used in the cache's nonce. *) + let incremental = + {incremental with header = {incremental.header with operations_hash}} + in + Baking_simulator.finalize_construction incremental + >>=? fun (validation_result, _) -> + protect + ~on_error:(fun _ -> return_none) + (fun () -> + Shell_services.Blocks.metadata_hash + cctxt + ~block:(`Hash (predecessor_block.hash, 0)) + ~chain + () + >>=? fun pred_block_metadata_hash -> + return (Some pred_block_metadata_hash)) + >>=? fun pred_block_metadata_hash -> + protect + ~on_error:(fun _ -> return_none) + (fun () -> + Shell_services.Blocks.Operation_metadata_hashes.root + cctxt + ~block:(`Hash (predecessor_block.hash, 0)) + ~chain + () + >>=? fun pred_op_metadata_hash -> return (Some pred_op_metadata_hash)) + >>=? fun pred_op_metadata_hash -> + finalize_block_header + incremental.header + timestamp + validation_result + operations_hash + pred_block_metadata_hash + pred_op_metadata_hash + >>=? fun shell_header -> + let operations = List.map (List.map convert_operation) operations in + return (shell_header, operations, payload_hash)) + >>=? fun (shell_header, operations, payload_hash) -> + Baking_pow.mine + ~proof_of_work_threshold:constants.proof_of_work_threshold + shell_header + (fun proof_of_work_nonce -> + { + Block_header.payload_hash; + payload_round; + seed_nonce_hash; + proof_of_work_nonce; + liquidity_baking_escape_vote; + }) + >>=? fun contents -> + let unsigned_block_header = + { + Block_header.shell = shell_header; + protocol_data = {contents; signature = Signature.zero}; + } + in + return {unsigned_block_header; operations} diff --git a/src/proto_012_PsiThaCa/lib_delegate/block_forge.mli b/src/proto_012_PsiThaCa/lib_delegate/block_forge.mli new file mode 100644 index 000000000000..5549a3f19881 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/block_forge.mli @@ -0,0 +1,63 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type unsigned_block = { + unsigned_block_header : Block_header.t; + operations : Tezos_base.Operation.t list list; +} + +type simulation_kind = + | Filter of Operation_pool.pool + | Apply of { + ordered_pool : Operation_pool.ordered_pool; + payload_hash : Block_payload_hash.t; + } + +type simulation_mode = Local of Context.index | Node + +val forge_faked_protocol_data : + ?payload_hash:Block_payload_hash.t -> + payload_round:Round.t -> + seed_nonce_hash:Nonce_hash.t option -> + liquidity_baking_escape_vote:bool -> + unit -> + block_header_data + +val forge : + #Protocol_client_context.full -> + chain_id:Chain_id.t -> + pred_info:Baking_state.block_info -> + timestamp:Time.Protocol.t -> + liquidity_baking_escape_vote:bool -> + Baking_configuration.fees_config -> + seed_nonce_hash:Nonce_hash.t option -> + payload_round:Round.t -> + Baking_state.validation_mode -> + simulation_kind -> + Constants.parametric -> + unsigned_block tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/client_baking_blocks.ml b/src/proto_012_PsiThaCa/lib_delegate/client_baking_blocks.ml new file mode 100644 index 000000000000..b678e02824c8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/client_baking_blocks.ml @@ -0,0 +1,188 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type block_info = { + hash : Block_hash.t; + chain_id : Chain_id.t; + predecessor : Block_hash.t; + fitness : Bytes.t list; + timestamp : Time.Protocol.t; + protocol : Protocol_hash.t; + next_protocol : Protocol_hash.t; + proto_level : int; + level : Raw_level.t; + context : Context_hash.t; +} + +let raw_info cctxt ?(chain = `Main) hash shell_header = + let block = `Hash (hash, 0) in + Shell_services.Chain.chain_id cctxt ~chain () >>=? fun chain_id -> + Shell_services.Blocks.protocols cctxt ~chain ~block () + >>=? fun {current_protocol = protocol; next_protocol} -> + let { + Tezos_base.Block_header.predecessor; + fitness; + timestamp; + level; + context; + proto_level; + _; + } = + shell_header + in + match Raw_level.of_int32 level with + | Ok level -> + return + { + hash; + chain_id; + predecessor; + fitness; + timestamp; + protocol; + next_protocol; + proto_level; + level; + context; + } + | Error _ -> failwith "Cannot convert level into int32" + +let info cctxt ?(chain = `Main) block = + Shell_services.Blocks.hash cctxt ~chain ~block () >>=? fun hash -> + Shell_services.Blocks.Header.shell_header cctxt ~chain ~block () + >>=? fun shell_header -> raw_info cctxt ~chain hash shell_header + +module Block_seen_event = struct + type t = { + hash : Block_hash.t; + header : Tezos_base.Block_header.t; + occurrence : [`Valid_blocks of Chain_id.t | `Heads]; + } + + let make hash header occurrence () = {hash; header; occurrence} + + module Definition = struct + let section = None + + let name = "block-seen-" ^ Protocol.name + + type nonrec t = t + + let encoding = + let open Data_encoding in + let v0_encoding = + conv + (function {hash; header; occurrence} -> (hash, occurrence, header)) + (fun (b, o, h) -> make b h o ()) + (obj3 + (req "hash" Block_hash.encoding) + (* Occurrence has to come before header, because: + (Invalid_argument + "Cannot merge two objects when the left element is of + variable length and the right one of dynamic + length. You should use the reverse order, or wrap the + second one with Data_encoding.dynamic_size.") *) + (req + "occurrence" + (union + [ + case + ~title:"heads" + (Tag 0) + (obj1 (req "occurrence-kind" (constant "heads"))) + (function `Heads -> Some () | _ -> None) + (fun () -> `Heads); + case + ~title:"valid-blocks" + (Tag 1) + (obj2 + (req "occurrence-kind" (constant "valid-blocks")) + (req "chain-id" Chain_id.encoding)) + (function + | `Valid_blocks ch -> Some ((), ch) | _ -> None) + (fun ((), ch) -> `Valid_blocks ch); + ])) + (req "header" Tezos_base.Block_header.encoding)) + in + With_version.(encoding ~name (first_version v0_encoding)) + + let pp ~short:_ ppf {hash; _} = + Format.fprintf ppf "Saw block %a" Block_hash.pp_short hash + + let doc = "Block observed while monitoring a blockchain." + + let level _ = Internal_event.Info + end + + module Event = Internal_event.Make (Definition) +end + +let monitor_valid_blocks cctxt ?chains ?protocols ~next_protocols () = + Monitor_services.valid_blocks cctxt ?chains ?protocols ?next_protocols () + >>=? fun (block_stream, _stop) -> + return + (Lwt_stream.map_s + (fun ((chain, block), header) -> + Block_seen_event.(Event.emit (make block header (`Valid_blocks chain))) + >>=? fun () -> + raw_info + cctxt + ~chain:(`Hash chain) + block + header.Tezos_base.Block_header.shell) + block_stream) + +let monitor_heads cctxt ~next_protocols chain = + Monitor_services.heads cctxt ?next_protocols chain + >>=? fun (block_stream, _stop) -> + return + (Lwt_stream.map_s + (fun (block, ({Tezos_base.Block_header.shell; _} as header)) -> + Block_seen_event.(Event.emit (make block header `Heads)) >>=? fun () -> + raw_info cctxt ~chain block shell) + block_stream) + +let blocks_from_current_cycle cctxt ?(chain = `Main) block ?(offset = 0l) () = + Shell_services.Blocks.hash cctxt ~chain ~block () >>=? fun hash -> + Shell_services.Blocks.Header.shell_header cctxt ~chain ~block () + >>=? fun {level; _} -> + Plugin.RPC.levels_in_current_cycle cctxt ~offset (chain, block) >>= function + | Error (RPC_context.Not_found _ :: _) -> return_nil + | Error _ as err -> Lwt.return err + | Ok (first, last) -> + let length = Int32.to_int (Int32.sub level (Raw_level.to_int32 first)) in + Shell_services.Blocks.list cctxt ~chain ~heads:[hash] ~length () + >>=? fun blocks -> + (* TODO-TB change this *) + let head = match blocks with hd :: _ -> hd | _ -> assert false in + let blocks = + List.remove (length - Int32.to_int (Raw_level.diff last first)) head + in + if Int32.equal level (Raw_level.to_int32 last) then + return (hash :: blocks) + else return blocks diff --git a/src/proto_012_PsiThaCa/lib_delegate/client_baking_blocks.mli b/src/proto_012_PsiThaCa/lib_delegate/client_baking_blocks.mli new file mode 100644 index 000000000000..fdf29d613ddb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/client_baking_blocks.mli @@ -0,0 +1,68 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type block_info = { + hash : Block_hash.t; + chain_id : Chain_id.t; + predecessor : Block_hash.t; + fitness : Bytes.t list; + timestamp : Time.Protocol.t; + protocol : Protocol_hash.t; + next_protocol : Protocol_hash.t; + proto_level : int; + level : Raw_level.t; + context : Context_hash.t; +} + +val info : + #Protocol_client_context.rpc_context -> + ?chain:Chain_services.chain -> + Block_services.block -> + block_info tzresult Lwt.t + +val monitor_valid_blocks : + #Protocol_client_context.rpc_context -> + ?chains:Chain_services.chain list -> + ?protocols:Protocol_hash.t list -> + next_protocols:Protocol_hash.t list option -> + unit -> + block_info tzresult Lwt_stream.t tzresult Lwt.t + +val monitor_heads : + #Protocol_client_context.rpc_context -> + next_protocols:Protocol_hash.t list option -> + Chain_services.chain -> + block_info tzresult Lwt_stream.t tzresult Lwt.t + +val blocks_from_current_cycle : + #Protocol_client_context.rpc_context -> + ?chain:Chain_services.chain -> + Block_services.block -> + ?offset:int32 -> + unit -> + Block_hash.t list tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/client_baking_denunciation.ml b/src/proto_012_PsiThaCa/lib_delegate/client_baking_denunciation.ml new file mode 100644 index 000000000000..09f35229368b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/client_baking_denunciation.ml @@ -0,0 +1,489 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Protocol_client_context +open Client_baking_blocks +module Events = Delegate_events.Denunciator + +module HLevel = Hashtbl.Make (struct + type t = Chain_id.t * Raw_level.t * Round.t + + let equal (c, l, r) (c', l', r') = + Chain_id.equal c c' && Raw_level.equal l l' && Round.equal r r' + + let hash (c, lvl, r) = Hashtbl.hash (c, lvl, r) +end) + +(* Blocks are associated to the delegates who baked them *) +module Delegate_Map = Map.Make (Signature.Public_key_hash) + +(* (pre)endorsements are associated to the slot they are injected + with; we rely on the fact that there is a unique canonical slot + identifying a (pre)endorser. *) +module Slot_Map = Slot.Map + +(* type of operations stream, as returned by monitor_operations RPC *) +type ops_stream = + ((Operation_hash.t * packed_operation) * error list) list Lwt_stream.t + +type 'a state = { + (* Endorsements seen so far *) + endorsements_table : Kind.endorsement operation Slot_Map.t HLevel.t; + (* Preendorsements seen so far *) + preendorsements_table : Kind.preendorsement operation Slot_Map.t HLevel.t; + (* Blocks received so far *) + blocks_table : Block_hash.t Delegate_Map.t HLevel.t; + (* Maximum delta of level to register *) + preserved_levels : int; + (* Highest level seen in a block *) + mutable highest_level_encountered : Raw_level.t; + (* This constant allows to set at which frequency (expressed in blocks levels) + the tables above are cleaned. Cleaning the table means removing information + stored about old levels up to + 'highest_level_encountered - preserved_levels'. + *) + clean_frequency : int; + (* the decreasing cleaning countdown for the next cleaning *) + mutable cleaning_countdown : int; + (* stream of all valid blocks *) + blocks_stream : (block_info, 'a) result Lwt_stream.t; + (* operations stream. Reset on new heads flush *) + mutable ops_stream : ops_stream; + (* operatons stream stopper. Used when a q new *) + mutable ops_stream_stopper : unit -> unit; +} + +let create_state ~preserved_levels blocks_stream ops_stream ops_stream_stopper = + let clean_frequency = max 1 (preserved_levels / 10) in + Lwt.return + { + endorsements_table = HLevel.create preserved_levels; + preendorsements_table = HLevel.create preserved_levels; + blocks_table = HLevel.create preserved_levels; + preserved_levels; + highest_level_encountered = Raw_level.root (* 0l *); + clean_frequency; + cleaning_countdown = clean_frequency; + blocks_stream; + ops_stream; + ops_stream_stopper; + } + +(* We choose a previous offset (5 blocks from head) to ensure that the + injected operation is branched from a valid + predecessor. Denunciation operations can be emitted when the + consensus is under attack and may occur so you want to inject the + operation from a block which is considered "final". *) +let get_block_offset level = + match Raw_level.of_int32 5l with + | Ok min_level -> + let offset = Raw_level.diff level min_level in + if Compare.Int32.(offset >= 0l) then Lwt.return (`Head 5) + else + (* offset < 0l *) + let negative_offset = Int32.to_int offset in + (* We cannot inject at at level 0 : this is the genesis + level. We inject starting from level 1 thus the '- 1'. *) + Lwt.return (`Head (5 + negative_offset - 1)) + | Error errs -> + Events.(emit invalid_level_conversion) (Environment.wrap_tztrace errs) + >>= fun () -> Lwt.return (`Head 0) + +let get_payload_hash (type kind) (op_kind : kind consensus_operation_type) + (op : kind Operation.t) = + match (op_kind, op.protocol_data.contents) with + | (Preendorsement, Single (Preendorsement consensus_content)) + | (Endorsement, Single (Endorsement consensus_content)) -> + consensus_content.block_payload_hash + | _ -> . + +let double_consensus_op_evidence (type kind) : + kind consensus_operation_type -> + #Protocol_client_context.full -> + 'a -> + branch:Block_hash.t -> + op1:kind Alpha_context.operation -> + op2:kind Alpha_context.operation -> + unit -> + bytes Environment.Error_monad.shell_tzresult Lwt.t = function + | Endorsement -> Plugin.RPC.Forge.double_endorsement_evidence + | Preendorsement -> Plugin.RPC.Forge.double_preendorsement_evidence + +let process_consensus_op (type kind) cctxt + (op_kind : kind consensus_operation_type) (new_op : kind Operation.t) + chain_id level round slot ops_table = + let map = + Option.value ~default:Slot_Map.empty + @@ HLevel.find ops_table (chain_id, level, round) + in + (* If a previous endorsement made by this pkh (the slot determines the pkh) + is found for the same level we inject a double_(pre)endorsement *) + match Slot_Map.find slot map with + | None -> + return + @@ HLevel.add + ops_table + (chain_id, level, round) + (Slot_Map.add slot new_op map) + | Some existing_op + when Block_payload_hash.( + get_payload_hash op_kind existing_op + <> get_payload_hash op_kind new_op) -> + (* same level and round, and different payload hash for this slot *) + let (new_op_hash, existing_op_hash) = + (Operation.hash new_op, Operation.hash existing_op) + in + let (op1, op2) = + if Operation_hash.(new_op_hash < existing_op_hash) then + (new_op, existing_op) + else (existing_op, new_op) + in + get_block_offset level >>= fun block -> + let chain = `Hash chain_id in + Alpha_block_services.hash cctxt ~chain ~block () >>=? fun block_hash -> + double_consensus_op_evidence + op_kind + cctxt + (`Hash chain_id, block) + ~branch:block_hash + ~op1 + ~op2 + () + >>=? fun bytes -> + let bytes = Signature.concat bytes Signature.zero in + let (double_op_detected, double_op_denounced) = + Events.( + match op_kind with + | Endorsement -> + (double_endorsement_detected, double_endorsement_denounced) + | Preendorsement -> + (double_preendorsement_detected, double_preendorsement_denounced)) + in + Events.(emit double_op_detected) (new_op_hash, existing_op_hash) + >>= fun () -> + HLevel.replace + ops_table + (chain_id, level, round) + (Slot_Map.add slot new_op map) ; + Shell_services.Injection.operation cctxt ~chain bytes >>=? fun op_hash -> + Events.(emit double_op_denounced) (op_hash, bytes) >>= fun () -> + return_unit + | _ -> return_unit + +let process_operations (cctxt : #Protocol_client_context.full) state + (endorsements : 'a list) ~packed_op chain_id = + List.iter_es + (fun op -> + let {shell; protocol_data; _} = packed_op op in + match protocol_data with + | Operation_data + ({contents = Single (Preendorsement {round; slot; level; _}); _} as + protocol_data) -> + let new_preendorsement : Kind.preendorsement Alpha_context.operation = + {shell; protocol_data} + in + process_consensus_op + cctxt + Preendorsement + new_preendorsement + chain_id + level + round + slot + state.preendorsements_table + | Operation_data + ({contents = Single (Endorsement {round; slot; level; _}); _} as + protocol_data) -> + let new_endorsement : Kind.endorsement Alpha_context.operation = + {shell; protocol_data} + in + process_consensus_op + cctxt + Endorsement + new_endorsement + chain_id + level + round + slot + state.endorsements_table + | _ -> + (* not a consensus operation *) + return_unit) + endorsements + +let context_block_header cctxt ~chain b_hash = + Alpha_block_services.header cctxt ~chain ~block:(`Hash (b_hash, 0)) () + >>=? fun ({shell; protocol_data; _} : Alpha_block_services.block_header) -> + return {Alpha_context.Block_header.shell; protocol_data} + +let process_block (cctxt : #Protocol_client_context.full) state + (header : Alpha_block_services.block_info) = + match header with + | {hash; metadata = None; _} -> + Events.(emit unexpected_pruned_block) hash >>= fun () -> return_unit + | { + Alpha_block_services.chain_id; + hash = new_hash; + metadata = Some {protocol_data = {baker; level_info = {level; _}; _}; _}; + header = {shell = {fitness; _}; _}; + _; + } -> ( + let fitness = Fitness.from_raw fitness in + Lwt.return + (match fitness with + | Ok fitness -> Ok (Fitness.round fitness) + | Error errs -> Error (Environment.wrap_tztrace errs)) + >>=? fun round -> + let chain = `Hash chain_id in + let map = + Option.value ~default:Delegate_Map.empty + @@ HLevel.find state.blocks_table (chain_id, level, round) + in + match Delegate_Map.find baker map with + | None -> + return + @@ HLevel.add + state.blocks_table + (chain_id, level, round) + (Delegate_Map.add baker new_hash map) + | Some existing_hash when Block_hash.(existing_hash = new_hash) -> + (* This case should never happen *) + Events.(emit double_baking_but_not) () >>= fun () -> + return + @@ HLevel.replace + state.blocks_table + (chain_id, level, round) + (Delegate_Map.add baker new_hash map) + | Some existing_hash -> + (* If a previous block made by this pkh is found for + the same (level, round) we inject a double_baking_evidence *) + context_block_header cctxt ~chain existing_hash >>=? fun bh1 -> + context_block_header cctxt ~chain new_hash >>=? fun bh2 -> + let hash1 = Block_header.hash bh1 in + let hash2 = Block_header.hash bh2 in + let (bh1, bh2) = + if Block_hash.(hash1 < hash2) then (bh1, bh2) else (bh2, bh1) + in + (* If the blocks are on different chains then skip it *) + get_block_offset level >>= fun block -> + Alpha_block_services.hash cctxt ~chain ~block () + >>=? fun block_hash -> + Plugin.RPC.Forge.double_baking_evidence + cctxt + (chain, block) + ~branch:block_hash + ~bh1 + ~bh2 + () + >>=? fun bytes -> + let bytes = Signature.concat bytes Signature.zero in + Events.(emit double_baking_detected) () >>= fun () -> + Shell_services.Injection.operation cctxt ~chain bytes + >>=? fun op_hash -> + Events.(emit double_baking_denounced) (op_hash, bytes) >>= fun () -> + return + @@ HLevel.replace + state.blocks_table + (chain_id, level, round) + (Delegate_Map.add baker new_hash map)) + +(* Remove levels that are lower than the + [highest_level_encountered] minus [preserved_levels] *) +let cleanup_old_operations state = + state.cleaning_countdown <- state.cleaning_countdown - 1 ; + if state.cleaning_countdown < 0 then ( + (* It's time to remove old levels *) + state.cleaning_countdown <- state.clean_frequency ; + let highest_level_encountered = + Int32.to_int (Raw_level.to_int32 state.highest_level_encountered) + in + let diff = highest_level_encountered - state.preserved_levels in + let threshold = + if diff < 0 then Raw_level.root + else + Raw_level.of_int32 (Int32.of_int diff) |> function + | Ok threshold -> threshold + | Error _ -> Raw_level.root + in + let filter hmap = + HLevel.filter_map_inplace + (fun (_, level, _) x -> + if Raw_level.(level < threshold) then None else Some x) + hmap + in + filter state.preendorsements_table ; + filter state.endorsements_table ; + filter state.blocks_table) + +(* Each new block is processed : + - Checking that every baker injected only once at this level + - Checking that every (pre)endorser operated only once at this level +*) +let process_new_block (cctxt : #Protocol_client_context.full) state + {hash; chain_id; level; protocol; next_protocol; _} = + if Protocol_hash.(protocol <> next_protocol) then + Events.(emit protocol_change_detected) () >>= fun () -> return_unit + else + Events.(emit accuser_saw_block) (level, hash) >>= fun () -> + let chain = `Hash chain_id in + let block = `Hash (hash, 0) in + state.highest_level_encountered <- + Raw_level.max level state.highest_level_encountered ; + (* Processing blocks *) + (Alpha_block_services.info cctxt ~chain ~block () >>= function + | Ok block_info -> process_block cctxt state block_info + | Error errs -> + Events.(emit fetch_operations_error) (hash, errs) >>= fun () -> + return_unit) + >>=? fun () -> + (* Processing (pre)endorsements in the block *) + (Alpha_block_services.Operations.operations cctxt ~chain ~block () + >>= function + | Ok (consensus_ops :: _) -> + let packed_op {Alpha_block_services.shell; protocol_data; _} = + {shell; protocol_data} + in + process_operations cctxt state consensus_ops ~packed_op chain_id + | Ok [] -> + (* should not happen, unless the semantics of + Alpha_block_services.Operations.operations (which is supposed to + return a list of 4 elements changes. In which case, this code + should be adapted). *) + assert false + | Error errs -> + Events.(emit fetch_operations_error) (hash, errs) >>= fun () -> + return_unit) + >>=? fun () -> + cleanup_old_operations state ; + return_unit + +let process_new_block cctxt state bi = + process_new_block cctxt state bi >>= function + | Ok () -> Events.(emit accuser_processed_block) bi.hash >>= return + | Error errs -> Events.(emit accuser_block_error) (bi.hash, errs) >>= return + +module B_Events = Delegate_events.Baking_scheduling + +let rec wait_for_first_block ~name stream = + Lwt_stream.get stream >>= function + | None | Some (Error _) -> + B_Events.(emit cannot_fetch_event) name >>= fun () -> + (* NOTE: this is not a tight loop because of Lwt_stream.get *) + wait_for_first_block ~name stream + | Some (Ok bi) -> Lwt.return bi + +let log_errors_and_continue ~name p = + p >>= function + | Ok () -> Lwt.return_unit + | Error errs -> B_Events.(emit daemon_error) (name, errs) + +let start_ops_monitor cctxt = + Alpha_block_services.Mempool.monitor_operations + cctxt + ~chain:cctxt#chain + ~applied:true + ~branch_delayed:true + ~branch_refused:true + ~refused:true + () + +let create (cctxt : #Protocol_client_context.full) ?canceler ~preserved_levels + valid_blocks_stream = + B_Events.(emit daemon_setup) name >>= fun () -> + start_ops_monitor cctxt >>=? fun (ops_stream, ops_stream_stopper) -> + create_state + ~preserved_levels + valid_blocks_stream + ops_stream + ops_stream_stopper + >>= fun state -> + Option.iter + (fun canceler -> + Lwt_canceler.on_cancel canceler (fun () -> + state.ops_stream_stopper () ; + Lwt.return_unit)) + canceler ; + wait_for_first_block ~name state.blocks_stream >>= fun _first_event -> + let last_get_block = ref None in + let get_block () = + match !last_get_block with + | None -> + let t = Lwt_stream.get state.blocks_stream in + last_get_block := Some t ; + t + | Some t -> t + in + let last_get_ops = ref None in + let get_ops () = + match !last_get_ops with + | None -> + let t = Lwt_stream.get state.ops_stream in + last_get_ops := Some t ; + t + | Some t -> t + in + Chain_services.chain_id cctxt () >>=? fun chain_id -> + (* main loop *) + let rec worker_loop () = + Lwt.choose + [ + (Lwt_exit.clean_up_starts >|= fun _ -> `Termination); + (get_block () >|= fun e -> `Block e); + (get_ops () >|= fun e -> `Operations e); + ] + >>= function + (* event matching *) + | `Termination -> return_unit + | `Block (None | Some (Error _)) -> + (* exit when the node is unavailable *) + last_get_block := None ; + B_Events.(emit daemon_connection_lost) name >>= fun () -> + fail Baking_errors.Node_connection_lost + | `Block (Some (Ok bi)) -> + last_get_block := None ; + log_errors_and_continue ~name @@ process_new_block cctxt state bi + >>= fun () -> worker_loop () + | `Operations None -> + (* restart a new operations monitor stream *) + last_get_ops := None ; + state.ops_stream_stopper () ; + start_ops_monitor cctxt >>=? fun (ops_stream, ops_stream_stopper) -> + state.ops_stream <- ops_stream ; + state.ops_stream_stopper <- ops_stream_stopper ; + worker_loop () + | `Operations (Some ops) -> + last_get_ops := None ; + log_errors_and_continue ~name + @@ process_operations + cctxt + state + ops + ~packed_op:(fun ((_h, op), _errl) -> op) + chain_id + >>= fun () -> worker_loop () + in + B_Events.(emit daemon_start) name >>= fun () -> worker_loop () diff --git a/src/proto_012_PsiThaCa/lib_delegate/client_baking_denunciation.mli b/src/proto_012_PsiThaCa/lib_delegate/client_baking_denunciation.mli new file mode 100644 index 000000000000..46e784d132b4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/client_baking_denunciation.mli @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val create : + #Protocol_client_context.full -> + ?canceler:Lwt_canceler.t -> + preserved_levels:int -> + Client_baking_blocks.block_info tzresult Lwt_stream.t -> + unit tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/client_baking_scheduling.ml b/src/proto_012_PsiThaCa/lib_delegate/client_baking_scheduling.ml new file mode 100644 index 000000000000..0c61aabfa353 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/client_baking_scheduling.ml @@ -0,0 +1,33 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Events = Delegate_events.Baking_scheduling + +let sleep_until time = + (* Sleeping is a system op, baking is a protocol op, this is where we convert *) + let time = Time.System.of_protocol_exn time in + let delay = Ptime.diff time (Tezos_stdlib_unix.Systime_os.now ()) in + if Ptime.Span.compare delay Ptime.Span.zero < 0 then None + else Some (Lwt_unix.sleep (Ptime.Span.to_float_s delay)) diff --git a/src/proto_012_PsiThaCa/lib_delegate/client_baking_scheduling.mli b/src/proto_012_PsiThaCa/lib_delegate/client_baking_scheduling.mli new file mode 100644 index 000000000000..ae4a323ca1cc --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/client_baking_scheduling.mli @@ -0,0 +1,54 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val sleep_until : Time.Protocol.t -> unit Lwt.t option + +(* val wait_for_first_event : + * name:string -> 'event tzresult Lwt_stream.t -> 'event Lwt.t + * + * val main : + * name:string -> + * cctxt:(#Protocol_client_context.full as 'a) -> + * stream:'event tzresult Lwt_stream.t -> + * state_maker:('event -> 'state tzresult Lwt.t) -> + * pre_loop:('a -> 'state -> 'event -> unit tzresult Lwt.t) -> + * compute_timeout:('state -> 'timesup Lwt.t) -> + * timeout_k:('a -> 'state -> 'timesup -> unit tzresult Lwt.t) -> + * event_k:('a -> 'state -> 'event -> unit tzresult Lwt.t) -> + * finalizer:('state -> unit Lwt.t) -> + * unit tzresult Lwt.t *) + +(** [main ~name ~cctxt ~stream ~state_maker ~pre_loop ~timeout_maker ~timeout_k + ~event_k] is an infinitely running loop that + monitors new events arriving on [stream]. The loop exits when the + [stream] gives an error. + + The function [pre_loop] is called before the loop starts. + + The loop maintains a state (of type ['state]) initialized by [state_maker] + and passed to the callbacks [timeout_maker] (used to set up waking-up + timeouts), [timeout_k] (when a computed timeout happens), and [event_k] + (when a new event arrives on the stream). +*) diff --git a/src/proto_012_PsiThaCa/lib_delegate/client_daemon.ml b/src/proto_012_PsiThaCa/lib_delegate/client_daemon.ml new file mode 100644 index 000000000000..a21ec55610d2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/client_daemon.ml @@ -0,0 +1,147 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let rec retry (cctxt : #Protocol_client_context.full) ?max_delay ~delay ~factor + ~tries f x = + f x >>= function + | Ok _ as r -> Lwt.return r + | Error + (RPC_client_errors.Request_failed {error = Connection_failed _; _} :: _) + as err + when tries > 0 -> ( + cctxt#message "Connection refused, retrying in %.2f seconds..." delay + >>= fun () -> + Lwt.pick + [ + (Lwt_unix.sleep delay >|= fun () -> `Continue); + (Lwt_exit.clean_up_starts >|= fun _ -> `Killed); + ] + >>= function + | `Killed -> Lwt.return err + | `Continue -> + let next_delay = delay *. factor in + let delay = + Option.fold + ~none:next_delay + ~some:(fun max_delay -> Float.min next_delay max_delay) + max_delay + in + retry cctxt ?max_delay ~delay ~factor ~tries:(tries - 1) f x) + | Error _ as err -> Lwt.return err + +let rec retry_on_disconnection (cctxt : #Protocol_client_context.full) f = + f () >>= function + | Ok () -> return_unit + | Error (Baking_errors.Node_connection_lost :: _) -> + cctxt#warning + "Lost connection with the node. Retrying to establish connection..." + >>= fun () -> + (* Wait forever when the node stops responding... *) + Client_confirmations.wait_for_bootstrapped + ~retry:(retry cctxt ~max_delay:10. ~delay:1. ~factor:1.5 ~tries:max_int) + cctxt + >>=? fun () -> retry_on_disconnection cctxt f + | Error err -> + cctxt#error "Unexpected error: %a. Exiting..." pp_print_trace err + +module Baker = struct + let run (cctxt : Protocol_client_context.full) ?minimal_fees + ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte + ?liquidity_baking_escape_vote ?per_block_vote_file ~chain ~context_path + ~keep_alive delegates = + let process () = + Config_services.user_activated_upgrades cctxt + >>=? fun user_activated_upgrades -> + let config = + Baking_configuration.make + ?minimal_fees + ?minimal_nanotez_per_gas_unit + ?minimal_nanotez_per_byte + ?liquidity_baking_escape_vote + ?per_block_vote_file + ~context_path + ~user_activated_upgrades + () + in + cctxt#message + "Baker v%s (%s) for %a started." + Tezos_version.Version.current_string + Tezos_version.Current_git_info.abbreviated_commit_hash + Protocol_hash.pp_short + Protocol.hash + >>= fun () -> + let canceler = Lwt_canceler.create () in + let _ = + Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _ -> + cctxt#message "Shutting down the baker..." >>= fun () -> + Lwt_canceler.cancel canceler >>= fun _ -> Lwt.return_unit) + in + Baking_scheduling.run cctxt ~canceler ~chain config delegates + in + Client_confirmations.wait_for_bootstrapped + ~retry:(retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + cctxt + >>=? fun () -> + cctxt#message "Waiting for protocol %s to start..." Protocol.name + >>= fun () -> + Node_rpc.await_protocol_activation cctxt ~chain () >>=? fun () -> + if keep_alive then retry_on_disconnection cctxt process else process () +end + +module Accuser = struct + let run (cctxt : #Protocol_client_context.full) ~chain ~preserved_levels + ~keep_alive = + let process () = + Client_baking_blocks.monitor_valid_blocks + ~next_protocols:(Some [Protocol.hash]) + cctxt + ~chains:[chain] + () + >>=? fun valid_blocks_stream -> + cctxt#message + "Accuser v%s (%s) for %a started." + Tezos_version.Version.current_string + Tezos_version.Current_git_info.abbreviated_commit_hash + Protocol_hash.pp_short + Protocol.hash + >>= fun () -> + let canceler = Lwt_canceler.create () in + let _ = + Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _ -> + cctxt#message "Shutting down the accuser..." >>= fun () -> + Lwt_canceler.cancel canceler >>= fun _ -> Lwt.return_unit) + in + Client_baking_denunciation.create + cctxt + ~canceler + ~preserved_levels + valid_blocks_stream + in + Client_confirmations.wait_for_bootstrapped + ~retry:(retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + cctxt + >>=? fun () -> + if keep_alive then retry_on_disconnection cctxt process else process () +end diff --git a/src/proto_012_PsiThaCa/lib_delegate/client_daemon.mli b/src/proto_012_PsiThaCa/lib_delegate/client_daemon.mli new file mode 100644 index 000000000000..d7e1c5a01e55 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/client_daemon.mli @@ -0,0 +1,53 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Daemons directly supported by lib_delegate *) + +(** {1 Baker daemon} *) +module Baker : sig + val run : + Protocol_client_context.full -> + ?minimal_fees:Protocol.Alpha_context.Tez.t -> + ?minimal_nanotez_per_gas_unit:Q.t -> + ?minimal_nanotez_per_byte:Q.t -> + ?liquidity_baking_escape_vote:bool -> + ?per_block_vote_file:string -> + chain:Shell_services.chain -> + context_path:string -> + keep_alive:bool -> + Baking_state.delegate list -> + unit tzresult Lwt.t +end + +(** {1 Accuser daemon} *) + +module Accuser : sig + val run : + #Protocol_client_context.full -> + chain:Chain_services.chain -> + preserved_levels:int -> + keep_alive:bool -> + unit tzresult Lwt.t +end diff --git a/src/proto_012_PsiThaCa/lib_delegate/context_ops.ml b/src/proto_012_PsiThaCa/lib_delegate/context_ops.ml new file mode 100644 index 000000000000..8762bc9ddd3b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/context_ops.ml @@ -0,0 +1,108 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Backend-agnostic operations on the context *) + +let mem (context : Environment_context.Context.t) key = + match context with + | Context {kind = Shell_context.Context; ctxt; _} -> Context.mem ctxt key + | Context {kind = Memory_context.Context; ctxt; _} -> + Tezos_context_memory.Context.mem ctxt key + | Context t -> + Environment_context.err_implementation_mismatch + ~expected:"shell or memory" + ~got:t.impl_name + +let get_protocol (context : Environment_context.Context.t) = + match context with + | Context {kind = Shell_context.Context; ctxt; _} -> Context.get_protocol ctxt + | Context {kind = Memory_context.Context; ctxt; _} -> + Tezos_context_memory.Context.get_protocol ctxt + | Context t -> + Environment_context.err_implementation_mismatch + ~expected:"shell or memory" + ~got:t.impl_name + +let add_predecessor_block_metadata_hash + (context : Environment_context.Context.t) hash = + match context with + | Context {kind = Shell_context.Context; ctxt; _} -> + Context.add_predecessor_block_metadata_hash ctxt hash + >|= Shell_context.wrap_disk_context + | Context {kind = Memory_context.Context; ctxt; _} -> + Tezos_context_memory.Context.add_predecessor_block_metadata_hash ctxt hash + >|= Memory_context.wrap_memory_context + | Context t -> + Environment_context.err_implementation_mismatch + ~expected:"shell or memory" + ~got:t.impl_name + +let add_predecessor_ops_metadata_hash (context : Environment_context.Context.t) + hash = + match context with + | Context {kind = Shell_context.Context; ctxt; _} -> + Context.add_predecessor_ops_metadata_hash ctxt hash + >|= Shell_context.wrap_disk_context + | Context {kind = Memory_context.Context; ctxt; _} -> + Tezos_context_memory.Context.add_predecessor_ops_metadata_hash ctxt hash + >|= Memory_context.wrap_memory_context + | Context t -> + Environment_context.err_implementation_mismatch + ~expected:"shell or memory" + ~got:t.impl_name + +let hash ~time ?message (context : Environment_context.Context.t) = + match context with + | Context {kind = Shell_context.Context; ctxt; _} -> + Context.hash ~time ?message ctxt + | Context {kind = Memory_context.Context; ctxt; _} -> + Tezos_context_memory.Context.hash ~time ?message ctxt + | Context t -> + Environment_context.err_implementation_mismatch + ~expected:"shell or memory" + ~got:t.impl_name + +let get_test_chain (context : Environment_context.Context.t) = + match context with + | Context {kind = Shell_context.Context; ctxt; _} -> + Context.get_test_chain ctxt + | Context {kind = Memory_context.Context; _} -> + Lwt.return Test_chain_status.Not_running + | Context t -> + Environment_context.err_implementation_mismatch + ~expected:"shell or memory" + ~got:t.impl_name + +let add_test_chain (context : Environment_context.Context.t) status = + match context with + | Context {kind = Shell_context.Context; ctxt; _} -> + Context.add_test_chain ctxt status >|= Shell_context.wrap_disk_context + | Context {kind = Memory_context.Context; ctxt; _} -> + Tezos_context_memory.Context.add_test_chain ctxt status + >|= Memory_context.wrap_memory_context + | Context t -> + Environment_context.err_implementation_mismatch + ~expected:"shell or memory" + ~got:t.impl_name diff --git a/src/proto_012_PsiThaCa/lib_delegate/delegate_events.ml b/src/proto_012_PsiThaCa/lib_delegate/delegate_events.ml new file mode 100644 index 000000000000..ec06b2a6442c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/delegate_events.ml @@ -0,0 +1,788 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Tocqueville Group, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +let level = Internal_event.Notice + +(* Ignore the value in the output. *) +let pp_ignore fmt _ = Format.pp_print_string fmt "" + +module Revelation = struct + include Internal_event.Simple + + let section = [Protocol.name; "delegate"; "reveal"] + + let no_nonce_reveal = + declare_1 + ~section + ~level + ~name:"no_nonce_reveal" + ~msg:"nothing to reveal for block {block}" + ("block", Block_hash.encoding) + + let reveal_nonce = + declare_5 + ~section + ~level + ~name:"reveal_nonce" + ~msg: + "revealing nonce {nonce} from level {level} for chain {chain}, block \ + {block} with operation {operation}" + ("nonce", Alpha_context.Nonce.encoding) + ("level", Alpha_context.Raw_level.encoding) + ("chain", Data_encoding.string) + ("block", Data_encoding.string) + ("operation", Operation_hash.encoding) +end + +module Nonces = struct + include Internal_event.Simple + + let section = [Protocol.name; "delegate"; "nonces"] + + let cannot_retrieve_block_header = + declare_2 + ~section + ~level:Warning + ~name:"cannot_retrieve_block_header" + ~msg:"cannot retrieve block {block} header associated to nonce: {errors}" + ~pp2:pp_print_top_error_of_trace + ("block", Data_encoding.string) + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let cannot_retrieve_head_level = + declare_0 + ~section + ~level:Error + ~name:"cannot_retrieve_head_level" + ~msg:"cannot fetch chain's head level; aborting nonce filtering" + () + + let too_many_orphans = + declare_1 + ~section + ~level:Warning + ~name:"too_many_orphans" + ~msg: + "found too many nonces associated to blocks unknown by the node in \ + '$TEZOS_CLIENT/{filename}'; after checking that these blocks were \ + never included in the chain (e.g. via a block explorer), consider \ + using `tezos-client filter orphan nonces` to clear them" + ("filename", Data_encoding.string) + + let found_nonce = + declare_2 + ~section + ~level + ~name:"found_nonce" + ~msg:"found nonce to reveal for {hash} (level: {level})" + ("hash", Block_hash.encoding) + ("level", Alpha_context.Raw_level.encoding) + + let bad_nonce = + declare_1 + ~section + ~level:Error + ~name:"bad_nonce" + ~msg:"incoherent nonce for level {level}" + ("level", Alpha_context.Raw_level.encoding) +end + +module Denunciator = struct + include Internal_event.Simple + + let section = [Protocol.name; "delegate"; "denunciation"] + + let invalid_level_conversion = + declare_1 + ~section + ~level:Error + ~name:"invalid_level_conversion" + ~msg:"invalid level conversion: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let double_endorsement_detected = + declare_2 + ~section + ~level + ~name:"double_endorsement_detected" + ~msg:"double endorsement detected" + ("existing_endorsement", Operation_hash.encoding) + ("new_endorsement", Operation_hash.encoding) + + let double_endorsement_denounced = + declare_2 + ~section + ~level + ~name:"double_endorsement_denounced" + ~msg:"double endorsement evidence injected: {hash}" + ("hash", Operation_hash.encoding) + ~pp2:pp_ignore + ("bytes", Data_encoding.bytes) + + let double_preendorsement_detected = + declare_2 + ~section + ~level + ~name:"double_preendorsement_detected" + ~msg:"double preendorsement detected" + ("existing_preendorsement", Operation_hash.encoding) + ("new_preendorsement", Operation_hash.encoding) + + let double_preendorsement_denounced = + declare_2 + ~section + ~level + ~name:"double_preendorsement_denounced" + ~msg:"double preendorsement evidence injected: {hash}" + ("hash", Operation_hash.encoding) + ~pp2:pp_ignore + ("bytes", Data_encoding.bytes) + + let inconsistent_endorsement = + declare_1 + ~section + ~level:Error + ~name:"inconsistent_endorsement" + ~msg:"inconsistent endorsement found {hash}" + ("hash", Operation_hash.encoding) + + let unexpected_pruned_block = + declare_1 + ~section + ~level:Error + ~name:"unexpected_pruned_block" + ~msg:"unexpected pruned block: {hash}" + ("hash", Block_hash.encoding) + + let double_baking_but_not = + declare_0 + ~section + ~level:Debug + ~name:"double_baking_but_not" + ~msg:"double baking detected but block hashes are equivalent; skipping" + () + + let double_baking_detected = + declare_0 + ~section + ~level + ~name:"double_baking_detected" + ~msg:"double baking detected" + () + + let double_baking_denounced = + declare_2 + ~section + ~level + ~name:"double_baking_denounced" + ~msg:"double baking evidence injected {hash}" + ("hash", Operation_hash.encoding) + ~pp2:pp_ignore + ("bytes", Data_encoding.bytes) + + let protocol_change_detected = + declare_0 + ~section + ~level:Error + ~name:"protocol_change_detected" + ~msg:"protocol changing detected; skipping the block" + () + + let accuser_saw_block = + declare_2 + ~section + ~level:Debug + ~name:"accuser_saw_block" + ~msg:"block level: {level}" + ("level", Alpha_context.Raw_level.encoding) + ("hash", Block_hash.encoding) + + let fetch_operations_error = + declare_2 + ~section + ~level:Error + ~name:"fetch_operations_error" + ~msg:"error while fetching operations in block {hash} {errors}" + ~pp2:pp_print_top_error_of_trace + ("hash", Block_hash.encoding) + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let accuser_processed_block = + declare_1 + ~section + ~level + ~name:"accuser_processed_block" + ~msg:"block {hash} registered" + ("hash", Block_hash.encoding) + + let accuser_block_error = + declare_2 + ~section + ~level:Error + ~name:"accuser_block_error" + ~msg:"error while processing block {hash} {errors}" + ~pp2:pp_print_top_error_of_trace + ("hash", Block_hash.encoding) + ("errors", Error_monad.(TzTrace.encoding error_encoding)) +end + +module Baking_scheduling = struct + include Internal_event.Simple + + let section = [Protocol.name; "delegate"; "baking-scheduling"] + + let cannot_fetch_event = + declare_1 + ~section + ~level:Info + ~name:"cannot_fetch_event" + ~msg:"{worker}: can't fetch the current event; waiting for new event" + ("worker", Data_encoding.string) + + let daemon_error = + declare_2 + ~section + ~level:Error + ~name:"daemon_error" + ~msg:"{worker}: error while baking: {errors}" + ~pp2:pp_print_top_error_of_trace + ("worker", Data_encoding.string) + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let daemon_setup = + declare_1 + ~section + ~level:Info + ~name:"daemon_setup" + ~msg:"setting up before the {worker} can start" + ("worker", Data_encoding.string) + + let daemon_connection_lost = + declare_1 + ~section + ~level:Error + ~name:"daemon_connection_lost" + ~msg:"connection to node lost, {worker} exiting" + ("worker", Data_encoding.string) + + let daemon_wakeup = + declare_1 + ~section + ~level:Debug + ~name:"daemon_wakeup" + ~msg:"waking up for {worker}" + ("worker", Data_encoding.string) + + let daemon_start = + declare_1 + ~section + ~level:Info + ~name:"daemon_start" + ~msg:"starting {worker} daemon" + ("worker", Data_encoding.string) +end + +module Baking_forge = struct + include Internal_event.Simple + + let section = [Protocol.name; "delegate"; "baking_forge"] + + let double_bake_near_miss = + declare_1 + ~section + ~level:Error + ~name:"double_bake_near_miss" + ~msg:"level {level}: previously baked" + ("level", Alpha_context.Raw_level.encoding) + + let inject_baked_block = + declare_3 + ~section + ~level:Info + ~name:"inject_baked_block" + ~msg:"Client_baking_forge.inject_block: inject {hash}" + ("hash", Block_hash.encoding) + ~pp2:pp_ignore + ("header", Data_encoding.bytes) + ~pp3:Format.(pp_print_list @@ pp_print_list @@ Operation.pp) + ( "operations", + Data_encoding.(list @@ list @@ dynamic_size Operation.encoding) ) + + let baking_local_validation_start = + declare_1 + ~section + ~level:Debug + ~name:"baking_local_validation_start" + ~msg:"starting client-side validation after {hash}" + ("hash", Block_hash.encoding) + + let context_fetch_error = + declare_1 + ~section + ~level:Error + ~name:"context_fetch_error" + ~msg:"error while fetching current context: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let reopen_context = + declare_0 + ~section + ~level + ~name:"reopen_context" + ~msg:"retrying to open the context" + () + + let baking_rejected_invalid_operation = + declare_2 + ~section + ~level:Debug + ~name:"baking_rejected_invalid_operation" + ~msg:"client-side validation: filtered invalid operation {hash} {errors}" + ~pp2:pp_print_top_error_of_trace + ("hash", Operation_hash.encoding) + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let shell_prevalidation_notice = + declare_0 + ~section + ~level + ~name:"shell_prevalidation_notice" + ~msg:"building a block using shell validation" + () + + let shell_prevalidation_new_protocol = + declare_0 + ~section + ~level + ~name:"shell_prevalidation_new_protocol" + ~msg:"new protocol detected: using shell validation" + () + + let found_valid_operations = + declare_4 + ~section + ~level + ~name:"found_valid_operations" + ~msg: + "found {valid_count} valid operations ({refused_count} refused) for \ + timestamp {timestamp} (fitness {fitness})" + ~pp4:Fitness.pp + ("valid_count", Data_encoding.int31) + ("refused_count", Data_encoding.int31) + ("timestamp", Time.System.encoding) + ("fitness", Fitness.encoding) + + let block_conversion_failed = + declare_1 + ~section + ~level:Error + ~name:"block_conversion_failed" + ~msg:"error on raw_level conversion: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let block_injection_failed = + declare_2 + ~section + ~level:Error + ~name:"block_injection_failed" + ~msg: + "error while injecting block; included operations: {operations}; \ + errors: {errors}" + ~pp1:(Format.pp_print_list Operation.pp) + ~pp2:pp_print_top_error_of_trace + ("operations", Data_encoding.(list @@ dynamic_size Operation.encoding)) + ("errors", Error_monad.trace_encoding) + + let built_invalid_block_error = + declare_1 + ~section + ~level:Error + ~name:"built_invalid_block_error" + ~msg: + "shell-side validation: error while prevalidating operations: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let try_baking = + declare_4 + ~section + ~level:Debug + ~name:"try_baking" + ~msg: + "try baking after {hash} (slot {priority}) for {client} ({timestamp})" + ("hash", Block_hash.encoding) + ("priority", Data_encoding.int31) + ("client", Data_encoding.string) + ("timestamp", Time.System.encoding) + + let new_head_received = + declare_0 + ~section + ~level + ~name:"new_head_received" + ~msg: + "received a new head while waiting for operations; aborting this block" + () + + let client_side_validation_error = + declare_1 + ~section + ~level:Error + ~name:"client_side_validation_error" + ~msg: + "client-side validation: error while filtering invalid operations: \ + {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let waiting_before_injection = + declare_2 + ~section + ~level + ~name:"waiting_before_injection" + ~msg: + "[{current_timestamp}] not ready to inject yet, waiting until \ + {valid_timestamp}" + ("current_timestamp", Time.System.encoding) + ("valid_timestamp", Time.System.encoding) + + let try_forging = + declare_4 + ~section + ~level:Debug + ~name:"try_forging" + ~msg: + "try forging locally the block header for {hash} (slot {priority}) for \ + {client} ({timestamp})" + ("hash", Block_hash.encoding) + ("priority", Data_encoding.int31) + ("client", Data_encoding.string) + ("timestamp", Time.System.encoding) + + let start_injecting_block = + declare_5 + ~section + ~level:Info + ~name:"start_injecting_block" + ~msg: + "injecting block (priority {priority}, fitness {fitness}) for {client} \ + after {predecessor}" + ~pp2:Fitness.pp + ("priority", Data_encoding.int31) + ("fitness", Fitness.encoding) + ("client", Data_encoding.string) + ("predecessor", Block_hash.encoding) + ("baker", Client_keys.Public_key_hash.encoding) + + let injected_block = + declare_7 + ~section + ~level + ~name:"injected_block" + ~msg: + "injected block {block_hash} for {client} after {predecessor} (level \ + {level}, priority {priority}, fitness {fitness}, operations \ + {operations})" + ~pp6:Fitness.pp + ~pp7:Format.(pp_print_list Operation.pp) + ("block_hash", Block_hash.encoding) + ("client", Data_encoding.string) + ("predecessor", Block_hash.encoding) + ("level", Alpha_context.Raw_level.encoding) + ("priority", Data_encoding.int31) + ("fitness", Fitness.encoding) + ("operations", Data_encoding.(list @@ dynamic_size Operation.encoding)) + + let baking_slot_fetch_errors = + declare_1 + ~section + ~level:Error + ~name:"baking_slot_fetch_errors" + ~msg:"error while fetching baking possibilities: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let no_slot_found = + declare_2 + ~section + ~level + ~name:"no_slot_found" + ~msg:"no slot found at level {level} (max_priority = {priority})" + ("level", Alpha_context.Raw_level.encoding) + ("priority", Data_encoding.int31) + + let have_baking_slot = + declare_6 + ~section + ~level + ~name:"have_baking_slot" + ~msg: + "new baking slot found (level {level}, priority {priority}) at \ + {timestamp} for {client} after {predecessor}" + ("level", Alpha_context.Raw_level.encoding) + ("priority", Data_encoding.int31) + ("timestamp", Time.System.encoding) + ("client", Data_encoding.string) + ("predecessor", Block_hash.encoding) + ("baker", Client_keys.Public_key_hash.encoding) + + let read_nonce_fail = + declare_1 + ~section + ~level:Error + ~name:"read_nonce_fail" + ~msg:"cannot read nonces: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let nonce_retrieval_fail = + declare_1 + ~section + ~level:Error + ~name:"nonce_retrieval_fail" + ~msg:"cannot retrieve unrevealed nonces: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let nonce_injection_fail = + declare_1 + ~section + ~level:Error + ~name:"nonce_injection_fail" + ~msg:"cannot inject nonces: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let retrying_on_error = + declare_1 + ~section + ~level:Error + ~name:"retrying_on_error" + ~msg:"retrying after baking error {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let endorsement_received = + declare_2 + ~section + ~level:Info + ~name:"endorsement_received" + ~msg:"received endorsement for slot {slot} (power: {power})" + ~pp1:Format.pp_print_int + ("slot", Data_encoding.int31) + ~pp2:Format.pp_print_int + ("power", Data_encoding.int31) + + let expected_validity_time = + declare_2 + ~section + ~name:"expected_validity_time" + ~level:Info + ~msg:"expected validity time: {time} (endorsing power: {power})" + ~pp1:Alpha_context.Timestamp.pp + ("time", Alpha_context.Timestamp.encoding) + ~pp2:Format.pp_print_int + ("power", Data_encoding.int31) + + let reading_per_block = + declare_1 + ~section + ~name:"reading_per_block" + ~level:Notice + ~msg:"reading per block vote file path: {path}" + ("path", Data_encoding.string) + + let per_block_vote_file_notice = + declare_1 + ~section + ~name:"per_block_vote_file_notice" + ~level:Notice + ~msg:"per block vote file {event}" + ("event", Data_encoding.string) + + let reading_liquidity_baking = + declare_0 + ~section + ~name:"reading_liquidity_baking" + ~level:Notice + ~msg:"reading liquidity baking escape vote" + () + + let liquidity_baking_escape_vote = + declare_1 + ~section + ~name:"liquidity_baking_escape_vote" + ~level:Notice + ~msg:"liquidity baking escape vote = {value}" + ("value", Data_encoding.bool) + + let per_block_vote_file_fail = + declare_1 + ~section + ~name:"per_block_vote_file_error" + ~level:Notice + ~msg:"Error reading the block vote file: {errors}" + ~pp1:pp_print_top_error_of_trace + ("errors", Error_monad.(TzTrace.encoding error_encoding)) + + let liquidity_baking_escape = + declare_0 + ~section + ~name:"liquidity_baking_continue" + ~level:Notice + ~msg:"Will vote to escape Liquidity Baking" + () + + let liquidity_baking_continue = + declare_0 + ~section + ~name:"liquidity_baking_escape" + ~level:Notice + ~msg:"Will vote to continue Liquidity Baking" + () +end + +module Endorsement = struct + include Internal_event.Simple + + let section = [Protocol.name; "delegate"; "endorsement"] + + let double_endorsement_near_miss = + declare_1 + ~section + ~level:Error + ~name:"double_endorsement_near_miss" + ~msg:"level {level}: previously endorsed" + ("level", Alpha_context.Raw_level.encoding) + + let injected_endorsement = + declare_5 + ~section + ~level + ~name:"injected_endorsement" + ~msg: + "injected endorsement for block '{block_hash}' (level {level}, \ + contract {client}) '{op_hash}'" + ("block_hash", Block_hash.encoding) + ("level", Alpha_context.Raw_level.encoding) + ("client", Data_encoding.string) + ("op_hash", Operation_hash.encoding) + ("baker", Client_keys.Public_key_hash.encoding) + + let endorsing = + declare_3 + ~section + ~level:Debug + ~name:"endorsing" + ~msg:"endorsing {block} for {client} (level {level})!" + ("block", Block_hash.encoding) + ("client", Data_encoding.string) + ("level", Alpha_context.Raw_level.encoding) + + let check_endorsement_ok = + declare_2 + ~section + ~level:Debug + ~name:"check_endorsement_ok" + ~msg:"checking if allowed to endorse block {block} for {client}" + ("block", Block_hash.encoding) + ("client", Data_encoding.string) + + let endorsement_no_slots_found = + declare_2 + ~section + ~level:Debug + ~name:"endorsement_no_slots_found" + ~msg:"no slot found for {block}/{client}" + ("block", Block_hash.encoding) + ("client", Data_encoding.string) + + let endorsement_slots_found = + declare_3 + ~section + ~level:Debug + ~name:"endorsement_slots_found" + ~msg:"found slots for {block}/{client} ({slots})" + ~pp3: + Format.( + fun fmt -> + fprintf + fmt + "[%a]" + (pp_print_list + ~pp_sep:(fun f () -> pp_print_string f "; ") + Format.pp_print_int)) + ("block", Block_hash.encoding) + ("client", Data_encoding.string) + ("slots", Data_encoding.list Data_encoding.int31) + + let previously_endorsed = + declare_1 + ~section + ~level:Debug + ~name:"previously_endorsed" + ~msg:"level {level} (or higher) previously endorsed: do not endorse" + ("level", Alpha_context.Raw_level.encoding) + + let endorsement_stale_block = + declare_1 + ~section + ~level:Info + ~name:"endorsement_stale_block" + ~msg:"ignore block {block}: forged too far the past" + ("block", Block_hash.encoding) + + let endorsement_got_block = + declare_1 + ~section + ~level:Info + ~name:"endorsement_got_block" + ~msg:"received new block {block}" + ("block", Block_hash.encoding) + + let wait_before_injecting = + declare_2 + ~section + ~level:Info + ~name:"wait_before_injecting" + ~msg:"waiting until {timestamp} ({timespan}) to inject endorsements" + ("timestamp", Time.System.encoding) + ("timespan", Time.System.Span.encoding) + + let error_while_endorsing = + declare_2 + ~section + ~level:Error + ~name:"error_while_endorsing" + ~msg:"error while injecting endorsement for baker {baker}: {errors}" + ~pp2:pp_print_top_error_of_trace + ("baker", Client_keys.Public_key_hash.encoding) + ("errors", Error_monad.(TzTrace.encoding error_encoding)) +end diff --git a/src/proto_012_PsiThaCa/lib_delegate/dune b/src/proto_012_PsiThaCa/lib_delegate/dune new file mode 100644 index 000000000000..17664ec3147f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/dune @@ -0,0 +1,89 @@ +(library + (name tezos_baking_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-baking-012-PsiThaCa) + (libraries tezos-base + tezos-version + tezos-protocol-012-PsiThaCa + tezos-protocol-environment + tezos-shell-context + tezos-shell-services + tezos-client-base + tezos-client-012-PsiThaCa + tezos-client-commands + tezos-stdlib + tezos-stdlib-unix + tezos-context + tezos-context.memory + tezos-rpc-http + tezos-rpc-http-client-unix + tezos-rpc + lwt-canceler + lwt-exit) + (library_flags (:standard -linkall)) + (modules (:standard \ + baking_commands + baking_commands_registration)) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -open Tezos_protocol_plugin_012_PsiThaCa + -open Tezos_shell_services + -open Tezos_client_base + -open Tezos_client_012_PsiThaCa + -open Tezos_client_commands + -open Tezos_stdlib + -open Tezos_stdlib_unix + -open Tezos_shell_context + -open Tezos_context + -open Tezos_rpc + -open Tezos_rpc_http))) + +(library + (name tezos_baking_012_PsiThaCa_commands) + (instrumentation (backend bisect_ppx)) + (public_name tezos-baking-012-PsiThaCa-commands) + (libraries tezos-base + tezos-protocol-012-PsiThaCa + tezos-protocol-environment + tezos-shell-services + tezos-client-base + tezos-client-012-PsiThaCa + tezos-client-commands + tezos-baking-012-PsiThaCa) + (library_flags (:standard -linkall)) + (modules baking_commands) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -open Tezos_stdlib_unix + -open Tezos_shell_services + -open Tezos_client_base + -open Tezos_client_012_PsiThaCa + -open Tezos_client_commands + -open Tezos_baking_012_PsiThaCa + -open Tezos_rpc))) + +(library + (name tezos_baking_012_PsiThaCa_commands_registration) + (instrumentation (backend bisect_ppx)) + (public_name tezos-baking-012-PsiThaCa-commands.registration) + (libraries tezos-base + tezos-protocol-012-PsiThaCa + tezos-protocol-environment + tezos-shell-services + tezos-client-base + tezos-client-012-PsiThaCa + tezos-client-commands + tezos-baking-012-PsiThaCa + tezos-baking-012-PsiThaCa-commands + tezos-rpc) + (library_flags (:standard -linkall)) + (modules baking_commands_registration) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -open Tezos_shell_services + -open Tezos_client_base + -open Tezos_client_012_PsiThaCa + -open Tezos_client_commands + -open Tezos_baking_012_PsiThaCa + -open Tezos_baking_012_PsiThaCa_commands + -open Tezos_rpc))) diff --git a/src/proto_012_PsiThaCa/lib_delegate/dune-project b/src/proto_012_PsiThaCa/lib_delegate/dune-project new file mode 100644 index 000000000000..d6286ff1f0d3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-accuser-alpha-commands) diff --git a/src/proto_012_PsiThaCa/lib_delegate/liquidity_baking_vote_file.ml b/src/proto_012_PsiThaCa/lib_delegate/liquidity_baking_vote_file.ml new file mode 100644 index 000000000000..57bc0ce5a187 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/liquidity_baking_vote_file.ml @@ -0,0 +1,162 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol_client_context +module Events = Baking_events.Liquidity_baking + +type per_block_votes = {liquidity_baking_escape_vote : bool option} + +let per_block_votes_encoding = + let open Data_encoding in + def "per_block_votes.alpha" + @@ conv + (fun {liquidity_baking_escape_vote} -> liquidity_baking_escape_vote) + (fun liquidity_baking_escape_vote -> {liquidity_baking_escape_vote}) + (obj1 (opt "liquidity_baking_escape_vote" Data_encoding.bool)) + +type error += Block_vote_file_not_found of string + +type error += Block_vote_file_invalid of string + +type error += Block_vote_file_wrong_content of string + +type error += Block_vote_file_missing_liquidity_baking_escape_vote of string + +let () = + register_error_kind + `Permanent + ~id:"Client_baking_forge.block_vote_file_not_found" + ~title: + "The provided block vote file path does not point to an existing file." + ~description: + "A block vote file path was provided on the command line but the path \ + does not point to an existing file." + ~pp:(fun ppf file_path -> + Format.fprintf + ppf + "@[The provided block vote file path \"%s\" does not point to an \ + existing file.@]" + file_path) + Data_encoding.(obj1 (req "file_path" string)) + (function + | Block_vote_file_not_found file_path -> Some file_path | _ -> None) + (fun file_path -> Block_vote_file_not_found file_path) ; + register_error_kind + `Permanent + ~id:"Client_baking_forge.block_vote_file_invalid" + ~title: + "The provided block vote file path does not point to a valid JSON file." + ~description: + "A block vote file path was provided on the command line but the path \ + does not point to a valid JSON file." + ~pp:(fun ppf file_path -> + Format.fprintf + ppf + "@[The provided block vote file path \"%s\" does not point to a valid \ + JSON file. The file exists but its content is not valid JSON.@]" + file_path) + Data_encoding.(obj1 (req "file_path" string)) + (function Block_vote_file_invalid file_path -> Some file_path | _ -> None) + (fun file_path -> Block_vote_file_invalid file_path) ; + register_error_kind + `Permanent + ~id:"Client_baking_forge.block_vote_file_wrong_content" + ~title:"The content of the provided block vote file is unexpected." + ~description: + "The block vote file is valid JSON but its content is not the expected \ + one." + ~pp:(fun ppf file_path -> + Format.fprintf + ppf + "@[The provided block vote file \"%s\" is a valid JSON file but its \ + content is unexpected. Expecting a JSON file containing either \ + '{\"liquidity_baking_escape_vote\": true}' or \ + '{\"liquidity_baking_escape_vote\": false}'.@]" + file_path) + Data_encoding.(obj1 (req "file_path" string)) + (function + | Block_vote_file_wrong_content file_path -> Some file_path | _ -> None) + (fun file_path -> Block_vote_file_wrong_content file_path) ; + register_error_kind + `Permanent + ~id: + "Client_baking_forge.block_vote_file_missing_liquidity_baking_escape_vote" + ~title: + "In the provided block vote file, no entry for liquidity baking escape \ + vote was found" + ~description: + "In the provided block vote file, no entry for liquidity baking escape \ + vote was found." + ~pp:(fun ppf file_path -> + Format.fprintf + ppf + "@[In the provided block vote file \"%s\", the \ + \"liquidity_baking_escape_vote\" boolean field is missing. Expecting \ + a JSON file containing either '{\"liquidity_baking_escape_vote\": \ + true}' or '{\"liquidity_baking_escape_vote\": false}'.@]" + file_path) + Data_encoding.(obj1 (req "file_path" string)) + (function + | Block_vote_file_missing_liquidity_baking_escape_vote file_path -> + Some file_path + | _ -> None) + (fun file_path -> + Block_vote_file_missing_liquidity_baking_escape_vote file_path) + +let traced_option_to_result ~error = + Option.fold ~some:ok ~none:(Error_monad.error error) + +let check_file_exists file = + if Sys.file_exists file then Result.return_unit + else error (Block_vote_file_not_found file) + +let read_liquidity_baking_escape_vote ~per_block_vote_file = + Events.(emit reading_per_block) per_block_vote_file >>= fun () -> + check_file_exists per_block_vote_file >>?= fun () -> + trace (Block_vote_file_invalid per_block_vote_file) + @@ Lwt_utils_unix.Json.read_file per_block_vote_file + >>=? fun votes_json -> + Events.(emit per_block_vote_file_notice) "found" >>= fun () -> + trace (Block_vote_file_wrong_content per_block_vote_file) + @@ Error_monad.protect (fun () -> + return + @@ Data_encoding.Json.destruct per_block_votes_encoding votes_json) + >>=? fun votes -> + Events.(emit per_block_vote_file_notice) "JSON decoded" >>= fun () -> + traced_option_to_result + ~error: + (Block_vote_file_missing_liquidity_baking_escape_vote per_block_vote_file) + votes.liquidity_baking_escape_vote + >>?= fun liquidity_baking_escape_vote -> + Events.(emit reading_liquidity_baking) () >>= fun () -> + Events.(emit liquidity_baking_escape_vote) liquidity_baking_escape_vote + >>= fun () -> return liquidity_baking_escape_vote + +let read_liquidity_baking_escape_vote_no_fail ~default ~per_block_vote_file = + read_liquidity_baking_escape_vote ~per_block_vote_file >>= function + | Ok vote -> Lwt.return vote + | Error errs -> + Events.(emit per_block_vote_file_fail) errs >>= fun () -> + Lwt.return default diff --git a/src/proto_012_PsiThaCa/lib_delegate/logging.ml b/src/proto_012_PsiThaCa/lib_delegate/logging.ml new file mode 100644 index 000000000000..ed9cb18c9db3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/logging.ml @@ -0,0 +1,167 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +let timestamp_tag = + Tag.def ~doc:"Timestamp when event occurred" "timestamp" Time.System.pp_hum + +let valid_ops = Tag.def ~doc:"Valid Operations" "valid_ops" Format.pp_print_int + +let op_count = + Tag.def ~doc:"Number of operations" "op_count" Format.pp_print_int + +let refused_ops = + Tag.def ~doc:"Refused Operations" "refused_ops" Format.pp_print_int + +let bake_priority_tag = + Tag.def ~doc:"Baking priority" "bake_priority" Format.pp_print_int + +let fitness_tag = Tag.def ~doc:"Fitness" "fitness" Fitness.pp + +let current_slots_tag = + Tag.def + ~doc:"Number of baking slots that can be baked at this time" + "current_slots" + Format.pp_print_int + +let future_slots_tag = + Tag.def + ~doc:"Number of baking slots in the foreseeable future but not yet bakeable" + "future_slots" + Format.pp_print_int + +let timespan_tag = Tag.def ~doc:"Timespan in seconds" "timespan" Ptime.Span.pp + +let filename_tag = Tag.def ~doc:"Filename" "filename" Format.pp_print_text + +let signed_header_tag = + Tag.def ~doc:"Signed header" "signed_header" (fun fmt x -> + Hex.pp fmt (Hex.of_bytes x)) + +let signed_operation_tag = + Tag.def ~doc:"Signed operation" "signed_operation" (fun fmt x -> + Hex.pp fmt (Hex.of_bytes x)) + +let operations_tag = + Tag.def + ~doc:"Block Operations" + "operations" + (Format.pp_print_list + ~pp_sep:(fun ppf () -> Format.fprintf ppf "+") + (fun ppf operations -> Format.fprintf ppf "%d" (List.length operations))) + +let raw_operations_tag = + Tag.def ~doc:"Raw operations" "raw_operations" (fun fmt raw_ops -> + let pp_op fmt op = + let json = Data_encoding.Json.construct Operation.raw_encoding op in + Format.fprintf fmt "%a" Data_encoding.Json.pp json + in + Format.fprintf + fmt + "@[%a@]" + (Format.pp_print_list ~pp_sep:Format.pp_print_cut pp_op) + raw_ops) + +let bake_op_count_tag = + Tag.def ~doc:"Bake Operation Count" "operation_count" Format.pp_print_int + +let endorsement_slot_tag = + Tag.def ~doc:"Endorsement Slot" "endorsement_slot" Format.pp_print_int + +let endorsement_slots_tag = + Tag.def + ~doc:"Endorsement Slots" + "endorsement_slots" + Format.(fun ppf v -> pp_print_int ppf (List.length v)) + +let denounced_endorsements_slots_tag = + Tag.def + ~doc:"Endorsement Slots" + "denounced_endorsement_slots" + Format.(pp_print_list pp_print_int) + +let denouncement_source_tag = + Tag.def ~doc:"Denounce Source" "source" Format.pp_print_text + +let level_tag = Tag.def ~doc:"Level" "level" Raw_level.pp + +let nonce_tag = + Tag.def + ~doc:"Nonce" + "nonce" + Data_encoding.Json.( + fun ppf nonce -> pp ppf (construct Nonce.encoding nonce)) + +let chain_tag = + Tag.def + ~doc:"Chain selector" + "chain" + Format.( + fun ppf chain -> + pp_print_string ppf @@ Block_services.chain_to_string chain) + +let block_tag = + Tag.def + ~doc:"Block selector" + "block" + Format.( + fun ppf block -> pp_print_string ppf @@ Block_services.to_string block) + +let worker_tag = + Tag.def ~doc:"Worker in which event occurred" "worker" Format.pp_print_text + +let block_header_tag = + Tag.def ~doc:"Raw block header" "block_header" (fun ppf _ -> + Format.fprintf ppf "[raw block header]") + +let conflicting_endorsements_tag = + Tag.def + ~doc:"Two conflicting endorsements signed by the same key" + "conflicting_endorsements" + Format.( + fun ppf (a, b) -> + fprintf + ppf + "%a / %a" + Operation_hash.pp + (Operation.hash a) + Operation_hash.pp + (Operation.hash b)) + +let conflicting_preendorsements_tag = + Tag.def + ~doc:"Two conflicting preendorsements signed by the same key" + "conflicting_preendorsements" + Format.( + fun ppf (a, b) -> + fprintf + ppf + "%a / %a" + Operation_hash.pp + (Operation.hash a) + Operation_hash.pp + (Operation.hash b)) diff --git a/src/proto_012_PsiThaCa/lib_delegate/logging.mli b/src/proto_012_PsiThaCa/lib_delegate/logging.mli new file mode 100644 index 000000000000..5e10680ae612 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/logging.mli @@ -0,0 +1,83 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +val timestamp_tag : Time.System.t Tag.def + +val valid_ops : int Tag.def + +val op_count : int Tag.def + +val refused_ops : int Tag.def + +val bake_priority_tag : int Tag.def + +val fitness_tag : Fitness.t Tag.def + +val current_slots_tag : int Tag.def + +val future_slots_tag : int Tag.def + +val timespan_tag : Time.System.Span.t Tag.def + +val filename_tag : string Tag.def + +val signed_header_tag : Bytes.t Tag.def + +val signed_operation_tag : Bytes.t Tag.def + +val operations_tag : Tezos_base.Operation.t list list Tag.def + +val raw_operations_tag : Operation.raw list Tag.def + +val bake_op_count_tag : int Tag.def + +val endorsement_slot_tag : int Tag.def + +val endorsement_slots_tag : int list Tag.def + +val denounced_endorsements_slots_tag : int list Tag.def + +val denouncement_source_tag : string Tag.def + +val level_tag : Raw_level.t Tag.def + +val nonce_tag : Nonce.t Tag.def + +val chain_tag : Block_services.chain Tag.def + +val block_tag : Block_services.block Tag.def + +val worker_tag : string Tag.def + +val block_header_tag : Block_header.t Tag.def + +val conflicting_endorsements_tag : + (Kind.endorsement operation * Kind.endorsement operation) Tag.def + +val conflicting_preendorsements_tag : + (Kind.preendorsement operation * Kind.preendorsement operation) Tag.def diff --git a/src/proto_012_PsiThaCa/lib_delegate/node_rpc.ml b/src/proto_012_PsiThaCa/lib_delegate/node_rpc.ml new file mode 100644 index 000000000000..cc250824a6ec --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/node_rpc.ml @@ -0,0 +1,200 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +module Block_services = Block_services.Make (Protocol) (Protocol) +module Events = Baking_events.Node_rpc + +let inject_block cctxt ?(force = false) ~chain signed_block_header operations = + let signed_shell_header_bytes = + Data_encoding.Binary.to_bytes_exn Block_header.encoding signed_block_header + in + Shell_services.Injection.block + cctxt + ~chain + ~force + signed_shell_header_bytes + operations + +let preapply_block cctxt ~chain ~head ~timestamp ~protocol_data operations = + Block_services.Helpers.Preapply.block + cctxt + ~chain + ~timestamp + ~block:(`Hash (head, 0)) + operations + ~protocol_data + +let extract_prequorum preendorsements = + match preendorsements with + | h :: _ as l -> + let ({protocol_data = {contents = Single (Preendorsement content); _}; _}) + = + (h : Kind.preendorsement Operation.t) + in + Some + { + Baking_state.level = Raw_level.to_int32 content.level; + round = content.round; + block_payload_hash = content.block_payload_hash; + preendorsements = l; + } + | _ -> None + +let raw_info cctxt ~chain ~block_hash shell payload_hash payload_round + current_protocol next_protocol live_blocks = + Events.(emit raw_info (block_hash, shell.Tezos_base.Block_header.level)) + >>= fun () -> + let open Protocol_client_context in + let block = `Hash (block_hash, 0) in + let is_in_protocol = Protocol_hash.(current_protocol = Protocol.hash) in + (if is_in_protocol then + Alpha_block_services.Operations.operations cctxt ~chain ~block () + >>=? fun operations -> + let operations = + List.map + (fun l -> + List.map + (fun {Alpha_block_services.shell; protocol_data; _} -> + {Alpha_context.shell; protocol_data}) + l) + operations + in + match Operation_pool.extract_operations_of_list_list operations with + | None -> failwith "Unexpected operation list size" + | Some operations -> return operations + else + (* If we are not in the current protocol, do no consider operations *) + return (None, [], Operation_pool.empty_payload)) + >>=? fun (preendorsements, quorum, payload) -> + (if is_in_protocol then Baking_state.round_of_shell_header shell + else (* If we are not in the current protocol, the round is 0 *) + ok Round.zero) + >>?= fun round -> + let prequorum = + Option.fold ~none:None ~some:extract_prequorum preendorsements + in + return + { + Baking_state.hash = block_hash; + shell; + payload_hash; + payload_round; + round; + protocol = current_protocol; + next_protocol; + prequorum; + quorum; + payload; + live_blocks; + } + +let dummy_payload_hash = Block_payload_hash.zero + +let info cctxt ~chain ~block () = + let open Protocol_client_context in + (* Fails if the block's protocol is not the current one *) + Shell_services.Blocks.protocols cctxt ~chain ~block () + >>=? fun {current_protocol; next_protocol} -> + (if Protocol_hash.(current_protocol <> Protocol.hash) then + Block_services.Header.shell_header cctxt ~chain ~block () >>=? fun shell -> + Chain_services.Blocks.Header.raw_protocol_data cctxt ~chain ~block () + >>=? fun protocol_data -> + let hash = + Tezos_base.Block_header.hash {Tezos_base.Block_header.shell; protocol_data} + in + let payload_hash = + (* If the protocol is not the same, then we won't need to use + the payload_hash *) + dummy_payload_hash + in + return (hash, shell, payload_hash, Round.zero) + else + Alpha_block_services.header cctxt ~chain ~block () + >>=? fun {hash; shell; protocol_data; _} -> + return + ( hash, + shell, + protocol_data.contents.payload_hash, + protocol_data.contents.payload_round )) + >>=? fun (hash, shell, payload_hash, payload_round) -> + (Chain_services.Blocks.live_blocks cctxt ~chain ~block () >>= function + | Error _ -> + (* The RPC might fail when a block's metadata is not available *) + Lwt.return Block_hash.Set.empty + | Ok live_blocks -> Lwt.return live_blocks) + >>= fun live_blocks -> + raw_info + cctxt + ~chain + ~block_hash:hash + shell + payload_hash + payload_round + current_protocol + next_protocol + live_blocks + +let find_in_cache_or_fetch cctxt ?cache ~chain block_hash = + let open Baking_cache in + let fetch () = info cctxt ~chain ~block:(`Hash (block_hash, 0)) () in + match cache with + | None -> fetch () + | Some block_cache -> ( + match Block_cache.find_opt block_cache block_hash with + | Some block_info -> return block_info + | None -> + fetch () >>=? fun block_info -> + Block_cache.replace block_cache block_hash block_info ; + return block_info) + +let proposal cctxt ?cache ~chain block_hash = + find_in_cache_or_fetch cctxt ~chain ?cache block_hash >>=? fun block -> + let predecessor_hash = block.shell.predecessor in + find_in_cache_or_fetch cctxt ~chain ?cache predecessor_hash + >>=? fun predecessor -> return {Baking_state.block; predecessor} + +let monitor_proposals cctxt ~chain () = + let cache = Baking_cache.Block_cache.create 100 in + Monitor_services.heads cctxt ~next_protocols:[Protocol.hash] chain + >>=? fun (block_stream, stopper) -> + return + ( Lwt_stream.filter_map_s + (fun (block_hash, _) -> + protect (fun () -> proposal cctxt ~cache ~chain block_hash) + >>= function + | Ok proposal -> Lwt.return_some proposal + | Error err -> + Events.(emit error_while_monitoring_heads err) >>= fun () -> + Lwt.return_none) + block_stream, + stopper ) + +let await_protocol_activation cctxt ~chain () = + Monitor_services.heads cctxt ~next_protocols:[Protocol.hash] chain + >>=? fun (_block_stream, stop) -> + stop () ; + return_unit diff --git a/src/proto_012_PsiThaCa/lib_delegate/node_rpc.mli b/src/proto_012_PsiThaCa/lib_delegate/node_rpc.mli new file mode 100644 index 000000000000..1c4b0f493a82 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/node_rpc.mli @@ -0,0 +1,76 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** Inject a block. + + @param force defaults to [false] + @return block hash of the newly injected block +*) +val inject_block : + #Protocol_client_context.full -> + ?force:bool -> + chain:Shell_services.chain -> + Block_header.t -> + Tezos_base.Operation.t list list -> + Block_hash.t tzresult Lwt.t + +(** Preapply a block using the node validation mechanism.*) +val preapply_block : + #Protocol_client_context.full -> + chain:Shell_services.chain -> + head:Block_hash.t -> + timestamp:Time.Protocol.t -> + protocol_data:Protocol.block_header_data -> + packed_operation list list -> + (Tezos_base.Block_header.shell_header * error Preapply_result.t list) tzresult + Lwt.t + +(** Fetch a proposal from the node. + + @param cache is unset by default +*) +val proposal : + #RPC_context.simple -> + ?cache:Baking_state.block_info Baking_cache.Block_cache.t -> + chain:Shell_services.chain -> + Block_hash.t -> + Baking_state.proposal tzresult Lwt.t + +(** Monitor proposals from the node.*) +val monitor_proposals : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + unit -> + (Baking_state.proposal Lwt_stream.t * (unit -> unit)) tzresult Lwt.t + +(** Await the current protocol to be activated. *) +val await_protocol_activation : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + unit -> + unit tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/operation_pool.ml b/src/proto_012_PsiThaCa/lib_delegate/operation_pool.ml new file mode 100644 index 000000000000..e680d7328aa6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/operation_pool.ml @@ -0,0 +1,327 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(* Should we use a better ordering ? *) + +module OpSet = Set.Make (struct + type t = packed_operation + + let compare = compare +end) + +(* TODO refine this: unpack operations *) +type pool = { + consensus : OpSet.t; + votes : OpSet.t; + anonymous : OpSet.t; + managers : OpSet.t; +} + +(* TODO refine this: unpack operations *) +type ordered_pool = { + ordered_consensus : packed_operation list; + ordered_votes : packed_operation list; + ordered_anonymous : packed_operation list; + ordered_managers : packed_operation list; +} + +let ordered_pool_encoding = + let open Data_encoding in + conv + (fun {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers} -> + (ordered_consensus, ordered_votes, ordered_anonymous, ordered_managers)) + (fun (ordered_consensus, ordered_votes, ordered_anonymous, ordered_managers) -> + {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers}) + (obj4 + (req "ordered_consensus" (list (dynamic_size Operation.encoding))) + (req "ordered_votes" (list (dynamic_size Operation.encoding))) + (req "ordered_payload" (list (dynamic_size Operation.encoding))) + (req "ordered_payload" (list (dynamic_size Operation.encoding)))) + +type payload = { + votes_payload : packed_operation list; + anonymous_payload : packed_operation list; + managers_payload : packed_operation list; +} + +let empty_payload = + {votes_payload = []; anonymous_payload = []; managers_payload = []} + +let payload_encoding = + let open Data_encoding in + conv + (fun {votes_payload; anonymous_payload; managers_payload} -> + (votes_payload, anonymous_payload, managers_payload)) + (fun (votes_payload, anonymous_payload, managers_payload) -> + {votes_payload; anonymous_payload; managers_payload}) + (obj3 + (req "votes_payload" (list (dynamic_size Operation.encoding))) + (req "anonymous_payload" (list (dynamic_size Operation.encoding))) + (req "managers_payload" (list (dynamic_size Operation.encoding)))) + +let pp_payload fmt {votes_payload; anonymous_payload; managers_payload} = + Format.fprintf + fmt + "[votes: %d, anonymous: %d, managers: %d]" + (List.length votes_payload) + (List.length anonymous_payload) + (List.length managers_payload) + +let empty = + { + consensus = OpSet.empty; + votes = OpSet.empty; + anonymous = OpSet.empty; + managers = OpSet.empty; + } + +let empty_ordered = + { + ordered_consensus = []; + ordered_votes = []; + ordered_anonymous = []; + ordered_managers = []; + } + +let pp_pool fmt {consensus; votes; anonymous; managers} = + Format.fprintf + fmt + "[consensus: %d, votes: %d, anonymous: %d, managers: %d]" + (OpSet.cardinal consensus) + (OpSet.cardinal votes) + (OpSet.cardinal anonymous) + (OpSet.cardinal managers) + +let pp_ordered_pool fmt + {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers} = + Format.fprintf + fmt + "[consensus: %d, votes: %d, anonymous: %d, managers: %d]" + (List.length ordered_consensus) + (List.length ordered_votes) + (List.length ordered_anonymous) + (List.length ordered_managers) + +(* Hypothesis : we suppose [List.length Protocol.Main.validation_passes = 4] *) +let consensus_index = 0 + +let votes_index = 1 + +let anonymous_index = 2 + +let managers_index = 3 + +let classify op = + (* Hypothesis: acceptable passes returns a size at most 1 list *) + match Main.acceptable_passes op with + | [pass] -> + if pass = consensus_index then `Consensus + (* TODO filter outdated consensus ops ? *) + else if pass = votes_index then `Votes + else if pass = anonymous_index then `Anonymous + else if pass = managers_index then `Managers + else `Bad + | _ -> `Bad + +let add_operation pool op = + match classify op with + | `Consensus -> + let consensus = OpSet.add op pool.consensus in + {pool with consensus} + | `Votes -> + let votes = OpSet.add op pool.votes in + {pool with votes} + | `Anonymous -> + let anonymous = OpSet.add op pool.anonymous in + {pool with anonymous} + | `Managers -> + let managers = OpSet.add op pool.managers in + {pool with managers} + | `Bad -> pool + +let add_operations pool new_ops = List.fold_left add_operation pool new_ops + +type consensus_filter = { + level : int32; + round : Round.t; + payload_hash : Block_payload_hash.t; +} + +(** From a pool of operations [operation_pool], the function filters + out the endorsements that are different from the [current_level], + the [current_round] or the optional [current_block_payload_hash], + as well as preendorsements. *) +let filter_with_relevant_consensus_ops ~(endorsement_filter : consensus_filter) + ~(preendorsement_filter : consensus_filter option) operation_set = + OpSet.filter + (fun {protocol_data; _} -> + match (protocol_data, preendorsement_filter) with + (* 1a. Remove preendorsements. *) + | (Operation_data {contents = Single (Preendorsement _); _}, None) -> + false + (* 1b. Filter preendorsements. *) + | ( Operation_data + { + contents = + Single (Preendorsement {level; round; block_payload_hash; _}); + _; + }, + Some + {level = level'; round = round'; payload_hash = block_payload_hash'} + ) -> + Compare.Int32.(Raw_level.to_int32 level = level') + && Round.(round = round') + && Block_payload_hash.(block_payload_hash = block_payload_hash') + (* 2. Filter endorsements. *) + | ( Operation_data + { + contents = + Single (Endorsement {level; round; block_payload_hash; _}); + _; + }, + _ ) -> + Compare.Int32.(Raw_level.to_int32 level = endorsement_filter.level) + && Round.(round = endorsement_filter.round) + && Block_payload_hash.( + block_payload_hash = endorsement_filter.payload_hash) + (* 3. Preserve all non-consensus operations. *) + | _ -> true) + operation_set + +let unpack_preendorsement packed_preendorsement = + let {shell; protocol_data = Operation_data data} = packed_preendorsement in + match data with + | {contents = Single (Preendorsement _); _} -> + Some ({shell; protocol_data = data} : Kind.preendorsement Operation.t) + | _ -> None + +let unpack_endorsement packed_endorsement = + let {shell; protocol_data = Operation_data data} = packed_endorsement in + match data with + | {contents = Single (Endorsement _); _} -> + Some ({shell; protocol_data = data} : Kind.endorsement Operation.t) + | _ -> None + +let filter_preendorsements ops = + List.filter_map + (function + | { + shell = {branch}; + protocol_data = + Operation_data + ({contents = Single (Preendorsement _); _} as content); + _; + } -> + Some + ({shell = {branch}; protocol_data = content} + : Kind.preendorsement operation) + | _ -> None) + ops + +let filter_endorsements ops = + List.filter_map + (function + | { + shell = {branch}; + protocol_data = + Operation_data ({contents = Single (Endorsement _); _} as content); + _; + } -> + Some + ({shell = {branch}; protocol_data = content} + : Kind.endorsement operation) + | _ -> None) + ops + +let pool_to_list_list {consensus; votes; anonymous; managers} = + List.map OpSet.elements [consensus; votes; anonymous; managers] + +let pool_of_list_list (ll : packed_operation list list) = + List.fold_left add_operations empty ll + +let ordered_to_list_list + {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers} = + [ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers] + +let ordered_of_list_list = function + | [ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers] -> + Some + {ordered_consensus; ordered_votes; ordered_anonymous; ordered_managers} + | _ -> None + +let payload_of_ordered_pool + {ordered_votes; ordered_anonymous; ordered_managers; _} = + { + votes_payload = ordered_votes; + anonymous_payload = ordered_anonymous; + managers_payload = ordered_managers; + } + +let ordered_pool_of_payload ~consensus_operations + {votes_payload; anonymous_payload; managers_payload} = + { + ordered_consensus = consensus_operations; + ordered_votes = votes_payload; + ordered_anonymous = anonymous_payload; + ordered_managers = managers_payload; + } + +let extract_operations_of_list_list = function + | [consensus; votes_payload; anonymous_payload; managers_payload] -> + let (preendorsements, endorsements) = + List.fold_left + (fun ( (preendorsements : Kind.preendorsement Operation.t list), + (endorsements : Kind.endorsement Operation.t list) ) + packed_op -> + let {shell; protocol_data = Operation_data data} = packed_op in + match data with + | {contents = Single (Preendorsement _); _} -> + ({shell; protocol_data = data} :: preendorsements, endorsements) + | {contents = Single (Endorsement _); _} -> + (preendorsements, {shell; protocol_data = data} :: endorsements) + | _ -> + (* unreachable *) + (preendorsements, endorsements)) + ([], []) + consensus + (* N.b. the order doesn't matter *) + in + let preendorsements = + if preendorsements = [] then None else Some preendorsements + in + let payload = {votes_payload; anonymous_payload; managers_payload} in + Some (preendorsements, endorsements, payload) + | _ -> None + +let filter_pool p {consensus; votes; anonymous; managers} = + { + consensus = OpSet.filter p consensus; + votes = OpSet.filter p votes; + anonymous = OpSet.filter p anonymous; + managers = OpSet.filter p managers; + } diff --git a/src/proto_012_PsiThaCa/lib_delegate/operation_pool.mli b/src/proto_012_PsiThaCa/lib_delegate/operation_pool.mli new file mode 100644 index 000000000000..54d8501cd6e9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/operation_pool.mli @@ -0,0 +1,123 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +val consensus_index : int + +val votes_index : int + +val anonymous_index : int + +val managers_index : int + +module OpSet : Set.S with type elt = packed_operation + +type pool = { + consensus : OpSet.t; + votes : OpSet.t; + anonymous : OpSet.t; + managers : OpSet.t; +} + +val empty : pool + +val pp_pool : Format.formatter -> pool -> unit + +val pool_to_list_list : pool -> packed_operation list list + +val pool_of_list_list : packed_operation list list -> pool + +val filter_pool : (packed_operation -> bool) -> pool -> pool + +type ordered_pool = { + ordered_consensus : packed_operation list; + ordered_votes : packed_operation list; + ordered_anonymous : packed_operation list; + ordered_managers : packed_operation list; +} + +val ordered_pool_encoding : ordered_pool Data_encoding.t + +val empty_ordered : ordered_pool + +val pp_ordered_pool : Format.formatter -> ordered_pool -> unit + +type payload = { + votes_payload : packed_operation list; + anonymous_payload : packed_operation list; + managers_payload : packed_operation list; +} + +val empty_payload : payload + +val payload_encoding : payload Data_encoding.t + +val pp_payload : Format.formatter -> payload -> unit + +val payload_of_ordered_pool : ordered_pool -> payload + +val ordered_pool_of_payload : + consensus_operations:packed_operation list -> payload -> ordered_pool + +val add_operation : pool -> packed_operation -> pool + +val add_operations : pool -> packed_operation list -> pool + +type consensus_filter = { + level : int32; + round : Round.t; + payload_hash : Block_payload_hash.t; +} + +val filter_with_relevant_consensus_ops : + endorsement_filter:consensus_filter -> + preendorsement_filter:consensus_filter option -> + OpSet.t -> + OpSet.t + +val unpack_preendorsement : + packed_operation -> Kind.preendorsement operation option + +val unpack_endorsement : packed_operation -> Kind.endorsement operation option + +val filter_preendorsements : + packed_operation list -> Kind.preendorsement operation list + +val filter_endorsements : + packed_operation list -> Kind.endorsement operation list + +val ordered_to_list_list : ordered_pool -> packed_operation list list + +val ordered_of_list_list : packed_operation list list -> ordered_pool option + +(** [preendorsements] <> None => (List.length preendorsements > 0) *) +val extract_operations_of_list_list : + packed_operation list list -> + (Kind.preendorsement operation list option + * Kind.endorsement operation list + * payload) + option diff --git a/src/proto_012_PsiThaCa/lib_delegate/operation_selection.ml b/src/proto_012_PsiThaCa/lib_delegate/operation_selection.ml new file mode 100644 index 000000000000..103165683567 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/operation_selection.ml @@ -0,0 +1,316 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Operation_pool + +let quota = Main.validation_passes + +let consensus_quota = Stdlib.List.nth quota Operation_pool.consensus_index + +let votes_quota = Stdlib.List.nth quota Operation_pool.votes_index + +let anonymous_quota = Stdlib.List.nth quota Operation_pool.anonymous_index + +let managers_quota = Stdlib.List.nth quota Operation_pool.managers_index + +type weighted_manager = { + op : packed_operation; + size : int; + fee : Tez.t; + gas : Fixed_point_repr.integral_tag Gas.Arith.t; + weight : Q.t; + source : public_key_hash; + counter : counter; +} + +module WeightedManagerSet = Set.Make (struct + type t = weighted_manager + + (* We order the operations by their weights except if they belong + to the same manager, if they do, we order them by their + counter. *) + let compare {source; counter; weight; _} + {source = source'; counter = counter'; weight = weight'; _} = + (* Be careful with the [compare] *) + let cmp_src = Signature.Public_key_hash.compare source source' in + if cmp_src = 0 then + (* we want the smallest counter first *) + let c = Z.compare counter counter' in + if c <> 0 then c else Q.compare weight' weight + (* if same counter, biggest weight first *) + else + (* We want the biggest weight first *) + let c = Q.compare weight' weight in + if c <> 0 then c else cmp_src +end) + +let weight_manager ~max_size ~hard_gas_limit_per_block ~minimal_fees + ~minimal_nanotez_per_gas_unit ~minimal_nanotez_per_byte op = + let {protocol_data = Operation_data {contents; _}; _} = op in + let open Operation in + let l = to_list (Contents_list contents) in + List.fold_left_e + (fun ((first_source, first_counter, total_fee, total_gas) as acc) -> + function + | Contents (Manager_operation {source; counter; fee; gas_limit; _}) -> + (Environment.wrap_tzresult @@ Tez.(total_fee +? fee)) + >>? fun total_fee -> + (* There is only one unique source per packed transaction *) + let first_source = Option.value ~default:source first_source in + (* We only care about the first counter *) + let first_counter = Option.value ~default:counter first_counter in + ok + ( Some first_source, + Some first_counter, + total_fee, + Gas.Arith.add total_gas gas_limit ) + | _ -> ok acc) + (None, None, Tez.zero, Gas.Arith.zero) + l + |> function + | Ok (Some source, Some counter, fee, gas) -> + if Tez.(fee < minimal_fees) then None + else + let size = Data_encoding.Binary.length Operation.encoding op in + let size_f = Q.of_int size in + let gas_f = Q.of_bigint (Gas.Arith.integral_to_z gas) in + let fee_f = Q.of_int64 (Tez.to_mutez fee) in + let size_ratio = Q.(size_f / Q.of_int max_size) in + let gas_ratio = + Q.( + gas_f + / Q.of_bigint (Gas.Arith.integral_to_z hard_gas_limit_per_block)) + in + let weight = Q.(fee_f / max size_ratio gas_ratio) in + let fees_in_nanotez = + Q.mul (Q.of_int64 (Tez.to_mutez fee)) (Q.of_int 1000) + in + let enough_fees_for_gas = + let minimal_fees_in_nanotez = + Q.mul + minimal_nanotez_per_gas_unit + (Q.of_bigint @@ Gas.Arith.integral_to_z gas) + in + Q.compare minimal_fees_in_nanotez fees_in_nanotez <= 0 + in + let enough_fees_for_size = + let minimal_fees_in_nanotez = + Q.mul minimal_nanotez_per_byte (Q.of_int size) + in + Q.compare minimal_fees_in_nanotez fees_in_nanotez <= 0 + in + if enough_fees_for_size && enough_fees_for_gas then + Some {op; size; weight; fee; gas; source; counter} + else None + | _ -> None + +let weight_managers ~hard_gas_limit_per_block ~minimal_fees + ~minimal_nanotez_per_gas_unit ~minimal_nanotez_per_byte managers = + OpSet.fold + (fun op acc -> + match + weight_manager + ~max_size:managers_quota.max_size + ~hard_gas_limit_per_block + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + op + with + | None -> acc + | Some w_op -> WeightedManagerSet.add w_op acc) + managers + WeightedManagerSet.empty + +(** Simulation *) + +type simulation_result = { + validation_result : Tezos_protocol_environment.validation_result; + block_header_metadata : block_header_metadata; + operations : packed_operation list list; + operations_hash : Operation_list_list_hash.t; +} + +let validate_operation inc op = + Baking_simulator.add_operation inc op >>= function + | Error _errs -> + (* TODO: log debug *) + (* "@[Client-side validation: filtered invalid operation %a@\n\ + * %a@]" + *) + Lwt.return_none + | Ok (resulting_state, receipt) -> ( + try + (* Check that the metadata are serializable/deserializable *) + let _ = + Data_encoding.Binary.( + of_bytes_exn + Protocol.operation_receipt_encoding + (to_bytes_exn Protocol.operation_receipt_encoding receipt)) + in + Lwt.return_some resulting_state + with _exn -> + (* TODO: log debug *) + (* f "Client-side validation: filtered invalid operation %a" + * -% t event "baking_rejected_invalid_operation" + * -% a + * errs_tag + * [ Validation_errors.Cannot_serialize_operation_metadata; + * Exn exn ]) + * >>= fun () -> *) + Lwt.return_none) + +let filter_valid_operations_up_to_quota inc (ops, quota) = + let {Environment_context.max_size; max_op} = quota in + let exception Full of (Baking_simulator.incremental * packed_operation list) + in + try + List.fold_left_s + (fun (inc, curr_size, nb_ops, acc) op -> + let op_size = + Data_encoding.Binary.length Alpha_context.Operation.encoding op + in + let new_size = curr_size + op_size in + if new_size > max_size then Lwt.return (inc, curr_size, nb_ops, acc) + else ( + Option.iter + (fun max_op -> if max_op = nb_ops + 1 then raise (Full (inc, acc))) + max_op ; + validate_operation inc op >>= function + | None -> Lwt.return (inc, curr_size, nb_ops, acc) + | Some inc' -> Lwt.return (inc', new_size, nb_ops + 1, op :: acc))) + (inc, 0, 0, []) + ops + >>= fun (inc, _, _, l) -> Lwt.return (inc, List.rev l) + with Full (inc, l) -> Lwt.return (inc, List.rev l) + +let filter_operations_with_simulation initial_inc fees_config + ~hard_gas_limit_per_block {consensus; votes; anonymous; managers} = + let { + Baking_configuration.minimal_fees; + minimal_nanotez_per_gas_unit; + minimal_nanotez_per_byte; + } = + fees_config + in + filter_valid_operations_up_to_quota + initial_inc + (OpSet.elements consensus, consensus_quota) + >>= fun (inc, consensus) -> + filter_valid_operations_up_to_quota inc (OpSet.elements votes, votes_quota) + >>= fun (inc, votes) -> + filter_valid_operations_up_to_quota + inc + (OpSet.elements anonymous, anonymous_quota) + >>= fun (inc, anonymous) -> + (* Sort the managers *) + let weighted_managers = + weight_managers + ~hard_gas_limit_per_block + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + managers + in + filter_valid_operations_up_to_quota + inc + ( WeightedManagerSet.elements weighted_managers + |> List.map (fun {op; _} -> op), + managers_quota ) + >>= fun (inc, managers) -> + let operations = [consensus; votes; anonymous; managers] in + let operations_hash = + Operation_list_list_hash.compute + (List.map + (fun sl -> + Operation_list_hash.compute (List.map Operation.hash_packed sl)) + operations) + in + let inc = {inc with header = {inc.header with operations_hash}} in + Baking_simulator.finalize_construction inc + >>=? fun (validation_result, block_header_metadata) -> + return {validation_result; block_header_metadata; operations; operations_hash} + +let filter_valid_operations_up_to_quota_without_simulation (ops, quota) = + let {Environment_context.max_size; max_op} = quota in + let exception Full of packed_operation list in + try + List.fold_left + (fun (curr_size, nb_ops, acc) op -> + let op_size = + Data_encoding.Binary.length Alpha_context.Operation.encoding op + in + let new_size = curr_size + op_size in + if new_size > max_size then (curr_size, nb_ops, acc) + else ( + Option.iter + (fun max_op -> if max_op = nb_ops + 1 then raise (Full acc)) + max_op ; + (new_size, nb_ops + 1, op :: acc))) + (0, 0, []) + ops + |> fun (_, _, l) -> List.rev l + with Full l -> List.rev l + +let filter_operations_without_simulation fees_config ~hard_gas_limit_per_block + {consensus; votes; anonymous; managers} = + let consensus = + filter_valid_operations_up_to_quota_without_simulation + (OpSet.elements consensus, consensus_quota) + in + let votes = + filter_valid_operations_up_to_quota_without_simulation + (OpSet.elements votes, votes_quota) + in + let anonymous = + filter_valid_operations_up_to_quota_without_simulation + (OpSet.elements anonymous, anonymous_quota) + in + let { + Baking_configuration.minimal_fees; + minimal_nanotez_per_gas_unit; + minimal_nanotez_per_byte; + } = + fees_config + in + (* Sort the managers *) + let weighted_managers = + weight_managers + ~hard_gas_limit_per_block + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + managers + in + let managers = + filter_valid_operations_up_to_quota_without_simulation + ( WeightedManagerSet.elements weighted_managers + |> List.map (fun {op; _} -> op), + managers_quota ) + in + let operations = [consensus; votes; anonymous; managers] in + operations diff --git a/src/proto_012_PsiThaCa/lib_delegate/operation_selection.mli b/src/proto_012_PsiThaCa/lib_delegate/operation_selection.mli new file mode 100644 index 000000000000..1159a6cba704 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/operation_selection.mli @@ -0,0 +1,48 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Environment_context + +type simulation_result = { + validation_result : validation_result; + block_header_metadata : Apply_results.block_metadata; + operations : packed_operation list list; + operations_hash : Operation_list_list_hash.t; +} + +val filter_operations_with_simulation : + Baking_simulator.incremental -> + Baking_configuration.fees_config -> + hard_gas_limit_per_block:Gas.Arith.integral -> + Operation_pool.pool -> + simulation_result tzresult Lwt.t + +val filter_operations_without_simulation : + Baking_configuration.fees_config -> + hard_gas_limit_per_block:Gas.Arith.integral -> + Operation_pool.pool -> + packed_operation list list diff --git a/src/proto_012_PsiThaCa/lib_delegate/operation_worker.ml b/src/proto_012_PsiThaCa/lib_delegate/operation_worker.ml new file mode 100644 index 000000000000..da6b8444748d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/operation_worker.ml @@ -0,0 +1,658 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* TODO: + add events + + running state introspection to recover/restart on failure + + Do we need a mutex ? +*) + +open Protocol_client_context +open Protocol +open Alpha_context + +module Events = struct + include Internal_event.Simple + + let section = [Protocol.name; "baker"; "operation_worker"] + + let pp_int = Format.pp_print_int + + let loop_failed = + declare_1 + ~section + ~name:"loop_failed" + ~level:Error + ~msg:"loop failed with {trace}" + ~pp1:Error_monad.pp_print_trace + ("trace", Error_monad.trace_encoding) + + let ended = + declare_1 + ~section + ~name:"ended" + ~level:Error + ~msg:"ended with error {stacktrace}" + ("stacktrace", Data_encoding.string) + + let pqc_reached = + declare_2 + ~section + ~name:"pqc_reached" + ~level:Debug + ~msg: + "pre-quorum reached (voting power: {voting_power}, {preendorsements} \ + preendorsements)" + ~pp1:pp_int + ("voting_power", Data_encoding.int31) + ~pp2:pp_int + ("preendorsements", Data_encoding.int31) + + let preendorsements_received = + declare_4 + ~section + ~name:"preendorsements_received" + ~level:Debug + ~msg: + "received {count} preendorsements (power: {delta_power}) (total voting \ + power: {voting_power}, {preendorsements} preendorsements)" + ~pp1:pp_int + ("count", Data_encoding.int31) + ~pp2:pp_int + ("delta_power", Data_encoding.int31) + ~pp3:pp_int + ("voting_power", Data_encoding.int31) + ~pp4:pp_int + ("preendorsements", Data_encoding.int31) + + let qc_reached = + declare_2 + ~section + ~name:"qc_reached" + ~level:Debug + ~msg: + "quorum reached (voting power: {voting_power}, {endorsements} \ + endorsements)" + ~pp1:pp_int + ("voting_power", Data_encoding.int31) + ~pp2:pp_int + ("endorsements", Data_encoding.int31) + + let endorsements_received = + declare_4 + ~section + ~name:"endorsements_received" + ~level:Debug + ~msg: + "received {count} endorsements (power: {delta_power}) (total voting \ + power: {voting_power}, {endorsements} endorsements)" + ~pp1:pp_int + ("count", Data_encoding.int31) + ~pp2:pp_int + ("delta_power", Data_encoding.int31) + ~pp3:pp_int + ("voting_power", Data_encoding.int31) + ~pp4:pp_int + ("endorsements", Data_encoding.int31) + + let starting_new_monitoring = + declare_0 + ~section + ~name:"starting_new_monitoring" + ~level:Debug + ~msg:"starting new monitoring" + () + + let end_of_stream = + declare_0 + ~section + ~name:"end_of_stream" + ~level:Debug + ~msg:"end of stream" + () + + let received_new_operations = + declare_0 + ~section + ~name:"received_new_operations" + ~level:Debug + ~msg:"received new operations" + () + + (* info messages *) + let shutting_down = + declare_0 + ~section + ~name:"shutting_down" + ~level:Info + ~msg:"shutting down operation worker" + () + + let mempool_initial_additions = + declare_1 + ~section + ~name:"mempool_initial_additions" + ~level:Info + ~msg:"added {count} initial operations in baker mempool" + ("count", Data_encoding.int31) + + let invalid_json_file = + declare_1 + ~section + ~name:"invalid_json_file" + ~level:Warning + ~msg:"{filename} is not a valid JSON file" + ("filename", Data_encoding.string) + + let no_mempool_found_in_file = + declare_1 + ~section + ~name:"no_mempool_found_in_file" + ~level:Warning + ~msg:"no mempool found in file {filename}" + ("filename", Data_encoding.string) + + let cannot_fetch_mempool = + declare_1 + ~section + ~name:"cannot_fetch_mempool" + ~level:Error + ~msg:"cannot fetch mempool: {errs}" + ("errs", Error_monad.(TzTrace.encoding error_encoding)) +end + +module Mempool = struct + type error += + | Failed_mempool_fetch of { + path : string; + reason : string; + details : Data_encoding.json option; + } + + let ops_of_mempool + (ops : Protocol_client_context.Alpha_block_services.Mempool.t) = + (* We only retain the applied, unprocessed and delayed operations *) + List.rev + (Operation_hash.Map.fold (fun _ op acc -> op :: acc) ops.unprocessed + @@ Operation_hash.Map.fold + (fun _ (op, _) acc -> op :: acc) + ops.branch_delayed + @@ List.rev_map (fun (_, op) -> op) ops.applied) + + let retrieve mempool = + match mempool with + | None -> Lwt.return_none + | Some mempool -> ( + let fail reason details = + let path = + match mempool with + | Baking_configuration.Mempool.Local {filename} -> filename + | Baking_configuration.Mempool.Remote {uri; _} -> Uri.to_string uri + in + fail (Failed_mempool_fetch {path; reason; details}) + in + let decode_mempool json = + protect + ~on_error:(fun _ -> + fail "cannot decode the received JSON into mempool" (Some json)) + (fun () -> + let mempool = + Data_encoding.Json.destruct + Protocol_client_context.Alpha_block_services.S.Mempool + .encoding + json + in + return (ops_of_mempool mempool)) + in + match mempool with + | Baking_configuration.Mempool.Local {filename} -> + if Sys.file_exists filename then + Tezos_stdlib_unix.Lwt_utils_unix.Json.read_file filename + >>= function + | Error _ -> + Events.(emit invalid_json_file filename) >>= fun () -> + Lwt.return_none + | Ok json -> ( + decode_mempool json >>= function + | Ok mempool -> Lwt.return_some mempool + | Error errs -> + Events.(emit cannot_fetch_mempool errs) >>= fun () -> + Lwt.return_none) + else + Events.(emit no_mempool_found_in_file filename) >>= fun () -> + Lwt.return_none + | Baking_configuration.Mempool.Remote {uri; http_headers} -> ( + ( (with_timeout + (Systime_os.sleep (Time.System.Span.of_seconds_exn 5.)) + (fun _ -> + Tezos_rpc_http_client_unix.RPC_client_unix.generic_json_call + ?headers:http_headers + `GET + uri) + >>=? function + | `Ok json -> return json + | `Unauthorized json -> fail "unauthorized request" json + | `Gone json -> fail "gone" json + | `Error json -> fail "error" json + | `Not_found json -> fail "not found" json + | `Forbidden json -> fail "forbidden" json + | `Conflict json -> fail "conflict" json) + >>=? fun json -> decode_mempool json ) + >>= function + | Ok mempool -> Lwt.return_some mempool + | Error errs -> + Events.(emit cannot_fetch_mempool errs) >>= fun () -> + Lwt.return_none)) +end + +type candidate = { + hash : Block_hash.t; + round_watched : Round.t; + payload_hash_watched : Block_payload_hash.t; +} + +let candidate_encoding = + let open Data_encoding in + conv + (fun {hash; round_watched; payload_hash_watched} -> + (hash, round_watched, payload_hash_watched)) + (fun (hash, round_watched, payload_hash_watched) -> + {hash; round_watched; payload_hash_watched}) + (obj3 + (req "hash" Block_hash.encoding) + (req "round_watched" Round.encoding) + (req "payload_hash_watched" Block_payload_hash.encoding)) + +type voting_power = int + +type event = + | Prequorum_reached of + candidate * voting_power * Kind.preendorsement operation list + | Quorum_reached of candidate * voting_power * Kind.endorsement operation list + +type pqc_watched = { + candidate_watched : candidate; + get_preendorsement_voting_power : slot:Slot.t -> int; + consensus_threshold : int; + mutable current_voting_power : int; + mutable preendorsements_received : Kind.preendorsement operation list; + mutable preendorsements_count : int; +} + +type qc_watched = { + candidate_watched : candidate; + get_endorsement_voting_power : slot:Slot.t -> int; + consensus_threshold : int; + mutable current_voting_power : int; + mutable endorsements_received : Kind.endorsement operation list; + mutable endorsements_count : int; +} + +type watch_kind = Pqc_watch of pqc_watched | Qc_watch of qc_watched + +type quorum_event_stream = { + stream : event Lwt_stream.t; + push : event option -> unit; +} + +type t = { + mutable operation_pool : Operation_pool.pool; + mutable canceler : Lwt_canceler.t; + mutable proposal_watched : watch_kind option; + qc_event_stream : quorum_event_stream; + lock : Lwt_mutex.t; + monitor_node_operations : bool; (* Keep on monitoring node operations *) +} + +let monitor_operations (cctxt : #Protocol_client_context.full) = + Alpha_block_services.Mempool.monitor_operations + cctxt + ~chain:cctxt#chain + ~applied:true + ~branch_delayed:true + ~branch_refused:false + ~refused:false + () + >>=? fun (operation_stream, stream_stopper) -> + let operation_stream = + Lwt_stream.map + (fun ops -> List.map (fun ((_, op), _) -> op) ops) + operation_stream + in + Shell_services.Blocks.Header.shell_header + cctxt + ~chain:cctxt#chain + ~block:(`Head 0) + () + >>=? fun shell_header -> + let round = + match Fitness.(round_from_raw shell_header.fitness) with + | Ok r -> r + | Error _ -> Round.zero + in + return ((shell_header.level, round), operation_stream, stream_stopper) + +let make_initial_state ?initial_mempool ?(monitor_node_operations = true) () = + let qc_event_stream = + let (stream, push) = Lwt_stream.create () in + {stream; push} + in + let canceler = Lwt_canceler.create () in + let operation_pool = + Option.fold + ~none:Operation_pool.empty + ~some:(Operation_pool.add_operations Operation_pool.empty) + initial_mempool + in + let lock = Lwt_mutex.create () in + { + operation_pool; + canceler; + proposal_watched = None; + qc_event_stream; + lock; + monitor_node_operations; + } + +let is_valid_consensus_content (candidate : candidate) consensus_content = + let {hash = _; round_watched; payload_hash_watched} = candidate in + Round.equal consensus_content.round round_watched + && Block_payload_hash.equal + consensus_content.block_payload_hash + payload_hash_watched + +let cancel_monitoring state = state.proposal_watched <- None + +let update_monitoring ?(should_lock = true) state ops = + (if should_lock then Lwt_mutex.with_lock state.lock else fun f -> f ()) + @@ fun () -> + (* If no block is watched, don't do anything *) + match state.proposal_watched with + | None -> Lwt.return_unit + | Some + (Pqc_watch + ({ + candidate_watched; + get_preendorsement_voting_power; + consensus_threshold; + _; + } as proposal_watched)) -> + let preendorsements = Operation_pool.filter_preendorsements ops in + let (preendorsements_count, voting_power) = + List.fold_left + (fun (count, power) (op : Kind.preendorsement Operation.t) -> + let { + shell = _; + protocol_data = + {contents = Single (Preendorsement consensus_content); _}; + _; + } = + op + in + if is_valid_consensus_content candidate_watched consensus_content + then ( + let op_power = + get_preendorsement_voting_power ~slot:consensus_content.slot + in + proposal_watched.current_voting_power <- + proposal_watched.current_voting_power + op_power ; + proposal_watched.preendorsements_received <- + op :: proposal_watched.preendorsements_received ; + proposal_watched.preendorsements_count <- + proposal_watched.preendorsements_count + 1 ; + (count + 1, power + op_power)) + else (count, power)) + (0, 0) + preendorsements + in + if proposal_watched.current_voting_power >= consensus_threshold then ( + Events.( + emit + pqc_reached + ( proposal_watched.current_voting_power, + proposal_watched.preendorsements_count )) + >>= fun () -> + state.qc_event_stream.push + (Some + (Prequorum_reached + ( candidate_watched, + proposal_watched.current_voting_power, + List.rev proposal_watched.preendorsements_received ))) ; + (* Once the event has been emitted, we cancel the monitoring *) + cancel_monitoring state ; + Lwt.return_unit) + else + Events.( + emit + preendorsements_received + ( preendorsements_count, + voting_power, + proposal_watched.current_voting_power, + proposal_watched.preendorsements_count )) + | Some + (Qc_watch + ({ + candidate_watched; + get_endorsement_voting_power; + consensus_threshold; + _; + } as proposal_watched)) -> + let endorsements = Operation_pool.filter_endorsements ops in + let (endorsements_count, voting_power) = + List.fold_left + (fun (count, power) (op : Kind.endorsement Operation.t) -> + let { + shell = _; + protocol_data = + {contents = Single (Endorsement consensus_content); _}; + _; + } = + op + in + if is_valid_consensus_content candidate_watched consensus_content + then ( + let op_power = + get_endorsement_voting_power ~slot:consensus_content.slot + in + proposal_watched.current_voting_power <- + proposal_watched.current_voting_power + op_power ; + proposal_watched.endorsements_received <- + op :: proposal_watched.endorsements_received ; + proposal_watched.endorsements_count <- + proposal_watched.endorsements_count + 1 ; + (count + 1, power + op_power)) + else (count, power)) + (0, 0) + endorsements + in + if proposal_watched.current_voting_power >= consensus_threshold then ( + Events.( + emit + qc_reached + ( proposal_watched.current_voting_power, + proposal_watched.endorsements_count )) + >>= fun () -> + state.qc_event_stream.push + (Some + (Quorum_reached + ( candidate_watched, + proposal_watched.current_voting_power, + List.rev proposal_watched.endorsements_received ))) ; + (* Once the event has been emitted, we cancel the monitoring *) + cancel_monitoring state ; + Lwt.return_unit) + else + Events.( + emit + endorsements_received + ( endorsements_count, + voting_power, + proposal_watched.current_voting_power, + proposal_watched.endorsements_count )) + +let monitor_quorum state new_proposal_watched = + Lwt_mutex.with_lock state.lock @@ fun () -> + (* if a previous monitoring was registered, we cancel it *) + if state.proposal_watched <> None then cancel_monitoring state ; + state.proposal_watched <- new_proposal_watched ; + let current_consensus_operations = + Operation_pool.OpSet.elements state.operation_pool.consensus + in + (* initialize with the currently present consensus operations *) + update_monitoring ~should_lock:false state current_consensus_operations + +let monitor_preendorsement_quorum state ~consensus_threshold + ~get_preendorsement_voting_power candidate_watched = + let new_proposal = + Some + (Pqc_watch + { + candidate_watched; + get_preendorsement_voting_power; + consensus_threshold; + current_voting_power = 0; + preendorsements_received = []; + preendorsements_count = 0; + }) + in + monitor_quorum state new_proposal + +let monitor_endorsement_quorum state ~consensus_threshold + ~get_endorsement_voting_power candidate_watched = + let new_proposal = + Some + (Qc_watch + { + candidate_watched; + get_endorsement_voting_power; + consensus_threshold; + current_voting_power = 0; + endorsements_received = []; + endorsements_count = 0; + }) + in + monitor_quorum state new_proposal + +let shutdown_worker state = + Events.(emit shutting_down ()) >>= fun () -> + Lwt_canceler.cancel state.canceler + +(* Each time a new head is received, the operation_pool field of the state is + cleaned/reset by this function. Instead of emptying it completely, we keep + the endorsements of at most 5 rounds and 1 level in the past, to be able to + include as much endorsements as possible in the next block if this baker is + the proposer. This allows to handle the following situations: + + - The baker observes an EQC for (L, R), but a proposal arrived for (L, R+1). + After the flush, extra endorsements on top of (L, R) are 'Branch_refused', + and are not re-sent by the node. If the baker proposes at (L+1, 1), he should + be able to include these extra endorsements. Hence the cache for old rounds. + + - The baker receives a head at (L+1, 0) on top of (L, 0), but this head + didn't reach consensus. If the baker who proposes at (L+1, 1) observed some + extra endorsements for (L, 0) that are not included in (L+1, 0), he may want + to add them. But these endorsements become 'Outdated' in the mempool once + (L+1, 0) is received. Hence the cache for previous level. +*) +let may_update_operations_pool state (head_level, head_round) = + let endorsements = + let head_round_i32 = Round.to_int32 head_round in + let head_level_i32 = head_level in + Operation_pool.OpSet.filter + (function + | { + protocol_data = + Operation_data + {contents = Single (Endorsement {round; level; _}); _}; + _; + } -> + let round_i32 = Round.to_int32 round in + let level_i32 = Raw_level.to_int32 level in + let delta_round = Int32.sub head_round_i32 round_i32 in + let delta_level = Int32.sub head_level_i32 level_i32 in + (* Only retain endorsements that are maximum 5 rounds old and + 1 level in the last *) + Compare.Int32.(delta_round <= 5l && delta_level <= 1l) + | _ -> false) + state.operation_pool.consensus + in + let operation_pool = + {Operation_pool.empty with Operation_pool.consensus = endorsements} + in + state.operation_pool <- operation_pool + +let create ?initial_mempool ?(monitor_node_operations = true) + (cctxt : #Protocol_client_context.full) = + Mempool.retrieve initial_mempool >>= fun initial_mempool -> + let state = make_initial_state ?initial_mempool ~monitor_node_operations () in + (* TODO should we continue forever ? *) + let rec worker_loop () = + monitor_operations cctxt >>= function + | Error err -> Events.(emit loop_failed err) + | Ok (head, operation_stream, op_stream_stopper) -> + Events.(emit starting_new_monitoring ()) >>= fun () -> + state.canceler <- Lwt_canceler.create () ; + Lwt_canceler.on_cancel state.canceler (fun () -> + op_stream_stopper () ; + cancel_monitoring state ; + Lwt.return_unit) ; + may_update_operations_pool state head ; + let rec loop () = + Lwt_stream.get operation_stream >>= function + | None -> + (* When the stream closes, it means a new head has been set, + we cancel the monitoring and flush current operations *) + Events.(emit end_of_stream ()) >>= fun () -> + op_stream_stopper () ; + cancel_monitoring state ; + worker_loop () + | Some ops -> + Events.(emit received_new_operations ()) >>= fun () -> + state.operation_pool <- + Operation_pool.add_operations state.operation_pool ops ; + update_monitoring state ops >>= fun () -> loop () + in + loop () + in + let worker_loop () = + (match initial_mempool with + | None -> Lwt.return_unit + | Some ops -> Events.(emit mempool_initial_additions (List.length ops))) + >>= fun () -> + if state.monitor_node_operations then worker_loop () else Lwt.return_unit + in + Lwt.dont_wait + (fun () -> + Lwt.finalize + (fun () -> worker_loop ()) + (fun () -> shutdown_worker state >>= fun _ -> Lwt.return_unit)) + (fun exn -> + Events.(emit__dont_wait__use_with_care ended (Printexc.to_string exn))) ; + Lwt.return state + +let get_current_operations state = state.operation_pool + +let get_quorum_event_stream state = state.qc_event_stream.stream diff --git a/src/proto_012_PsiThaCa/lib_delegate/operation_worker.mli b/src/proto_012_PsiThaCa/lib_delegate/operation_worker.mli new file mode 100644 index 000000000000..b7fb0559b29c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/operation_worker.mli @@ -0,0 +1,94 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Launch processes to gather operations from the mempool and make them + available for the baker. *) + +open Protocol +open Alpha_context + +(** {1 Datatypes}*) + +type t + +type candidate = { + hash : Block_hash.t; + round_watched : Round.t; + payload_hash_watched : Block_payload_hash.t; +} + +val candidate_encoding : candidate Data_encoding.t + +type voting_power = int + +type event = + | Prequorum_reached of + candidate * voting_power * Kind.preendorsement operation list + | Quorum_reached of candidate * voting_power * Kind.endorsement operation list + +(** {1 Constructors}*) + +(** [create ?initial_mempool ?monitor_node cctxt] create a monitoring process to + fetch operations for the baker to process. + + + @param initial_mempool initial operations to put in the worker's queue + (default: [None]) + + @param monitor_node_operations monitor operations on the node (defaults: [true]). Set + [monitor_node] to [false] to only consider the [initial_mempool] operations. + +*) +val create : + ?initial_mempool:Baking_configuration.Mempool.t -> + ?monitor_node_operations:bool -> + #Protocol_client_context.full -> + t Lwt.t + +(** {2 Accessors}*) + +val get_current_operations : t -> Operation_pool.pool + +val get_quorum_event_stream : t -> event Lwt_stream.t + +(** {3 Observers} *) + +val monitor_preendorsement_quorum : + t -> + consensus_threshold:int -> + get_preendorsement_voting_power:(slot:Slot.t -> int) -> + candidate -> + unit Lwt.t + +val monitor_endorsement_quorum : + t -> + consensus_threshold:int -> + get_endorsement_voting_power:(slot:Slot.t -> int) -> + candidate -> + unit Lwt.t + +val cancel_monitoring : t -> unit + +val shutdown_worker : t -> (unit, exn list) result Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/state_transitions.ml b/src/proto_012_PsiThaCa/lib_delegate/state_transitions.ml new file mode 100644 index 000000000000..2e76497495e5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/state_transitions.ml @@ -0,0 +1,703 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Baking_state +open Baking_actions +module Events = Baking_events.State_transitions + +let do_nothing state = Lwt.return (state, Do_nothing) + +type proposal_acceptance = Invalid | Outdated_proposal | Valid_proposal + +let is_acceptable_proposal_for_current_level state + (proposal : Baking_state.proposal) = + let current_round = state.round_state.current_round in + if Round.(current_round < proposal.block.round) then + Events.( + emit unexpected_proposal_round (current_round, proposal.block.round)) + >>= fun () -> Lwt.return Invalid + else if Round.(current_round > proposal.block.round) then + Lwt.return Outdated_proposal + else + (* current_round = proposal.round *) + let previous_proposal = state.level_state.latest_proposal in + if + Round.(proposal.block.round = previous_proposal.block.round) + && Block_hash.(proposal.block.hash <> previous_proposal.block.hash) + && Block_hash.( + proposal.predecessor.hash = previous_proposal.predecessor.hash) + then + (* An existing proposal was found at the same round: the + proposal is bad and should be punished by the accuser *) + Events.( + emit + proposal_for_round_already_seen + (proposal.block.hash, current_round, previous_proposal.block.hash)) + >>= fun () -> Lwt.return Invalid + else + (* current_round = proposal.block.round ∧ + proposal.block.round <> previous_proposal.block.round + => + proposal.block.round > previous_proposal.block.round + + The proposal has the expected round and the previous proposal + is a predecessor therefore the proposal is valid *) + Lwt.return Valid_proposal + +let make_consensus_list state proposal = + (* TODO efficiently iterate on the slot map instead of removing + duplicate endorsements *) + let level = + Raw_level.of_int32 state.level_state.current_level |> function + | Ok l -> l + | _ -> assert false + in + let round = proposal.block.round in + let block_payload_hash = proposal.block.payload_hash in + SlotMap.fold + (fun _slot (delegate, slots) acc -> + ( delegate, + {slot = Stdlib.List.hd slots.slots; level; round; block_payload_hash} ) + :: acc) + state.level_state.delegate_slots.own_delegate_slots + [] + |> List.sort_uniq compare + +(* If we do not have any slots, we won't inject any operation but we + will still participate to determine an elected block *) +let make_preendorse_action state proposal = + let updated_state = + let round_state = + {state.round_state with current_phase = Awaiting_preendorsements} + in + {state with round_state} + in + let preendorsements : (delegate * consensus_content) list = + make_consensus_list state proposal + in + Inject_preendorsements {preendorsements; updated_state} + +let update_proposal state proposal = + Events.(emit updating_latest_proposal proposal.block.hash) >>= fun () -> + let new_level_state = {state.level_state with latest_proposal = proposal} in + Lwt.return {state with level_state = new_level_state} + +let may_update_proposal state (proposal : proposal) = + assert ( + Compare.Int32.( + state.level_state.latest_proposal.block.shell.level + = proposal.block.shell.level)) ; + if + Round.(state.level_state.latest_proposal.block.round < proposal.block.round) + then update_proposal state proposal + else Lwt.return state + +let preendorse state proposal = + Events.(emit preendorsing_proposal proposal.block.hash) >>= fun () -> + if Protocol_hash.(proposal.block.protocol <> proposal.block.next_protocol) + then + (* We do not endorse the first transition block *) + let new_round_state = {state.round_state with current_phase = Idle} in + let new_state = {state with round_state = new_round_state} in + Lwt.return (new_state, Do_nothing) + else Lwt.return (state, make_preendorse_action state proposal) + +let extract_pqc state (new_proposal : proposal) = + match new_proposal.block.prequorum with + | None -> None + | Some pqc -> + let add_voting_power acc (op : Kind.preendorsement Operation.t) = + let open Protocol.Alpha_context.Operation in + let { + shell = _; + protocol_data = {contents = Single (Preendorsement {slot; _}); _}; + _; + } = + op + in + match + SlotMap.find slot state.level_state.delegate_slots.all_delegate_slots + with + | None -> + (* cannot happen if the map is correctly populated *) + acc + | Some {endorsing_power; _} -> acc + endorsing_power + in + let voting_power = + List.fold_left add_voting_power 0 pqc.preendorsements + in + let consensus_threshold = + state.global_state.constants.parametric.consensus_threshold + in + if Compare.Int.(voting_power >= consensus_threshold) then + Some (pqc.preendorsements, pqc.round) + else None + +let may_update_endorsable_payload_with_internal_pqc state + (new_proposal : proposal) = + match + (new_proposal.block.prequorum, state.level_state.endorsable_payload) + with + | (None, _) -> + (* The proposal does not contain a PQC: no need to update *) + state + | (Some {round = new_round; _}, Some {prequorum = {round = old_round; _}; _}) + when Round.(new_round < old_round) -> + (* The proposal pqc is outdated, do not update *) + state + | (Some better_prequorum, _) -> + assert ( + Block_payload_hash.( + better_prequorum.block_payload_hash = new_proposal.block.payload_hash)) ; + assert ( + Compare.Int32.(better_prequorum.level = new_proposal.block.shell.level)) ; + let new_endorsable_payload = + Some {proposal = new_proposal; prequorum = better_prequorum} + in + let new_level_state = + {state.level_state with endorsable_payload = new_endorsable_payload} + in + {state with level_state = new_level_state} + +let rec handle_new_proposal state (new_proposal : proposal) = + let current_level = state.level_state.current_level in + let new_proposal_level = new_proposal.block.shell.level in + if Compare.Int32.(current_level > new_proposal_level) then + (* The baker is ahead, a reorg may have happened. Do nothing: + wait for the node to send us the branch's head. This new head + should have a fitness that is greater than our current + proposal and thus, its level should be at least the same as + our current proposal's level. *) + Events.(emit baker_is_ahead_of_node (current_level, new_proposal_level)) + >>= fun () -> Lwt.return (state, Do_nothing) + else if Compare.Int32.(current_level = new_proposal_level) then + (* The received head is a new proposal for the current level: + let's check if it's a valid one for us. *) + let current_proposal = state.level_state.latest_proposal in + if + Block_hash.( + current_proposal.predecessor.hash <> new_proposal.predecessor.hash) + then + Events.( + emit + new_proposal_is_on_another_branch + (current_proposal.predecessor.hash, new_proposal.predecessor.hash)) + >>= fun () -> may_switch_branch state new_proposal + else + is_acceptable_proposal_for_current_level state new_proposal >>= function + | Invalid -> + (* The proposal is invalid: we ignore it *) + Events.(emit skipping_invalid_proposal ()) >>= fun () -> + do_nothing state + | Outdated_proposal -> + (* Check whether we need to update our endorsable payload *) + let state = + may_update_endorsable_payload_with_internal_pqc state new_proposal + in + (* The proposal is outdated: we update to be able to extract + its included endorsements but we do not endorse it *) + Events.(emit outdated_proposal new_proposal.block.hash) >>= fun () -> + may_update_proposal state new_proposal >>= fun state -> + do_nothing state + | Valid_proposal -> ( + (* Valid_proposal => proposal.round = current_round *) + (* Check whether we need to update our endorsable payload *) + let new_state = + may_update_endorsable_payload_with_internal_pqc state new_proposal + in + may_update_proposal new_state new_proposal >>= fun new_state -> + (* The proposal is valid but maybe we already locked on a payload *) + match new_state.level_state.locked_round with + | Some locked_round -> ( + if + Block_payload_hash.( + locked_round.payload_hash = new_proposal.block.payload_hash) + then + (* when the new head has the same payload as our + [locked_round], we accept it and preendorse *) + preendorse new_state new_proposal + else + (* The payload is different *) + match new_proposal.block.prequorum with + | Some {round; _} when Round.(locked_round.round < round) -> + (* This PQC is above our locked_round, we can preendorse it *) + preendorse new_state new_proposal + | _ -> Lwt.return (new_state, Do_nothing)) + | None -> + (* Otherwise, we did not lock on any payload, thus we can + preendorse it *) + preendorse new_state new_proposal) + else + (* new_proposal.level > current_level *) + (* Possible scenarios: + - we received a block for a next level + - we received our own block + This is where we update our [level_state] (and our [round_state]) *) + Events.(emit new_head_with_increasing_level ()) >>= fun () -> + let new_level = new_proposal.block.shell.level in + let compute_new_state ~current_round ~delegate_slots + ~next_level_delegate_slots = + let round_state = {current_round; current_phase = Idle} in + let level_state = + { + current_level = new_level; + latest_proposal = new_proposal; + (* Unlock values *) + locked_round = None; + endorsable_payload = None; + elected_block = None; + delegate_slots; + next_level_delegate_slots; + next_level_proposed_round = None; + } + in + (* recursive call with the up-to-date state to handle the new + level proposals *) + handle_new_proposal {state with level_state; round_state} new_proposal + in + let action = + Update_to_level {new_level_proposal = new_proposal; compute_new_state} + in + Lwt.return (state, action) + +and may_switch_branch state new_proposal = + let switch_branch state = + Events.(emit switching_branch ()) >>= fun () -> + (* If we are on a different branch, we also need to update our + [round_state] accordingly. + The recursive call to [handle_new_proposal] cannot end up + with an invalid proposal as it's on a different branch, thus + there is no need to backtrack to the former state as the new + proposal must end up being the new [latest_proposal]. That's + why we update it here. *) + let round_update = + { + Baking_actions.new_round_proposal = new_proposal; + handle_proposal = (fun state -> handle_new_proposal state new_proposal); + } + in + update_proposal state new_proposal >>= fun new_state -> + (* TODO if the branch proposal is outdated, we should + trigger an [End_of_round] to participate *) + Lwt.return (new_state, Synchronize_round round_update) + in + let current_endorsable_payload = state.level_state.endorsable_payload in + match (current_endorsable_payload, new_proposal.block.prequorum) with + | (None, Some _) | (None, None) -> + Events.(emit branch_proposal_has_better_fitness ()) >>= fun () -> + (* The new branch contains a PQC (and we do not) or a better + fitness, we switch. *) + switch_branch state + | (Some _, None) -> + (* We have a better PQC, we don't switch as we are able to + propose a better chain if we stay on our current one. *) + Events.(emit branch_proposal_has_no_prequorum ()) >>= fun () -> + do_nothing state + | (Some {prequorum = current_pqc; _}, Some new_pqc) -> + if Round.(current_pqc.round > new_pqc.round) then + Events.(emit branch_proposal_has_lower_prequorum ()) >>= fun () -> + (* The other's branch PQC is lower than ours, do not + switch *) + do_nothing state + else if Round.(current_pqc.round < new_pqc.round) then + Events.(emit branch_proposal_has_better_prequorum ()) >>= fun () -> + (* Their PQC is better than ours: we switch *) + switch_branch state + else + (* current_pqc.round = new_pqc *) + (* There is a PQC on two branches with the same round and + the same level but not the same predecessor : it's + impossible unless if there was some double-baking. This + shouldn't happen but do nothing anyway. *) + Events.(emit branch_proposal_has_same_prequorum ()) >>= fun () -> + do_nothing state + +(** In the association map [delegate_slots], the function returns an + optional pair ([delegate], [endorsing_slot]) if for the current + [round], the validator [delegate] has a endorsing slot. *) +let round_proposer state delegate_slots round = + (* TODO: make sure that for each slots all rounds in the map are filled *) + (* !FIXME! Endorsers and proposer are differents sets *) + (* !FIXME! the slotmap may be inconsistent & may sure to document + the invariants *) + let round_mod = + Int32.to_int (Round.to_int32 round) + mod state.global_state.constants.parametric.consensus_committee_size + in + SlotMap.find + state.level_state.delegate_slots.all_slots_by_round.(round_mod) + delegate_slots + +(** Inject a fresh block proposal containing the current operations of + the mempool in [state] and the additional [endorsements] for + [delegate] at round [round]. *) +let propose_fresh_block_action ~endorsements ?last_proposal + ~(predecessor : block_info) state delegate round = + (* TODO check if there is a trace where we could not have updated the level *) + (* The block to bake embeds the operations gathered by the + worker. However, consensus operations that are not relevant for + this block are filtered out. In the case of proposing a new fresh + block, the block is supposed to carry only endorsements for the + previous level. *) + let operation_pool = + (* 1. Fetch operations from the mempool. *) + let current_mempool = + let pool = + Operation_worker.get_current_operations + state.global_state.operation_worker + in + (* Considered the operations in the previous proposal as well *) + match last_proposal with + | Some proposal -> + let { + Operation_pool.votes_payload; + anonymous_payload; + managers_payload; + } = + proposal.payload + in + List.fold_left + Operation_pool.add_operations + pool + [votes_payload; anonymous_payload; managers_payload] + | None -> pool + in + (* 2. Filter and only retain relevant endorsements. *) + let relevant_consensus_operations = + let endorsement_filter = + { + Operation_pool.level = predecessor.shell.level; + round = predecessor.round; + payload_hash = predecessor.payload_hash; + } + in + Operation_pool.filter_with_relevant_consensus_ops + ~endorsement_filter + ~preendorsement_filter:None + current_mempool.consensus + in + let filtered_mempool = + {current_mempool with consensus = relevant_consensus_operations} + in + (* 3. Add the additional given [endorsements]. + N.b. this is a set: there won't be duplicates *) + Operation_pool.add_operations + filtered_mempool + (List.map Operation.pack endorsements) + in + let kind = Fresh operation_pool in + Events.(emit proposing_fresh_block (delegate, round)) >>= fun () -> + let block_to_bake = {predecessor; round; delegate; kind} in + let updated_state = + let new_round_state = {state.round_state with current_phase = Idle} in + {state with round_state = new_round_state} + in + Lwt.return @@ Inject_block {block_to_bake; updated_state} + +let repropose_block_action state delegate round (proposal : proposal) = + (* Possible cases: 1. There was a proposal but the PQC was not + reached 2. There was a proposal and the PQC and/or QC was + reached *) + (* We repropose the [endorsable_payload] if it exists, not the + [locked_round] as it may be older. *) + match state.level_state.endorsable_payload with + | None -> + Events.(emit no_endorsable_payload_fresh_block ()) >>= fun () -> + (* For case 1, we may re-inject with the same payload or a fresh + one. We make the choice of baking a fresh one: the previous + proposal may have been rejected because the block may have been + valid but may be considered "bad" (censored operations, empty + block, etc.) by the other validators. *) + (* Invariant: there is no locked round if there is no endorsable + payload *) + assert (state.level_state.locked_round = None) ; + let last_proposal_consensus_ops = proposal.block.quorum in + propose_fresh_block_action + ~endorsements:last_proposal_consensus_ops + state + ~last_proposal:proposal.block + ~predecessor:proposal.predecessor + delegate + round + | Some {proposal; prequorum} -> + Events.(emit repropose_block proposal.block.payload_hash) >>= fun () -> + (* For case 2, we re-inject the same block as [endorsable_round] + but we may add some left-overs endorsements. Therefore, the + operations we need to include are: + - the proposal's included endorsements + - the potential missing new endorsements for the + previous block + - the PQC of the endorsable payload *) + let consensus_operations = + (* Fetch preendorsements and endorsements from the mempool + (that could be missing from the proposal), filter, then add + consensus operations of the proposal itself, and convert + into [packed_operation trace]. *) + let mempool_consensus_operations = + (Operation_worker.get_current_operations + state.global_state.operation_worker) + .consensus + in + let all_consensus_operations = + (* Add the proposal and pqc consensus operations to the + mempool *) + List.fold_left + (fun set op -> Operation_pool.OpSet.add op set) + mempool_consensus_operations + (List.map Operation.pack proposal.block.quorum + @ List.map Operation.pack prequorum.preendorsements) + in + let endorsement_filter = + { + Operation_pool.level = proposal.predecessor.shell.level; + round = proposal.predecessor.round; + payload_hash = proposal.predecessor.payload_hash; + } + in + let preendorsement_filter = + Some + { + Operation_pool.level = prequorum.level; + round = prequorum.round; + payload_hash = prequorum.block_payload_hash; + } + in + Operation_pool.( + filter_with_relevant_consensus_ops + ~endorsement_filter + ~preendorsement_filter + all_consensus_operations + |> OpSet.elements) + in + let payload_hash = proposal.block.payload_hash in + let payload_round = proposal.block.payload_round in + let payload = proposal.block.payload in + let kind = + Reproposal {consensus_operations; payload_hash; payload_round; payload} + in + let block_to_bake = + {predecessor = proposal.predecessor; round; delegate; kind} + in + let updated_state = + let new_round_state = {state.round_state with current_phase = Idle} in + {state with round_state = new_round_state} + in + Lwt.return @@ Inject_block {block_to_bake; updated_state} + +let end_of_round state current_round = + let new_round = Round.succ current_round in + let new_round_state = {state.round_state with current_round = new_round} in + let new_state = {state with round_state = new_round_state} in + (* we need to check if we need to bake for this round or not *) + match + round_proposer + new_state + new_state.level_state.delegate_slots.own_delegate_slots + new_state.round_state.current_round + with + | None -> + Events.(emit no_proposal_slot new_round) >>= fun () -> + (* We don't have any delegate that may propose a new block for + this round -- We will wait for preendorsements when the next + level block arrive. Meanwhile, we are idle *) + let new_round_state = {new_state.round_state with current_phase = Idle} in + let new_state = {state with round_state = new_round_state} in + do_nothing new_state + | Some (delegate, _) -> + Events.(emit proposal_slot (new_round, delegate)) >>= fun () -> + (* We have a delegate, we need to determine what to inject *) + repropose_block_action + new_state + delegate + new_round + state.level_state.latest_proposal + >>= fun action -> Lwt.return (new_state, action) + +let time_to_bake state at_round = + (* It is now time to update the state level *) + (* We need to keep track for which block we have 2f+1 *endorsements*, that is, + which will become the new predecessor_block *) + (* Invariant: endorsable_round >= round(elected block) >= locked_round *) + let round_proposer_opt = + round_proposer + state + state.level_state.next_level_delegate_slots.own_delegate_slots + at_round + in + match (state.level_state.elected_block, round_proposer_opt) with + | (None, _) | (_, None) -> + (* Unreachable: the [Time_to_bake_next_level] event can only be + triggered when we have a slot and an elected block *) + assert false + | (Some elected_block, Some (delegate, _)) -> + let endorsements = elected_block.endorsement_qc in + let new_level_state = + {state.level_state with next_level_proposed_round = Some at_round} + in + let new_state = {state with level_state = new_level_state} in + propose_fresh_block_action + ~endorsements + ~predecessor:elected_block.proposal.block + new_state + delegate + at_round + >>= fun action -> Lwt.return (new_state, action) + +let update_locked_round state round payload_hash = + let locked_round = Some {payload_hash; round} in + let new_level_state = {state.level_state with locked_round} in + {state with level_state = new_level_state} + +let make_endorse_action state proposal = + let updated_state = + let new_round_state = + {state.round_state with current_phase = Awaiting_endorsements} + in + let new_state = {state with round_state = new_round_state} in + update_locked_round + new_state + proposal.block.round + proposal.block.payload_hash + in + let endorsements : (delegate * consensus_content) list = + make_consensus_list state proposal + in + Inject_endorsements {endorsements; updated_state} + +let prequorum_reached_when_awaiting_preendorsements state candidate + preendorsements = + let latest_proposal = state.level_state.latest_proposal in + if Block_hash.(candidate.Operation_worker.hash <> latest_proposal.block.hash) + then + Events.( + emit + unexpected_prequorum_received + (candidate.hash, latest_proposal.block.hash)) + >>= fun () -> do_nothing state + else + let prequorum = + { + level = latest_proposal.block.shell.level; + round = latest_proposal.block.round; + block_payload_hash = latest_proposal.block.payload_hash; + preendorsements + (* preendorsements may be nil when [consensus_threshold] is 0 *); + } + in + let new_endorsable_payload = {proposal = latest_proposal; prequorum} in + let new_level_state = + let level_state_with_new_payload = + { + state.level_state with + endorsable_payload = Some new_endorsable_payload; + } + in + match state.level_state.endorsable_payload with + | None -> level_state_with_new_payload + | Some endorsable_payload -> + if + Round.( + endorsable_payload.prequorum.round + < new_endorsable_payload.prequorum.round) + then level_state_with_new_payload + else state.level_state + in + let new_state = {state with level_state = new_level_state} in + Lwt.return (new_state, make_endorse_action new_state latest_proposal) + +let quorum_reached_when_waiting_endorsements state candidate endorsement_qc = + let latest_proposal = state.level_state.latest_proposal in + if Block_hash.(candidate.Operation_worker.hash <> latest_proposal.block.hash) + then + Events.( + emit + unexpected_quorum_received + (candidate.hash, latest_proposal.block.hash)) + >>= fun () -> do_nothing state + else + let new_level_state = + match state.level_state.elected_block with + | None -> + let elected_block = + Some {proposal = latest_proposal; endorsement_qc} + in + {state.level_state with elected_block} + | Some _ -> + (* If we already have an elected block, do not update it: the + earliest, the better. *) + state.level_state + in + let new_round_state = {state.round_state with current_phase = Idle} in + let new_state = + {state with round_state = new_round_state; level_state = new_level_state} + in + do_nothing new_state + +(* Hypothesis: + - The state is not to be modified outside this module + + - new_proposal's received blocks are expected to belong to our current + round + + - [Prequorum_reached] can only be received when we've seen a new head + + - [Quorum_reached] can only be received when we've seen a + [Prequorum_reached] *) +let step (state : Baking_state.t) (event : Baking_state.event) : + (Baking_state.t * Baking_actions.t) Lwt.t = + let phase = state.round_state.current_phase in + Events.(emit step_current_phase (phase, event)) >>= fun () -> + match (phase, event) with + (* Handle timeouts *) + | (_, Timeout (End_of_round {ending_round})) -> + (* If the round is ending, stop everything currently going on and + increment the round. *) + end_of_round state ending_round + | (_, Timeout (Time_to_bake_next_level {at_round})) -> + (* If it is time to bake the next level, stop everything currently + going on and propose the next level block *) + time_to_bake state at_round + | (Idle, New_proposal block_info) -> handle_new_proposal state block_info + | (Awaiting_endorsements, New_proposal block_info) + | (Awaiting_preendorsements, New_proposal block_info) -> + Events.(emit new_head_while_waiting_for_qc ()) >>= fun () -> + handle_new_proposal state block_info + | ( Awaiting_preendorsements, + Prequorum_reached (candidate, _voting_power, preendorsement_qc) ) -> + prequorum_reached_when_awaiting_preendorsements + state + candidate + preendorsement_qc + | ( Awaiting_endorsements, + Quorum_reached (candidate, _voting_power, endorsement_qc) ) -> + quorum_reached_when_waiting_endorsements state candidate endorsement_qc + (* Unreachable cases *) + | (Idle, (Prequorum_reached _ | Quorum_reached _)) + | (Awaiting_preendorsements, Quorum_reached _) + | (Awaiting_endorsements, Prequorum_reached _) -> + (* This cannot/should not happen *) + do_nothing state diff --git a/src/proto_012_PsiThaCa/lib_delegate/state_transitions.mli b/src/proto_012_PsiThaCa/lib_delegate/state_transitions.mli new file mode 100644 index 000000000000..bd449b20929c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/state_transitions.mli @@ -0,0 +1,90 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Baking_state +open Baking_actions + +val do_nothing : state -> (state * action) Lwt.t + +type proposal_acceptance = Invalid | Outdated_proposal | Valid_proposal + +val is_acceptable_proposal_for_current_level : + state -> proposal -> proposal_acceptance Lwt.t + +val make_consensus_list : + state -> proposal -> (delegate * consensus_content) list + +val make_preendorse_action : state -> proposal -> action + +val may_update_proposal : state -> proposal -> state Lwt.t + +val preendorse : state -> proposal -> (state * action) Lwt.t + +val extract_pqc : + state -> proposal -> (Kind.preendorsement operation list * Round.t) option + +val handle_new_proposal : state -> proposal -> (state * action) Lwt.t + +val round_proposer : + state -> + (delegate * endorsing_slot) SlotMap.t -> + Round.t -> + (delegate * endorsing_slot) option + +val propose_fresh_block_action : + endorsements:Kind.endorsement Operation.t list -> + ?last_proposal:block_info -> + predecessor:block_info -> + state -> + delegate -> + Round.t -> + action Lwt.t + +val repropose_block_action : + state -> delegate -> Round.t -> proposal -> action Lwt.t + +val end_of_round : state -> Round.t -> (state * action) Lwt.t + +val time_to_bake : state -> Round.t -> (state * action) Lwt.t + +val update_locked_round : state -> Round.t -> Block_payload_hash.t -> state + +val make_endorse_action : state -> proposal -> action + +val prequorum_reached_when_awaiting_preendorsements : + state -> + Operation_worker.candidate -> + Kind.preendorsement operation list -> + (state * action) Lwt.t + +val quorum_reached_when_waiting_endorsements : + state -> + Operation_worker.candidate -> + Kind.endorsement operation list -> + (state * action) Lwt.t + +val step : state -> event -> (state * action) Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/.ocamlformat b/src/proto_012_PsiThaCa/lib_delegate/test/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/README.md b/src/proto_012_PsiThaCa/lib_delegate/test/README.md new file mode 100644 index 000000000000..73f3e79bac88 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/README.md @@ -0,0 +1,116 @@ +# Testing Tenderbake via mockup-based simulations + +This test suite contains tests that check the baker. A notable feature that +distinguishes these tests from simple unit tests is that the baker is +examined as a whole with all its components working together. We do not run +a node, instead, we run a mockup node that allows us to create an illusion +for the baker that it talks to a real node. Thus, we have full control of +how the mockup node behaves, how the proposals and operations propagate, and +what the baker sees when it calls RPCs. + +Pros: + +* Integrates naturally with the existing testing setup and CI. No external + binaries or setup needed. +* Fast. The round time is currently constant and equal to 3 seconds. 2 + second was also tried, but that resulted in deviations from expected + behavior in about 10% of cases. Upon closer inspection it was found out + that round timeouts happen before a key event in the scenario. Supposedly, + this depends on the time the test is started as all other parameters are + set and deterministic. Switching 3 seconds solved the issue. +* Uses the same code as the baker, so people who are familiar with the + existing Tezos will benefit from their knowledge. +* Various assertions and checks can be expressed to ensure that the scenario + in question progresses exactly as it supposed to. +* Many details of how the baker sees the world can be tightly controlled. + +Cons: + +* Hard to see the logic of the scenario because it has to be written as a + collection of hooks. + +## Running the tests + +The tests can be run like this from the `src/proto_alpha/lib_delegate/test`: + +``` +$ dune exec ./main.exe -- -v +``` + +## Writing a test + +See the examples in `test_scenario.ml` for inspiration. Start writing a +scenario by deciding how many bakers you need and how many delegates each of +them will have (see the docs for `Mockup_simulator.run`): + +```ocaml + let open Mockup_simulator in + run [(3, (module Default_hooks)); (2, (module Default_hooks))] +``` + +* Set `debug` to `true` in `Mockup_simulator.default_config` and pass it to + `Mockup_simulator.run`. When `debug` is enabled baker logs will be printed. + This is the main instrument for observing what happens in the scenario. +* Consider setting `timeout` to an appropriate value. By default it is 10 + seconds, which should be fine for short scenarios, but may be insufficient + for longer ones. Timeout is a safety mechanism that prevents scenarios + from hanging and non-termination. +* It is also possible to control round durations, but it recommended to + use at least 3 seconds (the default). +* Finally, proposal slots can be controlled with the `delegate_selection` + field. Its value can either be `Random` for random selection of slots or + `Round_robin_over` with `Signature.public_key list list` inside. The + nested lists specify slot owners per level and round. + +```ocaml + let open Mockup_simulator in + let config = + { + default_config with + debug = true; + delegate_selection = + Round_robin_over + [ + (* round 0 round 1 round 2 round 3 *) + [bootstrap3; bootstrap4; bootstrap1; bootstrap2]; (* level 1 *) + [bootstrap1; bootstrap4; bootstrap2; bootstrap3]; (* level 2 *) + ]; + timeout = 15; + } + in + run ~config [(3, (module Default_hooks)); (2, (module Default_hooks))] +``` + +Note that delegate selection affects both (pre-)endorsing and voting power. +Delegates that do not have proposer slots will not be able to (pre-)endorse. +Voting power of delegates who have proposer slots will be proportional to +the number of slots they have. + +Next step is writing hook modules per baker that control its mockup mode and +execute assertions. In most cases there is no need to implement all hooks, +so the `Default_hooks` module can be reused, e.g.: + +```ocaml + let module Hooks : Mockup_simulator.Hooks = struct + include Mockup_simulator.Default_hooks + + let stop_on_event = function + | Baking_state.New_proposal {block; _} -> + (* Stop the node as soon as we receive a proposal with a level + higher than 5. *) + block.shell.level > 5l + | _ -> false + end in +``` + +Other hooks can be used to implement assertions using `failwith` and to set +mutable variable to track progress of a scenario. + +### Termination + +A scenario runs till all bakers terminate or till the scenario times out. A +baker can terminate successfully or unsuccessfully. Successful termination +happens when `stop_on_event` returns `true`. Unsuccessful termination occurs +when any of the hooks executes `failwith`. If at least one baker fails its +error message propagates and is displayed by the testing framework +(Alcotest). diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/dune b/src/proto_012_PsiThaCa/lib_delegate/test/dune new file mode 100644 index 000000000000..c5c14c54356d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/dune @@ -0,0 +1,25 @@ +(test + (name main) + (package tezos-baking-012-PsiThaCa) + (libraries + tezos-client-012-PsiThaCa + tezos_baking_012_PsiThaCa + tezos-baking-012-PsiThaCa.mockup-simulator + tezos-base-test-helpers + tezos-protocol-012-PsiThaCa-parameters + tezos-crypto + alcotest-lwt) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_micheline + -open Tezos_client_012_PsiThaCa + -open Tezos_protocol_012_PsiThaCa + -open Tezos_protocol_environment_012_PsiThaCa + -open Tezos_base_test_helpers + -open Tezos_012_PsiThaCa_mockup_simulator + -open Tezos_baking_012_PsiThaCa)) + (action (run %{exe:main.exe} -q -e))) + +(rule + (alias runtest_lint) + (deps (glob_files *.ml{,i})) + (action (run %{lib:tezos-tooling:lint.sh} %{deps}))) diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/main.ml b/src/proto_012_PsiThaCa/lib_delegate/test/main.ml new file mode 100644 index 000000000000..f05f721ebebb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/main.ml @@ -0,0 +1,10 @@ +(** Testing + ------- + Component: Baking + Invocation: dune build @src/proto_alpha/lib_delegate/runtest + Subject: Entrypoint + *) + +let () = + Lwt_main.run + (Alcotest_lwt.run "protocol_alpha" [("scenario", Test_scenario.tests)]) diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/.ocamlformat b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/broadcast_services.ml b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/broadcast_services.ml new file mode 100644 index 000000000000..deeffbf9f12e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/broadcast_services.ml @@ -0,0 +1,85 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module S = struct + open Data_encoding + + let path = RPC_path.(root / "broadcast") + + let dests_query = + let open RPC_query in + query (fun dests -> + object + method dests = dests + end) + |+ multi_field "dests" RPC_arg.int (fun t -> t#dests) + |> seal + + (* copied from lib_shell_services/injection_services.ml *) + let block_param = + obj2 + (req "block" (dynamic_size Block_header.encoding)) + (req + "operations" + (list (dynamic_size (list (dynamic_size Operation.encoding))))) + + let block = + RPC_service.post_service + ~description:"Broadcast a block." + ~query:dests_query + ~input:block_param + ~output:unit + RPC_path.(path / "block") + + let operation = + RPC_service.post_service + ~description:"Broadcast an operation." + ~query:dests_query + ~input:Alpha_context.Operation.encoding + ~output:unit + RPC_path.(path / "operation") +end + +open RPC_context + +let block ctxt ?(dests = []) raw operations = + make_call + S.block + ctxt + () + (object + method dests = dests + end) + (raw, operations) + +let operation ctxt ?(dests = []) operation = + make_call + S.operation + ctxt + () + (object + method dests = dests + end) + operation diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/dune b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/dune new file mode 100644 index 000000000000..c02523877354 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/dune @@ -0,0 +1,24 @@ +(library + (name tezos_012_PsiThaCa_mockup_simulator) + (public_name tezos-baking-012-PsiThaCa.mockup-simulator) + (libraries tezos-client-base-unix + tezos-client-commands + tezos-protocol-012-PsiThaCa + tezos-baking-012-PsiThaCa + tezos-mockup + tezos-mockup-proxy + tezos-mockup-commands) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -open Tezos_client_012_PsiThaCa + -open Tezos_client_commands + -open Tezos_baking_012_PsiThaCa + -open Tezos_stdlib_unix + -open Tezos_client_base_unix + -open Tezos_protocol_012_PsiThaCa_parameters + -open Tezos_protocol_012_PsiThaCa.Protocol))) + +(rule + (alias runtest_lint) + (deps (glob_files *.ml{,i})) + (action (run %{lib:tezos-tooling:lint.sh} %{deps}))) diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_client_context.ml b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_client_context.ml new file mode 100644 index 000000000000..d5e58d187999 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_client_context.ml @@ -0,0 +1,163 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Tezos_client_base + +let logger = + let log _channel msg = Lwt_fmt.printf "%s@." msg in + new Client_context.simple_printer log + +class dummy_prompter : Client_context.prompter = + object + method prompt : type a. (a, string tzresult) Client_context.lwt_format -> a + = + fun _msg -> assert false + + method prompt_password : type a. + (a, Bytes.t tzresult) Client_context.lwt_format -> a = + fun _msg -> assert false + + method multiple_password_retries = false + end + +let log _channel msg = + print_endline msg ; + Lwt.return_unit + +class faked_ctxt (hooks : Faked_services.hooks) (chain_id : Chain_id.t) : + RPC_context.json = + let local_ctxt = + let module Services = Faked_services.Make ((val hooks)) in + Tezos_mockup_proxy.RPC_client.local_ctxt (Services.directory chain_id) + in + object + method base = local_ctxt#base + + method generic_json_call meth ?body uri = + local_ctxt#generic_json_call meth ?body uri + + method generic_media_type_call meth ?body uri = + local_ctxt#generic_media_type_call meth ?body uri + + method call_service + : 'm 'p 'q 'i 'o. + (([< Resto.meth] as 'm), unit, 'p, 'q, 'i, 'o) RPC_service.t -> + 'p -> + 'q -> + 'i -> + 'o tzresult Lwt.t = + fun service params query body -> + local_ctxt#call_service service params query body + + method call_streamed_service + : 'm 'p 'q 'i 'o. + (([< Resto.meth] as 'm), unit, 'p, 'q, 'i, 'o) RPC_service.t -> + on_chunk:('o -> unit) -> + on_close:(unit -> unit) -> + 'p -> + 'q -> + 'i -> + (unit -> unit) tzresult Lwt.t = + fun service ~on_chunk ~on_close params query body -> + local_ctxt#call_streamed_service + service + ~on_chunk + ~on_close + params + query + body + end + +class faked_wallet ~base_dir ~filesystem : Client_context.wallet = + object (self) + method load_passwords = None + + method read_file fname = + match String.Hashtbl.find filesystem fname with + | None -> failwith "faked_wallet: cannot ead file (%s)" fname + | Some content -> return content + + method private filename alias_name = + Filename.concat + base_dir + (String.map (function ' ' -> '_' | c -> c) alias_name ^ "s") + + val lock_mutex = Lwt_mutex.create () + + method with_lock : type a. (unit -> a Lwt.t) -> a Lwt.t = + fun f -> Lwt_mutex.with_lock lock_mutex f + + method get_base_dir = base_dir + + method load : type a. + string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t = + fun alias_name ~default encoding -> + let filename = self#filename alias_name in + if not (String.Hashtbl.mem filesystem filename) then return default + else + self#read_file filename >>=? fun content -> + let json = (Ezjsonm.from_string content :> Data_encoding.json) in + match Data_encoding.Json.destruct encoding json with + | exception e -> + failwith + "did not understand the %s alias file %s : %s" + alias_name + filename + (Printexc.to_string e) + | data -> return data + + method write : type a. + string -> a -> a Data_encoding.encoding -> unit tzresult Lwt.t = + fun alias_name list encoding -> + let filename = self#filename alias_name in + let json = Data_encoding.Json.construct encoding list in + let str = Ezjsonm.value_to_string (json :> Ezjsonm.value) in + String.Hashtbl.replace filesystem filename str ; + return_unit + end + +class faked_io_wallet ~base_dir ~filesystem : Client_context.io_wallet = + object + inherit Client_context.simple_printer log + + inherit dummy_prompter + + inherit faked_wallet ~base_dir ~filesystem + end + +class unix_faked ~base_dir ~filesystem ~chain_id ~hooks : Client_context.full = + object + inherit faked_io_wallet ~base_dir ~filesystem + + inherit faked_ctxt hooks chain_id + + inherit Client_context_unix.unix_ui + + method chain = `Hash chain_id + + method block = `Head 0 + + method confirmations = None + end diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_daemon.ml b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_daemon.ml new file mode 100644 index 000000000000..1319d3df51d9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_daemon.ml @@ -0,0 +1,29 @@ +module Baker = struct + let run ~(cctxt : #Protocol_client_context.full) ~stop_on_event ~chain_id + ~(context_index : Abstract_context_index.t) ~delegates = + let chain = `Hash chain_id in + let baking_configuration = + let open Baking_configuration in + { + default_config with + validation = ContextIndex context_index; + state_recorder = Disabled; + } + in + (* By default errors are simply printed but the baker won't stop + because of them. This is not what we want for testing. Here we force + the baker to terminate unsuccessfully if an error occurs. *) + let canceler = Lwt_canceler.create () in + let on_error (err : error trace) = + Lwt_canceler.cancel canceler >>= fun _ -> + failwith "%a" Error_monad.pp_print_trace err + in + Baking_scheduling.run + cctxt + ~canceler + ~stop_on_event + ~on_error + ~chain + baking_configuration + delegates +end diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_services.ml b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_services.ml new file mode 100644 index 000000000000..392600503c55 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/faked_services.ml @@ -0,0 +1,295 @@ +open Tezos_shell_services +module Directory = Tezos_rpc.RPC_directory +module Chain_services = Tezos_shell_services.Chain_services +module Block_services = Tezos_shell_services.Block_services +module Block_services_alpha = Protocol_client_context.Alpha_block_services + +module type Mocked_services_hooks = sig + type mempool = Mockup.M.Block_services.Mempool.t + + (** The baker and endorser rely on this stream to be notified of new + blocks. *) + val monitor_heads : unit -> (Block_hash.t * Block_header.t) RPC_answer.stream + + (** Returns current and next protocol for a block. *) + val protocols : + Block_services.block -> Block_services.protocols tzresult Lwt.t + + (** [header] returns the block header of the block associated to the given + block specification. *) + val header : + Block_services.block -> Mockup.M.Block_services.block_header tzresult Lwt.t + + (** [operations] returns all operations included in the block. *) + val operations : + Block_services.block -> + Mockup.M.Block_services.operation list list tzresult Lwt.t + + (** [inject_block_callback] is called when an RPC is performed on + [Tezos_shell_services.Injection_services.S.block], after checking that + the block header can be deserialized. *) + val inject_block : + Block_hash.t -> + Block_header.t -> + Operation.t trace trace -> + unit tzresult Lwt.t + + (** [inject_operation] is used by the endorser (or the client) to inject + operations, including endorsements. *) + val inject_operation : Operation.t -> Operation_hash.t tzresult Lwt.t + + (** [pending_operations] returns the current contents of the mempool. It + is used by the baker to fetch operations to potentially include in the + block being baked. These operations might include endorsements. If + there aren't enough endorsements, the baker waits on + [monitor_operations]. *) + val pending_operations : unit -> mempool Lwt.t + + (** Return a stream of list of operations. Used by the baker to wait on + endorsements. Invariant: the stream becomes empty when the node changes + head. *) + val monitor_operations : + applied:bool -> + branch_delayed:bool -> + branch_refused:bool -> + refused:bool -> + ((Operation_hash.t * Mockup.M.Protocol.operation) * error list) list + RPC_answer.stream + + (** Lists block hashes from the chain, up to the last checkpoint, sorted + with decreasing fitness. Without arguments it returns the head of the + chain. Optional arguments allow to return the list of predecessors of a + given block or of a set of blocks. *) + val list_blocks : + heads:Block_hash.t list -> + length:int option -> + min_date:Time.Protocol.t option -> + Block_hash.t list list tzresult Lwt.t + + (** List the ancestors of the given block which, if referred to as + the branch in an operation header, are recent enough for that + operation to be included in the current block. *) + val live_blocks : Block_services.block -> Block_hash.Set.t tzresult Lwt.t + + (** [rpc_context_callback] is used in the implementations of several + RPCs (see local_services.ml). It should correspond to the + rpc_context constructed from the context at the requested block. *) + val rpc_context_callback : + Block_services.block -> Environment_context.rpc_context tzresult Lwt.t + + (** Return raw protocol data as a block. *) + val raw_protocol_data : Block_services.block -> Bytes.t tzresult Lwt.t + + (** Broadcast block manually to nodes [dests] (given by their + number, starting from 0). If [dests] is not provided, broadcast + to all nodes. *) + val broadcast_block : + ?dests:int list -> + Block_hash.t -> + Block_header.t -> + Operation.t trace trace -> + unit tzresult Lwt.t + + (** Broadcast operation manually to nodes [dests] (given by their + number, starting from 0). If [dests] is not provided, broadcast + to all nodes. *) + val broadcast_operation : + ?dests:int list -> Alpha_context.packed_operation -> unit tzresult Lwt.t + + (** Simulate waiting for the node to be bootstrapped. Because the + simulated node is already bootstrapped, returns the current head + immediately. *) + val monitor_bootstrapped : + unit -> (Block_hash.t * Time.Protocol.t) RPC_answer.stream +end + +type hooks = (module Mocked_services_hooks) + +module Make (Hooks : Mocked_services_hooks) = struct + let monitor_heads = + Directory.gen_register1 + Directory.empty + Monitor_services.S.heads + (fun _chain _next_protocol () -> + RPC_answer.return_stream (Hooks.monitor_heads ())) + + let monitor_bootstrapped = + Directory.gen_register0 + Directory.empty + Monitor_services.S.bootstrapped + (fun () () -> RPC_answer.return_stream (Hooks.monitor_bootstrapped ())) + + let protocols = + let path = + let open Tezos_rpc.RPC_path in + prefix Block_services.chain_path Block_services.path + in + let service = + Tezos_rpc.RPC_service.prefix path Block_services.Empty.S.protocols + in + Directory.register Directory.empty service (fun (_, block) () () -> + Hooks.protocols block) + + let header = + Directory.prefix + (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) + @@ Directory.register + Directory.empty + Mockup.M.Block_services.S.header + (fun (((), _chain), block) _ _ -> Hooks.header block) + + let operations = + Directory.prefix + (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) + @@ Directory.register + Directory.empty + Mockup.M.Block_services.S.Operations.operations + (fun (((), _chain), block) () () -> Hooks.operations block) + + let hash = + Directory.prefix + (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) + @@ Directory.register + Directory.empty + Block_services.Empty.S.hash + (fun (((), _chain), block) () () -> + Hooks.header block >>=? fun x -> return x.hash) + + let shell_header = + Directory.prefix + (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) + @@ Directory.register + Directory.empty + Mockup.M.Block_services.S.Header.shell_header + (fun (((), _chain), block) _ _ -> + Hooks.header block >>=? fun x -> return x.shell) + + let chain chain_id = + Directory.prefix + Chain_services.path + (Directory.register + Directory.empty + Chain_services.S.chain_id + (fun _chain () () -> return chain_id)) + + let inject_block = + Directory.register + Directory.empty + Injection_services.S.block + (fun () _chain (bytes, operations) -> + match Block_header.of_bytes bytes with + | None -> failwith "faked_services.inject_block: can't deserialize" + | Some block_header -> + let block_hash = Block_hash.hash_bytes [bytes] in + Hooks.inject_block block_hash block_header operations >>=? fun () -> + return block_hash) + + let inject_operation = + Directory.register + Directory.empty + Injection_services.S.operation + (fun () _chain bytes -> + match Data_encoding.Binary.of_bytes_opt Operation.encoding bytes with + | None -> failwith "faked_services.inject_operation: can't deserialize" + | Some operation -> Hooks.inject_operation operation) + + let broadcast_block = + Directory.register + Directory.empty + Broadcast_services.S.block + (fun () dests (block_header, operations) -> + let bytes = Block_header.to_bytes block_header in + let block_hash = Block_hash.hash_bytes [bytes] in + let dests = match dests#dests with [] -> None | dests -> Some dests in + Hooks.broadcast_block ?dests block_hash block_header operations) + + let broadcast_operation = + Directory.register + Directory.empty + Broadcast_services.S.operation + (fun () dests operation -> + let dests = match dests#dests with [] -> None | dests -> Some dests in + Hooks.broadcast_operation ?dests operation) + + let pending_operations = + Directory.gen_register + Directory.empty + (Mockup.M.Block_services.S.Mempool.pending_operations + @@ Block_services.mempool_path Block_services.chain_path) + (fun ((), _chain) _params () -> + Hooks.pending_operations () >>= fun mempool -> + Mockup.M.Block_services.Mempool.pending_operations_version_dispatcher + ~version:1 + mempool) + + let monitor_operations = + Directory.gen_register + Directory.empty + (Block_services_alpha.S.Mempool.monitor_operations + @@ Block_services.mempool_path Block_services.chain_path) + (fun ((), _chain) flags () -> + let stream = + Hooks.monitor_operations + ~applied:flags#applied + ~branch_delayed:flags#branch_delayed + ~branch_refused:flags#branch_refused + ~refused:flags#refused + in + RPC_answer.return_stream stream) + + let list_blocks = + Directory.prefix + Chain_services.path + (Directory.register + Directory.empty + Chain_services.S.Blocks.list + (fun ((), _chain) flags () -> + Hooks.list_blocks + ~heads:flags#heads + ~length:flags#length + ~min_date:flags#min_date)) + + let live_blocks = + Directory.prefix + (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) + @@ Directory.register + Directory.empty + Block_services.Empty.S.live_blocks + (fun (_, block) _ () -> Hooks.live_blocks block) + + let raw_protocol_data = + Directory.prefix + (Tezos_rpc.RPC_path.prefix Chain_services.path Block_services.path) + @@ Directory.register + Directory.empty + Block_services.Empty.S.Header.raw_protocol_data + (fun (_, block) () () -> Hooks.raw_protocol_data block) + + let shell_directory chain_id = + let merge = Directory.merge in + Directory.empty |> merge monitor_heads |> merge protocols |> merge header + |> merge operations |> merge hash |> merge shell_header + |> merge (chain chain_id) + |> merge inject_block |> merge inject_operation |> merge monitor_operations + |> merge list_blocks |> merge live_blocks |> merge raw_protocol_data + |> merge broadcast_block |> merge broadcast_operation + |> merge monitor_bootstrapped + + let directory chain_id = + let proto_directory = + Directory.prefix + Chain_services.path + (Directory.prefix + Block_services.path + (Directory.map + (fun (((), _chain), block) -> + Hooks.rpc_context_callback block >>= function + | Error _ -> assert false + | Ok rpc_context -> Lwt.return rpc_context) + Mockup.M.directory)) + in + let base = Directory.merge (shell_directory chain_id) proto_directory in + RPC_directory.register_describe_directory_service + base + RPC_service.description_service +end diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/mockup_simulator.ml b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/mockup_simulator.ml new file mode 100644 index 000000000000..38467f3ebc82 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/mockup_simulator.ml @@ -0,0 +1,1285 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type block = { + rpc_context : Environment_context.rpc_context; + protocol_data : Protocol.Alpha_context.Block_header.protocol_data; + raw_protocol_data : Bytes.t; + operations : Mockup.M.Block_services.operation list list; +} + +type chain = block list + +(** As new blocks and operations are received they are pushed to an Lwt_pipe + wrapped into this type. *) +type broadcast = + | Broadcast_block of Block_hash.t * Block_header.t * Operation.t list list + | Broadcast_op of Operation_hash.t * Alpha_context.packed_operation + +(** The state of a mockup node. *) +type state = { + instance_index : int; + (** Index of this node. Indices go from 0 to N-1 where N is the total + number of bakers in the simulation. *) + live_depth : int; + (** How many blocks (counting from the head into the past) are considered live? *) + mutable chain : chain; (** The chain as seen by this fake "node". *) + mutable mempool : (Operation_hash.t * Mockup.M.Protocol.operation) list; + (** Mempool of this fake "node". *) + chain_table : chain Block_hash.Table.t; + (** The chain table of this fake "node". It maps from block hashes to + blocks. *) + global_chain_table : block Block_hash.Table.t; + (** The global chain table that allows us to look up blocks that may be + missing in [chain_table], i.e. not known to this particular node. This + is used to find unknown predecessors. The real node can ask about an + unknown block and receive it on request, this is supposed to emulate + that functionality. *) + ctxt_table : Environment_context.rpc_context Context_hash.Table.t; + (** The context table allows us to look up rpc_context by its hash. *) + heads_pipe : (Block_hash.t * Block_header.t) Lwt_pipe.Unbounded.t; + (** [heads_pipe] is used to implement the [monitor_heads] RPC. *) + operations_pipe : + (Operation_hash.t * Mockup.M.Protocol.operation) option Lwt_pipe.Unbounded.t; + (** [operations_pipe] is used to implement the [operations_pipe] RPC. *) + mutable streaming_operations : bool; + (** A helper flag used to implement the monitor operations RPC. *) + broadcast_pipes : broadcast Lwt_pipe.Unbounded.t list; + (** Broadcast pipes per node. *) + genesis_block_true_hash : Block_hash.t; + (** True hash of the genesis + block as calculated by the + [Block_header.hash] function. *) +} + +let accounts = Mockup.Protocol_parameters.default_value.bootstrap_accounts + +let chain_id = Chain_id.of_string_exn "main" + +let genesis_block_hash = + Block_hash.of_b58check_exn + "BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU" + +let genesis_predecessor_block_hash = Block_hash.zero + +type propagation = Block | Pass | Delay of float + +type propagation_vector = propagation list + +module type Hooks = sig + val on_inject_block : + level:int32 -> + round:int32 -> + block_hash:Block_hash.t -> + block_header:Block_header.t -> + operations:Operation.t list list -> + protocol_data:Alpha_context.Block_header.protocol_data -> + (Block_hash.t * Block_header.t * Operation.t list list * propagation_vector) + tzresult + Lwt.t + + val on_inject_operation : + op_hash:Operation_hash.t -> + op:Alpha_context.packed_operation -> + (Operation_hash.t * Alpha_context.packed_operation * propagation_vector) + tzresult + Lwt.t + + val on_new_head : + block_hash:Block_hash.t -> + block_header:Block_header.t -> + (Block_hash.t * Block_header.t) option Lwt.t + + val on_new_operation : + Operation_hash.t * Alpha_context.packed_operation -> + (Operation_hash.t * Alpha_context.packed_operation) option Lwt.t + + val check_block_before_processing : + level:int32 -> + round:int32 -> + block_hash:Block_hash.t -> + block_header:Block_header.t -> + protocol_data:Alpha_context.Block_header.protocol_data -> + unit tzresult Lwt.t + + val check_chain_after_processing : + level:int32 -> round:int32 -> chain:chain -> unit tzresult Lwt.t + + val check_mempool_after_processing : + mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> + unit tzresult Lwt.t + + val stop_on_event : Baking_state.event -> bool + + val on_start_baker : + baker_position:int -> + delegates:Baking_state.delegate list -> + cctxt:Protocol_client_context.full -> + unit Lwt.t + + val check_chain_on_success : chain:chain -> unit tzresult Lwt.t +end + +(** Return a series of blocks starting from the block with the given + identifier. *) +let locate_blocks (state : state) + (block : Tezos_shell_services.Block_services.block) : + block list tzresult Lwt.t = + match block with + | `Hash (hash, rel) -> ( + match Block_hash.Table.find state.chain_table hash with + | None -> + failwith "locate_blocks: can't find the block %a" Block_hash.pp hash + | Some chain0 -> + let (_, chain) = List.split_n rel chain0 in + return chain) + | `Head rel -> + let (_, chain) = List.split_n rel state.chain in + return chain + | `Level _ -> failwith "locate_blocks: `Level block spec not handled" + | `Genesis -> failwith "locate_blocks: `Genesis block spec net handled" + | `Alias _ -> failwith "locate_blocks: `Alias block spec not handled" + +(** Similar to [locate_blocks], but only returns the first block. *) +let locate_block (state : state) + (block : Tezos_shell_services.Block_services.block) : block tzresult Lwt.t = + locate_blocks state block >>=? function + | [] -> failwith "locate_block: can't find the block" + | x :: _ -> return x + +(** Return the collection of live blocks for a given block identifier. *) +let live_blocks (state : state) block = + locate_blocks state block >>=? fun chain -> + let (segment, _) = List.split_n state.live_depth chain in + return + (List.fold_left + (fun set ({rpc_context; _} : block) -> + let hash = rpc_context.Environment_context.block_hash in + Block_hash.Set.add hash set) + (Block_hash.Set.singleton state.genesis_block_true_hash) + segment) + +(** Extract the round number from raw fitness. *) +let round_from_raw_fitness raw_fitness = + match Protocol.Alpha_context.Fitness.from_raw raw_fitness with + | Ok fitness -> + return + (Alpha_context.Round.to_int32 + (Protocol.Alpha_context.Fitness.round fitness)) + | Error _ -> failwith "round_from_raw_fitness: cannot parse fitness" + +(** Extract level from a block header. *) +let get_block_level (block_header : Block_header.t) = + return block_header.shell.level + +(** Extract round from a block header. *) +let get_block_round (block_header : Block_header.t) = + round_from_raw_fitness block_header.shell.fitness + +(** Parse protocol data. *) +let parse_protocol_data (protocol_data : Bytes.t) = + match + Data_encoding.Binary.of_bytes_opt + Protocol.Alpha_context.Block_header.protocol_data_encoding + protocol_data + with + | None -> failwith "can't parse protocol data of a block" + | Some parsed_protocol_data -> return parsed_protocol_data + +(** Broadcast an operation or block according to the given propagation + vector. *) +let handle_propagation msg propagation_vector broadcast_pipes = + List.iter_s + (fun (propagation, pipe) -> + match propagation with + | Block -> Lwt.return () + | Pass -> + Lwt_pipe.Unbounded.push pipe msg ; + Lwt.return_unit + | Delay s -> + Lwt.dont_wait + (fun () -> + Lwt_unix.sleep s >>= fun () -> + Lwt_pipe.Unbounded.push pipe msg ; + Lwt.return_unit) + (fun _exn -> ()) ; + Lwt.return ()) + (List.combine_drop propagation_vector broadcast_pipes) + >>= fun () -> return () + +(** Use the [user_hooks] to produce a module of functions that will perform + the heavy lifting for the RPC implementations. *) +let make_mocked_services_hooks (state : state) (user_hooks : (module Hooks)) : + Faked_services.hooks = + let module User_hooks = (val user_hooks : Hooks) in + let module Impl : Faked_services.Mocked_services_hooks = struct + type mempool = Mockup.M.Block_services.Mempool.t + + let monitor_heads () = + let next () = + let rec pop_until_ok () = + Lwt_pipe.Unbounded.pop state.heads_pipe + >>= fun (block_hash, block_header) -> + User_hooks.on_new_head ~block_hash ~block_header >>= function + | None -> pop_until_ok () + | Some head -> Lwt.return_some head + in + pop_until_ok () + in + let shutdown () = () in + RPC_answer.{next; shutdown} + + let monitor_bootstrapped () = + let first_run = ref true in + let next () = + if !first_run then ( + first_run := false ; + let b = match state.chain with [] -> assert false | b :: _ -> b in + let head_hash = b.rpc_context.block_hash in + let timestamp = b.rpc_context.block_header.timestamp in + Lwt.return_some (head_hash, timestamp)) + else Lwt.return_none + in + let shutdown () = () in + RPC_answer.{next; shutdown} + + let protocols (block : Tezos_shell_services.Block_services.block) = + locate_block state block >>=? fun x -> + let hash = x.rpc_context.block_hash in + let is_predecessor_of_genesis = + match block with + | `Hash (requested_hash, rel) -> + Int.equal rel 0 + && Block_hash.equal requested_hash genesis_predecessor_block_hash + | _ -> false + in + (* It is important to tell the baker that the genesis block is not in + the alpha protocol (we use Protocol_hash.zero). This will make the + baker not try to propose alternatives to that block and just accept + it as final in that Protocol_hash.zero protocol. The same for + predecessor of genesis, it should be in Protocol_hash.zero. *) + return + Tezos_shell_services.Block_services. + { + current_protocol = + (if + Block_hash.equal hash genesis_block_hash + || is_predecessor_of_genesis + then Protocol_hash.zero + else Protocol.hash); + next_protocol = + (if is_predecessor_of_genesis then Protocol_hash.zero + else Protocol.hash); + } + + let header (block : Tezos_shell_services.Block_services.block) : + Mockup.M.Block_services.block_header tzresult Lwt.t = + locate_block state block >>=? fun x -> + return + { + Mockup.M.Block_services.hash = x.rpc_context.block_hash; + chain_id; + shell = x.rpc_context.block_header; + protocol_data = x.protocol_data; + } + + let operations block = + locate_block state block >>=? fun x -> return x.operations + + let inject_block block_hash (block_header : Block_header.t) operations = + parse_protocol_data block_header.protocol_data >>=? fun protocol_data -> + get_block_level block_header >>=? fun level -> + get_block_round block_header >>=? fun round -> + User_hooks.on_inject_block + ~level + ~round + ~block_hash + ~block_header + ~operations + ~protocol_data + >>=? fun (block_hash1, block_header1, operations1, propagation_vector) -> + handle_propagation + (Broadcast_block (block_hash1, block_header1, operations1)) + propagation_vector + state.broadcast_pipes + + let all_pipes_or_select = function + | None -> return state.broadcast_pipes + | Some l -> + List.map_es + (fun n -> + match List.nth_opt state.broadcast_pipes n with + | None -> + failwith + "Node number %d is out of range (max is %d)" + n + (List.length state.broadcast_pipes - 1) + | Some pipe -> return pipe) + l + + let broadcast_block ?dests block_hash (block_header : Block_header.t) + operations = + all_pipes_or_select dests >>=? fun pipes -> + List.iter_s + (fun pipe -> + Lwt_pipe.Unbounded.push + pipe + (Broadcast_block (block_hash, block_header, operations)) ; + Lwt.return ()) + pipes + >>= return + + let inject_operation (Operation.{shell; proto} as op) = + let op_hash = Operation.hash op in + let proto_op_opt = + Data_encoding.Binary.of_bytes Protocol.operation_data_encoding proto + in + match proto_op_opt with + | Error _ -> failwith "inject_operation: cannot parse operation" + | Ok protocol_data -> + let op : Protocol.Alpha_context.packed_operation = + {shell; protocol_data} + in + User_hooks.on_inject_operation ~op_hash ~op + >>=? fun (op_hash1, op1, propagation_vector) -> + handle_propagation + (Broadcast_op (op_hash1, op1)) + propagation_vector + state.broadcast_pipes + >>=? fun () -> return op_hash1 + + let broadcast_operation ?dests + (op : Protocol.Alpha_context.packed_operation) = + all_pipes_or_select dests >>=? fun pipes -> + let op_hash = Alpha_context.Operation.hash_packed op in + List.iter_s + (fun pipe -> + Lwt_pipe.Unbounded.push pipe (Broadcast_op (op_hash, op)) ; + Lwt.return ()) + pipes + >>= return + + let pending_operations () = + let ops = state.mempool in + Lwt.return + Mockup.M.Block_services.Mempool. + { + applied = ops; + refused = Operation_hash.Map.empty; + outdated = Operation_hash.Map.empty; + branch_refused = Operation_hash.Map.empty; + branch_delayed = Operation_hash.Map.empty; + unprocessed = Operation_hash.Map.empty; + } + + let monitor_operations ~applied ~branch_delayed ~branch_refused ~refused = + ignore applied ; + ignore branch_delayed ; + ignore branch_refused ; + ignore refused ; + let streamed = ref false in + state.streaming_operations <- true ; + let next () = + let rec pop_until_ok () = + Lwt_pipe.Unbounded.pop state.operations_pipe >>= function + | None when !streamed -> Lwt.return None + | None -> + streamed := true ; + Lwt.return (Some []) + | Some op -> ( + User_hooks.on_new_operation op >>= function + | None when !streamed -> pop_until_ok () + | None -> + streamed := true ; + Lwt.return (Some []) + | Some (oph, op) -> + streamed := true ; + Lwt.return (Some [((oph, op), [])])) + in + pop_until_ok () + in + let shutdown () = () in + RPC_answer.{next; shutdown} + + let rpc_context_callback block = + locate_block state block >>=? fun x -> return x.rpc_context + + let list_blocks ~heads ~length ~min_date:_ = + let compare_block_fitnesses block0 block1 = + Fitness.compare + block0.rpc_context.block_header.fitness + block1.rpc_context.block_header.fitness + in + let hash_of_block block = block.rpc_context.block_hash in + let lookup_head head = + locate_blocks state (`Hash (head, 0)) >>=? fun xs -> + let segment = + match length with None -> xs | Some n -> List.take_n n xs + in + return + (List.map hash_of_block (List.sort compare_block_fitnesses segment)) + in + List.map_es lookup_head heads + + let live_blocks block = live_blocks state block + + let raw_protocol_data block = + locate_block state block >>=? fun x -> return x.raw_protocol_data + end in + (module Impl) + +(** Return the current head. *) +let head {chain; _} = + match List.hd chain with + | None -> failwith "mockup_simulator.ml: empty chain" + | Some hd -> return hd + +(** Clear from the mempool operations whose branch does not point to + a live block with respect to the current head. *) +let clear_mempool state = + head state >>=? fun head -> + let included_ops_hashes = + List.map + (fun (op : Mockup.M.Block_services.operation) -> op.hash) + (List.flatten head.operations) + in + live_blocks state (`Head 0) >>=? fun live_set -> + let mempool = + List.filter + (fun (_oph, (op : Mockup.M.Protocol.operation)) -> + let included_in_head = + List.mem + ~equal:Operation_hash.equal + (Alpha_context.Operation.hash_packed op) + included_ops_hashes + in + Block_hash.Set.mem op.shell.branch live_set && not included_in_head) + state.mempool + in + state.mempool <- mempool ; + return_unit + +(** Apply a block to the given [rpc_context]. *) +let reconstruct_context (rpc_context : Tezos_protocol_environment.rpc_context) + (operations : Operation.t list list) (block_header : Block_header.t) = + let header = rpc_context.block_header in + let predecessor_context = rpc_context.context in + parse_protocol_data block_header.protocol_data >>=? fun protocol_data -> + Mockup.M.Protocol.begin_application + ~chain_id + ~predecessor_context + ~predecessor_timestamp:header.timestamp + ~predecessor_fitness:header.fitness + ~cache:`Lazy + {shell = block_header.shell; protocol_data} + >>=? fun validation_state -> + let i = ref 0 in + List.fold_left_es + (List.fold_left_es (fun (validation_state, results) op -> + incr i ; + let operation_data = + Data_encoding.Binary.of_bytes_exn + Mockup.M.Protocol.operation_data_encoding + op.Operation.proto + in + let op = + {Mockup.M.Protocol.shell = op.shell; protocol_data = operation_data} + in + Mockup.M.Protocol.apply_operation validation_state op + >>=? fun (validation_state, receipt) -> + return (validation_state, receipt :: results))) + (validation_state, []) + operations + >>=? fun (validation_state, _) -> + Mockup.M.Protocol.finalize_block validation_state None + +(** Process an incoming block. If validation succeeds: + - update the current head to this new block + - cleanup outdated operations + - cleanup listener table + Note that this implementation does not handle concurrent branches. *) +let rec process_block state block_hash (block_header : Block_header.t) + operations = + let get_predecessor () = + let predecessor_hash = block_header.Block_header.shell.predecessor in + head state >>=? fun head -> + match Block_hash.Table.find state.chain_table predecessor_hash with + | None | Some [] -> ( + (* Even if the predecessor is not known locally, it might be known by + some node in the network. The code below "requests" information + about the block by its hash. *) + match + Block_hash.Table.find state.global_chain_table predecessor_hash + with + | None -> failwith "get_predecessor: unknown predecessor block" + | Some predecessor -> + let predecessor_block_header = + Block_header. + { + shell = predecessor.rpc_context.block_header; + protocol_data = predecessor.raw_protocol_data; + } + in + let predecessor_ops = + List.map + (fun xs -> + List.map + (fun (op : Mockup.M.Block_services.operation) -> + Operation. + { + shell = op.shell; + proto = + Data_encoding.Binary.to_bytes_exn + Protocol.operation_data_encoding + op.protocol_data; + }) + xs) + predecessor.operations + in + (* If the block is found, apply it before proceeding. *) + process_block + state + predecessor.rpc_context.block_hash + predecessor_block_header + predecessor_ops + >>=? fun () -> return predecessor) + | Some (predecessor :: _) -> + if + Int32.sub + head.rpc_context.block_header.level + predecessor.rpc_context.block_header.level + <= 2l + then return predecessor + else failwith "get_predecessor: the predecessor block is too old" + in + match Block_hash.Table.find state.chain_table block_hash with + | Some _ -> + (* The block is already known. *) + return_unit + | None -> + get_predecessor () >>=? fun predecessor -> + head state >>=? fun head -> + reconstruct_context predecessor.rpc_context operations block_header + >>=? fun ({context; _}, _) -> + let rpc_context = + Tezos_protocol_environment. + {context; block_hash; block_header = block_header.shell} + in + let operations = + List.map + (fun pass -> + List.map + (fun (Operation.{shell; proto} as op) -> + let hash : Operation_hash.t = Operation.hash op in + let protocol_data : Alpha_context.packed_protocol_data = + Data_encoding.Binary.of_bytes_exn + Protocol.operation_data_encoding + proto + in + let receipt = None in + { + Mockup.M.Block_services.chain_id; + hash; + shell; + protocol_data; + receipt; + }) + pass) + operations + in + parse_protocol_data block_header.protocol_data >>=? fun protocol_data -> + let new_block = + { + rpc_context; + protocol_data; + raw_protocol_data = block_header.protocol_data; + operations; + } + in + let predecessor_hash = block_header.Block_header.shell.predecessor in + let tail = + Block_hash.Table.find state.chain_table predecessor_hash + |> WithExceptions.Option.get ~loc:__LOC__ + in + let new_chain = new_block :: tail in + Block_hash.Table.replace state.chain_table block_hash new_chain ; + Block_hash.Table.replace state.global_chain_table block_hash new_block ; + Context_hash.Table.replace + state.ctxt_table + rpc_context.Environment_context.block_header.context + rpc_context ; + if + Fitness.( + block_header.shell.fitness > head.rpc_context.block_header.fitness) + then ( + state.chain <- new_chain ; + clear_mempool state >>=? fun () -> + (* The head has changed, the messages in the operations pipe are no + good anymore. *) + ignore (Lwt_pipe.Unbounded.pop_all_now state.operations_pipe) ; + (if state.streaming_operations then ( + state.streaming_operations <- false ; + Lwt_pipe.Unbounded.push state.operations_pipe None ; + Lwt.return ()) + else Lwt.return ()) + >>= fun () -> + (* Put back in the pipe operations that are still alive. *) + List.iter_s + (fun op -> + Lwt_pipe.Unbounded.push state.operations_pipe (Some op) ; + Lwt.return ()) + state.mempool + >>= fun () -> return_unit) + else return_unit + +(** This process listens to broadcast block and operations and incorporates + them in the context of the fake node. *) +let rec listener ~(user_hooks : (module Hooks)) ~state ~broadcast_pipe = + let module User_hooks = (val user_hooks : Hooks) in + Lwt_pipe.Unbounded.pop broadcast_pipe >>= function + | Broadcast_op (operation_hash, packed_operation) -> + state.mempool <- (operation_hash, packed_operation) :: state.mempool ; + Lwt_pipe.Unbounded.push + state.operations_pipe + (Some (operation_hash, packed_operation)) ; + User_hooks.check_mempool_after_processing ~mempool:state.mempool + >>=? fun () -> listener ~user_hooks ~state ~broadcast_pipe + | Broadcast_block (block_hash, block_header, operations) -> + get_block_level block_header >>=? fun level -> + get_block_round block_header >>=? fun round -> + parse_protocol_data block_header.protocol_data >>=? fun protocol_data -> + User_hooks.check_block_before_processing + ~level + ~round + ~block_hash + ~block_header + ~protocol_data + >>=? fun () -> + process_block state block_hash block_header operations >>=? fun () -> + User_hooks.check_chain_after_processing ~level ~round ~chain:state.chain + >>=? fun () -> + Lwt_pipe.Unbounded.push state.heads_pipe (block_hash, block_header) ; + listener ~user_hooks ~state ~broadcast_pipe + +(** Create a fake node state. *) +let create_fake_node_state ~i ~live_depth + ~(genesis_block : Block_header.t * Environment_context.rpc_context) + ~global_chain_table ~broadcast_pipes = + let (block_header0, rpc_context0) = genesis_block in + parse_protocol_data block_header0.protocol_data >>=? fun protocol_data -> + let genesis0 = + { + rpc_context = rpc_context0; + protocol_data; + raw_protocol_data = block_header0.protocol_data; + operations = [[]; []; []; []]; + } + in + let chain0 = [genesis0] in + let heads_pipe = Lwt_pipe.Unbounded.create () in + let operations_pipe = Lwt_pipe.Unbounded.create () in + let genesis_block_true_hash = + Block_header.hash + { + shell = rpc_context0.block_header; + protocol_data = block_header0.protocol_data; + } + in + Lwt_pipe.Unbounded.push heads_pipe (rpc_context0.block_hash, block_header0) ; + return + { + instance_index = i; + live_depth; + mempool = []; + chain = chain0; + chain_table = + Block_hash.Table.of_seq + (List.to_seq + [ + (rpc_context0.block_hash, chain0); + (genesis_block_true_hash, chain0); + (genesis_predecessor_block_hash, chain0); + ]); + global_chain_table; + ctxt_table = + Context_hash.Table.of_seq + (List.to_seq + [ + ( rpc_context0.Environment_context.block_header + .Block_header.context, + rpc_context0 ); + ]); + heads_pipe; + operations_pipe; + streaming_operations = false; + broadcast_pipes; + genesis_block_true_hash; + } + +(** Start baker process. *) +let baker_process ~(delegates : Baking_state.delegate list) ~base_dir + ~(genesis_block : Block_header.t * Environment_context.rpc_context) ~i + ~global_chain_table ~broadcast_pipes ~(user_hooks : (module Hooks)) = + let broadcast_pipe = + List.nth broadcast_pipes i |> WithExceptions.Option.get ~loc:__LOC__ + in + create_fake_node_state + ~i + ~live_depth:60 + ~genesis_block + ~global_chain_table + ~broadcast_pipes + >>=? fun state -> + let filesystem = String.Hashtbl.create 10 in + let wallet = new Faked_client_context.faked_io_wallet ~base_dir ~filesystem in + let cctxt = + let hooks = make_mocked_services_hooks state user_hooks in + new Protocol_client_context.wrap_full + (new Faked_client_context.unix_faked + ~base_dir + ~filesystem + ~chain_id + ~hooks) + in + let module User_hooks = (val user_hooks : Hooks) in + User_hooks.on_start_baker ~baker_position:i ~delegates ~cctxt >>= fun () -> + List.iter_es + (fun ({alias; public_key; public_key_hash; secret_key_uri} : + Baking_state.delegate) -> + let open Tezos_client_base in + let name = alias |> WithExceptions.Option.get ~loc:__LOC__ in + Client_keys.neuterize secret_key_uri >>=? fun public_key_uri -> + Client_keys.register_key + wallet + ~force:false + (public_key_hash, public_key_uri, secret_key_uri) + ~public_key + name) + delegates + >>=? fun () -> + let context_index = + let open Abstract_context_index in + { + checkout_fun = + (fun hash -> + Context_hash.Table.find state.ctxt_table hash + |> Option.map (fun Environment_context.{context; _} -> context) + |> Lwt.return); + finalize_fun = Lwt.return; + } + in + let module User_hooks = (val user_hooks : Hooks) in + let listener_process () = listener ~user_hooks ~state ~broadcast_pipe in + let stop_on_event event = User_hooks.stop_on_event event in + let baker_process () = + Faked_daemon.Baker.run + ~cctxt + ~stop_on_event + ~chain_id + ~context_index + ~delegates + in + Lwt.pick [listener_process (); baker_process ()] >>=? fun () -> + User_hooks.check_chain_on_success ~chain:state.chain + +let genesis_protocol_data (baker_sk : Signature.secret_key) + (predecessor_block_hash : Block_hash.t) + (block_header : Block_header.shell_header) : Bytes.t = + let proof_of_work_nonce = + Bytes.create Protocol.Alpha_context.Constants.proof_of_work_nonce_size + in + let operation_list_hash = Operation_list_hash.compute [] in + let payload_hash = + Protocol.Alpha_context.Block_payload.hash + ~predecessor:predecessor_block_hash + Alpha_context.Round.zero + operation_list_hash + in + let contents = + Protocol.Alpha_context.Block_header. + { + payload_hash; + payload_round = Alpha_context.Round.zero; + proof_of_work_nonce; + seed_nonce_hash = None; + liquidity_baking_escape_vote = + Baking_configuration.default_liquidity_baking_escape_vote; + } + in + let unsigned_header = + Data_encoding.Binary.to_bytes_exn + Protocol.Alpha_context.Block_header.unsigned_encoding + (block_header, contents) + in + let signature = + Signature.sign + ~watermark: + Alpha_context.Block_header.(to_watermark (Block_header chain_id)) + baker_sk + unsigned_header + in + Data_encoding.Binary.to_bytes_exn + Protocol.Alpha_context.Block_header.protocol_data_encoding + {contents; signature} + +(** Figure out who should be the signer for the genesis block. *) +let deduce_baker_sk + (accounts_with_secrets : + (Protocol.Alpha_context.Parameters.bootstrap_account + * Tezos_mockup_commands.Mockup_wallet.bootstrap_secret) + list) (total_accounts : int) (level : int) : + Signature.secret_key tzresult Lwt.t = + (match (total_accounts, level) with + | (_, 0) -> return 0 (* apparently this doesn't really matter *) + | _ -> + failwith + "cannot deduce baker for a genesis block, total accounts = %d, level = \ + %d" + total_accounts + level) + >>=? fun baker_index -> + let (_, secret) = + List.nth accounts_with_secrets baker_index + |> WithExceptions.Option.get ~loc:__LOC__ + in + let secret_key = + Signature.Secret_key.of_b58check_exn (Uri.path (secret.sk_uri :> Uri.t)) + in + return secret_key + +(** Generate the two initial genesis blocks. *) +let make_genesis_context ~delegate_selection ~round0 ~round1 + ~consensus_committee_size ~consensus_threshold accounts_with_secrets + (total_accounts : int) = + let default_constants = Mockup.Protocol_parameters.default_value.constants in + let round_durations = + let open Alpha_context in + Stdlib.Option.get + (Round.Durations.create_opt + ~first_round_duration:(Period.of_seconds_exn round0) + ~delay_increment_per_round: + (Period.of_seconds_exn (Int64.sub round1 round0))) + in + let constants = + { + default_constants with + delegate_selection; + consensus_committee_size; + consensus_threshold; + minimal_block_delay = Alpha_context.Period.of_seconds_exn (max 1L round0); + delay_increment_per_round = + Alpha_context.Period.of_seconds_exn Int64.(max 1L (sub round1 round0)); + } + in + let common_parameters = + Mockup.Protocol_parameters.{default_value with constants} + in + let make_block0 initial_timestamp = + let parameters = {common_parameters with initial_timestamp} in + let reencoded_parameters = + Data_encoding.Binary.of_bytes_exn Mockup.M.parameters_encoding + @@ Data_encoding.Binary.to_bytes_exn + Mockup.Protocol_parameters.encoding + parameters + in + let from_bootstrap_account i + ( (account : Protocol.Alpha_context.Parameters.bootstrap_account), + (secret : Tezos_mockup_commands.Mockup_wallet.bootstrap_secret) ) : + Mockup.Parsed_account.t = + { + name = Format.sprintf "bootstrap%d" (i + 1); + sk_uri = secret.sk_uri; + amount = account.amount; + } + in + let bootstrap_accounts = + Data_encoding.Json.construct + (Data_encoding.list Mockup.Parsed_account.encoding) + (List.mapi from_bootstrap_account accounts_with_secrets) + in + Mockup.M.init + ~cctxt:Faked_client_context.logger + ~parameters:reencoded_parameters + ~constants_overrides_json:None + ~bootstrap_accounts_json:(Some bootstrap_accounts) + >>=? fun {chain = _; rpc_context = rpc_context0; protocol_data = _} -> + let block_header0 = + { + rpc_context0.block_header with + predecessor = genesis_predecessor_block_hash; + } + in + let rpc_context = {rpc_context0 with block_header = block_header0} in + deduce_baker_sk accounts_with_secrets total_accounts 0 >>=? fun baker_sk -> + let protocol_data = + genesis_protocol_data + baker_sk + genesis_predecessor_block_hash + rpc_context.block_header + in + let block_header = + Block_header.{shell = rpc_context.block_header; protocol_data} + in + return (block_header, rpc_context) + in + + let level0_round0_duration = + Protocol.Alpha_context.Round.round_duration + round_durations + Alpha_context.Round.zero + in + let timestamp0 = + Time.Protocol.of_seconds + Int64.( + sub + (of_float (Unix.time ())) + (Alpha_context.Period.to_seconds level0_round0_duration)) + in + make_block0 timestamp0 + +(** By default, propagate every message everywhere. *) +let default_propagation_vector = List.repeat 5 Pass + +module Default_hooks : Hooks = struct + let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations + ~protocol_data:_ = + return (block_hash, block_header, operations, default_propagation_vector) + + let on_inject_operation ~op_hash ~op = + return (op_hash, op, default_propagation_vector) + + let on_new_head ~block_hash ~block_header = + Lwt.return (Some (block_hash, block_header)) + + let on_new_operation x = Lwt.return_some x + + let check_block_before_processing ~level:_ ~round:_ ~block_hash:_ + ~block_header:_ ~protocol_data:_ = + return_unit + + let check_chain_after_processing ~level:_ ~round:_ ~chain:_ = return_unit + + let check_mempool_after_processing ~mempool:_ = return_unit + + let stop_on_event _ = false + + let on_start_baker ~baker_position:_ ~delegates:_ ~cctxt:_ = Lwt.return_unit + + let check_chain_on_success ~chain:_ = return_unit +end + +type config = { + debug : bool; + round0 : int64; + round1 : int64; + timeout : int; + delegate_selection : Alpha_context.Constants.delegate_selection; + consensus_committee_size : int; + consensus_threshold : int; +} + +let default_config = + { + debug = false; + round0 = 2L; + (* Rounds should be long enough for the bakers to + exchange all the necessary messages. *) + round1 = 3L (* No real need to increase round durations. *); + timeout = 10; + delegate_selection = Random; + consensus_committee_size = + Default_parameters.constants_mainnet.consensus_committee_size; + consensus_threshold = + Default_parameters.constants_mainnet.consensus_threshold; + } + +let make_baking_delegate + ( (account : Alpha_context.Parameters.bootstrap_account), + (secret : Tezos_mockup_commands.Mockup_wallet.bootstrap_secret) ) : + Baking_state.delegate = + Baking_state. + { + alias = Some secret.name; + public_key = account.public_key |> WithExceptions.Option.get ~loc:__LOC__; + public_key_hash = account.public_key_hash; + secret_key_uri = secret.sk_uri; + } + +let run ?(config = default_config) bakers_spec = + Tezos_client_base.Client_keys.register_signer + (module Tezos_signer_backends.Unencrypted) ; + let total_accounts = + List.fold_left (fun acc (n, _) -> acc + n) 0 bakers_spec + in + if total_accounts = 0 then + failwith "the simulation should use at least one delegate" + else if total_accounts > 5 then + failwith "only up to 5 bootstrap accounts are available" + else + (* When logging is enabled it may cause non-termination: + + https://gitlab.com/nomadic-labs/tezos/-/issues/546 + + In particular, it seems that when logging is enabled the baker + process can get cancelled without executing its Lwt finalizer. *) + (if config.debug then Internal_event_unix.init () else Lwt.return_unit) + >>= fun () -> + let total_bakers = List.length bakers_spec in + (List.init ~when_negative_length:() total_bakers (fun _ -> + Lwt_pipe.Unbounded.create ()) + |> function + | Error () -> failwith "impossible: negative length of the baker spec" + | Ok xs -> return xs) + >>=? fun broadcast_pipes -> + let global_chain_table = Block_hash.Table.create 10 in + Tezos_mockup_commands.Mockup_wallet.default_bootstrap_accounts + >>=? fun bootstrap_secrets -> + let accounts_with_secrets = + List.combine_drop (List.take_n total_accounts accounts) bootstrap_secrets + in + let all_delegates = List.map make_baking_delegate accounts_with_secrets in + make_genesis_context + ~delegate_selection:config.delegate_selection + ~round0:config.round0 + ~round1:config.round1 + ~consensus_committee_size:config.consensus_committee_size + ~consensus_threshold:config.consensus_threshold + accounts_with_secrets + total_accounts + >>=? fun genesis_block -> + let take_third (_, _, x) = x in + let timeout_process () = + Lwt_unix.sleep (Float.of_int config.timeout) >>= fun () -> + failwith "the test is taking longer than %d seconds@." config.timeout + in + Lwt.pick + [ + timeout_process (); + Lwt_tzresult_syntax.join + (take_third + (List.fold_left + (fun (i, delegates_acc, ms) (n, user_hooks) -> + let (delegates, leftover_delegates) = + List.split_n n delegates_acc + in + let m = + baker_process + ~delegates + ~base_dir:"dummy" + ~genesis_block + ~i + ~global_chain_table + ~broadcast_pipes + ~user_hooks + in + (i + 1, leftover_delegates, m :: ms)) + (0, all_delegates, []) + bakers_spec)); + ] + +let get_account_pk i = + match List.nth accounts i with + | None -> assert false + | Some acc -> acc.public_key |> WithExceptions.Option.get ~loc:__LOC__ + +let bootstrap1 = get_account_pk 0 + +let bootstrap2 = get_account_pk 1 + +let bootstrap3 = get_account_pk 2 + +let bootstrap4 = get_account_pk 3 + +let bootstrap5 = get_account_pk 4 + +let check_block_signature ~block_hash ~(block_header : Block_header.t) + ~public_key = + let (protocol_data : Protocol.Alpha_context.Block_header.protocol_data) = + Data_encoding.Binary.of_bytes_exn + Protocol.Alpha_context.Block_header.protocol_data_encoding + block_header.protocol_data + in + let unsigned_header = + Data_encoding.Binary.to_bytes_exn + Protocol.Alpha_context.Block_header.unsigned_encoding + (block_header.shell, protocol_data.contents) + in + if + Signature.check + ~watermark: + Alpha_context.Block_header.(to_watermark (Block_header chain_id)) + public_key + protocol_data.signature + unsigned_header + then return_unit + else + failwith + "unexpected signature for %a; tried with %a@." + Block_hash.pp + block_hash + Signature.Public_key.pp + public_key + +type op_predicate = + Operation_hash.t -> Alpha_context.packed_operation -> bool tzresult Lwt.t + +let mempool_count_ops ~mempool ~predicate = + List.map_es (fun (op_hash, op) -> predicate op_hash op) mempool + >>=? fun results -> + return + (List.fold_left + (fun acc result -> if result then acc + 1 else acc) + 0 + results) + +let mempool_has_op ~mempool ~predicate = + mempool_count_ops ~mempool ~predicate >>=? fun n -> return (n > 0) + +let mempool_has_op_ref ~mempool ~predicate ~var = + mempool_has_op ~mempool ~predicate >>=? fun result -> + if result then var := true ; + return_unit + +let op_is_signed_by ~public_key (op_hash : Operation_hash.t) + (op : Alpha_context.packed_operation) = + match op.protocol_data with + | Operation_data d -> ( + (match d.contents with + | Single op_contents -> + return + (match op_contents with + | Endorsement _ -> + Alpha_context.Operation.to_watermark (Endorsement chain_id) + | Preendorsement _ -> + Alpha_context.Operation.to_watermark (Preendorsement chain_id) + | _ -> Signature.Generic_operation) + | _ -> failwith "unexpected contents in %a@." Operation_hash.pp op_hash) + >>=? fun watermark -> + match d.signature with + | None -> + failwith + "did not find a signature for op %a@." + Operation_hash.pp + op_hash + | Some signature -> + let unsigned_operation_bytes = + Data_encoding.Binary.to_bytes_exn + Protocol.Alpha_context.Operation.unsigned_encoding + (op.shell, Contents_list d.contents) + in + return + (Signature.check + ~watermark + public_key + signature + unsigned_operation_bytes)) + +let op_is_preendorsement ?level ?round (op_hash : Operation_hash.t) + (op : Alpha_context.packed_operation) = + match op.protocol_data with + | Operation_data d -> ( + match d.contents with + | Single op_contents -> ( + match op_contents with + | Preendorsement consensus_content -> + let right_level = + match level with + | None -> true + | Some expected_level -> + Int32.equal + (Alpha_context.Raw_level.to_int32 consensus_content.level) + expected_level + in + let right_round = + match round with + | None -> true + | Some expected_round -> + Int32.equal + (Alpha_context.Round.to_int32 consensus_content.round) + expected_round + in + return (right_level && right_round) + | _ -> return false) + | _ -> failwith "unexpected contents in %a@." Operation_hash.pp op_hash) + +let op_is_endorsement ?level ?round (op_hash : Operation_hash.t) + (op : Alpha_context.packed_operation) = + match op.protocol_data with + | Operation_data d -> ( + match d.contents with + | Single op_contents -> ( + match op_contents with + | Endorsement consensus_content -> + let right_level = + match level with + | None -> true + | Some expected_level -> + Int32.equal + (Alpha_context.Raw_level.to_int32 consensus_content.level) + expected_level + in + let right_round = + match round with + | None -> true + | Some expected_round -> + Int32.equal + (Alpha_context.Round.to_int32 consensus_content.round) + expected_round + in + return (right_level && right_round) + | _ -> return false) + | _ -> failwith "unexpected contents in %a@." Operation_hash.pp op_hash) + +let op_is_both f g op_hash op = + f op_hash op >>=? fun f_result -> + if f_result then g op_hash op else return false + +let save_proposal_payload + ~(protocol_data : Alpha_context.Block_header.protocol_data) ~var = + var := + Some + (protocol_data.contents.payload_hash, protocol_data.contents.payload_round) ; + return_unit + +let verify_payload_hash + ~(protocol_data : Alpha_context.Block_header.protocol_data) + ~original_proposal ~message = + match !original_proposal with + | None -> + failwith + "verify_payload_hash: expected to have observed a proposal by now" + | Some (original_hash, original_round) -> + if + Protocol.Block_payload_hash.equal + original_hash + protocol_data.contents.payload_hash + && Protocol.Alpha_context.Round.equal + original_round + protocol_data.contents.payload_round + then return_unit + else failwith "verify_payload_hash: %s" message + +let get_block_round block = + round_from_raw_fitness block.rpc_context.block_header.fitness diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/mockup_simulator.mli b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/mockup_simulator.mli new file mode 100644 index 000000000000..c538ab3a01b7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/mockup_simulator/mockup_simulator.mli @@ -0,0 +1,244 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Representation of a block in the simulator. *) +type block = { + rpc_context : Environment_context.rpc_context; + protocol_data : Protocol.Alpha_context.Block_header.protocol_data; + raw_protocol_data : Bytes.t; + operations : Mockup.M.Block_services.operation list list; +} + +(** Chain is a list of blocks. *) +type chain = block list + +(** How an operation or block should propagate through the network. *) +type propagation = + | Block (** Block the operation/block, it'll never be delivered. *) + | Pass (** Pass the operation/block as is. *) + | Delay of float + (** Delay the operation/block for the given number of seconds. *) + +(** Values of this type specify to which bakers a block or operation should + be delivered. *) +type propagation_vector = propagation list + +(** The way to control behavior of a mockup node. *) +module type Hooks = sig + (** This function is called on injection of a block by a particular baker. + It allows us to inspect, change, or discard the block. Calling the + injection RPC and actually updating the state of the mockup node are + two different operations. Normally the first entails the latter, but + not always. In particular, the [propagation_vector] controls what + bakers will see and incorporate the block. *) + val on_inject_block : + level:int32 -> + round:int32 -> + block_hash:Block_hash.t -> + block_header:Block_header.t -> + operations:Operation.t list list -> + protocol_data:Alpha_context.Block_header.protocol_data -> + (Block_hash.t * Block_header.t * Operation.t list list * propagation_vector) + tzresult + Lwt.t + + (** This function is called on injection of an operation. It is similar + to [on_inject_block], which see. *) + val on_inject_operation : + op_hash:Operation_hash.t -> + op:Alpha_context.packed_operation -> + (Operation_hash.t * Alpha_context.packed_operation * propagation_vector) + tzresult + Lwt.t + + (** This is called when a new head is going to be sent as the response to + a "monitor heads" RPC call. Returning [None] here terminates the + process for the baker. *) + val on_new_head : + block_hash:Block_hash.t -> + block_header:Block_header.t -> + (Block_hash.t * Block_header.t) option Lwt.t + + (** This is called when a new operation is going to be sent as the + response to a "monitor operations" RPC call. Returning [None] here + indicates that the node has advanced to the next level. *) + val on_new_operation : + Operation_hash.t * Alpha_context.packed_operation -> + (Operation_hash.t * Alpha_context.packed_operation) option Lwt.t + + (** Check a block before processing it in the mockup. *) + val check_block_before_processing : + level:int32 -> + round:int32 -> + block_hash:Block_hash.t -> + block_header:Block_header.t -> + protocol_data:Alpha_context.Block_header.protocol_data -> + unit tzresult Lwt.t + + (** Check the chain after processing a proposal. *) + val check_chain_after_processing : + level:int32 -> round:int32 -> chain:chain -> unit tzresult Lwt.t + + (** Check operations in the mempool after injecting an operation. *) + val check_mempool_after_processing : + mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> + unit tzresult Lwt.t + + (** This hook is used to decide when the baker is supposed to shut down. + It is triggered by receiving an event. *) + val stop_on_event : Baking_state.event -> bool + + (** This hook is used to gather information on the baker when it is + started (usually recording for later use). The first argument + [baker_position], is the position of the baker in the list of + bakers that were started for this run. *) + val on_start_baker : + baker_position:int -> + delegates:Baking_state.delegate list -> + cctxt:Protocol_client_context.full -> + unit Lwt.t + + (** Check to run on the chain upon successful termination. *) + val check_chain_on_success : chain:chain -> unit tzresult Lwt.t +end + +(** The default hook implementation. *) +module Default_hooks : Hooks + +(** Simulation configuration. *) +type config = { + debug : bool; + (** Whether to initialize the event system in order to display + information about the progress of the simulation. *) + round0 : int64; (** Duration of the round 0 in seconds. *) + round1 : int64; (** Duration of the round 1 in seconds. *) + timeout : int; + (** Maximal duration of the test. If the test takes + longer to terminate it'll be aborted with an + error. *) + delegate_selection : Alpha_context.Constants.delegate_selection; + (** Selection strategy for delegates per level *) + consensus_committee_size : int; + (** Size of the committee for tenderbake in number of slots *) + consensus_threshold : int; + (** Threshold, in number of slots, for the quorum to be considered + reached. Should be [2 * consensus_committee_size / 3 + 1] in + usual setting for tenderbake. *) +} + +(** Default configuration. *) +val default_config : config + +(** [run spec] runs a simulation according to the [spec]. Elements of [spec] + describe bakers: how many delegate each baker has and how it behaves. The + total number of delegates cannot exceed 5 for now (it is easy to increase + this limit). The delegates are assigned in order, gradually exhausting + the standard bootstrap accounts. For example, if the first baker has 3 + delegates and the second one has 2 delegates, we have the following + distribution of bootstrap accounts: + + Baker no. 1: bootstrap1, bootstrap2, bootstrap3 + + Baker no. 2: bootstrap4, bootstrap5 + + A simulation continues till all nodes finish either with an error or + successfully. If at least one node finishes with an error, it propagates + to the final result. *) +val run : ?config:config -> (int * (module Hooks)) list -> unit tzresult Lwt.t + +val bootstrap1 : Signature.public_key + +val bootstrap2 : Signature.public_key + +val bootstrap3 : Signature.public_key + +val bootstrap4 : Signature.public_key + +val bootstrap5 : Signature.public_key + +(** Check if a block header is signed by a given delegate. *) +val check_block_signature : + block_hash:Block_hash.t -> + block_header:Block_header.t -> + public_key:Signature.public_key -> + unit tzresult Lwt.t + +(** A shortcut type for predicates on operations. *) +type op_predicate = + Operation_hash.t -> Alpha_context.packed_operation -> bool tzresult Lwt.t + +(** Count the number of operations in the mempool that satisfy the given + predicate. *) +val mempool_count_ops : + mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> + predicate:op_predicate -> + int tzresult Lwt.t + +(** Check if the mempool has at least one operation that satisfies the given + predicate. *) +val mempool_has_op : + mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> + predicate:op_predicate -> + bool tzresult Lwt.t + +(** Similar to [mempool_has_op] but instead of returning a [bool] it sets + the given [bool ref]. *) +val mempool_has_op_ref : + mempool:(Operation_hash.t * Mockup.M.Protocol.operation) list -> + predicate:op_predicate -> + var:bool ref -> + unit tzresult Lwt.t + +(** Check if an operation is signed by the given delegate. *) +val op_is_signed_by : public_key:Signature.public_key -> op_predicate + +(** Check that an operation is a preendorsement. *) +val op_is_preendorsement : ?level:int32 -> ?round:int32 -> op_predicate + +(** Check that an operation is an endorsement. *) +val op_is_endorsement : ?level:int32 -> ?round:int32 -> op_predicate + +(** Combine two predicates. *) +val op_is_both : op_predicate -> op_predicate -> op_predicate + +(** Set the given variable to save payload hash and payload round. *) +val save_proposal_payload : + protocol_data:Alpha_context.Block_header.protocol_data -> + var:(Block_payload_hash.t * Alpha_context.Round.t) option ref -> + unit tzresult Lwt.t + +(** Check that payload hashes match, fail if it is not the case. *) +val verify_payload_hash : + protocol_data:Alpha_context.Block_header.protocol_data -> + original_proposal:(Block_payload_hash.t * Alpha_context.Round.t) option ref -> + message:string -> + unit tzresult Lwt.t + +(** Parse protocol data. *) +val parse_protocol_data : + Bytes.t -> Alpha_context.Block_header.protocol_data tzresult Lwt.t + +(** Get round of a block. *) +val get_block_round : block -> int32 tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_delegate/test/test_scenario.ml b/src/proto_012_PsiThaCa/lib_delegate/test/test_scenario.ml new file mode 100644 index 000000000000..b88fa46c0b75 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/test/test_scenario.ml @@ -0,0 +1,1317 @@ +open Mockup_simulator + +(* + +Test that the chain reaches the 5th level. + +*) + +let test_level_5 () = + let level_to_reach = 5l in + let module Hooks : Hooks = struct + include Default_hooks + + let stop_on_event = function + | Baking_state.New_proposal {block; _} -> + (* Stop the node as soon as we receive a proposal with a level + higher than [level_to_reach]. *) + block.shell.level > level_to_reach + | _ -> false + + let check_chain_on_success ~chain = + (* Make sure that all decided blocks have been decided at round 0. *) + let round_is_zero block = + let level = block.rpc_context.block_header.level in + get_block_round block >>=? fun round -> + if Int32.equal round 0l then return () + else failwith "block at level %ld was selected at round %ld" level round + in + List.iter_es round_is_zero chain + end in + (* Here we start two bakers, one with 3 delegates (bootstrap1, bootstrap2, + bootstrap3) and the other with 2 delegates (bootstrap4, bootstrap5). + The simulation continues till both nodes stop, see [stop_on_event] + above. *) + let config = + { + default_config with + timeout = Int32.to_int level_to_reach * 3; + round0 = 2L; + round1 = 3L; + } + in + run ~config [(3, (module Hooks)); (2, (module Hooks))] + +(* + +Scenario T1 + +1. Node A proposes at the round 0. +2. Both node A and node B preendorse. +3. Node A stops. +4. Node B endorses in the round 0 and locks. No decision is taken at the + round 0 because A did not endorse. +5. We check that in round 1 (the next slot for B), B proposes the same + value as A proposed in the round 0, not a new proposal. +*) + +let test_scenario_t1 () = + let original_proposal = ref None in + let a_preendorsed = ref false in + let b_preendorsed = ref false in + let b_endorsed = ref false in + let b_reproposed = ref false in + (* Here we use custom hooks to make each node/baker behave according to + its role in the scenario. *) + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let check_mempool_after_processing ~mempool = + mempool_has_op_ref + ~mempool + ~predicate: + (op_is_both + (op_is_signed_by ~public_key:bootstrap1) + (op_is_preendorsement ~level:1l ~round:0l)) + ~var:a_preendorsed + + let stop_on_event _ = !a_preendorsed + end in + let module Node_b_hooks : Hooks = struct + include Default_hooks + + let check_block_before_processing ~level ~round ~block_hash ~block_header + ~(protocol_data : Protocol.Alpha_context.Block_header.protocol_data) = + (match (!b_endorsed, level, round) with + | (false, 1l, 0l) -> + (* If any of the checks fails the whole scenario will fail. *) + check_block_signature ~block_hash ~block_header ~public_key:bootstrap1 + >>=? fun () -> + save_proposal_payload ~protocol_data ~var:original_proposal + | (true, 1l, 1l) -> + check_block_signature ~block_hash ~block_header ~public_key:bootstrap2 + >>=? fun () -> + verify_payload_hash + ~protocol_data + ~original_proposal + ~message:"a new block proposed instead of reproposal" + >>=? fun () -> + b_reproposed := true ; + return_unit + | _ -> failwith "unexpected level = %ld / round = %ld" level round) + >>=? fun () -> return_unit + + let check_mempool_after_processing ~mempool = + mempool_has_op_ref + ~mempool + ~predicate: + (op_is_both + (op_is_signed_by ~public_key:bootstrap2) + (op_is_preendorsement ~level:1l ~round:0l)) + ~var:b_preendorsed + >>=? fun () -> + mempool_has_op_ref + ~mempool + ~predicate: + (op_is_both + (op_is_signed_by ~public_key:bootstrap2) + (op_is_preendorsement ~level:1l ~round:0l)) + ~var:b_endorsed + + let stop_on_event _ = !b_reproposed + end in + let config = + { + default_config with + delegate_selection = Round_robin_over [[bootstrap1; bootstrap2]]; + } + in + run ~config [(1, (module Node_a_hooks)); (1, (module Node_b_hooks))] + +(* + +Scenario T2 + +1. Node A should propose at the round 0, but it is dead. +2. Node B waits til it has its proposal slot at round 1 and proposes then. + +*) + +let test_scenario_t2 () = + let b_proposed = ref false in + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let stop_on_event _ = true (* Node A stops immediately. *) + end in + let module Node_b_hooks : Hooks = struct + include Default_hooks + + let check_block_before_processing ~level ~round ~block_hash ~block_header + ~protocol_data:_ = + (* Here we test that the only block that B observes is its own + proposal for level 1 at round 1. *) + match (level, round) with + | (1l, 1l) -> + check_block_signature ~block_hash ~block_header ~public_key:bootstrap2 + >>=? fun () -> + b_proposed := true ; + return_unit + | _ -> failwith "unexpected level = %ld / round = %ld" level round + + let stop_on_event _ = + (* Stop as soon as B has proposed. This ends the test. *) + !b_proposed + end in + let config = + { + default_config with + delegate_selection = Round_robin_over [[bootstrap1; bootstrap2]]; + } + in + run ~config [(1, (module Node_a_hooks)); (1, (module Node_b_hooks))] + +(* + +Scenario T3 + +1. There are four nodes: A, B, C, and D. +2. C is the proposer at the round 0. It sends the proposal, which is + received by all bakers except for D. +3. Due to how the messages propagate, only B sees 3 preendorsements. It + endorses and locks. Other nodes all see fewer than 3 preendorsements. + + A -> A and B + B -> B + C -> C and B + +4. D proposes at the round 1. Its message reaches 3 nodes, including B. + + D -> D, B, C + +5. B does not preendorse because it is locked. +6. No decision is taken at the round 1. +7. B proposes at the round 2. There are no more problems with propagation of + messages, so a decision is reached. + +*) + +let test_scenario_t3 () = + let b_observed_pqc = ref false in + let original_proposal = ref None in + let we_are_done = ref false in + let stop_on_event0 _ = !we_are_done in + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let on_inject_operation ~op_hash ~op = + if !b_observed_pqc then return (op_hash, op, [Pass; Pass; Pass; Pass]) + else + op_is_preendorsement ~level:1l ~round:0l op_hash op + >>=? fun is_preendorsement -> + if is_preendorsement then + return (op_hash, op, [Pass; Pass; Block; Block]) + else failwith "unexpected operation from the node D" + + let stop_on_event = stop_on_event0 + end in + let module Node_b_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~(protocol_data : Protocol.Alpha_context.Block_header.protocol_data) = + match (level, round) with + | (1l, 2l) -> + check_block_signature ~block_hash ~block_header ~public_key:bootstrap2 + >>=? fun () -> + we_are_done := true ; + verify_payload_hash + ~protocol_data + ~original_proposal + ~message:"a new block proposed instead of reproposal" + >>=? fun () -> + return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) + | _ -> + failwith + "unexpected injection on the node B, level = %ld / round = %ld" + level + round + + let on_inject_operation ~op_hash ~op = + if !b_observed_pqc then return (op_hash, op, [Pass; Pass; Pass; Pass]) + else + op_is_preendorsement ~level:1l ~round:0l op_hash op + >>=? fun is_preendorsement -> + if is_preendorsement then + return (op_hash, op, [Block; Pass; Block; Block]) + else failwith "unexpected operation from the node B" + + let check_mempool_after_processing ~mempool = + let predicate op_hash op = + op_is_preendorsement ~level:1l ~round:0l op_hash op + in + mempool_count_ops ~mempool ~predicate >>=? fun n -> + if n > 3 then + failwith "B received too many preendorsements, expected to see only 3" + else if n = 3 then ( + b_observed_pqc := true ; + return_unit) + else return_unit + + let stop_on_event = stop_on_event0 + end in + let module Node_c_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~(protocol_data : Protocol.Alpha_context.Block_header.protocol_data) = + match (level, round) with + | (1l, 0l) -> + check_block_signature ~block_hash ~block_header ~public_key:bootstrap3 + >>=? fun () -> + save_proposal_payload ~protocol_data ~var:original_proposal + >>=? fun () -> + return + (block_hash, block_header, operations, [Pass; Pass; Pass; Block]) + | _ -> + failwith + "unexpected injection on the node C, level = %ld / round = %ld" + level + round + + let on_inject_operation ~op_hash ~op = + if !b_observed_pqc then return (op_hash, op, [Pass; Pass; Pass; Pass]) + else + op_is_preendorsement ~level:1l ~round:0l op_hash op + >>=? fun is_preendorsement -> + if is_preendorsement then + return (op_hash, op, [Block; Pass; Pass; Block]) + else failwith "unexpected operation from the node C" + + let stop_on_event = stop_on_event0 + end in + let module Node_d_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + match (level, round) with + | (1l, 1l) -> + return + (block_hash, block_header, operations, [Block; Pass; Pass; Pass]) + | _ -> + failwith + "unexpected injection on the node D, level = %ld / round = %ld" + level + round + + let on_inject_operation ~op_hash ~op = + if !b_observed_pqc then return (op_hash, op, [Pass; Pass; Pass; Pass]) + else return (op_hash, op, [Block; Block; Block; Block]) + + let stop_on_event = stop_on_event0 + end in + let config = + { + default_config with + delegate_selection = + Round_robin_over + [ + [bootstrap3; bootstrap4; bootstrap2; bootstrap1]; + [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; + ]; + } + in + run + ~config + [ + (1, (module Node_a_hooks)); + (1, (module Node_b_hooks)); + (1, (module Node_c_hooks)); + (1, (module Node_d_hooks)); + ] + +(* + +Scenario F1 + +1. Node C (bootstrap3) proposes at level 1 round 0, its proposal reaches all + nodes. +2. Propagation of preendorsements happens in such a way that only Node A + (bootstrap1) observes PQC: + + A -> A + B -> B and A + C -> C and A + D -> D and A + + Node A locks. + +3. At the level 1 round 1 node D (bootstrap4) proposes. Propagation of + messages is normal. + +4. Node A (bootstrap1) should propose at level 2 round 0. + +*) + +let test_scenario_f1 () = + let c_proposed_l1_r0 = ref false in + let d_proposed_l1_r1 = ref false in + let a_proposed_l2_r0 = ref false in + let stop_on_event0 _ = !a_proposed_l2_r0 in + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + match (!c_proposed_l1_r0, !d_proposed_l1_r1, level, round) with + | (true, true, 2l, 0l) -> + check_block_signature ~block_hash ~block_header ~public_key:bootstrap1 + >>=? fun () -> + (a_proposed_l2_r0 := true ; + return_unit) + >>=? fun () -> + return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) + | _ -> + failwith + "unexpected injection on the node A, level = %ld / round = %ld" + level + round + + let on_inject_operation ~op_hash ~op = + match (!c_proposed_l1_r0, !d_proposed_l1_r1) with + | (true, false) -> return (op_hash, op, [Pass; Block; Block; Block]) + | _ -> return (op_hash, op, [Pass; Pass; Pass; Pass]) + + let stop_on_event = stop_on_event0 + end in + let module Node_b_hooks : Hooks = struct + include Default_hooks + + let on_inject_operation ~op_hash ~op = + match (!c_proposed_l1_r0, !d_proposed_l1_r1) with + | (true, false) -> return (op_hash, op, [Pass; Pass; Block; Block]) + | _ -> return (op_hash, op, [Pass; Pass; Pass; Pass]) + + let stop_on_event = stop_on_event0 + end in + let module Node_c_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + match (!c_proposed_l1_r0, !d_proposed_l1_r1, level, round) with + | (false, false, 1l, 0l) -> + check_block_signature ~block_hash ~block_header ~public_key:bootstrap3 + >>=? fun () -> + (c_proposed_l1_r0 := true ; + return_unit) + >>=? fun () -> + return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) + | _ -> + failwith + "unexpected injection on the node C, level = %ld / round = %ld" + level + round + + let on_inject_operation ~op_hash ~op = + match (!c_proposed_l1_r0, !d_proposed_l1_r1) with + | (true, false) -> return (op_hash, op, [Pass; Block; Pass; Block]) + | _ -> return (op_hash, op, [Pass; Pass; Pass; Pass]) + + let stop_on_event = stop_on_event0 + end in + let module Node_d_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + match (!d_proposed_l1_r1, level, round) with + | (false, 1l, 1l) -> + check_block_signature ~block_hash ~block_header ~public_key:bootstrap4 + >>=? fun () -> + (d_proposed_l1_r1 := true ; + return_unit) + >>=? fun () -> + return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) + | _ -> + failwith + "unexpected injection on the node D, level = %ld / round = %ld" + level + round + + let on_inject_operation ~op_hash ~op = + match (!c_proposed_l1_r0, !d_proposed_l1_r1) with + | (true, false) -> return (op_hash, op, [Pass; Block; Block; Pass]) + | _ -> return (op_hash, op, [Pass; Pass; Pass; Pass]) + + let stop_on_event = stop_on_event0 + end in + let config = + { + default_config with + delegate_selection = + Round_robin_over + [ + [bootstrap3; bootstrap4; bootstrap1; bootstrap2]; + [bootstrap1; bootstrap4; bootstrap2; bootstrap3]; + ]; + timeout = 15; + } + in + run + ~config + [ + (1, (module Node_a_hooks)); + (1, (module Node_b_hooks)); + (1, (module Node_c_hooks)); + (1, (module Node_d_hooks)); + ] + +(* + +Scenario F2 + +1. There are four nodes: A, B, C, and D. +2. A proposes at 1.0 and observes EQC. +3. A has the slot at 2.0 but somehow it doesn't propose or its proposal is lost. +4. B, C, and D have the rounds 1, 2, and 3 respectively, but they also do not propose. +5. A should still propose at 2.4. + +*) + +let test_scenario_f2 () = + let proposal_2_4_observed = ref false in + let module Hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + let propagation_vector = + match (level, round) with + | (1l, 0l) -> [Pass; Pass; Pass; Pass] + | (2l, 0l) -> [Pass; Block; Block; Block] + | (2l, 4l) -> + proposal_2_4_observed := true ; + [Pass; Pass; Pass; Pass] + | _ -> [Block; Block; Block; Block] + in + return (block_hash, block_header, operations, propagation_vector) + + let stop_on_event _ = !proposal_2_4_observed + end in + let config = + { + default_config with + delegate_selection = + Round_robin_over + [ + [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; + [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; + ]; + timeout = 25; + round0 = 2L; + round1 = 3L; + } + in + run + ~config + [ + (1, (module Hooks)); + (1, (module Hooks)); + (1, (module Hooks)); + (1, (module Hooks)); + ] + +(* + +Scenario M1 + +1. Four nodes start, each with 1 delegate. +2. As soon as 2nd level is proposed all communication between nodes becomes + impossible. +3. The situation continues for 5 seconds. +4. After communication is resumed the bakers must continue making progress. + +*) + +let test_scenario_m1 () = + let observed_level2_timestamp = ref None in + let network_down_sec = 5. in + let module Hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round:_ ~block_hash ~block_header ~operations + ~protocol_data:_ = + let propagation_vector = + match !observed_level2_timestamp with + | None -> + if Compare.Int32.(level >= 2l) then ( + observed_level2_timestamp := Some (Unix.time ()) ; + [Pass; Pass; Pass; Pass]) + else [Pass; Pass; Pass; Pass] + | Some level2_observed -> + if Unix.time () -. level2_observed < network_down_sec then + [Block; Block; Block; Block] + else [Pass; Pass; Pass; Pass] + in + return (block_hash, block_header, operations, propagation_vector) + + let on_inject_operation ~op_hash ~op = + let propagation_vector = + match !observed_level2_timestamp with + | None -> [Pass; Pass; Pass; Pass] + | Some level2_observed -> + if Unix.time () -. level2_observed < network_down_sec then + [Block; Block; Block; Block] + else [Pass; Pass; Pass; Pass] + in + return (op_hash, op, propagation_vector) + + let stop_on_event = function + | Baking_state.New_proposal {block; _} -> block.shell.level > 4l + | _ -> false + end in + let config = {default_config with timeout = 25} in + run + ~config + [ + (1, (module Hooks)); + (1, (module Hooks)); + (1, (module Hooks)); + (1, (module Hooks)); + ] + +(* + +Scenario M2 + +1. Five nodes start (single delegate per node). +2. They decide level 1. +3. However, the node that has the slot for level 2 round 0 is not there + to participate. +4. We check that the chain continues advancing despite that. + +*) + +let test_scenario_m2 () = + let module Normal_node : Hooks = struct + include Default_hooks + + let stop_on_event = function + | Baking_state.New_proposal {block; _} -> block.shell.level > 5l + | _ -> false + end in + let module Missing_node : Hooks = struct + include Default_hooks + + let stop_on_event _ = true (* stop immediately *) + end in + let config = + { + default_config with + delegate_selection = + Round_robin_over + [ + [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; + [bootstrap5; bootstrap1; bootstrap2; bootstrap3; bootstrap4]; + ]; + round0 = 2L; + round1 = 3L; + timeout = 20; + } + in + run + ~config + [ + (1, (module Normal_node)); + (1, (module Normal_node)); + (1, (module Normal_node)); + (1, (module Normal_node)); + (1, (module Missing_node)); + ] + +(* + +Scenario M3 + +1. There are four nodes: A, B, C, and D. +2. A and B propose in turns. Messages from A reach every node, but messages + from other nodes only go to A. +3. The chain should not make progress. Since we have both bootstrap1 and + bootstrap2 in delegate selection they have equal voting power. Therefore + it is necessary to have 2 votes for pre-quorums (which is achieved when A + is proposing) and 2 votes for quorums (impossible because B has no way to + obtain PQC and thus cannot send endorsements). + +*) + +let test_scenario_m3 () = + let stop_on_event0 = function + | Baking_state.New_proposal {block; _} -> + block.shell.level = 1l + && Protocol.Alpha_context.Round.to_int32 block.round = 6l + | _ -> false + in + + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let stop_on_event = stop_on_event0 + end in + let module Other_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations + ~protocol_data:_ = + return (block_hash, block_header, operations, [Pass; Block; Block; Block]) + + let on_inject_operation ~op_hash ~op = + return (op_hash, op, [Pass; Block; Block; Block]) + + let stop_on_event = stop_on_event0 + end in + let config = + { + default_config with + delegate_selection = Round_robin_over [[bootstrap1; bootstrap2]]; + round0 = 2L; + round1 = 3L; + timeout = 30; + } + in + run + ~config + [ + (1, (module Node_a_hooks)); + (1, (module Other_hooks)); + (1, (module Other_hooks)); + (1, (module Other_hooks)); + ] + +(* + +Scenario M4 + +1. There are four bakers: A, B, C, and D. +2. A proposes at level 1 round 0. Its proposal reaches A, B, C, and D, but + with a delay of 0.5 seconds. +3. 3 votes are enough for consensus, because voting powers of all delegates + are equal. Preendorsements propagate freely, however endorsements from C + are blocked. +4. Check that at level 1 round 0 quorum is reached (from the point of view + of A). This means that D sends an endorsement despite receiving + preendorsements before the proposal. + +*) + +let test_scenario_m4 () = + let a_observed_qc = ref false in + let stop_on_event0 _ = !a_observed_qc in + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + match (level, round) with + | (1l, 0l) -> + check_block_signature ~block_hash ~block_header ~public_key:bootstrap1 + >>=? fun () -> + return + (block_hash, block_header, operations, [Pass; Pass; Pass; Delay 0.5]) + | _ -> + failwith + "unexpected injection on the node A, level = %ld / round = %ld" + level + round + + let check_mempool_after_processing ~mempool = + let predicate op_hash op = + op_is_endorsement ~level:1l ~round:0l op_hash op + in + mempool_count_ops ~mempool ~predicate >>=? fun n -> + if n > 3 then + failwith "A received too many endorsements, expected to see only 3" + else if n = 3 then ( + a_observed_qc := true ; + return_unit) + else return_unit + + let stop_on_event = stop_on_event0 + end in + let module Node_b_hooks : Hooks = struct + include Default_hooks + + let stop_on_event = stop_on_event0 + end in + let module Node_c_hooks : Hooks = struct + include Default_hooks + + let on_inject_operation ~op_hash ~op = + op_is_endorsement ~level:1l ~round:0l op_hash op + >>=? fun is_endorsement -> + return + ( op_hash, + op, + if is_endorsement then [Block; Block; Block; Block] + else [Pass; Pass; Pass; Pass] ) + + let stop_on_event = stop_on_event0 + end in + let module Node_d_hooks : Hooks = struct + include Default_hooks + + let stop_on_event = stop_on_event0 + end in + let config = + { + default_config with + delegate_selection = + Round_robin_over [[bootstrap1; bootstrap2; bootstrap3; bootstrap4]]; + } + in + run + ~config + [ + (1, (module Node_a_hooks)); + (1, (module Node_b_hooks)); + (1, (module Node_c_hooks)); + (1, (module Node_d_hooks)); + ] + +(* + +Scenario M5 + +1. There are four bakers: A, B, C, and D. +2. A proposes at level 1 round 0. Its proposal reaches A, B, C, and D, but with + a delay of 1 second. There are no problems with propagation of + preendorsements and endorsements. +3. At the level 1 all four bakers have proposer slots, however we block possible + proposals from B and C at higher rounds. +4. Check that D proposes at the level 2 round 0, which means that it has + observed QC. + +*) + +let test_scenario_m5 () = + let stop_on_event0 = function + | Baking_state.New_proposal {block; _} -> block.shell.level >= 2l + | _ -> false + in + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + match (level, round) with + | (1l, 0l) -> + check_block_signature ~block_hash ~block_header ~public_key:bootstrap1 + >>=? fun () -> + return + (block_hash, block_header, operations, [Pass; Pass; Pass; Delay 1.0]) + | _ -> + failwith + "unexpected injection on the node A, level = %ld / round = %ld" + level + round + + let stop_on_event = stop_on_event0 + end in + let module Other_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations + ~protocol_data:_ = + return (block_hash, block_header, operations, [Block; Block; Block; Block]) + + let stop_on_event = stop_on_event0 + end in + let module Node_d_hooks : Hooks = struct + include Default_hooks + + let stop_on_event = stop_on_event0 + end in + let config = + { + default_config with + delegate_selection = + Round_robin_over + [[bootstrap1; bootstrap2; bootstrap3; bootstrap4]; [bootstrap4]]; + round0 = 3L; + round1 = 4L; + } + in + run + ~config + [ + (1, (module Node_a_hooks)); + (1, (module Other_hooks)); + (1, (module Other_hooks)); + (1, (module Node_d_hooks)); + ] + +(* + +Scenario M6 + +1. There are four bakers: A, B, C, and D. +2. A proposes at level 1 round 0. Its proposal reaches all nodes, and they + observe PQC. Only A observes a QC. +3. At level 1 round 1 it is B's turn to propose. Since it has observed the + PQC, it reproposes A's proposal. A does not see it. +4. B observes PQC and QC for its proposal. +5. A proposes at level 2 round 0. No one sees the proposal. +6. B proposes at level 2 round 1. A sees B's proposal and switches its branch. +7. We wait 2 more levels before checking A's chain to verify that it has + adopted B's proposal. + +*) + +let test_scenario_m6 () = + let b_proposal_2_1 = ref None in + let stop_on_event0 = function + | Baking_state.New_proposal {block; _} -> block.shell.level > 4l + | _ -> false + in + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + let propagation_vector = + match (level, round) with + | (2l, 0l) -> [Pass; Block; Block; Block] + | _ -> [Pass; Pass; Pass; Pass] + in + return (block_hash, block_header, operations, propagation_vector) + + let on_inject_operation ~op_hash ~op = + op_is_endorsement ~level:1l ~round:0l op_hash op + >>=? fun is_a10_endorsement -> + return + ( op_hash, + op, + if is_a10_endorsement then [Pass; Block; Block; Block] + else [Pass; Pass; Pass; Pass] ) + + let stop_on_event = stop_on_event0 + + let check_chain_on_success ~chain = + match List.nth (List.rev chain) 2 with + | None -> failwith "Node A has empty chain" + | Some (block : block) -> + verify_payload_hash + ~protocol_data:block.protocol_data + ~original_proposal:b_proposal_2_1 + ~message:"A did not switch to B's proposal (level 2, round 1)" + end in + let module Node_b_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data = + (match (level, round) with + | (1l, 1l) -> return [Block; Delay 0.1; Delay 0.1; Delay 0.1] + | (2l, 1l) -> + save_proposal_payload ~protocol_data ~var:b_proposal_2_1 + >>=? fun () -> return [Pass; Pass; Pass; Pass] + | _ -> return [Pass; Pass; Pass; Pass]) + >>=? fun propagation_vector -> + return (block_hash, block_header, operations, propagation_vector) + + let on_inject_operation ~op_hash ~op = + op_is_endorsement ~level:1l ~round:0l op_hash op + >>=? fun is_a10_endorsement -> + return + ( op_hash, + op, + if is_a10_endorsement then [Pass; Block; Block; Block] + else [Pass; Pass; Pass; Pass] ) + + let stop_on_event = stop_on_event0 + end in + let module Other_node : Hooks = struct + include Default_hooks + + let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations + ~protocol_data:_ = + return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) + + let on_inject_operation ~op_hash ~op = + op_is_endorsement ~level:1l ~round:0l op_hash op + >>=? fun is_a10_endorsement -> + return + ( op_hash, + op, + if is_a10_endorsement then [Pass; Block; Block; Block] + else [Pass; Pass; Pass; Pass] ) + + let stop_on_event = stop_on_event0 + end in + let config = + { + default_config with + delegate_selection = + Round_robin_over + [ + [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; + [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; + ]; + timeout = 20; + } + in + run + ~config + [ + (1, (module Node_a_hooks)); + (1, (module Node_b_hooks)); + (1, (module Other_node)); + (1, (module Other_node)); + ] + +(* + +Scenario M7 + +The same as M6, but: + +5. B proposes at level 2 round 0 (A does not see the proposal). +6. A proposes at 2.1. B switches to A's branch when it receives 2.1. +7. We wait 2 more levels before checking everyone's chain to verify that + A's proposal has been selected. + +*) + +let test_scenario_m7 () = + let a_proposal_2_1 = ref None in + let c_received_2_1 = ref false in + let d_received_2_1 = ref false in + let stop_on_event0 = function + | Baking_state.New_proposal {block; _} -> block.shell.level > 4l + | _ -> false + in + let check_chain_on_success0 node_label ~chain = + match List.nth (List.rev chain) 2 with + | None -> failwith "Node %s has empty chain" node_label + | Some (block : block) -> + verify_payload_hash + ~protocol_data:block.protocol_data + ~original_proposal:a_proposal_2_1 + ~message: + (Format.sprintf + "%s did not switch to A's proposal (level 2, round 1)" + node_label) + in + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data = + (match (level, round) with + | (2l, 1l) -> save_proposal_payload ~protocol_data ~var:a_proposal_2_1 + | _ -> return_unit) + >>=? fun () -> + return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) + + let on_inject_operation ~op_hash ~op = + op_is_endorsement ~level:1l ~round:0l op_hash op + >>=? fun is_a10_endorsement -> + return + ( op_hash, + op, + if is_a10_endorsement then [Pass; Block; Block; Block] + else [Pass; Pass; Pass; Pass] ) + + let stop_on_event = stop_on_event0 + + let check_chain_on_success = check_chain_on_success0 "A" + end in + let module Node_b_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + (match (level, round) with + | (1l, 1l) -> return [Block; Delay 0.1; Delay 0.1; Delay 0.1] + | (2l, 0l) -> return [Block; Pass; Pass; Pass] + | _ -> return [Pass; Pass; Pass; Pass]) + >>=? fun propagation_vector -> + return (block_hash, block_header, operations, propagation_vector) + + let on_inject_operation ~op_hash ~op = + op_is_endorsement ~level:1l ~round:0l op_hash op + >>=? fun is_a10_endorsement -> + op_is_preendorsement ~level:2l op_hash op + >>=? fun level2_preendorsement -> + op_is_endorsement ~level:2l op_hash op >>=? fun level2_endorsement -> + let propagation_vector = + match + (is_a10_endorsement, level2_preendorsement, level2_endorsement) + with + | (true, _, _) -> [Pass; Block; Block; Block] + | (_, true, _) | (_, _, true) -> [Block; Block; Block; Block] + | (_, _, _) -> [Pass; Pass; Pass; Pass] + in + return (op_hash, op, propagation_vector) + + let stop_on_event = stop_on_event0 + + let check_chain_on_success = check_chain_on_success0 "B" + end in + let module Node_c_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations + ~protocol_data:_ = + let propagation_vector = + if !c_received_2_1 then [Pass; Pass; Pass; Pass] + else [Block; Block; Block; Block] + in + return (block_hash, block_header, operations, propagation_vector) + + let check_chain_after_processing ~level ~round ~chain:_ = + match (level, round) with + | (2l, 1l) -> + c_received_2_1 := true ; + return_unit + | _ -> return_unit + + let on_inject_operation ~op_hash ~op = + op_is_endorsement ~level:1l ~round:0l op_hash op + >>=? fun is_a10_endorsement -> + op_is_preendorsement ~level:2l op_hash op + >>=? fun level2_preendorsement -> + op_is_endorsement ~level:2l op_hash op >>=? fun level2_endorsement -> + let propagation_vector = + match + ( is_a10_endorsement, + !c_received_2_1, + level2_preendorsement, + level2_endorsement ) + with + | (true, _, _, _) -> [Pass; Block; Block; Block] + | (_, false, true, _) | (_, false, _, true) -> + [Block; Block; Block; Block] + | (_, _, _, _) -> [Pass; Pass; Pass; Pass] + in + return (op_hash, op, propagation_vector) + + let stop_on_event = stop_on_event0 + + let check_chain_on_success = check_chain_on_success0 "C" + end in + let module Node_d_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations + ~protocol_data:_ = + let propagation_vector = + if !d_received_2_1 then [Pass; Pass; Pass; Pass] + else [Block; Block; Block; Block] + in + return (block_hash, block_header, operations, propagation_vector) + + let check_chain_after_processing ~level ~round ~chain:_ = + match (level, round) with + | (2l, 1l) -> + d_received_2_1 := true ; + return_unit + | _ -> return_unit + + let on_inject_operation ~op_hash ~op = + op_is_endorsement ~level:1l ~round:0l op_hash op + >>=? fun is_a10_endorsement -> + op_is_preendorsement ~level:2l op_hash op + >>=? fun level2_preendorsement -> + op_is_endorsement ~level:2l op_hash op >>=? fun level2_endorsement -> + let propagation_vector = + match + ( is_a10_endorsement, + !d_received_2_1, + level2_preendorsement, + level2_endorsement ) + with + | (true, _, _, _) -> [Pass; Block; Block; Block] + | (_, false, true, _) | (_, false, _, true) -> + [Block; Block; Block; Block] + | (_, _, _, _) -> [Pass; Pass; Pass; Pass] + in + return (op_hash, op, propagation_vector) + + let stop_on_event = stop_on_event0 + + let check_chain_on_success = check_chain_on_success0 "D" + end in + let config = + { + default_config with + delegate_selection = + Round_robin_over + [ + [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; + [bootstrap2; bootstrap1; bootstrap3; bootstrap4]; + ]; + timeout = 20; + } + in + run + ~config + [ + (1, (module Node_a_hooks)); + (1, (module Node_b_hooks)); + (1, (module Node_c_hooks)); + (1, (module Node_d_hooks)); + ] + +(* + +Scenario M8 + +5. B proposes at 2.0 and observes PQC but not QC. +6. C re-proposes at 2.1 and similarly observes PQC but not QC. +7. A proposes at 2.2. B, C, and D do not switch to A's branch; moreover A + switches to their branch when it receives the next proposal (2.3). This + happens because B, C, and D have PQC despite A having a higher round (2 > 1). +8. We wait 2 more levels before checking everyone's chain to verify that + B's proposal has been selected. + +*) + +let test_scenario_m8 () = + let b_proposal_2_0 = ref None in + let stop_on_event0 = function + | Baking_state.New_proposal {block; _} -> block.shell.level > 4l + | _ -> false + in + let on_inject_operation0 ~op_hash ~op = + op_is_endorsement ~level:1l ~round:0l op_hash op + >>=? fun is_a10_endorsement -> + op_is_endorsement ~level:2l ~round:0l op_hash op + >>=? fun is_b20_endorsement -> + op_is_endorsement ~level:2l ~round:1l op_hash op + >>=? fun is_c21_endorsement -> + let propagation_vector = + if is_a10_endorsement then [Pass; Block; Block; Block] + else if is_b20_endorsement || is_c21_endorsement then + [Block; Block; Block; Block] + else [Pass; Pass; Pass; Pass] + in + return (op_hash, op, propagation_vector) + in + let check_chain_on_success0 node_label ~chain = + match List.nth (List.rev chain) 2 with + | None -> failwith "Node %s has empty chain" node_label + | Some (block : block) -> + verify_payload_hash + ~protocol_data:block.protocol_data + ~original_proposal:b_proposal_2_0 + ~message: + (Format.sprintf + "%s did not switch to B's proposal (level 2, round 0)" + node_label) + in + let module Node_a_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations + ~protocol_data:_ = + return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) + + let on_inject_operation = on_inject_operation0 + + let stop_on_event = stop_on_event0 + + let check_chain_on_success = check_chain_on_success0 "A" + end in + let module Node_b_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data = + (match (level, round) with + | (1l, 1l) -> return [Block; Delay 0.1; Delay 0.1; Delay 0.1] + | (2l, 0l) -> + save_proposal_payload ~protocol_data ~var:b_proposal_2_0 + >>=? fun () -> return [Block; Pass; Pass; Pass] + | _ -> return [Pass; Pass; Pass; Pass]) + >>=? fun propagation_vector -> + return (block_hash, block_header, operations, propagation_vector) + + let on_inject_operation = on_inject_operation0 + + let stop_on_event = stop_on_event0 + + let check_chain_on_success = check_chain_on_success0 "B" + end in + let module Node_c_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level ~round ~block_hash ~block_header ~operations + ~protocol_data:_ = + let propagation_vector = + match (level, round) with + | (2l, 1l) -> [Block; Pass; Pass; Pass] + | _ -> [Pass; Pass; Pass; Pass] + in + return (block_hash, block_header, operations, propagation_vector) + + let on_inject_operation = on_inject_operation0 + + let stop_on_event = stop_on_event0 + + let check_chain_on_success = check_chain_on_success0 "C" + end in + let module Node_d_hooks : Hooks = struct + include Default_hooks + + let on_inject_block ~level:_ ~round:_ ~block_hash ~block_header ~operations + ~protocol_data:_ = + return (block_hash, block_header, operations, [Pass; Pass; Pass; Pass]) + + let on_inject_operation = on_inject_operation0 + + let stop_on_event = stop_on_event0 + + let check_chain_on_success = check_chain_on_success0 "D" + end in + let config = + { + default_config with + delegate_selection = + Round_robin_over + [ + [bootstrap1; bootstrap2; bootstrap3; bootstrap4]; + [bootstrap2; bootstrap3; bootstrap1; bootstrap4]; + ]; + timeout = 30; + } + in + run + ~config + [ + (1, (module Node_a_hooks)); + (1, (module Node_b_hooks)); + (1, (module Node_c_hooks)); + (1, (module Node_d_hooks)); + ] + +let tests = + let open Tezos_base_test_helpers.Tztest in + [ + tztest "reaches level 5" `Quick test_level_5; + tztest "scenario t1" `Quick test_scenario_t1; + tztest "scenario t2" `Quick test_scenario_t2; + tztest "scenario t3" `Quick test_scenario_t3; + (* See issue https://gitlab.com/nomadic-labs/tezos/-/issues/518 *) + (* tztest "scenario f1" `Quick test_scenario_f1; *) + tztest "scenario f2" `Quick test_scenario_f2; + tztest "scenario m1" `Quick test_scenario_m1; + tztest "scenario m2" `Quick test_scenario_m2; + tztest "scenario m3" `Quick test_scenario_m3; + tztest "scenario m4" `Quick test_scenario_m4; + tztest "scenario m5" `Quick test_scenario_m5; + tztest "scenario m6" `Quick test_scenario_m6; + tztest "scenario m7" `Quick test_scenario_m7; + tztest "scenario m8" `Quick test_scenario_m8; + ] diff --git a/src/proto_012_PsiThaCa/lib_delegate/tezos-accuser-012-PsiThaCa-commands.opam b/src/proto_012_PsiThaCa/lib_delegate/tezos-accuser-012-PsiThaCa-commands.opam new file mode 100644 index 000000000000..a24ab4a5525d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/tezos-accuser-012-PsiThaCa-commands.opam @@ -0,0 +1,23 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-shell-services" + "tezos-client-base" + "tezos-client-commands" + "tezos-client-012-PsiThaCa" + "tezos-baking-012-PsiThaCa" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol-specific commands for `tezos-accuser`" diff --git a/src/proto_012_PsiThaCa/lib_delegate/tezos-baking-012-PsiThaCa-commands.opam b/src/proto_012_PsiThaCa/lib_delegate/tezos-baking-012-PsiThaCa-commands.opam new file mode 100644 index 000000000000..ab64e9f28769 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/tezos-baking-012-PsiThaCa-commands.opam @@ -0,0 +1,24 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-shell-services" + "tezos-shell-context" + "tezos-client-base" + "tezos-client-commands" + "tezos-client-012-PsiThaCa" + "tezos-baking-012-PsiThaCa" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol-specific commands for baking" diff --git a/src/proto_012_PsiThaCa/lib_delegate/tezos-baking-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_delegate/tezos-baking-012-PsiThaCa.opam new file mode 100644 index 000000000000..c187df0ebf94 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/tezos-baking-012-PsiThaCa.opam @@ -0,0 +1,33 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "tezos-tooling" { with-test } + "tezos-012-PsiThaCa-test-helpers" { with-test } + "dune" { >= "2.9" } + "tezos-base" + "tezos-version" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-shell-context" + "tezos-shell-services" + "tezos-context" + "tezos-client-base" + "tezos-client-commands" + "tezos-client-012-PsiThaCa" + "tezos-rpc-http-client-unix" + "lwt-canceler" { >= "0.3" & < "0.4" } + "lwt-exit" + "tezos-base-test-helpers" {with-test} + "tezos-protocol-012-PsiThaCa-parameters" {with-test} + "alcotest-lwt" {with-test} +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: base library for `tezos-baker/accuser`" diff --git a/src/proto_012_PsiThaCa/lib_delegate/tezos-endorser-012-PsiThaCa-commands.opam b/src/proto_012_PsiThaCa/lib_delegate/tezos-endorser-012-PsiThaCa-commands.opam new file mode 100644 index 000000000000..a0fca5b806db --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_delegate/tezos-endorser-012-PsiThaCa-commands.opam @@ -0,0 +1,23 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-shell-services" + "tezos-client-base" + "tezos-client-commands" + "tezos-client-012-PsiThaCa" + "tezos-baking-012-PsiThaCa" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol-specific commands for `tezos-endorser`" diff --git a/src/proto_012_PsiThaCa/lib_parameters/.ocamlformat b/src/proto_012_PsiThaCa/lib_parameters/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_parameters/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_parameters/default_parameters.ml b/src/proto_012_PsiThaCa/lib_parameters/default_parameters.ml new file mode 100644 index 000000000000..c2f8a1c05d00 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_parameters/default_parameters.ml @@ -0,0 +1,224 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol.Alpha_context + +let constants_mainnet = + let consensus_committee_size = 7000 in + let block_time = 30 in + let Constants.Generated. + { + consensus_threshold; + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + } = + Constants.Generated.generate + ~consensus_committee_size + ~blocks_per_minute:{numerator = 60; denominator = block_time} + in + { + Constants.preserved_cycles = 5; + blocks_per_cycle = 8192l; + blocks_per_commitment = 64l; + blocks_per_stake_snapshot = 512l; + blocks_per_voting_period = 40960l (* 5 cycles *); + hard_gas_limit_per_operation = Gas.Arith.(integral_of_int_exn 1_040_000); + hard_gas_limit_per_block = Gas.Arith.(integral_of_int_exn 5_200_000); + proof_of_work_threshold = Int64.(sub (shift_left 1L 46) 1L); + tokens_per_roll = Tez.(mul_exn one 6_000); + seed_nonce_revelation_tip = + (match Tez.(one /? 8L) with Ok c -> c | Error _ -> assert false); + origination_size = 257; + baking_reward_fixed_portion (* 10_000_000 mutez *); + baking_reward_bonus_per_slot (* 4_286 mutez *); + endorsing_reward_per_slot (* 2_857 mutez *); + hard_storage_limit_per_operation = Z.of_int 60_000; + cost_per_byte = Tez.of_mutez_exn 250L; + quorum_min = 20_00l; + quorum_max = 70_00l; + min_proposal_quorum = 5_00l; + (* liquidity_baking_subsidy is 1/16th of maximum total rewards for a block *) + liquidity_baking_subsidy = Tez.of_mutez_exn 2_500_000L; + (* level after protocol activation when liquidity baking shuts off: + about 6 months after first activation on mainnet *) + liquidity_baking_sunset_level = 3_063_809l; + (* 1/3 window size of 2000 blocks with precision of 1000 for integer computation *) + liquidity_baking_escape_ema_threshold = 666_667l; + (* The rationale behind the value of this constant is that an + operation should be considered alive for about one hour: + + minimal_block_delay context * max_operations_ttl = 3600 + + The unit for this value is a block. + *) + max_operations_time_to_live = 120; + minimal_block_delay = Period.of_seconds_exn (Int64.of_int block_time); + delay_increment_per_round = Period.of_seconds_exn 15L; + consensus_committee_size; + consensus_threshold; + (* 4667 slots *) + minimal_participation_ratio = {numerator = 2; denominator = 3}; + max_slashing_period = 2; + frozen_deposits_percentage = 10; + double_baking_punishment = Tez.(mul_exn one 640); + ratio_of_frozen_deposits_slashed_per_double_endorsement = + {numerator = 1; denominator = 2}; + delegate_selection = Constants.Random; + } + +let constants_sandbox = + let consensus_committee_size = 256 in + let block_time = 1 in + let Constants.Generated. + { + consensus_threshold = _; + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + } = + Constants.Generated.generate + ~consensus_committee_size + ~blocks_per_minute:{numerator = 60; denominator = block_time} + in + { + constants_mainnet with + Constants.preserved_cycles = 2; + blocks_per_cycle = 8l; + blocks_per_commitment = 4l; + blocks_per_stake_snapshot = 4l; + blocks_per_voting_period = 64l; + proof_of_work_threshold = Int64.of_int (-1); + liquidity_baking_sunset_level = 128l; + minimal_block_delay = Period.of_seconds_exn (Int64.of_int block_time); + delay_increment_per_round = Period.one_second; + consensus_committee_size = 256; + consensus_threshold = 0; + baking_reward_fixed_portion (* 333_333 mutez *); + baking_reward_bonus_per_slot (* 3_921 mutez *); + endorsing_reward_per_slot (* 2_604 mutez *); + max_slashing_period = 2; + frozen_deposits_percentage = 5; + } + +let constants_test = + let consensus_committee_size = 25 in + let Constants.Generated. + { + consensus_threshold; + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + } = + Constants.Generated.generate + ~consensus_committee_size + ~blocks_per_minute:{numerator = 2; denominator = 1} + in + { + constants_mainnet with + Constants.preserved_cycles = 3; + blocks_per_cycle = 12l; + blocks_per_commitment = 4l; + blocks_per_stake_snapshot = 4l; + blocks_per_voting_period = 24l; + proof_of_work_threshold = Int64.of_int (-1); + liquidity_baking_sunset_level = 4096l; + consensus_committee_size; + consensus_threshold (* 17 slots *); + max_slashing_period = 2; + baking_reward_fixed_portion (* 10 tez *); + baking_reward_bonus_per_slot (* 1.25 tez *); + endorsing_reward_per_slot (* 0.8 tez *); + frozen_deposits_percentage = + 5 + (* not 10 so that multiplication and + divisions do not easily get + intermingled *); + } + +let test_commitments = + lazy + (List.map + (fun (bpkh, amount) -> + let blinded_public_key_hash = + Protocol.Blinded_public_key_hash.of_b58check_exn bpkh + in + let amount = Protocol.Alpha_context.Tez.of_mutez_exn amount in + {Protocol.Alpha_context.Commitment.blinded_public_key_hash; amount}) + [ + ("btz1bRL4X5BWo2Fj4EsBdUwexXqgTf75uf1qa", 23932454669343L); + ("btz1SxjV1syBgftgKy721czKi3arVkVwYUFSv", 72954577464032L); + ("btz1LtoNCjiW23txBTenALaf5H6NKF1L3c1gw", 217487035428348L); + ("btz1SUd3mMhEBcWudrn8u361MVAec4WYCcFoy", 4092742372031L); + ("btz1MvBXf4orko1tsGmzkjLbpYSgnwUjEe81r", 17590039016550L); + ("btz1LoDZ3zsjgG3k3cqTpUMc9bsXbchu9qMXT", 26322312350555L); + ("btz1RMfq456hFV5AeDiZcQuZhoMv2dMpb9hpP", 244951387881443L); + ("btz1Y9roTh4A7PsMBkp8AgdVFrqUDNaBE59y1", 80065050465525L); + ("btz1Q1N2ePwhVw5ED3aaRVek6EBzYs1GDkSVD", 3569618927693L); + ("btz1VFFVsVMYHd5WfaDTAt92BeQYGK8Ri4eLy", 9034781424478L); + ]) + +let bootstrap_accounts_strings = + [ + "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"; + "edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9"; + "edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV"; + "edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU"; + "edpkv8EUUH68jmo3f7Um5PezmfGrRF24gnfLpH3sVNwJnV5bVCxL2n"; + ] + +let bootstrap_balance = Tez.of_mutez_exn 4_000_000_000_000L + +let compute_accounts = + List.map (fun s -> + let public_key = Signature.Public_key.of_b58check_exn s in + let public_key_hash = Signature.Public_key.hash public_key in + Parameters. + { + public_key_hash; + public_key = Some public_key; + amount = bootstrap_balance; + }) + +let bootstrap_accounts = compute_accounts bootstrap_accounts_strings + +let make_bootstrap_account (pkh, pk, amount) = + Parameters.{public_key_hash = pkh; public_key = Some pk; amount} + +let parameters_of_constants ?(bootstrap_accounts = bootstrap_accounts) + ?(bootstrap_contracts = []) ?(commitments = []) constants = + Parameters. + { + bootstrap_accounts; + bootstrap_contracts; + commitments; + constants; + security_deposit_ramp_up_cycles = None; + no_reward_cycles = None; + } + +let json_of_parameters parameters = + Data_encoding.Json.construct Parameters.encoding parameters diff --git a/src/proto_012_PsiThaCa/lib_parameters/default_parameters.mli b/src/proto_012_PsiThaCa/lib_parameters/default_parameters.mli new file mode 100644 index 000000000000..3551ac5d3117 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_parameters/default_parameters.mli @@ -0,0 +1,48 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol.Alpha_context + +val constants_mainnet : Constants.parametric + +val constants_sandbox : Constants.parametric + +val constants_test : Constants.parametric + +val test_commitments : Commitment.t list lazy_t + +val make_bootstrap_account : + Signature.public_key_hash * Signature.public_key * Tez.t -> + Parameters.bootstrap_account + +val parameters_of_constants : + ?bootstrap_accounts:Parameters.bootstrap_account list -> + ?bootstrap_contracts:Parameters.bootstrap_contract list -> + ?commitments:Commitment.t list -> + Constants.parametric -> + Parameters.t + +val json_of_parameters : Parameters.t -> Data_encoding.json diff --git a/src/proto_012_PsiThaCa/lib_parameters/dune b/src/proto_012_PsiThaCa/lib_parameters/dune new file mode 100644 index 000000000000..60eedffa945f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_parameters/dune @@ -0,0 +1,47 @@ +(library + (name tezos_protocol_012_PsiThaCa_parameters) + (instrumentation (backend bisect_ppx)) + (public_name tezos-protocol-012-PsiThaCa-parameters) + (modules :standard \ gen) + (libraries tezos-base + tezos-base.unix + tezos-protocol-environment + tezos-protocol-012-PsiThaCa) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -linkall)) +) + +(executable + (name gen) + (libraries tezos-base + tezos-protocol-012-PsiThaCa-parameters) + (modules gen) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa_parameters + -open Tezos_protocol_012_PsiThaCa + -linkall))) + +(rule + (targets sandbox-parameters.json) + (deps gen.exe) + (action (run %{deps} --sandbox))) + +(rule + (targets test-parameters.json) + (deps gen.exe) + (action (run %{deps} --test))) + +(rule + (targets mainnet-parameters.json) + (deps gen.exe) + (action (run %{deps} --mainnet))) + +(install + (section lib) + (files sandbox-parameters.json test-parameters.json mainnet-parameters.json)) + +(rule + (alias runtest_lint) + (deps (glob_files *.ml{,i})) + (action (run %{lib:tezos-tooling:lint.sh} %{deps}))) diff --git a/src/proto_012_PsiThaCa/lib_parameters/dune-project b/src/proto_012_PsiThaCa/lib_parameters/dune-project new file mode 100644 index 000000000000..c6a0caba245e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_parameters/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-protocol-alpha-parameters) diff --git a/src/proto_012_PsiThaCa/lib_parameters/gen.ml b/src/proto_012_PsiThaCa/lib_parameters/gen.ml new file mode 100644 index 000000000000..8fcc504044e5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_parameters/gen.ml @@ -0,0 +1,62 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Prints the json encoding of the parametric constants of protocol alpha. + $ dune utop src/proto_alpha/lib_protocol/test/helpers/ constants.ml +*) + +let () = + let print_usage_and_fail s = + Printf.eprintf "Usage: %s [ --sandbox | --test | --mainnet ]" Sys.argv.(0) ; + raise (Invalid_argument s) + in + let dump parameters file = + let str = + Data_encoding.Json.to_string + (Default_parameters.json_of_parameters parameters) + in + let fd = open_out file in + output_string fd str ; + close_out fd + in + if Array.length Sys.argv < 2 then print_usage_and_fail "" + else + match Sys.argv.(1) with + | "--sandbox" -> + dump + Default_parameters.(parameters_of_constants constants_sandbox) + "sandbox-parameters.json" + | "--test" -> + dump + Default_parameters.( + parameters_of_constants + ~commitments:(Lazy.force test_commitments) + constants_sandbox) + "test-parameters.json" + | "--mainnet" -> + dump + Default_parameters.(parameters_of_constants constants_mainnet) + "mainnet-parameters.json" + | s -> print_usage_and_fail s diff --git a/src/proto_012_PsiThaCa/lib_parameters/tezos-protocol-012-PsiThaCa-parameters.opam b/src/proto_012_PsiThaCa/lib_parameters/tezos-protocol-012-PsiThaCa-parameters.opam new file mode 100644 index 000000000000..9abeaecaaef3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_parameters/tezos-protocol-012-PsiThaCa-parameters.opam @@ -0,0 +1,18 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: parameters" diff --git a/src/proto_012_PsiThaCa/lib_plugin/.ocamlformat b/src/proto_012_PsiThaCa/lib_plugin/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_plugin/dune b/src/proto_012_PsiThaCa/lib_plugin/dune new file mode 100644 index 000000000000..aa7a0db4f654 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/dune @@ -0,0 +1,27 @@ +(library + (name tezos_protocol_plugin_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-protocol-plugin-012-PsiThaCa) + (libraries tezos-base + tezos-protocol-012-PsiThaCa + tezos-stdlib-unix + ) + (modules (:standard) \ Plugin_registerer) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_protocol_012_PsiThaCa + -open Tezos_stdlib_unix + ))) + +(library + (name tezos_protocol_plugin_012_PsiThaCa_registerer) + (instrumentation (backend bisect_ppx)) + (public_name tezos-protocol-plugin-012-PsiThaCa-registerer) + (libraries tezos-base + tezos-embedded-protocol-012-PsiThaCa + tezos-protocol-plugin-012-PsiThaCa + tezos-shell) + (modules Plugin_registerer) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_embedded_protocol_012_PsiThaCa + -open Tezos_protocol_plugin_012_PsiThaCa + -open Tezos_shell))) diff --git a/src/proto_012_PsiThaCa/lib_plugin/dune-project b/src/proto_012_PsiThaCa/lib_plugin/dune-project new file mode 100644 index 000000000000..9a66059d4b1d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-filters-alpha) diff --git a/src/proto_012_PsiThaCa/lib_plugin/plugin.ml b/src/proto_012_PsiThaCa/lib_plugin/plugin.ml new file mode 100644 index 000000000000..794a88b6a704 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/plugin.ml @@ -0,0 +1,3277 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Nomadic Development. *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** The assumed number of blocks between operation-creation time and + the actual time when the operation is included in a block. *) +let default_operation_inclusion_latency = 3 + +type Environment.Error_monad.error += Cannot_parse_operation (* `Branch *) + +type Environment.Error_monad.error += Cannot_serialize_log + +type Environment.Error_monad.error += Cannot_retrieve_predecessor_level + +let () = + Environment.Error_monad.register_error_kind + `Branch + ~id:"operation.cannot_parse" + ~title:"Cannot parse operation" + ~description:"The operation is ill-formed or for another protocol version" + ~pp:(fun ppf () -> Format.fprintf ppf "The operation cannot be parsed") + Data_encoding.unit + (function Cannot_parse_operation -> Some () | _ -> None) + (fun () -> Cannot_parse_operation) ; + (* Cannot serialize log *) + Environment.Error_monad.register_error_kind + `Temporary + ~id:"michelson_v1.cannot_serialize_log" + ~title:"Not enough gas to serialize execution trace" + ~description: + "Execution trace with stacks was to big to be serialized with the \ + provided gas" + Data_encoding.empty + (function Cannot_serialize_log -> Some () | _ -> None) + (fun () -> Cannot_serialize_log) ; + Environment.Error_monad.register_error_kind + `Temporary + ~id:"cannot_retrieve_predecessor_level" + ~title:"Cannot retrieve predecessor level" + ~description:"Cannot retrieve predecessor level." + Data_encoding.empty + (function Cannot_retrieve_predecessor_level -> Some () | _ -> None) + (fun () -> Cannot_retrieve_predecessor_level) + +module Mempool = struct + type nanotez = Q.t + + let nanotez_enc : nanotez Data_encoding.t = + let open Data_encoding in + def + "nanotez" + ~title:"A thousandth of a mutez" + ~description:"One thousand nanotez make a mutez (1 tez = 1e9 nanotez)" + (conv + (fun q -> (q.Q.num, q.Q.den)) + (fun (num, den) -> {Q.num; den}) + (tup2 z z)) + + let manager_op_replacement_factor_enc : Q.t Data_encoding.t = + let open Data_encoding in + def + "manager operation replacement factor" + ~title:"A manager operation's replacement factor" + ~description: + "The fee and fee/gas ratio of an operation to replace another" + (conv + (fun q -> (q.Q.num, q.Q.den)) + (fun (num, den) -> {Q.num; den}) + (tup2 z z)) + + type config = { + minimal_fees : Tez.t; + minimal_nanotez_per_gas_unit : nanotez; + minimal_nanotez_per_byte : nanotez; + allow_script_failure : bool; + (** If [true], this makes [post_filter_manager] unconditionally return + [`Passed_postfilter filter_state], no matter the operation's + success. *) + clock_drift : Period.t option; + replace_by_fee_factor : Q.t; + (** This field determines the amount of additional fees (given as a + factor of the declared fees) a manager should add to an operation + in order to (eventually) replace an existing (prechecked) one + in the mempool. Note that other criteria, such as the gas ratio, + are also taken into account to decide whether to accept the + replacement or not. *) + } + + let default_minimal_fees = + match Tez.of_mutez 100L with None -> assert false | Some t -> t + + let default_minimal_nanotez_per_gas_unit = Q.of_int 100 + + let default_minimal_nanotez_per_byte = Q.of_int 1000 + + (* If the drift is not specified, it will be the duration of round zero. + It allows only to spam with one future round. + + /!\ Warning /!\ : current plugin implementation implies that this drift + cumulates with the accepted drift regarding the current head's timestamp. + *) + + let config_encoding : config Data_encoding.t = + let open Data_encoding in + (* 105/100 = 1.05%: This is the minumum fee increase ratio required between + an operation and another one it'd replace in the prevalidator. *) + let replace_factor = Q.make (Z.of_int 105) (Z.of_int 100) in + conv + (fun { + minimal_fees; + minimal_nanotez_per_gas_unit; + minimal_nanotez_per_byte; + allow_script_failure; + clock_drift; + replace_by_fee_factor; + } -> + ( minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + allow_script_failure, + clock_drift, + replace_by_fee_factor )) + (fun ( minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + allow_script_failure, + clock_drift, + replace_by_fee_factor ) -> + { + minimal_fees; + minimal_nanotez_per_gas_unit; + minimal_nanotez_per_byte; + allow_script_failure; + clock_drift; + replace_by_fee_factor; + }) + (obj6 + (dft "minimal_fees" Tez.encoding default_minimal_fees) + (dft + "minimal_nanotez_per_gas_unit" + nanotez_enc + default_minimal_nanotez_per_gas_unit) + (dft + "minimal_nanotez_per_byte" + nanotez_enc + default_minimal_nanotez_per_byte) + (dft "allow_script_failure" bool true) + (opt "clock_drift" Period.encoding) + (dft + "replace_by_fee_factor" + manager_op_replacement_factor_enc + replace_factor)) + + let default_config = + { + minimal_fees = default_minimal_fees; + minimal_nanotez_per_gas_unit = default_minimal_nanotez_per_gas_unit; + minimal_nanotez_per_byte = default_minimal_nanotez_per_byte; + allow_script_failure = true; + clock_drift = None; + replace_by_fee_factor = + Q.make (Z.of_int 105) (Z.of_int 100) + (* Default value of [replace_by_fee_factor] is set to 5% *); + } + + type manager_gas_witness + + (* For each Prechecked manager operation (batched or not), we associate the + following information to its source: + - the operation's hash, needed in case the operation is replaced + afterwards, + - the total fee and gas_limit, needed to compare operations of the same + manager to decide which one has more fees w.r.t. announced gas limit + (modulo replace_by_fee_factor) + *) + type manager_op_info = { + operation_hash : Operation_hash.t; + gas_limit : manager_gas_witness Gas.Arith.t; + fee : Tez.t; + } + + type state = { + grandparent_level_start : Alpha_context.Timestamp.t option; + round_zero_duration : Period.t option; + op_prechecked_managers : manager_op_info Signature.Public_key_hash.Map.t; + (** All managers that are the source of manager operations + prechecked in the mempool. Each manager in the map is associated to + a record of type [manager_op_info] (See for record details above). + Each manager in the map should be accessible + with an operation hash in [operation_hash_to_manager]. *) + operation_hash_to_manager : Signature.Public_key_hash.t Operation_hash.Map.t; + (** Map of operation hash to manager used to remove a manager from + [op_prechecked_managers] with an operation hash. Each manager in the + map should also be in [op_prechecked_managers]. *) + } + + let empty : state = + { + grandparent_level_start = None; + round_zero_duration = None; + op_prechecked_managers = Signature.Public_key_hash.Map.empty; + operation_hash_to_manager = Operation_hash.Map.empty; + } + + let init config ?(validation_state : validation_state option) ~predecessor () + = + ignore config ; + (match validation_state with + | None -> return empty + | Some {ctxt; _} -> + let { + Tezos_base.Block_header.fitness = predecessor_fitness; + timestamp = predecessor_timestamp; + _; + } = + predecessor.Tezos_base.Block_header.shell + in + Alpha_context.Fitness.predecessor_round_from_raw predecessor_fitness + >>?= fun grandparent_round -> + Alpha_context.Fitness.round_from_raw predecessor_fitness + >>?= fun predecessor_round -> + Alpha_context.( + let round_durations = Constants.round_durations ctxt in + let round_zero_duration = + Round.round_duration round_durations Round.zero + in + Round.level_offset_of_round + round_durations + ~round:Round.(succ grandparent_round) + >>?= fun proposal_level_offset -> + Round.level_offset_of_round round_durations ~round:predecessor_round + >>?= fun proposal_round_offset -> + Period.(add proposal_level_offset proposal_round_offset) + >>?= fun proposal_offset -> + return + { + empty with + grandparent_level_start = + Some Timestamp.(predecessor_timestamp - proposal_offset); + round_zero_duration = Some round_zero_duration; + })) + >|= Environment.wrap_tzresult + + let on_flush config filter_state ?(validation_state : validation_state option) + ~predecessor () = + ignore filter_state ; + init config ?validation_state ~predecessor () + + let remove ~(filter_state : state) oph = + match + Operation_hash.Map.find oph filter_state.operation_hash_to_manager + with + | None -> filter_state + | Some source -> + { + filter_state with + op_prechecked_managers = + Signature.Public_key_hash.Map.remove + source + filter_state.op_prechecked_managers; + operation_hash_to_manager = + Operation_hash.Map.remove oph filter_state.operation_hash_to_manager; + } + + let get_manager_operation_gas_and_fee contents = + let open Operation in + let l = to_list (Contents_list contents) in + List.fold_left + (fun acc -> function + | Contents (Manager_operation {fee; gas_limit; _}) -> ( + match acc with + | Error _ as e -> e + | Ok (total_fee, total_gas) -> ( + match Tez.(total_fee +? fee) with + | Ok total_fee -> + Ok (total_fee, Gas.Arith.add total_gas gas_limit) + | Error _ as e -> e)) + | _ -> acc) + (Ok (Tez.zero, Gas.Arith.zero)) + l + + type Environment.Error_monad.error += Fees_too_low + + let () = + Environment.Error_monad.register_error_kind + `Permanent + ~id:"prefilter.fees_too_low" + ~title:"Operation fees are too low" + ~description:"Operation fees are too low" + ~pp:(fun ppf () -> Format.fprintf ppf "Operation fees are too low") + Data_encoding.unit + (function Fees_too_low -> Some () | _ -> None) + (fun () -> Fees_too_low) + + type Environment.Error_monad.error += Manager_restriction + + let () = + Environment.Error_monad.register_error_kind + `Temporary + ~id:"plugin_filter.manager_restriction" + ~title:"Only one manager operation per manager per block allowed" + ~description:"Only one manager operation per manager per block allowed" + ~pp:(fun ppf () -> + Format.fprintf + ppf + "Only one manager operation per manager per block allowed") + Data_encoding.unit + (function Manager_restriction -> Some () | _ -> None) + (fun () -> Manager_restriction) + + (* TODO: https://gitlab.com/tezos/tezos/-/issues/2238 + Write unit tests for the feature 'replace-by-fee' and for other changes + introduced by other MRs in the plugin. *) + (* In order to decide if the new operation can replace an old one from the + same manager, we check if its fees (resp. fees/gas ratio) are greater than + (or equal to) the old operations's fees (resp. fees/gas ratio), bumped by + the factor [config.replace_by_fee_factor]. + *) + let better_fees_and_ratio = + let bump config q = Q.mul q config.replace_by_fee_factor in + fun config old_gas old_fee new_gas new_fee -> + let old_fee = Tez.to_mutez old_fee |> Z.of_int64 |> Q.of_bigint in + let old_gas = Gas.Arith.integral_to_z old_gas |> Q.of_bigint in + let new_fee = Tez.to_mutez new_fee |> Z.of_int64 |> Q.of_bigint in + let new_gas = Gas.Arith.integral_to_z new_gas |> Q.of_bigint in + let old_ratio = Q.div old_fee old_gas in + let new_ratio = Q.div new_fee new_gas in + Q.compare new_ratio (bump config old_ratio) >= 0 + && Q.compare new_fee (bump config old_fee) >= 0 + + let check_manager_restriction config filter_state source ~fee ~gas_limit = + match + Signature.Public_key_hash.Map.find + source + filter_state.op_prechecked_managers + with + | None -> `Fresh + | Some {operation_hash = old_hash; gas_limit = old_gas; fee = old_fee} -> + (* Manager already seen: one manager per block limitation triggered. + Can replace old operation if new operation's fees are better *) + if better_fees_and_ratio config old_gas old_fee gas_limit fee then + `Replace old_hash + else + `Fail (`Branch_delayed [Environment.wrap_tzerror Manager_restriction]) + + let pre_filter_manager : + type t. + config -> + state -> + public_key_hash -> + int -> + t Kind.manager contents_list -> + [ `Passed_prefilter + | `Branch_refused of tztrace + | `Branch_delayed of tztrace + | `Refused of tztrace + | `Outdated of tztrace ] = + fun config filter_state source size op -> + let check_gas_and_fee fee gas_limit = + let fees_in_nanotez = + Q.mul (Q.of_int64 (Tez.to_mutez fee)) (Q.of_int 1000) + in + let minimal_fees_in_nanotez = + Q.mul (Q.of_int64 (Tez.to_mutez config.minimal_fees)) (Q.of_int 1000) + in + let minimal_fees_for_gas_in_nanotez = + Q.mul + config.minimal_nanotez_per_gas_unit + (Q.of_bigint @@ Gas.Arith.integral_to_z gas_limit) + in + let minimal_fees_for_size_in_nanotez = + Q.mul config.minimal_nanotez_per_byte (Q.of_int size) + in + if + Q.compare + fees_in_nanotez + (Q.add + minimal_fees_in_nanotez + (Q.add + minimal_fees_for_gas_in_nanotez + minimal_fees_for_size_in_nanotez)) + >= 0 + then `Passed_prefilter + else `Refused [Environment.wrap_tzerror Fees_too_low] + in + match get_manager_operation_gas_and_fee op with + | Error err -> `Refused (Environment.wrap_tztrace err) + | Ok (fee, gas_limit) -> ( + match + check_manager_restriction config filter_state source ~fee ~gas_limit + with + | `Fail errs -> errs + | `Fresh | `Replace _ -> check_gas_and_fee fee gas_limit) + + type Environment.Error_monad.error += Outdated_endorsement + + let () = + Environment.Error_monad.register_error_kind + `Temporary + ~id:"prefilter.outdated_endorsement" + ~title:"Endorsement is outdated" + ~description:"Endorsement is outdated" + ~pp:(fun ppf () -> Format.fprintf ppf "Endorsement is outdated") + Data_encoding.unit + (function Outdated_endorsement -> Some () | _ -> None) + (fun () -> Outdated_endorsement) + + type Environment.Error_monad.error += Wrong_operation + + let () = + Environment.Error_monad.register_error_kind + `Temporary + ~id:"prefilter.wrong_operation" + ~title:"Wrong operation" + ~description:"Failing_noop and old endorsement format are not accepted." + ~pp:(fun ppf () -> + Format.fprintf + ppf + "Failing_noop and old endorsement format are not accepted") + Data_encoding.unit + (function Wrong_operation -> Some () | _ -> None) + (fun () -> Wrong_operation) + + type Environment.Error_monad.error += Consensus_operation_in_far_future + + let () = + Environment.Error_monad.register_error_kind + `Branch + ~id:"prefilter.Consensus_operation_in_far_future" + ~title:"Consensus operation in far future" + ~description:"Consensus operation too far in the future are not accepted." + ~pp:(fun ppf () -> + Format.fprintf + ppf + "Consensus operation too far in the future are not accepted.") + Data_encoding.unit + (function Consensus_operation_in_far_future -> Some () | _ -> None) + (fun () -> Consensus_operation_in_far_future) + + (** {2} consensus operation filtering. + + In Tenderbake, we increased a lot the number of consensus + operations, therefore it seems necessary to be able to filter consensus + operations that could be produced by a Byzantine baker mis-using + its right to produce operations in future rounds or levels. + + We consider the situation where the head is at level [h_l], + round [h_r], and with timestamp [h_ts], with the predecessor of the head + being at round [hp_r]. + We receive at a time [now] a consensus operation for level [op_l] and + round [op_r]. + + A consensus operation is considered too far in the future, and therefore filtered, + if the earliest possible starting time of its round is greater than the + current time plus a safety margin of [config.clock_drift]. + + To consider potential level 2 reorgs, we first compute the expected + timestamp of round zero at previous level [hp0_ts], + + All ops at level p_l and round r' such that time(r') is greater than (now + drift) are + deemed too far in the future: + + h_r op_ts now+drift (h_l,r') + hp0_ts h_0 h_l | | | + +----+-----+---------+-------------------+--+-----+--------------+----------- + | | | | | | | + | h_ts h_r end time | now | earliest expected + | | | | time of round r' + |<----op_r rounds duration -------->| | + | + |<--------------- operations kept ---->|<-rejected----------... + | + |<-----------operations considered by the filter -----------... + + For an operation on a proposal at the next level, we consider the minimum + starting time of the operation's round, obtained by assuming that the proposal + at the next level was built on top of a proposal at round 0 for the current + level, itself based on a proposal at round 0 of previous level. + Operations on proposal with higher levels are treated similarly. + + All ops at the next level and round r' such that timestamp(r') > now+drift + are deemed too far in the future. + + r=0 r=1 h_r now now+drift (h_l+1,r') + hp0_ts h_0 h_l h_l | | | + +----+---- |-------+----+---------+----------+----------+---------- + | | | | | + | t0 | h_ts earliest expected + | | | | time of round r' + |<--- | earliest| | + | next level| | + | |<---------------------------------->| + round_offset(r') + + *) + + (** At a given level a consensus operation is acceptable if its earliest + expected timestamp, [op_earliest_ts] is below the current clock with an + accepted drift for the clock given by a configuration. *) + let acceptable ~drift ~op_earliest_ts ~now_timestamp = + Timestamp.( + now_timestamp +? drift >|? fun now_drifted -> + op_earliest_ts <= now_drifted) + + (** Check that an operation with the given [op_round], at level [op_level] + is likely to be correct, meaning it could have been produced before + now (+ the safety margin from configuration). + + Given an operation at level greater or equal than/to the current level, we + compute the expected timestamp of the operation's round. If the operation + is at a greater level, we assume that it is based on the proposal at round + zero of the current level. + + All operations whose (level, round) is lower than or equal to the current + head are deemed valid. + Note that in case where their is a high drift in the computer clock, they + might not have been considered valid by comparing their expected timestamp + to the clock. + + This is a stricter than necessary filter as it will reject operations that + could be valid in the current timeframe if the proposal they endorse is + built over a predecessor of the current proposal that would be of lower + round than the current one. + + What can we do that would be smarter: get current head's predecessor round + and timestamp to compute the timestamp t0 of a predecessor that would have + been proposed at round 0. + + Timestamp of round at current level for an alternative head that would be + based on such proposal would be computed based on t0. + For level higher than current head, compute the round's earliest timestamp + if all proposal passed at round 0 starting from t0. + *) + let acceptable_op ~config ~round_durations ~round_zero_duration + ~proposal_level ~proposal_round ~proposal_timestamp + ~(proposal_predecessor_level_start : Timestamp.t) ~op_level ~op_round + ~now_timestamp = + if + Raw_level.(succ op_level < proposal_level) + || (op_level = proposal_level && op_round <= proposal_round) + then + (* Past and current round operations are not in the future *) + (* This case could be handled directly in `pre_filter_far_future_consensus_ops` + for a (slightly) better performance. *) + Ok true + else + (* If, by some tolerance on local clock drift, the timestamp of the + current head is itself in the future, we use this time instead of + now_timestamp *) + let now_timestamp = Timestamp.(max now_timestamp proposal_timestamp) in + (* Computing when the current level started. *) + let drift = + Option.value ~default:round_zero_duration config.clock_drift + in + (* We compute the earliest timestamp possible [op_earliest_ts] for the + operation's (level,round), as if all proposals were accepted at round 0 + since the previous level. *) + (* Invariant: [op_level + 1 >= proposal_level] *) + let level_offset = Raw_level.(diff (succ op_level) proposal_level) in + Period.mult level_offset round_zero_duration >>? fun time_shift -> + Timestamp.(proposal_predecessor_level_start +? time_shift) + >>? fun earliest_op_level_start -> + (* computing the operations's round start from it's earliest + possible level start *) + Round.timestamp_of_another_round_same_level + round_durations + ~current_round:Round.zero + ~current_timestamp:earliest_op_level_start + ~considered_round:op_round + >>? fun op_earliest_ts -> + (* We finally check that the expected time of the operation is + acceptable *) + acceptable ~drift ~op_earliest_ts ~now_timestamp + + let pre_filter_far_future_consensus_ops config + ~filter_state:({grandparent_level_start; round_zero_duration; _} : state) + ?validation_state_before + ({level = op_level; round = op_round; _} : consensus_content) : bool Lwt.t + = + match + (grandparent_level_start, validation_state_before, round_zero_duration) + with + | (None, _, _) | (_, None, _) | (_, _, None) -> Lwt.return_true + | ( Some grandparent_level_start, + Some validation_state_before, + Some round_zero_duration ) -> ( + let ctxt : t = validation_state_before.ctxt in + match validation_state_before.mode with + | Application _ | Partial_application _ | Full_construction _ -> + assert false + (* Prefilter is always applied in mempool mode aka Partial_construction *) + | Partial_construction {predecessor_round = proposal_round; _} -> ( + (let proposal_timestamp = + Alpha_context.Timestamp.predecessor ctxt + in + let now_timestamp = Systime_os.now () |> Time.System.to_protocol in + let Level.{level; _} = Alpha_context.Level.current ctxt in + let proposal_level = + match Raw_level.pred level with + | None -> + (* mempool level is set to the successor of the + current head *) + assert false + | Some proposal_level -> proposal_level + in + let round_durations = + Alpha_context.Constants.round_durations ctxt + in + Lwt.return + @@ acceptable_op + ~config + ~round_durations + ~round_zero_duration + ~proposal_level + ~proposal_round + ~proposal_timestamp + ~proposal_predecessor_level_start:grandparent_level_start + ~op_level + ~op_round + ~now_timestamp) + >>= function + | Ok b -> Lwt.return b + | _ -> Lwt.return_false)) + + (** A quasi infinite amount of "valid" (pre)endorsements could be + sent by a committee member, one for each possible round number. + + This filter rejects (pre)endorsements that refer to a round + that could not have been reached within the time span between + the last head's timestamp and the current local clock. + + We add [config.clock_drift] time as a safety margin. + *) + let pre_filter config ~(filter_state : state) ?validation_state_before + (Operation_data {contents; _} as op : Operation.packed_protocol_data) = + let bytes = + (WithExceptions.Option.get ~loc:__LOC__ + @@ Data_encoding.Binary.fixed_length + Tezos_base.Operation.shell_header_encoding) + + Data_encoding.Binary.length Operation.protocol_data_encoding op + in + match contents with + | Single (Failing_noop _) -> + Lwt.return (`Refused [Environment.wrap_tzerror Wrong_operation]) + | Single (Preendorsement consensus_content) + | Single (Endorsement consensus_content) -> + pre_filter_far_future_consensus_ops + ~filter_state + config + ?validation_state_before + consensus_content + >>= fun keep -> + if keep then Lwt.return `Passed_prefilter + else + Lwt.return + (`Branch_refused + [Environment.wrap_tzerror Consensus_operation_in_far_future]) + | Single (Seed_nonce_revelation _) + | Single (Double_preendorsement_evidence _) + | Single (Double_endorsement_evidence _) + | Single (Double_baking_evidence _) + | Single (Activate_account _) + | Single (Proposals _) + | Single (Ballot _) -> + Lwt.return @@ `Passed_prefilter + | Single (Manager_operation {source; _}) as op -> + Lwt.return @@ pre_filter_manager config filter_state source bytes op + | Cons (Manager_operation {source; _}, _) as op -> + Lwt.return @@ pre_filter_manager config filter_state source bytes op + + let precheck_manager : + type t. + config -> + state -> + validation_state -> + Tezos_base.Operation.shell_header -> + t Kind.manager protocol_data -> + fee:Tez.t -> + gas_limit:manager_gas_witness Gas.Arith.t -> + public_key_hash -> + [> `Prechecked_manager + | `Prechecked_manager_with_replace of Operation_hash.t + | `Branch_delayed of tztrace + | `Branch_refused of tztrace + | `Refused of tztrace + | `Outdated of tztrace ] + Lwt.t = + fun config + filter_state + validation_state + shell + ({contents; _} as protocol_data : t Kind.manager protocol_data) + ~fee + ~gas_limit + source -> + let precheck_manager_and_check_signature ~on_success = + ( Main.precheck_manager validation_state contents >>=? fun () -> + let (raw_operation : t Kind.manager operation) = + Alpha_context.{shell; protocol_data} + in + Main.check_manager_signature validation_state contents raw_operation ) + >|= function + | Ok () -> on_success + | Error err -> ( + let err = Environment.wrap_tztrace err in + match classify_trace err with + | Branch -> `Branch_refused err + | Permanent -> `Refused err + | Temporary -> `Branch_delayed err + | Outdated -> `Outdated err) + in + match + check_manager_restriction config filter_state source ~fee ~gas_limit + with + | `Fail err -> Lwt.return err + | `Fresh -> + precheck_manager_and_check_signature ~on_success:`Prechecked_manager + | `Replace old_oph -> + precheck_manager_and_check_signature + ~on_success:(`Prechecked_manager_with_replace old_oph) + + let add_manager_restriction filter_state oph info source = + { + filter_state with + op_prechecked_managers = + (* Manager not seen yet, record it for next ops *) + Signature.Public_key_hash.Map.add + source + info + filter_state.op_prechecked_managers; + operation_hash_to_manager = + Operation_hash.Map.add oph source filter_state.operation_hash_to_manager + (* Record which manager is used for the operation hash. *); + } + + let precheck : + config -> + filter_state:state -> + validation_state:validation_state -> + Tezos_base.Operation.shell_header -> + Operation_hash.t -> + Main.operation_data -> + [ `Passed_precheck of state + | `Passed_precheck_with_replace of Operation_hash.t * state + | `Branch_delayed of tztrace + | `Branch_refused of tztrace + | `Refused of tztrace + | `Outdated of tztrace + | `Undecided ] + Lwt.t = + fun config + ~filter_state + ~validation_state + shell_header + oph + (Operation_data protocol_data) -> + let precheck_manager protocol_data source op = + match get_manager_operation_gas_and_fee op with + | Error err -> Lwt.return (`Refused (Environment.wrap_tztrace err)) + | Ok (fee, gas_limit) -> ( + let info = {operation_hash = oph; gas_limit; fee} in + precheck_manager + config + filter_state + validation_state + shell_header + protocol_data + source + ~fee + ~gas_limit + >|= function + | `Prechecked_manager -> + `Passed_precheck + (add_manager_restriction filter_state oph info source) + | `Prechecked_manager_with_replace old_oph -> + `Passed_precheck_with_replace + (old_oph, add_manager_restriction filter_state oph info source) + | (`Refused _ | `Branch_delayed _ | `Branch_refused _ | `Outdated _) + as errs -> + errs) + in + match protocol_data.contents with + | Single (Manager_operation {source; _}) as op -> + precheck_manager protocol_data source op + | Cons (Manager_operation {source; _}, _) as op -> + precheck_manager protocol_data source op + | Single _ -> Lwt.return `Undecided + + open Apply_results + + type Environment.Error_monad.error += Skipped_operation + + let () = + Environment.Error_monad.register_error_kind + `Temporary + ~id:"postfilter.skipped_operation" + ~title:"The operation has been skipped by the protocol" + ~description:"The operation has been skipped by the protocol" + ~pp:(fun ppf () -> + Format.fprintf ppf "The operation has been skipped by the protocol") + Data_encoding.unit + (function Skipped_operation -> Some () | _ -> None) + (fun () -> Skipped_operation) + + type Environment.Error_monad.error += Backtracked_operation + + let () = + Environment.Error_monad.register_error_kind + `Temporary + ~id:"postfilter.backtracked_operation" + ~title:"The operation has been backtracked by the protocol" + ~description:"The operation has been backtracked by the protocol" + ~pp:(fun ppf () -> + Format.fprintf ppf "The operation has been backtracked by the protocol") + Data_encoding.unit + (function Backtracked_operation -> Some () | _ -> None) + (fun () -> Backtracked_operation) + + let rec post_filter_manager : + type t. + Alpha_context.t -> + state -> + t Kind.manager contents_result_list -> + config -> + [`Passed_postfilter of state | `Refused of tztrace] = + fun ctxt filter_state result config -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/2181 + This function should be unit tested. + The errors that can be raised if allow_script_failure is enable should + be tested. *) + match result with + | Single_result (Manager_operation_result {operation_result; _}) -> ( + let check_allow_script_failure errs = + if config.allow_script_failure then `Passed_postfilter filter_state + else `Refused errs + in + match operation_result with + | Applied _ -> `Passed_postfilter filter_state + | Skipped _ -> + check_allow_script_failure + [Environment.wrap_tzerror Skipped_operation] + | Failed (_, errors) -> + check_allow_script_failure (Environment.wrap_tztrace errors) + | Backtracked (_, errors) -> + check_allow_script_failure + (match errors with + | Some e -> Environment.wrap_tztrace e + | None -> [Environment.wrap_tzerror Backtracked_operation])) + | Cons_result (Manager_operation_result res, rest) -> ( + post_filter_manager + ctxt + filter_state + (Single_result (Manager_operation_result res)) + config + |> function + | `Passed_postfilter filter_state -> + post_filter_manager ctxt filter_state rest config + | `Refused _ as errs -> errs) + + let post_filter config ~(filter_state : state) ~validation_state_before:_ + ~validation_state_after:({ctxt; _} : validation_state) (_op, receipt) = + match receipt with + | No_operation_metadata -> assert false (* only for multipass validator *) + | Operation_metadata {contents} -> ( + match contents with + | Single_result (Preendorsement_result _) + | Single_result (Endorsement_result _) + | Single_result (Seed_nonce_revelation_result _) + | Single_result (Double_preendorsement_evidence_result _) + | Single_result (Double_endorsement_evidence_result _) + | Single_result (Double_baking_evidence_result _) + | Single_result (Activate_account_result _) + | Single_result Proposals_result + | Single_result Ballot_result -> + Lwt.return (`Passed_postfilter filter_state) + | Single_result (Manager_operation_result _) as result -> + Lwt.return (post_filter_manager ctxt filter_state result config) + | Cons_result (Manager_operation_result _, _) as result -> + Lwt.return (post_filter_manager ctxt filter_state result config)) +end + +module View_helpers = struct + open Tezos_micheline + + type Environment.Error_monad.error += Viewed_contract_has_no_script + + type Environment.Error_monad.error += View_callback_origination_failed + + type Environment.Error_monad.error += + | Illformed_view_type of string * Script.expr + + type Environment.Error_monad.error += + | View_never_returns of string * Contract.t + + type Environment.Error_monad.error += + | View_unexpected_return of string * Contract.t + + let () = + Environment.Error_monad.register_error_kind + `Permanent + ~id:"viewedContractHasNoScript" + ~title:"Viewed contract has no script" + ~description:"A view was called on a contract with no script." + ~pp:(fun ppf () -> + Format.fprintf ppf "A view was called on a contract with no script.") + Data_encoding.(unit) + (function Viewed_contract_has_no_script -> Some () | _ -> None) + (fun () -> Viewed_contract_has_no_script) ; + Environment.Error_monad.register_error_kind + `Permanent + ~id:"viewCallbackOriginationFailed" + ~title:"View callback origination failed" + ~description:"View callback origination failed" + ~pp:(fun ppf () -> + Format.fprintf ppf "Error during origination of view callback contract.") + Data_encoding.(unit) + (function View_callback_origination_failed -> Some () | _ -> None) + (fun () -> View_callback_origination_failed) ; + Environment.Error_monad.register_error_kind + `Permanent + ~id:"illformedViewType" + ~title:"An entrypoint type is incompatible with TZIP-4 view type." + ~description:"An entrypoint type is incompatible with TZIP-4 view type." + ~pp:(fun ppf (entrypoint, typ) -> + Format.fprintf + ppf + "The view %s has type %a, it is not compatible with a TZIP-4 view \ + type." + entrypoint + Micheline_printer.print_expr + (Micheline_printer.printable + (fun x -> x) + (Michelson_v1_primitives.strings_of_prims typ))) + Data_encoding.( + obj2 (req "entrypoint" string) (req "type" Script.expr_encoding)) + (function Illformed_view_type (etp, exp) -> Some (etp, exp) | _ -> None) + (fun (etp, exp) -> Illformed_view_type (etp, exp)) ; + Environment.Error_monad.register_error_kind + `Permanent + ~id:"viewNeverReturns" + ~title: + "A view never returned a transaction to the given callback contract" + ~description: + "A view never initiated a transaction to the given callback contract." + ~pp:(fun ppf (entrypoint, callback) -> + Format.fprintf + ppf + "The view %s never initiated a transaction to the given callback \ + contract %a." + entrypoint + Contract.pp + callback) + Data_encoding.( + obj2 (req "entrypoint" string) (req "callback" Contract.encoding)) + (function View_never_returns (e, c) -> Some (e, c) | _ -> None) + (fun (e, c) -> View_never_returns (e, c)) ; + Environment.Error_monad.register_error_kind + `Permanent + ~id:"viewUnexpectedReturn" + ~title:"A view returned an unexpected list of operations" + ~description: + "A view initiated a list of operations while the TZIP-4 standard \ + expects only a transaction to the given callback contract." + ~pp:(fun ppf (entrypoint, callback) -> + Format.fprintf + ppf + "The view %s initiated a list of operations while the TZIP-4 \ + standard expects only a transaction to the given callback contract \ + %a." + entrypoint + Contract.pp + callback) + Data_encoding.( + obj2 (req "entrypoint" string) (req "callback" Contract.encoding)) + (function View_never_returns (e, c) -> Some (e, c) | _ -> None) + (fun (e, c) -> View_never_returns (e, c)) + + (* This script is actually never run, its usage is to ensure a + contract that has the type `contract ` is originated, which + will be required as callback of the view. *) + let make_viewer_script ty : Script.t = + let loc = 0 in + let ty = Micheline.root ty in + let code = + Micheline.strip_locations + @@ Micheline.Seq + ( loc, + [ + Micheline.Prim (loc, Script.K_parameter, [ty], []); + Micheline.Prim + ( loc, + Script.K_storage, + [Micheline.Prim (loc, Script.T_unit, [], [])], + [] ); + Micheline.Prim + ( loc, + Script.K_code, + [Micheline.Prim (loc, Script.I_FAILWITH, [], [])], + [] ); + ] ) + in + let storage = + Micheline.strip_locations (Micheline.Prim (loc, Script.D_Unit, [], [])) + in + {code = Script.lazy_expr code; storage = Script.lazy_expr storage} + + let make_view_parameter input callback = + let loc = 0 in + Micheline.strip_locations + (Micheline.Prim + ( loc, + Script.D_Pair, + [ + input; + Micheline.Bytes + ( loc, + Data_encoding.Binary.to_bytes_exn Contract.encoding callback ); + ], + [] )) + + let extract_view_output_type entrypoint ty = + match Micheline.root ty with + | Micheline.Prim + ( _, + Script.T_pair, + [_; Micheline.Prim (_, Script.T_contract, [ty], _)], + _ ) -> + ok (Micheline.strip_locations ty) + | _ -> Environment.Error_monad.error (Illformed_view_type (entrypoint, ty)) + + (* 'view' entrypoints returns their value by calling a callback contract, thus + the expected result is a unique internal transaction to this callback. *) + let extract_parameter_from_operations entrypoint operations callback = + let unexpected_return = + Environment.Error_monad.error + @@ View_unexpected_return (entrypoint, callback) + in + match operations with + | [ + Internal_operation + {operation = Transaction {destination; parameters; _}; _}; + ] + when Contract.equal destination callback -> + ok parameters + | [] -> + Environment.Error_monad.error + (View_never_returns (entrypoint, callback)) + | _ -> unexpected_return +end + +module RPC = struct + open Environment + open Alpha_context + open Environment.Error_monad + + let parse_operation (op : Operation.raw) = + match + Data_encoding.Binary.of_bytes_opt + Operation.protocol_data_encoding + op.proto + with + | Some protocol_data -> ok {shell = op.shell; protocol_data} + | None -> error Cannot_parse_operation + + let path = RPC_path.(open_root / "helpers") + + module Registration = struct + let patched_services = + ref (RPC_directory.empty : Updater.rpc_context RPC_directory.t) + + let register0_fullctxt ~chunked s f = + patched_services := + RPC_directory.register ~chunked !patched_services s (fun ctxt q i -> + Services_registration.rpc_init ctxt >>=? fun ctxt -> f ctxt q i) + + let register0 ~chunked s f = + register0_fullctxt ~chunked s (fun {context; _} -> f context) + + let register0_noctxt ~chunked s f = + patched_services := + RPC_directory.register ~chunked !patched_services s (fun _ q i -> f q i) + + let opt_register0_fullctxt ~chunked s f = + patched_services := + RPC_directory.opt_register ~chunked !patched_services s (fun ctxt q i -> + Services_registration.rpc_init ctxt >>=? fun ctxt -> f ctxt q i) + + let opt_register0 ~chunked s f = + opt_register0_fullctxt ~chunked s (fun {context; _} -> f context) + + let register1_fullctxt ~chunked s f = + patched_services := + RPC_directory.register + ~chunked + !patched_services + s + (fun (ctxt, arg) q i -> + Services_registration.rpc_init ctxt >>=? fun ctxt -> f ctxt arg q i) + + let register1 ~chunked s f = + register1_fullctxt ~chunked s (fun {context; _} x -> f context x) + + let register2_fullctxt ~chunked s f = + patched_services := + RPC_directory.register + ~chunked + !patched_services + s + (fun ((ctxt, arg1), arg2) q i -> + Services_registration.rpc_init ctxt >>=? fun ctxt -> + f ctxt arg1 arg2 q i) + + let register2 ~chunked s f = + register2_fullctxt ~chunked s (fun {context; _} a1 a2 q i -> + f context a1 a2 q i) + end + + let unparsing_mode_encoding = + let open Script_ir_translator in + let open Data_encoding in + union + ~tag_size:`Uint8 + [ + case + (Tag 0) + ~title:"Readable" + (constant "Readable") + (function + | Readable -> Some () | Optimized | Optimized_legacy -> None) + (fun () -> Readable); + case + (Tag 1) + ~title:"Optimized" + (constant "Optimized") + (function + | Optimized -> Some () | Readable | Optimized_legacy -> None) + (fun () -> Optimized); + case + (Tag 2) + ~title:"Optimized_legacy" + (constant "Optimized_legacy") + (function + | Optimized_legacy -> Some () | Readable | Optimized -> None) + (fun () -> Optimized_legacy); + ] + + module Scripts = struct + module S = struct + open Data_encoding + + let path = RPC_path.(path / "scripts") + + let run_code_input_encoding = + merge_objs + (obj10 + (req "script" Script.expr_encoding) + (req "storage" Script.expr_encoding) + (req "input" Script.expr_encoding) + (req "amount" Tez.encoding) + (req "balance" Tez.encoding) + (req "chain_id" Chain_id.encoding) + (opt "source" Contract.encoding) + (opt "payer" Contract.encoding) + (opt "gas" Gas.Arith.z_integral_encoding) + (dft "entrypoint" string "default")) + (obj3 + (opt "unparsing_mode" unparsing_mode_encoding) + (opt "now" Script_timestamp.encoding) + (opt "level" Script_int.n_encoding)) + + let run_code_output_encoding = + conv + (fun (storage, operations, lazy_storage_diff) -> + (storage, operations, lazy_storage_diff, lazy_storage_diff)) + (fun (storage, operations, legacy_lazy_storage_diff, lazy_storage_diff) + -> + let lazy_storage_diff = + Option.either lazy_storage_diff legacy_lazy_storage_diff + in + (storage, operations, lazy_storage_diff)) + (obj4 + (req "storage" Script.expr_encoding) + (req "operations" (list Operation.internal_operation_encoding)) + (opt "big_map_diff" Lazy_storage.legacy_big_map_diff_encoding) + (opt "lazy_storage_diff" Lazy_storage.encoding)) + + let trace_code_input_encoding = run_code_input_encoding + + let trace_encoding = + def "scripted.trace" @@ list + @@ obj3 + (req "location" Script.location_encoding) + (req "gas" Gas.encoding) + (req + "stack" + (list + (obj2 (req "item" Script.expr_encoding) (opt "annot" string)))) + + let trace_code_output_encoding = + conv + (fun (storage, operations, trace, lazy_storage_diff) -> + (storage, operations, trace, lazy_storage_diff, lazy_storage_diff)) + (fun ( storage, + operations, + trace, + legacy_lazy_storage_diff, + lazy_storage_diff ) -> + let lazy_storage_diff = + Option.either lazy_storage_diff legacy_lazy_storage_diff + in + (storage, operations, trace, lazy_storage_diff)) + (obj5 + (req "storage" Script.expr_encoding) + (req "operations" (list Operation.internal_operation_encoding)) + (req "trace" trace_encoding) + (opt "big_map_diff" Lazy_storage.legacy_big_map_diff_encoding) + (opt "lazy_storage_diff" Lazy_storage.encoding)) + + let run_view_encoding = + let open Data_encoding in + obj10 + (req "contract" Contract.encoding) + (req "entrypoint" string) + (req "input" Script.expr_encoding) + (req "chain_id" Chain_id.encoding) + (opt "source" Contract.encoding) + (opt "payer" Contract.encoding) + (opt "gas" Gas.Arith.z_integral_encoding) + (req "unparsing_mode" unparsing_mode_encoding) + (opt "now" Script_timestamp.encoding) + (opt "level" Script_int.n_encoding) + + let run_code = + RPC_service.post_service + ~description:"Run a piece of code in the current context" + ~query:RPC_query.empty + ~input:run_code_input_encoding + ~output:run_code_output_encoding + RPC_path.(path / "run_code") + + let trace_code = + RPC_service.post_service + ~description: + "Run a piece of code in the current context, keeping a trace" + ~query:RPC_query.empty + ~input:trace_code_input_encoding + ~output:trace_code_output_encoding + RPC_path.(path / "trace_code") + + let run_view = + RPC_service.post_service + ~description: + "Simulate a call to a view following the TZIP-4 standard. See \ + https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-4/tzip-4.md#view-entrypoints." + ~input:run_view_encoding + ~output:(obj1 (req "data" Script.expr_encoding)) + ~query:RPC_query.empty + RPC_path.(path / "run_view") + + let typecheck_code = + RPC_service.post_service + ~description:"Typecheck a piece of code in the current context" + ~query:RPC_query.empty + ~input: + (obj4 + (req "program" Script.expr_encoding) + (opt "gas" Gas.Arith.z_integral_encoding) + (opt "legacy" bool) + (opt "show_types" bool)) + ~output: + (obj2 + (req "type_map" Script_tc_errors_registration.type_map_enc) + (req "gas" Gas.encoding)) + RPC_path.(path / "typecheck_code") + + let script_size = + RPC_service.post_service + ~description:"Compute the size of a script in the current context" + ~query:RPC_query.empty + ~input: + (obj4 + (req "program" Script.expr_encoding) + (req "storage" Script.expr_encoding) + (opt "gas" Gas.Arith.z_integral_encoding) + (opt "legacy" bool)) + ~output:(obj1 (req "script_size" int31)) + RPC_path.(path / "script_size") + + let typecheck_data = + RPC_service.post_service + ~description: + "Check that some data expression is well formed and of a given \ + type in the current context" + ~query:RPC_query.empty + ~input: + (obj4 + (req "data" Script.expr_encoding) + (req "type" Script.expr_encoding) + (opt "gas" Gas.Arith.z_integral_encoding) + (opt "legacy" bool)) + ~output:(obj1 (req "gas" Gas.encoding)) + RPC_path.(path / "typecheck_data") + + let pack_data = + RPC_service.post_service + ~description: + "Computes the serialized version of some data expression using the \ + same algorithm as script instruction PACK" + ~input: + (obj3 + (req "data" Script.expr_encoding) + (req "type" Script.expr_encoding) + (opt "gas" Gas.Arith.z_integral_encoding)) + ~output:(obj2 (req "packed" bytes) (req "gas" Gas.encoding)) + ~query:RPC_query.empty + RPC_path.(path / "pack_data") + + let normalize_data = + RPC_service.post_service + ~description: + "Normalizes some data expression using the requested unparsing mode" + ~input: + (obj4 + (req "data" Script.expr_encoding) + (req "type" Script.expr_encoding) + (req "unparsing_mode" unparsing_mode_encoding) + (opt "legacy" bool)) + ~output:(obj1 (req "normalized" Script.expr_encoding)) + ~query:RPC_query.empty + RPC_path.(path / "normalize_data") + + let normalize_script = + RPC_service.post_service + ~description: + "Normalizes a Michelson script using the requested unparsing mode" + ~input: + (obj2 + (req "script" Script.expr_encoding) + (req "unparsing_mode" unparsing_mode_encoding)) + ~output:(obj1 (req "normalized" Script.expr_encoding)) + ~query:RPC_query.empty + RPC_path.(path / "normalize_script") + + let normalize_type = + RPC_service.post_service + ~description: + "Normalizes some Michelson type by expanding `pair a b c` as `pair \ + a (pair b c)" + ~input:(obj1 (req "type" Script.expr_encoding)) + ~output:(obj1 (req "normalized" Script.expr_encoding)) + ~query:RPC_query.empty + RPC_path.(path / "normalize_type") + + let run_operation = + RPC_service.post_service + ~description:"Run an operation without signature checks" + ~query:RPC_query.empty + ~input: + (obj2 + (req "operation" Operation.encoding) + (req "chain_id" Chain_id.encoding)) + ~output:Apply_results.operation_data_and_metadata_encoding + RPC_path.(path / "run_operation") + + let simulate_operation = + RPC_service.post_service + ~description:"Simulate an operation" + ~query:RPC_query.empty + ~input: + (obj3 + (req "operation" Operation.encoding) + (req "chain_id" Chain_id.encoding) + (dft "latency" int16 default_operation_inclusion_latency)) + ~output:Apply_results.operation_data_and_metadata_encoding + RPC_path.(path / "simulate_operation") + + let entrypoint_type = + RPC_service.post_service + ~description:"Return the type of the given entrypoint" + ~query:RPC_query.empty + ~input: + (obj2 + (req "script" Script.expr_encoding) + (dft "entrypoint" string "default")) + ~output:(obj1 (req "entrypoint_type" Script.expr_encoding)) + RPC_path.(path / "entrypoint") + + let list_entrypoints = + RPC_service.post_service + ~description:"Return the list of entrypoints of the given script" + ~query:RPC_query.empty + ~input:(obj1 (req "script" Script.expr_encoding)) + ~output: + (obj2 + (dft + "unreachable" + (Data_encoding.list + (obj1 + (req + "path" + (Data_encoding.list + Michelson_v1_primitives.prim_encoding)))) + []) + (req "entrypoints" (assoc Script.expr_encoding))) + RPC_path.(path / "entrypoints") + end + + module type UNPARSING_MODE = sig + val unparsing_mode : Script_ir_translator.unparsing_mode + end + + module Traced_interpreter (Unparsing_mode : UNPARSING_MODE) = struct + type log_element = + | Log : + context + * Script.location + * ('a * 's) + * ('a, 's) Script_typed_ir.stack_ty + -> log_element + + let unparse_stack ctxt (stack, stack_ty) = + (* We drop the gas limit as this function is only used for debugging/errors. *) + let ctxt = Gas.set_unlimited ctxt in + let rec unparse_stack : + type a s. + (a, s) Script_typed_ir.stack_ty * (a * s) -> + (Script.expr * string option) list tzresult Lwt.t = function + | (Bot_t, (EmptyCell, EmptyCell)) -> return_nil + | (Item_t (ty, rest_ty, annot), (v, rest)) -> + Script_ir_translator.unparse_data + ctxt + Unparsing_mode.unparsing_mode + ty + v + >>=? fun (data, _ctxt) -> + unparse_stack (rest_ty, rest) >|=? fun rest -> + let annot = + match Script_ir_annot.unparse_var_annot annot with + | [] -> None + | [a] -> Some a + | _ -> assert false + in + let data = Micheline.strip_locations data in + (data, annot) :: rest + in + unparse_stack (stack_ty, stack) + + let trace_logger () : Script_typed_ir.logger = + let log : log_element list ref = ref [] in + let log_interp _ ctxt loc sty stack = + log := Log (ctxt, loc, stack, sty) :: !log + in + let log_entry _ _ctxt _loc _sty _stack = () in + let log_exit _ ctxt loc sty stack = + log := Log (ctxt, loc, stack, sty) :: !log + in + let log_control _ = () in + let get_log () = + List.map_es + (fun (Log (ctxt, loc, stack, stack_ty)) -> + trace Cannot_serialize_log (unparse_stack ctxt (stack, stack_ty)) + >>=? fun stack -> return (loc, Gas.level ctxt, stack)) + !log + >>=? fun res -> return (Some (List.rev res)) + in + {log_exit; log_entry; log_interp; get_log; log_control} + + let execute ctxt step_constants ~script ~entrypoint ~parameter = + let open Script_interpreter in + let logger = trace_logger () in + execute + ~logger + ~cached_script:None + ctxt + Unparsing_mode.unparsing_mode + step_constants + ~script + ~entrypoint + ~parameter + ~internal:true + >>=? fun ({ctxt; storage; lazy_storage_diff; operations}, _) -> + logger.get_log () >|=? fun trace -> + let trace = Option.value ~default:[] trace in + ({ctxt; storage; lazy_storage_diff; operations}, trace) + end + + let typecheck_data : + legacy:bool -> + context -> + Script.expr * Script.expr -> + context tzresult Lwt.t = + fun ~legacy ctxt (data, exp_ty) -> + record_trace + (Script_tc_errors.Ill_formed_type (None, exp_ty, 0)) + (Script_ir_translator.parse_parameter_ty + ctxt + ~legacy + (Micheline.root exp_ty)) + >>?= fun (Ex_ty exp_ty, ctxt) -> + trace_eval + (fun () -> + let exp_ty = Script_ir_translator.serialize_ty_for_error exp_ty in + Script_tc_errors.Ill_typed_data (None, data, exp_ty)) + (let allow_forged = + true + (* Safe since we ignore the value afterwards. *) + in + Script_ir_translator.parse_data + ctxt + ~legacy + ~allow_forged + exp_ty + (Micheline.root data)) + >|=? fun (_, ctxt) -> ctxt + + module Unparse_types = struct + (* Same as the unparsing functions for types in Script_ir_translator but + does not consume gas and never folds (pair a (pair b c)) *) + + open Script_ir_translator + open Micheline + open Michelson_v1_primitives + open Script_ir_annot + open Script_typed_ir + + let rec unparse_comparable_ty : + type a loc. + loc:loc -> a comparable_ty -> (loc, Script.prim) Micheline.node = + fun ~loc -> function + | Unit_key meta -> Prim (loc, T_unit, [], unparse_type_annot meta.annot) + | Never_key meta -> + Prim (loc, T_never, [], unparse_type_annot meta.annot) + | Int_key meta -> Prim (loc, T_int, [], unparse_type_annot meta.annot) + | Nat_key meta -> Prim (loc, T_nat, [], unparse_type_annot meta.annot) + | Signature_key meta -> + Prim (loc, T_signature, [], unparse_type_annot meta.annot) + | String_key meta -> + Prim (loc, T_string, [], unparse_type_annot meta.annot) + | Bytes_key meta -> + Prim (loc, T_bytes, [], unparse_type_annot meta.annot) + | Mutez_key meta -> + Prim (loc, T_mutez, [], unparse_type_annot meta.annot) + | Bool_key meta -> Prim (loc, T_bool, [], unparse_type_annot meta.annot) + | Key_hash_key meta -> + Prim (loc, T_key_hash, [], unparse_type_annot meta.annot) + | Key_key meta -> Prim (loc, T_key, [], unparse_type_annot meta.annot) + | Timestamp_key meta -> + Prim (loc, T_timestamp, [], unparse_type_annot meta.annot) + | Address_key meta -> + Prim (loc, T_address, [], unparse_type_annot meta.annot) + | Chain_id_key meta -> + Prim (loc, T_chain_id, [], unparse_type_annot meta.annot) + | Pair_key ((l, al), (r, ar), meta) -> + let tl = add_field_annot al None (unparse_comparable_ty ~loc l) in + let tr = add_field_annot ar None (unparse_comparable_ty ~loc r) in + Prim (loc, T_pair, [tl; tr], unparse_type_annot meta.annot) + | Union_key ((l, al), (r, ar), meta) -> + let tl = add_field_annot al None (unparse_comparable_ty ~loc l) in + let tr = add_field_annot ar None (unparse_comparable_ty ~loc r) in + Prim (loc, T_or, [tl; tr], unparse_type_annot meta.annot) + | Option_key (t, meta) -> + Prim + ( loc, + T_option, + [unparse_comparable_ty ~loc t], + unparse_type_annot meta.annot ) + + let unparse_memo_size ~loc memo_size = + let z = Alpha_context.Sapling.Memo_size.unparse_to_z memo_size in + Int (loc, z) + + let rec unparse_ty : + type a loc. loc:loc -> a ty -> (loc, Script.prim) Micheline.node = + fun ~loc ty -> + let return (name, args, annot) = Prim (loc, name, args, annot) in + match ty with + | Unit_t meta -> return (T_unit, [], unparse_type_annot meta.annot) + | Int_t meta -> return (T_int, [], unparse_type_annot meta.annot) + | Nat_t meta -> return (T_nat, [], unparse_type_annot meta.annot) + | Signature_t meta -> + return (T_signature, [], unparse_type_annot meta.annot) + | String_t meta -> return (T_string, [], unparse_type_annot meta.annot) + | Bytes_t meta -> return (T_bytes, [], unparse_type_annot meta.annot) + | Mutez_t meta -> return (T_mutez, [], unparse_type_annot meta.annot) + | Bool_t meta -> return (T_bool, [], unparse_type_annot meta.annot) + | Key_hash_t meta -> + return (T_key_hash, [], unparse_type_annot meta.annot) + | Key_t meta -> return (T_key, [], unparse_type_annot meta.annot) + | Timestamp_t meta -> + return (T_timestamp, [], unparse_type_annot meta.annot) + | Address_t meta -> return (T_address, [], unparse_type_annot meta.annot) + | Operation_t meta -> + return (T_operation, [], unparse_type_annot meta.annot) + | Chain_id_t meta -> + return (T_chain_id, [], unparse_type_annot meta.annot) + | Never_t meta -> return (T_never, [], unparse_type_annot meta.annot) + | Bls12_381_g1_t meta -> + return (T_bls12_381_g1, [], unparse_type_annot meta.annot) + | Bls12_381_g2_t meta -> + return (T_bls12_381_g2, [], unparse_type_annot meta.annot) + | Bls12_381_fr_t meta -> + return (T_bls12_381_fr, [], unparse_type_annot meta.annot) + | Contract_t (ut, meta) -> + let t = unparse_ty ~loc ut in + return (T_contract, [t], unparse_type_annot meta.annot) + | Pair_t ((utl, l_field, l_var), (utr, r_field, r_var), meta) -> + let annot = unparse_type_annot meta.annot in + let utl = unparse_ty ~loc utl in + let tl = add_field_annot l_field l_var utl in + let utr = unparse_ty ~loc utr in + let tr = add_field_annot r_field r_var utr in + return (T_pair, [tl; tr], annot) + | Union_t ((utl, l_field), (utr, r_field), meta) -> + let annot = unparse_type_annot meta.annot in + let utl = unparse_ty ~loc utl in + let tl = add_field_annot l_field None utl in + let utr = unparse_ty ~loc utr in + let tr = add_field_annot r_field None utr in + return (T_or, [tl; tr], annot) + | Lambda_t (uta, utr, meta) -> + let ta = unparse_ty ~loc uta in + let tr = unparse_ty ~loc utr in + return (T_lambda, [ta; tr], unparse_type_annot meta.annot) + | Option_t (ut, meta) -> + let annot = unparse_type_annot meta.annot in + let ut = unparse_ty ~loc ut in + return (T_option, [ut], annot) + | List_t (ut, meta) -> + let t = unparse_ty ~loc ut in + return (T_list, [t], unparse_type_annot meta.annot) + | Ticket_t (ut, meta) -> + let t = unparse_comparable_ty ~loc ut in + return (T_ticket, [t], unparse_type_annot meta.annot) + | Set_t (ut, meta) -> + let t = unparse_comparable_ty ~loc ut in + return (T_set, [t], unparse_type_annot meta.annot) + | Map_t (uta, utr, meta) -> + let ta = unparse_comparable_ty ~loc uta in + let tr = unparse_ty ~loc utr in + return (T_map, [ta; tr], unparse_type_annot meta.annot) + | Big_map_t (uta, utr, meta) -> + let ta = unparse_comparable_ty ~loc uta in + let tr = unparse_ty ~loc utr in + return (T_big_map, [ta; tr], unparse_type_annot meta.annot) + | Sapling_transaction_t (memo_size, meta) -> + return + ( T_sapling_transaction, + [unparse_memo_size ~loc memo_size], + unparse_type_annot meta.annot ) + | Sapling_state_t (memo_size, meta) -> + return + ( T_sapling_state, + [unparse_memo_size ~loc memo_size], + unparse_type_annot meta.annot ) + | Chest_t meta -> return (T_chest, [], unparse_type_annot meta.annot) + | Chest_key_t meta -> + return (T_chest_key, [], unparse_type_annot meta.annot) + end + + let run_operation_service ctxt () + ({shell; protocol_data = Operation_data protocol_data}, chain_id) = + (* this code is a duplicate of Apply without signature check *) + let ret contents = + ( Operation_data protocol_data, + Apply_results.Operation_metadata {contents} ) + in + let operation : _ operation = {shell; protocol_data} in + let hash = Operation.hash {shell; protocol_data} in + let ctxt = Contract.init_origination_nonce ctxt hash in + let payload_producer = Signature.Public_key_hash.zero in + match protocol_data.contents with + | Single (Manager_operation _) as op -> + Apply.precheck_manager_contents_list ctxt op ~mempool_mode:true + >>=? fun (ctxt, prechecked_contents_list) -> + (* removed signature check here *) + Apply.apply_manager_contents_list + ctxt + Optimized + ~payload_producer + chain_id + prechecked_contents_list + >|= fun (_ctxt, result) -> ok @@ ret result + | Cons (Manager_operation _, _) as op -> + Apply.precheck_manager_contents_list ctxt op ~mempool_mode:true + >>=? fun (ctxt, prechecked_contents_list) -> + (* removed signature check here *) + Apply.apply_manager_contents_list + ctxt + Optimized + ~payload_producer + chain_id + prechecked_contents_list + >|= fun (_ctxt, result) -> ok @@ ret result + | _ -> + let predecessor_level = + match + Alpha_context.Level.pred ctxt (Alpha_context.Level.current ctxt) + with + | Some level -> level + | None -> assert false + in + Alpha_context.Round.get ctxt >>=? fun predecessor_round -> + Apply.apply_contents_list + ctxt + chain_id + (Partial_construction + { + predecessor_level; + predecessor_round; + grand_parent_round = Round.zero; + }) + Optimized + ~payload_producer + operation + operation.protocol_data.contents + >|=? fun (_ctxt, result) -> ret result + + (* + + The execution of an operation depends on the state of the + cache. In particular, gas consumption is usually impacted by + cache hits and misses. + + Unfortunately, the state of the cache is different between the + context at operation-creation time and the context when is + included in a block. + + Therefore, the simulation tries to predict the state of the + cache in a [time_in_blocks] assumed to be close to the inclusion + time of the operation. + + *) + let simulate_operation_service ctxt () (op, chain_id, time_in_blocks) = + let ctxt = Cache.Admin.future_cache_expectation ctxt ~time_in_blocks in + run_operation_service ctxt () (op, chain_id) + + let register () = + let originate_dummy_contract ctxt script balance = + let ctxt = Contract.init_origination_nonce ctxt Operation_hash.zero in + Lwt.return (Contract.fresh_contract_from_current_nonce ctxt) + >>=? fun (ctxt, dummy_contract) -> + Contract.raw_originate + ctxt + ~prepaid_bootstrap_storage:false + dummy_contract + ~script:(script, None) + >>=? fun ctxt -> + Token.transfer + ~origin:Simulation + ctxt + `Minted + (`Contract dummy_contract) + balance + >>=? fun (ctxt, _) -> return (ctxt, dummy_contract) + in + let script_entrypoint_type ctxt expr entrypoint = + let ctxt = Gas.set_unlimited ctxt in + let legacy = false in + let open Script_ir_translator in + parse_toplevel ctxt ~legacy expr + >>=? fun ({arg_type; root_name; _}, ctxt) -> + Lwt.return + ( ( parse_parameter_ty ctxt ~legacy arg_type + >>? fun (Ex_ty arg_type, _) -> + Script_ir_translator.find_entrypoint + ~root_name + arg_type + entrypoint ) + >>? fun (_f, Ex_ty ty) -> + unparse_ty ~loc:() ctxt ty >|? fun (ty_node, _) -> + Micheline.strip_locations ty_node ) + in + Registration.register0 + ~chunked:true + S.run_code + (fun + ctxt + () + ( ( code, + storage, + parameter, + amount, + balance, + chain_id, + source, + payer, + gas, + entrypoint ), + (unparsing_mode, now, level) ) + -> + let unparsing_mode = Option.value ~default:Readable unparsing_mode in + let storage = Script.lazy_expr storage in + let code = Script.lazy_expr code in + originate_dummy_contract ctxt {storage; code} balance + >>=? fun (ctxt, dummy_contract) -> + let (source, payer) = + match (source, payer) with + | (Some source, Some payer) -> (source, payer) + | (Some source, None) -> (source, source) + | (None, Some payer) -> (payer, payer) + | (None, None) -> (dummy_contract, dummy_contract) + in + let gas = + match gas with + | Some gas -> gas + | None -> Constants.hard_gas_limit_per_operation ctxt + in + let ctxt = Gas.set_limit ctxt gas in + let now = + match now with None -> Script_timestamp.now ctxt | Some t -> t + in + let level = + match level with + | None -> + (Level.current ctxt).level |> Raw_level.to_int32 + |> Script_int.of_int32 |> Script_int.abs + | Some z -> z + in + let step_constants = + let open Script_interpreter in + {source; payer; self = dummy_contract; amount; chain_id; now; level} + in + Script_interpreter.execute + ctxt + unparsing_mode + step_constants + ~cached_script:None + ~script:{storage; code} + ~entrypoint + ~parameter + ~internal:true + >|=? fun ( { + Script_interpreter.storage; + operations; + lazy_storage_diff; + _; + }, + _ ) -> (storage, operations, lazy_storage_diff)) ; + Registration.register0 + ~chunked:true + S.trace_code + (fun + ctxt + () + ( ( code, + storage, + parameter, + amount, + balance, + chain_id, + source, + payer, + gas, + entrypoint ), + (unparsing_mode, now, level) ) + -> + let unparsing_mode = Option.value ~default:Readable unparsing_mode in + let storage = Script.lazy_expr storage in + let code = Script.lazy_expr code in + originate_dummy_contract ctxt {storage; code} balance + >>=? fun (ctxt, dummy_contract) -> + let (source, payer) = + match (source, payer) with + | (Some source, Some payer) -> (source, payer) + | (Some source, None) -> (source, source) + | (None, Some payer) -> (payer, payer) + | (None, None) -> (dummy_contract, dummy_contract) + in + let gas = + match gas with + | Some gas -> gas + | None -> Constants.hard_gas_limit_per_operation ctxt + in + let ctxt = Gas.set_limit ctxt gas in + let now = + match now with None -> Script_timestamp.now ctxt | Some t -> t + in + let level = + match level with + | None -> + (Level.current ctxt).level |> Raw_level.to_int32 + |> Script_int.of_int32 |> Script_int.abs + | Some z -> z + in + let step_constants = + let open Script_interpreter in + {source; payer; self = dummy_contract; amount; chain_id; now; level} + in + let module Unparsing_mode = struct + let unparsing_mode = unparsing_mode + end in + let module Interp = Traced_interpreter (Unparsing_mode) in + Interp.execute + ctxt + step_constants + ~script:{storage; code} + ~entrypoint + ~parameter + >|=? fun ( { + Script_interpreter.storage; + operations; + lazy_storage_diff; + _; + }, + trace ) -> (storage, operations, trace, lazy_storage_diff)) ; + Registration.register0 + ~chunked:true + S.run_view + (fun + ctxt + () + ( contract, + entrypoint, + input, + chain_id, + source, + payer, + gas, + unparsing_mode, + now, + level ) + -> + Contract.get_script ctxt contract >>=? fun (ctxt, script_opt) -> + Option.fold + ~some:ok + ~none:(Error_monad.error View_helpers.Viewed_contract_has_no_script) + script_opt + >>?= fun script -> + Script_repr.(force_decode script.code) >>?= fun decoded_script -> + script_entrypoint_type ctxt decoded_script entrypoint + >>=? fun view_ty -> + View_helpers.extract_view_output_type entrypoint view_ty + >>?= fun ty -> + Error_monad.trace View_helpers.View_callback_origination_failed + @@ originate_dummy_contract + ctxt + (View_helpers.make_viewer_script ty) + Tez.zero + >>=? fun (ctxt, viewer_contract) -> + let (source, payer) = + match (source, payer) with + | (Some source, Some payer) -> (source, payer) + | (Some source, None) -> (source, source) + | (None, Some payer) -> (payer, payer) + | (None, None) -> (contract, contract) + in + let gas = + Option.value + ~default:(Constants.hard_gas_limit_per_operation ctxt) + gas + in + let ctxt = Gas.set_limit ctxt gas in + let now = + match now with None -> Script_timestamp.now ctxt | Some t -> t + in + let level = + match level with + | None -> + (Level.current ctxt).level |> Raw_level.to_int32 + |> Script_int.of_int32 |> Script_int.abs + | Some z -> z + in + let step_constants = + let open Script_interpreter in + { + source; + payer; + self = contract; + amount = Tez.zero; + chain_id; + now; + level; + } + in + let parameter = + View_helpers.make_view_parameter + (Micheline.root input) + viewer_contract + in + Script_interpreter.execute + ctxt + unparsing_mode + step_constants + ~script + ~cached_script:None + ~entrypoint + ~parameter + ~internal:true + >>=? fun ({Script_interpreter.operations; _}, (_, _)) -> + View_helpers.extract_parameter_from_operations + entrypoint + operations + viewer_contract + >>?= fun parameter -> Lwt.return (Script_repr.force_decode parameter)) ; + Registration.register0 + ~chunked:false + S.typecheck_code + (fun ctxt () (expr, maybe_gas, legacy, show_types) -> + let legacy = Option.value ~default:false legacy in + let show_types = Option.value ~default:true show_types in + let ctxt = + match maybe_gas with + | None -> Gas.set_unlimited ctxt + | Some gas -> Gas.set_limit ctxt gas + in + Script_ir_translator.typecheck_code ~legacy ~show_types ctxt expr + >|=? fun (res, ctxt) -> (res, Gas.level ctxt)) ; + Registration.register0 + ~chunked:false + S.script_size + (fun ctxt () (expr, storage, maybe_gas, legacy) -> + let legacy = Option.value ~default:false legacy in + let ctxt = + match maybe_gas with + | None -> Gas.set_unlimited ctxt + | Some gas -> Gas.set_limit ctxt gas + in + let code = Script.lazy_expr expr in + Script_ir_translator.parse_code ~legacy ctxt ~code + >>=? fun ( Ex_code + { + code; + arg_type; + storage_type; + views; + root_name; + code_size; + }, + ctxt ) -> + Script_ir_translator.parse_data + ~legacy + ~allow_forged:true + ctxt + storage_type + (Micheline.root storage) + >>=? fun (storage, _) -> + let script = + Script_ir_translator.Ex_script + { + code; + arg_type; + storage_type; + views; + root_name; + code_size; + storage; + } + in + let (size, cost) = Script_ir_translator.script_size script in + Gas.consume ctxt cost >>?= fun _ctxt -> return @@ size) ; + + Registration.register0 + ~chunked:false + S.typecheck_data + (fun ctxt () (data, ty, maybe_gas, legacy) -> + let legacy = Option.value ~default:false legacy in + let ctxt = + match maybe_gas with + | None -> Gas.set_unlimited ctxt + | Some gas -> Gas.set_limit ctxt gas + in + typecheck_data ~legacy ctxt (data, ty) >|=? fun ctxt -> Gas.level ctxt) ; + Registration.register0 + ~chunked:true + S.pack_data + (fun ctxt () (expr, typ, maybe_gas) -> + let open Script_ir_translator in + let ctxt = + match maybe_gas with + | None -> Gas.set_unlimited ctxt + | Some gas -> Gas.set_limit ctxt gas + in + parse_packable_ty ctxt ~legacy:true (Micheline.root typ) + >>?= fun (Ex_ty typ, ctxt) -> + parse_data + ctxt + ~legacy:true + ~allow_forged:true + typ + (Micheline.root expr) + >>=? fun (data, ctxt) -> + Script_ir_translator.pack_data ctxt typ data >|=? fun (bytes, ctxt) -> + (bytes, Gas.level ctxt)) ; + Registration.register0 + ~chunked:true + S.normalize_data + (fun ctxt () (expr, typ, unparsing_mode, legacy) -> + let open Script_ir_translator in + let legacy = Option.value ~default:false legacy in + let ctxt = Gas.set_unlimited ctxt in + Script_ir_translator.parse_any_ty ctxt ~legacy (Micheline.root typ) + >>?= fun (Ex_ty typ, ctxt) -> + parse_data ctxt ~legacy ~allow_forged:true typ (Micheline.root expr) + >>=? fun (data, ctxt) -> + Script_ir_translator.unparse_data ctxt unparsing_mode typ data + >|=? fun (normalized, _ctxt) -> Micheline.strip_locations normalized) ; + Registration.register0 + ~chunked:true + S.normalize_script + (fun ctxt () (script, unparsing_mode) -> + let ctxt = Gas.set_unlimited ctxt in + Script_ir_translator.unparse_code + ctxt + unparsing_mode + (Micheline.root script) + >|=? fun (normalized, _ctxt) -> Micheline.strip_locations normalized) ; + Registration.register0 ~chunked:true S.normalize_type (fun ctxt () typ -> + let open Script_ir_translator in + let ctxt = Gas.set_unlimited ctxt in + (* Unfortunately, Script_ir_translator.parse_any_ty is not exported *) + Script_ir_translator.parse_ty + ctxt + ~legacy:true + ~allow_lazy_storage:true + ~allow_operation:true + ~allow_contract:true + ~allow_ticket:true + (Micheline.root typ) + >>?= fun (Ex_ty typ, _ctxt) -> + let normalized = Unparse_types.unparse_ty ~loc:() typ in + return @@ Micheline.strip_locations normalized) ; + Registration.register0 ~chunked:true S.run_operation run_operation_service ; + Registration.register0 + ~chunked:true + S.simulate_operation + simulate_operation_service ; + Registration.register0 + ~chunked:true + S.entrypoint_type + (fun ctxt () (expr, entrypoint) -> + script_entrypoint_type ctxt expr entrypoint) ; + Registration.register0 + ~chunked:true + S.list_entrypoints + (fun ctxt () expr -> + let ctxt = Gas.set_unlimited ctxt in + let legacy = false in + let open Script_ir_translator in + parse_toplevel ~legacy ctxt expr + >>=? fun ({arg_type; root_name; _}, ctxt) -> + Lwt.return + ( parse_parameter_ty ctxt ~legacy arg_type + >>? fun (Ex_ty arg_type, _) -> + Script_ir_translator.list_entrypoints ~root_name arg_type ctxt + >|? fun (unreachable_entrypoint, map) -> + ( unreachable_entrypoint, + Entrypoints_map.fold + (fun entry (_, ty) acc -> + (entry, Micheline.strip_locations ty) :: acc) + map + [] ) )) + + let run_code ?unparsing_mode ?gas ?(entrypoint = "default") ~script ~storage + ~input ~amount ~balance ~chain_id ~source ~payer ~now ~level ctxt block + = + RPC_context.make_call0 + S.run_code + ctxt + block + () + ( ( script, + storage, + input, + amount, + balance, + chain_id, + source, + payer, + gas, + entrypoint ), + (unparsing_mode, now, level) ) + + let trace_code ?unparsing_mode ?gas ?(entrypoint = "default") ~script + ~storage ~input ~amount ~balance ~chain_id ~source ~payer ~now ~level + ctxt block = + RPC_context.make_call0 + S.trace_code + ctxt + block + () + ( ( script, + storage, + input, + amount, + balance, + chain_id, + source, + payer, + gas, + entrypoint ), + (unparsing_mode, now, level) ) + + let run_view ?gas ~contract ~entrypoint ~input ~chain_id ~now ~level ?source + ?payer ~unparsing_mode ctxt block = + RPC_context.make_call0 + S.run_view + ctxt + block + () + ( contract, + entrypoint, + input, + chain_id, + source, + payer, + gas, + unparsing_mode, + now, + level ) + + let typecheck_code ?gas ?legacy ~script ?show_types ctxt block = + RPC_context.make_call0 + S.typecheck_code + ctxt + block + () + (script, gas, legacy, show_types) + + let script_size ?gas ?legacy ~script ~storage ctxt block = + RPC_context.make_call0 + S.script_size + ctxt + block + () + (script, storage, gas, legacy) + + let typecheck_data ?gas ?legacy ~data ~ty ctxt block = + RPC_context.make_call0 + S.typecheck_data + ctxt + block + () + (data, ty, gas, legacy) + + let pack_data ?gas ~data ~ty ctxt block = + RPC_context.make_call0 S.pack_data ctxt block () (data, ty, gas) + + let normalize_data ?legacy ~data ~ty ~unparsing_mode ctxt block = + RPC_context.make_call0 + S.normalize_data + ctxt + block + () + (data, ty, unparsing_mode, legacy) + + let normalize_script ~script ~unparsing_mode ctxt block = + RPC_context.make_call0 + S.normalize_script + ctxt + block + () + (script, unparsing_mode) + + let normalize_type ~ty ctxt block = + RPC_context.make_call0 S.normalize_type ctxt block () ty + + let run_operation ~op ~chain_id ctxt block = + RPC_context.make_call0 S.run_operation ctxt block () (op, chain_id) + + let simulate_operation ~op ~chain_id ~latency ctxt block = + RPC_context.make_call0 + S.simulate_operation + ctxt + block + () + (op, chain_id, latency) + + let entrypoint_type ~script ~entrypoint ctxt block = + RPC_context.make_call0 S.entrypoint_type ctxt block () (script, entrypoint) + + let list_entrypoints ctxt block ~script = + RPC_context.make_call0 S.list_entrypoints ctxt block () script + end + + module Contract = struct + module S = struct + let path = + (RPC_path.(open_root / "context" / "contracts") + : RPC_context.t RPC_path.context) + + let get_storage_normalized = + let open Data_encoding in + RPC_service.post_service + ~description: + "Access the data of the contract and normalize it using the \ + requested unparsing mode." + ~input:(obj1 (req "unparsing_mode" unparsing_mode_encoding)) + ~query:RPC_query.empty + ~output:(option Script.expr_encoding) + RPC_path.(path /: Contract.rpc_arg / "storage" / "normalized") + + let get_script_normalized = + let open Data_encoding in + RPC_service.post_service + ~description: + "Access the script of the contract and normalize it using the \ + requested unparsing mode." + ~input:(obj1 (req "unparsing_mode" unparsing_mode_encoding)) + ~query:RPC_query.empty + ~output:(option Script.encoding) + RPC_path.(path /: Contract.rpc_arg / "script" / "normalized") + end + + let register () = + (* Patched RPC: get_storage *) + Registration.register1 + ~chunked:true + S.get_storage_normalized + (fun ctxt contract () unparsing_mode -> + Contract.get_script ctxt contract >>=? fun (ctxt, script) -> + match script with + | None -> return_none + | Some script -> + let ctxt = Gas.set_unlimited ctxt in + let open Script_ir_translator in + parse_script + ctxt + ~legacy:true + ~allow_forged_in_storage:true + script + >>=? fun (Ex_script script, ctxt) -> + unparse_script ctxt unparsing_mode script + >>=? fun (script, ctxt) -> + Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + script.storage + >>?= fun (storage, _ctxt) -> return_some storage) ; + (* Patched RPC: get_script *) + Registration.register1 + ~chunked:true + S.get_script_normalized + (fun ctxt contract () unparsing_mode -> + Contract.get_script ctxt contract >>=? fun (ctxt, script) -> + match script with + | None -> return_none + | Some script -> + let ctxt = Gas.set_unlimited ctxt in + let open Script_ir_translator in + parse_script + ctxt + ~legacy:true + ~allow_forged_in_storage:true + script + >>=? fun (Ex_script script, ctxt) -> + unparse_script ctxt unparsing_mode script + >>=? fun (script, _ctxt) -> return_some script) + + let get_storage_normalized ctxt block ~contract ~unparsing_mode = + RPC_context.make_call1 + S.get_storage_normalized + ctxt + block + contract + () + unparsing_mode + + let get_script_normalized ctxt block ~contract ~unparsing_mode = + RPC_context.make_call1 + S.get_script_normalized + ctxt + block + contract + () + unparsing_mode + end + + module Big_map = struct + module S = struct + let path = + (RPC_path.(open_root / "context" / "big_maps") + : RPC_context.t RPC_path.context) + + let big_map_get_normalized = + let open Data_encoding in + RPC_service.post_service + ~description: + "Access the value associated with a key in a big map, normalize \ + the output using the requested unparsing mode." + ~query:RPC_query.empty + ~input:(obj1 (req "unparsing_mode" unparsing_mode_encoding)) + ~output:Script.expr_encoding + RPC_path.( + path /: Big_map.Id.rpc_arg /: Script_expr_hash.rpc_arg + / "normalized") + end + + let register () = + Registration.register2 + ~chunked:true + S.big_map_get_normalized + (fun ctxt id key () unparsing_mode -> + let open Script_ir_translator in + let ctxt = Gas.set_unlimited ctxt in + Big_map.exists ctxt id >>=? fun (ctxt, types) -> + match types with + | None -> raise Not_found + | Some (_, value_type) -> ( + parse_big_map_value_ty + ctxt + ~legacy:true + (Micheline.root value_type) + >>?= fun (Ex_ty value_type, ctxt) -> + Big_map.get_opt ctxt id key >>=? fun (_ctxt, value) -> + match value with + | None -> raise Not_found + | Some value -> + parse_data + ctxt + ~legacy:true + ~allow_forged:true + value_type + (Micheline.root value) + >>=? fun (value, ctxt) -> + unparse_data ctxt unparsing_mode value_type value + >|=? fun (value, _ctxt) -> Micheline.strip_locations value)) + + let big_map_get_normalized ctxt block id key ~unparsing_mode = + RPC_context.make_call2 + S.big_map_get_normalized + ctxt + block + id + key + () + unparsing_mode + end + + module Forge = struct + module S = struct + open Data_encoding + + let path = RPC_path.(path / "forge") + + let operations = + RPC_service.post_service + ~description:"Forge an operation" + ~query:RPC_query.empty + ~input:Operation.unsigned_encoding + ~output:bytes + RPC_path.(path / "operations") + + let empty_proof_of_work_nonce = + Bytes.make Constants_repr.proof_of_work_nonce_size '\000' + + let protocol_data = + RPC_service.post_service + ~description:"Forge the protocol-specific part of a block header" + ~query:RPC_query.empty + ~input: + (obj5 + (req "payload_hash" Block_payload_hash.encoding) + (req "payload_round" Round.encoding) + (opt "nonce_hash" Nonce_hash.encoding) + (dft + "proof_of_work_nonce" + (Fixed.bytes Alpha_context.Constants.proof_of_work_nonce_size) + empty_proof_of_work_nonce) + (dft "liquidity_baking_escape_vote" bool false)) + ~output:(obj1 (req "protocol_data" bytes)) + RPC_path.(path / "protocol_data") + end + + let register () = + Registration.register0_noctxt + ~chunked:true + S.operations + (fun () (shell, proto) -> + return + (Data_encoding.Binary.to_bytes_exn + Operation.unsigned_encoding + (shell, proto))) ; + Registration.register0_noctxt + ~chunked:true + S.protocol_data + (fun + () + ( payload_hash, + payload_round, + seed_nonce_hash, + proof_of_work_nonce, + liquidity_baking_escape_vote ) + -> + return + (Data_encoding.Binary.to_bytes_exn + Block_header.contents_encoding + { + payload_hash; + payload_round; + seed_nonce_hash; + proof_of_work_nonce; + liquidity_baking_escape_vote; + })) + + module Manager = struct + let[@coq_axiom_with_reason "cast on e"] operations ctxt block ~branch + ~source ?sourcePubKey ~counter ~fee ~gas_limit ~storage_limit + operations = + Contract_services.manager_key ctxt block source >>= function + | Error _ as e -> Lwt.return e + | Ok revealed -> + let ops = + List.map + (fun (Manager operation) -> + Contents + (Manager_operation + { + source; + counter; + operation; + fee; + gas_limit; + storage_limit; + })) + operations + in + let ops = + match (sourcePubKey, revealed) with + | (None, _) | (_, Some _) -> ops + | (Some pk, None) -> + let operation = Reveal pk in + Contents + (Manager_operation + { + source; + counter; + operation; + fee; + gas_limit; + storage_limit; + }) + :: ops + in + Environment.wrap_tzresult @@ Operation.of_list ops >>?= fun ops -> + RPC_context.make_call0 S.operations ctxt block () ({branch}, ops) + + let reveal ctxt block ~branch ~source ~sourcePubKey ~counter ~fee () = + operations + ctxt + block + ~branch + ~source + ~sourcePubKey + ~counter + ~fee + ~gas_limit:Gas.Arith.zero + ~storage_limit:Z.zero + [] + + let transaction ctxt block ~branch ~source ?sourcePubKey ~counter ~amount + ~destination ?(entrypoint = "default") ?parameters ~gas_limit + ~storage_limit ~fee () = + let parameters = + Option.fold + ~some:Script.lazy_expr + ~none:Script.unit_parameter + parameters + in + operations + ctxt + block + ~branch + ~source + ?sourcePubKey + ~counter + ~fee + ~gas_limit + ~storage_limit + [Manager (Transaction {amount; parameters; destination; entrypoint})] + + let origination ctxt block ~branch ~source ?sourcePubKey ~counter ~balance + ?delegatePubKey ~script ~gas_limit ~storage_limit ~fee () = + operations + ctxt + block + ~branch + ~source + ?sourcePubKey + ~counter + ~fee + ~gas_limit + ~storage_limit + [ + Manager + (Origination + { + delegate = delegatePubKey; + script; + credit = balance; + preorigination = None; + }); + ] + + let delegation ctxt block ~branch ~source ?sourcePubKey ~counter ~fee + delegate = + operations + ctxt + block + ~branch + ~source + ?sourcePubKey + ~counter + ~fee + ~gas_limit:Gas.Arith.zero + ~storage_limit:Z.zero + [Manager (Delegation delegate)] + end + + let operation ctxt block ~branch operation = + RPC_context.make_call0 + S.operations + ctxt + block + () + ({branch}, Contents_list (Single operation)) + + let endorsement ctxt b ~branch ~consensus_content () = + operation ctxt b ~branch (Endorsement consensus_content) + + let proposals ctxt b ~branch ~source ~period ~proposals () = + operation ctxt b ~branch (Proposals {source; period; proposals}) + + let ballot ctxt b ~branch ~source ~period ~proposal ~ballot () = + operation ctxt b ~branch (Ballot {source; period; proposal; ballot}) + + let failing_noop ctxt b ~branch ~message () = + operation ctxt b ~branch (Failing_noop message) + + let seed_nonce_revelation ctxt block ~branch ~level ~nonce () = + operation ctxt block ~branch (Seed_nonce_revelation {level; nonce}) + + let double_baking_evidence ctxt block ~branch ~bh1 ~bh2 () = + operation ctxt block ~branch (Double_baking_evidence {bh1; bh2}) + + let double_endorsement_evidence ctxt block ~branch ~op1 ~op2 () = + operation ctxt block ~branch (Double_endorsement_evidence {op1; op2}) + + let double_preendorsement_evidence ctxt block ~branch ~op1 ~op2 () = + operation ctxt block ~branch (Double_preendorsement_evidence {op1; op2}) + + let empty_proof_of_work_nonce = + Bytes.make Constants_repr.proof_of_work_nonce_size '\000' + + let protocol_data ctxt block ?(payload_hash = Block_payload_hash.zero) + ?(payload_round = Round.zero) ?seed_nonce_hash + ?(proof_of_work_nonce = empty_proof_of_work_nonce) + ~liquidity_baking_escape_vote () = + RPC_context.make_call0 + S.protocol_data + ctxt + block + () + ( payload_hash, + payload_round, + seed_nonce_hash, + proof_of_work_nonce, + liquidity_baking_escape_vote ) + end + + module Parse = struct + module S = struct + open Data_encoding + + let path = RPC_path.(path / "parse") + + let operations = + RPC_service.post_service + ~description:"Parse operations" + ~query:RPC_query.empty + ~input: + (obj2 + (req "operations" (list (dynamic_size Operation.raw_encoding))) + (opt "check_signature" bool)) + ~output:(list (dynamic_size Operation.encoding)) + RPC_path.(path / "operations") + + let block = + RPC_service.post_service + ~description:"Parse a block" + ~query:RPC_query.empty + ~input:Block_header.raw_encoding + ~output:Block_header.protocol_data_encoding + RPC_path.(path / "block") + end + + let parse_protocol_data protocol_data = + match + Data_encoding.Binary.of_bytes_opt + Block_header.protocol_data_encoding + protocol_data + with + | None -> Stdlib.failwith "Cant_parse_protocol_data" + | Some protocol_data -> protocol_data + + let register () = + Registration.register0 + ~chunked:true + S.operations + (fun _ctxt () (operations, check) -> + List.map_es + (fun raw -> + parse_operation raw >>?= fun op -> + (match check with + | Some true -> return_unit (* FIXME *) + (* I.check_signature ctxt *) + (* op.protocol_data.signature op.shell op.protocol_data.contents *) + | Some false | None -> return_unit) + >|=? fun () -> op) + operations) ; + Registration.register0_noctxt ~chunked:false S.block (fun () raw_block -> + return @@ parse_protocol_data raw_block.protocol_data) + + let operations ctxt block ?check operations = + RPC_context.make_call0 S.operations ctxt block () (operations, check) + + let block ctxt block shell protocol_data = + RPC_context.make_call0 + S.block + ctxt + block + () + ({shell; protocol_data} : Block_header.raw) + end + + (* Compute the estimated starting time of a [round] at a future + [level], given the head's level [current_level], timestamp + [current_timestamp], and round [current_round]. Assumes blocks at + intermediate levels are produced at round 0. *) + let estimated_time round_durations ~current_level ~current_round + ~current_timestamp ~level ~round = + if Level.(level <= current_level) then Result.return_none + else + Round.of_int round >>? fun round -> + Round.timestamp_of_round + round_durations + ~round + ~predecessor_timestamp:current_timestamp + ~predecessor_round:current_round + >>? fun round_start_at_next_level -> + let step = Round.round_duration round_durations Round.zero in + let diff = Level.diff level current_level in + Period.mult (Int32.pred diff) step >>? fun delay -> + Timestamp.(round_start_at_next_level +? delay) >>? fun timestamp -> + Result.return_some timestamp + + let requested_levels ~default_level ctxt cycles levels = + match (levels, cycles) with + | ([], []) -> [default_level] + | (levels, cycles) -> + (* explicitly fail when requested levels or cycle are in the past... + or too far in the future... + TODO-TB: this old comment (from version Alpha) conflicts with + the specification of the RPCs that use this code. + *) + List.sort_uniq + Level.compare + (List.concat + (List.map (Level.from_raw ctxt) levels + :: List.map (Level.levels_in_cycle ctxt) cycles)) + + module Baking_rights = struct + type t = { + level : Raw_level.t; + delegate : Signature.Public_key_hash.t; + round : int; + timestamp : Timestamp.t option; + } + + let encoding = + let open Data_encoding in + conv + (fun {level; delegate; round; timestamp} -> + (level, delegate, round, timestamp)) + (fun (level, delegate, round, timestamp) -> + {level; delegate; round; timestamp}) + (obj4 + (req "level" Raw_level.encoding) + (req "delegate" Signature.Public_key_hash.encoding) + (req "round" uint16) + (opt "estimated_time" Timestamp.encoding)) + + let default_max_round = 64 + + module S = struct + open Data_encoding + + let path = RPC_path.(open_root / "helpers" / "baking_rights") + + type baking_rights_query = { + levels : Raw_level.t list; + cycle : Cycle.t option; + delegates : Signature.Public_key_hash.t list; + max_round : int option; + all : bool; + } + + let baking_rights_query = + let open RPC_query in + query (fun levels cycle delegates max_round all -> + {levels; cycle; delegates; max_round; all}) + |+ multi_field "level" Raw_level.rpc_arg (fun t -> t.levels) + |+ opt_field "cycle" Cycle.rpc_arg (fun t -> t.cycle) + |+ multi_field "delegate" Signature.Public_key_hash.rpc_arg (fun t -> + t.delegates) + |+ opt_field "max_round" RPC_arg.uint (fun t -> t.max_round) + |+ flag "all" (fun t -> t.all) + |> seal + + let baking_rights = + RPC_service.get_service + ~description: + (Format.sprintf + "Retrieves the list of delegates allowed to bake a block.\n\ + By default, it gives the best baking opportunities (in terms \ + of rounds) for bakers that have at least one opportunity below \ + the %dth round for the next block.\n\ + Parameters `level` and `cycle` can be used to specify the \ + (valid) level(s) in the past or future at which the baking \ + rights have to be returned.\n\ + Parameter `delegate` can be used to restrict the results to \ + the given delegates. If parameter `all` is set, all the baking \ + opportunities for each baker at each level are returned, \ + instead of just the first one.\n\ + Returns the list of baking opportunities up to round %d. Also \ + returns the minimal timestamps that correspond to these \ + opportunities. The timestamps are omitted for levels in the \ + past, and are only estimates for levels higher that the next \ + block's, based on the hypothesis that all predecessor blocks \ + were baked at the first round." + default_max_round + default_max_round) + ~query:baking_rights_query + ~output:(list encoding) + path + end + + let baking_rights_at_level ctxt max_round level = + Baking.baking_rights ctxt level >>=? fun delegates -> + Round.get ctxt >>=? fun current_round -> + let current_level = Level.current ctxt in + let current_timestamp = Timestamp.current ctxt in + let round_durations = Alpha_context.Constants.round_durations ctxt in + let rec loop l acc round = + if Compare.Int.(round > max_round) then return (List.rev acc) + else + let (Misc.LCons (pk, next)) = l in + let delegate = Signature.Public_key.hash pk in + estimated_time + round_durations + ~current_level + ~current_round + ~current_timestamp + ~level + ~round + >>?= fun timestamp -> + let acc = {level = level.level; delegate; round; timestamp} :: acc in + next () >>=? fun l -> loop l acc (round + 1) + in + loop delegates [] 0 + + let remove_duplicated_delegates rights = + List.rev @@ fst + @@ List.fold_left + (fun (acc, previous) r -> + if + Signature.Public_key_hash.Set.exists + (Signature.Public_key_hash.equal r.delegate) + previous + then (acc, previous) + else + (r :: acc, Signature.Public_key_hash.Set.add r.delegate previous)) + ([], Signature.Public_key_hash.Set.empty) + rights + + let register () = + Registration.register0 ~chunked:true S.baking_rights (fun ctxt q () -> + let cycles = + match q.cycle with None -> [] | Some cycle -> [cycle] + in + let levels = + requested_levels + ~default_level:(Level.succ ctxt (Level.current ctxt)) + ctxt + cycles + q.levels + in + let max_round = + match q.max_round with + | None -> default_max_round + | Some max_round -> + Compare.Int.min + max_round + (Constants.consensus_committee_size ctxt) + in + List.map_es (baking_rights_at_level ctxt max_round) levels + >|=? fun rights -> + let rights = + if q.all then rights + else List.map remove_duplicated_delegates rights + in + let rights = List.concat rights in + match q.delegates with + | [] -> rights + | _ :: _ as delegates -> + let is_requested p = + List.exists + (Signature.Public_key_hash.equal p.delegate) + delegates + in + List.filter is_requested rights) + + let get ctxt ?(levels = []) ?cycle ?(delegates = []) ?(all = false) + ?max_round block = + RPC_context.make_call0 + S.baking_rights + ctxt + block + {levels; cycle; delegates; max_round; all} + () + end + + module Endorsing_rights = struct + type delegate_rights = { + delegate : Signature.Public_key_hash.t; + first_slot : Slot.t; + endorsing_power : int; + } + + type t = { + level : Raw_level.t; + delegates_rights : delegate_rights list; + estimated_time : Time.t option; + } + + let delegate_rights_encoding = + let open Data_encoding in + conv + (fun {delegate; first_slot; endorsing_power} -> + (delegate, first_slot, endorsing_power)) + (fun (delegate, first_slot, endorsing_power) -> + {delegate; first_slot; endorsing_power}) + (obj3 + (req "delegate" Signature.Public_key_hash.encoding) + (req "first_slot" Slot.encoding) + (req "endorsing_power" uint16)) + + let encoding = + let open Data_encoding in + conv + (fun {level; delegates_rights; estimated_time} -> + (level, delegates_rights, estimated_time)) + (fun (level, delegates_rights, estimated_time) -> + {level; delegates_rights; estimated_time}) + (obj3 + (req "level" Raw_level.encoding) + (req "delegates" (list delegate_rights_encoding)) + (opt "estimated_time" Timestamp.encoding)) + + module S = struct + open Data_encoding + + let path = RPC_path.(path / "endorsing_rights") + + type endorsing_rights_query = { + levels : Raw_level.t list; + cycle : Cycle.t option; + delegates : Signature.Public_key_hash.t list; + } + + let endorsing_rights_query = + let open RPC_query in + query (fun levels cycle delegates -> {levels; cycle; delegates}) + |+ multi_field "level" Raw_level.rpc_arg (fun t -> t.levels) + |+ opt_field "cycle" Cycle.rpc_arg (fun t -> t.cycle) + |+ multi_field "delegate" Signature.Public_key_hash.rpc_arg (fun t -> + t.delegates) + |> seal + + let endorsing_rights = + RPC_service.get_service + ~description: + "Retrieves the delegates allowed to endorse a block.\n\ + By default, it gives the endorsing power for delegates that have \ + at least one endorsing slot for the next block.\n\ + Parameters `level` and `cycle` can be used to specify the (valid) \ + level(s) in the past or future at which the endorsing rights have \ + to be returned. Parameter `delegate` can be used to restrict the \ + results to the given delegates.\n\ + Returns the smallest endorsing slots and the endorsing power. \ + Also returns the minimal timestamp that corresponds to endorsing \ + at the given level. The timestamps are omitted for levels in the \ + past, and are only estimates for levels higher that the next \ + block's, based on the hypothesis that all predecessor blocks were \ + baked at the first round." + ~query:endorsing_rights_query + ~output:(list encoding) + path + end + + let endorsing_rights_at_level ctxt level = + Baking.endorsing_rights_by_first_slot ctxt level + >>=? fun (ctxt, rights) -> + Round.get ctxt >>=? fun current_round -> + let current_level = Level.current ctxt in + let current_timestamp = Timestamp.current ctxt in + let round_durations = Alpha_context.Constants.round_durations ctxt in + estimated_time + round_durations + ~current_level + ~current_round + ~current_timestamp + ~level + ~round:0 + >>?= fun estimated_time -> + let rights = + Slot.Map.fold + (fun first_slot (_pk, delegate, endorsing_power) acc -> + {delegate; first_slot; endorsing_power} :: acc) + rights + [] + in + return {level = level.level; delegates_rights = rights; estimated_time} + + let register () = + Registration.register0 ~chunked:true S.endorsing_rights (fun ctxt q () -> + let cycles = + match q.cycle with None -> [] | Some cycle -> [cycle] + in + let levels = + requested_levels + ~default_level:(Level.current ctxt) + ctxt + cycles + q.levels + in + List.map_es (endorsing_rights_at_level ctxt) levels + >|=? fun rights_per_level -> + match q.delegates with + | [] -> rights_per_level + | _ :: _ as delegates -> + List.filter_map + (fun rights_at_level -> + let is_requested p = + List.exists + (Signature.Public_key_hash.equal p.delegate) + delegates + in + match + List.filter is_requested rights_at_level.delegates_rights + with + | [] -> None + | delegates_rights -> + Some {rights_at_level with delegates_rights}) + rights_per_level) + + let get ctxt ?(levels = []) ?cycle ?(delegates = []) block = + RPC_context.make_call0 + S.endorsing_rights + ctxt + block + {levels; cycle; delegates} + () + end + + module Validators = struct + type t = { + level : Raw_level.t; + delegate : Signature.Public_key_hash.t; + slots : Slot.t list; + } + + let encoding = + let open Data_encoding in + conv + (fun {level; delegate; slots} -> (level, delegate, slots)) + (fun (level, delegate, slots) -> {level; delegate; slots}) + (obj3 + (req "level" Raw_level.encoding) + (req "delegate" Signature.Public_key_hash.encoding) + (req "slots" (list Slot.encoding))) + + module S = struct + open Data_encoding + + let path = RPC_path.(path / "validators") + + type validators_query = { + levels : Raw_level.t list; + delegates : Signature.Public_key_hash.t list; + } + + let validators_query = + let open RPC_query in + query (fun levels delegates -> {levels; delegates}) + |+ multi_field "level" Raw_level.rpc_arg (fun t -> t.levels) + |+ multi_field "delegate" Signature.Public_key_hash.rpc_arg (fun t -> + t.delegates) + |> seal + + let validators = + RPC_service.get_service + ~description: + "Retrieves the delegates allowed to endorse a block.\n\ + By default, it gives the endorsing slots for delegates that have \ + at least one in the next block.\n\ + Parameter `level` can be used to specify the (valid) level(s) in \ + the past or future at which the endorsement rights have to be \ + returned. Parameter `delegate` can be used to restrict the \ + results to the given delegates.\n\ + Returns the list of endorsing slots. Also returns the minimal \ + timestamps that correspond to these slots. The timestamps are \ + omitted for levels in the past, and are only estimates for levels \ + later that the next block, based on the hypothesis that all \ + predecessor blocks were baked at the first round." + ~query:validators_query + ~output:(list encoding) + path + end + + let endorsing_slots_at_level ctxt level = + Baking.endorsing_rights ctxt level >|=? fun (_, rights) -> + Signature.Public_key_hash.Map.fold + (fun delegate slots acc -> + {level = level.level; delegate; slots} :: acc) + rights + [] + + let register () = + Registration.register0 ~chunked:true S.validators (fun ctxt q () -> + let levels = + requested_levels + ~default_level:(Level.current ctxt) + ctxt + [] + q.levels + in + List.map_es (endorsing_slots_at_level ctxt) levels >|=? fun rights -> + let rights = List.concat rights in + match q.delegates with + | [] -> rights + | _ :: _ as delegates -> + let is_requested p = + List.exists + (Signature.Public_key_hash.equal p.delegate) + delegates + in + List.filter is_requested rights) + + let get ctxt ?(levels = []) ?(delegates = []) block = + RPC_context.make_call0 S.validators ctxt block {levels; delegates} () + end + + module S = struct + open Data_encoding + + type level_query = {offset : int32} + + let level_query : level_query RPC_query.t = + let open RPC_query in + query (fun offset -> {offset}) + |+ field "offset" RPC_arg.int32 0l (fun t -> t.offset) + |> seal + + let current_level = + RPC_service.get_service + ~description: + "Returns the level of the interrogated block, or the one of a block \ + located `offset` blocks after it in the chain. For instance, the \ + next block if `offset` is 1. The offset cannot be negative." + ~query:level_query + ~output:Level.encoding + RPC_path.(path / "current_level") + + let levels_in_current_cycle = + RPC_service.get_service + ~description:"Levels of a cycle" + ~query:level_query + ~output: + (obj2 + (req "first" Raw_level.encoding) + (req "last" Raw_level.encoding)) + RPC_path.(path / "levels_in_current_cycle") + + let round = + RPC_service.get_service + ~description: + "Returns the round of the interrogated block, or the one of a block \ + located `offset` blocks after in the chain (or before when \ + negative). For instance, the next block if `offset` is 1." + ~query:RPC_query.empty + ~output:Round.encoding + RPC_path.(path / "round") + end + + type Environment.Error_monad.error += Negative_level_offset + + let () = + Environment.Error_monad.register_error_kind + `Permanent + ~id:"negative_level_offset" + ~title:"The specified level offset is negative" + ~description:"The specified level offset is negative" + ~pp:(fun ppf () -> + Format.fprintf ppf "The specified level offset should be positive.") + Data_encoding.unit + (function Negative_level_offset -> Some () | _ -> None) + (fun () -> Negative_level_offset) + + let register () = + Scripts.register () ; + Forge.register () ; + Parse.register () ; + Contract.register () ; + Big_map.register () ; + Baking_rights.register () ; + Endorsing_rights.register () ; + Validators.register () ; + Registration.register0 ~chunked:false S.current_level (fun ctxt q () -> + if q.offset < 0l then fail Negative_level_offset + else + Lwt.return + (Level.from_raw_with_offset + ctxt + ~offset:q.offset + (Level.current ctxt).level)) ; + Registration.opt_register0 + ~chunked:true + S.levels_in_current_cycle + (fun ctxt q () -> + let rev_levels = + Level.levels_in_current_cycle ctxt ~offset:q.offset () + in + match rev_levels with + | [] -> return_none + | [level] -> return (Some (level.level, level.level)) + | last :: default_first :: rest -> + (* The [rev_levels] list is reversed, the last level is the head *) + let first = List.last default_first rest in + return (Some (first.level, last.level))) ; + Registration.register0 ~chunked:false S.round (fun ctxt () () -> + Round.get ctxt) + + let current_level ctxt ?(offset = 0l) block = + RPC_context.make_call0 S.current_level ctxt block {offset} () + + let levels_in_current_cycle ctxt ?(offset = 0l) block = + RPC_context.make_call0 S.levels_in_current_cycle ctxt block {offset} () + + let rpc_services = + register () ; + RPC_directory.merge rpc_services !Registration.patched_services +end diff --git a/src/proto_012_PsiThaCa/lib_plugin/plugin_registerer.ml b/src/proto_012_PsiThaCa/lib_plugin/plugin_registerer.ml new file mode 100644 index 000000000000..03b4f9dccbac --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/plugin_registerer.ml @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Development. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Plugin = struct + module Proto = Registerer.Registered + include Plugin +end + +let () = Prevalidator_filters.register (module Plugin) diff --git a/src/proto_012_PsiThaCa/lib_plugin/test/.ocamlformat b/src/proto_012_PsiThaCa/lib_plugin/test/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/test/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_plugin/test/dune b/src/proto_012_PsiThaCa/lib_plugin/test/dune new file mode 100644 index 000000000000..3177afccaf8c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/test/dune @@ -0,0 +1,16 @@ +(test + (name test_consensus_filter) + (package tezos-protocol-plugin-012-PsiThaCa) + (libraries tezos-base + alcotest-lwt + tezos-test-helpers + qcheck-alcotest + tezos-stdlib-unix + tezos-protocol-012-PsiThaCa-parameters + tezos-protocol-plugin-012-PsiThaCa) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_micheline + -open Tezos_protocol_012_PsiThaCa + -open Tezos_protocol_plugin_012_PsiThaCa + -open Tezos_protocol_environment_012_PsiThaCa + -open Tezos_protocol_012_PsiThaCa.Protocol))) diff --git a/src/proto_012_PsiThaCa/lib_plugin/test/test_consensus_filter.ml b/src/proto_012_PsiThaCa/lib_plugin/test/test_consensus_filter.ml new file mode 100644 index 000000000000..8e359c8ebf0b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/test/test_consensus_filter.ml @@ -0,0 +1,499 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lib_test.Qcheck_helpers +open Plugin.Mempool +open Alpha_context + +let config drift_opt = + { + minimal_fees = default_minimal_fees; + minimal_nanotez_per_gas_unit = default_minimal_nanotez_per_gas_unit; + minimal_nanotez_per_byte = default_minimal_nanotez_per_byte; + allow_script_failure = true; + clock_drift = + Option.map + (fun drift -> Period.of_seconds_exn (Int64.of_int drift)) + drift_opt; + replace_by_fee_factor = Q.make (Z.of_int 105) (Z.of_int 100); + } + +type Environment.Error_monad.error += Generation_failure + +(** Conversion helpers *) + +let int32_of_timestamp ts = + let i64 = Timestamp.to_seconds ts in + let i32 = Int64.to_int32 i64 in + if Int64.(equal (of_int32 i32) i64) then Ok i32 + else Environment.Error_monad.error Generation_failure + +let int32_of_timestamp_exn ts = + match int32_of_timestamp ts with + | Ok i32 -> i32 + | Error _err -> Stdlib.failwith "int32_of_timestamp_exn: number too big" + +let timestamp_of_int32 ts = Timestamp.of_seconds (Int64.of_int32 ts) + +(** Data Generators *) +module Generator = struct + open QCheck + + let decorate ?(prefix = "") ?(suffix = "") printer gen = + set_print (fun d -> prefix ^ printer d ^ suffix) gen + + let config = + decorate ~prefix:"clock_drift " (fun config -> + Option.fold + ~none:"round_0 duration" + ~some:(fun drift -> Int64.to_string @@ Period.to_seconds drift) + config.clock_drift) + @@ map + ~rev:(fun {clock_drift; _} -> + Option.map + (fun drift -> Int64.to_int @@ Period.to_seconds drift) + clock_drift) + config + (option small_nat) + + let of_error_arb gen = + of_option_arb + @@ map + ~rev:(function + | Some x -> Ok x + | None -> Environment.Error_monad.error Generation_failure) + (function Ok x -> Some x | Error _err -> None) + gen + + let small_nat_32 ?prefix ?suffix () = + decorate ?prefix ?suffix Int32.to_string + @@ map ~rev:Int32.to_int Int32.of_int small_nat + + let small_signed_32 ?prefix ?suffix () = + decorate ?prefix ?suffix Int32.to_string + @@ map ~rev:Int32.to_int Int32.of_int small_signed_int + + let decorated_small_nat ?prefix ?suffix () = + decorate ?prefix ?suffix string_of_int small_nat + + let dup gen = map ~rev:fst (fun x -> (x, x)) gen + + let round = + of_error_arb + @@ map + ~rev:(function Ok l -> Round.to_int32 l | Error _ -> -1l) + (fun i32 -> Round.of_int32 i32) + (small_nat_32 ~prefix:"rnd " ()) + + let same_rounds = dup round + + let level = + of_error_arb + @@ map + ~rev:(function Ok l -> Raw_level.to_int32 l | Error _ -> -1l) + Raw_level.of_int32 + (small_nat_32 ~prefix:"lev " ()) + + let same_levels = dup level + + let timestamp = + set_print Timestamp.to_notation + @@ map ~rev:int32_of_timestamp_exn (fun f -> timestamp_of_int32 f) int32 + + let near_timestamps = + map + ~rev:(fun (ts1, ts2) -> + let its1 = int32_of_timestamp_exn ts1 in + let its2 = int32_of_timestamp_exn ts2 in + Int32.(its1, sub its2 its1)) + (fun (i, diff) -> + timestamp_of_int32 i |> fun ts1 -> + timestamp_of_int32 Int32.(add i diff) |> fun ts2 -> (ts1, ts2)) + (pair int32 (small_signed_32 ~prefix:"+" ~suffix:"sec." ())) + + let dummy_timestamp = + match Timestamp.of_seconds_string "0" with + | Some ts -> ts + | _ -> assert false + + let unsafe_sub ts1 ts2 = + Int64.to_int @@ Period.to_seconds + @@ + match Timestamp.(ts1 -? ts2) with + | Ok diff -> diff + | Error _ -> assert false + + let successive_timestamp = + of_error_arb + @@ map + ~rev:(function + | Ok (ts1, ts2) -> (ts1, unsafe_sub ts2 ts1) + | Error _ -> (dummy_timestamp, -1)) + (fun (ts, (diff : int)) -> + Period.of_seconds (Int64.of_int diff) >>? fun diff -> + Timestamp.(ts +? diff) >>? fun ts2 -> Ok (ts, ts2)) + (pair timestamp (decorated_small_nat ~prefix:"+" ~suffix:"sec." ())) + + let param_acceptable ?(rounds = pair round round) ?(levels = pair level level) + ?(timestamps = near_timestamps) () = + pair config (pair (pair rounds levels) timestamps) +end + +let assert_no_error d = match d with Error _ -> assert false | Ok d -> d + +(** Constants : + This could be generated but it would largely increase the search space. *) +let round_durations : Round.round_durations = + assert_no_error + @@ Round.Durations.create + ~first_round_duration:Period.(of_seconds_exn 4L) + ~delay_increment_per_round:Period.(of_seconds_exn 10L) + +let round_zero_duration = Round.round_duration round_durations Round.zero + +(** Don't allow test to fail *) +let no_error = function + | Ok b -> b + | Error errs -> + Format.printf + "test fail due to error : %a@." + Error_monad.pp_print_trace + (Environment.wrap_tztrace errs) ; + false + +(** Helper to compute *) +let durations round_durations start stop = + List.map_e + (fun round -> + Round.of_int round >|? fun round -> + Round.round_duration round_durations round |> Period.to_seconds) + Tezos_stdlib.Utils.Infix.(start -- stop) + +(** Expected timestamp for the begining of a round at same level that + the proposal. + + It has been developped before the Round.timestamp_of_round_same_level and has a + different implementation. + +*) +let timestamp_of_round round_durations ~proposal_timestamp ~proposal_round + ~round = + (let iproposal_round = Int32.to_int @@ Round.to_int32 proposal_round in + let iround = Int32.to_int @@ Round.to_int32 round in + if Round.(proposal_round = round) then ok (Period.zero, proposal_timestamp) + else if Round.(proposal_round < round) then + durations round_durations iproposal_round (iround - 1) >>? fun durations -> + Period.of_seconds @@ List.fold_left Int64.add Int64.zero durations + >>? fun rounds_duration -> + Timestamp.(proposal_timestamp +? rounds_duration) >|? fun ts -> + (rounds_duration, ts) + else + durations round_durations iround (iproposal_round - 1) >>? fun durations -> + List.fold_left Int64.add Int64.zero durations |> fun rounds_duration -> + Timestamp.of_seconds + @@ Int64.sub (Timestamp.to_seconds proposal_timestamp) rounds_duration + |> fun ts -> + Period.of_seconds rounds_duration >|? fun rounds_duration -> + (rounds_duration, ts)) + >>? fun (_rnd_dur, exp_ts) -> ok exp_ts + +let drift_of = + let r0_dur = Round.round_duration round_durations Round.zero in + fun clock_drift -> Option.value ~default:r0_dur clock_drift + +(** [max_ts] computes the upper bound on future timestamps given the + accepted round drift. +*) +let max_ts clock_drift prop_ts now = + Timestamp.(max prop_ts now +? drift_of clock_drift) + +let count = None + +let predecessor_start proposal_timestamp proposal_round grandparent_round = + assert_no_error + @@ ( Round.level_offset_of_round + round_durations + ~round:Round.(succ grandparent_round) + >>? fun proposal_level_offset -> + Round.level_offset_of_round round_durations ~round:proposal_round + >>? fun proposal_round_offset -> + Period.(add proposal_level_offset proposal_round_offset) + >>? fun proposal_offset -> + Ok Timestamp.(proposal_timestamp - proposal_offset) ) + +(** TESTS *) + +(** Test past operations that are accepted whatever the current timestamp is: + strictly before the predecessor level or at the current level and with a + strictly lower round than the head. *) + +let test_acceptable_past_level = + QCheck.Test.make + ~name:"acceptable past op " + (Generator.param_acceptable ()) + (fun + ( config, + ( ((proposal_round, op_round), (proposal_level, op_level)), + (proposal_timestamp, now_timestamp) ) ) + -> + QCheck.( + Raw_level.( + proposal_level > succ op_level + || (proposal_level = op_level && Round.(proposal_round > op_round))) + ==> no_error + @@ acceptable_op + ~config + ~round_durations + ~round_zero_duration + ~proposal_level + ~proposal_round + ~proposal_timestamp + ~proposal_predecessor_level_start: + (predecessor_start + proposal_timestamp + proposal_round + Round.zero) + ~op_level + ~op_round + ~now_timestamp)) + +(** Test acceptable operations at current level, current round, i.e. on the + currently considered proposal *) +let test_acceptable_current_level_current_round = + let open QCheck in + Test.make + ?count + ~name:"same round, same level " + Generator.(param_acceptable ~rounds:same_rounds ~levels:same_levels ()) + (fun ( config, + (((op_round, _), (_, op_level)), (proposal_timestamp, now_timestamp)) + ) -> + let proposal_level = op_level in + let proposal_round = op_round in + no_error + @@ acceptable_op + ~config + ~round_durations + ~round_zero_duration + ~proposal_level + ~proposal_round + ~proposal_timestamp + ~proposal_predecessor_level_start: + (predecessor_start proposal_timestamp proposal_round Round.zero) + ~op_level + ~op_round + ~now_timestamp) + +(** Test operations at same level, different round, with an acceptable expected + timestamp for the operation. *) +let test_acceptable_current_level = + let open QCheck in + Test.make + ?count + ~name:"same level, different round, acceptable op" + Generator.(param_acceptable ~levels:same_levels ()) + (fun ( config, + ( ((proposal_round, op_round), (_, op_level)), + (proposal_timestamp, now_timestamp) ) ) -> + let proposal_level = op_level in + no_error + ( timestamp_of_round + round_durations + ~proposal_timestamp + ~proposal_round + ~round:op_round + >>? fun expected_time -> + max_ts config.clock_drift proposal_timestamp now_timestamp + >>? fun max_timestamp -> ok Timestamp.(expected_time <= max_timestamp) + ) + ==> no_error + @@ acceptable_op + ~config + ~round_durations + ~round_zero_duration + ~proposal_level + ~proposal_round + ~proposal_timestamp + ~proposal_predecessor_level_start: + (predecessor_start + proposal_timestamp + proposal_round + Round.zero) + ~op_level + ~op_round + ~now_timestamp) + +(** Test operations at same level, different round, with a too high expected + timestamp for the operation, and not at current round (which is always accepted). *) +let test_not_acceptable_current_level = + let open QCheck in + Test.make + ?count + ~name:"same level, different round, too far" + Generator.(param_acceptable ~levels:same_levels ()) + (fun ( config, + ( ((proposal_round, op_round), (_, op_level)), + (proposal_timestamp, now_timestamp) ) ) -> + let proposal_level = op_level in + no_error + ( timestamp_of_round + round_durations + ~proposal_timestamp + ~proposal_round + ~round:op_round + >>? fun expected_time -> + max_ts config.clock_drift proposal_timestamp now_timestamp + >>? fun max_timestamp -> + ok + Timestamp.( + expected_time > max_timestamp + && Round.(proposal_round <> op_round)) ) + ==> no_error + (acceptable_op + ~config + ~round_durations + ~round_zero_duration + ~proposal_level + ~proposal_round + ~proposal_timestamp + ~proposal_predecessor_level_start: + (predecessor_start + proposal_timestamp + proposal_round + Round.zero) + ~op_level + ~op_round + ~now_timestamp + >|? not)) + +(** Test operations at next level, different round, with an acceptable timestamp for + the operation. *) +let test_acceptable_next_level = + let open QCheck in + Test.make + ?count + ~name:"next level, acceptable op" + Generator.(param_acceptable ~levels:same_levels ()) + (fun ( config, + ( ((proposal_round, op_round), (proposal_level, _)), + (proposal_timestamp, now_timestamp) ) ) -> + let op_level = Raw_level.succ proposal_level in + no_error + ( timestamp_of_round + round_durations + ~proposal_timestamp + ~proposal_round + ~round:Round.zero + >>? fun current_level_start -> + Round.timestamp_of_round + round_durations + ~predecessor_timestamp:current_level_start + ~predecessor_round:Round.zero + ~round:op_round + >>? fun expected_time -> + max_ts config.clock_drift proposal_timestamp now_timestamp + >>? fun max_timestamp -> ok Timestamp.(expected_time <= max_timestamp) + ) + ==> no_error + @@ acceptable_op + ~config + ~round_durations + ~round_zero_duration + ~proposal_level + ~proposal_round + ~proposal_timestamp + ~proposal_predecessor_level_start: + (predecessor_start + proposal_timestamp + proposal_round + Round.zero) + ~op_level + ~op_round + ~now_timestamp) + +(** Test operations at next level, different round, with a too high timestamp + for the operation. *) +let test_not_acceptable_next_level = + let open QCheck in + Test.make + ?count + ~name:"next level, too far" + Generator.( + param_acceptable ~levels:same_levels ~timestamps:successive_timestamp ()) + (fun ( config, + ( ((proposal_round, op_round), (proposal_level, _)), + (proposal_timestamp, now_timestamp) ) ) -> + let op_level = Raw_level.succ proposal_level in + QCheck.assume + @@ no_error + ( timestamp_of_round + round_durations + ~proposal_timestamp + ~proposal_round + ~round:Round.zero + >>? fun current_level_start -> + Round.timestamp_of_round + round_durations + ~predecessor_timestamp:current_level_start + ~predecessor_round:Round.zero + ~round:op_round + >>? fun expected_time -> + Timestamp.( + proposal_timestamp + +? Round.round_duration round_durations proposal_round) + >>? fun next_level_ts -> + max_ts config.clock_drift next_level_ts now_timestamp + >>? fun max_timestamp -> + ok Timestamp.(expected_time > max_timestamp) ) ; + no_error + @@ (acceptable_op + ~config + ~round_durations + ~round_zero_duration + ~proposal_level + ~proposal_round + ~proposal_timestamp + ~proposal_predecessor_level_start: + (predecessor_start proposal_timestamp proposal_round Round.zero) + ~op_level + ~op_round + ~now_timestamp + >|? not)) + +let () = + Alcotest.run + "Filter" + [ + ( "pre_filter", + qcheck_wrap + [ + test_acceptable_past_level; + test_acceptable_current_level_current_round; + test_acceptable_current_level; + test_not_acceptable_current_level; + test_acceptable_next_level; + test_not_acceptable_next_level; + ] ); + ] diff --git a/src/proto_012_PsiThaCa/lib_plugin/tezos-protocol-plugin-012-PsiThaCa-registerer.opam b/src/proto_012_PsiThaCa/lib_plugin/tezos-protocol-plugin-012-PsiThaCa-registerer.opam new file mode 100644 index 000000000000..7039beb4f626 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/tezos-protocol-plugin-012-PsiThaCa-registerer.opam @@ -0,0 +1,18 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-embedded-protocol-012-PsiThaCa" + "tezos-protocol-plugin-012-PsiThaCa" + "tezos-shell" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol plugin registerer" diff --git a/src/proto_012_PsiThaCa/lib_plugin/tezos-protocol-plugin-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_plugin/tezos-protocol-plugin-012-PsiThaCa.opam new file mode 100644 index 000000000000..7f92c67bf011 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_plugin/tezos-protocol-plugin-012-PsiThaCa.opam @@ -0,0 +1,22 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-stdlib-unix" + "tezos-protocol-012-PsiThaCa" + "tezos-protocol-012-PsiThaCa-parameters" {with-test} + "tezos-test-helpers" {with-test} + "alcotest-lwt" {with-test} + "qcheck-alcotest" {with-test} +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol plugin" diff --git a/src/proto_012_PsiThaCa/lib_protocol/.ocamlformat b/src/proto_012_PsiThaCa/lib_protocol/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_protocol/TEZOS_PROTOCOL b/src/proto_012_PsiThaCa/lib_protocol/TEZOS_PROTOCOL new file mode 100644 index 000000000000..575bda8a9892 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/TEZOS_PROTOCOL @@ -0,0 +1,129 @@ +{ + "expected_env_version": 4, + "hash": "PsiThaCaT47Zboaw71QWScM8sXeMM7bbQFncK9FLqYc6EKdpjVP", + "modules": [ + "Misc", + "Non_empty_string", + "Path_encoding", + "Storage_description", + "State_hash", + "Nonce_hash", + "Script_expr_hash", + "Contract_hash", + "Blinded_public_key_hash", + "Block_payload_hash", + + "Slot_repr", + "Tez_repr", + "Period_repr", + "Time_repr", + "Round_repr", + "Block_payload_repr", + "Fixed_point_repr", + "Saturation_repr", + "Gas_limit_repr", + "Constants_repr", + "Raw_level_repr", + "Fitness_repr", + "Cycle_repr", + "Level_repr", + "Seed_repr", + "Sampler", + "Voting_period_repr", + "Script_string_repr", + "Script_int_repr", + "Script_timestamp_repr", + "Michelson_v1_primitives", + "Script_repr", + "Cache_memory_helpers", + "Contract_repr", + "Roll_repr_legacy", + "Vote_repr", + "Block_header_repr", + "Operation_repr", + "Manager_repr", + "Commitment_repr", + "Parameters_repr", + "Sapling_repr", + "Lazy_storage_kind", + "Receipt_repr", + "Migration_repr", + + "Raw_context_intf", + "Raw_context", + "Storage_costs", + "Storage_sigs", + "Storage_functors", + "Storage", + "Cache_repr", + + "Constants_storage", + "Level_storage", + "Nonce_storage", + "Seed_storage", + "Roll_storage_legacy", + "Contract_manager_storage", + "Delegate_activation_storage", + "Frozen_deposits_storage", + "Stake_storage", + "Contract_delegate_storage", + "Sapling_storage", + "Lazy_storage_diff", + "Contract_storage", + "Commitment_storage", + "Token", + "Delegate_storage", + "Bootstrap_storage", + "Voting_period_storage", + "Vote_storage", + "Fees_storage", + "Ticket_storage", + "Liquidity_baking_repr", + "Liquidity_baking_cpmm", + "Liquidity_baking_lqt", + "Liquidity_baking_migration", + "Init_storage", + "Sapling_validator", + + "Global_constants_costs", + "Global_constants_storage", + + "Alpha_context", + + "Local_gas_counter", + "Gas_monad", + "Script_tc_errors", + "Script_ir_annot", + "Script_typed_ir", + "Script_typed_ir_size", + "Script_typed_ir_size_costs", + "Michelson_v1_gas", + "Script_list", + "Script_comparable", + "Script_set", + "Script_map", + "Script_ir_translator", + "Script_cache", + "Script_tc_errors_registration", + "Ticket_costs", + "Ticket_scanner", + "Ticket_balance_key", + "Script_interpreter_defs", + "Script_interpreter", + + "Baking", + "Amendment", + "Apply_results", + "Apply", + + "Services_registration", + "Constants_services", + "Sapling_services", + "Contract_services", + "Delegate_services", + "Voting_services", + "Alpha_services", + + "Main" + ] +} diff --git a/src/proto_012_PsiThaCa/lib_protocol/alpha_context.ml b/src/proto_012_PsiThaCa/lib_protocol/alpha_context.ml new file mode 100644 index 000000000000..83321a218c37 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/alpha_context.ml @@ -0,0 +1,436 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = Raw_context.t + +type context = t + +module type BASIC_DATA = sig + type t + + include Compare.S with type t := t + + val encoding : t Data_encoding.t + + val pp : Format.formatter -> t -> unit +end + +module Tez = Tez_repr +module Period = Period_repr + +module Timestamp = struct + include Time_repr + + let current = Raw_context.current_timestamp + + let predecessor = Raw_context.predecessor_timestamp +end + +module Slot = struct + include Slot_repr + + let slot_range = List.slot_range +end + +include Operation_repr + +module Operation = struct + type 'kind t = 'kind operation = { + shell : Operation.shell_header; + protocol_data : 'kind protocol_data; + } + + type packed = packed_operation + + let unsigned_encoding = unsigned_operation_encoding + + include Operation_repr +end + +module Block_header = Block_header_repr + +module Vote = struct + include Vote_repr + include Vote_storage +end + +module Block_payload = struct + include Block_payload_repr +end + +module First_level_of_tenderbake = struct + let get = Storage.Tenderbake.First_level.get +end + +module Raw_level = Raw_level_repr +module Cycle = Cycle_repr +module Script_string = Script_string_repr +module Script_int = Script_int_repr + +module Script_timestamp = struct + include Script_timestamp_repr + + let now ctxt = + let {Constants_repr.minimal_block_delay; _} = Raw_context.constants ctxt in + let first_delay = Period_repr.to_seconds minimal_block_delay in + let current_timestamp = Raw_context.predecessor_timestamp ctxt in + Time.add current_timestamp first_delay |> Timestamp.to_seconds |> of_int64 +end + +module Script = struct + include Michelson_v1_primitives + include Script_repr + + type consume_deserialization_gas = Always | When_needed + + let force_decode_in_context ~consume_deserialization_gas ctxt lexpr = + let gas_cost = + match consume_deserialization_gas with + | Always -> Script_repr.stable_force_decode_cost lexpr + | When_needed -> Script_repr.force_decode_cost lexpr + in + Raw_context.consume_gas ctxt gas_cost >>? fun ctxt -> + Script_repr.force_decode lexpr >|? fun v -> (v, ctxt) + + let force_bytes_in_context ctxt lexpr = + Raw_context.consume_gas ctxt (Script_repr.force_bytes_cost lexpr) + >>? fun ctxt -> + Script_repr.force_bytes lexpr >|? fun v -> (v, ctxt) +end + +module Fees = Fees_storage + +type public_key = Signature.Public_key.t + +type public_key_hash = Signature.Public_key_hash.t + +type signature = Signature.t + +module Constants = struct + include Constants_repr + include Constants_storage + + let round_durations ctxt = Raw_context.round_durations ctxt + + let all ctxt = all (parametric ctxt) +end + +module Voting_period = struct + include Voting_period_repr + include Voting_period_storage +end + +module Round = struct + include Round_repr + module Durations = Durations + + type round_durations = Durations.t + + let pp_round_durations = Durations.pp + + let round_durations_encoding = Durations.encoding + + let round_duration = Round_repr.Durations.round_duration + + let update ctxt round = Storage.Block_round.update ctxt round + + let get ctxt = Storage.Block_round.get ctxt +end + +module Gas = struct + include Gas_limit_repr + + type error += Gas_limit_too_high = Raw_context.Gas_limit_too_high + + type error += Block_quota_exceeded = Raw_context.Block_quota_exceeded + + type error += Operation_quota_exceeded = Raw_context.Operation_quota_exceeded + + let check_limit_is_valid = Raw_context.check_gas_limit_is_valid + + let set_limit = Raw_context.set_gas_limit + + let consume_limit_in_block = Raw_context.consume_gas_limit_in_block + + let set_unlimited = Raw_context.set_gas_unlimited + + let consume = Raw_context.consume_gas + + let remaining_operation_gas = Raw_context.remaining_operation_gas + + let update_remaining_operation_gas = + Raw_context.update_remaining_operation_gas + + let reset_block_gas ctxt = + let gas = Constants.hard_gas_limit_per_block ctxt in + Raw_context.update_remaining_block_gas ctxt gas + + let level = Raw_context.gas_level + + let consumed = Raw_context.gas_consumed + + let block_level = Raw_context.block_gas_level + + (* Necessary to inject costs for Storage_costs into Gas.cost *) + let cost_of_repr cost = cost +end + +module Level = struct + include Level_repr + include Level_storage +end + +module Lazy_storage = struct + module Kind = Lazy_storage_kind + module IdSet = Kind.IdSet + include Lazy_storage_diff + + let legacy_big_map_diff_encoding = + Data_encoding.conv + Contract_storage.Legacy_big_map_diff.of_lazy_storage_diff + Contract_storage.Legacy_big_map_diff.to_lazy_storage_diff + Contract_storage.Legacy_big_map_diff.encoding +end + +module Contract = struct + include Contract_repr + include Contract_storage + + let init_origination_nonce = Raw_context.init_origination_nonce + + let unset_origination_nonce = Raw_context.unset_origination_nonce + + let is_manager_key_revealed = Contract_manager_storage.is_manager_key_revealed + + let reveal_manager_key = Contract_manager_storage.reveal_manager_key + + let get_manager_key = Contract_manager_storage.get_manager_key +end + +module Global_constants_storage = Global_constants_storage + +module Big_map = struct + module Big_map = Lazy_storage_kind.Big_map + + module Id = struct + type t = Big_map.Id.t + + let encoding = Big_map.Id.encoding + + let rpc_arg = Big_map.Id.rpc_arg + + let parse_z = Big_map.Id.parse_z + + let unparse_to_z = Big_map.Id.unparse_to_z + end + + let fresh ~temporary c = Lazy_storage.fresh Big_map ~temporary c + + let mem c m k = Storage.Big_map.Contents.mem (c, m) k + + let get_opt c m k = Storage.Big_map.Contents.find (c, m) k + + let list_values ?offset ?length c m = + Storage.Big_map.Contents.list_values ?offset ?length (c, m) + + let exists c id = + Raw_context.consume_gas c (Gas_limit_repr.read_bytes_cost 0) >>?= fun c -> + Storage.Big_map.Key_type.find c id >>=? fun kt -> + match kt with + | None -> return (c, None) + | Some kt -> + Storage.Big_map.Value_type.get c id >|=? fun kv -> (c, Some (kt, kv)) + + type update = Big_map.update = { + key : Script_repr.expr; + key_hash : Script_expr_hash.t; + value : Script_repr.expr option; + } + + type updates = Big_map.updates + + type alloc = Big_map.alloc = { + key_type : Script_repr.expr; + value_type : Script_repr.expr; + } +end + +module Sapling = struct + module Sapling_state = Lazy_storage_kind.Sapling_state + + module Id = struct + type t = Sapling_state.Id.t + + let encoding = Sapling_state.Id.encoding + + let rpc_arg = Sapling_state.Id.rpc_arg + + let parse_z = Sapling_state.Id.parse_z + + let unparse_to_z = Sapling_state.Id.unparse_to_z + end + + include Sapling_repr + include Sapling_storage + include Sapling_validator + + let fresh ~temporary c = Lazy_storage.fresh Sapling_state ~temporary c + + type updates = Sapling_state.updates + + type alloc = Sapling_state.alloc = {memo_size : Sapling_repr.Memo_size.t} +end + +module Receipt = Receipt_repr + +module Delegate = struct + include Delegate_storage + + type deposits = Storage.deposits = { + initial_amount : Tez.t; + current_amount : Tez.t; + } + + let grace_period = Delegate_activation_storage.grace_period + + let prepare_stake_distribution = Stake_storage.prepare_stake_distribution + + let registered = Contract_delegate_storage.registered + + let find = Contract_delegate_storage.find + + let delegated_contracts = Contract_delegate_storage.delegated_contracts +end + +module Stake_distribution = struct + let snapshot = Stake_storage.snapshot + + let baking_rights_owner = Delegate.baking_rights_owner + + let slot_owner = Delegate.slot_owner + + let delegate_pubkey = Delegate.pubkey + + let get_staking_balance = Delegate.staking_balance +end + +module Nonce = Nonce_storage + +module Seed = struct + include Seed_repr + include Seed_storage +end + +module Fitness = struct + type raw = Fitness.t + + include Fitness_repr +end + +module Bootstrap = Bootstrap_storage + +module Commitment = struct + include Commitment_repr + include Commitment_storage +end + +module Migration = Migration_repr + +module Consensus = struct + include Raw_context.Consensus + + let load_endorsement_branch ctxt = + Storage.Tenderbake.Endorsement_branch.find ctxt >>=? function + | Some endorsement_branch -> + Raw_context.Consensus.set_endorsement_branch ctxt endorsement_branch + |> return + | None -> return ctxt + + let store_endorsement_branch ctxt branch = + let ctxt = set_endorsement_branch ctxt branch in + Storage.Tenderbake.Endorsement_branch.add ctxt branch + + let load_grand_parent_branch ctxt = + Storage.Tenderbake.Grand_parent_branch.find ctxt >>=? function + | Some grand_parent_branch -> + Raw_context.Consensus.set_grand_parent_branch ctxt grand_parent_branch + |> return + | None -> return ctxt + + let store_grand_parent_branch ctxt branch = + let ctxt = set_grand_parent_branch ctxt branch in + Storage.Tenderbake.Grand_parent_branch.add ctxt branch +end + +let prepare_first_block = Init_storage.prepare_first_block + +let prepare ctxt ~level ~predecessor_timestamp ~timestamp = + Init_storage.prepare ctxt ~level ~predecessor_timestamp ~timestamp + >>=? fun (ctxt, balance_updates, origination_results) -> + Consensus.load_endorsement_branch ctxt >>=? fun ctxt -> + Consensus.load_grand_parent_branch ctxt >>=? fun ctxt -> + return (ctxt, balance_updates, origination_results) + +let finalize ?commit_message:message c fitness = + let context = Raw_context.recover c in + { + Updater.context; + fitness; + message; + max_operations_ttl = (Raw_context.constants c).max_operations_time_to_live; + last_allowed_fork_level = + Raw_level.to_int32 @@ Level.last_allowed_fork_level c; + } + +let current_context c = Raw_context.recover c + +let record_non_consensus_operation_hash = + Raw_context.record_non_consensus_operation_hash + +let non_consensus_operations = Raw_context.non_consensus_operations + +let activate = Raw_context.activate + +let reset_internal_nonce = Raw_context.reset_internal_nonce + +let fresh_internal_nonce = Raw_context.fresh_internal_nonce + +let record_internal_nonce = Raw_context.record_internal_nonce + +let internal_nonce_already_recorded = + Raw_context.internal_nonce_already_recorded + +let description = Raw_context.description + +module Parameters = Parameters_repr +module Liquidity_baking = Liquidity_baking_repr + +module Ticket_balance = struct + include Ticket_storage +end + +module Token = Token +module Cache = Cache_repr diff --git a/src/proto_012_PsiThaCa/lib_protocol/alpha_context.mli b/src/proto_012_PsiThaCa/lib_protocol/alpha_context.mli new file mode 100644 index 000000000000..90bfdec63267 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/alpha_context.mli @@ -0,0 +1,2436 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2021 Nomadic Labs *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** An [Alpha_context.t] is an immutable snapshot of the ledger state at some block + height, preserving + {{:https://tezos.gitlab.io/developer/entering_alpha.html#the-big-abstraction-barrier-alpha-context} + type-safety and invariants} of the ledger state. + + {2 Implementation} + + [Alpha_context.t] is a wrapper over [Raw_context.t], which in turn is a + wrapper around [Context.t] from the Protocol Environment. + + {2 Lifetime of an Alpha_context} + + - Creation, using [prepare] or [prepare_first_block] + + - Modification, using the operations defined in this signature + + - Finalization, using [finalize] + *) + +module type BASIC_DATA = sig + type t + + include Compare.S with type t := t + + val encoding : t Data_encoding.t + + val pp : Format.formatter -> t -> unit +end + +type t + +type context = t + +type public_key = Signature.Public_key.t + +type public_key_hash = Signature.Public_key_hash.t + +type signature = Signature.t + +module Slot : sig + type t + + include Compare.S with type t := t + + val pp : Format.formatter -> t -> unit + + val zero : t + + val succ : t -> t + + val of_int_do_not_use_except_for_parameters : int -> t + + val encoding : t Data_encoding.encoding + + val slot_range : min:int -> count:int -> t list tzresult + + module Map : Map.S with type key = t + + module Set : Set.S with type elt = t +end + +module Tez : sig + include BASIC_DATA + + type tez = t + + val zero : tez + + val one_mutez : tez + + val one_cent : tez + + val fifty_cents : tez + + val one : tez + + val ( -? ) : tez -> tez -> tez tzresult + + val sub_opt : tez -> tez -> tez option + + val ( +? ) : tez -> tez -> tez tzresult + + val ( *? ) : tez -> int64 -> tez tzresult + + val ( /? ) : tez -> int64 -> tez tzresult + + val of_string : string -> tez option + + val to_string : tez -> string + + val of_mutez : int64 -> tez option + + val to_mutez : tez -> int64 + + val of_mutez_exn : int64 -> t + + val mul_exn : t -> int -> t + + val div_exn : t -> int -> t +end + +module Period : sig + include BASIC_DATA + + type period = t + + val rpc_arg : period RPC_arg.arg + + val of_seconds : int64 -> period tzresult + + val of_seconds_exn : int64 -> period + + val to_seconds : period -> int64 + + val add : period -> period -> period tzresult + + val mult : int32 -> period -> period tzresult + + val zero : period + + val one_second : period + + val one_minute : period + + val one_hour : period + + val compare : period -> period -> int +end + +module Timestamp : sig + include BASIC_DATA with type t = Time.t + + type time = t + + val ( +? ) : time -> Period.t -> time tzresult + + val ( -? ) : time -> time -> Period.t tzresult + + val ( - ) : time -> Period.t -> time + + val of_notation : string -> time option + + val to_notation : time -> string + + val of_seconds : int64 -> time + + val to_seconds : time -> int64 + + val of_seconds_string : string -> time option + + val to_seconds_string : time -> string + + val current : context -> time + + val predecessor : context -> time +end + +module Raw_level : sig + include BASIC_DATA + + type raw_level = t + + val rpc_arg : raw_level RPC_arg.arg + + val diff : raw_level -> raw_level -> int32 + + val root : raw_level + + val succ : raw_level -> raw_level + + val pred : raw_level -> raw_level option + + val to_int32 : raw_level -> int32 + + val of_int32 : int32 -> raw_level tzresult +end + +module Cycle : sig + include BASIC_DATA + + type cycle = t + + val rpc_arg : cycle RPC_arg.arg + + val root : cycle + + val succ : cycle -> cycle + + val pred : cycle -> cycle option + + val add : cycle -> int -> cycle + + val sub : cycle -> int -> cycle option + + val to_int32 : cycle -> int32 + + module Map : Map.S with type key = cycle +end + +module Round : sig + (* A round represents an iteration of the single-shot consensus algorithm. + This mostly simply re-exports [Round_repr]. See [Round_repr] for + additional documentation of this module *) + + type t + + val zero : t + + val succ : t -> t + + val pred : t -> t tzresult + + val to_int32 : t -> int32 + + val of_int32 : int32 -> t tzresult + + val of_int : int -> t tzresult + + val to_int : t -> int tzresult + + val to_slot : t -> committee_size:int -> Slot.t tzresult + + val pp : Format.formatter -> t -> unit + + val encoding : t Data_encoding.t + + include Compare.S with type t := t + + module Map : Map.S with type key = t + + type round_durations + + val pp_round_durations : Format.formatter -> round_durations -> unit + + val round_durations_encoding : round_durations Data_encoding.t + + val round_duration : round_durations -> t -> Period.t + + module Durations : sig + val create : + first_round_duration:Period.t -> + delay_increment_per_round:Period.t -> + round_durations tzresult + + val create_opt : + first_round_duration:Period.t -> + delay_increment_per_round:Period.t -> + round_durations option + end + + val level_offset_of_round : round_durations -> round:t -> Period.t tzresult + + val timestamp_of_round : + round_durations -> + predecessor_timestamp:Time.t -> + predecessor_round:t -> + round:t -> + Time.t tzresult + + val timestamp_of_another_round_same_level : + round_durations -> + current_timestamp:Time.t -> + current_round:t -> + considered_round:t -> + Time.t tzresult + + val round_of_timestamp : + round_durations -> + predecessor_timestamp:Time.t -> + predecessor_round:t -> + timestamp:Time.t -> + t tzresult + + (* retrieve a round from the context *) + val get : context -> t tzresult Lwt.t + + (* store a round in context *) + val update : context -> t -> context tzresult Lwt.t +end + +module Gas : sig + (** This module implements the gas subsystem of the context. + + Gas reflects the computational cost of each operation to limit + the cost of operations and, by extension, the cost of blocks. + + There are two gas quotas: one for operation and one for + block. For this reason, we maintain two gas levels -- one for + operations and another one for blocks -- that correspond to the + remaining amounts of gas, initialized with the quota + limits and decreased each time gas is consumed. + + *) + + module Arith : + Fixed_point_repr.Safe + with type 'a t = Saturation_repr.may_saturate Saturation_repr.t + [@@coq_plain_module] + + (** For maintenance operations or for testing, gas can be + [Unaccounted]. Otherwise, the computation is [Limited] by the + [remaining] gas in the context. *) + type t = private Unaccounted | Limited of {remaining : Arith.fp} + + val encoding : t Data_encoding.encoding + + val pp : Format.formatter -> t -> unit + + (** [check_limit_is_valid ctxt limit] checks that the given gas + [limit] is well-formed, i.e., it does not exceed the hard gas + limit per operation as defined in [ctxt] and it is positive. *) + val check_limit_is_valid : context -> 'a Arith.t -> unit tzresult + + (** [set_limit ctxt limit] returns a context with a given + [limit] level of gas allocated for an operation. *) + val set_limit : context -> 'a Arith.t -> context + + (** [set_unlimited] allows unlimited gas consumption. *) + val set_unlimited : context -> context + + (** [remaining_operation_gas ctxt] returns the current gas level in + the context [ctxt] for the current operation. If gas is + [Unaccounted], an arbitrary value will be returned. *) + val remaining_operation_gas : context -> Arith.fp + + (** [reset_block_gas ctxt] returns a context where the remaining gas + in the block is reset to the constant [hard_gas_limit_per_block], + i.e., as if no operations have been included in the block. + + /!\ Do not call this function unless you want to validate + operations on their own (like in the mempool). *) + val reset_block_gas : context -> context + + (** [level ctxt] is the current gas level in [ctxt] for the current + operation. *) + val level : context -> t + + (** [update_remaining_operation_gas ctxt remaining] sets the current + gas level for operations to [remaining]. *) + val update_remaining_operation_gas : context -> Arith.fp -> context + + (** [consumed since until] is the operation gas level difference + between context [since] and context [until]. This function + returns [Arith.zero] if any of the two contexts allows for an + unlimited gas consumption. This function also returns + [Arith.zero] if [since] has less gas than [until]. *) + val consumed : since:context -> until:context -> Arith.fp + + (** [block_level ctxt] returns the block gas level in context [ctxt]. *) + val block_level : context -> Arith.fp + + (** Costs are computed using a saturating arithmetic. See + {!Saturation_repr}. *) + type cost = Saturation_repr.may_saturate Saturation_repr.t + + val cost_encoding : cost Data_encoding.encoding + + val pp_cost : Format.formatter -> cost -> unit + + (** [consume ctxt cost] subtracts [cost] to the current operation + gas level in [ctxt]. This operation may fail with + [Operation_quota_exceeded] if the operation gas level would + go below zero. *) + val consume : context -> cost -> context tzresult + + type error += Operation_quota_exceeded (* `Temporary *) + + (** [consume_limit_in_block ctxt limit] consumes [limit] in + the current block gas level of the context. This operation may + fail with error [Block_quota_exceeded] if not enough gas remains + in the block. This operation may also fail with + [Gas_limit_too_high] if [limit] is greater than the allowed + limit for operation gas level. *) + val consume_limit_in_block : context -> 'a Arith.t -> context tzresult + + type error += Block_quota_exceeded (* `Temporary *) + + type error += Gas_limit_too_high (* `Permanent *) + + (** The cost of free operation is [0]. *) + val free : cost + + (** [atomic_step_cost x] corresponds to [x] milliunit of gas. *) + val atomic_step_cost : _ Saturation_repr.t -> cost + + (** [step_cost x] corresponds to [x] units of gas. *) + val step_cost : _ Saturation_repr.t -> cost + + (** Cost of allocating qwords of storage. + [alloc_cost n] estimates the cost of allocating [n] qwords of storage. *) + val alloc_cost : _ Saturation_repr.t -> cost + + (** Cost of allocating bytes in the storage. + [alloc_bytes_cost b] estimates the cost of allocating [b] bytes of + storage. *) + val alloc_bytes_cost : int -> cost + + (** Cost of allocating bytes in the storage. + + [alloc_mbytes_cost b] estimates the cost of allocating [b] bytes of + storage and the cost of an header to describe these bytes. *) + val alloc_mbytes_cost : int -> cost + + (** Cost of reading the storage. + [read_bytes_cost n] estimates the cost of reading [n] bytes of storage. *) + val read_bytes_cost : int -> cost + + (** Cost of writing to storage. + [write_bytes_const n] estimates the cost of writing [n] bytes to the + storage. *) + val write_bytes_cost : int -> cost + + (** Multiply a cost by a factor. Both arguments are saturated arithmetic values, + so no negative numbers are involved. *) + val ( *@ ) : _ Saturation_repr.t -> cost -> cost + + (** Add two costs together. *) + val ( +@ ) : cost -> cost -> cost + + (** [cost_of_repr] is an internal operation needed to inject costs + for Storage_costs into Gas.cost. *) + val cost_of_repr : Gas_limit_repr.cost -> cost +end + +module Script_string : module type of Script_string_repr + +module Script_int : module type of Script_int_repr + +module Script_timestamp : sig + open Script_int + + type t + + val compare : t -> t -> int + + val to_string : t -> string + + val to_notation : t -> string option + + val to_num_str : t -> string + + val of_string : string -> t option + + val diff : t -> t -> z num + + val add_delta : t -> z num -> t + + val sub_delta : t -> z num -> t + + val now : context -> t + + val to_zint : t -> Z.t + + val of_zint : Z.t -> t + + val encoding : t Data_encoding.encoding +end + +module Script : sig + type prim = Michelson_v1_primitives.prim = + | K_parameter + | K_storage + | K_code + | K_view + | D_False + | D_Elt + | D_Left + | D_None + | D_Pair + | D_Right + | D_Some + | D_True + | D_Unit + | I_PACK + | I_UNPACK + | I_BLAKE2B + | I_SHA256 + | I_SHA512 + | I_ABS + | I_ADD + | I_AMOUNT + | I_AND + | I_BALANCE + | I_CAR + | I_CDR + | I_CHAIN_ID + | I_CHECK_SIGNATURE + | I_COMPARE + | I_CONCAT + | I_CONS + | I_CREATE_ACCOUNT + | I_CREATE_CONTRACT + | I_IMPLICIT_ACCOUNT + | I_DIP + | I_DROP + | I_DUP + | I_VIEW + | I_EDIV + | I_EMPTY_BIG_MAP + | I_EMPTY_MAP + | I_EMPTY_SET + | I_EQ + | I_EXEC + | I_APPLY + | I_FAILWITH + | I_GE + | I_GET + | I_GET_AND_UPDATE + | I_GT + | I_HASH_KEY + | I_IF + | I_IF_CONS + | I_IF_LEFT + | I_IF_NONE + | I_INT + | I_LAMBDA + | I_LE + | I_LEFT + | I_LEVEL + | I_LOOP + | I_LSL + | I_LSR + | I_LT + | I_MAP + | I_MEM + | I_MUL + | I_NEG + | I_NEQ + | I_NIL + | I_NONE + | I_NOT + | I_NOW + | I_OR + | I_PAIR + | I_UNPAIR + | I_PUSH + | I_RIGHT + | I_SIZE + | I_SOME + | I_SOURCE + | I_SENDER + | I_SELF + | I_SELF_ADDRESS + | I_SLICE + | I_STEPS_TO_QUOTA + | I_SUB + | I_SUB_MUTEZ + | I_SWAP + | I_TRANSFER_TOKENS + | I_SET_DELEGATE + | I_UNIT + | I_UPDATE + | I_XOR + | I_ITER + | I_LOOP_LEFT + | I_ADDRESS + | I_CONTRACT + | I_ISNAT + | I_CAST + | I_RENAME + | I_SAPLING_EMPTY_STATE + | I_SAPLING_VERIFY_UPDATE + | I_DIG + | I_DUG + | I_NEVER + | I_VOTING_POWER + | I_TOTAL_VOTING_POWER + | I_KECCAK + | I_SHA3 + | I_PAIRING_CHECK + | I_TICKET + | I_READ_TICKET + | I_SPLIT_TICKET + | I_JOIN_TICKETS + | I_OPEN_CHEST + | T_bool + | T_contract + | T_int + | T_key + | T_key_hash + | T_lambda + | T_list + | T_map + | T_big_map + | T_nat + | T_option + | T_or + | T_pair + | T_set + | T_signature + | T_string + | T_bytes + | T_mutez + | T_timestamp + | T_unit + | T_operation + | T_address + | T_sapling_transaction + | T_sapling_state + | T_chain_id + | T_never + | T_bls12_381_g1 + | T_bls12_381_g2 + | T_bls12_381_fr + | T_ticket + | T_chest_key + | T_chest + | H_constant + + type location = Micheline.canonical_location + + type annot = Micheline.annot + + type expr = prim Micheline.canonical + + type lazy_expr = expr Data_encoding.lazy_t + + val lazy_expr : expr -> lazy_expr + + type 'location michelson_node = ('location, prim) Micheline.node + + type unlocated_michelson_node = unit michelson_node + + type node = location michelson_node + + type t = {code : lazy_expr; storage : lazy_expr} + + val location_encoding : location Data_encoding.t + + val expr_encoding : expr Data_encoding.t + + val prim_encoding : prim Data_encoding.t + + val encoding : t Data_encoding.t + + val lazy_expr_encoding : lazy_expr Data_encoding.t + + val deserialization_cost_estimated_from_bytes : int -> Gas.cost + + val deserialized_cost : expr -> Gas.cost + + val serialized_cost : bytes -> Gas.cost + + val bytes_node_cost : bytes -> Gas.cost + + (** Mode of deserialization gas consumption in {!force_decode}: + + - {!Always}: the gas is taken independently of the internal state of the + [lazy_expr] + - {!When_needed}: the gas is consumed only if the [lazy_expr] has never + been deserialized before. *) + type consume_deserialization_gas = Always | When_needed + + (** Decode an expression in the context after consuming the deserialization + gas cost (see {!consume_deserialization_gas}). *) + val force_decode_in_context : + consume_deserialization_gas:consume_deserialization_gas -> + context -> + lazy_expr -> + (expr * context) tzresult + + val force_bytes_in_context : + context -> lazy_expr -> (bytes * context) tzresult + + val unit_parameter : lazy_expr + + val strip_locations_cost : _ michelson_node -> Gas.cost + + val strip_annotations_cost : node -> Gas.cost + + val strip_annotations : node -> node +end + +module Constants : sig + (** Fixed constants *) + type fixed + + type delegate_selection = + | Random + | Round_robin_over of Signature.Public_key.t list list + + val fixed_encoding : fixed Data_encoding.t + + val proof_of_work_nonce_size : int + + val nonce_length : int + + val max_anon_ops_per_block : int + + val max_operation_data_length : int + + val max_proposals_per_delegate : int + + val michelson_maximum_type_size : int + + type ratio = {numerator : int; denominator : int} + + val ratio_encoding : ratio Data_encoding.t + + val pp_ratio : Format.formatter -> ratio -> unit + + (** Constants parameterized by context *) + type parametric = { + preserved_cycles : int; + blocks_per_cycle : int32; + blocks_per_commitment : int32; + blocks_per_stake_snapshot : int32; + blocks_per_voting_period : int32; + hard_gas_limit_per_operation : Gas.Arith.integral; + hard_gas_limit_per_block : Gas.Arith.integral; + proof_of_work_threshold : int64; + tokens_per_roll : Tez.t; + seed_nonce_revelation_tip : Tez.t; + origination_size : int; + baking_reward_fixed_portion : Tez.t; + baking_reward_bonus_per_slot : Tez.t; + endorsing_reward_per_slot : Tez.t; + cost_per_byte : Tez.t; + hard_storage_limit_per_operation : Z.t; + quorum_min : int32; + quorum_max : int32; + min_proposal_quorum : int32; + liquidity_baking_subsidy : Tez.t; + liquidity_baking_sunset_level : int32; + liquidity_baking_escape_ema_threshold : int32; + max_operations_time_to_live : int; + minimal_block_delay : Period.t; + delay_increment_per_round : Period.t; + minimal_participation_ratio : ratio; + consensus_committee_size : int; + consensus_threshold : int; + max_slashing_period : int; + frozen_deposits_percentage : int; + double_baking_punishment : Tez.t; + ratio_of_frozen_deposits_slashed_per_double_endorsement : ratio; + delegate_selection : delegate_selection; + } + + module Generated : sig + type t = { + consensus_threshold : int; + baking_reward_fixed_portion : Tez.t; + baking_reward_bonus_per_slot : Tez.t; + endorsing_reward_per_slot : Tez.t; + } + + val generate : consensus_committee_size:int -> blocks_per_minute:ratio -> t + end + + val parametric_encoding : parametric Data_encoding.t + + val parametric : context -> parametric + + val preserved_cycles : context -> int + + val blocks_per_cycle : context -> int32 + + val blocks_per_commitment : context -> int32 + + val blocks_per_stake_snapshot : context -> int32 + + val blocks_per_voting_period : context -> int32 + + val hard_gas_limit_per_operation : context -> Gas.Arith.integral + + val hard_gas_limit_per_block : context -> Gas.Arith.integral + + val cost_per_byte : context -> Tez.t + + val hard_storage_limit_per_operation : context -> Z.t + + val proof_of_work_threshold : context -> int64 + + val tokens_per_roll : context -> Tez.t + + val seed_nonce_revelation_tip : context -> Tez.t + + val origination_size : context -> int + + val baking_reward_fixed_portion : context -> Tez.t + + val baking_reward_bonus_per_slot : context -> Tez.t + + val endorsing_reward_per_slot : context -> Tez.t + + val quorum_min : context -> int32 + + val quorum_max : context -> int32 + + val min_proposal_quorum : context -> int32 + + val liquidity_baking_subsidy : context -> Tez.t + + val liquidity_baking_sunset_level : context -> int32 + + val liquidity_baking_escape_ema_threshold : context -> int32 + + val minimal_block_delay : context -> Period.t + + val delay_increment_per_round : context -> Period.t + + val round_durations : context -> Round.round_durations + + val consensus_committee_size : context -> int + + val consensus_threshold : context -> int + + val minimal_participation_ratio : context -> ratio + + val max_slashing_period : context -> int + + val frozen_deposits_percentage : context -> int + + val double_baking_punishment : context -> Tez.t + + val ratio_of_frozen_deposits_slashed_per_double_endorsement : context -> ratio + + val delegate_selection_encoding : delegate_selection Data_encoding.t + + (** All constants: fixed and parametric *) + type t = private {fixed : fixed; parametric : parametric} + + val all : context -> t + + val encoding : t Data_encoding.t +end + +module Global_constants_storage : sig + type error += Expression_too_deep + + type error += Expression_already_registered + + (** A constant is the prim of the literal characters "constant". + A constant must have a single argument, being a string with a + well formed hash of a Micheline expression (i.e generated by + [Script_expr_hash.to_b58check]). *) + type error += Badly_formed_constant_expression + + type error += Nonexistent_global + + (** [get context hash] retrieves the Micheline value with the given hash. + + Fails with [Nonexistent_global] if no value is found at the given hash. + + Fails with [Storage_error Corrupted_data] if the deserialisation fails. + + Consumes [Gas_repr.read_bytes_cost ]. *) + val get : t -> Script_expr_hash.t -> (t * Script.expr) tzresult Lwt.t + + (** [register context value] Register a constant in the global table of constants, + returning the hash and storage bytes consumed. + + Does not type-check the Micheline code being registered, allow potentially + ill-typed Michelson values (see note at top of module in global_constants_storage.mli). + + The constant is stored unexpanded, but it is temporarily expanded at registration + time only to check the expanded version respects the following limits. + + Fails with [Expression_too_deep] if, after fully, expanding all constants, + the expression would contain too many nested levels, that is more than + [Constants_repr.max_allowed_global_constant_depth]. + + Fails with [Badly_formed_constant_expression] if constants are not + well-formed (see declaration of [Badly_formed_constant_expression]) or with + [Nonexistent_global] if a referenced constant does not exist in the table. + + Consumes serialization cost. + Consumes [Gas_repr.write_bytes_cost ] where size is the number + of bytes in the binary serialization provided by [Script.expr_encoding].*) + val register : + t -> Script.expr -> (t * Script_expr_hash.t * Z.t) tzresult Lwt.t + + (** [expand context expr] Replaces every constant in the + given Michelson expression with its value stored in the global table. + + The expansion is applied recursively so that the returned expression + contains no constant. + + Fails with [Badly_formed_constant_expression] if constants are not + well-formed (see declaration of [Badly_formed_constant_expression]) or + with [Nonexistent_global] if a referenced constant does not exist in + the table. *) + val expand : t -> Script.expr -> (t * Script.expr) tzresult Lwt.t + + module Internal_for_tests : sig + (** [node_too_large node] returns true if: + - The number of sub-nodes in the [node] + exceeds [Global_constants_storage.node_size_limit]. + - The sum of the bytes in String, Int, + and Bytes sub-nodes of [node] exceeds + [Global_constants_storage.bytes_size_limit]. + + Otherwise returns false. *) + val node_too_large : Script.node -> bool + + (** [bottom_up_fold_cps initial_accumulator node initial_k f] + folds [node] and all its sub-nodes if any, starting from + [initial_accumulator], using an initial continuation [initial_k]. + At each node, [f] is called to transform the continuation [k] into + the next one. This explicit manipulation of the continuation + is typically useful to short-circuit. + + Notice that a common source of bug is to forget to properly call the + continuation in `f`. *) + val bottom_up_fold_cps : + 'accumulator -> + 'loc Script.michelson_node -> + ('accumulator -> 'loc Script.michelson_node -> 'return) -> + ('accumulator -> + 'loc Script.michelson_node -> + ('accumulator -> 'loc Script.michelson_node -> 'return) -> + 'return) -> + 'return + + (** [expr_to_address_in_context context expr] converts [expr] + into a unique hash represented by a [Script_expr_hash.t]. + + Consumes gas corresponding to the cost of converting [expr] + to bytes and hashing the bytes. *) + val expr_to_address_in_context : + t -> Script.expr -> (t * Script_expr_hash.t) tzresult + end +end + +module Cache : sig + type size = int + + type index = int + + module Admin : sig + type key + + type value + + val pp : Format.formatter -> context -> unit + + val set_cache_layout : context -> size list -> context Lwt.t + + val sync : context -> cache_nonce:Bytes.t -> context Lwt.t + + val clear : context -> context + + val future_cache_expectation : context -> time_in_blocks:int -> context + + val cache_size : context -> cache_index:int -> size option + + val cache_size_limit : context -> cache_index:int -> size option + + val value_of_key : + context -> Context.Cache.key -> Context.Cache.value tzresult Lwt.t + end + + type namespace = private string + + val create_namespace : string -> namespace + + type identifier = string + + module type CLIENT = sig + type cached_value + + val cache_index : index + + val namespace : namespace + + val value_of_identifier : + context -> identifier -> cached_value tzresult Lwt.t + end + + module type INTERFACE = sig + type cached_value + + val update : + context -> identifier -> (cached_value * size) option -> context tzresult + + val find : context -> identifier -> cached_value option tzresult Lwt.t + + val list_identifiers : context -> (string * int) list + + val identifier_rank : context -> string -> int option + + val size : context -> int + + val size_limit : context -> int + end + + val register_exn : + (module CLIENT with type cached_value = 'a) -> + (module INTERFACE with type cached_value = 'a) +end + +module Level : sig + type t = private { + level : Raw_level.t; + level_position : int32; + cycle : Cycle.t; + cycle_position : int32; + expected_commitment : bool; + } + + include BASIC_DATA with type t := t + + val pp_full : Format.formatter -> t -> unit + + type level = t + + val root : context -> level + + val succ : context -> level -> level + + val pred : context -> level -> level option + + val from_raw : context -> Raw_level.t -> level + + (** Fails with [Negative_level_and_offset_sum] if the sum of the raw_level and the offset is negative. *) + val from_raw_with_offset : + context -> offset:int32 -> Raw_level.t -> level tzresult + + (** [add c level i] i must be positive *) + val add : context -> level -> int -> level + + (** [sub c level i] i must be positive *) + val sub : context -> level -> int -> level option + + val diff : level -> level -> int32 + + val current : context -> level + + val last_level_in_cycle : context -> Cycle.t -> level + + val levels_in_cycle : context -> Cycle.t -> level list + + val levels_in_current_cycle : context -> ?offset:int32 -> unit -> level list + + val last_allowed_fork_level : context -> Raw_level.t + + val dawn_of_a_new_cycle : context -> Cycle.t option + + val may_snapshot_rolls : context -> bool +end + +module Fitness : sig + type error += Invalid_fitness | Wrong_fitness | Outdated_fitness + + type raw = Fitness.t + + type t + + val encoding : t Data_encoding.t + + val pp : Format.formatter -> t -> unit + + val create : + level:Raw_level.t -> + locked_round:Round.t option -> + predecessor_round:Round.t -> + round:Round.t -> + t tzresult + + val create_without_locked_round : + level:Raw_level.t -> predecessor_round:Round.t -> round:Round.t -> t + + val to_raw : t -> raw + + val from_raw : raw -> t tzresult + + val round_from_raw : raw -> Round.t tzresult + + val predecessor_round_from_raw : raw -> Round.t tzresult + + val level : t -> Raw_level.t + + val round : t -> Round.t + + val locked_round : t -> Round.t option + + val predecessor_round : t -> Round.t +end + +module Nonce : sig + type t + + type nonce = t + + val encoding : nonce Data_encoding.t + + type unrevealed = {nonce_hash : Nonce_hash.t; delegate : public_key_hash} + + val record_hash : context -> unrevealed -> context tzresult Lwt.t + + val reveal : context -> Level.t -> nonce -> context tzresult Lwt.t + + type status = Unrevealed of unrevealed | Revealed of nonce + + val get : context -> Level.t -> status tzresult Lwt.t + + val of_bytes : bytes -> nonce tzresult + + val hash : nonce -> Nonce_hash.t + + val check_hash : nonce -> Nonce_hash.t -> bool +end + +module Seed : sig + type seed + + type error += Unknown of {oldest : Cycle.t; cycle : Cycle.t; latest : Cycle.t} + + val for_cycle : context -> Cycle.t -> seed tzresult Lwt.t + + val cycle_end : + context -> Cycle.t -> (context * Nonce.unrevealed list) tzresult Lwt.t + + val seed_encoding : seed Data_encoding.t +end + +module Big_map : sig + module Id : sig + type t + + val encoding : t Data_encoding.t + + val rpc_arg : t RPC_arg.arg + + (** In the protocol, to be used in parse_data only *) + val parse_z : Z.t -> t + + (** In the protocol, to be used in unparse_data only *) + val unparse_to_z : t -> Z.t + end + + val fresh : temporary:bool -> context -> (context * Id.t) tzresult Lwt.t + + val mem : + context -> Id.t -> Script_expr_hash.t -> (context * bool) tzresult Lwt.t + + val get_opt : + context -> + Id.t -> + Script_expr_hash.t -> + (context * Script.expr option) tzresult Lwt.t + + val exists : + context -> + Id.t -> + (context * (Script.expr * Script.expr) option) tzresult Lwt.t + + (** [list_values ?offset ?length ctxt id] lists all values stored in big map [id]. + + The first [offset] values are ignored (if passed). Negative offsets are treated as [0]. + + There will be no more than [length] values in the result list (if passed). + Negative values are treated as [0]. + + The returned {!context} takes into account gas consumption of loading values. + *) + val list_values : + ?offset:int -> + ?length:int -> + context -> + Id.t -> + (context * Script.expr list) tzresult Lwt.t + + type update = { + key : Script_repr.expr; + key_hash : Script_expr_hash.t; + value : Script_repr.expr option; + } + + type updates = update list + + type alloc = {key_type : Script_repr.expr; value_type : Script_repr.expr} +end + +module Sapling : sig + module Id : sig + type t + + val encoding : t Data_encoding.t + + val rpc_arg : t RPC_arg.arg + + val parse_z : Z.t -> t (* To be used in parse_data only *) + + val unparse_to_z : t -> Z.t (* To be used in unparse_data only *) + end + + val fresh : temporary:bool -> context -> (context * Id.t) tzresult Lwt.t + + type diff = private { + commitments_and_ciphertexts : + (Sapling.Commitment.t * Sapling.Ciphertext.t) list; + nullifiers : Sapling.Nullifier.t list; + } + + val diff_encoding : diff Data_encoding.t + + module Memo_size : sig + type t + + val encoding : t Data_encoding.t + + val equal : t -> t -> bool + + val parse_z : Z.t -> (t, string) result + + val unparse_to_z : t -> Z.t + end + + type state = private {id : Id.t option; diff : diff; memo_size : Memo_size.t} + + (** + Returns a [state] with fields filled accordingly. + [id] should only be used by [extract_lazy_storage_updates]. + *) + val empty_state : ?id:Id.t -> memo_size:Memo_size.t -> unit -> state + + type transaction = Sapling.UTXO.transaction + + val transaction_encoding : transaction Data_encoding.t + + val transaction_get_memo_size : transaction -> Memo_size.t option + + (** + Tries to fetch a state from the storage. + *) + val state_from_id : context -> Id.t -> (state * context) tzresult Lwt.t + + val rpc_arg : Id.t RPC_arg.t + + type root = Sapling.Hash.t + + val root_encoding : root Data_encoding.t + + (* Function exposed as RPC. Returns the root and a diff of a state starting + from an optional offset which is zero by default. *) + val get_diff : + context -> + Id.t -> + ?offset_commitment:Int64.t -> + ?offset_nullifier:Int64.t -> + unit -> + (root * diff) tzresult Lwt.t + + val verify_update : + context -> + state -> + transaction -> + string -> + (context * (Int64.t * state) option) tzresult Lwt.t + + type alloc = {memo_size : Memo_size.t} + + type updates = diff + + val transaction_in_memory_size : transaction -> Cache_memory_helpers.sint + + val diff_in_memory_size : diff -> Cache_memory_helpers.sint +end + +module Lazy_storage : sig + module Kind : sig + type ('id, 'alloc, 'updates) t = + | Big_map : (Big_map.Id.t, Big_map.alloc, Big_map.updates) t + | Sapling_state : (Sapling.Id.t, Sapling.alloc, Sapling.updates) t + end + + module IdSet : sig + type t + + type 'acc fold_f = {f : 'i 'a 'u. ('i, 'a, 'u) Kind.t -> 'i -> 'acc -> 'acc} + + val empty : t + + val mem : ('i, 'a, 'u) Kind.t -> 'i -> t -> bool + + val add : ('i, 'a, 'u) Kind.t -> 'i -> t -> t + + val diff : t -> t -> t + + val fold : ('i, 'a, 'u) Kind.t -> ('i -> 'acc -> 'acc) -> t -> 'acc -> 'acc + + val fold_all : 'acc fold_f -> t -> 'acc -> 'acc + end + + type ('id, 'alloc) init = Existing | Copy of {src : 'id} | Alloc of 'alloc + + type ('id, 'alloc, 'updates) diff = + | Remove + | Update of {init : ('id, 'alloc) init; updates : 'updates} + + type diffs_item + + val make : ('i, 'a, 'u) Kind.t -> 'i -> ('i, 'a, 'u) diff -> diffs_item + + type diffs = diffs_item list + + val encoding : diffs Data_encoding.t + + val diffs_in_memory_size : diffs -> Cache_memory_helpers.nodes_and_size + + val legacy_big_map_diff_encoding : diffs Data_encoding.t + + val cleanup_temporaries : context -> context Lwt.t + + val apply : t -> diffs -> (t * Z.t) tzresult Lwt.t +end + +module Contract : sig + include BASIC_DATA + + type contract = t + + val in_memory_size : t -> Cache_memory_helpers.sint + + val rpc_arg : contract RPC_arg.arg + + val to_b58check : contract -> string + + val of_b58check : string -> contract tzresult + + val implicit_contract : public_key_hash -> contract + + val is_implicit : contract -> public_key_hash option + + val exists : context -> contract -> bool tzresult Lwt.t + + val must_exist : context -> contract -> unit tzresult Lwt.t + + val allocated : context -> contract -> bool tzresult Lwt.t + + val must_be_allocated : context -> contract -> unit tzresult Lwt.t + + val list : context -> contract list Lwt.t + + val get_manager_key : + ?error:error -> context -> public_key_hash -> public_key tzresult Lwt.t + + val is_manager_key_revealed : + context -> public_key_hash -> bool tzresult Lwt.t + + val reveal_manager_key : + context -> public_key_hash -> public_key -> context tzresult Lwt.t + + val get_script_code : + context -> contract -> (context * Script.lazy_expr option) tzresult Lwt.t + + val get_script : + context -> contract -> (context * Script.t option) tzresult Lwt.t + + val get_storage : + context -> contract -> (context * Script.expr option) tzresult Lwt.t + + val get_counter : context -> public_key_hash -> Z.t tzresult Lwt.t + + val get_balance : context -> contract -> Tez.t tzresult Lwt.t + + val get_balance_carbonated : + context -> contract -> (context * Tez.t) tzresult Lwt.t + + val init_origination_nonce : context -> Operation_hash.t -> context + + val unset_origination_nonce : context -> context + + val fresh_contract_from_current_nonce : context -> (context * t) tzresult + + val originated_from_current_nonce : + since:context -> until:context -> contract list tzresult Lwt.t + + module Legacy_big_map_diff : sig + type item = private + | Update of { + big_map : Z.t; + diff_key : Script.expr; + diff_key_hash : Script_expr_hash.t; + diff_value : Script.expr option; + } + | Clear of Z.t + | Copy of {src : Z.t; dst : Z.t} + | Alloc of { + big_map : Z.t; + key_type : Script.expr; + value_type : Script.expr; + } + + type t = private item list + + val of_lazy_storage_diff : Lazy_storage.diffs -> t + end + + type error += Balance_too_low of contract * Tez.t * Tez.t + + val update_script_storage : + context -> + contract -> + Script.expr -> + Lazy_storage.diffs option -> + context tzresult Lwt.t + + val used_storage_space : context -> t -> Z.t tzresult Lwt.t + + val increment_counter : context -> public_key_hash -> context tzresult Lwt.t + + val check_counter_increment : + context -> public_key_hash -> Z.t -> unit tzresult Lwt.t + + (**/**) + + (* Only for testing *) + type origination_nonce + + val initial_origination_nonce : Operation_hash.t -> origination_nonce + + val originated_contract : origination_nonce -> contract + + val raw_originate : + context -> + prepaid_bootstrap_storage:bool -> + t -> + script:Script.t * Lazy_storage.diffs option -> + context tzresult Lwt.t +end + +module Receipt : sig + type balance = + | Contract of Contract.t + | Legacy_rewards of Signature.Public_key_hash.t * Cycle.t + | Block_fees + | Legacy_deposits of Signature.Public_key_hash.t * Cycle.t + | Deposits of public_key_hash + | Nonce_revelation_rewards + | Double_signing_evidence_rewards + | Endorsing_rewards + | Baking_rewards + | Baking_bonuses + | Legacy_fees of Signature.Public_key_hash.t * Cycle.t + | Storage_fees + | Double_signing_punishments + | Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool + | Liquidity_baking_subsidies + | Burned + | Commitments of Blinded_public_key_hash.t + | Bootstrap + | Invoice + | Initial_commitments + | Minted + + val compare_balance : balance -> balance -> int + + type balance_update = Debited of Tez.t | Credited of Tez.t + + type update_origin = + | Block_application + | Protocol_migration + | Subsidy + | Simulation + + val compare_update_origin : update_origin -> update_origin -> int + + type balance_updates = (balance * balance_update * update_origin) list + + val balance_updates_encoding : balance_updates Data_encoding.t + + val group_balance_updates : balance_updates -> balance_updates tzresult +end + +module Delegate : sig + val init : + context -> + Contract.t -> + Signature.Public_key_hash.t -> + context tzresult Lwt.t + + val find : context -> Contract.t -> public_key_hash option tzresult Lwt.t + + val set : + context -> Contract.t -> public_key_hash option -> context tzresult Lwt.t + + val frozen_deposits_limit : + context -> Signature.Public_key_hash.t -> Tez.t option tzresult Lwt.t + + val set_frozen_deposits_limit : + context -> Signature.Public_key_hash.t -> Tez.t option -> context Lwt.t + + val fold : + context -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(public_key_hash -> 'a -> 'a Lwt.t) -> + 'a Lwt.t + + val list : context -> public_key_hash list Lwt.t + + val check_delegate : context -> public_key_hash -> unit tzresult Lwt.t + + type participation_info = { + expected_cycle_activity : int; + minimal_cycle_activity : int; + missed_slots : int; + missed_levels : int; + remaining_allowed_missed_slots : int; + expected_endorsing_rewards : Tez.t; + } + + val delegate_participation_info : + context -> public_key_hash -> participation_info tzresult Lwt.t + + val cycle_end : + context -> + Cycle.t -> + Nonce.unrevealed list -> + (context * Receipt.balance_updates * Signature.Public_key_hash.t list) + tzresult + Lwt.t + + val already_slashed_for_double_endorsing : + context -> public_key_hash -> Level.t -> bool tzresult Lwt.t + + val already_slashed_for_double_baking : + context -> public_key_hash -> Level.t -> bool tzresult Lwt.t + + val punish_double_endorsing : + context -> + public_key_hash -> + Level.t -> + (context * Tez.t * Receipt.balance_updates) tzresult Lwt.t + + val punish_double_baking : + context -> + public_key_hash -> + Level.t -> + (context * Tez.t * Receipt.balance_updates) tzresult Lwt.t + + val full_balance : context -> public_key_hash -> Tez.t tzresult Lwt.t + + type level_participation = Participated | Didn't_participate + + val record_baking_activity_and_pay_rewards_and_fees : + context -> + payload_producer:Signature.Public_key_hash.t -> + block_producer:Signature.Public_key_hash.t -> + baking_reward:Tez.t -> + reward_bonus:Tez.t option -> + (context * Receipt.balance_updates) tzresult Lwt.t + + val record_endorsing_participation : + context -> + delegate:Signature.Public_key_hash.t -> + participation:level_participation -> + endorsing_power:int -> + context tzresult Lwt.t + + type deposits = {initial_amount : Tez.t; current_amount : Tez.t} + + val frozen_deposits : context -> public_key_hash -> deposits tzresult Lwt.t + + val staking_balance : + context -> Signature.Public_key_hash.t -> Tez.t tzresult Lwt.t + + val delegated_contracts : + context -> Signature.Public_key_hash.t -> Contract.t list Lwt.t + + val delegated_balance : + context -> Signature.Public_key_hash.t -> Tez.t tzresult Lwt.t + + val registered : context -> Signature.Public_key_hash.t -> bool tzresult Lwt.t + + val deactivated : + context -> Signature.Public_key_hash.t -> bool tzresult Lwt.t + + val grace_period : + context -> Signature.Public_key_hash.t -> Cycle.t tzresult Lwt.t + + val pubkey : context -> public_key_hash -> public_key tzresult Lwt.t + + val prepare_stake_distribution : context -> context tzresult Lwt.t +end + +module Voting_period : sig + type kind = Proposal | Exploration | Cooldown | Promotion | Adoption + + val kind_encoding : kind Data_encoding.encoding + + val pp_kind : Format.formatter -> kind -> unit + + (* This type should be abstract *) + type voting_period = private { + index : int32; + kind : kind; + start_position : int32; + } + + type t = voting_period + + include BASIC_DATA with type t := t + + val encoding : voting_period Data_encoding.t + + val pp : Format.formatter -> voting_period -> unit + + val reset : context -> context tzresult Lwt.t + + val succ : context -> context tzresult Lwt.t + + val get_current : context -> voting_period tzresult Lwt.t + + val get_current_kind : context -> kind tzresult Lwt.t + + val is_last_block : context -> bool tzresult Lwt.t + + type info = {voting_period : t; position : int32; remaining : int32} + + val info_encoding : info Data_encoding.t + + val pp_info : Format.formatter -> info -> unit + + val get_rpc_current_info : context -> info tzresult Lwt.t + + val get_rpc_succ_info : context -> info tzresult Lwt.t +end + +module Vote : sig + type proposal = Protocol_hash.t + + val record_proposal : + context -> Protocol_hash.t -> public_key_hash -> context tzresult Lwt.t + + val get_proposals : context -> int32 Protocol_hash.Map.t tzresult Lwt.t + + val clear_proposals : context -> context Lwt.t + + val recorded_proposal_count_for_delegate : + context -> public_key_hash -> int tzresult Lwt.t + + val listings_encoding : + (Signature.Public_key_hash.t * int32) list Data_encoding.t + + val update_listings : context -> context tzresult Lwt.t + + val listing_size : context -> int32 tzresult Lwt.t + + val in_listings : context -> public_key_hash -> bool Lwt.t + + val get_listings : context -> (public_key_hash * int32) list Lwt.t + + type ballot = Yay | Nay | Pass + + val get_voting_power_free : + context -> Signature.Public_key_hash.t -> int32 tzresult Lwt.t + + val get_voting_power : + context -> Signature.Public_key_hash.t -> (context * int32) tzresult Lwt.t + + val get_total_voting_power_free : context -> int32 tzresult Lwt.t + + val get_total_voting_power : context -> (context * int32) tzresult Lwt.t + + val ballot_encoding : ballot Data_encoding.t + + type ballots = {yay : int32; nay : int32; pass : int32} + + val ballots_encoding : ballots Data_encoding.t + + val has_recorded_ballot : context -> public_key_hash -> bool Lwt.t + + val record_ballot : + context -> public_key_hash -> ballot -> context tzresult Lwt.t + + val get_ballots : context -> ballots tzresult Lwt.t + + val get_ballot_list : + context -> (Signature.Public_key_hash.t * ballot) list Lwt.t + + val clear_ballots : context -> context Lwt.t + + val get_current_quorum : context -> int32 tzresult Lwt.t + + val get_participation_ema : context -> int32 tzresult Lwt.t + + val set_participation_ema : context -> int32 -> context tzresult Lwt.t + + val get_current_proposal : context -> proposal tzresult Lwt.t + + val find_current_proposal : context -> proposal option tzresult Lwt.t + + val init_current_proposal : context -> proposal -> context tzresult Lwt.t + + val clear_current_proposal : context -> context tzresult Lwt.t +end + +module Block_payload : sig + val hash : + predecessor:Block_hash.t -> + Round.t -> + Operation_list_hash.t -> + Block_payload_hash.t +end + +module Block_header : sig + type contents = { + payload_hash : Block_payload_hash.t; + payload_round : Round.t; + seed_nonce_hash : Nonce_hash.t option; + proof_of_work_nonce : bytes; + liquidity_baking_escape_vote : bool; + } + + type protocol_data = {contents : contents; signature : Signature.t} + + type t = {shell : Block_header.shell_header; protocol_data : protocol_data} + + type block_header = t + + type raw = Block_header.t + + type shell_header = Block_header.shell_header + + type block_watermark = Block_header of Chain_id.t + + val to_watermark : block_watermark -> Signature.watermark + + val of_watermark : Signature.watermark -> block_watermark option + + module Proof_of_work : sig + val check_hash : Block_hash.t -> int64 -> bool + + val check_header_proof_of_work_stamp : + shell_header -> contents -> int64 -> bool + + val check_proof_of_work_stamp : + proof_of_work_threshold:int64 -> block_header -> unit tzresult + end + + val raw : block_header -> raw + + val hash : block_header -> Block_hash.t + + val hash_raw : raw -> Block_hash.t + + val encoding : block_header Data_encoding.encoding + + val raw_encoding : raw Data_encoding.t + + val contents_encoding : contents Data_encoding.t + + val unsigned_encoding : (shell_header * contents) Data_encoding.t + + val protocol_data_encoding : protocol_data Data_encoding.encoding + + val shell_header_encoding : shell_header Data_encoding.encoding + + (** The maximum size of block headers in bytes *) + val max_header_length : int + + type error += + | Invalid_block_signature of Block_hash.t * Signature.Public_key_hash.t + | Invalid_stamp + | Invalid_payload_hash of { + expected : Block_payload_hash.t; + provided : Block_payload_hash.t; + } + | Locked_round_after_block_round of { + locked_round : Round_repr.t; + round : Round_repr.t; + } + | Invalid_payload_round of { + payload_round : Round_repr.t; + round : Round_repr.t; + } + | Insufficient_locked_round_evidence of { + voting_power : int; + consensus_threshold : int; + } + | Invalid_commitment of {expected : bool} + + val check_timestamp : + Round.round_durations -> + timestamp:Time.t -> + round:Round.t -> + predecessor_timestamp:Time.t -> + predecessor_round:Round.t -> + unit tzresult + + val check_signature : + t -> Chain_id.t -> Signature.Public_key.t -> unit tzresult + + val begin_validate_block_header : + block_header:t -> + chain_id:Chain_id.t -> + predecessor_timestamp:Time.t -> + predecessor_round:Round.t -> + fitness:Fitness.t -> + timestamp:Time.t -> + delegate_pk:Signature.public_key -> + round_durations:Round.round_durations -> + proof_of_work_threshold:int64 -> + expected_commitment:bool -> + unit tzresult + + type locked_round_evidence = { + preendorsement_round : Round.t; + preendorsement_count : int; + } + + type checkable_payload_hash = + | No_check + | Expected_payload_hash of Block_payload_hash.t + + val finalize_validate_block_header : + block_header_contents:contents -> + round:Round.t -> + fitness:Fitness.t -> + checkable_payload_hash:checkable_payload_hash -> + locked_round_evidence:locked_round_evidence option -> + consensus_threshold:int -> + unit tzresult +end + +module Kind : sig + type preendorsement_consensus_kind = Preendorsement_consensus_kind + + type endorsement_consensus_kind = Endorsement_consensus_kind + + type 'a consensus = + | Preendorsement_kind : preendorsement_consensus_kind consensus + | Endorsement_kind : endorsement_consensus_kind consensus + + type preendorsement = preendorsement_consensus_kind consensus + + type endorsement = endorsement_consensus_kind consensus + + type seed_nonce_revelation = Seed_nonce_revelation_kind + + type 'a double_consensus_operation_evidence = + | Double_consensus_operation_evidence + + type double_endorsement_evidence = + endorsement_consensus_kind double_consensus_operation_evidence + + type double_preendorsement_evidence = + preendorsement_consensus_kind double_consensus_operation_evidence + + type double_baking_evidence = Double_baking_evidence_kind + + type activate_account = Activate_account_kind + + type proposals = Proposals_kind + + type ballot = Ballot_kind + + type reveal = Reveal_kind + + type transaction = Transaction_kind + + type origination = Origination_kind + + type delegation = Delegation_kind + + type set_deposits_limit = Set_deposits_limit_kind + + type failing_noop = Failing_noop_kind + + type register_global_constant = Register_global_constant_kind + + type 'a manager = + | Reveal_manager_kind : reveal manager + | Transaction_manager_kind : transaction manager + | Origination_manager_kind : origination manager + | Delegation_manager_kind : delegation manager + | Register_global_constant_manager_kind : register_global_constant manager + | Set_deposits_limit_manager_kind : set_deposits_limit manager +end + +type 'a consensus_operation_type = + | Endorsement : Kind.endorsement consensus_operation_type + | Preendorsement : Kind.preendorsement consensus_operation_type + +val pp_operation_kind : + Format.formatter -> 'kind consensus_operation_type -> unit + +type consensus_content = { + slot : Slot.t; + level : Raw_level.t; + (* The level is not required to validate an endorsement when it corresponds + to the current payload, but if we want to filter endorsements, we need + the level. *) + round : Round.t; + block_payload_hash : Block_payload_hash.t; +} + +val consensus_content_encoding : consensus_content Data_encoding.t + +val pp_consensus_content : Format.formatter -> consensus_content -> unit + +type 'kind operation = { + shell : Operation.shell_header; + protocol_data : 'kind protocol_data; +} + +and 'kind protocol_data = { + contents : 'kind contents_list; + signature : Signature.t option; +} + +and _ contents_list = + | Single : 'kind contents -> 'kind contents_list + | Cons : + 'kind Kind.manager contents * 'rest Kind.manager contents_list + -> ('kind * 'rest) Kind.manager contents_list + +and _ contents = + | Preendorsement : consensus_content -> Kind.preendorsement contents + | Endorsement : consensus_content -> Kind.endorsement contents + | Seed_nonce_revelation : { + level : Raw_level.t; + nonce : Nonce.t; + } + -> Kind.seed_nonce_revelation contents + | Double_preendorsement_evidence : { + op1 : Kind.preendorsement operation; + op2 : Kind.preendorsement operation; + } + -> Kind.double_preendorsement_evidence contents + | Double_endorsement_evidence : { + op1 : Kind.endorsement operation; + op2 : Kind.endorsement operation; + } + -> Kind.double_endorsement_evidence contents + | Double_baking_evidence : { + bh1 : Block_header.t; + bh2 : Block_header.t; + } + -> Kind.double_baking_evidence contents + | Activate_account : { + id : Ed25519.Public_key_hash.t; + activation_code : Blinded_public_key_hash.activation_code; + } + -> Kind.activate_account contents + | Proposals : { + source : Signature.Public_key_hash.t; + period : int32; + proposals : Protocol_hash.t list; + } + -> Kind.proposals contents + | Ballot : { + source : Signature.Public_key_hash.t; + period : int32; + proposal : Protocol_hash.t; + ballot : Vote.ballot; + } + -> Kind.ballot contents + | Failing_noop : string -> Kind.failing_noop contents + | Manager_operation : { + source : Signature.Public_key_hash.t; + fee : Tez.tez; + counter : counter; + operation : 'kind manager_operation; + gas_limit : Gas.Arith.integral; + storage_limit : Z.t; + } + -> 'kind Kind.manager contents + +and _ manager_operation = + | Reveal : Signature.Public_key.t -> Kind.reveal manager_operation + | Transaction : { + amount : Tez.tez; + parameters : Script.lazy_expr; + entrypoint : string; + destination : Contract.contract; + } + -> Kind.transaction manager_operation + | Origination : { + delegate : Signature.Public_key_hash.t option; + script : Script.t; + credit : Tez.tez; + preorigination : Contract.t option; + } + -> Kind.origination manager_operation + | Delegation : + Signature.Public_key_hash.t option + -> Kind.delegation manager_operation + | Register_global_constant : { + value : Script.lazy_expr; + } + -> Kind.register_global_constant manager_operation + | Set_deposits_limit : + Tez.t option + -> Kind.set_deposits_limit manager_operation + +and counter = Z.t + +type 'kind internal_operation = { + source : Contract.contract; + operation : 'kind manager_operation; + nonce : int; +} + +type packed_manager_operation = + | Manager : 'kind manager_operation -> packed_manager_operation + +type packed_contents = Contents : 'kind contents -> packed_contents + +type packed_contents_list = + | Contents_list : 'kind contents_list -> packed_contents_list + +type packed_protocol_data = + | Operation_data : 'kind protocol_data -> packed_protocol_data + +type packed_operation = { + shell : Operation.shell_header; + protocol_data : packed_protocol_data; +} + +type packed_internal_operation = + | Internal_operation : 'kind internal_operation -> packed_internal_operation + +val manager_kind : 'kind manager_operation -> 'kind Kind.manager + +module Operation : sig + type nonrec 'kind contents = 'kind contents + + type nonrec packed_contents = packed_contents + + val contents_encoding : packed_contents Data_encoding.t + + type nonrec 'kind protocol_data = 'kind protocol_data + + type nonrec packed_protocol_data = packed_protocol_data + + type consensus_watermark = + | Endorsement of Chain_id.t + | Preendorsement of Chain_id.t + + val to_watermark : consensus_watermark -> Signature.watermark + + val of_watermark : Signature.watermark -> consensus_watermark option + + val protocol_data_encoding : packed_protocol_data Data_encoding.t + + val unsigned_encoding : + (Operation.shell_header * packed_contents_list) Data_encoding.t + + type raw = Operation.t = {shell : Operation.shell_header; proto : bytes} + + val raw_encoding : raw Data_encoding.t + + val contents_list_encoding : packed_contents_list Data_encoding.t + + type 'kind t = 'kind operation = { + shell : Operation.shell_header; + protocol_data : 'kind protocol_data; + } + + type nonrec packed = packed_operation + + val encoding : packed Data_encoding.t + + val raw : _ operation -> raw + + val hash : _ operation -> Operation_hash.t + + val hash_raw : raw -> Operation_hash.t + + val hash_packed : packed_operation -> Operation_hash.t + + val acceptable_passes : packed_operation -> int list + + type error += Missing_signature (* `Permanent *) + + type error += Invalid_signature (* `Permanent *) + + val check_signature : public_key -> Chain_id.t -> _ operation -> unit tzresult + + val internal_operation_encoding : packed_internal_operation Data_encoding.t + + val packed_internal_operation_in_memory_size : + packed_internal_operation -> Cache_memory_helpers.nodes_and_size + + val pack : 'kind operation -> packed_operation + + type ('a, 'b) eq = Eq : ('a, 'a) eq + + val equal : 'a operation -> 'b operation -> ('a, 'b) eq option + + module Encoding : sig + type 'b case = + | Case : { + tag : int; + name : string; + encoding : 'a Data_encoding.t; + select : packed_contents -> 'b contents option; + proj : 'b contents -> 'a; + inj : 'a -> 'b contents; + } + -> 'b case + + val preendorsement_case : Kind.preendorsement case + + val endorsement_case : Kind.endorsement case + + val seed_nonce_revelation_case : Kind.seed_nonce_revelation case + + val double_preendorsement_evidence_case : + Kind.double_preendorsement_evidence case + + val double_endorsement_evidence_case : Kind.double_endorsement_evidence case + + val double_baking_evidence_case : Kind.double_baking_evidence case + + val activate_account_case : Kind.activate_account case + + val proposals_case : Kind.proposals case + + val ballot_case : Kind.ballot case + + val failing_noop_case : Kind.failing_noop case + + val reveal_case : Kind.reveal Kind.manager case + + val transaction_case : Kind.transaction Kind.manager case + + val origination_case : Kind.origination Kind.manager case + + val delegation_case : Kind.delegation Kind.manager case + + val register_global_constant_case : + Kind.register_global_constant Kind.manager case + + val set_deposits_limit_case : Kind.set_deposits_limit Kind.manager case + + module Manager_operations : sig + type 'b case = + | MCase : { + tag : int; + name : string; + encoding : 'a Data_encoding.t; + select : packed_manager_operation -> 'kind manager_operation option; + proj : 'kind manager_operation -> 'a; + inj : 'a -> 'kind manager_operation; + } + -> 'kind case + + val reveal_case : Kind.reveal case + + val transaction_case : Kind.transaction case + + val origination_case : Kind.origination case + + val delegation_case : Kind.delegation case + + val register_global_constant_case : Kind.register_global_constant case + + val set_deposits_limit_case : Kind.set_deposits_limit case + end + end + + val of_list : packed_contents list -> packed_contents_list tzresult + + val to_list : packed_contents_list -> packed_contents list +end + +module Stake_distribution : sig + val snapshot : context -> context tzresult Lwt.t + + val baking_rights_owner : + context -> + Level.t -> + round:Round.t -> + (context * Slot.t * (public_key * public_key_hash)) tzresult Lwt.t + + val slot_owner : + context -> + Level.t -> + Slot.t -> + (context * (public_key * public_key_hash)) tzresult Lwt.t + + val delegate_pubkey : context -> public_key_hash -> public_key tzresult Lwt.t + + val get_staking_balance : + context -> Signature.Public_key_hash.t -> Tez.t tzresult Lwt.t +end + +module Commitment : sig + type t = { + blinded_public_key_hash : Blinded_public_key_hash.t; + amount : Tez.tez; + } + + val encoding : t Data_encoding.t +end + +module Bootstrap : sig + val cycle_end : context -> Cycle.t -> context tzresult Lwt.t +end + +module Migration : sig + type origination_result = { + balance_updates : Receipt.balance_updates; + originated_contracts : Contract.t list; + storage_size : Z.t; + paid_storage_size_diff : Z.t; + } +end + +(** Create an [Alpha_context.t] from an untyped context (first block in the chain only). *) +val prepare_first_block : + Context.t -> + typecheck: + (context -> + Script.t -> + ((Script.t * Lazy_storage.diffs option) * context) tzresult Lwt.t) -> + level:Int32.t -> + timestamp:Time.t -> + context tzresult Lwt.t + +(** Create an [Alpha_context.t] from an untyped context. *) +val prepare : + Context.t -> + level:Int32.t -> + predecessor_timestamp:Time.t -> + timestamp:Time.t -> + (context * Receipt.balance_updates * Migration.origination_result list) + tzresult + Lwt.t + +val activate : context -> Protocol_hash.t -> context Lwt.t + +val reset_internal_nonce : context -> context + +val fresh_internal_nonce : context -> (context * int) tzresult + +val record_internal_nonce : context -> int -> context + +val internal_nonce_already_recorded : context -> int -> bool + +val description : context Storage_description.t + +(** Finalize an {{!t} [Alpha_context.t]}, producing a [validation_result]. + *) +val finalize : + ?commit_message:string -> context -> Fitness.raw -> Updater.validation_result + +(** Should only be used by [Main.current_context] to return a context usable for RPCs *) +val current_context : context -> Context.t + +val record_non_consensus_operation_hash : context -> Operation_hash.t -> context + +val non_consensus_operations : context -> Operation_hash.t list + +module Parameters : sig + type bootstrap_account = { + public_key_hash : public_key_hash; + public_key : public_key option; + amount : Tez.t; + } + + type bootstrap_contract = { + delegate : public_key_hash option; + amount : Tez.t; + script : Script.t; + } + + type t = { + bootstrap_accounts : bootstrap_account list; + bootstrap_contracts : bootstrap_contract list; + commitments : Commitment.t list; + constants : Constants.parametric; + security_deposit_ramp_up_cycles : int option; + no_reward_cycles : int option; + } + + val encoding : t Data_encoding.t +end + +module Liquidity_baking : sig + val get_cpmm_address : context -> Contract.t tzresult Lwt.t + + type escape_ema = Int32.t + + val on_subsidy_allowed : + context -> + escape_vote:bool -> + (context -> Contract.t -> (context * 'a list) tzresult Lwt.t) -> + (context * 'a list * escape_ema) tzresult Lwt.t +end + +(** This module re-exports functions from [Ticket_storage]. See + documentation of the functions there. + *) +module Ticket_balance : sig + type key_hash + + val script_expr_hash_of_key_hash : key_hash -> Script_expr_hash.t + + val make_key_hash : + context -> + ticketer:Script.node -> + typ:Script.node -> + contents:Script.node -> + owner:Script.node -> + (key_hash * context) tzresult + + val adjust_balance : + context -> key_hash -> delta:Z.t -> (Z.t * context) tzresult Lwt.t + + val get_balance : context -> key_hash -> (Z.t option * context) tzresult Lwt.t +end + +module First_level_of_tenderbake : sig + val get : context -> Raw_level.t tzresult Lwt.t +end + +module Consensus : sig + include + Raw_context.CONSENSUS + with type t := t + and type slot := Slot.t + and type 'a slot_map := 'a Slot.Map.t + and type slot_set := Slot.Set.t + and type round := Round.t + + val store_endorsement_branch : + context -> Block_hash.t * Block_payload_hash.t -> context Lwt.t + + val store_grand_parent_branch : + context -> Block_hash.t * Block_payload_hash.t -> context Lwt.t +end + +(** See 'token.mli' for more explanation. *) +module Token : sig + type container = + [ `Contract of Contract.t + | `Collected_commitments of Blinded_public_key_hash.t + | `Delegate_balance of Signature.Public_key_hash.t + | `Frozen_deposits of Signature.Public_key_hash.t + | `Block_fees + | `Legacy_deposits of Signature.Public_key_hash.t * Cycle.t + | `Legacy_fees of Signature.Public_key_hash.t * Cycle.t + | `Legacy_rewards of Signature.Public_key_hash.t * Cycle.t ] + + type source = + [ `Invoice + | `Bootstrap + | `Initial_commitments + | `Revelation_rewards + | `Double_signing_evidence_rewards + | `Endorsing_rewards + | `Baking_rewards + | `Baking_bonuses + | `Minted + | `Liquidity_baking_subsidies + | container ] + + type sink = + [ `Storage_fees + | `Double_signing_punishments + | `Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool + | `Burned + | container ] + + val allocated : context -> container -> bool tzresult Lwt.t + + val balance : context -> container -> Tez.t tzresult Lwt.t + + val transfer_n : + ?origin:Receipt.update_origin -> + context -> + ([< source] * Tez.t) list -> + [< sink] -> + (context * Receipt.balance_updates) tzresult Lwt.t + + val transfer : + ?origin:Receipt.update_origin -> + context -> + [< source] -> + [< sink] -> + Tez.t -> + (context * Receipt.balance_updates) tzresult Lwt.t +end + +module Fees : sig + val record_paid_storage_space : + context -> Contract.t -> (context * Z.t * Z.t) tzresult Lwt.t + + val record_global_constant_storage_space : context -> Z.t -> context * Z.t + + val burn_storage_fees : + ?origin:Receipt.update_origin -> + context -> + storage_limit:Z.t -> + payer:Token.source -> + Z.t -> + (context * Z.t * Receipt.balance_updates) tzresult Lwt.t + + val burn_origination_fees : + ?origin:Receipt.update_origin -> + context -> + storage_limit:Z.t -> + payer:Token.source -> + (context * Z.t * Receipt.balance_updates) tzresult Lwt.t + + type error += Cannot_pay_storage_fee (* `Temporary *) + + type error += Operation_quota_exceeded (* `Temporary *) + + type error += Storage_limit_too_high (* `Permanent *) + + val check_storage_limit : context -> storage_limit:Z.t -> unit tzresult +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/alpha_services.ml b/src/proto_012_PsiThaCa/lib_protocol/alpha_services.ml new file mode 100644 index 000000000000..29832657ac27 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/alpha_services.ml @@ -0,0 +1,194 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +let custom_root = RPC_path.open_root + +module Seed = struct + module S = struct + open Data_encoding + + let seed = + RPC_service.post_service + ~description:"Seed of the cycle to which the block belongs." + ~query:RPC_query.empty + ~input:empty + ~output:Seed.seed_encoding + RPC_path.(custom_root / "context" / "seed") + end + + let () = + let open Services_registration in + register0 ~chunked:false S.seed (fun ctxt () () -> + let l = Level.current ctxt in + Seed.for_cycle ctxt l.cycle) + + let get ctxt block = RPC_context.make_call0 S.seed ctxt block () () +end + +module Nonce = struct + type info = Revealed of Nonce.t | Missing of Nonce_hash.t | Forgotten + + let info_encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"Revealed" + (obj1 (req "nonce" Nonce.encoding)) + (function Revealed nonce -> Some nonce | _ -> None) + (fun nonce -> Revealed nonce); + case + (Tag 1) + ~title:"Missing" + (obj1 (req "hash" Nonce_hash.encoding)) + (function Missing nonce -> Some nonce | _ -> None) + (fun nonce -> Missing nonce); + case + (Tag 2) + ~title:"Forgotten" + empty + (function Forgotten -> Some () | _ -> None) + (fun () -> Forgotten); + ] + + module S = struct + let get = + RPC_service.get_service + ~description:"Info about the nonce of a previous block." + ~query:RPC_query.empty + ~output:info_encoding + RPC_path.(custom_root / "context" / "nonces" /: Raw_level.rpc_arg) + end + + let register () = + let open Services_registration in + register1 ~chunked:false S.get (fun ctxt raw_level () () -> + let level = Level.from_raw ctxt raw_level in + Nonce.get ctxt level >|= function + | Ok (Revealed nonce) -> ok (Revealed nonce) + | Ok (Unrevealed {nonce_hash; _}) -> ok (Missing nonce_hash) + | Error _ -> ok Forgotten) + + let get ctxt block level = RPC_context.make_call1 S.get ctxt block level () () +end + +module Contract = Contract_services +module Constants = Constants_services +module Delegate = Delegate_services +module Voting = Voting_services +module Sapling = Sapling_services + +module Liquidity_baking = struct + module S = struct + let get_cpmm_address = + RPC_service.get_service + ~description:"Liquidity baking CPMM address" + ~query:RPC_query.empty + ~output:Alpha_context.Contract.encoding + RPC_path.(custom_root / "context" / "liquidity_baking" / "cpmm_address") + end + + let register () = + let open Services_registration in + register0 ~chunked:false S.get_cpmm_address (fun ctxt () () -> + Alpha_context.Liquidity_baking.get_cpmm_address ctxt) + + let get_cpmm_address ctxt block = + RPC_context.make_call0 S.get_cpmm_address ctxt block () () +end + +module Cache = struct + module S = struct + let cached_contracts = + RPC_service.get_service + ~description:"Return the list of cached contracts" + ~query:RPC_query.empty + ~output: + Data_encoding.(list @@ tup2 Alpha_context.Contract.encoding int31) + RPC_path.(custom_root / "context" / "cache" / "contracts" / "all") + + let contract_cache_size = + RPC_service.get_service + ~description:"Return the size of the contract cache" + ~query:RPC_query.empty + ~output:Data_encoding.int31 + RPC_path.(custom_root / "context" / "cache" / "contracts" / "size") + + let contract_cache_size_limit = + RPC_service.get_service + ~description:"Return the size limit of the contract cache" + ~query:RPC_query.empty + ~output:Data_encoding.int31 + RPC_path.( + custom_root / "context" / "cache" / "contracts" / "size_limit") + + let contract_rank = + RPC_service.post_service + ~description: + "Return the number of cached contracts older than the provided \ + contract" + ~query:RPC_query.empty + ~input:Alpha_context.Contract.encoding + ~output:Data_encoding.(option int31) + RPC_path.(custom_root / "context" / "cache" / "contracts" / "rank") + end + + let register () = + let open Services_registration in + register0 ~chunked:true S.cached_contracts (fun ctxt () () -> + Script_cache.entries ctxt |> Lwt.return) ; + register0 ~chunked:false S.contract_cache_size (fun ctxt () () -> + Script_cache.size ctxt |> return) ; + register0 ~chunked:false S.contract_cache_size_limit (fun ctxt () () -> + Script_cache.size_limit ctxt |> return) ; + register0 ~chunked:false S.contract_rank (fun ctxt () contract -> + Script_cache.contract_rank ctxt contract |> return) + + let cached_contracts ctxt block = + RPC_context.make_call0 S.cached_contracts ctxt block () () + + let contract_cache_size ctxt block = + RPC_context.make_call0 S.contract_cache_size ctxt block () () + + let contract_cache_size_limit ctxt block = + RPC_context.make_call0 S.contract_cache_size_limit ctxt block () () + + let contract_rank ctxt block contract = + RPC_context.make_call0 S.contract_rank ctxt block () contract +end + +let register () = + Contract.register () ; + Constants.register () ; + Delegate.register () ; + Nonce.register () ; + Voting.register () ; + Sapling.register () ; + Liquidity_baking.register () ; + Cache.register () diff --git a/src/proto_012_PsiThaCa/lib_protocol/alpha_services.mli b/src/proto_012_PsiThaCa/lib_protocol/alpha_services.mli new file mode 100644 index 000000000000..b32cb71dfe0a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/alpha_services.mli @@ -0,0 +1,81 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This declares Protocol RPC services. + + Protocol RPC services are read-only, and support querying the state of the + ledger (including information such as existing contracts, delegation, + voting, and so on), at a given block height. + + This is a mostly internal module used from [rpc_services] in [Main]. + *) + +open Alpha_context + +module Seed : sig + val get : 'a #RPC_context.simple -> 'a -> Seed.seed shell_tzresult Lwt.t +end + +module Nonce : sig + type info = Revealed of Nonce.t | Missing of Nonce_hash.t | Forgotten + + val get : + 'a #RPC_context.simple -> 'a -> Raw_level.t -> info shell_tzresult Lwt.t +end + +module Contract = Contract_services +module Constants = Constants_services +module Delegate = Delegate_services +module Voting = Voting_services +module Sapling = Sapling_services + +module Liquidity_baking : sig + val get_cpmm_address : + 'a #RPC_context.simple -> + 'a -> + Alpha_context.Contract.t shell_tzresult Lwt.t +end + +module Cache : sig + val cached_contracts : + 'a #RPC_context.simple -> + 'a -> + (Alpha_context.Contract.t * int) list shell_tzresult Lwt.t + + val contract_cache_size : + 'a #RPC_context.simple -> 'a -> int shell_tzresult Lwt.t + + val contract_cache_size_limit : + 'a #RPC_context.simple -> 'a -> int shell_tzresult Lwt.t + + val contract_rank : + 'a #RPC_context.simple -> + 'a -> + Alpha_context.Contract.t -> + int option shell_tzresult Lwt.t +end + +val register : unit -> unit diff --git a/src/proto_012_PsiThaCa/lib_protocol/amendment.ml b/src/proto_012_PsiThaCa/lib_protocol/amendment.ml new file mode 100644 index 000000000000..ae8b50212a46 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/amendment.ml @@ -0,0 +1,266 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +(** Returns the proposal submitted by the most delegates. + Returns None in case of a tie, if proposal quorum is below required + minimum or if there are no proposals. *) +let select_winning_proposal ctxt = + Vote.get_proposals ctxt >>=? fun proposals -> + let merge proposal vote winners = + match winners with + | None -> Some ([proposal], vote) + | Some (winners, winners_vote) as previous -> + if Compare.Int32.(vote = winners_vote) then + Some (proposal :: winners, winners_vote) + else if Compare.Int32.(vote > winners_vote) then Some ([proposal], vote) + else previous + in + match Protocol_hash.Map.fold merge proposals None with + | Some ([proposal], vote) -> + Vote.listing_size ctxt >>=? fun max_vote -> + let min_proposal_quorum = Constants.min_proposal_quorum ctxt in + let min_vote_to_pass = + Int32.div (Int32.mul min_proposal_quorum max_vote) 100_00l + in + if Compare.Int32.(vote >= min_vote_to_pass) then return_some proposal + else return_none + | _ -> return_none + +(* in case of a tie, let's do nothing. *) + +(** A proposal is approved if it has supermajority and the participation reaches + the current quorum. + Supermajority means the yays are more 8/10 of casted votes. + The participation is the ratio of all received votes, including passes, with + respect to the number of possible votes. + The participation EMA (exponential moving average) uses the last + participation EMA and the current participation./ + The expected quorum is calculated using the last participation EMA, capped + by the min/max quorum protocol constants. *) +let approval_and_participation_ema (ballots : Vote.ballots) ~maximum_vote + ~participation_ema ~expected_quorum = + (* Note overflows: considering a maximum of 8e8 tokens, with roll size as + small as 1e3, there is a maximum of 8e5 rolls and thus votes. + In 'participation' an Int64 is used because in the worst case 'all_votes is + 8e5 and after the multiplication is 8e9, making it potentially overflow a + signed Int32 which is 2e9. *) + let casted_votes = Int32.add ballots.yay ballots.nay in + let all_votes = Int32.add casted_votes ballots.pass in + let supermajority = Int32.div (Int32.mul 8l casted_votes) 10l in + let participation = + (* in centile of percentage *) + Int64.( + to_int32 (div (mul (of_int32 all_votes) 100_00L) (of_int32 maximum_vote))) + in + let approval = + Compare.Int32.( + participation >= expected_quorum && ballots.yay >= supermajority) + in + let new_participation_ema = + Int32.(div (add (mul 8l participation_ema) (mul 2l participation)) 10l) + in + (approval, new_participation_ema) + +let get_approval_and_update_participation_ema ctxt = + Vote.get_ballots ctxt >>=? fun ballots -> + Vote.listing_size ctxt >>=? fun maximum_vote -> + Vote.get_participation_ema ctxt >>=? fun participation_ema -> + Vote.get_current_quorum ctxt >>=? fun expected_quorum -> + Vote.clear_ballots ctxt >>= fun ctxt -> + let (approval, new_participation_ema) = + approval_and_participation_ema + ballots + ~maximum_vote + ~participation_ema + ~expected_quorum + in + Vote.set_participation_ema ctxt new_participation_ema >|=? fun ctxt -> + (ctxt, approval) + +(** Implements the state machine of the amendment procedure. Note that + [update_listings], that computes the vote weight of each delegate, is run at + the end of each voting period. This state-machine prepare the voting_period + for the next block. *) +let start_new_voting_period ctxt = + Voting_period.get_current_kind ctxt >>=? fun kind -> + (match kind with + | Proposal -> ( + select_winning_proposal ctxt >>=? fun proposal -> + Vote.clear_proposals ctxt >>= fun ctxt -> + match proposal with + | None -> Voting_period.reset ctxt + | Some proposal -> + Vote.init_current_proposal ctxt proposal >>=? Voting_period.succ) + | Exploration -> + get_approval_and_update_participation_ema ctxt + >>=? fun (ctxt, approved) -> + if approved then Voting_period.succ ctxt + else + Vote.clear_current_proposal ctxt >>=? fun ctxt -> + Voting_period.reset ctxt + | Cooldown -> Voting_period.succ ctxt + | Promotion -> + get_approval_and_update_participation_ema ctxt + >>=? fun (ctxt, approved) -> + if approved then Voting_period.succ ctxt + else Vote.clear_current_proposal ctxt >>=? Voting_period.reset + | Adoption -> + Vote.get_current_proposal ctxt >>=? fun proposal -> + activate ctxt proposal >>= fun ctxt -> + Vote.clear_current_proposal ctxt >>=? Voting_period.reset) + >>=? fun ctxt -> Vote.update_listings ctxt + +type error += + | (* `Branch *) + Invalid_proposal + | Unexpected_proposal + | Unauthorized_proposal + | Too_many_proposals + | Empty_proposal + | Unexpected_ballot + | Unauthorized_ballot + +let () = + let open Data_encoding in + (* Invalid proposal *) + register_error_kind + `Branch + ~id:"invalid_proposal" + ~title:"Invalid proposal" + ~description:"Ballot provided for a proposal that is not the current one." + ~pp:(fun ppf () -> Format.fprintf ppf "Invalid proposal") + empty + (function Invalid_proposal -> Some () | _ -> None) + (fun () -> Invalid_proposal) ; + (* Unexpected proposal *) + register_error_kind + `Branch + ~id:"unexpected_proposal" + ~title:"Unexpected proposal" + ~description:"Proposal recorded outside of a proposal period." + ~pp:(fun ppf () -> Format.fprintf ppf "Unexpected proposal") + empty + (function Unexpected_proposal -> Some () | _ -> None) + (fun () -> Unexpected_proposal) ; + (* Unauthorized proposal *) + register_error_kind + `Branch + ~id:"unauthorized_proposal" + ~title:"Unauthorized proposal" + ~description: + "The delegate provided for the proposal is not in the voting listings." + ~pp:(fun ppf () -> Format.fprintf ppf "Unauthorized proposal") + empty + (function Unauthorized_proposal -> Some () | _ -> None) + (fun () -> Unauthorized_proposal) ; + (* Unexpected ballot *) + register_error_kind + `Branch + ~id:"unexpected_ballot" + ~title:"Unexpected ballot" + ~description:"Ballot recorded outside of a voting period." + ~pp:(fun ppf () -> Format.fprintf ppf "Unexpected ballot") + empty + (function Unexpected_ballot -> Some () | _ -> None) + (fun () -> Unexpected_ballot) ; + (* Unauthorized ballot *) + register_error_kind + `Branch + ~id:"unauthorized_ballot" + ~title:"Unauthorized ballot" + ~description: + "The delegate provided for the ballot is not in the voting listings." + ~pp:(fun ppf () -> Format.fprintf ppf "Unauthorized ballot") + empty + (function Unauthorized_ballot -> Some () | _ -> None) + (fun () -> Unauthorized_ballot) ; + (* Too many proposals *) + register_error_kind + `Branch + ~id:"too_many_proposals" + ~title:"Too many proposals" + ~description:"The delegate reached the maximum number of allowed proposals." + ~pp:(fun ppf () -> Format.fprintf ppf "Too many proposals") + empty + (function Too_many_proposals -> Some () | _ -> None) + (fun () -> Too_many_proposals) ; + (* Empty proposal *) + register_error_kind + `Branch + ~id:"empty_proposal" + ~title:"Empty proposal" + ~description:"Proposal lists cannot be empty." + ~pp:(fun ppf () -> Format.fprintf ppf "Empty proposal") + empty + (function Empty_proposal -> Some () | _ -> None) + (fun () -> Empty_proposal) + +let record_proposals ctxt delegate proposals = + (match proposals with + | [] -> error Empty_proposal + | _ :: _ -> Result.return_unit) + >>?= fun () -> + Voting_period.get_current_kind ctxt >>=? function + | Proposal -> + Vote.in_listings ctxt delegate >>= fun in_listings -> + if in_listings then ( + Vote.recorded_proposal_count_for_delegate ctxt delegate + >>=? fun count -> + assert (Compare.Int.(Constants.max_proposals_per_delegate >= count)) ; + error_when + Compare.Int.( + List.compare_length_with + proposals + (Constants.max_proposals_per_delegate - count) + > 0) + Too_many_proposals + >>?= fun () -> + List.fold_left_es + (fun ctxt proposal -> Vote.record_proposal ctxt proposal delegate) + ctxt + proposals) + else fail Unauthorized_proposal + | Exploration | Cooldown | Promotion | Adoption -> fail Unexpected_proposal + +let record_ballot ctxt delegate proposal ballot = + Voting_period.get_current_kind ctxt >>=? function + | Exploration | Promotion -> + Vote.get_current_proposal ctxt >>=? fun current_proposal -> + error_unless + (Protocol_hash.equal proposal current_proposal) + Invalid_proposal + >>?= fun () -> + Vote.has_recorded_ballot ctxt delegate >>= fun has_ballot -> + error_when has_ballot Unauthorized_ballot >>?= fun () -> + Vote.in_listings ctxt delegate >>= fun in_listings -> + if in_listings then Vote.record_ballot ctxt delegate ballot + else fail Unauthorized_ballot + | Cooldown | Proposal | Adoption -> fail Unexpected_ballot + +let may_start_new_voting_period ctxt = + Voting_period.is_last_block ctxt >>=? fun is_last -> + if is_last then start_new_voting_period ctxt else return ctxt diff --git a/src/proto_012_PsiThaCa/lib_protocol/amendment.mli b/src/proto_012_PsiThaCa/lib_protocol/amendment.mli new file mode 100644 index 000000000000..200019bd03ea --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/amendment.mli @@ -0,0 +1,81 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Only delegates with at least one roll take part in the amendment + procedure. It works as follows: + + - Proposal period: delegates can submit protocol amendment + proposals using the proposal operation. At the end of a proposal + period, the proposal with most supporters is selected and we move + to an exploration period. If there are no proposals, or a tie + between proposals, a new proposal period starts. + + - Exploration period: delegates can cast votes to test or not the + winning proposal using the ballot operation. At the end of an + exploration period if participation reaches the quorum and the + proposal has a supermajority in favor, we proceed to a cooldown + period. Otherwise we go back to a proposal period. In any case, if + there is enough participation the quorum is updated. + + - Cooldown period: Nothing happens, this period is only a time gap + between exploration and promotion periods. At the end of a cooldown + period we move to a promotion period. + + - Promotion period: delegates can cast votes to promote or not the + proposal using the ballot operation. At the end of a promotion + period if participation reaches the quorum and the proposal has a + supermajority in favor, we move to an adoption period. Otherwise we + go back to a proposal period. In any case, if there is enough + participation the quorum is updated. + + - Adoption period: At the end of an adoption period, the proposal + is activated as the new protocol. *) + +open Alpha_context + +(** If at the end of a voting period, moves to the next one following + the state machine of the amendment procedure. *) +val may_start_new_voting_period : context -> context tzresult Lwt.t + +type error += + | Unexpected_proposal + | Unauthorized_proposal + | Too_many_proposals + | Empty_proposal + +(** Records a list of proposals for a delegate. + @raise Unexpected_proposal if [ctxt] is not in a proposal period. + @raise Unauthorized_proposal if [delegate] is not in the listing. *) +val record_proposals : + context -> public_key_hash -> Protocol_hash.t list -> context tzresult Lwt.t + +type error += Invalid_proposal | Unexpected_ballot | Unauthorized_ballot + +val record_ballot : + context -> + public_key_hash -> + Protocol_hash.t -> + Vote.ballot -> + context tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/apply.ml b/src/proto_012_PsiThaCa/lib_protocol/apply.ml new file mode 100644 index 000000000000..4b20f9e2fb24 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/apply.ml @@ -0,0 +1,2658 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Tezos Protocol Implementation - Main Entry Points *) + +open Alpha_context + +type error += + | (* `Permanent *) + Not_enough_endorsements of { + required : int; + endorsements : int; + } + | (* `Temporary *) + Wrong_consensus_operation_branch of + Block_hash.t * Block_hash.t + | (* `Permanent *) + Invalid_double_baking_evidence of { + hash1 : Block_hash.t; + level1 : Raw_level.t; + round1 : Round.t; + hash2 : Block_hash.t; + level2 : Raw_level.t; + round2 : Round.t; + } + | (* `Permanent *) + Wrong_level_for_consensus_operation of { + expected : Raw_level.t; + provided : Raw_level.t; + } + | (* `Permanent *) + Wrong_round_for_consensus_operation of { + expected : Round.t; + provided : Round.t; + } + | (* `Permanent *) + Preendorsement_round_too_high of { + block_round : Round.t; + provided : Round.t; + } + | (* `Permanent *) + Unexpected_endorsement_in_block + | (* `Permanent *) + Unexpected_preendorsement_in_block + | (* `Permanent *) + Wrong_payload_hash_for_consensus_operation of { + expected : Block_payload_hash.t; + provided : Block_payload_hash.t; + } + | (* `Permanent *) Wrong_slot_used_for_consensus_operation + | (* `Temporary *) + Consensus_operation_for_future_level of { + expected : Raw_level.t; + provided : Raw_level.t; + } + | (* `Temporary *) + Consensus_operation_for_future_round of { + expected : Round.t; + provided : Round.t; + } + | (* `Outdated *) + Consensus_operation_for_old_level of { + expected : Raw_level.t; + provided : Raw_level.t; + } + | (* `Branch *) + Consensus_operation_for_old_round of { + expected : Round.t; + provided : Round.t; + } + | (* `Branch *) + Consensus_operation_on_competing_proposal of { + expected : Block_payload_hash.t; + provided : Block_payload_hash.t; + } + | (* `Permanent *) + Set_deposits_limit_on_originated_contract + | (* `Temporary *) + Set_deposits_limit_on_unregistered_delegate of + Signature.Public_key_hash.t + | (* `Permanent *) + Set_deposits_limit_too_high of { + limit : Tez.t; + max_limit : Tez.t; + } + | (* `Branch *) Empty_transaction of Contract.t + +let () = + register_error_kind + `Permanent + ~id:"operations.wrong_slot" + ~title:"wrong slot" + ~description:"wrong slot" + ~pp:(fun ppf () -> Format.fprintf ppf "wrong slot") + Data_encoding.empty + (function Wrong_slot_used_for_consensus_operation -> Some () | _ -> None) + (fun () -> Wrong_slot_used_for_consensus_operation) ; + register_error_kind + `Permanent + ~id:"operation.not_enough_endorsements" + ~title:"Not enough endorsements" + ~description: + "The block being validated does not include the required minimum number \ + of endorsements." + ~pp:(fun ppf (required, endorsements) -> + Format.fprintf + ppf + "Wrong number of endorsements (%i), at least %i are expected" + endorsements + required) + Data_encoding.(obj2 (req "required" int31) (req "endorsements" int31)) + (function + | Not_enough_endorsements {required; endorsements} -> + Some (required, endorsements) + | _ -> None) + (fun (required, endorsements) -> + Not_enough_endorsements {required; endorsements}) ; + register_error_kind + `Temporary + ~id:"operation.wrong_consensus_operation_branch" + ~title:"Wrong consensus operation branch" + ~description: + "Trying to include an endorsement or preendorsement which points to the \ + wrong block.\n\ + \ It should be the predecessor for preendorsements and the \ + grandfather for endorsements." + ~pp:(fun ppf (e, p) -> + Format.fprintf + ppf + "Wrong branch %a, expected %a" + Block_hash.pp + p + Block_hash.pp + e) + Data_encoding.( + obj2 + (req "expected" Block_hash.encoding) + (req "provided" Block_hash.encoding)) + (function + | Wrong_consensus_operation_branch (e, p) -> Some (e, p) | _ -> None) + (fun (e, p) -> Wrong_consensus_operation_branch (e, p)) ; + register_error_kind + `Permanent + ~id:"block.invalid_double_baking_evidence" + ~title:"Invalid double baking evidence" + ~description: + "A double-baking evidence is inconsistent (two distinct level)" + ~pp:(fun ppf (hash1, level1, round1, hash2, level2, round2) -> + Format.fprintf + ppf + "Invalid double-baking evidence (hash: %a and %a, levels/rounds: \ + (%ld,%ld) and (%ld,%ld))" + Block_hash.pp + hash1 + Block_hash.pp + hash2 + (Raw_level.to_int32 level1) + (Round.to_int32 round1) + (Raw_level.to_int32 level2) + (Round.to_int32 round2)) + Data_encoding.( + obj6 + (req "hash1" Block_hash.encoding) + (req "level1" Raw_level.encoding) + (req "round1" Round.encoding) + (req "hash2" Block_hash.encoding) + (req "level2" Raw_level.encoding) + (req "round2" Round.encoding)) + (function + | Invalid_double_baking_evidence + {hash1; level1; round1; hash2; level2; round2} -> + Some (hash1, level1, round1, hash2, level2, round2) + | _ -> None) + (fun (hash1, level1, round1, hash2, level2, round2) -> + Invalid_double_baking_evidence + {hash1; level1; round1; hash2; level2; round2}) ; + register_error_kind + `Permanent + ~id:"wrong_level_for_consensus_operation" + ~title:"wrong level for consensus operation" + ~description:"Wrong level for consensus operation." + ~pp:(fun ppf (expected, provided) -> + Format.fprintf + ppf + "Wrong level for consensus operation (expected: %a, provided: %a)." + Raw_level.pp + expected + Raw_level.pp + provided) + Data_encoding.( + obj2 + (req "expected" Raw_level.encoding) + (req "provided" Raw_level.encoding)) + (function + | Wrong_level_for_consensus_operation {expected; provided} -> + Some (expected, provided) + | _ -> None) + (fun (expected, provided) -> + Wrong_level_for_consensus_operation {expected; provided}) ; + register_error_kind + `Permanent + ~id:"wrong_round_for_consensus_operation" + ~title:"wrong round for consensus operation" + ~description:"Wrong round for consensus operation." + ~pp:(fun ppf (expected, provided) -> + Format.fprintf + ppf + "Wrong round for consensus operation (expected: %a, provided: %a)." + Round.pp + expected + Round.pp + provided) + Data_encoding.( + obj2 (req "expected" Round.encoding) (req "provided" Round.encoding)) + (function + | Wrong_round_for_consensus_operation {expected; provided} -> + Some (expected, provided) + | _ -> None) + (fun (expected, provided) -> + Wrong_round_for_consensus_operation {expected; provided}) ; + register_error_kind + `Permanent + ~id:"preendorsement_round_too_high" + ~title:"preendorsement round too high" + ~description:"Preendorsement round too high." + ~pp:(fun ppf (block_round, provided) -> + Format.fprintf + ppf + "Preendorsement round too high (block_round: %a, provided: %a)." + Round.pp + block_round + Round.pp + provided) + Data_encoding.( + obj2 (req "block_round" Round.encoding) (req "provided" Round.encoding)) + (function + | Preendorsement_round_too_high {block_round; provided} -> + Some (block_round, provided) + | _ -> None) + (fun (block_round, provided) -> + Preendorsement_round_too_high {block_round; provided}) ; + register_error_kind + `Permanent + ~id:"wrong_payload_hash_for_consensus_operation" + ~title:"wrong payload hash for consensus operation" + ~description:"Wrong payload hash for consensus operation." + ~pp:(fun ppf (expected, provided) -> + Format.fprintf + ppf + "Wrong payload hash for consensus operation (expected: %a, provided: \ + %a)." + Block_payload_hash.pp_short + expected + Block_payload_hash.pp_short + provided) + Data_encoding.( + obj2 + (req "expected" Block_payload_hash.encoding) + (req "provided" Block_payload_hash.encoding)) + (function + | Wrong_payload_hash_for_consensus_operation {expected; provided} -> + Some (expected, provided) + | _ -> None) + (fun (expected, provided) -> + Wrong_payload_hash_for_consensus_operation {expected; provided}) ; + register_error_kind + `Permanent + ~id:"unexpected_endorsement_in_block" + ~title:"unexpected endorsement in block" + ~description:"Unexpected endorsement in block." + ~pp:(fun ppf () -> Format.fprintf ppf "Unexpected endorsement in block.") + Data_encoding.empty + (function Unexpected_endorsement_in_block -> Some () | _ -> None) + (fun () -> Unexpected_endorsement_in_block) ; + register_error_kind + `Permanent + ~id:"unexpected_preendorsement_in_block" + ~title:"unexpected preendorsement in block" + ~description:"Unexpected preendorsement in block." + ~pp:(fun ppf () -> Format.fprintf ppf "Unexpected preendorsement in block.") + Data_encoding.empty + (function Unexpected_preendorsement_in_block -> Some () | _ -> None) + (fun () -> Unexpected_preendorsement_in_block) ; + register_error_kind + `Temporary + ~id:"consensus_operation_for_future_level" + ~title:"Consensus operation for future level" + ~description:"Consensus operation for future level." + ~pp:(fun ppf (expected, provided) -> + Format.fprintf + ppf + "Consensus operation for future level\n\ + \ (expected: %a, provided: %a)." + Raw_level.pp + expected + Raw_level.pp + provided) + Data_encoding.( + obj2 + (req "expected" Raw_level.encoding) + (req "provided" Raw_level.encoding)) + (function + | Consensus_operation_for_future_level {expected; provided} -> + Some (expected, provided) + | _ -> None) + (fun (expected, provided) -> + Consensus_operation_for_future_level {expected; provided}) ; + register_error_kind + `Temporary + ~id:"consensus_operation_for_future_round" + ~title:"Consensus operation for future round" + ~description:"Consensus operation for future round." + ~pp:(fun ppf (expected, provided) -> + Format.fprintf + ppf + "Consensus operation for future round (expected: %a, provided: %a)." + Round.pp + expected + Round.pp + provided) + Data_encoding.( + obj2 (req "expected_max" Round.encoding) (req "provided" Round.encoding)) + (function + | Consensus_operation_for_future_round {expected; provided} -> + Some (expected, provided) + | _ -> None) + (fun (expected, provided) -> + Consensus_operation_for_future_round {expected; provided}) ; + register_error_kind + `Outdated + ~id:"consensus_operation_for_old_level" + ~title:"Consensus operation for old level" + ~description:"Consensus operation for old level." + ~pp:(fun ppf (expected, provided) -> + Format.fprintf + ppf + "Consensus operation for old level (expected: %a, provided: %a)." + Raw_level.pp + expected + Raw_level.pp + provided) + Data_encoding.( + obj2 + (req "expected" Raw_level.encoding) + (req "provided" Raw_level.encoding)) + (function + | Consensus_operation_for_old_level {expected; provided} -> + Some (expected, provided) + | _ -> None) + (fun (expected, provided) -> + Consensus_operation_for_old_level {expected; provided}) ; + register_error_kind + `Branch + ~id:"consensus_operation_for_old_round" + ~title:"Consensus operation for old round" + ~description:"Consensus operation for old round." + ~pp:(fun ppf (expected, provided) -> + Format.fprintf + ppf + "Consensus operation for old round (expected_min: %a, provided: %a)." + Round.pp + expected + Round.pp + provided) + Data_encoding.( + obj2 (req "expected_min" Round.encoding) (req "provided" Round.encoding)) + (function + | Consensus_operation_for_old_round {expected; provided} -> + Some (expected, provided) + | _ -> None) + (fun (expected, provided) -> + Consensus_operation_for_old_round {expected; provided}) ; + register_error_kind + `Branch + ~id:"consensus_operation_on_competing_proposal" + ~title:"Consensus operation on competing proposal" + ~description:"Consensus operation on competing proposal." + ~pp:(fun ppf (expected, provided) -> + Format.fprintf + ppf + "Consensus operation on competing proposal (expected: %a, provided: \ + %a)." + Block_payload_hash.pp_short + expected + Block_payload_hash.pp_short + provided) + Data_encoding.( + obj2 + (req "expected" Block_payload_hash.encoding) + (req "provided" Block_payload_hash.encoding)) + (function + | Consensus_operation_on_competing_proposal {expected; provided} -> + Some (expected, provided) + | _ -> None) + (fun (expected, provided) -> + Consensus_operation_on_competing_proposal {expected; provided}) ; + register_error_kind + `Permanent + ~id:"operation.set_deposits_limit_on_originated_contract" + ~title:"Set deposits limit on an originated contract" + ~description:"Cannot set deposits limit on an originated contract." + ~pp:(fun ppf () -> + Format.fprintf ppf "Cannot set deposits limit on an originated contract.") + Data_encoding.empty + (function + | Set_deposits_limit_on_originated_contract -> Some () | _ -> None) + (fun () -> Set_deposits_limit_on_originated_contract) ; + register_error_kind + `Temporary + ~id:"operation.set_deposits_limit_on_unregistered_delegate" + ~title:"Set deposits limit on an unregistered delegate" + ~description:"Cannot set deposits limit on an unregistered delegate." + ~pp:(fun ppf c -> + Format.fprintf + ppf + "Cannot set a deposits limit on the unregistered delegate %a." + Signature.Public_key_hash.pp + c) + Data_encoding.(obj1 (req "delegate" Signature.Public_key_hash.encoding)) + (function + | Set_deposits_limit_on_unregistered_delegate c -> Some c | _ -> None) + (fun c -> Set_deposits_limit_on_unregistered_delegate c) ; + register_error_kind + `Permanent + ~id:"operation.set_deposits_limit_too_high" + ~title:"Set deposits limit to a too high value" + ~description: + "Cannot set deposits limit such that the active stake overflows." + ~pp:(fun ppf (limit, max_limit) -> + Format.fprintf + ppf + "Cannot set deposits limit to %a as it is higher the allowed maximum \ + %a." + Tez.pp + limit + Tez.pp + max_limit) + Data_encoding.( + obj2 (req "limit" Tez.encoding) (req "max_limit" Tez.encoding)) + (function + | Set_deposits_limit_too_high {limit; max_limit} -> Some (limit, max_limit) + | _ -> None) + (fun (limit, max_limit) -> Set_deposits_limit_too_high {limit; max_limit}) ; + register_error_kind + `Branch + ~id:"contract.empty_transaction" + ~title:"Empty transaction" + ~description:"Forbidden to credit 0ꜩ to a contract without code." + ~pp:(fun ppf contract -> + Format.fprintf + ppf + "Transactions of 0ꜩ towards a contract without code are forbidden \ + (%a)." + Contract.pp + contract) + Data_encoding.(obj1 (req "contract" Contract.encoding)) + (function Empty_transaction c -> Some c | _ -> None) + (fun c -> Empty_transaction c) + +type error += (* `Temporary *) Wrong_voting_period of int32 * int32 + +type error += + | (* `Permanent *) Internal_operation_replay of packed_internal_operation + +type denunciation_kind = Preendorsement | Endorsement | Block + +let denunciation_kind_encoding = + let open Data_encoding in + string_enum + [ + ("preendorsement", Preendorsement); + ("endorsement", Endorsement); + ("block", Block); + ] + +let pp_denunciation_kind fmt : denunciation_kind -> unit = function + | Preendorsement -> Format.fprintf fmt "preendorsement" + | Endorsement -> Format.fprintf fmt "endorsement" + | Block -> Format.fprintf fmt "baking" + +type error += (* `Permanent *) + Invalid_denunciation of denunciation_kind + +type error += + | (* `Permanent *) + Inconsistent_denunciation of { + kind : denunciation_kind; + delegate1 : Signature.Public_key_hash.t; + delegate2 : Signature.Public_key_hash.t; + } + +type error += (* `Branch *) Unrequired_denunciation + +type error += + | (* `Temporary *) + Too_early_denunciation of { + kind : denunciation_kind; + level : Raw_level.t; + current : Raw_level.t; + } + +type error += + | (* `Permanent *) + Outdated_denunciation of { + kind : denunciation_kind; + level : Raw_level.t; + last_cycle : Cycle.t; + } + +type error += + | (* Permanent *) Invalid_activation of {pkh : Ed25519.Public_key_hash.t} + +type error += (* Permanent *) Multiple_revelation + +type error += (* Permanent *) Gas_quota_exceeded_init_deserialize + +type error += (* `Permanent *) Inconsistent_sources + +type error += (* `Permanent *) Failing_noop_error + +type error += + | (* `Permanent *) + Zero_frozen_deposits of Signature.Public_key_hash.t + +let () = + register_error_kind + `Temporary + ~id:"operation.wrong_voting_period" + ~title:"Wrong voting period" + ~description: + "Trying to include a proposal or ballot meant for another voting period" + ~pp:(fun ppf (e, p) -> + Format.fprintf ppf "Wrong voting period %ld, current is %ld" p e) + Data_encoding.( + obj2 (req "current_index" int32) (req "provided_index" int32)) + (function Wrong_voting_period (e, p) -> Some (e, p) | _ -> None) + (fun (e, p) -> Wrong_voting_period (e, p)) ; + register_error_kind + `Permanent + ~id:"internal_operation_replay" + ~title:"Internal operation replay" + ~description:"An internal operation was emitted twice by a script" + ~pp:(fun ppf (Internal_operation {nonce; _}) -> + Format.fprintf + ppf + "Internal operation %d was emitted twice by a script" + nonce) + Operation.internal_operation_encoding + (function Internal_operation_replay op -> Some op | _ -> None) + (fun op -> Internal_operation_replay op) ; + register_error_kind + `Permanent + ~id:"block.invalid_denunciation" + ~title:"Invalid denunciation" + ~description:"A denunciation is malformed" + ~pp:(fun ppf kind -> + Format.fprintf + ppf + "Malformed double-%a evidence" + pp_denunciation_kind + kind) + Data_encoding.(obj1 (req "kind" denunciation_kind_encoding)) + (function Invalid_denunciation kind -> Some kind | _ -> None) + (fun kind -> Invalid_denunciation kind) ; + register_error_kind + `Permanent + ~id:"block.inconsistent_denunciation" + ~title:"Inconsistent denunciation" + ~description: + "A denunciation operation is inconsistent (two distinct delegates)" + ~pp:(fun ppf (kind, delegate1, delegate2) -> + Format.fprintf + ppf + "Inconsistent double-%a evidence (distinct delegate: %a and %a)" + pp_denunciation_kind + kind + Signature.Public_key_hash.pp_short + delegate1 + Signature.Public_key_hash.pp_short + delegate2) + Data_encoding.( + obj3 + (req "kind" denunciation_kind_encoding) + (req "delegate1" Signature.Public_key_hash.encoding) + (req "delegate2" Signature.Public_key_hash.encoding)) + (function + | Inconsistent_denunciation {kind; delegate1; delegate2} -> + Some (kind, delegate1, delegate2) + | _ -> None) + (fun (kind, delegate1, delegate2) -> + Inconsistent_denunciation {kind; delegate1; delegate2}) ; + register_error_kind + `Branch + ~id:"block.unrequired_denunciation" + ~title:"Unrequired denunciation" + ~description:"A denunciation is unrequired" + ~pp:(fun ppf _ -> + Format.fprintf + ppf + "A valid denunciation cannot be applied: the associated delegate has \ + already been denounced for this level.") + Data_encoding.unit + (function Unrequired_denunciation -> Some () | _ -> None) + (fun () -> Unrequired_denunciation) ; + register_error_kind + `Temporary + ~id:"block.too_early_denunciation" + ~title:"Too early denunciation" + ~description:"A denunciation is too far in the future" + ~pp:(fun ppf (kind, level, current) -> + Format.fprintf + ppf + "A double-%a denunciation is too far in the future (current level: %a, \ + given level: %a)" + pp_denunciation_kind + kind + Raw_level.pp + current + Raw_level.pp + level) + Data_encoding.( + obj3 + (req "kind" denunciation_kind_encoding) + (req "level" Raw_level.encoding) + (req "current" Raw_level.encoding)) + (function + | Too_early_denunciation {kind; level; current} -> + Some (kind, level, current) + | _ -> None) + (fun (kind, level, current) -> + Too_early_denunciation {kind; level; current}) ; + register_error_kind + `Permanent + ~id:"block.outdated_denunciation" + ~title:"Outdated denunciation" + ~description:"A denunciation is outdated." + ~pp:(fun ppf (kind, level, last_cycle) -> + Format.fprintf + ppf + "A double-%a is outdated (last acceptable cycle: %a, given level: %a)" + pp_denunciation_kind + kind + Cycle.pp + last_cycle + Raw_level.pp + level) + Data_encoding.( + obj3 + (req "kind" denunciation_kind_encoding) + (req "level" Raw_level.encoding) + (req "last" Cycle.encoding)) + (function + | Outdated_denunciation {kind; level; last_cycle} -> + Some (kind, level, last_cycle) + | _ -> None) + (fun (kind, level, last_cycle) -> + Outdated_denunciation {kind; level; last_cycle}) ; + register_error_kind + `Permanent + ~id:"operation.invalid_activation" + ~title:"Invalid activation" + ~description: + "The given key and secret do not correspond to any existing preallocated \ + contract" + ~pp:(fun ppf pkh -> + Format.fprintf + ppf + "Invalid activation. The public key %a does not match any commitment." + Ed25519.Public_key_hash.pp + pkh) + Data_encoding.(obj1 (req "pkh" Ed25519.Public_key_hash.encoding)) + (function Invalid_activation {pkh} -> Some pkh | _ -> None) + (fun pkh -> Invalid_activation {pkh}) ; + register_error_kind + `Permanent + ~id:"block.multiple_revelation" + ~title:"Multiple revelations were included in a manager operation" + ~description: + "A manager operation should not contain more than one revelation" + ~pp:(fun ppf () -> + Format.fprintf + ppf + "Multiple revelations were included in a manager operation") + Data_encoding.empty + (function Multiple_revelation -> Some () | _ -> None) + (fun () -> Multiple_revelation) ; + register_error_kind + `Permanent + ~id:"gas_exhausted.init_deserialize" + ~title:"Not enough gas for initial deserialization of script expressions" + ~description: + "Gas limit was not high enough to deserialize the transaction parameters \ + or origination script code or initial storage, making the operation \ + impossible to parse within the provided gas bounds." + Data_encoding.empty + (function Gas_quota_exceeded_init_deserialize -> Some () | _ -> None) + (fun () -> Gas_quota_exceeded_init_deserialize) ; + register_error_kind + `Permanent + ~id:"operation.inconsistent_sources" + ~title:"Inconsistent sources in operation pack" + ~description: + "The operation pack includes operations from different sources." + ~pp:(fun ppf () -> + Format.pp_print_string + ppf + "The operation pack includes operations from different sources.") + Data_encoding.empty + (function Inconsistent_sources -> Some () | _ -> None) + (fun () -> Inconsistent_sources) ; + register_error_kind + `Permanent + ~id:"operation.failing_noop" + ~title:"Failing_noop operation are not executed by the protocol" + ~description: + "The failing_noop operation is an operation that is not and never will \ + be executed by the protocol." + ~pp:(fun ppf () -> + Format.fprintf + ppf + "The failing_noop operation cannot be executed by the protocol") + Data_encoding.empty + (function Failing_noop_error -> Some () | _ -> None) + (fun () -> Failing_noop_error) ; + register_error_kind + `Permanent + ~id:"delegate.zero_frozen_deposits" + ~title:"Zero frozen deposits" + ~description:"The delegate has zero frozen deposits." + ~pp:(fun ppf delegate -> + Format.fprintf + ppf + "Delegate %a has zero frozen deposits; it is not allowed to \ + bake/preendorse/endorse." + Signature.Public_key_hash.pp + delegate) + Data_encoding.(obj1 (req "delegate" Signature.Public_key_hash.encoding)) + (function Zero_frozen_deposits delegate -> Some delegate | _ -> None) + (fun delegate -> Zero_frozen_deposits delegate) + +open Apply_results + +let cache_layout = Constants_repr.cache_layout + +(** + + Retrieving the source code of a contract from its address is costly + because it requires I/Os. For this reason, we put the corresponding + Micheline expression in the cache. + + Elaborating a Micheline node into the well-typed script abstract + syntax tree is also a costly operation. The result of this operation + is cached as well. + +*) + +let apply_manager_operation_content : + type kind. + Alpha_context.t -> + Script_ir_translator.unparsing_mode -> + payer:Contract.t -> + source:Contract.t -> + chain_id:Chain_id.t -> + internal:bool -> + gas_consumed_in_precheck:Gas.cost option -> + kind manager_operation -> + (context + * kind successful_manager_operation_result + * packed_internal_operation list) + tzresult + Lwt.t = + fun ctxt + mode + ~payer + ~source + ~chain_id + ~internal + ~gas_consumed_in_precheck + operation -> + let before_operation = + (* This context is not used for backtracking. Only to compute + gas consumption and originations for the operation result. *) + ctxt + in + Contract.must_exist ctxt source >>=? fun () -> + Gas.consume ctxt Michelson_v1_gas.Cost_of.manager_operation >>?= fun ctxt -> + (match gas_consumed_in_precheck with + | None -> Ok ctxt + | Some gas -> Gas.consume ctxt gas) + >>?= fun ctxt -> + let consume_deserialization_gas = Script.When_needed in + (* [note]: deserialization gas has already been accounted for in the gas + consumed by the precheck and the lazy_exprs have been forced. *) + match operation with + | Reveal _ -> + return + (* No-op: action already performed by `precheck_manager_contents`. *) + ( ctxt, + (Reveal_result + {consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt} + : kind successful_manager_operation_result), + [] ) + | Transaction {amount; parameters; destination; entrypoint} -> ( + Script.force_decode_in_context + ~consume_deserialization_gas + ctxt + parameters + >>?= fun (parameter, ctxt) -> + (match Contract.is_implicit destination with + | None -> + (if Tez.(amount = zero) then + (* Detect potential call to non existent contract. *) + Contract.must_exist ctxt destination + else return_unit) + >>=? fun () -> + (* Since the contract is originated, nothing will be allocated + or the next transfer of tokens will fail. *) + return_false + | Some _ -> + (* Transfers of zero to implicit accounts are forbidden. *) + error_when Tez.(amount = zero) (Empty_transaction destination) + >>?= fun () -> + (* If the implicit contract is not yet allocated at this point then + the next transfer of tokens will allocate it. *) + Contract.allocated ctxt destination >|=? not) + >>=? fun allocated_destination_contract -> + Token.transfer ctxt (`Contract source) (`Contract destination) amount + >>=? fun (ctxt, balance_updates) -> + Script_cache.find ctxt destination >>=? fun (ctxt, cache_key, script) -> + match script with + | None -> + Lwt.return + ( ( (match entrypoint with + | "default" -> Result.return_unit + | entrypoint -> + error (Script_tc_errors.No_such_entrypoint entrypoint)) + >>? fun () -> + match Micheline.root parameter with + | Prim (_, D_Unit, [], _) -> + (* Allow [Unit] parameter to non-scripted contracts. *) + ok ctxt + | _ -> + error + (Script_interpreter.Bad_contract_parameter destination) ) + >|? fun ctxt -> + let result = + Transaction_result + { + storage = None; + lazy_storage_diff = None; + balance_updates; + originated_contracts = []; + consumed_gas = + Gas.consumed ~since:before_operation ~until:ctxt; + storage_size = Z.zero; + paid_storage_size_diff = Z.zero; + allocated_destination_contract; + } + in + (ctxt, result, []) ) + | Some (script, script_ir) -> + let now = Script_timestamp.now ctxt in + let level = + (Level.current ctxt).level |> Raw_level.to_int32 + |> Script_int.of_int32 |> Script_int.abs + in + let step_constants = + let open Script_interpreter in + {source; payer; self = destination; amount; chain_id; now; level} + in + Script_interpreter.execute + ctxt + ~cached_script:(Some script_ir) + mode + step_constants + ~script + ~parameter + ~entrypoint + ~internal + >>=? fun ( {ctxt; storage; lazy_storage_diff; operations}, + (updated_cached_script, updated_size) ) -> + Contract.update_script_storage + ctxt + destination + storage + lazy_storage_diff + >>=? fun ctxt -> + Fees.record_paid_storage_space ctxt destination + >>=? fun (ctxt, new_size, paid_storage_size_diff) -> + Contract.originated_from_current_nonce + ~since:before_operation + ~until:ctxt + >>=? fun originated_contracts -> + Lwt.return + ( Script_cache.update + ctxt + cache_key + ( {script with storage = Script.lazy_expr storage}, + updated_cached_script ) + updated_size + >|? fun ctxt -> + let result = + Transaction_result + { + storage = Some storage; + lazy_storage_diff; + balance_updates; + originated_contracts; + consumed_gas = + Gas.consumed ~since:before_operation ~until:ctxt; + storage_size = new_size; + paid_storage_size_diff; + allocated_destination_contract; + } + in + (ctxt, result, operations) )) + | Origination {delegate; script; preorigination; credit} -> + Script.force_decode_in_context + ~consume_deserialization_gas + ctxt + script.storage + >>?= fun (_unparsed_storage, ctxt) -> + Script.force_decode_in_context + ~consume_deserialization_gas + ctxt + script.code + >>?= fun (unparsed_code, ctxt) -> + Script_ir_translator.parse_script + ctxt + ~legacy:false + ~allow_forged_in_storage:internal + script + >>=? fun (Ex_script parsed_script, ctxt) -> + let views_result = + Script_ir_translator.typecheck_views + ctxt + ~legacy:false + parsed_script.storage_type + parsed_script.views + in + trace + (Script_tc_errors.Ill_typed_contract (unparsed_code, [])) + views_result + >>=? fun ctxt -> + Script_ir_translator.collect_lazy_storage + ctxt + parsed_script.storage_type + parsed_script.storage + >>?= fun (to_duplicate, ctxt) -> + let to_update = Script_ir_translator.no_lazy_storage_id in + Script_ir_translator.extract_lazy_storage_diff + ctxt + Optimized + parsed_script.storage_type + parsed_script.storage + ~to_duplicate + ~to_update + ~temporary:false + >>=? fun (storage, lazy_storage_diff, ctxt) -> + Script_ir_translator.unparse_data + ctxt + Optimized + parsed_script.storage_type + storage + >>=? fun (storage, ctxt) -> + let storage = Script.lazy_expr (Micheline.strip_locations storage) in + let script = {script with storage} in + (match preorigination with + | Some contract -> + assert internal ; + (* The preorigination field is only used to early return + the address of an originated contract in Michelson. + It cannot come from the outside. *) + ok (ctxt, contract) + | None -> Contract.fresh_contract_from_current_nonce ctxt) + >>?= fun (ctxt, contract) -> + Contract.raw_originate + ctxt + ~prepaid_bootstrap_storage:false + contract + ~script:(script, lazy_storage_diff) + >>=? fun ctxt -> + (match delegate with + | None -> return ctxt + | Some delegate -> Delegate.init ctxt contract delegate) + >>=? fun ctxt -> + Token.transfer ctxt (`Contract source) (`Contract contract) credit + >>=? fun (ctxt, balance_updates) -> + Fees.record_paid_storage_space ctxt contract + >|=? fun (ctxt, size, paid_storage_size_diff) -> + let result = + Origination_result + { + lazy_storage_diff; + balance_updates; + originated_contracts = [contract]; + consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + storage_size = size; + paid_storage_size_diff; + } + in + (ctxt, result, []) + | Delegation delegate -> + Delegate.set ctxt source delegate >|=? fun ctxt -> + ( ctxt, + Delegation_result + {consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt}, + [] ) + | Register_global_constant {value} -> + (* Decode the value and consume gas appropriately *) + Script.force_decode_in_context ~consume_deserialization_gas ctxt value + >>?= fun (expr, ctxt) -> + (* Set the key to the value in storage. *) + Global_constants_storage.register ctxt expr + >>=? fun (ctxt, address, size) -> + (* The burn and the reporting of the burn are calculated differently. + + [Fees.record_global_constant_storage_space] does the actual burn + based on the size of the constant registered, and this causes a + change in account balance. + + On the other hand, the receipt is calculated + with the help of [Fees.cost_of_bytes], and is included in block metadata + and the client output. The receipt is also used during simulation, + letting the client automatically set an appropriate storage limit. + TODO : is this concern still honored by the token management + refactoring ? *) + let (ctxt, paid_size) = + Fees.record_global_constant_storage_space ctxt size + in + let result = + Register_global_constant_result + { + balance_updates = []; + consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + size_of_constant = paid_size; + global_address = address; + } + in + return (ctxt, result, []) + | Set_deposits_limit limit -> ( + (match limit with + | None -> return_unit + | Some limit -> + let frozen_deposits_percentage = + Constants.frozen_deposits_percentage ctxt + in + let max_limit = + Tez.of_mutez_exn + Int64.( + mul (of_int frozen_deposits_percentage) Int64.(div max_int 100L)) + in + fail_when + Tez.(limit > max_limit) + (Set_deposits_limit_too_high {limit; max_limit})) + >>=? fun () -> + Contract.is_implicit source |> function + | None -> fail Set_deposits_limit_on_originated_contract + | Some delegate -> + Delegate.registered ctxt delegate >>=? fun is_registered -> + fail_unless + is_registered + (Set_deposits_limit_on_unregistered_delegate delegate) + >>=? fun () -> + Delegate.set_frozen_deposits_limit ctxt delegate limit >>= fun ctxt -> + return + ( ctxt, + Set_deposits_limit_result + { + consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + }, + [] )) + +type success_or_failure = Success of context | Failure + +let apply_internal_manager_operations ctxt mode ~payer ~chain_id ops = + let[@coq_struct "ctxt"] rec apply ctxt applied worklist = + match worklist with + | [] -> Lwt.return (Success ctxt, List.rev applied) + | Internal_operation ({source; operation; nonce} as op) :: rest -> ( + (if internal_nonce_already_recorded ctxt nonce then + fail (Internal_operation_replay (Internal_operation op)) + else + let ctxt = record_internal_nonce ctxt nonce in + apply_manager_operation_content + ctxt + mode + ~source + ~payer + ~chain_id + ~internal:true + ~gas_consumed_in_precheck:None + operation) + >>= function + | Error errors -> + let result = + Internal_operation_result + (op, Failed (manager_kind op.operation, errors)) + in + let skipped = + List.rev_map + (fun (Internal_operation op) -> + Internal_operation_result + (op, Skipped (manager_kind op.operation))) + rest + in + Lwt.return (Failure, List.rev (skipped @ result :: applied)) + | Ok (ctxt, result, emitted) -> + apply + ctxt + (Internal_operation_result (op, Applied result) :: applied) + (emitted @ rest)) + in + apply ctxt [] ops + +let precheck_manager_contents (type kind) ctxt (op : kind Kind.manager contents) + ~(only_batch : bool) : (context * precheck_result) tzresult Lwt.t = + let[@coq_match_with_default] (Manager_operation + { + source; + fee; + counter; + operation; + gas_limit; + storage_limit; + }) = + op + in + (if only_batch then + (* Gas.consume_limit_in_block will only raise a "temporary" error, however + when the precheck is called on a batch in isolation (like e.g. in the + mempool) it must "refuse" operations whose total gas_limit (the sum of + the gas_limits of each operation) is already above the block limit. We + add the "permanent" error Gas.Gas_limit_too_high on top of the trace to + this effect. *) + record_trace Gas.Gas_limit_too_high + else fun errs -> errs) + @@ Gas.consume_limit_in_block ctxt gas_limit + >>?= fun ctxt -> + let ctxt = Gas.set_limit ctxt gas_limit in + let ctxt_before = ctxt in + Fees.check_storage_limit ctxt ~storage_limit >>?= fun () -> + let source_contract = Contract.implicit_contract source in + Contract.must_be_allocated ctxt source_contract >>=? fun () -> + Contract.check_counter_increment ctxt source counter >>=? fun () -> + let consume_deserialization_gas = Script.Always in + (* We want to always consume the deserialization gas here, independently of + the internal state of the lazy_exprs in the arguments. Otherwise we might + risk getting different results if the operation has already been + deserialized before (e.g. when retrieve in JSON format). *) + (match operation with + | Reveal pk -> Contract.reveal_manager_key ctxt source pk + | Transaction {parameters; _} -> + Lwt.return + @@ record_trace Gas_quota_exceeded_init_deserialize + @@ (* Fail early if not enough gas for complete deserialization + cost or if deserialization fails. The gas consumed here is + "replayed" in [apply_manager_contents]. *) + ( Script.force_decode_in_context + ~consume_deserialization_gas + ctxt + parameters + >|? fun (_arg, ctxt) -> ctxt ) + | Origination {script; _} -> + Lwt.return + @@ record_trace Gas_quota_exceeded_init_deserialize + @@ (* See comment in the Transaction branch *) + ( Script.force_decode_in_context + ~consume_deserialization_gas + ctxt + script.code + >>? fun (_code, ctxt) -> + Script.force_decode_in_context + ~consume_deserialization_gas + ctxt + script.storage + >|? fun (_storage, ctxt) -> ctxt ) + | Register_global_constant {value} -> + Lwt.return + @@ record_trace Gas_quota_exceeded_init_deserialize + @@ (* See comment in the Transaction branch *) + ( Script.force_decode_in_context ~consume_deserialization_gas ctxt value + >|? fun (_value, ctxt) -> ctxt ) + | _ -> return ctxt) + >>=? fun ctxt -> + Contract.increment_counter ctxt source >>=? fun ctxt -> + Token.transfer ctxt (`Contract source_contract) `Block_fees fee + >|=? fun (ctxt, balance_updates) -> + let consumed_gas = Gas.consumed ~since:ctxt_before ~until:ctxt in + (ctxt, {balance_updates; consumed_gas}) + +(** [burn_storage_fees ctxt smopr storage_limit payer] burns the storage fees + associated to the transaction or origination result [smopr]. + Returns an updated context, an updated storage limit with the space consumed + by the operation subtracted, and [smopr] with the relevant balance updates + included. *) +let burn_storage_fees : + type kind. + context -> + kind successful_manager_operation_result -> + storage_limit:Z.t -> + payer:Contract.t -> + (context * Z.t * kind successful_manager_operation_result) tzresult Lwt.t = + fun ctxt smopr ~storage_limit ~payer -> + match smopr with + | Transaction_result payload -> + let consumed = payload.paid_storage_size_diff in + let payer = `Contract payer in + Fees.burn_storage_fees ctxt ~storage_limit ~payer consumed + >>=? fun (ctxt, storage_limit, storage_bus) -> + (if payload.allocated_destination_contract then + Fees.burn_origination_fees ctxt ~storage_limit ~payer + else return (ctxt, storage_limit, [])) + >>=? fun (ctxt, storage_limit, origination_bus) -> + let balance_updates = + storage_bus @ payload.balance_updates @ origination_bus + in + return + ( ctxt, + storage_limit, + Transaction_result + { + storage = payload.storage; + lazy_storage_diff = payload.lazy_storage_diff; + balance_updates; + originated_contracts = payload.originated_contracts; + consumed_gas = payload.consumed_gas; + storage_size = payload.storage_size; + paid_storage_size_diff = payload.paid_storage_size_diff; + allocated_destination_contract = + payload.allocated_destination_contract; + } ) + | Origination_result payload -> + let consumed = payload.paid_storage_size_diff in + let payer = `Contract payer in + Fees.burn_storage_fees ctxt ~storage_limit ~payer consumed + >>=? fun (ctxt, storage_limit, storage_bus) -> + Fees.burn_origination_fees ctxt ~storage_limit ~payer + >>=? fun (ctxt, storage_limit, origination_bus) -> + let balance_updates = + storage_bus @ origination_bus @ payload.balance_updates + in + return + ( ctxt, + storage_limit, + Origination_result + { + lazy_storage_diff = payload.lazy_storage_diff; + balance_updates; + originated_contracts = payload.originated_contracts; + consumed_gas = payload.consumed_gas; + storage_size = payload.storage_size; + paid_storage_size_diff = payload.paid_storage_size_diff; + } ) + | Reveal_result _ | Delegation_result _ -> return (ctxt, storage_limit, smopr) + | Register_global_constant_result payload -> + let consumed = payload.size_of_constant in + let payer = `Contract payer in + Fees.burn_storage_fees ctxt ~storage_limit ~payer consumed + >>=? fun (ctxt, storage_limit, storage_bus) -> + let balance_updates = storage_bus @ payload.balance_updates in + return + ( ctxt, + storage_limit, + Register_global_constant_result + { + balance_updates; + consumed_gas = payload.consumed_gas; + size_of_constant = payload.size_of_constant; + global_address = payload.global_address; + } ) + | Set_deposits_limit_result _ -> return (ctxt, storage_limit, smopr) + +let apply_manager_contents (type kind) ctxt mode chain_id + ~gas_consumed_in_precheck (op : kind Kind.manager contents) : + (success_or_failure + * kind manager_operation_result + * packed_internal_operation_result list) + Lwt.t = + let[@coq_match_with_default] (Manager_operation + { + source; + operation; + gas_limit; + storage_limit; + _; + }) = + op + in + (* We do not expose the internal scaling to the users. Instead, we multiply + the specified gas limit by the internal scaling. *) + let ctxt = Gas.set_limit ctxt gas_limit in + let source = Contract.implicit_contract source in + apply_manager_operation_content + ctxt + mode + ~source + ~payer:source + ~internal:false + ~gas_consumed_in_precheck + ~chain_id + operation + >>= function + | Ok (ctxt, operation_results, internal_operations) -> ( + apply_internal_manager_operations + ctxt + mode + ~payer:source + ~chain_id + internal_operations + >>= function + | (Success ctxt, internal_operations_results) -> ( + burn_storage_fees ctxt operation_results ~storage_limit ~payer:source + >>= function + | Ok (ctxt, storage_limit, operation_results) -> ( + List.fold_left_es + (fun (ctxt, storage_limit, res) iopr -> + let (Internal_operation_result (op, mopr)) = iopr in + match mopr with + | Applied smopr -> + burn_storage_fees ctxt smopr ~storage_limit ~payer:source + >>=? fun (ctxt, storage_limit, smopr) -> + let iopr = + Internal_operation_result (op, Applied smopr) + in + return (ctxt, storage_limit, iopr :: res) + | _ -> return (ctxt, storage_limit, iopr :: res)) + (ctxt, storage_limit, []) + internal_operations_results + >|= function + | Ok (ctxt, _, internal_operations_results) -> + ( Success ctxt, + Applied operation_results, + List.rev internal_operations_results ) + | Error errors -> + ( Failure, + Backtracked (operation_results, Some errors), + internal_operations_results )) + | Error errors -> + Lwt.return + ( Failure, + Backtracked (operation_results, Some errors), + internal_operations_results )) + | (Failure, internal_operations_results) -> + Lwt.return + (Failure, Applied operation_results, internal_operations_results)) + | Error errors -> + Lwt.return (Failure, Failed (manager_kind operation, errors), []) + +let skipped_operation_result : + type kind. kind manager_operation -> kind manager_operation_result = + function + | operation -> ( + match operation with + | Reveal _ -> + Applied + (Reveal_result {consumed_gas = Gas.Arith.zero} + : kind successful_manager_operation_result) + | _ -> Skipped (manager_kind operation)) + +let rec mark_skipped : + type kind. + payload_producer:Signature.Public_key_hash.t -> + Level.t -> + kind Kind.manager prechecked_contents_list -> + kind Kind.manager contents_result_list = + fun ~payload_producer level prechecked_contents_list -> + match[@coq_match_with_default] prechecked_contents_list with + | PrecheckedSingle + { + contents = Manager_operation {operation; _}; + result = {balance_updates; _}; + } -> + Single_result + (Manager_operation_result + { + balance_updates; + operation_result = skipped_operation_result operation; + internal_operation_results = []; + }) + | PrecheckedCons + ( { + contents = Manager_operation {operation; _}; + result = {balance_updates; _}; + }, + rest ) -> + Cons_result + ( Manager_operation_result + { + balance_updates; + operation_result = skipped_operation_result operation; + internal_operation_results = []; + }, + mark_skipped ~payload_producer level rest ) + +(** Returns an updated context, and a list of prechecked contents containing + balance updates for fees related to each manager operation in + [contents_list]. *) +let precheck_manager_contents_list ctxt contents_list ~mempool_mode = + let rec rec_precheck_manager_contents_list : + type kind. + Alpha_context.t -> + kind Kind.manager contents_list -> + (context * kind Kind.manager prechecked_contents_list) tzresult Lwt.t = + fun ctxt contents_list -> + match[@coq_match_with_default] contents_list with + | Single contents -> + precheck_manager_contents ctxt contents ~only_batch:mempool_mode + >>=? fun (ctxt, result) -> + return (ctxt, PrecheckedSingle {contents; result}) + | Cons (contents, rest) -> + precheck_manager_contents ctxt contents ~only_batch:mempool_mode + >>=? fun (ctxt, result) -> + rec_precheck_manager_contents_list ctxt rest + >>=? fun (ctxt, results_rest) -> + return (ctxt, PrecheckedCons ({contents; result}, results_rest)) + in + let ctxt = if mempool_mode then Gas.reset_block_gas ctxt else ctxt in + rec_precheck_manager_contents_list ctxt contents_list + +let check_manager_signature ctxt chain_id (op : _ Kind.manager contents_list) + raw_operation = + (* Currently, the [op] only contains one signature, so + all operations are required to be from the same manager. This may + change in the future, allowing several managers to group-sign a + sequence of transactions. *) + let check_same_manager (source, source_key) manager = + match manager with + | None -> + (* Consistency already checked by + [reveal_manager_key] in [precheck_manager_contents]. *) + ok (source, source_key) + | Some (manager, manager_key) -> + if Signature.Public_key_hash.equal source manager then + ok (source, Option.either manager_key source_key) + else error Inconsistent_sources + in + let rec find_source : + type kind. + kind Kind.manager contents_list -> + (Signature.public_key_hash * Signature.public_key option) option -> + (Signature.public_key_hash * Signature.public_key option) tzresult = + fun contents_list manager -> + let source (type kind) = function[@coq_match_with_default] + | (Manager_operation {source; operation = Reveal key; _} : + kind Kind.manager contents) -> + (source, Some key) + | Manager_operation {source; _} -> (source, None) + in + match contents_list with + | Single op -> check_same_manager (source op) manager + | Cons (op, rest) -> + check_same_manager (source op) manager >>? fun manager -> + find_source rest (Some manager) + in + find_source op None >>?= fun (source, source_key) -> + (match source_key with + | Some key -> return key + | None -> Contract.get_manager_key ctxt source) + >>=? fun public_key -> + Lwt.return (Operation.check_signature public_key chain_id raw_operation) + +let rec apply_manager_contents_list_rec : + type kind. + Alpha_context.t -> + Script_ir_translator.unparsing_mode -> + payload_producer:public_key_hash -> + Chain_id.t -> + kind Kind.manager prechecked_contents_list -> + (success_or_failure * kind Kind.manager contents_result_list) Lwt.t = + fun ctxt mode ~payload_producer chain_id prechecked_contents_list -> + let level = Level.current ctxt in + match[@coq_match_with_default] prechecked_contents_list with + | PrecheckedSingle + { + contents = Manager_operation _ as op; + result = {consumed_gas; balance_updates}; + } -> + apply_manager_contents + ctxt + mode + chain_id + ~gas_consumed_in_precheck:(Some consumed_gas) + op + >|= fun (ctxt_result, operation_result, internal_operation_results) -> + let result = + Manager_operation_result + {balance_updates; operation_result; internal_operation_results} + in + (ctxt_result, Single_result result) + | PrecheckedCons + ( { + contents = Manager_operation _ as op; + result = {consumed_gas; balance_updates}; + }, + rest ) -> ( + apply_manager_contents + ctxt + mode + chain_id + ~gas_consumed_in_precheck:(Some consumed_gas) + op + >>= function + | (Failure, operation_result, internal_operation_results) -> + let result = + Manager_operation_result + {balance_updates; operation_result; internal_operation_results} + in + Lwt.return + ( Failure, + Cons_result (result, mark_skipped ~payload_producer level rest) ) + | (Success ctxt, operation_result, internal_operation_results) -> + let result = + Manager_operation_result + {balance_updates; operation_result; internal_operation_results} + in + apply_manager_contents_list_rec + ctxt + mode + ~payload_producer + chain_id + rest + >|= fun (ctxt_result, results) -> + (ctxt_result, Cons_result (result, results))) + +let mark_backtracked results = + let rec mark_contents_list : + type kind. + kind Kind.manager contents_result_list -> + kind Kind.manager contents_result_list = function + | Single_result (Manager_operation_result op) -> + Single_result + (Manager_operation_result + { + balance_updates = op.balance_updates; + operation_result = + mark_manager_operation_result op.operation_result; + internal_operation_results = + List.map + mark_internal_operation_results + op.internal_operation_results; + }) + | Cons_result (Manager_operation_result op, rest) -> + Cons_result + ( Manager_operation_result + { + balance_updates = op.balance_updates; + operation_result = + mark_manager_operation_result op.operation_result; + internal_operation_results = + List.map + mark_internal_operation_results + op.internal_operation_results; + }, + mark_contents_list rest ) + and mark_internal_operation_results (Internal_operation_result (kind, result)) + = + Internal_operation_result (kind, mark_manager_operation_result result) + and mark_manager_operation_result : + type kind. kind manager_operation_result -> kind manager_operation_result + = function + | (Failed _ | Skipped _ | Backtracked _) as result -> result + | Applied (Reveal_result _) as result -> result + | Applied result -> Backtracked (result, None) + in + mark_contents_list results + [@@coq_axiom_with_reason "non-top-level mutual recursion"] + +type apply_mode = + | Application of { + predecessor_block : Block_hash.t; + payload_hash : Block_payload_hash.t; + locked_round : Round.t option; + predecessor_level : Level.t; + predecessor_round : Round.t; + round : Round.t; + } (* Both partial and normal *) + | Full_construction of { + predecessor_block : Block_hash.t; + payload_hash : Block_payload_hash.t; + predecessor_level : Level.t; + predecessor_round : Round.t; + round : Round.t; + } + | Partial_construction of { + predecessor_level : Level.t; + predecessor_round : Round.t; + grand_parent_round : Round.t; + } + +let get_predecessor_level = function + | Application {predecessor_level; _} + | Full_construction {predecessor_level; _} + | Partial_construction {predecessor_level; _} -> + predecessor_level + +let record_operation (type kind) ctxt (operation : kind operation) : context = + match operation.protocol_data.contents with + | Single (Preendorsement _) -> ctxt + | Single (Endorsement _) -> ctxt + | Single + ( Failing_noop _ | Proposals _ | Ballot _ | Seed_nonce_revelation _ + | Double_endorsement_evidence _ | Double_preendorsement_evidence _ + | Double_baking_evidence _ | Activate_account _ | Manager_operation _ ) + | Cons (Manager_operation _, _) -> + let hash = Operation.hash operation in + record_non_consensus_operation_hash ctxt hash + +type 'consensus_op_kind expected_consensus_content = { + payload_hash : Block_payload_hash.t; + branch : Block_hash.t; + level : Level.t; + round : Round.t; +} + +(* The [Alpha_context] is modified only in [Full_construction] mode + when we check a preendorsement if the [preendorsement_quorum_round] + was not set. *) +let compute_expected_consensus_content (type consensus_op_kind) + ~(current_level : Level.t) ~(proposal_level : Level.t) + (ctxt : Alpha_context.t) (application_mode : apply_mode) + (operation_kind : consensus_op_kind consensus_operation_type) + (operation_round : Round.t) (operation_level : Raw_level.t) : + (Alpha_context.t * consensus_op_kind expected_consensus_content) tzresult + Lwt.t = + match operation_kind with + | Endorsement -> ( + match Consensus.endorsement_branch ctxt with + | None -> ( + match application_mode with + | Application _ | Full_construction _ -> + fail Unexpected_endorsement_in_block + | Partial_construction _ -> + fail + (Consensus_operation_for_future_level + {expected = proposal_level.level; provided = operation_level}) + ) + | Some (branch, payload_hash) -> ( + match application_mode with + | Application {predecessor_round; _} + | Full_construction {predecessor_round; _} + | Partial_construction {predecessor_round; _} -> + return + ( ctxt, + { + payload_hash; + branch; + level = proposal_level; + round = predecessor_round; + } ))) + | Preendorsement -> ( + match application_mode with + | Application {locked_round = None; _} -> + fail Unexpected_preendorsement_in_block + | Application + { + payload_hash; + predecessor_block = branch; + locked_round = Some locked_round; + _; + } -> + return + ( ctxt, + { + payload_hash; + branch; + level = current_level; + round = locked_round; + } ) + | Partial_construction {predecessor_round; _} -> ( + match Consensus.endorsement_branch ctxt with + | None -> + fail + (Consensus_operation_for_future_level + {expected = proposal_level.level; provided = operation_level}) + | Some (branch, payload_hash) -> + return + ( ctxt, + { + payload_hash; + branch; + level = proposal_level; + round = predecessor_round; + } )) + | Full_construction {payload_hash; predecessor_block = branch; _} -> + let (ctxt', round) = + match Consensus.get_preendorsements_quorum_round ctxt with + | None -> + ( Consensus.set_preendorsements_quorum_round ctxt operation_round, + operation_round ) + | Some round -> (ctxt, round) + in + return (ctxt', {payload_hash; branch; level = current_level; round})) + +let check_level (apply_mode : apply_mode) ~expected ~provided = + match apply_mode with + | Application _ | Full_construction _ -> + error_unless + (Raw_level.equal expected provided) + (Wrong_level_for_consensus_operation {expected; provided}) + | Partial_construction _ -> + (* Valid grand parent's endorsements were treated by + [validate_grand_parent_endorsement]. *) + error_when + Raw_level.(expected > provided) + (Consensus_operation_for_old_level {expected; provided}) + >>? fun () -> + error_when + Raw_level.(expected < provided) + (Consensus_operation_for_future_level {expected; provided}) + +let check_payload_hash (apply_mode : apply_mode) ~expected ~provided = + match apply_mode with + | Application _ | Full_construction _ -> + error_unless + (Block_payload_hash.equal expected provided) + (Wrong_payload_hash_for_consensus_operation {expected; provided}) + | Partial_construction _ -> + error_unless + (Block_payload_hash.equal expected provided) + (Consensus_operation_on_competing_proposal {expected; provided}) + +let check_operation_branch ~expected ~provided = + error_unless + (Block_hash.equal expected provided) + (Wrong_consensus_operation_branch (expected, provided)) + +let check_round (type kind) (operation_kind : kind consensus_operation_type) + (apply_mode : apply_mode) ~(expected : Round.t) ~(provided : Round.t) : + unit tzresult = + match apply_mode with + | Partial_construction _ -> + error_when + Round.(expected > provided) + (Consensus_operation_for_old_round {expected; provided}) + >>? fun () -> + error_when + Round.(expected < provided) + (Consensus_operation_for_future_round {expected; provided}) + | Full_construction {round; _} | Application {round; _} -> + (match operation_kind with + | Preendorsement -> + error_when + Round.(round <= provided) + (Preendorsement_round_too_high {block_round = round; provided}) + | Endorsement -> Result.return_unit) + >>? fun () -> + error_unless + (Round.equal expected provided) + (Wrong_round_for_consensus_operation {expected; provided}) + +let check_consensus_content (type kind) (apply_mode : apply_mode) + (content : consensus_content) (operation_branch : Block_hash.t) + (operation_kind : kind consensus_operation_type) + (expected_content : kind expected_consensus_content) : unit tzresult = + let expected_level = expected_content.level.level in + let provided_level = content.level in + let expected_round = expected_content.round in + let provided_round = content.round in + check_level apply_mode ~expected:expected_level ~provided:provided_level + >>? fun () -> + check_round + operation_kind + apply_mode + ~expected:expected_round + ~provided:provided_round + >>? fun () -> + check_operation_branch + ~expected:expected_content.branch + ~provided:operation_branch + >>? fun () -> + check_payload_hash + apply_mode + ~expected:expected_content.payload_hash + ~provided:content.block_payload_hash + +(* Validate the 'operation.shell.branch' field of the operation. It MUST point + to the grandfather: the block hash used in the payload_hash. Otherwise we could produce + a preendorsement pointing to the direct proposal. This preendorsement wouldn't be able to + propagate for a subsequent proposal using it as a locked_round evidence. *) +let validate_consensus_contents (type kind) ctxt chain_id + (operation_kind : kind consensus_operation_type) + (operation : kind operation) (apply_mode : apply_mode) + (content : consensus_content) : + (context * public_key_hash * int) tzresult Lwt.t = + let current_level = Level.current ctxt in + let proposal_level = get_predecessor_level apply_mode in + let slot_map = + match operation_kind with + | Preendorsement -> Consensus.allowed_preendorsements ctxt + | Endorsement -> Consensus.allowed_endorsements ctxt + in + compute_expected_consensus_content + ~current_level + ~proposal_level + ctxt + apply_mode + operation_kind + content.round + content.level + >>=? fun (ctxt, expected_content) -> + check_consensus_content + apply_mode + content + operation.shell.branch + operation_kind + expected_content + >>?= fun () -> + match Slot.Map.find content.slot slot_map with + | None -> fail Wrong_slot_used_for_consensus_operation + | Some (delegate_pk, delegate_pkh, voting_power) -> + Delegate.frozen_deposits ctxt delegate_pkh >>=? fun frozen_deposits -> + fail_unless + Tez.(frozen_deposits.current_amount > zero) + (Zero_frozen_deposits delegate_pkh) + >>=? fun () -> + Operation.check_signature delegate_pk chain_id operation >>?= fun () -> + return (ctxt, delegate_pkh, voting_power) + +let apply_manager_contents_list ctxt mode ~payload_producer chain_id + prechecked_contents_list = + apply_manager_contents_list_rec + ctxt + mode + ~payload_producer + chain_id + prechecked_contents_list + >>= fun (ctxt_result, results) -> + match ctxt_result with + | Failure -> Lwt.return (ctxt (* backtracked *), mark_backtracked results) + | Success ctxt -> + Lazy_storage.cleanup_temporaries ctxt >|= fun ctxt -> (ctxt, results) + +let check_denunciation_age ctxt kind given_level = + let max_slashing_period = Constants.max_slashing_period ctxt in + let current_cycle = (Level.current ctxt).cycle in + let given_cycle = (Level.from_raw ctxt given_level).cycle in + let last_slashable_cycle = Cycle.add given_cycle max_slashing_period in + fail_when + Cycle.(given_cycle > current_cycle) + (Too_early_denunciation + {kind; level = given_level; current = (Level.current ctxt).level}) + >>=? fun () -> + fail_unless + Cycle.(last_slashable_cycle > current_cycle) + (Outdated_denunciation + {kind; level = given_level; last_cycle = last_slashable_cycle}) + +let punish_delegate ctxt delegate level mistake mk_result ~payload_producer = + let (already_slashed, punish) = + match mistake with + | `Double_baking -> + ( Delegate.already_slashed_for_double_baking, + Delegate.punish_double_baking ) + | `Double_endorsing -> + ( Delegate.already_slashed_for_double_endorsing, + Delegate.punish_double_endorsing ) + in + already_slashed ctxt delegate level >>=? fun slashed -> + fail_when slashed Unrequired_denunciation >>=? fun () -> + punish ctxt delegate level >>=? fun (ctxt, burned, punish_balance_updates) -> + (match Tez.(burned /? 2L) with + | Ok reward -> + Token.transfer + ctxt + `Double_signing_evidence_rewards + (`Contract (Contract.implicit_contract payload_producer)) + reward + | Error _ -> (* reward is Tez.zero *) return (ctxt, [])) + >|=? fun (ctxt, reward_balance_updates) -> + let balance_updates = reward_balance_updates @ punish_balance_updates in + (ctxt, Single_result (mk_result balance_updates)) + +let punish_double_endorsement_or_preendorsement (type kind) ctxt ~chain_id + ~preendorsement ~(op1 : kind Kind.consensus Operation.t) + ~(op2 : kind Kind.consensus Operation.t) ~payload_producer : + (t * kind Kind.double_consensus_operation_evidence contents_result_list) + tzresult + Lwt.t = + let mk_result (balance_updates : Receipt.balance_updates) : + kind Kind.double_consensus_operation_evidence contents_result = + match op1.protocol_data.contents with + | Single (Preendorsement _) -> + Double_preendorsement_evidence_result balance_updates + | Single (Endorsement _) -> + Double_endorsement_evidence_result balance_updates + in + match (op1.protocol_data.contents, op2.protocol_data.contents) with + | (Single (Preendorsement e1), Single (Preendorsement e2)) + | (Single (Endorsement e1), Single (Endorsement e2)) -> + let kind = if preendorsement then Preendorsement else Endorsement in + let op1_hash = Operation.hash op1 in + let op2_hash = Operation.hash op2 in + fail_unless + (Raw_level.(e1.level = e2.level) + && Round.(e1.round = e2.round) + && (not + (Block_payload_hash.equal + e1.block_payload_hash + e2.block_payload_hash)) + && (* we require an order on hashes to avoid the existence of + equivalent evidences *) + Operation_hash.(op1_hash < op2_hash)) + (Invalid_denunciation kind) + >>=? fun () -> + (* Disambiguate: levels are equal *) + let level = Level.from_raw ctxt e1.level in + check_denunciation_age ctxt kind level.level >>=? fun () -> + Stake_distribution.slot_owner ctxt level e1.slot + >>=? fun (ctxt, (delegate1_pk, delegate1)) -> + Stake_distribution.slot_owner ctxt level e2.slot + >>=? fun (ctxt, (_delegate2_pk, delegate2)) -> + fail_unless + (Signature.Public_key_hash.equal delegate1 delegate2) + (Inconsistent_denunciation {kind; delegate1; delegate2}) + >>=? fun () -> + let (delegate_pk, delegate) = (delegate1_pk, delegate1) in + Operation.check_signature delegate_pk chain_id op1 >>?= fun () -> + Operation.check_signature delegate_pk chain_id op2 >>?= fun () -> + punish_delegate + ctxt + delegate + level + `Double_endorsing + mk_result + ~payload_producer + +let punish_double_baking ctxt chain_id bh1 bh2 ~payload_producer = + let hash1 = Block_header.hash bh1 in + let hash2 = Block_header.hash bh2 in + Fitness.from_raw bh1.shell.fitness >>?= fun bh1_fitness -> + let round1 = Fitness.round bh1_fitness in + Fitness.from_raw bh2.shell.fitness >>?= fun bh2_fitness -> + let round2 = Fitness.round bh2_fitness in + ( Raw_level.of_int32 bh1.shell.level >>?= fun level1 -> + Raw_level.of_int32 bh2.shell.level >>?= fun level2 -> + fail_unless + (Compare.Int32.(bh1.shell.level = bh2.shell.level) + && Round.(round1 = round2) + && (* we require an order on hashes to avoid the existence of + equivalent evidences *) + Block_hash.(hash1 < hash2)) + (Invalid_double_baking_evidence + {hash1; level1; round1; hash2; level2; round2}) ) + >>=? fun () -> + Raw_level.of_int32 bh1.shell.level >>?= fun raw_level -> + check_denunciation_age ctxt Block raw_level >>=? fun () -> + let level = Level.from_raw ctxt raw_level in + let committee_size = Constants.consensus_committee_size ctxt in + Round.to_slot round1 ~committee_size >>?= fun slot1 -> + Stake_distribution.slot_owner ctxt level slot1 + >>=? fun (ctxt, (delegate1_pk, delegate1)) -> + Round.to_slot round2 ~committee_size >>?= fun slot2 -> + Stake_distribution.slot_owner ctxt level slot2 + >>=? fun (ctxt, (_delegate2_pk, delegate2)) -> + fail_unless + Signature.Public_key_hash.(delegate1 = delegate2) + (Inconsistent_denunciation {kind = Block; delegate1; delegate2}) + >>=? fun () -> + let (delegate_pk, delegate) = (delegate1_pk, delegate1) in + Block_header.check_signature bh1 chain_id delegate_pk >>?= fun () -> + Block_header.check_signature bh2 chain_id delegate_pk >>?= fun () -> + punish_delegate + ctxt + delegate + level + `Double_baking + ~payload_producer + (fun balance_updates -> Double_baking_evidence_result balance_updates) + +let is_parent_endorsement ctxt ~proposal_level ~grand_parent_round + (operation : 'a operation) (operation_content : consensus_content) = + match Consensus.grand_parent_branch ctxt with + | None -> false + | Some (great_grand_parent_hash, grand_parent_payload_hash) -> + (* Check level *) + Raw_level.(proposal_level.Level.level = succ operation_content.level) + (* Check round *) + && Round.(grand_parent_round = operation_content.round) + (* Check payload *) + && Block_payload_hash.( + grand_parent_payload_hash = operation_content.block_payload_hash) + && (* Check branch *) + Block_hash.(great_grand_parent_hash = operation.shell.branch) + +let validate_grand_parent_endorsement ctxt chain_id + (op : Kind.endorsement operation) = + match op.protocol_data.contents with + | Single (Endorsement e) -> + let level = Level.from_raw ctxt e.level in + Stake_distribution.slot_owner ctxt level e.slot + >>=? fun (ctxt, (delegate_pk, pkh)) -> + Operation.check_signature delegate_pk chain_id op >>?= fun () -> + Consensus.record_grand_parent_endorsement ctxt pkh >>?= fun ctxt -> + return + ( ctxt, + Single_result + (Endorsement_result + { + balance_updates = []; + delegate = pkh; + endorsement_power = + 0 (* dummy endorsement power: this will never be used *); + }) ) + +let apply_contents_list (type kind) ctxt chain_id (apply_mode : apply_mode) mode + ~payload_producer (operation : kind operation) + (contents_list : kind contents_list) : + (context * kind contents_result_list) tzresult Lwt.t = + let mempool_mode = + match apply_mode with + | Partial_construction _ -> true + | Full_construction _ | Application _ -> false + in + match[@coq_match_with_default] contents_list with + | Single (Preendorsement consensus_content) -> + validate_consensus_contents + ctxt + chain_id + Preendorsement + operation + apply_mode + consensus_content + >>=? fun (ctxt, delegate, voting_power) -> + Consensus.record_preendorsement + ctxt + ~initial_slot:consensus_content.slot + ~power:voting_power + consensus_content.round + >>?= fun ctxt -> + return + ( ctxt, + Single_result + (Preendorsement_result + { + balance_updates = []; + delegate; + preendorsement_power = voting_power; + }) ) + | Single (Endorsement consensus_content) -> ( + let proposal_level = get_predecessor_level apply_mode in + match apply_mode with + | Partial_construction {grand_parent_round; _} + when is_parent_endorsement + ctxt + ~proposal_level + ~grand_parent_round + operation + consensus_content -> + validate_grand_parent_endorsement ctxt chain_id operation + | _ -> + validate_consensus_contents + ctxt + chain_id + Endorsement + operation + apply_mode + consensus_content + >>=? fun (ctxt, delegate, voting_power) -> + Consensus.record_endorsement + ctxt + ~initial_slot:consensus_content.slot + ~power:voting_power + >>?= fun ctxt -> + return + ( ctxt, + Single_result + (Endorsement_result + { + balance_updates = []; + delegate; + endorsement_power = voting_power; + }) )) + | Single (Seed_nonce_revelation {level; nonce}) -> + let level = Level.from_raw ctxt level in + Nonce.reveal ctxt level nonce >>=? fun ctxt -> + let tip = Constants.seed_nonce_revelation_tip ctxt in + let contract = Contract.implicit_contract payload_producer in + Token.transfer ctxt `Revelation_rewards (`Contract contract) tip + >|=? fun (ctxt, balance_updates) -> + (ctxt, Single_result (Seed_nonce_revelation_result balance_updates)) + | Single (Double_preendorsement_evidence {op1; op2}) -> + punish_double_endorsement_or_preendorsement + ctxt + ~preendorsement:true + ~chain_id + ~op1 + ~op2 + ~payload_producer + | Single (Double_endorsement_evidence {op1; op2}) -> + punish_double_endorsement_or_preendorsement + ctxt + ~preendorsement:false + ~chain_id + ~op1 + ~op2 + ~payload_producer + | Single (Double_baking_evidence {bh1; bh2}) -> + punish_double_baking ctxt chain_id bh1 bh2 ~payload_producer + | Single (Activate_account {id = pkh; activation_code}) -> + let blinded_pkh = + Blinded_public_key_hash.of_ed25519_pkh activation_code pkh + in + let src = `Collected_commitments blinded_pkh in + Token.allocated ctxt src >>=? fun src_exists -> + fail_unless src_exists (Invalid_activation {pkh}) >>=? fun _ -> + let contract = Contract.implicit_contract (Signature.Ed25519 pkh) in + Token.balance ctxt src >>=? fun amount -> + Token.transfer ctxt src (`Contract contract) amount + >>=? fun (ctxt, bupds) -> + return (ctxt, Single_result (Activate_account_result bupds)) + | Single (Proposals {source; period; proposals}) -> + Delegate.pubkey ctxt source >>=? fun delegate -> + Operation.check_signature delegate chain_id operation >>?= fun () -> + Voting_period.get_current ctxt >>=? fun {index = current_period; _} -> + error_unless + Compare.Int32.(current_period = period) + (Wrong_voting_period (current_period, period)) + >>?= fun () -> + Amendment.record_proposals ctxt source proposals >|=? fun ctxt -> + (ctxt, Single_result Proposals_result) + | Single (Ballot {source; period; proposal; ballot}) -> + Delegate.pubkey ctxt source >>=? fun delegate -> + Operation.check_signature delegate chain_id operation >>?= fun () -> + Voting_period.get_current ctxt >>=? fun {index = current_period; _} -> + error_unless + Compare.Int32.(current_period = period) + (Wrong_voting_period (current_period, period)) + >>?= fun () -> + Amendment.record_ballot ctxt source proposal ballot >|=? fun ctxt -> + (ctxt, Single_result Ballot_result) + | Single (Failing_noop _) -> + (* Failing_noop _ always fails *) + fail Failing_noop_error + | Single (Manager_operation _) as op -> + precheck_manager_contents_list ctxt op ~mempool_mode + >>=? fun (ctxt, prechecked_contents_list) -> + check_manager_signature ctxt chain_id op operation >>=? fun () -> + apply_manager_contents_list + ctxt + mode + ~payload_producer + chain_id + prechecked_contents_list + >|= ok + | Cons (Manager_operation _, _) as op -> + precheck_manager_contents_list ctxt op ~mempool_mode + >>=? fun (ctxt, prechecked_contents_list) -> + check_manager_signature ctxt chain_id op operation >>=? fun () -> + apply_manager_contents_list + ctxt + mode + ~payload_producer + chain_id + prechecked_contents_list + >|= ok + +let apply_operation ctxt chain_id (apply_mode : apply_mode) mode + ~payload_producer hash operation = + let ctxt = Contract.init_origination_nonce ctxt hash in + let ctxt = record_operation ctxt operation in + apply_contents_list + ctxt + chain_id + apply_mode + mode + ~payload_producer + operation + operation.protocol_data.contents + >|=? fun (ctxt, result) -> + let ctxt = Gas.set_unlimited ctxt in + let ctxt = Contract.unset_origination_nonce ctxt in + (ctxt, {contents = result}) + +let may_start_new_cycle ctxt = + match Level.dawn_of_a_new_cycle ctxt with + | None -> return (ctxt, [], []) + | Some last_cycle -> + Seed.cycle_end ctxt last_cycle >>=? fun (ctxt, unrevealed) -> + Delegate.cycle_end ctxt last_cycle unrevealed + >>=? fun (ctxt, balance_updates, deactivated) -> + Bootstrap.cycle_end ctxt last_cycle >|=? fun ctxt -> + (ctxt, balance_updates, deactivated) + +let init_allowed_consensus_operations ctxt ~endorsement_level + ~preendorsement_level = + Delegate.prepare_stake_distribution ctxt >>=? fun ctxt -> + (if Level.(endorsement_level = preendorsement_level) then + Baking.endorsing_rights_by_first_slot ctxt endorsement_level + >>=? fun (ctxt, slots) -> + let consensus_operations = slots in + return (ctxt, consensus_operations, consensus_operations) + else + Baking.endorsing_rights_by_first_slot ctxt endorsement_level + >>=? fun (ctxt, endorsements_slots) -> + let endorsements = endorsements_slots in + Baking.endorsing_rights_by_first_slot ctxt preendorsement_level + >>=? fun (ctxt, preendorsements_slots) -> + let preendorsements = preendorsements_slots in + return (ctxt, endorsements, preendorsements)) + >>=? fun (ctxt, allowed_endorsements, allowed_preendorsements) -> + return + (Consensus.initialize_consensus_operation + ctxt + ~allowed_endorsements + ~allowed_preendorsements) + +let apply_liquidity_baking_subsidy ctxt ~escape_vote = + Liquidity_baking.on_subsidy_allowed + ctxt + ~escape_vote + (fun ctxt liquidity_baking_cpmm_contract -> + let ctxt = + (* We set a gas limit of 1/20th the block limit, which is ~10x + actual usage here in Granada. Gas consumed is reported in + the Transaction receipt, but not counted towards the block + limit. The gas limit is reset to unlimited at the end of + this function.*) + Gas.set_limit + ctxt + (Gas.Arith.integral_exn + (Z.div + (Gas.Arith.integral_to_z + (Constants.hard_gas_limit_per_block ctxt)) + (Z.of_int 20))) + in + let backtracking_ctxt = ctxt in + (let liquidity_baking_subsidy = Constants.liquidity_baking_subsidy ctxt in + (* credit liquidity baking subsidy to CPMM contract *) + Token.transfer + ~origin:Subsidy + ctxt + `Liquidity_baking_subsidies + (`Contract liquidity_baking_cpmm_contract) + liquidity_baking_subsidy + >>=? fun (ctxt, balance_updates) -> + Script_cache.find ctxt liquidity_baking_cpmm_contract + >>=? fun (ctxt, cache_key, script) -> + match script with + | None -> fail (Script_tc_errors.No_such_entrypoint "default") + | Some (script, script_ir) -> ( + let now = Script_timestamp.now ctxt in + let level = + (Level.current ctxt).level |> Raw_level.to_int32 + |> Script_int.of_int32 |> Script_int.abs + in + let step_constants = + let open Script_interpreter in + (* Using dummy values for source, payer, and chain_id + since they are not used within the CPMM default + entrypoint. *) + { + source = liquidity_baking_cpmm_contract; + payer = liquidity_baking_cpmm_contract; + self = liquidity_baking_cpmm_contract; + amount = liquidity_baking_subsidy; + chain_id = Chain_id.zero; + now; + level; + } + in + let parameter = + Micheline.strip_locations + Michelson_v1_primitives.(Prim (0, D_Unit, [], [])) + in + (* + Call CPPM default entrypoint with parameter Unit. + This is necessary for the CPMM's xtz_pool in storage to + increase since it cannot use BALANCE due to a transfer attack. + + Mimicks a transaction. + + There is no: + - storage burn (extra storage is free) + - fees (the operation is mandatory) + *) + Script_interpreter.execute + ctxt + Optimized + step_constants + ~script + ~parameter + ~cached_script:(Some script_ir) + ~entrypoint:"default" + ~internal:false + >>=? fun ( {ctxt; storage; lazy_storage_diff; operations}, + (updated_cached_script, updated_size) ) -> + match operations with + | _ :: _ -> + (* No internal operations are expected here. Something bad may be happening. *) + return (backtracking_ctxt, []) + | [] -> + (* update CPMM storage *) + Contract.update_script_storage + ctxt + liquidity_baking_cpmm_contract + storage + lazy_storage_diff + >>=? fun ctxt -> + Fees.record_paid_storage_space + ctxt + liquidity_baking_cpmm_contract + >>=? fun (ctxt, new_size, paid_storage_size_diff) -> + let consumed_gas = + Gas.consumed ~since:backtracking_ctxt ~until:ctxt + in + Script_cache.update + ctxt + cache_key + ( {script with storage = Script.lazy_expr storage}, + updated_cached_script ) + updated_size + >>?= fun ctxt -> + let result = + Transaction_result + { + storage = Some storage; + lazy_storage_diff; + balance_updates; + (* At this point in application the origination nonce has not been initialized so it's not possible to originate new contracts. We've checked above that none were originated. *) + originated_contracts = []; + consumed_gas; + storage_size = new_size; + paid_storage_size_diff; + allocated_destination_contract = false; + } + in + let ctxt = Gas.set_unlimited ctxt in + return (ctxt, [Successful_manager_result result]))) + >|= function + | Ok (ctxt, results) -> Ok (ctxt, results) + | Error _ -> + (* Do not fail if something bad happens during CPMM contract call. *) + let ctxt = Gas.set_unlimited backtracking_ctxt in + Ok (ctxt, [])) + +type 'a full_construction = { + ctxt : t; + protocol_data : 'a; + payload_producer : Signature.public_key_hash; + block_producer : Signature.public_key_hash; + round : Round.t; + implicit_operations_results : packed_successful_manager_operation_result list; + liquidity_baking_escape_ema : Liquidity_baking.escape_ema; +} + +let begin_full_construction ctxt ~predecessor_timestamp ~predecessor_level + ~predecessor_round ~round protocol_data = + let round_durations = Constants.round_durations ctxt in + let timestamp = Timestamp.current ctxt in + Block_header.check_timestamp + round_durations + ~timestamp + ~round + ~predecessor_timestamp + ~predecessor_round + >>?= fun () -> + let current_level = Level.current ctxt in + Stake_distribution.baking_rights_owner ctxt current_level ~round + >>=? fun (ctxt, _slot, (_block_producer_pk, block_producer)) -> + Delegate.frozen_deposits ctxt block_producer >>=? fun frozen_deposits -> + fail_unless + Tez.(frozen_deposits.current_amount > zero) + (Zero_frozen_deposits block_producer) + >>=? fun () -> + Stake_distribution.baking_rights_owner + ctxt + current_level + ~round:protocol_data.Block_header.payload_round + >>=? fun (ctxt, _slot, (_payload_producer_pk, payload_producer)) -> + init_allowed_consensus_operations + ctxt + ~endorsement_level:predecessor_level + ~preendorsement_level:current_level + >>=? fun ctxt -> + let escape_vote = protocol_data.liquidity_baking_escape_vote in + apply_liquidity_baking_subsidy ctxt ~escape_vote + >|=? fun ( ctxt, + liquidity_baking_operations_results, + liquidity_baking_escape_ema ) -> + { + ctxt; + protocol_data; + payload_producer; + block_producer; + round; + implicit_operations_results = liquidity_baking_operations_results; + liquidity_baking_escape_ema; + } + +let begin_partial_construction ctxt ~predecessor_level ~escape_vote = + (* In the mempool, only consensus operations for [predecessor_level] + (that is, head's level) are allowed, contrary to block validation + where endorsements are for the previous level and + preendorsements, if any, for the block's level. *) + init_allowed_consensus_operations + ctxt + ~endorsement_level:predecessor_level + ~preendorsement_level:predecessor_level + >>=? fun ctxt -> apply_liquidity_baking_subsidy ctxt ~escape_vote + +let begin_application ctxt chain_id (block_header : Block_header.t) fitness + ~predecessor_timestamp ~predecessor_level ~predecessor_round = + let round = Fitness.round fitness in + let current_level = Level.current ctxt in + Stake_distribution.baking_rights_owner ctxt current_level ~round + >>=? fun (ctxt, _slot, (block_producer_pk, block_producer)) -> + let round_durations = Constants.round_durations ctxt in + let timestamp = block_header.shell.timestamp in + Block_header.begin_validate_block_header + ~block_header + ~chain_id + ~predecessor_timestamp + ~predecessor_round + ~fitness + ~timestamp + ~delegate_pk:block_producer_pk + ~round_durations + ~proof_of_work_threshold:(Constants.proof_of_work_threshold ctxt) + ~expected_commitment:current_level.expected_commitment + >>?= fun () -> + Delegate.frozen_deposits ctxt block_producer >>=? fun frozen_deposits -> + fail_unless + Tez.(frozen_deposits.current_amount > zero) + (Zero_frozen_deposits block_producer) + >>=? fun () -> + Stake_distribution.baking_rights_owner + ctxt + current_level + ~round:block_header.protocol_data.contents.payload_round + >>=? fun (ctxt, _slot, (payload_producer_pk, _payload_producer)) -> + init_allowed_consensus_operations + ctxt + ~endorsement_level:predecessor_level + ~preendorsement_level:current_level + >>=? fun ctxt -> + let escape_vote = + block_header.Block_header.protocol_data.contents + .liquidity_baking_escape_vote + in + apply_liquidity_baking_subsidy ctxt ~escape_vote + >|=? fun ( ctxt, + liquidity_baking_operations_results, + liquidity_baking_escape_ema ) -> + ( ctxt, + payload_producer_pk, + block_producer, + liquidity_baking_operations_results, + liquidity_baking_escape_ema ) + +type finalize_application_mode = + | Finalize_full_construction of { + level : Raw_level.t; + predecessor_round : Round.t; + } + | Finalize_application of Fitness.t + +let compute_payload_hash (ctxt : Alpha_context.t) ~(predecessor : Block_hash.t) + ~(payload_round : Round.t) : Block_payload_hash.t = + let non_consensus_operations = non_consensus_operations ctxt in + let operations_hash = Operation_list_hash.compute non_consensus_operations in + Block_payload.hash ~predecessor payload_round operations_hash + +let are_endorsements_required ctxt ~level = + Alpha_context.First_level_of_tenderbake.get ctxt + >|=? fun first_Tenderbake_level -> + (* NB: the first level is the level of the migration block. This + block was proposed by an Emmy* baker. There are no + endorsements for this block. Therefore the block at the next + level cannot contain endorsements. *) + let tenderbake_level_position = Raw_level.diff level first_Tenderbake_level in + Compare.Int32.(tenderbake_level_position > 1l) + +let check_minimum_endorsements ~endorsing_power ~minimum = + fail_when + Compare.Int.(endorsing_power < minimum) + (Not_enough_endorsements + {required = minimum; endorsements = endorsing_power}) + +let finalize_application_check_validity ctxt (mode : finalize_application_mode) + protocol_data ~round ~predecessor ~endorsing_power ~consensus_threshold + ~required_endorsements = + (if required_endorsements then + check_minimum_endorsements ~endorsing_power ~minimum:consensus_threshold + else return_unit) + >>=? fun () -> + let block_payload_hash = + compute_payload_hash + ctxt + ~predecessor + ~payload_round:protocol_data.Block_header.payload_round + in + let locked_round_evidence = + Option.map + (fun (preendorsement_round, preendorsement_count) -> + Block_header.{preendorsement_round; preendorsement_count}) + (Consensus.locked_round_evidence ctxt) + in + (match mode with + | Finalize_application fitness -> ok fitness + | Finalize_full_construction {level; predecessor_round} -> + let locked_round = + match locked_round_evidence with + | None -> None + | Some {preendorsement_round; _} -> Some preendorsement_round + in + Fitness.create ~level ~round ~predecessor_round ~locked_round) + >>?= fun fitness -> + let checkable_payload_hash : Block_header.checkable_payload_hash = + match mode with + | Finalize_application _ -> Expected_payload_hash block_payload_hash + | Finalize_full_construction _ -> ( + match locked_round_evidence with + | Some _ -> Expected_payload_hash block_payload_hash + | None -> + (* In full construction, when there is no locked round + evidence (and thus no preendorsements), the baker cannot + know the payload hash before selecting the operations. We + may dismiss checking the initially given + payload_hash. However, to be valid, the baker must patch + the resulting block header with the actual payload + hash. *) + No_check) + in + Block_header.finalize_validate_block_header + ~block_header_contents:protocol_data + ~round + ~fitness + ~checkable_payload_hash + ~locked_round_evidence + ~consensus_threshold + >>?= fun () -> return (fitness, block_payload_hash) + +let record_endorsing_participation ctxt = + let validators = Consensus.allowed_endorsements ctxt in + Slot.Map.fold_es + (fun initial_slot (_delegate_pk, delegate, power) ctxt -> + let participation = + if Slot.Set.mem initial_slot (Consensus.endorsements_seen ctxt) then + Delegate.Participated + else Delegate.Didn't_participate + in + Delegate.record_endorsing_participation + ctxt + ~delegate + ~participation + ~endorsing_power:power) + validators + ctxt + +let finalize_application ctxt (mode : finalize_application_mode) protocol_data + ~payload_producer ~block_producer liquidity_baking_escape_ema + implicit_operations_results ~round ~predecessor ~migration_balance_updates = + let level = Alpha_context.Level.current ctxt in + let block_endorsing_power = Consensus.current_endorsement_power ctxt in + let consensus_threshold = Constants.consensus_threshold ctxt in + are_endorsements_required ctxt ~level:level.level + >>=? fun required_endorsements -> + finalize_application_check_validity + ctxt + mode + protocol_data + ~round + ~predecessor + ~endorsing_power:block_endorsing_power + ~consensus_threshold + ~required_endorsements + >>=? fun (fitness, block_payload_hash) -> + (* from this point nothing should fail *) + (* We mark the endorsement branch as the grand parent branch when + accessible. This will not be present before the first two blocks + of tenderbake. *) + (match Consensus.endorsement_branch ctxt with + | Some predecessor_branch -> + Consensus.store_grand_parent_branch ctxt predecessor_branch >>= return + | None -> return ctxt) + >>=? fun ctxt -> + (* We mark the current payload hash as the predecessor one => this + will only be accessed by the successor block now. *) + Consensus.store_endorsement_branch ctxt (predecessor, block_payload_hash) + >>= fun ctxt -> + Round.update ctxt round >>=? fun ctxt -> + (* end of level *) + (match protocol_data.Block_header.seed_nonce_hash with + | None -> return ctxt + | Some nonce_hash -> + Nonce.record_hash ctxt {nonce_hash; delegate = block_producer}) + >>=? fun ctxt -> + (if required_endorsements then + record_endorsing_participation ctxt >>=? fun ctxt -> + Baking.bonus_baking_reward ctxt ~endorsing_power:block_endorsing_power + >>?= fun rewards_bonus -> return (ctxt, Some rewards_bonus) + else return (ctxt, None)) + >>=? fun (ctxt, reward_bonus) -> + let baking_reward = Constants.baking_reward_fixed_portion ctxt in + Delegate.record_baking_activity_and_pay_rewards_and_fees + ctxt + ~payload_producer + ~block_producer + ~baking_reward + ~reward_bonus + >>=? fun (ctxt, baking_receipts) -> + (* end of cycle *) + (if Level.may_snapshot_rolls ctxt then Stake_distribution.snapshot ctxt + else return ctxt) + >>=? fun ctxt -> + may_start_new_cycle ctxt + >>=? fun (ctxt, cycle_end_balance_updates, deactivated) -> + Amendment.may_start_new_voting_period ctxt >>=? fun ctxt -> + let balance_updates = + migration_balance_updates @ baking_receipts @ cycle_end_balance_updates + in + let consumed_gas = + Gas.Arith.sub + (Gas.Arith.fp @@ Constants.hard_gas_limit_per_block ctxt) + (Gas.block_level ctxt) + in + Voting_period.get_rpc_current_info ctxt >|=? fun voting_period_info -> + let receipt = + Apply_results. + { + proposer = payload_producer; + baker = block_producer; + level_info = level; + voting_period_info; + nonce_hash = protocol_data.seed_nonce_hash; + consumed_gas; + deactivated; + balance_updates; + liquidity_baking_escape_ema; + implicit_operations_results; + } + in + (ctxt, fitness, receipt) + +let value_of_key ctxt k = Cache.Admin.value_of_key ctxt k diff --git a/src/proto_012_PsiThaCa/lib_protocol/apply.mli b/src/proto_012_PsiThaCa/lib_protocol/apply.mli new file mode 100644 index 000000000000..1282375017e1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/apply.mli @@ -0,0 +1,282 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module supports advancing the ledger state by applying [operation]s. + + Each operation application takes and returns an [Alpha_context.t], representing + the old and new state, respectively. + + The [Main] module provides wrappers for the functionality in this module, + satisfying the Protocol signature. + *) + +open Alpha_context +open Apply_results + +type error += + | (* `Temporary *) + Wrong_consensus_operation_branch of + Block_hash.t * Block_hash.t + +type error += + | (* `Permanent *) + Wrong_level_for_consensus_operation of { + expected : Raw_level.t; + provided : Raw_level.t; + } + | (* `Permanent *) + Wrong_round_for_consensus_operation of { + expected : Round.t; + provided : Round.t; + } + | (* `Permanent *) + Preendorsement_round_too_high of { + block_round : Round.t; + provided : Round.t; + } + +type error += + | (* `Permanent *) Internal_operation_replay of packed_internal_operation + +type denunciation_kind = Preendorsement | Endorsement | Block + +type error += (* `Permanent *) Invalid_denunciation of denunciation_kind + +type error += + | (* `Permanent *) + Inconsistent_denunciation of { + kind : denunciation_kind; + delegate1 : Signature.Public_key_hash.t; + delegate2 : Signature.Public_key_hash.t; + } + +type error += + | (* `Temporary *) + Too_early_denunciation of { + kind : denunciation_kind; + level : Raw_level.t; + current : Raw_level.t; + } + +type error += + | (* `Permanent *) + Outdated_denunciation of { + kind : denunciation_kind; + level : Raw_level.t; + last_cycle : Cycle.t; + } + +type error += + | (* `Permanent *) + Invalid_double_baking_evidence of { + hash1 : Block_hash.t; + level1 : Raw_level.t; + round1 : Round.t; + hash2 : Block_hash.t; + level2 : Raw_level.t; + round2 : Round.t; + } + +type error += + | (* Permanent *) Invalid_activation of {pkh : Ed25519.Public_key_hash.t} + +type error += (* Permanent *) Gas_quota_exceeded_init_deserialize + +type error += (* `Permanent *) Inconsistent_sources + +type error += (* `Permanent *) Failing_noop_error + +type error += (* `Branch *) Empty_transaction of Contract.t + +val begin_partial_construction : + t -> + predecessor_level:Level.t -> + escape_vote:bool -> + ( t + * packed_successful_manager_operation_result list + * Liquidity_baking.escape_ema, + error trace ) + result + Lwt.t + +type 'a full_construction = { + ctxt : t; + protocol_data : 'a; + payload_producer : Signature.public_key_hash; + block_producer : Signature.public_key_hash; + round : Round.t; + implicit_operations_results : packed_successful_manager_operation_result list; + liquidity_baking_escape_ema : Liquidity_baking.escape_ema; +} + +val begin_full_construction : + t -> + predecessor_timestamp:Time.t -> + predecessor_level:Level.t -> + predecessor_round:Round.t -> + round:Round.t -> + Block_header.contents -> + Block_header.contents full_construction tzresult Lwt.t + +val begin_application : + t -> + Chain_id.t -> + Block_header.t -> + Fitness.t -> + predecessor_timestamp:Time.t -> + predecessor_level:Level.t -> + predecessor_round:Round.t -> + (t + * Signature.public_key + * Signature.public_key_hash + * packed_successful_manager_operation_result list + * Liquidity_baking.escape_ema) + tzresult + Lwt.t + +type apply_mode = + | Application of { + predecessor_block : Block_hash.t; + payload_hash : Block_payload_hash.t; + locked_round : Round.t option; + predecessor_level : Level.t; + predecessor_round : Round.t; + round : Round.t; + } (* Both partial and normal *) + | Full_construction of { + predecessor_block : Block_hash.t; + payload_hash : Block_payload_hash.t; + predecessor_level : Level.t; + predecessor_round : Round.t; + round : Round.t; + } + | Partial_construction of { + predecessor_level : Level.t; + predecessor_round : Round.t; + grand_parent_round : Round.t; + } + +val apply_operation : + t -> + Chain_id.t -> + apply_mode -> + Script_ir_translator.unparsing_mode -> + payload_producer:public_key_hash -> + Operation_list_hash.elt -> + 'a operation -> + (t * 'a operation_metadata, error trace) result Lwt.t + +type finalize_application_mode = + | Finalize_full_construction of { + level : Raw_level.t; + predecessor_round : Round.t; + } + | Finalize_application of Fitness.t + +val finalize_application : + t -> + finalize_application_mode -> + Alpha_context.Block_header.contents -> + payload_producer:public_key_hash -> + block_producer:public_key_hash -> + Liquidity_baking.escape_ema -> + packed_successful_manager_operation_result list -> + round:Round.t -> + predecessor:Block_hash.t -> + migration_balance_updates:Receipt.balance_updates -> + (t * Fitness.t * block_metadata, error trace) result Lwt.t + +val apply_manager_contents_list : + t -> + Script_ir_translator.unparsing_mode -> + payload_producer:public_key_hash -> + Chain_id.t -> + 'a Kind.manager prechecked_contents_list -> + (t * 'a Kind.manager contents_result_list) Lwt.t + +val apply_contents_list : + t -> + Chain_id.t -> + apply_mode -> + Script_ir_translator.unparsing_mode -> + payload_producer:public_key_hash -> + 'kind operation -> + 'kind contents_list -> + (t * 'kind contents_result_list) tzresult Lwt.t + +(** [precheck_manager_contents_list validation_state contents_list] + Returns an updated context, and a list of prechecked contents + containing balance updates for fees related to each manager + operation in [contents_list] + + If [mempool_mode], the function checks whether the total gas limit + of this batch of operation is below the [gas_limit] of a block and + fails with a permanent error when above. Otherwise, the gas limit + of the batch is removed from the one of the block (when possible) + before moving on. *) +val precheck_manager_contents_list : + t -> + 'kind Kind.manager contents_list -> + mempool_mode:bool -> + (context * 'kind Kind.manager prechecked_contents_list) tzresult Lwt.t + +(** [value_of_key ctxt k] builds a value identified by key [k] + so that it can be put into the cache. *) +val value_of_key : t -> Context.Cache.key -> Context.Cache.value tzresult Lwt.t + +(** [cache_layout] describes how the caches needed by the protocol. + The length of the list defines the number of caches while each + element of this list corresponds to the size limit of each cache. *) +val cache_layout : int list + +(** Check if endorsements are required for a given level. *) +val are_endorsements_required : t -> level:Raw_level.t -> bool tzresult Lwt.t + +(** Check if a block's endorsing power is at least the minim required. *) +val check_minimum_endorsements : + endorsing_power:int -> minimum:int -> unit tzresult Lwt.t + +(** [check_manager_signature validation_state op raw_operation] + The function starts by retrieving the public key hash [pkh] of the manager + operation. In case the operation is batched, the function also checks that + the sources are all the same. + Once the [pkh] is retrieved, the function looks for its associated public + key. For that, the manager operation is inspected to check if it contains + a public key revelation. If not, the public key is searched in the context. + + @return [Error Invalid_signature] if the signature check fails + @return [Error Unrevealed_manager_key] if the manager has not yet been + revealed + @return [Error Failure "get_manager_key"] if the key is not found in the + context + @return [Error Inconsistent_sources] if the operations in a batch are not + from the same manager *) +val check_manager_signature : + t -> + Chain_id.t -> + 'a Kind.manager contents_list -> + 'b operation -> + (unit, error trace) result Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/apply_results.ml b/src/proto_012_PsiThaCa/lib_protocol/apply_results.ml new file mode 100644 index 000000000000..db84ac9e89c4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/apply_results.ml @@ -0,0 +1,1478 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Data_encoding + +let error_encoding = + def + "error" + ~description: + "The full list of RPC errors would be too long to include.\n\ + It is available at RPC `/errors` (GET).\n\ + Errors specific to protocol Alpha have an id that starts with \ + `proto.alpha`." + @@ splitted + ~json: + (conv + (fun err -> + Data_encoding.Json.construct Error_monad.error_encoding err) + (fun json -> + Data_encoding.Json.destruct Error_monad.error_encoding json) + json) + ~binary:Error_monad.error_encoding + +let trace_encoding = make_trace_encoding error_encoding + +type _ successful_manager_operation_result = + | Reveal_result : { + consumed_gas : Gas.Arith.fp; + } + -> Kind.reveal successful_manager_operation_result + | Transaction_result : { + storage : Script.expr option; + lazy_storage_diff : Lazy_storage.diffs option; + balance_updates : Receipt.balance_updates; + originated_contracts : Contract.t list; + consumed_gas : Gas.Arith.fp; + storage_size : Z.t; + paid_storage_size_diff : Z.t; + allocated_destination_contract : bool; + } + -> Kind.transaction successful_manager_operation_result + | Origination_result : { + lazy_storage_diff : Lazy_storage.diffs option; + balance_updates : Receipt.balance_updates; + originated_contracts : Contract.t list; + consumed_gas : Gas.Arith.fp; + storage_size : Z.t; + paid_storage_size_diff : Z.t; + } + -> Kind.origination successful_manager_operation_result + | Delegation_result : { + consumed_gas : Gas.Arith.fp; + } + -> Kind.delegation successful_manager_operation_result + | Register_global_constant_result : { + balance_updates : Receipt.balance_updates; + consumed_gas : Gas.Arith.fp; + size_of_constant : Z.t; + global_address : Script_expr_hash.t; + } + -> Kind.register_global_constant successful_manager_operation_result + | Set_deposits_limit_result : { + consumed_gas : Gas.Arith.fp; + } + -> Kind.set_deposits_limit successful_manager_operation_result + +let migration_origination_result_to_successful_manager_operation_result + ({ + balance_updates; + originated_contracts; + storage_size; + paid_storage_size_diff; + } : + Migration.origination_result) = + Origination_result + { + lazy_storage_diff = None; + balance_updates; + originated_contracts; + consumed_gas = Gas.Arith.zero; + storage_size; + paid_storage_size_diff; + } + +type packed_successful_manager_operation_result = + | Successful_manager_result : + 'kind successful_manager_operation_result + -> packed_successful_manager_operation_result + +let pack_migration_operation_results results = + List.map + (fun el -> + Successful_manager_result + (migration_origination_result_to_successful_manager_operation_result el)) + results + +type 'kind manager_operation_result = + | Applied of 'kind successful_manager_operation_result + | Backtracked of + 'kind successful_manager_operation_result * error trace option + | Failed : 'kind Kind.manager * error trace -> 'kind manager_operation_result + | Skipped : 'kind Kind.manager -> 'kind manager_operation_result +[@@coq_force_gadt] + +type packed_internal_operation_result = + | Internal_operation_result : + 'kind internal_operation * 'kind manager_operation_result + -> packed_internal_operation_result + +module Manager_result = struct + type 'kind case = + | MCase : { + op_case : 'kind Operation.Encoding.Manager_operations.case; + encoding : 'a Data_encoding.t; + kind : 'kind Kind.manager; + iselect : + packed_internal_operation_result -> + ('kind internal_operation * 'kind manager_operation_result) option; + select : + packed_successful_manager_operation_result -> + 'kind successful_manager_operation_result option; + proj : 'kind successful_manager_operation_result -> 'a; + inj : 'a -> 'kind successful_manager_operation_result; + t : 'kind manager_operation_result Data_encoding.t; + } + -> 'kind case + + let make ~op_case ~encoding ~kind ~iselect ~select ~proj ~inj = + let (Operation.Encoding.Manager_operations.MCase {name; _}) = op_case in + let t = + def (Format.asprintf "operation.alpha.operation_result.%s" name) + @@ union + ~tag_size:`Uint8 + [ + case + (Tag 0) + ~title:"Applied" + (merge_objs (obj1 (req "status" (constant "applied"))) encoding) + (fun o -> + match o with + | Skipped _ | Failed _ | Backtracked _ -> None + | Applied o -> ( + match select (Successful_manager_result o) with + | None -> None + | Some o -> Some ((), proj o))) + (fun ((), x) -> Applied (inj x)); + case + (Tag 1) + ~title:"Failed" + (obj2 + (req "status" (constant "failed")) + (req "errors" trace_encoding)) + (function Failed (_, errs) -> Some ((), errs) | _ -> None) + (fun ((), errs) -> Failed (kind, errs)); + case + (Tag 2) + ~title:"Skipped" + (obj1 (req "status" (constant "skipped"))) + (function Skipped _ -> Some () | _ -> None) + (fun () -> Skipped kind); + case + (Tag 3) + ~title:"Backtracked" + (merge_objs + (obj2 + (req "status" (constant "backtracked")) + (opt "errors" trace_encoding)) + encoding) + (fun o -> + match o with + | Skipped _ | Failed _ | Applied _ -> None + | Backtracked (o, errs) -> ( + match select (Successful_manager_result o) with + | None -> None + | Some o -> Some (((), errs), proj o))) + (fun (((), errs), x) -> Backtracked (inj x, errs)); + ] + in + MCase {op_case; encoding; kind; iselect; select; proj; inj; t} + + let[@coq_axiom_with_reason "gadt"] reveal_case = + make + ~op_case:Operation.Encoding.Manager_operations.reveal_case + ~encoding: + Data_encoding.( + obj2 + (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) + (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero)) + ~iselect:(function + | Internal_operation_result (({operation = Reveal _; _} as op), res) -> + Some (op, res) + | _ -> None) + ~select:(function + | Successful_manager_result (Reveal_result _ as op) -> Some op + | _ -> None) + ~kind:Kind.Reveal_manager_kind + ~proj:(function + | Reveal_result {consumed_gas} -> + (Gas.Arith.ceil consumed_gas, consumed_gas)) + ~inj:(fun (consumed_gas, consumed_milligas) -> + assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; + Reveal_result {consumed_gas = consumed_milligas}) + + let[@coq_axiom_with_reason "gadt"] transaction_case = + make + ~op_case:Operation.Encoding.Manager_operations.transaction_case + ~encoding: + (obj10 + (opt "storage" Script.expr_encoding) + (opt + (* The field [big_map_diff] is deprecated since 008, use [lazy_storage_diff] instead. + It is kept here for a transitional period, for tools like indexers to update. *) + (* TODO: https://gitlab.com/tezos/tezos/-/issues/1948 + Remove it in 009 or later. *) + "big_map_diff" + Lazy_storage.legacy_big_map_diff_encoding) + (dft "balance_updates" Receipt.balance_updates_encoding []) + (dft "originated_contracts" (list Contract.encoding) []) + (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) + (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) + (dft "storage_size" z Z.zero) + (dft "paid_storage_size_diff" z Z.zero) + (dft "allocated_destination_contract" bool false) + (opt "lazy_storage_diff" Lazy_storage.encoding)) + ~iselect:(function + | Internal_operation_result (({operation = Transaction _; _} as op), res) + -> + Some (op, res) + | _ -> None) + ~select:(function + | Successful_manager_result (Transaction_result _ as op) -> Some op + | _ -> None) + ~kind:Kind.Transaction_manager_kind + ~proj:(function + | Transaction_result + { + storage; + lazy_storage_diff; + balance_updates; + originated_contracts; + consumed_gas; + storage_size; + paid_storage_size_diff; + allocated_destination_contract; + } -> + ( storage, + lazy_storage_diff, + balance_updates, + originated_contracts, + Gas.Arith.ceil consumed_gas, + consumed_gas, + storage_size, + paid_storage_size_diff, + allocated_destination_contract, + lazy_storage_diff )) + ~inj: + (fun ( storage, + legacy_lazy_storage_diff, + balance_updates, + originated_contracts, + consumed_gas, + consumed_milligas, + storage_size, + paid_storage_size_diff, + allocated_destination_contract, + lazy_storage_diff ) -> + assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; + let lazy_storage_diff = + Option.either lazy_storage_diff legacy_lazy_storage_diff + in + Transaction_result + { + storage; + lazy_storage_diff; + balance_updates; + originated_contracts; + consumed_gas = consumed_milligas; + storage_size; + paid_storage_size_diff; + allocated_destination_contract; + }) + + let[@coq_axiom_with_reason "gadt"] origination_case = + make + ~op_case:Operation.Encoding.Manager_operations.origination_case + ~encoding: + (obj8 + (opt + (* The field [big_map_diff] is deprecated since 008, use [lazy_storage_diff] instead. + It is kept here for a transitional period, for tools like indexers to update. *) + (* TODO: https://gitlab.com/tezos/tezos/-/issues/1948 + Remove it in 009 or later. *) + "big_map_diff" + Lazy_storage.legacy_big_map_diff_encoding) + (dft "balance_updates" Receipt.balance_updates_encoding []) + (dft "originated_contracts" (list Contract.encoding) []) + (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) + (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) + (dft "storage_size" z Z.zero) + (dft "paid_storage_size_diff" z Z.zero) + (opt "lazy_storage_diff" Lazy_storage.encoding)) + ~iselect:(function + | Internal_operation_result (({operation = Origination _; _} as op), res) + -> + Some (op, res) + | _ -> None) + ~select:(function + | Successful_manager_result (Origination_result _ as op) -> Some op + | _ -> None) + ~proj:(function + | Origination_result + { + lazy_storage_diff; + balance_updates; + originated_contracts; + consumed_gas; + storage_size; + paid_storage_size_diff; + } -> + ( lazy_storage_diff, + balance_updates, + originated_contracts, + Gas.Arith.ceil consumed_gas, + consumed_gas, + storage_size, + paid_storage_size_diff, + lazy_storage_diff )) + ~kind:Kind.Origination_manager_kind + ~inj: + (fun ( legacy_lazy_storage_diff, + balance_updates, + originated_contracts, + consumed_gas, + consumed_milligas, + storage_size, + paid_storage_size_diff, + lazy_storage_diff ) -> + assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; + let lazy_storage_diff = + Option.either lazy_storage_diff legacy_lazy_storage_diff + in + Origination_result + { + lazy_storage_diff; + balance_updates; + originated_contracts; + consumed_gas = consumed_milligas; + storage_size; + paid_storage_size_diff; + }) + + let[@coq_axiom_with_reason "gadt"] register_global_constant_case = + make + ~op_case: + Operation.Encoding.Manager_operations.register_global_constant_case + ~encoding: + (obj4 + (req "balance_updates" Receipt.balance_updates_encoding) + (req "consumed_gas" Gas.Arith.n_integral_encoding) + (req "storage_size" z) + (req "global_address" Script_expr_hash.encoding)) + ~iselect:(function + | Internal_operation_result + (({operation = Register_global_constant _; _} as op), res) -> + Some (op, res) + | _ -> None) + ~select:(function + | Successful_manager_result (Register_global_constant_result _ as op) -> + Some op + | _ -> None) + ~proj:(function + | Register_global_constant_result + {balance_updates; consumed_gas; size_of_constant; global_address} -> + (balance_updates, consumed_gas, size_of_constant, global_address)) + ~kind:Kind.Register_global_constant_manager_kind + ~inj: + (fun (balance_updates, consumed_gas, size_of_constant, global_address) -> + Register_global_constant_result + {balance_updates; consumed_gas; size_of_constant; global_address}) + + let delegation_case = + make + ~op_case:Operation.Encoding.Manager_operations.delegation_case + ~encoding: + Data_encoding.( + obj2 + (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) + (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero)) + ~iselect:(function + | Internal_operation_result (({operation = Delegation _; _} as op), res) + -> + Some (op, res) + | _ -> None) + ~select:(function + | Successful_manager_result (Delegation_result _ as op) -> Some op + | _ -> None) + ~kind:Kind.Delegation_manager_kind + ~proj:(function[@coq_match_with_default] + | Delegation_result {consumed_gas} -> + (Gas.Arith.ceil consumed_gas, consumed_gas)) + ~inj:(fun (consumed_gas, consumed_milligas) -> + assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; + Delegation_result {consumed_gas = consumed_milligas}) + + let set_deposits_limit_case = + make + ~op_case:Operation.Encoding.Manager_operations.set_deposits_limit_case + ~encoding: + Data_encoding.( + obj2 + (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) + (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero)) + ~iselect:(function + | Internal_operation_result + (({operation = Set_deposits_limit _; _} as op), res) -> + Some (op, res) + | _ -> None) + ~select:(function + | Successful_manager_result (Set_deposits_limit_result _ as op) -> + Some op + | _ -> None) + ~kind:Kind.Set_deposits_limit_manager_kind + ~proj:(function + | Set_deposits_limit_result {consumed_gas} -> + (Gas.Arith.ceil consumed_gas, consumed_gas)) + ~inj:(fun (consumed_gas, consumed_milligas) -> + assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; + Set_deposits_limit_result {consumed_gas = consumed_milligas}) +end + +let internal_operation_result_encoding : + packed_internal_operation_result Data_encoding.t = + let make (type kind) + (Manager_result.MCase res_case : kind Manager_result.case) = + let (Operation.Encoding.Manager_operations.MCase op_case) = + res_case.op_case + in + case + (Tag op_case.tag) + ~title:op_case.name + (merge_objs + (obj3 + (req "kind" (constant op_case.name)) + (req "source" Contract.encoding) + (req "nonce" uint16)) + (merge_objs op_case.encoding (obj1 (req "result" res_case.t)))) + (fun op -> + match res_case.iselect op with + | Some (op, res) -> + Some (((), op.source, op.nonce), (op_case.proj op.operation, res)) + | None -> None) + (fun (((), source, nonce), (op, res)) -> + let op = {source; operation = op_case.inj op; nonce} in + Internal_operation_result (op, res)) + in + def "operation.alpha.internal_operation_result" + @@ union + [ + make Manager_result.reveal_case; + make Manager_result.transaction_case; + make Manager_result.origination_case; + make Manager_result.delegation_case; + make Manager_result.register_global_constant_case; + make Manager_result.set_deposits_limit_case; + ] + +let successful_manager_operation_result_encoding : + packed_successful_manager_operation_result Data_encoding.t = + let make (type kind) + (Manager_result.MCase res_case : kind Manager_result.case) = + let (Operation.Encoding.Manager_operations.MCase op_case) = + res_case.op_case + in + case + (Tag op_case.tag) + ~title:op_case.name + (merge_objs (obj1 (req "kind" (constant op_case.name))) res_case.encoding) + (fun res -> + match res_case.select res with + | Some res -> Some ((), res_case.proj res) + | None -> None) + (fun ((), res) -> Successful_manager_result (res_case.inj res)) + in + def "operation.alpha.successful_manager_operation_result" + @@ union + [ + make Manager_result.reveal_case; + make Manager_result.transaction_case; + make Manager_result.origination_case; + make Manager_result.delegation_case; + make Manager_result.set_deposits_limit_case; + ] + +type 'kind contents_result = + | Preendorsement_result : { + balance_updates : Receipt.balance_updates; + delegate : Signature.Public_key_hash.t; + preendorsement_power : int; + } + -> Kind.preendorsement contents_result + | Endorsement_result : { + balance_updates : Receipt.balance_updates; + delegate : Signature.Public_key_hash.t; + endorsement_power : int; + } + -> Kind.endorsement contents_result + | Seed_nonce_revelation_result : + Receipt.balance_updates + -> Kind.seed_nonce_revelation contents_result + | Double_endorsement_evidence_result : + Receipt.balance_updates + -> Kind.double_endorsement_evidence contents_result + | Double_preendorsement_evidence_result : + Receipt.balance_updates + -> Kind.double_preendorsement_evidence contents_result + | Double_baking_evidence_result : + Receipt.balance_updates + -> Kind.double_baking_evidence contents_result + | Activate_account_result : + Receipt.balance_updates + -> Kind.activate_account contents_result + | Proposals_result : Kind.proposals contents_result + | Ballot_result : Kind.ballot contents_result + | Manager_operation_result : { + balance_updates : Receipt.balance_updates; + operation_result : 'kind manager_operation_result; + internal_operation_results : packed_internal_operation_result list; + } + -> 'kind Kind.manager contents_result + +type packed_contents_result = + | Contents_result : 'kind contents_result -> packed_contents_result + +type packed_contents_and_result = + | Contents_and_result : + 'kind Operation.contents * 'kind contents_result + -> packed_contents_and_result + +type ('a, 'b) eq = Eq : ('a, 'a) eq [@@coq_force_gadt] + +let equal_manager_kind : + type a b. a Kind.manager -> b Kind.manager -> (a, b) eq option = + fun ka kb -> + match (ka, kb) with + | (Kind.Reveal_manager_kind, Kind.Reveal_manager_kind) -> Some Eq + | (Kind.Reveal_manager_kind, _) -> None + | (Kind.Transaction_manager_kind, Kind.Transaction_manager_kind) -> Some Eq + | (Kind.Transaction_manager_kind, _) -> None + | (Kind.Origination_manager_kind, Kind.Origination_manager_kind) -> Some Eq + | (Kind.Origination_manager_kind, _) -> None + | (Kind.Delegation_manager_kind, Kind.Delegation_manager_kind) -> Some Eq + | (Kind.Delegation_manager_kind, _) -> None + | ( Kind.Register_global_constant_manager_kind, + Kind.Register_global_constant_manager_kind ) -> + Some Eq + | (Kind.Register_global_constant_manager_kind, _) -> None + | (Kind.Set_deposits_limit_manager_kind, Kind.Set_deposits_limit_manager_kind) + -> + Some Eq + | (Kind.Set_deposits_limit_manager_kind, _) -> None + +module Encoding = struct + type 'kind case = + | Case : { + op_case : 'kind Operation.Encoding.case; + encoding : 'a Data_encoding.t; + select : packed_contents_result -> 'kind contents_result option; + mselect : + packed_contents_and_result -> + ('kind contents * 'kind contents_result) option; + proj : 'kind contents_result -> 'a; + inj : 'a -> 'kind contents_result; + } + -> 'kind case + + let tagged_case tag name args proj inj = + let open Data_encoding in + case + tag + ~title:(String.capitalize_ascii name) + (merge_objs (obj1 (req "kind" (constant name))) args) + (fun x -> match proj x with None -> None | Some x -> Some ((), x)) + (fun ((), x) -> inj x) + + let[@coq_axiom_with_reason "gadt"] preendorsement_case = + Case + { + op_case = Operation.Encoding.preendorsement_case; + encoding = + obj3 + (req "balance_updates" Receipt.balance_updates_encoding) + (req "delegate" Signature.Public_key_hash.encoding) + (req "preendorsement_power" int31); + select = + (function + | Contents_result (Preendorsement_result _ as op) -> Some op + | _ -> None); + mselect = + (function + | Contents_and_result ((Preendorsement _ as op), res) -> Some (op, res) + | _ -> None); + proj = + (function + | Preendorsement_result + {balance_updates; delegate; preendorsement_power} -> + (balance_updates, delegate, preendorsement_power)); + inj = + (fun (balance_updates, delegate, preendorsement_power) -> + Preendorsement_result + {balance_updates; delegate; preendorsement_power}); + } + + let[@coq_axiom_with_reason "gadt"] endorsement_case = + Case + { + op_case = Operation.Encoding.endorsement_case; + encoding = + obj3 + (req "balance_updates" Receipt.balance_updates_encoding) + (req "delegate" Signature.Public_key_hash.encoding) + (req "endorsement_power" int31); + select = + (function + | Contents_result (Endorsement_result _ as op) -> Some op | _ -> None); + mselect = + (function + | Contents_and_result ((Endorsement _ as op), res) -> Some (op, res) + | _ -> None); + proj = + (function + | Endorsement_result {balance_updates; delegate; endorsement_power} -> + (balance_updates, delegate, endorsement_power)); + inj = + (fun (balance_updates, delegate, endorsement_power) -> + Endorsement_result {balance_updates; delegate; endorsement_power}); + } + + let[@coq_axiom_with_reason "gadt"] seed_nonce_revelation_case = + Case + { + op_case = Operation.Encoding.seed_nonce_revelation_case; + encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); + select = + (function + | Contents_result (Seed_nonce_revelation_result _ as op) -> Some op + | _ -> None); + mselect = + (function + | Contents_and_result ((Seed_nonce_revelation _ as op), res) -> + Some (op, res) + | _ -> None); + proj = (fun (Seed_nonce_revelation_result bus) -> bus); + inj = (fun bus -> Seed_nonce_revelation_result bus); + } + + let[@coq_axiom_with_reason "gadt"] double_endorsement_evidence_case = + Case + { + op_case = Operation.Encoding.double_endorsement_evidence_case; + encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); + select = + (function + | Contents_result (Double_endorsement_evidence_result _ as op) -> + Some op + | _ -> None); + mselect = + (function + | Contents_and_result ((Double_endorsement_evidence _ as op), res) -> + Some (op, res) + | _ -> None); + proj = (fun (Double_endorsement_evidence_result bus) -> bus); + inj = (fun bus -> Double_endorsement_evidence_result bus); + } + + let[@coq_axiom_with_reason "gadt"] double_preendorsement_evidence_case = + Case + { + op_case = Operation.Encoding.double_preendorsement_evidence_case; + encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); + select = + (function + | Contents_result (Double_preendorsement_evidence_result _ as op) -> + Some op + | _ -> None); + mselect = + (function + | Contents_and_result ((Double_preendorsement_evidence _ as op), res) + -> + Some (op, res) + | _ -> None); + proj = (fun (Double_preendorsement_evidence_result bus) -> bus); + inj = (fun bus -> Double_preendorsement_evidence_result bus); + } + + let[@coq_axiom_with_reason "gadt"] double_baking_evidence_case = + Case + { + op_case = Operation.Encoding.double_baking_evidence_case; + encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); + select = + (function + | Contents_result (Double_baking_evidence_result _ as op) -> Some op + | _ -> None); + mselect = + (function + | Contents_and_result ((Double_baking_evidence _ as op), res) -> + Some (op, res) + | _ -> None); + proj = (fun (Double_baking_evidence_result bus) -> bus); + inj = (fun bus -> Double_baking_evidence_result bus); + } + + let[@coq_axiom_with_reason "gadt"] activate_account_case = + Case + { + op_case = Operation.Encoding.activate_account_case; + encoding = obj1 (req "balance_updates" Receipt.balance_updates_encoding); + select = + (function + | Contents_result (Activate_account_result _ as op) -> Some op + | _ -> None); + mselect = + (function + | Contents_and_result ((Activate_account _ as op), res) -> + Some (op, res) + | _ -> None); + proj = (fun (Activate_account_result bus) -> bus); + inj = (fun bus -> Activate_account_result bus); + } + + let[@coq_axiom_with_reason "gadt"] proposals_case = + Case + { + op_case = Operation.Encoding.proposals_case; + encoding = Data_encoding.empty; + select = + (function + | Contents_result (Proposals_result as op) -> Some op | _ -> None); + mselect = + (function + | Contents_and_result ((Proposals _ as op), res) -> Some (op, res) + | _ -> None); + proj = (fun Proposals_result -> ()); + inj = (fun () -> Proposals_result); + } + + let[@coq_axiom_with_reason "gadt"] ballot_case = + Case + { + op_case = Operation.Encoding.ballot_case; + encoding = Data_encoding.empty; + select = + (function + | Contents_result (Ballot_result as op) -> Some op | _ -> None); + mselect = + (function + | Contents_and_result ((Ballot _ as op), res) -> Some (op, res) + | _ -> None); + proj = (fun Ballot_result -> ()); + inj = (fun () -> Ballot_result); + } + + let[@coq_axiom_with_reason "gadt"] make_manager_case (type kind) + (Operation.Encoding.Case op_case : + kind Kind.manager Operation.Encoding.case) + (Manager_result.MCase res_case : kind Manager_result.case) mselect = + Case + { + op_case = Operation.Encoding.Case op_case; + encoding = + obj3 + (req "balance_updates" Receipt.balance_updates_encoding) + (req "operation_result" res_case.t) + (dft + "internal_operation_results" + (list internal_operation_result_encoding) + []); + select = + (function + | Contents_result + (Manager_operation_result + ({operation_result = Applied res; _} as op)) -> ( + match res_case.select (Successful_manager_result res) with + | Some res -> + Some + (Manager_operation_result + {op with operation_result = Applied res}) + | None -> None) + | Contents_result + (Manager_operation_result + ({operation_result = Backtracked (res, errs); _} as op)) -> ( + match res_case.select (Successful_manager_result res) with + | Some res -> + Some + (Manager_operation_result + {op with operation_result = Backtracked (res, errs)}) + | None -> None) + | Contents_result + (Manager_operation_result + ({operation_result = Skipped kind; _} as op)) -> ( + match equal_manager_kind kind res_case.kind with + | None -> None + | Some Eq -> + Some + (Manager_operation_result + {op with operation_result = Skipped kind})) + | Contents_result + (Manager_operation_result + ({operation_result = Failed (kind, errs); _} as op)) -> ( + match equal_manager_kind kind res_case.kind with + | None -> None + | Some Eq -> + Some + (Manager_operation_result + {op with operation_result = Failed (kind, errs)})) + | Contents_result (Preendorsement_result _) -> None + | Contents_result (Endorsement_result _) -> None + | Contents_result Ballot_result -> None + | Contents_result (Seed_nonce_revelation_result _) -> None + | Contents_result (Double_endorsement_evidence_result _) -> None + | Contents_result (Double_preendorsement_evidence_result _) -> None + | Contents_result (Double_baking_evidence_result _) -> None + | Contents_result (Activate_account_result _) -> None + | Contents_result Proposals_result -> None); + mselect; + proj = + (fun (Manager_operation_result + { + balance_updates = bus; + operation_result = r; + internal_operation_results = rs; + }) -> + (bus, r, rs)); + inj = + (fun (bus, r, rs) -> + Manager_operation_result + { + balance_updates = bus; + operation_result = r; + internal_operation_results = rs; + }); + } + + let[@coq_axiom_with_reason "gadt"] reveal_case = + make_manager_case + Operation.Encoding.reveal_case + Manager_result.reveal_case + (function + | Contents_and_result + ((Manager_operation {operation = Reveal _; _} as op), res) -> + Some (op, res) + | _ -> None) + + let[@coq_axiom_with_reason "gadt"] transaction_case = + make_manager_case + Operation.Encoding.transaction_case + Manager_result.transaction_case + (function + | Contents_and_result + ((Manager_operation {operation = Transaction _; _} as op), res) -> + Some (op, res) + | _ -> None) + + let[@coq_axiom_with_reason "gadt"] origination_case = + make_manager_case + Operation.Encoding.origination_case + Manager_result.origination_case + (function + | Contents_and_result + ((Manager_operation {operation = Origination _; _} as op), res) -> + Some (op, res) + | _ -> None) + + let[@coq_axiom_with_reason "gadt"] delegation_case = + make_manager_case + Operation.Encoding.delegation_case + Manager_result.delegation_case + (function + | Contents_and_result + ((Manager_operation {operation = Delegation _; _} as op), res) -> + Some (op, res) + | _ -> None) + + let[@coq_axiom_with_reason "gadt"] register_global_constant_case = + make_manager_case + Operation.Encoding.register_global_constant_case + Manager_result.register_global_constant_case + (function + | Contents_and_result + ( (Manager_operation {operation = Register_global_constant _; _} as + op), + res ) -> + Some (op, res) + | _ -> None) + + let[@coq_axiom_with_reason "gadt"] set_deposits_limit_case = + make_manager_case + Operation.Encoding.set_deposits_limit_case + Manager_result.set_deposits_limit_case + (function + | Contents_and_result + ( (Manager_operation {operation = Set_deposits_limit _; _} as op), + res ) -> + Some (op, res) + | _ -> None) +end + +let contents_result_encoding = + let open Encoding in + let make + (Case + { + op_case = Operation.Encoding.Case {tag; name; _}; + encoding; + mselect = _; + select; + proj; + inj; + }) = + let proj x = match select x with None -> None | Some x -> Some (proj x) in + let inj x = Contents_result (inj x) in + tagged_case (Tag tag) name encoding proj inj + in + def "operation.alpha.contents_result" + @@ union + [ + make seed_nonce_revelation_case; + make endorsement_case; + make preendorsement_case; + make double_preendorsement_evidence_case; + make double_endorsement_evidence_case; + make double_baking_evidence_case; + make activate_account_case; + make proposals_case; + make ballot_case; + make reveal_case; + make transaction_case; + make origination_case; + make delegation_case; + make register_global_constant_case; + make set_deposits_limit_case; + ] + +let contents_and_result_encoding = + let open Encoding in + let make + (Case + { + op_case = Operation.Encoding.Case {tag; name; encoding; proj; inj; _}; + mselect; + encoding = meta_encoding; + proj = meta_proj; + inj = meta_inj; + _; + }) = + let proj c = + match mselect c with + | Some (op, res) -> Some (proj op, meta_proj res) + | _ -> None + in + let inj (op, res) = Contents_and_result (inj op, meta_inj res) in + let encoding = merge_objs encoding (obj1 (req "metadata" meta_encoding)) in + tagged_case (Tag tag) name encoding proj inj + in + def "operation.alpha.operation_contents_and_result" + @@ union + [ + make seed_nonce_revelation_case; + make endorsement_case; + make preendorsement_case; + make double_preendorsement_evidence_case; + make double_endorsement_evidence_case; + make double_baking_evidence_case; + make activate_account_case; + make proposals_case; + make ballot_case; + make reveal_case; + make transaction_case; + make origination_case; + make delegation_case; + make register_global_constant_case; + make set_deposits_limit_case; + ] + +type 'kind contents_result_list = + | Single_result : 'kind contents_result -> 'kind contents_result_list + | Cons_result : + 'kind Kind.manager contents_result + * 'rest Kind.manager contents_result_list + -> ('kind * 'rest) Kind.manager contents_result_list + +type packed_contents_result_list = + | Contents_result_list : + 'kind contents_result_list + -> packed_contents_result_list + +let contents_result_list_encoding = + let rec to_list = function + | Contents_result_list (Single_result o) -> [Contents_result o] + | Contents_result_list (Cons_result (o, os)) -> + Contents_result o :: to_list (Contents_result_list os) + in + let rec of_list = function + | [] -> Error "cannot decode empty operation result" + | [Contents_result o] -> Ok (Contents_result_list (Single_result o)) + | Contents_result o :: os -> ( + of_list os >>? fun (Contents_result_list os) -> + match (o, os) with + | ( Manager_operation_result _, + Single_result (Manager_operation_result _) ) -> + Ok (Contents_result_list (Cons_result (o, os))) + | (Manager_operation_result _, Cons_result _) -> + Ok (Contents_result_list (Cons_result (o, os))) + | _ -> Error "cannot decode ill-formed operation result") + in + def "operation.alpha.contents_list_result" + @@ conv_with_guard to_list of_list (list contents_result_encoding) + +type 'kind contents_and_result_list = + | Single_and_result : + 'kind Alpha_context.contents * 'kind contents_result + -> 'kind contents_and_result_list + | Cons_and_result : + 'kind Kind.manager Alpha_context.contents + * 'kind Kind.manager contents_result + * 'rest Kind.manager contents_and_result_list + -> ('kind * 'rest) Kind.manager contents_and_result_list + +type packed_contents_and_result_list = + | Contents_and_result_list : + 'kind contents_and_result_list + -> packed_contents_and_result_list + +let contents_and_result_list_encoding = + let rec to_list = function + | Contents_and_result_list (Single_and_result (op, res)) -> + [Contents_and_result (op, res)] + | Contents_and_result_list (Cons_and_result (op, res, rest)) -> + Contents_and_result (op, res) :: to_list (Contents_and_result_list rest) + in + let rec of_list = function + | [] -> Error "cannot decode empty combined operation result" + | [Contents_and_result (op, res)] -> + Ok (Contents_and_result_list (Single_and_result (op, res))) + | Contents_and_result (op, res) :: rest -> ( + of_list rest >>? fun (Contents_and_result_list rest) -> + match (op, rest) with + | (Manager_operation _, Single_and_result (Manager_operation _, _)) -> + Ok (Contents_and_result_list (Cons_and_result (op, res, rest))) + | (Manager_operation _, Cons_and_result (_, _, _)) -> + Ok (Contents_and_result_list (Cons_and_result (op, res, rest))) + | _ -> Error "cannot decode ill-formed combined operation result") + in + conv_with_guard to_list of_list (Variable.list contents_and_result_encoding) + +type 'kind operation_metadata = {contents : 'kind contents_result_list} + +type packed_operation_metadata = + | Operation_metadata : 'kind operation_metadata -> packed_operation_metadata + | No_operation_metadata : packed_operation_metadata + +let operation_metadata_encoding = + def "operation.alpha.result" + @@ union + [ + case + (Tag 0) + ~title:"Operation_metadata" + contents_result_list_encoding + (function + | Operation_metadata {contents} -> + Some (Contents_result_list contents) + | _ -> None) + (fun (Contents_result_list contents) -> + Operation_metadata {contents}); + case + (Tag 1) + ~title:"No_operation_metadata" + empty + (function No_operation_metadata -> Some () | _ -> None) + (fun () -> No_operation_metadata); + ] + +let kind_equal : + type kind kind2. + kind contents -> kind2 contents_result -> (kind, kind2) eq option = + fun op res -> + match (op, res) with + | (Endorsement _, Endorsement_result _) -> Some Eq + | (Endorsement _, _) -> None + | (Preendorsement _, Preendorsement_result _) -> Some Eq + | (Preendorsement _, _) -> None + | (Seed_nonce_revelation _, Seed_nonce_revelation_result _) -> Some Eq + | (Seed_nonce_revelation _, _) -> None + | (Double_preendorsement_evidence _, Double_preendorsement_evidence_result _) + -> + Some Eq + | (Double_preendorsement_evidence _, _) -> None + | (Double_endorsement_evidence _, Double_endorsement_evidence_result _) -> + Some Eq + | (Double_endorsement_evidence _, _) -> None + | (Double_baking_evidence _, Double_baking_evidence_result _) -> Some Eq + | (Double_baking_evidence _, _) -> None + | (Activate_account _, Activate_account_result _) -> Some Eq + | (Activate_account _, _) -> None + | (Proposals _, Proposals_result) -> Some Eq + | (Proposals _, _) -> None + | (Ballot _, Ballot_result) -> Some Eq + | (Ballot _, _) -> None + | (Failing_noop _, _) -> + (* the Failing_noop operation always fails and can't have result *) + None + | ( Manager_operation {operation = Reveal _; _}, + Manager_operation_result {operation_result = Applied (Reveal_result _); _} + ) -> + Some Eq + | ( Manager_operation {operation = Reveal _; _}, + Manager_operation_result + {operation_result = Backtracked (Reveal_result _, _); _} ) -> + Some Eq + | ( Manager_operation {operation = Reveal _; _}, + Manager_operation_result + { + operation_result = Failed (Alpha_context.Kind.Reveal_manager_kind, _); + _; + } ) -> + Some Eq + | ( Manager_operation {operation = Reveal _; _}, + Manager_operation_result + {operation_result = Skipped Alpha_context.Kind.Reveal_manager_kind; _} + ) -> + Some Eq + | (Manager_operation {operation = Reveal _; _}, _) -> None + | ( Manager_operation {operation = Transaction _; _}, + Manager_operation_result + {operation_result = Applied (Transaction_result _); _} ) -> + Some Eq + | ( Manager_operation {operation = Transaction _; _}, + Manager_operation_result + {operation_result = Backtracked (Transaction_result _, _); _} ) -> + Some Eq + | ( Manager_operation {operation = Transaction _; _}, + Manager_operation_result + { + operation_result = + Failed (Alpha_context.Kind.Transaction_manager_kind, _); + _; + } ) -> + Some Eq + | ( Manager_operation {operation = Transaction _; _}, + Manager_operation_result + { + operation_result = Skipped Alpha_context.Kind.Transaction_manager_kind; + _; + } ) -> + Some Eq + | (Manager_operation {operation = Transaction _; _}, _) -> None + | ( Manager_operation {operation = Origination _; _}, + Manager_operation_result + {operation_result = Applied (Origination_result _); _} ) -> + Some Eq + | ( Manager_operation {operation = Origination _; _}, + Manager_operation_result + {operation_result = Backtracked (Origination_result _, _); _} ) -> + Some Eq + | ( Manager_operation {operation = Origination _; _}, + Manager_operation_result + { + operation_result = + Failed (Alpha_context.Kind.Origination_manager_kind, _); + _; + } ) -> + Some Eq + | ( Manager_operation {operation = Origination _; _}, + Manager_operation_result + { + operation_result = Skipped Alpha_context.Kind.Origination_manager_kind; + _; + } ) -> + Some Eq + | (Manager_operation {operation = Origination _; _}, _) -> None + | ( Manager_operation {operation = Delegation _; _}, + Manager_operation_result + {operation_result = Applied (Delegation_result _); _} ) -> + Some Eq + | ( Manager_operation {operation = Delegation _; _}, + Manager_operation_result + {operation_result = Backtracked (Delegation_result _, _); _} ) -> + Some Eq + | ( Manager_operation {operation = Delegation _; _}, + Manager_operation_result + { + operation_result = + Failed (Alpha_context.Kind.Delegation_manager_kind, _); + _; + } ) -> + Some Eq + | ( Manager_operation {operation = Delegation _; _}, + Manager_operation_result + { + operation_result = Skipped Alpha_context.Kind.Delegation_manager_kind; + _; + } ) -> + Some Eq + | (Manager_operation {operation = Delegation _; _}, _) -> None + | ( Manager_operation {operation = Register_global_constant _; _}, + Manager_operation_result + {operation_result = Applied (Register_global_constant_result _); _} ) -> + Some Eq + | ( Manager_operation {operation = Register_global_constant _; _}, + Manager_operation_result + { + operation_result = Backtracked (Register_global_constant_result _, _); + _; + } ) -> + Some Eq + | ( Manager_operation {operation = Register_global_constant _; _}, + Manager_operation_result + { + operation_result = + Failed (Alpha_context.Kind.Register_global_constant_manager_kind, _); + _; + } ) -> + Some Eq + | ( Manager_operation {operation = Register_global_constant _; _}, + Manager_operation_result + { + operation_result = + Skipped Alpha_context.Kind.Register_global_constant_manager_kind; + _; + } ) -> + Some Eq + | (Manager_operation {operation = Register_global_constant _; _}, _) -> None + | ( Manager_operation {operation = Set_deposits_limit _; _}, + Manager_operation_result + {operation_result = Applied (Set_deposits_limit_result _); _} ) -> + Some Eq + | ( Manager_operation {operation = Set_deposits_limit _; _}, + Manager_operation_result + {operation_result = Backtracked (Set_deposits_limit_result _, _); _} ) + -> + Some Eq + | ( Manager_operation {operation = Set_deposits_limit _; _}, + Manager_operation_result + { + operation_result = + Failed (Alpha_context.Kind.Set_deposits_limit_manager_kind, _); + _; + } ) -> + Some Eq + | ( Manager_operation {operation = Set_deposits_limit _; _}, + Manager_operation_result + { + operation_result = + Skipped Alpha_context.Kind.Set_deposits_limit_manager_kind; + _; + } ) -> + Some Eq + | (Manager_operation {operation = Set_deposits_limit _; _}, _) -> None + +let rec kind_equal_list : + type kind kind2. + kind contents_list -> kind2 contents_result_list -> (kind, kind2) eq option + = + fun contents res -> + match (contents, res) with + | (Single op, Single_result res) -> ( + match kind_equal op res with None -> None | Some Eq -> Some Eq) + | (Cons (op, ops), Cons_result (res, ress)) -> ( + match kind_equal op res with + | None -> None + | Some Eq -> ( + match kind_equal_list ops ress with + | None -> None + | Some Eq -> Some Eq)) + | _ -> None + +let[@coq_axiom_with_reason "gadt"] rec pack_contents_list : + type kind. + kind contents_list -> + kind contents_result_list -> + kind contents_and_result_list = + fun contents res -> + match (contents, res) with + | (Single op, Single_result res) -> Single_and_result (op, res) + | (Cons (op, ops), Cons_result (res, ress)) -> + Cons_and_result (op, res, pack_contents_list ops ress) + | ( Single (Manager_operation _), + Cons_result (Manager_operation_result _, Single_result _) ) -> + . + | ( Cons (_, _), + Single_result (Manager_operation_result {operation_result = Failed _; _}) + ) -> + . + | ( Cons (_, _), + Single_result (Manager_operation_result {operation_result = Skipped _; _}) + ) -> + . + | ( Cons (_, _), + Single_result (Manager_operation_result {operation_result = Applied _; _}) + ) -> + . + | ( Cons (_, _), + Single_result + (Manager_operation_result {operation_result = Backtracked _; _}) ) -> + . + | (Single _, Cons_result _) -> . + +let rec unpack_contents_list : + type kind. + kind contents_and_result_list -> + kind contents_list * kind contents_result_list = function + | Single_and_result (op, res) -> (Single op, Single_result res) + | Cons_and_result (op, res, rest) -> + let (ops, ress) = unpack_contents_list rest in + (Cons (op, ops), Cons_result (res, ress)) + +let rec to_list = function + | Contents_result_list (Single_result o) -> [Contents_result o] + | Contents_result_list (Cons_result (o, os)) -> + Contents_result o :: to_list (Contents_result_list os) + +let operation_data_and_metadata_encoding = + def "operation.alpha.operation_with_metadata" + @@ union + [ + case + (Tag 0) + ~title:"Operation_with_metadata" + (obj2 + (req "contents" (dynamic_size contents_and_result_list_encoding)) + (opt "signature" Signature.encoding)) + (function + | (Operation_data _, No_operation_metadata) -> None + | (Operation_data op, Operation_metadata res) -> ( + match kind_equal_list op.contents res.contents with + | None -> + Pervasives.failwith + "cannot decode inconsistent combined operation result" + | Some Eq -> + Some + ( Contents_and_result_list + (pack_contents_list op.contents res.contents), + op.signature ))) + (fun (Contents_and_result_list contents, signature) -> + let (op_contents, res_contents) = unpack_contents_list contents in + ( Operation_data {contents = op_contents; signature}, + Operation_metadata {contents = res_contents} )); + case + (Tag 1) + ~title:"Operation_without_metadata" + (obj2 + (req "contents" (dynamic_size Operation.contents_list_encoding)) + (opt "signature" Signature.encoding)) + (function + | (Operation_data op, No_operation_metadata) -> + Some (Contents_list op.contents, op.signature) + | (Operation_data _, Operation_metadata _) -> None) + (fun (Contents_list contents, signature) -> + (Operation_data {contents; signature}, No_operation_metadata)); + ] + +type block_metadata = { + proposer : Signature.Public_key_hash.t; + baker : Signature.Public_key_hash.t; + level_info : Level.t; + voting_period_info : Voting_period.info; + nonce_hash : Nonce_hash.t option; + consumed_gas : Gas.Arith.fp; + deactivated : Signature.Public_key_hash.t list; + balance_updates : Receipt.balance_updates; + liquidity_baking_escape_ema : Liquidity_baking.escape_ema; + implicit_operations_results : packed_successful_manager_operation_result list; +} + +let block_metadata_encoding = + let open Data_encoding in + def "block_header.alpha.metadata" + @@ conv + (fun { + proposer; + baker; + level_info; + voting_period_info; + nonce_hash; + consumed_gas; + deactivated; + balance_updates; + liquidity_baking_escape_ema; + implicit_operations_results; + } -> + ( proposer, + baker, + level_info, + voting_period_info, + nonce_hash, + consumed_gas, + deactivated, + balance_updates, + liquidity_baking_escape_ema, + implicit_operations_results )) + (fun ( proposer, + baker, + level_info, + voting_period_info, + nonce_hash, + consumed_gas, + deactivated, + balance_updates, + liquidity_baking_escape_ema, + implicit_operations_results ) -> + { + proposer; + baker; + level_info; + voting_period_info; + nonce_hash; + consumed_gas; + deactivated; + balance_updates; + liquidity_baking_escape_ema; + implicit_operations_results; + }) + (obj10 + (req "proposer" Signature.Public_key_hash.encoding) + (req "baker" Signature.Public_key_hash.encoding) + (req "level_info" Level.encoding) + (req "voting_period_info" Voting_period.info_encoding) + (req "nonce_hash" (option Nonce_hash.encoding)) + (req "consumed_gas" Gas.Arith.n_fp_encoding) + (req "deactivated" (list Signature.Public_key_hash.encoding)) + (req "balance_updates" Receipt.balance_updates_encoding) + (req "liquidity_baking_escape_ema" int32) + (req + "implicit_operations_results" + (list successful_manager_operation_result_encoding))) + +type precheck_result = { + consumed_gas : Gas.Arith.fp; + balance_updates : Receipt.balance_updates; +} + +type 'kind prechecked_contents = { + contents : 'kind contents; + result : precheck_result; +} + +type _ prechecked_contents_list = + | PrecheckedSingle : + 'kind prechecked_contents + -> 'kind prechecked_contents_list + | PrecheckedCons : + 'kind Kind.manager prechecked_contents + * 'rest Kind.manager prechecked_contents_list + -> ('kind * 'rest) Kind.manager prechecked_contents_list diff --git a/src/proto_012_PsiThaCa/lib_protocol/apply_results.mli b/src/proto_012_PsiThaCa/lib_protocol/apply_results.mli new file mode 100644 index 000000000000..8093333ada79 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/apply_results.mli @@ -0,0 +1,250 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Types representing results of applying an operation. + + These are used internally by [Apply], and can be used for experimenting + with protocol updates, by clients to print out a summary of the + operation at pre-injection simulation and at confirmation time, + and by block explorers. + *) + +open Alpha_context + +(** Result of applying a {!Operation.t}. Follows the same structure. *) +type 'kind operation_metadata = {contents : 'kind contents_result_list} + +and packed_operation_metadata = + | Operation_metadata : 'kind operation_metadata -> packed_operation_metadata + | No_operation_metadata : packed_operation_metadata + +(** Result of applying a {!Operation.contents_list}. Follows the same structure. *) +and 'kind contents_result_list = + | Single_result : 'kind contents_result -> 'kind contents_result_list + | Cons_result : + 'kind Kind.manager contents_result + * 'rest Kind.manager contents_result_list + -> ('kind * 'rest) Kind.manager contents_result_list + +and packed_contents_result_list = + | Contents_result_list : + 'kind contents_result_list + -> packed_contents_result_list + +(** Result of applying an {!Operation.contents}. Follows the same structure. *) +and 'kind contents_result = + | Preendorsement_result : { + balance_updates : Receipt.balance_updates; + delegate : Signature.Public_key_hash.t; + preendorsement_power : int; + } + -> Kind.preendorsement contents_result + | Endorsement_result : { + balance_updates : Receipt.balance_updates; + delegate : Signature.Public_key_hash.t; + endorsement_power : int; + } + -> Kind.endorsement contents_result + | Seed_nonce_revelation_result : + Receipt.balance_updates + -> Kind.seed_nonce_revelation contents_result + | Double_endorsement_evidence_result : + Receipt.balance_updates + -> Kind.double_endorsement_evidence contents_result + | Double_preendorsement_evidence_result : + Receipt.balance_updates + -> Kind.double_preendorsement_evidence contents_result + | Double_baking_evidence_result : + Receipt.balance_updates + -> Kind.double_baking_evidence contents_result + | Activate_account_result : + Receipt.balance_updates + -> Kind.activate_account contents_result + | Proposals_result : Kind.proposals contents_result + | Ballot_result : Kind.ballot contents_result + | Manager_operation_result : { + balance_updates : Receipt.balance_updates; + operation_result : 'kind manager_operation_result; + internal_operation_results : packed_internal_operation_result list; + } + -> 'kind Kind.manager contents_result + +and packed_contents_result = + | Contents_result : 'kind contents_result -> packed_contents_result + +(** The result of an operation in the queue. [Skipped] ones should + always be at the tail, and after a single [Failed]. *) +and 'kind manager_operation_result = + | Applied of 'kind successful_manager_operation_result + | Backtracked of + 'kind successful_manager_operation_result * error trace option + | Failed : 'kind Kind.manager * error trace -> 'kind manager_operation_result + | Skipped : 'kind Kind.manager -> 'kind manager_operation_result +[@@coq_force_gadt] + +(** Result of applying a {!manager_operation_content}, either internal + or external. *) +and _ successful_manager_operation_result = + | Reveal_result : { + consumed_gas : Gas.Arith.fp; + } + -> Kind.reveal successful_manager_operation_result + | Transaction_result : { + storage : Script.expr option; + lazy_storage_diff : Lazy_storage.diffs option; + balance_updates : Receipt.balance_updates; + originated_contracts : Contract.t list; + consumed_gas : Gas.Arith.fp; + storage_size : Z.t; + paid_storage_size_diff : Z.t; + allocated_destination_contract : bool; + } + -> Kind.transaction successful_manager_operation_result + | Origination_result : { + lazy_storage_diff : Lazy_storage.diffs option; + balance_updates : Receipt.balance_updates; + originated_contracts : Contract.t list; + consumed_gas : Gas.Arith.fp; + storage_size : Z.t; + paid_storage_size_diff : Z.t; + } + -> Kind.origination successful_manager_operation_result + | Delegation_result : { + consumed_gas : Gas.Arith.fp; + } + -> Kind.delegation successful_manager_operation_result + | Register_global_constant_result : { + (* The manager submitting the operation must pay + the cost of storage for the registered value. + We include the balance update here. *) + balance_updates : Receipt.balance_updates; + (* Gas consumed while validating and storing the registered + value. *) + consumed_gas : Gas.Arith.fp; + (* The size of the registered value in bytes. + Currently, this is simply the number of bytes in the binary + serialization of the Micheline value. *) + size_of_constant : Z.t; + (* The address of the newly registered value, being + the hash of its binary serialization. This could be + calulated on demand but we include it here in the + receipt for flexibility in the future. *) + global_address : Script_expr_hash.t; + } + -> Kind.register_global_constant successful_manager_operation_result + | Set_deposits_limit_result : { + consumed_gas : Gas.Arith.fp; + } + -> Kind.set_deposits_limit successful_manager_operation_result + +and packed_successful_manager_operation_result = + | Successful_manager_result : + 'kind successful_manager_operation_result + -> packed_successful_manager_operation_result + +and packed_internal_operation_result = + | Internal_operation_result : + 'kind internal_operation * 'kind manager_operation_result + -> packed_internal_operation_result + +val pack_migration_operation_results : + Migration.origination_result list -> + packed_successful_manager_operation_result list + +(** Serializer for {!packed_operation_result}. *) +val operation_metadata_encoding : packed_operation_metadata Data_encoding.t + +val operation_data_and_metadata_encoding : + (Operation.packed_protocol_data * packed_operation_metadata) Data_encoding.t + +type 'kind contents_and_result_list = + | Single_and_result : + 'kind Alpha_context.contents * 'kind contents_result + -> 'kind contents_and_result_list + | Cons_and_result : + 'kind Kind.manager Alpha_context.contents + * 'kind Kind.manager contents_result + * 'rest Kind.manager contents_and_result_list + -> ('kind * 'rest) Kind.manager contents_and_result_list + +type packed_contents_and_result_list = + | Contents_and_result_list : + 'kind contents_and_result_list + -> packed_contents_and_result_list + +val contents_and_result_list_encoding : + packed_contents_and_result_list Data_encoding.t + +val pack_contents_list : + 'kind contents_list -> + 'kind contents_result_list -> + 'kind contents_and_result_list + +val unpack_contents_list : + 'kind contents_and_result_list -> + 'kind contents_list * 'kind contents_result_list + +val to_list : packed_contents_result_list -> packed_contents_result list + +type ('a, 'b) eq = Eq : ('a, 'a) eq + +val kind_equal_list : + 'kind contents_list -> + 'kind2 contents_result_list -> + ('kind, 'kind2) eq option + +type block_metadata = { + proposer : Signature.Public_key_hash.t; + baker : Signature.Public_key_hash.t; + level_info : Level.t; + voting_period_info : Voting_period.info; + nonce_hash : Nonce_hash.t option; + consumed_gas : Gas.Arith.fp; + deactivated : Signature.Public_key_hash.t list; + balance_updates : Receipt.balance_updates; + liquidity_baking_escape_ema : Liquidity_baking.escape_ema; + implicit_operations_results : packed_successful_manager_operation_result list; +} + +val block_metadata_encoding : block_metadata Data_encoding.encoding + +type precheck_result = { + consumed_gas : Gas.Arith.fp; + balance_updates : Receipt.balance_updates; +} + +type 'kind prechecked_contents = { + contents : 'kind contents; + result : precheck_result; +} + +type _ prechecked_contents_list = + | PrecheckedSingle : + 'kind prechecked_contents + -> 'kind prechecked_contents_list + | PrecheckedCons : + 'kind Kind.manager prechecked_contents + * 'rest Kind.manager prechecked_contents_list + -> ('kind * 'rest) Kind.manager prechecked_contents_list diff --git a/src/proto_012_PsiThaCa/lib_protocol/baking.ml b/src/proto_012_PsiThaCa/lib_protocol/baking.ml new file mode 100644 index 000000000000..72140a035f19 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/baking.ml @@ -0,0 +1,130 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Misc + +type error += + | (* `Permanent *) + Insufficient_endorsing_power of { + endorsing_power : int; + consensus_threshold : int; + } + +let () = + register_error_kind + `Permanent + ~id:"baking.insufficient_endorsing_power" + ~title:"Insufficient endorsing power" + ~description: + "The endorsing power is insufficient to satisfy the consensus threshold." + ~pp:(fun ppf (endorsing_power, consensus_threshold) -> + Format.fprintf + ppf + "The endorsing power (%d) is insufficient to satisfy the consensus \ + threshold (%d)." + endorsing_power + consensus_threshold) + Data_encoding.( + obj2 (req "endorsing_power" int31) (req "consensus_threshold" int31)) + (function + | Insufficient_endorsing_power {endorsing_power; consensus_threshold} -> + Some (endorsing_power, consensus_threshold) + | _ -> None) + (fun (endorsing_power, consensus_threshold) -> + Insufficient_endorsing_power {endorsing_power; consensus_threshold}) + +let bonus_baking_reward ctxt ~endorsing_power = + let consensus_threshold = Constants.consensus_threshold ctxt in + let baking_reward_bonus_per_slot = + Constants.baking_reward_bonus_per_slot ctxt + in + let extra_endorsing_power = endorsing_power - consensus_threshold in + error_when + Compare.Int.(extra_endorsing_power < 0) + (Insufficient_endorsing_power {endorsing_power; consensus_threshold}) + >>? fun () -> + Tez.(baking_reward_bonus_per_slot *? Int64.of_int extra_endorsing_power) + +let baking_rights c level = + let rec f c round = + Stake_distribution.baking_rights_owner c level ~round + >>=? fun (c, _slot, (delegate, _)) -> + return (LCons (delegate, fun () -> f c (Round.succ round))) + in + f c Round.zero + +let endorsing_rights (ctxt : t) level = + let consensus_committee_size = Constants.consensus_committee_size ctxt in + Slot.slot_range ~min:0 ~count:consensus_committee_size >>?= fun slots -> + List.fold_left_es + (fun (ctxt, acc) slot -> + Stake_distribution.slot_owner ctxt level slot >>=? fun (ctxt, (_, pkh)) -> + return (ctxt, (slot, pkh) :: acc)) + (ctxt, []) + slots + >>=? fun (ctxt, right_owners) -> + let rights = + List.fold_left + (fun acc (slot, pkh) -> + let slots = + match Signature.Public_key_hash.Map.find pkh acc with + | None -> [slot] + | Some slots -> slot :: slots + in + Signature.Public_key_hash.Map.add pkh slots acc) + Signature.Public_key_hash.Map.empty + right_owners + in + return (ctxt, rights) + +let endorsing_rights_by_first_slot ctxt level = + Slot.slot_range ~min:0 ~count:(Constants.consensus_committee_size ctxt) + >>?= fun slots -> + List.fold_left_es + (fun (ctxt, (delegates_map, slots_map)) slot -> + Stake_distribution.slot_owner ctxt level slot + >|=? fun (ctxt, (pk, pkh)) -> + let (initial_slot, delegates_map) = + match Signature.Public_key_hash.Map.find pkh delegates_map with + | None -> + (slot, Signature.Public_key_hash.Map.add pkh slot delegates_map) + | Some initial_slot -> (initial_slot, delegates_map) + in + (* [slots_map]'keys are the minimal slots of delegates because + we fold on slots in increasing order *) + let slots_map = + Slot.Map.update + initial_slot + (function + | None -> Some (pk, pkh, 1) + | Some (pk, pkh, count) -> Some (pk, pkh, count + 1)) + slots_map + in + (ctxt, (delegates_map, slots_map))) + (ctxt, (Signature.Public_key_hash.Map.empty, Slot.Map.empty)) + slots + >>=? fun (ctxt, (_, slots_map)) -> return (ctxt, slots_map) diff --git a/src/proto_012_PsiThaCa/lib_protocol/baking.mli b/src/proto_012_PsiThaCa/lib_protocol/baking.mli new file mode 100644 index 000000000000..6504712552ed --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/baking.mli @@ -0,0 +1,60 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Misc + +type error += + | (* `Permanent *) + Insufficient_endorsing_power of { + endorsing_power : int; + consensus_threshold : int; + } + +(** For a given level computes who has the right to include an + endorsement in the next block. It returns a mapping from the + delegates with such rights to their endorsing slots. This function + is only used by the 'validators' RPC. *) +val endorsing_rights : + context -> + Level.t -> + (context * Slot.t list Signature.Public_key_hash.Map.t) tzresult Lwt.t + +(** Computes the endorsing rights for a given level. Returns a map + from allocated first slots to their owner's public key, public key + hash, and endorsing power. *) +val endorsing_rights_by_first_slot : + context -> + Level.t -> + (context * (public_key * public_key_hash * int) Slot.Map.t) tzresult Lwt.t + +(** Computes the bonus baking reward depending on the endorsing power. *) +val bonus_baking_reward : context -> endorsing_power:int -> Tez.t tzresult + +(** [baking_rights ctxt level] is the lazy list of contract's + public key hashes that are allowed to propose for [level] + at each round. *) +val baking_rights : context -> Level.t -> public_key lazy_list diff --git a/src/proto_012_PsiThaCa/lib_protocol/blinded_public_key_hash.ml b/src/proto_012_PsiThaCa/lib_protocol/blinded_public_key_hash.ml new file mode 100644 index 000000000000..4cabfdae0688 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/blinded_public_key_hash.ml @@ -0,0 +1,59 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module H = + Blake2B.Make + (Base58) + (struct + let name = "Blinded public key hash" + + let title = "A blinded public key hash" + + let b58check_prefix = "\001\002\049\223" + + let size = Some Ed25519.Public_key_hash.size + end) + +module Index = struct + include H + include Path_encoding.Make_hex (H) +end + +include H + +let () = Base58.check_encoded_prefix b58check_encoding "btz1" 37 + +let of_ed25519_pkh activation_code pkh = + hash_bytes ~key:activation_code [Ed25519.Public_key_hash.to_bytes pkh] + +type activation_code = bytes + +let activation_code_size = Ed25519.Public_key_hash.size + +let activation_code_encoding = Data_encoding.Fixed.bytes activation_code_size + +let activation_code_of_hex h = + if Compare.Int.(String.length h <> activation_code_size * 2) then None + else Hex.to_bytes (`Hex h) diff --git a/src/proto_012_PsiThaCa/lib_protocol/blinded_public_key_hash.mli b/src/proto_012_PsiThaCa/lib_protocol/blinded_public_key_hash.mli new file mode 100644 index 000000000000..9be85a79d08d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/blinded_public_key_hash.mli @@ -0,0 +1,45 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module handles hashes of implicit contract addresses used for + commitments in the origin block. + + This module is needed because for legal reasons, when the blockchain is + activated, the btz1 addresses of participants to the fundraising are not + listed directly but instead their hashes are listed, together with their + balances. Thus, the listed accounts can be activated and credited in the + activation block. *) + +include S.HASH + +type activation_code + +val activation_code_encoding : activation_code Data_encoding.t + +val of_ed25519_pkh : activation_code -> Ed25519.Public_key_hash.t -> t + +val activation_code_of_hex : string -> activation_code option + +module Index : Storage_description.INDEX with type t = t diff --git a/src/proto_012_PsiThaCa/lib_protocol/block_header_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/block_header_repr.ml new file mode 100644 index 000000000000..b753e6a9383b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/block_header_repr.ml @@ -0,0 +1,502 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Block header *) + +type contents = { + payload_hash : Block_payload_hash.t; + payload_round : Round_repr.t; + seed_nonce_hash : Nonce_hash.t option; + proof_of_work_nonce : bytes; + liquidity_baking_escape_vote : bool; +} + +type protocol_data = {contents : contents; signature : Signature.t} + +type t = {shell : Block_header.shell_header; protocol_data : protocol_data} + +type block_header = t + +type raw = Block_header.t + +type shell_header = Block_header.shell_header + +let raw_encoding = Block_header.encoding + +let shell_header_encoding = Block_header.shell_header_encoding + +type block_watermark = Block_header of Chain_id.t + +let bytes_of_block_watermark = function + | Block_header chain_id -> + Bytes.cat (Bytes.of_string "\x11") (Chain_id.to_bytes chain_id) + +let to_watermark b = Signature.Custom (bytes_of_block_watermark b) + +let of_watermark = function + | Signature.Custom b -> + if Compare.Int.(Bytes.length b > 0) then + match Bytes.get b 0 with + | '\x11' -> + Option.map + (fun chain_id -> Block_header chain_id) + (Chain_id.of_bytes_opt (Bytes.sub b 1 (Bytes.length b - 1))) + | _ -> None + else None + | _ -> None + +let contents_encoding = + let open Data_encoding in + def "block_header.alpha.unsigned_contents" + @@ conv + (fun { + payload_hash; + payload_round; + seed_nonce_hash; + proof_of_work_nonce; + liquidity_baking_escape_vote; + } -> + ( payload_hash, + payload_round, + proof_of_work_nonce, + seed_nonce_hash, + liquidity_baking_escape_vote )) + (fun ( payload_hash, + payload_round, + proof_of_work_nonce, + seed_nonce_hash, + liquidity_baking_escape_vote ) -> + { + payload_hash; + payload_round; + seed_nonce_hash; + proof_of_work_nonce; + liquidity_baking_escape_vote; + }) + (obj5 + (req "payload_hash" Block_payload_hash.encoding) + (req "payload_round" Round_repr.encoding) + (req + "proof_of_work_nonce" + (Fixed.bytes Constants_repr.proof_of_work_nonce_size)) + (opt "seed_nonce_hash" Nonce_hash.encoding) + (req "liquidity_baking_escape_vote" Data_encoding.bool)) + +let protocol_data_encoding = + let open Data_encoding in + def "block_header.alpha.signed_contents" + @@ conv + (fun {contents; signature} -> (contents, signature)) + (fun (contents, signature) -> {contents; signature}) + (merge_objs + contents_encoding + (obj1 (req "signature" Signature.encoding))) + +let raw {shell; protocol_data} = + let protocol_data = + Data_encoding.Binary.to_bytes_exn protocol_data_encoding protocol_data + in + {Block_header.shell; protocol_data} + +let unsigned_encoding = + let open Data_encoding in + merge_objs Block_header.shell_header_encoding contents_encoding + +let encoding = + let open Data_encoding in + def "block_header.alpha.full_header" + @@ conv + (fun {shell; protocol_data} -> (shell, protocol_data)) + (fun (shell, protocol_data) -> {shell; protocol_data}) + (merge_objs Block_header.shell_header_encoding protocol_data_encoding) + +(** Constants *) + +let max_header_length = + let fake_level = Raw_level_repr.root in + let fake_round = Round_repr.zero in + let fake_fitness = + Fitness_repr.create_without_locked_round + ~level:fake_level + ~predecessor_round:fake_round + ~round:fake_round + in + let fake_shell = + { + Block_header.level = 0l; + proto_level = 0; + predecessor = Block_hash.zero; + timestamp = Time.of_seconds 0L; + validation_passes = 0; + operations_hash = Operation_list_list_hash.zero; + fitness = Fitness_repr.to_raw fake_fitness; + context = Context_hash.zero; + } + and fake_contents = + { + payload_hash = Block_payload_hash.zero; + payload_round = Round_repr.zero; + proof_of_work_nonce = + Bytes.make Constants_repr.proof_of_work_nonce_size '0'; + seed_nonce_hash = Some Nonce_hash.zero; + liquidity_baking_escape_vote = false; + } + in + Data_encoding.Binary.length + encoding + { + shell = fake_shell; + protocol_data = {contents = fake_contents; signature = Signature.zero}; + } + +(** Header parsing entry point *) + +let hash_raw = Block_header.hash + +let hash {shell; protocol_data} = + Block_header.hash + { + shell; + protocol_data = + Data_encoding.Binary.to_bytes_exn protocol_data_encoding protocol_data; + } + +type locked_round_evidence = { + preendorsement_round : Round_repr.t; + preendorsement_count : int; +} + +type error += + | (* Permanent *) + Invalid_block_signature of + Block_hash.t * Signature.Public_key_hash.t + | (* Permanent *) Invalid_stamp + | (* Permanent *) + Invalid_payload_hash of { + expected : Block_payload_hash.t; + provided : Block_payload_hash.t; + } + | (* Permanent *) + Locked_round_after_block_round of { + locked_round : Round_repr.t; + round : Round_repr.t; + } + | (* Permanent *) + Invalid_payload_round of { + payload_round : Round_repr.t; + round : Round_repr.t; + } + | (* Permanent *) + Insufficient_locked_round_evidence of { + voting_power : int; + consensus_threshold : int; + } + | (* Permanent *) Invalid_commitment of {expected : bool} + | (* Permanent *) Wrong_timestamp of Time.t * Time.t + +let () = + register_error_kind + `Permanent + ~id:"block_header.invalid_block_signature" + ~title:"Invalid block signature" + ~description:"A block was not signed with the expected private key." + ~pp:(fun ppf (block, pkh) -> + Format.fprintf + ppf + "Invalid signature for block %a. Expected: %a." + Block_hash.pp_short + block + Signature.Public_key_hash.pp_short + pkh) + Data_encoding.( + obj2 + (req "block" Block_hash.encoding) + (req "expected" Signature.Public_key_hash.encoding)) + (function + | Invalid_block_signature (block, pkh) -> Some (block, pkh) | _ -> None) + (fun (block, pkh) -> Invalid_block_signature (block, pkh)) ; + register_error_kind + `Permanent + ~id:"block_header.invalid_stamp" + ~title:"Insufficient block proof-of-work stamp" + ~description:"The block's proof-of-work stamp is insufficient" + ~pp:(fun ppf () -> Format.fprintf ppf "Insufficient proof-of-work stamp") + Data_encoding.empty + (function Invalid_stamp -> Some () | _ -> None) + (fun () -> Invalid_stamp) ; + register_error_kind + `Permanent + ~id:"block_header.invalid_payload_hash" + ~title:"Invalid payload hash" + ~description:"Invalid payload hash." + ~pp:(fun ppf (expected, provided) -> + Format.fprintf + ppf + "Invalid payload hash (expected: %a, provided: %a)." + Block_payload_hash.pp_short + expected + Block_payload_hash.pp_short + provided) + Data_encoding.( + obj2 + (req "expected" Block_payload_hash.encoding) + (req "provided" Block_payload_hash.encoding)) + (function + | Invalid_payload_hash {expected; provided} -> Some (expected, provided) + | _ -> None) + (fun (expected, provided) -> Invalid_payload_hash {expected; provided}) ; + () ; + register_error_kind + `Permanent + ~id:"block_header.locked_round_after_block_round" + ~title:"Locked round after block round" + ~description:"Locked round after block round." + ~pp:(fun ppf (locked_round, round) -> + Format.fprintf + ppf + "Locked round (%a) is after the block round (%a)." + Round_repr.pp + locked_round + Round_repr.pp + round) + Data_encoding.( + obj2 + (req "locked_round" Round_repr.encoding) + (req "round" Round_repr.encoding)) + (function + | Locked_round_after_block_round {locked_round; round} -> + Some (locked_round, round) + | _ -> None) + (fun (locked_round, round) -> + Locked_round_after_block_round {locked_round; round}) ; + () ; + register_error_kind + `Permanent + ~id:"block_header.invalid_payload_round" + ~title:"Invalid payload round" + ~description:"The given payload round is invalid." + ~pp:(fun ppf (payload_round, round) -> + Format.fprintf + ppf + "The provided payload round (%a) is after the block round (%a)." + Round_repr.pp + payload_round + Round_repr.pp + round) + Data_encoding.( + obj2 + (req "payload_round" Round_repr.encoding) + (req "round" Round_repr.encoding)) + (function + | Invalid_payload_round {payload_round; round} -> + Some (payload_round, round) + | _ -> None) + (fun (payload_round, round) -> Invalid_payload_round {payload_round; round}) ; + register_error_kind + `Permanent + ~id:"block_header.insufficient_locked_round_evidence" + ~title:"Insufficient locked round evidence" + ~description:"Insufficient locked round evidence." + ~pp:(fun ppf (voting_power, consensus_threshold) -> + Format.fprintf + ppf + "The provided locked round evidence is not sufficient: provided %d \ + voting power but was expecting at least %d." + voting_power + consensus_threshold) + Data_encoding.( + obj2 (req "voting_power" int31) (req "consensus_threshold" int31)) + (function + | Insufficient_locked_round_evidence {voting_power; consensus_threshold} + -> + Some (voting_power, consensus_threshold) + | _ -> None) + (fun (voting_power, consensus_threshold) -> + Insufficient_locked_round_evidence {voting_power; consensus_threshold}) ; + register_error_kind + `Permanent + ~id:"block_header.invalid_commitment" + ~title:"Invalid commitment in block header" + ~description:"The block header has invalid commitment." + ~pp:(fun ppf expected -> + if expected then + Format.fprintf ppf "Missing seed's nonce commitment in block header." + else + Format.fprintf ppf "Unexpected seed's nonce commitment in block header.") + Data_encoding.(obj1 (req "expected" bool)) + (function Invalid_commitment {expected} -> Some expected | _ -> None) + (fun expected -> Invalid_commitment {expected}) ; + register_error_kind + `Permanent + ~id:"block_header.wrong_timestamp" + ~title:"Wrong timestamp" + ~description:"Block timestamp not the expected one." + ~pp:(fun ppf (block_ts, expected_ts) -> + Format.fprintf + ppf + "Wrong timestamp: block timestamp (%a) not the expected one (%a)" + Time.pp_hum + block_ts + Time.pp_hum + expected_ts) + Data_encoding.( + obj2 + (req "block_timestamp" Time.encoding) + (req "expected_timestamp" Time.encoding)) + (function Wrong_timestamp (t1, t2) -> Some (t1, t2) | _ -> None) + (fun (t1, t2) -> Wrong_timestamp (t1, t2)) + +let check_signature (block : t) (chain_id : Chain_id.t) + (key : Signature.Public_key.t) = + let check_signature key ({shell; protocol_data = {contents; signature}} : t) = + let unsigned_header = + Data_encoding.Binary.to_bytes_exn unsigned_encoding (shell, contents) + in + Signature.check + ~watermark:(to_watermark (Block_header chain_id)) + key + signature + unsigned_header + in + if check_signature key block then ok () + else + error (Invalid_block_signature (hash block, Signature.Public_key.hash key)) + +let check_payload_round ~round ~payload_round = + error_when + Round_repr.(payload_round > round) + (Invalid_payload_round {payload_round; round}) + +let check_timestamp round_durations ~timestamp ~round ~predecessor_timestamp + ~predecessor_round = + Round_repr.timestamp_of_round + round_durations + ~predecessor_timestamp + ~predecessor_round + ~round + >>? fun expected_timestamp -> + if Time_repr.(expected_timestamp = timestamp) then Error_monad.ok () + else error (Wrong_timestamp (timestamp, expected_timestamp)) + +module Proof_of_work = struct + let check_hash hash stamp_threshold = + let bytes = Block_hash.to_bytes hash in + let word = TzEndian.get_int64 bytes 0 in + Compare.Uint64.(word <= stamp_threshold) + + let check_header_proof_of_work_stamp shell contents stamp_threshold = + let hash = + hash {shell; protocol_data = {contents; signature = Signature.zero}} + in + check_hash hash stamp_threshold + + let check_proof_of_work_stamp ~proof_of_work_threshold block = + if + check_header_proof_of_work_stamp + block.shell + block.protocol_data.contents + proof_of_work_threshold + then ok () + else error Invalid_stamp +end + +let begin_validate_block_header ~(block_header : t) ~(chain_id : Chain_id.t) + ~(predecessor_timestamp : Time.t) ~(predecessor_round : Round_repr.t) + ~(fitness : Fitness_repr.t) ~(timestamp : Time.t) + ~(delegate_pk : Signature.Public_key.t) + ~(round_durations : Round_repr.Durations.t) + ~(proof_of_work_threshold : int64) ~(expected_commitment : bool) = + (* Level relationship between current node and the predecessor is + done by the shell. We know that level is predecessor level + 1. + The predecessor block hash is guaranteed by the shell to be the + one in the shell header. The operations are guaranteed to + correspond to the shell_header.operations_hash by the shell *) + let {payload_round; seed_nonce_hash; _} = + block_header.protocol_data.contents + in + let raw_level = block_header.shell.level in + Proof_of_work.check_proof_of_work_stamp ~proof_of_work_threshold block_header + >>? fun () -> + Raw_level_repr.of_int32 raw_level >>? fun level -> + check_signature block_header chain_id delegate_pk >>? fun () -> + let round = Fitness_repr.round fitness in + check_payload_round ~round ~payload_round >>? fun () -> + check_timestamp + round_durations + ~predecessor_timestamp + ~predecessor_round + ~timestamp + ~round + >>? fun () -> + Fitness_repr.check_except_locked_round fitness ~level ~predecessor_round + >>? fun () -> + let has_commitment = + match seed_nonce_hash with None -> false | Some _ -> true + in + error_unless + Compare.Bool.(has_commitment = expected_commitment) + (Invalid_commitment {expected = expected_commitment}) + +type checkable_payload_hash = + | No_check + | Expected_payload_hash of Block_payload_hash.t + +let finalize_validate_block_header ~(block_header_contents : contents) + ~(round : Round_repr.t) + ~(* We have to check the round because in the construction case it was + deduced from the time *) + (fitness : Fitness_repr.t) + ~(checkable_payload_hash : checkable_payload_hash) + ~(locked_round_evidence : locked_round_evidence option) + ~(consensus_threshold : int) = + let { + payload_hash = actual_payload_hash; + seed_nonce_hash = _; + proof_of_work_nonce = _; + _; + } = + block_header_contents + in + (match checkable_payload_hash with + | No_check -> Result.return_unit + | Expected_payload_hash bph -> + error_unless + (Block_payload_hash.equal actual_payload_hash bph) + (Invalid_payload_hash {expected = bph; provided = actual_payload_hash})) + >>? fun () -> + (match locked_round_evidence with + | None -> ok None + | Some {preendorsement_count; preendorsement_round} -> + error_when + Round_repr.(preendorsement_round >= round) + (Locked_round_after_block_round + {locked_round = preendorsement_round; round}) + >>? fun () -> + error_when + Compare.Int.(preendorsement_count < consensus_threshold) + (Insufficient_locked_round_evidence + {voting_power = preendorsement_count; consensus_threshold}) + >>? fun () -> ok (Some preendorsement_round)) + >>? fun locked_round -> Fitness_repr.check_locked_round fitness ~locked_round diff --git a/src/proto_012_PsiThaCa/lib_protocol/block_header_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/block_header_repr.mli new file mode 100644 index 000000000000..e4b3d09086e4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/block_header_repr.mli @@ -0,0 +1,159 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Representation of block headers. *) + +type contents = { + payload_hash : Block_payload_hash.t; + payload_round : Round_repr.t; + seed_nonce_hash : Nonce_hash.t option; + proof_of_work_nonce : bytes; + liquidity_baking_escape_vote : bool; + (* set by baker to vote in favor of permanently disabling liquidity baking *) +} + +type protocol_data = {contents : contents; signature : Signature.t} + +type t = {shell : Block_header.shell_header; protocol_data : protocol_data} + +type block_header = t + +type raw = Block_header.t + +type shell_header = Block_header.shell_header + +val raw : block_header -> raw + +val encoding : block_header Data_encoding.encoding + +val raw_encoding : raw Data_encoding.t + +val contents_encoding : contents Data_encoding.t + +val unsigned_encoding : (Block_header.shell_header * contents) Data_encoding.t + +val protocol_data_encoding : protocol_data Data_encoding.encoding + +val shell_header_encoding : shell_header Data_encoding.encoding + +type block_watermark = Block_header of Chain_id.t + +val to_watermark : block_watermark -> Signature.watermark + +val of_watermark : Signature.watermark -> block_watermark option + +(** The maximum size of block headers in bytes *) +val max_header_length : int + +val hash : block_header -> Block_hash.t + +val hash_raw : raw -> Block_hash.t + +type error += + | (* Permanent *) + Invalid_block_signature of + Block_hash.t * Signature.Public_key_hash.t + | (* Permanent *) Invalid_stamp + | (* Permanent *) + Invalid_payload_hash of { + expected : Block_payload_hash.t; + provided : Block_payload_hash.t; + } + | (* Permanent *) + Locked_round_after_block_round of { + locked_round : Round_repr.t; + round : Round_repr.t; + } + | (* Permanent *) + Invalid_payload_round of { + payload_round : Round_repr.t; + round : Round_repr.t; + } + | (* Permanent *) + Insufficient_locked_round_evidence of { + voting_power : int; + consensus_threshold : int; + } + | (* Permanent *) Invalid_commitment of {expected : bool} + +(** Checks if the header that would be built from the given components + is valid for the given difficulty. The signature is not passed as + it is does not impact the proof-of-work stamp. The stamp is checked + on the hash of a block header whose signature has been + zeroed-out. *) +module Proof_of_work : sig + val check_hash : Block_hash.t -> int64 -> bool + + val check_header_proof_of_work_stamp : + shell_header -> contents -> int64 -> bool + + val check_proof_of_work_stamp : + proof_of_work_threshold:int64 -> block_header -> unit tzresult +end + +(** [check_timestamp ctxt timestamp round predecessor_timestamp + predecessor_round] verifies that the block's timestamp and round + are coherent with the predecessor block's timestamp and + round. Fails with an error if that is not the case. *) +val check_timestamp : + Round_repr.Durations.t -> + timestamp:Time.t -> + round:Round_repr.t -> + predecessor_timestamp:Time.t -> + predecessor_round:Round_repr.t -> + unit tzresult + +val check_signature : t -> Chain_id.t -> Signature.Public_key.t -> unit tzresult + +val begin_validate_block_header : + block_header:t -> + chain_id:Chain_id.t -> + predecessor_timestamp:Time.t -> + predecessor_round:Round_repr.t -> + fitness:Fitness_repr.t -> + timestamp:Time.t -> + delegate_pk:Signature.public_key -> + round_durations:Round_repr.Durations.t -> + proof_of_work_threshold:int64 -> + expected_commitment:bool -> + unit tzresult + +type locked_round_evidence = { + preendorsement_round : Round_repr.t; + preendorsement_count : int; +} + +type checkable_payload_hash = + | No_check + | Expected_payload_hash of Block_payload_hash.t + +val finalize_validate_block_header : + block_header_contents:contents -> + round:Round_repr.t -> + fitness:Fitness_repr.t -> + checkable_payload_hash:checkable_payload_hash -> + locked_round_evidence:locked_round_evidence option -> + consensus_threshold:int -> + unit tzresult diff --git a/src/proto_012_PsiThaCa/lib_protocol/block_payload_hash.ml b/src/proto_012_PsiThaCa/lib_protocol/block_payload_hash.ml new file mode 100644 index 000000000000..724dec25f8b1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/block_payload_hash.ml @@ -0,0 +1,42 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* 32 *) +let prefix = "\001\106\242" (* vh(52) *) + +include + Blake2B.Make + (Base58) + (struct + let name = "value_hash" + + let title = "Hash of a consensus value" + + let b58check_prefix = prefix + + let size = None + end) + +let () = Base58.check_encoded_prefix b58check_encoding "vh" 52 diff --git a/src/proto_012_PsiThaCa/lib_protocol/block_payload_hash.mli b/src/proto_012_PsiThaCa/lib_protocol/block_payload_hash.mli new file mode 100644 index 000000000000..90280546e53c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/block_payload_hash.mli @@ -0,0 +1,28 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** A specialized Blake2B implementation for hashing block's payloads. *) + +include S.HASH diff --git a/src/proto_012_PsiThaCa/lib_protocol/block_payload_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/block_payload_repr.ml new file mode 100644 index 000000000000..ad46807466a5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/block_payload_repr.ml @@ -0,0 +1,41 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Value on which validators try to reach a consensus. + + Consensus at a given level is reached on a sequence of operations. However, + to differentiate between two blocks having the same sequence of operations, + assuming that could ever happen (for instance, two empty blocks), we also + include the hash of the block that precedes the block where these operations + should be included. *) + +let hash ~predecessor round operations_hash = + let open Data_encoding in + let predecessor = Binary.to_bytes_exn Block_hash.encoding predecessor in + let round = Binary.to_bytes_exn Round_repr.encoding round in + let operations_hash = + Binary.to_bytes_exn Operation_list_hash.encoding operations_hash + in + Block_payload_hash.hash_bytes [predecessor; round; operations_hash] diff --git a/src/proto_012_PsiThaCa/lib_protocol/block_payload_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/block_payload_repr.mli new file mode 100644 index 000000000000..82c672e280cb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/block_payload_repr.mli @@ -0,0 +1,41 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Value on which validators try to reach a consensus. + + Consensus at a given level is reached on a sequence of operations. However, + to differentiate between two blocks having the same sequence of operations, + assuming that could ever happen (for instance, two empty blocks), we also + include the hash of the block that precedes the block where these operations + should be included. *) + +(** [hash ~predecessor:block_hash round oplh] creates a payload hash given a + [block_hash], the first [round] at which the payload was proposed + and the hash [oplh] of the non-consensus operations. *) +val hash : + predecessor:Block_hash.t -> + Round_repr.t -> + Operation_list_hash.t -> + Block_payload_hash.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/bootstrap_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/bootstrap_storage.ml new file mode 100644 index 000000000000..3636d5f1793e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/bootstrap_storage.ml @@ -0,0 +1,120 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let init_account (ctxt, balance_updates) + ({public_key_hash; public_key; amount} : Parameters_repr.bootstrap_account) + = + let contract = Contract_repr.implicit_contract public_key_hash in + Token.transfer + ~origin:Protocol_migration + ctxt + `Bootstrap + (`Contract contract) + amount + >>=? fun (ctxt, new_balance_updates) -> + (match public_key with + | Some public_key -> + Contract_manager_storage.reveal_manager_key + ctxt + public_key_hash + public_key + >>=? fun ctxt -> Delegate_storage.set ctxt contract (Some public_key_hash) + | None -> return ctxt) + >|=? fun ctxt -> (ctxt, new_balance_updates @ balance_updates) + +let init_contract ~typecheck (ctxt, balance_updates) + ({delegate; amount; script} : Parameters_repr.bootstrap_contract) = + Contract_storage.fresh_contract_from_current_nonce ctxt + >>?= fun (ctxt, contract) -> + typecheck ctxt script >>=? fun (script, ctxt) -> + Contract_storage.raw_originate + ctxt + ~prepaid_bootstrap_storage:true + contract + ~script + >>=? fun ctxt -> + (match delegate with + | None -> return ctxt + | Some delegate -> Delegate_storage.init ctxt contract delegate) + >>=? fun ctxt -> + let origin = Receipt_repr.Protocol_migration in + Token.transfer ~origin ctxt `Bootstrap (`Contract contract) amount + >|=? fun (ctxt, new_balance_updates) -> + (ctxt, new_balance_updates @ balance_updates) + +let init ctxt ~typecheck ?no_reward_cycles accounts contracts = + let nonce = Operation_hash.hash_string ["Un festival de GADT."] in + let ctxt = Raw_context.init_origination_nonce ctxt nonce in + List.fold_left_es init_account (ctxt, []) accounts + >>=? fun (ctxt, balance_updates) -> + List.fold_left_es (init_contract ~typecheck) (ctxt, balance_updates) contracts + >>=? fun (ctxt, balance_updates) -> + (match no_reward_cycles with + | None -> return ctxt + | Some cycles -> + (* Store pending ramp ups. *) + let constants = Raw_context.constants ctxt in + (* Start without rewards *) + Raw_context.patch_constants ctxt (fun c -> + { + c with + baking_reward_fixed_portion = Tez_repr.zero; + baking_reward_bonus_per_slot = Tez_repr.zero; + endorsing_reward_per_slot = Tez_repr.zero; + }) + >>= fun ctxt -> + (* Store the final reward. *) + Storage.Ramp_up.( + Rewards.init + ctxt + (Cycle_repr.of_int32_exn (Int32.of_int cycles)) + { + baking_reward_fixed_portion = constants.baking_reward_fixed_portion; + baking_reward_bonus_per_slot = + constants.baking_reward_bonus_per_slot; + endorsing_reward_per_slot = constants.endorsing_reward_per_slot; + })) + >|=? fun ctxt -> (ctxt, balance_updates) + +let cycle_end ctxt last_cycle = + let next_cycle = Cycle_repr.succ last_cycle in + Storage.Ramp_up.Rewards.find ctxt next_cycle >>=? function + | None -> return ctxt + | Some + Storage.Ramp_up. + { + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + } -> + Storage.Ramp_up.Rewards.remove_existing ctxt next_cycle >>=? fun ctxt -> + Raw_context.patch_constants ctxt (fun c -> + { + c with + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + }) + >|= ok diff --git a/src/proto_012_PsiThaCa/lib_protocol/bootstrap_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/bootstrap_storage.mli new file mode 100644 index 000000000000..3b72ec8ca940 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/bootstrap_storage.mli @@ -0,0 +1,38 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val init : + Raw_context.t -> + typecheck: + (Raw_context.t -> + Script_repr.t -> + ((Script_repr.t * Lazy_storage_diff.diffs option) * Raw_context.t) tzresult + Lwt.t) -> + ?no_reward_cycles:int -> + Parameters_repr.bootstrap_account list -> + Parameters_repr.bootstrap_contract list -> + (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t + +val cycle_end : Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/cache_memory_helpers.ml b/src/proto_012_PsiThaCa/lib_protocol/cache_memory_helpers.ml new file mode 100644 index 000000000000..83bdeb348494 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/cache_memory_helpers.ml @@ -0,0 +1,168 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** The [Nodes] module is used to count the number of computation steps + performed when evaluating the size of the in-memory graph corresponding + to an OCaml value. + + In first approximation, the value of type [Nodes.t] threaded through + {!expr_size} below and through the module {!Script_typed_ir_size} + is meant to match the number of recursive calls in the [traverse] + functions of {!Script_typed_ir} and in that of {!node_size}. + + The assumption is that there's a bounded amount of work performed between + two such recursive calls, hence that the total work is bounded above + by something proportional to the [Nodes.t] accumulator. + + Computations on values of type [Nodes.t] do not overflow, as they + are bounded above by the number of nodes traversed when computing + an OCaml value. + *) +module Nodes : sig + type t = private int + + val zero : t + + val one : t [@@ocaml.warning "-32"] + + val succ : t -> t + + val add : t -> t -> t + + val to_int : t -> int +end = struct + type t = int + + let zero = 0 + + let one = 1 + + let succ x = x + 1 + + let add x y = x + y + + let to_int x = x +end + +(** {2 Helpers to deal with computing the in-memory size of values} *) + +type sint = Saturation_repr.may_saturate Saturation_repr.t + +type nodes_and_size = Nodes.t * sint + +let ( !! ) = Saturation_repr.safe_int + +let ( +! ) = Saturation_repr.add + +let ( +? ) s x = Saturation_repr.add s !!x + +let ( *? ) s x = Saturation_repr.mul s !!x + +let ( /? ) s x = Saturation_repr.ediv s !!x + +let ( ++ ) (n1, s1) (n2, s2) = (Nodes.add n1 n2, s1 +! s2) + +let zero = (Nodes.zero, !!0) + +let word_size = !!8 + +let header_size = word_size + +let int64_size = header_size +! (word_size *? 2) + +let h1w = header_size +! word_size + +let h2w = header_size +! (word_size *? 2) + +let h3w = header_size +! (word_size *? 3) + +let h4w = header_size +! (word_size *? 4) + +let h5w = header_size +! (word_size *? 5) + +let hh3w = (word_size *? 3) +! (header_size *? 2) + +let hh6w = (word_size *? 6) +! (header_size *? 2) + +let hh8w = (word_size *? 8) +! (header_size *? 2) + +let z_size z = + let numbits = Z.numbits z in + if Compare.Int.(numbits <= 62) then !!0 else (word_size *? Z.size z) +? 32 + +let string_size_gen len = header_size +? (len + (8 - (len mod 8))) + +let bytes_size b = string_size_gen (Bytes.length b) + +let string_size s = string_size_gen (String.length s) + +let ret_adding (nodes, size) added = (nodes, size +! added) + +let ret_succ_adding (nodes, size) added = (Nodes.succ nodes, size +! added) + +let ret_succ (nodes, size) = (Nodes.succ nodes, size) + +let option_size some x = + let some x = h1w +! some x in + Option.fold ~none:!!0 ~some x + +let option_size_vec some x = + let some x = ret_adding (some x) h1w in + Option.fold ~none:zero ~some x + +let list_cell_size elt_size = + header_size +! word_size +! word_size +! elt_size + [@@ocaml.inline always] + +let list_fold_size elt_size list = + List.fold_left + (fun accu elt -> ret_succ_adding (accu ++ elt_size elt) h2w) + zero + list + +let boxed_tup2 x y = + header_size +! word_size +! word_size +! x +! y + [@@ocaml.inline always] + +let node_size = + let open Micheline in + let annotation_size a = + List.fold_left + (fun accu s -> ret_succ_adding accu (h2w +! string_size s)) + zero + a + in + let internal_node_size = function + | Int (_, z) -> (Nodes.one, h2w +! z_size z) + | String (_, s) -> (Nodes.one, h2w +! string_size s) + | Bytes (_, s) -> (Nodes.one, h2w +! bytes_size s) + | Prim (_, _, _, a) -> ret_succ_adding (annotation_size a) h4w + | Seq (_, _) -> (Nodes.one, h2w) + in + fun node -> + Script_repr.fold node zero @@ fun accu node -> + accu ++ internal_node_size node + +let expr_size expr = node_size (Micheline.root expr) diff --git a/src/proto_012_PsiThaCa/lib_protocol/cache_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/cache_repr.ml new file mode 100644 index 000000000000..6aeada3338db --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/cache_repr.ml @@ -0,0 +1,249 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Cache_costs = struct + module S = Saturation_repr + + (* Computed by typing the contract + "{parameter unit; storage unit; code FAILWITH}" + and evaluating + [(8 * Obj.reachable_words (Obj.repr typed_script))] + where [typed_script] is of type [ex_script] *) + let minimal_size_of_typed_contract_in_bytes = 688 + + let approximate_cardinal bytes = + S.safe_int (bytes / minimal_size_of_typed_contract_in_bytes) + + let log2 x = S.safe_int (1 + S.numbits x) + + let cache_update_constant = S.safe_int 600 + + let cache_update_coeff = S.safe_int 57 + + (* Cost of calling [Environment_cache.update]. *) + let cache_update ~cache_size_in_bytes = + let approx_card = approximate_cardinal cache_size_in_bytes in + Gas_limit_repr.atomic_step_cost + S.(add cache_update_constant (mul cache_update_coeff (log2 approx_card))) + + (* Cost of calling [Environment_cache.find]. + This overapproximates [cache_find] slightly. *) + let cache_find = cache_update +end + +type index = int + +type size = int + +type identifier = string + +type namespace = string + +let compare_namespace = Compare.String.compare + +type internal_identifier = {namespace : namespace; id : identifier} + +let separator = '@' + +let sanitize namespace = + if String.contains namespace separator then + invalid_arg + (Format.asprintf + "Invalid cache namespace: '%s'. Character %c is forbidden." + namespace + separator) + else namespace + +let create_namespace = sanitize + +let string_of_internal_identifier {namespace; id} = + namespace ^ String.make 1 separator ^ id + +let internal_identifier_of_string raw = + match String.index_opt raw separator with + | None -> assert false + | Some index -> + { + (* We do not need to call sanitize here since we stop at the first '@' + from index 0. It is a guarantee that there is no '@' between 0 and + (index - 1 ). *) + namespace = String.sub raw 0 index; + id = + (let delim_idx = index + 1 in + String.sub raw delim_idx (String.length raw - delim_idx)); + } + +let internal_identifier_of_key key = + let raw = Raw_context.Cache.identifier_of_key key in + internal_identifier_of_string raw + +let key_of_internal_identifier ~cache_index identifier = + let raw = string_of_internal_identifier identifier in + Raw_context.Cache.key_of_identifier ~cache_index raw + +let make_key = + let namespaces = ref [] in + fun ~cache_index ~namespace -> + if List.mem ~equal:String.equal namespace !namespaces then + invalid_arg + (Format.sprintf "Cache key namespace %s already exist." namespace) + else ( + namespaces := namespace :: !namespaces ; + fun ~id -> + let identifier = {namespace; id} in + key_of_internal_identifier ~cache_index identifier) + +module NamespaceMap = Map.Make (struct + type t = namespace + + let compare = compare_namespace +end) + +type partial_key_handler = + Raw_context.t -> string -> Context.Cache.value tzresult Lwt.t + +let value_of_key_handlers : partial_key_handler NamespaceMap.t ref = + ref NamespaceMap.empty + +module Admin = struct + include Raw_context.Cache + + let list_keys context ~cache_index = + Raw_context.Cache.list_keys context ~cache_index + + let key_rank context key = Raw_context.Cache.key_rank context key + + let value_of_key ctxt key = + (* [value_of_key] is a maintenance operation: it is typically run + when a node reboots. For this reason, this operation is not + carbonated. *) + let ctxt = Raw_context.set_gas_unlimited ctxt in + let {namespace; id} = internal_identifier_of_key key in + match NamespaceMap.find namespace !value_of_key_handlers with + | Some value_of_key -> value_of_key ctxt id + | None -> + failwith + (Format.sprintf "No handler for key `%s%c%s'" namespace separator id) +end + +module type CLIENT = sig + val cache_index : int + + val namespace : namespace + + type cached_value + + val value_of_identifier : + Raw_context.t -> identifier -> cached_value tzresult Lwt.t +end + +module type INTERFACE = sig + type cached_value + + val update : + Raw_context.t -> + identifier -> + (cached_value * int) option -> + Raw_context.t tzresult + + val find : Raw_context.t -> identifier -> cached_value option tzresult Lwt.t + + val list_identifiers : Raw_context.t -> (identifier * int) list + + val identifier_rank : Raw_context.t -> identifier -> int option + + val size : Raw_context.t -> size + + val size_limit : Raw_context.t -> size +end + +let register_exn (type cvalue) + (module C : CLIENT with type cached_value = cvalue) : + (module INTERFACE with type cached_value = cvalue) = + if + Compare.Int.(C.cache_index < 0) + || Compare.List_length_with.(Constants_repr.cache_layout <= C.cache_index) + then invalid_arg "Cache index is invalid" ; + let mk = make_key ~cache_index:C.cache_index ~namespace:C.namespace in + (module struct + type cached_value = C.cached_value + + type Admin.value += K of cached_value + + let () = + let voi ctxt i = + C.value_of_identifier ctxt i >>=? fun v -> return (K v) + in + value_of_key_handlers := + NamespaceMap.add C.namespace voi !value_of_key_handlers + + let size ctxt = + Option.value ~default:max_int + @@ Admin.cache_size ctxt ~cache_index:C.cache_index + + let size_limit ctxt = + Option.value ~default:max_int + @@ Admin.cache_size_limit ctxt ~cache_index:C.cache_index + + let update ctxt id v = + let cache_size_in_bytes = size ctxt in + Raw_context.consume_gas + ctxt + (Cache_costs.cache_update ~cache_size_in_bytes) + >|? fun ctxt -> + let v = Option.map (fun (v, size) -> (K v, size)) v in + Admin.update ctxt (mk ~id) v + + let find ctxt id = + let cache_size_in_bytes = size ctxt in + Raw_context.consume_gas ctxt (Cache_costs.cache_find ~cache_size_in_bytes) + >>?= fun ctxt -> + Admin.find ctxt (mk ~id) >>= function + | None -> return None + | Some (K v) -> return (Some v) + | _ -> + (* This execution path is impossible because all the keys of + C's namespace (which is unique to C) are constructed with + [K]. This [assert false] could have been pushed into the + environment in exchange for extra complexity. The + argument that justifies this [assert false] seems + simple enough to keep the current design though. *) + assert false + + let list_identifiers ctxt = + Admin.list_keys ctxt ~cache_index:C.cache_index |> function + | None -> + (* `cache_index` is valid. *) + assert false + | Some list -> + List.filter_map + (fun (key, age) -> + let {namespace; id} = internal_identifier_of_key key in + if String.equal namespace C.namespace then Some (id, age) + else None) + list + + let identifier_rank ctxt id = Admin.key_rank ctxt (mk ~id) + end) diff --git a/src/proto_012_PsiThaCa/lib_protocol/cache_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/cache_repr.mli new file mode 100644 index 000000000000..feefb25ec55b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/cache_repr.mli @@ -0,0 +1,233 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** + + Frequently used data should be kept in memory and persisted along a + chain of blocks. The caching mechanism allows the economic protocol + to declare such data and to rely on a Least Recently Used strategy + to keep the cache size under a fixed limit. + + Take a look at {!Environment_cache} and {!Environment_context} + for additional implementation details about the protocol cache. + + The protocol has two main kinds of interaction with the cache: + + 1. It is responsible for setting up the cache with appropriate + parameter values and callbacks. It must also compute cache nonces + to give the shell enough information to properly synchronize the + in-memory cache with the block contexts and protocol upgrades. + A typical place where this happens is {!Apply}. + This aspect must be implemented using {!Cache.Admin}. + + 2. It can exploit the cache to retrieve, to insert, and to update + cached values from the in-memory cache. The basic idea is to + avoid recomputing values from scratch at each block when they are + frequently used. {!Script_cache} is an example of such usage. + This aspect must be implemented using {!Cache.Interface}. + + *) + +(** Size for subcaches and values of the cache. *) +type size = int + +(** Index type to index caches. *) +type index = int + +(** + + The following module acts on the whole cache, not on a specific + sub-cache, unlike {!Interface}. It is used to administrate the + protocol cache, e.g., to maintain the cache in a consistent state + with respect to the chain. This module is typically used by + low-level layers of the protocol and by the shell. + + *) +module Admin : sig + (** A key uniquely identifies a cached [value] in some subcache. *) + type key + + (** Cached values. *) + type value + + (** [pp fmt ctxt] is a pretty printter for the [cache] of [ctxt]. *) + val pp : Format.formatter -> Raw_context.t -> unit + + (** [set_cache_layout ctxt layout] sets the caches of [ctxt] to + comply with given [layout]. If there was already a cache in + [ctxt], it is erased by the new layout. + + In that case, a fresh collection of empty caches is reconstructed + from the new [layout]. Notice that cache [key]s are invalidated + in that case, i.e. [find t k] will return [None]. *) + val set_cache_layout : Raw_context.t -> size list -> Raw_context.t Lwt.t + + (** [sync ctxt ~cache_nonce] updates the context with the domain of + the cache computed so far. Such function is expected to be called + at the end of the validation of a block, when there is no more + accesses to the cache. + + [cache_nonce] identifies the block that introduced new cache + entries. The nonce should identify uniquely the block which + modifies this value. It cannot be the block hash for circularity + reasons: The value of the nonce is stored onto the context and + consequently influences the context hash of the very same + block. Such nonce cannot be determined by the shell and its + computation is delegated to the economic protocol. *) + val sync : Raw_context.t -> cache_nonce:Bytes.t -> Raw_context.t Lwt.t + + (** [clear ctxt] removes all cache entries. *) + val clear : Raw_context.t -> Raw_context.t + + (** {3 Cache helpers for RPCs} *) + + (** [future_cache_expectation ctxt ~time_in_blocks] returns [ctxt] except + that the entries of the caches that are presumably too old to + still be in the caches in [n_blocks] are removed. + + This function is based on a heuristic. The context maintains + the median of the number of removed entries: this number is + multipled by `n_blocks` to determine the entries that are + likely to be removed in `n_blocks`. *) + val future_cache_expectation : + Raw_context.t -> time_in_blocks:int -> Raw_context.t + + (** [cache_size ctxt ~cache_index] returns an overapproximation of + the size of the cache. Returns [None] if [cache_index] is + greater than the number of subcaches declared by the cache + layout. *) + val cache_size : Raw_context.t -> cache_index:int -> size option + + (** [cache_size_limit ctxt ~cache_index] returns the maximal size of + the cache indexed by [cache_index]. Returns [None] if + [cache_index] is greater than the number of subcaches declared + by the cache layout. *) + val cache_size_limit : Raw_context.t -> cache_index:int -> size option + + (** [value_of_key ctxt k] interprets the functions introduced by + [register] to construct a cacheable value for a key [k]. *) + val value_of_key : + Raw_context.t -> Context.Cache.key -> Context.Cache.value tzresult Lwt.t +end + +(** A client uses a unique namespace (represented as a string + without '@') to avoid collision with the keys of other + clients. *) +type namespace = private string + +(** [create_namespace str] creates a valid namespace from [str] + + @raise Invalid_argument if [str] contains '@' + *) +val create_namespace : string -> namespace + +(** A key is fully determined by a namespace and an identifier. *) +type identifier = string + +(** + To use the cache, a client must implement the [CLIENT] + interface. + + *) +module type CLIENT = sig + (** The type of value to be stored in the cache. *) + type cached_value + + (** The client must declare the index of the subcache where its + values shall live. [cache_index] must be between [0] and + [List.length Constants_repr.cache_layout - 1]. *) + val cache_index : index + + (** The client must declare a namespace. This namespace must + be unique. Otherwise, the program stops. + A namespace cannot contain '@'. *) + val namespace : namespace + + (** [value_of_identifier id] builds the cached value identified by + [id]. This function is called when the subcache is loaded into + memory from the on-disk representation of its domain. + + An error during the execution of this function is fatal as + witnessed by its type: an error embedded in a [tzresult] is not + supposed to be caught by the protocol. *) + val value_of_identifier : + Raw_context.t -> identifier -> cached_value tzresult Lwt.t +end + +(** + + An [INTERFACE] to the subcache where keys live in a given [namespace]. + + *) +module type INTERFACE = sig + (** The type of value to be stored in the cache. *) + type cached_value + + (** [update ctxt i (Some (e, size))] returns a context where the + value [e] of given [size] is associated to identifier [i] in + the subcache. If [i] is already in the subcache, the cache + entry is updated. + + [update ctxt i None] removes [i] from the subcache. *) + val update : + Raw_context.t -> + identifier -> + (cached_value * size) option -> + Raw_context.t tzresult + + (** [find ctxt i = Some v] if [v] is the value associated to [i] + in the subcache. Returns [None] if there is no such value in + the subcache. This function is in the Lwt monad because if the + value may have not been constructed (see the lazy loading + mode in {!Environment_context}), it is constructed on the fly. *) + val find : Raw_context.t -> identifier -> cached_value option tzresult Lwt.t + + (** [list_identifiers ctxt] returns the list of the + identifiers of the cached values along with their respective + size. The returned list is sorted in terms of their age in the + cache, the oldest coming first. *) + val list_identifiers : Raw_context.t -> (string * int) list + + (** [identifier_rank ctxt identifier] returns the number of cached values + older than the one of [identifier]; or, [None] if the [identifier] has + no associated value in the subcache. *) + val identifier_rank : Raw_context.t -> string -> int option + + (** [size ctxt] returns an overapproximation of the subcache size + (in bytes). *) + val size : Raw_context.t -> int + + (** [size_limit ctxt] returns the maximal size of the subcache + (in bytes). *) + val size_limit : Raw_context.t -> int +end + +(** [register_exn client] produces an [Interface] specific to a + given [client]. This function can fail if [client] does not + respect the invariant declared in the documentation of + {!CLIENT}. *) +val register_exn : + (module CLIENT with type cached_value = 'a) -> + (module INTERFACE with type cached_value = 'a) diff --git a/src/proto_012_PsiThaCa/lib_protocol/commitment_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/commitment_repr.ml new file mode 100644 index 000000000000..38f114120c35 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/commitment_repr.ml @@ -0,0 +1,36 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = { + blinded_public_key_hash : Blinded_public_key_hash.t; + amount : Tez_repr.t; +} + +let encoding = + let open Data_encoding in + conv + (fun {blinded_public_key_hash; amount} -> (blinded_public_key_hash, amount)) + (fun (blinded_public_key_hash, amount) -> {blinded_public_key_hash; amount}) + (tup2 Blinded_public_key_hash.encoding Tez_repr.encoding) diff --git a/src/proto_012_PsiThaCa/lib_protocol/commitment_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/commitment_repr.mli new file mode 100644 index 000000000000..edca4134d844 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/commitment_repr.mli @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = { + blinded_public_key_hash : Blinded_public_key_hash.t; + amount : Tez_repr.t; +} + +val encoding : t Data_encoding.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/commitment_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/commitment_storage.ml new file mode 100644 index 000000000000..272702a4ae67 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/commitment_storage.ml @@ -0,0 +1,44 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let exists = Storage.Commitments.mem + +let committed_amount ctxt bpkh = + Storage.Commitments.find ctxt bpkh >>=? fun balance -> + return (Option.value ~default:Tez_repr.zero balance) + +let increase_commitment_only_call_from_token ctxt bpkh amount = + if Tez_repr.(amount = zero) then return ctxt + else + committed_amount ctxt bpkh >>=? fun balance -> + Tez_repr.(amount +? balance) >>?= fun new_balance -> + Storage.Commitments.add ctxt bpkh new_balance >|= ok + +let decrease_commitment_only_call_from_token ctxt bpkh amount = + committed_amount ctxt bpkh >>=? fun balance -> + Tez_repr.(balance -? amount) >>?= fun new_balance -> + if Tez_repr.(new_balance = Tez_repr.zero) then + Storage.Commitments.remove ctxt bpkh >|= ok + else Storage.Commitments.add ctxt bpkh new_balance >|= ok diff --git a/src/proto_012_PsiThaCa/lib_protocol/commitment_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/commitment_storage.mli new file mode 100644 index 000000000000..6c74e56a076a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/commitment_storage.mli @@ -0,0 +1,45 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** [exists ctxt bpkh] returns true iff [bpkh] is associated to a non null + commitment. *) +val exists : Raw_context.t -> Blinded_public_key_hash.t -> bool Lwt.t + +(** [committed_amount ctxt bpkh] return the commitment associated to [bpkh], or + [Tez_repr.zero] if [bpkh] has no associated commitment. *) +val committed_amount : + Raw_context.t -> Blinded_public_key_hash.t -> Tez_repr.t tzresult Lwt.t + +val increase_commitment_only_call_from_token : + Raw_context.t -> + Blinded_public_key_hash.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t + +val decrease_commitment_only_call_from_token : + Raw_context.t -> + Blinded_public_key_hash.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/constants_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/constants_repr.ml new file mode 100644 index 000000000000..4acea2a75df2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/constants_repr.ml @@ -0,0 +1,644 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* The fitness version number was: + - "\000" until and including proto 004 + - "\001" until and including proto 010 +*) +let fitness_version_number = "\002" + +let proof_of_work_nonce_size = 8 + +let nonce_length = 32 + +let max_anon_ops_per_block = 132 + +let max_proposals_per_delegate = 20 + +let max_operation_data_length = 32 * 1024 (* 32kB *) + +let max_micheline_node_count = 50_000 + +let max_micheline_bytes_limit = 50_000 + +let max_allowed_global_constant_depth = 10_000 + +(* In this version of the protocol, there are the following subcaches: + + * One for contract source code and storage. Its size has been + chosen not too exceed 100 000 000 bytes. + + * One for the stake distribution for all cycles stored at any + moment (* preserved_cycles + max_slashing_period + 1 *) + + * One for the sampler state for all cycles stored at any moment. *) + +let stake_distribution_size = 500 (* delegates*) * 15 (* words *) * 4 +(* bytes *) + +let sampler_state_size = 80 (* words *) * 4 (* bytes *) + +let cache_layout = + [ + 100_000_000; + 8 (* cycles *) * stake_distribution_size; + 8 (* cycles *) * sampler_state_size; + ] + +(* In previous versions of the protocol, this + [michelson_maximum_type_size] limit was set to 1000 but + the contract input types (pair ) + were not checked. Both components, and + where however checked hence it was possible to build + types as big as 2001. *) +let michelson_maximum_type_size = 2001 + +type fixed = unit + +type ratio = {numerator : int; denominator : int} + +let ratio_encoding = + let open Data_encoding in + conv_with_guard + (fun r -> (r.numerator, r.denominator)) + (fun (numerator, denominator) -> + if Compare.Int.(denominator > 0) then ok {numerator; denominator} + else Error "The denominator must be greater than 0.") + (obj2 (req "numerator" uint16) (req "denominator" uint16)) + +let pp_ratio fmt {numerator; denominator} = + Format.fprintf fmt "%d/%d" numerator denominator + +let fixed_encoding = + let open Data_encoding in + let uint62 = + let max_int_int64 = Int64.of_int max_int in + conv_with_guard + (fun int -> Int64.of_int int) + (fun int64 -> + if Compare.Int64.(int64 < 0L) then Error "Negative integer" + else if Compare.Int64.(int64 > max_int_int64) then + Error "Integer does not fit in 62 bits" + else ok @@ Int64.to_int int64) + int64 + in + conv + (fun () -> + ( proof_of_work_nonce_size, + nonce_length, + max_anon_ops_per_block, + max_operation_data_length, + max_proposals_per_delegate, + max_micheline_node_count, + max_micheline_bytes_limit, + max_allowed_global_constant_depth, + cache_layout, + michelson_maximum_type_size )) + (fun ( _proof_of_work_nonce_size, + _nonce_length, + _max_anon_ops_per_block, + _max_operation_data_length, + _max_proposals_per_delegate, + _max_micheline_node_count, + _max_micheline_bytes_limit, + _max_allowed_global_constant_depth, + _cache_layout, + _michelson_maximum_type_size ) -> ()) + (obj10 + (req "proof_of_work_nonce_size" uint8) + (req "nonce_length" uint8) + (req "max_anon_ops_per_block" uint8) + (req "max_operation_data_length" int31) + (req "max_proposals_per_delegate" uint8) + (req "max_micheline_node_count" int31) + (req "max_micheline_bytes_limit" int31) + (req "max_allowed_global_constants_depth" int31) + (req "cache_layout" (list uint62)) + (req "michelson_maximum_type_size" uint16)) + +let fixed = () + +type delegate_selection = + | Random + | Round_robin_over of Signature.Public_key.t list list + +let delegate_selection_encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"Random_delegate_selection" + (constant "random") + (function Random -> Some () | _ -> None) + (fun () -> Random); + case + (Tag 1) + ~title:"Round_robin_over_delegates" + (list (list Signature.Public_key.encoding)) + (function Round_robin_over l -> Some l | _ -> None) + (fun l -> Round_robin_over l); + ] + +(* The encoded representation of this type is stored in the context as + bytes. Changing the encoding, or the value of these constants from + the previous protocol may break the context migration, or (even + worse) yield an incorrect context after migration. + + If you change this encoding, you should ensure that there is a + proper migration of the constants during context migration. *) +type parametric = { + preserved_cycles : int; + blocks_per_cycle : int32; + blocks_per_commitment : int32; + blocks_per_stake_snapshot : int32; + blocks_per_voting_period : int32; + hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; + hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; + proof_of_work_threshold : int64; + tokens_per_roll : Tez_repr.t; + seed_nonce_revelation_tip : Tez_repr.t; + origination_size : int; + baking_reward_fixed_portion : Tez_repr.t; + baking_reward_bonus_per_slot : Tez_repr.t; + endorsing_reward_per_slot : Tez_repr.t; + cost_per_byte : Tez_repr.t; + hard_storage_limit_per_operation : Z.t; + quorum_min : int32; + quorum_max : int32; + min_proposal_quorum : int32; + liquidity_baking_subsidy : Tez_repr.t; + liquidity_baking_sunset_level : int32; + liquidity_baking_escape_ema_threshold : int32; + max_operations_time_to_live : int; + minimal_block_delay : Period_repr.t; + delay_increment_per_round : Period_repr.t; + minimal_participation_ratio : ratio; + consensus_committee_size : int; + consensus_threshold : int; + max_slashing_period : int; + frozen_deposits_percentage : int; + double_baking_punishment : Tez_repr.t; + ratio_of_frozen_deposits_slashed_per_double_endorsement : ratio; + delegate_selection : delegate_selection; +} + +let parametric_encoding = + let open Data_encoding in + conv + (fun c -> + ( ( c.preserved_cycles, + c.blocks_per_cycle, + c.blocks_per_commitment, + c.blocks_per_stake_snapshot, + c.blocks_per_voting_period, + c.hard_gas_limit_per_operation, + c.hard_gas_limit_per_block, + c.proof_of_work_threshold, + c.tokens_per_roll ), + ( ( c.seed_nonce_revelation_tip, + c.origination_size, + c.baking_reward_fixed_portion, + c.baking_reward_bonus_per_slot, + c.endorsing_reward_per_slot, + c.cost_per_byte, + c.hard_storage_limit_per_operation, + c.quorum_min ), + ( ( c.quorum_max, + c.min_proposal_quorum, + c.liquidity_baking_subsidy, + c.liquidity_baking_sunset_level, + c.liquidity_baking_escape_ema_threshold, + c.max_operations_time_to_live, + c.minimal_block_delay, + c.delay_increment_per_round, + c.consensus_committee_size, + c.consensus_threshold ), + ( c.minimal_participation_ratio, + c.max_slashing_period, + c.frozen_deposits_percentage, + c.double_baking_punishment, + c.ratio_of_frozen_deposits_slashed_per_double_endorsement, + c.delegate_selection ) ) ) )) + (fun ( ( preserved_cycles, + blocks_per_cycle, + blocks_per_commitment, + blocks_per_stake_snapshot, + blocks_per_voting_period, + hard_gas_limit_per_operation, + hard_gas_limit_per_block, + proof_of_work_threshold, + tokens_per_roll ), + ( ( seed_nonce_revelation_tip, + origination_size, + baking_reward_fixed_portion, + baking_reward_bonus_per_slot, + endorsing_reward_per_slot, + cost_per_byte, + hard_storage_limit_per_operation, + quorum_min ), + ( ( quorum_max, + min_proposal_quorum, + liquidity_baking_subsidy, + liquidity_baking_sunset_level, + liquidity_baking_escape_ema_threshold, + max_operations_time_to_live, + minimal_block_delay, + delay_increment_per_round, + consensus_committee_size, + consensus_threshold ), + ( minimal_participation_ratio, + max_slashing_period, + frozen_deposits_percentage, + double_baking_punishment, + ratio_of_frozen_deposits_slashed_per_double_endorsement, + delegate_selection ) ) ) ) -> + { + preserved_cycles; + blocks_per_cycle; + blocks_per_commitment; + blocks_per_stake_snapshot; + blocks_per_voting_period; + hard_gas_limit_per_operation; + hard_gas_limit_per_block; + proof_of_work_threshold; + tokens_per_roll; + seed_nonce_revelation_tip; + origination_size; + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + cost_per_byte; + hard_storage_limit_per_operation; + quorum_min; + quorum_max; + min_proposal_quorum; + liquidity_baking_subsidy; + liquidity_baking_sunset_level; + liquidity_baking_escape_ema_threshold; + max_operations_time_to_live; + minimal_block_delay; + delay_increment_per_round; + minimal_participation_ratio; + max_slashing_period; + consensus_committee_size; + consensus_threshold; + frozen_deposits_percentage; + double_baking_punishment; + ratio_of_frozen_deposits_slashed_per_double_endorsement; + delegate_selection; + }) + (merge_objs + (obj9 + (req "preserved_cycles" uint8) + (req "blocks_per_cycle" int32) + (req "blocks_per_commitment" int32) + (req "blocks_per_stake_snapshot" int32) + (req "blocks_per_voting_period" int32) + (req + "hard_gas_limit_per_operation" + Gas_limit_repr.Arith.z_integral_encoding) + (req + "hard_gas_limit_per_block" + Gas_limit_repr.Arith.z_integral_encoding) + (req "proof_of_work_threshold" int64) + (req "tokens_per_roll" Tez_repr.encoding)) + (merge_objs + (obj8 + (req "seed_nonce_revelation_tip" Tez_repr.encoding) + (req "origination_size" int31) + (req "baking_reward_fixed_portion" Tez_repr.encoding) + (req "baking_reward_bonus_per_slot" Tez_repr.encoding) + (req "endorsing_reward_per_slot" Tez_repr.encoding) + (req "cost_per_byte" Tez_repr.encoding) + (req "hard_storage_limit_per_operation" z) + (req "quorum_min" int32)) + (merge_objs + (obj10 + (req "quorum_max" int32) + (req "min_proposal_quorum" int32) + (req "liquidity_baking_subsidy" Tez_repr.encoding) + (req "liquidity_baking_sunset_level" int32) + (req "liquidity_baking_escape_ema_threshold" int32) + (req "max_operations_time_to_live" int16) + (req "minimal_block_delay" Period_repr.encoding) + (req "delay_increment_per_round" Period_repr.encoding) + (req "consensus_committee_size" int31) + (req "consensus_threshold" int31)) + (obj6 + (req "minimal_participation_ratio" ratio_encoding) + (req "max_slashing_period" int31) + (req "frozen_deposits_percentage" int31) + (req "double_baking_punishment" Tez_repr.encoding) + (req + "ratio_of_frozen_deposits_slashed_per_double_endorsement" + ratio_encoding) + (dft "delegate_selection" delegate_selection_encoding Random))))) + +type t = {fixed : fixed; parametric : parametric} + +let all parametric = {fixed; parametric} + +let encoding = + let open Data_encoding in + conv + (fun {fixed; parametric} -> (fixed, parametric)) + (fun (fixed, parametric) -> {fixed; parametric}) + (merge_objs fixed_encoding parametric_encoding) + +type error += Invalid_protocol_constants of string (* `Permanent *) + +let () = + register_error_kind + `Permanent + ~id:"constants.invalid_protocol_constants" + ~title:"Invalid protocol constants" + ~description:"The provided protocol constants are not coherent." + ~pp:(fun ppf reason -> + Format.fprintf ppf "Invalid protocol constants: %s" reason) + Data_encoding.(obj1 (req "reason" string)) + (function Invalid_protocol_constants reason -> Some reason | _ -> None) + (fun reason -> Invalid_protocol_constants reason) + +let check_constants constants = + error_unless + Period_repr.(constants.minimal_block_delay > zero) + (Invalid_protocol_constants + "The minimal block delay must be greater than zero") + >>? fun () -> + error_unless + Period_repr.(constants.delay_increment_per_round > zero) + (Invalid_protocol_constants + "The delay increment per round must be greater than zero") + >>? fun () -> + error_unless + Compare.Int.(constants.consensus_committee_size > 3) + (Invalid_protocol_constants + "The consensus committee size must be strictly greater than 3.") + >>? fun () -> + error_unless + Compare.Int.( + constants.consensus_threshold >= 0 + && constants.consensus_threshold <= constants.consensus_committee_size) + (Invalid_protocol_constants + "The consensus threshold must be greater than or equal to 0 and less \ + than or equal to the consensus commitee size.") + >>? fun () -> + error_unless + (let {numerator; denominator} = constants.minimal_participation_ratio in + Compare.Int.(numerator >= 0 && denominator > 0)) + (Invalid_protocol_constants + "The minimal participation ratio must be a non-negative valid ratio.") + >>? fun () -> + error_unless + Compare.Int.( + constants.minimal_participation_ratio.numerator + <= constants.minimal_participation_ratio.denominator) + (Invalid_protocol_constants + "The minimal participation ratio must be less than or equal to 100%.") + >>? fun () -> + error_unless + Compare.Int.(constants.max_slashing_period > 0) + (Invalid_protocol_constants + "The unfreeze delay must be strictly greater than 0.") + >>? fun () -> + (* The [frozen_deposits_percentage] should be a percentage *) + error_unless + Compare.Int.( + constants.frozen_deposits_percentage > 0 + && constants.frozen_deposits_percentage <= 100) + (Invalid_protocol_constants + "The frozen percentage ratio must be strictly greater than 0 and less \ + or equal than 100.") + >>? fun () -> + error_unless + Tez_repr.(constants.double_baking_punishment >= zero) + (Invalid_protocol_constants + "The double baking punishment must be non-negative.") + >>? fun () -> + error_unless + (let {numerator; denominator} = + constants.ratio_of_frozen_deposits_slashed_per_double_endorsement + in + Compare.Int.(numerator >= 0 && denominator > 0)) + (Invalid_protocol_constants + "The ratio of frozen deposits ratio slashed per double endorsement must \ + be a non-negative valid ratio.") + >>? fun () -> Result.return_unit + +module Generated = struct + type t = { + consensus_threshold : int; + baking_reward_fixed_portion : Tez_repr.t; + baking_reward_bonus_per_slot : Tez_repr.t; + endorsing_reward_per_slot : Tez_repr.t; + } + + let generate ~consensus_committee_size ~blocks_per_minute = + let consensus_threshold = (consensus_committee_size * 2 / 3) + 1 in + (* As in previous protocols, we set the maximum total rewards per minute to + be 80 tez. *) + let rewards_per_minute = Tez_repr.(mul_exn one 80) in + let rewards_per_block = + Tez_repr.( + div_exn + (mul_exn rewards_per_minute blocks_per_minute.denominator) + blocks_per_minute.numerator) + in + let rewards_half = Tez_repr.(div_exn rewards_per_block 2) in + let rewards_quarter = Tez_repr.(div_exn rewards_per_block 4) in + { + consensus_threshold; + baking_reward_fixed_portion = rewards_quarter; + baking_reward_bonus_per_slot = + Tez_repr.div_exn + rewards_quarter + (consensus_committee_size - consensus_threshold); + endorsing_reward_per_slot = + Tez_repr.div_exn rewards_half consensus_committee_size; + } +end + +module Proto_previous = struct + type parametric = { + preserved_cycles : int; + blocks_per_cycle : int32; + blocks_per_commitment : int32; + blocks_per_roll_snapshot : int32; + blocks_per_voting_period : int32; + time_between_blocks : Period_repr.t list; + minimal_block_delay : Period_repr.t; + endorsers_per_block : int; + hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; + hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; + proof_of_work_threshold : int64; + tokens_per_roll : Tez_repr.t; + seed_nonce_revelation_tip : Tez_repr.t; + origination_size : int; + block_security_deposit : Tez_repr.t; + endorsement_security_deposit : Tez_repr.t; + baking_reward_per_endorsement : Tez_repr.t list; + endorsement_reward : Tez_repr.t list; + cost_per_byte : Tez_repr.t; + hard_storage_limit_per_operation : Z.t; + quorum_min : int32; + quorum_max : int32; + min_proposal_quorum : int32; + initial_endorsers : int; + delay_per_missing_endorsement : Period_repr.t; + liquidity_baking_subsidy : Tez_repr.t; + liquidity_baking_sunset_level : int32; + liquidity_baking_escape_ema_threshold : int32; + } + + let parametric_encoding = + let open Data_encoding in + conv + (fun c -> + ( ( c.preserved_cycles, + c.blocks_per_cycle, + c.blocks_per_commitment, + c.blocks_per_roll_snapshot, + c.blocks_per_voting_period, + c.time_between_blocks, + c.endorsers_per_block, + c.hard_gas_limit_per_operation, + c.hard_gas_limit_per_block, + c.proof_of_work_threshold ), + ( ( c.tokens_per_roll, + c.seed_nonce_revelation_tip, + c.origination_size, + c.block_security_deposit, + c.endorsement_security_deposit, + c.baking_reward_per_endorsement, + c.endorsement_reward, + c.cost_per_byte, + c.hard_storage_limit_per_operation ), + ( c.quorum_min, + c.quorum_max, + c.min_proposal_quorum, + c.initial_endorsers, + c.delay_per_missing_endorsement, + c.minimal_block_delay, + c.liquidity_baking_subsidy, + c.liquidity_baking_sunset_level, + c.liquidity_baking_escape_ema_threshold ) ) )) + (fun ( ( preserved_cycles, + blocks_per_cycle, + blocks_per_commitment, + blocks_per_roll_snapshot, + blocks_per_voting_period, + time_between_blocks, + endorsers_per_block, + hard_gas_limit_per_operation, + hard_gas_limit_per_block, + proof_of_work_threshold ), + ( ( tokens_per_roll, + seed_nonce_revelation_tip, + origination_size, + block_security_deposit, + endorsement_security_deposit, + baking_reward_per_endorsement, + endorsement_reward, + cost_per_byte, + hard_storage_limit_per_operation ), + ( quorum_min, + quorum_max, + min_proposal_quorum, + initial_endorsers, + delay_per_missing_endorsement, + minimal_block_delay, + liquidity_baking_subsidy, + liquidity_baking_sunset_level, + liquidity_baking_escape_ema_threshold ) ) ) -> + { + preserved_cycles; + blocks_per_cycle; + blocks_per_commitment; + blocks_per_roll_snapshot; + blocks_per_voting_period; + time_between_blocks; + endorsers_per_block; + hard_gas_limit_per_operation; + hard_gas_limit_per_block; + proof_of_work_threshold; + tokens_per_roll; + seed_nonce_revelation_tip; + origination_size; + block_security_deposit; + endorsement_security_deposit; + baking_reward_per_endorsement; + endorsement_reward; + cost_per_byte; + hard_storage_limit_per_operation; + quorum_min; + quorum_max; + min_proposal_quorum; + initial_endorsers; + delay_per_missing_endorsement; + minimal_block_delay; + liquidity_baking_subsidy; + liquidity_baking_sunset_level; + liquidity_baking_escape_ema_threshold; + }) + (merge_objs + (obj10 + (req "preserved_cycles" uint8) + (req "blocks_per_cycle" int32) + (req "blocks_per_commitment" int32) + (req "blocks_per_roll_snapshot" int32) + (req "blocks_per_voting_period" int32) + (req "time_between_blocks" (list Period_repr.encoding)) + (req "endorsers_per_block" uint16) + (req + "hard_gas_limit_per_operation" + Gas_limit_repr.Arith.z_integral_encoding) + (req + "hard_gas_limit_per_block" + Gas_limit_repr.Arith.z_integral_encoding) + (req "proof_of_work_threshold" int64)) + (merge_objs + (obj9 + (req "tokens_per_roll" Tez_repr.encoding) + (req "seed_nonce_revelation_tip" Tez_repr.encoding) + (req "origination_size" int31) + (req "block_security_deposit" Tez_repr.encoding) + (req "endorsement_security_deposit" Tez_repr.encoding) + (req "baking_reward_per_endorsement" (list Tez_repr.encoding)) + (req "endorsement_reward" (list Tez_repr.encoding)) + (req "cost_per_byte" Tez_repr.encoding) + (req "hard_storage_limit_per_operation" z)) + (obj9 + (req "quorum_min" int32) + (req "quorum_max" int32) + (req "min_proposal_quorum" int32) + (req "initial_endorsers" uint16) + (req "delay_per_missing_endorsement" Period_repr.encoding) + (req "minimal_block_delay" Period_repr.encoding) + (req "liquidity_baking_subsidy" Tez_repr.encoding) + (req "liquidity_baking_sunset_level" int32) + (req "liquidity_baking_escape_ema_threshold" int32)))) +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/constants_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/constants_repr.mli new file mode 100644 index 000000000000..eace934c36bd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/constants_repr.mli @@ -0,0 +1,197 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val fitness_version_number : string + +val proof_of_work_nonce_size : int + +val nonce_length : int + +val max_anon_ops_per_block : int + +val max_proposals_per_delegate : int + +val max_operation_data_length : int + +(** A global size limit on the size of Micheline expressions + after expansion. + + We want to prevent constants from being + used to create huge values that could potentially do damage + if ever printed or sent over the network. We arrived at this + number by finding the largest possible contract in terms of + number of nodes. The number of nodes is constrained by the + current "max_operation_data_length" (32768) to be ~10,000 ( + see "largest_flat_contract.tz" in the tezt suite for the largest + contract with constants that can be originated). As a first + approximation, we set the node size limit to 5 times this amount. *) +val max_micheline_node_count : int + +(** Same as [max_micheline_node_count] but for limiting the combined + bytes of the strings, ints and bytes in a expanded Micheline + expression. *) +val max_micheline_bytes_limit : int + +(** Represents the maximum depth of an expression stored + in the table after all references to other constants have + (recursively) been expanded, where depth refers to the + nesting of [Prim] and/or [Seq] nodes. + + The size was chosen arbitrarily to match the typechecker + in [Script_ir_translator]. *) +val max_allowed_global_constant_depth : int + +(* an over-approximation of the size (in bytes) of an entry in the cache + storing the stake distribution for a given cycle *) +val stake_distribution_size : int + +(* an over-approximation of the size (in bytes) of an entry in the + cache storing the sampler state for a given cycle *) +val sampler_state_size : int + +(** Each protocol defines the number of subcaches and their respective + limit size using [cache_layout]. *) +val cache_layout : int list + +val michelson_maximum_type_size : int + +type fixed + +val fixed_encoding : fixed Data_encoding.encoding + +type ratio = {numerator : int; denominator : int} + +val ratio_encoding : ratio Data_encoding.t + +val pp_ratio : Format.formatter -> ratio -> unit + +type delegate_selection = + | Random + | Round_robin_over of Signature.Public_key.t list list + +val delegate_selection_encoding : delegate_selection Data_encoding.encoding + +type parametric = { + preserved_cycles : int; + blocks_per_cycle : int32; + blocks_per_commitment : int32; + blocks_per_stake_snapshot : int32; + blocks_per_voting_period : int32; + hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; + hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; + proof_of_work_threshold : int64; + tokens_per_roll : Tez_repr.t; + seed_nonce_revelation_tip : Tez_repr.t; + origination_size : int; + baking_reward_fixed_portion : Tez_repr.t; + baking_reward_bonus_per_slot : Tez_repr.t; + endorsing_reward_per_slot : Tez_repr.t; + cost_per_byte : Tez_repr.t; + hard_storage_limit_per_operation : Z.t; + quorum_min : int32; + (* in centile of a percentage *) + quorum_max : int32; + min_proposal_quorum : int32; + liquidity_baking_subsidy : Tez_repr.t; + liquidity_baking_sunset_level : int32; + liquidity_baking_escape_ema_threshold : int32; + max_operations_time_to_live : int; + minimal_block_delay : Period_repr.t; + delay_increment_per_round : Period_repr.t; + minimal_participation_ratio : ratio; + consensus_committee_size : int; + (* in slots *) + consensus_threshold : int; + (* in slots *) + max_slashing_period : int; + (* in cycles *) + frozen_deposits_percentage : int; + (* that is, (100 * delegated tz / own tz) *) + double_baking_punishment : Tez_repr.t; + ratio_of_frozen_deposits_slashed_per_double_endorsement : ratio; + delegate_selection : delegate_selection; +} + +val parametric_encoding : parametric Data_encoding.encoding + +type t = private {fixed : fixed; parametric : parametric} + +val all : parametric -> t + +val encoding : t Data_encoding.encoding + +type error += (* `Permanent *) Invalid_protocol_constants of string + +(** performs some consistency checks on the protocol parameters *) +val check_constants : parametric -> unit tzresult + +module Generated : sig + type t = { + consensus_threshold : int; + baking_reward_fixed_portion : Tez_repr.t; + baking_reward_bonus_per_slot : Tez_repr.t; + endorsing_reward_per_slot : Tez_repr.t; + } + + (* This function is meant to be used just in lib_parameters and in the + migration code to be sure that the parameters are consistent. *) + val generate : consensus_committee_size:int -> blocks_per_minute:ratio -> t +end + +module Proto_previous : sig + type parametric = { + preserved_cycles : int; + blocks_per_cycle : int32; + blocks_per_commitment : int32; + blocks_per_roll_snapshot : int32; + blocks_per_voting_period : int32; + time_between_blocks : Period_repr.t list; + minimal_block_delay : Period_repr.t; + endorsers_per_block : int; + hard_gas_limit_per_operation : Gas_limit_repr.Arith.integral; + hard_gas_limit_per_block : Gas_limit_repr.Arith.integral; + proof_of_work_threshold : int64; + tokens_per_roll : Tez_repr.t; + seed_nonce_revelation_tip : Tez_repr.t; + origination_size : int; + block_security_deposit : Tez_repr.t; + endorsement_security_deposit : Tez_repr.t; + baking_reward_per_endorsement : Tez_repr.t list; + endorsement_reward : Tez_repr.t list; + cost_per_byte : Tez_repr.t; + hard_storage_limit_per_operation : Z.t; + quorum_min : int32; + quorum_max : int32; + min_proposal_quorum : int32; + initial_endorsers : int; + delay_per_missing_endorsement : Period_repr.t; + liquidity_baking_subsidy : Tez_repr.t; + liquidity_baking_sunset_level : int32; + liquidity_baking_escape_ema_threshold : int32; + } + + val parametric_encoding : parametric Data_encoding.encoding +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/constants_services.ml b/src/proto_012_PsiThaCa/lib_protocol/constants_services.ml new file mode 100644 index 000000000000..bc7e8ae3bb0e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/constants_services.ml @@ -0,0 +1,59 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +let custom_root = + (RPC_path.(open_root / "context" / "constants") + : RPC_context.t RPC_path.context) + +module S = struct + open Data_encoding + + let errors = + RPC_service.get_service + ~description:"Schema for all the RPC errors from this protocol version" + ~query:RPC_query.empty + ~output:json_schema + RPC_path.(custom_root / "errors") + + let all = + RPC_service.get_service + ~description:"All constants" + ~query:RPC_query.empty + ~output:Alpha_context.Constants.encoding + custom_root +end + +let register () = + let open Services_registration in + register0_noctxt ~chunked:true S.errors (fun () () -> + return Data_encoding.Json.(schema error_encoding)) ; + register0 ~chunked:false S.all (fun ctxt () () -> + return @@ Constants.all ctxt) + +let errors ctxt block = RPC_context.make_call0 S.errors ctxt block () () + +let all ctxt block = RPC_context.make_call0 S.all ctxt block () () diff --git a/src/proto_012_PsiThaCa/lib_protocol/constants_services.mli b/src/proto_012_PsiThaCa/lib_protocol/constants_services.mli new file mode 100644 index 000000000000..4ebdfc3557d2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/constants_services.mli @@ -0,0 +1,34 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +val errors : + 'a #RPC_context.simple -> 'a -> Data_encoding.json_schema shell_tzresult Lwt.t + +(** Returns all the constants of the protocol *) +val all : 'a #RPC_context.simple -> 'a -> Constants.t shell_tzresult Lwt.t + +val register : unit -> unit diff --git a/src/proto_012_PsiThaCa/lib_protocol/constants_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/constants_storage.ml new file mode 100644 index 000000000000..e4f4241c338f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/constants_storage.ml @@ -0,0 +1,150 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let preserved_cycles c = + let constants = Raw_context.constants c in + constants.preserved_cycles + +let blocks_per_cycle c = + let constants = Raw_context.constants c in + constants.blocks_per_cycle + +let blocks_per_commitment c = + let constants = Raw_context.constants c in + constants.blocks_per_commitment + +let blocks_per_stake_snapshot c = + let constants = Raw_context.constants c in + constants.blocks_per_stake_snapshot + +let blocks_per_voting_period c = + let constants = Raw_context.constants c in + constants.blocks_per_voting_period + +let hard_gas_limit_per_operation c = + let constants = Raw_context.constants c in + constants.hard_gas_limit_per_operation + +let hard_gas_limit_per_block c = + let constants = Raw_context.constants c in + constants.hard_gas_limit_per_block + +let cost_per_byte c = + let constants = Raw_context.constants c in + constants.cost_per_byte + +let hard_storage_limit_per_operation c = + let constants = Raw_context.constants c in + constants.hard_storage_limit_per_operation + +let proof_of_work_threshold c = + let constants = Raw_context.constants c in + constants.proof_of_work_threshold + +let tokens_per_roll c = + let constants = Raw_context.constants c in + constants.tokens_per_roll + +let seed_nonce_revelation_tip c = + let constants = Raw_context.constants c in + constants.seed_nonce_revelation_tip + +let origination_size c = + let constants = Raw_context.constants c in + constants.origination_size + +let baking_reward_fixed_portion c = + let constants = Raw_context.constants c in + constants.baking_reward_fixed_portion + +let baking_reward_bonus_per_slot c = + let constants = Raw_context.constants c in + constants.baking_reward_bonus_per_slot + +let endorsing_reward_per_slot c = + let constants = Raw_context.constants c in + constants.endorsing_reward_per_slot + +let quorum_min c = + let constants = Raw_context.constants c in + constants.quorum_min + +let quorum_max c = + let constants = Raw_context.constants c in + constants.quorum_max + +let min_proposal_quorum c = + let constants = Raw_context.constants c in + constants.min_proposal_quorum + +let liquidity_baking_subsidy c = + let constants = Raw_context.constants c in + constants.liquidity_baking_subsidy + +let liquidity_baking_sunset_level c = + let constants = Raw_context.constants c in + constants.liquidity_baking_sunset_level + +let liquidity_baking_escape_ema_threshold c = + let constants = Raw_context.constants c in + constants.liquidity_baking_escape_ema_threshold + +let parametric c = Raw_context.constants c + +let minimal_block_delay c = + let constants = Raw_context.constants c in + constants.minimal_block_delay + +let delay_increment_per_round c = + let constants = Raw_context.constants c in + constants.delay_increment_per_round + +let consensus_committee_size c = + let constants = Raw_context.constants c in + constants.consensus_committee_size + +let consensus_threshold c = + let constants = Raw_context.constants c in + constants.consensus_threshold + +let minimal_participation_ratio c = + let constants = Raw_context.constants c in + constants.minimal_participation_ratio + +let max_slashing_period c = + let constants = Raw_context.constants c in + constants.max_slashing_period + +let frozen_deposits_percentage c = + let constants = Raw_context.constants c in + constants.frozen_deposits_percentage + +let double_baking_punishment c = + let constants = Raw_context.constants c in + constants.double_baking_punishment + +let ratio_of_frozen_deposits_slashed_per_double_endorsement c = + let constants = Raw_context.constants c in + constants.ratio_of_frozen_deposits_slashed_per_double_endorsement diff --git a/src/proto_012_PsiThaCa/lib_protocol/constants_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/constants_storage.mli new file mode 100644 index 000000000000..0af74a51a528 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/constants_storage.mli @@ -0,0 +1,91 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val preserved_cycles : Raw_context.t -> int + +val blocks_per_cycle : Raw_context.t -> int32 + +val blocks_per_commitment : Raw_context.t -> int32 + +val blocks_per_stake_snapshot : Raw_context.t -> int32 + +val blocks_per_voting_period : Raw_context.t -> int32 + +val hard_gas_limit_per_operation : + Raw_context.t -> Gas_limit_repr.Arith.integral + +val hard_gas_limit_per_block : Raw_context.t -> Gas_limit_repr.Arith.integral + +val cost_per_byte : Raw_context.t -> Tez_repr.t + +val hard_storage_limit_per_operation : Raw_context.t -> Z.t + +val proof_of_work_threshold : Raw_context.t -> int64 + +val tokens_per_roll : Raw_context.t -> Tez_repr.t + +val seed_nonce_revelation_tip : Raw_context.t -> Tez_repr.t + +val origination_size : Raw_context.t -> int + +val baking_reward_fixed_portion : Raw_context.t -> Tez_repr.t + +val baking_reward_bonus_per_slot : Raw_context.t -> Tez_repr.t + +val endorsing_reward_per_slot : Raw_context.t -> Tez_repr.t + +val quorum_min : Raw_context.t -> int32 + +val quorum_max : Raw_context.t -> int32 + +val min_proposal_quorum : Raw_context.t -> int32 + +val liquidity_baking_subsidy : Raw_context.t -> Tez_repr.t + +val liquidity_baking_sunset_level : Raw_context.t -> int32 + +val liquidity_baking_escape_ema_threshold : Raw_context.t -> int32 + +val parametric : Raw_context.t -> Constants_repr.parametric + +val consensus_committee_size : Raw_context.t -> int + +val consensus_threshold : Raw_context.t -> int + +val minimal_participation_ratio : Raw_context.t -> Constants_repr.ratio + +val max_slashing_period : Raw_context.t -> int + +val frozen_deposits_percentage : Raw_context.t -> int + +val double_baking_punishment : Raw_context.t -> Tez_repr.t + +val ratio_of_frozen_deposits_slashed_per_double_endorsement : + Raw_context.t -> Constants_repr.ratio + +val minimal_block_delay : Raw_context.t -> Period_repr.t + +val delay_increment_per_round : Raw_context.t -> Period_repr.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_delegate_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/contract_delegate_storage.ml new file mode 100644 index 000000000000..ca295af19167 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_delegate_storage.ml @@ -0,0 +1,83 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let find = Storage.Contract.Delegate.find + +let remove_contract_stake ctxt contract amount = + find ctxt contract >>=? function + | None -> return ctxt + | Some delegate -> Stake_storage.remove_stake ctxt delegate amount + +let add_contract_stake ctxt contract amount = + find ctxt contract >>=? function + | None -> return ctxt + | Some delegate -> Stake_storage.add_stake ctxt delegate amount + +(* A delegate is registered if its "implicit account" delegates to itself. *) +let registered c delegate = + Storage.Contract.Delegate.find c (Contract_repr.implicit_contract delegate) + >|=? function + | Some current_delegate -> + Signature.Public_key_hash.equal delegate current_delegate + | None -> false + +let link c contract delegate = + Storage.Contract.Balance.get c contract >>=? fun balance -> + Stake_storage.add_stake c delegate balance >>=? fun c -> + Storage.Contract.Delegated.add + (c, Contract_repr.implicit_contract delegate) + contract + >|= ok + +let unlink c contract = + Storage.Contract.Delegate.find c contract >>=? function + | None -> return c + | Some delegate -> + Storage.Contract.Balance.get c contract >>=? fun balance -> + (* Removes the balance of the contract from the delegate *) + Stake_storage.remove_stake c delegate balance >>=? fun c -> + Storage.Contract.Delegated.remove + (c, Contract_repr.implicit_contract delegate) + contract + >|= ok + +let init ctxt contract delegate = + Storage.Contract.Delegate.init ctxt contract delegate >>=? fun ctxt -> + link ctxt contract delegate + +let delete ctxt contract = + unlink ctxt contract >>=? fun ctxt -> + Storage.Contract.Delegate.remove ctxt contract >|= ok + +let remove ctxt contract = unlink ctxt contract + +let set ctxt contract delegate = + unlink ctxt contract >>=? fun ctxt -> + Storage.Contract.Delegate.add ctxt contract delegate >>= fun ctxt -> + link ctxt contract delegate + +let delegated_contracts ctxt delegate = + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Delegated.elements (ctxt, contract) diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_delegate_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/contract_delegate_storage.mli new file mode 100644 index 000000000000..1a62d96b6ade --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_delegate_storage.mli @@ -0,0 +1,88 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** [find ctxt contract] returns the delegate associated to [contract], or [None] + if [contract] has no delegate]. *) +val find : + Raw_context.t -> + Contract_repr.t -> + Signature.Public_key_hash.t option tzresult Lwt.t + +(** [registered ctxt delegate] returns true iff delegate is an implicit contract + that delegates to itself. *) +val registered : + Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t + +(** [init ctxt contract delegate] sets the [delegate] associated to [contract]. + + This function is undefined if [contract] is not allocated, or if [contract] + has already a delegate. *) +val init : + Raw_context.t -> + Contract_repr.t -> + Signature.Public_key_hash.t -> + Raw_context.t tzresult Lwt.t + +(** [remove ctxt contract] removes contract from the list of contracts that + delegated to [find ctxt contract], i.e. the output of [delegated_contracts]. + This function does not affect the value of the expression + [find ctxt contract]. + + This function is undefined if [contract] is not allocated. *) +val remove : Raw_context.t -> Contract_repr.t -> Raw_context.t tzresult Lwt.t + +(** [delete ctxt contract] behaves as [remove ctxt contract], but in addition + removes the association of the [contract] to its current delegate, leaving + the former with no delegate. + + This function is undefined if [contract] is not allocated. *) +val delete : Raw_context.t -> Contract_repr.t -> Raw_context.t tzresult Lwt.t + +(** [set ctxt contract delegate] updates the [delegate] associated to [contract]. + + This function is undefined if [contract] is not allocated, or if [contract] + does not have a delegate. *) +val set : + Raw_context.t -> + Contract_repr.t -> + Signature.Public_key_hash.t -> + Raw_context.t tzresult Lwt.t + +(** [delegated_contracts ctxt delegate] returns the list of contracts (implicit + or originated) that delegated to [delegate]. *) +val delegated_contracts : + Raw_context.t -> Signature.Public_key_hash.t -> Contract_repr.t list Lwt.t + +(** [add_contract_stake ctxt contract amount] calls + [Stake_storage.add_stake ctxt delegate amount] if [contract] has a + [delegate]. Otherwise this function does nothing. *) +val add_contract_stake : + Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t + +(** [remove_contract_stake ctxt contract amount] calls + [Stake_storage.remove_stake ctxt delegate amount] if [contract] has a + [delegate]. Otherwise this function does nothing. *) +val remove_contract_stake : + Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_hash.ml b/src/proto_012_PsiThaCa/lib_protocol/contract_hash.ml new file mode 100644 index 000000000000..c232a80278df --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_hash.ml @@ -0,0 +1,45 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* 20 *) +let contract_hash = "\002\090\121" (* KT1(36) *) + +module H = + Blake2B.Make + (Base58) + (struct + let name = "Contract_hash" + + let title = "A contract ID" + + let b58check_prefix = contract_hash + + let size = Some 20 + end) + +include H +include Path_encoding.Make_hex (H) + +let () = Base58.check_encoded_prefix b58check_encoding "KT1" 36 diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_hash.mli b/src/proto_012_PsiThaCa/lib_protocol/contract_hash.mli new file mode 100644 index 000000000000..1cbc424150af --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_hash.mli @@ -0,0 +1,29 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** A specialized Blake2B implementation for hashing contract identifiers. *) + +include S.HASH diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_manager_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/contract_manager_storage.ml new file mode 100644 index 000000000000..43464734c5aa --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_manager_storage.ml @@ -0,0 +1,130 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | (* `Branch *) Unrevealed_manager_key of Contract_repr.t + | (* `Permanent *) + Inconsistent_hash of { + public_key : Signature.Public_key.t; + expected_hash : Signature.Public_key_hash.t; + provided_hash : Signature.Public_key_hash.t; + } + | (* `Branch *) Previously_revealed_key of Contract_repr.t + +let () = + register_error_kind + `Branch + ~id:"contract.unrevealed_key" + ~title:"Manager operation precedes key revelation" + ~description: + "One tried to apply a manager operation without revealing the manager \ + public key" + ~pp:(fun ppf s -> + Format.fprintf + ppf + "Unrevealed manager key for contract %a." + Contract_repr.pp + s) + Data_encoding.(obj1 (req "contract" Contract_repr.encoding)) + (function Unrevealed_manager_key s -> Some s | _ -> None) + (fun s -> Unrevealed_manager_key s) ; + register_error_kind + `Permanent + ~id:"contract.manager.inconsistent_hash" + ~title:"Inconsistent public key hash" + ~description: + "A revealed manager public key is inconsistent with the announced hash" + ~pp:(fun ppf (k, eh, ph) -> + Format.fprintf + ppf + "The hash of the manager public key %s is not %a as announced but %a" + (Signature.Public_key.to_b58check k) + Signature.Public_key_hash.pp + ph + Signature.Public_key_hash.pp + eh) + Data_encoding.( + obj3 + (req "public_key" Signature.Public_key.encoding) + (req "expected_hash" Signature.Public_key_hash.encoding) + (req "provided_hash" Signature.Public_key_hash.encoding)) + (function + | Inconsistent_hash {public_key; expected_hash; provided_hash} -> + Some (public_key, expected_hash, provided_hash) + | _ -> None) + (fun (public_key, expected_hash, provided_hash) -> + Inconsistent_hash {public_key; expected_hash; provided_hash}) ; + register_error_kind + `Branch + ~id:"contract.previously_revealed_key" + ~title:"Manager operation already revealed" + ~description:"One tried to reveal twice a manager public key" + ~pp:(fun ppf s -> + Format.fprintf + ppf + "Previously revealed manager key for contract %a." + Contract_repr.pp + s) + Data_encoding.(obj1 (req "contract" Contract_repr.encoding)) + (function Previously_revealed_key s -> Some s | _ -> None) + (fun s -> Previously_revealed_key s) + +let init = Storage.Contract.Manager.init + +let is_manager_key_revealed c manager = + let contract = Contract_repr.implicit_contract manager in + Storage.Contract.Manager.find c contract >>=? function + | None -> return_false + | Some (Manager_repr.Hash _) -> return_false + | Some (Manager_repr.Public_key _) -> return_true + +let reveal_manager_key c manager public_key = + let contract = Contract_repr.implicit_contract manager in + Storage.Contract.Manager.get c contract >>=? function + | Public_key _ -> fail (Previously_revealed_key contract) + | Hash v -> + let actual_hash = Signature.Public_key.hash public_key in + if Signature.Public_key_hash.equal actual_hash v then + let v = Manager_repr.Public_key public_key in + Storage.Contract.Manager.update c contract v + else + fail + (Inconsistent_hash + {public_key; expected_hash = v; provided_hash = actual_hash}) + +let get_manager_key ?error ctxt pkh = + let contract = Contract_repr.implicit_contract pkh in + Storage.Contract.Manager.find ctxt contract >>=? function + | None -> ( + match error with + | None -> failwith "get_manager_key" + | Some error -> fail error) + | Some (Manager_repr.Hash _) -> ( + match error with + | None -> fail (Unrevealed_manager_key contract) + | Some error -> fail error) + | Some (Manager_repr.Public_key pk) -> return pk + +let remove_existing = Storage.Contract.Manager.remove_existing diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_manager_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/contract_manager_storage.mli new file mode 100644 index 000000000000..8982e89a7699 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_manager_storage.mli @@ -0,0 +1,67 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | (* `Branch *) Unrevealed_manager_key of Contract_repr.t + | (* `Permanent *) + Inconsistent_hash of { + public_key : Signature.Public_key.t; + expected_hash : Signature.Public_key_hash.t; + provided_hash : Signature.Public_key_hash.t; + } + | (* `Branch *) Previously_revealed_key of Contract_repr.t + +(** [init ctxt contract manager] associates [manager] to [contract]. This + function is undefined if [contract] has already a manager associated to it. +*) +val init : + Raw_context.t -> + Contract_repr.t -> + Manager_repr.manager_key -> + Raw_context.t tzresult Lwt.t + +val is_manager_key_revealed : + Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t + +val reveal_manager_key : + Raw_context.t -> + Signature.Public_key_hash.t -> + Signature.Public_key.t -> + Raw_context.t tzresult Lwt.t + +(** [get_manager_key ?error ctxt pkh] returns the revealed manager key of the + contract represented by [pkh]. When [error] is not provided this function + fails with "get_manager_key" error if [pkh] does not have a manager, and + with [Unrevealed_manager_key] error if the manager has not revealed its key. + When [error] is provided, the function fails with the provided [error] in + both cases. *) +val get_manager_key : + ?error:error -> + Raw_context.t -> + Signature.Public_key_hash.t -> + Signature.Public_key.t tzresult Lwt.t + +val remove_existing : + Raw_context.t -> Contract_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/contract_repr.ml new file mode 100644 index 000000000000..84c4251b5c6a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_repr.ml @@ -0,0 +1,214 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = + | Implicit of Signature.Public_key_hash.t + | Originated of Contract_hash.t + +include Compare.Make (struct + type nonrec t = t + + let compare l1 l2 = + match (l1, l2) with + | (Implicit pkh1, Implicit pkh2) -> + Signature.Public_key_hash.compare pkh1 pkh2 + | (Originated h1, Originated h2) -> Contract_hash.compare h1 h2 + | (Implicit _, Originated _) -> -1 + | (Originated _, Implicit _) -> 1 +end) + +type contract = t + +let blake2b_hash_size = + let open Cache_memory_helpers in + header_size +! word_size +! string_size_gen 20 + +let public_key_hash_in_memory_size = + let open Cache_memory_helpers in + header_size +! word_size +! blake2b_hash_size + +let in_memory_size = + let open Cache_memory_helpers in + function + | Implicit _ -> header_size +! word_size +! public_key_hash_in_memory_size + | Originated _ -> header_size +! word_size +! blake2b_hash_size + +type error += Invalid_contract_notation of string (* `Permanent *) + +let to_b58check = function + | Implicit pbk -> Signature.Public_key_hash.to_b58check pbk + | Originated h -> Contract_hash.to_b58check h + +let of_b58check s = + match Base58.decode s with + | Some data -> ( + match data with + | Ed25519.Public_key_hash.Data h -> ok (Implicit (Signature.Ed25519 h)) + | Secp256k1.Public_key_hash.Data h -> + ok (Implicit (Signature.Secp256k1 h)) + | P256.Public_key_hash.Data h -> ok (Implicit (Signature.P256 h)) + | Contract_hash.Data h -> ok (Originated h) + | _ -> error (Invalid_contract_notation s)) + | None -> error (Invalid_contract_notation s) + +let pp ppf = function + | Implicit pbk -> Signature.Public_key_hash.pp ppf pbk + | Originated h -> Contract_hash.pp ppf h + +let pp_short ppf = function + | Implicit pbk -> Signature.Public_key_hash.pp_short ppf pbk + | Originated h -> Contract_hash.pp_short ppf h + +let encoding = + let open Data_encoding in + def + "contract_id" + ~title:"A contract handle" + ~description: + "A contract notation as given to an RPC or inside scripts. Can be a \ + base58 implicit contract hash or a base58 originated contract hash." + @@ splitted + ~binary: + (union + ~tag_size:`Uint8 + [ + case + (Tag 0) + ~title:"Implicit" + Signature.Public_key_hash.encoding + (function Implicit k -> Some k | _ -> None) + (fun k -> Implicit k); + case + (Tag 1) + (Fixed.add_padding Contract_hash.encoding 1) + ~title:"Originated" + (function Originated k -> Some k | _ -> None) + (fun k -> Originated k); + ]) + ~json: + (conv + to_b58check + (fun s -> + match of_b58check s with + | Ok s -> s + | Error _ -> Json.cannot_destruct "Invalid contract notation.") + string) + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"contract.invalid_contract_notation" + ~title:"Invalid contract notation" + ~pp:(fun ppf x -> Format.fprintf ppf "Invalid contract notation %S" x) + ~description: + "A malformed contract notation was given to an RPC or in a script." + (obj1 (req "notation" string)) + (function Invalid_contract_notation loc -> Some loc | _ -> None) + (fun loc -> Invalid_contract_notation loc) + +let implicit_contract id = Implicit id + +let is_implicit = function Implicit m -> Some m | Originated _ -> None + +let is_originated = function Implicit _ -> None | Originated h -> Some h + +type origination_nonce = { + operation_hash : Operation_hash.t; + origination_index : int32; +} + +let origination_nonce_encoding = + let open Data_encoding in + conv + (fun {operation_hash; origination_index} -> + (operation_hash, origination_index)) + (fun (operation_hash, origination_index) -> + {operation_hash; origination_index}) + @@ obj2 (req "operation" Operation_hash.encoding) (dft "index" int32 0l) + +let originated_contract nonce = + let data = + Data_encoding.Binary.to_bytes_exn origination_nonce_encoding nonce + in + Originated (Contract_hash.hash_bytes [data]) + +let originated_contracts + ~since:{origination_index = first; operation_hash = first_hash} + ~until: + ({origination_index = last; operation_hash = last_hash} as + origination_nonce) = + assert (Operation_hash.equal first_hash last_hash) ; + let[@coq_struct "origination_index"] rec contracts acc origination_index = + if Compare.Int32.(origination_index < first) then acc + else + let origination_nonce = {origination_nonce with origination_index} in + let acc = originated_contract origination_nonce :: acc in + contracts acc (Int32.pred origination_index) + in + contracts [] (Int32.pred last) + +let initial_origination_nonce operation_hash = + {operation_hash; origination_index = 0l} + +let incr_origination_nonce nonce = + let origination_index = Int32.succ nonce.origination_index in + {nonce with origination_index} + +let rpc_arg = + let construct = to_b58check in + let destruct hash = + Result.map_error (fun _ -> "Cannot parse contract id") (of_b58check hash) + in + RPC_arg.make + ~descr:"A contract identifier encoded in b58check." + ~name:"contract_id" + ~construct + ~destruct + () + +module Index = struct + type t = contract + + let path_length = 1 + + let to_path c l = + let raw_key = Data_encoding.Binary.to_bytes_exn encoding c in + let (`Hex key) = Hex.of_bytes raw_key in + key :: l + + let of_path = function + | [key] -> + Option.bind + (Hex.to_bytes (`Hex key)) + (Data_encoding.Binary.of_bytes_opt encoding) + | _ -> None + + let rpc_arg = rpc_arg + + let encoding = encoding + + let compare = compare +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/contract_repr.mli new file mode 100644 index 000000000000..803275062627 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_repr.mli @@ -0,0 +1,99 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module defines identifiers for two basic types of contracts. It also + specifies how to compute originated contract's hash from origination + nonce. *) + +(** A contract is simply an account on the blockchain ledger. There are two + types of contracts: + - implicit contracts represent accounts of users of the blockchain; + - originated are special accounts with a Michelson script attached to + them. Every time a transaction is sent to an originated account, its + associated script is run in order to trigger some action in response. + + An implicit account is identified by the hash of the public key which was + used to create it. The owner of the corresponding private key is the + holder of the account. An originated contract's hash is derived from its + origination nonce (see below). *) +type t = private + | Implicit of Signature.Public_key_hash.t + | Originated of Contract_hash.t + +type contract = t + +include Compare.S with type t := contract + +val public_key_hash_in_memory_size : Cache_memory_helpers.sint + +val in_memory_size : t -> Cache_memory_helpers.sint + +(** {2 Implicit contracts} *) + +val implicit_contract : Signature.Public_key_hash.t -> contract + +val is_implicit : contract -> Signature.Public_key_hash.t option + +(** {2 Originated contracts} *) + +(** Originated contracts handles are crafted from the hash of the + operation that triggered their origination (and nothing else). + As a single operation can trigger several originations, the + corresponding handles are forged from a deterministic sequence of + nonces, initialized with the hash of the operation. *) +type origination_nonce + +val originated_contract : origination_nonce -> contract + +val originated_contracts : + since:origination_nonce -> until:origination_nonce -> contract list + +val initial_origination_nonce : Operation_hash.t -> origination_nonce + +val incr_origination_nonce : origination_nonce -> origination_nonce + +val is_originated : contract -> Contract_hash.t option + +(** {2 Human readable notation} *) + +type error += Invalid_contract_notation of string (* `Permanent *) + +val to_b58check : contract -> string + +val of_b58check : string -> contract tzresult + +val pp : Format.formatter -> contract -> unit + +val pp_short : Format.formatter -> contract -> unit + +(** {2 Serializers} *) + +val encoding : contract Data_encoding.t + +val origination_nonce_encoding : origination_nonce Data_encoding.t + +val rpc_arg : contract RPC_arg.arg + +module Index : Storage_description.INDEX with type t = t diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_services.ml b/src/proto_012_PsiThaCa/lib_protocol/contract_services.ml new file mode 100644 index 000000000000..799d8c5ae62b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_services.ml @@ -0,0 +1,527 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +let custom_root = + (RPC_path.(open_root / "context" / "contracts") + : RPC_context.t RPC_path.context) + +let big_map_root = + (RPC_path.(open_root / "context" / "big_maps") + : RPC_context.t RPC_path.context) + +type info = { + balance : Tez.t; + delegate : public_key_hash option; + counter : counter option; + script : Script.t option; +} + +let info_encoding = + let open Data_encoding in + conv + (fun {balance; delegate; script; counter} -> + (balance, delegate, script, counter)) + (fun (balance, delegate, script, counter) -> + {balance; delegate; script; counter}) + @@ obj4 + (req "balance" Tez.encoding) + (opt "delegate" Signature.Public_key_hash.encoding) + (opt "script" Script.encoding) + (opt "counter" n) + +module S = struct + open Data_encoding + + let balance = + RPC_service.get_service + ~description:"Access the balance of a contract." + ~query:RPC_query.empty + ~output:Tez.encoding + RPC_path.(custom_root /: Contract.rpc_arg / "balance") + + let manager_key = + RPC_service.get_service + ~description:"Access the manager of a contract." + ~query:RPC_query.empty + ~output:(option Signature.Public_key.encoding) + RPC_path.(custom_root /: Contract.rpc_arg / "manager_key") + + let delegate = + RPC_service.get_service + ~description:"Access the delegate of a contract, if any." + ~query:RPC_query.empty + ~output:Signature.Public_key_hash.encoding + RPC_path.(custom_root /: Contract.rpc_arg / "delegate") + + let counter = + RPC_service.get_service + ~description:"Access the counter of a contract, if any." + ~query:RPC_query.empty + ~output:z + RPC_path.(custom_root /: Contract.rpc_arg / "counter") + + let script = + RPC_service.get_service + ~description:"Access the code and data of the contract." + ~query:RPC_query.empty + ~output:Script.encoding + RPC_path.(custom_root /: Contract.rpc_arg / "script") + + let storage = + RPC_service.get_service + ~description:"Access the data of the contract." + ~query:RPC_query.empty + ~output:Script.expr_encoding + RPC_path.(custom_root /: Contract.rpc_arg / "storage") + + let entrypoint_type = + RPC_service.get_service + ~description:"Return the type of the given entrypoint of the contract" + ~query:RPC_query.empty + ~output:Script.expr_encoding + RPC_path.( + custom_root /: Contract.rpc_arg / "entrypoints" /: RPC_arg.string) + + let list_entrypoints = + RPC_service.get_service + ~description:"Return the list of entrypoints of the contract" + ~query:RPC_query.empty + ~output: + (obj2 + (dft + "unreachable" + (Data_encoding.list + (obj1 + (req + "path" + (Data_encoding.list + Michelson_v1_primitives.prim_encoding)))) + []) + (req "entrypoints" (assoc Script.expr_encoding))) + RPC_path.(custom_root /: Contract.rpc_arg / "entrypoints") + + let contract_big_map_get_opt = + RPC_service.post_service + ~description: + "Access the value associated with a key in a big map of the contract \ + (deprecated)." + ~query:RPC_query.empty + ~input: + (obj2 + (req "key" Script.expr_encoding) + (req "type" Script.expr_encoding)) + ~output:(option Script.expr_encoding) + RPC_path.(custom_root /: Contract.rpc_arg / "big_map_get") + + let big_map_get = + RPC_service.get_service + ~description:"Access the value associated with a key in a big map." + ~query:RPC_query.empty + ~output:Script.expr_encoding + RPC_path.(big_map_root /: Big_map.Id.rpc_arg /: Script_expr_hash.rpc_arg) + + type big_map_get_all_query = {offset : int option; length : int option} + + let rpc_arg_uint : int RPC_arg.t = + let int_of_string s = + int_of_string_opt s + |> Option.to_result + ~none:(Format.sprintf "Cannot parse integer value %s" s) + >>? fun i -> + if Compare.Int.(i < 0) then + Error (Format.sprintf "Negative integer: %d" i) + else Ok i + in + RPC_arg.make + ~name:"uint" + ~descr:"A non-negative integer (greater than or equal to 0)." + ~destruct:int_of_string + ~construct:string_of_int + () + + let big_map_get_all_query : big_map_get_all_query RPC_query.t = + let open RPC_query in + query (fun offset length -> {offset; length}) + |+ opt_field + ~descr: + "Skip the first [offset] values. Useful in combination with \ + [length] for pagination." + "offset" + rpc_arg_uint + (fun t -> t.offset) + |+ opt_field + ~descr: + "Only retrieve [length] values. Useful in combination with [offset] \ + for pagination." + "length" + rpc_arg_uint + (fun t -> t.length) + |> seal + + let big_map_get_all = + RPC_service.get_service + ~description: + "Get the (optionally paginated) list of values in a big map. Order of \ + values is unspecified, but is guaranteed to be consistent." + ~query:big_map_get_all_query + ~output:(list Script.expr_encoding) + RPC_path.(big_map_root /: Big_map.Id.rpc_arg) + + let info = + RPC_service.get_service + ~description:"Access the complete status of a contract." + ~query:RPC_query.empty + ~output:info_encoding + RPC_path.(custom_root /: Contract.rpc_arg) + + let list = + RPC_service.get_service + ~description: + "All existing contracts (including non-empty default contracts)." + ~query:RPC_query.empty + ~output:(list Contract.encoding) + custom_root + + module Sapling = struct + (* + Sapling: these RPCs are like Sapling RPCs (sapling_services.ml) + specialized for contracts containing a single sapling state. + *) + + let single_sapling_get_id ctxt contract_id = + Contract.get_script ctxt contract_id >>=? fun (ctxt, script) -> + match script with + | None -> return (None, ctxt) + | Some script -> + let ctxt = Gas.set_unlimited ctxt in + Script_ir_translator.parse_script + ctxt + ~legacy:true + ~allow_forged_in_storage:true + script + >|= fun tzresult -> + tzresult >>? fun (Ex_script script, ctxt) -> + Script_ir_translator.get_single_sapling_state + ctxt + script.storage_type + script.storage + + let make_service + Sapling_services.S.Args.{name; description; query; output; f} = + let name = "single_sapling_" ^ name in + let path = RPC_path.(custom_root /: Contract.rpc_arg / name) in + let service = RPC_service.get_service ~description ~query ~output path in + ( service, + fun ctxt contract_id q () -> + single_sapling_get_id ctxt contract_id >>=? fun (sapling_id, ctxt) -> + Option.map_es (fun sapling_id -> f ctxt sapling_id q) sapling_id ) + + let get_diff = make_service Sapling_services.S.Args.get_diff + + let register () = + let reg chunked (service, f) = + Services_registration.opt_register1 ~chunked service f + in + reg false get_diff + + let mk_call1 (service, _f) ctxt block id q = + RPC_context.make_call1 service ctxt block id q () + end +end + +let[@coq_axiom_with_reason "gadt"] register () = + let open Services_registration in + register0 ~chunked:true S.list (fun ctxt () () -> Contract.list ctxt >|= ok) ; + let register_field ~chunked s f = + opt_register1 ~chunked s (fun ctxt contract () () -> + Contract.exists ctxt contract >>=? function + | true -> f ctxt contract >|=? Option.some + | false -> return_none) + in + let register_opt_field ~chunked s f = + opt_register1 ~chunked s (fun ctxt contract () () -> + Contract.exists ctxt contract >>=? function + | true -> f ctxt contract + | false -> return_none) + in + let do_big_map_get ctxt id key = + let open Script_ir_translator in + let ctxt = Gas.set_unlimited ctxt in + Big_map.exists ctxt id >>=? fun (ctxt, types) -> + match types with + | None -> return_none + | Some (_, value_type) -> ( + parse_big_map_value_ty ctxt ~legacy:true (Micheline.root value_type) + >>?= fun (Ex_ty value_type, ctxt) -> + Big_map.get_opt ctxt id key >>=? fun (_ctxt, value) -> + match value with + | None -> return_none + | Some value -> + parse_data + ctxt + ~legacy:true + ~allow_forged:true + value_type + (Micheline.root value) + >>=? fun (value, ctxt) -> + unparse_data ctxt Readable value_type value + >|=? fun (value, _ctxt) -> Some (Micheline.strip_locations value)) + in + let do_big_map_get_all ?offset ?length ctxt id = + let open Script_ir_translator in + let ctxt = Gas.set_unlimited ctxt in + Big_map.exists ctxt id >>=? fun (ctxt, types) -> + match types with + | None -> raise Not_found + | Some (_, value_type) -> + parse_big_map_value_ty ctxt ~legacy:true (Micheline.root value_type) + >>?= fun (Ex_ty value_type, ctxt) -> + Big_map.list_values ?offset ?length ctxt id >>=? fun (ctxt, values) -> + List.fold_left_s + (fun acc value -> + acc >>?= fun (ctxt, rev_values) -> + parse_data + ctxt + ~legacy:true + ~allow_forged:true + value_type + (Micheline.root value) + >>=? fun (value, ctxt) -> + unparse_data ctxt Readable value_type value + >|=? fun (value, ctxt) -> + (ctxt, Micheline.strip_locations value :: rev_values)) + (Ok (ctxt, [])) + values + >|=? fun (_ctxt, rev_values) -> List.rev rev_values + in + register_field ~chunked:false S.balance Contract.get_balance ; + opt_register1 ~chunked:false S.manager_key (fun ctxt contract () () -> + match Contract.is_implicit contract with + | None -> return_none + | Some mgr -> ( + Contract.is_manager_key_revealed ctxt mgr >>=? function + | false -> return_some None + | true -> + Contract.get_manager_key ctxt mgr >|=? fun key -> Some (Some key))) ; + register_opt_field ~chunked:false S.delegate Delegate.find ; + opt_register1 ~chunked:false S.counter (fun ctxt contract () () -> + match Contract.is_implicit contract with + | None -> return_none + | Some mgr -> + Contract.get_counter ctxt mgr >|=? fun counter -> Some counter) ; + register_opt_field ~chunked:true S.script (fun c v -> + Contract.get_script c v >|=? fun (_, v) -> v) ; + register_opt_field ~chunked:true S.storage (fun ctxt contract -> + Contract.get_script ctxt contract >>=? fun (ctxt, script) -> + match script with + | None -> return_none + | Some script -> + let ctxt = Gas.set_unlimited ctxt in + let open Script_ir_translator in + parse_script ctxt ~legacy:true ~allow_forged_in_storage:true script + >>=? fun (Ex_script script, ctxt) -> + unparse_script ctxt Readable script >>=? fun (script, ctxt) -> + Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + script.storage + >>?= fun (storage, _ctxt) -> return_some storage) ; + opt_register2 ~chunked:true S.entrypoint_type (fun ctxt v entrypoint () () -> + Contract.get_script_code ctxt v >>=? fun (_, expr) -> + match expr with + | None -> return_none + | Some expr -> + let ctxt = Gas.set_unlimited ctxt in + let legacy = true in + let open Script_ir_translator in + Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + expr + >>?= fun (expr, _) -> + parse_toplevel ctxt ~legacy expr + >>=? fun ({arg_type; root_name; _}, ctxt) -> + Lwt.return + (( parse_parameter_ty ctxt ~legacy arg_type + >>? fun (Ex_ty arg_type, _) -> + Script_ir_translator.find_entrypoint + ~root_name + arg_type + entrypoint ) + |> function + | Ok (_f, Ex_ty ty) -> + unparse_ty ~loc:() ctxt ty >|? fun (ty_node, _) -> + Some (Micheline.strip_locations ty_node) + | Error _ -> Result.return_none)) ; + opt_register1 ~chunked:true S.list_entrypoints (fun ctxt v () () -> + Contract.get_script_code ctxt v >>=? fun (_, expr) -> + match expr with + | None -> return_none + | Some expr -> + let ctxt = Gas.set_unlimited ctxt in + let legacy = true in + let open Script_ir_translator in + Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + expr + >>?= fun (expr, _) -> + parse_toplevel ctxt ~legacy expr + >>=? fun ({arg_type; root_name; _}, ctxt) -> + Lwt.return + ( ( parse_parameter_ty ctxt ~legacy arg_type + >>? fun (Ex_ty arg_type, _) -> + Script_ir_translator.list_entrypoints ~root_name arg_type ctxt + ) + >|? fun (unreachable_entrypoint, map) -> + Some + ( unreachable_entrypoint, + Entrypoints_map.fold + (fun entry (_, ty) acc -> + (entry, Micheline.strip_locations ty) :: acc) + map + [] ) )) ; + opt_register1 + ~chunked:true + S.contract_big_map_get_opt + (fun ctxt contract () (key, key_type) -> + Contract.get_script ctxt contract >>=? fun (ctxt, script) -> + let key_type_node = Micheline.root key_type in + Script_ir_translator.parse_comparable_ty ctxt key_type_node + >>?= fun (Ex_comparable_ty key_type, ctxt) -> + Script_ir_translator.parse_comparable_data + ctxt + key_type + (Micheline.root key) + >>=? fun (key, ctxt) -> + Script_ir_translator.hash_comparable_data ctxt key_type key + >>=? fun (key, ctxt) -> + match script with + | None -> return_none + | Some script -> ( + let ctxt = Gas.set_unlimited ctxt in + let open Script_ir_translator in + parse_script ctxt ~legacy:true ~allow_forged_in_storage:true script + >>=? fun (Ex_script script, ctxt) -> + Script_ir_translator.collect_lazy_storage + ctxt + script.storage_type + script.storage + >>?= fun (ids, _ctxt) -> + match Script_ir_translator.list_of_big_map_ids ids with + | [] | _ :: _ :: _ -> return_some None + | [id] -> do_big_map_get ctxt id key >|=? Option.some)) ; + opt_register2 ~chunked:true S.big_map_get (fun ctxt id key () () -> + do_big_map_get ctxt id key) ; + register1 ~chunked:true S.big_map_get_all (fun ctxt id {offset; length} () -> + do_big_map_get_all ?offset ?length ctxt id) ; + register_field ~chunked:false S.info (fun ctxt contract -> + Contract.get_balance ctxt contract >>=? fun balance -> + Delegate.find ctxt contract >>=? fun delegate -> + (match Contract.is_implicit contract with + | Some manager -> + Contract.get_counter ctxt manager >>=? fun counter -> + return_some counter + | None -> return_none) + >>=? fun counter -> + Contract.get_script ctxt contract >>=? fun (ctxt, script) -> + (match script with + | None -> return (None, ctxt) + | Some script -> + let ctxt = Gas.set_unlimited ctxt in + let open Script_ir_translator in + parse_script ctxt ~legacy:true ~allow_forged_in_storage:true script + >>=? fun (Ex_script script, ctxt) -> + unparse_script ctxt Readable script >|=? fun (script, ctxt) -> + (Some script, ctxt)) + >|=? fun (script, _ctxt) -> {balance; delegate; script; counter}) ; + S.Sapling.register () + +let list ctxt block = RPC_context.make_call0 S.list ctxt block () () + +let info ctxt block contract = + RPC_context.make_call1 S.info ctxt block contract () () + +let balance ctxt block contract = + RPC_context.make_call1 S.balance ctxt block contract () () + +let manager_key ctxt block mgr = + RPC_context.make_call1 + S.manager_key + ctxt + block + (Contract.implicit_contract mgr) + () + () + +let delegate ctxt block contract = + RPC_context.make_call1 S.delegate ctxt block contract () () + +let delegate_opt ctxt block contract = + RPC_context.make_opt_call1 S.delegate ctxt block contract () () + +let counter ctxt block mgr = + RPC_context.make_call1 + S.counter + ctxt + block + (Contract.implicit_contract mgr) + () + () + +let script ctxt block contract = + RPC_context.make_call1 S.script ctxt block contract () () + +let script_opt ctxt block contract = + RPC_context.make_opt_call1 S.script ctxt block contract () () + +let storage ctxt block contract = + RPC_context.make_call1 S.storage ctxt block contract () () + +let entrypoint_type ctxt block contract entrypoint = + RPC_context.make_call2 S.entrypoint_type ctxt block contract entrypoint () () + +let list_entrypoints ctxt block contract = + RPC_context.make_call1 S.list_entrypoints ctxt block contract () () + +let storage_opt ctxt block contract = + RPC_context.make_opt_call1 S.storage ctxt block contract () () + +let big_map_get ctxt block id key = + RPC_context.make_call2 S.big_map_get ctxt block id key () () + +let contract_big_map_get_opt ctxt block contract key = + RPC_context.make_call1 S.contract_big_map_get_opt ctxt block contract () key + +let single_sapling_get_diff ctxt block id ?offset_commitment ?offset_nullifier + () = + S.Sapling.(mk_call1 get_diff) + ctxt + block + id + Sapling_services.{offset_commitment; offset_nullifier} diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_services.mli b/src/proto_012_PsiThaCa/lib_protocol/contract_services.mli new file mode 100644 index 000000000000..458dfbe4d617 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_services.mli @@ -0,0 +1,126 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +val list : 'a #RPC_context.simple -> 'a -> Contract.t list shell_tzresult Lwt.t + +type info = { + balance : Tez.t; + delegate : public_key_hash option; + counter : counter option; + script : Script.t option; +} + +val info_encoding : info Data_encoding.t + +val info : + 'a #RPC_context.simple -> 'a -> Contract.t -> info shell_tzresult Lwt.t + +val balance : + 'a #RPC_context.simple -> 'a -> Contract.t -> Tez.t shell_tzresult Lwt.t + +val manager_key : + 'a #RPC_context.simple -> + 'a -> + public_key_hash -> + public_key option shell_tzresult Lwt.t + +val delegate : + 'a #RPC_context.simple -> + 'a -> + Contract.t -> + public_key_hash shell_tzresult Lwt.t + +val delegate_opt : + 'a #RPC_context.simple -> + 'a -> + Contract.t -> + public_key_hash option shell_tzresult Lwt.t + +val counter : + 'a #RPC_context.simple -> + 'a -> + public_key_hash -> + counter shell_tzresult Lwt.t + +val script : + 'a #RPC_context.simple -> 'a -> Contract.t -> Script.t shell_tzresult Lwt.t + +val script_opt : + 'a #RPC_context.simple -> + 'a -> + Contract.t -> + Script.t option shell_tzresult Lwt.t + +val storage : + 'a #RPC_context.simple -> 'a -> Contract.t -> Script.expr shell_tzresult Lwt.t + +val entrypoint_type : + 'a #RPC_context.simple -> + 'a -> + Contract.t -> + string -> + Script.expr shell_tzresult Lwt.t + +val list_entrypoints : + 'a #RPC_context.simple -> + 'a -> + Contract.t -> + (Michelson_v1_primitives.prim list list * (string * Script.expr) list) + shell_tzresult + Lwt.t + +val storage_opt : + 'a #RPC_context.simple -> + 'a -> + Contract.t -> + Script.expr option shell_tzresult Lwt.t + +val big_map_get : + 'a #RPC_context.simple -> + 'a -> + Big_map.Id.t -> + Script_expr_hash.t -> + Script.expr shell_tzresult Lwt.t + +val contract_big_map_get_opt : + 'a #RPC_context.simple -> + 'a -> + Contract.t -> + Script.expr * Script.expr -> + Script.expr option shell_tzresult Lwt.t + +val single_sapling_get_diff : + 'a #RPC_context.simple -> + 'a -> + Contract.t -> + ?offset_commitment:int64 -> + ?offset_nullifier:int64 -> + unit -> + (Sapling.root * Sapling.diff) shell_tzresult Lwt.t + +val register : unit -> unit diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/contract_storage.ml new file mode 100644 index 000000000000..5bce09cebc50 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_storage.ml @@ -0,0 +1,629 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | (* `Temporary *) + Balance_too_low of + Contract_repr.contract * Tez_repr.t * Tez_repr.t + | (* `Temporary *) + Counter_in_the_past of Contract_repr.contract * Z.t * Z.t + | (* `Branch *) + Counter_in_the_future of Contract_repr.contract * Z.t * Z.t + | (* `Temporary *) + Non_existing_contract of Contract_repr.contract + | (* `Branch *) + Empty_implicit_contract of Signature.Public_key_hash.t + | (* `Branch *) + Empty_implicit_delegated_contract of + Signature.Public_key_hash.t + | (* `Permanent *) + Inconsistent_public_key of + Signature.Public_key.t * Signature.Public_key.t + | (* `Permanent *) Failure of string + +let () = + register_error_kind + `Temporary + ~id:"contract.balance_too_low" + ~title:"Balance too low" + ~description:"An operation tried to spend more tokens than the contract has" + ~pp:(fun ppf (c, b, a) -> + Format.fprintf + ppf + "Balance of contract %a too low (%a) to spend %a" + Contract_repr.pp + c + Tez_repr.pp + b + Tez_repr.pp + a) + Data_encoding.( + obj3 + (req "contract" Contract_repr.encoding) + (req "balance" Tez_repr.encoding) + (req "amount" Tez_repr.encoding)) + (function Balance_too_low (c, b, a) -> Some (c, b, a) | _ -> None) + (fun (c, b, a) -> Balance_too_low (c, b, a)) ; + register_error_kind + `Temporary + ~id:"contract.counter_in_the_future" + ~title:"Invalid counter (not yet reached) in a manager operation" + ~description:"An operation assumed a contract counter in the future" + ~pp:(fun ppf (contract, exp, found) -> + Format.fprintf + ppf + "Counter %a not yet reached for contract %a (expected %a)" + Z.pp_print + found + Contract_repr.pp + contract + Z.pp_print + exp) + Data_encoding.( + obj3 + (req "contract" Contract_repr.encoding) + (req "expected" z) + (req "found" z)) + (function Counter_in_the_future (c, x, y) -> Some (c, x, y) | _ -> None) + (fun (c, x, y) -> Counter_in_the_future (c, x, y)) ; + register_error_kind + `Branch + ~id:"contract.counter_in_the_past" + ~title:"Invalid counter (already used) in a manager operation" + ~description:"An operation assumed a contract counter in the past" + ~pp:(fun ppf (contract, exp, found) -> + Format.fprintf + ppf + "Counter %a already used for contract %a (expected %a)" + Z.pp_print + found + Contract_repr.pp + contract + Z.pp_print + exp) + Data_encoding.( + obj3 + (req "contract" Contract_repr.encoding) + (req "expected" z) + (req "found" z)) + (function Counter_in_the_past (c, x, y) -> Some (c, x, y) | _ -> None) + (fun (c, x, y) -> Counter_in_the_past (c, x, y)) ; + register_error_kind + `Temporary + ~id:"contract.non_existing_contract" + ~title:"Non existing contract" + ~description: + "A contract handle is not present in the context (either it never was or \ + it has been destroyed)" + ~pp:(fun ppf contract -> + Format.fprintf ppf "Contract %a does not exist" Contract_repr.pp contract) + Data_encoding.(obj1 (req "contract" Contract_repr.encoding)) + (function Non_existing_contract c -> Some c | _ -> None) + (fun c -> Non_existing_contract c) ; + register_error_kind + `Permanent + ~id:"contract.manager.inconsistent_public_key" + ~title:"Inconsistent public key" + ~description: + "A provided manager public key is different with the public key stored \ + in the contract" + ~pp:(fun ppf (eh, ph) -> + Format.fprintf + ppf + "Expected manager public key %s but %s was provided" + (Signature.Public_key.to_b58check ph) + (Signature.Public_key.to_b58check eh)) + Data_encoding.( + obj2 + (req "public_key" Signature.Public_key.encoding) + (req "expected_public_key" Signature.Public_key.encoding)) + (function Inconsistent_public_key (eh, ph) -> Some (eh, ph) | _ -> None) + (fun (eh, ph) -> Inconsistent_public_key (eh, ph)) ; + register_error_kind + `Permanent + ~id:"contract.failure" + ~title:"Contract storage failure" + ~description:"Unexpected contract storage error" + ~pp:(fun ppf s -> Format.fprintf ppf "Contract_storage.Failure %S" s) + Data_encoding.(obj1 (req "message" string)) + (function Failure s -> Some s | _ -> None) + (fun s -> Failure s) ; + register_error_kind + `Branch + ~id:"implicit.empty_implicit_contract" + ~title:"Empty implicit contract" + ~description: + "No manager operations are allowed on an empty implicit contract." + ~pp:(fun ppf implicit -> + Format.fprintf + ppf + "Empty implicit contract (%a)" + Signature.Public_key_hash.pp + implicit) + Data_encoding.(obj1 (req "implicit" Signature.Public_key_hash.encoding)) + (function Empty_implicit_contract c -> Some c | _ -> None) + (fun c -> Empty_implicit_contract c) ; + register_error_kind + `Branch + ~id:"implicit.empty_implicit_delegated_contract" + ~title:"Empty implicit delegated contract" + ~description:"Emptying an implicit delegated account is not allowed." + ~pp:(fun ppf implicit -> + Format.fprintf + ppf + "Emptying implicit delegated contract (%a)" + Signature.Public_key_hash.pp + implicit) + Data_encoding.(obj1 (req "implicit" Signature.Public_key_hash.encoding)) + (function Empty_implicit_delegated_contract c -> Some c | _ -> None) + (fun c -> Empty_implicit_delegated_contract c) + +let failwith msg = fail (Failure msg) + +module Legacy_big_map_diff = struct + (* + Big_map_diff receipt as it was represented in 006 and earlier. + It is kept here for now for backward compatibility of tools. *) + + type item = + | Update of { + big_map : Z.t; + diff_key : Script_repr.expr; + diff_key_hash : Script_expr_hash.t; + diff_value : Script_repr.expr option; + } + | Clear of Z.t + | Copy of {src : Z.t; dst : Z.t} + | Alloc of { + big_map : Z.t; + key_type : Script_repr.expr; + value_type : Script_repr.expr; + } + + type t = item list + + let item_encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"update" + (obj5 + (req "action" (constant "update")) + (req "big_map" z) + (req "key_hash" Script_expr_hash.encoding) + (req "key" Script_repr.expr_encoding) + (opt "value" Script_repr.expr_encoding)) + (function + | Update {big_map; diff_key_hash; diff_key; diff_value} -> + Some ((), big_map, diff_key_hash, diff_key, diff_value) + | _ -> None) + (fun ((), big_map, diff_key_hash, diff_key, diff_value) -> + Update {big_map; diff_key_hash; diff_key; diff_value}); + case + (Tag 1) + ~title:"remove" + (obj2 (req "action" (constant "remove")) (req "big_map" z)) + (function Clear big_map -> Some ((), big_map) | _ -> None) + (fun ((), big_map) -> Clear big_map); + case + (Tag 2) + ~title:"copy" + (obj3 + (req "action" (constant "copy")) + (req "source_big_map" z) + (req "destination_big_map" z)) + (function Copy {src; dst} -> Some ((), src, dst) | _ -> None) + (fun ((), src, dst) -> Copy {src; dst}); + case + (Tag 3) + ~title:"alloc" + (obj4 + (req "action" (constant "alloc")) + (req "big_map" z) + (req "key_type" Script_repr.expr_encoding) + (req "value_type" Script_repr.expr_encoding)) + (function + | Alloc {big_map; key_type; value_type} -> + Some ((), big_map, key_type, value_type) + | _ -> None) + (fun ((), big_map, key_type, value_type) -> + Alloc {big_map; key_type; value_type}); + ] + + let encoding = Data_encoding.list item_encoding + + let to_lazy_storage_diff legacy_diffs = + let rev_head (diffs : (_ * (_, _, _) Lazy_storage_diff.diff) list) = + match diffs with + | [] -> [] + | (_, Remove) :: _ -> diffs + | (id, Update {init; updates}) :: rest -> + (id, Update {init; updates = List.rev updates}) :: rest + in + (* Invariant: + Updates are collected one by one, in reverse order, on the head diff + item. So only and exactly the head diff item has its updates reversed. + *) + List.fold_left + (fun (new_diff : (_ * (_, _, _) Lazy_storage_diff.diff) list) item -> + match item with + | Clear id -> (id, Lazy_storage_diff.Remove) :: rev_head new_diff + | Copy {src; dst} -> + let src = + Lazy_storage_kind.Big_map.Id + .of_legacy_USE_ONLY_IN_Legacy_big_map_diff + src + in + (dst, Lazy_storage_diff.Update {init = Copy {src}; updates = []}) + :: rev_head new_diff + | Alloc {big_map; key_type; value_type} -> + ( big_map, + Lazy_storage_diff.( + Update + { + init = Alloc Lazy_storage_kind.Big_map.{key_type; value_type}; + updates = []; + }) ) + :: rev_head new_diff + | Update + { + big_map; + diff_key = key; + diff_key_hash = key_hash; + diff_value = value; + } -> ( + match new_diff with + | (id, diff) :: rest when Compare.Z.(id = big_map) -> + let diff = + match diff with + | Remove -> assert false + | Update {init; updates} -> + let updates = + Lazy_storage_kind.Big_map.{key; key_hash; value} + :: updates + in + Lazy_storage_diff.Update {init; updates} + in + (id, diff) :: rest + | new_diff -> + let updates = + [Lazy_storage_kind.Big_map.{key; key_hash; value}] + in + (big_map, Update {init = Existing; updates}) + :: rev_head new_diff)) + [] + legacy_diffs + |> rev_head + |> List.rev_map (fun (id, diff) -> + let id = + Lazy_storage_kind.Big_map.Id + .of_legacy_USE_ONLY_IN_Legacy_big_map_diff + id + in + Lazy_storage_diff.make Lazy_storage_kind.Big_map id diff) + + let of_lazy_storage_diff diffs = + List.fold_left + (fun legacy_diffs (Lazy_storage_diff.Item (kind, id, diff)) -> + let diffs = + match kind with + | Lazy_storage_kind.Big_map -> ( + let id = + Lazy_storage_kind.Big_map.Id + .to_legacy_USE_ONLY_IN_Legacy_big_map_diff + id + in + match diff with + | Remove -> [Clear id] + | Update {init; updates} -> ( + let updates = + List.rev_map + (fun {Lazy_storage_kind.Big_map.key; key_hash; value} -> + Update + { + big_map = id; + diff_key = key; + diff_key_hash = key_hash; + diff_value = value; + }) + updates + in + match init with + | Existing -> updates + | Copy {src} -> + let src = + Lazy_storage_kind.Big_map.Id + .to_legacy_USE_ONLY_IN_Legacy_big_map_diff + src + in + Copy {src; dst = id} :: updates + | Alloc {key_type; value_type} -> + Alloc {big_map = id; key_type; value_type} :: updates)) + | _ -> (* Not a Big_map *) [] + in + diffs :: legacy_diffs) + [] + diffs + |> List.rev |> List.flatten + [@@coq_axiom_with_reason "gadt"] +end + +let update_script_lazy_storage c = function + | None -> return (c, Z.zero) + | Some diffs -> Lazy_storage_diff.apply c diffs + +let create_base c ~prepaid_bootstrap_storage + (* Free space for bootstrap contracts *) + contract ~balance ~manager ?script () = + (match Contract_repr.is_implicit contract with + | None -> return c + | Some _ -> + Storage.Contract.Global_counter.get c >>=? fun counter -> + Storage.Contract.Counter.init c contract counter) + >>=? fun c -> + Storage.Contract.Balance.init c contract balance >>=? fun c -> + (match manager with + | Some manager -> + Contract_manager_storage.init c contract (Manager_repr.Hash manager) + | None -> return c) + >>=? fun c -> + match script with + | Some ({Script_repr.code; storage}, lazy_storage_diff) -> + Storage.Contract.Code.init c contract code >>=? fun (c, code_size) -> + Storage.Contract.Storage.init c contract storage + >>=? fun (c, storage_size) -> + update_script_lazy_storage c lazy_storage_diff + >>=? fun (c, lazy_storage_size) -> + let total_size = + Z.add + (Z.add (Z.of_int code_size) (Z.of_int storage_size)) + lazy_storage_size + in + assert (Compare.Z.(total_size >= Z.zero)) ; + let prepaid_bootstrap_storage = + if prepaid_bootstrap_storage then total_size else Z.zero + in + Storage.Contract.Paid_storage_space.init + c + contract + prepaid_bootstrap_storage + >>=? fun c -> + Storage.Contract.Used_storage_space.init c contract total_size + | None -> return c + +let raw_originate c ~prepaid_bootstrap_storage contract ~script = + create_base + c + ~prepaid_bootstrap_storage + contract + ~balance:Tez_repr.zero + ~manager:None + ~script + () + +let create_implicit c manager ~balance = + create_base + c + ~prepaid_bootstrap_storage:false + (Contract_repr.implicit_contract manager) + ~balance + ~manager:(Some manager) + ?script:None + () + +let delete c contract = + match Contract_repr.is_implicit contract with + | None -> + (* For non implicit contract Big_map should be cleared *) + failwith "Non implicit contracts cannot be removed" + | Some _ -> + Contract_delegate_storage.remove c contract >>=? fun c -> + Storage.Contract.Balance.remove_existing c contract >>=? fun c -> + Contract_manager_storage.remove_existing c contract >>=? fun c -> + Storage.Contract.Counter.remove_existing c contract >>=? fun c -> + Storage.Contract.Code.remove c contract >>=? fun (c, _, _) -> + Storage.Contract.Storage.remove c contract >>=? fun (c, _, _) -> + Storage.Contract.Paid_storage_space.remove c contract >>= fun c -> + Storage.Contract.Used_storage_space.remove c contract >|= ok + +let allocated c contract = + Storage.Contract.Balance.find c contract >>=? function + | None -> return_false + | Some _ -> return_true + +let exists c contract = + match Contract_repr.is_implicit contract with + | Some _ -> return_true + | None -> allocated c contract + +let must_exist c contract = + exists c contract >>=? function + | true -> return_unit + | false -> fail (Non_existing_contract contract) + +let must_be_allocated c contract = + allocated c contract >>=? function + | true -> return_unit + | false -> ( + match Contract_repr.is_implicit contract with + | Some pkh -> fail (Empty_implicit_contract pkh) + | None -> fail (Non_existing_contract contract)) + +let list c = Storage.Contract.list c + +let fresh_contract_from_current_nonce c = + Raw_context.increment_origination_nonce c >|? fun (c, nonce) -> + (c, Contract_repr.originated_contract nonce) + +let originated_from_current_nonce ~since:ctxt_since ~until:ctxt_until = + Raw_context.get_origination_nonce ctxt_since >>?= fun since -> + Raw_context.get_origination_nonce ctxt_until >>?= fun until -> + List.filter_es + (fun contract -> exists ctxt_until contract) + (Contract_repr.originated_contracts ~since ~until) + +let check_counter_increment c manager counter = + let contract = Contract_repr.implicit_contract manager in + Storage.Contract.Counter.get c contract >>=? fun contract_counter -> + let expected = Z.succ contract_counter in + if Compare.Z.(expected = counter) then return_unit + else if Compare.Z.(expected > counter) then + fail (Counter_in_the_past (contract, expected, counter)) + else fail (Counter_in_the_future (contract, expected, counter)) + +let increment_counter c manager = + let contract = Contract_repr.implicit_contract manager in + Storage.Contract.Global_counter.get c >>=? fun global_counter -> + Storage.Contract.Global_counter.update c (Z.succ global_counter) >>=? fun c -> + Storage.Contract.Counter.get c contract >>=? fun contract_counter -> + Storage.Contract.Counter.update c contract (Z.succ contract_counter) + +let get_script_code c contract = Storage.Contract.Code.find c contract + +let get_script c contract = + Storage.Contract.Code.find c contract >>=? fun (c, code) -> + Storage.Contract.Storage.find c contract >>=? fun (c, storage) -> + match (code, storage) with + | (None, None) -> return (c, None) + | (Some code, Some storage) -> return (c, Some {Script_repr.code; storage}) + | (None, Some _) | (Some _, None) -> failwith "get_script" + +let get_storage ctxt contract = + Storage.Contract.Storage.find ctxt contract >>=? function + | (ctxt, None) -> return (ctxt, None) + | (ctxt, Some storage) -> + Raw_context.consume_gas ctxt (Script_repr.force_decode_cost storage) + >>?= fun ctxt -> + Script_repr.force_decode storage >>?= fun storage -> + return (ctxt, Some storage) + +let get_counter c manager = + let contract = Contract_repr.implicit_contract manager in + Storage.Contract.Counter.find c contract >>=? function + | None -> ( + match Contract_repr.is_implicit contract with + | Some _ -> Storage.Contract.Global_counter.get c + | None -> failwith "get_counter") + | Some v -> return v + +let get_balance c contract = + Storage.Contract.Balance.find c contract >>=? function + | None -> ( + match Contract_repr.is_implicit contract with + | Some _ -> return Tez_repr.zero + | None -> failwith "get_balance") + | Some v -> return v + +let get_balance_carbonated c contract = + (* Reading an int64 from /contracts/index//balance *) + Raw_context.consume_gas + c + (Storage_costs.read_access ~path_length:4 ~read_bytes:8) + >>?= fun c -> + get_balance c contract >>=? fun balance -> return (c, balance) + +let update_script_storage c contract storage lazy_storage_diff = + let storage = Script_repr.lazy_expr storage in + update_script_lazy_storage c lazy_storage_diff + >>=? fun (c, lazy_storage_size_diff) -> + Storage.Contract.Storage.update c contract storage >>=? fun (c, size_diff) -> + Storage.Contract.Used_storage_space.get c contract >>=? fun previous_size -> + let new_size = + Z.add previous_size (Z.add lazy_storage_size_diff (Z.of_int size_diff)) + in + Storage.Contract.Used_storage_space.update c contract new_size + +let spend_only_call_from_token c contract amount = + Storage.Contract.Balance.find c contract >>=? fun balance -> + let balance = Option.value balance ~default:Tez_repr.zero in + match Tez_repr.(balance -? amount) with + | Error _ -> fail (Balance_too_low (contract, balance, amount)) + | Ok new_balance -> ( + Storage.Contract.Balance.update c contract new_balance >>=? fun c -> + Contract_delegate_storage.remove_contract_stake c contract amount + >>=? fun c -> + if Tez_repr.(new_balance > Tez_repr.zero) then return c + else + match Contract_repr.is_implicit contract with + | None -> return c (* Never delete originated contracts *) + | Some pkh -> ( + Contract_delegate_storage.find c contract >>=? function + | Some pkh' -> + if Signature.Public_key_hash.equal pkh pkh' then return c + else + (* Delegated implicit accounts cannot be emptied *) + fail (Empty_implicit_delegated_contract pkh) + | None -> + (* Delete empty implicit contract *) + delete c contract)) + +(* [Tez_repr.(amount <> zero)] is a precondition of this function. It ensures that + no entry associating a null balance to an implicit contract exists in the map + [Storage.Contract.Balance]. *) +let credit_only_call_from_token c contract amount = + Storage.Contract.Balance.find c contract >>=? function + | None -> ( + match Contract_repr.is_implicit contract with + | None -> fail (Non_existing_contract contract) + | Some manager -> create_implicit c manager ~balance:amount) + | Some balance -> + Tez_repr.(amount +? balance) >>?= fun balance -> + Storage.Contract.Balance.update c contract balance >>=? fun c -> + Contract_delegate_storage.add_contract_stake c contract amount + +let init c = + Storage.Contract.Global_counter.init c Z.zero >>=? fun c -> + Lazy_storage_diff.init c + +let used_storage_space c contract = + Storage.Contract.Used_storage_space.find c contract + >|=? Option.value ~default:Z.zero + +let paid_storage_space c contract = + Storage.Contract.Paid_storage_space.find c contract + >|=? Option.value ~default:Z.zero + +let set_paid_storage_space_and_return_fees_to_pay c contract new_storage_space = + Storage.Contract.Paid_storage_space.get c contract + >>=? fun already_paid_space -> + if Compare.Z.(already_paid_space >= new_storage_space) then return (Z.zero, c) + else + let to_pay = Z.sub new_storage_space already_paid_space in + Storage.Contract.Paid_storage_space.update c contract new_storage_space + >|=? fun c -> (to_pay, c) + +let update_balance ctxt contract f amount = + Storage.Contract.Balance.get ctxt contract >>=? fun balance -> + f balance amount >>?= fun new_balance -> + Storage.Contract.Balance.update ctxt contract new_balance + +let increase_balance_only_call_from_token ctxt contract amount = + update_balance ctxt contract Tez_repr.( +? ) amount + +let decrease_balance_only_call_from_token ctxt contract amount = + update_balance ctxt contract Tez_repr.( -? ) amount diff --git a/src/proto_012_PsiThaCa/lib_protocol/contract_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/contract_storage.mli new file mode 100644 index 000000000000..a08917d33c32 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contract_storage.mli @@ -0,0 +1,184 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | (* `Temporary *) + Balance_too_low of + Contract_repr.contract * Tez_repr.t * Tez_repr.t + | (* `Temporary *) + Counter_in_the_past of Contract_repr.contract * Z.t * Z.t + | (* `Branch *) + Counter_in_the_future of Contract_repr.contract * Z.t * Z.t + | (* `Temporary *) + Non_existing_contract of Contract_repr.contract + | (* `Branch *) + Empty_implicit_contract of Signature.Public_key_hash.t + | (* `Branch *) + Empty_implicit_delegated_contract of + Signature.Public_key_hash.t + | (* `Permanent *) + Inconsistent_public_key of + Signature.Public_key.t * Signature.Public_key.t + | (* `Permanent *) Failure of string + +(** [allocated ctxt contract] returns [true] if and only if the + contract is stored in [Storage.Contract.Balance]. *) +val allocated : Raw_context.t -> Contract_repr.t -> bool tzresult Lwt.t + +(** [exists ctxt contract] returns [true] if and only if either the + contract is originated or it is (implicit and) "allocated". *) +val exists : Raw_context.t -> Contract_repr.t -> bool tzresult Lwt.t + +(** [must_exist ctxt contract] fails with the [Non_existing_contract] error if + [exists ctxt contract] returns [false]. Even though this function is + gas-free, it is always called in a context where some gas consumption is + guaranteed whenever necessary. The first context is that of a transfer + operation, and in that case the base cost of a manager operation + ([Micheclson_v1_gas.Cost_of.manager_operation]) is consumed. The second + context is that of an activation operation, and in that case no gas needs to + be consumed since that operation is not a manager operation. *) +val must_exist : Raw_context.t -> Contract_repr.t -> unit tzresult Lwt.t + +(** [must_be_allocated ctxt contract] fails when the contract is not + allocated. It fails with [Non_existing_contract] if the contract is + originated, and it fails with [Empty_implicit_contract] if the + contract is implicit. *) +val must_be_allocated : Raw_context.t -> Contract_repr.t -> unit tzresult Lwt.t + +val list : Raw_context.t -> Contract_repr.t list Lwt.t + +val check_counter_increment : + Raw_context.t -> Signature.Public_key_hash.t -> Z.t -> unit tzresult Lwt.t + +val increment_counter : + Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t + +val get_balance : Raw_context.t -> Contract_repr.t -> Tez_repr.t tzresult Lwt.t + +val get_balance_carbonated : + Raw_context.t -> + Contract_repr.t -> + (Raw_context.t * Tez_repr.t) tzresult Lwt.t + +val get_counter : + Raw_context.t -> Signature.Public_key_hash.t -> Z.t tzresult Lwt.t + +val get_script_code : + Raw_context.t -> + Contract_repr.t -> + (Raw_context.t * Script_repr.lazy_expr option) tzresult Lwt.t + +val get_script : + Raw_context.t -> + Contract_repr.t -> + (Raw_context.t * Script_repr.t option) tzresult Lwt.t + +val get_storage : + Raw_context.t -> + Contract_repr.t -> + (Raw_context.t * Script_repr.expr option) tzresult Lwt.t + +module Legacy_big_map_diff : sig + type item = private + | Update of { + big_map : Z.t; + diff_key : Script_repr.expr; + diff_key_hash : Script_expr_hash.t; + diff_value : Script_repr.expr option; + } + | Clear of Z.t + | Copy of {src : Z.t; dst : Z.t} + | Alloc of { + big_map : Z.t; + key_type : Script_repr.expr; + value_type : Script_repr.expr; + } + + type t = item list + + val encoding : t Data_encoding.t + + val to_lazy_storage_diff : t -> Lazy_storage_diff.diffs + + val of_lazy_storage_diff : Lazy_storage_diff.diffs -> t +end + +val update_script_storage : + Raw_context.t -> + Contract_repr.t -> + Script_repr.expr -> + Lazy_storage_diff.diffs option -> + Raw_context.t tzresult Lwt.t + +val credit_only_call_from_token : + Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t + +val spend_only_call_from_token : + Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t + +(** [raw_originate ctxt ~prepaid_bootstrap_storage contract ~script] + originates the [contract] parameter. The [storage] space allocated by this + origination is considered to be free of charge or to have been already paid + for by the user, if and only if [prepaid_bootstrap_storage] is [true]. In + particular, the amount of space allocated by this origination will be part + of the consumed space to pay for returned by the next call to + [Fees_storage.record_paid_storage_space ctxt contract], if and only if + [prepaid_bootstrap_storage] is [false]. *) +val raw_originate : + Raw_context.t -> + prepaid_bootstrap_storage:bool -> + Contract_repr.t -> + script:Script_repr.t * Lazy_storage_diff.diffs option -> + Raw_context.t tzresult Lwt.t + +val fresh_contract_from_current_nonce : + Raw_context.t -> (Raw_context.t * Contract_repr.t) tzresult + +val originated_from_current_nonce : + since:Raw_context.t -> + until:Raw_context.t -> + Contract_repr.t list tzresult Lwt.t + +val init : Raw_context.t -> Raw_context.t tzresult Lwt.t + +val used_storage_space : Raw_context.t -> Contract_repr.t -> Z.t tzresult Lwt.t + +val paid_storage_space : Raw_context.t -> Contract_repr.t -> Z.t tzresult Lwt.t + +val set_paid_storage_space_and_return_fees_to_pay : + Raw_context.t -> + Contract_repr.t -> + Z.t -> + (Z.t * Raw_context.t) tzresult Lwt.t + +(** Increases the balance of a contract. Calling this function directly may + break important invariants. Consider calling [credit] instead. *) +val increase_balance_only_call_from_token : + Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t + +(** Decreases the balance of a contract. Calling this function directly may + break important invariants. Consider calling [spend] instead. *) +val decrease_balance_only_call_from_token : + Raw_context.t -> Contract_repr.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.bin b/src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.bin new file mode 100644 index 000000000000..c4e455868ecb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.bin @@ -0,0 +1 @@ +0x02000011c405000764076407640865046e00000006256f776e6572076504620000000d256d696e4c71744d696e7465640765046200000013256d6178546f6b656e734465706f7369746564046b0000000925646561646c696e650000000d256164644c6971756964697479046c000000082564656661756c7407640865046e0000000325746f076504620000000a256c71744275726e65640765046a00000010256d696e58747a57697468647261776e0765046200000013256d696e546f6b656e7357697468647261776e046b0000000925646561646c696e65000000102572656d6f76654c69717569646974790865046e00000015256f7574707574446578746572436f6e74726163740765046200000010256d696e546f6b656e73426f756768740765046e0000000325746f076504620000000b25746f6b656e73536f6c64046b0000000925646561646c696e650000000d25746f6b656e546f546f6b656e07640865046e0000000325746f076504620000000b25746f6b656e73536f6c640765046a0000000d256d696e58747a426f75676874046b0000000925646561646c696e650000000b25746f6b656e546f58747a0865046e0000000325746f0765046200000010256d696e546f6b656e73426f75676874046b0000000925646561646c696e650000000b2578747a546f546f6b656e0501076504620000000a25746f6b656e506f6f6c0765046a000000082578747a506f6f6c0765046200000009256c7174546f74616c0765046e0000000d25746f6b656e41646472657373046e0000000b256c71744164647265737305020200000f7203210317034c0316072e02000009d1072e020000035a072e020000032603210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200004074303620003032702000002ea0743036a000105700004032105710005031703160322072f0200000013074303680100000008444956206279203003270200000000031603130743036a0001034c0322072f02000000130743036801000000084449562062792030032702000000000316034c0321057100020570000603210571000703170317031605700002032105710003033a0322072f020000001307430368010000000844495620627920300327020000000003160570000205700006032105710007031605700003033a0322072f020000001307430368010000000844495620627920300327020000002a03210317034c03160743036200000570000203190325072c02000000000200000008074303620001031205700002034c0321057100020319032a072c020000000c05200005074303620004032702000001b60571000203210571000303190337072c020000000c0520000407430362000503270200000190057000030321057100040317031703170570000203210571000305700005032105710006031703170316031203420570000403210571000503170316034205700004032105710005031603420317034c032105710002057000050321057100060316031203420321031703170313057000060317031603120342034c03160342034c03490354034203480342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d05700002033005700003034205700002032105710003034c03210317034c031605700002031703170317031706550765045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e072f020000000807430362000c032702000000000743036a000005700002057000030342034d05700002053d036d05700002031b05700002031b0342020000002803200321031703170313057000020321057100030317031603120342034c03160342053d036d0342020000066b072e020000038d03210317034c0316034c03210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200005074303620003032702000003470743036a000003130319032a072c020000000c0520000507430362000a03270200000323057000040321057100050317031703160743036a000105700006032105710007031703160322072f0200000013074303680100000008444956206279203003270200000000031605700004032105710005033a0322072f020000001307430368010000000844495620627920300327020000000003160743036a0001034c033a0570000503210571000603170317031605700006032105710007031605700005032105710006033a0322072f02000000130743036801000000084449562062792030032702000000000316057000030570000203210571000303190337072c020000000c0520000607430362000b0327020000022e05700002034c03210571000203190337072c020000000c0520000507430362000d032702000002060570000203210571000305700005032105710006031703170316034b0356072f020000000807430362000e03270200000000034c032105710002057000060321057100070316034b0356072f020000000807430362000f03270200000000057000040743035b0000034b0348034205700006032105710007034c03210317034c031605700002031703170317031706550765045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e072f020000000807430362000c032702000000000743036a000005700002057000030342034d0570000305700005032105710006034203490354034205700006032105710007034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d05700004032105710005057000060555036c072f020000000807430362000903270200000000034c0743036c030b034d0570000603210571000703170317057000060570000703210571000803170316034b034205700006031603420321031703170317057000060342034c032105710002031703160342034c031603420317057000040342053d036d05700002031b05700002031b05700002031b034202000002d203210317034c0316034c03210317034c0316034c03210317034c0316034c03210317034c03160570000406550765046e0000000325746f0765046200000010256d696e546f6b656e73426f75676874046b0000000925646561646c696e650000000b2578747a546f546f6b656e072f020000000807430362001f032702000000000743036a000003130319032a072c020000000c0520000607430362000a0327020000022d05700002032105710003034003190328072c020000000c05200006074303620003032702000002050743036200a70f05700002032105710003033a0743036200a80f057000070321057100080316033a031205700006032105710007031703160743036200a70f05700004032105710005033a033a0322072f020000001307430368010000000844495620627920300327020000000003160743036200a80f0743036200a70f05700002032105710003033a0322072f02000000130743036801000000084449562062792030032702000000000316057000070321057100080317057000040321057100050570000903210571000a031603120342032103170317057000030321057100040570000a03170316034b0342034c031603420570000403490354034203480342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d057000040570000303210571000405700006057000080342057000070342034d0570000305700004034b0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d05700003053d036d05700002031b05700002031b05700002031b0342020000058d072e02000002cc03210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200004074303620003032702000002900743036a000003130319032a072c020000000c0520000407430362000a0327020000026c0743036200a70f05700002032105710003033a0743036200a80f057000050321057100060316033a03120743036a000105700005032105710006031703160322072f020000001307430368010000000844495620627920300327020000000003160743036200a70f05700004032105710005033a033a0322072f020000001307430368010000000844495620627920300327020000000003160743036a0001034c033a0743036200a80f0743036200a70f05700002032105710003033a0322072f0200000013074303680100000008444956206279203003270200000000031605700002034c03210571000203190337072c020000000a032007430362000803270200000000057000020321057100030349035403420348034205700005032105710006034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d034c032105710002057000050555036c072f020000000807430362000903270200000000034c0743036c030b034d0570000503210571000603170570000505700006032105710007031603120342032103170317057000050321057100060570000703170316034b0342034c031603420570000305700004034b0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d034c053d036d05700002031b05700002031b05700002031b034202000002b503210317034c0316034c03210317034c0316034c034003190328072c020000000c05200003074303620003032702000002830743036a000105700003032105710004031703160322072f0200000013074303680100000008444956206279203003270200000000031603130743036a0001034c0322072f020000001307430368010000000844495620627920300327020000000003160743036200a80f0743036200a70f05700002032105710003033a0322072f02000000130743036801000000084449562062792030032702000000000316032105700002034b03110743036200a70f05700002032105710003033a0743036200a80f05700004033a03120570000503210571000603160743036200a70f05700004032105710005033a033a0322072f0200000013074303680100000008444956206279203003270200000000031605700003034c03210571000203190337072c020000000a0320074303620012032702000000000321057000050321057100060316034b0356072f02000000080743036200130327020000000005700005032105710006031703170743036a000105700005033a05700006032105710007031703160312034205700005031603420317034c0342034c057000030342034903540342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d0743036a000105700003033a0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d05700002053d036d05700002031b05700002031b0342 diff --git a/src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.mligo b/src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.mligo new file mode 100644 index 000000000000..37213e25a216 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.mligo @@ -0,0 +1,388 @@ +// ============================================================================= +// Entrypoints +// ============================================================================= + +type add_liquidity = + [@layout:comb] + { owner : address ; + minLqtMinted : nat ; + maxTokensDeposited : nat ; + deadline : timestamp ; + } + +type remove_liquidity = + [@layout:comb] + { [@annot:to] to_ : address ; // recipient of the liquidity redemption + lqtBurned : nat ; // amount of lqt owned by sender to burn + minXtzWithdrawn : tez ; // minimum amount of tez to withdraw + minTokensWithdrawn : nat ; // minimum amount of tokens to whitdw + deadline : timestamp ; // the time before which the request must be completed + } + +type xtz_to_token = + [@layout:comb] + { [@annot:to] to_ : address ; + minTokensBought : nat ; + deadline : timestamp ; + } + +type token_to_xtz = + [@layout:comb] + { [@annot:to] to_ : address ; + tokensSold : nat ; + minXtzBought : tez ; + deadline : timestamp ; + } + +type token_to_token = + [@layout:comb] + { outputDexterContract : address ; + minTokensBought : nat ; + [@annot:to] to_ : address ; + tokensSold : nat ; + deadline : timestamp ; + } + +type entrypoint = +| AddLiquidity of add_liquidity +| RemoveLiquidity of remove_liquidity +| XtzToToken of xtz_to_token +| TokenToXtz of token_to_xtz +| Default of unit +| TokenToToken of token_to_token + + +// ============================================================================= +// Storage +// ============================================================================= + +type storage = + [@layout:comb] + { tokenPool : nat ; + xtzPool : tez ; + lqtTotal : nat ; + tokenAddress : address ; + lqtAddress : address ; + } + +// ============================================================================= +// Type Synonyms +// ============================================================================= + +type result = operation list * storage + +// FA1.2 +type token_contract_transfer = address * (address * nat) +type get_balance = address * (nat contract) + +// custom entrypoint for LQT FA1.2 +type mintOrBurn = + [@layout:comb] + { quantity : int ; + target : address } + +// ============================================================================= +// Error codes +// ============================================================================= + +[@inline] let error_TOKEN_CONTRACT_MUST_HAVE_A_TRANSFER_ENTRYPOINT = 0n +(* 1n *) +[@inline] let error_SELF_IS_UPDATING_TOKEN_POOL_MUST_BE_FALSE = 2n +[@inline] let error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE = 3n +[@inline] let error_MAX_TOKENS_DEPOSITED_MUST_BE_GREATER_THAN_OR_EQUAL_TO_TOKENS_DEPOSITED = 4n +[@inline] let error_LQT_MINTED_MUST_BE_GREATER_THAN_MIN_LQT_MINTED = 5n +(* 6n *) +(* 7n *) +[@inline] let error_XTZ_BOUGHT_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_XTZ_BOUGHT = 8n +[@inline] let error_INVALID_TO_ADDRESS = 9n +[@inline] let error_AMOUNT_MUST_BE_ZERO = 10n +[@inline] let error_THE_AMOUNT_OF_XTZ_WITHDRAWN_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_XTZ_WITHDRAWN = 11n +[@inline] let error_LQT_CONTRACT_MUST_HAVE_A_MINT_OR_BURN_ENTRYPOINT = 12n +[@inline] let error_THE_AMOUNT_OF_TOKENS_WITHDRAWN_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_TOKENS_WITHDRAWN = 13n +[@inline] let error_CANNOT_BURN_MORE_THAN_THE_TOTAL_AMOUNT_OF_LQT = 14n +[@inline] let error_TOKEN_POOL_MINUS_TOKENS_WITHDRAWN_IS_NEGATIVE = 15n +(* 16n *) +(* 17n *) +[@inline] let error_TOKENS_BOUGHT_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_TOKENS_BOUGHT = 18n +[@inline] let error_TOKEN_POOL_MINUS_TOKENS_BOUGHT_IS_NEGATIVE = 19n +[@inline] let error_ONLY_MANAGER_CAN_SET_BAKER = 20n +[@inline] let error_ONLY_MANAGER_CAN_SET_MANAGER = 21n +[@inline] let error_BAKER_PERMANENTLY_FROZEN = 22n +[@inline] let error_ONLY_MANAGER_CAN_SET_LQT_ADRESS = 23n +[@inline] let error_LQT_ADDRESS_ALREADY_SET = 24n +[@inline] let error_CALL_NOT_FROM_AN_IMPLICIT_ACCOUNT = 25n +(* 26n *) +(* 27n *) +#if FA2 +[@inline] let error_INVALID_FA2_TOKEN_CONTRACT_MISSING_BALANCE_OF = 28n +#else +[@inline] let error_INVALID_FA12_TOKEN_CONTRACT_MISSING_GETBALANCE = 28n +#endif +[@inline] let error_THIS_ENTRYPOINT_MAY_ONLY_BE_CALLED_BY_GETBALANCE_OF_TOKENADDRESS = 29n +(* 30n *) +[@inline] let error_INVALID_INTERMEDIATE_CONTRACT = 31n +[@inline] let error_INVALID_FA2_BALANCE_RESPONSE = 32n +[@inline] let error_UNEXPECTED_REENTRANCE_IN_UPDATE_TOKEN_POOL = 33n + + +// ============================================================================= +// Functions +// ============================================================================= + +[@inline] +let fee = 999n + +[@inline] let null_address = ("tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU" : address) + +(* this is slightly inefficient to inline, but, nice to have a clean stack for + the entrypoints for the Coq verification *) +[@inline] +let mutez_to_natural (a: tez) : nat = a / 1mutez + +[@inline] +let natural_to_mutez (a: nat): tez = a * 1mutez + +[@inline] +let is_a_nat (i : int) : nat option = Michelson.is_nat i + +let ceildiv (numerator : nat) (denominator : nat) : nat = + match (ediv numerator denominator) with + | None -> (failwith("DIV by 0") : nat) + | Some v -> let (q, r) = v in if r = 0n then q else q + 1n + +[@inline] +let mint_or_burn (storage : storage) (target : address) (quantity : int) : operation = + let lqt_admin : mintOrBurn contract = + match (Tezos.get_entrypoint_opt "%mintOrBurn" storage.lqtAddress : mintOrBurn contract option) with + | None -> (failwith error_LQT_CONTRACT_MUST_HAVE_A_MINT_OR_BURN_ENTRYPOINT : mintOrBurn contract) + | Some contract -> contract in + Tezos.transaction {quantity = quantity ; target = target} 0mutez lqt_admin + +[@inline] +let token_transfer (storage : storage) (from : address) (to_ : address) (token_amount : nat) : operation = + let token_contract: token_contract_transfer contract = + match (Tezos.get_entrypoint_opt "%transfer" storage.tokenAddress : token_contract_transfer contract option) with + | None -> (failwith error_TOKEN_CONTRACT_MUST_HAVE_A_TRANSFER_ENTRYPOINT : token_contract_transfer contract) + | Some contract -> contract in + Tezos.transaction (from, (to_, token_amount)) 0mutez token_contract + +[@inline] +let xtz_transfer (to_ : address) (amount_ : tez) : operation = + let to_contract : unit contract = + match (Tezos.get_contract_opt to_ : unit contract option) with + | None -> (failwith error_INVALID_TO_ADDRESS : unit contract) + | Some c -> c in + Tezos.transaction () amount_ to_contract + +// ============================================================================= +// Entrypoint Functions +// ============================================================================= + +// We assume the contract is originated with at least one liquidity +// provider set up already, so lqtTotal, xtzPool and tokenPool will +// always be positive after the initial setup, unless all liquidity is +// removed, at which point the contract is considered dead and stops working +// properly. (To prevent this, at least one address should keep at least a +// small amount of liquidity in the contract forever.) + +let add_liquidity (param : add_liquidity) (storage: storage) : result = + let { owner = owner ; + minLqtMinted = minLqtMinted ; + maxTokensDeposited = maxTokensDeposited ; + deadline = deadline } = param in + + if Tezos.now >= deadline then + (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) + else + // the contract is initialized, use the existing exchange rate + // mints nothing if the contract has been emptied, but that's OK + let xtzPool : nat = mutez_to_natural storage.xtzPool in + let nat_amount : nat = mutez_to_natural Tezos.amount in + let lqt_minted : nat = nat_amount * storage.lqtTotal / xtzPool in + let tokens_deposited : nat = ceildiv (nat_amount * storage.tokenPool) xtzPool in + + if tokens_deposited > maxTokensDeposited then + (failwith error_MAX_TOKENS_DEPOSITED_MUST_BE_GREATER_THAN_OR_EQUAL_TO_TOKENS_DEPOSITED : result) + else if lqt_minted < minLqtMinted then + (failwith error_LQT_MINTED_MUST_BE_GREATER_THAN_MIN_LQT_MINTED : result) + else + let storage = {storage with + lqtTotal = storage.lqtTotal + lqt_minted ; + tokenPool = storage.tokenPool + tokens_deposited ; + xtzPool = storage.xtzPool + Tezos.amount} in + + // send tokens from sender to exchange + let op_token = token_transfer storage Tezos.sender Tezos.self_address tokens_deposited in + // mint lqt tokens for them + let op_lqt = mint_or_burn storage owner (int lqt_minted) in + ([op_token; op_lqt], storage) + +let remove_liquidity (param : remove_liquidity) (storage : storage) : result = + let { to_ = to_ ; + lqtBurned = lqtBurned ; + minXtzWithdrawn = minXtzWithdrawn ; + minTokensWithdrawn = minTokensWithdrawn ; + deadline = deadline } = param in + + if Tezos.now >= deadline then + (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) + else if Tezos.amount > 0mutez then + (failwith error_AMOUNT_MUST_BE_ZERO : result) + else begin + let xtz_withdrawn : tez = natural_to_mutez ((lqtBurned * (mutez_to_natural storage.xtzPool)) / storage.lqtTotal) in + let tokens_withdrawn : nat = lqtBurned * storage.tokenPool / storage.lqtTotal in + + // Check that minimum withdrawal conditions are met + if xtz_withdrawn < minXtzWithdrawn then + (failwith error_THE_AMOUNT_OF_XTZ_WITHDRAWN_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_XTZ_WITHDRAWN : result) + else if tokens_withdrawn < minTokensWithdrawn then + (failwith error_THE_AMOUNT_OF_TOKENS_WITHDRAWN_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_TOKENS_WITHDRAWN : result) + // Proceed to form the operations and update the storage + else begin + // calculate lqtTotal, convert int to nat + let new_lqtTotal = match (is_a_nat ( storage.lqtTotal - lqtBurned)) with + // This check should be unecessary, the fa12 logic normally takes care of it + | None -> (failwith error_CANNOT_BURN_MORE_THAN_THE_TOTAL_AMOUNT_OF_LQT : nat) + | Some n -> n in + // Calculate tokenPool, convert int to nat + let new_tokenPool = match is_a_nat (storage.tokenPool - tokens_withdrawn) with + | None -> (failwith error_TOKEN_POOL_MINUS_TOKENS_WITHDRAWN_IS_NEGATIVE : nat) + | Some n -> n in + + let op_lqt = mint_or_burn storage Tezos.sender (0 - lqtBurned) in + let op_token = token_transfer storage Tezos.self_address to_ tokens_withdrawn in + let op_xtz = xtz_transfer to_ xtz_withdrawn in + let storage = {storage with xtzPool = storage.xtzPool - xtz_withdrawn ; lqtTotal = new_lqtTotal ; tokenPool = new_tokenPool} in + ([op_lqt; op_token; op_xtz], storage) + end + end + + +let xtz_to_token (param : xtz_to_token) (storage : storage) = + let { to_ = to_ ; + minTokensBought = minTokensBought ; + deadline = deadline } = param in + + if Tezos.now >= deadline then + (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) + else begin + // we don't check that xtzPool > 0, because that is impossible + // unless all liquidity has been removed + let xtzPool = mutez_to_natural storage.xtzPool in + let nat_amount = mutez_to_natural Tezos.amount in + + let amount_net_burn = (nat_amount * 999n) / 1000n in + let burn_amount = abs (nat_amount - amount_net_burn) in + + let tokens_bought = + (let bought = (amount_net_burn * fee * storage.tokenPool) / (xtzPool * 1000n + (amount_net_burn * fee)) in + if bought < minTokensBought then + (failwith error_TOKENS_BOUGHT_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_TOKENS_BOUGHT : nat) + else + bought) + in + let new_tokenPool = (match is_nat (storage.tokenPool - tokens_bought) with + | None -> (failwith error_TOKEN_POOL_MINUS_TOKENS_BOUGHT_IS_NEGATIVE : nat) + | Some difference -> difference) in + + // update xtzPool + let storage = {storage with + xtzPool = storage.xtzPool + (natural_to_mutez amount_net_burn); + tokenPool = new_tokenPool } in + // send tokens_withdrawn to to address + // if tokens_bought is greater than storage.tokenPool, this will fail + let op = token_transfer storage Tezos.self_address to_ tokens_bought in + let op_burn = xtz_transfer null_address (natural_to_mutez burn_amount) in + ([ op ; op_burn], storage) + end + + +let token_to_xtz (param : token_to_xtz) (storage : storage) = + let { to_ = to_ ; + tokensSold = tokensSold ; + minXtzBought = minXtzBought ; + deadline = deadline } = param in + + if Tezos.now >= deadline then + (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) + else if Tezos.amount > 0mutez then + (failwith error_AMOUNT_MUST_BE_ZERO : result) + else + // we don't check that tokenPool > 0, because that is impossible + // unless all liquidity has been removed + let xtz_bought = natural_to_mutez (((tokensSold * fee * (mutez_to_natural storage.xtzPool)) / (storage.tokenPool * 1000n + (tokensSold * fee)))) in + + let xtz_bought_net_burn = + let bought = (xtz_bought * 999n) / 1000n in + if bought < minXtzBought then (failwith error_XTZ_BOUGHT_MUST_BE_GREATER_THAN_OR_EQUAL_TO_MIN_XTZ_BOUGHT : tez) else bought in + + let op_token = token_transfer storage Tezos.sender Tezos.self_address tokensSold in + let op_tez = xtz_transfer to_ xtz_bought_net_burn in + let storage = {storage with tokenPool = storage.tokenPool + tokensSold ; + xtzPool = storage.xtzPool - xtz_bought } in + + let burn_amount = xtz_bought - xtz_bought_net_burn in + let op_burn = xtz_transfer null_address burn_amount in + ([op_token ; op_tez; op_burn], storage) + +// entrypoint to allow depositing funds +let default_ (storage : storage) : result = + // update xtzPool + let storage = {storage with xtzPool = storage.xtzPool + Tezos.amount } in + (([] : operation list), storage) + +let token_to_token (param : token_to_token) (storage : storage) : result = + let { outputDexterContract = outputDexterContract ; + minTokensBought = minTokensBought ; + to_ = to_ ; + tokensSold = tokensSold ; + deadline = deadline } = param in + + let outputDexterContract_contract: xtz_to_token contract = + (match (Tezos.get_entrypoint_opt "%xtzToToken" outputDexterContract : xtz_to_token contract option) with + | None -> (failwith error_INVALID_INTERMEDIATE_CONTRACT : xtz_to_token contract) + | Some c -> c) in + + if Tezos.amount > 0mutez then + (failwith error_AMOUNT_MUST_BE_ZERO : result) + else if Tezos.now >= deadline then + (failwith error_THE_CURRENT_TIME_MUST_BE_LESS_THAN_THE_DEADLINE : result) + else + // we don't check that tokenPool > 0, because that is impossible unless all liquidity has been removed + let xtz_bought = (tokensSold * fee * storage.xtzPool) / (storage.tokenPool * 1000n + (tokensSold * fee)) in + + let xtz_bought_net_burn = (xtz_bought * 999n) / 1000n in + + let storage = {storage with + tokenPool = storage.tokenPool + tokensSold ; + xtzPool = storage.xtzPool - xtz_bought } in + + let op1 = token_transfer storage Tezos.sender Tezos.self_address tokensSold in + let op2 = + Tezos.transaction + {to_ = to_; minTokensBought = minTokensBought; deadline = deadline} + xtz_bought_net_burn + outputDexterContract_contract in + + let burn_amount = xtz_bought - xtz_bought_net_burn in + let op_burn = xtz_transfer null_address burn_amount in + ([op1 ; op2; op_burn], storage) + +// ============================================================================= +// Main +// ============================================================================= + +let main ((entrypoint, storage) : entrypoint * storage) : result = + match entrypoint with + | AddLiquidity param -> + add_liquidity param storage + | RemoveLiquidity param -> + remove_liquidity param storage + | Default -> + default_ storage + | XtzToToken param -> + xtz_to_token param storage + | TokenToXtz param -> + token_to_xtz param storage + | TokenToToken param -> + token_to_token param storage \ No newline at end of file diff --git a/src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.tz b/src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.tz new file mode 100644 index 000000000000..15a0819c52e8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contracts/cpmm.tz @@ -0,0 +1,929 @@ +{ parameter + (or (or (or (pair %addLiquidity + (address %owner) + (pair (nat %minLqtMinted) (pair (nat %maxTokensDeposited) (timestamp %deadline)))) + (unit %default)) + (or (pair %removeLiquidity + (address %to) + (pair (nat %lqtBurned) + (pair (mutez %minXtzWithdrawn) (pair (nat %minTokensWithdrawn) (timestamp %deadline))))) + (pair %tokenToToken + (address %outputDexterContract) + (pair (nat %minTokensBought) + (pair (address %to) (pair (nat %tokensSold) (timestamp %deadline))))))) + (or (pair %tokenToXtz + (address %to) + (pair (nat %tokensSold) (pair (mutez %minXtzBought) (timestamp %deadline)))) + (pair %xtzToToken (address %to) (pair (nat %minTokensBought) (timestamp %deadline))))) ; + storage + (pair (nat %tokenPool) + (pair (mutez %xtzPool) + (pair (nat %lqtTotal) (pair (address %tokenAddress) (address %lqtAddress))))) ; + code { DUP ; + CDR ; + SWAP ; + CAR ; + IF_LEFT + { IF_LEFT + { IF_LEFT + { DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + NOW ; + COMPARE ; + GE ; + IF { DROP 4 ; PUSH nat 3 ; FAILWITH } + { PUSH mutez 1 ; + DIG 4 ; + DUP ; + DUG 5 ; + CDR ; + CAR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + AMOUNT ; + PUSH mutez 1 ; + SWAP ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + SWAP ; + DUP ; + DUG 2 ; + DIG 6 ; + DUP ; + DUG 7 ; + CDR ; + CDR ; + CAR ; + DIG 2 ; + DUP ; + DUG 3 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DIG 2 ; + DIG 6 ; + DUP ; + DUG 7 ; + CAR ; + DIG 3 ; + MUL ; + EDIV ; + IF_NONE + { PUSH string "DIV by 0" ; FAILWITH } + { DUP ; + CDR ; + SWAP ; + CAR ; + PUSH nat 0 ; + DIG 2 ; + COMPARE ; + EQ ; + IF {} { PUSH nat 1 ; ADD } } ; + DIG 2 ; + SWAP ; + DUP ; + DUG 2 ; + COMPARE ; + GT ; + IF { DROP 5 ; PUSH nat 4 ; FAILWITH } + { DUG 2 ; + DUP ; + DUG 3 ; + COMPARE ; + LT ; + IF { DROP 4 ; PUSH nat 5 ; FAILWITH } + { DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + CDR ; + CDR ; + DIG 2 ; + DUP ; + DUG 3 ; + DIG 5 ; + DUP ; + DUG 6 ; + CDR ; + CDR ; + CAR ; + ADD ; + PAIR ; + DIG 4 ; + DUP ; + DUG 5 ; + CDR ; + CAR ; + PAIR ; + DIG 4 ; + DUP ; + DUG 5 ; + CAR ; + PAIR ; + CDR ; + SWAP ; + DUP ; + DUG 2 ; + DIG 5 ; + DUP ; + DUG 6 ; + CAR ; + ADD ; + PAIR ; + DUP ; + CDR ; + CDR ; + AMOUNT ; + DIG 6 ; + CDR ; + CAR ; + ADD ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + SWAP ; + SELF ; + ADDRESS ; + PAIR ; + SENDER ; + PAIR ; + SWAP ; + DUP ; + DUG 2 ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + DIG 3 ; + CDR ; + CDR ; + CDR ; + CAR ; + CONTRACT %transfer (pair address (pair address nat)) ; + IF_NONE { PUSH nat 0 ; FAILWITH } {} ; + PUSH mutez 0 ; + DIG 3 ; + DIG 3 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS ; + DIG 2 ; + INT ; + DIG 3 ; + PAIR ; + DIG 2 ; + DUP ; + DUG 3 ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + DIG 2 ; + CDR ; + CDR ; + CDR ; + CDR ; + CONTRACT %mintOrBurn (pair (int %quantity) (address %target)) ; + IF_NONE { PUSH nat 12 ; FAILWITH } {} ; + PUSH mutez 0 ; + DIG 2 ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS ; + DIG 2 ; + NIL operation ; + DIG 2 ; + CONS ; + DIG 2 ; + CONS ; + PAIR } } } } + { DROP ; + DUP ; + CDR ; + CDR ; + AMOUNT ; + DIG 2 ; + DUP ; + DUG 3 ; + CDR ; + CAR ; + ADD ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + NIL operation ; + PAIR } } + { IF_LEFT + { DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + NOW ; + COMPARE ; + GE ; + IF { DROP 5 ; PUSH nat 3 ; FAILWITH } + { PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + GT ; + IF { DROP 5 ; PUSH nat 10 ; FAILWITH } + { DIG 4 ; + DUP ; + DUG 5 ; + CDR ; + CDR ; + CAR ; + PUSH mutez 1 ; + DIG 6 ; + DUP ; + DUG 7 ; + CDR ; + CAR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DIG 4 ; + DUP ; + DUG 5 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + PUSH mutez 1 ; + SWAP ; + MUL ; + DIG 5 ; + DUP ; + DUG 6 ; + CDR ; + CDR ; + CAR ; + DIG 6 ; + DUP ; + DUG 7 ; + CAR ; + DIG 5 ; + DUP ; + DUG 6 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DIG 3 ; + DIG 2 ; + DUP ; + DUG 3 ; + COMPARE ; + LT ; + IF { DROP 6 ; PUSH nat 11 ; FAILWITH } + { DIG 2 ; + SWAP ; + DUP ; + DUG 2 ; + COMPARE ; + LT ; + IF { DROP 5 ; PUSH nat 13 ; FAILWITH } + { DIG 2 ; + DUP ; + DUG 3 ; + DIG 5 ; + DUP ; + DUG 6 ; + CDR ; + CDR ; + CAR ; + SUB ; + ISNAT ; + IF_NONE { PUSH nat 14 ; FAILWITH } {} ; + SWAP ; + DUP ; + DUG 2 ; + DIG 6 ; + DUP ; + DUG 7 ; + CAR ; + SUB ; + ISNAT ; + IF_NONE { PUSH nat 15 ; FAILWITH } {} ; + DIG 4 ; + PUSH int 0 ; + SUB ; + SENDER ; + PAIR ; + DIG 6 ; + DUP ; + DUG 7 ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + DIG 2 ; + CDR ; + CDR ; + CDR ; + CDR ; + CONTRACT %mintOrBurn (pair (int %quantity) (address %target)) ; + IF_NONE { PUSH nat 12 ; FAILWITH } {} ; + PUSH mutez 0 ; + DIG 2 ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS ; + DIG 3 ; + DIG 5 ; + DUP ; + DUG 6 ; + PAIR ; + SELF ; + ADDRESS ; + PAIR ; + DIG 6 ; + DUP ; + DUG 7 ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + DIG 3 ; + CDR ; + CDR ; + CDR ; + CAR ; + CONTRACT %transfer (pair address (pair address nat)) ; + IF_NONE { PUSH nat 0 ; FAILWITH } {} ; + PUSH mutez 0 ; + DIG 3 ; + DIG 3 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS ; + DIG 4 ; + DUP ; + DUG 5 ; + DIG 6 ; + CONTRACT unit ; + IF_NONE { PUSH nat 9 ; FAILWITH } {} ; + SWAP ; + PUSH unit Unit ; + TRANSFER_TOKENS ; + DIG 6 ; + DUP ; + DUG 7 ; + CDR ; + CDR ; + DIG 6 ; + DIG 7 ; + DUP ; + DUG 8 ; + CDR ; + CAR ; + SUB ; + PAIR ; + DIG 6 ; + CAR ; + PAIR ; + DUP ; + CDR ; + CDR ; + CDR ; + DIG 6 ; + PAIR ; + SWAP ; + DUP ; + DUG 2 ; + CDR ; + CAR ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + CDR ; + DIG 4 ; + PAIR ; + NIL operation ; + DIG 2 ; + CONS ; + DIG 2 ; + CONS ; + DIG 2 ; + CONS ; + PAIR } } } } } + { DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + DIG 4 ; + CONTRACT %xtzToToken + (pair (address %to) (pair (nat %minTokensBought) (timestamp %deadline))) ; + IF_NONE { PUSH nat 31 ; FAILWITH } {} ; + PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + GT ; + IF { DROP 6 ; PUSH nat 10 ; FAILWITH } + { DIG 2 ; + DUP ; + DUG 3 ; + NOW ; + COMPARE ; + GE ; + IF { DROP 6 ; PUSH nat 3 ; FAILWITH } + { PUSH nat 999 ; + DIG 2 ; + DUP ; + DUG 3 ; + MUL ; + PUSH nat 1000 ; + DIG 7 ; + DUP ; + DUG 8 ; + CAR ; + MUL ; + ADD ; + DIG 6 ; + DUP ; + DUG 7 ; + CDR ; + CAR ; + PUSH nat 999 ; + DIG 4 ; + DUP ; + DUG 5 ; + MUL ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + PUSH nat 1000 ; + PUSH nat 999 ; + DIG 2 ; + DUP ; + DUG 3 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DIG 7 ; + DUP ; + DUG 8 ; + CDR ; + DIG 4 ; + DUP ; + DUG 5 ; + DIG 9 ; + DUP ; + DUG 10 ; + CAR ; + ADD ; + PAIR ; + DUP ; + CDR ; + CDR ; + DIG 3 ; + DUP ; + DUG 4 ; + DIG 10 ; + CDR ; + CAR ; + SUB ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + DIG 4 ; + SELF ; + ADDRESS ; + PAIR ; + SENDER ; + PAIR ; + SWAP ; + DUP ; + DUG 2 ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + DIG 3 ; + CDR ; + CDR ; + CDR ; + CAR ; + CONTRACT %transfer (pair address (pair address nat)) ; + IF_NONE { PUSH nat 0 ; FAILWITH } {} ; + PUSH mutez 0 ; + DIG 3 ; + DIG 3 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS ; + DIG 4 ; + DIG 3 ; + DUP ; + DUG 4 ; + DIG 6 ; + DIG 8 ; + PAIR ; + DIG 7 ; + PAIR ; + TRANSFER_TOKENS ; + DIG 3 ; + DIG 4 ; + SUB ; + PUSH address "tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU" ; + CONTRACT unit ; + IF_NONE { PUSH nat 9 ; FAILWITH } {} ; + SWAP ; + PUSH unit Unit ; + TRANSFER_TOKENS ; + DIG 3 ; + NIL operation ; + DIG 2 ; + CONS ; + DIG 2 ; + CONS ; + DIG 2 ; + CONS ; + PAIR } } } } } + { IF_LEFT + { DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + NOW ; + COMPARE ; + GE ; + IF { DROP 4 ; PUSH nat 3 ; FAILWITH } + { PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + GT ; + IF { DROP 4 ; PUSH nat 10 ; FAILWITH } + { PUSH nat 999 ; + DIG 2 ; + DUP ; + DUG 3 ; + MUL ; + PUSH nat 1000 ; + DIG 5 ; + DUP ; + DUG 6 ; + CAR ; + MUL ; + ADD ; + PUSH mutez 1 ; + DIG 5 ; + DUP ; + DUG 6 ; + CDR ; + CAR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + PUSH nat 999 ; + DIG 4 ; + DUP ; + DUG 5 ; + MUL ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + PUSH mutez 1 ; + SWAP ; + MUL ; + PUSH nat 1000 ; + PUSH nat 999 ; + DIG 2 ; + DUP ; + DUG 3 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DIG 2 ; + SWAP ; + DUP ; + DUG 2 ; + COMPARE ; + LT ; + IF { DROP ; PUSH nat 8 ; FAILWITH } {} ; + DIG 2 ; + DUP ; + DUG 3 ; + SELF ; + ADDRESS ; + PAIR ; + SENDER ; + PAIR ; + DIG 5 ; + DUP ; + DUG 6 ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + DIG 3 ; + CDR ; + CDR ; + CDR ; + CAR ; + CONTRACT %transfer (pair address (pair address nat)) ; + IF_NONE { PUSH nat 0 ; FAILWITH } {} ; + PUSH mutez 0 ; + DIG 3 ; + DIG 3 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS ; + SWAP ; + DUP ; + DUG 2 ; + DIG 5 ; + CONTRACT unit ; + IF_NONE { PUSH nat 9 ; FAILWITH } {} ; + SWAP ; + PUSH unit Unit ; + TRANSFER_TOKENS ; + DIG 5 ; + DUP ; + DUG 6 ; + CDR ; + DIG 5 ; + DIG 6 ; + DUP ; + DUG 7 ; + CAR ; + ADD ; + PAIR ; + DUP ; + CDR ; + CDR ; + DIG 5 ; + DUP ; + DUG 6 ; + DIG 7 ; + CDR ; + CAR ; + SUB ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + DIG 3 ; + DIG 4 ; + SUB ; + PUSH address "tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU" ; + CONTRACT unit ; + IF_NONE { PUSH nat 9 ; FAILWITH } {} ; + SWAP ; + PUSH unit Unit ; + TRANSFER_TOKENS ; + SWAP ; + NIL operation ; + DIG 2 ; + CONS ; + DIG 2 ; + CONS ; + DIG 2 ; + CONS ; + PAIR } } } + { DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + NOW ; + COMPARE ; + GE ; + IF { DROP 3 ; PUSH nat 3 ; FAILWITH } + { PUSH mutez 1 ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + CAR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + AMOUNT ; + PUSH mutez 1 ; + SWAP ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + PUSH nat 1000 ; + PUSH nat 999 ; + DIG 2 ; + DUP ; + DUG 3 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DUP ; + DIG 2 ; + SUB ; + ABS ; + PUSH nat 999 ; + DIG 2 ; + DUP ; + DUG 3 ; + MUL ; + PUSH nat 1000 ; + DIG 4 ; + MUL ; + ADD ; + DIG 5 ; + DUP ; + DUG 6 ; + CAR ; + PUSH nat 999 ; + DIG 4 ; + DUP ; + DUG 5 ; + MUL ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DIG 3 ; + SWAP ; + DUP ; + DUG 2 ; + COMPARE ; + LT ; + IF { DROP ; PUSH nat 18 ; FAILWITH } {} ; + DUP ; + DIG 5 ; + DUP ; + DUG 6 ; + CAR ; + SUB ; + ISNAT ; + IF_NONE { PUSH nat 19 ; FAILWITH } {} ; + DIG 5 ; + DUP ; + DUG 6 ; + CDR ; + CDR ; + PUSH mutez 1 ; + DIG 5 ; + MUL ; + DIG 6 ; + DUP ; + DUG 7 ; + CDR ; + CAR ; + ADD ; + PAIR ; + DIG 5 ; + CAR ; + PAIR ; + CDR ; + SWAP ; + PAIR ; + SWAP ; + DIG 3 ; + PAIR ; + SELF ; + ADDRESS ; + PAIR ; + SWAP ; + DUP ; + DUG 2 ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + SWAP ; + DUP ; + CDR ; + SWAP ; + CAR ; + DIG 3 ; + CDR ; + CDR ; + CDR ; + CAR ; + CONTRACT %transfer (pair address (pair address nat)) ; + IF_NONE { PUSH nat 0 ; FAILWITH } {} ; + PUSH mutez 0 ; + DIG 3 ; + DIG 3 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS ; + PUSH mutez 1 ; + DIG 3 ; + MUL ; + PUSH address "tz1Ke2h7sDdakHJQh8WX4Z372du1KChsksyU" ; + CONTRACT unit ; + IF_NONE { PUSH nat 9 ; FAILWITH } {} ; + SWAP ; + PUSH unit Unit ; + TRANSFER_TOKENS ; + DIG 2 ; + NIL operation ; + DIG 2 ; + CONS ; + DIG 2 ; + CONS ; + PAIR } } } } } + diff --git a/src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.bin b/src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.bin new file mode 100644 index 000000000000..4fa01f58526f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.bin @@ -0,0 +1 @@ +0x020000070005000764076407640865046e00000008257370656e6465720462000000062576616c75650000000825617070726f766508650865046e00000006256f776e6572046e00000008257370656e646572000000082572657175657374065a0362000000092563616c6c6261636b0000000d25676574416c6c6f77616e636507640865046e00000006256f776e6572065a0362000000092563616c6c6261636b0000000b2567657442616c616e63650865046c000000082572657175657374065a0362000000092563616c6c6261636b0000000f25676574546f74616c537570706c7907640865045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e0865046e000000052566726f6d0765046e0000000325746f0462000000062576616c756500000009257472616e73666572050107650861036e03620000000725746f6b656e73076508610765046e00000006256f776e6572046e00000008257370656e64657203620000000b25616c6c6f77616e6365730765046e000000062561646d696e04620000000d25746f74616c5f737570706c7905020200000552032103170743036a000003130319033c072c020000001607430368010000000b446f6e7453656e6454657a03270200000000034c0316072e02000001b2072e0200000132072e02000000e2034c03210571000203170316034c0321057100020316034803420743036200000570000303210571000403170319032a07430362000005700003032105710004057000030321057100040329072f020000000607430362000002000000000319032a0314072c0200000020074303680100000015556e73616665416c6c6f77616e63654368616e676503270200000000057000030321057100040317031705700002057000030317074303620000034c03210571000203190325072c02000000060320053e0362020000000203460570000303500342034c03160342053d036d03420200000044034c032105700002053d036d034c03210571000203170743036a000005700004031703160570000403160329072f02000000060743036200000200000000034d031b03420200000074072e0200000042034c032105700002053d036d034c03210571000203170743036a00000570000403160570000403160329072f02000000060743036200000200000000034d031b03420200000026034c032105700002053d036d034c03170743036a000005700003031703170317034d031b0342020000035e072e020000013c034c03210571000203170317031603480319033c072c02000000140743036801000000094f6e6c7941646d696e03270200000000032103160570000203210571000303160570000203210571000303170329072f0200000006074303620000020000000003120356072f020000003607430368010000002b43616e6e6f74206275726e206d6f7265207468616e207468652074617267657427732062616c616e63652e03270200000000034c032105710002031605700003032105710004031703170317031203110570000303210571000403170570000403160743036200000570000403210571000503190325072c020000000a057000030320053e03620200000006057000030346057000040317035003420321057100020317031703160342034c032105710002031703160342034c03160342053d036d03420200000216034c03210571000203170316057000020321057100030316057000020321057100030316034803190325072c0200000002034c02000000a903480570000303210571000403160342057000030321057100040317031705700003032105710004057000020321057100030329072f02000000060743036200000200000000034b0356072f020000001d0743036801000000124e6f74456e6f756768416c6c6f77616e636503270200000000057000030743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c03460570000203500570000203210571000303170317057000020321057100030570000403210571000503160329072f02000000060743036200000200000000034b0356072f020000001b0743036801000000104e6f74456e6f75676842616c616e636503270200000000057000020743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c034605700003032105710004031603500570000203210571000303170317034c03210571000205700004032105710005031703160329072f020000000607430362000002000000000312034c0743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c034605700003031703160350057000020317034c0342032103170317057000020342034c03160342053d036d0342 diff --git a/src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.mligo b/src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.mligo new file mode 100644 index 000000000000..7c2fa5012d1e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.mligo @@ -0,0 +1,164 @@ +type transfer = + [@layout:comb] + { [@annot:from] address_from : address; + [@annot:to] address_to : address; + value : nat } + +type approve = + [@layout:comb] + { spender : address; + value : nat } + +type mintOrBurn = + [@layout:comb] + { quantity : int ; + target : address } + +type allowance_key = + [@layout:comb] + { owner : address; + spender : address } + +type getAllowance = + [@layout:comb] + { request : allowance_key; + callback : nat contract } + +type getBalance = + [@layout:comb] + { owner : address; + callback : nat contract } + +type getTotalSupply = + [@layout:comb] + { request : unit ; + callback : nat contract } + +type tokens = (address, nat) big_map +type allowances = (allowance_key, nat) big_map + +type storage = + [@layout:comb] + { tokens : tokens; + allowances : allowances; + admin : address; + total_supply : nat; + } + +type parameter = + | Transfer of transfer + | Approve of approve + | MintOrBurn of mintOrBurn + | GetAllowance of getAllowance + | GetBalance of getBalance + | GetTotalSupply of getTotalSupply + +type result = operation list * storage + +[@inline] +let maybe (n : nat) : nat option = + if n = 0n + then (None : nat option) + else Some n + +let transfer (param : transfer) (storage : storage) : result = + let allowances = storage.allowances in + let tokens = storage.tokens in + let allowances = + if Tezos.sender = param.address_from + then allowances + else + let allowance_key = { owner = param.address_from ; spender = Tezos.sender } in + let authorized_value = + match Big_map.find_opt allowance_key allowances with + | Some value -> value + | None -> 0n in + let authorized_value = + match is_nat (authorized_value - param.value) with + | None -> (failwith "NotEnoughAllowance" : nat) + | Some authorized_value -> authorized_value in + Big_map.update allowance_key (maybe authorized_value) allowances in + let tokens = + let from_balance = + match Big_map.find_opt param.address_from tokens with + | Some value -> value + | None -> 0n in + let from_balance = + match is_nat (from_balance - param.value) with + | None -> (failwith "NotEnoughBalance" : nat) + | Some from_balance -> from_balance in + Big_map.update param.address_from (maybe from_balance) tokens in + let tokens = + let to_balance = + match Big_map.find_opt param.address_to tokens with + | Some value -> value + | None -> 0n in + let to_balance = to_balance + param.value in + Big_map.update param.address_to (maybe to_balance) tokens in + (([] : operation list), { storage with tokens = tokens; allowances = allowances }) + +let approve (param : approve) (storage : storage) : result = + let allowances = storage.allowances in + let allowance_key = { owner = Tezos.sender ; spender = param.spender } in + let previous_value = + match Big_map.find_opt allowance_key allowances with + | Some value -> value + | None -> 0n in + begin + if previous_value > 0n && param.value > 0n + then (failwith "UnsafeAllowanceChange") + else (); + let allowances = Big_map.update allowance_key (maybe param.value) allowances in + (([] : operation list), { storage with allowances = allowances }) + end + +let mintOrBurn (param : mintOrBurn) (storage : storage) : result = + begin + if Tezos.sender <> storage.admin + then failwith "OnlyAdmin" + else (); + let tokens = storage.tokens in + let old_balance = + match Big_map.find_opt param.target tokens with + | None -> 0n + | Some bal -> bal in + let new_balance = + match is_nat (old_balance + param.quantity) with + | None -> (failwith "Cannot burn more than the target's balance." : nat) + | Some bal -> bal in + let tokens = Big_map.update param.target (maybe new_balance) storage.tokens in + let total_supply = abs (storage.total_supply + param.quantity) in + (([] : operation list), { storage with tokens = tokens ; total_supply = total_supply }) + end + +let getAllowance (param : getAllowance) (storage : storage) : operation list = + let value = + match Big_map.find_opt param.request storage.allowances with + | Some value -> value + | None -> 0n in + [Tezos.transaction value 0mutez param.callback] + +let getBalance (param : getBalance) (storage : storage) : operation list = + let value = + match Big_map.find_opt param.owner storage.tokens with + | Some value -> value + | None -> 0n in + [Tezos.transaction value 0mutez param.callback] + +let getTotalSupply (param : getTotalSupply) (storage : storage) : operation list = + let total = storage.total_supply in + [Tezos.transaction total 0mutez param.callback] + +let main (param, storage : parameter * storage) : result = + begin + if Tezos.amount <> 0mutez + then failwith "DontSendTez" + else (); + match param with + | Transfer param -> transfer param storage + | Approve param -> approve param storage + | MintOrBurn param -> mintOrBurn param storage + | GetAllowance param -> (getAllowance param storage, storage) + | GetBalance param -> (getBalance param storage, storage) + | GetTotalSupply param -> (getTotalSupply param storage, storage) + end diff --git a/src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.tz b/src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.tz new file mode 100644 index 000000000000..d0f5f45fd05f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/contracts/lqt.tz @@ -0,0 +1,327 @@ +{ parameter + (or (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (pair (address %to) (nat %value))))) ; + storage + (pair (big_map %tokens address nat) + (pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (pair (address %admin) (nat %total_supply)))) ; + code { DUP ; + CDR ; + PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + NEQ ; + IF { PUSH string "DontSendTez" ; FAILWITH } {} ; + SWAP ; + CAR ; + IF_LEFT + { IF_LEFT + { IF_LEFT + { SWAP ; + DUP ; + DUG 2 ; + CDR ; + CAR ; + SWAP ; + DUP ; + DUG 2 ; + CAR ; + SENDER ; + PAIR ; + PUSH nat 0 ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + COMPARE ; + GT ; + PUSH nat 0 ; + DIG 3 ; + DUP ; + DUG 4 ; + DIG 3 ; + DUP ; + DUG 4 ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + COMPARE ; + GT ; + AND ; + IF { PUSH string "UnsafeAllowanceChange" ; FAILWITH } {} ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + CDR ; + DIG 2 ; + DIG 3 ; + CDR ; + PUSH nat 0 ; + SWAP ; + DUP ; + DUG 2 ; + COMPARE ; + EQ ; + IF { DROP ; NONE nat } { SOME } ; + DIG 3 ; + UPDATE ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + NIL operation ; + PAIR } + { SWAP ; + DUP ; + DIG 2 ; + NIL operation ; + SWAP ; + DUP ; + DUG 2 ; + CDR ; + PUSH mutez 0 ; + DIG 4 ; + CDR ; + CAR ; + DIG 4 ; + CAR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + TRANSFER_TOKENS ; + CONS ; + PAIR } } + { IF_LEFT + { SWAP ; + DUP ; + DIG 2 ; + NIL operation ; + SWAP ; + DUP ; + DUG 2 ; + CDR ; + PUSH mutez 0 ; + DIG 4 ; + CAR ; + DIG 4 ; + CAR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + TRANSFER_TOKENS ; + CONS ; + PAIR } + { SWAP ; + DUP ; + DIG 2 ; + NIL operation ; + SWAP ; + CDR ; + PUSH mutez 0 ; + DIG 3 ; + CDR ; + CDR ; + CDR ; + TRANSFER_TOKENS ; + CONS ; + PAIR } } } + { IF_LEFT + { SWAP ; + DUP ; + DUG 2 ; + CDR ; + CDR ; + CAR ; + SENDER ; + COMPARE ; + NEQ ; + IF { PUSH string "OnlyAdmin" ; FAILWITH } {} ; + DUP ; + CAR ; + DIG 2 ; + DUP ; + DUG 3 ; + CAR ; + DIG 2 ; + DUP ; + DUG 3 ; + CDR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + ADD ; + ISNAT ; + IF_NONE + { PUSH string "Cannot burn more than the target's balance." ; FAILWITH } + {} ; + SWAP ; + DUP ; + DUG 2 ; + CAR ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + CDR ; + CDR ; + ADD ; + ABS ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + DIG 4 ; + CAR ; + PUSH nat 0 ; + DIG 4 ; + DUP ; + DUG 5 ; + COMPARE ; + EQ ; + IF { DIG 3 ; DROP ; NONE nat } { DIG 3 ; SOME } ; + DIG 4 ; + CDR ; + UPDATE ; + PAIR ; + DUP ; + DUG 2 ; + CDR ; + CDR ; + CAR ; + PAIR ; + SWAP ; + DUP ; + DUG 2 ; + CDR ; + CAR ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + NIL operation ; + PAIR } + { SWAP ; + DUP ; + DUG 2 ; + CDR ; + CAR ; + DIG 2 ; + DUP ; + DUG 3 ; + CAR ; + DIG 2 ; + DUP ; + DUG 3 ; + CAR ; + SENDER ; + COMPARE ; + EQ ; + IF { SWAP } + { SENDER ; + DIG 3 ; + DUP ; + DUG 4 ; + CAR ; + PAIR ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + CDR ; + DIG 3 ; + DUP ; + DUG 4 ; + DIG 2 ; + DUP ; + DUG 3 ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + SUB ; + ISNAT ; + IF_NONE { PUSH string "NotEnoughAllowance" ; FAILWITH } {} ; + DIG 3 ; + PUSH nat 0 ; + DIG 2 ; + DUP ; + DUG 3 ; + COMPARE ; + EQ ; + IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; + DIG 2 ; + UPDATE } ; + DIG 2 ; + DUP ; + DUG 3 ; + CDR ; + CDR ; + DIG 2 ; + DUP ; + DUG 3 ; + DIG 4 ; + DUP ; + DUG 5 ; + CAR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + SUB ; + ISNAT ; + IF_NONE { PUSH string "NotEnoughBalance" ; FAILWITH } {} ; + DIG 2 ; + PUSH nat 0 ; + DIG 2 ; + DUP ; + DUG 3 ; + COMPARE ; + EQ ; + IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; + DIG 3 ; + DUP ; + DUG 4 ; + CAR ; + UPDATE ; + DIG 2 ; + DUP ; + DUG 3 ; + CDR ; + CDR ; + SWAP ; + DUP ; + DUG 2 ; + DIG 4 ; + DUP ; + DUG 5 ; + CDR ; + CAR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + ADD ; + SWAP ; + PUSH nat 0 ; + DIG 2 ; + DUP ; + DUG 3 ; + COMPARE ; + EQ ; + IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; + DIG 3 ; + CDR ; + CAR ; + UPDATE ; + DIG 2 ; + CDR ; + SWAP ; + PAIR ; + DUP ; + CDR ; + CDR ; + DIG 2 ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + NIL operation ; + PAIR } } } } + diff --git a/src/proto_012_PsiThaCa/lib_protocol/coq-of-ocaml/README.md b/src/proto_012_PsiThaCa/lib_protocol/coq-of-ocaml/README.md new file mode 100644 index 000000000000..dc8bbda5de5e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/coq-of-ocaml/README.md @@ -0,0 +1,11 @@ +# coq-of-ocaml + +In this folder we put the files relevant to the compilation of the protocol to +Coq using [coq-of-ocaml](https://clarus.github.io/coq-of-ocaml/). The code of +the protocol is annotated with `[@coq_...]` OCaml attributes. These attributes +are here to help the compilation to Coq. We document them on: +https://clarus.github.io/coq-of-ocaml/docs/attributes + +* `config.json` This file describes the configuration parameters for + coq-of-ocaml in the CI. For more information, see the + [documentation](https://clarus.github.io/coq-of-ocaml/docs/configuration). diff --git a/src/proto_012_PsiThaCa/lib_protocol/coq-of-ocaml/config.json b/src/proto_012_PsiThaCa/lib_protocol/coq-of-ocaml/config.json new file mode 100644 index 000000000000..22b81851b21b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/coq-of-ocaml/config.json @@ -0,0 +1,255 @@ +{ + "alias_barrier_modules": [ + "Tezos_protocol_environment_alpha__Environment" + ], + "constant_warning": false, + "constructor_map": [ + ["public_key_hash", "Ed25519", "Ed25519Hash"], + ["public_key_hash", "P256", "P256Hash"], + ["public_key_hash", "Secp256k1", "Secp256k1Hash"] + ], + "error_category_blacklist": [ + "side_effect" + ], + "error_filename_blacklist": [ + ], + "error_message_blacklist": [ + "Unbound module Tezos_protocol_012_PsiThaCa_functor", + "The placeholders `_` in types are not handled", + "No type known for the following variants: `Ge, `Lt, `Eq, `Le, `Gt", + "No type known for the following variants: `Eq, `Ge, `Gt, `Le, `Lt", + "No type known for the following variants: `Eq", + "Constructor of the variant `Eq unknown", + "No type known for the following variants: `Tree, `Value", + "Constructor of the variant `Tree unknown", + "Constructor of the variant `Value unknown", + "Anonymous definition of signatures is not handled", + "A variable name instead of a pattern was expected", + "We only support extensible types in patterns at the head", + "This kind of signature is not handled", + "Tezos_raw_protocol_012_PsiThaCa.Raw_context_intf.T", + "No type known for the following variants:", + "Constructor of the variant", + "Polymorphic variant types are defined as standard algebraic types" + ], + "escape_value": [ + "a", + "acc", + "alloc", + "b", + "baking_rights_query", + "case", + "cons", + "context", + "descr", + "diff", + "elt", + "endorsing_rights_query", + "eq", + "error", + "field", + "fixed", + "fp", + "frozen_balance", + "gas_counter_status", + "handler", + "has_big_map", + "has_lazy_storage", + "hash", + "info", + "init", + "integral", + "internal_gas", + "json", + "json_schema", + "judgement", + "key", + "kind", + "l", + "lazy_expr", + "level_query", + "list_query", + "may_saturate", + "mul_safe", + "namespace", + "nonce", + "query", + "p", + "parametric", + "r", + "raw", + "seed", + "sequence", + "snapshot", + "stack", + "storage", + "storage_error", + "t", + "tc_context", + "toplevel", + "trace", + "type_logger" + ], + "first_class_module_path_blacklist": [ + "Tezos_raw_protocol_012_PsiThaCa", + "Tezos_protocol_environment_alpha.Environment", + "Tezos_protocol_environment_alpha.Environment.Sapling" + ], + "first_class_module_signature_blacklist": [ + "Environment_context.TREE", + "Tezos_protocol_environment_alpha__Environment.Map.OrderedType", + "Tezos_protocol_environment_alpha__Environment.Set.OrderedType", + "Tezos_raw_protocol_012_PsiThaCa__Raw_context.T", + "Tezos_raw_protocol_012_PsiThaCa.Alpha_context.Cache.CLIENT", + "Tezos_raw_protocol_012_PsiThaCa.Alpha_context.Cache.INTERFACE", + "Tezos_sapling__Core_sig.T_encoding" + ], + "merge_returns": [ + ["return=", "return?", "return=?"] + ], + "merge_types": [ + ["M=", "M?", "M=?"] + ], + "monadic_lets": [ + ["Error_monad.op_gtgteq", "let="], + ["Error_monad.op_gtgteqquestion", "let=?"], + ["Error_monad.op_gtgtquestion", "let?"] + ], + "monadic_let_returns": [ + ["Error_monad.op_gtpipeeq", "let=", "return="], + ["Error_monad.op_gtpipeeqquestion", "let=?", "return=?"], + ["Error_monad.op_gtpipequestion", "let?", "return?"] + ], + "monadic_returns": [ + ["Lwt.__return", "return="], + ["Error_monad.__return", "return=?"], + ["Error_monad.ok", "return?"] + ], + "monadic_return_lets": [ + ["Error_monad.op_gtgtquestioneq", "return=", "let=?"] + ], + "operator_infix": [ + ["Compare.Int.(Compare.S.op_eq)", "=i"], + ["Compare.Int.(Compare.S.op_ltgt)", "<>i"], + ["Compare.Int.(Compare.S.op_lteq)", "<=i"], + ["Compare.Int.(Compare.S.op_lt)", "=i"], + ["Compare.Int.(Compare.S.op_gt)", ">i"], + + ["Compare.Int32.(Compare.S.op_eq)", "=i32"], + ["Compare.Int32.(Compare.S.op_ltgt)", "<>i32"], + ["Compare.Int32.(Compare.S.op_lteq)", "<=i32"], + ["Compare.Int32.(Compare.S.op_lt)", "=i32"], + ["Compare.Int32.(Compare.S.op_gt)", ">i32"], + + ["Compare.Int64.(Compare.S.op_eq)", "=i64"], + ["Compare.Int64.(Compare.S.op_ltgt)", "<>i64"], + ["Compare.Int64.(Compare.S.op_lteq)", "<=i64"], + ["Compare.Int64.(Compare.S.op_lt)", "=i64"], + ["Compare.Int64.(Compare.S.op_gt)", ">i64"], + + ["Compare.Z.(Compare.S.op_eq)", "=Z"], + ["Compare.Z.(Compare.S.op_ltgt)", "<>Z"], + ["Compare.Z.(Compare.S.op_lteq)", "<=Z"], + ["Compare.Z.(Compare.S.op_lt)", "=Z"], + ["Compare.Z.(Compare.S.op_gt)", ">Z"], + + ["Int32.add", "+i32"], + ["Int32.sub", "-i32"], + ["Int32.mul", "*i32"], + ["Int32.div", "/i32"], + + ["Int64.add", "+i64"], + ["Int64.sub", "-i64"], + ["Int64.mul", "*i64"], + ["Int64.div", "/i64"], + + ["Pervasives.op_andand", "&&"], + ["Pervasives.op_pipepipe", "||"], + + ["Pervasives.op_plus", "+i"], + ["Pervasives.op_minus", "-i"], + ["Pervasives.op_star", "*i"], + ["Pervasives.op_div", "/i"], + + ["Z.add", "+Z"], + ["Z.sub", "-Z"], + ["Z.mul", "*Z"], + ["Z.div", "/Z"], + + ["Z_syntax.op_plus", "+Z"], + ["Z_syntax.op_star", "*Z"] + ], + "renaming_rules": [ + ["Error_monad.tzresult", "M?"], + ["Lwt.t", "M="], + ["Failure", "Failure"] + ], + "renaming_type_constructor": [ + ["Compare.Char.(Compare.S.t)", "ascii"], + ["Compare.Int.(Compare.S.t)", "int"], + ["Compare.Int32.(Compare.S.t)", "int32"], + ["Compare.Int64.(Compare.S.t)", "int64"], + ["Compare.String.(Compare.S.t)", "string"], + ["Compare.Z.(Compare.S.t)", "Z.t"] + ], + "require": [ + ["Tezos_raw_protocol_012_PsiThaCa", "TezosOfOCaml.Proto_alpha"] + ], + "require_import": [ + ["Tezos_protocol_environment_alpha", "TezosOfOCaml.Proto_alpha"] + ], + "require_long_ident": [ + ["Storage_description", "TezosOfOCaml.Proto_alpha"] + ], + "require_mli": [ + ], + "variant_constructors": [ + ["Dir", "Context.Dir"], + ["Key", "Context.Key"], + ["Uint16", "Data_encoding.Uint16"], + ["Uint8", "Data_encoding.Uint8"], + ["Hex", "Hex.Hex"], + ["Branch", "Error_monad.Branch"], + ["Permanent", "Error_monad.Permanent"], + ["Temporary", "Error_monad.Temporary"] + ], + "variant_types": [ + ["Dir", "Context.key_or_dir"], + ["Key", "Context.key_or_dir"] + ], + "without_guard_checking": [ + "apply.ml", + "apply_results.ml", + "baking.ml", + "contract_repr.ml", + "delegate_services.ml", + "fixed_point_repr.ml", + "helpers_services.ml", + "lazy_storage_kind.ml", + "legacy_script_support_repr.ml", + "level_storage.ml", + "michelson_v1_gas.ml", + "michelson_v1_primitives.ml", + "misc.ml", + "operation_repr.ml", + "raw_context.ml", + "roll_storage.ml", + "sapling_storage.ml", + "script_interpreter.ml", + "script_ir_annot.ml", + "script_ir_translator.ml", + "script_repr.ml", + "seed_repr.ml", + "storage_description.ml", + "storage_functors.ml", + "tez_repr.ml" + ], + "without_positivity_checking": [ + "misc.ml", + "storage_description.ml" + ] +} diff --git a/src/proto_012_PsiThaCa/lib_protocol/cycle_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/cycle_repr.ml new file mode 100644 index 000000000000..b1a4b8bc6e0b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/cycle_repr.ml @@ -0,0 +1,85 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = int32 + +type cycle = t + +let encoding = Data_encoding.int32 + +let rpc_arg = RPC_arg.like RPC_arg.uint31 ~descr:"A cycle integer" "block_cycle" + +let pp ppf cycle = Format.fprintf ppf "%ld" cycle + +include (Compare.Int32 : Compare.S with type t := t) + +module Map = Map.Make (Compare.Int32) + +let root = 0l + +let succ = Int32.succ + +let pred = function 0l -> None | i -> Some (Int32.pred i) + +let add c i = + assert (Compare.Int.(i >= 0)) ; + Int32.add c (Int32.of_int i) + +let sub c i = + assert (Compare.Int.(i >= 0)) ; + let r = Int32.sub c (Int32.of_int i) in + if Compare.Int32.(r < 0l) then None else Some r + +let diff = Int32.sub + +let to_int32 i = i + +let of_int32_exn l = + if Compare.Int32.(l >= 0l) then l else invalid_arg "Cycle_repr.of_int32_exn" + +let of_string_exn s = + let int32_opt = Int32.of_string_opt s in + match int32_opt with + | None -> invalid_arg "Cycle_repr.of_string_exn" + | Some int32 -> of_int32_exn int32 + +let ( ---> ) = Misc.( ---> ) + +module Index = struct + type t = cycle + + let path_length = 1 + + let to_path c l = Int32.to_string (to_int32 c) :: l + + let of_path = function [s] -> Int32.of_string_opt s | _ -> None + + let rpc_arg = rpc_arg + + let encoding = encoding + + let compare = compare +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/cycle_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/cycle_repr.mli new file mode 100644 index 000000000000..bfd7a7b66db3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/cycle_repr.mli @@ -0,0 +1,61 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t + +type cycle = t + +include Compare.S with type t := t + +val encoding : cycle Data_encoding.t + +val rpc_arg : cycle RPC_arg.arg + +val pp : Format.formatter -> cycle -> unit + +val root : cycle + +val pred : cycle -> cycle option + +val add : cycle -> int -> cycle + +val sub : cycle -> int -> cycle option + +val succ : cycle -> cycle + +val diff : cycle -> cycle -> int32 + +(** a ---> b = [a; ...; b] *) +val ( ---> ) : cycle -> cycle -> cycle list + +val to_int32 : cycle -> int32 + +val of_int32_exn : int32 -> cycle + +val of_string_exn : string -> cycle + +module Map : Map.S with type key = cycle + +module Index : Storage_description.INDEX with type t = cycle diff --git a/src/proto_012_PsiThaCa/lib_protocol/delegate_activation_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/delegate_activation_storage.ml new file mode 100644 index 000000000000..2d090108f20b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/delegate_activation_storage.ml @@ -0,0 +1,87 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let is_inactive ctxt delegate = + Storage.Contract.Inactive_delegate.mem + ctxt + (Contract_repr.implicit_contract delegate) + >>= fun inactive -> + if inactive then return inactive + else + Storage.Contract.Delegate_desactivation.find + ctxt + (Contract_repr.implicit_contract delegate) + >|=? function + | Some last_active_cycle -> + let ({Level_repr.cycle = current_cycle; _} : Level_repr.t) = + Raw_context.current_level ctxt + in + Cycle_repr.(last_active_cycle < current_cycle) + | None -> + (* This case is only when called from `set_active`, when creating + a contract. *) + false + +let grace_period ctxt delegate = + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Delegate_desactivation.get ctxt contract + +let set_inactive = Storage.Contract.Inactive_delegate.add + +let set_active ctxt delegate = + is_inactive ctxt delegate >>=? fun inactive -> + let current_cycle = (Raw_context.current_level ctxt).cycle in + let preserved_cycles = Constants_storage.preserved_cycles ctxt in + (* We allow a number of cycles before a delegate is deactivated as follows: + - if the delegate is active, we give it at least `1 + preserved_cycles` + after the current cycle before to be deactivated. + - if the delegate is new or inactive, we give it additionally + `preserved_cycles` because the delegate needs this number of cycles to + receive rights, so `1 + 2 * preserved_cycles` in total. *) + Storage.Contract.Delegate_desactivation.find + ctxt + (Contract_repr.implicit_contract delegate) + >>=? fun current_last_active_cycle -> + let last_active_cycle = + match current_last_active_cycle with + | None -> Cycle_repr.add current_cycle (1 + (2 * preserved_cycles)) + | Some current_last_active_cycle -> + let delay = + if inactive then 1 + (2 * preserved_cycles) else 1 + preserved_cycles + in + let updated = Cycle_repr.add current_cycle delay in + Cycle_repr.max current_last_active_cycle updated + in + Storage.Contract.Delegate_desactivation.add + ctxt + (Contract_repr.implicit_contract delegate) + last_active_cycle + >>= fun ctxt -> + if not inactive then return (ctxt, inactive) + else + Storage.Contract.Inactive_delegate.remove + ctxt + (Contract_repr.implicit_contract delegate) + >>= fun ctxt -> return (ctxt, inactive) diff --git a/src/proto_012_PsiThaCa/lib_protocol/delegate_activation_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/delegate_activation_storage.mli new file mode 100644 index 000000000000..e18ca676079e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/delegate_activation_storage.mli @@ -0,0 +1,39 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val is_inactive : + Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t + +(** [grace_period ctxt delegate] is the cycle at which the delegate is + scheduled to become inactive. *) +val grace_period : + Raw_context.t -> Signature.Public_key_hash.t -> Cycle_repr.t tzresult Lwt.t + +val set_inactive : Raw_context.t -> Contract_repr.t -> Raw_context.t Lwt.t + +val set_active : + Raw_context.t -> + Signature.Public_key_hash.t -> + (Raw_context.t * bool) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/delegate_services.ml b/src/proto_012_PsiThaCa/lib_protocol/delegate_services.ml new file mode 100644 index 000000000000..1595f62f5802 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/delegate_services.ml @@ -0,0 +1,418 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +type error += Balance_rpc_non_delegate of public_key_hash + +let () = + register_error_kind + `Temporary + ~id:"delegate_service.balance_rpc_on_non_delegate" + ~title:"Balance request for an unregistered delegate" + ~description:"The account whose balance was requested is not a delegate." + ~pp:(fun ppf pkh -> + Format.fprintf + ppf + "The implicit account (%a) whose balance was requested is not a \ + registered delegate. To get the balance of this account you can use \ + the ../context/contracts/%a/balance RPC." + Signature.Public_key_hash.pp + pkh + Signature.Public_key_hash.pp + pkh) + Data_encoding.(obj1 (req "pkh" Signature.Public_key_hash.encoding)) + (function Balance_rpc_non_delegate pkh -> Some pkh | _ -> None) + (fun pkh -> Balance_rpc_non_delegate pkh) + +type info = { + full_balance : Tez.t; + current_frozen_deposits : Tez.t; + frozen_deposits : Tez.t; + staking_balance : Tez.t; + frozen_deposits_limit : Tez.t option; + delegated_contracts : Contract.t list; + delegated_balance : Tez.t; + deactivated : bool; + grace_period : Cycle.t; + voting_power : int32; +} + +let info_encoding = + let open Data_encoding in + conv + (fun { + full_balance; + current_frozen_deposits; + frozen_deposits; + staking_balance; + frozen_deposits_limit; + delegated_contracts; + delegated_balance; + deactivated; + grace_period; + voting_power; + } -> + ( full_balance, + current_frozen_deposits, + frozen_deposits, + staking_balance, + frozen_deposits_limit, + delegated_contracts, + delegated_balance, + deactivated, + grace_period, + voting_power )) + (fun ( full_balance, + current_frozen_deposits, + frozen_deposits, + staking_balance, + frozen_deposits_limit, + delegated_contracts, + delegated_balance, + deactivated, + grace_period, + voting_power ) -> + { + full_balance; + current_frozen_deposits; + frozen_deposits; + staking_balance; + frozen_deposits_limit; + delegated_contracts; + delegated_balance; + deactivated; + grace_period; + voting_power; + }) + (obj10 + (req "full_balance" Tez.encoding) + (req "current_frozen_deposits" Tez.encoding) + (req "frozen_deposits" Tez.encoding) + (req "staking_balance" Tez.encoding) + (opt "frozen_deposits_limit" Tez.encoding) + (req "delegated_contracts" (list Contract.encoding)) + (req "delegated_balance" Tez.encoding) + (req "deactivated" bool) + (req "grace_period" Cycle.encoding) + (req "voting_power" int32)) + +let participation_info_encoding = + let open Data_encoding in + conv + (fun { + Delegate.expected_cycle_activity; + minimal_cycle_activity; + missed_slots; + missed_levels; + remaining_allowed_missed_slots; + expected_endorsing_rewards; + } -> + ( expected_cycle_activity, + minimal_cycle_activity, + missed_slots, + missed_levels, + remaining_allowed_missed_slots, + expected_endorsing_rewards )) + (fun ( expected_cycle_activity, + minimal_cycle_activity, + missed_slots, + missed_levels, + remaining_allowed_missed_slots, + expected_endorsing_rewards ) -> + { + expected_cycle_activity; + minimal_cycle_activity; + missed_slots; + missed_levels; + remaining_allowed_missed_slots; + expected_endorsing_rewards; + }) + (obj6 + (req "expected_cycle_activity" int31) + (req "minimal_cycle_activity" int31) + (req "missed_slots" int31) + (req "missed_levels" int31) + (req "remaining_allowed_missed_slots" int31) + (req "expected_endorsing_rewards" Tez.encoding)) + +module S = struct + let raw_path = RPC_path.(open_root / "context" / "delegates") + + open Data_encoding + + type list_query = {active : bool; inactive : bool} + + let list_query : list_query RPC_query.t = + let open RPC_query in + query (fun active inactive -> {active; inactive}) + |+ flag "active" (fun t -> t.active) + |+ flag "inactive" (fun t -> t.inactive) + |> seal + + let list_delegate = + RPC_service.get_service + ~description:"Lists all registered delegates." + ~query:list_query + ~output:(list Signature.Public_key_hash.encoding) + raw_path + + let path = RPC_path.(raw_path /: Signature.Public_key_hash.rpc_arg) + + let info = + RPC_service.get_service + ~description:"Everything about a delegate." + ~query:RPC_query.empty + ~output:info_encoding + path + + let full_balance = + RPC_service.get_service + ~description: + "Returns the full balance (in mutez) of a given delegate, including \ + the frozen deposits. It does not include its delegated balance." + ~query:RPC_query.empty + ~output:Tez.encoding + RPC_path.(path / "full_balance") + + let current_frozen_deposits = + RPC_service.get_service + ~description: + "Returns the current amount of the frozen deposits (in mutez)." + ~query:RPC_query.empty + ~output:Tez.encoding + RPC_path.(path / "current_frozen_deposits") + + let frozen_deposits = + RPC_service.get_service + ~description: + "Returns the initial amount (that is, at the beginning of a cycle) of \ + the frozen deposits (in mutez). This amount is the same as the \ + current amount of the frozen deposits, unless the delegate has been \ + punished." + ~query:RPC_query.empty + ~output:Tez.encoding + RPC_path.(path / "frozen_deposits") + + let staking_balance = + RPC_service.get_service + ~description: + "Returns the total amount of tokens (in mutez) delegated to a given \ + delegate. This includes the balances of all the contracts that \ + delegate to it, but also the balance of the delegate itself and its \ + frozen deposits." + ~query:RPC_query.empty + ~output:Tez.encoding + RPC_path.(path / "staking_balance") + + let frozen_deposits_limit = + RPC_service.get_service + ~description: + "Returns the frozen deposits limit for the given delegate or none if \ + no limit is set." + ~query:RPC_query.empty + ~output:(Data_encoding.option Tez.encoding) + RPC_path.(path / "frozen_deposits_limit") + + let delegated_contracts = + RPC_service.get_service + ~description: + "Returns the list of contracts that delegate to a given delegate." + ~query:RPC_query.empty + ~output:(list Contract.encoding) + RPC_path.(path / "delegated_contracts") + + let delegated_balance = + RPC_service.get_service + ~description: + "Returns the sum (in mutez) of all balances of all the contracts that \ + delegate to a given delegate. This excludes the delegate's own \ + balance and its frozen deposits." + ~query:RPC_query.empty + ~output:Tez.encoding + RPC_path.(path / "delegated_balance") + + let deactivated = + RPC_service.get_service + ~description: + "Tells whether the delegate is currently tagged as deactivated or not." + ~query:RPC_query.empty + ~output:bool + RPC_path.(path / "deactivated") + + let grace_period = + RPC_service.get_service + ~description: + "Returns the cycle by the end of which the delegate might be \ + deactivated if she fails to execute any delegate action. A \ + deactivated delegate might be reactivated (without loosing any stake) \ + by simply re-registering as a delegate. For deactivated delegates, \ + this value contains the cycle at which they were deactivated." + ~query:RPC_query.empty + ~output:Cycle.encoding + RPC_path.(path / "grace_period") + + let voting_power = + RPC_service.get_service + ~description: + "The number of rolls in the vote listings for a given delegate" + ~query:RPC_query.empty + ~output:Data_encoding.int32 + RPC_path.(path / "voting_power") + + let participation = + RPC_service.get_service + ~description: + "Returns cycle and level participation information. In particular this \ + indicates, in the field 'expected_cycle_activity', the number of \ + slots the delegate is expected to have in the cycle based on its \ + active stake. The field 'minimal_cycle_activity' indicates the \ + minimal endorsing slots in the cycle required to get endorsing \ + rewards. It is computed based on 'expected_cycle_activity. The fields \ + 'missed_slots' and 'missed_levels' indicate the number of missed \ + endorsing slots and missed levels (for endorsing) in the cycle so \ + far. 'missed_slots' indicates the number of missed endorsing slots in \ + the cycle so far. The field 'remaining_allowed_missed_slots' \ + indicates the remaining amount of endorsing slots that can be missed \ + in the cycle before forfeiting the rewards. Finally, \ + 'expected_endorsing_rewards' indicates the endorsing rewards that \ + will be distributed at the end of the cycle if activity at that point \ + will be greater than the minimal required; if the activity is already \ + known to be below the required minimum, then the rewards are zero." + ~query:RPC_query.empty + ~output:participation_info_encoding + RPC_path.(path / "participation") +end + +let register () = + let open Services_registration in + register0 ~chunked:true S.list_delegate (fun ctxt q () -> + Delegate.list ctxt >>= fun delegates -> + match q with + | {active = true; inactive = false} -> + List.filter_es + (fun pkh -> Delegate.deactivated ctxt pkh >|=? not) + delegates + | {active = false; inactive = true} -> + List.filter_es (fun pkh -> Delegate.deactivated ctxt pkh) delegates + | _ -> return delegates) ; + register1 ~chunked:false S.info (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.full_balance ctxt pkh >>=? fun full_balance -> + Delegate.frozen_deposits ctxt pkh >>=? fun frozen_deposits -> + Delegate.staking_balance ctxt pkh >>=? fun staking_balance -> + Delegate.frozen_deposits_limit ctxt pkh >>=? fun frozen_deposits_limit -> + Delegate.delegated_contracts ctxt pkh >>= fun delegated_contracts -> + Delegate.delegated_balance ctxt pkh >>=? fun delegated_balance -> + Delegate.deactivated ctxt pkh >>=? fun deactivated -> + Delegate.grace_period ctxt pkh >>=? fun grace_period -> + Vote.get_voting_power_free ctxt pkh >|=? fun voting_power -> + { + full_balance; + current_frozen_deposits = frozen_deposits.current_amount; + frozen_deposits = frozen_deposits.initial_amount; + staking_balance; + frozen_deposits_limit; + delegated_contracts; + delegated_balance; + deactivated; + grace_period; + voting_power; + }) ; + register1 ~chunked:false S.full_balance (fun ctxt pkh () () -> + trace (Balance_rpc_non_delegate pkh) (Delegate.check_delegate ctxt pkh) + >>=? fun () -> Delegate.full_balance ctxt pkh) ; + register1 ~chunked:false S.current_frozen_deposits (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.frozen_deposits ctxt pkh >>=? fun deposits -> + return deposits.current_amount) ; + register1 ~chunked:false S.frozen_deposits (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.frozen_deposits ctxt pkh >>=? fun deposits -> + return deposits.initial_amount) ; + register1 ~chunked:false S.staking_balance (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.staking_balance ctxt pkh) ; + register1 ~chunked:false S.frozen_deposits_limit (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.frozen_deposits_limit ctxt pkh) ; + register1 ~chunked:true S.delegated_contracts (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.delegated_contracts ctxt pkh >|= ok) ; + register1 ~chunked:false S.delegated_balance (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.delegated_balance ctxt pkh) ; + register1 ~chunked:false S.deactivated (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.deactivated ctxt pkh) ; + register1 ~chunked:false S.grace_period (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.grace_period ctxt pkh) ; + register1 ~chunked:false S.voting_power (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Vote.get_voting_power_free ctxt pkh) ; + register1 ~chunked:false S.participation (fun ctxt pkh () () -> + Delegate.check_delegate ctxt pkh >>=? fun () -> + Delegate.delegate_participation_info ctxt pkh) + +let list ctxt block ?(active = true) ?(inactive = false) () = + RPC_context.make_call0 S.list_delegate ctxt block {active; inactive} () + +let info ctxt block pkh = RPC_context.make_call1 S.info ctxt block pkh () () + +let full_balance ctxt block pkh = + RPC_context.make_call1 S.full_balance ctxt block pkh () () + +let current_frozen_deposits ctxt block pkh = + RPC_context.make_call1 S.current_frozen_deposits ctxt block pkh () () + +let frozen_deposits ctxt block pkh = + RPC_context.make_call1 S.frozen_deposits ctxt block pkh () () + +let staking_balance ctxt block pkh = + RPC_context.make_call1 S.staking_balance ctxt block pkh () () + +let frozen_deposits_limit ctxt block pkh = + RPC_context.make_call1 S.frozen_deposits_limit ctxt block pkh () () + +let delegated_contracts ctxt block pkh = + RPC_context.make_call1 S.delegated_contracts ctxt block pkh () () + +let delegated_balance ctxt block pkh = + RPC_context.make_call1 S.delegated_balance ctxt block pkh () () + +let deactivated ctxt block pkh = + RPC_context.make_call1 S.deactivated ctxt block pkh () () + +let grace_period ctxt block pkh = + RPC_context.make_call1 S.grace_period ctxt block pkh () () + +let voting_power ctxt block pkh = + RPC_context.make_call1 S.voting_power ctxt block pkh () () + +let participation ctxt block pkh = + RPC_context.make_call1 S.participation ctxt block pkh () () diff --git a/src/proto_012_PsiThaCa/lib_protocol/delegate_services.mli b/src/proto_012_PsiThaCa/lib_protocol/delegate_services.mli new file mode 100644 index 000000000000..ac9e3db4280d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/delegate_services.mli @@ -0,0 +1,122 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +val list : + 'a #RPC_context.simple -> + 'a -> + ?active:bool -> + ?inactive:bool -> + unit -> + Signature.Public_key_hash.t list shell_tzresult Lwt.t + +type info = { + full_balance : Tez.t; (** Balance + Frozen balance *) + current_frozen_deposits : Tez.t; + frozen_deposits : Tez.t; + staking_balance : Tez.t; + frozen_deposits_limit : Tez.t option; + delegated_contracts : Contract.t list; + delegated_balance : Tez.t; + deactivated : bool; + grace_period : Cycle.t; + voting_power : int32; +} + +val info_encoding : info Data_encoding.t + +val info : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + info shell_tzresult Lwt.t + +val full_balance : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + Tez.t shell_tzresult Lwt.t + +val current_frozen_deposits : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + Tez.t shell_tzresult Lwt.t + +val frozen_deposits : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + Tez.t shell_tzresult Lwt.t + +val staking_balance : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + Tez.t shell_tzresult Lwt.t + +val frozen_deposits_limit : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + Tez.t option shell_tzresult Lwt.t + +val delegated_contracts : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + Contract.t list shell_tzresult Lwt.t + +val delegated_balance : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + Tez.t shell_tzresult Lwt.t + +val deactivated : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + bool shell_tzresult Lwt.t + +val grace_period : + 'a #RPC_context.simple -> + 'a -> + Signature.Public_key_hash.t -> + Cycle.t shell_tzresult Lwt.t + +val voting_power : + 'a #RPC_context.simple -> 'a -> public_key_hash -> int32 shell_tzresult Lwt.t + +val participation : + 'a #RPC_context.simple -> + 'a -> + public_key_hash -> + Delegate.participation_info shell_tzresult Lwt.t + +val register : unit -> unit diff --git a/src/proto_012_PsiThaCa/lib_protocol/delegate_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/delegate_storage.ml new file mode 100644 index 000000000000..2816916d4767 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/delegate_storage.ml @@ -0,0 +1,908 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | (* `Permanent *) No_deletion of Signature.Public_key_hash.t + | (* `Temporary *) Active_delegate + | (* `Temporary *) Current_delegate + | (* `Permanent *) Empty_delegate_account of Signature.Public_key_hash.t + | (* `Permanent *) Unregistered_delegate of Signature.Public_key_hash.t + | (* `Permanent *) Unassigned_validation_slot_for_level of Level_repr.t * int + | (* `Permanent *) + Cannot_find_active_stake of { + cycle : Cycle_repr.t; + delegate : Signature.Public_key_hash.t; + } + | (* `Temporary *) Not_registered of Signature.Public_key_hash.t + +let () = + register_error_kind + `Permanent + ~id:"delegate.no_deletion" + ~title:"Forbidden delegate deletion" + ~description:"Tried to unregister a delegate" + ~pp:(fun ppf delegate -> + Format.fprintf + ppf + "Delegate deletion is forbidden (%a)" + Signature.Public_key_hash.pp + delegate) + Data_encoding.(obj1 (req "delegate" Signature.Public_key_hash.encoding)) + (function No_deletion c -> Some c | _ -> None) + (fun c -> No_deletion c) ; + register_error_kind + `Temporary + ~id:"delegate.already_active" + ~title:"Delegate already active" + ~description:"Useless delegate reactivation" + ~pp:(fun ppf () -> + Format.fprintf ppf "The delegate is still active, no need to refresh it") + Data_encoding.empty + (function Active_delegate -> Some () | _ -> None) + (fun () -> Active_delegate) ; + register_error_kind + `Temporary + ~id:"delegate.unchanged" + ~title:"Unchanged delegated" + ~description:"Contract already delegated to the given delegate" + ~pp:(fun ppf () -> + Format.fprintf + ppf + "The contract is already delegated to the same delegate") + Data_encoding.empty + (function Current_delegate -> Some () | _ -> None) + (fun () -> Current_delegate) ; + register_error_kind + `Permanent + ~id:"delegate.empty_delegate_account" + ~title:"Empty delegate account" + ~description:"Cannot register a delegate when its implicit account is empty" + ~pp:(fun ppf delegate -> + Format.fprintf + ppf + "Delegate registration is forbidden when the delegate\n\ + \ implicit account is empty (%a)" + Signature.Public_key_hash.pp + delegate) + Data_encoding.(obj1 (req "delegate" Signature.Public_key_hash.encoding)) + (function Empty_delegate_account c -> Some c | _ -> None) + (fun c -> Empty_delegate_account c) ; + (* Unregistered delegate *) + register_error_kind + `Permanent + ~id:"contract.manager.unregistered_delegate" + ~title:"Unregistered delegate" + ~description:"A contract cannot be delegated to an unregistered delegate" + ~pp:(fun ppf k -> + Format.fprintf + ppf + "The provided public key (with hash %a) is not registered as valid \ + delegate key." + Signature.Public_key_hash.pp + k) + Data_encoding.(obj1 (req "hash" Signature.Public_key_hash.encoding)) + (function Unregistered_delegate k -> Some k | _ -> None) + (fun k -> Unregistered_delegate k) ; + (* Unassigned_validation_slot_for_level *) + register_error_kind + `Permanent + ~id:"delegate.unassigned_validation_slot_for_level" + ~title:"Unassigned validation slot for level" + ~description: + "The validation slot for the given level is not assigned. Nobody payed \ + for that slot, or the level is either in the past or too far in the \ + future (further than the validatiors_selection_offset constant)" + ~pp:(fun ppf (l, slot) -> + Format.fprintf + ppf + "The validation slot %i for the level %a is not assigned. Nobody payed \ + for that slot, or the level is either in the past or too far in the \ + future (further than the validatiors_selection_offset constant)" + slot + Level_repr.pp + l) + Data_encoding.(obj2 (req "level" Level_repr.encoding) (req "slot" int31)) + (function + | Unassigned_validation_slot_for_level (l, s) -> Some (l, s) | _ -> None) + (fun (l, s) -> Unassigned_validation_slot_for_level (l, s)) ; + register_error_kind + `Permanent + ~id:"delegate.cannot_find_active_stake" + ~title:"Cannot find active stake" + ~description: + "The active stake of a delegate cannot be found for the given cycle." + ~pp:(fun ppf (cycle, delegate) -> + Format.fprintf + ppf + "The active stake of the delegate %a cannot be found for the cycle %a." + Cycle_repr.pp + cycle + Signature.Public_key_hash.pp + delegate) + Data_encoding.( + obj2 + (req "cycle" Cycle_repr.encoding) + (req "delegate" Signature.Public_key_hash.encoding)) + (function + | Cannot_find_active_stake {cycle; delegate} -> Some (cycle, delegate) + | _ -> None) + (fun (cycle, delegate) -> Cannot_find_active_stake {cycle; delegate}) ; + register_error_kind + `Temporary + ~id:"delegate.not_registered" + ~title:"Not a registered delegate" + ~description: + "The provided public key hash is not the address of a registered \ + delegate." + ~pp:(fun ppf pkh -> + Format.fprintf + ppf + "The provided public key hash (%a) is not the address of a registered \ + delegate. If you own this account and want to register it as a \ + delegate, use a delegation operation to delegate the account to \ + itself." + Signature.Public_key_hash.pp + pkh) + Data_encoding.(obj1 (req "pkh" Signature.Public_key_hash.encoding)) + (function Not_registered pkh -> Some pkh | _ -> None) + (fun pkh -> Not_registered pkh) + +let set_inactive ctxt delegate = + let delegate_contract = Contract_repr.implicit_contract delegate in + Delegate_activation_storage.set_inactive ctxt delegate_contract + >>= fun ctxt -> + Stake_storage.deactivate_only_call_from_delegate_storage ctxt delegate >|= ok + +let set_active ctxt delegate = + Delegate_activation_storage.set_active ctxt delegate + >>=? fun (ctxt, inactive) -> + if not inactive then return ctxt + else Stake_storage.activate_only_call_from_delegate_storage ctxt delegate + +let staking_balance ctxt delegate = + Contract_delegate_storage.registered ctxt delegate >>=? fun is_registered -> + if is_registered then Stake_storage.get_staking_balance ctxt delegate + else return Tez_repr.zero + +let pubkey ctxt delegate = + Contract_manager_storage.get_manager_key + ctxt + delegate + ~error:(Unregistered_delegate delegate) + +let init ctxt contract delegate = + Contract_manager_storage.is_manager_key_revealed ctxt delegate + >>=? fun known_delegate -> + error_unless known_delegate (Unregistered_delegate delegate) >>?= fun () -> + Contract_delegate_storage.registered ctxt delegate >>=? fun is_registered -> + error_unless is_registered (Unregistered_delegate delegate) >>?= fun () -> + Contract_delegate_storage.init ctxt contract delegate + +let set c contract delegate = + match delegate with + | None -> ( + match Contract_repr.is_implicit contract with + | Some pkh -> + (* check if contract is a registered delegate *) + Contract_delegate_storage.registered c pkh >>=? fun is_registered -> + if is_registered then fail (No_deletion pkh) + else Contract_delegate_storage.delete c contract + | None -> Contract_delegate_storage.delete c contract) + | Some delegate -> + Contract_manager_storage.is_manager_key_revealed c delegate + >>=? fun known_delegate -> + Contract_delegate_storage.registered c delegate + >>=? fun registered_delegate -> + let self_delegation = + match Contract_repr.is_implicit contract with + | Some pkh -> Signature.Public_key_hash.equal pkh delegate + | None -> false + in + if (not known_delegate) || not (registered_delegate || self_delegation) + then fail (Unregistered_delegate delegate) + else + (Contract_delegate_storage.find c contract >>=? function + | Some current_delegate + when Signature.Public_key_hash.equal delegate current_delegate -> + if self_delegation then + Delegate_activation_storage.is_inactive c delegate >>=? function + | true -> return_unit + | false -> fail Active_delegate + else fail Current_delegate + | None | Some _ -> return_unit) + >>=? fun () -> + (* check if contract is a registered delegate *) + (match Contract_repr.is_implicit contract with + | Some pkh -> + Contract_delegate_storage.registered c pkh >>=? fun is_registered -> + (* allow self-delegation to re-activate *) + if (not self_delegation) && is_registered then + fail (No_deletion pkh) + else return_unit + | None -> return_unit) + >>=? fun () -> + Storage.Contract.Balance.mem c contract >>= fun exists -> + error_when + (self_delegation && not exists) + (Empty_delegate_account delegate) + >>?= fun () -> + Contract_delegate_storage.set c contract delegate >>=? fun c -> + if self_delegation then + Storage.Delegates.add c delegate >>= fun c -> set_active c delegate + else return c + +let frozen_deposits_limit ctxt delegate = + Storage.Contract.Frozen_deposits_limit.find + ctxt + (Contract_repr.implicit_contract delegate) + +let set_frozen_deposits_limit ctxt delegate limit = + Storage.Contract.Frozen_deposits_limit.add_or_remove + ctxt + (Contract_repr.implicit_contract delegate) + limit + +let update_activity ctxt last_cycle = + let preserved = Constants_storage.preserved_cycles ctxt in + match Cycle_repr.sub last_cycle preserved with + | None -> return (ctxt, []) + | Some _unfrozen_cycle -> + Stake_storage.fold_on_active_delegates_with_rolls + ctxt + ~order:`Sorted + ~init:(Ok (ctxt, [])) + ~f:(fun delegate () acc -> + acc >>?= fun (ctxt, deactivated) -> + Delegate_activation_storage.grace_period ctxt delegate + >>=? fun cycle -> + if Cycle_repr.(cycle <= last_cycle) then + set_inactive ctxt delegate >|=? fun ctxt -> + (ctxt, delegate :: deactivated) + else return (ctxt, deactivated)) + >|=? fun (ctxt, deactivated) -> (ctxt, deactivated) + +let expected_slots_for_given_active_stake ctxt ~total_active_stake ~active_stake + = + let blocks_per_cycle = + Int32.to_int (Constants_storage.blocks_per_cycle ctxt) + in + let consensus_committee_size = + Constants_storage.consensus_committee_size ctxt + in + let number_of_endorsements_per_cycle = + blocks_per_cycle * consensus_committee_size + in + return + (Z.to_int + (Z.div + (Z.mul + (Z.of_int64 (Tez_repr.to_mutez active_stake)) + (Z.of_int number_of_endorsements_per_cycle)) + (Z.of_int64 (Tez_repr.to_mutez total_active_stake)))) + +let delegate_participated_enough ctxt delegate = + Storage.Contract.Missed_endorsements.find ctxt delegate >>=? function + | None -> return_true + | Some missed_endorsements -> + return Compare.Int.(missed_endorsements.remaining_slots >= 0) + +let delegate_has_revealed_nonces delegate unrevelead_nonces_set = + not (Signature.Public_key_hash.Set.mem delegate unrevelead_nonces_set) + +let distribute_endorsing_rewards ctxt last_cycle unrevealed_nonces = + let endorsing_reward_per_slot = + Constants_storage.endorsing_reward_per_slot ctxt + in + let unrevealed_nonces_set = + List.fold_left + (fun set {Storage.Seed.nonce_hash = _; delegate} -> + Signature.Public_key_hash.Set.add delegate set) + Signature.Public_key_hash.Set.empty + unrevealed_nonces + in + Stake_storage.get_total_active_stake ctxt last_cycle + >>=? fun total_active_stake -> + Stake_storage.get_selected_distribution ctxt last_cycle >>=? fun delegates -> + List.fold_left_es + (fun (ctxt, balance_updates) (delegate, active_stake) -> + let delegate_contract = Contract_repr.implicit_contract delegate in + delegate_participated_enough ctxt delegate_contract + >>=? fun sufficient_participation -> + let has_revealed_nonces = + delegate_has_revealed_nonces delegate unrevealed_nonces_set + in + expected_slots_for_given_active_stake + ctxt + ~total_active_stake + ~active_stake + >>=? fun expected_slots -> + let rewards = Tez_repr.mul_exn endorsing_reward_per_slot expected_slots in + (if sufficient_participation && has_revealed_nonces then + (* Sufficient participation: we pay the rewards *) + Token.transfer + ctxt + `Endorsing_rewards + (`Contract delegate_contract) + rewards + >|=? fun (ctxt, payed_rewards_receipts) -> + (ctxt, payed_rewards_receipts @ balance_updates) + else + (* Insufficient participation or unrevealed nonce: no rewards *) + Token.transfer + ctxt + `Endorsing_rewards + (`Lost_endorsing_rewards + (delegate, not sufficient_participation, not has_revealed_nonces)) + rewards + >|=? fun (ctxt, payed_rewards_receipts) -> + (ctxt, payed_rewards_receipts @ balance_updates)) + >>=? fun (ctxt, balance_updates) -> + Storage.Contract.Missed_endorsements.remove ctxt delegate_contract + >>= fun ctxt -> return (ctxt, balance_updates)) + (ctxt, []) + delegates + +let clear_outdated_slashed_deposits ctxt ~new_cycle = + let max_slashable_period = Constants_storage.max_slashing_period ctxt in + match Cycle_repr.(sub new_cycle max_slashable_period) with + | None -> Lwt.return ctxt + | Some outdated_cycle -> Storage.Slashed_deposits.clear (ctxt, outdated_cycle) + +(* Return a map from delegates (with active stake at some cycle + in the cycle window [from_cycle, to_cycle]) to the maximum + of the stake to be deposited for each such cycle (which is just the + [frozen_deposits_percentage] of the active stake at that cycle). Also + return the delegates that have fallen out of the sliding window. *) +let max_frozen_deposits_and_delegates_to_remove ctxt ~from_cycle ~to_cycle = + let frozen_deposits_percentage = + Constants_storage.frozen_deposits_percentage ctxt + in + let cycles = Cycle_repr.(from_cycle ---> to_cycle) in + (match Cycle_repr.pred from_cycle with + | None -> return Signature.Public_key_hash.Set.empty + | Some cleared_cycle -> ( + Stake_storage.find_selected_distribution ctxt cleared_cycle + >|=? fun cleared_cycle_delegates -> + match cleared_cycle_delegates with + | None -> Signature.Public_key_hash.Set.empty + | Some delegates -> + List.fold_left + (fun set (d, _) -> Signature.Public_key_hash.Set.add d set) + Signature.Public_key_hash.Set.empty + delegates)) + >>=? fun cleared_cycle_delegates -> + List.fold_left_es + (fun (maxima, delegates_to_remove) (cycle : Cycle_repr.t) -> + Stake_storage.get_selected_distribution ctxt cycle + >|=? fun active_stakes -> + List.fold_left + (fun (maxima, delegates_to_remove) (delegate, stake) -> + let stake_to_be_deposited = + Tez_repr.(div_exn (mul_exn stake frozen_deposits_percentage) 100) + in + let maxima = + Signature.Public_key_hash.Map.update + delegate + (function + | None -> Some stake_to_be_deposited + | Some maximum -> + Some (Tez_repr.max maximum stake_to_be_deposited)) + maxima + in + let delegates_to_remove = + Signature.Public_key_hash.Set.remove delegate delegates_to_remove + in + (maxima, delegates_to_remove)) + (maxima, delegates_to_remove) + active_stakes) + (Signature.Public_key_hash.Map.empty, cleared_cycle_delegates) + cycles + +let freeze_deposits ?(origin = Receipt_repr.Block_application) ctxt ~new_cycle + ~balance_updates = + let max_slashable_period = Constants_storage.max_slashing_period ctxt in + (* We want to be able to slash for at most [max_slashable_period] *) + (match Cycle_repr.(sub new_cycle (max_slashable_period - 1)) with + | None -> + Storage.Tenderbake.First_level.get ctxt + >>=? fun first_level_of_tenderbake -> + let cycle_eras = Raw_context.cycle_eras ctxt in + let level = Level_repr.from_raw ~cycle_eras first_level_of_tenderbake in + return level.cycle + | Some cycle -> return cycle) + >>=? fun from_cycle -> + let preserved_cycles = Constants_storage.preserved_cycles ctxt in + let to_cycle = Cycle_repr.(add new_cycle preserved_cycles) in + max_frozen_deposits_and_delegates_to_remove ctxt ~from_cycle ~to_cycle + >>=? fun (maxima, delegates_to_remove) -> + Signature.Public_key_hash.Map.fold_es + (fun delegate maximum_stake_to_be_deposited (ctxt, balance_updates) -> + (* Here we make sure to preserve the following invariant : + maximum_stake_to_be_deposited <= frozen_deposits + balance + See select_distribution_for_cycle *) + let delegate_contract = Contract_repr.implicit_contract delegate in + Frozen_deposits_storage.update_deposits_cap + ctxt + delegate_contract + maximum_stake_to_be_deposited + >>=? fun (ctxt, current_amount) -> + if Tez_repr.(current_amount > maximum_stake_to_be_deposited) then + Tez_repr.(current_amount -? maximum_stake_to_be_deposited) + >>?= fun to_reimburse -> + Token.transfer + ~origin + ctxt + (`Frozen_deposits delegate) + (`Delegate_balance delegate) + to_reimburse + >|=? fun (ctxt, bupds) -> (ctxt, bupds @ balance_updates) + else if Tez_repr.(current_amount < maximum_stake_to_be_deposited) then + Tez_repr.(maximum_stake_to_be_deposited -? current_amount) + >>?= fun desired_to_freeze -> + Storage.Contract.Balance.get ctxt delegate_contract >>=? fun balance -> + (* In case the delegate hasn't been slashed in this cycle, + the following invariant holds: + maximum_stake_to_be_deposited <= frozen_deposits + balance + See select_distribution_for_cycle + + If the delegate has been slashed during the cycle, the invariant + above doesn't necessarily hold. In this case, we freeze the max + we can for the delegate. *) + let to_freeze = Tez_repr.(min balance desired_to_freeze) in + Token.transfer + ~origin + ctxt + (`Delegate_balance delegate) + (`Frozen_deposits delegate) + to_freeze + >|=? fun (ctxt, bupds) -> (ctxt, bupds @ balance_updates) + else return (ctxt, balance_updates)) + maxima + (ctxt, balance_updates) + >>=? fun (ctxt, balance_updates) -> + (* Unfreeze deposits (that is, set them to zero) for delegates that + were previously in the relevant window (and therefore had some + frozen deposits) but are not in the new window; because that means + that such a delegate had no active stake in the relevant cycles, + and therefore it should have no frozen deposits. *) + Signature.Public_key_hash.Set.fold_es + (fun delegate (ctxt, balance_updates) -> + let delegate_contract = Contract_repr.implicit_contract delegate in + Frozen_deposits_storage.get ctxt delegate_contract + >>=? fun frozen_deposits -> + if Tez_repr.(frozen_deposits.current_amount > zero) then + Frozen_deposits_storage.update_deposits_cap + ctxt + delegate_contract + Tez_repr.zero + >>=? fun (ctxt, (_current_amount : Tez_repr.t)) -> + Token.transfer + ~origin + ctxt + (`Frozen_deposits delegate) + (`Delegate_balance delegate) + frozen_deposits.current_amount + >|=? fun (ctxt, bupds) -> (ctxt, bupds @ balance_updates) + else return (ctxt, balance_updates)) + delegates_to_remove + (ctxt, balance_updates) + +let freeze_deposits_do_not_call_except_for_migration = + freeze_deposits ~origin:Protocol_migration + +let cycle_end ctxt last_cycle unrevealed_nonces = + let new_cycle = Cycle_repr.add last_cycle 1 in + Stake_storage.select_new_distribution_at_cycle_end ctxt ~new_cycle pubkey + >>=? fun ctxt -> + clear_outdated_slashed_deposits ctxt ~new_cycle >>= fun ctxt -> + distribute_endorsing_rewards ctxt last_cycle unrevealed_nonces + >>=? fun (ctxt, balance_updates) -> + freeze_deposits ctxt ~new_cycle ~balance_updates + >>=? fun (ctxt, balance_updates) -> + Stake_storage.clear_at_cycle_end ctxt ~new_cycle >>=? fun ctxt -> + update_activity ctxt last_cycle >>=? fun (ctxt, deactivated_delagates) -> + return (ctxt, balance_updates, deactivated_delagates) + +let balance ctxt delegate = + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Balance.get ctxt contract + +let frozen_deposits ctxt delegate = + Frozen_deposits_storage.get ctxt (Contract_repr.implicit_contract delegate) + +let full_balance ctxt delegate = + frozen_deposits ctxt delegate >>=? fun frozen_deposits -> + balance ctxt delegate >>=? fun balance -> + Lwt.return Tez_repr.(frozen_deposits.current_amount +? balance) + +let deactivated = Delegate_activation_storage.is_inactive + +let delegated_balance ctxt delegate = + staking_balance ctxt delegate >>=? fun staking_balance -> + balance ctxt delegate >>=? fun balance -> + frozen_deposits ctxt delegate >>=? fun frozen_deposits -> + Tez_repr.(balance +? frozen_deposits.current_amount) + >>?= fun self_staking_balance -> + Lwt.return Tez_repr.(staking_balance -? self_staking_balance) + +let fold = Storage.Delegates.fold + +let list = Storage.Delegates.elements + +(* The fact that this succeeds iff [registered ctxt pkh] returns true is an + invariant of the [set] function. *) +let check_delegate ctxt pkh = + Storage.Delegates.mem ctxt pkh >>= function + | true -> return_unit + | false -> fail (Not_registered pkh) + +module Random = struct + (* [init_random_state] initialize a random sequence drawing state + that's unique for a given (seed, level, index) triple. Elements + from this sequence are drawn using [take_int64], updating the + state for the next draw. The initial state is the Blake2b hash of + the three randomness sources, and an offset set to zero + (indicating that zero bits of randomness have been + consumed). When drawing random elements, bits are extracted from + the state until exhaustion (256 bits), at which point the state + is rehashed and the offset reset to 0. *) + + let init_random_state seed level index = + ( Raw_hashes.blake2b + (Data_encoding.Binary.to_bytes_exn + Data_encoding.(tup3 Seed_repr.seed_encoding int32 int32) + (seed, level.Level_repr.cycle_position, Int32.of_int index)), + 0 ) + + let take_int64 bound state = + let drop_if_over = + (* This function draws random values in [0-(bound-1)] by drawing + in [0-(2^63-1)] (64-bit) and computing the value modulo + [bound]. For the application of [mod bound] to preserve + uniformity, the input space must be of the form + [0-(n*bound-1)]. We enforce this by rejecting 64-bit samples + above this limit (in which case, we draw a new 64-sample from + the sequence and try again). *) + Int64.sub Int64.max_int (Int64.rem Int64.max_int bound) + in + let rec loop (bytes, n) = + let consumed_bytes = 8 in + let state_size = Bytes.length bytes in + if Compare.Int.(n > state_size - consumed_bytes) then + loop (Raw_hashes.blake2b bytes, 0) + else + let r = Int64.abs (TzEndian.get_int64 bytes n) in + if Compare.Int64.(r >= drop_if_over) then + loop (bytes, n + consumed_bytes) + else + let v = Int64.rem r bound in + (v, (bytes, n + consumed_bytes)) + in + loop state + + let owner c (level : Level_repr.t) offset = + (* TODO: https://gitlab.com/tezos/tezos/-/issues/2084 + compute sampler at stake distribution snapshot instead of lazily. *) + let cycle = level.Level_repr.cycle in + (match Raw_context.sampler_for_cycle c cycle with + | Error `Sampler_not_set -> + Seed_storage.for_cycle c cycle >>=? fun seed -> + Stake_storage.Delegate_sampler_state.get c cycle >>=? fun state -> + let (c, seed, state) = + match Raw_context.set_sampler_for_cycle c cycle (seed, state) with + | Error `Sampler_already_set -> assert false + | Ok c -> (c, seed, state) + in + return (c, seed, state) + | Ok (seed, state) -> return (c, seed, state)) + >>=? fun (c, seed, state) -> + let sample ~int_bound ~mass_bound = + let state = init_random_state seed level offset in + let (i, state) = take_int64 (Int64.of_int int_bound) state in + let (elt, _) = take_int64 mass_bound state in + (Int64.to_int i, elt) + in + let (pk, pkh) = Sampler.sample state sample in + return (c, (pk, pkh)) +end + +(* Round robin delegate selection. This is only used for testing purposes. *) +module Round_robin = struct + let over level slot delegates = + let nth_mod n l = + match List.nth_opt l (n mod List.length l) with + | None -> assert false + | Some x -> x + in + let level_int = Int32.to_int level.Level_repr.level_position in + if Compare.Int.(level_int = 0) then + (* dummy case for level 0 *) + nth_mod 0 delegates |> nth_mod 0 |> return + else + let adjusted_level = level_int - 1 in + let n_defined_levels = List.length delegates in + if Compare.Int.(adjusted_level < n_defined_levels) then + nth_mod adjusted_level delegates |> nth_mod slot |> return + else + let delegates = + match List.rev delegates with [] -> assert false | last :: _ -> last + in + nth_mod (level_int - n_defined_levels + slot) delegates |> return +end + +let slot_owner c level slot = + match (Constants_storage.parametric c).delegate_selection with + | Random -> Random.owner c level (Slot_repr.to_int slot) + | Round_robin_over delegates -> + Round_robin.over level (Slot_repr.to_int slot) delegates >|=? fun pk -> + (c, (pk, Signature.Public_key.hash pk)) + +let baking_rights_owner c (level : Level_repr.t) ~round = + Round_repr.to_int round >>?= fun round -> + let consensus_committee_size = Constants_storage.consensus_committee_size c in + let pos = round mod consensus_committee_size in + slot_owner c level pos >>=? fun (ctxt, pk) -> + return (ctxt, Slot_repr.of_int_do_not_use_except_for_parameters pos, pk) + +let already_slashed_for_double_endorsing ctxt delegate (level : Level_repr.t) = + Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate) + >>=? function + | None -> return_false + | Some slashed -> return slashed.for_double_endorsing + +let already_slashed_for_double_baking ctxt delegate (level : Level_repr.t) = + Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate) + >>=? function + | None -> return_false + | Some slashed -> return slashed.for_double_baking + +let punish_double_endorsing ctxt delegate (level : Level_repr.t) = + let delegate_contract = Contract_repr.implicit_contract delegate in + Frozen_deposits_storage.get ctxt delegate_contract >>=? fun frozen_deposits -> + let slashing_ratio : Constants_repr.ratio = + Constants_storage.ratio_of_frozen_deposits_slashed_per_double_endorsement + ctxt + in + let punish_value = + Tez_repr.( + div_exn + (mul_exn frozen_deposits.initial_amount slashing_ratio.numerator) + slashing_ratio.denominator) + in + let amount_to_burn = + Tez_repr.(min frozen_deposits.current_amount punish_value) + in + Token.transfer + ctxt + (`Frozen_deposits delegate) + `Double_signing_punishments + amount_to_burn + >>=? fun (ctxt, balance_updates) -> + Stake_storage.remove_stake ctxt delegate amount_to_burn >>=? fun ctxt -> + Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate) + >>=? fun slashed -> + let slashed : Storage.slashed_level = + match slashed with + | None -> {for_double_endorsing = true; for_double_baking = false} + | Some slashed -> + assert (Compare.Bool.(slashed.for_double_endorsing = false)) ; + {slashed with for_double_endorsing = true} + in + Storage.Slashed_deposits.add + (ctxt, level.cycle) + (level.level, delegate) + slashed + >>= fun ctxt -> return (ctxt, amount_to_burn, balance_updates) + +let punish_double_baking ctxt delegate (level : Level_repr.t) = + let delegate_contract = Contract_repr.implicit_contract delegate in + Frozen_deposits_storage.get ctxt delegate_contract >>=? fun frozen_deposits -> + let slashing_for_one_block = + Constants_storage.double_baking_punishment ctxt + in + let amount_to_burn = + Tez_repr.(min frozen_deposits.current_amount slashing_for_one_block) + in + Token.transfer + ctxt + (`Frozen_deposits delegate) + `Double_signing_punishments + amount_to_burn + >>=? fun (ctxt, balance_updates) -> + Stake_storage.remove_stake ctxt delegate amount_to_burn >>=? fun ctxt -> + Storage.Slashed_deposits.find (ctxt, level.cycle) (level.level, delegate) + >>=? fun slashed -> + let slashed : Storage.slashed_level = + match slashed with + | None -> {for_double_endorsing = false; for_double_baking = true} + | Some slashed -> + assert (Compare.Bool.(slashed.for_double_baking = false)) ; + {slashed with for_double_baking = true} + in + Storage.Slashed_deposits.add + (ctxt, level.cycle) + (level.level, delegate) + slashed + >>= fun ctxt -> return (ctxt, amount_to_burn, balance_updates) + +type level_participation = Participated | Didn't_participate + +(* Note that the participation for the last block of a cycle is + recorded in the next cycle. *) +let record_endorsing_participation ctxt ~delegate ~participation + ~endorsing_power = + match participation with + | Participated -> set_active ctxt delegate + | Didn't_participate -> ( + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Missed_endorsements.find ctxt contract >>=? function + | Some {remaining_slots; missed_levels} -> + let remaining_slots = remaining_slots - endorsing_power in + Storage.Contract.Missed_endorsements.update + ctxt + contract + {remaining_slots; missed_levels = missed_levels + 1} + | None -> ( + let level = Level_storage.current ctxt in + Raw_context.stake_distribution_for_current_cycle ctxt + >>?= fun stake_distribution -> + match + Signature.Public_key_hash.Map.find delegate stake_distribution + with + | None -> + (* This happens when the block is the first one in a + cycle, and therefore the endorsements are for the last + block of the previous cycle, and when the delegate does + not have an active stake at the current cycle; in this + case its participation is simply ignored. *) + assert (Compare.Int32.(level.cycle_position = 0l)) ; + return ctxt + | Some active_stake -> + Stake_storage.get_total_active_stake ctxt level.cycle + >>=? fun total_active_stake -> + expected_slots_for_given_active_stake + ctxt + ~total_active_stake + ~active_stake + >>=? fun expected_slots -> + let Constants_repr.{numerator; denominator} = + Constants_storage.minimal_participation_ratio ctxt + in + let minimal_activity = expected_slots * numerator / denominator in + let maximal_inactivity = expected_slots - minimal_activity in + let remaining_slots = maximal_inactivity - endorsing_power in + Storage.Contract.Missed_endorsements.init + ctxt + contract + {remaining_slots; missed_levels = 1})) + +let record_baking_activity_and_pay_rewards_and_fees ctxt ~payload_producer + ~block_producer ~baking_reward ~reward_bonus = + set_active ctxt payload_producer >>=? fun ctxt -> + (if not (Signature.Public_key_hash.equal payload_producer block_producer) then + set_active ctxt block_producer + else return ctxt) + >>=? fun ctxt -> + let pay_payload_producer ctxt delegate = + let contract = Contract_repr.implicit_contract delegate in + Token.balance ctxt `Block_fees >>=? fun block_fees -> + Token.transfer_n + ctxt + [(`Block_fees, block_fees); (`Baking_rewards, baking_reward)] + (`Contract contract) + in + let pay_block_producer ctxt delegate bonus = + let contract = Contract_repr.implicit_contract delegate in + Token.transfer ctxt `Baking_bonuses (`Contract contract) bonus + in + pay_payload_producer ctxt payload_producer + >>=? fun (ctxt, balance_updates_payload_producer) -> + (match reward_bonus with + | Some bonus -> pay_block_producer ctxt block_producer bonus + | None -> return (ctxt, [])) + >>=? fun (ctxt, balance_updates_block_producer) -> + return + (ctxt, balance_updates_payload_producer @ balance_updates_block_producer) + +type participation_info = { + expected_cycle_activity : int; + minimal_cycle_activity : int; + missed_slots : int; + missed_levels : int; + remaining_allowed_missed_slots : int; + expected_endorsing_rewards : Tez_repr.t; +} + +(* Inefficient, only for RPC *) +let delegate_participation_info ctxt delegate = + let level = Level_storage.current ctxt in + Stake_storage.get_selected_distribution ctxt level.cycle + >>=? fun stake_distribution -> + match + List.assoc_opt + ~equal:Signature.Public_key_hash.equal + delegate + stake_distribution + with + | None -> + (* delegate does not have an active stake at the current cycle *) + return + { + expected_cycle_activity = 0; + minimal_cycle_activity = 0; + missed_slots = 0; + missed_levels = 0; + remaining_allowed_missed_slots = 0; + expected_endorsing_rewards = Tez_repr.zero; + } + | Some active_stake -> + Stake_storage.get_total_active_stake ctxt level.cycle + >>=? fun total_active_stake -> + expected_slots_for_given_active_stake + ctxt + ~total_active_stake + ~active_stake + >>=? fun expected_cycle_activity -> + let Constants_repr.{numerator; denominator} = + Constants_storage.minimal_participation_ratio ctxt + in + let endorsing_reward_per_slot = + Constants_storage.endorsing_reward_per_slot ctxt + in + let minimal_cycle_activity = + expected_cycle_activity * numerator / denominator + in + let maximal_cycle_inactivity = + expected_cycle_activity - minimal_cycle_activity + in + let expected_endorsing_rewards = + Tez_repr.mul_exn endorsing_reward_per_slot expected_cycle_activity + in + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Missed_endorsements.find ctxt contract + >>=? fun missed_endorsements -> + let (missed_slots, missed_levels, remaining_allowed_missed_slots) = + match missed_endorsements with + | None -> (0, 0, maximal_cycle_inactivity) + | Some {remaining_slots; missed_levels} -> + ( maximal_cycle_inactivity - remaining_slots, + missed_levels, + Compare.Int.max 0 remaining_slots ) + in + let expected_endorsing_rewards = + match missed_endorsements with + | Some r when Compare.Int.(r.remaining_slots < 0) -> Tez_repr.zero + | _ -> expected_endorsing_rewards + in + return + { + expected_cycle_activity; + minimal_cycle_activity; + missed_slots; + missed_levels; + remaining_allowed_missed_slots; + expected_endorsing_rewards; + } diff --git a/src/proto_012_PsiThaCa/lib_protocol/delegate_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/delegate_storage.mli new file mode 100644 index 000000000000..c5c41bfbe13c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/delegate_storage.mli @@ -0,0 +1,242 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Allow to register a delegate when creating an account. *) +val init : + Raw_context.t -> + Contract_repr.t -> + Signature.Public_key_hash.t -> + Raw_context.t tzresult Lwt.t + +val pubkey : + Raw_context.t -> + Signature.Public_key_hash.t -> + Signature.Public_key.t tzresult Lwt.t + +(** Updating the delegate of a contract. + + When calling this function on an "implicit contract" and setting + the delegate to the contract manager registers it as a delegate. One + cannot unregister a delegate for now. The associate contract is now + 'undeletable'. *) +val set : + Raw_context.t -> + Contract_repr.t -> + Signature.Public_key_hash.t option -> + Raw_context.t tzresult Lwt.t + +val frozen_deposits_limit : + Raw_context.t -> + Signature.Public_key_hash.t -> + Tez_repr.t option tzresult Lwt.t + +val set_frozen_deposits_limit : + Raw_context.t -> + Signature.Public_key_hash.t -> + Tez_repr.t option -> + Raw_context.t Lwt.t + +type error += + | (* `Permanent *) No_deletion of Signature.Public_key_hash.t + | (* `Temporary *) Active_delegate + | (* `Temporary *) Current_delegate + | (* `Permanent *) Empty_delegate_account of Signature.Public_key_hash.t + | (* `Permanent *) Unregistered_delegate of Signature.Public_key_hash.t + | (* `Permanent *) Unassigned_validation_slot_for_level of Level_repr.t * int + | (* `Permanent *) + Cannot_find_active_stake of { + cycle : Cycle_repr.t; + delegate : Signature.Public_key_hash.t; + } + | (* `Temporary *) Not_registered of Signature.Public_key_hash.t + +(** Check that a given implicit account is a registered delegate. *) +val check_delegate : + Raw_context.t -> Signature.Public_key_hash.t -> unit tzresult Lwt.t + +(** Participation information. We denote by: + - "static" information that does not change during the cycle + - "dynamic" information that may change during the cycle *) +type participation_info = { + expected_cycle_activity : int; + (** The total expected slots to be endorsed in the cycle. (static) *) + minimal_cycle_activity : int; + (** The minimal endorsing slots in the cycle to get endorsing + rewards. (static) *) + missed_slots : int; + (** The number of missed endorsing slots in the cycle. (dynamic) *) + missed_levels : int; + (** The number of missed endorsing levels in the cycle. (dynamic) *) + remaining_allowed_missed_slots : int; + (** Remaining amount of endorsing slots that can be missed in the + cycle before forfeiting the rewards. (dynamic) *) + expected_endorsing_rewards : Tez_repr.t; + (** Endorsing rewards that will be distributed at the end of the + cycle if activity at that point will be greater than the minimal + required. If the activity is already known to be below the + required minimum, then the rewards are zero. (dynamic) *) +} + +val delegate_participation_info : + Raw_context.t -> + Signature.Public_key_hash.t -> + participation_info tzresult Lwt.t + +(** Iterate on all registered delegates. *) +val fold : + Raw_context.t -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(Signature.Public_key_hash.t -> 'a -> 'a Lwt.t) -> + 'a Lwt.t + +(** List all registered delegates. *) +val list : Raw_context.t -> Signature.Public_key_hash.t list Lwt.t + +val balance : + Raw_context.t -> Signature.public_key_hash -> Tez_repr.tez tzresult Lwt.t + +type level_participation = Participated | Didn't_participate + +(** Record the participation of a delegate as a validator. *) +val record_endorsing_participation : + Raw_context.t -> + delegate:Signature.Public_key_hash.t -> + participation:level_participation -> + endorsing_power:int -> + Raw_context.t tzresult Lwt.t + +(** Sets the payload and block producer as active. Pays the baking + reward and the fees to the payload producer and the reward bonus to + the payload producer (if the reward_bonus is not None).*) +val record_baking_activity_and_pay_rewards_and_fees : + Raw_context.t -> + payload_producer:Signature.Public_key_hash.t -> + block_producer:Signature.Public_key_hash.t -> + baking_reward:Tez_repr.t -> + reward_bonus:Tez_repr.t option -> + (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t + +(** Trigger the context maintenance at the end of cycle 'n', i.e.: + unfreeze the endorsing rewards, potentially deactivate delegates. + Return the corresponding balances updates and the list of + deactivated delegates. *) +val cycle_end : + Raw_context.t -> + Cycle_repr.t -> + Storage.Seed.unrevealed_nonce list -> + (Raw_context.t + * Receipt_repr.balance_updates + * Signature.Public_key_hash.t list) + tzresult + Lwt.t + +(** Returns true if the given delegate has already been slashed + for double baking for the given level. *) +val already_slashed_for_double_baking : + Raw_context.t -> + Signature.Public_key_hash.t -> + Level_repr.t -> + bool tzresult Lwt.t + +(** Returns true if the given delegate has already been slashed + for double preendorsing or double endorsing for the given level. *) +val already_slashed_for_double_endorsing : + Raw_context.t -> + Signature.Public_key_hash.t -> + Level_repr.t -> + bool tzresult Lwt.t + +(** Burn some frozen deposit for a delegate at a given level. Returns + the burned amount. *) +val punish_double_endorsing : + Raw_context.t -> + Signature.Public_key_hash.t -> + Level_repr.t -> + (Raw_context.t * Tez_repr.t * Receipt_repr.balance_updates) tzresult Lwt.t + +val punish_double_baking : + Raw_context.t -> + Signature.Public_key_hash.t -> + Level_repr.t -> + (Raw_context.t * Tez_repr.t * Receipt_repr.balance_updates) tzresult Lwt.t + +(** Returns a delegate's frozen deposits, both the current amount and + the initial freezed amount. + + A delegate's frozen balance is only composed of frozen deposits; + rewards and fees are not frozen, but simply credited at the right + moment. *) +val frozen_deposits : + Raw_context.t -> + Signature.Public_key_hash.t -> + Storage.deposits tzresult Lwt.t + +(** Returns the full 'balance' of the implicit contract associated to + a given key, i.e. the sum of the spendable balance and of the + frozen balance. + + Only use this function for RPCs: this is expensive. *) +val full_balance : + Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t + +val staking_balance : + Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t + +(** Only use this function for RPCs: this is expensive. *) +val delegated_balance : + Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t + +val deactivated : + Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t + +(** Participation slots potentially associated to accounts. The + accounts that didn't place a deposit will be excluded from this + list. This function should only be used to compute the deposits to + freeze or initialize the protocol while stitching. RPCs can use this + function to predict an approximation of long term future slot + allocations. It shouldn't be used in the baker. *) +val slot_owner : + Raw_context.t -> + Level_repr.t -> + Slot_repr.t -> + (Raw_context.t * (Signature.Public_key.t * Signature.Public_key_hash.t)) + tzresult + Lwt.t + +val baking_rights_owner : + Raw_context.t -> + Level_repr.t -> + round:Round_repr.round -> + (Raw_context.t * int * (Signature.public_key * Signature.public_key_hash)) + tzresult + Lwt.t + +val freeze_deposits_do_not_call_except_for_migration : + Raw_context.t -> + new_cycle:Cycle_repr.t -> + balance_updates:Receipt_repr.balance_updates -> + (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/dune b/src/proto_012_PsiThaCa/lib_protocol/dune new file mode 120000 index 000000000000..8b081aeedbd3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/dune @@ -0,0 +1 @@ +../../lib_protocol_compiler/dune_protocol.v1 \ No newline at end of file diff --git a/src/proto_012_PsiThaCa/lib_protocol/dune-project b/src/proto_012_PsiThaCa/lib_protocol/dune-project new file mode 100644 index 000000000000..df7b10d91d08 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-embedded-protocol-012-PsiThaCa) diff --git a/src/proto_012_PsiThaCa/lib_protocol/dune.inc b/src/proto_012_PsiThaCa/lib_protocol/dune.inc new file mode 100644 index 000000000000..fbd579bff2be --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/dune.inc @@ -0,0 +1,708 @@ + + +; +; /!\ /!\ Do not modify this file /!\ /!\ +; +; but the original template in `tezos-protocol-compiler` +; + +; generated from src/lib_protocol_compiler/dune_protocol.template.v1 + +; This template is intended for protocols written after the Tezos +; project start using OCaml 4.12. +; +; template.v1 was introduced when we bumped the version of our OCaml +; dependency to 4.12. This change to a newer OCaml version introduced +; new warnings that need to be ignored in the protocols written before +; the update (see dune_protocol.template.v0). + +(rule + (targets environment.ml) + (action + (write-file %{targets} + "module Name = struct let name = \"012-PsiThaCa\" end +include Tezos_protocol_environment.MakeV4(Name)() +module CamlinternalFormatBasics = struct include CamlinternalFormatBasics end +"))) + +(rule + (targets registerer.ml) + (deps + misc.mli misc.ml + non_empty_string.mli non_empty_string.ml + path_encoding.mli path_encoding.ml + storage_description.mli storage_description.ml + state_hash.mli state_hash.ml + nonce_hash.mli nonce_hash.ml + script_expr_hash.mli script_expr_hash.ml + contract_hash.mli contract_hash.ml + blinded_public_key_hash.mli blinded_public_key_hash.ml + block_payload_hash.mli block_payload_hash.ml + slot_repr.mli slot_repr.ml + tez_repr.mli tez_repr.ml + period_repr.mli period_repr.ml + time_repr.mli time_repr.ml + round_repr.mli round_repr.ml + block_payload_repr.mli block_payload_repr.ml + fixed_point_repr.mli fixed_point_repr.ml + saturation_repr.mli saturation_repr.ml + gas_limit_repr.mli gas_limit_repr.ml + constants_repr.mli constants_repr.ml + raw_level_repr.mli raw_level_repr.ml + fitness_repr.mli fitness_repr.ml + cycle_repr.mli cycle_repr.ml + level_repr.mli level_repr.ml + seed_repr.mli seed_repr.ml + sampler.mli sampler.ml + voting_period_repr.mli voting_period_repr.ml + script_string_repr.mli script_string_repr.ml + script_int_repr.mli script_int_repr.ml + script_timestamp_repr.mli script_timestamp_repr.ml + michelson_v1_primitives.mli michelson_v1_primitives.ml + script_repr.mli script_repr.ml + cache_memory_helpers.ml + contract_repr.mli contract_repr.ml + roll_repr_legacy.mli roll_repr_legacy.ml + vote_repr.mli vote_repr.ml + block_header_repr.mli block_header_repr.ml + operation_repr.mli operation_repr.ml + manager_repr.mli manager_repr.ml + commitment_repr.mli commitment_repr.ml + parameters_repr.mli parameters_repr.ml + sapling_repr.ml + lazy_storage_kind.mli lazy_storage_kind.ml + receipt_repr.mli receipt_repr.ml + migration_repr.mli migration_repr.ml + raw_context_intf.ml + raw_context.mli raw_context.ml + storage_costs.mli storage_costs.ml + storage_sigs.ml + storage_functors.mli storage_functors.ml + storage.mli storage.ml + cache_repr.mli cache_repr.ml + constants_storage.mli constants_storage.ml + level_storage.mli level_storage.ml + nonce_storage.mli nonce_storage.ml + seed_storage.mli seed_storage.ml + roll_storage_legacy.mli roll_storage_legacy.ml + contract_manager_storage.mli contract_manager_storage.ml + delegate_activation_storage.mli delegate_activation_storage.ml + frozen_deposits_storage.mli frozen_deposits_storage.ml + stake_storage.mli stake_storage.ml + contract_delegate_storage.mli contract_delegate_storage.ml + sapling_storage.ml + lazy_storage_diff.mli lazy_storage_diff.ml + contract_storage.mli contract_storage.ml + commitment_storage.mli commitment_storage.ml + token.mli token.ml + delegate_storage.mli delegate_storage.ml + bootstrap_storage.mli bootstrap_storage.ml + voting_period_storage.mli voting_period_storage.ml + vote_storage.mli vote_storage.ml + fees_storage.mli fees_storage.ml + ticket_storage.mli ticket_storage.ml + liquidity_baking_repr.mli liquidity_baking_repr.ml + liquidity_baking_cpmm.ml + liquidity_baking_lqt.ml + liquidity_baking_migration.mli liquidity_baking_migration.ml + init_storage.mli init_storage.ml + sapling_validator.ml + global_constants_costs.mli global_constants_costs.ml + global_constants_storage.mli global_constants_storage.ml + alpha_context.mli alpha_context.ml + local_gas_counter.ml + gas_monad.mli gas_monad.ml + script_tc_errors.ml + script_ir_annot.mli script_ir_annot.ml + script_typed_ir.mli script_typed_ir.ml + script_typed_ir_size.mli script_typed_ir_size.ml + script_typed_ir_size_costs.mli script_typed_ir_size_costs.ml + michelson_v1_gas.mli michelson_v1_gas.ml + script_list.mli script_list.ml + script_comparable.mli script_comparable.ml + script_set.mli script_set.ml + script_map.mli script_map.ml + script_ir_translator.mli script_ir_translator.ml + script_cache.mli script_cache.ml + script_tc_errors_registration.mli script_tc_errors_registration.ml + ticket_costs.mli ticket_costs.ml + ticket_scanner.mli ticket_scanner.ml + ticket_balance_key.mli ticket_balance_key.ml + script_interpreter_defs.ml + script_interpreter.mli script_interpreter.ml + baking.mli baking.ml + amendment.mli amendment.ml + apply_results.mli apply_results.ml + apply.mli apply.ml + services_registration.mli services_registration.ml + constants_services.mli constants_services.ml + sapling_services.ml + contract_services.mli contract_services.ml + delegate_services.mli delegate_services.ml + voting_services.mli voting_services.ml + alpha_services.mli alpha_services.ml + main.mli main.ml + (:src_dir TEZOS_PROTOCOL)) + (action + (with-stdout-to %{targets} + (chdir %{workspace_root} (run %{bin:tezos-embedded-protocol-packer} "%{src_dir}" "012_PsiThaCa"))))) + +(rule + (targets functor.ml) + (deps + misc.mli misc.ml + non_empty_string.mli non_empty_string.ml + path_encoding.mli path_encoding.ml + storage_description.mli storage_description.ml + state_hash.mli state_hash.ml + nonce_hash.mli nonce_hash.ml + script_expr_hash.mli script_expr_hash.ml + contract_hash.mli contract_hash.ml + blinded_public_key_hash.mli blinded_public_key_hash.ml + block_payload_hash.mli block_payload_hash.ml + slot_repr.mli slot_repr.ml + tez_repr.mli tez_repr.ml + period_repr.mli period_repr.ml + time_repr.mli time_repr.ml + round_repr.mli round_repr.ml + block_payload_repr.mli block_payload_repr.ml + fixed_point_repr.mli fixed_point_repr.ml + saturation_repr.mli saturation_repr.ml + gas_limit_repr.mli gas_limit_repr.ml + constants_repr.mli constants_repr.ml + raw_level_repr.mli raw_level_repr.ml + fitness_repr.mli fitness_repr.ml + cycle_repr.mli cycle_repr.ml + level_repr.mli level_repr.ml + seed_repr.mli seed_repr.ml + sampler.mli sampler.ml + voting_period_repr.mli voting_period_repr.ml + script_string_repr.mli script_string_repr.ml + script_int_repr.mli script_int_repr.ml + script_timestamp_repr.mli script_timestamp_repr.ml + michelson_v1_primitives.mli michelson_v1_primitives.ml + script_repr.mli script_repr.ml + cache_memory_helpers.ml + contract_repr.mli contract_repr.ml + roll_repr_legacy.mli roll_repr_legacy.ml + vote_repr.mli vote_repr.ml + block_header_repr.mli block_header_repr.ml + operation_repr.mli operation_repr.ml + manager_repr.mli manager_repr.ml + commitment_repr.mli commitment_repr.ml + parameters_repr.mli parameters_repr.ml + sapling_repr.ml + lazy_storage_kind.mli lazy_storage_kind.ml + receipt_repr.mli receipt_repr.ml + migration_repr.mli migration_repr.ml + raw_context_intf.ml + raw_context.mli raw_context.ml + storage_costs.mli storage_costs.ml + storage_sigs.ml + storage_functors.mli storage_functors.ml + storage.mli storage.ml + cache_repr.mli cache_repr.ml + constants_storage.mli constants_storage.ml + level_storage.mli level_storage.ml + nonce_storage.mli nonce_storage.ml + seed_storage.mli seed_storage.ml + roll_storage_legacy.mli roll_storage_legacy.ml + contract_manager_storage.mli contract_manager_storage.ml + delegate_activation_storage.mli delegate_activation_storage.ml + frozen_deposits_storage.mli frozen_deposits_storage.ml + stake_storage.mli stake_storage.ml + contract_delegate_storage.mli contract_delegate_storage.ml + sapling_storage.ml + lazy_storage_diff.mli lazy_storage_diff.ml + contract_storage.mli contract_storage.ml + commitment_storage.mli commitment_storage.ml + token.mli token.ml + delegate_storage.mli delegate_storage.ml + bootstrap_storage.mli bootstrap_storage.ml + voting_period_storage.mli voting_period_storage.ml + vote_storage.mli vote_storage.ml + fees_storage.mli fees_storage.ml + ticket_storage.mli ticket_storage.ml + liquidity_baking_repr.mli liquidity_baking_repr.ml + liquidity_baking_cpmm.ml + liquidity_baking_lqt.ml + liquidity_baking_migration.mli liquidity_baking_migration.ml + init_storage.mli init_storage.ml + sapling_validator.ml + global_constants_costs.mli global_constants_costs.ml + global_constants_storage.mli global_constants_storage.ml + alpha_context.mli alpha_context.ml + local_gas_counter.ml + gas_monad.mli gas_monad.ml + script_tc_errors.ml + script_ir_annot.mli script_ir_annot.ml + script_typed_ir.mli script_typed_ir.ml + script_typed_ir_size.mli script_typed_ir_size.ml + script_typed_ir_size_costs.mli script_typed_ir_size_costs.ml + michelson_v1_gas.mli michelson_v1_gas.ml + script_list.mli script_list.ml + script_comparable.mli script_comparable.ml + script_set.mli script_set.ml + script_map.mli script_map.ml + script_ir_translator.mli script_ir_translator.ml + script_cache.mli script_cache.ml + script_tc_errors_registration.mli script_tc_errors_registration.ml + ticket_costs.mli ticket_costs.ml + ticket_scanner.mli ticket_scanner.ml + ticket_balance_key.mli ticket_balance_key.ml + script_interpreter_defs.ml + script_interpreter.mli script_interpreter.ml + baking.mli baking.ml + amendment.mli amendment.ml + apply_results.mli apply_results.ml + apply.mli apply.ml + services_registration.mli services_registration.ml + constants_services.mli constants_services.ml + sapling_services.ml + contract_services.mli contract_services.ml + delegate_services.mli delegate_services.ml + voting_services.mli voting_services.ml + alpha_services.mli alpha_services.ml + main.mli main.ml + (:src_dir TEZOS_PROTOCOL)) + (action (with-stdout-to %{targets} + (chdir %{workspace_root} + (run %{bin:tezos-protocol-compiler.tezos-protocol-packer} %{src_dir}))))) + +(rule + (targets protocol.ml) + (deps + misc.mli misc.ml + non_empty_string.mli non_empty_string.ml + path_encoding.mli path_encoding.ml + storage_description.mli storage_description.ml + state_hash.mli state_hash.ml + nonce_hash.mli nonce_hash.ml + script_expr_hash.mli script_expr_hash.ml + contract_hash.mli contract_hash.ml + blinded_public_key_hash.mli blinded_public_key_hash.ml + block_payload_hash.mli block_payload_hash.ml + slot_repr.mli slot_repr.ml + tez_repr.mli tez_repr.ml + period_repr.mli period_repr.ml + time_repr.mli time_repr.ml + round_repr.mli round_repr.ml + block_payload_repr.mli block_payload_repr.ml + fixed_point_repr.mli fixed_point_repr.ml + saturation_repr.mli saturation_repr.ml + gas_limit_repr.mli gas_limit_repr.ml + constants_repr.mli constants_repr.ml + raw_level_repr.mli raw_level_repr.ml + fitness_repr.mli fitness_repr.ml + cycle_repr.mli cycle_repr.ml + level_repr.mli level_repr.ml + seed_repr.mli seed_repr.ml + sampler.mli sampler.ml + voting_period_repr.mli voting_period_repr.ml + script_string_repr.mli script_string_repr.ml + script_int_repr.mli script_int_repr.ml + script_timestamp_repr.mli script_timestamp_repr.ml + michelson_v1_primitives.mli michelson_v1_primitives.ml + script_repr.mli script_repr.ml + cache_memory_helpers.ml + contract_repr.mli contract_repr.ml + roll_repr_legacy.mli roll_repr_legacy.ml + vote_repr.mli vote_repr.ml + block_header_repr.mli block_header_repr.ml + operation_repr.mli operation_repr.ml + manager_repr.mli manager_repr.ml + commitment_repr.mli commitment_repr.ml + parameters_repr.mli parameters_repr.ml + sapling_repr.ml + lazy_storage_kind.mli lazy_storage_kind.ml + receipt_repr.mli receipt_repr.ml + migration_repr.mli migration_repr.ml + raw_context_intf.ml + raw_context.mli raw_context.ml + storage_costs.mli storage_costs.ml + storage_sigs.ml + storage_functors.mli storage_functors.ml + storage.mli storage.ml + cache_repr.mli cache_repr.ml + constants_storage.mli constants_storage.ml + level_storage.mli level_storage.ml + nonce_storage.mli nonce_storage.ml + seed_storage.mli seed_storage.ml + roll_storage_legacy.mli roll_storage_legacy.ml + contract_manager_storage.mli contract_manager_storage.ml + delegate_activation_storage.mli delegate_activation_storage.ml + frozen_deposits_storage.mli frozen_deposits_storage.ml + stake_storage.mli stake_storage.ml + contract_delegate_storage.mli contract_delegate_storage.ml + sapling_storage.ml + lazy_storage_diff.mli lazy_storage_diff.ml + contract_storage.mli contract_storage.ml + commitment_storage.mli commitment_storage.ml + token.mli token.ml + delegate_storage.mli delegate_storage.ml + bootstrap_storage.mli bootstrap_storage.ml + voting_period_storage.mli voting_period_storage.ml + vote_storage.mli vote_storage.ml + fees_storage.mli fees_storage.ml + ticket_storage.mli ticket_storage.ml + liquidity_baking_repr.mli liquidity_baking_repr.ml + liquidity_baking_cpmm.ml + liquidity_baking_lqt.ml + liquidity_baking_migration.mli liquidity_baking_migration.ml + init_storage.mli init_storage.ml + sapling_validator.ml + global_constants_costs.mli global_constants_costs.ml + global_constants_storage.mli global_constants_storage.ml + alpha_context.mli alpha_context.ml + local_gas_counter.ml + gas_monad.mli gas_monad.ml + script_tc_errors.ml + script_ir_annot.mli script_ir_annot.ml + script_typed_ir.mli script_typed_ir.ml + script_typed_ir_size.mli script_typed_ir_size.ml + script_typed_ir_size_costs.mli script_typed_ir_size_costs.ml + michelson_v1_gas.mli michelson_v1_gas.ml + script_list.mli script_list.ml + script_comparable.mli script_comparable.ml + script_set.mli script_set.ml + script_map.mli script_map.ml + script_ir_translator.mli script_ir_translator.ml + script_cache.mli script_cache.ml + script_tc_errors_registration.mli script_tc_errors_registration.ml + ticket_costs.mli ticket_costs.ml + ticket_scanner.mli ticket_scanner.ml + ticket_balance_key.mli ticket_balance_key.ml + script_interpreter_defs.ml + script_interpreter.mli script_interpreter.ml + baking.mli baking.ml + amendment.mli amendment.ml + apply_results.mli apply_results.ml + apply.mli apply.ml + services_registration.mli services_registration.ml + constants_services.mli constants_services.ml + sapling_services.ml + contract_services.mli contract_services.ml + delegate_services.mli delegate_services.ml + voting_services.mli voting_services.ml + alpha_services.mli alpha_services.ml + main.mli main.ml) + (action + (write-file %{targets} + "module Environment = Tezos_protocol_environment_012_PsiThaCa.Environment +let hash = Tezos_crypto.Protocol_hash.of_b58check_exn \"PsiThaCaT47Zboaw71QWScM8sXeMM7bbQFncK9FLqYc6EKdpjVP\" +let name = Environment.Name.name +include Tezos_raw_protocol_012_PsiThaCa +include Tezos_raw_protocol_012_PsiThaCa.Main +"))) + +(library + (name tezos_protocol_environment_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-protocol-012-PsiThaCa.environment) + (library_flags (:standard -linkall)) + (libraries tezos-protocol-environment) + (modules Environment)) + +(library + (name tezos_raw_protocol_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-protocol-012-PsiThaCa.raw) + (libraries tezos_protocol_environment_012_PsiThaCa) + (library_flags (:standard -linkall)) + (flags (:standard -nopervasives -nostdlib + -w +a-4-40..42-44-45-48 + -warn-error +a + -open Tezos_protocol_environment_012_PsiThaCa__Environment + -open Pervasives + -open Error_monad)) + (modules + Misc + Non_empty_string + Path_encoding + Storage_description + State_hash + Nonce_hash + Script_expr_hash + Contract_hash + Blinded_public_key_hash + Block_payload_hash + Slot_repr + Tez_repr + Period_repr + Time_repr + Round_repr + Block_payload_repr + Fixed_point_repr + Saturation_repr + Gas_limit_repr + Constants_repr + Raw_level_repr + Fitness_repr + Cycle_repr + Level_repr + Seed_repr + Sampler + Voting_period_repr + Script_string_repr + Script_int_repr + Script_timestamp_repr + Michelson_v1_primitives + Script_repr + Cache_memory_helpers + Contract_repr + Roll_repr_legacy + Vote_repr + Block_header_repr + Operation_repr + Manager_repr + Commitment_repr + Parameters_repr + Sapling_repr + Lazy_storage_kind + Receipt_repr + Migration_repr + Raw_context_intf + Raw_context + Storage_costs + Storage_sigs + Storage_functors + Storage + Cache_repr + Constants_storage + Level_storage + Nonce_storage + Seed_storage + Roll_storage_legacy + Contract_manager_storage + Delegate_activation_storage + Frozen_deposits_storage + Stake_storage + Contract_delegate_storage + Sapling_storage + Lazy_storage_diff + Contract_storage + Commitment_storage + Token + Delegate_storage + Bootstrap_storage + Voting_period_storage + Vote_storage + Fees_storage + Ticket_storage + Liquidity_baking_repr + Liquidity_baking_cpmm + Liquidity_baking_lqt + Liquidity_baking_migration + Init_storage + Sapling_validator + Global_constants_costs + Global_constants_storage + Alpha_context + Local_gas_counter + Gas_monad + Script_tc_errors + Script_ir_annot + Script_typed_ir + Script_typed_ir_size + Script_typed_ir_size_costs + Michelson_v1_gas + Script_list + Script_comparable + Script_set + Script_map + Script_ir_translator + Script_cache + Script_tc_errors_registration + Ticket_costs + Ticket_scanner + Ticket_balance_key + Script_interpreter_defs + Script_interpreter + Baking + Amendment + Apply_results + Apply + Services_registration + Constants_services + Sapling_services + Contract_services + Delegate_services + Voting_services + Alpha_services + Main)) + +(install + (section lib) + (package tezos-protocol-012-PsiThaCa) + (files (TEZOS_PROTOCOL as raw/TEZOS_PROTOCOL))) + +(library + (name tezos_protocol_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-protocol-012-PsiThaCa) + (libraries + tezos-protocol-environment + tezos-protocol-environment-sigs + tezos_raw_protocol_012_PsiThaCa) + (flags -w "+a-4-40..42-44-45-48" + -warn-error "+a" + -nopervasives) + (modules Protocol)) + +(library + (name tezos_protocol_012_PsiThaCa_functor) + ; The instrumentation is removed as it can lead to a stack overflow + ; https://gitlab.com/tezos/tezos/-/issues/1927 + ; (instrumentation (backend bisect_ppx)) + (public_name tezos-protocol-functor-012-PsiThaCa) + (libraries + tezos-protocol-environment + tezos-protocol-environment-sigs + tezos-protocol-012-PsiThaCa.raw) + (flags -w "+a-4-40..42-44-45-48" + -warn-error "+a" + -nopervasives) + (modules Functor)) + +(library + (name tezos_embedded_protocol_012_PsiThaCa) + (instrumentation (backend bisect_ppx)) + (public_name tezos-embedded-protocol-012-PsiThaCa) + (library_flags (:standard -linkall)) + (libraries tezos-protocol-012-PsiThaCa + tezos-protocol-updater + tezos-protocol-environment) + (flags (:standard -w +a-4-40..42-44-45-48 + -warn-error +a)) + (modules Registerer)) + +(rule + (alias runtest_compile_protocol) + (deps + misc.mli misc.ml + non_empty_string.mli non_empty_string.ml + path_encoding.mli path_encoding.ml + storage_description.mli storage_description.ml + state_hash.mli state_hash.ml + nonce_hash.mli nonce_hash.ml + script_expr_hash.mli script_expr_hash.ml + contract_hash.mli contract_hash.ml + blinded_public_key_hash.mli blinded_public_key_hash.ml + block_payload_hash.mli block_payload_hash.ml + slot_repr.mli slot_repr.ml + tez_repr.mli tez_repr.ml + period_repr.mli period_repr.ml + time_repr.mli time_repr.ml + round_repr.mli round_repr.ml + block_payload_repr.mli block_payload_repr.ml + fixed_point_repr.mli fixed_point_repr.ml + saturation_repr.mli saturation_repr.ml + gas_limit_repr.mli gas_limit_repr.ml + constants_repr.mli constants_repr.ml + raw_level_repr.mli raw_level_repr.ml + fitness_repr.mli fitness_repr.ml + cycle_repr.mli cycle_repr.ml + level_repr.mli level_repr.ml + seed_repr.mli seed_repr.ml + sampler.mli sampler.ml + voting_period_repr.mli voting_period_repr.ml + script_string_repr.mli script_string_repr.ml + script_int_repr.mli script_int_repr.ml + script_timestamp_repr.mli script_timestamp_repr.ml + michelson_v1_primitives.mli michelson_v1_primitives.ml + script_repr.mli script_repr.ml + cache_memory_helpers.ml + contract_repr.mli contract_repr.ml + roll_repr_legacy.mli roll_repr_legacy.ml + vote_repr.mli vote_repr.ml + block_header_repr.mli block_header_repr.ml + operation_repr.mli operation_repr.ml + manager_repr.mli manager_repr.ml + commitment_repr.mli commitment_repr.ml + parameters_repr.mli parameters_repr.ml + sapling_repr.ml + lazy_storage_kind.mli lazy_storage_kind.ml + receipt_repr.mli receipt_repr.ml + migration_repr.mli migration_repr.ml + raw_context_intf.ml + raw_context.mli raw_context.ml + storage_costs.mli storage_costs.ml + storage_sigs.ml + storage_functors.mli storage_functors.ml + storage.mli storage.ml + cache_repr.mli cache_repr.ml + constants_storage.mli constants_storage.ml + level_storage.mli level_storage.ml + nonce_storage.mli nonce_storage.ml + seed_storage.mli seed_storage.ml + roll_storage_legacy.mli roll_storage_legacy.ml + contract_manager_storage.mli contract_manager_storage.ml + delegate_activation_storage.mli delegate_activation_storage.ml + frozen_deposits_storage.mli frozen_deposits_storage.ml + stake_storage.mli stake_storage.ml + contract_delegate_storage.mli contract_delegate_storage.ml + sapling_storage.ml + lazy_storage_diff.mli lazy_storage_diff.ml + contract_storage.mli contract_storage.ml + commitment_storage.mli commitment_storage.ml + token.mli token.ml + delegate_storage.mli delegate_storage.ml + bootstrap_storage.mli bootstrap_storage.ml + voting_period_storage.mli voting_period_storage.ml + vote_storage.mli vote_storage.ml + fees_storage.mli fees_storage.ml + ticket_storage.mli ticket_storage.ml + liquidity_baking_repr.mli liquidity_baking_repr.ml + liquidity_baking_cpmm.ml + liquidity_baking_lqt.ml + liquidity_baking_migration.mli liquidity_baking_migration.ml + init_storage.mli init_storage.ml + sapling_validator.ml + global_constants_costs.mli global_constants_costs.ml + global_constants_storage.mli global_constants_storage.ml + alpha_context.mli alpha_context.ml + local_gas_counter.ml + gas_monad.mli gas_monad.ml + script_tc_errors.ml + script_ir_annot.mli script_ir_annot.ml + script_typed_ir.mli script_typed_ir.ml + script_typed_ir_size.mli script_typed_ir_size.ml + script_typed_ir_size_costs.mli script_typed_ir_size_costs.ml + michelson_v1_gas.mli michelson_v1_gas.ml + script_list.mli script_list.ml + script_comparable.mli script_comparable.ml + script_set.mli script_set.ml + script_map.mli script_map.ml + script_ir_translator.mli script_ir_translator.ml + script_cache.mli script_cache.ml + script_tc_errors_registration.mli script_tc_errors_registration.ml + ticket_costs.mli ticket_costs.ml + ticket_scanner.mli ticket_scanner.ml + ticket_balance_key.mli ticket_balance_key.ml + script_interpreter_defs.ml + script_interpreter.mli script_interpreter.ml + baking.mli baking.ml + amendment.mli amendment.ml + apply_results.mli apply_results.ml + apply.mli apply.ml + services_registration.mli services_registration.ml + constants_services.mli constants_services.ml + sapling_services.ml + contract_services.mli contract_services.ml + delegate_services.mli delegate_services.ml + voting_services.mli voting_services.ml + alpha_services.mli alpha_services.ml + main.mli main.ml + (:src_dir TEZOS_PROTOCOL)) + (action (run %{bin:tezos-protocol-compiler} .))) + +(rule + (alias runtest_sandbox) + (deps .tezos_protocol_012_PsiThaCa.objs/native/tezos_protocol_012_PsiThaCa.cmx) + (action (progn))) + +(rule + (alias runtest) + (package tezos-protocol-012-PsiThaCa) + (deps (alias runtest_sandbox)) + (action (progn))) diff --git a/src/proto_012_PsiThaCa/lib_protocol/fees_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/fees_storage.ml new file mode 100644 index 000000000000..b156a09a3d1a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/fees_storage.ml @@ -0,0 +1,111 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += Cannot_pay_storage_fee (* `Temporary *) + +type error += Operation_quota_exceeded (* `Temporary *) + +type error += Storage_limit_too_high (* `Permanent *) + +let () = + let open Data_encoding in + register_error_kind + `Temporary + ~id:"contract.cannot_pay_storage_fee" + ~title:"Cannot pay storage fee" + ~description:"The storage fee is higher than the contract balance" + ~pp:(fun ppf () -> Format.fprintf ppf "Cannot pay storage storage fee") + Data_encoding.empty + (function Cannot_pay_storage_fee -> Some () | _ -> None) + (fun () -> Cannot_pay_storage_fee) ; + register_error_kind + `Temporary + ~id:"storage_exhausted.operation" + ~title:"Storage quota exceeded for the operation" + ~description: + "A script or one of its callee wrote more bytes than the operation said \ + it would" + Data_encoding.empty + (function Operation_quota_exceeded -> Some () | _ -> None) + (fun () -> Operation_quota_exceeded) ; + register_error_kind + `Permanent + ~id:"storage_limit_too_high" + ~title:"Storage limit out of protocol hard bounds" + ~description:"A transaction tried to exceed the hard limit on storage" + empty + (function Storage_limit_too_high -> Some () | _ -> None) + (fun () -> Storage_limit_too_high) + +let record_global_constant_storage_space context size = + (* Following the precedent of big_map, a key in the + global table of constants costs 65 bytes (see + [Lazy_storage_diff.Big_map.bytes_size_for_big_map_key])*) + let cost_of_key = Z.of_int 65 in + let to_be_paid = Z.add size cost_of_key in + (context, to_be_paid) + +let record_paid_storage_space c contract = + Contract_storage.used_storage_space c contract >>=? fun size -> + Contract_storage.set_paid_storage_space_and_return_fees_to_pay c contract size + >>=? fun (to_be_paid, c) -> return (c, size, to_be_paid) + +let source_must_exist c src = + match src with + | `Contract src -> Contract_storage.must_exist c src + | _ -> return_unit + +let burn_storage_fees ?(origin = Receipt_repr.Block_application) c + ~storage_limit ~payer consumed = + let remaining = Z.sub storage_limit consumed in + if Compare.Z.(remaining < Z.zero) then fail Operation_quota_exceeded + else + let cost_per_byte = Constants_storage.cost_per_byte c in + Tez_repr.(cost_per_byte *? Z.to_int64 consumed) >>?= fun to_burn -> + (* Burning the fees... *) + if Tez_repr.(to_burn = Tez_repr.zero) then + (* If the payer was deleted by transferring all its balance, and no space + was used, burning zero would fail *) + return (c, remaining, []) + else + trace + Cannot_pay_storage_fee + ( source_must_exist c payer >>=? fun () -> + Token.transfer ~origin c payer `Storage_fees to_burn + >>=? fun (ctxt, balance_updates) -> + return (ctxt, remaining, balance_updates) ) + +let burn_origination_fees ?(origin = Receipt_repr.Block_application) c + ~storage_limit ~payer = + let origination_size = Constants_storage.origination_size c in + burn_storage_fees ~origin c ~storage_limit ~payer (Z.of_int origination_size) + +let check_storage_limit c ~storage_limit = + if + Compare.Z.( + storage_limit > (Raw_context.constants c).hard_storage_limit_per_operation) + || Compare.Z.(storage_limit < Z.zero) + then error Storage_limit_too_high + else Result.return_unit diff --git a/src/proto_012_PsiThaCa/lib_protocol/fees_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/fees_storage.mli new file mode 100644 index 000000000000..fcb5ae412492 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/fees_storage.mli @@ -0,0 +1,77 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += Cannot_pay_storage_fee (* `Temporary *) + +type error += Operation_quota_exceeded (* `Temporary *) + +type error += Storage_limit_too_high (* `Permanent *) + +(** [record_global_constant_storage_space ctxt size] records + paid storage space for registering a new global constant. + Cost is in bytes + 65 additional bytes for the key + hash of the expression. Returns new context and the cost. +*) +val record_global_constant_storage_space : + Raw_context.t -> Z.t -> Raw_context.t * Z.t + +(** [record_paid_storage_space ctxt contract] updates the amount of storage + consumed by the [contract] and considered as accounted for as far as + future payment is concerned. Returns a new context, the total space + consumed by the [contract], and the additional (and unpaid) space consumed + since the last call of this function on this [contract]. *) +val record_paid_storage_space : + Raw_context.t -> Contract_repr.t -> (Raw_context.t * Z.t * Z.t) tzresult Lwt.t + +(** [check_storage_limit ctxt ~storage_limit] raises the [Storage_limit_too_high] + error iff [storage_limit] is negative or greater the constant + [hard_storage_limit_per_operation]. *) +val check_storage_limit : Raw_context.t -> storage_limit:Z.t -> unit tzresult + +(** [burn_storage_fees ctxt ~storage_limit ~payer consumed] takes funds from the + [payer] to pay the cost of the [consumed] storage. This function has an + optional parameter [~origin] that allows to set the origin of returned + balance updates (by default the parameter is set to [Block_application]). + Returns an updated context, an updated storage limit equal to + [storage_limit - consumed], and the relevant balance updates. + Raises the [Operation_quota_exceeded] error if [storage_limit < consumed]. + Raises the [Cannot_pay_storage_fee] error if the funds from the [payer] are + not sufficient to pay the storage fees. *) +val burn_storage_fees : + ?origin:Receipt_repr.update_origin -> + Raw_context.t -> + storage_limit:Z.t -> + payer:Token.source -> + Z.t -> + (Raw_context.t * Z.t * Receipt_repr.balance_updates) tzresult Lwt.t + +(** Calls [burn_storage_fees] with the parameter [consumed] mapped to the + constant [origination_size]. *) +val burn_origination_fees : + ?origin:Receipt_repr.update_origin -> + Raw_context.t -> + storage_limit:Z.t -> + payer:Token.source -> + (Raw_context.t * Z.t * Receipt_repr.balance_updates) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/fitness_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/fitness_repr.ml new file mode 100644 index 000000000000..0a1c3bd7fa8a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/fitness_repr.ml @@ -0,0 +1,289 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = { + level : Raw_level_repr.t; + locked_round : Round_repr.t option; + predecessor_round : Round_repr.t; + (* by convention, predecessor_round is 0 in case of protocol migration *) + round : Round_repr.t; +} + +let encoding = + let open Data_encoding in + def + "fitness" + (conv_with_guard + (fun {level; locked_round; predecessor_round; round} -> + (level, locked_round, predecessor_round, round)) + (fun (level, locked_round, predecessor_round, round) -> + match locked_round with + | None -> ok {level; locked_round; predecessor_round; round} + | Some locked_round_val -> + if Round_repr.(round <= locked_round_val) then + Error "Locked round must be smaller than round." + else ok {level; locked_round; predecessor_round; round}) + (obj4 + (req "level" Raw_level_repr.encoding) + (req "locked_round" (option Round_repr.encoding)) + (req "predecessor_round" Round_repr.encoding) + (req "round" Round_repr.encoding))) + +let pp ppf f = + let minus_sign = + if Round_repr.(f.predecessor_round = Round_repr.zero) then "" else "-" + in + let locked_round ppf locked_round = + match locked_round with + | None -> Format.pp_print_string ppf "unlocked" + | Some round -> Format.fprintf ppf "locked: %a" Round_repr.pp round + in + Format.fprintf + ppf + "(%a, %a, %s%a, %a)" + Raw_level_repr.pp + f.level + locked_round + f.locked_round + minus_sign + Round_repr.pp + f.predecessor_round + Round_repr.pp + f.round + +type error += + | (* `Permanent *) Invalid_fitness + | (* `Permanent *) Wrong_fitness + | (* `Permanent *) Outdated_fitness + | (* `Permanent *) + Locked_round_not_less_than_round of { + round : Round_repr.t; + locked_round : Round_repr.t; + } + +let () = + register_error_kind + `Permanent + ~id:"invalid_fitness" + ~title:"Invalid fitness" + ~description: + "Fitness representation should be exactly 4 times 4 bytes long." + ~pp:(fun ppf () -> Format.fprintf ppf "Invalid fitness") + Data_encoding.empty + (function Invalid_fitness -> Some () | _ -> None) + (fun () -> Invalid_fitness) ; + register_error_kind + `Permanent + ~id:"wrong_fitness" + ~title:"Wrong fitness" + ~description:"Wrong fitness." + ~pp:(fun ppf () -> Format.fprintf ppf "Wrong fitness.") + Data_encoding.empty + (function Wrong_fitness -> Some () | _ -> None) + (fun () -> Wrong_fitness) ; + register_error_kind + `Permanent + ~id:"outdated_fitness" + ~title:"Outdated fitness" + ~description:"Outdated fitness: referring to a previous version" + ~pp:(fun ppf () -> + Format.fprintf ppf "Outdated fitness: referring to a previous version.") + Data_encoding.empty + (function Outdated_fitness -> Some () | _ -> None) + (fun () -> Outdated_fitness) ; + register_error_kind + `Permanent + ~id:"locked_round_not_less_than_round" + ~title:"Locked round not smaller than round" + ~description:"The round is smaller than or equal to the locked round." + ~pp:(fun ppf (round, locked_round) -> + Format.fprintf + ppf + "Incorrect fitness: round %a is less than or equal to locked round %a." + Round_repr.pp + round + Round_repr.pp + locked_round) + Data_encoding.( + obj2 + (req "round" Round_repr.encoding) + (req "locked_round" Round_repr.encoding)) + (function + | Locked_round_not_less_than_round {round; locked_round} -> + Some (round, locked_round) + | _ -> None) + (fun (round, locked_round) -> + Locked_round_not_less_than_round {round; locked_round}) + +let create_without_locked_round ~level ~predecessor_round ~round = + {level; locked_round = None; predecessor_round; round} + +let create ~level ~locked_round ~predecessor_round ~round = + match locked_round with + | None -> ok {level; locked_round; predecessor_round; round} + | Some locked_round_val -> + error_when + Round_repr.(round <= locked_round_val) + (Locked_round_not_less_than_round + {round; locked_round = locked_round_val}) + >>? fun () -> ok {level; locked_round; predecessor_round; round} + +let int32_to_bytes i = + let b = Bytes.make 4 '\000' in + TzEndian.set_int32 b 0 i ; + b + +let int32_of_bytes b = + if Compare.Int.(Bytes.length b <> 4) then error Invalid_fitness + else ok (TzEndian.get_int32 b 0) + +(* Locked round is an option. And we want None to be smaller than any other + value. The way the shell handles the order makes the empty Bytes smaller + than any other *) +let locked_round_to_bytes = function + | None -> Bytes.empty + | Some locked_round -> int32_to_bytes (Round_repr.to_int32 locked_round) + +let locked_round_of_bytes b = + match Bytes.length b with + | 0 -> ok None + | 4 -> Round_repr.of_int32 (TzEndian.get_int32 b 0) >>? fun r -> ok (Some r) + | _ -> error Invalid_fitness + +let predecessor_round_of_bytes neg_predecessor_round = + int32_of_bytes neg_predecessor_round >>? fun neg_predecessor_round -> + Round_repr.of_int32 @@ Int32.pred (Int32.neg neg_predecessor_round) + +let round_of_bytes round = int32_of_bytes round >>? Round_repr.of_int32 + +let to_raw {level; locked_round; predecessor_round; round} = + [ + Bytes.of_string Constants_repr.fitness_version_number; + int32_to_bytes (Raw_level_repr.to_int32 level); + locked_round_to_bytes locked_round; + int32_to_bytes + (Int32.pred (Int32.neg (Round_repr.to_int32 predecessor_round))); + int32_to_bytes (Round_repr.to_int32 round); + ] + +let from_raw = function + | [version; level; locked_round; neg_predecessor_round; round] + when Compare.String.( + Bytes.to_string version = Constants_repr.fitness_version_number) -> + int32_of_bytes level >>? Raw_level_repr.of_int32 >>? fun level -> + locked_round_of_bytes locked_round >>? fun locked_round -> + predecessor_round_of_bytes neg_predecessor_round + >>? fun predecessor_round -> + round_of_bytes round >>? fun round -> + create ~level ~locked_round ~predecessor_round ~round + | [version; _] + when Compare.String.( + Bytes.to_string version < Constants_repr.fitness_version_number) -> + error Outdated_fitness + | [] (* genesis fitness *) -> error Outdated_fitness + | _ -> error Invalid_fitness + +let round_from_raw = function + | [version; _level; _locked_round; _neg_predecessor_round; round] + when Compare.String.( + Bytes.to_string version = Constants_repr.fitness_version_number) -> + round_of_bytes round + | [version; _] + when Compare.String.( + Bytes.to_string version < Constants_repr.fitness_version_number) -> + ok Round_repr.zero + | [] (* genesis fitness *) -> ok Round_repr.zero + | _ -> error Invalid_fitness + +let predecessor_round_from_raw = function + | [version; _level; _locked_round; neg_predecessor_round; _round] + when Compare.String.( + Bytes.to_string version = Constants_repr.fitness_version_number) -> + predecessor_round_of_bytes neg_predecessor_round + | [version; _] + when Compare.String.( + Bytes.to_string version < Constants_repr.fitness_version_number) -> + ok Round_repr.zero + | [] (* genesis fitness *) -> ok Round_repr.zero + | _ -> error Invalid_fitness + +let check_except_locked_round fitness ~level ~predecessor_round = + let { + level = expected_level; + locked_round = _; + predecessor_round = expected_predecessor_round; + round = _; + } = + fitness + in + let correct = + Raw_level_repr.(level = expected_level) + && Round_repr.(predecessor_round = expected_predecessor_round) + in + error_unless correct Wrong_fitness + +let check_locked_round fitness ~locked_round = + let { + level = _; + locked_round = expected_locked_round; + predecessor_round = _; + round = _; + } = + fitness + in + let correct = + match (locked_round, expected_locked_round) with + | (None, None) -> true + | (Some _, None) | (None, Some _) -> false + | (Some v, Some v') -> Round_repr.(v = v') + in + error_unless correct Wrong_fitness + +let level fitness = fitness.level + +let round fitness = fitness.round + +let locked_round fitness = fitness.locked_round + +let predecessor_round fitness = fitness.predecessor_round + +module Internal_for_tests = struct + module ListInt32Compare = Compare.List (Compare.Int32) + + let compare f ff = + let unopt l = + match l with Some l -> Round_repr.to_int32 l | None -> -1l + in + let to_list {level; locked_round; predecessor_round; round} = + Int32. + [ + Raw_level_repr.to_int32 level; + unopt locked_round; + neg (Round_repr.to_int32 predecessor_round); + Round_repr.to_int32 round; + ] + in + ListInt32Compare.compare (to_list f) (to_list ff) +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/fitness_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/fitness_repr.mli new file mode 100644 index 000000000000..7a3ebaa8afe4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/fitness_repr.mli @@ -0,0 +1,96 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | (* `Permanent *) Invalid_fitness + | (* `Permanent *) Wrong_fitness + | (* `Permanent *) Outdated_fitness + | (* `Permanent *) + Locked_round_not_less_than_round of { + round : Round_repr.t; + locked_round : Round_repr.t; + } + +type t + +val encoding : t Data_encoding.t + +val pp : Format.formatter -> t -> unit + +val create : + level:Raw_level_repr.t -> + locked_round:Round_repr.t option -> + predecessor_round:Round_repr.t -> + round:Round_repr.t -> + t tzresult + +val create_without_locked_round : + level:Raw_level_repr.t -> + predecessor_round:Round_repr.t -> + round:Round_repr.t -> + t + +val to_raw : t -> Fitness.t + +(** Returns the corresponding protocol fitness if the shell fitness has + the expected version, given by + Constants_repr.fitness_version_number. If the fitness' version is + from a previous protocol version, then it raises an "outdated + fitness" error. If the fitness version is higher then + it raises an "invalid fitness" error. *) +val from_raw : Fitness.t -> t tzresult + +(** Returns the round from a raw fitness. If the fitness is from a + previous protocol, the returned value will be Round.zero. *) +val round_from_raw : Fitness.t -> Round_repr.t tzresult + +(** Returns the predecessor round from a raw fitness. If the fitness + is from a previous protocol, the returned value will be Round.zero. *) +val predecessor_round_from_raw : Fitness.t -> Round_repr.t tzresult + +(** Validate only the part of the fitness for which information are + available during begin_application *) +val check_except_locked_round : + t -> level:Raw_level_repr.t -> predecessor_round:Round_repr.t -> unit tzresult + +(** Validate the locked_round component of the fitness, which could + not be validated during begin_application. *) +val check_locked_round : t -> locked_round:Round_repr.t option -> unit tzresult + +val level : t -> Raw_level_repr.t + +val round : t -> Round_repr.t + +val locked_round : t -> Round_repr.t option + +val predecessor_round : t -> Round_repr.t + +(**/**) + +module Internal_for_tests : sig + (** uses a lexicographic order relation for [level, locked_round, + -predecessor_round, round] *) + val compare : t -> t -> int +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/fixed_point_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/fixed_point_repr.ml new file mode 100644 index 000000000000..531fd045f453 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/fixed_point_repr.ml @@ -0,0 +1,94 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type fp_tag (* Tag for fixed point computations *) + +type integral_tag (* Tag for integral computations *) + +module type Safe = sig + type 'a t [@@coq_phantom] + + type fp = fp_tag t + + type integral = integral_tag t + + val integral_exn : Z.t -> integral + + val integral_of_int_exn : int -> integral + + val integral_to_z : integral -> Z.t + + val zero : 'a t + + val add : 'a t -> 'a t -> 'a t + + val sub : 'a t -> 'a t -> 'a t + + val ceil : fp -> integral + + val floor : fp -> integral + + val fp : 'a t -> fp + + val ( = ) : 'a t -> 'b t -> bool + + val ( <> ) : 'a t -> 'b t -> bool + + val ( < ) : 'a t -> 'b t -> bool + + val ( <= ) : 'a t -> 'b t -> bool + + val ( >= ) : 'a t -> 'b t -> bool + + val ( > ) : 'a t -> 'b t -> bool + + val compare : 'a t -> 'b t -> int + + val equal : 'a t -> 'b t -> bool + + val max : 'a t -> 'a t -> 'a t + + val min : 'a t -> 'a t -> 'a t + + val pp : Format.formatter -> 'a t -> unit + + val pp_integral : Format.formatter -> integral -> unit + + val n_fp_encoding : fp Data_encoding.t + + val n_integral_encoding : integral Data_encoding.t + + val z_fp_encoding : fp Data_encoding.t + + val z_integral_encoding : integral Data_encoding.t +end + +module type Full = sig + type 'a t [@@coq_phantom] + + include Safe with type 'a t := 'a t + + val unsafe_fp : Z.t -> fp +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/fixed_point_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/fixed_point_repr.mli new file mode 100644 index 000000000000..a9dee73a6f6e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/fixed_point_repr.mli @@ -0,0 +1,105 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module defines a standard signature for modules providing fixed-point + arithmetic. *) + +type fp_tag (* Tag for fixed point computations *) + +type integral_tag (* Tag for integral computations *) + +(** A signature for modules implementing a fixed-point arithmetic. + + Fixed-point types come in two flavours: + - integral (marked with [integral_tag]), behaving like integers; + - fp (marked with [fp_tag]), allowing for fractions. + + Such numbers represent standard arithmetic, rounding (converting fp + flavour to integral one) and comparisons (which can work across flavours). *) +module type Safe = sig + type 'a t [@@coq_phantom] + + type fp = fp_tag t + + type integral = integral_tag t + + val integral_exn : Z.t -> integral + + val integral_of_int_exn : int -> integral + + val integral_to_z : integral -> Z.t + + val zero : 'a t + + val add : 'a t -> 'a t -> 'a t + + val sub : 'a t -> 'a t -> 'a t + + val ceil : fp -> integral + + val floor : fp -> integral + + val fp : 'a t -> fp + + val ( = ) : 'a t -> 'b t -> bool + + val ( <> ) : 'a t -> 'b t -> bool + + val ( < ) : 'a t -> 'b t -> bool + + val ( <= ) : 'a t -> 'b t -> bool + + val ( >= ) : 'a t -> 'b t -> bool + + val ( > ) : 'a t -> 'b t -> bool + + val compare : 'a t -> 'b t -> int + + val equal : 'a t -> 'b t -> bool + + val max : 'a t -> 'a t -> 'a t + + val min : 'a t -> 'a t -> 'a t + + val pp : Format.formatter -> 'a t -> unit + + val pp_integral : Format.formatter -> integral -> unit + + val n_fp_encoding : fp Data_encoding.t + + val n_integral_encoding : integral Data_encoding.t + + val z_fp_encoding : fp Data_encoding.t + + val z_integral_encoding : integral Data_encoding.t +end + +module type Full = sig + type 'a t [@@coq_phantom] + + include Safe with type 'a t := 'a t + + val unsafe_fp : Z.t -> fp +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/frozen_deposits_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/frozen_deposits_storage.ml new file mode 100644 index 000000000000..26a3141df6bd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/frozen_deposits_storage.ml @@ -0,0 +1,61 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let init ctxt delegate = + Storage.Contract.Frozen_deposits.init + ctxt + (Contract_repr.implicit_contract delegate) + {initial_amount = Tez_repr.zero; current_amount = Tez_repr.zero} + +let allocated = Storage.Contract.Frozen_deposits.mem + +let get = Storage.Contract.Frozen_deposits.get + +let find = Storage.Contract.Frozen_deposits.find + +let update_balance ctxt delegate f amount = + let delegate_contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Frozen_deposits.get ctxt delegate_contract + >>=? fun frozen_deposits -> + f frozen_deposits.current_amount amount >>?= fun new_amount -> + Storage.Contract.Frozen_deposits.update + ctxt + delegate_contract + {frozen_deposits with current_amount = new_amount} + +let credit_only_call_from_token ctxt delegate amount = + update_balance ctxt delegate Tez_repr.( +? ) amount + +let spend_only_call_from_token ctxt delegate amount = + update_balance ctxt delegate Tez_repr.( -? ) amount + +let update_deposits_cap ctxt delegate_contract deposits_cap = + Storage.Contract.Frozen_deposits.get ctxt delegate_contract + >>=? fun frozen_deposits -> + Storage.Contract.Frozen_deposits.update + ctxt + delegate_contract + {frozen_deposits with initial_amount = deposits_cap} + >|=? fun ctxt -> (ctxt, frozen_deposits.current_amount) diff --git a/src/proto_012_PsiThaCa/lib_protocol/frozen_deposits_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/frozen_deposits_storage.mli new file mode 100644 index 000000000000..a990dbcf99d8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/frozen_deposits_storage.mli @@ -0,0 +1,52 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val init : + Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t + +val allocated : Raw_context.t -> Contract_repr.t -> bool Lwt.t + +val get : Raw_context.t -> Contract_repr.t -> Storage.deposits tzresult Lwt.t + +val find : + Raw_context.t -> Contract_repr.t -> Storage.deposits option tzresult Lwt.t + +val credit_only_call_from_token : + Raw_context.t -> + Signature.Public_key_hash.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t + +val spend_only_call_from_token : + Raw_context.t -> + Signature.Public_key_hash.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t + +val update_deposits_cap : + Raw_context.t -> + Contract_repr.t -> + Tez_repr.t -> + (Raw_context.t * Tez_repr.t) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/gas_limit_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/gas_limit_repr.ml new file mode 100644 index 000000000000..b613533863e7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/gas_limit_repr.ml @@ -0,0 +1,210 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let decimals = 3 + +type fp_tag + +type integral_tag + +module S = Saturation_repr + +(* 1 gas unit *) +let scaling_factor = S.mul_safe_of_int_exn 1000 + +module Arith = struct + type 'a t = S.may_saturate S.t + + type fp = fp_tag t + + type integral = integral_tag t + + let scaling_factor = scaling_factor + + let sub = S.sub + + let add = S.add + + let zero = S.zero + + let min = S.min + + let max = S.max + + let compare = S.compare + + let ( < ) = S.( < ) + + let ( <> ) = S.( <> ) + + let ( > ) = S.( > ) + + let ( <= ) = S.( <= ) + + let ( >= ) = S.( >= ) + + let ( = ) = S.( = ) + + let equal = S.equal + + let of_int_opt = S.of_int_opt + + let fatally_saturated_int i = + failwith (string_of_int i ^ " should not be saturated.") + + let fatally_saturated_z z = + failwith (Z.to_string z ^ " should not be saturated.") + + let integral_of_int_exn i = + S.( + match of_int_opt i with + | None -> fatally_saturated_int i + | Some i' -> + let r = scale_fast scaling_factor i' in + if r = saturated then fatally_saturated_int i else r) + + let integral_exn z = + match Z.to_int z with + | i -> integral_of_int_exn i + | exception Z.Overflow -> fatally_saturated_z z + + let integral_to_z (i : integral) : Z.t = S.(to_z (ediv i scaling_factor)) + + let ceil x = + let r = S.erem x scaling_factor in + if r = zero then x else add x (sub scaling_factor r) + + let floor x = sub x (S.erem x scaling_factor) + + let fp x = x + + let pp fmtr fp = + let q = S.(ediv fp scaling_factor |> to_int) in + let r = S.(erem fp scaling_factor |> to_int) in + if Compare.Int.(r = 0) then Format.fprintf fmtr "%d" q + else Format.fprintf fmtr "%d.%0*d" q decimals r + + let pp_integral = pp + + let n_fp_encoding : fp Data_encoding.t = S.n_encoding + + let z_fp_encoding : fp Data_encoding.t = S.z_encoding + + let n_integral_encoding : integral Data_encoding.t = + Data_encoding.conv integral_to_z integral_exn Data_encoding.n + + let z_integral_encoding : integral Data_encoding.t = + Data_encoding.conv integral_to_z integral_exn Data_encoding.z + + let unsafe_fp x = + match of_int_opt (Z.to_int x) with + | Some int -> int + | None -> fatally_saturated_z x + + let sub_opt = S.sub_opt +end + +type t = Unaccounted | Limited of {remaining : Arith.fp} + +type cost = S.may_saturate S.t + +let encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"Limited" + Arith.z_fp_encoding + (function Limited {remaining} -> Some remaining | _ -> None) + (fun remaining -> Limited {remaining}); + case + (Tag 1) + ~title:"Unaccounted" + (constant "unaccounted") + (function Unaccounted -> Some () | _ -> None) + (fun () -> Unaccounted); + ] + +let pp ppf = function + | Unaccounted -> Format.fprintf ppf "unaccounted" + | Limited {remaining} -> + Format.fprintf ppf "%a units remaining" Arith.pp remaining + +let cost_encoding = S.z_encoding + +let pp_cost fmt z = S.pp fmt z + +(* 2 units of gas *) +let allocation_weight = + S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 2)) |> S.mul_safe_exn + +let step_weight = scaling_factor + +(* 100 units of gas *) +let read_base_weight = + S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 100)) |> S.mul_safe_exn + +(* 160 units of gas *) +let write_base_weight = + S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 160)) |> S.mul_safe_exn + +(* 10 units of gas *) +let byte_read_weight = + S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 10)) |> S.mul_safe_exn + +(* 15 units of gas *) +let byte_written_weight = + S.(mul_fast scaling_factor (S.mul_safe_of_int_exn 15)) |> S.mul_safe_exn + +let cost_to_milligas (cost : cost) : Arith.fp = cost + +let raw_consume gas_counter cost = + let gas = cost_to_milligas cost in + Arith.sub_opt gas_counter gas + +let alloc_cost n = + S.scale_fast allocation_weight S.(add n (S.mul_safe_of_int_exn 1)) + +let alloc_bytes_cost n = alloc_cost (S.safe_int ((n + 7) / 8)) + +let atomic_step_cost : 'a S.t -> cost = S.may_saturate + +let step_cost n = S.scale_fast step_weight n + +let free = S.zero + +let read_bytes_cost n = + S.add read_base_weight (S.scale_fast byte_read_weight (S.safe_int n)) + +let write_bytes_cost n = + S.add write_base_weight (S.scale_fast byte_written_weight (S.safe_int n)) + +let ( +@ ) x y = S.add x y + +let ( *@ ) x y = S.mul x y + +let alloc_mbytes_cost n = + alloc_cost (S.mul_safe_of_int_exn 12) +@ alloc_bytes_cost n diff --git a/src/proto_012_PsiThaCa/lib_protocol/gas_limit_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/gas_limit_repr.mli new file mode 100644 index 000000000000..3b87007d6ee7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/gas_limit_repr.mli @@ -0,0 +1,110 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Internal representation of the gas limit available to the node baking a new + block. It should be proportional to the time and energy required to perform a + computation. + + This protects the bakers from performing exceedingly costly computations + while baking and also allows them to select cheaper-to-compute operations to + include in their blocks, as their reward for baking a block is not directly + related to the resources consumed by the machine performing the operation. + + It can be [Unaccounted] (unlimited) or [Limited] to some fixed-point value + (see [Fixed_point_repr] for the details). The value is represented with 3 + decimal places of precision. + + All computations on gas are performed in saturation arithmetic (see + [Saturation_repr]) bounded between [0] and [2 ^ 62 - 1]*) + +module Arith : + Fixed_point_repr.Full + with type 'a t = Saturation_repr.may_saturate Saturation_repr.t +[@@coq_plain_module] + +type t = Unaccounted | Limited of {remaining : Arith.fp} + +val encoding : t Data_encoding.encoding + +val pp : Format.formatter -> t -> unit + +(** Represents a gas cost of an operation. The gas model is constructed such + that the cost of each operation is roughly proportional to the time required + to perform the operation. If the gas cost of an operation exceeds the + available limit, such an operation is rejected. This is especially meant to + protect bakers against DoS attacks. *) +type cost = Saturation_repr.may_saturate Saturation_repr.t + +val cost_encoding : cost Data_encoding.encoding + +val pp_cost : Format.formatter -> cost -> unit + +(** Subtracts the cost from the current limit. Returns [None] if the limit + would fall below [0]. *) +val raw_consume : Arith.fp -> cost -> Arith.fp option + +(** The cost of free operation is [0]. *) +val free : cost + +(** [atomic_step_cost x] corresponds to [x] milliunit of gas. *) +val atomic_step_cost : _ Saturation_repr.t -> cost + +(** [step_cost x] corresponds to [x] units of gas. *) +val step_cost : _ Saturation_repr.t -> cost + +(** Cost of allocating qwords of storage. + + [alloc_cost n] estimates the cost of allocating [n] qwords of storage. *) +val alloc_cost : _ Saturation_repr.t -> cost + +(** Cost of allocating bytes in the storage. + + [alloc_bytes_cost b] estimates the cost of allocating [b] bytes of + storage. *) +val alloc_bytes_cost : int -> cost + +(** Cost of allocating bytes in the storage. + + [alloc_mbytes_cost b] estimates the cost of allocating [b] bytes of + storage and the cost of a header to describe these bytes. *) +val alloc_mbytes_cost : int -> cost + +(** Cost of reading the storage. + + [read_bytes_const n] estimates the cost of reading [n] bytes of storage. *) +val read_bytes_cost : int -> cost + +(** Cost of writing to storage. + + [write_bytes_const n] estimates the cost of writing [n] bytes to the + storage. *) +val write_bytes_cost : int -> cost + +(** Multiply a cost by a factor. Both arguments are saturated arithmetic values, + so no negative numbers are involved. *) +val ( *@ ) : _ Saturation_repr.t -> cost -> cost + +(** Add two costs together. *) +val ( +@ ) : cost -> cost -> cost diff --git a/src/proto_012_PsiThaCa/lib_protocol/gas_monad.ml b/src/proto_012_PsiThaCa/lib_protocol/gas_monad.ml new file mode 100644 index 000000000000..b0dd6b506d2b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/gas_monad.ml @@ -0,0 +1,53 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +(* The outer [tzresult] is for gas exhaustion only. The inner [result] is for all + other (non-gas) errors. *) +type ('a, 'trace) t = context -> (('a, 'trace) result * context) tzresult + +type ('a, 'trace) gas_monad = ('a, 'trace) t + +let of_result x ctxt = ok (x, ctxt) + +let return x = of_result (ok x) + +let ( >>$ ) m f ctxt = + m ctxt >>? fun (x, ctxt) -> + match x with Ok y -> f y ctxt | Error _ as err -> of_result err ctxt + +let ( >|$ ) m f ctxt = m ctxt >>? fun (x, ctxt) -> of_result (x >|? f) ctxt + +let ( >?$ ) m f = m >>$ fun x -> of_result (f x) + +let ( >??$ ) m f ctxt = m ctxt >>? fun (x, ctxt) -> f x ctxt + +let consume_gas cost ctxt = Gas.consume ctxt cost >>? return () + +let run ctxt x = x ctxt + +let record_trace_eval f m ctxt = + m ctxt >>? fun (x, ctxt) -> of_result (record_trace_eval f x) ctxt diff --git a/src/proto_012_PsiThaCa/lib_protocol/gas_monad.mli b/src/proto_012_PsiThaCa/lib_protocol/gas_monad.mli new file mode 100644 index 000000000000..ad329151f442 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/gas_monad.mli @@ -0,0 +1,71 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +(** This monad combines: + - a state monad where the state is the context + - two levels of error monad to distinguish gas exhaustion from other errors + + It is useful for backtracking on type checking errors without backtracking + the consumed gas. +*) +type ('a, 'trace) t + +(** Alias of [('a, 'trace) t] to avoid confusion when the module is open *) +type ('a, 'trace) gas_monad = ('a, 'trace) t + +(** monadic return operator of the gas monad *) +val return : 'a -> ('a, 'trace) t + +(** Binding operator for the gas monad *) +val ( >>$ ) : ('a, 'trace) t -> ('a -> ('b, 'trace) t) -> ('b, 'trace) t + +(** Mapping operator for the gas monad, [m >|$ f] is equivalent to + [m >>$ fun x -> return (f x)] *) +val ( >|$ ) : ('a, 'trace) t -> ('a -> 'b) -> ('b, 'trace) t + +(** Variant of [( >>$ )] to bind uncarbonated functions *) +val ( >?$ ) : ('a, 'trace) t -> ('a -> ('b, 'trace) result) -> ('b, 'trace) t + +(** Another variant of [( >>$ )] that lets recover from inner errors *) +val ( >??$ ) : + ('a, 'trace) t -> (('a, 'trace) result -> ('b, 'trace) t) -> ('b, 'trace) t + +(** gas-free embedding of tzresult values. [of_result x] is equivalent to [return () >?$ fun () -> x] *) +val of_result : ('a, 'trace) result -> ('a, 'trace) t + +(** A wrapper around Gas.consume. If that fails, the whole computation + within the Gas_monad returns an error. See the Alpha_context.Gas module + for details.*) +val consume_gas : Gas.cost -> (unit, 'trace) t + +(** Escaping the gas monad *) +val run : context -> ('a, 'trace) t -> (('a, 'trace) result * context) tzresult + +(** re-export of [Error_monad.record_trace_eval]. This function has no + effect in the case of a gas-exhaustion error. *) +val record_trace_eval : + (unit -> 'err) -> ('a, 'err trace) t -> ('a, 'err trace) t diff --git a/src/proto_012_PsiThaCa/lib_protocol/global_constants_costs.ml b/src/proto_012_PsiThaCa/lib_protocol/global_constants_costs.ml new file mode 100644 index 000000000000..61bbab15e6b3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/global_constants_costs.ml @@ -0,0 +1,47 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module S = Saturation_repr + +let log2 x = S.safe_int (1 + S.numbits x) + +let ( + ) = S.add + +let ( lsr ) = S.shift_right + +(* Approximating 200 + 1.266960 * number of bytes *) +let expr_to_address_in_context_cost bytes = + let v0 = Bytes.length bytes |> S.safe_int in + S.safe_int 200 + (v0 + (v0 lsr 2)) |> Gas_limit_repr.atomic_step_cost + +let expand_constants_branch_cost = + Gas_limit_repr.atomic_step_cost @@ S.safe_int 4095 + +(* Approximating 100 + 4.639474 * n*log(n) *) +let expand_no_constants_branch_cost node = + let v0 = Script_repr.micheline_nodes node |> S.safe_int in + let v0 = S.mul v0 (log2 v0) in + S.safe_int 100 + S.mul (S.safe_int 4) v0 + (v0 lsr 1) + (v0 lsr 3) + |> Gas_limit_repr.atomic_step_cost diff --git a/src/proto_012_PsiThaCa/lib_protocol/global_constants_costs.mli b/src/proto_012_PsiThaCa/lib_protocol/global_constants_costs.mli new file mode 100644 index 000000000000..9f24e8b34d39 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/global_constants_costs.mli @@ -0,0 +1,34 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Costs function for the global table of constants. *) + +(** Cost of calling [Global_constats_storage.expr_to_address_in_context]. *) +val expr_to_address_in_context_cost : bytes -> Gas_limit_repr.cost + +(** Step costs for [Global_constats_storage.expand_node]. *) +val expand_constants_branch_cost : Gas_limit_repr.cost + +val expand_no_constants_branch_cost : Script_repr.node -> Gas_limit_repr.cost diff --git a/src/proto_012_PsiThaCa/lib_protocol/global_constants_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/global_constants_storage.ml new file mode 100644 index 000000000000..429b454d44f1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/global_constants_storage.ml @@ -0,0 +1,270 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +open Micheline +open Michelson_v1_primitives + +(* + + See [expand] for an example. + + TODO: https://gitlab.com/tezos/tezos/-/issues/1609 + Move function to lib_micheline. + + On our next opportunity to update the environment, we + should move this function to lib_micheline. + +*) +let bottom_up_fold_cps initial_accumulator node initial_k f = + let rec traverse_node accu node k = + f accu node @@ fun accu node -> + match node with + | String _ | Int _ | Bytes _ -> k accu node + | Prim (loc, prim, args, annot) -> + (traverse_nodes [@ocaml.tailcall]) accu args @@ fun accu args -> + f accu (Prim (loc, prim, args, annot)) k + | Seq (loc, elts) -> + (traverse_nodes [@ocaml.tailcall]) accu elts @@ fun accu elts -> + f accu (Seq (loc, elts)) k + and traverse_nodes accu nodes k = + match nodes with + | [] -> k accu [] + | node :: nodes -> + (traverse_node [@ocaml.tailcall]) accu node @@ fun accu node -> + (traverse_nodes [@ocaml.tailcall]) accu nodes @@ fun accu nodes -> + k accu (node :: nodes) + in + traverse_node initial_accumulator node initial_k + [@@coq_axiom_with_reason "local mutually recursive definition not handled"] + +module Gas_costs = Global_constants_costs +module Expr_hash_map = Map.Make (Script_expr_hash) + +type error += Expression_too_deep + +type error += Expression_already_registered + +type error += Badly_formed_constant_expression + +type error += Nonexistent_global + +type error += Expression_too_large + +let () = + let description = + "Attempted to register an expression that, after fully expanding all \ + referenced global constants, would result in too many levels of nesting." + in + register_error_kind + `Branch + ~id:"Expression_too_deep" + ~title:"Expression too deep" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Expression_too_deep -> Some () | _ -> None) + (fun () -> Expression_too_deep) ; + let description = + "Attempted to register an expression as global constant that has already \ + been registered." + in + register_error_kind + `Branch + ~id:"Expression_already_registered" + ~title:"Expression already registered" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Expression_already_registered -> Some () | _ -> None) + (fun () -> Expression_already_registered) ; + let description = + "Found a badly formed constant expression. The 'constant' primitive must \ + always be followed by a string of the hash of the expression it points \ + to." + in + register_error_kind + `Branch + ~id:"Badly_formed_constant_expression" + ~title:"Badly formed constant expression" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Badly_formed_constant_expression -> Some () | _ -> None) + (fun () -> Badly_formed_constant_expression) ; + let description = + "No registered global was found at the given hash in storage." + in + register_error_kind + `Branch + ~id:"Nonexistent_global" + ~title:"Tried to look up nonexistent global" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Nonexistent_global -> Some () | _ -> None) + (fun () -> Nonexistent_global) ; + let description = + "Encountered an expression that, after expanding all constants, is larger \ + than the expression size limit." + in + register_error_kind + `Branch + ~id:"Expression_too_large" + ~title:"Expression too large" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.empty + (function Expression_too_large -> Some () | _ -> None) + (fun () -> Expression_too_large) + +let get context hash = + Storage.Global_constants.Map.find context hash >>=? fun (context, value) -> + match value with + | None -> fail Nonexistent_global + | Some value -> return (context, value) + +let expr_to_address_in_context context expr = + let lexpr = Script_repr.lazy_expr expr in + Raw_context.consume_gas context @@ Script_repr.force_bytes_cost lexpr + >>? fun context -> + Script_repr.force_bytes lexpr >>? fun b -> + Raw_context.consume_gas context @@ Gas_costs.expr_to_address_in_context_cost b + >|? fun context -> (context, Script_expr_hash.hash_bytes [b]) + +let node_too_large node = + let node_size = Script_repr.Micheline_size.of_node node in + let nodes = Saturation_repr.to_int node_size.nodes in + let string_bytes = Saturation_repr.to_int node_size.string_bytes in + let z_bytes = Saturation_repr.to_int node_size.z_bytes in + Compare.Int.( + nodes > Constants_repr.max_micheline_node_count + || string_bytes + z_bytes > Constants_repr.max_micheline_bytes_limit) + +let expand_node context node = + (* We charge for traversing the top-level node at the beginning. + Inside the loop, we charge for traversing each new constant + that gets expanded. *) + Raw_context.consume_gas + context + (Gas_costs.expand_no_constants_branch_cost node) + >>?= fun context -> + bottom_up_fold_cps + (* We carry a Boolean representing whether we + had to do any expansions or not. *) + (context, Expr_hash_map.empty, false) + node + (fun (context, _, did_expansion) node -> + return (context, node, did_expansion)) + (fun (context, map, did_expansion) node k -> + match node with + | Prim (_, H_constant, args, annot) -> ( + (* Charge for validating the b58check hash. *) + Raw_context.consume_gas context Gas_costs.expand_constants_branch_cost + >>?= fun context -> + match (args, annot) with + (* A constant Prim should always have a single String argument, + being a properly formatted hash. *) + | ([String (_, address)], []) -> ( + match Script_expr_hash.of_b58check_opt address with + | None -> fail Badly_formed_constant_expression + | Some hash -> ( + match Expr_hash_map.find hash map with + | Some node -> + (* Charge traversing the newly retrieved node *) + Raw_context.consume_gas + context + (Gas_costs.expand_no_constants_branch_cost node) + >>?= fun context -> k (context, map, true) node + | None -> + get context hash >>=? fun (context, expr) -> + (* Charge traversing the newly retrieved node *) + let node = root expr in + Raw_context.consume_gas + context + (Gas_costs.expand_no_constants_branch_cost node) + >>?= fun context -> + k (context, Expr_hash_map.add hash node map, true) node)) + | _ -> fail Badly_formed_constant_expression) + | Int _ | String _ | Bytes _ | Prim _ | Seq _ -> + k (context, map, did_expansion) node) + >>=? fun (context, node, did_expansion) -> + if did_expansion then + (* Gas charged during expansion is at least proportional to the size of the + resulting node so the execution time of [node_too_large] is already + covered. *) + if node_too_large node then fail Expression_too_large + else return (context, node) + else return (context, node) + +let expand context expr = + expand_node context (root expr) >|=? fun (context, node) -> + (context, strip_locations node) + +(** Computes the maximum depth of a Micheline node. Fails + with [Expression_too_deep] if greater than + [max_allowed_global_constant_depth].*) +let check_depth node = + let rec advance node depth k = + if Compare.Int.(depth > Constants_repr.max_allowed_global_constant_depth) + then error Expression_too_deep + else + match node with + | Int _ | String _ | Bytes _ | Prim (_, _, [], _) | Seq (_, []) -> + (k [@tailcall]) (depth + 1) + | Prim (loc, _, hd :: tl, _) | Seq (loc, hd :: tl) -> + (advance [@tailcall]) hd (depth + 1) (fun dhd -> + (advance [@tailcall]) + (* Because [depth] doesn't care about the content + of the expression, we can safely throw away information + about primitives and replace them with the [Seq] constructor.*) + (Seq (loc, tl)) + depth + (fun dtl -> (k [@tailcall]) (Compare.Int.max dhd dtl))) + in + advance node 0 (fun x -> Ok x) + +let register context value = + (* To calculate the total depth, we first expand all constants + in the expression. This may fail with [Expression_too_large]. + + Though the stored expression is the unexpanded version. + *) + expand_node context (root value) >>=? fun (context, node) -> + (* We do not need to carbonate [check_depth]. [expand_node] and + [Storage.Global_constants.Map.init] are already carbonated + with gas at least proportional to the size of the expanded node + and the computation cost of [check_depth] is of the same order. *) + check_depth node >>?= fun (_depth : int) -> + expr_to_address_in_context context value >>?= fun (context, key) -> + trace Expression_already_registered + @@ Storage.Global_constants.Map.init context key value + >|=? fun (context, size) -> (context, key, Z.of_int size) + +module Internal_for_tests = struct + let node_too_large = node_too_large + + let bottom_up_fold_cps = bottom_up_fold_cps + + let expr_to_address_in_context = expr_to_address_in_context +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/global_constants_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/global_constants_storage.mli new file mode 100644 index 000000000000..096143c3c2af --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/global_constants_storage.mli @@ -0,0 +1,150 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module represents access to a global table of constant + Micheline values. Users may register a Micheline value in the + table, paying the cost of storage. Once stored, contracts source code may + reference this value by its hash. + + Note: the table does not typecheck the values stored in it. + Instead, any place that uses constants must first call [expand] + before typechecking the code. This decision was made to make it as + easy as possible for users to register values to the table, and also + to allow maximum flexibility in the use of constants for different + parts of a Michelson script (code, types, data, etc.). *) + +type error += Expression_too_deep + +type error += Expression_already_registered + +(** A constant is the prim of the literal characters "constant". + A constant must have a single argument, being a string with a + well formed hash of a Micheline expression (i.e generated by + [Script_expr_hash.to_b58check]). *) +type error += Badly_formed_constant_expression + +type error += Nonexistent_global + +(** [get context hash] retrieves the Micheline value with the given hash. + + Fails with [Nonexistent_global] if no value is found at the given hash. + + Fails with [Storage_error Corrupted_data] if the deserialisation fails. + + Consumes [Gas_repr.read_bytes_cost ]. *) +val get : + Raw_context.t -> + Script_expr_hash.t -> + (Raw_context.t * Script_repr.expr) tzresult Lwt.t + +(** [register context value] registers a constant in the global table of constants, + returning the hash and storage bytes consumed. + + Does not type-check the Micheline code being registered, allow potentially + ill-typed Michelson values to be stored in the table (see note at top of module). + + The constant is stored unexpanded, but it is temporarily expanded at registration + time only to check the expanded version respects the following limits. + This also ensures there are no cyclic dependencies between constants. + + Fails with [Expression_too_deep] if, after fully expanding all constants, + the expression would have a depth greater than [Constant_repr.max_allowed_global_constant_depth]. + + Fails with [Badly_formed_constant_expression] if constants are not + well-formed (see declaration of [Badly_formed_constant_expression]) or with + [Nonexistent_global] if a referenced constant does not exist in the table. + + Consumes serialization cost. + Consumes [Gas_repr.write_bytes_cost ] where size is the number + of bytes in the binary serialization provided by [Script_repr.expr_encoding]. *) +val register : + Raw_context.t -> + Script_repr.expr -> + (Raw_context.t * Script_expr_hash.t * Z.t) tzresult Lwt.t + +(** [expand context expr] replaces every constant in the + given Michelson expression with its value stored in the global table. + + The expansion is applied recursively so that the returned expression + contains no constant. + + Fails with [Badly_formed_constant_expression] if constants are not + well-formed (see declaration of [Badly_formed_constant_expression]) or + with [Nonexistent_global] if a referenced constant does not exist in + the table. *) +val expand : + Raw_context.t -> + Script_repr.expr -> + (Raw_context.t * Script_repr.expr) tzresult Lwt.t + +module Internal_for_tests : sig + (** [node_too_large node] returns true if: + - The number of sub-nodes in the [node] + exceeds [Global_constants_storage.node_size_limit]. + - The sum of the bytes in String, Int, + and Bytes sub-nodes of [node] exceeds + [Global_constants_storage.bytes_size_limit]. + + Otherwise returns false. *) + val node_too_large : Script_repr.node -> bool + + (** [bottom_up_fold_cps initial_accumulator node initial_k f] + folds [node] and all its sub-nodes if any, starting from + [initial_accumulator], using an initial continuation [initial_k]. + At each node, [f] is called to transform the continuation [k] into + the next one. This explicit manipulation of the continuation + is typically useful to short-circuit. + + Notice that a common source of bug is to forget to properly call the + continuation in `f`. + + See [Global_constants_storage.expand] for an example. + + TODO: https://gitlab.com/tezos/tezos/-/issues/1609 + Move function to lib_micheline. + + On our next opportunity to update the environment, we + should move this function to lib_micheline. + *) + val bottom_up_fold_cps : + 'accumulator -> + 'loc Script_repr.michelson_node -> + ('accumulator -> 'loc Script_repr.michelson_node -> 'return) -> + ('accumulator -> + 'loc Script_repr.michelson_node -> + ('accumulator -> 'loc Script_repr.michelson_node -> 'return) -> + 'return) -> + 'return + + (* [expr_to_address_in_context context expr] converts [expr] + into a unique hash represented by a [Script_expr_hash.t]. + + Consumes gas corresponding to the cost of converting [expr] + to bytes and hashing the bytes. *) + val expr_to_address_in_context : + Raw_context.t -> + Script_repr.expr -> + (Raw_context.t * Script_expr_hash.t) tzresult +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/init_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/init_storage.ml new file mode 100644 index 000000000000..ac570744fb1c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/init_storage.ml @@ -0,0 +1,312 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* Copyright (c) 2021 DaiLambda, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* + To add invoices, you can use a helper function like this one: + + (** Invoice a contract at a given address with a given amount. Returns the + updated context and a balance update receipt (singleton list). The address + must be a valid base58 hash, otherwise this is no-op and returns an empty + receipts list. + + Do not fail if something goes wrong. + *) + let invoice_contract ctxt ~address ~amount_mutez = + match Tez_repr.of_mutez amount_mutez with + | None -> Lwt.return (ctxt, []) + | Some amount -> ( + ( Contract_repr.of_b58check address >>?= fun recipient -> + Token.transfer + ~origin:Protocol_migration + ctxt + `Invoice + (`Contract recipient) + amount ) + >|= function + | Ok res -> res + | Error _ -> (ctxt, [])) +*) + +let unfreeze_deposits_rewards_and_fees ctxt delegate cycle = + Token.balance ctxt (`Legacy_deposits (delegate, cycle)) >>=? fun deposits -> + Token.balance ctxt (`Legacy_fees (delegate, cycle)) >>=? fun fees -> + Token.balance ctxt (`Legacy_rewards (delegate, cycle)) >>=? fun rewards -> + let contract = Contract_repr.implicit_contract delegate in + Token.transfer_n + ~origin:Protocol_migration + ctxt + [ + (`Legacy_deposits (delegate, cycle), deposits); + (`Legacy_fees (delegate, cycle), fees); + (`Legacy_rewards (delegate, cycle), rewards); + ] + (`Delegate_balance delegate) + >>=? fun (ctxt, balance_updates) -> + Contract_delegate_storage.add_contract_stake ctxt contract rewards + >|=? fun ctxt -> (ctxt, balance_updates) + +(* Note that Legacy_frozen_* tables do not need to be cleared because + they become empty, given that when the amount in such a table + becomes 0 the contract is automatically removed from the table (see + the [Transfer] module). *) +let unfreeze_all_remaining_deposits_rewards_and_fees ctxt migration_cycle = + let preserved = Constants_storage.preserved_cycles ctxt in + List.fold_left_es + (fun (ctxt, balance_updates) cycle_offset -> + match Cycle_repr.sub migration_cycle cycle_offset with + | None -> return (ctxt, balance_updates) + | Some unfrozen_cycle -> + Storage.Legacy_delegates_with_frozen_balance.fold + (ctxt, unfrozen_cycle) + ~order:`Sorted + ~init:(Ok (ctxt, balance_updates)) + ~f:(fun delegate acc -> + acc >>?= fun (ctxt, bus) -> + unfreeze_deposits_rewards_and_fees ctxt delegate unfrozen_cycle + >|=? fun (ctxt, balance_updates) -> (ctxt, balance_updates @ bus)) + >>=? fun (ctxt, balance_updates) -> + Storage.Legacy_delegates_with_frozen_balance.clear + (ctxt, unfrozen_cycle) + >>= fun ctxt -> return (ctxt, balance_updates)) + (ctxt, []) + Misc.(0 --> preserved) + +let migrate_nonces ctxt migration_cycle = + let migrate_cycle ctxt cycle = + let levels = Level_storage.levels_with_commitments_in_cycle ctxt cycle in + let migrate ctxt level = + Storage.Seed.Nonce_legacy.mem ctxt level >>= function + | false -> return ctxt + | true -> + Storage.Seed.Nonce_legacy.get ctxt level >>=? fun nonce -> + Storage.Seed.Nonce.add ctxt level nonce >>= return + in + List.fold_left_es migrate ctxt levels + in + List.fold_left_es + migrate_cycle + ctxt + (match Cycle_repr.pred migration_cycle with + | None -> [migration_cycle] + | Some previous_cycle -> [previous_cycle; migration_cycle]) + +let prepare_first_block ctxt ~typecheck ~level ~timestamp = + Raw_context.prepare_first_block ~level ~timestamp ctxt + >>=? fun (previous_protocol, ctxt) -> + let cycle = (Raw_context.current_level ctxt).cycle in + (match previous_protocol with + | Genesis param -> + (* This is the genesis protocol: initialise the state *) + let init_commitment (ctxt, balance_updates) + Commitment_repr.{blinded_public_key_hash; amount} = + Token.transfer + ctxt + `Initial_commitments + (`Collected_commitments blinded_public_key_hash) + amount + >>=? fun (ctxt, new_balance_updates) -> + return (ctxt, new_balance_updates @ balance_updates) + in + List.fold_left_es init_commitment (ctxt, []) param.commitments + >>=? fun (ctxt, commitments_balance_updates) -> + Storage.Stake.Last_snapshot.init ctxt 0 >>=? fun ctxt -> + Seed_storage.init ctxt >>=? fun ctxt -> + Contract_storage.init ctxt >>=? fun ctxt -> + Bootstrap_storage.init + ctxt + ~typecheck + ?no_reward_cycles:param.no_reward_cycles + param.bootstrap_accounts + param.bootstrap_contracts + >>=? fun (ctxt, bootstrap_balance_updates) -> + Stake_storage.init_first_cycles ctxt Delegate_storage.pubkey + >>=? fun ctxt -> + Vote_storage.init + ctxt + ~start_position:(Level_storage.current ctxt).level_position + >>=? fun ctxt -> + Storage.Block_round.init ctxt Round_repr.zero >>=? fun ctxt -> + Vote_storage.update_listings ctxt >>=? fun ctxt -> + (* Must be called after other originations since it unsets the origination nonce.*) + Liquidity_baking_migration.init ctxt ~typecheck + >>=? fun (ctxt, operation_results) -> + Storage.Pending_migration.Operation_results.init ctxt operation_results + >>=? fun ctxt -> + Raw_level_repr.of_int32 level >>?= fun first_level -> + Storage.Tenderbake.First_level.init ctxt first_level >>=? fun ctxt -> + return (ctxt, commitments_balance_updates @ bootstrap_balance_updates) + | Hangzhou_011 -> + Raw_level_repr.of_int32 level >>?= fun first_level -> + Storage.Tenderbake.First_level.init ctxt first_level >>=? fun ctxt -> + Storage.Block_round.init ctxt Round_repr.zero >>=? fun ctxt -> + Raw_context.remove_existing_tree ctxt ["block_priority"] >>=? fun ctxt -> + Storage.Legacy_active_delegates_with_rolls.fold + ctxt + ~order:`Sorted + ~init:(Ok ctxt) + ~f:(fun pkh ctxt -> + ctxt >>?= fun ctxt -> + Storage.Roll_legacy.Delegate_roll_list.remove_existing ctxt pkh) + >>=? fun ctxt -> + Storage.Legacy_active_delegates_with_rolls.clear ctxt >>= fun ctxt -> + let old_tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + let new_tokens_per_roll = Tez_repr.(mul_exn one 6_000) in + assert (Tez_repr.(new_tokens_per_roll < old_tokens_per_roll)) ; + Roll_storage_legacy.fold + ctxt + ~f:(fun _roll pk (stakes, pk_map) -> + let (pkh, pk_map) = + match Misc.Public_key_map.find pk pk_map with + | None -> + let pkh = Signature.Public_key.hash pk in + (pkh, Misc.Public_key_map.add pk pkh pk_map) + | Some pkh -> (pkh, pk_map) + in + let stake = + Signature.Public_key_hash.Map.update + pkh + (function None -> Some 1l | Some n -> Some (Int32.succ n)) + stakes + in + return (stake, pk_map)) + (Signature.Public_key_hash.Map.empty, Misc.Public_key_map.empty) + >>=? fun (stakes, _pk_map) -> + Storage.Delegates.fold + ctxt + ~order:`Sorted + ~init:(Ok ctxt) + ~f:(fun pkh ctxt -> + ctxt >>?= fun ctxt -> + Roll_storage_legacy.get_change ctxt pkh >>=? fun change -> + Storage.Roll_legacy.Delegate_change.remove ctxt pkh >>= fun ctxt -> + Frozen_deposits_storage.init ctxt pkh >>=? fun ctxt -> + Delegate_activation_storage.is_inactive ctxt pkh >>=? fun inactive -> + match Signature.Public_key_hash.Map.find pkh stakes with + | None -> + Storage.Stake.Staking_balance.init ctxt pkh change + >>=? fun ctxt -> + if (not inactive) && Tez_repr.(change >= new_tokens_per_roll) then + Storage.Stake.Active_delegate_with_one_roll.add ctxt pkh () + >>= fun ctxt -> return ctxt + else return ctxt + | Some n -> + Lwt.return + ( Tez_repr.(old_tokens_per_roll *? Int64.of_int32 n) + >>? fun rolls -> Tez_repr.(rolls +? change) ) + >>=? fun staking_balance -> + Storage.Stake.Staking_balance.init ctxt pkh staking_balance + >>=? fun ctxt -> + (if not inactive then + Storage.Stake.Active_delegate_with_one_roll.add ctxt pkh () + else Lwt.return ctxt) + >>= fun ctxt -> return ctxt) + >>=? fun ctxt -> + Raw_context.patch_constants ctxt (fun constants -> + { + constants with + Constants_repr.tokens_per_roll = Tez_repr.(mul_exn one 6_000); + }) + >>= fun ctxt -> + (* NOTE: the code below fails when the migration happens during + the first cycle after Genesis, probably because of a bug in + the initialization of the previous protocol from Genesis. *) + let preserved = Constants_storage.preserved_cycles ctxt in + let max_slashing_period = Constants_storage.max_slashing_period ctxt in + List.fold_left_s + (fun ctxt cycle -> + Storage.Roll_legacy.Last_for_snapshot.clear (ctxt, cycle) + >>= fun ctxt -> + Storage.Roll_legacy.Snapshot_for_cycle.remove ctxt cycle) + ctxt + Cycle_repr.( + (match Cycle_repr.sub cycle preserved with + | None -> cycle + | Some cycle -> cycle) + ---> Cycle_repr.add cycle (preserved + 3)) + >>= fun ctxt -> + Raw_context.remove_existing_tree ctxt ["rolls"] >>=? fun ctxt -> + migrate_nonces ctxt cycle >>=? fun ctxt -> + unfreeze_all_remaining_deposits_rewards_and_fees ctxt cycle + >>=? fun (ctxt, balance_updates) -> + Storage.Stake.Last_snapshot.init ctxt 0 >>=? fun ctxt -> + List.fold_left_es + (fun ctxt cycle -> + Storage.Seed.For_cycle.mem ctxt cycle >>= function + | false -> return ctxt + | true -> + Stake_storage.snapshot ctxt >>=? fun ctxt -> + Stake_storage + .select_distribution_for_cycle_do_not_call_except_for_migration + ctxt + cycle + Delegate_storage.pubkey) + ctxt + Cycle_repr.( + (match Cycle_repr.sub cycle (max_slashing_period - 1) with + | None -> cycle + | Some cycle -> cycle) + ---> Cycle_repr.add cycle (preserved + 1)) + >>=? fun ctxt -> + (* Remove seeds that will not be useful any longer: those from + [cycle - preserved_cycles - 1] to [cycle - max_slashable_period]. + NB: The seed at [cycle - preserved] is already removed by + H.cycle_end. The seed at [cycle - max_slashable_period + 1] + is removed a bit later below by [Stake_storage.clear_at_cycle_end]. *) + (match + ( Cycle_repr.sub cycle (preserved - 1), + Cycle_repr.sub cycle max_slashing_period ) + with + | (Some from_cycle, Some to_cycle) -> + List.fold_left_es + (fun ctxt cycle -> + Storage.Seed.For_cycle.mem ctxt cycle >>= function + | false -> return ctxt + | true -> Storage.Seed.For_cycle.remove_existing ctxt cycle) + ctxt + Cycle_repr.(from_cycle ---> to_cycle) + | _ -> return ctxt) + >>=? fun ctxt -> return (ctxt, balance_updates)) + >>=? fun (ctxt, balance_updates) -> + Stake_storage.snapshot ctxt >>=? fun ctxt -> + Delegate_storage.freeze_deposits_do_not_call_except_for_migration + ~new_cycle:cycle + ~balance_updates + ctxt + >>=? fun (ctxt, balance_updates) -> + (match Level_storage.dawn_of_a_new_cycle ctxt with + | None -> return ctxt + | Some last_cycle -> + assert (Cycle_repr.(last_cycle = cycle)) ; + Stake_storage.clear_at_cycle_end ctxt ~new_cycle:(Cycle_repr.succ cycle)) + >>=? fun ctxt -> + Receipt_repr.group_balance_updates balance_updates >>?= fun balance_updates -> + Storage.Pending_migration.Balance_updates.add ctxt balance_updates + >>= fun ctxt -> return ctxt + +let prepare ctxt ~level ~predecessor_timestamp ~timestamp = + Raw_context.prepare ~level ~predecessor_timestamp ~timestamp ctxt + >>=? fun ctxt -> Storage.Pending_migration.remove ctxt diff --git a/src/proto_012_PsiThaCa/lib_protocol/init_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/init_storage.mli new file mode 100644 index 000000000000..0b71d116c541 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/init_storage.mli @@ -0,0 +1,55 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Functions to setup storage. Used by [Alpha_context.prepare]. + + If you have defined a new type of storage, you should add relevant + setups here. + *) + +(* This is the genesis protocol: initialise the state *) +val prepare_first_block : + Context.t -> + typecheck: + (Raw_context.t -> + Script_repr.t -> + ((Script_repr.t * Lazy_storage_diff.diffs option) * Raw_context.t) + Error_monad.tzresult + Lwt.t) -> + level:int32 -> + timestamp:Time.t -> + (Raw_context.t, Error_monad.error Error_monad.trace) Pervasives.result Lwt.t + +val prepare : + Context.t -> + level:Int32.t -> + predecessor_timestamp:Time.t -> + timestamp:Time.t -> + (Raw_context.t + * Receipt_repr.balance_updates + * Migration_repr.origination_result list) + Error_monad.tzresult + Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_diff.ml b/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_diff.ml new file mode 100644 index 000000000000..9a7030c35741 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_diff.ml @@ -0,0 +1,439 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type Next = sig + type id + + val init : Raw_context.t -> Raw_context.t tzresult Lwt.t + + val incr : Raw_context.t -> (Raw_context.t * id) tzresult Lwt.t +end + +module type Total_bytes = sig + type id + + val init : Raw_context.t -> id -> Z.t -> Raw_context.t tzresult Lwt.t + + val get : Raw_context.t -> id -> Z.t tzresult Lwt.t + + val update : Raw_context.t -> id -> Z.t -> Raw_context.t tzresult Lwt.t +end + +(** Operations to be defined on a lazy storage type. *) +module type OPS = sig + module Id : Lazy_storage_kind.ID + + type alloc + + type updates + + val title : string + + val alloc_encoding : alloc Data_encoding.t + + val updates_encoding : updates Data_encoding.t + + val alloc_in_memory_size : alloc -> Cache_memory_helpers.nodes_and_size + + val updates_in_memory_size : updates -> Cache_memory_helpers.nodes_and_size + + val bytes_size_for_empty : Z.t + + val alloc : Raw_context.t -> id:Id.t -> alloc -> Raw_context.t tzresult Lwt.t + + val apply_updates : + Raw_context.t -> id:Id.t -> updates -> (Raw_context.t * Z.t) tzresult Lwt.t + + module Next : Next with type id := Id.t + + module Total_bytes : Total_bytes with type id := Id.t + + (** Deep copy. *) + val copy : + Raw_context.t -> from:Id.t -> to_:Id.t -> Raw_context.t tzresult Lwt.t + + (** Deep deletion. *) + val remove : Raw_context.t -> Id.t -> Raw_context.t Lwt.t +end + +module Big_map = struct + include Lazy_storage_kind.Big_map + + let alloc_in_memory_size {key_type; value_type} = + let open Cache_memory_helpers in + ret_adding + (expr_size key_type ++ expr_size value_type) + (header_size +! (word_size *? 2)) + + let updates_in_memory_size updates = + let open Cache_memory_helpers in + let update_size {key; key_hash = _; value} = + ret_adding + (expr_size key ++ option_size_vec expr_size value) + (header_size +! (word_size *? 3) +? Script_expr_hash.size) + in + list_fold_size update_size updates + + let bytes_size_for_big_map_key = 65 + + let bytes_size_for_empty = + let bytes_size_for_big_map = 33 in + Z.of_int bytes_size_for_big_map + + let alloc ctxt ~id {key_type; value_type} = + (* Annotations are erased to allow sharing on [Copy]. The types from the + contract code are used, these ones are only used to make sure they are + compatible during transmissions between contracts, and only need to be + compatible, annotations notwithstanding. *) + let key_type = + Micheline.strip_locations + (Script_repr.strip_annotations (Micheline.root key_type)) + in + let value_type = + Micheline.strip_locations + (Script_repr.strip_annotations (Micheline.root value_type)) + in + Storage.Big_map.Key_type.init ctxt id key_type >>=? fun ctxt -> + Storage.Big_map.Value_type.init ctxt id value_type + + let apply_update ctxt ~id + { + key = _key_is_shown_only_on_the_receipt_in_print_big_map_diff; + key_hash; + value; + } = + match value with + | None -> + Storage.Big_map.Contents.remove (ctxt, id) key_hash + >|=? fun (ctxt, freed, existed) -> + let freed = + if existed then freed + bytes_size_for_big_map_key else freed + in + (ctxt, Z.of_int ~-freed) + | Some v -> + Storage.Big_map.Contents.add (ctxt, id) key_hash v + >|=? fun (ctxt, size_diff, existed) -> + let size_diff = + if existed then size_diff else size_diff + bytes_size_for_big_map_key + in + (ctxt, Z.of_int size_diff) + + let apply_updates ctxt ~id updates = + List.fold_left_es + (fun (ctxt, size) update -> + apply_update ctxt ~id update >|=? fun (ctxt, added_size) -> + (ctxt, Z.add size added_size)) + (ctxt, Z.zero) + updates + + include Storage.Big_map +end + +type ('id, 'alloc, 'updates) ops = + (module OPS + with type Id.t = 'id + and type alloc = 'alloc + and type updates = 'updates) + +module Sapling_state = struct + include Lazy_storage_kind.Sapling_state + + let alloc_in_memory_size {memo_size = (_ : int)} = + let open Cache_memory_helpers in + (Nodes.zero, header_size +! word_size) + + let updates_in_memory_size update = + (Cache_memory_helpers.Nodes.zero, Sapling_repr.diff_in_memory_size update) + + let bytes_size_for_empty = Z.of_int 33 + + let alloc ctxt ~id {memo_size} = Sapling_storage.init ctxt id ~memo_size + + let apply_updates ctxt ~id updates = + Sapling_storage.apply_diff ctxt id updates + + include Storage.Sapling +end + +(* + To add a new lazy storage kind here, you only need to create a module similar + to [Big_map] above and add a case to [get_ops] below. +*) + +let get_ops : type i a u. (i, a, u) Lazy_storage_kind.t -> (i, a, u) ops = + function + | Big_map -> (module Big_map) + | Sapling_state -> (module Sapling_state) + [@@coq_axiom_with_reason "gadt"] + +type ('id, 'alloc) init = Existing | Copy of {src : 'id} | Alloc of 'alloc + +type ('id, 'alloc, 'updates) diff = + | Remove + | Update of {init : ('id, 'alloc) init; updates : 'updates} + +let diff_encoding : type i a u. (i, a, u) ops -> (i, a, u) diff Data_encoding.t + = + fun (module OPS) -> + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"update" + (obj2 + (req "action" (constant "update")) + (req "updates" OPS.updates_encoding)) + (function + | Update {init = Existing; updates} -> Some ((), updates) | _ -> None) + (fun ((), updates) -> Update {init = Existing; updates}); + case + (Tag 1) + ~title:"remove" + (obj1 (req "action" (constant "remove"))) + (function Remove -> Some () | _ -> None) + (fun () -> Remove); + case + (Tag 2) + ~title:"copy" + (obj3 + (req "action" (constant "copy")) + (req "source" OPS.Id.encoding) + (req "updates" OPS.updates_encoding)) + (function + | Update {init = Copy {src}; updates} -> Some ((), src, updates) + | _ -> None) + (fun ((), src, updates) -> Update {init = Copy {src}; updates}); + case + (Tag 3) + ~title:"alloc" + (merge_objs + (obj2 + (req "action" (constant "alloc")) + (req "updates" OPS.updates_encoding)) + OPS.alloc_encoding) + (function + | Update {init = Alloc alloc; updates} -> Some (((), updates), alloc) + | _ -> None) + (fun (((), updates), alloc) -> Update {init = Alloc alloc; updates}); + ] + +let init_size : + type i a u. + (i, a, u) ops -> (i, a) init -> Cache_memory_helpers.nodes_and_size = + fun (module OPS) init -> + let open Cache_memory_helpers in + match init with + | Existing -> zero + | Copy {src = _id_is_a_Z_fitting_in_an_int_for_a_long_time} -> + (Nodes.zero, header_size +! word_size) + | Alloc alloc -> + ret_adding (OPS.alloc_in_memory_size alloc) (header_size +! word_size) + +let updates_size : + type i a u. (i, a, u) ops -> u -> Cache_memory_helpers.nodes_and_size = + fun (module OPS) updates -> OPS.updates_in_memory_size updates + +let diff_in_memory_size kind diff = + let open Cache_memory_helpers in + match diff with + | Remove -> zero + | Update {init; updates} -> + let ops = get_ops kind in + ret_adding (init_size ops init ++ updates_size ops updates) h2w + +(** + [apply_updates ctxt ops ~id init] applies the updates [updates] on lazy + storage [id] on storage context [ctxt] using operations [ops] and returns the + updated storage context and the added size in bytes (may be negative). +*) +let apply_updates : + type i a u. + Raw_context.t -> + (i, a, u) ops -> + id:i -> + u -> + (Raw_context.t * Z.t) tzresult Lwt.t = + fun ctxt (module OPS) ~id updates -> + OPS.apply_updates ctxt ~id updates >>=? fun (ctxt, updates_size) -> + if Z.(equal updates_size zero) then return (ctxt, updates_size) + else + OPS.Total_bytes.get ctxt id >>=? fun size -> + OPS.Total_bytes.update ctxt id (Z.add size updates_size) >|=? fun ctxt -> + (ctxt, updates_size) + +(** + [apply_init ctxt ops ~id init] applies the initialization [init] on lazy + storage [id] on storage context [ctxt] using operations [ops] and returns the + updated storage context and the added size in bytes (may be negative). + + If [id] represents a temporary lazy storage, the added size may be wrong. +*) +let apply_init : + type i a u. + Raw_context.t -> + (i, a, u) ops -> + id:i -> + (i, a) init -> + (Raw_context.t * Z.t) tzresult Lwt.t = + fun ctxt (module OPS) ~id init -> + match init with + | Existing -> return (ctxt, Z.zero) + | Copy {src} -> + OPS.copy ctxt ~from:src ~to_:id >>=? fun ctxt -> + if OPS.Id.is_temp id then return (ctxt, Z.zero) + else + OPS.Total_bytes.get ctxt src >>=? fun copy_size -> + return (ctxt, Z.add copy_size OPS.bytes_size_for_empty) + | Alloc alloc -> + OPS.Total_bytes.init ctxt id Z.zero >>=? fun ctxt -> + OPS.alloc ctxt ~id alloc >>=? fun ctxt -> + return (ctxt, OPS.bytes_size_for_empty) + +(** + [apply_diff ctxt ops ~id diff] applies the diff [diff] on lazy storage [id] + on storage context [ctxt] using operations [ops] and returns the updated + storage context and the added size in bytes (may be negative). + + If [id] represents a temporary lazy storage, the added size may be wrong. +*) +let apply_diff : + type i a u. + Raw_context.t -> + (i, a, u) ops -> + id:i -> + (i, a, u) diff -> + (Raw_context.t * Z.t) tzresult Lwt.t = + fun ctxt ((module OPS) as ops) ~id diff -> + match diff with + | Remove -> + if OPS.Id.is_temp id then + OPS.remove ctxt id >|= fun ctxt -> ok (ctxt, Z.zero) + else + OPS.Total_bytes.get ctxt id >>=? fun size -> + OPS.remove ctxt id >>= fun ctxt -> + return (ctxt, Z.neg (Z.add size OPS.bytes_size_for_empty)) + | Update {init; updates} -> + apply_init ctxt ops ~id init >>=? fun (ctxt, init_size) -> + apply_updates ctxt ops ~id updates >>=? fun (ctxt, updates_size) -> + return (ctxt, Z.add init_size updates_size) + +type diffs_item = + | Item : + ('i, 'a, 'u) Lazy_storage_kind.t * 'i * ('i, 'a, 'u) diff + -> diffs_item + +let make : + type i a u. + (i, a, u) Lazy_storage_kind.t -> i -> (i, a, u) diff -> diffs_item = + fun k id diff -> Item (k, id, diff) + +let item_encoding = + let open Data_encoding in + union + @@ List.map + (fun (tag, Lazy_storage_kind.Ex_Kind k) -> + let ops = get_ops k in + let (module OPS) = ops in + let title = OPS.title in + case + (Tag tag) + ~title + (obj3 + (req "kind" (constant title)) + (req "id" OPS.Id.encoding) + (req "diff" (diff_encoding ops))) + (fun (Item (kind, id, diff)) -> + match Lazy_storage_kind.equal k kind with + | Eq -> Some ((), id, diff) + | Neq -> None) + (fun ((), id, diff) -> Item (k, id, diff))) + Lazy_storage_kind.all + [@@coq_axiom_with_reason "gadt"] + +let item_in_memory_size + (Item + ( kind + (* kinds are constant tags *), + _id_is_a_Z_fitting_in_an_int_for_a_long_time, + diff )) = + let open Cache_memory_helpers in + ret_adding (diff_in_memory_size kind diff) h3w + +type diffs = diffs_item list + +let diffs_in_memory_size diffs = + Cache_memory_helpers.list_fold_size item_in_memory_size diffs + +let encoding = + let open Data_encoding in + def "lazy_storage_diff" @@ list item_encoding + +let apply ctxt diffs = + List.fold_left_es + (fun (ctxt, total_size) (Item (k, id, diff)) -> + let ops = get_ops k in + apply_diff ctxt ops ~id diff >|=? fun (ctxt, added_size) -> + let (module OPS) = ops in + ( ctxt, + if OPS.Id.is_temp id then total_size else Z.add total_size added_size )) + (ctxt, Z.zero) + diffs + +let fresh : + type i a u. + (i, a, u) Lazy_storage_kind.t -> + temporary:bool -> + Raw_context.t -> + (Raw_context.t * i) tzresult Lwt.t = + fun kind ~temporary ctxt -> + if temporary then + return + (Raw_context.fold_map_temporary_lazy_storage_ids ctxt (fun temp_ids -> + Lazy_storage_kind.Temp_ids.fresh kind temp_ids)) + else + let (module OPS) = get_ops kind in + OPS.Next.incr ctxt + [@@coq_axiom_with_reason "gadt"] + +let init ctxt = + List.fold_left_es + (fun ctxt (_tag, Lazy_storage_kind.Ex_Kind k) -> + let (module OPS) = get_ops k in + OPS.Next.init ctxt) + ctxt + Lazy_storage_kind.all + [@@coq_axiom_with_reason "gadt"] + +let cleanup_temporaries ctxt = + Raw_context.map_temporary_lazy_storage_ids_s ctxt (fun temp_ids -> + List.fold_left_s + (fun ctxt (_tag, Lazy_storage_kind.Ex_Kind k) -> + let (module OPS) = get_ops k in + Lazy_storage_kind.Temp_ids.fold_s k OPS.remove temp_ids ctxt) + ctxt + Lazy_storage_kind.all + >|= fun ctxt -> (ctxt, Lazy_storage_kind.Temp_ids.init)) + [@@coq_axiom_with_reason "gadt"] diff --git a/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_diff.mli b/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_diff.mli new file mode 100644 index 000000000000..17637213d75b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_diff.mli @@ -0,0 +1,71 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining 'a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** + See [Lazy_storage_kind] for an introduction on lazy storage. + + This module defines operations on lazy storage types and diffs. +*) + +type ('id, 'alloc) init = Existing | Copy of {src : 'id} | Alloc of 'alloc + +type ('id, 'alloc, 'updates) diff = + | Remove + | Update of {init : ('id, 'alloc) init; updates : 'updates} + +(* Exposing this type is needed only for legacy big map diff. *) +type diffs_item = private + | Item : + ('i, 'a, 'u) Lazy_storage_kind.t * 'i * ('i, 'a, 'u) diff + -> diffs_item + +val make : + ('i, 'a, 'u) Lazy_storage_kind.t -> 'i -> ('i, 'a, 'u) diff -> diffs_item + +type diffs = diffs_item list + +val diffs_in_memory_size : diffs -> Cache_memory_helpers.nodes_and_size + +val encoding : diffs Data_encoding.t + +(** + The returned [Z.t] is the size added by the application of the diffs. +*) +val apply : Raw_context.t -> diffs -> (Raw_context.t * Z.t) tzresult Lwt.t + +val fresh : + ('id, _, _) Lazy_storage_kind.t -> + temporary:bool -> + Raw_context.t -> + (Raw_context.t * 'id) tzresult Lwt.t + +(** + Initializes the storage for all lazy storage kind. + This is useful for genesis only. + Protocol updates need to initialize new lazy storage kinds. +*) +val init : Raw_context.t -> Raw_context.t tzresult Lwt.t + +val cleanup_temporaries : Raw_context.t -> Raw_context.t Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_kind.ml b/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_kind.ml new file mode 100644 index 000000000000..799e55e047f7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_kind.ml @@ -0,0 +1,325 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type TEMP_ID = sig + type t + + val equal : t -> t -> bool + + val init : t + + val next : t -> t +end + +module type ID = sig + type t + + val compare : t -> t -> int + + val encoding : t Data_encoding.t + + val rpc_arg : t RPC_arg.arg + + val init : t + + (** In the protocol, to be used in parse_data only *) + val parse_z : Z.t -> t + + (** In the protocol, to be used in unparse_data only *) + val unparse_to_z : t -> Z.t + + val next : t -> t + + val is_temp : t -> bool + + val of_legacy_USE_ONLY_IN_Legacy_big_map_diff : Z.t -> t + + val to_legacy_USE_ONLY_IN_Legacy_big_map_diff : t -> Z.t + + include Path_encoding.S with type t := t +end + +module type Title = sig + val title : string +end + +module type TitleWithId = sig + val title : string + + module Id : ID + + module Temp_id : TEMP_ID with type t = private Id.t + + module IdSet : Set.S with type elt = Id.t +end + +module MakeId (Title : Title) : TitleWithId = struct + let title = Title.title + + let title_words = String.map (function '_' -> ' ' | c -> c) title + + let rpc_arg_error = Format.sprintf "Cannot parse %s id" title_words + + let description = Format.sprintf "A %s identifier" title_words + + let name = title ^ "_id" + + let encoding_title = String.capitalize_ascii title_words ^ " identifier" + + module Id = struct + type t = Z.t + + let compare = Z.compare + + let encoding = + Data_encoding.def name ~title:encoding_title ~description Data_encoding.z + + let rpc_arg = + let construct = Z.to_string in + let destruct hash = + Result.catch_f (fun () -> Z.of_string hash) (fun _ -> rpc_arg_error) + in + RPC_arg.make ~descr:description ~name ~construct ~destruct () + + let init = Z.zero + + let parse_z (z : Z.t) : t = z + + let unparse_to_z (z : t) : Z.t = z + + let next = Z.succ + + let of_legacy_USE_ONLY_IN_Legacy_big_map_diff (z : Z.t) : t = z + + let to_legacy_USE_ONLY_IN_Legacy_big_map_diff (z : t) : Z.t = z + + let is_temp z = Compare.Z.(z < Z.zero) + + let path_length = 1 + + let to_path z l = Z.to_string z :: l + + let of_path = function + | [] | _ :: _ :: _ -> None + | [z] -> Some (Z.of_string z) + end + + module Temp_id = struct + type t = Id.t + + let equal = Z.equal + + let init = Z.of_int ~-1 + + let next z = Z.sub z Z.one + end + + module IdSet = Set.Make (Id) +end + +module Big_map = struct + include MakeId (struct + let title = "big_map" + end) + + type alloc = {key_type : Script_repr.expr; value_type : Script_repr.expr} + + type update = { + key : Script_repr.expr; + (** The key is ignored by [apply_update] but is shown in the receipt, + as specified in [print_big_map_diff]. *) + key_hash : Script_expr_hash.t; + value : Script_repr.expr option; + } + + type updates = update list + + let alloc_encoding = + let open Data_encoding in + conv + (fun {key_type; value_type} -> (key_type, value_type)) + (fun (key_type, value_type) -> {key_type; value_type}) + (obj2 + (req "key_type" Script_repr.expr_encoding) + (req "value_type" Script_repr.expr_encoding)) + + let update_encoding = + let open Data_encoding in + conv + (fun {key_hash; key; value} -> (key_hash, key, value)) + (fun (key_hash, key, value) -> {key_hash; key; value}) + (obj3 + (req "key_hash" Script_expr_hash.encoding) + (req "key" Script_repr.expr_encoding) + (opt "value" Script_repr.expr_encoding)) + + let updates_encoding = Data_encoding.list update_encoding +end + +module Sapling_state = struct + include MakeId (struct + let title = "sapling_state" + end) + + type alloc = {memo_size : Sapling_repr.Memo_size.t} + + type updates = Sapling_repr.diff + + let alloc_encoding = + let open Data_encoding in + conv + (fun {memo_size} -> memo_size) + (fun memo_size -> {memo_size}) + (obj1 (req "memo_size" Sapling_repr.Memo_size.encoding)) + + let updates_encoding = Sapling_repr.diff_encoding +end + +(* + When adding cases to this type, grep for [new lazy storage kind] in the code + for locations to update. + It must be: + - the value [all] right below, + - modules [Temp_ids], [IdSet] below, + - the rest should be guided by type errors. +*) +type ('id, 'alloc, 'updates) t = + | Big_map : (Big_map.Id.t, Big_map.alloc, Big_map.updates) t + | Sapling_state + : (Sapling_state.Id.t, Sapling_state.alloc, Sapling_state.updates) t + +type ex = Ex_Kind : (_, _, _) t -> ex + +(* /!\ Don't forget to add new lazy storage kinds here. /!\ *) +let all = [(0, Ex_Kind Big_map); (1, Ex_Kind Sapling_state)] + +type (_, _) cmp = Eq : ('a, 'a) cmp | Neq + +let equal : + type i1 a1 u1 i2 a2 u2. + (i1, a1, u1) t -> (i2, a2, u2) t -> (i1 * a1 * u1, i2 * a2 * u2) cmp = + fun k1 k2 -> + match (k1, k2) with + | (Big_map, Big_map) -> Eq + | (Sapling_state, Sapling_state) -> Eq + | (Big_map, _) -> Neq + | (_, Big_map) -> Neq + +type ('i, 'a, 'u) kind = ('i, 'a, 'u) t + +module Temp_ids = struct + type t = { + big_map : Big_map.Temp_id.t; + sapling_state : Sapling_state.Temp_id.t; + } + + let init = + {big_map = Big_map.Temp_id.init; sapling_state = Sapling_state.Temp_id.init} + + let fresh : type i a u. (i, a, u) kind -> t -> t * i = + fun kind temp_ids -> + match kind with + | Big_map -> + let big_map = Big_map.Temp_id.next temp_ids.big_map in + ({temp_ids with big_map}, (temp_ids.big_map :> Big_map.Id.t)) + | Sapling_state -> + let sapling_state = Sapling_state.Temp_id.next temp_ids.sapling_state in + ( {temp_ids with sapling_state}, + (temp_ids.sapling_state :> Sapling_state.Id.t) ) + [@@coq_axiom_with_reason "gadt"] + + let fold_s : + type i a u. + (i, a, u) kind -> ('acc -> i -> 'acc Lwt.t) -> t -> 'acc -> 'acc Lwt.t = + fun kind f temp_ids acc -> + let helper (type j) (module Temp_id : TEMP_ID with type t = j) ~last f = + let rec aux acc id = + if Temp_id.equal id last then Lwt.return acc + else f acc id >>= fun acc -> aux acc (Temp_id.next id) + in + aux acc Temp_id.init + in + match kind with + | Big_map -> + helper + (module Big_map.Temp_id) + ~last:temp_ids.big_map + (fun acc temp_id -> f acc (temp_id :> i)) + | Sapling_state -> + helper + (module Sapling_state.Temp_id) + ~last:temp_ids.sapling_state + (fun acc temp_id -> f acc (temp_id :> i)) + [@@coq_axiom_with_reason "gadt"] +end + +module IdSet = struct + type t = {big_map : Big_map.IdSet.t; sapling_state : Sapling_state.IdSet.t} + + type 'acc fold_f = {f : 'i 'a 'u. ('i, 'a, 'u) kind -> 'i -> 'acc -> 'acc} + + let empty = + {big_map = Big_map.IdSet.empty; sapling_state = Sapling_state.IdSet.empty} + + let mem (type i a u) (kind : (i, a, u) kind) (id : i) set = + match (kind, set) with + | (Big_map, {big_map; _}) -> Big_map.IdSet.mem id big_map + | (Sapling_state, {sapling_state; _}) -> + Sapling_state.IdSet.mem id sapling_state + [@@coq_axiom_with_reason "gadt"] + + let add (type i a u) (kind : (i, a, u) kind) (id : i) set = + match (kind, set) with + | (Big_map, {big_map; _}) -> + let big_map = Big_map.IdSet.add id big_map in + {set with big_map} + | (Sapling_state, {sapling_state; _}) -> + let sapling_state = Sapling_state.IdSet.add id sapling_state in + {set with sapling_state} + [@@coq_axiom_with_reason "gadt"] + + let diff set1 set2 = + let big_map = Big_map.IdSet.diff set1.big_map set2.big_map in + let sapling_state = + Sapling_state.IdSet.diff set1.sapling_state set2.sapling_state + in + {big_map; sapling_state} + [@@coq_axiom_with_reason "gadt"] + + let fold (type i a u) (kind : (i, a, u) kind) (f : i -> 'acc -> 'acc) set + (acc : 'acc) = + match (kind, set) with + | (Big_map, {big_map; _}) -> Big_map.IdSet.fold f big_map acc + | (Sapling_state, {sapling_state; _}) -> + Sapling_state.IdSet.fold f sapling_state acc + [@@coq_axiom_with_reason "gadt"] + + let fold_all f set acc = + List.fold_left + (fun acc (_, Ex_Kind kind) -> fold kind (f.f kind) set acc) + acc + all + [@@coq_axiom_with_reason "gadt"] +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_kind.mli b/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_kind.mli new file mode 100644 index 000000000000..eb23fb9545ad --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/lazy_storage_kind.mli @@ -0,0 +1,178 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** + Lazy_storage offers a unified interface for specific Michelson datatype that + behave somewhat lazily, because they are intended to be quite big. + Instead of serializing/deserializing the whole value to/from the storage, + only an identifier is used. The identifier acts like a pointer. + When using the value in a Michelson script, some part of it may be read from + the storage, and a lightweight diff is computed. + The diff is effectively applied to the storage at the end of the execution. + + This module defines the different kinds of lazy storages and their basic + properties. See also [Lazy_storage_diff]. + + Lazy storage types are: + - Big_map +*) + +(** + Lazy storage ids are kept as abstract as possible to avoid mixing them up. + + Behind the scene they are [Z.t]s but, within the protocol, only [parse_data]/ + [unparse_data] are allowed convert from/to it. + + Temporary ids may be used to pass values between contracts that won't be kept + longer than the lifetime of the operation. + Behind the scene, temporary ids are negative [Z.t]s. +*) +module type ID = sig + type t + + val compare : t -> t -> int + + val encoding : t Data_encoding.t + + val rpc_arg : t RPC_arg.arg + + (** Initial value for ids: zero. *) + val init : t + + (** In the protocol, to be used in parse_data only *) + val parse_z : Z.t -> t + + (** In the protocol, to be used in unparse_data only *) + val unparse_to_z : t -> Z.t + + val next : t -> t + + val is_temp : t -> bool + + (* To be removed once legacy big map diff is removed: *) + + val of_legacy_USE_ONLY_IN_Legacy_big_map_diff : Z.t -> t + + val to_legacy_USE_ONLY_IN_Legacy_big_map_diff : t -> Z.t + + (* To be used in storage: *) + + include Path_encoding.S with type t := t +end + +module Big_map : sig + val title : string + + module Id : ID + + type alloc = {key_type : Script_repr.expr; value_type : Script_repr.expr} + + type update = { + key : Script_repr.expr; + (** The key is ignored by [apply_update] but is shown in the receipt, + as specified in [print_big_map_diff]. *) + key_hash : Script_expr_hash.t; + value : Script_repr.expr option; + } + + type updates = update list + + val alloc_encoding : alloc Data_encoding.t + + val updates_encoding : updates Data_encoding.t +end + +module Sapling_state : sig + val title : string + + module Id : ID + + type alloc = {memo_size : Sapling_repr.Memo_size.t} + + type updates = Sapling_repr.diff + + val alloc_encoding : alloc Data_encoding.t + + val updates_encoding : updates Data_encoding.t +end + +(** + Kinds of lazy storage. + The GADT ensures operations are properly applied to the correct kind. + + ['id] the abstract type for the identifier of the kind. + ['alloc] is the type used to construct a new value. + ['updates] is the type used to update a value. +*) +type ('id, 'alloc, 'updates) t = + | Big_map : (Big_map.Id.t, Big_map.alloc, Big_map.updates) t + | Sapling_state + : (Sapling_state.Id.t, Sapling_state.alloc, Sapling_state.updates) t + +type ex = Ex_Kind : (_, _, _) t -> ex + +val all : (int * ex) list + +type (_, _) cmp = Eq : ('a, 'a) cmp | Neq + +val equal : + ('i1, 'a1, 'u1) t -> + ('i2, 'a2, 'u2) t -> + ('i1 * 'a1 * 'u1, 'i2 * 'a2 * 'u2) cmp + +type ('i, 'a, 'u) kind = ('i, 'a, 'u) t + +(** + Type to manage temporary ids. + Used only in the context. +*) +module Temp_ids : sig + type t + + val init : t + + val fresh : ('i, 'a, 'u) kind -> t -> t * 'i + + val fold_s : + ('i, 'a, 'u) kind -> ('acc -> 'i -> 'acc Lwt.t) -> t -> 'acc -> 'acc Lwt.t +end + +module IdSet : sig + type t + + type 'acc fold_f = {f : 'i 'a 'u. ('i, 'a, 'u) kind -> 'i -> 'acc -> 'acc} + + val empty : t + + val mem : ('i, 'a, 'u) kind -> 'i -> t -> bool + + val add : ('i, 'a, 'u) kind -> 'i -> t -> t + + val diff : t -> t -> t + + val fold : ('i, 'a, 'u) kind -> ('i -> 'acc -> 'acc) -> t -> 'acc -> 'acc + + val fold_all : 'acc fold_f -> t -> 'acc -> 'acc +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/level_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/level_repr.ml new file mode 100644 index 000000000000..3ad6794c55ff --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/level_repr.ml @@ -0,0 +1,336 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = { + level : Raw_level_repr.t; + level_position : int32; + cycle : Cycle_repr.t; + cycle_position : int32; + expected_commitment : bool; +} + +include Compare.Make (struct + type nonrec t = t + + let compare {level = l1; _} {level = l2; _} = Raw_level_repr.compare l1 l2 +end) + +type level = t + +let pp ppf {level; _} = Raw_level_repr.pp ppf level + +let pp_full ppf l = + Format.fprintf + ppf + "%a.%ld (cycle %a.%ld)" + Raw_level_repr.pp + l.level + l.level_position + Cycle_repr.pp + l.cycle + l.cycle_position + +let encoding = + let open Data_encoding in + conv + (fun {level; level_position; cycle; cycle_position; expected_commitment} -> + (level, level_position, cycle, cycle_position, expected_commitment)) + (fun (level, level_position, cycle, cycle_position, expected_commitment) -> + {level; level_position; cycle; cycle_position; expected_commitment}) + (obj5 + (req + "level" + ~description: + "The level of the block relative to genesis. This is also the \ + Shell's notion of level." + Raw_level_repr.encoding) + (req + "level_position" + ~description: + "The level of the block relative to the successor of the genesis \ + block. More precisely, it is the position of the block relative \ + to the block that starts the \"Alpha family\" of protocols, which \ + includes all protocols except Genesis (that is, from 001 \ + onwards)." + int32) + (req + "cycle" + ~description: + "The current cycle's number. Note that cycles are a \ + protocol-specific notion. As a result, the cycle number starts at \ + 0 with the first block of the Alpha family of protocols." + Cycle_repr.encoding) + (req + "cycle_position" + ~description: + "The current level of the block relative to the first block of the \ + current cycle." + int32) + (req + "expected_commitment" + ~description: + "Tells whether the baker of this block has to commit a seed nonce \ + hash." + bool)) + +let diff {level = l1; _} {level = l2; _} = + Int32.sub (Raw_level_repr.to_int32 l1) (Raw_level_repr.to_int32 l2) + +type cycle_era = { + first_level : Raw_level_repr.t; + first_cycle : Cycle_repr.t; + blocks_per_cycle : int32; + blocks_per_commitment : int32; +} + +type cycle_eras = cycle_era list + +type error += Invalid_cycle_eras + +let () = + register_error_kind + `Temporary + ~id:"level_repr.invalid_cycle_eras" + ~title:"Invalid cycle eras" + ~description: + "The cycles eras are not valid: empty list or non-decreasing first \ + levels or first cycles." + ~pp:(fun ppf () -> + Format.fprintf + ppf + "The cycles eras are not valid: empty list or non-decreasing first \ + levels or first cycles.") + Data_encoding.empty + (function Invalid_cycle_eras -> Some () | _ -> None) + (fun () -> Invalid_cycle_eras) + +let create_cycle_eras cycle_eras = + match cycle_eras with + | [] -> error Invalid_cycle_eras + | newest_era :: older_eras -> + let rec aux {first_level; first_cycle; _} older_eras = + match older_eras with + | ({ + first_level = first_level_of_previous_era; + first_cycle = first_cycle_of_previous_era; + _; + } as previous_era) + :: even_older_eras -> + if + Raw_level_repr.(first_level > first_level_of_previous_era) + && Cycle_repr.(first_cycle > first_cycle_of_previous_era) + then aux previous_era even_older_eras + else error Invalid_cycle_eras + | [] -> ok () + in + aux newest_era older_eras >>? fun () -> ok cycle_eras + +let cycle_era_encoding = + let open Data_encoding in + conv + (fun {first_level; first_cycle; blocks_per_cycle; blocks_per_commitment} -> + (first_level, first_cycle, blocks_per_cycle, blocks_per_commitment)) + (fun (first_level, first_cycle, blocks_per_cycle, blocks_per_commitment) -> + {first_level; first_cycle; blocks_per_cycle; blocks_per_commitment}) + (obj4 + (req + "first_level" + ~description:"The first level of a new cycle era." + Raw_level_repr.encoding) + (req + "first_cycle" + ~description:"The first cycle of a new cycle era." + Cycle_repr.encoding) + (req + "blocks_per_cycle" + ~description: + "The value of the blocks_per_cycle constant used during the cycle \ + era starting with first_level." + int32) + (req + "blocks_per_commitment" + ~description: + "The value of the blocks_per_commitment constant used during the \ + cycle era starting with first_level." + int32)) + +let cycle_eras_encoding = + Data_encoding.conv_with_guard + (fun eras -> eras) + (fun eras -> + match create_cycle_eras eras with + | Ok eras -> Ok eras + | Error _ -> Error "Invalid cycle eras") + (Data_encoding.list cycle_era_encoding) + +let current_era = function [] -> assert false | cycle_era :: _ -> cycle_era + +let root_level cycle_eras = + let first_era = List.last_opt cycle_eras in + let first_era = + match first_era with + | Some first_era -> first_era + | None -> + (* {!create_cycle_eras} fails if the list is empty. + {!cycle_eras_encoding} uses {!create_cycle_eras} and so fails on empty + lists too. *) + assert false + in + { + level = first_era.first_level; + level_position = 0l; + cycle = Cycle_repr.root; + cycle_position = 0l; + expected_commitment = false; + } + +(* This function returns the cycle era to which [level] belongs. *) +let era_of_level ~cycle_eras level = + let rec aux = function + | ({first_level; _} as era) :: previous_eras -> + if Raw_level_repr.(level >= first_level) then era else aux previous_eras + | [] -> assert false + in + aux cycle_eras + +(* This function returns the cycle era to which [cycle] belongs. *) +let era_of_cycle ~cycle_eras cycle = + let rec aux = function + | ({first_cycle; _} as era) :: previous_eras -> + if Cycle_repr.(cycle >= first_cycle) then era else aux previous_eras + | [] -> assert false + in + aux cycle_eras + +(* precondition: [level] belongs to [era] *) +let level_from_raw_with_era era ~first_level_in_alpha_family level = + let {first_level; first_cycle; blocks_per_cycle; blocks_per_commitment} = + era + in + let level_position_in_era = Raw_level_repr.diff level first_level in + assert (Compare.Int32.(level_position_in_era >= 0l)) ; + let cycles_since_era_start = + Int32.div level_position_in_era blocks_per_cycle + in + let cycle = + Cycle_repr.add first_cycle (Int32.to_int cycles_since_era_start) + in + let cycle_position = Int32.rem level_position_in_era blocks_per_cycle in + let level_position = Raw_level_repr.diff level first_level_in_alpha_family in + let expected_commitment = + Compare.Int32.( + Int32.rem cycle_position blocks_per_commitment + = Int32.pred blocks_per_commitment) + in + {level; level_position; cycle; cycle_position; expected_commitment} + +let level_from_raw_aux_exn ~cycle_eras level = + let first_level_in_alpha_family = + match List.rev cycle_eras with + | [] -> assert false + | {first_level; _} :: _ -> first_level + in + let era = era_of_level ~cycle_eras level in + level_from_raw_with_era era ~first_level_in_alpha_family level + +let from_raw ~cycle_eras l = level_from_raw_aux_exn ~cycle_eras l + +type error += Level_not_in_alpha of Raw_level_repr.t + +let () = + register_error_kind + `Permanent + ~id:"level_not_in_alpha" + ~title:"Level not in Alpha family" + ~description:"Level not in Alpha family" + ~pp:(fun ppf level -> + Format.fprintf + ppf + "Level %a is not in the Alpha family of protocols." + Raw_level_repr.pp + level) + Data_encoding.(obj1 (req "level" Raw_level_repr.encoding)) + (function Level_not_in_alpha level -> Some level | _ -> None) + (fun level -> Level_not_in_alpha level) + +let level_from_raw_aux ~cycle_eras level = + let first_level_in_alpha_family = + match List.rev cycle_eras with + | [] -> assert false + | {first_level; _} :: _ -> first_level + in + error_when + Raw_level_repr.(level < first_level_in_alpha_family) + (Level_not_in_alpha level) + >|? fun () -> + let era = era_of_level ~cycle_eras level in + level_from_raw_with_era era ~first_level_in_alpha_family level + +type error += Negative_level_and_offset_sum of int32 * int32 + +let () = + register_error_kind + `Permanent + ~id:"negative_level_and_offset_sum" + ~title:"Negative sum of level and offset" + ~description:"Negative sum of level and offset" + ~pp:(fun ppf (level, offset) -> + Format.fprintf + ppf + "Sum of level (%ld) and offset (%ld) is negative." + level + offset) + Data_encoding.(obj2 (req "level" int32) (req "offset" int32)) + (function + | Negative_level_and_offset_sum (level, offset) -> Some (level, offset) + | _ -> None) + (fun (level, offset) -> Negative_level_and_offset_sum (level, offset)) + +let from_raw_with_offset ~cycle_eras ~offset raw_level = + let res = Raw_level_repr.(of_int32 (Int32.add (to_int32 raw_level) offset)) in + match res with + | Ok level -> level_from_raw_aux ~cycle_eras level + | Error _ -> + error + (Negative_level_and_offset_sum + (Raw_level_repr.to_int32 raw_level, offset)) + +let first_level_in_cycle_from_eras ~cycle_eras cycle = + let first_level_in_alpha_family = + match List.rev cycle_eras with + | [] -> assert false + | {first_level; _} :: _ -> first_level + in + let era = era_of_cycle ~cycle_eras cycle in + let cycle_position = Cycle_repr.diff cycle era.first_cycle in + let offset = Int32.mul era.blocks_per_cycle cycle_position in + let first_level_in_cycle = + Raw_level_repr.(of_int32_exn (Int32.add (to_int32 era.first_level) offset)) + in + level_from_raw_with_era era ~first_level_in_alpha_family first_level_in_cycle + +let last_of_cycle ~cycle_eras level = + let era = era_of_level ~cycle_eras level.level in + Compare.Int32.(Int32.succ level.cycle_position = era.blocks_per_cycle) diff --git a/src/proto_012_PsiThaCa/lib_protocol/level_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/level_repr.mli new file mode 100644 index 000000000000..16e335b8f168 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/level_repr.mli @@ -0,0 +1,115 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module defines the protocol representation of a level. Besides the "raw + level", which is the shell's notion of the level, this representation also + contains additional information, like the cycle the level belongs to. *) + +type t = private { + level : Raw_level_repr.t; + (** The level of the block relative to genesis. This + is also the Shell's notion of level. *) + level_position : int32; + (** The level of the block relative to the block that starts the + alpha family of protocols. *) + cycle : Cycle_repr.t; + (** The current cycle's number. Note that cycles are a protocol-specific + notion. As a result, the cycle number starts at 0 with the first block of + the first version of protocol alpha. *) + cycle_position : int32; + (** The current level of the block relative to the first block of the current + cycle. *) + expected_commitment : bool; +} + +type level = t + +include Compare.S with type t := level + +val encoding : level Data_encoding.t + +val pp : Format.formatter -> level -> unit + +val pp_full : Format.formatter -> level -> unit + +val diff : level -> level -> int32 + +(** A cycle era is a chunk of cycles having the same number of levels + per cycle and the same number of blocks per commitment. *) +type cycle_era = { + first_level : Raw_level_repr.t; (** The first level of a cycle era. *) + first_cycle : Cycle_repr.t; (** The first cycle of a cycle era. *) + blocks_per_cycle : int32; + (** The value of the blocks_per_cycle constant used during the cycle + era starting with first_level. *) + blocks_per_commitment : int32; + (** The value of the blocks_per_commitment constant used during the + cycle era starting with first_level. *) +} + +(** Stores the cycles eras of the Alpha family of protocols *) +type cycle_eras + +val cycle_eras_encoding : cycle_eras Data_encoding.t + +(** Preconditions on the input list of cycle eras: + - the list is not empty + - the first levels and the first cycles are decreasing, meaning that the + first era in the list is the current era, and the last era in the list + is the oldest era + Invariants: + - the first era therefore contains the same constants as in Constants + - the first level of an era is the first level of a cycle +*) +val create_cycle_eras : cycle_era list -> cycle_eras tzresult + +(** Returns the current era *) +val current_era : cycle_eras -> cycle_era + +(** Returns the first level of the oldest era *) +val root_level : cycle_eras -> level + +(** Returns the annotated level corresponding to a raw level *) +val from_raw : cycle_eras:cycle_eras -> Raw_level_repr.t -> level + +(** Returns the annotated level corresponding to a raw level and an + offset. A positive offset corresponds to a higher level. + Fails with [Negative_level_and_offset_sum] if the sum of the raw_level and the offset is negative. + Fails with [Level_not_in_alpha] if the sum of the raw_level and the offset + is a level before the first level in the Alpha family of protocols. *) +val from_raw_with_offset : + cycle_eras:cycle_eras -> offset:int32 -> Raw_level_repr.t -> level tzresult + +(** Returns the first level of the given cycle. *) +val first_level_in_cycle_from_eras : + cycle_eras:cycle_eras -> Cycle_repr.t -> level + +(** Returns true if the given level is the last of a cycle. *) +val last_of_cycle : cycle_eras:cycle_eras -> level -> bool + +(**/**) + +(* exported for unit testing only *) +type error += Invalid_cycle_eras diff --git a/src/proto_012_PsiThaCa/lib_protocol/level_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/level_storage.ml new file mode 100644 index 000000000000..cf4fa87d12c4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/level_storage.ml @@ -0,0 +1,122 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Level_repr + +let from_raw c l = + let cycle_eras = Raw_context.cycle_eras c in + Level_repr.from_raw ~cycle_eras l + +let from_raw_with_offset c ~offset l : Level_repr.t tzresult = + let cycle_eras = Raw_context.cycle_eras c in + Level_repr.from_raw_with_offset ~cycle_eras ~offset l + +let root c = Raw_context.cycle_eras c |> Level_repr.root_level + +let succ c (l : Level_repr.t) = from_raw c (Raw_level_repr.succ l.level) + +let pred c (l : Level_repr.t) = + match Raw_level_repr.pred l.Level_repr.level with + | None -> None + | Some l -> Some (from_raw c l) + +let add c (l : Level_repr.t) n = from_raw c (Raw_level_repr.add l.level n) + +let sub c (l : Level_repr.t) n = + match Raw_level_repr.sub l.level n with + | None -> None + | Some raw_level -> + let cycle_eras = Raw_context.cycle_eras c in + let root_level = Level_repr.root_level cycle_eras in + if Raw_level_repr.(raw_level >= root_level.level) then + Some (from_raw c raw_level) + else None + +let current ctxt = Raw_context.current_level ctxt + +let previous ctxt = + let l = current ctxt in + match pred ctxt l with + | None -> assert false (* We never validate the Genesis... *) + | Some p -> p + +let first_level_in_cycle ctxt cycle = + let cycle_eras = Raw_context.cycle_eras ctxt in + Level_repr.first_level_in_cycle_from_eras ~cycle_eras cycle + +let last_level_in_cycle ctxt c = + match pred ctxt (first_level_in_cycle ctxt (Cycle_repr.succ c)) with + | None -> assert false + | Some x -> x + +let levels_in_cycle ctxt cycle = + let first = first_level_in_cycle ctxt cycle in + let[@coq_struct "n"] rec loop (n : Level_repr.t) acc = + if Cycle_repr.(n.cycle = first.cycle) then loop (succ ctxt n) (n :: acc) + else acc + in + loop first [] + +let levels_in_current_cycle ctxt ?(offset = 0l) () = + let current_cycle = Cycle_repr.to_int32 (current ctxt).cycle in + let cycle = Int32.add current_cycle offset in + if Compare.Int32.(cycle < 0l) then [] + else + let cycle = Cycle_repr.of_int32_exn cycle in + levels_in_cycle ctxt cycle + +let levels_with_commitments_in_cycle ctxt c = + let first = first_level_in_cycle ctxt c in + let[@coq_struct "n"] rec loop (n : Level_repr.t) acc = + if Cycle_repr.(n.cycle = first.cycle) then + if n.expected_commitment then loop (succ ctxt n) (n :: acc) + else loop (succ ctxt n) acc + else acc + in + loop first [] + +let last_allowed_fork_level c = + let level = Raw_context.current_level c in + let preserved_cycles = Constants_storage.preserved_cycles c in + match Cycle_repr.sub level.cycle preserved_cycles with + | None -> Raw_level_repr.root + | Some cycle -> (first_level_in_cycle c cycle).level + +let last_of_a_cycle ctxt level = + let cycle_eras = Raw_context.cycle_eras ctxt in + Level_repr.last_of_cycle ~cycle_eras level + +let dawn_of_a_new_cycle ctxt = + let level = current ctxt in + if last_of_a_cycle ctxt level then Some level.cycle else None + +let may_snapshot_rolls ctxt = + let level = current ctxt in + let blocks_per_stake_snapshot = + Constants_storage.blocks_per_stake_snapshot ctxt + in + Compare.Int32.equal + (Int32.rem level.cycle_position blocks_per_stake_snapshot) + (Int32.pred blocks_per_stake_snapshot) diff --git a/src/proto_012_PsiThaCa/lib_protocol/level_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/level_storage.mli new file mode 100644 index 000000000000..aeebe659b64f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/level_storage.mli @@ -0,0 +1,71 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val current : Raw_context.t -> Level_repr.t + +val previous : Raw_context.t -> Level_repr.t + +val root : Raw_context.t -> Level_repr.t + +val from_raw : Raw_context.t -> Raw_level_repr.t -> Level_repr.t + +(** Fails with [Negative_level_and_offset_sum] if the sum of the raw_level and the offset is negative. *) +val from_raw_with_offset : + Raw_context.t -> offset:int32 -> Raw_level_repr.t -> Level_repr.t tzresult + +val pred : Raw_context.t -> Level_repr.t -> Level_repr.t option + +val succ : Raw_context.t -> Level_repr.t -> Level_repr.t + +(** [i] must be positive *) +val add : Raw_context.t -> Level_repr.t -> int -> Level_repr.t + +(** [sub c level i] returns None if the level is before the first + level of the Alpha family of protocol, otherwise it returns the + expected level. [i] must be positive. *) +val sub : Raw_context.t -> Level_repr.t -> int -> Level_repr.t option + +val first_level_in_cycle : Raw_context.t -> Cycle_repr.t -> Level_repr.t + +val last_level_in_cycle : Raw_context.t -> Cycle_repr.t -> Level_repr.t + +val levels_in_cycle : Raw_context.t -> Cycle_repr.t -> Level_repr.t list + +val levels_in_current_cycle : + Raw_context.t -> ?offset:int32 -> unit -> Level_repr.t list + +val levels_with_commitments_in_cycle : + Raw_context.t -> Cycle_repr.t -> Level_repr.t list + +val last_allowed_fork_level : Raw_context.t -> Raw_level_repr.t + +(** Returns [Some cycle] if the current level represents the last + level of [cycle] and [None] if the level is not the last level of a + cycle. *) +val dawn_of_a_new_cycle : Raw_context.t -> Cycle_repr.t option + +(** Returns [true] if the rolls should be snapshot at the current + level. *) +val may_snapshot_rolls : Raw_context.t -> bool diff --git a/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_cpmm.ml b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_cpmm.ml new file mode 100644 index 000000000000..be63503aa883 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_cpmm.ml @@ -0,0 +1,13 @@ +let script_hex : Hex.t = + `Hex + "02000011c405000764076407640865046e00000006256f776e6572076504620000000d256d696e4c71744d696e7465640765046200000013256d6178546f6b656e734465706f7369746564046b0000000925646561646c696e650000000d256164644c6971756964697479046c000000082564656661756c7407640865046e0000000325746f076504620000000a256c71744275726e65640765046a00000010256d696e58747a57697468647261776e0765046200000013256d696e546f6b656e7357697468647261776e046b0000000925646561646c696e65000000102572656d6f76654c69717569646974790865046e00000015256f7574707574446578746572436f6e74726163740765046200000010256d696e546f6b656e73426f756768740765046e0000000325746f076504620000000b25746f6b656e73536f6c64046b0000000925646561646c696e650000000d25746f6b656e546f546f6b656e07640865046e0000000325746f076504620000000b25746f6b656e73536f6c640765046a0000000d256d696e58747a426f75676874046b0000000925646561646c696e650000000b25746f6b656e546f58747a0865046e0000000325746f0765046200000010256d696e546f6b656e73426f75676874046b0000000925646561646c696e650000000b2578747a546f546f6b656e0501076504620000000a25746f6b656e506f6f6c0765046a000000082578747a506f6f6c0765046200000009256c7174546f74616c0765046e0000000d25746f6b656e41646472657373046e0000000b256c71744164647265737305020200000f7203210317034c0316072e02000009d1072e020000035a072e020000032603210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200004074303620003032702000002ea0743036a000105700004032105710005031703160322072f0200000013074303680100000008444956206279203003270200000000031603130743036a0001034c0322072f02000000130743036801000000084449562062792030032702000000000316034c0321057100020570000603210571000703170317031605700002032105710003033a0322072f020000001307430368010000000844495620627920300327020000000003160570000205700006032105710007031605700003033a0322072f020000001307430368010000000844495620627920300327020000002a03210317034c03160743036200000570000203190325072c02000000000200000008074303620001031205700002034c0321057100020319032a072c020000000c05200005074303620004032702000001b60571000203210571000303190337072c020000000c0520000407430362000503270200000190057000030321057100040317031703170570000203210571000305700005032105710006031703170316031203420570000403210571000503170316034205700004032105710005031603420317034c032105710002057000050321057100060316031203420321031703170313057000060317031603120342034c03160342034c03490354034203480342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d05700002033005700003034205700002032105710003034c03210317034c031605700002031703170317031706550765045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e072f020000000807430362000c032702000000000743036a000005700002057000030342034d05700002053d036d05700002031b05700002031b0342020000002803200321031703170313057000020321057100030317031603120342034c03160342053d036d0342020000066b072e020000038d03210317034c0316034c03210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200005074303620003032702000003470743036a000003130319032a072c020000000c0520000507430362000a03270200000323057000040321057100050317031703160743036a000105700006032105710007031703160322072f0200000013074303680100000008444956206279203003270200000000031605700004032105710005033a0322072f020000001307430368010000000844495620627920300327020000000003160743036a0001034c033a0570000503210571000603170317031605700006032105710007031605700005032105710006033a0322072f02000000130743036801000000084449562062792030032702000000000316057000030570000203210571000303190337072c020000000c0520000607430362000b0327020000022e05700002034c03210571000203190337072c020000000c0520000507430362000d032702000002060570000203210571000305700005032105710006031703170316034b0356072f020000000807430362000e03270200000000034c032105710002057000060321057100070316034b0356072f020000000807430362000f03270200000000057000040743035b0000034b0348034205700006032105710007034c03210317034c031605700002031703170317031706550765045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e072f020000000807430362000c032702000000000743036a000005700002057000030342034d0570000305700005032105710006034203490354034205700006032105710007034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d05700004032105710005057000060555036c072f020000000807430362000903270200000000034c0743036c030b034d0570000603210571000703170317057000060570000703210571000803170316034b034205700006031603420321031703170317057000060342034c032105710002031703160342034c031603420317057000040342053d036d05700002031b05700002031b05700002031b034202000002d203210317034c0316034c03210317034c0316034c03210317034c0316034c03210317034c03160570000406550765046e0000000325746f0765046200000010256d696e546f6b656e73426f75676874046b0000000925646561646c696e650000000b2578747a546f546f6b656e072f020000000807430362001f032702000000000743036a000003130319032a072c020000000c0520000607430362000a0327020000022d05700002032105710003034003190328072c020000000c05200006074303620003032702000002050743036200a70f05700002032105710003033a0743036200a80f057000070321057100080316033a031205700006032105710007031703160743036200a70f05700004032105710005033a033a0322072f020000001307430368010000000844495620627920300327020000000003160743036200a80f0743036200a70f05700002032105710003033a0322072f02000000130743036801000000084449562062792030032702000000000316057000070321057100080317057000040321057100050570000903210571000a031603120342032103170317057000030321057100040570000a03170316034b0342034c031603420570000403490354034203480342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d057000040570000303210571000405700006057000080342057000070342034d0570000305700004034b0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d05700003053d036d05700002031b05700002031b05700002031b0342020000058d072e02000002cc03210317034c0316034c03210317034c0316034c03210317034c0316034c034003190328072c020000000c05200004074303620003032702000002900743036a000003130319032a072c020000000c0520000407430362000a0327020000026c0743036200a70f05700002032105710003033a0743036200a80f057000050321057100060316033a03120743036a000105700005032105710006031703160322072f020000001307430368010000000844495620627920300327020000000003160743036200a70f05700004032105710005033a033a0322072f020000001307430368010000000844495620627920300327020000000003160743036a0001034c033a0743036200a80f0743036200a70f05700002032105710003033a0322072f0200000013074303680100000008444956206279203003270200000000031605700002034c03210571000203190337072c020000000a032007430362000803270200000000057000020321057100030349035403420348034205700005032105710006034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d034c032105710002057000050555036c072f020000000807430362000903270200000000034c0743036c030b034d0570000503210571000603170570000505700006032105710007031603120342032103170317057000050321057100060570000703170316034b0342034c031603420570000305700004034b0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d034c053d036d05700002031b05700002031b05700002031b034202000002b503210317034c0316034c03210317034c0316034c034003190328072c020000000c05200003074303620003032702000002830743036a000105700003032105710004031703160322072f0200000013074303680100000008444956206279203003270200000000031603130743036a0001034c0322072f020000001307430368010000000844495620627920300327020000000003160743036200a80f0743036200a70f05700002032105710003033a0322072f02000000130743036801000000084449562062792030032702000000000316032105700002034b03110743036200a70f05700002032105710003033a0743036200a80f05700004033a03120570000503210571000603160743036200a70f05700004032105710005033a033a0322072f0200000013074303680100000008444956206279203003270200000000031605700003034c03210571000203190337072c020000000a0320074303620012032702000000000321057000050321057100060316034b0356072f02000000080743036200130327020000000005700005032105710006031703170743036a000105700005033a05700006032105710007031703160312034205700005031603420317034c0342034c057000030342034903540342034c032105710002034c03210317034c0316034c03210317034c031605700003031703170317031606550765036e0765036e036200000009257472616e73666572072f0200000008074303620000032702000000000743036a000005700003057000030342057000030342034d0743036a000105700003033a0743036e0100000024747a314b65326837734464616b484a5168385758345a3337326475314b4368736b7379550555036c072f020000000807430362000903270200000000034c0743036c030b034d05700002053d036d05700002031b05700002031b0342" + +let script_bytes : Bytes.t option = Hex.to_bytes script_hex + +let script_opt : Script_repr.expr option = + Option.bind + script_bytes + (Data_encoding.Binary.of_bytes_opt Script_repr.expr_encoding) + +let script : Script_repr.expr = + Option.value_f ~default:(fun () -> assert false) script_opt diff --git a/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_lqt.ml b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_lqt.ml new file mode 100644 index 000000000000..80c92e523d0f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_lqt.ml @@ -0,0 +1,13 @@ +let script_hex : Hex.t = + `Hex + "020000070005000764076407640865046e00000008257370656e6465720462000000062576616c75650000000825617070726f766508650865046e00000006256f776e6572046e00000008257370656e646572000000082572657175657374065a0362000000092563616c6c6261636b0000000d25676574416c6c6f77616e636507640865046e00000006256f776e6572065a0362000000092563616c6c6261636b0000000b2567657442616c616e63650865046c000000082572657175657374065a0362000000092563616c6c6261636b0000000f25676574546f74616c537570706c7907640865045b00000009257175616e74697479046e00000007257461726765740000000b256d696e744f724275726e0865046e000000052566726f6d0765046e0000000325746f0462000000062576616c756500000009257472616e73666572050107650861036e03620000000725746f6b656e73076508610765046e00000006256f776e6572046e00000008257370656e64657203620000000b25616c6c6f77616e6365730765046e000000062561646d696e04620000000d25746f74616c5f737570706c7905020200000552032103170743036a000003130319033c072c020000001607430368010000000b446f6e7453656e6454657a03270200000000034c0316072e02000001b2072e0200000132072e02000000e2034c03210571000203170316034c0321057100020316034803420743036200000570000303210571000403170319032a07430362000005700003032105710004057000030321057100040329072f020000000607430362000002000000000319032a0314072c0200000020074303680100000015556e73616665416c6c6f77616e63654368616e676503270200000000057000030321057100040317031705700002057000030317074303620000034c03210571000203190325072c02000000060320053e0362020000000203460570000303500342034c03160342053d036d03420200000044034c032105700002053d036d034c03210571000203170743036a000005700004031703160570000403160329072f02000000060743036200000200000000034d031b03420200000074072e0200000042034c032105700002053d036d034c03210571000203170743036a00000570000403160570000403160329072f02000000060743036200000200000000034d031b03420200000026034c032105700002053d036d034c03170743036a000005700003031703170317034d031b0342020000035e072e020000013c034c03210571000203170317031603480319033c072c02000000140743036801000000094f6e6c7941646d696e03270200000000032103160570000203210571000303160570000203210571000303170329072f0200000006074303620000020000000003120356072f020000003607430368010000002b43616e6e6f74206275726e206d6f7265207468616e207468652074617267657427732062616c616e63652e03270200000000034c032105710002031605700003032105710004031703170317031203110570000303210571000403170570000403160743036200000570000403210571000503190325072c020000000a057000030320053e03620200000006057000030346057000040317035003420321057100020317031703160342034c032105710002031703160342034c03160342053d036d03420200000216034c03210571000203170316057000020321057100030316057000020321057100030316034803190325072c0200000002034c02000000a903480570000303210571000403160342057000030321057100040317031705700003032105710004057000020321057100030329072f02000000060743036200000200000000034b0356072f020000001d0743036801000000124e6f74456e6f756768416c6c6f77616e636503270200000000057000030743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c03460570000203500570000203210571000303170317057000020321057100030570000403210571000503160329072f02000000060743036200000200000000034b0356072f020000001b0743036801000000104e6f74456e6f75676842616c616e636503270200000000057000020743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c034605700003032105710004031603500570000203210571000303170317034c03210571000205700004032105710005031703160329072f020000000607430362000002000000000312034c0743036200000570000203210571000303190325072c0200000008034c0320053e03620200000004034c034605700003031703160350057000020317034c0342032103170317057000020342034c03160342053d036d0342" + +let script_bytes : Bytes.t option = Hex.to_bytes script_hex + +let script_opt : Script_repr.expr option = + Option.bind + script_bytes + (Data_encoding.Binary.of_bytes_opt Script_repr.expr_encoding) + +let script : Script_repr.expr = + Option.value_f ~default:(fun () -> assert false) script_opt diff --git a/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_migration.ml b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_migration.ml new file mode 100644 index 000000000000..89985c3ff7e7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_migration.ml @@ -0,0 +1,242 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Tocqueville Group, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module is used to originate contracts for liquidity baking during + protocol stitching: a CPMM (constant product market making) contract and a + liquidity token FA1.2 contract, with the storage of each containing the + other's address. + + The CPMM's storage contains a token address, which corresponds to tzBTC when + originated on mainnet and a reference FA1.2 contract when originated for + testing. + + The test FA1.2 contract uses the same script as the liquidity token. Its + manager is initialized to the first bootstrap account. Before originating it, + we make sure we are not on mainnet by both checking for the existence of the + tzBTC contract and that the level is sufficiently low. + + The Michelson and Ligo code, as well as Coq proofs, for the CPMM and + liquidity token contracts are available here: + https://gitlab.com/dexter2tz/dexter2tz/-/tree/liquidity_baking + + All contracts were generated from Ligo at revision + 4d10d07ca05abe0f8a5fb97d15267bf5d339d9f4 and converted to OCaml using + `tezos-client convert`. +*) + +open Michelson_v1_primitives +open Micheline + +let null_address = + Bytes.of_string + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000" + +let mainnet_tzBTC_address = "KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn" + +(** If token_pool, xtz_pool, or lqt_total are ever zero the CPMM will be + permanently broken. Therefore, we initialize it with the null address + registered as a liquidity provider with 1 satoshi tzBTC and 100 mutez + (roughly the current exchange rate). *) +let cpmm_init_storage ~token_address ~lqt_address = + Script_repr.lazy_expr + (Micheline.strip_locations + (Prim + ( 0, + D_Pair, + [ + Int (1, Z.one); + Int (2, Z.of_int 100); + Int (3, Z.of_int 100); + String (4, token_address); + String (5, lqt_address); + ], + [] ))) + +let lqt_init_storage cpmm_address = + Script_repr.lazy_expr + (Micheline.strip_locations + (Prim + ( 0, + D_Pair, + [ + Seq + ( 1, + [ + Prim + ( 2, + D_Elt, + [Bytes (3, null_address); Int (4, Z.of_int 100)], + [] ); + ] ); + Seq (5, []); + String (6, cpmm_address); + Int (7, Z.of_int 100); + ], + [] ))) + +let test_fa12_init_storage manager = + Script_repr.lazy_expr + (Micheline.strip_locations + (Prim + ( 0, + D_Pair, + [ + Seq (1, []); + Seq (2, []); + String (3, manager); + Int (4, Z.of_int 10_000); + ], + [] ))) + +let originate ctxt address ~balance script = + Contract_storage.raw_originate + ctxt + ~prepaid_bootstrap_storage:true + address + ~script + >>=? fun ctxt -> + Contract_storage.used_storage_space ctxt address >>=? fun size -> + Fees_storage.burn_origination_fees + ~origin:Protocol_migration + ctxt + ~storage_limit:(Z.of_int64 Int64.max_int) + ~payer:`Liquidity_baking_subsidies + >>=? fun (ctxt, _, origination_updates) -> + Fees_storage.burn_storage_fees + ~origin:Protocol_migration + ctxt + ~storage_limit:(Z.of_int64 Int64.max_int) + ~payer:`Liquidity_baking_subsidies + size + >>=? fun (ctxt, _, storage_updates) -> + Token.transfer + ~origin:Protocol_migration + ctxt + `Liquidity_baking_subsidies + (`Contract address) + balance + >>=? fun (ctxt, transfer_updates) -> + let balance_updates = + origination_updates @ storage_updates @ transfer_updates + in + let result : Migration_repr.origination_result = + { + balance_updates; + originated_contracts = [address]; + storage_size = size; + paid_storage_size_diff = size; + } + in + return (ctxt, result) + +let originate_test_fa12 ~typecheck ctxt admin = + Contract_storage.fresh_contract_from_current_nonce ctxt + >>?= fun (ctxt, fa12_address) -> + let script = + Script_repr. + { + code = Script_repr.lazy_expr Liquidity_baking_lqt.script; + storage = + test_fa12_init_storage (Signature.Public_key_hash.to_b58check admin); + } + in + typecheck ctxt script >>=? fun (script, ctxt) -> + originate ctxt fa12_address ~balance:(Tez_repr.of_mutez_exn 1_000_000L) script + >|=? fun (ctxt, origination_result) -> + (ctxt, fa12_address, [origination_result]) + +(* hardcoded from lib_parameters *) +let first_bootstrap_account = + Signature.Public_key.hash + (Signature.Public_key.of_b58check_exn + "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav") + +let check_tzBTC ~typecheck current_level ctxt f = + Contract_repr.of_b58check mainnet_tzBTC_address >>?= fun tzBTC -> + Contract_storage.exists ctxt tzBTC >>=? function + | true -> + (* If tzBTC exists, we're on mainnet and we use it as the token address in the CPMM. *) + f ctxt tzBTC [] + | false -> + (* If the tzBTC contract does not exist, we originate a test FA1.2 contract using the same script as the LQT. This is so that we can test the contracts after performing the same protocol migration that will be done on mainnet. + + First, we check current level is below mainnet level roughly around 010 injection so we do not accidentally originate the test token contract on mainnet. *) + if Compare.Int32.(current_level < 1_437_862l) then + originate_test_fa12 ~typecheck ctxt first_bootstrap_account + (* Token contract admin *) + >>=? fun (ctxt, token_address, token_result) -> + f ctxt token_address token_result + else + (* If we accidentally entered the tzBTC address incorrectly, but current level indicates this could be mainnet, we do not originate any contracts *) + return (ctxt, []) + +let init ctxt ~typecheck = + (* We use a custom origination nonce because it is unset when stitching from 009 *) + let nonce = Operation_hash.hash_string ["Drip, drip, drip."] in + let ctxt = Raw_context.init_origination_nonce ctxt nonce in + Storage.Liquidity_baking.Escape_ema.init ctxt 0l >>=? fun ctxt -> + let current_level = + Raw_level_repr.to_int32 (Level_storage.current ctxt).level + in + Contract_storage.fresh_contract_from_current_nonce ctxt + >>?= fun (ctxt, cpmm_address) -> + Contract_storage.fresh_contract_from_current_nonce ctxt + >>?= fun (ctxt, lqt_address) -> + Storage.Liquidity_baking.Cpmm_address.init ctxt cpmm_address >>=? fun ctxt -> + check_tzBTC + ~typecheck + current_level + ctxt + (fun ctxt token_address token_result -> + let cpmm_script = + Script_repr. + { + code = Script_repr.lazy_expr Liquidity_baking_cpmm.script; + storage = + cpmm_init_storage + ~token_address:(Contract_repr.to_b58check token_address) + ~lqt_address:(Contract_repr.to_b58check lqt_address); + } + in + typecheck ctxt cpmm_script >>=? fun (cpmm_script, ctxt) -> + let lqt_script = + Script_repr. + { + code = Script_repr.lazy_expr Liquidity_baking_lqt.script; + storage = lqt_init_storage (Contract_repr.to_b58check cpmm_address); + } + in + typecheck ctxt lqt_script >>=? fun (lqt_script, ctxt) -> + originate + ctxt + cpmm_address + ~balance:(Tez_repr.of_mutez_exn 100L) + cpmm_script + >>=? fun (ctxt, cpmm_result) -> + originate ctxt lqt_address ~balance:Tez_repr.zero lqt_script + >|=? fun (ctxt, lqt_result) -> + (* Unsets the origination nonce, which is okay because this is called after other originations in stitching. *) + let ctxt = Raw_context.unset_origination_nonce ctxt in + (ctxt, [cpmm_result; lqt_result] @ token_result)) diff --git a/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_migration.mli b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_migration.mli new file mode 100644 index 000000000000..27059e493d50 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_migration.mli @@ -0,0 +1,33 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Tocqueville Group, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val init : + Raw_context.t -> + typecheck: + (Raw_context.t -> + Script_repr.t -> + ((Script_repr.t * Lazy_storage_diff.diffs option) * Raw_context.t) tzresult + Lwt.t) -> + (Raw_context.t * Migration_repr.origination_result list) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_repr.ml new file mode 100644 index 000000000000..2dc35196d273 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_repr.ml @@ -0,0 +1,71 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Tocqueville Group, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let get_cpmm_address = Storage.Liquidity_baking.Cpmm_address.get + +let get_escape_ema = Storage.Liquidity_baking.Escape_ema.get + +type escape_ema = Int32.t + +let on_cpmm_exists ctxt f = + get_cpmm_address ctxt >>=? fun cpmm_contract -> + Contract_storage.exists ctxt cpmm_contract >>=? function + | false -> + (* do nothing if the cpmm is not found *) + return (ctxt, []) + | true -> f ctxt cpmm_contract + +let on_below_sunset ctxt f = + let sunset_level = Constants_storage.liquidity_baking_sunset_level ctxt in + let level = Raw_level_repr.to_int32 (Level_storage.current ctxt).level in + if Compare.Int32.(level >= sunset_level) then return (ctxt, []) + else on_cpmm_exists ctxt f + +(* ema starts at zero + ema[n+1] = (1999 * ema[n] // 2000) + (1000 if escape_vote[n] else 0) + where escape_vote is protocol_data.contents.liquidity_baking_escape_vote *) +let update_escape_ema ctxt ~escape_vote = + get_escape_ema ctxt >>=? fun old_ema -> + (* if ema is over threshold, we don't update it because liquidity baking is permanently off *) + if + Compare.Int32.( + old_ema < Constants_storage.liquidity_baking_escape_ema_threshold ctxt) + then + let new_ema = + Int32.( + add (div (mul 1999l old_ema) 2000l) (if escape_vote then 1000l else 0l)) + in + Storage.Liquidity_baking.Escape_ema.update ctxt new_ema >|=? fun ctxt -> + (ctxt, new_ema, false) + else return (ctxt, old_ema, true) + +let on_subsidy_allowed ctxt ~escape_vote f = + update_escape_ema ctxt ~escape_vote + >>=? fun (ctxt, escape_ema, threshold_reached) -> + (* liquidity baking permanently shuts off if threshold is reached once *) + if threshold_reached then return (ctxt, [], escape_ema) + else + on_below_sunset ctxt f >|=? fun (ctxt, operation_results) -> + (ctxt, operation_results, escape_ema) diff --git a/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_repr.mli new file mode 100644 index 000000000000..f631ec4ddf4a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/liquidity_baking_repr.mli @@ -0,0 +1,36 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Tocqueville Group, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val get_cpmm_address : Raw_context.t -> Contract_repr.t tzresult Lwt.t + +type escape_ema = Int32.t + +(** Checks if below EMA threshold (after updating), sunset level, and if CPMM + contract exists. *) +val on_subsidy_allowed : + Raw_context.t -> + escape_vote:bool -> + (Raw_context.t -> Contract_repr.t -> (Raw_context.t * 'a list) tzresult Lwt.t) -> + (Raw_context.t * 'a list * escape_ema) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/local_gas_counter.ml b/src/proto_012_PsiThaCa/lib_protocol/local_gas_counter.ml new file mode 100644 index 000000000000..7ae70ae9f593 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/local_gas_counter.ml @@ -0,0 +1,99 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +(* + + Gas update and check for gas exhaustion + ======================================= + + Costs of various computations are subtracted from an amount of gas made + available for the script execution. + + Updating the gas counter is a critical aspect to operation validation + because it is done at many places. + + For this reason, the gas counter must be read and updated as quickly as + possible. Hence, the gas counter should be stored in a machine register. To + motivate the OCaml compiler to make that choice, we represent the gas counter + as a local parameter of the execution [step] function. + +*) + +type local_gas_counter = int + +(* + + The gas counter stored in the context is desynchronized with the + [local_gas_counter] used locally. When we have to call a gas-consuming + function working on context with no local gas counter, we must update the + context so that it carries an up-to-date gas counter. Similarly, when we + return from such a function, the [local_gas_counter] must be updated as well. + + To statically track these points where the context's gas counter + must be updated, we introduce a type for outdated contexts. The + [step] function carries an [outdated_context]. When an external + function needs a [context], the typechecker points out the need for + a conversion: this forces us to either call [update_context], or + better, when this is possible, the function + [use_gas_counter_in_ctxt]. + +*) +type outdated_context = OutDatedContext of context [@@unboxed] + +let update_context local_gas_counter = function + | OutDatedContext ctxt -> + Gas.update_remaining_operation_gas + ctxt + (Saturation_repr.safe_int local_gas_counter) + [@@ocaml.inline always] + +let update_local_gas_counter ctxt = + (Gas.remaining_operation_gas ctxt :> int) + [@@ocaml.inline always] + +let outdated ctxt = OutDatedContext ctxt [@@ocaml.inline always] + +let context_from_outdated_context (OutDatedContext ctxt) = + ctxt + [@@ocaml.inline always] + +let use_gas_counter_in_ctxt ctxt local_gas_counter f = + let ctxt = update_context local_gas_counter ctxt in + f ctxt >>=? fun (y, ctxt) -> + return (y, outdated ctxt, update_local_gas_counter ctxt) + [@@ocaml.inline always] + +let update_and_check gas_counter (cost : Gas.cost) = + let gas_counter = gas_counter - (cost :> int) in + if Compare.Int.(gas_counter < 0) then None else Some gas_counter + [@@ocaml.inline always] + +let consume local_gas_counter cost = + match update_and_check local_gas_counter cost with + | None -> error Gas.Operation_quota_exceeded + | Some local_gas_counter -> Ok local_gas_counter + [@@ocaml.inline always] diff --git a/src/proto_012_PsiThaCa/lib_protocol/main.ml b/src/proto_012_PsiThaCa/lib_protocol/main.ml new file mode 100644 index 000000000000..8e8f8243b37a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/main.ml @@ -0,0 +1,822 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Tezos Protocol Implementation - Protocol Signature Instance *) + +type block_header_data = Alpha_context.Block_header.protocol_data + +type block_header = Alpha_context.Block_header.t = { + shell : Block_header.shell_header; + protocol_data : block_header_data; +} + +let block_header_data_encoding = + Alpha_context.Block_header.protocol_data_encoding + +type block_header_metadata = Apply_results.block_metadata + +let block_header_metadata_encoding = Apply_results.block_metadata_encoding + +type operation_data = Alpha_context.packed_protocol_data = + | Operation_data : + 'kind Alpha_context.Operation.protocol_data + -> operation_data + +let operation_data_encoding = Alpha_context.Operation.protocol_data_encoding + +type operation_receipt = Apply_results.packed_operation_metadata = + | Operation_metadata : + 'kind Apply_results.operation_metadata + -> operation_receipt + | No_operation_metadata : operation_receipt + +let operation_receipt_encoding = Apply_results.operation_metadata_encoding + +let operation_data_and_receipt_encoding = + Apply_results.operation_data_and_metadata_encoding + +type operation = Alpha_context.packed_operation = { + shell : Operation.shell_header; + protocol_data : operation_data; +} + +let acceptable_passes = Alpha_context.Operation.acceptable_passes + +let max_block_length = Alpha_context.Block_header.max_header_length + +let max_operation_data_length = + Alpha_context.Constants.max_operation_data_length + +let validation_passes = + let open Alpha_context.Constants in + Updater. + [ + (* 2048 endorsements *) + {max_size = 2048 * 2048; max_op = Some 2048}; + (* 32k of voting operations *) + {max_size = 32 * 1024; max_op = None}; + (* revelations, wallet activations and denunciations *) + { + max_size = max_anon_ops_per_block * 1024; + max_op = Some max_anon_ops_per_block; + }; + (* 512kB *) + {max_size = 512 * 1024; max_op = None}; + ] + +let rpc_services = + Alpha_services.register () ; + Services_registration.get_rpc_services () + +type validation_mode = + | Application of { + block_header : Alpha_context.Block_header.t; + fitness : Alpha_context.Fitness.t; + payload_producer : Alpha_context.public_key_hash; + block_producer : Alpha_context.public_key_hash; + predecessor_round : Alpha_context.Round.t; + predecessor_level : Alpha_context.Level.t; + } + | Partial_application of { + block_header : Alpha_context.Block_header.t; + fitness : Alpha_context.Fitness.t; + payload_producer : Alpha_context.public_key_hash; + block_producer : Alpha_context.public_key_hash; + predecessor_level : Alpha_context.Level.t; + predecessor_round : Alpha_context.Round.t; + } + (* Mempool only *) + | Partial_construction of { + predecessor : Block_hash.t; + predecessor_fitness : Fitness.t; + predecessor_level : Alpha_context.Level.t; + predecessor_round : Alpha_context.Round.t; + } + (* Baker only *) + | Full_construction of { + predecessor : Block_hash.t; + payload_producer : Alpha_context.public_key_hash; + block_producer : Alpha_context.public_key_hash; + protocol_data_contents : Alpha_context.Block_header.contents; + level : Int32.t; + round : Alpha_context.Round.t; + predecessor_level : Alpha_context.Level.t; + predecessor_round : Alpha_context.Round.t; + } + +type validation_state = { + mode : validation_mode; + chain_id : Chain_id.t; + ctxt : Alpha_context.t; + op_count : int; + migration_balance_updates : Alpha_context.Receipt.balance_updates; + liquidity_baking_escape_ema : Int32.t; + implicit_operations_results : + Apply_results.packed_successful_manager_operation_result list; +} + +let cache_layout = Apply.cache_layout + +let begin_partial_application ~chain_id ~ancestor_context:ctxt + ~predecessor_timestamp ~(predecessor_fitness : Fitness.t) + (block_header : Alpha_context.Block_header.t) = + (* Note: we don't have access to the predecessor context. *) + let level = block_header.shell.level in + let timestamp = block_header.shell.timestamp in + Alpha_context.Fitness.from_raw block_header.shell.fitness >>?= fun fitness -> + Alpha_context.Fitness.round_from_raw predecessor_fitness + >>?= fun predecessor_round -> + Alpha_context.prepare ~level ~predecessor_timestamp ~timestamp ctxt + >>=? fun (ctxt, migration_balance_updates, migration_operation_results) -> + Alpha_context.Raw_level.of_int32 (Int32.pred level) + >>?= fun predecessor_level -> + let predecessor_level = + Alpha_context.Level.(from_raw ctxt predecessor_level) + in + Apply.begin_application + ctxt + chain_id + block_header + fitness + ~predecessor_timestamp + ~predecessor_level + ~predecessor_round + >>=? fun ( ctxt, + payload_producer_pk, + block_producer, + liquidity_baking_operations_results, + liquidity_baking_escape_ema ) -> + let mode = + Partial_application + { + block_header; + fitness; + predecessor_level; + predecessor_round; + payload_producer = Signature.Public_key.hash payload_producer_pk; + block_producer; + } + in + return + { + mode; + chain_id; + ctxt; + op_count = 0; + migration_balance_updates; + liquidity_baking_escape_ema; + implicit_operations_results = + Apply_results.pack_migration_operation_results + migration_operation_results + @ liquidity_baking_operations_results; + } + +(* During applications the valid consensus operations are: + * Endorsements on previous block with the right round, level, payload_hash (of the predecessor block) + * Preendorsements on current level, previous round, and the payload_hash of the current block + Those endorsements justify that the previous block was finalized. + Those preendorsements justify the locked_round part of the fitness of the current block + *) +let begin_application ~chain_id ~predecessor_context:ctxt ~predecessor_timestamp + ~predecessor_fitness (block_header : Alpha_context.Block_header.t) = + let level = block_header.shell.level in + let timestamp = block_header.shell.timestamp in + Alpha_context.Fitness.from_raw block_header.shell.fitness >>?= fun fitness -> + Alpha_context.Fitness.round_from_raw predecessor_fitness + >>?= fun predecessor_round -> + Alpha_context.Raw_level.of_int32 (Int32.pred level) + >>?= fun predecessor_level -> + Alpha_context.prepare ~level ~predecessor_timestamp ~timestamp ctxt + >>=? fun (ctxt, migration_balance_updates, migration_operation_results) -> + let predecessor_level = Alpha_context.Level.from_raw ctxt predecessor_level in + Apply.begin_application + ctxt + chain_id + block_header + fitness + ~predecessor_timestamp + ~predecessor_level + ~predecessor_round + >>=? fun ( ctxt, + payload_producer, + block_producer, + liquidity_baking_operations_results, + liquidity_baking_escape_ema ) -> + let mode = + Application + { + block_header; + fitness; + predecessor_round; + predecessor_level; + payload_producer = Signature.Public_key.hash payload_producer; + block_producer; + } + in + return + { + mode; + chain_id; + ctxt; + op_count = 0; + migration_balance_updates; + liquidity_baking_escape_ema; + implicit_operations_results = + Apply_results.pack_migration_operation_results + migration_operation_results + @ liquidity_baking_operations_results; + } + +let begin_construction ~chain_id ~predecessor_context:ctxt + ~predecessor_timestamp ~predecessor_level ~predecessor_fitness ~predecessor + ~timestamp ?(protocol_data : block_header_data option) () = + let level = Int32.succ predecessor_level in + Alpha_context.prepare ~level ~predecessor_timestamp ~timestamp ctxt + >>=? fun (ctxt, migration_balance_updates, migration_operation_results) -> + Alpha_context.Raw_level.of_int32 predecessor_level + >>?= fun predecessor_level -> + let predecessor_level = + Alpha_context.Level.(from_raw ctxt predecessor_level) + in + (match protocol_data with + | None -> + Alpha_context.Fitness.round_from_raw predecessor_fitness + >>?= fun predecessor_round -> + let escape_vote = false in + Apply.begin_partial_construction ctxt ~predecessor_level ~escape_vote + >>=? fun ( ctxt, + liquidity_baking_operations_results, + liquidity_baking_escape_ema ) -> + let mode = + Partial_construction + { + predecessor; + predecessor_fitness; + predecessor_level; + predecessor_round; + } + in + return + ( mode, + ctxt, + liquidity_baking_operations_results, + liquidity_baking_escape_ema ) + | Some proto_header -> + Alpha_context.Fitness.round_from_raw predecessor_fitness + >>?= fun predecessor_round -> + let round_durations = Alpha_context.Constants.round_durations ctxt in + Alpha_context.Round.round_of_timestamp + round_durations + ~predecessor_timestamp + ~predecessor_round + ~timestamp + >>?= fun round -> + (* The endorsement/preendorsement validation rules for construction are the + same as for application. *) + Apply.begin_full_construction + ctxt + ~predecessor_timestamp + ~predecessor_round + ~predecessor_level + ~round + proto_header.contents + >>=? fun { + ctxt; + protocol_data = protocol_data_contents; + payload_producer; + block_producer; + round; + liquidity_baking_escape_ema; + implicit_operations_results = + liquidity_baking_operations_results; + } -> + let mode = + Full_construction + { + predecessor; + payload_producer; + block_producer; + level; + round; + protocol_data_contents; + predecessor_round; + predecessor_level; + } + in + return + ( mode, + ctxt, + liquidity_baking_operations_results, + liquidity_baking_escape_ema )) + >|=? fun ( mode, + ctxt, + liquidity_baking_operations_results, + liquidity_baking_escape_ema ) -> + { + mode; + chain_id; + ctxt; + op_count = 0; + migration_balance_updates; + liquidity_baking_escape_ema; + implicit_operations_results = + Apply_results.pack_migration_operation_results migration_operation_results + @ liquidity_baking_operations_results; + } + +let apply_operation_with_mode mode ctxt chain_id data op_count operation + ~payload_producer = + let {shell; protocol_data = Operation_data protocol_data} = operation in + let operation : _ Alpha_context.operation = {shell; protocol_data} in + Apply.apply_operation + ctxt + chain_id + mode + Optimized + ~payload_producer + (Alpha_context.Operation.hash operation) + operation + >|=? fun (ctxt, result) -> + let op_count = op_count + 1 in + ({data with ctxt; op_count}, Operation_metadata result) + +let apply_operation ({mode; chain_id; ctxt; op_count; _} as data) + (operation : Alpha_context.packed_operation) = + match mode with + | Partial_application _ + when not + (List.exists + (Compare.Int.equal 0) + (Alpha_context.Operation.acceptable_passes operation)) -> + (* Multipass validation only considers operations in pass 0. *) + let op_count = op_count + 1 in + return ({data with ctxt; op_count}, No_operation_metadata) + | Partial_application + { + block_header = + { + shell = {predecessor; _}; + protocol_data = {contents = {payload_hash; _}; _}; + }; + fitness; + payload_producer; + predecessor_round; + predecessor_level; + _; + } -> + let locked_round = Alpha_context.Fitness.locked_round fitness in + apply_operation_with_mode + (Apply.Application + { + payload_hash; + predecessor_block = predecessor; + predecessor_round; + predecessor_level; + locked_round; + round = Alpha_context.Fitness.round fitness; + }) + ctxt + chain_id + data + op_count + operation + ~payload_producer + | Application + { + block_header = + { + shell = {predecessor; _}; + protocol_data = {contents = {payload_hash; _}; _}; + }; + fitness; + payload_producer; + predecessor_round; + predecessor_level; + _; + } -> + let locked_round = Alpha_context.Fitness.locked_round fitness in + apply_operation_with_mode + (Apply.Application + { + payload_hash; + predecessor_block = predecessor; + predecessor_round; + predecessor_level; + locked_round; + round = Alpha_context.Fitness.round fitness; + }) + ctxt + chain_id + data + op_count + operation + ~payload_producer + | Partial_construction + {predecessor_level; predecessor_round; predecessor_fitness; _} -> + Alpha_context.Fitness.predecessor_round_from_raw predecessor_fitness + >>?= fun grand_parent_round -> + apply_operation_with_mode + (Apply.Partial_construction + {predecessor_round; predecessor_level; grand_parent_round}) + ctxt + chain_id + data + op_count + operation + ~payload_producer:Signature.Public_key_hash.zero + | Full_construction + { + payload_producer; + predecessor; + predecessor_round; + predecessor_level; + protocol_data_contents = {payload_hash; _}; + round; + _; + } -> + apply_operation_with_mode + (Apply.Full_construction + { + payload_hash; + predecessor_block = predecessor; + predecessor_level; + predecessor_round; + round; + }) + ctxt + chain_id + data + op_count + operation + ~payload_producer + +let cache_nonce_from_block_header shell contents = + let open Alpha_context.Block_header in + let shell = + Block_header. + { + level = 0l; + proto_level = 0; + predecessor = shell.predecessor; + timestamp = Time.of_seconds 0L; + validation_passes = 0; + operations_hash = shell.operations_hash; + fitness = []; + context = Context_hash.zero; + } + in + let contents = + { + contents with + payload_hash = Block_payload_hash.zero; + proof_of_work_nonce = + Bytes.make Constants_repr.proof_of_work_nonce_size '0'; + } + in + let protocol_data = {signature = Signature.zero; contents} in + let x = {shell; protocol_data} in + Block_hash.to_bytes (hash x) + +let finalize_block_application ctxt round ~cache_nonce finalize_application_mode + protocol_data payload_producer block_producer liquidity_baking_escape_ema + implicit_operations_results predecessor migration_balance_updates op_count = + Apply.finalize_application + ctxt + finalize_application_mode + protocol_data + ~payload_producer + ~block_producer + liquidity_baking_escape_ema + implicit_operations_results + ~round + ~predecessor + ~migration_balance_updates + >>=? fun (ctxt, fitness, receipt) -> + Alpha_context.Cache.Admin.sync ctxt ~cache_nonce >>= fun ctxt -> + let level = Alpha_context.Level.current ctxt in + let raw_level = Alpha_context.Raw_level.to_int32 level.level in + let commit_message = + Format.asprintf + "lvl %ld, fit:%a, round %a, %d ops" + raw_level + Alpha_context.Fitness.pp + fitness + Alpha_context.Round.pp + round + op_count + in + let validation_result = + Alpha_context.finalize + ~commit_message + ctxt + (Alpha_context.Fitness.to_raw fitness) + in + return (validation_result, receipt) + +type error += Missing_shell_header + +let () = + register_error_kind + `Permanent + ~id:"main.missing_shell_header" + ~title:"Missing shell_header during finalisation of a block" + ~description: + "During finalisation of a block header in Application mode or Full \ + construction mode, a shell header should be provided so that a cache \ + nonce can be computed." + ~pp:(fun ppf () -> + Format.fprintf + ppf + "No shell header provided during the finalisation of a block.") + Data_encoding.unit + (function Missing_shell_header -> Some () | _ -> None) + (fun () -> Missing_shell_header) + +let finalize_block + { + mode; + ctxt; + op_count; + migration_balance_updates; + liquidity_baking_escape_ema; + implicit_operations_results; + _; + } shell_header = + match mode with + | Partial_construction {predecessor_fitness; _} -> + Alpha_context.Voting_period.get_rpc_current_info ctxt + >>=? fun voting_period_info -> + let level_info = Alpha_context.Level.current ctxt in + let fitness = predecessor_fitness in + let ctxt = Alpha_context.finalize ctxt fitness in + return + ( ctxt, + Apply_results. + { + proposer = Signature.Public_key_hash.zero; + baker = Signature.Public_key_hash.zero; + level_info; + voting_period_info; + nonce_hash = None; + consumed_gas = Alpha_context.Gas.Arith.zero; + deactivated = []; + balance_updates = migration_balance_updates; + liquidity_baking_escape_ema; + implicit_operations_results; + } ) + | Partial_application {fitness; block_producer; _} -> + (* For partial application we do not completely check the block validity. + Validating the endorsements is sufficient for a good precheck *) + let level = Alpha_context.Level.current ctxt in + let included_endorsements = + Alpha_context.Consensus.current_endorsement_power ctxt + in + let minimum = Alpha_context.Constants.consensus_threshold ctxt in + Apply.are_endorsements_required ctxt ~level:level.level + >>=? fun endorsements_required -> + (if endorsements_required then + Apply.check_minimum_endorsements + ~endorsing_power:included_endorsements + ~minimum + else return_unit) + >>=? fun () -> + Alpha_context.Voting_period.get_rpc_current_info ctxt + >|=? fun voting_period_info -> + let level_info = Alpha_context.Level.current ctxt in + let ctxt = + Alpha_context.finalize ctxt (Alpha_context.Fitness.to_raw fitness) + in + ( ctxt, + Apply_results. + { + proposer = Signature.Public_key_hash.zero; + (* We cannot retrieve the proposer as it requires the + frozen deposit that might not be available depending on + the context given to the partial application. *) + baker = block_producer; + level_info; + voting_period_info; + nonce_hash = None; + consumed_gas = Alpha_context.Gas.Arith.zero; + deactivated = []; + balance_updates = migration_balance_updates; + liquidity_baking_escape_ema; + implicit_operations_results; + } ) + | Application + { + payload_producer; + fitness; + block_producer; + block_header = {protocol_data = {contents = protocol_data; _}; shell}; + _; + } -> + let round = Alpha_context.Fitness.round fitness in + let cache_nonce = cache_nonce_from_block_header shell protocol_data in + finalize_block_application + ctxt + ~cache_nonce + round + (Finalize_application fitness) + protocol_data + payload_producer + block_producer + liquidity_baking_escape_ema + implicit_operations_results + shell.predecessor + migration_balance_updates + op_count + | Full_construction + { + predecessor; + predecessor_round; + protocol_data_contents; + round; + level; + payload_producer; + block_producer; + _; + } -> + Option.value_e + shell_header + ~error:(Error_monad.trace_of_error Missing_shell_header) + >>?= fun shell_header -> + let cache_nonce = + cache_nonce_from_block_header shell_header protocol_data_contents + in + Alpha_context.Raw_level.of_int32 level >>?= fun level -> + finalize_block_application + ctxt + round + ~cache_nonce + (Finalize_full_construction {level; predecessor_round}) + protocol_data_contents + payload_producer + block_producer + liquidity_baking_escape_ema + implicit_operations_results + predecessor + migration_balance_updates + op_count + +let relative_position_within_block op1 op2 = + let open Alpha_context in + let (Operation_data op1) = op1.protocol_data in + let (Operation_data op2) = op2.protocol_data in + match[@coq_match_with_default] (op1.contents, op2.contents) with + | (Single (Preendorsement _), Single (Preendorsement _)) -> 0 + | (Single (Preendorsement _), _) -> -1 + | (_, Single (Preendorsement _)) -> 1 + | (Single (Endorsement _), Single (Endorsement _)) -> 0 + | (Single (Endorsement _), _) -> -1 + | (_, Single (Endorsement _)) -> 1 + | (Single (Seed_nonce_revelation _), Single (Seed_nonce_revelation _)) -> 0 + | (_, Single (Seed_nonce_revelation _)) -> 1 + | (Single (Seed_nonce_revelation _), _) -> -1 + | ( Single (Double_preendorsement_evidence _), + Single (Double_preendorsement_evidence _) ) -> + 0 + | (_, Single (Double_preendorsement_evidence _)) -> 1 + | (Single (Double_preendorsement_evidence _), _) -> -1 + | ( Single (Double_endorsement_evidence _), + Single (Double_endorsement_evidence _) ) -> + 0 + | (_, Single (Double_endorsement_evidence _)) -> 1 + | (Single (Double_endorsement_evidence _), _) -> -1 + | (Single (Double_baking_evidence _), Single (Double_baking_evidence _)) -> 0 + | (_, Single (Double_baking_evidence _)) -> 1 + | (Single (Double_baking_evidence _), _) -> -1 + | (Single (Activate_account _), Single (Activate_account _)) -> 0 + | (_, Single (Activate_account _)) -> 1 + | (Single (Activate_account _), _) -> -1 + | (Single (Proposals _), Single (Proposals _)) -> 0 + | (_, Single (Proposals _)) -> 1 + | (Single (Proposals _), _) -> -1 + | (Single (Ballot _), Single (Ballot _)) -> 0 + | (_, Single (Ballot _)) -> 1 + | (Single (Ballot _), _) -> -1 + | (Single (Failing_noop _), Single (Failing_noop _)) -> 0 + | (_, Single (Failing_noop _)) -> 1 + | (Single (Failing_noop _), _) -> -1 + (* Manager operations with smaller counter are pre-validated first. *) + | (Single (Manager_operation op1), Single (Manager_operation op2)) -> + Z.compare op1.counter op2.counter + | (Cons (Manager_operation op1, _), Single (Manager_operation op2)) -> + Z.compare op1.counter op2.counter + | (Single (Manager_operation op1), Cons (Manager_operation op2, _)) -> + Z.compare op1.counter op2.counter + | (Cons (Manager_operation op1, _), Cons (Manager_operation op2, _)) -> + Z.compare op1.counter op2.counter + +let init_cache ctxt = + Context.Cache.set_cache_layout ctxt cache_layout >>= fun ctxt -> + Lwt.return (Context.Cache.clear ctxt) + +let init ctxt block_header = + let level = block_header.Block_header.level in + let timestamp = block_header.timestamp in + let typecheck (ctxt : Alpha_context.context) (script : Alpha_context.Script.t) + = + let allow_forged_in_storage = + false + (* There should be no forged value in bootstrap contracts. *) + in + Script_ir_translator.parse_script + ctxt + ~legacy:true + ~allow_forged_in_storage + script + >>=? fun (Ex_script parsed_script, ctxt) -> + Script_ir_translator.extract_lazy_storage_diff + ctxt + Optimized + parsed_script.storage_type + parsed_script.storage + ~to_duplicate:Script_ir_translator.no_lazy_storage_id + ~to_update:Script_ir_translator.no_lazy_storage_id + ~temporary:false + >>=? fun (storage, lazy_storage_diff, ctxt) -> + Script_ir_translator.unparse_data + ctxt + Optimized + parsed_script.storage_type + storage + >|=? fun (storage, ctxt) -> + let storage = + Alpha_context.Script.lazy_expr (Micheline.strip_locations storage) + in + (({script with storage}, lazy_storage_diff), ctxt) + in + (* The cache must be synced at the end of block validation, so we do + so here for the first block in a protocol where `finalize_block` + is not called. *) + Alpha_context.Raw_level.of_int32 level >>?= fun raw_level -> + let init_fitness = + Alpha_context.Fitness.create_without_locked_round + ~level:raw_level + ~round:Alpha_context.Round.zero + ~predecessor_round:Alpha_context.Round.zero + in + init_cache ctxt >>= fun ctxt -> + Alpha_context.prepare_first_block ~typecheck ~level ~timestamp ctxt + >>=? fun ctxt -> + let cache_nonce = + cache_nonce_from_block_header + block_header + { + payload_hash = Block_payload_hash.zero; + payload_round = Alpha_context.Round.zero; + liquidity_baking_escape_vote = false; + seed_nonce_hash = None; + proof_of_work_nonce = + Bytes.make Constants_repr.proof_of_work_nonce_size '0'; + } + in + Alpha_context.Cache.Admin.sync ctxt ~cache_nonce >>= fun ctxt -> + return + (Alpha_context.finalize ctxt (Alpha_context.Fitness.to_raw init_fitness)) + +let value_of_key ~chain_id:_ ~predecessor_context:ctxt ~predecessor_timestamp + ~predecessor_level:pred_level ~predecessor_fitness:_ ~predecessor:_ + ~timestamp = + let level = Int32.succ pred_level in + Alpha_context.prepare ctxt ~level ~predecessor_timestamp ~timestamp + >>=? fun (ctxt, _, _) -> return (Apply.value_of_key ctxt) + +let check_manager_signature {chain_id; ctxt; _} op raw_op = + Apply.check_manager_signature ctxt chain_id op raw_op + +let precheck_manager {ctxt; _} op = + (* We do not account for the gas limit of the batch in the block + since this function does not return a context, but we check that + this limit is within bounds (and fail otherwise with a + permanenent error). *) + Apply.precheck_manager_contents_list ctxt op ~mempool_mode:true + >|=? fun (_ : + Alpha_context.t + * 'kind Alpha_context.Kind.manager + Apply_results.prechecked_contents_list) -> () + +(* Vanity nonce: 0105000201649133 *) diff --git a/src/proto_012_PsiThaCa/lib_protocol/main.mli b/src/proto_012_PsiThaCa/lib_protocol/main.mli new file mode 100644 index 000000000000..ee6fb2dd6638 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/main.mli @@ -0,0 +1,139 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Tezos Protocol Implementation - Protocol Signature Instance + + This module is the entrypoint to the protocol for shells and other + embedders. This signature is an instance of + {{!Tezos_protocol_environment_sigs.V3.T.Updater.PROTOCOL} the + [Updater.PROTOCOL] signature} from the + {{:https://tezos.gitlab.io/shell/the_big_picture.html#the-economic-protocol-environment-and-compiler} + Protocol Environment}. + + Each Protocol depends on a version of the Protocol Environment. For the + currently developed protocol, this is normally the latest version. You can + see {{!Tezos_protocol_environment_sigs} the full list of versions here}. + + For details on how Protocol and Environment interact, see + {{:https://tezos.gitlab.io/shell/the_big_picture.html} this overview}. + *) + +type validation_mode = + | Application of { + block_header : Alpha_context.Block_header.t; + fitness : Alpha_context.Fitness.t; + payload_producer : Alpha_context.public_key_hash; + block_producer : Alpha_context.public_key_hash; + predecessor_round : Alpha_context.Round.t; + predecessor_level : Alpha_context.Level.t; + } + | Partial_application of { + block_header : Alpha_context.Block_header.t; + fitness : Alpha_context.Fitness.t; + payload_producer : Alpha_context.public_key_hash; + block_producer : Alpha_context.public_key_hash; + predecessor_level : Alpha_context.Level.t; + predecessor_round : Alpha_context.Round.t; + } + (* Mempool only *) + | Partial_construction of { + predecessor : Block_hash.t; + predecessor_fitness : Fitness.t; + predecessor_level : Alpha_context.Level.t; + predecessor_round : Alpha_context.Round.t; + } + (* Baker only *) + | Full_construction of { + predecessor : Block_hash.t; + payload_producer : Alpha_context.public_key_hash; + block_producer : Alpha_context.public_key_hash; + protocol_data_contents : Alpha_context.Block_header.contents; + level : Int32.t; + round : Alpha_context.Round.t; + predecessor_level : Alpha_context.Level.t; + predecessor_round : Alpha_context.Round.t; + } + +type validation_state = { + mode : validation_mode; + chain_id : Chain_id.t; + ctxt : Alpha_context.t; + op_count : int; + migration_balance_updates : Alpha_context.Receipt.balance_updates; + liquidity_baking_escape_ema : Int32.t; + implicit_operations_results : + Apply_results.packed_successful_manager_operation_result list; +} + +type operation_data = Alpha_context.packed_protocol_data + +type operation = Alpha_context.packed_operation = { + shell : Operation.shell_header; + protocol_data : operation_data; +} + +val init_cache : Context.t -> Context.t Lwt.t + +(** [check_manager_signature validation_state op raw_operation] + The function starts by retrieving the public key hash [pkh] of the manager + operation. In case the operation is batched, the function also checks that + the sources are all the same. + Once the [pkh] is retrieved, the function looks for its associated public + key. For that, the manager operation is inspected to check if it contains + a public key revelation. If not, the public key is searched in the context. + + @return [Error Invalid_signature] if the signature check fails + @return [Error Unrevealed_manager_key] if the manager has not yet been + revealed + @return [Error Failure "get_manager_key"] if the key is not found in the + context + @return [Error Inconsistent_sources] if the operations in a batch are not + from the same manager *) +val check_manager_signature : + validation_state -> + 'b Alpha_context.Kind.manager Alpha_context.contents_list -> + 'a Alpha_context.operation -> + unit tzresult Lwt.t + +(** [precheck_manager validation_state op] returns [()] if the manager operation + [op] is solveable, returns an error otherwise. An operation is solveable if + it is well-formed and can pay the fees to be included in a block with either + a success or a failure status. + This function uses [Apply.precheck_manager_contents_list] but discard the + context and balance update *) +val precheck_manager : + validation_state -> + 'a Alpha_context.Kind.manager Alpha_context.contents_list -> + unit tzresult Lwt.t + +include + Updater.PROTOCOL + with type block_header_data = Alpha_context.Block_header.protocol_data + and type block_header_metadata = Apply_results.block_metadata + and type block_header = Alpha_context.Block_header.t + and type operation_data := operation_data + and type operation_receipt = Apply_results.packed_operation_metadata + and type operation := operation + and type validation_state := validation_state diff --git a/src/proto_012_PsiThaCa/lib_protocol/manager_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/manager_repr.ml new file mode 100644 index 000000000000..b96a51401289 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/manager_repr.ml @@ -0,0 +1,52 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Tezos Protocol Implementation - Low level Repr. of Managers' keys *) + +type manager_key = + | Hash of Signature.Public_key_hash.t + | Public_key of Signature.Public_key.t + +type t = manager_key + +open Data_encoding + +let hash_case tag = + case + tag + ~title:"Public_key_hash" + Signature.Public_key_hash.encoding + (function Hash hash -> Some hash | _ -> None) + (fun hash -> Hash hash) + +let pubkey_case tag = + case + tag + ~title:"Public_key" + Signature.Public_key.encoding + (function Public_key hash -> Some hash | _ -> None) + (fun hash -> Public_key hash) + +let encoding = union [hash_case (Tag 0); pubkey_case (Tag 1)] diff --git a/src/proto_012_PsiThaCa/lib_protocol/manager_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/manager_repr.mli new file mode 100644 index 000000000000..18ca236d71b1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/manager_repr.mli @@ -0,0 +1,38 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Tezos Protocol Implementation - Low level Repr. of Managers' keys *) + +(** The public key of the manager of a contract is reveled only after the + first operation. At Origination time, the manager provides only the hash + of its public key that is stored in the contract. When the public key + is actually revealed, the public key instead of the hash of the key *) +type manager_key = + | Hash of Signature.Public_key_hash.t + | Public_key of Signature.Public_key.t + +type t = manager_key + +val encoding : t Data_encoding.encoding diff --git a/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_gas.ml b/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_gas.ml new file mode 100644 index 000000000000..b3175d63a615 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_gas.ml @@ -0,0 +1,1809 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Gas +module S = Saturation_repr + +module Cost_of = struct + module S_syntax = struct + (* This is a good enough approximation. S.numbits 0 = 0 *) + let log2 x = S.safe_int (1 + S.numbits x) + + let ( + ) = S.add + + let ( * ) = S.mul + + let ( lsr ) = S.shift_right + end + + let z_bytes (z : Z.t) = + let bits = Z.numbits z in + (7 + bits) / 8 + + let int_bytes (z : 'a Script_int.num) = z_bytes (Script_int.to_zint z) + + let manager_operation = step_cost @@ S.safe_int 1_000 + + module Generated_costs = struct + (* Automatically generated costs functions. *) + + (* model N_IAbs_int *) + (* Approximating 0.065045 x term *) + let cost_N_IAbs_int size = S.safe_int (25 + (size lsr 4)) + + (* model N_IAdd_bls12_381_fr *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IAdd_bls12_381_fr = S.safe_int 45 + + (* model N_IAdd_bls12_381_g1 *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IAdd_bls12_381_g1 = S.safe_int 925 + + (* model N_IAdd_bls12_381_g2 *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IAdd_bls12_381_g2 = S.safe_int 2_520 + + let cost_linear_op_int size1 size2 = + let open S_syntax in + let v0 = S.safe_int (Compare.Int.max size1 size2) in + S.safe_int 55 + ((v0 lsr 4) + (v0 lsr 7)) + + (* model N_IAdd_int *) + (* Approximating 0.078154 x term *) + let cost_N_IAdd_int = cost_linear_op_int + + (* model N_IAdd_nat *) + (* Approximating 0.077807 x term *) + let cost_N_IAdd_nat = cost_linear_op_int + + (* model N_IAdd_seconds_to_timestamp *) + (* Approximating 0.078056 x term *) + let cost_N_IAdd_seconds_to_timestamp = cost_linear_op_int + + (* model N_IAdd_tez *) + let cost_N_IAdd_tez = S.safe_int 20 + + (* model N_IAdd_timestamp_to_seconds *) + (* Approximating 0.077771 x term *) + let cost_N_IAdd_timestamp_to_seconds = cost_linear_op_int + + (* model N_IAddress *) + let cost_N_IAddress = S.safe_int 10 + + (* model N_IAmount *) + let cost_N_IAmount = S.safe_int 15 + + (* model N_IAnd *) + let cost_N_IAnd = S.safe_int 20 + + (* model N_IAnd_int_nat *) + (* Approximating 0.076804 x 2 x term *) + let cost_N_IAnd_int_nat size1 size2 = + let open S_syntax in + let v0 = S.safe_int (Compare.Int.min size1 size2) in + S.safe_int 50 + ((v0 lsr 3) + (v0 lsr 6)) + + (* model N_IAnd_nat *) + (* Approximating 0.076804 x term *) + (* The difference with `cost_N_IAnd_int_nat` comes from Zarith, where the + complexity of `Z.logand` depends on the sign of the argument. *) + let cost_N_IAnd_nat size1 size2 = + let open S_syntax in + let v0 = S.safe_int (Compare.Int.min size1 size2) in + S.safe_int 50 + ((v0 lsr 4) + (v0 lsr 7)) + + (* model N_IApply *) + let cost_N_IApply = S.safe_int 160 + + (* model N_IBlake2b *) + (* Approximating 1.120804 x term *) + let cost_N_IBlake2b size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 430 + v0 + (v0 lsr 3) + + (* model N_IBytes_size *) + let cost_N_IBytes_size = S.safe_int 15 + + (* model N_ICar *) + let cost_N_ICar = S.safe_int 10 + + (* model N_ICdr *) + let cost_N_ICdr = S.safe_int 10 + + (* model N_IChainId *) + let cost_N_IChainId = S.safe_int 15 + + (* model N_ICheck_signature_ed25519 *) + (* Approximating 1.123507 x term *) + let cost_N_ICheck_signature_ed25519 size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 65_800 + (v0 + (v0 lsr 3)) + + (* model N_ICheck_signature_p256 *) + (* Approximating 1.111539 x term *) + let cost_N_ICheck_signature_p256 size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 990_000 + (v0 + (v0 lsr 3)) + + (* model N_ICheck_signature_secp256k1 *) + (* Approximating 1.125404 x term *) + let cost_N_ICheck_signature_secp256k1 size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 51_600 + (v0 + (v0 lsr 3)) + + (* model N_IComb *) + (* Approximating 3.531001 x term *) + (* Note: size >= 2, so the cost is never 0 *) + let cost_N_IComb size = + let open S_syntax in + let v0 = S.safe_int size in + (S.safe_int 3 * v0) + (v0 lsr 1) + (v0 lsr 5) + + (* model N_IComb_get *) + (* Approximating 0.573180 x term *) + let cost_N_IComb_get size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 30 + (v0 lsr 1) + (v0 lsr 4) + + (* model N_IComb_set *) + (* Approximating 1.287531 x term *) + let cost_N_IComb_set size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 40 + (v0 + (v0 lsr 2) + (v0 lsr 5)) + + (* Model N_ICompare *) + (* Approximating 0.024413 x term *) + let cost_N_ICompare size1 size2 = + let open S_syntax in + let v0 = S.safe_int (Compare.Int.min size1 size2) in + S.safe_int 35 + ((v0 lsr 6) + (v0 lsr 7)) + + (* model N_IConcat_bytes_pair *) + (* Approximating 0.065017 x term *) + let cost_N_IConcat_bytes_pair size1 size2 = + let open S_syntax in + let v0 = S.safe_int size1 + S.safe_int size2 in + S.safe_int 65 + (v0 lsr 4) + + (* model N_IConcat_string_pair *) + (* Approximating 0.061402 x term *) + let cost_N_IConcat_string_pair size1 size2 = + let open S_syntax in + let v0 = S.safe_int size1 + S.safe_int size2 in + S.safe_int 65 + (v0 lsr 4) + + (* model N_ICons_list *) + let cost_N_ICons_list = S.safe_int 15 + + (* model N_ICons_none *) + let cost_N_ICons_none = S.safe_int 15 + + (* model N_ICons_pair *) + let cost_N_ICons_pair = S.safe_int 15 + + (* model N_ICons_some *) + let cost_N_ICons_some = S.safe_int 15 + + (* model N_IConst *) + let cost_N_IConst = S.safe_int 10 + + (* model N_IContract *) + let cost_N_IContract = S.safe_int 30 + + (* model N_ICreate_contract *) + let cost_N_ICreate_contract = S.safe_int 30 + + (* model N_IDiff_timestamps *) + (* Approximating 0.077922 x term *) + let cost_N_IDiff_timestamps = cost_linear_op_int + + (* model N_IDig *) + (* Approximating 6.750442 x term *) + let cost_N_IDig size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 60 + ((S.safe_int 6 * v0) + (v0 lsr 1) + (v0 lsr 2)) + + (* model N_IDip *) + let cost_N_IDip = S.safe_int 15 + + (* model N_IDipN *) + (* Approximating 1.708122 x term *) + let cost_N_IDipN size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 45 + (v0 + (v0 lsr 1) + (v0 lsr 3)) + + (* model N_IView *) + let cost_N_IView = S.safe_int 1460 + + (* model N_IDrop *) + let cost_N_IDrop = S.safe_int 10 + + (* model N_IDropN *) + (* Approximating 2.713108 x term *) + let cost_N_IDropN size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 60 + (S.safe_int 2 * v0) + (v0 lsr 1) + (v0 lsr 3) + + (* model N_IDug *) + (* Approximating 6.718396 x term *) + let cost_N_IDug size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 60 + ((S.safe_int 6 * v0) + (v0 lsr 1) + (v0 lsr 2)) + + (* model N_IDup *) + let cost_N_IDup = S.safe_int 10 + + (* model N_IDupN *) + (* Approximating 1.129785 x term *) + let cost_N_IDupN size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 20 + v0 + (v0 lsr 3) + + let cost_div_int size1 size2 = + let q = size1 - size2 in + if Compare.Int.(q < 0) then S.safe_int 140 + else + let open S_syntax in + let v0 = S.safe_int q * S.safe_int size2 in + S.safe_int 140 + (v0 lsr 10) + (v0 lsr 11) + (v0 lsr 13) + + (* model N_IEdiv_int *) + (* Approximating 0.001591 x term *) + let cost_N_IEdiv_int = cost_div_int + + (* model N_IEdiv_nat *) + (* Approximating 0.001605 x term *) + let cost_N_IEdiv_nat = cost_div_int + + (* model N_IEdiv_tez *) + let cost_N_IEdiv_tez = S.safe_int 140 + + (* model N_IEdiv_teznat *) + let cost_N_IEdiv_teznat = S.safe_int 140 + + (* model N_IEmpty_big_map *) + let cost_N_IEmpty_big_map = S.safe_int 15 + + (* model N_IEmpty_map *) + let cost_N_IEmpty_map = S.safe_int 220 + + (* model N_IEmpty_set *) + let cost_N_IEmpty_set = S.safe_int 220 + + (* model N_IEq *) + let cost_N_IEq = S.safe_int 15 + + (* model N_IExec *) + let cost_N_IExec = S.safe_int 15 + + (* model N_IFailwith *) + (* let cost_N_IFailwith = S.safe_int 105 *) + + (* model N_IGe *) + let cost_N_IGe = S.safe_int 15 + + (* model N_IGt *) + let cost_N_IGt = S.safe_int 15 + + (* model N_IHalt *) + let cost_N_IHalt = S.safe_int 15 + + (* model N_IHash_key *) + let cost_N_IHash_key = S.safe_int 655 + + (* model N_IIf *) + let cost_N_IIf = S.safe_int 10 + + (* model N_IIf_cons *) + let cost_N_IIf_cons = S.safe_int 10 + + (* model N_IIf_left *) + let cost_N_IIf_left = S.safe_int 10 + + (* model N_IIf_none *) + let cost_N_IIf_none = S.safe_int 10 + + (* model N_IOpt_map *) + let cost_opt_map = S.safe_int 15 + + (* model N_IImplicit_account *) + let cost_N_IImplicit_account = S.safe_int 10 + + (* model N_IInt_bls12_381_z_fr *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IInt_bls12_381_z_fr = S.safe_int 125 + + (* model N_IInt_nat *) + let cost_N_IInt_nat = S.safe_int 15 + + (* model N_IIs_nat *) + let cost_N_IIs_nat = S.safe_int 15 + + (* model N_IKeccak *) + (* Approximating 8.276352 x term *) + let cost_N_IKeccak size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 1350 + ((S.safe_int 8 * v0) + (v0 lsr 2)) + + (* model N_ILambda *) + let cost_N_ILambda = S.safe_int 10 + + (* model N_ILe *) + let cost_N_ILe = S.safe_int 15 + + (* model N_ILeft *) + let cost_N_ILeft = S.safe_int 15 + + (* model N_ILevel *) + let cost_N_ILevel = S.safe_int 15 + + (* model N_IList_iter *) + let cost_N_IList_iter _ = S.safe_int 25 + + (* model N_IList_map *) + let cost_N_IList_map _ = S.safe_int 25 + + (* model N_IList_size *) + let cost_N_IList_size = S.safe_int 15 + + (* model N_ILoop *) + let cost_N_ILoop = S.safe_int 10 + + (* model N_ILoop_left *) + let cost_N_ILoop_left = S.safe_int 10 + + (* model N_ILsl_nat *) + (* Approximating 0.115642 x term *) + let cost_N_ILsl_nat size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 60 + ((v0 lsr 4) + (v0 lsr 5) + (v0 lsr 6)) + + (* model N_ILsr_nat *) + (* Approximating 0.115565 x term *) + let cost_N_ILsr_nat size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 60 + ((v0 lsr 4) + (v0 lsr 5) + (v0 lsr 6)) + + (* model N_ILt *) + let cost_N_ILt = S.safe_int 15 + + (* model N_IMap_get *) + (* Approximating 0.048359 x term *) + let cost_N_IMap_get size1 size2 = + let open S_syntax in + let v0 = size1 * log2 size2 in + S.safe_int 110 + (v0 lsr 5) + (v0 lsr 6) + + (* model N_IMap_get_and_update *) + (* Approximating 0.145661 x term *) + let cost_N_IMap_get_and_update size1 size2 = + let open S_syntax in + let v0 = size1 * log2 size2 in + S.safe_int 135 + (v0 lsr 3) + (v0 lsr 6) + + (* model N_IMap_iter *) + (* Approximating 7.621331 x term *) + let cost_N_IMap_iter size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 70 + (S.safe_int 7 * v0) + (v0 lsr 1) + (v0 lsr 3) + + (* model N_IMap_map *) + (* Approximating 7.46280485884 x term *) + let cost_N_IMap_map size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 265 + ((S.safe_int 7 * v0) + (v0 lsr 1)) + + (* model N_IMap_mem *) + (* Approximating 0.048446 x term *) + let cost_N_IMap_mem size1 size2 = + let open S_syntax in + let v0 = size1 * log2 size2 in + S.safe_int 110 + (v0 lsr 5) + (v0 lsr 6) + + (* model N_IMap_size *) + let cost_N_IMap_size = S.safe_int 15 + + (* model N_IMap_update *) + (* Approximating 0.097072 x term *) + let cost_N_IMap_update size1 size2 = + let open S_syntax in + let v0 = size1 * log2 size2 in + S.safe_int 130 + (v0 lsr 4) + (v0 lsr 5) + + (* model N_IMul_bls12_381_fr *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IMul_bls12_381_fr = S.safe_int 65 + + (* model N_IMul_bls12_381_fr_z *) + (* Approximating 1.059386 x term *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IMul_bls12_381_fr_z size1 = + let open S_syntax in + let v0 = S.safe_int size1 in + S.safe_int 330 + v0 + (v0 lsr 4) + + (* model N_IMul_bls12_381_g1 *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IMul_bls12_381_g1 = S.safe_int 103_000 + + (* model N_IMul_bls12_381_g2 *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IMul_bls12_381_g2 = S.safe_int 220_000 + + (* model N_IMul_bls12_381_z_fr *) + (* Approximating 1.068674 x term *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IMul_bls12_381_z_fr size1 = + let open S_syntax in + let v0 = S.safe_int size1 in + S.safe_int 330 + v0 + (v0 lsr 4) + + let cost_mul size1 size2 = + let open S_syntax in + let a = S.add (S.safe_int size1) (S.safe_int size2) in + let v0 = a * log2 a in + S.safe_int 100 + (v0 lsr 1) + (v0 lsr 2) + (v0 lsr 4) + + (* model N_IMul_int *) + (* Approximating 0.857931 x term *) + let cost_N_IMul_int = cost_mul + + (* model N_IMul_nat *) + (* Approximating 0.861823 x term *) + let cost_N_IMul_nat = cost_mul + + (* model N_IMul_nattez *) + let cost_N_IMul_nattez = S.safe_int 50 + + (* model N_IMul_teznat *) + let cost_N_IMul_teznat = S.safe_int 50 + + (* model N_INeg_bls12_381_fr *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_INeg_bls12_381_fr = S.safe_int 45 + + (* model N_INeg_bls12_381_g1 *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_INeg_bls12_381_g1 = S.safe_int 60 + + (* model N_INeg_bls12_381_g2 *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_INeg_bls12_381_g2 = S.safe_int 85 + + (* model N_INeg *) + (* Approximating 0.066076 x term *) + let cost_N_INeg size = + let open S_syntax in + S.safe_int 40 + (S.safe_int size lsr 4) + + (* model N_INeq *) + let cost_N_INeq = S.safe_int 15 + + (* model N_INil *) + let cost_N_INil = S.safe_int 15 + + (* model N_INot *) + let cost_N_INot = S.safe_int 10 + + (* model N_INot_int *) + (* Approximating 0.075541 x term *) + let cost_N_INot_int size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 50 + ((v0 lsr 4) + (v0 lsr 7)) + + (* model N_INow *) + let cost_N_INow = S.safe_int 15 + + (* model N_IOpen_chest *) + (* 612000 + chest * 19 + time * 19050 *) + let cost_N_IOpen_chest ~chest ~time = + let open S_syntax in + let v0 = S.safe_int chest in + let v1 = S.safe_int time in + S.safe_int 612_000 + (S.safe_int 19 * v0) + (S.safe_int 19050 * v1) + + (* model N_IOr *) + let cost_N_IOr = S.safe_int 15 + + (* model N_IOr_nat *) + (* Approximating 0.075758 x term *) + let cost_N_IOr_nat = cost_linear_op_int + + (* model N_IPairing_check_bls12_381 *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_N_IPairing_check_bls12_381 size = + S.add (S.safe_int 450_000) (S.mul (S.safe_int 342_500) (S.safe_int size)) + + (* model N_IRead_ticket *) + let cost_N_IRead_ticket = S.safe_int 15 + + (* model N_IRight *) + let cost_N_IRight = S.safe_int 15 + + (* model N_ISapling_empty_state *) + let cost_N_ISapling_empty_state = S.safe_int 15 + + (* model N_ISapling_verify_update *) + (* Approximating 1.27167 x term *) + (* Approximating 38.72115 x term *) + let cost_N_ISapling_verify_update size1 size2 = + let open S_syntax in + let v1 = S.safe_int size1 in + let v0 = S.safe_int size2 in + S.safe_int 84_050 + (v1 + (v1 lsr 2)) + (S.safe_int 39 * v0) + + (* model N_ISelf_address *) + let cost_N_ISelf_address = S.safe_int 15 + + (* model N_ISelf *) + let cost_N_ISelf = S.safe_int 15 + + (* model N_ISender *) + let cost_N_ISender = S.safe_int 15 + + (* model N_ISet_delegate *) + let cost_N_ISet_delegate = S.safe_int 40 + + (* model N_ISet_iter *) + (* Approximating 7.633555 x term *) + let cost_N_ISet_iter size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 70 + (S.safe_int 7 * v0) + (v0 lsr 1) + (v0 lsr 3) + + (* model N_ISet_size *) + let cost_N_ISet_size = S.safe_int 15 + + (* model N_ISha256 *) + (* Approximating 4.763264 x term *) + let cost_N_ISha256 size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 600 + ((S.safe_int 4 * v0) + (v0 lsr 1) + (v0 lsr 2)) + + (* model N_ISha3 *) + (* Approximating 8.362339 x term *) + let cost_N_ISha3 = cost_N_IKeccak + + (* model N_ISha512 *) + (* Approximating 3.074641 x term *) + let cost_N_ISha512 size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 680 + (S.safe_int 3 * v0) + + (* model N_ISlice_bytes *) + (* Approximating 0.065752 x term *) + let cost_N_ISlice_bytes size = + let open S_syntax in + S.safe_int 40 + (S.safe_int size lsr 4) + + (* model N_ISlice_string *) + (* Approximating 0.065688 x term *) + let cost_N_ISlice_string size = + let open S_syntax in + S.safe_int 40 + (S.safe_int size lsr 4) + + (* model N_ISource *) + let cost_N_ISource = S.safe_int 15 + + (* model N_ISplit_ticket *) + (* Approximating 0.132362 x term *) + let cost_N_ISplit_ticket size1 size2 = + let open S_syntax in + let v1 = S.safe_int (Compare.Int.max size1 size2) in + S.safe_int 55 + (v1 lsr 3) + + (* model N_IString_size *) + let cost_N_IString_size = S.safe_int 15 + + (* model N_ISub_int *) + (* Approximating 0.077849 x term *) + let cost_N_ISub_int = cost_linear_op_int + + (* model N_ISub_tez *) + let cost_N_ISub_tez = S.safe_int 20 + + (* model N_ISub_tez_legacy *) + let cost_N_ISub_tez_legacy = S.safe_int 20 + + (* model N_ISub_timestamp_seconds *) + (* Approximating 0.077794 x term *) + let cost_N_ISub_timestamp_seconds = cost_linear_op_int + + (* model N_ISwap *) + let cost_N_ISwap = S.safe_int 10 + + (* model N_ITicket *) + let cost_N_ITicket = S.safe_int 15 + + (* model N_ITotal_voting_power *) + let cost_N_ITotal_voting_power = S.safe_int 370 + + (* model N_ITransfer_tokens *) + let cost_N_ITransfer_tokens = S.safe_int 30 + + (* model N_IUncomb *) + (* Approximating 3.944710 x term *) + let cost_N_IUncomb size = + let open S_syntax in + let v0 = S.safe_int size in + S.safe_int 25 + (S.safe_int 4 * v0) + + (* model N_IUnpair *) + let cost_N_IUnpair = S.safe_int 10 + + (* model N_IVoting_power *) + let cost_N_IVoting_power = S.safe_int 530 + + (* model N_IXor *) + let cost_N_IXor = S.safe_int 20 + + (* model N_IXor_nat *) + (* Approximating 0.075601 x term *) + let cost_N_IXor_nat = cost_linear_op_int + + (* model N_KCons *) + let cost_N_KCons = S.safe_int 15 + + (* model N_KIter *) + let cost_N_KIter = S.safe_int 20 + + (* model N_KList_enter_body *) + (* Approximating 1.672196 x term *) + let cost_N_KList_enter_body xs size_ys = + match xs with + | [] -> + let open S_syntax in + let v0 = S.safe_int size_ys in + S.safe_int 40 + (v0 + (v0 lsr 1) + (v0 lsr 3)) + | _ :: _ -> S.safe_int 70 + + (* model N_KList_exit_body *) + let cost_N_KList_exit_body = S.safe_int 30 + + (* model N_KLoop_in *) + let cost_N_KLoop_in = S.safe_int 15 + + (* model N_KLoop_in_left *) + let cost_N_KLoop_in_left = S.safe_int 15 + + (* model N_KMap_enter_body *) + let cost_N_KMap_enter_body = S.safe_int 165 + + (* model N_KNil *) + let cost_N_KNil = S.safe_int 20 + + (* model N_KReturn *) + let cost_N_KReturn = S.safe_int 15 + + (* model N_KView_exit *) + let cost_N_KView_exit = S.safe_int 20 + + (* model N_KMap_head *) + let const_N_KMap_head = S.safe_int 20 + + (* model N_KUndip *) + let cost_N_KUndip = S.safe_int 15 + + (* model DECODING_BLS_FR *) + (* when benchmarking, compile bls12-381-unix without ADX, see + https://gitlab.com/dannywillems/ocaml-bls12-381/-/blob/71d0b4d467fbfaa6452d702fcc408d7a70916a80/README.md#install + *) + let cost_DECODING_BLS_FR = S.safe_int 150 + + (* model DECODING_BLS_G1 *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_DECODING_BLS_G1 = S.safe_int 65_300 + + (* model DECODING_BLS_G2 *) + (* when benchmarking, compile bls12-381-unix without ADX *) + let cost_DECODING_BLS_G2 = S.safe_int 73_300 + + (* model B58CHECK_DECODING_CHAIN_ID *) + let cost_B58CHECK_DECODING_CHAIN_ID = S.safe_int 1_600 + + (* model B58CHECK_DECODING_PUBLIC_KEY_HASH_ed25519 *) + let cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 3_300 + + (* model B58CHECK_DECODING_PUBLIC_KEY_HASH_p256 *) + let cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_p256 = S.safe_int 3_300 + + (* model B58CHECK_DECODING_PUBLIC_KEY_HASH_secp256k1 *) + let cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 3_300 + + (* model B58CHECK_DECODING_PUBLIC_KEY_ed25519 *) + let cost_B58CHECK_DECODING_PUBLIC_KEY_ed25519 = S.safe_int 4_200 + + (* model B58CHECK_DECODING_PUBLIC_KEY_p256 *) + let cost_B58CHECK_DECODING_PUBLIC_KEY_p256 = S.safe_int 325_000 + + (* model B58CHECK_DECODING_PUBLIC_KEY_secp256k1 *) + let cost_B58CHECK_DECODING_PUBLIC_KEY_secp256k1 = S.safe_int 9_000 + + (* model B58CHECK_DECODING_SIGNATURE_ed25519 *) + let cost_B58CHECK_DECODING_SIGNATURE_ed25519 = S.safe_int 6_400 + + (* model B58CHECK_DECODING_SIGNATURE_p256 *) + let cost_B58CHECK_DECODING_SIGNATURE_p256 = S.safe_int 6_400 + + (* model B58CHECK_DECODING_SIGNATURE_secp256k1 *) + let cost_B58CHECK_DECODING_SIGNATURE_secp256k1 = S.safe_int 6_400 + + (* model ENCODING_BLS_FR *) + let cost_ENCODING_BLS_FR = S.safe_int 80 + + (* model ENCODING_BLS_G1 *) + let cost_ENCODING_BLS_G1 = S.safe_int 3200 + + (* model ENCODING_BLS_G2 *) + let cost_ENCODING_BLS_G2 = S.safe_int 3900 + + (* model B58CHECK_ENCODING_CHAIN_ID *) + let cost_B58CHECK_ENCODING_CHAIN_ID = S.safe_int 1_800 + + (* model B58CHECK_ENCODING_PUBLIC_KEY_HASH_ed25519 *) + let cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 3_200 + + (* model B58CHECK_ENCODING_PUBLIC_KEY_HASH_p256 *) + let cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_p256 = S.safe_int 3_200 + + (* model B58CHECK_ENCODING_PUBLIC_KEY_HASH_secp256k1 *) + let cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 3_200 + + (* model B58CHECK_ENCODING_PUBLIC_KEY_ed25519 *) + let cost_B58CHECK_ENCODING_PUBLIC_KEY_ed25519 = S.safe_int 4_500 + + (* model B58CHECK_ENCODING_PUBLIC_KEY_p256 *) + let cost_B58CHECK_ENCODING_PUBLIC_KEY_p256 = S.safe_int 4_550 + + (* model B58CHECK_ENCODING_PUBLIC_KEY_secp256k1 *) + let cost_B58CHECK_ENCODING_PUBLIC_KEY_secp256k1 = S.safe_int 4_950 + + (* model B58CHECK_ENCODING_SIGNATURE_ed25519 *) + let cost_B58CHECK_ENCODING_SIGNATURE_ed25519 = S.safe_int 8_300 + + (* model B58CHECK_ENCODING_SIGNATURE_p256 *) + let cost_B58CHECK_ENCODING_SIGNATURE_p256 = S.safe_int 8_300 + + (* model B58CHECK_ENCODING_SIGNATURE_secp256k1 *) + let cost_B58CHECK_ENCODING_SIGNATURE_secp256k1 = S.safe_int 8_300 + + (* model DECODING_CHAIN_ID *) + let cost_DECODING_CHAIN_ID = S.safe_int 50 + + (* model DECODING_PUBLIC_KEY_HASH_ed25519 *) + let cost_DECODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 50 + + (* model DECODING_PUBLIC_KEY_HASH_p256 *) + let cost_DECODING_PUBLIC_KEY_HASH_p256 = S.safe_int 50 + + (* model DECODING_PUBLIC_KEY_HASH_secp256k1 *) + let cost_DECODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 50 + + (* model DECODING_PUBLIC_KEY_ed25519 *) + let cost_DECODING_PUBLIC_KEY_ed25519 = S.safe_int 60 + + (* model DECODING_PUBLIC_KEY_p256 *) + let cost_DECODING_PUBLIC_KEY_p256 = S.safe_int 320_000 + + (* model DECODING_PUBLIC_KEY_secp256k1 *) + let cost_DECODING_PUBLIC_KEY_secp256k1 = S.safe_int 4_900 + + (* model DECODING_SIGNATURE_ed25519 *) + let cost_DECODING_SIGNATURE_ed25519 = S.safe_int 35 + + (* model DECODING_SIGNATURE_p256 *) + let cost_DECODING_SIGNATURE_p256 = S.safe_int 35 + + (* model DECODING_SIGNATURE_secp256k1 *) + let cost_DECODING_SIGNATURE_secp256k1 = S.safe_int 35 + + (* model DECODING_Chest_key *) + let cost_DECODING_Chest_key = S.safe_int 5900 + + (* model DECODING_Chest *) + (* Approximating 0.039349 x term *) + let cost_DECODING_Chest ~bytes = + let open S_syntax in + let v0 = S.safe_int bytes in + S.safe_int 7400 + (v0 lsr 5) + (v0 lsr 7) + + (* model ENCODING_CHAIN_ID *) + let cost_ENCODING_CHAIN_ID = S.safe_int 50 + + (* model ENCODING_PUBLIC_KEY_HASH_ed25519 *) + let cost_ENCODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 70 + + (* model ENCODING_PUBLIC_KEY_HASH_p256 *) + let cost_ENCODING_PUBLIC_KEY_HASH_p256 = S.safe_int 70 + + (* model ENCODING_PUBLIC_KEY_HASH_secp256k1 *) + let cost_ENCODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 70 + + (* model ENCODING_PUBLIC_KEY_ed25519 *) + let cost_ENCODING_PUBLIC_KEY_ed25519 = S.safe_int 80 + + (* model ENCODING_PUBLIC_KEY_p256 *) + let cost_ENCODING_PUBLIC_KEY_p256 = S.safe_int 90 + + (* model ENCODING_PUBLIC_KEY_secp256k1 *) + let cost_ENCODING_PUBLIC_KEY_secp256k1 = S.safe_int 455 + + (* model ENCODING_SIGNATURE_ed25519 *) + let cost_ENCODING_SIGNATURE_ed25519 = S.safe_int 45 + + (* model ENCODING_SIGNATURE_p256 *) + let cost_ENCODING_SIGNATURE_p256 = S.safe_int 45 + + (* model ENCODING_SIGNATURE_secp256k1 *) + let cost_ENCODING_SIGNATURE_secp256k1 = S.safe_int 45 + + (* model ENCODING_Chest_key *) + let cost_ENCODING_Chest_key = S.safe_int 13500 + + (* model ENCODING_Chest *) + (* Approximating 0.120086 x term *) + let cost_ENCODING_Chest ~plaintext_size = + let open S_syntax in + let v0 = S.safe_int plaintext_size in + S.safe_int 16630 + (v0 lsr 3) + + (* model TIMESTAMP_READABLE_DECODING *) + let cost_TIMESTAMP_READABLE_DECODING = S.safe_int 100 + + (* model TIMESTAMP_READABLE_ENCODING *) + let cost_TIMESTAMP_READABLE_ENCODING = S.safe_int 820 + + (* model CHECK_PRINTABLE *) + let cost_CHECK_PRINTABLE size = + let open S_syntax in + S.safe_int 14 + (S.safe_int 10 * S.safe_int size) + + (* model MERGE_TYPES + This is the estimated cost of one iteration of merge_types, extracted + and copied manually from the parameter fit for the MERGE_TYPES benchmark + (the model is parametric on the size of the type, which we don't have + access to in O(1)). *) + let cost_MERGE_TYPES = S.safe_int 220 + + (* model TYPECHECKING_CODE + This is the cost of one iteration of parse_instr, extracted by hand from the + parameter fit for the TYPECHECKING_CODE benchmark. *) + let cost_TYPECHECKING_CODE = S.safe_int 220 + + (* model UNPARSING_CODE + This is the cost of one iteration of unparse_instr, extracted by hand from the + parameter fit for the UNPARSING_CODE benchmark. *) + let cost_UNPARSING_CODE = S.safe_int 115 + + (* model TYPECHECKING_DATA + This is the cost of one iteration of parse_data, extracted by hand from the + parameter fit for the TYPECHECKING_DATA benchmark. *) + let cost_TYPECHECKING_DATA = S.safe_int 100 + + (* model UNPARSING_DATA + This is the cost of one iteration of unparse_data, extracted by hand from the + parameter fit for the UNPARSING_DATA benchmark. *) + let cost_UNPARSING_DATA = S.safe_int 45 + + (* model PARSE_TYPE + This is the cost of one iteration of parse_ty, extracted by hand from the + parameter fit for the PARSE_TYPE benchmark. *) + let cost_PARSE_TYPE = S.safe_int 60 + + (* model UNPARSE_TYPE + This is the cost of one iteration of unparse_ty, extracted by hand from the + parameter fit for the UNPARSE_TYPE benchmark. *) + let cost_UNPARSE_TYPE type_size = S.mul (S.safe_int 20) type_size + + (* TODO: Add benchmarked value from [Unparse_comparable_type_benchmark]. *) + let cost_UNPARSE_COMPARABLE_TYPE type_size = S.mul (S.safe_int 20) type_size + + (* TODO: benchmark *) + let cost_COMPARABLE_TY_OF_TY = S.safe_int 120 + + (* model SAPLING_TRANSACTION_ENCODING *) + let cost_SAPLING_TRANSACTION_ENCODING ~inputs ~outputs = + S.safe_int (1500 + (inputs * 160) + (outputs * 320)) + + (* model SAPLING_DIFF_ENCODING *) + let cost_SAPLING_DIFF_ENCODING ~nfs ~cms = + S.safe_int ((nfs * 22) + (cms * 215)) + end + + module Interpreter = struct + open Generated_costs + + let drop = atomic_step_cost cost_N_IDrop + + let dup = atomic_step_cost cost_N_IDup + + let swap = atomic_step_cost cost_N_ISwap + + let cons_some = atomic_step_cost cost_N_ICons_some + + let cons_none = atomic_step_cost cost_N_ICons_none + + let if_none = atomic_step_cost cost_N_IIf_none + + let opt_map = atomic_step_cost cost_opt_map + + let cons_pair = atomic_step_cost cost_N_ICons_pair + + let unpair = atomic_step_cost cost_N_IUnpair + + let car = atomic_step_cost cost_N_ICar + + let cdr = atomic_step_cost cost_N_ICdr + + let cons_left = atomic_step_cost cost_N_ILeft + + let cons_right = atomic_step_cost cost_N_IRight + + let if_left = atomic_step_cost cost_N_IIf_left + + let cons_list = atomic_step_cost cost_N_ICons_list + + let nil = atomic_step_cost cost_N_INil + + let if_cons = atomic_step_cost cost_N_IIf_cons + + let list_map : 'a Script_typed_ir.boxed_list -> Gas.cost = + fun {length; _} -> atomic_step_cost (cost_N_IList_map length) + + let list_size = atomic_step_cost cost_N_IList_size + + let list_iter : 'a Script_typed_ir.boxed_list -> Gas.cost = + fun {length; _} -> atomic_step_cost (cost_N_IList_iter length) + + let empty_set = atomic_step_cost cost_N_IEmpty_set + + let set_iter (type a) ((module Box) : a Script_typed_ir.set) = + atomic_step_cost (cost_N_ISet_iter Box.size) + + let set_size = atomic_step_cost cost_N_ISet_size + + let empty_map = atomic_step_cost cost_N_IEmpty_map + + let map_map (type k v) ((module Box) : (k, v) Script_typed_ir.map) = + atomic_step_cost (cost_N_IMap_map Box.size) + + let map_iter (type k v) ((module Box) : (k, v) Script_typed_ir.map) = + atomic_step_cost (cost_N_IMap_iter Box.size) + + let map_size = atomic_step_cost cost_N_IMap_size + + let big_map_elt_size = S.safe_int Script_expr_hash.size + + let big_map_mem ({size; _} : _ Script_typed_ir.big_map_overlay) = + atomic_step_cost (cost_N_IMap_mem big_map_elt_size (S.safe_int size)) + + let big_map_get ({size; _} : _ Script_typed_ir.big_map_overlay) = + atomic_step_cost (cost_N_IMap_get big_map_elt_size (S.safe_int size)) + + let big_map_update ({size; _} : _ Script_typed_ir.big_map_overlay) = + atomic_step_cost (cost_N_IMap_update big_map_elt_size (S.safe_int size)) + + let big_map_get_and_update ({size; _} : _ Script_typed_ir.big_map_overlay) = + atomic_step_cost + (cost_N_IMap_get_and_update big_map_elt_size (S.safe_int size)) + + let add_seconds_timestamp : + 'a Script_int.num -> Script_timestamp.t -> Gas.cost = + fun seconds timestamp -> + let seconds_bytes = int_bytes seconds in + let timestamp_bytes = z_bytes (Script_timestamp.to_zint timestamp) in + atomic_step_cost + (cost_N_IAdd_seconds_to_timestamp seconds_bytes timestamp_bytes) + + let add_timestamp_seconds : + Script_timestamp.t -> 'a Script_int.num -> Gas.cost = + fun timestamp seconds -> + let seconds_bytes = int_bytes seconds in + let timestamp_bytes = z_bytes (Script_timestamp.to_zint timestamp) in + atomic_step_cost + (cost_N_IAdd_timestamp_to_seconds timestamp_bytes seconds_bytes) + + let sub_timestamp_seconds : + Script_timestamp.t -> 'a Script_int.num -> Gas.cost = + fun timestamp seconds -> + let seconds_bytes = int_bytes seconds in + let timestamp_bytes = z_bytes (Script_timestamp.to_zint timestamp) in + atomic_step_cost + (cost_N_ISub_timestamp_seconds timestamp_bytes seconds_bytes) + + let diff_timestamps t1 t2 = + let t1_bytes = z_bytes (Script_timestamp.to_zint t1) in + let t2_bytes = z_bytes (Script_timestamp.to_zint t2) in + atomic_step_cost (cost_N_IDiff_timestamps t1_bytes t2_bytes) + + let concat_string_pair s1 s2 = + atomic_step_cost + (cost_N_IConcat_string_pair + (Script_string.length s1) + (Script_string.length s2)) + + let slice_string s = + atomic_step_cost (cost_N_ISlice_string (Script_string.length s)) + + let string_size = atomic_step_cost cost_N_IString_size + + let concat_bytes_pair b1 b2 = + atomic_step_cost + (cost_N_IConcat_bytes_pair (Bytes.length b1) (Bytes.length b2)) + + let slice_bytes b = atomic_step_cost (cost_N_ISlice_bytes (Bytes.length b)) + + let bytes_size = atomic_step_cost cost_N_IBytes_size + + let add_tez = atomic_step_cost cost_N_IAdd_tez + + let sub_tez = atomic_step_cost cost_N_ISub_tez + + let sub_tez_legacy = atomic_step_cost cost_N_ISub_tez_legacy + + let mul_teznat = atomic_step_cost cost_N_IMul_teznat + + let mul_nattez = atomic_step_cost cost_N_IMul_nattez + + let bool_or = atomic_step_cost cost_N_IOr + + let bool_and = atomic_step_cost cost_N_IAnd + + let bool_xor = atomic_step_cost cost_N_IXor + + let bool_not = atomic_step_cost cost_N_INot + + let is_nat = atomic_step_cost cost_N_IIs_nat + + let abs_int i = atomic_step_cost (cost_N_IAbs_int (int_bytes i)) + + let int_nat = atomic_step_cost cost_N_IInt_nat + + let neg i = atomic_step_cost (cost_N_INeg (int_bytes i)) + + let add_int i1 i2 = + atomic_step_cost (cost_N_IAdd_int (int_bytes i1) (int_bytes i2)) + + let add_nat i1 i2 = + atomic_step_cost (cost_N_IAdd_nat (int_bytes i1) (int_bytes i2)) + + let sub_int i1 i2 = + atomic_step_cost (cost_N_ISub_int (int_bytes i1) (int_bytes i2)) + + let mul_int i1 i2 = + atomic_step_cost (cost_N_IMul_int (int_bytes i1) (int_bytes i2)) + + let mul_nat i1 i2 = + atomic_step_cost (cost_N_IMul_nat (int_bytes i1) (int_bytes i2)) + + let ediv_teznat _tez _n = atomic_step_cost cost_N_IEdiv_teznat + + let ediv_tez = atomic_step_cost cost_N_IEdiv_tez + + let ediv_int i1 i2 = + atomic_step_cost (cost_N_IEdiv_int (int_bytes i1) (int_bytes i2)) + + let ediv_nat i1 i2 = + atomic_step_cost (cost_N_IEdiv_nat (int_bytes i1) (int_bytes i2)) + + let eq = atomic_step_cost cost_N_IEq + + let lsl_nat shifted = atomic_step_cost (cost_N_ILsl_nat (int_bytes shifted)) + + let lsr_nat shifted = atomic_step_cost (cost_N_ILsr_nat (int_bytes shifted)) + + let or_nat n1 n2 = + atomic_step_cost (cost_N_IOr_nat (int_bytes n1) (int_bytes n2)) + + let and_nat n1 n2 = + atomic_step_cost (cost_N_IAnd_nat (int_bytes n1) (int_bytes n2)) + + let and_int_nat n1 n2 = + atomic_step_cost (cost_N_IAnd_int_nat (int_bytes n1) (int_bytes n2)) + + let xor_nat n1 n2 = + atomic_step_cost (cost_N_IXor_nat (int_bytes n1) (int_bytes n2)) + + let not_int i = atomic_step_cost (cost_N_INot_int (int_bytes i)) + + let if_ = atomic_step_cost cost_N_IIf + + let loop = atomic_step_cost cost_N_ILoop + + let loop_left = atomic_step_cost cost_N_ILoop_left + + let dip = atomic_step_cost cost_N_IDip + + let view = atomic_step_cost cost_N_IView + + let check_signature (pkey : Signature.public_key) b = + let cost = + match pkey with + | Ed25519 _ -> cost_N_ICheck_signature_ed25519 (Bytes.length b) + | Secp256k1 _ -> cost_N_ICheck_signature_secp256k1 (Bytes.length b) + | P256 _ -> cost_N_ICheck_signature_p256 (Bytes.length b) + in + atomic_step_cost cost + + let blake2b b = atomic_step_cost (cost_N_IBlake2b (Bytes.length b)) + + let sha256 b = atomic_step_cost (cost_N_ISha256 (Bytes.length b)) + + let sha512 b = atomic_step_cost (cost_N_ISha512 (Bytes.length b)) + + let dign n = atomic_step_cost (cost_N_IDig n) + + let dugn n = atomic_step_cost (cost_N_IDug n) + + let dipn n = atomic_step_cost (cost_N_IDipN n) + + let dropn n = atomic_step_cost (cost_N_IDropN n) + + let voting_power = atomic_step_cost cost_N_IVoting_power + + let total_voting_power = atomic_step_cost cost_N_ITotal_voting_power + + let keccak b = atomic_step_cost (cost_N_IKeccak (Bytes.length b)) + + let sha3 b = atomic_step_cost (cost_N_ISha3 (Bytes.length b)) + + let add_bls12_381_g1 = atomic_step_cost cost_N_IAdd_bls12_381_g1 + + let add_bls12_381_g2 = atomic_step_cost cost_N_IAdd_bls12_381_g2 + + let add_bls12_381_fr = atomic_step_cost cost_N_IAdd_bls12_381_fr + + let mul_bls12_381_g1 = atomic_step_cost cost_N_IMul_bls12_381_g1 + + let mul_bls12_381_g2 = atomic_step_cost cost_N_IMul_bls12_381_g2 + + let mul_bls12_381_fr = atomic_step_cost cost_N_IMul_bls12_381_fr + + let mul_bls12_381_fr_z z = + atomic_step_cost (cost_N_IMul_bls12_381_fr_z (int_bytes z)) + + let mul_bls12_381_z_fr z = + atomic_step_cost (cost_N_IMul_bls12_381_z_fr (int_bytes z)) + + let int_bls12_381_fr = atomic_step_cost cost_N_IInt_bls12_381_z_fr + + let neg_bls12_381_g1 = atomic_step_cost cost_N_INeg_bls12_381_g1 + + let neg_bls12_381_g2 = atomic_step_cost cost_N_INeg_bls12_381_g2 + + let neg_bls12_381_fr = atomic_step_cost cost_N_INeg_bls12_381_fr + + let neq = atomic_step_cost cost_N_INeq + + let pairing_check_bls12_381 (l : 'a Script_typed_ir.boxed_list) = + atomic_step_cost (cost_N_IPairing_check_bls12_381 l.length) + + let comb n = atomic_step_cost (cost_N_IComb n) + + let uncomb n = atomic_step_cost (cost_N_IUncomb n) + + let comb_get n = atomic_step_cost (cost_N_IComb_get n) + + let comb_set n = atomic_step_cost (cost_N_IComb_set n) + + let dupn n = atomic_step_cost (cost_N_IDupN n) + + let sapling_verify_update ~inputs ~outputs = + atomic_step_cost (cost_N_ISapling_verify_update inputs outputs) + + let sapling_empty_state = atomic_step_cost cost_N_ISapling_empty_state + + let halt = atomic_step_cost cost_N_IHalt + + let const = atomic_step_cost cost_N_IConst + + let empty_big_map = atomic_step_cost cost_N_IEmpty_big_map + + let lt = atomic_step_cost cost_N_ILt + + let le = atomic_step_cost cost_N_ILe + + let gt = atomic_step_cost cost_N_IGt + + let ge = atomic_step_cost cost_N_IGe + + let exec = atomic_step_cost cost_N_IExec + + let apply = atomic_step_cost cost_N_IApply + + let lambda = atomic_step_cost cost_N_ILambda + + let address = atomic_step_cost cost_N_IAddress + + let contract = atomic_step_cost cost_N_IContract + + let transfer_tokens = atomic_step_cost cost_N_ITransfer_tokens + + let implicit_account = atomic_step_cost cost_N_IImplicit_account + + let create_contract = atomic_step_cost cost_N_ICreate_contract + + let set_delegate = atomic_step_cost cost_N_ISet_delegate + + let level = atomic_step_cost cost_N_ILevel + + let now = atomic_step_cost cost_N_INow + + let source = atomic_step_cost cost_N_ISource + + let sender = atomic_step_cost cost_N_ISender + + let self = atomic_step_cost cost_N_ISelf + + let self_address = atomic_step_cost cost_N_ISelf_address + + let amount = atomic_step_cost cost_N_IAmount + + let chain_id = atomic_step_cost cost_N_IChainId + + let ticket = atomic_step_cost cost_N_ITicket + + let read_ticket = atomic_step_cost cost_N_IRead_ticket + + let hash_key _ = atomic_step_cost cost_N_IHash_key + + let split_ticket _ amount_a amount_b = + atomic_step_cost + (cost_N_ISplit_ticket (int_bytes amount_a) (int_bytes amount_b)) + + let open_chest ~chest ~time = + let plaintext = Timelock.get_plaintext_size chest in + let log_time = Z.log2 Z.(add one time) in + atomic_step_cost (cost_N_IOpen_chest ~chest:plaintext ~time:log_time) + + (* --------------------------------------------------------------------- *) + (* Semi-hand-crafted models *) + + let compare_unit = atomic_step_cost (S.safe_int 10) + + let compare_pair_tag = atomic_step_cost (S.safe_int 10) + + let compare_union_tag = atomic_step_cost (S.safe_int 10) + + let compare_option_tag = atomic_step_cost (S.safe_int 10) + + let compare_bool = atomic_step_cost (cost_N_ICompare 1 1) + + let compare_signature = atomic_step_cost (S.safe_int 92) + + let compare_string s1 s2 = + atomic_step_cost + (cost_N_ICompare (Script_string.length s1) (Script_string.length s2)) + + let compare_bytes b1 b2 = + atomic_step_cost (cost_N_ICompare (Bytes.length b1) (Bytes.length b2)) + + let compare_mutez = atomic_step_cost (cost_N_ICompare 8 8) + + let compare_int i1 i2 = + atomic_step_cost (cost_N_ICompare (int_bytes i1) (int_bytes i2)) + + let compare_nat n1 n2 = + atomic_step_cost (cost_N_ICompare (int_bytes n1) (int_bytes n2)) + + let compare_key_hash = + let sz = Signature.Public_key_hash.size in + atomic_step_cost (cost_N_ICompare sz sz) + + let compare_key = atomic_step_cost (S.safe_int 92) + + let compare_timestamp t1 t2 = + atomic_step_cost + (cost_N_ICompare + (z_bytes (Script_timestamp.to_zint t1)) + (z_bytes (Script_timestamp.to_zint t2))) + + (* Maximum size of an entrypoint in bytes *) + let entrypoint_size = 31 + + let compare_address = + let sz = Signature.Public_key_hash.size + entrypoint_size in + atomic_step_cost (cost_N_ICompare sz sz) + + let compare_chain_id = atomic_step_cost (S.safe_int 30) + + (* Defunctionalized CPS *) + type cont = + | Compare : 'a Script_typed_ir.comparable_ty * 'a * 'a * cont -> cont + | Return : cont + + let compare : type a. a Script_typed_ir.comparable_ty -> a -> a -> cost = + fun ty x y -> + let rec compare : + type a. + a Script_typed_ir.comparable_ty -> a -> a -> cost -> cont -> cost = + fun ty x y acc k -> + match ty with + | Unit_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_unit) k + | Never_key _ -> ( match x with _ -> .) + | Bool_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_bool) k + | String_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_string x y) k + | Signature_key _ -> + (apply [@tailcall]) Gas.(acc +@ compare_signature) k + | Bytes_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_bytes x y) k + | Mutez_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_mutez) k + | Int_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_int x y) k + | Nat_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_nat x y) k + | Key_hash_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_key_hash) k + | Key_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_key) k + | Timestamp_key _ -> + (apply [@tailcall]) Gas.(acc +@ compare_timestamp x y) k + | Address_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_address) k + | Chain_id_key _ -> (apply [@tailcall]) Gas.(acc +@ compare_chain_id) k + | Pair_key ((tl, _), (tr, _), _) -> + (* Reasonable over-approximation of the cost of lexicographic comparison. *) + let (xl, xr) = x in + let (yl, yr) = y in + (compare [@tailcall]) + tl + xl + yl + Gas.(acc +@ compare_pair_tag) + (Compare (tr, xr, yr, k)) + | Union_key ((tl, _), (tr, _), _) -> ( + match (x, y) with + | (L x, L y) -> + (compare [@tailcall]) tl x y Gas.(acc +@ compare_union_tag) k + | (L _, R _) -> (apply [@tailcall]) Gas.(acc +@ compare_union_tag) k + | (R _, L _) -> (apply [@tailcall]) Gas.(acc +@ compare_union_tag) k + | (R x, R y) -> + (compare [@tailcall]) tr x y Gas.(acc +@ compare_union_tag) k) + | Option_key (t, _) -> ( + match (x, y) with + | (None, None) -> + (apply [@tailcall]) Gas.(acc +@ compare_option_tag) k + | (None, Some _) -> + (apply [@tailcall]) Gas.(acc +@ compare_option_tag) k + | (Some _, None) -> + (apply [@tailcall]) Gas.(acc +@ compare_option_tag) k + | (Some x, Some y) -> + (compare [@tailcall]) t x y Gas.(acc +@ compare_option_tag) k) + and apply cost k = + match k with + | Compare (ty, x, y, k) -> (compare [@tailcall]) ty x y cost k + | Return -> cost + in + compare ty x y Gas.free Return + [@@coq_axiom_with_reason "non top-level mutually recursive function"] + + let view_mem (elt : Script_string.t) + (m : Script_typed_ir.view Script_typed_ir.SMap.t) = + let open S_syntax in + let per_elt_cost = + compare (Script_typed_ir.string_key ~annot:None) elt elt + in + let size = S.safe_int (Script_typed_ir.SMap.cardinal m) in + let intercept = atomic_step_cost (S.safe_int 80) in + Gas.(intercept +@ (log2 size *@ per_elt_cost)) + + let view_get = view_mem + + let view_update (elt : Script_string.t) + (m : Script_typed_ir.view Script_typed_ir.SMap.t) = + let open S_syntax in + let per_elt_cost = + compare (Script_typed_ir.string_key ~annot:None) elt elt + in + let size = S.safe_int (Script_typed_ir.SMap.cardinal m) in + let intercept = atomic_step_cost (S.safe_int 80) in + Gas.(intercept +@ (S.safe_int 2 * log2 size *@ per_elt_cost)) + + let set_mem (type a) (elt : a) ((module Box) : a Script_typed_ir.set) = + let open S_syntax in + let per_elt_cost = compare Box.elt_ty elt elt in + let size = S.safe_int Box.size in + let intercept = atomic_step_cost (S.safe_int 115) in + Gas.(intercept +@ (log2 size *@ per_elt_cost)) + + let set_update (type a) (elt : a) ((module Box) : a Script_typed_ir.set) = + let open S_syntax in + let per_elt_cost = compare Box.elt_ty elt elt in + let size = S.safe_int Box.size in + let intercept = atomic_step_cost (S.safe_int 130) in + (* The 2 factor reflects the update vs mem overhead as benchmarked + on non-structured data *) + Gas.(intercept +@ (S.safe_int 2 * log2 size *@ per_elt_cost)) + + let map_mem (type k v) (elt : k) ((module Box) : (k, v) Script_typed_ir.map) + = + let open S_syntax in + let per_elt_cost = compare Box.key_ty elt elt in + let size = S.safe_int Box.size in + let intercept = atomic_step_cost (S.safe_int 80) in + Gas.(intercept +@ (log2 size *@ per_elt_cost)) + + let map_get = map_mem + + let map_update (type k v) (elt : k) + ((module Box) : (k, v) Script_typed_ir.map) = + let open S_syntax in + let per_elt_cost = compare Box.key_ty elt elt in + let size = S.safe_int Box.size in + let intercept = atomic_step_cost (S.safe_int 80) in + (* The 2 factor reflects the update vs mem overhead as benchmarked + on non-structured data *) + Gas.(intercept +@ (S.safe_int 2 * log2 size *@ per_elt_cost)) + + let map_get_and_update (type k v) (elt : k) + ((module Box) : (k, v) Script_typed_ir.map) = + let open S_syntax in + let per_elt_cost = compare Box.key_ty elt elt in + let size = S.safe_int Box.size in + let intercept = atomic_step_cost (S.safe_int 80) in + (* The 3 factor reflects the update vs mem overhead as benchmarked + on non-structured data *) + Gas.(intercept +@ (S.safe_int 3 * log2 size *@ per_elt_cost)) + + let join_tickets : + 'a Script_typed_ir.comparable_ty -> + 'a Script_typed_ir.ticket -> + 'a Script_typed_ir.ticket -> + Gas.cost = + fun ty ticket_a ticket_b -> + let contents_comparison = + compare ty ticket_a.contents ticket_b.contents + in + Gas.( + contents_comparison +@ compare_address + +@ add_nat ticket_a.amount ticket_b.amount) + + (* Continuations *) + module Control = struct + let nil = atomic_step_cost cost_N_KNil + + let cons = atomic_step_cost cost_N_KCons + + let return = atomic_step_cost cost_N_KReturn + + let view_exit = atomic_step_cost cost_N_KView_exit + + let map_head = atomic_step_cost const_N_KMap_head + + let undip = atomic_step_cost cost_N_KUndip + + let loop_in = atomic_step_cost cost_N_KLoop_in + + let loop_in_left = atomic_step_cost cost_N_KLoop_in_left + + let iter = atomic_step_cost cost_N_KIter + + let list_enter_body xs ys_len = + atomic_step_cost (cost_N_KList_enter_body xs ys_len) + + let list_exit_body = atomic_step_cost cost_N_KList_exit_body + + let map_enter_body = atomic_step_cost cost_N_KMap_enter_body + + let map_exit_body (type k v) (key : k) (map : (k, v) Script_typed_ir.map) + = + map_update key map + end + + (* --------------------------------------------------------------------- *) + (* Hand-crafted models *) + + (* The cost functions below where not benchmarked, a cost model was derived + from looking at similar instructions. *) + + (* Cost for Concat_string is paid in two steps: when entering the interpreter, + the user pays for the cost of computing the information necessary to compute + the actual gas (so it's meta-gas): indeed, one needs to run through the + list of strings to compute the total allocated cost. + [concat_string_precheck] corresponds to the meta-gas cost of this computation. + *) + let concat_string_precheck (l : 'a Script_typed_ir.boxed_list) = + (* we set the precheck to be slightly more expensive than cost_N_IList_iter *) + atomic_step_cost (S.mul (S.safe_int l.length) (S.safe_int 10)) + + (* This is the cost of allocating a string and blitting existing ones into it. *) + let concat_string total_bytes = + atomic_step_cost + S.(add (S.safe_int 100) (S.ediv total_bytes (S.safe_int 10))) + + (* Same story as Concat_string. *) + let concat_bytes total_bytes = + atomic_step_cost + S.(add (S.safe_int 100) (S.ediv total_bytes (S.safe_int 10))) + + (* Cost of access taken care of in Contract_storage.get_balance_carbonated *) + let balance = Gas.free + + (* Cost of Unpack pays two integer comparisons, and a Bytes slice *) + let unpack bytes = + let blen = Bytes.length bytes in + let open S_syntax in + atomic_step_cost (S.safe_int 260 + (S.safe_int blen lsr 3)) + + (* TODO benchmark *) + (* FIXME: imported from 006, needs proper benchmarks *) + let unpack_failed bytes = + (* We cannot instrument failed deserialization, + so we take worst case fees: a set of size 1 bytes values. *) + let blen = String.length bytes in + let len = S.safe_int blen in + let d = Z.numbits (Z.of_int blen) in + (len *@ alloc_mbytes_cost 1) + +@ len + *@ (S.safe_int d *@ (alloc_cost (S.safe_int 3) +@ step_cost S.one)) + end + + module Typechecking = struct + open Generated_costs + + let public_key_optimized = + atomic_step_cost + @@ S.( + max + cost_DECODING_PUBLIC_KEY_ed25519 + (max + cost_DECODING_PUBLIC_KEY_secp256k1 + cost_DECODING_PUBLIC_KEY_p256)) + + let public_key_readable = + atomic_step_cost + @@ S.( + max + cost_B58CHECK_DECODING_PUBLIC_KEY_ed25519 + (max + cost_B58CHECK_DECODING_PUBLIC_KEY_secp256k1 + cost_B58CHECK_DECODING_PUBLIC_KEY_p256)) + + let key_hash_optimized = + atomic_step_cost + @@ S.( + max + cost_DECODING_PUBLIC_KEY_HASH_ed25519 + (max + cost_DECODING_PUBLIC_KEY_HASH_secp256k1 + cost_DECODING_PUBLIC_KEY_HASH_p256)) + + let key_hash_readable = + atomic_step_cost + @@ S.( + max + cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_ed25519 + (max + cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_secp256k1 + cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_p256)) + + let signature_optimized = + atomic_step_cost + @@ S.( + max + cost_DECODING_SIGNATURE_ed25519 + (max + cost_DECODING_SIGNATURE_secp256k1 + cost_DECODING_SIGNATURE_p256)) + + let signature_readable = + atomic_step_cost + @@ S.( + max + cost_B58CHECK_DECODING_SIGNATURE_ed25519 + (max + cost_B58CHECK_DECODING_SIGNATURE_secp256k1 + cost_B58CHECK_DECODING_SIGNATURE_p256)) + + let chain_id_optimized = atomic_step_cost cost_DECODING_CHAIN_ID + + let chain_id_readable = atomic_step_cost cost_B58CHECK_DECODING_CHAIN_ID + + (* Reasonable approximation *) + let address_optimized = key_hash_optimized + + (* Reasonable approximation *) + let contract_optimized = key_hash_optimized + + (* Reasonable approximation *) + let contract_readable = key_hash_readable + + let bls12_381_g1 = atomic_step_cost cost_DECODING_BLS_G1 + + let bls12_381_g2 = atomic_step_cost cost_DECODING_BLS_G2 + + let bls12_381_fr = atomic_step_cost cost_DECODING_BLS_FR + + let check_printable s = + atomic_step_cost (cost_CHECK_PRINTABLE (String.length s)) + + let merge_cycle = atomic_step_cost cost_MERGE_TYPES + + let parse_type_cycle = atomic_step_cost cost_PARSE_TYPE + + let parse_instr_cycle = atomic_step_cost cost_TYPECHECKING_CODE + + let parse_data_cycle = atomic_step_cost cost_TYPECHECKING_DATA + + let comparable_ty_of_ty_cycle = atomic_step_cost cost_COMPARABLE_TY_OF_TY + + (* Cost of a cycle of checking that a type is dupable *) + (* TODO: bench *) + let check_dupable_cycle = atomic_step_cost cost_TYPECHECKING_DATA + + let bool = free + + let unit = free + + let timestamp_readable = atomic_step_cost cost_TIMESTAMP_READABLE_DECODING + + (* Reasonable estimate. *) + let contract = Gas.(S.safe_int 2 *@ public_key_readable) + + (* Balance stored at /contracts/index/hash/balance, on 64 bits *) + let contract_exists = + Gas.cost_of_repr @@ Storage_costs.read_access ~path_length:4 ~read_bytes:8 + + (* Constructing proof arguments consists in a decreasing loop in the result + monad, allocating at each step. We charge a reasonable overapproximation. *) + let proof_argument n = + atomic_step_cost (S.mul (S.safe_int n) (S.safe_int 50)) + + let chest_key = atomic_step_cost cost_DECODING_Chest_key + + let chest ~bytes = atomic_step_cost (cost_DECODING_Chest ~bytes) + end + + module Unparsing = struct + open Generated_costs + + let public_key_optimized = + atomic_step_cost + @@ S.( + max + cost_ENCODING_PUBLIC_KEY_ed25519 + (max + cost_ENCODING_PUBLIC_KEY_secp256k1 + cost_ENCODING_PUBLIC_KEY_p256)) + + let public_key_readable = + atomic_step_cost + @@ S.( + max + cost_B58CHECK_ENCODING_PUBLIC_KEY_ed25519 + (max + cost_B58CHECK_ENCODING_PUBLIC_KEY_secp256k1 + cost_B58CHECK_ENCODING_PUBLIC_KEY_p256)) + + let key_hash_optimized = + atomic_step_cost + @@ S.( + max + cost_ENCODING_PUBLIC_KEY_HASH_ed25519 + (max + cost_ENCODING_PUBLIC_KEY_HASH_secp256k1 + cost_ENCODING_PUBLIC_KEY_HASH_p256)) + + let key_hash_readable = + atomic_step_cost + @@ S.( + max + cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_ed25519 + (max + cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_secp256k1 + cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_p256)) + + let signature_optimized = + atomic_step_cost + @@ S.( + max + cost_ENCODING_SIGNATURE_ed25519 + (max + cost_ENCODING_SIGNATURE_secp256k1 + cost_ENCODING_SIGNATURE_p256)) + + let signature_readable = + atomic_step_cost + @@ S.( + max + cost_B58CHECK_ENCODING_SIGNATURE_ed25519 + (max + cost_B58CHECK_ENCODING_SIGNATURE_secp256k1 + cost_B58CHECK_ENCODING_SIGNATURE_p256)) + + let chain_id_optimized = atomic_step_cost cost_ENCODING_CHAIN_ID + + let chain_id_readable = atomic_step_cost cost_B58CHECK_ENCODING_CHAIN_ID + + let timestamp_readable = atomic_step_cost cost_TIMESTAMP_READABLE_ENCODING + + (* Reasonable approximation *) + let address_optimized = key_hash_optimized + + (* Reasonable approximation *) + let contract_optimized = key_hash_optimized + + (* Reasonable approximation *) + let contract_readable = key_hash_readable + + let bls12_381_g1 = atomic_step_cost cost_ENCODING_BLS_G1 + + let bls12_381_g2 = atomic_step_cost cost_ENCODING_BLS_G2 + + let bls12_381_fr = atomic_step_cost cost_ENCODING_BLS_FR + + let unparse_type ty = + atomic_step_cost + @@ cost_UNPARSE_TYPE Script_typed_ir.(ty_size ty |> Type_size.to_int) + + let unparse_comparable_type comp_ty = + atomic_step_cost + @@ cost_UNPARSE_COMPARABLE_TYPE + Script_typed_ir.(comparable_ty_size comp_ty |> Type_size.to_int) + + let unparse_instr_cycle = atomic_step_cost cost_UNPARSING_CODE + + let unparse_data_cycle = atomic_step_cost cost_UNPARSING_DATA + + let unit = Gas.free + + (* Reasonable estimate. *) + let contract = Gas.(S.safe_int 2 *@ public_key_readable) + + (* Reuse 006 costs. *) + let operation bytes = Script.bytes_node_cost bytes + + let sapling_transaction (t : Sapling.transaction) = + let inputs = List.length t.inputs in + let outputs = List.length t.outputs in + atomic_step_cost (cost_SAPLING_TRANSACTION_ENCODING ~inputs ~outputs) + + let sapling_diff (d : Sapling.diff) = + let nfs = List.length d.nullifiers in + let cms = List.length d.commitments_and_ciphertexts in + atomic_step_cost (cost_SAPLING_DIFF_ENCODING ~nfs ~cms) + + let chest_key = atomic_step_cost cost_ENCODING_Chest_key + + let chest ~plaintext_size = + atomic_step_cost (cost_ENCODING_Chest ~plaintext_size) + end +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_gas.mli b/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_gas.mli new file mode 100644 index 000000000000..2b4674cbcca1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_gas.mli @@ -0,0 +1,506 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +module Cost_of : sig + val manager_operation : Gas.cost + + module Interpreter : sig + val drop : Gas.cost + + val dup : Gas.cost + + val swap : Gas.cost + + val cons_some : Gas.cost + + val cons_none : Gas.cost + + val if_none : Gas.cost + + val opt_map : Gas.cost + + val cons_pair : Gas.cost + + val unpair : Gas.cost + + val car : Gas.cost + + val cdr : Gas.cost + + val cons_left : Gas.cost + + val cons_right : Gas.cost + + val if_left : Gas.cost + + val cons_list : Gas.cost + + val nil : Gas.cost + + val if_cons : Gas.cost + + val list_map : 'a Script_typed_ir.boxed_list -> Gas.cost + + val list_size : Gas.cost + + val list_iter : 'a Script_typed_ir.boxed_list -> Gas.cost + + val empty_set : Gas.cost + + val set_iter : 'a Script_typed_ir.set -> Gas.cost + + val set_mem : 'a -> 'a Script_typed_ir.set -> Gas.cost + + val set_update : 'a -> 'a Script_typed_ir.set -> Gas.cost + + val set_size : Gas.cost + + val empty_map : Gas.cost + + val map_map : ('k, 'v) Script_typed_ir.map -> Gas.cost + + val map_iter : ('k, 'v) Script_typed_ir.map -> Gas.cost + + val map_mem : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost + + val map_get : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost + + val map_update : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost + + val map_get_and_update : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost + + val big_map_mem : (_, _) Script_typed_ir.big_map_overlay -> Gas.cost + + val big_map_get : (_, _) Script_typed_ir.big_map_overlay -> Gas.cost + + val big_map_update : (_, _) Script_typed_ir.big_map_overlay -> Gas.cost + + val big_map_get_and_update : + (_, _) Script_typed_ir.big_map_overlay -> Gas.cost + + val map_size : Gas.cost + + val add_seconds_timestamp : + 'a Script_int.num -> Script_timestamp.t -> Gas.cost + + val add_timestamp_seconds : + Script_timestamp.t -> 'a Script_int.num -> Gas.cost + + val sub_timestamp_seconds : + Script_timestamp.t -> 'a Script_int.num -> Gas.cost + + val diff_timestamps : Script_timestamp.t -> Script_timestamp.t -> Gas.cost + + val concat_string_pair : Script_string.t -> Script_string.t -> Gas.cost + + val slice_string : Script_string.t -> Gas.cost + + val string_size : Gas.cost + + val concat_bytes_pair : bytes -> bytes -> Gas.cost + + val slice_bytes : bytes -> Gas.cost + + val bytes_size : Gas.cost + + val add_tez : Gas.cost + + val sub_tez : Gas.cost + + val sub_tez_legacy : Gas.cost + + val mul_teznat : Gas.cost + + val mul_nattez : Gas.cost + + val bool_or : Gas.cost + + val bool_and : Gas.cost + + val bool_xor : Gas.cost + + val bool_not : Gas.cost + + val is_nat : Gas.cost + + val abs_int : Alpha_context.Script_int.z Script_int.num -> Gas.cost + + val int_nat : Gas.cost + + val neg : 'a Script_int.num -> Gas.cost + + val add_int : 'a Script_int.num -> 'b Script_int.num -> Gas.cost + + val add_nat : + Alpha_context.Script_int.n Script_int.num -> + Alpha_context.Script_int.n Script_int.num -> + Gas.cost + + val sub_int : 'a Script_int.num -> 'b Script_int.num -> Gas.cost + + val mul_int : 'a Script_int.num -> 'b Script_int.num -> Gas.cost + + val mul_nat : + Alpha_context.Script_int.n Script_int.num -> 'a Script_int.num -> Gas.cost + + val ediv_teznat : 'a -> 'b Script_int.num -> Gas.cost + + val ediv_tez : Gas.cost + + val ediv_int : 'a Script_int.num -> 'b Script_int.num -> Gas.cost + + val ediv_nat : + Alpha_context.Script_int.n Script_int.num -> 'a Script_int.num -> Gas.cost + + val eq : Gas.cost + + val lsl_nat : 'a Script_int.num -> Gas.cost + + val lsr_nat : 'a Script_int.num -> Gas.cost + + val or_nat : 'a Script_int.num -> 'b Script_int.num -> Gas.cost + + val and_nat : 'a Script_int.num -> 'b Script_int.num -> Gas.cost + + val and_int_nat : + Alpha_context.Script_int.z Script_int.num -> + Alpha_context.Script_int.n Script_int.num -> + Gas.cost + + val xor_nat : 'a Script_int.num -> 'b Script_int.num -> Gas.cost + + val not_int : 'a Script_int.num -> Gas.cost + + val if_ : Gas.cost + + val loop : Gas.cost + + val loop_left : Gas.cost + + val dip : Gas.cost + + val check_signature : Signature.public_key -> bytes -> Gas.cost + + val blake2b : bytes -> Gas.cost + + val sha256 : bytes -> Gas.cost + + val sha512 : bytes -> Gas.cost + + val dign : int -> Gas.cost + + val dugn : int -> Gas.cost + + val dipn : int -> Gas.cost + + val dropn : int -> Gas.cost + + val voting_power : Gas.cost + + val total_voting_power : Gas.cost + + val keccak : bytes -> Gas.cost + + val sha3 : bytes -> Gas.cost + + val add_bls12_381_g1 : Gas.cost + + val add_bls12_381_g2 : Gas.cost + + val add_bls12_381_fr : Gas.cost + + val mul_bls12_381_g1 : Gas.cost + + val mul_bls12_381_g2 : Gas.cost + + val mul_bls12_381_fr : Gas.cost + + val mul_bls12_381_fr_z : 'a Script_int.num -> Gas.cost + + val mul_bls12_381_z_fr : 'a Script_int.num -> Gas.cost + + val int_bls12_381_fr : Gas.cost + + val neg_bls12_381_g1 : Gas.cost + + val neg_bls12_381_g2 : Gas.cost + + val neg_bls12_381_fr : Gas.cost + + val neq : Gas.cost + + val pairing_check_bls12_381 : 'a Script_typed_ir.boxed_list -> Gas.cost + + val comb : int -> Gas.cost + + val uncomb : int -> Gas.cost + + val comb_get : int -> Gas.cost + + val comb_set : int -> Gas.cost + + val dupn : int -> Gas.cost + + val compare : 'a Script_typed_ir.comparable_ty -> 'a -> 'a -> Gas.cost + + val concat_string_precheck : 'a Script_typed_ir.boxed_list -> Gas.cost + + val concat_string : + Saturation_repr.may_saturate Saturation_repr.t -> Gas.cost + + val concat_bytes : + Saturation_repr.may_saturate Saturation_repr.t -> Gas.cost + + val halt : Gas.cost + + val const : Gas.cost + + val empty_big_map : Gas.cost + + val lt : Gas.cost + + val le : Gas.cost + + val gt : Gas.cost + + val ge : Gas.cost + + val exec : Gas.cost + + val apply : Gas.cost + + val lambda : Gas.cost + + val address : Gas.cost + + val contract : Gas.cost + + val view : Gas.cost + + val view_mem : + Script_string.t -> Script_typed_ir.view Script_typed_ir.SMap.t -> Gas.cost + + val view_get : + Script_string.t -> Script_typed_ir.view Script_typed_ir.SMap.t -> Gas.cost + + val view_update : + Script_string.t -> Script_typed_ir.view Script_typed_ir.SMap.t -> Gas.cost + + val transfer_tokens : Gas.cost + + val implicit_account : Gas.cost + + val create_contract : Gas.cost + + val set_delegate : Gas.cost + + val balance : Gas.cost + + val level : Gas.cost + + val now : Gas.cost + + val hash_key : Signature.Public_key.t -> Gas.cost + + val source : Gas.cost + + val sender : Gas.cost + + val self : Gas.cost + + val self_address : Gas.cost + + val amount : Gas.cost + + val chain_id : Gas.cost + + val unpack : bytes -> Gas.cost + + val unpack_failed : string -> Gas.cost + + val sapling_empty_state : Gas.cost + + val sapling_verify_update : inputs:int -> outputs:int -> Gas.cost + + val ticket : Gas.cost + + val read_ticket : Gas.cost + + val split_ticket : + 'a Script_int.num -> 'a Script_int.num -> 'a Script_int.num -> Gas.cost + + val join_tickets : + 'a Script_typed_ir.comparable_ty -> + 'a Script_typed_ir.ticket -> + 'a Script_typed_ir.ticket -> + Gas.cost + + val open_chest : chest:Timelock.chest -> time:Z.t -> Gas.cost + + module Control : sig + val nil : Gas.cost + + val cons : Gas.cost + + val return : Gas.cost + + val view_exit : Gas.cost + + val map_head : Gas.cost + + val undip : Gas.cost + + val loop_in : Gas.cost + + val loop_in_left : Gas.cost + + val iter : Gas.cost + + val list_enter_body : 'a list -> int -> Gas.cost + + val list_exit_body : Gas.cost + + val map_enter_body : Gas.cost + + val map_exit_body : 'k -> ('k, 'v) Script_typed_ir.map -> Gas.cost + end + end + + module Typechecking : sig + val public_key_optimized : Gas.cost + + val public_key_readable : Gas.cost + + val key_hash_optimized : Gas.cost + + val key_hash_readable : Gas.cost + + val signature_optimized : Gas.cost + + val signature_readable : Gas.cost + + val chain_id_optimized : Gas.cost + + val chain_id_readable : Gas.cost + + val address_optimized : Gas.cost + + val contract_optimized : Gas.cost + + val contract_readable : Gas.cost + + val bls12_381_g1 : Gas.cost + + val bls12_381_g2 : Gas.cost + + val bls12_381_fr : Gas.cost + + val check_printable : string -> Gas.cost + + val merge_cycle : Gas.cost + + val parse_type_cycle : Gas.cost + + val parse_instr_cycle : Gas.cost + + val parse_data_cycle : Gas.cost + + val comparable_ty_of_ty_cycle : Gas.cost + + val check_dupable_cycle : Gas.cost + + val bool : Gas.cost + + val unit : Gas.cost + + val timestamp_readable : Gas.cost + + val contract : Gas.cost + + val contract_exists : Gas.cost + + val proof_argument : int -> Gas.cost + + val chest_key : Gas.cost + + val chest : bytes:int -> Gas.cost + end + + module Unparsing : sig + val public_key_optimized : Gas.cost + + val public_key_readable : Gas.cost + + val key_hash_optimized : Gas.cost + + val key_hash_readable : Gas.cost + + val signature_optimized : Gas.cost + + val signature_readable : Gas.cost + + val chain_id_optimized : Gas.cost + + val chain_id_readable : Gas.cost + + val timestamp_readable : Gas.cost + + val address_optimized : Gas.cost + + val contract_optimized : Gas.cost + + val contract_readable : Gas.cost + + val bls12_381_g1 : Gas.cost + + val bls12_381_g2 : Gas.cost + + val bls12_381_fr : Gas.cost + + val unparse_type : 'a Script_typed_ir.ty -> Gas.cost + + val unparse_comparable_type : 'a Script_typed_ir.comparable_ty -> Gas.cost + + val unparse_instr_cycle : Gas.cost + + val unparse_data_cycle : Gas.cost + + val unit : Gas.cost + + val contract : Gas.cost + + val operation : bytes -> Gas.cost + + val sapling_transaction : Sapling.transaction -> Gas.cost + + val sapling_diff : Sapling.diff -> Gas.cost + + val chest_key : Gas.cost + + val chest : plaintext_size:int -> Gas.cost + end +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_primitives.ml b/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_primitives.ml new file mode 100644 index 000000000000..c1434b14ec14 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_primitives.ml @@ -0,0 +1,799 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Micheline + +type error += Unknown_primitive_name of string + +type error += Invalid_case of string + +type error += + | Invalid_primitive_name of + string Micheline.canonical * Micheline.canonical_location + +type prim = + | K_parameter + | K_storage + | K_code + | K_view + | D_False + | D_Elt + | D_Left + | D_None + | D_Pair + | D_Right + | D_Some + | D_True + | D_Unit + | I_PACK + | I_UNPACK + | I_BLAKE2B + | I_SHA256 + | I_SHA512 + | I_ABS + | I_ADD + | I_AMOUNT + | I_AND + | I_BALANCE + | I_CAR + | I_CDR + | I_CHAIN_ID + | I_CHECK_SIGNATURE + | I_COMPARE + | I_CONCAT + | I_CONS + | I_CREATE_ACCOUNT + | I_CREATE_CONTRACT + | I_IMPLICIT_ACCOUNT + | I_DIP + | I_DROP + | I_DUP + | I_VIEW + | I_EDIV + | I_EMPTY_BIG_MAP + | I_EMPTY_MAP + | I_EMPTY_SET + | I_EQ + | I_EXEC + | I_APPLY + | I_FAILWITH + | I_GE + | I_GET + | I_GET_AND_UPDATE + | I_GT + | I_HASH_KEY + | I_IF + | I_IF_CONS + | I_IF_LEFT + | I_IF_NONE + | I_INT + | I_LAMBDA + | I_LE + | I_LEFT + | I_LEVEL + | I_LOOP + | I_LSL + | I_LSR + | I_LT + | I_MAP + | I_MEM + | I_MUL + | I_NEG + | I_NEQ + | I_NIL + | I_NONE + | I_NOT + | I_NOW + | I_OR + | I_PAIR + | I_UNPAIR + | I_PUSH + | I_RIGHT + | I_SIZE + | I_SOME + | I_SOURCE + | I_SENDER + | I_SELF + | I_SELF_ADDRESS + | I_SLICE + | I_STEPS_TO_QUOTA + | I_SUB + | I_SUB_MUTEZ + | I_SWAP + | I_TRANSFER_TOKENS + | I_SET_DELEGATE + | I_UNIT + | I_UPDATE + | I_XOR + | I_ITER + | I_LOOP_LEFT + | I_ADDRESS + | I_CONTRACT + | I_ISNAT + | I_CAST + | I_RENAME + | I_SAPLING_EMPTY_STATE + | I_SAPLING_VERIFY_UPDATE + | I_DIG + | I_DUG + | I_NEVER + | I_VOTING_POWER + | I_TOTAL_VOTING_POWER + | I_KECCAK + | I_SHA3 + | I_PAIRING_CHECK + | I_TICKET + | I_READ_TICKET + | I_SPLIT_TICKET + | I_JOIN_TICKETS + | I_OPEN_CHEST + | T_bool + | T_contract + | T_int + | T_key + | T_key_hash + | T_lambda + | T_list + | T_map + | T_big_map + | T_nat + | T_option + | T_or + | T_pair + | T_set + | T_signature + | T_string + | T_bytes + | T_mutez + | T_timestamp + | T_unit + | T_operation + | T_address + | T_sapling_transaction + | T_sapling_state + | T_chain_id + | T_never + | T_bls12_381_g1 + | T_bls12_381_g2 + | T_bls12_381_fr + | T_ticket + | T_chest_key + | T_chest + | H_constant + +(* Auxiliary types for error documentation. + All the prim constructor prefixes must match their namespace. *) +type namespace = + | (* prefix "T" *) Type_namespace + | (* prefix "D" *) Constant_namespace + | (* prefix "I" *) Instr_namespace + | (* prefix "K" *) Keyword_namespace + | (* prefix "H" *) Constant_hash_namespace + +let namespace = function + | K_code | K_view | K_parameter | K_storage -> Keyword_namespace + | D_Elt | D_False | D_Left | D_None | D_Pair | D_Right | D_Some | D_True + | D_Unit -> + Constant_namespace + | I_ABS | I_ADD | I_ADDRESS | I_AMOUNT | I_AND | I_APPLY | I_BALANCE + | I_BLAKE2B | I_CAR | I_CAST | I_CDR | I_CHAIN_ID | I_CHECK_SIGNATURE + | I_COMPARE | I_CONCAT | I_CONS | I_CONTRACT | I_CREATE_ACCOUNT + | I_CREATE_CONTRACT | I_DIG | I_DIP | I_DROP | I_DUG | I_DUP | I_VIEW | I_EDIV + | I_EMPTY_BIG_MAP | I_EMPTY_MAP | I_EMPTY_SET | I_EQ | I_EXEC | I_FAILWITH + | I_GE | I_GET | I_GET_AND_UPDATE | I_GT | I_HASH_KEY | I_IF | I_IF_CONS + | I_IF_LEFT | I_IF_NONE | I_IMPLICIT_ACCOUNT | I_INT | I_ISNAT | I_ITER + | I_JOIN_TICKETS | I_KECCAK | I_LAMBDA | I_LE | I_LEFT | I_LEVEL | I_LOOP + | I_LOOP_LEFT | I_LSL | I_LSR | I_LT | I_MAP | I_MEM | I_MUL | I_NEG | I_NEQ + | I_NEVER | I_NIL | I_NONE | I_NOT | I_NOW | I_OR | I_PACK | I_PAIR + | I_PAIRING_CHECK | I_PUSH | I_READ_TICKET | I_RENAME | I_RIGHT + | I_SAPLING_EMPTY_STATE | I_SAPLING_VERIFY_UPDATE | I_SELF | I_SELF_ADDRESS + | I_SENDER | I_SET_DELEGATE | I_SHA256 | I_SHA512 | I_SHA3 | I_SIZE | I_SLICE + | I_SOME | I_SOURCE | I_SPLIT_TICKET | I_STEPS_TO_QUOTA | I_SUB | I_SUB_MUTEZ + | I_SWAP | I_TICKET | I_TOTAL_VOTING_POWER | I_TRANSFER_TOKENS | I_UNIT + | I_UNPACK | I_UNPAIR | I_UPDATE | I_VOTING_POWER | I_XOR | I_OPEN_CHEST -> + Instr_namespace + | T_address | T_big_map | T_bool | T_bytes | T_chain_id | T_contract | T_int + | T_key | T_key_hash | T_lambda | T_list | T_map | T_mutez | T_nat | T_never + | T_operation | T_option | T_or | T_pair | T_sapling_state + | T_sapling_transaction | T_set | T_signature | T_string | T_timestamp + | T_unit | T_bls12_381_fr | T_bls12_381_g1 | T_bls12_381_g2 | T_ticket + | T_chest_key | T_chest -> + Type_namespace + | H_constant -> Constant_hash_namespace + +let valid_case name = + let is_lower = function '_' | 'a' .. 'z' -> true | _ -> false in + let is_upper = function '_' | 'A' .. 'Z' -> true | _ -> false in + let[@coq_struct "a_value"] rec for_all a b f = + Compare.Int.(a > b) || (f a && for_all (a + 1) b f) + in + let len = String.length name in + Compare.Int.(len <> 0) + && Compare.Char.(name.[0] <> '_') + && ((is_upper name.[0] && for_all 1 (len - 1) (fun i -> is_upper name.[i])) + || (is_upper name.[0] && for_all 1 (len - 1) (fun i -> is_lower name.[i])) + || (is_lower name.[0] && for_all 1 (len - 1) (fun i -> is_lower name.[i])) + ) + +let string_of_prim = function + | K_parameter -> "parameter" + | K_storage -> "storage" + | K_code -> "code" + | K_view -> "view" + | D_False -> "False" + | D_Elt -> "Elt" + | D_Left -> "Left" + | D_None -> "None" + | D_Pair -> "Pair" + | D_Right -> "Right" + | D_Some -> "Some" + | D_True -> "True" + | D_Unit -> "Unit" + | I_PACK -> "PACK" + | I_UNPACK -> "UNPACK" + | I_BLAKE2B -> "BLAKE2B" + | I_SHA256 -> "SHA256" + | I_SHA512 -> "SHA512" + | I_ABS -> "ABS" + | I_ADD -> "ADD" + | I_AMOUNT -> "AMOUNT" + | I_AND -> "AND" + | I_BALANCE -> "BALANCE" + | I_CAR -> "CAR" + | I_CDR -> "CDR" + | I_CHAIN_ID -> "CHAIN_ID" + | I_CHECK_SIGNATURE -> "CHECK_SIGNATURE" + | I_COMPARE -> "COMPARE" + | I_CONCAT -> "CONCAT" + | I_CONS -> "CONS" + | I_CREATE_ACCOUNT -> "CREATE_ACCOUNT" + | I_CREATE_CONTRACT -> "CREATE_CONTRACT" + | I_IMPLICIT_ACCOUNT -> "IMPLICIT_ACCOUNT" + | I_DIP -> "DIP" + | I_DROP -> "DROP" + | I_DUP -> "DUP" + | I_EDIV -> "EDIV" + | I_EMPTY_BIG_MAP -> "EMPTY_BIG_MAP" + | I_EMPTY_MAP -> "EMPTY_MAP" + | I_EMPTY_SET -> "EMPTY_SET" + | I_EQ -> "EQ" + | I_EXEC -> "EXEC" + | I_APPLY -> "APPLY" + | I_FAILWITH -> "FAILWITH" + | I_GE -> "GE" + | I_GET -> "GET" + | I_GET_AND_UPDATE -> "GET_AND_UPDATE" + | I_GT -> "GT" + | I_HASH_KEY -> "HASH_KEY" + | I_IF -> "IF" + | I_IF_CONS -> "IF_CONS" + | I_IF_LEFT -> "IF_LEFT" + | I_IF_NONE -> "IF_NONE" + | I_INT -> "INT" + | I_LAMBDA -> "LAMBDA" + | I_LE -> "LE" + | I_LEFT -> "LEFT" + | I_LEVEL -> "LEVEL" + | I_LOOP -> "LOOP" + | I_LSL -> "LSL" + | I_LSR -> "LSR" + | I_LT -> "LT" + | I_MAP -> "MAP" + | I_MEM -> "MEM" + | I_MUL -> "MUL" + | I_NEG -> "NEG" + | I_NEQ -> "NEQ" + | I_NIL -> "NIL" + | I_NONE -> "NONE" + | I_NOT -> "NOT" + | I_NOW -> "NOW" + | I_OR -> "OR" + | I_PAIR -> "PAIR" + | I_PUSH -> "PUSH" + | I_RIGHT -> "RIGHT" + | I_SIZE -> "SIZE" + | I_SOME -> "SOME" + | I_SOURCE -> "SOURCE" + | I_SENDER -> "SENDER" + | I_SELF -> "SELF" + | I_SELF_ADDRESS -> "SELF_ADDRESS" + | I_SLICE -> "SLICE" + | I_STEPS_TO_QUOTA -> "STEPS_TO_QUOTA" + | I_SUB -> "SUB" + | I_SUB_MUTEZ -> "SUB_MUTEZ" + | I_SWAP -> "SWAP" + | I_TRANSFER_TOKENS -> "TRANSFER_TOKENS" + | I_SET_DELEGATE -> "SET_DELEGATE" + | I_UNIT -> "UNIT" + | I_UNPAIR -> "UNPAIR" + | I_UPDATE -> "UPDATE" + | I_XOR -> "XOR" + | I_ITER -> "ITER" + | I_LOOP_LEFT -> "LOOP_LEFT" + | I_ADDRESS -> "ADDRESS" + | I_CONTRACT -> "CONTRACT" + | I_ISNAT -> "ISNAT" + | I_CAST -> "CAST" + | I_RENAME -> "RENAME" + | I_SAPLING_EMPTY_STATE -> "SAPLING_EMPTY_STATE" + | I_SAPLING_VERIFY_UPDATE -> "SAPLING_VERIFY_UPDATE" + | I_DIG -> "DIG" + | I_DUG -> "DUG" + | I_NEVER -> "NEVER" + | I_VOTING_POWER -> "VOTING_POWER" + | I_TOTAL_VOTING_POWER -> "TOTAL_VOTING_POWER" + | I_KECCAK -> "KECCAK" + | I_SHA3 -> "SHA3" + | I_PAIRING_CHECK -> "PAIRING_CHECK" + | I_TICKET -> "TICKET" + | I_READ_TICKET -> "READ_TICKET" + | I_SPLIT_TICKET -> "SPLIT_TICKET" + | I_JOIN_TICKETS -> "JOIN_TICKETS" + | I_OPEN_CHEST -> "OPEN_CHEST" + | I_VIEW -> "VIEW" + | T_bool -> "bool" + | T_contract -> "contract" + | T_int -> "int" + | T_key -> "key" + | T_key_hash -> "key_hash" + | T_lambda -> "lambda" + | T_list -> "list" + | T_map -> "map" + | T_big_map -> "big_map" + | T_nat -> "nat" + | T_option -> "option" + | T_or -> "or" + | T_pair -> "pair" + | T_set -> "set" + | T_signature -> "signature" + | T_string -> "string" + | T_bytes -> "bytes" + | T_mutez -> "mutez" + | T_timestamp -> "timestamp" + | T_unit -> "unit" + | T_operation -> "operation" + | T_address -> "address" + | T_sapling_state -> "sapling_state" + | T_sapling_transaction -> "sapling_transaction" + | T_chain_id -> "chain_id" + | T_never -> "never" + | T_bls12_381_g1 -> "bls12_381_g1" + | T_bls12_381_g2 -> "bls12_381_g2" + | T_bls12_381_fr -> "bls12_381_fr" + | T_ticket -> "ticket" + | T_chest_key -> "chest_key" + | T_chest -> "chest" + | H_constant -> "constant" + +let prim_of_string = function + | "parameter" -> ok K_parameter + | "storage" -> ok K_storage + | "code" -> ok K_code + | "view" -> ok K_view + | "False" -> ok D_False + | "Elt" -> ok D_Elt + | "Left" -> ok D_Left + | "None" -> ok D_None + | "Pair" -> ok D_Pair + | "Right" -> ok D_Right + | "Some" -> ok D_Some + | "True" -> ok D_True + | "Unit" -> ok D_Unit + | "PACK" -> ok I_PACK + | "UNPACK" -> ok I_UNPACK + | "BLAKE2B" -> ok I_BLAKE2B + | "SHA256" -> ok I_SHA256 + | "SHA512" -> ok I_SHA512 + | "ABS" -> ok I_ABS + | "ADD" -> ok I_ADD + | "AMOUNT" -> ok I_AMOUNT + | "AND" -> ok I_AND + | "BALANCE" -> ok I_BALANCE + | "CAR" -> ok I_CAR + | "CDR" -> ok I_CDR + | "CHAIN_ID" -> ok I_CHAIN_ID + | "CHECK_SIGNATURE" -> ok I_CHECK_SIGNATURE + | "COMPARE" -> ok I_COMPARE + | "CONCAT" -> ok I_CONCAT + | "CONS" -> ok I_CONS + | "CREATE_ACCOUNT" -> ok I_CREATE_ACCOUNT + | "CREATE_CONTRACT" -> ok I_CREATE_CONTRACT + | "IMPLICIT_ACCOUNT" -> ok I_IMPLICIT_ACCOUNT + | "DIP" -> ok I_DIP + | "DROP" -> ok I_DROP + | "DUP" -> ok I_DUP + | "VIEW" -> ok I_VIEW + | "EDIV" -> ok I_EDIV + | "EMPTY_BIG_MAP" -> ok I_EMPTY_BIG_MAP + | "EMPTY_MAP" -> ok I_EMPTY_MAP + | "EMPTY_SET" -> ok I_EMPTY_SET + | "EQ" -> ok I_EQ + | "EXEC" -> ok I_EXEC + | "APPLY" -> ok I_APPLY + | "FAILWITH" -> ok I_FAILWITH + | "GE" -> ok I_GE + | "GET" -> ok I_GET + | "GET_AND_UPDATE" -> ok I_GET_AND_UPDATE + | "GT" -> ok I_GT + | "HASH_KEY" -> ok I_HASH_KEY + | "IF" -> ok I_IF + | "IF_CONS" -> ok I_IF_CONS + | "IF_LEFT" -> ok I_IF_LEFT + | "IF_NONE" -> ok I_IF_NONE + | "INT" -> ok I_INT + | "KECCAK" -> ok I_KECCAK + | "LAMBDA" -> ok I_LAMBDA + | "LE" -> ok I_LE + | "LEFT" -> ok I_LEFT + | "LEVEL" -> ok I_LEVEL + | "LOOP" -> ok I_LOOP + | "LSL" -> ok I_LSL + | "LSR" -> ok I_LSR + | "LT" -> ok I_LT + | "MAP" -> ok I_MAP + | "MEM" -> ok I_MEM + | "MUL" -> ok I_MUL + | "NEG" -> ok I_NEG + | "NEQ" -> ok I_NEQ + | "NIL" -> ok I_NIL + | "NONE" -> ok I_NONE + | "NOT" -> ok I_NOT + | "NOW" -> ok I_NOW + | "OR" -> ok I_OR + | "PAIR" -> ok I_PAIR + | "UNPAIR" -> ok I_UNPAIR + | "PAIRING_CHECK" -> ok I_PAIRING_CHECK + | "PUSH" -> ok I_PUSH + | "RIGHT" -> ok I_RIGHT + | "SHA3" -> ok I_SHA3 + | "SIZE" -> ok I_SIZE + | "SOME" -> ok I_SOME + | "SOURCE" -> ok I_SOURCE + | "SENDER" -> ok I_SENDER + | "SELF" -> ok I_SELF + | "SELF_ADDRESS" -> ok I_SELF_ADDRESS + | "SLICE" -> ok I_SLICE + | "STEPS_TO_QUOTA" -> ok I_STEPS_TO_QUOTA + | "SUB" -> ok I_SUB + | "SUB_MUTEZ" -> ok I_SUB_MUTEZ + | "SWAP" -> ok I_SWAP + | "TRANSFER_TOKENS" -> ok I_TRANSFER_TOKENS + | "SET_DELEGATE" -> ok I_SET_DELEGATE + | "UNIT" -> ok I_UNIT + | "UPDATE" -> ok I_UPDATE + | "XOR" -> ok I_XOR + | "ITER" -> ok I_ITER + | "LOOP_LEFT" -> ok I_LOOP_LEFT + | "ADDRESS" -> ok I_ADDRESS + | "CONTRACT" -> ok I_CONTRACT + | "ISNAT" -> ok I_ISNAT + | "CAST" -> ok I_CAST + | "RENAME" -> ok I_RENAME + | "SAPLING_EMPTY_STATE" -> ok I_SAPLING_EMPTY_STATE + | "SAPLING_VERIFY_UPDATE" -> ok I_SAPLING_VERIFY_UPDATE + | "DIG" -> ok I_DIG + | "DUG" -> ok I_DUG + | "NEVER" -> ok I_NEVER + | "VOTING_POWER" -> ok I_VOTING_POWER + | "TOTAL_VOTING_POWER" -> ok I_TOTAL_VOTING_POWER + | "TICKET" -> ok I_TICKET + | "READ_TICKET" -> ok I_READ_TICKET + | "SPLIT_TICKET" -> ok I_SPLIT_TICKET + | "JOIN_TICKETS" -> ok I_JOIN_TICKETS + | "OPEN_CHEST" -> ok I_OPEN_CHEST + | "bool" -> ok T_bool + | "contract" -> ok T_contract + | "int" -> ok T_int + | "key" -> ok T_key + | "key_hash" -> ok T_key_hash + | "lambda" -> ok T_lambda + | "list" -> ok T_list + | "map" -> ok T_map + | "big_map" -> ok T_big_map + | "nat" -> ok T_nat + | "option" -> ok T_option + | "or" -> ok T_or + | "pair" -> ok T_pair + | "set" -> ok T_set + | "signature" -> ok T_signature + | "string" -> ok T_string + | "bytes" -> ok T_bytes + | "mutez" -> ok T_mutez + | "timestamp" -> ok T_timestamp + | "unit" -> ok T_unit + | "operation" -> ok T_operation + | "address" -> ok T_address + | "sapling_state" -> ok T_sapling_state + | "sapling_transaction" -> ok T_sapling_transaction + | "chain_id" -> ok T_chain_id + | "never" -> ok T_never + | "bls12_381_g1" -> ok T_bls12_381_g1 + | "bls12_381_g2" -> ok T_bls12_381_g2 + | "bls12_381_fr" -> ok T_bls12_381_fr + | "ticket" -> ok T_ticket + | "chest_key" -> ok T_chest_key + | "chest" -> ok T_chest + | "constant" -> ok H_constant + | n -> + if valid_case n then error (Unknown_primitive_name n) + else error (Invalid_case n) + +let prims_of_strings expr = + let rec convert = function + | (Int _ | String _ | Bytes _) as expr -> ok expr + | Prim (loc, prim, args, annot) -> + Error_monad.record_trace + (Invalid_primitive_name (expr, loc)) + (prim_of_string prim) + >>? fun prim -> + List.map_e convert args >|? fun args -> Prim (loc, prim, args, annot) + | Seq (loc, args) -> List.map_e convert args >|? fun args -> Seq (loc, args) + in + convert (root expr) >|? fun expr -> strip_locations expr + [@@coq_axiom_with_reason + "implicit type conversion for expr in the constant cases"] + +let strings_of_prims expr = + let rec convert = function + | (Int _ | String _ | Bytes _) as expr -> expr + | Prim (loc, prim, args, annot) -> + let prim = string_of_prim prim in + let args = List.map convert args in + Prim (loc, prim, args, annot) + | Seq (loc, args) -> + let args = List.map convert args in + Seq (loc, args) + in + strip_locations (convert (root expr)) + [@@coq_axiom_with_reason + "implicit type conversion for expr in the constant cases"] + +let prim_encoding = + let open Data_encoding in + def "michelson.v1.primitives" + @@ string_enum + (* Add the comment below every 10 lines *) + [ + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("parameter", K_parameter); + ("storage", K_storage); + ("code", K_code); + ("False", D_False); + ("Elt", D_Elt); + ("Left", D_Left); + ("None", D_None); + ("Pair", D_Pair); + ("Right", D_Right); + ("Some", D_Some); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("True", D_True); + ("Unit", D_Unit); + ("PACK", I_PACK); + ("UNPACK", I_UNPACK); + ("BLAKE2B", I_BLAKE2B); + ("SHA256", I_SHA256); + ("SHA512", I_SHA512); + ("ABS", I_ABS); + ("ADD", I_ADD); + ("AMOUNT", I_AMOUNT); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("AND", I_AND); + ("BALANCE", I_BALANCE); + ("CAR", I_CAR); + ("CDR", I_CDR); + ("CHECK_SIGNATURE", I_CHECK_SIGNATURE); + ("COMPARE", I_COMPARE); + ("CONCAT", I_CONCAT); + ("CONS", I_CONS); + ("CREATE_ACCOUNT", I_CREATE_ACCOUNT); + ("CREATE_CONTRACT", I_CREATE_CONTRACT); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("IMPLICIT_ACCOUNT", I_IMPLICIT_ACCOUNT); + ("DIP", I_DIP); + ("DROP", I_DROP); + ("DUP", I_DUP); + ("EDIV", I_EDIV); + ("EMPTY_MAP", I_EMPTY_MAP); + ("EMPTY_SET", I_EMPTY_SET); + ("EQ", I_EQ); + ("EXEC", I_EXEC); + ("FAILWITH", I_FAILWITH); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("GE", I_GE); + ("GET", I_GET); + ("GT", I_GT); + ("HASH_KEY", I_HASH_KEY); + ("IF", I_IF); + ("IF_CONS", I_IF_CONS); + ("IF_LEFT", I_IF_LEFT); + ("IF_NONE", I_IF_NONE); + ("INT", I_INT); + ("LAMBDA", I_LAMBDA); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("LE", I_LE); + ("LEFT", I_LEFT); + ("LOOP", I_LOOP); + ("LSL", I_LSL); + ("LSR", I_LSR); + ("LT", I_LT); + ("MAP", I_MAP); + ("MEM", I_MEM); + ("MUL", I_MUL); + ("NEG", I_NEG); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("NEQ", I_NEQ); + ("NIL", I_NIL); + ("NONE", I_NONE); + ("NOT", I_NOT); + ("NOW", I_NOW); + ("OR", I_OR); + ("PAIR", I_PAIR); + ("PUSH", I_PUSH); + ("RIGHT", I_RIGHT); + ("SIZE", I_SIZE); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("SOME", I_SOME); + ("SOURCE", I_SOURCE); + ("SENDER", I_SENDER); + ("SELF", I_SELF); + ("STEPS_TO_QUOTA", I_STEPS_TO_QUOTA); + ("SUB", I_SUB); + ("SWAP", I_SWAP); + ("TRANSFER_TOKENS", I_TRANSFER_TOKENS); + ("SET_DELEGATE", I_SET_DELEGATE); + ("UNIT", I_UNIT); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("UPDATE", I_UPDATE); + ("XOR", I_XOR); + ("ITER", I_ITER); + ("LOOP_LEFT", I_LOOP_LEFT); + ("ADDRESS", I_ADDRESS); + ("CONTRACT", I_CONTRACT); + ("ISNAT", I_ISNAT); + ("CAST", I_CAST); + ("RENAME", I_RENAME); + ("bool", T_bool); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("contract", T_contract); + ("int", T_int); + ("key", T_key); + ("key_hash", T_key_hash); + ("lambda", T_lambda); + ("list", T_list); + ("map", T_map); + ("big_map", T_big_map); + ("nat", T_nat); + ("option", T_option); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("or", T_or); + ("pair", T_pair); + ("set", T_set); + ("signature", T_signature); + ("string", T_string); + ("bytes", T_bytes); + ("mutez", T_mutez); + ("timestamp", T_timestamp); + ("unit", T_unit); + ("operation", T_operation); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("address", T_address); + (* Alpha_002 addition *) + ("SLICE", I_SLICE); + (* Alpha_005 addition *) + ("DIG", I_DIG); + ("DUG", I_DUG); + ("EMPTY_BIG_MAP", I_EMPTY_BIG_MAP); + ("APPLY", I_APPLY); + ("chain_id", T_chain_id); + ("CHAIN_ID", I_CHAIN_ID); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + (* Alpha_008 addition *) + ("LEVEL", I_LEVEL); + ("SELF_ADDRESS", I_SELF_ADDRESS); + ("never", T_never); + ("NEVER", I_NEVER); + ("UNPAIR", I_UNPAIR); + ("VOTING_POWER", I_VOTING_POWER); + ("TOTAL_VOTING_POWER", I_TOTAL_VOTING_POWER); + ("KECCAK", I_KECCAK); + ("SHA3", I_SHA3); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + (* Alpha_008 addition *) + ("PAIRING_CHECK", I_PAIRING_CHECK); + ("bls12_381_g1", T_bls12_381_g1); + ("bls12_381_g2", T_bls12_381_g2); + ("bls12_381_fr", T_bls12_381_fr); + ("sapling_state", T_sapling_state); + ("sapling_transaction", T_sapling_transaction); + ("SAPLING_EMPTY_STATE", I_SAPLING_EMPTY_STATE); + ("SAPLING_VERIFY_UPDATE", I_SAPLING_VERIFY_UPDATE); + ("ticket", T_ticket); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + (* Alpha_008 addition *) + ("TICKET", I_TICKET); + ("READ_TICKET", I_READ_TICKET); + ("SPLIT_TICKET", I_SPLIT_TICKET); + ("JOIN_TICKETS", I_JOIN_TICKETS); + ("GET_AND_UPDATE", I_GET_AND_UPDATE); + (* Alpha_011 addition *) + ("chest", T_chest); + ("chest_key", T_chest_key); + ("OPEN_CHEST", I_OPEN_CHEST); + (* /!\ NEW INSTRUCTIONS MUST BE ADDED AT THE END OF THE STRING_ENUM, FOR BACKWARD COMPATIBILITY OF THE ENCODING. *) + ("VIEW", I_VIEW); + ("view", K_view); + ("constant", H_constant); + (* Alpha_012 addition *) + ("SUB_MUTEZ", I_SUB_MUTEZ); + (* New instructions must be added here, for backward compatibility of the encoding. *) + (* Keep the comment above at the end of the list *) + ] + +let () = + register_error_kind + `Permanent + ~id:"michelson_v1.unknown_primitive_name" + ~title:"Unknown primitive name" + ~description:"In a script or data expression, a primitive was unknown." + ~pp:(fun ppf n -> Format.fprintf ppf "Unknown primitive %s." n) + Data_encoding.(obj1 (req "wrong_primitive_name" string)) + (function Unknown_primitive_name got -> Some got | _ -> None) + (fun got -> Unknown_primitive_name got) ; + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_primitive_name_case" + ~title:"Invalid primitive name case" + ~description: + "In a script or data expression, a primitive name is neither uppercase, \ + lowercase or capitalized." + ~pp:(fun ppf n -> Format.fprintf ppf "Primitive %s has invalid case." n) + Data_encoding.(obj1 (req "wrong_primitive_name" string)) + (function Invalid_case name -> Some name | _ -> None) + (fun name -> Invalid_case name) ; + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_primitive_name" + ~title:"Invalid primitive name" + ~description: + "In a script or data expression, a primitive name is unknown or has a \ + wrong case." + ~pp:(fun ppf _ -> Format.fprintf ppf "Invalid primitive.") + Data_encoding.( + obj2 + (req + "expression" + (Micheline.canonical_encoding ~variant:"generic" string)) + (req "location" Micheline.canonical_location_encoding)) + (function + | Invalid_primitive_name (expr, loc) -> Some (expr, loc) | _ -> None) + (fun (expr, loc) -> Invalid_primitive_name (expr, loc)) + +let string_of_namespace = function + | Type_namespace -> "T" + | Constant_namespace -> "D" + | Instr_namespace -> "I" + | Keyword_namespace -> "K" + | Constant_hash_namespace -> "H" diff --git a/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_primitives.mli b/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_primitives.mli new file mode 100644 index 000000000000..3c2a65db73dd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/michelson_v1_primitives.mli @@ -0,0 +1,230 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += (* `Permanent *) Unknown_primitive_name of string + +type error += (* `Permanent *) Invalid_case of string + +type error += + | (* `Permanent *) + Invalid_primitive_name of + string Micheline.canonical * Micheline.canonical_location + +(** Types of nodes in Michelson's AST. They fall into 4 categories: + - types (prefixed with [T_]); + - constants (prefixed with [D_]); + - instructions (prefixed with [I_]); + - keywords (prefixed with [K_]). + + Recall that Micheline is essentially just S-expressions with + a few extra atom types for strings and numbers. This variant + represents the values the [Prim] atoms in the Michelson subset + of Micheline. Other types (such as ['a Micheline.canonical]) are + frequently parameterized by this type. This gives us a strongly-typed + subset of Micheline while keeping the set of primitives independent + from the definition of Micheline for easier changes. +*) +type prim = + | K_parameter + | K_storage + | K_code + | K_view + | D_False + | D_Elt + | D_Left + | D_None + | D_Pair + | D_Right + | D_Some + | D_True + | D_Unit + | I_PACK + | I_UNPACK + | I_BLAKE2B + | I_SHA256 + | I_SHA512 + | I_ABS + | I_ADD + | I_AMOUNT + | I_AND + | I_BALANCE + | I_CAR + | I_CDR + | I_CHAIN_ID + | I_CHECK_SIGNATURE + | I_COMPARE + | I_CONCAT + | I_CONS + | I_CREATE_ACCOUNT + | I_CREATE_CONTRACT + | I_IMPLICIT_ACCOUNT + | I_DIP + | I_DROP + | I_DUP + | I_VIEW + | I_EDIV + | I_EMPTY_BIG_MAP + | I_EMPTY_MAP + | I_EMPTY_SET + | I_EQ + | I_EXEC + | I_APPLY + | I_FAILWITH + | I_GE + | I_GET + | I_GET_AND_UPDATE + | I_GT + | I_HASH_KEY + | I_IF + | I_IF_CONS + | I_IF_LEFT + | I_IF_NONE + | I_INT + | I_LAMBDA + | I_LE + | I_LEFT + | I_LEVEL + | I_LOOP + | I_LSL + | I_LSR + | I_LT + | I_MAP + | I_MEM + | I_MUL + | I_NEG + | I_NEQ + | I_NIL + | I_NONE + | I_NOT + | I_NOW + | I_OR + | I_PAIR + | I_UNPAIR + | I_PUSH + | I_RIGHT + | I_SIZE + | I_SOME + | I_SOURCE + | I_SENDER + | I_SELF + | I_SELF_ADDRESS + | I_SLICE + | I_STEPS_TO_QUOTA + | I_SUB + | I_SUB_MUTEZ + | I_SWAP + | I_TRANSFER_TOKENS + | I_SET_DELEGATE + | I_UNIT + | I_UPDATE + | I_XOR + | I_ITER + | I_LOOP_LEFT + | I_ADDRESS + | I_CONTRACT + | I_ISNAT + | I_CAST + | I_RENAME + | I_SAPLING_EMPTY_STATE + | I_SAPLING_VERIFY_UPDATE + | I_DIG + | I_DUG + | I_NEVER + | I_VOTING_POWER + | I_TOTAL_VOTING_POWER + | I_KECCAK + | I_SHA3 + | I_PAIRING_CHECK + | I_TICKET + | I_READ_TICKET + | I_SPLIT_TICKET + | I_JOIN_TICKETS + | I_OPEN_CHEST + | T_bool + | T_contract + | T_int + | T_key + | T_key_hash + | T_lambda + | T_list + | T_map + | T_big_map + | T_nat + | T_option + | T_or + | T_pair + | T_set + | T_signature + | T_string + | T_bytes + | T_mutez + | T_timestamp + | T_unit + | T_operation + | T_address + | T_sapling_transaction + | T_sapling_state + | T_chain_id + | T_never + | T_bls12_381_g1 + | T_bls12_381_g2 + | T_bls12_381_fr + | T_ticket + | T_chest_key + | T_chest + (* See the interface of [Global_constants_storage]. *) + | H_constant + +(** Auxiliary types for error documentation. + All the prim constructor prefixes must match their namespace. *) + +type namespace = + | (* prefix "T" *) Type_namespace + | (* prefix "D" *) Constant_namespace + | (* prefix "I" *) Instr_namespace + | (* prefix "K" *) Keyword_namespace + (* The Constant Hash namespace is a singleton reserved + for the constant keyword. Unlike other primitives, + constants have no representation in the typed IR, + being fully expanded away before typechecking. *) + | (* prefix "H" *) Constant_hash_namespace + +val namespace : prim -> namespace + +val prim_encoding : prim Data_encoding.encoding + +val string_of_prim : prim -> string + +val prim_of_string : string -> prim tzresult + +val prims_of_strings : + string Micheline.canonical -> prim Micheline.canonical tzresult + +val strings_of_prims : prim Micheline.canonical -> string Micheline.canonical + +(** The string corresponds to the constructor prefix from the given namespace + (i.e. "T", "D", "I" or "K") *) +val string_of_namespace : namespace -> string diff --git a/src/proto_012_PsiThaCa/lib_protocol/migration_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/migration_repr.ml new file mode 100644 index 000000000000..5d4d513caff1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/migration_repr.ml @@ -0,0 +1,62 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Tocqueville Group, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type origination_result = { + balance_updates : Receipt_repr.balance_updates; + originated_contracts : Contract_repr.t list; + storage_size : Z.t; + paid_storage_size_diff : Z.t; +} + +let origination_result_list_encoding = + let open Data_encoding in + def "operation.alpha.origination_result" + @@ list + (conv + (fun { + balance_updates; + originated_contracts; + storage_size; + paid_storage_size_diff; + } -> + ( balance_updates, + originated_contracts, + storage_size, + paid_storage_size_diff )) + (fun ( balance_updates, + originated_contracts, + storage_size, + paid_storage_size_diff ) -> + { + balance_updates; + originated_contracts; + storage_size; + paid_storage_size_diff; + }) + (obj4 + (dft "balance_updates" Receipt_repr.balance_updates_encoding []) + (dft "originated_contracts" (list Contract_repr.encoding) []) + (dft "storage_size" z Z.zero) + (dft "paid_storage_size_diff" z Z.zero))) diff --git a/src/proto_012_PsiThaCa/lib_protocol/migration_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/migration_repr.mli new file mode 100644 index 000000000000..ea34cb1b7ee6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/migration_repr.mli @@ -0,0 +1,39 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Tocqueville Group, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Dupe of `Kind.origination successful_manager_operation_result` for use + inside Alpha_context. Converted in Apply_results. + + Doesn't consume gas and omits lazy_storage_diff field since it would + require copying Script_ir_translator functions to work on Raw_context. + *) +type origination_result = { + balance_updates : Receipt_repr.balance_updates; + originated_contracts : Contract_repr.t list; + storage_size : Z.t; + paid_storage_size_diff : Z.t; +} + +val origination_result_list_encoding : origination_result list Data_encoding.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/misc.ml b/src/proto_012_PsiThaCa/lib_protocol/misc.ml new file mode 100644 index 000000000000..bd350a5ef85b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/misc.ml @@ -0,0 +1,92 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Public_key_map = Map.Make (Signature.Public_key) + +type 'a lazyt = unit -> 'a + +type 'a lazy_list_t = LCons of 'a * 'a lazy_list_t tzresult Lwt.t lazyt + +type 'a lazy_list = 'a lazy_list_t tzresult Lwt.t + +let[@coq_struct "i"] rec ( --> ) i j = + (* [i; i+1; ...; j] *) + if Compare.Int.(i > j) then [] else i :: (succ i --> j) + +let[@coq_struct "j"] rec ( <-- ) i j = + (* [j; j-1; ...; i] *) + if Compare.Int.(i > j) then [] else j :: (i <-- pred j) + +let[@coq_struct "i"] rec ( ---> ) i j = + (* [i; i+1; ...; j] *) + if Compare.Int32.(i > j) then [] else i :: (Int32.succ i ---> j) + +let split delim ?(limit = max_int) path = + let l = String.length path in + let rec do_slashes acc limit i = + if Compare.Int.(i >= l) then List.rev acc + else if Compare.Char.(path.[i] = delim) then do_slashes acc limit (i + 1) + else do_split acc limit i + and do_split acc limit i = + if Compare.Int.(limit <= 0) then + if Compare.Int.(i = l) then List.rev acc + else List.rev (String.sub path i (l - i) :: acc) + else do_component acc (pred limit) i i + and do_component acc limit i j = + if Compare.Int.(j >= l) then + if Compare.Int.(i = j) then List.rev acc + else List.rev (String.sub path i (j - i) :: acc) + else if Compare.Char.(path.[j] = delim) then + do_slashes (String.sub path i (j - i) :: acc) limit j + else do_component acc limit i (j + 1) + in + if Compare.Int.(limit > 0) then do_slashes [] limit 0 else [path] + [@@coq_axiom_with_reason "non-top-level mutual recursion"] + +let pp_print_paragraph ppf description = + Format.fprintf + ppf + "@[%a@]" + Format.(pp_print_list ~pp_sep:pp_print_space pp_print_string) + (split ' ' description) + +let take n l = + let rec loop acc n xs = + if Compare.Int.(n <= 0) then Some (List.rev acc, xs) + else match xs with [] -> None | x :: xs -> loop (x :: acc) (n - 1) xs + in + loop [] n l + +let remove_prefix ~prefix s = + let x = String.length prefix in + let n = String.length s in + if Compare.Int.(n >= x) && Compare.String.(String.sub s 0 x = prefix) then + Some (String.sub s x (n - x)) + else None + +let rec remove_elem_from_list nb = function + | [] -> [] + | _ :: _ as l when Compare.Int.(nb <= 0) -> l + | _ :: tl -> remove_elem_from_list (nb - 1) tl diff --git a/src/proto_012_PsiThaCa/lib_protocol/misc.mli b/src/proto_012_PsiThaCa/lib_protocol/misc.mli new file mode 100644 index 000000000000..734ca29f9bcf --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/misc.mli @@ -0,0 +1,51 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** {2 Helper functions} *) + +module Public_key_map : Map.S with type key = Signature.Public_key.t + +type 'a lazyt = unit -> 'a + +type 'a lazy_list_t = LCons of 'a * 'a lazy_list_t tzresult Lwt.t lazyt + +type 'a lazy_list = 'a lazy_list_t tzresult Lwt.t + +(** Include bounds *) +val ( --> ) : int -> int -> int list + +val ( <-- ) : int -> int -> int list + +val ( ---> ) : Int32.t -> Int32.t -> Int32.t list + +val pp_print_paragraph : Format.formatter -> string -> unit + +val take : int -> 'a list -> ('a list * 'a list) option + +(** Some (input with [prefix] removed), if string has [prefix], else [None] *) +val remove_prefix : prefix:string -> string -> string option + +(** [remove nb list] remove the first [nb] elements from the list [list]. *) +val remove_elem_from_list : int -> 'a list -> 'a list diff --git a/src/proto_012_PsiThaCa/lib_protocol/non_empty_string.ml b/src/proto_012_PsiThaCa/lib_protocol/non_empty_string.ml new file mode 100644 index 000000000000..9ce9b11d27e8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/non_empty_string.ml @@ -0,0 +1,42 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Compare.String + +let of_string = function "" -> None | s -> Some s + +let of_string_exn = function + | "" -> invalid_arg "Unexpected empty string" + | s -> s + +let cat2 a ?(sep = "") b = String.concat sep [a; b] + +let split_on_last sep s = + match String.rindex_opt s sep with + | Some i when Compare.Int.(i > 0 && i < String.length s - 1) -> + let s1 = String.sub s 0 i in + let s2 = String.sub s (i + 1) (String.length s - 1 - i) in + Some (s1, s2) + | _ -> None diff --git a/src/proto_012_PsiThaCa/lib_protocol/non_empty_string.mli b/src/proto_012_PsiThaCa/lib_protocol/non_empty_string.mli new file mode 100644 index 000000000000..a9973efd775f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/non_empty_string.mli @@ -0,0 +1,45 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** A string that is guaranteed to be non-empty *) +type t = private string + +include Compare.S with type t := t + +(** Returns [None] if the original string is empty. *) +val of_string : string -> t option + +(** Fails with [Invalid_argument] if the original string is empty. *) +val of_string_exn : string -> t + +(** [cat2 a b] concatenates [a] and [b]. + [cat2 a ~sep b] concatenates [a], [sep], and [b]. *) +val cat2 : t -> ?sep:string -> t -> t + +(** [split_on_last c s] finds the last occurrence of [c] in [s] and returns + the substring before and the substring after. + Returns [None] if [c] is not present in [s] or if one or both substrings + would end up being empty. *) +val split_on_last : char -> t -> (t * t) option diff --git a/src/proto_012_PsiThaCa/lib_protocol/nonce_hash.ml b/src/proto_012_PsiThaCa/lib_protocol/nonce_hash.ml new file mode 100644 index 000000000000..10a3f7efe42b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/nonce_hash.ml @@ -0,0 +1,45 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* 32 *) +let nonce_hash = "\069\220\169" (* nce(53) *) + +module H = + Blake2B.Make + (Base58) + (struct + let name = "cycle_nonce" + + let title = "A nonce hash" + + let b58check_prefix = nonce_hash + + let size = None + end) + +include H +include Path_encoding.Make_hex (H) + +let () = Base58.check_encoded_prefix b58check_encoding "nce" 53 diff --git a/src/proto_012_PsiThaCa/lib_protocol/nonce_hash.mli b/src/proto_012_PsiThaCa/lib_protocol/nonce_hash.mli new file mode 100644 index 000000000000..aeeef12905bd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/nonce_hash.mli @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** A specialized Blake2B implementation for hashing nonces. *) + +include S.HASH + +include Path_encoding.S with type t := t diff --git a/src/proto_012_PsiThaCa/lib_protocol/nonce_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/nonce_storage.ml new file mode 100644 index 000000000000..60e8d8f0dff6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/nonce_storage.ml @@ -0,0 +1,132 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = Seed_repr.nonce + +type nonce = t + +let encoding = Seed_repr.nonce_encoding + +type error += + | Too_late_revelation + | Too_early_revelation + | Previously_revealed_nonce + | Inconsistent_nonce + +let () = + register_error_kind + `Branch + ~id:"nonce.too_late_revelation" + ~title:"Too late nonce revelation" + ~description:"Nonce revelation happens too late" + ~pp:(fun ppf () -> + Format.fprintf ppf "This nonce cannot be revealed anymore.") + Data_encoding.unit + (function Too_late_revelation -> Some () | _ -> None) + (fun () -> Too_late_revelation) ; + register_error_kind + `Temporary + ~id:"nonce.too_early_revelation" + ~title:"Too early nonce revelation" + ~description:"Nonce revelation happens before cycle end" + ~pp:(fun ppf () -> + Format.fprintf ppf "This nonce should not yet be revealed") + Data_encoding.unit + (function Too_early_revelation -> Some () | _ -> None) + (fun () -> Too_early_revelation) ; + register_error_kind + `Branch + ~id:"nonce.previously_revealed" + ~title:"Previously revealed nonce" + ~description:"Duplicated revelation for a nonce." + ~pp:(fun ppf () -> Format.fprintf ppf "This nonce was previously revealed") + Data_encoding.unit + (function Previously_revealed_nonce -> Some () | _ -> None) + (fun () -> Previously_revealed_nonce) ; + register_error_kind + `Branch + ~id:"nonce.inconsistent" + ~title:"Inconsistent nonce" + ~description: + "The provided nonce is inconsistent with the committed nonce hash." + ~pp:(fun ppf () -> + Format.fprintf + ppf + "This nonce revelation is invalid (inconsistent with the committed \ + hash)") + Data_encoding.unit + (function Inconsistent_nonce -> Some () | _ -> None) + (fun () -> Inconsistent_nonce) + +(* checks that the level of a revelation is not too early or too late wrt to the + current context and that a nonce has not been already revealed for that level *) +let get_unrevealed ctxt (level : Level_repr.t) = + let cur_level = Level_storage.current ctxt in + match Cycle_repr.pred cur_level.cycle with + | None -> fail Too_early_revelation (* no revelations during cycle 0 *) + | Some revealed_cycle -> ( + if Cycle_repr.(revealed_cycle < level.Level_repr.cycle) then + fail Too_early_revelation + else if Cycle_repr.(level.Level_repr.cycle < revealed_cycle) then + fail Too_late_revelation + else + Storage.Seed.Nonce.get ctxt level >>=? function + | Revealed _ -> fail Previously_revealed_nonce + | Unrevealed status -> return status) + +let record_hash ctxt unrevealed = + let level = Level_storage.current ctxt in + Storage.Seed.Nonce.init ctxt level (Unrevealed unrevealed) + +let reveal ctxt level nonce = + get_unrevealed ctxt level >>=? fun unrevealed -> + error_unless + (Seed_repr.check_hash nonce unrevealed.nonce_hash) + Inconsistent_nonce + >>?= fun () -> Storage.Seed.Nonce.update ctxt level (Revealed nonce) + +type unrevealed = Storage.Seed.unrevealed_nonce = { + nonce_hash : Nonce_hash.t; + delegate : Signature.Public_key_hash.t; +} + +type status = Storage.Seed.nonce_status = + | Unrevealed of unrevealed + | Revealed of Seed_repr.nonce + +let get = Storage.Seed.Nonce.get + +type nonce_presence = No_nonce_expected | Nonce_expected of status + +let check ctxt level = + Storage.Seed.Nonce.find ctxt level >>=? function + | None -> return No_nonce_expected + | Some status -> return (Nonce_expected status) + +let of_bytes = Seed_repr.make_nonce + +let hash = Seed_repr.hash + +let check_hash = Seed_repr.check_hash diff --git a/src/proto_012_PsiThaCa/lib_protocol/nonce_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/nonce_storage.mli new file mode 100644 index 000000000000..16147031052e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/nonce_storage.mli @@ -0,0 +1,60 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | Too_late_revelation + | Too_early_revelation + | Previously_revealed_nonce + | Inconsistent_nonce + +type t = Seed_repr.nonce + +type nonce = t + +val encoding : nonce Data_encoding.t + +type unrevealed = Storage.Seed.unrevealed_nonce = { + nonce_hash : Nonce_hash.t; + delegate : Signature.Public_key_hash.t; +} + +type status = Unrevealed of unrevealed | Revealed of Seed_repr.nonce + +val get : Raw_context.t -> Level_repr.t -> status tzresult Lwt.t + +type nonce_presence = No_nonce_expected | Nonce_expected of status + +val check : Raw_context.t -> Level_repr.t -> nonce_presence tzresult Lwt.t + +val record_hash : Raw_context.t -> unrevealed -> Raw_context.t tzresult Lwt.t + +val reveal : + Raw_context.t -> Level_repr.t -> nonce -> Raw_context.t tzresult Lwt.t + +val of_bytes : bytes -> nonce tzresult + +val hash : nonce -> Nonce_hash.t + +val check_hash : nonce -> Nonce_hash.t -> bool diff --git a/src/proto_012_PsiThaCa/lib_protocol/operation_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/operation_repr.ml new file mode 100644 index 000000000000..5db0a3162834 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/operation_repr.ml @@ -0,0 +1,1149 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Tezos Protocol Implementation - Low level Repr. of Operations *) + +module Kind = struct + type preendorsement_consensus_kind = Preendorsement_consensus_kind + + type endorsement_consensus_kind = Endorsement_consensus_kind + + type 'a consensus = + | Preendorsement_kind : preendorsement_consensus_kind consensus + | Endorsement_kind : endorsement_consensus_kind consensus + + type preendorsement = preendorsement_consensus_kind consensus + + type endorsement = endorsement_consensus_kind consensus + + type seed_nonce_revelation = Seed_nonce_revelation_kind + + type 'a double_consensus_operation_evidence = + | Double_consensus_operation_evidence + + type double_endorsement_evidence = + endorsement_consensus_kind double_consensus_operation_evidence + + type double_preendorsement_evidence = + preendorsement_consensus_kind double_consensus_operation_evidence + + type double_baking_evidence = Double_baking_evidence_kind + + type activate_account = Activate_account_kind + + type proposals = Proposals_kind + + type ballot = Ballot_kind + + type reveal = Reveal_kind + + type transaction = Transaction_kind + + type origination = Origination_kind + + type delegation = Delegation_kind + + type set_deposits_limit = Set_deposits_limit_kind + + type failing_noop = Failing_noop_kind + + type register_global_constant = Register_global_constant_kind + + type 'a manager = + | Reveal_manager_kind : reveal manager + | Transaction_manager_kind : transaction manager + | Origination_manager_kind : origination manager + | Delegation_manager_kind : delegation manager + | Register_global_constant_manager_kind : register_global_constant manager + | Set_deposits_limit_manager_kind : set_deposits_limit manager +end + +type 'a consensus_operation_type = + | Endorsement : Kind.endorsement consensus_operation_type + | Preendorsement : Kind.preendorsement consensus_operation_type + +let pp_operation_kind (type kind) ppf + (operation_kind : kind consensus_operation_type) = + match operation_kind with + | Endorsement -> Format.fprintf ppf "Endorsement" + | Preendorsement -> Format.fprintf ppf "Preendorsement" + +type consensus_content = { + slot : Slot_repr.t; + level : Raw_level_repr.t; + (* The level is not required to validate an endorsement when it corresponds + to the current payload, but if we want to filter endorsements, we need + the level. *) + round : Round_repr.t; + block_payload_hash : Block_payload_hash.t; + (* NOTE: This could be just the hash of the set of operations (the + actual payload). The grandfather block hash should already be + fixed by the operation.shell.branch field. This is not really + important but could make things easier for debugging *) +} + +let consensus_content_encoding = + let open Data_encoding in + conv + (fun {slot; level; round; block_payload_hash} -> + (slot, level, round, block_payload_hash)) + (fun (slot, level, round, block_payload_hash) -> + {slot; level; round; block_payload_hash}) + (obj4 + (req "slot" Slot_repr.encoding) + (req "level" Raw_level_repr.encoding) + (req "round" Round_repr.encoding) + (req "block_payload_hash" Block_payload_hash.encoding)) + +let pp_consensus_content ppf content = + Format.fprintf + ppf + "(%ld, %a, %a, %a)" + (Raw_level_repr.to_int32 content.level) + Round_repr.pp + content.round + Slot_repr.pp + content.slot + Block_payload_hash.pp_short + content.block_payload_hash + +type consensus_watermark = + | Endorsement of Chain_id.t + | Preendorsement of Chain_id.t + +let bytes_of_consensus_watermark = function + | Preendorsement chain_id -> + Bytes.cat (Bytes.of_string "\x12") (Chain_id.to_bytes chain_id) + | Endorsement chain_id -> + Bytes.cat (Bytes.of_string "\x13") (Chain_id.to_bytes chain_id) + +let to_watermark w = Signature.Custom (bytes_of_consensus_watermark w) + +let of_watermark = function + | Signature.Custom b -> + if Compare.Int.(Bytes.length b > 0) then + match Bytes.get b 0 with + | '\x12' -> + Option.map + (fun chain_id -> Endorsement chain_id) + (Chain_id.of_bytes_opt (Bytes.sub b 1 (Bytes.length b - 1))) + | '\x13' -> + Option.map + (fun chain_id -> Preendorsement chain_id) + (Chain_id.of_bytes_opt (Bytes.sub b 1 (Bytes.length b - 1))) + | _ -> None + else None + | _ -> None + +type raw = Operation.t = {shell : Operation.shell_header; proto : bytes} + +let raw_encoding = Operation.encoding + +type 'kind operation = { + shell : Operation.shell_header; + protocol_data : 'kind protocol_data; +} + +and 'kind protocol_data = { + contents : 'kind contents_list; + signature : Signature.t option; +} + +and _ contents_list = + | Single : 'kind contents -> 'kind contents_list + | Cons : + 'kind Kind.manager contents * 'rest Kind.manager contents_list + -> ('kind * 'rest) Kind.manager contents_list + +and _ contents = + | Preendorsement : consensus_content -> Kind.preendorsement contents + | Endorsement : consensus_content -> Kind.endorsement contents + | Seed_nonce_revelation : { + level : Raw_level_repr.t; + nonce : Seed_repr.nonce; + } + -> Kind.seed_nonce_revelation contents + | Double_preendorsement_evidence : { + op1 : Kind.preendorsement operation; + op2 : Kind.preendorsement operation; + } + -> Kind.double_preendorsement_evidence contents + | Double_endorsement_evidence : { + op1 : Kind.endorsement operation; + op2 : Kind.endorsement operation; + } + -> Kind.double_endorsement_evidence contents + | Double_baking_evidence : { + bh1 : Block_header_repr.t; + bh2 : Block_header_repr.t; + } + -> Kind.double_baking_evidence contents + | Activate_account : { + id : Ed25519.Public_key_hash.t; + activation_code : Blinded_public_key_hash.activation_code; + } + -> Kind.activate_account contents + | Proposals : { + source : Signature.Public_key_hash.t; + period : int32; + proposals : Protocol_hash.t list; + } + -> Kind.proposals contents + | Ballot : { + source : Signature.Public_key_hash.t; + period : int32; + proposal : Protocol_hash.t; + ballot : Vote_repr.ballot; + } + -> Kind.ballot contents + | Failing_noop : string -> Kind.failing_noop contents + | Manager_operation : { + source : Signature.public_key_hash; + fee : Tez_repr.tez; + counter : counter; + operation : 'kind manager_operation; + gas_limit : Gas_limit_repr.Arith.integral; + storage_limit : Z.t; + } + -> 'kind Kind.manager contents + +and _ manager_operation = + | Reveal : Signature.Public_key.t -> Kind.reveal manager_operation + | Transaction : { + amount : Tez_repr.tez; + parameters : Script_repr.lazy_expr; + entrypoint : string; + destination : Contract_repr.contract; + } + -> Kind.transaction manager_operation + | Origination : { + delegate : Signature.Public_key_hash.t option; + script : Script_repr.t; + credit : Tez_repr.tez; + preorigination : Contract_repr.t option; + } + -> Kind.origination manager_operation + | Delegation : + Signature.Public_key_hash.t option + -> Kind.delegation manager_operation + | Register_global_constant : { + value : Script_repr.lazy_expr; + } + -> Kind.register_global_constant manager_operation + | Set_deposits_limit : + Tez_repr.t option + -> Kind.set_deposits_limit manager_operation + +and counter = Z.t + +let manager_kind : type kind. kind manager_operation -> kind Kind.manager = + function + | Reveal _ -> Kind.Reveal_manager_kind + | Transaction _ -> Kind.Transaction_manager_kind + | Origination _ -> Kind.Origination_manager_kind + | Delegation _ -> Kind.Delegation_manager_kind + | Register_global_constant _ -> Kind.Register_global_constant_manager_kind + | Set_deposits_limit _ -> Kind.Set_deposits_limit_manager_kind + +type 'kind internal_operation = { + source : Contract_repr.contract; + operation : 'kind manager_operation; + nonce : int; +} + +type packed_manager_operation = + | Manager : 'kind manager_operation -> packed_manager_operation + +type packed_contents = Contents : 'kind contents -> packed_contents + +type packed_contents_list = + | Contents_list : 'kind contents_list -> packed_contents_list + +type packed_protocol_data = + | Operation_data : 'kind protocol_data -> packed_protocol_data + +type packed_operation = { + shell : Operation.shell_header; + protocol_data : packed_protocol_data; +} + +let pack ({shell; protocol_data} : _ operation) : packed_operation = + {shell; protocol_data = Operation_data protocol_data} + +type packed_internal_operation = + | Internal_operation : 'kind internal_operation -> packed_internal_operation + +let rec to_list = function + | Contents_list (Single o) -> [Contents o] + | Contents_list (Cons (o, os)) -> Contents o :: to_list (Contents_list os) + +(* This first version of of_list has the type (_, string) result expected by + the conv_with_guard combinator of Data_encoding. For a more conventional + return type see [of_list] below. *) +let rec of_list_internal = function + | [] -> Error "Operation lists should not be empty." + | [Contents o] -> Ok (Contents_list (Single o)) + | Contents o :: os -> ( + of_list_internal os >>? fun (Contents_list os) -> + match (o, os) with + | (Manager_operation _, Single (Manager_operation _)) -> + Ok (Contents_list (Cons (o, os))) + | (Manager_operation _, Cons _) -> Ok (Contents_list (Cons (o, os))) + | _ -> + Error + "Operation list of length > 1 should only contains manager \ + operations.") + +type error += Contents_list_error of string (* `Permanent *) + +let of_list l = + match of_list_internal l with + | Ok contents -> Ok contents + | Error s -> error @@ Contents_list_error s + +module Encoding = struct + open Data_encoding + + let case tag name args proj inj = + case + tag + ~title:(String.capitalize_ascii name) + (merge_objs (obj1 (req "kind" (constant name))) args) + (fun x -> match proj x with None -> None | Some x -> Some ((), x)) + (fun ((), x) -> inj x) + + module Manager_operations = struct + type 'kind case = + | MCase : { + tag : int; + name : string; + encoding : 'a Data_encoding.t; + select : packed_manager_operation -> 'kind manager_operation option; + proj : 'kind manager_operation -> 'a; + inj : 'a -> 'kind manager_operation; + } + -> 'kind case + [@@coq_force_gadt] + + let[@coq_axiom_with_reason "gadt"] reveal_case = + MCase + { + tag = 0; + name = "reveal"; + encoding = obj1 (req "public_key" Signature.Public_key.encoding); + select = (function Manager (Reveal _ as op) -> Some op | _ -> None); + proj = (function Reveal pkh -> pkh); + inj = (fun pkh -> Reveal pkh); + } + + let entrypoint_encoding = + def + ~title:"entrypoint" + ~description:"Named entrypoint to a Michelson smart contract" + "entrypoint" + @@ + let builtin_case tag name = + Data_encoding.case + (Tag tag) + ~title:name + (constant name) + (fun n -> if Compare.String.(n = name) then Some () else None) + (fun () -> name) + in + union + [ + builtin_case 0 "default"; + builtin_case 1 "root"; + builtin_case 2 "do"; + builtin_case 3 "set_delegate"; + builtin_case 4 "remove_delegate"; + Data_encoding.case + (Tag 255) + ~title:"named" + (Bounded.string 31) + (fun s -> Some s) + (fun s -> s); + ] + + let[@coq_axiom_with_reason "gadt"] transaction_case = + MCase + { + tag = 1; + name = "transaction"; + encoding = + obj3 + (req "amount" Tez_repr.encoding) + (req "destination" Contract_repr.encoding) + (opt + "parameters" + (obj2 + (req "entrypoint" entrypoint_encoding) + (req "value" Script_repr.lazy_expr_encoding))); + select = + (function Manager (Transaction _ as op) -> Some op | _ -> None); + proj = + (function + | Transaction {amount; destination; parameters; entrypoint} -> + let parameters = + if + Script_repr.is_unit_parameter parameters + && Compare.String.(entrypoint = "default") + then None + else Some (entrypoint, parameters) + in + (amount, destination, parameters)); + inj = + (fun (amount, destination, parameters) -> + let (entrypoint, parameters) = + match parameters with + | None -> ("default", Script_repr.unit_parameter) + | Some (entrypoint, value) -> (entrypoint, value) + in + Transaction {amount; destination; parameters; entrypoint}); + } + + let[@coq_axiom_with_reason "gadt"] origination_case = + MCase + { + tag = 2; + name = "origination"; + encoding = + obj3 + (req "balance" Tez_repr.encoding) + (opt "delegate" Signature.Public_key_hash.encoding) + (req "script" Script_repr.encoding); + select = + (function Manager (Origination _ as op) -> Some op | _ -> None); + proj = + (function + | Origination + { + credit; + delegate; + script; + preorigination = + _ + (* the hash is only used internally + when originating from smart + contracts, don't serialize it *); + } -> + (credit, delegate, script)); + inj = + (fun (credit, delegate, script) -> + Origination {credit; delegate; script; preorigination = None}); + } + + let[@coq_axiom_with_reason "gadt"] delegation_case = + MCase + { + tag = 3; + name = "delegation"; + encoding = obj1 (opt "delegate" Signature.Public_key_hash.encoding); + select = + (function Manager (Delegation _ as op) -> Some op | _ -> None); + proj = (function Delegation key -> key); + inj = (fun key -> Delegation key); + } + + let[@coq_axiom_with_reason "gadt"] register_global_constant_case = + MCase + { + tag = 4; + name = "register_global_constant"; + encoding = obj1 (req "value" Script_repr.lazy_expr_encoding); + select = + (function + | Manager (Register_global_constant _ as op) -> Some op | _ -> None); + proj = (function Register_global_constant {value} -> value); + inj = (fun value -> Register_global_constant {value}); + } + + let[@coq_axiom_with_reason "gadt"] set_deposits_limit_case = + MCase + { + tag = 5; + name = "set_deposits_limit"; + encoding = obj1 (opt "limit" Tez_repr.encoding); + select = + (function + | Manager (Set_deposits_limit _ as op) -> Some op | _ -> None); + proj = (function Set_deposits_limit key -> key); + inj = (fun key -> Set_deposits_limit key); + } + + let encoding = + let make (MCase {tag; name; encoding; select; proj; inj}) = + case + (Tag tag) + name + encoding + (fun o -> + match select o with None -> None | Some o -> Some (proj o)) + (fun x -> Manager (inj x)) + in + union + ~tag_size:`Uint8 + [ + make reveal_case; + make transaction_case; + make origination_case; + make delegation_case; + make register_global_constant_case; + make set_deposits_limit_case; + ] + end + + type 'b case = + | Case : { + tag : int; + name : string; + encoding : 'a Data_encoding.t; + select : packed_contents -> 'b contents option; + proj : 'b contents -> 'a; + inj : 'a -> 'b contents; + } + -> 'b case + + let preendorsement_case = + Case + { + tag = 20; + (* Preendorsement where added after *) + name = "preendorsement"; + encoding = consensus_content_encoding; + select = + (function Contents (Preendorsement _ as op) -> Some op | _ -> None); + proj = (fun (Preendorsement preendorsement) -> preendorsement); + inj = (fun preendorsement -> Preendorsement preendorsement); + } + + (* Defined before endorsement encoding because this is used there *) + let preendorsement_encoding = + let make (Case {tag; name; encoding; select = _; proj; inj}) = + case (Tag tag) name encoding (fun o -> Some (proj o)) (fun x -> inj x) + in + let to_list : Kind.preendorsement contents_list -> _ = function + | Single o -> o + in + let of_list : Kind.preendorsement contents -> _ = function + | o -> Single o + in + def "inlined.preendorsement" + @@ conv + (fun ({shell; protocol_data = {contents; signature}} : _ operation) -> + (shell, (contents, signature))) + (fun (shell, (contents, signature)) : _ operation -> + {shell; protocol_data = {contents; signature}}) + (merge_objs + Operation.shell_header_encoding + (obj2 + (req + "operations" + (conv to_list of_list + @@ def "inlined.preendorsement.contents" + @@ union [make preendorsement_case])) + (varopt "signature" Signature.encoding))) + + let endorsement_encoding = + obj4 + (req "slot" Slot_repr.encoding) + (req "level" Raw_level_repr.encoding) + (req "round" Round_repr.encoding) + (req "block_payload_hash" Block_payload_hash.encoding) + + let endorsement_case = + Case + { + tag = 21; + name = "endorsement"; + encoding = endorsement_encoding; + select = + (function Contents (Endorsement _ as op) -> Some op | _ -> None); + proj = + (fun [@coq_match_with_default] (Endorsement consensus_content) -> + ( consensus_content.slot, + consensus_content.level, + consensus_content.round, + consensus_content.block_payload_hash )); + inj = + (fun (slot, level, round, block_payload_hash) -> + Endorsement {slot; level; round; block_payload_hash}); + } + + let[@coq_axiom_with_reason "gadt"] endorsement_encoding = + let make (Case {tag; name; encoding; select = _; proj; inj}) = + case (Tag tag) name encoding (fun o -> Some (proj o)) (fun x -> inj x) + in + let to_list : Kind.endorsement contents_list -> _ = fun (Single o) -> o in + let of_list : Kind.endorsement contents -> _ = fun o -> Single o in + def "inlined.endorsement" + @@ conv + (fun ({shell; protocol_data = {contents; signature}} : _ operation) -> + (shell, (contents, signature))) + (fun (shell, (contents, signature)) : _ operation -> + {shell; protocol_data = {contents; signature}}) + (merge_objs + Operation.shell_header_encoding + (obj2 + (req + "operations" + (conv to_list of_list + @@ def "inlined.endorsement_mempool.contents" + @@ union [make endorsement_case])) + (varopt "signature" Signature.encoding))) + + let[@coq_axiom_with_reason "gadt"] seed_nonce_revelation_case = + Case + { + tag = 1; + name = "seed_nonce_revelation"; + encoding = + obj2 + (req "level" Raw_level_repr.encoding) + (req "nonce" Seed_repr.nonce_encoding); + select = + (function + | Contents (Seed_nonce_revelation _ as op) -> Some op | _ -> None); + proj = (fun (Seed_nonce_revelation {level; nonce}) -> (level, nonce)); + inj = (fun (level, nonce) -> Seed_nonce_revelation {level; nonce}); + } + + let[@coq_axiom_with_reason "gadt"] double_preendorsement_evidence_case : + Kind.double_preendorsement_evidence case = + Case + { + tag = 7; + name = "double_preendorsement_evidence"; + encoding = + obj2 + (req "op1" (dynamic_size preendorsement_encoding)) + (req "op2" (dynamic_size preendorsement_encoding)); + select = + (function + | Contents (Double_preendorsement_evidence _ as op) -> Some op + | _ -> None); + proj = (fun (Double_preendorsement_evidence {op1; op2}) -> (op1, op2)); + inj = (fun (op1, op2) -> Double_preendorsement_evidence {op1; op2}); + } + + let[@coq_axiom_with_reason "gadt"] double_endorsement_evidence_case : + Kind.double_endorsement_evidence case = + Case + { + tag = 2; + name = "double_endorsement_evidence"; + encoding = + obj2 + (req "op1" (dynamic_size endorsement_encoding)) + (req "op2" (dynamic_size endorsement_encoding)); + select = + (function + | Contents (Double_endorsement_evidence _ as op) -> Some op + | _ -> None); + proj = (fun (Double_endorsement_evidence {op1; op2}) -> (op1, op2)); + inj = (fun (op1, op2) -> Double_endorsement_evidence {op1; op2}); + } + + let[@coq_axiom_with_reason "gadt"] double_baking_evidence_case = + Case + { + tag = 3; + name = "double_baking_evidence"; + encoding = + obj2 + (req "bh1" (dynamic_size Block_header_repr.encoding)) + (req "bh2" (dynamic_size Block_header_repr.encoding)); + select = + (function + | Contents (Double_baking_evidence _ as op) -> Some op | _ -> None); + proj = (fun (Double_baking_evidence {bh1; bh2}) -> (bh1, bh2)); + inj = (fun (bh1, bh2) -> Double_baking_evidence {bh1; bh2}); + } + + let[@coq_axiom_with_reason "gadt"] activate_account_case = + Case + { + tag = 4; + name = "activate_account"; + encoding = + obj2 + (req "pkh" Ed25519.Public_key_hash.encoding) + (req "secret" Blinded_public_key_hash.activation_code_encoding); + select = + (function + | Contents (Activate_account _ as op) -> Some op | _ -> None); + proj = + (fun (Activate_account {id; activation_code}) -> + (id, activation_code)); + inj = + (fun (id, activation_code) -> Activate_account {id; activation_code}); + } + + let[@coq_axiom_with_reason "gadt"] proposals_case = + Case + { + tag = 5; + name = "proposals"; + encoding = + obj3 + (req "source" Signature.Public_key_hash.encoding) + (req "period" int32) + (req "proposals" (list Protocol_hash.encoding)); + select = + (function Contents (Proposals _ as op) -> Some op | _ -> None); + proj = + (fun (Proposals {source; period; proposals}) -> + (source, period, proposals)); + inj = + (fun (source, period, proposals) -> + Proposals {source; period; proposals}); + } + + let[@coq_axiom_with_reason "gadt"] ballot_case = + Case + { + tag = 6; + name = "ballot"; + encoding = + obj4 + (req "source" Signature.Public_key_hash.encoding) + (req "period" int32) + (req "proposal" Protocol_hash.encoding) + (req "ballot" Vote_repr.ballot_encoding); + select = (function Contents (Ballot _ as op) -> Some op | _ -> None); + proj = + (function + | Ballot {source; period; proposal; ballot} -> + (source, period, proposal, ballot)); + inj = + (fun (source, period, proposal, ballot) -> + Ballot {source; period; proposal; ballot}); + } + + let failing_noop_case = + Case + { + tag = 17; + name = "failing_noop"; + encoding = obj1 (req "arbitrary" Data_encoding.string); + select = + (function Contents (Failing_noop _ as op) -> Some op | _ -> None); + proj = + (function[@coq_match_with_default] Failing_noop message -> message); + inj = (function message -> Failing_noop message); + } + + let manager_encoding = + obj5 + (req "source" Signature.Public_key_hash.encoding) + (req "fee" Tez_repr.encoding) + (req "counter" (check_size 10 n)) + (req "gas_limit" (check_size 10 Gas_limit_repr.Arith.n_integral_encoding)) + (req "storage_limit" (check_size 10 n)) + + let extract : type kind. kind Kind.manager contents -> _ = + function[@coq_match_with_default] + | Manager_operation + {source; fee; counter; gas_limit; storage_limit; operation = _} -> + (source, fee, counter, gas_limit, storage_limit) + + let rebuild (source, fee, counter, gas_limit, storage_limit) operation = + Manager_operation + {source; fee; counter; gas_limit; storage_limit; operation} + + let[@coq_axiom_with_reason "gadt"] make_manager_case tag (type kind) + (Manager_operations.MCase mcase : kind Manager_operations.case) = + Case + { + tag; + name = mcase.name; + encoding = merge_objs manager_encoding mcase.encoding; + select = + (function + | Contents (Manager_operation ({operation; _} as op)) -> ( + match mcase.select (Manager operation) with + | None -> None + | Some operation -> Some (Manager_operation {op with operation})) + | _ -> None); + proj = + (function + | Manager_operation {operation; _} as op -> + (extract op, mcase.proj operation)); + inj = (fun (op, contents) -> rebuild op (mcase.inj contents)); + } + + let reveal_case = make_manager_case 107 Manager_operations.reveal_case + + let transaction_case = + make_manager_case 108 Manager_operations.transaction_case + + let origination_case = + make_manager_case 109 Manager_operations.origination_case + + let delegation_case = make_manager_case 110 Manager_operations.delegation_case + + let register_global_constant_case = + make_manager_case 111 Manager_operations.register_global_constant_case + + let set_deposits_limit_case = + make_manager_case 112 Manager_operations.set_deposits_limit_case + + let contents_encoding = + let make (Case {tag; name; encoding; select; proj; inj}) = + case + (Tag tag) + name + encoding + (fun o -> match select o with None -> None | Some o -> Some (proj o)) + (fun x -> Contents (inj x)) + in + def "operation.alpha.contents" + @@ union + [ + make endorsement_case; + make preendorsement_case; + make seed_nonce_revelation_case; + make double_endorsement_evidence_case; + make double_preendorsement_evidence_case; + make double_baking_evidence_case; + make activate_account_case; + make proposals_case; + make ballot_case; + make reveal_case; + make transaction_case; + make origination_case; + make delegation_case; + make set_deposits_limit_case; + make failing_noop_case; + make register_global_constant_case; + ] + + let contents_list_encoding = + conv_with_guard to_list of_list_internal (Variable.list contents_encoding) + + let optional_signature_encoding = + conv + (function Some s -> s | None -> Signature.zero) + (fun s -> if Signature.equal s Signature.zero then None else Some s) + Signature.encoding + + let protocol_data_encoding = + def "operation.alpha.contents_and_signature" + @@ conv + (fun (Operation_data {contents; signature}) -> + (Contents_list contents, signature)) + (fun (Contents_list contents, signature) -> + Operation_data {contents; signature}) + (obj2 + (req "contents" contents_list_encoding) + (req "signature" optional_signature_encoding)) + + let operation_encoding = + conv + (fun {shell; protocol_data} -> (shell, protocol_data)) + (fun (shell, protocol_data) -> {shell; protocol_data}) + (merge_objs Operation.shell_header_encoding protocol_data_encoding) + + let unsigned_operation_encoding = + def "operation.alpha.unsigned_operation" + @@ merge_objs + Operation.shell_header_encoding + (obj1 (req "contents" contents_list_encoding)) + + let internal_operation_encoding = + def "operation.alpha.internal_operation" + @@ conv + (fun (Internal_operation {source; operation; nonce}) -> + ((source, nonce), Manager operation)) + (fun ((source, nonce), Manager operation) -> + Internal_operation {source; operation; nonce}) + (merge_objs + (obj2 (req "source" Contract_repr.encoding) (req "nonce" uint16)) + Manager_operations.encoding) +end + +let encoding = Encoding.operation_encoding + +let contents_encoding = Encoding.contents_encoding + +let contents_list_encoding = Encoding.contents_list_encoding + +let protocol_data_encoding = Encoding.protocol_data_encoding + +let unsigned_operation_encoding = Encoding.unsigned_operation_encoding + +let internal_operation_encoding = Encoding.internal_operation_encoding + +let raw ({shell; protocol_data} : _ operation) = + let proto = + Data_encoding.Binary.to_bytes_exn + protocol_data_encoding + (Operation_data protocol_data) + in + {Operation.shell; proto} + +let acceptable_passes (op : packed_operation) = + let (Operation_data protocol_data) = op.protocol_data in + match protocol_data.contents with + | Single (Failing_noop _) -> [] + | Single (Preendorsement _) -> [0] + | Single (Endorsement _) -> [0] + | Single (Proposals _) -> [1] + | Single (Ballot _) -> [1] + | Single (Seed_nonce_revelation _) -> [2] + | Single (Double_endorsement_evidence _) -> [2] + | Single (Double_preendorsement_evidence _) -> [2] + | Single (Double_baking_evidence _) -> [2] + | Single (Activate_account _) -> [2] + | Single (Manager_operation _) -> [3] + | Cons (Manager_operation _, _ops) -> [3] + +type error += Invalid_signature (* `Permanent *) + +type error += Missing_signature (* `Permanent *) + +let () = + register_error_kind + `Permanent + ~id:"operation.invalid_signature" + ~title:"Invalid operation signature" + ~description: + "The operation signature is ill-formed or has been made with the wrong \ + public key" + ~pp:(fun ppf () -> Format.fprintf ppf "The operation signature is invalid") + Data_encoding.unit + (function Invalid_signature -> Some () | _ -> None) + (fun () -> Invalid_signature) ; + register_error_kind + `Permanent + ~id:"operation.missing_signature" + ~title:"Missing operation signature" + ~description: + "The operation is of a kind that must be signed, but the signature is \ + missing" + ~pp:(fun ppf () -> Format.fprintf ppf "The operation requires a signature") + Data_encoding.unit + (function Missing_signature -> Some () | _ -> None) + (fun () -> Missing_signature) ; + register_error_kind + `Permanent + ~id:"operation.contents_list_error" + ~title:"Invalid list of operation contents." + ~description: + "An operation contents list has an unexpected shape; it should be either \ + a single operation or a non-empty list of manager operations" + ~pp:(fun ppf s -> + Format.fprintf + ppf + "An operation contents list has an unexpected shape: %s" + s) + Data_encoding.(obj1 (req "message" string)) + (function Contents_list_error s -> Some s | _ -> None) + (fun s -> Contents_list_error s) + +let check_signature (type kind) key chain_id + ({shell; protocol_data} : kind operation) = + let check ~watermark contents signature = + let unsigned_operation = + Data_encoding.Binary.to_bytes_exn + unsigned_operation_encoding + (shell, contents) + in + if Signature.check ~watermark key signature unsigned_operation then Ok () + else error Invalid_signature + in + match protocol_data.signature with + | None -> error Missing_signature + | Some signature -> ( + match protocol_data.contents with + | Single (Preendorsement _) as contents -> + check + ~watermark:(to_watermark (Preendorsement chain_id)) + (Contents_list contents) + signature + | Single (Endorsement _) as contents -> + check + ~watermark:(to_watermark (Endorsement chain_id)) + (Contents_list contents) + signature + | Single + ( Failing_noop _ | Proposals _ | Ballot _ | Seed_nonce_revelation _ + | Double_endorsement_evidence _ | Double_preendorsement_evidence _ + | Double_baking_evidence _ | Activate_account _ | Manager_operation _ + ) -> + check + ~watermark:Generic_operation + (Contents_list protocol_data.contents) + signature + | Cons (Manager_operation _, _ops) -> + check + ~watermark:Generic_operation + (Contents_list protocol_data.contents) + signature) + +let hash_raw = Operation.hash + +let hash (o : _ operation) = + let proto = + Data_encoding.Binary.to_bytes_exn + protocol_data_encoding + (Operation_data o.protocol_data) + in + Operation.hash {shell = o.shell; proto} + +let hash_packed (o : packed_operation) = + let proto = + Data_encoding.Binary.to_bytes_exn protocol_data_encoding o.protocol_data + in + Operation.hash {shell = o.shell; proto} + +type ('a, 'b) eq = Eq : ('a, 'a) eq [@@coq_force_gadt] + +let equal_manager_operation_kind : + type a b. a manager_operation -> b manager_operation -> (a, b) eq option = + fun op1 op2 -> + match (op1, op2) with + | (Reveal _, Reveal _) -> Some Eq + | (Reveal _, _) -> None + | (Transaction _, Transaction _) -> Some Eq + | (Transaction _, _) -> None + | (Origination _, Origination _) -> Some Eq + | (Origination _, _) -> None + | (Delegation _, Delegation _) -> Some Eq + | (Delegation _, _) -> None + | (Register_global_constant _, Register_global_constant _) -> Some Eq + | (Register_global_constant _, _) -> None + | (Set_deposits_limit _, Set_deposits_limit _) -> Some Eq + | (Set_deposits_limit _, _) -> None + +let equal_contents_kind : type a b. a contents -> b contents -> (a, b) eq option + = + fun op1 op2 -> + match (op1, op2) with + | (Preendorsement _, Preendorsement _) -> Some Eq + | (Preendorsement _, _) -> None + | (Endorsement _, Endorsement _) -> Some Eq + | (Endorsement _, _) -> None + | (Seed_nonce_revelation _, Seed_nonce_revelation _) -> Some Eq + | (Seed_nonce_revelation _, _) -> None + | (Double_endorsement_evidence _, Double_endorsement_evidence _) -> Some Eq + | (Double_endorsement_evidence _, _) -> None + | (Double_preendorsement_evidence _, Double_preendorsement_evidence _) -> + Some Eq + | (Double_preendorsement_evidence _, _) -> None + | (Double_baking_evidence _, Double_baking_evidence _) -> Some Eq + | (Double_baking_evidence _, _) -> None + | (Activate_account _, Activate_account _) -> Some Eq + | (Activate_account _, _) -> None + | (Proposals _, Proposals _) -> Some Eq + | (Proposals _, _) -> None + | (Ballot _, Ballot _) -> Some Eq + | (Ballot _, _) -> None + | (Failing_noop _, Failing_noop _) -> Some Eq + | (Failing_noop _, _) -> None + | (Manager_operation op1, Manager_operation op2) -> ( + match equal_manager_operation_kind op1.operation op2.operation with + | None -> None + | Some Eq -> Some Eq) + | (Manager_operation _, _) -> None + +let rec equal_contents_kind_list : + type a b. a contents_list -> b contents_list -> (a, b) eq option = + fun op1 op2 -> + match (op1, op2) with + | (Single op1, Single op2) -> equal_contents_kind op1 op2 + | (Single _, Cons _) -> None + | (Cons _, Single _) -> None + | (Cons (op1, ops1), Cons (op2, ops2)) -> ( + match equal_contents_kind op1 op2 with + | None -> None + | Some Eq -> ( + match equal_contents_kind_list ops1 ops2 with + | None -> None + | Some Eq -> Some Eq)) + +let equal : type a b. a operation -> b operation -> (a, b) eq option = + fun op1 op2 -> + if not (Operation_hash.equal (hash op1) (hash op2)) then None + else + equal_contents_kind_list + op1.protocol_data.contents + op2.protocol_data.contents + +open Cache_memory_helpers + +let script_lazy_expr_size (expr : Script_repr.lazy_expr) = + let fun_value expr = ret_adding (expr_size expr) word_size in + let fun_bytes bytes = (Nodes.zero, word_size +! bytes_size bytes) in + let fun_combine expr_size bytes_size = expr_size ++ bytes_size in + ret_adding + (Data_encoding.apply_lazy ~fun_value ~fun_bytes ~fun_combine expr) + header_size + +let script_repr_size ({code; storage} : Script_repr.t) = + ret_adding (script_lazy_expr_size code ++ script_lazy_expr_size storage) h2w + +let internal_manager_operation_size (type a) (op : a manager_operation) = + match op with + | Transaction {amount = _; parameters; entrypoint; destination} -> + ret_adding + (script_lazy_expr_size parameters) + (h4w +! int64_size + +! string_size_gen (String.length entrypoint) + +! Contract_repr.in_memory_size destination) + | Origination {delegate; script; credit = _; preorigination} -> + ret_adding + (script_repr_size script) + (h4w + +! option_size + (fun _ -> Contract_repr.public_key_hash_in_memory_size) + delegate + +! int64_size + +! option_size Contract_repr.in_memory_size preorigination) + | Delegation pkh_opt -> + ( Nodes.zero, + h1w + +! option_size + (fun _ -> Contract_repr.public_key_hash_in_memory_size) + pkh_opt ) + | Reveal _ -> + (* Reveals can't occur as internal operations *) + assert false + | Register_global_constant _ -> + (* Global constant registrations can't occur as internal operations *) + assert false + | Set_deposits_limit _ -> + (* Set_deposits_limit can't occur as internal operations *) + assert false + +let packed_internal_operation_in_memory_size : + packed_internal_operation -> nodes_and_size = function + | Internal_operation iop -> + let {source; operation; nonce = _} = iop in + let source_size = Contract_repr.in_memory_size source in + let nonce_size = word_size in + ret_adding + (internal_manager_operation_size operation) + (h2w +! source_size +! nonce_size) diff --git a/src/proto_012_PsiThaCa/lib_protocol/operation_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/operation_repr.mli new file mode 100644 index 000000000000..730ac686d0ad --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/operation_repr.mli @@ -0,0 +1,377 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Tezos Protocol Implementation - Low level Repr. of Operations + + Defines kinds of operations that can be performed on chain: + - preendorsement + - endorsement + - double baking evidence + - double preendorsing evidence + - double endorsing evidence + - seed nonce revelation + - account activation + - proposal (see: [Voting_repr]) + - ballot (see: [Voting_repr]) + - failing noop + - manager operation (which in turn has several types): + - revelation + - transaction + - origination + - delegation + - set deposits limitation + + Each of them can be encoded as raw bytes. Operations are distinguished at + type level using phantom type parameters. [packed_operation] type allows + for unifying them when required, for instance to put them on a single + list. *) + +module Kind : sig + type preendorsement_consensus_kind = Preendorsement_consensus_kind + + type endorsement_consensus_kind = Endorsement_consensus_kind + + type 'a consensus = + | Preendorsement_kind : preendorsement_consensus_kind consensus + | Endorsement_kind : endorsement_consensus_kind consensus + + type preendorsement = preendorsement_consensus_kind consensus + + type endorsement = endorsement_consensus_kind consensus + + type seed_nonce_revelation = Seed_nonce_revelation_kind + + type 'a double_consensus_operation_evidence = + | Double_consensus_operation_evidence + + type double_endorsement_evidence = + endorsement_consensus_kind double_consensus_operation_evidence + + type double_preendorsement_evidence = + preendorsement_consensus_kind double_consensus_operation_evidence + + type double_baking_evidence = Double_baking_evidence_kind + + type activate_account = Activate_account_kind + + type proposals = Proposals_kind + + type ballot = Ballot_kind + + type reveal = Reveal_kind + + type transaction = Transaction_kind + + type origination = Origination_kind + + type delegation = Delegation_kind + + type set_deposits_limit = Set_deposits_limit_kind + + type failing_noop = Failing_noop_kind + + type register_global_constant = Register_global_constant_kind + + type 'a manager = + | Reveal_manager_kind : reveal manager + | Transaction_manager_kind : transaction manager + | Origination_manager_kind : origination manager + | Delegation_manager_kind : delegation manager + | Register_global_constant_manager_kind : register_global_constant manager + | Set_deposits_limit_manager_kind : set_deposits_limit manager +end + +type 'a consensus_operation_type = + | Endorsement : Kind.endorsement consensus_operation_type + | Preendorsement : Kind.preendorsement consensus_operation_type + +val pp_operation_kind : + Format.formatter -> 'kind consensus_operation_type -> unit + +type consensus_content = { + slot : Slot_repr.t; + (* By convention, this is the validator's first slot. *) + level : Raw_level_repr.t; + (* The level of (pre)endorsed block. *) + round : Round_repr.t; + (* The round of (pre)endorsed block. *) + block_payload_hash : Block_payload_hash.t; + (* The payload hash of (pre)endorsed block. *) +} + +val consensus_content_encoding : consensus_content Data_encoding.t + +val pp_consensus_content : Format.formatter -> consensus_content -> unit + +type consensus_watermark = + | Endorsement of Chain_id.t + | Preendorsement of Chain_id.t + +val to_watermark : consensus_watermark -> Signature.watermark + +val of_watermark : Signature.watermark -> consensus_watermark option + +type raw = Operation.t = {shell : Operation.shell_header; proto : bytes} + +val raw_encoding : raw Data_encoding.t + +type 'kind operation = { + shell : Operation.shell_header; + protocol_data : 'kind protocol_data; +} + +and 'kind protocol_data = { + contents : 'kind contents_list; + signature : Signature.t option; +} + +and _ contents_list = + | Single : 'kind contents -> 'kind contents_list + | Cons : + 'kind Kind.manager contents * 'rest Kind.manager contents_list + -> ('kind * 'rest) Kind.manager contents_list + +and _ contents = + | Preendorsement : consensus_content -> Kind.preendorsement contents + | Endorsement : consensus_content -> Kind.endorsement contents + | Seed_nonce_revelation : { + level : Raw_level_repr.t; + nonce : Seed_repr.nonce; + } + -> Kind.seed_nonce_revelation contents + | Double_preendorsement_evidence : { + op1 : Kind.preendorsement operation; + op2 : Kind.preendorsement operation; + } + -> Kind.double_preendorsement_evidence contents + | Double_endorsement_evidence : { + op1 : Kind.endorsement operation; + op2 : Kind.endorsement operation; + } + -> Kind.double_endorsement_evidence contents + | Double_baking_evidence : { + bh1 : Block_header_repr.t; + bh2 : Block_header_repr.t; + } + -> Kind.double_baking_evidence contents + | Activate_account : { + id : Ed25519.Public_key_hash.t; + activation_code : Blinded_public_key_hash.activation_code; + } + -> Kind.activate_account contents + | Proposals : { + source : Signature.Public_key_hash.t; + period : int32; + proposals : Protocol_hash.t list; + } + -> Kind.proposals contents + | Ballot : { + source : Signature.Public_key_hash.t; + period : int32; + proposal : Protocol_hash.t; + ballot : Vote_repr.ballot; + } + -> Kind.ballot contents + | Failing_noop : string -> Kind.failing_noop contents + | Manager_operation : { + source : Signature.Public_key_hash.t; + fee : Tez_repr.tez; + counter : counter; + operation : 'kind manager_operation; + gas_limit : Gas_limit_repr.Arith.integral; + storage_limit : Z.t; + } + -> 'kind Kind.manager contents + +and _ manager_operation = + | Reveal : Signature.Public_key.t -> Kind.reveal manager_operation + | Transaction : { + amount : Tez_repr.tez; + parameters : Script_repr.lazy_expr; + entrypoint : string; + destination : Contract_repr.contract; + } + -> Kind.transaction manager_operation + | Origination : { + delegate : Signature.Public_key_hash.t option; + script : Script_repr.t; + credit : Tez_repr.tez; + preorigination : Contract_repr.t option; + } + -> Kind.origination manager_operation + | Delegation : + Signature.Public_key_hash.t option + -> Kind.delegation manager_operation + | Register_global_constant : { + value : Script_repr.lazy_expr; + } + -> Kind.register_global_constant manager_operation + | Set_deposits_limit : + Tez_repr.t option + -> Kind.set_deposits_limit manager_operation + +and counter = Z.t + +type 'kind internal_operation = { + source : Contract_repr.contract; + operation : 'kind manager_operation; + nonce : int; +} + +type packed_manager_operation = + | Manager : 'kind manager_operation -> packed_manager_operation + +type packed_contents = Contents : 'kind contents -> packed_contents + +type packed_contents_list = + | Contents_list : 'kind contents_list -> packed_contents_list + +val of_list : packed_contents list -> packed_contents_list tzresult + +val to_list : packed_contents_list -> packed_contents list + +type packed_protocol_data = + | Operation_data : 'kind protocol_data -> packed_protocol_data + +type packed_operation = { + shell : Operation.shell_header; + protocol_data : packed_protocol_data; +} + +val pack : 'kind operation -> packed_operation + +type packed_internal_operation = + | Internal_operation : 'kind internal_operation -> packed_internal_operation + +val manager_kind : 'kind manager_operation -> 'kind Kind.manager + +val encoding : packed_operation Data_encoding.t + +val contents_encoding : packed_contents Data_encoding.t + +val contents_list_encoding : packed_contents_list Data_encoding.t + +val protocol_data_encoding : packed_protocol_data Data_encoding.t + +val unsigned_operation_encoding : + (Operation.shell_header * packed_contents_list) Data_encoding.t + +val raw : _ operation -> raw + +val hash_raw : raw -> Operation_hash.t + +val hash : _ operation -> Operation_hash.t + +val hash_packed : packed_operation -> Operation_hash.t + +val acceptable_passes : packed_operation -> int list + +type error += Missing_signature (* `Permanent *) + +type error += Invalid_signature (* `Permanent *) + +val check_signature : + Signature.Public_key.t -> Chain_id.t -> _ operation -> unit tzresult + +val internal_operation_encoding : packed_internal_operation Data_encoding.t + +type ('a, 'b) eq = Eq : ('a, 'a) eq + +val equal : 'a operation -> 'b operation -> ('a, 'b) eq option + +val packed_internal_operation_in_memory_size : + packed_internal_operation -> Cache_memory_helpers.nodes_and_size + +module Encoding : sig + type 'b case = + | Case : { + tag : int; + name : string; + encoding : 'a Data_encoding.t; + select : packed_contents -> 'b contents option; + proj : 'b contents -> 'a; + inj : 'a -> 'b contents; + } + -> 'b case + + val preendorsement_case : Kind.preendorsement case + + val endorsement_case : Kind.endorsement case + + val seed_nonce_revelation_case : Kind.seed_nonce_revelation case + + val double_preendorsement_evidence_case : + Kind.double_preendorsement_evidence case + + val double_endorsement_evidence_case : Kind.double_endorsement_evidence case + + val double_baking_evidence_case : Kind.double_baking_evidence case + + val activate_account_case : Kind.activate_account case + + val proposals_case : Kind.proposals case + + val ballot_case : Kind.ballot case + + val failing_noop_case : Kind.failing_noop case + + val reveal_case : Kind.reveal Kind.manager case + + val transaction_case : Kind.transaction Kind.manager case + + val origination_case : Kind.origination Kind.manager case + + val delegation_case : Kind.delegation Kind.manager case + + val register_global_constant_case : + Kind.register_global_constant Kind.manager case + + val set_deposits_limit_case : Kind.set_deposits_limit Kind.manager case + + module Manager_operations : sig + type 'b case = + | MCase : { + tag : int; + name : string; + encoding : 'a Data_encoding.t; + select : packed_manager_operation -> 'kind manager_operation option; + proj : 'kind manager_operation -> 'a; + inj : 'a -> 'kind manager_operation; + } + -> 'kind case + + val reveal_case : Kind.reveal case + + val transaction_case : Kind.transaction case + + val origination_case : Kind.origination case + + val delegation_case : Kind.delegation case + + val register_global_constant_case : Kind.register_global_constant case + + val set_deposits_limit_case : Kind.set_deposits_limit case + end +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/parameters_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/parameters_repr.ml new file mode 100644 index 000000000000..5f21e6c3d453 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/parameters_repr.ml @@ -0,0 +1,132 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type bootstrap_account = { + public_key_hash : Signature.Public_key_hash.t; + public_key : Signature.Public_key.t option; + amount : Tez_repr.t; +} + +type bootstrap_contract = { + delegate : Signature.Public_key_hash.t option; + amount : Tez_repr.t; + script : Script_repr.t; +} + +type t = { + bootstrap_accounts : bootstrap_account list; + bootstrap_contracts : bootstrap_contract list; + commitments : Commitment_repr.t list; + constants : Constants_repr.parametric; + security_deposit_ramp_up_cycles : int option; + no_reward_cycles : int option; +} + +let bootstrap_account_encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"Public_key_known" + (tup2 Signature.Public_key.encoding Tez_repr.encoding) + (function + | {public_key_hash; public_key = Some public_key; amount} -> + assert ( + Signature.Public_key_hash.equal + (Signature.Public_key.hash public_key) + public_key_hash) ; + Some (public_key, amount) + | {public_key = None; _} -> None) + (fun (public_key, amount) -> + { + public_key = Some public_key; + public_key_hash = Signature.Public_key.hash public_key; + amount; + }); + case + (Tag 1) + ~title:"Public_key_unknown" + (tup2 Signature.Public_key_hash.encoding Tez_repr.encoding) + (function + | {public_key_hash; public_key = None; amount} -> + Some (public_key_hash, amount) + | {public_key = Some _; _} -> None) + (fun (public_key_hash, amount) -> + {public_key = None; public_key_hash; amount}); + ] + +let bootstrap_contract_encoding = + let open Data_encoding in + conv + (fun {delegate; amount; script} -> (delegate, amount, script)) + (fun (delegate, amount, script) -> {delegate; amount; script}) + (obj3 + (opt "delegate" Signature.Public_key_hash.encoding) + (req "amount" Tez_repr.encoding) + (req "script" Script_repr.encoding)) + +let encoding = + let open Data_encoding in + conv + (fun { + bootstrap_accounts; + bootstrap_contracts; + commitments; + constants; + security_deposit_ramp_up_cycles; + no_reward_cycles; + } -> + ( ( bootstrap_accounts, + bootstrap_contracts, + commitments, + security_deposit_ramp_up_cycles, + no_reward_cycles ), + constants )) + (fun ( ( bootstrap_accounts, + bootstrap_contracts, + commitments, + security_deposit_ramp_up_cycles, + no_reward_cycles ), + constants ) -> + { + bootstrap_accounts; + bootstrap_contracts; + commitments; + constants; + security_deposit_ramp_up_cycles; + no_reward_cycles; + }) + (merge_objs + (obj5 + (req "bootstrap_accounts" (list bootstrap_account_encoding)) + (dft "bootstrap_contracts" (list bootstrap_contract_encoding) []) + (dft "commitments" (list Commitment_repr.encoding) []) + (opt "security_deposit_ramp_up_cycles" int31) + (opt "no_reward_cycles" int31)) + Constants_repr.parametric_encoding) + +let check_params params = Constants_repr.check_constants params.constants diff --git a/src/proto_012_PsiThaCa/lib_protocol/parameters_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/parameters_repr.mli new file mode 100644 index 000000000000..0b9e3af8ed3d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/parameters_repr.mli @@ -0,0 +1,57 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module defines protocol parameters, i.e. constants regulating the + behaviour of the blockchain under the protocol. *) + +(** An implict contract (account) initially existing on a chain since genesis. *) +type bootstrap_account = { + public_key_hash : Signature.Public_key_hash.t; + public_key : Signature.Public_key.t option; + amount : Tez_repr.t; +} + +(** An originated contract initially existing on a chain since genesis. *) +type bootstrap_contract = { + delegate : Signature.Public_key_hash.t option; + amount : Tez_repr.t; + script : Script_repr.t; +} + +(** Protocol parameters define some constants regulating behaviour of the + chain. *) +type t = { + bootstrap_accounts : bootstrap_account list; + bootstrap_contracts : bootstrap_contract list; + commitments : Commitment_repr.t list; + constants : Constants_repr.parametric; + security_deposit_ramp_up_cycles : int option; + no_reward_cycles : int option; +} + +val encoding : t Data_encoding.t + +val check_params : t -> unit tzresult diff --git a/src/proto_012_PsiThaCa/lib_protocol/path_encoding.ml b/src/proto_012_PsiThaCa/lib_protocol/path_encoding.ml new file mode 100644 index 000000000000..e2657785be11 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/path_encoding.ml @@ -0,0 +1,54 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 DaiLambda, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type S = sig + type t + + val to_path : t -> string list -> string list + + val of_path : string list -> t option + + val path_length : int +end + +module Make_hex (H : sig + type t + + val to_bytes : t -> bytes + + val of_bytes_opt : bytes -> t option +end) = +struct + let path_length = 1 + + let to_path t l = + let (`Hex key) = Hex.of_bytes (H.to_bytes t) in + key :: l + + let of_path = function + | [path] -> Option.bind (Hex.to_bytes (`Hex path)) H.of_bytes_opt + | _ -> None +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/path_encoding.mli b/src/proto_012_PsiThaCa/lib_protocol/path_encoding.mli new file mode 100644 index 000000000000..7388fb52f6d2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/path_encoding.mli @@ -0,0 +1,48 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 DaiLambda, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type S = sig + type t + + (** [to_path t postfix] returns the context path name for [t] + postfixed with [postfix] *) + val to_path : t -> string list -> string list + + (** [of_path path] parses [path] as a context path name for [t] *) + val of_path : string list -> t option + + (** Directory levels of the path encoding of [t] *) + val path_length : int +end + +(** Path encoding in hex: /[0-9a-f]{2}+/ *) +module Make_hex (H : sig + type t + + val to_bytes : t -> bytes + + val of_bytes_opt : bytes -> t option +end) : S with type t := H.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/period_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/period_repr.ml new file mode 100644 index 000000000000..1f2de5752be8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/period_repr.ml @@ -0,0 +1,164 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* `Permanent *) +type error += Malformed_period of int64 | Invalid_arg | Period_overflow + +let () = + let open Data_encoding in + (* Malformed period *) + register_error_kind + `Permanent + ~id:"malformed_period" + ~title:"Malformed period" + ~description:"Period is negative." + ~pp:(fun ppf period -> + Format.fprintf ppf "The given period '%Ld' is negative " period) + (obj1 (req "malformed_period" int64)) + (function Malformed_period n -> Some n | _ -> None) + (fun n -> Malformed_period n) ; + (* Invalid arg *) + register_error_kind + `Permanent + ~id:"invalid_arg" + ~title:"Invalid arg" + ~description:"Negative multiple of periods are not allowed." + ~pp:(fun ppf () -> Format.fprintf ppf "Invalid arg") + empty + (function Invalid_arg -> Some () | _ -> None) + (fun () -> Invalid_arg) ; + let title = "Period overflow" in + register_error_kind + `Permanent + ~id:"period_overflow" + ~title + ~description:"Last operation generated an integer overflow." + ~pp:(fun ppf () -> Format.fprintf ppf "%s" title) + empty + (function Period_overflow -> Some () | _ -> None) + (fun () -> Period_overflow) + +module type INTERNAL = sig + type t = private int64 + + val create : int64 -> t option + + val zero : t + + val one : t + + val mult_ : t -> t -> t option + + val add_ : t -> t -> t option + + val encoding : t Data_encoding.t + + val rpc_arg : t RPC_arg.arg + + val pp : Format.formatter -> t -> unit + + include Compare.S with type t := t +end + +(* Internal module implementing natural numbers using int64. These are different + from usual (wrapping up) unsigned integers in that if one overflows the + representation bounds for int64 through [add] or [mul], a [None] value is + returned *) +module Internal : INTERNAL = struct + type t = Int64.t + + let encoding = + Data_encoding.( + with_decoding_guard + (fun t -> + if Compare.Int64.(t >= 0L) then Ok () + else Error "Positive int64 required") + int64) + + let rpc_arg = RPC_arg.uint63 + + let pp ppf v = Format.fprintf ppf "%Ld" v + + include (Compare.Int64 : Compare.S with type t := t) + + let zero = 0L + + let one = 1L + + let create t = if t >= zero then Some t else None + + (* The create function is not used in the [mul_] and [add_] below to not add + extra Some | None pattern matching to handle since the overflow checks are + generic and apply as well to negative as positive integers . + + To handle overflows, both [add_] and [mult_] return option types. [None] is + returned on detected overflow, [Some value] when everything went well. *) + let mult_ a b = + if a <> zero then + let res = Int64.mul a b in + if Int64.div res a <> b then None else Some res + else Some zero + + let add_ a b = + let res = Int64.add a b in + if res < a || res < b then None else Some res +end + +include Internal + +type period = Internal.t + +let to_seconds (t : Internal.t) = (t :> int64) + +let of_seconds secs = + match Internal.create secs with + | Some v -> ok v + | None -> error (Malformed_period secs) + +let of_seconds_exn t = + match Internal.create t with + | Some t -> t + | None -> invalid_arg "Period.of_seconds_exn" + +let mult i p = + match Internal.create (Int64.of_int32 i) with + | None -> error Invalid_arg + | Some iper -> ( + match Internal.mult_ iper p with + | None -> error Period_overflow + | Some res -> ok res) + +let add p1 p2 = + match Internal.add_ p1 p2 with + | None -> error Period_overflow + | Some res -> ok res + +let ( +? ) = add + +let one_second = Internal.one + +let one_minute = of_seconds_exn 60L + +let one_hour = of_seconds_exn 3600L diff --git a/src/proto_012_PsiThaCa/lib_protocol/period_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/period_repr.mli new file mode 100644 index 000000000000..92f60493a57d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/period_repr.mli @@ -0,0 +1,73 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t + +(** Represents a period of time as a non-negative integer. *) +type period = t + +include Compare.S with type t := t + +val encoding : period Data_encoding.t + +val rpc_arg : period RPC_arg.t + +val pp : Format.formatter -> period -> unit + +(** Returns the number of seconds contained in the period. *) +val to_seconds : period -> int64 + +(** Converts a number of seconds to a [period]. + + [of_second s] fails if [s] is not positive. *) +val of_seconds : int64 -> period tzresult + +(** Converts a number of seconds to [period]. + + [of_second s] fails if [s] is not positive. + It should only be used at toplevel for constants. *) +val of_seconds_exn : int64 -> period + +(** Safe addition of periods, guarded against overflow. *) +val add : period -> period -> period tzresult + +(** Alias for [add]. *) +val ( +? ) : period -> period -> period tzresult + +(** Safe multiplication by a positive integer. Guarded against overflow. *) +val mult : int32 -> period -> period tzresult + +val zero : period + +val one_second : period + +val one_minute : period + +val one_hour : period + +(** [compare x y] returns [0] if [x] is equal to [y], a negative + integer if [x] is shorter than [y], and a positive integer if [x] + is longer than [y]. *) +val compare : period -> period -> int diff --git a/src/proto_012_PsiThaCa/lib_protocol/raw_context.ml b/src/proto_012_PsiThaCa/lib_protocol/raw_context.ml new file mode 100644 index 000000000000..23b2bbaf2374 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/raw_context.ml @@ -0,0 +1,1295 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Int_set = Set.Make (Compare.Int) + +(* + + Gas levels maintenance + ======================= + + The context maintains two levels of gas, one corresponds to the gas + available for the current operation while the other is the gas + available for the current block. Both levels are maintained + independently: [consume_gas] only decreases the operation level, + and block level should be updated with [consume_gas_limit_in_block]. + + A layered context + ================= + + Updating the context [remaining_operation_gas] is a critical routine + called very frequently by the operations performed by the protocol. + On the contrary, other fields are less frequently updated. + + In a previous version of the context datatype definition, all + the fields were represented at the toplevel. To update the remaining + gas, we had to copy ~25 fields (that is 200 bytes). + + With the following layered representation, we only have to + copy 2 fields (16 bytes) during [remaining_operation_gas] update. + This has a significant impact on the Michelson runtime efficiency. + + Here are the fields on the [back] of the context: + + *) + +module Raw_consensus = struct + (** Consensus operations are indexed by their [initial slots]. Given + a delegate, the [initial slot] is the lowest slot assigned to + this delegate. *) + + type t = { + current_endorsement_power : int; + (** Number of endorsement slots recorded for the current block. *) + allowed_endorsements : + (Signature.Public_key.t * Signature.Public_key_hash.t * int) + Slot_repr.Map.t; + (** Endorsements rights for the current block. Only an endorsement + for the lowest slot in the block can be recorded. The map + associates to each initial slot the [pkh] associated to this + slot with its power. *) + allowed_preendorsements : + (Signature.Public_key.t * Signature.Public_key_hash.t * int) + Slot_repr.Map.t; + (** Preendorsements rights for the current block. Only a preendorsement + for the lowest slot in the block can be recorded. The map + associates to each initial slot the [pkh] associated to this + slot with its power. *) + grand_parent_endorsements_seen : Signature.Public_key_hash.Set.t; + (** Record the endorsements already seen for the grand + parent. This only useful for the partial construction mode. *) + endorsements_seen : Slot_repr.Set.t; + (** Record the endorsements already seen. Only initial slots are indexed. *) + preendorsements_seen : Slot_repr.Set.t; + (** Record the preendorsements already seen. Only initial slots + are indexed. *) + locked_round_evidence : (Round_repr.t * int) option; + (** Record the preendorsement power for a locked round. *) + preendorsements_quorum_round : Round_repr.t option; + (** in block construction mode, record the round of preendorsements + included in a block. *) + endorsement_branch : (Block_hash.t * Block_payload_hash.t) option; + grand_parent_branch : (Block_hash.t * Block_payload_hash.t) option; + } + + (** Invariant: + + - [slot \in endorsements_seen => Int_map.mem slot allowed_endorsements] + + - [slot \in preendorsements_seen => Int_map.mem slot allowed_preendorsements] + + - [ |endorsements_seen| > 0 => |included endorsements| > 0] + + *) + + let empty : t = + { + current_endorsement_power = 0; + allowed_endorsements = Slot_repr.Map.empty; + allowed_preendorsements = Slot_repr.Map.empty; + grand_parent_endorsements_seen = Signature.Public_key_hash.Set.empty; + endorsements_seen = Slot_repr.Set.empty; + preendorsements_seen = Slot_repr.Set.empty; + locked_round_evidence = None; + preendorsements_quorum_round = None; + endorsement_branch = None; + grand_parent_branch = None; + } + + type error += Double_inclusion_of_consensus_operation + + let () = + register_error_kind + `Branch + ~id:"operation.double_inclusion_of_consensus_operation" + ~title:"double inclusion of consensus operation" + ~description:"double inclusion of consensus operation" + ~pp:(fun ppf () -> + Format.fprintf ppf "Double inclusion of consensus operation") + Data_encoding.empty + (function + | Double_inclusion_of_consensus_operation -> Some () | _ -> None) + (fun () -> Double_inclusion_of_consensus_operation) + + let record_grand_parent_endorsement t pkh = + error_when + (Signature.Public_key_hash.Set.mem pkh t.grand_parent_endorsements_seen) + Double_inclusion_of_consensus_operation + >|? fun () -> + { + t with + grand_parent_endorsements_seen = + Signature.Public_key_hash.Set.add pkh t.grand_parent_endorsements_seen; + } + + let record_endorsement t ~initial_slot ~power = + error_when + (Slot_repr.Set.mem initial_slot t.endorsements_seen) + Double_inclusion_of_consensus_operation + >|? fun () -> + { + t with + current_endorsement_power = t.current_endorsement_power + power; + endorsements_seen = Slot_repr.Set.add initial_slot t.endorsements_seen; + } + + let record_preendorsement ~initial_slot ~power round t = + error_when + (Slot_repr.Set.mem initial_slot t.preendorsements_seen) + Double_inclusion_of_consensus_operation + >|? fun () -> + let locked_round_evidence = + match t.locked_round_evidence with + | None -> Some (round, power) + | Some (_stored_round, evidences) -> + (* In mempool mode, round and stored_round can be different. + It doesn't matter in that case since quorum certificates + are not used in mempool. + For other cases [Apply.check_round] verifies it. *) + Some (round, evidences + power) + in + { + t with + locked_round_evidence; + preendorsements_seen = + Slot_repr.Set.add initial_slot t.preendorsements_seen; + } + + let set_preendorsements_quorum_round round t = + match t.preendorsements_quorum_round with + | Some round' -> + (* If the rounds are different, an error should have already + been raised. *) + assert (Round_repr.equal round round') ; + t + | None -> {t with preendorsements_quorum_round = Some round} + + let initialize_with_endorsements_and_preendorsements ~allowed_endorsements + ~allowed_preendorsements t = + {t with allowed_endorsements; allowed_preendorsements} + + let locked_round_evidence t = t.locked_round_evidence + + let endorsement_branch t = t.endorsement_branch + + let grand_parent_branch t = t.grand_parent_branch + + let set_endorsement_branch t endorsement_branch = + {t with endorsement_branch = Some endorsement_branch} + + let set_grand_parent_branch t grand_parent_branch = + {t with grand_parent_branch = Some grand_parent_branch} +end + +type back = { + context : Context.t; + constants : Constants_repr.parametric; + round_durations : Round_repr.Durations.t; + cycle_eras : Level_repr.cycle_eras; + level : Level_repr.t; + predecessor_timestamp : Time.t; + timestamp : Time.t; + fees : Tez_repr.t; + origination_nonce : Contract_repr.origination_nonce option; + temporary_lazy_storage_ids : Lazy_storage_kind.Temp_ids.t; + internal_nonce : int; + internal_nonces_used : Int_set.t; + remaining_block_gas : Gas_limit_repr.Arith.fp; + unlimited_operation_gas : bool; + consensus : Raw_consensus.t; + non_consensus_operations : Operation_hash.t list; + sampler_state : + (Seed_repr.seed + * (Signature.Public_key.t * Signature.Public_key_hash.t) Sampler.t) + Cycle_repr.Map.t; + stake_distribution_for_current_cycle : + Tez_repr.t Signature.Public_key_hash.Map.t option; +} + +(* + + The context is simply a record with two fields which + limits the cost of updating the [remaining_operation_gas]. + +*) +type t = {remaining_operation_gas : Gas_limit_repr.Arith.fp; back : back} + +type root = t + +(* + + Context fields accessors + ======================== + + To have the context related code more robust to evolutions, + we introduce accessors to get and to update the context + components. + +*) +let[@inline] context ctxt = ctxt.back.context + +let[@inline] current_level ctxt = ctxt.back.level + +let[@inline] predecessor_timestamp ctxt = ctxt.back.predecessor_timestamp + +let[@inline] current_timestamp ctxt = ctxt.back.timestamp + +let[@inline] round_durations ctxt = ctxt.back.round_durations + +let[@inline] cycle_eras ctxt = ctxt.back.cycle_eras + +let[@inline] constants ctxt = ctxt.back.constants + +let[@inline] recover ctxt = ctxt.back.context + +let[@inline] fees ctxt = ctxt.back.fees + +let[@inline] origination_nonce ctxt = ctxt.back.origination_nonce + +let[@inline] internal_nonce ctxt = ctxt.back.internal_nonce + +let[@inline] internal_nonces_used ctxt = ctxt.back.internal_nonces_used + +let[@inline] remaining_block_gas ctxt = ctxt.back.remaining_block_gas + +let[@inline] unlimited_operation_gas ctxt = ctxt.back.unlimited_operation_gas + +let[@inline] temporary_lazy_storage_ids ctxt = + ctxt.back.temporary_lazy_storage_ids + +let[@inline] remaining_operation_gas ctxt = ctxt.remaining_operation_gas + +let[@inline] non_consensus_operations ctxt = ctxt.back.non_consensus_operations + +let[@inline] sampler_state ctxt = ctxt.back.sampler_state + +let[@inline] update_back ctxt back = {ctxt with back} + +let[@inline] update_remaining_block_gas ctxt remaining_block_gas = + update_back ctxt {ctxt.back with remaining_block_gas} + +let[@inline] update_remaining_operation_gas ctxt remaining_operation_gas = + {ctxt with remaining_operation_gas} + +let[@inline] update_unlimited_operation_gas ctxt unlimited_operation_gas = + update_back ctxt {ctxt.back with unlimited_operation_gas} + +let[@inline] update_context ctxt context = + update_back ctxt {ctxt.back with context} + +let[@inline] update_constants ctxt constants = + update_back ctxt {ctxt.back with constants} + +let[@inline] update_origination_nonce ctxt origination_nonce = + update_back ctxt {ctxt.back with origination_nonce} + +let[@inline] update_internal_nonce ctxt internal_nonce = + update_back ctxt {ctxt.back with internal_nonce} + +let[@inline] update_internal_nonces_used ctxt internal_nonces_used = + update_back ctxt {ctxt.back with internal_nonces_used} + +let[@inline] update_fees ctxt fees = update_back ctxt {ctxt.back with fees} + +let[@inline] update_temporary_lazy_storage_ids ctxt temporary_lazy_storage_ids = + update_back ctxt {ctxt.back with temporary_lazy_storage_ids} + +let[@inline] update_non_consensus_operations ctxt non_consensus_operations = + update_back ctxt {ctxt.back with non_consensus_operations} + +let[@inline] update_sampler_state ctxt sampler_state = + update_back ctxt {ctxt.back with sampler_state} + +type error += Too_many_internal_operations (* `Permanent *) + +type error += Block_quota_exceeded (* `Temporary *) + +type error += Operation_quota_exceeded (* `Temporary *) + +type error += Stake_distribution_not_set (* `Branch *) + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"too_many_internal_operations" + ~title:"Too many internal operations" + ~description: + "A transaction exceeded the hard limit of internal operations it can emit" + empty + (function Too_many_internal_operations -> Some () | _ -> None) + (fun () -> Too_many_internal_operations) ; + register_error_kind + `Temporary + ~id:"gas_exhausted.operation" + ~title:"Gas quota exceeded for the operation" + ~description: + "A script or one of its callee took more time than the operation said it \ + would" + empty + (function Operation_quota_exceeded -> Some () | _ -> None) + (fun () -> Operation_quota_exceeded) ; + register_error_kind + `Temporary + ~id:"gas_exhausted.block" + ~title:"Gas quota exceeded for the block" + ~description: + "The sum of gas consumed by all the operations in the block exceeds the \ + hard gas limit per block" + empty + (function Block_quota_exceeded -> Some () | _ -> None) + (fun () -> Block_quota_exceeded) ; + register_error_kind + `Permanent + ~id:"delegate.stake_distribution_not_set" + ~title:"Stake distribution not set" + ~description:"The stake distribution for the current cycle is not set." + ~pp:(fun ppf () -> + Format.fprintf + ppf + "The stake distribution for the current cycle is not set.") + Data_encoding.(empty) + (function Stake_distribution_not_set -> Some () | _ -> None) + (fun () -> Stake_distribution_not_set) + +let fresh_internal_nonce ctxt = + if Compare.Int.(internal_nonce ctxt >= 65_535) then + error Too_many_internal_operations + else + ok + (update_internal_nonce ctxt (internal_nonce ctxt + 1), internal_nonce ctxt) + +let reset_internal_nonce ctxt = + let ctxt = update_internal_nonce ctxt 0 in + update_internal_nonces_used ctxt Int_set.empty + +let record_internal_nonce ctxt k = + update_internal_nonces_used ctxt (Int_set.add k (internal_nonces_used ctxt)) + +let internal_nonce_already_recorded ctxt k = + Int_set.mem k (internal_nonces_used ctxt) + +let get_collected_fees ctxt = fees ctxt + +let credit_collected_fees_only_call_from_token ctxt fees' = + let previous = get_collected_fees ctxt in + Tez_repr.(previous +? fees') >|? fun fees -> update_fees ctxt fees + +let spend_collected_fees_only_call_from_token ctxt fees' = + let previous = get_collected_fees ctxt in + Tez_repr.(previous -? fees') >|? fun fees -> update_fees ctxt fees + +type error += Undefined_operation_nonce (* `Permanent *) + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"undefined_operation_nonce" + ~title:"Ill timed access to the origination nonce" + ~description: + "An origination was attempted out of the scope of a manager operation" + empty + (function Undefined_operation_nonce -> Some () | _ -> None) + (fun () -> Undefined_operation_nonce) + +let init_origination_nonce ctxt operation_hash = + let origination_nonce = + Some (Contract_repr.initial_origination_nonce operation_hash) + in + update_origination_nonce ctxt origination_nonce + +let increment_origination_nonce ctxt = + match origination_nonce ctxt with + | None -> error Undefined_operation_nonce + | Some cur_origination_nonce -> + let origination_nonce = + Some (Contract_repr.incr_origination_nonce cur_origination_nonce) + in + let ctxt = update_origination_nonce ctxt origination_nonce in + ok (ctxt, cur_origination_nonce) + +let get_origination_nonce ctxt = + match origination_nonce ctxt with + | None -> error Undefined_operation_nonce + | Some origination_nonce -> ok origination_nonce + +let unset_origination_nonce ctxt = update_origination_nonce ctxt None + +type error += Gas_limit_too_high (* `Permanent *) + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"gas_limit_too_high" + ~title:"Gas limit out of protocol hard bounds" + ~description:"A transaction tried to exceed the hard limit on gas" + empty + (function Gas_limit_too_high -> Some () | _ -> None) + (fun () -> Gas_limit_too_high) + +let gas_level ctxt = + let open Gas_limit_repr in + if unlimited_operation_gas ctxt then Unaccounted + else Limited {remaining = remaining_operation_gas ctxt} + +let block_gas_level = remaining_block_gas + +let check_gas_limit_is_valid ctxt (remaining : 'a Gas_limit_repr.Arith.t) = + if + Gas_limit_repr.Arith.( + remaining > (constants ctxt).hard_gas_limit_per_operation + || remaining < zero) + then error Gas_limit_too_high + else Result.return_unit + +let consume_gas_limit_in_block ctxt (limit : 'a Gas_limit_repr.Arith.t) = + let open Gas_limit_repr in + check_gas_limit_is_valid ctxt limit >>? fun () -> + let block_gas = block_gas_level ctxt in + let limit = Arith.fp limit in + if Arith.(limit > block_gas) then error Block_quota_exceeded + else + let level = Arith.sub (block_gas_level ctxt) limit in + let ctxt = update_remaining_block_gas ctxt level in + Ok ctxt + +let set_gas_limit ctxt (remaining : 'a Gas_limit_repr.Arith.t) = + let open Gas_limit_repr in + let remaining_operation_gas = Arith.fp remaining in + let ctxt = update_unlimited_operation_gas ctxt false in + {ctxt with remaining_operation_gas} + +let set_gas_unlimited ctxt = update_unlimited_operation_gas ctxt true + +let consume_gas ctxt cost = + match Gas_limit_repr.raw_consume (remaining_operation_gas ctxt) cost with + | Some gas_counter -> Ok (update_remaining_operation_gas ctxt gas_counter) + | None -> + if unlimited_operation_gas ctxt then ok ctxt + else error Operation_quota_exceeded + +let check_enough_gas ctxt cost = + consume_gas ctxt cost >>? fun _ -> Result.return_unit + +let gas_consumed ~since ~until = + match (gas_level since, gas_level until) with + | (Limited {remaining = before}, Limited {remaining = after}) -> + Gas_limit_repr.Arith.sub before after + | (_, _) -> Gas_limit_repr.Arith.zero + +type missing_key_kind = Get | Set | Del | Copy + +type storage_error = + | Incompatible_protocol_version of string + | Missing_key of string list * missing_key_kind + | Existing_key of string list + | Corrupted_data of string list + +let storage_error_encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"Incompatible_protocol_version" + (obj1 (req "incompatible_protocol_version" string)) + (function Incompatible_protocol_version arg -> Some arg | _ -> None) + (fun arg -> Incompatible_protocol_version arg); + case + (Tag 1) + ~title:"Missing_key" + (obj2 + (req "missing_key" (list string)) + (req + "function" + (string_enum + [("get", Get); ("set", Set); ("del", Del); ("copy", Copy)]))) + (function Missing_key (key, f) -> Some (key, f) | _ -> None) + (fun (key, f) -> Missing_key (key, f)); + case + (Tag 2) + ~title:"Existing_key" + (obj1 (req "existing_key" (list string))) + (function Existing_key key -> Some key | _ -> None) + (fun key -> Existing_key key); + case + (Tag 3) + ~title:"Corrupted_data" + (obj1 (req "corrupted_data" (list string))) + (function Corrupted_data key -> Some key | _ -> None) + (fun key -> Corrupted_data key); + ] + +let pp_storage_error ppf = function + | Incompatible_protocol_version version -> + Format.fprintf + ppf + "Found a context with an unexpected version '%s'." + version + | Missing_key (key, Get) -> + Format.fprintf ppf "Missing key '%s'." (String.concat "/" key) + | Missing_key (key, Set) -> + Format.fprintf + ppf + "Cannot set undefined key '%s'." + (String.concat "/" key) + | Missing_key (key, Del) -> + Format.fprintf + ppf + "Cannot delete undefined key '%s'." + (String.concat "/" key) + | Missing_key (key, Copy) -> + Format.fprintf + ppf + "Cannot copy undefined key '%s'." + (String.concat "/" key) + | Existing_key key -> + Format.fprintf + ppf + "Cannot initialize defined key '%s'." + (String.concat "/" key) + | Corrupted_data key -> + Format.fprintf + ppf + "Failed to parse the data at '%s'." + (String.concat "/" key) + +type error += Storage_error of storage_error + +let () = + register_error_kind + `Permanent + ~id:"context.storage_error" + ~title:"Storage error (fatal internal error)" + ~description: + "An error that should never happen unless something has been deleted or \ + corrupted in the database." + ~pp:(fun ppf err -> + Format.fprintf ppf "@[Storage error:@ %a@]" pp_storage_error err) + storage_error_encoding + (function Storage_error err -> Some err | _ -> None) + (fun err -> Storage_error err) + +let storage_error err = error (Storage_error err) + +(* Initialization *********************************************************) + +(* This key should always be populated for every version of the + protocol. It's absence meaning that the context is empty. *) +let version_key = ["version"] + +(* This value is set by the snapshot_alpha.sh script, don't change it. *) +let version_value = "ithaca_012" + +let version = "v1" + +let cycle_eras_key = [version; "cycle_eras"] + +let constants_key = [version; "constants"] + +let protocol_param_key = ["protocol_parameters"] + +let get_cycle_eras ctxt = + Context.find ctxt cycle_eras_key >|= function + | None -> storage_error (Missing_key (cycle_eras_key, Get)) + | Some bytes -> ( + match + Data_encoding.Binary.of_bytes_opt Level_repr.cycle_eras_encoding bytes + with + | None -> storage_error (Corrupted_data cycle_eras_key) + | Some cycle_eras -> ok cycle_eras) + +let set_cycle_eras ctxt cycle_eras = + let bytes = + Data_encoding.Binary.to_bytes_exn Level_repr.cycle_eras_encoding cycle_eras + in + Context.add ctxt cycle_eras_key bytes >|= ok + +type error += Failed_to_parse_parameter of bytes + +type error += Failed_to_decode_parameter of Data_encoding.json * string + +let () = + register_error_kind + `Temporary + ~id:"context.failed_to_parse_parameter" + ~title:"Failed to parse parameter" + ~description:"The protocol parameters are not valid JSON." + ~pp:(fun ppf bytes -> + Format.fprintf + ppf + "@[Cannot parse the protocol parameter:@ %s@]" + (Bytes.to_string bytes)) + Data_encoding.(obj1 (req "contents" bytes)) + (function Failed_to_parse_parameter data -> Some data | _ -> None) + (fun data -> Failed_to_parse_parameter data) ; + register_error_kind + `Temporary + ~id:"context.failed_to_decode_parameter" + ~title:"Failed to decode parameter" + ~description:"Unexpected JSON object." + ~pp:(fun ppf (json, msg) -> + Format.fprintf + ppf + "@[Cannot decode the protocol parameter:@ %s@ %a@]" + msg + Data_encoding.Json.pp + json) + Data_encoding.(obj2 (req "contents" json) (req "error" string)) + (function + | Failed_to_decode_parameter (json, msg) -> Some (json, msg) | _ -> None) + (fun (json, msg) -> Failed_to_decode_parameter (json, msg)) + +let get_proto_param ctxt = + Context.find ctxt protocol_param_key >>= function + | None -> failwith "Missing protocol parameters." + | Some bytes -> ( + match Data_encoding.Binary.of_bytes_opt Data_encoding.json bytes with + | None -> fail (Failed_to_parse_parameter bytes) + | Some json -> ( + Context.remove ctxt protocol_param_key >|= fun ctxt -> + match Data_encoding.Json.destruct Parameters_repr.encoding json with + | exception (Data_encoding.Json.Cannot_destruct _ as exn) -> + Format.kasprintf + failwith + "Invalid protocol_parameters: %a %a" + (fun ppf -> Data_encoding.Json.print_error ppf) + exn + Data_encoding.Json.pp + json + | param -> + Parameters_repr.check_params param >>? fun () -> ok (param, ctxt)) + ) + +let add_constants ctxt constants = + let bytes = + Data_encoding.Binary.to_bytes_exn + Constants_repr.parametric_encoding + constants + in + Context.add ctxt constants_key bytes + +let get_constants ctxt = + Context.find ctxt constants_key >|= function + | None -> failwith "Internal error: cannot read constants in context." + | Some bytes -> ( + match + Data_encoding.Binary.of_bytes_opt + Constants_repr.parametric_encoding + bytes + with + | None -> failwith "Internal error: cannot parse constants in context." + | Some constants -> ok constants) + +let patch_constants ctxt f = + let constants = f (constants ctxt) in + add_constants (context ctxt) constants >|= fun context -> + let ctxt = update_context ctxt context in + update_constants ctxt constants + +let check_inited ctxt = + Context.find ctxt version_key >|= function + | None -> failwith "Internal error: un-initialized context." + | Some bytes -> + let s = Bytes.to_string bytes in + if Compare.String.(s = version_value) then Result.return_unit + else storage_error (Incompatible_protocol_version s) + +let check_cycle_eras (cycle_eras : Level_repr.cycle_eras) + (constants : Constants_repr.parametric) = + let current_era = Level_repr.current_era cycle_eras in + assert ( + Compare.Int32.(current_era.blocks_per_cycle = constants.blocks_per_cycle)) ; + assert ( + Compare.Int32.( + current_era.blocks_per_commitment = constants.blocks_per_commitment)) + +let prepare ~level ~predecessor_timestamp ~timestamp ctxt = + Raw_level_repr.of_int32 level >>?= fun level -> + check_inited ctxt >>=? fun () -> + get_constants ctxt >>=? fun constants -> + Round_repr.Durations.create + ~first_round_duration:constants.minimal_block_delay + ~delay_increment_per_round:constants.delay_increment_per_round + >>?= fun round_durations -> + get_cycle_eras ctxt >|=? fun cycle_eras -> + check_cycle_eras cycle_eras constants ; + let level = Level_repr.from_raw ~cycle_eras level in + { + remaining_operation_gas = Gas_limit_repr.Arith.zero; + back = + { + context = ctxt; + constants; + level; + predecessor_timestamp; + timestamp; + round_durations; + cycle_eras; + fees = Tez_repr.zero; + origination_nonce = None; + temporary_lazy_storage_ids = Lazy_storage_kind.Temp_ids.init; + internal_nonce = 0; + internal_nonces_used = Int_set.empty; + remaining_block_gas = + Gas_limit_repr.Arith.fp + constants.Constants_repr.hard_gas_limit_per_block; + unlimited_operation_gas = true; + consensus = Raw_consensus.empty; + non_consensus_operations = []; + sampler_state = Cycle_repr.Map.empty; + stake_distribution_for_current_cycle = None; + }; + } + +type previous_protocol = Genesis of Parameters_repr.t | Hangzhou_011 + +let check_and_update_protocol_version ctxt = + (Context.find ctxt version_key >>= function + | None -> + failwith "Internal error: un-initialized context in check_first_block." + | Some bytes -> + let s = Bytes.to_string bytes in + if Compare.String.(s = version_value) then + failwith "Internal error: previously initialized context." + else if Compare.String.(s = "genesis") then + get_proto_param ctxt >|=? fun (param, ctxt) -> (Genesis param, ctxt) + else if Compare.String.(s = "hangzhou_011") then + return (Hangzhou_011, ctxt) + else Lwt.return @@ storage_error (Incompatible_protocol_version s)) + >>=? fun (previous_proto, ctxt) -> + Context.add ctxt version_key (Bytes.of_string version_value) >|= fun ctxt -> + ok (previous_proto, ctxt) + +(* only for the migration *) +let[@warning "-32"] get_previous_protocol_constants ctxt = + Context.find ctxt constants_key >>= function + | None -> + failwith + "Internal error: cannot read previous protocol constants in context." + | Some bytes -> ( + match + Data_encoding.Binary.of_bytes_opt + Constants_repr.Proto_previous.parametric_encoding + bytes + with + | None -> + failwith + "Internal error: cannot parse previous protocol constants in \ + context." + | Some constants -> Lwt.return constants) + +(* You should ensure that if the type `Constant_repr.parametric` is + different from the previous protocol or the value of these + constants is modified, is changed from the previous protocol, then + you `propagate` these constants to the new protocol by writing them + onto the context via the function `add_constants` or + `patch_constants`. + + This migration can be achieved also implicitly by modifying the + encoding directly in a way which is compatible with the previous + protocol. However, by doing so, you do not change the value of + these constants inside the context. *) +let prepare_first_block ~level ~timestamp ctxt = + check_and_update_protocol_version ctxt >>=? fun (previous_proto, ctxt) -> + (match previous_proto with + | Genesis param -> + Raw_level_repr.of_int32 level >>?= fun first_level -> + let cycle_era = + { + Level_repr.first_level; + first_cycle = Cycle_repr.root; + blocks_per_cycle = param.constants.blocks_per_cycle; + blocks_per_commitment = param.constants.blocks_per_commitment; + } + in + Level_repr.create_cycle_eras [cycle_era] >>?= fun cycle_eras -> + set_cycle_eras ctxt cycle_eras >>=? fun ctxt -> + add_constants ctxt param.constants >|= ok + | Hangzhou_011 -> + get_previous_protocol_constants ctxt >>= fun c -> + let minimal_block_delay = c.minimal_block_delay in + let minimal_block_delay_s = Period_repr.to_seconds minimal_block_delay in + (if Compare.Int64.(minimal_block_delay_s = 30L) then + (* that's the mainnet value of the constant; so we're + probably on the mainnet: do no inherit this constant's + value (as done in the else case below) *) + Period_repr.of_seconds 15L + else + match c.time_between_blocks with + | first_time_between_blocks :: _ -> + let delay_increment_per_round_s = + let m = + Int64.sub + (Period_repr.to_seconds first_time_between_blocks) + minimal_block_delay_s + in + if Compare.Int64.(m < 1L) then 1L else m + in + Period_repr.of_seconds delay_increment_per_round_s + | [] -> ok minimal_block_delay) + >>?= fun delay_increment_per_round -> + let constants = + let consensus_committee_size = 7000 in + let Constants_repr.Generated. + { + consensus_threshold; + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + } = + Constants_repr.Generated.generate + ~consensus_committee_size + ~blocks_per_minute: + {numerator = 60; denominator = Int64.to_int minimal_block_delay_s} + in + Constants_repr. + { + preserved_cycles = c.preserved_cycles; + blocks_per_cycle = c.blocks_per_cycle; + blocks_per_commitment = c.blocks_per_commitment; + blocks_per_stake_snapshot = c.blocks_per_roll_snapshot; + blocks_per_voting_period = c.blocks_per_voting_period; + hard_gas_limit_per_operation = c.hard_gas_limit_per_operation; + hard_gas_limit_per_block = c.hard_gas_limit_per_block; + proof_of_work_threshold = c.proof_of_work_threshold; + tokens_per_roll = + (* NB: the old value is used during the migration, and + changed to a new value there *) + c.tokens_per_roll; + seed_nonce_revelation_tip = c.seed_nonce_revelation_tip; + origination_size = c.origination_size; + (* Same value as in the previous protocol. *) + max_operations_time_to_live = 120; + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + cost_per_byte = c.cost_per_byte; + hard_storage_limit_per_operation = + c.hard_storage_limit_per_operation; + quorum_min = c.quorum_min; + quorum_max = c.quorum_max; + min_proposal_quorum = c.min_proposal_quorum; + liquidity_baking_subsidy = c.liquidity_baking_subsidy; + liquidity_baking_sunset_level = + (* preserve a lower level for testnets *) + (if Compare.Int32.(c.liquidity_baking_sunset_level = 2_244_609l) + then 3_063_809l + else c.liquidity_baking_sunset_level); + liquidity_baking_escape_ema_threshold = 666_667l; + minimal_block_delay; + delay_increment_per_round; + consensus_committee_size; + consensus_threshold; + minimal_participation_ratio = {numerator = 2; denominator = 3}; + max_slashing_period = 2; + frozen_deposits_percentage = 10; + double_baking_punishment = Tez_repr.(mul_exn one 640); + ratio_of_frozen_deposits_slashed_per_double_endorsement = + {numerator = 1; denominator = 2}; + delegate_selection = Random; + } + in + add_constants ctxt constants >>= fun ctxt -> return ctxt) + >>=? fun ctxt -> + prepare ctxt ~level ~predecessor_timestamp:timestamp ~timestamp + >|=? fun ctxt -> (previous_proto, ctxt) + +let activate ctxt h = Updater.activate (context ctxt) h >|= update_context ctxt + +(* Generic context ********************************************************) + +type key = string list + +type value = bytes + +type tree = Context.tree + +module type T = + Raw_context_intf.T + with type root := root + and type key := key + and type value := value + and type tree := tree + +let mem ctxt k = Context.mem (context ctxt) k + +let mem_tree ctxt k = Context.mem_tree (context ctxt) k + +let get ctxt k = + Context.find (context ctxt) k >|= function + | None -> storage_error (Missing_key (k, Get)) + | Some v -> ok v + +let get_tree ctxt k = + Context.find_tree (context ctxt) k >|= function + | None -> storage_error (Missing_key (k, Get)) + | Some v -> ok v + +let find ctxt k = Context.find (context ctxt) k + +let find_tree ctxt k = Context.find_tree (context ctxt) k + +let add ctxt k v = Context.add (context ctxt) k v >|= update_context ctxt + +let add_tree ctxt k v = + Context.add_tree (context ctxt) k v >|= update_context ctxt + +let init ctxt k v = + Context.mem (context ctxt) k >>= function + | true -> Lwt.return @@ storage_error (Existing_key k) + | _ -> + Context.add (context ctxt) k v >|= fun context -> + ok (update_context ctxt context) + +let init_tree ctxt k v : _ tzresult Lwt.t = + Context.mem_tree (context ctxt) k >>= function + | true -> Lwt.return @@ storage_error (Existing_key k) + | _ -> + Context.add_tree (context ctxt) k v >|= fun context -> + ok (update_context ctxt context) + +let update ctxt k v = + Context.mem (context ctxt) k >>= function + | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) + | _ -> + Context.add (context ctxt) k v >|= fun context -> + ok (update_context ctxt context) + +let update_tree ctxt k v = + Context.mem_tree (context ctxt) k >>= function + | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) + | _ -> + Context.add_tree (context ctxt) k v >|= fun context -> + ok (update_context ctxt context) + +(* Verify that the key is present before deleting *) +let remove_existing ctxt k = + Context.mem (context ctxt) k >>= function + | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) + | _ -> + Context.remove (context ctxt) k >|= fun context -> + ok (update_context ctxt context) + +(* Verify that the key is present before deleting *) +let remove_existing_tree ctxt k = + Context.mem_tree (context ctxt) k >>= function + | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) + | _ -> + Context.remove (context ctxt) k >|= fun context -> + ok (update_context ctxt context) + +(* Do not verify before deleting *) +let remove ctxt k = Context.remove (context ctxt) k >|= update_context ctxt + +let add_or_remove ctxt k = function + | None -> remove ctxt k + | Some v -> add ctxt k v + +let add_or_remove_tree ctxt k = function + | None -> remove ctxt k + | Some v -> add_tree ctxt k v + +let list ctxt ?offset ?length k = Context.list (context ctxt) ?offset ?length k + +let fold ?depth ctxt k ~order ~init ~f = + Context.fold ?depth (context ctxt) k ~order ~init ~f + +module Tree : + Raw_context_intf.TREE + with type t := t + and type key := key + and type value := value + and type tree := tree = struct + include Context.Tree + + let empty ctxt = Context.Tree.empty (context ctxt) + + let get t k = + find t k >|= function + | None -> storage_error (Missing_key (k, Get)) + | Some v -> ok v + + let get_tree t k = + find_tree t k >|= function + | None -> storage_error (Missing_key (k, Get)) + | Some v -> ok v + + let init t k v = + mem t k >>= function + | true -> Lwt.return @@ storage_error (Existing_key k) + | _ -> add t k v >|= ok + + let init_tree t k v = + mem_tree t k >>= function + | true -> Lwt.return @@ storage_error (Existing_key k) + | _ -> add_tree t k v >|= ok + + let update t k v = + mem t k >>= function + | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) + | _ -> add t k v >|= ok + + let update_tree t k v = + mem_tree t k >>= function + | false -> Lwt.return @@ storage_error (Missing_key (k, Set)) + | _ -> add_tree t k v >|= ok + + (* Verify that the key is present before deleting *) + let remove_existing t k = + mem t k >>= function + | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) + | _ -> remove t k >|= ok + + (* Verify that the key is present before deleting *) + let remove_existing_tree t k = + mem_tree t k >>= function + | false -> Lwt.return @@ storage_error (Missing_key (k, Del)) + | _ -> remove t k >|= ok + + let add_or_remove t k = function None -> remove t k | Some v -> add t k v + + let add_or_remove_tree t k = function + | None -> remove t k + | Some v -> add_tree t k v +end + +let project x = x + +let absolute_key _ k = k + +let description = Storage_description.create () + +let fold_map_temporary_lazy_storage_ids ctxt f = + f (temporary_lazy_storage_ids ctxt) |> fun (temporary_lazy_storage_ids, x) -> + (update_temporary_lazy_storage_ids ctxt temporary_lazy_storage_ids, x) + +let map_temporary_lazy_storage_ids_s ctxt f = + f (temporary_lazy_storage_ids ctxt) + >|= fun (ctxt, temporary_lazy_storage_ids) -> + update_temporary_lazy_storage_ids ctxt temporary_lazy_storage_ids + +module Cache = struct + type key = Context.Cache.key + + type value = Context.Cache.value = .. + + let key_of_identifier = Context.Cache.key_of_identifier + + let identifier_of_key = Context.Cache.identifier_of_key + + let pp fmt ctxt = Context.Cache.pp fmt (context ctxt) + + let find c k = Context.Cache.find (context c) k + + let set_cache_layout c layout = + Context.Cache.set_cache_layout (context c) layout >>= fun ctxt -> + Lwt.return (update_context c ctxt) + + let update c k v = Context.Cache.update (context c) k v |> update_context c + + let sync c ~cache_nonce = + Context.Cache.sync (context c) ~cache_nonce >>= fun ctxt -> + Lwt.return (update_context c ctxt) + + let clear c = Context.Cache.clear (context c) |> update_context c + + let list_keys c ~cache_index = + Context.Cache.list_keys (context c) ~cache_index + + let key_rank c key = Context.Cache.key_rank (context c) key + + let cache_size_limit c ~cache_index = + Context.Cache.cache_size_limit (context c) ~cache_index + + let cache_size c ~cache_index = + Context.Cache.cache_size (context c) ~cache_index + + let future_cache_expectation c ~time_in_blocks = + Context.Cache.future_cache_expectation (context c) ~time_in_blocks + |> update_context c +end + +let record_non_consensus_operation_hash ctxt operation_hash = + update_non_consensus_operations + ctxt + (operation_hash :: non_consensus_operations ctxt) + +let non_consensus_operations ctxt = List.rev (non_consensus_operations ctxt) + +let set_sampler_for_cycle ctxt cycle sampler_with_seed = + let map = sampler_state ctxt in + if Cycle_repr.Map.mem cycle map then Error `Sampler_already_set + else + let map = Cycle_repr.Map.add cycle sampler_with_seed map in + Ok (update_sampler_state ctxt map) + +let sampler_for_cycle ctxt cycle = + let map = sampler_state ctxt in + match Cycle_repr.Map.find cycle map with + | None -> Error `Sampler_not_set + | Some sampler -> Ok sampler + +let stake_distribution_for_current_cycle ctxt = + match ctxt.back.stake_distribution_for_current_cycle with + | None -> error Stake_distribution_not_set + | Some s -> ok s + +let init_stake_distribution_for_current_cycle ctxt + stake_distribution_for_current_cycle = + update_back + ctxt + { + ctxt.back with + stake_distribution_for_current_cycle = + Some stake_distribution_for_current_cycle; + } + +module type CONSENSUS = sig + type t + + type 'value slot_map + + type slot_set + + type slot + + type round + + val allowed_endorsements : + t -> (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map + + val allowed_preendorsements : + t -> (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map + + val current_endorsement_power : t -> int + + val initialize_consensus_operation : + t -> + allowed_endorsements: + (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map -> + allowed_preendorsements: + (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map -> + t + + val record_grand_parent_endorsement : + t -> Signature.Public_key_hash.t -> t tzresult + + val record_endorsement : t -> initial_slot:slot -> power:int -> t tzresult + + val record_preendorsement : + t -> initial_slot:slot -> power:int -> round -> t tzresult + + val endorsements_seen : t -> slot_set + + val get_preendorsements_quorum_round : t -> round option + + val set_preendorsements_quorum_round : t -> round -> t + + val locked_round_evidence : t -> (round * int) option + + val set_endorsement_branch : t -> Block_hash.t * Block_payload_hash.t -> t + + val endorsement_branch : t -> (Block_hash.t * Block_payload_hash.t) option + + val set_grand_parent_branch : t -> Block_hash.t * Block_payload_hash.t -> t + + val grand_parent_branch : t -> (Block_hash.t * Block_payload_hash.t) option +end + +module Consensus : + CONSENSUS + with type t := t + and type slot := Slot_repr.t + and type 'a slot_map := 'a Slot_repr.Map.t + and type slot_set := Slot_repr.Set.t + and type round := Round_repr.t = struct + let[@inline] allowed_endorsements ctxt = + ctxt.back.consensus.allowed_endorsements + + let[@inline] allowed_preendorsements ctxt = + ctxt.back.consensus.allowed_preendorsements + + let[@inline] current_endorsement_power ctxt = + ctxt.back.consensus.current_endorsement_power + + let[@inline] get_preendorsements_quorum_round ctxt = + ctxt.back.consensus.preendorsements_quorum_round + + let[@inline] locked_round_evidence ctxt = + Raw_consensus.locked_round_evidence ctxt.back.consensus + + let[@inline] update_consensus_with ctxt f = + {ctxt with back = {ctxt.back with consensus = f ctxt.back.consensus}} + + let[@inline] update_consensus_with_tzresult ctxt f = + f ctxt.back.consensus >|? fun consensus -> + {ctxt with back = {ctxt.back with consensus}} + + let[@inline] initialize_consensus_operation ctxt ~allowed_endorsements + ~allowed_preendorsements = + update_consensus_with + ctxt + (Raw_consensus.initialize_with_endorsements_and_preendorsements + ~allowed_endorsements + ~allowed_preendorsements) + + let[@inline] record_grand_parent_endorsement ctxt pkh = + update_consensus_with_tzresult ctxt (fun ctxt -> + Raw_consensus.record_grand_parent_endorsement ctxt pkh) + + let[@inline] record_preendorsement ctxt ~initial_slot ~power round = + update_consensus_with_tzresult + ctxt + (Raw_consensus.record_preendorsement ~initial_slot ~power round) + + let[@inline] record_endorsement ctxt ~initial_slot ~power = + update_consensus_with_tzresult + ctxt + (Raw_consensus.record_endorsement ~initial_slot ~power) + + let[@inline] endorsements_seen ctxt = ctxt.back.consensus.endorsements_seen + + let[@inline] set_preendorsements_quorum_round ctxt round = + update_consensus_with + ctxt + (Raw_consensus.set_preendorsements_quorum_round round) + + let[@inline] endorsement_branch ctxt = + Raw_consensus.endorsement_branch ctxt.back.consensus + + let[@inline] set_endorsement_branch ctxt branch = + update_consensus_with ctxt (fun ctxt -> + Raw_consensus.set_endorsement_branch ctxt branch) + + let[@inline] grand_parent_branch ctxt = + Raw_consensus.grand_parent_branch ctxt.back.consensus + + let[@inline] set_grand_parent_branch ctxt branch = + update_consensus_with ctxt (fun ctxt -> + Raw_consensus.set_grand_parent_branch ctxt branch) +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/raw_context.mli b/src/proto_012_PsiThaCa/lib_protocol/raw_context.mli new file mode 100644 index 000000000000..e4a30b69ca51 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/raw_context.mli @@ -0,0 +1,320 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** {1 Errors} *) + +type error += Too_many_internal_operations (* `Permanent *) + +type missing_key_kind = Get | Set | Del | Copy + +(** An internal storage error that should not happen *) +type storage_error = + | Incompatible_protocol_version of string + | Missing_key of string list * missing_key_kind + | Existing_key of string list + | Corrupted_data of string list + +type error += Storage_error of storage_error + +type error += Failed_to_parse_parameter of bytes + +type error += Failed_to_decode_parameter of Data_encoding.json * string + +val storage_error : storage_error -> 'a tzresult + +(** {1 Abstract Context} *) + +(** Abstract view of the context. + Includes a handle to the functional key-value database + ({!Context.t}) along with some in-memory values (gas, etc.). *) +type t + +type root = t + +(** Retrieves the state of the database and gives its abstract view. + It also returns wether this is the first block validated + with this version of the protocol. *) +val prepare : + level:Int32.t -> + predecessor_timestamp:Time.t -> + timestamp:Time.t -> + Context.t -> + t tzresult Lwt.t + +type previous_protocol = Genesis of Parameters_repr.t | Hangzhou_011 + +val prepare_first_block : + level:int32 -> + timestamp:Time.t -> + Context.t -> + (previous_protocol * t) tzresult Lwt.t + +val activate : t -> Protocol_hash.t -> t Lwt.t + +(** Returns the state of the database resulting of operations on its + abstract view *) +val recover : t -> Context.t + +val current_level : t -> Level_repr.t + +val predecessor_timestamp : t -> Time.t + +val current_timestamp : t -> Time.t + +val constants : t -> Constants_repr.parametric + +val patch_constants : + t -> (Constants_repr.parametric -> Constants_repr.parametric) -> t Lwt.t + +val round_durations : t -> Round_repr.Durations.t + +(** Retrieve the cycle eras. *) +val cycle_eras : t -> Level_repr.cycle_eras + +(** Increment the current block fee stash that will be credited to the payload + producer's account at finalize_application *) +val credit_collected_fees_only_call_from_token : t -> Tez_repr.t -> t tzresult + +(** Decrement the current block fee stash that will be credited to the payload + producer's account at finalize_application *) +val spend_collected_fees_only_call_from_token : t -> Tez_repr.t -> t tzresult + +(** Returns the current block fee stash that will be credited to the payload + producer's account at finalize_application *) +val get_collected_fees : t -> Tez_repr.t + +type error += Gas_limit_too_high (* `Permanent *) + +val check_gas_limit_is_valid : t -> 'a Gas_limit_repr.Arith.t -> unit tzresult + +val consume_gas_limit_in_block : t -> 'a Gas_limit_repr.Arith.t -> t tzresult + +val set_gas_limit : t -> 'a Gas_limit_repr.Arith.t -> t + +val set_gas_unlimited : t -> t + +val gas_level : t -> Gas_limit_repr.t + +val gas_consumed : since:t -> until:t -> Gas_limit_repr.Arith.fp + +val remaining_operation_gas : t -> Gas_limit_repr.Arith.fp + +val update_remaining_operation_gas : t -> Gas_limit_repr.Arith.fp -> t + +val block_gas_level : t -> Gas_limit_repr.Arith.fp + +val update_remaining_block_gas : t -> Gas_limit_repr.Arith.fp -> t + +type error += Undefined_operation_nonce (* `Permanent *) + +val init_origination_nonce : t -> Operation_hash.t -> t + +val get_origination_nonce : t -> Contract_repr.origination_nonce tzresult + +val increment_origination_nonce : + t -> (t * Contract_repr.origination_nonce) tzresult + +val unset_origination_nonce : t -> t + +(** {1 Generic accessors} *) + +type key = string list + +type value = bytes + +type tree + +module type T = + Raw_context_intf.T + with type root := root + and type key := key + and type value := value + and type tree := tree + +include T with type t := t + +(** Initialize the local nonce used for preventing a script to + duplicate an internal operation to replay it. *) +val reset_internal_nonce : t -> t + +(** Increments the internal operation nonce. *) +val fresh_internal_nonce : t -> (t * int) tzresult + +(** Mark an internal operation nonce as taken. *) +val record_internal_nonce : t -> int -> t + +(** Check is the internal operation nonce has been taken. *) +val internal_nonce_already_recorded : t -> int -> bool + +val fold_map_temporary_lazy_storage_ids : + t -> + (Lazy_storage_kind.Temp_ids.t -> Lazy_storage_kind.Temp_ids.t * 'res) -> + t * 'res + +val map_temporary_lazy_storage_ids_s : + t -> + (Lazy_storage_kind.Temp_ids.t -> (t * Lazy_storage_kind.Temp_ids.t) Lwt.t) -> + t Lwt.t + +module Cache : + Context.CACHE + with type t := t + and type size := int + and type index := int + and type identifier := string + and type key = Context.Cache.key + and type value = Context.Cache.value + +(* Hashes of non-consensus operations are stored so that, when + finalizing the block, we can compute the block's payload hash. *) +val record_non_consensus_operation_hash : t -> Operation_hash.t -> t + +val non_consensus_operations : t -> Operation_hash.t list + +(** [set_sampler_for_cycle ctxt cycle sampler] evaluates to + [Ok c] with [c] verifying [sampler_for_cycle c cycle = sampler] + if no sampler was set for the same [cycle] beforehand. + In the other case, it returns [Error `Sampler_already_set]. *) +val set_sampler_for_cycle : + t -> + Cycle_repr.t -> + Seed_repr.seed * (Signature.public_key * Signature.public_key_hash) Sampler.t -> + (t, [`Sampler_already_set]) result + +(** [sampler_for_cycle ctxt cycle] evaluates to [Ok sampler] if a sampler was + set for [cycle] using [set_sampler_for_cycle]. + Otherwise, it returns [Error `Sampler_not_set]. *) +val sampler_for_cycle : + t -> + Cycle_repr.t -> + ( Seed_repr.seed * (Signature.public_key * Signature.public_key_hash) Sampler.t, + [`Sampler_not_set] ) + result + +(* The stake distribution is stored both in [t] and in the cache. It + may be sufficient to only store it in the cache. *) +val stake_distribution_for_current_cycle : + t -> Tez_repr.t Signature.Public_key_hash.Map.t tzresult + +val init_stake_distribution_for_current_cycle : + t -> Tez_repr.t Signature.Public_key_hash.Map.t -> t + +module type CONSENSUS = sig + type t + + type 'value slot_map + + type slot_set + + type slot + + type round + + (** Returns a map where each endorser's pkh is associated to the + list of its endorsing slots (in decreasing order) for a given + level. *) + val allowed_endorsements : + t -> (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map + + (** Returns a map where each endorser's pkh is associated to the + list of its endorsing slots (in decreasing order) for a given + level. *) + val allowed_preendorsements : + t -> (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map + + (** [endorsement power ctx] returns the endorsement power of the + current block. *) + val current_endorsement_power : t -> int + + (** Initializes the map of allowed endorsements and preendorsements, + this function must be called only once and before applying + any consensus operation. *) + val initialize_consensus_operation : + t -> + allowed_endorsements: + (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map -> + allowed_preendorsements: + (Signature.Public_key.t * Signature.Public_key_hash.t * int) slot_map -> + t + + (** [record_grand_parent_endorsement ctx pkh] records an + grand_parent_endorsement for the current block. This is only + useful for the partial construction mode. *) + val record_grand_parent_endorsement : + t -> Signature.Public_key_hash.t -> t tzresult + + (** [record_endorsement ctx ~initial_slot ~power] records an + endorsement for the current block. + + The endorsement should be valid in the sense that + [Int_map.find_opt initial_slot allowed_endorsement ctx = Some + (pkh, power)]. *) + val record_endorsement : t -> initial_slot:slot -> power:int -> t tzresult + + (** [record_preendorsement ctx ~initial_slot ~power round + payload_hash power] records a preendorsement for a proposal at + [round] with payload [payload_hash]. + + The preendorsement should be valid in the sense that + [Int_map.find_opt initial_slot allowed_preendorsement ctx = Some + (pkh, power)]. *) + val record_preendorsement : + t -> initial_slot:slot -> power:int -> round -> t tzresult + + val endorsements_seen : t -> slot_set + + (** [get_preendorsements_quorum_round ctx] returns [None] if no + preendorsement are included in the current block. Otherwise, + return [Some r] where [r] is the round of the preendorsements + included in the block. *) + val get_preendorsements_quorum_round : t -> round option + + (** [set_preendorsements_quorum_round ctx round] sets the round for + preendorsements included in this block. This function should be + called only once. + + This function is only used in [Full_construction] mode. *) + val set_preendorsements_quorum_round : t -> round -> t + + (** [locked_round_evidence ctx] returns the round of the recorded + preendorsements as well as their power. *) + val locked_round_evidence : t -> (round * int) option + + val set_endorsement_branch : t -> Block_hash.t * Block_payload_hash.t -> t + + val endorsement_branch : t -> (Block_hash.t * Block_payload_hash.t) option + + val set_grand_parent_branch : t -> Block_hash.t * Block_payload_hash.t -> t + + val grand_parent_branch : t -> (Block_hash.t * Block_payload_hash.t) option +end + +module Consensus : + CONSENSUS + with type t := t + and type slot := Slot_repr.t + and type 'a slot_map := 'a Slot_repr.Map.t + and type slot_set := Slot_repr.Set.t + and type round := Round_repr.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/raw_context_intf.ml b/src/proto_012_PsiThaCa/lib_protocol/raw_context_intf.ml new file mode 100644 index 000000000000..dc1817f0a2d6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/raw_context_intf.ml @@ -0,0 +1,260 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2018-2021 Tarides *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** All context manipulation functions. This signature is included + as-is for direct context accesses, and used in {!Storage_functors} + to provide restricted views to the context. *) + +module type VIEW = sig + (* Same as [Environment_context.VIEW] but with extra getters and + setters functions. *) + + (** The type for context handler. *) + type t + + (** The type for context trees. *) + type tree + + (** The type for context keys. *) + type key = string list + + (** The type for context values. *) + type value = bytes + + (** {2 Getters} *) + + (** [mem t k] is an Lwt promise that resolves to [true] iff [k] is bound + to a value in [t]. *) + val mem : t -> key -> bool Lwt.t + + (** [mem_tree t k] is like {!mem} but for trees. *) + val mem_tree : t -> key -> bool Lwt.t + + (** [get t k] is an Lwt promise that resolves to [Ok v] if [k] is + bound to the value [v] in [t] and {!Storage_Error Missing_key} + otherwise. *) + val get : t -> key -> value tzresult Lwt.t + + (** [get_tree] is like {!get} but for trees. *) + val get_tree : t -> key -> tree tzresult Lwt.t + + (** [find t k] is an Lwt promise that resolves to [Some v] if [k] is + bound to the value [v] in [t] and [None] otherwise. *) + val find : t -> key -> value option Lwt.t + + (** [find_tree t k] is like {!find} but for trees. *) + val find_tree : t -> key -> tree option Lwt.t + + (** [list t key] is the list of files and sub-nodes stored under [k] in [t]. + The result order is not specified but is stable. + + [offset] and [length] are used for pagination. *) + val list : + t -> ?offset:int -> ?length:int -> key -> (string * tree) list Lwt.t + + (** {2 Setters} *) + + (** [init t k v] is an Lwt promise that resolves to [Ok c] if: + + - [k] is unbound in [t]; + - [k] is bound to [v] in [c]; + - and [c] is similar to [t] otherwise. + + It is {!Storage_error Existing_key} if [k] is already bound in [t]. *) + val init : t -> key -> value -> t tzresult Lwt.t + + (** [init_tree] is like {!init} but for trees. *) + val init_tree : t -> key -> tree -> t tzresult Lwt.t + + (** [update t k v] is an Lwt promise that resolves to [Ok c] if: + + - [k] is bound in [t]; + - [k] is bound to [v] in [c]; + - and [c] is similar to [t] otherwise. + + It is {!Storage_error Missing_key} if [k] is not already bound in [t]. *) + val update : t -> key -> value -> t tzresult Lwt.t + + (** [update_tree] is like {!update} but for trees. *) + val update_tree : t -> key -> tree -> t tzresult Lwt.t + + (** [add t k v] is an Lwt promise that resolves to [c] such that: + + - [k] is bound to [v] in [c]; + - and [c] is similar to [t] otherwise. + + If [k] was already bound in [t] to a value that is physically equal + to [v], the result of the function is a promise that resolves to + [t]. Otherwise, the previous binding of [k] in [t] disappears. *) + val add : t -> key -> value -> t Lwt.t + + (** [add_tree] is like {!add} but for trees. *) + val add_tree : t -> key -> tree -> t Lwt.t + + (** [remove t k v] is an Lwt promise that resolves to [c] such that: + + - [k] is unbound in [c]; + - and [c] is similar to [t] otherwise. *) + val remove : t -> key -> t Lwt.t + + (** [remove_existing t k v] is an Lwt promise that resolves to [Ok c] if: + + - [k] is bound in [t] to a value; + - [k] is unbound in [c]; + - and [c] is similar to [t] otherwise.*) + val remove_existing : t -> key -> t tzresult Lwt.t + + (** [remove_existing_tree t k v] is an Lwt promise that reolves to [Ok c] if: + + - [k] is bound in [t] to a tree; + - [k] is unbound in [c]; + - and [c] is similar to [t] otherwise.*) + val remove_existing_tree : t -> key -> t tzresult Lwt.t + + (** [add_or_remove t k v] is: + + - [add t k x] if [v] is [Some x]; + - [remove t k] otherwise. *) + val add_or_remove : t -> key -> value option -> t Lwt.t + + (** [add_or_remove_tree t k v] is: + + - [add_tree t k x] if [v] is [Some x]; + - [remove t k] otherwise. *) + val add_or_remove_tree : t -> key -> tree option -> t Lwt.t + + (** {2 Folds} *) + + (** [fold ?depth t root ~init ~f] recursively folds over the trees + and values of [t]. The [f] callbacks are called with a key relative + to [root]. [f] is never called with an empty key for values; i.e., + folding over a value is a no-op. + + Elements are traversed in lexical order of keys. + + The depth is 0-indexed. If [depth] is set (by default it is not), then [f] + is only called when the conditions described by the parameter is true: + + - [Eq d] folds over nodes and contents of depth exactly [d]. + - [Lt d] folds over nodes and contents of depth strictly less than [d]. + - [Le d] folds over nodes and contents of depth less than or equal to [d]. + - [Gt d] folds over nodes and contents of depth strictly more than [d]. + - [Ge d] folds over nodes and contents of depth more than or equal to [d]. *) + val fold : + ?depth:[`Eq of int | `Le of int | `Lt of int | `Ge of int | `Gt of int] -> + t -> + key -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(key -> tree -> 'a -> 'a Lwt.t) -> + 'a Lwt.t +end + +module type TREE = sig + (** [Tree] provides immutable, in-memory partial mirror of the + context, with lazy reads and delayed writes. The trees are Merkle + trees that carry the same hash as the part of the context they + mirror. + + Trees are immutable and non-persistent (they disappear if the + host crash), held in memory for efficiency, where reads are done + lazily and writes are done only when needed, e.g. on + [Context.commit]. If a key is modified twice, only the last + value will be written to disk on commit. *) + + (** The type for context views. *) + type t + + (** The type for context trees. *) + type tree + + include VIEW with type t := tree and type tree := tree + + (** [empty _] is the empty tree. *) + val empty : t -> tree + + (** [is_empty t] is true iff [t] is [empty _]. *) + val is_empty : tree -> bool + + (** [kind t] is [t]'s kind. It's either a tree node or a leaf + value. *) + val kind : tree -> [`Value | `Tree] + + (** [to_value t] is [Some v] is [t] is a leaf tree and [None] otherwise. *) + val to_value : tree -> value option Lwt.t + + (** [hash t] is [t]'s Merkle hash. *) + val hash : tree -> Context_hash.t + + (** [equal x y] is true iff [x] and [y] have the same Merkle hash. *) + val equal : tree -> tree -> bool + + (** {2 Caches} *) + + (** [clear ?depth t] clears all caches in the tree [t] for subtrees with a + depth higher than [depth]. If [depth] is not set, all of the subtrees are + cleared. *) + val clear : ?depth:int -> tree -> unit +end + +module type T = sig + (** The type for root contexts. *) + type root + + include VIEW + + module Tree : + TREE + with type t := t + and type key := key + and type value := value + and type tree := tree + + (** Internally used in {!Storage_functors} to escape from a view. *) + val project : t -> root + + (** Internally used in {!Storage_functors} to retrieve a full key + from partial key relative a view. *) + val absolute_key : t -> key -> key + + (** Raised if block gas quota is exhausted during gas + consumption. *) + type error += Block_quota_exceeded + + (** Raised if operation gas quota is exhausted during gas + consumption. *) + type error += Operation_quota_exceeded + + (** Internally used in {!Storage_functors} to consume gas from + within a view. May raise {!Block_quota_exceeded} or + {!Operation_quota_exceeded}. *) + val consume_gas : t -> Gas_limit_repr.cost -> t tzresult + + (** Check if consume_gas will fail *) + val check_enough_gas : t -> Gas_limit_repr.cost -> unit tzresult + + val description : t Storage_description.t +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/raw_level_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/raw_level_repr.ml new file mode 100644 index 000000000000..01f33c8e4b0c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/raw_level_repr.ml @@ -0,0 +1,108 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = int32 + +type raw_level = t + +include (Compare.Int32 : Compare.S with type t := t) + +let pp ppf level = Format.fprintf ppf "%ld" level + +let rpc_arg = + let construct raw_level = Int32.to_string raw_level in + let destruct str = + Int32.of_string_opt str |> Option.to_result ~none:"Cannot parse level" + in + RPC_arg.make + ~descr:"A level integer" + ~name:"block_level" + ~construct + ~destruct + () + +let root = 0l + +let succ = Int32.succ + +let add l i = + assert (Compare.Int.(i >= 0)) ; + Int32.add l (Int32.of_int i) + +let sub l i = + assert (Compare.Int.(i >= 0)) ; + let res = Int32.sub l (Int32.of_int i) in + if Compare.Int32.(res >= 0l) then Some res else None + +let pred l = if l = 0l then None else Some (Int32.pred l) + +let diff = Int32.sub + +let to_int32 l = l + +let of_int32_exn l = + if Compare.Int32.(l >= 0l) then l else invalid_arg "Level_repr.of_int32" + +let encoding = + Data_encoding.conv_with_guard + (fun i -> i) + (fun i -> try ok (of_int32_exn i) with Invalid_argument s -> Error s) + Data_encoding.int32 + +type error += Unexpected_level of Int32.t (* `Permanent *) + +let () = + register_error_kind + `Permanent + ~id:"unexpected_level" + ~title:"Unexpected level" + ~description:"Level must be non-negative." + ~pp:(fun ppf l -> + Format.fprintf + ppf + "The level is %s but should be non-negative." + (Int32.to_string l)) + Data_encoding.(obj1 (req "level" int32)) + (function Unexpected_level l -> Some l | _ -> None) + (fun l -> Unexpected_level l) + +let of_int32 l = + Error_monad.catch_f (fun () -> of_int32_exn l) (fun _ -> Unexpected_level l) + +module Index = struct + type t = raw_level + + let path_length = 1 + + let to_path level l = Int32.to_string level :: l + + let of_path = function [s] -> Int32.of_string_opt s | _ -> None + + let rpc_arg = rpc_arg + + let encoding = encoding + + let compare = compare +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/raw_level_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/raw_level_repr.mli new file mode 100644 index 000000000000..a10ebdaa31ea --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/raw_level_repr.mli @@ -0,0 +1,64 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** The shell's notion of a level: an integer indicating the number of blocks + since genesis: genesis is 0, all other blocks have increasing levels from + there. *) +type t + +type raw_level = t + +(** @raise Invalid_argument when the level to encode is not positive *) +val encoding : raw_level Data_encoding.t + +val rpc_arg : raw_level RPC_arg.arg + +val pp : Format.formatter -> raw_level -> unit + +include Compare.S with type t := raw_level + +val to_int32 : raw_level -> int32 + +(** @raise Invalid_argument when the level to encode is negative *) +val of_int32_exn : int32 -> raw_level + +(** Can trigger Unexpected_level error when the level to encode is negative *) +val of_int32 : int32 -> raw_level tzresult + +val diff : raw_level -> raw_level -> int32 + +val root : raw_level + +val succ : raw_level -> raw_level + +val pred : raw_level -> raw_level option + +(** [add l i] i must be positive *) +val add : raw_level -> int -> raw_level + +(** [sub l i] i must be positive *) +val sub : raw_level -> int -> raw_level option + +module Index : Storage_description.INDEX with type t = raw_level diff --git a/src/proto_012_PsiThaCa/lib_protocol/receipt_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/receipt_repr.ml new file mode 100644 index 000000000000..eeb6ab22a70c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/receipt_repr.ml @@ -0,0 +1,410 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type balance = + | Contract of Contract_repr.t + | Legacy_rewards of Signature.Public_key_hash.t * Cycle_repr.t + | Block_fees + | Legacy_deposits of Signature.Public_key_hash.t * Cycle_repr.t + | Deposits of Signature.Public_key_hash.t + | Nonce_revelation_rewards + | Double_signing_evidence_rewards + | Endorsing_rewards + | Baking_rewards + | Baking_bonuses + | Legacy_fees of Signature.Public_key_hash.t * Cycle_repr.t + | Storage_fees + | Double_signing_punishments + | Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool + | Liquidity_baking_subsidies + | Burned + | Commitments of Blinded_public_key_hash.t + | Bootstrap + | Invoice + | Initial_commitments + | Minted + +let balance_encoding = + let open Data_encoding in + def "operation_metadata.alpha.balance" + @@ union + [ + case + (Tag 0) + ~title:"Contract" + (obj2 + (req "kind" (constant "contract")) + (req "contract" Contract_repr.encoding)) + (function Contract c -> Some ((), c) | _ -> None) + (fun ((), c) -> Contract c); + case + (Tag 1) + ~title:"Legacy_rewards" + (obj4 + (req "kind" (constant "freezer")) + (req "category" (constant "legacy_rewards")) + (req "delegate" Signature.Public_key_hash.encoding) + (req "cycle" Cycle_repr.encoding)) + (function Legacy_rewards (d, l) -> Some ((), (), d, l) | _ -> None) + (fun ((), (), d, l) -> Legacy_rewards (d, l)); + case + (Tag 2) + ~title:"Block_fees" + (obj2 + (req "kind" (constant "accumulator")) + (req "category" (constant "block fees"))) + (function Block_fees -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Block_fees); + case + (Tag 3) + ~title:"Legacy_deposits" + (obj4 + (req "kind" (constant "freezer")) + (req "category" (constant "legacy_deposits")) + (req "delegate" Signature.Public_key_hash.encoding) + (req "cycle" Cycle_repr.encoding)) + (function + | Legacy_deposits (d, l) -> Some ((), (), d, l) | _ -> None) + (fun ((), (), d, l) -> Legacy_deposits (d, l)); + case + (Tag 4) + ~title:"Deposits" + (obj3 + (req "kind" (constant "freezer")) + (req "category" (constant "deposits")) + (req "delegate" Signature.Public_key_hash.encoding)) + (function Deposits d -> Some ((), (), d) | _ -> None) + (fun ((), (), d) -> Deposits d); + case + (Tag 5) + ~title:"Nonce_revelation_rewards" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "nonce revelation rewards"))) + (function Nonce_revelation_rewards -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Nonce_revelation_rewards); + case + (Tag 6) + ~title:"Double_signing_evidence_rewards" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "double signing evidence rewards"))) + (function + | Double_signing_evidence_rewards -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Double_signing_evidence_rewards); + case + (Tag 7) + ~title:"Endorsing_rewards" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "endorsing rewards"))) + (function Endorsing_rewards -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Endorsing_rewards); + case + (Tag 8) + ~title:"Baking_rewards" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "baking rewards"))) + (function Baking_rewards -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Baking_rewards); + case + (Tag 9) + ~title:"Baking_bonuses" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "baking bonuses"))) + (function Baking_bonuses -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Baking_bonuses); + case + (Tag 10) + ~title:"Legacy_fees" + (obj4 + (req "kind" (constant "freezer")) + (req "category" (constant "legacy_fees")) + (req "delegate" Signature.Public_key_hash.encoding) + (req "cycle" Cycle_repr.encoding)) + (function Legacy_fees (d, l) -> Some ((), (), d, l) | _ -> None) + (fun ((), (), d, l) -> Legacy_fees (d, l)); + case + (Tag 11) + ~title:"Storage_fees" + (obj2 + (req "kind" (constant "burned")) + (req "category" (constant "storage fees"))) + (function Storage_fees -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Storage_fees); + case + (Tag 12) + ~title:"Double_signing_punishments" + (obj2 + (req "kind" (constant "burned")) + (req "category" (constant "punishments"))) + (function Double_signing_punishments -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Double_signing_punishments); + case + (Tag 13) + ~title:"Lost_endorsing_rewards" + (obj5 + (req "kind" (constant "burned")) + (req "category" (constant "lost endorsing rewards")) + (req "delegate" Signature.Public_key_hash.encoding) + (req "participation" Data_encoding.bool) + (req "revelation" Data_encoding.bool)) + (function + | Lost_endorsing_rewards (d, p, r) -> Some ((), (), d, p, r) + | _ -> None) + (fun ((), (), d, p, r) -> Lost_endorsing_rewards (d, p, r)); + case + (Tag 14) + ~title:"Liquidity_baking_subsidies" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "subsidy"))) + (function Liquidity_baking_subsidies -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Liquidity_baking_subsidies); + case + (Tag 15) + ~title:"Burned" + (obj2 + (req "kind" (constant "burned")) + (req "category" (constant "burned"))) + (function Burned -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Burned); + case + (Tag 16) + ~title:"Commitments" + (obj3 + (req "kind" (constant "commitment")) + (req "category" (constant "commitment")) + (req "committer" Blinded_public_key_hash.encoding)) + (function Commitments bpkh -> Some ((), (), bpkh) | _ -> None) + (fun ((), (), bpkh) -> Commitments bpkh); + case + (Tag 17) + ~title:"Bootstrap" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "bootstrap"))) + (function Bootstrap -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Bootstrap); + case + (Tag 18) + ~title:"Invoice" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "invoice"))) + (function Invoice -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Invoice); + case + (Tag 19) + ~title:"Initial_commitments" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "commitment"))) + (function Initial_commitments -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Initial_commitments); + case + (Tag 20) + ~title:"Minted" + (obj2 + (req "kind" (constant "minted")) + (req "category" (constant "minted"))) + (function Minted -> Some ((), ()) | _ -> None) + (fun ((), ()) -> Minted); + ] + +let is_not_zero c = not (Compare.Int.equal c 0) + +let compare_balance ba bb = + match (ba, bb) with + | (Contract ca, Contract cb) -> Contract_repr.compare ca cb + | (Legacy_rewards (pkha, ca), Legacy_rewards (pkhb, cb)) -> + let c = Signature.Public_key_hash.compare pkha pkhb in + if is_not_zero c then c else Cycle_repr.compare ca cb + | (Legacy_deposits (pkha, ca), Legacy_deposits (pkhb, cb)) -> + let c = Signature.Public_key_hash.compare pkha pkhb in + if is_not_zero c then c else Cycle_repr.compare ca cb + | (Deposits pkha, Deposits pkhb) -> + Signature.Public_key_hash.compare pkha pkhb + | ( Lost_endorsing_rewards (pkha, pa, ra), + Lost_endorsing_rewards (pkhb, pb, rb) ) -> + let c = Signature.Public_key_hash.compare pkha pkhb in + if is_not_zero c then c + else + let c = Compare.Bool.compare pa pb in + if is_not_zero c then c else Compare.Bool.compare ra rb + | (Commitments bpkha, Commitments bpkhb) -> + Blinded_public_key_hash.compare bpkha bpkhb + | (Legacy_fees (pkha, ca), Legacy_fees (pkhb, cb)) -> + let c = Signature.Public_key_hash.compare pkha pkhb in + if is_not_zero c then c else Cycle_repr.compare ca cb + | (_, _) -> + let index b = + match b with + | Contract _ -> 0 + | Legacy_rewards _ -> 1 + | Block_fees -> 2 + | Legacy_deposits _ -> 3 + | Deposits _ -> 4 + | Nonce_revelation_rewards -> 5 + | Double_signing_evidence_rewards -> 6 + | Endorsing_rewards -> 7 + | Baking_rewards -> 8 + | Baking_bonuses -> 9 + | Legacy_fees _ -> 10 + | Storage_fees -> 11 + | Double_signing_punishments -> 12 + | Lost_endorsing_rewards _ -> 13 + | Liquidity_baking_subsidies -> 14 + | Burned -> 15 + | Commitments _ -> 16 + | Bootstrap -> 17 + | Invoice -> 18 + | Initial_commitments -> 19 + | Minted -> 20 + (* don't forget to add parameterized cases in the first part of the function *) + in + Compare.Int.compare (index ba) (index bb) + +type balance_update = Debited of Tez_repr.t | Credited of Tez_repr.t + +let balance_update_encoding = + let open Data_encoding in + def "operation_metadata.alpha.balance_update" + @@ obj1 + (req + "change" + (conv + (function + | Credited v -> Tez_repr.to_mutez v + | Debited v -> Int64.neg (Tez_repr.to_mutez v)) + ( Json.wrap_error @@ fun v -> + if Compare.Int64.(v < 0L) then + match Tez_repr.of_mutez (Int64.neg v) with + | Some v -> Debited v + | None -> assert false (* [of_mutez z] is [None] iff [z < 0] *) + else + match Tez_repr.of_mutez v with + | Some v -> Credited v + | None -> assert false (* same *) ) + int64)) + +type update_origin = + | Block_application + | Protocol_migration + | Subsidy + | Simulation + +let compare_update_origin oa ob = + let index o = + match o with + | Block_application -> 0 + | Protocol_migration -> 1 + | Subsidy -> 2 + | Simulation -> 3 + in + Compare.Int.compare (index oa) (index ob) + +let update_origin_encoding = + let open Data_encoding in + def "operation_metadata.alpha.update_origin" + @@ obj1 @@ req "origin" + @@ union + [ + case + (Tag 0) + ~title:"Block_application" + (constant "block") + (function Block_application -> Some () | _ -> None) + (fun () -> Block_application); + case + (Tag 1) + ~title:"Protocol_migration" + (constant "migration") + (function Protocol_migration -> Some () | _ -> None) + (fun () -> Protocol_migration); + case + (Tag 2) + ~title:"Subsidy" + (constant "subsidy") + (function Subsidy -> Some () | _ -> None) + (fun () -> Subsidy); + case + (Tag 3) + ~title:"Simulation" + (constant "simulation") + (function Simulation -> Some () | _ -> None) + (fun () -> Simulation); + ] + +type balance_updates = (balance * balance_update * update_origin) list + +let balance_updates_encoding = + let open Data_encoding in + def "operation_metadata.alpha.balance_updates" + @@ list + (conv + (function + | (balance, balance_update, update_origin) -> + ((balance, balance_update), update_origin)) + (fun ((balance, balance_update), update_origin) -> + (balance, balance_update, update_origin)) + (merge_objs + (merge_objs balance_encoding balance_update_encoding) + update_origin_encoding)) + +module BalanceMap = Map.Make (struct + type t = balance * update_origin + + let compare (ba, ua) (bb, ub) = + let c = compare_balance ba bb in + if is_not_zero c then c else compare_update_origin ua ub +end) + +let group_balance_updates balance_updates = + List.fold_left_e + (fun acc (b, update, o) -> + (match BalanceMap.find (b, o) acc with + | None -> ok update + | Some present -> ( + match (present, update) with + | (Credited a, Debited b) | (Debited b, Credited a) -> + if Tez_repr.(a >= b) then + Tez_repr.(a -? b) >>? fun update -> ok (Credited update) + else Tez_repr.(b -? a) >>? fun update -> ok (Debited update) + | (Credited a, Credited b) -> + Tez_repr.(a +? b) >>? fun update -> ok (Credited update) + | (Debited a, Debited b) -> + Tez_repr.(a +? b) >>? fun update -> ok (Debited update))) + >>? function + | Credited update when Tez_repr.(update = zero) -> + ok (BalanceMap.remove (b, o) acc) + | update -> ok (BalanceMap.add (b, o) update acc)) + BalanceMap.empty + balance_updates + >>? fun map -> + ok (BalanceMap.fold (fun (b, o) u acc -> (b, u, o) :: acc) map []) diff --git a/src/proto_012_PsiThaCa/lib_protocol/receipt_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/receipt_repr.mli new file mode 100644 index 000000000000..7457de8aefd6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/receipt_repr.mli @@ -0,0 +1,80 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Places where tez can be found in the ledger's state. *) +type balance = + | Contract of Contract_repr.t + | Legacy_rewards of Signature.Public_key_hash.t * Cycle_repr.t + | Block_fees + | Legacy_deposits of Signature.Public_key_hash.t * Cycle_repr.t + | Deposits of Signature.Public_key_hash.t + | Nonce_revelation_rewards + | Double_signing_evidence_rewards + | Endorsing_rewards + | Baking_rewards + | Baking_bonuses + | Legacy_fees of Signature.Public_key_hash.t * Cycle_repr.t + | Storage_fees + | Double_signing_punishments + | Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool + | Liquidity_baking_subsidies + | Burned + | Commitments of Blinded_public_key_hash.t + | Bootstrap + | Invoice + | Initial_commitments + | Minted + +(** Compares two balances. *) +val compare_balance : balance -> balance -> int + +(** A credit or debit of tez to a balance. *) +type balance_update = Debited of Tez_repr.t | Credited of Tez_repr.t + +(** An origin of a balance update *) +type update_origin = + | Block_application (** Update from a block application *) + | Protocol_migration (** Update from a protocol migration *) + | Subsidy (** Update from an inflationary subsidy *) + | Simulation (** Simulation of an operation **) + +(** Compares two origins. *) +val compare_update_origin : update_origin -> update_origin -> int + +(** A list of balance updates. Duplicates may happen. + For example, an entry of the form [(Rewards (b,c), Credited am, ...)] + indicates that the balance of frozen rewards has been increased by [am] + for baker [b] and cycle [c]. *) +type balance_updates = (balance * balance_update * update_origin) list + +(** The property [Json.destruct (Json.construct balance_updates) = balance_updates] + does not always hold for [balance_updates_encoding] when [balance_updates] + contains entries of the form [(_, _ Tez_repr.zero, _)]. This is because the + [balance_update] [(_ Tez_repr.zero)] always decodes into [(Credited Tez_repr.zero)]. *) +val balance_updates_encoding : balance_updates Data_encoding.t + +(** Group updates by (balance x origin), and remove zero-valued balances. *) +val group_balance_updates : balance_updates -> balance_updates tzresult diff --git a/src/proto_012_PsiThaCa/lib_protocol/roll_repr_legacy.ml b/src/proto_012_PsiThaCa/lib_protocol/roll_repr_legacy.ml new file mode 100644 index 000000000000..598db52da902 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/roll_repr_legacy.ml @@ -0,0 +1,60 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Compare.Int32 + +type roll = t + +let encoding = + Data_encoding.( + with_decoding_guard + (fun t -> if t >= 0l then Ok () else Error "Positive int32 required") + int32) + +let first = 0l + +let succ i = Int32.succ i + +let random sequence ~bound = Seed_repr.take_int32 sequence bound + +let rpc_arg = RPC_arg.like RPC_arg.uint31 "roll" + +let to_int32 v = v + +module Index = struct + type t = roll + + let path_length = 1 + + let to_path roll l = Int32.to_string roll :: l + + let of_path = function s :: _ -> Int32.of_string_opt s | _ -> None + + let rpc_arg = rpc_arg + + let encoding = encoding + + let compare = compare +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/roll_repr_legacy.mli b/src/proto_012_PsiThaCa/lib_protocol/roll_repr_legacy.mli new file mode 100644 index 000000000000..cb792b0128e7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/roll_repr_legacy.mli @@ -0,0 +1,44 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = private int32 + +type roll = t + +val encoding : roll Data_encoding.t + +val rpc_arg : roll RPC_arg.t + +val random : Seed_repr.sequence -> bound:roll -> roll * Seed_repr.sequence + +val first : roll + +val succ : roll -> roll + +val to_int32 : roll -> Int32.t + +val ( = ) : roll -> roll -> bool + +module Index : Storage_description.INDEX with type t = roll diff --git a/src/proto_012_PsiThaCa/lib_protocol/roll_storage_legacy.ml b/src/proto_012_PsiThaCa/lib_protocol/roll_storage_legacy.ml new file mode 100644 index 000000000000..b37010dff898 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/roll_storage_legacy.ml @@ -0,0 +1,359 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | (* `Permanent *) Consume_roll_change + | (* `Permanent *) No_roll_for_delegate + | (* `Permanent *) No_stake_snapshot_for_cycle of Cycle_repr.t + | (* `Permanent *) Unregistered_delegate of Signature.Public_key_hash.t + +let () = + let open Data_encoding in + (* Consume roll change *) + register_error_kind + `Permanent + ~id:"contract.manager.consume_roll_change" + ~title:"Consume roll change" + ~description:"Change is not enough to consume a roll." + ~pp:(fun ppf () -> + Format.fprintf ppf "Not enough change to consume a roll.") + empty + (function Consume_roll_change -> Some () | _ -> None) + (fun () -> Consume_roll_change) ; + (* No roll for delegate *) + register_error_kind + `Permanent + ~id:"contract.manager.no_roll_for_delegate" + ~title:"No roll for delegate" + ~description:"Delegate has no roll." + ~pp:(fun ppf () -> Format.fprintf ppf "Delegate has no roll.") + empty + (function No_roll_for_delegate -> Some () | _ -> None) + (fun () -> No_roll_for_delegate) ; + (* No roll snapshot for cycle *) + register_error_kind + `Permanent + ~id:"contract.manager.no_stake_snapshot_for_cycle" + ~title:"No roll snapshot for cycle" + ~description: + "A snapshot of the rolls distribution does not exist for this cycle." + ~pp:(fun ppf c -> + Format.fprintf + ppf + "A snapshot of the rolls distribution does not exist for cycle %a" + Cycle_repr.pp + c) + (obj1 (req "cycle" Cycle_repr.encoding)) + (function No_stake_snapshot_for_cycle c -> Some c | _ -> None) + (fun c -> No_stake_snapshot_for_cycle c) ; + (* Unregistered delegate *) + register_error_kind + `Permanent + ~id:"contract.manager.unregistered_delegate_legacy" + ~title:"Unregistered delegate" + ~description:"A contract cannot be delegated to an unregistered delegate" + ~pp:(fun ppf k -> + Format.fprintf + ppf + "The provided public key (with hash %a) is not registered as valid \ + delegate key." + Signature.Public_key_hash.pp + k) + (obj1 (req "hash" Signature.Public_key_hash.encoding)) + (function Unregistered_delegate k -> Some k | _ -> None) + (fun k -> Unregistered_delegate k) + +let get_contract_delegate ctxt contract = + Storage.Contract.Delegate.find ctxt contract + +let delegate_pubkey ctxt delegate = + Storage.Contract.Manager.find ctxt (Contract_repr.implicit_contract delegate) + >>=? function + | None | Some (Manager_repr.Hash _) -> fail (Unregistered_delegate delegate) + | Some (Manager_repr.Public_key pk) -> return pk + +let fold ctxt ~f init = + Storage.Roll_legacy.Next.get ctxt >>=? fun last -> + let[@coq_struct "roll"] rec loop ctxt roll acc = + if Roll_repr_legacy.(roll = last) then return acc + else + Storage.Roll_legacy.Owner.find ctxt roll >>=? function + | None -> loop ctxt (Roll_repr_legacy.succ roll) acc + | Some delegate -> + f roll delegate acc >>=? fun acc -> + loop ctxt (Roll_repr_legacy.succ roll) acc + in + loop ctxt Roll_repr_legacy.first init + +let get_change ctxt delegate = + Storage.Roll_legacy.Delegate_change.find ctxt delegate + >|=? Option.value ~default:Tez_repr.zero + +module Delegate = struct + let fresh_roll ctxt = + Storage.Roll_legacy.Next.get ctxt >>=? fun roll -> + Storage.Roll_legacy.Next.update ctxt (Roll_repr_legacy.succ roll) + >|=? fun ctxt -> (roll, ctxt) + + let get_limbo_roll ctxt = + Storage.Roll_legacy.Limbo.find ctxt >>=? function + | None -> + fresh_roll ctxt >>=? fun (roll, ctxt) -> + Storage.Roll_legacy.Limbo.init ctxt roll >|=? fun ctxt -> (roll, ctxt) + | Some roll -> return (roll, ctxt) + + let consume_roll_change ctxt delegate = + let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> + record_trace Consume_roll_change Tez_repr.(change -? tokens_per_roll) + >>?= fun new_change -> + Storage.Roll_legacy.Delegate_change.update ctxt delegate new_change + + let recover_roll_change ctxt delegate = + let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> + Tez_repr.(change +? tokens_per_roll) >>?= fun new_change -> + Storage.Roll_legacy.Delegate_change.update ctxt delegate new_change + + let pop_roll_from_delegate ctxt delegate = + recover_roll_change ctxt delegate >>=? fun ctxt -> + (* beginning: + delegate : roll -> successor_roll -> ... + limbo : limbo_head -> ... + *) + Storage.Roll_legacy.Limbo.find ctxt >>=? fun limbo_head -> + Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate >>=? function + | None -> fail No_roll_for_delegate + | Some roll -> + Storage.Roll_legacy.Owner.remove_existing ctxt roll >>=? fun ctxt -> + Storage.Roll_legacy.Successor.find ctxt roll >>=? fun successor_roll -> + Storage.Roll_legacy.Delegate_roll_list.add_or_remove + ctxt + delegate + successor_roll + >>= fun ctxt -> + (* delegate : successor_roll -> ... + roll ------^ + limbo : limbo_head -> ... *) + Storage.Roll_legacy.Successor.add_or_remove ctxt roll limbo_head + >>= fun ctxt -> + (* delegate : successor_roll -> ... + roll ------v + limbo : limbo_head -> ... *) + Storage.Roll_legacy.Limbo.add ctxt roll >|= fun ctxt -> + (* delegate : successor_roll -> ... + limbo : roll -> limbo_head -> ... *) + ok (roll, ctxt) + + let create_roll_in_delegate ctxt delegate delegate_pk = + consume_roll_change ctxt delegate >>=? fun ctxt -> + (* beginning: + delegate : delegate_head -> ... + limbo : roll -> limbo_successor -> ... + *) + Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate + >>=? fun delegate_head -> + get_limbo_roll ctxt >>=? fun (roll, ctxt) -> + Storage.Roll_legacy.Owner.init ctxt roll delegate_pk >>=? fun ctxt -> + Storage.Roll_legacy.Successor.find ctxt roll >>=? fun limbo_successor -> + Storage.Roll_legacy.Limbo.add_or_remove ctxt limbo_successor >>= fun ctxt -> + (* delegate : delegate_head -> ... + roll ------v + limbo : limbo_successor -> ... *) + Storage.Roll_legacy.Successor.add_or_remove ctxt roll delegate_head + >>= fun ctxt -> + (* delegate : delegate_head -> ... + roll ------^ + limbo : limbo_successor -> ... *) + Storage.Roll_legacy.Delegate_roll_list.add ctxt delegate roll + (* delegate : roll -> delegate_head -> ... + limbo : limbo_successor -> ... *) + >|= ok + + let ensure_inited ctxt delegate = + Storage.Roll_legacy.Delegate_change.mem ctxt delegate >>= function + | true -> return ctxt + | false -> + Storage.Roll_legacy.Delegate_change.init ctxt delegate Tez_repr.zero + + let is_inactive ctxt delegate = + Storage.Contract.Inactive_delegate.mem + ctxt + (Contract_repr.implicit_contract delegate) + >>= fun inactive -> + if inactive then return inactive + else + Storage.Contract.Delegate_desactivation.find + ctxt + (Contract_repr.implicit_contract delegate) + >|=? function + | Some last_active_cycle -> + let ({Level_repr.cycle = current_cycle; _} : Level_repr.t) = + Raw_context.current_level ctxt + in + Cycle_repr.(last_active_cycle < current_cycle) + | None -> + (* This case is only when called from `set_active`, when creating + a contract. *) + false + + let add_amount ctxt delegate amount = + ensure_inited ctxt delegate >>=? fun ctxt -> + let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> + Tez_repr.(amount +? change) >>?= fun change -> + Storage.Roll_legacy.Delegate_change.update ctxt delegate change + >>=? fun ctxt -> + delegate_pubkey ctxt delegate >>=? fun delegate_pk -> + let[@coq_struct "change"] rec loop ctxt change = + if Tez_repr.(change < tokens_per_roll) then return ctxt + else + Tez_repr.(change -? tokens_per_roll) >>?= fun change -> + create_roll_in_delegate ctxt delegate delegate_pk >>=? fun ctxt -> + loop ctxt change + in + is_inactive ctxt delegate >>=? fun inactive -> + if inactive then return ctxt + else + loop ctxt change >>=? fun ctxt -> + Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate + >>=? fun rolls -> + match rolls with + | None -> return ctxt + | Some _ -> + Storage.Legacy_active_delegates_with_rolls.add ctxt delegate >|= ok + + let remove_amount ctxt delegate amount = + let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + let[@coq_struct "change"] rec loop ctxt change = + if Tez_repr.(amount <= change) then return (ctxt, change) + else + pop_roll_from_delegate ctxt delegate >>=? fun (_, ctxt) -> + Tez_repr.(change +? tokens_per_roll) >>?= fun change -> loop ctxt change + in + Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> + is_inactive ctxt delegate >>=? fun inactive -> + (if inactive then return (ctxt, change) + else + loop ctxt change >>=? fun (ctxt, change) -> + Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate + >>=? fun rolls -> + match rolls with + | None -> + Storage.Legacy_active_delegates_with_rolls.remove ctxt delegate + >|= fun ctxt -> ok (ctxt, change) + | Some _ -> return (ctxt, change)) + >>=? fun (ctxt, change) -> + Tez_repr.(change -? amount) >>?= fun change -> + Storage.Roll_legacy.Delegate_change.update ctxt delegate change + + let set_inactive ctxt delegate = + ensure_inited ctxt delegate >>=? fun ctxt -> + let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> + Storage.Contract.Inactive_delegate.add + ctxt + (Contract_repr.implicit_contract delegate) + >>= fun ctxt -> + Storage.Legacy_active_delegates_with_rolls.remove ctxt delegate + >>= fun ctxt -> + let[@coq_struct "change"] rec loop ctxt change = + Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate >>=? function + | None -> return (ctxt, change) + | Some _roll -> + pop_roll_from_delegate ctxt delegate >>=? fun (_, ctxt) -> + Tez_repr.(change +? tokens_per_roll) >>?= fun change -> + loop ctxt change + in + loop ctxt change >>=? fun (ctxt, change) -> + Storage.Roll_legacy.Delegate_change.update ctxt delegate change + + let set_active ctxt delegate = + is_inactive ctxt delegate >>=? fun inactive -> + let current_cycle = (Raw_context.current_level ctxt).cycle in + let preserved_cycles = Constants_storage.preserved_cycles ctxt in + (* When the delegate is new or inactive, she will become active in + `1+preserved_cycles`, and we allow `preserved_cycles` for the + delegate to start baking. When the delegate is active, we only + give her at least `preserved_cycles` after the current cycle + before to be deactivated. *) + Storage.Contract.Delegate_desactivation.find + ctxt + (Contract_repr.implicit_contract delegate) + >>=? fun current_expiration -> + let expiration = + match current_expiration with + | None -> Cycle_repr.add current_cycle (1 + (2 * preserved_cycles)) + | Some current_expiration -> + let delay = + if inactive then 1 + (2 * preserved_cycles) + else 1 + preserved_cycles + in + let updated = Cycle_repr.add current_cycle delay in + Cycle_repr.max current_expiration updated + in + Storage.Contract.Delegate_desactivation.add + ctxt + (Contract_repr.implicit_contract delegate) + expiration + >>= fun ctxt -> + if not inactive then return ctxt + else + ensure_inited ctxt delegate >>=? fun ctxt -> + let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + Storage.Roll_legacy.Delegate_change.get ctxt delegate >>=? fun change -> + Storage.Contract.Inactive_delegate.remove + ctxt + (Contract_repr.implicit_contract delegate) + >>= fun ctxt -> + delegate_pubkey ctxt delegate >>=? fun delegate_pk -> + let[@coq_struct "change"] rec loop ctxt change = + if Tez_repr.(change < tokens_per_roll) then return ctxt + else + Tez_repr.(change -? tokens_per_roll) >>?= fun change -> + create_roll_in_delegate ctxt delegate delegate_pk >>=? fun ctxt -> + loop ctxt change + in + loop ctxt change >>=? fun ctxt -> + Storage.Roll_legacy.Delegate_roll_list.find ctxt delegate + >>=? fun rolls -> + match rolls with + | None -> return ctxt + | Some _ -> + Storage.Legacy_active_delegates_with_rolls.add ctxt delegate >|= ok +end + +module Contract = struct + let add_amount c contract amount = + get_contract_delegate c contract >>=? function + | None -> return c + | Some delegate -> Delegate.add_amount c delegate amount + + let remove_amount c contract amount = + get_contract_delegate c contract >>=? function + | None -> return c + | Some delegate -> Delegate.remove_amount c delegate amount +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/roll_storage_legacy.mli b/src/proto_012_PsiThaCa/lib_protocol/roll_storage_legacy.mli new file mode 100644 index 000000000000..9d63dea855be --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/roll_storage_legacy.mli @@ -0,0 +1,173 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** + Basic roll manipulation. + + The storage related to roll (i.e. `Storage.Roll`) is not used outside of + this module. And, this interface enforces the invariant that a roll is + always either in the limbo list or owned by a delegate. +*) + +type error += + | (* `Permanent *) Consume_roll_change + | (* `Permanent *) No_roll_for_delegate + | (* `Permanent *) No_stake_snapshot_for_cycle of Cycle_repr.t + | (* `Permanent *) Unregistered_delegate of Signature.Public_key_hash.t + +(** + [fold ctxt f init] folds [f] on the list of all rolls from [Roll_repr.first] + to [Storage.Next.Roll] of the context [ctxt]. Only rolls which have owners + are considered, rolls without owners are skipped. The first parameter of [f] + is a roll [r], the second parameter of [f] is the owner of [r], and the last + parameter is the initial value of the accumulator. +*) +val fold : + Raw_context.t -> + f:(Roll_repr_legacy.roll -> Signature.Public_key.t -> 'a -> 'a tzresult Lwt.t) -> + 'a -> + 'a tzresult Lwt.t + +module Delegate : sig + val is_inactive : + Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t + + (** + [add_amount ctxt dlg am] performs the following actions: + + 1. if the delegate [dlg] is inactive, increase its change [chg] by [am], + 2. if the [dlg] is active, update [dlg]'s number of rolls [nr], and change + [chg] so that [dlg]'s number of tokens is increased by [am], and equal + to [nr * tokens_per_roll + chg], where [chg < tokens_per_roll]. + *) + val add_amount : + Raw_context.t -> + Signature.Public_key_hash.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t + + (** + [remove_amount ctxt dlg am] performs the following actions: + + 1. if the delegate [dlg] is inactive, decrease its change [chg] by [am], + 2. if the [dlg] is active, update [dlg]'s number of rolls [nr], and change + [chg] so that [dlg]'s number of tokens is decreased by [am], and equal to + [nr * tokens_per_roll + chg], where [chg < tokens_per_roll]. + *) + val remove_amount : + Raw_context.t -> + Signature.Public_key_hash.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t + + (** + [set_inactive ctxt dlg] renders delegate [dlg] inactive and performs the + following actions: + + 1. empty the list of rolls of [dlg], + 2. increase the change of [dlg] by [nr * tokens_per_roll], where [nr] is + [dlg]'s number of rolls prior to inactivation. + *) + val set_inactive : + Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t + + (** + If the delegate [dlg] is already active then [set_active ctxt dlg] + performs the following sequence of actions: + + 1. if the delegate is not scheduled to become inactive, then schedule the + delegate to become inactive after [(preserved_cycles * 2) + 1] cycles, + 2. if the delegate is already scheduled to become inactive at cycle [ic], + then re-schedule it to become inactive at cycle + [max ic (cc + preserved_cycles + 1)], where [cc] is the current cycle. + + If [dlg] is inactive then this function puts [dlg] in active state and + performs the following actions: + + 1. if [dlg] is not scheduled to become inactive, schedule [dlg] to become + inactive after [(preserved_cycles * 2) + 1] cycles, + 2. if the [dlg] is already scheduled to become inactive at cycle [ic], + then re-schedule it to become inactive at cycle + [max ic (cc + (preserved_cycles * 2) + 1)], where [cc] is the current + cycle, + 3. dispatch [dlg]'s change [chg] into [nr] rolls of size [tokens_per_roll] + so that the total amount managed by [dlg] is unchanged and equal to + [(nr * tokens_per_roll) + chg], where [chg < tokens_per_roll]. + *) + val set_active : + Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t +end + +module Contract : sig + (** + Calls [Delegate.add_amount ctxt contract am] if a delegate is associated + to [contract], or returns unchanged [ctxt] otherwise. + *) + val add_amount : + Raw_context.t -> + Contract_repr.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t + + (** + Calls [Delegate.remove_amount ctxt contract am] if a delegate is associated + to [contract], or returns unchanged [ctxt] otherwise. + *) + val remove_amount : + Raw_context.t -> + Contract_repr.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t +end + +(** + [delegate_pubkey ctxt delegate] returns the public key of + [delegate] found in context [ctxt] if there exists a registered + contract. +*) +val delegate_pubkey : + Raw_context.t -> + Signature.Public_key_hash.t -> + Signature.Public_key.t tzresult Lwt.t + +(** + [get_change ctxt delegate] returns the amount of change held by + [delegate] in context [ctxt]. The change is the part of the staking + balance of a delegate that is not part of a roll, i.e., the amount + of staking balance (smaller than the value of a roll) not being + taken into account for baking rights computation. +*) +val get_change : + Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t + +(** + [get_contract_delegate ctxt contract] returns the public key hash + of the delegate whose contract is [contract] in context [ctxt]. +*) +val get_contract_delegate : + Raw_context.t -> + Contract_repr.t -> + Signature.Public_key_hash.t option tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/round_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/round_repr.ml new file mode 100644 index 000000000000..d80ad520b9a5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/round_repr.ml @@ -0,0 +1,429 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type round = int32 + +type t = round + +module Map = Map.Make (Int32) + +include (Compare.Int32 : Compare.S with type t := t) + +let zero = 0l + +let succ n = + if Compare.Int32.equal n Int32.max_int then + invalid_arg "round_repr.succ: cannot apply succ to maximum round value" + else Int32.succ n + +let pp fmt i = Format.fprintf fmt "%ld" i + +type error += Negative_round of int + +type error += Round_overflow of int + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"negative_round" + ~title:"Negative round" + ~description:"Round cannot be built out of negative integers." + ~pp:(fun ppf i -> + Format.fprintf + ppf + "Negative round cannot be built out of negative integers (%Ld)" + i) + (obj1 (req "Negative_round" int64)) + (function Negative_round i -> Some (Int64.of_int i) | _ -> None) + (fun i -> Negative_round (Int64.to_int i)) ; + register_error_kind + `Permanent + ~id:"round_overflow" + ~title:"Round overflow" + ~description: + "Round cannot be built out of integer greater than maximum int32 value." + ~pp:(fun ppf i -> + Format.fprintf + ppf + "Round cannot be built out of integer greater than maximum int32 value \ + (%Ld)" + i) + (obj1 (req "Negative_round" int64)) + (function Round_overflow i -> Some (Int64.of_int i) | _ -> None) + (fun i -> Round_overflow (Int64.to_int i)) + +let of_int32 i = + if i >= 0l then Ok i else error (Negative_round (Int32.to_int i)) + [@@inline] + +let pred r = + let p = Int32.pred r in + of_int32 p + +let of_int i = + if Compare.Int.(i < 0) then error (Negative_round i) + else + (* i is positive *) + let i32 = Int32.of_int i in + if Compare.Int.(Int32.to_int i32 = i) then Ok i32 + else error (Round_overflow i) + +let to_int i32 = + let i = Int32.to_int i32 in + if Int32.(equal (of_int i) i32) then ok i else error (Round_overflow i) + +let to_int32 t = t [@@inline] + +let to_slot round ~committee_size = + to_int round >|? fun r -> + let slot = r mod committee_size in + Slot_repr.of_int_exn slot + +let encoding = + Data_encoding.conv_with_guard + (fun i -> i) + (fun i -> + match of_int32 i with + | Ok _ as res -> res + | Error _ -> Error "Round_repr.encoding: negative round") + Data_encoding.int32 + +module Durations = struct + type t = { + first_round_duration : Period_repr.t; + delay_increment_per_round : Period_repr.t; + } + + type error += + | Non_increasing_rounds of {increment : Period_repr.t} + | Round_durations_must_be_at_least_one_second of {round : Period_repr.t} + + let () = + register_error_kind + `Permanent + ~id:"durations.non_increasing_rounds" + ~title:"Non increasing round" + ~description:"The provided rounds are not increasing." + ~pp:(fun ppf increment -> + Format.fprintf + ppf + "The provided rounds are not increasing (increment: %a)" + Period_repr.pp + increment) + Data_encoding.(obj1 (req "increment" Period_repr.encoding)) + (function + | Non_increasing_rounds {increment} -> Some increment | _ -> None) + (fun increment -> Non_increasing_rounds {increment}) + + let pp fmt t = + Format.fprintf + fmt + "%a,@ +%a" + Period_repr.pp + t.first_round_duration + Period_repr.pp + t.delay_increment_per_round + + let create ~first_round_duration ~delay_increment_per_round = + error_when + Compare.Int64.(Period_repr.to_seconds first_round_duration < 1L) + (Round_durations_must_be_at_least_one_second + {round = first_round_duration}) + >>? fun () -> + error_when + Compare.Int64.(Period_repr.to_seconds delay_increment_per_round < 1L) + (Non_increasing_rounds {increment = delay_increment_per_round}) + >>? fun () -> ok {first_round_duration; delay_increment_per_round} + + let create_opt ~first_round_duration ~delay_increment_per_round = + match create ~first_round_duration ~delay_increment_per_round with + | Ok v -> Some v + | Error _ -> None + + let encoding = + let open Data_encoding in + conv_with_guard + (fun {first_round_duration; delay_increment_per_round} -> + (first_round_duration, delay_increment_per_round)) + (fun (first_round_duration, delay_increment_per_round) -> + match create_opt ~first_round_duration ~delay_increment_per_round with + | None -> + Error + "Either round durations are non-increasing or minimal block \ + delay < 1" + | Some rounds -> Ok rounds) + (obj2 + (req "first_round_duration" Period_repr.encoding) + (req "delay_increment_per_round" Period_repr.encoding)) + + let round_duration {first_round_duration; delay_increment_per_round} round = + if Compare.Int32.(round < 0l) then + invalid_arg "round must be a non-negative integer" + else + let first_round_duration_s = Period_repr.to_seconds first_round_duration + and delay_increment_per_round_s = + Period_repr.to_seconds delay_increment_per_round + in + Period_repr.of_seconds_exn + Int64.( + add + first_round_duration_s + (mul (of_int32 round) delay_increment_per_round_s)) +end + +type error += Round_too_high of int32 + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"round_too_high" + ~title:"round too high" + ~description:"block round too high." + ~pp:(fun ppf round -> + Format.fprintf ppf "Block round is too high: %ld" round) + (obj1 (req "level_offset_too_high" int32)) + (function Round_too_high round -> Some round | _ -> None) + (fun round -> Round_too_high round) + +(* The duration of round n follows the arithmetic sequence: + + round_duration(0) = first_round_duration + round_duration(r+1) = round_duration(r) + delay_increment_per_round + + Hence, this sequence can be explicited into: + + round_duration(r) = first_round_duration + r * delay_increment_per_round + + The level offset of round r is the sum of the durations of the rounds up + until round r - 1. In other words, when r > 0 + + level_offset_of_round(0) = 0 + level_offset_of_round(r+1) = level_offset_of_round(r) + round_duration(r) + +Hence + + level_offset_of_round(r) = Σ_{k=0}^{r-1} (round_duration(k)) + + After unfolding the series, the same function can be finally explicited into + + level_offset_of_round(0) = 0 + level_offset_of_round(r) = r * first_round_duration + + 1/2 * r * (r - 1) * delay_increment_per_round +*) +let level_offset_of_round round_durations ~round = + if Compare.Int32.(round = zero) then ok Int64.zero + else + let sum_durations = + let Durations.{first_round_duration; delay_increment_per_round} = + round_durations + in + let roundz = Int64.of_int32 round in + let m = Z.of_int64 Int64.(div (mul roundz (pred roundz)) (of_int 2)) in + Z.( + add + (mul + m + (Z.of_int64 @@ Period_repr.to_seconds delay_increment_per_round)) + (mul + (Z.of_int32 round) + (Z.of_int64 @@ Period_repr.to_seconds first_round_duration))) + in + if Compare.Z.(sum_durations > Z.of_int64 Int64.max_int) then + error (Round_too_high round) + else ok (Z.to_int64 sum_durations) + +type error += Level_offset_too_high of Period_repr.t + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"level_offset_too_high" + ~title:"level offset too high" + ~description:"The block's level offset is too high." + ~pp:(fun ppf offset -> + Format.fprintf + ppf + "The block's level offset is too high: %a" + Period_repr.pp + offset) + (obj1 (req "level_offset_too_high" Period_repr.encoding)) + (function Level_offset_too_high offset -> Some offset | _ -> None) + (fun offset -> Level_offset_too_high offset) + +type round_and_offset = {round : int32; offset : Period_repr.t} + +(** Complexity: O(log max_int). *) +let round_and_offset round_durations ~level_offset = + let level_offset_in_seconds = Period_repr.to_seconds level_offset in + (* We have the invariant [round <= level_offset] so there is no need to search + beyond [level_offset]. We set [right_bound] to [level_offset + 1] to avoid + triggering the error level_offset too high when the round equals + [level_offset]. *) + let right_bound = + if Compare.Int64.(level_offset_in_seconds < Int64.of_int32 Int32.max_int) + then Int32.of_int (Int64.to_int level_offset_in_seconds + 1) + else Int32.max_int + in + let rec bin_search min_r max_r = + if Compare.Int32.(min_r >= right_bound) then + error (Level_offset_too_high level_offset) + else + let round = Int32.(add min_r (div (sub max_r min_r) 2l)) in + level_offset_of_round round_durations ~round:(Int32.succ round) + >>? fun next_level_offset -> + if + Compare.Int64.(Period_repr.to_seconds level_offset >= next_level_offset) + then bin_search (Int32.succ round) max_r + else + level_offset_of_round round_durations ~round + >>? fun current_level_offset -> + if + Compare.Int64.( + Period_repr.to_seconds level_offset < current_level_offset) + then bin_search min_r round + else + ok + { + round; + offset = + Period_repr.of_seconds_exn + (Int64.sub + (Period_repr.to_seconds level_offset) + current_level_offset); + } + in + bin_search 0l right_bound + +(** Complexity: O(|round_durations|). *) +let timestamp_of_round round_durations ~predecessor_timestamp ~predecessor_round + ~round = + let pred_round_duration = + Durations.round_duration round_durations predecessor_round + in + (* First, the function computes when the current level l is supposed + to start. This is given by adding to the timestamp of the round + of predecessor level l-1 [predecessor_timestamp], the duration of + its last round [predecessor_round]. *) + Time_repr.(predecessor_timestamp +? pred_round_duration) + >>? fun start_of_current_level -> + (* Finally, we sum the durations of the rounds at the current level l until + reaching current [round]. *) + level_offset_of_round round_durations ~round >>? fun level_offset -> + let level_offset = Period_repr.of_seconds_exn level_offset in + Time_repr.(start_of_current_level +? level_offset) + +(** Unlike [timestamp_of_round], this function gets the starting time + of a given round, given the timestamp and the round of a proposal + at the same level. + + We compute the starting time of [considered_round] from a given + [round_durations] description, some [current_round], and its + starting time [current_timestamp]. + + Complexity: O(|round_durations|). *) +let timestamp_of_another_round_same_level round_durations ~current_timestamp + ~current_round ~considered_round = + level_offset_of_round round_durations ~round:considered_round + >>? fun target_offset -> + level_offset_of_round round_durations ~round:current_round + >>? fun current_offset -> + ok + @@ Time_repr.of_seconds + Int64.( + add + (sub (Time_repr.to_seconds current_timestamp) current_offset) + target_offset) + +type error += + | Round_of_past_timestamp of { + provided_timestamp : Time.t; + predecessor_timestamp : Time.t; + predecessor_round : t; + } + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"round_of_past_timestamp" + ~title:"Round_of_timestamp for past timestamp" + ~description:"Provided timestamp is before the expected level start." + ~pp:(fun ppf (provided_ts, predecessor_ts, round) -> + Format.fprintf + ppf + "Provided timestamp (%a) is before the expected level start (computed \ + based on predecessor_ts %a at round %a)." + Time.pp_hum + provided_ts + Time.pp_hum + predecessor_ts + pp + round) + (obj3 + (req "provided_timestamp" Time.encoding) + (req "predecessor_timestamp" Time.encoding) + (req "predecessor_round" encoding)) + (function + | Round_of_past_timestamp + {provided_timestamp; predecessor_timestamp; predecessor_round} -> + Some (provided_timestamp, predecessor_timestamp, predecessor_round) + | _ -> None) + (fun (provided_timestamp, predecessor_timestamp, predecessor_round) -> + Round_of_past_timestamp + {provided_timestamp; predecessor_timestamp; predecessor_round}) + +let round_of_timestamp round_durations ~predecessor_timestamp ~predecessor_round + ~timestamp = + let round_duration = + Durations.round_duration round_durations predecessor_round + in + Time_repr.(predecessor_timestamp +? round_duration) + >>? fun start_of_current_level -> + Period_repr.of_seconds (Time_repr.diff timestamp start_of_current_level) + |> Error_monad.record_trace + (Round_of_past_timestamp + { + predecessor_timestamp; + provided_timestamp = timestamp; + predecessor_round; + }) + >>? fun diff -> + round_and_offset round_durations ~level_offset:diff + >>? fun round_and_offset -> ok round_and_offset.round + +let level_offset_of_round round_durations ~round = + level_offset_of_round round_durations ~round >>? fun offset -> + ok (Period_repr.of_seconds_exn offset) + +module Internals_for_test = struct + type round_and_offset_raw = {round : round; offset : Period_repr.t} + + let round_and_offset round_durations ~level_offset = + round_and_offset round_durations ~level_offset >|? fun v -> + {round = v.round; offset = v.offset} +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/round_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/round_repr.mli new file mode 100644 index 000000000000..292ed5d939b8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/round_repr.mli @@ -0,0 +1,245 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** A round represents an iteration of the single-shot consensus algorithm. + + Rounds can be seen as an infinite, 0-indexed, list of durations. The + durations are generated by an arithmetic progression depending on + {!val:Constants_repr.minimal_block_delay} (its initial value, a.k.a the one for + round 0) and {!val:Constants_repr.delay_increment_per_round} (its common + difference) . + + Round identifiers are non-negative 32 bit integers. This interface ensures + that no negative round can be created. *) + +type round + +type t = round + +(** Round zero *) +val zero : t + +(** Successor of the given round. + + @raise [Invalid_arg] if applied to the upper bound of the round integer + representation. *) +val succ : t -> t + +(** Predecessor of the given round. + Returns an error if applied to [zero], as negative round are + prohibited. *) +val pred : t -> t tzresult + +(** Building a round from an int32. + Returns an error if applied to a negative number. *) +val of_int32 : int32 -> t tzresult + +val to_int32 : t -> int32 + +(** Building a round from an int. + Returns an error if applied to a negative number or a number + greater than Int32.max_int. *) +val of_int : int -> t tzresult + +(** Building an int from a round. + Returns an error if the value does not fit in max_int. (current + 32bit encodings always fit in int on 64bit architecture though). *) +val to_int : t -> int tzresult + +(** Returns the slot corresponding to the given round [r], that is [r + mod committee_size]. *) +val to_slot : t -> committee_size:int -> Slot_repr.t tzresult + +(** Round encoding. + Be aware that decoding a negative 32 bit integer would lead to an + exception. *) +val encoding : t Data_encoding.t + +val pp : Format.formatter -> t -> unit + +include Compare.S with type t := t + +module Map : Map.S with type key = t + +(** {2 Round duration representation} *) + +module Durations : sig + (** [round_durations] represents the duration of rounds in seconds *) + type t + + val pp : Format.formatter -> t -> unit + + (** {3 Creation functions} *) + + (** [create ~first_round_duration ~delay_increment_per_round] creates a valid + duration value + + @param first_round_duration duration of round 0 + @param delay_increment_per_round amount of time added in from one round + duration to the duration of its next round + @raises Invalid_argument if + - first_round_duration <= 1; or + - delay_increment_per_round is <= 0 + *) + val create : + first_round_duration:Period_repr.t -> + delay_increment_per_round:Period_repr.t -> + t tzresult + + (** [create_opt ~first_round_duration ~delay_increment_per_round] returns a valid duration value + [Some d] when [create ~first_round_duration ~delay_increment_per_round] + does not fail. It returns [None] otherwise. *) + val create_opt : + first_round_duration:Period_repr.t -> + delay_increment_per_round:Period_repr.t -> + t option + + (** {b Warning} May trigger an exception when the expected invariant + does not hold. *) + val encoding : t Data_encoding.encoding + + (** {3 Accessors}*) + + (** [round_duration round_durations ~round] returns the duration of round + [~round]. This duration follows the arithmetic progression + + duration(round_n) = [first_round_duration] + round_n * [delay_increment_per_round] + + *) + val round_duration : t -> round -> Period_repr.t +end + +(** [level_offset_of_round round_durations ~round:r] represents the offset of the + starting time of round [r] with respect to the start of the level. + round = 0 1 2 3 r + + |-----|-----|-----|-----|-----|--- ... ... --|------|------- + | + <-------------------------------------------> + level_offset +*) +val level_offset_of_round : Durations.t -> round:t -> Period_repr.t tzresult + +(** [timestamp_of_round round_durations ~predecessor_timestamp:pred_ts + ~predecessor_round:pred_round ~round] returns the + starting time of round [round] given that the timestamp and the round of + the block at the previous level is [pred_ts] and [pred_round], + respectively. + + pred_round = 0 pred_round + + |-----|.. ... --|--------|-- ... --|------- + | | + | | + pred_ts | + | + start_of_cur_level + | + | + |-----|------|-- ... --|-------|- + cur_round = 0 1 | round + | + res_ts + + Precisely, the resulting timestamp is: + [pred_ts + round_duration(pred_round) + level_offset_of_round(round)]. +*) +val timestamp_of_round : + Durations.t -> + predecessor_timestamp:Time_repr.t -> + predecessor_round:t -> + round:t -> + Time_repr.t tzresult + +(** [timestamp_of_another_round_same_level + round_durations + ~current_timestamp + ~current_round + ~considered_round] + returns the starting time of round [considered_round]. + + start of current + level current ts result + | | | + | | | + |-----|----...--|-- ... ------|- + | | | | + cur_round = 0 1 current considered + round round + + It also works when [considered_round] is lower than [current_round]. + + Precisely, the resulting timestamp is: + [current_timestamp - level_offset_of_round(current_round) + + level_offset_of_round(considered_round)]. +*) +val timestamp_of_another_round_same_level : + Durations.t -> + current_timestamp:Time_repr.t -> + current_round:t -> + considered_round:t -> + Time_repr.t tzresult + +(** [round_of_timestamp round_durations ~predecessor_timestamp ~predecessor_round + ~timestamp:ts] returns the round to which the timestamp [ts] belongs to, + given that the timestamp and the round of the block at the previous level is + [pred_ts] and [pred_round], respectively. + + Precisely, the resulting round is: + [round_and_offset round_durations ~level_offset:diff] where + [diff = ts - (predecessor_timestamp + round_duration(predecessor_round)]. + + Returns an error when the timestamp is before the level start.*) +val round_of_timestamp : + Durations.t -> + predecessor_timestamp:Time_repr.t -> + predecessor_round:t -> + timestamp:Time_repr.t -> + t tzresult + +module Internals_for_test : sig + type round_and_offset_raw = {round : round; offset : Period_repr.t} + + (** [round_and_offset round_durations ~level_offset], where [level_offset] + represents a time offset with respect to the start of the first round, + returns a tuple [(r, round_offset)] where the round [r] is such that + [level_offset_of_round(r) <= level_offset < level_offset_of_round(r+1)] and + [round_offset := level_offset - level_offset_of_round(r)]]. + + round = 0 1 2 3 r + + |-----|-----|-----|-----|-----|--- ... ... --|--------|-- ... --|------- + | + round_delay(r) + | + | + <-----> + round_offset + <---------------------------------------------------> + level_offset +*) + val round_and_offset : + Durations.t -> level_offset:Period_repr.t -> round_and_offset_raw tzresult +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/sampler.ml b/src/proto_012_PsiThaCa/lib_protocol/sampler.ml new file mode 100644 index 000000000000..3e7737d2f76e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/sampler.ml @@ -0,0 +1,209 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* + + This module implements the alias method for sampling from a given + distribution. The distribution need not be normalized. + +*) + +module type Mass = sig + type t + + val encoding : t Data_encoding.t + + val zero : t + + val of_int : int -> t + + val mul : t -> t -> t + + val add : t -> t -> t + + val sub : t -> t -> t + + val ( = ) : t -> t -> bool + + val ( <= ) : t -> t -> bool + + val ( < ) : t -> t -> bool +end + +module type S = sig + type mass + + type 'a t + + val create : ('a * mass) list -> 'a t + + val sample : 'a t -> (int_bound:int -> mass_bound:mass -> int * mass) -> 'a + + val encoding : 'a Data_encoding.t -> 'a t Data_encoding.t +end + +module Make (Mass : Mass) : S with type mass = Mass.t = struct + type mass = Mass.t + + type 'a t = { + total : Mass.t; + support : 'a FallbackArray.t; + p : Mass.t FallbackArray.t; + alias : int FallbackArray.t; + } + + let rec init_loop total p alias small large = + match (small, large) with + | ([], _) -> List.iter (fun (_, i) -> FallbackArray.set p i total) large + | (_, []) -> + (* This can only happen because of numerical inaccuracies when using + eg [Mass.t = float] *) + List.iter (fun (_, i) -> FallbackArray.set p i total) small + | ((qi, i) :: small', (qj, j) :: large') -> + FallbackArray.set p i qi ; + FallbackArray.set alias i j ; + let qj' = Mass.sub (Mass.add qi qj) total in + if Mass.(qj' < total) then + init_loop total p alias ((qj', j) :: small') large' + else init_loop total p alias small' ((qj', j) :: large') + + let support : + fallback:'a -> length:int -> ('a * Mass.t) list -> 'a FallbackArray.t = + fun ~fallback ~length measure -> + let a = FallbackArray.make length fallback in + List.iteri (fun i (elt, _) -> FallbackArray.set a i elt) measure ; + a + + let check_and_cleanup measure = + let (total, measure) = + List.fold_left + (fun ((total, m) as acc) ((_, p) as point) -> + if Mass.(zero < p) then (Mass.add total p, point :: m) + else if Mass.(p < zero) then invalid_arg "create" + else (* p = zero: drop point *) + acc) + (Mass.zero, []) + measure + in + match measure with + | [] -> invalid_arg "create" + | (fallback, _) :: _ -> (fallback, total, measure) + + (* NB: duplicate elements in the support are not merged; + the algorithm should still function correctly. *) + let create (measure : ('a * Mass.t) list) = + let (fallback, total, measure) = check_and_cleanup measure in + let length = List.length measure in + let n = Mass.of_int length in + let (_, small, large) = + List.fold_left + (fun (i, small, large) (_, p) -> + let q = Mass.mul p n in + if Mass.(q < total) then (i + 1, (q, i) :: small, large) + else (i + 1, small, (q, i) :: large)) + (0, [], []) + measure + in + let support = support ~fallback ~length measure in + let p = FallbackArray.make length total in + let alias = FallbackArray.make length (-1) in + init_loop total p alias small large ; + {total; support; p; alias} + + let sample {total; support; p; alias} draw_i_elt = + let n = FallbackArray.length support in + let (i, elt) = draw_i_elt ~int_bound:n ~mass_bound:total in + let p = FallbackArray.get p i in + if Mass.(elt < p) then FallbackArray.get support i + else + let j = FallbackArray.get alias i in + assert (Compare.Int.(j >= 0)) ; + FallbackArray.get support j + + (* Note: this could go in the environment maybe? *) + let array_encoding : 'a Data_encoding.t -> 'a FallbackArray.t Data_encoding.t + = + fun venc -> + let open Data_encoding in + conv + (fun array -> + let length = FallbackArray.length array in + let fallback = FallbackArray.fallback array in + let elements = + List.rev (FallbackArray.fold (fun acc elt -> elt :: acc) array []) + in + (length, fallback, elements)) + (fun (length, fallback, elements) -> + let array = FallbackArray.make length fallback in + List.iteri (fun i elt -> FallbackArray.set array i elt) elements ; + array) + (obj3 + (req "length" int31) + (req "fallback" venc) + (req "elements" (list venc))) + + let mass_array_encoding = array_encoding Mass.encoding + + let int_array_encoding = array_encoding Data_encoding.int31 + + let encoding enc = + let open Data_encoding in + conv + (fun {total; support; p; alias} -> (total, support, p, alias)) + (fun (total, support, p, alias) -> {total; support; p; alias}) + (obj4 + (req "total" Mass.encoding) + (req "support" (array_encoding enc)) + (req "p" mass_array_encoding) + (req "alias" int_array_encoding)) +end + +module Internal_for_tests = struct + module Make = Make +end + +module Mass : Mass with type t = int64 = struct + type t = int64 + + let encoding = Data_encoding.int64 + + let zero = 0L + + let of_int = Int64.of_int + + let mul = Int64.mul + + let add = Int64.add + + let sub = Int64.sub + + let ( = ) = Compare.Int64.( = ) + + let ( <= ) = Compare.Int64.( <= ) + + let ( < ) = Compare.Int64.( < ) +end + +include Make (Mass) diff --git a/src/proto_012_PsiThaCa/lib_protocol/sampler.mli b/src/proto_012_PsiThaCa/lib_protocol/sampler.mli new file mode 100644 index 000000000000..cd4b8b950178 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/sampler.mli @@ -0,0 +1,98 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +(** Efficient sampling from given finitely supported (nonzero, positive) + measures using the alias method. Measures need not be normalized on input, + but sampling proceeds from the normalized probability measure associated + to the given measure. + *) + +(** [Mass] is the module type describing the measure associated to points. *) +module type Mass = sig + (** [t] is the type describing the measure associated to points. *) + type t + + val encoding : t Data_encoding.t + + val zero : t + + val of_int : int -> t + + val mul : t -> t -> t + + val add : t -> t -> t + + val sub : t -> t -> t + + val ( = ) : t -> t -> bool + + val ( <= ) : t -> t -> bool + + val ( < ) : t -> t -> bool +end + +(** [S] is the module type of a module allowing to construct samplers based + on the alias method. *) +module type S = sig + (** [mass] is the type in which finite measures take their values + (see [Mass] module type). *) + type mass + + (** ['a t] is the type of auxilliary data for sampling from + a given distribution. *) + type 'a t + + (** [create measure] constructs auxilliary data to sample from + [measure] after normalization. Complexity: O(n). + + It is assumed that the measure is positive. [measure] can contain + zero mass elements: those are removed in a pre-processing step. + The total mass of the measure should be strictly positive. + + @raise Invalid_argument if [measure] contains negative mass elements + or if it contains only zero mass elements. *) + val create : ('a * mass) list -> 'a t + + (** [sample auxdata rand] creates a sampler from [auxdata] that follows + the distribution associated to the measure specified when + creating the [auxdata]. The parameter [rand] is a random sampler + for the two random values used by the sampling method. The first + bound is at most the length of the list passed to [create] when + creating [auxdata]. The second bound is at most the sum of all + items in the list passed to [create]. *) + val sample : 'a t -> (int_bound:int -> mass_bound:mass -> int * mass) -> 'a + + (** [encoding e] constructs an encoding for ['a t] given an encoding for ['a]. *) + val encoding : 'a Data_encoding.t -> 'a t Data_encoding.t +end + +(**/**) + +module Internal_for_tests : sig + (** [Make(Mass)] instantiates a module allowing to creates + samplers for [Mass]-valued finite measures. *) + module Make : functor (Mass : Mass) -> S with type mass = Mass.t +end + +include S with type mass = Int64.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/sapling_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/sapling_repr.ml new file mode 100644 index 000000000000..2b5dc17ef038 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/sapling_repr.ml @@ -0,0 +1,200 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type transaction = Sapling.UTXO.transaction + +let transaction_encoding = Sapling.UTXO.transaction_encoding + +(* The two data structures in the state are all ordered by position, a diff + contains the elements starting from an offset position up to the most recent + position. A diff can be applied to a state stored in a context to obtain a + new state. + Diffs are used by the Michelson interpreter during the evaluation of smart + contracts to keep a temporary state that may be discarded. + Diffs are also returned by an RPC to allow a client to synchronize its own + state with the chain. + *) +type diff = { + commitments_and_ciphertexts : + (Sapling.Commitment.t * Sapling.Ciphertext.t) list; + nullifiers : Sapling.Nullifier.t list; +} + +let diff_encoding = + let open Data_encoding in + conv + (fun d -> (d.commitments_and_ciphertexts, d.nullifiers)) + (fun (commitments_and_ciphertexts, nullifiers) -> + (match commitments_and_ciphertexts with + | [] -> () + | (_cm_hd, ct_hd) :: rest -> + let memo_size = Sapling.Ciphertext.get_memo_size ct_hd in + List.iter + (fun (_cm, ct) -> + assert ( + Compare.Int.(Sapling.Ciphertext.get_memo_size ct = memo_size))) + rest) ; + {commitments_and_ciphertexts; nullifiers}) + (obj2 + (req + "commitments_and_ciphertexts" + (list (tup2 Sapling.Commitment.encoding Sapling.Ciphertext.encoding))) + (req "nullifiers" (list Sapling.Nullifier.encoding))) + +module Memo_size = struct + type t = int + + let encoding = Data_encoding.uint16 + + let equal = Compare.Int.( = ) + + let max_uint16 = 0xffff + + let max_uint16_z = Z.of_int max_uint16 + + let err = + Error + ("a positive 16-bit integer (between 0 and " ^ string_of_int max_uint16 + ^ ")") + + let parse_z z = + if Compare.Z.(Z.zero <= z) && Compare.Z.(z <= max_uint16_z) then + Ok (Z.to_int z) + else err + + let unparse_to_z = Z.of_int +end + +let transaction_get_memo_size (transaction : Sapling.UTXO.transaction) = + match transaction.outputs with + | [] -> None + | {ciphertext; _} :: _ -> + (* Encoding ensures all ciphertexts have the same memo size. *) + Some (Sapling.Ciphertext.get_memo_size ciphertext) + +open Cache_memory_helpers + +(* This should be exported by [lib_sapling] rather than implemented here. *) +let input_in_memory_size = + (* type input = + * Sapling.UTXO.input = { + * cv : Sapling.CV.t; + * nf : Sapling.Nullifier.t; + * rk : Sapling.UTXO.rk; + * proof_i : Sapling.UTXO.spend_proof; + * signature : Sapling.UTXO.spend_sig; + * } *) + let cv_size = string_size_gen 32 in + let nf_size = string_size_gen 32 in + let rk_size = string_size_gen 32 in + let proof_i_size = string_size_gen @@ (48 + 96 + 48) in + let signature_size = string_size_gen 64 in + header_size +! (word_size *? 5) +! cv_size +! nf_size +! rk_size + +! proof_i_size +! signature_size + +let ciphertext_size = + (* type t = { + * cv : CV.t; + * epk : DH.epk; + * payload_enc : Bytes.t; + * nonce_enc : Crypto_box.nonce; + * payload_out : Bytes.t; + * nonce_out : Crypto_box.nonce; + * } *) + let cv_size = string_size_gen 32 in + let epk_size = string_size_gen 32 in + let nonce_enc_size = + string_size_gen 24 + (* from lib_hacl_glue/unix/hacl.ml:Nonce.size *) + in + let payload_out_size = + string_size_gen (32 + 32 + 16) + (* from lib_sapling/core.ml:Ciphertext.encoding *) + in + let nonce_out_size = string_size_gen 24 in + let fixed_payload_data_size = + 11 + 8 + 32 + 16 + 4 + (* from lib_sapling/core.ml:Ciphertext.get_memo_size *) + in + + fun memo_size -> + let payload_size = string_size_gen (memo_size + fixed_payload_data_size) in + header_size +! (word_size *? 6) +! cv_size +! epk_size +! payload_size + +! nonce_enc_size +! payload_out_size +! nonce_out_size + +let output_in_memory_size = + (* type output = { + * cm : Commitment.t; + * proof_o : output_proof; + * ciphertext : Ciphertext.t; + * } *) + let cm_size = string_size_gen 32 in + let proof_o_size = string_size_gen @@ (48 + 96 + 48) in + let ciphertext_size = ciphertext_size in + + fun memo_size -> + header_size +! (word_size *? 3) +! cm_size +! proof_o_size + +! ciphertext_size memo_size + +(** Returns an approximation of the in-memory size of a Sapling transaction. *) +let transaction_in_memory_size (transaction : Sapling.UTXO.transaction) = + (* type transaction = + * transaction = { + * inputs : Sapling.UTXO.input list; + * outputs : Sapling.UTXO.output list; + * binding_sig : Sapling.UTXO.binding_sig; + * balance : int64; + * root : Sapling.Hash.t; + * } *) + let binding_sig_size = string_size_gen 64 in + let balance_size = int64_size in + let root_size = string_size_gen 32 in + let inputs = List.length transaction.inputs in + let outputs = List.length transaction.outputs in + let memo_size = + Option.value ~default:0 (transaction_get_memo_size transaction) + in + header_size +! (word_size *? 5) + +! (list_cell_size input_in_memory_size *? inputs) + +! (list_cell_size (output_in_memory_size memo_size) *? outputs) + +! binding_sig_size +! balance_size +! root_size + +(** Returns an approximation of the in-memory size of a Sapling diff. *) +let diff_in_memory_size ({commitments_and_ciphertexts; nullifiers} : diff) = + let cms_and_cts = List.length commitments_and_ciphertexts in + let nfs = List.length nullifiers in + let cm_size = string_size_gen 32 in + let nf_size = string_size_gen 32 in + let memo_size = + (* All memo_size in a diff should be equal (see invariant enforced by + [diff] encoding above) *) + match commitments_and_ciphertexts with + | [] -> 0 + | (_, ct) :: _ -> Sapling.Ciphertext.get_memo_size ct + in + header_size +! (word_size *? 2) + +! list_cell_size (boxed_tup2 cm_size (ciphertext_size memo_size)) + *? cms_and_cts + +! (list_cell_size nf_size *? nfs) diff --git a/src/proto_012_PsiThaCa/lib_protocol/sapling_services.ml b/src/proto_012_PsiThaCa/lib_protocol/sapling_services.ml new file mode 100644 index 000000000000..738cecaaff22 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/sapling_services.ml @@ -0,0 +1,103 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +let custom_root = + (RPC_path.(open_root / "context" / "sapling") + : RPC_context.t RPC_path.context) + +type diff_query = { + offset_commitment : Int64.t option; + offset_nullifier : Int64.t option; +} + +module S = struct + module Args = struct + type ('query_type, 'output_type) t = { + name : string; + description : string; + query : 'query_type RPC_query.t; + output : 'output_type Data_encoding.t; + f : context -> Sapling.Id.t -> 'query_type -> 'output_type tzresult Lwt.t; + } + + let get_diff_query : diff_query RPC_query.t = + let open RPC_query in + query (fun offset_commitment offset_nullifier -> + {offset_commitment; offset_nullifier}) + |+ opt_field + ~descr: + "Commitments and ciphertexts are returned from the specified \ + offset up to the most recent." + "offset_commitment" + RPC_arg.uint63 + (fun {offset_commitment; _} -> offset_commitment) + |+ opt_field + ~descr: + "Nullifiers are returned from the specified offset up to the most \ + recent." + "offset_nullifier" + RPC_arg.uint63 + (fun {offset_nullifier; _} -> offset_nullifier) + |> seal + + let encoding = + let open Data_encoding in + merge_objs (obj1 (req "root" Sapling.root_encoding)) Sapling.diff_encoding + + let get_diff = + { + name = "get_diff"; + description = + "Returns the root and a diff of a state starting from an optional \ + offset which is zero by default."; + query = get_diff_query; + output = encoding; + f = + (fun ctxt id {offset_commitment; offset_nullifier} -> + Sapling.get_diff ctxt id ?offset_commitment ?offset_nullifier ()); + } + end + + let make_service Args.{name; description; query; output; f} = + let path = RPC_path.(custom_root /: Sapling.rpc_arg / name) in + let service = RPC_service.get_service ~description ~query ~output path in + (service, fun ctxt id q () -> f ctxt id q) + + let get_diff = make_service Args.get_diff +end + +let register () = + let reg ~chunked (service, f) = + Services_registration.register1 ~chunked service f + in + reg ~chunked:false S.get_diff + +let mk_call1 (service, _f) ctxt block id q = + RPC_context.make_call1 service ctxt block id q () + +let get_diff ctxt block id ?offset_commitment ?offset_nullifier () = + mk_call1 S.get_diff ctxt block id {offset_commitment; offset_nullifier} diff --git a/src/proto_012_PsiThaCa/lib_protocol/sapling_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/sapling_storage.ml new file mode 100644 index 000000000000..167f75f1f913 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/sapling_storage.ml @@ -0,0 +1,489 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type COMMITMENTS = sig + val init : Raw_context.t -> Storage.Sapling.id -> Raw_context.t Lwt.t + + val default_root : Sapling.Hash.t + + val get_root : + Raw_context.t -> + Storage.Sapling.id -> + (Raw_context.t * Sapling.Hash.t) tzresult Lwt.t + + val add : + Raw_context.t -> + Storage.Sapling.id -> + Sapling.Commitment.t list -> + int64 -> + (Raw_context.t * int) tzresult Lwt.t + + val get_from : + Raw_context.t -> + Storage.Sapling.id -> + int64 -> + Sapling.Commitment.t list tzresult Lwt.t +end + +module Commitments : COMMITMENTS = struct + module H = Sapling.Hash + + (** Incremental Merkle Tree + * + * A tree of height h contains 2^h leaves and h+1 levels of nodes with + * leaves at level 0 and root at level h. + * + * The leaves are commitments and the tree it is treated as always filled + * with a default value H.uncommitted. This allows to have proofs of + * membership, or witnesses, of fixed size. + * + * All the nodes at the same level of an empty tree have the same hash, + * which can be computed from the default value of the leaves. This is + * stored in the [uncommitted] list. + * + * Any subtree filled with default values is represented by the Empty + * constructor and given its height it's possible to compute its hash + * using the [uncommitted] list. + * + * The leaves are indexed by their position [pos], ranging from 0 to + * (2^h)-1. The encoding of [pos] limits the possible size of the tree. + * In any case the only valid height for the Sapling library is 32, so even + * if the library encodes positions as uint64, they never exceed uint32. + * + * The tree is incremental in the sense that leaves cannot be modified but + * only added and exclusively in successive positions. + * + * Given that elements are added and retrieved by position, it is possible + * to use this information to efficiently navigate the tree. + * Given a tree of height [h] and a position [pos], if pos < pow2 (h-1) only + * the left subtree needs to be inspected recursively. Otherwise only the + * right needs to be visited, decreasing [pos] by [pow2 (h-1)]. + * + * In order to avoid storing the height for each subtree (or worse + * recomputing it), each function with suffix `_height` expects the height + * of the tree as parameter. These functions are only for internal use and + * are later aliased by functions using the default height of a Sapling + * incremental Merkle tree. + * + * Each node of the tree is indexed starting from the root at index 1, + * followed by its left child at index 2, right child at index 3 and so on + * until the last leaf at index 2^(depth+1)-1, or in terms of height + * 2^(32 - height +1) -1. + * The functions left and right return the index of the left and right child + * of a node. + *) + + let pow2 h = Int64.(shift_left 1L h) + + let max_height = 32 + + let max_size = pow2 max_height + + let assert_node node height = + assert ( + let first_of_height = pow2 (max_height - height) in + let first_of_next_height = Int64.shift_left first_of_height 1 in + Compare.Int64.(node >= first_of_height && node < first_of_next_height)) + + let assert_height height = + assert (Compare.Int.(height >= 0 && height <= max_height)) + + let assert_pos pos height = + assert (Compare.Int64.(pos >= 0L && pos <= pow2 height)) + + let default_root = H.uncommitted ~height:max_height + + let init = Storage.Sapling.commitments_init + + let get_root_height ctx id node height = + assert_node node height ; + assert_height height ; + Storage.Sapling.Commitments.find (ctx, id) node >|=? function + | (ctx, None) -> + let hash = H.uncommitted ~height in + (ctx, hash) + | (ctx, Some hash) -> (ctx, hash) + + let left node = Int64.mul node 2L + + let right node = Int64.(add (mul node 2L) 1L) + + (* Not tail-recursive *) + let rec split_at n l = + if Compare.Int64.(n = 0L) then ([], l) + else + match l with + | [] -> ([], l) + | x :: xs -> + let (l1, l2) = split_at Int64.(pred n) xs in + (x :: l1, l2) + + (* [insert tree height pos cms] inserts the list of commitments + [cms] in the tree [tree] of height [height] at the next position [pos]. + Returns the context, the size of the added storage, and the hash of the + node. Not tail-recursive. + Pre: incremental tree /\ + size tree + List.length cms <= pow2 height /\ + pos = size tree /\ + Post: incremental tree /\ + to_list (insert tree height pos cms) = to_list t @ cms *) + let[@coq_struct "height"] rec insert ctx id node height pos cms = + assert_node node height ; + assert_height height ; + assert_pos pos height ; + match (height, cms) with + | (_, []) -> + get_root_height ctx id node height >|=? fun (ctx, h) -> (ctx, 0, h) + | (0, [cm]) -> + let h = H.of_commitment cm in + Storage.Sapling.Commitments.init (ctx, id) node h + >|=? fun (ctx, size) -> (ctx, size, h) + | _ -> + let height = height - 1 in + (if Compare.Int64.(pos < pow2 height) then + let at = Int64.(sub (pow2 height) pos) in + let (cml, cmr) = split_at at cms in + insert ctx id (left node) height pos cml >>=? fun (ctx, size_l, hl) -> + insert ctx id (right node) height 0L cmr >|=? fun (ctx, size_r, hr) -> + (ctx, size_l + size_r, hl, hr) + else + get_root_height ctx id (left node) height >>=? fun (ctx, hl) -> + let pos = Int64.(sub pos (pow2 height)) in + insert ctx id (right node) height pos cms + >|=? fun (ctx, size_r, hr) -> (ctx, size_r, hl, hr)) + >>=? fun (ctx, size_children, hl, hr) -> + let h = H.merkle_hash ~height hl hr in + Storage.Sapling.Commitments.add (ctx, id) node h + >|=? fun (ctx, size, _existing) -> (ctx, size + size_children, h) + + let[@coq_struct "height"] rec fold_from_height ctx id node ~pos ~f ~acc height + = + assert_node node height ; + assert_height height ; + assert_pos pos height ; + Storage.Sapling.Commitments.find (ctx, id) node + (* we don't count gas for this function, it is called only by RPC *) + >>=? + function + | (_ctx, None) -> return acc + | (_ctx, Some h) -> + if Compare.Int.(height = 0) then return (f acc h) + else + let full = pow2 (height - 1) in + if Compare.Int64.(pos < full) then + fold_from_height ctx id (left node) ~pos ~f ~acc (height - 1) + >>=? fun acc -> + (* Setting pos to 0 folds on the whole right subtree *) + fold_from_height ctx id (right node) ~pos:0L ~f ~acc (height - 1) + else + let pos = Int64.(sub pos full) in + fold_from_height ctx id (right node) ~pos ~f ~acc (height - 1) + + let root_node = 1L + + let get_root ctx id = get_root_height ctx id root_node max_height + + (* Expects pos to be the next position to insert. Pos is also the number of + inserted leaves. + A commitment should always be added together with a corresponding + ciphertext in the same position. + [insert] is not tail-recursive so we put a hard limit on the size of the + list of commitments. The use of [split_at] has O(n logn) complexity that is + less relevant on a smaller list. *) + let add ctx id cms pos = + let l = List.length cms in + assert (Compare.Int.(l <= 1000)) ; + let n' = Int64.(add pos (of_int l)) in + assert (Compare.Int64.(n' <= max_size)) ; + insert ctx id root_node max_height pos cms >|=? fun (ctx, size, _h) -> + (ctx, size) + + let get_from ctx id pos = + fold_from_height + ctx + id + root_node + ~pos + ~f:(fun acc c -> H.to_commitment c :: acc) + ~acc:[] + max_height + >|=? fun l -> List.rev l +end + +module Ciphertexts = struct + let init ctx id = Storage.Sapling.ciphertexts_init ctx id + + (* a ciphertext should always be added together with a corresponding + commitment in the same position *) + let add ctx id c pos = Storage.Sapling.Ciphertexts.init (ctx, id) pos c + + let get_from ctx id offset = + let rec aux (ctx, acc) pos = + Storage.Sapling.Ciphertexts.find (ctx, id) pos >>=? fun (ctx, c) -> + match c with + | None -> return (ctx, List.rev acc) + | Some c -> aux (ctx, c :: acc) (Int64.succ pos) + in + aux (ctx, []) offset +end + +(* Collection of nullifiers w/o duplicates, append-only. It has a dual + implementation with a hash map for constant `mem` and with a ordered set to + retrieve by position. *) +module Nullifiers = struct + let init = Storage.Sapling.nullifiers_init + + let size ctx id = Storage.Sapling.Nullifiers_size.get (ctx, id) + + let mem ctx id nf = Storage.Sapling.Nullifiers_hashed.mem (ctx, id) nf + + (* Allows for duplicates as they are already checked by verify_update before + updating the state. + Not tail-recursive so we put a hard limit on the size of the + list of nullifiers. *) + let add ctx id nfs = + assert (Compare.Int.(List.compare_length_with nfs 1000 <= 0)) ; + size ctx id >>=? fun nf_start_pos -> + List.fold_right_es + (fun nf (ctx, pos, acc_size) -> + Storage.Sapling.Nullifiers_hashed.init (ctx, id) nf + >>=? fun (ctx, size) -> + Storage.Sapling.Nullifiers_ordered.init (ctx, id) pos nf >|=? fun ctx -> + (ctx, Int64.succ pos, Z.add acc_size (Z.of_int size))) + nfs + (ctx, nf_start_pos, Z.zero) + >>=? fun (ctx, nf_end_pos, size) -> + Storage.Sapling.Nullifiers_size.update (ctx, id) nf_end_pos >|=? fun ctx -> + (ctx, size) + + let get_from ctx id offset = + let[@coq_struct "pos"] rec aux acc pos = + Storage.Sapling.Nullifiers_ordered.find (ctx, id) pos >>=? function + | None -> return @@ List.rev acc + | Some c -> aux (c :: acc) (Int64.succ pos) + in + aux [] offset +end + +(** Bounded queue of roots. The full size is initialized with the default + uncommitted root, that's why roots storage doesn't need to be carbonated. + A maximum of one new root is added per protocol level. + If multiple transactions for the same shielded pool are processed during the + same contract call or several calls in the same block, only the last root + will be stored. + This property prevents transactions in the same block from depending on each + other and guarantees that a transaction will be valid for a least two hours + (hence the 120 size) after being forged. *) +module Roots = struct + let size = 120l + + (* pos is the index of the last inserted element *) + + let get ctx id = + Storage.Sapling.Roots_pos.get (ctx, id) >>=? fun pos -> + Storage.Sapling.Roots.get (ctx, id) pos + + let init ctx id = + let[@coq_struct "pos"] rec aux ctx pos = + if Compare.Int32.(pos < 0l) then return ctx + else + Storage.Sapling.Roots.init (ctx, id) pos Commitments.default_root + >>=? fun ctx -> aux ctx (Int32.pred pos) + in + aux ctx (Int32.pred size) >>=? fun ctx -> + Storage.Sapling.Roots_pos.init (ctx, id) 0l >>=? fun ctx -> + let level = (Raw_context.current_level ctx).level in + Storage.Sapling.Roots_level.init (ctx, id) level + + let mem ctx id root = + Storage.Sapling.Roots_pos.get (ctx, id) >>=? fun start_pos -> + let rec aux pos = + Storage.Sapling.Roots.get (ctx, id) pos >>=? fun hash -> + if Compare.Int.(Sapling.Hash.compare hash root = 0) then return true + else + let pos = Int32.(pred pos) in + let pos = if Compare.Int32.(pos < 0l) then Int32.pred size else pos in + if Compare.Int32.(pos = start_pos) then return false else aux pos + in + aux start_pos + + (* allows duplicates *) + let add ctx id root = + Storage.Sapling.Roots_pos.get (ctx, id) >>=? fun pos -> + let level = (Raw_context.current_level ctx).level in + Storage.Sapling.Roots_level.get (ctx, id) >>=? fun stored_level -> + if Raw_level_repr.(stored_level = level) then + (* if there is another add during the same level, it will over-write on + the same position *) + Storage.Sapling.Roots.add (ctx, id) pos root >|= ok + else + (* it's the first add for this level *) + (* TODO(samoht): why is it using [update] and not [init] then? *) + Storage.Sapling.Roots_level.update (ctx, id) level >>=? fun ctx -> + let pos = Int32.rem (Int32.succ pos) size in + Storage.Sapling.Roots_pos.update (ctx, id) pos >>=? fun ctx -> + Storage.Sapling.Roots.add (ctx, id) pos root >|= ok +end + +(** This type links the permanent state stored in the context at the specified + id together with the ephemeral diff managed by the Michelson + interpreter. After a successful execution the diff can be applied to update + the state at id. The first time a state is created its id is None, one will + be assigned after the first application. *) +type state = { + id : Lazy_storage_kind.Sapling_state.Id.t option; + diff : Sapling_repr.diff; + memo_size : Sapling_repr.Memo_size.t; +} + +let empty_diff = + Sapling_repr.{commitments_and_ciphertexts = []; nullifiers = []} + +let empty_state ?id ~memo_size () = {id; diff = empty_diff; memo_size} + +(** Returns a state from an existing id. *) +let state_from_id ctxt id = + Storage.Sapling.Memo_size.get (ctxt, id) >|=? fun memo_size -> + ({id = Some id; diff = empty_diff; memo_size}, ctxt) + +let rpc_arg = Storage.Sapling.rpc_arg + +let get_memo_size ctx id = Storage.Sapling.Memo_size.get (ctx, id) + +let init ctx id ~memo_size = + Storage.Sapling.Memo_size.add (ctx, id) memo_size >>= fun ctx -> + Storage.Sapling.Commitments_size.add (ctx, id) Int64.zero >>= fun ctx -> + Commitments.init ctx id >>= fun ctx -> + Nullifiers.init ctx id >>= fun ctx -> + Roots.init ctx id >>=? fun ctx -> Ciphertexts.init ctx id >|= ok + +(* Gas costs for apply_diff. *) +let sapling_apply_diff_cost ~inputs ~outputs = + let open Saturation_repr in + add + (safe_int 1_300_000) + (add + (scale_fast (mul_safe_of_int_exn 5_000) (safe_int inputs)) + (scale_fast (mul_safe_of_int_exn 55_000) (safe_int outputs))) + +(** Applies a diff to a state id stored in the context. Updates Commitments, + Ciphertexts and Nullifiers using the diff and updates the Roots using the + new Commitments tree. *) +let apply_diff ctx id diff = + let open Sapling_repr in + let nb_commitments = List.length diff.commitments_and_ciphertexts in + let nb_nullifiers = List.length diff.nullifiers in + let sapling_cost = + sapling_apply_diff_cost ~inputs:nb_nullifiers ~outputs:nb_commitments + in + Raw_context.consume_gas ctx sapling_cost >>?= fun ctx -> + Storage.Sapling.Commitments_size.get (ctx, id) >>=? fun cm_start_pos -> + let cms = List.rev_map fst diff.commitments_and_ciphertexts in + Commitments.add ctx id cms cm_start_pos >>=? fun (ctx, size) -> + Storage.Sapling.Commitments_size.update + (ctx, id) + (Int64.add cm_start_pos (Int64.of_int nb_commitments)) + >>=? fun ctx -> + List.fold_right_es + (fun (_cm, cp) (ctx, pos, acc_size) -> + Ciphertexts.add ctx id cp pos >|=? fun (ctx, size) -> + (ctx, Int64.succ pos, Z.add acc_size (Z.of_int size))) + diff.commitments_and_ciphertexts + (ctx, cm_start_pos, Z.of_int size) + >>=? fun (ctx, _ct_end_pos, size) -> + Nullifiers.add ctx id diff.nullifiers >>=? fun (ctx, size_nf) -> + let size = Z.add size size_nf in + match diff.commitments_and_ciphertexts with + | [] -> + (* avoids adding duplicates to Roots *) + return (ctx, size) + | _ :: _ -> + Commitments.get_root ctx id >>=? fun (ctx, root) -> + Roots.add ctx id root >|=? fun ctx -> (ctx, size) + +let add {id; diff; memo_size} cm_cipher_list = + assert ( + List.for_all + (fun (_cm, cipher) -> + Compare.Int.(Sapling.Ciphertext.get_memo_size cipher = memo_size)) + cm_cipher_list) ; + { + id; + diff = + { + diff with + commitments_and_ciphertexts = + List.rev cm_cipher_list @ diff.commitments_and_ciphertexts; + }; + memo_size; + } + +let root_mem ctx {id; _} tested_root = + match id with + | Some id -> Roots.mem ctx id tested_root + | None -> + return + Compare.Int.( + Sapling.Hash.compare tested_root Commitments.default_root = 0) + +(* to avoid a double spend we need to check the disk AND the diff *) +let nullifiers_mem ctx {id; diff; _} nf = + let exists_in_diff = + List.exists + (fun v -> Compare.Int.(Sapling.Nullifier.compare nf v = 0)) + diff.nullifiers + in + if exists_in_diff then return (ctx, true) + else + match id with + | None -> return (ctx, false) + | Some id -> Nullifiers.mem ctx id nf + +(* Allows for duplicates as they are already checked by verify_update before + updating the state. *) +let nullifiers_add {id; diff; memo_size} nf = + {id; diff = {diff with nullifiers = nf :: diff.nullifiers}; memo_size} + +type root = Sapling.Hash.t + +let root_encoding = Sapling.Hash.encoding + +let get_diff ctx id ?(offset_commitment = 0L) ?(offset_nullifier = 0L) () = + if + not + Sapling.Commitment.( + valid_position offset_commitment && valid_position offset_nullifier) + then failwith "Invalid argument." + else + Commitments.get_from ctx id offset_commitment >>=? fun commitments -> + Roots.get ctx id >>=? fun root -> + Nullifiers.get_from ctx id offset_nullifier >>=? fun nullifiers -> + Ciphertexts.get_from ctx id offset_commitment + (* we don't count gas for RPCs *) + >|=? fun (_ctx, ciphertexts) -> + match List.combine ~when_different_lengths:() commitments ciphertexts with + | Error () -> failwith "Invalid argument." + | Ok commitments_and_ciphertexts -> + (root, Sapling_repr.{commitments_and_ciphertexts; nullifiers}) diff --git a/src/proto_012_PsiThaCa/lib_protocol/sapling_validator.ml b/src/proto_012_PsiThaCa/lib_protocol/sapling_validator.ml new file mode 100644 index 000000000000..ce0e41e0133c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/sapling_validator.ml @@ -0,0 +1,108 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Check that each nullifier is not already present in the state and add it. + Important to avoid spending the same input twice in a transaction. *) +let rec check_and_update_nullifiers ctxt state inputs = + match inputs with + | [] -> return (ctxt, Some state) + | input :: inputs -> ( + Sapling_storage.nullifiers_mem ctxt state Sapling.UTXO.(input.nf) + >>=? function + | (ctxt, true) -> return (ctxt, None) + | (ctxt, false) -> + let state = + Sapling_storage.nullifiers_add state Sapling.UTXO.(input.nf) + in + check_and_update_nullifiers ctxt state inputs) + +let verify_update : + Raw_context.t -> + Sapling_storage.state -> + Sapling_repr.transaction -> + string -> + (Raw_context.t * (Int64.t * Sapling_storage.state) option) tzresult Lwt.t = + fun ctxt state transaction key -> + (* Check the transaction *) + (* To avoid overflowing the balance, the number of inputs and outputs must be + bounded. + Ciphertexts' memo_size must match the state's memo_size. + These constraints are already enforced at the encoding level. *) + assert (Compare.Int.(List.compare_length_with transaction.inputs 5208 <= 0)) ; + assert (Compare.Int.(List.compare_length_with transaction.outputs 2019 <= 0)) ; + let pass = + List.for_all + (fun output -> + Compare.Int.( + Sapling.Ciphertext.get_memo_size Sapling.UTXO.(output.ciphertext) + = state.memo_size)) + transaction.outputs + in + if not pass then return (ctxt, None) + else + (* Check the root is a recent state *) + Sapling_storage.root_mem ctxt state transaction.root >>=? fun pass -> + if not pass then return (ctxt, None) + else + check_and_update_nullifiers ctxt state transaction.inputs >|=? function + | (ctxt, None) -> (ctxt, None) + | (ctxt, Some state) -> + Sapling.Verification.with_verification_ctx (fun vctx -> + let pass = + (* Check all the output ZK proofs *) + List.for_all + (fun output -> Sapling.Verification.check_output vctx output) + transaction.outputs + in + if not pass then (ctxt, None) + else + let pass = + (* Check all the input Zk proofs and signatures *) + List.for_all + (fun input -> + Sapling.Verification.check_spend + vctx + input + transaction.root + key) + transaction.inputs + in + if not pass then (ctxt, None) + else + let pass = + (* Check the signature and balance of the whole transaction *) + Sapling.Verification.final_check vctx transaction key + in + if not pass then (ctxt, None) + else + (* update tree *) + let list_to_add = + List.map + (fun output -> + Sapling.UTXO.(output.cm, output.ciphertext)) + transaction.outputs + in + let state = Sapling_storage.add state list_to_add in + (ctxt, Some (transaction.balance, state))) diff --git a/src/proto_012_PsiThaCa/lib_protocol/saturation_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/saturation_repr.ml new file mode 100644 index 000000000000..abdbb379d3e2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/saturation_repr.ml @@ -0,0 +1,170 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* let () = assert (Sys.int_size = 63) *) + +type _ t = int + +type mul_safe + +type may_saturate + +let may_saturate : _ t -> may_saturate t = fun x -> x + +let to_int x = x + +let ( < ) : _ t -> _ t -> bool = Compare.Int.( < ) + +let ( <= ) : _ t -> _ t -> bool = Compare.Int.( <= ) + +let ( > ) : _ t -> _ t -> bool = Compare.Int.( > ) + +let ( >= ) : _ t -> _ t -> bool = Compare.Int.( >= ) + +let ( = ) : _ t -> _ t -> bool = Compare.Int.( = ) + +let equal = ( = ) + +let ( <> ) : _ t -> _ t -> bool = Compare.Int.( <> ) + +let max : _ t -> _ t -> _ t = fun x y -> if x >= y then x else y + +let min : _ t -> _ t -> _ t = fun x y -> if x >= y then y else x + +let compare : _ t -> _ t -> _ t = Compare.Int.compare + +let saturated = max_int + +let of_int_opt t = if t >= 0 && t < saturated then Some t else None + +let of_z_opt z = + match Z.to_int z with int -> of_int_opt int | exception Z.Overflow -> None + +let to_z x = Z.of_int x + +let saturate_if_undef = function None -> saturated | Some x -> x + +let safe_int x = of_int_opt x |> saturate_if_undef + +let numbits x = + let x = ref x and n = ref 0 in + (let y = !x lsr 32 in + if y <> 0 then ( + n := !n + 32 ; + x := y)) ; + (let y = !x lsr 16 in + if y <> 0 then ( + n := !n + 16 ; + x := y)) ; + (let y = !x lsr 8 in + if y <> 0 then ( + n := !n + 8 ; + x := y)) ; + (let y = !x lsr 4 in + if y <> 0 then ( + n := !n + 4 ; + x := y)) ; + (let y = !x lsr 2 in + if y <> 0 then ( + n := !n + 2 ; + x := y)) ; + if !x lsr 1 <> 0 then !n + 2 else !n + !x + +let zero = 0 + +let one = 1 + +let small_enough z = + (* The following literal triggers an error if compiled under 32-bit + architectures, please do not modify it. This is a static way to + ensure that this file is compiled under a 64-bit architecture. *) + z land 0x7fffffff80000000 = 0 + +let mul_safe x = if small_enough x then Some x else None + +let mul_safe_exn x = + if small_enough x then x + else failwith (Format.sprintf "mul_safe_exn: %d must be below 2147483648" x) + +let mul_safe_of_int_exn x = + Option.bind (of_int_opt x) mul_safe |> function + | None -> + failwith + (Format.sprintf "mul_safe_of_int_exn: %d must be below 2147483648" x) + | Some x -> x + +(* If [x] is positive, shifting to the right will produce a number + which is positive and is less than [x]. *) +let shift_right x y = (x :> int) lsr y + +let shift_left x y = + if shift_right saturated y < x then saturated else (x :> int) lsl y + +let mul x y = + (* assert (x >= 0 && y >= 0); *) + match x with + | 0 -> 0 + | x -> + if small_enough x && small_enough y then x * y + else if Compare.Int.(y > saturated / x) then saturated + else x * y + +let mul_fast x y = x * y + +let scale_fast x y = + if x = 0 then 0 + else if small_enough y then x * y + else if Compare.Int.(y > saturated / x) then saturated + else x * y + +let add x y = + let z = x + y in + if Compare.Int.(z >= 0) then z else saturated + +let succ x = add one x + +let sub x y = Compare.Int.max (x - y) 0 + +let sub_opt x y = + let s = x - y in + if Compare.Int.(s >= 0) then Some s else None + +(* Notice that Z.erem does not behave as mod on negative numbers. + Fortunately, the inhabitant of [t] are non-negative. *) +let erem x y = x mod y + +let ediv x y = x / y + +let t_to_z_exn z = + match of_z_opt z with + | None -> + (* since the encoding is applied to values of type [t]. *) assert false + | Some x -> x + +let z_encoding = Data_encoding.(check_size 9 (conv to_z t_to_z_exn z)) + +let n_encoding = Data_encoding.(check_size 9 (conv to_z t_to_z_exn n)) + +let pp fmt x = Format.pp_print_int fmt x diff --git a/src/proto_012_PsiThaCa/lib_protocol/saturation_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/saturation_repr.mli new file mode 100644 index 000000000000..d937abc29813 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/saturation_repr.mli @@ -0,0 +1,204 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module provides saturated arithmetic between 0 and 2^62 - 1. + + This means that the arithmetic operations provided by this module + do not overflow. If an operation would produce an integer [x] + greater than [2 ^ 62 - 1], it is [saturated] to this + value. Similarly, if an operation would produce a negative integer, + it outputs [zero] instead. + + This saturation arithmetic is used to monitor gas levels. While the + gas model can produce values beyond 2^62 - 1, there is no point in + distinguishing these values from 2^62 - 1 because the amount of gas + available is significantly lower than this limit. + + Notice that most saturation arithmetic operations do not behave + as their standard counterparts when one of their operands is + saturated. For instance, + + (saturated + saturated) - saturated = 0 + + For more information about saturation arithmetic, take a look at: + + https://en.wikipedia.org/wiki/Saturation_arithmetic + +*) + +(** An integer of type ['a t] is between [0] and [saturated]. + + The type parameter ['a] is [mul_safe] if the integer is known + not to overflow when multiplied with another [mul_safe t]. + + The type parameter ['a] is [may_saturate] if the integer is + not known to be sufficiently small to prevent overflow during + multiplication. + +*) +type 'a t = private int + +type mul_safe + +type may_saturate + +val may_saturate : _ t -> may_saturate t + +(** [to_int x] returns the underlying integer representing [x]. *) +val to_int : 'a t -> int + +(** 0 *) +val zero : _ t + +(** 1 *) +val one : _ t + +(** 2^62 - 1 *) +val saturated : may_saturate t + +(** We inherit the order over native integers. *) +val ( >= ) : _ t -> _ t -> bool + +val ( > ) : _ t -> _ t -> bool + +val ( <= ) : _ t -> _ t -> bool + +val ( < ) : _ t -> _ t -> bool + +val ( = ) : _ t -> _ t -> bool + +val ( <> ) : _ t -> _ t -> bool + +val equal : _ t -> _ t -> bool + +val min : 'a t -> 'a t -> 'a t + +val max : 'a t -> 'a t -> 'a t + +val compare : 'a t -> 'b t -> int + +(** [numbits x] returns the number of bits used in the binary representation + of [x]. *) +val numbits : 'a t -> int + +(** [shift_right x y] behaves like a logical shift of [x] by [y] bits + to the right. [y] must be between 0 and 63. *) +val shift_right : 'a t -> int -> 'a t + +(** [shift_left x y] behaves like a logical shift of [x] by [y] bits + to the left. [y] must be between 0 and 63. In cases where [x lsl y] + is overflowing, [shift_left x y] is [saturated]. *) +val shift_left : 'a t -> int -> 'a t + +(** [mul x y] behaves like multiplication between native integers as + long as its result stay below [saturated]. Otherwise, [mul] returns + [saturated]. *) +val mul : _ t -> _ t -> may_saturate t + +(** [mul_safe x] returns a [mul_safe t] only if [x] does not trigger + overflows when multiplied with another [mul_safe t]. More precisely, + [x] is safe for fast multiplications if [x < 2147483648]. *) +val mul_safe : _ t -> mul_safe t option + +(** [mul_fast x y] exploits the fact that [x] and [y] are known not to + provoke overflows during multiplication to perform a mere + multiplication. *) +val mul_fast : mul_safe t -> mul_safe t -> may_saturate t + +(** [scale_fast x y] exploits the fact that [x] is known not to + provoke overflows during multiplication to perform a + multiplication faster than [mul]. *) +val scale_fast : mul_safe t -> _ t -> may_saturate t + +(** [add x y] behaves like addition between native integers as long as + its result stay below [saturated]. Otherwise, [add] returns + [saturated]. *) +val add : _ t -> _ t -> may_saturate t + +(** [succ x] is like [add one x] *) +val succ : _ t -> may_saturate t + +(** [sub x y] behaves like subtraction between native integers as long + as its result stay positive. Otherwise, [sub] returns [zero]. + This function assumes that [x] is not saturated. +*) +val sub : 'a t -> _ t -> 'a t + +(** [sub_opt x y] behaves like subtraction between native integers as + long as its result stay positive. Otherwise, [sub] returns + [None]. *) +val sub_opt : 'a t -> _ t -> 'a t option + +(** [ediv x y] returns [x / y]. This operation never saturates, hence + it is exactly the same as its native counterpart. [y] is supposed + to be strictly greater than 0, otherwise this function raises + [Division_by_zero]. *) +val ediv : 'a t -> _ t -> 'a t + +(** [erem x y] returns [x mod y]. [y] is supposed to be strictly + greater than 0, otherwise this function raises + [Division_by_zero]. *) +val erem : _ t -> 'b t -> 'b t + +(** [of_int_opt x] returns [Some x] if [x >= 0] and [x < saturated], + and [None] otherwise. *) +val of_int_opt : int -> may_saturate t option + +(** [of_z_opt x] returns [Some x] if [x >= 0] and [x < saturated], + and [None] otherwise. *) +val of_z_opt : Z.t -> may_saturate t option + +(** When a saturated integer is sufficiently small (i.e. strictly less + than 2147483648), we can assign it the type [mul_safe S.t] to use + it within fast multiplications, named [S.scale_fast] and + [S.mul_fast]. + + The following function allows such type assignment but may raise an + exception if the assumption is wrong. Therefore, [mul_safe_exn] + should only be used to define toplevel values, so that these + exceptions can only occur during startup. + *) +val mul_safe_exn : may_saturate t -> mul_safe t + +(** [mul_safe_of_int_exn x] is the composition of [of_int_opt] and + [mul_safe] in the option monad. This function raises [Invalid_argument] + if [x] is not safe. This function should be used on integer literals + that are obviously [mul_safe]. *) +val mul_safe_of_int_exn : int -> mul_safe t + +(** [safe_int x] is [of_int_opt x |> saturate_if_undef]. *) +val safe_int : int -> may_saturate t + +(** [to_z z] is [Z.of_int]. *) +val to_z : _ t -> Z.t + +(** Encoding for [t] through the encoding for [z] integers. *) +val z_encoding : _ t Data_encoding.t + +(** Encoding for [t] through the encoding for non-negative integers. *) +val n_encoding : _ t Data_encoding.t + +(** A pretty-printer for native integers. *) +val pp : Format.formatter -> _ t -> unit diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_cache.ml b/src/proto_012_PsiThaCa/lib_protocol/script_cache.ml new file mode 100644 index 000000000000..b32aa4da5baa --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_cache.ml @@ -0,0 +1,109 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +type identifier = string + +let identifier_of_contract addr = Contract.to_b58check addr + +let contract_of_identifier identifier = Contract.of_b58check identifier + +type cached_contract = Script.t * Script_ir_translator.ex_script + +let load_and_elaborate ctxt addr = + Contract.get_script ctxt addr >>=? fun (ctxt, script) -> + match script with + | None -> return (ctxt, None) + | Some script -> + Script_ir_translator.( + parse_script ctxt script ~legacy:true ~allow_forged_in_storage:true + >>=? fun (ex_script, ctxt) -> + (* We consume gas after the fact in order to not have to instrument + [script_size] (for efficiency). + This is safe, as we already pay gas proportional to storage size + in [parse_script] beforehand. *) + let (size, cost) = script_size ex_script in + Gas.consume ctxt cost >>?= fun ctxt -> + return (ctxt, Some (script, ex_script, size))) + +module Client = struct + type cached_value = cached_contract + + let namespace = Cache.create_namespace "contract" + + let cache_index = 0 + + let value_of_identifier ctxt identifier = + (* + + I/O, deserialization, and elaboration of contracts scripts + are cached. + + *) + contract_of_identifier identifier >>?= fun addr -> + load_and_elaborate ctxt addr >>=? function + | (_, None) -> + (* [value_of_identifier ctxt k] is applied to identifiers stored + in the cache. Only script-based contracts that have been + executed are in the cache. Hence, [get_script] always + succeeds for these identifiers if [ctxt] and the [cache] are + properly synchronized by the shell. *) + failwith "Script_cache: Inconsistent script cache." + | (_, Some (unparsed_script, ir_script, _)) -> + return (unparsed_script, ir_script) +end + +module Cache = (val Cache.register_exn (module Client)) + +let find ctxt addr = + let identifier = identifier_of_contract addr in + Cache.find ctxt identifier >>=? function + | Some (unparsed_script, ex_script) -> + return (ctxt, identifier, Some (unparsed_script, ex_script)) + | None -> ( + load_and_elaborate ctxt addr >>=? function + | (ctxt, None) -> return (ctxt, identifier, None) + | (ctxt, Some (unparsed_script, script_ir, size)) -> + let cached_value = (unparsed_script, script_ir) in + Lwt.return + ( Cache.update ctxt identifier (Some (cached_value, size)) + >>? fun ctxt -> + ok (ctxt, identifier, Some (unparsed_script, script_ir)) )) + +let update ctxt identifier updated_script approx_size = + Cache.update ctxt identifier (Some (updated_script, approx_size)) + +let entries ctxt = + Cache.list_identifiers ctxt + |> List.map_e @@ fun (identifier, age) -> + contract_of_identifier identifier >|? fun contract -> (contract, age) + +let contract_rank ctxt addr = + Cache.identifier_rank ctxt (identifier_of_contract addr) + +let size = Cache.size + +let size_limit = Cache.size_limit diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_cache.mli b/src/proto_012_PsiThaCa/lib_protocol/script_cache.mli new file mode 100644 index 000000000000..641bad38e99a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_cache.mli @@ -0,0 +1,81 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module manages the cache for smart contracts. + + This cache must be consistent with the on-disk representation + of the smart contracts. In particular, [update] must be called + each time a contract storage is updated. + +*) + +open Alpha_context + +(** Each cached script has a unique identifier in the cache. *) +type identifier + +(** The cache holds the unparsed and the internal representation of + the contract. *) +type cached_contract = Script.t * Script_ir_translator.ex_script + +(** [find ctxt contract] returns [(ctxt', identifier, script)] where: + - [ctxt'] is [ctxt] with less gas; + - [identifier] is the identifier identifying the [contract] in the cache; + - [script = None] if there is no such contract in [ctxt]; + - [script = Some (unparsed_script, ir_script)] where + - [unparsed_script] is the contract source code and storage; + - [script_ir] is a typed internal representation of the contract, i.e., + the abstract syntax tree of its code as well as its storage. + + This function consumes gas depending on the cache. If the contract is not + in the cache, then the function also consumes the gas of [Contract.get_script] + and [Script_ir_translator.parse_script]. *) +val find : + context -> + Contract.t -> + (context * identifier * cached_contract option) tzresult Lwt.t + +(** [update ctxt identifier unparsed_script ir_script size] refreshes the + cached contract identified by [identifier] with a new [unparsed_script], + a new [ir_script], and a new size. *) +val update : context -> identifier -> cached_contract -> int -> context tzresult + +(** [entries ctxt] returns the contracts in the cache as well as their + respective size. The list is sorted by date of last modification: + the least recently updated entry comes first. *) +val entries : context -> (Contract.t * int) list tzresult + +(** [contract_rank ctxt contract] returns the number of contracts + older than [contract] in the cache of [ctxt]. This function + returns [None] if [contract] does not exist in the cache of + [ctxt]. *) +val contract_rank : context -> Contract.t -> int option + +(** [size ctxt] is an overapproximation of the cache size in + memory (in bytes). *) +val size : context -> int + +(** [size_limit ctxt] is the maximal size of the cache (in bytes). *) +val size_limit : context -> int diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_comparable.ml b/src/proto_012_PsiThaCa/lib_protocol/script_comparable.ml new file mode 100644 index 000000000000..ab542f4867f3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_comparable.ml @@ -0,0 +1,89 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Script_typed_ir + +let compare_address (x, ex) (y, ey) = + let lres = Contract.compare x y in + if Compare.Int.(lres = 0) then Compare.String.compare ex ey else lres + +type compare_comparable_cont = + | Compare_comparable : + 'a comparable_ty * 'a * 'a * compare_comparable_cont + -> compare_comparable_cont + | Compare_comparable_return : compare_comparable_cont + +let compare_comparable : type a. a comparable_ty -> a -> a -> int = + let rec compare_comparable : + type a. a comparable_ty -> compare_comparable_cont -> a -> a -> int = + fun kind k x y -> + match (kind, x, y) with + | (Unit_key _, (), ()) -> (apply [@tailcall]) 0 k + | (Never_key _, _, _) -> . + | (Signature_key _, x, y) -> (apply [@tailcall]) (Signature.compare x y) k + | (String_key _, x, y) -> (apply [@tailcall]) (Script_string.compare x y) k + | (Bool_key _, x, y) -> (apply [@tailcall]) (Compare.Bool.compare x y) k + | (Mutez_key _, x, y) -> (apply [@tailcall]) (Tez.compare x y) k + | (Key_hash_key _, x, y) -> + (apply [@tailcall]) (Signature.Public_key_hash.compare x y) k + | (Key_key _, x, y) -> + (apply [@tailcall]) (Signature.Public_key.compare x y) k + | (Int_key _, x, y) -> (apply [@tailcall]) (Script_int.compare x y) k + | (Nat_key _, x, y) -> (apply [@tailcall]) (Script_int.compare x y) k + | (Timestamp_key _, x, y) -> + (apply [@tailcall]) (Script_timestamp.compare x y) k + | (Address_key _, x, y) -> (apply [@tailcall]) (compare_address x y) k + | (Bytes_key _, x, y) -> (apply [@tailcall]) (Compare.Bytes.compare x y) k + | (Chain_id_key _, x, y) -> (apply [@tailcall]) (Chain_id.compare x y) k + | (Pair_key ((tl, _), (tr, _), _), (lx, rx), (ly, ry)) -> + (compare_comparable [@tailcall]) + tl + (Compare_comparable (tr, rx, ry, k)) + lx + ly + | (Union_key ((tl, _), _, _), L x, L y) -> + (compare_comparable [@tailcall]) tl k x y + | (Union_key _, L _, R _) -> -1 + | (Union_key _, R _, L _) -> 1 + | (Union_key (_, (tr, _), _), R x, R y) -> + (compare_comparable [@tailcall]) tr k x y + | (Option_key _, None, None) -> (apply [@tailcall]) 0 k + | (Option_key _, None, Some _) -> -1 + | (Option_key _, Some _, None) -> 1 + | (Option_key (t, _), Some x, Some y) -> + (compare_comparable [@tailcall]) t k x y + and apply ret k = + match (ret, k) with + | (0, Compare_comparable (ty, x, y, k)) -> + (compare_comparable [@tailcall]) ty k x y + | (0, Compare_comparable_return) -> 0 + | (ret, _) -> + (* ret <> 0, we perform an early exit *) + if Compare.Int.(ret > 0) then 1 else -1 + in + fun t -> compare_comparable t Compare_comparable_return + [@@coq_axiom_with_reason "non top-level mutually recursive function"] diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_comparable.mli b/src/proto_012_PsiThaCa/lib_protocol/script_comparable.mli new file mode 100644 index 000000000000..8f489511625a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_comparable.mli @@ -0,0 +1,29 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val compare_comparable : 'a Script_typed_ir.comparable_ty -> 'a -> 'a -> int + +val compare_address : Script_typed_ir.address -> Script_typed_ir.address -> int diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_expr_hash.ml b/src/proto_012_PsiThaCa/lib_protocol/script_expr_hash.ml new file mode 100644 index 000000000000..4b26c6d4234d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_expr_hash.ml @@ -0,0 +1,44 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let script_expr_hash = "\013\044\064\027" (* expr(54) *) + +module H = + Blake2B.Make + (Base58) + (struct + let name = "script_expr" + + let title = "A script expression ID" + + let b58check_prefix = script_expr_hash + + let size = None + end) + +include H +include Path_encoding.Make_hex (H) + +let () = Base58.check_encoded_prefix b58check_encoding "expr" 54 diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_expr_hash.mli b/src/proto_012_PsiThaCa/lib_protocol/script_expr_hash.mli new file mode 100644 index 000000000000..8ba38e2eaaf5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_expr_hash.mli @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** A specialized Blake2B implementation for hashing Michelson expressions. *) + +include S.HASH + +include Path_encoding.S with type t := t diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_int_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/script_int_repr.ml new file mode 100644 index 000000000000..f5eff71ab42c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_int_repr.ml @@ -0,0 +1,113 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type n = Natural_tag + +type z = Integer_tag + +(* We could define `num` as a GADT with constructors for `n` and `z`. + This would enable factorizing the code a bit in the Michelson interpreter and + also make formal the claim that `num` is only instantiated with `n` and `z`, + but it would result in space and time overheads when manipulating `num`s, by + having to deconstruct to and reconstruct from `Z.t`. *) +type 't num = Z.t + +let compare x y = Z.compare x y + +let zero = Z.zero + +let zero_n = Z.zero + +let one_n = Z.one + +let to_string x = Z.to_string x + +let of_string s = Option.catch (fun () -> Z.of_string s) + +let of_int32 n = Z.of_int64 @@ Int64.of_int32 n + +let to_int64 x = Option.catch (fun () -> Z.to_int64 x) + +let of_int64 n = Z.of_int64 n + +let to_int x = Option.catch (fun () -> Z.to_int x) + +let of_int n = Z.of_int n + +let of_zint x = x + +let to_zint x = x + +let add x y = Z.add x y + +let sub x y = Z.sub x y + +let mul x y = Z.mul x y + +let ediv x y = Option.catch (fun () -> Z.ediv_rem x y) + +let add_n = add + +let succ_n = Z.succ + +let mul_n = mul + +let ediv_n = ediv + +let abs x = Z.abs x + +let is_nat x = if Compare.Z.(x < Z.zero) then None else Some x + +let neg x = Z.neg x + +let int x = x + +let shift_left x y = + if Compare.Int.(Z.compare y (Z.of_int 256) > 0) then None + else + let y = Z.to_int y in + Some (Z.shift_left x y) + +let shift_right x y = + if Compare.Int.(Z.compare y (Z.of_int 256) > 0) then None + else + let y = Z.to_int y in + Some (Z.shift_right x y) + +let shift_left_n = shift_left + +let shift_right_n = shift_right + +let logor x y = Z.logor x y + +let logxor x y = Z.logxor x y + +let logand x y = Z.logand x y + +let lognot x = Z.lognot x + +let z_encoding : z num Data_encoding.encoding = Data_encoding.z + +let n_encoding : n num Data_encoding.encoding = Data_encoding.n diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_int_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/script_int_repr.mli new file mode 100644 index 000000000000..b31894d5982f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_int_repr.mli @@ -0,0 +1,161 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** The types for arbitrary precision integers in Michelson. + The type variable ['t] is always [n] or [z], + [n num] and [z num] are incompatible. + + This is internally a [Z.t]. + This module mostly adds signedness preservation guarantees. *) +type 't num [@@coq_phantom] + +(** Flag for natural numbers. *) +type n = Natural_tag + +(** Flag for relative numbers. *) +type z = Integer_tag + +(** Natural zero. *) +val zero_n : n num + +(** Natural one. *) +val one_n : n num + +(** Natural successor. + + [succ_n x] is the same as [add_n one_n]. + *) +val succ_n : n num -> n num + +(** Relative zero. *) +val zero : z num + +(** Compare two numbers as if they were *) +val compare : 'a num -> 'a num -> int + +(** Conversion to an OCaml [string] in decimal notation. *) +val to_string : _ num -> string + +(** Conversion from an OCaml [string]. + Returns [None] in case of an invalid notation. + Supports [+] and [-] sign modifiers, and [0x], [0o] and [0b] base modifiers. *) +val of_string : string -> z num option + +(** Conversion from an OCaml [int32]. *) +val of_int32 : int32 -> z num + +(** Conversion to an OCaml [int64], returns [None] on overflow. *) +val to_int64 : _ num -> int64 option + +(** Conversion from an OCaml [int64]. *) +val of_int64 : int64 -> z num + +(** Conversion to an OCaml [int], returns [None] on overflow. *) +val to_int : _ num -> int option + +(** Conversion from an OCaml [int]. *) +val of_int : int -> z num + +(** Conversion from a Zarith integer ([Z.t]). *) +val of_zint : Z.t -> z num + +(** Conversion to a Zarith integer ([Z.t]). *) +val to_zint : 'a num -> Z.t + +(** Addition between naturals. *) +val add_n : n num -> n num -> n num + +(** Multiplication with a natural. *) +val mul_n : n num -> 'a num -> 'a num + +(** Euclidean division of a natural. + [ediv_n n d] returns [None] if divisor is zero, + or [Some (q, r)] where [n = d * q + r] and [[0 <= r < d]] otherwise. *) +val ediv_n : n num -> 'a num -> ('a num * n num) option + +(** Sign agnostic addition. + Use {!add_n} when working with naturals to preserve the sign. *) +val add : _ num -> _ num -> z num + +(** Sign agnostic subtraction. + Use {!sub_n} when working with naturals to preserve the sign. *) +val sub : _ num -> _ num -> z num + +(** Sign agnostic multiplication. + Use {!mul_n} when working with a natural to preserve the sign. *) +val mul : _ num -> _ num -> z num + +(** Sign agnostic euclidean division. + [ediv n d] returns [None] if divisor is zero, + or [Some (q, r)] where [n = d * q + r] and [[0 <= r < |d|]] otherwise. + Use {!ediv_n} when working with a natural to preserve the sign. *) +val ediv : _ num -> _ num -> (z num * n num) option + +(** Compute the absolute value of a relative, turning it into a natural. *) +val abs : z num -> n num + +(** Partial identity over [N]. *) +val is_nat : z num -> n num option + +(** Negates a number. *) +val neg : _ num -> z num + +(** Turns a natural into a relative, not changing its value. *) +val int : n num -> z num + +(** Reverses each bit in the representation of the number. + Also applies to the sign. *) +val lognot : _ num -> z num + +(** Shifts the natural to the left of a number of bits between 0 and 256. + Returns [None] if the amount is too high. *) +val shift_left_n : n num -> n num -> n num option + +(** Shifts the natural to the right of a number of bits between 0 and 256. + Returns [None] if the amount is too high. *) +val shift_right_n : n num -> n num -> n num option + +(** Shifts the number to the left of a number of bits between 0 and 256. + Returns [None] if the amount is too high. *) +val shift_left : 'a num -> n num -> 'a num option + +(** Shifts the number to the right of a number of bits between 0 and 256. + Returns [None] if the amount is too high. *) +val shift_right : 'a num -> n num -> 'a num option + +(** Applies a boolean or operation to each bit. *) +val logor : 'a num -> 'a num -> 'a num + +(** Applies a boolean and operation to each bit. *) +val logand : _ num -> n num -> n num + +(** Applies a boolean xor operation to each bit. *) +val logxor : n num -> n num -> n num + +(** Naturals are encoded using Data_encoding.n *) +val n_encoding : n num Data_encoding.encoding + +(** Integers are encoded using Data_encoding.z *) +val z_encoding : z num Data_encoding.encoding diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_interpreter.ml b/src/proto_012_PsiThaCa/lib_protocol/script_interpreter.ml new file mode 100644 index 000000000000..1bbd4bc7cb04 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_interpreter.ml @@ -0,0 +1,1798 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* + + This module implements an interpreter for Michelson. It takes the + form of a [step] function that interprets script instructions in a + dedicated abstract machine. + + The interpreter is written in a small-step style: an execution + [step] only interprets a single instruction by updating the + configuration of a dedicated abstract machine. + + This abstract machine has two components: + + - a stack to control which instructions must be executed ; and + + - a stack of values where instructions get their inputs and put + their outputs. + + In addition, the machine has access to effectful primitives to + interact with the execution environment (e.g. the Tezos + node). These primitives live in the [Lwt+State+Error] monad. Hence, + this interpreter produces a computation in the [Lwt+State+Error] + monad. + + This interpreter enjoys the following properties: + + - The interpreter is tail-recursive, hence it is robust to stack + overflow. This property is checked by the compiler thanks to the + [@ocaml.tailcall] annotation of each recursive call. + + - The interpreter is type-preserving. Thanks to GADTs, the typing + rules of Michelson are statically checked by the OCaml typechecker: + a Michelson program cannot go wrong. + + - The interpreter is tagless. Thanks to GADTs, the exact shape of + the stack is known statically so the interpreter does not have to + check that the input stack has the shape expected by the + instruction to be executed. + + Outline + ======= + + This file is organized as follows: + + 1. Definition of runtime errors. + + 2. Interpretation loop: This is the main functionality of this + module, aka the [step] function. + + 3. Interface functions: This part of the module builds high-level + functions on top of the more basic [step] function. + + Auxiliary definitions can be found in {!Script_interpreter_defs}. + + Implementation details are explained along the file. + +*) + +open Alpha_context +open Script +open Script_typed_ir +open Script_ir_translator +open Local_gas_counter +open Script_interpreter_defs +module S = Saturation_repr + +type step_constants = Script_typed_ir.step_constants = { + source : Contract.t; + payer : Contract.t; + self : Contract.t; + amount : Tez.t; + chain_id : Chain_id.t; + now : Script_timestamp.t; + level : Script_int.n Script_int.num; +} + +(* ---- Run-time errors -----------------------------------------------------*) + +type error += Reject of Script.location * Script.expr * execution_trace option + +type error += Overflow of Script.location * execution_trace option + +type error += Runtime_contract_error : Contract.t * Script.expr -> error + +type error += Bad_contract_parameter of Contract.t (* `Permanent *) + +type error += Cannot_serialize_failure + +type error += Cannot_serialize_storage + +type error += Michelson_too_many_recursive_calls + +let () = + let open Data_encoding in + let trace_encoding = + list + @@ obj3 + (req "location" Script.location_encoding) + (req "gas" Gas.encoding) + (req + "stack" + (list (obj2 (req "item" Script.expr_encoding) (opt "annot" string)))) + in + (* Reject *) + register_error_kind + `Temporary + ~id:"michelson_v1.script_rejected" + ~title:"Script failed" + ~description:"A FAILWITH instruction was reached" + (obj3 + (req "location" Script.location_encoding) + (req "with" Script.expr_encoding) + (opt "trace" trace_encoding)) + (function Reject (loc, v, trace) -> Some (loc, v, trace) | _ -> None) + (fun (loc, v, trace) -> Reject (loc, v, trace)) ; + (* Overflow *) + register_error_kind + `Temporary + ~id:"michelson_v1.script_overflow" + ~title:"Script failed (overflow error)" + ~description: + "A FAIL instruction was reached due to the detection of an overflow" + (obj2 + (req "location" Script.location_encoding) + (opt "trace" trace_encoding)) + (function Overflow (loc, trace) -> Some (loc, trace) | _ -> None) + (fun (loc, trace) -> Overflow (loc, trace)) ; + (* Runtime contract error *) + register_error_kind + `Temporary + ~id:"michelson_v1.runtime_error" + ~title:"Script runtime error" + ~description:"Toplevel error for all runtime script errors" + (obj2 + (req "contract_handle" Contract.encoding) + (req "contract_code" Script.expr_encoding)) + (function + | Runtime_contract_error (contract, expr) -> Some (contract, expr) + | _ -> None) + (fun (contract, expr) -> Runtime_contract_error (contract, expr)) ; + (* Bad contract parameter *) + register_error_kind + `Permanent + ~id:"michelson_v1.bad_contract_parameter" + ~title:"Contract supplied an invalid parameter" + ~description: + "Either no parameter was supplied to a contract with a non-unit \ + parameter type, a non-unit parameter was passed to an account, or a \ + parameter was supplied of the wrong type" + Data_encoding.(obj1 (req "contract" Contract.encoding)) + (function Bad_contract_parameter c -> Some c | _ -> None) + (fun c -> Bad_contract_parameter c) ; + (* Cannot serialize failure *) + register_error_kind + `Temporary + ~id:"michelson_v1.cannot_serialize_failure" + ~title:"Not enough gas to serialize argument of FAILWITH" + ~description: + "Argument of FAILWITH was too big to be serialized with the provided gas" + Data_encoding.empty + (function Cannot_serialize_failure -> Some () | _ -> None) + (fun () -> Cannot_serialize_failure) ; + (* Cannot serialize storage *) + register_error_kind + `Temporary + ~id:"michelson_v1.cannot_serialize_storage" + ~title:"Not enough gas to serialize execution storage" + ~description: + "The returned storage was too big to be serialized with the provided gas" + Data_encoding.empty + (function Cannot_serialize_storage -> Some () | _ -> None) + (fun () -> Cannot_serialize_storage) + +(* + + Interpretation loop + =================== + +*) + +(* + + As announced earlier, the [step] function produces a computation in + the [Lwt+State+Error] monad. The [State] monad is implemented by + having the [context] passed as input and returned updated as + output. The [Error] monad is represented by the [tzresult] type + constructor. + + The [step] function is actually defined as an internal + tail-recursive routine of the toplevel [step]. It monitors the gas + level before executing the instruction under focus, once this is + done, it recursively calls itself on the continuation held by the + current instruction. + + For each pure instruction (i.e. that is not monadic), the + interpretation simply updates the input arguments of the [step] + function. Since these arguments are (most likely) stored in + hardware registers and since the tail-recursive calls are compiled + into direct jumps, this interpretation technique offers good + performances while saving safety thanks to a rich typing. + + For each impure instruction, the interpreter makes use of monadic + bindings to compose monadic primitives with the [step] function. + Again, we make sure that the recursive calls to [step] are tail + calls by annotating them with [@ocaml.tailcall]. + + The [step] function is actually based on several mutually + recursive functions that can be separated in two groups: the first + group focuses on the evaluation of continuations while the second + group is about evaluating the instructions. + +*) + +(* + + Evaluation of continuations + =========================== + + As explained in [Script_typed_ir], there are several kinds of + continuations, each having a specific evaluation rules. The + following group of functions starts with a list of evaluation + rules for continuations that generate fresh continuations. This + group ends with the definition of [next], which dispatches + evaluation rules depending on the continuation at stake. + + *) +let rec kmap_exit : + type a b c d e f g h m n o. (a, b, c, d, e, f, g, h, m, n, o) kmap_exit_type + = + fun mk g gas (body, xs, ys, yk) ks accu stack -> + let ys = Script_map.update yk (Some accu) ys in + let ks = mk (KMap_enter_body (body, xs, ys, ks)) in + let (accu, stack) = stack in + (next [@ocaml.tailcall]) g gas ks accu stack + [@@inline] + +and kmap_enter : type a b c d i j k. (a, b, c, d, i, j, k) kmap_enter_type = + fun mk g gas (body, xs, ys) ks accu stack -> + match xs with + | [] -> (next [@ocaml.tailcall]) g gas ks ys (accu, stack) + | (xk, xv) :: xs -> + let ks = mk (KMap_exit_body (body, xs, ys, xk, ks)) in + let res = (xk, xv) in + let stack = (accu, stack) in + (step [@ocaml.tailcall]) g gas body ks res stack + [@@inline] + +and klist_exit : type a b c d i j. (a, b, c, d, i, j) klist_exit_type = + fun mk g gas (body, xs, ys, len) ks accu stack -> + let ks = mk (KList_enter_body (body, xs, accu :: ys, len, ks)) in + let (accu, stack) = stack in + (next [@ocaml.tailcall]) g gas ks accu stack + [@@inline] + +and klist_enter : type a b c d e j. (a, b, c, d, e, j) klist_enter_type = + fun mk g gas (body, xs, ys, len) ks' accu stack -> + match xs with + | [] -> + let ys = {elements = List.rev ys; length = len} in + (next [@ocaml.tailcall]) g gas ks' ys (accu, stack) + | x :: xs -> + let ks = mk (KList_exit_body (body, xs, ys, len, ks')) in + (step [@ocaml.tailcall]) g gas body ks x (accu, stack) + [@@inline] + +and kloop_in_left : type a b c d e f g. (a, b, c, d, e, f, g) kloop_in_left_type + = + fun g gas ks0 ki ks' accu stack -> + match accu with + | L v -> (step [@ocaml.tailcall]) g gas ki ks0 v stack + | R v -> (next [@ocaml.tailcall]) g gas ks' v stack + [@@inline] + +and kloop_in : type a b c r f s. (a, b, c, r, f, s) kloop_in_type = + fun g gas ks0 ki ks' accu stack -> + let (accu', stack') = stack in + if accu then (step [@ocaml.tailcall]) g gas ki ks0 accu' stack' + else (next [@ocaml.tailcall]) g gas ks' accu' stack' + [@@inline] + +and kiter : type a b s r f. (a, b, s, r, f) kiter_type = + fun mk g gas (body, xs) ks accu stack -> + match xs with + | [] -> (next [@ocaml.tailcall]) g gas ks accu stack + | x :: xs -> + let ks = mk (KIter (body, xs, ks)) in + (step [@ocaml.tailcall]) g gas body ks x (accu, stack) + [@@inline] + +and next : + type a s r f. + outdated_context * step_constants -> + local_gas_counter -> + (a, s, r, f) continuation -> + a -> + s -> + (r * f * outdated_context * local_gas_counter) tzresult Lwt.t = + fun ((ctxt, _) as g) gas ks0 accu stack -> + match consume_control gas ks0 with + | None -> fail Gas.Operation_quota_exceeded + | Some gas -> ( + match ks0 with + | KLog (ks, logger) -> + (klog [@ocaml.tailcall]) logger g gas ks0 ks accu stack + | KNil -> Lwt.return (Ok (accu, stack, ctxt, gas)) + | KCons (k, ks) -> (step [@ocaml.tailcall]) g gas k ks accu stack + | KLoop_in (ki, ks') -> + (kloop_in [@ocaml.tailcall]) g gas ks0 ki ks' accu stack + | KReturn (stack', ks) -> (next [@ocaml.tailcall]) g gas ks accu stack' + | KMap_head (f, ks) -> (next [@ocaml.tailcall]) g gas ks (f accu) stack + | KLoop_in_left (ki, ks') -> + (kloop_in_left [@ocaml.tailcall]) g gas ks0 ki ks' accu stack + | KUndip (x, ks) -> (next [@ocaml.tailcall]) g gas ks x (accu, stack) + | KIter (body, xs, ks) -> + let extra = (body, xs) in + (kiter [@ocaml.tailcall]) id g gas extra ks accu stack + | KList_enter_body (body, xs, ys, len, ks) -> + let extra = (body, xs, ys, len) in + (klist_enter [@ocaml.tailcall]) id g gas extra ks accu stack + | KList_exit_body (body, xs, ys, len, ks) -> + let extra = (body, xs, ys, len) in + (klist_exit [@ocaml.tailcall]) id g gas extra ks accu stack + | KMap_enter_body (body, xs, ys, ks) -> + let extra = (body, xs, ys) in + (kmap_enter [@ocaml.tailcall]) id g gas extra ks accu stack + | KMap_exit_body (body, xs, ys, yk, ks) -> + let extra = (body, xs, ys, yk) in + (kmap_exit [@ocaml.tailcall]) id g gas extra ks accu stack + | KView_exit (orig_step_constants, ks) -> + let g = (fst g, orig_step_constants) in + (next [@ocaml.tailcall]) g gas ks accu stack) + +(* + + Evaluation of instructions + ========================== + + The following functions define evaluation rules for instructions that + generate fresh continuations. As such, they expect a constructor + [log_if_needed] which inserts a [KLog] if the evaluation is logged. + + The [step] function is taking care of the evaluation of the other + instructions. + +*) +and ilist_map : type a b c d e f g h. (a, b, c, d, e, f, g, h) ilist_map_type = + fun log_if_needed g gas (body, k) ks accu stack -> + let xs = accu.elements in + let ys = [] in + let len = accu.length in + let ks = + log_if_needed (KList_enter_body (body, xs, ys, len, KCons (k, ks))) + in + let (accu, stack) = stack in + (next [@ocaml.tailcall]) g gas ks accu stack + [@@inline] + +and ilist_iter : type a b c d e f g. (a, b, c, d, e, f, g) ilist_iter_type = + fun log_if_needed g gas (body, k) ks accu stack -> + let xs = accu.elements in + let ks = log_if_needed (KIter (body, xs, KCons (k, ks))) in + let (accu, stack) = stack in + (next [@ocaml.tailcall]) g gas ks accu stack + [@@inline] + +and iset_iter : type a b c d e f g. (a, b, c, d, e, f, g) iset_iter_type = + fun log_if_needed g gas (body, k) ks accu stack -> + let set = accu in + let l = List.rev (Script_set.fold (fun e acc -> e :: acc) set []) in + let ks = log_if_needed (KIter (body, l, KCons (k, ks))) in + let (accu, stack) = stack in + (next [@ocaml.tailcall]) g gas ks accu stack + [@@inline] + +and imap_map : type a b c d e f g h i. (a, b, c, d, e, f, g, h, i) imap_map_type + = + fun log_if_needed g gas (body, k) ks accu stack -> + let map = accu in + let xs = List.rev (Script_map.fold (fun k v a -> (k, v) :: a) map []) in + let ys = Script_map.(empty @@ key_ty map) in + let ks = log_if_needed (KMap_enter_body (body, xs, ys, KCons (k, ks))) in + let (accu, stack) = stack in + (next [@ocaml.tailcall]) g gas ks accu stack + [@@inline] + +and imap_iter : type a b c d e f g h. (a, b, c, d, e, f, g, h) imap_iter_type = + fun log_if_needed g gas (body, k) ks accu stack -> + let map = accu in + let l = List.rev (Script_map.fold (fun k v a -> (k, v) :: a) map []) in + let ks = log_if_needed (KIter (body, l, KCons (k, ks))) in + let (accu, stack) = stack in + (next [@ocaml.tailcall]) g gas ks accu stack + [@@inline] + +and imul_teznat : type a b c d e f. (a, b, c, d, e, f) imul_teznat_type = + fun logger g gas (kinfo, k) ks accu stack -> + let x = accu in + let (y, stack) = stack in + match Script_int.to_int64 y with + | None -> get_log logger >>=? fun log -> fail (Overflow (kinfo.iloc, log)) + | Some y -> + Tez.(x *? y) >>?= fun res -> (step [@ocaml.tailcall]) g gas k ks res stack + +and imul_nattez : type a b c d e f. (a, b, c, d, e, f) imul_nattez_type = + fun logger g gas (kinfo, k) ks accu stack -> + let y = accu in + let (x, stack) = stack in + match Script_int.to_int64 y with + | None -> get_log logger >>=? fun log -> fail (Overflow (kinfo.iloc, log)) + | Some y -> + Tez.(x *? y) >>?= fun res -> (step [@ocaml.tailcall]) g gas k ks res stack + +and ilsl_nat : type a b c d e f. (a, b, c, d, e, f) ilsl_nat_type = + fun logger g gas (kinfo, k) ks accu stack -> + let x = accu and (y, stack) = stack in + match Script_int.shift_left_n x y with + | None -> get_log logger >>=? fun log -> fail (Overflow (kinfo.iloc, log)) + | Some x -> (step [@ocaml.tailcall]) g gas k ks x stack + +and ilsr_nat : type a b c d e f. (a, b, c, d, e, f) ilsr_nat_type = + fun logger g gas (kinfo, k) ks accu stack -> + let x = accu and (y, stack) = stack in + match Script_int.shift_right_n x y with + | None -> get_log logger >>=? fun log -> fail (Overflow (kinfo.iloc, log)) + | Some r -> (step [@ocaml.tailcall]) g gas k ks r stack + +and ifailwith : type a b. (a, b) ifailwith_type = + fun logger (ctxt, _) gas kloc tv accu -> + let v = accu in + let ctxt = update_context gas ctxt in + trace Cannot_serialize_failure (unparse_data ctxt Optimized tv v) + >>=? fun (v, _ctxt) -> + let v = Micheline.strip_locations v in + get_log logger >>=? fun log -> fail (Reject (kloc, v, log)) + +and iexec : type a b c d e f g. (a, b, c, d, e, f, g) iexec_type = + fun logger g gas k ks accu stack -> + let arg = accu and (code, stack) = stack in + let (Lam (code, _)) = code in + let code = + match logger with + | None -> code.kinstr + | Some logger -> log_kinstr logger code.kinstr + in + let ks = KReturn (stack, KCons (k, ks)) in + (step [@ocaml.tailcall]) g gas code ks arg (EmptyCell, EmptyCell) + +and step : type a s b t r f. (a, s, b, t, r, f) step_type = + fun ((ctxt, sc) as g) gas i ks accu stack -> + match consume_instr gas i accu stack with + | None -> fail Gas.Operation_quota_exceeded + | Some gas -> ( + match i with + | ILog (_, event, logger, k) -> + (log [@ocaml.tailcall]) (logger, event) g gas k ks accu stack + | IHalt _ -> (next [@ocaml.tailcall]) g gas ks accu stack + (* stack ops *) + | IDrop (_, k) -> + let (accu, stack) = stack in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IDup (_, k) -> (step [@ocaml.tailcall]) g gas k ks accu (accu, stack) + | ISwap (_, k) -> + let (top, stack) = stack in + (step [@ocaml.tailcall]) g gas k ks top (accu, stack) + | IConst (_, v, k) -> (step [@ocaml.tailcall]) g gas k ks v (accu, stack) + (* options *) + | ICons_some (_, k) -> + (step [@ocaml.tailcall]) g gas k ks (Some accu) stack + | ICons_none (_, k) -> + (step [@ocaml.tailcall]) g gas k ks None (accu, stack) + | IIf_none {branch_if_none; branch_if_some; k; _} -> ( + match accu with + | None -> + let (accu, stack) = stack in + (step [@ocaml.tailcall]) + g + gas + branch_if_none + (KCons (k, ks)) + accu + stack + | Some v -> + (step [@ocaml.tailcall]) + g + gas + branch_if_some + (KCons (k, ks)) + v + stack) + | IOpt_map {body; k; kinfo = _} -> ( + match accu with + | None -> (step [@ocaml.tailcall]) g gas k ks None stack + | Some v -> + let ks' = KMap_head (Option.some, KCons (k, ks)) in + (step [@ocaml.tailcall]) g gas body ks' v stack) + (* pairs *) + | ICons_pair (_, k) -> + let (b, stack) = stack in + (step [@ocaml.tailcall]) g gas k ks (accu, b) stack + | IUnpair (_, k) -> + let (a, b) = accu in + (step [@ocaml.tailcall]) g gas k ks a (b, stack) + | ICar (_, k) -> + let (a, _) = accu in + (step [@ocaml.tailcall]) g gas k ks a stack + | ICdr (_, k) -> + let (_, b) = accu in + (step [@ocaml.tailcall]) g gas k ks b stack + (* unions *) + | ICons_left (_, k) -> (step [@ocaml.tailcall]) g gas k ks (L accu) stack + | ICons_right (_, k) -> (step [@ocaml.tailcall]) g gas k ks (R accu) stack + | IIf_left {branch_if_left; branch_if_right; k; _} -> ( + match accu with + | L v -> + (step [@ocaml.tailcall]) + g + gas + branch_if_left + (KCons (k, ks)) + v + stack + | R v -> + (step [@ocaml.tailcall]) + g + gas + branch_if_right + (KCons (k, ks)) + v + stack) + (* lists *) + | ICons_list (_, k) -> + let (tl, stack) = stack in + let accu = Script_list.cons accu tl in + (step [@ocaml.tailcall]) g gas k ks accu stack + | INil (_, k) -> + let stack = (accu, stack) in + let accu = Script_list.empty in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IIf_cons {branch_if_cons; branch_if_nil; k; _} -> ( + match accu.elements with + | [] -> + let (accu, stack) = stack in + (step [@ocaml.tailcall]) + g + gas + branch_if_nil + (KCons (k, ks)) + accu + stack + | hd :: tl -> + let tl = {elements = tl; length = accu.length - 1} in + (step [@ocaml.tailcall]) + g + gas + branch_if_cons + (KCons (k, ks)) + hd + (tl, stack)) + | IList_map (_, body, k) -> + (ilist_map [@ocaml.tailcall]) id g gas (body, k) ks accu stack + | IList_size (_, k) -> + let list = accu in + let len = Script_int.(abs (of_int list.length)) in + (step [@ocaml.tailcall]) g gas k ks len stack + | IList_iter (_, body, k) -> + (ilist_iter [@ocaml.tailcall]) id g gas (body, k) ks accu stack + (* sets *) + | IEmpty_set (_, ty, k) -> + let res = Script_set.empty ty in + let stack = (accu, stack) in + (step [@ocaml.tailcall]) g gas k ks res stack + | ISet_iter (_, body, k) -> + (iset_iter [@ocaml.tailcall]) id g gas (body, k) ks accu stack + | ISet_mem (_, k) -> + let (set, stack) = stack in + let res = Script_set.mem accu set in + (step [@ocaml.tailcall]) g gas k ks res stack + | ISet_update (_, k) -> + let (presence, (set, stack)) = stack in + let res = Script_set.update accu presence set in + (step [@ocaml.tailcall]) g gas k ks res stack + | ISet_size (_, k) -> + let res = Script_set.size accu in + (step [@ocaml.tailcall]) g gas k ks res stack + (* maps *) + | IEmpty_map (_, ty, k) -> + let res = Script_map.empty ty and stack = (accu, stack) in + (step [@ocaml.tailcall]) g gas k ks res stack + | IMap_map (_, body, k) -> + (imap_map [@ocaml.tailcall]) id g gas (body, k) ks accu stack + | IMap_iter (_, body, k) -> + (imap_iter [@ocaml.tailcall]) id g gas (body, k) ks accu stack + | IMap_mem (_, k) -> + let (map, stack) = stack in + let res = Script_map.mem accu map in + (step [@ocaml.tailcall]) g gas k ks res stack + | IMap_get (_, k) -> + let (map, stack) = stack in + let res = Script_map.get accu map in + (step [@ocaml.tailcall]) g gas k ks res stack + | IMap_update (_, k) -> + let (v, (map, stack)) = stack in + let key = accu in + let res = Script_map.update key v map in + (step [@ocaml.tailcall]) g gas k ks res stack + | IMap_get_and_update (_, k) -> + let key = accu in + let (v, (map, rest)) = stack in + let map' = Script_map.update key v map in + let v' = Script_map.get key map in + (step [@ocaml.tailcall]) g gas k ks v' (map', rest) + | IMap_size (_, k) -> + let res = Script_map.size accu in + (step [@ocaml.tailcall]) g gas k ks res stack + (* Big map operations *) + | IEmpty_big_map (_, tk, tv, k) -> + let ebm = Script_ir_translator.empty_big_map tk tv in + (step [@ocaml.tailcall]) g gas k ks ebm (accu, stack) + | IBig_map_mem (_, k) -> + let (map, stack) = stack in + let key = accu in + ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> + Script_ir_translator.big_map_mem ctxt key map ) + >>=? fun (res, ctxt, gas) -> + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks res stack + | IBig_map_get (_, k) -> + let (map, stack) = stack in + let key = accu in + ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> + Script_ir_translator.big_map_get ctxt key map ) + >>=? fun (res, ctxt, gas) -> + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks res stack + | IBig_map_update (_, k) -> + let key = accu in + let (maybe_value, (map, stack)) = stack in + ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> + Script_ir_translator.big_map_update ctxt key maybe_value map ) + >>=? fun (big_map, ctxt, gas) -> + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks big_map stack + | IBig_map_get_and_update (_, k) -> + let key = accu in + let (v, (map, stack)) = stack in + ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> + Script_ir_translator.big_map_get_and_update ctxt key v map ) + >>=? fun ((v', map'), ctxt, gas) -> + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks v' (map', stack) + (* timestamp operations *) + | IAdd_seconds_to_timestamp (_, k) -> + let n = accu in + let (t, stack) = stack in + let result = Script_timestamp.add_delta t n in + (step [@ocaml.tailcall]) g gas k ks result stack + | IAdd_timestamp_to_seconds (_, k) -> + let t = accu in + let (n, stack) = stack in + let result = Script_timestamp.add_delta t n in + (step [@ocaml.tailcall]) g gas k ks result stack + | ISub_timestamp_seconds (_, k) -> + let t = accu in + let (s, stack) = stack in + let result = Script_timestamp.sub_delta t s in + (step [@ocaml.tailcall]) g gas k ks result stack + | IDiff_timestamps (_, k) -> + let t1 = accu in + let (t2, stack) = stack in + let result = Script_timestamp.diff t1 t2 in + (step [@ocaml.tailcall]) g gas k ks result stack + (* string operations *) + | IConcat_string_pair (_, k) -> + let x = accu in + let (y, stack) = stack in + let s = Script_string.concat_pair x y in + (step [@ocaml.tailcall]) g gas k ks s stack + | IConcat_string (_, k) -> + let ss = accu in + (* The cost for this fold_left has been paid upfront *) + let total_length = + List.fold_left + (fun acc s -> S.add acc (S.safe_int (Script_string.length s))) + S.zero + ss.elements + in + consume gas (Interp_costs.concat_string total_length) >>?= fun gas -> + let s = Script_string.concat ss.elements in + (step [@ocaml.tailcall]) g gas k ks s stack + | ISlice_string (_, k) -> + let offset = accu and (length, (s, stack)) = stack in + let s_length = Z.of_int (Script_string.length s) in + let offset = Script_int.to_zint offset in + let length = Script_int.to_zint length in + if Compare.Z.(offset < s_length && Z.add offset length <= s_length) + then + let s = Script_string.sub s (Z.to_int offset) (Z.to_int length) in + (step [@ocaml.tailcall]) g gas k ks (Some s) stack + else (step [@ocaml.tailcall]) g gas k ks None stack + | IString_size (_, k) -> + let s = accu in + let result = Script_int.(abs (of_int (Script_string.length s))) in + (step [@ocaml.tailcall]) g gas k ks result stack + (* bytes operations *) + | IConcat_bytes_pair (_, k) -> + let x = accu in + let (y, stack) = stack in + let s = Bytes.cat x y in + (step [@ocaml.tailcall]) g gas k ks s stack + | IConcat_bytes (_, k) -> + let ss = accu in + (* The cost for this fold_left has been paid upfront *) + let total_length = + List.fold_left + (fun acc s -> S.add acc (S.safe_int (Bytes.length s))) + S.zero + ss.elements + in + consume gas (Interp_costs.concat_string total_length) >>?= fun gas -> + let s = Bytes.concat Bytes.empty ss.elements in + (step [@ocaml.tailcall]) g gas k ks s stack + | ISlice_bytes (_, k) -> + let offset = accu and (length, (s, stack)) = stack in + let s_length = Z.of_int (Bytes.length s) in + let offset = Script_int.to_zint offset in + let length = Script_int.to_zint length in + if Compare.Z.(offset < s_length && Z.add offset length <= s_length) + then + let s = Bytes.sub s (Z.to_int offset) (Z.to_int length) in + (step [@ocaml.tailcall]) g gas k ks (Some s) stack + else (step [@ocaml.tailcall]) g gas k ks None stack + | IBytes_size (_, k) -> + let s = accu in + let result = Script_int.(abs (of_int (Bytes.length s))) in + (step [@ocaml.tailcall]) g gas k ks result stack + (* currency operations *) + | IAdd_tez (_, k) -> + let x = accu in + let (y, stack) = stack in + Tez.(x +? y) >>?= fun res -> + (step [@ocaml.tailcall]) g gas k ks res stack + | ISub_tez (_, k) -> + let x = accu in + let (y, stack) = stack in + let res = Tez.sub_opt x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | ISub_tez_legacy (_, k) -> + let x = accu in + let (y, stack) = stack in + Tez.(x -? y) >>?= fun res -> + (step [@ocaml.tailcall]) g gas k ks res stack + | IMul_teznat (kinfo, k) -> + imul_teznat None g gas (kinfo, k) ks accu stack + | IMul_nattez (kinfo, k) -> + imul_nattez None g gas (kinfo, k) ks accu stack + (* boolean operations *) + | IOr (_, k) -> + let x = accu in + let (y, stack) = stack in + (step [@ocaml.tailcall]) g gas k ks (x || y) stack + | IAnd (_, k) -> + let x = accu in + let (y, stack) = stack in + (step [@ocaml.tailcall]) g gas k ks (x && y) stack + | IXor (_, k) -> + let x = accu in + let (y, stack) = stack in + let res = Compare.Bool.(x <> y) in + (step [@ocaml.tailcall]) g gas k ks res stack + | INot (_, k) -> + let x = accu in + (step [@ocaml.tailcall]) g gas k ks (not x) stack + (* integer operations *) + | IIs_nat (_, k) -> + let x = accu in + let res = Script_int.is_nat x in + (step [@ocaml.tailcall]) g gas k ks res stack + | IAbs_int (_, k) -> + let x = accu in + let res = Script_int.abs x in + (step [@ocaml.tailcall]) g gas k ks res stack + | IInt_nat (_, k) -> + let x = accu in + let res = Script_int.int x in + (step [@ocaml.tailcall]) g gas k ks res stack + | INeg (_, k) -> + let x = accu in + let res = Script_int.neg x in + (step [@ocaml.tailcall]) g gas k ks res stack + | IAdd_int (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.add x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IAdd_nat (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.add_n x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | ISub_int (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.sub x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IMul_int (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.mul x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IMul_nat (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.mul_n x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IEdiv_teznat (_, k) -> + let x = accu and (y, stack) = stack in + let x = Script_int.of_int64 (Tez.to_mutez x) in + let result = + match Script_int.ediv x y with + | None -> None + | Some (q, r) -> ( + match (Script_int.to_int64 q, Script_int.to_int64 r) with + | (Some q, Some r) -> ( + match (Tez.of_mutez q, Tez.of_mutez r) with + | (Some q, Some r) -> Some (q, r) + (* Cannot overflow *) + | _ -> assert false) + (* Cannot overflow *) + | _ -> assert false) + in + (step [@ocaml.tailcall]) g gas k ks result stack + | IEdiv_tez (_, k) -> + let x = accu and (y, stack) = stack in + let x = Script_int.abs (Script_int.of_int64 (Tez.to_mutez x)) in + let y = Script_int.abs (Script_int.of_int64 (Tez.to_mutez y)) in + let result = + match Script_int.ediv_n x y with + | None -> None + | Some (q, r) -> ( + match Script_int.to_int64 r with + | None -> assert false (* Cannot overflow *) + | Some r -> ( + match Tez.of_mutez r with + | None -> assert false (* Cannot overflow *) + | Some r -> Some (q, r))) + in + (step [@ocaml.tailcall]) g gas k ks result stack + | IEdiv_int (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.ediv x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IEdiv_nat (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.ediv_n x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | ILsl_nat (kinfo, k) -> ilsl_nat None g gas (kinfo, k) ks accu stack + | ILsr_nat (kinfo, k) -> ilsr_nat None g gas (kinfo, k) ks accu stack + | IOr_nat (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.logor x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IAnd_nat (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.logand x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IAnd_int_nat (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.logand x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IXor_nat (_, k) -> + let x = accu and (y, stack) = stack in + let res = Script_int.logxor x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | INot_int (_, k) -> + let x = accu in + let res = Script_int.lognot x in + (step [@ocaml.tailcall]) g gas k ks res stack + (* control *) + | IIf {branch_if_true; branch_if_false; k; _} -> + let (res, stack) = stack in + if accu then + (step [@ocaml.tailcall]) + g + gas + branch_if_true + (KCons (k, ks)) + res + stack + else + (step [@ocaml.tailcall]) + g + gas + branch_if_false + (KCons (k, ks)) + res + stack + | ILoop (_, body, k) -> + let ks = KLoop_in (body, KCons (k, ks)) in + (next [@ocaml.tailcall]) g gas ks accu stack + | ILoop_left (_, bl, br) -> + let ks = KLoop_in_left (bl, KCons (br, ks)) in + (next [@ocaml.tailcall]) g gas ks accu stack + | IDip (_, b, k) -> + let ign = accu in + let ks = KUndip (ign, KCons (k, ks)) in + let (accu, stack) = stack in + (step [@ocaml.tailcall]) g gas b ks accu stack + | IExec (_, k) -> iexec None g gas k ks accu stack + | IApply (_, capture_ty, k) -> + let capture = accu in + let (lam, stack) = stack in + apply ctxt gas capture_ty capture lam >>=? fun (lam', ctxt, gas) -> + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks lam' stack + | ILambda (_, lam, k) -> + (step [@ocaml.tailcall]) g gas k ks lam (accu, stack) + | IFailwith (_, kloc, tv) -> ifailwith None g gas kloc tv accu + (* comparison *) + | ICompare (_, ty, k) -> + let a = accu in + let (b, stack) = stack in + let r = + Script_int.of_int @@ Script_comparable.compare_comparable ty a b + in + (step [@ocaml.tailcall]) g gas k ks r stack + (* comparators *) + | IEq (_, k) -> + let a = accu in + let a = Script_int.compare a Script_int.zero in + let a = Compare.Int.(a = 0) in + (step [@ocaml.tailcall]) g gas k ks a stack + | INeq (_, k) -> + let a = accu in + let a = Script_int.compare a Script_int.zero in + let a = Compare.Int.(a <> 0) in + (step [@ocaml.tailcall]) g gas k ks a stack + | ILt (_, k) -> + let a = accu in + let a = Script_int.compare a Script_int.zero in + let a = Compare.Int.(a < 0) in + (step [@ocaml.tailcall]) g gas k ks a stack + | ILe (_, k) -> + let a = accu in + let a = Script_int.compare a Script_int.zero in + let a = Compare.Int.(a <= 0) in + (step [@ocaml.tailcall]) g gas k ks a stack + | IGt (_, k) -> + let a = accu in + let a = Script_int.compare a Script_int.zero in + let a = Compare.Int.(a > 0) in + (step [@ocaml.tailcall]) g gas k ks a stack + | IGe (_, k) -> + let a = accu in + let a = Script_int.compare a Script_int.zero in + let a = Compare.Int.(a >= 0) in + (step [@ocaml.tailcall]) g gas k ks a stack + (* packing *) + | IPack (_, ty, k) -> + let value = accu in + ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> + Script_ir_translator.pack_data ctxt ty value ) + >>=? fun (bytes, ctxt, gas) -> + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks bytes stack + | IUnpack (_, ty, k) -> + let bytes = accu in + ( use_gas_counter_in_ctxt ctxt gas @@ fun ctxt -> + unpack ctxt ~ty ~bytes ) + >>=? fun (opt, ctxt, gas) -> + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks opt stack + | IAddress (_, k) -> + let (_, address) = accu in + (step [@ocaml.tailcall]) g gas k ks address stack + | IContract (kinfo, t, entrypoint, k) -> ( + let contract = accu in + match (contract, entrypoint) with + | ((contract, "default"), entrypoint) + | ((contract, entrypoint), "default") -> + let ctxt = update_context gas ctxt in + Script_ir_translator.parse_contract_for_script + ctxt + kinfo.iloc + t + contract + ~entrypoint + >>=? fun (ctxt, maybe_contract) -> + let gas = update_local_gas_counter ctxt in + let ctxt = outdated ctxt in + let accu = maybe_contract in + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks accu stack + | _ -> (step [@ocaml.tailcall]) (ctxt, sc) gas k ks None stack) + | ITransfer_tokens (_, k) -> + let p = accu in + let (amount, ((tp, (destination, entrypoint)), stack)) = stack in + transfer (ctxt, sc) gas amount tp p destination entrypoint + >>=? fun (accu, ctxt, gas) -> + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks accu stack + | IImplicit_account (_, k) -> + let key = accu in + let contract = Contract.implicit_contract key in + let res = (unit_t ~annot:None, (contract, "default")) in + (step [@ocaml.tailcall]) g gas k ks res stack + | IView (_, View_signature {name; input_ty; output_ty}, k) -> ( + let input = accu in + let ((c, _entrypoint_is_ignored), stack) = stack in + let ctxt = update_context gas ctxt in + Contract.get_script ctxt c >>=? fun (ctxt, script_opt) -> + let return_none ctxt = + (step [@ocaml.tailcall]) + (outdated ctxt, sc) + (update_local_gas_counter ctxt) + k + ks + None + stack + in + match script_opt with + | None -> (return_none [@ocaml.tailcall]) ctxt + | Some script -> ( + parse_script + ~legacy:true + ~allow_forged_in_storage:true + ctxt + script + >>=? fun (Ex_script {storage; storage_type; views; _}, ctxt) -> + Gas.consume ctxt (Interp_costs.view_get name views) + >>?= fun ctxt -> + match SMap.find name views with + | None -> (return_none [@ocaml.tailcall]) ctxt + | Some view -> ( + let view_result = + Script_ir_translator.parse_view_returning + ctxt + ~legacy:true + storage_type + view + in + trace_eval + (fun () -> + Script_tc_errors.Ill_typed_contract + (Micheline.strip_locations view.view_code, [])) + view_result + >>=? fun (Ex_view f, ctxt) -> + match f with + | Lam + ( { + kloc; + kaft = Item_t (aft_ty, Bot_t, _); + kbef = Item_t (bef_ty, Bot_t, _); + kinstr; + }, + _script_view ) -> ( + pair_t + kloc + (input_ty, None, None) + (storage_type, None, None) + ~annot:None + >>?= fun pair_ty -> + let open Gas_monad in + let io_ty = + Script_ir_translator.merge_types + ~merge_type_error_flag:Default_merge_type_error + ~legacy:true + kloc + aft_ty + output_ty + >>$ fun (out_eq, _ty) -> + merge_types + ~merge_type_error_flag:Default_merge_type_error + ~legacy:true + kloc + bef_ty + pair_ty + >|$ fun (in_eq, _ty) -> (out_eq, in_eq) + in + Gas_monad.run ctxt io_ty >>?= fun (eq, ctxt) -> + match eq with + | Error _ -> (return_none [@ocaml.tailcall]) ctxt + | Ok (Eq, Eq) -> ( + let kkinfo = kinfo_of_kinstr k in + match kkinfo.kstack_ty with + | Item_t (_, s, a) -> + let kstack_ty = Item_t (output_ty, s, a) in + let kkinfo = {kkinfo with kstack_ty} in + let ks = KCons (ICons_some (kkinfo, k), ks) in + (step [@ocaml.tailcall]) + ( outdated ctxt, + { + sc with + source = sc.self; + self = c; + amount = Tez.zero; + } ) + (update_local_gas_counter ctxt) + kinstr + (KView_exit (sc, KReturn (stack, ks))) + (input, storage) + (EmptyCell, EmptyCell)))))) + | ICreate_contract + { + storage_type; + arg_type; + lambda = Lam (_, code); + views; + root_name; + k; + _; + } -> + (* Removed the instruction's arguments manager, spendable and delegatable *) + let delegate = accu in + let (credit, (init, stack)) = stack in + create_contract + g + gas + storage_type + arg_type + code + views + root_name + delegate + credit + init + >>=? fun (res, contract, ctxt, gas) -> + let stack = ((contract, "default"), stack) in + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks res stack + | ISet_delegate (_, k) -> + let delegate = accu in + let operation = Delegation delegate in + let ctxt = update_context gas ctxt in + fresh_internal_nonce ctxt >>?= fun (ctxt, nonce) -> + let res = + (Internal_operation {source = sc.self; operation; nonce}, None) + in + let gas = update_local_gas_counter ctxt in + let ctxt = outdated ctxt in + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks res stack + | IBalance (_, k) -> + let ctxt = update_context gas ctxt in + Contract.get_balance_carbonated ctxt sc.self + >>=? fun (ctxt, balance) -> + let gas = update_local_gas_counter ctxt in + let ctxt = outdated ctxt in + let g = (ctxt, sc) in + (step [@ocaml.tailcall]) g gas k ks balance (accu, stack) + | ILevel (_, k) -> + (step [@ocaml.tailcall]) g gas k ks sc.level (accu, stack) + | INow (_, k) -> (step [@ocaml.tailcall]) g gas k ks sc.now (accu, stack) + | ICheck_signature (_, k) -> + let key = accu and (signature, (message, stack)) = stack in + let res = Signature.check key signature message in + (step [@ocaml.tailcall]) g gas k ks res stack + | IHash_key (_, k) -> + let key = accu in + let res = Signature.Public_key.hash key in + (step [@ocaml.tailcall]) g gas k ks res stack + | IBlake2b (_, k) -> + let bytes = accu in + let hash = Raw_hashes.blake2b bytes in + (step [@ocaml.tailcall]) g gas k ks hash stack + | ISha256 (_, k) -> + let bytes = accu in + let hash = Raw_hashes.sha256 bytes in + (step [@ocaml.tailcall]) g gas k ks hash stack + | ISha512 (_, k) -> + let bytes = accu in + let hash = Raw_hashes.sha512 bytes in + (step [@ocaml.tailcall]) g gas k ks hash stack + | ISource (_, k) -> + let res = (sc.payer, "default") in + (step [@ocaml.tailcall]) g gas k ks res (accu, stack) + | ISender (_, k) -> + let res = (sc.source, "default") in + (step [@ocaml.tailcall]) g gas k ks res (accu, stack) + | ISelf (_, ty, entrypoint, k) -> + let res = (ty, (sc.self, entrypoint)) in + (step [@ocaml.tailcall]) g gas k ks res (accu, stack) + | ISelf_address (_, k) -> + let res = (sc.self, "default") in + (step [@ocaml.tailcall]) g gas k ks res (accu, stack) + | IAmount (_, k) -> + let accu = sc.amount and stack = (accu, stack) in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IDig (_, _n, n', k) -> + let ((accu, stack), x) = + interp_stack_prefix_preserving_operation + (fun v stack -> (stack, v)) + n' + accu + stack + in + let accu = x and stack = (accu, stack) in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IDug (_, _n, n', k) -> + let v = accu in + let (accu, stack) = stack in + let ((accu, stack), ()) = + interp_stack_prefix_preserving_operation + (fun accu stack -> ((v, (accu, stack)), ())) + n' + accu + stack + in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IDipn (_, _n, n', b, k) -> + let (accu, stack, restore_prefix) = kundip n' accu stack k in + let ks = KCons (restore_prefix, ks) in + (step [@ocaml.tailcall]) g gas b ks accu stack + | IDropn (_, _n, n', k) -> + let stack = + let rec aux : + type a s b t. + (b, t, b, t, a, s, a, s) stack_prefix_preservation_witness -> + a -> + s -> + b * t = + fun w accu stack -> + match w with + | KRest -> (accu, stack) + | KPrefix (_, w) -> + let (accu, stack) = stack in + aux w accu stack + in + aux n' accu stack + in + let (accu, stack) = stack in + (step [@ocaml.tailcall]) g gas k ks accu stack + | ISapling_empty_state (_, memo_size, k) -> + let state = Sapling.empty_state ~memo_size () in + (step [@ocaml.tailcall]) g gas k ks state (accu, stack) + | ISapling_verify_update (_, k) -> ( + let transaction = accu in + let (state, stack) = stack in + let address = Contract.to_b58check sc.self in + let chain_id = Chain_id.to_b58check sc.chain_id in + let anti_replay = address ^ chain_id in + let ctxt = update_context gas ctxt in + Sapling.verify_update ctxt state transaction anti_replay + >>=? fun (ctxt, balance_state_opt) -> + let gas = update_local_gas_counter ctxt in + let ctxt = outdated ctxt in + match balance_state_opt with + | Some (balance, state) -> + let state = Some (Script_int.of_int64 balance, state) in + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks state stack + | None -> (step [@ocaml.tailcall]) (ctxt, sc) gas k ks None stack) + | IChainId (_, k) -> + let accu = sc.chain_id and stack = (accu, stack) in + (step [@ocaml.tailcall]) g gas k ks accu stack + | INever _ -> ( match accu with _ -> .) + | IVoting_power (_, k) -> + let key_hash = accu in + let ctxt = update_context gas ctxt in + Vote.get_voting_power ctxt key_hash >>=? fun (ctxt, rolls) -> + let power = Script_int.(abs (of_int32 rolls)) in + let gas = update_local_gas_counter ctxt in + let ctxt = outdated ctxt in + (step [@ocaml.tailcall]) (ctxt, sc) gas k ks power stack + | ITotal_voting_power (_, k) -> + let ctxt = update_context gas ctxt in + Vote.get_total_voting_power ctxt >>=? fun (ctxt, rolls) -> + let power = Script_int.(abs (of_int32 rolls)) in + let gas = update_local_gas_counter ctxt in + let ctxt = outdated ctxt in + let g = (ctxt, sc) in + (step [@ocaml.tailcall]) g gas k ks power (accu, stack) + | IKeccak (_, k) -> + let bytes = accu in + let hash = Raw_hashes.keccak256 bytes in + (step [@ocaml.tailcall]) g gas k ks hash stack + | ISha3 (_, k) -> + let bytes = accu in + let hash = Raw_hashes.sha3_256 bytes in + (step [@ocaml.tailcall]) g gas k ks hash stack + | IAdd_bls12_381_g1 (_, k) -> + let x = accu and (y, stack) = stack in + let accu = Bls12_381.G1.add x y in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IAdd_bls12_381_g2 (_, k) -> + let x = accu and (y, stack) = stack in + let accu = Bls12_381.G2.add x y in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IAdd_bls12_381_fr (_, k) -> + let x = accu and (y, stack) = stack in + let accu = Bls12_381.Fr.add x y in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IMul_bls12_381_g1 (_, k) -> + let x = accu and (y, stack) = stack in + let accu = Bls12_381.G1.mul x y in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IMul_bls12_381_g2 (_, k) -> + let x = accu and (y, stack) = stack in + let accu = Bls12_381.G2.mul x y in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IMul_bls12_381_fr (_, k) -> + let x = accu and (y, stack) = stack in + let accu = Bls12_381.Fr.mul x y in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IMul_bls12_381_fr_z (_, k) -> + let x = accu and (y, stack) = stack in + let x = Bls12_381.Fr.of_z (Script_int.to_zint x) in + let res = Bls12_381.Fr.mul x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IMul_bls12_381_z_fr (_, k) -> + let y = accu and (x, stack) = stack in + let x = Bls12_381.Fr.of_z (Script_int.to_zint x) in + let res = Bls12_381.Fr.mul x y in + (step [@ocaml.tailcall]) g gas k ks res stack + | IInt_bls12_381_fr (_, k) -> + let x = accu in + let res = Script_int.of_zint (Bls12_381.Fr.to_z x) in + (step [@ocaml.tailcall]) g gas k ks res stack + | INeg_bls12_381_g1 (_, k) -> + let x = accu in + let accu = Bls12_381.G1.negate x in + (step [@ocaml.tailcall]) g gas k ks accu stack + | INeg_bls12_381_g2 (_, k) -> + let x = accu in + let accu = Bls12_381.G2.negate x in + (step [@ocaml.tailcall]) g gas k ks accu stack + | INeg_bls12_381_fr (_, k) -> + let x = accu in + let accu = Bls12_381.Fr.negate x in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IPairing_check_bls12_381 (_, k) -> + let pairs = accu in + let check = Bls12_381.pairing_check pairs.elements in + (step [@ocaml.tailcall]) g gas k ks check stack + | IComb (_, _, witness, k) -> + let rec aux : + type before after. + (before, after) comb_gadt_witness -> before -> after = + fun witness stack -> + match (witness, stack) with + | (Comb_one, stack) -> stack + | (Comb_succ witness', (a, tl)) -> + let (b, tl') = aux witness' tl in + ((a, b), tl') + in + let stack = aux witness (accu, stack) in + let (accu, stack) = stack in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IUncomb (_, _, witness, k) -> + let rec aux : + type before after. + (before, after) uncomb_gadt_witness -> before -> after = + fun witness stack -> + match (witness, stack) with + | (Uncomb_one, stack) -> stack + | (Uncomb_succ witness', ((a, b), tl)) -> (a, aux witness' (b, tl)) + in + let stack = aux witness (accu, stack) in + let (accu, stack) = stack in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IComb_get (_, _, witness, k) -> + let comb = accu in + let rec aux : + type before after. + (before, after) comb_get_gadt_witness -> before -> after = + fun witness comb -> + match (witness, comb) with + | (Comb_get_zero, v) -> v + | (Comb_get_one, (a, _)) -> a + | (Comb_get_plus_two witness', (_, b)) -> aux witness' b + in + let accu = aux witness comb in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IComb_set (_, _, witness, k) -> + let value = accu and (comb, stack) = stack in + let rec aux : + type value before after. + (value, before, after) comb_set_gadt_witness -> + value -> + before -> + after = + fun witness value item -> + match (witness, item) with + | (Comb_set_zero, _) -> value + | (Comb_set_one, (_hd, tl)) -> (value, tl) + | (Comb_set_plus_two witness', (hd, tl)) -> + (hd, aux witness' value tl) + in + let accu = aux witness value comb in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IDup_n (_, _, witness, k) -> + let rec aux : + type before after. + (before, after) dup_n_gadt_witness -> before -> after = + fun witness stack -> + match (witness, stack) with + | (Dup_n_zero, (a, _)) -> a + | (Dup_n_succ witness', (_, tl)) -> aux witness' tl + in + let stack = (accu, stack) in + let accu = aux witness stack in + (step [@ocaml.tailcall]) g gas k ks accu stack + (* Tickets *) + | ITicket (_, k) -> + let contents = accu and (amount, stack) = stack in + let ticketer = sc.self in + let accu = {ticketer; contents; amount} in + (step [@ocaml.tailcall]) g gas k ks accu stack + | IRead_ticket (_, k) -> + let {ticketer; contents; amount} = accu in + let stack = (accu, stack) in + let accu = ((ticketer, "default"), (contents, amount)) in + (step [@ocaml.tailcall]) g gas k ks accu stack + | ISplit_ticket (_, k) -> + let ticket = accu and ((amount_a, amount_b), stack) = stack in + let result = + if + Compare.Int.( + Script_int.(compare (add_n amount_a amount_b) ticket.amount) = 0) + then + Some + ( {ticket with amount = amount_a}, + {ticket with amount = amount_b} ) + else None + in + (step [@ocaml.tailcall]) g gas k ks result stack + | IJoin_tickets (_, contents_ty, k) -> + let (ticket_a, ticket_b) = accu in + let result = + if + Compare.Int.( + Contract.compare ticket_a.ticketer ticket_b.ticketer = 0 + && Script_comparable.compare_comparable + contents_ty + ticket_a.contents + ticket_b.contents + = 0) + then + Some + { + ticketer = ticket_a.ticketer; + contents = ticket_a.contents; + amount = Script_int.add_n ticket_a.amount ticket_b.amount; + } + else None + in + (step [@ocaml.tailcall]) g gas k ks result stack + | IOpen_chest (_, k) -> + let open Timelock in + let chest_key = accu in + let (chest, (time_z, stack)) = stack in + (* If the time is not an integer we then consider the proof as + incorrect. Indeed the verification asks for an integer for practical reasons. + Therefore no proof can be correct.*) + let accu = + match Alpha_context.Script_int.to_int time_z with + | None -> R false + | Some time -> ( + match open_chest chest chest_key ~time with + | Correct bytes -> L bytes + | Bogus_cipher -> R false + | Bogus_opening -> R true) + in + (step [@ocaml.tailcall]) g gas k ks accu stack) + +(* + + Zero-cost logging + ================= + +*) + +(* + + The following functions insert a logging instruction and modify the + continuation to continue the logging process in the next execution + steps. + + There is a special treatment of instructions that generate fresh + continuations: we pass a constructor as argument to their + evaluation rules so that they can instrument these fresh + continuations by themselves. + + This on-the-fly instrumentation of the execution allows zero-cost + logging since logging instructions are only introduced if an + initial logging continuation is pushed in the initial continuation + that starts the evaluation. + +*) +and log : + type a s b t r f. logger * logging_event -> (a, s, b, t, r, f) step_type = + fun (logger, event) ((ctxt, _) as g) gas k ks accu stack -> + (match (k, event) with + | (ILog _, LogEntry) -> () + | (_, LogEntry) -> log_entry logger ctxt gas k accu stack + | (_, LogExit prev_kinfo) -> log_exit logger ctxt gas prev_kinfo k accu stack) ; + let k = log_next_kinstr logger k in + let with_log k = match k with KLog _ -> k | _ -> KLog (k, logger) in + match k with + | IList_map (_, body, k) -> + (ilist_map [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack + | IList_iter (_, body, k) -> + (ilist_iter [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack + | ISet_iter (_, body, k) -> + (iset_iter [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack + | IMap_map (_, body, k) -> + (imap_map [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack + | IMap_iter (_, body, k) -> + (imap_iter [@ocaml.tailcall]) with_log g gas (body, k) ks accu stack + | ILoop (_, body, k) -> + let ks = with_log (KLoop_in (body, KCons (k, ks))) in + (next [@ocaml.tailcall]) g gas ks accu stack + | ILoop_left (_, bl, br) -> + let ks = with_log (KLoop_in_left (bl, KCons (br, ks))) in + (next [@ocaml.tailcall]) g gas ks accu stack + | IMul_teznat (kinfo, k) -> + let extra = (kinfo, k) in + (imul_teznat [@ocaml.tailcall]) (Some logger) g gas extra ks accu stack + | IMul_nattez (kinfo, k) -> + let extra = (kinfo, k) in + (imul_nattez [@ocaml.tailcall]) (Some logger) g gas extra ks accu stack + | ILsl_nat (kinfo, k) -> + let extra = (kinfo, k) in + (ilsl_nat [@ocaml.tailcall]) (Some logger) g gas extra ks accu stack + | ILsr_nat (kinfo, k) -> + let extra = (kinfo, k) in + (ilsr_nat [@ocaml.tailcall]) (Some logger) g gas extra ks accu stack + | IFailwith (_, kloc, tv) -> + (ifailwith [@ocaml.tailcall]) (Some logger) g gas kloc tv accu + | IExec (_, k) -> + (iexec [@ocaml.tailcall]) (Some logger) g gas k ks accu stack + | _ -> (step [@ocaml.tailcall]) g gas k (with_log ks) accu stack + [@@inline] + +and klog : + type a s r f. + logger -> + outdated_context * step_constants -> + local_gas_counter -> + (a, s, r, f) continuation -> + (a, s, r, f) continuation -> + a -> + s -> + (r * f * outdated_context * local_gas_counter) tzresult Lwt.t = + fun logger g gas ks0 ks accu stack -> + (match ks with KLog _ -> () | _ -> log_control logger ks) ; + let enable_log ki = log_kinstr logger ki in + let mk k = match k with KLog _ -> k | _ -> KLog (k, logger) in + match ks with + | KCons (ki, ks') -> + let log = enable_log ki in + let ks = mk ks' in + (step [@ocaml.tailcall]) g gas log ks accu stack + | KNil -> (next [@ocaml.tailcall]) g gas ks accu stack + | KLoop_in (ki, ks') -> + let ks' = mk ks' in + let ki = enable_log ki in + (kloop_in [@ocaml.tailcall]) g gas ks0 ki ks' accu stack + | KReturn (stack', ks') -> + let ks' = mk ks' in + let ks = KReturn (stack', ks') in + (next [@ocaml.tailcall]) g gas ks accu stack + | KMap_head (f, ks) -> (next [@ocaml.tailcall]) g gas ks (f accu) stack + | KLoop_in_left (ki, ks') -> + let ks' = mk ks' in + let ki = enable_log ki in + (kloop_in_left [@ocaml.tailcall]) g gas ks0 ki ks' accu stack + | KUndip (x, ks') -> + let ks' = mk ks' in + let ks = KUndip (x, ks') in + (next [@ocaml.tailcall]) g gas ks accu stack + | KIter (body, xs, ks') -> + let ks' = mk ks' in + let body = enable_log body in + (kiter [@ocaml.tailcall]) mk g gas (body, xs) ks' accu stack + | KList_enter_body (body, xs, ys, len, ks') -> + let ks' = mk ks' in + let extra = (body, xs, ys, len) in + (klist_enter [@ocaml.tailcall]) mk g gas extra ks' accu stack + | KList_exit_body (body, xs, ys, len, ks') -> + let ks' = mk ks' in + let extra = (body, xs, ys, len) in + (klist_exit [@ocaml.tailcall]) mk g gas extra ks' accu stack + | KMap_enter_body (body, xs, ys, ks') -> + let ks' = mk ks' in + (kmap_enter [@ocaml.tailcall]) mk g gas (body, xs, ys) ks' accu stack + | KMap_exit_body (body, xs, ys, yk, ks') -> + let ks' = mk ks' in + (kmap_exit [@ocaml.tailcall]) mk g gas (body, xs, ys, yk) ks' accu stack + | KView_exit (orig_step_constants, ks') -> + let g = (fst g, orig_step_constants) in + (next [@ocaml.tailcall]) g gas ks' accu stack + | KLog (_, _) -> + (* This case should never happen. *) + (next [@ocaml.tailcall]) g gas ks accu stack + [@@inline] + +(* + + Entrypoints + =========== + +*) + +let step_descr ~log_now logger (ctxt, sc) descr accu stack = + let gas = (Gas.remaining_operation_gas ctxt :> int) in + (match logger with + | None -> step (outdated ctxt, sc) gas descr.kinstr KNil accu stack + | Some logger -> + (if log_now then + let kinfo = kinfo_of_kinstr descr.kinstr in + logger.log_interp descr.kinstr ctxt kinfo.iloc descr.kbef (accu, stack)) ; + let log = + ILog (kinfo_of_kinstr descr.kinstr, LogEntry, logger, descr.kinstr) + in + step (outdated ctxt, sc) gas log KNil accu stack) + >>=? fun (accu, stack, ctxt, gas) -> + return (accu, stack, update_context gas ctxt) + +let interp logger g (Lam (code, _)) arg = + step_descr ~log_now:true logger g code arg (EmptyCell, EmptyCell) + >|=? fun (ret, (EmptyCell, EmptyCell), ctxt) -> (ret, ctxt) + +let kstep logger ctxt step_constants kinstr accu stack = + let gas = (Gas.remaining_operation_gas ctxt :> int) in + let kinstr = + match logger with + | None -> kinstr + | Some logger -> ILog (kinfo_of_kinstr kinstr, LogEntry, logger, kinstr) + in + step (outdated ctxt, step_constants) gas kinstr KNil accu stack + >>=? fun (accu, stack, ctxt, gas) -> + return (accu, stack, update_context gas ctxt) + +let internal_step ctxt step_constants gas kinstr accu stack = + step (ctxt, step_constants) gas kinstr KNil accu stack + +let step logger ctxt step_constants descr stack = + step_descr ~log_now:false logger (ctxt, step_constants) descr stack + +(* + + High-level functions + ==================== + +*) +let execute logger ctxt mode step_constants ~entrypoint ~internal + unparsed_script cached_script arg : + (Script.expr + * packed_internal_operation list + * context + * Lazy_storage.diffs option + * ex_script + * int) + tzresult + Lwt.t = + (match cached_script with + | None -> + parse_script + ctxt + unparsed_script + ~legacy:true + ~allow_forged_in_storage:true + | Some ex_script -> return (ex_script, ctxt)) + >>=? fun ( Ex_script + { + code_size; + code; + arg_type; + storage; + storage_type; + root_name; + views; + }, + ctxt ) -> + record_trace + (Bad_contract_parameter step_constants.self) + (find_entrypoint arg_type ~root_name entrypoint) + >>?= fun (box, _) -> + trace + (Bad_contract_parameter step_constants.self) + (parse_data ctxt ~legacy:false ~allow_forged:internal arg_type (box arg)) + >>=? fun (arg, ctxt) -> + Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + unparsed_script.code + >>?= fun (script_code, ctxt) -> + Script_ir_translator.collect_lazy_storage ctxt arg_type arg + >>?= fun (to_duplicate, ctxt) -> + Script_ir_translator.collect_lazy_storage ctxt storage_type storage + >>?= fun (to_update, ctxt) -> + trace + (Runtime_contract_error (step_constants.self, script_code)) + (interp logger (ctxt, step_constants) code (arg, storage)) + >>=? fun ((ops, storage), ctxt) -> + Script_ir_translator.extract_lazy_storage_diff + ctxt + mode + ~temporary:false + ~to_duplicate + ~to_update + storage_type + storage + >>=? fun (storage, lazy_storage_diff, ctxt) -> + trace + Cannot_serialize_storage + ( unparse_data ctxt mode storage_type storage + >>=? fun (unparsed_storage, ctxt) -> + Lwt.return + ( Gas.consume ctxt (Script.strip_locations_cost unparsed_storage) + >>? fun ctxt -> ok (Micheline.strip_locations unparsed_storage, ctxt) ) + ) + >>=? fun (unparsed_storage, ctxt) -> + Lwt.return + (let (ops, op_diffs) = List.split ops.elements in + let lazy_storage_diff = + match + List.flatten + (List.map + (Option.value ~default:[]) + (op_diffs @ [lazy_storage_diff])) + with + | [] -> None + | diff -> Some diff + in + let script = + Ex_script + {code_size; code; arg_type; storage; storage_type; root_name; views} + in + (* We consume gas after the fact in order to not have to instrument + [script_size] (for efficiency). + This is safe, as we already pay gas proportional to storage size + in [unparse_data]. *) + let (size, cost) = Script_ir_translator.script_size script in + Gas.consume ctxt cost >>? fun ctxt -> + ok (unparsed_storage, ops, ctxt, lazy_storage_diff, script, size)) + +type execution_result = { + ctxt : context; + storage : Script.expr; + lazy_storage_diff : Lazy_storage.diffs option; + operations : packed_internal_operation list; +} + +let execute ?logger ctxt ~cached_script mode step_constants ~script ~entrypoint + ~parameter ~internal = + execute + logger + ctxt + mode + step_constants + ~entrypoint + ~internal + script + cached_script + (Micheline.root parameter) + >|=? fun (storage, operations, ctxt, lazy_storage_diff, ex_script, approx_size) + -> ({ctxt; storage; lazy_storage_diff; operations}, (ex_script, approx_size)) + +(* + + Internals + ========= + +*) + +(* + + We export the internals definitions for tool that requires + a white-box view on the interpreter, typically snoop, the + gas model inference engine. + +*) +module Internals = struct + type nonrec local_gas_counter = local_gas_counter + + type nonrec outdated_context = outdated_context = + | OutDatedContext of Alpha_context.t + [@@unboxed] + + let next logger g gas ks accu stack = + let ks = + match logger with None -> ks | Some logger -> KLog (ks, logger) + in + next g gas ks accu stack + + let step (ctxt, step_constants) gas ks accu stack = + internal_step ctxt step_constants gas ks accu stack +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_interpreter.mli b/src/proto_012_PsiThaCa/lib_protocol/script_interpreter.mli new file mode 100644 index 000000000000..2f2f5b7c672b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_interpreter.mli @@ -0,0 +1,168 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This is the Michelson interpreter. + + This module offers a way to execute either a Michelson script or a + Michelson instruction. + + Implementation details are documented in the .ml file. + +*) + +open Alpha_context +open Script_typed_ir + +type error += Reject of Script.location * Script.expr * execution_trace option + +type error += Overflow of Script.location * execution_trace option + +type error += Runtime_contract_error : Contract.t * Script.expr -> error + +type error += Bad_contract_parameter of Contract.t (* `Permanent *) + +type error += Cannot_serialize_failure + +type error += Cannot_serialize_storage + +type error += Michelson_too_many_recursive_calls + +type execution_result = { + ctxt : context; + storage : Script.expr; + lazy_storage_diff : Lazy_storage.diffs option; + operations : packed_internal_operation list; +} + +type step_constants = Script_typed_ir.step_constants = { + source : Contract.t; + payer : Contract.t; + self : Contract.t; + amount : Tez.t; + chain_id : Chain_id.t; + now : Script_timestamp.t; + level : Script_int.n Script_int.num; +} + +val step : + logger option -> + context -> + Script_typed_ir.step_constants -> + ('a, 's, 'r, 'f) Script_typed_ir.kdescr -> + 'a -> + 's -> + ('r * 'f * context) tzresult Lwt.t + +(** [execute ?logger ctxt ~cached_script mode step_constant ~script + ~entrypoint ~parameter ~internal] interprets the [script]'s + [entrypoint] for a given [parameter]. + + This will update the local storage of the contract + [step_constants.self]. Other pieces of contextual information + ([source], [payer], [amount], and [chaind_id]) are also passed in + [step_constant]. + + [internal] is [true] if and only if the execution happens within an + internal operation. + + [mode] is the unparsing mode, as declared by + {!Script_ir_translator}. + + [cached_script] is the cached elaboration of [script], that is the + well typed abstract syntax tree produced by the type elaboration of + [script] during a previous execution and stored in the in-memory + cache. + +*) +val execute : + ?logger:logger -> + Alpha_context.t -> + cached_script:Script_ir_translator.ex_script option -> + Script_ir_translator.unparsing_mode -> + step_constants -> + script:Script.t -> + entrypoint:string -> + parameter:Script.expr -> + internal:bool -> + (execution_result * (Script_ir_translator.ex_script * int)) tzresult Lwt.t + +(** [kstep logger ctxt step_constants kinstr accu stack] interprets the + script represented by [kinstr] under the context [ctxt]. This will + turn a stack whose topmost element is [accu] and remaining elements + [stack] into a new accumulator and a new stack. This function also + returns an updated context. If [logger] is given, [kstep] calls back + its functions at specific points of the execution. The execution is + parameterized by some [step_constants]. *) +val kstep : + logger option -> + context -> + step_constants -> + ('a, 's, 'r, 'f) Script_typed_ir.kinstr -> + 'a -> + 's -> + ('r * 'f * context) tzresult Lwt.t + +(** Internal interpretation loop + ============================ + + The following types and the following functions are exposed + in the interface to allow the inference of a gas model in + snoop. + + Strictly speaking, they should not be considered as part of + the interface since they expose implementation details that + may change in the future. + +*) + +module Internals : sig + (** Internally, the interpretation loop uses a local gas counter. *) + type local_gas_counter = int + + (** During the evaluation, the gas level in the context is outdated. + See comments in the implementation file for more details. *) + type outdated_context = OutDatedContext of context [@@unboxed] + + (** [next logger (ctxt, step_constants) local_gas_counter ks accu + stack] is an internal function which interprets the continuation + [ks] to execute the interpreter on the current A-stack. *) + val next : + logger option -> + outdated_context * step_constants -> + local_gas_counter -> + ('a, 's, 'r, 'f) continuation -> + 'a -> + 's -> + ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t + + val step : + outdated_context * step_constants -> + local_gas_counter -> + ('a, 's, 'r, 'f) Script_typed_ir.kinstr -> + 'a -> + 's -> + ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_interpreter_defs.ml b/src/proto_012_PsiThaCa/lib_protocol/script_interpreter_defs.ml new file mode 100644 index 000000000000..0aacd527bc73 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_interpreter_defs.ml @@ -0,0 +1,855 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* + + This module provides auxiliary definitions used in the interpreter. + + These are internal private definitions. Do not rely on them outside + the interpreter. + +*) + +open Alpha_context +open Script +open Script_typed_ir +open Script_ir_translator +open Local_gas_counter + +(* + + Computing the cost of Michelson instructions + ============================================ + + The function [cost_of_instr] provides a cost model for Michelson + instructions. It is used by the interpreter to track the + consumption of gas. This consumption may depend on the values + on the stack. + + *) + +module Interp_costs = Michelson_v1_gas.Cost_of.Interpreter + +let cost_of_instr : type a s r f. (a, s, r, f) kinstr -> a -> s -> Gas.cost = + fun i accu stack -> + match i with + | IList_map _ -> + let list = accu in + Interp_costs.list_map list + | IList_iter _ -> + let list = accu in + Interp_costs.list_iter list + | ISet_iter _ -> + let set = accu in + Interp_costs.set_iter set + | ISet_mem _ -> + let v = accu and (set, _) = stack in + Interp_costs.set_mem v set + | ISet_update _ -> + let v = accu and (_, (set, _)) = stack in + Interp_costs.set_update v set + | IMap_map _ -> + let map = accu in + Interp_costs.map_map map + | IMap_iter _ -> + let map = accu in + Interp_costs.map_iter map + | IMap_mem _ -> + let v = accu and (map, _) = stack in + Interp_costs.map_mem v map + | IMap_get _ -> + let v = accu and (map, _) = stack in + Interp_costs.map_get v map + | IMap_update _ -> + let k = accu and (_, (map, _)) = stack in + Interp_costs.map_update k map + | IMap_get_and_update _ -> + let k = accu and (_, (map, _)) = stack in + Interp_costs.map_get_and_update k map + | IBig_map_mem _ -> + let (map, _) = stack in + Interp_costs.big_map_mem map.diff + | IBig_map_get _ -> + let (map, _) = stack in + Interp_costs.big_map_get map.diff + | IBig_map_update _ -> + let (_, (map, _)) = stack in + Interp_costs.big_map_update map.diff + | IBig_map_get_and_update _ -> + let (_, (map, _)) = stack in + Interp_costs.big_map_get_and_update map.diff + | IAdd_seconds_to_timestamp _ -> + let n = accu and (t, _) = stack in + Interp_costs.add_seconds_timestamp n t + | IAdd_timestamp_to_seconds _ -> + let t = accu and (n, _) = stack in + Interp_costs.add_timestamp_seconds t n + | ISub_timestamp_seconds _ -> + let t = accu and (n, _) = stack in + Interp_costs.sub_timestamp_seconds t n + | IDiff_timestamps _ -> + let t1 = accu and (t2, _) = stack in + Interp_costs.diff_timestamps t1 t2 + | IConcat_string_pair _ -> + let x = accu and (y, _) = stack in + Interp_costs.concat_string_pair x y + | IConcat_string _ -> + let ss = accu in + Interp_costs.concat_string_precheck ss + | ISlice_string _ -> + let _offset = accu in + let (_length, (s, _)) = stack in + Interp_costs.slice_string s + | IConcat_bytes_pair _ -> + let x = accu and (y, _) = stack in + Interp_costs.concat_bytes_pair x y + | IConcat_bytes _ -> + let ss = accu in + Interp_costs.concat_string_precheck ss + | ISlice_bytes _ -> + let (_, (s, _)) = stack in + Interp_costs.slice_bytes s + | IMul_teznat _ -> Interp_costs.mul_teznat + | IMul_nattez _ -> Interp_costs.mul_nattez + | IAbs_int _ -> + let x = accu in + Interp_costs.abs_int x + | INeg _ -> + let x = accu in + Interp_costs.neg x + | IAdd_int _ -> + let x = accu and (y, _) = stack in + Interp_costs.add_int x y + | IAdd_nat _ -> + let x = accu and (y, _) = stack in + Interp_costs.add_nat x y + | ISub_int _ -> + let x = accu and (y, _) = stack in + Interp_costs.sub_int x y + | IMul_int _ -> + let x = accu and (y, _) = stack in + Interp_costs.mul_int x y + | IMul_nat _ -> + let x = accu and (y, _) = stack in + Interp_costs.mul_nat x y + | IEdiv_teznat _ -> + let x = accu and (y, _) = stack in + Interp_costs.ediv_teznat x y + | IEdiv_int _ -> + let x = accu and (y, _) = stack in + Interp_costs.ediv_int x y + | IEdiv_nat _ -> + let x = accu and (y, _) = stack in + Interp_costs.ediv_nat x y + | ILsl_nat _ -> + let x = accu in + Interp_costs.lsl_nat x + | ILsr_nat _ -> + let x = accu in + Interp_costs.lsr_nat x + | IOr_nat _ -> + let x = accu and (y, _) = stack in + Interp_costs.or_nat x y + | IAnd_nat _ -> + let x = accu and (y, _) = stack in + Interp_costs.and_nat x y + | IAnd_int_nat _ -> + let x = accu and (y, _) = stack in + Interp_costs.and_int_nat x y + | IXor_nat _ -> + let x = accu and (y, _) = stack in + Interp_costs.xor_nat x y + | INot_int _ -> + let x = accu in + Interp_costs.not_int x + | ICompare (_, ty, _) -> + let a = accu and (b, _) = stack in + Interp_costs.compare ty a b + | ICheck_signature _ -> + let key = accu and (_, (message, _)) = stack in + Interp_costs.check_signature key message + | IHash_key _ -> + let pk = accu in + Interp_costs.hash_key pk + | IBlake2b _ -> + let bytes = accu in + Interp_costs.blake2b bytes + | ISha256 _ -> + let bytes = accu in + Interp_costs.sha256 bytes + | ISha512 _ -> + let bytes = accu in + Interp_costs.sha512 bytes + | IKeccak _ -> + let bytes = accu in + Interp_costs.keccak bytes + | ISha3 _ -> + let bytes = accu in + Interp_costs.sha3 bytes + | IPairing_check_bls12_381 _ -> + let pairs = accu in + Interp_costs.pairing_check_bls12_381 pairs + | ISapling_verify_update _ -> + let tx = accu in + let inputs = List.length tx.inputs in + let outputs = List.length tx.outputs in + Interp_costs.sapling_verify_update ~inputs ~outputs + | ISplit_ticket _ -> + let ticket = accu and ((amount_a, amount_b), _) = stack in + Interp_costs.split_ticket ticket.amount amount_a amount_b + | IJoin_tickets (_, ty, _) -> + let (ticket_a, ticket_b) = accu in + Interp_costs.join_tickets ty ticket_a ticket_b + | IHalt _ -> Interp_costs.halt + | IDrop _ -> Interp_costs.drop + | IDup _ -> Interp_costs.dup + | ISwap _ -> Interp_costs.swap + | IConst _ -> Interp_costs.const + | ICons_some _ -> Interp_costs.cons_some + | ICons_none _ -> Interp_costs.cons_none + | IIf_none _ -> Interp_costs.if_none + | IOpt_map _ -> Interp_costs.opt_map + | ICons_pair _ -> Interp_costs.cons_pair + | IUnpair _ -> Interp_costs.unpair + | ICar _ -> Interp_costs.car + | ICdr _ -> Interp_costs.cdr + | ICons_left _ -> Interp_costs.cons_left + | ICons_right _ -> Interp_costs.cons_right + | IIf_left _ -> Interp_costs.if_left + | ICons_list _ -> Interp_costs.cons_list + | INil _ -> Interp_costs.nil + | IIf_cons _ -> Interp_costs.if_cons + | IList_size _ -> Interp_costs.list_size + | IEmpty_set _ -> Interp_costs.empty_set + | ISet_size _ -> Interp_costs.set_size + | IEmpty_map _ -> Interp_costs.empty_map + | IMap_size _ -> Interp_costs.map_size + | IEmpty_big_map _ -> Interp_costs.empty_big_map + | IString_size _ -> Interp_costs.string_size + | IBytes_size _ -> Interp_costs.bytes_size + | IAdd_tez _ -> Interp_costs.add_tez + | ISub_tez _ -> Interp_costs.sub_tez + | ISub_tez_legacy _ -> Interp_costs.sub_tez_legacy + | IOr _ -> Interp_costs.bool_or + | IAnd _ -> Interp_costs.bool_and + | IXor _ -> Interp_costs.bool_xor + | INot _ -> Interp_costs.bool_not + | IIs_nat _ -> Interp_costs.is_nat + | IInt_nat _ -> Interp_costs.int_nat + | IInt_bls12_381_fr _ -> Interp_costs.int_bls12_381_fr + | IEdiv_tez _ -> Interp_costs.ediv_tez + | IIf _ -> Interp_costs.if_ + | ILoop _ -> Interp_costs.loop + | ILoop_left _ -> Interp_costs.loop_left + | IDip _ -> Interp_costs.dip + | IExec _ -> Interp_costs.exec + | IApply _ -> Interp_costs.apply + | ILambda _ -> Interp_costs.lambda + | IFailwith _ -> Gas.free + | IEq _ -> Interp_costs.eq + | INeq _ -> Interp_costs.neq + | ILt _ -> Interp_costs.lt + | ILe _ -> Interp_costs.le + | IGt _ -> Interp_costs.gt + | IGe _ -> Interp_costs.ge + | IPack _ -> Gas.free + | IUnpack _ -> + let b = accu in + Interp_costs.unpack b + | IAddress _ -> Interp_costs.address + | IContract _ -> Interp_costs.contract + | ITransfer_tokens _ -> Interp_costs.transfer_tokens + | IView _ -> Interp_costs.view + | IImplicit_account _ -> Interp_costs.implicit_account + | ISet_delegate _ -> Interp_costs.set_delegate + | IBalance _ -> Interp_costs.balance + | ILevel _ -> Interp_costs.level + | INow _ -> Interp_costs.now + | ISapling_empty_state _ -> Interp_costs.sapling_empty_state + | ISource _ -> Interp_costs.source + | ISender _ -> Interp_costs.sender + | ISelf _ -> Interp_costs.self + | ISelf_address _ -> Interp_costs.self_address + | IAmount _ -> Interp_costs.amount + | IDig (_, n, _, _) -> Interp_costs.dign n + | IDug (_, n, _, _) -> Interp_costs.dugn n + | IDipn (_, n, _, _, _) -> Interp_costs.dipn n + | IDropn (_, n, _, _) -> Interp_costs.dropn n + | IChainId _ -> Interp_costs.chain_id + | ICreate_contract _ -> Interp_costs.create_contract + | INever _ -> ( match accu with _ -> .) + | IVoting_power _ -> Interp_costs.voting_power + | ITotal_voting_power _ -> Interp_costs.total_voting_power + | IAdd_bls12_381_g1 _ -> Interp_costs.add_bls12_381_g1 + | IAdd_bls12_381_g2 _ -> Interp_costs.add_bls12_381_g2 + | IAdd_bls12_381_fr _ -> Interp_costs.add_bls12_381_fr + | IMul_bls12_381_g1 _ -> Interp_costs.mul_bls12_381_g1 + | IMul_bls12_381_g2 _ -> Interp_costs.mul_bls12_381_g2 + | IMul_bls12_381_fr _ -> Interp_costs.mul_bls12_381_fr + | INeg_bls12_381_g1 _ -> Interp_costs.neg_bls12_381_g1 + | INeg_bls12_381_g2 _ -> Interp_costs.neg_bls12_381_g2 + | INeg_bls12_381_fr _ -> Interp_costs.neg_bls12_381_fr + | IMul_bls12_381_fr_z _ -> + let z = accu in + Interp_costs.mul_bls12_381_fr_z z + | IMul_bls12_381_z_fr _ -> + let (z, _) = stack in + Interp_costs.mul_bls12_381_z_fr z + | IDup_n (_, n, _, _) -> Interp_costs.dupn n + | IComb (_, n, _, _) -> Interp_costs.comb n + | IUncomb (_, n, _, _) -> Interp_costs.uncomb n + | IComb_get (_, n, _, _) -> Interp_costs.comb_get n + | IComb_set (_, n, _, _) -> Interp_costs.comb_set n + | ITicket _ -> Interp_costs.ticket + | IRead_ticket _ -> Interp_costs.read_ticket + | IOpen_chest _ -> + let _chest_key = accu and (chest, (time, _)) = stack in + Interp_costs.open_chest + ~chest + ~time:(Alpha_context.Script_int.to_zint time) + | ILog _ -> Gas.free + [@@ocaml.inline always] + [@@coq_axiom_with_reason "unreachable expression `.` not handled"] + +let cost_of_control : type a s r f. (a, s, r, f) continuation -> Gas.cost = + fun ks -> + match ks with + | KLog _ -> Gas.free + | KNil -> Interp_costs.Control.nil + | KCons (_, _) -> Interp_costs.Control.cons + | KReturn _ -> Interp_costs.Control.return + | KMap_head (_, _) -> Interp_costs.Control.map_head + | KUndip (_, _) -> Interp_costs.Control.undip + | KLoop_in (_, _) -> Interp_costs.Control.loop_in + | KLoop_in_left (_, _) -> Interp_costs.Control.loop_in_left + | KIter (_, _, _) -> Interp_costs.Control.iter + | KList_enter_body (_, xs, _, len, _) -> + Interp_costs.Control.list_enter_body xs len + | KList_exit_body (_, _, _, _, _) -> Interp_costs.Control.list_exit_body + | KMap_enter_body (_, _, _, _) -> Interp_costs.Control.map_enter_body + | KMap_exit_body (_, _, map, key, _) -> + Interp_costs.Control.map_exit_body key map + | KView_exit (_, _) -> Interp_costs.Control.view_exit + +(* + + [step] calls [consume_instr] at the beginning of each execution step. + + [Local_gas_counter.consume] is used in the implementation of + [IConcat_string] and [IConcat_bytes] because in that special cases, the + cost is expressed with respect to a non-constant-time computation on the + inputs. + +*) + +let consume_instr local_gas_counter k accu stack = + let cost = cost_of_instr k accu stack in + update_and_check local_gas_counter cost + [@@ocaml.inline always] + +let consume_control local_gas_counter ks = + let cost = cost_of_control ks in + update_and_check local_gas_counter cost + [@@ocaml.inline always] + +(* + + Auxiliary functions used by the instrumentation + =============================================== + +*) + +let log_entry logger ctxt gas k accu stack = + let kinfo = kinfo_of_kinstr k in + let ctxt = update_context gas ctxt in + logger.log_entry k ctxt kinfo.iloc kinfo.kstack_ty (accu, stack) + +let log_exit logger ctxt gas kinfo_prev k accu stack = + let kinfo = kinfo_of_kinstr k in + let ctxt = update_context gas ctxt in + logger.log_exit k ctxt kinfo_prev.iloc kinfo.kstack_ty (accu, stack) + +let log_control logger ks = logger.log_control ks + +let get_log = function + | None -> Lwt.return (Ok None) + | Some logger -> logger.get_log () + [@@ocaml.inline always] + +(* [log_kinstr logger i] emits an instruction to instrument the + execution of [i] with [logger]. *) +let log_kinstr logger i = ILog (kinfo_of_kinstr i, LogEntry, logger, i) + +(* [log_next_kinstr logger i] instruments the next instruction of [i] + with the [logger]. + + Notice that the instrumentation breaks the sharing of continuations + that is normally enforced between branches of conditionals. This + has a performance cost. Anyway, the instrumentation allocates many + new [ILog] instructions and [KLog] continuations which makes + the execution of instrumented code significantly slower than + non-instrumented code. "Zero-cost logging" means that the normal + non-instrumented execution is not impacted by the ability to + instrument it, not that the logging itself has no cost. + +*) +let log_next_kinstr logger i = + let apply k = + ILog + ( kinfo_of_kinstr k, + LogExit (kinfo_of_kinstr i), + logger, + log_kinstr logger k ) + in + kinstr_rewritek i {apply} + +(* We pass the identity function when no instrumentation is needed. *) +let id x = x [@@inline] + +(* + + Auxiliary functions used by the interpretation loop + =================================================== + +*) + +(* The following function pops n elements from the stack + and push their reintroduction in the continuations stack. *) +let rec kundip : + type a s e z c u d w b t. + (a, s, e, z, c, u, d, w) stack_prefix_preservation_witness -> + c -> + u -> + (d, w, b, t) kinstr -> + a * s * (e, z, b, t) kinstr = + fun w accu stack k -> + match w with + | KPrefix (kinfo, w) -> + let k = IConst (kinfo, accu, k) in + let (accu, stack) = stack in + kundip w accu stack k + | KRest -> (accu, stack, k) + +(* [apply ctxt gas ty v lam] specializes [lam] by fixing its first + formal argument to [v]. The type of [v] is represented by [ty]. *) +let apply ctxt gas capture_ty capture lam = + let (Lam (descr, expr)) = lam in + let (Item_t (full_arg_ty, _, _)) = descr.kbef in + let ctxt = update_context gas ctxt in + unparse_data ctxt Optimized capture_ty capture >>=? fun (const_expr, ctxt) -> + let loc = Micheline.dummy_location in + unparse_ty ~loc ctxt capture_ty >>?= fun (ty_expr, ctxt) -> + match full_arg_ty with + | Pair_t ((capture_ty, _, _), (arg_ty, _, _), _) -> + let arg_stack_ty = Item_t (arg_ty, Bot_t, None) in + let full_descr = + { + kloc = descr.kloc; + kbef = arg_stack_ty; + kaft = descr.kaft; + kinstr = + (let kinfo_const = {iloc = descr.kloc; kstack_ty = arg_stack_ty} in + let kinfo_pair = + { + iloc = descr.kloc; + kstack_ty = Item_t (capture_ty, arg_stack_ty, None); + } + in + IConst (kinfo_const, capture, ICons_pair (kinfo_pair, descr.kinstr))); + } + in + let full_expr = + Micheline.Seq + ( loc, + [ + Prim (loc, I_PUSH, [ty_expr; const_expr], []); + Prim (loc, I_PAIR, [], []); + expr; + ] ) + in + let lam' = Lam (full_descr, full_expr) in + let gas = update_local_gas_counter ctxt in + return (lam', outdated ctxt, gas) + | _ -> assert false + +(* [transfer (ctxt, sc) gas tez tp p destination entrypoint] + creates an operation that transfers an amount of [tez] to + a contract determined by [(destination, entrypoint)] + instantiated with argument [p] of type [tp]. *) +let transfer (ctxt, sc) gas amount tp p destination entrypoint = + let ctxt = update_context gas ctxt in + collect_lazy_storage ctxt tp p >>?= fun (to_duplicate, ctxt) -> + let to_update = no_lazy_storage_id in + extract_lazy_storage_diff + ctxt + Optimized + tp + p + ~to_duplicate + ~to_update + ~temporary:true + >>=? fun (p, lazy_storage_diff, ctxt) -> + unparse_data ctxt Optimized tp p >>=? fun (p, ctxt) -> + Gas.consume ctxt (Script.strip_locations_cost p) >>?= fun ctxt -> + let operation = + Transaction + { + amount; + destination; + entrypoint; + parameters = Script.lazy_expr (Micheline.strip_locations p); + } + in + fresh_internal_nonce ctxt >>?= fun (ctxt, nonce) -> + let iop = {source = sc.self; operation; nonce} in + let res = (Internal_operation iop, lazy_storage_diff) in + let gas = update_local_gas_counter ctxt in + let ctxt = outdated ctxt in + return (res, ctxt, gas) + +(* [create_contract (ctxt, sc) gas storage_ty param_ty code root_name + delegate credit init] creates an origination operation for a + contract represented by [code], with some [root_name], some initial + [credit] (taken to contract being executed), and an initial storage + [init] of type [storage_ty]. The type of the new contract argument + is [param_ty]. *) + +(* TODO: https://gitlab.com/tezos/tezos/-/issues/1688 + Refactor the sharing part of unparse_script and create_contract *) +let create_contract (ctxt, sc) gas storage_type param_type code views root_name + delegate credit init = + let ctxt = update_context gas ctxt in + let loc = Micheline.dummy_location in + unparse_ty ~loc ctxt param_type >>?= fun (unparsed_param_type, ctxt) -> + let unparsed_param_type = + Script_ir_translator.add_field_annot root_name None unparsed_param_type + in + unparse_ty ~loc ctxt storage_type >>?= fun (unparsed_storage_type, ctxt) -> + let open Micheline in + let view name {input_ty; output_ty; view_code} views = + Prim + ( loc, + K_view, + [ + String (loc, Script_string.to_string name); + input_ty; + output_ty; + view_code; + ], + [] ) + :: views + in + let views = SMap.fold view views [] |> List.rev in + let code = + strip_locations + (Seq + ( loc, + [ + Prim (loc, K_parameter, [unparsed_param_type], []); + Prim (loc, K_storage, [unparsed_storage_type], []); + Prim (loc, K_code, [code], []); + ] + @ views )) + in + collect_lazy_storage ctxt storage_type init >>?= fun (to_duplicate, ctxt) -> + let to_update = no_lazy_storage_id in + extract_lazy_storage_diff + ctxt + Optimized + storage_type + init + ~to_duplicate + ~to_update + ~temporary:true + >>=? fun (init, lazy_storage_diff, ctxt) -> + unparse_data ctxt Optimized storage_type init >>=? fun (storage, ctxt) -> + Gas.consume ctxt (Script.strip_locations_cost storage) >>?= fun ctxt -> + let storage = strip_locations storage in + Contract.fresh_contract_from_current_nonce ctxt >>?= fun (ctxt, contract) -> + let operation = + Origination + { + credit; + delegate; + preorigination = Some contract; + script = + {code = Script.lazy_expr code; storage = Script.lazy_expr storage}; + } + in + fresh_internal_nonce ctxt >>?= fun (ctxt, nonce) -> + let res = + (Internal_operation {source = sc.self; operation; nonce}, lazy_storage_diff) + in + let gas = update_local_gas_counter ctxt in + let ctxt = outdated ctxt in + return (res, contract, ctxt, gas) + +(* [unpack ctxt ty bytes] deserialize [bytes] into a value of type [ty]. *) +let unpack ctxt ~ty ~bytes = + Gas.consume + ctxt + (Script.deserialization_cost_estimated_from_bytes (Bytes.length bytes)) + >>?= fun ctxt -> + if + Compare.Int.(Bytes.length bytes >= 1) + && Compare.Int.(TzEndian.get_uint8 bytes 0 = 0x05) + then + let str = Bytes.sub_string bytes 1 (Bytes.length bytes - 1) in + match Data_encoding.Binary.of_string_opt Script.expr_encoding str with + | None -> + Lwt.return + ( Gas.consume ctxt (Interp_costs.unpack_failed str) >|? fun ctxt -> + (None, ctxt) ) + | Some expr -> ( + parse_data + ctxt + ~legacy:false + ~allow_forged:false + ty + (Micheline.root expr) + >|= function + | Ok (value, ctxt) -> ok (Some value, ctxt) + | Error _ignored -> + Gas.consume ctxt (Interp_costs.unpack_failed str) >|? fun ctxt -> + (None, ctxt)) + else return (None, ctxt) + +(* [interp_stack_prefix_preserving_operation f w accu stack] applies + a well-typed operation [f] under some prefix of the A-stack + exploiting [w] to justify that the shape of the stack is + preserved. *) +let rec interp_stack_prefix_preserving_operation : + type a s b t c u d w result. + (a -> s -> (b * t) * result) -> + (a, s, b, t, c, u, d, w) stack_prefix_preservation_witness -> + c -> + u -> + (d * w) * result = + fun f n accu stk -> + match (n, stk) with + | (KPrefix (_, n), rest) -> + interp_stack_prefix_preserving_operation f n (fst rest) (snd rest) + |> fun ((v, rest'), result) -> ((accu, (v, rest')), result) + | (KRest, v) -> f accu v + +(* + + Some auxiliary functions have complex types and must be annotated + because of GADTs and polymorphic recursion. + + To improve readibility, we introduce their types as abbreviations: + +*) + +type ('a, 's, 'b, 't, 'r, 'f) step_type = + outdated_context * step_constants -> + local_gas_counter -> + ('a, 's, 'b, 't) kinstr -> + ('b, 't, 'r, 'f) continuation -> + 'a -> + 's -> + ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'm, 'n, 'o) kmap_exit_type = + (('c, 'd, 'e, 'f) continuation -> ('a, 'b, 'g, 'h) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('m * 'n, 'c * 'd, 'o, 'c * 'd) kinstr * ('m * 'n) list * ('m, 'o) map * 'm -> + (('m, 'o) map, 'c * 'd, 'e, 'f) continuation -> + 'o -> + 'a * 'b -> + ('g * 'h * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'j, 'k) kmap_enter_type = + (('a, 'b * 'c, 'd, 'e) continuation -> ('a, 'b * 'c, 'd, 'e) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('j * 'k, 'b * 'c, 'a, 'b * 'c) kinstr * ('j * 'k) list * ('j, 'a) map -> + (('j, 'a) map, 'b * 'c, 'd, 'e) continuation -> + 'b -> + 'c -> + ('d * 'e * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'i, 'j) klist_exit_type = + (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('i, 'a * 'b, 'j, 'a * 'b) kinstr * 'i list * 'j list * local_gas_counter -> + ('j boxed_list, 'a * 'b, 'c, 'd) continuation -> + 'j -> + 'a * 'b -> + ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'j) klist_enter_type = + (('b, 'a * 'c, 'd, 'e) continuation -> ('b, 'a * 'c, 'd, 'e) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('j, 'a * 'c, 'b, 'a * 'c) kinstr * 'j list * 'b list * local_gas_counter -> + ('b boxed_list, 'a * 'c, 'd, 'e) continuation -> + 'a -> + 'c -> + ('d * 'e * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f, 'g) kloop_in_left_type = + outdated_context * step_constants -> + local_gas_counter -> + ('c, 'd, 'e, 'f) continuation -> + ('a, 'g, 'c, 'd) kinstr -> + ('b, 'g, 'e, 'f) continuation -> + ('a, 'b) union -> + 'g -> + ('e * 'f * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'r, 'f, 's) kloop_in_type = + outdated_context * step_constants -> + local_gas_counter -> + ('b, 'c, 'r, 'f) continuation -> + ('a, 's, 'b, 'c) kinstr -> + ('a, 's, 'r, 'f) continuation -> + bool -> + 'a * 's -> + ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 's, 'r, 'f) kiter_type = + (('a, 's, 'r, 'f) continuation -> ('a, 's, 'r, 'f) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('b, 'a * 's, 'a, 's) kinstr * 'b list -> + ('a, 's, 'r, 'f) continuation -> + 'a -> + 's -> + ('r * 'f * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h) ilist_map_type = + (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('e, 'a * 'b, 'f, 'a * 'b) kinstr * ('f boxed_list, 'a * 'b, 'g, 'h) kinstr -> + ('g, 'h, 'c, 'd) continuation -> + 'e boxed_list -> + 'a * 'b -> + ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f, 'g) ilist_iter_type = + (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('e, 'a * 'b, 'a, 'b) kinstr * ('a, 'b, 'f, 'g) kinstr -> + ('f, 'g, 'c, 'd) continuation -> + 'e boxed_list -> + 'a * 'b -> + ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f, 'g) iset_iter_type = + (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('e, 'a * 'b, 'a, 'b) kinstr * ('a, 'b, 'f, 'g) kinstr -> + ('f, 'g, 'c, 'd) continuation -> + 'e set -> + 'a * 'b -> + ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i) imap_map_type = + (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('e * 'f, 'a * 'b, 'g, 'a * 'b) kinstr + * (('e, 'g) map, 'a * 'b, 'h, 'i) kinstr -> + ('h, 'i, 'c, 'd) continuation -> + ('e, 'f) map -> + 'a * 'b -> + ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h) imap_iter_type = + (('a, 'b, 'c, 'd) continuation -> ('a, 'b, 'c, 'd) continuation) -> + outdated_context * step_constants -> + local_gas_counter -> + ('e * 'f, 'a * 'b, 'a, 'b) kinstr * ('a, 'b, 'g, 'h) kinstr -> + ('g, 'h, 'c, 'd) continuation -> + ('e, 'f) map -> + 'a * 'b -> + ('c * 'd * outdated_context * local_gas_counter) tzresult Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f) imul_teznat_type = + logger option -> + outdated_context * step_constants -> + local_gas_counter -> + (Tez.t, 'a) kinfo * (Tez.t, 'b, 'c, 'd) kinstr -> + ('c, 'd, 'e, 'f) continuation -> + Tez.t -> + Script_int.n Script_int.num * 'b -> + ('e * 'f * outdated_context * local_gas_counter, error trace) result Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f) imul_nattez_type = + logger option -> + outdated_context * step_constants -> + local_gas_counter -> + (Script_int.n Script_int.num, 'a) kinfo * (Tez.t, 'b, 'c, 'd) kinstr -> + ('c, 'd, 'e, 'f) continuation -> + Script_int.n Script_int.num -> + Tez.t * 'b -> + ('e * 'f * outdated_context * local_gas_counter, error trace) result Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f) ilsl_nat_type = + logger option -> + outdated_context * step_constants -> + local_gas_counter -> + (Script_int.n Script_int.num, 'a) kinfo + * (Script_int.n Script_int.num, 'b, 'c, 'd) kinstr -> + ('c, 'd, 'e, 'f) continuation -> + Script_int.n Script_int.num -> + Script_int.n Script_int.num * 'b -> + ('e * 'f * outdated_context * local_gas_counter, error trace) result Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f) ilsr_nat_type = + logger option -> + outdated_context * step_constants -> + local_gas_counter -> + (Script_int.n Script_int.num, 'a) kinfo + * (Script_int.n Script_int.num, 'b, 'c, 'd) kinstr -> + ('c, 'd, 'e, 'f) continuation -> + Script_int.n Script_int.num -> + Script_int.n Script_int.num * 'b -> + ('e * 'f * outdated_context * local_gas_counter, error trace) result Lwt.t + +type ('a, 'b) ifailwith_type = + logger option -> + outdated_context * step_constants -> + local_gas_counter -> + Script.location -> + 'a ty -> + 'a -> + ('b, error trace) result Lwt.t + +type ('a, 'b, 'c, 'd, 'e, 'f, 'g) iexec_type = + logger option -> + outdated_context * step_constants -> + local_gas_counter -> + ('a, 'b, 'c, 'd) kinstr -> + ('c, 'd, 'e, 'f) continuation -> + 'g -> + ('g, 'a) lambda * 'b -> + ('e * 'f * outdated_context * local_gas_counter) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_ir_annot.ml b/src/proto_012_PsiThaCa/lib_protocol/script_ir_annot.ml new file mode 100644 index 000000000000..90ac3451266a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_ir_annot.ml @@ -0,0 +1,528 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Micheline +open Script_tc_errors + +type var_annot = Var_annot of Non_empty_string.t [@@ocaml.unboxed] + +type type_annot = Type_annot of Non_empty_string.t [@@ocaml.unboxed] + +type field_annot = Field_annot of Non_empty_string.t [@@ocaml.unboxed] + +module FOR_TESTS = struct + let unsafe_var_annot_of_string s = + Var_annot (Non_empty_string.of_string_exn s) + + let unsafe_type_annot_of_string s = + Type_annot (Non_empty_string.of_string_exn s) + + let unsafe_field_annot_of_string s = + Field_annot (Non_empty_string.of_string_exn s) +end + +let some_var_annot_of_string_exn s = + Some (Var_annot (Non_empty_string.of_string_exn s)) + +let some_field_annot_of_string_exn s = + Some (Field_annot (Non_empty_string.of_string_exn s)) + +let default_now_annot = some_var_annot_of_string_exn "now" + +let default_amount_annot = some_var_annot_of_string_exn "amount" + +let default_balance_annot = some_var_annot_of_string_exn "balance" + +let default_level_annot = some_var_annot_of_string_exn "level" + +let default_source_annot = some_var_annot_of_string_exn "source" + +let default_sender_annot = some_var_annot_of_string_exn "sender" + +let default_self_annot = some_var_annot_of_string_exn "self" + +let default_arg_annot = some_var_annot_of_string_exn "arg" + +let lambda_arg_annot = some_var_annot_of_string_exn "@arg" + +let default_param_annot = some_var_annot_of_string_exn "parameter" + +let default_storage_annot = some_var_annot_of_string_exn "storage" + +let default_car_annot = some_field_annot_of_string_exn "car" + +let default_cdr_annot = some_field_annot_of_string_exn "cdr" + +let default_contract_annot = some_field_annot_of_string_exn "contract" + +let default_addr_annot = some_field_annot_of_string_exn "address" + +let default_pack_annot = some_field_annot_of_string_exn "packed" + +let default_unpack_annot = some_field_annot_of_string_exn "unpacked" + +let default_slice_annot = some_field_annot_of_string_exn "slice" + +let default_elt_annot = some_field_annot_of_string_exn "elt" + +let default_key_annot = some_field_annot_of_string_exn "key" + +let default_hd_annot = some_field_annot_of_string_exn "hd" + +let default_tl_annot = some_field_annot_of_string_exn "tl" + +let default_some_annot = some_field_annot_of_string_exn "some" + +let default_left_annot = some_field_annot_of_string_exn "left" + +let default_right_annot = some_field_annot_of_string_exn "right" + +let default_sapling_state_annot = some_var_annot_of_string_exn "sapling" + +let default_sapling_balance_annot = + some_var_annot_of_string_exn "sapling_balance" + +let unparse_type_annot : type_annot option -> string list = function + | None -> [] + | Some (Type_annot a) -> [":" ^ (a :> string)] + +let unparse_var_annot : var_annot option -> string list = function + | None -> [] + | Some (Var_annot a) -> ["@" ^ (a :> string)] + +let unparse_field_annot : field_annot option -> string list = function + | None -> [] + | Some (Field_annot a) -> ["%" ^ (a :> string)] + +let field_to_var_annot : field_annot option -> var_annot option = function + | None -> None + | Some (Field_annot s) -> Some (Var_annot s) + +let type_to_var_annot : type_annot option -> var_annot option = function + | None -> None + | Some (Type_annot s) -> Some (Var_annot s) + +let var_to_field_annot : var_annot option -> field_annot option = function + | None -> None + | Some (Var_annot s) -> Some (Field_annot s) + +let default_annot ~default = function None -> default | annot -> annot + +let gen_access_annot : + var_annot option -> + ?default:field_annot option -> + field_annot option -> + var_annot option = + fun value_annot ?(default = None) field_annot -> + match (value_annot, field_annot, default) with + | (None, None, _) | (Some _, None, None) -> None + | (None, Some (Field_annot f), _) -> Some (Var_annot f) + | (Some (Var_annot v), None, Some (Field_annot f)) -> + Some (Var_annot (Non_empty_string.cat2 v ~sep:"." f)) + | (Some (Var_annot v), Some (Field_annot f), _) -> + Some (Var_annot (Non_empty_string.cat2 v ~sep:"." f)) + +let merge_type_annot : + legacy:bool -> + type_annot option -> + type_annot option -> + type_annot option tzresult = + fun ~legacy annot1 annot2 -> + match (annot1, annot2) with + | (None, None) | (Some _, None) | (None, Some _) -> Result.return_none + | (Some (Type_annot a1), Some (Type_annot a2)) -> + if legacy || Non_empty_string.(a1 = a2) then ok annot1 + else + error + (Inconsistent_annotations (":" ^ (a1 :> string), ":" ^ (a2 :> string))) + +let merge_field_annot : + legacy:bool -> + field_annot option -> + field_annot option -> + field_annot option tzresult = + fun ~legacy annot1 annot2 -> + match (annot1, annot2) with + | (None, None) | (Some _, None) | (None, Some _) -> Result.return_none + | (Some (Field_annot a1), Some (Field_annot a2)) -> + if legacy || Non_empty_string.(a1 = a2) then ok annot1 + else + error + (Inconsistent_annotations ("%" ^ (a1 :> string), "%" ^ (a2 :> string))) + +let merge_var_annot : var_annot option -> var_annot option -> var_annot option = + fun annot1 annot2 -> + match (annot1, annot2) with + | (None, None) | (Some _, None) | (None, Some _) -> None + | (Some (Var_annot a1), Some (Var_annot a2)) -> + if Non_empty_string.(a1 = a2) then annot1 else None + +let error_unexpected_annot loc annot = + match annot with + | [] -> Result.return_unit + | _ :: _ -> error (Unexpected_annotation loc) + +(* Check that the predicate p holds on all s.[k] for k >= i *) +let string_iter p s i = + let len = String.length s in + let rec aux i = + if Compare.Int.(i >= len) then Result.return_unit + else p s.[i] >>? fun () -> aux (i + 1) + in + aux i + +let is_allowed_char = function + | 'a' .. 'z' | 'A' .. 'Z' | '_' | '.' | '%' | '@' | '0' .. '9' -> true + | _ -> false + +(* Valid annotation characters as defined by the allowed_annot_char function from lib_micheline/micheline_parser *) +let check_char loc c = + if is_allowed_char c then Result.return_unit + else error (Unexpected_annotation loc) + +(* This constant is defined in lib_micheline/micheline_parser which is not available in the environment. *) +let max_annot_length = 255 + +type annot_opt = + | Field_annot_opt of Non_empty_string.t option + | Type_annot_opt of Non_empty_string.t option + | Var_annot_opt of Non_empty_string.t option + +let percent = Non_empty_string.of_string_exn "%" + +let percent_percent = Non_empty_string.of_string_exn "%%" + +let at = Non_empty_string.of_string_exn "@" + +let parse_annots loc ?(allow_special_var = false) ?(allow_special_field = false) + l = + (* allow empty annotations as wildcards but otherwise only accept + annotations that start with [a-zA-Z_] *) + let sub_or_wildcard wrap s = + match Non_empty_string.of_string s with + | None -> ok @@ wrap None + | Some s -> ( + match (s :> string).[0] with + | 'a' .. 'z' | 'A' .. 'Z' | '_' | '0' .. '9' -> + (* check that all characters are valid*) + string_iter (check_char loc) (s :> string) 1 >>? fun () -> + ok @@ wrap (Some s) + | _ -> error (Unexpected_annotation loc)) + in + List.map_e + (function + | "@%" when allow_special_var -> ok @@ Var_annot_opt (Some percent) + | "@%%" when allow_special_var -> + ok @@ Var_annot_opt (Some percent_percent) + | "%@" when allow_special_field -> ok @@ Field_annot_opt (Some at) + | s -> ( + let len = String.length s in + if Compare.Int.(len = 0 || len > max_annot_length) then + error (Unexpected_annotation loc) + else + let rest = String.sub s 1 (len - 1) in + match s.[0] with + | ':' -> sub_or_wildcard (fun a -> Type_annot_opt a) rest + | '@' -> sub_or_wildcard (fun a -> Var_annot_opt a) rest + | '%' -> sub_or_wildcard (fun a -> Field_annot_opt a) rest + | _ -> error (Unexpected_annotation loc))) + l + +let opt_var_of_var_opt = function None -> None | Some a -> Some (Var_annot a) + +let opt_field_of_field_opt = function + | None -> None + | Some a -> Some (Field_annot a) + +let opt_type_of_type_opt = function + | None -> None + | Some a -> Some (Type_annot a) + +let classify_annot loc l : + (var_annot option list * type_annot option list * field_annot option list) + tzresult = + try + let (_, rv, _, rt, _, rf) = + List.fold_left + (fun (in_v, rv, in_t, rt, in_f, rf) a -> + match (a, in_v, rv, in_t, rt, in_f, rf) with + | (Var_annot_opt a, true, _, _, _, _, _) + | (Var_annot_opt a, false, [], _, _, _, _) -> + (true, opt_var_of_var_opt a :: rv, false, rt, false, rf) + | (Type_annot_opt a, _, _, true, _, _, _) + | (Type_annot_opt a, _, _, false, [], _, _) -> + (false, rv, true, opt_type_of_type_opt a :: rt, false, rf) + | (Field_annot_opt a, _, _, _, _, true, _) + | (Field_annot_opt a, _, _, _, _, false, []) -> + (false, rv, false, rt, true, opt_field_of_field_opt a :: rf) + | _ -> raise Exit) + (false, [], false, [], false, []) + l + in + ok (List.rev rv, List.rev rt, List.rev rf) + with Exit -> error (Ungrouped_annotations loc) + +let get_one_annot loc = function + | [] -> Result.return_none + | [a] -> ok a + | _ -> error (Unexpected_annotation loc) + +let get_two_annot loc = function + | [] -> ok (None, None) + | [a] -> ok (a, None) + | [a; b] -> ok (a, b) + | _ -> error (Unexpected_annotation loc) + +let parse_type_annot : + Script.location -> string list -> type_annot option tzresult = + fun loc annot -> + parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> + error_unexpected_annot loc vars >>? fun () -> + error_unexpected_annot loc fields >>? fun () -> get_one_annot loc types + +let parse_composed_type_annot : + Script.location -> + string list -> + (type_annot option * field_annot option * field_annot option) tzresult = + fun loc annot -> + parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> + error_unexpected_annot loc vars >>? fun () -> + get_one_annot loc types >>? fun t -> + get_two_annot loc fields >|? fun (f1, f2) -> (t, f1, f2) + +let parse_field_annot : + Script.location -> string list -> field_annot option tzresult = + fun loc annot -> + parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> + error_unexpected_annot loc vars >>? fun () -> + error_unexpected_annot loc types >>? fun () -> get_one_annot loc fields + +let extract_field_annot : + Script.node -> (Script.node * field_annot option) tzresult = function + | Prim (loc, prim, args, annot) -> + let rec extract_first acc = function + | [] -> (None, annot) + | s :: rest -> + if Compare.Int.(String.length s > 0) && Compare.Char.(s.[0] = '%') + then (Some s, List.rev_append acc rest) + else extract_first (s :: acc) rest + in + let (field_annot, annot) = extract_first [] annot in + (match field_annot with + | None -> Result.return_none + | Some field_annot -> parse_field_annot loc [field_annot]) + >|? fun field_annot -> (Prim (loc, prim, args, annot), field_annot) + | expr -> ok (expr, None) + +let check_correct_field : + field_annot option -> field_annot option -> unit tzresult = + fun f1 f2 -> + match (f1, f2) with + | (None, _) | (_, None) -> Result.return_unit + | (Some (Field_annot s1), Some (Field_annot s2)) -> + if Non_empty_string.(s1 = s2) then Result.return_unit + else + error + (Inconsistent_field_annotations + ("%" ^ (s1 :> string), "%" ^ (s2 :> string))) + +let parse_var_annot : + Script.location -> + ?default:var_annot option -> + string list -> + var_annot option tzresult = + fun loc ?default annot -> + parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> + error_unexpected_annot loc types >>? fun () -> + error_unexpected_annot loc fields >>? fun () -> + get_one_annot loc vars >|? function + | Some _ as a -> a + | None -> ( match default with Some a -> a | None -> None) + +let split_last_dot = function + | None -> (None, None) + | Some (Field_annot s) -> ( + match Non_empty_string.split_on_last '.' s with + | Some (s1, s2) -> + let f = + match (s2 :> string) with + | "car" | "cdr" -> None + | _ -> Some (Field_annot s2) + in + (Some (Var_annot s1), f) + | None -> (None, Some (Field_annot s))) + +let split_if_special ~loc ~if_special v f = + match f with + | Some (Field_annot fa) when Non_empty_string.(fa = at) -> ( + match if_special with + | Some special_var -> ok @@ split_last_dot special_var + | None -> error (Unexpected_annotation loc)) + | _ -> ok (v, f) + +let common_prefix v1 v2 = + match (v1, v2) with + | (Some (Var_annot s1), Some (Var_annot s2)) when Non_empty_string.(s1 = s2) + -> + v1 + | (Some _, None) -> v1 + | (None, Some _) -> v2 + | (_, _) -> None + +let parse_constr_annot : + Script.location -> + ?if_special_first:field_annot option -> + ?if_special_second:field_annot option -> + string list -> + (var_annot option + * type_annot option + * field_annot option + * field_annot option) + tzresult = + fun loc ?if_special_first ?if_special_second annot -> + parse_annots ~allow_special_field:true loc annot >>? classify_annot loc + >>? fun (vars, types, fields) -> + get_one_annot loc vars >>? fun v -> + get_one_annot loc types >>? fun t -> + get_two_annot loc fields >>? fun (f1, f2) -> + split_if_special ~loc ~if_special:if_special_first v f1 >>? fun (v1, f1) -> + split_if_special ~loc ~if_special:if_special_second v f2 >|? fun (v2, f2) -> + let v = match v with None -> common_prefix v1 v2 | Some _ -> v in + (v, t, f1, f2) + +let parse_two_var_annot : + Script.location -> + string list -> + (var_annot option * var_annot option) tzresult = + fun loc annot -> + parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> + error_unexpected_annot loc types >>? fun () -> + error_unexpected_annot loc fields >>? fun () -> get_two_annot loc vars + +let var_annot_from_special : + field_name:field_annot option -> + default:var_annot option -> + value_annot:var_annot option -> + var_annot option -> + var_annot option = + fun ~field_name ~default ~value_annot v -> + match v with + | Some (Var_annot va) -> ( + match (va :> string) with + | "%" -> field_to_var_annot field_name + | "%%" -> default + | _ -> v) + | None -> value_annot + +let parse_destr_annot : + Script.location -> + string list -> + default_accessor:field_annot option -> + field_name:field_annot option -> + pair_annot:var_annot option -> + value_annot:var_annot option -> + (var_annot option * field_annot option) tzresult = + fun loc annot ~default_accessor ~field_name ~pair_annot ~value_annot -> + parse_annots loc ~allow_special_var:true annot >>? classify_annot loc + >>? fun (vars, types, fields) -> + error_unexpected_annot loc types >>? fun () -> + get_one_annot loc vars >>? fun v -> + get_one_annot loc fields >|? fun f -> + let default = + gen_access_annot pair_annot field_name ~default:default_accessor + in + let v = var_annot_from_special ~field_name ~default ~value_annot v in + (v, f) + +let parse_unpair_annot : + Script.location -> + string list -> + field_name_car:field_annot option -> + field_name_cdr:field_annot option -> + pair_annot:var_annot option -> + value_annot_car:var_annot option -> + value_annot_cdr:var_annot option -> + (var_annot option + * var_annot option + * field_annot option + * field_annot option) + tzresult = + fun loc + annot + ~field_name_car + ~field_name_cdr + ~pair_annot + ~value_annot_car + ~value_annot_cdr -> + parse_annots loc ~allow_special_var:true annot >>? classify_annot loc + >>? fun (vars, types, fields) -> + error_unexpected_annot loc types >>? fun () -> + get_two_annot loc vars >>? fun (vcar, vcdr) -> + get_two_annot loc fields >|? fun (fcar, fcdr) -> + let default_car = + gen_access_annot pair_annot field_name_car ~default:default_car_annot + in + let default_cdr = + gen_access_annot pair_annot field_name_cdr ~default:default_cdr_annot + in + let vcar = + var_annot_from_special + ~field_name:field_name_car + ~default:default_car + ~value_annot:value_annot_car + vcar + in + let vcdr = + var_annot_from_special + ~field_name:field_name_cdr + ~default:default_cdr + ~value_annot:value_annot_cdr + vcdr + in + (vcar, vcdr, fcar, fcdr) + +let parse_entrypoint_annot : + Script.location -> + ?default:var_annot option -> + string list -> + (var_annot option * field_annot option) tzresult = + fun loc ?default annot -> + parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> + error_unexpected_annot loc types >>? fun () -> + get_one_annot loc fields >>? fun f -> + get_one_annot loc vars >|? function + | Some _ as a -> (a, f) + | None -> ( match default with Some a -> (a, f) | None -> (None, f)) + +let parse_var_type_annot : + Script.location -> + string list -> + (var_annot option * type_annot option) tzresult = + fun loc annot -> + parse_annots loc annot >>? classify_annot loc >>? fun (vars, types, fields) -> + error_unexpected_annot loc fields >>? fun () -> + get_one_annot loc vars >>? fun v -> + get_one_annot loc types >|? fun t -> (v, t) diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_ir_annot.mli b/src/proto_012_PsiThaCa/lib_protocol/script_ir_annot.mli new file mode 100644 index 000000000000..47fab3b005b2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_ir_annot.mli @@ -0,0 +1,230 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +type var_annot = private Var_annot of Non_empty_string.t [@@ocaml.unboxed] + +type type_annot = private Type_annot of Non_empty_string.t [@@ocaml.unboxed] + +type field_annot = private Field_annot of Non_empty_string.t [@@ocaml.unboxed] + +module FOR_TESTS : sig + val unsafe_var_annot_of_string : string -> var_annot + + val unsafe_type_annot_of_string : string -> type_annot + + val unsafe_field_annot_of_string : string -> field_annot +end + +(** Default annotations *) + +val default_now_annot : var_annot option + +val default_amount_annot : var_annot option + +val default_balance_annot : var_annot option + +val default_level_annot : var_annot option + +val default_source_annot : var_annot option + +val default_sender_annot : var_annot option + +val default_self_annot : var_annot option + +val default_arg_annot : var_annot option + +val lambda_arg_annot : var_annot option + +val default_param_annot : var_annot option + +val default_storage_annot : var_annot option + +val default_sapling_state_annot : var_annot option + +val default_sapling_balance_annot : var_annot option + +val default_car_annot : field_annot option + +val default_cdr_annot : field_annot option + +val default_contract_annot : field_annot option + +val default_addr_annot : field_annot option + +val default_pack_annot : field_annot option + +val default_unpack_annot : field_annot option + +val default_slice_annot : field_annot option + +val default_elt_annot : field_annot option + +val default_key_annot : field_annot option + +val default_hd_annot : field_annot option + +val default_tl_annot : field_annot option + +val default_some_annot : field_annot option + +val default_left_annot : field_annot option + +val default_right_annot : field_annot option + +(** Unparse annotations to their string representation *) + +val unparse_type_annot : type_annot option -> string list + +val unparse_var_annot : var_annot option -> string list + +val unparse_field_annot : field_annot option -> string list + +(** Conversion functions between different annotation kinds *) + +val field_to_var_annot : field_annot option -> var_annot option + +val type_to_var_annot : type_annot option -> var_annot option + +val var_to_field_annot : var_annot option -> field_annot option + +(** Replace an annotation by its default value if it is [None] *) +val default_annot : default:'a option -> 'a option -> 'a option + +(** Generate annotation for field accesses, of the form [var.field1.field2] *) +val gen_access_annot : + var_annot option -> + ?default:field_annot option -> + field_annot option -> + var_annot option + +(** Merge type annotations. + @return an error {!Inconsistent_type_annotations} if they are both present + and different, unless [legacy] *) +val merge_type_annot : + legacy:bool -> + type_annot option -> + type_annot option -> + type_annot option tzresult + +(** Merge field annotations. + @return an error {!Inconsistent_type_annotations} if they are both present + and different, unless [legacy] *) +val merge_field_annot : + legacy:bool -> + field_annot option -> + field_annot option -> + field_annot option tzresult + +(** Merge variable annotations, does not fail ([None] if different). *) +val merge_var_annot : var_annot option -> var_annot option -> var_annot option + +(** @return an error {!Unexpected_annotation} in the monad the list is not empty. *) +val error_unexpected_annot : Script.location -> 'a list -> unit tzresult + +(** Parse a type annotation only. *) +val parse_type_annot : + Script.location -> string list -> type_annot option tzresult + +(** Parse a field annotation only. *) +val parse_field_annot : + Script.location -> string list -> field_annot option tzresult + +(** Parse an annotation for composed types, of the form + [:ty_name %field1 %field2] in any order. *) +val parse_composed_type_annot : + Script.location -> + string list -> + (type_annot option * field_annot option * field_annot option) tzresult + +(** Extract and remove a field annotation from a node *) +val extract_field_annot : + Script.node -> (Script.node * field_annot option) tzresult + +(** Check that field annotations match, used for field accesses. *) +val check_correct_field : + field_annot option -> field_annot option -> unit tzresult + +(** Instruction annotations parsing *) + +(** Parse a variable annotation, replaced by a default value if [None]. *) +val parse_var_annot : + Script.location -> + ?default:var_annot option -> + string list -> + var_annot option tzresult + +val is_allowed_char : char -> bool + +val parse_constr_annot : + Script.location -> + ?if_special_first:field_annot option -> + ?if_special_second:field_annot option -> + string list -> + (var_annot option + * type_annot option + * field_annot option + * field_annot option) + tzresult + +val parse_two_var_annot : + Script.location -> + string list -> + (var_annot option * var_annot option) tzresult + +val parse_destr_annot : + Script.location -> + string list -> + default_accessor:field_annot option -> + field_name:field_annot option -> + pair_annot:var_annot option -> + value_annot:var_annot option -> + (var_annot option * field_annot option) tzresult + +val parse_unpair_annot : + Script.location -> + string list -> + field_name_car:field_annot option -> + field_name_cdr:field_annot option -> + pair_annot:var_annot option -> + value_annot_car:var_annot option -> + value_annot_cdr:var_annot option -> + (var_annot option + * var_annot option + * field_annot option + * field_annot option) + tzresult + +val parse_entrypoint_annot : + Script.location -> + ?default:var_annot option -> + string list -> + (var_annot option * field_annot option) tzresult + +val parse_var_type_annot : + Script.location -> + string list -> + (var_annot option * type_annot option) tzresult diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_ir_translator.ml b/src/proto_012_PsiThaCa/lib_protocol/script_ir_translator.ml new file mode 100644 index 000000000000..ceb7553e3dc0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_ir_translator.ml @@ -0,0 +1,6787 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Micheline +open Script +open Script_tc_errors +open Script_ir_annot +open Script_typed_ir +module Typecheck_costs = Michelson_v1_gas.Cost_of.Typechecking +module Unparse_costs = Michelson_v1_gas.Cost_of.Unparsing + +type ex_stack_ty = Ex_stack_ty : ('a, 's) stack_ty -> ex_stack_ty + +(* + + The following type represents an instruction parameterized by its + continuation. During the elaboration of the typed term, a sequence + of instructions in Micheline is read from left to right: hence, the + elaboration needs to wait for the next instruction to be elaborated + to be able to construct the current instruction. + +*) +type ('a, 's, 'b, 'u) cinstr = { + apply : + 'r 'f. ('a, 's) kinfo -> ('b, 'u, 'r, 'f) kinstr -> ('a, 's, 'r, 'f) kinstr; +} + +(* + + While a [Script_typed_ir.descr] contains a fully defined + instruction, [descr] contains a [cinstr], that is an instruction + parameterized by the next instruction, as explained in the previous + comment. + +*) +type ('a, 's, 'b, 'u) descr = { + loc : Script.location; + bef : ('a, 's) stack_ty; + aft : ('b, 'u) stack_ty; + instr : ('a, 's, 'b, 'u) cinstr; +} + +let close_descr {loc; bef; aft; instr} = + let kinfo = {iloc = loc; kstack_ty = aft} in + let kinfo' = {iloc = loc; kstack_ty = bef} in + let kinstr = instr.apply kinfo' (IHalt kinfo) in + {kloc = loc; kbef = bef; kaft = aft; kinstr} + +let kinfo_of_descr {loc; bef; _} = {iloc = loc; kstack_ty = bef} + +let compose_descr : + type a s b u c v. + Script.location -> + (a, s, b, u) descr -> + (b, u, c, v) descr -> + (a, s, c, v) descr = + fun loc d1 d2 -> + { + loc; + bef = d1.bef; + aft = d2.aft; + instr = + { + apply = + (fun _ k -> + d1.instr.apply + (kinfo_of_descr d1) + (d2.instr.apply (kinfo_of_descr d2) k)); + }; + } + +type tc_context = + | Lambda : tc_context + | Dip : ('a, 's) stack_ty * tc_context -> tc_context + | Toplevel : { + storage_type : 'sto ty; + param_type : 'param ty; + root_name : field_annot option; + } + -> tc_context + +type unparsing_mode = Optimized | Readable | Optimized_legacy + +type type_logger = + Script.location -> + (Script.expr * Script.annot) list -> + (Script.expr * Script.annot) list -> + unit + +let add_dip ty annot prev = + match prev with + | Lambda | Toplevel _ -> + Dip (Item_t (ty, Item_t (unit_t ~annot:None, Bot_t, None), annot), prev) + | Dip (stack, _) -> Dip (Item_t (ty, stack, annot), prev) + +(* ---- Error helpers -------------------------------------------------------*) + +let location = function + | Prim (loc, _, _, _) + | Int (loc, _) + | String (loc, _) + | Bytes (loc, _) + | Seq (loc, _) -> + loc + +let kind_equal a b = + match (a, b) with + | (Int_kind, Int_kind) + | (String_kind, String_kind) + | (Bytes_kind, Bytes_kind) + | (Prim_kind, Prim_kind) + | (Seq_kind, Seq_kind) -> + true + | _ -> false + +let kind = function + | Int _ -> Int_kind + | String _ -> String_kind + | Bytes _ -> Bytes_kind + | Prim _ -> Prim_kind + | Seq _ -> Seq_kind + +let unexpected expr exp_kinds exp_ns exp_prims = + match expr with + | Int (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Int_kind) + | String (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, String_kind) + | Bytes (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Bytes_kind) + | Seq (loc, _) -> Invalid_kind (loc, Prim_kind :: exp_kinds, Seq_kind) + | Prim (loc, name, _, _) -> ( + let open Michelson_v1_primitives in + match (namespace name, exp_ns) with + | (Type_namespace, Type_namespace) + | (Instr_namespace, Instr_namespace) + | (Constant_namespace, Constant_namespace) -> + Invalid_primitive (loc, exp_prims, name) + | (ns, _) -> Invalid_namespace (loc, name, exp_ns, ns)) + +let check_kind kinds expr = + let kind = kind expr in + if List.exists (kind_equal kind) kinds then Result.return_unit + else + let loc = location expr in + error (Invalid_kind (loc, kinds, kind)) + +(* ---- Unparsing (Typed IR -> Untyped expressions) of types -----------------*) + +(* This part contains the unparsing that does not depend on parsing + (everything that cannot contain a lambda). The rest is located at + the end of the file. *) + +let rec ty_of_comparable_ty : type a. a comparable_ty -> a ty = function + | Unit_key tname -> Unit_t tname + | Never_key tname -> Never_t tname + | Int_key tname -> Int_t tname + | Nat_key tname -> Nat_t tname + | Signature_key tname -> Signature_t tname + | String_key tname -> String_t tname + | Bytes_key tname -> Bytes_t tname + | Mutez_key tname -> Mutez_t tname + | Bool_key tname -> Bool_t tname + | Key_hash_key tname -> Key_hash_t tname + | Key_key tname -> Key_t tname + | Timestamp_key tname -> Timestamp_t tname + | Address_key tname -> Address_t tname + | Chain_id_key tname -> Chain_id_t tname + | Pair_key ((l, al), (r, ar), tname) -> + Pair_t + ( (ty_of_comparable_ty l, al, None), + (ty_of_comparable_ty r, ar, None), + tname ) + | Union_key ((l, al), (r, ar), tname) -> + Union_t ((ty_of_comparable_ty l, al), (ty_of_comparable_ty r, ar), tname) + | Option_key (t, tname) -> Option_t (ty_of_comparable_ty t, tname) + +let add_field_annot a var = function + | Prim (loc, prim, args, annots) -> + Prim + (loc, prim, args, annots @ unparse_field_annot a @ unparse_var_annot var) + | expr -> expr + +let rec unparse_comparable_ty_uncarbonated : + type a loc. loc:loc -> a comparable_ty -> loc Script.michelson_node = + fun ~loc -> function + | Unit_key meta -> Prim (loc, T_unit, [], unparse_type_annot meta.annot) + | Never_key meta -> Prim (loc, T_never, [], unparse_type_annot meta.annot) + | Int_key meta -> Prim (loc, T_int, [], unparse_type_annot meta.annot) + | Nat_key meta -> Prim (loc, T_nat, [], unparse_type_annot meta.annot) + | Signature_key meta -> + Prim (loc, T_signature, [], unparse_type_annot meta.annot) + | String_key meta -> Prim (loc, T_string, [], unparse_type_annot meta.annot) + | Bytes_key meta -> Prim (loc, T_bytes, [], unparse_type_annot meta.annot) + | Mutez_key meta -> Prim (loc, T_mutez, [], unparse_type_annot meta.annot) + | Bool_key meta -> Prim (loc, T_bool, [], unparse_type_annot meta.annot) + | Key_hash_key meta -> + Prim (loc, T_key_hash, [], unparse_type_annot meta.annot) + | Key_key meta -> Prim (loc, T_key, [], unparse_type_annot meta.annot) + | Timestamp_key meta -> + Prim (loc, T_timestamp, [], unparse_type_annot meta.annot) + | Address_key meta -> Prim (loc, T_address, [], unparse_type_annot meta.annot) + | Chain_id_key meta -> + Prim (loc, T_chain_id, [], unparse_type_annot meta.annot) + | Pair_key ((l, al), (r, ar), meta) -> ( + let tl = + add_field_annot al None (unparse_comparable_ty_uncarbonated ~loc l) + in + let tr = + add_field_annot ar None (unparse_comparable_ty_uncarbonated ~loc r) + in + (* Fold [pair a1 (pair ... (pair an-1 an))] into [pair a1 ... an] *) + (* Note that the folding does not happen if the pair on the right has a + field annotation because this annotation would be lost *) + match tr with + | Prim (_, T_pair, ts, []) -> + Prim (loc, T_pair, tl :: ts, unparse_type_annot meta.annot) + | _ -> Prim (loc, T_pair, [tl; tr], unparse_type_annot meta.annot)) + | Union_key ((l, al), (r, ar), meta) -> + let tl = + add_field_annot al None (unparse_comparable_ty_uncarbonated ~loc l) + in + let tr = + add_field_annot ar None (unparse_comparable_ty_uncarbonated ~loc r) + in + Prim (loc, T_or, [tl; tr], unparse_type_annot meta.annot) + | Option_key (t, meta) -> + Prim + ( loc, + T_option, + [unparse_comparable_ty_uncarbonated ~loc t], + unparse_type_annot meta.annot ) + +let unparse_memo_size ~loc memo_size = + let z = Sapling.Memo_size.unparse_to_z memo_size in + Int (loc, z) + +let rec unparse_ty_uncarbonated : + type a loc. loc:loc -> a ty -> loc Script.michelson_node = + fun ~loc ty -> + let prim (name, args, annot) = Prim (loc, name, args, annot) in + match ty with + | Unit_t meta -> prim (T_unit, [], unparse_type_annot meta.annot) + | Int_t meta -> prim (T_int, [], unparse_type_annot meta.annot) + | Nat_t meta -> prim (T_nat, [], unparse_type_annot meta.annot) + | Signature_t meta -> prim (T_signature, [], unparse_type_annot meta.annot) + | String_t meta -> prim (T_string, [], unparse_type_annot meta.annot) + | Bytes_t meta -> prim (T_bytes, [], unparse_type_annot meta.annot) + | Mutez_t meta -> prim (T_mutez, [], unparse_type_annot meta.annot) + | Bool_t meta -> prim (T_bool, [], unparse_type_annot meta.annot) + | Key_hash_t meta -> prim (T_key_hash, [], unparse_type_annot meta.annot) + | Key_t meta -> prim (T_key, [], unparse_type_annot meta.annot) + | Timestamp_t meta -> prim (T_timestamp, [], unparse_type_annot meta.annot) + | Address_t meta -> prim (T_address, [], unparse_type_annot meta.annot) + | Operation_t meta -> prim (T_operation, [], unparse_type_annot meta.annot) + | Chain_id_t meta -> prim (T_chain_id, [], unparse_type_annot meta.annot) + | Never_t meta -> prim (T_never, [], unparse_type_annot meta.annot) + | Bls12_381_g1_t meta -> + prim (T_bls12_381_g1, [], unparse_type_annot meta.annot) + | Bls12_381_g2_t meta -> + prim (T_bls12_381_g2, [], unparse_type_annot meta.annot) + | Bls12_381_fr_t meta -> + prim (T_bls12_381_fr, [], unparse_type_annot meta.annot) + | Contract_t (ut, meta) -> + let t = unparse_ty_uncarbonated ~loc ut in + prim (T_contract, [t], unparse_type_annot meta.annot) + | Pair_t ((utl, l_field, l_var), (utr, r_field, r_var), meta) -> + let annot = unparse_type_annot meta.annot in + let utl = unparse_ty_uncarbonated ~loc utl in + let tl = add_field_annot l_field l_var utl in + let utr = unparse_ty_uncarbonated ~loc utr in + let tr = add_field_annot r_field r_var utr in + (* Fold [pair a1 (pair ... (pair an-1 an))] into [pair a1 ... an] *) + (* Note that the folding does not happen if the pair on the right has an + annotation because this annotation would be lost *) + prim + (match tr with + | Prim (_, T_pair, ts, []) -> (T_pair, tl :: ts, annot) + | _ -> (T_pair, [tl; tr], annot)) + | Union_t ((utl, l_field), (utr, r_field), meta) -> + let annot = unparse_type_annot meta.annot in + let utl = unparse_ty_uncarbonated ~loc utl in + let tl = add_field_annot l_field None utl in + let utr = unparse_ty_uncarbonated ~loc utr in + let tr = add_field_annot r_field None utr in + prim (T_or, [tl; tr], annot) + | Lambda_t (uta, utr, meta) -> + let ta = unparse_ty_uncarbonated ~loc uta in + let tr = unparse_ty_uncarbonated ~loc utr in + prim (T_lambda, [ta; tr], unparse_type_annot meta.annot) + | Option_t (ut, meta) -> + let annot = unparse_type_annot meta.annot in + let ut = unparse_ty_uncarbonated ~loc ut in + prim (T_option, [ut], annot) + | List_t (ut, meta) -> + let t = unparse_ty_uncarbonated ~loc ut in + prim (T_list, [t], unparse_type_annot meta.annot) + | Ticket_t (ut, meta) -> + let t = unparse_comparable_ty_uncarbonated ~loc ut in + prim (T_ticket, [t], unparse_type_annot meta.annot) + | Set_t (ut, meta) -> + let t = unparse_comparable_ty_uncarbonated ~loc ut in + prim (T_set, [t], unparse_type_annot meta.annot) + | Map_t (uta, utr, meta) -> + let ta = unparse_comparable_ty_uncarbonated ~loc uta in + let tr = unparse_ty_uncarbonated ~loc utr in + prim (T_map, [ta; tr], unparse_type_annot meta.annot) + | Big_map_t (uta, utr, meta) -> + let ta = unparse_comparable_ty_uncarbonated ~loc uta in + let tr = unparse_ty_uncarbonated ~loc utr in + prim (T_big_map, [ta; tr], unparse_type_annot meta.annot) + | Sapling_transaction_t (memo_size, meta) -> + prim + ( T_sapling_transaction, + [unparse_memo_size ~loc memo_size], + unparse_type_annot meta.annot ) + | Sapling_state_t (memo_size, meta) -> + prim + ( T_sapling_state, + [unparse_memo_size ~loc memo_size], + unparse_type_annot meta.annot ) + | Chest_key_t meta -> prim (T_chest_key, [], unparse_type_annot meta.annot) + | Chest_t meta -> prim (T_chest, [], unparse_type_annot meta.annot) + +let unparse_ty ~loc ctxt ty = + Gas.consume ctxt (Unparse_costs.unparse_type ty) >|? fun ctxt -> + (unparse_ty_uncarbonated ~loc ty, ctxt) + +let unparse_comparable_ty ~loc ctxt comp_ty = + Gas.consume ctxt (Unparse_costs.unparse_comparable_type comp_ty) + >|? fun ctxt -> (unparse_comparable_ty_uncarbonated ~loc comp_ty, ctxt) + +let[@coq_struct "function_parameter"] rec strip_var_annots = function + | (Int _ | String _ | Bytes _) as atom -> atom + | Seq (loc, args) -> Seq (loc, List.map strip_var_annots args) + | Prim (loc, name, args, annots) -> + let not_var_annot s = Compare.Char.(s.[0] <> '@') in + let annots = List.filter not_var_annot annots in + Prim (loc, name, List.map strip_var_annots args, annots) + +let serialize_ty_for_error ty = + (* + Types are bounded by [Constants.michelson_maximum_type_size], so + [unparse_ty_uncarbonated], [strip_var_annots], and [strip_locations] are + bounded in time. + + It is hence OK to use them in errors that are not caught in the validation + (only once in apply). + *) + let ty = unparse_ty_uncarbonated ~loc:() ty in + Micheline.strip_locations (strip_var_annots ty) + +let[@coq_axiom_with_reason "gadt"] rec comparable_ty_of_ty : + type a. + context -> Script.location -> a ty -> (a comparable_ty * context) tzresult = + fun ctxt loc ty -> + Gas.consume ctxt Typecheck_costs.comparable_ty_of_ty_cycle >>? fun ctxt -> + match ty with + | Unit_t tname -> ok ((Unit_key tname : a comparable_ty), ctxt) + | Never_t tname -> ok (Never_key tname, ctxt) + | Int_t tname -> ok (Int_key tname, ctxt) + | Nat_t tname -> ok (Nat_key tname, ctxt) + | Signature_t tname -> ok (Signature_key tname, ctxt) + | String_t tname -> ok (String_key tname, ctxt) + | Bytes_t tname -> ok (Bytes_key tname, ctxt) + | Mutez_t tname -> ok (Mutez_key tname, ctxt) + | Bool_t tname -> ok (Bool_key tname, ctxt) + | Key_hash_t tname -> ok (Key_hash_key tname, ctxt) + | Key_t tname -> ok (Key_key tname, ctxt) + | Timestamp_t tname -> ok (Timestamp_key tname, ctxt) + | Address_t tname -> ok (Address_key tname, ctxt) + | Chain_id_t tname -> ok (Chain_id_key tname, ctxt) + | Pair_t ((l, al, _), (r, ar, _), pname) -> + comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> + comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> + (Pair_key ((lty, al), (rty, ar), pname), ctxt) + | Union_t ((l, al), (r, ar), tname) -> + comparable_ty_of_ty ctxt loc l >>? fun (lty, ctxt) -> + comparable_ty_of_ty ctxt loc r >|? fun (rty, ctxt) -> + (Union_key ((lty, al), (rty, ar), tname), ctxt) + | Option_t (tt, tname) -> + comparable_ty_of_ty ctxt loc tt >|? fun (ty, ctxt) -> + (Option_key (ty, tname), ctxt) + | Lambda_t _ | List_t _ | Ticket_t _ | Set_t _ | Map_t _ | Big_map_t _ + | Contract_t _ | Operation_t _ | Bls12_381_fr_t _ | Bls12_381_g1_t _ + | Bls12_381_g2_t _ | Sapling_state_t _ | Sapling_transaction_t _ + | Chest_key_t _ | Chest_t _ -> + let t = serialize_ty_for_error ty in + error (Comparable_type_expected (loc, t)) + +let rec unparse_stack_uncarbonated : + type a s. (a, s) stack_ty -> (Script.expr * Script.annot) list = function + | Bot_t -> [] + | Item_t (ty, rest, annot) -> + let uty = unparse_ty_uncarbonated ~loc:() ty in + let urest = unparse_stack_uncarbonated rest in + (strip_locations uty, unparse_var_annot annot) :: urest + +let serialize_stack_for_error ctxt stack_ty = + match Gas.level ctxt with + | Unaccounted -> unparse_stack_uncarbonated stack_ty + | Limited _ -> [] + +let name_of_ty : type a. a ty -> type_annot option = function + | Unit_t meta -> meta.annot + | Int_t meta -> meta.annot + | Nat_t meta -> meta.annot + | String_t meta -> meta.annot + | Bytes_t meta -> meta.annot + | Mutez_t meta -> meta.annot + | Bool_t meta -> meta.annot + | Key_hash_t meta -> meta.annot + | Key_t meta -> meta.annot + | Timestamp_t meta -> meta.annot + | Address_t meta -> meta.annot + | Signature_t meta -> meta.annot + | Operation_t meta -> meta.annot + | Chain_id_t meta -> meta.annot + | Never_t meta -> meta.annot + | Contract_t (_, meta) -> meta.annot + | Pair_t (_, _, meta) -> meta.annot + | Union_t (_, _, meta) -> meta.annot + | Lambda_t (_, _, meta) -> meta.annot + | Option_t (_, meta) -> meta.annot + | List_t (_, meta) -> meta.annot + | Ticket_t (_, meta) -> meta.annot + | Set_t (_, meta) -> meta.annot + | Map_t (_, _, meta) -> meta.annot + | Big_map_t (_, _, meta) -> meta.annot + | Bls12_381_g1_t meta -> meta.annot + | Bls12_381_g2_t meta -> meta.annot + | Bls12_381_fr_t meta -> meta.annot + | Sapling_state_t (_, meta) -> meta.annot + | Sapling_transaction_t (_, meta) -> meta.annot + | Chest_key_t meta -> meta.annot + | Chest_t meta -> meta.annot + +let unparse_unit ~loc ctxt () = ok (Prim (loc, D_Unit, [], []), ctxt) + +let unparse_int ~loc ctxt v = ok (Int (loc, Script_int.to_zint v), ctxt) + +let unparse_nat ~loc ctxt v = ok (Int (loc, Script_int.to_zint v), ctxt) + +let unparse_string ~loc ctxt s = + ok (String (loc, Script_string.to_string s), ctxt) + +let unparse_bytes ~loc ctxt s = ok (Bytes (loc, s), ctxt) + +let unparse_bool ~loc ctxt b = + ok (Prim (loc, (if b then D_True else D_False), [], []), ctxt) + +let unparse_timestamp ~loc ctxt mode t = + match mode with + | Optimized | Optimized_legacy -> + ok (Int (loc, Script_timestamp.to_zint t), ctxt) + | Readable -> ( + Gas.consume ctxt Unparse_costs.timestamp_readable >>? fun ctxt -> + match Script_timestamp.to_notation t with + | None -> ok (Int (loc, Script_timestamp.to_zint t), ctxt) + | Some s -> ok (String (loc, s), ctxt)) + +let unparse_address ~loc ctxt mode (c, entrypoint) = + Gas.consume ctxt Unparse_costs.contract >>? fun ctxt -> + (match entrypoint with + (* given parse_address, this should not happen *) + | "" -> error Unparsing_invariant_violated + | _ -> ok ()) + >|? fun () -> + match mode with + | Optimized | Optimized_legacy -> + let entrypoint = match entrypoint with "default" -> "" | name -> name in + let bytes = + Data_encoding.Binary.to_bytes_exn + Data_encoding.(tup2 Contract.encoding Variable.string) + (c, entrypoint) + in + (Bytes (loc, bytes), ctxt) + | Readable -> + let notation = + match entrypoint with + | "default" -> Contract.to_b58check c + | entrypoint -> Contract.to_b58check c ^ "%" ^ entrypoint + in + (String (loc, notation), ctxt) + +let unparse_contract ~loc ctxt mode (_, address) = + unparse_address ~loc ctxt mode address + +let unparse_signature ~loc ctxt mode s = + match mode with + | Optimized | Optimized_legacy -> + Gas.consume ctxt Unparse_costs.signature_optimized >|? fun ctxt -> + let bytes = Data_encoding.Binary.to_bytes_exn Signature.encoding s in + (Bytes (loc, bytes), ctxt) + | Readable -> + Gas.consume ctxt Unparse_costs.signature_readable >|? fun ctxt -> + (String (loc, Signature.to_b58check s), ctxt) + +let unparse_mutez ~loc ctxt v = ok (Int (loc, Z.of_int64 (Tez.to_mutez v)), ctxt) + +let unparse_key ~loc ctxt mode k = + match mode with + | Optimized | Optimized_legacy -> + Gas.consume ctxt Unparse_costs.public_key_optimized >|? fun ctxt -> + let bytes = + Data_encoding.Binary.to_bytes_exn Signature.Public_key.encoding k + in + (Bytes (loc, bytes), ctxt) + | Readable -> + Gas.consume ctxt Unparse_costs.public_key_readable >|? fun ctxt -> + (String (loc, Signature.Public_key.to_b58check k), ctxt) + +let unparse_key_hash ~loc ctxt mode k = + match mode with + | Optimized | Optimized_legacy -> + Gas.consume ctxt Unparse_costs.key_hash_optimized >|? fun ctxt -> + let bytes = + Data_encoding.Binary.to_bytes_exn Signature.Public_key_hash.encoding k + in + (Bytes (loc, bytes), ctxt) + | Readable -> + Gas.consume ctxt Unparse_costs.key_hash_readable >|? fun ctxt -> + (String (loc, Signature.Public_key_hash.to_b58check k), ctxt) + +let unparse_operation ~loc ctxt (op, _big_map_diff) = + let bytes = + Data_encoding.Binary.to_bytes_exn Operation.internal_operation_encoding op + in + Gas.consume ctxt (Unparse_costs.operation bytes) >|? fun ctxt -> + (Bytes (loc, bytes), ctxt) + +let unparse_chain_id ~loc ctxt mode chain_id = + match mode with + | Optimized | Optimized_legacy -> + Gas.consume ctxt Unparse_costs.chain_id_optimized >|? fun ctxt -> + let bytes = + Data_encoding.Binary.to_bytes_exn Chain_id.encoding chain_id + in + (Bytes (loc, bytes), ctxt) + | Readable -> + Gas.consume ctxt Unparse_costs.chain_id_readable >|? fun ctxt -> + (String (loc, Chain_id.to_b58check chain_id), ctxt) + +let unparse_bls12_381_g1 ~loc ctxt x = + Gas.consume ctxt Unparse_costs.bls12_381_g1 >|? fun ctxt -> + let bytes = Bls12_381.G1.to_bytes x in + (Bytes (loc, bytes), ctxt) + +let unparse_bls12_381_g2 ~loc ctxt x = + Gas.consume ctxt Unparse_costs.bls12_381_g2 >|? fun ctxt -> + let bytes = Bls12_381.G2.to_bytes x in + (Bytes (loc, bytes), ctxt) + +let unparse_bls12_381_fr ~loc ctxt x = + Gas.consume ctxt Unparse_costs.bls12_381_fr >|? fun ctxt -> + let bytes = Bls12_381.Fr.to_bytes x in + (Bytes (loc, bytes), ctxt) + +let unparse_with_data_encoding ~loc ctxt s unparse_cost encoding = + Lwt.return + ( Gas.consume ctxt unparse_cost >|? fun ctxt -> + let bytes = Data_encoding.Binary.to_bytes_exn encoding s in + (Bytes (loc, bytes), ctxt) ) + +(* -- Unparsing data of complex types -- *) + +type ('ty, 'depth) comb_witness = + | Comb_Pair : ('t, 'd) comb_witness -> (_ * 't, unit -> 'd) comb_witness + | Comb_Any : (_, _) comb_witness + +let unparse_pair (type r) ~loc unparse_l unparse_r ctxt mode + (r_comb_witness : (r, unit -> unit -> _) comb_witness) (l, (r : r)) = + unparse_l ctxt l >>=? fun (l, ctxt) -> + unparse_r ctxt r >|=? fun (r, ctxt) -> + (* Fold combs. + For combs, three notations are supported: + - a) [Pair x1 (Pair x2 ... (Pair xn-1 xn) ...)], + - b) [Pair x1 x2 ... xn-1 xn], and + - c) [{x1; x2; ...; xn-1; xn}]. + In readable mode, we always use b), + in optimized mode we use the shortest to serialize: + - for n=2, [Pair x1 x2], + - for n=3, [Pair x1 (Pair x2 x3)], + - for n>=4, [{x1; x2; ...; xn}]. + *) + let res = + match (mode, r_comb_witness, r) with + | (Optimized, Comb_Pair _, Micheline.Seq (_, r)) -> + (* Optimized case n > 4 *) + Micheline.Seq (loc, l :: r) + | ( Optimized, + Comb_Pair (Comb_Pair _), + Prim (_, D_Pair, [x2; Prim (_, D_Pair, [x3; x4], [])], []) ) -> + (* Optimized case n = 4 *) + Micheline.Seq (loc, [l; x2; x3; x4]) + | (Readable, Comb_Pair _, Prim (_, D_Pair, xs, [])) -> + (* Readable case n > 2 *) + Prim (loc, D_Pair, l :: xs, []) + | _ -> + (* The remaining cases are: + - Optimized n = 2, + - Optimized n = 3, and + - Readable n = 2, + - Optimized_legacy, any n *) + Prim (loc, D_Pair, [l; r], []) + in + (res, ctxt) + +let unparse_union ~loc unparse_l unparse_r ctxt = function + | L l -> + unparse_l ctxt l >|=? fun (l, ctxt) -> (Prim (loc, D_Left, [l], []), ctxt) + | R r -> + unparse_r ctxt r >|=? fun (r, ctxt) -> (Prim (loc, D_Right, [r], []), ctxt) + +let unparse_option ~loc unparse_v ctxt = function + | Some v -> + unparse_v ctxt v >|=? fun (v, ctxt) -> (Prim (loc, D_Some, [v], []), ctxt) + | None -> return (Prim (loc, D_None, [], []), ctxt) + +(* -- Unparsing data of comparable types -- *) + +let comparable_comb_witness2 : + type t. t comparable_ty -> (t, unit -> unit -> unit) comb_witness = function + | Pair_key (_, (Pair_key _, _), _) -> Comb_Pair (Comb_Pair Comb_Any) + | Pair_key _ -> Comb_Pair Comb_Any + | _ -> Comb_Any + +let[@coq_axiom_with_reason "gadt"] rec unparse_comparable_data : + type a loc. + loc:loc -> + context -> + unparsing_mode -> + a comparable_ty -> + a -> + (loc Script.michelson_node * context) tzresult Lwt.t = + fun ~loc ctxt mode ty a -> + (* No need for stack_depth here. Unlike [unparse_data], + [unparse_comparable_data] doesn't call [unparse_code]. + The stack depth is bounded by the type depth, currently bounded + by 1000 (michelson_maximum_type_size). *) + Gas.consume ctxt Unparse_costs.unparse_data_cycle + (* We could have a smaller cost but let's keep it consistent with + [unparse_data] for now. *) + >>?= + fun ctxt -> + match (ty, a) with + | (Unit_key _, v) -> Lwt.return @@ unparse_unit ~loc ctxt v + | (Int_key _, v) -> Lwt.return @@ unparse_int ~loc ctxt v + | (Nat_key _, v) -> Lwt.return @@ unparse_nat ~loc ctxt v + | (String_key _, s) -> Lwt.return @@ unparse_string ~loc ctxt s + | (Bytes_key _, s) -> Lwt.return @@ unparse_bytes ~loc ctxt s + | (Bool_key _, b) -> Lwt.return @@ unparse_bool ~loc ctxt b + | (Timestamp_key _, t) -> Lwt.return @@ unparse_timestamp ~loc ctxt mode t + | (Address_key _, address) -> + Lwt.return @@ unparse_address ~loc ctxt mode address + | (Signature_key _, s) -> Lwt.return @@ unparse_signature ~loc ctxt mode s + | (Mutez_key _, v) -> Lwt.return @@ unparse_mutez ~loc ctxt v + | (Key_key _, k) -> Lwt.return @@ unparse_key ~loc ctxt mode k + | (Key_hash_key _, k) -> Lwt.return @@ unparse_key_hash ~loc ctxt mode k + | (Chain_id_key _, chain_id) -> + Lwt.return @@ unparse_chain_id ~loc ctxt mode chain_id + | (Pair_key ((tl, _), (tr, _), _), pair) -> + let r_witness = comparable_comb_witness2 tr in + let unparse_l ctxt v = unparse_comparable_data ~loc ctxt mode tl v in + let unparse_r ctxt v = unparse_comparable_data ~loc ctxt mode tr v in + unparse_pair ~loc unparse_l unparse_r ctxt mode r_witness pair + | (Union_key ((tl, _), (tr, _), _), v) -> + let unparse_l ctxt v = unparse_comparable_data ~loc ctxt mode tl v in + let unparse_r ctxt v = unparse_comparable_data ~loc ctxt mode tr v in + unparse_union ~loc unparse_l unparse_r ctxt v + | (Option_key (t, _), v) -> + let unparse_v ctxt v = unparse_comparable_data ~loc ctxt mode t v in + unparse_option ~loc unparse_v ctxt v + | (Never_key _, _) -> . + +let pack_node unparsed ctxt = + Gas.consume ctxt (Script.strip_locations_cost unparsed) >>? fun ctxt -> + let bytes = + Data_encoding.Binary.to_bytes_exn + expr_encoding + (Micheline.strip_locations unparsed) + in + Gas.consume ctxt (Script.serialized_cost bytes) >|? fun ctxt -> + let bytes = Bytes.cat (Bytes.of_string "\005") bytes in + (bytes, ctxt) + +let pack_comparable_data ctxt typ data ~mode = + unparse_comparable_data ~loc:() ctxt mode typ data + >>=? fun (unparsed, ctxt) -> Lwt.return @@ pack_node unparsed ctxt + +let hash_bytes ctxt bytes = + Gas.consume ctxt (Michelson_v1_gas.Cost_of.Interpreter.blake2b bytes) + >|? fun ctxt -> (Script_expr_hash.(hash_bytes [bytes]), ctxt) + +let hash_comparable_data ctxt typ data = + pack_comparable_data ctxt typ data ~mode:Optimized_legacy + >>=? fun (bytes, ctxt) -> Lwt.return @@ hash_bytes ctxt bytes + +(* ---- Tickets ------------------------------------------------------------ *) + +(* + All comparable types are dupable, this function exists only to not forget + checking this property when adding new types. +*) +let check_dupable_comparable_ty : type a. a comparable_ty -> unit = function + | Unit_key _ | Never_key _ | Int_key _ | Nat_key _ | Signature_key _ + | String_key _ | Bytes_key _ | Mutez_key _ | Bool_key _ | Key_hash_key _ + | Key_key _ | Timestamp_key _ | Chain_id_key _ | Address_key _ | Pair_key _ + | Union_key _ | Option_key _ -> + () + +let rec check_dupable_ty : + type a. context -> location -> a ty -> context tzresult = + fun ctxt loc ty -> + Gas.consume ctxt Typecheck_costs.check_dupable_cycle >>? fun ctxt -> + match ty with + | Unit_t _ -> ok ctxt + | Int_t _ -> ok ctxt + | Nat_t _ -> ok ctxt + | Signature_t _ -> ok ctxt + | String_t _ -> ok ctxt + | Bytes_t _ -> ok ctxt + | Mutez_t _ -> ok ctxt + | Key_hash_t _ -> ok ctxt + | Key_t _ -> ok ctxt + | Timestamp_t _ -> ok ctxt + | Address_t _ -> ok ctxt + | Bool_t _ -> ok ctxt + | Contract_t (_, _) -> ok ctxt + | Operation_t _ -> ok ctxt + | Chain_id_t _ -> ok ctxt + | Never_t _ -> ok ctxt + | Bls12_381_g1_t _ -> ok ctxt + | Bls12_381_g2_t _ -> ok ctxt + | Bls12_381_fr_t _ -> ok ctxt + | Sapling_state_t _ -> ok ctxt + | Sapling_transaction_t _ -> ok ctxt + | Chest_t _ -> ok ctxt + | Chest_key_t _ -> ok ctxt + | Ticket_t _ -> error (Unexpected_ticket loc) + | Pair_t ((ty_a, _, _), (ty_b, _, _), _) -> + check_dupable_ty ctxt loc ty_a >>? fun ctxt -> + check_dupable_ty ctxt loc ty_b + | Union_t ((ty_a, _), (ty_b, _), _) -> + check_dupable_ty ctxt loc ty_a >>? fun ctxt -> + check_dupable_ty ctxt loc ty_b + | Lambda_t (_, _, _) -> + (* + Lambda are dupable as long as: + - they don't contain non-dupable values, e.g. in `PUSH` + (mostly non-dupable values should probably be considered forged) + - they are not the result of a partial application on a non-dupable + value. `APPLY` rejects non-packable types (because of `PUSH`). + Hence non-dupable should imply non-packable. + *) + ok ctxt + | Option_t (ty, _) -> check_dupable_ty ctxt loc ty + | List_t (ty, _) -> check_dupable_ty ctxt loc ty + | Set_t (key_ty, _) -> + let () = check_dupable_comparable_ty key_ty in + ok ctxt + | Map_t (key_ty, val_ty, _) -> + let () = check_dupable_comparable_ty key_ty in + check_dupable_ty ctxt loc val_ty + | Big_map_t (key_ty, val_ty, _) -> + let () = check_dupable_comparable_ty key_ty in + check_dupable_ty ctxt loc val_ty + +(* ---- Equality witnesses --------------------------------------------------*) + +type ('ta, 'tb) eq = Eq : ('same, 'same) eq + +let record_inconsistent_types loc ta tb = + record_trace_eval (fun () -> + let ta = serialize_ty_for_error ta in + let tb = serialize_ty_for_error tb in + Inconsistent_types (Some loc, ta, tb)) + +let merge_type_metadata : + legacy:bool -> 'a ty_metadata -> 'b ty_metadata -> 'a ty_metadata tzresult = + fun ~legacy {size = size_a; annot = annot_a} {size = size_b; annot = annot_b} -> + Type_size.merge size_a size_b >>? fun size -> + merge_type_annot ~legacy annot_a annot_b >|? fun annot -> {annot; size} + +(* Takes two comparable types and simultaneously merge their annotations and + check that they represent the same type. + + The result contains: + - an equality witness between the types of the two inputs + - the merged type + - an updated context (for gas consumption) + + The tzresult monad is used at two levels: the inner tzresult + is used for tracking merge errors (types of different shapes + or annotation mismatches), the outer tzresult is used only + for gas consumption. Separating these two error cases like + this allows to recover from a type comparison error without + reverting the gas consumption. + *) +let rec merge_comparable_types : + type ta tb. + legacy:bool -> + ta comparable_ty -> + tb comparable_ty -> + ( (ta comparable_ty, tb comparable_ty) eq * ta comparable_ty, + error trace ) + Gas_monad.t = + let open Gas_monad in + fun ~legacy ta tb -> + consume_gas Typecheck_costs.merge_cycle >>$ fun () -> + let merge_type_metadata ~legacy meta_a meta_b = + of_result @@ merge_type_metadata ~legacy meta_a meta_b + in + let merge_field_annot ~legacy annot_a annot_b = + of_result @@ merge_field_annot ~legacy annot_a annot_b + in + let return f eq annot_a annot_b : + ( (ta comparable_ty, tb comparable_ty) eq * ta comparable_ty, + error trace ) + gas_monad = + merge_type_metadata ~legacy annot_a annot_b >>$ fun annot -> + return (eq, f annot) + in + match (ta, tb) with + | (Unit_key annot_a, Unit_key annot_b) -> + return (fun annot -> Unit_key annot) Eq annot_a annot_b + | (Never_key annot_a, Never_key annot_b) -> + return (fun annot -> Never_key annot) Eq annot_a annot_b + | (Int_key annot_a, Int_key annot_b) -> + return (fun annot -> Int_key annot) Eq annot_a annot_b + | (Nat_key annot_a, Nat_key annot_b) -> + return (fun annot -> Nat_key annot) Eq annot_a annot_b + | (Signature_key annot_a, Signature_key annot_b) -> + return (fun annot -> Signature_key annot) Eq annot_a annot_b + | (String_key annot_a, String_key annot_b) -> + return (fun annot -> String_key annot) Eq annot_a annot_b + | (Bytes_key annot_a, Bytes_key annot_b) -> + return (fun annot -> Bytes_key annot) Eq annot_a annot_b + | (Mutez_key annot_a, Mutez_key annot_b) -> + return (fun annot -> Mutez_key annot) Eq annot_a annot_b + | (Bool_key annot_a, Bool_key annot_b) -> + return (fun annot -> Bool_key annot) Eq annot_a annot_b + | (Key_hash_key annot_a, Key_hash_key annot_b) -> + return (fun annot -> Key_hash_key annot) Eq annot_a annot_b + | (Key_key annot_a, Key_key annot_b) -> + return (fun annot -> Key_key annot) Eq annot_a annot_b + | (Timestamp_key annot_a, Timestamp_key annot_b) -> + return (fun annot -> Timestamp_key annot) Eq annot_a annot_b + | (Chain_id_key annot_a, Chain_id_key annot_b) -> + return (fun annot -> Chain_id_key annot) Eq annot_a annot_b + | (Address_key annot_a, Address_key annot_b) -> + return (fun annot -> Address_key annot) Eq annot_a annot_b + | ( Pair_key ((left_a, annot_left_a), (right_a, annot_right_a), annot_a), + Pair_key ((left_b, annot_left_b), (right_b, annot_right_b), annot_b) ) + -> + merge_type_metadata ~legacy annot_a annot_b >>$ fun annot -> + merge_field_annot ~legacy annot_left_a annot_left_b + >>$ fun annot_left -> + merge_field_annot ~legacy annot_right_a annot_right_b + >>$ fun annot_right -> + merge_comparable_types ~legacy left_a left_b >>$ fun (Eq, left) -> + merge_comparable_types ~legacy right_a right_b >|$ fun (Eq, right) -> + ( (Eq : (ta comparable_ty, tb comparable_ty) eq), + Pair_key ((left, annot_left), (right, annot_right), annot) ) + | ( Union_key ((left_a, annot_left_a), (right_a, annot_right_a), annot_a), + Union_key ((left_b, annot_left_b), (right_b, annot_right_b), annot_b) ) + -> + merge_type_metadata ~legacy annot_a annot_b >>$ fun annot -> + merge_field_annot ~legacy annot_left_a annot_left_b + >>$ fun annot_left -> + merge_field_annot ~legacy annot_right_a annot_right_b + >>$ fun annot_right -> + merge_comparable_types ~legacy left_a left_b >>$ fun (Eq, left) -> + merge_comparable_types ~legacy right_a right_b >|$ fun (Eq, right) -> + ( (Eq : (ta comparable_ty, tb comparable_ty) eq), + Union_key ((left, annot_left), (right, annot_right), annot) ) + | (Option_key (ta, annot_a), Option_key (tb, annot_b)) -> + merge_type_metadata ~legacy annot_a annot_b >>$ fun annot -> + merge_comparable_types ~legacy ta tb >|$ fun (Eq, t) -> + ((Eq : (ta comparable_ty, tb comparable_ty) eq), Option_key (t, annot)) + | (_, _) -> + let ta = serialize_ty_for_error (ty_of_comparable_ty ta) in + let tb = serialize_ty_for_error (ty_of_comparable_ty tb) in + of_result @@ error (Inconsistent_types (None, ta, tb)) + +(* This function does not distinguish gas errors from merge errors. If you need + to recover from a type mismatch and consume the exact gas for the failed + comparison, use [merge_comparable_types] instead. +*) +let comparable_ty_eq : + type ta tb. + context -> + ta comparable_ty -> + tb comparable_ty -> + ((ta comparable_ty, tb comparable_ty) eq * context) tzresult = + fun ctxt ta tb -> + Gas_monad.run ctxt (merge_comparable_types ~legacy:true ta tb) + >>? fun (eq_ty, ctxt) -> + eq_ty >|? fun (eq, _ty) -> (eq, ctxt) + +let merge_memo_sizes ms1 ms2 = + if Sapling.Memo_size.equal ms1 ms2 then ok ms1 + else error (Inconsistent_memo_sizes (ms1, ms2)) + +type merge_type_error_flag = Default_merge_type_error | Fast_merge_type_error + +let default_merge_type_error ty1 ty2 = + let ty1 = serialize_ty_for_error ty1 in + let ty2 = serialize_ty_for_error ty2 in + Inconsistent_types (None, ty1, ty2) + +type error += Inconsistent_types_fast + +let fast_merge_type_error _ty1 _ty2 = Inconsistent_types_fast + +let merge_type_error ~merge_type_error_flag = + match merge_type_error_flag with + | Default_merge_type_error -> default_merge_type_error + | Fast_merge_type_error -> fast_merge_type_error + +let record_inconsistent_carbonated ta tb = + Gas_monad.record_trace_eval (fun () -> + let ta = serialize_ty_for_error ta in + let tb = serialize_ty_for_error tb in + Inconsistent_types (None, ta, tb)) + +(* Same as merge_comparable_types but for any types *) +let merge_types : + type a b. + legacy:bool -> + merge_type_error_flag:merge_type_error_flag -> + Script.location -> + a ty -> + b ty -> + ((a ty, b ty) eq * a ty, error trace) Gas_monad.t = + let open Gas_monad in + fun ~legacy ~merge_type_error_flag loc ty1 ty2 -> + let merge_type_metadata tn1 tn2 = + of_result + (merge_type_metadata ~legacy tn1 tn2 + |> record_inconsistent_types loc ty1 ty2) + in + let merge_field_annot ~legacy tn1 tn2 = + of_result (merge_field_annot ~legacy tn1 tn2) + in + let merge_memo_sizes ms1 ms2 = of_result (merge_memo_sizes ms1 ms2) in + let rec help : + type ta tb. + ta ty -> tb ty -> ((ta ty, tb ty) eq * ta ty, error trace) gas_monad = + fun ty1 ty2 -> help0 ty1 ty2 |> record_inconsistent_carbonated ty1 ty2 + and help0 : + type ta tb. + ta ty -> tb ty -> ((ta ty, tb ty) eq * ta ty, error trace) gas_monad = + fun ty1 ty2 -> + consume_gas Typecheck_costs.merge_cycle >>$ fun () -> + let return f eq annot_a annot_b : + ((ta ty, tb ty) eq * ta ty, error trace) gas_monad = + merge_type_metadata annot_a annot_b >>$ fun annot -> return (eq, f annot) + in + match (ty1, ty2) with + | (Unit_t tn1, Unit_t tn2) -> + return (fun tname -> Unit_t tname) Eq tn1 tn2 + | (Int_t tn1, Int_t tn2) -> return (fun tname -> Int_t tname) Eq tn1 tn2 + | (Nat_t tn1, Nat_t tn2) -> return (fun tname -> Nat_t tname) Eq tn1 tn2 + | (Key_t tn1, Key_t tn2) -> return (fun tname -> Key_t tname) Eq tn1 tn2 + | (Key_hash_t tn1, Key_hash_t tn2) -> + return (fun tname -> Key_hash_t tname) Eq tn1 tn2 + | (String_t tn1, String_t tn2) -> + return (fun tname -> String_t tname) Eq tn1 tn2 + | (Bytes_t tn1, Bytes_t tn2) -> + return (fun tname -> Bytes_t tname) Eq tn1 tn2 + | (Signature_t tn1, Signature_t tn2) -> + return (fun tname -> Signature_t tname) Eq tn1 tn2 + | (Mutez_t tn1, Mutez_t tn2) -> + return (fun tname -> Mutez_t tname) Eq tn1 tn2 + | (Timestamp_t tn1, Timestamp_t tn2) -> + return (fun tname -> Timestamp_t tname) Eq tn1 tn2 + | (Address_t tn1, Address_t tn2) -> + return (fun tname -> Address_t tname) Eq tn1 tn2 + | (Bool_t tn1, Bool_t tn2) -> + return (fun tname -> Bool_t tname) Eq tn1 tn2 + | (Chain_id_t tn1, Chain_id_t tn2) -> + return (fun tname -> Chain_id_t tname) Eq tn1 tn2 + | (Never_t tn1, Never_t tn2) -> + return (fun tname -> Never_t tname) Eq tn1 tn2 + | (Operation_t tn1, Operation_t tn2) -> + return (fun tname -> Operation_t tname) Eq tn1 tn2 + | (Bls12_381_g1_t tn1, Bls12_381_g1_t tn2) -> + return (fun tname -> Bls12_381_g1_t tname) Eq tn1 tn2 + | (Bls12_381_g2_t tn1, Bls12_381_g2_t tn2) -> + return (fun tname -> Bls12_381_g2_t tname) Eq tn1 tn2 + | (Bls12_381_fr_t tn1, Bls12_381_fr_t tn2) -> + return (fun tname -> Bls12_381_fr_t tname) Eq tn1 tn2 + | (Map_t (tal, tar, tn1), Map_t (tbl, tbr, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + help tar tbr >>$ fun (Eq, value) -> + merge_comparable_types ~legacy tal tbl >|$ fun (Eq, tk) -> + ((Eq : (ta ty, tb ty) eq), Map_t (tk, value, tname)) + | (Big_map_t (tal, tar, tn1), Big_map_t (tbl, tbr, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + help tar tbr >>$ fun (Eq, value) -> + merge_comparable_types ~legacy tal tbl >|$ fun (Eq, tk) -> + ((Eq : (ta ty, tb ty) eq), Big_map_t (tk, value, tname)) + | (Set_t (ea, tn1), Set_t (eb, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + merge_comparable_types ~legacy ea eb >|$ fun (Eq, e) -> + ((Eq : (ta ty, tb ty) eq), Set_t (e, tname)) + | (Ticket_t (ea, tn1), Ticket_t (eb, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + merge_comparable_types ~legacy ea eb >|$ fun (Eq, e) -> + ((Eq : (ta ty, tb ty) eq), Ticket_t (e, tname)) + | ( Pair_t ((tal, l_field1, l_var1), (tar, r_field1, r_var1), tn1), + Pair_t ((tbl, l_field2, l_var2), (tbr, r_field2, r_var2), tn2) ) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + merge_field_annot ~legacy l_field1 l_field2 >>$ fun l_field -> + merge_field_annot ~legacy r_field1 r_field2 >>$ fun r_field -> + let l_var = merge_var_annot l_var1 l_var2 in + let r_var = merge_var_annot r_var1 r_var2 in + help tal tbl >>$ fun (Eq, left_ty) -> + help tar tbr >|$ fun (Eq, right_ty) -> + ( (Eq : (ta ty, tb ty) eq), + Pair_t ((left_ty, l_field, l_var), (right_ty, r_field, r_var), tname) + ) + | ( Union_t ((tal, tal_annot), (tar, tar_annot), tn1), + Union_t ((tbl, tbl_annot), (tbr, tbr_annot), tn2) ) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + merge_field_annot ~legacy tal_annot tbl_annot >>$ fun left_annot -> + merge_field_annot ~legacy tar_annot tbr_annot >>$ fun right_annot -> + help tal tbl >>$ fun (Eq, left_ty) -> + help tar tbr >|$ fun (Eq, right_ty) -> + ( (Eq : (ta ty, tb ty) eq), + Union_t ((left_ty, left_annot), (right_ty, right_annot), tname) ) + | (Lambda_t (tal, tar, tn1), Lambda_t (tbl, tbr, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + help tal tbl >>$ fun (Eq, left_ty) -> + help tar tbr >|$ fun (Eq, right_ty) -> + ((Eq : (ta ty, tb ty) eq), Lambda_t (left_ty, right_ty, tname)) + | (Contract_t (tal, tn1), Contract_t (tbl, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + help tal tbl >|$ fun (Eq, arg_ty) -> + ((Eq : (ta ty, tb ty) eq), Contract_t (arg_ty, tname)) + | (Option_t (tva, tn1), Option_t (tvb, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + help tva tvb >|$ fun (Eq, ty) -> + ((Eq : (ta ty, tb ty) eq), Option_t (ty, tname)) + | (List_t (tva, tn1), List_t (tvb, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + help tva tvb >|$ fun (Eq, ty) -> + ((Eq : (ta ty, tb ty) eq), List_t (ty, tname)) + | (Sapling_state_t (ms1, tn1), Sapling_state_t (ms2, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + merge_memo_sizes ms1 ms2 >|$ fun ms -> + (Eq, Sapling_state_t (ms, tname)) + | (Sapling_transaction_t (ms1, tn1), Sapling_transaction_t (ms2, tn2)) -> + merge_type_metadata tn1 tn2 >>$ fun tname -> + merge_memo_sizes ms1 ms2 >|$ fun ms -> + (Eq, Sapling_transaction_t (ms, tname)) + | (Chest_t tn1, Chest_t tn2) -> + return (fun tname -> Chest_t tname) Eq tn1 tn2 + | (Chest_key_t tn1, Chest_key_t tn2) -> + return (fun tname -> Chest_key_t tname) Eq tn1 tn2 + | (_, _) -> + of_result @@ error @@ merge_type_error ~merge_type_error_flag ty1 ty2 + in + help ty1 ty2 + [@@coq_axiom_with_reason "non-top-level mutual recursion"] + +(* This function does not distinguish gas errors from merge errors. If you need + to recover from a type mismatch and consume the exact gas for the failed + comparison, use [merge_types] instead. +*) +let ty_eq : + type ta tb. + legacy:bool -> + context -> + Script.location -> + ta ty -> + tb ty -> + ((ta ty, tb ty) eq * context) tzresult = + fun ~legacy ctxt loc ta tb -> + Gas_monad.run ctxt + @@ merge_types + ~merge_type_error_flag:Default_merge_type_error + ~legacy + loc + ta + tb + >>? fun (eq_ty, ctxt) -> + eq_ty >|? fun (eq, _ty) -> (eq, ctxt) + +(* Same as merge_comparable_types and merge_types but for stacks. + A single error monad is used here because there is no need to + recover from stack merging errors. *) +let merge_stacks : + type ta tb ts tu. + legacy:bool -> + Script.location -> + context -> + int -> + (ta, ts) stack_ty -> + (tb, tu) stack_ty -> + (((ta, ts) stack_ty, (tb, tu) stack_ty) eq * (ta, ts) stack_ty * context) + tzresult = + fun ~legacy loc -> + let rec help : + type ta tb ts tu. + context -> + int -> + (ta, ts) stack_ty -> + (tb, tu) stack_ty -> + (((ta, ts) stack_ty, (tb, tu) stack_ty) eq * (ta, ts) stack_ty * context) + tzresult = + fun ctxt lvl stack1 stack2 -> + match (stack1, stack2) with + | (Bot_t, Bot_t) -> ok (Eq, Bot_t, ctxt) + | (Item_t (ty1, rest1, annot1), Item_t (ty2, rest2, annot2)) -> + Gas_monad.run ctxt + @@ merge_types + ~merge_type_error_flag:Default_merge_type_error + ~legacy + loc + ty1 + ty2 + |> record_trace (Bad_stack_item lvl) + >>? fun (eq_ty, ctxt) -> + eq_ty >>? fun (Eq, ty) -> + help ctxt (lvl + 1) rest1 rest2 >|? fun (Eq, rest, ctxt) -> + let annot = merge_var_annot annot1 annot2 in + ( (Eq : ((ta, ts) stack_ty, (tb, tu) stack_ty) eq), + Item_t (ty, rest, annot), + ctxt ) + | (_, _) -> error Bad_stack_length + in + help + +(* ---- Type checker results -------------------------------------------------*) + +type ('a, 's) judgement = + | Typed : ('a, 's, 'b, 'u) descr -> ('a, 's) judgement + | Failed : { + descr : 'b 'u. ('b, 'u) stack_ty -> ('a, 's, 'b, 'u) descr; + } + -> ('a, 's) judgement + +(* ---- Type checker (Untyped expressions -> Typed IR) ----------------------*) + +type ('a, 's, 'b, 'u, 'c, 'v) branch = { + branch : + 'r 'f. + ('a, 's, 'r, 'f) descr -> ('b, 'u, 'r, 'f) descr -> ('c, 'v, 'r, 'f) descr; +} +[@@unboxed] + +let merge_branches : + type a s b u c v. + legacy:bool -> + context -> + Script.location -> + (a, s) judgement -> + (b, u) judgement -> + (a, s, b, u, c, v) branch -> + ((c, v) judgement * context) tzresult = + fun ~legacy ctxt loc btr bfr {branch} -> + match (btr, bfr) with + | (Typed ({aft = aftbt; _} as dbt), Typed ({aft = aftbf; _} as dbf)) -> + let unmatched_branches () = + let aftbt = serialize_stack_for_error ctxt aftbt in + let aftbf = serialize_stack_for_error ctxt aftbf in + Unmatched_branches (loc, aftbt, aftbf) + in + record_trace_eval + unmatched_branches + ( merge_stacks ~legacy loc ctxt 1 aftbt aftbf + >|? fun (Eq, merged_stack, ctxt) -> + ( Typed + (branch + {dbt with aft = merged_stack} + {dbf with aft = merged_stack}), + ctxt ) ) + | (Failed {descr = descrt}, Failed {descr = descrf}) -> + let descr ret = branch (descrt ret) (descrf ret) in + ok (Failed {descr}, ctxt) + | (Typed dbt, Failed {descr = descrf}) -> + ok (Typed (branch dbt (descrf dbt.aft)), ctxt) + | (Failed {descr = descrt}, Typed dbf) -> + ok (Typed (branch (descrt dbf.aft) dbf), ctxt) + +let parse_memo_size (n : (location, _) Micheline.node) : + Sapling.Memo_size.t tzresult = + match n with + | Int (_, z) -> ( + match Sapling.Memo_size.parse_z z with + | Ok _ as ok_memo_size -> ok_memo_size [@coq_cast] + | Error msg -> + error + @@ Invalid_syntactic_constant (location n, strip_locations n, msg)) + | _ -> error @@ Invalid_kind (location n, [Int_kind], kind n) + +type ex_comparable_ty = + | Ex_comparable_ty : 'a comparable_ty -> ex_comparable_ty + +let[@coq_struct "ty"] rec parse_comparable_ty : + stack_depth:int -> + context -> + Script.node -> + (ex_comparable_ty * context) tzresult = + fun ~stack_depth ctxt ty -> + Gas.consume ctxt Typecheck_costs.parse_type_cycle >>? fun ctxt -> + if Compare.Int.(stack_depth > 10000) then + error Typechecking_too_many_recursive_calls + else + match ty with + | Prim (loc, T_unit, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (unit_key ~annot), ctxt) + | Prim (loc, T_never, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (never_key ~annot), ctxt) + | Prim (loc, T_int, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (int_key ~annot), ctxt) + | Prim (loc, T_nat, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (nat_key ~annot), ctxt) + | Prim (loc, T_signature, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (signature_key ~annot), ctxt) + | Prim (loc, T_string, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (string_key ~annot), ctxt) + | Prim (loc, T_bytes, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (bytes_key ~annot), ctxt) + | Prim (loc, T_mutez, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (mutez_key ~annot), ctxt) + | Prim (loc, T_bool, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (bool_key ~annot), ctxt) + | Prim (loc, T_key_hash, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (key_hash_key ~annot), ctxt) + | Prim (loc, T_key, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (key_key ~annot), ctxt) + | Prim (loc, T_timestamp, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (timestamp_key ~annot), ctxt) + | Prim (loc, T_chain_id, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (chain_id_key ~annot), ctxt) + | Prim (loc, T_address, [], annot) -> + parse_type_annot loc annot >|? fun annot -> + (Ex_comparable_ty (address_key ~annot), ctxt) + | Prim + ( loc, + (( T_unit | T_never | T_int | T_nat | T_string | T_bytes | T_mutez + | T_bool | T_key_hash | T_timestamp | T_address | T_chain_id + | T_signature | T_key ) as prim), + l, + _ ) -> + error (Invalid_arity (loc, prim, 0, List.length l)) + | Prim (loc, T_pair, left :: right, annot) -> + parse_type_annot loc annot >>? fun annot -> + extract_field_annot left >>? fun (left, left_annot) -> + (match right with + | [right] -> extract_field_annot right + | right -> + (* Unfold [pair t1 ... tn] as [pair t1 (... (pair tn-1 tn))] *) + ok (Prim (loc, T_pair, right, []), None)) + >>? fun (right, right_annot) -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt right + >>? fun (Ex_comparable_ty right, ctxt) -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt left + >>? fun (Ex_comparable_ty left, ctxt) -> + pair_key loc (left, left_annot) (right, right_annot) ~annot + >|? fun ty -> (Ex_comparable_ty ty, ctxt) + | Prim (loc, T_or, [left; right], annot) -> + parse_type_annot loc annot >>? fun annot -> + extract_field_annot left >>? fun (left, left_annot) -> + extract_field_annot right >>? fun (right, right_annot) -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt right + >>? fun (Ex_comparable_ty right, ctxt) -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt left + >>? fun (Ex_comparable_ty left, ctxt) -> + union_key loc (left, left_annot) (right, right_annot) ~annot + >|? fun ty -> (Ex_comparable_ty ty, ctxt) + | Prim (loc, ((T_pair | T_or) as prim), l, _) -> + error (Invalid_arity (loc, prim, 2, List.length l)) + | Prim (loc, T_option, [t], annot) -> + parse_type_annot loc annot >>? fun annot -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt t + >>? fun (Ex_comparable_ty t, ctxt) -> + option_key loc t ~annot >|? fun ty -> (Ex_comparable_ty ty, ctxt) + | Prim (loc, T_option, l, _) -> + error (Invalid_arity (loc, T_option, 1, List.length l)) + | Prim + ( loc, + (T_set | T_map | T_list | T_lambda | T_contract | T_operation), + _, + _ ) -> + error (Comparable_type_expected (loc, Micheline.strip_locations ty)) + | expr -> + error + @@ unexpected + expr + [] + Type_namespace + [ + T_unit; + T_never; + T_int; + T_nat; + T_string; + T_bytes; + T_mutez; + T_bool; + T_key_hash; + T_timestamp; + T_address; + T_pair; + T_or; + T_option; + T_chain_id; + T_signature; + T_key; + ] + +type ex_ty = Ex_ty : 'a ty -> ex_ty + +let[@coq_axiom_with_reason "complex mutually recursive definition"] rec parse_packable_ty + : + context -> + stack_depth:int -> + legacy:bool -> + Script.node -> + (ex_ty * context) tzresult = + fun ctxt ~stack_depth ~legacy -> + (parse_ty [@tailcall]) + ctxt + ~stack_depth + ~legacy + ~allow_lazy_storage:false + ~allow_operation:false + ~allow_contract: + legacy + (* type contract is forbidden in UNPACK because of + https://gitlab.com/tezos/tezos/-/issues/301 *) + ~allow_ticket:false + +and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_parameter_ty + : + context -> + stack_depth:int -> + legacy:bool -> + Script.node -> + (ex_ty * context) tzresult = + fun ctxt ~stack_depth ~legacy -> + (parse_ty [@tailcall]) + ctxt + ~stack_depth + ~legacy + ~allow_lazy_storage:true + ~allow_operation:false + ~allow_contract:true + ~allow_ticket:true + +and parse_view_input_ty : + context -> + stack_depth:int -> + legacy:bool -> + Script.node -> + (ex_ty * context) tzresult = + fun ctxt ~stack_depth ~legacy -> + (parse_ty [@tailcall]) + ctxt + ~stack_depth + ~legacy + ~allow_lazy_storage:false + ~allow_operation:false + ~allow_contract:true + ~allow_ticket:false + +and parse_view_output_ty : + context -> + stack_depth:int -> + legacy:bool -> + Script.node -> + (ex_ty * context) tzresult = + fun ctxt ~stack_depth ~legacy -> + (parse_ty [@tailcall]) + ctxt + ~stack_depth + ~legacy + ~allow_lazy_storage:false + ~allow_operation:false + ~allow_contract:true + ~allow_ticket:false + +and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_normal_storage_ty + : + context -> + stack_depth:int -> + legacy:bool -> + Script.node -> + (ex_ty * context) tzresult = + fun ctxt ~stack_depth ~legacy -> + (parse_ty [@tailcall]) + ctxt + ~stack_depth + ~legacy + ~allow_lazy_storage:true + ~allow_operation:false + ~allow_contract:legacy + ~allow_ticket:true + +and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_any_ty + : + context -> + stack_depth:int -> + legacy:bool -> + Script.node -> + (ex_ty * context) tzresult = + fun ctxt ~stack_depth ~legacy -> + (parse_ty [@tailcall]) + ctxt + ~stack_depth + ~legacy + ~allow_lazy_storage:true + ~allow_operation:true + ~allow_contract:true + ~allow_ticket:true + +and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_ty : + context -> + stack_depth:int -> + legacy:bool -> + allow_lazy_storage:bool -> + allow_operation:bool -> + allow_contract:bool -> + allow_ticket:bool -> + Script.node -> + (ex_ty * context) tzresult = + fun ctxt + ~stack_depth + ~legacy + ~allow_lazy_storage + ~allow_operation + ~allow_contract + ~allow_ticket + node -> + Gas.consume ctxt Typecheck_costs.parse_type_cycle >>? fun ctxt -> + if Compare.Int.(stack_depth > 10000) then + error Typechecking_too_many_recursive_calls + else + match node with + | Prim (loc, T_unit, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (unit_t ~annot), ctxt) + | Prim (loc, T_int, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (int_t ~annot), ctxt) + | Prim (loc, T_nat, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (nat_t ~annot), ctxt) + | Prim (loc, T_string, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (string_t ~annot), ctxt) + | Prim (loc, T_bytes, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (bytes_t ~annot), ctxt) + | Prim (loc, T_mutez, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (mutez_t ~annot), ctxt) + | Prim (loc, T_bool, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (bool_t ~annot), ctxt) + | Prim (loc, T_key, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (key_t ~annot), ctxt) + | Prim (loc, T_key_hash, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (key_hash_t ~annot), ctxt) + | Prim (loc, T_chest_key, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (chest_key_t ~annot), ctxt) + | Prim (loc, T_chest, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (chest_t ~annot), ctxt) + | Prim (loc, T_timestamp, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (timestamp_t ~annot), ctxt) + | Prim (loc, T_address, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (address_t ~annot), ctxt) + | Prim (loc, T_signature, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (signature_t ~annot), ctxt) + | Prim (loc, T_operation, [], annot) -> + if allow_operation then + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (operation_t ~annot), ctxt) + else error (Unexpected_operation loc) + | Prim (loc, T_chain_id, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (chain_id_t ~annot), ctxt) + | Prim (loc, T_never, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (never_t ~annot), ctxt) + | Prim (loc, T_bls12_381_g1, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (bls12_381_g1_t ~annot), ctxt) + | Prim (loc, T_bls12_381_g2, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (bls12_381_g2_t ~annot), ctxt) + | Prim (loc, T_bls12_381_fr, [], annot) -> + parse_type_annot loc annot >>? fun annot -> + ok (Ex_ty (bls12_381_fr_t ~annot), ctxt) + | Prim (loc, T_contract, [utl], annot) -> + if allow_contract then + parse_parameter_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy utl + >>? fun (Ex_ty tl, ctxt) -> + parse_type_annot loc annot >>? fun annot -> + contract_t loc tl ~annot >|? fun ty -> (Ex_ty ty, ctxt) + else error (Unexpected_contract loc) + | Prim (loc, T_pair, utl :: utr, annot) -> + extract_field_annot utl >>? fun (utl, left_field) -> + parse_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + ~allow_lazy_storage + ~allow_operation + ~allow_contract + ~allow_ticket + utl + >>? fun (Ex_ty tl, ctxt) -> + (match utr with + | [utr] -> extract_field_annot utr + | utr -> + (* Unfold [pair t1 ... tn] as [pair t1 (... (pair tn-1 tn))] *) + ok (Prim (loc, T_pair, utr, []), None)) + >>? fun (utr, right_field) -> + parse_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + ~allow_lazy_storage + ~allow_operation + ~allow_contract + ~allow_ticket + utr + >>? fun (Ex_ty tr, ctxt) -> + parse_type_annot loc annot >>? fun annot -> + pair_t loc (tl, left_field, None) (tr, right_field, None) ~annot + >|? fun ty -> (Ex_ty ty, ctxt) + | Prim (loc, T_or, [utl; utr], annot) -> + extract_field_annot utl >>? fun (utl, left_constr) -> + extract_field_annot utr >>? fun (utr, right_constr) -> + parse_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + ~allow_lazy_storage + ~allow_operation + ~allow_contract + ~allow_ticket + utl + >>? fun (Ex_ty tl, ctxt) -> + parse_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + ~allow_lazy_storage + ~allow_operation + ~allow_contract + ~allow_ticket + utr + >>? fun (Ex_ty tr, ctxt) -> + parse_type_annot loc annot >>? fun annot -> + union_t loc (tl, left_constr) (tr, right_constr) ~annot >|? fun ty -> + (Ex_ty ty, ctxt) + | Prim (loc, T_lambda, [uta; utr], annot) -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy uta + >>? fun (Ex_ty ta, ctxt) -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy utr + >>? fun (Ex_ty tr, ctxt) -> + parse_type_annot loc annot >>? fun annot -> + lambda_t loc ta tr ~annot >|? fun ty -> (Ex_ty ty, ctxt) + | Prim (loc, T_option, [ut], annot) -> + (if legacy then + (* legacy semantics with (broken) field annotations *) + extract_field_annot ut >>? fun (ut, _some_constr) -> + parse_composed_type_annot loc annot + >>? fun (ty_name, _none_constr, _) -> ok (ut, ty_name) + else parse_type_annot loc annot >>? fun annot -> ok (ut, annot)) + >>? fun (ut, annot) -> + parse_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + ~allow_lazy_storage + ~allow_operation + ~allow_contract + ~allow_ticket + ut + >>? fun (Ex_ty t, ctxt) -> + option_t loc t ~annot >|? fun ty -> (Ex_ty ty, ctxt) + | Prim (loc, T_list, [ut], annot) -> + parse_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + ~allow_lazy_storage + ~allow_operation + ~allow_contract + ~allow_ticket + ut + >>? fun (Ex_ty t, ctxt) -> + parse_type_annot loc annot >>? fun annot -> + list_t loc t ~annot >|? fun ty -> (Ex_ty ty, ctxt) + | Prim (loc, T_ticket, [ut], annot) -> + if allow_ticket then + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt ut + >>? fun (Ex_comparable_ty t, ctxt) -> + parse_type_annot loc annot >>? fun annot -> + ticket_t loc t ~annot >|? fun ty -> (Ex_ty ty, ctxt) + else error (Unexpected_ticket loc) + | Prim (loc, T_set, [ut], annot) -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt ut + >>? fun (Ex_comparable_ty t, ctxt) -> + parse_type_annot loc annot >>? fun annot -> + set_t loc t ~annot >|? fun ty -> (Ex_ty ty, ctxt) + | Prim (loc, T_map, [uta; utr], annot) -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt uta + >>? fun (Ex_comparable_ty ta, ctxt) -> + parse_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + ~allow_lazy_storage + ~allow_operation + ~allow_contract + ~allow_ticket + utr + >>? fun (Ex_ty tr, ctxt) -> + parse_type_annot loc annot >>? fun annot -> + map_t loc ta tr ~annot >|? fun ty -> (Ex_ty ty, ctxt) + | Prim (loc, T_sapling_transaction, [memo_size], annot) -> + parse_type_annot loc annot >>? fun annot -> + parse_memo_size memo_size >|? fun memo_size -> + (Ex_ty (sapling_transaction_t ~memo_size ~annot), ctxt) + (* + /!\ When adding new lazy storage kinds, be careful to use + [when allow_lazy_storage] /!\ + Lazy storage should not be packable to avoid stealing a lazy storage + from another contract with `PUSH t id` or `UNPACK`. + *) + | Prim (loc, T_big_map, args, annot) when allow_lazy_storage -> + (parse_big_map_ty [@tailcall]) ctxt ~stack_depth ~legacy loc args annot + | Prim (loc, T_sapling_state, [memo_size], annot) when allow_lazy_storage -> + parse_type_annot loc annot >>? fun annot -> + parse_memo_size memo_size >|? fun memo_size -> + (Ex_ty (sapling_state_t ~memo_size ~annot), ctxt) + | Prim (loc, (T_big_map | T_sapling_state), _, _) -> + error (Unexpected_lazy_storage loc) + | Prim + ( loc, + (( T_unit | T_signature | T_int | T_nat | T_string | T_bytes | T_mutez + | T_bool | T_key | T_key_hash | T_timestamp | T_address | T_chain_id + | T_operation | T_never ) as prim), + l, + _ ) -> + error (Invalid_arity (loc, prim, 0, List.length l)) + | Prim + ( loc, + ((T_set | T_list | T_option | T_contract | T_ticket) as prim), + l, + _ ) -> + error (Invalid_arity (loc, prim, 1, List.length l)) + | Prim (loc, ((T_pair | T_or | T_map | T_lambda) as prim), l, _) -> + error (Invalid_arity (loc, prim, 2, List.length l)) + | expr -> + error + @@ unexpected + expr + [] + Type_namespace + [ + T_pair; + T_or; + T_set; + T_map; + T_list; + T_option; + T_lambda; + T_unit; + T_signature; + T_contract; + T_int; + T_nat; + T_operation; + T_string; + T_bytes; + T_mutez; + T_bool; + T_key; + T_key_hash; + T_timestamp; + T_chain_id; + T_never; + T_bls12_381_g1; + T_bls12_381_g2; + T_bls12_381_fr; + T_ticket; + ] + +and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_big_map_ty + ctxt ~stack_depth ~legacy big_map_loc args map_annot = + Gas.consume ctxt Typecheck_costs.parse_type_cycle >>? fun ctxt -> + match args with + | [key_ty; value_ty] -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt key_ty + >>? fun (Ex_comparable_ty key_ty, ctxt) -> + parse_big_map_value_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + value_ty + >>? fun (Ex_ty value_ty, ctxt) -> + parse_type_annot big_map_loc map_annot >>? fun annot -> + big_map_t big_map_loc key_ty value_ty ~annot >|? fun big_map_ty -> + (Ex_ty big_map_ty, ctxt) + | args -> error @@ Invalid_arity (big_map_loc, T_big_map, 2, List.length args) + +and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_big_map_value_ty + ctxt ~stack_depth ~legacy value_ty = + (parse_ty [@tailcall]) + ctxt + ~stack_depth + ~legacy + ~allow_lazy_storage:false + ~allow_operation:false + ~allow_contract:legacy + ~allow_ticket:true + value_ty + +let parse_storage_ty : + context -> + stack_depth:int -> + legacy:bool -> + Script.node -> + (ex_ty * context) tzresult = + fun ctxt ~stack_depth ~legacy node -> + match node with + | Prim + ( loc, + T_pair, + [Prim (big_map_loc, T_big_map, args, map_annot); remaining_storage], + storage_annot ) + when legacy -> ( + match storage_annot with + | [] -> + (parse_normal_storage_ty [@tailcall]) ctxt ~stack_depth ~legacy node + | [single] + when Compare.Int.(String.length single > 0) + && Compare.Char.(single.[0] = '%') -> + (parse_normal_storage_ty [@tailcall]) ctxt ~stack_depth ~legacy node + | _ -> + (* legacy semantics of big maps used the wrong annotation parser *) + Gas.consume ctxt Typecheck_costs.parse_type_cycle >>? fun ctxt -> + parse_big_map_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + big_map_loc + args + map_annot + >>? fun (Ex_ty big_map_ty, ctxt) -> + parse_normal_storage_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + remaining_storage + >>? fun (Ex_ty remaining_storage, ctxt) -> + parse_composed_type_annot loc storage_annot + >>? fun (annot, map_field, storage_field) -> + pair_t + loc + (big_map_ty, map_field, None) + (remaining_storage, storage_field, None) + ~annot + >|? fun ty -> (Ex_ty ty, ctxt)) + | _ -> (parse_normal_storage_ty [@tailcall]) ctxt ~stack_depth ~legacy node + +let check_packable ~legacy loc root = + let rec check : type t. t ty -> unit tzresult = function + (* /!\ When adding new lazy storage kinds, be sure to return an error. /!\ + Lazy storage should not be packable. *) + | Big_map_t _ -> error (Unexpected_lazy_storage loc) + | Sapling_state_t _ -> error (Unexpected_lazy_storage loc) + | Operation_t _ -> error (Unexpected_operation loc) + | Unit_t _ -> Result.return_unit + | Int_t _ -> Result.return_unit + | Nat_t _ -> Result.return_unit + | Signature_t _ -> Result.return_unit + | String_t _ -> Result.return_unit + | Bytes_t _ -> Result.return_unit + | Mutez_t _ -> Result.return_unit + | Key_hash_t _ -> Result.return_unit + | Key_t _ -> Result.return_unit + | Timestamp_t _ -> Result.return_unit + | Address_t _ -> Result.return_unit + | Bool_t _ -> Result.return_unit + | Chain_id_t _ -> Result.return_unit + | Never_t _ -> Result.return_unit + | Set_t (_, _) -> Result.return_unit + | Ticket_t _ -> error (Unexpected_ticket loc) + | Lambda_t (_, _, _) -> Result.return_unit + | Bls12_381_g1_t _ -> Result.return_unit + | Bls12_381_g2_t _ -> Result.return_unit + | Bls12_381_fr_t _ -> Result.return_unit + | Pair_t ((l_ty, _, _), (r_ty, _, _), _) -> + check l_ty >>? fun () -> check r_ty + | Union_t ((l_ty, _), (r_ty, _), _) -> check l_ty >>? fun () -> check r_ty + | Option_t (v_ty, _) -> check v_ty + | List_t (elt_ty, _) -> check elt_ty + | Map_t (_, elt_ty, _) -> check elt_ty + | Contract_t (_, _) when legacy -> Result.return_unit + | Contract_t (_, _) -> error (Unexpected_contract loc) + | Sapling_transaction_t _ -> ok () + | Chest_key_t _ -> Result.return_unit + | Chest_t _ -> Result.return_unit + in + check root + +type toplevel = { + code_field : Script.node; + arg_type : Script.node; + storage_type : Script.node; + views : view SMap.t; + root_name : field_annot option; +} + +type ('arg, 'storage) code = { + code : (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; + arg_type : 'arg ty; + storage_type : 'storage ty; + views : view SMap.t; + root_name : field_annot option; + code_size : Cache_memory_helpers.sint; +} + +type ex_script = Ex_script : ('a, 'c) script -> ex_script + +type ex_code = Ex_code : ('a, 'c) code -> ex_code + +type 'storage ex_view = + | Ex_view : + ('input * 'storage, 'output) Script_typed_ir.lambda + -> 'storage ex_view + +type (_, _) dig_proof_argument = + | Dig_proof_argument : + ('x, 'a * 's, 'a, 's, 'b, 't, 'c, 'u) stack_prefix_preservation_witness + * 'x ty + * var_annot option + * ('c, 'u) stack_ty + -> ('b, 't) dig_proof_argument + +type (_, _, _) dug_proof_argument = + | Dug_proof_argument : + (('a, 's, 'x, 'a * 's, 'b, 't, 'c, 'u) stack_prefix_preservation_witness + * ('c, 'u) stack_ty) + -> ('b, 't, 'x) dug_proof_argument + +type (_, _) dipn_proof_argument = + | Dipn_proof_argument : + ('fa, 'fs, 'fb, 'fu, 'a, 's, 'b, 'u) stack_prefix_preservation_witness + * context + * ('fa, 'fs, 'fb, 'fu) descr + * ('b, 'u) stack_ty + -> ('a, 's) dipn_proof_argument + +type (_, _) dropn_proof_argument = + | Dropn_proof_argument : + ('fa, 'fs, 'fa, 'fs, 'a, 's, 'a, 's) stack_prefix_preservation_witness + * ('fa, 'fs) stack_ty + -> ('a, 's) dropn_proof_argument + +type 'before comb_proof_argument = + | Comb_proof_argument : + ('a * 's, 'b * 'u) comb_gadt_witness * ('b, 'u) stack_ty + -> ('a * 's) comb_proof_argument + +type 'before uncomb_proof_argument = + | Uncomb_proof_argument : + ('a * 's, 'b * 'u) uncomb_gadt_witness * ('b, 'u) stack_ty + -> ('a * 's) uncomb_proof_argument + +type 'before comb_get_proof_argument = + | Comb_get_proof_argument : + ('before, 'after) comb_get_gadt_witness * 'after ty + -> 'before comb_get_proof_argument + +type ('rest, 'before) comb_set_proof_argument = + | Comb_set_proof_argument : + ('rest, 'before, 'after) comb_set_gadt_witness * 'after ty + -> ('rest, 'before) comb_set_proof_argument + +type 'before dup_n_proof_argument = + | Dup_n_proof_argument : + ('before, 'a) dup_n_gadt_witness * 'a ty + -> 'before dup_n_proof_argument + +let find_entrypoint (type full) (full : full ty) ~root_name entrypoint = + let annot_is_entrypoint entrypoint = function + | None -> false + | Some (Field_annot l) -> Compare.String.((l :> string) = entrypoint) + in + let loc = Micheline.dummy_location in + let rec find_entrypoint : + type t. t ty -> string -> ((Script.node -> Script.node) * ex_ty) option = + fun t entrypoint -> + match t with + | Union_t ((tl, al), (tr, ar), _) -> ( + if annot_is_entrypoint entrypoint al then + Some ((fun e -> Prim (loc, D_Left, [e], [])), Ex_ty tl) + else if annot_is_entrypoint entrypoint ar then + Some ((fun e -> Prim (loc, D_Right, [e], [])), Ex_ty tr) + else + match find_entrypoint tl entrypoint with + | Some (f, t) -> Some ((fun e -> Prim (loc, D_Left, [f e], [])), t) + | None -> ( + match find_entrypoint tr entrypoint with + | Some (f, t) -> + Some ((fun e -> Prim (loc, D_Right, [f e], [])), t) + | None -> None)) + | _ -> None + in + let entrypoint = + if Compare.String.(entrypoint = "") then "default" else entrypoint + in + if Compare.Int.(String.length entrypoint > 31) then + error (Entrypoint_name_too_long entrypoint) + else + match root_name with + | Some (Field_annot root_name) + when Compare.String.(entrypoint = (root_name :> string)) -> + ok ((fun e -> e), Ex_ty full) + | _ -> ( + match find_entrypoint full entrypoint with + | Some result -> ok result + | None -> ( + match entrypoint with + | "default" -> ok ((fun e -> e), Ex_ty full) + | _ -> error (No_such_entrypoint entrypoint))) + +let find_entrypoint_for_type (type full exp) ~legacy ~merge_type_error_flag + ~(full : full ty) ~(expected : exp ty) ~root_name entrypoint loc : + (string * exp ty, error trace) Gas_monad.t = + let open Gas_monad in + match find_entrypoint full ~root_name entrypoint with + | Error _ as err -> of_result err + | Ok (_, Ex_ty ty) -> ( + merge_types ~legacy ~merge_type_error_flag loc ty expected + >??$ fun eq_ty -> + match (entrypoint, root_name) with + | ("default", Some (Field_annot fa)) + when Compare.String.((fa :> string) = "root") -> ( + match eq_ty with + | Ok (Eq, ty) -> return ("default", (ty : exp ty)) + | Error _ -> + merge_types ~legacy ~merge_type_error_flag loc full expected + >?$ fun (Eq, full) -> ok ("root", (full : exp ty))) + | _ -> of_result (eq_ty >|? fun (Eq, ty) -> (entrypoint, (ty : exp ty)))) + +module Entrypoints = Set.Make (String) + +let well_formed_entrypoints (type full) (full : full ty) ~root_name = + let merge path annot (type t) (ty : t ty) reachable + ((first_unreachable, all) as acc) = + match annot with + | None -> + ok + (if reachable then acc + else + match ty with + | Union_t _ -> acc + | _ -> ( + match first_unreachable with + | None -> (Some (List.rev path), all) + | Some _ -> acc)) + | Some (Field_annot name) -> + let name = (name :> string) in + if Compare.Int.(String.length name > 31) then + error (Entrypoint_name_too_long name) + else if Entrypoints.mem name all then error (Duplicate_entrypoint name) + else ok (first_unreachable, Entrypoints.add name all) + in + let rec check : + type t. + t ty -> + prim list -> + bool -> + prim list option * Entrypoints.t -> + (prim list option * Entrypoints.t) tzresult = + fun t path reachable acc -> + match t with + | Union_t ((tl, al), (tr, ar), _) -> + merge (D_Left :: path) al tl reachable acc >>? fun acc -> + merge (D_Right :: path) ar tr reachable acc >>? fun acc -> + check + tl + (D_Left :: path) + (match al with Some _ -> true | None -> reachable) + acc + >>? fun acc -> + check + tr + (D_Right :: path) + (match ar with Some _ -> true | None -> reachable) + acc + | _ -> ok acc + in + let (init, reachable) = + match root_name with + | None -> (Entrypoints.empty, false) + | Some (Field_annot name) -> (Entrypoints.singleton (name :> string), true) + in + check full [] reachable (None, init) >>? fun (first_unreachable, all) -> + if not (Entrypoints.mem "default" all) then Result.return_unit + else + match first_unreachable with + | None -> Result.return_unit + | Some path -> error (Unreachable_entrypoint path) + +let parse_uint ~nb_bits = + assert (Compare.Int.(nb_bits >= 0 && nb_bits <= 30)) ; + let max_int = (1 lsl nb_bits) - 1 in + let max_z = Z.of_int max_int in + function + | Micheline.Int (_, n) when Compare.Z.(Z.zero <= n) && Compare.Z.(n <= max_z) + -> + ok (Z.to_int n) + | node -> + error + @@ Invalid_syntactic_constant + ( location node, + strip_locations node, + "a positive " ^ string_of_int nb_bits + ^ "-bit integer (between 0 and " ^ string_of_int max_int ^ ")" ) + +let parse_uint10 = parse_uint ~nb_bits:10 + +let parse_uint11 = parse_uint ~nb_bits:11 + +(* This type is used to: + - serialize and deserialize tickets when they are stored or transferred, + - type the READ_TICKET instruction. *) +let opened_ticket_type loc ty = + pair_3_key + loc + (address_key ~annot:None, None) + (ty, None) + (nat_key ~annot:None, None) + +(* -- parse data of primitive types -- *) + +let parse_unit ctxt ~legacy = function + | Prim (loc, D_Unit, [], annot) -> + (if legacy then Result.return_unit else error_unexpected_annot loc annot) + >>? fun () -> + Gas.consume ctxt Typecheck_costs.unit >|? fun ctxt -> ((), ctxt) + | Prim (loc, D_Unit, l, _) -> + error @@ Invalid_arity (loc, D_Unit, 0, List.length l) + | expr -> error @@ unexpected expr [] Constant_namespace [D_Unit] + +let parse_bool ctxt ~legacy = function + | Prim (loc, D_True, [], annot) -> + (if legacy then Result.return_unit else error_unexpected_annot loc annot) + >>? fun () -> + Gas.consume ctxt Typecheck_costs.bool >|? fun ctxt -> (true, ctxt) + | Prim (loc, D_False, [], annot) -> + (if legacy then Result.return_unit else error_unexpected_annot loc annot) + >>? fun () -> + Gas.consume ctxt Typecheck_costs.bool >|? fun ctxt -> (false, ctxt) + | Prim (loc, ((D_True | D_False) as c), l, _) -> + error @@ Invalid_arity (loc, c, 0, List.length l) + | expr -> error @@ unexpected expr [] Constant_namespace [D_True; D_False] + +let parse_string ctxt : Script.node -> (Script_string.t * context) tzresult = + function + | String (loc, v) as expr -> + Gas.consume ctxt (Typecheck_costs.check_printable v) >>? fun ctxt -> + record_trace + (Invalid_syntactic_constant + (loc, strip_locations expr, "a printable ascii string")) + (Script_string.of_string v >|? fun s -> (s, ctxt)) + | expr -> error @@ Invalid_kind (location expr, [String_kind], kind expr) + +let parse_bytes ctxt = function + | Bytes (_, v) -> ok (v, ctxt) + | expr -> error @@ Invalid_kind (location expr, [Bytes_kind], kind expr) + +let parse_int ctxt = function + | Int (_, v) -> ok (Script_int.of_zint v, ctxt) + | expr -> error @@ Invalid_kind (location expr, [Int_kind], kind expr) + +let parse_nat ctxt : + Script.node -> (Script_int.n Script_int.num * context) tzresult = function + | Int (loc, v) as expr -> ( + let v = Script_int.of_zint v in + match Script_int.is_nat v with + | Some nat -> ok (nat, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a non-negative integer")) + | expr -> error @@ Invalid_kind (location expr, [Int_kind], kind expr) + +let parse_mutez ctxt : Script.node -> (Tez.t * context) tzresult = function + | Int (loc, v) as expr -> ( + match + let open Option in + bind (catch (fun () -> Z.to_int64 v)) Tez.of_mutez + with + | Some tez -> Ok (tez, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid mutez amount")) + | expr -> error @@ Invalid_kind (location expr, [Int_kind], kind expr) + +let parse_timestamp ctxt : + Script.node -> (Script_timestamp.t * context) tzresult = function + | Int (_, v) (* As unparsed with [Optimized] or out of bounds [Readable]. *) + -> + ok (Script_timestamp.of_zint v, ctxt) + | String (loc, s) as expr (* As unparsed with [Readable]. *) -> ( + Gas.consume ctxt Typecheck_costs.timestamp_readable >>? fun ctxt -> + match Script_timestamp.of_string s with + | Some v -> ok (v, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid timestamp")) + | expr -> + error @@ Invalid_kind (location expr, [String_kind; Int_kind], kind expr) + +let parse_key ctxt : Script.node -> (public_key * context) tzresult = function + | Bytes (loc, bytes) as expr -> ( + (* As unparsed with [Optimized]. *) + Gas.consume ctxt Typecheck_costs.public_key_optimized + >>? fun ctxt -> + match + Data_encoding.Binary.of_bytes_opt Signature.Public_key.encoding bytes + with + | Some k -> ok (k, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid public key")) + | String (loc, s) as expr -> ( + (* As unparsed with [Readable]. *) + Gas.consume ctxt Typecheck_costs.public_key_readable + >>? fun ctxt -> + match Signature.Public_key.of_b58check_opt s with + | Some k -> ok (k, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid public key")) + | expr -> + error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) + +let parse_key_hash ctxt : Script.node -> (public_key_hash * context) tzresult = + function + | Bytes (loc, bytes) as expr -> ( + (* As unparsed with [Optimized]. *) + Gas.consume ctxt Typecheck_costs.key_hash_optimized + >>? fun ctxt -> + match + Data_encoding.Binary.of_bytes_opt + Signature.Public_key_hash.encoding + bytes + with + | Some k -> ok (k, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid key hash")) + | String (loc, s) as expr (* As unparsed with [Readable]. *) -> ( + Gas.consume ctxt Typecheck_costs.key_hash_readable >>? fun ctxt -> + match Signature.Public_key_hash.of_b58check_opt s with + | Some k -> ok (k, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid key hash")) + | expr -> + error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) + +let parse_signature ctxt : Script.node -> (signature * context) tzresult = + function + | Bytes (loc, bytes) as expr (* As unparsed with [Optimized]. *) -> ( + Gas.consume ctxt Typecheck_costs.signature_optimized >>? fun ctxt -> + match Data_encoding.Binary.of_bytes_opt Signature.encoding bytes with + | Some k -> ok (k, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid signature")) + | String (loc, s) as expr (* As unparsed with [Readable]. *) -> ( + Gas.consume ctxt Typecheck_costs.signature_readable >>? fun ctxt -> + match Signature.of_b58check_opt s with + | Some s -> ok (s, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid signature")) + | expr -> + error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) + +let parse_chain_id ctxt : Script.node -> (Chain_id.t * context) tzresult = + function + | Bytes (loc, bytes) as expr -> ( + Gas.consume ctxt Typecheck_costs.chain_id_optimized >>? fun ctxt -> + match Data_encoding.Binary.of_bytes_opt Chain_id.encoding bytes with + | Some k -> ok (k, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid chain id")) + | String (loc, s) as expr -> ( + Gas.consume ctxt Typecheck_costs.chain_id_readable >>? fun ctxt -> + match Chain_id.of_b58check_opt s with + | Some s -> ok (s, ctxt) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid chain id")) + | expr -> + error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) + +let parse_address ctxt : Script.node -> (address * context) tzresult = function + | Bytes (loc, bytes) as expr (* As unparsed with [Optimized]. *) -> ( + Gas.consume ctxt Typecheck_costs.contract >>? fun ctxt -> + match + Data_encoding.Binary.of_bytes_opt + Data_encoding.(tup2 Contract.encoding Variable.string) + bytes + with + | Some (c, entrypoint) -> ( + if Compare.Int.(String.length entrypoint > 31) then + error (Entrypoint_name_too_long entrypoint) + else + match entrypoint with + | "" -> ok ((c, "default"), ctxt) + | "default" -> error (Unexpected_annotation loc) + | name -> ok ((c, name), ctxt)) + | None -> + error + @@ Invalid_syntactic_constant + (loc, strip_locations expr, "a valid address")) + | String (loc, s) (* As unparsed with [Readable]. *) -> + Gas.consume ctxt Typecheck_costs.contract >>? fun ctxt -> + (match String.index_opt s '%' with + | None -> ok (s, "default") + | Some pos -> ( + let len = String.length s - pos - 1 in + let name = String.sub s (pos + 1) len in + if Compare.Int.(len > 31) then error (Entrypoint_name_too_long name) + else + match (String.sub s 0 pos, name) with + | (addr, "") -> ok (addr, "default") + | (_, "default") -> error @@ Unexpected_annotation loc + | addr_and_name -> ok addr_and_name)) + >>? fun (addr, entrypoint) -> + Contract.of_b58check addr >|? fun c -> ((c, entrypoint), ctxt) + | expr -> + error @@ Invalid_kind (location expr, [String_kind; Bytes_kind], kind expr) + +let parse_never expr : (never * context) tzresult = + error @@ Invalid_never_expr (location expr) + +(* -- parse data of complex types -- *) + +let parse_pair (type r) parse_l parse_r ctxt ~legacy + (r_comb_witness : (r, unit -> _) comb_witness) expr = + let parse_comb loc l rs = + parse_l ctxt l >>=? fun (l, ctxt) -> + (match (rs, r_comb_witness) with + | ([r], _) -> ok r + | ([], _) -> error @@ Invalid_arity (loc, D_Pair, 2, 1) + | (_ :: _, Comb_Pair _) -> + (* Unfold [Pair x1 ... xn] as [Pair x1 (Pair x2 ... xn-1 xn))] + for type [pair ta (pair tb1 tb2)] and n >= 3 only *) + ok (Prim (loc, D_Pair, rs, [])) + | _ -> error @@ Invalid_arity (loc, D_Pair, 2, 1 + List.length rs)) + >>?= fun r -> + parse_r ctxt r >|=? fun (r, ctxt) -> ((l, r), ctxt) + in + match expr with + | Prim (loc, D_Pair, l :: rs, annot) -> + (if legacy then Result.return_unit else error_unexpected_annot loc annot) + >>?= fun () -> parse_comb loc l rs + | Prim (loc, D_Pair, l, _) -> + fail @@ Invalid_arity (loc, D_Pair, 2, List.length l) + (* Unfold [{x1; ...; xn}] as [Pair x1 x2 ... xn-1 xn] for n >= 2 *) + | Seq (loc, l :: (_ :: _ as rs)) -> parse_comb loc l rs + | Seq (loc, l) -> fail @@ Invalid_seq_arity (loc, 2, List.length l) + | expr -> fail @@ unexpected expr [] Constant_namespace [D_Pair] + +let parse_union parse_l parse_r ctxt ~legacy = function + | Prim (loc, D_Left, [v], annot) -> + (if legacy then Result.return_unit else error_unexpected_annot loc annot) + >>?= fun () -> + parse_l ctxt v >|=? fun (v, ctxt) -> (L v, ctxt) + | Prim (loc, D_Left, l, _) -> + fail @@ Invalid_arity (loc, D_Left, 1, List.length l) + | Prim (loc, D_Right, [v], annot) -> + (if legacy then Result.return_unit else error_unexpected_annot loc annot) + >>?= fun () -> + parse_r ctxt v >|=? fun (v, ctxt) -> (R v, ctxt) + | Prim (loc, D_Right, l, _) -> + fail @@ Invalid_arity (loc, D_Right, 1, List.length l) + | expr -> fail @@ unexpected expr [] Constant_namespace [D_Left; D_Right] + +let parse_option parse_v ctxt ~legacy = function + | Prim (loc, D_Some, [v], annot) -> + (if legacy then Result.return_unit else error_unexpected_annot loc annot) + >>?= fun () -> + parse_v ctxt v >|=? fun (v, ctxt) -> (Some v, ctxt) + | Prim (loc, D_Some, l, _) -> + fail @@ Invalid_arity (loc, D_Some, 1, List.length l) + | Prim (loc, D_None, [], annot) -> + Lwt.return + ( (if legacy then Result.return_unit + else error_unexpected_annot loc annot) + >|? fun () -> (None, ctxt) ) + | Prim (loc, D_None, l, _) -> + fail @@ Invalid_arity (loc, D_None, 0, List.length l) + | expr -> fail @@ unexpected expr [] Constant_namespace [D_Some; D_None] + +(* -- parse data of comparable types -- *) + +let comparable_comb_witness1 : + type t. t comparable_ty -> (t, unit -> unit) comb_witness = function + | Pair_key _ -> Comb_Pair Comb_Any + | _ -> Comb_Any + +let[@coq_axiom_with_reason "gadt"] rec parse_comparable_data : + type a. + ?type_logger:type_logger -> + context -> + a comparable_ty -> + Script.node -> + (a * context) tzresult Lwt.t = + fun ?type_logger ctxt ty script_data -> + (* No need for stack_depth here. Unlike [parse_data], + [parse_comparable_data] doesn't call [parse_returning]. + The stack depth is bounded by the type depth, bounded by 1024. *) + let parse_data_error () = + let ty = serialize_ty_for_error (ty_of_comparable_ty ty) in + Invalid_constant (location script_data, strip_locations script_data, ty) + in + let traced_no_lwt body = record_trace_eval parse_data_error body in + let traced body = trace_eval parse_data_error body in + Gas.consume ctxt Typecheck_costs.parse_data_cycle + (* We could have a smaller cost but let's keep it consistent with + [parse_data] for now. *) + >>?= + fun ctxt -> + let legacy = false in + match (ty, script_data) with + | (Unit_key _, expr) -> + Lwt.return @@ traced_no_lwt + @@ (parse_unit ctxt ~legacy expr : (a * context) tzresult) + | (Bool_key _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_bool ctxt ~legacy expr + | (String_key _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_string ctxt expr + | (Bytes_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_bytes ctxt expr + | (Int_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_int ctxt expr + | (Nat_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_nat ctxt expr + | (Mutez_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_mutez ctxt expr + | (Timestamp_key _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_timestamp ctxt expr + | (Key_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_key ctxt expr + | (Key_hash_key _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_key_hash ctxt expr + | (Signature_key _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_signature ctxt expr + | (Chain_id_key _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_chain_id ctxt expr + | (Address_key _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_address ctxt expr + | (Pair_key ((tl, _), (tr, _), _), expr) -> + let r_witness = comparable_comb_witness1 tr in + let parse_l ctxt v = parse_comparable_data ?type_logger ctxt tl v in + let parse_r ctxt v = parse_comparable_data ?type_logger ctxt tr v in + traced @@ parse_pair parse_l parse_r ctxt ~legacy r_witness expr + | (Union_key ((tl, _), (tr, _), _), expr) -> + let parse_l ctxt v = parse_comparable_data ?type_logger ctxt tl v in + let parse_r ctxt v = parse_comparable_data ?type_logger ctxt tr v in + traced @@ parse_union parse_l parse_r ctxt ~legacy expr + | (Option_key (t, _), expr) -> + let parse_v ctxt v = parse_comparable_data ?type_logger ctxt t v in + traced @@ parse_option parse_v ctxt ~legacy expr + | (Never_key _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_never expr + +(* -- parse data of any type -- *) + +let comb_witness1 : type t. t ty -> (t, unit -> unit) comb_witness = function + | Pair_t _ -> Comb_Pair Comb_Any + | _ -> Comb_Any + +(* + Some values, such as operations, tickets, or big map ids, are used only + internally and are not allowed to be forged by users. + In [parse_data], [allow_forged] should be [false] for: + - PUSH + - UNPACK + - user-provided script parameters + - storage on origination + And [true] for: + - internal calls parameters + - storage after origination +*) + +let[@coq_axiom_with_reason "gadt"] rec parse_data : + type a. + ?type_logger:type_logger -> + stack_depth:int -> + context -> + legacy:bool -> + allow_forged:bool -> + a ty -> + Script.node -> + (a * context) tzresult Lwt.t = + fun ?type_logger ~stack_depth ctxt ~legacy ~allow_forged ty script_data -> + Gas.consume ctxt Typecheck_costs.parse_data_cycle >>?= fun ctxt -> + let non_terminal_recursion ?type_logger ctxt ~legacy ty script_data = + if Compare.Int.(stack_depth > 10_000) then + fail Typechecking_too_many_recursive_calls + else + parse_data + ?type_logger + ~stack_depth:(stack_depth + 1) + ctxt + ~legacy + ~allow_forged + ty + script_data + in + let parse_data_error () = + let ty = serialize_ty_for_error ty in + Invalid_constant (location script_data, strip_locations script_data, ty) + in + let fail_parse_data () = fail (parse_data_error ()) in + let traced_no_lwt body = record_trace_eval parse_data_error body in + let traced body = trace_eval parse_data_error body in + let traced_fail err = Lwt.return @@ traced_no_lwt (error err) in + let parse_items ?type_logger ctxt expr key_type value_type items item_wrapper + = + List.fold_left_es + (fun (last_value, map, ctxt) item -> + match item with + | Prim (loc, D_Elt, [k; v], annot) -> + (if legacy then Result.return_unit + else error_unexpected_annot loc annot) + >>?= fun () -> + parse_comparable_data ?type_logger ctxt key_type k + >>=? fun (k, ctxt) -> + non_terminal_recursion ?type_logger ctxt ~legacy value_type v + >>=? fun (v, ctxt) -> + Lwt.return + ( (match last_value with + | Some value -> + Gas.consume + ctxt + (Michelson_v1_gas.Cost_of.Interpreter.compare + key_type + value + k) + >>? fun ctxt -> + let c = + Script_comparable.compare_comparable key_type value k + in + if Compare.Int.(0 <= c) then + if Compare.Int.(0 = c) then + error (Duplicate_map_keys (loc, strip_locations expr)) + else + error (Unordered_map_keys (loc, strip_locations expr)) + else ok ctxt + | None -> ok ctxt) + >>? fun ctxt -> + Gas.consume + ctxt + (Michelson_v1_gas.Cost_of.Interpreter.map_update k map) + >|? fun ctxt -> + (Some k, Script_map.update k (Some (item_wrapper v)) map, ctxt) + ) + | Prim (loc, D_Elt, l, _) -> + fail @@ Invalid_arity (loc, D_Elt, 2, List.length l) + | Prim (loc, name, _, _) -> + fail @@ Invalid_primitive (loc, [D_Elt], name) + | Int _ | String _ | Bytes _ | Seq _ -> fail_parse_data ()) + (None, Script_map.empty key_type, ctxt) + items + |> traced + >|=? fun (_, items, ctxt) -> (items, ctxt) + in + let parse_big_map_items (type t) ?type_logger ctxt expr + (key_type : t comparable_ty) value_type items item_wrapper = + List.fold_left_es + (fun (last_key, {map; size}, ctxt) item -> + match item with + | Prim (loc, D_Elt, [k; v], annot) -> + (if legacy then Result.return_unit + else error_unexpected_annot loc annot) + >>?= fun () -> + parse_comparable_data ?type_logger ctxt key_type k + >>=? fun (k, ctxt) -> + hash_comparable_data ctxt key_type k >>=? fun (key_hash, ctxt) -> + non_terminal_recursion ?type_logger ctxt ~legacy value_type v + >>=? fun (v, ctxt) -> + Lwt.return + ( (match last_key with + | Some last_key -> + Gas.consume + ctxt + (Michelson_v1_gas.Cost_of.Interpreter.compare + key_type + last_key + k) + >>? fun ctxt -> + let c = + Script_comparable.compare_comparable key_type last_key k + in + if Compare.Int.(0 <= c) then + if Compare.Int.(0 = c) then + error (Duplicate_map_keys (loc, strip_locations expr)) + else + error (Unordered_map_keys (loc, strip_locations expr)) + else ok ctxt + | None -> ok ctxt) + >>? fun ctxt -> + Gas.consume + ctxt + (Michelson_v1_gas.Cost_of.Interpreter.big_map_update + {map; size}) + >>? fun ctxt -> + if Big_map_overlay.mem key_hash map then + error (Duplicate_map_keys (loc, strip_locations expr)) + else + ok + ( Some k, + { + map = + Big_map_overlay.add key_hash (k, item_wrapper v) map; + size = size + 1; + }, + ctxt ) ) + | Prim (loc, D_Elt, l, _) -> + fail @@ Invalid_arity (loc, D_Elt, 2, List.length l) + | Prim (loc, name, _, _) -> + fail @@ Invalid_primitive (loc, [D_Elt], name) + | Int _ | String _ | Bytes _ | Seq _ -> fail_parse_data ()) + (None, {map = Big_map_overlay.empty; size = 0}, ctxt) + items + |> traced + >|=? fun (_, map, ctxt) -> (map, ctxt) + in + match (ty, script_data) with + | (Unit_t _, expr) -> + Lwt.return @@ traced_no_lwt + @@ (parse_unit ctxt ~legacy expr : (a * context) tzresult) + | (Bool_t _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_bool ctxt ~legacy expr + | (String_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_string ctxt expr + | (Bytes_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_bytes ctxt expr + | (Int_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_int ctxt expr + | (Nat_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_nat ctxt expr + | (Mutez_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_mutez ctxt expr + | (Timestamp_t _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_timestamp ctxt expr + | (Key_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_key ctxt expr + | (Key_hash_t _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_key_hash ctxt expr + | (Signature_t _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_signature ctxt expr + | (Operation_t _, _) -> + (* operations cannot appear in parameters or storage, + the protocol should never parse the bytes of an operation *) + assert false + | (Chain_id_t _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_chain_id ctxt expr + | (Address_t _, expr) -> + Lwt.return @@ traced_no_lwt @@ parse_address ctxt expr + | (Contract_t (ty, _), expr) -> + traced + ( parse_address ctxt expr >>?= fun ((c, entrypoint), ctxt) -> + let loc = location expr in + parse_contract + ~stack_depth:(stack_depth + 1) + ~legacy + ctxt + loc + ty + c + ~entrypoint + >|=? fun (ctxt, _) -> ((ty, (c, entrypoint)), ctxt) ) + (* Pairs *) + | (Pair_t ((tl, _, _), (tr, _, _), _), expr) -> + let r_witness = comb_witness1 tr in + let parse_l ctxt v = + non_terminal_recursion ?type_logger ctxt ~legacy tl v + in + let parse_r ctxt v = + non_terminal_recursion ?type_logger ctxt ~legacy tr v + in + traced @@ parse_pair parse_l parse_r ctxt ~legacy r_witness expr + (* Unions *) + | (Union_t ((tl, _), (tr, _), _), expr) -> + let parse_l ctxt v = + non_terminal_recursion ?type_logger ctxt ~legacy tl v + in + let parse_r ctxt v = + non_terminal_recursion ?type_logger ctxt ~legacy tr v + in + traced @@ parse_union parse_l parse_r ctxt ~legacy expr + (* Lambdas *) + | (Lambda_t (ta, tr, _ty_name), (Seq (_loc, _) as script_instr)) -> + traced + @@ parse_returning + Lambda + ?type_logger + ~stack_depth:(stack_depth + 1) + ctxt + ~legacy + (ta, lambda_arg_annot) + tr + script_instr + | (Lambda_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) + (* Options *) + | (Option_t (t, _), expr) -> + let parse_v ctxt v = + non_terminal_recursion ?type_logger ctxt ~legacy t v + in + traced @@ parse_option parse_v ctxt ~legacy expr + (* Lists *) + | (List_t (t, _ty_name), Seq (_loc, items)) -> + traced + @@ List.fold_right_es + (fun v (rest, ctxt) -> + non_terminal_recursion ?type_logger ctxt ~legacy t v + >|=? fun (v, ctxt) -> (Script_list.cons v rest, ctxt)) + items + (Script_list.empty, ctxt) + | (List_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) + (* Tickets *) + | (Ticket_t (t, _ty_name), expr) -> + if allow_forged then + opened_ticket_type (location expr) t >>?= fun ty -> + parse_comparable_data ?type_logger ctxt ty expr + >|=? fun (((ticketer, _entrypoint), (contents, amount)), ctxt) -> + ({ticketer; contents; amount}, ctxt) + else traced_fail (Unexpected_forged_value (location expr)) + (* Sets *) + | (Set_t (t, _ty_name), (Seq (loc, vs) as expr)) -> + traced + @@ List.fold_left_es + (fun (last_value, set, ctxt) v -> + parse_comparable_data ?type_logger ctxt t v >>=? fun (v, ctxt) -> + Lwt.return + ( (match last_value with + | Some value -> + Gas.consume + ctxt + (Michelson_v1_gas.Cost_of.Interpreter.compare t value v) + >>? fun ctxt -> + let c = Script_comparable.compare_comparable t value v in + if Compare.Int.(0 <= c) then + if Compare.Int.(0 = c) then + error + (Duplicate_set_values (loc, strip_locations expr)) + else + error + (Unordered_set_values (loc, strip_locations expr)) + else ok ctxt + | None -> ok ctxt) + >>? fun ctxt -> + Gas.consume + ctxt + (Michelson_v1_gas.Cost_of.Interpreter.set_update v set) + >|? fun ctxt -> (Some v, Script_set.update v true set, ctxt) )) + (None, Script_set.empty t, ctxt) + vs + >|=? fun (_, set, ctxt) -> (set, ctxt) + | (Set_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) + (* Maps *) + | (Map_t (tk, tv, _ty_name), (Seq (_, vs) as expr)) -> + parse_items ?type_logger ctxt expr tk tv vs (fun x -> x) + | (Map_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) + | (Big_map_t (tk, tv, _ty_name), expr) -> + (match expr with + | Int (loc, id) -> + return (Some (id, loc), {map = Big_map_overlay.empty; size = 0}, ctxt) + | Seq (_, vs) -> + parse_big_map_items ?type_logger ctxt expr tk tv vs (fun x -> Some x) + >|=? fun (diff, ctxt) -> (None, diff, ctxt) + | Prim (loc, D_Pair, [Int (loc_id, id); Seq (_, vs)], annot) -> + error_unexpected_annot loc annot >>?= fun () -> + option_t loc tv ~annot:None >>?= fun tv_opt -> + parse_big_map_items ?type_logger ctxt expr tk tv_opt vs (fun x -> x) + >|=? fun (diff, ctxt) -> (Some (id, loc_id), diff, ctxt) + | Prim (_, D_Pair, [Int _; expr], _) -> + traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) + | Prim (_, D_Pair, [expr; _], _) -> + traced_fail (Invalid_kind (location expr, [Int_kind], kind expr)) + | Prim (loc, D_Pair, l, _) -> + traced_fail @@ Invalid_arity (loc, D_Pair, 2, List.length l) + | _ -> + traced_fail + (unexpected expr [Seq_kind; Int_kind] Constant_namespace [D_Pair])) + >>=? fun (id_opt, diff, ctxt) -> + (match id_opt with + | None -> return @@ (None, ctxt) + | Some (id, loc) -> + if allow_forged then + let id = Big_map.Id.parse_z id in + Big_map.exists ctxt id >>=? function + | (_, None) -> traced_fail (Invalid_big_map (loc, id)) + | (ctxt, Some (btk, btv)) -> + Lwt.return + ( parse_comparable_ty + ~stack_depth:(stack_depth + 1) + ctxt + (Micheline.root btk) + >>? fun (Ex_comparable_ty btk, ctxt) -> + parse_big_map_value_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + (Micheline.root btv) + >>? fun (Ex_ty btv, ctxt) -> + comparable_ty_eq ctxt tk btk >>? fun (Eq, ctxt) -> + ty_eq ~legacy:true ctxt loc tv btv >>? fun (Eq, ctxt) -> + ok (Some id, ctxt) ) + else traced_fail (Unexpected_forged_value loc)) + >|=? fun (id, ctxt) -> ({id; diff; key_type = tk; value_type = tv}, ctxt) + | (Never_t _, expr) -> Lwt.return @@ traced_no_lwt @@ parse_never expr + (* Bls12_381 types *) + | (Bls12_381_g1_t _, Bytes (_, bs)) -> ( + Gas.consume ctxt Typecheck_costs.bls12_381_g1 >>?= fun ctxt -> + match Bls12_381.G1.of_bytes_opt bs with + | Some pt -> return (pt, ctxt) + | None -> fail_parse_data ()) + | (Bls12_381_g1_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) + | (Bls12_381_g2_t _, Bytes (_, bs)) -> ( + Gas.consume ctxt Typecheck_costs.bls12_381_g2 >>?= fun ctxt -> + match Bls12_381.G2.of_bytes_opt bs with + | Some pt -> return (pt, ctxt) + | None -> fail_parse_data ()) + | (Bls12_381_g2_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) + | (Bls12_381_fr_t _, Bytes (_, bs)) -> ( + Gas.consume ctxt Typecheck_costs.bls12_381_fr >>?= fun ctxt -> + match Bls12_381.Fr.of_bytes_opt bs with + | Some pt -> return (pt, ctxt) + | None -> fail_parse_data ()) + | (Bls12_381_fr_t _, Int (_, v)) -> + Gas.consume ctxt Typecheck_costs.bls12_381_fr >>?= fun ctxt -> + return (Bls12_381.Fr.of_z v, ctxt) + | (Bls12_381_fr_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) + (* + /!\ When adding new lazy storage kinds, you may want to guard the parsing + of identifiers with [allow_forged]. + *) + (* Sapling *) + | (Sapling_transaction_t (memo_size, _), Bytes (_, bytes)) -> ( + match + Data_encoding.Binary.of_bytes_opt Sapling.transaction_encoding bytes + with + | Some transaction -> ( + match Sapling.transaction_get_memo_size transaction with + | None -> return (transaction, ctxt) + | Some transac_memo_size -> + Lwt.return + ( merge_memo_sizes memo_size transac_memo_size >|? fun _ms -> + (transaction, ctxt) )) + | None -> fail_parse_data ()) + | (Sapling_transaction_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) + | (Sapling_state_t (memo_size, _), Int (loc, id)) -> + if allow_forged then + let id = Sapling.Id.parse_z id in + Sapling.state_from_id ctxt id >>=? fun (state, ctxt) -> + Lwt.return + ( traced_no_lwt @@ merge_memo_sizes memo_size state.Sapling.memo_size + >|? fun _memo_size -> (state, ctxt) ) + else traced_fail (Unexpected_forged_value loc) + | (Sapling_state_t (memo_size, _), Seq (_, [])) -> + return (Sapling.empty_state ~memo_size (), ctxt) + | (Sapling_state_t _, expr) -> + (* Do not allow to input diffs as they are untrusted and may not be the + result of a verify_update. *) + traced_fail + (Invalid_kind (location expr, [Int_kind; Seq_kind], kind expr)) + (* Time lock*) + | (Chest_key_t _, Bytes (_, bytes)) -> ( + Gas.consume ctxt Typecheck_costs.chest_key >>?= fun ctxt -> + match + Data_encoding.Binary.of_bytes_opt Timelock.chest_key_encoding bytes + with + | Some chest_key -> return (chest_key, ctxt) + | None -> fail_parse_data ()) + | (Chest_key_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) + | (Chest_t _, Bytes (_, bytes)) -> ( + Gas.consume ctxt (Typecheck_costs.chest ~bytes:(Bytes.length bytes)) + >>?= fun ctxt -> + match Data_encoding.Binary.of_bytes_opt Timelock.chest_encoding bytes with + | Some chest -> return (chest, ctxt) + | None -> fail_parse_data ()) + | (Chest_t _, expr) -> + traced_fail (Invalid_kind (location expr, [Bytes_kind], kind expr)) + +and parse_view_returning : + type storage. + ?type_logger:type_logger -> + context -> + legacy:bool -> + storage ty -> + view -> + (storage ex_view * context) tzresult Lwt.t = + fun ?type_logger ctxt ~legacy storage_type {input_ty; output_ty; view_code} -> + let input_ty_loc = location input_ty in + record_trace_eval + (fun () -> + Ill_formed_type + (Some "arg of view", strip_locations input_ty, input_ty_loc)) + (parse_view_input_ty ctxt ~stack_depth:0 ~legacy input_ty) + >>?= fun (Ex_ty input_ty', ctxt) -> + let output_ty_loc = location output_ty in + record_trace_eval + (fun () -> + Ill_formed_type + (Some "return of view", strip_locations output_ty, output_ty_loc)) + (parse_view_output_ty ctxt ~stack_depth:0 ~legacy output_ty) + >>?= fun (Ex_ty output_ty', ctxt) -> + pair_t + input_ty_loc + (input_ty', None, None) + (storage_type, None, None) + ~annot:None + >>?= fun pair_ty -> + parse_instr + ?type_logger + ~stack_depth:0 + Lambda + ctxt + ~legacy + view_code + (Item_t (pair_ty, Bot_t, None)) + >>=? fun (judgement, ctxt) -> + Lwt.return + @@ + match judgement with + | Failed {descr} -> + let cur_view' = + Ex_view + (Lam + (close_descr (descr (Item_t (output_ty', Bot_t, None))), view_code)) + in + ok (cur_view', ctxt) + | Typed ({loc; aft; _} as descr) -> ( + let ill_type_view loc stack_ty () = + let actual = serialize_stack_for_error ctxt stack_ty in + let expected_stack = Item_t (output_ty', Bot_t, None) in + let expected = serialize_stack_for_error ctxt expected_stack in + Ill_typed_view {loc; actual; expected} + in + match aft with + | Item_t (ty, Bot_t, _) -> + record_trace_eval + (ill_type_view loc aft : unit -> _) + ( ty_eq ~legacy ctxt loc ty output_ty' >|? fun (Eq, ctxt) -> + let view' = Ex_view (Lam (close_descr descr, view_code)) in + (view', ctxt) ) + | _ -> error (ill_type_view loc aft ())) + +and typecheck_views : + type storage. + ?type_logger:type_logger -> + context -> + legacy:bool -> + storage ty -> + view SMap.t -> + context tzresult Lwt.t = + fun ?type_logger ctxt ~legacy storage_type views -> + let aux _name cur_view ctxt = + parse_view_returning ?type_logger ctxt ~legacy storage_type cur_view + >|=? fun (_parsed_view, ctxt) -> ctxt + in + SMap.fold_es aux views ctxt + +and[@coq_axiom_with_reason "gadt"] parse_returning : + type arg ret. + ?type_logger:type_logger -> + stack_depth:int -> + tc_context -> + context -> + legacy:bool -> + arg ty * var_annot option -> + ret ty -> + Script.node -> + ((arg, ret) lambda * context) tzresult Lwt.t = + fun ?type_logger + ~stack_depth + tc_context + ctxt + ~legacy + (arg, arg_annot) + ret + script_instr -> + parse_instr + ?type_logger + tc_context + ctxt + ~legacy + ~stack_depth:(stack_depth + 1) + script_instr + (Item_t (arg, Bot_t, arg_annot)) + >>=? function + | (Typed ({loc; aft = Item_t (ty, Bot_t, _) as stack_ty; _} as descr), ctxt) + -> + Lwt.return + @@ record_trace_eval + (fun () -> + let ret = serialize_ty_for_error ret in + let stack_ty = serialize_stack_for_error ctxt stack_ty in + Bad_return (loc, stack_ty, ret)) + ( ty_eq ~legacy ctxt loc ty ret >|? fun (Eq, ctxt) -> + ((Lam (close_descr descr, script_instr) : (arg, ret) lambda), ctxt) + ) + | (Typed {loc; aft = stack_ty; _}, ctxt) -> + let ret = serialize_ty_for_error ret in + let stack_ty = serialize_stack_for_error ctxt stack_ty in + fail @@ Bad_return (loc, stack_ty, ret) + | (Failed {descr}, ctxt) -> + return + ( (Lam (close_descr (descr (Item_t (ret, Bot_t, None))), script_instr) + : (arg, ret) lambda), + ctxt ) + +and[@coq_axiom_with_reason "gadt"] parse_instr : + type a s. + ?type_logger:type_logger -> + stack_depth:int -> + tc_context -> + context -> + legacy:bool -> + Script.node -> + (a, s) stack_ty -> + ((a, s) judgement * context) tzresult Lwt.t = + fun ?type_logger ~stack_depth tc_context ctxt ~legacy script_instr stack_ty -> + let check_item_ty (type a b) ctxt (exp : a ty) (got : b ty) loc name n m : + ((a, b) eq * a ty * context) tzresult = + record_trace_eval (fun () -> + let stack_ty = serialize_stack_for_error ctxt stack_ty in + Bad_stack (loc, name, m, stack_ty)) + @@ record_trace + (Bad_stack_item n) + ( Gas_monad.run ctxt + @@ merge_types + ~legacy + ~merge_type_error_flag:Default_merge_type_error + loc + exp + got + >>? fun (eq_ty, ctxt) -> + eq_ty >|? fun (Eq, ty) -> ((Eq : (a, b) eq), (ty : a ty), ctxt) ) + in + let log_stack loc stack_ty aft = + match (type_logger, script_instr) with + | (None, _) | (Some _, (Int _ | String _ | Bytes _)) -> () + | (Some log, (Prim _ | Seq _)) -> + (* Unparsing for logging is not carbonated as this + is used only by the client and not the protocol *) + let stack_ty = unparse_stack_uncarbonated stack_ty in + let aft = unparse_stack_uncarbonated aft in + log loc stack_ty aft + in + let typed_no_lwt ctxt loc instr aft = + log_stack loc stack_ty aft ; + let j = Typed {loc; instr; bef = stack_ty; aft} in + Ok (j, ctxt) + in + let typed ctxt loc instr aft = + Lwt.return @@ typed_no_lwt ctxt loc instr aft + in + Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>?= fun ctxt -> + let non_terminal_recursion ?type_logger tc_context ctxt ~legacy script_instr + stack_ty = + if Compare.Int.(stack_depth > 10000) then + fail Typechecking_too_many_recursive_calls + else + parse_instr + ?type_logger + tc_context + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + script_instr + stack_ty + in + match (script_instr, stack_ty) with + (* stack ops *) + | (Prim (loc, I_DROP, [], annot), Item_t (_, rest, _)) -> + (error_unexpected_annot loc annot >>?= fun () -> + typed ctxt loc {apply = (fun kinfo k -> IDrop (kinfo, k))} rest + : ((a, s) judgement * context) tzresult Lwt.t) + | (Prim (loc, I_DROP, [n], result_annot), whole_stack) -> + parse_uint10 n >>?= fun whole_n -> + Gas.consume ctxt (Typecheck_costs.proof_argument whole_n) >>?= fun ctxt -> + let rec make_proof_argument : + type a s. + int -> (a, s) stack_ty -> (a, s) dropn_proof_argument tzresult = + fun n stk -> + match (Compare.Int.(n = 0), stk) with + | (true, rest) -> ok @@ Dropn_proof_argument (KRest, rest) + | (false, Item_t (_, rest, _)) -> + make_proof_argument (n - 1) rest + >|? fun (Dropn_proof_argument (n', stack_after_drops)) -> + let kinfo = {iloc = loc; kstack_ty = rest} in + Dropn_proof_argument (KPrefix (kinfo, n'), stack_after_drops) + | (_, _) -> + let whole_stack = serialize_stack_for_error ctxt whole_stack in + error (Bad_stack (loc, I_DROP, whole_n, whole_stack)) + in + error_unexpected_annot loc result_annot >>?= fun () -> + make_proof_argument whole_n whole_stack + >>?= fun (Dropn_proof_argument (n', stack_after_drops)) -> + let kdropn kinfo k = IDropn (kinfo, whole_n, n', k) in + typed ctxt loc {apply = kdropn} stack_after_drops + | (Prim (loc, I_DROP, (_ :: _ :: _ as l), _), _) -> + (* Technically, the arities 0 and 1 are allowed but the error only mentions 1. + However, DROP is equivalent to DROP 1 so hinting at an arity of 1 makes sense. *) + fail (Invalid_arity (loc, I_DROP, 1, List.length l)) + | (Prim (loc, I_DUP, [], annot), Item_t (v, rest, stack_annot)) -> + parse_var_annot loc annot ~default:stack_annot >>?= fun annot -> + record_trace_eval + (fun () -> + let t = serialize_ty_for_error v in + Non_dupable_type (loc, t)) + (check_dupable_ty ctxt loc v) + >>?= fun ctxt -> + let dup = {apply = (fun kinfo k -> IDup (kinfo, k))} in + typed ctxt loc dup (Item_t (v, Item_t (v, rest, stack_annot), annot)) + | (Prim (loc, I_DUP, [n], v_annot), stack_ty) -> + parse_var_annot loc v_annot >>?= fun annot -> + let rec make_proof_argument : + type a s. + int -> (a, s) stack_ty -> (a * s) dup_n_proof_argument tzresult = + fun n (stack_ty : (a, s) stack_ty) -> + match (n, stack_ty) with + | (1, Item_t (hd_ty, _, _)) -> + ok @@ Dup_n_proof_argument (Dup_n_zero, hd_ty) + | (n, Item_t (_, tl_ty, _)) -> + make_proof_argument (n - 1) tl_ty + >|? fun (Dup_n_proof_argument (dup_n_witness, b_ty)) -> + Dup_n_proof_argument (Dup_n_succ dup_n_witness, b_ty) + | _ -> + let whole_stack = serialize_stack_for_error ctxt stack_ty in + error (Bad_stack (loc, I_DUP, 1, whole_stack)) + in + parse_uint10 n >>?= fun n -> + Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> + error_unless (Compare.Int.( > ) n 0) (Dup_n_bad_argument loc) + >>?= fun () -> + record_trace (Dup_n_bad_stack loc) (make_proof_argument n stack_ty) + >>?= fun (Dup_n_proof_argument (witness, after_ty)) -> + record_trace_eval + (fun () -> + let t = serialize_ty_for_error after_ty in + Non_dupable_type (loc, t)) + (check_dupable_ty ctxt loc after_ty) + >>?= fun ctxt -> + let dupn = {apply = (fun kinfo k -> IDup_n (kinfo, n, witness, k))} in + typed ctxt loc dupn (Item_t (after_ty, stack_ty, annot)) + | (Prim (loc, I_DIG, [n], result_annot), stack) -> + let rec make_proof_argument : + type a s. int -> (a, s) stack_ty -> (a, s) dig_proof_argument tzresult + = + fun n stk -> + match (Compare.Int.(n = 0), stk) with + | (true, Item_t (v, rest, annot)) -> + ok @@ Dig_proof_argument (KRest, v, annot, rest) + | (false, Item_t (v, rest, annot)) -> + make_proof_argument (n - 1) rest + >|? fun (Dig_proof_argument (n', x, xv, aft')) -> + let kinfo = {iloc = loc; kstack_ty = aft'} in + Dig_proof_argument + (KPrefix (kinfo, n'), x, xv, Item_t (v, aft', annot)) + | (_, _) -> + let whole_stack = serialize_stack_for_error ctxt stack in + error (Bad_stack (loc, I_DIG, 3, whole_stack)) + in + parse_uint10 n >>?= fun n -> + Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> + error_unexpected_annot loc result_annot >>?= fun () -> + make_proof_argument n stack + >>?= fun (Dig_proof_argument (n', x, stack_annot, aft)) -> + let dig = {apply = (fun kinfo k -> IDig (kinfo, n, n', k))} in + typed ctxt loc dig (Item_t (x, aft, stack_annot)) + | (Prim (loc, I_DIG, (([] | _ :: _ :: _) as l), _), _) -> + fail (Invalid_arity (loc, I_DIG, 1, List.length l)) + | (Prim (loc, I_DUG, [n], result_annot), Item_t (x, whole_stack, stack_annot)) + -> + parse_uint10 n >>?= fun whole_n -> + Gas.consume ctxt (Typecheck_costs.proof_argument whole_n) >>?= fun ctxt -> + let rec make_proof_argument : + type a s x. + int -> + x ty -> + var_annot option -> + (a, s) stack_ty -> + (a, s, x) dug_proof_argument tzresult = + fun n x stack_annot stk -> + match (Compare.Int.(n = 0), stk) with + | (true, rest) -> + ok @@ Dug_proof_argument (KRest, Item_t (x, rest, stack_annot)) + | (false, Item_t (v, rest, annot)) -> + make_proof_argument (n - 1) x stack_annot rest + >|? fun (Dug_proof_argument (n', aft')) -> + let kinfo = {iloc = loc; kstack_ty = aft'} in + Dug_proof_argument (KPrefix (kinfo, n'), Item_t (v, aft', annot)) + | (_, _) -> + let whole_stack = serialize_stack_for_error ctxt whole_stack in + error (Bad_stack (loc, I_DUG, whole_n, whole_stack)) + in + error_unexpected_annot loc result_annot >>?= fun () -> + make_proof_argument whole_n x stack_annot whole_stack + >>?= fun (Dug_proof_argument (n', aft)) -> + let dug = {apply = (fun kinfo k -> IDug (kinfo, whole_n, n', k))} in + typed ctxt loc dug aft + | (Prim (loc, I_DUG, [_], result_annot), stack) -> + Lwt.return + ( error_unexpected_annot loc result_annot >>? fun () -> + let stack = serialize_stack_for_error ctxt stack in + error (Bad_stack (loc, I_DUG, 1, stack)) ) + | (Prim (loc, I_DUG, (([] | _ :: _ :: _) as l), _), _) -> + fail (Invalid_arity (loc, I_DUG, 1, List.length l)) + | ( Prim (loc, I_SWAP, [], annot), + Item_t (v, Item_t (w, rest, stack_annot), cur_top_annot) ) -> + error_unexpected_annot loc annot >>?= fun () -> + let swap = {apply = (fun kinfo k -> ISwap (kinfo, k))} in + let stack_ty = Item_t (w, Item_t (v, rest, cur_top_annot), stack_annot) in + typed ctxt loc swap stack_ty + | (Prim (loc, I_PUSH, [t; d], annot), stack) -> + parse_var_annot loc annot >>?= fun annot -> + parse_packable_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy t + >>?= fun (Ex_ty t, ctxt) -> + parse_data + ?type_logger + ~stack_depth:(stack_depth + 1) + ctxt + ~legacy + ~allow_forged:false + t + d + >>=? fun (v, ctxt) -> + let const = {apply = (fun kinfo k -> IConst (kinfo, v, k))} in + typed ctxt loc const (Item_t (t, stack, annot)) + | (Prim (loc, I_UNIT, [], annot), stack) -> + parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> + let const = {apply = (fun kinfo k -> IConst (kinfo, (), k))} in + typed ctxt loc const (Item_t (unit_t ~annot:ty_name, stack, annot)) + (* options *) + | (Prim (loc, I_SOME, [], annot), Item_t (t, rest, _)) -> + parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> + let cons_some = {apply = (fun kinfo k -> ICons_some (kinfo, k))} in + option_t loc t ~annot:ty_name >>?= fun ty -> + typed ctxt loc cons_some (Item_t (ty, rest, annot)) + | (Prim (loc, I_NONE, [t], annot), stack) -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy t + >>?= fun (Ex_ty t, ctxt) -> + parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> + let cons_none = {apply = (fun kinfo k -> ICons_none (kinfo, k))} in + option_t loc t ~annot:ty_name >>?= fun ty -> + let stack_ty = Item_t (ty, stack, annot) in + typed ctxt loc cons_none stack_ty + | (Prim (loc, I_MAP, [body], annot), Item_t (Option_t (t, _), rest, opt_annot)) + -> ( + check_kind [Seq_kind] body >>?= fun () -> + parse_var_type_annot loc annot >>?= fun (ret_annot, opt_ty_name) -> + let elt_annot = gen_access_annot opt_annot default_some_annot in + non_terminal_recursion + ?type_logger + ~legacy + tc_context + ctxt + body + (Item_t (t, rest, elt_annot)) + >>=? fun (judgement, ctxt) -> + Lwt.return + @@ + match judgement with + | Typed ({loc; aft = Item_t (ret, aft_rest, _aft_annot); _} as kibody) -> + let invalid_map_body () = + let aft = serialize_stack_for_error ctxt kibody.aft in + Invalid_map_body (loc, aft) + in + record_trace_eval + invalid_map_body + ( merge_stacks ~legacy loc ctxt 1 aft_rest rest + >>? fun (Eq, rest, ctxt) -> + option_t loc ret ~annot:opt_ty_name >>? fun opt_ty -> + let final_stack = Item_t (opt_ty, rest, ret_annot) in + let hinfo = + {iloc = loc; kstack_ty = Item_t (ret, aft_rest, ret_annot)} + in + let cinfo = kinfo_of_descr kibody in + let body = kibody.instr.apply cinfo (IHalt hinfo) in + let apply kinfo k = IOpt_map {kinfo; body; k} in + typed_no_lwt ctxt loc {apply} final_stack ) + | Typed {aft = Bot_t; _} -> + let aft = serialize_stack_for_error ctxt Bot_t in + error (Invalid_map_body (loc, aft)) + | Failed _ -> error (Invalid_map_block_fail loc)) + | ( Prim (loc, I_IF_NONE, [bt; bf], annot), + (Item_t (Option_t (t, _), rest, option_annot) as bef) ) -> + check_kind [Seq_kind] bt >>?= fun () -> + check_kind [Seq_kind] bf >>?= fun () -> + error_unexpected_annot loc annot >>?= fun () -> + let annot = gen_access_annot option_annot default_some_annot in + non_terminal_recursion ?type_logger tc_context ctxt ~legacy bt rest + >>=? fun (btr, ctxt) -> + let stack_ty = Item_t (t, rest, annot) in + non_terminal_recursion ?type_logger tc_context ctxt ~legacy bf stack_ty + >>=? fun (bfr, ctxt) -> + let branch ibt ibf = + let ifnone = + { + apply = + (fun kinfo k -> + let hinfo = kinfo_of_kinstr k in + let btinfo = kinfo_of_descr ibt + and bfinfo = kinfo_of_descr ibf in + let branch_if_none = ibt.instr.apply btinfo (IHalt hinfo) + and branch_if_some = ibf.instr.apply bfinfo (IHalt hinfo) in + IIf_none {kinfo; branch_if_none; branch_if_some; k}); + } + in + {loc; instr = ifnone; bef; aft = ibt.aft} + in + Lwt.return @@ merge_branches ~legacy ctxt loc btr bfr {branch} + (* pairs *) + | ( Prim (loc, I_PAIR, [], annot), + Item_t (a, Item_t (b, rest, snd_annot), fst_annot) ) -> + parse_constr_annot + loc + annot + ~if_special_first:(var_to_field_annot fst_annot) + ~if_special_second:(var_to_field_annot snd_annot) + >>?= fun (annot, ty_name, l_field, r_field) -> + pair_t loc (a, l_field, fst_annot) (b, r_field, snd_annot) ~annot:ty_name + >>?= fun ty -> + let stack_ty = Item_t (ty, rest, annot) in + let cons_pair = {apply = (fun kinfo k -> ICons_pair (kinfo, k))} in + typed ctxt loc cons_pair stack_ty + | (Prim (loc, I_PAIR, [n], annot), stack_ty) -> + parse_var_annot loc annot >>?= fun annot -> + let rec make_proof_argument : + type a s. + int -> (a, s) stack_ty -> (a * s) comb_proof_argument tzresult = + fun n stack_ty -> + match (n, stack_ty) with + | (1, Item_t (a_ty, tl_ty, _a_annot_opt)) -> + ok (Comb_proof_argument (Comb_one, Item_t (a_ty, tl_ty, annot))) + | (n, Item_t (a_ty, tl_ty, _prop_annot_opt)) -> + make_proof_argument (n - 1) tl_ty + >>? fun (Comb_proof_argument + (comb_witness, Item_t (b_ty, tl_ty', annot))) -> + pair_t loc (a_ty, None, None) (b_ty, None, None) ~annot:None + >|? fun pair_t -> + Comb_proof_argument + (Comb_succ comb_witness, Item_t (pair_t, tl_ty', annot)) + | _ -> + let whole_stack = serialize_stack_for_error ctxt stack_ty in + error (Bad_stack (loc, I_PAIR, 1, whole_stack)) + in + parse_uint10 n >>?= fun n -> + Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> + error_unless (Compare.Int.( > ) n 1) (Pair_bad_argument loc) + >>?= fun () -> + make_proof_argument n stack_ty + >>?= fun (Comb_proof_argument (witness, after_ty)) -> + let comb = {apply = (fun kinfo k -> IComb (kinfo, n, witness, k))} in + typed ctxt loc comb after_ty + | (Prim (loc, I_UNPAIR, [n], annot), stack_ty) -> + error_unexpected_annot loc annot >>?= fun () -> + let rec make_proof_argument : + type a s. + int -> (a, s) stack_ty -> (a * s) uncomb_proof_argument tzresult = + fun n stack_ty -> + match (n, stack_ty) with + | (1, Item_t (a_ty, tl_ty, annot)) -> + ok @@ Uncomb_proof_argument (Uncomb_one, Item_t (a_ty, tl_ty, annot)) + | ( n, + Item_t + ( Pair_t ((a_ty, field_opt, _), (b_ty, b_field_opt, _), _), + tl_ty, + _ ) ) -> + let b_annot = Script_ir_annot.field_to_var_annot b_field_opt in + make_proof_argument (n - 1) (Item_t (b_ty, tl_ty, b_annot)) + >|? fun (Uncomb_proof_argument (uncomb_witness, after_ty)) -> + Uncomb_proof_argument + ( Uncomb_succ uncomb_witness, + Item_t + (a_ty, after_ty, Script_ir_annot.field_to_var_annot field_opt) + ) + | _ -> + let whole_stack = serialize_stack_for_error ctxt stack_ty in + error (Bad_stack (loc, I_UNPAIR, 1, whole_stack)) + in + parse_uint10 n >>?= fun n -> + Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> + error_unless (Compare.Int.( > ) n 1) (Unpair_bad_argument loc) + >>?= fun () -> + make_proof_argument n stack_ty + >>?= fun (Uncomb_proof_argument (witness, after_ty)) -> + let uncomb = {apply = (fun kinfo k -> IUncomb (kinfo, n, witness, k))} in + typed ctxt loc uncomb after_ty + | (Prim (loc, I_GET, [n], annot), Item_t (comb_ty, rest_ty, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let rec make_proof_argument : + type b. int -> b ty -> b comb_get_proof_argument tzresult = + fun n ty -> + match (n, ty) with + | (0, value_ty) -> + ok @@ Comb_get_proof_argument (Comb_get_zero, value_ty) + | (1, Pair_t ((hd_ty, _at1, _at2), _, _annot)) -> + ok @@ Comb_get_proof_argument (Comb_get_one, hd_ty) + | (n, Pair_t (_, (tl_ty, _bt1, _bt2), _annot)) -> + make_proof_argument (n - 2) tl_ty + >|? fun (Comb_get_proof_argument (comb_get_left_witness, ty')) -> + Comb_get_proof_argument + (Comb_get_plus_two comb_get_left_witness, ty') + | _ -> + let whole_stack = serialize_stack_for_error ctxt stack_ty in + error (Bad_stack (loc, I_GET, 1, whole_stack)) + in + parse_uint11 n >>?= fun n -> + Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> + make_proof_argument n comb_ty + >>?= fun (Comb_get_proof_argument (witness, ty')) -> + let after_stack_ty = Item_t (ty', rest_ty, annot) in + let comb_get = + {apply = (fun kinfo k -> IComb_get (kinfo, n, witness, k))} + in + typed ctxt loc comb_get after_stack_ty + | ( Prim (loc, I_UPDATE, [n], annot), + Item_t (value_ty, Item_t (comb_ty, rest_ty, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let rec make_proof_argument : + type value before. + int -> + value ty -> + before ty -> + (value, before) comb_set_proof_argument tzresult = + fun n value_ty ty -> + match (n, ty) with + | (0, _) -> ok @@ Comb_set_proof_argument (Comb_set_zero, value_ty) + | (1, Pair_t ((_hd_ty, at1, at2), (tl_ty, bt1, bt2), {annot; _})) -> + pair_t loc (value_ty, at1, at2) (tl_ty, bt1, bt2) ~annot + >|? fun after_ty -> Comb_set_proof_argument (Comb_set_one, after_ty) + | (n, Pair_t ((hd_ty, at1, at2), (tl_ty, bt1, bt2), {annot; _})) -> + make_proof_argument (n - 2) value_ty tl_ty + >>? fun (Comb_set_proof_argument (comb_set_left_witness, tl_ty')) -> + pair_t loc (hd_ty, at1, at2) (tl_ty', bt1, bt2) ~annot + >|? fun after_ty -> + Comb_set_proof_argument + (Comb_set_plus_two comb_set_left_witness, after_ty) + | _ -> + let whole_stack = serialize_stack_for_error ctxt stack_ty in + error (Bad_stack (loc, I_UPDATE, 2, whole_stack)) + in + parse_uint11 n >>?= fun n -> + Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> + make_proof_argument n value_ty comb_ty + >>?= fun (Comb_set_proof_argument (witness, after_ty)) -> + let after_stack_ty = Item_t (after_ty, rest_ty, annot) in + let comb_set = + {apply = (fun kinfo k -> IComb_set (kinfo, n, witness, k))} + in + typed ctxt loc comb_set after_stack_ty + | ( Prim (loc, I_UNPAIR, [], annot), + Item_t + ( Pair_t + ( (a, expected_field_annot_a, a_annot), + (b, expected_field_annot_b, b_annot), + _ ), + rest, + pair_annot ) ) -> + parse_unpair_annot + loc + annot + ~pair_annot + ~value_annot_car:a_annot + ~value_annot_cdr:b_annot + ~field_name_car:expected_field_annot_a + ~field_name_cdr:expected_field_annot_b + >>?= fun (annot_a, annot_b, field_a, field_b) -> + check_correct_field field_a expected_field_annot_a >>?= fun () -> + check_correct_field field_b expected_field_annot_b >>?= fun () -> + let unpair = {apply = (fun kinfo k -> IUnpair (kinfo, k))} in + typed ctxt loc unpair (Item_t (a, Item_t (b, rest, annot_b), annot_a)) + | ( Prim (loc, I_CAR, [], annot), + Item_t + (Pair_t ((a, expected_field_annot, a_annot), _, _), rest, pair_annot) ) + -> + parse_destr_annot + loc + annot + ~pair_annot + ~value_annot:a_annot + ~field_name:expected_field_annot + ~default_accessor:default_car_annot + >>?= fun (annot, field_annot) -> + check_correct_field field_annot expected_field_annot >>?= fun () -> + let car = {apply = (fun kinfo k -> ICar (kinfo, k))} in + typed ctxt loc car (Item_t (a, rest, annot)) + | ( Prim (loc, I_CDR, [], annot), + Item_t + (Pair_t (_, (b, expected_field_annot, b_annot), _), rest, pair_annot) ) + -> + parse_destr_annot + loc + annot + ~pair_annot + ~value_annot:b_annot + ~field_name:expected_field_annot + ~default_accessor:default_cdr_annot + >>?= fun (annot, field_annot) -> + check_correct_field field_annot expected_field_annot >>?= fun () -> + let cdr = {apply = (fun kinfo k -> ICdr (kinfo, k))} in + typed ctxt loc cdr (Item_t (b, rest, annot)) + (* unions *) + | (Prim (loc, I_LEFT, [tr], annot), Item_t (tl, rest, stack_annot)) -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy tr + >>?= fun (Ex_ty tr, ctxt) -> + parse_constr_annot + loc + annot + ~if_special_first:(var_to_field_annot stack_annot) + >>?= fun (annot, tname, l_field, r_field) -> + let cons_left = {apply = (fun kinfo k -> ICons_left (kinfo, k))} in + union_t loc (tl, l_field) (tr, r_field) ~annot:tname >>?= fun ty -> + let stack_ty = Item_t (ty, rest, annot) in + typed ctxt loc cons_left stack_ty + | (Prim (loc, I_RIGHT, [tl], annot), Item_t (tr, rest, stack_annot)) -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy tl + >>?= fun (Ex_ty tl, ctxt) -> + parse_constr_annot + loc + annot + ~if_special_second:(var_to_field_annot stack_annot) + >>?= fun (annot, tname, l_field, r_field) -> + let cons_right = {apply = (fun kinfo k -> ICons_right (kinfo, k))} in + union_t loc (tl, l_field) (tr, r_field) ~annot:tname >>?= fun ty -> + let stack_ty = Item_t (ty, rest, annot) in + typed ctxt loc cons_right stack_ty + | ( Prim (loc, I_IF_LEFT, [bt; bf], annot), + (Item_t (Union_t ((tl, l_field), (tr, r_field), _), rest, union_annot) as + bef) ) -> + check_kind [Seq_kind] bt >>?= fun () -> + check_kind [Seq_kind] bf >>?= fun () -> + error_unexpected_annot loc annot >>?= fun () -> + let left_annot = + gen_access_annot union_annot l_field ~default:default_left_annot + in + let right_annot = + gen_access_annot union_annot r_field ~default:default_right_annot + in + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + bt + (Item_t (tl, rest, left_annot)) + >>=? fun (btr, ctxt) -> + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + bf + (Item_t (tr, rest, right_annot)) + >>=? fun (bfr, ctxt) -> + let branch ibt ibf = + let infobt = kinfo_of_descr ibt and infobf = kinfo_of_descr ibf in + let instr = + { + apply = + (fun kinfo k -> + let hinfo = kinfo_of_kinstr k in + let branch_if_left = ibt.instr.apply infobt (IHalt hinfo) + and branch_if_right = ibf.instr.apply infobf (IHalt hinfo) in + IIf_left {kinfo; branch_if_left; branch_if_right; k}); + } + in + {loc; instr; bef; aft = ibt.aft} + in + Lwt.return @@ merge_branches ~legacy ctxt loc btr bfr {branch} + (* lists *) + | (Prim (loc, I_NIL, [t], annot), stack) -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy t + >>?= fun (Ex_ty t, ctxt) -> + parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> + let nil = {apply = (fun kinfo k -> INil (kinfo, k))} in + list_t loc t ~annot:ty_name >>?= fun ty -> + typed ctxt loc nil (Item_t (ty, stack, annot)) + | ( Prim (loc, I_CONS, [], annot), + Item_t (tv, Item_t (List_t (t, ty_name), rest, _), _) ) -> + check_item_ty ctxt tv t loc I_CONS 1 2 >>?= fun (Eq, t, ctxt) -> + parse_var_annot loc annot >>?= fun annot -> + let cons_list = {apply = (fun kinfo k -> ICons_list (kinfo, k))} in + (typed ctxt loc cons_list (Item_t (List_t (t, ty_name), rest, annot)) + : ((a, s) judgement * context) tzresult Lwt.t) + | ( Prim (loc, I_IF_CONS, [bt; bf], annot), + (Item_t (List_t (t, ty_name), rest, list_annot) as bef) ) -> + check_kind [Seq_kind] bt >>?= fun () -> + check_kind [Seq_kind] bf >>?= fun () -> + error_unexpected_annot loc annot >>?= fun () -> + let hd_annot = gen_access_annot list_annot default_hd_annot in + let tl_annot = gen_access_annot list_annot default_tl_annot in + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + bt + (Item_t (t, Item_t (List_t (t, ty_name), rest, tl_annot), hd_annot)) + >>=? fun (btr, ctxt) -> + non_terminal_recursion ?type_logger tc_context ctxt ~legacy bf rest + >>=? fun (bfr, ctxt) -> + let branch ibt ibf = + let infobt = kinfo_of_descr ibt and infobf = kinfo_of_descr ibf in + let instr = + { + apply = + (fun kinfo k -> + let hinfo = kinfo_of_kinstr k in + let branch_if_cons = ibt.instr.apply infobt (IHalt hinfo) + and branch_if_nil = ibf.instr.apply infobf (IHalt hinfo) in + IIf_cons {kinfo; branch_if_nil; branch_if_cons; k}); + } + in + {loc; instr; bef; aft = ibt.aft} + in + Lwt.return @@ merge_branches ~legacy ctxt loc btr bfr {branch} + | (Prim (loc, I_SIZE, [], annot), Item_t (List_t _, rest, _)) -> + parse_var_type_annot loc annot >>?= fun (annot, tname) -> + let list_size = {apply = (fun kinfo k -> IList_size (kinfo, k))} in + typed ctxt loc list_size (Item_t (nat_t ~annot:tname, rest, annot)) + | ( Prim (loc, I_MAP, [body], annot), + Item_t (List_t (elt, _), starting_rest, list_annot) ) -> ( + check_kind [Seq_kind] body >>?= fun () -> + parse_var_type_annot loc annot >>?= fun (ret_annot, list_ty_name) -> + let elt_annot = gen_access_annot list_annot default_elt_annot in + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + body + (Item_t (elt, starting_rest, elt_annot)) + >>=? fun (judgement, ctxt) -> + Lwt.return + @@ + match judgement with + | Typed ({aft = Item_t (ret, rest, _); _} as kibody) -> + let invalid_map_body () = + let aft = serialize_stack_for_error ctxt kibody.aft in + Invalid_map_body (loc, aft) + in + record_trace_eval + invalid_map_body + ( merge_stacks ~legacy loc ctxt 1 rest starting_rest + >>? fun (Eq, rest, ctxt) -> + let binfo = kinfo_of_descr kibody in + let hinfo = + {iloc = loc; kstack_ty = Item_t (ret, rest, ret_annot)} + in + let ibody = kibody.instr.apply binfo (IHalt hinfo) in + let list_map = + {apply = (fun kinfo k -> IList_map (kinfo, ibody, k))} + in + list_t loc ret ~annot:list_ty_name >>? fun ty -> + let stack = Item_t (ty, rest, ret_annot) in + typed_no_lwt ctxt loc list_map stack ) + | Typed {aft; _} -> + let aft = serialize_stack_for_error ctxt aft in + error (Invalid_map_body (loc, aft)) + | Failed _ -> error (Invalid_map_block_fail loc)) + | ( Prim (loc, I_ITER, [body], annot), + Item_t (List_t (elt, _), rest, list_annot) ) -> ( + check_kind [Seq_kind] body >>?= fun () -> + error_unexpected_annot loc annot >>?= fun () -> + let elt_annot = gen_access_annot list_annot default_elt_annot in + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + body + (Item_t (elt, rest, elt_annot)) + >>=? fun (judgement, ctxt) -> + let mk_list_iter ibody = + { + apply = + (fun kinfo k -> + let hinfo = {iloc = loc; kstack_ty = rest} in + let binfo = kinfo_of_descr ibody in + let ibody = ibody.instr.apply binfo (IHalt hinfo) in + IList_iter (kinfo, ibody, k)); + } + in + Lwt.return + @@ + match judgement with + | Typed ({aft; _} as ibody) -> + let invalid_iter_body () = + let aft = serialize_stack_for_error ctxt ibody.aft in + let rest = serialize_stack_for_error ctxt rest in + Invalid_iter_body (loc, rest, aft) + in + record_trace_eval + invalid_iter_body + ( merge_stacks ~legacy loc ctxt 1 aft rest + >>? fun (Eq, rest, ctxt) : ((a, s) judgement * context) tzresult -> + typed_no_lwt ctxt loc (mk_list_iter ibody) rest ) + | Failed {descr} -> typed_no_lwt ctxt loc (mk_list_iter (descr rest)) rest + ) + (* sets *) + | (Prim (loc, I_EMPTY_SET, [t], annot), rest) -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt t + >>?= fun (Ex_comparable_ty t, ctxt) -> + parse_var_type_annot loc annot >>?= fun (annot, tname) -> + let instr = {apply = (fun kinfo k -> IEmpty_set (kinfo, t, k))} in + set_t loc t ~annot:tname >>?= fun ty -> + typed ctxt loc instr (Item_t (ty, rest, annot)) + | ( Prim (loc, I_ITER, [body], annot), + Item_t (Set_t (comp_elt, _), rest, set_annot) ) -> ( + check_kind [Seq_kind] body >>?= fun () -> + error_unexpected_annot loc annot >>?= fun () -> + let elt_annot = gen_access_annot set_annot default_elt_annot in + let elt = ty_of_comparable_ty comp_elt in + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + body + (Item_t (elt, rest, elt_annot)) + >>=? fun (judgement, ctxt) -> + let mk_iset_iter ibody = + { + apply = + (fun kinfo k -> + let hinfo = {iloc = loc; kstack_ty = rest} in + let binfo = kinfo_of_descr ibody in + let ibody = ibody.instr.apply binfo (IHalt hinfo) in + ISet_iter (kinfo, ibody, k)); + } + in + Lwt.return + @@ + match judgement with + | Typed ({aft; _} as ibody) -> + let invalid_iter_body () = + let aft = serialize_stack_for_error ctxt ibody.aft in + let rest = serialize_stack_for_error ctxt rest in + Invalid_iter_body (loc, rest, aft) + in + record_trace_eval + invalid_iter_body + ( merge_stacks ~legacy loc ctxt 1 aft rest + >>? fun (Eq, rest, ctxt) : ((a, s) judgement * context) tzresult -> + typed_no_lwt ctxt loc (mk_iset_iter ibody) rest ) + | Failed {descr} -> typed_no_lwt ctxt loc (mk_iset_iter (descr rest)) rest + ) + | ( Prim (loc, I_MEM, [], annot), + Item_t (v, Item_t (Set_t (elt, _), rest, _), _) ) -> + let elt = ty_of_comparable_ty elt in + parse_var_type_annot loc annot >>?= fun (annot, tname) -> + check_item_ty ctxt elt v loc I_MEM 1 2 >>?= fun (Eq, _, ctxt) -> + let instr = {apply = (fun kinfo k -> ISet_mem (kinfo, k))} in + (typed ctxt loc instr (Item_t (bool_t ~annot:tname, rest, annot)) + : ((a, s) judgement * context) tzresult Lwt.t) + | ( Prim (loc, I_UPDATE, [], annot), + Item_t + ( v, + Item_t (Bool_t _, Item_t (Set_t (elt, tname), rest, set_annot), _), + _ ) ) -> + check_item_ty ctxt (ty_of_comparable_ty elt) v loc I_UPDATE 1 3 + >>?= fun (Eq, _, ctxt) -> + parse_var_annot loc annot ~default:set_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISet_update (kinfo, k))} in + (typed ctxt loc instr (Item_t (Set_t (elt, tname), rest, annot)) + : ((a, s) judgement * context) tzresult Lwt.t) + | (Prim (loc, I_SIZE, [], annot), Item_t (Set_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISet_size (kinfo, k))} in + typed ctxt loc instr (Item_t (nat_t ~annot:None, rest, annot)) + (* maps *) + | (Prim (loc, I_EMPTY_MAP, [tk; tv], annot), stack) -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt tk + >>?= fun (Ex_comparable_ty tk, ctxt) -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy tv + >>?= fun (Ex_ty tv, ctxt) -> + parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> + let instr = {apply = (fun kinfo k -> IEmpty_map (kinfo, tk, k))} in + map_t loc tk tv ~annot:ty_name >>?= fun ty -> + typed ctxt loc instr (Item_t (ty, stack, annot)) + | ( Prim (loc, I_MAP, [body], annot), + Item_t (Map_t (ck, elt, _), starting_rest, _map_annot) ) -> ( + let k = ty_of_comparable_ty ck in + check_kind [Seq_kind] body >>?= fun () -> + parse_var_type_annot loc annot >>?= fun (ret_annot, ty_name) -> + let k_name = field_to_var_annot default_key_annot in + let e_name = field_to_var_annot default_elt_annot in + pair_t loc (k, None, k_name) (elt, None, e_name) ~annot:None + >>?= fun ty -> + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + body + (Item_t (ty, starting_rest, None)) + >>=? fun (judgement, ctxt) -> + Lwt.return + @@ + match judgement with + | Typed ({aft = Item_t (ret, rest, _); _} as ibody) -> + let invalid_map_body () = + let aft = serialize_stack_for_error ctxt ibody.aft in + Invalid_map_body (loc, aft) + in + record_trace_eval + invalid_map_body + ( merge_stacks ~legacy loc ctxt 1 rest starting_rest + >>? fun (Eq, rest, ctxt) -> + let instr = + { + apply = + (fun kinfo k -> + let binfo = kinfo_of_descr ibody in + let hinfo = + {iloc = loc; kstack_ty = Item_t (ret, rest, ret_annot)} + in + let ibody = ibody.instr.apply binfo (IHalt hinfo) in + IMap_map (kinfo, ibody, k)); + } + in + map_t loc ck ret ~annot:ty_name >>? fun ty -> + let stack = Item_t (ty, rest, ret_annot) in + typed_no_lwt ctxt loc instr stack ) + | Typed {aft; _} -> + let aft = serialize_stack_for_error ctxt aft in + error (Invalid_map_body (loc, aft)) + | Failed _ -> error (Invalid_map_block_fail loc)) + | ( Prim (loc, I_ITER, [body], annot), + Item_t (Map_t (comp_elt, element_ty, _), rest, _map_annot) ) -> ( + check_kind [Seq_kind] body >>?= fun () -> + error_unexpected_annot loc annot >>?= fun () -> + let k_name = field_to_var_annot default_key_annot in + let e_name = field_to_var_annot default_elt_annot in + let key = ty_of_comparable_ty comp_elt in + pair_t loc (key, None, k_name) (element_ty, None, e_name) ~annot:None + >>?= fun ty -> + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + body + (Item_t (ty, rest, None)) + >>=? fun (judgement, ctxt) -> + let make_instr ibody = + { + apply = + (fun kinfo k -> + let hinfo = {iloc = loc; kstack_ty = rest} in + let binfo = kinfo_of_descr ibody in + let ibody = ibody.instr.apply binfo (IHalt hinfo) in + IMap_iter (kinfo, ibody, k)); + } + in + Lwt.return + @@ + match judgement with + | Typed ({aft; _} as ibody) -> + let invalid_iter_body () = + let aft = serialize_stack_for_error ctxt ibody.aft in + let rest = serialize_stack_for_error ctxt rest in + Invalid_iter_body (loc, rest, aft) + in + record_trace_eval + invalid_iter_body + ( merge_stacks ~legacy loc ctxt 1 aft rest + >>? fun (Eq, rest, ctxt) : ((a, s) judgement * context) tzresult -> + typed_no_lwt ctxt loc (make_instr ibody) rest ) + | Failed {descr} -> typed_no_lwt ctxt loc (make_instr (descr rest)) rest) + | ( Prim (loc, I_MEM, [], annot), + Item_t (vk, Item_t (Map_t (ck, _, _), rest, _), _) ) -> + let k = ty_of_comparable_ty ck in + check_item_ty ctxt vk k loc I_MEM 1 2 >>?= fun (Eq, _, ctxt) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMap_mem (kinfo, k))} in + (typed ctxt loc instr (Item_t (bool_t ~annot:None, rest, annot)) + : ((a, s) judgement * context) tzresult Lwt.t) + | ( Prim (loc, I_GET, [], annot), + Item_t (vk, Item_t (Map_t (ck, elt, _), rest, _), _) ) -> + let k = ty_of_comparable_ty ck in + check_item_ty ctxt vk k loc I_GET 1 2 >>?= fun (Eq, _, ctxt) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMap_get (kinfo, k))} in + option_t loc elt ~annot:None + >>?= fun ty : ((a, s) judgement * context) tzresult Lwt.t -> + typed ctxt loc instr (Item_t (ty, rest, annot)) + | ( Prim (loc, I_UPDATE, [], annot), + Item_t + ( vk, + Item_t + ( Option_t (vv, _), + Item_t (Map_t (ck, v, map_name), rest, map_annot), + _ ), + _ ) ) -> + let k = ty_of_comparable_ty ck in + check_item_ty ctxt vk k loc I_UPDATE 1 3 >>?= fun (Eq, _, ctxt) -> + check_item_ty ctxt vv v loc I_UPDATE 2 3 >>?= fun (Eq, v, ctxt) -> + parse_var_annot loc annot ~default:map_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMap_update (kinfo, k))} in + (typed ctxt loc instr (Item_t (Map_t (ck, v, map_name), rest, annot)) + : ((a, s) judgement * context) tzresult Lwt.t) + | ( Prim (loc, I_GET_AND_UPDATE, [], annot), + Item_t + ( vk, + Item_t + ( Option_t (vv, vname), + Item_t (Map_t (ck, v, map_name), rest, map_annot), + v_annot ), + _ ) ) -> + let k = ty_of_comparable_ty ck in + check_item_ty ctxt vk k loc I_GET_AND_UPDATE 1 3 >>?= fun (Eq, _, ctxt) -> + check_item_ty ctxt vv v loc I_GET_AND_UPDATE 2 3 >>?= fun (Eq, v, ctxt) -> + parse_var_annot loc annot ~default:map_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMap_get_and_update (kinfo, k))} in + let stack = + Item_t + ( Option_t (vv, vname), + Item_t (Map_t (ck, v, map_name), rest, annot), + v_annot ) + in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + | (Prim (loc, I_SIZE, [], annot), Item_t (Map_t (_, _, _), rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMap_size (kinfo, k))} in + typed ctxt loc instr (Item_t (nat_t ~annot:None, rest, annot)) + (* big_map *) + | (Prim (loc, I_EMPTY_BIG_MAP, [tk; tv], annot), stack) -> + parse_comparable_ty ~stack_depth:(stack_depth + 1) ctxt tk + >>?= fun (Ex_comparable_ty tk, ctxt) -> + parse_big_map_value_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy tv + >>?= fun (Ex_ty tv, ctxt) -> + parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> + let instr = + {apply = (fun kinfo k -> IEmpty_big_map (kinfo, tk, tv, k))} + in + big_map_t loc tk tv ~annot:ty_name >>?= fun ty -> + let stack = Item_t (ty, stack, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MEM, [], annot), + Item_t (set_key, Item_t (Big_map_t (map_key, _, _), rest, _), _) ) -> + let k = ty_of_comparable_ty map_key in + check_item_ty ctxt set_key k loc I_MEM 1 2 >>?= fun (Eq, _, ctxt) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IBig_map_mem (kinfo, k))} in + let stack = Item_t (bool_t ~annot:None, rest, annot) in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + | ( Prim (loc, I_GET, [], annot), + Item_t (vk, Item_t (Big_map_t (ck, elt, _), rest, _), _) ) -> + let k = ty_of_comparable_ty ck in + check_item_ty ctxt vk k loc I_GET 1 2 >>?= fun (Eq, _, ctxt) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IBig_map_get (kinfo, k))} in + option_t loc elt ~annot:None >>?= fun ty -> + let stack = Item_t (ty, rest, annot) in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + | ( Prim (loc, I_UPDATE, [], annot), + Item_t + ( set_key, + Item_t + ( Option_t (set_value, _), + Item_t (Big_map_t (map_key, map_value, map_name), rest, map_annot), + _ ), + _ ) ) -> + let k = ty_of_comparable_ty map_key in + check_item_ty ctxt set_key k loc I_UPDATE 1 3 >>?= fun (Eq, _, ctxt) -> + check_item_ty ctxt set_value map_value loc I_UPDATE 2 3 + >>?= fun (Eq, map_value, ctxt) -> + parse_var_annot loc annot ~default:map_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IBig_map_update (kinfo, k))} in + let stack = + Item_t (Big_map_t (map_key, map_value, map_name), rest, annot) + in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + | ( Prim (loc, I_GET_AND_UPDATE, [], annot), + Item_t + ( vk, + Item_t + ( Option_t (vv, vname), + Item_t (Big_map_t (ck, v, map_name), rest, map_annot), + v_annot ), + _ ) ) -> + let k = ty_of_comparable_ty ck in + check_item_ty ctxt vk k loc I_GET_AND_UPDATE 1 3 >>?= fun (Eq, _, ctxt) -> + check_item_ty ctxt vv v loc I_GET_AND_UPDATE 2 3 >>?= fun (Eq, v, ctxt) -> + parse_var_annot loc annot ~default:map_annot >>?= fun annot -> + let instr = + {apply = (fun kinfo k -> IBig_map_get_and_update (kinfo, k))} + in + let stack = + Item_t + ( Option_t (vv, vname), + Item_t (Big_map_t (ck, v, map_name), rest, annot), + v_annot ) + in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + (* Sapling *) + | (Prim (loc, I_SAPLING_EMPTY_STATE, [memo_size], annot), rest) -> + parse_memo_size memo_size >>?= fun memo_size -> + parse_var_annot loc annot ~default:default_sapling_state_annot + >>?= fun annot -> + let instr = + {apply = (fun kinfo k -> ISapling_empty_state (kinfo, memo_size, k))} + in + let stack = + Item_t (sapling_state_t ~memo_size ~annot:None, rest, annot) + in + typed ctxt loc instr stack + | ( Prim (loc, I_SAPLING_VERIFY_UPDATE, [], _), + Item_t + ( Sapling_transaction_t (transaction_memo_size, _), + Item_t + ( (Sapling_state_t (state_memo_size, _) as state_ty), + rest, + stack_annot ), + _ ) ) -> + merge_memo_sizes state_memo_size transaction_memo_size + >>?= fun _memo_size -> + let instr = + {apply = (fun kinfo k -> ISapling_verify_update (kinfo, k))} + in + pair_t + loc + (int_t ~annot:None, None, default_sapling_balance_annot) + (state_ty, None, None) + ~annot:None + >>?= fun pair_ty -> + option_t loc pair_ty ~annot:None >>?= fun ty -> + let stack = Item_t (ty, rest, stack_annot) in + typed ctxt loc instr stack + (* control *) + | (Seq (loc, []), stack) -> + let instr = {apply = (fun _kinfo k -> k)} in + typed ctxt loc instr stack + | (Seq (_, [single]), stack) -> + non_terminal_recursion ?type_logger tc_context ctxt ~legacy single stack + | (Seq (loc, hd :: tl), stack) -> ( + non_terminal_recursion ?type_logger tc_context ctxt ~legacy hd stack + >>=? fun (judgement, ctxt) -> + match judgement with + | Failed _ -> fail (Fail_not_in_tail_position (Micheline.location hd)) + | Typed ({aft = middle; _} as ihd) -> + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + (Seq (Micheline.dummy_location, tl)) + middle + >|=? fun (judgement, ctxt) -> + let judgement = + match judgement with + | Failed {descr} -> + let descr ret = compose_descr loc ihd (descr ret) in + Failed {descr} + | Typed itl -> Typed (compose_descr loc ihd itl) + in + (judgement, ctxt)) + | (Prim (loc, I_IF, [bt; bf], annot), (Item_t (Bool_t _, rest, _) as bef)) -> + check_kind [Seq_kind] bt >>?= fun () -> + check_kind [Seq_kind] bf >>?= fun () -> + error_unexpected_annot loc annot >>?= fun () -> + non_terminal_recursion ?type_logger tc_context ctxt ~legacy bt rest + >>=? fun (btr, ctxt) -> + non_terminal_recursion ?type_logger tc_context ctxt ~legacy bf rest + >>=? fun (bfr, ctxt) -> + let branch ibt ibf = + let infobt = kinfo_of_descr ibt and infobf = kinfo_of_descr ibf in + let instr = + { + apply = + (fun kinfo k -> + let hinfo = kinfo_of_kinstr k in + let branch_if_true = ibt.instr.apply infobt (IHalt hinfo) + and branch_if_false = ibf.instr.apply infobf (IHalt hinfo) in + IIf {kinfo; branch_if_true; branch_if_false; k}); + } + in + {loc; instr; bef; aft = ibt.aft} + in + Lwt.return @@ merge_branches ~legacy ctxt loc btr bfr {branch} + | ( Prim (loc, I_LOOP, [body], annot), + (Item_t (Bool_t _, rest, _stack_annot) as stack) ) -> ( + check_kind [Seq_kind] body >>?= fun () -> + error_unexpected_annot loc annot >>?= fun () -> + non_terminal_recursion ?type_logger tc_context ctxt ~legacy body rest + >>=? fun (judgement, ctxt) -> + Lwt.return + @@ + match judgement with + | Typed ibody -> + let unmatched_branches () = + let aft = serialize_stack_for_error ctxt ibody.aft in + let stack = serialize_stack_for_error ctxt stack in + Unmatched_branches (loc, aft, stack) + in + record_trace_eval + unmatched_branches + ( merge_stacks ~legacy loc ctxt 1 ibody.aft stack + >>? fun (Eq, _stack, ctxt) -> + let instr = + { + apply = + (fun kinfo k -> + let ibody = + ibody.instr.apply (kinfo_of_descr ibody) (IHalt kinfo) + in + ILoop (kinfo, ibody, k)); + } + in + typed_no_lwt ctxt loc instr rest ) + | Failed {descr} -> + let instr = + { + apply = + (fun kinfo k -> + let ibody = descr stack in + let ibody = + ibody.instr.apply (kinfo_of_descr ibody) (IHalt kinfo) + in + ILoop (kinfo, ibody, k)); + } + in + typed_no_lwt ctxt loc instr rest) + | ( Prim (loc, I_LOOP_LEFT, [body], annot), + (Item_t (Union_t ((tl, l_field), (tr, _), _), rest, union_annot) as stack) + ) -> ( + check_kind [Seq_kind] body >>?= fun () -> + parse_var_annot loc annot >>?= fun annot -> + let l_annot = + gen_access_annot union_annot l_field ~default:default_left_annot + in + non_terminal_recursion + ?type_logger + tc_context + ctxt + ~legacy + body + (Item_t (tl, rest, l_annot)) + >>=? fun (judgement, ctxt) -> + Lwt.return + @@ + match judgement with + | Typed ibody -> + let unmatched_branches () = + let aft = serialize_stack_for_error ctxt ibody.aft in + let stack = serialize_stack_for_error ctxt stack in + Unmatched_branches (loc, aft, stack) + in + record_trace_eval + unmatched_branches + ( merge_stacks ~legacy loc ctxt 1 ibody.aft stack + >>? fun (Eq, _stack, ctxt) -> + let instr = + { + apply = + (fun kinfo k -> + let ibody = + ibody.instr.apply (kinfo_of_descr ibody) (IHalt kinfo) + in + ILoop_left (kinfo, ibody, k)); + } + in + let stack = Item_t (tr, rest, annot) in + typed_no_lwt ctxt loc instr stack ) + | Failed {descr} -> + let instr = + { + apply = + (fun kinfo k -> + let ibody = descr stack in + let ibody = + ibody.instr.apply (kinfo_of_descr ibody) (IHalt kinfo) + in + ILoop_left (kinfo, ibody, k)); + } + in + let stack = Item_t (tr, rest, annot) in + typed_no_lwt ctxt loc instr stack) + | (Prim (loc, I_LAMBDA, [arg; ret; code], annot), stack) -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy arg + >>?= fun (Ex_ty arg, ctxt) -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy ret + >>?= fun (Ex_ty ret, ctxt) -> + check_kind [Seq_kind] code >>?= fun () -> + parse_var_annot loc annot >>?= fun annot -> + parse_returning + Lambda + ?type_logger + ~stack_depth:(stack_depth + 1) + ctxt + ~legacy + (arg, default_arg_annot) + ret + code + >>=? fun (lambda, ctxt) -> + let instr = {apply = (fun kinfo k -> ILambda (kinfo, lambda, k))} in + lambda_t loc arg ret ~annot:None >>?= fun ty -> + let stack = Item_t (ty, stack, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_EXEC, [], annot), + Item_t (arg, Item_t (Lambda_t (param, ret, _), rest, _), _) ) -> + check_item_ty ctxt arg param loc I_EXEC 1 2 >>?= fun (Eq, _, ctxt) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IExec (kinfo, k))} in + let stack = Item_t (ret, rest, annot) in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + | ( Prim (loc, I_APPLY, [], annot), + Item_t + ( capture, + Item_t + ( Lambda_t + ( Pair_t + ((capture_ty, _, _), (arg_ty, _, _), {annot = lam_annot; _}), + ret, + _ ), + rest, + _ ), + _ ) ) -> + check_packable ~legacy:false loc capture_ty >>?= fun () -> + check_item_ty ctxt capture capture_ty loc I_APPLY 1 2 + >>?= fun (Eq, capture_ty, ctxt) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IApply (kinfo, capture_ty, k))} in + lambda_t loc arg_ty ret ~annot:lam_annot + (* This cannot fail because the type [lambda 'arg 'ret] is always smaller than + the input type [lambda (pair 'arg 'capture) 'ret]. In an ideal world, there + would be a smart deconstructor to ensure this statically. *) + >>?= + fun res_ty -> + let stack = Item_t (res_ty, rest, annot) in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + | (Prim (loc, I_DIP, [code], annot), Item_t (v, rest, stack_annot)) -> ( + error_unexpected_annot loc annot >>?= fun () -> + check_kind [Seq_kind] code >>?= fun () -> + non_terminal_recursion + ?type_logger + (add_dip v stack_annot tc_context) + ctxt + ~legacy + code + rest + >>=? fun (judgement, ctxt) -> + match judgement with + | Typed descr -> + let instr = + { + apply = + (fun kinfo k -> + let binfo = {iloc = descr.loc; kstack_ty = descr.bef} in + let kinfoh = {iloc = descr.loc; kstack_ty = descr.aft} in + let b = descr.instr.apply binfo (IHalt kinfoh) in + IDip (kinfo, b, k)); + } + in + let stack = Item_t (v, descr.aft, stack_annot) in + typed ctxt loc instr stack + | Failed _ -> fail (Fail_not_in_tail_position loc)) + | (Prim (loc, I_DIP, [n; code], result_annot), stack) -> + parse_uint10 n >>?= fun n -> + Gas.consume ctxt (Typecheck_costs.proof_argument n) >>?= fun ctxt -> + let rec make_proof_argument : + type a s. + int -> + tc_context -> + (a, s) stack_ty -> + (a, s) dipn_proof_argument tzresult Lwt.t = + fun n inner_tc_context stk -> + match (Compare.Int.(n = 0), stk) with + | (true, rest) -> ( + non_terminal_recursion + ?type_logger + inner_tc_context + ctxt + ~legacy + code + rest + >>=? fun (judgement, ctxt) -> + Lwt.return + @@ + match judgement with + | Typed descr -> + ok + (Dipn_proof_argument (KRest, ctxt, descr, descr.aft) + : (a, s) dipn_proof_argument) + | Failed _ -> error (Fail_not_in_tail_position loc)) + | (false, Item_t (v, rest, annot)) -> + make_proof_argument (n - 1) (add_dip v annot tc_context) rest + >|=? fun (Dipn_proof_argument (n', ctxt, descr, aft')) -> + let kinfo' = {iloc = loc; kstack_ty = aft'} in + let w = KPrefix (kinfo', n') in + Dipn_proof_argument (w, ctxt, descr, Item_t (v, aft', annot)) + | (_, _) -> + Lwt.return + (let whole_stack = serialize_stack_for_error ctxt stack in + error (Bad_stack (loc, I_DIP, 1, whole_stack))) + in + error_unexpected_annot loc result_annot >>?= fun () -> + make_proof_argument n tc_context stack + >>=? fun (Dipn_proof_argument (n', ctxt, descr, aft)) -> + let kinfo = {iloc = descr.loc; kstack_ty = descr.bef} in + let kinfoh = {iloc = descr.loc; kstack_ty = descr.aft} in + let b = descr.instr.apply kinfo (IHalt kinfoh) in + let res = {apply = (fun kinfo k -> IDipn (kinfo, n, n', b, k))} in + typed ctxt loc res aft + | (Prim (loc, I_DIP, (([] | _ :: _ :: _ :: _) as l), _), _) -> + (* Technically, the arities 1 and 2 are allowed but the error only mentions 2. + However, DIP {code} is equivalent to DIP 1 {code} so hinting at an arity of 2 makes sense. *) + fail (Invalid_arity (loc, I_DIP, 2, List.length l)) + | (Prim (loc, I_FAILWITH, [], annot), Item_t (v, _rest, _)) -> + Lwt.return + ( error_unexpected_annot loc annot >>? fun () -> + (if legacy then Result.return_unit + else check_packable ~legacy:false loc v) + >|? fun () -> + let instr = {apply = (fun kinfo _k -> IFailwith (kinfo, loc, v))} in + let descr aft = {loc; instr; bef = stack_ty; aft} in + log_stack loc stack_ty Bot_t ; + (Failed {descr}, ctxt) ) + | (Prim (loc, I_NEVER, [], annot), Item_t (Never_t _, _rest, _)) -> + Lwt.return + ( error_unexpected_annot loc annot >|? fun () -> + let instr = {apply = (fun kinfo _k -> INever kinfo)} in + let descr aft = {loc; instr; bef = stack_ty; aft} in + log_stack loc stack_ty Bot_t ; + (Failed {descr}, ctxt) ) + (* timestamp operations *) + | ( Prim (loc, I_ADD, [], annot), + Item_t (Timestamp_t tname, Item_t (Int_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = + {apply = (fun kinfo k -> IAdd_timestamp_to_seconds (kinfo, k))} + in + typed ctxt loc instr (Item_t (Timestamp_t tname, rest, annot)) + | ( Prim (loc, I_ADD, [], annot), + Item_t (Int_t _, Item_t (Timestamp_t tname, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = + {apply = (fun kinfo k -> IAdd_seconds_to_timestamp (kinfo, k))} + in + typed ctxt loc instr (Item_t (Timestamp_t tname, rest, annot)) + | ( Prim (loc, I_SUB, [], annot), + Item_t (Timestamp_t tname, Item_t (Int_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = + {apply = (fun kinfo k -> ISub_timestamp_seconds (kinfo, k))} + in + let stack = Item_t (Timestamp_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_SUB, [], annot), + Item_t + ( Timestamp_t {annot = tn1; size = _}, + Item_t (Timestamp_t {annot = tn2; size = _}, rest, _), + _ ) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_annot ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IDiff_timestamps (kinfo, k))} in + let stack = Item_t (int_t ~annot:tname, rest, annot) in + typed ctxt loc instr stack + (* string operations *) + | ( Prim (loc, I_CONCAT, [], annot), + Item_t (String_t tn1, Item_t (String_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IConcat_string_pair (kinfo, k))} in + typed ctxt loc instr (Item_t (String_t tname, rest, annot)) + | ( 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 -> + let instr = {apply = (fun kinfo k -> IConcat_string (kinfo, k))} in + typed ctxt loc instr (Item_t (String_t tname, rest, annot)) + | ( Prim (loc, I_SLICE, [], annot), + Item_t + ( Nat_t _, + Item_t (Nat_t _, Item_t (String_t tname, rest, string_annot), _), + _ ) ) -> + parse_var_annot + ~default:(gen_access_annot string_annot default_slice_annot) + loc + annot + >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISlice_string (kinfo, k))} in + let stack = Item_t (option_string'_t tname, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_SIZE, [], annot), Item_t (String_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IString_size (kinfo, k))} in + let stack = Item_t (nat_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + (* bytes operations *) + | ( Prim (loc, I_CONCAT, [], annot), + Item_t (Bytes_t tn1, Item_t (Bytes_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IConcat_bytes_pair (kinfo, k))} in + let stack = Item_t (Bytes_t tname, rest, annot) in + typed ctxt loc instr stack + | ( 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 -> + let instr = {apply = (fun kinfo k -> IConcat_bytes (kinfo, k))} in + let stack = Item_t (Bytes_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_SLICE, [], annot), + Item_t + ( Nat_t _, + Item_t (Nat_t _, Item_t (Bytes_t tname, rest, bytes_annot), _), + _ ) ) -> + parse_var_annot + ~default:(gen_access_annot bytes_annot default_slice_annot) + loc + annot + >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISlice_bytes (kinfo, k))} in + let stack = Item_t (option_bytes'_t tname, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_SIZE, [], annot), Item_t (Bytes_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IBytes_size (kinfo, k))} in + let stack = Item_t (nat_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + (* currency operations *) + | ( Prim (loc, I_ADD, [], annot), + Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IAdd_tez (kinfo, k))} in + let stack = Item_t (Mutez_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_SUB, [], annot), + Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) ) -> + if legacy then + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> ISub_tez_legacy (kinfo, k))} in + let stack = Item_t (Mutez_t tname, rest, annot) in + typed ctxt loc instr stack + else fail (Deprecated_instruction I_SUB) + | ( Prim (loc, I_SUB_MUTEZ, [], annot), + Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> ISub_tez (kinfo, k))} in + let stack = Item_t (option_mutez'_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Mutez_t tname, Item_t (Nat_t _, rest, _), _) ) -> + (* no type name check *) + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_teznat (kinfo, k))} in + let stack = Item_t (Mutez_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Nat_t _, Item_t (Mutez_t tname, rest, _), _) ) -> + (* no type name check *) + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_nattez (kinfo, k))} in + let stack = Item_t (Mutez_t tname, rest, annot) in + typed ctxt loc instr stack + (* boolean operations *) + | ( Prim (loc, I_OR, [], annot), + Item_t (Bool_t tn1, Item_t (Bool_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IOr (kinfo, k))} in + let stack = Item_t (Bool_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_AND, [], annot), + Item_t (Bool_t tn1, Item_t (Bool_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IAnd (kinfo, k))} in + let stack = Item_t (Bool_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_XOR, [], annot), + Item_t (Bool_t tn1, Item_t (Bool_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IXor (kinfo, k))} in + let stack = Item_t (Bool_t tname, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_NOT, [], annot), Item_t (Bool_t tname, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INot (kinfo, k))} in + let stack = Item_t (Bool_t tname, rest, annot) in + typed ctxt loc instr stack + (* integer operations *) + | (Prim (loc, I_ABS, [], annot), Item_t (Int_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IAbs_int (kinfo, k))} in + let stack = Item_t (nat_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_ISNAT, [], annot), Item_t (Int_t _, rest, int_annot)) -> + parse_var_annot loc annot ~default:int_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IIs_nat (kinfo, k))} in + let stack = Item_t (option_nat_t, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_INT, [], annot), Item_t (Nat_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IInt_nat (kinfo, k))} in + let stack = Item_t (int_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_NEG, [], annot), Item_t (Int_t tname, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INeg (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_NEG, [], annot), Item_t (Nat_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INeg (kinfo, k))} in + let stack = Item_t (int_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_ADD, [], annot), + Item_t (Int_t tn1, Item_t (Int_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IAdd_int (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_ADD, [], annot), + Item_t (Int_t tname, Item_t (Nat_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IAdd_int (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_ADD, [], annot), + Item_t (Nat_t _, Item_t (Int_t tname, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IAdd_int (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_ADD, [], annot), + Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IAdd_nat (kinfo, k))} in + let stack = Item_t (Nat_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_SUB, [], annot), + Item_t (Int_t tn1, Item_t (Int_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> ISub_int (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_SUB, [], annot), + Item_t (Int_t tname, Item_t (Nat_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISub_int (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_SUB, [], annot), + Item_t (Nat_t _, Item_t (Int_t tname, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISub_int (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_SUB, [], annot), + Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun _tname -> + let instr = {apply = (fun kinfo k -> ISub_int (kinfo, k))} in + let stack = Item_t (int_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Int_t tn1, Item_t (Int_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IMul_int (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Int_t tname, Item_t (Nat_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_int (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Nat_t _, Item_t (Int_t tname, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_nat (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IMul_nat (kinfo, k))} in + let stack = Item_t (Nat_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_EDIV, [], annot), + Item_t (Mutez_t tname, Item_t (Nat_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IEdiv_teznat (kinfo, k))} in + let stack = Item_t (option_pair_mutez'_mutez'_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_EDIV, [], annot), + Item_t (Mutez_t tn1, Item_t (Mutez_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IEdiv_tez (kinfo, k))} in + let stack = Item_t (option_pair_nat_mutez'_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_EDIV, [], annot), + Item_t (Int_t tn1, Item_t (Int_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IEdiv_int (kinfo, k))} in + let stack = Item_t (option_pair_int'_nat_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_EDIV, [], annot), + Item_t (Int_t tname, Item_t (Nat_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IEdiv_int (kinfo, k))} in + let stack = Item_t (option_pair_int'_nat_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_EDIV, [], annot), + Item_t (Nat_t tname, Item_t (Int_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IEdiv_nat (kinfo, k))} in + let stack = Item_t (option_pair_int_nat'_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_EDIV, [], annot), + Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IEdiv_nat (kinfo, k))} in + let stack = Item_t (option_pair_nat'_nat'_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_LSL, [], annot), + Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> ILsl_nat (kinfo, k))} in + let stack = Item_t (Nat_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_LSR, [], annot), + Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> ILsr_nat (kinfo, k))} in + let stack = Item_t (Nat_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_OR, [], annot), + Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IOr_nat (kinfo, k))} in + let stack = Item_t (Nat_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_AND, [], annot), + Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IAnd_nat (kinfo, k))} in + let stack = Item_t (Nat_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_AND, [], annot), + Item_t (Int_t _, Item_t (Nat_t tname, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IAnd_int_nat (kinfo, k))} in + let stack = Item_t (Nat_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_XOR, [], annot), + Item_t (Nat_t tn1, Item_t (Nat_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IXor_nat (kinfo, k))} in + let stack = Item_t (Nat_t tname, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_NOT, [], annot), Item_t (Int_t tname, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INot_int (kinfo, k))} in + let stack = Item_t (Int_t tname, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_NOT, [], annot), Item_t (Nat_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INot_int (kinfo, k))} in + let stack = Item_t (int_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + (* comparison *) + | (Prim (loc, I_COMPARE, [], annot), Item_t (t1, Item_t (t2, rest, _), _)) -> + parse_var_annot loc annot >>?= fun annot -> + check_item_ty ctxt t1 t2 loc I_COMPARE 1 2 >>?= fun (Eq, t, ctxt) -> + comparable_ty_of_ty ctxt loc t >>?= fun (key, ctxt) -> + let instr = {apply = (fun kinfo k -> ICompare (kinfo, key, k))} in + let stack = Item_t (int_t ~annot:None, rest, annot) in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + (* comparators *) + | (Prim (loc, I_EQ, [], annot), Item_t (Int_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IEq (kinfo, k))} in + let stack = Item_t (bool_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_NEQ, [], annot), Item_t (Int_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INeq (kinfo, k))} in + let stack = Item_t (bool_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_LT, [], annot), Item_t (Int_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ILt (kinfo, k))} in + let stack = Item_t (bool_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_GT, [], annot), Item_t (Int_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IGt (kinfo, k))} in + let stack = Item_t (bool_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_LE, [], annot), Item_t (Int_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ILe (kinfo, k))} in + let stack = Item_t (bool_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_GE, [], annot), Item_t (Int_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IGe (kinfo, k))} in + let stack = Item_t (bool_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + (* annotations *) + | (Prim (loc, I_CAST, [cast_t], annot), Item_t (t, stack, item_annot)) -> + parse_var_annot loc annot ~default:item_annot >>?= fun annot -> + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy cast_t + >>?= fun (Ex_ty cast_t, ctxt) -> + ty_eq ~legacy ctxt loc cast_t t >>?= fun (Eq, ctxt) -> + let instr = {apply = (fun _ k -> k)} in + let stack = Item_t (cast_t, stack, annot) in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + | (Prim (loc, I_RENAME, [], annot), Item_t (t, stack, _)) -> + parse_var_annot loc annot >>?= fun annot -> + (* can erase annot *) + let instr = {apply = (fun _ k -> k)} in + let stack = Item_t (t, stack, annot) in + typed ctxt loc instr stack + (* packing *) + | (Prim (loc, I_PACK, [], annot), Item_t (t, rest, unpacked_annot)) -> + check_packable + ~legacy:true + (* allow to pack contracts for hash/signature checks *) loc + t + >>?= fun () -> + parse_var_annot + loc + annot + ~default:(gen_access_annot unpacked_annot default_pack_annot) + >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IPack (kinfo, t, k))} in + let stack = Item_t (bytes_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_UNPACK, [ty], annot), Item_t (Bytes_t _, rest, packed_annot)) + -> + parse_packable_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy ty + >>?= fun (Ex_ty t, ctxt) -> + parse_var_type_annot loc annot >>?= fun (annot, ty_name) -> + option_t loc t ~annot:ty_name >>?= fun res_ty -> + let annot = + default_annot + annot + ~default:(gen_access_annot packed_annot default_unpack_annot) + in + let instr = {apply = (fun kinfo k -> IUnpack (kinfo, t, k))} in + let stack = Item_t (res_ty, rest, annot) in + typed ctxt loc instr stack + (* protocol *) + | ( Prim (loc, I_ADDRESS, [], annot), + Item_t (Contract_t _, rest, contract_annot) ) -> + parse_var_annot + loc + annot + ~default:(gen_access_annot contract_annot default_addr_annot) + >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IAddress (kinfo, k))} in + let stack = Item_t (address_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_CONTRACT, [ty], annot), Item_t (Address_t _, rest, addr_annot)) + -> + parse_parameter_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy ty + >>?= fun (Ex_ty t, ctxt) -> + contract_t loc t ~annot:None >>?= fun contract_ty -> + option_t loc contract_ty ~annot:None >>?= fun res_ty -> + parse_entrypoint_annot + loc + annot + ~default:(gen_access_annot addr_annot default_contract_annot) + >>?= fun (annot, entrypoint) -> + (match entrypoint with + | None -> Ok "default" + | Some (Field_annot entrypoint) -> + let entrypoint = (entrypoint :> string) in + if Compare.String.(entrypoint = "default") then + error (Unexpected_annotation loc) + else if Compare.Int.(String.length entrypoint > 31) then + error (Entrypoint_name_too_long entrypoint) + else Ok entrypoint) + >>?= fun entrypoint -> + let instr = + {apply = (fun kinfo k -> IContract (kinfo, t, entrypoint, k))} + in + let stack = Item_t (res_ty, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_VIEW, [name; output_ty], annot), + Item_t (input_ty, Item_t (Address_t _, rest, addr_annot), _) ) -> + let output_ty_loc = location output_ty in + parse_view_name ctxt name >>?= fun (name, ctxt) -> + parse_view_output_ty ctxt ~stack_depth:0 ~legacy output_ty + >>?= fun (Ex_ty output_ty, ctxt) -> + option_t output_ty_loc output_ty ~annot:None >>?= fun res_ty -> + parse_var_annot + loc + annot + ~default:(gen_access_annot addr_annot default_contract_annot) + >>?= fun annot -> + let instr = + { + apply = + (fun kinfo k -> + IView (kinfo, View_signature {name; input_ty; output_ty}, k)); + } + in + let stack = Item_t (res_ty, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_TRANSFER_TOKENS, [], annot), + Item_t (p, Item_t (Mutez_t _, Item_t (Contract_t (cp, _), rest, _), _), _) + ) -> + check_item_ty ctxt p cp loc I_TRANSFER_TOKENS 1 4 + >>?= fun (Eq, _, ctxt) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ITransfer_tokens (kinfo, k))} in + let stack = Item_t (operation_t ~annot:None, rest, annot) in + (typed ctxt loc instr stack : ((a, s) judgement * context) tzresult Lwt.t) + | ( Prim (loc, I_SET_DELEGATE, [], annot), + Item_t (Option_t (Key_hash_t _, _), rest, _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISet_delegate (kinfo, k))} in + let stack = Item_t (operation_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (_, I_CREATE_ACCOUNT, _, _), _) -> + fail (Deprecated_instruction I_CREATE_ACCOUNT) + | (Prim (loc, I_IMPLICIT_ACCOUNT, [], annot), Item_t (Key_hash_t _, rest, _)) + -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IImplicit_account (kinfo, k))} in + let stack = Item_t (contract_unit_t, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_CREATE_CONTRACT, [(Seq _ as code)], annot), + Item_t + ( Option_t (Key_hash_t _, _), + Item_t (Mutez_t _, Item_t (ginit, rest, _), _), + _ ) ) -> + parse_two_var_annot loc annot >>?= fun (op_annot, addr_annot) -> + let canonical_code = Micheline.strip_locations code in + parse_toplevel ctxt ~legacy canonical_code + >>?= fun ({arg_type; storage_type; code_field; views; root_name}, ctxt) -> + record_trace + (Ill_formed_type (Some "parameter", canonical_code, location arg_type)) + (parse_parameter_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + arg_type) + >>?= fun (Ex_ty arg_type, ctxt) -> + (if legacy then Result.return_unit + else well_formed_entrypoints ~root_name arg_type) + >>?= fun () -> + record_trace + (Ill_formed_type (Some "storage", canonical_code, location storage_type)) + (parse_storage_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + storage_type) + >>?= fun (Ex_ty storage_type, ctxt) -> + let arg_annot = + default_annot + (type_to_var_annot (name_of_ty arg_type)) + ~default:default_param_annot + in + let storage_annot = + default_annot + (type_to_var_annot (name_of_ty storage_type)) + ~default:default_storage_annot + in + pair_t + loc + (arg_type, None, arg_annot) + (storage_type, None, storage_annot) + ~annot:None + >>?= fun arg_type_full -> + pair_t + loc + (list_operation_t, None, None) + (storage_type, None, None) + ~annot:None + >>?= fun ret_type_full -> + trace + (Ill_typed_contract (canonical_code, [])) + (parse_returning + (Toplevel {storage_type; param_type = arg_type; root_name}) + ctxt + ~legacy + ?type_logger + ~stack_depth:(stack_depth + 1) + (arg_type_full, None) + ret_type_full + code_field) + >>=? fun ( (Lam + ( { + kbef = Item_t (arg, Bot_t, _); + kaft = Item_t (ret, Bot_t, _); + _; + }, + _ ) as lambda), + ctxt ) -> + let views_result = + typecheck_views ctxt ?type_logger ~legacy storage_type views + in + trace (Ill_typed_contract (canonical_code, [])) views_result + >>=? fun ctxt -> + ty_eq ~legacy ctxt loc arg arg_type_full >>?= fun (Eq, ctxt) -> + ty_eq ~legacy ctxt loc ret ret_type_full >>?= fun (Eq, ctxt) -> + ty_eq ~legacy ctxt loc storage_type ginit >>?= fun (Eq, ctxt) -> + let instr = + { + apply = + (fun kinfo k -> + ICreate_contract + {kinfo; storage_type; arg_type; lambda; views; root_name; k}); + } + in + let stack = + Item_t + ( operation_t ~annot:None, + Item_t (address_t ~annot:None, rest, addr_annot), + op_annot ) + in + typed ctxt loc instr stack + | (Prim (loc, I_NOW, [], annot), stack) -> + parse_var_annot loc annot ~default:default_now_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INow (kinfo, k))} in + let stack = Item_t (timestamp_t ~annot:None, stack, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_AMOUNT, [], annot), stack) -> + parse_var_annot loc annot ~default:default_amount_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IAmount (kinfo, k))} in + let stack = Item_t (mutez_t ~annot:None, stack, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_CHAIN_ID, [], annot), stack) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IChainId (kinfo, k))} in + let stack = Item_t (chain_id_t ~annot:None, stack, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_BALANCE, [], annot), stack) -> + parse_var_annot loc annot ~default:default_balance_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IBalance (kinfo, k))} in + let stack = Item_t (mutez_t ~annot:None, stack, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_LEVEL, [], annot), stack) -> + parse_var_annot loc annot ~default:default_level_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ILevel (kinfo, k))} in + let stack = Item_t (nat_t ~annot:None, stack, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_VOTING_POWER, [], annot), Item_t (Key_hash_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IVoting_power (kinfo, k))} in + let stack = Item_t (nat_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_TOTAL_VOTING_POWER, [], annot), stack) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ITotal_voting_power (kinfo, k))} in + let stack = Item_t (nat_t ~annot:None, stack, annot) in + typed ctxt loc instr stack + | (Prim (_, I_STEPS_TO_QUOTA, _, _), _) -> + fail (Deprecated_instruction I_STEPS_TO_QUOTA) + | (Prim (loc, I_SOURCE, [], annot), stack) -> + parse_var_annot loc annot ~default:default_source_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISource (kinfo, k))} in + let stack = Item_t (address_t ~annot:None, stack, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_SENDER, [], annot), stack) -> + parse_var_annot loc annot ~default:default_sender_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISender (kinfo, k))} in + let stack = Item_t (address_t ~annot:None, stack, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_SELF, [], annot), stack) -> + Lwt.return + ( parse_entrypoint_annot loc annot ~default:default_self_annot + >>? fun (annot, entrypoint) -> + let entrypoint = + Option.fold + ~some:(fun (Field_annot annot) -> (annot :> string)) + ~none:"default" + entrypoint + in + let rec get_toplevel_type : + tc_context -> ((a, s) judgement * context) tzresult = function + | Lambda -> error (Self_in_lambda loc) + | Dip (_, prev) -> get_toplevel_type prev + | Toplevel {param_type; root_name; storage_type = _} -> + find_entrypoint param_type ~root_name entrypoint + >>? fun (_, Ex_ty param_type) -> + contract_t loc param_type ~annot:None >>? fun res_ty -> + let instr = + { + apply = + (fun kinfo k -> ISelf (kinfo, param_type, entrypoint, k)); + } + in + let stack = Item_t (res_ty, stack, annot) in + typed_no_lwt ctxt loc instr stack + in + get_toplevel_type tc_context ) + | (Prim (loc, I_SELF_ADDRESS, [], annot), stack) -> + parse_var_annot loc annot ~default:default_self_annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISelf_address (kinfo, k))} in + let stack = Item_t (address_t ~annot:None, stack, annot) in + typed ctxt loc instr stack + (* cryptography *) + | (Prim (loc, I_HASH_KEY, [], annot), Item_t (Key_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IHash_key (kinfo, k))} in + let stack = Item_t (key_hash_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_CHECK_SIGNATURE, [], annot), + Item_t (Key_t _, Item_t (Signature_t _, Item_t (Bytes_t _, rest, _), _), _) + ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ICheck_signature (kinfo, k))} in + let stack = Item_t (bool_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_BLAKE2B, [], annot), Item_t (Bytes_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IBlake2b (kinfo, k))} in + let stack = Item_t (bytes_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_SHA256, [], annot), Item_t (Bytes_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISha256 (kinfo, k))} in + let stack = Item_t (bytes_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_SHA512, [], annot), Item_t (Bytes_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISha512 (kinfo, k))} in + let stack = Item_t (bytes_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_KECCAK, [], annot), Item_t (Bytes_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IKeccak (kinfo, k))} in + let stack = Item_t (bytes_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_SHA3, [], annot), Item_t (Bytes_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> ISha3 (kinfo, k))} in + let stack = Item_t (bytes_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_ADD, [], annot), + Item_t (Bls12_381_g1_t tn1, Item_t (Bls12_381_g1_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IAdd_bls12_381_g1 (kinfo, k))} in + let stack = Item_t (Bls12_381_g1_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_ADD, [], annot), + Item_t (Bls12_381_g2_t tn1, Item_t (Bls12_381_g2_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IAdd_bls12_381_g2 (kinfo, k))} in + let stack = Item_t (Bls12_381_g2_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_ADD, [], annot), + Item_t (Bls12_381_fr_t tn1, Item_t (Bls12_381_fr_t tn2, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + merge_type_metadata ~legacy tn1 tn2 >>?= fun tname -> + let instr = {apply = (fun kinfo k -> IAdd_bls12_381_fr (kinfo, k))} in + let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Bls12_381_g1_t tname, Item_t (Bls12_381_fr_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_bls12_381_g1 (kinfo, k))} in + let stack = Item_t (Bls12_381_g1_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Bls12_381_g2_t tname, Item_t (Bls12_381_fr_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_bls12_381_g2 (kinfo, k))} in + let stack = Item_t (Bls12_381_g2_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Bls12_381_fr_t tname, Item_t (Bls12_381_fr_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_bls12_381_fr (kinfo, k))} in + let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Nat_t {annot = tname; _}, Item_t (Bls12_381_fr_t _, rest, _), _) + ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_bls12_381_fr_z (kinfo, k))} in + let stack = Item_t (bls12_381_fr_t ~annot:tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Int_t {annot = tname; _}, Item_t (Bls12_381_fr_t _, rest, _), _) + ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_bls12_381_fr_z (kinfo, k))} in + let stack = Item_t (bls12_381_fr_t ~annot:tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Bls12_381_fr_t tname, Item_t (Int_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_bls12_381_z_fr (kinfo, k))} in + let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_MUL, [], annot), + Item_t (Bls12_381_fr_t tname, Item_t (Nat_t _, rest, _), _) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IMul_bls12_381_z_fr (kinfo, k))} in + let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_INT, [], annot), Item_t (Bls12_381_fr_t _, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> IInt_bls12_381_fr (kinfo, k))} in + let stack = Item_t (int_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_NEG, [], annot), Item_t (Bls12_381_g1_t tname, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INeg_bls12_381_g1 (kinfo, k))} in + let stack = Item_t (Bls12_381_g1_t tname, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_NEG, [], annot), Item_t (Bls12_381_g2_t tname, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INeg_bls12_381_g2 (kinfo, k))} in + let stack = Item_t (Bls12_381_g2_t tname, rest, annot) in + typed ctxt loc instr stack + | (Prim (loc, I_NEG, [], annot), Item_t (Bls12_381_fr_t tname, rest, _)) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = {apply = (fun kinfo k -> INeg_bls12_381_fr (kinfo, k))} in + let stack = Item_t (Bls12_381_fr_t tname, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_PAIRING_CHECK, [], annot), + Item_t + ( List_t + (Pair_t ((Bls12_381_g1_t _, _, _), (Bls12_381_g2_t _, _, _), _), _), + rest, + _ ) ) -> + parse_var_annot loc annot >>?= fun annot -> + let instr = + {apply = (fun kinfo k -> IPairing_check_bls12_381 (kinfo, k))} + in + let stack = Item_t (bool_t ~annot:None, rest, annot) in + typed ctxt loc instr stack + (* Tickets *) + | (Prim (loc, I_TICKET, [], annot), Item_t (t, Item_t (Nat_t _, rest, _), _)) + -> + parse_var_annot loc annot >>?= fun annot -> + comparable_ty_of_ty ctxt loc t >>?= fun (ty, ctxt) -> + ticket_t loc ty ~annot:None >>?= fun res_ty -> + let instr = {apply = (fun kinfo k -> ITicket (kinfo, k))} in + let stack = Item_t (res_ty, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_READ_TICKET, [], annot), + (Item_t (Ticket_t (t, _), _, _) as full_stack) ) -> + parse_var_annot loc annot >>?= fun annot -> + let () = check_dupable_comparable_ty t in + opened_ticket_type loc t >>?= fun opened_ticket_ty -> + let result = ty_of_comparable_ty opened_ticket_ty in + let instr = {apply = (fun kinfo k -> IRead_ticket (kinfo, k))} in + let stack = Item_t (result, full_stack, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_SPLIT_TICKET, [], annot), + Item_t + ( (Ticket_t (t, _) as ticket_t), + Item_t + (Pair_t ((Nat_t _, fa_a, a_a), (Nat_t _, fa_b, a_b), _), rest, _), + _ ) ) -> + parse_var_annot loc annot >>?= fun annot -> + let () = check_dupable_comparable_ty t in + pair_t loc (ticket_t, fa_a, a_a) (ticket_t, fa_b, a_b) ~annot:None + >>?= fun pair_tickets_ty -> + option_t loc pair_tickets_ty ~annot:None >>?= fun res_ty -> + let instr = {apply = (fun kinfo k -> ISplit_ticket (kinfo, k))} in + let stack = Item_t (res_ty, rest, annot) in + typed ctxt loc instr stack + | ( Prim (loc, I_JOIN_TICKETS, [], annot), + Item_t + ( Pair_t (((Ticket_t _ as ty_a), _, _), ((Ticket_t _ as ty_b), _, _), _), + rest, + _ ) ) -> ( + parse_var_annot loc annot >>?= fun annot -> + Gas_monad.run ctxt + @@ merge_types + ~legacy + ~merge_type_error_flag:Default_merge_type_error + loc + ty_a + ty_b + >>?= fun (eq_ty, ctxt) -> + eq_ty >>?= fun (Eq, ty) -> + match ty with + | Ticket_t (contents_ty, _) -> + option_t loc ty ~annot:None >>?= fun res_ty -> + let instr = + {apply = (fun kinfo k -> IJoin_tickets (kinfo, contents_ty, k))} + in + let stack = Item_t (res_ty, rest, annot) in + typed ctxt loc instr stack + | _ -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/1962 + fix injectivity of types *) + assert false) + (* Timelocks *) + | ( Prim (loc, I_OPEN_CHEST, [], _), + Item_t (Chest_key_t _, Item_t (Chest_t _, Item_t (Nat_t _, rest, _), _), _) + ) -> + let instr = {apply = (fun kinfo k -> IOpen_chest (kinfo, k))} in + typed ctxt loc instr (Item_t (union_bytes_bool_t, rest, None)) + (* Primitive parsing errors *) + | ( Prim + ( loc, + (( I_DUP | I_SWAP | I_SOME | I_UNIT | I_PAIR | I_UNPAIR | I_CAR + | I_CDR | I_CONS | I_CONCAT | I_SLICE | I_MEM | I_UPDATE | I_GET + | I_EXEC | I_FAILWITH | I_SIZE | I_ADD | I_SUB | I_SUB_MUTEZ | I_MUL + | I_EDIV | I_OR | I_AND | I_XOR | I_NOT | I_ABS | I_NEG | I_LSL + | I_LSR | I_COMPARE | I_EQ | I_NEQ | I_LT | I_GT | I_LE | I_GE + | I_TRANSFER_TOKENS | I_SET_DELEGATE | I_NOW | I_IMPLICIT_ACCOUNT + | I_AMOUNT | I_BALANCE | I_LEVEL | I_CHECK_SIGNATURE | I_HASH_KEY + | I_SOURCE | I_SENDER | I_BLAKE2B | I_SHA256 | I_SHA512 | I_ADDRESS + | I_RENAME | I_PACK | I_ISNAT | I_INT | I_SELF | I_CHAIN_ID | I_NEVER + | I_VOTING_POWER | I_TOTAL_VOTING_POWER | I_KECCAK | I_SHA3 + | I_PAIRING_CHECK | I_TICKET | I_READ_TICKET | I_SPLIT_TICKET + | I_JOIN_TICKETS | I_OPEN_CHEST ) as name), + (_ :: _ as l), + _ ), + _ ) -> + fail (Invalid_arity (loc, name, 0, List.length l)) + | ( Prim + ( loc, + (( I_NONE | I_LEFT | I_RIGHT | I_NIL | I_MAP | I_ITER | I_EMPTY_SET + | I_LOOP | I_LOOP_LEFT | I_CONTRACT | I_CAST | I_UNPACK + | I_CREATE_CONTRACT ) as name), + (([] | _ :: _ :: _) as l), + _ ), + _ ) -> + fail (Invalid_arity (loc, name, 1, List.length l)) + | ( Prim + ( loc, + (( I_PUSH | I_VIEW | I_IF_NONE | I_IF_LEFT | I_IF_CONS | I_EMPTY_MAP + | I_EMPTY_BIG_MAP | I_IF ) as name), + (([] | [_] | _ :: _ :: _ :: _) as l), + _ ), + _ ) -> + fail (Invalid_arity (loc, name, 2, List.length l)) + | ( Prim (loc, I_LAMBDA, (([] | [_] | [_; _] | _ :: _ :: _ :: _ :: _) as l), _), + _ ) -> + fail (Invalid_arity (loc, I_LAMBDA, 3, List.length l)) + (* Stack errors *) + | ( Prim + ( loc, + (( I_ADD | I_SUB | I_SUB_MUTEZ | I_MUL | I_EDIV | I_AND | I_OR | I_XOR + | I_LSL | I_LSR | I_CONCAT | I_PAIRING_CHECK ) as name), + [], + _ ), + Item_t (ta, Item_t (tb, _, _), _) ) -> + let ta = serialize_ty_for_error ta in + let tb = serialize_ty_for_error tb in + fail (Undefined_binop (loc, name, ta, tb)) + | ( Prim + ( loc, + (( I_NEG | I_ABS | I_NOT | I_SIZE | I_EQ | I_NEQ | I_LT | I_GT | I_LE + | I_GE + (* CONCAT is both unary and binary; this case can only be triggered + on a singleton stack *) + | I_CONCAT ) as name), + [], + _ ), + Item_t (t, _, _) ) -> + let t = serialize_ty_for_error t in + fail (Undefined_unop (loc, name, t)) + | (Prim (loc, ((I_UPDATE | I_SLICE | I_OPEN_CHEST) as name), [], _), stack) -> + Lwt.return + (let stack = serialize_stack_for_error ctxt stack in + error (Bad_stack (loc, name, 3, stack))) + | (Prim (loc, I_CREATE_CONTRACT, _, _), stack) -> + let stack = serialize_stack_for_error ctxt stack in + fail (Bad_stack (loc, I_CREATE_CONTRACT, 7, stack)) + | (Prim (loc, I_TRANSFER_TOKENS, [], _), stack) -> + Lwt.return + (let stack = serialize_stack_for_error ctxt stack in + error (Bad_stack (loc, I_TRANSFER_TOKENS, 4, stack))) + | ( Prim + ( loc, + (( I_DROP | I_DUP | I_CAR | I_CDR | I_UNPAIR | I_SOME | I_BLAKE2B + | I_SHA256 | I_SHA512 | I_DIP | I_IF_NONE | I_LEFT | I_RIGHT + | I_IF_LEFT | I_IF | I_LOOP | I_IF_CONS | I_IMPLICIT_ACCOUNT | I_NEG + | I_ABS | I_INT | I_NOT | I_HASH_KEY | I_EQ | I_NEQ | I_LT | I_GT + | I_LE | I_GE | I_SIZE | I_FAILWITH | I_RENAME | I_PACK | I_ISNAT + | I_ADDRESS | I_SET_DELEGATE | I_CAST | I_MAP | I_ITER | I_LOOP_LEFT + | I_UNPACK | I_CONTRACT | I_NEVER | I_KECCAK | I_SHA3 | I_READ_TICKET + | I_JOIN_TICKETS ) as name), + _, + _ ), + stack ) -> + Lwt.return + (let stack = serialize_stack_for_error ctxt stack in + error (Bad_stack (loc, name, 1, stack))) + | ( Prim + ( loc, + (( I_SWAP | I_PAIR | I_CONS | I_GET | I_MEM | I_EXEC + | I_CHECK_SIGNATURE | I_ADD | I_SUB | I_SUB_MUTEZ | I_MUL | I_EDIV + | I_AND | I_OR | I_XOR | I_LSL | I_LSR | I_COMPARE | I_PAIRING_CHECK + | I_TICKET | I_SPLIT_TICKET ) as name), + _, + _ ), + stack ) -> + Lwt.return + (let stack = serialize_stack_for_error ctxt stack in + error (Bad_stack (loc, name, 2, stack))) + (* Generic parsing errors *) + | (expr, _) -> + fail + @@ unexpected + expr + [Seq_kind] + Instr_namespace + [ + I_DROP; + I_DUP; + I_DIG; + I_DUG; + I_VIEW; + I_SWAP; + I_SOME; + I_UNIT; + I_PAIR; + I_UNPAIR; + I_CAR; + I_CDR; + I_CONS; + I_MEM; + I_UPDATE; + I_MAP; + I_ITER; + I_GET; + I_GET_AND_UPDATE; + I_EXEC; + I_FAILWITH; + I_SIZE; + I_CONCAT; + I_ADD; + I_SUB; + I_SUB_MUTEZ; + I_MUL; + I_EDIV; + I_OR; + I_AND; + I_XOR; + I_NOT; + I_ABS; + I_INT; + I_NEG; + I_LSL; + I_LSR; + I_COMPARE; + I_EQ; + I_NEQ; + I_LT; + I_GT; + I_LE; + I_GE; + I_TRANSFER_TOKENS; + I_CREATE_CONTRACT; + I_NOW; + I_AMOUNT; + I_BALANCE; + I_LEVEL; + I_IMPLICIT_ACCOUNT; + I_CHECK_SIGNATURE; + I_BLAKE2B; + I_SHA256; + I_SHA512; + I_HASH_KEY; + I_PUSH; + I_NONE; + I_LEFT; + I_RIGHT; + I_NIL; + I_EMPTY_SET; + I_DIP; + I_LOOP; + I_IF_NONE; + I_IF_LEFT; + I_IF_CONS; + I_EMPTY_MAP; + I_EMPTY_BIG_MAP; + I_IF; + I_SOURCE; + I_SENDER; + I_SELF; + I_SELF_ADDRESS; + I_LAMBDA; + I_NEVER; + I_VOTING_POWER; + I_TOTAL_VOTING_POWER; + I_KECCAK; + I_SHA3; + I_PAIRING_CHECK; + I_SAPLING_EMPTY_STATE; + I_SAPLING_VERIFY_UPDATE; + I_TICKET; + I_READ_TICKET; + I_SPLIT_TICKET; + I_JOIN_TICKETS; + I_OPEN_CHEST; + ] + +and[@coq_axiom_with_reason "complex mutually recursive definition"] parse_contract : + type arg. + stack_depth:int -> + legacy:bool -> + context -> + Script.location -> + arg ty -> + Contract.t -> + entrypoint:string -> + (context * arg typed_contract) tzresult Lwt.t = + fun ~stack_depth ~legacy ctxt loc arg contract ~entrypoint -> + match Contract.is_implicit contract with + | Some _ -> ( + match entrypoint with + | "default" -> + (* An implicit account on the "default" entrypoint always exists and has type unit. *) + Lwt.return + ( ty_eq ~legacy:true ctxt loc arg (unit_t ~annot:None) + >|? fun (Eq, ctxt) -> + let contract : arg typed_contract = + (arg, (contract, entrypoint)) + in + (ctxt, contract) ) + | _ -> fail (No_such_entrypoint entrypoint)) + | None -> ( + (* Originated account *) + trace (Invalid_contract (loc, contract)) + @@ Contract.get_script_code ctxt contract + >>=? fun (ctxt, code) -> + match code with + | None -> fail (Invalid_contract (loc, contract)) + | Some code -> + Lwt.return + ( Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + code + >>? fun (code, ctxt) -> + (* can only fail because of gas *) + parse_toplevel ctxt ~legacy:true code + >>? fun ({arg_type; root_name; _}, ctxt) -> + parse_parameter_ty + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy:true + arg_type + >>? fun (Ex_ty targ, ctxt) -> + (* we don't check targ size here because it's a legacy contract code *) + Gas_monad.run ctxt + @@ find_entrypoint_for_type + ~legacy + ~merge_type_error_flag:Default_merge_type_error + ~full:targ + ~expected:arg + ~root_name + entrypoint + loc + >>? fun (entrypoint_arg, ctxt) -> + entrypoint_arg >|? fun (entrypoint, arg) -> + let contract : arg typed_contract = + (arg, (contract, entrypoint)) + in + (ctxt, contract) )) + +and parse_view_name ctxt : Script.node -> (Script_string.t * context) tzresult = + function + | String (loc, v) as expr -> + (* The limitation of length of string is same as entrypoint *) + if Compare.Int.(String.length v > 31) then error (View_name_too_long v) + else + let rec check_char i = + if Compare.Int.(i < 0) then ok v + else if Script_ir_annot.is_allowed_char v.[i] then check_char (i - 1) + else error (Bad_view_name loc) + in + Gas.consume ctxt (Typecheck_costs.check_printable v) >>? fun ctxt -> + record_trace + (Invalid_syntactic_constant + ( loc, + strip_locations expr, + "string [a-zA-Z0-9_.%@] and the maximum string length of 31 \ + characters" )) + ( check_char (String.length v - 1) >>? fun v -> + Script_string.of_string v >|? fun s -> (s, ctxt) ) + | expr -> error @@ Invalid_kind (location expr, [String_kind], kind expr) + +and parse_toplevel : + context -> legacy:bool -> Script.expr -> (toplevel * context) tzresult = + fun ctxt ~legacy toplevel -> + record_trace (Ill_typed_contract (toplevel, [])) + @@ + match root toplevel with + | Int (loc, _) -> error (Invalid_kind (loc, [Seq_kind], Int_kind)) + | String (loc, _) -> error (Invalid_kind (loc, [Seq_kind], String_kind)) + | Bytes (loc, _) -> error (Invalid_kind (loc, [Seq_kind], Bytes_kind)) + | Prim (loc, _, _, _) -> error (Invalid_kind (loc, [Seq_kind], Prim_kind)) + | Seq (_, fields) -> ( + let rec find_fields ctxt p s c views fields = + match fields with + | [] -> ok (ctxt, (p, s, c, views)) + | Int (loc, _) :: _ -> error (Invalid_kind (loc, [Prim_kind], Int_kind)) + | String (loc, _) :: _ -> + error (Invalid_kind (loc, [Prim_kind], String_kind)) + | Bytes (loc, _) :: _ -> + error (Invalid_kind (loc, [Prim_kind], Bytes_kind)) + | Seq (loc, _) :: _ -> error (Invalid_kind (loc, [Prim_kind], Seq_kind)) + | Prim (loc, K_parameter, [arg], annot) :: rest -> ( + match p with + | None -> find_fields ctxt (Some (arg, loc, annot)) s c views rest + | Some _ -> error (Duplicate_field (loc, K_parameter))) + | Prim (loc, K_storage, [arg], annot) :: rest -> ( + match s with + | None -> find_fields ctxt p (Some (arg, loc, annot)) c views rest + | Some _ -> error (Duplicate_field (loc, K_storage))) + | Prim (loc, K_code, [arg], annot) :: rest -> ( + match c with + | None -> find_fields ctxt p s (Some (arg, loc, annot)) views rest + | Some _ -> error (Duplicate_field (loc, K_code))) + | Prim (loc, ((K_parameter | K_storage | K_code) as name), args, _) :: _ + -> + error (Invalid_arity (loc, name, 1, List.length args)) + | Prim (loc, K_view, [name; input_ty; output_ty; view_code], _) :: rest + -> + parse_view_name ctxt name >>? fun (str, ctxt) -> + Gas.consume + ctxt + (Michelson_v1_gas.Cost_of.Interpreter.view_update str views) + >>? fun ctxt -> + if SMap.mem str views then error (Duplicated_view_name loc) + else + let views' = + SMap.add str {input_ty; output_ty; view_code} views + in + find_fields ctxt p s c views' rest + | Prim (loc, K_view, args, _) :: _ -> + error (Invalid_arity (loc, K_view, 4, List.length args)) + | Prim (loc, name, _, _) :: _ -> + let allowed = [K_parameter; K_storage; K_code; K_view] in + error (Invalid_primitive (loc, allowed, name)) + in + find_fields ctxt None None None SMap.empty fields + >>? fun (ctxt, toplevel) -> + match toplevel with + | (None, _, _, _) -> error (Missing_field K_parameter) + | (Some _, None, _, _) -> error (Missing_field K_storage) + | (Some _, Some _, None, _) -> error (Missing_field K_code) + | ( Some (p, ploc, pannot), + Some (s, sloc, sannot), + Some (c, cloc, carrot), + views ) -> + let maybe_root_name = + (* root name can be attached to either the parameter + primitive or the toplevel constructor *) + 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) + && Compare.Char.(single.[0] = '%') -> + parse_field_annot ploc [single] >>? fun pannot -> + ok (p, [], pannot) + | _ -> ok (p, pannot, None)) + in + (if legacy then + (* legacy semantics ignores spurious annotations *) + match maybe_root_name with + | Ok (p, _, root_name) -> ok (p, root_name) + | Error _ -> ok (p, None) + else + (* only one field annot is allowed to set the root entrypoint name *) + maybe_root_name >>? fun (p, pannot, root_name) -> + Script_ir_annot.error_unexpected_annot ploc pannot >>? fun () -> + Script_ir_annot.error_unexpected_annot cloc carrot >>? fun () -> + Script_ir_annot.error_unexpected_annot sloc sannot >|? fun () -> + (p, root_name)) + >|? fun (arg_type, root_name) -> + ({code_field = c; arg_type; root_name; views; storage_type = s}, ctxt) + ) + +(* Same as [parse_contract], but does not fail when the contact is missing or + if the expected type doesn't match the actual one. In that case None is + returned and some overapproximation of the typechecking gas is consumed. + This can still fail on gas exhaustion. *) +let parse_contract_for_script : + type arg. + context -> + Script.location -> + arg ty -> + Contract.t -> + entrypoint:string -> + (context * arg typed_contract option) tzresult Lwt.t = + fun ctxt loc arg contract ~entrypoint -> + match Contract.is_implicit contract with + | Some _ -> ( + match entrypoint with + | "default" -> + (* An implicit account on the "default" entrypoint always exists and has type unit. *) + Lwt.return + ( Gas_monad.run ctxt + @@ merge_types + ~legacy:true + ~merge_type_error_flag:Fast_merge_type_error + loc + arg + (unit_t ~annot:None) + >|? fun (eq_ty, ctxt) -> + match eq_ty with + | Ok (Eq, _ty) -> + let contract : arg typed_contract = + (arg, (contract, entrypoint)) + in + (ctxt, Some contract) + | Error _ -> (ctxt, None) ) + | _ -> + Lwt.return + ( Gas.consume ctxt Typecheck_costs.parse_instr_cycle >|? fun ctxt -> + (* An implicit account on any other entrypoint is not a valid contract. *) + (ctxt, None) )) + | None -> ( + (* Originated account *) + trace (Invalid_contract (loc, contract)) + @@ Contract.get_script_code ctxt contract + >>=? fun (ctxt, code) -> + match code with + | None -> return (ctxt, None) + | Some code -> + Lwt.return + ( Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + code + >>? fun (code, ctxt) -> + (* can only fail because of gas *) + match parse_toplevel ctxt ~legacy:true code with + | Error _ -> error (Invalid_contract (loc, contract)) + | Ok ({arg_type; root_name; _}, ctxt) -> ( + match + parse_parameter_ty ctxt ~stack_depth:0 ~legacy:true arg_type + with + | Error _ -> error (Invalid_contract (loc, contract)) + | Ok (Ex_ty targ, ctxt) -> ( + (* we don't check targ size here because it's a legacy contract code *) + Gas_monad.run ctxt + @@ find_entrypoint_for_type + ~legacy:false + ~merge_type_error_flag:Fast_merge_type_error + ~full:targ + ~expected:arg + ~root_name + entrypoint + loc + >|? fun (entrypoint_arg, ctxt) -> + match entrypoint_arg with + | Ok (entrypoint, arg) -> + let contract : arg typed_contract = + (arg, (contract, entrypoint)) + in + (ctxt, Some contract) + | Error _ -> (ctxt, None))) )) + +let parse_code : + ?type_logger:type_logger -> + context -> + legacy:bool -> + code:lazy_expr -> + (ex_code * context) tzresult Lwt.t = + fun ?type_logger ctxt ~legacy ~code -> + Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + code + >>?= fun (code, ctxt) -> + Global_constants_storage.expand ctxt code >>=? fun (ctxt, code) -> + parse_toplevel ctxt ~legacy code + >>?= fun ({arg_type; storage_type; code_field; views; root_name}, ctxt) -> + let arg_type_loc = location arg_type in + record_trace + (Ill_formed_type (Some "parameter", code, arg_type_loc)) + (parse_parameter_ty ctxt ~stack_depth:0 ~legacy arg_type) + >>?= fun (Ex_ty arg_type, ctxt) -> + (if legacy then Result.return_unit + else well_formed_entrypoints ~root_name arg_type) + >>?= fun () -> + let storage_type_loc = location storage_type in + record_trace + (Ill_formed_type (Some "storage", code, storage_type_loc)) + (parse_storage_ty ctxt ~stack_depth:0 ~legacy storage_type) + >>?= fun (Ex_ty storage_type, ctxt) -> + let arg_annot = + default_annot + (type_to_var_annot (name_of_ty arg_type)) + ~default:default_param_annot + in + let storage_annot = + default_annot + (type_to_var_annot (name_of_ty storage_type)) + ~default:default_storage_annot + in + + pair_t + storage_type_loc + (arg_type, None, arg_annot) + (storage_type, None, storage_annot) + ~annot:None + >>?= fun arg_type_full -> + pair_t + storage_type_loc + (list_operation_t, None, None) + (storage_type, None, None) + ~annot:None + >>?= fun ret_type_full -> + trace + (Ill_typed_contract (code, [])) + (parse_returning + (Toplevel {storage_type; param_type = arg_type; root_name}) + ctxt + ~legacy + ~stack_depth:0 + ?type_logger + (arg_type_full, None) + ret_type_full + code_field) + >>=? fun (code, ctxt) -> + Lwt.return + (let open Script_typed_ir_size in + let view_size view = + node_size view.view_code ++ node_size view.input_ty + ++ node_size view.output_ty + in + let views_size = SMap.fold (fun _ v s -> view_size v ++ s) views zero in + (* The size of the storage_type and the arg_type is counted by + [lambda_size]. *) + let ir_size = lambda_size code in + let (nodes, code_size) = views_size ++ ir_size in + (* We consume gas after the fact in order to not have to instrument + [node_size] (for efficiency). + This is safe, as we already pay gas proportional to [views_size] + and [ir_size] during their typechecking. *) + Gas.consume ctxt (Script_typed_ir_size_costs.nodes_cost ~nodes) + >>? fun ctxt -> + ok + (Ex_code {code; arg_type; storage_type; views; root_name; code_size}, ctxt)) + +let parse_storage : + ?type_logger:type_logger -> + context -> + legacy:bool -> + allow_forged:bool -> + 'storage ty -> + storage:lazy_expr -> + ('storage * context) tzresult Lwt.t = + fun ?type_logger ctxt ~legacy ~allow_forged storage_type ~storage -> + Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + storage + >>?= fun (storage, ctxt) -> + trace_eval + (fun () -> + let storage_type = serialize_ty_for_error storage_type in + Ill_typed_data (None, storage, storage_type)) + (parse_data + ?type_logger + ~stack_depth:0 + ctxt + ~legacy + ~allow_forged + storage_type + (root storage)) + +let[@coq_axiom_with_reason "gadt"] parse_script : + ?type_logger:type_logger -> + context -> + legacy:bool -> + allow_forged_in_storage:bool -> + Script.t -> + (ex_script * context) tzresult Lwt.t = + fun ?type_logger ctxt ~legacy ~allow_forged_in_storage {code; storage} -> + parse_code ~legacy ctxt ?type_logger ~code + >>=? fun ( Ex_code {code; arg_type; storage_type; views; root_name; code_size}, + ctxt ) -> + parse_storage + ?type_logger + ctxt + ~legacy + ~allow_forged:allow_forged_in_storage + storage_type + ~storage + >|=? fun (storage, ctxt) -> + ( Ex_script + {code_size; code; arg_type; storage; storage_type; views; root_name}, + ctxt ) + +let typecheck_code : + legacy:bool -> + show_types:bool -> + context -> + Script.expr -> + (type_map * context) tzresult Lwt.t = + fun ~legacy ~show_types ctxt code -> + (* Constants need to be expanded or [parse_toplevel] may fail. *) + Global_constants_storage.expand ctxt code >>=? fun (ctxt, code) -> + parse_toplevel ctxt ~legacy code + >>?= fun ({arg_type; storage_type; code_field; views; root_name}, ctxt) -> + let type_map = ref [] in + let arg_type_loc = location arg_type in + record_trace + (Ill_formed_type (Some "parameter", code, arg_type_loc)) + (parse_parameter_ty ctxt ~stack_depth:0 ~legacy arg_type) + >>?= fun (Ex_ty arg_type, ctxt) -> + (if legacy then Result.return_unit + else well_formed_entrypoints ~root_name arg_type) + >>?= fun () -> + let storage_type_loc = location storage_type in + record_trace + (Ill_formed_type (Some "storage", code, storage_type_loc)) + (parse_storage_ty ctxt ~stack_depth:0 ~legacy storage_type) + >>?= fun (Ex_ty storage_type, ctxt) -> + let arg_annot = + default_annot + (type_to_var_annot (name_of_ty arg_type)) + ~default:default_param_annot + in + let storage_annot = + default_annot + (type_to_var_annot (name_of_ty storage_type)) + ~default:default_storage_annot + in + pair_t + storage_type_loc + (arg_type, None, arg_annot) + (storage_type, None, storage_annot) + ~annot:None + >>?= fun arg_type_full -> + pair_t + storage_type_loc + (list_operation_t, None, None) + (storage_type, None, None) + ~annot:None + >>?= fun ret_type_full -> + let type_logger loc bef aft = type_map := (loc, (bef, aft)) :: !type_map in + let type_logger = if show_types then Some type_logger else None in + let result = + parse_returning + (Toplevel {storage_type; param_type = arg_type; root_name}) + ctxt + ~legacy + ~stack_depth:0 + ?type_logger + (arg_type_full, None) + ret_type_full + code_field + in + trace (Ill_typed_contract (code, !type_map)) result >>=? fun (Lam _, ctxt) -> + let views_result = + typecheck_views + ctxt + ~type_logger:(fun loc bef aft -> + type_map := (loc, (bef, aft)) :: !type_map) + ~legacy + storage_type + views + in + trace (Ill_typed_contract (code, !type_map)) views_result >|=? fun ctxt -> + (!type_map, ctxt) + +module Entrypoints_map = Map.Make (String) + +let list_entrypoints (type full) (full : full ty) ctxt ~root_name = + let merge path annot (type t) (ty : t ty) reachable + ((unreachables, all) as acc) = + match annot with + | None -> ( + ok + @@ + if reachable then acc + else + match ty with + | Union_t _ -> acc + | _ -> (List.rev path :: unreachables, all)) + | Some (Field_annot name) -> + let name = (name :> string) in + if Compare.Int.(String.length name > 31) then + ok (List.rev path :: unreachables, all) + else if Entrypoints_map.mem name all then + ok (List.rev path :: unreachables, all) + else + unparse_ty ~loc:() ctxt ty >>? fun (unparsed_ty, _) -> + ok + ( unreachables, + Entrypoints_map.add name (List.rev path, unparsed_ty) all ) + in + let rec fold_tree : + type t. + t ty -> + prim list -> + bool -> + prim list list + * (prim list * Script.unlocated_michelson_node) Entrypoints_map.t -> + (prim list list + * (prim list * Script.unlocated_michelson_node) Entrypoints_map.t) + tzresult = + fun t path reachable acc -> + match t with + | Union_t ((tl, al), (tr, ar), _) -> + merge (D_Left :: path) al tl reachable acc >>? fun acc -> + merge (D_Right :: path) ar tr reachable acc >>? fun acc -> + fold_tree + tl + (D_Left :: path) + (match al with Some _ -> true | None -> reachable) + acc + >>? fun acc -> + fold_tree + tr + (D_Right :: path) + (match ar with Some _ -> true | None -> reachable) + acc + | _ -> ok acc + in + unparse_ty ~loc:() ctxt full >>? fun (unparsed_full, _) -> + let (init, reachable) = + match root_name with + | None -> (Entrypoints_map.empty, false) + | Some (Field_annot name) -> + (Entrypoints_map.singleton (name :> string) ([], unparsed_full), true) + in + fold_tree full [] reachable ([], init) + [@@coq_axiom_with_reason "unsupported syntax"] + +(* ---- Unparsing (Typed IR -> Untyped expressions) --------------------------*) + +(* -- Unparsing data of any type -- *) + +let comb_witness2 : type t. t ty -> (t, unit -> unit -> unit) comb_witness = + function + | Pair_t (_, (Pair_t _, _, _), _) -> Comb_Pair (Comb_Pair Comb_Any) + | Pair_t _ -> Comb_Pair Comb_Any + | _ -> Comb_Any + +let[@coq_axiom_with_reason "gadt"] rec unparse_data : + type a. + context -> + stack_depth:int -> + unparsing_mode -> + a ty -> + a -> + (Script.node * context) tzresult Lwt.t = + fun ctxt ~stack_depth mode ty a -> + Gas.consume ctxt Unparse_costs.unparse_data_cycle >>?= fun ctxt -> + let non_terminal_recursion ctxt mode ty a = + if Compare.Int.(stack_depth > 10_000) then + fail Unparsing_too_many_recursive_calls + else unparse_data ctxt ~stack_depth:(stack_depth + 1) mode ty a + in + let loc = Micheline.dummy_location in + match (ty, a) with + | (Unit_t _, v) -> Lwt.return @@ unparse_unit ~loc ctxt v + | (Int_t _, v) -> Lwt.return @@ unparse_int ~loc ctxt v + | (Nat_t _, v) -> Lwt.return @@ unparse_nat ~loc ctxt v + | (String_t _, s) -> Lwt.return @@ unparse_string ~loc ctxt s + | (Bytes_t _, s) -> Lwt.return @@ unparse_bytes ~loc ctxt s + | (Bool_t _, b) -> Lwt.return @@ unparse_bool ~loc ctxt b + | (Timestamp_t _, t) -> Lwt.return @@ unparse_timestamp ~loc ctxt mode t + | (Address_t _, address) -> + Lwt.return @@ unparse_address ~loc ctxt mode address + | (Contract_t _, contract) -> + Lwt.return @@ unparse_contract ~loc ctxt mode contract + | (Signature_t _, s) -> Lwt.return @@ unparse_signature ~loc ctxt mode s + | (Mutez_t _, v) -> Lwt.return @@ unparse_mutez ~loc ctxt v + | (Key_t _, k) -> Lwt.return @@ unparse_key ~loc ctxt mode k + | (Key_hash_t _, k) -> Lwt.return @@ unparse_key_hash ~loc ctxt mode k + | (Operation_t _, operation) -> + Lwt.return @@ unparse_operation ~loc ctxt operation + | (Chain_id_t _, chain_id) -> + Lwt.return @@ unparse_chain_id ~loc ctxt mode chain_id + | (Bls12_381_g1_t _, x) -> Lwt.return @@ unparse_bls12_381_g1 ~loc ctxt x + | (Bls12_381_g2_t _, x) -> Lwt.return @@ unparse_bls12_381_g2 ~loc ctxt x + | (Bls12_381_fr_t _, x) -> Lwt.return @@ unparse_bls12_381_fr ~loc ctxt x + | (Pair_t ((tl, _, _), (tr, _, _), _), pair) -> + let r_witness = comb_witness2 tr in + let unparse_l ctxt v = non_terminal_recursion ctxt mode tl v in + let unparse_r ctxt v = non_terminal_recursion ctxt mode tr v in + unparse_pair ~loc unparse_l unparse_r ctxt mode r_witness pair + | (Union_t ((tl, _), (tr, _), _), v) -> + let unparse_l ctxt v = non_terminal_recursion ctxt mode tl v in + let unparse_r ctxt v = non_terminal_recursion ctxt mode tr v in + unparse_union ~loc unparse_l unparse_r ctxt v + | (Option_t (t, _), v) -> + let unparse_v ctxt v = non_terminal_recursion ctxt mode t v in + unparse_option ~loc unparse_v ctxt v + | (List_t (t, _), items) -> + List.fold_left_es + (fun (l, ctxt) element -> + non_terminal_recursion ctxt mode t element + >|=? fun (unparsed, ctxt) -> (unparsed :: l, ctxt)) + ([], ctxt) + items.elements + >|=? fun (items, ctxt) -> (Micheline.Seq (loc, List.rev items), ctxt) + | (Ticket_t (t, _), {ticketer; contents; amount}) -> + (* ideally we would like to allow a little overhead here because it is only used for unparsing *) + opened_ticket_type loc t >>?= fun opened_ticket_ty -> + let t = ty_of_comparable_ty opened_ticket_ty in + (unparse_data [@tailcall]) + ctxt + ~stack_depth + mode + t + ((ticketer, "default"), (contents, amount)) + | (Set_t (t, _), set) -> + List.fold_left_es + (fun (l, ctxt) item -> + unparse_comparable_data ~loc ctxt mode t item >|=? fun (item, ctxt) -> + (item :: l, ctxt)) + ([], ctxt) + (Script_set.fold (fun e acc -> e :: acc) set []) + >|=? fun (items, ctxt) -> (Micheline.Seq (loc, items), ctxt) + | (Map_t (kt, vt, _), map) -> + let items = Script_map.fold (fun k v acc -> (k, v) :: acc) map [] in + unparse_items ctxt ~stack_depth:(stack_depth + 1) mode kt vt items + >|=? fun (items, ctxt) -> (Micheline.Seq (loc, items), ctxt) + | (Big_map_t (_kt, _vt, _), {id = Some id; diff = {size; _}; _}) + when Compare.Int.( = ) size 0 -> + return (Micheline.Int (loc, Big_map.Id.unparse_to_z id), ctxt) + | (Big_map_t (kt, vt, _), {id = Some id; diff = {map; _}; _}) -> + let items = + Big_map_overlay.fold (fun _ (k, v) acc -> (k, v) :: acc) map [] + in + let items = + (* Sort the items in Michelson comparison order and not in key + hash order. This code path is only exercised for tracing, + so we don't bother carbonating this sort operation + precisely. Also, the sort uses a reverse compare because + [unparse_items] will reverse the result. *) + List.sort + (fun (a, _) (b, _) -> Script_comparable.compare_comparable kt b a) + items + in + (* this can't fail if the original type is well-formed + because [option vt] is always strictly smaller than [big_map kt vt] *) + option_t loc vt ~annot:None >>?= fun vt -> + unparse_items ctxt ~stack_depth:(stack_depth + 1) mode kt vt items + >|=? fun (items, ctxt) -> + ( Micheline.Prim + ( loc, + D_Pair, + [Int (loc, Big_map.Id.unparse_to_z id); Seq (loc, items)], + [] ), + ctxt ) + | (Big_map_t (kt, vt, _), {id = None; diff = {map; _}; _}) -> + let items = + Big_map_overlay.fold + (fun _ (k, v) acc -> + match v with None -> acc | Some v -> (k, v) :: acc) + map + [] + in + let items = + (* See note above. *) + List.sort + (fun (a, _) (b, _) -> Script_comparable.compare_comparable kt b a) + items + in + unparse_items ctxt ~stack_depth:(stack_depth + 1) mode kt vt items + >|=? fun (items, ctxt) -> (Micheline.Seq (loc, items), ctxt) + | (Lambda_t _, Lam (_, original_code)) -> + unparse_code ctxt ~stack_depth:(stack_depth + 1) mode original_code + | (Never_t _, _) -> . + | (Sapling_transaction_t _, s) -> + Lwt.return + ( Gas.consume ctxt (Unparse_costs.sapling_transaction s) >|? fun ctxt -> + let bytes = + Data_encoding.Binary.to_bytes_exn Sapling.transaction_encoding s + in + (Bytes (loc, bytes), ctxt) ) + | (Sapling_state_t _, {id; diff; _}) -> + Lwt.return + ( Gas.consume ctxt (Unparse_costs.sapling_diff diff) >|? fun ctxt -> + ( (match diff with + | {commitments_and_ciphertexts = []; nullifiers = []} -> ( + match id with + | None -> Micheline.Seq (loc, []) + | Some id -> + let id = Sapling.Id.unparse_to_z id in + Micheline.Int (loc, id)) + | diff -> ( + let diff_bytes = + Data_encoding.Binary.to_bytes_exn Sapling.diff_encoding diff + in + let unparsed_diff = Bytes (loc, diff_bytes) in + match id with + | None -> unparsed_diff + | Some id -> + let id = Sapling.Id.unparse_to_z id in + Micheline.Prim + (loc, D_Pair, [Int (loc, id); unparsed_diff], []))), + ctxt ) ) + | (Chest_key_t _, s) -> + unparse_with_data_encoding + ~loc + ctxt + s + Unparse_costs.chest_key + Timelock.chest_key_encoding + | (Chest_t _, s) -> + unparse_with_data_encoding + ~loc + ctxt + s + (Unparse_costs.chest ~plaintext_size:(Timelock.get_plaintext_size s)) + Timelock.chest_encoding + +and unparse_items : + type k v. + context -> + stack_depth:int -> + unparsing_mode -> + k comparable_ty -> + v ty -> + (k * v) list -> + (Script.node list * context) tzresult Lwt.t = + fun ctxt ~stack_depth mode kt vt items -> + List.fold_left_es + (fun (l, ctxt) (k, v) -> + let loc = Micheline.dummy_location in + unparse_comparable_data ~loc ctxt mode kt k >>=? fun (key, ctxt) -> + unparse_data ctxt ~stack_depth:(stack_depth + 1) mode vt v + >|=? fun (value, ctxt) -> (Prim (loc, D_Elt, [key; value], []) :: l, ctxt)) + ([], ctxt) + items + +and[@coq_axiom_with_reason "gadt"] unparse_code ctxt ~stack_depth mode code = + let legacy = true in + Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>?= fun ctxt -> + let non_terminal_recursion ctxt mode code = + if Compare.Int.(stack_depth > 10_000) then + fail Unparsing_too_many_recursive_calls + else unparse_code ctxt ~stack_depth:(stack_depth + 1) mode code + in + match code with + | Prim (loc, I_PUSH, [ty; data], annot) -> + parse_packable_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy ty + >>?= fun (Ex_ty t, ctxt) -> + let allow_forged = + false + (* Forgeable in PUSH data are already forbidden at parsing, + the only case for which this matters is storing a lambda resulting + from APPLYing a non-forgeable but this cannot happen either as long + as all packable values are also forgeable. *) + in + parse_data + ctxt + ~stack_depth:(stack_depth + 1) + ~legacy + ~allow_forged + t + data + >>=? fun (data, ctxt) -> + unparse_data ctxt ~stack_depth:(stack_depth + 1) mode t data + >>=? fun (data, ctxt) -> + return (Prim (loc, I_PUSH, [ty; data], annot), ctxt) + | Seq (loc, items) -> + List.fold_left_es + (fun (l, ctxt) item -> + non_terminal_recursion ctxt mode item >|=? fun (item, ctxt) -> + (item :: l, ctxt)) + ([], ctxt) + items + >>=? fun (items, ctxt) -> + return (Micheline.Seq (loc, List.rev items), ctxt) + | Prim (loc, prim, items, annot) -> + List.fold_left_es + (fun (l, ctxt) item -> + non_terminal_recursion ctxt mode item >|=? fun (item, ctxt) -> + (item :: l, ctxt)) + ([], ctxt) + items + >>=? fun (items, ctxt) -> + return (Prim (loc, prim, List.rev items, annot), ctxt) + | (Int _ | String _ | Bytes _) as atom -> return (atom, ctxt) + +(* Gas accounting may not be perfect in this function, as it is only called by RPCs. *) +(* TODO: https://gitlab.com/tezos/tezos/-/issues/1688 + Refactor the sharing part of unparse_script and create_contract *) +let unparse_script ctxt mode + {code; arg_type; storage; storage_type; root_name; views; _} = + let (Lam (_, original_code)) = code in + unparse_code ctxt ~stack_depth:0 mode original_code >>=? fun (code, ctxt) -> + unparse_data ctxt ~stack_depth:0 mode storage_type storage + >>=? fun (storage, ctxt) -> + Lwt.return + (let loc = Micheline.dummy_location in + unparse_ty ~loc ctxt arg_type >>? fun (arg_type, ctxt) -> + unparse_ty ~loc ctxt storage_type >>? fun (storage_type, ctxt) -> + let arg_type = add_field_annot root_name None arg_type in + let open Micheline in + let view name {input_ty; output_ty; view_code} views = + Prim + ( loc, + K_view, + [ + String (loc, Script_string.to_string name); + input_ty; + output_ty; + view_code; + ], + [] ) + :: views + in + let views = SMap.fold view views [] |> List.rev in + let code = + Seq + ( loc, + [ + Prim (loc, K_parameter, [arg_type], []); + Prim (loc, K_storage, [storage_type], []); + Prim (loc, K_code, [code], []); + ] + @ views ) + in + Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>? fun ctxt -> + Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>? fun ctxt -> + Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>? fun ctxt -> + Gas.consume ctxt Unparse_costs.unparse_instr_cycle >>? fun ctxt -> + Gas.consume ctxt (Script.strip_locations_cost code) >>? fun ctxt -> + Gas.consume ctxt (Script.strip_locations_cost storage) >|? fun ctxt -> + ( { + code = lazy_expr (strip_locations code); + storage = lazy_expr (strip_locations storage); + }, + ctxt )) + +let pack_data_with_mode ctxt typ data ~mode = + unparse_data ~stack_depth:0 ctxt mode typ data >>=? fun (unparsed, ctxt) -> + Lwt.return @@ pack_node unparsed ctxt + +let hash_data ctxt typ data = + pack_data_with_mode ctxt typ data ~mode:Optimized_legacy + >>=? fun (bytes, ctxt) -> Lwt.return @@ hash_bytes ctxt bytes + +let pack_data ctxt typ data = + pack_data_with_mode ctxt typ data ~mode:Optimized_legacy + +(* ---------------- Big map -------------------------------------------------*) + +let empty_big_map key_type value_type = + { + id = None; + diff = {map = Big_map_overlay.empty; size = 0}; + key_type; + value_type; + } + +let big_map_mem ctxt key {id; diff; key_type; _} = + hash_comparable_data ctxt key_type key >>=? fun (key, ctxt) -> + match (Big_map_overlay.find key diff.map, id) with + | (None, None) -> return (false, ctxt) + | (None, Some id) -> + Alpha_context.Big_map.mem ctxt id key >|=? fun (ctxt, res) -> (res, ctxt) + | (Some (_, None), _) -> return (false, ctxt) + | (Some (_, Some _), _) -> return (true, ctxt) + +let big_map_get_by_hash ctxt key {id; diff; value_type; _} = + match (Big_map_overlay.find key diff.map, id) with + | (Some (_, x), _) -> return (x, ctxt) + | (None, None) -> return (None, ctxt) + | (None, Some id) -> ( + Alpha_context.Big_map.get_opt ctxt id key >>=? function + | (ctxt, None) -> return (None, ctxt) + | (ctxt, Some value) -> + parse_data + ~stack_depth:0 + ctxt + ~legacy:true + ~allow_forged:true + value_type + (Micheline.root value) + >|=? fun (x, ctxt) -> (Some x, ctxt)) + +let big_map_get ctxt key map = + hash_comparable_data ctxt map.key_type key >>=? fun (key_hash, ctxt) -> + big_map_get_by_hash ctxt key_hash map + +let big_map_update_by_hash ctxt key_hash key value map = + let contains = Big_map_overlay.mem key_hash map.diff.map in + return + ( { + map with + diff = + { + map = Big_map_overlay.add key_hash (key, value) map.diff.map; + size = (if contains then map.diff.size else map.diff.size + 1); + }; + }, + ctxt ) + +let big_map_update ctxt key value map = + hash_comparable_data ctxt map.key_type key >>=? fun (key_hash, ctxt) -> + big_map_update_by_hash ctxt key_hash key value map + +let big_map_get_and_update ctxt key value map = + hash_comparable_data ctxt map.key_type key >>=? fun (key_hash, ctxt) -> + big_map_update_by_hash ctxt key_hash key value map >>=? fun (map', ctxt) -> + big_map_get_by_hash ctxt key_hash map >>=? fun (old_value, ctxt) -> + return ((old_value, map'), ctxt) + +(* ---------------- Lazy storage---------------------------------------------*) + +type lazy_storage_ids = Lazy_storage.IdSet.t + +let no_lazy_storage_id = Lazy_storage.IdSet.empty + +let diff_of_big_map ctxt mode ~temporary ~ids_to_copy + {id; key_type; value_type; diff} = + (match id with + | Some id -> + if Lazy_storage.IdSet.mem Big_map id ids_to_copy then + Big_map.fresh ~temporary ctxt >|=? fun (ctxt, duplicate) -> + (ctxt, Lazy_storage.Copy {src = id}, duplicate) + else + (* The first occurrence encountered of a big_map reuses the + ID. This way, the payer is only charged for the diff. + For this to work, this diff has to be put at the end of + the global diff, otherwise the duplicates will use the + updated version as a base. This is true because we add + this diff first in the accumulator of + `extract_lazy_storage_updates`, and this accumulator is not + reversed. *) + return (ctxt, Lazy_storage.Existing, id) + | None -> + Big_map.fresh ~temporary ctxt >>=? fun (ctxt, id) -> + Lwt.return + (let kt = unparse_comparable_ty_uncarbonated ~loc:() key_type in + Gas.consume ctxt (Script.strip_locations_cost kt) >>? fun ctxt -> + unparse_ty ~loc:() ctxt value_type >>? fun (kv, ctxt) -> + Gas.consume ctxt (Script.strip_locations_cost kv) >|? fun ctxt -> + let key_type = Micheline.strip_locations kt in + let value_type = Micheline.strip_locations kv in + (ctxt, Lazy_storage.(Alloc Big_map.{key_type; value_type}), id))) + >>=? fun (ctxt, init, id) -> + let pairs = + Big_map_overlay.fold + (fun key_hash (key, value) acc -> (key_hash, key, value) :: acc) + diff.map + [] + in + List.fold_left_es + (fun (acc, ctxt) (key_hash, key, value) -> + Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>?= fun ctxt -> + unparse_comparable_data ~loc:() ctxt mode key_type key + >>=? fun (key_node, ctxt) -> + Gas.consume ctxt (Script.strip_locations_cost key_node) >>?= fun ctxt -> + let key = Micheline.strip_locations key_node in + (match value with + | None -> return (None, ctxt) + | Some x -> + unparse_data ~stack_depth:0 ctxt mode value_type x + >>=? fun (node, ctxt) -> + Lwt.return + ( Gas.consume ctxt (Script.strip_locations_cost node) >|? fun ctxt -> + (Some (Micheline.strip_locations node), ctxt) )) + >|=? fun (value, ctxt) -> + let diff_item = Big_map.{key; key_hash; value} in + (diff_item :: acc, ctxt)) + ([], ctxt) + (List.rev pairs) + >|=? fun (updates, ctxt) -> (Lazy_storage.Update {init; updates}, id, ctxt) + +let diff_of_sapling_state ctxt ~temporary ~ids_to_copy + ({id; diff; memo_size} : Sapling.state) = + (match id with + | Some id -> + if Lazy_storage.IdSet.mem Sapling_state id ids_to_copy then + Sapling.fresh ~temporary ctxt >|=? fun (ctxt, duplicate) -> + (ctxt, Lazy_storage.Copy {src = id}, duplicate) + else return (ctxt, Lazy_storage.Existing, id) + | None -> + Sapling.fresh ~temporary ctxt >|=? fun (ctxt, id) -> + (ctxt, Lazy_storage.Alloc Sapling.{memo_size}, id)) + >|=? fun (ctxt, init, id) -> + (Lazy_storage.Update {init; updates = diff}, id, ctxt) + +(** + Witness flag for whether a type can be populated by a value containing a + lazy storage. + [False_f] must be used only when a value of the type cannot contain a lazy + storage. + + This flag is built in [has_lazy_storage] and used only in + [extract_lazy_storage_updates] and [collect_lazy_storage]. + + This flag is necessary to avoid these two functions to have a quadratic + complexity in the size of the type. + + Add new lazy storage kinds here. + + Please keep the usage of this GADT local. +*) +type 'ty has_lazy_storage = + | True_f : _ has_lazy_storage + | False_f : _ has_lazy_storage + | Pair_f : + 'a has_lazy_storage * 'b has_lazy_storage + -> ('a, 'b) pair has_lazy_storage + | Union_f : + 'a has_lazy_storage * 'b has_lazy_storage + -> ('a, 'b) union has_lazy_storage + | Option_f : 'a has_lazy_storage -> 'a option has_lazy_storage + | List_f : 'a has_lazy_storage -> 'a boxed_list has_lazy_storage + | Map_f : 'v has_lazy_storage -> (_, 'v) map has_lazy_storage + +(** + This function is called only on storage and parameter types of contracts, + once per typechecked contract. It has a complexity linear in the size of + the types, which happen to be literally written types, so the gas for them + has already been paid. +*) +let rec has_lazy_storage : type t. t ty -> t has_lazy_storage = + fun ty -> + let aux1 cons t = + match has_lazy_storage t with False_f -> False_f | h -> cons h + in + let aux2 cons t1 t2 = + match (has_lazy_storage t1, has_lazy_storage t2) with + | (False_f, False_f) -> False_f + | (h1, h2) -> cons h1 h2 + in + match ty with + | Big_map_t (_, _, _) -> True_f + | Sapling_state_t _ -> True_f + | Unit_t _ -> False_f + | Int_t _ -> False_f + | Nat_t _ -> False_f + | Signature_t _ -> False_f + | String_t _ -> False_f + | Bytes_t _ -> False_f + | Mutez_t _ -> False_f + | Key_hash_t _ -> False_f + | Key_t _ -> False_f + | Timestamp_t _ -> False_f + | Address_t _ -> False_f + | Bool_t _ -> False_f + | Lambda_t (_, _, _) -> False_f + | Set_t (_, _) -> False_f + | Contract_t (_, _) -> False_f + | Operation_t _ -> False_f + | Chain_id_t _ -> False_f + | Never_t _ -> False_f + | Bls12_381_g1_t _ -> False_f + | Bls12_381_g2_t _ -> False_f + | Bls12_381_fr_t _ -> False_f + | Sapling_transaction_t _ -> False_f + | Ticket_t _ -> False_f + | Chest_key_t _ -> False_f + | Chest_t _ -> False_f + | Pair_t ((l, _, _), (r, _, _), _) -> aux2 (fun l r -> Pair_f (l, r)) l r + | Union_t ((l, _), (r, _), _) -> aux2 (fun l r -> Union_f (l, r)) l r + | Option_t (t, _) -> aux1 (fun h -> Option_f h) t + | List_t (t, _) -> aux1 (fun h -> List_f h) t + | Map_t (_, t, _) -> aux1 (fun h -> Map_f h) t + +(** + Transforms a value potentially containing lazy storage in an intermediary + state to a value containing lazy storage only represented by identifiers. + + Returns the updated value, the updated set of ids to copy, and the lazy + storage diff to show on the receipt and apply on the storage. + +*) +let[@coq_axiom_with_reason "gadt"] extract_lazy_storage_updates ctxt mode + ~temporary ids_to_copy acc ty x = + let rec aux : + type a. + context -> + unparsing_mode -> + temporary:bool -> + Lazy_storage.IdSet.t -> + Lazy_storage.diffs -> + a ty -> + a -> + has_lazy_storage:a has_lazy_storage -> + (context * a * Lazy_storage.IdSet.t * Lazy_storage.diffs) tzresult Lwt.t = + fun ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage -> + Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>?= fun ctxt -> + match (has_lazy_storage, ty, x) with + | (False_f, _, _) -> return (ctxt, x, ids_to_copy, acc) + | (_, Big_map_t (_, _, _), map) -> + diff_of_big_map ctxt mode ~temporary ~ids_to_copy map + >|=? fun (diff, id, ctxt) -> + let map = + { + map with + diff = {map = Big_map_overlay.empty; size = 0}; + id = Some id; + } + in + let diff = Lazy_storage.make Big_map id diff in + let ids_to_copy = Lazy_storage.IdSet.add Big_map id ids_to_copy in + (ctxt, map, ids_to_copy, diff :: acc) + | (_, Sapling_state_t _, sapling_state) -> + diff_of_sapling_state ctxt ~temporary ~ids_to_copy sapling_state + >|=? fun (diff, id, ctxt) -> + let sapling_state = + Sapling.empty_state ~id ~memo_size:sapling_state.memo_size () + in + let diff = Lazy_storage.make Sapling_state id diff in + let ids_to_copy = Lazy_storage.IdSet.add Sapling_state id ids_to_copy in + (ctxt, sapling_state, ids_to_copy, diff :: acc) + | (Pair_f (hl, hr), Pair_t ((tyl, _, _), (tyr, _, _), _), (xl, xr)) -> + aux ctxt mode ~temporary ids_to_copy acc tyl xl ~has_lazy_storage:hl + >>=? fun (ctxt, xl, ids_to_copy, acc) -> + aux ctxt mode ~temporary ids_to_copy acc tyr xr ~has_lazy_storage:hr + >|=? fun (ctxt, xr, ids_to_copy, acc) -> + (ctxt, (xl, xr), ids_to_copy, acc) + | (Union_f (has_lazy_storage, _), Union_t ((ty, _), (_, _), _), L x) -> + aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage + >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, L x, ids_to_copy, acc) + | (Union_f (_, has_lazy_storage), Union_t ((_, _), (ty, _), _), R x) -> + aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage + >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, R x, ids_to_copy, acc) + | (Option_f has_lazy_storage, Option_t (ty, _), Some x) -> + aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage + >|=? fun (ctxt, x, ids_to_copy, acc) -> (ctxt, Some x, ids_to_copy, acc) + | (List_f has_lazy_storage, List_t (ty, _), l) -> + List.fold_left_es + (fun (ctxt, l, ids_to_copy, acc) x -> + aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage + >|=? fun (ctxt, x, ids_to_copy, acc) -> + (ctxt, Script_list.cons x l, ids_to_copy, acc)) + (ctxt, Script_list.empty, ids_to_copy, acc) + l.elements + >|=? fun (ctxt, l, ids_to_copy, acc) -> + let reversed = {length = l.length; elements = List.rev l.elements} in + (ctxt, reversed, ids_to_copy, acc) + | (Map_f has_lazy_storage, Map_t (_, ty, _), (module M)) -> + let bindings m = M.OPS.fold (fun k v bs -> (k, v) :: bs) m [] in + List.fold_left_es + (fun (ctxt, m, ids_to_copy, acc) (k, x) -> + aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage + >|=? fun (ctxt, x, ids_to_copy, acc) -> + (ctxt, M.OPS.add k x m, ids_to_copy, acc)) + (ctxt, M.OPS.empty, ids_to_copy, acc) + (bindings M.boxed) + >|=? fun (ctxt, m, ids_to_copy, acc) -> + let module M = struct + module OPS = M.OPS + + type key = M.key + + type value = M.value + + let key_ty = M.key_ty + + let boxed = m + + let size = M.size + end in + ( ctxt, + (module M : Boxed_map with type key = M.key and type value = M.value), + ids_to_copy, + acc ) + | (_, Option_t (_, _), None) -> return (ctxt, None, ids_to_copy, acc) + | _ -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/1962 + fix injectivity of types *) + assert false + in + let has_lazy_storage = has_lazy_storage ty in + aux ctxt mode ~temporary ids_to_copy acc ty x ~has_lazy_storage + +(** We namespace an error type for [fold_lazy_storage]. The error case is only + available when the ['error] parameter is equal to unit. *) +module Fold_lazy_storage = struct + type ('acc, 'error) result = + | Ok : 'acc -> ('acc, 'error) result + | Error : ('acc, unit) result +end + +(** Prematurely abort if [f] generates an error. Use this function without the + [unit] type for [error] if you are in a case where errors are impossible. +*) +let[@coq_axiom_with_reason "gadt"] rec fold_lazy_storage : + type a error. + f:('acc, error) Fold_lazy_storage.result Lazy_storage.IdSet.fold_f -> + init:'acc -> + context -> + a ty -> + a -> + has_lazy_storage:a has_lazy_storage -> + (('acc, error) Fold_lazy_storage.result * context) tzresult = + fun ~f ~init ctxt ty x ~has_lazy_storage -> + Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>? fun ctxt -> + match (has_lazy_storage, ty, x) with + | (_, Big_map_t (_, _, _), {id = Some id; _}) -> + Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>? fun ctxt -> + ok (f.f Big_map id (Fold_lazy_storage.Ok init), ctxt) + | (_, Sapling_state_t _, {id = Some id; _}) -> + Gas.consume ctxt Typecheck_costs.parse_instr_cycle >>? fun ctxt -> + ok (f.f Sapling_state id (Fold_lazy_storage.Ok init), ctxt) + | (False_f, _, _) -> ok (Fold_lazy_storage.Ok init, ctxt) + | (_, Big_map_t (_, _, _), {id = None; _}) -> + ok (Fold_lazy_storage.Ok init, ctxt) + | (_, Sapling_state_t _, {id = None; _}) -> + ok (Fold_lazy_storage.Ok init, ctxt) + | (Pair_f (hl, hr), Pair_t ((tyl, _, _), (tyr, _, _), _), (xl, xr)) -> ( + fold_lazy_storage ~f ~init ctxt tyl xl ~has_lazy_storage:hl + >>? fun (init, ctxt) -> + match init with + | Fold_lazy_storage.Ok init -> + fold_lazy_storage ~f ~init ctxt tyr xr ~has_lazy_storage:hr + | Fold_lazy_storage.Error -> ok (init, ctxt)) + | (Union_f (has_lazy_storage, _), Union_t ((ty, _), (_, _), _), L x) -> + fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage + | (Union_f (_, has_lazy_storage), Union_t ((_, _), (ty, _), _), R x) -> + fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage + | (_, Option_t (_, _), None) -> ok (Fold_lazy_storage.Ok init, ctxt) + | (Option_f has_lazy_storage, Option_t (ty, _), Some x) -> + fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage + | (List_f has_lazy_storage, List_t (ty, _), l) -> + List.fold_left + (fun (acc : (('acc, error) Fold_lazy_storage.result * context) tzresult) + x -> + acc >>? fun (init, ctxt) -> + match init with + | Fold_lazy_storage.Ok init -> + fold_lazy_storage ~f ~init ctxt ty x ~has_lazy_storage + | Fold_lazy_storage.Error -> ok (init, ctxt)) + (ok (Fold_lazy_storage.Ok init, ctxt)) + l.elements + | (Map_f has_lazy_storage, Map_t (_, ty, _), m) -> + Script_map.fold + (fun _ + v + (acc : (('acc, error) Fold_lazy_storage.result * context) tzresult) -> + acc >>? fun (init, ctxt) -> + match init with + | Fold_lazy_storage.Ok init -> + fold_lazy_storage ~f ~init ctxt ty v ~has_lazy_storage + | Fold_lazy_storage.Error -> ok (init, ctxt)) + m + (ok (Fold_lazy_storage.Ok init, ctxt)) + | _ -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/1962 + fix injectivity of types *) + assert false + +let[@coq_axiom_with_reason "gadt"] collect_lazy_storage ctxt ty x = + let has_lazy_storage = has_lazy_storage ty in + let f kind id (acc : (_, never) Fold_lazy_storage.result) = + let acc = match acc with Fold_lazy_storage.Ok acc -> acc in + Fold_lazy_storage.Ok (Lazy_storage.IdSet.add kind id acc) + in + fold_lazy_storage ~f:{f} ~init:no_lazy_storage_id ctxt ty x ~has_lazy_storage + >>? fun (ids, ctxt) -> + match ids with Fold_lazy_storage.Ok ids -> ok (ids, ctxt) + +let[@coq_axiom_with_reason "gadt"] extract_lazy_storage_diff ctxt mode + ~temporary ~to_duplicate ~to_update ty v = + (* + Basically [to_duplicate] are ids from the argument and [to_update] are ids + from the storage before execution (i.e. it is safe to reuse them since they + will be owned by the same contract). + *) + let to_duplicate = Lazy_storage.IdSet.diff to_duplicate to_update in + extract_lazy_storage_updates ctxt mode ~temporary to_duplicate [] ty v + >|=? fun (ctxt, v, alive, diffs) -> + let diffs = + if temporary then diffs + else + let dead = Lazy_storage.IdSet.diff to_update alive in + Lazy_storage.IdSet.fold_all + {f = (fun kind id acc -> Lazy_storage.make kind id Remove :: acc)} + dead + diffs + in + match diffs with + | [] -> (v, None, ctxt) + | diffs -> (v, Some diffs (* do not reverse *), ctxt) + +let list_of_big_map_ids ids = + Lazy_storage.IdSet.fold Big_map (fun id acc -> id :: acc) ids [] + +let parse_data = parse_data ~stack_depth:0 + +let parse_instr : + type a s. + ?type_logger:type_logger -> + tc_context -> + context -> + legacy:bool -> + Script.node -> + (a, s) stack_ty -> + ((a, s) judgement * context) tzresult Lwt.t = + fun ?type_logger tc_context ctxt ~legacy script_instr stack_ty -> + parse_instr + ~stack_depth:0 + ?type_logger + tc_context + ctxt + ~legacy + script_instr + stack_ty + +let unparse_data = unparse_data ~stack_depth:0 + +let unparse_code ctxt mode code = + (* Constants need to be expanded or [unparse_code] may fail. *) + Global_constants_storage.expand ctxt (strip_locations code) + >>=? fun (ctxt, code) -> unparse_code ~stack_depth:0 ctxt mode (root code) + +let parse_contract ~legacy context loc arg_ty contract ~entrypoint = + parse_contract ~stack_depth:0 ~legacy context loc arg_ty contract ~entrypoint + +let parse_toplevel ctxt ~legacy toplevel = + Global_constants_storage.expand ctxt toplevel >>=? fun (ctxt, toplevel) -> + Lwt.return @@ parse_toplevel ctxt ~legacy toplevel + +let parse_comparable_ty = parse_comparable_ty ~stack_depth:0 + +let parse_big_map_value_ty = parse_big_map_value_ty ~stack_depth:0 + +let parse_packable_ty = parse_packable_ty ~stack_depth:0 + +let parse_parameter_ty = parse_parameter_ty ~stack_depth:0 + +let parse_any_ty = parse_any_ty ~stack_depth:0 + +let parse_ty = parse_ty ~stack_depth:0 + +let ty_eq ctxt = ty_eq ~legacy:true ctxt + +let[@coq_axiom_with_reason "gadt"] get_single_sapling_state ctxt ty x = + let has_lazy_storage = has_lazy_storage ty in + let f (type i a u) (kind : (i, a, u) Lazy_storage.Kind.t) (id : i) + single_id_opt : (Sapling.Id.t option, unit) Fold_lazy_storage.result = + match kind with + | Lazy_storage.Kind.Sapling_state -> ( + match single_id_opt with + | Fold_lazy_storage.Ok None -> Fold_lazy_storage.Ok (Some id) + | Fold_lazy_storage.Ok (Some _) -> + Fold_lazy_storage.Error (* more than one *) + | Fold_lazy_storage.Error -> single_id_opt) + | _ -> single_id_opt + in + fold_lazy_storage ~f:{f} ~init:None ctxt ty x ~has_lazy_storage + >>? fun (id, ctxt) -> + match id with + | Fold_lazy_storage.Ok (Some id) -> ok (Some id, ctxt) + | Fold_lazy_storage.Ok None | Fold_lazy_storage.Error -> ok (None, ctxt) + +(* + + {!Script_cache} needs a measure of the script size in memory. + Determining this size is not easy in OCaml because of sharing. + + Indeed, many values present in the script share the same memory + area. This is especially true for types and stack types: they are + heavily shared in every typed IR internal representation. As a + consequence, computing the size of the typed IR without taking + sharing into account leads to a size which is sometimes two order + of magnitude bigger than the actual size. + + We could track down this sharing. Unfortunately, sharing is not + part of OCaml semantics: for this reason, a compiler can optimize + memory representation by adding more sharing. If two nodes use + different optimization flags or compilers, such a precise + computation of the memory footprint of scripts would lead to two + distinct sizes. As these sizes occur in the blockchain context, + this situation would lead to a fork. + + For this reason, we introduce a *size model* for the script size. + This model provides an overapproximation of the actual size in + memory. The risk is to be too far from the actual size: the cache + would then be wrongly marked as full. This situation would make the + cache less useful but should present no security risk . + +*) +let script_size + (Ex_script + { + code_size; + code = _; + arg_type = _; + storage; + storage_type; + root_name = _; + views = _; + }) = + let (nodes, storage_size) = + Script_typed_ir_size.value_size storage_type storage + in + let cost = Script_typed_ir_size_costs.nodes_cost ~nodes in + (Saturation_repr.(add code_size storage_size |> to_int), cost) diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_ir_translator.mli b/src/proto_012_PsiThaCa/lib_protocol/script_ir_translator.mli new file mode 100644 index 000000000000..0dedd1b2aa07 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_ir_translator.mli @@ -0,0 +1,502 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Overview: + +This mli is organized into roughly three parts: + +1. A set of new types prefixed with "ex_" +Michelson is encoded in a GADT that preserves certain properties about its +type system. If you haven't read about GADT's, check out the relevant section +in the Tezos docs: +https://tezos.gitlab.io/developer/gadt.html#generalized-algebraic-data-types-gadts + +The idea is that type representing a Michelson type, ['a ty], is parameterized +by a type 'a. But that 'a can't be just _any_ type; it must be valid according +to the definition of ['a ty]. Thus, if I give you a value of type ['a ty], +all you know is that "there exists some 'a such that 'a ty exists". You must be +careful not to accidentally quantify 'a universally, that is "for all 'a, +'a ty exists", otherwise you'll get an annoying error about 'a trying to escape +it's scope. We do this by hiding 'a in an existential type. This is what +ex_comparable_ty, ex_ty, ex_stack_ty, etc. do. + +2. A set of functions dealing with high-level Michelson types: +This module also provides functions for interacting with the list, map, +set, and big_map Michelson types. + +3. A set of functions for parsing and typechecking Michelson. +Finally, and what you likely came for, the module provides many functions prefixed +with "parse_" that convert untyped Micheline (which is essentially S-expressions +with a few primitive atom types) into the GADT encoding well-typed Michelson. Likewise +there is a number of functions prefixed "unparse_" that do the reverse. These functions +consume gas, and thus are parameterized by an [Alpha_context.t]. + +The variety of functions reflects the variety of things one might want to parse, +from [parse_data] for arbitrary Micheline expressions to [parse_contract] for +well-formed Michelson contracts. +*) + +(** {1 Michelson Existential Witness types} *) +open Alpha_context + +open Script_tc_errors + +type ('ta, 'tb) eq = Eq : ('same, 'same) eq + +type ex_comparable_ty = + | Ex_comparable_ty : 'a Script_typed_ir.comparable_ty -> ex_comparable_ty + +type ex_ty = Ex_ty : 'a Script_typed_ir.ty -> ex_ty + +type ex_stack_ty = + | Ex_stack_ty : ('a, 's) Script_typed_ir.stack_ty -> ex_stack_ty + +type ex_script = Ex_script : ('a, 'b) Script_typed_ir.script -> ex_script + +type toplevel = { + code_field : Script.node; + arg_type : Script.node; + storage_type : Script.node; + views : Script_typed_ir.view Script_typed_ir.SMap.t; + root_name : Script_ir_annot.field_annot option; +} + +type ('arg, 'storage) code = { + code : + ( ('arg, 'storage) Script_typed_ir.pair, + ( Script_typed_ir.operation Script_typed_ir.boxed_list, + 'storage ) + Script_typed_ir.pair ) + Script_typed_ir.lambda; + arg_type : 'arg Script_typed_ir.ty; + storage_type : 'storage Script_typed_ir.ty; + views : Script_typed_ir.view Script_typed_ir.SMap.t; + root_name : Script_ir_annot.field_annot option; + code_size : Cache_memory_helpers.sint; + (** This is an over-approximation of the value size in memory, in + bytes, of the contract's static part, that is its source + code. This includes the code of the contract as well as the code + of the views. The storage size is not taken into account by this + field as it has a dynamic size. *) +} + +type ex_code = Ex_code : ('a, 'c) code -> ex_code + +type 'storage ex_view = + | Ex_view : + ('input * 'storage, 'output) Script_typed_ir.lambda + -> 'storage ex_view + +type ('a, 's, 'b, 'u) cinstr = { + apply : + 'r 'f. + ('a, 's) Script_typed_ir.kinfo -> + ('b, 'u, 'r, 'f) Script_typed_ir.kinstr -> + ('a, 's, 'r, 'f) Script_typed_ir.kinstr; +} + +type ('a, 's, 'b, 'u) descr = { + loc : Script.location; + bef : ('a, 's) Script_typed_ir.stack_ty; + aft : ('b, 'u) Script_typed_ir.stack_ty; + instr : ('a, 's, 'b, 'u) cinstr; +} + +type tc_context = + | Lambda : tc_context + | Dip : ('a, 's) Script_typed_ir.stack_ty * tc_context -> tc_context + | Toplevel : { + storage_type : 'sto Script_typed_ir.ty; + param_type : 'param Script_typed_ir.ty; + root_name : Script_ir_annot.field_annot option; + } + -> tc_context + +type ('a, 's) judgement = + | Typed : ('a, 's, 'b, 'u) descr -> ('a, 's) judgement + | Failed : { + descr : 'b 'u. ('b, 'u) Script_typed_ir.stack_ty -> ('a, 's, 'b, 'u) descr; + } + -> ('a, 's) judgement + +val close_descr : + ('a, 'b, 'c, 'd) descr -> ('a, 'b, 'c, 'd) Script_typed_ir.kdescr + +(** Flag that drives unparsing of typed values to nodes. + - [Optimized_legacy] must be kept backward-compatible in order to compute + valid hashes (of big map keys). + - [Optimized] may be used as long as the result can be read by parse_data. + - [Readable] produces with [string] values instead of [bytes] when feasible. +*) +type unparsing_mode = Optimized | Readable | Optimized_legacy + +type merge_type_error_flag = Default_merge_type_error | Fast_merge_type_error + +(* ---- Lists, Sets and Maps ----------------------------------------------- *) + +(** {2 High-level Michelson Data Types} *) +type type_logger = + Script.location -> + (Script.expr * Script.annot) list -> + (Script.expr * Script.annot) list -> + unit + +(** Create an empty big_map *) +val empty_big_map : + 'a Script_typed_ir.comparable_ty -> + 'b Script_typed_ir.ty -> + ('a, 'b) Script_typed_ir.big_map + +val big_map_mem : + context -> + 'key -> + ('key, 'value) Script_typed_ir.big_map -> + (bool * context) tzresult Lwt.t + +val big_map_get : + context -> + 'key -> + ('key, 'value) Script_typed_ir.big_map -> + ('value option * context) tzresult Lwt.t + +(** Update a big map. See {!big_map_get_and_update} for details. *) +val big_map_update : + context -> + 'key -> + 'value option -> + ('key, 'value) Script_typed_ir.big_map -> + (('key, 'value) Script_typed_ir.big_map * context) tzresult Lwt.t + +(** Update a big map, returning the old value of the given key and the new map. + + This does {i not} modify the underlying storage, only the diff table. + *) +val big_map_get_and_update : + context -> + 'key -> + 'value option -> + ('key, 'value) Script_typed_ir.big_map -> + (('value option * ('key, 'value) Script_typed_ir.big_map) * context) tzresult + Lwt.t + +val ty_eq : + context -> + Script.location -> + 'ta Script_typed_ir.ty -> + 'tb Script_typed_ir.ty -> + (('ta Script_typed_ir.ty, 'tb Script_typed_ir.ty) eq * context) tzresult + +val merge_types : + legacy:bool -> + merge_type_error_flag:merge_type_error_flag -> + Script.location -> + 'a Script_typed_ir.ty -> + 'b Script_typed_ir.ty -> + ( ('a Script_typed_ir.ty, 'b Script_typed_ir.ty) eq * 'a Script_typed_ir.ty, + error trace ) + Gas_monad.t + +(** {3 Parsing and Typechecking Michelson} *) +val parse_comparable_data : + ?type_logger:type_logger -> + context -> + 'a Script_typed_ir.comparable_ty -> + Script.node -> + ('a * context) tzresult Lwt.t + +val parse_data : + ?type_logger:type_logger -> + context -> + legacy:bool -> + allow_forged:bool -> + 'a Script_typed_ir.ty -> + Script.node -> + ('a * context) tzresult Lwt.t + +val unparse_data : + context -> + unparsing_mode -> + 'a Script_typed_ir.ty -> + 'a -> + (Script.node * context) tzresult Lwt.t + +val unparse_comparable_data : + loc:'loc -> + context -> + unparsing_mode -> + 'a Script_typed_ir.comparable_ty -> + 'a -> + ('loc Script.michelson_node * context) tzresult Lwt.t + +val unparse_code : + context -> + unparsing_mode -> + Script.node -> + (Script.node * context) tzresult Lwt.t + +val parse_instr : + ?type_logger:type_logger -> + tc_context -> + context -> + legacy:bool -> + Script.node -> + ('a, 's) Script_typed_ir.stack_ty -> + (('a, 's) judgement * context) tzresult Lwt.t + +(** + [parse_ty] specialized for the right-hand side part of a big map type, i.e. + the `value` in `big_map key value`. +*) +val parse_big_map_value_ty : + context -> legacy:bool -> Script.node -> (ex_ty * context) tzresult + +val parse_packable_ty : + context -> legacy:bool -> Script.node -> (ex_ty * context) tzresult + +val parse_parameter_ty : + context -> legacy:bool -> Script.node -> (ex_ty * context) tzresult + +val parse_comparable_ty : + context -> Script.node -> (ex_comparable_ty * context) tzresult + +val parse_view_input_ty : + context -> + stack_depth:int -> + legacy:bool -> + Script.node -> + (ex_ty * context) tzresult + +val parse_view_output_ty : + context -> + stack_depth:int -> + legacy:bool -> + Script.node -> + (ex_ty * context) tzresult + +val parse_view_returning : + ?type_logger:type_logger -> + context -> + legacy:bool -> + 'storage Script_typed_ir.ty -> + Script_typed_ir.view -> + ('storage ex_view * context) tzresult Lwt.t + +val typecheck_views : + ?type_logger:type_logger -> + context -> + legacy:bool -> + 'storage Script_typed_ir.ty -> + Script_typed_ir.view Script_typed_ir.SMap.t -> + context tzresult Lwt.t + +(** + [parse_ty] allowing big_map values, operations, contract and tickets. +*) +val parse_any_ty : + context -> legacy:bool -> Script.node -> (ex_ty * context) tzresult + +(** We expose [parse_ty] for convenience to external tools. Please use + specialized versions such as [parse_packable_ty], [parse_parameter_ty], + [parse_comparable_ty], or [parse_big_map_value_ty] if possible. *) +val parse_ty : + context -> + legacy:bool -> + allow_lazy_storage:bool -> + allow_operation:bool -> + allow_contract:bool -> + allow_ticket:bool -> + Script.node -> + (ex_ty * context) tzresult + +val unparse_ty : + loc:'loc -> + context -> + 'a Script_typed_ir.ty -> + ('loc Script.michelson_node * context) tzresult + +val unparse_comparable_ty : + loc:'loc -> + context -> + 'a Script_typed_ir.comparable_ty -> + ('loc Script.michelson_node * context) tzresult + +val ty_of_comparable_ty : + 'a Script_typed_ir.comparable_ty -> 'a Script_typed_ir.ty + +val parse_toplevel : + context -> legacy:bool -> Script.expr -> (toplevel * context) tzresult Lwt.t + +val add_field_annot : + Script_ir_annot.field_annot option -> + Script_ir_annot.var_annot option -> + ('loc, 'prim) Micheline.node -> + ('loc, 'prim) Micheline.node + +(** High-level function to typecheck a Michelson script. This function is not + used for validating operations but only for the [typecheck_code] RPC. + + If [show_types] is set to [true], details of the typechecking are returned + in the [type_map], otherwise the returned [type_map] is empty. *) +val typecheck_code : + legacy:bool -> + show_types:bool -> + context -> + Script.expr -> + (type_map * context) tzresult Lwt.t + +val serialize_ty_for_error : 'a Script_typed_ir.ty -> Script.expr + +val parse_code : + ?type_logger:type_logger -> + context -> + legacy:bool -> + code:Script.lazy_expr -> + (ex_code * context) tzresult Lwt.t + +val parse_storage : + ?type_logger:type_logger -> + context -> + legacy:bool -> + allow_forged:bool -> + 'storage Script_typed_ir.ty -> + storage:Script.lazy_expr -> + ('storage * context) tzresult Lwt.t + +(** Combines [parse_code] and [parse_storage] *) +val parse_script : + ?type_logger:type_logger -> + context -> + legacy:bool -> + allow_forged_in_storage:bool -> + Script.t -> + (ex_script * context) tzresult Lwt.t + +(* Gas accounting may not be perfect in this function, as it is only called by RPCs. *) +val unparse_script : + context -> + unparsing_mode -> + ('a, 'b) Script_typed_ir.script -> + (Script.t * context) tzresult Lwt.t + +val parse_contract : + legacy:bool -> + context -> + Script.location -> + 'a Script_typed_ir.ty -> + Contract.t -> + entrypoint:string -> + (context * 'a Script_typed_ir.typed_contract) tzresult Lwt.t + +val parse_contract_for_script : + context -> + Script.location -> + 'a Script_typed_ir.ty -> + Contract.t -> + entrypoint:string -> + (context * 'a Script_typed_ir.typed_contract option) tzresult Lwt.t + +val find_entrypoint : + 't Script_typed_ir.ty -> + root_name:Script_ir_annot.field_annot option -> + string -> + ((Script.node -> Script.node) * ex_ty) tzresult + +module Entrypoints_map : Map.S with type key = string + +val list_entrypoints : + 't Script_typed_ir.ty -> + context -> + root_name:Script_ir_annot.field_annot option -> + (Michelson_v1_primitives.prim list list + * (Michelson_v1_primitives.prim list * Script.unlocated_michelson_node) + Entrypoints_map.t) + tzresult + +val pack_data : + context -> 'a Script_typed_ir.ty -> 'a -> (bytes * context) tzresult Lwt.t + +val hash_comparable_data : + context -> + 'a Script_typed_ir.comparable_ty -> + 'a -> + (Script_expr_hash.t * context) tzresult Lwt.t + +val hash_data : + context -> + 'a Script_typed_ir.ty -> + 'a -> + (Script_expr_hash.t * context) tzresult Lwt.t + +type lazy_storage_ids + +val no_lazy_storage_id : lazy_storage_ids + +(** Traverse the given type, producing a {!lazy_storage_ids} for + use with {!extract_lazy_storage_diff}. + *) +val collect_lazy_storage : + context -> + 'a Script_typed_ir.ty -> + 'a -> + (lazy_storage_ids * context) tzresult + +val list_of_big_map_ids : lazy_storage_ids -> Big_map.Id.t list + +(** Produce a lazy storage diff, containing in-memory writes to + lazy data structures such as big_maps yet to be committed. + + The resulting diff can be committed to the underlying storage + (context) using [Lazy_storage_diff.apply]. + + @param to_duplicate + Lazy data structure reference produced via {!collect_lazy_storage} + that can not be reused. Typically collected via traversing + the parameters to a smart contract. + @param to_update + Lazy data structure reference produced via {!collect_lazy_storage} + that can be reused. Typically collected via traversing the previous + storage of a smart contract. + *) +val extract_lazy_storage_diff : + context -> + unparsing_mode -> + temporary:bool -> + to_duplicate:lazy_storage_ids -> + to_update:lazy_storage_ids -> + 'a Script_typed_ir.ty -> + 'a -> + ('a * Lazy_storage.diffs option * context) tzresult Lwt.t + +(* return [None] if none or more than one found *) +val get_single_sapling_state : + context -> + 'a Script_typed_ir.ty -> + 'a -> + (Sapling.Id.t option * context) tzresult + +(** [script_size script] returns an overapproximation of the size of + the in-memory representation of [script] as well as the cost + associated to computing that overapproximation. *) +val script_size : ex_script -> int * Gas_limit_repr.cost diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_list.ml b/src/proto_012_PsiThaCa/lib_protocol/script_list.ml new file mode 100644 index 000000000000..7e9cbdeb2214 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_list.ml @@ -0,0 +1,32 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Script_typed_ir + +let empty : 'a boxed_list = {elements = []; length = 0} + +let cons : 'a -> 'a boxed_list -> 'a boxed_list = + fun elt l -> {length = 1 + l.length; elements = elt :: l.elements} diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_list.mli b/src/proto_012_PsiThaCa/lib_protocol/script_list.mli new file mode 100644 index 000000000000..01a4670df6b4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_list.mli @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Empty list. *) +val empty : 'a Script_typed_ir.boxed_list + +(** Prepend an element. *) +val cons : 'a -> 'a Script_typed_ir.boxed_list -> 'a Script_typed_ir.boxed_list diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_map.ml b/src/proto_012_PsiThaCa/lib_protocol/script_map.ml new file mode 100644 index 000000000000..d53d16aeefeb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_map.ml @@ -0,0 +1,97 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Script_typed_ir + +let key_ty : type a b. (a, b) map -> a comparable_ty = + fun (module Box) -> Box.key_ty + +let empty : type a b. a comparable_ty -> (a, b) map = + fun ty -> + let module OPS = Map.Make (struct + type t = a + + let compare = Script_comparable.compare_comparable ty + end) in + (module struct + type key = a + + type value = b + + let key_ty = ty + + module OPS = struct + type value = b + + include OPS + + type nonrec t = value t + end + + let boxed = OPS.empty + + let size = 0 + end) + +let get : type key value. key -> (key, value) map -> value option = + fun k (module Box) -> Box.OPS.find k Box.boxed + +let update : type a b. a -> b option -> (a, b) map -> (a, b) map = + fun k v (module Box) -> + let (boxed, size) = + let contains = + match Box.OPS.find k Box.boxed with None -> false | _ -> true + in + match v with + | Some v -> (Box.OPS.add k v Box.boxed, Box.size + if contains then 0 else 1) + | None -> (Box.OPS.remove k Box.boxed, Box.size - if contains then 1 else 0) + in + (module struct + type key = a + + type value = b + + let key_ty = Box.key_ty + + module OPS = Box.OPS + + let boxed = boxed + + let size = size + end) + +let mem : type key value. key -> (key, value) map -> bool = + fun k (module Box) -> + match Box.OPS.find k Box.boxed with None -> false | _ -> true + +let fold : + type key value acc. + (key -> value -> acc -> acc) -> (key, value) map -> acc -> acc = + fun f (module Box) -> Box.OPS.fold f Box.boxed + +let size : type key value. (key, value) map -> Script_int.n Script_int.num = + fun (module Box) -> Script_int.(abs (of_int Box.size)) diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_map.mli b/src/proto_012_PsiThaCa/lib_protocol/script_map.mli new file mode 100644 index 000000000000..7bd3cd51e4b4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_map.mli @@ -0,0 +1,49 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +val empty : 'a Script_typed_ir.comparable_ty -> ('a, 'b) Script_typed_ir.map + +val fold : + ('key -> 'value -> 'acc -> 'acc) -> + ('key, 'value) Script_typed_ir.map -> + 'acc -> + 'acc + +val update : + 'a -> + 'b option -> + ('a, 'b) Script_typed_ir.map -> + ('a, 'b) Script_typed_ir.map + +val mem : 'key -> ('key, 'value) Script_typed_ir.map -> bool + +val get : 'key -> ('key, 'value) Script_typed_ir.map -> 'value option + +val key_ty : ('a, 'b) Script_typed_ir.map -> 'a Script_typed_ir.comparable_ty + +val size : ('a, 'b) Script_typed_ir.map -> Script_int.n Script_int.num diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/script_repr.ml new file mode 100644 index 000000000000..c286e56f9087 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_repr.ml @@ -0,0 +1,353 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type location = Micheline.canonical_location + +let location_encoding = Micheline.canonical_location_encoding + +type annot = Micheline.annot + +type expr = Michelson_v1_primitives.prim Micheline.canonical + +type lazy_expr = expr Data_encoding.lazy_t + +type 'location michelson_node = + ('location, Michelson_v1_primitives.prim) Micheline.node + +type unlocated_michelson_node = unit michelson_node + +type node = location michelson_node + +let expr_encoding = + Micheline.canonical_encoding + ~variant:"michelson_v1" + Michelson_v1_primitives.prim_encoding + +type error += Lazy_script_decode (* `Permanent *) + +let () = + register_error_kind + `Permanent + ~id:"invalid_binary_format" + ~title:"Invalid binary format" + ~description: + "Could not deserialize some piece of data from its binary representation" + Data_encoding.empty + (function Lazy_script_decode -> Some () | _ -> None) + (fun () -> Lazy_script_decode) + +let lazy_expr_encoding = Data_encoding.lazy_encoding expr_encoding + +let lazy_expr expr = Data_encoding.make_lazy expr_encoding expr + +type t = {code : lazy_expr; storage : lazy_expr} + +let encoding = + let open Data_encoding in + def "scripted.contracts" + @@ conv + (fun {code; storage} -> (code, storage)) + (fun (code, storage) -> {code; storage}) + (obj2 (req "code" lazy_expr_encoding) (req "storage" lazy_expr_encoding)) + +module S = Saturation_repr + +module Micheline_size = struct + type t = { + nodes : S.may_saturate S.t; + string_bytes : S.may_saturate S.t; + z_bytes : S.may_saturate S.t; + } + + let make ~nodes ~string_bytes ~z_bytes = {nodes; string_bytes; z_bytes} + + let zero = {nodes = S.zero; string_bytes = S.zero; z_bytes = S.zero} + + let add_int acc n = + let numbits = Z.numbits n in + let z_bytes = + S.safe_int ((numbits + 7) / 8) + (* Compute the number of bytes in a Z.t *) + in + { + nodes = S.succ acc.nodes; + string_bytes = acc.string_bytes; + z_bytes = S.add acc.z_bytes z_bytes; + } + + let add_string acc n = + let string_bytes = S.safe_int (String.length n) in + { + nodes = S.succ acc.nodes; + string_bytes = S.add acc.string_bytes string_bytes; + z_bytes = acc.z_bytes; + } + + let add_bytes acc n = + let string_bytes = S.safe_int (Bytes.length n) in + { + nodes = S.succ acc.nodes; + string_bytes = S.add acc.string_bytes string_bytes; + z_bytes = acc.z_bytes; + } + + let add_node s = {s with nodes = S.succ s.nodes} + + (* We model annotations as Seqs of Strings *) + let of_annots acc annots = + List.fold_left (fun acc s -> add_string acc s) acc annots + + let[@coq_struct "nodes"] rec of_nodes acc nodes more_nodes = + let open Micheline in + match nodes with + | [] -> ( + match more_nodes with + | [] -> acc + | nodes :: more_nodes -> + (of_nodes [@ocaml.tailcall]) acc nodes more_nodes) + | Int (_, n) :: nodes -> + let acc = add_int acc n in + (of_nodes [@ocaml.tailcall]) acc nodes more_nodes + | String (_, s) :: nodes -> + let acc = add_string acc s in + (of_nodes [@ocaml.tailcall]) acc nodes more_nodes + | Bytes (_, s) :: nodes -> + let acc = add_bytes acc s in + (of_nodes [@ocaml.tailcall]) acc nodes more_nodes + | Prim (_, _, args, annots) :: nodes -> + let acc = add_node acc in + let acc = of_annots acc annots in + (of_nodes [@ocaml.tailcall]) acc args (nodes :: more_nodes) + | Seq (_, args) :: nodes -> + let acc = add_node acc in + (of_nodes [@ocaml.tailcall]) acc args (nodes :: more_nodes) + + let of_node node = of_nodes zero [node] [] + + let dot_product s1 s2 = + S.add + (S.mul s1.nodes s2.nodes) + (S.add + (S.mul s1.string_bytes s2.string_bytes) + (S.mul s1.z_bytes s2.z_bytes)) +end + +(* Costs pertaining to deserialization of Micheline values (bytes to Micheline). + The costs are given in atomic steps (see [Gas_limit_repr]). *) +module Micheline_decoding = struct + (* Cost vector allowing to compute decoding costs as a function of the + size of the Micheline term *) + let micheline_size_dependent_cost = + let traversal_cost = S.safe_int 60 in + let string_per_byte_cost = S.safe_int 10 in + let z_per_byte_cost = S.safe_int 10 in + Micheline_size.make + ~nodes:traversal_cost + ~string_bytes:string_per_byte_cost + ~z_bytes:z_per_byte_cost + + let bytes_dependent_cost = S.safe_int 20 +end + +(* Costs pertaining to serialization of Micheline values (Micheline to bytes) + The costs are given in atomic steps (see [Gas_limit_repr]). *) +module Micheline_encoding = struct + (* Cost vector allowing to compute encoding cost as a function of the + size of the Micheline term *) + let micheline_size_dependent_cost = + let traversal_cost = S.safe_int 100 in + let string_per_byte_cost = S.safe_int 10 in + let z_per_byte_cost = S.safe_int 25 in + Micheline_size.make + ~nodes:traversal_cost + ~string_bytes:string_per_byte_cost + ~z_bytes:z_per_byte_cost + + let bytes_dependent_cost = S.safe_int 33 +end + +let expr_size expr = Micheline_size.of_node (Micheline.root expr) + +(* Compute the cost of serializing a term of given [size]. *) +let serialization_cost size = + Gas_limit_repr.atomic_step_cost + @@ Micheline_size.dot_product + size + Micheline_encoding.micheline_size_dependent_cost + +(* Compute the cost of deserializing a term of given [size]. *) +let deserialization_cost size = + Gas_limit_repr.atomic_step_cost + @@ Micheline_size.dot_product + size + Micheline_decoding.micheline_size_dependent_cost + +(* Estimate the cost of deserializing a term encoded in [bytes_len] bytes. *) +let deserialization_cost_estimated_from_bytes bytes_len = + Gas_limit_repr.atomic_step_cost + @@ S.mul Micheline_decoding.bytes_dependent_cost (S.safe_int bytes_len) + +(* Estimate the cost of serializing a term from its encoded form, + having [bytes_len] bytes. *) +let serialization_cost_estimated_from_bytes bytes_len = + Gas_limit_repr.atomic_step_cost + @@ S.mul Micheline_encoding.bytes_dependent_cost (S.safe_int bytes_len) + +(* Cost of running [strip_locations] on a term with [size] nodes. + Note that [strip_locations] will reallocate a fresh Micheline tree. + This only depends on the total number of nodes (not the size of + the leaves). *) +let cost_micheline_strip_locations size = + Gas_limit_repr.atomic_step_cost @@ S.mul (S.safe_int size) (S.safe_int 51) + +(* TODO: https://gitlab.com/tezos/tezos/-/issues/2049 + Plugin benchmarked gas. + Replace this definition, copied from [cost_michelines_strip_locations]. +*) +(* Cost of running [strip_annotations] on a term with [size] nodes. + Note that [strip_annotations] will reallocate a fresh Micheline tree. + This only depends on the total number of nodes (not the size of + the leaves). *) +let cost_micheline_strip_annotations size = + Gas_limit_repr.atomic_step_cost @@ S.mul (S.safe_int size) (S.safe_int 51) + +(* This is currently used to estimate the cost of serializing an operation. *) +let bytes_node_cost s = serialization_cost_estimated_from_bytes (Bytes.length s) + +let deserialized_cost expr = + Gas_limit_repr.atomic_step_cost @@ deserialization_cost (expr_size expr) + +let serialized_cost bytes = + let cost = + let size = Bytes.length bytes in + S.add (serialization_cost_estimated_from_bytes size) + @@ (* N_IConcat_bytes_pair inlined here *) + S.add (S.safe_int 65) (S.shift_right (S.safe_int size) 4) + in + Gas_limit_repr.atomic_step_cost cost + +let force_decode_cost lexpr = + Data_encoding.apply_lazy + ~fun_value:(fun _ -> Gas_limit_repr.free) + ~fun_bytes:(fun b -> + deserialization_cost_estimated_from_bytes (Bytes.length b)) + ~fun_combine:(fun _ _ -> Gas_limit_repr.free) + lexpr + +let stable_force_decode_cost lexpr = + let has_bytes = + Data_encoding.apply_lazy + ~fun_value:(fun v -> `Only_value v) + ~fun_bytes:(fun b -> `Has_bytes b) + ~fun_combine:(fun _v b -> + (* When the lazy_expr contains both a deserialized version + and a serialized one, we compute the cost from the + serialized version because its is cheaper to do. *) + b) + lexpr + in + match has_bytes with + | `Has_bytes b -> deserialization_cost_estimated_from_bytes (Bytes.length b) + | `Only_value v -> + (* This code path should not be reached in theory because values that are + decoded should have been encoded before. + Here we use Data_encoding.Binary.length, which yields the same results + as serializing the value and taking the size, without the need to + encode (in particular, less allocations). + *) + deserialization_cost_estimated_from_bytes + (Data_encoding.Binary.length expr_encoding v) + +let force_decode lexpr = + match Data_encoding.force_decode lexpr with + | Some v -> ok v + | None -> error Lazy_script_decode + +let force_bytes_cost expr = + (* Estimating the cost directly from the bytes would be cheaper, but + using [serialized_cost] is more accurate. *) + Data_encoding.apply_lazy + ~fun_value:(fun v -> serialization_cost (expr_size v)) + ~fun_bytes:(fun _ -> Gas_limit_repr.free) + ~fun_combine:(fun _ _ -> Gas_limit_repr.free) + expr + +let force_bytes expr = + Error_monad.catch_f + (fun () -> Data_encoding.force_bytes expr) + (fun _ -> Lazy_script_decode) + +let unit = + Micheline.strip_locations (Prim (0, Michelson_v1_primitives.D_Unit, [], [])) + +let unit_parameter = lazy_expr unit + +let is_unit_parameter = + let unit_bytes = Data_encoding.force_bytes unit_parameter in + Data_encoding.apply_lazy + ~fun_value:(fun v -> + match Micheline.root v with + | Prim (_, Michelson_v1_primitives.D_Unit, [], []) -> true + | _ -> false) + ~fun_bytes:(fun b -> Compare.Bytes.equal b unit_bytes) + ~fun_combine:(fun res _ -> res) + +let[@coq_struct "node"] rec strip_annotations node = + let open Micheline in + match node with + | (Int (_, _) | String (_, _) | Bytes (_, _)) as leaf -> leaf + | Prim (loc, name, args, _) -> + Prim (loc, name, List.map strip_annotations args, []) + | Seq (loc, args) -> Seq (loc, List.map strip_annotations args) + +let rec micheline_fold_aux node f acc k = + match node with + | Micheline.Int (_, _) -> k (f acc node) + | Micheline.String (_, _) -> k (f acc node) + | Micheline.Bytes (_, _) -> k (f acc node) + | Micheline.Prim (_, _, subterms, _) -> + micheline_fold_nodes subterms f (f acc node) k + | Micheline.Seq (_, subterms) -> + micheline_fold_nodes subterms f (f acc node) k + +and[@coq_mutual_as_notation] [@coq_struct "subterms"] micheline_fold_nodes + subterms f acc k = + match subterms with + | [] -> k acc + | node :: nodes -> + micheline_fold_nodes nodes f acc @@ fun acc -> + micheline_fold_aux node f acc k + +let fold node init f = micheline_fold_aux node f init (fun x -> x) + +let micheline_nodes node = fold node 0 @@ fun n _ -> n + 1 + +let strip_locations_cost node = + let nodes = micheline_nodes node in + cost_micheline_strip_locations nodes + +let strip_annotations_cost node = + let nodes = micheline_nodes node in + cost_micheline_strip_annotations nodes diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/script_repr.mli new file mode 100644 index 000000000000..66569c6bf094 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_repr.mli @@ -0,0 +1,130 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Defines a Michelson expression representation as a Micheline node with + canonical ([int]) location and [Michelson_v1_primitives.prim] as content. + + Types [expr] and [node] both define representation of Michelson + expressions and are indeed the same type internally, although this is not + visible outside Micheline due to interface abstraction. *) + +(** Locations are used by Micheline mostly for error-reporting and pretty- + printing expressions. [canonical_location] is simply an [int]. *) +type location = Micheline.canonical_location + +(** Annotations attached to Michelson expressions. *) +type annot = Micheline.annot + +(** Represents a Michelson expression as canonical Micheline. *) +type expr = Michelson_v1_primitives.prim Micheline.canonical + +type error += Lazy_script_decode (* `Permanent *) + +(** A record containing either an underlying serialized representation of an + expression or a deserialized one, or both. If either is absent, it will be + computed on-demand. *) +type lazy_expr = expr Data_encoding.lazy_t + +type 'location michelson_node = + ('location, Michelson_v1_primitives.prim) Micheline.node + +type unlocated_michelson_node = unit michelson_node + +(** Same as [expr], but used in different contexts, as required by Micheline's + abstract interface. *) +type node = location michelson_node + +val location_encoding : location Data_encoding.t + +val expr_encoding : expr Data_encoding.t + +val lazy_expr_encoding : lazy_expr Data_encoding.t + +val lazy_expr : expr -> lazy_expr + +(** Type [t] joins the contract's code and storage in a single record. *) +type t = {code : lazy_expr; storage : lazy_expr} + +val encoding : t Data_encoding.encoding + +(* Basic gas costs of operations related to processing Michelson: *) + +val deserialization_cost_estimated_from_bytes : int -> Gas_limit_repr.cost + +val deserialized_cost : expr -> Gas_limit_repr.cost + +val serialized_cost : bytes -> Gas_limit_repr.cost + +val bytes_node_cost : bytes -> Gas_limit_repr.cost + +(** Returns (a lower bound on) the cost to deserialize a + {!lazy_expr}. If the expression has already been deserialized + (i.e. the lazy expression contains the deserialized value or both + the bytes representation and the deserialized value) then the cost + is {b free}. *) +val force_decode_cost : lazy_expr -> Gas_limit_repr.cost + +(** Like {!force_decode_cost}, excepted that the returned cost does + not depend on the internal state of the lazy_expr. This means that + the cost is never free (excepted for zero bytes expressions). *) +val stable_force_decode_cost : lazy_expr -> Gas_limit_repr.cost + +val force_decode : lazy_expr -> expr tzresult + +(** Returns the cost to serialize a {!lazy_expr}. If the expression + has already been deserialized (i.e. le lazy expression contains the + bytes representation or both the bytes representation and the + deserialized value) then the cost is {b free}. *) +val force_bytes_cost : lazy_expr -> Gas_limit_repr.cost + +val force_bytes : lazy_expr -> bytes tzresult + +val unit_parameter : lazy_expr + +val is_unit_parameter : lazy_expr -> bool + +val strip_annotations : node -> node + +val strip_locations_cost : _ michelson_node -> Gas_limit_repr.cost + +val strip_annotations_cost : node -> Gas_limit_repr.cost + +module Micheline_size : sig + type t = { + nodes : Saturation_repr.may_saturate Saturation_repr.t; + string_bytes : Saturation_repr.may_saturate Saturation_repr.t; + z_bytes : Saturation_repr.may_saturate Saturation_repr.t; + } + + val of_node : node -> t +end + +(** [micheline_nodes root] returns the number of internal nodes in the + micheline expression held from [root]. *) +val micheline_nodes : node -> int + +(** [fold node i f] traverses [node] applying [f] on an + accumulator initialized by [i]. *) +val fold : node -> 'c -> ('c -> node -> 'c) -> 'c diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_set.ml b/src/proto_012_PsiThaCa/lib_protocol/script_set.ml new file mode 100644 index 000000000000..703ffae7aaa7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_set.ml @@ -0,0 +1,75 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Script_typed_ir + +let empty : type a. a comparable_ty -> a set = + fun ty -> + let module OPS = Set.Make (struct + type t = a + + let compare = Script_comparable.compare_comparable ty + end) in + (module struct + type elt = a + + let elt_ty = ty + + module OPS = OPS + + let boxed = OPS.empty + + let size = 0 + end) + +let update : type a. a -> bool -> a set -> a set = + fun v b (module Box) -> + (module struct + type elt = a + + let elt_ty = Box.elt_ty + + module OPS = Box.OPS + + let boxed = + if b then Box.OPS.add v Box.boxed else Box.OPS.remove v Box.boxed + + let size = + let mem = Box.OPS.mem v Box.boxed in + if mem then if b then Box.size else Box.size - 1 + else if b then Box.size + 1 + else Box.size + end) + +let mem : type elt. elt -> elt set -> bool = + fun v (module Box) -> Box.OPS.mem v Box.boxed + +let fold : type elt acc. (elt -> acc -> acc) -> elt set -> acc -> acc = + fun f (module Box) -> Box.OPS.fold f Box.boxed + +let size : type elt. elt set -> Script_int.n Script_int.num = + fun (module Box) -> Script_int.(abs (of_int Box.size)) diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_set.mli b/src/proto_012_PsiThaCa/lib_protocol/script_set.mli new file mode 100644 index 000000000000..f97a434c25ab --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_set.mli @@ -0,0 +1,37 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +val empty : 'a Script_typed_ir.comparable_ty -> 'a Script_typed_ir.set + +val fold : ('elt -> 'acc -> 'acc) -> 'elt Script_typed_ir.set -> 'acc -> 'acc + +val update : 'a -> bool -> 'a Script_typed_ir.set -> 'a Script_typed_ir.set + +val mem : 'elt -> 'elt Script_typed_ir.set -> bool + +val size : 'elt Script_typed_ir.set -> Script_int.n Script_int.num diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_string_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/script_string_repr.ml new file mode 100644 index 000000000000..e6e45dd9ee6d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_string_repr.ml @@ -0,0 +1,77 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Strings of printable characters *) + +type t = string (* Invariant: contains only printable characters *) + +type error += Non_printable_character of (int * string) + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"michelson_v1.non_printable_character" + ~title:"Non printable character in a Michelson string" + ~description: + "Michelson strings are only allowed to contain printable characters \ + (either the newline character or characters in the [32, 126] ASCII \ + range)." + ~pp:(fun ppf (pos, s) -> + Format.fprintf + ppf + "In Michelson string \"%s\", character at position %d has ASCII code \ + %d. Expected: either a newline character (ASCII code 10) or a \ + printable character (ASCII code between 32 and 126)." + s + pos + (Char.code s.[pos])) + (obj2 (req "position" int31) (req "string" string)) + (function Non_printable_character (pos, s) -> Some (pos, s) | _ -> None) + (fun (pos, s) -> Non_printable_character (pos, s)) + +let empty = "" + +let of_string v = + let rec check_printable_ascii i = + if Compare.Int.(i < 0) then ok v + else + match v.[i] with + | '\n' | '\x20' .. '\x7E' -> check_printable_ascii (i - 1) + | _ -> error @@ Non_printable_character (i, v) + in + check_printable_ascii (String.length v - 1) + +let to_string s = s + +let compare = Compare.String.compare + +let length = String.length + +let concat_pair x y = x ^ y + +let concat l = String.concat "" l + +let sub s offset length = String.sub s offset length diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_string_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/script_string_repr.mli new file mode 100644 index 000000000000..f94b65b389e1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_string_repr.mli @@ -0,0 +1,46 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Strings of printable characters *) + +type t + +type error += Non_printable_character of (int * string) + +val empty : t + +val of_string : string -> t tzresult + +val to_string : t -> string + +val compare : t -> t -> int + +val length : t -> int + +val concat_pair : t -> t -> t + +val concat : t list -> t + +val sub : t -> int -> int -> t diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_tc_errors.ml b/src/proto_012_PsiThaCa/lib_protocol/script_tc_errors.ml new file mode 100644 index 000000000000..2fd81d50fb59 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_tc_errors.ml @@ -0,0 +1,201 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Script + +(* ---- Error definitions ---------------------------------------------------*) + +type kind = Int_kind | String_kind | Bytes_kind | Prim_kind | Seq_kind + +type unparsed_stack_ty = (Script.expr * Script.annot) list + +type type_map = (Script.location * (unparsed_stack_ty * unparsed_stack_ty)) list + +(* Structure errors *) +type error += Invalid_arity of Script.location * prim * int * int + +type error += Invalid_seq_arity of Script.location * int * int + +type error += + | Invalid_namespace of + Script.location + * prim + * Michelson_v1_primitives.namespace + * Michelson_v1_primitives.namespace + +type error += Invalid_primitive of Script.location * prim list * prim + +type error += Invalid_kind of Script.location * kind list * kind + +type error += Invalid_never_expr of Script.location + +type error += Missing_field of prim + +type error += Duplicate_field of Script.location * prim + +type error += Unexpected_lazy_storage of Script.location + +type error += Unexpected_operation of Script.location + +type error += Unexpected_contract of Script.location + +type error += No_such_entrypoint of string + +type error += Duplicate_entrypoint of string + +type error += Unreachable_entrypoint of prim list + +type error += Entrypoint_name_too_long of string + +(* Instruction typing errors *) +type error += Fail_not_in_tail_position of Script.location + +type error += + | Undefined_binop : + Script.location * prim * Script.expr * Script.expr + -> error + +type error += Undefined_unop : Script.location * prim * Script.expr -> error + +type error += + | Bad_return : Script.location * unparsed_stack_ty * Script.expr -> error + +type error += + | Bad_stack : Script.location * prim * int * unparsed_stack_ty -> error + +type error += + | Unmatched_branches : + Script.location * unparsed_stack_ty * unparsed_stack_ty + -> error + +(* View errors *) +type error += View_name_too_long of string + +type error += Bad_view_name of Script.location + +type error += + | Ill_typed_view of { + loc : Script.location; + actual : unparsed_stack_ty; + expected : unparsed_stack_ty; + } + +type error += Duplicated_view_name of Script.location + +type error += Self_in_lambda of Script.location + +type error += Bad_stack_length + +type error += Bad_stack_item of int + +type error += Inconsistent_annotations of string * string + +type error += + | Inconsistent_type_annotations : + Script.location * Script.expr * Script.expr + -> error + +type error += Inconsistent_field_annotations of string * string + +type error += Unexpected_annotation of Script.location + +type error += Ungrouped_annotations of Script.location + +type error += Invalid_map_body : Script.location * unparsed_stack_ty -> error + +type error += Invalid_map_block_fail of Script.location + +type error += + | Invalid_iter_body : + Script.location * unparsed_stack_ty * unparsed_stack_ty + -> error + +type error += Type_too_large : Script.location * int -> error + +type error += Pair_bad_argument of Script.location + +type error += Unpair_bad_argument of Script.location + +type error += Dup_n_bad_argument of Script.location + +type error += Dup_n_bad_stack of Script.location + +(* Value typing errors *) +type error += + | Invalid_constant : Script.location * Script.expr * Script.expr -> error + +type error += + | Invalid_syntactic_constant : Script.location * Script.expr * string -> error + +type error += Invalid_contract of Script.location * Contract.t + +type error += Invalid_big_map of Script.location * Big_map.Id.t + +type error += Comparable_type_expected : Script.location * Script.expr -> error + +type error += Inconsistent_type_sizes : int * int -> error + +type error += + | Inconsistent_types : + Script.location option * Script.expr * Script.expr + -> error + +type error += + | Inconsistent_memo_sizes : Sapling.Memo_size.t * Sapling.Memo_size.t -> error + +type error += Unordered_map_keys of Script.location * Script.expr + +type error += Unordered_set_values of Script.location * Script.expr + +type error += Duplicate_map_keys of Script.location * Script.expr + +type error += Duplicate_set_values of Script.location * Script.expr + +(* Toplevel errors *) +type error += + | Ill_typed_data : string option * Script.expr * Script.expr -> error + +type error += Ill_formed_type of string option * Script.expr * Script.location + +type error += Ill_typed_contract : Script.expr * type_map -> error + +(* Deprecation errors *) +type error += Deprecated_instruction of prim + +(* Stackoverflow errors *) +type error += Typechecking_too_many_recursive_calls + +type error += Unparsing_too_many_recursive_calls + +(* Ticket errors *) +type error += Unexpected_ticket of Script.location + +type error += Unexpected_forged_value of Script.location + +type error += Non_dupable_type of Script.location * Script.expr + +(* Impossible errors *) +type error += Unparsing_invariant_violated diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_tc_errors_registration.ml b/src/proto_012_PsiThaCa/lib_protocol/script_tc_errors_registration.ml new file mode 100644 index 000000000000..06c60d426ce6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_tc_errors_registration.ml @@ -0,0 +1,805 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Script +open Script_tc_errors + +(* Helpers for encoding *) +let type_map_enc = + let open Data_encoding in + let stack_enc = list (tup2 Script.expr_encoding (list string)) in + list + (conv + (fun (loc, (bef, aft)) -> (loc, bef, aft)) + (fun (loc, bef, aft) -> (loc, (bef, aft))) + (obj3 + (req "location" Script.location_encoding) + (req "stack_before" stack_enc) + (req "stack_after" stack_enc))) + +let stack_ty_enc = + let open Data_encoding in + list (obj2 (req "type" Script.expr_encoding) (dft "annots" (list string) [])) + +(* main registration *) +let () = + let open Data_encoding in + let located enc = + merge_objs (obj1 (req "location" Script.location_encoding)) enc + in + let arity_enc = int8 in + let namespace_enc = + def + "primitiveNamespace" + ~title:"Primitive namespace" + ~description: + "One of the five possible namespaces of primitive (data constructor, \ + type name, instruction, keyword, or constant hash)." + @@ string_enum + [ + ("type", Michelson_v1_primitives.Type_namespace); + ("constant", Constant_namespace); + ("instruction", Instr_namespace); + ("keyword", Keyword_namespace); + ("constant_hash", Constant_hash_namespace); + ] + in + let kind_enc = + def + "expressionKind" + ~title:"Expression kind" + ~description: + "One of the four possible kinds of expression (integer, string, \ + primitive application or sequence)." + @@ string_enum + [ + ("integer", Int_kind); + ("string", String_kind); + ("bytes", Bytes_kind); + ("primitiveApplication", Prim_kind); + ("sequence", Seq_kind); + ] + in + (* -- Structure errors ---------------------- *) + (* Invalid arity *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_arity" + ~title:"Invalid arity" + ~description: + "In a script or data expression, a primitive was applied to an \ + unsupported number of arguments." + (located + (obj3 + (req "primitive_name" Script.prim_encoding) + (req "expected_arity" arity_enc) + (req "wrong_arity" arity_enc))) + (function + | Invalid_arity (loc, name, exp, got) -> Some (loc, (name, exp, got)) + | _ -> None) + (fun (loc, (name, exp, got)) -> Invalid_arity (loc, name, exp, got)) ; + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_seq_arity" + ~title:"Invalid sequence arity" + ~description: + "In a script or data expression, a sequence was used with a number of \ + elements too small." + (located + (obj2 + (req "minimal_expected_arity" arity_enc) + (req "wrong_arity" arity_enc))) + (function + | Invalid_seq_arity (loc, exp, got) -> Some (loc, (exp, got)) | _ -> None) + (fun (loc, (exp, got)) -> Invalid_seq_arity (loc, exp, got)) ; + (* Missing field *) + register_error_kind + `Permanent + ~id:"michelson_v1.missing_script_field" + ~title:"Script is missing a field (parse error)" + ~description:"When parsing script, a field was expected, but not provided" + (obj1 (req "prim" prim_encoding)) + (function Missing_field prim -> Some prim | _ -> None) + (fun prim -> Missing_field prim) ; + (* Invalid primitive *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_primitive" + ~title:"Invalid primitive" + ~description:"In a script or data expression, a primitive was unknown." + (located + (obj2 + (dft "expected_primitive_names" (list prim_encoding) []) + (req "wrong_primitive_name" prim_encoding))) + (function + | Invalid_primitive (loc, exp, got) -> Some (loc, (exp, got)) | _ -> None) + (fun (loc, (exp, got)) -> Invalid_primitive (loc, exp, got)) ; + (* Invalid kind *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_expression_kind" + ~title:"Invalid expression kind" + ~description: + "In a script or data expression, an expression was of the wrong kind \ + (for instance a string where only a primitive applications can appear)." + (located + (obj2 (req "expected_kinds" (list kind_enc)) (req "wrong_kind" kind_enc))) + (function + | Invalid_kind (loc, exp, got) -> Some (loc, (exp, got)) | _ -> None) + (fun (loc, (exp, got)) -> Invalid_kind (loc, exp, got)) ; + (* Invalid namespace *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_primitive_namespace" + ~title:"Invalid primitive namespace" + ~description: + "In a script or data expression, a primitive was of the wrong namespace." + (located + (obj3 + (req "primitive_name" prim_encoding) + (req "expected_namespace" namespace_enc) + (req "wrong_namespace" namespace_enc))) + (function + | Invalid_namespace (loc, name, exp, got) -> Some (loc, (name, exp, got)) + | _ -> None) + (fun (loc, (name, exp, got)) -> Invalid_namespace (loc, name, exp, got)) ; + (* Invalid literal for type never *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_never_expr" + ~title:"Invalid expression for type never" + ~description: + "In a script or data expression, an expression was provided but a value \ + of type never was expected. No expression can have type never." + (located unit) + (function Invalid_never_expr loc -> Some (loc, ()) | _ -> None) + (fun (loc, ()) -> Invalid_never_expr loc) ; + (* Duplicate field *) + register_error_kind + `Permanent + ~id:"michelson_v1.duplicate_script_field" + ~title:"Script has a duplicated field (parse error)" + ~description:"When parsing script, a field was found more than once" + (obj2 (req "loc" location_encoding) (req "prim" prim_encoding)) + (function Duplicate_field (loc, prim) -> Some (loc, prim) | _ -> None) + (fun (loc, prim) -> Duplicate_field (loc, prim)) ; + (* Unexpected big_map *) + register_error_kind + `Permanent + ~id:"michelson_v1.unexpected_lazy_storage" + ~title:"Lazy storage in unauthorized position (type error)" + ~description: + "When parsing script, a big_map or sapling_state type was found in a \ + position where it could end up stored inside a big_map, which is \ + forbidden for now." + (obj1 (req "loc" location_encoding)) + (function Unexpected_lazy_storage loc -> Some loc | _ -> None) + (fun loc -> Unexpected_lazy_storage loc) ; + (* Unexpected operation *) + register_error_kind + `Permanent + ~id:"michelson_v1.unexpected_operation" + ~title:"Operation in unauthorized position (type error)" + ~description: + "When parsing script, an operation type was found in the storage or \ + parameter field." + (obj1 (req "loc" location_encoding)) + (function Unexpected_operation loc -> Some loc | _ -> None) + (fun loc -> Unexpected_operation loc) ; + (* No such entrypoint *) + register_error_kind + `Permanent + ~id:"michelson_v1.no_such_entrypoint" + ~title:"No such entrypoint (type error)" + ~description:"An entrypoint was not found when calling a contract." + (obj1 (req "entrypoint" string)) + (function No_such_entrypoint entrypoint -> Some entrypoint | _ -> None) + (fun entrypoint -> No_such_entrypoint entrypoint) ; + (* Unreachable entrypoint *) + register_error_kind + `Permanent + ~id:"michelson_v1.unreachable_entrypoint" + ~title:"Unreachable entrypoint (type error)" + ~description:"An entrypoint in the contract is not reachable." + (obj1 (req "path" (list prim_encoding))) + (function Unreachable_entrypoint path -> Some path | _ -> None) + (fun path -> Unreachable_entrypoint path) ; + (* Duplicate entrypoint *) + register_error_kind + `Permanent + ~id:"michelson_v1.duplicate_entrypoint" + ~title:"Duplicate entrypoint (type error)" + ~description:"Two entrypoints have the same name." + (obj1 (req "path" string)) + (function Duplicate_entrypoint entrypoint -> Some entrypoint | _ -> None) + (fun entrypoint -> Duplicate_entrypoint entrypoint) ; + (* Entrypoint name too long *) + register_error_kind + `Permanent + ~id:"michelson_v1.entrypoint_name_too_long" + ~title:"Entrypoint name too long (type error)" + ~description: + "An entrypoint name exceeds the maximum length of 31 characters." + (obj1 (req "name" string)) + (function + | Entrypoint_name_too_long entrypoint -> Some entrypoint | _ -> None) + (fun entrypoint -> Entrypoint_name_too_long entrypoint) ; + (* Unexpected contract *) + register_error_kind + `Permanent + ~id:"michelson_v1.unexpected_contract" + ~title:"Contract in unauthorized position (type error)" + ~description: + "When parsing script, a contract type was found in the storage or \ + parameter field." + (obj1 (req "loc" location_encoding)) + (function Unexpected_contract loc -> Some loc | _ -> None) + (fun loc -> Unexpected_contract loc) ; + (* -- Value typing errors ---------------------- *) + (* Unordered map keys *) + register_error_kind + `Permanent + ~id:"michelson_v1.unordered_map_literal" + ~title:"Invalid map key order" + ~description:"Map keys must be in strictly increasing order" + (obj2 + (req "location" Script.location_encoding) + (req "item" Script.expr_encoding)) + (function Unordered_map_keys (loc, expr) -> Some (loc, expr) | _ -> None) + (fun (loc, expr) -> Unordered_map_keys (loc, expr)) ; + (* Duplicate map keys *) + register_error_kind + `Permanent + ~id:"michelson_v1.duplicate_map_keys" + ~title:"Duplicate map keys" + ~description:"Map literals cannot contain duplicated keys" + (obj2 + (req "location" Script.location_encoding) + (req "item" Script.expr_encoding)) + (function Duplicate_map_keys (loc, expr) -> Some (loc, expr) | _ -> None) + (fun (loc, expr) -> Duplicate_map_keys (loc, expr)) ; + (* Unordered set values *) + register_error_kind + `Permanent + ~id:"michelson_v1.unordered_set_literal" + ~title:"Invalid set value order" + ~description:"Set values must be in strictly increasing order" + (obj2 + (req "location" Script.location_encoding) + (req "value" Script.expr_encoding)) + (function + | Unordered_set_values (loc, expr) -> Some (loc, expr) | _ -> None) + (fun (loc, expr) -> Unordered_set_values (loc, expr)) ; + (* Duplicate set values *) + register_error_kind + `Permanent + ~id:"michelson_v1.duplicate_set_values_in_literal" + ~title:"Sets literals cannot contain duplicate elements" + ~description: + "Set literals cannot contain duplicate elements, but a duplicate was \ + found while parsing." + (obj2 + (req "location" Script.location_encoding) + (req "value" Script.expr_encoding)) + (function + | Duplicate_set_values (loc, expr) -> Some (loc, expr) | _ -> None) + (fun (loc, expr) -> Duplicate_set_values (loc, expr)) ; + (* -- Instruction typing errors ------------- *) + (* Fail not in tail position *) + register_error_kind + `Permanent + ~id:"michelson_v1.fail_not_in_tail_position" + ~title:"FAIL not in tail position" + ~description:"There is non trivial garbage code after a FAIL instruction." + (located empty) + (function Fail_not_in_tail_position loc -> Some (loc, ()) | _ -> None) + (fun (loc, ()) -> Fail_not_in_tail_position loc) ; + (* Undefined binary operation *) + register_error_kind + `Permanent + ~id:"michelson_v1.undefined_binop" + ~title:"Undefined binop" + ~description: + "A binary operation is called on operands of types over which it is not \ + defined." + (located + (obj3 + (req "operator_name" prim_encoding) + (req "wrong_left_operand_type" Script.expr_encoding) + (req "wrong_right_operand_type" Script.expr_encoding))) + (function + | Undefined_binop (loc, n, tyl, tyr) -> Some (loc, (n, tyl, tyr)) + | _ -> None) + (fun (loc, (n, tyl, tyr)) -> Undefined_binop (loc, n, tyl, tyr)) ; + (* Undefined unary operation *) + register_error_kind + `Permanent + ~id:"michelson_v1.undefined_unop" + ~title:"Undefined unop" + ~description: + "A unary operation is called on an operand of type over which it is not \ + defined." + (located + (obj2 + (req "operator_name" prim_encoding) + (req "wrong_operand_type" Script.expr_encoding))) + (function Undefined_unop (loc, n, ty) -> Some (loc, (n, ty)) | _ -> None) + (fun (loc, (n, ty)) -> Undefined_unop (loc, n, ty)) ; + (* Bad return *) + register_error_kind + `Permanent + ~id:"michelson_v1.bad_return" + ~title:"Bad return" + ~description:"Unexpected stack at the end of a lambda or script." + (located + (obj2 + (req "expected_return_type" Script.expr_encoding) + (req "wrong_stack_type" stack_ty_enc))) + (function Bad_return (loc, sty, ty) -> Some (loc, (ty, sty)) | _ -> None) + (fun (loc, (ty, sty)) -> Bad_return (loc, sty, ty)) ; + (* Bad stack *) + register_error_kind + `Permanent + ~id:"michelson_v1.bad_stack" + ~title:"Bad stack" + ~description:"The stack has an unexpected length or contents." + (located + (obj3 + (req "primitive_name" prim_encoding) + (req "relevant_stack_portion" int16) + (req "wrong_stack_type" stack_ty_enc))) + (function + | Bad_stack (loc, name, s, sty) -> Some (loc, (name, s, sty)) | _ -> None) + (fun (loc, (name, s, sty)) -> Bad_stack (loc, name, s, sty)) ; + (* Inconsistent annotations *) + register_error_kind + `Permanent + ~id:"michelson_v1.inconsistent_annotations" + ~title:"Annotations inconsistent between branches" + ~description:"The annotations on two types could not be merged" + (obj2 (req "annot1" string) (req "annot2" string)) + (function + | Inconsistent_annotations (annot1, annot2) -> Some (annot1, annot2) + | _ -> None) + (fun (annot1, annot2) -> Inconsistent_annotations (annot1, annot2)) ; + (* Inconsistent field annotations *) + register_error_kind + `Permanent + ~id:"michelson_v1.inconsistent_field_annotations" + ~title:"Annotations for field accesses is inconsistent" + ~description: + "The specified field does not match the field annotation in the type" + (obj2 (req "annot1" string) (req "annot2" string)) + (function + | Inconsistent_field_annotations (annot1, annot2) -> Some (annot1, annot2) + | _ -> None) + (fun (annot1, annot2) -> Inconsistent_field_annotations (annot1, annot2)) ; + (* Inconsistent type annotations *) + register_error_kind + `Permanent + ~id:"michelson_v1.inconsistent_type_annotations" + ~title:"Types contain inconsistent annotations" + ~description:"The two types contain annotations that do not match" + (located + (obj2 + (req "type1" Script.expr_encoding) + (req "type2" Script.expr_encoding))) + (function + | Inconsistent_type_annotations (loc, ty1, ty2) -> Some (loc, (ty1, ty2)) + | _ -> None) + (fun (loc, (ty1, ty2)) -> Inconsistent_type_annotations (loc, ty1, ty2)) ; + (* Unexpected annotation *) + register_error_kind + `Permanent + ~id:"michelson_v1.unexpected_annotation" + ~title:"An annotation was encountered where no annotation is expected" + ~description:"A node in the syntax tree was improperly annotated" + (located empty) + (function Unexpected_annotation loc -> Some (loc, ()) | _ -> None) + (fun (loc, ()) -> Unexpected_annotation loc) ; + (* Ungrouped annotations *) + register_error_kind + `Permanent + ~id:"michelson_v1.ungrouped_annotations" + ~title:"Annotations of the same kind were found spread apart" + ~description:"Annotations of the same kind must be grouped" + (located empty) + (function Ungrouped_annotations loc -> Some (loc, ()) | _ -> None) + (fun (loc, ()) -> Ungrouped_annotations loc) ; + (* Unmatched branches *) + register_error_kind + `Permanent + ~id:"michelson_v1.unmatched_branches" + ~title:"Unmatched branches" + ~description: + "At the join point at the end of two code branches the stacks have \ + inconsistent lengths or contents." + (located + (obj2 + (req "first_stack_type" stack_ty_enc) + (req "other_stack_type" stack_ty_enc))) + (function + | Unmatched_branches (loc, stya, styb) -> Some (loc, (stya, styb)) + | _ -> None) + (fun (loc, (stya, styb)) -> Unmatched_branches (loc, stya, styb)) ; + (* Bad stack item *) + register_error_kind + `Permanent + ~id:"michelson_v1.bad_stack_item" + ~title:"Bad stack item" + ~description: + "The type of a stack item is unexpected (this error is always \ + accompanied by a more precise one)." + (obj1 (req "item_level" int16)) + (function Bad_stack_item n -> Some n | _ -> None) + (fun n -> Bad_stack_item n) ; + (* SELF in lambda *) + register_error_kind + `Permanent + ~id:"michelson_v1.self_in_lambda" + ~title:"SELF instruction in lambda" + ~description:"A SELF instruction was encountered in a lambda expression." + (located empty) + (function Self_in_lambda loc -> Some (loc, ()) | _ -> None) + (fun (loc, ()) -> Self_in_lambda loc) ; + (* Bad stack length *) + register_error_kind + `Permanent + ~id:"michelson_v1.inconsistent_stack_lengths" + ~title:"Inconsistent stack lengths" + ~description: + "A stack was of an unexpected length (this error is always in the \ + context of a located error)." + empty + (function Bad_stack_length -> Some () | _ -> None) + (fun () -> Bad_stack_length) ; + (* -- Value typing errors ------------------- *) + (* Invalid constant *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_constant" + ~title:"Invalid constant" + ~description:"A data expression was invalid for its expected type." + (located + (obj2 + (req "expected_type" Script.expr_encoding) + (req "wrong_expression" Script.expr_encoding))) + (function + | Invalid_constant (loc, expr, ty) -> Some (loc, (ty, expr)) | _ -> None) + (fun (loc, (ty, expr)) -> Invalid_constant (loc, expr, ty)) ; + (* View name too long *) + register_error_kind + `Permanent + ~id:"michelson_v1.view_name_too_long" + ~title:"View name too long (type error)" + ~description:"A view name exceeds the maximum length of 31 characters." + (obj1 (req "name" string)) + (function View_name_too_long name -> Some name | _ -> None) + (fun name -> View_name_too_long name) ; + (* Duplicated view name *) + register_error_kind + `Permanent + ~id:"michelson_v1.duplicated_view_name" + ~title:"Duplicated view name" + ~description:"The name of view in toplevel should be unique." + (obj1 (req "location" Script.location_encoding)) + (function Duplicated_view_name loc -> Some loc | _ -> None) + (fun loc -> Duplicated_view_name loc) ; + (* Invalid syntactic constant *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_syntactic_constant" + ~title:"Invalid constant (parse error)" + ~description:"A compile-time constant was invalid for its expected form." + (located + (obj2 + (req "expected_form" string) + (req "wrong_expression" Script.expr_encoding))) + (function + | Invalid_syntactic_constant (loc, expr, expected) -> + Some (loc, (expected, expr)) + | _ -> None) + (fun (loc, (expected, expr)) -> + Invalid_syntactic_constant (loc, expr, expected)) ; + (* Invalid contract *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_contract" + ~title:"Invalid contract" + ~description: + "A script or data expression references a contract that does not exist \ + or assumes a wrong type for an existing contract." + (located (obj1 (req "contract" Contract.encoding))) + (function Invalid_contract (loc, c) -> Some (loc, c) | _ -> None) + (fun (loc, c) -> Invalid_contract (loc, c)) ; + (* Invalid big_map *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_big_map" + ~title:"Invalid big_map" + ~description: + "A script or data expression references a big_map that does not exist or \ + assumes a wrong type for an existing big_map." + (located (obj1 (req "big_map" Big_map.Id.encoding))) + (function Invalid_big_map (loc, c) -> Some (loc, c) | _ -> None) + (fun (loc, c) -> Invalid_big_map (loc, c)) ; + (* Comparable type expected *) + register_error_kind + `Permanent + ~id:"michelson_v1.comparable_type_expected" + ~title:"Comparable type expected" + ~description: + "A non comparable type was used in a place where only comparable types \ + are accepted." + (located (obj1 (req "wrong_type" Script.expr_encoding))) + (function + | Comparable_type_expected (loc, ty) -> Some (loc, ty) | _ -> None) + (fun (loc, ty) -> Comparable_type_expected (loc, ty)) ; + (* Inconsistent type sizes *) + register_error_kind + `Permanent + ~id:"michelson_v1.inconsistent_type_sizes" + ~title:"Inconsistent type sizes" + ~description: + "Two types were expected to be equal but they have different sizes." + (obj2 (req "first_type_size" int31) (req "other_type_size" int31)) + (function + | Inconsistent_type_sizes (tya, tyb) -> Some (tya, tyb) | _ -> None) + (fun (tya, tyb) -> Inconsistent_type_sizes (tya, tyb)) ; + (* Inconsistent types *) + register_error_kind + `Permanent + ~id:"michelson_v1.inconsistent_types" + ~title:"Inconsistent types" + ~description: + "This is the basic type clash error, that appears in several places \ + where the equality of two types have to be proven, it is always \ + accompanied with another error that provides more context." + (obj3 + (opt "loc" Script.location_encoding) + (req "first_type" Script.expr_encoding) + (req "other_type" Script.expr_encoding)) + (function + | Inconsistent_types (loc, tya, tyb) -> Some (loc, tya, tyb) | _ -> None) + (fun (loc, tya, tyb) -> Inconsistent_types (loc, tya, tyb)) ; + (* Inconsistent memo_sizes *) + register_error_kind + `Permanent + ~id:"michelson_v1.inconsistent_memo_sizes" + ~title:"Inconsistent memo sizes" + ~description:"Memo sizes of two sapling states or transactions do not match" + (obj2 + (req "first_memo_size" Sapling.Memo_size.encoding) + (req "other_memo_size" Sapling.Memo_size.encoding)) + (function + | Inconsistent_memo_sizes (msa, msb) -> Some (msa, msb) | _ -> None) + (fun (msa, msb) -> Inconsistent_memo_sizes (msa, msb)) ; + (* -- Instruction typing errors ------------------- *) + (* Bad view name *) + register_error_kind + `Permanent + ~id:"michelson_v1.bad_view_name" + ~title:"Bad view name" + ~description:"In a view declaration, the view name must be a string" + (obj1 (req "loc" Script.location_encoding)) + (function Bad_view_name loc -> Some loc | _ -> None) + (fun loc -> Bad_view_name loc) ; + (* Invalid view body *) + register_error_kind + `Permanent + ~id:"michelson_v1.ill_typed_view" + ~title:"Ill typed view" + ~description:"The return of a view block did not match the expected type" + (obj3 + (req "loc" Script.location_encoding) + (req "resulted_view_stack" stack_ty_enc) + (req "expected_view_stack" stack_ty_enc)) + (function + | Ill_typed_view {loc; actual; expected} -> Some (loc, actual, expected) + | _ -> None) + (fun (loc, actual, expected) -> Ill_typed_view {loc; actual; expected}) ; + (* Invalid map body *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_map_body" + ~title:"Invalid map body" + ~description:"The body of a map block did not match the expected type" + (obj2 (req "loc" Script.location_encoding) (req "body_type" stack_ty_enc)) + (function Invalid_map_body (loc, stack) -> Some (loc, stack) | _ -> None) + (fun (loc, stack) -> Invalid_map_body (loc, stack)) ; + (* Invalid map block FAIL *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_map_block_fail" + ~title:"FAIL instruction occurred as body of map block" + ~description: + "FAIL cannot be the only instruction in the body. The proper type of the \ + return list cannot be inferred." + (obj1 (req "loc" Script.location_encoding)) + (function Invalid_map_block_fail loc -> Some loc | _ -> None) + (fun loc -> Invalid_map_block_fail loc) ; + (* Invalid ITER body *) + register_error_kind + `Permanent + ~id:"michelson_v1.invalid_iter_body" + ~title:"ITER body returned wrong stack type" + ~description: + "The body of an ITER instruction must result in the same stack type as \ + before the ITER." + (obj3 + (req "loc" Script.location_encoding) + (req "bef_stack" stack_ty_enc) + (req "aft_stack" stack_ty_enc)) + (function + | Invalid_iter_body (loc, bef, aft) -> Some (loc, bef, aft) | _ -> None) + (fun (loc, bef, aft) -> Invalid_iter_body (loc, bef, aft)) ; + (* Type too large *) + register_error_kind + `Permanent + ~id:"michelson_v1.type_too_large" + ~title:"Stack item type too large" + ~description:"An instruction generated a type larger than the limit." + (obj2 (req "loc" Script.location_encoding) (req "maximum_type_size" uint16)) + (function Type_too_large (loc, maxts) -> Some (loc, maxts) | _ -> None) + (fun (loc, maxts) -> Type_too_large (loc, maxts)) ; + (* Bad PAIR argument *) + register_error_kind + `Permanent + ~id:"michelson_v1.bad_pair_argument" + ~title:"0 or 1 passed to PAIR" + ~description:"PAIR expects an argument of at least 2" + (obj1 (req "loc" Script.location_encoding)) + (function Pair_bad_argument loc -> Some loc | _ -> None) + (fun loc -> Pair_bad_argument loc) ; + (* Bad UNPAIR argument *) + register_error_kind + `Permanent + ~id:"michelson_v1.bad_unpair_argument" + ~title:"0 or 1 passed to UNPAIR" + ~description:"UNPAIR expects an argument of at least 2" + (obj1 (req "loc" Script.location_encoding)) + (function Unpair_bad_argument loc -> Some loc | _ -> None) + (fun loc -> Unpair_bad_argument loc) ; + (* Bad dup_n argument *) + register_error_kind + `Permanent + ~id:"michelson_v1.bad_dupn_argument" + ~title:"0 passed to DUP n" + ~description:"DUP expects an argument of at least 1 (passed 0)" + (obj1 (req "loc" Script.location_encoding)) + (function Dup_n_bad_argument loc -> Some loc | _ -> None) + (fun loc -> Dup_n_bad_argument loc) ; + (* Bad dup_n stack *) + register_error_kind + `Permanent + ~id:"michelson_v1.bad_dupn_stack" + ~title:"Stack too short when typing DUP n" + ~description:"Stack present when typing DUP n was too short" + (obj1 (req "loc" Script.location_encoding)) + (function Dup_n_bad_stack x -> Some x | _ -> None) + (fun x -> Dup_n_bad_stack x) ; + (* -- Toplevel errors ------------------- *) + (* Ill typed data *) + register_error_kind + `Permanent + ~id:"michelson_v1.ill_typed_data" + ~title:"Ill typed data" + ~description: + "The toplevel error thrown when trying to typecheck a data expression \ + against a given type (always followed by more precise errors)." + (obj3 + (opt "identifier" string) + (req "expected_type" Script.expr_encoding) + (req "ill_typed_expression" Script.expr_encoding)) + (function + | Ill_typed_data (name, expr, ty) -> Some (name, ty, expr) | _ -> None) + (fun (name, ty, expr) -> Ill_typed_data (name, expr, ty)) ; + (* Ill formed type *) + register_error_kind + `Permanent + ~id:"michelson_v1.ill_formed_type" + ~title:"Ill formed type" + ~description: + "The toplevel error thrown when trying to parse a type expression \ + (always followed by more precise errors)." + (obj3 + (opt "identifier" string) + (req "ill_formed_expression" Script.expr_encoding) + (req "location" Script.location_encoding)) + (function + | Ill_formed_type (name, expr, loc) -> Some (name, expr, loc) | _ -> None) + (fun (name, expr, loc) -> Ill_formed_type (name, expr, loc)) ; + (* Ill typed contract *) + register_error_kind + `Permanent + ~id:"michelson_v1.ill_typed_contract" + ~title:"Ill typed contract" + ~description: + "The toplevel error thrown when trying to typecheck a contract code \ + against given input, output and storage types (always followed by more \ + precise errors)." + (obj2 + (req "ill_typed_code" Script.expr_encoding) + (req "type_map" type_map_enc)) + (function + | Ill_typed_contract (expr, type_map) -> Some (expr, type_map) | _ -> None) + (fun (expr, type_map) -> Ill_typed_contract (expr, type_map)) ; + (* Deprecated instruction *) + register_error_kind + `Permanent + ~id:"michelson_v1.deprecated_instruction" + ~title:"Script is using a deprecated instruction" + ~description: + "A deprecated instruction usage is disallowed in newly created contracts" + (obj1 (req "prim" prim_encoding)) + (function Deprecated_instruction prim -> Some prim | _ -> None) + (fun prim -> Deprecated_instruction prim) ; + (* Typechecking stack overflow *) + register_error_kind + `Temporary + ~id:"michelson_v1.typechecking_too_many_recursive_calls" + ~title:"Too many recursive calls during typechecking" + ~description:"Too many recursive calls were needed for typechecking" + Data_encoding.empty + (function Typechecking_too_many_recursive_calls -> Some () | _ -> None) + (fun () -> Typechecking_too_many_recursive_calls) ; + (* Unparsing stack overflow *) + register_error_kind + `Temporary + ~id:"michelson_v1.unparsing_stack_overflow" + ~title:"Too many recursive calls during unparsing" + ~description:"Too many recursive calls were needed for unparsing" + Data_encoding.empty + (function Unparsing_too_many_recursive_calls -> Some () | _ -> None) + (fun () -> Unparsing_too_many_recursive_calls) ; + (* Unexpected forged value *) + register_error_kind + `Permanent + ~id:"michelson_v1.unexpected_forged_value" + ~title:"Unexpected forged value" + ~description: + "A forged value was encountered but disallowed for that position." + (obj1 (req "location" Script.location_encoding)) + (function Unexpected_forged_value loc -> Some loc | _ -> None) + (fun loc -> Unexpected_forged_value loc) ; + (* Unexpected ticket *) + register_error_kind + `Permanent + ~id:"michelson_v1.unexpected_ticket" + ~title:"Ticket in unauthorized position (type error)" + ~description:"A ticket type has been found" + (obj1 (req "loc" location_encoding)) + (function Unexpected_ticket loc -> Some loc | _ -> None) + (fun loc -> Unexpected_ticket loc) ; + (* Attempt to duplicate a non-dupable type *) + register_error_kind + `Permanent + ~id:"michelson_v1.non_dupable_type" + ~title:"Non-dupable type duplication attempt" + ~description:"DUP was used on a non-dupable type (e.g. tickets)." + (obj2 (req "loc" location_encoding) (req "type" Script.expr_encoding)) + (function Non_dupable_type (loc, ty) -> Some (loc, ty) | _ -> None) + (fun (loc, ty) -> Non_dupable_type (loc, ty)) diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_tc_errors_registration.mli b/src/proto_012_PsiThaCa/lib_protocol/script_tc_errors_registration.mli new file mode 100644 index 000000000000..c8dd34c2e0bd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_tc_errors_registration.mli @@ -0,0 +1,34 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Script + +val type_map_enc : + (location * ((expr * string list) list * (expr * string list) list)) list + Data_encoding.encoding + +val stack_ty_enc : (expr * string list) list Data_encoding.encoding diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_timestamp_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/script_timestamp_repr.ml new file mode 100644 index 000000000000..22b51a4945f0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_timestamp_repr.ml @@ -0,0 +1,55 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = Z.t + +let compare = Z.compare + +let of_int64 = Z.of_int64 + +let of_string x = + match Time_repr.of_notation x with + | None -> Option.catch (fun () -> Z.of_string x) + | Some time -> Some (of_int64 (Time_repr.to_seconds time)) + +let to_notation x = + Option.catch (fun () -> + Time_repr.to_notation (Time.of_seconds (Z.to_int64 x))) + +let to_num_str = Z.to_string + +let to_string x = match to_notation x with None -> to_num_str x | Some s -> s + +let diff x y = Script_int_repr.of_zint @@ Z.sub x y + +let sub_delta t delta = Z.sub t (Script_int_repr.to_zint delta) + +let add_delta t delta = Z.add t (Script_int_repr.to_zint delta) + +let to_zint x = x + +let of_zint x = x + +let encoding : t Data_encoding.encoding = Data_encoding.z diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_timestamp_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/script_timestamp_repr.mli new file mode 100644 index 000000000000..2e628dae2991 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_timestamp_repr.mli @@ -0,0 +1,68 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Defines the internal Michelson representation for timestamps and basic + operations that can be performed on it. *) + +open Script_int_repr + +(** Representation of timestamps specific to the Michelson interpreter. + A number of seconds since the epoch. *) +type t + +(** Convert a number of seconds since the epoch to a timestamp.*) +val of_int64 : int64 -> t + +(** Compare timestamps. Returns [1] if the first timestamp is later than the + second one; [0] if they're equal and [-1] othwerwise. *) +val compare : t -> t -> int + +(** Convert a timestamp to RFC3339 notation if possible **) +val to_notation : t -> string option + +(** Convert a timestamp to a string representation of the seconds *) +val to_num_str : t -> string + +(** Convert to RFC3339 notation if possible, or num if not *) +val to_string : t -> string + +val of_string : string -> t option + +(** Returns difference between timestamps as integral number of seconds + in Michelson representation of numbers. *) +val diff : t -> t -> z num + +(** Add a number of seconds to the timestamp. *) +val add_delta : t -> z num -> t + +(** Subtract a number of seconds from the timestamp. *) +val sub_delta : t -> z num -> t + +val to_zint : t -> Z.t + +val of_zint : Z.t -> t + +(* Timestamps are encoded exactly as Z. *) +val encoding : t Data_encoding.encoding diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir.ml b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir.ml new file mode 100644 index 000000000000..9b990909ca57 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir.ml @@ -0,0 +1,2201 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Script_int +open Script_ir_annot + +(* + + The step function of the interpreter is parametrized by a bunch of values called the step constants. + These values are indeed constants during the call of a smart contract with the notable exception of + the IView instruction which modifies `source`, `self`, and `amount` and the KView_exit continuation + which restores them. + ====================== + +*) +type step_constants = { + source : Contract.t; + (** The address calling this contract, as returned by SENDER. *) + payer : Contract.t; + (** The address of the implicit account that initiated the chain of contract calls, as returned by SOURCE. *) + self : Contract.t; + (** The address of the contract being executed, as returned by SELF and SELF_ADDRESS. + Also used: + - as ticketer in TICKET + - as caller in VIEW, TRANSFER_TOKENS, and CREATE_CONTRACT *) + amount : Tez.t; + (** The amount of the current transaction, as returned by AMOUNT. *) + chain_id : Chain_id.t; + (** The chain id of the chain, as returned by CHAIN_ID. *) + now : Script_timestamp.t; + (** The earliest time at which the current block could have been timestamped, as returned by NOW. *) + level : Script_int.n Script_int.num; + (** The level of the current block, as returned by LEVEL. *) +} + +(* Preliminary definitions. *) + +type never = | + +type address = Contract.t * string + +type ('a, 'b) pair = 'a * 'b + +type ('a, 'b) union = L of 'a | R of 'b + +type operation = packed_internal_operation * Lazy_storage.diffs option + +type 'a ticket = {ticketer : Contract.t; contents : 'a; amount : n num} + +module type TYPE_SIZE = sig + (* A type size represents the size of its type parameter. + This constraint is enforced inside this module (Script_type_ir), hence there + should be no way to construct a type size outside of it. + + It allows keeping type metadata and types non-private. + + This module is here because we want three levels of visibility over this + code: + - inside this submodule, we have [type 'a t = int] + - outside of [Script_typed_ir], the ['a t] type is abstract and we have + the invariant that whenever [x : 'a t] we have that [x] is exactly + the size of ['a]. + - in-between (inside [Script_typed_ir] but outside the [Type_size] + submodule), the type is abstract but we have access to unsafe + constructors that can break the invariant. + *) + type 'a t + + val merge : 'a t -> 'b t -> 'a t tzresult + + val to_int : 'a t -> Saturation_repr.mul_safe Saturation_repr.t + + (* Unsafe constructors, to be used only safely and inside this module *) + + val one : _ t + + val two : _ t + + val three : _ t + + val four : (_, _) pair option t + + val compound1 : Script.location -> _ t -> _ t tzresult + + val compound2 : Script.location -> _ t -> _ t -> _ t tzresult +end + +module Type_size : TYPE_SIZE = struct + type 'a t = int + + let () = + (* static-like check that all [t] values fit in a [mul_safe] *) + let (_ : Saturation_repr.mul_safe Saturation_repr.t) = + Saturation_repr.mul_safe_of_int_exn Constants.michelson_maximum_type_size + in + () + + let to_int = Saturation_repr.mul_safe_of_int_exn + + let one = 1 + + let two = 2 + + let three = 3 + + let four = 4 + + let merge x y = + if Compare.Int.(x = y) then ok x + else error @@ Script_tc_errors.Inconsistent_type_sizes (x, y) + + let of_int loc size = + let max_size = Constants.michelson_maximum_type_size in + if Compare.Int.(size <= max_size) then ok size + else error (Script_tc_errors.Type_too_large (loc, max_size)) + + let compound1 loc size = of_int loc (1 + size) + + let compound2 loc size1 size2 = of_int loc (1 + size1 + size2) +end + +type empty_cell = EmptyCell + +type end_of_stack = empty_cell * empty_cell + +type 'a ty_metadata = {annot : type_annot option; size : 'a Type_size.t} + +type _ comparable_ty = + | Unit_key : unit ty_metadata -> unit comparable_ty + | Never_key : never ty_metadata -> never comparable_ty + | Int_key : z num ty_metadata -> z num comparable_ty + | Nat_key : n num ty_metadata -> n num comparable_ty + | Signature_key : signature ty_metadata -> signature comparable_ty + | String_key : Script_string.t ty_metadata -> Script_string.t comparable_ty + | Bytes_key : Bytes.t ty_metadata -> Bytes.t comparable_ty + | Mutez_key : Tez.t ty_metadata -> Tez.t comparable_ty + | Bool_key : bool ty_metadata -> bool comparable_ty + | Key_hash_key : public_key_hash ty_metadata -> public_key_hash comparable_ty + | Key_key : public_key ty_metadata -> public_key comparable_ty + | Timestamp_key : + Script_timestamp.t ty_metadata + -> Script_timestamp.t comparable_ty + | Chain_id_key : Chain_id.t ty_metadata -> Chain_id.t comparable_ty + | Address_key : address ty_metadata -> address comparable_ty + | Pair_key : + ('a comparable_ty * field_annot option) + * ('b comparable_ty * field_annot option) + * ('a, 'b) pair ty_metadata + -> ('a, 'b) pair comparable_ty + | Union_key : + ('a comparable_ty * field_annot option) + * ('b comparable_ty * field_annot option) + * ('a, 'b) union ty_metadata + -> ('a, 'b) union comparable_ty + | Option_key : + 'v comparable_ty * 'v option ty_metadata + -> 'v option comparable_ty + +let comparable_ty_metadata : type a. a comparable_ty -> a ty_metadata = function + | Unit_key meta -> meta + | Never_key meta -> meta + | Int_key meta -> meta + | Nat_key meta -> meta + | Signature_key meta -> meta + | String_key meta -> meta + | Bytes_key meta -> meta + | Mutez_key meta -> meta + | Bool_key meta -> meta + | Key_hash_key meta -> meta + | Key_key meta -> meta + | Timestamp_key meta -> meta + | Chain_id_key meta -> meta + | Address_key meta -> meta + | Pair_key (_, _, meta) -> meta + | Union_key (_, _, meta) -> meta + | Option_key (_, meta) -> meta + +let comparable_ty_size t = (comparable_ty_metadata t).size + +let unit_key ~annot = Unit_key {annot; size = Type_size.one} + +let never_key ~annot = Never_key {annot; size = Type_size.one} + +let int_key ~annot = Int_key {annot; size = Type_size.one} + +let nat_key ~annot = Nat_key {annot; size = Type_size.one} + +let signature_key ~annot = Signature_key {annot; size = Type_size.one} + +let string_key ~annot = String_key {annot; size = Type_size.one} + +let bytes_key ~annot = Bytes_key {annot; size = Type_size.one} + +let mutez_key ~annot = Mutez_key {annot; size = Type_size.one} + +let bool_key ~annot = Bool_key {annot; size = Type_size.one} + +let key_hash_key ~annot = Key_hash_key {annot; size = Type_size.one} + +let key_key ~annot = Key_key {annot; size = Type_size.one} + +let timestamp_key ~annot = Timestamp_key {annot; size = Type_size.one} + +let chain_id_key ~annot = Chain_id_key {annot; size = Type_size.one} + +let address_key ~annot = Address_key {annot; size = Type_size.one} + +let pair_key loc (l, fannot_l) (r, fannot_r) ~annot = + Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) + >|? fun size -> Pair_key ((l, fannot_l), (r, fannot_r), {annot; size}) + +let pair_3_key loc l m r = + pair_key loc m r ~annot:None >>? fun r -> pair_key loc l (r, None) ~annot:None + +let union_key loc (l, fannot_l) (r, fannot_r) ~annot = + Type_size.compound2 loc (comparable_ty_size l) (comparable_ty_size r) + >|? fun size -> Union_key ((l, fannot_l), (r, fannot_r), {annot; size}) + +let option_key loc t ~annot = + Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> + Option_key (t, {annot; size}) + +(* + + This signature contains the exact set of functions used in the + protocol. We do not include all [Set.S] because this would + increase the size of the first class modules used to represent + [boxed_set]. + + Warning: for any change in this signature, there must be a + change in [Script_typed_ir_size.value_size] which updates + [boxing_space] in the case for sets. + +*) +module type Boxed_set_OPS = sig + type t + + type elt + + val empty : t + + val add : elt -> t -> t + + val mem : elt -> t -> bool + + val remove : elt -> t -> t + + val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a +end + +module type Boxed_set = sig + type elt + + val elt_ty : elt comparable_ty + + module OPS : Boxed_set_OPS with type elt = elt + + val boxed : OPS.t + + val size : int +end + +type 'elt set = (module Boxed_set with type elt = 'elt) + +(* + + Same remark as for [Boxed_set_OPS]. (See below.) + +*) +module type Boxed_map_OPS = sig + type t + + type key + + type value + + val empty : t + + val add : key -> value -> t -> t + + val remove : key -> t -> t + + val find : key -> t -> value option + + val fold : (key -> value -> 'a -> 'a) -> t -> 'a -> 'a +end + +module type Boxed_map = sig + type key + + type value + + val key_ty : key comparable_ty + + module OPS : Boxed_map_OPS with type key = key and type value = value + + val boxed : OPS.t + + val size : int +end + +type ('key, 'value) map = + (module Boxed_map with type key = 'key and type value = 'value) + +module Big_map_overlay = Map.Make (struct + type t = Script_expr_hash.t + + let compare = Script_expr_hash.compare +end) + +type ('key, 'value) big_map_overlay = { + map : ('key * 'value option) Big_map_overlay.t; + size : int; +} + +type 'elt boxed_list = {elements : 'elt list; length : int} + +module SMap = Map.Make (Script_string) + +type view = { + input_ty : Script.node; + output_ty : Script.node; + view_code : Script.node; +} + +type ('arg, 'storage) script = { + code : (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; + arg_type : 'arg ty; + storage : 'storage; + storage_type : 'storage ty; + views : view SMap.t; + root_name : field_annot option; + code_size : Cache_memory_helpers.sint; + (* This is an over-approximation of the value size in memory, in + bytes, of the contract's static part, that is its source + code. This includes the code of the contract as well as the code + of the views. The storage size is not taken into account by this + field as it has a dynamic size. *) +} + +(* ---- Instructions --------------------------------------------------------*) +and ('before_top, 'before, 'result_top, 'result) kinstr = + (* + Stack + ----- + *) + | IDrop : + ('a, 'b * 's) kinfo * ('b, 's, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IDup : + ('a, 's) kinfo * ('a, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISwap : + ('a, 'b * 's) kinfo * ('b, 'a * 's, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IConst : + ('a, 's) kinfo * 'ty * ('ty, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + (* + Pairs + ----- + *) + | ICons_pair : + ('a, 'b * 's) kinfo * ('a * 'b, 's, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | ICar : + ('a * 'b, 's) kinfo * ('a, 's, 'r, 'f) kinstr + -> ('a * 'b, 's, 'r, 'f) kinstr + | ICdr : + ('a * 'b, 's) kinfo * ('b, 's, 'r, 'f) kinstr + -> ('a * 'b, 's, 'r, 'f) kinstr + | IUnpair : + ('a * 'b, 's) kinfo * ('a, 'b * 's, 'r, 'f) kinstr + -> ('a * 'b, 's, 'r, 'f) kinstr + (* + Options + ------- + *) + | ICons_some : + ('v, 's) kinfo * ('v option, 's, 'r, 'f) kinstr + -> ('v, 's, 'r, 'f) kinstr + | ICons_none : + ('a, 's) kinfo * ('b option, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IIf_none : { + kinfo : ('a option, 'b * 's) kinfo; + branch_if_none : ('b, 's, 'c, 't) kinstr; + branch_if_some : ('a, 'b * 's, 'c, 't) kinstr; + k : ('c, 't, 'r, 'f) kinstr; + } + -> ('a option, 'b * 's, 'r, 'f) kinstr + | IOpt_map : { + kinfo : ('a option, 's) kinfo; + body : ('a, 's, 'b, 's) kinstr; + k : ('b option, 's, 'c, 't) kinstr; + } + -> ('a option, 's, 'c, 't) kinstr + (* + Unions + ------ + *) + | ICons_left : + ('a, 's) kinfo * (('a, 'b) union, 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ICons_right : + ('b, 's) kinfo * (('a, 'b) union, 's, 'r, 'f) kinstr + -> ('b, 's, 'r, 'f) kinstr + | IIf_left : { + kinfo : (('a, 'b) union, 's) kinfo; + branch_if_left : ('a, 's, 'c, 't) kinstr; + branch_if_right : ('b, 's, 'c, 't) kinstr; + k : ('c, 't, 'r, 'f) kinstr; + } + -> (('a, 'b) union, 's, 'r, 'f) kinstr + (* + Lists + ----- + *) + | ICons_list : + ('a, 'a boxed_list * 's) kinfo * ('a boxed_list, 's, 'r, 'f) kinstr + -> ('a, 'a boxed_list * 's, 'r, 'f) kinstr + | INil : + ('a, 's) kinfo * ('b boxed_list, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IIf_cons : { + kinfo : ('a boxed_list, 'b * 's) kinfo; + branch_if_cons : ('a, 'a boxed_list * ('b * 's), 'c, 't) kinstr; + branch_if_nil : ('b, 's, 'c, 't) kinstr; + k : ('c, 't, 'r, 'f) kinstr; + } + -> ('a boxed_list, 'b * 's, 'r, 'f) kinstr + | IList_map : + ('a boxed_list, 'c * 's) kinfo + * ('a, 'c * 's, 'b, 'c * 's) kinstr + * ('b boxed_list, 'c * 's, 'r, 'f) kinstr + -> ('a boxed_list, 'c * 's, 'r, 'f) kinstr + | IList_iter : + ('a boxed_list, 'b * 's) kinfo + * ('a, 'b * 's, 'b, 's) kinstr + * ('b, 's, 'r, 'f) kinstr + -> ('a boxed_list, 'b * 's, 'r, 'f) kinstr + | IList_size : + ('a boxed_list, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> ('a boxed_list, 's, 'r, 'f) kinstr + (* + Sets + ---- + *) + | IEmpty_set : + ('a, 's) kinfo * 'b comparable_ty * ('b set, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISet_iter : + ('a set, 'b * 's) kinfo + * ('a, 'b * 's, 'b, 's) kinstr + * ('b, 's, 'r, 'f) kinstr + -> ('a set, 'b * 's, 'r, 'f) kinstr + | ISet_mem : + ('a, 'a set * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> ('a, 'a set * 's, 'r, 'f) kinstr + | ISet_update : + ('a, bool * ('a set * 's)) kinfo * ('a set, 's, 'r, 'f) kinstr + -> ('a, bool * ('a set * 's), 'r, 'f) kinstr + | ISet_size : + ('a set, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> ('a set, 's, 'r, 'f) kinstr + (* + Maps + ---- + *) + | IEmpty_map : + ('a, 's) kinfo * 'b comparable_ty * (('b, 'c) map, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IMap_map : + (('a, 'b) map, 'd * 's) kinfo + * ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr + * (('a, 'c) map, 'd * 's, 'r, 'f) kinstr + -> (('a, 'b) map, 'd * 's, 'r, 'f) kinstr + | IMap_iter : + (('a, 'b) map, 'c * 's) kinfo + * ('a * 'b, 'c * 's, 'c, 's) kinstr + * ('c, 's, 'r, 'f) kinstr + -> (('a, 'b) map, 'c * 's, 'r, 'f) kinstr + | IMap_mem : + ('a, ('a, 'b) map * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) map * 's, 'r, 'f) kinstr + | IMap_get : + ('a, ('a, 'b) map * 's) kinfo * ('b option, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) map * 's, 'r, 'f) kinstr + | IMap_update : + ('a, 'b option * (('a, 'b) map * 's)) kinfo + * (('a, 'b) map, 's, 'r, 'f) kinstr + -> ('a, 'b option * (('a, 'b) map * 's), 'r, 'f) kinstr + | IMap_get_and_update : + ('a, 'b option * (('a, 'b) map * 's)) kinfo + * ('b option, ('a, 'b) map * 's, 'r, 'f) kinstr + -> ('a, 'b option * (('a, 'b) map * 's), 'r, 'f) kinstr + | IMap_size : + (('a, 'b) map, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (('a, 'b) map, 's, 'r, 'f) kinstr + (* + Big maps + -------- + *) + | IEmpty_big_map : + ('a, 's) kinfo + * 'b comparable_ty + * 'c ty + * (('b, 'c) big_map, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IBig_map_mem : + ('a, ('a, 'b) big_map * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) big_map * 's, 'r, 'f) kinstr + | IBig_map_get : + ('a, ('a, 'b) big_map * 's) kinfo * ('b option, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) big_map * 's, 'r, 'f) kinstr + | IBig_map_update : + ('a, 'b option * (('a, 'b) big_map * 's)) kinfo + * (('a, 'b) big_map, 's, 'r, 'f) kinstr + -> ('a, 'b option * (('a, 'b) big_map * 's), 'r, 'f) kinstr + | IBig_map_get_and_update : + ('a, 'b option * (('a, 'b) big_map * 's)) kinfo + * ('b option, ('a, 'b) big_map * 's, 'r, 'f) kinstr + -> ('a, 'b option * (('a, 'b) big_map * 's), 'r, 'f) kinstr + (* + Strings + ------- + *) + | IConcat_string : + (Script_string.t boxed_list, 's) kinfo + * (Script_string.t, 's, 'r, 'f) kinstr + -> (Script_string.t boxed_list, 's, 'r, 'f) kinstr + | IConcat_string_pair : + (Script_string.t, Script_string.t * 's) kinfo + * (Script_string.t, 's, 'r, 'f) kinstr + -> (Script_string.t, Script_string.t * 's, 'r, 'f) kinstr + | ISlice_string : + (n num, n num * (Script_string.t * 's)) kinfo + * (Script_string.t option, 's, 'r, 'f) kinstr + -> (n num, n num * (Script_string.t * 's), 'r, 'f) kinstr + | IString_size : + (Script_string.t, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (Script_string.t, 's, 'r, 'f) kinstr + (* + Bytes + ----- + *) + | IConcat_bytes : + (bytes boxed_list, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes boxed_list, 's, 'r, 'f) kinstr + | IConcat_bytes_pair : + (bytes, bytes * 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, bytes * 's, 'r, 'f) kinstr + | ISlice_bytes : + (n num, n num * (bytes * 's)) kinfo * (bytes option, 's, 'r, 'f) kinstr + -> (n num, n num * (bytes * 's), 'r, 'f) kinstr + | IBytes_size : + (bytes, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + (* + Timestamps + ---------- + *) + | IAdd_seconds_to_timestamp : + (z num, Script_timestamp.t * 's) kinfo + * (Script_timestamp.t, 's, 'r, 'f) kinstr + -> (z num, Script_timestamp.t * 's, 'r, 'f) kinstr + | IAdd_timestamp_to_seconds : + (Script_timestamp.t, z num * 's) kinfo + * (Script_timestamp.t, 's, 'r, 'f) kinstr + -> (Script_timestamp.t, z num * 's, 'r, 'f) kinstr + | ISub_timestamp_seconds : + (Script_timestamp.t, z num * 's) kinfo + * (Script_timestamp.t, 's, 'r, 'f) kinstr + -> (Script_timestamp.t, z num * 's, 'r, 'f) kinstr + | IDiff_timestamps : + (Script_timestamp.t, Script_timestamp.t * 's) kinfo + * (z num, 's, 'r, 'f) kinstr + -> (Script_timestamp.t, Script_timestamp.t * 's, 'r, 'f) kinstr + (* + Tez + --- + *) + | IAdd_tez : + (Tez.t, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr + -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr + | ISub_tez : + (Tez.t, Tez.t * 's) kinfo * (Tez.t option, 's, 'r, 'f) kinstr + -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr + | ISub_tez_legacy : + (Tez.t, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr + -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr + | IMul_teznat : + (Tez.t, n num * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr + -> (Tez.t, n num * 's, 'r, 'f) kinstr + | IMul_nattez : + (n num, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr + -> (n num, Tez.t * 's, 'r, 'f) kinstr + | IEdiv_teznat : + (Tez.t, n num * 's) kinfo + * ((Tez.t, Tez.t) pair option, 's, 'r, 'f) kinstr + -> (Tez.t, n num * 's, 'r, 'f) kinstr + | IEdiv_tez : + (Tez.t, Tez.t * 's) kinfo + * ((n num, Tez.t) pair option, 's, 'r, 'f) kinstr + -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr + (* + Booleans + -------- + *) + | IOr : + (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (bool, bool * 's, 'r, 'f) kinstr + | IAnd : + (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (bool, bool * 's, 'r, 'f) kinstr + | IXor : + (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (bool, bool * 's, 'r, 'f) kinstr + | INot : + (bool, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (bool, 's, 'r, 'f) kinstr + (* + Integers + -------- + *) + | IIs_nat : + (z num, 's) kinfo * (n num option, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | INeg : + ('a num, 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 's, 'r, 'f) kinstr + | IAbs_int : + (z num, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | IInt_nat : + (n num, 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> (n num, 's, 'r, 'f) kinstr + | IAdd_int : + ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 'b num * 's, 'r, 'f) kinstr + | IAdd_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | ISub_int : + ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 'b num * 's, 'r, 'f) kinstr + | IMul_int : + ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 'b num * 's, 'r, 'f) kinstr + | IMul_nat : + (n num, 'a num * 's) kinfo * ('a num, 's, 'r, 'f) kinstr + -> (n num, 'a num * 's, 'r, 'f) kinstr + | IEdiv_int : + ('a num, 'b num * 's) kinfo + * ((z num, n num) pair option, 's, 'r, 'f) kinstr + -> ('a num, 'b num * 's, 'r, 'f) kinstr + | IEdiv_nat : + (n num, 'a num * 's) kinfo + * (('a num, n num) pair option, 's, 'r, 'f) kinstr + -> (n num, 'a num * 's, 'r, 'f) kinstr + | ILsl_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | ILsr_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | IOr_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + (* Even though `IAnd_nat` and `IAnd_int_nat` could be merged into a single + instruction from both the type and behavior point of views, their gas costs + differ too much (see `cost_N_IAnd_nat` and `cost_N_IAnd_int_nat` in + `Michelson_v1_gas.Cost_of.Generated_costs`), so we keep them separated. *) + | IAnd_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | IAnd_int_nat : + (z num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (z num, n num * 's, 'r, 'f) kinstr + | IXor_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | INot_int : + ('a num, 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 's, 'r, 'f) kinstr + (* + Control + ------- + *) + | IIf : { + kinfo : (bool, 'a * 's) kinfo; + branch_if_true : ('a, 's, 'b, 'u) kinstr; + branch_if_false : ('a, 's, 'b, 'u) kinstr; + k : ('b, 'u, 'r, 'f) kinstr; + } + -> (bool, 'a * 's, 'r, 'f) kinstr + | ILoop : + (bool, 'a * 's) kinfo + * ('a, 's, bool, 'a * 's) kinstr + * ('a, 's, 'r, 'f) kinstr + -> (bool, 'a * 's, 'r, 'f) kinstr + | ILoop_left : + (('a, 'b) union, 's) kinfo + * ('a, 's, ('a, 'b) union, 's) kinstr + * ('b, 's, 'r, 'f) kinstr + -> (('a, 'b) union, 's, 'r, 'f) kinstr + | IDip : + ('a, 'b * 's) kinfo + * ('b, 's, 'c, 't) kinstr + * ('a, 'c * 't, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IExec : + ('a, ('a, 'b) lambda * 's) kinfo * ('b, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) lambda * 's, 'r, 'f) kinstr + | IApply : + ('a, ('a * 'b, 'c) lambda * 's) kinfo + * 'a ty + * (('b, 'c) lambda, 's, 'r, 'f) kinstr + -> ('a, ('a * 'b, 'c) lambda * 's, 'r, 'f) kinstr + | ILambda : + ('a, 's) kinfo + * ('b, 'c) lambda + * (('b, 'c) lambda, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IFailwith : + ('a, 's) kinfo * Script.location * 'a ty + -> ('a, 's, 'r, 'f) kinstr + (* + Comparison + ---------- + *) + | ICompare : + ('a, 'a * 's) kinfo * 'a comparable_ty * (z num, 's, 'r, 'f) kinstr + -> ('a, 'a * 's, 'r, 'f) kinstr + (* + Comparators + ----------- + *) + | IEq : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | INeq : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | ILt : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | IGt : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | ILe : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | IGe : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + (* + Protocol + -------- + *) + | IAddress : + ('a typed_contract, 's) kinfo * (address, 's, 'r, 'f) kinstr + -> ('a typed_contract, 's, 'r, 'f) kinstr + | IContract : + (address, 's) kinfo + * 'a ty + * string + * ('a typed_contract option, 's, 'r, 'f) kinstr + -> (address, 's, 'r, 'f) kinstr + | IView : + ('a, address * 's) kinfo + * ('a, 'b) view_signature + * ('b option, 's, 'r, 'f) kinstr + -> ('a, address * 's, 'r, 'f) kinstr + | ITransfer_tokens : + ('a, Tez.t * ('a typed_contract * 's)) kinfo + * (operation, 's, 'r, 'f) kinstr + -> ('a, Tez.t * ('a typed_contract * 's), 'r, 'f) kinstr + | IImplicit_account : + (public_key_hash, 's) kinfo * (unit typed_contract, 's, 'r, 'f) kinstr + -> (public_key_hash, 's, 'r, 'f) kinstr + | ICreate_contract : { + kinfo : (public_key_hash option, Tez.t * ('a * 's)) kinfo; + storage_type : 'a ty; + arg_type : 'b ty; + lambda : ('b * 'a, operation boxed_list * 'a) lambda; + views : view SMap.t; + root_name : field_annot option; + k : (operation, address * 's, 'r, 'f) kinstr; + } + -> (public_key_hash option, Tez.t * ('a * 's), 'r, 'f) kinstr + | ISet_delegate : + (public_key_hash option, 's) kinfo * (operation, 's, 'r, 'f) kinstr + -> (public_key_hash option, 's, 'r, 'f) kinstr + | INow : + ('a, 's) kinfo * (Script_timestamp.t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IBalance : + ('a, 's) kinfo * (Tez.t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ILevel : + ('a, 's) kinfo * (n num, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ICheck_signature : + (public_key, signature * (bytes * 's)) kinfo * (bool, 's, 'r, 'f) kinstr + -> (public_key, signature * (bytes * 's), 'r, 'f) kinstr + | IHash_key : + (public_key, 's) kinfo * (public_key_hash, 's, 'r, 'f) kinstr + -> (public_key, 's, 'r, 'f) kinstr + | IPack : + ('a, 's) kinfo * 'a ty * (bytes, 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IUnpack : + (bytes, 's) kinfo * 'a ty * ('a option, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | IBlake2b : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | ISha256 : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | ISha512 : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | ISource : + ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISender : + ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISelf : + ('a, 's) kinfo + * 'b ty + * string + * ('b typed_contract, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISelf_address : + ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IAmount : + ('a, 's) kinfo * (Tez.t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISapling_empty_state : + ('a, 's) kinfo + * Sapling.Memo_size.t + * (Sapling.state, 'a * 's, 'b, 'f) kinstr + -> ('a, 's, 'b, 'f) kinstr + | ISapling_verify_update : + (Sapling.transaction, Sapling.state * 's) kinfo + * ((z num, Sapling.state) pair option, 's, 'r, 'f) kinstr + -> (Sapling.transaction, Sapling.state * 's, 'r, 'f) kinstr + | IDig : + ('a, 's) kinfo + * int + * ('b, 'c * 't, 'c, 't, 'a, 's, 'd, 'u) stack_prefix_preservation_witness + * ('b, 'd * 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IDug : + ('a, 'b * 's) kinfo + * int + * ('c, 't, 'a, 'c * 't, 'b, 's, 'd, 'u) stack_prefix_preservation_witness + * ('d, 'u, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IDipn : + ('a, 's) kinfo + * int + * ('c, 't, 'd, 'v, 'a, 's, 'b, 'u) stack_prefix_preservation_witness + * ('c, 't, 'd, 'v) kinstr + * ('b, 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IDropn : + ('a, 's) kinfo + * int + * ('b, 'u, 'b, 'u, 'a, 's, 'a, 's) stack_prefix_preservation_witness + * ('b, 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IChainId : + ('a, 's) kinfo * (Chain_id.t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | INever : (never, 's) kinfo -> (never, 's, 'r, 'f) kinstr + | IVoting_power : + (public_key_hash, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (public_key_hash, 's, 'r, 'f) kinstr + | ITotal_voting_power : + ('a, 's) kinfo * (n num, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IKeccak : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | ISha3 : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | IAdd_bls12_381_g1 : + (Bls12_381.G1.t, Bls12_381.G1.t * 's) kinfo + * (Bls12_381.G1.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G1.t, Bls12_381.G1.t * 's, 'r, 'f) kinstr + | IAdd_bls12_381_g2 : + (Bls12_381.G2.t, Bls12_381.G2.t * 's) kinfo + * (Bls12_381.G2.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G2.t, Bls12_381.G2.t * 's, 'r, 'f) kinstr + | IAdd_bls12_381_fr : + (Bls12_381.Fr.t, Bls12_381.Fr.t * 's) kinfo + * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IMul_bls12_381_g1 : + (Bls12_381.G1.t, Bls12_381.Fr.t * 's) kinfo + * (Bls12_381.G1.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G1.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IMul_bls12_381_g2 : + (Bls12_381.G2.t, Bls12_381.Fr.t * 's) kinfo + * (Bls12_381.G2.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G2.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IMul_bls12_381_fr : + (Bls12_381.Fr.t, Bls12_381.Fr.t * 's) kinfo + * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IMul_bls12_381_z_fr : + (Bls12_381.Fr.t, 'a num * 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, 'a num * 's, 'r, 'f) kinstr + | IMul_bls12_381_fr_z : + ('a num, Bls12_381.Fr.t * 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> ('a num, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IInt_bls12_381_fr : + (Bls12_381.Fr.t, 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + | INeg_bls12_381_g1 : + (Bls12_381.G1.t, 's) kinfo * (Bls12_381.G1.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G1.t, 's, 'r, 'f) kinstr + | INeg_bls12_381_g2 : + (Bls12_381.G2.t, 's) kinfo * (Bls12_381.G2.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G2.t, 's, 'r, 'f) kinstr + | INeg_bls12_381_fr : + (Bls12_381.Fr.t, 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + | IPairing_check_bls12_381 : + ((Bls12_381.G1.t, Bls12_381.G2.t) pair boxed_list, 's) kinfo + * (bool, 's, 'r, 'f) kinstr + -> ((Bls12_381.G1.t, Bls12_381.G2.t) pair boxed_list, 's, 'r, 'f) kinstr + | IComb : + ('a, 's) kinfo + * int + * ('a * 's, 'b * 'u) comb_gadt_witness + * ('b, 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IUncomb : + ('a, 's) kinfo + * int + * ('a * 's, 'b * 'u) uncomb_gadt_witness + * ('b, 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IComb_get : + ('t, 's) kinfo + * int + * ('t, 'v) comb_get_gadt_witness + * ('v, 's, 'r, 'f) kinstr + -> ('t, 's, 'r, 'f) kinstr + | IComb_set : + ('a, 'b * 's) kinfo + * int + * ('a, 'b, 'c) comb_set_gadt_witness + * ('c, 's, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IDup_n : + ('a, 's) kinfo + * int + * ('a * 's, 't) dup_n_gadt_witness + * ('t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ITicket : + ('a, n num * 's) kinfo * ('a ticket, 's, 'r, 'f) kinstr + -> ('a, n num * 's, 'r, 'f) kinstr + | IRead_ticket : + ('a ticket, 's) kinfo + * (address * ('a * n num), 'a ticket * 's, 'r, 'f) kinstr + -> ('a ticket, 's, 'r, 'f) kinstr + | ISplit_ticket : + ('a ticket, (n num * n num) * 's) kinfo + * (('a ticket * 'a ticket) option, 's, 'r, 'f) kinstr + -> ('a ticket, (n num * n num) * 's, 'r, 'f) kinstr + | IJoin_tickets : + ('a ticket * 'a ticket, 's) kinfo + * 'a comparable_ty + * ('a ticket option, 's, 'r, 'f) kinstr + -> ('a ticket * 'a ticket, 's, 'r, 'f) kinstr + | IOpen_chest : + (Timelock.chest_key, Timelock.chest * (n num * 's)) kinfo + * ((bytes, bool) union, 's, 'r, 'f) kinstr + -> (Timelock.chest_key, Timelock.chest * (n num * 's), 'r, 'f) kinstr + (* + Internal control instructions + ----------------------------- + *) + | IHalt : ('a, 's) kinfo -> ('a, 's, 'a, 's) kinstr + | ILog : + ('a, 's) kinfo * logging_event * logger * ('a, 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + +and logging_event = + | LogEntry : logging_event + | LogExit : ('b, 'u) kinfo -> logging_event + +and ('arg, 'ret) lambda = + | Lam : + ('arg, end_of_stack, 'ret, end_of_stack) kdescr * Script.node + -> ('arg, 'ret) lambda +[@@coq_force_gadt] + +and 'arg typed_contract = 'arg ty * address + +and (_, _, _, _) continuation = + | KNil : ('r, 'f, 'r, 'f) continuation + | KCons : + ('a, 's, 'b, 't) kinstr * ('b, 't, 'r, 'f) continuation + -> ('a, 's, 'r, 'f) continuation + | KReturn : + 's * ('a, 's, 'r, 'f) continuation + -> ('a, end_of_stack, 'r, 'f) continuation + | KMap_head : + ('a -> 'b) * ('b, 's, 'r, 'f) continuation + -> ('a, 's, 'r, 'f) continuation + | KUndip : + 'b * ('b, 'a * 's, 'r, 'f) continuation + -> ('a, 's, 'r, 'f) continuation + | KLoop_in : + ('a, 's, bool, 'a * 's) kinstr * ('a, 's, 'r, 'f) continuation + -> (bool, 'a * 's, 'r, 'f) continuation + | KLoop_in_left : + ('a, 's, ('a, 'b) union, 's) kinstr * ('b, 's, 'r, 'f) continuation + -> (('a, 'b) union, 's, 'r, 'f) continuation + | KIter : + ('a, 'b * 's, 'b, 's) kinstr * 'a list * ('b, 's, 'r, 'f) continuation + -> ('b, 's, 'r, 'f) continuation + | KList_enter_body : + ('a, 'c * 's, 'b, 'c * 's) kinstr + * 'a list + * 'b list + * int + * ('b boxed_list, 'c * 's, 'r, 'f) continuation + -> ('c, 's, 'r, 'f) continuation + | KList_exit_body : + ('a, 'c * 's, 'b, 'c * 's) kinstr + * 'a list + * 'b list + * int + * ('b boxed_list, 'c * 's, 'r, 'f) continuation + -> ('b, 'c * 's, 'r, 'f) continuation + | KMap_enter_body : + ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr + * ('a * 'b) list + * ('a, 'c) map + * (('a, 'c) map, 'd * 's, 'r, 'f) continuation + -> ('d, 's, 'r, 'f) continuation + | KMap_exit_body : + ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr + * ('a * 'b) list + * ('a, 'c) map + * 'a + * (('a, 'c) map, 'd * 's, 'r, 'f) continuation + -> ('c, 'd * 's, 'r, 'f) continuation + | KView_exit : + step_constants * ('a, 's, 'r, 'f) continuation + -> ('a, 's, 'r, 'f) continuation + | KLog : + ('a, 's, 'r, 'f) continuation * logger + -> ('a, 's, 'r, 'f) continuation + +and ('a, 's, 'b, 'f, 'c, 'u) logging_function = + ('a, 's, 'b, 'f) kinstr -> + context -> + Script.location -> + ('c, 'u) stack_ty -> + 'c * 'u -> + unit + +and execution_trace = + (Script.location * Gas.t * (Script.expr * string option) list) list + +and logger = { + log_interp : 'a 's 'b 'f 'c 'u. ('a, 's, 'b, 'f, 'c, 'u) logging_function; + log_entry : 'a 's 'b 'f. ('a, 's, 'b, 'f, 'a, 's) logging_function; + log_control : 'a 's 'b 'f. ('a, 's, 'b, 'f) continuation -> unit; + log_exit : 'a 's 'b 'f 'c 'u. ('a, 's, 'b, 'f, 'c, 'u) logging_function; + get_log : unit -> execution_trace option tzresult Lwt.t; +} + +(* ---- Auxiliary types -----------------------------------------------------*) +and 'ty ty = + | Unit_t : unit ty_metadata -> unit ty + | Int_t : z num ty_metadata -> z num ty + | Nat_t : n num ty_metadata -> n num ty + | Signature_t : signature ty_metadata -> signature ty + | String_t : Script_string.t ty_metadata -> Script_string.t ty + | Bytes_t : Bytes.t ty_metadata -> bytes ty + | Mutez_t : Tez.t ty_metadata -> Tez.t ty + | Key_hash_t : public_key_hash ty_metadata -> public_key_hash ty + | Key_t : public_key ty_metadata -> public_key ty + | Timestamp_t : Script_timestamp.t ty_metadata -> Script_timestamp.t ty + | Address_t : address ty_metadata -> address ty + | Bool_t : bool ty_metadata -> bool ty + | Pair_t : + ('a ty * field_annot option * var_annot option) + * ('b ty * field_annot option * var_annot option) + * ('a, 'b) pair ty_metadata + -> ('a, 'b) pair ty + | Union_t : + ('a ty * field_annot option) + * ('b ty * field_annot option) + * ('a, 'b) union ty_metadata + -> ('a, 'b) union ty + | Lambda_t : + 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata + -> ('arg, 'ret) lambda ty + | Option_t : 'v ty * 'v option ty_metadata -> 'v option ty + | List_t : 'v ty * 'v boxed_list ty_metadata -> 'v boxed_list ty + | Set_t : 'v comparable_ty * 'v set ty_metadata -> 'v set ty + | Map_t : + 'k comparable_ty * 'v ty * ('k, 'v) map ty_metadata + -> ('k, 'v) map ty + | Big_map_t : + 'k comparable_ty * 'v ty * ('k, 'v) big_map ty_metadata + -> ('k, 'v) big_map ty + | Contract_t : + 'arg ty * 'arg typed_contract ty_metadata + -> 'arg typed_contract ty + | Sapling_transaction_t : + Sapling.Memo_size.t * Sapling.transaction ty_metadata + -> Sapling.transaction ty + | Sapling_state_t : + Sapling.Memo_size.t * Sapling.state ty_metadata + -> Sapling.state ty + | Operation_t : operation ty_metadata -> operation ty + | Chain_id_t : Chain_id.t ty_metadata -> Chain_id.t ty + | Never_t : never ty_metadata -> never ty + | Bls12_381_g1_t : Bls12_381.G1.t ty_metadata -> Bls12_381.G1.t ty + | Bls12_381_g2_t : Bls12_381.G2.t ty_metadata -> Bls12_381.G2.t ty + | Bls12_381_fr_t : Bls12_381.Fr.t ty_metadata -> Bls12_381.Fr.t ty + | Ticket_t : 'a comparable_ty * 'a ticket ty_metadata -> 'a ticket ty + | Chest_key_t : Timelock.chest_key ty_metadata -> Timelock.chest_key ty + | Chest_t : Timelock.chest ty_metadata -> Timelock.chest ty + +and ('top_ty, 'resty) stack_ty = + | Item_t : + 'ty ty * ('ty2, 'rest) stack_ty * var_annot option + -> ('ty, 'ty2 * 'rest) stack_ty + | Bot_t : (empty_cell, empty_cell) stack_ty + +and ('key, 'value) big_map = { + id : Big_map.Id.t option; + diff : ('key, 'value) big_map_overlay; + key_type : 'key comparable_ty; + value_type : 'value ty; +} + +and ('a, 's, 'r, 'f) kdescr = { + kloc : Script.location; + kbef : ('a, 's) stack_ty; + kaft : ('r, 'f) stack_ty; + kinstr : ('a, 's, 'r, 'f) kinstr; +} + +and ('a, 's) kinfo = {iloc : Script.location; kstack_ty : ('a, 's) stack_ty} + +and (_, _, _, _, _, _, _, _) stack_prefix_preservation_witness = + | KPrefix : + ('y, 'u) kinfo + * ('c, 'v, 'd, 'w, 'x, 's, 'y, 'u) stack_prefix_preservation_witness + -> ( 'c, + 'v, + 'd, + 'w, + 'a, + 'x * 's, + 'a, + 'y * 'u ) + stack_prefix_preservation_witness + | KRest : ('a, 's, 'b, 'u, 'a, 's, 'b, 'u) stack_prefix_preservation_witness + +and ('before, 'after) comb_gadt_witness = + | Comb_one : ('a * ('x * 'before), 'a * ('x * 'before)) comb_gadt_witness + | Comb_succ : + ('before, 'b * 'after) comb_gadt_witness + -> ('a * 'before, ('a * 'b) * 'after) comb_gadt_witness + +and ('before, 'after) uncomb_gadt_witness = + | Uncomb_one : ('rest, 'rest) uncomb_gadt_witness + | Uncomb_succ : + ('b * 'before, 'after) uncomb_gadt_witness + -> (('a * 'b) * 'before, 'a * 'after) uncomb_gadt_witness + +and ('before, 'after) comb_get_gadt_witness = + | Comb_get_zero : ('b, 'b) comb_get_gadt_witness + | Comb_get_one : ('a * 'b, 'a) comb_get_gadt_witness + | Comb_get_plus_two : + ('before, 'after) comb_get_gadt_witness + -> ('a * 'before, 'after) comb_get_gadt_witness + +and ('value, 'before, 'after) comb_set_gadt_witness = + | Comb_set_zero : ('value, _, 'value) comb_set_gadt_witness + | Comb_set_one : ('value, 'hd * 'tl, 'value * 'tl) comb_set_gadt_witness + | Comb_set_plus_two : + ('value, 'before, 'after) comb_set_gadt_witness + -> ('value, 'a * 'before, 'a * 'after) comb_set_gadt_witness +[@@coq_force_gadt] + +and (_, _) dup_n_gadt_witness = + | Dup_n_zero : ('a * 'rest, 'a) dup_n_gadt_witness + | Dup_n_succ : + ('stack, 'b) dup_n_gadt_witness + -> ('a * 'stack, 'b) dup_n_gadt_witness + +and ('a, 'b) view_signature = + | View_signature of { + name : Script_string.t; + input_ty : 'a ty; + output_ty : 'b ty; + } + +let kinfo_of_kinstr : type a s b f. (a, s, b, f) kinstr -> (a, s) kinfo = + fun i -> + match i with + | IDrop (kinfo, _) -> kinfo + | IDup (kinfo, _) -> kinfo + | ISwap (kinfo, _) -> kinfo + | IConst (kinfo, _, _) -> kinfo + | ICons_pair (kinfo, _) -> kinfo + | ICar (kinfo, _) -> kinfo + | ICdr (kinfo, _) -> kinfo + | IUnpair (kinfo, _) -> kinfo + | ICons_some (kinfo, _) -> kinfo + | ICons_none (kinfo, _) -> kinfo + | IIf_none {kinfo; _} -> kinfo + | IOpt_map {kinfo; _} -> kinfo + | ICons_left (kinfo, _) -> kinfo + | ICons_right (kinfo, _) -> kinfo + | IIf_left {kinfo; _} -> kinfo + | ICons_list (kinfo, _) -> kinfo + | INil (kinfo, _) -> kinfo + | IIf_cons {kinfo; _} -> kinfo + | IList_map (kinfo, _, _) -> kinfo + | IList_iter (kinfo, _, _) -> kinfo + | IList_size (kinfo, _) -> kinfo + | IEmpty_set (kinfo, _, _) -> kinfo + | ISet_iter (kinfo, _, _) -> kinfo + | ISet_mem (kinfo, _) -> kinfo + | ISet_update (kinfo, _) -> kinfo + | ISet_size (kinfo, _) -> kinfo + | IEmpty_map (kinfo, _, _) -> kinfo + | IMap_map (kinfo, _, _) -> kinfo + | IMap_iter (kinfo, _, _) -> kinfo + | IMap_mem (kinfo, _) -> kinfo + | IMap_get (kinfo, _) -> kinfo + | IMap_update (kinfo, _) -> kinfo + | IMap_get_and_update (kinfo, _) -> kinfo + | IMap_size (kinfo, _) -> kinfo + | IEmpty_big_map (kinfo, _, _, _) -> kinfo + | IBig_map_mem (kinfo, _) -> kinfo + | IBig_map_get (kinfo, _) -> kinfo + | IBig_map_update (kinfo, _) -> kinfo + | IBig_map_get_and_update (kinfo, _) -> kinfo + | IConcat_string (kinfo, _) -> kinfo + | IConcat_string_pair (kinfo, _) -> kinfo + | ISlice_string (kinfo, _) -> kinfo + | IString_size (kinfo, _) -> kinfo + | IConcat_bytes (kinfo, _) -> kinfo + | IConcat_bytes_pair (kinfo, _) -> kinfo + | ISlice_bytes (kinfo, _) -> kinfo + | IBytes_size (kinfo, _) -> kinfo + | IAdd_seconds_to_timestamp (kinfo, _) -> kinfo + | IAdd_timestamp_to_seconds (kinfo, _) -> kinfo + | ISub_timestamp_seconds (kinfo, _) -> kinfo + | IDiff_timestamps (kinfo, _) -> kinfo + | IAdd_tez (kinfo, _) -> kinfo + | ISub_tez (kinfo, _) -> kinfo + | ISub_tez_legacy (kinfo, _) -> kinfo + | IMul_teznat (kinfo, _) -> kinfo + | IMul_nattez (kinfo, _) -> kinfo + | IEdiv_teznat (kinfo, _) -> kinfo + | IEdiv_tez (kinfo, _) -> kinfo + | IOr (kinfo, _) -> kinfo + | IAnd (kinfo, _) -> kinfo + | IXor (kinfo, _) -> kinfo + | INot (kinfo, _) -> kinfo + | IIs_nat (kinfo, _) -> kinfo + | INeg (kinfo, _) -> kinfo + | IAbs_int (kinfo, _) -> kinfo + | IInt_nat (kinfo, _) -> kinfo + | IAdd_int (kinfo, _) -> kinfo + | IAdd_nat (kinfo, _) -> kinfo + | ISub_int (kinfo, _) -> kinfo + | IMul_int (kinfo, _) -> kinfo + | IMul_nat (kinfo, _) -> kinfo + | IEdiv_int (kinfo, _) -> kinfo + | IEdiv_nat (kinfo, _) -> kinfo + | ILsl_nat (kinfo, _) -> kinfo + | ILsr_nat (kinfo, _) -> kinfo + | IOr_nat (kinfo, _) -> kinfo + | IAnd_nat (kinfo, _) -> kinfo + | IAnd_int_nat (kinfo, _) -> kinfo + | IXor_nat (kinfo, _) -> kinfo + | INot_int (kinfo, _) -> kinfo + | IIf {kinfo; _} -> kinfo + | ILoop (kinfo, _, _) -> kinfo + | ILoop_left (kinfo, _, _) -> kinfo + | IDip (kinfo, _, _) -> kinfo + | IExec (kinfo, _) -> kinfo + | IApply (kinfo, _, _) -> kinfo + | ILambda (kinfo, _, _) -> kinfo + | IFailwith (kinfo, _, _) -> kinfo + | ICompare (kinfo, _, _) -> kinfo + | IEq (kinfo, _) -> kinfo + | INeq (kinfo, _) -> kinfo + | ILt (kinfo, _) -> kinfo + | IGt (kinfo, _) -> kinfo + | ILe (kinfo, _) -> kinfo + | IGe (kinfo, _) -> kinfo + | IAddress (kinfo, _) -> kinfo + | IContract (kinfo, _, _, _) -> kinfo + | ITransfer_tokens (kinfo, _) -> kinfo + | IView (kinfo, _, _) -> kinfo + | IImplicit_account (kinfo, _) -> kinfo + | ICreate_contract {kinfo; _} -> kinfo + | ISet_delegate (kinfo, _) -> kinfo + | INow (kinfo, _) -> kinfo + | IBalance (kinfo, _) -> kinfo + | ILevel (kinfo, _) -> kinfo + | ICheck_signature (kinfo, _) -> kinfo + | IHash_key (kinfo, _) -> kinfo + | IPack (kinfo, _, _) -> kinfo + | IUnpack (kinfo, _, _) -> kinfo + | IBlake2b (kinfo, _) -> kinfo + | ISha256 (kinfo, _) -> kinfo + | ISha512 (kinfo, _) -> kinfo + | ISource (kinfo, _) -> kinfo + | ISender (kinfo, _) -> kinfo + | ISelf (kinfo, _, _, _) -> kinfo + | ISelf_address (kinfo, _) -> kinfo + | IAmount (kinfo, _) -> kinfo + | ISapling_empty_state (kinfo, _, _) -> kinfo + | ISapling_verify_update (kinfo, _) -> kinfo + | IDig (kinfo, _, _, _) -> kinfo + | IDug (kinfo, _, _, _) -> kinfo + | IDipn (kinfo, _, _, _, _) -> kinfo + | IDropn (kinfo, _, _, _) -> kinfo + | IChainId (kinfo, _) -> kinfo + | INever kinfo -> kinfo + | IVoting_power (kinfo, _) -> kinfo + | ITotal_voting_power (kinfo, _) -> kinfo + | IKeccak (kinfo, _) -> kinfo + | ISha3 (kinfo, _) -> kinfo + | IAdd_bls12_381_g1 (kinfo, _) -> kinfo + | IAdd_bls12_381_g2 (kinfo, _) -> kinfo + | IAdd_bls12_381_fr (kinfo, _) -> kinfo + | IMul_bls12_381_g1 (kinfo, _) -> kinfo + | IMul_bls12_381_g2 (kinfo, _) -> kinfo + | IMul_bls12_381_fr (kinfo, _) -> kinfo + | IMul_bls12_381_z_fr (kinfo, _) -> kinfo + | IMul_bls12_381_fr_z (kinfo, _) -> kinfo + | IInt_bls12_381_fr (kinfo, _) -> kinfo + | INeg_bls12_381_g1 (kinfo, _) -> kinfo + | INeg_bls12_381_g2 (kinfo, _) -> kinfo + | INeg_bls12_381_fr (kinfo, _) -> kinfo + | IPairing_check_bls12_381 (kinfo, _) -> kinfo + | IComb (kinfo, _, _, _) -> kinfo + | IUncomb (kinfo, _, _, _) -> kinfo + | IComb_get (kinfo, _, _, _) -> kinfo + | IComb_set (kinfo, _, _, _) -> kinfo + | IDup_n (kinfo, _, _, _) -> kinfo + | ITicket (kinfo, _) -> kinfo + | IRead_ticket (kinfo, _) -> kinfo + | ISplit_ticket (kinfo, _) -> kinfo + | IJoin_tickets (kinfo, _, _) -> kinfo + | IHalt kinfo -> kinfo + | ILog (kinfo, _, _, _) -> kinfo + | IOpen_chest (kinfo, _) -> kinfo + +type kinstr_rewritek = { + apply : 'b 'u 'r 'f. ('b, 'u, 'r, 'f) kinstr -> ('b, 'u, 'r, 'f) kinstr; +} + +let kinstr_rewritek : + type a s r f. (a, s, r, f) kinstr -> kinstr_rewritek -> (a, s, r, f) kinstr + = + fun i f -> + match i with + | IDrop (kinfo, k) -> IDrop (kinfo, f.apply k) + | IDup (kinfo, k) -> IDup (kinfo, f.apply k) + | ISwap (kinfo, k) -> ISwap (kinfo, f.apply k) + | IConst (kinfo, x, k) -> IConst (kinfo, x, f.apply k) + | ICons_pair (kinfo, k) -> ICons_pair (kinfo, f.apply k) + | ICar (kinfo, k) -> ICar (kinfo, f.apply k) + | ICdr (kinfo, k) -> ICdr (kinfo, f.apply k) + | IUnpair (kinfo, k) -> IUnpair (kinfo, f.apply k) + | ICons_some (kinfo, k) -> ICons_some (kinfo, f.apply k) + | ICons_none (kinfo, k) -> ICons_none (kinfo, f.apply k) + | IIf_none {kinfo; branch_if_none; branch_if_some; k} -> + IIf_none + { + kinfo; + branch_if_none = f.apply branch_if_none; + branch_if_some = f.apply branch_if_some; + k = f.apply k; + } + | IOpt_map {kinfo; body; k} -> + let body = f.apply body in + let k = f.apply k in + IOpt_map {kinfo; body; k} + | ICons_left (kinfo, k) -> ICons_left (kinfo, f.apply k) + | ICons_right (kinfo, k) -> ICons_right (kinfo, f.apply k) + | IIf_left {kinfo; branch_if_left; branch_if_right; k} -> + IIf_left + { + kinfo; + branch_if_left = f.apply branch_if_left; + branch_if_right = f.apply branch_if_right; + k = f.apply k; + } + | ICons_list (kinfo, k) -> ICons_list (kinfo, f.apply k) + | INil (kinfo, k) -> INil (kinfo, f.apply k) + | IIf_cons {kinfo; branch_if_cons; branch_if_nil; k} -> + IIf_cons + { + kinfo; + branch_if_cons = f.apply branch_if_cons; + branch_if_nil = f.apply branch_if_nil; + k = f.apply k; + } + | IList_map (kinfo, body, k) -> IList_map (kinfo, f.apply body, f.apply k) + | IList_iter (kinfo, body, k) -> IList_iter (kinfo, f.apply body, f.apply k) + | IList_size (kinfo, k) -> IList_size (kinfo, f.apply k) + | IEmpty_set (kinfo, ty, k) -> IEmpty_set (kinfo, ty, f.apply k) + | ISet_iter (kinfo, body, k) -> ISet_iter (kinfo, f.apply body, f.apply k) + | ISet_mem (kinfo, k) -> ISet_mem (kinfo, f.apply k) + | ISet_update (kinfo, k) -> ISet_update (kinfo, f.apply k) + | ISet_size (kinfo, k) -> ISet_size (kinfo, f.apply k) + | IEmpty_map (kinfo, cty, k) -> IEmpty_map (kinfo, cty, f.apply k) + | IMap_map (kinfo, body, k) -> IMap_map (kinfo, f.apply body, f.apply k) + | IMap_iter (kinfo, body, k) -> IMap_iter (kinfo, f.apply body, f.apply k) + | IMap_mem (kinfo, k) -> IMap_mem (kinfo, f.apply k) + | IMap_get (kinfo, k) -> IMap_get (kinfo, f.apply k) + | IMap_update (kinfo, k) -> IMap_update (kinfo, f.apply k) + | IMap_get_and_update (kinfo, k) -> IMap_get_and_update (kinfo, f.apply k) + | IMap_size (kinfo, k) -> IMap_size (kinfo, f.apply k) + | IEmpty_big_map (kinfo, cty, ty, k) -> + IEmpty_big_map (kinfo, cty, ty, f.apply k) + | IBig_map_mem (kinfo, k) -> IBig_map_mem (kinfo, f.apply k) + | IBig_map_get (kinfo, k) -> IBig_map_get (kinfo, f.apply k) + | IBig_map_update (kinfo, k) -> IBig_map_update (kinfo, f.apply k) + | IBig_map_get_and_update (kinfo, k) -> + IBig_map_get_and_update (kinfo, f.apply k) + | IConcat_string (kinfo, k) -> IConcat_string (kinfo, f.apply k) + | IConcat_string_pair (kinfo, k) -> IConcat_string_pair (kinfo, f.apply k) + | ISlice_string (kinfo, k) -> ISlice_string (kinfo, f.apply k) + | IString_size (kinfo, k) -> IString_size (kinfo, f.apply k) + | IConcat_bytes (kinfo, k) -> IConcat_bytes (kinfo, f.apply k) + | IConcat_bytes_pair (kinfo, k) -> IConcat_bytes_pair (kinfo, f.apply k) + | ISlice_bytes (kinfo, k) -> ISlice_bytes (kinfo, f.apply k) + | IBytes_size (kinfo, k) -> IBytes_size (kinfo, f.apply k) + | IAdd_seconds_to_timestamp (kinfo, k) -> + IAdd_seconds_to_timestamp (kinfo, f.apply k) + | IAdd_timestamp_to_seconds (kinfo, k) -> + IAdd_timestamp_to_seconds (kinfo, f.apply k) + | ISub_timestamp_seconds (kinfo, k) -> + ISub_timestamp_seconds (kinfo, f.apply k) + | IDiff_timestamps (kinfo, k) -> IDiff_timestamps (kinfo, f.apply k) + | IAdd_tez (kinfo, k) -> IAdd_tez (kinfo, f.apply k) + | ISub_tez (kinfo, k) -> ISub_tez (kinfo, f.apply k) + | ISub_tez_legacy (kinfo, k) -> ISub_tez_legacy (kinfo, f.apply k) + | IMul_teznat (kinfo, k) -> IMul_teznat (kinfo, f.apply k) + | IMul_nattez (kinfo, k) -> IMul_nattez (kinfo, f.apply k) + | IEdiv_teznat (kinfo, k) -> IEdiv_teznat (kinfo, f.apply k) + | IEdiv_tez (kinfo, k) -> IEdiv_tez (kinfo, f.apply k) + | IOr (kinfo, k) -> IOr (kinfo, f.apply k) + | IAnd (kinfo, k) -> IAnd (kinfo, f.apply k) + | IXor (kinfo, k) -> IXor (kinfo, f.apply k) + | INot (kinfo, k) -> INot (kinfo, f.apply k) + | IIs_nat (kinfo, k) -> IIs_nat (kinfo, f.apply k) + | INeg (kinfo, k) -> INeg (kinfo, f.apply k) + | IAbs_int (kinfo, k) -> IAbs_int (kinfo, f.apply k) + | IInt_nat (kinfo, k) -> IInt_nat (kinfo, f.apply k) + | IAdd_int (kinfo, k) -> IAdd_int (kinfo, f.apply k) + | IAdd_nat (kinfo, k) -> IAdd_nat (kinfo, f.apply k) + | ISub_int (kinfo, k) -> ISub_int (kinfo, f.apply k) + | IMul_int (kinfo, k) -> IMul_int (kinfo, f.apply k) + | IMul_nat (kinfo, k) -> IMul_nat (kinfo, f.apply k) + | IEdiv_int (kinfo, k) -> IEdiv_int (kinfo, f.apply k) + | IEdiv_nat (kinfo, k) -> IEdiv_nat (kinfo, f.apply k) + | ILsl_nat (kinfo, k) -> ILsl_nat (kinfo, f.apply k) + | ILsr_nat (kinfo, k) -> ILsr_nat (kinfo, f.apply k) + | IOr_nat (kinfo, k) -> IOr_nat (kinfo, f.apply k) + | IAnd_nat (kinfo, k) -> IAnd_nat (kinfo, f.apply k) + | IAnd_int_nat (kinfo, k) -> IAnd_int_nat (kinfo, f.apply k) + | IXor_nat (kinfo, k) -> IXor_nat (kinfo, f.apply k) + | INot_int (kinfo, k) -> INot_int (kinfo, f.apply k) + | IIf {kinfo; branch_if_true; branch_if_false; k} -> + IIf + { + kinfo; + branch_if_true = f.apply branch_if_true; + branch_if_false = f.apply branch_if_false; + k = f.apply k; + } + | ILoop (kinfo, kbody, k) -> ILoop (kinfo, f.apply kbody, f.apply k) + | ILoop_left (kinfo, kl, kr) -> ILoop_left (kinfo, f.apply kl, f.apply kr) + | IDip (kinfo, body, k) -> IDip (kinfo, f.apply body, f.apply k) + | IExec (kinfo, k) -> IExec (kinfo, f.apply k) + | IApply (kinfo, ty, k) -> IApply (kinfo, ty, f.apply k) + | ILambda (kinfo, l, k) -> ILambda (kinfo, l, f.apply k) + | IFailwith (kinfo, i, ty) -> IFailwith (kinfo, i, ty) + | ICompare (kinfo, ty, k) -> ICompare (kinfo, ty, f.apply k) + | IEq (kinfo, k) -> IEq (kinfo, f.apply k) + | INeq (kinfo, k) -> INeq (kinfo, f.apply k) + | ILt (kinfo, k) -> ILt (kinfo, f.apply k) + | IGt (kinfo, k) -> IGt (kinfo, f.apply k) + | ILe (kinfo, k) -> ILe (kinfo, f.apply k) + | IGe (kinfo, k) -> IGe (kinfo, f.apply k) + | IAddress (kinfo, k) -> IAddress (kinfo, f.apply k) + | IContract (kinfo, ty, code, k) -> IContract (kinfo, ty, code, f.apply k) + | ITransfer_tokens (kinfo, k) -> ITransfer_tokens (kinfo, f.apply k) + | IView (kinfo, view_signature, k) -> IView (kinfo, view_signature, f.apply k) + | IImplicit_account (kinfo, k) -> IImplicit_account (kinfo, f.apply k) + | ICreate_contract + {kinfo; storage_type; arg_type; lambda; views; root_name; k} -> + let k = f.apply k in + ICreate_contract + {kinfo; storage_type; arg_type; lambda; views; root_name; k} + | ISet_delegate (kinfo, k) -> ISet_delegate (kinfo, f.apply k) + | INow (kinfo, k) -> INow (kinfo, f.apply k) + | IBalance (kinfo, k) -> IBalance (kinfo, f.apply k) + | ILevel (kinfo, k) -> ILevel (kinfo, f.apply k) + | ICheck_signature (kinfo, k) -> ICheck_signature (kinfo, f.apply k) + | IHash_key (kinfo, k) -> IHash_key (kinfo, f.apply k) + | IPack (kinfo, ty, k) -> IPack (kinfo, ty, f.apply k) + | IUnpack (kinfo, ty, k) -> IUnpack (kinfo, ty, f.apply k) + | IBlake2b (kinfo, k) -> IBlake2b (kinfo, f.apply k) + | ISha256 (kinfo, k) -> ISha256 (kinfo, f.apply k) + | ISha512 (kinfo, k) -> ISha512 (kinfo, f.apply k) + | ISource (kinfo, k) -> ISource (kinfo, f.apply k) + | ISender (kinfo, k) -> ISender (kinfo, f.apply k) + | ISelf (kinfo, ty, s, k) -> ISelf (kinfo, ty, s, f.apply k) + | ISelf_address (kinfo, k) -> ISelf_address (kinfo, f.apply k) + | IAmount (kinfo, k) -> IAmount (kinfo, f.apply k) + | ISapling_empty_state (kinfo, s, k) -> + ISapling_empty_state (kinfo, s, f.apply k) + | ISapling_verify_update (kinfo, k) -> + ISapling_verify_update (kinfo, f.apply k) + | IDig (kinfo, n, p, k) -> IDig (kinfo, n, p, f.apply k) + | IDug (kinfo, n, p, k) -> IDug (kinfo, n, p, f.apply k) + | IDipn (kinfo, n, p, k1, k2) -> IDipn (kinfo, n, p, f.apply k1, f.apply k2) + | IDropn (kinfo, n, p, k) -> IDropn (kinfo, n, p, f.apply k) + | IChainId (kinfo, k) -> IChainId (kinfo, f.apply k) + | INever kinfo -> INever kinfo + | IVoting_power (kinfo, k) -> IVoting_power (kinfo, f.apply k) + | ITotal_voting_power (kinfo, k) -> ITotal_voting_power (kinfo, f.apply k) + | IKeccak (kinfo, k) -> IKeccak (kinfo, f.apply k) + | ISha3 (kinfo, k) -> ISha3 (kinfo, f.apply k) + | IAdd_bls12_381_g1 (kinfo, k) -> IAdd_bls12_381_g1 (kinfo, f.apply k) + | IAdd_bls12_381_g2 (kinfo, k) -> IAdd_bls12_381_g2 (kinfo, f.apply k) + | IAdd_bls12_381_fr (kinfo, k) -> IAdd_bls12_381_fr (kinfo, f.apply k) + | IMul_bls12_381_g1 (kinfo, k) -> IMul_bls12_381_g1 (kinfo, f.apply k) + | IMul_bls12_381_g2 (kinfo, k) -> IMul_bls12_381_g2 (kinfo, f.apply k) + | IMul_bls12_381_fr (kinfo, k) -> IMul_bls12_381_fr (kinfo, f.apply k) + | IMul_bls12_381_z_fr (kinfo, k) -> IMul_bls12_381_z_fr (kinfo, f.apply k) + | IMul_bls12_381_fr_z (kinfo, k) -> IMul_bls12_381_fr_z (kinfo, f.apply k) + | IInt_bls12_381_fr (kinfo, k) -> IInt_bls12_381_fr (kinfo, f.apply k) + | INeg_bls12_381_g1 (kinfo, k) -> INeg_bls12_381_g1 (kinfo, f.apply k) + | INeg_bls12_381_g2 (kinfo, k) -> INeg_bls12_381_g2 (kinfo, f.apply k) + | INeg_bls12_381_fr (kinfo, k) -> INeg_bls12_381_fr (kinfo, f.apply k) + | IPairing_check_bls12_381 (kinfo, k) -> + IPairing_check_bls12_381 (kinfo, f.apply k) + | IComb (kinfo, n, p, k) -> IComb (kinfo, n, p, f.apply k) + | IUncomb (kinfo, n, p, k) -> IUncomb (kinfo, n, p, f.apply k) + | IComb_get (kinfo, n, p, k) -> IComb_get (kinfo, n, p, f.apply k) + | IComb_set (kinfo, n, p, k) -> IComb_set (kinfo, n, p, f.apply k) + | IDup_n (kinfo, n, p, k) -> IDup_n (kinfo, n, p, f.apply k) + | ITicket (kinfo, k) -> ITicket (kinfo, f.apply k) + | IRead_ticket (kinfo, k) -> IRead_ticket (kinfo, f.apply k) + | ISplit_ticket (kinfo, k) -> ISplit_ticket (kinfo, f.apply k) + | IJoin_tickets (kinfo, ty, k) -> IJoin_tickets (kinfo, ty, f.apply k) + | IHalt kinfo -> IHalt kinfo + | ILog (kinfo, event, logger, k) -> ILog (kinfo, event, logger, k) + | IOpen_chest (kinfo, k) -> IOpen_chest (kinfo, f.apply k) + +let ty_metadata : type a. a ty -> a ty_metadata = function + | Unit_t meta -> meta + | Never_t meta -> meta + | Int_t meta -> meta + | Nat_t meta -> meta + | Signature_t meta -> meta + | String_t meta -> meta + | Bytes_t meta -> meta + | Mutez_t meta -> meta + | Bool_t meta -> meta + | Key_hash_t meta -> meta + | Key_t meta -> meta + | Timestamp_t meta -> meta + | Chain_id_t meta -> meta + | Address_t meta -> meta + | Pair_t (_, _, meta) -> meta + | Union_t (_, _, meta) -> meta + | Option_t (_, meta) -> meta + | Lambda_t (_, _, meta) -> meta + | List_t (_, meta) -> meta + | Set_t (_, meta) -> meta + | Map_t (_, _, meta) -> meta + | Big_map_t (_, _, meta) -> meta + | Ticket_t (_, meta) -> meta + | Contract_t (_, meta) -> meta + | Sapling_transaction_t (_, meta) -> meta + | Sapling_state_t (_, meta) -> meta + | Operation_t meta -> meta + | Bls12_381_g1_t meta -> meta + | Bls12_381_g2_t meta -> meta + | Bls12_381_fr_t meta -> meta + | Chest_t meta -> meta + | Chest_key_t meta -> meta + +let ty_size t = (ty_metadata t).size + +let unit_t ~annot = Unit_t {annot; size = Type_size.one} + +let int_t ~annot = Int_t {annot; size = Type_size.one} + +let nat_t ~annot = Nat_t {annot; size = Type_size.one} + +let signature_t ~annot = Signature_t {annot; size = Type_size.one} + +let string_t ~annot = String_t {annot; size = Type_size.one} + +let bytes_t ~annot = Bytes_t {annot; size = Type_size.one} + +let mutez_t ~annot = Mutez_t {annot; size = Type_size.one} + +let key_hash_t ~annot = Key_hash_t {annot; size = Type_size.one} + +let key_t ~annot = Key_t {annot; size = Type_size.one} + +let timestamp_t ~annot = Timestamp_t {annot; size = Type_size.one} + +let address_t ~annot = Address_t {annot; size = Type_size.one} + +let bool_t ~annot = Bool_t {annot; size = Type_size.one} + +let pair_t loc (l, fannot_l, vannot_l) (r, fannot_r, vannot_r) ~annot = + Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> + Pair_t ((l, fannot_l, vannot_l), (r, fannot_r, vannot_r), {annot; size}) + +let union_t loc (l, fannot_l) (r, fannot_r) ~annot = + Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> + Union_t ((l, fannot_l), (r, fannot_r), {annot; size}) + +let union_bytes_bool_t = + Union_t + ( (bytes_t ~annot:None, None), + (bool_t ~annot:None, None), + {annot = None; size = Type_size.three} ) + +let lambda_t loc l r ~annot = + Type_size.compound2 loc (ty_size l) (ty_size r) >|? fun size -> + Lambda_t (l, r, {annot; size}) + +let option_t loc t ~annot = + Type_size.compound1 loc (ty_size t) >|? fun size -> Option_t (t, {annot; size}) + +let option_mutez'_t meta = + let {annot; size = _} = meta in + Option_t (mutez_t ~annot, {annot = None; size = Type_size.two}) + +let option_string'_t meta = + let {annot; size = _} = meta in + Option_t (string_t ~annot, {annot = None; size = Type_size.two}) + +let option_bytes'_t meta = + let {annot; size = _} = meta in + Option_t (bytes_t ~annot, {annot = None; size = Type_size.two}) + +let option_nat_t = + Option_t (nat_t ~annot:None, {annot = None; size = Type_size.two}) + +let option_pair_nat_nat_t = + Option_t + ( Pair_t + ( (nat_t ~annot:None, None, None), + (nat_t ~annot:None, None, None), + {annot = None; size = Type_size.three} ), + {annot = None; size = Type_size.four} ) + +let option_pair_nat'_nat'_t meta = + let {annot; size = _} = meta in + Option_t + ( Pair_t + ( (nat_t ~annot, None, None), + (nat_t ~annot, None, None), + {annot = None; size = Type_size.three} ), + {annot = None; size = Type_size.four} ) + +let option_pair_nat_mutez'_t meta = + let {annot; size = _} = meta in + Option_t + ( Pair_t + ( (nat_t ~annot:None, None, None), + (mutez_t ~annot, None, None), + {annot = None; size = Type_size.three} ), + {annot = None; size = Type_size.four} ) + +let option_pair_mutez'_mutez'_t meta = + let {annot; size = _} = meta in + Option_t + ( Pair_t + ( (mutez_t ~annot, None, None), + (mutez_t ~annot, None, None), + {annot = None; size = Type_size.three} ), + {annot = None; size = Type_size.four} ) + +let option_pair_int'_nat_t meta = + let {annot; size = _} = meta in + Option_t + ( Pair_t + ( (int_t ~annot, None, None), + (nat_t ~annot:None, None, None), + {annot = None; size = Type_size.three} ), + {annot = None; size = Type_size.four} ) + +let option_pair_int_nat'_t meta = + let {annot; size = _} = meta in + Option_t + ( Pair_t + ( (int_t ~annot:None, None, None), + (nat_t ~annot, None, None), + {annot = None; size = Type_size.three} ), + {annot = None; size = Type_size.four} ) + +let list_t loc t ~annot = + Type_size.compound1 loc (ty_size t) >|? fun size -> List_t (t, {annot; size}) + +let operation_t ~annot = Operation_t {annot; size = Type_size.one} + +let list_operation_t = + List_t (operation_t ~annot:None, {annot = None; size = Type_size.two}) + +let set_t loc t ~annot = + Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> + Set_t (t, {annot; size}) + +let map_t loc l r ~annot = + Type_size.compound2 loc (comparable_ty_size l) (ty_size r) >|? fun size -> + Map_t (l, r, {annot; size}) + +let big_map_t loc l r ~annot = + Type_size.compound2 loc (comparable_ty_size l) (ty_size r) >|? fun size -> + Big_map_t (l, r, {annot; size}) + +let contract_t loc t ~annot = + Type_size.compound1 loc (ty_size t) >|? fun size -> + Contract_t (t, {annot; size}) + +let contract_unit_t = + Contract_t (unit_t ~annot:None, {annot = None; size = Type_size.two}) + +let sapling_transaction_t ~memo_size ~annot = + Sapling_transaction_t (memo_size, {annot; size = Type_size.one}) + +let sapling_state_t ~memo_size ~annot = + Sapling_state_t (memo_size, {annot; size = Type_size.one}) + +let chain_id_t ~annot = Chain_id_t {annot; size = Type_size.one} + +let never_t ~annot = Never_t {annot; size = Type_size.one} + +let bls12_381_g1_t ~annot = Bls12_381_g1_t {annot; size = Type_size.one} + +let bls12_381_g2_t ~annot = Bls12_381_g2_t {annot; size = Type_size.one} + +let bls12_381_fr_t ~annot = Bls12_381_fr_t {annot; size = Type_size.one} + +let ticket_t loc t ~annot = + Type_size.compound1 loc (comparable_ty_size t) >|? fun size -> + Ticket_t (t, {annot; size}) + +let chest_key_t ~annot = Chest_key_t {annot; size = Type_size.one} + +let chest_t ~annot = Chest_t {annot; size = Type_size.one} + +type 'a kinstr_traverse = { + apply : 'b 'u 'r 'f. 'a -> ('b, 'u, 'r, 'f) kinstr -> 'a; +} + +let kinstr_traverse i init f = + let rec aux : + type ret a s r f. 'accu -> (a, s, r, f) kinstr -> ('accu -> ret) -> ret = + fun accu t continue -> + let accu = f.apply accu t in + let next k = + (aux [@ocaml.tailcall]) accu k @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + let next2 k1 k2 = + (aux [@ocaml.tailcall]) accu k1 @@ fun accu -> + (aux [@ocaml.tailcall]) accu k2 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + let next3 k1 k2 k3 = + (aux [@ocaml.tailcall]) accu k1 @@ fun accu -> + (aux [@ocaml.tailcall]) accu k2 @@ fun accu -> + (aux [@ocaml.tailcall]) accu k3 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + let return () = (continue [@ocaml.tailcall]) accu in + match t with + | IDrop (_, k) -> (next [@ocaml.tailcall]) k + | IDup (_, k) -> (next [@ocaml.tailcall]) k + | ISwap (_, k) -> (next [@ocaml.tailcall]) k + | IConst (_, _, k) -> (next [@ocaml.tailcall]) k + | ICons_pair (_, k) -> (next [@ocaml.tailcall]) k + | ICar (_, k) -> (next [@ocaml.tailcall]) k + | ICdr (_, k) -> (next [@ocaml.tailcall]) k + | IUnpair (_, k) -> (next [@ocaml.tailcall]) k + | ICons_some (_, k) -> (next [@ocaml.tailcall]) k + | ICons_none (_, k) -> (next [@ocaml.tailcall]) k + | IIf_none {kinfo = _; branch_if_none = k1; branch_if_some = k2; k} -> + (next3 [@ocaml.tailcall]) k1 k2 k + | IOpt_map {kinfo = _; body; k} -> (next2 [@ocaml.tailcall]) body k + | ICons_left (_, k) -> (next [@ocaml.tailcall]) k + | ICons_right (_, k) -> (next [@ocaml.tailcall]) k + | IIf_left {kinfo = _; branch_if_left = k1; branch_if_right = k2; k} -> + (next3 [@ocaml.tailcall]) k1 k2 k + | ICons_list (_, k) -> (next [@ocaml.tailcall]) k + | INil (_, k) -> (next [@ocaml.tailcall]) k + | IIf_cons {kinfo = _; branch_if_nil = k1; branch_if_cons = k2; k} -> + (next3 [@ocaml.tailcall]) k1 k2 k + | IList_map (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 + | IList_iter (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 + | IList_size (_, k) -> (next [@ocaml.tailcall]) k + | IEmpty_set (_, _, k) -> (next [@ocaml.tailcall]) k + | ISet_iter (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 + | ISet_mem (_, k) -> (next [@ocaml.tailcall]) k + | ISet_update (_, k) -> (next [@ocaml.tailcall]) k + | ISet_size (_, k) -> (next [@ocaml.tailcall]) k + | IEmpty_map (_, _, k) -> (next [@ocaml.tailcall]) k + | IMap_map (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 + | IMap_iter (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 + | IMap_mem (_, k) -> (next [@ocaml.tailcall]) k + | IMap_get (_, k) -> (next [@ocaml.tailcall]) k + | IMap_update (_, k) -> (next [@ocaml.tailcall]) k + | IMap_get_and_update (_, k) -> (next [@ocaml.tailcall]) k + | IMap_size (_, k) -> (next [@ocaml.tailcall]) k + | IEmpty_big_map (_, _, _, k) -> (next [@ocaml.tailcall]) k + | IBig_map_mem (_, k) -> (next [@ocaml.tailcall]) k + | IBig_map_get (_, k) -> (next [@ocaml.tailcall]) k + | IBig_map_update (_, k) -> (next [@ocaml.tailcall]) k + | IBig_map_get_and_update (_, k) -> (next [@ocaml.tailcall]) k + | IConcat_string (_, k) -> (next [@ocaml.tailcall]) k + | IConcat_string_pair (_, k) -> (next [@ocaml.tailcall]) k + | ISlice_string (_, k) -> (next [@ocaml.tailcall]) k + | IString_size (_, k) -> (next [@ocaml.tailcall]) k + | IConcat_bytes (_, k) -> (next [@ocaml.tailcall]) k + | IConcat_bytes_pair (_, k) -> (next [@ocaml.tailcall]) k + | ISlice_bytes (_, k) -> (next [@ocaml.tailcall]) k + | IBytes_size (_, k) -> (next [@ocaml.tailcall]) k + | IAdd_seconds_to_timestamp (_, k) -> (next [@ocaml.tailcall]) k + | IAdd_timestamp_to_seconds (_, k) -> (next [@ocaml.tailcall]) k + | ISub_timestamp_seconds (_, k) -> (next [@ocaml.tailcall]) k + | IDiff_timestamps (_, k) -> (next [@ocaml.tailcall]) k + | IAdd_tez (_, k) -> (next [@ocaml.tailcall]) k + | ISub_tez (_, k) -> (next [@ocaml.tailcall]) k + | ISub_tez_legacy (_, k) -> (next [@ocaml.tailcall]) k + | IMul_teznat (_, k) -> (next [@ocaml.tailcall]) k + | IMul_nattez (_, k) -> (next [@ocaml.tailcall]) k + | IEdiv_teznat (_, k) -> (next [@ocaml.tailcall]) k + | IEdiv_tez (_, k) -> (next [@ocaml.tailcall]) k + | IOr (_, k) -> (next [@ocaml.tailcall]) k + | IAnd (_, k) -> (next [@ocaml.tailcall]) k + | IXor (_, k) -> (next [@ocaml.tailcall]) k + | INot (_, k) -> (next [@ocaml.tailcall]) k + | IIs_nat (_, k) -> (next [@ocaml.tailcall]) k + | INeg (_, k) -> (next [@ocaml.tailcall]) k + | IAbs_int (_, k) -> (next [@ocaml.tailcall]) k + | IInt_nat (_, k) -> (next [@ocaml.tailcall]) k + | IAdd_int (_, k) -> (next [@ocaml.tailcall]) k + | IAdd_nat (_, k) -> (next [@ocaml.tailcall]) k + | ISub_int (_, k) -> (next [@ocaml.tailcall]) k + | IMul_int (_, k) -> (next [@ocaml.tailcall]) k + | IMul_nat (_, k) -> (next [@ocaml.tailcall]) k + | IEdiv_int (_, k) -> (next [@ocaml.tailcall]) k + | IEdiv_nat (_, k) -> (next [@ocaml.tailcall]) k + | ILsl_nat (_, k) -> (next [@ocaml.tailcall]) k + | ILsr_nat (_, k) -> (next [@ocaml.tailcall]) k + | IOr_nat (_, k) -> (next [@ocaml.tailcall]) k + | IAnd_nat (_, k) -> (next [@ocaml.tailcall]) k + | IAnd_int_nat (_, k) -> (next [@ocaml.tailcall]) k + | IXor_nat (_, k) -> (next [@ocaml.tailcall]) k + | INot_int (_, k) -> (next [@ocaml.tailcall]) k + | IIf {kinfo = _; branch_if_true = k1; branch_if_false = k2; k} -> + (next3 [@ocaml.tailcall]) k1 k2 k + | ILoop (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 + | ILoop_left (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 + | IDip (_, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 + | IExec (_, k) -> (next [@ocaml.tailcall]) k + | IApply (_, _, k) -> (next [@ocaml.tailcall]) k + | ILambda (_, _, k) -> (next [@ocaml.tailcall]) k + | IFailwith (_, _, _) -> (return [@ocaml.tailcall]) () + | ICompare (_, _, k) -> (next [@ocaml.tailcall]) k + | IEq (_, k) -> (next [@ocaml.tailcall]) k + | INeq (_, k) -> (next [@ocaml.tailcall]) k + | ILt (_, k) -> (next [@ocaml.tailcall]) k + | IGt (_, k) -> (next [@ocaml.tailcall]) k + | ILe (_, k) -> (next [@ocaml.tailcall]) k + | IGe (_, k) -> (next [@ocaml.tailcall]) k + | IAddress (_, k) -> (next [@ocaml.tailcall]) k + | IContract (_, _, _, k) -> (next [@ocaml.tailcall]) k + | IView (_, _, k) -> (next [@ocaml.tailcall]) k + | ITransfer_tokens (_, k) -> (next [@ocaml.tailcall]) k + | IImplicit_account (_, k) -> (next [@ocaml.tailcall]) k + | ICreate_contract {k; _} -> (next [@ocaml.tailcall]) k + | ISet_delegate (_, k) -> (next [@ocaml.tailcall]) k + | INow (_, k) -> (next [@ocaml.tailcall]) k + | IBalance (_, k) -> (next [@ocaml.tailcall]) k + | ILevel (_, k) -> (next [@ocaml.tailcall]) k + | ICheck_signature (_, k) -> (next [@ocaml.tailcall]) k + | IHash_key (_, k) -> (next [@ocaml.tailcall]) k + | IPack (_, _, k) -> (next [@ocaml.tailcall]) k + | IUnpack (_, _, k) -> (next [@ocaml.tailcall]) k + | IBlake2b (_, k) -> (next [@ocaml.tailcall]) k + | ISha256 (_, k) -> (next [@ocaml.tailcall]) k + | ISha512 (_, k) -> (next [@ocaml.tailcall]) k + | ISource (_, k) -> (next [@ocaml.tailcall]) k + | ISender (_, k) -> (next [@ocaml.tailcall]) k + | ISelf (_, _, _, k) -> (next [@ocaml.tailcall]) k + | ISelf_address (_, k) -> (next [@ocaml.tailcall]) k + | IAmount (_, k) -> (next [@ocaml.tailcall]) k + | ISapling_empty_state (_, _, k) -> (next [@ocaml.tailcall]) k + | ISapling_verify_update (_, k) -> (next [@ocaml.tailcall]) k + | IDig (_, _, _, k) -> (next [@ocaml.tailcall]) k + | IDug (_, _, _, k) -> (next [@ocaml.tailcall]) k + | IDipn (_, _, _, k1, k2) -> (next2 [@ocaml.tailcall]) k1 k2 + | IDropn (_, _, _, k) -> (next [@ocaml.tailcall]) k + | IChainId (_, k) -> (next [@ocaml.tailcall]) k + | INever _ -> (return [@ocaml.tailcall]) () + | IVoting_power (_, k) -> (next [@ocaml.tailcall]) k + | ITotal_voting_power (_, k) -> (next [@ocaml.tailcall]) k + | IKeccak (_, k) -> (next [@ocaml.tailcall]) k + | ISha3 (_, k) -> (next [@ocaml.tailcall]) k + | IAdd_bls12_381_g1 (_, k) -> (next [@ocaml.tailcall]) k + | IAdd_bls12_381_g2 (_, k) -> (next [@ocaml.tailcall]) k + | IAdd_bls12_381_fr (_, k) -> (next [@ocaml.tailcall]) k + | IMul_bls12_381_g1 (_, k) -> (next [@ocaml.tailcall]) k + | IMul_bls12_381_g2 (_, k) -> (next [@ocaml.tailcall]) k + | IMul_bls12_381_fr (_, k) -> (next [@ocaml.tailcall]) k + | IMul_bls12_381_z_fr (_, k) -> (next [@ocaml.tailcall]) k + | IMul_bls12_381_fr_z (_, k) -> (next [@ocaml.tailcall]) k + | IInt_bls12_381_fr (_, k) -> (next [@ocaml.tailcall]) k + | INeg_bls12_381_g1 (_, k) -> (next [@ocaml.tailcall]) k + | INeg_bls12_381_g2 (_, k) -> (next [@ocaml.tailcall]) k + | INeg_bls12_381_fr (_, k) -> (next [@ocaml.tailcall]) k + | IPairing_check_bls12_381 (_, k) -> (next [@ocaml.tailcall]) k + | IComb (_, _, _, k) -> (next [@ocaml.tailcall]) k + | IUncomb (_, _, _, k) -> (next [@ocaml.tailcall]) k + | IComb_get (_, _, _, k) -> (next [@ocaml.tailcall]) k + | IComb_set (_, _, _, k) -> (next [@ocaml.tailcall]) k + | IDup_n (_, _, _, k) -> (next [@ocaml.tailcall]) k + | ITicket (_, k) -> (next [@ocaml.tailcall]) k + | IRead_ticket (_, k) -> (next [@ocaml.tailcall]) k + | ISplit_ticket (_, k) -> (next [@ocaml.tailcall]) k + | IJoin_tickets (_, _, k) -> (next [@ocaml.tailcall]) k + | IOpen_chest (_, k) -> (next [@ocaml.tailcall]) k + | IHalt _ -> (return [@ocaml.tailcall]) () + | ILog (_, _, _, k) -> (next [@ocaml.tailcall]) k + in + aux init i (fun accu -> accu) + +type 'a ty_traverse = { + apply : 't. 'a -> 't ty -> 'a; + apply_comparable : 't. 'a -> 't comparable_ty -> 'a; +} + +let (ty_traverse, comparable_ty_traverse) = + let rec aux : + type t ret accu. + accu ty_traverse -> accu -> t comparable_ty -> (accu -> ret) -> ret = + fun f accu ty continue -> + let accu = f.apply_comparable accu ty in + let next2 ty1 ty2 = + (aux [@ocaml.tailcall]) f accu ty1 @@ fun accu -> + (aux [@ocaml.tailcall]) f accu ty2 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + let next ty1 = + (aux [@ocaml.tailcall]) f accu ty1 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + let return () = (continue [@ocaml.tailcall]) accu in + match ty with + | Unit_key _ | Int_key _ | Nat_key _ | Signature_key _ | String_key _ + | Bytes_key _ | Mutez_key _ | Key_hash_key _ | Key_key _ | Timestamp_key _ + | Address_key _ | Bool_key _ | Chain_id_key _ | Never_key _ -> + (return [@ocaml.tailcall]) () + | Pair_key ((ty1, _), (ty2, _), _) -> (next2 [@ocaml.tailcall]) ty1 ty2 + | Union_key ((ty1, _), (ty2, _), _) -> (next2 [@ocaml.tailcall]) ty1 ty2 + | Option_key (ty, _) -> (next [@ocaml.tailcall]) ty + and aux' : + type ret t accu. accu ty_traverse -> accu -> t ty -> (accu -> ret) -> ret + = + fun f accu ty continue -> + let accu = f.apply accu ty in + match (ty : t ty) with + | Unit_t _ | Int_t _ | Nat_t _ | Signature_t _ | String_t _ | Bytes_t _ + | Mutez_t _ | Key_hash_t _ | Key_t _ | Timestamp_t _ | Address_t _ + | Bool_t _ + | Sapling_transaction_t (_, _) + | Sapling_state_t (_, _) + | Operation_t _ | Chain_id_t _ | Never_t _ | Bls12_381_g1_t _ + | Bls12_381_g2_t _ | Bls12_381_fr_t _ -> + (continue [@ocaml.tailcall]) accu + | Ticket_t (cty, _) -> aux f accu cty continue + | Chest_key_t _ | Chest_t _ -> (continue [@ocaml.tailcall]) accu + | Pair_t ((ty1, _, _), (ty2, _, _), _) -> + (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue + | Union_t ((ty1, _), (ty2, _), _) -> + (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue + | Lambda_t (ty1, ty2, _) -> + (next2' [@ocaml.tailcall]) f accu ty1 ty2 continue + | Option_t (ty1, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue + | List_t (ty1, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue + | Set_t (cty, _) -> (aux [@ocaml.tailcall]) f accu cty @@ continue + | Map_t (cty, ty1, _) -> + (aux [@ocaml.tailcall]) f accu cty @@ fun accu -> + (next' [@ocaml.tailcall]) f accu ty1 continue + | Big_map_t (cty, ty1, _) -> + (aux [@ocaml.tailcall]) f accu cty @@ fun accu -> + (next' [@ocaml.tailcall]) f accu ty1 continue + | Contract_t (ty1, _) -> (next' [@ocaml.tailcall]) f accu ty1 continue + and next2' : + type a b ret accu. + accu ty_traverse -> accu -> a ty -> b ty -> (accu -> ret) -> ret = + fun f accu ty1 ty2 continue -> + (aux' [@ocaml.tailcall]) f accu ty1 @@ fun accu -> + (aux' [@ocaml.tailcall]) f accu ty2 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + and next' : + type a ret accu. accu ty_traverse -> accu -> a ty -> (accu -> ret) -> ret + = + fun f accu ty1 continue -> + (aux' [@ocaml.tailcall]) f accu ty1 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + ( (fun ty init f -> aux' f init ty (fun accu -> accu)), + fun cty init f -> aux f init cty (fun accu -> accu) ) + +type 'accu stack_ty_traverse = { + apply : 'ty 's. 'accu -> ('ty, 's) stack_ty -> 'accu; +} + +let stack_ty_traverse (type a t) (sty : (a, t) stack_ty) init f = + let rec aux : type b u. 'accu -> (b, u) stack_ty -> 'accu = + fun accu sty -> + match sty with + | Bot_t -> f.apply accu sty + | Item_t (_, sty', _) -> aux (f.apply accu sty) sty' + in + aux init sty + +type 'a value_traverse = { + apply : 't. 'a -> 't ty -> 't -> 'a; + apply_comparable : 't. 'a -> 't comparable_ty -> 't -> 'a; +} + +let value_traverse (type t) (ty : (t ty, t comparable_ty) union) (x : t) init f + = + let rec aux : type ret t. 'accu -> t ty -> t -> ('accu -> ret) -> ret = + fun accu ty x continue -> + let accu = f.apply accu ty x in + let next2 ty1 ty2 x1 x2 = + (aux [@ocaml.tailcall]) accu ty1 x1 @@ fun accu -> + (aux [@ocaml.tailcall]) accu ty2 x2 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + let next ty1 x1 = + (aux [@ocaml.tailcall]) accu ty1 x1 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + let return () = (continue [@ocaml.tailcall]) accu in + let rec on_list ty' accu = function + | [] -> (continue [@ocaml.tailcall]) accu + | x :: xs -> + (aux [@ocaml.tailcall]) accu ty' x @@ fun accu -> + (on_list [@ocaml.tailcall]) ty' accu xs + in + match ty with + | Unit_t _ | Int_t _ | Nat_t _ | Signature_t _ | String_t _ | Bytes_t _ + | Mutez_t _ | Key_hash_t _ | Key_t _ | Timestamp_t _ | Address_t _ + | Bool_t _ + | Sapling_transaction_t (_, _) + | Sapling_state_t (_, _) + | Operation_t _ | Chain_id_t _ | Never_t _ | Bls12_381_g1_t _ + | Bls12_381_g2_t _ | Bls12_381_fr_t _ | Chest_key_t _ | Chest_t _ + | Lambda_t (_, _, _) -> + (return [@ocaml.tailcall]) () + | Pair_t ((ty1, _, _), (ty2, _, _), _) -> + (next2 [@ocaml.tailcall]) ty1 ty2 (fst x) (snd x) + | Union_t ((ty1, _), (ty2, _), _) -> ( + match x with + | L l -> (next [@ocaml.tailcall]) ty1 l + | R r -> (next [@ocaml.tailcall]) ty2 r) + | Option_t (ty, _) -> ( + match x with + | None -> return () + | Some v -> (next [@ocaml.tailcall]) ty v) + | Ticket_t (cty, _) -> (aux' [@ocaml.tailcall]) accu cty x.contents continue + | List_t (ty', _) -> on_list ty' accu x.elements + | Map_t (kty, ty', _) -> + let module M = (val x) in + let bindings = M.OPS.fold (fun k v bs -> (k, v) :: bs) M.boxed [] in + on_bindings accu kty ty' continue bindings + | Set_t (ty', _) -> + let module M = (val x) in + let elements = M.OPS.fold (fun x s -> x :: s) M.boxed [] in + on_list' accu ty' elements continue + | Big_map_t (_, _, _) -> + (* For big maps, there is no obvious recursion scheme so we + delegate this case to the client. *) + (return [@ocaml.tailcall]) () + | Contract_t (_, _) -> (return [@ocaml.tailcall]) () + and on_list' : + type ret t. 'accu -> t comparable_ty -> t list -> ('accu -> ret) -> ret = + fun accu ty' xs continue -> + match xs with + | [] -> (continue [@ocaml.tailcall]) accu + | x :: xs -> + (aux' [@ocaml.tailcall]) accu ty' x @@ fun accu -> + (on_list' [@ocaml.tailcall]) accu ty' xs continue + and on_bindings : + type ret k v. + 'accu -> k comparable_ty -> v ty -> ('accu -> ret) -> (k * v) list -> ret + = + fun accu kty ty' continue xs -> + match xs with + | [] -> (continue [@ocaml.tailcall]) accu + | (k, v) :: xs -> + (aux' [@ocaml.tailcall]) accu kty k @@ fun accu -> + (aux [@ocaml.tailcall]) accu ty' v @@ fun accu -> + (on_bindings [@ocaml.tailcall]) accu kty ty' continue xs + and aux' : type ret t. 'accu -> t comparable_ty -> t -> ('accu -> ret) -> ret + = + fun accu ty x continue -> + let accu = f.apply_comparable accu ty x in + let next2 ty1 ty2 x1 x2 = + (aux' [@ocaml.tailcall]) accu ty1 x1 @@ fun accu -> + (aux' [@ocaml.tailcall]) accu ty2 x2 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + let next ty1 x1 = + (aux' [@ocaml.tailcall]) accu ty1 x1 @@ fun accu -> + (continue [@ocaml.tailcall]) accu + in + let return () = (continue [@ocaml.tailcall]) accu in + match ty with + | Unit_key _ | Int_key _ | Nat_key _ | Signature_key _ | String_key _ + | Bytes_key _ | Mutez_key _ | Key_hash_key _ | Key_key _ | Timestamp_key _ + | Address_key _ | Bool_key _ | Chain_id_key _ | Never_key _ -> + (return [@ocaml.tailcall]) () + | Pair_key ((ty1, _), (ty2, _), _) -> + (next2 [@ocaml.tailcall]) ty1 ty2 (fst x) (snd x) + | Union_key ((ty1, _), (ty2, _), _) -> ( + match x with + | L l -> (next [@ocaml.tailcall]) ty1 l + | R r -> (next [@ocaml.tailcall]) ty2 r) + | Option_key (ty, _) -> ( + match x with + | None -> (return [@ocaml.tailcall]) () + | Some v -> (next [@ocaml.tailcall]) ty v) + in + match ty with + | L ty -> aux init ty x (fun accu -> accu) + | R cty -> aux' init cty x (fun accu -> accu) + [@@coq_axiom_with_reason "local mutually recursive definition not handled"] + +let stack_top_ty : type a b s. (a, b * s) stack_ty -> a ty = function + | Item_t (ty, _, _) -> ty diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir.mli b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir.mli new file mode 100644 index 000000000000..5bb1a5814352 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir.mli @@ -0,0 +1,1594 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Script_int +open Script_ir_annot + +type step_constants = { + source : Contract.t; + payer : Contract.t; + self : Contract.t; + amount : Tez.t; + chain_id : Chain_id.t; + now : Script_timestamp.t; + level : Script_int.n Script_int.num; +} + +(* Preliminary definitions. *) + +type never = | + +type address = Contract.t * string + +type ('a, 'b) pair = 'a * 'b + +type ('a, 'b) union = L of 'a | R of 'b + +type operation = packed_internal_operation * Lazy_storage.diffs option + +type 'a ticket = {ticketer : Contract.t; contents : 'a; amount : n num} + +type empty_cell = EmptyCell + +type end_of_stack = empty_cell * empty_cell + +module Type_size : sig + type 'a t + + val merge : 'a t -> 'b t -> 'a t tzresult + + val to_int : 'a t -> Saturation_repr.mul_safe Saturation_repr.t +end + +type 'a ty_metadata = {annot : type_annot option; size : 'a Type_size.t} + +type _ comparable_ty = + | Unit_key : unit ty_metadata -> unit comparable_ty + | Never_key : never ty_metadata -> never comparable_ty + | Int_key : z num ty_metadata -> z num comparable_ty + | Nat_key : n num ty_metadata -> n num comparable_ty + | Signature_key : signature ty_metadata -> signature comparable_ty + | String_key : Script_string.t ty_metadata -> Script_string.t comparable_ty + | Bytes_key : Bytes.t ty_metadata -> Bytes.t comparable_ty + | Mutez_key : Tez.t ty_metadata -> Tez.t comparable_ty + | Bool_key : bool ty_metadata -> bool comparable_ty + | Key_hash_key : public_key_hash ty_metadata -> public_key_hash comparable_ty + | Key_key : public_key ty_metadata -> public_key comparable_ty + | Timestamp_key : + Script_timestamp.t ty_metadata + -> Script_timestamp.t comparable_ty + | Chain_id_key : Chain_id.t ty_metadata -> Chain_id.t comparable_ty + | Address_key : address ty_metadata -> address comparable_ty + | Pair_key : + ('a comparable_ty * field_annot option) + * ('b comparable_ty * field_annot option) + * ('a, 'b) pair ty_metadata + -> ('a, 'b) pair comparable_ty + | Union_key : + ('a comparable_ty * field_annot option) + * ('b comparable_ty * field_annot option) + * ('a, 'b) union ty_metadata + -> ('a, 'b) union comparable_ty + | Option_key : + 'v comparable_ty * 'v option ty_metadata + -> 'v option comparable_ty + +val unit_key : annot:type_annot option -> unit comparable_ty + +val never_key : annot:type_annot option -> never comparable_ty + +val int_key : annot:type_annot option -> z num comparable_ty + +val nat_key : annot:type_annot option -> n num comparable_ty + +val signature_key : annot:type_annot option -> signature comparable_ty + +val string_key : annot:type_annot option -> Script_string.t comparable_ty + +val bytes_key : annot:type_annot option -> Bytes.t comparable_ty + +val mutez_key : annot:type_annot option -> Tez.t comparable_ty + +val bool_key : annot:type_annot option -> bool comparable_ty + +val key_hash_key : annot:type_annot option -> public_key_hash comparable_ty + +val key_key : annot:type_annot option -> public_key comparable_ty + +val timestamp_key : annot:type_annot option -> Script_timestamp.t comparable_ty + +val chain_id_key : annot:type_annot option -> Chain_id.t comparable_ty + +val address_key : annot:type_annot option -> address comparable_ty + +val pair_key : + Script.location -> + 'a comparable_ty * field_annot option -> + 'b comparable_ty * field_annot option -> + annot:type_annot option -> + ('a, 'b) pair comparable_ty tzresult + +val pair_3_key : + Script.location -> + 'a comparable_ty * field_annot option -> + 'b comparable_ty * field_annot option -> + 'c comparable_ty * field_annot option -> + ('a, ('b, 'c) pair) pair comparable_ty tzresult + +val union_key : + Script.location -> + 'a comparable_ty * field_annot option -> + 'b comparable_ty * field_annot option -> + annot:type_annot option -> + ('a, 'b) union comparable_ty tzresult + +val option_key : + Script.location -> + 'v comparable_ty -> + annot:type_annot option -> + 'v option comparable_ty tzresult + +module type Boxed_set_OPS = sig + type t + + type elt + + val empty : t + + val add : elt -> t -> t + + val mem : elt -> t -> bool + + val remove : elt -> t -> t + + val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a +end + +module type Boxed_set = sig + type elt + + val elt_ty : elt comparable_ty + + module OPS : Boxed_set_OPS with type elt = elt + + val boxed : OPS.t + + val size : int +end + +type 'elt set = (module Boxed_set with type elt = 'elt) + +module type Boxed_map_OPS = sig + type t + + type key + + type value + + val empty : t + + val add : key -> value -> t -> t + + val remove : key -> t -> t + + val find : key -> t -> value option + + val fold : (key -> value -> 'a -> 'a) -> t -> 'a -> 'a +end + +module type Boxed_map = sig + type key + + type value + + val key_ty : key comparable_ty + + module OPS : Boxed_map_OPS with type key = key and type value = value + + val boxed : OPS.t + + val size : int +end + +type ('key, 'value) map = + (module Boxed_map with type key = 'key and type value = 'value) + +module Big_map_overlay : Map.S with type key = Script_expr_hash.t + +type ('key, 'value) big_map_overlay = { + map : ('key * 'value option) Big_map_overlay.t; + size : int; +} + +type 'elt boxed_list = {elements : 'elt list; length : int} + +module SMap : Map.S with type key = Script_string.t + +type view = { + input_ty : Script.node; + output_ty : Script.node; + view_code : Script.node; +} + +type ('arg, 'storage) script = { + code : (('arg, 'storage) pair, (operation boxed_list, 'storage) pair) lambda; + arg_type : 'arg ty; + storage : 'storage; + storage_type : 'storage ty; + views : view SMap.t; + root_name : field_annot option; + code_size : Cache_memory_helpers.sint; +} + +(* ---- Instructions --------------------------------------------------------*) + +(* + + The instructions of Michelson are represented in the following + Generalized Algebraic Datatypes. + + There are three important aspects in that type declaration. + + First, we follow a tagless approach for values: they are directly + represented as OCaml values. This reduces the computational cost of + interpretation because there is no need to check the shape of a + value before applying an operation to it. To achieve that, the GADT + encodes the typing rules of the Michelson programming + language. This static information is sufficient for the typechecker + to justify the absence of runtime checks. As a bonus, it also + ensures that well-typed Michelson programs cannot go wrong: if the + interpreter typechecks then we have the static guarantee that no + stack underflow or type error can occur at runtime. + + Second, we maintain the invariant that the stack type always has a + distinguished topmost element. This invariant is important to + implement the stack as an accumulator followed by a linked list of + cells, a so-called A-Stack. This representation is considered in + the literature[1] as an efficient representation of the stack for a + stack-based abstract machine, mainly because this opens the + opportunity for the accumulator to be stored in a hardware + register. In the GADT, this invariant is encoded by representing + the stack type using two parameters instead of one: the first one + is the type of the accumulator while the second is the type of the + rest of the stack. + + Third, in this representation, each instruction embeds its + potential successor instructions in the control flow. This design + choice permits an efficient implementation of the continuation + stack in the interpreter. Assigning a precise type to this kind of + instruction which is a cell in a linked list of instructions is + similar to the typing of delimited continuations: we need to give a + type to the stack ['before] the execution of the instruction, a + type to the stack ['after] the execution of the instruction and + before the execution of the next, and a type for the [`result]ing + stack type after the execution of the whole chain of instructions. + + Combining these three aspects, the type [kinstr] needs four + parameters: + + ('before_top, 'before, 'result_top, 'result) kinstr + + Notice that we could have chosen to only give two parameters to + [kinstr] by manually enforcing each argument to be a pair but this + is error-prone: with four parameters, this constraint is enforced + by the arity of the type constructor itself. + + Hence, an instruction which has a successor instruction enjoys a + type of the form: + + ... * ('after_top, 'after, 'result_top, 'result) kinstr * ... -> + ('before_top, 'before, 'result_top, 'result) kinstr + + where ['before_top] and ['before] are the types of the stack top + and rest before the instruction chain, ['after_top] and ['after] + are the types of the stack top and rest after the instruction + chain, and ['result_top] and ['result] are the types of the stack + top and rest after the instruction chain. The [IHalt] instruction + ends a sequence of instructions and has no successor, as shown by + its type: + + IHalt : ('a, 's) kinfo -> ('a, 's, 'a, 's) kinstr + + Each instruction is decorated by some metadata (typically to hold + locations). The type for these metadata is [kinfo]: such a value is + only used for logging and error reporting and has no impact on the + operational semantics. + + Notations: + ---------- + + In the following declaration, we use 'a, 'b, 'c, 'd, ... to assign + types to stack cell contents while we use 's, 't, 'u, 'v, ... to + assign types to stacks. + + The types for the final result and stack rest of a whole sequence + of instructions are written 'r and 'f (standing for "result" and + "final stack rest", respectively). + + Instructions for internal execution steps + ========================================= + + Some instructions encoded in the following type are not present in the + source language. They only appear during evaluation to account for + intermediate execution steps. Indeed, since the interpreter follows + a small-step style, it is sometimes necessary to decompose a + source-level instruction (e.g. List_map) into several instructions + with smaller steps. This technique seems required to get an + efficient tail-recursive interpreter. + + References + ========== + [1]: http://www.complang.tuwien.ac.at/projects/interpreters.html + + *) +and ('before_top, 'before, 'result_top, 'result) kinstr = + (* + Stack + ----- + *) + | IDrop : + ('a, 'b * 's) kinfo * ('b, 's, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IDup : + ('a, 's) kinfo * ('a, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISwap : + ('a, 'b * 's) kinfo * ('b, 'a * 's, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IConst : + ('a, 's) kinfo * 'ty * ('ty, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + (* + Pairs + ----- + *) + | ICons_pair : + ('a, 'b * 's) kinfo * ('a * 'b, 's, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | ICar : + ('a * 'b, 's) kinfo * ('a, 's, 'r, 'f) kinstr + -> ('a * 'b, 's, 'r, 'f) kinstr + | ICdr : + ('a * 'b, 's) kinfo * ('b, 's, 'r, 'f) kinstr + -> ('a * 'b, 's, 'r, 'f) kinstr + | IUnpair : + ('a * 'b, 's) kinfo * ('a, 'b * 's, 'r, 'f) kinstr + -> ('a * 'b, 's, 'r, 'f) kinstr + (* + Options + ------- + *) + | ICons_some : + ('v, 's) kinfo * ('v option, 's, 'r, 'f) kinstr + -> ('v, 's, 'r, 'f) kinstr + | ICons_none : + ('a, 's) kinfo * ('b option, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IIf_none : { + kinfo : ('a option, 'b * 's) kinfo; + branch_if_none : ('b, 's, 'c, 't) kinstr; + branch_if_some : ('a, 'b * 's, 'c, 't) kinstr; + k : ('c, 't, 'r, 'f) kinstr; + } + -> ('a option, 'b * 's, 'r, 'f) kinstr + | IOpt_map : { + kinfo : ('a option, 's) kinfo; + body : ('a, 's, 'b, 's) kinstr; + k : ('b option, 's, 'c, 't) kinstr; + } + -> ('a option, 's, 'c, 't) kinstr + (* + Unions + ------ + *) + | ICons_left : + ('a, 's) kinfo * (('a, 'b) union, 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ICons_right : + ('b, 's) kinfo * (('a, 'b) union, 's, 'r, 'f) kinstr + -> ('b, 's, 'r, 'f) kinstr + | IIf_left : { + kinfo : (('a, 'b) union, 's) kinfo; + branch_if_left : ('a, 's, 'c, 't) kinstr; + branch_if_right : ('b, 's, 'c, 't) kinstr; + k : ('c, 't, 'r, 'f) kinstr; + } + -> (('a, 'b) union, 's, 'r, 'f) kinstr + (* + Lists + ----- + *) + | ICons_list : + ('a, 'a boxed_list * 's) kinfo * ('a boxed_list, 's, 'r, 'f) kinstr + -> ('a, 'a boxed_list * 's, 'r, 'f) kinstr + | INil : + ('a, 's) kinfo * ('b boxed_list, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IIf_cons : { + kinfo : ('a boxed_list, 'b * 's) kinfo; + branch_if_cons : ('a, 'a boxed_list * ('b * 's), 'c, 't) kinstr; + branch_if_nil : ('b, 's, 'c, 't) kinstr; + k : ('c, 't, 'r, 'f) kinstr; + } + -> ('a boxed_list, 'b * 's, 'r, 'f) kinstr + | IList_map : + ('a boxed_list, 'c * 's) kinfo + * ('a, 'c * 's, 'b, 'c * 's) kinstr + * ('b boxed_list, 'c * 's, 'r, 'f) kinstr + -> ('a boxed_list, 'c * 's, 'r, 'f) kinstr + | IList_iter : + ('a boxed_list, 'b * 's) kinfo + * ('a, 'b * 's, 'b, 's) kinstr + * ('b, 's, 'r, 'f) kinstr + -> ('a boxed_list, 'b * 's, 'r, 'f) kinstr + | IList_size : + ('a boxed_list, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> ('a boxed_list, 's, 'r, 'f) kinstr + (* + Sets + ---- + *) + | IEmpty_set : + ('a, 's) kinfo * 'b comparable_ty * ('b set, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISet_iter : + ('a set, 'b * 's) kinfo + * ('a, 'b * 's, 'b, 's) kinstr + * ('b, 's, 'r, 'f) kinstr + -> ('a set, 'b * 's, 'r, 'f) kinstr + | ISet_mem : + ('a, 'a set * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> ('a, 'a set * 's, 'r, 'f) kinstr + | ISet_update : + ('a, bool * ('a set * 's)) kinfo * ('a set, 's, 'r, 'f) kinstr + -> ('a, bool * ('a set * 's), 'r, 'f) kinstr + | ISet_size : + ('a set, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> ('a set, 's, 'r, 'f) kinstr + (* + Maps + ---- + *) + | IEmpty_map : + ('a, 's) kinfo * 'b comparable_ty * (('b, 'c) map, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IMap_map : + (('a, 'b) map, 'd * 's) kinfo + * ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr + * (('a, 'c) map, 'd * 's, 'r, 'f) kinstr + -> (('a, 'b) map, 'd * 's, 'r, 'f) kinstr + | IMap_iter : + (('a, 'b) map, 'c * 's) kinfo + * ('a * 'b, 'c * 's, 'c, 's) kinstr + * ('c, 's, 'r, 'f) kinstr + -> (('a, 'b) map, 'c * 's, 'r, 'f) kinstr + | IMap_mem : + ('a, ('a, 'b) map * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) map * 's, 'r, 'f) kinstr + | IMap_get : + ('a, ('a, 'b) map * 's) kinfo * ('b option, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) map * 's, 'r, 'f) kinstr + | IMap_update : + ('a, 'b option * (('a, 'b) map * 's)) kinfo + * (('a, 'b) map, 's, 'r, 'f) kinstr + -> ('a, 'b option * (('a, 'b) map * 's), 'r, 'f) kinstr + | IMap_get_and_update : + ('a, 'b option * (('a, 'b) map * 's)) kinfo + * ('b option, ('a, 'b) map * 's, 'r, 'f) kinstr + -> ('a, 'b option * (('a, 'b) map * 's), 'r, 'f) kinstr + | IMap_size : + (('a, 'b) map, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (('a, 'b) map, 's, 'r, 'f) kinstr + (* + Big maps + -------- + *) + | IEmpty_big_map : + ('a, 's) kinfo + * 'b comparable_ty + * 'c ty + * (('b, 'c) big_map, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IBig_map_mem : + ('a, ('a, 'b) big_map * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) big_map * 's, 'r, 'f) kinstr + | IBig_map_get : + ('a, ('a, 'b) big_map * 's) kinfo * ('b option, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) big_map * 's, 'r, 'f) kinstr + | IBig_map_update : + ('a, 'b option * (('a, 'b) big_map * 's)) kinfo + * (('a, 'b) big_map, 's, 'r, 'f) kinstr + -> ('a, 'b option * (('a, 'b) big_map * 's), 'r, 'f) kinstr + | IBig_map_get_and_update : + ('a, 'b option * (('a, 'b) big_map * 's)) kinfo + * ('b option, ('a, 'b) big_map * 's, 'r, 'f) kinstr + -> ('a, 'b option * (('a, 'b) big_map * 's), 'r, 'f) kinstr + (* + Strings + ------- + *) + | IConcat_string : + (Script_string.t boxed_list, 's) kinfo + * (Script_string.t, 's, 'r, 'f) kinstr + -> (Script_string.t boxed_list, 's, 'r, 'f) kinstr + | IConcat_string_pair : + (Script_string.t, Script_string.t * 's) kinfo + * (Script_string.t, 's, 'r, 'f) kinstr + -> (Script_string.t, Script_string.t * 's, 'r, 'f) kinstr + | ISlice_string : + (n num, n num * (Script_string.t * 's)) kinfo + * (Script_string.t option, 's, 'r, 'f) kinstr + -> (n num, n num * (Script_string.t * 's), 'r, 'f) kinstr + | IString_size : + (Script_string.t, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (Script_string.t, 's, 'r, 'f) kinstr + (* + Bytes + ----- + *) + | IConcat_bytes : + (bytes boxed_list, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes boxed_list, 's, 'r, 'f) kinstr + | IConcat_bytes_pair : + (bytes, bytes * 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, bytes * 's, 'r, 'f) kinstr + | ISlice_bytes : + (n num, n num * (bytes * 's)) kinfo * (bytes option, 's, 'r, 'f) kinstr + -> (n num, n num * (bytes * 's), 'r, 'f) kinstr + | IBytes_size : + (bytes, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + (* + Timestamps + ---------- + *) + | IAdd_seconds_to_timestamp : + (z num, Script_timestamp.t * 's) kinfo + * (Script_timestamp.t, 's, 'r, 'f) kinstr + -> (z num, Script_timestamp.t * 's, 'r, 'f) kinstr + | IAdd_timestamp_to_seconds : + (Script_timestamp.t, z num * 's) kinfo + * (Script_timestamp.t, 's, 'r, 'f) kinstr + -> (Script_timestamp.t, z num * 's, 'r, 'f) kinstr + | ISub_timestamp_seconds : + (Script_timestamp.t, z num * 's) kinfo + * (Script_timestamp.t, 's, 'r, 'f) kinstr + -> (Script_timestamp.t, z num * 's, 'r, 'f) kinstr + | IDiff_timestamps : + (Script_timestamp.t, Script_timestamp.t * 's) kinfo + * (z num, 's, 'r, 'f) kinstr + -> (Script_timestamp.t, Script_timestamp.t * 's, 'r, 'f) kinstr + (* + Tez + --- + *) + | IAdd_tez : + (Tez.t, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr + -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr + | ISub_tez : + (Tez.t, Tez.t * 's) kinfo * (Tez.t option, 's, 'r, 'f) kinstr + -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr + | ISub_tez_legacy : + (Tez.t, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr + -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr + | IMul_teznat : + (Tez.t, n num * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr + -> (Tez.t, n num * 's, 'r, 'f) kinstr + | IMul_nattez : + (n num, Tez.t * 's) kinfo * (Tez.t, 's, 'r, 'f) kinstr + -> (n num, Tez.t * 's, 'r, 'f) kinstr + | IEdiv_teznat : + (Tez.t, n num * 's) kinfo + * ((Tez.t, Tez.t) pair option, 's, 'r, 'f) kinstr + -> (Tez.t, n num * 's, 'r, 'f) kinstr + | IEdiv_tez : + (Tez.t, Tez.t * 's) kinfo + * ((n num, Tez.t) pair option, 's, 'r, 'f) kinstr + -> (Tez.t, Tez.t * 's, 'r, 'f) kinstr + (* + Booleans + -------- + *) + | IOr : + (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (bool, bool * 's, 'r, 'f) kinstr + | IAnd : + (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (bool, bool * 's, 'r, 'f) kinstr + | IXor : + (bool, bool * 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (bool, bool * 's, 'r, 'f) kinstr + | INot : + (bool, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (bool, 's, 'r, 'f) kinstr + (* + Integers + -------- + *) + | IIs_nat : + (z num, 's) kinfo * (n num option, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | INeg : + ('a num, 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 's, 'r, 'f) kinstr + | IAbs_int : + (z num, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | IInt_nat : + (n num, 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> (n num, 's, 'r, 'f) kinstr + | IAdd_int : + ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 'b num * 's, 'r, 'f) kinstr + | IAdd_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | ISub_int : + ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 'b num * 's, 'r, 'f) kinstr + | IMul_int : + ('a num, 'b num * 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 'b num * 's, 'r, 'f) kinstr + | IMul_nat : + (n num, 'a num * 's) kinfo * ('a num, 's, 'r, 'f) kinstr + -> (n num, 'a num * 's, 'r, 'f) kinstr + | IEdiv_int : + ('a num, 'b num * 's) kinfo + * ((z num, n num) pair option, 's, 'r, 'f) kinstr + -> ('a num, 'b num * 's, 'r, 'f) kinstr + | IEdiv_nat : + (n num, 'a num * 's) kinfo + * (('a num, n num) pair option, 's, 'r, 'f) kinstr + -> (n num, 'a num * 's, 'r, 'f) kinstr + | ILsl_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | ILsr_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | IOr_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | IAnd_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | IAnd_int_nat : + (z num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (z num, n num * 's, 'r, 'f) kinstr + | IXor_nat : + (n num, n num * 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (n num, n num * 's, 'r, 'f) kinstr + | INot_int : + ('a num, 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> ('a num, 's, 'r, 'f) kinstr + (* + Control + ------- + *) + | IIf : { + kinfo : (bool, 'a * 's) kinfo; + branch_if_true : ('a, 's, 'b, 'u) kinstr; + branch_if_false : ('a, 's, 'b, 'u) kinstr; + k : ('b, 'u, 'r, 'f) kinstr; + } + -> (bool, 'a * 's, 'r, 'f) kinstr + | ILoop : + (bool, 'a * 's) kinfo + * ('a, 's, bool, 'a * 's) kinstr + * ('a, 's, 'r, 'f) kinstr + -> (bool, 'a * 's, 'r, 'f) kinstr + | ILoop_left : + (('a, 'b) union, 's) kinfo + * ('a, 's, ('a, 'b) union, 's) kinstr + * ('b, 's, 'r, 'f) kinstr + -> (('a, 'b) union, 's, 'r, 'f) kinstr + | IDip : + ('a, 'b * 's) kinfo + * ('b, 's, 'c, 't) kinstr + * ('a, 'c * 't, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IExec : + ('a, ('a, 'b) lambda * 's) kinfo * ('b, 's, 'r, 'f) kinstr + -> ('a, ('a, 'b) lambda * 's, 'r, 'f) kinstr + | IApply : + ('a, ('a * 'b, 'c) lambda * 's) kinfo + * 'a ty + * (('b, 'c) lambda, 's, 'r, 'f) kinstr + -> ('a, ('a * 'b, 'c) lambda * 's, 'r, 'f) kinstr + | ILambda : + ('a, 's) kinfo + * ('b, 'c) lambda + * (('b, 'c) lambda, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IFailwith : + ('a, 's) kinfo * Script.location * 'a ty + -> ('a, 's, 'r, 'f) kinstr + (* + Comparison + ---------- + *) + | ICompare : + ('a, 'a * 's) kinfo * 'a comparable_ty * (z num, 's, 'r, 'f) kinstr + -> ('a, 'a * 's, 'r, 'f) kinstr + (* + Comparators + ----------- + *) + | IEq : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | INeq : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | ILt : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | IGt : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | ILe : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + | IGe : + (z num, 's) kinfo * (bool, 's, 'r, 'f) kinstr + -> (z num, 's, 'r, 'f) kinstr + (* + Protocol + -------- + *) + | IAddress : + ('a typed_contract, 's) kinfo * (address, 's, 'r, 'f) kinstr + -> ('a typed_contract, 's, 'r, 'f) kinstr + | IContract : + (address, 's) kinfo + * 'a ty + * string + * ('a typed_contract option, 's, 'r, 'f) kinstr + -> (address, 's, 'r, 'f) kinstr + | IView : + ('a, address * 's) kinfo + * ('a, 'b) view_signature + * ('b option, 's, 'r, 'f) kinstr + -> ('a, address * 's, 'r, 'f) kinstr + | ITransfer_tokens : + ('a, Tez.t * ('a typed_contract * 's)) kinfo + * (operation, 's, 'r, 'f) kinstr + -> ('a, Tez.t * ('a typed_contract * 's), 'r, 'f) kinstr + | IImplicit_account : + (public_key_hash, 's) kinfo * (unit typed_contract, 's, 'r, 'f) kinstr + -> (public_key_hash, 's, 'r, 'f) kinstr + | ICreate_contract : { + kinfo : (public_key_hash option, Tez.t * ('a * 's)) kinfo; + storage_type : 'a ty; + arg_type : 'b ty; + lambda : ('b * 'a, operation boxed_list * 'a) lambda; + views : view SMap.t; + root_name : field_annot option; + k : (operation, address * 's, 'r, 'f) kinstr; + } + -> (public_key_hash option, Tez.t * ('a * 's), 'r, 'f) kinstr + | ISet_delegate : + (public_key_hash option, 's) kinfo * (operation, 's, 'r, 'f) kinstr + -> (public_key_hash option, 's, 'r, 'f) kinstr + | INow : + ('a, 's) kinfo * (Script_timestamp.t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IBalance : + ('a, 's) kinfo * (Tez.t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ILevel : + ('a, 's) kinfo * (n num, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ICheck_signature : + (public_key, signature * (bytes * 's)) kinfo * (bool, 's, 'r, 'f) kinstr + -> (public_key, signature * (bytes * 's), 'r, 'f) kinstr + | IHash_key : + (public_key, 's) kinfo * (public_key_hash, 's, 'r, 'f) kinstr + -> (public_key, 's, 'r, 'f) kinstr + | IPack : + ('a, 's) kinfo * 'a ty * (bytes, 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IUnpack : + (bytes, 's) kinfo * 'a ty * ('a option, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | IBlake2b : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | ISha256 : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | ISha512 : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | ISource : + ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISender : + ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISelf : + ('a, 's) kinfo + * 'b ty + * string + * ('b typed_contract, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISelf_address : + ('a, 's) kinfo * (address, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IAmount : + ('a, 's) kinfo * (Tez.t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ISapling_empty_state : + ('a, 's) kinfo + * Sapling.Memo_size.t + * (Sapling.state, 'a * 's, 'b, 'f) kinstr + -> ('a, 's, 'b, 'f) kinstr + | ISapling_verify_update : + (Sapling.transaction, Sapling.state * 's) kinfo + * ((z num, Sapling.state) pair option, 's, 'r, 'f) kinstr + -> (Sapling.transaction, Sapling.state * 's, 'r, 'f) kinstr + | IDig : + ('a, 's) kinfo + (* + There is a prefix of length [n] common to the input stack + of type ['a * 's] and an intermediary stack of type ['d * 'u]. + *) + * int + (* + Under this common prefix, the input stack has type ['b * 'c * 't] and + the intermediary stack type ['c * 't] because we removed the ['b] from + the input stack. This value of type ['b] is pushed on top of the + stack passed to the continuation. + *) + * ('b, 'c * 't, 'c, 't, 'a, 's, 'd, 'u) stack_prefix_preservation_witness + * ('b, 'd * 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IDug : + ('a, 'b * 's) kinfo + (* + The input stack has type ['a * 'b * 's]. + + There is a prefix of length [n] common to its substack + of type ['b * 's] and the output stack of type ['d * 'u]. + *) + * int + (* + Under this common prefix, the first stack has type ['c * 't] + and the second has type ['a * 'c * 't] because we have pushed + the topmost element of this input stack under the common prefix. + *) + * ('c, 't, 'a, 'c * 't, 'b, 's, 'd, 'u) stack_prefix_preservation_witness + * ('d, 'u, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IDipn : + ('a, 's) kinfo + (* + The body of Dipn is applied under a prefix of size [n]... + *) + * int + (* + ... the relation between the types of the input and output stacks + is characterized by the following witness. + (See forthcoming comments about [stack_prefix_preservation_witness].) + *) + * ('c, 't, 'd, 'v, 'a, 's, 'b, 'u) stack_prefix_preservation_witness + * ('c, 't, 'd, 'v) kinstr + * ('b, 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IDropn : + ('a, 's) kinfo + (* + The input stack enjoys a prefix of length [n]... + *) + * int + (* + ... and the following value witnesses that under this prefix + the stack has type ['b * 'u]. + *) + * ('b, 'u, 'b, 'u, 'a, 's, 'a, 's) stack_prefix_preservation_witness + (* + This stack is passed to the continuation since we drop the + entire prefix. + *) + * ('b, 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IChainId : + ('a, 's) kinfo * (Chain_id.t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | INever : (never, 's) kinfo -> (never, 's, 'r, 'f) kinstr + | IVoting_power : + (public_key_hash, 's) kinfo * (n num, 's, 'r, 'f) kinstr + -> (public_key_hash, 's, 'r, 'f) kinstr + | ITotal_voting_power : + ('a, 's) kinfo * (n num, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IKeccak : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | ISha3 : + (bytes, 's) kinfo * (bytes, 's, 'r, 'f) kinstr + -> (bytes, 's, 'r, 'f) kinstr + | IAdd_bls12_381_g1 : + (Bls12_381.G1.t, Bls12_381.G1.t * 's) kinfo + * (Bls12_381.G1.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G1.t, Bls12_381.G1.t * 's, 'r, 'f) kinstr + | IAdd_bls12_381_g2 : + (Bls12_381.G2.t, Bls12_381.G2.t * 's) kinfo + * (Bls12_381.G2.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G2.t, Bls12_381.G2.t * 's, 'r, 'f) kinstr + | IAdd_bls12_381_fr : + (Bls12_381.Fr.t, Bls12_381.Fr.t * 's) kinfo + * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IMul_bls12_381_g1 : + (Bls12_381.G1.t, Bls12_381.Fr.t * 's) kinfo + * (Bls12_381.G1.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G1.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IMul_bls12_381_g2 : + (Bls12_381.G2.t, Bls12_381.Fr.t * 's) kinfo + * (Bls12_381.G2.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G2.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IMul_bls12_381_fr : + (Bls12_381.Fr.t, Bls12_381.Fr.t * 's) kinfo + * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IMul_bls12_381_z_fr : + (Bls12_381.Fr.t, 'a num * 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, 'a num * 's, 'r, 'f) kinstr + | IMul_bls12_381_fr_z : + ('a num, Bls12_381.Fr.t * 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> ('a num, Bls12_381.Fr.t * 's, 'r, 'f) kinstr + | IInt_bls12_381_fr : + (Bls12_381.Fr.t, 's) kinfo * (z num, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + | INeg_bls12_381_g1 : + (Bls12_381.G1.t, 's) kinfo * (Bls12_381.G1.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G1.t, 's, 'r, 'f) kinstr + | INeg_bls12_381_g2 : + (Bls12_381.G2.t, 's) kinfo * (Bls12_381.G2.t, 's, 'r, 'f) kinstr + -> (Bls12_381.G2.t, 's, 'r, 'f) kinstr + | INeg_bls12_381_fr : + (Bls12_381.Fr.t, 's) kinfo * (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + -> (Bls12_381.Fr.t, 's, 'r, 'f) kinstr + | IPairing_check_bls12_381 : + ((Bls12_381.G1.t, Bls12_381.G2.t) pair boxed_list, 's) kinfo + * (bool, 's, 'r, 'f) kinstr + -> ((Bls12_381.G1.t, Bls12_381.G2.t) pair boxed_list, 's, 'r, 'f) kinstr + | IComb : + ('a, 's) kinfo + * int + * ('a * 's, 'b * 'u) comb_gadt_witness + * ('b, 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IUncomb : + ('a, 's) kinfo + * int + * ('a * 's, 'b * 'u) uncomb_gadt_witness + * ('b, 'u, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | IComb_get : + ('t, 's) kinfo + * int + * ('t, 'v) comb_get_gadt_witness + * ('v, 's, 'r, 'f) kinstr + -> ('t, 's, 'r, 'f) kinstr + | IComb_set : + ('a, 'b * 's) kinfo + * int + * ('a, 'b, 'c) comb_set_gadt_witness + * ('c, 's, 'r, 'f) kinstr + -> ('a, 'b * 's, 'r, 'f) kinstr + | IDup_n : + ('a, 's) kinfo + * int + * ('a * 's, 't) dup_n_gadt_witness + * ('t, 'a * 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + | ITicket : + ('a, n num * 's) kinfo * ('a ticket, 's, 'r, 'f) kinstr + -> ('a, n num * 's, 'r, 'f) kinstr + | IRead_ticket : + ('a ticket, 's) kinfo + * (address * ('a * n num), 'a ticket * 's, 'r, 'f) kinstr + -> ('a ticket, 's, 'r, 'f) kinstr + | ISplit_ticket : + ('a ticket, (n num * n num) * 's) kinfo + * (('a ticket * 'a ticket) option, 's, 'r, 'f) kinstr + -> ('a ticket, (n num * n num) * 's, 'r, 'f) kinstr + | IJoin_tickets : + ('a ticket * 'a ticket, 's) kinfo + * 'a comparable_ty + * ('a ticket option, 's, 'r, 'f) kinstr + -> ('a ticket * 'a ticket, 's, 'r, 'f) kinstr + | IOpen_chest : + (Timelock.chest_key, Timelock.chest * (n num * 's)) kinfo + * ((bytes, bool) union, 's, 'r, 'f) kinstr + -> (Timelock.chest_key, Timelock.chest * (n num * 's), 'r, 'f) kinstr + (* + + Internal control instructions + ============================= + + The following instructions are not available in the source language. + They are used by the internals of the interpreter. + *) + | IHalt : ('a, 's) kinfo -> ('a, 's, 'a, 's) kinstr + | ILog : + ('a, 's) kinfo * logging_event * logger * ('a, 's, 'r, 'f) kinstr + -> ('a, 's, 'r, 'f) kinstr + +and logging_event = + | LogEntry : logging_event + | LogExit : ('b, 'u) kinfo -> logging_event + +and ('arg, 'ret) lambda = + | Lam : + ('arg, end_of_stack, 'ret, end_of_stack) kdescr * Script.node + -> ('arg, 'ret) lambda +[@@coq_force_gadt] + +and 'arg typed_contract = 'arg ty * address + +(* + + Control stack + ============= + + The control stack is a list of [kinstr]. + + Since [kinstr] denotes a list of instructions, the control stack + can be seen as a list of instruction sequences, each representing a + form of delimited continuation (i.e. a control stack fragment). The + [continuation] GADT ensures that the input and output stack types of the + continuations are consistent. + + Loops have a special treatment because their control stack is reused + as is for the next iteration. This avoids the reallocation of a + control stack cell at each iteration. + + To implement [step] as a tail-recursive function, we implement + higher-order iterators (i.e. MAPs and ITERs) using internal instructions +. Roughly speaking, these instructions help in decomposing the execution + of [I f c] (where [I] is an higher-order iterator over a container [c]) + into three phases: to start the iteration, to execute [f] if there are + elements to be processed in [c], and to loop. + + Dip also has a dedicated constructor in the control stack. This + allows the stack prefix to be restored after the execution of the + [Dip]'s body. + + Following the same style as in [kinstr], [continuation] has four + arguments, two for each stack types. More precisely, with + + [('bef_top, 'bef, 'aft_top, 'aft) continuation] + + we encode the fact that the stack before executing the continuation + has type [('bef_top * 'bef)] and that the stack after this execution + has type [('aft_top * 'aft)]. + +*) +and (_, _, _, _) continuation = + (* This continuation returns immediately. *) + | KNil : ('r, 'f, 'r, 'f) continuation + (* This continuation starts with the next instruction to execute. *) + | KCons : + ('a, 's, 'b, 't) kinstr * ('b, 't, 'r, 'f) continuation + -> ('a, 's, 'r, 'f) continuation + (* This continuation represents a call frame: it stores the caller's + stack of type ['s] and the continuation which expects the callee's + result on top of the stack. *) + | KReturn : + 's * ('a, 's, 'r, 'f) continuation + -> ('a, end_of_stack, 'r, 'f) continuation + (* This continuation is useful when stack head requires some wrapping or + unwrapping before it can be passed forward. For instance this continuation + is used after a [MAP] instruction applied to an option in order to wrap the + result back in a [Some] constructor. + + /!\ When using it, make sure the function runs in constant time or that gas + has been properly charged beforehand. + Also make sure it runs with a small, bounded stack. + *) + | KMap_head : + ('a -> 'b) * ('b, 's, 'r, 'f) continuation + -> ('a, 's, 'r, 'f) continuation + (* This continuation comes right after a [Dip i] to restore the topmost + element ['b] of the stack after having executed [i] in the substack + of type ['a * 's]. *) + | KUndip : + 'b * ('b, 'a * 's, 'r, 'f) continuation + -> ('a, 's, 'r, 'f) continuation + (* This continuation is executed at each iteration of a loop with + a Boolean condition. *) + | KLoop_in : + ('a, 's, bool, 'a * 's) kinstr * ('a, 's, 'r, 'f) continuation + -> (bool, 'a * 's, 'r, 'f) continuation + (* This continuation is executed at each iteration of a loop with + a condition encoded by a sum type. *) + | KLoop_in_left : + ('a, 's, ('a, 'b) union, 's) kinstr * ('b, 's, 'r, 'f) continuation + -> (('a, 'b) union, 's, 'r, 'f) continuation + (* This continuation is executed at each iteration of a traversal. + (Used in List, Map and Set.) *) + | KIter : + ('a, 'b * 's, 'b, 's) kinstr * 'a list * ('b, 's, 'r, 'f) continuation + -> ('b, 's, 'r, 'f) continuation + (* This continuation represents each step of a List.map. *) + | KList_enter_body : + ('a, 'c * 's, 'b, 'c * 's) kinstr + * 'a list + * 'b list + * int + * ('b boxed_list, 'c * 's, 'r, 'f) continuation + -> ('c, 's, 'r, 'f) continuation + (* This continuation represents what is done after each step of a List.map. *) + | KList_exit_body : + ('a, 'c * 's, 'b, 'c * 's) kinstr + * 'a list + * 'b list + * int + * ('b boxed_list, 'c * 's, 'r, 'f) continuation + -> ('b, 'c * 's, 'r, 'f) continuation + (* This continuation represents each step of a Map.map. *) + | KMap_enter_body : + ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr + * ('a * 'b) list + * ('a, 'c) map + * (('a, 'c) map, 'd * 's, 'r, 'f) continuation + -> ('d, 's, 'r, 'f) continuation + (* This continuation represents what is done after each step of a Map.map. *) + | KMap_exit_body : + ('a * 'b, 'd * 's, 'c, 'd * 's) kinstr + * ('a * 'b) list + * ('a, 'c) map + * 'a + * (('a, 'c) map, 'd * 's, 'r, 'f) continuation + -> ('c, 'd * 's, 'r, 'f) continuation + (* This continuation represents what is done after returning from a view. + It holds the original step constants value prior to entering the view. *) + | KView_exit : + step_constants * ('a, 's, 'r, 'f) continuation + -> ('a, 's, 'r, 'f) continuation + (* This continuation instruments the execution with a [logger]. *) + | KLog : + ('a, 's, 'r, 'f) continuation * logger + -> ('a, 's, 'r, 'f) continuation + +(* + + Execution instrumentation + ========================= + + One can observe the context and the stack at some specific points + of an execution step. This feature is implemented by calling back + some [logging_function]s defined in a record of type [logger] + passed as argument to the step function. + + A [logger] is typically embedded in an [KLog] continuation by the + client to trigger an evaluation instrumented with some logging. The + logger is then automatically propagated to the logging instruction + [ILog] as well as to any instructions that need to generate a + backtrace when it fails (e.g., [IFailwith], [IMul_teznat], ...). + +*) +and ('a, 's, 'b, 'f, 'c, 'u) logging_function = + ('a, 's, 'b, 'f) kinstr -> + context -> + Script.location -> + ('c, 'u) stack_ty -> + 'c * 'u -> + unit + +and execution_trace = + (Script.location * Gas.t * (Script.expr * string option) list) list + +and logger = { + log_interp : 'a 's 'b 'f 'c 'u. ('a, 's, 'b, 'f, 'c, 'u) logging_function; + (** [log_interp] is called at each call of the internal function + [interp]. [interp] is called when starting the interpretation of + a script and subsequently at each [Exec] instruction. *) + log_entry : 'a 's 'b 'f. ('a, 's, 'b, 'f, 'a, 's) logging_function; + (** [log_entry] is called {i before} executing each instruction but + {i after} gas for this instruction has been successfully + consumed. *) + log_control : 'a 's 'b 'f. ('a, 's, 'b, 'f) continuation -> unit; + (** [log_control] is called {i before} the interpretation of the + current continuation. *) + log_exit : 'a 's 'b 'f 'c 'u. ('a, 's, 'b, 'f, 'c, 'u) logging_function; + (** [log_exit] is called {i after} executing each instruction. *) + get_log : unit -> execution_trace option tzresult Lwt.t; + (** [get_log] allows to obtain an execution trace, if any was + produced. *) +} + +(* ---- Auxiliary types -----------------------------------------------------*) +and 'ty ty = + | Unit_t : unit ty_metadata -> unit ty + | Int_t : z num ty_metadata -> z num ty + | Nat_t : n num ty_metadata -> n num ty + | Signature_t : signature ty_metadata -> signature ty + | String_t : Script_string.t ty_metadata -> Script_string.t ty + | Bytes_t : Bytes.t ty_metadata -> bytes ty + | Mutez_t : Tez.t ty_metadata -> Tez.t ty + | Key_hash_t : public_key_hash ty_metadata -> public_key_hash ty + | Key_t : public_key ty_metadata -> public_key ty + | Timestamp_t : Script_timestamp.t ty_metadata -> Script_timestamp.t ty + | Address_t : address ty_metadata -> address ty + | Bool_t : bool ty_metadata -> bool ty + | Pair_t : + ('a ty * field_annot option * var_annot option) + * ('b ty * field_annot option * var_annot option) + * ('a, 'b) pair ty_metadata + -> ('a, 'b) pair ty + | Union_t : + ('a ty * field_annot option) + * ('b ty * field_annot option) + * ('a, 'b) union ty_metadata + -> ('a, 'b) union ty + | Lambda_t : + 'arg ty * 'ret ty * ('arg, 'ret) lambda ty_metadata + -> ('arg, 'ret) lambda ty + | Option_t : 'v ty * 'v option ty_metadata -> 'v option ty + | List_t : 'v ty * 'v boxed_list ty_metadata -> 'v boxed_list ty + | Set_t : 'v comparable_ty * 'v set ty_metadata -> 'v set ty + | Map_t : + 'k comparable_ty * 'v ty * ('k, 'v) map ty_metadata + -> ('k, 'v) map ty + | Big_map_t : + 'k comparable_ty * 'v ty * ('k, 'v) big_map ty_metadata + -> ('k, 'v) big_map ty + | Contract_t : + 'arg ty * 'arg typed_contract ty_metadata + -> 'arg typed_contract ty + | Sapling_transaction_t : + Sapling.Memo_size.t * Sapling.transaction ty_metadata + -> Sapling.transaction ty + | Sapling_state_t : + Sapling.Memo_size.t * Sapling.state ty_metadata + -> Sapling.state ty + | Operation_t : operation ty_metadata -> operation ty + | Chain_id_t : Chain_id.t ty_metadata -> Chain_id.t ty + | Never_t : never ty_metadata -> never ty + | Bls12_381_g1_t : Bls12_381.G1.t ty_metadata -> Bls12_381.G1.t ty + | Bls12_381_g2_t : Bls12_381.G2.t ty_metadata -> Bls12_381.G2.t ty + | Bls12_381_fr_t : Bls12_381.Fr.t ty_metadata -> Bls12_381.Fr.t ty + | Ticket_t : 'a comparable_ty * 'a ticket ty_metadata -> 'a ticket ty + | Chest_key_t : Timelock.chest_key ty_metadata -> Timelock.chest_key ty + | Chest_t : Timelock.chest ty_metadata -> Timelock.chest ty + +and ('top_ty, 'resty) stack_ty = + | Item_t : + 'ty ty * ('ty2, 'rest) stack_ty * var_annot option + -> ('ty, 'ty2 * 'rest) stack_ty + | Bot_t : (empty_cell, empty_cell) stack_ty + +and ('key, 'value) big_map = { + id : Big_map.Id.t option; + diff : ('key, 'value) big_map_overlay; + key_type : 'key comparable_ty; + value_type : 'value ty; +} + +and ('a, 's, 'r, 'f) kdescr = { + kloc : Script.location; + kbef : ('a, 's) stack_ty; + kaft : ('r, 'f) stack_ty; + kinstr : ('a, 's, 'r, 'f) kinstr; +} + +and ('a, 's) kinfo = {iloc : Script.location; kstack_ty : ('a, 's) stack_ty} + +(* + + Several instructions work under an arbitrary deep stack prefix + (e.g, IDipn, IDropn, etc). To convince the typechecker that + these instructions are well-typed, we must provide a witness + to statically characterize the relationship between the input + and the output stacks. The inhabitants of the following GADT + act as such witnesses. + + More precisely, a value [w] of type + + [(c, t, d, v, a, s, b, u) stack_prefix_preservation_witness] + + proves that there is a common prefix between an input stack + of type [a * s] and an output stack of type [b * u]. This prefix + is as deep as the number of [KPrefix] application in [w]. When + used with an operation parameterized by a natural number [n] + characterizing the depth at which the operation must be applied, + [w] is the Peano encoding of [n]. + + When this prefix is removed from the two stacks, the input stack + has type [c * t] while the output stack has type [d * v]. + +*) +and (_, _, _, _, _, _, _, _) stack_prefix_preservation_witness = + | KPrefix : + ('y, 'u) kinfo + * ('c, 'v, 'd, 'w, 'x, 's, 'y, 'u) stack_prefix_preservation_witness + -> ( 'c, + 'v, + 'd, + 'w, + 'a, + 'x * 's, + 'a, + 'y * 'u ) + stack_prefix_preservation_witness + | KRest : ('a, 's, 'b, 'u, 'a, 's, 'b, 'u) stack_prefix_preservation_witness + +and ('before, 'after) comb_gadt_witness = + | Comb_one : ('a * ('x * 'before), 'a * ('x * 'before)) comb_gadt_witness + | Comb_succ : + ('before, 'b * 'after) comb_gadt_witness + -> ('a * 'before, ('a * 'b) * 'after) comb_gadt_witness + +and ('before, 'after) uncomb_gadt_witness = + | Uncomb_one : ('rest, 'rest) uncomb_gadt_witness + | Uncomb_succ : + ('b * 'before, 'after) uncomb_gadt_witness + -> (('a * 'b) * 'before, 'a * 'after) uncomb_gadt_witness + +and ('before, 'after) comb_get_gadt_witness = + | Comb_get_zero : ('b, 'b) comb_get_gadt_witness + | Comb_get_one : ('a * 'b, 'a) comb_get_gadt_witness + | Comb_get_plus_two : + ('before, 'after) comb_get_gadt_witness + -> ('a * 'before, 'after) comb_get_gadt_witness + +and ('value, 'before, 'after) comb_set_gadt_witness = + | Comb_set_zero : ('value, _, 'value) comb_set_gadt_witness + | Comb_set_one : ('value, 'hd * 'tl, 'value * 'tl) comb_set_gadt_witness + | Comb_set_plus_two : + ('value, 'before, 'after) comb_set_gadt_witness + -> ('value, 'a * 'before, 'a * 'after) comb_set_gadt_witness +[@@coq_force_gadt] + +(* + + [dup_n_gadt_witness ('s, 't)] ensures that there exists at least + [n] elements in ['s] and that the [n]-th element of ['s] is of type + ['t]. Here [n] follows Peano's encoding (0 and successor). + Besides, [0] corresponds to the topmost element of ['s]. + + This relational predicate is defined by induction on [n]. + +*) +and (_, _) dup_n_gadt_witness = + | Dup_n_zero : ('a * 'rest, 'a) dup_n_gadt_witness + | Dup_n_succ : + ('stack, 'b) dup_n_gadt_witness + -> ('a * 'stack, 'b) dup_n_gadt_witness + +and ('a, 'b) view_signature = + | View_signature of { + name : Script_string.t; + input_ty : 'a ty; + output_ty : 'b ty; + } + +val kinfo_of_kinstr : ('a, 's, 'b, 'f) kinstr -> ('a, 's) kinfo + +type kinstr_rewritek = { + apply : 'b 'u 'r 'f. ('b, 'u, 'r, 'f) kinstr -> ('b, 'u, 'r, 'f) kinstr; +} + +val kinstr_rewritek : + ('a, 's, 'r, 'f) kinstr -> kinstr_rewritek -> ('a, 's, 'r, 'f) kinstr + +val ty_size : 'a ty -> 'a Type_size.t + +val comparable_ty_size : 'a comparable_ty -> 'a Type_size.t + +val unit_t : annot:type_annot option -> unit ty + +val int_t : annot:type_annot option -> z num ty + +val nat_t : annot:type_annot option -> n num ty + +val signature_t : annot:type_annot option -> signature ty + +val string_t : annot:type_annot option -> Script_string.t ty + +val bytes_t : annot:type_annot option -> Bytes.t ty + +val mutez_t : annot:type_annot option -> Tez.t ty + +val key_hash_t : annot:type_annot option -> public_key_hash ty + +val key_t : annot:type_annot option -> public_key ty + +val timestamp_t : annot:type_annot option -> Script_timestamp.t ty + +val address_t : annot:type_annot option -> address ty + +val bool_t : annot:type_annot option -> bool ty + +val pair_t : + Script.location -> + 'a ty * field_annot option * var_annot option -> + 'b ty * field_annot option * var_annot option -> + annot:type_annot option -> + ('a, 'b) pair ty tzresult + +val union_t : + Script.location -> + 'a ty * field_annot option -> + 'b ty * field_annot option -> + annot:type_annot option -> + ('a, 'b) union ty tzresult + +val union_bytes_bool_t : (Bytes.t, bool) union ty + +val lambda_t : + Script.location -> + 'arg ty -> + 'ret ty -> + annot:type_annot option -> + ('arg, 'ret) lambda ty tzresult + +val option_t : + Script.location -> 'v ty -> annot:type_annot option -> 'v option ty tzresult + +(* the quote is used to indicate where the annotation will go *) + +val option_mutez'_t : _ ty_metadata -> Tez.t option ty + +val option_string'_t : _ ty_metadata -> Script_string.t option ty + +val option_bytes'_t : _ ty_metadata -> Bytes.t option ty + +val option_nat_t : n num option ty + +val option_pair_nat_nat_t : (n num, n num) pair option ty + +val option_pair_nat'_nat'_t : _ ty_metadata -> (n num, n num) pair option ty + +val option_pair_nat_mutez'_t : _ ty_metadata -> (n num, Tez.t) pair option ty + +val option_pair_mutez'_mutez'_t : _ ty_metadata -> (Tez.t, Tez.t) pair option ty + +val option_pair_int'_nat_t : _ ty_metadata -> (z num, n num) pair option ty + +val option_pair_int_nat'_t : _ ty_metadata -> (z num, n num) pair option ty + +val list_t : + Script.location -> + 'v ty -> + annot:type_annot option -> + 'v boxed_list ty tzresult + +val list_operation_t : operation boxed_list ty + +val set_t : + Script.location -> + 'v comparable_ty -> + annot:type_annot option -> + 'v set ty tzresult + +val map_t : + Script.location -> + 'k comparable_ty -> + 'v ty -> + annot:type_annot option -> + ('k, 'v) map ty tzresult + +val big_map_t : + Script.location -> + 'k comparable_ty -> + 'v ty -> + annot:type_annot option -> + ('k, 'v) big_map ty tzresult + +val contract_t : + Script.location -> + 'arg ty -> + annot:type_annot option -> + 'arg typed_contract ty tzresult + +val contract_unit_t : unit typed_contract ty + +val sapling_transaction_t : + memo_size:Sapling.Memo_size.t -> + annot:type_annot option -> + Sapling.transaction ty + +val sapling_state_t : + memo_size:Sapling.Memo_size.t -> annot:type_annot option -> Sapling.state ty + +val operation_t : annot:type_annot option -> operation ty + +val chain_id_t : annot:type_annot option -> Chain_id.t ty + +val never_t : annot:type_annot option -> never ty + +val bls12_381_g1_t : annot:type_annot option -> Bls12_381.G1.t ty + +val bls12_381_g2_t : annot:type_annot option -> Bls12_381.G2.t ty + +val bls12_381_fr_t : annot:type_annot option -> Bls12_381.Fr.t ty + +val ticket_t : + Script.location -> + 'a comparable_ty -> + annot:type_annot option -> + 'a ticket ty tzresult + +val chest_key_t : annot:type_annot option -> Timelock.chest_key ty + +val chest_t : annot:type_annot option -> Timelock.chest ty + +(** + + The following functions named `X_traverse` for X in { kinstr, ty, + comparable_ty, value } provide tail recursive top down traversals + over the values of these types. + + The traversal goes through a value and rewrites an accumulator + along the way starting from some [init]ial value for the + accumulator. + + All these traversals follow the same recursion scheme: the + user-provided function is first called on the toplevel value, then + the traversal recurses on the direct subvalues of the same type. + + Hence, the user-provided function must only compute the + contribution of the value on the accumulator minus the contribution + of its subvalues of the same type. + +*) +type 'a kinstr_traverse = { + apply : 'b 'u 'r 'f. 'a -> ('b, 'u, 'r, 'f) kinstr -> 'a; +} + +val kinstr_traverse : + ('a, 'b, 'c, 'd) kinstr -> 'ret -> 'ret kinstr_traverse -> 'ret + +type 'a ty_traverse = { + apply : 't. 'a -> 't ty -> 'a; + apply_comparable : 't. 'a -> 't comparable_ty -> 'a; +} + +val comparable_ty_traverse : 'a comparable_ty -> 'r -> 'r ty_traverse -> 'r + +val ty_traverse : 'a ty -> 'r -> 'r ty_traverse -> 'r + +type 'accu stack_ty_traverse = { + apply : 'ty 's. 'accu -> ('ty, 's) stack_ty -> 'accu; +} + +val stack_ty_traverse : ('a, 's) stack_ty -> 'r -> 'r stack_ty_traverse -> 'r + +type 'a value_traverse = { + apply : 't. 'a -> 't ty -> 't -> 'a; + apply_comparable : 't. 'a -> 't comparable_ty -> 't -> 'a; +} + +val value_traverse : + ('t ty, 't comparable_ty) union -> 't -> 'r -> 'r value_traverse -> 'r + +val stack_top_ty : ('a, 'b * 's) stack_ty -> 'a ty diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size.ml b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size.ml new file mode 100644 index 000000000000..839a6ec28a22 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size.ml @@ -0,0 +1,741 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context +open Script_typed_ir +include Cache_memory_helpers + +let script_string_size s = Script_string.to_string s |> string_size + +(* Memo-sizes are 16-bit integers *) +let sapling_memo_size_size = !!0 + +let (comparable_ty_size, ty_size) = + let base {annot = _; size = _} = hh3w in + let apply_comparable : + type a. nodes_and_size -> a comparable_ty -> nodes_and_size = + fun accu cty -> + match cty with + | Unit_key a -> ret_succ_adding accu (base a) + | Int_key a -> ret_succ_adding accu (base a) + | Nat_key a -> ret_succ_adding accu (base a) + | Signature_key a -> ret_succ_adding accu (base a) + | String_key a -> ret_succ_adding accu (base a) + | Bytes_key a -> ret_succ_adding accu (base a) + | Mutez_key a -> ret_succ_adding accu (base a) + | Key_hash_key a -> ret_succ_adding accu (base a) + | Key_key a -> ret_succ_adding accu (base a) + | Timestamp_key a -> ret_succ_adding accu (base a) + | Address_key a -> ret_succ_adding accu (base a) + | Bool_key a -> ret_succ_adding accu (base a) + | Chain_id_key a -> ret_succ_adding accu (base a) + | Never_key a -> ret_succ_adding accu (base a) + | Pair_key ((_ty1, _fa1), (_ty2, _fa2), a) -> + ret_succ_adding accu @@ (base a +! hh6w) + | Union_key ((_ty1, _fa1), (_ty2, _fa2), a) -> + ret_succ_adding accu @@ (base a +! hh6w) + | Option_key (_ty, a) -> ret_succ_adding accu @@ (base a +! word_size) + and apply : type a. nodes_and_size -> a ty -> nodes_and_size = + fun accu ty -> + match ty with + | Unit_t a -> ret_succ_adding accu @@ base a + | Int_t a -> ret_succ_adding accu @@ base a + | Nat_t a -> ret_succ_adding accu @@ base a + | Signature_t a -> ret_succ_adding accu @@ base a + | String_t a -> ret_succ_adding accu @@ base a + | Bytes_t a -> ret_succ_adding accu @@ base a + | Mutez_t a -> ret_succ_adding accu @@ base a + | Key_hash_t a -> ret_succ_adding accu @@ base a + | Key_t a -> ret_succ_adding accu @@ base a + | Timestamp_t a -> ret_succ_adding accu @@ base a + | Address_t a -> ret_succ_adding accu @@ base a + | Bool_t a -> ret_succ_adding accu @@ base a + | Operation_t a -> ret_succ_adding accu @@ base a + | Chain_id_t a -> ret_succ_adding accu @@ base a + | Never_t a -> ret_succ_adding accu @@ base a + | Bls12_381_g1_t a -> ret_succ_adding accu @@ base a + | Bls12_381_g2_t a -> ret_succ_adding accu @@ base a + | Bls12_381_fr_t a -> ret_succ_adding accu @@ base a + | Chest_key_t a -> ret_succ_adding accu @@ base a + | Chest_t a -> ret_succ_adding accu @@ base a + | Pair_t ((_ty1, _fa1, _va1), (_ty2, _fa2, _va2), a) -> + ret_succ_adding accu @@ (base a +! hh8w) + | Union_t ((_ty1, _fa1), (_ty2, _fa2), a) -> + ret_succ_adding accu @@ (base a +! hh6w) + | Lambda_t (_ty1, _ty2, a) -> + ret_succ_adding accu @@ (base a +! (word_size *? 2)) + | Option_t (_ty, a) -> ret_succ_adding accu @@ (base a +! word_size) + | List_t (_ty, a) -> ret_succ_adding accu @@ (base a +! word_size) + | Set_t (_cty, a) -> ret_succ_adding accu @@ (base a +! word_size) + | Map_t (_cty, _ty, a) -> + ret_succ_adding accu @@ (base a +! (word_size *? 2)) + | Big_map_t (_cty, _ty, a) -> + ret_succ_adding accu @@ (base a +! (word_size *? 2)) + | Contract_t (_ty, a) -> ret_succ_adding accu @@ (base a +! word_size) + | Sapling_transaction_t (_m, a) -> + ret_succ_adding accu @@ (base a +! sapling_memo_size_size +! word_size) + | Sapling_state_t (_m, a) -> + ret_succ_adding accu @@ (base a +! sapling_memo_size_size +! word_size) + | Ticket_t (_cty, a) -> ret_succ_adding accu @@ (base a +! word_size) + in + let f = ({apply; apply_comparable} : nodes_and_size ty_traverse) in + ( (fun cty -> comparable_ty_traverse cty zero f), + fun ty -> ty_traverse ty zero f ) + +let stack_ty_size s = + let apply : type a s. nodes_and_size -> (a, s) stack_ty -> nodes_and_size = + fun accu s -> + match s with + | Bot_t -> ret_succ accu + | Item_t (ty, _, _annot) -> ret_succ_adding (accu ++ ty_size ty) h3w + in + stack_ty_traverse s zero {apply} + +let script_nat_size n = Script_int.to_zint n |> z_size + +let script_int_size n = Script_int.to_zint n |> z_size + +let signature_size = h3w +? Signature.size + +let key_hash_size (x : Signature.public_key_hash) = + h1w + +? Signature.( + match x with + | Ed25519 _ -> Ed25519.Public_key_hash.size + | Secp256k1 _ -> Secp256k1.Public_key_hash.size + | P256 _ -> P256.Public_key_hash.size) + +let public_key_size (x : public_key) = + let ks = Signature.Public_key.size x in + h1w +? ks + +let mutez_size = h2w + +let timestamp_size x = Script_timestamp.to_zint x |> z_size + +let contract_size = Contract.in_memory_size + +let address_size ((c, s) : address) = h2w +! contract_size c +! string_size s + +let view_signature_size (View_signature {name; input_ty; output_ty}) = + ret_adding + (ty_size input_ty ++ ty_size output_ty) + (h3w +! script_string_size name) + +let script_expr_hash_size = Script_expr_hash.size + +let peano_shape_proof = + let scale = header_size +! h1w in + fun k -> scale *? k + +let stack_prefix_preservation_witness_size = + let kinfo_size = h2w in + let scale = header_size +! (h2w +! kinfo_size) in + fun k -> scale *? k + +let comb_gadt_witness_size = peano_shape_proof + +let uncomb_gadt_witness_size = peano_shape_proof + +let comb_get_gadt_witness_size = peano_shape_proof + +let comb_set_gadt_witness_size = peano_shape_proof + +let dup_n_gadt_witness_size = peano_shape_proof + +let contract_size (arg_ty, address) = + ret_adding (ty_size arg_ty) (h2w +! address_size address) + +let sapling_state_size {Sapling.id; diff; memo_size = _} = + h3w + +! option_size (fun x -> z_size (Sapling.Id.unparse_to_z x)) id + +! Sapling.diff_in_memory_size diff + +! sapling_memo_size_size + +let operation_size + (operation : + packed_internal_operation * Lazy_storage.diffs_item list option) = + let (poi, diffs) = operation in + ret_adding + (Operation.packed_internal_operation_in_memory_size poi + ++ option_size_vec Lazy_storage.diffs_in_memory_size diffs) + h2w + +let chain_id_size = h1w +? Chain_id.size + +(* [contents] is handle by the recursion scheme in [value_size] *) +let ticket_size {ticketer; contents = _; amount} = + h3w +! Contract.in_memory_size ticketer +! script_nat_size amount + +let chest_size chest = + (* + type chest = { + locked_value : locked_value; + rsa_public : rsa_public; + ciphertext : ciphertext; + } + *) + let locked_value_size = 256 in + let rsa_public_size = 256 in + let ciphertext_size = Timelock.get_plaintext_size chest in + h3w +? (locked_value_size + rsa_public_size + ciphertext_size) + +let chest_key_size _ = + (* + type chest_key = { + unlocked_value : unlocked_value; + proof : time_lock_proof + } + *) + let unlocked_value_size = 256 in + let proof_size = 256 in + h2w +? (unlocked_value_size + proof_size) + +let view_size {input_ty; output_ty; view_code} = + ret_adding + (node_size input_ty ++ node_size output_ty ++ node_size view_code) + h3w + +let views_size views = + SMap.fold + (fun k view accu -> + ret_adding (accu ++ view_size view) (script_string_size k +! h4w)) + views + zero + +let kinfo_size {iloc = _; kstack_ty = _} = h2w + +(* The following mutually recursive functions are mostly + tail-recursive and the only recursive call that is not a tailcall + cannot be nested. (See [big_map_size].) For this reason, these + functions should not trigger stack overflows. *) +let rec value_size : + type a. + count_lambda_nodes:bool -> + nodes_and_size -> + (a ty, a comparable_ty) union -> + a -> + nodes_and_size = + fun ~count_lambda_nodes accu ty x -> + let apply : type a. nodes_and_size -> a ty -> a -> nodes_and_size = + fun accu ty x -> + match ty with + | Unit_t _ -> ret_succ accu + | Int_t _ -> ret_succ_adding accu (script_int_size x) + | Nat_t _ -> ret_succ_adding accu (script_nat_size x) + | Signature_t _ -> ret_succ_adding accu signature_size + | String_t _ -> ret_succ_adding accu (script_string_size x) + | Bytes_t _ -> ret_succ_adding accu (bytes_size x) + | Mutez_t _ -> ret_succ_adding accu mutez_size + | Key_hash_t _ -> ret_succ_adding accu (key_hash_size x) + | Key_t _ -> ret_succ_adding accu (public_key_size x) + | Timestamp_t _ -> ret_succ_adding accu (timestamp_size x) + | Address_t _ -> ret_succ_adding accu (address_size x) + | Bool_t _ -> ret_succ accu + | Pair_t (_, _, _) -> ret_succ_adding accu h2w + | Union_t (_, _, _) -> ret_succ_adding accu h1w + | Lambda_t (_, _, _) -> + (lambda_size [@ocaml.tailcall]) ~count_lambda_nodes (ret_succ accu) x + | Option_t (_, _) -> ret_succ_adding accu (option_size (fun _ -> !!0) x) + | List_t (_, _) -> ret_succ_adding accu (h2w +! (h2w *? x.length)) + | Set_t (_, _) -> + let module M = (val x) in + let boxing_space = !!300 in + ret_succ_adding accu (boxing_space +! (h4w *? M.size)) + | Map_t (_, _, _) -> + let module M = (val x) in + let boxing_space = !!300 in + ret_succ_adding accu (boxing_space +! (h5w *? M.size)) + | Big_map_t (cty, ty', _) -> + (big_map_size [@ocaml.tailcall]) + ~count_lambda_nodes + (ret_succ accu) + cty + ty' + x + | Contract_t (_, _) -> ret_succ (accu ++ contract_size x) + | Sapling_transaction_t (_, _) -> + ret_succ_adding accu (Sapling.transaction_in_memory_size x) + | Sapling_state_t (_, _) -> ret_succ_adding accu (sapling_state_size x) + | Operation_t _ -> ret_succ (accu ++ operation_size x) + | Chain_id_t _ -> ret_succ_adding accu chain_id_size + | Never_t _ -> ( match x with _ -> .) + (* Related to https://gitlab.com/dannywillems/ocaml-bls12-381/-/issues/56. + Since the update to blst as a backend for bls12-381, size_in_bytes is not + the correct value for the allocated memory. + There is 1 word for the OCaml block header, 1 word for the C pointer and + a certain number of words for the actual value of the algebraic object + whose size is fixed and defined by the object itself. + For G1, it allocates 3 C values of type blst_fp which is 48 bytes. + For G2, it allocates 3 C values of type blst_fp2 which is 48 * 2 bytes. + For Fr, it allocates 1 C value of type blst_fr which is 32 bytes. + *) + | Bls12_381_g1_t _ -> ret_succ_adding accu !!((2 * 8) + (3 * 48)) + | Bls12_381_g2_t _ -> ret_succ_adding accu !!((2 * 8) + (3 * 48 * 2)) + | Bls12_381_fr_t _ -> ret_succ_adding accu !!((2 * 8) + 32) + | Ticket_t (_, _) -> ret_succ_adding accu (ticket_size x) + | Chest_key_t _ -> ret_succ_adding accu (chest_key_size x) + | Chest_t _ -> ret_succ_adding accu (chest_size x) + in + let apply_comparable : + type a. nodes_and_size -> a comparable_ty -> a -> nodes_and_size = + fun accu ty x -> + match ty with + | Unit_key _ -> ret_succ accu + | Int_key _ -> ret_succ_adding accu (script_int_size x) + | Nat_key _ -> ret_succ_adding accu (script_nat_size x) + | Signature_key _ -> ret_succ_adding accu signature_size + | String_key _ -> ret_succ_adding accu (script_string_size x) + | Bytes_key _ -> ret_succ_adding accu (bytes_size x) + | Mutez_key _ -> ret_succ_adding accu mutez_size + | Key_hash_key _ -> ret_succ_adding accu (key_hash_size x) + | Key_key _ -> ret_succ_adding accu (public_key_size x) + | Timestamp_key _ -> ret_succ_adding accu (timestamp_size x) + | Address_key _ -> ret_succ_adding accu (address_size x) + | Bool_key _ -> ret_succ accu + | Pair_key (_, _, _) -> ret_succ_adding accu h2w + | Union_key (_, _, _) -> ret_succ_adding accu h1w + | Option_key (_, _) -> ret_succ_adding accu (option_size (fun _ -> !!0) x) + | Chain_id_key _ -> ret_succ_adding accu chain_id_size + | Never_key _ -> ( match x with _ -> .) + in + value_traverse ty x accu {apply; apply_comparable} + [@@coq_axiom_with_reason "unreachable expressions '.' not handled for now"] + +and big_map_size : + type a b. + count_lambda_nodes:bool -> + nodes_and_size -> + a comparable_ty -> + b ty -> + (a, b) big_map -> + nodes_and_size = + fun ~count_lambda_nodes accu cty ty' {id; diff; key_type; value_type} -> + (* [Map.bindings] cannot overflow and only consumes a + logarithmic amount of stack. *) + let diff_size = + let map_size = + Big_map_overlay.fold + (fun _key_hash (key, value) accu -> + let accu = ret_succ_adding accu !!script_expr_hash_size in + (* The following recursive call cannot introduce a stack + overflow because this would require a key of type + big_map while big_map is not comparable. *) + let accu = value_size ~count_lambda_nodes accu (R cty) key in + match value with + | None -> accu + | Some value -> + (value_size [@ocaml.tailcall]) + ~count_lambda_nodes + accu + (L ty') + value) + diff.map + accu + in + + ret_adding map_size h2w + in + let big_map_id_size s = z_size (Big_map.Id.unparse_to_z s) in + let id_size = option_size big_map_id_size id in + ret_adding + (comparable_ty_size key_type ++ ty_size value_type ++ diff_size) + (h4w +! id_size) + +and lambda_size : + type i o. + count_lambda_nodes:bool -> nodes_and_size -> (i, o) lambda -> nodes_and_size + = + fun ~count_lambda_nodes accu (Lam (kdescr, node)) -> + (* We assume that the nodes' size have already been counted if the + lambda is not a toplevel lambda. *) + let accu = + ret_adding (accu ++ if count_lambda_nodes then node_size node else zero) h2w + in + (kdescr_size [@ocaml.tailcall]) ~count_lambda_nodes:false accu kdescr + +and kdescr_size : + type a s r f. + count_lambda_nodes:bool -> + nodes_and_size -> + (a, s, r, f) kdescr -> + nodes_and_size = + fun ~count_lambda_nodes accu {kloc = _; kbef; kaft; kinstr} -> + let accu = + ret_adding (accu ++ stack_ty_size kbef ++ stack_ty_size kaft) h4w + in + (kinstr_size [@ocaml.tailcall]) ~count_lambda_nodes accu kinstr + +and kinstr_size : + type a s r f. + count_lambda_nodes:bool -> + nodes_and_size -> + (a, s, r, f) kinstr -> + nodes_and_size = + fun ~count_lambda_nodes accu t -> + let base kinfo = h2w +! kinfo_size kinfo in + let apply : + type a s r f. nodes_and_size -> (a, s, r, f) kinstr -> nodes_and_size = + fun accu t -> + match t with + | IDrop (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IDup (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISwap (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IConst (kinfo, x, k) -> + let accu = ret_succ_adding accu (base kinfo +! word_size) in + (value_size [@ocaml.tailcall]) + ~count_lambda_nodes + accu + (L (stack_top_ty (kinfo_of_kinstr k).kstack_ty)) + x + | ICons_pair (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ICar (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ICdr (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IUnpair (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ICons_some (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ICons_none (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IIf_none {kinfo; _} -> ret_succ_adding accu (base kinfo) + | IOpt_map {kinfo; _} -> ret_succ_adding accu (base kinfo) + | ICons_left (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ICons_right (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IIf_left {kinfo; _} -> ret_succ_adding accu (base kinfo) + | ICons_list (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INil (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IIf_cons {kinfo; _} -> ret_succ_adding accu (base kinfo) + | IList_map (kinfo, _, _) -> ret_succ_adding accu (base kinfo) + | IList_iter (kinfo, _, _) -> ret_succ_adding accu (base kinfo) + | IList_size (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IEmpty_set (kinfo, cty, _) -> + ret_succ_adding + (accu ++ comparable_ty_size cty) + (base kinfo +! word_size) + | ISet_iter (kinfo, _, _) -> ret_succ_adding accu (base kinfo) + | ISet_mem (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISet_update (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISet_size (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IEmpty_map (kinfo, cty, _) -> + ret_succ_adding + (accu ++ comparable_ty_size cty) + (base kinfo +! word_size) + | IMap_map (kinfo, _, _) -> ret_succ_adding accu (base kinfo +! word_size) + | IMap_iter (kinfo, _, _) -> ret_succ_adding accu (base kinfo +! word_size) + | IMap_mem (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMap_get (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMap_update (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMap_get_and_update (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMap_size (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IEmpty_big_map (kinfo, cty, ty, _) -> + ret_succ_adding + (accu ++ comparable_ty_size cty ++ ty_size ty) + (base kinfo +! (word_size *? 2)) + | IBig_map_mem (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IBig_map_get (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IBig_map_update (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IBig_map_get_and_update (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IConcat_string (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IConcat_string_pair (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISlice_string (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IString_size (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IConcat_bytes (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IConcat_bytes_pair (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISlice_bytes (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IBytes_size (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAdd_seconds_to_timestamp (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAdd_timestamp_to_seconds (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISub_timestamp_seconds (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IDiff_timestamps (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAdd_tez (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISub_tez (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISub_tez_legacy (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMul_teznat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMul_nattez (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IEdiv_teznat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IEdiv_tez (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IOr (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAnd (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IXor (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INot (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IIs_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INeg (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAbs_int (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IInt_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAdd_int (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAdd_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISub_int (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMul_int (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMul_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IEdiv_int (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IEdiv_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ILsl_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ILsr_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IOr_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAnd_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAnd_int_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IXor_nat (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INot_int (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IIf {kinfo; _} -> ret_succ_adding accu (base kinfo) + | ILoop (kinfo, _, _) -> ret_succ_adding accu (base kinfo) + | ILoop_left (kinfo, _, _) -> ret_succ_adding accu (base kinfo +! word_size) + | IDip (kinfo, _, _) -> ret_succ_adding accu (base kinfo +! word_size) + | IExec (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IApply (kinfo, ty, _) -> + ret_succ_adding (accu ++ ty_size ty) (base kinfo +! word_size) + | ILambda (kinfo, lambda, _) -> + let accu = ret_succ_adding accu (base kinfo +! word_size) in + (lambda_size [@ocaml.tailcall]) ~count_lambda_nodes accu lambda + | IFailwith (kinfo, _, ty) -> + ret_succ_adding (accu ++ ty_size ty) (base kinfo +! word_size) + | ICompare (kinfo, cty, _) -> + ret_succ_adding + (accu ++ comparable_ty_size cty) + (base kinfo +! word_size) + | IEq (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INeq (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ILt (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IGt (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ILe (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IGe (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAddress (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IContract (kinfo, ty, s, _) -> + ret_succ_adding + (accu ++ ty_size ty) + (base kinfo +! string_size s +! (word_size *? 2)) + | IView (kinfo, s, _) -> + ret_succ_adding (accu ++ view_signature_size s) (base kinfo +! word_size) + | ITransfer_tokens (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IImplicit_account (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ICreate_contract + {kinfo; storage_type; arg_type; lambda; root_name = _; views; k = _} -> + let accu = + ret_succ_adding + (accu ++ ty_size storage_type ++ ty_size arg_type + ++ views_size views) + (base kinfo +! (word_size *? 4)) + in + (lambda_size [@ocaml.tailcall]) ~count_lambda_nodes accu lambda + | ISet_delegate (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INow (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IBalance (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ILevel (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ICheck_signature (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IHash_key (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IPack (kinfo, ty, _) -> + ret_succ_adding (accu ++ ty_size ty) (base kinfo +! word_size) + | IUnpack (kinfo, ty, _) -> + ret_succ_adding (accu ++ ty_size ty) (base kinfo +! word_size) + | IBlake2b (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISha256 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISha512 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISource (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISender (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISelf (kinfo, ty, s, _) -> + ret_succ_adding + (accu ++ ty_size ty) + (base kinfo +! (word_size *? 2) +! string_size s) + | ISelf_address (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAmount (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISapling_empty_state (kinfo, _m, _) -> + ret_succ_adding accu (base kinfo +! word_size +! sapling_memo_size_size) + | ISapling_verify_update (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IDig (kinfo, n, _, _) -> + ret_succ_adding + accu + (base kinfo +! (word_size *? 2) + +! stack_prefix_preservation_witness_size n) + | IDug (kinfo, n, _, _) -> + ret_succ_adding + accu + (base kinfo +! (word_size *? 2) + +! stack_prefix_preservation_witness_size n) + | IDipn (kinfo, n, _, _, _) -> + ret_succ_adding + accu + (base kinfo +! (word_size *? 2) + +! stack_prefix_preservation_witness_size n) + | IDropn (kinfo, n, _, _) -> + ret_succ_adding + accu + (base kinfo +! (word_size *? 2) + +! stack_prefix_preservation_witness_size n) + | IChainId (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INever kinfo -> ret_succ_adding accu (kinfo_size kinfo) + | IVoting_power (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ITotal_voting_power (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IKeccak (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISha3 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAdd_bls12_381_g1 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAdd_bls12_381_g2 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IAdd_bls12_381_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMul_bls12_381_g1 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMul_bls12_381_g2 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMul_bls12_381_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMul_bls12_381_z_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IMul_bls12_381_fr_z (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IInt_bls12_381_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INeg_bls12_381_g1 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INeg_bls12_381_g2 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | INeg_bls12_381_fr (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IPairing_check_bls12_381 (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IComb (kinfo, n, _, _) -> + ret_succ_adding + accu + (base kinfo +! (word_size *? 2) +! comb_gadt_witness_size n) + | IUncomb (kinfo, n, _, _) -> + ret_succ_adding + accu + (base kinfo +! (word_size *? 2) +! uncomb_gadt_witness_size n) + | IComb_get (kinfo, n, _, _) -> + ret_succ_adding + accu + (base kinfo +! (word_size *? 2) +! comb_get_gadt_witness_size n) + | IComb_set (kinfo, n, _, _) -> + ret_succ_adding + accu + (base kinfo +! (word_size *? 2) +! comb_set_gadt_witness_size n) + | IDup_n (kinfo, n, _, _) -> + ret_succ_adding + accu + (base kinfo +! (word_size *? 2) +! dup_n_gadt_witness_size n) + | ITicket (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IRead_ticket (kinfo, _) -> ret_succ_adding accu (base kinfo) + | ISplit_ticket (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IJoin_tickets (kinfo, cty, _) -> + ret_succ_adding + (accu ++ comparable_ty_size cty) + (base kinfo +! word_size) + | IOpen_chest (kinfo, _) -> ret_succ_adding accu (base kinfo) + | IHalt kinfo -> ret_succ_adding accu (h1w +! kinfo_size kinfo) + | ILog (_, _, _, _) -> + (* This instruction is ignored because it is only used for testing. *) + accu + in + kinstr_traverse t accu {apply} + +let rec kinstr_extra_size : type a s r f. (a, s, r, f) kinstr -> nodes_and_size + = + fun t -> + let ret_zero x = (Nodes.zero, x) in + let apply : + type a s r f. nodes_and_size -> (a, s, r, f) kinstr -> nodes_and_size = + fun accu t -> + let stack_prefix_preservation_witness_size n = ret_zero (!!24 *? n) in + let dup_n_gadt_witness_size n = ret_zero (!!16 *? n) in + let comb n = ret_zero (!!16 *? n) in + let if_join k = + let kinfo = Script_typed_ir.kinfo_of_kinstr k in + stack_ty_size kinfo.kstack_ty + in + let self_size = + match t with + (* Op n *) + | IDig (_, n, _, _) -> stack_prefix_preservation_witness_size n + | IDug (_, n, _, _) -> stack_prefix_preservation_witness_size n + | IDipn (_, n, _, _, _) -> stack_prefix_preservation_witness_size n + | IDropn (_, n, _, _) -> stack_prefix_preservation_witness_size n + | IComb (_, n, _, _) -> comb n + | IUncomb (_, n, _, _) -> comb n + | IComb_get (_, n, _, _) -> comb (n / 2) + | IComb_set (_, n, _, _) -> comb (n / 2) + | IDup_n (_, n, _, _) -> dup_n_gadt_witness_size n + (* Whole stack types after conditionals and loops. *) + | IIf {k; _} -> if_join k + | IIf_cons {k; _} -> if_join k + | IIf_none {k; _} -> if_join k + | IIf_left {k; _} -> if_join k + (* Every instruction whose elaboration uses [merge_types], + [check_item_ty], [comparable_of_ty], or [ty_of_comparable_ty] + to create a type that is embedded in the IR. *) + | IJoin_tickets (_, _, k) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr k in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | ITicket (_, k) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr k in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | IRead_ticket (_, k) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr k in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | ICons_list (_, k) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr k in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | IMap_update (_, k) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr k in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | IMap_get_and_update (_, k) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr k in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | IBig_map_get_and_update (_, k) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr k in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | IApply (_, ty, _) -> ty_size ty + | ICompare (_, ty, _) -> comparable_ty_size ty + | IList_iter (_, body, _) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr body in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | IList_map (_, body, _) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr body in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | ISet_iter (_, body, _) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr body in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | IMap_map (_, body, _) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr body in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | IMap_iter (_, body, _) -> ( + let kinfo = Script_typed_ir.kinfo_of_kinstr body in + match kinfo.kstack_ty with Item_t (ty, _, _) -> ty_size ty) + | ILambda (_, lambda, _) -> lambda_extra_size lambda + | ICreate_contract {lambda; _} -> lambda_extra_size lambda + | _ -> zero + in + ret_succ (accu ++ self_size) + in + kinstr_traverse t zero {apply} + +and lambda_extra_size : type i o. (i, o) lambda -> nodes_and_size = + fun (Lam ({kinstr; _}, _)) -> kinstr_extra_size kinstr + +let lambda_size lam = + (* + + The following formula has been obtained through a regression + over the corpus of mainnet contracts in Granada. + + *) + let (lambda_nodes, lambda_size) = + lambda_size ~count_lambda_nodes:true zero lam + in + let (lambda_extra_size_nodes, lambda_extra_size) = lambda_extra_size lam in + let size = (lambda_size *? 157 /? 100) +! (lambda_extra_size *? 18 /? 100) in + (Nodes.add lambda_nodes lambda_extra_size_nodes, size) + +let kinstr_size kinstr = + let (kinstr_extra_size_nodes, kinstr_extra_size) = kinstr_extra_size kinstr in + let (kinstr_nodes, kinstr_size) = + kinstr_size ~count_lambda_nodes:true zero kinstr + in + let size = (kinstr_size *? 157 /? 100) +! (kinstr_extra_size *? 18 /? 100) in + (Nodes.add kinstr_nodes kinstr_extra_size_nodes, size) + +let value_size ty x = value_size ~count_lambda_nodes:true zero (L ty) x diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size.mli b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size.mli new file mode 100644 index 000000000000..5cdbb052e0e1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size.mli @@ -0,0 +1,71 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module provides overapproximation of memory footprint for + Michelson-related values. + + These overapproximations are used by the cache to evaluate its own + memory footprint and enforce declared limit over its size. + +*) + +(** [value_size ty v] returns an overapproximation of the size of the + in-memory representation of [v] of type [ty]. *) +val value_size : + 'a Script_typed_ir.ty -> 'a -> Cache_memory_helpers.nodes_and_size + +(** [ty_size ty] returns an overapproximation of the size of the + in-memory representation of type [ty]. *) +val ty_size : 'a Script_typed_ir.ty -> Cache_memory_helpers.nodes_and_size + +(** [comparable_ty_size cty] returns an overapproximation of the size + of the in-memory representation of comparable type [cty]. *) +val comparable_ty_size : + 'a Script_typed_ir.comparable_ty -> Cache_memory_helpers.nodes_and_size + +(** [lambda_size l] returns an overapproximation of the size of the + internal IR for the Michelson lambda abstraction [l]. *) +val lambda_size : + ('a, 'b) Script_typed_ir.lambda -> Cache_memory_helpers.nodes_and_size + +(** [kinstr_size i] returns an overapproximation of the size of the + internal IR [i]. *) +val kinstr_size : + ('a, 's, 'r, 'f) Script_typed_ir.kinstr -> Cache_memory_helpers.nodes_and_size + +(** [node_size root] returns the size of the in-memory representation + of [root] in bytes. This is an over-approximation of the memory + actually consumed by [root] since no sharing is taken into + account. *) +val node_size : Script_repr.node -> Cache_memory_helpers.nodes_and_size + +(** Pointwise addition (reexport from {!Cache_memory_helpers}) *) +val ( ++ ) : + Cache_memory_helpers.nodes_and_size -> + Cache_memory_helpers.nodes_and_size -> + Cache_memory_helpers.nodes_and_size + +(** Zero vector (reexport from {!Cache_memory_helpers}) *) +val zero : Cache_memory_helpers.nodes_and_size diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size_costs.ml b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size_costs.ml new file mode 100644 index 000000000000..b2e4a9af007c --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size_costs.ml @@ -0,0 +1,34 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module S = Saturation_repr + +(** FIXME insert proper gas constants (the gas constant below was fitted on + a non-standard machine) *) +let nodes_cost ~nodes = + let open S in + let nodes = Cache_memory_helpers.Nodes.to_int nodes in + let coeff = safe_int 45 in + Gas_limit_repr.atomic_step_cost (mul coeff (S.safe_int nodes)) diff --git a/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size_costs.mli b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size_costs.mli new file mode 100644 index 000000000000..9789e3d104af --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/script_typed_ir_size_costs.mli @@ -0,0 +1,28 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** [node_size_cost ~nodes] returns the cost of having called + a function in {!Script_typed_ir_size} that returned [nodes]. *) +val nodes_cost : nodes:Cache_memory_helpers.Nodes.t -> Gas_limit_repr.cost diff --git a/src/proto_012_PsiThaCa/lib_protocol/seed_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/seed_repr.ml new file mode 100644 index 000000000000..ea1c28351d31 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/seed_repr.ml @@ -0,0 +1,150 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Tezos Protocol Implementation - Random number generation *) + +type seed = B of State_hash.t + +type t = T of State_hash.t + +type sequence = S of State_hash.t + +type nonce = bytes + +let nonce_encoding = Data_encoding.Fixed.bytes Constants_repr.nonce_length + +let initial_seed = "Laissez-faire les proprietaires." + +let zero_bytes = Bytes.make Nonce_hash.size '\000' + +let state_hash_encoding = + let open Data_encoding in + conv State_hash.to_bytes State_hash.of_bytes_exn (Fixed.bytes Nonce_hash.size) + +let seed_encoding = + let open Data_encoding in + conv (fun (B b) -> b) (fun b -> B b) state_hash_encoding + +let empty = B (State_hash.hash_string [initial_seed]) + +let nonce (B state) nonce = + B (State_hash.hash_bytes [State_hash.to_bytes state; nonce]) + +let initialize_new (B state) append = + T (State_hash.hash_bytes (State_hash.to_bytes state :: zero_bytes :: append)) + +let xor_higher_bits i b = + let higher = TzEndian.get_int32 b 0 in + let r = Int32.logxor higher i in + let res = Bytes.copy b in + TzEndian.set_int32 res 0 r ; + res + +let sequence (T state) n = + State_hash.to_bytes state |> xor_higher_bits n |> fun b -> + S (State_hash.hash_bytes [b]) + +let take (S state) = + let b = State_hash.to_bytes state in + let h = State_hash.hash_bytes [b] in + (State_hash.to_bytes h, S h) + +let take_int32 s bound = + if Compare.Int32.(bound <= 0l) then invalid_arg "Seed_repr.take_int32" + (* FIXME *) + else + let drop_if_over = + Int32.sub Int32.max_int (Int32.rem Int32.max_int bound) + in + let rec loop s = + let (bytes, s) = take s in + let r = Int32.abs (TzEndian.get_int32 bytes 0) in + if Compare.Int32.(r >= drop_if_over) then loop s + else + let v = Int32.rem r bound in + (v, s) + in + loop s + +let take_int64 s bound = + if Compare.Int64.(bound <= 0L) then invalid_arg "Seed_repr.take_int64" + (* FIXME *) + else + let drop_if_over = + Int64.sub Int64.max_int (Int64.rem Int64.max_int bound) + in + + let rec loop s = + let (bytes, s) = take s in + let r = Int64.abs (TzEndian.get_int64 bytes 0) in + if Compare.Int64.(r >= drop_if_over) then loop s + else + let v = Int64.rem r bound in + (v, s) + in + loop s + +type error += Unexpected_nonce_length (* `Permanent *) + +let () = + register_error_kind + `Permanent + ~id:"unexpected_nonce_length" + ~title:"Unexpected nonce length" + ~description:"Nonce length is incorrect." + ~pp:(fun ppf () -> + Format.fprintf + ppf + "Nonce length is not %i bytes long as it should." + Constants_repr.nonce_length) + Data_encoding.empty + (function Unexpected_nonce_length -> Some () | _ -> None) + (fun () -> Unexpected_nonce_length) + +let make_nonce nonce = + if Compare.Int.(Bytes.length nonce <> Constants_repr.nonce_length) then + error Unexpected_nonce_length + else ok nonce + +let hash nonce = Nonce_hash.hash_bytes [nonce] + +let check_hash nonce hash = + Compare.Int.(Bytes.length nonce = Constants_repr.nonce_length) + && Nonce_hash.equal (Nonce_hash.hash_bytes [nonce]) hash + +let nonce_hash_key_part = Nonce_hash.to_path + +let initial_nonce_0 = zero_bytes + +let initial_nonce_hash_0 = hash initial_nonce_0 + +let deterministic_seed seed = nonce seed zero_bytes + +let initial_seeds n = + let[@coq_struct "i"] rec loop acc elt i = + if Compare.Int.(i = 1) then List.rev (elt :: acc) + else loop (elt :: acc) (deterministic_seed elt) (i - 1) + in + loop [] (B (State_hash.hash_bytes [])) n diff --git a/src/proto_012_PsiThaCa/lib_protocol/seed_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/seed_repr.mli new file mode 100644 index 000000000000..b19f8c93b19e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/seed_repr.mli @@ -0,0 +1,111 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Tezos Protocol Implementation - Random number generation + + This is not expected to be a good cryptographic random number + generator. In particular this is supposed to be used in situations + where the seed is a globally known information. + + The only expected property is: It should be difficult to find a + seed such that the generated sequence is a given one. *) + +(** {2 Random Generation} *) + +(** The state of the random number generator *) +type t + +(** A random seed, to derive random sequences from *) +type seed + +(** A random sequence, to derive random values from *) +type sequence + +(** [initialize_new state ident] returns a new generator *) +val initialize_new : seed -> bytes list -> t + +(** [sequence state n] prepares the n-th sequence of a state *) +val sequence : t -> int32 -> sequence + +(** Generates the next random value in the sequence *) +val take : sequence -> bytes * sequence + +(** [take_int32 s bound] generates the next random value as a bounded [int32] + + @param bound must be a positive integer + @raise Invalid_argument "Seed_repr.take_int32" if [bound] <= 0 + *) +val take_int32 : sequence -> int32 -> int32 * sequence + +(** [take_int64 s bound] generates the next random value as a bounded [int64] + + @param bound must be a positive integer + @raise Invalid_argument "Seed_repr.take_int64" if [bound] <= 0 + *) +val take_int64 : sequence -> int64 -> int64 * sequence + +(** {2 Predefined seeds} *) + +val empty : seed + +(** Returns a new seed by hashing the one passed with a constant. *) +val deterministic_seed : seed -> seed + +(** [initial_seeds n] generates the first [n] seeds for which there are no nonces. + The first seed is a constant value. The kth seed is the hash of seed (k-1) + concatenated with a constant. *) +val initial_seeds : int -> seed list + +(** {2 Entropy} *) + +(** A nonce for adding entropy to the generator *) +type nonce + +(** Add entropy to the seed generator *) +val nonce : seed -> nonce -> seed + +(** Use a byte sequence as a nonce *) +val make_nonce : bytes -> nonce tzresult + +(** Compute the has of a nonce *) +val hash : nonce -> Nonce_hash.t + +(** [check_hash nonce hash] is true if the nonce correspond to the hash *) +val check_hash : nonce -> Nonce_hash.t -> bool + +(** For using nonce hashes as keys in the hierarchical database *) +val nonce_hash_key_part : Nonce_hash.t -> string list -> string list + +(** {2 Predefined nonce} *) + +val initial_nonce_0 : nonce + +val initial_nonce_hash_0 : Nonce_hash.t + +(** {2 Serializers} *) + +val nonce_encoding : nonce Data_encoding.t + +val seed_encoding : seed Data_encoding.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/seed_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/seed_storage.ml new file mode 100644 index 000000000000..2f0723743686 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/seed_storage.ml @@ -0,0 +1,127 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | Unknown of { + oldest : Cycle_repr.t; + cycle : Cycle_repr.t; + latest : Cycle_repr.t; + } + +(* `Permanent *) + +let () = + register_error_kind + `Permanent + ~id:"seed.unknown_seed" + ~title:"Unknown seed" + ~description:"The requested seed is not available" + ~pp:(fun ppf (oldest, cycle, latest) -> + if Cycle_repr.(cycle < oldest) then + Format.fprintf + ppf + "The seed for cycle %a has been cleared from the context (oldest \ + known seed is for cycle %a)" + Cycle_repr.pp + cycle + Cycle_repr.pp + oldest + else + Format.fprintf + ppf + "The seed for cycle %a has not been computed yet (latest known seed \ + is for cycle %a)" + Cycle_repr.pp + cycle + Cycle_repr.pp + latest) + Data_encoding.( + obj3 + (req "oldest" Cycle_repr.encoding) + (req "requested" Cycle_repr.encoding) + (req "latest" Cycle_repr.encoding)) + (function + | Unknown {oldest; cycle; latest} -> Some (oldest, cycle, latest) + | _ -> None) + (fun (oldest, cycle, latest) -> Unknown {oldest; cycle; latest}) + +let compute_for_cycle c ~revealed cycle = + match Cycle_repr.pred cycle with + | None -> assert false (* should not happen *) + | Some previous_cycle -> + let levels = Level_storage.levels_with_commitments_in_cycle c revealed in + let combine (c, random_seed, unrevealed) level = + Storage.Seed.Nonce.get c level >>=? function + | Revealed nonce -> + Storage.Seed.Nonce.remove_existing c level >|=? fun c -> + (c, Seed_repr.nonce random_seed nonce, unrevealed) + | Unrevealed u -> + Storage.Seed.Nonce.remove_existing c level >|=? fun c -> + (c, random_seed, u :: unrevealed) + in + Storage.Seed.For_cycle.get c previous_cycle >>=? fun prev_seed -> + let seed = Seed_repr.deterministic_seed prev_seed in + List.fold_left_es combine (c, seed, []) levels + >>=? fun (c, seed, unrevealed) -> + Storage.Seed.For_cycle.init c cycle seed >|=? fun c -> (c, unrevealed) + +let for_cycle ctxt cycle = + let preserved = Constants_storage.preserved_cycles ctxt in + let current_level = Level_storage.current ctxt in + let current_cycle = current_level.cycle in + let latest = + if Cycle_repr.(current_cycle = root) then + Cycle_repr.add current_cycle (preserved + 1) + else Cycle_repr.add current_cycle preserved + in + let oldest = + match Cycle_repr.sub current_cycle preserved with + | None -> Cycle_repr.root + | Some oldest -> oldest + in + error_unless + Cycle_repr.(oldest <= cycle && cycle <= latest) + (Unknown {oldest; cycle; latest}) + >>?= fun () -> Storage.Seed.For_cycle.get ctxt cycle + +let init ctxt = + let preserved = Constants_storage.preserved_cycles ctxt in + List.fold_left_es + (fun (c, ctxt) seed -> + let cycle = Cycle_repr.of_int32_exn (Int32.of_int c) in + Storage.Seed.For_cycle.init ctxt cycle seed >|=? fun ctxt -> (c + 1, ctxt)) + (0, ctxt) + (Seed_repr.initial_seeds (preserved + 2)) + >|=? snd + +let cycle_end ctxt last_cycle = + (* NB: the clearing of past seeds is done elsewhere by the caller *) + let preserved = Constants_storage.preserved_cycles ctxt in + match Cycle_repr.pred last_cycle with + | None -> return (ctxt, []) + | Some revealed -> + (* cycle with revelations *) + let inited_seed_cycle = Cycle_repr.add last_cycle (preserved + 1) in + compute_for_cycle ctxt ~revealed inited_seed_cycle diff --git a/src/proto_012_PsiThaCa/lib_protocol/seed_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/seed_storage.mli new file mode 100644 index 000000000000..37e87efed99b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/seed_storage.mli @@ -0,0 +1,47 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += + | Unknown of { + oldest : Cycle_repr.t; + cycle : Cycle_repr.t; + latest : Cycle_repr.t; + } + +(* `Permanent *) + +(** Generates the first [preserved_cycles+2] seeds for which + there are no nonces. *) +val init : Raw_context.t -> Raw_context.t tzresult Lwt.t + +val for_cycle : Raw_context.t -> Cycle_repr.t -> Seed_repr.seed tzresult Lwt.t + +(** If it is the end of the cycle, computes and stores the seed of cycle at + distance [preserved_cycle+2] in the future using the seed of the previous + cycle and the revelations of the current one. *) +val cycle_end : + Raw_context.t -> + Cycle_repr.t -> + (Raw_context.t * Nonce_storage.unrevealed list) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/services_registration.ml b/src/proto_012_PsiThaCa/lib_protocol/services_registration.ml new file mode 100644 index 000000000000..41880bfc28c3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/services_registration.ml @@ -0,0 +1,122 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +type rpc_context = { + block_hash : Block_hash.t; + block_header : Block_header.shell_header; + context : Alpha_context.t; +} + +let rpc_init ({block_hash; block_header; context} : Updater.rpc_context) = + let level = block_header.level in + let timestamp = block_header.timestamp in + Alpha_context.prepare + ~level + ~predecessor_timestamp:timestamp + ~timestamp + context + >|=? fun (context, _, _) -> {block_hash; block_header; context} + +let rpc_services = + ref (RPC_directory.empty : Updater.rpc_context RPC_directory.t) + +let register0_fullctxt ~chunked s f = + rpc_services := + RPC_directory.register ~chunked !rpc_services s (fun ctxt q i -> + rpc_init ctxt >>=? fun ctxt -> f ctxt q i) + +let register0 ~chunked s f = + register0_fullctxt ~chunked s (fun {context; _} -> f context) + +let register0_noctxt ~chunked s f = + rpc_services := + RPC_directory.register ~chunked !rpc_services s (fun _ q i -> f q i) + +let register1_fullctxt ~chunked s f = + rpc_services := + RPC_directory.register ~chunked !rpc_services s (fun (ctxt, arg) q i -> + rpc_init ctxt >>=? fun ctxt -> f ctxt arg q i) + +let register1 ~chunked s f = + register1_fullctxt ~chunked s (fun {context; _} x -> f context x) + +let register2_fullctxt ~chunked s f = + rpc_services := + RPC_directory.register + ~chunked + !rpc_services + s + (fun ((ctxt, arg1), arg2) q i -> + rpc_init ctxt >>=? fun ctxt -> f ctxt arg1 arg2 q i) + +let register2 ~chunked s f = + register2_fullctxt ~chunked s (fun {context; _} a1 a2 q i -> + f context a1 a2 q i) + +let opt_register0_fullctxt ~chunked s f = + rpc_services := + RPC_directory.opt_register ~chunked !rpc_services s (fun ctxt q i -> + rpc_init ctxt >>=? fun ctxt -> f ctxt q i) + +let opt_register0 ~chunked s f = + opt_register0_fullctxt ~chunked s (fun {context; _} -> f context) + +let opt_register1_fullctxt ~chunked s f = + rpc_services := + RPC_directory.opt_register ~chunked !rpc_services s (fun (ctxt, arg) q i -> + rpc_init ctxt >>=? fun ctxt -> f ctxt arg q i) + +let opt_register1 ~chunked s f = + opt_register1_fullctxt ~chunked s (fun {context; _} x -> f context x) + +let opt_register2_fullctxt ~chunked s f = + rpc_services := + RPC_directory.opt_register + ~chunked + !rpc_services + s + (fun ((ctxt, arg1), arg2) q i -> + rpc_init ctxt >>=? fun ctxt -> f ctxt arg1 arg2 q i) + +let opt_register2 ~chunked s f = + opt_register2_fullctxt ~chunked s (fun {context; _} a1 a2 q i -> + f context a1 a2 q i) + +let get_rpc_services () = + let p = + RPC_directory.map + (fun c -> + rpc_init c >|= function + | Error t -> + raise (Failure (Format.asprintf "%a" Error_monad.pp_trace t)) + | Ok c -> c.context) + (Storage_description.build_directory Alpha_context.description) + in + RPC_directory.register_dynamic_directory + !rpc_services + RPC_path.(open_root / "context" / "raw" / "json") + (fun _ -> Lwt.return p) diff --git a/src/proto_012_PsiThaCa/lib_protocol/services_registration.mli b/src/proto_012_PsiThaCa/lib_protocol/services_registration.mli new file mode 100644 index 000000000000..7c6df68ebd23 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/services_registration.mli @@ -0,0 +1,127 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Functions for RPC service registration, using [Updater.rpc_context] and + [RPC_service.t] from the Protocol Environment. + + This module is a frontend to a mutable service directory. The various + [register] functions update the directory as a side-effect. + + The [get_rpc_services] function returns the resulting [RPC_context]. It is + parameterized by [Updater.rpc_context] which acts as the service prefix (in + practice meaning this type will be passed to each handler). Hence, + Protocol RPC services provide a {i read-only} view of the Ledger state. + *) + +open Alpha_context + +type rpc_context = { + block_hash : Block_hash.t; + block_header : Block_header.shell_header; + context : t; +} + +val rpc_init : Updater.rpc_context -> rpc_context Error_monad.tzresult Lwt.t + +val register0 : + chunked:bool -> + ( [< RPC_service.meth], + Updater.rpc_context, + Updater.rpc_context, + 'a, + 'b, + 'c ) + RPC_service.t -> + (t -> 'a -> 'b -> 'c Error_monad.tzresult Lwt.t) -> + unit + +val register0_noctxt : + chunked:bool -> + ([< RPC_service.meth], Updater.rpc_context, 'a, 'b, 'c, 'd) RPC_service.t -> + ('b -> 'c -> 'd Error_monad.tzresult Lwt.t) -> + unit + +val register1 : + chunked:bool -> + ( [< RPC_service.meth], + Updater.rpc_context, + Updater.rpc_context * 'a, + 'b, + 'c, + 'd ) + RPC_service.t -> + (t -> 'a -> 'b -> 'c -> 'd Error_monad.tzresult Lwt.t) -> + unit + +val register2 : + chunked:bool -> + ( [< RPC_service.meth], + Updater.rpc_context, + (Updater.rpc_context * 'a) * 'b, + 'c, + 'd, + 'e ) + RPC_service.t -> + (t -> 'a -> 'b -> 'c -> 'd -> 'e Error_monad.tzresult Lwt.t) -> + unit + +val opt_register0 : + chunked:bool -> + ( [< RPC_service.meth], + Updater.rpc_context, + Updater.rpc_context, + 'a, + 'b, + 'c ) + RPC_service.t -> + (t -> 'a -> 'b -> 'c option Error_monad.tzresult Lwt.t) -> + unit + +val opt_register1 : + chunked:bool -> + ( [< RPC_service.meth], + Updater.rpc_context, + Updater.rpc_context * 'a, + 'b, + 'c, + 'd ) + RPC_service.t -> + (t -> 'a -> 'b -> 'c -> 'd option Error_monad.tzresult Lwt.t) -> + unit + +val opt_register2 : + chunked:bool -> + ( [< RPC_service.meth], + Updater.rpc_context, + (Updater.rpc_context * 'a) * 'b, + 'c, + 'd, + 'e ) + RPC_service.t -> + (t -> 'a -> 'b -> 'c -> 'd -> 'e option Error_monad.tzresult Lwt.t) -> + unit + +val get_rpc_services : unit -> Updater.rpc_context RPC_directory.directory diff --git a/src/proto_012_PsiThaCa/lib_protocol/slot_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/slot_repr.ml new file mode 100644 index 000000000000..3b6c861b2022 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/slot_repr.ml @@ -0,0 +1,138 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type error += Invalid_slot of int + +let () = + register_error_kind + `Permanent + ~id:"slot.invalid_slot" + ~title:"invalid slot" + ~description:"Invalid slot" + ~pp:(fun ppf x -> Format.fprintf ppf "invalid slot: %d" x) + Data_encoding.(obj1 (req "bad_slot" int31)) + (function Invalid_slot x -> Some x | _ -> None) + (fun x -> Invalid_slot x) + +include Compare.Int + +(* TODO? should there be some assertions to verify that slots are + never too big ? Or do that in a storage module that depends on + constants ? *) + +let encoding = Data_encoding.uint16 + +let pp = Format.pp_print_int + +let zero = 0 + +let succ = succ + +let to_int x = x + +let max_value = (1 lsl 16) - 1 + +let of_int_do_not_use_except_for_parameters i = i + +let of_int_exn i = + if Compare.Int.(i < 0 || i > max_value) then + invalid_arg + (Format.sprintf + "valid slot values are in the interval [0, %d] (%d given)" + max_value + i) + else i + +module Map = Map.Make (Compare.Int) +module Set = Set.Make (Compare.Int) + +module List = struct + (* Expected invariant: list of increasing values *) + (* TODO find a way to properly enforce this invariant *) + type nonrec t = t list + + module Compressed = struct + type elt = {skip : int; take : int} + + type encoded = elt list + + let elt_encoding = + Data_encoding.( + conv + (fun {skip; take} -> (skip, take)) + (fun (skip, take) -> {skip; take}) + (obj2 (req "skip" uint16) (req "take" uint16))) + + let encoding = Data_encoding.list elt_encoding + + let encode l : encoded = + let rec loop_taking ~pos ~skipped ~taken l = + match l with + | [] -> if taken > 0 then [{skip = skipped; take = taken}] else [] + | h :: t -> + if h = pos then + loop_taking ~pos:(pos + 1) ~skipped ~taken:(taken + 1) t + else + let elt = {skip = skipped; take = taken} in + let skipped = h - pos in + let taken = 1 in + let elts = loop_taking ~pos:(h + 1) ~skipped ~taken t in + elt :: elts + in + loop_taking ~pos:0 ~skipped:0 ~taken:0 l + + let decode (elts : encoded) = + let rec loop ~pos elts = + match elts with + | [] -> Ok [] + | elt :: elts -> ( + let pos = pos + elt.skip in + match + List.init ~when_negative_length:() elt.take (fun i -> i + pos) + with + | Ok l -> ( + let pos = pos + elt.take in + match loop ~pos elts with Ok t -> Ok (l @ t) | e -> e) + | Error () -> + Error "A compressed element contains a negative list size") + in + loop ~pos:0 elts + end + + let encoding = + Data_encoding.conv_with_guard + Compressed.encode + Compressed.decode + Compressed.encoding + + let slot_range ~min ~count = + error_when (min < 0) (Invalid_slot min) >>? fun () -> + error_when (min > max_value) (Invalid_slot min) >>? fun () -> + error_when (count < 1) (Invalid_slot count) >>? fun () -> + error_when (count > max_value) (Invalid_slot count) >>? fun () -> + let max = min + count - 1 in + error_when (max > max_value) (Invalid_slot max) >>? fun () -> + ok Misc.(min --> max) +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/slot_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/slot_repr.mli new file mode 100644 index 000000000000..c173ce7c7251 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/slot_repr.mli @@ -0,0 +1,63 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* TODO: https://gitlab.com/tezos/tezos/-/issues/2057 + remake abstract (required index for storage) *) +type t = int + +val encoding : t Data_encoding.t + +val pp : Format.formatter -> t -> unit + +val zero : t + +val succ : t -> t + +val max_value : t + +val of_int_do_not_use_except_for_parameters : int -> t + +(** [of_int i] creates a slot index from integer [i] + + @raise Invalid_argument if [i < 0 || i > max_value] +*) +val of_int_exn : int -> t + +val to_int : t -> int + +module Map : Map.S with type key = t + +module Set : Set.S with type elt = t + +include Compare.S with type t := t + +module List : sig + (* Expected invariant: list of increasing values *) + type nonrec t = t list + + val encoding : t Data_encoding.t + + val slot_range : min:int -> count:int -> t tzresult +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/stake_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/stake_storage.ml new file mode 100644 index 000000000000..2927c48e8348 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/stake_storage.ml @@ -0,0 +1,325 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Misc + +module Selected_distribution_for_cycle = struct + module Cache_client = struct + type cached_value = (Signature.Public_key_hash.t * Tez_repr.t) list + + let namespace = Cache_repr.create_namespace "stake_distribution" + + let cache_index = 1 + + let value_of_identifier ctxt identifier = + let cycle = Cycle_repr.of_string_exn identifier in + Storage.Stake.Selected_distribution_for_cycle.get ctxt cycle + end + + module Cache = (val Cache_repr.register_exn (module Cache_client)) + + let identifier_of_cycle cycle = Format.asprintf "%a" Cycle_repr.pp cycle + + let init ctxt cycle stakes = + let id = identifier_of_cycle cycle in + Storage.Stake.Selected_distribution_for_cycle.init ctxt cycle stakes + >>=? fun ctxt -> + let size = Constants_repr.stake_distribution_size in + Cache.update ctxt id (Some (stakes, size)) >>?= fun ctxt -> return ctxt + + let get ctxt cycle = + let id = identifier_of_cycle cycle in + Cache.find ctxt id >>=? function + | None -> Storage.Stake.Selected_distribution_for_cycle.get ctxt cycle + | Some v -> return v + + let remove_existing ctxt cycle = + let id = identifier_of_cycle cycle in + (Cache.find ctxt id >>=? function + | None -> return ctxt + | Some _ -> Cache.update ctxt id None |> Lwt.return) + >>=? fun ctxt -> + Storage.Stake.Selected_distribution_for_cycle.remove_existing ctxt cycle +end + +module Delegate_sampler_state = struct + module Cache_client = struct + type cached_value = + (Signature.Public_key.t * Signature.Public_key_hash.t) Sampler.t + + let namespace = Cache_repr.create_namespace "sampler_state" + + let cache_index = 2 + + let value_of_identifier ctxt identifier = + let cycle = Cycle_repr.of_string_exn identifier in + Storage.Delegate_sampler_state.get ctxt cycle + end + + module Cache = (val Cache_repr.register_exn (module Cache_client)) + + let identifier_of_cycle cycle = Format.asprintf "%a" Cycle_repr.pp cycle + + let init ctxt cycle sampler_state = + let id = identifier_of_cycle cycle in + Storage.Delegate_sampler_state.init ctxt cycle sampler_state + >>=? fun ctxt -> + let size = Constants_repr.sampler_state_size in + Cache.update ctxt id (Some (sampler_state, size)) >>?= fun ctxt -> + return ctxt + + let get ctxt cycle = + let id = identifier_of_cycle cycle in + Cache.find ctxt id >>=? function + | None -> Storage.Delegate_sampler_state.get ctxt cycle + | Some v -> return v + + let remove_existing ctxt cycle = + let id = identifier_of_cycle cycle in + (Cache.find ctxt id >>=? function + | None -> return ctxt + | Some _ -> Cache.update ctxt id None |> Lwt.return) + >>=? fun ctxt -> Storage.Delegate_sampler_state.remove_existing ctxt cycle +end + +let get_staking_balance = Storage.Stake.Staking_balance.get + +let ensure_stake_inited ctxt delegate = + Storage.Stake.Staking_balance.mem ctxt delegate >>= function + | true -> return ctxt + | false -> + Frozen_deposits_storage.init ctxt delegate >>=? fun ctxt -> + Storage.Stake.Staking_balance.init ctxt delegate Tez_repr.zero + +let remove_stake ctxt delegate amount = + ensure_stake_inited ctxt delegate >>=? fun ctxt -> + let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + get_staking_balance ctxt delegate >>=? fun staking_balance_before -> + Tez_repr.(staking_balance_before -? amount) >>?= fun staking_balance -> + Storage.Stake.Staking_balance.update ctxt delegate staking_balance + >>=? fun ctxt -> + Delegate_activation_storage.is_inactive ctxt delegate >>=? fun inactive -> + if (not inactive) && Tez_repr.(staking_balance_before >= tokens_per_roll) then + if Tez_repr.(staking_balance < tokens_per_roll) then + Storage.Stake.Active_delegate_with_one_roll.remove ctxt delegate + >>= fun ctxt -> return ctxt + else return ctxt + else + (* The delegate was not in Stake.Active_delegate_with_one_roll, + either because it was inactive, or because it did not have a + roll, in which case it still does not have a roll. *) + return ctxt + +let add_stake ctxt delegate amount = + ensure_stake_inited ctxt delegate >>=? fun ctxt -> + let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + get_staking_balance ctxt delegate >>=? fun staking_balance_before -> + Tez_repr.(amount +? staking_balance_before) >>?= fun staking_balance -> + Storage.Stake.Staking_balance.update ctxt delegate staking_balance + >>=? fun ctxt -> + if Tez_repr.(staking_balance >= tokens_per_roll) then + Delegate_activation_storage.is_inactive ctxt delegate >>=? fun inactive -> + if inactive || Tez_repr.(staking_balance_before >= tokens_per_roll) then + return ctxt + else + Storage.Stake.Active_delegate_with_one_roll.add ctxt delegate () + >>= fun ctxt -> return ctxt + else + (* The delegate was not in Stake.Active_delegate_with_one_roll, + because it did not have a roll (as otherwise it would have a + roll now). *) + return ctxt + +let deactivate_only_call_from_delegate_storage ctxt delegate = + Storage.Stake.Active_delegate_with_one_roll.remove ctxt delegate + +let activate_only_call_from_delegate_storage ctxt delegate = + ensure_stake_inited ctxt delegate >>=? fun ctxt -> + get_staking_balance ctxt delegate >>=? fun staking_balance -> + let tokens_per_roll = Constants_storage.tokens_per_roll ctxt in + if Tez_repr.(staking_balance >= tokens_per_roll) then + Storage.Stake.Active_delegate_with_one_roll.add ctxt delegate () + >>= fun ctxt -> return ctxt + else return ctxt + +let snapshot ctxt = + Storage.Stake.Last_snapshot.get ctxt >>=? fun index -> + Storage.Stake.Last_snapshot.update ctxt (index + 1) >>=? fun ctxt -> + Storage.Stake.Staking_balance.snapshot ctxt index >>=? fun ctxt -> + Storage.Stake.Active_delegate_with_one_roll.snapshot ctxt index + +let select_distribution_for_cycle ctxt cycle pubkey = + Storage.Stake.Last_snapshot.get ctxt >>=? fun max_index -> + Storage.Seed.For_cycle.get ctxt cycle >>=? fun seed -> + let rd = Seed_repr.initialize_new seed [Bytes.of_string "stake_snapshot"] in + let seq = Seed_repr.sequence rd 0l in + let selected_index = + Seed_repr.take_int32 seq (Int32.of_int max_index) |> fst |> Int32.to_int + in + List.fold_left_es + (fun ctxt index -> + (if Compare.Int.(index = selected_index) then + Storage.Stake.Active_delegate_with_one_roll.fold_snapshot + ctxt + index + ~order:`Sorted + ~init:([], Tez_repr.zero) + ~f:(fun delegate () (acc, total_stake) -> + Storage.Stake.Staking_balance.Snapshot.get ctxt (index, delegate) + >>=? fun staking_balance -> + let delegate_contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Frozen_deposits_limit.find ctxt delegate_contract + >>=? fun frozen_deposits_limit -> + Storage.Contract.Balance.get ctxt delegate_contract + >>=? fun balance -> + Frozen_deposits_storage.get ctxt delegate_contract + >>=? fun frozen_deposits -> + Tez_repr.(balance +? frozen_deposits.current_amount) + >>?= fun total_balance -> + let frozen_deposits_percentage = + Constants_storage.frozen_deposits_percentage ctxt + in + let stake_to_consider = + match frozen_deposits_limit with + | Some frozen_deposits_limit -> ( + try + let max_mutez = Tez_repr.of_mutez_exn Int64.max_int in + let frozen_stake_limit = + if Tez_repr.(frozen_deposits_limit > div_exn max_mutez 100) + then max_mutez + else + Tez_repr.( + div_exn + (mul_exn frozen_deposits_limit 100) + frozen_deposits_percentage) + in + Tez_repr.min staking_balance frozen_stake_limit + with _ -> staking_balance) + | None -> staking_balance + in + let max_staking_capacity = + Tez_repr.( + div_exn (mul_exn total_balance 100) frozen_deposits_percentage) + in + let stake_for_cycle = + Tez_repr.min stake_to_consider max_staking_capacity + in + Tez_repr.(total_stake +? stake_for_cycle) >>?= fun total_stake -> + return ((delegate, stake_for_cycle) :: acc, total_stake)) + >>=? fun (stakes, total_stake) -> + let stakes = + List.sort (fun (_, x) (_, y) -> Tez_repr.compare y x) stakes + in + Selected_distribution_for_cycle.init ctxt cycle stakes >>=? fun ctxt -> + Storage.Total_active_stake.add ctxt cycle total_stake >>= fun ctxt -> + List.fold_left_es + (fun acc (pkh, stake) -> + pubkey ctxt pkh >>=? fun pk -> + return (((pk, pkh), Tez_repr.to_mutez stake) :: acc)) + [] + stakes + >>=? fun stakes_pk -> + let state = Sampler.create stakes_pk in + Delegate_sampler_state.init ctxt cycle state + else return ctxt) + >>=? fun ctxt -> + Storage.Stake.Staking_balance.delete_snapshot ctxt index >>= fun ctxt -> + Storage.Stake.Active_delegate_with_one_roll.delete_snapshot ctxt index + >>= fun ctxt -> return ctxt) + ctxt + Misc.(0 --> (max_index - 1)) + >>=? fun ctxt -> Storage.Stake.Last_snapshot.update ctxt 0 + +let select_distribution_for_cycle_do_not_call_except_for_migration = + select_distribution_for_cycle + +let clear_cycle ctxt cycle = + Storage.Total_active_stake.remove_existing ctxt cycle >>=? fun ctxt -> + Selected_distribution_for_cycle.remove_existing ctxt cycle >>=? fun ctxt -> + Delegate_sampler_state.remove_existing ctxt cycle >>=? fun ctxt -> + Storage.Seed.For_cycle.remove_existing ctxt cycle + +let init_first_cycles ctxt pubkey = + let preserved = Constants_storage.preserved_cycles ctxt in + List.fold_left_es + (fun ctxt c -> + let cycle = Cycle_repr.of_int32_exn (Int32.of_int c) in + snapshot ctxt >>=? fun ctxt -> + select_distribution_for_cycle ctxt cycle pubkey) + ctxt + (0 --> preserved) + >>=? fun ctxt -> + (* Precompute a snapshot for cycle (preserved_cycles + 1) *) + snapshot ctxt + +let fold ctxt ~f ~order init = + Storage.Stake.Active_delegate_with_one_roll.fold + ctxt + ~order + ~init:(Ok init) + ~f:(fun delegate () acc -> + acc >>?= fun acc -> + get_staking_balance ctxt delegate >>=? fun stake -> + f (delegate, stake) acc) + +let select_new_distribution_at_cycle_end ctxt ~new_cycle = + let preserved = Constants_storage.preserved_cycles ctxt in + let for_cycle = Cycle_repr.add new_cycle preserved in + select_distribution_for_cycle ctxt for_cycle + +let clear_at_cycle_end ctxt ~new_cycle = + let max_slashing_period = Constants_storage.max_slashing_period ctxt in + match Cycle_repr.sub new_cycle max_slashing_period with + | None -> return ctxt + | Some cycle_to_clear -> clear_cycle ctxt cycle_to_clear + +let get ctxt delegate = + Storage.Stake.Active_delegate_with_one_roll.mem ctxt delegate >>= function + | true -> get_staking_balance ctxt delegate + | false -> return Tez_repr.zero + +let fold_on_active_delegates_with_rolls = + Storage.Stake.Active_delegate_with_one_roll.fold + +let get_selected_distribution = Selected_distribution_for_cycle.get + +let find_selected_distribution = + Storage.Stake.Selected_distribution_for_cycle.find + +let prepare_stake_distribution ctxt = + let level = Level_storage.current ctxt in + Selected_distribution_for_cycle.get ctxt level.cycle >>=? fun stakes -> + let stake_distribution = + List.fold_left + (fun map (pkh, stake) -> Signature.Public_key_hash.Map.add pkh stake map) + Signature.Public_key_hash.Map.empty + stakes + in + return + (Raw_context.init_stake_distribution_for_current_cycle + ctxt + stake_distribution) + +let get_total_active_stake = Storage.Total_active_stake.get diff --git a/src/proto_012_PsiThaCa/lib_protocol/stake_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/stake_storage.mli new file mode 100644 index 000000000000..66984a63211e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/stake_storage.mli @@ -0,0 +1,126 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Delegate_sampler_state : sig + val init : + Raw_context.t -> + Cycle_repr.t -> + Storage.Delegate_sampler_state.value -> + Raw_context.t tzresult Lwt.t + + val get : + Raw_context.t -> + Cycle_repr.t -> + Storage.Delegate_sampler_state.value tzresult Lwt.t + + val remove_existing : + Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t +end + +val remove_stake : + Raw_context.t -> + Signature.Public_key_hash.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t + +val add_stake : + Raw_context.t -> + Signature.Public_key_hash.t -> + Tez_repr.t -> + Raw_context.t tzresult Lwt.t + +val deactivate_only_call_from_delegate_storage : + Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t Lwt.t + +val activate_only_call_from_delegate_storage : + Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t tzresult Lwt.t + +val get_staking_balance : + Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t + +val snapshot : Raw_context.t -> Raw_context.t tzresult Lwt.t + +val select_distribution_for_cycle_do_not_call_except_for_migration : + Raw_context.t -> + Cycle_repr.t -> + (Raw_context.t -> + Signature.Public_key_hash.t -> + Signature.Public_key.t tzresult Lwt.t) -> + Raw_context.t tzresult Lwt.t + +val clear_cycle : Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t + +val init_first_cycles : + Raw_context.t -> + (Raw_context.t -> + Signature.Public_key_hash.t -> + Signature.Public_key.t tzresult Lwt.t) -> + Raw_context.t tzresult Lwt.t + +val fold : + Raw_context.t -> + f:(Signature.Public_key_hash.t * Tez_repr.t -> 'a -> 'a tzresult Lwt.t) -> + order:[`Sorted | `Undefined] -> + 'a -> + 'a tzresult Lwt.t + +val select_new_distribution_at_cycle_end : + Raw_context.t -> + new_cycle:Cycle_repr.t -> + (Raw_context.t -> + Signature.Public_key_hash.t -> + Signature.Public_key.t tzresult Lwt.t) -> + Raw_context.t tzresult Lwt.t + +val clear_at_cycle_end : + Raw_context.t -> new_cycle:Cycle_repr.t -> Raw_context.t tzresult Lwt.t + +val get : + Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t tzresult Lwt.t + +val fold_on_active_delegates_with_rolls : + Raw_context.t -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(Signature.Public_key_hash.t -> unit -> 'a -> 'a Lwt.t) -> + 'a Lwt.t + +val get_selected_distribution : + Raw_context.t -> + Cycle_repr.t -> + (Signature.Public_key_hash.t * Tez_repr.t) list tzresult Lwt.t + +val find_selected_distribution : + Raw_context.t -> + Cycle_repr.t -> + (Signature.Public_key_hash.t * Tez_repr.t) list option tzresult Lwt.t + +(** Copy the stake distribution for the current cycle (from + [Storage.Stake.Selected_distribution_for_cycle]) in the raw + context. *) +val prepare_stake_distribution : Raw_context.t -> Raw_context.t tzresult Lwt.t + +val get_total_active_stake : + Raw_context.t -> Cycle_repr.t -> Tez_repr.t tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/state_hash.ml b/src/proto_012_PsiThaCa/lib_protocol/state_hash.ml new file mode 100644 index 000000000000..a39ce4a21127 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/state_hash.ml @@ -0,0 +1,44 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let random_state_hash = "\076\064\204" (* rng(53): never used... *) + +module H = + Blake2B.Make + (Base58) + (struct + let name = "random" + + let title = "A random generation state" + + let b58check_prefix = random_state_hash + + let size = None + end) + +include H +include Path_encoding.Make_hex (H) + +let () = Base58.check_encoded_prefix b58check_encoding "rng" 53 diff --git a/src/proto_012_PsiThaCa/lib_protocol/state_hash.mli b/src/proto_012_PsiThaCa/lib_protocol/state_hash.mli new file mode 100644 index 000000000000..7ae77f3a0c42 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/state_hash.mli @@ -0,0 +1,30 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** A specialized Blake2B implementation for hashing internal states of random + number generators. *) + +include S.HASH diff --git a/src/proto_012_PsiThaCa/lib_protocol/storage.ml b/src/proto_012_PsiThaCa/lib_protocol/storage.ml new file mode 100644 index 000000000000..1dfc0041e643 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/storage.ml @@ -0,0 +1,1616 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Storage_functors +open Storage_sigs + +module Encoding = struct + module UInt16 = struct + type t = int + + let encoding = Data_encoding.uint16 + end + + module Int32 = struct + type t = Int32.t + + let encoding = Data_encoding.int32 + end + + module Int64 = struct + type t = Int64.t + + let encoding = Data_encoding.int64 + end + + module Z = struct + type t = Z.t + + let encoding = Data_encoding.z + end +end + +module Int31_index : sig + include INDEX with type t = int +end = struct + type t = int + + let path_length = 1 + + let to_path c l = string_of_int c :: l + + let of_path = function [] | _ :: _ :: _ -> None | [c] -> int_of_string_opt c + + type 'a ipath = 'a * t + + let args = + Storage_description.One + { + rpc_arg = RPC_arg.int; + encoding = Data_encoding.int31; + compare = Compare.Int.compare; + } +end + +module Make_index (H : Storage_description.INDEX) : + INDEX with type t = H.t and type 'a ipath = 'a * H.t = struct + include H + + type 'a ipath = 'a * t + + let args = Storage_description.One {rpc_arg; encoding; compare} +end + +module type Simple_single_data_storage = sig + type value + + val get : Raw_context.t -> value tzresult Lwt.t + + val update : Raw_context.t -> value -> Raw_context.t tzresult Lwt.t + + val init : Raw_context.t -> value -> Raw_context.t tzresult Lwt.t +end + +module Legacy_block_priority : + Simple_single_data_storage with type value = int = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["block_priority"] + end) + (Encoding.UInt16) + +module Block_round : Simple_single_data_storage with type value = Round_repr.t = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["block_round"] + end) + (Round_repr) + +module Tenderbake = struct + module First_level = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["first_level_of_Tenderbake"] + end) + (Raw_level_repr) + + module Branch = struct + type t = Block_hash.t * Block_payload_hash.t + + let encoding = + Data_encoding.( + obj2 + (req "grand_parent_hash" Block_hash.encoding) + (req "predecessor_payload" Block_payload_hash.encoding)) + end + + module Endorsement_branch = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["endorsement_branch"] + end) + (Branch) + + module Grand_parent_branch = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["grand_parent_branch"] + end) + (Branch) +end + +(** Contracts handling *) + +type deposits = {initial_amount : Tez_repr.t; current_amount : Tez_repr.t} + +module Deposits = struct + type t = deposits + + let encoding = + let open Data_encoding in + conv + (fun {initial_amount; current_amount} -> (initial_amount, current_amount)) + (fun (initial_amount, current_amount) -> {initial_amount; current_amount}) + (obj2 + (req "initial_amount" Tez_repr.encoding) + (req "actual_amount" Tez_repr.encoding)) +end + +type missed_endorsements_info = {remaining_slots : int; missed_levels : int} + +module Missed_endorsements_info = struct + type t = missed_endorsements_info + + let encoding = + let open Data_encoding in + conv + (fun {remaining_slots; missed_levels} -> (remaining_slots, missed_levels)) + (fun (remaining_slots, missed_levels) -> {remaining_slots; missed_levels}) + (obj2 (req "remaining_slots" int31) (req "missed_levels" int31)) +end + +module Contract = struct + module Raw_context = + Make_subcontext (Registered) (Raw_context) + (struct + let name = ["contracts"] + end) + + module Global_counter : Simple_single_data_storage with type value = Z.t = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["global_counter"] + end) + (Encoding.Z) + + module Indexed_context = + Make_indexed_subcontext + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["index"] + end)) + (Make_index (Contract_repr.Index)) + + let fold = Indexed_context.fold_keys + + let list = Indexed_context.keys + + module Balance = + Indexed_context.Make_map + (struct + let name = ["balance"] + end) + (Tez_repr) + + module Missed_endorsements = + Indexed_context.Make_map + (struct + let name = ["missed_endorsements"] + end) + (Missed_endorsements_info) + + module Legacy_frozen_balance_index = + Make_indexed_subcontext + (Make_subcontext (Ghost) (Indexed_context.Raw_context) + (struct + let name = ["frozen_balance"] + end)) + (Make_index (Cycle_repr.Index)) + + module Legacy_frozen_deposits = + Legacy_frozen_balance_index.Make_map + (struct + let name = ["deposits"] + end) + (Tez_repr) + + module Legacy_frozen_fees = + Legacy_frozen_balance_index.Make_map + (struct + let name = ["fees"] + end) + (Tez_repr) + + module Legacy_frozen_rewards = + Legacy_frozen_balance_index.Make_map + (struct + let name = ["rewards"] + end) + (Tez_repr) + + module Manager = + Indexed_context.Make_map + (struct + let name = ["manager"] + end) + (Manager_repr) + + module Delegate = + Indexed_context.Make_map + (struct + let name = ["delegate"] + end) + (Signature.Public_key_hash) + + module Inactive_delegate = + Indexed_context.Make_set + (Registered) + (struct + let name = ["inactive_delegate"] + end) + + module Delegate_desactivation = + Indexed_context.Make_map + (struct + let name = ["delegate_desactivation"] + end) + (Cycle_repr) + + module Delegated = + Make_data_set_storage + (Make_subcontext (Registered) (Indexed_context.Raw_context) + (struct + let name = ["delegated"] + end)) + (Make_index (Contract_repr.Index)) + + module Counter = + Indexed_context.Make_map + (struct + let name = ["counter"] + end) + (Encoding.Z) + + (* Consume gas for serialization and deserialization of expr in this + module *) + module Make_carbonated_map_expr (N : Storage_sigs.NAME) : + Storage_sigs.Non_iterable_indexed_carbonated_data_storage + with type key = Contract_repr.t + and type value = Script_repr.lazy_expr + and type t := Raw_context.t = struct + module I = + Indexed_context.Make_carbonated_map + (N) + (struct + type t = Script_repr.lazy_expr + + let encoding = Script_repr.lazy_expr_encoding + end) + + type context = I.context + + type key = I.key + + type value = I.value + + let mem = I.mem + + let remove_existing = I.remove_existing + + let remove = I.remove + + let consume_deserialize_gas ctxt value = + Raw_context.consume_gas ctxt (Script_repr.force_decode_cost value) + + let consume_serialize_gas ctxt value = + Raw_context.consume_gas ctxt (Script_repr.force_bytes_cost value) + + let get ctxt contract = + I.get ctxt contract >>=? fun (ctxt, value) -> + Lwt.return + (consume_deserialize_gas ctxt value >|? fun ctxt -> (ctxt, value)) + + let find ctxt contract = + I.find ctxt contract >>=? fun (ctxt, value_opt) -> + Lwt.return + @@ + match value_opt with + | None -> ok (ctxt, None) + | Some value -> + consume_deserialize_gas ctxt value >|? fun ctxt -> (ctxt, value_opt) + + let update ctxt contract value = + consume_serialize_gas ctxt value >>?= fun ctxt -> + I.update ctxt contract value + + let add_or_remove ctxt contract value_opt = + match value_opt with + | None -> I.add_or_remove ctxt contract None + | Some value -> + consume_serialize_gas ctxt value >>?= fun ctxt -> + I.add_or_remove ctxt contract value_opt + + let init ctxt contract value = + consume_serialize_gas ctxt value >>?= fun ctxt -> + I.init ctxt contract value + + let add ctxt contract value = + consume_serialize_gas ctxt value >>?= fun ctxt -> + I.add ctxt contract value + end + + module Code = Make_carbonated_map_expr (struct + let name = ["code"] + end) + + module Storage = Make_carbonated_map_expr (struct + let name = ["storage"] + end) + + module Paid_storage_space = + Indexed_context.Make_map + (struct + let name = ["paid_bytes"] + end) + (Encoding.Z) + + module Used_storage_space = + Indexed_context.Make_map + (struct + let name = ["used_bytes"] + end) + (Encoding.Z) + + module Roll_list_legacy = + Indexed_context.Make_map + (struct + let name = ["roll_list"] + end) + (Roll_repr_legacy) + + module Change_legacy = + Indexed_context.Make_map + (struct + let name = ["change"] + end) + (Tez_repr) + + module Frozen_deposits = + Indexed_context.Make_map + (struct + let name = ["frozen_deposits"] + end) + (Deposits) + + module Frozen_deposits_limit = + Indexed_context.Make_map + (struct + let name = ["frozen_deposits_limit"] + end) + (Tez_repr) +end + +module type NEXT = sig + type id + + val init : Raw_context.t -> Raw_context.t tzresult Lwt.t + + val incr : Raw_context.t -> (Raw_context.t * id) tzresult Lwt.t +end + +module Global_constants = struct + module Map = + Make_indexed_carbonated_data_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["global_constant"] + end)) + (Make_index (Script_expr_hash)) + (struct + type t = Script_repr.expr + + let encoding = Script_repr.expr_encoding + end) +end + +(** Big maps handling *) + +module Big_map = struct + type id = Lazy_storage_kind.Big_map.Id.t + + module Raw_context = + Make_subcontext (Registered) (Raw_context) + (struct + let name = ["big_maps"] + end) + + module Next : NEXT with type id := id = struct + module Storage = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["next"] + end) + (Lazy_storage_kind.Big_map.Id) + + let incr ctxt = + Storage.get ctxt >>=? fun i -> + Storage.update ctxt (Lazy_storage_kind.Big_map.Id.next i) >|=? fun ctxt -> + (ctxt, i) + + let init ctxt = Storage.init ctxt Lazy_storage_kind.Big_map.Id.init + end + + module Index = Lazy_storage_kind.Big_map.Id + + module Indexed_context = + Make_indexed_subcontext + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["index"] + end)) + (Make_index (Index)) + + let rpc_arg = Index.rpc_arg + + let fold = Indexed_context.fold_keys + + let list = Indexed_context.keys + + let remove ctxt n = Indexed_context.remove ctxt n + + let copy ctxt ~from ~to_ = Indexed_context.copy ctxt ~from ~to_ + + type key = Raw_context.t * Index.t + + module Total_bytes = + Indexed_context.Make_map + (struct + let name = ["total_bytes"] + end) + (Encoding.Z) + + module Key_type = + Indexed_context.Make_map + (struct + let name = ["key_type"] + end) + (struct + type t = Script_repr.expr + + let encoding = Script_repr.expr_encoding + end) + + module Value_type = + Indexed_context.Make_map + (struct + let name = ["value_type"] + end) + (struct + type t = Script_repr.expr + + let encoding = Script_repr.expr_encoding + end) + + module Contents : + Non_iterable_indexed_carbonated_data_storage_with_values + with type key = Script_expr_hash.t + and type value = Script_repr.expr + and type t := key = struct + module I = + Storage_functors.Make_indexed_carbonated_data_storage + (Make_subcontext (Registered) (Indexed_context.Raw_context) + (struct + let name = ["contents"] + end)) + (Make_index (Script_expr_hash)) + (struct + type t = Script_repr.expr + + let encoding = Script_repr.expr_encoding + end) + + type context = I.context + + type key = I.key + + type value = I.value + + let mem = I.mem + + let remove_existing = I.remove_existing + + let remove = I.remove + + let update = I.update + + let add_or_remove = I.add_or_remove + + let init = I.init + + let add = I.add + + let list_values = I.list_values + + let consume_deserialize_gas ctxt value = + Raw_context.consume_gas ctxt (Script_repr.deserialized_cost value) + + let get ctxt contract = + I.get ctxt contract >>=? fun (ctxt, value) -> + Lwt.return + (consume_deserialize_gas ctxt value >|? fun ctxt -> (ctxt, value)) + + let find ctxt contract = + I.find ctxt contract >>=? fun (ctxt, value_opt) -> + Lwt.return + @@ + match value_opt with + | None -> ok (ctxt, None) + | Some value -> + consume_deserialize_gas ctxt value >|? fun ctxt -> (ctxt, value_opt) + end +end + +module Sapling = struct + type id = Lazy_storage_kind.Sapling_state.Id.t + + module Raw_context = + Make_subcontext (Registered) (Raw_context) + (struct + let name = ["sapling"] + end) + + module Next = struct + module Storage = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["next"] + end) + (Lazy_storage_kind.Sapling_state.Id) + + let incr ctxt = + Storage.get ctxt >>=? fun i -> + Storage.update ctxt (Lazy_storage_kind.Sapling_state.Id.next i) + >|=? fun ctxt -> (ctxt, i) + + let init ctxt = Storage.init ctxt Lazy_storage_kind.Sapling_state.Id.init + end + + module Index = Lazy_storage_kind.Sapling_state.Id + + let rpc_arg = Index.rpc_arg + + module Indexed_context = + Make_indexed_subcontext + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["index"] + end)) + (Make_index (Index)) + + let remove ctxt n = Indexed_context.remove ctxt n + + let copy ctxt ~from ~to_ = Indexed_context.copy ctxt ~from ~to_ + + module Total_bytes = + Indexed_context.Make_map + (struct + let name = ["total_bytes"] + end) + (Encoding.Z) + + module Commitments_size = + Make_single_data_storage (Registered) (Indexed_context.Raw_context) + (struct + let name = ["commitments_size"] + end) + (Encoding.Int64) + + module Memo_size = + Make_single_data_storage (Registered) (Indexed_context.Raw_context) + (struct + let name = ["memo_size"] + end) + (Sapling_repr.Memo_size) + + module Commitments : + Non_iterable_indexed_carbonated_data_storage + with type t := Raw_context.t * id + and type key = int64 + and type value = Sapling.Hash.t = + Make_indexed_carbonated_data_storage + (Make_subcontext (Registered) (Indexed_context.Raw_context) + (struct + let name = ["commitments"] + end)) + (Make_index (struct + type t = int64 + + let rpc_arg = + let construct = Int64.to_string in + let destruct hash = + Int64.of_string_opt hash + |> Result.of_option ~error:"Cannot parse node position" + in + RPC_arg.make + ~descr:"The position of a node in a sapling commitment tree" + ~name:"sapling_node_position" + ~construct + ~destruct + () + + let encoding = + Data_encoding.def + "sapling_node_position" + ~title:"Sapling node position" + ~description: + "The position of a node in a sapling commitment tree" + Data_encoding.int64 + + let compare = Compare.Int64.compare + + let path_length = 1 + + let to_path c l = Int64.to_string c :: l + + let of_path = function [c] -> Int64.of_string_opt c | _ -> None + end)) + (Sapling.Hash) + + let commitments_init ctx id = + Indexed_context.Raw_context.remove (ctx, id) ["commitments"] + >|= fun (ctx, _id) -> ctx + + module Ciphertexts : + Non_iterable_indexed_carbonated_data_storage + with type t := Raw_context.t * id + and type key = int64 + and type value = Sapling.Ciphertext.t = + Make_indexed_carbonated_data_storage + (Make_subcontext (Registered) (Indexed_context.Raw_context) + (struct + let name = ["ciphertexts"] + end)) + (Make_index (struct + type t = int64 + + let rpc_arg = + let construct = Int64.to_string in + let destruct hash = + Int64.of_string_opt hash + |> Result.of_option ~error:"Cannot parse ciphertext position" + in + RPC_arg.make + ~descr:"The position of a sapling ciphertext" + ~name:"sapling_ciphertext_position" + ~construct + ~destruct + () + + let encoding = + Data_encoding.def + "sapling_ciphertext_position" + ~title:"Sapling ciphertext position" + ~description:"The position of a sapling ciphertext" + Data_encoding.int64 + + let compare = Compare.Int64.compare + + let path_length = 1 + + let to_path c l = Int64.to_string c :: l + + let of_path = function [c] -> Int64.of_string_opt c | _ -> None + end)) + (Sapling.Ciphertext) + + let ciphertexts_init ctx id = + Indexed_context.Raw_context.remove (ctx, id) ["commitments"] + >|= fun (ctx, _id) -> ctx + + module Nullifiers_size = + Make_single_data_storage (Registered) (Indexed_context.Raw_context) + (struct + let name = ["nullifiers_size"] + end) + (Encoding.Int64) + + (* For sequential access when building a diff *) + module Nullifiers_ordered : + Non_iterable_indexed_data_storage + with type t := Raw_context.t * id + and type key = int64 + and type value = Sapling.Nullifier.t = + Make_indexed_data_storage + (Make_subcontext (Registered) (Indexed_context.Raw_context) + (struct + let name = ["nullifiers_ordered"] + end)) + (Make_index (struct + type t = int64 + + let rpc_arg = + let construct = Int64.to_string in + let destruct hash = + Int64.of_string_opt hash + |> Result.of_option ~error:"Cannot parse nullifier position" + in + RPC_arg.make + ~descr:"A sapling nullifier position" + ~name:"sapling_nullifier_position" + ~construct + ~destruct + () + + let encoding = + Data_encoding.def + "sapling_nullifier_position" + ~title:"Sapling nullifier position" + ~description:"Sapling nullifier position" + Data_encoding.int64 + + let compare = Compare.Int64.compare + + let path_length = 1 + + let to_path c l = Int64.to_string c :: l + + let of_path = function [c] -> Int64.of_string_opt c | _ -> None + end)) + (Sapling.Nullifier) + + (* Check membership in O(1) for verify_update *) + module Nullifiers_hashed = + Make_carbonated_data_set_storage + (Make_subcontext (Registered) (Indexed_context.Raw_context) + (struct + let name = ["nullifiers_hashed"] + end)) + (Make_index (struct + type t = Sapling.Nullifier.t + + let encoding = Sapling.Nullifier.encoding + + let of_string hexstring = + Option.bind + (Hex.to_bytes (`Hex hexstring)) + (Data_encoding.Binary.of_bytes_opt encoding) + |> Result.of_option ~error:"Cannot parse sapling nullifier" + + let to_string nf = + let b = Data_encoding.Binary.to_bytes_exn encoding nf in + let (`Hex hexstring) = Hex.of_bytes b in + hexstring + + let rpc_arg = + RPC_arg.make + ~descr:"A sapling nullifier" + ~name:"sapling_nullifier" + ~construct:to_string + ~destruct:of_string + () + + let compare = Sapling.Nullifier.compare + + let path_length = 1 + + let to_path c l = to_string c :: l + + let of_path = function + | [c] -> Result.to_option (of_string c) + | _ -> None + end)) + + let nullifiers_init ctx id = + Nullifiers_size.add (ctx, id) Int64.zero >>= fun ctx -> + Indexed_context.Raw_context.remove (ctx, id) ["nullifiers_ordered"] + >>= fun (ctx, id) -> + Indexed_context.Raw_context.remove (ctx, id) ["nullifiers_hashed"] + >|= fun (ctx, _id) -> ctx + + module Roots : + Non_iterable_indexed_data_storage + with type t := Raw_context.t * id + and type key = int32 + and type value = Sapling.Hash.t = + Make_indexed_data_storage + (Make_subcontext (Registered) (Indexed_context.Raw_context) + (struct + let name = ["roots"] + end)) + (Make_index (struct + type t = int32 + + let rpc_arg = + let construct = Int32.to_string in + let destruct hash = + Int32.of_string_opt hash + |> Result.of_option ~error:"Cannot parse nullifier position" + in + RPC_arg.make + ~descr:"A sapling root" + ~name:"sapling_root" + ~construct + ~destruct + () + + let encoding = + Data_encoding.def + "sapling_root" + ~title:"Sapling root" + ~description:"Sapling root" + Data_encoding.int32 + + let compare = Compare.Int32.compare + + let path_length = 1 + + let to_path c l = Int32.to_string c :: l + + let of_path = function [c] -> Int32.of_string_opt c | _ -> None + end)) + (Sapling.Hash) + + module Roots_pos = + Make_single_data_storage (Registered) (Indexed_context.Raw_context) + (struct + let name = ["roots_pos"] + end) + (Encoding.Int32) + + module Roots_level = + Make_single_data_storage (Registered) (Indexed_context.Raw_context) + (struct + let name = ["roots_level"] + end) + (Raw_level_repr) +end + +module Public_key_hash = struct + open Signature + include Signature.Public_key_hash + module Path_Ed25519 = Path_encoding.Make_hex (Ed25519.Public_key_hash) + module Path_Secp256k1 = Path_encoding.Make_hex (Secp256k1.Public_key_hash) + module Path_P256 = Path_encoding.Make_hex (P256.Public_key_hash) + + let to_path (key : public_key_hash) l = + match key with + | Ed25519 h -> ( + match Path_Ed25519.to_path h l with + | [s] -> ["ed25519"; s] + | _ -> assert false) + | Secp256k1 h -> ( + match Path_Secp256k1.to_path h l with + | [s] -> ["secp256k1"; s] + | _ -> assert false) + | P256 h -> ( + match Path_P256.to_path h l with + | [s] -> ["p256"; s] + | _ -> assert false) + + let of_path : _ -> public_key_hash option = function + | "ed25519" :: rest -> ( + match Path_Ed25519.of_path rest with + | Some pkh -> Some (Ed25519 pkh) + | None -> None) + | "secp256k1" :: rest -> ( + match Path_Secp256k1.of_path rest with + | Some pkh -> Some (Secp256k1 pkh) + | None -> None) + | "p256" :: rest -> ( + match Path_P256.of_path rest with + | Some pkh -> Some (P256 pkh) + | None -> None) + | _ -> None + + let path_length = + let l1 = Path_Ed25519.path_length + and l2 = Path_Secp256k1.path_length + and l3 = Path_P256.path_length in + assert (match (l1, l2, l3) with (1, 1, 1) -> true | _ -> false) ; + 2 +end + +module Public_key_hash_index = Make_index (Public_key_hash) + +module Protocol_hash = struct + include Protocol_hash + include Path_encoding.Make_hex (Protocol_hash) +end + +module Delegates = + Make_data_set_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["delegates"] + end)) + (Public_key_hash_index) + +module Legacy_active_delegates_with_rolls = + Make_data_set_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["active_delegates_with_rolls"] + end)) + (Public_key_hash_index) + +module Legacy_delegates_with_frozen_balance_index = + Make_indexed_subcontext + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["delegates_with_frozen_balance"] + end)) + (Make_index (Cycle_repr.Index)) + +module Legacy_delegates_with_frozen_balance = + Make_data_set_storage + (Legacy_delegates_with_frozen_balance_index.Raw_context) + (Public_key_hash_index) + +(** Per cycle storage *) + +type slashed_level = {for_double_endorsing : bool; for_double_baking : bool} + +module Slashed_level = struct + type t = slashed_level + + let encoding = + let open Data_encoding in + conv + (fun {for_double_endorsing; for_double_baking} -> + (for_double_endorsing, for_double_baking)) + (fun (for_double_endorsing, for_double_baking) -> + {for_double_endorsing; for_double_baking}) + (obj2 (req "for_double_endorsing" bool) (req "for_double_baking" bool)) +end + +module Cycle = struct + module Indexed_context = + Make_indexed_subcontext + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["cycle"] + end)) + (Make_index (Cycle_repr.Index)) + + module Slashed_deposits = + Make_indexed_data_storage + (Make_subcontext (Registered) (Indexed_context.Raw_context) + (struct + let name = ["slashed_deposits"] + end)) + (Pair (Make_index (Raw_level_repr.Index)) (Public_key_hash_index)) + (Slashed_level) + + module Last_roll_legacy = + Make_indexed_data_storage + (Make_subcontext (Ghost) (Indexed_context.Raw_context) + (struct + let name = ["last_roll"] + end)) + (Int31_index) + (Roll_repr_legacy) + + module Roll_snapshot_legacy = + Indexed_context.Make_map + (struct + let name = ["roll_snapshot"] + end) + (Encoding.UInt16) + + module Selected_stake_distribution = + Indexed_context.Make_map + (struct + let name = ["selected_stake_distribution"] + end) + (struct + type t = (Signature.Public_key_hash.t * Tez_repr.t) list + + let encoding = + Data_encoding.( + Variable.list + (obj2 + (req "baker" Signature.Public_key_hash.encoding) + (req "active_stake" Tez_repr.encoding))) + end) + + module Total_active_stake = + Indexed_context.Make_map + (struct + let name = ["total_active_stake"] + end) + (Tez_repr) + + let public_key_with_ghost_hash_encoding = + Data_encoding.conv + fst + (fun x -> (x, Signature.Public_key.hash x)) + Signature.Public_key.encoding + + module Delegate_sampler_state = + Indexed_context.Make_map + (struct + let name = ["delegate_sampler_state"] + end) + (struct + type t = + (Signature.Public_key.t * Signature.Public_key_hash.t) Sampler.t + + let encoding = Sampler.encoding public_key_with_ghost_hash_encoding + end) + + type unrevealed_nonce = { + nonce_hash : Nonce_hash.t; + delegate : Signature.Public_key_hash.t; + } + + type nonce_status = + | Unrevealed of unrevealed_nonce + | Revealed of Seed_repr.nonce + + let nonce_status_encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"Unrevealed" + (tup2 Nonce_hash.encoding Signature.Public_key_hash.encoding) + (function + | Unrevealed {nonce_hash; delegate} -> Some (nonce_hash, delegate) + | _ -> None) + (fun (nonce_hash, delegate) -> Unrevealed {nonce_hash; delegate}); + case + (Tag 1) + ~title:"Revealed" + Seed_repr.nonce_encoding + (function Revealed nonce -> Some nonce | _ -> None) + (fun nonce -> Revealed nonce); + ] + + module Nonce = + Make_indexed_data_storage + (Make_subcontext (Registered) (Indexed_context.Raw_context) + (struct + let name = ["nonces"] + end)) + (Make_index (Raw_level_repr.Index)) + (struct + type t = nonce_status + + let encoding = nonce_status_encoding + end) + + let nonce_status_encoding_legacy = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"Unrevealed" + (tup4 + Nonce_hash.encoding + Signature.Public_key_hash.encoding + Tez_repr.encoding + Tez_repr.encoding) + (function + | Unrevealed _ -> + assert false (* only used in read only for migration *) + | _ -> None) + (fun (nonce_hash, delegate, _, _) -> + Unrevealed {nonce_hash; delegate}); + case + (Tag 1) + ~title:"Revealed" + Seed_repr.nonce_encoding + (function + | Revealed _ -> + assert false (* only used in read only for migration *) + | _ -> None) + (fun nonce -> Revealed nonce); + ] + + module Nonce_legacy = + Make_indexed_data_storage + (Make_subcontext (Ghost) (Indexed_context.Raw_context) + (struct + let name = ["nonces"] + end)) + (Make_index (Raw_level_repr.Index)) + (struct + type t = nonce_status + + let encoding = nonce_status_encoding_legacy + end) + + module Seed = + Indexed_context.Make_map + (struct + let name = ["random_seed"] + end) + (struct + type t = Seed_repr.seed + + let encoding = Seed_repr.seed_encoding + end) +end + +module Slashed_deposits = Cycle.Slashed_deposits + +module Stake = struct + module Staking_balance = + Make_indexed_data_snapshotable_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["staking_balance"] + end)) + (Int31_index) + (Public_key_hash_index) + (Tez_repr) + + module Active_delegate_with_one_roll = + Make_indexed_data_snapshotable_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["active_delegate_with_one_roll"] + end)) + (Int31_index) + (Public_key_hash_index) + (struct + type t = unit + + let encoding = Data_encoding.unit + end) + + module Selected_distribution_for_cycle = Cycle.Selected_stake_distribution + + module Last_snapshot = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["last_snapshot"] + end) + (Encoding.UInt16) +end + +module Total_active_stake = Cycle.Total_active_stake +module Delegate_sampler_state = Cycle.Delegate_sampler_state + +module Roll_legacy = struct + module Raw_context = + Make_subcontext (Ghost) (Raw_context) + (struct + let name = ["rolls"] + end) + + module Indexed_context = + Make_indexed_subcontext + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["index"] + end)) + (Make_index (Roll_repr_legacy.Index)) + + module Next = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["next"] + end) + (Roll_repr_legacy) + + module Limbo = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["limbo"] + end) + (Roll_repr_legacy) + + module Delegate_roll_list = + Wrap_indexed_data_storage + (Contract.Roll_list_legacy) + (struct + type t = Signature.Public_key_hash.t + + let wrap = Contract_repr.implicit_contract + + let unwrap = Contract_repr.is_implicit + end) + + module Successor = + Indexed_context.Make_map + (struct + let name = ["successor"] + end) + (Roll_repr_legacy) + + module Delegate_change = + Wrap_indexed_data_storage + (Contract.Change_legacy) + (struct + type t = Signature.Public_key_hash.t + + let wrap = Contract_repr.implicit_contract + + let unwrap = Contract_repr.is_implicit + end) + + module Snapshoted_owner_index : INDEX with type t = Cycle_repr.t * int = + struct + type t = Cycle_repr.t * int + + let path_length = Cycle_repr.Index.path_length + 1 + + let to_path (c, n) s = Cycle_repr.Index.to_path c (string_of_int n :: s) + + let of_path l = + match Misc.take Cycle_repr.Index.path_length l with + | None | Some (_, ([] | _ :: _ :: _)) -> None + | Some (l1, [l2]) -> ( + match (Cycle_repr.Index.of_path l1, int_of_string_opt l2) with + | (None, _) | (_, None) -> None + | (Some c, Some i) -> Some (c, i)) + + type 'a ipath = ('a * Cycle_repr.t) * int + + let left_args = + Storage_description.One + { + rpc_arg = Cycle_repr.rpc_arg; + encoding = Cycle_repr.encoding; + compare = Cycle_repr.compare; + } + + let right_args = + Storage_description.One + { + rpc_arg = RPC_arg.int; + encoding = Data_encoding.int31; + compare = Compare.Int.compare; + } + + let args = Storage_description.(Pair (left_args, right_args)) + end + + module Owner = + Make_indexed_data_snapshotable_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["owner"] + end)) + (Snapshoted_owner_index) + (Make_index (Roll_repr_legacy.Index)) + (Signature.Public_key) + + module Snapshot_for_cycle = Cycle.Roll_snapshot_legacy + module Last_for_snapshot = Cycle.Last_roll_legacy + + let clear = Indexed_context.clear +end + +(** Votes *) + +module Vote = struct + module Raw_context = + Make_subcontext (Registered) (Raw_context) + (struct + let name = ["votes"] + end) + + module Pred_period_kind = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["pred_period_kind"] + end) + (struct + type t = Voting_period_repr.kind + + let encoding = Voting_period_repr.kind_encoding + end) + + module Current_period = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["current_period"] + end) + (struct + type t = Voting_period_repr.t + + let encoding = Voting_period_repr.encoding + end) + + module Participation_ema = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["participation_ema"] + end) + (Encoding.Int32) + + module Current_proposal = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["current_proposal"] + end) + (Protocol_hash) + + module Listings_size = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["listings_size"] + end) + (Encoding.Int32) + + module Listings = + Make_indexed_data_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["listings"] + end)) + (Public_key_hash_index) + (Encoding.Int32) + + module Proposals = + Make_data_set_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["proposals"] + end)) + (Pair (Make_index (Protocol_hash)) (Public_key_hash_index)) + + module Proposals_count = + Make_indexed_data_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["proposals_count"] + end)) + (Public_key_hash_index) + (Encoding.UInt16) + + module Ballots = + Make_indexed_data_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["ballots"] + end)) + (Public_key_hash_index) + (struct + type t = Vote_repr.ballot + + let encoding = Vote_repr.ballot_encoding + end) +end + +module type FOR_CYCLE = sig + val init : + Raw_context.t -> + Cycle_repr.t -> + Seed_repr.seed -> + Raw_context.t tzresult Lwt.t + + val mem : Raw_context.t -> Cycle_repr.t -> bool Lwt.t + + val get : Raw_context.t -> Cycle_repr.t -> Seed_repr.seed tzresult Lwt.t + + val remove_existing : + Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t +end + +(** Seed *) + +module Seed = struct + type unrevealed_nonce = Cycle.unrevealed_nonce = { + nonce_hash : Nonce_hash.t; + delegate : Signature.Public_key_hash.t; + } + + type nonce_status = Cycle.nonce_status = + | Unrevealed of unrevealed_nonce + | Revealed of Seed_repr.nonce + + module Nonce : + Non_iterable_indexed_data_storage + with type key := Level_repr.t + and type value := nonce_status + and type t := Raw_context.t = struct + open Level_repr + + type context = Raw_context.t + + let mem ctxt (l : Level_repr.t) = Cycle.Nonce.mem (ctxt, l.cycle) l.level + + let get ctxt (l : Level_repr.t) = Cycle.Nonce.get (ctxt, l.cycle) l.level + + let find ctxt (l : Level_repr.t) = Cycle.Nonce.find (ctxt, l.cycle) l.level + + let update ctxt (l : Level_repr.t) v = + Cycle.Nonce.update (ctxt, l.cycle) l.level v + + let init ctxt (l : Level_repr.t) v = + Cycle.Nonce.init (ctxt, l.cycle) l.level v + + let add ctxt (l : Level_repr.t) v = + Cycle.Nonce.add (ctxt, l.cycle) l.level v + + let add_or_remove ctxt (l : Level_repr.t) v = + Cycle.Nonce.add_or_remove (ctxt, l.cycle) l.level v + + let remove_existing ctxt (l : Level_repr.t) = + Cycle.Nonce.remove_existing (ctxt, l.cycle) l.level + + let remove ctxt (l : Level_repr.t) = + Cycle.Nonce.remove (ctxt, l.cycle) l.level + end + + module Nonce_legacy = struct + open Level_repr + + type context = Raw_context.t + + let mem ctxt (l : Level_repr.t) = + Cycle.Nonce_legacy.mem (ctxt, l.cycle) l.level + + let get ctxt (l : Level_repr.t) = + Cycle.Nonce_legacy.get (ctxt, l.cycle) l.level + + let find ctxt (l : Level_repr.t) = + Cycle.Nonce_legacy.find (ctxt, l.cycle) l.level + + let update ctxt (l : Level_repr.t) v = + Cycle.Nonce_legacy.update (ctxt, l.cycle) l.level v + + let init ctxt (l : Level_repr.t) v = + Cycle.Nonce_legacy.init (ctxt, l.cycle) l.level v + + let add ctxt (l : Level_repr.t) v = + Cycle.Nonce_legacy.add (ctxt, l.cycle) l.level v + + let add_or_remove ctxt (l : Level_repr.t) v = + Cycle.Nonce_legacy.add_or_remove (ctxt, l.cycle) l.level v + + let remove_existing ctxt (l : Level_repr.t) = + Cycle.Nonce_legacy.remove_existing (ctxt, l.cycle) l.level + + let remove ctxt (l : Level_repr.t) = + Cycle.Nonce_legacy.remove (ctxt, l.cycle) l.level + end + + module For_cycle : FOR_CYCLE = Cycle.Seed +end + +(** Commitments *) + +module Commitments = + Make_indexed_data_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["commitments"] + end)) + (Make_index (Blinded_public_key_hash.Index)) + (Tez_repr) + +(** Ramp up rewards... *) + +module Ramp_up = struct + type reward = { + baking_reward_fixed_portion : Tez_repr.t; + baking_reward_bonus_per_slot : Tez_repr.t; + endorsing_reward_per_slot : Tez_repr.t; + } + + module Rewards = + Make_indexed_data_storage + (Make_subcontext (Registered) (Raw_context) + (struct + let name = ["ramp_up"; "rewards"] + end)) + (Make_index (Cycle_repr.Index)) + (struct + type t = reward + + let encoding = + Data_encoding.( + conv + (fun { + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + } -> + ( baking_reward_fixed_portion, + baking_reward_bonus_per_slot, + endorsing_reward_per_slot )) + (fun ( baking_reward_fixed_portion, + baking_reward_bonus_per_slot, + endorsing_reward_per_slot ) -> + { + baking_reward_fixed_portion; + baking_reward_bonus_per_slot; + endorsing_reward_per_slot; + }) + (obj3 + (req "baking_reward_fixed_portion" Tez_repr.encoding) + (req "baking_reward_bonus_per_slot" Tez_repr.encoding) + (req "endorsing_reward_per_slot" Tez_repr.encoding))) + end) +end + +module Pending_migration = struct + module Balance_updates = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["pending_migration_balance_updates"] + end) + (struct + type t = Receipt_repr.balance_updates + + let encoding = Receipt_repr.balance_updates_encoding + end) + + module Operation_results = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["pending_migration_operation_results"] + end) + (struct + type t = Migration_repr.origination_result list + + let encoding = Migration_repr.origination_result_list_encoding + end) + + let remove ctxt = + let balance_updates ctxt = + Balance_updates.find ctxt >>=? function + | Some balance_updates -> + Balance_updates.remove ctxt >>= fun ctxt -> + (* When applying balance updates in a migration, we must attach receipts. + The balance updates returned from here will be applied in the first + block of the new protocol. *) + return (ctxt, balance_updates) + | None -> return (ctxt, []) + in + let operation_results ctxt = + Operation_results.find ctxt >>=? function + | Some operation_results -> + Operation_results.remove ctxt >>= fun ctxt -> + return (ctxt, operation_results) + | None -> return (ctxt, []) + in + balance_updates ctxt >>=? fun (ctxt, balance_updates) -> + operation_results ctxt >>=? fun (ctxt, operation_results) -> + return (ctxt, balance_updates, operation_results) +end + +module Liquidity_baking = struct + module Escape_ema = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["liquidity_baking_escape_ema"] + end) + (Encoding.Int32) + + module Cpmm_address = + Make_single_data_storage (Registered) (Raw_context) + (struct + let name = ["liquidity_baking_cpmm_address"] + end) + (Contract_repr) +end + +module Ticket_balance = struct + module Name = struct + let name = ["ticket_balance"] + end + + module Sub_context = Make_subcontext (Registered) (Raw_context) (Name) + module Index = Make_index (Script_expr_hash) + module Table = + Make_indexed_carbonated_data_storage (Sub_context) (Index) (Encoding.Z) +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/storage.mli b/src/proto_012_PsiThaCa/lib_protocol/storage.mli new file mode 100644 index 000000000000..2aa47e9dc6ae --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/storage.mli @@ -0,0 +1,693 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Tezos Protocol Implementation - Typed storage + + This module hides the hierarchical (key x value) database under + pre-allocated typed accessors for all persistent entities of the + tezos context. + + This interface enforces no invariant on the contents of the + database. Its goal is to centralize all accessors in order to have + a complete view over the database contents and avoid key + collisions. *) + +open Storage_sigs + +module type Simple_single_data_storage = sig + type value + + val get : Raw_context.t -> value tzresult Lwt.t + + val update : Raw_context.t -> value -> Raw_context.t tzresult Lwt.t + + val init : Raw_context.t -> value -> Raw_context.t tzresult Lwt.t +end + +module Legacy_block_priority : Simple_single_data_storage with type value = int + +module Block_round : Simple_single_data_storage with type value = Round_repr.t + +module Roll_legacy : sig + (** Storage from this submodule must only be accessed through the + module `Roll_legacy`. *) + + module Owner : + Indexed_data_snapshotable_storage + with type key = Roll_repr_legacy.t + and type snapshot = Cycle_repr.t * int + and type value = Signature.Public_key.t + and type t := Raw_context.t + + val clear : Raw_context.t -> Raw_context.t Lwt.t + + (** The next roll to be allocated. *) + module Next : + Single_data_storage + with type value = Roll_repr_legacy.t + and type t := Raw_context.t + + (** Rolls linked lists represent both account owned and free rolls. + All rolls belongs either to the limbo list or to an owned list. *) + + (** Head of the linked list of rolls in limbo *) + module Limbo : + Single_data_storage + with type value = Roll_repr_legacy.t + and type t := Raw_context.t + + (** Rolls associated to contracts, a linked list per contract *) + module Delegate_roll_list : + Indexed_data_storage + with type key = Signature.Public_key_hash.t + and type value = Roll_repr_legacy.t + and type t := Raw_context.t + + (** Use this to iter on a linked list of rolls *) + module Successor : + Indexed_data_storage + with type key = Roll_repr_legacy.t + and type value = Roll_repr_legacy.t + and type t := Raw_context.t + + (** The tez of a contract that are not assigned to rolls *) + module Delegate_change : + Indexed_data_storage + with type key = Signature.Public_key_hash.t + and type value = Tez_repr.t + and type t := Raw_context.t + + (** Index of the randomly selected roll snapshot of a given cycle. *) + module Snapshot_for_cycle : + Indexed_data_storage + with type key = Cycle_repr.t + and type value = int + and type t := Raw_context.t + + (** Last roll in the snapshoted roll allocation of a given cycle. *) + module Last_for_snapshot : + Indexed_data_storage + with type key = int + and type value = Roll_repr_legacy.t + and type t = Raw_context.t * Cycle_repr.t +end + +type deposits = {initial_amount : Tez_repr.t; current_amount : Tez_repr.t} + +type missed_endorsements_info = {remaining_slots : int; missed_levels : int} + +module Contract : sig + (** Storage from this submodule must only be accessed through the + module `Contract`. *) + + module Global_counter : Simple_single_data_storage with type value = Z.t + + (** The domain of alive contracts *) + val fold : + Raw_context.t -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(Contract_repr.t -> 'a -> 'a Lwt.t) -> + 'a Lwt.t + + val list : Raw_context.t -> Contract_repr.t list Lwt.t + + (** The tez possessed by a contract and that can be used. A contract + may also possess tez in frozen deposits. Empty balances (of zero + tez) are only allowed for originated contracts, not for implicit + ones. *) + module Balance : + Indexed_data_storage + with type key = Contract_repr.t + and type value = Tez_repr.t + and type t := Raw_context.t + + (** If the value is not set, the delegate didn't miss any endorsing + opportunity. If it is set, this value is a record of type + [missed_endorsements_info], where: + - [remaining_slots] is the difference between the maximum number of + slots that can be missed and the number of missed slots; + therefore, when the number is positive, it represents the number + of slots that a delegate can still miss before forfeiting its + endorsing rewards for the current cycle; when the number is zero + it means rewards are not lost, but no further slots can be + missed anymore; + - [missed_levels] represents the number of missed levels (for + endorsing). *) + module Missed_endorsements : + Indexed_data_storage + with type key = Contract_repr.t + and type value = missed_endorsements_info + and type t := Raw_context.t + + (** Frozen balance, see 'delegate_storage.mli' for more explanation. + Always update `Delegates_with_frozen_balance` accordingly. + + Deprecated only used for migration + *) + module Legacy_frozen_deposits : + Indexed_data_storage + with type key = Cycle_repr.t + and type value = Tez_repr.t + and type t = Raw_context.t * Contract_repr.t + + (** Deprecated only used for migration *) + module Legacy_frozen_fees : + Indexed_data_storage + with type key = Cycle_repr.t + and type value = Tez_repr.t + and type t = Raw_context.t * Contract_repr.t + + (** Deprecated only used for migration *) + module Legacy_frozen_rewards : + Indexed_data_storage + with type key = Cycle_repr.t + and type value = Tez_repr.t + and type t = Raw_context.t * Contract_repr.t + + (** The manager of a contract *) + module Manager : + Indexed_data_storage + with type key = Contract_repr.t + and type value = Manager_repr.t + and type t := Raw_context.t + + (** The delegate of a contract, if any. *) + module Delegate : + Indexed_data_storage + with type key = Contract_repr.t + and type value = Signature.Public_key_hash.t + and type t := Raw_context.t + + (** All contracts (implicit and originated) that are delegated, if any *) + module Delegated : + Data_set_storage + with type elt = Contract_repr.t + and type t = Raw_context.t * Contract_repr.t + + (** The part of a delegate balance that can't be used. The total + balance is frozen_deposits.current_amount + balance. It also stores + the initial frozen balance in frozen_deposits.initial_amount. We + have current_amount <= initial_amount and current_amount < + initial_amount iff the delegate was slashed. *) + module Frozen_deposits : + Indexed_data_storage + with type key = Contract_repr.t + and type value = deposits + and type t := Raw_context.t + + (** If there is a value, the frozen balance for the contract won't + exceed it (starting in preserved_cycles + 1). *) + module Frozen_deposits_limit : + Indexed_data_storage + with type key = Contract_repr.t + and type value = Tez_repr.t + and type t := Raw_context.t + + module Inactive_delegate : + Data_set_storage with type elt = Contract_repr.t and type t = Raw_context.t + + (** The last cycle where the delegate is considered active; that is, + at the next cycle it will be considered inactive. *) + module Delegate_desactivation : + Indexed_data_storage + with type key = Contract_repr.t + and type value = Cycle_repr.t + and type t := Raw_context.t + + module Counter : + Indexed_data_storage + with type key = Contract_repr.t + and type value = Z.t + and type t := Raw_context.t + + module Code : + Non_iterable_indexed_carbonated_data_storage + with type key = Contract_repr.t + and type value = Script_repr.lazy_expr + and type t := Raw_context.t + + module Storage : + Non_iterable_indexed_carbonated_data_storage + with type key = Contract_repr.t + and type value = Script_repr.lazy_expr + and type t := Raw_context.t + + (** Current storage space in bytes. + Includes code, global storage and big map elements. *) + module Used_storage_space : + Indexed_data_storage + with type key = Contract_repr.t + and type value = Z.t + and type t := Raw_context.t + + (** Maximal space available without needing to burn new fees. *) + module Paid_storage_space : + Indexed_data_storage + with type key = Contract_repr.t + and type value = Z.t + and type t := Raw_context.t +end + +module Big_map : sig + type id = Lazy_storage_kind.Big_map.Id.t + + module Next : sig + val incr : Raw_context.t -> (Raw_context.t * id) tzresult Lwt.t + + val init : Raw_context.t -> Raw_context.t tzresult Lwt.t + end + + (** The domain of alive big maps *) + val fold : + Raw_context.t -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(id -> 'a -> 'a Lwt.t) -> + 'a Lwt.t + + val list : Raw_context.t -> id list Lwt.t + + val remove : Raw_context.t -> id -> Raw_context.t Lwt.t + + val copy : Raw_context.t -> from:id -> to_:id -> Raw_context.t tzresult Lwt.t + + type key = Raw_context.t * id + + val rpc_arg : id RPC_arg.t + + module Contents : sig + include + Non_iterable_indexed_carbonated_data_storage + with type key = Script_expr_hash.t + and type value = Script_repr.expr + and type t := key + + (** HACK *) + val list_values : + ?offset:int -> + ?length:int -> + Raw_context.t * id -> + (Raw_context.t * Script_repr.expr list) tzresult Lwt.t + end + + module Total_bytes : + Indexed_data_storage + with type key = id + and type value = Z.t + and type t := Raw_context.t + + module Key_type : + Indexed_data_storage + with type key = id + and type value = Script_repr.expr + and type t := Raw_context.t + + module Value_type : + Indexed_data_storage + with type key = id + and type value = Script_repr.expr + and type t := Raw_context.t +end + +module Sapling : sig + type id = Lazy_storage_kind.Sapling_state.Id.t + + val rpc_arg : id RPC_arg.t + + module Next : sig + val incr : Raw_context.t -> (Raw_context.t * id) tzresult Lwt.t + + val init : Raw_context.t -> Raw_context.t tzresult Lwt.t + end + + val copy : Raw_context.t -> from:id -> to_:id -> Raw_context.t tzresult Lwt.t + + val remove : Raw_context.t -> id -> Raw_context.t Lwt.t + + module Total_bytes : + Indexed_data_storage + with type key = id + and type value = Z.t + and type t := Raw_context.t + + (* Used by both Commitments and Ciphertexts *) + module Commitments_size : + Single_data_storage with type t := Raw_context.t * id and type value = int64 + + module Memo_size : + Single_data_storage with type t := Raw_context.t * id and type value = int + + module Commitments : + Non_iterable_indexed_carbonated_data_storage + with type t := Raw_context.t * id + and type key = int64 + and type value = Sapling.Hash.t + + val commitments_init : Raw_context.t -> id -> Raw_context.t Lwt.t + + module Ciphertexts : + Non_iterable_indexed_carbonated_data_storage + with type t := Raw_context.t * id + and type key = int64 + and type value = Sapling.Ciphertext.t + + val ciphertexts_init : Raw_context.t -> id -> Raw_context.t Lwt.t + + module Nullifiers_size : + Single_data_storage with type t := Raw_context.t * id and type value = int64 + + module Nullifiers_ordered : + Non_iterable_indexed_data_storage + with type t := Raw_context.t * id + and type key = int64 + and type value = Sapling.Nullifier.t + + module Nullifiers_hashed : + Carbonated_data_set_storage + with type t := Raw_context.t * id + and type elt = Sapling.Nullifier.t + + val nullifiers_init : Raw_context.t -> id -> Raw_context.t Lwt.t + + module Roots : + Non_iterable_indexed_data_storage + with type t := Raw_context.t * id + and type key = int32 + and type value = Sapling.Hash.t + + module Roots_pos : + Single_data_storage with type t := Raw_context.t * id and type value = int32 + + module Roots_level : + Single_data_storage + with type t := Raw_context.t * id + and type value = Raw_level_repr.t +end + +(** Set of all registered delegates. *) +module Delegates : + Data_set_storage + with type t := Raw_context.t + and type elt = Signature.Public_key_hash.t + +type slashed_level = {for_double_endorsing : bool; for_double_baking : bool} + +(** Set used to avoid slashing multiple times the same event *) +module Slashed_deposits : + Indexed_data_storage + with type t := Raw_context.t * Cycle_repr.t + and type key = Raw_level_repr.t * Signature.Public_key_hash.t + and type value = slashed_level + +(** Set of all active delegates with rolls. *) +module Legacy_active_delegates_with_rolls : + Data_set_storage + with type t := Raw_context.t + and type elt = Signature.Public_key_hash.t + +module Stake : sig + (** The map of all the staking balances of all delegates, including + those with less than one roll. It might be large *) + module Staking_balance : + Indexed_data_snapshotable_storage + with type key = Signature.Public_key_hash.t + and type value = Tez_repr.t + and type snapshot = int + and type t := Raw_context.t + + (** This is a set, encoded in a map with value unit. This should be + fairly small compared to staking balance *) + module Active_delegate_with_one_roll : + Indexed_data_snapshotable_storage + with type key = Signature.Public_key_hash.t + and type value = unit + and type snapshot = int + and type t := Raw_context.t + + module Last_snapshot : + Single_data_storage with type value = int and type t := Raw_context.t + + (** List of active stake *) + module Selected_distribution_for_cycle : + Indexed_data_storage + with type key = Cycle_repr.t + and type value = (Signature.Public_key_hash.t * Tez_repr.t) list + and type t := Raw_context.t +end + +(** Sum of the active stakes of all the delegates with rolls *) +module Total_active_stake : + Indexed_data_storage + with type key = Cycle_repr.t + and type value = Tez_repr.t + and type t := Raw_context.t + +(** State of the sampler used to select delegates. Managed synchronously + with [Stake.Selected_distribution_for_cycle]. *) +module Delegate_sampler_state : + Indexed_data_storage + with type key = Cycle_repr.t + and type value = + (Signature.Public_key.t * Signature.Public_key_hash.t) Sampler.t + and type t := Raw_context.t + +(** Set of all the delegates with frozen rewards/deposits/fees for a given cycle. + Deprecated: This is now only used for stitching while migrating from an + emmy protocol. This is to be removed in the next version. + + This table must be cleaned after migration. *) +module Legacy_delegates_with_frozen_balance : + Data_set_storage + with type t = Raw_context.t * Cycle_repr.t + and type elt = Signature.Public_key_hash.t + +(** Votes *) + +module Vote : sig + module Pred_period_kind : + Single_data_storage + with type value = Voting_period_repr.kind + and type t := Raw_context.t + + module Current_period : + Single_data_storage + with type value = Voting_period_repr.t + and type t := Raw_context.t + + (** Participation exponential moving average, in centile of percentage *) + module Participation_ema : + Single_data_storage with type value = int32 and type t := Raw_context.t + + module Current_proposal : + Single_data_storage + with type value = Protocol_hash.t + and type t := Raw_context.t + + (** Sum of all rolls of all delegates. *) + module Listings_size : + Single_data_storage with type value = int32 and type t := Raw_context.t + + (** Contains all delegates with their assigned number of rolls. *) + module Listings : + Indexed_data_storage + with type key = Signature.Public_key_hash.t + and type value = int32 + and type t := Raw_context.t + + (** Set of protocol proposal with corresponding proposer delegate *) + module Proposals : + Data_set_storage + with type elt = Protocol_hash.t * Signature.Public_key_hash.t + and type t := Raw_context.t + + (** Keeps for each delegate the number of proposed protocols *) + module Proposals_count : + Indexed_data_storage + with type key = Signature.Public_key_hash.t + and type value = int + and type t := Raw_context.t + + (** Contains for each delegate its ballot *) + module Ballots : + Indexed_data_storage + with type key = Signature.Public_key_hash.t + and type value = Vote_repr.ballot + and type t := Raw_context.t +end + +module type FOR_CYCLE = sig + val init : + Raw_context.t -> + Cycle_repr.t -> + Seed_repr.seed -> + Raw_context.t tzresult Lwt.t + + val mem : Raw_context.t -> Cycle_repr.t -> bool Lwt.t + + val get : Raw_context.t -> Cycle_repr.t -> Seed_repr.seed tzresult Lwt.t + + val remove_existing : + Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t +end + +(** Seed *) + +module Seed : sig + (** Storage from this submodule must only be accessed through the + module `Seed`. *) + + type unrevealed_nonce = { + nonce_hash : Nonce_hash.t; + delegate : Signature.Public_key_hash.t; + } + + type nonce_status = + | Unrevealed of unrevealed_nonce + | Revealed of Seed_repr.nonce + + module Nonce : + Non_iterable_indexed_data_storage + with type key := Level_repr.t + and type value := nonce_status + and type t := Raw_context.t + + module Nonce_legacy : + Non_iterable_indexed_data_storage + with type key := Level_repr.t + and type value := nonce_status + and type t := Raw_context.t + + module For_cycle : FOR_CYCLE +end + +(** Commitments *) + +module Commitments : + Indexed_data_storage + with type key = Blinded_public_key_hash.t + and type value = Tez_repr.t + and type t := Raw_context.t + +(** Ramp up rewards *) +module Ramp_up : sig + type reward = { + baking_reward_fixed_portion : Tez_repr.t; + baking_reward_bonus_per_slot : Tez_repr.t; + endorsing_reward_per_slot : Tez_repr.t; + } + + module Rewards : + Indexed_data_storage + with type key = Cycle_repr.t + and type value := reward + and type t := Raw_context.t +end + +module Pending_migration : sig + module Balance_updates : + Single_data_storage + with type value = Receipt_repr.balance_updates + and type t := Raw_context.t + + module Operation_results : + Single_data_storage + with type value = Migration_repr.origination_result list + and type t := Raw_context.t + + val remove : + Raw_context.t -> + (Raw_context.t + * Receipt_repr.balance_updates + * Migration_repr.origination_result list) + tzresult + Lwt.t +end + +module Liquidity_baking : sig + (** Exponential moving average (ema) of flags set in protocol_data.contents. + If at any block it's above the threshold set in constants, + liquidity baking permanently shuts off. **) + module Escape_ema : + Single_data_storage with type t := Raw_context.t and type value = Int32.t + + (** Constant product market maker contract that receives liquidity baking subsidy. **) + module Cpmm_address : + Single_data_storage + with type t := Raw_context.t + and type value = Contract_repr.t +end + +(** A map of [Script_repr.expr] values, indexed by their hash ([Script_expr_hash.t]). + Values from this map can be incorporated by any contract via the primitive + [Michelson_v1_primitives.H_constant]. *) +module Global_constants : sig + module Map : + Non_iterable_indexed_carbonated_data_storage + with type t := Raw_context.t + and type key = Script_expr_hash.t + and type value = Script_repr.expr +end + +(** This module exposes a balance table for tracking ticket ownership. + The table is a mapping from keys to values where the keys consist of a + hashed representation of: + - A ticketer, i.e. the creator of the ticket + - The content of a the ticket + - The contract that owns some amount of the ticket + The values of the table are the amounts owned by each key. + *) +module Ticket_balance : sig + module Table : + Non_iterable_indexed_carbonated_data_storage + with type t := Raw_context.t + and type key = Script_expr_hash.t + and type value = Z.t +end + +(** Tenderbake *) + +module Tenderbake : sig + module First_level : + Single_data_storage + with type t := Raw_context.t + and type value = Raw_level_repr.t + + (** [Endorsement_branch] stores a single value composed of the + grandparent hash and the predecessor's payload (computed with + the grandparent hash) used to verify the validity of + endorsements. *) + module Endorsement_branch : + Single_data_storage + with type value = Block_hash.t * Block_payload_hash.t + and type t := Raw_context.t + + (** [Grand_parent_branch] stores a single value composed of the + great-grand parent hash and the grand parent's payload *) + module Grand_parent_branch : + Single_data_storage + with type value = Block_hash.t * Block_payload_hash.t + and type t := Raw_context.t +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/storage_costs.ml b/src/proto_012_PsiThaCa/lib_protocol/storage_costs.ml new file mode 100644 index 000000000000..dae9e12456fe --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/storage_costs.ml @@ -0,0 +1,43 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* The model for read accesses is the following: + + cost(path_length, read_bytes) = 200_000 + 5000 * path_length + 2 * read_bytes +*) +let read_access ~path_length ~read_bytes = + let open Saturation_repr in + let base_cost = safe_int (200_000 + (5000 * path_length)) in + Gas_limit_repr.atomic_step_cost + (add base_cost (mul (safe_int 2) (safe_int read_bytes))) + +(* The model for write accesses is the following: + + cost(written_bytes) = 200_000 + 4 * written_bytes +*) +let write_access ~written_bytes = + let open Saturation_repr in + Gas_limit_repr.atomic_step_cost + (add (safe_int 200_000) (mul (safe_int 4) (safe_int written_bytes))) diff --git a/src/proto_012_PsiThaCa/lib_protocol/storage_costs.mli b/src/proto_012_PsiThaCa/lib_protocol/storage_costs.mli new file mode 100644 index 000000000000..0b91ce04eaae --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/storage_costs.mli @@ -0,0 +1,30 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Cost of reading [read_bytes] at a key of length [path_length]. *) +val read_access : path_length:int -> read_bytes:int -> Gas_limit_repr.cost + +(** Cost of performing a single write access, writing [written_bytes] bytes. *) +val write_access : written_bytes:int -> Gas_limit_repr.cost diff --git a/src/proto_012_PsiThaCa/lib_protocol/storage_description.ml b/src/proto_012_PsiThaCa/lib_protocol/storage_description.ml new file mode 100644 index 000000000000..7bac72c5a969 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/storage_description.ml @@ -0,0 +1,388 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module StringMap = Map.Make (String) + +type 'key t = 'key desc_with_path + +(** [desc_with_path] describes a position in the storage. It's composed + [rev_path] which is the reverse path up to the position, and [dir] the + position's [description]. [rev_path] is only useful in case of an error to + print a descriptive message. [List.rev rev_path] is a storage's path that + contains no conflict and allows the registration of a [dir]'s storage. + NB: [rev_path] indicates the position in the tree, so once the node is + added, it won't change; whereas [dir] is mutable because when more subtrees + are added this may require updating it. *) +and 'key desc_with_path = { + rev_path : string list; + mutable dir : 'key description; +} + +and 'key description = + | Empty : 'key description + | Value : { + get : 'key -> 'a option tzresult Lwt.t; + encoding : 'a Data_encoding.t; + } + -> 'key description + | NamedDir : 'key t StringMap.t -> 'key description + | IndexedDir : { + arg : 'a RPC_arg.t; + arg_encoding : 'a Data_encoding.t; + list : 'key -> 'a list tzresult Lwt.t; + subdir : ('key * 'a) t; + } + -> 'key description + +let[@coq_struct "function_parameter"] rec pp : + type a. Format.formatter -> a t -> unit = + fun ppf {dir; _} -> + match dir with + | Empty -> Format.fprintf ppf "Empty" + | Value _e -> Format.fprintf ppf "Value" + | NamedDir map -> + Format.fprintf + ppf + "@[%a@]" + (Format.pp_print_list pp_item) + (StringMap.bindings map) + | IndexedDir {arg; subdir; _} -> + let name = Format.asprintf "<%s>" (RPC_arg.descr arg).name in + pp_item ppf (name, subdir) + +and[@coq_mutual_as_notation] pp_item : + type a. Format.formatter -> string * a t -> unit = + fun ppf (name, desc) -> Format.fprintf ppf "@[%s@ %a@]" name pp desc + +let pp_rev_path ppf path = + Format.fprintf + ppf + "[%a]" + Format.( + pp_print_list + ~pp_sep:(fun ppf () -> pp_print_string ppf " / ") + pp_print_string) + (List.rev path) + +let rec register_named_subcontext : type r. r t -> string list -> r t = + fun desc names -> + match (desc.dir, names) with + | (_, []) -> desc + | (Value _, _) | (IndexedDir _, _) -> + Format.kasprintf + invalid_arg + "Could not register a named subcontext at %a because of an existing %a." + pp_rev_path + desc.rev_path + pp + desc + | (Empty, name :: names) -> + let subdir = {rev_path = name :: desc.rev_path; dir = Empty} in + desc.dir <- NamedDir (StringMap.singleton name subdir) ; + register_named_subcontext subdir names + | (NamedDir map, name :: names) -> + let subdir = + match StringMap.find name map with + | Some subdir -> subdir + | None -> + let subdir = {rev_path = name :: desc.rev_path; dir = Empty} in + desc.dir <- NamedDir (StringMap.add name subdir map) ; + subdir + in + register_named_subcontext subdir names + +type (_, _, _) args = + | One : { + rpc_arg : 'a RPC_arg.t; + encoding : 'a Data_encoding.t; + compare : 'a -> 'a -> int; + } + -> ('key, 'a, 'key * 'a) args + | Pair : + ('key, 'a, 'inter_key) args * ('inter_key, 'b, 'sub_key) args + -> ('key, 'a * 'b, 'sub_key) args + +let rec unpack : type a b c. (a, b, c) args -> c -> a * b = function + | One _ -> fun x -> x + | Pair (l, r) -> + let unpack_l = unpack l in + let unpack_r = unpack r in + fun x -> + let (c, d) = unpack_r x in + let (b, a) = unpack_l c in + (b, (a, d)) + [@@coq_axiom_with_reason "gadt"] + +let rec pack : type a b c. (a, b, c) args -> a -> b -> c = function + | One _ -> fun b a -> (b, a) + | Pair (l, r) -> + let pack_l = pack l in + let pack_r = pack r in + fun b (a, d) -> + let c = pack_l b a in + pack_r c d + [@@coq_axiom_with_reason "gadt"] + +let rec compare : type a b c. (a, b, c) args -> b -> b -> int = function + | One {compare; _} -> compare + | Pair (l, r) -> ( + let compare_l = compare l in + let compare_r = compare r in + fun (a1, b1) (a2, b2) -> + match compare_l a1 a2 with 0 -> compare_r b1 b2 | x -> x) + [@@coq_axiom_with_reason "gadt"] + +let destutter equal l = + match l with + | [] -> [] + | (i, _) :: l -> + let rec loop acc i = function + | [] -> acc + | (j, _) :: l -> if equal i j then loop acc i l else loop (j :: acc) j l + in + loop [i] i l + +let rec register_indexed_subcontext : + type r a b. + r t -> list:(r -> a list tzresult Lwt.t) -> (r, a, b) args -> b t = + fun desc ~list path -> + match path with + | Pair (left, right) -> + let compare_left = compare left in + let equal_left x y = Compare.Int.(compare_left x y = 0) in + let list_left r = list r >|=? fun l -> destutter equal_left l in + let list_right r = + let (a, k) = unpack left r in + list a >|=? fun l -> + List.map snd (List.filter (fun (x, _) -> equal_left x k) l) + in + register_indexed_subcontext + (register_indexed_subcontext desc ~list:list_left left) + ~list:list_right + right + | One {rpc_arg = arg; encoding = arg_encoding; _} -> ( + match desc.dir with + | Value _ | NamedDir _ -> + Format.kasprintf + invalid_arg + "Could not register an indexed subcontext at %a because of an \ + existing %a." + pp_rev_path + desc.rev_path + pp + desc + | Empty -> + let subdir = + { + rev_path = + Format.sprintf "(Maybe of %s)" RPC_arg.(descr arg).name + :: desc.rev_path; + dir = Empty; + } + in + desc.dir <- IndexedDir {arg; arg_encoding; list; subdir} ; + subdir + | IndexedDir {arg = inner_arg; subdir; _} -> ( + match RPC_arg.eq arg inner_arg with + | None -> + Format.kasprintf + invalid_arg + "An indexed subcontext at %a already exists but has a \ + different argument: `%s` <> `%s`." + pp_rev_path + desc.rev_path + (RPC_arg.descr arg).name + (RPC_arg.descr inner_arg).name + | Some RPC_arg.Eq -> subdir)) + [@@coq_axiom_with_reason "gadt"] + +let register_value : + type a b. + a t -> get:(a -> b option tzresult Lwt.t) -> b Data_encoding.t -> unit = + fun desc ~get encoding -> + match desc.dir with + | Empty -> desc.dir <- Value {get; encoding} + | _ -> + Format.kasprintf + invalid_arg + "Could not register a value at %a because of an existing %a." + pp_rev_path + desc.rev_path + pp + desc + +let create () = {rev_path = []; dir = Empty} + +module type INDEX = sig + type t + + include Path_encoding.S with type t := t + + val rpc_arg : t RPC_arg.t + + val encoding : t Data_encoding.t + + val compare : t -> t -> int +end + +type _ handler = + | Handler : { + encoding : 'a Data_encoding.t; + get : 'key -> int -> 'a tzresult Lwt.t; + } + -> 'key handler + +type _ opt_handler = + | Opt_handler : { + encoding : 'a Data_encoding.t; + get : 'key -> int -> 'a option tzresult Lwt.t; + } + -> 'key opt_handler + +let rec combine_object = function + | [] -> + Handler {encoding = Data_encoding.unit; get = (fun _ _ -> return_unit)} + | (name, Opt_handler handler) :: fields -> + let (Handler handlers) = combine_object fields in + Handler + { + encoding = + Data_encoding.merge_objs + Data_encoding.(obj1 (opt name (dynamic_size handler.encoding))) + handlers.encoding; + get = + (fun k i -> + handler.get k i >>=? fun v1 -> + handlers.get k i >|=? fun v2 -> (v1, v2)); + } + [@@coq_axiom_with_reason "gadt"] + +type query = {depth : int} + +let depth_query = + let open RPC_query in + query (fun depth -> {depth}) + |+ field "depth" RPC_arg.uint 0 (fun t -> t.depth) + |> seal + +let build_directory : type key. key t -> key RPC_directory.t = + fun dir -> + let rpc_dir = ref (RPC_directory.empty : key RPC_directory.t) in + let register : + type ikey. + chunked:bool -> (key, ikey) RPC_path.t -> ikey opt_handler -> unit = + fun ~chunked path (Opt_handler {encoding; get}) -> + let service = + RPC_service.get_service ~query:depth_query ~output:encoding path + in + rpc_dir := + RPC_directory.opt_register ~chunked !rpc_dir service (fun k q () -> + get k (q.depth + 1)) + in + let rec build_handler : + type ikey. ikey t -> (key, ikey) RPC_path.t -> ikey opt_handler = + fun desc path -> + match desc.dir with + | Empty -> + Opt_handler + {encoding = Data_encoding.unit; get = (fun _ _ -> return_none)} + | Value {get; encoding} -> + let handler = + Opt_handler + { + encoding; + get = + (fun k i -> if Compare.Int.(i < 0) then return_none else get k); + } + in + register ~chunked:true path handler ; + handler + | NamedDir map -> + let fields = StringMap.bindings map in + let fields = + List.map + (fun (name, dir) -> + (name, build_handler dir RPC_path.(path / name))) + fields + in + let (Handler handler) = combine_object fields in + let handler = + Opt_handler + { + encoding = handler.encoding; + get = + (fun k i -> + if Compare.Int.(i < 0) then return_none + else handler.get k (i - 1) >>=? fun v -> return_some v); + } + in + register ~chunked:true path handler ; + handler + | IndexedDir {arg; arg_encoding; list; subdir} -> + let (Opt_handler handler) = + build_handler subdir RPC_path.(path /: arg) + in + let encoding = + let open Data_encoding in + union + [ + case + (Tag 0) + ~title:"Leaf" + (dynamic_size arg_encoding) + (function (key, None) -> Some key | _ -> None) + (fun key -> (key, None)); + case + (Tag 1) + ~title:"Dir" + (tup2 + (dynamic_size arg_encoding) + (dynamic_size handler.encoding)) + (function (key, Some value) -> Some (key, value) | _ -> None) + (fun (key, value) -> (key, Some value)); + ] + in + let get k i = + if Compare.Int.(i < 0) then return_none + else if Compare.Int.(i = 0) then return_some [] + else + list k >>=? fun keys -> + List.map_es + (fun key -> + if Compare.Int.(i = 1) then return (key, None) + else handler.get (k, key) (i - 1) >|=? fun value -> (key, value)) + keys + >>=? fun values -> return_some values + in + let handler = + Opt_handler + {encoding = Data_encoding.(list (dynamic_size encoding)); get} + in + register ~chunked:true path handler ; + handler + in + ignore (build_handler dir RPC_path.open_root : key opt_handler) ; + !rpc_dir + [@@coq_axiom_with_reason "gadt"] diff --git a/src/proto_012_PsiThaCa/lib_protocol/storage_description.mli b/src/proto_012_PsiThaCa/lib_protocol/storage_description.mli new file mode 100644 index 000000000000..33e44cc39f13 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/storage_description.mli @@ -0,0 +1,93 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module is responsible for building the description of the current state + of the storage, which is then used to build specification of the RPC + endpoints for accessing the storage. It produces [resto] [RPC_directory.t] + values, which can be used directly to construct the RPC endpoint tree. *) + +(** Typed description of the key-value context. *) +type 'key t + +(** Trivial display of the key-value context layout. *) +val pp : Format.formatter -> 'key t -> unit + +(** Export an RPC hierarchy for querying the context. There is one service + by possible path in the context. Services for "directory" are able to + aggregate in one JSON object the whole subtree. *) +val build_directory : 'key t -> 'key RPC_directory.t + +(** Create a empty context description, + keys will be registered by side effects. *) +val create : unit -> 'key t + +(** Register a single key accessor at a given path. *) +val register_value : + 'key t -> get:('key -> 'a option tzresult Lwt.t) -> 'a Data_encoding.t -> unit + +(** Return a description for a prefixed fragment of the given context. + All keys registered in the subcontext will be shared by the external + context *) +val register_named_subcontext : 'key t -> string list -> 'key t + +(** Description of an index as a sequence of `RPC_arg.t`. *) +type (_, _, _) args = + | One : { + rpc_arg : 'a RPC_arg.t; + encoding : 'a Data_encoding.t; + compare : 'a -> 'a -> int; + } + -> ('key, 'a, 'key * 'a) args + | Pair : + ('key, 'a, 'inter_key) args * ('inter_key, 'b, 'sub_key) args + -> ('key, 'a * 'b, 'sub_key) args + +(** Return a description for a indexed sub-context. + All keys registered in the subcontext will be shared by the external + context. One should provide a function to list all the registered + index in the context. *) +val register_indexed_subcontext : + 'key t -> + list:('key -> 'arg list tzresult Lwt.t) -> + ('key, 'arg, 'sub_key) args -> + 'sub_key t + +(** Helpers for manipulating and defining indexes. *) + +val pack : ('key, 'a, 'sub_key) args -> 'key -> 'a -> 'sub_key + +val unpack : ('key, 'a, 'sub_key) args -> 'sub_key -> 'key * 'a + +module type INDEX = sig + type t + + include Path_encoding.S with type t := t + + val rpc_arg : t RPC_arg.t + + val encoding : t Data_encoding.t + + val compare : t -> t -> int +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/storage_functors.ml b/src/proto_012_PsiThaCa/lib_protocol/storage_functors.ml new file mode 100644 index 000000000000..48a611f95b88 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/storage_functors.ml @@ -0,0 +1,1123 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Storage_sigs + +module Registered = struct + let ghost = false +end + +module Ghost = struct + let ghost = true +end + +module type ENCODER = sig + type t + + val of_bytes : key:(unit -> string list) -> bytes -> t tzresult + + val to_bytes : t -> bytes +end + +module Make_encoder (V : VALUE) : ENCODER with type t := V.t = struct + let of_bytes ~key b = + match Data_encoding.Binary.of_bytes_opt V.encoding b with + | None -> error (Raw_context.Storage_error (Corrupted_data (key ()))) + | Some v -> Ok v + + let to_bytes v = + match Data_encoding.Binary.to_bytes_opt V.encoding v with + | Some b -> b + | None -> Bytes.empty +end + +let len_name = "len" + +let data_name = "data" + +let encode_len_value bytes = + let length = Bytes.length bytes in + Data_encoding.(Binary.to_bytes_exn int31) length + +let decode_len_value key len = + match Data_encoding.(Binary.of_bytes_opt int31) len with + | None -> error (Raw_context.Storage_error (Corrupted_data key)) + | Some len -> ok len + +module Make_subcontext (R : REGISTER) (C : Raw_context.T) (N : NAME) : + Raw_context.T with type t = C.t = struct + type t = C.t + + let to_key k = N.name @ k + + let mem t k = C.mem t (to_key k) + + let mem_tree t k = C.mem_tree t (to_key k) + + let get t k = C.get t (to_key k) + + let get_tree t k = C.get_tree t (to_key k) + + let find t k = C.find t (to_key k) + + let find_tree t k = C.find_tree t (to_key k) + + let add t k v = C.add t (to_key k) v + + let add_tree t k v = C.add_tree t (to_key k) v + + let init t k v = C.init t (to_key k) v + + let init_tree t k v = C.init_tree t (to_key k) v + + let update t k v = C.update t (to_key k) v + + let update_tree t k v = C.update_tree t (to_key k) v + + let add_or_remove t k v = C.add_or_remove t (to_key k) v + + let add_or_remove_tree t k v = C.add_or_remove_tree t (to_key k) v + + let remove_existing t k = C.remove_existing t (to_key k) + + let remove_existing_tree t k = C.remove_existing_tree t (to_key k) + + let remove t k = C.remove t (to_key k) + + let list t ?offset ?length k = C.list t ?offset ?length (to_key k) + + let fold ?depth t k ~order ~init ~f = + C.fold ?depth t (to_key k) ~order ~init ~f + + module Tree = C.Tree + + let project = C.project + + let absolute_key c k = C.absolute_key c (to_key k) + + type error += Block_quota_exceeded = C.Block_quota_exceeded + + type error += Operation_quota_exceeded = C.Operation_quota_exceeded + + let consume_gas = C.consume_gas + + let check_enough_gas = C.check_enough_gas + + let description = + let description = + if R.ghost then Storage_description.create () else C.description + in + Storage_description.register_named_subcontext description N.name +end + +module Make_single_data_storage + (R : REGISTER) + (C : Raw_context.T) + (N : NAME) + (V : VALUE) : Single_data_storage with type t = C.t and type value = V.t = +struct + type t = C.t + + type context = t + + type value = V.t + + let mem t = C.mem t N.name + + include Make_encoder (V) + + let get t = + C.get t N.name >>=? fun b -> + let key () = C.absolute_key t N.name in + Lwt.return (of_bytes ~key b) + + let find t = + C.find t N.name >|= function + | None -> Result.return_none + | Some b -> + let key () = C.absolute_key t N.name in + of_bytes ~key b >|? fun v -> Some v + + let init t v = C.init t N.name (to_bytes v) >|=? fun t -> C.project t + + let update t v = C.update t N.name (to_bytes v) >|=? fun t -> C.project t + + let add t v = C.add t N.name (to_bytes v) >|= fun t -> C.project t + + let add_or_remove t v = + C.add_or_remove t N.name (Option.map to_bytes v) >|= fun t -> C.project t + + let remove t = C.remove t N.name >|= fun t -> C.project t + + let remove_existing t = C.remove_existing t N.name >|=? fun t -> C.project t + + let () = + let open Storage_description in + let description = + if R.ghost then Storage_description.create () else C.description + in + register_value + ~get:find + (register_named_subcontext description N.name) + V.encoding + [@@coq_axiom_with_reason "stack overflow in Coq"] +end + +module type INDEX = sig + type t + + include Path_encoding.S with type t := t + + type 'a ipath + + val args : ('a, t, 'a ipath) Storage_description.args +end + +module Pair (I1 : INDEX) (I2 : INDEX) : INDEX with type t = I1.t * I2.t = struct + type t = I1.t * I2.t + + let path_length = I1.path_length + I2.path_length + + let to_path (x, y) l = I1.to_path x (I2.to_path y l) + + let of_path l = + match Misc.take I1.path_length l with + | None -> None + | Some (l1, l2) -> ( + match (I1.of_path l1, I2.of_path l2) with + | (Some x, Some y) -> Some (x, y) + | _ -> None) + + type 'a ipath = 'a I1.ipath I2.ipath + + let args = Storage_description.Pair (I1.args, I2.args) +end + +module Make_data_set_storage (C : Raw_context.T) (I : INDEX) : + Data_set_storage with type t = C.t and type elt = I.t = struct + type t = C.t + + type context = t + + type elt = I.t + + let inited = Bytes.of_string "inited" + + let mem s i = C.mem s (I.to_path i []) + + let add s i = C.add s (I.to_path i []) inited >|= fun t -> C.project t + + let remove s i = C.remove s (I.to_path i []) >|= fun t -> C.project t + + let clear s = C.remove s [] >|= fun t -> C.project t + + let fold s ~order ~init ~f = + C.fold ~depth:(`Eq I.path_length) s [] ~order ~init ~f:(fun file tree acc -> + match C.Tree.kind tree with + | `Value -> ( + match I.of_path file with None -> assert false | Some p -> f p acc) + | `Tree -> Lwt.return acc) + + let elements s = + fold s ~order:`Sorted ~init:[] ~f:(fun p acc -> Lwt.return (p :: acc)) + + let () = + let open Storage_description in + let unpack = unpack I.args in + register_value (* TODO fixme 'elements...' *) + ~get:(fun c -> + let (c, k) = unpack c in + mem c k >>= function true -> return_some true | false -> return_none) + (register_indexed_subcontext + ~list:(fun c -> elements c >|= ok) + C.description + I.args) + Data_encoding.bool + [@@coq_axiom_with_reason "stack overflow in Coq"] +end + +module Make_indexed_data_storage (C : Raw_context.T) (I : INDEX) (V : VALUE) : + Indexed_data_storage with type t = C.t and type key = I.t and type value = V.t = +struct + type t = C.t + + type context = t + + type key = I.t + + type value = V.t + + include Make_encoder (V) + + let mem s i = C.mem s (I.to_path i []) + + let get s i = + C.get s (I.to_path i []) >>=? fun b -> + let key () = C.absolute_key s (I.to_path i []) in + Lwt.return (of_bytes ~key b) + + let find s i = + C.find s (I.to_path i []) >|= function + | None -> Result.return_none + | Some b -> + let key () = C.absolute_key s (I.to_path i []) in + of_bytes ~key b >|? fun v -> Some v + + let update s i v = + C.update s (I.to_path i []) (to_bytes v) >|=? fun t -> C.project t + + let init s i v = + C.init s (I.to_path i []) (to_bytes v) >|=? fun t -> C.project t + + let add s i v = C.add s (I.to_path i []) (to_bytes v) >|= fun t -> C.project t + + let add_or_remove s i v = + C.add_or_remove s (I.to_path i []) (Option.map to_bytes v) >|= fun t -> + C.project t + + let remove s i = C.remove s (I.to_path i []) >|= fun t -> C.project t + + let remove_existing s i = + C.remove_existing s (I.to_path i []) >|=? fun t -> C.project t + + let clear s = C.remove s [] >|= fun t -> C.project t + + let fold s ~order ~init ~f = + C.fold ~depth:(`Eq I.path_length) s [] ~order ~init ~f:(fun file tree acc -> + C.Tree.to_value tree >>= function + | Some v -> ( + match I.of_path file with + | None -> assert false + | Some path -> ( + let key () = C.absolute_key s file in + match of_bytes ~key v with + | Ok v -> f path v acc + | Error _ -> Lwt.return acc)) + | None -> Lwt.return acc) + + let fold_keys s ~order ~init ~f = + fold s ~order ~init ~f:(fun k _ acc -> f k acc) + + let bindings s = + fold s ~order:`Sorted ~init:[] ~f:(fun p v acc -> + Lwt.return ((p, v) :: acc)) + + let keys s = + fold_keys s ~order:`Sorted ~init:[] ~f:(fun p acc -> Lwt.return (p :: acc)) + + let () = + let open Storage_description in + let unpack = unpack I.args in + register_value + ~get:(fun c -> + let (c, k) = unpack c in + find c k) + (register_indexed_subcontext + ~list:(fun c -> keys c >|= ok) + C.description + I.args) + V.encoding + [@@coq_axiom_with_reason "stack overflow in Coq"] +end + +(* Internal-use-only version of {!Make_indexed_carbonated_data_storage} to + expose fold_keys_unaccounted *) +module Make_indexed_carbonated_data_storage_INTERNAL + (C : Raw_context.T) + (I : INDEX) + (V : VALUE) : + Non_iterable_indexed_carbonated_data_storage_INTERNAL + with type t = C.t + and type key = I.t + and type value = V.t = struct + type t = C.t + + type context = t + + type key = I.t + + type value = V.t + + include Make_encoder (V) + + let data_key i = I.to_path i [data_name] + + let len_key i = I.to_path i [len_name] + + let consume_mem_gas c key = + C.consume_gas + c + (Storage_costs.read_access ~path_length:(List.length key) ~read_bytes:0) + + let existing_size c i = + C.find c (len_key i) >|= function + | None -> ok (0, false) + | Some len -> decode_len_value (len_key i) len >|? fun len -> (len, true) + + let consume_read_gas get c i = + let len_key = len_key i in + get c len_key >>=? fun len -> + Lwt.return + ( decode_len_value len_key len >>? fun read_bytes -> + let cost = + Storage_costs.read_access + ~path_length:(List.length len_key) + ~read_bytes + in + C.consume_gas c cost ) + + (* For the future: here, we bill a generic cost for encoding the value + to bytes. It would be cleaner for users of this functor to provide + gas costs for the encoding. *) + let consume_serialize_write_gas set c i v = + let bytes = to_bytes v in + let len = Bytes.length bytes in + C.consume_gas c (Gas_limit_repr.alloc_mbytes_cost len) >>?= fun c -> + let cost = Storage_costs.write_access ~written_bytes:len in + C.consume_gas c cost >>?= fun c -> + set c (len_key i) (encode_len_value bytes) >|=? fun c -> (c, bytes) + + let consume_remove_gas del c i = + C.consume_gas c (Storage_costs.write_access ~written_bytes:0) >>?= fun c -> + del c (len_key i) + + let mem s i = + let key = data_key i in + consume_mem_gas s key >>?= fun s -> + C.mem s key >|= fun exists -> ok (C.project s, exists) + + let get_unprojected s i = + consume_read_gas C.get s i >>=? fun s -> + C.get s (data_key i) >>=? fun b -> + let key () = C.absolute_key s (data_key i) in + Lwt.return (of_bytes ~key b >|? fun v -> (s, v)) + + let get s i = get_unprojected s i >|=? fun (s, v) -> (C.project s, v) + + let find s i = + let key = data_key i in + consume_mem_gas s key >>?= fun s -> + C.mem s key >>= fun exists -> + if exists then get s i >|=? fun (s, v) -> (s, Some v) + else return (C.project s, None) + + let update s i v = + existing_size s i >>=? fun (prev_size, _) -> + consume_serialize_write_gas C.update s i v >>=? fun (s, bytes) -> + C.update s (data_key i) bytes >|=? fun t -> + let size_diff = Bytes.length bytes - prev_size in + (C.project t, size_diff) + + let init s i v = + consume_serialize_write_gas C.init s i v >>=? fun (s, bytes) -> + C.init s (data_key i) bytes >|=? fun t -> + let size = Bytes.length bytes in + (C.project t, size) + + let add s i v = + let add s i v = C.add s i v >|= ok in + existing_size s i >>=? fun (prev_size, existed) -> + consume_serialize_write_gas add s i v >>=? fun (s, bytes) -> + add s (data_key i) bytes >|=? fun t -> + let size_diff = Bytes.length bytes - prev_size in + (C.project t, size_diff, existed) + + let remove s i = + let remove s i = C.remove s i >|= ok in + existing_size s i >>=? fun (prev_size, existed) -> + consume_remove_gas remove s i >>=? fun s -> + remove s (data_key i) >|=? fun t -> (C.project t, prev_size, existed) + + let remove_existing s i = + existing_size s i >>=? fun (prev_size, _) -> + consume_remove_gas C.remove_existing s i >>=? fun s -> + C.remove_existing s (data_key i) >|=? fun t -> (C.project t, prev_size) + + let add_or_remove s i v = + match v with None -> remove s i | Some v -> add s i v + + (** Because big map values are not stored under some common key, + we have no choice but to fold over all nodes with a path of length + [I.path_length] to retrieve actual keys and then paginate. + + While this is inefficient and will traverse the whole tree ([O(n)]), there + currently isn't a better decent alternative. + + Once https://gitlab.com/tezos/tezos/-/merge_requests/2771 which flattens paths is done, + {!C.list} could be used instead here. *) + let list_values ?(offset = 0) ?(length = max_int) s = + let root = [] in + let depth = `Eq I.path_length in + C.fold + s + root + ~depth + ~order:`Sorted + ~init:(ok (s, [], offset, length)) + ~f:(fun file tree acc -> + match (C.Tree.kind tree, acc) with + | (`Tree, Ok (s, rev_values, offset, length)) -> ( + if Compare.Int.(length <= 0) then + (* Keep going until the end, we have no means of short-circuiting *) + Lwt.return acc + else if Compare.Int.(offset > 0) then + (* Offset (first element) not reached yet *) + let offset = pred offset in + Lwt.return (Ok (s, rev_values, offset, length)) + else + (* Nominal case *) + match I.of_path file with + | None -> assert false + | Some key -> + get_unprojected s key >|=? fun (s, value) -> + (s, value :: rev_values, 0, pred length)) + | _ -> Lwt.return acc) + >|=? fun (s, rev_values, _offset, _length) -> + (C.project s, List.rev rev_values) + + let fold_keys_unaccounted s ~order ~init ~f = + C.fold ~depth:(`Eq I.path_length) s [] ~order ~init ~f:(fun file tree acc -> + match C.Tree.kind tree with + | `Value -> ( + match List.rev file with + | last :: _ when Compare.String.(last = len_name) -> Lwt.return acc + | last :: rest when Compare.String.(last = data_name) -> ( + let file = List.rev rest in + match I.of_path file with + | None -> assert false + | Some path -> f path acc) + | _ -> assert false) + | `Tree -> Lwt.return acc) + + let keys_unaccounted s = + fold_keys_unaccounted s ~order:`Sorted ~init:[] ~f:(fun p acc -> + Lwt.return (p :: acc)) + + let () = + let open Storage_description in + let unpack = unpack I.args in + register_value (* TODO export consumed gas ?? *) + ~get:(fun c -> + let (c, k) = unpack c in + find c k >|=? fun (_, v) -> v) + (register_indexed_subcontext + ~list:(fun c -> keys_unaccounted c >|= ok) + C.description + I.args) + V.encoding + [@@coq_axiom_with_reason "stack overflow in Coq"] +end + +module Make_indexed_carbonated_data_storage : functor + (C : Raw_context.T) + (I : INDEX) + (V : VALUE) + -> + Non_iterable_indexed_carbonated_data_storage_with_values + with type t = C.t + and type key = I.t + and type value = V.t = + Make_indexed_carbonated_data_storage_INTERNAL + +module Make_carbonated_data_set_storage (C : Raw_context.T) (I : INDEX) : + Carbonated_data_set_storage with type t = C.t and type elt = I.t = struct + module V = struct + type t = unit + + let encoding = Data_encoding.unit + end + + module M = Make_indexed_carbonated_data_storage_INTERNAL (C) (I) (V) + + type t = M.t + + type context = t + + type elt = I.t + + let mem = M.mem + + let init s i = M.init s i () + + let remove s i = M.remove s i + + let fold_keys_unaccounted = M.fold_keys_unaccounted +end + +module Make_indexed_data_snapshotable_storage + (C : Raw_context.T) + (Snapshot_index : INDEX) + (I : INDEX) + (V : VALUE) : + Indexed_data_snapshotable_storage + with type t = C.t + and type snapshot = Snapshot_index.t + and type key = I.t + and type value = V.t = struct + type snapshot = Snapshot_index.t + + let data_name = ["current"] + + let snapshot_name = ["snapshot"] + + module C_data = + Make_subcontext (Registered) (C) + (struct + let name = data_name + end) + + module C_snapshot = + Make_subcontext (Registered) (C) + (struct + let name = snapshot_name + end) + + module V_encoder = Make_encoder (V) + include Make_indexed_data_storage (C_data) (I) (V) + module Snapshot = + Make_indexed_data_storage (C_snapshot) (Pair (Snapshot_index) (I)) (V) + + let snapshot_path id = snapshot_name @ Snapshot_index.to_path id [] + + let snapshot_exists s id = C.mem_tree s (snapshot_path id) + + let err_missing_key key = Raw_context.storage_error (Missing_key (key, Copy)) + + let snapshot s id = + C.find_tree s data_name >>= function + | None -> Lwt.return (err_missing_key data_name) + | Some tree -> + C.add_tree s (snapshot_path id) tree >|= (fun t -> C.project t) >|= ok + + let fold_snapshot s id ~order ~init ~f = + C.find_tree s (snapshot_path id) >>= function + | None -> Lwt.return (err_missing_key data_name) + | Some tree -> + C_data.Tree.fold + tree + ~depth:(`Eq I.path_length) + [] + ~order + ~init:(Ok init) + ~f:(fun file tree acc -> + acc >>?= fun acc -> + C.Tree.to_value tree >>= function + | Some v -> ( + match I.of_path file with + | None -> assert false + | Some path -> ( + let key () = C.absolute_key s file in + match V_encoder.of_bytes ~key v with + | Ok v -> f path v acc + | Error _ -> return acc)) + | None -> return acc) + + let delete_snapshot s id = + C.remove s (snapshot_path id) >|= fun t -> C.project t +end + +module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX) : + Indexed_raw_context + with type t = C.t + and type key = I.t + and type 'a ipath = 'a I.ipath = struct + type t = C.t + + type context = t + + type key = I.t + + type 'a ipath = 'a I.ipath + + let clear t = C.remove t [] >|= fun t -> C.project t + + let fold_keys t ~order ~init ~f = + C.fold ~depth:(`Eq I.path_length) t [] ~order ~init ~f:(fun path tree acc -> + match C.Tree.kind tree with + | `Tree -> ( + match I.of_path path with + | None -> assert false + | Some path -> f path acc) + | `Value -> Lwt.return acc) + + let keys t = + fold_keys t ~order:`Sorted ~init:[] ~f:(fun i acc -> Lwt.return (i :: acc)) + + let err_missing_key key = Raw_context.storage_error (Missing_key (key, Copy)) + + let copy t ~from ~to_ = + let from = I.to_path from [] in + let to_ = I.to_path to_ [] in + C.find_tree t from >>= function + | None -> Lwt.return (err_missing_key from) + | Some tree -> C.add_tree t to_ tree >|= ok + + let remove t k = C.remove t (I.to_path k []) + + let description = + Storage_description.register_indexed_subcontext + ~list:(fun c -> keys c >|= ok) + C.description + I.args + + let unpack = Storage_description.unpack I.args + + let pack = Storage_description.pack I.args + + module Raw_context : Raw_context.T with type t = C.t I.ipath = struct + type t = C.t I.ipath + + let to_key i k = I.to_path i k + + let mem c k = + let (t, i) = unpack c in + C.mem t (to_key i k) + + let mem_tree c k = + let (t, i) = unpack c in + C.mem_tree t (to_key i k) + + let get c k = + let (t, i) = unpack c in + C.get t (to_key i k) + + let get_tree c k = + let (t, i) = unpack c in + C.get_tree t (to_key i k) + + let find c k = + let (t, i) = unpack c in + C.find t (to_key i k) + + let find_tree c k = + let (t, i) = unpack c in + C.find_tree t (to_key i k) + + let list c ?offset ?length k = + let (t, i) = unpack c in + C.list t ?offset ?length (to_key i k) + + let init c k v = + let (t, i) = unpack c in + C.init t (to_key i k) v >|=? fun t -> pack t i + + let init_tree c k v = + let (t, i) = unpack c in + C.init_tree t (to_key i k) v >|=? fun t -> pack t i + + let update c k v = + let (t, i) = unpack c in + C.update t (to_key i k) v >|=? fun t -> pack t i + + let update_tree c k v = + let (t, i) = unpack c in + C.update_tree t (to_key i k) v >|=? fun t -> pack t i + + let add c k v = + let (t, i) = unpack c in + C.add t (to_key i k) v >|= fun t -> pack t i + + let add_tree c k v = + let (t, i) = unpack c in + C.add_tree t (to_key i k) v >|= fun t -> pack t i + + let add_or_remove c k v = + let (t, i) = unpack c in + C.add_or_remove t (to_key i k) v >|= fun t -> pack t i + + let add_or_remove_tree c k v = + let (t, i) = unpack c in + C.add_or_remove_tree t (to_key i k) v >|= fun t -> pack t i + + let remove_existing c k = + let (t, i) = unpack c in + C.remove_existing t (to_key i k) >|=? fun t -> pack t i + + let remove_existing_tree c k = + let (t, i) = unpack c in + C.remove_existing_tree t (to_key i k) >|=? fun t -> pack t i + + let remove c k = + let (t, i) = unpack c in + C.remove t (to_key i k) >|= fun t -> pack t i + + let fold ?depth c k ~order ~init ~f = + let (t, i) = unpack c in + C.fold ?depth t (to_key i k) ~order ~init ~f + + module Tree = struct + include C.Tree + + let empty c = + let (t, _) = unpack c in + C.Tree.empty t + end + + let project c = + let (t, _) = unpack c in + C.project t + + let absolute_key c k = + let (t, i) = unpack c in + C.absolute_key t (to_key i k) + + type error += Block_quota_exceeded = C.Block_quota_exceeded + + type error += Operation_quota_exceeded = C.Operation_quota_exceeded + + let consume_gas c g = + let (t, i) = unpack c in + C.consume_gas t g >>? fun t -> ok (pack t i) + + let check_enough_gas c g = + let (t, _i) = unpack c in + C.check_enough_gas t g + + let description = description + end + + module Make_set (R : REGISTER) (N : NAME) : + Data_set_storage with type t = t and type elt = key = struct + type t = C.t + + type context = t + + type elt = I.t + + let inited = Bytes.of_string "inited" + + let mem s i = Raw_context.mem (pack s i) N.name + + let add s i = + Raw_context.add (pack s i) N.name inited >|= fun c -> + let (s, _) = unpack c in + C.project s + + let remove s i = + Raw_context.remove (pack s i) N.name >|= fun c -> + let (s, _) = unpack c in + C.project s + + let clear s = + fold_keys s ~init:s ~order:`Sorted ~f:(fun i s -> + Raw_context.remove (pack s i) N.name >|= fun c -> + let (s, _) = unpack c in + s) + >|= fun t -> C.project t + + let fold s ~order ~init ~f = + fold_keys s ~order ~init ~f:(fun i acc -> + mem s i >>= function true -> f i acc | false -> Lwt.return acc) + + let elements s = + fold s ~order:`Sorted ~init:[] ~f:(fun p acc -> Lwt.return (p :: acc)) + + let () = + let open Storage_description in + let unpack = unpack I.args in + let description = + if R.ghost then Storage_description.create () + else Raw_context.description + in + register_value + ~get:(fun c -> + let (c, k) = unpack c in + mem c k >>= function true -> return_some true | false -> return_none) + (register_named_subcontext description N.name) + Data_encoding.bool + [@@coq_axiom_with_reason "stack overflow in Coq"] + end + + module Make_map (N : NAME) (V : VALUE) : + Indexed_data_storage with type t = t and type key = key and type value = V.t = + struct + type t = C.t + + type context = t + + type key = I.t + + type value = V.t + + include Make_encoder (V) + + let mem s i = Raw_context.mem (pack s i) N.name + + let get s i = + Raw_context.get (pack s i) N.name >>=? fun b -> + let key () = Raw_context.absolute_key (pack s i) N.name in + Lwt.return (of_bytes ~key b) + + let find s i = + Raw_context.find (pack s i) N.name >|= function + | None -> Result.return_none + | Some b -> + let key () = Raw_context.absolute_key (pack s i) N.name in + of_bytes ~key b >|? fun v -> Some v + + let update s i v = + Raw_context.update (pack s i) N.name (to_bytes v) >|=? fun c -> + let (s, _) = unpack c in + C.project s + + let init s i v = + Raw_context.init (pack s i) N.name (to_bytes v) >|=? fun c -> + let (s, _) = unpack c in + C.project s + + let add s i v = + Raw_context.add (pack s i) N.name (to_bytes v) >|= fun c -> + let (s, _) = unpack c in + C.project s + + let add_or_remove s i v = + Raw_context.add_or_remove (pack s i) N.name (Option.map to_bytes v) + >|= fun c -> + let (s, _) = unpack c in + C.project s + + let remove s i = + Raw_context.remove (pack s i) N.name >|= fun c -> + let (s, _) = unpack c in + C.project s + + let remove_existing s i = + Raw_context.remove_existing (pack s i) N.name >|=? fun c -> + let (s, _) = unpack c in + C.project s + + let clear s = + fold_keys s ~order:`Sorted ~init:s ~f:(fun i s -> + Raw_context.remove (pack s i) N.name >|= fun c -> + let (s, _) = unpack c in + s) + >|= fun t -> C.project t + + let fold s ~order ~init ~f = + fold_keys s ~order ~init ~f:(fun i acc -> + get s i >>= function Error _ -> Lwt.return acc | Ok v -> f i v acc) + + let bindings s = + fold s ~order:`Sorted ~init:[] ~f:(fun p v acc -> + Lwt.return ((p, v) :: acc)) + + let fold_keys s ~order ~init ~f = + fold_keys s ~order ~init ~f:(fun i acc -> + mem s i >>= function false -> Lwt.return acc | true -> f i acc) + + let keys s = + fold_keys s ~order:`Sorted ~init:[] ~f:(fun p acc -> + Lwt.return (p :: acc)) + + let () = + let open Storage_description in + let unpack = unpack I.args in + register_value + ~get:(fun c -> + let (c, k) = unpack c in + find c k) + (register_named_subcontext Raw_context.description N.name) + V.encoding + [@@coq_axiom_with_reason "stack overflow in Coq"] + end + + module Make_carbonated_map (N : NAME) (V : VALUE) : + Non_iterable_indexed_carbonated_data_storage + with type t = t + and type key = key + and type value = V.t = struct + type t = C.t + + type context = t + + type key = I.t + + type value = V.t + + include Make_encoder (V) + + let len_name = len_name :: N.name + + let data_name = data_name :: N.name + + let path_length = List.length N.name + 1 + + let consume_mem_gas c = + Raw_context.consume_gas + c + (Storage_costs.read_access ~path_length ~read_bytes:0) + + let existing_size c = + Raw_context.find c len_name >|= function + | None -> ok (0, false) + | Some len -> decode_len_value len_name len >|? fun len -> (len, true) + + let consume_read_gas get c = + get c len_name >>=? fun len -> + Lwt.return + ( decode_len_value len_name len >>? fun read_bytes -> + Raw_context.consume_gas + c + (Storage_costs.read_access ~path_length ~read_bytes) ) + + let consume_write_gas set c v = + let bytes = to_bytes v in + let len = Bytes.length bytes in + Raw_context.consume_gas c (Storage_costs.write_access ~written_bytes:len) + >>?= fun c -> + set c len_name (encode_len_value bytes) >|=? fun c -> (c, bytes) + + let consume_remove_gas del c = + Raw_context.consume_gas c (Storage_costs.write_access ~written_bytes:0) + >>?= fun c -> del c len_name + + let mem s i = + consume_mem_gas (pack s i) >>?= fun c -> + Raw_context.mem c data_name >|= fun res -> ok (Raw_context.project c, res) + + let get s i = + consume_read_gas Raw_context.get (pack s i) >>=? fun c -> + Raw_context.get c data_name >>=? fun b -> + let key () = Raw_context.absolute_key c data_name in + Lwt.return (of_bytes ~key b >|? fun v -> (Raw_context.project c, v)) + + let find s i = + consume_mem_gas (pack s i) >>?= fun c -> + let (s, _) = unpack c in + Raw_context.mem (pack s i) data_name >>= fun exists -> + if exists then get s i >|=? fun (s, v) -> (s, Some v) + else return (C.project s, None) + + let update s i v = + existing_size (pack s i) >>=? fun (prev_size, _) -> + consume_write_gas Raw_context.update (pack s i) v >>=? fun (c, bytes) -> + Raw_context.update c data_name bytes >|=? fun c -> + let size_diff = Bytes.length bytes - prev_size in + (Raw_context.project c, size_diff) + + let init s i v = + consume_write_gas Raw_context.init (pack s i) v >>=? fun (c, bytes) -> + Raw_context.init c data_name bytes >|=? fun c -> + let size = Bytes.length bytes in + (Raw_context.project c, size) + + let add s i v = + let add c k v = Raw_context.add c k v >|= ok in + existing_size (pack s i) >>=? fun (prev_size, existed) -> + consume_write_gas add (pack s i) v >>=? fun (c, bytes) -> + add c data_name bytes >|=? fun c -> + let size_diff = Bytes.length bytes - prev_size in + (Raw_context.project c, size_diff, existed) + + let remove s i = + let remove c k = Raw_context.remove c k >|= ok in + existing_size (pack s i) >>=? fun (prev_size, existed) -> + consume_remove_gas remove (pack s i) >>=? fun c -> + remove c data_name >|=? fun c -> + (Raw_context.project c, prev_size, existed) + + let remove_existing s i = + existing_size (pack s i) >>=? fun (prev_size, _) -> + consume_remove_gas Raw_context.remove_existing (pack s i) >>=? fun c -> + Raw_context.remove_existing c data_name >|=? fun c -> + (Raw_context.project c, prev_size) + + let add_or_remove s i v = + match v with None -> remove s i | Some v -> add s i v + + let () = + let open Storage_description in + let unpack = unpack I.args in + register_value + ~get:(fun c -> + let (c, k) = unpack c in + find c k >|=? fun (_, v) -> v) + (register_named_subcontext Raw_context.description N.name) + V.encoding + [@@coq_axiom_with_reason "stack overflow in Coq"] + end +end + +module type WRAPPER = sig + type t + + type key + + val wrap : t -> key + + val unwrap : key -> t option +end + +module Wrap_indexed_data_storage + (C : Indexed_data_storage) + (K : WRAPPER with type key := C.key) : + Indexed_data_storage + with type t = C.t + and type key = K.t + and type value = C.value = struct + type t = C.t + + type context = C.t + + type key = K.t + + type value = C.value + + let mem ctxt k = C.mem ctxt (K.wrap k) + + let get ctxt k = C.get ctxt (K.wrap k) + + let find ctxt k = C.find ctxt (K.wrap k) + + let update ctxt k v = C.update ctxt (K.wrap k) v + + let init ctxt k v = C.init ctxt (K.wrap k) v + + let add ctxt k v = C.add ctxt (K.wrap k) v + + let add_or_remove ctxt k v = C.add_or_remove ctxt (K.wrap k) v + + let remove_existing ctxt k = C.remove_existing ctxt (K.wrap k) + + let remove ctxt k = C.remove ctxt (K.wrap k) + + let clear ctxt = C.clear ctxt + + let fold ctxt ~order ~init ~f = + C.fold ctxt ~order ~init ~f:(fun k v acc -> + match K.unwrap k with None -> Lwt.return acc | Some k -> f k v acc) + + let bindings s = + fold s ~order:`Sorted ~init:[] ~f:(fun p v acc -> + Lwt.return ((p, v) :: acc)) + + let fold_keys s ~order ~init ~f = + C.fold_keys s ~order ~init ~f:(fun k acc -> + match K.unwrap k with None -> Lwt.return acc | Some k -> f k acc) + + let keys s = + fold_keys s ~order:`Sorted ~init:[] ~f:(fun p acc -> Lwt.return (p :: acc)) +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/storage_functors.mli b/src/proto_012_PsiThaCa/lib_protocol/storage_functors.mli new file mode 100644 index 000000000000..5b78bc8a1f7f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/storage_functors.mli @@ -0,0 +1,122 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Tezos Protocol Implementation - Typed storage builders. + + @see [Make_subcontext] + *) + +open Storage_sigs + +module Registered : REGISTER + +module Ghost : REGISTER + +(** Given a [Raw_context], return a new [Raw_context] that projects into + a given subtree. Similar to a {i functional lens}. + *) +module Make_subcontext (_ : REGISTER) (C : Raw_context.T) (_ : NAME) : + Raw_context.T with type t = C.t + +module Make_single_data_storage + (_ : REGISTER) + (C : Raw_context.T) + (_ : NAME) + (V : VALUE) : Single_data_storage with type t = C.t and type value = V.t + +(** A type that can be serialized as a [string list], and used + as a prefix in the typed datastore. + + Useful to implement storage of maps and sets. + *) +module type INDEX = sig + type t + + include Path_encoding.S with type t := t + + type 'a ipath + + val args : ('a, t, 'a ipath) Storage_description.args +end + +module Pair (I1 : INDEX) (I2 : INDEX) : INDEX with type t = I1.t * I2.t + +(** Create storage for a compound type. *) +module Make_data_set_storage (C : Raw_context.T) (I : INDEX) : + Data_set_storage with type t = C.t and type elt = I.t + +(** Like [Make_data_set_storage], adding tracking of storage cost. *) +module Make_carbonated_data_set_storage (C : Raw_context.T) (I : INDEX) : + Carbonated_data_set_storage with type t = C.t and type elt = I.t + +(** This functor creates storage for types with a notion of an index. *) +module Make_indexed_data_storage (C : Raw_context.T) (I : INDEX) (V : VALUE) : + Indexed_data_storage with type t = C.t and type key = I.t and type value = V.t + +(** Like [Make_indexed_data_storage], adding tracking of storage cost. *) +module Make_indexed_carbonated_data_storage + (C : Raw_context.T) + (I : INDEX) + (V : VALUE) : + Non_iterable_indexed_carbonated_data_storage_with_values + with type t = C.t + and type key = I.t + and type value = V.t + +module Make_indexed_data_snapshotable_storage + (C : Raw_context.T) + (Snapshot : INDEX) + (I : INDEX) + (V : VALUE) : + Indexed_data_snapshotable_storage + with type t = C.t + and type snapshot = Snapshot.t + and type key = I.t + and type value = V.t + +module Make_indexed_subcontext (C : Raw_context.T) (I : INDEX) : + Indexed_raw_context + with type t = C.t + and type key = I.t + and type 'a ipath = 'a I.ipath + +module type WRAPPER = sig + type t + + type key + + val wrap : t -> key + + val unwrap : key -> t option +end + +module Wrap_indexed_data_storage + (C : Indexed_data_storage) + (K : WRAPPER with type key := C.key) : + Indexed_data_storage + with type t = C.t + and type key = K.t + and type value = C.value diff --git a/src/proto_012_PsiThaCa/lib_protocol/storage_sigs.ml b/src/proto_012_PsiThaCa/lib_protocol/storage_sigs.ml new file mode 100644 index 000000000000..9a3d04cf73c6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/storage_sigs.ml @@ -0,0 +1,418 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2019-2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** {1 Entity Accessor Signatures} *) + +(** The generic signature of a single data accessor (a single value + bound to a specific key in the hierarchical (key x value) + database). *) +module type Single_data_storage = sig + type t + + type context = t + + (** The type of the value *) + type value + + (** Tells if the data is already defined *) + val mem : context -> bool Lwt.t + + (** Retrieve the value from the storage bucket ; returns a + {!Storage_error} if the key is not set or if the deserialisation + fails *) + val get : context -> value tzresult Lwt.t + + (** Retrieves the value from the storage bucket ; returns [None] if + the data is not initialized, or {!Storage_helpers.Storage_error} + if the deserialisation fails *) + val find : context -> value option tzresult Lwt.t + + (** Allocates the storage bucket and initializes it ; returns a + {!Storage_error Existing_key} if the bucket exists *) + val init : context -> value -> Raw_context.t tzresult Lwt.t + + (** Updates the content of the bucket ; returns a {!Storage_Error + Missing_key} if the value does not exists *) + val update : context -> value -> Raw_context.t tzresult Lwt.t + + (** Allocates the data and initializes it with a value ; just + updates it if the bucket exists *) + val add : context -> value -> Raw_context.t Lwt.t + + (** When the value is [Some v], allocates the data and initializes + it with [v] ; just updates it if the bucket exists. When the + value is [None], delete the storage bucket when the value ; does + nothing if the bucket does not exists. *) + val add_or_remove : context -> value option -> Raw_context.t Lwt.t + + (** Delete the storage bucket ; returns a {!Storage_error + Missing_key} if the bucket does not exists *) + val remove_existing : context -> Raw_context.t tzresult Lwt.t + + (** Removes the storage bucket and its contents ; does nothing if + the bucket does not exists *) + val remove : context -> Raw_context.t Lwt.t +end +[@@coq_precise_signature] + +(** Restricted version of {!Indexed_data_storage} w/o iterators. *) +module type Non_iterable_indexed_data_storage = sig + type t + + type context = t + + (** An abstract type for keys *) + type key + + (** The type of values *) + type value + + (** Tells if a given key is already bound to a storage bucket *) + val mem : context -> key -> bool Lwt.t + + (** Retrieve a value from the storage bucket at a given key ; + returns {!Storage_error Missing_key} if the key is not set ; + returns {!Storage_error Corrupted_data} if the deserialisation + fails. *) + val get : context -> key -> value tzresult Lwt.t + + (** Retrieve a value from the storage bucket at a given key ; + returns [None] if the value is not set ; returns {!Storage_error + Corrupted_data} if the deserialisation fails. *) + val find : context -> key -> value option tzresult Lwt.t + + (** Updates the content of a bucket ; returns A {!Storage_Error + Missing_key} if the value does not exists. *) + val update : context -> key -> value -> Raw_context.t tzresult Lwt.t + + (** Allocates a storage bucket at the given key and initializes it ; + returns a {!Storage_error Existing_key} if the bucket exists. *) + val init : context -> key -> value -> Raw_context.t tzresult Lwt.t + + (** Allocates a storage bucket at the given key and initializes it + with a value ; just updates it if the bucket exists. *) + val add : context -> key -> value -> Raw_context.t Lwt.t + + (** When the value is [Some v], allocates the data and initializes + it with [v] ; just updates it if the bucket exists. When the + value is [None], delete the storage bucket when the value ; does + nothing if the bucket does not exists. *) + val add_or_remove : context -> key -> value option -> Raw_context.t Lwt.t + + (** Delete a storage bucket and its contents ; returns a + {!Storage_error Missing_key} if the bucket does not exists. *) + val remove_existing : context -> key -> Raw_context.t tzresult Lwt.t + + (** Removes a storage bucket and its contents ; does nothing if the + bucket does not exists. *) + val remove : context -> key -> Raw_context.t Lwt.t +end +[@@coq_precise_signature] + +(** Variant of {!Non_iterable_indexed_data_storage} with gas accounting. *) +module type Non_iterable_indexed_carbonated_data_storage = sig + type t + + type context = t + + (** An abstract type for keys *) + type key + + (** The type of values *) + type value + + (** Tells if a given key is already bound to a storage bucket. + Consumes [Gas_repr.read_bytes_cost Z.zero]. *) + val mem : context -> key -> (Raw_context.t * bool) tzresult Lwt.t + + (** Retrieve a value from the storage bucket at a given key ; + returns {!Storage_error Missing_key} if the key is not set ; + returns {!Storage_error Corrupted_data} if the deserialisation + fails. + Consumes [Gas_repr.read_bytes_cost ]. *) + val get : context -> key -> (Raw_context.t * value) tzresult Lwt.t + + (** Retrieve a value from the storage bucket at a given key ; + returns [None] if the value is not set ; returns {!Storage_error + Corrupted_data} if the deserialisation fails. + Consumes [Gas_repr.read_bytes_cost ] if present + or [Gas_repr.read_bytes_cost Z.zero]. *) + val find : context -> key -> (Raw_context.t * value option) tzresult Lwt.t + + (** Updates the content of a bucket ; returns A {!Storage_Error + Missing_key} if the value does not exists. + Consumes serialization cost. + Consumes [Gas_repr.write_bytes_cost ]. + Returns the difference from the old to the new size. *) + val update : context -> key -> value -> (Raw_context.t * int) tzresult Lwt.t + + (** Allocates a storage bucket at the given key and initializes it ; + returns a {!Storage_error Existing_key} if the bucket exists. + Consumes serialization cost. + Consumes [Gas_repr.write_bytes_cost ]. + Returns the size. *) + val init : context -> key -> value -> (Raw_context.t * int) tzresult Lwt.t + + (** Allocates a storage bucket at the given key and initializes it + with a value ; just updates it if the bucket exists. + Consumes serialization cost. + Consumes [Gas_repr.write_bytes_cost ]. + Returns the difference from the old (maybe 0) to the new size, and a boolean + indicating if a value was already associated to this key. *) + val add : + context -> key -> value -> (Raw_context.t * int * bool) tzresult Lwt.t + + (** When the value is [Some v], allocates the data and initializes + it with [v] ; just updates it if the bucket exists. When the + value is [None], delete the storage bucket when the value ; does + nothing if the bucket does not exists. + Consumes serialization cost. + Consumes the same gas cost as either {!remove} or {!init_set}. + Returns the difference from the old (maybe 0) to the new size, and a boolean + indicating if a value was already associated to this key. *) + val add_or_remove : + context -> + key -> + value option -> + (Raw_context.t * int * bool) tzresult Lwt.t + + (** Delete a storage bucket and its contents ; returns a + {!Storage_error Missing_key} if the bucket does not exists. + Consumes [Gas_repr.write_bytes_cost Z.zero]. + Returns the freed size. *) + val remove_existing : context -> key -> (Raw_context.t * int) tzresult Lwt.t + + (** Removes a storage bucket and its contents ; does nothing if the + bucket does not exists. + Consumes [Gas_repr.write_bytes_cost Z.zero]. + Returns the freed size, and a boolean + indicating if a value was already associated to this key. *) + val remove : context -> key -> (Raw_context.t * int * bool) tzresult Lwt.t +end +[@@coq_precise_signature] + +module type Non_iterable_indexed_carbonated_data_storage_with_values = sig + include Non_iterable_indexed_carbonated_data_storage + + (* HACK *) + val list_values : + ?offset:int -> + ?length:int -> + t -> + (Raw_context.t * value list) tzresult Lwt.t +end + +module type Non_iterable_indexed_carbonated_data_storage_INTERNAL = sig + include Non_iterable_indexed_carbonated_data_storage_with_values + + val fold_keys_unaccounted : + context -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(key -> 'a -> 'a Lwt.t) -> + 'a Lwt.t +end + +(** The generic signature of indexed data accessors (a set of values + of the same type indexed by keys of the same form in the + hierarchical (key x value) database). *) +module type Indexed_data_storage = sig + include Non_iterable_indexed_data_storage + + (** Empties all the keys and associated data. *) + val clear : context -> Raw_context.t Lwt.t + + (** Lists all the keys. *) + val keys : context -> key list Lwt.t + + (** Lists all the keys and associated data. *) + val bindings : context -> (key * value) list Lwt.t + + (** Iterates over all the keys and associated data. *) + val fold : + context -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(key -> value -> 'a -> 'a Lwt.t) -> + 'a Lwt.t + + (** Iterate over all the keys. *) + val fold_keys : + context -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(key -> 'a -> 'a Lwt.t) -> + 'a Lwt.t +end + +module type Indexed_data_snapshotable_storage = sig + type snapshot + + type key + + include Indexed_data_storage with type key := key + + module Snapshot : + Indexed_data_storage + with type key = snapshot * key + and type value = value + and type t = t + + val snapshot_exists : context -> snapshot -> bool Lwt.t + + val snapshot : context -> snapshot -> Raw_context.t tzresult Lwt.t + + val fold_snapshot : + context -> + snapshot -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(key -> value -> 'a -> 'a tzresult Lwt.t) -> + 'a tzresult Lwt.t + + val delete_snapshot : context -> snapshot -> Raw_context.t Lwt.t +end + +(** The generic signature of a data set accessor (a set of values + bound to a specific key prefix in the hierarchical (key x value) + database). *) +module type Data_set_storage = sig + type t + + type context = t + + (** The type of elements. *) + type elt + + (** Tells if a elt is a member of the set *) + val mem : context -> elt -> bool Lwt.t + + (** Adds a elt is a member of the set *) + val add : context -> elt -> Raw_context.t Lwt.t + + (** Removes a elt of the set ; does nothing if not a member *) + val remove : context -> elt -> Raw_context.t Lwt.t + + (** Returns the elements of the set, deserialized in a list in no + particular order. *) + val elements : context -> elt list Lwt.t + + (** Iterates over the elements of the set. *) + val fold : + context -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(elt -> 'a -> 'a Lwt.t) -> + 'a Lwt.t + + (** Removes all elements in the set *) + val clear : context -> Raw_context.t Lwt.t +end + +(** Variant of {!Data_set_storage} with gas accounting. *) +module type Carbonated_data_set_storage = sig + type t + + type context = t + + (** The type of elements. *) + type elt + + (** Tells whether an elt is a member of the set. + Consumes [Gas_repr.read_bytes_cost Z.zero] *) + val mem : context -> elt -> (Raw_context.t * bool) tzresult Lwt.t + + (** Adds an elt as a member of the set. + Consumes [Gas_repr.write_bytes_cost ]. + Returns the the new size. *) + val init : context -> elt -> (Raw_context.t * int) tzresult Lwt.t + + (** Removes an elt from the set ; does nothing if not a member. + Consumes [Gas_repr.write_bytes_cost Z.zero]. + Returns the freed size, and a boolean + indicating if a value was already associated to this key. *) + val remove : context -> elt -> (Raw_context.t * int * bool) tzresult Lwt.t + + val fold_keys_unaccounted : + context -> + order:[`Sorted | `Undefined] -> + init:'acc -> + f:(elt -> 'acc -> 'acc Lwt.t) -> + 'acc Lwt.t +end + +module type NAME = sig + val name : Raw_context.key +end + +module type VALUE = sig + type t + + val encoding : t Data_encoding.t +end + +module type REGISTER = sig + val ghost : bool +end + +module type Indexed_raw_context = sig + type t + + type context = t + + type key + + type 'a ipath + + val clear : context -> Raw_context.t Lwt.t + + val fold_keys : + context -> + order:[`Sorted | `Undefined] -> + init:'a -> + f:(key -> 'a -> 'a Lwt.t) -> + 'a Lwt.t + + val keys : context -> key list Lwt.t + + val remove : context -> key -> context Lwt.t + + val copy : context -> from:key -> to_:key -> context tzresult Lwt.t + + module Make_set (_ : REGISTER) (_ : NAME) : + Data_set_storage with type t = t and type elt = key + + module Make_map (_ : NAME) (V : VALUE) : + Indexed_data_storage with type t = t and type key = key and type value = V.t + + module Make_carbonated_map (_ : NAME) (V : VALUE) : + Non_iterable_indexed_carbonated_data_storage + with type t = t + and type key = key + and type value = V.t + + module Raw_context : Raw_context.T with type t = t ipath +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/.ocamlformat b/src/proto_012_PsiThaCa/lib_protocol/test/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/big_interpreter_stack.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/big_interpreter_stack.tz new file mode 100644 index 000000000000..24832df0827f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/big_interpreter_stack.tz @@ -0,0 +1,5 @@ +{ parameter unit ; + storage unit ; + code { CAR ; + { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { { {} ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; } ; + NIL operation; PAIR } } diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract.tz new file mode 100644 index 000000000000..48ba07e191fe --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract.tz @@ -0,0 +1,69 @@ +# This contract manages a shielded pool with a 1 to 1 conversion with respect to +# the tez, updated by a sapling transaction. The second parameter is an optional +# implicit account used to claim funds when unshielding. +storage (sapling_state 8); +parameter (list (pair (sapling_transaction 8) (option key_hash) ) ); +code { # Stack manipulation + UNPAIR; + NIL operation; + SWAP; + DIP { SWAP}; + AMOUNT ; + SWAP ; + DIP {SWAP} ; + ITER { UNPAIR; + DIP { SWAP }; + # We verify the transaction and update the storage if the transaction is + # valid. The shielded transactions are handled here. + # The new state is pushed on top of the stack in addition to the balance + # of the transaction. If the rest of the script goes well, this state + # will be the new state of the smart contract. + SAPLING_VERIFY_UPDATE; + # In the case of an invalid transaction, we stop. + ASSERT_SOME; + UNPAIR; + # Convert the balance in mutez, keeping the signed + # balance on top of the stack and the balance in mutez as the second + # element + DUP; + DIP { ABS; # in case of negative balance i.e. shielding + PUSH mutez 1; + MUL; }; + # We have three cases now: unshielding, shielding and transfers. + # If the balance is strictly positive (i.e. unshielding), we send funds + # to the given address. + # If no address is given (see ASSERT_SOME), we stop + IFGT { + DIIP { ASSERT_SOME; + IMPLICIT_ACCOUNT }; + SWAP; + DIP { UNIT; + TRANSFER_TOKENS; + SWAP; + # Stack manipulation to order. The operations will consist of the + # TRANSFER_TOKEN operation. + DIP {CONS} ;}; + } + # If the balance is negative or 0 (i.e. shielding or transfer), + # we verify the amount transferred in the transaction is exactly the + # balance of the verify_update output. It does enforce the conversion + # 1-1 between mutez and shielded token. + # No operation is executed. + { + DIIP {SWAP}; + DIP {SWAP}; + SWAP; + SUB_MUTEZ; ASSERT_SOME; + # As we transfer or shield token, an implicit account is not + # required. It is a good practice to verify. + # If an implicit account has been given, it might be an invalid + # operation or a call error. + DIIP { ASSERT_NONE;}; + SWAP; + }; + }; + DIP { + PUSH mutez 0; + ASSERT_CMPEQ;}; + SWAP; + PAIR} \ No newline at end of file diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_double.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_double.tz new file mode 100644 index 000000000000..89148c8c355f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_double.tz @@ -0,0 +1,33 @@ +storage (pair (sapling_state :left 8) (sapling_state :right 8) ); +parameter (pair bool (pair (sapling_transaction :left 8) (sapling_transaction :right 8)) ); +code { UNPAIR ; + UNPAIR ; + DIP {UNPAIR} ; + DIIIP {UNPAIR} ; + DIIP {SWAP} ; + IF { SAPLING_VERIFY_UPDATE ; + ASSERT_SOME ; + UNPAIR ; + DROP ; + DIP {DIP {DUP}; + SAPLING_VERIFY_UPDATE; + ASSERT_SOME ; + UNPAIR ; + DROP ; + DROP;}; + } + { DIP { DUP}; + SAPLING_VERIFY_UPDATE; + ASSERT_SOME; + UNPAIR; + DROP; + DROP ; + DIP { SAPLING_VERIFY_UPDATE ; + ASSERT_SOME ; + UNPAIR; + DROP ; + }}; + PAIR; + NIL operation; + PAIR; + } diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_drop.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_drop.tz new file mode 100644 index 000000000000..b7e1b3912ff9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_drop.tz @@ -0,0 +1,14 @@ +storage (unit); +parameter (list (sapling_transaction 8)); +code { UNPAIR ; + SAPLING_EMPTY_STATE 8; + SWAP ; + ITER { SAPLING_VERIFY_UPDATE ; + ASSERT_SOME ; + UNPAIR ; + DROP ; + } ; + DROP ; + NIL operation; + PAIR; + } diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_send.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_send.tz new file mode 100644 index 000000000000..6eedc9dbc619 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_send.tz @@ -0,0 +1,20 @@ +storage (unit); +parameter (pair (contract (or (sapling_transaction 8) (sapling_state 8))) (sapling_transaction 8)); +code { UNPAIR ; + UNPAIR; + SWAP ; + SAPLING_EMPTY_STATE 8; + SWAP ; + SAPLING_VERIFY_UPDATE ; + ASSERT_SOME ; + UNPAIR ; + DROP ; + PUSH mutez 0; + SWAP ; + RIGHT (sapling_transaction 8); + TRANSFER_TOKENS; + NIL operation; + SWAP; + CONS; + PAIR; + } diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_state_as_arg.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_state_as_arg.tz new file mode 100644 index 000000000000..e8a96df046ee --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_contract_state_as_arg.tz @@ -0,0 +1,18 @@ +storage (option (sapling_transaction 8)); +parameter (or (sapling_transaction 8) (sapling_state 8)); +code { UNPAIR ; + IF_LEFT + { + DIP {DROP;}; + SOME; + } + { DIP {ASSERT_SOME;}; + SWAP ; + SAPLING_VERIFY_UPDATE; + ASSERT_SOME; + DROP ; + NONE (sapling_transaction 8) ; + }; + NIL operation; + PAIR; + } diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_push_sapling_state.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_push_sapling_state.tz new file mode 100644 index 000000000000..8d1db432bf2e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_push_sapling_state.tz @@ -0,0 +1,11 @@ +# Attempt to use `PUSH sapling_state 0` where 0 is the ID of a sapling state. +# sapling_state is not allowed in the instruction PUSH. +parameter unit; +storage unit; +code { DROP; + PUSH (sapling_state 8) 0; + DROP; + PUSH unit Unit; + NIL operation; + PAIR; + } diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_use_existing_state.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_use_existing_state.tz new file mode 100644 index 000000000000..b637870653f8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/sapling_use_existing_state.tz @@ -0,0 +1,12 @@ +parameter (pair (sapling_transaction 8) (sapling_state 8)); +storage (sapling_state 8); +code { UNPAIR; + UNPAIR; + DIIP { DROP }; + SAPLING_VERIFY_UPDATE; + ASSERT_SOME; + UNPAIR; + DROP; + NIL operation; + PAIR; + } diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/temp_big_maps.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/temp_big_maps.tz new file mode 100644 index 000000000000..0a9162f8f982 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/temp_big_maps.tz @@ -0,0 +1,81 @@ +# Testing passing/originating with big maps from different sources +# This contract is used by test_temp_big_maps.ml + +# The left member of the parameter is either: +# - (Left True) to use a fresh big map +# - (Left False) to use the stored big map +# - (Right bigmap) to use the passed big map + +# The right member of the parameter is used to decide between: +# - passing the argument (positive value) +# - doing nothing (zero) +# - originating (negative value) + +parameter (pair (or bool (big_map int int)) int); +storage (big_map int int); +code + { # parameter * storage :: [] + UNPAIR; # parameter :: storage :: [] + UNPAIR; # parameter.fst :: parameter.snd :: storage :: [] + DIP { SWAP }; # parameter.fst :: storage :: parameter.snd :: [] + IF_LEFT + { # parameter.fst.Left :: storage :: parameter.snd :: [] + IF + { # storage :: parameter.snd :: [] + DROP; # parameter.snd :: [] + EMPTY_BIG_MAP int int; # empty_big_map :: parameter.snd :: [] + PUSH (option int) (Some 2); # Some 2 :: empty_big_map :: parameter.snd :: [] + PUSH int 1; # 1 :: Some 2 :: empty_big_map :: parameter.snd :: [] + UPDATE; # big_map { 1 -> 2 } :: parameter.snd :: [] + } + { # stored_big_map :: parameter.snd :: [] + } + } + { # parameter.fst.Right :: storage :: parameter.snd :: [] + DIP { DROP } # passed_big_map :: parameter.snd :: [] + }; + DUP; # big_map :: big_map :: parameter.snd :: [] + DIG 2; # parameter.snd :: big_map :: big_map :: [] + DUP; # parameter.snd :: parameter.snd :: big_map :: big_map :: [] + IFGT + { # parameter.snd :: big_map :: big_map :: [] + PUSH int -1; + ADD; # parameter.snd - 1 :: big_map :: big_map :: [] + SWAP; # big_map :: parameter.snd - 1 :: big_map :: [] + RIGHT bool ; # Right big_map :: parameter.snd - 1 :: big_map :: [] + PAIR; # Right big_map * (parameter.snd - 1) :: big_map :: [] + DIP { SELF; PUSH mutez 0; }; # Right big_map * (parameter.snd - 1) :: 0 mutez :: self :: big_map :: [] + TRANSFER_TOKENS; # transfer_tokens :: big_map :: [] + NIL operation; # nil_operation :: transfer_tokens :: big_map :: [] + SWAP; # transfer_tokens :: nil_operation :: big_map :: [] + CONS # list operation :: big_map :: [] + } + { # parameter.snd :: big_map :: big_map :: [] + IFEQ + { # big_map :: big_map :: [] + DROP; # big_map :: [] + NIL operation; # list operation :: big_map :: [] + } + { # big_map :: big_map :: [] + PUSH mutez 0; # 0 mutez :: big_map :: big_map :: [] + NONE key_hash; # None key_hash :: 0 mutez :: big_map :: big_map :: [] + CREATE_CONTRACT + { + parameter unit; + storage (big_map int int); + code + { + UNPAIR; + DROP; + NIL operation; + PAIR + } + }; # create_contract :: address :: big_map :: [] + DIP { DROP }; # create_contract :: big_map :: [] + NIL operation; # nil_operation :: create_contract :: big_map :: [] + SWAP; # create_contract :: nil_operation :: big_map :: [] + CONS # list operation :: big_map :: [] + }; + }; + PAIR # (list operation * big_map) :: [] + } diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/contracts/timelock.tz b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/timelock.tz new file mode 100644 index 000000000000..2ddad4258117 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/contracts/timelock.tz @@ -0,0 +1,31 @@ +# This contract takes a chest and chest key as parameter. +# It tries to open it and stores the resulting bytes if successful. +# Otherwise it stores some hardcoded bytes to test that we are in +# the expected branch +storage (bytes); +parameter (pair (chest_key) (chest)); +code { + UNPAIR; + DIP {DROP}; + UNPAIR; + DIIP {PUSH nat 1000}; + OPEN_CHEST; + IF_LEFT + { # successful case + NIL operation; + PAIR ; + } + { + IF + { # first type of failure + PUSH bytes 0x01; + NIL operation; + PAIR; + } + { # second type of failure + PUSH bytes 0x00; + NIL operation; + PAIR; + } + } + } diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/dune b/src/proto_012_PsiThaCa/lib_protocol/test/dune new file mode 100644 index 000000000000..e45d4c01c09a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/dune @@ -0,0 +1,80 @@ +(tests + (names main + saturation_fuzzing + test_gas_properties + test_tez_repr + liquidity_baking_pbt + test_script_comparison + test_sampler) + (package tezos-protocol-012-PsiThaCa-tests) + (deps (glob_files contracts/*)) + (libraries tezos-base + tezos-micheline + tezos-protocol-environment + alcotest-lwt + tezos-test-helpers + qcheck-alcotest + tezos-012-PsiThaCa-test-helpers + tezos-stdlib-unix + tezos-client-base + tezos-protocol-012-PsiThaCa-parameters + tezos-base-test-helpers + tezos-sapling + astring + tezos-protocol-plugin-012-PsiThaCa + tezos-benchmark + tezos-benchmark-012-PsiThaCa) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_micheline + -open Tezos_client_012_PsiThaCa + -open Tezos_protocol_012_PsiThaCa + -open Tezos_protocol_012_PsiThaCa_parameters + -open Tezos_protocol_plugin_012_PsiThaCa + -open Tezos_protocol_environment_012_PsiThaCa + -open Tezos_benchmark_012_PsiThaCa + -open Tezos_benchmark_type_inference_012_PsiThaCa + -open Tezos_012_PsiThaCa_test_helpers + -open Tezos_base_test_helpers))) + +(rule + (copy %{lib:tezos-protocol-012-PsiThaCa-parameters:test-parameters.json} + protocol_parameters.json)) + +; runs both `Quick and `Slow tests +(rule + (alias runtest_proto_012_PsiThaCa) + (deps (glob_files contracts/*)) + (package tezos-protocol-012-PsiThaCa-tests) + (action (run %{exe:main.exe}))) + +; runs only the `Quick tests +(rule + (alias runtest_quick) + (deps (glob_files contracts/*)) + (package tezos-protocol-012-PsiThaCa-tests) + (action (run %{exe:main.exe} -q))) + +(rule + (alias runtest_saturation_fuzzing) + (package tezos-protocol-012-PsiThaCa-tests) + (action (run %{exe:saturation_fuzzing.exe}))) + +(rule + (alias runtest_sampler) + (package tezos-protocol-012-PsiThaCa-tests) + (action (run %{exe:test_sampler.exe}))) + +(rule + (alias runtest_test_script_comparison) + (package tezos-protocol-012-PsiThaCa-tests) + (action (run %{exe:test_script_comparison.exe}))) + +(rule + (alias runtest_test_tez_repr) + (package tezos-protocol-012-PsiThaCa-tests) + (action (run %{exe:test_tez_repr.exe}))) + +(rule + (alias runtest_liquidity_baking_pbt) + (package tezos-protocol-012-PsiThaCa-tests) + (action (run %{exe:liquidity_baking_pbt.exe}))) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/.ocamlformat b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/README.md b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/README.md new file mode 100644 index 000000000000..b071cfb4ec03 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/README.md @@ -0,0 +1,3 @@ +## Helpers to build unit/integration tests for the protocol + +The OPAM package `tezos-alpha-test-helpers` contains helpers to build unit/integration tests, like forging a block, a context, nonces, operations, etc. diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/account.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/account.ml new file mode 100644 index 000000000000..47e8e5a2e7ec --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/account.ml @@ -0,0 +1,115 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type t = { + pkh : Signature.Public_key_hash.t; + pk : Signature.Public_key.t; + sk : Signature.Secret_key.t; +} + +type account = t + +let known_accounts = Signature.Public_key_hash.Table.create 17 + +let random_seed ~rng_state = + Bytes.init Hacl.Ed25519.sk_size (fun _i -> + Char.chr (Random.State.int rng_state 256)) + +let new_account ?seed () = + let (pkh, pk, sk) = Signature.generate_key ~algo:Ed25519 ?seed () in + let account = {pkh; pk; sk} in + Signature.Public_key_hash.Table.add known_accounts pkh account ; + account + +let add_account ({pkh; _} as account) = + Signature.Public_key_hash.Table.add known_accounts pkh account + +let activator_account = + let seed = random_seed ~rng_state:(Random.State.make [|0x1337533D|]) in + new_account ~seed () + +let find pkh = + match Signature.Public_key_hash.Table.find known_accounts pkh with + | Some k -> return k + | None -> failwith "Missing account: %a" Signature.Public_key_hash.pp pkh + +let find_alternate pkh = + let exception Found of t in + try + Signature.Public_key_hash.Table.iter + (fun pkh' account -> + if not (Signature.Public_key_hash.equal pkh pkh') then + raise (Found account)) + known_accounts ; + raise Not_found + with Found account -> account + +let dummy_account = + let seed = + random_seed ~rng_state:(Random.State.make [|0x1337533D; 0x1337533D|]) + in + new_account ~seed () + +let default_initial_balance = Tez.of_mutez_exn 4_000_000_000_000L + +let generate_accounts ?rng_state ?(initial_balances = []) n : (t * Tez.t) list = + Signature.Public_key_hash.Table.clear known_accounts ; + let amount i = + match List.nth_opt initial_balances i with + | None -> default_initial_balance + | Some a -> Tez.of_mutez_exn a + in + let rng_state = + match rng_state with + | None -> Random.State.make_self_init () + | Some state -> state + in + List.map + (fun i -> + let (pkh, pk, sk) = + Signature.generate_key ~algo:Ed25519 ~seed:(random_seed ~rng_state) () + in + let account = {pkh; pk; sk} in + Signature.Public_key_hash.Table.add known_accounts pkh account ; + (account, amount i)) + (0 -- (n - 1)) + +let commitment_secret = + Blinded_public_key_hash.activation_code_of_hex + "aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbb" + |> WithExceptions.Option.get ~loc:__LOC__ + +let new_commitment ?seed () = + let (pkh, pk, sk) = Signature.generate_key ?seed ~algo:Ed25519 () in + let unactivated_account = {pkh; pk; sk} in + let open Commitment in + let pkh = match pkh with Ed25519 pkh -> pkh | _ -> assert false in + let bpkh = Blinded_public_key_hash.of_ed25519_pkh commitment_secret pkh in + Lwt.return + ( (Environment.wrap_tzresult @@ Tez.(one *? 4_000L)) >|? fun amount -> + (unactivated_account, {blinded_public_key_hash = bpkh; amount}) ) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/account.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/account.mli new file mode 100644 index 000000000000..f327344fcfbb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/account.mli @@ -0,0 +1,68 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type t = { + pkh : Signature.Public_key_hash.t; + pk : Signature.Public_key.t; + sk : Signature.Secret_key.t; +} + +type account = t + +val known_accounts : t Signature.Public_key_hash.Table.t + +val activator_account : account + +val dummy_account : account + +val new_account : ?seed:Bytes.t -> unit -> account + +val add_account : t -> unit + +val find : Signature.Public_key_hash.t -> t tzresult Lwt.t + +val find_alternate : Signature.Public_key_hash.t -> t + +(** 4.000.000.000 tez *) +val default_initial_balance : Tez.t + +(** [generate_accounts ?initial_balances n] : generates [n] random + accounts with the initial balance of the [i]th account given by the + [i]th value in the list [initial_balances] or otherwise + [default_initial_balance] tz (if the list is too short); and add them to the + global account state *) +val generate_accounts : + ?rng_state:Random.State.t -> + ?initial_balances:int64 list -> + int -> + (t * Tez.t) list + +val commitment_secret : Blinded_public_key_hash.activation_code + +val new_commitment : + ?seed:Bytes.t -> unit -> (account * Commitment.t) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/assert.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/assert.ml new file mode 100644 index 000000000000..a68d43f6f3b9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/assert.ml @@ -0,0 +1,178 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +let error ~loc v f = + match v with + | Error err when List.exists f err -> return_unit + | Ok _ -> failwith "Unexpected successful result (%s)" loc + | Error err -> failwith "@[Unexpected error (%s): %a@]" loc pp_print_trace err + +let test_error_encodings e = + let module E = Environment.Error_monad in + ignore (E.pp Format.str_formatter e) ; + let e' = E.json_of_error e |> E.error_of_json in + assert (e = e') + +let proto_error ~loc v f = + error ~loc v (function + | Environment.Ecoproto_error err -> + test_error_encodings err ; + f err + | _ -> false) + +let proto_error_with_info ~loc res error_title = + proto_error ~loc res (function err -> + error_title + = (Error_monad.find_info_of_error (Environment.wrap_tzerror err)).title) + +let equal ~loc (cmp : 'a -> 'a -> bool) msg pp a b = + if not (cmp a b) then + failwith "@[@[[%s]@] - @[%s : %a is not equal to %a@]@]" loc msg pp a pp b + else return_unit + +let leq ~loc (cmp : 'a -> 'a -> int) msg pp a b = + if cmp a b > 0 then + failwith + "@[@[[%s]@] - @[%s : %a is not less or equal to %a@]@]" + loc + msg + pp + a + pp + b + else return_unit + +let not_equal ~loc (cmp : 'a -> 'a -> bool) msg pp a b = + if cmp a b then + failwith "@[@[[%s]@] - @[%s : %a is equal to %a@]@]" loc msg pp a pp b + else return_unit + +module Int32 = struct + include Int32 + + let pp pp v = Format.pp_print_int pp (Int32.to_int v) +end + +module Int64 = struct + include Int64 + + let pp pp v = Format.pp_print_int pp (Int64.to_int v) +end + +(* int *) +let equal_int ~loc (a : int) (b : int) = + equal ~loc Int.equal "Integers aren't equal" Format.pp_print_int a b + +let not_equal_int ~loc (a : int) (b : int) = + not_equal ~loc Int.equal "Integers are equal" Format.pp_print_int a b + +let leq_int ~loc (a : int) (b : int) = + leq ~loc Compare.Int.compare "Integer comparison" Format.pp_print_int a b + +(* int32 *) +let equal_int32 ~loc (a : int32) (b : int32) = + equal ~loc Int32.equal "Int32 aren't equal" Int32.pp a b + +(* int64 *) +let equal_int64 ~loc (a : int64) (b : int64) = + equal ~loc Compare.Int64.( = ) "Int64 aren't equal" Int64.pp a b + +let not_equal_int64 ~loc (a : int64) (b : int64) = + not_equal ~loc Int64.equal "Int64 are equal" Int64.pp a b + +let leq_int64 ~loc (a : int64) (b : int64) = + leq ~loc Compare.Int64.compare "Int64 comparison" Int64.pp a b + +(* bool *) +let equal_bool ~loc (a : bool) (b : bool) = + equal ~loc Bool.equal "Booleans aren't equal" Format.pp_print_bool a b + +let not_equal_bool ~loc (a : bool) (b : bool) = + not_equal ~loc Bool.equal "Booleans are equal" Format.pp_print_bool a b + +(* tez *) +let equal_tez ~loc (a : Alpha_context.Tez.t) (b : Alpha_context.Tez.t) = + let open Alpha_context in + equal ~loc Tez.( = ) "Tez aren't equal" Tez.pp a b + +let not_equal_tez ~loc (a : Alpha_context.Tez.t) (b : Alpha_context.Tez.t) = + let open Alpha_context in + not_equal ~loc Tez.( = ) "Tez are equal" Tez.pp a b + +(* pkh *) +let equal_pkh ~loc (a : Signature.Public_key_hash.t) + (b : Signature.Public_key_hash.t) = + let module PKH = Signature.Public_key_hash in + equal ~loc PKH.equal "Public key hashes aren't equal" PKH.pp a b + +let not_equal_pkh ~loc (a : Signature.Public_key_hash.t) + (b : Signature.Public_key_hash.t) = + let module PKH = Signature.Public_key_hash in + not_equal ~loc PKH.equal "Public key hashes are equal" PKH.pp a b + +let get_some ~loc = function + | Some x -> return x + | None -> failwith "Unexpected None (%s)" loc + +let is_none ~loc ~pp = function + | Some x -> failwith "Unexpected (Some %a) (%s)" pp x loc + | None -> return_unit + +open Context + +(* Some asserts for account operations *) + +(** [balance_is b c amount] checks that the current balance of contract [c] is + [amount]. + Default balance type is [Main], pass [~kind] with [Deposit], [Fees] or + [Rewards] for the others. *) +let balance_is ~loc b contract expected = + Contract.balance b contract >>=? fun balance -> + equal_tez ~loc balance expected + +(** [balance_was_operated ~operand b c old_balance amount] checks that the + current balance of contract [c] is [operand old_balance amount] and + returns the current balance. + Default balance type is [Main], pass [~kind] with [Deposit], [Fees] or + [Rewards] for the others. *) +let balance_was_operated ~operand ~loc b contract old_balance amount = + operand old_balance amount |> Environment.wrap_tzresult >>?= fun expected -> + balance_is ~loc b contract expected + +let balance_was_credited = + balance_was_operated ~operand:Alpha_context.Tez.( +? ) + +let balance_was_debited = balance_was_operated ~operand:Alpha_context.Tez.( -? ) + +let pp_print_list pp out xs = + let list_pp fmt = + Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ";@.") fmt + in + Format.fprintf out "[%a]" (list_pp pp) xs + +let assert_equal_list ~loc eq msg pp = + equal ~loc (List.equal eq) msg (pp_print_list pp) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/block.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/block.ml new file mode 100644 index 000000000000..119ddd6dda03 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/block.ml @@ -0,0 +1,759 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +module Proto_Nonce = Nonce (* Renamed otherwise is masked by Alpha_context *) + +open Alpha_context + +(* This type collects a block and the context that results from its application *) +type t = { + hash : Block_hash.t; + header : Block_header.t; + operations : Operation.packed list; + context : Tezos_protocol_environment.Context.t; +} + +type block = t + +let rpc_context block = + { + Environment.Updater.block_hash = block.hash; + block_header = block.header.shell; + context = block.context; + } + +let rpc_ctxt = + new Environment.proto_rpc_context_of_directory + rpc_context + Plugin.RPC.rpc_services + +(******** Policies ***********) + +(* Policies are functions that take a block and return a tuple + [(account, level, timestamp)] for the [forge_header] function. *) + +(* This type is used only to provide a simpler interface to the exterior. *) +type baker_policy = + | By_round of int + | By_account of public_key_hash + | Excluding of public_key_hash list + +type baking_mode = Application | Baking + +let get_next_baker_by_round round block = + Plugin.RPC.Baking_rights.get rpc_ctxt ~all:true ~max_round:(round + 1) block + >|=? fun bakers -> + let {Plugin.RPC.Baking_rights.delegate = pkh; timestamp; _} = + WithExceptions.Option.get ~loc:__LOC__ + @@ List.find + (fun {Plugin.RPC.Baking_rights.round = r; _} -> r = round) + bakers + in + (pkh, round, WithExceptions.Option.to_exn ~none:(Failure "") timestamp) + +let get_next_baker_by_account pkh block = + Plugin.RPC.Baking_rights.get rpc_ctxt ~delegates:[pkh] block + >>=? fun bakers -> + (match List.hd bakers with + | Some b -> return b + | None -> failwith "No slots found for %a" Signature.Public_key_hash.pp pkh) + >>=? fun {Plugin.RPC.Baking_rights.delegate = pkh; timestamp; round; _} -> + return + (pkh, round, WithExceptions.Option.to_exn ~none:(Failure __LOC__) timestamp) + +let get_next_baker_excluding excludes block = + Plugin.RPC.Baking_rights.get rpc_ctxt block >|=? fun bakers -> + let {Plugin.RPC.Baking_rights.delegate = pkh; timestamp; round; _} = + WithExceptions.Option.get ~loc:__LOC__ + @@ List.find + (fun {Plugin.RPC.Baking_rights.delegate; _} -> + not + (List.mem ~equal:Signature.Public_key_hash.equal delegate excludes)) + bakers + in + (pkh, round, WithExceptions.Option.to_exn ~none:(Failure "") timestamp) + +let dispatch_policy = function + | By_round r -> get_next_baker_by_round r + | By_account a -> get_next_baker_by_account a + | Excluding al -> get_next_baker_excluding al + +let get_next_baker ?(policy = By_round 0) = dispatch_policy policy + +let get_round (b : t) = + let fitness = b.header.shell.fitness in + Fitness.(from_raw fitness >|? round) |> Environment.wrap_tzresult + +module Forge = struct + type header = { + baker : public_key_hash; + (* the signer of the block *) + shell : Block_header.shell_header; + contents : Block_header.contents; + } + + let default_proof_of_work_nonce = + Bytes.create Constants.proof_of_work_nonce_size + + let make_contents ?(proof_of_work_nonce = default_proof_of_work_nonce) + ~payload_hash ~payload_round ?(liquidity_baking_escape_vote = false) + ~seed_nonce_hash () = + Block_header. + { + payload_hash; + payload_round; + proof_of_work_nonce; + seed_nonce_hash; + liquidity_baking_escape_vote; + } + + let make_shell ~level ~predecessor ~timestamp ~fitness ~operations_hash = + Tezos_base.Block_header. + { + level; + predecessor; + timestamp; + fitness; + operations_hash; + (* We don't care of the following values, only the shell validates them. *) + proto_level = 0; + validation_passes = 0; + context = Context_hash.zero; + } + + let set_seed_nonce_hash seed_nonce_hash {baker; shell; contents} = + {baker; shell; contents = {contents with seed_nonce_hash}} + + let set_baker baker header = {header with baker} + + let sign_header {baker; shell; contents} = + Account.find baker >|=? fun delegate -> + let unsigned_bytes = + Data_encoding.Binary.to_bytes_exn + Block_header.unsigned_encoding + (shell, contents) + in + let signature = + Signature.sign + ~watermark:Block_header.(to_watermark (Block_header Chain_id.zero)) + delegate.sk + unsigned_bytes + in + Block_header.{shell; protocol_data = {contents; signature}} + + let classify_operations operations = + let validation_passes_len = List.length Main.validation_passes in + let t = Array.make validation_passes_len [] in + List.iter + (fun (op : packed_operation) -> + List.iter + (fun pass -> t.(pass) <- op :: t.(pass)) + (Main.acceptable_passes op)) + operations ; + let t = Array.map List.rev t in + Array.to_list t + + let forge_header ?(locked_round = None) ?(payload_round = None) + ?(policy = By_round 0) ?timestamp ?(operations = []) + ?liquidity_baking_escape_vote pred = + let pred_fitness = + match Fitness.from_raw pred.header.shell.fitness with + | Ok pred_fitness -> pred_fitness + | _ -> assert false + in + let predecessor_round = Fitness.round pred_fitness in + dispatch_policy policy pred >>=? fun (pkh, round, expected_timestamp) -> + let timestamp = Option.value ~default:expected_timestamp timestamp in + let level = Int32.succ pred.header.shell.level in + Raw_level.of_int32 level |> Environment.wrap_tzresult >>?= fun raw_level -> + Round.of_int round |> Environment.wrap_tzresult >>?= fun round -> + Fitness.create ~level:raw_level ~predecessor_round ~round ~locked_round + >|? Fitness.to_raw |> Environment.wrap_tzresult + >>?= fun fitness -> + (Plugin.RPC.current_level ~offset:1l rpc_ctxt pred >|=? function + | {expected_commitment = true; _} -> Some (fst (Proto_Nonce.generate ())) + | {expected_commitment = false; _} -> None) + >|=? fun seed_nonce_hash -> + let hashes = List.map Operation.hash_packed operations in + let operations_hash = + Operation_list_list_hash.compute [Operation_list_hash.compute hashes] + in + let shell = + make_shell + ~level + ~predecessor:pred.hash + ~timestamp + ~fitness + ~operations_hash + in + let operations = classify_operations operations in + let non_consensus_operations = + List.concat (match List.tl operations with None -> [] | Some l -> l) + in + let hashes = List.map Operation.hash_packed non_consensus_operations in + let non_consensus_operations_hash = Operation_list_hash.compute hashes in + let payload_round = + match payload_round with None -> round | Some r -> r + in + let payload_hash = + Block_payload.hash + ~predecessor:shell.predecessor + payload_round + non_consensus_operations_hash + in + let contents = + make_contents + ~seed_nonce_hash + ?liquidity_baking_escape_vote + ~payload_hash + ~payload_round + () + in + {baker = pkh; shell; contents} + + (* compatibility only, needed by incremental *) + let contents ?(proof_of_work_nonce = default_proof_of_work_nonce) + ?seed_nonce_hash ?(liquidity_baking_escape_vote = false) ~payload_hash + ~payload_round () = + { + Block_header.proof_of_work_nonce; + seed_nonce_hash; + liquidity_baking_escape_vote; + payload_hash; + payload_round; + } +end + +(********* Genesis creation *************) + +(* Hard-coded context key *) +let protocol_param_key = ["protocol_parameters"] + +let check_constants_consistency constants = + let open Constants in + let {blocks_per_cycle; blocks_per_commitment; blocks_per_stake_snapshot; _} = + constants + in + Error_monad.unless (blocks_per_commitment <= blocks_per_cycle) (fun () -> + failwith + "Inconsistent constants : blocks per commitment must be less than \ + blocks per cycle") + >>=? fun () -> + Error_monad.unless (blocks_per_cycle >= blocks_per_stake_snapshot) (fun () -> + failwith + "Inconsistent constants : blocks per cycle must be superior than \ + blocks per roll snapshot") + +let prepare_main_init_params ?bootstrap_contracts commitments constants + initial_accounts = + let open Tezos_protocol_012_PsiThaCa_parameters in + let bootstrap_accounts = + List.map + (fun (Account.{pk; pkh; _}, amount) -> + Default_parameters.make_bootstrap_account (pkh, pk, amount)) + initial_accounts + in + let parameters = + Default_parameters.parameters_of_constants + ~bootstrap_accounts + ?bootstrap_contracts + ~commitments + constants + in + let json = Default_parameters.json_of_parameters parameters in + let proto_params = + Data_encoding.Binary.to_bytes_exn Data_encoding.json json + in + Tezos_protocol_environment.Context.( + let empty = Memory_context.empty in + add empty ["version"] (Bytes.of_string "genesis") >>= fun ctxt -> + add ctxt protocol_param_key proto_params) + +let initial_context ?(commitments = []) ?bootstrap_contracts constants header + initial_accounts = + prepare_main_init_params + ?bootstrap_contracts + commitments + constants + initial_accounts + >>= fun ctxt -> + Main.init ctxt header >|= Environment.wrap_tzresult >|=? fun {context; _} -> + context + +let initial_alpha_context ?(commitments = []) constants + (block_header : Block_header.shell_header) initial_accounts = + prepare_main_init_params commitments constants initial_accounts + >>= fun ctxt -> + let level = block_header.level in + let timestamp = block_header.timestamp in + let typecheck (ctxt : Alpha_context.context) (script : Alpha_context.Script.t) + = + let allow_forged_in_storage = + false + (* There should be no forged value in bootstrap contracts. *) + in + Script_ir_translator.parse_script + ctxt + ~legacy:true + ~allow_forged_in_storage + script + >>=? fun (Ex_script parsed_script, ctxt) -> + Script_ir_translator.extract_lazy_storage_diff + ctxt + Optimized + parsed_script.storage_type + parsed_script.storage + ~to_duplicate:Script_ir_translator.no_lazy_storage_id + ~to_update:Script_ir_translator.no_lazy_storage_id + ~temporary:false + >>=? fun (storage, lazy_storage_diff, ctxt) -> + Script_ir_translator.unparse_data + ctxt + Optimized + parsed_script.storage_type + storage + >|=? fun (storage, ctxt) -> + let storage = + Alpha_context.Script.lazy_expr (Micheline.strip_locations storage) + in + (({script with storage}, lazy_storage_diff), ctxt) + in + Main.init_cache ctxt >>= fun ctxt -> + Alpha_context.prepare_first_block ~typecheck ~level ~timestamp ctxt + >|= Environment.wrap_tzresult + +let genesis_with_parameters parameters = + let hash = + Block_hash.of_b58check_exn + "BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU" + in + let fitness = + Fitness_repr.create_without_locked_round + ~level:(Protocol.Raw_level_repr.of_int32_exn 0l) + ~predecessor_round:Round_repr.zero + ~round:Round_repr.zero + |> Fitness_repr.to_raw + in + let shell = + Forge.make_shell + ~level:0l + ~predecessor:hash + ~timestamp:Time.Protocol.epoch + ~fitness + ~operations_hash:Operation_list_list_hash.zero + in + let contents = + Forge.make_contents + ~payload_hash:Block_payload_hash.zero + ~payload_round:Round.zero + ~seed_nonce_hash:None + () + in + let open Tezos_protocol_012_PsiThaCa_parameters in + let json = Default_parameters.json_of_parameters parameters in + let proto_params = + Data_encoding.Binary.to_bytes_exn Data_encoding.json json + in + Tezos_protocol_environment.Context.( + let empty = Memory_context.empty in + add empty ["version"] (Bytes.of_string "genesis") >>= fun ctxt -> + add ctxt protocol_param_key proto_params) + >>= fun ctxt -> + Main.init ctxt shell >|= Environment.wrap_tzresult >|=? fun {context; _} -> + { + hash; + header = {shell; protocol_data = {contents; signature = Signature.zero}}; + operations = []; + context; + } + +let validate_initial_accounts (initial_accounts : (Account.t * Tez.t) list) + tokens_per_roll = + if initial_accounts = [] then + Stdlib.failwith "Must have one account with a roll to bake" ; + (* Check there is at least one roll *) + Lwt.catch + (fun () -> + List.fold_left_es + (fun acc (_, amount) -> + Environment.wrap_tzresult @@ Tez.( +? ) acc amount >>?= fun acc -> + if acc >= tokens_per_roll then raise Exit else return acc) + Tez.zero + initial_accounts + >>=? fun _ -> + failwith "Insufficient tokens in initial accounts to create one roll") + (function Exit -> return_unit | exc -> raise exc) + +let prepare_initial_context_params ?consensus_threshold ?min_proposal_quorum + ?level ?cost_per_byte ?liquidity_baking_subsidy ?endorsing_reward_per_slot + ?baking_reward_bonus_per_slot ?baking_reward_fixed_portion ?origination_size + ?blocks_per_cycle initial_accounts = + let open Tezos_protocol_012_PsiThaCa_parameters in + let constants = Default_parameters.constants_test in + let min_proposal_quorum = + Option.value ~default:constants.min_proposal_quorum min_proposal_quorum + in + let cost_per_byte = + Option.value ~default:constants.cost_per_byte cost_per_byte + in + let liquidity_baking_subsidy = + Option.value + ~default:constants.liquidity_baking_subsidy + liquidity_baking_subsidy + in + let endorsing_reward_per_slot = + Option.value + ~default:constants.endorsing_reward_per_slot + endorsing_reward_per_slot + in + let baking_reward_bonus_per_slot = + Option.value + ~default:constants.baking_reward_bonus_per_slot + baking_reward_bonus_per_slot + in + let baking_reward_fixed_portion = + Option.value + ~default:constants.baking_reward_fixed_portion + baking_reward_fixed_portion + in + let origination_size = + Option.value ~default:constants.origination_size origination_size + in + let blocks_per_cycle = + Option.value ~default:constants.blocks_per_cycle blocks_per_cycle + in + (* ?origination_size *) + let consensus_threshold = + Option.value ~default:constants.consensus_threshold consensus_threshold + in + let constants = + { + constants with + endorsing_reward_per_slot; + baking_reward_bonus_per_slot; + baking_reward_fixed_portion; + origination_size; + blocks_per_cycle; + min_proposal_quorum; + cost_per_byte; + liquidity_baking_subsidy; + consensus_threshold; + } + in + (* Check there is at least one roll *) + Lwt.catch + (fun () -> + List.fold_left_es + (fun acc (_, amount) -> + Environment.wrap_tzresult @@ Tez.( +? ) acc amount >>?= fun acc -> + if acc >= constants.tokens_per_roll then raise Exit else return acc) + Tez.zero + initial_accounts + >>=? fun _ -> + failwith "Insufficient tokens in initial accounts to create one roll") + (function Exit -> return_unit | exc -> raise exc) + >>=? fun () -> + check_constants_consistency constants >>=? fun () -> + let hash = + Block_hash.of_b58check_exn + "BLockGenesisGenesisGenesisGenesisGenesisCCCCCeZiLHU" + in + let level = Option.value ~default:0l level in + let fitness = + Fitness_repr.create_without_locked_round + ~level:(Protocol.Raw_level_repr.of_int32_exn level) + ~predecessor_round:Round_repr.zero + ~round:Round_repr.zero + |> Fitness_repr.to_raw + in + let shell = + Forge.make_shell + ~level + ~predecessor:hash + ~timestamp:Time.Protocol.epoch + ~fitness + ~operations_hash:Operation_list_list_hash.zero + in + validate_initial_accounts initial_accounts constants.tokens_per_roll + (* Perhaps this could return a new type signifying its name *) + >|=? fun _initial_accounts -> (constants, shell, hash) + +(* if no parameter file is passed we check in the current directory + where the test is run *) +let genesis ?commitments ?consensus_threshold ?min_proposal_quorum + ?bootstrap_contracts ?level ?cost_per_byte ?liquidity_baking_subsidy + ?endorsing_reward_per_slot ?baking_reward_bonus_per_slot + ?baking_reward_fixed_portion ?origination_size ?blocks_per_cycle + (initial_accounts : (Account.t * Tez.t) list) = + prepare_initial_context_params + ?consensus_threshold + ?min_proposal_quorum + ?level + ?cost_per_byte + ?liquidity_baking_subsidy + ?endorsing_reward_per_slot + ?baking_reward_bonus_per_slot + ?baking_reward_fixed_portion + ?origination_size + ?blocks_per_cycle + initial_accounts + >>=? fun (constants, shell, hash) -> + initial_context + ?commitments + ?bootstrap_contracts + constants + shell + initial_accounts + >|=? fun context -> + let contents = + Forge.make_contents + ~payload_hash:Block_payload_hash.zero + ~payload_round:Round.zero + ~seed_nonce_hash:None + () + in + { + hash; + header = {shell; protocol_data = {contents; signature = Signature.zero}}; + operations = []; + context; + } + +let alpha_context ?commitments ?min_proposal_quorum + (initial_accounts : (Account.t * Tez.t) list) = + prepare_initial_context_params ?min_proposal_quorum initial_accounts + >>=? fun (constants, shell, _hash) -> + initial_alpha_context ?commitments constants shell initial_accounts + +(********* Baking *************) + +(* Note that by calling this function without [protocol_data], we force the mode + to be partial construction (by correspondingly calling [begin_construction] + without [protocol_data]). *) +let get_application_vstate (pred : t) (operations : Protocol.operation trace) = + Forge.forge_header pred ~operations >>=? fun header -> + Forge.sign_header header >>=? fun header -> + let open Environment.Error_monad in + Main.begin_application + ~chain_id:Chain_id.zero + ~predecessor_context:pred.context + ~predecessor_fitness:pred.header.shell.fitness + ~predecessor_timestamp:pred.header.shell.timestamp + header + >|= Environment.wrap_tzresult + +let get_construction_vstate ?(policy = By_round 0) ?timestamp + ?(protocol_data = None) (pred : t) = + let open Protocol in + dispatch_policy policy pred >>=? fun (_pkh, _round, expected_timestamp) -> + let timestamp = Option.value ~default:expected_timestamp timestamp in + Main.begin_construction + ~chain_id:Chain_id.zero + ~predecessor_context:pred.context + ~predecessor_timestamp:pred.header.shell.timestamp + ~predecessor_level:pred.header.shell.level + ~predecessor_fitness:pred.header.shell.fitness + ~predecessor:pred.hash + ?protocol_data + ~timestamp + () + >|= Environment.wrap_tzresult + +let apply_with_metadata ?(policy = By_round 0) ~baking_mode header + ?(operations = []) pred = + let open Environment.Error_monad in + ( (match baking_mode with + | Application -> + Main.begin_application + ~chain_id:Chain_id.zero + ~predecessor_context:pred.context + ~predecessor_fitness:pred.header.shell.fitness + ~predecessor_timestamp:pred.header.shell.timestamp + header + >|= Environment.wrap_tzresult + | Baking -> + get_construction_vstate + ~policy + ~protocol_data:(Some header.protocol_data) + (pred : t)) + >>=? fun vstate -> + List.fold_left_es + (fun vstate op -> + apply_operation vstate op >|= Environment.wrap_tzresult + >|=? fun (state, _result) -> state) + vstate + operations + >>=? fun vstate -> + Main.finalize_block vstate (Some header.shell) >|= Environment.wrap_tzresult + >|=? fun (validation, result) -> (validation.context, result) ) + >|=? fun (context, result) -> + let hash = Block_header.hash header in + ({hash; header; operations; context}, result) + +let apply header ?(operations = []) pred = + apply_with_metadata header ~operations pred ~baking_mode:Application + >>=? fun (t, _metadata) -> return t + +let bake_with_metadata ?locked_round ?policy ?timestamp ?operation ?operations + ?payload_round ~baking_mode ?liquidity_baking_escape_vote pred = + let operations = + match (operation, operations) with + | (Some op, Some ops) -> Some (op :: ops) + | (Some op, None) -> Some [op] + | (None, Some ops) -> Some ops + | (None, None) -> None + in + Forge.forge_header + ?payload_round + ?locked_round + ?timestamp + ?policy + ?operations + ?liquidity_baking_escape_vote + pred + >>=? fun header -> + Forge.sign_header header >>=? fun header -> + apply_with_metadata ?policy ~baking_mode header ?operations pred + +let bake ?(baking_mode = Application) ?payload_round ?locked_round ?policy + ?timestamp ?operation ?operations ?liquidity_baking_escape_vote pred = + bake_with_metadata + ?payload_round + ~baking_mode + ?locked_round + ?policy + ?timestamp + ?operation + ?operations + ?liquidity_baking_escape_vote + pred + >>=? fun (t, (_metadata : block_header_metadata)) -> return t + +(********** Cycles ****************) + +(* This function is duplicated from Context to avoid a cyclic dependency *) +let get_constants b = Alpha_services.Constants.all rpc_ctxt b + +let bake_n ?(baking_mode = Application) ?policy ?liquidity_baking_escape_vote n + b = + List.fold_left_es + (fun b _ -> bake ~baking_mode ?policy ?liquidity_baking_escape_vote b) + b + (1 -- n) + +let bake_n_with_all_balance_updates ?(baking_mode = Application) ?policy + ?liquidity_baking_escape_vote n b = + List.fold_left_es + (fun (b, balance_updates_rev) _ -> + bake_with_metadata ~baking_mode ?policy ?liquidity_baking_escape_vote b + >>=? fun (b, metadata) -> + let balance_updates_rev = + List.rev_append metadata.balance_updates balance_updates_rev + in + let balance_updates_rev = + List.fold_left + (fun balance_updates_rev -> + let open Apply_results in + function + | Successful_manager_result (Reveal_result _) + | Successful_manager_result (Delegation_result _) -> + balance_updates_rev + | Successful_manager_result (Set_deposits_limit_result _) -> + balance_updates_rev + | Successful_manager_result + (Transaction_result {balance_updates; _}) + | Successful_manager_result + (Origination_result {balance_updates; _}) + | Successful_manager_result + (Register_global_constant_result {balance_updates; _}) -> + List.rev_append balance_updates balance_updates_rev) + balance_updates_rev + metadata.implicit_operations_results + in + return (b, balance_updates_rev)) + (b, []) + (1 -- n) + >|=? fun (b, balance_updates_rev) -> (b, List.rev balance_updates_rev) + +let bake_n_with_origination_results ?(baking_mode = Application) ?policy n b = + List.fold_left_es + (fun (b, origination_results_rev) _ -> + bake_with_metadata ~baking_mode ?policy b >>=? fun (b, metadata) -> + let origination_results_rev = + List.fold_left + (fun origination_results_rev -> + let open Apply_results in + function + | Successful_manager_result (Reveal_result _) + | Successful_manager_result (Delegation_result _) + | Successful_manager_result (Transaction_result _) + | Successful_manager_result (Register_global_constant_result _) + | Successful_manager_result (Set_deposits_limit_result _) -> + origination_results_rev + | Successful_manager_result (Origination_result x) -> + Origination_result x :: origination_results_rev) + origination_results_rev + metadata.implicit_operations_results + in + return (b, origination_results_rev)) + (b, []) + (1 -- n) + >|=? fun (b, origination_results_rev) -> (b, List.rev origination_results_rev) + +let bake_n_with_liquidity_baking_escape_ema ?(baking_mode = Application) ?policy + ?liquidity_baking_escape_vote n b = + List.fold_left_es + (fun (b, _escape_ema) _ -> + bake_with_metadata ~baking_mode ?policy ?liquidity_baking_escape_vote b + >|=? fun (b, metadata) -> (b, metadata.liquidity_baking_escape_ema)) + (b, 0l) + (1 -- n) + +let bake_until_cycle_end ?policy b = + get_constants b >>=? fun Constants.{parametric = {blocks_per_cycle; _}; _} -> + let current_level = b.header.shell.level in + let current_level = Int32.rem current_level blocks_per_cycle in + let delta = Int32.sub blocks_per_cycle current_level in + bake_n ?policy (Int32.to_int delta) b + +let bake_until_n_cycle_end ?policy n b = + List.fold_left_es (fun b _ -> bake_until_cycle_end ?policy b) b (1 -- n) + +let current_cycle b = + get_constants b >>=? fun Constants.{parametric = {blocks_per_cycle; _}; _} -> + let current_level = b.header.shell.level in + let current_cycle = Int32.div current_level blocks_per_cycle in + let current_cycle = Cycle.add Cycle.root (Int32.to_int current_cycle) in + return current_cycle + +let bake_until_cycle ?policy cycle (b : t) = + let rec loop (b : t) = + current_cycle b >>=? fun current_cycle -> + if Cycle.equal cycle current_cycle then return b + else bake_until_cycle_end ?policy b >>=? fun b -> loop b + in + loop b diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/block.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/block.mli new file mode 100644 index 000000000000..621252da276f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/block.mli @@ -0,0 +1,258 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type t = { + hash : Block_hash.t; + header : Block_header.t; + operations : Operation.packed list; + context : Tezos_protocol_environment.Context.t; (** Resulting context *) +} + +type block = t + +val rpc_ctxt : t Environment.RPC_context.simple + +(** Policies to select the next baker: + - [By_round r] selects the baker at round [r] + - [By_account pkh] selects the first slot for baker [pkh] + - [Excluding pkhs] selects the first baker that doesn't belong to [pkhs] +*) +type baker_policy = + | By_round of int + | By_account of public_key_hash + | Excluding of public_key_hash list + +(** + The default baking functions below is to use (blocks) [Application] mode. + Setting [baking_mode] allows to switch to [Full_construction] mode. +*) +type baking_mode = Application | Baking + +(** Returns (account, round, timestamp) of the next baker given + a policy, defaults to By_round 0. *) +val get_next_baker : + ?policy:baker_policy -> + t -> + (public_key_hash * int * Time.Protocol.t) tzresult Lwt.t + +val get_round : block -> Round.t tzresult + +module Forge : sig + val contents : + ?proof_of_work_nonce:Bytes.t -> + ?seed_nonce_hash:Nonce_hash.t -> + ?liquidity_baking_escape_vote:bool -> + payload_hash:Block_payload_hash.t -> + payload_round:Round.t -> + unit -> + Block_header.contents + + type header + + val classify_operations : packed_operation list -> packed_operation list list + + (** Forges a correct header following the policy. + The header can then be modified and applied with [apply]. *) + val forge_header : + ?locked_round:Alpha_context.Round.t option -> + ?payload_round:Round.t option -> + ?policy:baker_policy -> + ?timestamp:Timestamp.time -> + ?operations:Operation.packed list -> + ?liquidity_baking_escape_vote:bool -> + t -> + header tzresult Lwt.t + + (** Sets uniquely seed_nonce_hash of a header *) + val set_seed_nonce_hash : Nonce_hash.t option -> header -> header + + (** Sets the baker that will sign the header to an arbitrary pkh *) + val set_baker : public_key_hash -> header -> header + + (** Signs the header with the key of the baker configured in the header. + The header can no longer be modified, only applied. *) + val sign_header : header -> Block_header.block_header tzresult Lwt.t +end + +val check_constants_consistency : Constants.parametric -> unit tzresult Lwt.t + +(** [genesis accounts] : generates an initial block with the + given constants [] and initializes [accounts] with their + associated amounts. +*) +val genesis : + ?commitments:Commitment.t list -> + ?consensus_threshold:int -> + ?min_proposal_quorum:int32 -> + ?bootstrap_contracts:Parameters.bootstrap_contract list -> + ?level:int32 -> + ?cost_per_byte:Tez.t -> + ?liquidity_baking_subsidy:Tez.t -> + ?endorsing_reward_per_slot:Tez.t -> + ?baking_reward_bonus_per_slot:Tez.t -> + ?baking_reward_fixed_portion:Tez.t -> + ?origination_size:int -> + ?blocks_per_cycle:int32 -> + (Account.t * Tez.tez) list -> + block tzresult Lwt.t + +val genesis_with_parameters : Parameters.t -> block tzresult Lwt.t + +(** [alpha_context accounts] : instantiates an alpha_context with the + given constants [] and initializes [accounts] with their + associated amounts. +*) +val alpha_context : + ?commitments:Commitment.t list -> + ?min_proposal_quorum:int32 -> + (Account.t * Tez.tez) list -> + Alpha_context.t tzresult Lwt.t + +(** + [get_application_vstate pred operations] constructs a protocol validation + environment for operations in application mode on top of the given block + with the given operations. It's a shortcut for [begin_application] +*) +val get_application_vstate : + t -> Protocol.operation list -> validation_state tzresult Lwt.t + +(** + [get_construction_vstate ?policy ?timestamp ?protocol_data pred] + constructs a protocol validation environment for operations in + construction mode on top of the given block. The mode is + full(baking)/partial(mempool) if [protocol_data] given/absent. It's a + shortcut for [begin_construction] + *) +val get_construction_vstate : + ?policy:baker_policy -> + ?timestamp:Timestamp.time -> + ?protocol_data:block_header_data option -> + block -> + validation_state tzresult Lwt.t + +(** applies a signed header and its operations to a block and + obtains a new block *) +val apply : + Block_header.block_header -> + ?operations:Operation.packed list -> + t -> + t tzresult Lwt.t + +(** + [bake b] returns a block [b'] which has as predecessor block [b]. + Optional parameter [policy] allows to pick the next baker in several ways. + This function bundles together [forge_header], [sign_header] and [apply]. + These functions should be used instead of bake to craft unusual blocks for + testing together with setters for properties of the headers. + For examples see seed.ml or double_baking.ml +*) +val bake : + ?baking_mode:baking_mode -> + ?payload_round:Round.t option -> + ?locked_round:Alpha_context.Round.t option -> + ?policy:baker_policy -> + ?timestamp:Timestamp.time -> + ?operation:Operation.packed -> + ?operations:Operation.packed list -> + ?liquidity_baking_escape_vote:bool -> + t -> + t tzresult Lwt.t + +(** Bakes [n] blocks. *) +val bake_n : + ?baking_mode:baking_mode -> + ?policy:baker_policy -> + ?liquidity_baking_escape_vote:bool -> + int -> + t -> + block tzresult Lwt.t + +(** Version of bake_n that returns a list of all balance updates included + in the metadata of baked blocks. **) +val bake_n_with_all_balance_updates : + ?baking_mode:baking_mode -> + ?policy:baker_policy -> + ?liquidity_baking_escape_vote:bool -> + int -> + t -> + (block * Alpha_context.Receipt.balance_updates) tzresult Lwt.t + +(** Version of bake_n that returns a list of all origination results + in the metadata of baked blocks. **) +val bake_n_with_origination_results : + ?baking_mode:baking_mode -> + ?policy:baker_policy -> + int -> + t -> + (block + * Alpha_context.Kind.origination + Apply_results.successful_manager_operation_result + list) + tzresult + Lwt.t + +(** Version of bake_n that returns the liquidity baking escape EMA after [n] blocks. **) +val bake_n_with_liquidity_baking_escape_ema : + ?baking_mode:baking_mode -> + ?policy:baker_policy -> + ?liquidity_baking_escape_vote:bool -> + int -> + t -> + (block * Alpha_context.Liquidity_baking.escape_ema) tzresult Lwt.t + +val current_cycle : t -> Cycle.t tzresult Lwt.t + +(** Given a block [b] at level [l] bakes enough blocks to complete a cycle, + that is [blocks_per_cycle - (l % blocks_per_cycle)]. *) +val bake_until_cycle_end : ?policy:baker_policy -> t -> t tzresult Lwt.t + +(** Bakes enough blocks to end [n] cycles. *) +val bake_until_n_cycle_end : + ?policy:baker_policy -> int -> t -> t tzresult Lwt.t + +(** Bakes enough blocks to reach the cycle. *) +val bake_until_cycle : ?policy:baker_policy -> Cycle.t -> t -> t tzresult Lwt.t + +(** Common util function to create parameters for [initial_context] function *) +val prepare_initial_context_params : + ?consensus_threshold:int -> + ?min_proposal_quorum:int32 -> + ?level:int32 -> + ?cost_per_byte:Tez.t -> + ?liquidity_baking_subsidy:Tez.t -> + ?endorsing_reward_per_slot:Tez.t -> + ?baking_reward_bonus_per_slot:Tez.t -> + ?baking_reward_fixed_portion:Tez.t -> + ?origination_size:int -> + ?blocks_per_cycle:int32 -> + (Account.t * Tez.t) list -> + ( Constants.parametric * Block_header.shell_header * Block_hash.t, + tztrace ) + result + Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/consensus_helpers.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/consensus_helpers.ml new file mode 100644 index 000000000000..ad62da449a9b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/consensus_helpers.ml @@ -0,0 +1,108 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +let test_consensus_operation ?construction_mode ?level ?block_payload_hash ?slot + ?round ~endorsed_block ~error_title ~is_preendorsement ~context ~loc () = + (if is_preendorsement then + Op.preendorsement + ~endorsed_block + ?block_payload_hash + ?level + ?slot + ?round + context + () + >|=? fun op -> Operation.pack op + else + Op.endorsement + ~endorsed_block + ?block_payload_hash + ?level + ?slot + ?round + context + () + >|=? fun op -> Operation.pack op) + >>=? fun op -> + match construction_mode with + | None -> + (* meaning Application mode *) + Block.bake ~operations:[op] endorsed_block >>= fun res -> + Assert.proto_error_with_info ~loc res error_title + | Some (pred, protocol_data) -> + (* meaning partial construction or full construction mode, depending on + [protocol_data] *) + Block.get_construction_vstate ~protocol_data pred >>=? fun vstate -> + apply_operation vstate op >|= Environment.wrap_tzresult >>= fun res -> + Assert.proto_error_with_info ~loc res error_title + +let delegate_of_first_slot b = + let module V = Plugin.RPC.Validators in + Context.get_endorsers b >|=? function + | {V.delegate; slots = s :: _ as slots; _} :: _ -> ((delegate, slots), s) + | _ -> assert false + +let delegate_of_slot slot b = + let module V = Plugin.RPC.Validators in + Context.get_endorsers b >|=? fun endorsers -> + List.find_map + (function + | {V.delegate; slots = s :: _ as slots; _} when Slot.equal s slot -> + Some (delegate, slots) + | _ -> None) + endorsers + |> function + | None -> assert false + | Some d -> d + +let test_consensus_op_for_next ~genesis ~kind ~next = + let dorsement ~endorsed_block ~delegate b = + match kind with + | `Preendorsement -> + Op.preendorsement ~endorsed_block ~delegate b () >|=? Operation.pack + | `Endorsement -> + Op.endorsement ~endorsed_block ~delegate b () >|=? Operation.pack + in + Block.bake genesis >>=? fun b1 -> + (match next with + | `Level -> Block.bake b1 + | `Round -> Block.bake ~policy:(By_round 1) genesis) + >>=? fun b2 -> + Incremental.begin_construction ~mempool_mode:true b1 >>=? fun inc -> + delegate_of_first_slot (B b1) >>=? fun (delegate, slot) -> + dorsement ~endorsed_block:b1 ~delegate (B genesis) >>=? fun operation -> + Incremental.add_operation inc operation >>=? fun inc -> + delegate_of_slot slot (B b2) >>=? fun delegate -> + dorsement ~endorsed_block:b2 ~delegate (B b1) >>=? fun operation -> + Incremental.add_operation inc operation >>= fun res -> + let error_title = + match next with + | `Level -> "Consensus operation for future level" + | `Round -> "Consensus operation for future round" + in + Assert.proto_error_with_info ~loc:__LOC__ res error_title diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/context.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/context.ml new file mode 100644 index 000000000000..4b27ddc8e949 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/context.ml @@ -0,0 +1,368 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type t = B of Block.t | I of Incremental.t + +let branch = function B b -> b.hash | I i -> (Incremental.predecessor i).hash + +let level = function B b -> b.header.shell.level | I i -> Incremental.level i + +let get_level ctxt = + level ctxt |> Raw_level.of_int32 |> Environment.wrap_tzresult + +let rpc_ctxt = + object + method call_proto_service0 + : 'm 'q 'i 'o. + ( ([< RPC_service.meth] as 'm), + Environment.RPC_context.t, + Environment.RPC_context.t, + 'q, + 'i, + 'o ) + RPC_service.t -> + t -> + 'q -> + 'i -> + 'o tzresult Lwt.t = + fun s pr q i -> + match pr with + | B b -> Block.rpc_ctxt#call_proto_service0 s b q i + | I b -> Incremental.rpc_ctxt#call_proto_service0 s b q i + + method call_proto_service1 + : 'm 'a 'q 'i 'o. + ( ([< RPC_service.meth] as 'm), + Environment.RPC_context.t, + Environment.RPC_context.t * 'a, + 'q, + 'i, + 'o ) + RPC_service.t -> + t -> + 'a -> + 'q -> + 'i -> + 'o tzresult Lwt.t = + fun s pr a q i -> + match pr with + | B bl -> Block.rpc_ctxt#call_proto_service1 s bl a q i + | I bl -> Incremental.rpc_ctxt#call_proto_service1 s bl a q i + + method call_proto_service2 + : 'm 'a 'b 'q 'i 'o. + ( ([< RPC_service.meth] as 'm), + Environment.RPC_context.t, + (Environment.RPC_context.t * 'a) * 'b, + 'q, + 'i, + 'o ) + RPC_service.t -> + t -> + 'a -> + 'b -> + 'q -> + 'i -> + 'o tzresult Lwt.t = + fun s pr a b q i -> + match pr with + | B bl -> Block.rpc_ctxt#call_proto_service2 s bl a b q i + | I bl -> Incremental.rpc_ctxt#call_proto_service2 s bl a b q i + + method call_proto_service3 + : 'm 'a 'b 'c 'q 'i 'o. + ( ([< RPC_service.meth] as 'm), + Environment.RPC_context.t, + ((Environment.RPC_context.t * 'a) * 'b) * 'c, + 'q, + 'i, + 'o ) + RPC_service.t -> + t -> + 'a -> + 'b -> + 'c -> + 'q -> + 'i -> + 'o tzresult Lwt.t = + fun s pr a b c q i -> + match pr with + | B bl -> Block.rpc_ctxt#call_proto_service3 s bl a b c q i + | I bl -> Incremental.rpc_ctxt#call_proto_service3 s bl a b c q i + end + +let get_endorsers ctxt = Plugin.RPC.Validators.get rpc_ctxt ctxt + +let get_endorser ctxt = + get_endorsers ctxt >|=? fun endorsers -> + let endorser = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd endorsers in + (endorser.delegate, endorser.slots) + +let get_endorser_n ctxt n = + Plugin.RPC.Validators.get rpc_ctxt ctxt >|=? fun endorsers -> + let endorser = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth endorsers n + in + (endorser.delegate, endorser.slots) + +let get_endorsing_power_for_delegate ctxt ?levels pkh = + Plugin.RPC.Validators.get rpc_ctxt ?levels ctxt >>=? fun endorsers -> + let rec find_slots_for_delegate = function + | [] -> return 0 + | {Plugin.RPC.Validators.delegate; slots; _} :: t -> + if Signature.Public_key_hash.equal delegate pkh then + return (List.length slots) + else find_slots_for_delegate t + in + find_slots_for_delegate endorsers + +let get_voting_power = Delegate_services.voting_power rpc_ctxt + +let get_total_voting_power = Alpha_services.Voting.total_voting_power rpc_ctxt + +let get_bakers ?(filter = fun _x -> true) ctxt = + Plugin.RPC.Baking_rights.get rpc_ctxt ctxt >|=? fun bakers -> + List.filter filter bakers + |> List.map (fun p -> p.Plugin.RPC.Baking_rights.delegate) + +let get_baker ctxt ~round = + get_bakers ~filter:(fun x -> x.round = round) ctxt >>=? fun bakers -> + (* there is only one baker for a given round *) + match bakers with [baker] -> return baker | _ -> assert false + +let get_seed_nonce_hash ctxt = + let header = + match ctxt with B {header; _} -> header | I i -> Incremental.header i + in + match header.protocol_data.contents.seed_nonce_hash with + | None -> failwith "No committed nonce" + | Some hash -> return hash + +let get_seed ctxt = Alpha_services.Seed.get rpc_ctxt ctxt + +let get_constants ctxt = Alpha_services.Constants.all rpc_ctxt ctxt + +let get_baking_reward_fixed_portion ctxt = + get_constants ctxt + >>=? fun {Constants.parametric = {baking_reward_fixed_portion; _}; _} -> + return baking_reward_fixed_portion + +let get_bonus_reward ctxt ~endorsing_power = + get_constants ctxt + >>=? fun { + Constants.parametric = + {baking_reward_bonus_per_slot; consensus_threshold; _}; + _; + } -> + let multiplier = max 0 (endorsing_power - consensus_threshold) in + return Test_tez.(baking_reward_bonus_per_slot *! Int64.of_int multiplier) + +let get_endorsing_reward ctxt ~expected_endorsing_power = + get_constants ctxt + >>=? fun {Constants.parametric = {endorsing_reward_per_slot; _}; _} -> + Lwt.return + (Environment.wrap_tzresult + Tez.(endorsing_reward_per_slot *? Int64.of_int expected_endorsing_power)) + +let get_liquidity_baking_subsidy ctxt = + get_constants ctxt + >>=? fun {Constants.parametric = {liquidity_baking_subsidy; _}; _} -> + return liquidity_baking_subsidy + +let get_liquidity_baking_cpmm_address ctxt = + Alpha_services.Liquidity_baking.get_cpmm_address rpc_ctxt ctxt + +(* Voting *) + +module Vote = struct + let get_ballots ctxt = Alpha_services.Voting.ballots rpc_ctxt ctxt + + let get_ballot_list ctxt = Alpha_services.Voting.ballot_list rpc_ctxt ctxt + + let get_current_period ctxt = + Alpha_services.Voting.current_period rpc_ctxt ctxt + + let get_current_quorum ctxt = + Alpha_services.Voting.current_quorum rpc_ctxt ctxt + + let get_listings ctxt = Alpha_services.Voting.listings rpc_ctxt ctxt + + let get_proposals ctxt = Alpha_services.Voting.proposals rpc_ctxt ctxt + + let get_current_proposal ctxt = + Alpha_services.Voting.current_proposal rpc_ctxt ctxt + + let get_protocol (b : Block.t) = + Tezos_protocol_environment.Context.get_protocol b.context + + let get_participation_ema (b : Block.t) = + Environment.Context.find b.context ["votes"; "participation_ema"] + >|= function + | None -> assert false + | Some bytes -> ok (TzEndian.get_int32 bytes 0) + + let set_participation_ema (b : Block.t) ema = + let bytes = Bytes.make 4 '\000' in + TzEndian.set_int32 bytes 0 ema ; + Environment.Context.add b.context ["votes"; "participation_ema"] bytes + >|= fun context -> {b with context} +end + +module Contract = struct + let pp = Alpha_context.Contract.pp + + let equal a b = Alpha_context.Contract.compare a b = 0 + + let pkh c = + Alpha_context.Contract.is_implicit c |> function + | Some p -> return p + | None -> failwith "pkh: only for implicit contracts" + + let balance ctxt contract = + Alpha_services.Contract.balance rpc_ctxt ctxt contract + + let counter ctxt contract = + match Contract.is_implicit contract with + | None -> invalid_arg "Helpers.Context.counter" + | Some mgr -> Alpha_services.Contract.counter rpc_ctxt ctxt mgr + + let manager _ contract = + match Contract.is_implicit contract with + | None -> invalid_arg "Helpers.Context.manager" + | Some pkh -> Account.find pkh + + let is_manager_key_revealed ctxt contract = + match Contract.is_implicit contract with + | None -> invalid_arg "Helpers.Context.is_manager_key_revealed" + | Some mgr -> + Alpha_services.Contract.manager_key rpc_ctxt ctxt mgr >|=? fun res -> + res <> None + + let delegate ctxt contract = + Alpha_services.Contract.delegate rpc_ctxt ctxt contract + + let delegate_opt ctxt contract = + Alpha_services.Contract.delegate_opt rpc_ctxt ctxt contract + + let storage ctxt contract = + Alpha_services.Contract.storage rpc_ctxt ctxt contract + + let script ctxt contract = + Alpha_services.Contract.script rpc_ctxt ctxt contract + >>=? fun {code; storage = _} -> + match Data_encoding.force_decode code with + | Some v -> return v + | None -> invalid_arg "Cannot force lazy script" + + let script_hash ctxt contract = + script ctxt contract >>=? fun script -> + let bytes = Data_encoding.Binary.to_bytes_exn Script.expr_encoding script in + return @@ Script_expr_hash.hash_bytes [bytes] +end + +module Delegate = struct + type info = Delegate_services.info = { + full_balance : Tez.t; + current_frozen_deposits : Tez.t; + frozen_deposits : Tez.t; + staking_balance : Tez.t; + frozen_deposits_limit : Tez.t option; + delegated_contracts : Alpha_context.Contract.t list; + delegated_balance : Tez.t; + deactivated : bool; + grace_period : Cycle.t; + voting_power : int32; + } + + let info ctxt pkh = Delegate_services.info rpc_ctxt ctxt pkh + + let full_balance ctxt pkh = Delegate_services.full_balance rpc_ctxt ctxt pkh + + let current_frozen_deposits ctxt pkh = + Delegate_services.current_frozen_deposits rpc_ctxt ctxt pkh + + let initial_frozen_deposits ctxt pkh = + Delegate_services.frozen_deposits rpc_ctxt ctxt pkh + + let staking_balance ctxt pkh = + Delegate_services.staking_balance rpc_ctxt ctxt pkh + + let frozen_deposits_limit ctxt pkh = + Delegate_services.frozen_deposits_limit rpc_ctxt ctxt pkh + + let deactivated ctxt pkh = Delegate_services.deactivated rpc_ctxt ctxt pkh + + let participation ctxt pkh = Delegate_services.participation rpc_ctxt ctxt pkh +end + +let init ?rng_state ?commitments ?(initial_balances = []) ?consensus_threshold + ?min_proposal_quorum ?bootstrap_contracts ?level ?cost_per_byte + ?liquidity_baking_subsidy ?endorsing_reward_per_slot + ?baking_reward_bonus_per_slot ?baking_reward_fixed_portion ?origination_size + ?blocks_per_cycle n = + let accounts = Account.generate_accounts ?rng_state ~initial_balances n in + let contracts = + List.map + (fun (a, _) -> Alpha_context.Contract.implicit_contract Account.(a.pkh)) + accounts + in + Block.genesis + ?commitments + ?consensus_threshold + ?min_proposal_quorum + ?bootstrap_contracts + ?level + ?cost_per_byte + ?liquidity_baking_subsidy + ?endorsing_reward_per_slot + ?baking_reward_bonus_per_slot + ?baking_reward_fixed_portion + ?origination_size + ?blocks_per_cycle + accounts + >|=? fun blk -> (blk, contracts) + +let init_with_constants constants n = + let accounts = Account.generate_accounts n in + let contracts = + List.map + (fun (a, _) -> Alpha_context.Contract.implicit_contract Account.(a.pkh)) + accounts + in + let open Tezos_protocol_012_PsiThaCa_parameters in + let bootstrap_accounts = + List.map + (fun (acc, tez) -> + Default_parameters.make_bootstrap_account + (acc.Account.pkh, acc.Account.pk, tez)) + accounts + in + let parameters = + Default_parameters.parameters_of_constants ~bootstrap_accounts constants + in + Block.genesis_with_parameters parameters >|=? fun blk -> (blk, contracts) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/context.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/context.mli new file mode 100644 index 000000000000..5a61a8258ee0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/context.mli @@ -0,0 +1,188 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Environment + +type t = B of Block.t | I of Incremental.t + +val branch : t -> Block_hash.t + +val get_level : t -> Raw_level.t tzresult + +val get_endorsers : t -> Plugin.RPC.Validators.t list tzresult Lwt.t + +val get_endorser : t -> (public_key_hash * Slot.t list) tzresult Lwt.t + +val get_endorser_n : t -> int -> (public_key_hash * Slot.t list) tzresult Lwt.t + +val get_endorsing_power_for_delegate : + t -> ?levels:Raw_level.t list -> public_key_hash -> int tzresult Lwt.t + +val get_voting_power : + t -> public_key_hash -> int32 Environment.Error_monad.shell_tzresult Lwt.t + +val get_total_voting_power : + t -> int32 Environment.Error_monad.shell_tzresult Lwt.t + +val get_bakers : + ?filter:(Plugin.RPC.Baking_rights.t -> bool) -> + t -> + public_key_hash list tzresult Lwt.t + +val get_baker : t -> round:int -> public_key_hash tzresult Lwt.t + +val get_seed_nonce_hash : t -> Nonce_hash.t tzresult Lwt.t + +(** Returns the seed of the cycle to which the block belongs to. *) +val get_seed : t -> Seed.seed tzresult Lwt.t + +(** Returns all the constants of the protocol *) +val get_constants : t -> Constants.t tzresult Lwt.t + +val get_baking_reward_fixed_portion : t -> Tez.t tzresult Lwt.t + +val get_bonus_reward : t -> endorsing_power:int -> Tez.t tzresult Lwt.t + +val get_endorsing_reward : + t -> expected_endorsing_power:int -> Tez.t tzresult Lwt.t + +val get_liquidity_baking_subsidy : t -> Tez.t tzresult Lwt.t + +val get_liquidity_baking_cpmm_address : t -> Contract.t tzresult Lwt.t + +module Vote : sig + val get_ballots : t -> Vote.ballots tzresult Lwt.t + + val get_ballot_list : + t -> (Signature.Public_key_hash.t * Vote.ballot) list tzresult Lwt.t + + val get_current_period : t -> Voting_period.info tzresult Lwt.t + + val get_current_quorum : t -> int32 tzresult Lwt.t + + val get_participation_ema : Block.t -> int32 tzresult Lwt.t + + val get_listings : + t -> (Signature.Public_key_hash.t * int32) list tzresult Lwt.t + + val get_proposals : t -> int32 Protocol_hash.Map.t tzresult Lwt.t + + val get_current_proposal : t -> Protocol_hash.t option tzresult Lwt.t + + val get_protocol : Block.t -> Protocol_hash.t Lwt.t + + val set_participation_ema : Block.t -> int32 -> Block.t Lwt.t +end + +module Contract : sig + val pp : Format.formatter -> Contract.t -> unit + + val equal : Contract.t -> Contract.t -> bool + + val pkh : Contract.t -> public_key_hash tzresult Lwt.t + + (** Returns the balance of a contract, by default the main balance. + If the contract is implicit the frozen balances are available too: + deposit, fees or rewards. *) + val balance : t -> Contract.t -> Tez.t tzresult Lwt.t + + val counter : t -> Contract.t -> Z.t tzresult Lwt.t + + val manager : t -> Contract.t -> Account.t tzresult Lwt.t + + val is_manager_key_revealed : t -> Contract.t -> bool tzresult Lwt.t + + val delegate : t -> Contract.t -> public_key_hash tzresult Lwt.t + + val delegate_opt : t -> Contract.t -> public_key_hash option tzresult Lwt.t + + val storage : t -> Contract.t -> Script.expr tzresult Lwt.t + + val script : t -> Contract.t -> Script.expr tzresult Lwt.t + + val script_hash : t -> Contract.t -> Script_expr_hash.t tzresult Lwt.t +end + +module Delegate : sig + type info = Delegate_services.info = { + full_balance : Tez.t; + current_frozen_deposits : Tez.t; + frozen_deposits : Tez.t; + staking_balance : Tez.t; + frozen_deposits_limit : Tez.t option; + delegated_contracts : Alpha_context.Contract.t list; + delegated_balance : Tez.t; + deactivated : bool; + grace_period : Cycle.t; + voting_power : int32; + } + + val info : t -> public_key_hash -> Delegate_services.info tzresult Lwt.t + + val full_balance : t -> public_key_hash -> Tez.t tzresult Lwt.t + + val current_frozen_deposits : t -> public_key_hash -> Tez.t tzresult Lwt.t + + (** calls the RPC [frozen_deposits]: we're using a different name to + be more easily distinguishable from [current_frozen_deposits] *) + val initial_frozen_deposits : t -> public_key_hash -> Tez.t tzresult Lwt.t + + val staking_balance : t -> public_key_hash -> Tez.t tzresult Lwt.t + + val frozen_deposits_limit : + t -> public_key_hash -> Tez.t option tzresult Lwt.t + + val deactivated : t -> public_key_hash -> bool tzresult Lwt.t + + val participation : + t -> public_key_hash -> Delegate.participation_info tzresult Lwt.t +end + +(** [init n] : returns an initial block with [n] initialized accounts + and the associated implicit contracts *) +val init : + ?rng_state:Random.State.t -> + ?commitments:Commitment.t list -> + ?initial_balances:int64 list -> + ?consensus_threshold:int -> + ?min_proposal_quorum:int32 -> + ?bootstrap_contracts:Parameters.bootstrap_contract list -> + ?level:int32 -> + ?cost_per_byte:Tez.t -> + ?liquidity_baking_subsidy:Tez.t -> + ?endorsing_reward_per_slot:Tez.t -> + ?baking_reward_bonus_per_slot:Tez.t -> + ?baking_reward_fixed_portion:Tez.t -> + ?origination_size:int -> + ?blocks_per_cycle:int32 -> + int -> + (Block.t * Alpha_context.Contract.t list) tzresult Lwt.t + +val init_with_constants : + Constants.parametric -> + int -> + (Block.t * Alpha_context.Contract.t list) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/contract_helpers.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/contract_helpers.ml new file mode 100644 index 000000000000..6935d7ade5b8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/contract_helpers.ml @@ -0,0 +1,101 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Error_monad_operators + +(** Initializes 2 addresses to do only operations plus one that will be + used to bake. *) +let init () = + Context.init ~consensus_threshold:0 3 >|=? fun (b, contracts) -> + let (src0, src1, src2) = + match contracts with + | src0 :: src1 :: src2 :: _ -> (src0, src1, src2) + | _ -> assert false + in + let baker = + match Alpha_context.Contract.is_implicit src0 with + | Some v -> v + | None -> assert false + in + (b, baker, src1, src2) + +(** Returns a block in which the contract is originated. *) +let originate_contract file storage src b baker = + let load_file f = + let ic = open_in f in + let res = really_input_string ic (in_channel_length ic) in + close_in ic ; + res + in + let contract_string = load_file file in + let code = Expr.toplevel_from_string contract_string in + let storage = Expr.from_string storage in + let script = + Alpha_context.Script.{code = lazy_expr code; storage = lazy_expr storage} + in + Op.origination (B b) src ~fee:(Test_tez.of_int 10) ~script + >>=? fun (operation, dst) -> + Incremental.begin_construction ~policy:Block.(By_account baker) b + >>=? fun incr -> + Incremental.add_operation incr operation >>=? fun incr -> + Incremental.finalize_block incr >|=? fun b -> (dst, b) + +let default_source = Contract.implicit_contract Signature.Public_key_hash.zero + +let default_step_constants = + Script_interpreter. + { + source = default_source; + payer = default_source; + self = default_source; + amount = Tez.zero; + chain_id = Chain_id.zero; + now = Script_timestamp.of_zint Z.zero; + level = Script_int.zero_n; + } + +(** Helper function that parses and types a script, its initial storage and + parameters from strings. It then executes the typed script with the storage + and parameter and returns the result. *) +let run_script ctx ?(step_constants = default_step_constants) contract + ?(entrypoint = "default") ~storage ~parameter () = + let contract_expr = Expr.from_string contract in + let storage_expr = Expr.from_string storage in + let parameter_expr = Expr.from_string parameter in + let script = + Script.{code = lazy_expr contract_expr; storage = lazy_expr storage_expr} + in + Script_interpreter.execute + ctx + Readable + step_constants + ~script + ~cached_script:None + ~entrypoint + ~parameter:parameter_expr + ~internal:false + >>=?? fun res -> return res diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/cpmm_logic.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/cpmm_logic.ml new file mode 100644 index 000000000000..a1d4d8027c58 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/cpmm_logic.ml @@ -0,0 +1,102 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** This is a simulation of the CPMM contract, as implemented in mligo + in [src/proto_alpha/lib_protocol/contracts/cpmm.mligo]. The + interested reader should look for comments in this file to gain a + better understanding of the contract logic. *) +module Simulate_raw = struct + let mutez_to_natural t = Z.of_int64 (Tez.to_mutez t) + + let natural_to_mutez n = Tez.of_mutez_exn (Z.to_int64 n) + + let addLiquidity ~tokenPool ~xtzPool ~lqtTotal ~amount = + let xtzPool = mutez_to_natural xtzPool in + let nat_amount = mutez_to_natural amount in + let lqt_minted = Z.(nat_amount * lqtTotal / xtzPool) in + let tokens_deposited = Z.(cdiv (nat_amount * tokenPool) xtzPool) in + (lqt_minted, tokens_deposited) + + let removeLiquidity ~tokenPool ~xtzPool ~lqtTotal ~lqtBurned = + let xtz_withdrawn = + natural_to_mutez Z.(lqtBurned * mutez_to_natural xtzPool / lqtTotal) + in + let tokens_withdrawn = Z.(lqtBurned * tokenPool / lqtTotal) in + (xtz_withdrawn, tokens_withdrawn) + + let tokenToXtz ~tokenPool ~xtzPool ~tokensSold = + let fee = Z.of_int 999 in + let xtz_bought_nat = + Z.( + tokensSold * fee * mutez_to_natural xtzPool + / ((tokenPool * of_int 1000) + (tokensSold * fee))) + in + let bought = Z.(xtz_bought_nat * of_int 999 / of_int 1000) in + (natural_to_mutez bought, xtz_bought_nat) + + let xtzToToken ~tokenPool ~xtzPool ~amount = + let fee = Z.of_int 999 in + let xtzPool = mutez_to_natural xtzPool in + let nat_amount = mutez_to_natural amount in + let amount_net_burn = Z.(nat_amount * Z.of_int 999 / Z.of_int 1000) in + let tokens_bought = + Z.( + amount_net_burn * fee * tokenPool + / ((xtzPool * Z.of_int 1000) + (amount_net_burn * fee))) + in + (tokens_bought, amount_net_burn) + + let tokenToToken ~tokenPool ~xtzPool ~tokensSold = + let fee = Z.of_int 999 in + let xtz_bought_nat = + Z.( + tokensSold * fee * mutez_to_natural xtzPool + / ((tokenPool * of_int 1000) + (tokensSold * fee))) + in + let xtz_bought_net_burn = Z.(xtz_bought_nat * of_int 999 / of_int 1000) in + (natural_to_mutez xtz_bought_net_burn, xtz_bought_nat) +end + +module Simulate = struct + open Cpmm_repr.Storage + + let addLiquidity {tokenPool; xtzPool; lqtTotal; _} amount = + Simulate_raw.addLiquidity ~xtzPool ~tokenPool ~lqtTotal ~amount + + let removeLiquidity {tokenPool; xtzPool; lqtTotal; _} lqtBurned = + Simulate_raw.removeLiquidity ~tokenPool ~xtzPool ~lqtTotal ~lqtBurned + + let tokenToXtz {tokenPool; xtzPool; _} tokensSold = + Simulate_raw.tokenToXtz ~tokenPool ~xtzPool ~tokensSold + + let xtzToToken {tokenPool; xtzPool; _} amount = + Simulate_raw.xtzToToken ~tokenPool ~xtzPool ~amount + + let tokenToToken {tokenPool; xtzPool; _} tokensSold = + Simulate_raw.tokenToToken ~tokenPool ~xtzPool ~tokensSold +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/cpmm_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/cpmm_repr.ml new file mode 100644 index 000000000000..5ec22503b0eb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/cpmm_repr.ml @@ -0,0 +1,384 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Expr_common + +(* // ============================================================================= + * // Storage + * // ============================================================================= *) + +module Storage = struct + type t = { + tokenPool : Z.t; + xtzPool : Tez.t; + lqtTotal : Z.t; + tokenAddress : Contract.t; + lqtAddress : Contract.t; + } + + let zero : t = + { + tokenPool = Z.zero; + xtzPool = Tez.zero; + lqtTotal = Z.zero; + tokenAddress = + Contract.originated_contract + (Contract.initial_origination_nonce Operation_hash.zero); + lqtAddress = + Contract.originated_contract + (Contract.initial_origination_nonce Operation_hash.zero); + } + + let to_string {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} = + Format.asprintf + "{tokenPool : %a; xtzPool : %s; lqtTotal : %a; tokenAddress : %s; \ + lqtAddress : %s;}" + Z.pp_print + tokenPool + (Int64.to_string @@ Tez.to_mutez xtzPool) + Z.pp_print + lqtTotal + (Contract.to_b58check tokenAddress) + (Contract.to_b58check lqtAddress) + + let pp fmt s = Format.fprintf fmt "%s" (to_string s) + + let eq s s' = s = s' + + let to_expr : + loc:'a -> + t -> + ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = + fun ~loc {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} -> + comb + ~loc + [ + int ~loc tokenPool; + mutez ~loc xtzPool; + int ~loc lqtTotal; + address_string ~loc tokenAddress; + address_string ~loc lqtAddress; + ] + + let to_michelson_string e = + let e = to_expr ~loc:0 e in + Format.asprintf + "%a" + Michelson_v1_printer.print_expr + (Micheline.strip_locations e) + + type exn += Invalid_storage_expr of string + + (** Note: parses a storage unparsed in readable mode (as + e.g. returned by [Alpha_services.Contract.storage]), so that + contracts are represented by strings. *) + let of_expr_exn : + ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node -> t = + function + | Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [ + Tezos_micheline.Micheline.Int (_, tokenPool); + Tezos_micheline.Micheline.Int (_, xtzPool); + Tezos_micheline.Micheline.Int (_, lqtTotal); + Tezos_micheline.Micheline.String (_, tokenAddress); + Tezos_micheline.Micheline.String (_, lqtAddress); + ], + [] ) -> + let xtzPool = Tez.of_mutez_exn (Z.to_int64 xtzPool) in + let tokenAddress = address_of_string_exn tokenAddress in + let lqtAddress = address_of_string_exn lqtAddress in + {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} + | e -> + let canonical = Micheline.strip_locations e in + let msg = + Format.asprintf + "Not a valid CPMM storage: %s /// %a" + (try + Michelson_v1_printer.micheline_string_of_expression + ~zero_loc:true + canonical + with Z.Overflow -> + "Cannot represent as micheline due to overflowing Z -> int") + Michelson_v1_printer.print_expr + canonical + in + raise (Invalid_storage_expr msg) + + let get (ctxt : Context.t) ~(contract : Contract.t) : t tzresult Lwt.t = + Context.Contract.storage ctxt contract >|=? Micheline.root >|=? of_expr_exn + + let of_tuple (tokenPool, xtzPool, lqtTotal, tokenAddress, lqtAddress) = + {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} + + let to_tuple {tokenPool; xtzPool; lqtTotal; tokenAddress; lqtAddress} = + (tokenPool, xtzPool, lqtTotal, tokenAddress, lqtAddress) + + let valid {tokenPool; xtzPool; lqtTotal; _} = + tokenPool > Z.zero && lqtTotal > Z.zero && Tez.(xtzPool > Tez.zero) +end + +module Parameter = struct + (* // ============================================================================= + * // Entrypoints + * // ============================================================================= *) + + type add_liquidity = { + owner : Contract.t; + minLqtMinted : Z.t; + maxTokensDeposited : Z.t; + deadline : Script_timestamp.t; + } + + type remove_liquidity = { + to_ : Contract.t; + (* recipient of the liquidity redemption *) + lqtBurned : Z.t; + (* amount of lqt owned by sender to burn *) + minXtzWithdrawn : Tez.t; + (* minimum amount of Tez.t to withdraw *) + minTokensWithdrawn : Z.t; + (* minimum amount of tokens to withdraw *) + deadline : Script_timestamp.t; + (* the time before which the request must be completed *) + } + + type token_to_token = { + outputDexterContract : Contract.t; + minTokensBought : Z.t; + to_ : Contract.t; + tokensSold : Z.t; + deadline : Script_timestamp.t; + } + + type token_to_xtz = { + to_ : Contract.t; + tokensSold : Z.t; + minXtzBought : Tez.t; + deadline : Script_timestamp.t; + } + + type xtz_to_token = { + to_ : Contract.t; + minTokensBought : Z.t; + deadline : Script_timestamp.t; + } + + type t = + | AddLiquidity of add_liquidity + | Default of unit + | RemoveLiquidity of remove_liquidity + | TokenToToken of token_to_token + | TokenToXtz of token_to_xtz + | XtzToToken of xtz_to_token + + let addLiquidity p = AddLiquidity p + + let default p = Default p + + let removeLiquidity p = RemoveLiquidity p + + let tokenToToken p = TokenToToken p + + let tokenToXtz p = TokenToXtz p + + let xtzToToken p = XtzToToken p + + let add_liquidity_to_string : add_liquidity -> string = + fun {owner; minLqtMinted; maxTokensDeposited; deadline} -> + Format.asprintf + "{owner : %s; minLqtMinted : %a; maxTokensDeposited : %a; deadline : %s }" + (Contract.to_b58check owner) + Z.pp_print + minLqtMinted + Z.pp_print + maxTokensDeposited + (Script_timestamp.to_string deadline) + + let remove_liquidity_to_string : remove_liquidity -> string = + fun {to_; lqtBurned; minXtzWithdrawn; minTokensWithdrawn; deadline} -> + Format.asprintf + "{owner : %s; lqtBurned : %a; minXtzWithdrawn : %s; minTokensWithdrawn : \ + %a; deadline : %s }" + (Contract.to_b58check to_) + Z.pp_print + lqtBurned + (Int64.to_string @@ Tez.to_mutez minXtzWithdrawn) + Z.pp_print + minTokensWithdrawn + (Script_timestamp.to_string deadline) + + let token_to_token_to_string : token_to_token -> string = + fun {outputDexterContract; minTokensBought; to_; tokensSold; deadline} -> + Format.asprintf + "{outputDexterContract : %s; minTokensBought : %a; to_ : %s; tokensSold \ + : %a; deadline : %s }" + (Contract.to_b58check outputDexterContract) + Z.pp_print + minTokensBought + (Contract.to_b58check to_) + Z.pp_print + tokensSold + (Script_timestamp.to_string deadline) + + let token_to_xtz_to_string : token_to_xtz -> string = + fun {to_; tokensSold; minXtzBought; deadline} -> + Format.asprintf + "{to_ : %s; tokensSold : %a; minXtzBought : %s; deadline : %s }" + (Contract.to_b58check to_) + Z.pp_print + tokensSold + (Int64.to_string @@ Tez.to_mutez minXtzBought) + (Script_timestamp.to_string deadline) + + let xtz_to_token_to_string : xtz_to_token -> string = + fun {to_; minTokensBought; deadline} -> + Format.asprintf + "{to_ : %s; minTokensBought : %a; deadline : %s }" + (Contract.to_b58check to_) + Z.pp_print + minTokensBought + (Script_timestamp.to_string deadline) + + let to_string : t -> string = function + | AddLiquidity p -> + Format.asprintf "AddLiquidity %s" (add_liquidity_to_string p) + | Default () -> "Default ()" + | RemoveLiquidity p -> + Format.asprintf "RemoveLiquidity %s" (remove_liquidity_to_string p) + | TokenToToken p -> + Format.asprintf "TokenToToken (%s)" (token_to_token_to_string p) + | TokenToXtz p -> + Format.asprintf "TokenToXtz (%s)" (token_to_xtz_to_string p) + | XtzToToken p -> + Format.asprintf "XtzToToken (%s)" (xtz_to_token_to_string p) + + let entrypoint_of_parameter : t -> string = function + | AddLiquidity _ -> "addLiquidity" + | Default _ -> "default" + | RemoveLiquidity _ -> "removeLiquidity" + | TokenToToken _ -> "tokenToToken" + | TokenToXtz _ -> "tokenToXtz" + | XtzToToken _ -> "xtzToToken" + + let pp fmt s = Format.fprintf fmt "%s" (to_string s) + + let eq s s' = s = s' + + let to_expr_rooted : + loc:'a -> + t -> + ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = + fun ~loc -> function + | AddLiquidity {owner; minLqtMinted; maxTokensDeposited; deadline} -> + comb + ~loc + [ + address_string ~loc owner; + int ~loc minLqtMinted; + int ~loc maxTokensDeposited; + timestamp ~loc deadline; + ] + | Default () -> unit ~loc + | RemoveLiquidity + {to_; lqtBurned; minXtzWithdrawn; minTokensWithdrawn; deadline} -> + comb + ~loc + [ + address_string ~loc to_; + int ~loc lqtBurned; + mutez ~loc minXtzWithdrawn; + int ~loc minTokensWithdrawn; + timestamp ~loc deadline; + ] + | TokenToToken + {outputDexterContract; minTokensBought; to_; tokensSold; deadline} -> + comb + ~loc + [ + address_string ~loc outputDexterContract; + int ~loc minTokensBought; + address_string ~loc to_; + int ~loc tokensSold; + timestamp ~loc deadline; + ] + | TokenToXtz {to_; tokensSold; minXtzBought; deadline} -> + comb + ~loc + [ + address_string ~loc to_; + int ~loc tokensSold; + mutez ~loc minXtzBought; + timestamp ~loc deadline; + ] + | XtzToToken {to_; minTokensBought; deadline} -> + comb + ~loc + [ + address_string ~loc to_; + int ~loc minTokensBought; + timestamp ~loc deadline; + ] + + let to_expr : + loc:'a -> + t -> + ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = + fun ~loc p -> + let rooted = to_expr_rooted ~loc p in + match p with + | AddLiquidity _ -> left ~loc @@ left ~loc @@ left ~loc rooted + | Default () -> left ~loc @@ left ~loc @@ right ~loc rooted + | RemoveLiquidity _ -> left ~loc @@ right ~loc @@ left ~loc rooted + | TokenToToken _ -> left ~loc @@ right ~loc @@ right ~loc rooted + | TokenToXtz _ -> right ~loc @@ left ~loc rooted + | XtzToToken _ -> right ~loc @@ right ~loc rooted + + let to_michelson_string e = + let e = to_expr ~loc:0 e in + Format.asprintf + "%a" + Michelson_v1_printer.print_expr + (Micheline.strip_locations e) +end + +let transaction (ctxt : Context.t) ~(contract : Contract.t) ~(src : Contract.t) + ?(amount = Tez.zero) (parameters : Parameter.t) = + let entrypoint = Parameter.entrypoint_of_parameter parameters in + let rooted_param_lazy = + parameters + |> Parameter.to_expr_rooted ~loc:0 + |> Micheline.strip_locations |> Alpha_context.Script.lazy_expr + in + Op.transaction + ctxt + src + contract + amount + ~entrypoint + ~parameters:rooted_param_lazy diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/dune b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/dune new file mode 100644 index 000000000000..6c4ee394fe14 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/dune @@ -0,0 +1,24 @@ +(library + (name tezos_012_PsiThaCa_test_helpers) + (instrumentation (backend bisect_ppx)) + (public_name tezos-012-PsiThaCa-test-helpers) + (libraries alcotest-lwt + qcheck-alcotest + tezos-test-helpers + tezos-base + tezos-micheline + tezos-stdlib-unix + tezos-shell-services + tezos-protocol-environment + tezos-protocol-012-PsiThaCa + tezos-protocol-012-PsiThaCa-parameters + tezos-client-012-PsiThaCa + tezos-protocol-plugin-012-PsiThaCa) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_micheline + -open Tezos_stdlib_unix + -open Tezos_protocol_012_PsiThaCa + -open Tezos_client_012_PsiThaCa + -open Tezos_protocol_plugin_012_PsiThaCa + -open Tezos_protocol_environment_012_PsiThaCa + -open Tezos_shell_services))) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/dune-project b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/dune-project new file mode 100644 index 000000000000..8d36470afaad --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/dune-project @@ -0,0 +1,3 @@ +(lang dune 2.9) +(formatting (enabled_for ocaml)) +(name tezos-alpha-test-helpers) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/error_monad_operators.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/error_monad_operators.ml new file mode 100644 index 000000000000..61eb43e4020a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/error_monad_operators.ml @@ -0,0 +1,11 @@ +open Protocol + +let ( >>=?? ) x y = + x >>= function + | Ok s -> y s + | Error err -> Lwt.return @@ Error (Environment.wrap_tztrace err) + +let ( >>??= ) x y = + match x with + | Ok s -> y s + | Error err -> Lwt.return @@ Error (Environment.wrap_tztrace err) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/expr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/expr.ml new file mode 100644 index 000000000000..37074c20b00e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/expr.ml @@ -0,0 +1,50 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +exception Expression_from_string + +(** Parse a Michelson expression from string, raising an exception on error. *) +let from_string ?(check_micheline_indentation = false) str : Script.expr = + let (ast, errs) = + Michelson_v1_parser.parse_expression ~check:check_micheline_indentation str + in + (match errs with + | [] -> () + | lst -> + Format.printf "expr_from_string: %a\n" Error_monad.pp_print_trace lst ; + raise Expression_from_string) ; + ast.expanded + +(** Parses a Michelson contract from string, raising an exception on error. *) +let toplevel_from_string ?(check_micheline_indentation = false) str = + let (ast, errs) = + Michelson_v1_parser.parse_toplevel ~check:check_micheline_indentation str + in + match errs with [] -> ast.expanded | _ -> Stdlib.failwith "parse toplevel" + +let to_string c = Format.asprintf "%a" Michelson_v1_printer.print_expr c diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/expr_common.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/expr_common.ml new file mode 100644 index 000000000000..1dd79eeba539 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/expr_common.ml @@ -0,0 +1,82 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(* From OCaml values to Micheline expressions *) + +let seq ~loc l = Tezos_micheline.Micheline.Seq (loc, l) + +let pair ~loc a b = + Tezos_micheline.Micheline.Prim (loc, Script.D_Pair, [a; b], []) + +let comb ~loc es = Tezos_micheline.Micheline.Prim (loc, Script.D_Pair, es, []) + +let none ~loc () = Tezos_micheline.Micheline.Prim (loc, Script.D_None, [], []) + +let some ~loc a = Tezos_micheline.Micheline.Prim (loc, Script.D_Some, [a], []) + +let left ~loc a = Tezos_micheline.Micheline.Prim (loc, Script.D_Left, [a], []) + +let right ~loc b = Tezos_micheline.Micheline.Prim (loc, Script.D_Right, [b], []) + +let unit ~loc = Tezos_micheline.Micheline.Prim (loc, Script.D_Unit, [], []) + +let int ~loc i = Tezos_micheline.Micheline.Int (loc, i) + +let bytes ~loc s = Tezos_micheline.Micheline.Bytes (loc, s) + +let string ~loc s = Tezos_micheline.Micheline.String (loc, s) + +let mutez ~loc m = int ~loc (Z.of_int64 (Tez.to_mutez m)) + +(* Translate a timestamp to a Micheline expression in optimized + form *) +let timestamp ~loc ts = int ~loc (Script_timestamp.to_zint ts) + +let address ~loc adr = + bytes ~loc @@ Data_encoding.Binary.to_bytes_exn Contract.encoding adr + +let address_string ~loc adr = string ~loc @@ Contract.to_b58check adr + +let big_map_id ~loc id = int ~loc @@ Big_map.Id.unparse_to_z id + +(* From Micheline expressions to OCaml values *) + +let timestamp_of_zint zint = Script_timestamp.of_zint zint + +let public_key_of_bytes_exn b = + Data_encoding.Binary.of_bytes_exn Signature.Public_key.encoding b + +let address_of_bytes_exn b = + Data_encoding.Binary.of_bytes_exn Contract.encoding b + +type exn += Invalid_address_expr of string + +let address_of_string_exn s = + match Contract.of_b58check s with + | Ok c -> c + | Error _ -> raise @@ Invalid_address_expr s diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/incremental.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/incremental.ml new file mode 100644 index 000000000000..ea9c124bed9f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/incremental.ml @@ -0,0 +1,224 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +module Proto_Nonce = Nonce (* Renamed otherwise is masked by Alpha_context *) + +open Alpha_context + +type t = { + predecessor : Block.t; + state : validation_state; + rev_operations : Operation.packed list; + rev_tickets : operation_receipt list; + header : Block_header.t; + delegate : Account.t; +} + +type incremental = t + +let predecessor {predecessor; _} = predecessor + +let header {header; _} = header + +let rev_tickets {rev_tickets; _} = rev_tickets + +let validation_state {state; _} = state + +let level st = st.header.shell.level + +let rpc_context st = + let fitness = (header st).shell.fitness in + let result = Alpha_context.finalize st.state.ctxt fitness in + { + Environment.Updater.block_hash = Block_hash.zero; + block_header = {st.header.shell with fitness = result.fitness}; + context = result.context; + } + +let rpc_ctxt = + new Environment.proto_rpc_context_of_directory rpc_context rpc_services + +let alpha_ctxt st = st.state.ctxt + +let begin_construction ?timestamp ?seed_nonce_hash ?(mempool_mode = false) + ?(policy = Block.By_round 0) (predecessor : Block.t) = + Block.get_next_baker ~policy predecessor + >>=? fun (delegate, round, real_timestamp) -> + Account.find delegate >>=? fun delegate -> + Round.of_int round |> Environment.wrap_tzresult >>?= fun payload_round -> + let timestamp = Option.value ~default:real_timestamp timestamp in + (match seed_nonce_hash with + | Some _hash -> return seed_nonce_hash + | None -> ( + Plugin.RPC.current_level ~offset:1l Block.rpc_ctxt predecessor + >|=? function + | {expected_commitment = true; _} -> Some (fst (Proto_Nonce.generate ())) + | {expected_commitment = false; _} -> None)) + >>=? fun seed_nonce_hash -> + let contents = + Block.Forge.contents + ?seed_nonce_hash + ~payload_hash:Block_payload_hash.zero + ~payload_round + () + in + let protocol_data = + if mempool_mode then None + else Some {Block_header.contents; signature = Signature.zero} + in + let header = + { + Block_header.shell = + { + predecessor = predecessor.hash; + proto_level = predecessor.header.shell.proto_level; + validation_passes = predecessor.header.shell.validation_passes; + fitness = predecessor.header.shell.fitness; + timestamp; + level = predecessor.header.shell.level; + context = Context_hash.zero; + operations_hash = Operation_list_list_hash.zero; + }; + protocol_data = {contents; signature = Signature.zero}; + } + in + begin_construction + ~chain_id:Chain_id.zero + ~predecessor_context:predecessor.context + ~predecessor_timestamp:predecessor.header.shell.timestamp + ~predecessor_fitness:predecessor.header.shell.fitness + ~predecessor_level:predecessor.header.shell.level + ~predecessor:predecessor.hash + ~timestamp + ?protocol_data + () + >|= fun state -> + Environment.wrap_tzresult state >|? fun state -> + {predecessor; state; rev_operations = []; rev_tickets = []; header; delegate} + +let detect_script_failure : + type kind. kind Apply_results.operation_metadata -> _ = + let rec detect_script_failure : + type kind. kind Apply_results.contents_result_list -> _ = + let open Apply_results in + let detect_script_failure_single (type kind) + (Manager_operation_result + {operation_result; internal_operation_results; _} : + kind Kind.manager Apply_results.contents_result) = + let detect_script_failure (type kind) + (result : kind manager_operation_result) = + match result with + | Applied _ -> Ok () + | Skipped _ -> assert false + | Backtracked (_, None) -> + (* there must be another error for this to happen *) + Ok () + | Backtracked (_, Some errs) -> Error (Environment.wrap_tztrace errs) + | Failed (_, errs) -> Error (Environment.wrap_tztrace errs) + in + List.fold_left + (fun acc (Internal_operation_result (_, r)) -> + acc >>? fun () -> detect_script_failure r) + (detect_script_failure operation_result) + internal_operation_results + in + function + | Single_result (Manager_operation_result _ as res) -> + detect_script_failure_single res + | Single_result _ -> Ok () + | Cons_result (res, rest) -> + detect_script_failure_single res >>? fun () -> + detect_script_failure rest + in + fun {contents} -> detect_script_failure contents + +let add_operation ?expect_apply_failure ?expect_failure st op = + let open Apply_results in + apply_operation st.state op >|= Environment.wrap_tzresult >>= fun result -> + match (expect_apply_failure, result) with + | (Some _, Ok _) -> failwith "Error expected while adding operation" + | (Some f, Error err) -> f err >|=? fun () -> st + | (None, result) -> ( + result >>?= fun result -> + match result with + | (state, (Operation_metadata result as metadata)) -> + detect_script_failure result |> fun result -> + (match expect_failure with + | None -> Lwt.return result + | Some f -> ( + match result with + | Ok _ -> failwith "Error expected while adding operation" + | Error e -> f e)) + >|=? fun () -> + { + st with + state; + rev_operations = op :: st.rev_operations; + rev_tickets = metadata :: st.rev_tickets; + } + | (state, (No_operation_metadata as metadata)) -> + return + { + st with + state; + rev_operations = op :: st.rev_operations; + rev_tickets = metadata :: st.rev_tickets; + }) + +let finalize_block st = + let operations = List.rev st.rev_operations in + let operations_hash = + Operation_list_list_hash.compute + [Operation_list_hash.compute (List.map Operation.hash_packed operations)] + in + let shell_header = + { + st.header.shell with + level = Int32.succ st.header.shell.level; + operations_hash; + } + in + finalize_block st.state (Some shell_header) >|= fun x -> + Environment.wrap_tzresult x >|? fun (result, _) -> + let operations = List.rev st.rev_operations in + let operations_hash = + Operation_list_list_hash.compute + [Operation_list_hash.compute (List.map Operation.hash_packed operations)] + in + let header = + { + st.header with + shell = + { + st.header.shell with + level = Int32.succ st.header.shell.level; + operations_hash; + fitness = result.fitness; + }; + } + in + let hash = Block_header.hash header in + {Block.hash; header; operations; context = result.context} diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/incremental.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/incremental.mli new file mode 100644 index 000000000000..87c33f9dc9a4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/incremental.mli @@ -0,0 +1,62 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +type t + +type incremental = t + +val predecessor : incremental -> Block.t + +val header : incremental -> Block_header.t + +val rev_tickets : incremental -> operation_receipt list + +val validation_state : incremental -> validation_state + +val level : incremental -> int32 + +val begin_construction : + ?timestamp:Time.Protocol.t -> + ?seed_nonce_hash:Nonce_hash.t -> + ?mempool_mode:bool -> + ?policy:Block.baker_policy -> + Block.t -> + incremental tzresult Lwt.t + +val add_operation : + ?expect_apply_failure:(error list -> unit tzresult Lwt.t) -> + ?expect_failure:(error list -> unit tzresult Lwt.t) -> + incremental -> + Operation.packed -> + incremental tzresult Lwt.t + +val finalize_block : incremental -> Block.t tzresult Lwt.t + +val rpc_ctxt : incremental Environment.RPC_context.simple + +val alpha_ctxt : incremental -> Alpha_context.context diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_generator.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_generator.ml new file mode 100644 index 000000000000..878d6f4aaa82 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_generator.ml @@ -0,0 +1,351 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Liquidity_baking_machine +open QCheck.Gen +open Lib_test + +let total_xtz = 32_000_000_000_000L + +let ten_subsidies = 25_000_000L + +let rec remove_last_element = function + | [_] -> [] + | x :: rst -> x :: remove_last_element rst + | [] -> raise (Invalid_argument "remove_last_element") + +(** Try to shrink a list by removing elements from the tail of said + list. + + The elements themselves are not shrinked. *) +let shrink_list_spine_tail : 'a list QCheck.Shrink.t = + let rec shrinked_list = function + | [] -> [] + | l -> + let l = remove_last_element l in + l :: shrinked_list l + in + fun l -> QCheck.Iter.of_list (shrinked_list l) + +let gen_balances : int64 -> int -> int -> balances QCheck.Gen.t = + fun max_xtz max_tzbtc max_liquidity -> + let+ xtz = Qcheck_helpers.int64_strictly_positive_gen max_xtz + and+ tzbtc = Qcheck_helpers.int_strictly_positive_gen max_tzbtc + and+ liquidity = Qcheck_helpers.int_strictly_positive_gen max_liquidity in + {xtz; tzbtc; liquidity} + +let gen_specs : int -> int -> specs QCheck.Gen.t = + fun total_tzbtc total_liquidity -> + (* 1. We pick a random number to decide how many implicit account we + will set-up in the specs. Note that there will be one more + implicit accounts, the [Holder], that we will use to reach the + expected balances for the CPMM and the implicit accounts. *) + let* accounts_numbers = int_range 10 20 in + (* 2. To keep the generator simpler, we do not try to strictly reach + the [total_tzbtc] and [total_liquidity] value, but rather we + compute maxima for the implicit accounts balances from + them. *) + (* 2.1. We divide a fraction of the [total_xtz] that we need to + share to the implicit accounts. The rationale is to provide + a large amount to xtz to [Holder], so that we do not have to + worry about it being “rich enough.” *) + let max_xtz = Int64.(div total_xtz (of_int (50 * accounts_numbers))) in + (* 2.2. We divide [total_tzbtc] between the implicit accounts *and* + the CPMM contract. *) + let max_tzbtc = total_tzbtc / (accounts_numbers + 1) in + (* 2.2. We divide [total_liquidity] between the implicit accounts only. *) + let max_liquidity = total_liquidity / accounts_numbers in + let+ cpmm_balance = gen_balances max_xtz max_tzbtc 1 + and+ accounts_balances = + list_repeat accounts_numbers (gen_balances max_xtz max_tzbtc max_liquidity) + in + { + cpmm_min_xtz_balance = cpmm_balance.xtz; + cpmm_min_tzbtc_balance = cpmm_balance.tzbtc; + accounts_balances; + } + +let arb_specs : tzbtc -> liquidity -> specs QCheck.arbitrary = + fun total_tzbtc total_liquidity -> + QCheck.make + ~print:(fun specs -> Format.asprintf "%a" pp_specs specs) + (gen_specs total_tzbtc total_liquidity) + +type 'a optgen = 'a option QCheck.Gen.t + +let ( let*? ) (m : 'a optgen) (f : 'a -> 'b optgen) = + let* x = m in + match x with None -> return None | Some x -> f x + +(** [genopt_oneof l] tries to generate a value using the generators of + [l], one at a time. + + First, the list [l] is randomized, then each generator is + tried. The first one to return a result (not [None]) is picked. If + all generators returns [None], the generators tries again with the + whole list (at most 100 times). If no generator of [l] is able to + return a result, then [genopt_oneof l] returns [None]. *) +let genopt_oneof (l : 'a optgen list) : 'a optgen = + let* l = QCheck.Gen.shuffle_l l in + let rec aux n = function + | [] -> if n = 0 then pure None else aux (n - 1) l + | g :: l -> ( + let* x = g in + match x with None -> aux n l | Some x -> pure @@ Some x) + in + aux 100 l + +let genopt_account ?choice ?(filter = Fun.const true) env : contract_id optgen = + let l = + List.filter + filter + (Option.fold ~none:env.implicit_accounts ~some:(fun x -> [x]) choice) + in + if l = [] then return None else map Option.some (oneofl l) + +let genopt_account_with_tzbtc ?choice ?(min = 1) env state = + genopt_account + ?choice + ~filter:(fun a -> SymbolicMachine.get_tzbtc_balance a env state >= min) + env + +let genopt_account_with_xtz ?choice ?(min = 1L) env state = + genopt_account + ?choice + ~filter:(fun a -> SymbolicMachine.get_xtz_balance a state >= min) + env + +let genopt_account_with_liquidity ?choice ?(min = 1) env state = + genopt_account + ?choice + ~filter:(fun a -> SymbolicMachine.get_liquidity_balance a env state >= min) + env + +let genopt_step_tzbtc_to_xtz : + ?source:contract_id -> + ?destination:contract_id -> + contract_id env -> + SymbolicMachine.t -> + contract_id step optgen = + fun ?source ?destination env state -> + let*? source = genopt_account_with_tzbtc ?choice:source env state in + let*? destination = genopt_account ?choice:destination env in + let+ tzbtc_deposit = + Qcheck_helpers.int_strictly_positive_gen + (SymbolicMachine.get_tzbtc_balance source env state) + in + (* See note (2) *) + if + SymbolicMachine.get_tzbtc_balance env.cpmm_contract env state + < Int.max_int - tzbtc_deposit + then Some (SellTzBTC {source; destination; tzbtc_deposit}) + else None + +let genopt_step_xtz_to_tzbtc : + ?source:contract_id -> + ?destination:contract_id -> + contract_id env -> + SymbolicMachine.t -> + contract_id step optgen = + fun ?source ?destination env state -> + let*? source = genopt_account_with_xtz ?choice:source env state in + let*? destination = genopt_account ?choice:destination env in + let+ xtz_deposit = + map + Int64.of_int + (int_range + 1 + (Int64.to_int @@ SymbolicMachine.get_xtz_balance source state)) + in + (* See note (2) *) + if + SymbolicMachine.get_xtz_balance env.cpmm_contract state + < Int64.(sub max_int (add ten_subsidies xtz_deposit)) + then Some (BuyTzBTC {source; destination; xtz_deposit}) + else None + +let genopt_step_add_liquidity : + ?source:contract_id -> + ?destination:contract_id -> + contract_id env -> + SymbolicMachine.t -> + contract_id step optgen = + fun ?source ?destination env state -> + let rec find_xtz_deposit candidate max_tzbtc_deposit = + let tzbtc_deposit = + SymbolicMachine.predict_required_tzbtc_deposit candidate env state + in + if tzbtc_deposit <= max_tzbtc_deposit then candidate + else find_xtz_deposit (Int64.div candidate 2L) max_tzbtc_deposit + in + let*? source = genopt_account_with_xtz ?choice:source env state in + let*? destination = genopt_account ?choice:destination env in + let source_xtz_pool = SymbolicMachine.get_xtz_balance source state in + (* the source needs at least one xtz *) + if 1L < source_xtz_pool then + let+ candidate = + Qcheck_helpers.int64_strictly_positive_gen source_xtz_pool + in + let xtz_deposit = + find_xtz_deposit + candidate + (SymbolicMachine.get_tzbtc_balance source env state) + in + (* See note (2) *) + if + SymbolicMachine.get_xtz_balance env.cpmm_contract state + < Int64.(sub max_int (add ten_subsidies xtz_deposit)) + then Some (AddLiquidity {source; destination; xtz_deposit}) + else None + else pure None + +let genopt_step_remove_liquidity : + ?source:contract_id -> + ?destination:contract_id -> + contract_id env -> + SymbolicMachine.t -> + contract_id step optgen = + fun ?source ?destination env state -> + let*? source = genopt_account_with_liquidity ?choice:source env state in + let*? destination = genopt_account ?choice:destination env in + let lqt_available = SymbolicMachine.get_liquidity_balance source env state in + if 1 < lqt_available then + let+ lqt_burned = + int_range 1 (SymbolicMachine.get_liquidity_balance source env state) + in + Some (RemoveLiquidity {source; destination; lqt_burned}) + else return None + +let genopt_step : + ?source:contract_id -> + ?destination:contract_id -> + contract_id env -> + SymbolicMachine.t -> + contract_id step optgen = + fun ?source ?destination env state -> + genopt_oneof + [ + genopt_step_tzbtc_to_xtz env state ?source ?destination; + genopt_step_xtz_to_tzbtc env state ?source ?destination; + genopt_step_add_liquidity env state ?source ?destination; + genopt_step_remove_liquidity env state ?source ?destination; + ] + +let rec gen_steps : + ?source:contract_id -> + ?destination:contract_id -> + contract_id env -> + SymbolicMachine.t -> + int -> + contract_id step list QCheck.Gen.t = + fun ?source ?destination env state size -> + if size <= 0 then return [] + else + let* h = genopt_step ?source ?destination env state in + match h with + | None -> pure [] + | Some h -> + let state = SymbolicMachine.step h env state in + let* rst = gen_steps ?source ?destination env state (size - 1) in + pure (h :: rst) + +let gen_scenario : + tzbtc -> liquidity -> int -> (specs * contract_id step list) QCheck.Gen.t = + fun total_tzbtc total_liquidity size -> + let* specs = gen_specs total_tzbtc total_liquidity in + let (state, env) = SymbolicMachine.build specs in + let+ scenario = gen_steps env state size in + (specs, scenario) + +let pp_scenario fmt (specs, steps) = + Format.( + fprintf + fmt + "@[{@ @[ @[specs@ = %a;@]@ @[steps@ = @[[ \ + %a]@]@]@]}@]" + pp_specs + specs + (pp_print_list + ~pp_sep:(fun fmt _ -> fprintf fmt "@ ; ") + (pp_step pp_contract_id)) + steps) + +let arb_scenario : + tzbtc -> + liquidity -> + int -> + (specs * contract_id step list) QCheck.arbitrary = + fun total_tzbtc total_liquidity size -> + QCheck.make + ~print:(Format.asprintf "%a" pp_scenario) + ~shrink:(fun (specs, steps) -> + (* See note (1) *) + QCheck.Iter.pair (QCheck.Iter.return specs) (shrink_list_spine_tail steps)) + (gen_scenario total_tzbtc total_liquidity size) + +let gen_adversary_scenario : + tzbtc -> + liquidity -> + int -> + (specs * contract_id * contract_id step list) QCheck.Gen.t = + fun total_tzbtc total_liquidity size -> + let* specs = gen_specs total_tzbtc total_liquidity in + let (state, env) = SymbolicMachine.build ~subsidy:0L specs in + let* c = oneofl env.implicit_accounts in + let+ scenario = gen_steps ~source:c ~destination:c env state size in + (specs, c, scenario) + +let arb_adversary_scenario : + tzbtc -> + liquidity -> + int -> + (specs * contract_id * contract_id step list) QCheck.arbitrary = + fun total_tzbtc total_liquidity size -> + QCheck.make + ~print:(fun (specs, _, steps) -> + Format.asprintf "%a" pp_scenario (specs, steps)) + ~shrink:(fun (specs, c, steps) -> + (* see note (1) *) + QCheck.Iter.triple + (QCheck.Iter.return specs) + (QCheck.Iter.return c) + (shrink_list_spine_tail steps)) + (gen_adversary_scenario total_tzbtc total_liquidity size) + +(* -------------------------------------------------------------------------- *) + +(* Note (1) + + We shrink a valid scenario by removing steps from its tails, + because a prefix of a valid scenario remains a valid + scenario. Removing a random element of a scenario could lead to an + invalid scenario. *) + +(* Note (2) + + If we are not being careful, it is possible to provoke an overflow + in the xtzPool and tzbtcPool. We try to avoid that as much as + possible by being very careful with the steps that are likely to + add xtz to the contract. *) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_generator.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_generator.mli new file mode 100644 index 000000000000..c0f1a9811438 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_generator.mli @@ -0,0 +1,77 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module provides a set of abstractions to reason about the + so-called “liquidity baking” feature[1]. + + [1]: https://gitlab.com/tezos/tzip/-/blob/master/drafts/current/draft-liquidity_baking.md + + We remind that this feature is built upon three smart contracts: + (1) a CPMM contract initially based on Dexter 2, and (2) two + tokens contracts. + + Our purpose for Liquidity Baking is to easily express and test + invariants regarding the execution of these contracts. To that + end, we have introduced a set of dedicated types to describe + arbitrary contexts in terms of account balances (see + [Liquidity_baking_machine.specs]), along with [build] functions + that turn a description of a context into concrete states. + + In this module, we provide QCheck generators which allow to + construct arbitrary specifications for states, and so-called + scenarios ({i i.e.}, sequences of entrypoint calls). *) + +open Liquidity_baking_machine + +(** [arb_specs max_tzbtc max_liquidity] constructs arbitrary Liquidity + Baking [specs] for an initial state, where at most [max_tzbtc] and + [max_liquidity] are shared among an arbitrary number of implicit + accounts. *) +val arb_specs : tzbtc -> liquidity -> specs QCheck.arbitrary + +(** [arb_scenario max_tzbtc max_liquidity size] constructs arbitrary + Liquidity Baking [specs] with a semantics similar to [arb_specs], along with sequences of {b valid} + scenarios ({i i.e.}, sequences of entrypoint calls) of length + [size]. By valid, we mean that running the scenario using a + Liquidity baking machine initialized with the [specs] should + succeed. *) +val arb_scenario : + tzbtc -> liquidity -> int -> (specs * contract_id step list) QCheck.arbitrary + +(** [arb_adversary_scenario max_tzbtc max_liquidity size] constructs + arbitrary scenarios that can be used to challenge the “no global + gain” property of Liquidity Baking. + + The key idea of this property is the following: a given contract + cannot profit from Liquidity Baking if they are the only one to + interact with the CPMM (in the absence of subsidies). The scenario + generated by [arb_adversary_scenario] only consists in [step] + performed by one contract. This contract is identified by the + [contract_id] returned by this function. *) +val arb_adversary_scenario : + tzbtc -> + liquidity -> + int -> + (specs * contract_id * contract_id step list) QCheck.arbitrary diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_machine.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_machine.ml new file mode 100644 index 000000000000..d0989378f549 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_machine.ml @@ -0,0 +1,1364 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** To implement the interface of this module, as described and + documented in the related MLI file, we rely on the OCaml module + system. More precisely, most of the implementation of the two + public machines ([ValidationMachine] and [SymbolicMachine]) is + derived by means of functors. + + The machines provide two key functions which can be used in a + test suite: + + - [M.build specs] which allows to construct an initial state of + a machine [M] that satisfies the properties described by + [specs] (along with the so-called “environment” of the + machine) + - [M.step s env state] (resp. [M.run]) which allows to execute a + so-called scenario [step] (resp. a sequence of [step]s, {i + i.e.}, a complete scenario) by the machine [M] from the state + [state]. + + The module is organized as follows: + + 1. We introduce the necessary abstractions we later use to + specify the properties the initial state of a given machine + needs to satisfy (most notably the [specs] type). + 2. Then, we introduce the [step] type, which describes the + various actions we can make a machine perform as part of a + more complete scenario. + 3. We introduce the [MACHINE] module type which lists the + necessary types and functions we need to derive a machine + capable of executing scenarios, and the [Machine.Make] + functor that we can use to derive such a machine + automatically. + 4. We introduce the [MACHINE_WITH_INIT] module type which is a + superset of [MACHINE], extended with an [init] function + (analogous to {! Context.init}) to create an initial, mostly + blank state, and the [MachineBuilder.Make] functor that we + can use to derive a machine with a [build] function. + 5. We construct the [ConcreteMachine], that allows to + asynchronously execute scenarios against the Tezos + blockchain. + 6. We implement the [AbstractMachine.Make] functor, which we + can use to construct machines that can simulate the + execution scenarios completely off-chains, by reimplementing + the LB features logic in pure OCaml. + 7. We use [AbstractMachine.Make] to create the [SymbolicMachine]. + 8. We use the [AbstractMachine.Make] functor in conjuction with + the [ConcreteMachine] to introduce the [ValidationMachine]. + + _ + / \ A warning for developers willing to modify this module: + / | \ dealing with the subsidy of the Liquidity Baking (LB) + / · \ feature is probably the main source of complexity and + /_______\ fragility of this module. + + At several places (marked with a /!\ note), we need to predict the + xtz pool of the CPMM contract, in order to compute the amount of + tzBTC token it will provide or request. To make this prediction, + we need to determine how many blocks have been/will be baked. This + means that each time we modify the code of the machine functors, + we will probably have to modify the code marked with /!\ too. + + To reduce the potential to get things wrong, we have introduced + constants to prevent the use of “magic numbers” (numbers whose + meaning cannot be guessed only by looking at the formula). The + value of these constants is not statically checked, so pay extra + attention before modifying them. + + Ideally, we could probably compute these magic numbers using a + dedicated machine, whose purpose would be to count the number of + call to the [bake] function. For the sake of simplicity, we do not + do it currently. *) + +(** The number of blocks baked in order to execute the {! + AddLiquidity} step. *) +let blocks_per_add_liquidity_step = 2L + +(** The number of blocks baked by the [init] function. Since + Tenderbake, we need to compensate for deposits, so the number is + no longer constant. It is linear wrt. the number of accounts. *) +let blocks_during_init len = Int64.add 3L len + +(** The number of blocks baked by the [mint_tzbtc] functions *) +let blocks_per_mint_tzbtc = 1L + +(** A timestamp “far in the future” which should not be exceeded when + running tests. *) +let far_future = Alpha_context.Script_timestamp.of_zint (Z.of_int 42_000) +(* Hypothesis: the tests start at timestamp 0, and 42000 is + “big enough.” *) + +(* --------------------------------------------------------------------------- *) + +(** {1 Miscellaneous Helpers} *) + +let is_implicit_exn account = + match Contract.is_implicit account with Some k -> k | _ -> assert false + +module List_helpers = struct + let rec zip l r = + match (l, r) with + | (xl :: rstl, xr :: rstr) -> (xl, xr) :: zip rstl rstr + | _ -> [] + + let nth_exn l n = + match List.nth l n with + | Some x -> x + | _ -> raise (Invalid_argument "nth_exn") + + let assoc_exn c l = + match List.assoc ~equal:( = ) c l with + | Some x -> x + | _ -> raise (Invalid_argument "assoc_exn") +end + +(* --------------------------------------------------------------------------- *) + +(** {1 Characterizing Initial Machines States} *) + +(** In order to run so-called scenarios against our machines, we first + need to characterize their initial state. *) + +type xtz = int64 + +type tzbtc = int + +type liquidity = int + +type balances = {xtz : xtz; tzbtc : tzbtc; liquidity : liquidity} + +let pp_balances fmt b = + Format.fprintf + fmt + "@[{xtz = %a; tzbtc = %d; liquidity = %d}@]" + Tez.pp + (Tez.of_mutez_exn b.xtz) + b.tzbtc + b.liquidity + +let xtz {xtz; _} = xtz + +type specs = { + cpmm_min_xtz_balance : xtz; + cpmm_min_tzbtc_balance : tzbtc; + accounts_balances : balances list; +} + +let pp_specs fmt specs = + Format.( + fprintf + fmt + "@[{@ @[cpmm = {min_xtz = %a; min_tzbtc = %d}@ @[accounts = \ + [@ %a@ ]@]@]@ }@]" + Tez.pp + (Tez.of_mutez_exn specs.cpmm_min_xtz_balance) + specs.cpmm_min_tzbtc_balance + (pp_print_list ~pp_sep:pp_print_space pp_balances) + specs.accounts_balances) + +(* --------------------------------------------------------------------------- *) + +(** {1 Scenario [step] }*) + +type 'a step = + | SellTzBTC of {source : 'a; destination : 'a; tzbtc_deposit : tzbtc} + | BuyTzBTC of {source : 'a; destination : 'a; xtz_deposit : xtz} + | AddLiquidity of {source : 'a; destination : 'a; xtz_deposit : xtz} + | RemoveLiquidity of {source : 'a; destination : 'a; lqt_burned : liquidity} + +let pp_step pp_contract fmt = function + | SellTzBTC p -> + Format.( + fprintf + fmt + "@[SellTzBTC(%a, %dtz₿, %a)@]" + pp_contract + p.source + p.tzbtc_deposit + pp_contract + p.destination) + | BuyTzBTC p -> + Format.( + fprintf + fmt + "@[BuyTzBTC(%a, %aꜩ, %a)@]" + pp_contract + p.source + Tez.pp + (Tez.of_mutez_exn p.xtz_deposit) + pp_contract + p.destination) + | AddLiquidity p -> + Format.( + fprintf + fmt + "@[AddLiquidity(%a, %aꜩ, %a)@]" + pp_contract + p.source + Tez.pp + (Tez.of_mutez_exn p.xtz_deposit) + pp_contract + p.destination) + | RemoveLiquidity p -> + Format.( + fprintf + fmt + "@[RemoveLiquidity(%a, %d lqt, %a)@]" + pp_contract + p.source + p.lqt_burned + pp_contract + p.destination) + +type contract_id = + | Cpmm + | Holder + | TzBTC + | TzBTCAdmin + | Liquidity + | LiquidityAdmin + | ImplicitAccount of int + +let contract_id_to_string = function + | Holder -> "holder" + | Cpmm -> "cpmm" + | TzBTC -> "tzbtc" + | TzBTCAdmin -> "tzbtc_admin" + | Liquidity -> "lqt" + | LiquidityAdmin -> "lqt_admin" + | ImplicitAccount i -> Format.sprintf "#%d" i + +let pp_contract_id fmt c = Format.(fprintf fmt "[%s]" (contract_id_to_string c)) + +(* --------------------------------------------------------------------------- *) + +(** {1 Machines} *) + +(** {2 Machine Environment} *) + +type 'a env = { + cpmm_contract : 'a; + tzbtc_contract : 'a; + tzbtc_admin : 'a; + liquidity_contract : 'a; + liquidity_admin : 'a; + implicit_accounts : 'a list; + holder : 'a; + subsidy : xtz; +} + +let refine_contract env = function + | Cpmm -> env.cpmm_contract + | TzBTC -> env.tzbtc_contract + | TzBTCAdmin -> env.tzbtc_admin + | Liquidity -> env.liquidity_contract + | LiquidityAdmin -> env.liquidity_admin + | Holder -> env.holder + | ImplicitAccount i -> List_helpers.nth_exn env.implicit_accounts i + +let refine_step env step = + match step with + | SellTzBTC p -> + SellTzBTC + { + p with + source = refine_contract env p.source; + destination = refine_contract env p.destination; + } + | BuyTzBTC p -> + BuyTzBTC + { + p with + source = refine_contract env p.source; + destination = refine_contract env p.destination; + } + | AddLiquidity p -> + AddLiquidity + { + p with + source = refine_contract env p.source; + destination = refine_contract env p.destination; + } + | RemoveLiquidity p -> + RemoveLiquidity + { + p with + source = refine_contract env p.source; + destination = refine_contract env p.destination; + } + +(** {2 Machine Module Type} *) + +module type MACHINE = sig + type 'a m + + type contract + + type t + + type operation + + val pp_contract : Format.formatter -> contract -> unit + + val ( >>= ) : 'a m -> ('a -> 'b m) -> 'b m + + val fold_m : ('a -> 'b -> 'a m) -> 'a -> 'b list -> 'a m + + val pure : 'a -> 'a m + + val get_balances : contract -> contract env -> t -> balances m + + val get_xtz_balance : contract -> t -> xtz m + + val get_tzbtc_balance : contract -> contract env -> t -> tzbtc m + + val get_liquidity_balance : contract -> contract env -> t -> liquidity m + + val get_cpmm_total_liquidity : contract env -> t -> liquidity m + + val bake : + invariant:(contract env -> t -> bool m) -> + baker:contract -> + operation list -> + contract env -> + t -> + t m + + val transaction : src:contract -> contract -> xtz -> t -> operation m + + val token_to_xtz : + src:contract -> contract -> tzbtc -> contract env -> t -> operation m + + val xtz_to_token : + src:contract -> contract -> xtz -> contract env -> t -> operation m + + (* [mint_or_burn_tzbtc contract amount env state] will construct an + operation to credit or remove [amount] tzbtc tokens to [contract] *) + val mint_or_burn_tzbtc : + contract -> liquidity -> contract env -> t -> operation m + + (** [approve_tzbtc contract amount env state] will construct an + operation to authorize the CPMM contract to spend [amount] tzbtc + on behalf of [contract] *) + val approve_tzbtc : contract -> tzbtc -> contract env -> t -> operation m + + val add_liquidity : + src:contract -> contract -> xtz -> tzbtc -> contract env -> t -> operation m + + val remove_liquidity : + src:contract -> contract -> liquidity -> contract env -> t -> operation m + + val reveal : Account.t -> t -> operation m +end + +(** {2 Tezos Constants} *) + +let default_subsidy = + let open Tezos_protocol_012_PsiThaCa_parameters in + Tez.to_mutez @@ Default_parameters.constants_test.liquidity_baking_subsidy + +let security_deposit = 640_000_000L + +(* When calling [Context.init] with a list of initial balances, the + sum of these balances should be equal to this constant. *) +let total_xtz = 32_000_000_000_000L + +let tzbtc_admin_account : Account.t = + { + pkh = + Signature.Public_key_hash.of_b58check_exn + "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; + pk = + Signature.Public_key.of_b58check_exn + "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"; + sk = + Signature.Secret_key.of_b58check_exn + "edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh"; + } + +let cpmm_initial_balance = {xtz = 100L; tzbtc = 1; liquidity = 0} + +let cpmm_initial_liquidity_supply = 100 + +(** {2 Machine Functor} *) + +module Machine = struct + module Make (S : MACHINE) = struct + open S + + let mint_tzbtc destination ~invariant amount env state = + mint_or_burn_tzbtc destination amount env state >>= fun op -> + bake ~invariant ~baker:env.holder [op] env state + + let add_liquidity ~invariant src dst xtz_deposit tzbtc_deposit env state = + approve_tzbtc src tzbtc_deposit env state >>= fun lqt_op -> + bake ~invariant ~baker:env.holder [lqt_op] env state >>= fun state -> + add_liquidity ~src dst xtz_deposit tzbtc_deposit env state + >>= fun cpmm_op -> bake ~invariant ~baker:env.holder [cpmm_op] env state + + let remove_liquidity ~invariant src dst lqt_burned env state = + remove_liquidity ~src dst lqt_burned env state >>= fun cpmm_op -> + bake ~invariant ~baker:env.holder [cpmm_op] env state + + let sell_tzbtc ~invariant src dst tzbtc_deposit env state = + approve_tzbtc src tzbtc_deposit env state >>= fun tzbtc_op -> + bake ~invariant ~baker:env.holder [tzbtc_op] env state >>= fun state -> + token_to_xtz ~src dst tzbtc_deposit env state >>= fun cpmm_op -> + bake ~invariant ~baker:env.holder [cpmm_op] env state + + let buy_tzbtc ~invariant src dst xtz_deposit env state = + xtz_to_token ~src dst xtz_deposit env state >>= fun cpmm_op -> + bake ~invariant ~baker:env.holder [cpmm_op] env state + + let check_state_satisfies_specs (env : S.contract env) (state : S.t) + (specs : specs) = + let implicit_accounts_targets = + List_helpers.zip env.implicit_accounts specs.accounts_balances + in + fold_m + (fun _ acc -> + let expected = List_helpers.assoc_exn acc implicit_accounts_targets in + get_balances acc env state >>= fun amount -> + assert (expected = amount) ; + pure ()) + () + env.implicit_accounts + >>= fun _ -> + get_tzbtc_balance env.cpmm_contract env state + >>= fun cpmm_tzbtc_balance -> + assert (specs.cpmm_min_tzbtc_balance <= cpmm_tzbtc_balance) ; + get_xtz_balance env.cpmm_contract state >>= fun current_cpmm_xtz -> + assert ( + Int64.(to_int specs.cpmm_min_xtz_balance <= to_int @@ current_cpmm_xtz)) ; + pure () + + (** [predict_required_tzbtc_deposit xtz_deposit env state] + predicts the tzbtc deposit which will be required by the CPMM + contract for a deposit of [xtz_deposit]. + + This function is used by the machines to make the according + call to the [approve] entrypoint of the TzBTC contract. *) + let predict_required_tzbtc_deposit xtz_deposit env state = + get_xtz_balance env.cpmm_contract state >>= fun xtzPool -> + (* /!\ We need to take into accounts the number of blocks baked + to actually call the [add_liquidity] entry point of the + CPMM. *) + let xtzPool = + Tez.of_mutez_exn + Int64.(add xtzPool (mul blocks_per_add_liquidity_step env.subsidy)) + in + get_tzbtc_balance env.cpmm_contract env state >>= fun tokenPool -> + let tokenPool = Z.of_int tokenPool in + get_cpmm_total_liquidity env state >>= fun lqtTotal -> + let lqtTotal = Z.of_int lqtTotal in + let amount = Tez.of_mutez_exn xtz_deposit in + let (_, tokens_deposited) = + Cpmm_logic.Simulate_raw.addLiquidity + ~tokenPool + ~xtzPool + ~lqtTotal + ~amount + in + pure (Z.to_int tokens_deposited) + + let step ?(invariant = fun _ _ -> pure true) s env state = + match s with + | SellTzBTC {source; destination; tzbtc_deposit} -> + sell_tzbtc ~invariant source destination tzbtc_deposit env state + | BuyTzBTC {source; destination; xtz_deposit} -> + buy_tzbtc ~invariant source destination xtz_deposit env state + | AddLiquidity {source; destination; xtz_deposit} -> + predict_required_tzbtc_deposit xtz_deposit env state + >>= fun tzbtc_deposit -> + add_liquidity + ~invariant + source + destination + xtz_deposit + tzbtc_deposit + env + state + | RemoveLiquidity {source; destination; lqt_burned} -> + remove_liquidity ~invariant source destination lqt_burned env state + + let run ?(invariant = fun _ _ -> pure true) scenario env state = + fold_m + (fun state s -> step ~invariant (refine_step env s) env state) + state + scenario + end +end + +let initial_xtz_repartition accounts_balances = + let distributed_xtz = List.fold_left Int64.add 0L accounts_balances in + let bootstrap1_xtz = Int64.sub total_xtz distributed_xtz in + let initial_balances = bootstrap1_xtz :: accounts_balances in + let n = List.length initial_balances in + (n, initial_balances) + +(* --------------------------------------------------------------------------- *) + +(** {1 Machines with a [build] Function} *) + +module type MACHINE_WITH_INIT = sig + include MACHINE + + (** [init balances] will create an “initial” state wherein the + [balances] have been distributed to [n] implicit contracts ([n] + being the size of the [balances] list). This function also + creates a [holder] implicit account which has the rest of the + xtz liquidity (the test framework forces the sum of xtz balances + to be equal to [total_xtz]). [init] also accepts an optional + argument [subsidy] to modify the default value of the subsidy + minted by the protocol in favor of the CPMM. *) + val init : + invariant:(contract env -> t -> bool m) -> + ?subsidy:xtz -> + xtz list -> + (t * contract env) m +end + +(** [initial_xtz_pool] balances predicts the value of the CPMM’s xtz + pool just before we start using the [add_liquidity] entrypoint to + provide to each implicit accounts the necessary liquidity + tokens. *) +let initial_xtz_pool balances subsidy = + (* /!\ In addition to the initial CPMM balances, we need to take + into account the subsidies of each block baked before this + point, which currently consist in: + + - One call to the [init] function + - One call to the [mint_tzbtc] function per implicit + accounts + + If the [build] function changes, this functions needs to be + updated accordingly. *) + let len = Int64.of_int (List.length balances) in + Int64.( + add + cpmm_initial_balance.xtz + (mul + (add (blocks_during_init len) (mul blocks_per_mint_tzbtc len)) + subsidy)) + +(** [predict_initial_balances xtz_pool tzbtc_pool lqt_total balances] + evaluates the extra xtz and tzbtc tokens to add to each balance of + the list [balances] so that the related implicit accounts can call + the [add_liquidity] entrypoint in order to have the required + liquidity token. + + For instance, for a balance [b] such that [b.liquidity = 10], we + compute [xtz_etra] and [tzbtc_extra] so that the implicit account + will be able to buy [10] liquidity tokens, and replace [b] with + [{b with xtz = b.xtz + xtz_extra; tzbtc = b.tzbtc + tzbtc_extra}] + in the returned list. + + The implementation of this function is made more complex than it + should due to the mechanism of subsidy of LB. In particular, it is + depends on the number of block baked to buy liquidities. *) +let predict_initial_balances balances subsidy = + let open Z in + let subsidy_z = of_int64 subsidy in + (* Due to the roundness of [Z.( / )], it is not straightforward to + find the inverse of the equation used to compute the number of + liquidity tokens bought with the [add_liquidity] entrypoint. To + find the suitable number of xtz to propose in order to buy + [liquidity_target], we naively search for the correct + solution. We compute a [xtz_candidate] by ignoring the roundness + of [Z.( / )], then increment it until it works. *) + let find_xtz_extra xtz_pool lqt_total liquidity_target = + let rec aux xtz_candidate = + let liquidity_z = xtz_candidate * lqt_total / xtz_pool in + if liquidity_z = liquidity_target then xtz_candidate + else aux (xtz_candidate + Z.one) + in + let xtz_extra_candidate = liquidity_target * xtz_pool / lqt_total in + aux xtz_extra_candidate + in + let rec predict_initial_balances xtz_pool tzbtc_pool lqt_total = function + | {xtz; tzbtc; liquidity} :: rst -> + (* balance inputs *) + (* /!\ We compute two blocks per [add_liquidity] entrypoint, + hence the two subsidies *) + let xtz_pool = + xtz_pool + (Z.of_int64 blocks_per_add_liquidity_step * subsidy_z) + in + let xtz_z = of_int64 xtz in + let tzbtc_z = of_int tzbtc in + let liquidity_z = of_int liquidity in + (* compute extra for being able to buy liquidity tokens *) + let xtz_extra = find_xtz_extra xtz_pool lqt_total liquidity_z in + let tzbtc_extra = cdiv (xtz_extra * tzbtc_pool) xtz_pool in + (* compute new balances *) + let xtz = to_int64 (xtz_z + xtz_extra) in + let tzbtc = to_int (tzbtc_z + tzbtc_extra) in + let liquidity = to_int liquidity_z in + (* new pools *) + let xtz_pool' = xtz_pool + xtz_extra in + let tzbtc_pool' = tzbtc_pool + tzbtc_extra in + let lqt_total' = lqt_total + liquidity_z in + (* recursion time *) + {xtz; tzbtc; liquidity} + :: predict_initial_balances xtz_pool' tzbtc_pool' lqt_total' rst + | [] -> [] + in + predict_initial_balances + (of_int64 @@ initial_xtz_pool balances subsidy) + (of_int cpmm_initial_balance.tzbtc) + (of_int cpmm_initial_liquidity_supply) + balances + +module MachineBuilder = struct + module Make (S : MACHINE_WITH_INIT) = struct + open S + include Machine.Make (S) + + let build : + ?invariant:(S.contract env -> S.t -> bool m) -> + ?subsidy:xtz -> + specs -> + (S.t * S.contract env) m = + fun ?(invariant = fun _ _ -> pure true) + ?(subsidy = default_subsidy) + ({cpmm_min_xtz_balance; accounts_balances; cpmm_min_tzbtc_balance} as + specs) -> + let accounts_balances_with_extra = + predict_initial_balances accounts_balances subsidy + in + let xtz_balances_with_extra = List.map xtz accounts_balances_with_extra in + (* 1. Create an initial context *) + init ~invariant ~subsidy xtz_balances_with_extra >>= fun (state, env) -> + invariant env state >>= fun cond -> + assert cond ; + (* 2. Provide the initial tzBTC liquidities to implicit accounts *) + let accounts = + List_helpers.zip + env.implicit_accounts + (List_helpers.zip accounts_balances accounts_balances_with_extra) + in + fold_m + (fun state (address, (_, balances)) -> + mint_tzbtc ~invariant address balances.tzbtc env state) + state + accounts + >>= fun state -> + (* 3. Make implicit accounts buy liquidities *) + fold_m + (fun state (address, (target_balances, balances_with_extra)) -> + let xtz = Int64.sub balances_with_extra.xtz target_balances.xtz in + let tzbtc = balances_with_extra.tzbtc - target_balances.tzbtc in + add_liquidity ~invariant address address xtz tzbtc env state) + state + accounts + >>= fun state -> + (* 4. Provide any missing tzbtc tokens to [cpmm_contract], if necessary *) + get_tzbtc_balance env.cpmm_contract env state + >>= fun current_cpmm_tzbtc_balance -> + let tzbtc_missing = cpmm_min_tzbtc_balance - current_cpmm_tzbtc_balance in + (if 0 < tzbtc_missing then + (* 4.1. Provide the tokens to the [bootstrap1] account, as a + temporary holder for CPMM missing tzBTC balance *) + mint_tzbtc ~invariant env.holder tzbtc_missing env state >>= fun state -> + (* 4.1. Make [bootstrap1] buy some xtz against the appropriate + amount of tzbtc *) + sell_tzbtc ~invariant env.holder env.holder tzbtc_missing env state + else pure state) + >>= fun state -> + (* 5. Provide any missing xtz tokens to [cpmm_contract], if necessary *) + get_xtz_balance env.cpmm_contract state + >>= fun current_cpmm_xtz_balance -> + let xtz_missing = + Int64.sub cpmm_min_xtz_balance current_cpmm_xtz_balance + in + (if 0L < xtz_missing then + transaction ~src:env.holder env.cpmm_contract xtz_missing state + >>= fun op -> bake ~invariant ~baker:env.holder [op] env state + else pure state) + >>= fun state -> + check_state_satisfies_specs env state specs >>= fun _ -> pure (state, env) + end +end + +(* --------------------------------------------------------------------------- *) + +module ConcreteBaseMachine : + MACHINE_WITH_INIT + with type 'a m = 'a tzresult Lwt.t + and type contract = Contract.t + and type t = Block.t = struct + type 'a m = 'a tzresult Lwt.t + + type contract = Contract.t + + type operation = packed_operation + + type t = Block.t + + let pp_contract = Contract.pp + + let ( >>= ) = ( >>=? ) + + let fold_m = Environment.List.fold_left_es + + let pure = Error_monad.return + + let get_xtz_balance contract blk = + Context.Contract.balance (B blk) contract >>= fun x -> + pure @@ Tez.to_mutez x + + let get_tzbtc_balance contract env blk = + Lqt_fa12_repr.Storage.getBalance_opt + (B blk) + ~contract:env.tzbtc_contract + (contract, "default") + >>=? fun mamount -> + pure (Option.value (Option.map Z.to_int mamount) ~default:0) + + let get_liquidity_balance contract env blk = + Lqt_fa12_repr.Storage.getBalance_opt + (B blk) + ~contract:env.liquidity_contract + (contract, "default") + >>=? fun mamount -> + pure (Option.value (Option.map Z.to_int mamount) ~default:0) + + let get_cpmm_total_liquidity env blk = + Cpmm_repr.Storage.get (B blk) ~contract:env.cpmm_contract + >>=? fun cpmm_storage -> pure @@ Z.to_int cpmm_storage.lqtTotal + + let get_balances contract env blk = + get_xtz_balance contract blk >>= fun xtz -> + get_tzbtc_balance contract env blk >>= fun tzbtc -> + get_liquidity_balance contract env blk >>= fun liquidity -> + pure {xtz; tzbtc; liquidity} + + let bake ~invariant ~baker ops env blk = + Incremental.begin_construction + ~policy:(Block.By_account (is_implicit_exn baker)) + blk + >>= fun incr -> + fold_m Incremental.add_operation incr ops >>= fun incr -> + Incremental.finalize_block incr >>= fun blk -> + invariant env blk >>= fun cond -> + assert cond ; + return blk + + let reveal (account : Account.t) blk = Op.revelation (B blk) account.pk + + let transaction ~src dst amount blk = + Op.transaction (B blk) src dst (Tez.of_mutez_exn amount) + + let token_to_xtz ~src dst tzbtc_deposit env blk = + Cpmm_repr.transaction + (B blk) + ~src + ~contract:env.cpmm_contract + (Cpmm_repr.Parameter.TokenToXtz + { + to_ = dst; + minXtzBought = Tez.zero; + tokensSold = Z.of_int tzbtc_deposit; + deadline = far_future; + }) + + let xtz_to_token ~src dst amount env blk = + Cpmm_repr.transaction + (B blk) + ~src + ~contract:env.cpmm_contract + (Cpmm_repr.Parameter.XtzToToken + {to_ = dst; minTokensBought = Z.zero; deadline = far_future}) + ~amount:(Tez.of_mutez_exn amount) + + let approve_tzbtc src tzbtc env blk = + let maxTokensDeposited = Z.of_int tzbtc in + Lqt_fa12_repr.transaction + (B blk) + ~src + ~contract:env.tzbtc_contract + (Lqt_fa12_repr.Parameter.Approve + {spender = env.cpmm_contract; value = maxTokensDeposited}) + + let mint_or_burn_tzbtc target amount env blk = + let quantity = Z.of_int amount in + let ctxt = Context.B blk in + Lqt_fa12_repr.transaction + ctxt + ~src:env.tzbtc_admin + ~contract:env.tzbtc_contract + (Lqt_fa12_repr.Parameter.mintOrBurn {target; quantity}) + + let add_liquidity ~src dst xtz_deposit tzbtc_deposit env blk = + let amount = Tez.of_mutez_exn xtz_deposit in + let maxTokensDeposited = Z.of_int tzbtc_deposit in + Cpmm_repr.transaction + (B blk) + ~src + ~contract:env.cpmm_contract + ~amount + (Cpmm_repr.Parameter.AddLiquidity + { + owner = dst; + maxTokensDeposited; + minLqtMinted = Z.zero; + deadline = far_future; + }) + + let remove_liquidity ~src dst lqt_burned env blk = + let lqtBurned = Z.of_int lqt_burned in + Cpmm_repr.transaction + (B blk) + ~src + ~contract:env.cpmm_contract + (Cpmm_repr.Parameter.RemoveLiquidity + { + to_ = dst; + lqtBurned; + minXtzWithdrawn = Tez.zero; + minTokensWithdrawn = Z.zero; + deadline = far_future; + }) + + let reveal_tzbtc_admin ~invariant env state = + Account.add_account tzbtc_admin_account ; + transaction ~src:env.holder env.tzbtc_admin 1L state >>= fun op1 -> + bake ~invariant ~baker:env.holder [op1] env state >>= fun state -> + reveal tzbtc_admin_account state >>= fun op2 -> + bake ~invariant ~baker:env.holder [op2] env state + + let init ~invariant ?subsidy accounts_balances = + let liquidity_baking_subsidy = Option.map Tez.of_mutez_exn subsidy in + let (n, initial_balances) = initial_xtz_repartition accounts_balances in + Context.init + n + ~consensus_threshold:0 + ~initial_balances + ~cost_per_byte:Tez.zero + ~endorsing_reward_per_slot:Tez.zero + ~baking_reward_bonus_per_slot:Tez.zero + ~baking_reward_fixed_portion:Tez.zero + ~origination_size:0 + ~blocks_per_cycle:10_000l + ?liquidity_baking_subsidy + >>= function + | (blk, holder :: accounts) -> + let ctxt = Context.B blk in + Context.get_liquidity_baking_cpmm_address ctxt >>= fun cpmm_contract -> + Context.Contract.storage ctxt cpmm_contract >>= fun storage -> + let storage = Cpmm_repr.Storage.of_expr_exn (Micheline.root storage) in + let tzbtc_contract = storage.tokenAddress in + let liquidity_contract = storage.lqtAddress in + Context.Contract.storage ctxt tzbtc_contract >>= fun storage -> + let storage = + Lqt_fa12_repr.Storage.of_expr_exn (Micheline.root storage) + in + let tzbtc_admin = storage.admin in + Context.Contract.storage ctxt liquidity_contract >>= fun storage -> + let storage = + Lqt_fa12_repr.Storage.of_expr_exn (Micheline.root storage) + in + let liquidity_admin = storage.admin in + Context.get_liquidity_baking_subsidy (B blk) >>=? fun subsidy -> + let env = + { + cpmm_contract; + tzbtc_contract; + tzbtc_admin; + liquidity_contract; + liquidity_admin; + implicit_accounts = accounts; + holder; + subsidy = Tez.to_mutez subsidy; + } + in + reveal_tzbtc_admin ~invariant:(fun _ _ -> pure true) env blk + >>= fun blk -> + mint_or_burn_tzbtc env.cpmm_contract cpmm_initial_balance.tzbtc env blk + >>= fun op -> + bake ~invariant:(fun _ _ -> pure true) ~baker:env.holder [op] env blk + >>= fun blk -> + (* Since Tenderbake, we need to compensate for potential deposits + related to the consensus. *) + List.fold_left_i_es + (fun idx blk contract -> + match List.nth accounts_balances idx with + | Some target -> + get_xtz_balance contract blk >>=? fun balance -> + let delta = Int64.(sub target balance) in + if Compare.Int64.(0L = delta) then + (* We need to be able to determine the number of + blocks baked in the init function (to predict the + CPMM balance). So even when there is no delta to + compensate with, we bake an empty block. *) + bake + ~invariant:(fun _ _ -> pure true) + ~baker:env.holder + [] + env + blk + else if Compare.Int64.(0L < delta) then + transaction ~src:env.holder contract delta blk >>= fun op -> + bake + ~invariant:(fun _ _ -> pure true) + ~baker:env.holder + [op] + env + blk + else assert false + | None -> assert false) + blk + accounts + >>=? fun blk -> + (* We did not check the invariant before, because the CPMM + contract was in an inconsistent state. More precisely, it + was supposed to hold tzbtc tokens, while in practice it was + not. This was solved by the last call to [bake]. *) + invariant env blk >>= fun cond -> + assert cond ; + pure (blk, env) + | _ -> assert false +end + +module ConcreteMachine = struct + include ConcreteBaseMachine + include Machine.Make (ConcreteBaseMachine) + include MachineBuilder.Make (ConcreteBaseMachine) +end + +(* --------------------------------------------------------------------------- *) + +(** {1 Abstract Machines} *) + +type 'a state = { + cpmm_total_liquidity : liquidity; + accounts_balances : ('a * balances) list; +} + +let refine_state env state = + { + cpmm_total_liquidity = state.cpmm_total_liquidity; + accounts_balances = + List.map + (fun (c, b) -> (refine_contract env c, b)) + state.accounts_balances; + } + +let update_balances account f state = + match List.assoc ~equal:( = ) account state.accounts_balances with + | Some b -> + { + state with + accounts_balances = + (account, f b) + :: List.remove_assoc ~equal:( = ) account state.accounts_balances; + } + | _ -> assert false + +let update_xtz_balance account f = + update_balances account (fun b -> {b with xtz = f b.xtz}) + +let update_tzbtc_balance account f = + update_balances account (fun b -> {b with tzbtc = f b.tzbtc}) + +let update_liquidity_balance account f = + update_balances account (fun b -> {b with liquidity = f b.liquidity}) + +let transfer_xtz_balance src dest d st = + update_xtz_balance src (fun b -> Int64.sub b d) st + |> update_xtz_balance dest (fun b -> Int64.add b d) + +let transfer_tzbtc_balance src dest d st = + update_tzbtc_balance src (fun b -> b - d) st + |> update_tzbtc_balance dest (fun b -> d + b) + +module AbstractMachine = struct + module type C = sig + type t + + val pp : Format.formatter -> t -> unit + end + + module Make (C : C) : + MACHINE with type 'a m = 'a and type contract = C.t and type t = C.t state = + struct + type 'a m = 'a + + type contract = C.t + + type t = C.t state + + type operation = t -> t + + let pp_contract = C.pp + + let ( >>= ) x f = f x + + let pure = Fun.id + + let fold_m = List.fold_left + + let get_balances account state = + match List.assoc ~equal:( = ) account state.accounts_balances with + | Some x -> x + | _ -> assert false + + let get_xtz_balance account state = (get_balances account state).xtz + + let get_tzbtc_balance account _env state = + (get_balances account state).tzbtc + + let get_liquidity_balance account _env state = + (get_balances account state).liquidity + + let get_balances account _env state = get_balances account state + + let get_cpmm_total_liquidity _env state = state.cpmm_total_liquidity + + let reveal _pk _state state = state + + let transaction ~src dst amount _ state = + transfer_xtz_balance src dst amount state + + let xtz_bought tzbtc env state = + let xtzPool = + Tez.of_mutez_exn @@ get_xtz_balance env.cpmm_contract state + in + let tokenPool = + Z.of_int @@ get_tzbtc_balance env.cpmm_contract env state + in + let tokensSold = Z.of_int tzbtc in + let (xtz_bought, xtz_net_bought) = + Cpmm_logic.Simulate_raw.tokenToXtz ~xtzPool ~tokenPool ~tokensSold + in + (Z.to_int64 xtz_net_bought, Tez.to_mutez xtz_bought) + + let token_to_xtz ~src dst amount env _ state = + let (xtz_bought, xtz_net_bought) = xtz_bought amount env state in + state + |> transfer_tzbtc_balance src env.cpmm_contract amount + |> update_xtz_balance env.cpmm_contract (fun b -> Int64.sub b xtz_bought) + |> update_xtz_balance dst (Int64.add xtz_net_bought) + + let tzbtc_bought env state amount = + let xtzPool = + Tez.of_mutez_exn @@ get_xtz_balance env.cpmm_contract state + in + let tokenPool = + Z.of_int @@ get_tzbtc_balance env.cpmm_contract env state + in + let amount = Tez.of_mutez_exn amount in + let (tzbtc_bought, xtz_earnt) = + Cpmm_logic.Simulate_raw.xtzToToken ~xtzPool ~tokenPool ~amount + in + (Z.to_int tzbtc_bought, Z.to_int64 xtz_earnt) + + let xtz_to_token ~src dst amount env _ state = + let (tzbtc_bought, xtz_earnt) = tzbtc_bought env state amount in + update_xtz_balance src (fun b -> Int64.sub b amount) state + |> update_xtz_balance env.cpmm_contract (Int64.add xtz_earnt) + |> transfer_tzbtc_balance env.cpmm_contract dst tzbtc_bought + + let mint_or_burn_tzbtc target amount _ _ = + update_tzbtc_balance target (( + ) amount) + + let approve_tzbtc _contract _amount _env _state = Fun.id + + let add_liquidity ~src dst xtz_deposit _tzbtc_deposit env _ state = + let xtzPool = + Tez.of_mutez_exn (get_xtz_balance env.cpmm_contract state) + in + let tokenPool = + Z.of_int (get_tzbtc_balance env.cpmm_contract env state) + in + let lqtTotal = Z.of_int state.cpmm_total_liquidity in + let amount = Tez.of_mutez_exn xtz_deposit in + let (lqt_minted, tokens_deposited) = + Cpmm_logic.Simulate_raw.addLiquidity + ~tokenPool + ~xtzPool + ~lqtTotal + ~amount + in + let lqt_minted = Z.to_int lqt_minted in + let tokens_deposited = Z.to_int tokens_deposited in + let state = + transfer_xtz_balance src env.cpmm_contract xtz_deposit state + |> transfer_tzbtc_balance src env.cpmm_contract tokens_deposited + |> update_liquidity_balance dst (( + ) lqt_minted) + in + { + state with + cpmm_total_liquidity = state.cpmm_total_liquidity + lqt_minted; + } + + let remove_liquidity ~src dst lqt_burned env _ state = + let xtzPool = + Tez.of_mutez_exn (get_xtz_balance env.cpmm_contract state) + in + let tokenPool = + Z.of_int (get_tzbtc_balance env.cpmm_contract env state) + in + let lqtTotal = Z.of_int state.cpmm_total_liquidity in + let lqtBurned = Z.of_int lqt_burned in + let (xtz_withdrawn, tokens_withdrawn) = + Cpmm_logic.Simulate_raw.removeLiquidity + ~tokenPool + ~xtzPool + ~lqtTotal + ~lqtBurned + in + let xtz_withdrawn = Tez.to_mutez xtz_withdrawn in + let tokens_withdrawn = Z.to_int tokens_withdrawn in + let state = + update_xtz_balance dst (fun b -> Int64.add b xtz_withdrawn) state + |> update_tzbtc_balance dst (( + ) tokens_withdrawn) + |> update_liquidity_balance src (fun b -> b - lqt_burned) + |> update_xtz_balance env.cpmm_contract (fun b -> + Int64.sub b xtz_withdrawn) + |> update_tzbtc_balance env.cpmm_contract (fun b -> + b - tokens_withdrawn) + in + { + state with + cpmm_total_liquidity = state.cpmm_total_liquidity - lqt_burned; + } + + (* Ideally, we should also deal with the release of security + deposit, but since our tests are not long enough for this to + happen, we omit this aspect of the simulation. *) + let bake ~invariant ~baker operations env state = + let state = + update_xtz_balance env.cpmm_contract (Int64.add env.subsidy) state + |> (fun state -> List.fold_left ( |> ) state operations) + |> update_xtz_balance baker (fun b -> Int64.sub b security_deposit) + in + assert (invariant env state) ; + state + end +end + +(* --------------------------------------------------------------------------- *) + +(** {1 Symbolic Machine} *) + +module SymbolicBaseMachine : + MACHINE_WITH_INIT + with type 'a m = 'a + and type contract = contract_id + and type t = contract_id state = struct + include AbstractMachine.Make (struct + type t = contract_id + + let pp = pp_contract_id + end) + + let init ~invariant:_ ?(subsidy = default_subsidy) accounts_balances = + let (_, initial_balances) = initial_xtz_repartition accounts_balances in + let len = Int64.of_int (List.length accounts_balances) in + match initial_balances with + | holder_xtz :: accounts -> + let xtz_cpmm = + Int64.( + add cpmm_initial_balance.xtz (mul (blocks_during_init len) subsidy)) + in + ( { + cpmm_total_liquidity = cpmm_initial_liquidity_supply; + accounts_balances = + (Cpmm, {cpmm_initial_balance with xtz = xtz_cpmm}) + :: + (Holder, {xtz = holder_xtz; tzbtc = 0; liquidity = 0}) + :: + (TzBTCAdmin, {xtz = 0L; tzbtc = 0; liquidity = 0}) + :: + List.mapi + (fun i xtz -> + (ImplicitAccount i, {xtz; tzbtc = 0; liquidity = 0})) + accounts; + }, + { + cpmm_contract = Cpmm; + tzbtc_contract = TzBTC; + tzbtc_admin = TzBTCAdmin; + liquidity_contract = Liquidity; + liquidity_admin = LiquidityAdmin; + implicit_accounts = + List.mapi (fun i _ -> ImplicitAccount i) accounts; + holder = Holder; + subsidy; + } ) + | [] -> assert false +end + +module SymbolicMachine = struct + include SymbolicBaseMachine + include Machine.Make (SymbolicBaseMachine) + include MachineBuilder.Make (SymbolicBaseMachine) +end + +(* --------------------------------------------------------------------------- *) + +(** {1 Validation Machine} *) + +module ValidationBaseMachine : + MACHINE_WITH_INIT + with type 'a m = 'a ConcreteBaseMachine.m + and type t = ConcreteBaseMachine.t * Contract.t state + and type contract = Contract.t = struct + module GhostMachine = AbstractMachine.Make (struct + type t = Contract.t + + let pp = Contract.pp + end) + + type 'a m = 'a ConcreteBaseMachine.m + + type t = ConcreteBaseMachine.t * GhostMachine.t + + type contract = Contract.t + + type operation = ConcreteBaseMachine.operation * GhostMachine.operation + + let pp_contract = Contract.pp + + let ( >>= ) = ConcreteBaseMachine.( >>= ) + + let fold_m = ConcreteBaseMachine.fold_m + + let pure = ConcreteBaseMachine.pure + + let get_balances contract env (_, state) = + pure (GhostMachine.get_balances contract env state) + + let get_xtz_balance contract (_, state) = + pure (GhostMachine.get_xtz_balance contract state) + + let get_tzbtc_balance contract env (_, state) = + pure (GhostMachine.get_tzbtc_balance contract env state) + + let get_liquidity_balance contract env (_, state) = + pure (GhostMachine.get_liquidity_balance contract env state) + + let get_cpmm_total_liquidity env (_, state) = + pure (GhostMachine.get_cpmm_total_liquidity env state) + + let bake ~invariant ~baker ops env (blk, state) = + let cops = List.map fst ops in + let rops = List.map snd ops in + ConcreteBaseMachine.( + bake ~invariant:(fun _ _ -> pure true) ~baker cops env blk) + >>= fun blk -> + let state = + GhostMachine.bake ~invariant:(fun _ _ -> true) ~baker rops env state + in + invariant env (blk, state) >>= fun cond -> + assert cond ; + pure (blk, state) + + let transaction ~src dst xtz (blk, state) = + ConcreteBaseMachine.transaction ~src dst xtz blk >>= fun cop -> + pure (cop, GhostMachine.transaction ~src dst xtz state) + + let token_to_xtz ~src dst tzbtc env (blk, state) = + ConcreteBaseMachine.token_to_xtz ~src dst tzbtc env blk >>= fun cop -> + pure (cop, GhostMachine.token_to_xtz ~src dst tzbtc env state) + + let xtz_to_token ~src dst xtz env (blk, state) = + ConcreteBaseMachine.xtz_to_token ~src dst xtz env blk >>= fun cop -> + pure (cop, GhostMachine.xtz_to_token ~src dst xtz env state) + + let mint_or_burn_tzbtc dst tzbtc env (blk, state) = + ConcreteBaseMachine.mint_or_burn_tzbtc dst tzbtc env blk >>= fun cop -> + pure (cop, GhostMachine.mint_or_burn_tzbtc dst tzbtc env state) + + let approve_tzbtc dst tzbtc env (blk, state) = + ConcreteBaseMachine.approve_tzbtc dst tzbtc env blk >>= fun cop -> + pure (cop, GhostMachine.approve_tzbtc dst tzbtc env state) + + let add_liquidity ~src dst xtz_deposit tzbtc_deposit env (blk, state) = + ConcreteBaseMachine.add_liquidity ~src dst xtz_deposit tzbtc_deposit env blk + >>= fun cop -> + pure + ( cop, + GhostMachine.add_liquidity ~src dst xtz_deposit tzbtc_deposit env state + ) + + let remove_liquidity ~src dst lqt_burned env (blk, state) = + ConcreteBaseMachine.remove_liquidity ~src dst lqt_burned env blk + >>= fun cop -> + pure (cop, GhostMachine.remove_liquidity ~src dst lqt_burned env state) + + let reveal account (blk, state) = + ConcreteBaseMachine.reveal account blk >>= fun cop -> + pure (cop, GhostMachine.reveal account state) + + let init ~invariant ?subsidy balances = + ConcreteBaseMachine.init + ~invariant:(fun _ _ -> return true) + ?subsidy + balances + >>= fun (blk, env) -> + let (state, _) = + SymbolicBaseMachine.init ~invariant:(fun _ _ -> true) ?subsidy balances + in + let state = refine_state env state in + invariant env (blk, state) >>= fun cond -> + assert cond ; + pure ((blk, state), env) +end + +module ValidationMachine = struct + include ValidationBaseMachine + include Machine.Make (ValidationBaseMachine) + include MachineBuilder.Make (ValidationBaseMachine) + + module Symbolic = struct + let get_xtz_balance = get_xtz_balance + + let get_tzbtc_balance = get_tzbtc_balance + + let get_liquidity_balance = get_liquidity_balance + + let get_cpmm_total_liquidity = get_cpmm_total_liquidity + end + + module Concrete = struct + let get_xtz_balance contract (blk, _) = + ConcreteMachine.get_xtz_balance contract blk + + let get_tzbtc_balance contract env (blk, _) = + ConcreteMachine.get_tzbtc_balance contract env blk + + let get_liquidity_balance contract env (blk, _) = + ConcreteMachine.get_liquidity_balance contract env blk + + let get_cpmm_total_liquidity env (blk, _) = + ConcreteMachine.get_cpmm_total_liquidity env blk + end +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_machine.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_machine.mli new file mode 100644 index 000000000000..76107f8b4d61 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/liquidity_baking_machine.mli @@ -0,0 +1,387 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** This module provides the means to test extensively the Liquidity + Baking (LB) feature. We recall that this feature is built upon + three smart contracts: (1) a CPMM contract initially based on + Dexter 2, and (2) two tokens contracts. Our objective is to run + “scenarios” consisting in interleaved, realistic calls to these + contracts, and to assert these scenarios do not yield any + undesirable behaviors. + + To that end, three “machines” are provided. + + - The {! SymbolicMachine} allows to simulate scenarios involving + the LB feature completely off-chain. It can be seen as an + abstraction of the concrete implementation provided by the Tezos + node. + - The {! ConcreteMachine } allows to execute scenarios on-chain. + - The {! ValidationMachine } combines the two previously mentioned + machines. In other words, the {! ValidationMachine} makes the {! + SymbolicMachine} and the [ConcreteMachine] execute the same + scenarios, and asserts they remain synchronized after each baked + block. + + The {! ValidationMachine} allows to (1) validate the {! + SymbolicMachine} ({i i.e.,} the reimplementation of the LB + contracts logic) against the real implementation provided by + Tezos, {b and} the contracts originated by the protocol correctly + implement the LB logic, as implemented by the {! SymbolicMachine}. + That is, the {! ValidationMachine} reports desynchronization of + the two machines, but cannot explain this desynchronization. *) + +(** {1 Machine State Characterization} *) + +type xtz = int64 + +type tzbtc = int + +type liquidity = int + +(** As far as liquidity baking is concerned, an account can hold three + kinds of tokens: [xtz], [tzbtc], and [liquidity]. *) +type balances = {xtz : xtz; tzbtc : tzbtc; liquidity : liquidity} + +val pp_balances : Format.formatter -> balances -> unit + +(** A value of type [specs] allows to specify an initial state of a + “machine”. + + In a nutshell, it consists in specifying the minimal balances of + the CPMM contracts and a set of implicit contracts. The two + machines provided by this module has a [build] function which + turns a [specs] into a consistent initial state for this + machine. *) +type specs = { + cpmm_min_xtz_balance : xtz; + cpmm_min_tzbtc_balance : tzbtc; + accounts_balances : balances list; +} + +val pp_specs : Format.formatter -> specs -> unit + +(** A value of type ['a env] (where ['a] is the type of contract + identifiers) summarizes the different contracts involved in the LB + feature. + + Values of type [env] are constructed by the [build] function of + the machines. *) +type 'a env = private { + cpmm_contract : 'a; + tzbtc_contract : 'a; + tzbtc_admin : 'a; + liquidity_contract : 'a; + liquidity_admin : 'a; + implicit_accounts : 'a list; + holder : 'a; + subsidy : xtz; +} + +(** A value of type ['a step] (where ['a] is the type used to identify + contracts) describes a consistent sequence of LB smart contract + calls. + + For instance, [SellTzBTC] consists in approving an allowance in + the [TzBTC] contract, then calling the [token_to_xtz] entry point + of the [CPMM]. *) +type 'a step = + | SellTzBTC of {source : 'a; destination : 'a; tzbtc_deposit : tzbtc} + | BuyTzBTC of {source : 'a; destination : 'a; xtz_deposit : xtz} + | AddLiquidity of {source : 'a; destination : 'a; xtz_deposit : xtz} + | RemoveLiquidity of {source : 'a; destination : 'a; lqt_burned : liquidity} + +val pp_step : + (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a step -> unit + +(** A summary of the state of a machine, parameterized by the type of + contract identifier. *) +type 'a state = { + cpmm_total_liquidity : liquidity; + accounts_balances : ('a * balances) list; +} + +(** {1 The Symbolic Machine} *) + +(** In the {! SymbolicMachine}, a contract is identified by a symbolic + value. *) +type contract_id = + | Cpmm + | Holder + | TzBTC + | TzBTCAdmin + | Liquidity + | LiquidityAdmin + (* We use integers to distinguish between implicit account because + this integer has the extra benefit of being the index of the + related account in [env.implicit_accounts]. *) + | ImplicitAccount of int + +val pp_contract_id : Format.formatter -> contract_id -> unit + +module SymbolicMachine : sig + (** The state of the {! SymbolicMachine}. *) + type t = contract_id state + + (** [get_xtz_balance c state] returns the amount of mutez owned by + [c] in [state]. *) + val get_xtz_balance : contract_id -> t -> xtz + + (** [get_tzbtc_balance c env state] returns the amount of TzBTC + owned by [c] in [state], according to the [TzBTC] contract. *) + val get_tzbtc_balance : contract_id -> contract_id env -> t -> tzbtc + + (** [get_liquidity_balance c env state] returns the amount of + liquidity token owned by [c] in [state], according to the + [Liquidity] contract. *) + val get_liquidity_balance : contract_id -> contract_id env -> t -> liquidity + + (** [get_cpmm_total_liquidity env state] fetches the current amount + of liquidity tokens distributed by the CPMM contract from the + state [state]. *) + val get_cpmm_total_liquidity : contract_id env -> t -> liquidity + + (** [predict_required_tzbtc_deposit xtz_deposit env state] predicts + the deposit in TzBTC which will be required by the CPMM contract + when executing a step [AddLiquidity] with [xtz_deposit] from + [state]. *) + val predict_required_tzbtc_deposit : xtz -> contract_id env -> t -> tzbtc + + (** [build specs] computes (1) an initial state for the {! + SymbolicMachine}, and (2) the environment associated to this + state. + + The machine enforces the resulting state is consistent with the + [specs] given as inputs, and raises an [Assert_failure] + exception if it does not. + + One can use the optional argument [subsidy] to set the subsidy + amount to a given value (by default, we use the same as the main + chain). Additionally, the [invariant] optional argument can be + used to verify that a given invariant holds at the end of the + initialization. *) + val build : + ?invariant:(contract_id env -> t -> bool) -> + ?subsidy:xtz -> + specs -> + t * contract_id env + + (** [step s env state] executes a single step [s] from [state]. + + The [invariant] optional argument can be used to verify that a + given invariant holds after each baked block. *) + val step : + ?invariant:(contract_id env -> t -> bool) -> + contract_id step -> + contract_id env -> + t -> + t + + (** [run steps env state] executes a list of steps from [state]. + + The [invariant] optional argument can be used to verify that a + given invariant holds after each baked block. *) + val run : + ?invariant:(contract_id env -> t -> bool) -> + contract_id step list -> + contract_id env -> + t -> + t +end + +(** A machine that can execute scenarios onchain. *) +module ConcreteMachine : sig + (** The state of the {! ConcreteMachine}. *) + type t = Block.t + + (** [get_xtz_balance c state] returns the amount of mutez owned by + [c] in [state]. *) + val get_xtz_balance : Contract.t -> t -> xtz tzresult Lwt.t + + (** [get_tzbtc_balance c env state] returns the amount of TzBTC + owned by [c] in [state], according to the [TzBTC] contract. *) + val get_tzbtc_balance : + Contract.t -> Contract.t env -> t -> tzbtc tzresult Lwt.t + + (** [get_liquidity_balance c env state] returns the amount of + liquidity token owned by [c] in [state], according to the + [Liquidity] contract. *) + val get_liquidity_balance : + Contract.t -> Contract.t env -> t -> liquidity tzresult Lwt.t + + (** [get_cpmm_total_liquidity env state] fetches the current amount + of liquidity tokens distributed by the CPMM contract from the + state [state]. *) + val get_cpmm_total_liquidity : Contract.t env -> t -> liquidity tzresult Lwt.t + + (** [build specs] asynchronously computes (1) an initial block for + the {! ConcreteMachine}, and (2) the environment associated to + this block. + + The machine enforces the resulting state is consistent with the + [specs] given as inputs, and raises an [Assert_failure] + exception if it does not. It also enforces that the machines + used underneath remain in sync. + + One can use the optional argument [subsidy] to set the subsidy + amount to a given value (by default, we use the same as the main + chain). Additionally, the [invariant] optional argument can be + used to verify that a given invariant holds at the end of the + initialization. *) + val build : + ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> + ?subsidy:xtz -> + specs -> + (t * Contract.t env) tzresult Lwt.t + + (** [step s env state] asynchronously executes a single step [s] + from [state]. + + The [invariant] optional argument can be used to verify that a + given invariant holds after each baked block. *) + val step : + ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> + Contract.t step -> + Contract.t env -> + t -> + t tzresult Lwt.t + + (** [run lss env state] asynchronously executes a list of steps from + [state]. + + The [invariant] optional argument can be used to verify that a + given invariant holds after each baked block. *) + val run : + ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> + contract_id step list -> + Contract.t env -> + t -> + t tzresult Lwt.t +end + +module ValidationMachine : sig + (** The state of the {! ValidationMachine}. *) + type t = ConcreteMachine.t * Contract.t state + + module Symbolic : sig + (** A collections of functions to introspect the symbolic part of + the [ValidationMachine] state. *) + + (** [get_xtz_balance c state] returns the amount of mutez owned by + [c] in the symbolic part of [state]. *) + val get_xtz_balance : Contract.t -> t -> xtz tzresult Lwt.t + + (** [get_tzbtc_balance c env state] returns the amount of TzBTC + owned by [c] in the symbolic part of [state], according to the + [TzBTC] contract. *) + val get_tzbtc_balance : + Contract.t -> Contract.t env -> t -> tzbtc tzresult Lwt.t + + (** [get_liquidity_balance c env state] returns the amount of + liquidity token owned by [c] in the symbolic part of [state], + according to the [Liquidity] contract. *) + val get_liquidity_balance : + Contract.t -> Contract.t env -> t -> liquidity tzresult Lwt.t + + (** [get_cpmm_total_liquidity env state] fetches the   current + amount of liquidity tokens distributed by the CPMM   contract + using the symbolic part of the state [state]. *) + val get_cpmm_total_liquidity : + Contract.t env -> t -> liquidity tzresult Lwt.t + end + + module Concrete : sig + (** A collections of functions to introspect the concrete part of + the [ValidationMachine] state. *) + + (** [get_xtz_balance c state] returns the amount of mutez owned by + [c] in the concrete part of [state]. *) + val get_xtz_balance : Contract.t -> t -> xtz tzresult Lwt.t + + (** [get_tzbtc_balance c env state] returns the amount of TzBTC + owned by [c] in the concrete part of [state], according to the + [TzBTC] contract. *) + val get_tzbtc_balance : + Contract.t -> Contract.t env -> t -> tzbtc tzresult Lwt.t + + (** [get_liquidity_balance c env state] returns the amount of + liquidity token owned by [c] in the concrete part of [state], + according to the [Liquidity] contract. *) + val get_liquidity_balance : + Contract.t -> Contract.t env -> t -> liquidity tzresult Lwt.t + + (** [get_cpmm_total_liquidity env state] fetches the current + amount of liquidity tokens distributed by the CPMM contract + using the concrete part of the state [state]. *) + val get_cpmm_total_liquidity : + Contract.t env -> t -> liquidity tzresult Lwt.t + end + + (** [build specs] asynchronously computes (1) an initial state for + the {! ValidationMachine}, and (2) the environment associated to + this state. + + The machine enforces the resulting state is consistent with the + [specs] given as inputs, and raises an [Assert_failure] + exception if it does not. It also enforces that the machines + used underneath remain in sync. + + One can use the optional argument [subsidy] to set the subsidy + amount to a given value (by default, we use the same as the main + chain). Additionally, the [invariant] optional argument can be + used to verify that a given invariant holds at the end of the + initialization. *) + val build : + ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> + ?subsidy:xtz -> + specs -> + (t * Contract.t env) tzresult Lwt.t + + (** [step s env state] asynchronously executes a single step [s] + from [state]. + + The [invariant] optional argument can be used to verify that a + given invariant holds after each baked block. *) + val step : + ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> + Contract.t step -> + Contract.t env -> + t -> + t tzresult Lwt.t + + (** [run lss env state] asynchronously executes a list of steps from + [state]. + + The [invariant] optional argument can be used to verify that a + given invariant holds after each baked block. *) + val run : + ?invariant:(Contract.t env -> t -> bool tzresult Lwt.t) -> + contract_id step list -> + Contract.t env -> + t -> + t tzresult Lwt.t +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/lqt_fa12_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/lqt_fa12_repr.ml new file mode 100644 index 000000000000..937dfb8297b2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/lqt_fa12_repr.ml @@ -0,0 +1,252 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Expr_common + +module Parameter = struct + (* // ============================================================================= + * // Entrypoints + * // ============================================================================= *) + + (* Note: in the lqt_fa12 contract, [value] is a nat. Hence, it + should always be positive *) + type approve = {spender : Contract.t; value : Z.t} + + type mintOrBurn = {quantity : Z.t; target : Contract.t} + + (* Note: this wrapper does not implement a reprensentation for the + entrypoints transfer, getAllowance, getBalance, getTotalSupply, + as they are not used as of yet. *) + type t = Approve of approve | MintOrBurn of mintOrBurn + + let approve p = + assert (Z.lt Z.zero p.value || Z.equal Z.zero p.value) ; + Approve p + + let mintOrBurn p = MintOrBurn p + + let approve_to_string {spender; value} = + Format.asprintf + "{ spender: %a; value: %a }" + Contract.pp + spender + Z.pp_print + value + + let mint_or_burn_to_string {quantity; target} = + Format.asprintf + "{ quantity: %a; target: %a }" + Z.pp_print + quantity + Contract.pp + target + + let to_string : t -> string = function + | Approve p -> Format.asprintf "Approve %s" (approve_to_string p) + | MintOrBurn p -> Format.asprintf "MintOrBurn %s" (mint_or_burn_to_string p) + + let entrypoint_of_parameter : t -> string = function + | Approve _ -> "approve" + | MintOrBurn _ -> "mintOrBurn" + + let pp fmt s = Format.fprintf fmt "%s" (to_string s) + + let eq s s' = s = s' + + let to_expr_rooted : + loc:'a -> + t -> + ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = + fun ~loc -> function + | MintOrBurn {quantity; target} -> + comb ~loc [int ~loc quantity; address_string ~loc target] + | Approve {spender; value} -> + comb ~loc [address_string ~loc spender; int ~loc value] + + let to_expr : + loc:'a -> + t -> + ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = + fun ~loc p -> + let rooted = to_expr_rooted ~loc p in + match p with + | MintOrBurn _ -> right ~loc @@ left ~loc rooted + | Approve _ -> left ~loc @@ left ~loc @@ left ~loc rooted + + let to_michelson_string e = + let e = to_expr ~loc:0 e in + Format.asprintf + "%a" + Michelson_v1_printer.print_expr + (Micheline.strip_locations e) +end + +(* // ============================================================================= + * // Storage + * // ============================================================================= *) + +module Storage = struct + let pp_big_map_id fmt v = Z.pp_print fmt (Big_map.Id.unparse_to_z v) + + type t = { + tokens : Big_map.Id.t; + allowances : Big_map.Id.t; + admin : Contract.t; + totalSupply : Z.t; + } + + let pp {tokens; allowances; admin; totalSupply} = + Format.asprintf + "{ tokens: %a; allowances: %a; admin: %a; totalSupply: %a}" + Z.pp_print + (Big_map.Id.unparse_to_z tokens) + Z.pp_print + (Big_map.Id.unparse_to_z allowances) + Contract.pp + admin + Z.pp_print + totalSupply + + let null : t = + { + tokens = Big_map.Id.parse_z Z.zero; + allowances = Big_map.Id.parse_z Z.one; + admin = Contract.implicit_contract Signature.Public_key_hash.zero; + totalSupply = Z.zero; + } + + let eq s s' = s = s' + + let to_expr : + loc:'a -> + t -> + ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node = + fun ~loc {tokens; allowances; admin; totalSupply} -> + comb + ~loc + [ + big_map_id ~loc tokens; + big_map_id ~loc allowances; + address_string ~loc admin; + int ~loc totalSupply; + ] + + let to_michelson_string e = + let e = to_expr ~loc:0 e in + Format.asprintf + "%a" + Michelson_v1_printer.print_expr + (Micheline.strip_locations e) + + type exn += Invalid_storage_expr of string + + (** Note: parses a storage unparsed in readable mode (as + e.g. returned by [Alpha_services.Contract.storage]), so that + contracts are represented by strings. *) + let of_expr_exn : + ('a, Michelson_v1_primitives.prim) Tezos_micheline.Micheline.node -> t = + function + | Tezos_micheline.Micheline.Prim + ( _, + Script.D_Pair, + [ + Tezos_micheline.Micheline.Int (_, tokens); + Tezos_micheline.Micheline.Int (_, allowances); + Tezos_micheline.Micheline.String (_, admin); + Tezos_micheline.Micheline.Int (_, totalSupply); + ], + [] ) -> + let tokens = Big_map.Id.parse_z tokens in + let allowances = Big_map.Id.parse_z allowances in + let admin = address_of_string_exn admin in + {tokens; allowances; admin; totalSupply} + | e -> + let canonical = Micheline.strip_locations e in + let msg = + Format.asprintf + "Not a valid LQT_FA1.2 storage: %s /// %a" + (try + Michelson_v1_printer.micheline_string_of_expression + ~zero_loc:true + canonical + with Z.Overflow -> + "Cannot represent as micheline due to overflowing Z -> int") + Michelson_v1_printer.print_expr + canonical + in + raise (Invalid_storage_expr msg) + + let get (ctxt : Context.t) ~(contract : Contract.t) : t tzresult Lwt.t = + Context.Contract.storage ctxt contract >|=? Micheline.root >|=? of_expr_exn + + let get_alpha_context (ctxt : Context.t) : Alpha_context.t tzresult Lwt.t = + (match ctxt with + | B b -> + (* can perhaps be retrieved through Raw_context.prepare ? *) + Incremental.begin_construction b + | I i -> return i) + >|=? Incremental.alpha_ctxt + + let getBalance_opt (ctxt : Context.t) ~(contract : Contract.t) + (owner : Script_typed_ir.address) = + get ctxt ~contract >>=? fun storage -> + let tokens = storage.tokens in + get_alpha_context ctxt >>=? fun ctxt -> + Script_ir_translator.hash_data + ctxt + Script_typed_ir.(address_t ~annot:None) + owner + >|= Environment.wrap_tzresult + >>=? fun (address_hash, ctxt) -> + Big_map.get_opt ctxt tokens address_hash >|= Environment.wrap_tzresult + >>=? function + | (_, Some canonical) -> ( + match Tezos_micheline.Micheline.root canonical with + | Tezos_micheline.Micheline.Int (_, amount) -> return @@ Some amount + | _ -> assert false) + | (_, None) -> return @@ None + + let getBalance (ctxt : Context.t) ~(contract : Contract.t) + (owner : Script_typed_ir.address) = + getBalance_opt ctxt ~contract owner >|=? Option.value ~default:Z.zero +end + +let transaction (ctxt : Context.t) ~(contract : Contract.t) ~(src : Contract.t) + ?(amount = Tez.zero) (parameters : Parameter.t) = + let entrypoint = Parameter.entrypoint_of_parameter parameters in + let rooted_param_lazy = + parameters + |> Parameter.to_expr_rooted ~loc:0 + |> Micheline.strip_locations |> Alpha_context.Script.lazy_expr + in + Op.transaction + ctxt + src + contract + amount + ~entrypoint + ~parameters:rooted_param_lazy diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/nonce.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/nonce.ml new file mode 100644 index 000000000000..695cdcdbbec9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/nonce.ml @@ -0,0 +1,35 @@ +(**************************************************************************) +(* *) +(* Copyright (c) 2014 - 2018. *) +(* Dynamic Ledger Solutions, Inc.< contact@tezos.com > *) +(* *) +(* All rights reserved.No warranty, explicit or implicit, provided. *) +(* *) +(**************************************************************************) + +open Protocol + +module Table = Hashtbl.Make (struct + type t = Nonce_hash.t + + let hash h = Int32.to_int (TzEndian.get_int32 (Nonce_hash.to_bytes h) 0) + + let equal = Nonce_hash.equal +end) + +let known_nonces = Table.create 17 + +let generate () = + match + Alpha_context.Nonce.of_bytes + @@ Rand.generate Alpha_context.Constants.nonce_length + with + | Ok nonce -> + let hash = Alpha_context.Nonce.hash nonce in + Table.add known_nonces hash nonce ; + (hash, nonce) + | Error _ -> assert false + +let forget_all () = Table.clear known_nonces + +let get hash = Table.find known_nonces hash diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/nonce.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/nonce.mli new file mode 100644 index 000000000000..8a8b258b0658 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/nonce.mli @@ -0,0 +1,33 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** Returns a fresh nonce and its corresponding hash (and stores them). *) +val generate : unit -> Nonce_hash.t * Alpha_context.Nonce.t + +val get : Nonce_hash.t -> Alpha_context.Nonce.t option + +val forget_all : unit -> unit diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/op.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/op.ml new file mode 100644 index 000000000000..336715cea48f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/op.ml @@ -0,0 +1,476 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +let sign ?(watermark = Signature.Generic_operation) sk ctxt contents = + let branch = Context.branch ctxt in + let unsigned = + Data_encoding.Binary.to_bytes_exn + Operation.unsigned_encoding + ({branch}, Contents_list contents) + in + let signature = Some (Signature.sign ~watermark sk unsigned) in + ({shell = {branch}; protocol_data = {contents; signature}} : _ Operation.t) + +(** Generates the block payload hash based on the hash [pred_hash] of + the predecessor block and the hash of non-consensus operations of + the current block [b]. *) +let mk_block_payload_hash pred_hash payload_round (b : Block.t) = + let ops = Block.Forge.classify_operations b.operations in + let non_consensus_operations = + List.concat (match List.tl ops with None -> [] | Some l -> l) + in + let hashes = List.map Operation.hash_packed non_consensus_operations in + let non_consensus_operations_hash = Operation_list_hash.compute hashes in + Block_payload.hash + ~predecessor:pred_hash + payload_round + non_consensus_operations_hash + +(* ctxt is used for getting the branch in sign *) +let endorsement ?delegate ?slot ?level ?round ?block_payload_hash + ~endorsed_block ctxt ?(signing_context = ctxt) () = + let pred_hash = match ctxt with Context.B b -> b.hash | _ -> assert false in + (match delegate with + | None -> Context.get_endorser (B endorsed_block) + | Some v -> return v) + >>=? fun (delegate_pkh, slots) -> + let slot = + match slot with None -> Stdlib.List.hd slots | Some slot -> slot + in + (match level with + | None -> Context.get_level (B endorsed_block) + | Some level -> ok level) + >>?= fun level -> + (match round with + | None -> Block.get_round endorsed_block + | Some round -> ok round) + >>?= fun round -> + let block_payload_hash = + match block_payload_hash with + | None -> mk_block_payload_hash pred_hash round endorsed_block + | Some block_payload_hash -> block_payload_hash + in + let consensus_content = {slot; level; round; block_payload_hash} in + let op = Single (Endorsement consensus_content) in + Account.find delegate_pkh >>=? fun delegate -> + return + (sign + ~watermark:Operation.(to_watermark (Endorsement Chain_id.zero)) + delegate.sk + signing_context + op) + +let preendorsement ?delegate ?slot ?level ?round ?block_payload_hash + ~endorsed_block ctxt ?(signing_context = ctxt) () = + let pred_hash = match ctxt with Context.B b -> b.hash | _ -> assert false in + (match delegate with + | None -> Context.get_endorser (B endorsed_block) + | Some v -> return v) + >>=? fun (delegate_pkh, slots) -> + let slot = + match slot with None -> Stdlib.List.hd slots | Some slot -> slot + in + (match level with + | None -> Context.get_level (B endorsed_block) + | Some level -> ok level) + >>?= fun level -> + (match round with + | None -> Block.get_round endorsed_block + | Some round -> ok round) + >>?= fun round -> + let block_payload_hash = + match block_payload_hash with + | None -> mk_block_payload_hash pred_hash round endorsed_block + | Some block_payload_hash -> block_payload_hash + in + let consensus_content = {slot; level; round; block_payload_hash} in + let op = Single (Preendorsement consensus_content) in + Account.find delegate_pkh >>=? fun delegate -> + return + (sign + ~watermark:Operation.(to_watermark (Preendorsement Chain_id.zero)) + delegate.sk + signing_context + op) + +let sign ?watermark sk ctxt (Contents_list contents) = + Operation.pack (sign ?watermark sk ctxt contents) + +let combine_operations ?public_key ?counter ?spurious_operation ~source ctxt + (packed_operations : packed_operation list) = + assert (match packed_operations with [] -> false | _ :: _ -> true) ; + (* Hypothesis : each operation must have the same branch (is this really true?) *) + let {Tezos_base.Operation.branch} = + (WithExceptions.Option.get ~loc:__LOC__ @@ List.hd packed_operations).shell + in + assert ( + List.for_all + (fun {shell = {Tezos_base.Operation.branch = b; _}; _} -> + Block_hash.(branch = b)) + packed_operations) ; + (* TODO? : check signatures consistency *) + let unpacked_operations = + List.map + (function + | {Alpha_context.protocol_data = Operation_data {contents; _}; _} -> ( + match Contents_list contents with + | Contents_list (Single o) -> Contents o + | Contents_list + (Cons (Manager_operation {operation = Reveal _; _}, Single o)) + -> + Contents o + | _ -> (* TODO : decent error *) assert false)) + packed_operations + in + (match counter with + | Some counter -> return counter + | None -> Context.Contract.counter ctxt source) + >>=? fun counter -> + (* We increment the counter *) + let counter = Z.succ counter in + Context.Contract.manager ctxt source >>=? fun account -> + let public_key = Option.value ~default:account.pk public_key in + (Context.Contract.is_manager_key_revealed ctxt source >|=? function + | false -> + let reveal_op = + Manager_operation + { + source = Signature.Public_key.hash public_key; + fee = Tez.zero; + counter; + operation = Reveal public_key; + gas_limit = Gas.Arith.integral_of_int_exn 10_000; + storage_limit = Z.zero; + } + in + (Some (Contents reveal_op), Z.succ counter) + | true -> (None, counter)) + >>=? fun (manager_op, counter) -> + (* Update counters and transform into a contents_list *) + let operations = + List.fold_left + (fun (counter, acc) -> function + | Contents (Manager_operation m) -> + ( Z.succ counter, + Contents (Manager_operation {m with counter}) :: acc ) + | x -> (counter, x :: acc)) + (counter, match manager_op with None -> [] | Some op -> [op]) + unpacked_operations + |> snd |> List.rev + in + (* patch a random operation with a corrupted pkh *) + let operations = + match spurious_operation with + | None -> operations + | Some op -> ( + let op = + match op with + | {protocol_data; shell = _} -> ( + match protocol_data with + | Operation_data {contents; _} -> ( + match contents with + | Cons _ -> assert false + | Single op -> Alpha_context.Contents op)) + in + (* Select where to insert spurious op *) + let legit_ops = List.length operations in + let index = Random.int legit_ops in + match List.split_n index operations with + | (preserved_prefix, preserved_suffix) -> + preserved_prefix @ op :: preserved_suffix) + in + Environment.wrap_tzresult @@ Operation.of_list operations + >>?= fun operations -> return @@ sign account.sk ctxt operations + +let manager_operation ?counter ?(fee = Tez.zero) ?gas_limit ?storage_limit + ?public_key ~source ctxt operation = + (match counter with + | Some counter -> return counter + | None -> Context.Contract.counter ctxt source) + >>=? fun counter -> + Context.get_constants ctxt >>=? fun c -> + let gas_limit = + let default = c.parametric.hard_gas_limit_per_operation in + Option.value ~default gas_limit + in + let storage_limit = + Option.value + ~default:c.parametric.hard_storage_limit_per_operation + storage_limit + in + Context.Contract.manager ctxt source >>=? fun account -> + let public_key = Option.value ~default:account.pk public_key in + let counter = Z.succ counter in + Context.Contract.is_manager_key_revealed ctxt source >|=? function + | true -> + let op = + Manager_operation + { + source = Signature.Public_key.hash public_key; + fee; + counter; + operation; + gas_limit; + storage_limit; + } + in + Contents_list (Single op) + | false -> + let op_reveal = + Manager_operation + { + source = Signature.Public_key.hash public_key; + fee = Tez.zero; + counter; + operation = Reveal public_key; + gas_limit = Gas.Arith.integral_of_int_exn 10000; + storage_limit = Z.zero; + } + in + let op = + Manager_operation + { + source = Signature.Public_key.hash public_key; + fee; + counter = Z.succ counter; + operation; + gas_limit; + storage_limit; + } + in + Contents_list (Cons (op_reveal, Single op)) + +let revelation ?(fee = Tez.zero) ctxt public_key = + let pkh = Signature.Public_key.hash public_key in + let source = Contract.implicit_contract pkh in + Context.Contract.counter ctxt source >>=? fun counter -> + Context.Contract.manager ctxt source >|=? fun account -> + let counter = Z.succ counter in + let sop = + Contents_list + (Single + (Manager_operation + { + source = Signature.Public_key.hash public_key; + fee; + counter; + operation = Reveal public_key; + gas_limit = Gas.Arith.integral_of_int_exn 10000; + storage_limit = Z.zero; + })) + in + sign account.sk ctxt sop + +let failing_noop ctxt source arbitrary = + let op = Contents_list (Single (Failing_noop arbitrary)) in + Account.find source >>=? fun account -> return @@ sign account.sk ctxt op + +let originated_contract op = + let nonce = Contract.initial_origination_nonce (Operation.hash_packed op) in + Contract.originated_contract nonce + +exception Impossible + +let origination ?counter ?delegate ~script ?(preorigination = None) ?public_key + ?credit ?fee ?gas_limit ?storage_limit ctxt source = + Context.Contract.manager ctxt source >>=? fun account -> + let default_credit = Tez.of_mutez @@ Int64.of_int 1000001 in + let default_credit = + WithExceptions.Option.to_exn ~none:Impossible default_credit + in + let credit = Option.value ~default:default_credit credit in + let operation = Origination {delegate; script; credit; preorigination} in + manager_operation + ?counter + ?public_key + ?fee + ?gas_limit + ?storage_limit + ~source + ctxt + operation + >|=? fun sop -> + let op = sign account.sk ctxt sop in + (op, originated_contract op) + +let register_global_constant ?counter ?public_key ?fee ?gas_limit ?storage_limit + ctxt ~source ~value = + Context.Contract.manager ctxt source >>=? fun account -> + let operation = Register_global_constant {value} in + manager_operation + ?counter + ?public_key + ?fee + ?gas_limit + ?storage_limit + ~source + ctxt + operation + >|=? fun sop -> sign account.sk ctxt sop + +let miss_signed_endorsement ?level ~endorsed_block ctxt = + (match level with None -> Context.get_level ctxt | Some level -> ok level) + >>?= fun level -> + Context.get_endorser ctxt >>=? fun (real_delegate_pkh, slots) -> + let delegate = Account.find_alternate real_delegate_pkh in + endorsement ~delegate:(delegate.pkh, slots) ~level ~endorsed_block ctxt () + +let transaction ?counter ?fee ?gas_limit ?storage_limit + ?(parameters = Script.unit_parameter) ?(entrypoint = "default") ctxt + (src : Contract.t) (dst : Contract.t) (amount : Tez.t) = + let top = Transaction {amount; parameters; destination = dst; entrypoint} in + manager_operation ?counter ?fee ?gas_limit ?storage_limit ~source:src ctxt top + >>=? fun sop -> + Context.Contract.manager ctxt src >|=? fun account -> sign account.sk ctxt sop + +let delegation ?fee ctxt source dst = + let top = Delegation dst in + manager_operation + ?fee + ~gas_limit:(Gas.Arith.integral_of_int_exn 1000) + ~source + ctxt + top + >>=? fun sop -> + Context.Contract.manager ctxt source >|=? fun account -> + sign account.sk ctxt sop + +let set_deposits_limit ?fee ctxt source limit = + let top = Set_deposits_limit limit in + manager_operation + ?fee + ~gas_limit:(Gas.Arith.integral_of_int_exn 1000) + ~source + ctxt + top + >>=? fun sop -> + Context.Contract.manager ctxt source >|=? fun account -> + sign account.sk ctxt sop + +let activation ctxt (pkh : Signature.Public_key_hash.t) activation_code = + (match pkh with + | Ed25519 edpkh -> return edpkh + | _ -> + failwith + "Wrong public key hash : %a - Commitments must be activated with an \ + Ed25519 encrypted public key hash" + Signature.Public_key_hash.pp + pkh) + >|=? fun id -> + let contents = Single (Activate_account {id; activation_code}) in + let branch = Context.branch ctxt in + { + shell = {branch}; + protocol_data = Operation_data {contents; signature = None}; + } + +let double_endorsement ctxt op1 op2 = + let contents = Single (Double_endorsement_evidence {op1; op2}) in + let branch = Context.branch ctxt in + { + shell = {branch}; + protocol_data = Operation_data {contents; signature = None}; + } + +let double_preendorsement ctxt op1 op2 = + let contents = Single (Double_preendorsement_evidence {op1; op2}) in + let branch = Context.branch ctxt in + { + shell = {branch}; + protocol_data = Operation_data {contents; signature = None}; + } + +let double_baking ctxt bh1 bh2 = + let contents = Single (Double_baking_evidence {bh1; bh2}) in + let branch = Context.branch ctxt in + { + shell = {branch}; + protocol_data = Operation_data {contents; signature = None}; + } + +let seed_nonce_revelation ctxt level nonce = + { + shell = {branch = Context.branch ctxt}; + protocol_data = + Operation_data + { + contents = Single (Seed_nonce_revelation {level; nonce}); + signature = None; + }; + } + +let proposals ctxt (pkh : Contract.t) proposals = + Context.Contract.pkh pkh >>=? fun source -> + Context.Vote.get_current_period ctxt + >>=? fun {voting_period = {index; _}; _} -> + let op = Proposals {source; period = index; proposals} in + Account.find source >|=? fun account -> + sign account.sk ctxt (Contents_list (Single op)) + +let ballot ctxt (pkh : Contract.t) proposal ballot = + Context.Contract.pkh pkh >>=? fun source -> + Context.Vote.get_current_period ctxt + >>=? fun {voting_period = {index; _}; _} -> + let op = Ballot {source; period = index; proposal; ballot} in + Account.find source >|=? fun account -> + sign account.sk ctxt (Contents_list (Single op)) + +let dummy_script = + let open Micheline in + Script. + { + code = + lazy_expr + (strip_locations + (Seq + ( (), + [ + Prim ((), K_parameter, [Prim ((), T_unit, [], [])], []); + Prim ((), K_storage, [Prim ((), T_unit, [], [])], []); + Prim + ( (), + K_code, + [ + Seq + ( (), + [ + Prim ((), I_CDR, [], []); + Prim + ( (), + I_NIL, + [Prim ((), T_operation, [], [])], + [] ); + Prim ((), I_PAIR, [], []); + ] ); + ], + [] ); + ] ))); + storage = lazy_expr (strip_locations (Prim ((), D_Unit, [], []))); + } + +let dummy_script_cost = Test_tez.of_mutez_exn 9_500L diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/op.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/op.mli new file mode 100644 index 000000000000..77aeec462235 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/op.mli @@ -0,0 +1,175 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +val endorsement : + ?delegate:public_key_hash * Slot.t list -> + ?slot:Slot.t -> + ?level:Raw_level.t -> + ?round:Round.t -> + ?block_payload_hash:Block_payload_hash.t -> + endorsed_block:Block.t -> + Context.t -> + ?signing_context:Context.t -> + unit -> + Kind.endorsement Operation.t tzresult Lwt.t + +val preendorsement : + ?delegate:public_key_hash * Slot.t list -> + ?slot:Slot.t -> + ?level:Raw_level.t -> + ?round:Round.t -> + ?block_payload_hash:Block_payload_hash.t -> + endorsed_block:Block.t -> + Context.t -> + ?signing_context:Context.t -> + unit -> + Kind.preendorsement Operation.t tzresult Lwt.t + +val miss_signed_endorsement : + ?level:Raw_level.t -> + endorsed_block:Block.t -> + Context.t -> + Kind.endorsement Operation.t tzresult Lwt.t + +val transaction : + ?counter:Z.t -> + ?fee:Tez.tez -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + ?parameters:Script.lazy_expr -> + ?entrypoint:string -> + Context.t -> + Contract.t -> + Contract.t -> + Tez.t -> + Operation.packed tzresult Lwt.t + +val delegation : + ?fee:Tez.tez -> + Context.t -> + Contract.t -> + public_key_hash option -> + Operation.packed tzresult Lwt.t + +val set_deposits_limit : + ?fee:Tez.tez -> + Context.t -> + Contract.t -> + Tez.tez option -> + Operation.packed tzresult Lwt.t + +val revelation : + ?fee:Tez.tez -> Context.t -> public_key -> Operation.packed tzresult Lwt.t + +val failing_noop : + Context.t -> public_key_hash -> string -> Operation.packed tzresult Lwt.t + +val origination : + ?counter:Z.t -> + ?delegate:public_key_hash -> + script:Script.t -> + ?preorigination:Contract.contract option -> + ?public_key:public_key -> + ?credit:Tez.tez -> + ?fee:Tez.tez -> + ?gas_limit:Gas.Arith.integral -> + ?storage_limit:Z.t -> + Context.t -> + Contract.contract -> + (Operation.packed * Contract.contract) tzresult Lwt.t + +val originated_contract : Operation.packed -> Contract.contract + +val register_global_constant : + ?counter:Z.t -> + ?public_key:Signature.public_key -> + ?fee:Tez.tez -> + ?gas_limit:Alpha_context.Gas.Arith.integral -> + ?storage_limit:Z.t -> + Context.t -> + (* Account doing the registration *) + source:Contract.t -> + (* Micheline value to be registered *) + value:Protocol.Alpha_context.Script.lazy_expr -> + (Protocol.operation, tztrace) result Lwt.t + +val double_endorsement : + Context.t -> + Kind.endorsement Operation.t -> + Kind.endorsement Operation.t -> + Operation.packed + +val double_preendorsement : + Context.t -> + Kind.preendorsement Operation.t -> + Kind.preendorsement Operation.t -> + Operation.packed + +val double_baking : + Context.t -> + Block_header.block_header -> + Block_header.block_header -> + Operation.packed + +val activation : + Context.t -> + Signature.Public_key_hash.t -> + Blinded_public_key_hash.activation_code -> + Operation.packed tzresult Lwt.t + +val combine_operations : + ?public_key:public_key -> + ?counter:counter -> + ?spurious_operation:packed_operation -> + source:Contract.t -> + Context.t -> + packed_operation list -> + packed_operation tzresult Lwt.t + +(** Reveals a seed_nonce that was previously committed at a certain level *) +val seed_nonce_revelation : + Context.t -> Raw_level.t -> Nonce.t -> Operation.packed + +(** Propose a list of protocol hashes during the approval voting *) +val proposals : + Context.t -> + Contract.t -> + Protocol_hash.t list -> + Operation.packed tzresult Lwt.t + +(** Cast a vote yay, nay or pass *) +val ballot : + Context.t -> + Contract.t -> + Protocol_hash.t -> + Vote.ballot -> + Operation.packed tzresult Lwt.t + +val dummy_script : Script.t + +val dummy_script_cost : Tez.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/rewards.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/rewards.ml new file mode 100644 index 000000000000..bc9c833a8221 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/rewards.ml @@ -0,0 +1,1641 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2019--2021 Nomadic Labs, *) +(* Copyright (c) 2019 Cryptium Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** The tables are precomputed using this the following formulas: + +let max_endos = 256 +let max_reward = 40 + +let r = 0.5 +let a = 3. +let b = 1.5 + +let ( -- ) i j = List.init (j - i + 1) (fun x -> x + i) + +let baking_rewards = + let reward p e = + let r_aux = + if p = 0 then + r *. (float_of_int max_reward) + else + a + in + let r = r_aux /. (float_of_int max_endos) in + let r = 1_000_000. *. r in + Float.to_int ((float_of_int e) *. (ceil r)) in + + let ps = 0 -- 2 in + let es = 0 -- max_endos in + + List.map (fun p -> + List.map (fun e -> + reward p e + ) es |> Array.of_list + ) ps |> Array.of_list + + +let endorsing_rewards = + let reward p e = + let r_aux = + (1. -. r) *. + (float_of_int max_reward) /. + (float_of_int max_endos) in + let r = if p = 0 then r_aux else r_aux /. b in + let r = 1_000_000. *. r in + Float.to_int ((float_of_int e) *. (floor r)) in + + let ps = 0 -- 2 in + let es = 0 -- max_endos in + + List.map (fun p -> + List.map (fun e -> + reward p e + ) es |> Array.of_list + ) ps |> Array.of_list + + *) + +let baking_rewards : int array array = + [| + [| + 0; + 78125; + 156250; + 234375; + 312500; + 390625; + 468750; + 546875; + 625000; + 703125; + 781250; + 859375; + 937500; + 1015625; + 1093750; + 1171875; + 1250000; + 1328125; + 1406250; + 1484375; + 1562500; + 1640625; + 1718750; + 1796875; + 1875000; + 1953125; + 2031250; + 2109375; + 2187500; + 2265625; + 2343750; + 2421875; + 2500000; + 2578125; + 2656250; + 2734375; + 2812500; + 2890625; + 2968750; + 3046875; + 3125000; + 3203125; + 3281250; + 3359375; + 3437500; + 3515625; + 3593750; + 3671875; + 3750000; + 3828125; + 3906250; + 3984375; + 4062500; + 4140625; + 4218750; + 4296875; + 4375000; + 4453125; + 4531250; + 4609375; + 4687500; + 4765625; + 4843750; + 4921875; + 5000000; + 5078125; + 5156250; + 5234375; + 5312500; + 5390625; + 5468750; + 5546875; + 5625000; + 5703125; + 5781250; + 5859375; + 5937500; + 6015625; + 6093750; + 6171875; + 6250000; + 6328125; + 6406250; + 6484375; + 6562500; + 6640625; + 6718750; + 6796875; + 6875000; + 6953125; + 7031250; + 7109375; + 7187500; + 7265625; + 7343750; + 7421875; + 7500000; + 7578125; + 7656250; + 7734375; + 7812500; + 7890625; + 7968750; + 8046875; + 8125000; + 8203125; + 8281250; + 8359375; + 8437500; + 8515625; + 8593750; + 8671875; + 8750000; + 8828125; + 8906250; + 8984375; + 9062500; + 9140625; + 9218750; + 9296875; + 9375000; + 9453125; + 9531250; + 9609375; + 9687500; + 9765625; + 9843750; + 9921875; + 10000000; + 10078125; + 10156250; + 10234375; + 10312500; + 10390625; + 10468750; + 10546875; + 10625000; + 10703125; + 10781250; + 10859375; + 10937500; + 11015625; + 11093750; + 11171875; + 11250000; + 11328125; + 11406250; + 11484375; + 11562500; + 11640625; + 11718750; + 11796875; + 11875000; + 11953125; + 12031250; + 12109375; + 12187500; + 12265625; + 12343750; + 12421875; + 12500000; + 12578125; + 12656250; + 12734375; + 12812500; + 12890625; + 12968750; + 13046875; + 13125000; + 13203125; + 13281250; + 13359375; + 13437500; + 13515625; + 13593750; + 13671875; + 13750000; + 13828125; + 13906250; + 13984375; + 14062500; + 14140625; + 14218750; + 14296875; + 14375000; + 14453125; + 14531250; + 14609375; + 14687500; + 14765625; + 14843750; + 14921875; + 15000000; + 15078125; + 15156250; + 15234375; + 15312500; + 15390625; + 15468750; + 15546875; + 15625000; + 15703125; + 15781250; + 15859375; + 15937500; + 16015625; + 16093750; + 16171875; + 16250000; + 16328125; + 16406250; + 16484375; + 16562500; + 16640625; + 16718750; + 16796875; + 16875000; + 16953125; + 17031250; + 17109375; + 17187500; + 17265625; + 17343750; + 17421875; + 17500000; + 17578125; + 17656250; + 17734375; + 17812500; + 17890625; + 17968750; + 18046875; + 18125000; + 18203125; + 18281250; + 18359375; + 18437500; + 18515625; + 18593750; + 18671875; + 18750000; + 18828125; + 18906250; + 18984375; + 19062500; + 19140625; + 19218750; + 19296875; + 19375000; + 19453125; + 19531250; + 19609375; + 19687500; + 19765625; + 19843750; + 19921875; + 20000000; + |]; + [| + 0; + 11719; + 23438; + 35157; + 46876; + 58595; + 70314; + 82033; + 93752; + 105471; + 117190; + 128909; + 140628; + 152347; + 164066; + 175785; + 187504; + 199223; + 210942; + 222661; + 234380; + 246099; + 257818; + 269537; + 281256; + 292975; + 304694; + 316413; + 328132; + 339851; + 351570; + 363289; + 375008; + 386727; + 398446; + 410165; + 421884; + 433603; + 445322; + 457041; + 468760; + 480479; + 492198; + 503917; + 515636; + 527355; + 539074; + 550793; + 562512; + 574231; + 585950; + 597669; + 609388; + 621107; + 632826; + 644545; + 656264; + 667983; + 679702; + 691421; + 703140; + 714859; + 726578; + 738297; + 750016; + 761735; + 773454; + 785173; + 796892; + 808611; + 820330; + 832049; + 843768; + 855487; + 867206; + 878925; + 890644; + 902363; + 914082; + 925801; + 937520; + 949239; + 960958; + 972677; + 984396; + 996115; + 1007834; + 1019553; + 1031272; + 1042991; + 1054710; + 1066429; + 1078148; + 1089867; + 1101586; + 1113305; + 1125024; + 1136743; + 1148462; + 1160181; + 1171900; + 1183619; + 1195338; + 1207057; + 1218776; + 1230495; + 1242214; + 1253933; + 1265652; + 1277371; + 1289090; + 1300809; + 1312528; + 1324247; + 1335966; + 1347685; + 1359404; + 1371123; + 1382842; + 1394561; + 1406280; + 1417999; + 1429718; + 1441437; + 1453156; + 1464875; + 1476594; + 1488313; + 1500032; + 1511751; + 1523470; + 1535189; + 1546908; + 1558627; + 1570346; + 1582065; + 1593784; + 1605503; + 1617222; + 1628941; + 1640660; + 1652379; + 1664098; + 1675817; + 1687536; + 1699255; + 1710974; + 1722693; + 1734412; + 1746131; + 1757850; + 1769569; + 1781288; + 1793007; + 1804726; + 1816445; + 1828164; + 1839883; + 1851602; + 1863321; + 1875040; + 1886759; + 1898478; + 1910197; + 1921916; + 1933635; + 1945354; + 1957073; + 1968792; + 1980511; + 1992230; + 2003949; + 2015668; + 2027387; + 2039106; + 2050825; + 2062544; + 2074263; + 2085982; + 2097701; + 2109420; + 2121139; + 2132858; + 2144577; + 2156296; + 2168015; + 2179734; + 2191453; + 2203172; + 2214891; + 2226610; + 2238329; + 2250048; + 2261767; + 2273486; + 2285205; + 2296924; + 2308643; + 2320362; + 2332081; + 2343800; + 2355519; + 2367238; + 2378957; + 2390676; + 2402395; + 2414114; + 2425833; + 2437552; + 2449271; + 2460990; + 2472709; + 2484428; + 2496147; + 2507866; + 2519585; + 2531304; + 2543023; + 2554742; + 2566461; + 2578180; + 2589899; + 2601618; + 2613337; + 2625056; + 2636775; + 2648494; + 2660213; + 2671932; + 2683651; + 2695370; + 2707089; + 2718808; + 2730527; + 2742246; + 2753965; + 2765684; + 2777403; + 2789122; + 2800841; + 2812560; + 2824279; + 2835998; + 2847717; + 2859436; + 2871155; + 2882874; + 2894593; + 2906312; + 2918031; + 2929750; + 2941469; + 2953188; + 2964907; + 2976626; + 2988345; + 3000064; + |]; + [| + 0; + 11719; + 23438; + 35157; + 46876; + 58595; + 70314; + 82033; + 93752; + 105471; + 117190; + 128909; + 140628; + 152347; + 164066; + 175785; + 187504; + 199223; + 210942; + 222661; + 234380; + 246099; + 257818; + 269537; + 281256; + 292975; + 304694; + 316413; + 328132; + 339851; + 351570; + 363289; + 375008; + 386727; + 398446; + 410165; + 421884; + 433603; + 445322; + 457041; + 468760; + 480479; + 492198; + 503917; + 515636; + 527355; + 539074; + 550793; + 562512; + 574231; + 585950; + 597669; + 609388; + 621107; + 632826; + 644545; + 656264; + 667983; + 679702; + 691421; + 703140; + 714859; + 726578; + 738297; + 750016; + 761735; + 773454; + 785173; + 796892; + 808611; + 820330; + 832049; + 843768; + 855487; + 867206; + 878925; + 890644; + 902363; + 914082; + 925801; + 937520; + 949239; + 960958; + 972677; + 984396; + 996115; + 1007834; + 1019553; + 1031272; + 1042991; + 1054710; + 1066429; + 1078148; + 1089867; + 1101586; + 1113305; + 1125024; + 1136743; + 1148462; + 1160181; + 1171900; + 1183619; + 1195338; + 1207057; + 1218776; + 1230495; + 1242214; + 1253933; + 1265652; + 1277371; + 1289090; + 1300809; + 1312528; + 1324247; + 1335966; + 1347685; + 1359404; + 1371123; + 1382842; + 1394561; + 1406280; + 1417999; + 1429718; + 1441437; + 1453156; + 1464875; + 1476594; + 1488313; + 1500032; + 1511751; + 1523470; + 1535189; + 1546908; + 1558627; + 1570346; + 1582065; + 1593784; + 1605503; + 1617222; + 1628941; + 1640660; + 1652379; + 1664098; + 1675817; + 1687536; + 1699255; + 1710974; + 1722693; + 1734412; + 1746131; + 1757850; + 1769569; + 1781288; + 1793007; + 1804726; + 1816445; + 1828164; + 1839883; + 1851602; + 1863321; + 1875040; + 1886759; + 1898478; + 1910197; + 1921916; + 1933635; + 1945354; + 1957073; + 1968792; + 1980511; + 1992230; + 2003949; + 2015668; + 2027387; + 2039106; + 2050825; + 2062544; + 2074263; + 2085982; + 2097701; + 2109420; + 2121139; + 2132858; + 2144577; + 2156296; + 2168015; + 2179734; + 2191453; + 2203172; + 2214891; + 2226610; + 2238329; + 2250048; + 2261767; + 2273486; + 2285205; + 2296924; + 2308643; + 2320362; + 2332081; + 2343800; + 2355519; + 2367238; + 2378957; + 2390676; + 2402395; + 2414114; + 2425833; + 2437552; + 2449271; + 2460990; + 2472709; + 2484428; + 2496147; + 2507866; + 2519585; + 2531304; + 2543023; + 2554742; + 2566461; + 2578180; + 2589899; + 2601618; + 2613337; + 2625056; + 2636775; + 2648494; + 2660213; + 2671932; + 2683651; + 2695370; + 2707089; + 2718808; + 2730527; + 2742246; + 2753965; + 2765684; + 2777403; + 2789122; + 2800841; + 2812560; + 2824279; + 2835998; + 2847717; + 2859436; + 2871155; + 2882874; + 2894593; + 2906312; + 2918031; + 2929750; + 2941469; + 2953188; + 2964907; + 2976626; + 2988345; + 3000064; + |]; + |] + +let endorsing_rewards : int array array = + [| + [| + 0; + 78125; + 156250; + 234375; + 312500; + 390625; + 468750; + 546875; + 625000; + 703125; + 781250; + 859375; + 937500; + 1015625; + 1093750; + 1171875; + 1250000; + 1328125; + 1406250; + 1484375; + 1562500; + 1640625; + 1718750; + 1796875; + 1875000; + 1953125; + 2031250; + 2109375; + 2187500; + 2265625; + 2343750; + 2421875; + 2500000; + 2578125; + 2656250; + 2734375; + 2812500; + 2890625; + 2968750; + 3046875; + 3125000; + 3203125; + 3281250; + 3359375; + 3437500; + 3515625; + 3593750; + 3671875; + 3750000; + 3828125; + 3906250; + 3984375; + 4062500; + 4140625; + 4218750; + 4296875; + 4375000; + 4453125; + 4531250; + 4609375; + 4687500; + 4765625; + 4843750; + 4921875; + 5000000; + 5078125; + 5156250; + 5234375; + 5312500; + 5390625; + 5468750; + 5546875; + 5625000; + 5703125; + 5781250; + 5859375; + 5937500; + 6015625; + 6093750; + 6171875; + 6250000; + 6328125; + 6406250; + 6484375; + 6562500; + 6640625; + 6718750; + 6796875; + 6875000; + 6953125; + 7031250; + 7109375; + 7187500; + 7265625; + 7343750; + 7421875; + 7500000; + 7578125; + 7656250; + 7734375; + 7812500; + 7890625; + 7968750; + 8046875; + 8125000; + 8203125; + 8281250; + 8359375; + 8437500; + 8515625; + 8593750; + 8671875; + 8750000; + 8828125; + 8906250; + 8984375; + 9062500; + 9140625; + 9218750; + 9296875; + 9375000; + 9453125; + 9531250; + 9609375; + 9687500; + 9765625; + 9843750; + 9921875; + 10000000; + 10078125; + 10156250; + 10234375; + 10312500; + 10390625; + 10468750; + 10546875; + 10625000; + 10703125; + 10781250; + 10859375; + 10937500; + 11015625; + 11093750; + 11171875; + 11250000; + 11328125; + 11406250; + 11484375; + 11562500; + 11640625; + 11718750; + 11796875; + 11875000; + 11953125; + 12031250; + 12109375; + 12187500; + 12265625; + 12343750; + 12421875; + 12500000; + 12578125; + 12656250; + 12734375; + 12812500; + 12890625; + 12968750; + 13046875; + 13125000; + 13203125; + 13281250; + 13359375; + 13437500; + 13515625; + 13593750; + 13671875; + 13750000; + 13828125; + 13906250; + 13984375; + 14062500; + 14140625; + 14218750; + 14296875; + 14375000; + 14453125; + 14531250; + 14609375; + 14687500; + 14765625; + 14843750; + 14921875; + 15000000; + 15078125; + 15156250; + 15234375; + 15312500; + 15390625; + 15468750; + 15546875; + 15625000; + 15703125; + 15781250; + 15859375; + 15937500; + 16015625; + 16093750; + 16171875; + 16250000; + 16328125; + 16406250; + 16484375; + 16562500; + 16640625; + 16718750; + 16796875; + 16875000; + 16953125; + 17031250; + 17109375; + 17187500; + 17265625; + 17343750; + 17421875; + 17500000; + 17578125; + 17656250; + 17734375; + 17812500; + 17890625; + 17968750; + 18046875; + 18125000; + 18203125; + 18281250; + 18359375; + 18437500; + 18515625; + 18593750; + 18671875; + 18750000; + 18828125; + 18906250; + 18984375; + 19062500; + 19140625; + 19218750; + 19296875; + 19375000; + 19453125; + 19531250; + 19609375; + 19687500; + 19765625; + 19843750; + 19921875; + 20000000; + |]; + [| + 0; + 52083; + 104166; + 156249; + 208332; + 260415; + 312498; + 364581; + 416664; + 468747; + 520830; + 572913; + 624996; + 677079; + 729162; + 781245; + 833328; + 885411; + 937494; + 989577; + 1041660; + 1093743; + 1145826; + 1197909; + 1249992; + 1302075; + 1354158; + 1406241; + 1458324; + 1510407; + 1562490; + 1614573; + 1666656; + 1718739; + 1770822; + 1822905; + 1874988; + 1927071; + 1979154; + 2031237; + 2083320; + 2135403; + 2187486; + 2239569; + 2291652; + 2343735; + 2395818; + 2447901; + 2499984; + 2552067; + 2604150; + 2656233; + 2708316; + 2760399; + 2812482; + 2864565; + 2916648; + 2968731; + 3020814; + 3072897; + 3124980; + 3177063; + 3229146; + 3281229; + 3333312; + 3385395; + 3437478; + 3489561; + 3541644; + 3593727; + 3645810; + 3697893; + 3749976; + 3802059; + 3854142; + 3906225; + 3958308; + 4010391; + 4062474; + 4114557; + 4166640; + 4218723; + 4270806; + 4322889; + 4374972; + 4427055; + 4479138; + 4531221; + 4583304; + 4635387; + 4687470; + 4739553; + 4791636; + 4843719; + 4895802; + 4947885; + 4999968; + 5052051; + 5104134; + 5156217; + 5208300; + 5260383; + 5312466; + 5364549; + 5416632; + 5468715; + 5520798; + 5572881; + 5624964; + 5677047; + 5729130; + 5781213; + 5833296; + 5885379; + 5937462; + 5989545; + 6041628; + 6093711; + 6145794; + 6197877; + 6249960; + 6302043; + 6354126; + 6406209; + 6458292; + 6510375; + 6562458; + 6614541; + 6666624; + 6718707; + 6770790; + 6822873; + 6874956; + 6927039; + 6979122; + 7031205; + 7083288; + 7135371; + 7187454; + 7239537; + 7291620; + 7343703; + 7395786; + 7447869; + 7499952; + 7552035; + 7604118; + 7656201; + 7708284; + 7760367; + 7812450; + 7864533; + 7916616; + 7968699; + 8020782; + 8072865; + 8124948; + 8177031; + 8229114; + 8281197; + 8333280; + 8385363; + 8437446; + 8489529; + 8541612; + 8593695; + 8645778; + 8697861; + 8749944; + 8802027; + 8854110; + 8906193; + 8958276; + 9010359; + 9062442; + 9114525; + 9166608; + 9218691; + 9270774; + 9322857; + 9374940; + 9427023; + 9479106; + 9531189; + 9583272; + 9635355; + 9687438; + 9739521; + 9791604; + 9843687; + 9895770; + 9947853; + 9999936; + 10052019; + 10104102; + 10156185; + 10208268; + 10260351; + 10312434; + 10364517; + 10416600; + 10468683; + 10520766; + 10572849; + 10624932; + 10677015; + 10729098; + 10781181; + 10833264; + 10885347; + 10937430; + 10989513; + 11041596; + 11093679; + 11145762; + 11197845; + 11249928; + 11302011; + 11354094; + 11406177; + 11458260; + 11510343; + 11562426; + 11614509; + 11666592; + 11718675; + 11770758; + 11822841; + 11874924; + 11927007; + 11979090; + 12031173; + 12083256; + 12135339; + 12187422; + 12239505; + 12291588; + 12343671; + 12395754; + 12447837; + 12499920; + 12552003; + 12604086; + 12656169; + 12708252; + 12760335; + 12812418; + 12864501; + 12916584; + 12968667; + 13020750; + 13072833; + 13124916; + 13176999; + 13229082; + 13281165; + 13333248; + |]; + [| + 0; + 52083; + 104166; + 156249; + 208332; + 260415; + 312498; + 364581; + 416664; + 468747; + 520830; + 572913; + 624996; + 677079; + 729162; + 781245; + 833328; + 885411; + 937494; + 989577; + 1041660; + 1093743; + 1145826; + 1197909; + 1249992; + 1302075; + 1354158; + 1406241; + 1458324; + 1510407; + 1562490; + 1614573; + 1666656; + 1718739; + 1770822; + 1822905; + 1874988; + 1927071; + 1979154; + 2031237; + 2083320; + 2135403; + 2187486; + 2239569; + 2291652; + 2343735; + 2395818; + 2447901; + 2499984; + 2552067; + 2604150; + 2656233; + 2708316; + 2760399; + 2812482; + 2864565; + 2916648; + 2968731; + 3020814; + 3072897; + 3124980; + 3177063; + 3229146; + 3281229; + 3333312; + 3385395; + 3437478; + 3489561; + 3541644; + 3593727; + 3645810; + 3697893; + 3749976; + 3802059; + 3854142; + 3906225; + 3958308; + 4010391; + 4062474; + 4114557; + 4166640; + 4218723; + 4270806; + 4322889; + 4374972; + 4427055; + 4479138; + 4531221; + 4583304; + 4635387; + 4687470; + 4739553; + 4791636; + 4843719; + 4895802; + 4947885; + 4999968; + 5052051; + 5104134; + 5156217; + 5208300; + 5260383; + 5312466; + 5364549; + 5416632; + 5468715; + 5520798; + 5572881; + 5624964; + 5677047; + 5729130; + 5781213; + 5833296; + 5885379; + 5937462; + 5989545; + 6041628; + 6093711; + 6145794; + 6197877; + 6249960; + 6302043; + 6354126; + 6406209; + 6458292; + 6510375; + 6562458; + 6614541; + 6666624; + 6718707; + 6770790; + 6822873; + 6874956; + 6927039; + 6979122; + 7031205; + 7083288; + 7135371; + 7187454; + 7239537; + 7291620; + 7343703; + 7395786; + 7447869; + 7499952; + 7552035; + 7604118; + 7656201; + 7708284; + 7760367; + 7812450; + 7864533; + 7916616; + 7968699; + 8020782; + 8072865; + 8124948; + 8177031; + 8229114; + 8281197; + 8333280; + 8385363; + 8437446; + 8489529; + 8541612; + 8593695; + 8645778; + 8697861; + 8749944; + 8802027; + 8854110; + 8906193; + 8958276; + 9010359; + 9062442; + 9114525; + 9166608; + 9218691; + 9270774; + 9322857; + 9374940; + 9427023; + 9479106; + 9531189; + 9583272; + 9635355; + 9687438; + 9739521; + 9791604; + 9843687; + 9895770; + 9947853; + 9999936; + 10052019; + 10104102; + 10156185; + 10208268; + 10260351; + 10312434; + 10364517; + 10416600; + 10468683; + 10520766; + 10572849; + 10624932; + 10677015; + 10729098; + 10781181; + 10833264; + 10885347; + 10937430; + 10989513; + 11041596; + 11093679; + 11145762; + 11197845; + 11249928; + 11302011; + 11354094; + 11406177; + 11458260; + 11510343; + 11562426; + 11614509; + 11666592; + 11718675; + 11770758; + 11822841; + 11874924; + 11927007; + 11979090; + 12031173; + 12083256; + 12135339; + 12187422; + 12239505; + 12291588; + 12343671; + 12395754; + 12447837; + 12499920; + 12552003; + 12604086; + 12656169; + 12708252; + 12760335; + 12812418; + 12864501; + 12916584; + 12968667; + 13020750; + 13072833; + 13124916; + 13176999; + 13229082; + 13281165; + 13333248; + |]; + |] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/sapling_helpers.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/sapling_helpers.ml new file mode 100644 index 000000000000..a5698ff56ac2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/sapling_helpers.ml @@ -0,0 +1,397 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +module Common = struct + let memo_size_of_int i = + match Alpha_context.Sapling.Memo_size.parse_z @@ Z.of_int i with + | Ok memo_size -> memo_size + | Error _ -> assert false + + let int_of_memo_size ms = + Alpha_context.Sapling.Memo_size.unparse_to_z ms |> Z.to_int + + let wrap e = Lwt.return (Environment.wrap_tzresult e) + + let assert_true res = res >|=? fun res -> assert res + + let assert_false res = res >|=? fun res -> assert (not res) + + let assert_some res = res >|=? function Some s -> s | None -> assert false + + let assert_none res = + res >>=? function Some _ -> assert false | None -> return_unit + + let assert_error res = + res >>= function Ok _ -> assert false | Error _ -> return_unit + + let print ?(prefix = "") e v = + Printf.printf + "%s: %s\n" + prefix + Data_encoding.(Json.to_string (Json.construct e v)) + + let to_hex x encoding = + Hex.show (Hex.of_bytes Data_encoding.Binary.(to_bytes_exn encoding x)) + + let randomized_byte ?pos v encoding = + let bytes = Data_encoding.Binary.(to_bytes_exn encoding v) in + let rec aux () = + let random_char = Random.int 256 |> char_of_int in + let pos = Option.value ~default:(Random.int (Bytes.length bytes)) pos in + if random_char = Bytes.get bytes pos then aux () + else Bytes.set bytes pos random_char + in + aux () ; + Data_encoding.Binary.(of_bytes_exn encoding bytes) + + type wallet = { + sk : Tezos_sapling.Core.Wallet.Spending_key.t; + vk : Tezos_sapling.Core.Wallet.Viewing_key.t; + } + + let wallet_gen () = + let sk = + Tezos_sapling.Core.Wallet.Spending_key.of_seed + (Tezos_crypto.Hacl.Rand.gen 32) + in + let vk = Tezos_sapling.Core.Wallet.Viewing_key.of_sk sk in + {sk; vk} + + let gen_addr n vk = + let rec aux n index res = + if Compare.Int.( <= ) n 0 then res + else + let (new_index, new_addr) = + Tezos_sapling.Core.Client.Viewing_key.new_address vk index + in + aux (n - 1) new_index (new_addr :: res) + in + aux n Tezos_sapling.Core.Client.Viewing_key.default_index [] + + let gen_nf () = + let {vk; _} = wallet_gen () in + let addr = + snd + @@ Tezos_sapling.Core.Wallet.Viewing_key.(new_address vk default_index) + in + let amount = 10L in + let rcm = Tezos_sapling.Core.Client.Rcm.random () in + let position = 10L in + Tezos_sapling.Core.Client.Nullifier.compute addr vk ~amount rcm ~position + + let gen_cm_cipher ~memo_size () = + let open Tezos_sapling.Core.Client in + let {vk; _} = wallet_gen () in + let addr = + snd + @@ Tezos_sapling.Core.Wallet.Viewing_key.(new_address vk default_index) + in + let amount = 10L in + let rcm = Tezos_sapling.Core.Client.Rcm.random () in + let cm = Commitment.compute addr ~amount rcm in + let cipher = + let payload_enc = + Data_encoding.Binary.to_bytes_exn + Data_encoding.bytes + (Hacl.Rand.gen (memo_size + 4 + 16 + 11 + 32 + 8)) + in + Data_encoding.Binary.of_bytes_exn + Ciphertext.encoding + (Bytes.concat + Bytes.empty + [ + Bytes.create (32 + 32); + payload_enc; + Bytes.create (24 + 64 + 16 + 24); + ]) + in + (cm, cipher) + + (* rebuilds from empty at each call *) + let client_state_of_diff ~memo_size (root, diff) = + let open Alpha_context.Sapling in + let cs = + Tezos_sapling.Storage.add + (Tezos_sapling.Storage.empty ~memo_size) + diff.commitments_and_ciphertexts + in + assert (Tezos_sapling.Storage.get_root cs = root) ; + List.fold_left + (fun s nf -> Tezos_sapling.Storage.add_nullifier s nf) + cs + diff.nullifiers +end + +module Alpha_context_helpers = struct + include Common + + let init () = + Context.init 1 >>=? fun (b, _) -> + Alpha_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + (* ~fitness:b.header.shell.fitness *) + >>= wrap + >|=? fun (ctxt, _, _) -> ctxt + + (* takes a state obtained from Sapling.empty_state or Sapling.state_from_id and + passed through Sapling.verify_update *) + let finalize ctx = + let open Alpha_context in + let open Sapling in + function + | {id = None; diff; memo_size} -> + Sapling.fresh ~temporary:false ctx >>= wrap >>=? fun (ctx, id) -> + let init = Lazy_storage.Alloc {memo_size} in + let lazy_storage_diff = Lazy_storage.Update {init; updates = diff} in + let diffs = [Lazy_storage.make Sapling_state id lazy_storage_diff] in + Lazy_storage.apply ctx diffs >>= wrap >|=? fun (ctx, _added_size) -> + (ctx, id) + | {id = Some id; diff; _} -> + let init = Lazy_storage.Existing in + let lazy_storage_diff = Lazy_storage.Update {init; updates = diff} in + let diffs = [Lazy_storage.make Sapling_state id lazy_storage_diff] in + Lazy_storage.apply ctx diffs >>= wrap >|=? fun (ctx, _added_size) -> + (ctx, id) + + (* disk only version *) + let verify_update ctx ?memo_size ?id vt = + let anti_replay = "anti-replay" in + (match id with + | None -> + (match memo_size with + | None -> ( + match vt.Environment.Sapling.UTXO.outputs with + | [] -> failwith "Can't infer memo_size from empty outputs" + | output :: _ -> + return + @@ Environment.Sapling.Ciphertext.get_memo_size + output.ciphertext) + | Some memo_size -> return memo_size) + >>=? fun memo_size -> + let memo_size = memo_size_of_int memo_size in + let vs = Alpha_context.Sapling.empty_state ~memo_size () in + return (vs, ctx) + | Some id -> + (* Storage.Sapling.Roots.get (Obj.magic ctx, id) 0l *) + (* >>= wrap *) + (* >>=? fun (_, root) -> *) + (* print ~prefix:"verify: " Environment.Sapling.Hash.encoding root ; *) + Alpha_context.Sapling.state_from_id ctx id >>= wrap) + >>=? fun (vs, ctx) -> + Alpha_context.Sapling.verify_update ctx vs vt anti_replay >>= wrap + >>=? fun (ctx, res) -> + match res with + | None -> return_none + | Some (_balance, vs) -> + finalize ctx vs >>=? fun (ctx, id) -> + let fake_fitness = + Alpha_context.( + let level = + match Raw_level.of_int32 0l with + | Error _ -> assert false + | Ok l -> l + in + Fitness.create_without_locked_round + ~level + ~predecessor_round:Round.zero + ~round:Round.zero + |> Fitness.to_raw) + in + let ectx = (Alpha_context.finalize ctx fake_fitness).context in + (* bump the level *) + Alpha_context.prepare + ectx + ~level: + Alpha_context.( + Raw_level.to_int32 Level.((succ ctx (current ctx)).level)) + ~predecessor_timestamp:(Time.Protocol.of_seconds Int64.zero) + ~timestamp:(Time.Protocol.of_seconds Int64.zero) + >>= wrap + >|=? fun (ctx, _, _) -> Some (ctx, id) + + let transfer_inputs_outputs w cs is = + (* Tezos_sapling.Storage.size cs *) + (* |> fun (a, b) -> *) + (* Printf.printf "%Ld %Ld" a b ; *) + let inputs = + List.map + (fun i -> + Tezos_sapling.Forge.Input.get cs (Int64.of_int i) w.vk + |> WithExceptions.Option.get ~loc:__LOC__ + |> snd) + is + in + let addr = + snd + @@ Tezos_sapling.Core.Wallet.Viewing_key.(new_address w.vk default_index) + in + let memo_size = Tezos_sapling.Storage.get_memo_size cs in + let o = + Tezos_sapling.Forge.make_output addr 1000000L (Bytes.create memo_size) + in + (inputs, [o]) + + let transfer w cs is = + let anti_replay = "anti-replay" in + let (ins, outs) = transfer_inputs_outputs w cs is in + (* change the wallet of this last line *) + Tezos_sapling.Forge.forge_transaction ins outs w.sk anti_replay cs + + let client_state_alpha ctx id = + Alpha_context.Sapling.get_diff ctx id () >>= wrap >>=? fun diff -> + Alpha_context.Sapling.state_from_id ctx id >>= wrap + >|=? fun ({memo_size; _}, _ctx) -> + let memo_size = int_of_memo_size memo_size in + client_state_of_diff ~memo_size diff +end + +(* + Interpreter level +*) + +module Interpreter_helpers = struct + include Common + include Contract_helpers + + (** Returns a block in which the contract is originated. + Also returns the associated anti-replay string and KT1 address. *) + let originate_contract file storage src b baker = + originate_contract file storage src b baker >|=? fun (dst, b) -> + let anti_replay = + Format.asprintf + "%a%a" + Alpha_context.Contract.pp + dst + Chain_id.pp + Chain_id.zero + in + (dst, b, anti_replay) + + let hex_shield ~memo_size wallet anti_replay = + let ps = Tezos_sapling.Storage.empty ~memo_size in + let addr = + snd + @@ Tezos_sapling.Core.Wallet.Viewing_key.( + new_address wallet.vk default_index) + in + let output = + Tezos_sapling.Forge.make_output addr 15L (Bytes.create memo_size) + in + let pt = + Tezos_sapling.Forge.forge_transaction [] [output] wallet.sk anti_replay ps + in + let hex_string = + "0x" + ^ Hex.show + (Hex.of_bytes + Data_encoding.Binary.( + to_bytes_exn + Tezos_sapling.Core.Client.UTXO.transaction_encoding + pt)) + in + hex_string + + (* Make a transaction and sync a local client state. [to_exclude] is the list + of addresses that cannot bake the block*) + let transac_and_sync ~memo_size block parameters amount src dst baker = + let amount_tez = + Test_tez.(Alpha_context.Tez.one_mutez *! Int64.of_int amount) + in + let fee = Test_tez.of_int 10 in + Op.transaction ~fee (B block) src dst amount_tez ~parameters + >>=? fun operation -> + Incremental.begin_construction ~policy:Block.(By_account baker) block + >>=? fun incr -> + Incremental.add_operation incr operation >>=? fun incr -> + Incremental.finalize_block incr >>=? fun block -> + Alpha_services.Contract.single_sapling_get_diff + Block.rpc_ctxt + block + dst + ~offset_commitment:0L + ~offset_nullifier:0L + () + >|=? fun diff -> + let state = client_state_of_diff ~memo_size diff in + (block, state) + + (* Returns a list of printed shield transactions and their total amount. *) + let shield ~memo_size sk number_transac vk printer anti_replay = + let state = Tezos_sapling.Storage.empty ~memo_size in + let rec aux number_transac number_outputs index amount_output total res = + if Compare.Int.(number_transac <= 0) then (res, total) + else + let (new_index, new_addr) = + Tezos_sapling.Core.Wallet.Viewing_key.(new_address vk index) + in + let outputs = + List.init ~when_negative_length:() number_outputs (fun _ -> + Tezos_sapling.Forge.make_output + new_addr + amount_output + (Bytes.create memo_size)) + |> function + | Error () -> assert false (* conditional above guards against this *) + | Ok outputs -> outputs + in + let tr_hex = + to_hex + (Tezos_sapling.Forge.forge_transaction + ~number_dummy_inputs:0 + ~number_dummy_outputs:0 + [] + outputs + sk + anti_replay + state) + Tezos_sapling.Core.Client.UTXO.transaction_encoding + in + aux + (number_transac - 1) + (number_outputs + 1) + new_index + (Int64.add 20L amount_output) + (total + (number_outputs * Int64.to_int amount_output)) + (printer tr_hex :: res) + in + aux + number_transac + 2 + Tezos_sapling.Core.Wallet.Viewing_key.default_index + 20L + 0 + [] + + (* This fails if the operation is not correct wrt the block *) + let next_block block operation = + Incremental.begin_construction block >>=? fun incr -> + Incremental.add_operation incr operation >>=? fun incr -> + Incremental.finalize_block incr +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_big_map.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_big_map.ml new file mode 100644 index 000000000000..8573cafd1818 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_big_map.ml @@ -0,0 +1,30 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) + +let update k v m ctxt = Protocol.Script_ir_translator.big_map_update ctxt k v m + +let of_list key_ty ty xs ctxt = + List.fold_left_es + (fun (bm, ctxt) (k, v) -> update k (Some v) bm ctxt) + (Protocol.Script_ir_translator.empty_big_map key_ty ty, ctxt) + xs diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_big_map.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_big_map.mli new file mode 100644 index 000000000000..d3875195820a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_big_map.mli @@ -0,0 +1,44 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) + +(** Update a big map. See [Script_typed_ir.big_map_get_and_update] for details. *) +val update : + 'key -> + 'value option -> + ('key, 'value) Protocol.Script_typed_ir.big_map -> + Protocol.Alpha_context.t -> + (('key, 'value) Protocol.Script_typed_ir.big_map * Protocol.Alpha_context.t) + Protocol.Environment.Error_monad.tzresult + Lwt.t + +(** Convert a list to a [Script_big_map]. If the list contains duplicate keys, + the first occurence is used. + *) +val of_list : + 'key Protocol.Script_typed_ir.comparable_ty -> + 'value Protocol.Script_typed_ir.ty -> + ('key * 'value) list -> + Protocol.Alpha_context.t -> + (('key, 'value) Protocol.Script_typed_ir.big_map * Protocol.Alpha_context.t) + Protocol.Environment.Error_monad.tzresult + Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_list.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_list.ml new file mode 100644 index 000000000000..b224d784226b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_list.ml @@ -0,0 +1,29 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol.Script_typed_ir (* For record fields *) + +let of_list xs = {elements = xs; length = List.length xs} diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_list.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_list.mli new file mode 100644 index 000000000000..fecdbe0072c1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_list.mli @@ -0,0 +1,28 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Convert a standard list to a Script IR list. *) +val of_list : 'a list -> 'a Protocol.Script_typed_ir.boxed_list diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_map.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_map.ml new file mode 100644 index 000000000000..5b780f7ac8e2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_map.ml @@ -0,0 +1,36 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let of_list : + type k v. + k Protocol.Script_typed_ir.comparable_ty -> + (k * v) list -> + (k, v) Protocol.Script_typed_ir.map = + fun ty1 xs -> + List.fold_left + (fun rs (k, v) -> Protocol.Script_map.update k (Some v) rs) + (Protocol.Script_map.empty ty1) + xs diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_map.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_map.mli new file mode 100644 index 000000000000..e81cf5956c93 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_map.mli @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Trili Tech *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Convert a list to a [Script_map]. If the list contains duplicate keys, + the last occurence is used. *) +val of_list : + 'k Protocol.Script_typed_ir.comparable_ty -> + ('k * 'v) list -> + ('k, 'v) Protocol.Script_typed_ir.map diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_set.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_set.ml new file mode 100644 index 000000000000..b02d082465a4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_set.ml @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let of_list ty1 xs = + List.fold_left + (fun rs k -> Protocol.Script_set.update k true rs) + (Protocol.Script_set.empty ty1) + xs diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_set.mli b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_set.mli new file mode 100644 index 000000000000..7df70020e3b3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/script_set.mli @@ -0,0 +1,32 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Convert a list to a Script IR set. If the list contains duplicates, + the last occurence is used. *) +val of_list : + 'a Protocol.Script_typed_ir.comparable_ty -> + 'a list -> + 'a Protocol.Script_typed_ir.set diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/test_global_constants.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/test_global_constants.ml new file mode 100644 index 000000000000..1e98e513b7d3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/test_global_constants.ml @@ -0,0 +1,327 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Micheline +open Michelson_v1_primitives + +let create_context () = + let accounts = Account.generate_accounts 2 in + Block.alpha_context accounts + +let expr_to_hash expr = + let lexpr = Script_repr.lazy_expr expr in + Script_repr.force_bytes lexpr >|? fun b -> Script_expr_hash.hash_bytes [b] + +let assert_expr_equal loc = + Assert.equal + ~loc + ( = ) + "Michelson Expressions Not Equal" + Michelson_v1_printer.print_expr + +let assert_proto_error_id loc id result = + let test err = + (Error_monad.find_info_of_error err).id + = "proto." ^ Protocol.name ^ "." ^ id + in + Assert.error ~loc result test + +let assert_ok_lwt x = + match Lwt_main.run x with + | Ok x -> x + | Error _ -> raise @@ Failure "Called assert_ok_lwt on Error" + +let assert_ok = function + | Ok x -> x + | Error _ -> raise @@ Failure "Called assert_ok on Error" + +(** Filters out values that would cause [register] *) +let assume_expr_not_too_large expr = + let node = root expr in + QCheck.assume @@ not + @@ Global_constants_storage.Internal_for_tests.node_too_large node + +module Generators = struct + let context_arbitrary () = + QCheck.make @@ QCheck.Gen.return (create_context () |> assert_ok_lwt) + + let prims = + [ + K_parameter; + K_storage; + K_code; + D_False; + D_Elt; + D_Left; + D_None; + D_Pair; + D_Right; + D_Some; + D_True; + D_Unit; + I_PACK; + I_UNPACK; + I_BLAKE2B; + I_SHA256; + I_SHA512; + I_ABS; + I_ADD; + I_AMOUNT; + I_AND; + I_BALANCE; + I_CAR; + I_CDR; + I_CHAIN_ID; + I_CHECK_SIGNATURE; + I_COMPARE; + I_CONCAT; + I_CONS; + I_CREATE_ACCOUNT; + I_CREATE_CONTRACT; + I_IMPLICIT_ACCOUNT; + I_DIP; + I_DROP; + I_DUP; + I_EDIV; + I_EMPTY_BIG_MAP; + I_EMPTY_MAP; + I_EMPTY_SET; + I_EQ; + I_EXEC; + I_APPLY; + I_FAILWITH; + I_GE; + I_GET; + I_GET_AND_UPDATE; + I_GT; + I_HASH_KEY; + I_IF; + I_IF_CONS; + I_IF_LEFT; + I_IF_NONE; + I_INT; + I_LAMBDA; + I_LE; + I_LEFT; + I_LEVEL; + I_LOOP; + I_LSL; + I_LSR; + I_LT; + I_MAP; + I_MEM; + I_MUL; + I_NEG; + I_NEQ; + I_NIL; + I_NONE; + I_NOT; + I_NOW; + I_OR; + I_PAIR; + I_UNPAIR; + I_PUSH; + I_RIGHT; + I_SIZE; + I_SOME; + I_SOURCE; + I_SENDER; + I_SELF; + I_SELF_ADDRESS; + I_SLICE; + I_STEPS_TO_QUOTA; + I_SUB; + I_SWAP; + I_TRANSFER_TOKENS; + I_SET_DELEGATE; + I_UNIT; + I_UPDATE; + I_XOR; + I_ITER; + I_LOOP_LEFT; + I_ADDRESS; + I_CONTRACT; + I_ISNAT; + I_CAST; + I_RENAME; + I_SAPLING_EMPTY_STATE; + I_SAPLING_VERIFY_UPDATE; + I_DIG; + I_DUG; + I_NEVER; + I_VOTING_POWER; + I_TOTAL_VOTING_POWER; + I_KECCAK; + I_SHA3; + I_PAIRING_CHECK; + I_TICKET; + I_READ_TICKET; + I_SPLIT_TICKET; + I_JOIN_TICKETS; + T_bool; + T_contract; + T_int; + T_key; + T_key_hash; + T_lambda; + T_list; + T_map; + T_big_map; + T_nat; + T_option; + T_or; + T_pair; + T_set; + T_signature; + T_string; + T_bytes; + T_mutez; + T_timestamp; + T_unit; + T_operation; + T_address; + T_sapling_transaction; + T_sapling_state; + T_chain_id; + T_never; + T_bls12_381_g1; + T_bls12_381_g2; + T_bls12_381_fr; + T_ticket; + H_constant; + ] + + let prim_gen = QCheck.Gen.oneofl prims + + let prims_without_constants_gen = + QCheck.Gen.oneofl (List.filter (fun x -> x != H_constant) prims) + + let z_gen = QCheck.Gen.map Z.of_int QCheck.Gen.int + + let micheline_node_gen l_gen p_gen annot_gen : + ('l, 'p) Micheline.node QCheck.Gen.t = + let open Micheline in + let open QCheck.Gen in + fix + (fun self () -> + frequency + [ + (3, map (fun (l, x) -> Int (l, x)) (pair l_gen z_gen)); + (3, map (fun (l, x) -> String (l, x)) (pair l_gen string)); + ( 3, + map + (fun (l, x) -> Bytes (l, Bytes.of_string x)) + (pair l_gen string) ); + ( 1, + map + (fun (l, p, args, annot) -> Prim (l, p, args, annot)) + (quad + l_gen + p_gen + (list_size (int_bound 10) (self ())) + annot_gen) ); + ( 1, + map + (fun (l, args) -> Seq (l, args)) + (pair l_gen (list_size (int_bound 10) (self ()))) ); + ]) + () + + let rec replace_with_constant : + Script.node -> Script.location -> Script.node * Script.node option = + fun node loc -> + let open Michelson_v1_primitives in + let open Micheline in + let rec loop : Script.node list -> Script.node list * Script.node option = + function + | [] -> ([], None) + | hd :: tl -> ( + match replace_with_constant hd loc with + | (node, Some x) -> (node :: tl, Some x) + | (_, None) -> + let (l, x) = loop tl in + (hd :: l, x)) + in + match node with + | (Int (l, _) | String (l, _) | Bytes (l, _)) as node -> + if l = loc then + let hash = + node |> strip_locations |> expr_to_hash |> assert_ok + |> Script_expr_hash.to_b58check + in + (Prim (-1, H_constant, [String (-1, hash)], []), Some node) + else (node, None) + | Prim (l, prim, args, annot) as node -> + if l = loc then + let hash = + node |> strip_locations |> expr_to_hash |> assert_ok + |> Script_expr_hash.to_b58check + in + (Prim (-1, H_constant, [String (-1, hash)], []), Some node) + else + let (result, x) = loop args in + (Prim (l, prim, result, annot), x) + | Seq (l, args) as node -> + if l = loc then + let hash = + node |> strip_locations |> expr_to_hash |> assert_ok + |> Script_expr_hash.to_b58check + in + (Prim (-1, H_constant, [String (-1, hash)], []), Some node) + else + let (result, x) = loop args in + (Seq (l, result), x) + + let micheline_gen p_gen annot_gen = + QCheck.Gen.map + Micheline.strip_locations + (micheline_node_gen (QCheck.Gen.return (-1)) p_gen annot_gen) + + let canonical_without_constant_gen () = + QCheck.Gen.map + strip_locations + (micheline_node_gen + (QCheck.Gen.return (-1)) + prims_without_constants_gen + (QCheck.Gen.return [])) + + let canonical_without_constant_arbitrary () = + QCheck.make (canonical_without_constant_gen ()) + + let canonical_with_constant_gen () = + let open QCheck.Gen in + canonical_without_constant_gen () >>= fun expr -> + let size = Script_repr.micheline_nodes (root expr) in + 0 -- (size - 1) >|= fun loc -> + match replace_with_constant (root expr) loc with + | (_, None) -> assert false + | (node, Some replaced_node) -> + (expr, strip_locations node, strip_locations replaced_node) + + let canonical_with_constant_arbitrary () = + QCheck.make (canonical_with_constant_gen ()) +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/test_tez.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/test_tez.ml new file mode 100644 index 000000000000..5809c11c2adf --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/test_tez.ml @@ -0,0 +1,70 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context +open Environment + +(* This module wraps the errors from the protocol *) +open Tez + +let ( +? ) t1 t2 = t1 +? t2 |> wrap_tzresult + +let ( -? ) t1 t2 = t1 -? t2 |> wrap_tzresult + +let ( *? ) t1 t2 = t1 *? t2 |> wrap_tzresult + +let ( /? ) t1 t2 = t1 /? t2 |> wrap_tzresult + +let ( +! ) t1 t2 = + match t1 +? t2 with Ok r -> r | Error _ -> Pervasives.failwith "adding tez" + +let ( -! ) t1 t2 = + match t1 -? t2 with + | Ok r -> r + | Error _ -> Pervasives.failwith "subtracting tez" + +let ( *! ) t1 t2 = + match t1 *? t2 with + | Ok r -> r + | Error _ -> Pervasives.failwith "multiplying tez" + +let ( /! ) t1 t2 = + match t1 /? t2 with + | Ok r -> r + | Error _ -> Pervasives.failwith "dividing tez" + +let of_int x = + match Tez.of_mutez (Int64.mul (Int64.of_int x) 1_000_000L) with + | None -> invalid_arg "tez_of_int" + | Some x -> x + +let of_mutez_exn x = + match Tez.of_mutez x with None -> invalid_arg "tez_of_mutez" | Some x -> x + +let to_mutez = Tez.to_mutez + +let max_tez = + match Tez.of_mutez Int64.max_int with None -> assert false | Some p -> p diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/testable.ml b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/testable.ml new file mode 100644 index 000000000000..287b46840b00 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/testable.ml @@ -0,0 +1,38 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let contract : Protocol.Alpha_context.Contract.t Alcotest.testable = + let open Protocol in + let open Alpha_context in + Alcotest.testable Contract.pp Contract.( = ) + +let script_expr : Protocol.Alpha_context.Script.expr Alcotest.testable = + Alcotest.testable Michelson_v1_printer.print_expr ( = ) + +let trace : tztrace Alcotest.testable = Alcotest.testable pp_print_trace ( = ) + +let protocol_error : Environment.Error_monad.error Alcotest.testable = + let open Environment.Error_monad in + Alcotest.testable pp ( = ) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/helpers/tezos-012-PsiThaCa-test-helpers.opam b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/tezos-012-PsiThaCa-test-helpers.opam new file mode 100644 index 000000000000..c2a64a103249 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/helpers/tezos-012-PsiThaCa-test-helpers.opam @@ -0,0 +1,25 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-base" + "tezos-stdlib-unix" + "tezos-shell-services" + "tezos-protocol-environment" + "tezos-protocol-012-PsiThaCa" + "tezos-protocol-012-PsiThaCa-parameters" + "tezos-client-012-PsiThaCa" + "tezos-test-helpers" + "alcotest-lwt" + "qcheck-alcotest" +] +build: [ + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: protocol testing framework" diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/liquidity_baking_pbt.ml b/src/proto_012_PsiThaCa/lib_protocol/test/liquidity_baking_pbt.ml new file mode 100644 index 000000000000..2778520e7519 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/liquidity_baking_pbt.ml @@ -0,0 +1,299 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: pbt for liquidity baking + Invocation: [QCHECK_SEED=] dune exec src/proto_alpha/lib_protocol/test/liquidity_baking_pbt.exe + Subject: Test liquidity baking contracts using randomly generated inputs. +*) + +open Protocol +open Alpha_context +open Liquidity_baking_machine + +(** We use the “machines” provided by the {! Liquidity_baking_machine} + module. Because using the [ConcreteMachine] (hence, the {! + ValidationMachine} too) is slow, we implement the following + test-suit architecture: + + - One {v QCheck v}-based test is used to validate consistency of + the {! SymbolicMachine} wrt. the [ConcreteMachine], thanks to + the {! ValidationMachine}. + - The rest of the tests use the {! SymbolicMachine} in order to be + more effective. *) + +(** [all_true l] waits for all promises of [l], and returns [true] iff + they all resolve to [true]. *) +let all_true = List.for_all_ep Fun.id + +let extract_qcheck_tzresult : unit tzresult Lwt.t -> bool = + fun p -> + match Lwt_main.run p with + | Ok () -> true + | Error err -> QCheck.Test.fail_reportf "@\n%a@." pp_print_trace err + +let rec run_and_check check scenarios env state = + match scenarios with + | step :: rst -> + let state' = SymbolicMachine.step step env state in + assert (check state state') ; + run_and_check check rst env state' + | [] -> state + +let one_balance_decreases c env state state' = + let xtz = SymbolicMachine.get_xtz_balance c state in + let tzbtc = SymbolicMachine.get_tzbtc_balance c env state in + let lqt = SymbolicMachine.get_liquidity_balance c env state in + let xtz' = SymbolicMachine.get_xtz_balance c state' in + let tzbtc' = SymbolicMachine.get_tzbtc_balance c env state' in + let lqt' = SymbolicMachine.get_liquidity_balance c env state' in + xtz' < xtz || tzbtc' < tzbtc || lqt' < lqt + || (xtz' = xtz && tzbtc' = tzbtc && lqt' = lqt) + +let get_float_balances env state = + let xtz = + Int64.to_float @@ SymbolicMachine.get_xtz_balance env.cpmm_contract state + in + let tzbtc = + Int.to_float + @@ SymbolicMachine.get_tzbtc_balance env.cpmm_contract env state + in + let lqt = + Int.to_float @@ SymbolicMachine.get_cpmm_total_liquidity env state + in + (xtz, tzbtc, lqt) + +(** [is_remove_liquidity_consistent env state state'] returns [true] + iff, when the liquidity pool decreased in [state'], then the + fraction of tzbtc and xtz returned to the liquidity provider is + lesser or equal than the fraction of lqt burnt. *) +let is_remove_liquidity_consistent env state state' = + let (xtz, tzbtc, lqt) = get_float_balances env state in + let (xtz', tzbtc', lqt') = get_float_balances env state' in + if lqt' < lqt then + let flqt = (lqt -. lqt') /. lqt in + let fxtz = (xtz -. xtz') /. xtz in + let ftzbtc = (tzbtc -. tzbtc') /. tzbtc in + fxtz <= flqt && ftzbtc <= flqt + else true + +(** [is_share_price_increasing env state state'] returns [true] iff + the product of supplies (tzbtc, and xtz) increases. + + See https://blog.nomadic-labs.com/progress-report-on-the-verification-of-liquidity-baking-smart-contracts.html#evolution-of-the-product-of-supplies *) +let is_share_price_increasing env state state' = + let (xtz, tzbtc, lqt) = get_float_balances env state in + let (xtz', tzbtc', lqt') = get_float_balances env state' in + xtz *. tzbtc /. (lqt *. lqt) <= xtz' *. tzbtc' /. (lqt' *. lqt') + +(** [positive_pools env state] returns [true] iff the three pools of + the CPMM (as identified in [env]) are strictly positive in + [state]. *) +let positive_pools env state = + let xtz = SymbolicMachine.get_xtz_balance env.cpmm_contract state in + let tzbtc = SymbolicMachine.get_tzbtc_balance env.cpmm_contract env state in + let lqt = SymbolicMachine.get_cpmm_total_liquidity env state in + 0L < xtz && 0 < tzbtc && 0 < lqt + +(** [validate_xtz_balance c env (blk, state)] returns [true] iff the + tez balance for the contract [c] is the same in [blk] and in + [state]. *) +let validate_xtz_balance : + Contract.t -> ValidationMachine.t -> bool tzresult Lwt.t = + fun contract state -> + ValidationMachine.Symbolic.get_xtz_balance contract state >>=? fun expected -> + ValidationMachine.Concrete.get_xtz_balance contract state >>=? fun amount -> + return (amount = expected) + +(** [validate_tzbtc_balance c env (blk, state)] returns [true] iff the + tzbtc balance for the contract [c] is the same in [blk] and in + [state]. *) +let validate_tzbtc_balance : + Contract.t -> Contract.t env -> ValidationMachine.t -> bool tzresult Lwt.t = + fun contract env state -> + ValidationMachine.Symbolic.get_tzbtc_balance contract env state + >>=? fun expected -> + ValidationMachine.Concrete.get_tzbtc_balance contract env state + >>=? fun amount -> return (expected = amount) + +(** [validate_liquidity_balance c env (blk, state)] returns [true] if + the contract [c] holds the same amount of liquidity in [blk] and + [state]. *) +let validate_liquidity_balance : + Contract.t -> Contract.t env -> ValidationMachine.t -> bool tzresult Lwt.t = + fun contract env state -> + ValidationMachine.Symbolic.get_liquidity_balance contract env state + >>=? fun expected -> + ValidationMachine.Concrete.get_liquidity_balance contract env state + >>=? fun amount -> return (expected = amount) + +(** [validate_balances c env (blk, state)] returns true iff the + contract [c] holds the same amount of tez, tzbtc and liquidity in + [blk] and [state]. *) +let validate_balances : + Contract.t -> Contract.t env -> ValidationMachine.t -> bool tzresult Lwt.t = + fun contract env combined_state -> + all_true + [ + validate_xtz_balance contract combined_state; + validate_tzbtc_balance contract env combined_state; + validate_liquidity_balance contract env combined_state; + ] + +(** [validate_cpmm_total_liquidity env state] returns true iff the + CPMM has distributed the same amount of liquidity tokens in its + concrete and symbolic parts of [state]. *) +let validate_cpmm_total_liquidity env state = + ValidationMachine.Concrete.get_cpmm_total_liquidity env state + >>=? fun concrete_cpmm_total_liquidity -> + ValidationMachine.Symbolic.get_cpmm_total_liquidity env state + >>=? fun ghost_cpmm_total_liquidity -> + return (concrete_cpmm_total_liquidity = ghost_cpmm_total_liquidity) + +(** [validate_consistency env (blk, state)] checks if the accounts in + [env] (the CPMM and the implicit accounts) share the same balances + in [blk] and [state]. *) +let validate_consistency : + Contract.t env -> ValidationMachine.t -> bool tzresult Lwt.t = + (* We do not try to validate the xtz balance of [holder] in this + function. Indeed, they are hard to predict due to allocation + fees, and security deposits. *) + fun env state -> + all_true + (validate_cpmm_total_liquidity env state + :: + validate_balances env.cpmm_contract env state + :: + List.map + (fun account -> validate_balances account env state) + env.implicit_accounts) + +(** [validate_storage env blk] returns [true] iff the storage of the + CPMM contract is consistent wrt. to its actual balances (tez, + tzbtc, and liquidity). *) +let validate_storage : + Contract.t env -> ConcreteMachine.t -> bool tzresult Lwt.t = + fun env blk -> + Cpmm_repr.Storage.get (B blk) ~contract:env.cpmm_contract + >>=? fun cpmm_storage -> + all_true + [ + (* 1. Check the CPMM's [xtzPool] is equal to the actual CPMM balance *) + ( ConcreteMachine.get_xtz_balance env.cpmm_contract blk + >>=? fun cpmm_xtz -> return (cpmm_xtz = Tez.to_mutez cpmm_storage.xtzPool) + ); + (* 2. Check the CPMM’s [lqtTotal] is correct wrt. liquidity contract *) + ( Lqt_fa12_repr.Storage.get (B blk) ~contract:env.liquidity_contract + >>=? fun liquidity_storage -> + return (cpmm_storage.lqtTotal = liquidity_storage.totalSupply) ); + (* 3. Check the CPMM’s [tokenPool] is correct *) + ( ConcreteMachine.get_tzbtc_balance env.cpmm_contract env blk + >>=? fun cpmm_tzbtc -> + return (Z.to_int cpmm_storage.tokenPool = cpmm_tzbtc) ); + ] + +(** [machine_validation_tests] is a list of asynchronous tests aiming + at asserting the correctness and consistencies of the machines + themselves. *) +let machine_validation_tests = + [ + QCheck.Test.make + ~count:10 + ~name:"Concrete/Symbolic Consistency" + (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 10) + (fun (specs, scenario) -> + extract_qcheck_tzresult + (let invariant = validate_consistency in + ValidationMachine.build ~invariant specs >>=? fun (state, env) -> + ValidationMachine.run ~invariant scenario env state >>=? fun _ -> + return_unit)); + QCheck.Test.make + ~count:10 + ~name:"Storage consistency" + (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 10) + (fun (specs, scenario) -> + extract_qcheck_tzresult + (let invariant = validate_storage in + ConcreteMachine.build ~invariant specs >>=? fun (state, env) -> + ConcreteMachine.run ~invariant scenario env state >>=? fun _ -> + return_unit)); + QCheck.Test.make + ~count:100_000 + ~name:"Positive pools" + (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 50) + (fun (specs, scenario) -> + extract_qcheck_tzresult + (let invariant = positive_pools in + let (state, env) = SymbolicMachine.build ~invariant specs in + let _ = SymbolicMachine.run ~invariant scenario env state in + return_unit)); + ] + +(** [economic_tests] is a list of asynchronous tests aiming at + asserting the good economic properties of the Liquidity Baking + feature. *) +let economic_tests = + [ + QCheck.Test.make + ~count:100_000 + ~name:"No global gain" + (Liquidity_baking_generator.arb_adversary_scenario 1_000_000 1_000_000 50) + (fun (specs, attacker, scenario) -> + let (state, env) = SymbolicMachine.build ~subsidy:0L specs in + let _ = + run_and_check (one_balance_decreases attacker env) scenario env state + in + true); + QCheck.Test.make + ~count:100_000 + ~name:"Remove liquidities is consistent" + (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 50) + (fun (specs, scenario) -> + let (state, env) = SymbolicMachine.build ~subsidy:0L specs in + let _ = + run_and_check (is_remove_liquidity_consistent env) scenario env state + in + true); + QCheck.Test.make + ~count:100_000 + ~name:"Share price only increases" + (Liquidity_baking_generator.arb_scenario 1_000_000 1_000_000 50) + (fun (specs, scenario) -> + let (state, env) = SymbolicMachine.build ~subsidy:0L specs in + let _ = + run_and_check (is_share_price_increasing env) scenario env state + in + true); + ] + +let _ = + let open Lib_test.Qcheck_helpers in + Alcotest.run + "Liquidity baking PBT" + [ + ("Machines Cross-Validation", qcheck_wrap machine_validation_tests); + ("Economic Properties", qcheck_wrap economic_tests); + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/main.ml b/src/proto_012_PsiThaCa/lib_protocol/test/main.ml new file mode 100644 index 000000000000..3d6601be939b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/main.ml @@ -0,0 +1,82 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol + Invocation: dune build @src/proto_alpha/lib_protocol/runtest + Subject: Entrypoint +*) + +let () = + Alcotest_lwt.run + "protocol_012_PsiThaCa" + [ + ("transfer", Test_transfer.tests); + ("origination", Test_origination.tests); + ("activation", Test_activation.tests); + ("revelation", Test_reveal.tests); + ("endorsement", Test_endorsement.tests); + ("preendorsement", Test_preendorsement.tests); + ("double endorsement", Test_double_endorsement.tests); + ("double preendorsement", Test_double_preendorsement.tests); + ("double baking", Test_double_baking.tests); + ("seed", Test_seed.tests); + ("baking", Test_baking.tests); + ("delegation", Test_delegation.tests); + ("deactivation", Test_deactivation.tests); + ("combined", Test_combined_operations.tests); + ("qty", Test_qty.tests); + ("voting", Test_voting.tests); + ("interpretation", Test_interpretation.tests); + ("typechecking", Test_typechecking.tests); + ("fixed point computation", Test_fixed_point.tests); + ("gas levels", Test_gas_levels.tests); + ("saturation arithmetic", Test_saturation.tests); + ("gas cost functions", Test_gas_costs.tests); + ("lazy storage diff", Test_lazy_storage_diff.tests); + ("global table of constants", Test_global_constants_storage.tests); + ("sapling", Test_sapling.tests); + ("helpers rpcs", Test_helpers_rpcs.tests); + ("failing_noop operation", Test_failing_noop.tests); + ("storage description", Test_storage.tests); + ("time", Test_time_repr.tests); + ("constants", Test_constants.tests); + ("level module", Test_level_module.tests); + ("liquidity baking", Test_liquidity_baking.tests); + ("temp big maps", Test_temp_big_maps.tests); + ("timelock", Test_timelock.tests); + ("script typed ir size", Test_script_typed_ir_size.tests); + ("ticket storage", Test_ticket_storage.tests); + ("ticket scanner", Test_ticket_scanner.tests); + ("ticket balance key", Test_ticket_balance_key.tests); + ("fitness", Test_fitness.tests); + ("round", Test_round_repr.tests); + ("participation monitoring", Test_participation.tests); + ("frozen deposits", Test_frozen_deposits.tests); + ("token movements", Test_token.tests); + ("receipt encodings", Test_receipt.tests); + ] + |> Lwt_main.run diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/saturation_fuzzing.ml b/src/proto_012_PsiThaCa/lib_protocol/test/saturation_fuzzing.ml new file mode 100644 index 000000000000..bc3a97638f99 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/saturation_fuzzing.ml @@ -0,0 +1,183 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol Library + Invocation: dune exec src/proto_alpha/lib_protocol/test/saturation_fuzzing.exe + Subject: Operations in Saturation_repr +*) + +open Protocol.Saturation_repr +open Lib_test.Qcheck_helpers + +(** A generator that returns a [t] that cannot be [saturated] *) +let unsatured_arb = of_option_arb @@ QCheck.map of_int_opt QCheck.int + +(** The general generator for [t]: generates both unsaturated values + and [saturated]. *) +let t_arb : may_saturate t QCheck.arbitrary = + QCheck.frequency [(1, QCheck.always saturated); (4, unsatured_arb)] + +(* Test. + * Tests that [add] commutes. + *) +let test_add_commutes = + QCheck.Test.make + ~name:"t1 + t2 = t2 + t1" + (QCheck.pair t_arb t_arb) + (fun (t1, t2) -> + let t1_plus_t2 = add t1 t2 in + let t2_plus_t1 = add t2 t1 in + qcheck_eq ~pp t1_plus_t2 t2_plus_t1) + +(* Test. + * Tests that [mul] commutes. + *) +let test_mul_commutes = + QCheck.Test.make + ~name:"t1 * t2 = t2 * t1" + (QCheck.pair t_arb t_arb) + (fun (t1, t2) -> + let t1_times_t2 = mul t1 t2 in + let t2_times_t1 = mul t2 t1 in + qcheck_eq ~pp t1_times_t2 t2_times_t1) + +(* Test. + * Tests that [zero] is neutral for [add]. + *) +let test_add_zero = + QCheck.Test.make ~name:"t + 0 = t" t_arb (fun t -> + let t_plus_zero = add t zero in + qcheck_eq' ~pp ~expected:t ~actual:t_plus_zero ()) + +(* Test. + * Tests that t1 + t2 >= t1 + *) +let test_add_neq = + QCheck.Test.make + ~name:"t1 + t2 >= t1" + (QCheck.pair t_arb t_arb) + (fun (t1, t2) -> + let t1_plus_t2 = add t1 t2 in + t1_plus_t2 >= t1) + +(* Test. + * Tests that 1 is neutral for [mul]. + *) +let test_mul_one = + let one = safe_int 1 in + QCheck.Test.make ~name:"t * 1 = t" t_arb (fun t -> + let t_times_one = mul t one in + qcheck_eq' ~pp ~expected:t ~actual:t_times_one ()) + +(* Test. + * Tests that [t] times [0] equals [0]. + *) +let test_mul_zero = + QCheck.Test.make ~name:"t * 0 = 0" t_arb (fun t -> + let t_times_zero = mul t zero in + qcheck_eq' ~pp ~expected:zero ~actual:t_times_zero ()) + +(* Test. + * Tests that [t] [sub] [zero] equals [t]. + *) +let test_sub_zero = + QCheck.Test.make ~name:"t - 0 = t" t_arb (fun t -> + let t_sub_zero = sub t zero in + qcheck_eq' ~pp ~expected:t ~actual:t_sub_zero ()) + +(* Test. + * Tests that [t] [sub] [t] equals [zero]. + *) +let test_sub_itself = + QCheck.Test.make ~name:"t - t = 0" t_arb (fun t -> + let t_sub_t = sub t t in + qcheck_eq' ~pp ~expected:zero ~actual:t_sub_t ()) + +(* Test. + * Tests that t1 - t2 <= t1 + *) +let test_sub_neq = + QCheck.Test.make + ~name:"t1 - t2 <= t1" + (QCheck.pair t_arb t_arb) + (fun (t1, t2) -> + let t1_minus_t2 = sub t1 t2 in + t1_minus_t2 <= t1) + +(* Test. + * Tests that (t1 + t2) - t2 <= t1 + *) +let test_add_sub = + QCheck.Test.make + ~name:"(t1 + t2) - t2 <= t1" + (QCheck.pair t_arb t_arb) + (fun (t1, t2) -> + let lhs = sub (add t1 t2) t2 in + lhs <= t1) + +(* Test. + * Tests that (t1 - t2) + t2 >= t1 + *) +let test_sub_add = + QCheck.Test.make + ~name:"(t1 - t2) + t2 >= t1" + (QCheck.pair t_arb t_arb) + (fun (t1, t2) -> + let lhs = add (sub t1 t2) t2 in + lhs >= t1) + +(* Test. + * Tests that [saturated] >= t + *) +let test_leq_saturated = + QCheck.Test.make ~name:"t <= saturated" t_arb (fun t -> saturated >= t) + +(* Test. + * Tests that [zero] <= t + *) +let test_geq_zero = QCheck.Test.make ~name:"t >= 0" t_arb (fun t -> zero <= t) + +let tests_add = [test_add_commutes; test_add_zero; test_add_neq] + +let tests_mul = [test_mul_commutes; test_mul_one; test_mul_zero] + +let tests_sub = [test_sub_zero; test_sub_itself; test_sub_neq] + +let tests_add_sub = [test_add_sub; test_sub_add] + +let tests_boundaries = [test_leq_saturated; test_geq_zero] + +let () = + Alcotest.run + "Saturation" + [ + ("add", qcheck_wrap tests_add); + ("mul", qcheck_wrap tests_mul); + ("sub", qcheck_wrap tests_sub); + ("add and sub", qcheck_wrap tests_add_sub); + ("<= and >=", qcheck_wrap tests_boundaries); + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_activation.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_activation.ml new file mode 100644 index 000000000000..8dbcfde004c4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_activation.ml @@ -0,0 +1,587 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (activation) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^activation$" + Subject: The activation operation creates an implicit contract from a + registered commitment present in the context. It is + parametrized by a public key hash (pkh) and a secret. + + The commitments are composed of : + - a blinded pkh that can be revealed by the secret ; + - an amount. + + The commitments and the secrets are generated from + /scripts/create_genesis/create_genesis.py and should be + coherent. +*) + +open Protocol +open Alpha_context +open Test_tez + +(* Generated commitments and secrets *) + +let commitments = + List.map + (fun (bpkh, a) -> + Commitment. + { + blinded_public_key_hash = Blinded_public_key_hash.of_b58check_exn bpkh; + amount = Tez.of_mutez_exn (Int64.of_string a); + }) + [ + ("btz1bRL4X5BWo2Fj4EsBdUwexXqgTf75uf1qa", "23932454669343"); + ("btz1SxjV1syBgftgKy721czKi3arVkVwYUFSv", "72954577464032"); + ("btz1LtoNCjiW23txBTenALaf5H6NKF1L3c1gw", "217487035428349"); + ("btz1SUd3mMhEBcWudrn8u361MVAec4WYCcFoy", "4092742372031"); + ("btz1MvBXf4orko1tsGmzkjLbpYSgnwUjEe81r", "17590039016550"); + ("btz1LoDZ3zsjgG3k3cqTpUMc9bsXbchu9qMXT", "26322312350555"); + ("btz1RMfq456hFV5AeDiZcQuZhoMv2dMpb9hpP", "244951387881443"); + ("btz1Y9roTh4A7PsMBkp8AgdVFrqUDNaBE59y1", "80065050465525"); + ("btz1Q1N2ePwhVw5ED3aaRVek6EBzYs1GDkSVD", "3569618927693"); + ("btz1VFFVsVMYHd5WfaDTAt92BeQYGK8Ri4eLy", "9034781424478"); + ] + +type secret_account = { + account : public_key_hash; + activation_code : Blinded_public_key_hash.activation_code; + amount : Tez.t; +} + +let secrets () = + (* Exported from proto_alpha client - TODO : remove when relocated to lib_crypto *) + let read_key mnemonic email password = + match Tezos_client_base.Bip39.of_words mnemonic with + | None -> assert false + | Some t -> + (* TODO: unicode normalization (NFKD)... *) + let passphrase = Bytes.(cat (of_string email) (of_string password)) in + let sk = Tezos_client_base.Bip39.to_seed ~passphrase t in + let sk = Bytes.sub sk 0 32 in + let sk : Signature.Secret_key.t = + Ed25519 + (Data_encoding.Binary.of_bytes_exn Ed25519.Secret_key.encoding sk) + in + let pk = Signature.Secret_key.to_public_key sk in + let pkh = Signature.Public_key.hash pk in + (pkh, pk, sk) + in + List.map + (fun (mnemonic, secret, amount, pkh, password, email) -> + let (pkh', pk, sk) = read_key mnemonic email password in + let pkh = Signature.Public_key_hash.of_b58check_exn pkh in + assert (Signature.Public_key_hash.equal pkh pkh') ; + let account = Account.{pkh; pk; sk} in + Account.add_account account ; + { + account = account.pkh; + activation_code = + Stdlib.Option.get + (Blinded_public_key_hash.activation_code_of_hex secret); + amount = + WithExceptions.Option.to_exn + ~none:(Invalid_argument "tez conversion") + (Tez.of_mutez (Int64.of_string amount)); + }) + [ + ( [ + "envelope"; + "hospital"; + "mind"; + "sunset"; + "cancel"; + "muscle"; + "leisure"; + "thumb"; + "wine"; + "market"; + "exit"; + "lucky"; + "style"; + "picnic"; + "success"; + ], + "0f39ed0b656509c2ecec4771712d9cddefe2afac", + "23932454669343", + "tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF", + "z0eZHQQGKt", + "cjgfoqmk.wpxnvnup@tezos.example.org" ); + ( [ + "flag"; + "quote"; + "will"; + "valley"; + "mouse"; + "chat"; + "hold"; + "prosper"; + "silk"; + "tent"; + "cruel"; + "cause"; + "demise"; + "bottom"; + "practice"; + ], + "41f98b15efc63fa893d61d7d6eee4a2ce9427ac4", + "72954577464032", + "tz1X4maqF9tC1Yn4jULjHRAyzjAtc25Z68TX", + "MHErskWPE6", + "oklmcktr.ztljnpzc@tezos.example.org" ); + ( [ + "library"; + "away"; + "inside"; + "paper"; + "wise"; + "focus"; + "sweet"; + "expose"; + "require"; + "change"; + "stove"; + "planet"; + "zone"; + "reflect"; + "finger"; + ], + "411dfef031eeecc506de71c9df9f8e44297cf5ba", + "217487035428349", + "tz1SWBY7rWMutEuWS54Pt33MkzAS6eWkUuTc", + "0AO6BzQNfN", + "ctgnkvqm.kvtiybky@tezos.example.org" ); + ( [ + "cruel"; + "fluid"; + "damage"; + "demand"; + "mimic"; + "above"; + "village"; + "alpha"; + "vendor"; + "staff"; + "absent"; + "uniform"; + "fire"; + "asthma"; + "milk"; + ], + "08d7d355bc3391d12d140780b39717d9f46fcf87", + "4092742372031", + "tz1amUjiZaevaxQy5wKn4SSRvVoERCip3nZS", + "9kbZ7fR6im", + "bnyxxzqr.tdszcvqb@tezos.example.org" ); + ( [ + "opera"; + "divorce"; + "easy"; + "myself"; + "idea"; + "aim"; + "dash"; + "scout"; + "case"; + "resource"; + "vote"; + "humor"; + "ticket"; + "client"; + "edge"; + ], + "9b7cad042fba557618bdc4b62837c5f125b50e56", + "17590039016550", + "tz1Zaee3QBtD4ErY1SzqUvyYTrENrExu6yQM", + "suxT5H09yY", + "iilkhohu.otnyuvna@tezos.example.org" ); + ( [ + "token"; + "similar"; + "ginger"; + "tongue"; + "gun"; + "sort"; + "piano"; + "month"; + "hotel"; + "vote"; + "undo"; + "success"; + "hobby"; + "shell"; + "cart"; + ], + "124c0ca217f11ffc6c7b76a743d867c8932e5afd", + "26322312350555", + "tz1geDUUhfXK1EMj7VQdRjug1MoFe6gHWnCU", + "4odVdLykaa", + "kwhlglvr.slriitzy@tezos.example.org" ); + ( [ + "shield"; + "warrior"; + "gorilla"; + "birth"; + "steak"; + "neither"; + "feel"; + "only"; + "liberty"; + "float"; + "oven"; + "extend"; + "pulse"; + "suffer"; + "vapor"; + ], + "ac7a2125beea68caf5266a647f24dce9fea018a7", + "244951387881443", + "tz1h3nY7jcZciJgAwRhWcrEwqfVp7VQoffur", + "A6yeMqBFG8", + "lvrmlbyj.yczltcxn@tezos.example.org" ); + ( [ + "waste"; + "open"; + "scan"; + "tip"; + "subway"; + "dance"; + "rent"; + "copper"; + "garlic"; + "laundry"; + "defense"; + "clerk"; + "another"; + "staff"; + "liar"; + ], + "2b3e94be133a960fa0ef87f6c0922c19f9d87ca2", + "80065050465525", + "tz1VzL4Xrb3fL3ckvqCWy6bdGMzU2w9eoRqs", + "oVZqpq60sk", + "rfodmrha.zzdndvyk@tezos.example.org" ); + ( [ + "fiber"; + "next"; + "property"; + "cradle"; + "silk"; + "obey"; + "gossip"; + "push"; + "key"; + "second"; + "across"; + "minimum"; + "nice"; + "boil"; + "age"; + ], + "dac31640199f2babc157aadc0021cd71128ca9ea", + "3569618927693", + "tz1RUHg536oRKhPLFfttcB5gSWAhh4E9TWjX", + "FfytQTTVbu", + "owecikdy.gxnyttya@tezos.example.org" ); + ( [ + "print"; + "labor"; + "budget"; + "speak"; + "poem"; + "diet"; + "chunk"; + "eternal"; + "book"; + "saddle"; + "pioneer"; + "ankle"; + "happy"; + "only"; + "exclude"; + ], + "bb841227f250a066eb8429e56937ad504d7b34dd", + "9034781424478", + "tz1M1LFbgctcPWxstrao9aLr2ECW1fV4pH5u", + "zknAl3lrX2", + "ettilrvh.zsrqrbud@tezos.example.org" ); + ] + +(** Helper: Create a genesis block with predefined commitments, + accounts and balances. *) +let activation_init () = + Context.init ~consensus_threshold:0 ~commitments 1 >|=? fun (b, cs) -> + secrets () |> fun ss -> (b, cs, ss) + +(** Verify the genesis block created by [activation_init] can be + baked. *) +let test_simple_init_with_commitments () = + activation_init () >>=? fun (blk, _contracts, _secrets) -> + Block.bake blk >>=? fun _ -> return_unit + +(** A single activation *) +let test_single_activation () = + activation_init () >>=? fun (blk, _contracts, secrets) -> + let ({account; activation_code; amount = expected_amount; _} as _first_one) = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets + in + (* Contract does not exist *) + Assert.balance_is + ~loc:__LOC__ + (B blk) + (Contract.implicit_contract account) + Tez.zero + >>=? fun () -> + Op.activation (B blk) account activation_code >>=? fun operation -> + Block.bake ~operation blk >>=? fun blk -> + (* Contract does exist *) + Assert.balance_is + ~loc:__LOC__ + (B blk) + (Contract.implicit_contract account) + expected_amount + +(** 10 activations, one per bake. *) +let test_multi_activation_1 () = + activation_init () >>=? fun (blk, _contracts, secrets) -> + List.fold_left_es + (fun blk {account; activation_code; amount = expected_amount; _} -> + Op.activation (B blk) account activation_code >>=? fun operation -> + Block.bake ~operation blk >>=? fun blk -> + Assert.balance_is + ~loc:__LOC__ + (B blk) + (Contract.implicit_contract account) + expected_amount + >|=? fun () -> blk) + blk + secrets + >>=? fun _ -> return_unit + +(** All of the 10 activations occur in one bake. *) +let test_multi_activation_2 () = + activation_init () >>=? fun (blk, _contracts, secrets) -> + List.fold_left_es + (fun ops {account; activation_code; _} -> + Op.activation (B blk) account activation_code >|=? fun op -> op :: ops) + [] + secrets + >>=? fun ops -> + Block.bake ~operations:ops blk >>=? fun blk -> + List.iter_es + (fun {account; amount = expected_amount; _} -> + (* Contract does exist *) + Assert.balance_is + ~loc:__LOC__ + (B blk) + (Contract.implicit_contract account) + expected_amount) + secrets + +(** Transfer with activated account. *) +let test_activation_and_transfer () = + activation_init () >>=? fun (blk, contracts, secrets) -> + let ({account; activation_code; _} as _first_one) = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets + in + let bootstrap_contract = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts + in + let first_contract = Contract.implicit_contract account in + Op.activation (B blk) account activation_code >>=? fun operation -> + Block.bake ~operation blk >>=? fun blk -> + Context.Contract.balance (B blk) bootstrap_contract >>=? fun amount -> + Test_tez.( /? ) amount 2L >>?= fun half_amount -> + Context.Contract.balance (B blk) first_contract + >>=? fun activated_amount_before -> + Op.transaction (B blk) bootstrap_contract first_contract half_amount + >>=? fun operation -> + Block.bake ~operation blk >>=? fun blk -> + Assert.balance_was_credited + ~loc:__LOC__ + (B blk) + (Contract.implicit_contract account) + activated_amount_before + half_amount + +(** Transfer to an unactivated account and then activating it. *) +let test_transfer_to_unactivated_then_activate () = + activation_init () >>=? fun (blk, contracts, secrets) -> + let ({account; activation_code; amount} as _first_one) = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets + in + let bootstrap_contract = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts + in + let unactivated_commitment_contract = Contract.implicit_contract account in + Context.Contract.balance (B blk) bootstrap_contract >>=? fun b_amount -> + b_amount /? 2L >>?= fun b_half_amount -> + Incremental.begin_construction blk >>=? fun inc -> + Op.transaction + (I inc) + bootstrap_contract + unactivated_commitment_contract + b_half_amount + >>=? fun op -> + Incremental.add_operation inc op >>=? fun inc -> + Op.activation (I inc) account activation_code >>=? fun op' -> + Incremental.add_operation inc op' >>=? fun inc -> + Incremental.finalize_block inc >>=? fun blk2 -> + Assert.balance_was_credited + ~loc:__LOC__ + (B blk2) + (Contract.implicit_contract account) + amount + b_half_amount + +(****************************************************************) +(* The following test scenarios are supposed to raise errors. *) +(****************************************************************) + +(** Invalid pkh activation: expected to fail as the context does not + contain any commitment. *) +let test_invalid_activation_with_no_commitments () = + Context.init 1 >>=? fun (blk, _) -> + let secrets = secrets () in + let ({account; activation_code; _} as _first_one) = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets + in + Op.activation (B blk) account activation_code >>=? fun operation -> + Block.bake ~operation blk >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Invalid_activation _ -> true + | _ -> false) + +(** Wrong activation: wrong secret given in the operation. *) +let test_invalid_activation_wrong_secret () = + activation_init () >>=? fun (blk, _, secrets) -> + let ({account; _} as _first_one) = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth secrets 0 + in + let ({activation_code; _} as _second_one) = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth secrets 1 + in + Op.activation (B blk) account activation_code >>=? fun operation -> + Block.bake ~operation blk >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Invalid_activation _ -> true + | _ -> false) + +(** Invalid pkh activation : expected to fail as the context does not + contain an associated commitment. *) +let test_invalid_activation_inexistent_pkh () = + activation_init () >>=? fun (blk, _, secrets) -> + let ({activation_code; _} as _first_one) = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets + in + let inexistent_pkh = + Signature.Public_key_hash.of_b58check_exn + "tz1PeQHGKPWSpNoozvxgqLN9TFsj6rDqNV3o" + in + Op.activation (B blk) inexistent_pkh activation_code >>=? fun operation -> + Block.bake ~operation blk >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Invalid_activation _ -> true + | _ -> false) + +(** Invalid pkh activation : expected to fail as the commitment has + already been claimed. *) +let test_invalid_double_activation () = + activation_init () >>=? fun (blk, _, secrets) -> + let ({account; activation_code; _} as _first_one) = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets + in + Incremental.begin_construction blk >>=? fun inc -> + Op.activation (I inc) account activation_code >>=? fun op -> + Incremental.add_operation inc op >>=? fun inc -> + Op.activation (I inc) account activation_code >>=? fun op' -> + Incremental.add_operation inc op' >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Invalid_activation _ -> true + | _ -> false) + +(** Transfer from an unactivated commitment account. *) +let test_invalid_transfer_from_unactivated_account () = + activation_init () >>=? fun (blk, contracts, secrets) -> + let ({account; _} as _first_one) = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd secrets + in + let bootstrap_contract = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts + in + let unactivated_commitment_contract = Contract.implicit_contract account in + (* No activation *) + Op.transaction + (B blk) + unactivated_commitment_contract + bootstrap_contract + Tez.one + >>=? fun operation -> + Block.bake ~operation blk >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Contract_storage.Empty_implicit_contract pkh -> + if pkh = account then true else false + | _ -> false) + +let tests = + [ + Tztest.tztest + "init with commitments" + `Quick + test_simple_init_with_commitments; + Tztest.tztest "single activation" `Quick test_single_activation; + Tztest.tztest "multi-activation one-by-one" `Quick test_multi_activation_1; + Tztest.tztest + "multi-activation all at a time" + `Quick + test_multi_activation_2; + Tztest.tztest "activation and transfer" `Quick test_activation_and_transfer; + Tztest.tztest + "transfer to unactivated account then activate" + `Quick + test_transfer_to_unactivated_then_activate; + Tztest.tztest + "invalid activation with no commitments" + `Quick + test_invalid_activation_with_no_commitments; + Tztest.tztest + "invalid activation with commitments" + `Quick + test_invalid_activation_inexistent_pkh; + Tztest.tztest + "invalid double activation" + `Quick + test_invalid_double_activation; + Tztest.tztest + "wrong activation code" + `Quick + test_invalid_activation_wrong_secret; + Tztest.tztest + "invalid transfer from unactivated account" + `Quick + test_invalid_transfer_from_unactivated_account; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_baking.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_baking.ml new file mode 100644 index 000000000000..4242171ae8af --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_baking.ml @@ -0,0 +1,455 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (baking) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^baking$" + Subject: Rewards and bakers. Tests based on RPCs. +*) + +open Protocol +open Alpha_context + +(** Verify the level is correctly computed when the first cycle is + passed and after baking a certain fixed number of blocks (10 for + the moment). The result should be [blocks_per_cycle + 10] where + [blocks_per_cycle] comes from the constants of the selected + protocol. + + IMPROVEMENTS: + - Randomize the number of cycle. + - Randomize the number of accounts created at the beginning + - Randomize the blocks per cycle. + - Randomize the number of blocks baked after the n cycles baked + previously. *) +let test_cycle () = + Context.init ~consensus_threshold:0 5 >>=? fun (b, _) -> + Context.get_constants (B b) >>=? fun csts -> + let blocks_per_cycle = csts.parametric.blocks_per_cycle in + let pp fmt x = Format.fprintf fmt "%ld" x in + Block.bake b >>=? fun b -> + Block.bake_until_cycle_end b >>=? fun b -> + Context.get_level (B b) >>?= fun curr_level -> + Assert.equal + ~loc:__LOC__ + Int32.equal + "not the right level" + pp + (Alpha_context.Raw_level.to_int32 curr_level) + blocks_per_cycle + >>=? fun () -> + Context.get_level (B b) >>?= fun l -> + Block.bake_n 10 b >>=? fun b -> + Context.get_level (B b) >>?= fun curr_level -> + Assert.equal + ~loc:__LOC__ + Int32.equal + "not the right level" + pp + (Alpha_context.Raw_level.to_int32 curr_level) + (Int32.add (Alpha_context.Raw_level.to_int32 l) 10l) + +let wrap et = et >>= fun e -> Lwt.return (Environment.wrap_tzresult e) + +(** Test baking [n] cycles in a raw works smoothly. *) +let test_bake_n_cycles n () = + let open Block in + let policy = By_round 0 in + Context.init ~consensus_threshold:0 1 >>=? fun (block, _contracts) -> + Block.bake_until_n_cycle_end ~policy n block >>=? fun _block -> return () + +(** Check that, after one or two voting periods, the voting power of a baker is + updated according to the rewards it receives for baking the blocks in the + voting periods. Note we consider only one baker. *) +let test_voting_power_cache () = + let open Block in + let policy = By_round 0 in + Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _contracts) -> + Context.get_constants (B genesis) >>=? fun csts -> + let blocks_per_voting_period = csts.parametric.blocks_per_voting_period in + let blocks_per_voting_periods n = + Int64.of_int (n * Int32.to_int blocks_per_voting_period) + in + Context.get_baking_reward_fixed_portion (B genesis) >>=? fun baking_reward -> + let tokens_per_roll = csts.parametric.tokens_per_roll in + let rolls_from_tez amount = + Test_tez.(amount /! Tez.to_mutez tokens_per_roll) + |> Tez.to_mutez |> Int64.to_int + in + Context.get_bakers (B genesis) >>=? fun bakers -> + let baker = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bakers in + Context.Delegate.full_balance (B genesis) baker >>=? fun full_balance -> + let assert_voting_power n block = + Context.get_voting_power (B block) baker >>=? fun voting_power -> + Assert.equal_int ~loc:__LOC__ n (Int32.to_int voting_power) + in + (* the voting power is the number of rolls *) + let initial_voting_power_at_genesis = rolls_from_tez full_balance in + assert_voting_power initial_voting_power_at_genesis genesis >>=? fun () -> + let rewards_after_one_voting_period = + Test_tez.(baking_reward *! blocks_per_voting_periods 1) + in + let expected_delta_voting_power_after_one_voting_period = + rolls_from_tez rewards_after_one_voting_period + in + Block.bake_n ~policy (Int32.to_int blocks_per_voting_period) genesis + >>=? fun block -> + let expected_voting_power_after_one_voting_period = + initial_voting_power_at_genesis + + expected_delta_voting_power_after_one_voting_period + in + assert_voting_power expected_voting_power_after_one_voting_period block + >>=? fun () -> + let rewards_after_two_voting_periods = + Test_tez.(baking_reward *! blocks_per_voting_periods 2) + in + let expected_delta_voting_power_after_two_voting_periods = + rolls_from_tez rewards_after_two_voting_periods + in + Block.bake_n ~policy (Int32.to_int blocks_per_voting_period) block + >>=? fun block -> + let expected_voting_power_after_two_voting_periods = + initial_voting_power_at_genesis + + expected_delta_voting_power_after_two_voting_periods + in + assert_voting_power expected_voting_power_after_two_voting_periods block + +(** test that after baking, one gets the baking reward fixed portion. *) +let test_basic_baking_reward () = + Context.init ~consensus_threshold:0 1 >>=? fun (genesis, contracts) -> + Block.bake genesis >>=? fun b -> + let baker = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + Context.Contract.pkh baker >>=? fun baker_pkh -> + Context.Contract.balance (B b) baker >>=? fun bal -> + Context.Delegate.current_frozen_deposits (B b) baker_pkh + >>=? fun frozen_deposit -> + Context.get_baking_reward_fixed_portion (B b) >>=? fun br -> + let open Test_tez in + let expected_initial_balance = bal +! frozen_deposit -! br in + Assert.equal_tez + ~loc:__LOC__ + expected_initial_balance + Account.default_initial_balance + +let get_contract_for_pkh contracts pkh = + let rec find_contract = function + | [] -> assert false + | c :: t -> + Context.Contract.pkh c >>=? fun c_pkh -> + if Signature.Public_key_hash.equal c_pkh pkh then return c + else find_contract t + in + find_contract contracts + +let get_baker_different_from_baker ctxt baker = + Context.get_bakers + ~filter:(fun x -> not (Signature.Public_key_hash.equal x.delegate baker)) + ctxt + >>=? fun bakers -> + return (WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bakers) + +(** Test that + - the block producer gets the bonus for including the endorsements; + - the payload producer gets the baking reward. + + The test checks this in two scenarios, in the first one the payload producer + and the block producer are the same delegate, in the second one they are + different. The first scenario is checked by first baking block [b1] and then + block [b2] at round 0 containing a number of endorsements for [b1] and the + checking the balance of [b2]'s baker. For the second scenario another block + [b2'] is build on top of [b1] by a different baker, using the same payload as + [b2]. *) +let test_rewards_block_and_payload_producer () = + Context.init ~consensus_threshold:1 10 >>=? fun (genesis, contracts) -> + Context.get_baker (B genesis) ~round:0 >>=? fun baker_b1 -> + get_contract_for_pkh contracts baker_b1 >>=? fun baker_b1_contract -> + Block.bake ~policy:(By_round 0) genesis >>=? fun b1 -> + Context.get_endorsers (B b1) >>=? fun endorsers -> + List.map_es + (function + | {Plugin.RPC.Validators.delegate; slots; _} -> return (delegate, slots)) + endorsers + >>=? fun endorsers -> + (* We let just a part of the endorsers vote; we assume here that 5 of 10 + endorsers will have together at least one slot (to pass the threshold), but + not all slots (to make the test more interesting, otherwise we know the + total endorsing power). *) + let endorsers = List.take_n 5 endorsers in + List.map_ep + (fun endorser -> + Op.endorsement ~delegate:endorser ~endorsed_block:b1 (B genesis) () + >|=? Operation.pack) + endorsers + >>=? fun endos -> + let endorsing_power = + List.fold_left + (fun acc (_pkh, slots) -> acc + List.length slots) + 0 + endorsers + in + let fee = Tez.one in + Op.transaction (B b1) ~fee baker_b1_contract baker_b1_contract Tez.zero + >>=? fun tx -> + Block.bake ~policy:(By_round 0) ~operations:(tx :: endos) b1 >>=? fun b2 -> + Context.get_baker (B b1) ~round:0 >>=? fun baker_b2 -> + get_contract_for_pkh contracts baker_b2 >>=? fun baker_b2_contract -> + Context.Contract.balance (B b2) baker_b2_contract >>=? fun bal -> + Context.Delegate.current_frozen_deposits (B b2) baker_b2 + >>=? fun frozen_deposit -> + Context.get_baking_reward_fixed_portion (B b2) >>=? fun baking_reward -> + Context.get_bonus_reward (B b2) ~endorsing_power >>=? fun bonus_reward -> + (if Signature.Public_key_hash.equal baker_b2 baker_b1 then + Context.get_baking_reward_fixed_portion (B b1) + else return Tez.zero) + >>=? fun reward_for_b1 -> + (* we are in the first scenario where the payload producer is the same as the + block producer, in our case, [baker_b2]. [baker_b2] gets the baking reward + plus the fee for the transaction [tx]. *) + let expected_balance = + let open Test_tez in + Account.default_initial_balance -! frozen_deposit +! baking_reward + +! bonus_reward +! reward_for_b1 +! fee + in + Assert.equal_tez ~loc:__LOC__ bal expected_balance >>=? fun () -> + (* Some new baker [baker_b2'] bakes b2' at the first round which does not + correspond to a slot of [baker_b2] and it includes the PQC for [b2]. We + check that the fixed baking reward goes to the payload producer [baker_b2], + while the bonus goes to the the block producer (aka baker) [baker_b2']. *) + Context.get_endorsers (B b2) >>=? fun endorsers -> + List.map_es + (function + | {Plugin.RPC.Validators.delegate; slots; _} -> return (delegate, slots)) + endorsers + >>=? fun preendorsers -> + List.map_ep + (fun endorser -> + Op.preendorsement ~delegate:endorser ~endorsed_block:b2 (B b1) () + >|=? Operation.pack) + preendorsers + >>=? fun preendos -> + Context.get_baker (B b1) ~round:0 >>=? fun baker_b2 -> + get_baker_different_from_baker (B b1) baker_b2 >>=? fun baker_b2' -> + Block.bake + ~payload_round:(Some Round.zero) + ~locked_round:(Some Round.zero) + ~policy:(By_account baker_b2') + ~operations:(tx :: preendos @ endos) + b1 + >>=? fun b2' -> + (* [baker_b2], as payload producer, gets the block reward and the fees *) + Context.Contract.balance (B b2') baker_b2_contract >>=? fun bal -> + Context.Delegate.current_frozen_deposits (B b2') baker_b2 + >>=? fun frozen_deposit -> + let reward_for_b1 = + if Signature.Public_key_hash.equal baker_b2 baker_b1 then baking_reward + else Tez.zero + in + let expected_balance = + let open Test_tez in + Account.default_initial_balance +! baking_reward -! frozen_deposit + +! reward_for_b1 +! fee + in + Assert.equal_tez ~loc:__LOC__ bal expected_balance >>=? fun () -> + (* [baker_b2'] gets the bonus because he is the one who included the + endorsements *) + get_contract_for_pkh contracts baker_b2' >>=? fun baker_b2'_contract -> + Context.Contract.balance (B b2') baker_b2'_contract >>=? fun bal' -> + Context.Delegate.current_frozen_deposits (B b2') baker_b2' + >>=? fun frozen_deposits' -> + Context.get_baker (B genesis) ~round:0 >>=? fun baker_b1 -> + let reward_for_b1' = + if Signature.Public_key_hash.equal baker_b2' baker_b1 then baking_reward + else Tez.zero + in + let expected_balance' = + let open Test_tez in + Account.default_initial_balance +! bonus_reward +! reward_for_b1' + -! frozen_deposits' + in + Assert.equal_tez ~loc:__LOC__ bal' expected_balance' + +(** We test that: + - a delegate that has active stake can bake; + - a delegate that has no active stake cannot bake. +*) +let test_enough_active_stake_to_bake ~has_active_stake () = + Context.init 1 >>=? fun (b_for_constants, _) -> + Context.get_constants (B b_for_constants) + >>=? fun Constants.{parametric = {tokens_per_roll; _}; _} -> + let tpr = Tez.to_mutez tokens_per_roll in + (* N.B. setting the balance has an impact on the active stake; without + delegation, the full balance is the same as the staking balance and the + active balance is less or equal the staking balance (see + [Delegate_storage.select_distribution_for_cycle]). *) + let initial_bal1 = if has_active_stake then tpr else Int64.sub tpr 1L in + Context.init ~initial_balances:[initial_bal1; tpr] ~consensus_threshold:0 2 + >>=? fun (b0, accounts) -> + let (account1, _account2) = + match accounts with a1 :: a2 :: _ -> (a1, a2) | _ -> assert false + in + Context.Contract.pkh account1 >>=? fun pkh1 -> + Context.get_constants (B b0) + >>=? fun Constants.{parametric = {baking_reward_fixed_portion; _}; _} -> + Block.bake ~policy:(By_account pkh1) b0 >>= fun b1 -> + if has_active_stake then + b1 >>?= fun b1 -> + Context.Contract.balance (B b1) account1 >>=? fun bal -> + Context.Delegate.current_frozen_deposits (B b1) pkh1 + >>=? fun frozen_deposit -> + let expected_bal = + Test_tez.( + Tez.of_mutez_exn initial_bal1 + -! frozen_deposit +! baking_reward_fixed_portion) + in + Assert.equal_tez ~loc:__LOC__ bal expected_bal + else + (* pkh1 has less than tokens_per_roll so it will have no slots, thus it + cannot be a proposer, thus it cannot bake. Precisely, bake fails because + get_next_baker_by_account fails with "No slots found for pkh1" *) + Assert.error ~loc:__LOC__ b1 (fun _ -> true) + +let test_committee_sampling () = + let test_distribution max_round distribution = + let (initial_balances, bounds) = List.split distribution in + let accounts = + Account.generate_accounts ~initial_balances (List.length initial_balances) + in + let bootstrap_accounts = + List.map + (fun (acc, tez) -> + Default_parameters.make_bootstrap_account + (acc.Account.pkh, acc.Account.pk, tez)) + accounts + in + let constants = + { + Default_parameters.constants_test with + consensus_committee_size = max_round; + consensus_threshold = 0; + } + in + let parameters = + Default_parameters.parameters_of_constants ~bootstrap_accounts constants + in + Block.genesis_with_parameters parameters >>=? fun genesis -> + Plugin.RPC.Baking_rights.get Block.rpc_ctxt ~all:true ~max_round genesis + >|=? fun bakers -> + let stats = Stdlib.Hashtbl.create 10 in + Stdlib.List.iter2 + (fun (acc, _) bounds -> + Stdlib.Hashtbl.add stats acc.Account.pkh (bounds, 0)) + accounts + bounds ; + List.iter + (fun {Plugin.RPC.Baking_rights.delegate = pkh; _} -> + let (bounds, n) = Stdlib.Hashtbl.find stats pkh in + Stdlib.Hashtbl.replace stats pkh (bounds, n + 1)) + bakers ; + let one_failed = ref false in + Format.eprintf + "Testing with baker distribution [%a], committee size %d.@\n" + (Format.pp_print_list + ~pp_sep:(fun ppf () -> Format.fprintf ppf ",") + (fun ppf (tez, _) -> Format.fprintf ppf "%Ld" tez)) + distribution + max_round ; + Stdlib.Hashtbl.iter + (fun pkh ((min_p, max_p), n) -> + let failed = not (n >= min_p && n <= max_p) in + Format.eprintf + " - %s%a %d%s@." + (if failed then "\027[1m" else "") + Signature.Public_key_hash.pp + pkh + n + (if failed then + Format.asprintf " [FAIL]\027[0m should be \\in [%d,%d]" min_p max_p + else "") ; + if failed then one_failed := true) + stats ; + if !one_failed then + Stdlib.failwith + "The proportion of bakers marked as [FAILED] in the log output appear \ + in the wrong proportion in the committee." + else Format.eprintf "Test succesful.@\n" + in + (* The tests below are not deterministic, but the probability that + they fail is infinitesimal. *) + test_distribution + 100_000 + [ + (8_000_000_000L, (9_400, 10_600)); + (8_000_000_000L, (9_400, 10_600)); + (8_000_000_000L, (9_400, 10_600)); + (8_000_000_000L, (9_400, 10_600)); + (8_000_000_000L, (9_400, 10_600)); + (8_000_000_000L, (9_400, 10_600)); + (8_000_000_000L, (9_400, 10_600)); + (8_000_000_000L, (9_400, 10_600)); + (8_000_000_000L, (9_400, 10_600)); + (8_000_000_000L, (9_400, 10_600)); + ] + >>=? fun () -> + test_distribution + 10_000 + [ + (16_000_000_000L, (4_600, 5_400)); + (8_000_000_000L, (2_200, 2_800)); + (8_000_000_000L, (2_200, 2_800)); + ] + >>=? fun () -> + test_distribution + 10_000 + [(792_000_000_000L, (9_830, 9_970)); (8_000_000_000L, (40, 160))] + +let tests = + [ + Tztest.tztest "cycle" `Quick test_cycle; + Tztest.tztest + "test_bake_n_cycles for 12 cycles" + `Quick + (test_bake_n_cycles 12); + Tztest.tztest "voting_power" `Quick test_voting_power_cache; + Tztest.tztest + "the fixed baking reward is given after a bake" + `Quick + test_basic_baking_reward; + Tztest.tztest + "test that the block producer gets the bonus while the payload producer \ + gets the baking reward " + `Quick + test_rewards_block_and_payload_producer; + Tztest.tztest + "test that a delegate with 8000 tez can bake" + `Quick + (test_enough_active_stake_to_bake ~has_active_stake:true); + Tztest.tztest + "test that a delegate with 7999 tez cannot bake" + `Quick + (test_enough_active_stake_to_bake ~has_active_stake:false); + Tztest.tztest "test committee sampling" `Quick test_committee_sampling; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_combined_operations.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_combined_operations.ml new file mode 100644 index 000000000000..027f10eb2fe4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_combined_operations.ml @@ -0,0 +1,335 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (combined operations) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^combined$" + Subject: Multiple operations can be grouped in one ensuring their + deterministic application. + + If an invalid operation is present in this group of + operations, the previously applied operations are + backtracked leaving the context unchanged and the + following operations are skipped. Fees attributed to the + operations are collected by the baker nonetheless. + + Only manager operations are allowed in multiple transactions. + They must all belong to the same manager as there is only one + signature. +*) + +open Protocol +open Alpha_context + +let ten_tez = Test_tez.of_int 10 + +let gas_limit = Alpha_context.Gas.Arith.integral_of_int_exn 3000 + +(** Groups ten transactions between the same parties. *) +let test_multiple_transfers () = + Context.init 3 >>=? fun (blk, contracts) -> + let (c1, c2, c3) = + match contracts with [c1; c2; c3] -> (c1, c2, c3) | _ -> assert false + in + List.map_es + (fun _ -> Op.transaction ~gas_limit (B blk) c1 c2 Tez.one) + (1 -- 10) + >>=? fun ops -> + Op.combine_operations ~source:c1 (B blk) ops >>=? fun operation -> + Context.Contract.pkh c3 >>=? fun baker_pkh -> + Incremental.begin_construction ~policy:(By_account baker_pkh) blk + >>=? fun inc -> + Context.Contract.balance (I inc) c1 >>=? fun c1_old_balance -> + Context.Contract.balance (I inc) c2 >>=? fun c2_old_balance -> + Incremental.add_operation inc operation >>=? fun inc -> + Assert.balance_was_debited + ~loc:__LOC__ + (I inc) + c1 + c1_old_balance + (Test_tez.of_int 10) + >>=? fun () -> + Assert.balance_was_credited + ~loc:__LOC__ + (I inc) + c2 + c2_old_balance + (Test_tez.of_int 10) + >>=? fun () -> return_unit + +(** Groups ten delegated originations. *) +let test_multiple_origination_and_delegation () = + Context.init 2 >>=? fun (blk, contracts) -> + let (c1, c2) = + match contracts with [c1; c2] -> (c1, c2) | _ -> assert false + in + let n = 10 in + Context.get_constants (B blk) + >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> + Context.Contract.pkh c2 >>=? fun delegate_pkh -> + (* Deploy n smart contracts with dummy scripts from c1 *) + List.map_es + (fun i -> + Op.origination + ~gas_limit + ~delegate:delegate_pkh + ~counter:(Z.of_int i) + ~fee:Tez.zero + ~script:Op.dummy_script + ~credit:(Test_tez.of_int 10) + (B blk) + c1) + (1 -- n) + >>=? fun originations -> + (* These computed originated contracts are not the ones really created *) + (* We will extract them from the tickets *) + let (originations_operations, _) = List.split originations in + Op.combine_operations ~source:c1 (B blk) originations_operations + >>=? fun operation -> + Incremental.begin_construction blk >>=? fun inc -> + Context.Contract.balance (I inc) c1 >>=? fun c1_old_balance -> + Incremental.add_operation inc operation >>=? fun inc -> + (* To retrieve the originated contracts, it is easier to extract them + from the tickets. Else, we could (could we ?) hash each combined + operation individually. *) + let tickets = Incremental.rev_tickets inc in + let open Apply_results in + let tickets = + List.fold_left + (fun acc -> function + | No_operation_metadata -> assert false + | Operation_metadata {contents} -> + to_list (Contents_result_list contents) @ acc) + [] + tickets + |> List.rev + in + let new_contracts = + List.map + (function + | Contents_result + (Manager_operation_result + { + operation_result = + Applied (Origination_result {originated_contracts = [h]; _}); + _; + }) -> + h + | _ -> assert false) + tickets + in + (* Previous balance - (Credit (n * 10tz) + Origination cost (n tz)) *) + Test_tez.(cost_per_byte *? Int64.of_int origination_size) + >>?= fun origination_burn -> + Test_tez.(origination_burn *? Int64.of_int n) + >>?= fun origination_total_cost -> + Test_tez.( *? ) Op.dummy_script_cost 10L + >>? Test_tez.( +? ) (Test_tez.of_int (10 * n)) + >>? Test_tez.( +? ) origination_total_cost + >>?= fun total_cost -> + Assert.balance_was_debited ~loc:__LOC__ (I inc) c1 c1_old_balance total_cost + >>=? fun () -> + List.iter_es + (fun c -> Assert.balance_is ~loc:__LOC__ (I inc) c (Test_tez.of_int 10)) + new_contracts + +let expect_balance_too_low = function + | Environment.Ecoproto_error (Contract_storage.Balance_too_low _) :: _ -> + return_unit + | _ -> + failwith + "Contract should not have a sufficient balance : operation expected to \ + fail." + +(** Groups three operations, the middle one failing. + Checks that the receipt is consistent. + Variant without fees. *) +let test_failing_operation_in_the_middle () = + Context.init 2 >>=? fun (blk, contracts) -> + let (c1, c2) = + match contracts with [c1; c2] -> (c1, c2) | _ -> assert false + in + Op.transaction ~gas_limit ~fee:Tez.zero (B blk) c1 c2 Tez.one >>=? fun op1 -> + Op.transaction ~gas_limit ~fee:Tez.zero (B blk) c1 c2 Test_tez.max_tez + >>=? fun op2 -> + Op.transaction ~gas_limit ~fee:Tez.zero (B blk) c1 c2 Tez.one >>=? fun op3 -> + let operations = [op1; op2; op3] in + Op.combine_operations ~source:c1 (B blk) operations >>=? fun operation -> + Incremental.begin_construction blk >>=? fun inc -> + Context.Contract.balance (I inc) c1 >>=? fun c1_old_balance -> + Context.Contract.balance (I inc) c2 >>=? fun c2_old_balance -> + Incremental.add_operation ~expect_failure:expect_balance_too_low inc operation + >>=? fun inc -> + let tickets = Incremental.rev_tickets inc in + let open Apply_results in + let tickets = + List.fold_left + (fun acc -> function + | No_operation_metadata -> assert false + | Operation_metadata {contents} -> + to_list (Contents_result_list contents) @ acc) + [] + tickets + in + (match tickets with + | Contents_result + (Manager_operation_result {operation_result = Backtracked _; _}) + :: Contents_result + (Manager_operation_result {operation_result = Failed (_, trace); _}) + :: Contents_result + (Manager_operation_result {operation_result = Skipped _; _}) + :: _ -> + let trace_string = + Format.asprintf "%a" Environment.Error_monad.pp_trace trace + in + let expect = + Format.asprintf "Balance of contract %a too low" Context.Contract.pp c1 + in + assert (Astring.String.is_infix ~affix:expect trace_string) + | _ -> assert false) ; + Assert.balance_is ~loc:__LOC__ (I inc) c1 c1_old_balance >>=? fun () -> + Assert.balance_is ~loc:__LOC__ (I inc) c2 c2_old_balance >>=? fun () -> + return_unit + +(** Groups three operations, the middle one failing. + Checks that the receipt is consistent. + Variant with fees, that should be spent even in case of failure. *) +let test_failing_operation_in_the_middle_with_fees () = + Context.init 2 >>=? fun (blk, contracts) -> + let (c1, c2) = + match contracts with [c1; c2] -> (c1, c2) | _ -> assert false + in + Op.transaction ~fee:Tez.one (B blk) c1 c2 Tez.one >>=? fun op1 -> + Op.transaction ~fee:Tez.one (B blk) c1 c2 Test_tez.max_tez >>=? fun op2 -> + Op.transaction ~fee:Tez.one (B blk) c1 c2 Tez.one >>=? fun op3 -> + let operations = [op1; op2; op3] in + Op.combine_operations ~source:c1 (B blk) operations >>=? fun operation -> + Incremental.begin_construction blk >>=? fun inc -> + Context.Contract.balance (I inc) c1 >>=? fun c1_old_balance -> + Context.Contract.balance (I inc) c2 >>=? fun c2_old_balance -> + Incremental.add_operation ~expect_failure:expect_balance_too_low inc operation + >>=? fun inc -> + let tickets = Incremental.rev_tickets inc in + let open Apply_results in + let tickets = + List.fold_left + (fun acc -> function + | No_operation_metadata -> assert false + | Operation_metadata {contents} -> + to_list (Contents_result_list contents) @ acc) + [] + tickets + in + (match tickets with + | Contents_result + (Manager_operation_result {operation_result = Backtracked _; _}) + :: Contents_result + (Manager_operation_result {operation_result = Failed (_, trace); _}) + :: Contents_result + (Manager_operation_result {operation_result = Skipped _; _}) + :: _ -> + let trace_string = + Format.asprintf "%a" Environment.Error_monad.pp_trace trace + in + let expect = + Format.asprintf "Balance of contract %a too low" Context.Contract.pp c1 + in + assert (Astring.String.is_infix ~affix:expect trace_string) + | _ -> assert false) ; + (* In the presence of a failure, all the fees are collected. Even for skipped operations. *) + Assert.balance_was_debited + ~loc:__LOC__ + (I inc) + c1 + c1_old_balance + (Test_tez.of_int 3) + >>=? fun () -> + Assert.balance_is ~loc:__LOC__ (I inc) c2 c2_old_balance >>=? fun () -> + return_unit + +let expect_wrong_signature list = + if + List.exists + (function + | Environment.Ecoproto_error Apply.Inconsistent_sources -> true + | _ -> false) + list + then return_unit + else + failwith + "Packed operation has invalid source in the middle : operation expected \ + to fail." + +let test_wrong_signature_in_the_middle () = + Context.init 2 >>=? function + | (_, []) | (_, [_]) -> assert false + | (blk, c1 :: c2 :: _) -> + Op.transaction ~gas_limit ~fee:Tez.one (B blk) c1 c2 Tez.one + >>=? fun op1 -> + Op.transaction ~gas_limit ~fee:Tez.one (B blk) c2 c1 Tez.one + >>=? fun op2 -> + Incremental.begin_construction blk >>=? fun inc -> + (* Make legit transfers, performing reveals *) + Incremental.add_operation inc op1 >>=? fun inc -> + Incremental.add_operation inc op2 >>=? fun inc -> + (* Cook transactions for actual test *) + Op.transaction ~gas_limit ~fee:Tez.one (I inc) c1 c2 Tez.one + >>=? fun op1 -> + Op.transaction ~gas_limit ~fee:Tez.one (I inc) c1 c2 Tez.one + >>=? fun op2 -> + Op.transaction ~gas_limit ~fee:Tez.one (I inc) c1 c2 Tez.one + >>=? fun op3 -> + Op.transaction ~gas_limit ~fee:Tez.one (I inc) c2 c1 Tez.one + >>=? fun spurious_operation -> + let operations = [op1; op2; op3] in + Op.combine_operations ~spurious_operation ~source:c1 (I inc) operations + >>=? fun operation -> + Incremental.add_operation + ~expect_apply_failure:expect_wrong_signature + inc + operation + >>=? fun _inc -> return_unit + +let tests = + [ + Tztest.tztest "multiple transfers" `Quick test_multiple_transfers; + Tztest.tztest + "multiple originations and delegations" + `Quick + test_multiple_origination_and_delegation; + Tztest.tztest + "Failing operation in the middle" + `Quick + test_failing_operation_in_the_middle; + Tztest.tztest + "Failing operation in the middle (with fees)" + `Quick + test_failing_operation_in_the_middle_with_fees; + Tztest.tztest + "Failing operation (wrong manager in the middle of a pack)" + `Quick + test_wrong_signature_in_the_middle; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_constants.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_constants.ml new file mode 100644 index 000000000000..3476f92ac99f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_constants.ml @@ -0,0 +1,87 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (baking) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^constants$" + Subject: the consistency of parametric constants + *) + +open Test_tez + +let test_constants_consistency () = + let open Default_parameters in + List.iter_es + Block.check_constants_consistency + [constants_mainnet; constants_sandbox; constants_test] + +let test_max_operations_ttl () = + let open Protocol in + (* We check the rationale that the value for [max_operations_time_to_live] is the following: + + [minimal_time_between_blocks * max_operations_time_to_live = 3600] *) + let constants = Default_parameters.constants_mainnet in + Environment.wrap_tzresult + (Alpha_context.Period.mult + (Int32.of_int constants.max_operations_time_to_live) + constants.minimal_block_delay) + >>?= fun result -> + Assert.equal + ~loc:__LOC__ + (fun x y -> Alpha_context.Period.compare x y = 0) + "max_operations_ttl" + Alpha_context.Period.pp + Alpha_context.Period.one_hour + result + +(** Test that the amount of the liquidity baking subsidy is epsilon smaller than + 1/16th of the maximum reward. *) +let liquidity_baking_subsidy_param () = + let constants = Default_parameters.constants_mainnet in + constants.baking_reward_bonus_per_slot + *? Int64.of_int (constants.consensus_committee_size / 3) + >>?= fun baking_reward_bonus -> + constants.baking_reward_fixed_portion +? baking_reward_bonus + >>?= fun baking_rewards -> + constants.endorsing_reward_per_slot + *? Int64.of_int constants.consensus_committee_size + >>?= fun validators_rewards -> + baking_rewards +? validators_rewards >>?= fun total_rewards -> + total_rewards /? 16L >>?= fun expected_subsidy -> + constants.liquidity_baking_subsidy -? expected_subsidy >>?= fun diff -> + let max_diff = 1000 (* mutez *) in + Assert.leq_int ~loc:__LOC__ (Int64.to_int (to_mutez diff)) max_diff + +let tests = + [ + Tztest.tztest "constants consistency" `Quick test_constants_consistency; + Tztest.tztest "max_operations_ttl" `Quick test_max_operations_ttl; + Tztest.tztest + "test liquidity_baking_subsidy parameter is 1/16th of total baking \ + rewards" + `Quick + liquidity_baking_subsidy_param; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_deactivation.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_deactivation.ml new file mode 100644 index 000000000000..d30303acb4eb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_deactivation.ml @@ -0,0 +1,351 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (rolls) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^deactivation$" + Subject: After a given number of cycles during which a delegate has not + made use of its baking and endorsing rights, its account will + be deactivated for validator selection. To bake/endorse + again, it will have to re-activate its account. +*) + +open Protocol +open Alpha_context +open Test_tez + +let account_pair = function [a1; a2] -> (a1, a2) | _ -> assert false + +let wrap e = Lwt.return (Environment.wrap_tzresult e) + +(** Check that [Delegate.staking_balance] is the same as [Delegate.full_balance] + (this is not true in general, but in these tests it is because they only deal + with self-delegation. Also, check that [Delegate.staking_balance] coincides + with [Stake_storage.get] when the account is active and it has at least one + roll. *) +let check_stake ~loc (b : Block.t) (account : Account.t) = + Context.Delegate.staking_balance (B b) account.pkh >>=? fun staking_balance -> + Context.Delegate.full_balance (B b) account.pkh >>=? fun full_balance -> + Assert.equal_tez ~loc full_balance staking_balance >>=? fun () -> + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >>= wrap + >>=? fun ctxt -> + Stake_storage.get ctxt account.pkh >>= wrap >>=? fun stake -> + Assert.equal_int64 + ~loc + (Tez_repr.to_mutez stake) + (Tez.to_mutez staking_balance) + +(** Check that [Stake_storage.get] returns 0 (following a deactivation). Note + that in case of deactivation [Delegate.staking_balance] does not necessarily + coincide with [Stake_storage.get] in that [Delegate.staking_balance] may be + positive (while [Stake_storage.get] returns 0 because the account is no + longer in [Active_delegate_with_one_roll] because of deactivation, see + [Stake_storage].) *) +let check_no_stake ~loc (b : Block.t) (account : Account.t) = + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >>= wrap + >>=? fun ctxt -> + Stake_storage.get ctxt account.pkh >>= wrap >>=? fun stake -> + Assert.equal_int64 ~loc (Tez_repr.to_mutez stake) 0L + +(** Create a block with two initialized contracts/accounts. Assert + that the first account has a staking balance that is equal to its + own balance, and that its staking rights are consistent + (check_stake). *) +let test_simple_staking_rights () = + Context.init 2 >>=? fun (b, accounts) -> + let (a1, _a2) = account_pair accounts in + Context.Contract.balance (B b) a1 >>=? fun balance -> + Context.Contract.pkh a1 >>=? fun delegate1 -> + Context.Delegate.current_frozen_deposits (B b) delegate1 + >>=? fun frozen_deposits -> + let expected_initial_balance = + Account.default_initial_balance -! frozen_deposits + in + Assert.equal_tez ~loc:__LOC__ balance expected_initial_balance >>=? fun () -> + Context.Contract.manager (B b) a1 >>=? fun m1 -> + Context.Delegate.info (B b) m1.pkh >>=? fun info -> + Assert.equal_tez + ~loc:__LOC__ + Account.default_initial_balance + info.staking_balance + >>=? fun () -> check_stake ~loc:__LOC__ b m1 + +(** Create a block with two initialized contracts/accounts. Bake + five blocks. Assert that the staking balance of the first account + equals to its balance. Then both accounts have consistent staking + rights. *) +let test_simple_staking_rights_after_baking () = + Context.init ~consensus_threshold:0 2 >>=? fun (b, accounts) -> + let (a1, a2) = account_pair accounts in + Context.Contract.manager (B b) a1 >>=? fun m1 -> + Context.Contract.manager (B b) a2 >>=? fun m2 -> + Block.bake_n ~policy:(By_account m2.pkh) 5 b >>=? fun b -> + Context.Contract.balance (B b) a1 >>=? fun balance -> + Context.Contract.pkh a1 >>=? fun delegate1 -> + Context.Delegate.current_frozen_deposits (B b) delegate1 + >>=? fun frozen_deposits -> + balance +? frozen_deposits >>?= fun full_balance -> + Context.Delegate.info (B b) m1.pkh >>=? fun info -> + Assert.equal_tez ~loc:__LOC__ full_balance info.staking_balance >>=? fun () -> + check_stake ~loc:__LOC__ b m1 >>=? fun () -> check_stake ~loc:__LOC__ b m2 + +let check_active_staking_balance ~loc ~deactivated b (m : Account.t) = + Context.Delegate.info (B b) m.pkh >>=? fun info -> + Assert.equal_bool ~loc info.deactivated deactivated >>=? fun () -> + if deactivated then check_no_stake ~loc b m else check_stake ~loc b m + +let run_until_deactivation () = + Context.init ~consensus_threshold:0 2 >>=? fun (b, accounts) -> + let (a1, a2) = account_pair accounts in + Context.Contract.balance (B b) a1 >>=? fun balance_start -> + Context.Contract.manager (B b) a1 >>=? fun m1 -> + Context.Contract.manager (B b) a2 >>=? fun m2 -> + check_active_staking_balance ~loc:__LOC__ ~deactivated:false b m1 + >>=? fun () -> + Context.Delegate.info (B b) m1.pkh >>=? fun info -> + Block.bake_until_cycle ~policy:(By_account m2.pkh) info.grace_period b + >>=? fun b -> + check_active_staking_balance ~loc:__LOC__ ~deactivated:false b m1 + >>=? fun () -> + Block.bake_until_cycle_end ~policy:(By_account m2.pkh) b >>=? fun b -> + check_active_staking_balance ~loc:__LOC__ ~deactivated:true b m1 + >|=? fun () -> (b, ((a1, m1), balance_start), (a2, m2)) + +(** From an initialized block with two contracts/accounts, the first + one is active then deactivated. After baking, check that the + account is active again. Baking rights are ensured. *) +let test_deactivation_then_bake () = + run_until_deactivation () + >>=? fun ( b, + ((_deactivated_contract, deactivated_account), _start_balance), + (_a2, _m2) ) -> + Block.bake ~policy:(By_account deactivated_account.pkh) b >>=? fun b -> + check_active_staking_balance + ~loc:__LOC__ + ~deactivated:false + b + deactivated_account + +(** check that an account which is deactivated for [preserved_cycles] cannot be + part of a committee *) +let test_a_really_deactivated_account_is_not_in_the_committee () = + run_until_deactivation () + >>=? fun ( b, + ((_deactivated_contract, deactivated_account), _start_balance), + (_a2, m2) ) -> + (* at this point, the deactivated account can either bake (because it still + has rights) and become active again, or, in case it is inactive for another + [preserved_cycles], it has no more rights, thus cannot be part of the + committee. *) + let constants = Default_parameters.constants_test in + Block.bake_until_n_cycle_end + (constants.preserved_cycles + 1) + ~policy:(By_account m2.pkh) + b + >>=? fun b -> + Plugin.RPC.Baking_rights.get + Block.rpc_ctxt + ~delegates:[deactivated_account.pkh] + b + >>=? fun bakers -> + match List.hd bakers with Some _ -> assert false | None -> return_unit + +(** A deactivated account, after baking with self-delegation, is + active again. Preservation of its balance is tested. Baking rights + are ensured. *) +let test_deactivation_then_self_delegation () = + run_until_deactivation () + >>=? fun ( b, + ((deactivated_contract, deactivated_account), _start_balance), + (_a2, m2) ) -> + Op.delegation (B b) deactivated_contract (Some deactivated_account.pkh) + >>=? fun self_delegation -> + Block.bake ~policy:(By_account m2.pkh) b ~operation:self_delegation + >>=? fun b -> + check_active_staking_balance + ~loc:__LOC__ + ~deactivated:false + b + deactivated_account + >>=? fun () -> check_stake ~loc:__LOC__ b deactivated_account + +(** A deactivated account, which is emptied (into a newly created sink + account), then self-delegated, becomes activated. Its balance is + zero. Baking rights are ensured. *) +let test_deactivation_then_empty_then_self_delegation () = + run_until_deactivation () + >>=? fun ( b, + ((deactivated_contract, deactivated_account), _start_balance), + (_a2, m2) ) -> + (* empty the contract *) + Context.Contract.balance (B b) deactivated_contract >>=? fun balance -> + let sink_account = Account.new_account () in + let sink_contract = Contract.implicit_contract sink_account.pkh in + Context.get_constants (B b) + >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> + cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> + let amount = + match balance -? origination_burn with Ok r -> r | Error _ -> assert false + in + Op.transaction (B b) deactivated_contract sink_contract amount + >>=? fun empty_contract -> + Block.bake ~policy:(By_account m2.pkh) ~operation:empty_contract b + >>=? fun b1 -> + (* the account is deactivated, the stake is 0. *) + check_no_stake ~loc:__LOC__ b deactivated_account >>=? fun () -> + (* self delegation *) + Op.delegation (B b1) deactivated_contract (Some deactivated_account.pkh) + >>=? fun self_delegation -> + Block.bake ~policy:(By_account m2.pkh) ~operation:self_delegation b1 + >>=? fun b2 -> + check_active_staking_balance + ~loc:__LOC__ + ~deactivated:false + b2 + deactivated_account + >>=? fun () -> + (* the account is activated, the stake is still 0. *) + Context.Contract.balance (B b2) deactivated_contract >>=? fun balance -> + Assert.equal_tez ~loc:__LOC__ Tez.zero balance + +(** A deactivated account, which is emptied, then self-delegated, then + re-credited of the sunk amount, becomes active again. Staking + rights remain consistent. *) +let test_deactivation_then_empty_then_self_delegation_then_recredit () = + run_until_deactivation () + >>=? fun ( b, + ((deactivated_contract, deactivated_account), _start_balance), + (_a2, m2) ) -> + (* empty the contract *) + Context.Contract.balance (B b) deactivated_contract >>=? fun balance -> + let sink_account = Account.new_account () in + let sink_contract = Contract.implicit_contract sink_account.pkh in + Context.get_constants (B b) + >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> + cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> + let amount = + match balance -? origination_burn with Ok r -> r | Error _ -> assert false + in + Op.transaction (B b) deactivated_contract sink_contract amount + >>=? fun empty_contract -> + Block.bake ~policy:(By_account m2.pkh) ~operation:empty_contract b + >>=? fun b0 -> + (* the account is deactivated, the stake is 0. *) + check_no_stake ~loc:__LOC__ b deactivated_account >>=? fun () -> + (**** self delegation *) + Op.delegation (B b0) deactivated_contract (Some deactivated_account.pkh) + >>=? fun self_delegation -> + Block.bake ~policy:(By_account m2.pkh) ~operation:self_delegation b0 + >>=? fun b1 -> + (* the account is still deactivated *) + check_no_stake ~loc:__LOC__ b deactivated_account >>=? fun () -> + (**** recredit *) + Op.transaction (B b1) sink_contract deactivated_contract amount + >>=? fun recredit_contract -> + Block.bake ~policy:(By_account m2.pkh) ~operation:recredit_contract b1 + >>=? fun b2 -> + check_active_staking_balance + ~loc:__LOC__ + ~deactivated:false + b2 + deactivated_account + >>=? fun () -> + Context.Contract.balance (B b2) deactivated_contract >>=? fun balance2 -> + Assert.equal_tez ~loc:__LOC__ amount balance2 >>=? fun () -> + check_stake ~loc:__LOC__ b2 deactivated_account + +(** Initialize a block with two contracts/accounts. A third new account is also + created. The first account is self-delegated. First account sends to third + one tokens_per_roll tez (so that, once it is active, it can appear in + [Active_delegate_with_one_roll]. The third account has no delegate and is + consistent for baking rights. Then, it is self-delegated and is supposed to + be activated. Again, consistency for baking rights are preserved for the + first and third accounts. *) +let test_delegation () = + Context.init ~consensus_threshold:0 2 >>=? fun (b, accounts) -> + let (a1, a2) = account_pair accounts in + let m3 = Account.new_account () in + Account.add_account m3 ; + Context.Contract.manager (B b) a1 >>=? fun m1 -> + Context.Contract.manager (B b) a2 >>=? fun m2 -> + let a3 = Contract.implicit_contract m3.pkh in + Context.Contract.delegate_opt (B b) a1 >>=? fun delegate -> + (match delegate with + | None -> assert false + | Some pkh -> assert (Signature.Public_key_hash.equal pkh m1.pkh)) ; + let constants = Default_parameters.constants_test in + let one_roll = constants.tokens_per_roll in + Op.transaction (B b) a1 a3 one_roll >>=? fun transact -> + Block.bake ~policy:(By_account m2.pkh) b ~operation:transact >>=? fun b -> + Context.Contract.delegate_opt (B b) a3 >>=? fun delegate -> + (match delegate with None -> () | Some _ -> assert false) ; + check_no_stake ~loc:__LOC__ b m3 >>=? fun () -> + Op.delegation (B b) a3 (Some m3.pkh) >>=? fun delegation -> + Block.bake ~policy:(By_account m2.pkh) b ~operation:delegation >>=? fun b -> + Context.Contract.delegate_opt (B b) a3 >>=? fun delegate -> + (match delegate with + | None -> assert false + | Some pkh -> assert (Signature.Public_key_hash.equal pkh m3.pkh)) ; + check_active_staking_balance ~loc:__LOC__ ~deactivated:false b m3 + >>=? fun () -> + check_stake ~loc:__LOC__ b m3 >>=? fun () -> check_stake ~loc:__LOC__ b m1 + +let tests = + [ + Tztest.tztest "simple staking rights" `Quick test_simple_staking_rights; + Tztest.tztest + "simple staking rights after baking" + `Quick + test_simple_staking_rights_after_baking; + Tztest.tztest "deactivation then bake" `Quick test_deactivation_then_bake; + Tztest.tztest + "deactivation then self delegation" + `Quick + test_deactivation_then_self_delegation; + Tztest.tztest + "deactivation then empty then self delegation" + `Quick + test_deactivation_then_empty_then_self_delegation; + Tztest.tztest + "deactivation then empty then self delegation then recredit" + `Quick + test_deactivation_then_empty_then_self_delegation_then_recredit; + Tztest.tztest "delegate" `Quick test_delegation; + Tztest.tztest + "a really deactivated account is not part of the committee" + `Quick + test_a_really_deactivated_account_is_not_in_the_committee; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_delegation.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_delegation.ml new file mode 100644 index 000000000000..ab8e525674af --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_delegation.ml @@ -0,0 +1,1580 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (delegation) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^delegation$" + Subject: - Properties on bootstrap contracts (self-delegation, + cannot delete/change their delegate (as opposed to contracts + not-being-delegate which can do these), bootstrap manager + as delegate during origination). + - Properties on delegation depending on whether delegate + keys registration, through origination and delegation. +*) + +open Protocol +open Alpha_context +open Test_tez + +(*****************************************************************************) +(* Bootstrap contracts + ------------------- + Bootstrap contracts are heavily used in other tests. It is helpful to test + some properties of these contracts, so we can correctly interpret the other + tests that use them. *) +(*****************************************************************************) + +let expect_error err = function + | err0 :: _ when err = err0 -> return_unit + | _ -> failwith "Unexpected successful result" + +let expect_alpha_error err = expect_error (Environment.Ecoproto_error err) + +let expect_no_change_registered_delegate_pkh pkh = function + | Environment.Ecoproto_error (Delegate_storage.No_deletion pkh0) :: _ + when pkh0 = pkh -> + return_unit + | _ -> failwith "Delegate can not be deleted and operation should fail." + +(** Bootstrap contracts delegate to themselves. *) +let bootstrap_manager_is_bootstrap_delegate () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + let bootstrap0 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + Context.Contract.delegate (B b) bootstrap0 >>=? fun delegate0 -> + Context.Contract.manager (B b) bootstrap0 >>=? fun manager0 -> + Assert.equal_pkh ~loc:__LOC__ delegate0 manager0.pkh + +(** Bootstrap contracts cannot change their delegate. *) +let bootstrap_delegate_cannot_change ~fee () = + Context.init 2 >>=? fun (b, bootstrap_contracts) -> + let bootstrap0 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth bootstrap_contracts 0 + in + let bootstrap1 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth bootstrap_contracts 1 + in + Context.Contract.pkh bootstrap0 >>=? fun pkh1 -> + Incremental.begin_construction b ~policy:(Block.Excluding [pkh1]) + >>=? fun i -> + Context.Contract.manager (I i) bootstrap1 >>=? fun manager1 -> + Context.Contract.balance (I i) bootstrap0 >>=? fun balance0 -> + Context.Contract.delegate (I i) bootstrap0 >>=? fun delegate0 -> + (* change delegation to bootstrap1 *) + Op.delegation ~fee (I i) bootstrap0 (Some manager1.pkh) + >>=? fun set_delegate -> + if fee > balance0 then + Incremental.add_operation i set_delegate >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + Incremental.add_operation + ~expect_failure:(expect_no_change_registered_delegate_pkh delegate0) + i + set_delegate + >>=? fun i -> + Incremental.finalize_block i >>=? fun b -> + (* bootstrap0 still has same delegate *) + Context.Contract.delegate (B b) bootstrap0 >>=? fun delegate0_after -> + Assert.equal_pkh ~loc:__LOC__ delegate0_after delegate0 >>=? fun () -> + (* fee has been debited *) + Assert.balance_was_debited ~loc:__LOC__ (B b) bootstrap0 balance0 fee + +(** Bootstrap contracts cannot delete their delegation. *) +let bootstrap_delegate_cannot_be_removed ~fee () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + Incremental.begin_construction b >>=? fun i -> + Context.Contract.balance (I i) bootstrap >>=? fun balance -> + Context.Contract.delegate (I i) bootstrap >>=? fun delegate -> + Context.Contract.manager (I i) bootstrap >>=? fun manager -> + (* remove delegation *) + Op.delegation ~fee (I i) bootstrap None >>=? fun set_delegate -> + if fee > balance then + Incremental.add_operation i set_delegate >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + Incremental.add_operation + ~expect_failure:(expect_no_change_registered_delegate_pkh manager.pkh) + i + set_delegate + >>=? fun i -> + (* delegate has not changed *) + Context.Contract.delegate (I i) bootstrap >>=? fun delegate_after -> + Assert.equal_pkh ~loc:__LOC__ delegate delegate_after >>=? fun () -> + (* fee has been debited *) + Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee + +(** Contracts not registered as delegate can change their + delegation. *) +let delegate_can_be_changed_from_unregistered_contract ~fee () = + Context.init 2 >>=? fun (b, bootstrap_contracts) -> + let bootstrap0 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let bootstrap1 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth bootstrap_contracts 1 + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let unregistered = Contract.implicit_contract unregistered_pkh in + Incremental.begin_construction b >>=? fun i -> + Context.Contract.manager (I i) bootstrap0 >>=? fun manager0 -> + Context.Contract.manager (I i) bootstrap1 >>=? fun manager1 -> + let credit = of_int 10 in + Op.transaction ~fee:Tez.zero (I i) bootstrap0 unregistered credit + >>=? fun credit_contract -> + Context.Contract.balance (I i) bootstrap0 >>=? fun balance -> + Incremental.add_operation i credit_contract >>=? fun i -> + (* delegate to bootstrap0 *) + Op.delegation ~fee:Tez.zero (I i) unregistered (Some manager0.pkh) + >>=? fun set_delegate -> + Incremental.add_operation i set_delegate >>=? fun i -> + Context.Contract.delegate (I i) unregistered >>=? fun delegate -> + Assert.equal_pkh ~loc:__LOC__ delegate manager0.pkh >>=? fun () -> + (* change delegation to bootstrap1 *) + Op.delegation ~fee (I i) unregistered (Some manager1.pkh) + >>=? fun change_delegate -> + if fee > balance then + Incremental.add_operation i change_delegate >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + Incremental.add_operation i change_delegate >>=? fun i -> + (* delegate has changed *) + Context.Contract.delegate (I i) unregistered >>=? fun delegate_after -> + Assert.equal_pkh ~loc:__LOC__ delegate_after manager1.pkh >>=? fun () -> + (* fee has been debited *) + Assert.balance_was_debited ~loc:__LOC__ (I i) unregistered credit fee + +(** Contracts not registered as delegate can delete their + delegation. *) +let delegate_can_be_removed_from_unregistered_contract ~fee () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let unregistered = Contract.implicit_contract unregistered_pkh in + Incremental.begin_construction b >>=? fun i -> + Context.Contract.manager (I i) bootstrap >>=? fun manager -> + let credit = of_int 10 in + Op.transaction ~fee:Tez.zero (I i) bootstrap unregistered credit + >>=? fun credit_contract -> + Context.Contract.balance (I i) bootstrap >>=? fun balance -> + Incremental.add_operation i credit_contract >>=? fun i -> + (* delegate to bootstrap *) + Op.delegation ~fee:Tez.zero (I i) unregistered (Some manager.pkh) + >>=? fun set_delegate -> + Incremental.add_operation i set_delegate >>=? fun i -> + Context.Contract.delegate (I i) unregistered >>=? fun delegate -> + Assert.equal_pkh ~loc:__LOC__ delegate manager.pkh >>=? fun () -> + (* remove delegation *) + Op.delegation ~fee (I i) unregistered None >>=? fun delete_delegate -> + if fee > balance then + Incremental.add_operation i delete_delegate >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + Incremental.add_operation i delete_delegate >>=? fun i -> + (* the delegate has been removed *) + (Context.Contract.delegate_opt (I i) unregistered >>=? function + | None -> return_unit + | Some _ -> failwith "Expected delegate to be removed") + >>=? fun () -> + (* fee has been debited *) + Assert.balance_was_debited ~loc:__LOC__ (I i) unregistered credit fee + +(** Bootstrap keys are already registered as delegate keys. *) +let bootstrap_manager_already_registered_delegate ~fee () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + Context.Contract.manager (I i) bootstrap >>=? fun manager -> + let pkh = manager.pkh in + let impl_contract = Contract.implicit_contract pkh in + Context.Contract.balance (I i) impl_contract >>=? fun balance -> + Op.delegation ~fee (I i) impl_contract (Some pkh) >>=? fun sec_reg -> + if fee > balance then + Incremental.add_operation i sec_reg >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + Incremental.add_operation + ~expect_failure:(function + | Environment.Ecoproto_error Delegate_storage.Active_delegate :: _ -> + return_unit + | _ -> failwith "Delegate is already active and operation should fail.") + i + sec_reg + >>=? fun i -> + (* fee has been debited *) + Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract balance fee + +(** Bootstrap manager can be set as delegate of an originated contract + (through origination operation). *) +let delegate_to_bootstrap_by_origination ~fee () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + Context.Contract.manager (I i) bootstrap >>=? fun manager -> + Context.Contract.balance (I i) bootstrap >>=? fun balance -> + (* originate a contract with bootstrap's manager as delegate *) + Op.origination + ~fee + ~credit:Tez.zero + ~delegate:manager.pkh + (I i) + bootstrap + ~script:Op.dummy_script + >>=? fun (op, orig_contract) -> + Context.get_constants (I i) + >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> + (* 0.257tz *) + cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> + fee +? origination_burn >>? ( +? ) Op.dummy_script_cost >>?= fun total_fee -> + if fee > balance then + Incremental.add_operation i op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else if total_fee > balance && balance >= fee then + (* origination did not proceed; fee has been debited *) + Incremental.add_operation + i + ~expect_failure:(function + | Environment.Ecoproto_error (Contract.Balance_too_low _) :: _ -> + return_unit + | _ -> + failwith + "Not enough balance for origination burn: operation should fail.") + op + >>=? fun i -> + (* fee was taken *) + Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee + >>=? fun () -> + (* originated contract has not been created *) + Context.Contract.balance (I i) orig_contract >>= fun err -> + Assert.error ~loc:__LOC__ err (function + | RPC_context.Not_found _ -> true + | _ -> false) + else + (* bootstrap is delegate, fee + origination burn have been debited *) + Incremental.add_operation i op >>=? fun i -> + Context.Contract.delegate (I i) orig_contract >>=? fun delegate -> + Assert.equal_pkh ~loc:__LOC__ delegate manager.pkh >>=? fun () -> + Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance total_fee + +let undelegated_originated_bootstrap_contract () = + Context.init + 1 + ~bootstrap_contracts: + [ + Parameters.{delegate = None; amount = Tez.zero; script = Op.dummy_script}; + ] + >>=? fun (b, _) -> + Block.bake b >>=? fun b -> + (* We know the address of the first originated bootstrap contract because we know the bootstrap origination nonce. This address corresponds to the first TF vesting contract on mainnnet. *) + Lwt.return @@ Environment.wrap_tzresult + @@ Alpha_context.Contract.of_b58check "KT1WPEis2WhAc2FciM2tZVn8qe6pCBe9HkDp" + >>=? fun originated_bootstrap0 -> + Context.Contract.delegate_opt (B b) originated_bootstrap0 + >>=? fun delegate0 -> + match delegate0 with + | None -> return_unit + | Some _ -> failwith "Bootstrap contract should be undelegated (%s)" __LOC__ + +let tests_bootstrap_contracts = + [ + Tztest.tztest + "bootstrap contracts delegate to themselves" + `Quick + bootstrap_manager_is_bootstrap_delegate; + Tztest.tztest + "bootstrap contracts can change their delegate (small fee)" + `Quick + (bootstrap_delegate_cannot_change ~fee:Tez.one_mutez); + Tztest.tztest + "bootstrap contracts can change their delegate (max fee)" + `Quick + (bootstrap_delegate_cannot_change ~fee:max_tez); + Tztest.tztest + "bootstrap contracts cannot remove their delegation (small fee)" + `Quick + (bootstrap_delegate_cannot_be_removed ~fee:Tez.one_mutez); + Tztest.tztest + "bootstrap contracts cannot remove their delegation (max fee)" + `Quick + (bootstrap_delegate_cannot_be_removed ~fee:max_tez); + Tztest.tztest + "contracts not registered as delegate can remove their delegation (small \ + fee)" + `Quick + (delegate_can_be_changed_from_unregistered_contract ~fee:Tez.one_mutez); + Tztest.tztest + "contracts not registered as delegate can remove their delegation (max \ + fee)" + `Quick + (delegate_can_be_changed_from_unregistered_contract ~fee:max_tez); + Tztest.tztest + "contracts not registered as delegate can remove their delegation (small \ + fee)" + `Quick + (delegate_can_be_removed_from_unregistered_contract ~fee:Tez.one_mutez); + Tztest.tztest + "contracts not registered as delegate can remove their delegation (max \ + fee)" + `Quick + (delegate_can_be_removed_from_unregistered_contract ~fee:max_tez); + Tztest.tztest + "bootstrap keys are already registered as delegate keys (small fee)" + `Quick + (bootstrap_manager_already_registered_delegate ~fee:Tez.one_mutez); + Tztest.tztest + "bootstrap keys are already registered as delegate keys (max fee)" + `Quick + (bootstrap_manager_already_registered_delegate ~fee:max_tez); + Tztest.tztest + "bootstrap manager can be delegate (init origination, small fee)" + `Quick + (delegate_to_bootstrap_by_origination ~fee:Tez.one_mutez); + (* balance enough for fee but not for fee + origination burn + dummy script storage cost *) + Tztest.tztest + "bootstrap manager can be delegate (init origination, edge case)" + `Quick + (delegate_to_bootstrap_by_origination + ~fee:(Tez.of_mutez_exn 3_999_999_705_000L)); + (* fee bigger than bootstrap's initial balance*) + Tztest.tztest + "bootstrap manager can be delegate (init origination, large fee)" + `Quick + (delegate_to_bootstrap_by_origination ~fee:(Test_tez.of_int 10_000_000)); + Tztest.tztest + "originated bootstrap contract can be undelegated" + `Quick + undelegated_originated_bootstrap_contract; + ] + +(*****************************************************************************) +(* Delegate registration + --------------------- + A delegate is a pkh. Delegates must be registered. Registration is + done via the self-delegation of the implicit contract corresponding + to the pkh. The implicit contract must be credited when the + self-delegation is done. Furthermore, trying to register an already + registered key raises an error. + + In this series of tests, we verify that + 1- unregistered delegate keys cannot be delegated to, + 2- registered keys can be delegated to, + 3- registering an already registered key raises an error. + + We consider three scenarios for setting a delegate: + - through origination, + - through delegation when the implicit contract has no delegate yet, + - through delegation when the implicit contract already has a delegate. + + We also test that emptying the implicit contract linked to a + registered delegate key does not unregister the delegate key. + + Valid registration + ------------------ + Unregistered key: + - contract not credited and no self-delegation, + - contract credited but no self-delegation, + - contract not credited and self-delegation. + + Not credited: + - no credit operation + - credit operation of 1μꜩ and then debit operation of 1μꜩ *) +(*****************************************************************************) + +(* Part A. + Unregistered delegate keys cannot be used for delegation + + Two main series of tests: without self-delegation and with a failed attempt at self-delegation: + + 1/ no self-delegation + a/ no credit + - no token transfer + - credit of 1μꜩ and then debit of 1μꜩ + b/ with credit of 1μꜩ. + For every scenario, we try three different ways of delegating: + - through origination (init origination) + - through delegation when no delegate was assigned (init delegation) + - through delegation when a delegate was assigned (switch delegation). + + 2/ Self-delegation fails if the contract has no credit. We try the + two possibilities of 1a for non-credited contracts. *) + +let expect_unregistered_key pkh = function + | Environment.Ecoproto_error (Delegate_storage.Unregistered_delegate pkh0) + :: _ + when pkh = pkh0 -> + return_unit + | _ -> failwith "Delegate key is not registered: operation should fail." + +(* Part A. Section 1. + No self-delegation. *) + +(** No token transfer, no self-delegation. Originated account. If + fees are higher than balance, [Balance_too_low] is + raised. Otherwise, it checks the correct exception is raised + (unregistered key), and the fees are still debited. Using RPCs, we + verify the contract has not been originated. *) +let test_unregistered_delegate_key_init_origination ~fee () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + (* origination with delegate argument *) + Op.origination + ~fee + ~delegate:unregistered_pkh + (I i) + bootstrap + ~script:Op.dummy_script + >>=? fun (op, orig_contract) -> + Context.get_constants (I i) + >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> + cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> + fee +? origination_burn >>?= fun _total_fee -> + (* FIXME unused variable *) + Context.Contract.balance (I i) bootstrap >>=? fun balance -> + if fee > balance then + Incremental.add_operation i op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* origination did not proceed; fee has been debited *) + Incremental.add_operation + ~expect_failure:(expect_unregistered_key unregistered_pkh) + i + op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee + >>=? fun () -> + (* originated contract has not been created *) + Context.Contract.balance (I i) orig_contract >>= fun err -> + Assert.error ~loc:__LOC__ err (function + | RPC_context.Not_found _ -> true + | _ -> false) + +(** Delegation when delegate key is not assigned. Delegate account is + initialized. If fees are higher than initial credit (10 tez), + [Balance_too_low] is raised. Otherwise, fees are still debited. The + implicit contract has no delegate. *) +let test_unregistered_delegate_key_init_delegation ~fee () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + let unregistered_delegate_account = Account.new_account () in + let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in + (* initial credit for the delegated contract *) + let credit = of_int 10 in + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit + >>=? fun credit_contract -> + Incremental.add_operation i credit_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract credit >>=? fun _ -> + (* try to delegate *) + Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) + >>=? fun delegate_op -> + if fee > credit then + Incremental.add_operation i delegate_op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* fee has been debited; no delegate *) + Incremental.add_operation + i + ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) + delegate_op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract credit fee + >>=? fun () -> + (* implicit contract has no delegate *) + Context.Contract.delegate (I i) impl_contract >>= fun err -> + Assert.error ~loc:__LOC__ err (function + | RPC_context.Not_found _ -> true + | _ -> false) + +(** Re-delegation when a delegate key was already assigned. If fees + are higher than initial credit (10 tez), [Balance_too_low] is + raised. Otherwise, fees are not debited and the implicit contract + delegate remains unchanged. *) +let test_unregistered_delegate_key_switch_delegation ~fee () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let bootstrap_pkh = + Contract.is_implicit bootstrap |> WithExceptions.Option.get ~loc:__LOC__ + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + let unregistered_delegate_account = Account.new_account () in + let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in + (* initial credit for the delegated contract *) + let credit = of_int 10 in + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit + >>=? fun init_credit -> + Incremental.add_operation i init_credit >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract credit >>=? fun _ -> + (* set and check the initial delegate *) + Op.delegation ~fee:Tez.zero (I i) impl_contract (Some bootstrap_pkh) + >>=? fun delegate_op -> + Incremental.add_operation i delegate_op >>=? fun i -> + Context.Contract.delegate (I i) bootstrap >>=? fun delegate_pkh -> + Assert.equal_pkh ~loc:__LOC__ bootstrap_pkh delegate_pkh >>=? fun () -> + (* try to delegate *) + Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) + >>=? fun delegate_op -> + if fee > credit then + Incremental.add_operation i delegate_op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* fee has been debited; no delegate *) + Incremental.add_operation + i + ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) + delegate_op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract credit fee + >>=? fun () -> + (* implicit contract delegate has not changed *) + Context.Contract.delegate (I i) bootstrap >>=? fun delegate_pkh_after -> + Assert.equal_pkh ~loc:__LOC__ delegate_pkh delegate_pkh_after + +(** Same as [unregistered_delegate_key_init_origination] and credits + [amount], no self-delegation. *) +let test_unregistered_delegate_key_init_origination_credit ~fee ~amount () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + (* credit + check balance *) + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* origination with delegate argument *) + Context.Contract.balance (I i) bootstrap >>=? fun balance -> + Op.origination + ~fee + ~delegate:unregistered_pkh + (I i) + bootstrap + ~script:Op.dummy_script + >>=? fun (op, orig_contract) -> + if fee > balance then + Incremental.add_operation i op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* origination not done, fee taken *) + Incremental.add_operation + ~expect_failure:(expect_unregistered_key unregistered_pkh) + i + op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee + >>=? fun () -> + Context.Contract.balance (I i) orig_contract >>= fun err -> + Assert.error ~loc:__LOC__ err (function + | RPC_context.Not_found _ -> true + | _ -> false) + +(** Same as [unregistered_delegate_key_init_delegation] and credits + the amount [amount] of the implicit contract. *) +let test_unregistered_delegate_key_init_delegation_credit ~fee ~amount () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + let unregistered_delegate_account = Account.new_account () in + let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in + (* credit + check balance *) + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* initial credit for the delegated contract *) + let credit = of_int 10 in + credit +? amount >>?= fun balance -> + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit + >>=? fun init_credit -> + Incremental.add_operation i init_credit >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract balance >>=? fun _ -> + (* try to delegate *) + Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) + >>=? fun delegate_op -> + if fee > credit then + Incremental.add_operation i delegate_op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* fee has been taken, no delegate for contract *) + Incremental.add_operation + ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) + i + delegate_op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract balance fee + >>=? fun () -> + Context.Contract.delegate (I i) impl_contract >>= fun err -> + Assert.error ~loc:__LOC__ err (function + | RPC_context.Not_found _ -> true + | _ -> false) + +(** Same as in [unregistered_delegate_key_switch_delegation] and + credits the amount [amount] to the implicit contract. *) +let test_unregistered_delegate_key_switch_delegation_credit ~fee ~amount () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let bootstrap_pkh = + Contract.is_implicit bootstrap |> WithExceptions.Option.get ~loc:__LOC__ + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + let unregistered_delegate_account = Account.new_account () in + let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in + (* credit + check balance *) + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* initial credit for the delegated contract *) + let credit = of_int 10 in + credit +? amount >>?= fun balance -> + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit + >>=? fun init_credit -> + Incremental.add_operation i init_credit >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract balance >>=? fun _ -> + (* set and check the initial delegate *) + Op.delegation ~fee:Tez.zero (I i) impl_contract (Some bootstrap_pkh) + >>=? fun delegate_op -> + Incremental.add_operation i delegate_op >>=? fun i -> + Context.Contract.delegate (I i) bootstrap >>=? fun delegate_pkh -> + Assert.equal_pkh ~loc:__LOC__ bootstrap_pkh delegate_pkh >>=? fun () -> + (* switch delegate through delegation *) + Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) + >>=? fun delegate_op -> + if fee > credit then + Incremental.add_operation i delegate_op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* fee has been taken, delegate for contract has not changed *) + Incremental.add_operation + ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) + i + delegate_op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract balance fee + >>=? fun () -> + Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> + Assert.not_equal_pkh ~loc:__LOC__ delegate unregistered_delegate_pkh + >>=? fun () -> Assert.equal_pkh ~loc:__LOC__ delegate bootstrap_pkh + +(** A credit of some amount followed by a debit of the same amount, + no self-delegation. *) +let test_unregistered_delegate_key_init_origination_credit_debit ~fee ~amount () + = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + (* credit + check balance *) + Op.transaction (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* debit + check balance *) + Op.transaction (I i) impl_contract bootstrap amount >>=? fun debit_contract -> + Incremental.add_operation i debit_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> + (* origination with delegate argument *) + Context.Contract.balance (I i) bootstrap >>=? fun balance -> + Op.origination + ~fee + ~delegate:unregistered_pkh + (I i) + bootstrap + ~script:Op.dummy_script + >>=? fun (op, orig_contract) -> + if fee > balance then + Incremental.add_operation i op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* fee taken, origination not processed *) + Incremental.add_operation + ~expect_failure:(expect_unregistered_key unregistered_pkh) + i + op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) bootstrap balance fee + >>=? fun () -> + Context.Contract.balance (I i) orig_contract >>= fun err -> + Assert.error ~loc:__LOC__ err (function + | RPC_context.Not_found _ -> true + | _ -> false) + +(** Same as in [unregistered_delegate_key_init_delegation] but credits + then debits the amount [amount] to the implicit contract. *) +let test_unregistered_delegate_key_init_delegation_credit_debit ~amount ~fee () + = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + let unregistered_delegate_account = Account.new_account () in + let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in + (* credit + check balance *) + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* debit + check balance *) + Op.transaction ~fee:Tez.zero (I i) impl_contract bootstrap amount + >>=? fun debit_contract -> + Incremental.add_operation i debit_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> + (* initial credit for the delegated contract *) + let credit = of_int 10 in + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit + >>=? fun credit_contract -> + Incremental.add_operation i credit_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract credit >>=? fun _ -> + (* try to delegate *) + Op.delegation ~fee (I i) impl_contract (Some unregistered_delegate_pkh) + >>=? fun delegate_op -> + if fee > credit then + Incremental.add_operation i delegate_op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* fee has been taken, no delegate for contract *) + Incremental.add_operation + ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) + i + delegate_op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract credit fee + >>=? fun () -> + Context.Contract.delegate (I i) impl_contract >>= fun err -> + Assert.error ~loc:__LOC__ err (function + | RPC_context.Not_found _ -> true + | _ -> false) + +(** Same as in [unregistered_delegate_key_switch_delegation] but + credits then debits the amount [amount] to the implicit contract. *) +let test_unregistered_delegate_key_switch_delegation_credit_debit ~fee ~amount + () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let bootstrap_pkh = + Contract.is_implicit bootstrap |> WithExceptions.Option.get ~loc:__LOC__ + in + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + let unregistered_delegate_account = Account.new_account () in + let unregistered_delegate_pkh = Account.(unregistered_delegate_account.pkh) in + (* credit + check balance *) + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* debit + check balance *) + Op.transaction (I i) impl_contract bootstrap amount >>=? fun debit_contract -> + Incremental.add_operation i debit_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> + (* delegation - initial credit for the delegated contract *) + let credit = of_int 10 in + Op.transaction ~fee:Tez.zero (I i) bootstrap impl_contract credit + >>=? fun credit_contract -> + Incremental.add_operation i credit_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract credit >>=? fun _ -> + (* set and check the initial delegate *) + Op.delegation ~fee:Tez.zero (I i) impl_contract (Some bootstrap_pkh) + >>=? fun delegate_op -> + Incremental.add_operation i delegate_op >>=? fun i -> + Context.Contract.delegate (I i) bootstrap >>=? fun delegate_pkh -> + Assert.equal_pkh ~loc:__LOC__ bootstrap_pkh delegate_pkh >>=? fun () -> + (* switch delegate through delegation *) + Op.delegation (I i) ~fee impl_contract (Some unregistered_delegate_pkh) + >>=? fun delegate_op -> + if fee > credit then + Incremental.add_operation i delegate_op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* fee has been taken, delegate for contract has not changed *) + Incremental.add_operation + ~expect_failure:(expect_unregistered_key unregistered_delegate_pkh) + i + delegate_op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) impl_contract credit fee + >>=? fun () -> + Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> + Assert.not_equal_pkh ~loc:__LOC__ delegate unregistered_delegate_pkh + +(* Part A. Section 2. + Self-delegation to an empty contract fails. *) + +(** Self-delegation with zero-balance contract should fail. *) +let test_failed_self_delegation_no_transaction () = + Context.init 1 >>=? fun (b, _) -> + Incremental.begin_construction b >>=? fun i -> + let account = Account.new_account () in + let unregistered_pkh = Account.(account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + (* check balance *) + Context.Contract.balance (I i) impl_contract >>=? fun balance -> + Assert.equal_tez ~loc:__LOC__ Tez.zero balance >>=? fun _ -> + (* self delegation fails *) + Op.delegation (I i) impl_contract (Some unregistered_pkh) + >>=? fun self_delegation -> + Incremental.add_operation i self_delegation >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Empty_implicit_contract pkh -> + if pkh = unregistered_pkh then true else false + | _ -> false) + +(** Implicit contract is credited then debited of same amount (i.e., + is emptied). Self-delegation fails. *) +let test_failed_self_delegation_emptied_implicit_contract amount () = + (* create an implicit contract *) + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let account = Account.new_account () in + let unregistered_pkh = Account.(account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + (* credit implicit contract and check balance *) + Op.transaction (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* empty implicit contract and check balance *) + Op.transaction (I i) impl_contract bootstrap amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> + (* self delegation fails *) + Op.delegation (I i) impl_contract (Some unregistered_pkh) + >>=? fun self_delegation -> + Incremental.add_operation i self_delegation >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Empty_implicit_contract pkh -> + if pkh = unregistered_pkh then true else false + | _ -> false) + +(** Implicit contract is credited with a non-zero quantity [amount] + tz, then it is delegated. The operation of debit of [amount] tz + should fail as the contract is already delegated. *) +let test_emptying_delegated_implicit_contract_fails amount () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + Context.Contract.manager (I i) bootstrap >>=? fun bootstrap_manager -> + let account = Account.new_account () in + let unregistered_pkh = Account.(account.pkh) in + let impl_contract = Contract.implicit_contract unregistered_pkh in + (* credit unregistered implicit contract and check balance *) + Op.transaction (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* delegate the contract to the bootstrap *) + Op.delegation (I i) impl_contract (Some bootstrap_manager.pkh) + >>=? fun delegation -> + Incremental.add_operation i delegation >>=? fun i -> + (* empty implicit contract and expect error since the contract is delegated *) + Op.transaction (I i) impl_contract bootstrap amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Empty_implicit_delegated_contract _ -> true + | _ -> false) + +(* Part B. + - Valid registration: + - Credit implicit contract with some ꜩ + verification of balance + - Self delegation + verification + - Empty contract + verification of balance + verification of not being erased / self-delegation + - Create delegator implicit contract w first implicit contract as delegate + verification of delegation. *) + +(** Initialized account is credited of [amount] tz, then + self-delegated. *) +let test_valid_delegate_registration_init_delegation_credit amount () = + (* create an implicit contract *) + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let delegate_account = Account.new_account () in + let delegate_pkh = Account.(delegate_account.pkh) in + let impl_contract = Contract.implicit_contract delegate_pkh in + (* credit > 0ꜩ + check balance *) + Op.transaction (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* self delegation + verification *) + Op.delegation (I i) impl_contract (Some delegate_pkh) + >>=? fun self_delegation -> + Incremental.add_operation i self_delegation >>=? fun i -> + Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> + Assert.equal_pkh ~loc:__LOC__ delegate delegate_pkh >>=? fun _ -> + (* create an implicit contract with no delegate *) + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let delegator = Contract.implicit_contract unregistered_pkh in + Op.transaction ~fee:Tez.zero (I i) bootstrap delegator Tez.one + >>=? fun credit_contract -> + Incremental.add_operation i credit_contract >>=? fun i -> + (* check no delegate for delegator contract *) + Context.Contract.delegate (I i) delegator >>= fun err -> + Assert.error ~loc:__LOC__ err (function + | RPC_context.Not_found _ -> true + | _ -> false) + >>=? fun _ -> + (* delegation to the newly registered key *) + Op.delegation (I i) delegator (Some delegate_account.pkh) + >>=? fun delegation -> + Incremental.add_operation i delegation >>=? fun i -> + (* check delegation *) + Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> + Assert.equal_pkh ~loc:__LOC__ delegator_delegate delegate_pkh + +(** Create an implicit contract, credits with [amount] + tz. Self-delegates. Create another implicit contract with + bootstrap as delegate. Re-delegate it to the first implicit + contract. *) +let test_valid_delegate_registration_switch_delegation_credit amount () = + (* create an implicit contract *) + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let delegate_account = Account.new_account () in + let delegate_pkh = Account.(delegate_account.pkh) in + let impl_contract = Contract.implicit_contract delegate_pkh in + (* credit > 0ꜩ + check balance *) + Op.transaction (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* self delegation + verification *) + Op.delegation (I i) impl_contract (Some delegate_pkh) + >>=? fun self_delegation -> + Incremental.add_operation i self_delegation >>=? fun i -> + Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> + Assert.equal_pkh ~loc:__LOC__ delegate delegate_pkh >>=? fun _ -> + (* create an implicit contract with bootstrap's account as delegate *) + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let delegator = Contract.implicit_contract unregistered_pkh in + Op.transaction ~fee:Tez.zero (I i) bootstrap delegator Tez.one + >>=? fun credit_contract -> + Incremental.add_operation i credit_contract >>=? fun i -> + Context.Contract.manager (I i) bootstrap >>=? fun bootstrap_manager -> + Op.delegation (I i) delegator (Some bootstrap_manager.pkh) + >>=? fun delegation -> + Incremental.add_operation i delegation >>=? fun i -> + (* test delegate of new contract is bootstrap *) + Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> + Assert.equal_pkh ~loc:__LOC__ delegator_delegate bootstrap_manager.pkh + >>=? fun _ -> + (* delegation with newly registered key *) + Op.delegation (I i) delegator (Some delegate_account.pkh) + >>=? fun delegation -> + Incremental.add_operation i delegation >>=? fun i -> + Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> + Assert.equal_pkh ~loc:__LOC__ delegator_delegate delegate_pkh + +(** Create an implicit contract. *) +let test_valid_delegate_registration_init_delegation_credit_debit amount () = + (* create an implicit contract *) + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let delegate_account = Account.new_account () in + let delegate_pkh = Account.(delegate_account.pkh) in + let impl_contract = Contract.implicit_contract delegate_pkh in + (* credit > 0ꜩ+ check balance *) + Op.transaction (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* self delegation + verification *) + Op.delegation (I i) impl_contract (Some delegate_pkh) + >>=? fun self_delegation -> + Incremental.add_operation i self_delegation >>=? fun i -> + Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> + Assert.equal_pkh ~loc:__LOC__ delegate_pkh delegate >>=? fun _ -> + (* empty implicit contracts are usually deleted but they are kept if + they were registered as delegates. we empty the contract in + order to verify this. *) + Op.transaction (I i) impl_contract bootstrap amount >>=? fun empty_contract -> + Incremental.add_operation i empty_contract >>=? fun i -> + (* impl_contract is empty *) + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> + (* verify self-delegation after contract is emptied *) + Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> + Assert.equal_pkh ~loc:__LOC__ delegate_pkh delegate >>=? fun _ -> + (* create an implicit contract with no delegate *) + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let delegator = Contract.implicit_contract unregistered_pkh in + Op.transaction ~fee:Tez.zero (I i) bootstrap delegator Tez.one + >>=? fun credit_contract -> + Incremental.add_operation i credit_contract >>=? fun i -> + (* check no delegate for delegator contract *) + Context.Contract.delegate (I i) delegator >>= fun err -> + Assert.error ~loc:__LOC__ err (function + | RPC_context.Not_found _ -> true + | _ -> false) + >>=? fun _ -> + (* delegation to the newly registered key *) + Op.delegation (I i) delegator (Some delegate_account.pkh) + >>=? fun delegation -> + Incremental.add_operation i delegation >>=? fun i -> + (* check delegation *) + Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> + Assert.equal_pkh ~loc:__LOC__ delegator_delegate delegate_pkh + +(** A created implicit contract is credited with [amount] tz, then is + self-delegated. It is emptied (fund back into bootstrap), and + should remain existing (as registered as delegate). Another created + implicit contract is delegated to bootstrap, then should be able to + be re-delegated to the latter contract. *) +let test_valid_delegate_registration_switch_delegation_credit_debit amount () = + (* create an implicit contract *) + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let delegate_account = Account.new_account () in + let delegate_pkh = Account.(delegate_account.pkh) in + let impl_contract = Contract.implicit_contract delegate_pkh in + (* credit > 0ꜩ + check balance *) + Op.transaction (I i) bootstrap impl_contract amount + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract amount >>=? fun _ -> + (* self delegation + verification *) + Op.delegation (I i) impl_contract (Some delegate_pkh) + >>=? fun self_delegation -> + Incremental.add_operation i self_delegation >>=? fun i -> + Context.Contract.delegate (I i) impl_contract >>=? fun delegate -> + Assert.equal_pkh ~loc:__LOC__ delegate_pkh delegate >>=? fun _ -> + (* empty implicit contracts are usually deleted but they are kept if + they were registered as delegates. we empty the contract in + order to verify this. *) + Op.transaction (I i) impl_contract bootstrap amount >>=? fun empty_contract -> + Incremental.add_operation i empty_contract >>=? fun i -> + (* impl_contract is empty *) + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> + (* create an implicit contract with bootstrap's account as delegate *) + let unregistered_account = Account.new_account () in + let unregistered_pkh = Account.(unregistered_account.pkh) in + let delegator = Contract.implicit_contract unregistered_pkh in + Op.transaction ~fee:Tez.zero (I i) bootstrap delegator Tez.one + >>=? fun credit_contract -> + Incremental.add_operation i credit_contract >>=? fun i -> + Context.Contract.manager (I i) bootstrap >>=? fun bootstrap_manager -> + Op.delegation (I i) delegator (Some bootstrap_manager.pkh) + >>=? fun delegation -> + Incremental.add_operation i delegation >>=? fun i -> + (* test delegate of new contract is bootstrap *) + Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> + Assert.equal_pkh ~loc:__LOC__ delegator_delegate bootstrap_manager.pkh + >>=? fun _ -> + (* delegation with newly registered key *) + Op.delegation (I i) delegator (Some delegate_account.pkh) + >>=? fun delegation -> + Incremental.add_operation i delegation >>=? fun i -> + Context.Contract.delegate (I i) delegator >>=? fun delegator_delegate -> + Assert.equal_pkh ~loc:__LOC__ delegator_delegate delegate_pkh + +(* Part C. + A second self-delegation should raise an [Active_delegate] error. *) + +(** Second self-delegation should fail with implicit contract with + some credit. *) +let test_double_registration () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let account = Account.new_account () in + let pkh = Account.(account.pkh) in + let impl_contract = Contract.implicit_contract pkh in + (* credit 1μꜩ+ check balance *) + Op.transaction (I i) bootstrap impl_contract Tez.one_mutez + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.one_mutez >>=? fun _ -> + (* self-delegation *) + Op.delegation (I i) impl_contract (Some pkh) >>=? fun self_delegation -> + Incremental.add_operation i self_delegation >>=? fun i -> + (* second self-delegation *) + Op.delegation (I i) impl_contract (Some pkh) >>=? fun second_registration -> + Incremental.add_operation i second_registration >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Delegate_storage.Active_delegate -> true + | _ -> false) + +(** Second self-delegation should fail with implicit contract emptied + after first self-delegation. *) +let test_double_registration_when_empty () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let account = Account.new_account () in + let pkh = Account.(account.pkh) in + let impl_contract = Contract.implicit_contract pkh in + (* credit 1μꜩ+ check balance *) + Op.transaction (I i) bootstrap impl_contract Tez.one_mutez + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.one_mutez >>=? fun _ -> + (* self delegation *) + Op.delegation (I i) impl_contract (Some pkh) >>=? fun self_delegation -> + Incremental.add_operation i self_delegation >>=? fun i -> + (* empty the delegate account *) + Op.transaction (I i) impl_contract bootstrap Tez.one_mutez + >>=? fun empty_contract -> + Incremental.add_operation i empty_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> + (* second self-delegation *) + Op.delegation (I i) impl_contract (Some pkh) >>=? fun second_registration -> + Incremental.add_operation i second_registration >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Delegate_storage.Active_delegate -> true + | _ -> false) + +(** Second self-delegation should fail with implicit contract emptied + then credited back after first self-delegation. *) +let test_double_registration_when_recredited () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let account = Account.new_account () in + let pkh = Account.(account.pkh) in + let impl_contract = Contract.implicit_contract pkh in + (* credit 1μꜩ+ check balance *) + Op.transaction (I i) bootstrap impl_contract Tez.one_mutez + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.one_mutez >>=? fun _ -> + (* self delegation *) + Op.delegation (I i) impl_contract (Some pkh) >>=? fun self_delegation -> + Incremental.add_operation i self_delegation >>=? fun i -> + (* empty the delegate account *) + Op.transaction (I i) impl_contract bootstrap Tez.one_mutez + >>=? fun empty_contract -> + Incremental.add_operation i empty_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.zero >>=? fun _ -> + (* credit 1μꜩ+ check balance *) + Op.transaction (I i) bootstrap impl_contract Tez.one_mutez + >>=? fun create_contract -> + Incremental.add_operation i create_contract >>=? fun i -> + Assert.balance_is ~loc:__LOC__ (I i) impl_contract Tez.one_mutez >>=? fun _ -> + (* second self-delegation *) + Op.delegation (I i) impl_contract (Some pkh) >>=? fun second_registration -> + Incremental.add_operation i second_registration >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Delegate_storage.Active_delegate -> true + | _ -> false) + +(** Self-delegation on unrevealed contract. *) +let test_unregistered_and_unrevealed_self_delegate_key_init_delegation ~fee () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let {Account.pkh; _} = Account.new_account () in + let {Account.pkh = delegate_pkh; _} = Account.new_account () in + let contract = Alpha_context.Contract.implicit_contract pkh in + Op.transaction (I i) bootstrap contract (of_int 10) >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Op.delegation ~fee (I i) contract (Some delegate_pkh) >>=? fun op -> + Context.Contract.balance (I i) contract >>=? fun balance -> + if fee > balance then + Incremental.add_operation i op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* origination did not proceed; fee has been debited *) + Incremental.add_operation + ~expect_failure:(expect_unregistered_key delegate_pkh) + i + op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) contract balance fee + +(** Self-delegation on revealed but not registered contract. *) +let test_unregistered_and_revealed_self_delegate_key_init_delegation ~fee () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let {Account.pkh; pk; _} = Account.new_account () in + let {Account.pkh = delegate_pkh; _} = Account.new_account () in + let contract = Alpha_context.Contract.implicit_contract pkh in + Op.transaction (I i) bootstrap contract (of_int 10) >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Op.revelation (I i) pk >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Op.delegation ~fee (I i) contract (Some delegate_pkh) >>=? fun op -> + Context.Contract.balance (I i) contract >>=? fun balance -> + if fee > balance then + Incremental.add_operation i op >>= fun err -> + Assert.proto_error ~loc:__LOC__ err (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + else + (* origination did not proceed; fee has been debited *) + Incremental.add_operation + ~expect_failure:(expect_unregistered_key delegate_pkh) + i + op + >>=? fun i -> + Assert.balance_was_debited ~loc:__LOC__ (I i) contract balance fee + +(** Self-delegation on revealed and registered contract. *) +let test_registered_self_delegate_key_init_delegation () = + Context.init 1 >>=? fun (b, bootstrap_contracts) -> + Incremental.begin_construction b >>=? fun i -> + let bootstrap = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bootstrap_contracts + in + let {Account.pkh; _} = Account.new_account () in + let {Account.pkh = delegate_pkh; pk = delegate_pk; _} = + Account.new_account () + in + let contract = Alpha_context.Contract.implicit_contract pkh in + let delegate_contract = + Alpha_context.Contract.implicit_contract delegate_pkh + in + Op.transaction (I i) bootstrap contract (of_int 10) >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Op.transaction (I i) bootstrap delegate_contract (of_int 1) >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Op.revelation (I i) delegate_pk >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Op.delegation (I i) delegate_contract (Some delegate_pkh) >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Op.delegation (I i) contract (Some delegate_pkh) >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Context.Contract.delegate (I i) contract >>=? fun delegate -> + Assert.equal_pkh ~loc:__LOC__ delegate delegate_pkh >>=? fun () -> return_unit + +let tests_delegate_registration = + [ + (*** unregistered delegate key: no self-delegation ***) + (* no token transfer, no self-delegation *) + Tztest.tztest + "unregistered delegate key (origination, small fee)" + `Quick + (test_unregistered_delegate_key_init_origination ~fee:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key (origination, edge case fee)" + `Quick + (test_unregistered_delegate_key_init_origination ~fee:(of_int 3_999_488)); + Tztest.tztest + "unregistered delegate key (origination, large fee)" + `Quick + (test_unregistered_delegate_key_init_origination ~fee:(of_int 10_000_000)); + Tztest.tztest + "unregistered delegate key (init with delegation, small fee)" + `Quick + (test_unregistered_delegate_key_init_delegation ~fee:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key (init with delegation, max fee)" + `Quick + (test_unregistered_delegate_key_init_delegation ~fee:max_tez); + Tztest.tztest + "unregistered delegate key (switch with delegation, small fee)" + `Quick + (test_unregistered_delegate_key_switch_delegation ~fee:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key (switch with delegation, max fee)" + `Quick + (test_unregistered_delegate_key_switch_delegation ~fee:max_tez); + (* credit/debit 1μꜩ, no self-delegation *) + Tztest.tztest + "unregistered delegate key - credit/debit 1μꜩ (origination, small fee)" + `Quick + (test_unregistered_delegate_key_init_origination_credit_debit + ~fee:Tez.one_mutez + ~amount:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key - credit/debit 1μꜩ (origination, large fee)" + `Quick + (test_unregistered_delegate_key_init_origination_credit_debit + ~fee:max_tez + ~amount:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key - credit/debit 1μꜩ (init with delegation, \ + small fee)" + `Quick + (test_unregistered_delegate_key_init_delegation_credit_debit + ~amount:Tez.one_mutez + ~fee:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key - credit/debit 1μꜩ (init with delegation, \ + large fee)" + `Quick + (test_unregistered_delegate_key_init_delegation_credit_debit + ~amount:Tez.one_mutez + ~fee:max_tez); + Tztest.tztest + "unregistered delegate key - credit/debit 1μꜩ (switch with \ + delegation, small fee)" + `Quick + (test_unregistered_delegate_key_switch_delegation_credit_debit + ~amount:Tez.one_mutez + ~fee:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key - credit/debit 1μꜩ (switch with \ + delegation, large fee)" + `Quick + (test_unregistered_delegate_key_switch_delegation_credit_debit + ~amount:Tez.one_mutez + ~fee:max_tez); + (* credit 1μꜩ, no self-delegation *) + Tztest.tztest + "unregistered delegate key - credit 1μꜩ (origination, small fee)" + `Quick + (test_unregistered_delegate_key_init_origination_credit + ~fee:Tez.one_mutez + ~amount:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key - credit 1μꜩ (origination, edge case fee)" + `Quick + (test_unregistered_delegate_key_init_origination_credit + ~fee:(of_int 3_999_488) + ~amount:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key - credit 1μꜩ (origination, large fee)" + `Quick + (test_unregistered_delegate_key_init_origination_credit + ~fee:(of_int 10_000_000) + ~amount:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key - credit 1μꜩ (init with delegation, small \ + fee)" + `Quick + (test_unregistered_delegate_key_init_delegation_credit + ~amount:Tez.one_mutez + ~fee:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key - credit 1μꜩ (init with delegation, large \ + fee)" + `Quick + (test_unregistered_delegate_key_init_delegation_credit + ~amount:Tez.one_mutez + ~fee:max_tez); + Tztest.tztest + "unregistered delegate key - credit 1μꜩ (switch with delegation, \ + small fee)" + `Quick + (test_unregistered_delegate_key_switch_delegation_credit + ~amount:Tez.one_mutez + ~fee:Tez.one_mutez); + Tztest.tztest + "unregistered delegate key - credit 1μꜩ (switch with delegation, \ + large fee)" + `Quick + (test_unregistered_delegate_key_switch_delegation_credit + ~amount:Tez.one_mutez + ~fee:max_tez); + (* self delegation on unrevealed and unregistered contract *) + Tztest.tztest + "unregistered and unrevealed self-delegation (small fee)" + `Quick + (test_unregistered_and_unrevealed_self_delegate_key_init_delegation + ~fee:Tez.one_mutez); + Tztest.tztest + "unregistered and unrevealed self-delegation (large fee)" + `Quick + (test_unregistered_and_unrevealed_self_delegate_key_init_delegation + ~fee:max_tez); + (* self delegation on unregistered contract *) + Tztest.tztest + "unregistered and revealed self-delegation (small fee)" + `Quick + (test_unregistered_and_revealed_self_delegate_key_init_delegation + ~fee:Tez.one_mutez); + Tztest.tztest + "unregistered and revealed self-delegation large fee)" + `Quick + (test_unregistered_and_revealed_self_delegate_key_init_delegation + ~fee:max_tez); + (* self delegation on registered contract *) + Tztest.tztest + "registered and revealed self-delegation" + `Quick + test_registered_self_delegate_key_init_delegation; + (*** unregistered delegate key: failed self-delegation ***) + (* no token transfer, self-delegation *) + Tztest.tztest + "failed self-delegation: no transaction" + `Quick + test_failed_self_delegation_no_transaction; + (* credit 1μtz, debit 1μtz, self-delegation *) + Tztest.tztest + "failed self-delegation: credit & debit 1μꜩ" + `Quick + (test_failed_self_delegation_emptied_implicit_contract Tez.one_mutez); + (* credit 1μtz, delegate, debit 1μtz *) + Tztest.tztest + "empty delegated contract is not deleted: credit 1μꜩ, delegate & \ + debit 1μꜩ" + `Quick + (test_emptying_delegated_implicit_contract_fails Tez.one_mutez); + (*** valid registration ***) + (* valid registration: credit 1 μꜩ, self delegation *) + Tztest.tztest + "valid delegate registration: credit 1μꜩ, self delegation (init with \ + delegation)" + `Quick + (test_valid_delegate_registration_init_delegation_credit Tez.one_mutez); + Tztest.tztest + "valid delegate registration: credit 1μꜩ, self delegation (switch \ + with delegation)" + `Quick + (test_valid_delegate_registration_switch_delegation_credit Tez.one_mutez); + (* valid registration: credit 1 μꜩ, self delegation, debit 1μꜩ *) + Tztest.tztest + "valid delegate registration: credit 1μꜩ, self delegation, debit \ + 1μꜩ (init with delegation)" + `Quick + (test_valid_delegate_registration_init_delegation_credit_debit + Tez.one_mutez); + Tztest.tztest + "valid delegate registration: credit 1μꜩ, self delegation, debit \ + 1μꜩ (switch with delegation)" + `Quick + (test_valid_delegate_registration_switch_delegation_credit_debit + Tez.one_mutez); + (*** double registration ***) + Tztest.tztest "double registration" `Quick test_double_registration; + Tztest.tztest + "double registration when delegate account is emptied" + `Quick + test_double_registration_when_empty; + Tztest.tztest + "double registration when delegate account is emptied and then recredited" + `Quick + test_double_registration_when_recredited; + ] + +(******************************************************************************) +(* Main *) +(******************************************************************************) + +let tests = tests_bootstrap_contracts @ tests_delegate_registration diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_double_baking.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_double_baking.ml new file mode 100644 index 000000000000..9a6bdf1b3691 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_double_baking.ml @@ -0,0 +1,365 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (double baking) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^double baking$" + Subject: A double baking evidence operation may be injected when it has + been observed that a baker baked two different blocks at the + same level and same round. +*) + +open Protocol +open Alpha_context + +(****************************************************************) +(* Utility functions *) +(****************************************************************) + +let get_hd_hd = function x :: y :: _ -> (x, y) | _ -> assert false + +let get_first_different_baker baker bakers = + WithExceptions.Option.get ~loc:__LOC__ + @@ List.find + (fun baker' -> Signature.Public_key_hash.( <> ) baker baker') + bakers + +let get_first_different_bakers ctxt = + Context.get_bakers ctxt >|=? function + | [] | [_] -> assert false + | baker_1 :: other_bakers -> + (baker_1, get_first_different_baker baker_1 other_bakers) + +let get_baker_different_from_baker ctxt baker = + Context.get_bakers + ~filter:(fun x -> not (Signature.Public_key_hash.equal x.delegate baker)) + ctxt + >>=? fun bakers -> + return (WithExceptions.Option.get ~loc:__LOC__ @@ List.hd bakers) + +let get_first_different_endorsers ctxt = + Context.get_endorsers ctxt >|=? fun endorsers -> get_hd_hd endorsers + +(** Bake two block at the same level using the same policy (i.e. same + baker). *) +let block_fork ?policy contracts b = + let (contract_a, contract_b) = get_hd_hd contracts in + Op.transaction (B b) contract_a contract_b Alpha_context.Tez.one_cent + >>=? fun operation -> + Block.bake ?policy ~operation b >>=? fun blk_a -> + Block.bake ?policy b >|=? fun blk_b -> (blk_a, blk_b) + +let order_block_hashes ~correct_order bh1 bh2 = + let hash1 = Block_header.hash bh1 in + let hash2 = Block_header.hash bh2 in + let c = Block_hash.compare hash1 hash2 in + if correct_order then if c < 0 then (bh1, bh2) else (bh2, bh1) + else if c < 0 then (bh2, bh1) + else (bh1, bh2) + +let double_baking ctxt ?(correct_order = true) bh1 bh2 = + let (bh1, bh2) = order_block_hashes ~correct_order bh1 bh2 in + Op.double_baking ctxt bh1 bh2 + +(****************************************************************) +(* Tests *) +(****************************************************************) + +(** Simple scenario where two blocks are baked by a same baker and + exposed by a double baking evidence operation. *) +let test_valid_double_baking_evidence () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, contracts) -> + Context.get_constants (B genesis) + >>=? fun Constants.{parametric = {double_baking_punishment; _}; _} -> + get_first_different_bakers (B genesis) >>=? fun (baker1, baker2) -> + block_fork ~policy:(By_account baker1) contracts genesis + >>=? fun (blk_a, blk_b) -> + double_baking (B blk_a) blk_a.header blk_b.header |> fun operation -> + Block.bake ~policy:(By_account baker2) ~operation blk_a >>=? fun blk_final -> + (* Check that the frozen deposits are slashed *) + Context.Delegate.current_frozen_deposits (B blk_a) baker1 + >>=? fun frozen_deposits_before -> + Context.Delegate.current_frozen_deposits (B blk_final) baker1 + >>=? fun frozen_deposits_after -> + let slashed_amount = + Test_tez.(frozen_deposits_before -! frozen_deposits_after) + in + Assert.equal_tez ~loc:__LOC__ slashed_amount double_baking_punishment + >>=? fun () -> + (* Check that the initial frozen deposits has not changed *) + Context.Delegate.initial_frozen_deposits (B blk_final) baker1 + >>=? fun initial_frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ initial_frozen_deposits frozen_deposits_before + +(** Test that the payload producer of the block containing a double + baking evidence (and not the block producer, if different) receives + the reward. *) +let test_payload_producer_gets_evidence_rewards () = + Context.init ~consensus_threshold:0 10 >>=? fun (genesis, contracts) -> + Context.get_constants (B genesis) + >>=? fun Constants. + { + parametric = + {double_baking_punishment; baking_reward_fixed_portion; _}; + _; + } -> + get_first_different_bakers (B genesis) >>=? fun (baker1, baker2) -> + block_fork ~policy:(By_account baker1) contracts genesis >>=? fun (b1, b2) -> + double_baking (B b1) b1.header b2.header |> fun db_evidence -> + Block.bake ~policy:(By_account baker2) ~operation:db_evidence b1 + >>=? fun b_with_evidence -> + Context.get_endorsers (B b_with_evidence) >>=? fun endorsers -> + List.map_es + (function + | {Plugin.RPC.Validators.delegate; slots; _} -> return (delegate, slots)) + endorsers + >>=? fun preendorsers -> + List.map_ep + (fun endorser -> + Op.preendorsement + ~delegate:endorser + ~endorsed_block:b_with_evidence + (B b1) + () + >|=? Operation.pack) + preendorsers + >>=? fun preendos -> + Block.bake + ~payload_round:(Some Round.zero) + ~locked_round:(Some Round.zero) + ~policy:(By_account baker1) + ~operations:(db_evidence :: preendos) + b1 + >>=? fun b' -> + (* the frozen deposits of the double-signer [baker1] are slashed *) + Context.Delegate.current_frozen_deposits (B b1) baker1 + >>=? fun frozen_deposits_before -> + Context.Delegate.current_frozen_deposits (B b') baker1 + >>=? fun frozen_deposits_after -> + let slashed_amount = + Test_tez.(frozen_deposits_before -! frozen_deposits_after) + in + Assert.equal_tez ~loc:__LOC__ slashed_amount double_baking_punishment + >>=? fun () -> + (* [baker2] included the double baking evidence in [b_with_evidence] + and so it receives the reward for the evidence included in [b'] + (besides the reward for proposing the payload). *) + Context.Delegate.full_balance (B b1) baker2 >>=? fun full_balance -> + let evidence_reward = Test_tez.(slashed_amount /! 2L) in + let expected_reward = + Test_tez.(baking_reward_fixed_portion +! evidence_reward) + in + Context.Delegate.full_balance (B b') baker2 + >>=? fun full_balance_with_rewards -> + let real_reward = Test_tez.(full_balance_with_rewards -! full_balance) in + Assert.equal_tez ~loc:__LOC__ expected_reward real_reward >>=? fun () -> + (* [baker1] did not produce the payload, it does not receive the reward for the + evidence *) + Context.Delegate.full_balance (B b1) baker1 >>=? fun full_balance_at_b1 -> + Context.Delegate.full_balance (B b') baker1 >>=? fun full_balance_at_b' -> + Assert.equal_tez + ~loc:__LOC__ + full_balance_at_b' + Test_tez.(full_balance_at_b1 -! double_baking_punishment) + +(****************************************************************) +(* The following test scenarios are supposed to raise errors. *) +(****************************************************************) + +(** Check that a double baking operation fails if it exposes the same two + blocks. *) +let test_same_blocks () = + Context.init 2 >>=? fun (b, _contracts) -> + Block.bake b >>=? fun ba -> + double_baking (B ba) ba.header ba.header |> fun operation -> + Block.bake ~operation ba >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Invalid_double_baking_evidence _ -> true + | _ -> false) + >>=? fun () -> return_unit + +(** Check that an double baking operation that is invalid due to + incorrect ordering of the block headers fails. *) +let test_incorrect_order () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, contracts) -> + block_fork ~policy:(By_round 0) contracts genesis >>=? fun (blk_a, blk_b) -> + double_baking (B genesis) ~correct_order:false blk_a.header blk_b.header + |> fun operation -> + Block.bake ~operation genesis >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Invalid_double_baking_evidence _ -> true + | _ -> false) + +(** Check that a double baking operation exposing two blocks with + different levels fails. *) +let test_different_levels () = + Context.init ~consensus_threshold:0 2 >>=? fun (b, contracts) -> + block_fork ~policy:(By_round 0) contracts b >>=? fun (blk_a, blk_b) -> + Block.bake blk_b >>=? fun blk_b_2 -> + double_baking (B blk_a) blk_a.header blk_b_2.header |> fun operation -> + Block.bake ~operation blk_a >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Invalid_double_baking_evidence _ -> true + | _ -> false) + +(** Check that a double baking operation exposing two yet-to-be-baked + blocks fails. *) +let test_too_early_double_baking_evidence () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, contracts) -> + Block.bake_until_cycle_end genesis >>=? fun b -> + block_fork ~policy:(By_round 0) contracts b >>=? fun (blk_a, blk_b) -> + double_baking (B b) blk_a.header blk_b.header |> fun operation -> + Block.bake ~operation genesis >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Too_early_denunciation {kind = Block; _} -> true + | _ -> false) + +(** Check that after [max_slashing_period * blocks_per_cycle + 1] blocks -- corresponding to 2 cycles + --, it is not possible to create a double baking operation anymore. *) +let test_too_late_double_baking_evidence () = + Context.init ~consensus_threshold:0 2 >>=? fun (b, contracts) -> + Context.get_constants (B b) + >>=? fun Constants.{parametric = {max_slashing_period; _}; _} -> + block_fork ~policy:(By_round 0) contracts b >>=? fun (blk_a, blk_b) -> + Block.bake_until_n_cycle_end max_slashing_period blk_a >>=? fun blk -> + double_baking (B blk) blk_a.header blk_b.header |> fun operation -> + Block.bake ~operation blk >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Outdated_denunciation {kind = Block; _} -> true + | _ -> false) + +(** Check that before [max_slashing_period * blocks_per_cycle] blocks + -- corresponding to 2 cycles --, it is still possible to create a + double baking operation. *) +let test_just_in_time_double_baking_evidence () = + Context.init ~consensus_threshold:0 2 >>=? fun (b, contracts) -> + Context.get_constants (B b) + >>=? fun Constants.{parametric = {blocks_per_cycle; _}; _} -> + block_fork ~policy:(By_round 0) contracts b >>=? fun (blk_a, blk_b) -> + Block.bake_until_cycle_end blk_a >>=? fun blk -> + Block.bake_n Int32.(sub blocks_per_cycle 2l |> to_int) blk >>=? fun blk -> + let operation = double_baking (B blk) blk_a.header blk_b.header in + (* We include the denuncation in the previous to last block of the + cycle. *) + Block.bake ~operation blk >>=? fun _ -> return_unit + +(** Check that an invalid double baking evidence that exposes two + block baking with same level made by different bakers fails. *) +let test_different_delegates () = + Context.init 2 >>=? fun (b, _) -> + get_first_different_bakers (B b) >>=? fun (baker_1, baker_2) -> + Block.bake ~policy:(By_account baker_1) b >>=? fun blk_a -> + Block.bake ~policy:(By_account baker_2) b >>=? fun blk_b -> + double_baking (B blk_a) blk_a.header blk_b.header |> fun operation -> + Block.bake ~operation blk_a >>= fun e -> + Assert.proto_error ~loc:__LOC__ e (function + | Apply.Invalid_double_baking_evidence _ -> true + | _ -> false) + +(** This test is supposed to mimic that a block cannot be baked by one baker and + signed by another. The way it tries to show this is by using a + Double_baking_evidence operation: + - say [baker_1] bakes block blk_a so blk_a has a header with baker_1's + signature + - say we create an artificial [header_b] for a block b' with timestamp [ts] + at the same level as [blk_a], and the header is created such that it says that + b' is baked by the same [baker_1] and signed by [baker_2] + - because [header_b] says that b' is baked by [baker_0], b' has the same + round as [blk_a], which together with the fact that b' and [blk_a] have the + same level, means that double_baking is valid: we have [blk_a] and b' at the + same level and round, but with different timestamps and signed by different + bakers. + This test fails with an error stating that block is signed by the wrong + baker. *) +let test_wrong_signer () = + let header_custom_signer baker baker_2 timestamp b = + Block.Forge.forge_header ~policy:(By_account baker) ~timestamp b + >>=? fun header -> + Block.Forge.set_baker baker_2 header |> Block.Forge.sign_header + in + Context.init 2 >>=? fun (b, _) -> + get_first_different_bakers (B b) >>=? fun (baker_1, baker_2) -> + Block.bake ~policy:(By_account baker_1) b >>=? fun blk_a -> + let ts = Timestamp.of_seconds_string (Int64.to_string 10L) in + match ts with + | None -> assert false + | Some ts -> + header_custom_signer baker_1 baker_2 ts b >>=? fun header_b -> + double_baking (B blk_a) blk_a.header header_b |> fun operation -> + Block.bake ~operation blk_a >>= fun e -> + Assert.proto_error ~loc:__LOC__ e (function + | Block_header.Invalid_block_signature _ -> true + | _ -> false) + +(** an evidence can only be accepted once (this also means that the + same evidence doesn't lead to slashing the offender twice) *) +let test_double_evidence () = + Context.init ~consensus_threshold:0 3 >>=? fun (blk, contracts) -> + block_fork contracts blk >>=? fun (blk_a, blk_b) -> + Block.bake_until_cycle_end blk_a >>=? fun blk -> + double_baking (B blk) blk_a.header blk_b.header |> fun evidence -> + Block.bake ~operation:evidence blk >>=? fun blk -> + double_baking (B blk) blk_b.header blk_a.header |> fun evidence -> + Block.bake ~operation:evidence blk >>= fun e -> + Assert.proto_error ~loc:__LOC__ e (function err -> + let error_info = + Error_monad.find_info_of_error (Environment.wrap_tzerror err) + in + error_info.title = "Unrequired denunciation") + +let tests = + [ + Tztest.tztest + "valid double baking evidence" + `Quick + test_valid_double_baking_evidence; + Tztest.tztest + "payload producer receives the rewards for double baking evidence" + `Quick + test_payload_producer_gets_evidence_rewards; + (* Should fail*) + Tztest.tztest "same blocks" `Quick test_same_blocks; + Tztest.tztest "incorrect order" `Quick test_incorrect_order; + Tztest.tztest "different levels" `Quick test_different_levels; + Tztest.tztest + "too early double baking evidence" + `Quick + test_too_early_double_baking_evidence; + Tztest.tztest + "too late double baking evidence" + `Quick + test_too_late_double_baking_evidence; + Tztest.tztest + "just in time double baking evidence" + `Quick + test_just_in_time_double_baking_evidence; + Tztest.tztest "different delegates" `Quick test_different_delegates; + Tztest.tztest "wrong delegate" `Quick test_wrong_signer; + Tztest.tztest + "reject double injection of an evidence" + `Quick + test_double_evidence; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_double_endorsement.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_double_endorsement.ml new file mode 100644 index 000000000000..093a182be5fb --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_double_endorsement.ml @@ -0,0 +1,513 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (double endorsement) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^double endorsement$" + Subject: Double endorsement evidence operation may happen when an + endorser endorsed two different blocks on the same level. +*) + +open Protocol +open Alpha_context + +(****************************************************************) +(* Utility functions *) +(****************************************************************) + +let get_hd_hd = function x :: y :: _ -> (x, y) | _ -> assert false + +let get_first_different_baker baker bakers = + WithExceptions.Option.get ~loc:__LOC__ + @@ List.find + (fun baker' -> Signature.Public_key_hash.( <> ) baker baker') + bakers + +let get_first_different_bakers ctxt = + Context.get_bakers ctxt >|=? function + | [] -> assert false + | baker_1 :: other_bakers -> + (baker_1, get_first_different_baker baker_1 other_bakers) + +let get_first_different_endorsers ctxt = + Context.get_endorsers ctxt >|=? fun endorsers -> get_hd_hd endorsers + +let block_fork b = + get_first_different_bakers (B b) >>=? fun (baker_1, baker_2) -> + Block.bake ~policy:(By_account baker_1) b >>=? fun blk_a -> + Block.bake ~policy:(By_account baker_2) b >|=? fun blk_b -> (blk_a, blk_b) + +(****************************************************************) +(* Tests *) +(****************************************************************) + +let get_first_2_accounts_contracts contracts = + let ((contract1, account1), (contract2, account2)) = + match contracts with + | [a1; a2] -> + ( ( a1, + Contract.is_implicit a1 |> function + | None -> assert false + | Some pkh -> pkh ), + ( a2, + Contract.is_implicit a2 |> function + | None -> assert false + | Some pkh -> pkh ) ) + | _ -> assert false + in + ((contract1, account1), (contract2, account2)) + +let order_endorsements ~correct_order op1 op2 = + let oph1 = Operation.hash op1 in + let oph2 = Operation.hash op2 in + let c = Operation_hash.compare oph1 oph2 in + if correct_order then if c < 0 then (op1, op2) else (op2, op1) + else if c < 0 then (op2, op1) + else (op1, op2) + +let double_endorsement ctxt ?(correct_order = true) op1 op2 = + let (e1, e2) = order_endorsements ~correct_order op1 op2 in + Op.double_endorsement ctxt e1 e2 + +(** This test verifies that when a "cheater" double endorses and + doesn't have enough tokens to re-freeze of full deposit, we only + freeze what we can (i.e. the remaining balance) but we check that + another denunciation will slash 50% of the initial (expected) amount + of the deposit. *) + +(** Simple scenario where two endorsements are made from the same + delegate and exposed by a double_endorsement operation. Also verify + that punishment is operated. *) +let test_valid_double_endorsement_evidence () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> + block_fork genesis >>=? fun (blk_1, blk_2) -> + (* from blk_1 we bake blk_a and from blk_2 we bake blk_b so that + the same delegate endorses blk_a and blk_b and these 2 form + a valid double endorsement evidence; + - note that we cannot have double endorsement evidence + at the level of blk_1, blk_2 because both have as parent genesis + and so the endorsements are identical because the blocks blk_1, blk_2 + are identical. *) + Block.bake blk_1 >>=? fun blk_a -> + Block.bake blk_2 >>=? fun blk_b -> + Context.get_endorser (B blk_a) >>=? fun (delegate, _) -> + Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> + Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> + let operation = double_endorsement (B genesis) endorsement_a endorsement_b in + Context.get_bakers (B blk_a) >>=? fun bakers -> + let baker = get_first_different_baker delegate bakers in + Context.Delegate.full_balance (B blk_a) baker >>=? fun full_balance -> + Block.bake ~policy:(By_account baker) ~operation blk_a >>=? fun blk_final -> + (* Check that parts of the frozen deposits are slashed *) + Context.Delegate.current_frozen_deposits (B blk_a) delegate + >>=? fun frozen_deposits_before -> + Context.Delegate.current_frozen_deposits (B blk_final) delegate + >>=? fun frozen_deposits_after -> + Context.get_constants (B genesis) >>=? fun csts -> + let r = + csts.parametric.ratio_of_frozen_deposits_slashed_per_double_endorsement + in + let expected_frozen_deposits_after = + Test_tez.( + frozen_deposits_before + *! Int64.of_int (r.denominator - r.numerator) + /! Int64.of_int r.denominator) + in + Assert.equal_tez + ~loc:__LOC__ + expected_frozen_deposits_after + frozen_deposits_after + >>=? fun () -> + (* Check that the initial frozen deposits has not changed *) + Context.Delegate.initial_frozen_deposits (B blk_final) delegate + >>=? fun initial_frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ initial_frozen_deposits frozen_deposits_before + >>=? fun () -> + (* Check that [baker] is rewarded with: + - baking_reward_fixed_portion for baking and, + - half of the frozen_deposits for including the evidence *) + let baking_reward = csts.parametric.baking_reward_fixed_portion in + let evidence_reward = Test_tez.(frozen_deposits_after /! 2L) in + let expected_reward = Test_tez.(baking_reward +! evidence_reward) in + Context.Delegate.full_balance (B blk_final) baker + >>=? fun full_balance_with_rewards -> + let real_reward = Test_tez.(full_balance_with_rewards -! full_balance) in + Assert.equal_tez ~loc:__LOC__ expected_reward real_reward + +(** Say a delegate double-endorses twice and say the 2 evidences are timely + included. Then the delegate can no longer bake. *) +let test_two_double_endorsement_evidences_leadsto_no_bake () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> + block_fork genesis >>=? fun (blk_1, blk_2) -> + Block.bake blk_1 >>=? fun blk_a -> + Block.bake blk_2 >>=? fun blk_b -> + Context.get_endorser (B blk_a) >>=? fun (delegate, _) -> + Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> + Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> + let operation = double_endorsement (B genesis) endorsement_a endorsement_b in + Context.get_bakers (B blk_a) >>=? fun bakers -> + let baker = get_first_different_baker delegate bakers in + Context.Delegate.full_balance (B blk_a) baker >>=? fun _full_balance -> + Block.bake ~policy:(By_account baker) ~operation blk_a + >>=? fun blk_with_evidence1 -> + block_fork blk_with_evidence1 >>=? fun (blk_30, blk_40) -> + Block.bake blk_30 >>=? fun blk_3 -> + Block.bake blk_40 >>=? fun blk_4 -> + Op.endorsement ~endorsed_block:blk_3 (B blk_30) () >>=? fun endorsement_3 -> + Op.endorsement ~endorsed_block:blk_4 (B blk_40) () >>=? fun endorsement_4 -> + let operation = + double_endorsement (B blk_with_evidence1) endorsement_3 endorsement_4 + in + Block.bake ~policy:(By_account baker) ~operation blk_3 + >>=? fun blk_with_evidence2 -> + (* Check that all the frozen deposits are slashed *) + Context.Delegate.current_frozen_deposits (B blk_with_evidence2) delegate + >>=? fun frozen_deposits_after -> + Assert.equal_tez ~loc:__LOC__ Tez.zero frozen_deposits_after >>=? fun () -> + Block.bake ~policy:(By_account delegate) blk_with_evidence2 >>= fun b -> + (* a delegate with 0 frozen deposits cannot bake *) + Assert.proto_error ~loc:__LOC__ b (function err -> + let error_info = + Error_monad.find_info_of_error (Environment.wrap_tzerror err) + in + error_info.title = "Zero frozen deposits") + +(****************************************************************) +(* The following test scenarios are supposed to raise errors. *) +(****************************************************************) + +(** Check that an invalid double endorsement operation that exposes a + valid endorsement fails. *) +let test_invalid_double_endorsement () = + Context.init ~consensus_threshold:0 10 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b -> + Op.endorsement ~endorsed_block:b (B genesis) () >>=? fun endorsement -> + Block.bake ~operation:(Operation.pack endorsement) b >>=? fun b -> + Op.double_endorsement (B b) endorsement endorsement |> fun operation -> + Block.bake ~operation b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Invalid_denunciation Endorsement -> true + | _ -> false) + +(** Check that an double endorsement operation that is invalid due to + incorrect ordering of the endorsements fails. *) +let test_invalid_double_endorsement_variant () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> + Block.bake_until_cycle_end genesis >>=? fun b -> + block_fork b >>=? fun (blk_1, blk_2) -> + Block.bake blk_1 >>=? fun blk_a -> + Block.bake blk_2 >>=? fun blk_b -> + Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> + Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> + double_endorsement + (B genesis) + ~correct_order:false + endorsement_a + endorsement_b + |> fun operation -> + Block.bake ~operation genesis >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Invalid_denunciation Endorsement -> true + | _ -> false) + +(** Check that a future-cycle double endorsement fails. *) +let test_too_early_double_endorsement_evidence () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> + Block.bake_until_cycle_end genesis >>=? fun b -> + block_fork b >>=? fun (blk_1, blk_2) -> + Block.bake blk_1 >>=? fun blk_a -> + Block.bake blk_2 >>=? fun blk_b -> + Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> + Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> + double_endorsement (B genesis) endorsement_a endorsement_b |> fun operation -> + Block.bake ~operation genesis >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Too_early_denunciation {kind = Endorsement; _} -> true + | _ -> false) + +(** Check that after [max_slashing_period * blocks_per_cycle + 1], it is not possible + to create a double_endorsement anymore. *) +let test_too_late_double_endorsement_evidence () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> + Context.get_constants (B genesis) + >>=? fun Constants. + {parametric = {max_slashing_period; blocks_per_cycle; _}; _} -> + block_fork genesis >>=? fun (blk_1, blk_2) -> + Block.bake blk_1 >>=? fun blk_a -> + Block.bake blk_2 >>=? fun blk_b -> + Op.endorsement ~endorsed_block:blk_a (B blk_1) () >>=? fun endorsement_a -> + Op.endorsement ~endorsed_block:blk_b (B blk_2) () >>=? fun endorsement_b -> + Block.bake_n ((max_slashing_period * Int32.to_int blocks_per_cycle) + 1) blk_a + >>=? fun blk -> + double_endorsement (B blk) endorsement_a endorsement_b |> fun operation -> + Block.bake ~operation blk >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Outdated_denunciation {kind = Endorsement; _} -> true + | _ -> false) + +(** Check that an invalid double endorsement evidence that exposes two + endorsements made by two different endorsers fails. *) +let test_different_delegates () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun genesis -> + block_fork genesis >>=? fun (blk_1, blk_2) -> + Block.bake blk_1 >>=? fun blk_a -> + Block.bake blk_2 >>=? fun blk_b -> + Context.get_endorser (B blk_a) >>=? fun (endorser_a, a_slots) -> + get_first_different_endorsers (B blk_b) + >>=? fun (endorser_b1c, endorser_b2c) -> + let (endorser_b, b_slots) = + if Signature.Public_key_hash.( = ) endorser_a endorser_b1c.delegate then + (endorser_b2c.delegate, endorser_b2c.slots) + else (endorser_b1c.delegate, endorser_b1c.slots) + in + Op.endorsement + ~delegate:(endorser_a, a_slots) + ~endorsed_block:blk_a + (B blk_1) + () + >>=? fun e_a -> + Op.endorsement + ~delegate:(endorser_b, b_slots) + ~endorsed_block:blk_b + (B blk_2) + () + >>=? fun e_b -> + Block.bake ~operation:(Operation.pack e_b) blk_b >>=? fun _ -> + double_endorsement (B blk_b) e_a e_b |> fun operation -> + Block.bake ~operation blk_b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Inconsistent_denunciation {kind = Endorsement; _} -> true + | _ -> false) + +(** Check that a double endorsement evidence that exposes a ill-formed + endorsement fails. *) +let test_wrong_delegate () = + Context.init ~consensus_threshold:0 2 >>=? fun (genesis, _contracts) -> + block_fork genesis >>=? fun (blk_1, blk_2) -> + Block.bake blk_1 >>=? fun blk_a -> + Block.bake blk_2 >>=? fun blk_b -> + Context.get_endorser (B blk_a) >>=? fun (endorser_a, a_slots) -> + Op.endorsement + ~delegate:(endorser_a, a_slots) + ~endorsed_block:blk_a + (B blk_1) + () + >>=? fun endorsement_a -> + Context.get_endorser_n (B blk_b) 0 >>=? fun (endorser0, slots0) -> + Context.get_endorser_n (B blk_b) 1 >>=? fun (endorser1, slots1) -> + let (endorser_b, b_slots) = + if Signature.Public_key_hash.equal endorser_a endorser0 then + (endorser1, slots1) + else (endorser0, slots0) + in + Op.endorsement + ~delegate:(endorser_b, b_slots) + ~endorsed_block:blk_b + (B blk_2) + () + >>=? fun endorsement_b -> + double_endorsement (B blk_b) endorsement_a endorsement_b |> fun operation -> + Block.bake ~operation blk_b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Inconsistent_denunciation {kind = Endorsement; _} -> true + | _ -> false) + +let test_freeze_more_with_low_balance = + let get_endorsing_slots_for_account ctxt account = + (* Get the slots of the given account in the given context. *) + Context.get_endorsers ctxt >>=? function + | [d1; d2] -> + return + (if Signature.Public_key_hash.equal account d1.delegate then d1 + else if Signature.Public_key_hash.equal account d2.delegate then d2 + else assert false) + .slots + | _ -> assert false + (* there are exactly two endorsers for this test. *) + in + let double_endorse_and_punish b2 account1 = + (* Bake a block on top of [b2] that includes a double-endorsement + denunciation of [account1]. *) + block_fork b2 >>=? fun (blk_d1, blk_d2) -> + Block.bake ~policy:(Block.By_account account1) blk_d1 >>=? fun blk_a -> + Block.bake ~policy:(Block.By_account account1) blk_d2 >>=? fun blk_b -> + get_endorsing_slots_for_account (B blk_a) account1 >>=? fun slots_a -> + Op.endorsement + ~delegate:(account1, slots_a) + ~endorsed_block:blk_a + (B blk_d1) + () + >>=? fun end_a -> + get_endorsing_slots_for_account (B blk_b) account1 >>=? fun slots_b -> + Op.endorsement + ~delegate:(account1, slots_b) + ~endorsed_block:blk_b + (B blk_d2) + () + >>=? fun end_b -> + let denunciation = double_endorsement (B b2) end_a end_b in + Block.bake ~policy:(Excluding [account1]) b2 ~operations:[denunciation] + in + let check_unique_endorser b account2 = + Context.get_endorsers (B b) >>=? function + | [{delegate; _}] when Signature.Public_key_hash.equal account2 delegate -> + return_unit + | _ -> failwith "We are supposed to only have account2 as endorser." + in + fun () -> + let constants = + { + Default_parameters.constants_test with + endorsing_reward_per_slot = Tez.zero; + baking_reward_bonus_per_slot = Tez.zero; + baking_reward_fixed_portion = Tez.zero; + consensus_threshold = 0; + origination_size = 0; + preserved_cycles = 5; + ratio_of_frozen_deposits_slashed_per_double_endorsement = + (* enforce that ratio is 50% is the test's params. *) + {numerator = 1; denominator = 2}; + } + in + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((_contract1, account1), (_contract2, account2)) = + get_first_2_accounts_contracts contracts + in + (* we empty the available balance of [account1]. *) + Context.Delegate.info (B genesis) account1 >>=? fun info1 -> + Op.transaction + (B genesis) + (Contract.implicit_contract account1) + (Contract.implicit_contract account2) + Test_tez.(info1.full_balance -! info1.frozen_deposits) + >>=? fun op -> + Block.bake ~policy:(Block.By_account account2) genesis ~operations:[op] + >>=? fun b2 -> + Context.Delegate.info (B b2) account1 >>=? fun info2 -> + (* after block [b2], the spendable balance of [account1] is 0tz. So, given + that we have the invariant full_balance = spendable balance + + frozen_deposits, in this particular case, full_balance = frozen_deposits + for [account1], and the frozen_deposits didn't change since genesis. *) + Assert.equal_tez ~loc:__LOC__ info2.full_balance info2.frozen_deposits + >>=? fun () -> + Assert.equal_tez ~loc:__LOC__ info1.frozen_deposits info2.frozen_deposits + >>=? fun () -> + double_endorse_and_punish b2 account1 >>=? fun b3 -> + (* Denunciation has happened: we check that the full balance of [account1] + is (still) equal to its deposit. *) + Context.Delegate.info (B b3) account1 >>=? fun info3 -> + Assert.equal_tez + ~loc:__LOC__ + info3.full_balance + info3.current_frozen_deposits + >>=? fun () -> + (* We also check that compared to deposits at block [b2], [account1] lost + 50% of its deposits. *) + let slash_ratio = + constants.ratio_of_frozen_deposits_slashed_per_double_endorsement + in + let expected_frozen_deposits_after = + Test_tez.( + info2.frozen_deposits + *! Int64.of_int (slash_ratio.denominator - slash_ratio.numerator) + /! Int64.of_int slash_ratio.denominator) + in + Assert.equal_tez + ~loc:__LOC__ + expected_frozen_deposits_after + info3.current_frozen_deposits + >>=? fun () -> + (* We now bake until end of cycle only with [account2]: + block of the new cycle are called cX below. *) + Block.bake_until_cycle_end b3 >>=? fun c1 -> + double_endorse_and_punish c1 account1 >>=? fun c2 -> + (* Second denunciation has happened: we check that the full balance of + [account1] reflects the slashing of 50% of the original deposit. Its + current deposits are thus 0tz. *) + Context.Delegate.info (B c2) account1 >>=? fun info4 -> + Assert.equal_tez ~loc:__LOC__ info4.full_balance Tez.zero >>=? fun () -> + Assert.equal_tez ~loc:__LOC__ info4.current_frozen_deposits Tez.zero + >>=? fun () -> + Block.bake c2 ~policy:(By_account account1) >>= fun c3 -> + (* Once the deposits dropped to 0, the baker cannot bake anymore *) + Assert.proto_error_with_info ~loc:__LOC__ c3 "Zero frozen deposits" + >>=? fun () -> + (* We bake [2 * preserved_cycles] additional cycles only with [account2]. + Because [account1] does not bake during this period, it loses its rights. + *) + Block.bake_until_n_cycle_end + ~policy:(By_account account2) + (2 * constants.preserved_cycles) + c2 + >>=? fun d1 -> + Context.Delegate.info (B d1) account1 >>=? fun info5 -> + (* [account1] is only deactivated after 1 + [2 * preserved_cycles] (see + [Delegate_activation_storage.set_active] since the last time it was + active, that is, since the first cycle. Thus the cycle at which + [account1] is deactivated is 2 + [2 * preserved_cycles] from genesis. *) + Assert.equal_bool ~loc:__LOC__ info5.deactivated false >>=? fun () -> + (* account1 is still active, but has no rights. *) + check_unique_endorser d1 account2 >>=? fun () -> + Block.bake_until_cycle_end ~policy:(By_account account2) d1 >>=? fun e1 -> + (* account1 has no rights and furthermore is no longer active. *) + check_unique_endorser e1 account2 >>=? fun () -> + Context.Delegate.info (B e1) account1 >>=? fun info6 -> + Assert.equal_bool ~loc:__LOC__ info6.deactivated true + +let tests = + [ + Tztest.tztest + "valid double endorsement evidence" + `Quick + test_valid_double_endorsement_evidence; + Tztest.tztest + "2 valid double endorsement evidences lead to not being able to bake" + `Quick + test_two_double_endorsement_evidences_leadsto_no_bake; + Tztest.tztest + "invalid double endorsement evidence" + `Quick + test_invalid_double_endorsement; + Tztest.tztest + "another invalid double endorsement evidence" + `Quick + test_invalid_double_endorsement_variant; + Tztest.tztest + "too early double endorsement evidence" + `Quick + test_too_early_double_endorsement_evidence; + Tztest.tztest + "too late double endorsement evidence" + `Quick + test_too_late_double_endorsement_evidence; + Tztest.tztest "different delegates" `Quick test_different_delegates; + Tztest.tztest "wrong delegate" `Quick test_wrong_delegate; + Tztest.tztest + "freeze available balance after slashing" + `Quick + test_freeze_more_with_low_balance; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_double_preendorsement.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_double_preendorsement.ml new file mode 100644 index 000000000000..d5e5f7a2c2b3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_double_preendorsement.ml @@ -0,0 +1,337 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (double preendorsement) in Full_construction & Application modes + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ + -- test "^double preendorsement$" + Subject: These tests target different cases for double preendorsement *) + +open Protocol +open Alpha_context + +module type MODE = sig + val name : string + + val baking_mode : Block.baking_mode +end + +module BakeWithMode (Mode : MODE) : sig + val tests : unit Alcotest_lwt.test_case trace +end = struct + let name = Mode.name + + let bake = Block.bake ~baking_mode:Mode.baking_mode + + let bake_n = Block.bake_n ~baking_mode:Mode.baking_mode + + (****************************************************************) + (* Utility functions *) + (****************************************************************) + + (** Helper function for illformed denunciations construction *) + + let pick_endorsers ctxt = + let module V = Plugin.RPC.Validators in + Context.get_endorsers ctxt >>=? function + | a :: b :: _ -> + return ((a.V.delegate, a.V.slots), (b.V.delegate, b.V.slots)) + | _ -> assert false + + let invalid_denunciation loc res = + Assert.proto_error_with_info ~loc res "Invalid denunciation" + + let malformed_double_preendorsement_denunciation + ?(include_endorsement = false) ?(block_round = 0) + ?(mk_evidence = fun ctxt p1 p2 -> Op.double_preendorsement ctxt p1 p2) + ~loc () = + Context.init ~consensus_threshold:0 10 >>=? fun (genesis, _) -> + bake genesis >>=? fun b1 -> + bake ~policy:(By_round 0) b1 >>=? fun b2_A -> + Op.endorsement ~endorsed_block:b1 (B genesis) () >>=? fun e -> + let operations = if include_endorsement then [Operation.pack e] else [] in + bake ~policy:(By_round block_round) ~operations b1 >>=? fun b2_B -> + Op.preendorsement ~endorsed_block:b2_A (B b1) () >>=? fun op1 -> + Op.preendorsement ~endorsed_block:b2_B (B b1) () >>=? fun op2 -> + let op = mk_evidence (B genesis) op1 op2 in + bake b1 ~operations:[op] >>= fun res -> invalid_denunciation loc res + + let max_slashing_period () = + Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> + Context.get_constants (B genesis) + >>=? fun {parametric = {max_slashing_period; blocks_per_cycle; _}; _} -> + return (max_slashing_period * Int32.to_int blocks_per_cycle) + + let unrequired_denunciation loc res = + Assert.proto_error_with_info ~loc res "Unrequired denunciation" + + let inconsistent_denunciation loc res = + Assert.proto_error_with_info ~loc res "Inconsistent denunciation" + + let outdated_denunciation loc res = + Assert.proto_error_with_info ~loc res "Outdated denunciation" + + let unexpected_failure loc res = + (* no error is expected *) + Assert.proto_error ~loc res (function _ -> false) + + let unexpected_success loc _ _ _ _ _ = + Alcotest.fail (loc ^ ": Test should not succeed") + + let expected_success _loc baker pred bbad (d1, _) (d2, _) = + (* same preendorsers in case denunciation succeeds*) + Assert.equal_pkh ~loc:__LOC__ d1 d2 >>=? fun () -> + Context.get_constants (B pred) + >>=? fun Constants. + { + parametric = + { + ratio_of_frozen_deposits_slashed_per_double_endorsement = r; + _; + }; + _; + } -> + (* let's bake the block on top of pred without denunciating d1 *) + bake ~policy:(By_account baker) pred >>=? fun bgood -> + (* Checking what the endorser lost *) + Context.Delegate.current_frozen_deposits (B pred) d1 + >>=? fun frozen_deposit -> + Context.Delegate.full_balance (B bgood) d1 >>=? fun bal_good -> + Context.Delegate.full_balance (B bbad) d1 >>=? fun bal_bad -> + (* the diff of the two balances in normal and in denunciation cases *) + let diff_end_bal = Test_tez.(bal_good -! bal_bad) in + (* amount lost due to denunciation *) + let lost_deposit = + Test_tez.( + frozen_deposit *! Int64.of_int r.numerator /! Int64.of_int r.denominator) + in + (* have of the lost deposts will be earned by the baker *) + let denun_reward = Test_tez.(lost_deposit /! 2L) in + (* if the baker is the endorser, he'll only loose half of the deposits *) + let expected_endo_loss = + if Signature.Public_key_hash.equal baker d1 then + Test_tez.(lost_deposit -! denun_reward) + else lost_deposit + in + Assert.equal_tez ~loc:__LOC__ expected_endo_loss diff_end_bal >>=? fun () -> + (* Checking what the baker earned (or lost) *) + Context.Delegate.full_balance (B bgood) baker >>=? fun bal_good -> + Context.Delegate.full_balance (B bbad) baker >>=? fun bal_bad -> + (* if baker = endorser, the baker's balance in the good case is better, + because half of his deposits are burnt in the bad (double-preendorsement) + situation. In case baker <> endorser, bal_bad of the baker gets half of + burnt deposit of d1, so it's higher + *) + let (high, low) = + if Signature.Public_key_hash.equal baker d1 then (bal_good, bal_bad) + else (bal_bad, bal_good) + in + let diff_baker = Test_tez.(high -! low) in + (* the baker has either earnt or lost (in case baker = d1) half of burnt + endorsement deposits *) + Assert.equal_tez ~loc:__LOC__ denun_reward diff_baker >>=? fun () -> + return_unit + + let order_preendorsements ~correct_order op1 op2 = + let oph1 = Operation.hash op1 in + let oph2 = Operation.hash op2 in + let c = Operation_hash.compare oph1 oph2 in + if correct_order then if c < 0 then (op1, op2) else (op2, op1) + else if c < 0 then (op2, op1) + else (op1, op2) + + (** Helper function for denunciations inclusion *) + let generic_double_preendorsement_denunciation ~nb_blocks_before_double + ~nb_blocks_before_denunciation + ?(test_expected_ok = fun _loc _baker _pred _bbad _d1 _d2 -> return_unit) + ?(test_expected_ko = fun _loc _res -> return_unit) + ?(pick_endorsers = + fun ctxt -> pick_endorsers ctxt >>=? fun (a, _b) -> return (a, a)) ~loc + () = + Context.init ~consensus_threshold:0 10 >>=? fun (genesis, contracts) -> + let addr = + match List.hd contracts with None -> assert false | Some e -> e + in + (* bake `nb_blocks_before_double blocks` before double preendorsing *) + bake_n nb_blocks_before_double genesis >>=? fun blk -> + (* producing two differents blocks and two preendorsements op1 and op2 *) + Op.transaction (B genesis) addr addr Tez.one_mutez >>=? fun trans -> + bake ~policy:(By_round 0) blk >>=? fun head_A -> + bake ~policy:(By_round 0) blk ~operations:[trans] >>=? fun head_B -> + pick_endorsers (B head_A) >>=? fun (d1, d2) -> + (* default: d1 = d2 *) + Op.preendorsement ~delegate:d1 ~endorsed_block:head_A (B blk) () + >>=? fun op1 -> + Op.preendorsement ~delegate:d2 ~endorsed_block:head_B (B blk) () + >>=? fun op2 -> + let (op1, op2) = order_preendorsements ~correct_order:true op1 op2 in + (* bake `nb_blocks_before_denunciation` before double preend. denunciation *) + bake_n nb_blocks_before_denunciation blk >>=? fun blk -> + let op : Operation.packed = Op.double_preendorsement (B blk) op1 op2 in + Context.get_baker (B blk) ~round:0 >>=? fun baker -> + bake ~policy:(By_account baker) blk ~operations:[op] >>= function + | Ok new_head -> + test_expected_ok loc baker blk new_head d1 d2 >>=? fun () -> + let op : Operation.packed = + Op.double_preendorsement (B new_head) op2 op1 + in + bake new_head ~operations:[op] >>= invalid_denunciation loc + >>=? fun () -> + let op : Operation.packed = + Op.double_preendorsement (B new_head) op1 op2 + in + bake new_head ~operations:[op] >>= unrequired_denunciation loc + | Error _ as res -> test_expected_ko loc res + + (****************************************************************) + (* Tests *) + (****************************************************************) + + (** Preendorsing two blocks that are structurally equal is not punished *) + let malformed_double_preendorsement_denunciation_same_payload_hash_1 () = + malformed_double_preendorsement_denunciation ~loc:__LOC__ () + + (** Preendorsing two blocks that are structurally equal up to the endorsements + they include is not punished *) + let malformed_double_preendorsement_denunciation_same_payload_hash_2 () = + malformed_double_preendorsement_denunciation + (* including an endorsement in one of the blocks doesn't change its + payload hash *) + ~include_endorsement:true + ~loc:__LOC__ + () + + (** Denunciation evidence cannot have the same operations *) + let malformed_double_preendorsement_denunciation_same_preendorsement () = + malformed_double_preendorsement_denunciation + (* exactly the same preendorsement operation => illformed *) + ~mk_evidence:(fun ctxt p1 _p2 -> Op.double_preendorsement ctxt p1 p1) + ~loc:__LOC__ + () + + (** Preendorsing two blocks with different rounds is not punished *) + let malformed_double_preendorsement_denunciation_different_rounds () = + malformed_double_preendorsement_denunciation ~loc:__LOC__ ~block_round:1 () + + (** Preendorsing two blocks by two different validators is not punished *) + let malformed_double_preendorsement_denunciation_different_validators () = + generic_double_preendorsement_denunciation + ~nb_blocks_before_double:0 + ~nb_blocks_before_denunciation:2 + ~test_expected_ok:unexpected_success + ~test_expected_ko:inconsistent_denunciation + ~pick_endorsers (* pick different endorsers *) + ~loc:__LOC__ + () + + (** Attempt a denunciation of a double-pre in the first block after genesis *) + let double_preendorsement_just_after_upgrade () = + generic_double_preendorsement_denunciation + ~nb_blocks_before_double:0 + ~nb_blocks_before_denunciation:1 + ~test_expected_ok:expected_success + ~test_expected_ko:unexpected_failure + ~loc:__LOC__ + () + + (** Denunciation of double-pre at level L is injected at level L' = max_slashing_period. + The denunciation is outdated. *) + let double_preendorsement_denunciation_during_slashing_period () = + max_slashing_period () >>=? fun max_slashing_period -> + generic_double_preendorsement_denunciation + ~nb_blocks_before_double:0 + ~nb_blocks_before_denunciation:(max_slashing_period / 2) + ~test_expected_ok:expected_success + ~test_expected_ko:unexpected_failure + ~loc:__LOC__ + () + + (** Denunciation of double-pre at level L is injected 1 block after unfreeze + delay. Too late: denunciation is outdated. *) + let double_preendorsement_denunciation_after_slashing_period () = + max_slashing_period () >>=? fun max_slashing_period -> + generic_double_preendorsement_denunciation + ~nb_blocks_before_double:0 + ~nb_blocks_before_denunciation:(max_slashing_period + 1) + ~test_expected_ok:unexpected_success + ~test_expected_ko:outdated_denunciation + ~loc:__LOC__ + () + + let my_tztest title test = + Tztest.tztest (Format.sprintf "%s: %s" name title) test + + let tests = + [ + (* illformed denunciations *) + my_tztest + "ko: malformed_double_preendorsement_denunciation_same_payload_hash_1" + `Quick + malformed_double_preendorsement_denunciation_same_payload_hash_1; + my_tztest + "ko: malformed_double_preendorsement_denunciation_same_payload_hash_2" + `Quick + malformed_double_preendorsement_denunciation_same_payload_hash_2; + my_tztest + "ko: malformed_double_preendorsement_denunciation_different_rounds" + `Quick + malformed_double_preendorsement_denunciation_different_rounds; + my_tztest + "ko: malformed_double_preendorsement_denunciation_same_preendorsement" + `Quick + malformed_double_preendorsement_denunciation_same_preendorsement; + my_tztest + "ko: malformed_double_preendorsement_denunciation_different_validators" + `Quick + malformed_double_preendorsement_denunciation_different_validators; + my_tztest + "double_preendorsement_just_after_upgrade" + `Quick + double_preendorsement_just_after_upgrade; + (* tests for unfreeze *) + my_tztest + "double_preendorsement_denunciation_during_slashing_period" + `Quick + double_preendorsement_denunciation_during_slashing_period; + my_tztest + "double_preendorsement_denunciation_after_slashing_period" + `Quick + double_preendorsement_denunciation_after_slashing_period; + ] +end + +let tests = + let module AppMode = BakeWithMode (struct + let name = "AppMode" + + let baking_mode = Block.Application + end) in + let module ConstrMode = BakeWithMode (struct + let name = "ConstrMode" + + let baking_mode = Block.Baking + end) in + AppMode.tests @ ConstrMode.tests diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_endorsement.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_endorsement.ml new file mode 100644 index 000000000000..f84560f38b49 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_endorsement.ml @@ -0,0 +1,594 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (endorsement) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^endorsement$" + Subject: Endorsing a block adds an extra layer of confidence + to the Tezos' PoS algorithm. The block endorsing + operation must be included in the following block. +*) + +open Protocol +open Alpha_context + +let init_genesis ?policy () = + Context.init ~consensus_threshold:0 5 >>=? fun (genesis, _) -> + Block.bake ?policy genesis >>=? fun b -> return (genesis, b) + +(** inject an endorsement and return the block with the endorsement and its + parent. *) +let inject_the_first_endorsement () = + init_genesis () >>=? fun (genesis, b) -> + Op.endorsement ~endorsed_block:b (B genesis) () >>=? fun op -> + Block.bake ~operations:[Operation.pack op] b >>=? fun b' -> return (b', b) + +(****************************************************************) +(* Tests *) +(****************************************************************) + +(** Apply a single endorsement from the slot 0 endorser. *) +let test_simple_endorsement () = + inject_the_first_endorsement () >>=? fun _ -> return_unit + +(****************************************************************) +(* The following test scenarios are supposed to raise errors. *) +(****************************************************************) + +(** Apply an endorsement with a negative slot. *) +let test_negative_slot () = + Context.init 5 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b -> + Context.get_endorser (B b) >>=? fun (delegate, _slots) -> + Lwt.catch + (fun () -> + Op.endorsement + ~delegate:(delegate, [Slot.of_int_do_not_use_except_for_parameters (-1)]) + ~endorsed_block:b + (B genesis) + () + >>=? fun _ -> + failwith "negative slot should not be accepted by the binary format") + (function + | Data_encoding.Binary.Write_error _ -> return_unit | e -> Lwt.fail e) + +(** Apply an endorsement with a non-normalized slot (that is, not the smallest + possible). *) +let test_non_normalized_slot () = + Context.init 5 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b -> + Context.get_endorsers (B b) >>=? fun endorsers_list -> + (* find an endorsers with more than 1 slot *) + List.find_map + (function + | {Plugin.RPC.Validators.delegate; slots; _} -> + if Compare.List_length_with.(slots > 1) then Some (delegate, slots) + else None) + endorsers_list + |> function + | None -> assert false + | Some (delegate, slots) -> + let set_slots = Slot.Set.of_list slots in + (* no duplicated slots *) + Assert.equal_int + ~loc:__LOC__ + (Slot.Set.cardinal set_slots) + (List.length slots) + >>=? fun () -> + (* the first slot should be the smallest slot *) + Assert.equal + ~loc:__LOC__ + (fun x y -> Slot.compare x y = 0) + "the first slot is not the smallest" + Slot.pp + (WithExceptions.Option.get ~loc:__LOC__ @@ List.hd slots) + (WithExceptions.Option.get ~loc:__LOC__ @@ Slot.Set.min_elt set_slots) + >>=? fun () -> + Op.endorsement + ~delegate:(delegate, List.rev slots) + ~endorsed_block:b + (B genesis) + () + >>=? fun op -> + let policy = Block.Excluding [delegate] in + Block.bake ~policy ~operations:[Operation.pack op] b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function err -> + let error_info = + Error_monad.find_info_of_error (Environment.wrap_tzerror err) + in + error_info.title = "wrong slot") + +(** Wrong endorsement predecessor : apply an endorsement with an + incorrect block predecessor. *) +let test_wrong_endorsement_predecessor () = + init_genesis () >>=? fun (genesis, b) -> + Op.endorsement ~endorsed_block:b (B genesis) ~signing_context:(B b) () + >>=? fun operation -> + let operation = Operation.pack operation in + Block.bake ~operation b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Wrong_consensus_operation_branch _ -> true + | _ -> false) + +(** Invalid_endorsement_level: apply an endorsement with an incorrect + level (i.e. the predecessor level). *) +let test_invalid_endorsement_level () = + init_genesis () >>=? fun (genesis, b) -> + Context.get_level (B genesis) >>?= fun genesis_level -> + Op.endorsement ~level:genesis_level ~endorsed_block:b (B genesis) () + >>=? fun op -> + Block.bake ~operations:[Operation.pack op] b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Wrong_level_for_consensus_operation _ -> true + | _ -> false) + +(** Duplicate endorsement : apply an endorsement that has already been applied. *) +let test_duplicate_endorsement () = + init_genesis () >>=? fun (genesis, b) -> + Incremental.begin_construction b >>=? fun inc -> + Op.endorsement ~endorsed_block:b (B genesis) () >>=? fun operation -> + let operation = Operation.pack operation in + Incremental.add_operation inc operation >>=? fun inc -> + Op.endorsement ~endorsed_block:b (B genesis) () >>=? fun operation -> + let operation = Operation.pack operation in + Incremental.add_operation inc operation >>= fun res -> + Assert.proto_error_with_info + ~loc:__LOC__ + res + "double inclusion of consensus operation" + +(** Consensus operation for future level : apply an endorsement with a level in the future *) +let test_consensus_operation_endorsement_for_future_level () = + init_genesis () >>=? fun (genesis, pred) -> + let raw_level = Raw_level.of_int32 (Int32.of_int 10) in + let level = match raw_level with Ok l -> l | Error _ -> assert false in + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:pred + ~level + ~error_title:"Consensus operation for future level" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Consensus operation for old level : apply an endorsement one level in the past *) +let test_consensus_operation_endorsement_for_predecessor_level () = + init_genesis () >>=? fun (genesis, pred) -> + let raw_level = Raw_level.of_int32 (Int32.of_int 0) in + let level = match raw_level with Ok l -> l | Error _ -> assert false in + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:pred + ~level + ~error_title:"Endorsement for previous level" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Consensus operation for old level : apply an endorsement with more than one level in the past *) +let test_consensus_operation_endorsement_for_old_level () = + init_genesis () >>=? fun (genesis, pred) -> + Block.bake genesis >>=? fun next_block -> + let raw_level = Raw_level.of_int32 (Int32.of_int 0) in + let level = match raw_level with Ok l -> l | Error _ -> assert false in + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:pred + ~level + ~error_title:"Consensus operation for old level" + ~context:(Context.B next_block) + ~construction_mode:(pred, None) + () + +(** Consensus operation for future round : apply an endorsement with a round in the future *) +let test_consensus_operation_endorsement_for_future_round () = + init_genesis () >>=? fun (genesis, pred) -> + Environment.wrap_tzresult (Round.of_int 21) >>?= fun round -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:pred + ~round + ~error_title:"Consensus operation for future round" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Consensus operation for old round : apply an endorsement with a round in the past *) +let test_consensus_operation_endorsement_for_old_round () = + init_genesis ~policy:(By_round 10) () >>=? fun (genesis, pred) -> + Environment.wrap_tzresult (Round.of_int 0) >>?= fun round -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:pred + ~round + ~error_title:"Consensus operation for old round" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Consensus operation on competing proposal : apply an endorsement on a competing proposal *) +let test_consensus_operation_endorsement_on_competing_proposal () = + init_genesis () >>=? fun (genesis, pred) -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:pred + ~block_payload_hash:Block_payload_hash.zero + ~error_title:"Consensus operation on competing proposal" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Wrong round : apply an endorsement with an incorrect round *) +let test_wrong_round () = + init_genesis () >>=? fun (genesis, b) -> + Environment.wrap_tzresult (Round.of_int 2) >>?= fun round -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:b + ~round + ~error_title:"wrong round for consensus operation" + ~context:(Context.B genesis) + () + +(** Wrong level : apply an endorsement with an incorrect level *) +let test_wrong_level () = + init_genesis () >>=? fun (genesis, b) -> + let context = Context.B genesis in + let raw_level = Raw_level.of_int32 (Int32.of_int 0) in + let level = match raw_level with Ok l -> l | Error _ -> assert false in + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:b + ~level + ~error_title:"wrong level for consensus operation" + ~context + () + +(** Wrong payload hash : apply an endorsement with an incorrect payload hash *) +let test_wrong_payload_hash () = + init_genesis () >>=? fun (genesis, b) -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:b + ~block_payload_hash:Block_payload_hash.zero + ~error_title:"wrong payload hash for consensus operation" + ~context:(Context.B genesis) + () + +let test_wrong_slot_used () = + init_genesis () >>=? fun (genesis, b) -> + Context.get_endorser (B b) >>=? fun (_, slots) -> + (match slots with + | _x :: y :: _ -> return y + | _ -> failwith "Slots size should be at least of 2 ") + >>=? fun slot -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:false + ~endorsed_block:b + ~slot + ~error_title:"wrong slot" + ~context:(Context.B genesis) + () + +(** Check that: + - a block with not enough endorsement cannot be baked; + - a block with enough endorsement is baked. *) +let test_endorsement_threshold ~sufficient_threshold () = + (* We choose a relative large number of accounts so that the probability that + any delegate has [consensus_threshold] slots is low and most delegates have + about 1 slot so we can get closer to the limit of [consensus_threshold]: we + check that a block with endorsing power [consensus_threshold - 1] won't be + baked. *) + Context.init 10 >>=? fun (genesis, _contracts) -> + Block.bake genesis >>=? fun b -> + Context.get_constants (B b) + >>=? fun {parametric = {consensus_threshold; _}; _} -> + Context.get_endorsers (B b) >>=? fun endorsers_list -> + Block.get_round b >>?= fun round -> + List.fold_left_es + (fun (counter, endos) {Plugin.RPC.Validators.delegate; slots; _} -> + let new_counter = counter + List.length slots in + if + (sufficient_threshold && counter < consensus_threshold) + || ((not sufficient_threshold) && new_counter < consensus_threshold) + then + Op.endorsement + ~round + ~delegate:(delegate, slots) + ~endorsed_block:b + (B genesis) + () + >>=? fun endo -> return (new_counter, Operation.pack endo :: endos) + else return (counter, endos)) + (0, []) + endorsers_list + >>=? fun (_, endos) -> + Block.bake ~operations:endos b >>= fun b -> + if sufficient_threshold then return_unit + else + Assert.proto_error ~loc:__LOC__ b (function err -> + let error_info = + Error_monad.find_info_of_error (Environment.wrap_tzerror err) + in + error_info.title = "Not enough endorsements") + +(** Fitness gap: this is a straightforward update from Emmy to Tenderbake, that + is, check that the level is incremented in a child block. *) +let test_fitness_gap () = + inject_the_first_endorsement () >>=? fun (b, pred_b) -> + let fitness = + match Fitness.from_raw b.header.shell.fitness with + | Ok fitness -> fitness + | _ -> assert false + in + let pred_fitness = + match Fitness.from_raw pred_b.header.shell.fitness with + | Ok fitness -> fitness + | _ -> assert false + in + let level = Fitness.level fitness in + let pred_level = Fitness.level pred_fitness in + let level_diff = + Int32.sub (Raw_level.to_int32 level) (Raw_level.to_int32 pred_level) + in + Assert.equal_int32 ~loc:__LOC__ level_diff 1l + +let test_preendorsement_endorsement_same_level () = + Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b1 -> + Incremental.begin_construction ~mempool_mode:true ~policy:(By_round 2) b1 + >>=? fun i -> + Op.endorsement ~endorsed_block:b1 (B genesis) () >>=? fun op_endo -> + let op_endo = Alpha_context.Operation.pack op_endo in + Incremental.add_operation i op_endo >>=? fun _i -> + Op.preendorsement ~endorsed_block:b1 (B genesis) () >>=? fun op_preendo -> + let op_preendo = Alpha_context.Operation.pack op_preendo in + Incremental.add_operation i op_preendo >>=? fun _i -> return () + +(** Test for endorsement injection with wrong slot in mempool mode. This + test is expected to fail *) +let test_wrong_endorsement_slot_in_mempool_mode () = + Context.init ~consensus_threshold:1 5 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b1 -> + let module V = Plugin.RPC.Validators in + (Context.get_endorsers (B b1) >>=? function + | {V.slots = _ :: non_canonical_slot :: _; _} :: _ -> + (* we didn't use min slot for the injection. It's bad !*) + return (Some non_canonical_slot) + | _ -> assert false) + >>=? fun slot -> + Op.endorsement ~endorsed_block:b1 (B genesis) ?slot () >>=? fun endo -> + let endo = Operation.pack endo in + Incremental.begin_construction ~mempool_mode:true b1 >>=? fun i -> + Incremental.add_operation i endo >>= fun res -> + Assert.proto_error_with_info ~loc:__LOC__ res "wrong slot" + +(** Endorsement for next level *) +let test_endorsement_for_next_level () = + init_genesis () >>=? fun (genesis, _) -> + Consensus_helpers.test_consensus_op_for_next + ~genesis + ~kind:`Endorsement + ~next:`Level + +(** Endorsement for next round *) +let test_endorsement_for_next_round () = + init_genesis () >>=? fun (genesis, _) -> + Consensus_helpers.test_consensus_op_for_next + ~genesis + ~kind:`Endorsement + ~next:`Round + +(** Endorsement of grandparent *) +let test_endorsement_grandparent () = + Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b_gp -> + Block.bake b_gp >>=? fun b -> + Incremental.begin_construction ~mempool_mode:true b >>=? fun i -> + (* Endorsement on grandparent *) + Op.endorsement ~endorsed_block:b_gp (B genesis) () >>=? fun op1 -> + (* Endorsement on parent *) + Op.endorsement ~endorsed_block:b (B b_gp) () >>=? fun op2 -> + let op1 = Alpha_context.Operation.pack op1 in + let op2 = Alpha_context.Operation.pack op2 in + (* Both should be accepted by the mempool *) + Incremental.add_operation i op1 >>=? fun i -> + Incremental.add_operation i op2 >>=? fun _i -> return () + +(** Double inclusion of grandparent endorsement *) +let test_double_endorsement_grandparent () = + Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b_gp -> + Block.bake b_gp >>=? fun b -> + Incremental.begin_construction ~mempool_mode:true b >>=? fun i -> + (* Endorsement on grandparent *) + Op.endorsement ~endorsed_block:b_gp (B genesis) () >>=? fun op1 -> + (* Endorsement on parent *) + Op.endorsement ~endorsed_block:b (B b_gp) () >>=? fun op2 -> + let op1 = Alpha_context.Operation.pack op1 in + let op2 = Alpha_context.Operation.pack op2 in + (* The first grand parent endorsement should be accepted by the + mempool but the second rejected. *) + Incremental.add_operation i op1 >>=? fun i -> + Incremental.add_operation i op1 >>= fun res -> + Assert.proto_error_with_info + ~loc:__LOC__ + res + "double inclusion of consensus operation" + >>=? fun () -> + Incremental.add_operation i op2 >>=? fun _i -> return () + +(** Endorsement of grandparent on same slot as parent *) +let test_endorsement_grandparent_same_slot () = + Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b_gp -> + Block.bake b_gp >>=? fun b -> + Incremental.begin_construction ~mempool_mode:true b >>=? fun i -> + (* Endorsement on parent *) + Consensus_helpers.delegate_of_first_slot (B b) >>=? fun (delegate, slot) -> + Op.endorsement ~endorsed_block:b ~delegate (B b_gp) () >>=? fun op2 -> + (* Endorsement on grandparent *) + Consensus_helpers.delegate_of_slot slot (B b_gp) >>=? fun delegate -> + Op.endorsement ~endorsed_block:b_gp ~delegate (B genesis) () >>=? fun op1 -> + let op1 = Alpha_context.Operation.pack op1 in + let op2 = Alpha_context.Operation.pack op2 in + (* Both should be accepted by the mempool *) + Incremental.add_operation i op1 >>=? fun i -> + Incremental.add_operation i op2 >>=? fun _i -> return () + +(** Endorsement of grandparent in application mode should be rejected *) +let test_endorsement_grandparent_application () = + Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b_gp -> + Block.bake b_gp >>=? fun b -> + Op.endorsement ~endorsed_block:b_gp (B genesis) () >>=? fun op -> + Block.bake ~operations:[Operation.pack op] b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Wrong_level_for_consensus_operation _ -> true + | _ -> false) + +(** Endorsement of grandparent in full construction mode should be rejected *) +let test_endorsement_grandparent_full_construction () = + Context.init ~consensus_threshold:0 1 >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b_gp -> + Block.bake b_gp >>=? fun b -> + Incremental.begin_construction b >>=? fun i -> + (* Endorsement on grandparent *) + Op.endorsement ~endorsed_block:b_gp (B genesis) () >>=? fun op1 -> + let op1 = Alpha_context.Operation.pack op1 in + Incremental.add_operation i op1 >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Wrong_level_for_consensus_operation _ -> true + | _ -> false) + +let tests = + [ + Tztest.tztest "Simple endorsement" `Quick test_simple_endorsement; + Tztest.tztest "Endorsement with slot -1" `Quick test_negative_slot; + Tztest.tztest + "Endorsement wrapped with non-normalized slot" + `Quick + test_non_normalized_slot; + Tztest.tztest "Fitness gap" `Quick test_fitness_gap; + (* Fail scenarios *) + Tztest.tztest + "Wrong endorsement predecessor" + `Quick + test_wrong_endorsement_predecessor; + Tztest.tztest + "Invalid endorsement level" + `Quick + test_invalid_endorsement_level; + Tztest.tztest "Duplicate endorsement" `Quick test_duplicate_endorsement; + Tztest.tztest + "Endorsement for future level" + `Quick + test_consensus_operation_endorsement_for_future_level; + Tztest.tztest + "Endorsement for predecessor level" + `Quick + test_consensus_operation_endorsement_for_old_level; + Tztest.tztest + "Endorsement for old level" + `Quick + test_consensus_operation_endorsement_for_old_level; + Tztest.tztest + "Endorsement for future round" + `Quick + test_consensus_operation_endorsement_for_future_round; + Tztest.tztest + "Endorsement for old round" + `Quick + test_consensus_operation_endorsement_for_old_round; + Tztest.tztest + "Endorsement on competing proposal" + `Quick + test_consensus_operation_endorsement_on_competing_proposal; + Tztest.tztest "Wrong level for consensus operation" `Quick test_wrong_level; + Tztest.tztest "Wrong round for consensus operation" `Quick test_wrong_round; + Tztest.tztest + "Wrong payload hash for consensus operation" + `Quick + test_wrong_payload_hash; + Tztest.tztest + "Wrong slot used for consensus operation" + `Quick + test_wrong_slot_used; + Tztest.tztest + "sufficient endorsement threshold" + `Quick + (test_endorsement_threshold ~sufficient_threshold:true); + Tztest.tztest + "insufficient endorsement threshold" + `Quick + (test_endorsement_threshold ~sufficient_threshold:false); + Tztest.tztest + "Endorsement/Preendorsement at same level" + `Quick + test_preendorsement_endorsement_same_level; + Tztest.tztest + "Wrong endorsement slot in mempool mode" + `Quick + test_wrong_endorsement_slot_in_mempool_mode; + Tztest.tztest + "Endorsement for next level" + `Quick + test_endorsement_for_next_level; + Tztest.tztest + "Endorsement for next round" + `Quick + test_endorsement_for_next_round; + Tztest.tztest + "Endorsement for grandparent" + `Quick + test_endorsement_grandparent; + Tztest.tztest + "Double endorsement of grandparent" + `Quick + test_double_endorsement_grandparent; + Tztest.tztest + "Endorsement for grandparent on same slot as parent" + `Quick + test_endorsement_grandparent_same_slot; + Tztest.tztest + "Endorsement for grandparent in application mode" + `Quick + test_endorsement_grandparent_application; + Tztest.tztest + "Endorsement for grandparent in full construction mode" + `Quick + test_endorsement_grandparent_full_construction; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_failing_noop.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_failing_noop.ml new file mode 100644 index 000000000000..a791db14ab4e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_failing_noop.ml @@ -0,0 +1,62 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ + -- test "^failing_noop operation$" + Subject: The Failing_noop operation was added bearing in mind the + possibility for the end user to sign arbitrary bytes, + encapsulate in the operation, with the absolute garanty that + the signed bytes can't be used for something against the + user's will. The Failing_noop operation always fails when + applied. + *) + +open Protocol +open Alpha_context + +let register_one_contract () = + Context.init 1 >>=? fun (b, contracts) -> + let contract = + List.nth contracts 0 |> WithExceptions.Option.get ~loc:__LOC__ + in + return (b, contract) + +(** try to apply a failing_noop and assert that the operation fails *) +let failing_noop_must_fail_when_injected () = + register_one_contract () >>=? fun (blk, contract) -> + Contract.is_implicit contract |> function + | None -> Alcotest.fail "only implicit accounts can sign" + | Some source -> + Op.failing_noop (B blk) source "tezos" >>=? fun operation -> + Block.bake ~operation blk >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Failing_noop_error -> true + | _ -> false) + +let tests = + [Tztest.tztest "injection fails" `Quick failing_noop_must_fail_when_injected] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_fitness.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_fitness.ml new file mode 100644 index 000000000000..12affd131b6b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_fitness.ml @@ -0,0 +1,157 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (committee selection) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^fitness$" + Subject: test the fitness module +*) + +open Protocol + +let level_zero = Raw_level_repr.of_int32_exn 0l + +let round_of_int32_exn i = + match Round_repr.of_int32 i with + | Ok i -> i + | Error _ -> Stdlib.failwith "Invalid round representation" + +let make_tuple (level, r_opt, r0, r1) = + let r_opt = Option.map round_of_int32_exn r_opt in + let r0 = round_of_int32_exn r0 in + let r1 = round_of_int32_exn r1 in + (level, r_opt, r0, r1) + +let test_cases = + List.map + make_tuple + [ + (3l, Some 1l, 1l, 12l); + (10l, Some 1l, 1l, 12l); + (10l, Some 4l, 2l, 6l); + (10l, Some 4l, 1l, 12l); + (9l, Some 2l, 0l, 3l); + (7l, None, 0l, 3l); + (7l, None, 1l, 3l); + (0l, None, 0l, 0l); + (12l, Some 2l, 8l, 7l); + (10l, Some 0l, 1l, 1l); + (8l, None, 1l, 0l); + (12l, Some 1l, 8l, 7l); + (8l, None, 6l, 0l); + ] + +let rec product l1 l2 = + match l1 with + | [] -> [] + | h :: tl -> List.map (fun x -> (h, x)) l2 @ product tl l2 + +let test_product_cases = product test_cases test_cases + +let tuple_to_fitness (level, locked_round, predecessor_round, round) = + Fitness_repr.create + ~level:(Raw_level_repr.of_int32_exn level) + ~locked_round + ~predecessor_round + ~round + +let tuple_to_fitness_exn tuple = + tuple_to_fitness tuple |> function + | Ok f -> f + | Error err -> + Format.kasprintf + Stdlib.failwith + "cannot create fitness from tuple: %a" + pp_print_trace + (Environment.wrap_tztrace err) + +let test_from_to_raw_fitness tuple = + let fitness = tuple_to_fitness_exn tuple in + Fitness_repr.from_raw (Fitness_repr.to_raw fitness) |> function + | Ok new_fitness -> assert (fitness = new_fitness) + | Error _x -> assert false + +let test_from_to_raw_fitness_all () = + List.iter test_from_to_raw_fitness test_cases ; + return_unit + +let test_locked_round () = + let test_bad_cases = + List.map + make_tuple + [ + (8l, Some 7l, 1l, 1l); + (9l, Some 8l, 0l, 3l); + (10l, Some 7l, 2l, 6l); + (11l, Some 5l, 5l, 1l); + (8l, Some 2l, 1l, 1l); + (9l, Some 3l, 0l, 3l); + (11l, Some 5l, 5l, 1l); + (13l, Some 2l, 1l, 1l); + (10l, Some 4l, 1l, 1l); + (8l, Some 7l, 1l, 1l); + (10l, Some 8l, 2l, 6l); + (11l, Some 9l, 5l, 1l); + (12l, Some 10l, 8l, 7l); + (13l, Some 14l, 1l, 1l); + ] + in + List.iter_es + (fun tuple -> + Environment.wrap_tzresult @@ tuple_to_fitness tuple |> function + | Error + [ + Environment.Ecoproto_error + (Fitness_repr.Locked_round_not_less_than_round _); + ] -> + return_unit + | Error err -> failwith "unexpected failure: %a" pp_print_trace err + | Ok f -> failwith "unexpected success: %a" Fitness_repr.pp f) + test_bad_cases + +let test_compare (tuple1, tuple2) = + let fitness1 = tuple_to_fitness_exn tuple1 in + let fitness2 = tuple_to_fitness_exn tuple2 in + let raw_fitness1 = Fitness_repr.to_raw fitness1 in + let raw_fitness2 = Fitness_repr.to_raw fitness2 in + let cmp_fitness = Fitness_repr.Internal_for_tests.compare fitness1 fitness2 in + let cmp_raw_fitness = Fitness.compare raw_fitness1 raw_fitness2 in + Assert.equal_int ~loc:__LOC__ cmp_fitness cmp_raw_fitness + +let test_compare_all () = List.iter_es test_compare test_product_cases + +let tests = + [ + Tztest.tztest + "from/to raw fitness is identity" + `Quick + test_from_to_raw_fitness_all; + Tztest.tztest "locked round is smaller than round" `Quick test_locked_round; + Tztest.tztest + "compare fitness = compare raw_fitness" + `Quick + test_compare_all; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_fixed_point.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_fixed_point.ml new file mode 100644 index 000000000000..c4f44f70acf5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_fixed_point.ml @@ -0,0 +1,174 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (fixed-point decimals) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^fixed point computation$" + Subject: On fixed-point decimal numbers. +*) + +open Protocol + +exception Fixed_point_test_error of string + +let err x = Exn (Fixed_point_test_error x) + +module type Arith = sig + type t + + val zero : t + + val equal : t -> t -> bool + + val random : unit -> t + + val add : t -> t -> t + + val sub : t -> t -> t +end + +let n = Z.of_int 42 + +let n' = Z.of_int 43 + +let basic_arith name (module A : Arith) = + let err msg = err (Format.asprintf "%s test: %s" name msg) in + let x = A.random () in + fail_unless A.(add zero x = x) (err "zero is neutral for +") >>=? fun () -> + let x = A.random () in + let y = A.random () in + fail_unless A.(add x y = add y x) (err "addition is commutative") + >>=? fun () -> + let x = A.random () in + fail_unless + A.(sub (add zero x) x = zero) + (err "addition and subtraction cancel") + >>=? fun () -> + let x = A.random () in + let y = A.random () in + let z = A.random () in + fail_unless + A.(add x (add y z) = add (add x y) z) + (err "addition is associative") + +let arith_from_integral : (module Fixed_point_repr.Full) -> (module Arith) = + fun (module FP) -> + let module Arith = struct + type t = FP.integral + + let zero = FP.zero + + let equal = FP.equal + + let random () = FP.integral_of_int_exn (Random.int 898987) + + let add = FP.add + + let sub = FP.sub + end in + (module Arith) + +let arith_from_fp : (module Fixed_point_repr.Full) -> (module Arith) = + fun (module FP) -> + let module Arith = struct + type t = FP.fp + + let zero = FP.zero + + let equal = FP.equal + + let random () = FP.unsafe_fp (Z.of_int (Random.int 898987)) + + let add = FP.add + + let sub = FP.sub + end in + (module Arith) + +let integral_tests () = + let module FP = Gas_limit_repr.Arith in + (* test roundtrips *) + fail_unless (FP.(integral_to_z (integral_exn n)) = n) (err "roundtrip > 0") + >>=? fun () -> + fail_unless + (FP.(integral_to_z (integral_exn Z.zero)) = Z.zero) + (err "roundtrip = 0") + >>=? fun () -> + (* test ceil/floor on integral *) + fail_unless + FP.(ceil (fp (integral_exn n)) = integral_exn n) + (err "integral;fp;ceil = integral") + >>=? fun () -> + fail_unless + FP.(floor (fp (integral_exn n)) = integral_exn n) + (err "integral;fp;floor = integral") + >>=? fun () -> + fail_unless + (Format.asprintf "%a" FP.pp FP.(fp (integral_exn n)) + = Format.asprintf "%a" FP.pp_integral (FP.integral_exn n)) + (err "pp_integral(integral) = pp(fp(integral))") + >>=? fun () -> basic_arith "integral arith" (arith_from_integral (module FP)) + +let fp_nonzero () = + let decimals = 3 in + let module FP = Gas_limit_repr.Arith in + let prefix msg = Format.asprintf "(%d decimals) %s" decimals msg in + let err msg = err (prefix msg) in + basic_arith (prefix "integral arith") (arith_from_integral (module FP)) + >>=? fun () -> + basic_arith (prefix "fp arith") (arith_from_fp (module FP)) >>=? fun () -> + let epsilon = FP.unsafe_fp Z.one in + fail_unless FP.(ceil epsilon = integral_exn Z.one) (err "ceil eps = 1") + >>=? fun () -> + fail_unless FP.(floor epsilon = integral_exn Z.zero) (err "floor eps = 1") + >>=? fun () -> + let x = Z.of_int (Random.int 980812) in + fail_unless + FP.( + ceil (add (fp (integral_exn x)) (unsafe_fp Z.one)) + = integral_exn (Z.succ x)) + (err "ceil (x + eps) = x + 1") + +let fp_pp () = + let module FP = Gas_limit_repr.Arith in + let prefix msg = Format.asprintf "(%d decimals) %s" 3 msg in + let err msg = err (prefix msg) in + let epsilon = FP.unsafe_fp Z.one in + let ( =:= ) x expected = Format.asprintf "%a" FP.pp x = expected in + fail_unless (epsilon =:= "0.001") (err "eps = 0.001") >>=? fun () -> + fail_unless (FP.unsafe_fp (Z.of_int 1000) =:= "1") (err "1.000 = 1") + >>=? fun () -> + fail_unless (FP.unsafe_fp (Z.of_int 1001) =:= "1.001") (err "1.001") + >>=? fun () -> + fail_unless (FP.unsafe_fp (Z.of_int 10001) =:= "10.001") (err "10.001") + >>=? fun () -> fail_unless (FP.zero =:= "0") (err "0") + +let tests = + [ + Tztest.tztest "Integral tests (3 decimals)" `Quick integral_tests; + Tztest.tztest "FP tests (3 decimals)" `Quick fp_nonzero; + Tztest.tztest "FP pp tests (3 decimals)" `Quick fp_pp; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_frozen_deposits.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_frozen_deposits.ml new file mode 100644 index 000000000000..d377bd4a1233 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_frozen_deposits.ml @@ -0,0 +1,631 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (frozen_deposits) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^frozen deposits$" + Subject: consistency of frozen deposits and the [set_deposits_limit] operation + *) + +open Protocol +open Alpha_context +open Test_tez + +let constants = + { + Default_parameters.constants_test with + endorsing_reward_per_slot = Tez.zero; + baking_reward_bonus_per_slot = Tez.zero; + baking_reward_fixed_portion = Tez.zero; + consensus_threshold = 0; + origination_size = 0; + } + +let get_first_2_accounts_contracts contracts = + let ((contract1, account1), (contract2, account2)) = + match contracts with + | [a1; a2] -> + ( ( a1, + Contract.is_implicit a1 |> function + | None -> assert false + | Some pkh -> pkh ), + ( a2, + Contract.is_implicit a2 |> function + | None -> assert false + | Some pkh -> pkh ) ) + | _ -> assert false + in + ((contract1, account1), (contract2, account2)) + +(* Terminology: + +- staking balance = full balance + delegated stake; obtained with + Delegate.staking_balance + +- active stake = the amount of tez with which a delegate participates in + consensus; it must be greater than 1 roll and less or equal the staking + balance; it is computed in [Delegate_storage.select_distribution_for_cycle] + +- frozen deposits = represents frozen_deposits_percentage of the maximum stake during + preserved_cycles + max_slashing_period cycles; obtained with + Delegate.current_frozen_deposits + +- spendable balance = full balance - frozen deposits; obtained with Contract.balance + +- full balance = spendable balance + frozen deposits; obtained with Delegate.full_balance +*) +let test_invariants () = + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((contract1, account1), (contract2, _account2)) = + get_first_2_accounts_contracts contracts + in + Context.Delegate.staking_balance (B genesis) account1 + >>=? fun staking_balance -> + Context.Delegate.full_balance (B genesis) account1 >>=? fun full_balance -> + Context.Contract.balance (B genesis) contract1 >>=? fun spendable_balance -> + Context.Delegate.current_frozen_deposits (B genesis) account1 + >>=? fun frozen_deposits -> + (* before delegation *) + Assert.equal_tez ~loc:__LOC__ full_balance staking_balance >>=? fun () -> + Assert.equal_tez + ~loc:__LOC__ + full_balance + Test_tez.(spendable_balance +! frozen_deposits) + >>=? fun () -> + (* to see how delegation plays a role, let's delegate to account1; + N.B. account2 represents a delegate so it cannot delegate to account1; this is + why we go through new_account as an intermediate *) + Context.Contract.balance (B genesis) contract2 >>=? fun spendable_balance2 -> + let new_account = (Account.new_account ()).pkh in + let new_contract = Contract.implicit_contract new_account in + (* we first put some money in new_account *) + Op.transaction (B genesis) contract2 new_contract spendable_balance2 + >>=? fun transfer -> + Block.bake ~operation:transfer genesis >>=? fun b -> + Context.Contract.balance (B b) new_contract >>=? fun new_account_balance -> + Assert.equal_tez ~loc:__LOC__ new_account_balance spendable_balance2 + >>=? fun () -> + Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> + Block.bake ~operation:delegation b >>=? fun b1 -> + Block.bake_until_n_cycle_end constants.preserved_cycles b1 >>=? fun b2 -> + Context.Delegate.staking_balance (B b2) account1 + >>=? fun new_staking_balance -> + Context.Delegate.full_balance (B b2) account1 >>=? fun new_full_balance -> + Context.Contract.balance (B b2) contract1 >>=? fun new_spendable_balance -> + Context.Delegate.current_frozen_deposits (B b2) account1 + >>=? fun new_frozen_deposits -> + (* after delegation, we see the delegated stake reflected in the new staking + balance of account1 *) + Assert.equal_tez + ~loc:__LOC__ + new_staking_balance + Test_tez.(new_full_balance +! new_account_balance) + >>=? fun () -> + Assert.equal_tez + ~loc:__LOC__ + new_full_balance + Test_tez.(new_spendable_balance +! new_frozen_deposits) + >>=? fun () -> + let expected_new_frozen_deposits = + Test_tez.( + (* in this particular example, if we follow the calculation of the active + stake, it is precisely the new_staking_balance *) + new_staking_balance /! 100L + *! Int64.of_int constants.frozen_deposits_percentage) + in + Assert.equal_tez ~loc:__LOC__ new_frozen_deposits expected_new_frozen_deposits + +let test_set_limit balance_percentage () = + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((contract1, account1), (_contract2, account2)) = + get_first_2_accounts_contracts contracts + in + (Context.Delegate.frozen_deposits_limit (B genesis) account1 >>=? function + | Some _ -> Alcotest.fail "unexpected deposits limit" + | None -> return_unit) + >>=? fun () -> + (* Test deposit consistency before and after first cycle *) + Context.Delegate.full_balance (B genesis) account1 >>=? fun full_balance -> + Context.Delegate.current_frozen_deposits (B genesis) account1 + >>=? fun frozen_deposits -> + let expected_deposits = + full_balance *! Int64.of_int constants.frozen_deposits_percentage /! 100L + in + Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_deposits >>=? fun () -> + (* Bake until end of first cycle *) + Block.bake_until_cycle_end genesis >>=? fun b -> + Context.Delegate.full_balance (B genesis) account1 >>=? fun full_balance -> + Context.Delegate.current_frozen_deposits (B genesis) account1 + >>=? fun frozen_deposits -> + let expected_deposits = + full_balance *! Int64.of_int constants.frozen_deposits_percentage /! 100L + in + Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_deposits >>=? fun () -> + (* set deposits limit to balance_percentage out of the balance *) + let limit = + Test_tez.(full_balance *! Int64.of_int balance_percentage /! 100L) + in + Op.set_deposits_limit (B genesis) contract1 (Some limit) >>=? fun operation -> + Block.bake ~policy:(By_account account2) ~operation b >>=? fun b -> + (Context.Delegate.frozen_deposits_limit (B b) account1 >>=? function + | Some set_limit -> Assert.equal_tez ~loc:__LOC__ set_limit limit + | None -> Alcotest.fail "unexpected absence of deposits limit") + >>=? fun () -> + (* the frozen deposits limit affects the active stake for cycles starting with c + + preserved_cycles + 1; the new active stake is taken into account when + computing the frozen deposits for cycle c+1 already, however the user may see + an update to its frozen deposits at cycle c + preserved_cycles + + max_slashing_period at the latest (because up to that cycle the frozen + deposits also depend on the active stake at cycles before cycle c+1). *) + let expected_number_of_cycles_with_previous_deposit = + constants.preserved_cycles + constants.max_slashing_period + in + Block.bake_until_n_cycle_end + ~policy:(By_account account2) + (expected_number_of_cycles_with_previous_deposit - 1) + b + >>=? fun b -> + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits -> + Assert.not_equal_tez ~loc:__LOC__ frozen_deposits Tez.zero >>=? fun () -> + Block.bake_until_cycle_end ~policy:(By_account account2) b >>=? fun b -> + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ frozen_deposits limit + +let test_cannot_bake_with_zero_deposits () = + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((contract1, account1), (_contract2, account2)) = + get_first_2_accounts_contracts contracts + in + (* N.B. there is no non-zero frozen deposits value for which one cannot bake: + even with a small deposit one can still bake, though with a smaller probability + (because the frozen deposits value impacts the active stake and the active + stake is the one used to determine baking/endorsing rights. *) + Op.set_deposits_limit (B genesis) contract1 (Some Tez.zero) + >>=? fun operation -> + Block.bake ~policy:(By_account account2) ~operation genesis >>=? fun b -> + let expected_number_of_cycles_with_previous_deposit = + constants.preserved_cycles + constants.max_slashing_period - 1 + in + Block.bake_until_n_cycle_end + ~policy:(By_account account2) + expected_number_of_cycles_with_previous_deposit + b + >>=? fun b -> + Block.bake ~policy:(By_account account1) b >>= fun b1 -> + (* by now, the active stake of account1 is 0 so it no longer has slots, thus it + cannot be a proposer, thus it cannot bake. Precisely, bake fails because + get_next_baker_by_account fails with "No slots found" *) + Assert.error ~loc:__LOC__ b1 (fun _ -> true) + +let test_deposits_after_stake_removal () = + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((contract1, account1), (contract2, account2)) = + get_first_2_accounts_contracts contracts + in + Context.Delegate.current_frozen_deposits (B genesis) account1 + >>=? fun initial_frozen_deposits_1 -> + Context.Delegate.current_frozen_deposits (B genesis) account2 + >>=? fun initial_frozen_deposits_2 -> + let expected_new_frozen_deposits_2 = + Test_tez.(initial_frozen_deposits_2 *! 3L /! 2L) + in + (* Move half the account1's balance to account2 *) + Context.Delegate.full_balance (B genesis) account1 >>=? fun full_balance -> + let half_balance = Test_tez.(full_balance /! 2L) in + Op.transaction (B genesis) contract1 contract2 half_balance + >>=? fun operation -> + Block.bake ~operation genesis >>=? fun b -> + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits_1 -> + Assert.equal_tez ~loc:__LOC__ frozen_deposits_1 initial_frozen_deposits_1 + >>=? fun () -> + Context.Delegate.current_frozen_deposits (B b) account2 + >>=? fun frozen_deposits_2 -> + Assert.equal_tez ~loc:__LOC__ frozen_deposits_2 initial_frozen_deposits_2 + >>=? fun () -> + (* Bake a cycle to act account2's new frozen deposits *) + Block.bake_until_cycle_end b >>=? fun b -> + let rec loop b n = + if n = 0 then return b + else + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits_1 -> + (* the frozen_deposits is frozen_deposits_percentage of the maximum active stake + during the last preserved_cycles + max_slashing_period cycles; + consequently, though the active stake of account1 has decreased at + cycle c, this decrease makes the frozen deposits smaller only after + preserved cycles + max_slashing_period. *) + Assert.equal_tez ~loc:__LOC__ frozen_deposits_1 initial_frozen_deposits_1 + >>=? fun () -> + (* the active stake of account2 has increased and this increase affects + the frozen_deposits from this cycle as it is greater than previous ones. *) + Context.Delegate.current_frozen_deposits (B b) account2 + >>=? fun frozen_deposits_2 -> + Assert.equal_tez + ~loc:__LOC__ + frozen_deposits_2 + expected_new_frozen_deposits_2 + >>=? fun () -> + Block.bake_until_cycle_end b >>=? fun b -> loop b (pred n) + in + (* the frozen deposits for account1 do not change until [preserved cycles + + max_slashing_period] are baked (-1 because we already baked a cycle) *) + loop b (constants.preserved_cycles + constants.max_slashing_period - 1) + >>=? fun b -> + (* after preserved cycles + max_slashing_period, the frozen_deposits for account1 + reflects the decrease in account1's active stake. *) + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits_1 -> + Assert.equal_tez + ~loc:__LOC__ + frozen_deposits_1 + Test_tez.(initial_frozen_deposits_1 /! 2L) + >>=? fun () -> + Context.Delegate.current_frozen_deposits (B b) account2 + >>=? fun frozen_deposits_2 -> + Assert.equal_tez ~loc:__LOC__ frozen_deposits_2 expected_new_frozen_deposits_2 + +let test_unfreeze_deposits_after_deactivation () = + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((contract1, account1), (_contract2, account2)) = + get_first_2_accounts_contracts contracts + in + Context.Delegate.full_balance (B genesis) account1 >>=? fun initial_balance -> + (* [account1] will not participate (ie bake/endorse); we set the + expected last cycles at which it is considered active and at + which it has non-zero deposits *) + let last_active_cycle = + 1 + (2 * constants.preserved_cycles) + (* according to [Delegate_storage.set_active] *) + in + let last_cycle_with_deposits = + last_active_cycle + constants.preserved_cycles + + constants.max_slashing_period + (* according to [Delegate_storage.freeze_deposits] *) + in + let cycles_to_bake = last_cycle_with_deposits + constants.preserved_cycles in + let rec loop b n = + if n = 0 then return b + else + Block.bake_until_cycle_end ~policy:(By_account account2) b >>=? fun b -> + Context.Delegate.deactivated (B b) account1 >>=? fun is_deactivated -> + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits -> + (* the spendable balance *) + Context.Contract.balance (B b) contract1 >>=? fun balance -> + let new_cycle = cycles_to_bake - n + 1 in + Assert.equal_bool + ~loc:__LOC__ + is_deactivated + (new_cycle > last_active_cycle) + >>=? fun () -> + Assert.equal_bool + ~loc:__LOC__ + (new_cycle > last_cycle_with_deposits) + (* as soon as frozen_deposits are set to zero from a non-zero value v, v is + returned to the spendable balance of account1; in this particular + case, the spendable balance [balance] updated with v is precisely the + initial_balance.*) + (Tez.(frozen_deposits = zero) && Tez.(balance = initial_balance)) + >>=? fun () -> loop b (pred n) + in + loop genesis cycles_to_bake >>=? fun _b -> return_unit + +let test_frozen_deposits_with_delegation () = + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((_contract1, account1), (contract2, account2)) = + get_first_2_accounts_contracts contracts + in + Context.Delegate.staking_balance (B genesis) account1 + >>=? fun initial_staking_balance -> + Context.Delegate.current_frozen_deposits (B genesis) account1 + >>=? fun initial_frozen_deposits -> + Context.Contract.balance (B genesis) contract2 >>=? fun delegated_amount -> + let new_account = Account.new_account () in + let new_contract = Contract.implicit_contract new_account.pkh in + Op.transaction (B genesis) contract2 new_contract delegated_amount + >>=? fun transfer -> + Block.bake ~operation:transfer genesis >>=? fun b -> + Context.Delegate.staking_balance (B b) account2 + >>=? fun new_staking_balance -> + let expected_new_staking_balance = + Test_tez.(initial_staking_balance -! delegated_amount) + in + Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance + >>=? fun () -> + Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> + Block.bake ~operation:delegation b >>=? fun b -> + let expected_new_staking_balance = + Test_tez.(initial_staking_balance +! delegated_amount) + in + Context.Delegate.staking_balance (B b) account1 + >>=? fun new_staking_balance -> + Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance + >>=? fun () -> + (* Bake one cycle to update the frozen deposits *) + Block.bake_until_cycle_end b >>=? fun b -> + let expected_new_frozen_deposits = + Test_tez.( + initial_frozen_deposits + +! delegated_amount + *! Int64.of_int constants.frozen_deposits_percentage + /! 100L) + in + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun new_frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ new_frozen_deposits expected_new_frozen_deposits + >>=? fun () -> + let cycles_to_bake = + 2 * (constants.preserved_cycles + constants.max_slashing_period) + in + let rec loop b n = + if n = 0 then return b + else + Block.bake_until_cycle_end ~policy:(By_account account1) b >>=? fun b -> + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits + >>=? fun () -> loop b (pred n) + in + (* Check that frozen deposits do not change for a sufficient period of + time *) + loop b cycles_to_bake >>=? fun _b -> return_unit + +let test_frozen_deposits_with_overdelegation () = + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((contract1, account1), (contract2, account2)) = + get_first_2_accounts_contracts contracts + in + (* - [account1] and [account2] give their spendable balance to [new_account] + - [new_account] overdelegates to [account1] *) + Context.Delegate.staking_balance (B genesis) account1 + >>=? fun initial_staking_balance -> + Context.Delegate.staking_balance (B genesis) account2 + >>=? fun initial_staking_balance' -> + Context.Delegate.current_frozen_deposits (B genesis) account1 + >>=? fun initial_frozen_deposits -> + Context.Contract.balance (B genesis) contract1 >>=? fun amount -> + Context.Contract.balance (B genesis) contract2 >>=? fun amount' -> + let new_account = (Account.new_account ()).pkh in + let new_contract = Contract.implicit_contract new_account in + Op.transaction (B genesis) contract1 new_contract amount >>=? fun transfer1 -> + Op.transaction (B genesis) contract2 new_contract amount' + >>=? fun transfer2 -> + Block.bake ~operations:[transfer1; transfer2] genesis >>=? fun b -> + let expected_new_staking_balance = + Test_tez.(initial_staking_balance -! amount) + in + Context.Delegate.staking_balance (B b) account1 + >>=? fun new_staking_balance -> + Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance + >>=? fun () -> + let expected_new_staking_balance' = + Test_tez.(initial_staking_balance' -! amount') + in + Context.Delegate.staking_balance (B b) account2 + >>=? fun new_staking_balance' -> + Assert.equal_tez + ~loc:__LOC__ + new_staking_balance' + expected_new_staking_balance' + >>=? fun () -> + Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> + Block.bake ~operation:delegation b >>=? fun b -> + Context.Delegate.staking_balance (B b) account1 + >>=? fun new_staking_balance -> + let expected_new_staking_balance = + Test_tez.(initial_frozen_deposits +! amount +! amount') + in + Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance + >>=? fun () -> + (* Finish the cycle to update the frozen deposits *) + Block.bake_until_cycle_end b >>=? fun b -> + Context.Delegate.full_balance (B b) account1 + >>=? fun expected_new_frozen_deposits -> + (* the equality follows from the definition of active stake in + [Delegate.select_distribution_for_cycle]. *) + assert (initial_frozen_deposits = expected_new_frozen_deposits) ; + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun new_frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ new_frozen_deposits expected_new_frozen_deposits + >>=? fun () -> + let cycles_to_bake = + 2 * (constants.preserved_cycles + constants.max_slashing_period) + in + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits + >>=? fun () -> + let rec loop b n = + if n = 0 then return b + else + Block.bake_until_cycle_end ~policy:(By_account account1) b >>=? fun b -> + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits + >>=? fun () -> loop b (pred n) + in + (* Check that frozen deposits do not change for a sufficient period of + time *) + loop b cycles_to_bake >>=? fun _b -> return_unit + +let test_set_limit_with_overdelegation () = + let constants = {constants with frozen_deposits_percentage = 10} in + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((contract1, account1), (contract2, account2)) = + get_first_2_accounts_contracts contracts + in + (* - [account1] and [account2] will give 80% of their balance to + [new_account] + - [new_account] will overdelegate to [account1] but [account1] will set + its frozen deposits limit to 15% of its stake *) + Context.Delegate.staking_balance (B genesis) account1 + >>=? fun initial_staking_balance -> + Context.Delegate.staking_balance (B genesis) account2 + >>=? fun initial_staking_balance' -> + let amount = Test_tez.(initial_staking_balance *! 8L /! 10L) in + let amount' = Test_tez.(initial_staking_balance' *! 8L /! 10L) in + let limit = Test_tez.(initial_staking_balance *! 15L /! 100L) in + let new_account = (Account.new_account ()).pkh in + let new_contract = Contract.implicit_contract new_account in + Op.transaction (B genesis) contract1 new_contract amount >>=? fun transfer1 -> + Op.transaction (B genesis) contract2 new_contract amount' + >>=? fun transfer2 -> + Block.bake ~operations:[transfer1; transfer2] genesis >>=? fun b -> + Op.set_deposits_limit (B b) contract1 (Some limit) >>=? fun set_deposits -> + Block.bake ~operation:set_deposits b >>=? fun b -> + let expected_new_staking_balance = + Test_tez.(initial_staking_balance -! amount) + in + Context.Delegate.staking_balance (B b) account1 + >>=? fun new_staking_balance -> + Assert.equal_tez ~loc:__LOC__ new_staking_balance expected_new_staking_balance + >>=? fun () -> + let expected_new_staking_balance' = + Test_tez.(initial_staking_balance' -! amount') + in + Context.Delegate.staking_balance (B b) account2 + >>=? fun new_staking_balance' -> + Assert.equal_tez + ~loc:__LOC__ + new_staking_balance' + expected_new_staking_balance' + >>=? fun () -> + Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> + Block.bake ~operation:delegation b >>=? fun b -> + (* Finish the cycle to update the frozen deposits *) + Block.bake_until_cycle_end b >>=? fun b -> + let expected_new_frozen_deposits = limit in + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits + >>=? fun () -> + let cycles_to_bake = + 2 * (constants.preserved_cycles + constants.max_slashing_period) + in + let rec loop b n = + if n = 0 then return b + else + Block.bake_until_cycle_end ~policy:(By_account account1) b >>=? fun b -> + Context.Delegate.current_frozen_deposits (B b) account1 + >>=? fun frozen_deposits -> + Assert.equal_tez ~loc:__LOC__ frozen_deposits expected_new_frozen_deposits + >>=? fun () -> loop b (pred n) + in + (* Check that frozen deposits do not change for a sufficient period of + time *) + loop b cycles_to_bake >>=? fun _b -> return_unit + +(** This test fails when [to_cycle] in [Delegate.freeze_deposits] is smaller than + [new_cycle + preserved_cycles]. *) +let test_error_is_thrown_when_smaller_upper_bound_for_frozen_window () = + Context.init_with_constants constants 2 >>=? fun (genesis, contracts) -> + let ((contract1, account1), (contract2, _account2)) = + match contracts with + | [a1; a2] -> + ( ( a1, + Contract.is_implicit a1 |> function + | None -> assert false + | Some pkh -> pkh ), + ( a2, + Contract.is_implicit a2 |> function + | None -> assert false + | Some pkh -> pkh ) ) + | _ -> assert false + in + (* [account2] delegates (through [new_account]) to [account1] its spendable + balance. The point is to make [account1] have a lot of staking balance so + that, after [preserved_cycles] when the active stake reflects this increase + in staking balance, its [maximum_stake_to_be_deposited] is bigger than the frozen + deposit which is computed on a smaller window because [to_cycle] is smaller + than [new_cycle + preserved_cycles]. *) + Context.Contract.balance (B genesis) contract2 >>=? fun delegated_amount -> + let new_account = Account.new_account () in + let new_contract = Contract.implicit_contract new_account.pkh in + Op.transaction (B genesis) contract2 new_contract delegated_amount + >>=? fun transfer -> + Block.bake ~operation:transfer genesis >>=? fun b -> + Op.delegation (B b) new_contract (Some account1) >>=? fun delegation -> + Block.bake ~operation:delegation b >>=? fun b -> + Block.bake_until_cycle_end b >>=? fun b -> + (* After 1 cycle, namely, at cycle 2, [account1] transfers all its spendable + balance. *) + Context.Contract.balance (B b) contract1 >>=? fun balance1 -> + Op.transaction (B b) contract1 contract2 balance1 >>=? fun operation -> + Block.bake ~operation b >>=? fun b -> + Block.bake_until_n_cycle_end constants.preserved_cycles b >>=? fun _ -> + (* By this time, after [preserved_cycles] passed after [account1] has emptied + its spendable balance, because [account1] had a big staking balance at + cycle 0, at this cycle it has a big active stake, and so its + [maximum_stake_to_be_deposited] too is bigger than [frozen_deposits.current_amount], + so the variable [to_freeze] in [freeze_deposits] is positive. + Because the spendable balance of [account1] is 0, an error "Underflowing + subtraction" is raised at the end of the cycle when updating the balance by + subtracting [to_freeze] in [freeze_deposits]. + Note that by taking [to_cycle] is [new_cycle + preserved_cycles], + [frozen_deposits.current_amount] can no longer be smaller + than [maximum_stake_to_be_deposited], that is, the invariant + maximum_stake_to_be_deposited <= frozen_deposits + balance is preserved. + *) + return_unit + +let tests = + Tztest. + [ + tztest "test invariants" `Quick test_invariants; + tztest "set deposits limit to 0%" `Quick (test_set_limit 0); + tztest "set deposits limit to 5%" `Quick (test_set_limit 5); + tztest + "cannot bake with zero deposits" + `Quick + test_cannot_bake_with_zero_deposits; + tztest + "deposits after stake removal" + `Quick + test_deposits_after_stake_removal; + tztest + "unfreeze deposits after deactivation" + `Quick + test_unfreeze_deposits_after_deactivation; + tztest + "frozen deposits with delegation" + `Quick + test_frozen_deposits_with_delegation; + tztest + "test frozen deposits with overdelegation" + `Quick + test_frozen_deposits_with_overdelegation; + tztest + "test set limit with overdelegation" + `Quick + test_set_limit_with_overdelegation; + tztest + "test error is thrown when the frozen window is smaller" + `Quick + test_error_is_thrown_when_smaller_upper_bound_for_frozen_window; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_gas_costs.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_gas_costs.ml new file mode 100644 index 000000000000..b2ff11874743 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_gas_costs.ml @@ -0,0 +1,289 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (gas costs) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^gas cost functions$" + Subject: Gas costs + Current limitations: for maps, sets & compare, we only test + integer comparable keys. +*) + +open Protocol +module S = Saturation_repr + +let dummy_list = Script_list.(cons 42 empty) + +let forty_two = Alpha_context.Script_int.of_int 42 + +let forty_two_n = Alpha_context.Script_int.abs forty_two + +let dummy_set = + let open Script_set in + update forty_two true (empty Script_typed_ir.(int_key ~annot:None)) + +let dummy_map = + let open Script_map in + update + forty_two + (Some forty_two) + (empty Script_typed_ir.(int_key ~annot:None)) + +let dummy_timestamp = Alpha_context.Script_timestamp.of_zint (Z.of_int 42) + +let dummy_pk = + Signature.Public_key.of_b58check_exn + "edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU" + +let dummy_bytes = Bytes.of_string "dummy" + +let dummy_string = + match Alpha_context.Script_string.of_string "dummy" with + | Ok s -> s + | Error _ -> assert false + +let dummy_ty = Script_typed_ir.never_t ~annot:None + +let free = ["balance"; "bool"; "parsing_unit"; "unparsing_unit"] + +(* /!\ The compiler will only complain if costs are _removed_ /!\*) +let all_interpreter_costs = + let open Michelson_v1_gas.Cost_of.Interpreter in + [ + ("drop", drop); + ("dup", dup); + ("swap", swap); + ("cons_some", cons_some); + ("cons_none", cons_none); + ("if_none", if_none); + ("cons_pair", cons_pair); + ("car", car); + ("cdr", cdr); + ("cons_left", cons_left); + ("cons_right", cons_right); + ("if_left", if_left); + ("cons_list", cons_list); + ("nil", nil); + ("if_cons", if_cons); + ("list_map", list_map dummy_list); + ("list_size", list_size); + ("list_iter", list_iter dummy_list); + ("empty_set", empty_set); + ("set_iter", set_iter dummy_set); + ("set_mem", set_mem forty_two dummy_set); + ("set_update", set_update forty_two dummy_set); + ("set_size", set_size); + ("empty_map", empty_map); + ("map_map", map_map dummy_map); + ("map_iter", map_iter dummy_map); + ("map_mem", map_mem forty_two dummy_map); + ("map_get", map_get forty_two dummy_map); + ("map_update", map_update forty_two dummy_map); + ("map_size", map_size); + ("add_seconds_timestamp", add_seconds_timestamp forty_two dummy_timestamp); + ("sub_timestamp_seconds", sub_timestamp_seconds dummy_timestamp forty_two); + ("diff_timestamps", diff_timestamps dummy_timestamp dummy_timestamp); + ("concat_string_pair", concat_string_pair dummy_string dummy_string); + ("slice_string", slice_string dummy_string); + ("string_size", string_size); + ("concat_bytes_pair", concat_bytes_pair dummy_bytes dummy_bytes); + ("slice_bytes", slice_bytes dummy_bytes); + ("bytes_size", bytes_size); + ("add_tez", add_tez); + ("sub_tez", sub_tez); + ("mul_teznat", mul_teznat); + ("bool_or", bool_or); + ("bool_and", bool_and); + ("bool_xor", bool_xor); + ("bool_not", bool_not); + ("is_nat", is_nat); + ("abs_int", abs_int forty_two); + ("int_nat", int_nat); + ("neg", neg forty_two); + ("add_int", add_int forty_two forty_two); + ("sub_int", sub_int forty_two forty_two); + ("mul_int", mul_int forty_two forty_two); + ("ediv_teznat", ediv_teznat Alpha_context.Tez.fifty_cents forty_two); + ("ediv_tez", ediv_tez); + ("ediv_int", ediv_int forty_two (Alpha_context.Script_int.of_int 1)); + ("eq", eq); + ("lsl_nat", lsl_nat forty_two); + ("lsr_nat", lsr_nat forty_two); + ("or_nat", or_nat forty_two forty_two); + ("and_nat", and_nat forty_two forty_two); + ("xor_nat", xor_nat forty_two forty_two); + ("not_int", not_int forty_two); + ("if_", if_); + ("loop", loop); + ("loop_left", loop_left); + ("dip", dip); + ("check_signature", check_signature dummy_pk dummy_bytes); + ("blake2b", blake2b dummy_bytes); + ("sha256", sha256 dummy_bytes); + ("sha512", sha512 dummy_bytes); + ("dign", dign 42); + ("dugn", dugn 42); + ("dipn", dipn 42); + ("dropn", dropn 42); + ("neq", neq); + ( "compare", + compare Script_typed_ir.(int_key ~annot:None) forty_two forty_two ); + ( "concat_string_precheck", + concat_string_precheck Script_list.(cons "42" empty) ); + ("concat_string", concat_string (S.safe_int 42)); + ("concat_bytes", concat_bytes (S.safe_int 42)); + ("exec", exec); + ("apply", apply); + ("lambda", lambda); + ("address", address); + ("contract", contract); + ("transfer_tokens", transfer_tokens); + ("implicit_account", implicit_account); + ("create_contract", create_contract); + ("set_delegate", set_delegate); + (* balance is free *) + ("balance", balance); + ("level", level); + ("now", now); + ("hash_key", hash_key dummy_pk); + ("source", source); + ("sender", sender); + ("self", self); + ("self_address", self_address); + ("amount", amount); + ("chain_id", chain_id); + ("unpack_failed", unpack_failed "dummy"); + ] + +(* /!\ The compiler will only complain if costs are _removed_ /!\*) +let all_parsing_costs = + let open Michelson_v1_gas.Cost_of.Typechecking in + [ + ("public_key_optimized", public_key_optimized); + ("public_key_readable", public_key_readable); + ("key_hash_optimized", key_hash_optimized); + ("key_hash_readable", key_hash_readable); + ("signature_optimized", signature_optimized); + ("signature_readable", signature_readable); + ("chain_id_optimized", chain_id_optimized); + ("chain_id_readable", chain_id_readable); + ("address_optimized", address_optimized); + ("contract_optimized", contract_optimized); + ("contract_readable", contract_readable); + ("check_printable", check_printable "dummy"); + ("merge_cycle", merge_cycle); + ("parse_type_cycle", parse_type_cycle); + ("parse_instr_cycle", parse_instr_cycle); + ("parse_data_cycle", parse_data_cycle); + ("bool", bool); + ("parsing_unit", unit); + ("timestamp_readable", timestamp_readable); + ("contract", contract); + ("contract_exists", contract_exists); + ("proof_argument", proof_argument 42); + ] + +(* /!\ The compiler will only complain if costs are _removed_ /!\*) +let all_unparsing_costs = + let open Michelson_v1_gas.Cost_of.Unparsing in + [ + ("public_key_optimized", public_key_optimized); + ("public_key_readable", public_key_readable); + ("key_hash_optimized", key_hash_optimized); + ("key_hash_readable", key_hash_readable); + ("signature_optimized", signature_optimized); + ("signature_readable", signature_readable); + ("chain_id_optimized", chain_id_optimized); + ("chain_id_readable", chain_id_readable); + ("timestamp_readable", timestamp_readable); + ("address_optimized", address_optimized); + ("contract_optimized", contract_optimized); + ("contract_readable", contract_readable); + ("unparse_type", unparse_type dummy_ty); + ("unparse_instr_cycle", unparse_instr_cycle); + ("unparse_data_cycle", unparse_data_cycle); + ("unparsing_unit", unit); + ("contract", contract); + ("operation", operation dummy_bytes); + ] + +(* /!\ The compiler will only complain if costs are _removed_ /!\*) +let all_io_costs = + let open Storage_costs in + [ + ("read_access 0 0", read_access ~path_length:0 ~read_bytes:0); + ("read_access 1 0", read_access ~path_length:1 ~read_bytes:0); + ("read_access 0 1", read_access ~path_length:0 ~read_bytes:1); + ("read_access 1 1", read_access ~path_length:1 ~read_bytes:1); + ("write_access 0", write_access ~written_bytes:0); + ("write_access 1", write_access ~written_bytes:1); + ] + +(* Here we're using knowledge of the internal representation of costs to + cast them to S ... *) +let cast_cost_to_s (c : Alpha_context.Gas.cost) : _ S.t = + Data_encoding.Binary.to_bytes_exn Alpha_context.Gas.cost_encoding c + |> Data_encoding.Binary.of_bytes_exn S.n_encoding + +(** Checks that all costs are positive values. *) +let test_cost_reprs_are_all_positive list () = + List.iter_es + (fun (cost_name, cost) -> + if S.(cost > S.zero) then return_unit + else if S.equal cost S.zero && List.mem ~equal:String.equal cost_name free + then return_unit + else + fail + (Exn + (Failure (Format.asprintf "Gas cost test \"%s\" failed" cost_name)))) + list + +(** Checks that all costs are positive values. *) +let test_costs_are_all_positive list () = + let list = + List.map (fun (cost_name, cost) -> (cost_name, cast_cost_to_s cost)) list + in + test_cost_reprs_are_all_positive list () + +let tests = + [ + Tztest.tztest + "Positivity of interpreter costs" + `Quick + (test_costs_are_all_positive all_interpreter_costs); + Tztest.tztest + "Positivity of typechecking costs" + `Quick + (test_costs_are_all_positive all_parsing_costs); + Tztest.tztest + "Positivity of unparsing costs" + `Quick + (test_costs_are_all_positive all_unparsing_costs); + Tztest.tztest + "Positivity of io costs" + `Quick + (test_cost_reprs_are_all_positive all_io_costs); + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_gas_levels.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_gas_levels.ml new file mode 100644 index 000000000000..a19c1476d1d5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_gas_levels.ml @@ -0,0 +1,481 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (Gas levels) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^gas levels$" + Subject: On gas consumption and exhaustion. +*) + +open Protocol +open Raw_context +module S = Saturation_repr + +(* This value is supposed to be larger than the block gas level limit + but not saturated. *) +let opg = max_int / 10000 + +exception Gas_levels_test_error of string + +let err x = Exn (Gas_levels_test_error x) + +let succeed x = match x with Ok _ -> true | _ -> false + +let failed x = not (succeed x) + +let dummy_context () = + Context.init ~consensus_threshold:0 1 >>=? fun (block, _) -> + Raw_context.prepare + ~level:Int32.zero + ~predecessor_timestamp:Time.Protocol.epoch + ~timestamp:Time.Protocol.epoch + (* ~fitness:[] *) + (block.context : Environment_context.Context.t) + >|= Environment.wrap_tzresult + +let consume_gas_lwt context gas = + Lwt.return (consume_gas context (S.safe_int gas)) + >|= Environment.wrap_tzresult + +let consume_gas_limit_in_block_lwt context gas = + Lwt.return (consume_gas_limit_in_block context gas) + >|= Environment.wrap_tzresult + +let test_detect_gas_exhaustion_in_fresh_context () = + dummy_context () >>=? fun context -> + fail_unless + (consume_gas context (S.safe_int opg) |> succeed) + (err "In a fresh context, gas consumption is unlimited.") + +(** Create a context with a given block gas level, capped at the + hard gas limit per block *) +let make_context remaining_block_gas = + let open Gas_limit_repr in + dummy_context () >>=? fun context -> + let hard_limit = Arith.fp (constants context).hard_gas_limit_per_operation in + let hard_limit_block = + Arith.fp (constants context).hard_gas_limit_per_block + in + let block_gas = Arith.(unsafe_fp (Z.of_int remaining_block_gas)) in + let rec aux context to_consume = + (* Because of saturated arithmetic, [to_consume] should never be negative. *) + assert (Arith.(to_consume >= zero)) ; + if Arith.(to_consume = zero) then return context + else if Arith.(to_consume <= hard_limit) then + consume_gas_limit_in_block_lwt context to_consume + else + consume_gas_limit_in_block_lwt context hard_limit >>=? fun context -> + aux context (Arith.sub to_consume hard_limit) + in + aux context Arith.(sub hard_limit_block block_gas) + +(** Test operation gas exhaustion. Should pass when remaining gas is 0, + and fail when it goes over *) +let test_detect_gas_exhaustion_when_operation_gas_hits_zero () = + let gas_op = 100000 in + dummy_context () >>=? fun context -> + set_gas_limit context (Gas_limit_repr.Arith.unsafe_fp (Z.of_int gas_op)) + |> fun context -> + fail_unless + (consume_gas context (S.safe_int gas_op) |> succeed) + (err "Succeed when consuming exactly the remaining operation gas.") + >>=? fun () -> + fail_unless + (consume_gas context (S.safe_int (gas_op + 1)) |> failed) + (err "Fail when consuming more than the remaining operation gas.") + +(** Test block gas exhaustion *) +let test_detect_gas_exhaustion_when_block_gas_hits_zero () = + let gas k = Gas_limit_repr.Arith.unsafe_fp (Z.of_int k) in + let remaining_gas = gas 100000 and too_much = gas (100000 + 1) in + make_context 100000 >>=? fun context -> + fail_unless + (consume_gas_limit_in_block context remaining_gas |> succeed) + (err "Succeed when consuming exactly the remaining block gas.") + >>=? fun () -> + fail_unless + (consume_gas_limit_in_block context too_much |> failed) + (err "Fail when consuming more than the remaining block gas.") + +(** Test invalid gas limit. Should fail when limit is above the hard gas limit per + operation *) +let test_detect_gas_limit_consumption_above_hard_gas_operation_limit () = + dummy_context () >>=? fun context -> + fail_unless + (consume_gas_limit_in_block + context + (Gas_limit_repr.Arith.unsafe_fp (Z.of_int opg)) + |> failed) + (err + "Fail when consuming gas above the hard limit per operation in the \ + block.") + +(** For a given [context], check if its levels match those given in [block_level] and + [operation_level] *) +let check_context_levels context block_level operation_level = + let op_check = + match gas_level context with + | Unaccounted -> true + | Limited {remaining} -> + Gas_limit_repr.Arith.(unsafe_fp (Z.of_int operation_level) = remaining) + in + let block_check = + Gas_limit_repr.Arith.( + unsafe_fp (Z.of_int block_level) = block_gas_level context) + in + fail_unless + (op_check || block_check) + (err "Unexpected block and operation gas levels") + >>=? fun () -> + fail_unless op_check (err "Unexpected operation gas level") >>=? fun () -> + fail_unless block_check (err "Unexpected block gas level") + +let monitor remaining_block_gas initial_operation_level consumed_gas () = + let op_limit = + Gas_limit_repr.Arith.unsafe_fp (Z.of_int initial_operation_level) + in + make_context remaining_block_gas >>=? fun context -> + consume_gas_limit_in_block_lwt context op_limit >>=? fun context -> + set_gas_limit context op_limit |> fun context -> + consume_gas_lwt context consumed_gas >>=? fun context -> + check_context_levels + context + (remaining_block_gas - initial_operation_level) + (initial_operation_level - consumed_gas) + +let test_monitor_gas_level = monitor 1000 100 10 + +(** Test cas consumption mode switching (limited -> unlimited) *) +let test_set_gas_unlimited () = + let init_block_gas = 100000 in + let op_limit_int = 10000 in + let op_limit = Gas_limit_repr.Arith.unsafe_fp (Z.of_int op_limit_int) in + make_context init_block_gas >>=? fun context -> + set_gas_limit context op_limit |> set_gas_unlimited |> fun context -> + consume_gas_lwt context opg >>=? fun context -> + check_context_levels context init_block_gas (-1) + +(** Test cas consumption mode switching (unlimited -> limited) *) +let test_set_gas_limited () = + let init_block_gas = 100000 in + let op_limit_int = 10000 in + let op_limit = Gas_limit_repr.Arith.unsafe_fp (Z.of_int op_limit_int) in + let op_gas = 100 in + make_context init_block_gas >>=? fun context -> + set_gas_unlimited context |> fun context -> + set_gas_limit context op_limit |> fun context -> + consume_gas_lwt context op_gas >>=? fun context -> + check_context_levels context init_block_gas (op_limit_int - op_gas) + +(*** Tests with blocks ***) + +let apply_with_gas header ?(operations = []) (pred : Block.t) = + let open Alpha_context in + (let open Environment.Error_monad in + begin_application + ~chain_id:Chain_id.zero + ~predecessor_context:pred.context + ~predecessor_fitness:pred.header.shell.fitness + ~predecessor_timestamp:pred.header.shell.timestamp + header + >>=? fun vstate -> + List.fold_left_es + (fun vstate op -> + apply_operation vstate op >|=? fun (state, _result) -> state) + vstate + operations + >>=? fun vstate -> + finalize_block vstate (Some header.shell) >|=? fun (validation, result) -> + (validation.context, result.consumed_gas)) + >|= Environment.wrap_tzresult + >|=? fun (context, consumed_gas) -> + let hash = Block_header.hash header in + ({Block.hash; header; operations; context}, consumed_gas) + +let bake_with_gas ?policy ?timestamp ?operation ?operations pred = + let operations = + match (operation, operations) with + | (Some op, Some ops) -> Some (op :: ops) + | (Some op, None) -> Some [op] + | (None, Some ops) -> Some ops + | (None, None) -> None + in + Block.Forge.forge_header ?timestamp ?policy ?operations pred + >>=? fun header -> + Block.Forge.sign_header header >>=? fun header -> + apply_with_gas header ?operations pred + +let check_consumed_gas consumed expected = + fail_unless + Alpha_context.Gas.Arith.(consumed = expected) + (err + (Format.asprintf + "Gas discrepancy: consumed gas : %a | expected : %a\n" + Alpha_context.Gas.Arith.pp + consumed + Alpha_context.Gas.Arith.pp + expected)) + +let lazy_unit = Alpha_context.Script.lazy_expr (Expr.from_string "Unit") + +let prepare_origination block source script = + let code = Expr.toplevel_from_string script in + let script = + Alpha_context.Script.{code = lazy_expr code; storage = lazy_unit} + in + Op.origination (B block) source ~script + +let originate_contract block source script = + prepare_origination block source script >>=? fun (operation, dst) -> + Block.bake ~operation block >>=? fun block -> return (block, dst) + +let init_block to_originate = + Context.init ~consensus_threshold:0 1 >>=? fun (block, contracts) -> + let src = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + (*** originate contracts ***) + let rec full_originate block originated = function + | [] -> return (block, List.rev originated) + | h :: t -> + originate_contract block src h >>=? fun (block, ct) -> + full_originate block (ct :: originated) t + in + full_originate block [] to_originate >>=? fun (block, originated) -> + return (block, src, originated) + +let nil_contract = + "parameter unit;\n\ + storage unit;\n\ + code {\n\ + \ DROP;\n\ + \ UNIT; NIL operation; PAIR\n\ + \ }\n" + +let fail_contract = "parameter unit; storage unit; code { FAIL }" + +let loop_contract = + "parameter unit;\n\ + storage unit;\n\ + code {\n\ + \ DROP;\n\ + \ PUSH bool True;\n\ + \ LOOP {\n\ + \ PUSH string \"GASGASGAS\";\n\ + \ PACK;\n\ + \ SHA3;\n\ + \ DROP;\n\ + \ PUSH bool True\n\ + \ };\n\ + \ UNIT; NIL operation; PAIR\n\ + \ }\n" + +let block_with_one_origination contract = + init_block [contract] >>=? fun (block, src, originated) -> + match originated with [dst] -> return (block, src, dst) | _ -> assert false + +let full_block () = + init_block [nil_contract; fail_contract; loop_contract] + >>=? fun (block, src, originated) -> + let (dst_nil, dst_fail, dst_loop) = + match originated with [c1; c2; c3] -> (c1, c2, c3) | _ -> assert false + in + return (block, src, dst_nil, dst_fail, dst_loop) + +(** Combine a list of operations into an operation list. Also returns + the sum of their gas limits.*) +let combine_operations_with_gas ?counter block src list_dst = + let rec make_op_list full_gas op_list = function + | [] -> return (full_gas, List.rev op_list) + | (dst, gas_limit) :: t -> + Op.transaction ~gas_limit (B block) src dst Alpha_context.Tez.zero + >>=? fun op -> + make_op_list + (Alpha_context.Gas.Arith.add full_gas gas_limit) + (op :: op_list) + t + in + make_op_list Alpha_context.Gas.Arith.zero [] list_dst + >>=? fun (full_gas, op_list) -> + Op.combine_operations ?counter ~source:src (B block) op_list + >>=? fun operation -> return (operation, full_gas) + +(** Applies [combine_operations_with_gas] to lists in a list, then bake a block + with this list of operations. Also returns the sum of all gas limits *) +let bake_operations_with_gas ?counter block src list_list_dst = + let counter = Option.value ~default:Z.zero counter in + let rec make_list full_gas op_list counter = function + | [] -> return (full_gas, List.rev op_list) + | list_dst :: t -> + let n = Z.of_int (List.length list_dst) in + combine_operations_with_gas ~counter block src list_dst + >>=? fun (op, gas) -> + make_list + (Alpha_context.Gas.Arith.add full_gas gas) + (op :: op_list) + (Z.add counter n) + t + in + make_list Alpha_context.Gas.Arith.zero [] counter list_list_dst + >>=? fun (gas_limit_total, operations) -> + bake_with_gas ~operations block >>=? fun (block, consumed_gas) -> + return (block, consumed_gas, gas_limit_total) + +let basic_gas_sampler () = + Alpha_context.Gas.Arith.integral_of_int_exn (100 + Random.int 900) + +let generic_test_block_one_origination contract gas_sampler structure = + block_with_one_origination contract >>=? fun (block, src, dst) -> + let lld = List.map (List.map (fun _ -> (dst, gas_sampler ()))) structure in + bake_operations_with_gas ~counter:Z.one block src lld + >>=? fun (_block, consumed_gas, gas_limit_total) -> + check_consumed_gas consumed_gas gas_limit_total + +let make_batch_test_block_one_origination name contract gas_sampler = + let test = generic_test_block_one_origination contract gas_sampler in + let test_one_operation () = test [[()]] in + let test_one_operation_list () = test [[(); (); ()]] in + let test_many_single_operations () = test [[()]; [()]; [()]] in + let test_mixed_operations () = test [[(); ()]; [()]; [(); (); ()]] in + let app_n = List.map (fun (x, y) -> (x ^ " with contract " ^ name, y)) in + app_n + [ + ("Test bake one operation", test_one_operation); + ("Test bake one operation list", test_one_operation_list); + ("Test multiple single operations", test_many_single_operations); + ("Test both lists and single operations", test_mixed_operations); + ] + +(** Tests the consumption of all gas in a block, should pass *) +let test_consume_exactly_all_block_gas () = + block_with_one_origination nil_contract >>=? fun (block, src, dst) -> + (* assumptions: + hard gas limit per operation = 1040000 + hard gas limit per block = 5200000 + *) + let lld = + List.map + (fun _ -> [(dst, Alpha_context.Gas.Arith.integral_of_int_exn 1040000)]) + [1; 1; 1; 1; 1] + in + bake_operations_with_gas ~counter:Z.one block src lld >>=? fun _ -> return () + +(** Tests the consumption of more than the block gas level with many single + operations, should fail *) +let test_malformed_block_max_limit_reached () = + block_with_one_origination nil_contract >>=? fun (block, src, dst) -> + (* assumptions: + hard gas limit per operation = 1040000 + hard gas limit per block = 5200000 + *) + let lld = + [(dst, Alpha_context.Gas.Arith.integral_of_int_exn 1)] + :: + List.map + (fun _ -> [(dst, Alpha_context.Gas.Arith.integral_of_int_exn 1040000)]) + [1; 1; 1; 1; 1] + in + bake_operations_with_gas ~counter:Z.one block src lld >>= function + | Error _ -> return_unit + | Ok _ -> + fail + (err + "Invalid block: sum of operation gas limits exceeds hard gas limit \ + per block") + +(** Tests the consumption of more than the block gas level with one big + operation list, should fail *) +let test_malformed_block_max_limit_reached' () = + block_with_one_origination nil_contract >>=? fun (block, src, dst) -> + (* assumptions: + hard gas limit per operation = 1040000 + hard gas limit per block = 5200000 + *) + let lld = + [ + (dst, Alpha_context.Gas.Arith.integral_of_int_exn 1) + :: + List.map + (fun _ -> (dst, Alpha_context.Gas.Arith.integral_of_int_exn 1040000)) + [1; 1; 1; 1; 1]; + ] + in + bake_operations_with_gas ~counter:Z.one block src lld >>= function + | Error _ -> return_unit + | Ok _ -> + fail + (err + "Invalid block: sum of gas limits in operation list exceeds hard \ + gas limit per block") + +let test_block_mixed_operations () = + full_block () >>=? fun (block, src, dst_nil, dst_fail, dst_loop) -> + let l = [[dst_nil]; [dst_nil; dst_fail; dst_nil]; [dst_loop]; [dst_nil]] in + let lld = List.map (List.map (fun x -> (x, basic_gas_sampler ()))) l in + bake_operations_with_gas ~counter:(Z.of_int 3) block src lld + >>=? fun (_block, consumed_gas, gas_limit_total) -> + check_consumed_gas consumed_gas gas_limit_total + +let quick (what, how) = Tztest.tztest what `Quick how + +let tests = + List.map + quick + ([ + ( "Detect gas exhaustion in fresh context", + test_detect_gas_exhaustion_in_fresh_context ); + ( "Detect gas exhaustion when operation gas as hits zero", + test_detect_gas_exhaustion_when_operation_gas_hits_zero ); + ( "Detect gas exhaustion when block gas as hits zero", + test_detect_gas_exhaustion_when_block_gas_hits_zero ); + ( "Detect gas limit consumption when it is above the hard gas operation \ + limit", + test_detect_gas_limit_consumption_above_hard_gas_operation_limit ); + ( "Each new operation impacts block gas level, each gas consumption \ + impacts operation gas level", + test_monitor_gas_level ); + ( "Switches operation gas consumption from limited to unlimited", + test_set_gas_unlimited ); + ( "Switches operation gas consumption from unlimited to limited", + test_set_gas_limited ); + ( "Accepts a block that consumes all of its gas", + test_consume_exactly_all_block_gas ); + ( "Detect when the sum of all operation gas limits exceeds the hard gas \ + limit per block", + test_malformed_block_max_limit_reached ); + ( "Detect when gas limit of operation list exceeds the hard gas limit \ + per block", + test_malformed_block_max_limit_reached' ); + ( "Test the gas consumption of various operations", + test_block_mixed_operations ); + ] + @ make_batch_test_block_one_origination "nil" nil_contract basic_gas_sampler + @ make_batch_test_block_one_origination + "fail" + fail_contract + basic_gas_sampler + @ make_batch_test_block_one_origination + "infinite loop" + loop_contract + basic_gas_sampler) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_gas_properties.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_gas_properties.ml new file mode 100644 index 000000000000..9e0c1a32c05d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_gas_properties.ml @@ -0,0 +1,139 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (gas properties) + Invocation: dune exec src/proto_alpha/lib_protocol/test/test_gas_properties.exe + Subject: Arithmetic properties around gas. +*) + +open Protocol +open Lib_test.Qcheck_helpers + +(** Extract a Tezos result for compatibility with QCheck. *) +let extract_qcheck_result = function + | Ok pure_result -> pure_result + | Error err -> + Format.printf "@\n%a@." Environment.Error_monad.pp_trace err ; + false + +(** [Gas.free] is the neutral element of gas addition: [any_cost +@ Gas.free = Gas.free +@ any_cost = any_cost]. *) +let test_free_neutral (start, any_cost) = + let open Alpha_context in + extract_qcheck_result + ( Gas.consume start Gas.free >>? fun free_first -> + Gas.consume free_first any_cost >>? fun branch1 -> + Gas.consume start any_cost >>? fun cost_first -> + Gas.consume cost_first Gas.free >|? fun branch2 -> + let equal_consumption_from_start t1 t2 = + Gas.Arith.( + qcheck_eq + ~pp + ~eq:equal + (Gas.consumed ~since:start ~until:t1) + (Gas.consumed ~since:start ~until:t2)) + in + equal_consumption_from_start branch1 branch2 + && equal_consumption_from_start branch1 cost_first ) + +(** Consuming [Gas.free] is equivalent to consuming nothing. *) +let test_free_consumption start = + let open Alpha_context in + extract_qcheck_result + ( Gas.consume start Gas.free >|? fun after_empty_consumption -> + Gas.Arith.( + qcheck_eq + ~pp + ~eq:equal + (Gas.consumed ~since:start ~until:after_empty_consumption) + zero) ) + +(** Consuming [cost1] then [cost2] is equivalent to consuming + [Gas.(cost1 +@ cost2)]. *) +let test_consume_commutes (start, cost1, cost2) = + let open Alpha_context in + extract_qcheck_result + ( Gas.consume start cost1 >>? fun after_cost1 -> + Gas.consume after_cost1 cost2 >>? fun branch1 -> + Gas.consume start Gas.(cost1 +@ cost2) >|? fun branch2 -> + Gas.Arith.( + qcheck_eq + ~pp + ~eq:equal + (Gas.consumed ~since:start ~until:branch1) + (Gas.consumed ~since:start ~until:branch2)) ) + +(** Arbitrary context with a gas limit of 100_000_000. *) +let context_arb : Alpha_context.t QCheck.arbitrary = + QCheck.always + (Lwt_main.run + ( Context.init 1 >>=? fun (b, _contracts) -> + Incremental.begin_construction b >|=? fun inc -> + let state = Incremental.validation_state inc in + Alpha_context.Gas.set_limit + state.ctxt + Alpha_context.Gas.Arith.(fp (integral_of_int_exn 100_000_000)) ) + |> function + | Ok a -> a + | Error _ -> assert false) + +(** This arbitrary could be improved (pretty printer and shrinker) if there was a way to convert a [cost] back to an [int]. Otherwise one needs to write a custom [arbitrary] instance, but I wanted to stick to the former design of this test for the time being. *) +let gas_cost_arb : Alpha_context.Gas.cost QCheck.arbitrary = + let open Alpha_context.Gas in + let open QCheck in + let rand = 0 -- 1000 in + let safe_rand = map Saturation_repr.safe_int rand in + choose + [ + map atomic_step_cost safe_rand; + map step_cost safe_rand; + map alloc_cost safe_rand; + map alloc_bytes_cost rand; + map alloc_mbytes_cost rand; + map read_bytes_cost rand; + map write_bytes_cost rand; + ] + +let tests = + [ + QCheck.Test.make + ~count:1000 + ~name:"Consuming commutes" + QCheck.(triple context_arb gas_cost_arb gas_cost_arb) + test_consume_commutes; + QCheck.Test.make + ~count:1000 + ~name:"Consuming [free] consumes nothing" + context_arb + test_free_consumption; + QCheck.Test.make + ~count:1000 + ~name:"[free] is the neutral element of Gas addition" + QCheck.(pair context_arb gas_cost_arb) + test_free_neutral; + ] + +let () = Alcotest.run "gas properties" [("gas properties", qcheck_wrap tests)] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_global_constants_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_global_constants_storage.ml new file mode 100644 index 000000000000..e9c1f74cefc7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_global_constants_storage.ml @@ -0,0 +1,138 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +open Protocol +open Alpha_context +open Test_transfer + +(** Testing + ------- + Component: Protocol (global table of constants) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ + -- test "^global table of constants$" + Subject: This module tests that the global table of constants + can be written to and read from across blocks. +*) + +let get_next_context b = + Incremental.begin_construction b >>=? fun b -> + return (Incremental.alpha_ctxt b) + +let assert_expr_equal loc = + Assert.equal + ~loc + ( = ) + "Michelson Expressions Not Equal" + Michelson_v1_printer.print_expr + +let assert_proto_error_id loc id result = + let test err = + (Error_monad.find_info_of_error err).id + = "proto." ^ Protocol.name ^ "." ^ id + in + Assert.error ~loc result test + +let expr_to_hash expr = + let lexpr = Script_repr.lazy_expr @@ Expr.from_string expr in + Script_repr.force_bytes lexpr >|? fun b -> Script_expr_hash.hash_bytes [b] + +(* This test has a long wind-up, but is very simple: it just asserts + that values written to the global table of constants persist across + blocks. *) +let get_happy_path () = + register_two_contracts () >>=? fun (b, alice, bob) -> + Incremental.begin_construction b >>=? fun b -> + let expr_str = "Pair 3 7" in + let expr = Expr.from_string expr_str in + Environment.wrap_tzresult @@ expr_to_hash expr_str >>?= fun hash -> + Op.register_global_constant + (I b) + ~source:alice + ~value:(Script_repr.lazy_expr expr) + >>=? fun op -> + Incremental.add_operation b op >>=? fun b -> + Incremental.finalize_block b >>=? fun b -> + let assert_unchanged b = + get_next_context b >>=? fun context -> + Global_constants_storage.get context hash >|= Environment.wrap_tzresult + >>=? fun (_, result_expr) -> + assert_expr_equal __LOC__ expr result_expr >|=? fun _ -> b + in + assert_unchanged b >>=? fun b -> + let do_many_transfers b = + Incremental.begin_construction b >>=? fun b -> + n_transactions 10 b alice bob (Tez.of_mutez_exn 1000L) >>=? fun b -> + Incremental.finalize_block b >>=? fun b -> assert_unchanged b + in + do_many_transfers b >>=? do_many_transfers >>=? do_many_transfers >>= fun _ -> + Lwt.return_ok () + +(* Blocks that include a registration of a bad expression should + fail. *) +let test_registration_of_bad_expr_fails () = + register_two_contracts () >>=? fun (b, alice, _) -> + Incremental.begin_construction b >>=? fun b -> + (* To produce the failure, we attempt to register an expression with + a malformed hash. *) + let expr = Expr.from_string "Pair 1 (constant \"foo\")" in + Op.register_global_constant + (I b) + ~source:alice + ~value:(Script_repr.lazy_expr expr) + >>=? fun op -> + Incremental.add_operation b op + >>= assert_proto_error_id __LOC__ "Badly_formed_constant_expression" + +(* You cannot register the same expression twice. *) +let test_no_double_register () = + register_two_contracts () >>=? fun (b, alice, _) -> + Incremental.begin_construction b >>=? fun b -> + let expr = Expr.from_string "Pair 1 2" in + Op.register_global_constant + (I b) + ~source:alice + ~value:(Script_repr.lazy_expr expr) + >>=? fun op -> + Incremental.add_operation b op >>=? fun b -> + (* Register the same expression again *) + Op.register_global_constant + (I b) + ~source:alice + ~value:(Script_repr.lazy_expr expr) + >>=? fun op -> + Incremental.add_operation b op + >>= assert_proto_error_id __LOC__ "Expression_already_registered" + +let tests = + [ + Tztest.tztest "Multiple blocks happy path" `Quick get_happy_path; + Tztest.tztest + "Bad register global operations fail when added to the block" + `Quick + test_registration_of_bad_expr_fails; + Tztest.tztest + "You cannot register the same expression twice." + `Quick + test_no_double_register; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_helpers_rpcs.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_helpers_rpcs.ml new file mode 100644 index 000000000000..392da059c317 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_helpers_rpcs.ml @@ -0,0 +1,69 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020-2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (Helpers RPCs) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^helpers rpcs$" + Subject: On RPCs. +*) + +open Protocol +open Alpha_context + +(* Test the baking_rights RPC. + Future levels or cycles are not tested because it's hard in this framework, + using only RPCs, to fabricate them. *) +let test_baking_rights () = + Context.init 2 >>=? fun (b, contracts) -> + let open Plugin.RPC.Baking_rights in + (* default max_round returns 65 results *) + get Block.rpc_ctxt b ~all:true >>=? fun rights -> + assert (Compare.List_length_with.(rights = 65)) ; + (* arbitrary max_round *) + let max_round = 15 in + get Block.rpc_ctxt b ~all:true ~max_round >>=? fun rights -> + assert (Compare.List_length_with.(rights = max_round + 1)) ; + (* filtering by delegate *) + let d = + Option.bind (List.nth contracts 0) Contract.is_implicit + |> WithExceptions.Option.get ~loc:__LOC__ + in + get Block.rpc_ctxt b ~all:true ~delegates:[d] >>=? fun rights -> + assert (List.for_all (fun {delegate; _} -> delegate = d) rights) ; + (* filtering by cycle *) + Plugin.RPC.current_level Block.rpc_ctxt b >>=? fun {cycle; _} -> + get Block.rpc_ctxt b ~all:true ~cycle >>=? fun rights -> + Plugin.RPC.levels_in_current_cycle Block.rpc_ctxt b >>=? fun (first, last) -> + assert ( + List.for_all (fun {level; _} -> level >= first && level <= last) rights) ; + (* filtering by level *) + Plugin.RPC.current_level Block.rpc_ctxt b >>=? fun {level; _} -> + get Block.rpc_ctxt b ~all:true ~levels:[level] >>=? fun rights -> + let expected_level = level in + assert (List.for_all (fun {level; _} -> level = expected_level) rights) ; + return_unit + +let tests = [Tztest.tztest "baking_rights" `Quick test_baking_rights] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_interpretation.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_interpretation.ml new file mode 100644 index 000000000000..5fce6966082b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_interpretation.ml @@ -0,0 +1,304 @@ +(** Testing + ------- + Component: Protocol (interpretation) + Dependencies: src/proto_alpha/lib_protocol/script_interpreter.ml + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^interpretation$" + Subject: Interpretation of Michelson scripts +*) + +open Protocol +open Alpha_context +open Script_interpreter +open Error_monad_operators + +let test_context () = + Context.init 3 >>=? fun (b, _cs) -> + Incremental.begin_construction b >>=? fun v -> + return (Incremental.alpha_ctxt v) + +let logger = + Script_typed_ir. + { + log_interp = (fun _ _ _ _ _ -> ()); + log_entry = (fun _ _ _ _ _ -> ()); + log_exit = (fun _ _ _ _ _ -> ()); + log_control = (fun _ -> ()); + get_log = (fun () -> Lwt.return (Ok None)); + } + +let run_step ctxt code accu stack = + let open Script_interpreter in + let open Contract_helpers in + step None ctxt default_step_constants code accu stack + >>=? fun ((_, _, ctxt') as r) -> + step (Some logger) ctxt default_step_constants code accu stack + >>=? fun (_, _, ctxt'') -> + if Gas.(remaining_operation_gas ctxt' <> remaining_operation_gas ctxt'') then + Alcotest.failf "Logging should not have an impact on gas consumption." ; + return r + +(** Runs a script with an ill-typed parameter and verifies that a + Bad_contract_parameter error is returned. *) +let test_bad_contract_parameter () = + test_context () >>=? fun ctx -> + (* Run script with a parameter of wrong type *) + Contract_helpers.run_script + ctx + "{parameter unit; storage unit; code { CAR; NIL operation; PAIR }}" + ~storage:"Unit" + ~parameter:"0" + () + >>= function + | Ok _ -> Alcotest.fail "expected an error" + | Error (Environment.Ecoproto_error (Bad_contract_parameter source') :: _) -> + Alcotest.(check Testable.contract) + "incorrect field in Bad_contract_parameter" + Contract_helpers.default_source + source' ; + return_unit + | Error errs -> + Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs + +let test_multiplication_close_to_overflow_passes () = + test_context () >>=? fun ctx -> + (* Get sure that multiplication deals with numbers between 2^62 and + 2^63 without overflowing *) + Contract_helpers.run_script + ctx + "{parameter unit;storage unit;code {DROP; PUSH mutez 2944023901536524477; \ + PUSH nat 2; MUL; DROP; UNIT; NIL operation; PAIR}}" + ~storage:"Unit" + ~parameter:"Unit" + () + >>= function + | Ok _ -> return_unit + | Error errs -> + Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs + +let read_file filename = + let ch = open_in filename in + let s = really_input_string ch (in_channel_length ch) in + close_in ch ; + s + +(** The purpose of these two tests is to check that the Michelson interpreter is + stack-safe (because it is tail-recursive). + + This requires to confront it to deep recursions, typically deeper than what + the gas limit allows. Unfortunately we cannot run the interpreter in + unaccounted gas mode because for efficiency it uses a custom gas management + that represents the gas counter as a mere integer. Instead we set the gas + counter to the highest possible value ([Saturation_repr.saturated]); with + the current gas costs and limits this enables more than a million recursive + calls which is larger than the stack size. *) + +let test_stack_overflow () = + let open Script_typed_ir in + test_context () >>=? fun ctxt -> + (* Set the gas counter to the maximum value *) + let ctxt = + Gas.update_remaining_operation_gas ctxt Saturation_repr.saturated + in + let stack = Bot_t in + let descr kinstr = {kloc = 0; kbef = stack; kaft = stack; kinstr} in + let kinfo = {iloc = -1; kstack_ty = stack} in + let kinfo' = + {iloc = -1; kstack_ty = Item_t (bool_t ~annot:None, stack, None)} + in + let enorme_et_seq n = + let rec aux n acc = + if n = 0 then acc + else aux (n - 1) (IConst (kinfo, true, IDrop (kinfo', acc))) + in + aux n (IHalt kinfo) + in + run_step ctxt (descr (enorme_et_seq 1_000_000)) EmptyCell EmptyCell + >>= function + | Ok _ -> return_unit + | Error trace -> + let trace_string = + Format.asprintf "%a" Environment.Error_monad.pp_trace trace + in + Alcotest.failf "Unexpected error (%s) at %s" trace_string __LOC__ + +(** The stack-safety of the interpreter relies a lot on the stack-safety of + Lwt.bind. This second test is similar to the previous one but uses an + instruction (IBig_map_mem) for which the interpreter calls Lwt.bind. *) + +let test_stack_overflow_in_lwt () = + let open Script_typed_ir in + test_context () >>=? fun ctxt -> + let ctxt = + Gas.update_remaining_operation_gas ctxt Saturation_repr.saturated + in + let stack = Bot_t in + let item ty s = Item_t (ty, s, None) in + let unit_t = unit_t ~annot:None in + let unit_k = unit_key ~annot:None in + let bool_t = bool_t ~annot:None in + big_map_t (-1) unit_k unit_t ~annot:None >>??= fun big_map_t -> + let descr kinstr = {kloc = 0; kbef = stack; kaft = stack; kinstr} in + let kinfo s = {iloc = -1; kstack_ty = s} in + let stack1 = item big_map_t Bot_t in + let stack2 = item big_map_t (item big_map_t Bot_t) in + let stack3 = item unit_t stack2 in + let stack4 = item bool_t stack1 in + let push_empty_big_map k = IEmpty_big_map (kinfo stack, unit_k, unit_t, k) in + let large_mem_seq n = + let rec aux n acc = + if n = 0 then acc + else + aux + (n - 1) + (IDup + ( kinfo stack1, + IConst + ( kinfo stack2, + (), + IBig_map_mem (kinfo stack3, IDrop (kinfo stack4, acc)) ) )) + in + aux n (IDrop (kinfo stack1, IHalt (kinfo stack))) + in + let script = push_empty_big_map (large_mem_seq 1_000_000) in + run_step ctxt (descr script) EmptyCell EmptyCell >>= function + | Ok _ -> return_unit + | Error trace -> + let trace_string = + Format.asprintf "%a" Environment.Error_monad.pp_trace trace + in + Alcotest.failf "Unexpected error (%s) at %s" trace_string __LOC__ + +(** Test the encoding/decoding of script_interpreter.ml specific errors *) +let test_json_roundtrip name testable enc v = + let v' = + Data_encoding.Json.destruct enc (Data_encoding.Json.construct enc v) + in + Alcotest.check + testable + (Format.asprintf "round trip should not change value of %s" name) + v + v' ; + return_unit + +(** Encoding/decoding of script_interpreter.ml specific errors. *) +let test_json_roundtrip_err name e () = + test_json_roundtrip + name + Testable.protocol_error + Environment.Error_monad.error_encoding + e + +let error_encoding_tests = + let contract_zero = + Contract.implicit_contract Signature.Public_key_hash.zero + in + let script_expr_int = Micheline.strip_locations (Micheline.Int (0, Z.zero)) in + List.map + (fun (name, e) -> + Tztest.tztest + (Format.asprintf "test error encoding: %s" name) + `Quick + (test_json_roundtrip_err name e)) + [ + ("Reject", Reject (0, script_expr_int, None)); + ("Overflow", Overflow (0, None)); + ( "Runtime_contract_error", + Runtime_contract_error (contract_zero, script_expr_int) ); + ("Bad_contract_parameter", Bad_contract_parameter contract_zero); + ("Cannot_serialize_failure", Cannot_serialize_failure); + ("Cannot_serialize_storage", Cannot_serialize_storage); + ] + +module Test_map_instr_on_options = struct + type storage = {prev : int option; total : int} + + (* storage: (last input * total); param replaces the last input and + if some – gets added to the total. *) + let test_map_option_script = + {| { parameter (option int); + storage (pair (option int) int); + code { + UNPAIR ; + DIP { CDR } ; + MAP { + DUP ; + DIP { ADD } ; + } ; + PAIR ; + NIL operation ; + PAIR ; + } + } |} + + let run_test_map_opt_script param {prev; total} = + let storage = + Option.fold + ~none:(Format.sprintf "Pair None %d" total) + ~some:(fun p -> Format.sprintf "Pair (Some %d) %d" p total) + prev + in + let parameter = + Option.fold ~none:"None" ~some:(Format.sprintf "Some %d") param + in + test_context () >>=? fun ctxt -> + Contract_helpers.run_script + ctxt + test_map_option_script + ~storage + ~parameter + () + + let assume_storage_shape = + let open Micheline in + let open Michelson_v1_primitives in + function + | Prim (_, D_Pair, [Prim (_, D_None, [], _); Int (_, total)], _) -> + {prev = None; total = Z.to_int total} + | Prim (_, D_Pair, [Prim (_, D_Some, [Int (_, prev)], _); Int (_, total)], _) + -> + {prev = Some (Z.to_int prev); total = Z.to_int total} + | _ -> QCheck.assume_fail () + + let assertions storage_before storage_after = function + | None -> + Assert.is_none ~loc:__LOC__ ~pp:Format.pp_print_int storage_after.prev + >>=? fun () -> + Assert.equal_int ~loc:__LOC__ storage_before.total storage_after.total + | Some input -> + Assert.get_some ~loc:__LOC__ storage_after.prev >>=? fun prev_aft -> + Assert.equal_int ~loc:__LOC__ input prev_aft >>=? fun () -> + Assert.equal_int + ~loc:__LOC__ + (storage_before.total + input) + storage_after.total + + let test_mapping (input, prev, total) = + let storage_before = {prev; total} in + run_test_map_opt_script input storage_before >>=? fun ({storage; _}, _) -> + let new_storage = assume_storage_shape (Micheline.root storage) in + assertions storage_before new_storage input +end + +let tests = + [ + Tztest.tztest "test bad contract error" `Quick test_bad_contract_parameter; + Tztest.tztest "check robustness overflow error" `Slow test_stack_overflow; + Tztest.tztest + "check robustness overflow error in lwt" + `Slow + test_stack_overflow_in_lwt; + Tztest.tztest + "test multiplication no illegitimate overflow" + `Quick + test_multiplication_close_to_overflow_passes; + Tztest.tztest "test stack overflow error" `Slow test_stack_overflow; + Tztest.tztest_qcheck + ~name:"test map instr against options" + QCheck.( + triple + (option small_signed_int) + (option small_signed_int) + small_signed_int) + Test_map_instr_on_options.test_mapping; + ] + @ error_encoding_tests diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_lazy_storage_diff.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_lazy_storage_diff.ml new file mode 100644 index 000000000000..cd55c3228f92 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_lazy_storage_diff.ml @@ -0,0 +1,141 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol + +(** Generation of input data *) + +let ids = + [|1; 42; 1337; 1984|] |> Array.map Z.of_int + |> Array.map Lazy_storage_kind.Big_map.Id.parse_z + +let strs = [|"0"; "True"; "nat"; "bool"|] + +let exprs = strs |> Array.map Expr.from_string + +let hashes = + strs |> Array.map (fun x -> [x]) |> Array.map Script_expr_hash.hash_string + +let updates_len_existing = [1; 2; 3] + +let updates_len_other = 0 :: updates_len_existing + +let gen_inits idx : + (( Lazy_storage_kind.Big_map.Id.t, + Lazy_storage_kind.Big_map.alloc ) + Lazy_storage_diff.init + * int list) + list = + [ + (Existing, updates_len_existing); + (Copy {src = ids.(idx - 1)}, updates_len_other); + ( Alloc {key_type = exprs.(idx); value_type = exprs.(idx - 1)}, + updates_len_other ); + ] + +let gen_update_list idx : Lazy_storage_kind.Big_map.update list = + [None; Some exprs.(idx)] + |> List.map (fun value -> + Lazy_storage_kind.Big_map. + {key = exprs.(idx); key_hash = hashes.(idx); value}) + +let rec gen_updates updates_len : Lazy_storage_kind.Big_map.updates list = + if updates_len = 0 then [] + else + gen_updates (updates_len - 1) + |> List.map (fun suffix -> + gen_update_list updates_len + |> List.map (fun prefix -> prefix :: suffix)) + |> List.flatten + +let gen_updates_list updates_lens : Lazy_storage_kind.Big_map.updates list = + updates_lens |> List.map gen_updates |> List.flatten + +let gen_diffs idx : + ( Lazy_storage_kind.Big_map.Id.t, + Lazy_storage_kind.Big_map.alloc, + Lazy_storage_kind.Big_map.updates ) + Lazy_storage_diff.diff + list = + let open Lazy_storage_diff in + Remove + :: + (gen_inits idx + |> List.map (fun (init, updates_lens) -> + gen_updates_list updates_lens + |> List.map (fun updates -> Update {init; updates})) + |> List.flatten) + +let gen_diffs_items idx : Lazy_storage_diff.diffs_item list = + let id = ids.(idx) in + gen_diffs idx |> List.map (fun diff -> Lazy_storage_diff.make Big_map id diff) + +let rec gen_diffs_list len : Lazy_storage_diff.diffs list = + if len = 0 then [] + else + gen_diffs_list (len - 1) + |> List.map (fun suffix -> + gen_diffs_items len |> List.map (fun prefix -> prefix :: suffix)) + |> List.flatten + +let diffs_list_lens = [0; 1; 2; 3] + +let diffs_list : Lazy_storage_diff.diffs list = + diffs_list_lens |> List.map gen_diffs_list |> List.flatten + +(** Properties to check *) + +let conversion_roundtrip lazy_storage_diff = + let legacy_big_map_diff = + Contract_storage.Legacy_big_map_diff.of_lazy_storage_diff lazy_storage_diff + in + let reconverted = + Contract_storage.Legacy_big_map_diff.to_lazy_storage_diff + legacy_big_map_diff + in + assert (Stdlib.( = ) reconverted lazy_storage_diff) + +let encoding_roundtrip lazy_storage_diff = + let encoded = + Data_encoding.Binary.to_bytes_exn + Lazy_storage_diff.encoding + lazy_storage_diff + in + match Data_encoding.Binary.of_bytes Lazy_storage_diff.encoding encoded with + | Ok decoded -> assert (Stdlib.( = ) decoded lazy_storage_diff) + | Error _ -> Stdlib.failwith "Decoding failed" + +(** Iterator and test definitions *) + +let on_diffs f () = + List.iter f diffs_list ; + return_unit + +(* Marked Slow because they take 5 to 10 seconds and are unlikely to change *) +let tests = + [ + Tztest.tztest "conversion roundtrip" `Slow (on_diffs conversion_roundtrip); + Tztest.tztest "encoding roundtrip" `Slow (on_diffs encoding_roundtrip); + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_level_module.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_level_module.ml new file mode 100644 index 000000000000..64546a24a264 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_level_module.ml @@ -0,0 +1,275 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (baking) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^level module$" + Subject: some functions in the Level module +*) + +open Protocol + +let test_create_cycle_eras () = + let empty_cycle_eras = + Level_repr.create_cycle_eras [] |> Environment.wrap_tzresult + in + Assert.proto_error ~loc:__LOC__ empty_cycle_eras (function + | Level_repr.Invalid_cycle_eras -> true + | _ -> false) + >>=? fun () -> + let increasing_first_levels = + [ + Level_repr. + { + first_level = Raw_level_repr.of_int32_exn 1l; + first_cycle = Cycle_repr.succ Cycle_repr.root; + blocks_per_cycle = 8l; + blocks_per_commitment = 2l; + }; + { + first_level = Raw_level_repr.of_int32_exn 9l; + first_cycle = Cycle_repr.root; + blocks_per_cycle = 8l; + blocks_per_commitment = 2l; + }; + ] + |> Level_repr.create_cycle_eras |> Environment.wrap_tzresult + in + Assert.proto_error ~loc:__LOC__ increasing_first_levels (function + | Level_repr.Invalid_cycle_eras -> true + | _ -> false) + >>=? fun () -> + let increasing_first_cycles = + [ + Level_repr. + { + first_level = Raw_level_repr.of_int32_exn 9l; + first_cycle = Cycle_repr.root; + blocks_per_cycle = 8l; + blocks_per_commitment = 2l; + }; + { + first_level = Raw_level_repr.of_int32_exn 1l; + first_cycle = Cycle_repr.succ Cycle_repr.root; + blocks_per_cycle = 8l; + blocks_per_commitment = 2l; + }; + ] + |> Level_repr.create_cycle_eras |> Environment.wrap_tzresult + in + Assert.proto_error ~loc:__LOC__ increasing_first_cycles (function + | Level_repr.Invalid_cycle_eras -> true + | _ -> false) + +let test_case_1 = + ( [ + Level_repr. + { + first_level = Raw_level_repr.of_int32_exn 1l; + first_cycle = Cycle_repr.root; + blocks_per_cycle = 8l; + blocks_per_commitment = 2l; + }; + ], + [ + (1, (1, 0, 0, 0, false)); + (2, (2, 1, 0, 1, true)); + (3, (3, 2, 0, 2, false)); + (8, (8, 7, 0, 7, true)); + (9, (9, 8, 1, 0, false)); + (16, (16, 15, 1, 7, true)); + (17, (17, 16, 2, 0, false)); + (64, (64, 63, 7, 7, true)); + (65, (65, 64, 8, 0, false)); + ] ) + +let test_case_2 = + ( List.rev + [ + Level_repr. + { + first_level = Raw_level_repr.of_int32_exn 1l; + first_cycle = Cycle_repr.root; + blocks_per_cycle = 8l; + blocks_per_commitment = 2l; + }; + { + first_level = Raw_level_repr.of_int32_exn 17l; + first_cycle = Cycle_repr.of_int32_exn 2l; + blocks_per_cycle = 16l; + blocks_per_commitment = 4l; + }; + ], + [ + (1, (1, 0, 0, 0, false)); + (2, (2, 1, 0, 1, true)); + (3, (3, 2, 0, 2, false)); + (8, (8, 7, 0, 7, true)); + (9, (9, 8, 1, 0, false)); + (16, (16, 15, 1, 7, true)); + (17, (17, 16, 2, 0, false)); + (32, (32, 31, 2, 15, true)); + (33, (33, 32, 3, 0, false)); + (64, (64, 63, 4, 15, true)); + (65, (65, 64, 5, 0, false)); + ] ) + +let test_case_3 = + ( List.rev + [ + Level_repr. + { + first_level = Raw_level_repr.of_int32_exn 1l; + first_cycle = Cycle_repr.root; + blocks_per_cycle = 8l; + blocks_per_commitment = 2l; + }; + { + first_level = Raw_level_repr.of_int32_exn 17l; + first_cycle = Cycle_repr.of_int32_exn 2l; + blocks_per_cycle = 16l; + blocks_per_commitment = 4l; + }; + { + first_level = Raw_level_repr.of_int32_exn 49l; + first_cycle = Cycle_repr.of_int32_exn 4l; + blocks_per_cycle = 6l; + blocks_per_commitment = 3l; + }; + ], + [ + (1, (1, 0, 0, 0, false)); + (2, (2, 1, 0, 1, true)); + (3, (3, 2, 0, 2, false)); + (8, (8, 7, 0, 7, true)); + (9, (9, 8, 1, 0, false)); + (16, (16, 15, 1, 7, true)); + (17, (17, 16, 2, 0, false)); + (32, (32, 31, 2, 15, true)); + (33, (33, 32, 3, 0, false)); + (48, (48, 47, 3, 15, true)); + (49, (49, 48, 4, 0, false)); + (64, (64, 63, 6, 3, false)); + (65, (65, 64, 6, 4, false)); + (66, (66, 65, 6, 5, true)); + (67, (67, 66, 7, 0, false)); + ] ) + +let test_level_from_raw () = + List.iter_es + (fun (cycle_eras, test_cases) -> + List.iter_es + (fun ( input_level, + ( level, + level_position, + cycle, + cycle_position, + expected_commitment ) ) -> + let raw_level = + Raw_level_repr.of_int32_exn (Int32.of_int input_level) + in + Level_repr.create_cycle_eras cycle_eras |> Environment.wrap_tzresult + >>?= fun cycle_eras -> + let level_from_raw = + Protocol.Level_repr.from_raw ~cycle_eras raw_level + in + Assert.equal_int + ~loc:__LOC__ + (Int32.to_int (Raw_level_repr.to_int32 level_from_raw.level)) + level + >>=? fun () -> + Assert.equal_int + ~loc:__LOC__ + (Int32.to_int level_from_raw.level_position) + level_position + >>=? fun () -> + Assert.equal_int + ~loc:__LOC__ + (Int32.to_int (Cycle_repr.to_int32 level_from_raw.cycle)) + cycle + >>=? fun () -> + Assert.equal_int + ~loc:__LOC__ + (Int32.to_int level_from_raw.cycle_position) + cycle_position + >>=? fun () -> + Assert.equal_bool + ~loc:__LOC__ + level_from_raw.expected_commitment + expected_commitment + >>=? fun () -> + let offset = + Int32.neg (Int32.add Int32.one (Int32.of_int input_level)) + in + let res = + Level_repr.from_raw_with_offset ~cycle_eras ~offset raw_level + in + Assert.proto_error + ~loc:__LOC__ + (Environment.wrap_tzresult res) + (fun err -> + let error_info = + Error_monad.find_info_of_error (Environment.wrap_tzerror err) + in + error_info.title = "Negative sum of level and offset")) + test_cases) + [test_case_1; test_case_2; test_case_3] + +let test_first_level_in_cycle () = + let cycle_eras = fst test_case_3 in + let test_cases = + (* cycle, level *) + [ + (0l, 1); + (1l, 9); + (2l, 17); + (3l, 33); + (4l, 49); + (5l, 55); + (6l, 61); + (7l, 67); + ] + in + let f (input_cycle, level) = + Level_repr.create_cycle_eras cycle_eras |> Environment.wrap_tzresult + >>?= fun cycle_eras -> + let input_cycle = Cycle_repr.of_int32_exn input_cycle in + let level_res = + Level_repr.first_level_in_cycle_from_eras ~cycle_eras input_cycle + in + Assert.equal_int + ~loc:__LOC__ + (Int32.to_int (Raw_level_repr.to_int32 level_res.level)) + level + in + List.iter_es f test_cases + +let tests = + [ + Tztest.tztest "create_cycle_eras" `Quick test_create_cycle_eras; + Tztest.tztest "level_from_raw" `Quick test_level_from_raw; + Tztest.tztest "first_level_in_cycle" `Quick test_first_level_in_cycle; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_liquidity_baking.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_liquidity_baking.ml new file mode 100644 index 000000000000..8748cbe87ed4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_liquidity_baking.ml @@ -0,0 +1,562 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Tocqueville Group, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: liquidity baking + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^liquidity baking$" + Subject: Test liquidity baking subsidies, CPMM storage updates, + sunset shut off, and escape hatch shut off. +*) + +open Liquidity_baking_machine +open Protocol +open Test_tez + +let generate_init_state () = + let cpmm_min_xtz_balance = 10_000_000L in + let cpmm_min_tzbtc_balance = 100_000 in + let accounts_balances = + [ + {xtz = 1_000_000L; tzbtc = 1; liquidity = 100}; + {xtz = 1_000L; tzbtc = 1000; liquidity = 100}; + {xtz = 40_000_000L; tzbtc = 350000; liquidity = 300}; + ] + in + ValidationMachine.build + {cpmm_min_xtz_balance; cpmm_min_tzbtc_balance; accounts_balances} + >>=? fun _ -> return_unit + +(* The script hash of + + https://gitlab.com/dexter2tz/dexter2tz/-/blob/d98643881fe14996803997f1283e84ebd2067e35/dexter.liquidity_baking.mligo.tz + +*) +let expected_cpmm_hash = + Script_expr_hash.of_b58check_exn + "exprvEBYbxZruLZ9aUDEC9cUxn5KUj361xsaZXGfCxogFoKQ1er9Np" + +(* The script hash of + + https://gitlab.com/dexter2tz/dexter2tz/-/blob/d98643881fe14996803997f1283e84ebd2067e35/lqt_fa12.mligo.tz + +*) +let expected_lqt_hash = + Script_expr_hash.of_b58check_exn + "exprufAK15C2FCbxGLCEVXFe26p3eQdYuwZRk1morJUwy9NBUmEZVB" + +(* Test that the scripts of the Liquidity Baking contracts (CPMM and LQT) have the expected hashes. *) +let liquidity_baking_origination () = + Context.init 1 >>=? fun (blk, _contracts) -> + Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun cpmm_address -> + Context.Contract.script_hash (B blk) cpmm_address >>=? fun cpmm_hash -> + Lwt.return @@ Environment.wrap_tzresult + @@ Alpha_context.Contract.of_b58check "KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + >>=? fun lqt_address -> + Context.Contract.script_hash (B blk) lqt_address >>=? fun lqt_hash -> + Assert.equal + ~loc:__LOC__ + Script_expr_hash.equal + "Unexpected CPMM script." + Script_expr_hash.pp + cpmm_hash + expected_cpmm_hash + >>=? fun () -> + Assert.equal + ~loc:__LOC__ + Script_expr_hash.equal + "Unexpected LQT script." + Script_expr_hash.pp + lqt_hash + expected_lqt_hash + >>=? fun () -> return_unit + +(* Test that the CPMM address in storage is correct *) +let liquidity_baking_cpmm_address () = + Context.init 1 >>=? fun (blk, _contracts) -> + Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> + Assert.equal + ~loc:__LOC__ + String.equal + "CPMM address in storage is incorrect" + Format.pp_print_string + (Alpha_context.Contract.to_b58check liquidity_baking) + "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5" + >>=? fun () -> return_unit + +(* Test that after [n] blocks, the liquidity baking CPMM contract is credited [n] times the subsidy amount. *) +let liquidity_baking_subsidies n () = + Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> + Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> + Context.Contract.balance (B blk) liquidity_baking >>=? fun old_balance -> + Block.bake_n n blk >>=? fun blk -> + Context.get_liquidity_baking_subsidy (B blk) + >>=? fun liquidity_baking_subsidy -> + (liquidity_baking_subsidy *? Int64.(of_int n)) >>?= fun expected_credit -> + Assert.balance_was_credited + ~loc:__LOC__ + (B blk) + liquidity_baking + old_balance + expected_credit + >>=? fun () -> return_unit + +(* Test that [n] blocks after the liquidity baking sunset, the subsidy is not applied anymore. + More precisely, after the sunset, the total amount credited to the subsidy is only proportional + to the sunset level and in particular it does not depend on [n]. *) +let liquidity_baking_sunset_level n () = + Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> + Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> + Context.get_constants (B blk) >>=? fun csts -> + let sunset = csts.parametric.liquidity_baking_sunset_level in + Context.Contract.balance (B blk) liquidity_baking >>=? fun old_balance -> + Block.bake_n (Int32.to_int sunset + n) blk >>=? fun blk -> + Context.get_liquidity_baking_subsidy (B blk) + >>=? fun liquidity_baking_subsidy -> + (liquidity_baking_subsidy *? Int64.(sub (of_int32 sunset) 1L)) + >>?= fun expected_credit -> + Assert.balance_was_credited + ~loc:__LOC__ + (B blk) + liquidity_baking + old_balance + expected_credit + >>=? fun () -> return_unit + +(* Test that subsidy shuts off at correct escape level alternating baking [n_vote_false] blocks with liquidity_baking_escape_vote = false and [n_vote_true] blocks with it true followed by [bake_after_escape] blocks with it false. *) +(* Escape level is roughly 2*(log(1-1/(2*percent_flagging)) / log(0.999)) *) +let liquidity_baking_escape_hatch n_vote_false n_vote_true escape_level + bake_after_escape () = + Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> + Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> + Context.Contract.balance (B blk) liquidity_baking >>=? fun old_balance -> + let rec bake_escaping blk i = + if i < escape_level then + Block.bake_n n_vote_false blk >>=? fun blk -> + Block.bake_n ~liquidity_baking_escape_vote:true n_vote_true blk + >>=? fun blk -> bake_escaping blk (i + n_vote_false + n_vote_true) + else return blk + in + bake_escaping blk 0 >>=? fun blk -> + Block.bake_n bake_after_escape blk >>=? fun blk -> + Context.get_liquidity_baking_subsidy (B blk) + >>=? fun liquidity_baking_subsidy -> + liquidity_baking_subsidy *? Int64.of_int escape_level + >>?= fun expected_balance -> + Assert.balance_was_credited + ~loc:__LOC__ + (B blk) + liquidity_baking + old_balance + expected_balance + >>=? fun () -> return_unit + +(* 100% of blocks have liquidity_baking_escape_vote = true *) +let liquidity_baking_escape_hatch_100 n () = + liquidity_baking_escape_hatch 0 1 812 n () + +(* 80% of blocks have liquidity_baking_escape_vote = true *) +let liquidity_baking_escape_hatch_80 n () = + liquidity_baking_escape_hatch 1 4 1079 n () + +(* 60% of blocks have liquidity_baking_escape_vote = true *) +let liquidity_baking_escape_hatch_60 n () = + liquidity_baking_escape_hatch 2 3 1624 n () + +(* 40% of blocks have liquidity_baking_escape_vote = true *) +let liquidity_baking_escape_hatch_40 n () = + liquidity_baking_escape_hatch 3 2 3590 n () + +(* 33% of blocks have liquidity_baking_escape_vote = true. + Escape hatch should not be activated. *) +let liquidity_baking_escape_hatch_33 n () = + Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> + Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> + Context.get_constants (B blk) >>=? fun csts -> + let sunset = csts.parametric.liquidity_baking_sunset_level in + Context.Contract.balance (B blk) liquidity_baking >>=? fun old_balance -> + let rec bake_33_percent_escaping blk i = + if i < Int32.to_int sunset + n then + Block.bake blk >>=? fun blk -> + Block.bake blk >>=? fun blk -> + Block.bake ~liquidity_baking_escape_vote:true blk >>=? fun blk -> + bake_33_percent_escaping blk (i + 3) + else return blk + in + bake_33_percent_escaping blk 0 >>=? fun blk -> + Context.get_liquidity_baking_subsidy (B blk) + >>=? fun liquidity_baking_subsidy -> + (liquidity_baking_subsidy *? Int64.(sub (of_int32 sunset) 1L)) + >>?= fun expected_balance -> + Assert.balance_was_credited + ~loc:__LOC__ + (B blk) + liquidity_baking + old_balance + expected_balance + >>=? fun () -> return_unit + +(* Test that the escape EMA in block metadata is correct. *) +let liquidity_baking_escape_ema n_vote_false n_vote_true escape_level + bake_after_escape expected_escape_ema () = + Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> + let rec bake_escaping blk i = + if i < escape_level then + Block.bake_n n_vote_false blk >>=? fun blk -> + Block.bake_n ~liquidity_baking_escape_vote:true n_vote_true blk + >>=? fun blk -> bake_escaping blk (i + n_vote_false + n_vote_true) + else return blk + in + bake_escaping blk 0 >>=? fun blk -> + (* We only need to return the escape EMA at the end. *) + Block.bake_n_with_liquidity_baking_escape_ema bake_after_escape blk + >>=? fun (_blk, escape_ema) -> + Assert.leq_int ~loc:__LOC__ (Int32.to_int escape_ema) expected_escape_ema + >>=? fun () -> return_unit + +(* With no bakers setting the escape vote, EMA should be zero. *) +let liquidity_baking_escape_ema_zero () = + liquidity_baking_escape_ema 0 0 0 100 0 () + +(* The EMA should be not much over the threshold after the escape hatch has been activated. We add 1_000 to the constant to give room for the last update. *) +let liquidity_baking_escape_ema_threshold () = + liquidity_baking_escape_ema 0 1 812 1 667_667 () + +let liquidity_baking_storage n () = + Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> + Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> + Context.get_liquidity_baking_subsidy (B blk) >>=? fun subsidy -> + let expected_storage = + Expr.from_string + (Printf.sprintf + "Pair 1\n\ + \ %d\n\ + \ 100\n\ + \ \"KT1VqarPDicMFn1ejmQqqshUkUXTCTXwmkCN\"\n\ + \ \"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo\"" + (100 + (n * Int64.to_int (to_mutez subsidy)))) + in + Block.bake_n n blk >>=? fun blk -> + Context.Contract.storage (B blk) liquidity_baking >>=? fun storage -> + let to_string expr = + Format.asprintf "%a" Michelson_v1_printer.print_expr expr + in + Assert.equal + ~loc:__LOC__ + String.equal + "Storage isn't equal" + Format.pp_print_string + (to_string storage) + (to_string expected_storage) + >>=? fun () -> return_unit + +let liquidity_baking_balance_update () = + Context.init ~consensus_threshold:0 1 >>=? fun (blk, _contracts) -> + Context.get_liquidity_baking_cpmm_address (B blk) >>=? fun liquidity_baking -> + Context.get_constants (B blk) >>=? fun csts -> + let sunset = csts.parametric.liquidity_baking_sunset_level in + let subsidy = csts.parametric.liquidity_baking_subsidy in + Block.bake_n_with_all_balance_updates Int32.(to_int (add sunset 100l)) blk + >>=? fun (_blk, balance_updates) -> + let liquidity_baking_updates = + List.filter + (fun el -> + match el with + | ( Alpha_context.Receipt.Contract contract, + Alpha_context.Receipt.Credited _, + Alpha_context.Receipt.Subsidy ) -> + Alpha_context.Contract.(contract = liquidity_baking) + | _ -> false) + balance_updates + in + List.fold_left_e + (fun accum (_, update, _) -> + match update with + | Alpha_context.Receipt.Credited x -> accum +? x + | Alpha_context.Receipt.Debited _ -> assert false) + (of_int 0) + liquidity_baking_updates + >>?= fun credits -> + Assert.equal_int + ~loc:__LOC__ + (Int64.to_int (to_mutez credits)) + ((Int32.to_int sunset - 1) * Int64.to_int (to_mutez subsidy)) + >>=? fun () -> return_unit + +let get_cpmm_result results = + match results with + | cpmm_result :: _results -> cpmm_result + | _ -> assert false + +let get_lqt_result results = + match results with + | _cpmm_result :: lqt_result :: _results -> lqt_result + | _ -> assert false + +let get_address_in_result result = + match result with + | Apply_results.Origination_result {originated_contracts; _} -> ( + match originated_contracts with [c] -> c | _ -> assert false) + +let get_balance_updates_in_result result = + match result with + | Apply_results.Origination_result {balance_updates; _} -> balance_updates + +let get_balance_update_in_result result = + match get_balance_updates_in_result result with + | [(Contract _, Credited balance, Protocol_migration)] -> balance + | [_; _; _; _; _; (Contract _, Credited balance, Protocol_migration)] -> + balance + | _ -> assert false + +let liquidity_baking_origination_result_cpmm_address () = + Context.init 1 >>=? fun (blk, _contracts) -> + Context.get_liquidity_baking_cpmm_address (B blk) + >>=? fun cpmm_address_in_storage -> + Block.bake_n_with_origination_results 1 blk + >>=? fun (_blk, origination_results) -> + let result = get_cpmm_result origination_results in + let address = get_address_in_result result in + Assert.equal + ~loc:__LOC__ + Context.Contract.equal + "CPMM address in storage is not the same as in origination result" + Context.Contract.pp + address + cpmm_address_in_storage + >>=? fun () -> return_unit + +let liquidity_baking_origination_result_cpmm_balance () = + Context.init 1 >>=? fun (blk, _contracts) -> + Block.bake_n_with_origination_results 1 blk + >>=? fun (_blk, origination_results) -> + let result = get_cpmm_result origination_results in + let balance_update = get_balance_update_in_result result in + Assert.equal_tez ~loc:__LOC__ balance_update (of_mutez_exn 100L) + >>=? fun () -> return_unit + +let liquidity_baking_origination_result_lqt_address () = + Context.init 1 >>=? fun (blk, _contracts) -> + Block.bake_n_with_origination_results 1 blk + >>=? fun (_blk, origination_results) -> + let result = get_lqt_result origination_results in + let address = get_address_in_result result in + Assert.equal + ~loc:__LOC__ + String.equal + "LQT address in origination result is incorrect" + Format.pp_print_string + (Alpha_context.Contract.to_b58check address) + "KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + >>=? fun () -> return_unit + +let liquidity_baking_origination_result_lqt_balance () = + Context.init 1 >>=? fun (blk, _contracts) -> + Block.bake_n_with_origination_results 1 blk + >>=? fun (_blk, origination_results) -> + let result = get_lqt_result origination_results in + let balance_updates = get_balance_updates_in_result result in + match balance_updates with + | [ + (Liquidity_baking_subsidies, Debited am1, Protocol_migration); + (Storage_fees, Credited am2, Protocol_migration); + (Liquidity_baking_subsidies, Debited am3, Protocol_migration); + (Storage_fees, Credited am4, Protocol_migration); + ] -> + Assert.equal_tez ~loc:__LOC__ am1 am2 >>=? fun () -> + Assert.equal_tez ~loc:__LOC__ am3 am4 >>=? fun () -> + Assert.equal_tez ~loc:__LOC__ am1 (of_mutez_exn 64_250L) >>=? fun () -> + Assert.equal_tez ~loc:__LOC__ am3 (of_mutez_exn 494_500L) + | _ -> failwith "Unexpected balance updates (%s)" __LOC__ + +(* Test that with no contract at the tzBTC address and the level low enough to indicate we're not on mainnet, three contracts are originated in stitching. *) +let liquidity_baking_origination_test_migration () = + Context.init 1 >>=? fun (blk, _contracts) -> + Block.bake_n_with_origination_results 1 blk + >>=? fun (_blk, origination_results) -> + let num_results = List.length origination_results in + Assert.equal_int ~loc:__LOC__ num_results 3 + +(* Test that with no contract at the tzBTC address and the level high enough to indicate we could be on mainnet, no contracts are originated in stitching. *) +let liquidity_baking_origination_no_tzBTC_mainnet_migration () = + Context.init ~consensus_threshold:0 ~level:1_437_862l 1 + >>=? fun (blk, _contracts) -> + (* By baking a bit we also check that the subsidy application with no CPMM present does nothing rather than stopping the chain.*) + Block.bake_n_with_origination_results 64 blk + >>=? fun (_blk, origination_results) -> + let num_results = List.length origination_results in + Assert.equal_int ~loc:__LOC__ num_results 0 + +let tests = + [ + Tztest.tztest + "test liquidity baking script hashes" + `Quick + liquidity_baking_origination; + Tztest.tztest + "test liquidity baking cpmm is originated at the expected address" + `Quick + liquidity_baking_cpmm_address; + Tztest.tztest "Init Context" `Quick generate_init_state; + Tztest.tztest + "test liquidity baking subsidy is correct" + `Quick + (liquidity_baking_subsidies 64); + Tztest.tztest + "test liquidity baking shuts off at sunset level when baking one block \ + longer" + `Quick + (liquidity_baking_sunset_level 1); + Tztest.tztest + "test liquidity baking shuts off at sunset level when baking two blocks \ + longer" + `Quick + (liquidity_baking_sunset_level 2); + Tztest.tztest + "test liquidity baking shuts off at sunset level when baking 100 blocks \ + longer" + `Quick + (liquidity_baking_sunset_level 100); + Tztest.tztest + "test liquidity baking escape hatch with 100% of bakers flagging when \ + baking one block longer" + `Quick + (liquidity_baking_escape_hatch_100 1); + Tztest.tztest + "test liquidity baking escape hatch with 100% of bakers flagging when \ + baking two blocks longer" + `Quick + (liquidity_baking_escape_hatch_100 2); + Tztest.tztest + "test liquidity baking escape hatch with 100% of bakers flagging when \ + baking 100 blocks longer" + `Quick + (liquidity_baking_escape_hatch_100 100); + Tztest.tztest + "test liquidity baking escape hatch with 80% of bakers flagging when \ + baking one block longer" + `Quick + (liquidity_baking_escape_hatch_80 1); + Tztest.tztest + "test liquidity baking escape hatch with 80% of bakers flagging when \ + baking two blocks longer" + `Quick + (liquidity_baking_escape_hatch_80 2); + Tztest.tztest + "test liquidity baking escape hatch with 80% of bakers flagging when \ + baking 100 blocks longer" + `Quick + (liquidity_baking_escape_hatch_80 100); + Tztest.tztest + "test liquidity baking escape hatch with 60% of bakers flagging when \ + baking one block longer" + `Quick + (liquidity_baking_escape_hatch_60 1); + Tztest.tztest + "test liquidity baking escape hatch with 60% of bakers flagging when \ + baking two blocks longer" + `Quick + (liquidity_baking_escape_hatch_60 2); + Tztest.tztest + "test liquidity baking escape hatch with 60% of bakers flagging when \ + baking 100 blocks longer" + `Quick + (liquidity_baking_escape_hatch_60 100); + Tztest.tztest + "test liquidity baking escape hatch with 40% of bakers flagging when \ + baking one block longer" + `Quick + (liquidity_baking_escape_hatch_40 1); + Tztest.tztest + "test liquidity baking escape hatch with 40% of bakers flagging when \ + baking two blocks longer" + `Quick + (liquidity_baking_escape_hatch_40 2); + Tztest.tztest + "test liquidity baking escape hatch with 40% of bakers flagging when \ + baking 100 blocks longer" + `Quick + (liquidity_baking_escape_hatch_40 100); + Tztest.tztest + "test liquidity baking shuts off at sunset level with escape hatch at \ + 33% and baking one block longer" + `Quick + (liquidity_baking_escape_hatch_33 1); + Tztest.tztest + "test liquidity baking shuts off at sunset level with escape hatch at \ + 33% and baking two blocks longer" + `Quick + (liquidity_baking_escape_hatch_33 2); + Tztest.tztest + "test liquidity baking shuts off at sunset level with escape hatch at \ + 33% and baking 100 blocks longer" + `Quick + (liquidity_baking_escape_hatch_33 100); + Tztest.tztest + "test liquidity baking escape ema in block metadata is zero with no \ + bakers flagging." + `Quick + liquidity_baking_escape_ema_zero; + Tztest.tztest + "test liquidity baking escape ema is equal to the threshold after the \ + escape hatch has been activated" + `Quick + liquidity_baking_escape_ema_threshold; + Tztest.tztest + "test liquidity baking storage is updated" + `Quick + (liquidity_baking_storage 64); + Tztest.tztest + "test liquidity baking balance updates" + `Quick + liquidity_baking_balance_update; + Tztest.tztest + "test liquidity baking CPMM address in storage matches address in the \ + origination result" + `Quick + liquidity_baking_origination_result_cpmm_address; + Tztest.tztest + "test liquidity baking CPMM balance in origination result is 100 mutez" + `Quick + liquidity_baking_origination_result_cpmm_balance; + Tztest.tztest + "test liquidity baking LQT contract is originated at expected address" + `Quick + liquidity_baking_origination_result_lqt_address; + Tztest.tztest + "test liquidity baking LQT balance in origination result is 0 mutez" + `Quick + liquidity_baking_origination_result_lqt_balance; + Tztest.tztest + "test liquidity baking originates three contracts when tzBTC does not \ + exist and level indicates we are not on mainnet" + `Quick + liquidity_baking_origination_test_migration; + Tztest.tztest + "test liquidity baking originates three contracts when tzBTC does not \ + exist and level indicates we might be on mainnet" + `Quick + liquidity_baking_origination_no_tzBTC_mainnet_migration; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_origination.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_origination.ml new file mode 100644 index 000000000000..1be2daf1da7a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_origination.ml @@ -0,0 +1,240 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (origination) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^origination$" + Subject: On originating contracts. +*) + +open Protocol +open Alpha_context +open Test_tez + +let ten_tez = of_int 10 + +(* The possible fees are: a given credit, an origination burn fee + (constants_repr.default.origination_burn = 257 mtez), a fee that is paid when + creating an originate contract. *) +let total_fees_for_origination ?(fee = Tez.zero) ?(credit = Tez.zero) b = + Context.get_constants (B b) + >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> + cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> + credit +? fee >>? ( +? ) origination_burn >>? ( +? ) Op.dummy_script_cost + >>?= fun total_fee -> return total_fee + +(* [test_origination_balances fee credit spendable delegatable] takes four + optional parameter: fee is the fee that pay if require to create an + originated contract; credit is the amount of tez that will send to this + contract; delegatable default is set to true meaning that this contract is + able to delegate. + + This function creates 2 contracts, one for originating (called source) and + one for baking; get the balance of the source contract, call the + origination operation to create a new originated contract from this contract + with all the possible fees; and check the balance before/after originated + operation valid. + - the source contract has payed all the fees + - the originated has been credited correctly. + Note that we need 2 contracts because in Tenderbake the baker receives the + fees instantaneously. So to see that the fees are subtracted, we need that + the bake is done by another delegated. *) +let test_origination_balances ~loc:_ ?(fee = Tez.zero) ?(credit = Tez.zero) () = + Context.init 2 >>=? fun (b, contracts) -> + let source = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + let contract_for_bake = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 + in + Context.Contract.pkh source >>=? fun pkh_for_orig -> + Context.Contract.pkh contract_for_bake >>=? fun pkh_for_bake -> + Op.origination (B b) source ~fee ~credit ~script:Op.dummy_script + >>=? fun (operation, new_contract) -> + total_fees_for_origination ~fee ~credit b >>=? fun total_fee -> + Block.bake ~operation ~policy:(By_account pkh_for_bake) b >>=? fun b -> + (* check that after the block has been baked the contract for originating + was debited all the fees *) + Context.Delegate.current_frozen_deposits (B b) pkh_for_orig + >>=? fun deposits -> + total_fee +? deposits >>?= fun total_fee_plus_deposits -> + Assert.balance_was_debited + ~loc:__LOC__ + (B b) + source + Account.default_initial_balance + total_fee_plus_deposits + >>=? fun _ -> + (* check the balance of the originate contract is equal to credit *) + Assert.balance_is ~loc:__LOC__ (B b) new_contract credit + +(** [register_origination fee credit spendable delegatable] takes four + optional parameter: fee for the fee need to be paid if set to + create an originated contract; credit is the amount of tez that + send to this originated contract; spendable default is set to true + meaning that this contract is spendable; delegatable default is + set to true meaning that this contract is able to delegate. *) +let register_origination ?(fee = Tez.zero) ?(credit = Tez.zero) () = + Context.init 2 >>=? fun (b, contracts) -> + let source = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + let contract_for_bake = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 + in + Context.Contract.pkh source >>=? fun source_pkh -> + Context.Contract.pkh contract_for_bake >>=? fun pkh_for_bake -> + Op.origination (B b) source ~fee ~credit ~script:Op.dummy_script + >>=? fun (operation, originated) -> + Block.bake ~operation ~policy:(By_account pkh_for_bake) b >>=? fun b -> + (* fee + credit were debited from source *) + total_fees_for_origination ~fee ~credit b >>=? fun total_fee -> + Context.Delegate.current_frozen_deposits (B b) source_pkh >>=? fun deposits -> + total_fee +? deposits >>?= fun total_fee_plus_deposits -> + Assert.balance_was_debited + ~loc:__LOC__ + (B b) + source + Account.default_initial_balance + total_fee_plus_deposits + >>=? fun () -> + (* originated contract has been credited *) + Assert.balance_was_credited ~loc:__LOC__ (B b) originated Tez.zero credit + >|=? fun () -> + (* TODO spendable or not and delegatable or not if relevant for some + test. Not the case at the moment, cf. uses of + register_origination *) + (b, source, originated) + +(******************************************************) +(* Tests *) +(******************************************************) + +(** Basic test. A contract is created as well as the newly originated + contract (called from origination operation). The balance + before/after are checked. *) +let test_balances_simple () = test_origination_balances ~loc:__LOC__ () + +(** Same as [balances_simple] but credits 10 tez to the originated + contract (no fees). *) +let test_balances_credit () = + test_origination_balances ~loc:__LOC__ ~credit:ten_tez () + +(** Same as [balances_credit] with 10 tez fees. *) +let test_balances_credit_fee () = + test_origination_balances ~loc:__LOC__ ~credit:(of_int 2) ~fee:ten_tez () + +(** Ask source contract to pay a fee when originating a contract. *) +let test_pay_fee () = + register_origination ~credit:(of_int 2) ~fee:ten_tez () + >>=? fun (_b, _contract, _new_contract) -> return_unit + +(******************************************************) +(** Errors *) + +(******************************************************) + +(** Create an originate contract where the contract does not have + enough tez to pay for the fee. *) +let test_not_tez_in_contract_to_pay_fee () = + Context.init 2 >>=? fun (b, contracts) -> + let contract_1 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 + in + let contract_2 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 + in + Incremental.begin_construction b >>=? fun inc -> + (* transfer everything but one tez from 1 to 2 and check balance of 1 *) + Context.Contract.balance (I inc) contract_1 >>=? fun balance -> + balance -? Tez.one >>?= fun amount -> + Op.transaction (I inc) contract_1 contract_2 amount >>=? fun operation -> + Incremental.add_operation inc operation >>=? fun inc -> + Assert.balance_was_debited ~loc:__LOC__ (I inc) contract_1 balance amount + >>=? fun _ -> + (* use this source contract to create an originate contract where it requires + to pay a fee and add an amount of credit into this new contract *) + Op.origination + (I inc) + ~fee:ten_tez + ~credit:Tez.one + contract_1 + ~script:Op.dummy_script + >>=? fun (op, _) -> + Incremental.add_operation inc op >>= fun inc -> + Assert.proto_error ~loc:__LOC__ inc (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + +(* Set the endorser of the block as manager/delegate of the originated + account. *) +let register_contract_get_endorser () = + Context.init 1 >>=? fun (b, contracts) -> + let contract = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + Incremental.begin_construction b >>=? fun inc -> + Context.get_endorser (I inc) >|=? fun (account_endorser, _slots) -> + (inc, contract, account_endorser) + +(* Create multiple originated contracts and ask contract to pay the fee. *) +let n_originations n ?credit ?fee () = + List.fold_left_es + (fun new_contracts _ -> + register_origination ?fee ?credit () + >|=? fun (_b, _source, new_contract) -> new_contract :: new_contracts) + [] + (1 -- n) + +(** Create 100 originations. *) +let test_multiple_originations () = + n_originations 100 ~credit:(of_int 2) ~fee:ten_tez () >>=? fun contracts -> + Assert.equal_int ~loc:__LOC__ (List.length contracts) 100 + +(** Cannot originate two contracts with the same context's counter. *) +let test_counter () = + Context.init 1 >>=? fun (b, contracts) -> + let contract = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + Incremental.begin_construction b >>=? fun inc -> + Op.origination (I inc) ~credit:Tez.one contract ~script:Op.dummy_script + >>=? fun (op1, _) -> + Op.origination (I inc) ~credit:Tez.one contract ~script:Op.dummy_script + >>=? fun (op2, _) -> + Incremental.add_operation inc op1 >>=? fun inc -> + Incremental.add_operation inc op2 >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Contract_storage.Counter_in_the_past _ -> true + | _ -> false) + +(******************************************************) + +let tests = + [ + Tztest.tztest "balances_simple" `Quick test_balances_simple; + Tztest.tztest "balances_credit" `Quick test_balances_credit; + Tztest.tztest "balances_credit_fee" `Quick test_balances_credit_fee; + Tztest.tztest "pay_fee" `Quick test_pay_fee; + Tztest.tztest + "not enough tez in contract to pay fee" + `Quick + test_not_tez_in_contract_to_pay_fee; + Tztest.tztest "multiple originations" `Quick test_multiple_originations; + Tztest.tztest "counter" `Quick test_counter; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_participation.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_participation.ml new file mode 100644 index 000000000000..2c61028e62e3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_participation.ml @@ -0,0 +1,208 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (participation monitoring) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^participation" + Subject: Participation monitoring in Tenderbake +*) + +open Protocol +open Alpha_context + +(** [baker] bakes and [endorser] endorses *) +let bake_and_endorse_once (b_pred, b_cur) baker endorser = + let open Context in + Context.get_endorsers (B b_cur) >>=? fun endorsers_list -> + List.find_map + (function + | {Plugin.RPC.Validators.delegate; slots; _} -> + if Signature.Public_key_hash.equal delegate endorser then + Some (delegate, slots) + else None) + endorsers_list + |> function + | None -> assert false + | Some delegate -> + Block.get_round b_cur >>?= fun round -> + Op.endorsement ~round ~delegate ~endorsed_block:b_cur (B b_pred) () + >>=? fun endorsement -> + let endorsement = Operation.pack endorsement in + Block.bake ~policy:(By_account baker) ~operation:endorsement b_cur + +(** We test that: + - a delegate that participates enough, gets its endorsing rewards at the end of the cycle, + - a delegate that does not participating enough during a cycle, doesn't get rewarded. + + The case distinction is made by the boolean argument [sufficient_participation]. + If [sufficient_participation] is true, + then a validator endorses for as long as the minimal required activity is not reached, + otherwise it does not endorse. + Finally, we check the validator's balance at the end of the cycle. +*) +let test_participation ~sufficient_participation () = + let n_accounts = 2 in + Context.init ~consensus_threshold:1 n_accounts >>=? fun (b0, accounts) -> + Context.get_constants (B b0) >>=? fun csts -> + let blocks_per_cycle = Int32.to_int csts.parametric.blocks_per_cycle in + let mpr = csts.parametric.minimal_participation_ratio in + assert (blocks_per_cycle mod mpr.denominator = 0) ; + (* if this assertion does not hold, then the test might be incorrect *) + let committee_size = csts.parametric.consensus_committee_size in + let expected_nb_slots = blocks_per_cycle * committee_size / n_accounts in + let minimal_nb_active_slots = + mpr.numerator * expected_nb_slots / mpr.denominator + in + let (account1, account2) = + match accounts with a1 :: a2 :: _ -> (a1, a2) | _ -> assert false + in + Context.Contract.pkh account1 >>=? fun del1 -> + Context.Contract.pkh account2 >>=? fun del2 -> + Block.bake ~policy:(By_account del1) b0 >>=? fun b1 -> + (* To separate concerns, only [del1] bakes: this way, we don't need to + consider baking rewards for [del2]. Delegate [del2] endorses only + if the target [minimal_nb_active_slots] is not reached; for the + rest, it is [del1] that endorses. *) + List.fold_left_es + (fun (b_pred, b_crt, endorsing_power) level -> + let int_level = Int32.of_int level in + Environment.wrap_tzresult (Raw_level.of_int32 int_level) >>?= fun level -> + Context.get_endorsing_power_for_delegate (B b_crt) ~levels:[level] del1 + >>=? fun endorsing_power_for_level -> + let (endorser, new_endorsing_power) = + if sufficient_participation && endorsing_power < minimal_nb_active_slots + then (del2, endorsing_power + endorsing_power_for_level) + else (del1, endorsing_power) + in + bake_and_endorse_once (b_pred, b_crt) del1 endorser >>=? fun b -> + return (b_crt, b, new_endorsing_power)) + (b0, b1, 0) + (2 -- (blocks_per_cycle - 1)) + >>=? fun (pred_b, b, _) -> + Context.Contract.balance (B pred_b) account2 >|=? Tez.to_mutez + >>=? fun bal2_at_pred_b -> + Context.Contract.balance (B b) account2 >|=? Tez.to_mutez + >>=? fun bal2_at_b -> + (* - If not sufficient_participation, we check that the balance of del2 at b is the + balance of del2 at pred_b; consequently, no rewards could have been given + to del2. + - If sufficient participation, we check that the balance of del2 at b is the + balance of del2 at pred_b plus the endorsing rewards. *) + Context.get_endorsing_reward (B b) ~expected_endorsing_power:expected_nb_slots + >|=? Tez.to_mutez + >>=? fun er -> + let endorsing_rewards = if sufficient_participation then er else 0L in + let expected_bal2_at_b = Int64.add bal2_at_pred_b endorsing_rewards in + Assert.equal_int64 ~loc:__LOC__ bal2_at_b expected_bal2_at_b + +(* We bake and endorse with 1 out of 2 accounts; we monitor the result + returned by the '../delegates//participation' RPC for the + non-participating account. *) +let test_participation_rpc () = + let n_accounts = 2 in + Context.init ~consensus_threshold:1 n_accounts >>=? fun (b0, accounts) -> + let (account1, account2) = + match accounts with a1 :: a2 :: _ -> (a1, a2) | _ -> assert false + in + Context.Contract.pkh account1 >>=? fun del1 -> + Context.Contract.pkh account2 >>=? fun del2 -> + Context.get_constants (B b0) >>=? fun csts -> + let blocks_per_cycle = Int32.to_int csts.parametric.blocks_per_cycle in + let Constants.{numerator; denominator} = + csts.parametric.minimal_participation_ratio + in + let expected_cycle_activity = + blocks_per_cycle * csts.parametric.consensus_committee_size / n_accounts + in + let minimal_cycle_activity = + expected_cycle_activity * numerator / denominator + in + let allowed_missed_slots = expected_cycle_activity - minimal_cycle_activity in + let expected_endorsing_rewards = + Tez.mul_exn + csts.parametric.endorsing_reward_per_slot + expected_cycle_activity + in + Block.bake ~policy:(By_account del1) b0 >>=? fun b1 -> + List.fold_left_es + (fun (b_pred, b_crt, total_endorsing_power) level_int -> + Context.Delegate.participation (B b_crt) del2 >>=? fun info -> + Assert.equal_int + ~loc:__LOC__ + info.expected_cycle_activity + expected_cycle_activity + >>=? fun () -> + Assert.equal_int + ~loc:__LOC__ + info.minimal_cycle_activity + minimal_cycle_activity + >>=? fun () -> + Assert.equal_int ~loc:__LOC__ info.missed_levels (level_int - 1) + >>=? fun () -> + let missed_slots = total_endorsing_power in + Assert.equal_int ~loc:__LOC__ info.missed_slots missed_slots + >>=? fun () -> + let remaining_allowed_missed_slots = + allowed_missed_slots - missed_slots + in + Assert.equal_int + ~loc:__LOC__ + info.remaining_allowed_missed_slots + (max 0 remaining_allowed_missed_slots) + >>=? fun () -> + let endorsing_rewards = + if remaining_allowed_missed_slots >= 0 then expected_endorsing_rewards + else Tez.zero + in + Assert.equal_tez + ~loc:__LOC__ + info.expected_endorsing_rewards + endorsing_rewards + >>=? fun () -> + bake_and_endorse_once (b_pred, b_crt) del1 del1 >>=? fun b -> + (* [level_int] is the level of [b_crt] *) + level_int |> Int32.of_int |> Raw_level.of_int32 + |> Environment.wrap_tzresult + >>?= fun level -> + Context.get_endorsing_power_for_delegate (B b_crt) ~levels:[level] del2 + >>=? fun endorsing_power -> + return (b_crt, b, total_endorsing_power + endorsing_power)) + (b0, b1, 0) + (1 -- (blocks_per_cycle - 2)) + >>=? fun (_, _, _) -> return_unit + +let tests = + [ + Tztest.tztest + "test insufficient participation" + `Quick + (test_participation ~sufficient_participation:false); + Tztest.tztest + "test minimal participation" + `Quick + (test_participation ~sufficient_participation:true); + Tztest.tztest "test participation RPC" `Quick test_participation_rpc; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_preendorsement.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_preendorsement.ml new file mode 100644 index 000000000000..728f4c79c0f5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_preendorsement.ml @@ -0,0 +1,228 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (preendorsement) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^preendorsement$" +*) + +open Protocol +open Alpha_context + +(****************************************************************) +(* Utility functions *) +(****************************************************************) + +let init_genesis ?policy () = + Context.init ~consensus_threshold:0 5 >>=? fun (genesis, _) -> + Block.bake ?policy genesis >>=? fun b -> return (genesis, b) + +(****************************************************************) +(* Tests *) +(****************************************************************) + +(** Consensus operation for future level : apply a preendorsement with a level in the future *) +let test_consensus_operation_preendorsement_for_future_level () = + init_genesis () >>=? fun (genesis, pred) -> + let raw_level = Raw_level.of_int32 (Int32.of_int 10) in + let level = match raw_level with Ok l -> l | Error _ -> assert false in + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:true + ~endorsed_block:pred + ~level + ~error_title:"Consensus operation for future level" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Consensus operation for old level : apply a preendorsement with a level in the past *) +let test_consensus_operation_preendorsement_for_old_level () = + init_genesis () >>=? fun (genesis, pred) -> + let raw_level = Raw_level.of_int32 (Int32.of_int 0) in + let level = match raw_level with Ok l -> l | Error _ -> assert false in + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:true + ~endorsed_block:pred + ~level + ~error_title:"Consensus operation for old level" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Consensus operation for future round : apply a preendorsement with a round in the future *) +let test_consensus_operation_preendorsement_for_future_round () = + init_genesis () >>=? fun (genesis, pred) -> + Environment.wrap_tzresult (Round.of_int 21) >>?= fun round -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:true + ~endorsed_block:pred + ~round + ~error_title:"Consensus operation for future round" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Consensus operation for old round : apply a preendorsement with a round in the past *) +let test_consensus_operation_preendorsement_for_old_round () = + init_genesis ~policy:(By_round 10) () >>=? fun (genesis, pred) -> + Environment.wrap_tzresult (Round.of_int 0) >>?= fun round -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:true + ~endorsed_block:pred + ~round + ~error_title:"Consensus operation for old round" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Consensus operation on competing proposal : apply a preendorsement on a competing proposal *) +let test_consensus_operation_preendorsement_on_competing_proposal () = + init_genesis () >>=? fun (genesis, pred) -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:true + ~endorsed_block:pred + ~block_payload_hash:Block_payload_hash.zero + ~error_title:"Consensus operation on competing proposal" + ~context:(Context.B genesis) + ~construction_mode:(pred, None) + () + +(** Unexpected preendorsements in block : apply a preendorsement with an incorrect round *) +let test_unexpected_preendorsements_in_blocks () = + init_genesis () >>=? fun (genesis, pred) -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:true + ~endorsed_block:pred + ~error_title:"unexpected preendorsement in block" + ~context:(Context.B genesis) + () + +(** Round too high : apply a preendorsement with a too high round *) +let test_too_high_round () = + init_genesis () >>=? fun (genesis, pred) -> + let raw_level = Raw_level.of_int32 (Int32.of_int 2) in + let level = match raw_level with Ok l -> l | Error _ -> assert false in + Environment.wrap_tzresult (Round.of_int 1) >>?= fun round -> + Consensus_helpers.test_consensus_operation + ~loc:__LOC__ + ~is_preendorsement:true + ~endorsed_block:pred + ~round + ~level + ~error_title:"preendorsement round too high" + ~context:(Context.B genesis) + ~construction_mode:(pred, Some pred.header.protocol_data) + () + +(** Duplicate preendorsement : apply a preendorsement that has already been applied. *) +let test_duplicate_preendorsement () = + init_genesis () >>=? fun (genesis, _) -> + Block.bake genesis >>=? fun b -> + Incremental.begin_construction ~mempool_mode:true b >>=? fun inc -> + Op.preendorsement ~endorsed_block:b (B genesis) () >>=? fun operation -> + let operation = Operation.pack operation in + Incremental.add_operation inc operation >>=? fun inc -> + Op.preendorsement ~endorsed_block:b (B genesis) () >>=? fun operation -> + let operation = Operation.pack operation in + Incremental.add_operation inc operation >>= fun res -> + Assert.proto_error_with_info + ~loc:__LOC__ + res + "double inclusion of consensus operation" + +(** Preendorsement for next level *) +let test_preendorsement_for_next_level () = + init_genesis () >>=? fun (genesis, _) -> + Consensus_helpers.test_consensus_op_for_next + ~genesis + ~kind:`Preendorsement + ~next:`Level + +(** Preendorsement for next round *) +let test_preendorsement_for_next_round () = + init_genesis () >>=? fun (genesis, _) -> + Consensus_helpers.test_consensus_op_for_next + ~genesis + ~kind:`Preendorsement + ~next:`Round + +let tests = + let module AppMode = Test_preendorsement_functor.BakeWithMode (struct + let name = "AppMode" + + let baking_mode = Block.Application + end) in + let module ConstrMode = Test_preendorsement_functor.BakeWithMode (struct + let name = "ConstrMode" + + let baking_mode = Block.Baking + end) in + AppMode.tests @ ConstrMode.tests + @ [ + Tztest.tztest + "Preendorsement for future level" + `Quick + test_consensus_operation_preendorsement_for_future_level; + Tztest.tztest + "Preendorsement for old level" + `Quick + test_consensus_operation_preendorsement_for_old_level; + Tztest.tztest + "Preendorsement for future round" + `Quick + test_consensus_operation_preendorsement_for_future_round; + Tztest.tztest + "Preendorsement for old round" + `Quick + test_consensus_operation_preendorsement_for_old_round; + Tztest.tztest + "Preendorsement on competing proposal" + `Quick + test_consensus_operation_preendorsement_on_competing_proposal; + Tztest.tztest + "Unexpected preendorsements in blocks" + `Quick + test_unexpected_preendorsements_in_blocks; + Tztest.tztest "Preendorsements round too high" `Quick test_too_high_round; + Tztest.tztest + "Duplicate preendorsement" + `Quick + test_duplicate_preendorsement; + Tztest.tztest + "Preendorsement for next level" + `Quick + test_preendorsement_for_next_level; + Tztest.tztest + "Preendorsement for next round" + `Quick + test_preendorsement_for_next_round; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_preendorsement_functor.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_preendorsement_functor.ml new file mode 100644 index 000000000000..543738183300 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_preendorsement_functor.ml @@ -0,0 +1,266 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (preendorsement) in Full_construction & Application modes + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^preendorsement$" + Subject: preendorsement inclusion in a block +*) + +open Protocol +open Alpha_context + +(****************************************************************) +(* Utility functions *) +(****************************************************************) +module type MODE = sig + val name : string + + val baking_mode : Block.baking_mode +end + +module BakeWithMode (Mode : MODE) : sig + val tests : unit Alcotest_lwt.test_case trace +end = struct + let name = Mode.name + + let bake = Block.bake ~baking_mode:Mode.baking_mode + + let aux_simple_preendorsement_inclusion ?(payload_round = Some Round.zero) + ?(locked_round = Some Round.zero) ?(block_round = 1) + ?(preend_round = Round.zero) + ?(preend_branch = fun _predpred pred _curr -> pred) + ?(preendorsed_block = fun _predpred _pred curr -> curr) + ?(mk_ops = fun op -> [op]) + ?(get_delegate_and_slot = + fun _predpred _pred _curr -> return (None, None)) + ?(post_process = Ok (fun _ -> return_unit)) ~loc () = + Context.init ~consensus_threshold:1 5 >>=? fun (genesis, _) -> + bake genesis >>=? fun b1 -> + Op.endorsement ~endorsed_block:b1 (B genesis) () >>=? fun endo -> + let endo = Operation.pack endo in + bake b1 ~operations:[endo] >>=? fun b2 -> + let ctxt = Context.B (preend_branch genesis b1 b2) in + let endorsed_block = preendorsed_block genesis b1 b2 in + get_delegate_and_slot genesis b1 b2 >>=? fun (delegate, slot) -> + Op.preendorsement + ?delegate + ?slot + ~round:preend_round + ~endorsed_block + ctxt + () + >>=? fun p -> + let operations = endo :: (mk_ops @@ Operation.pack p) in + bake + ~payload_round + ~locked_round + ~policy:(By_round block_round) + ~operations + b1 + >>= fun res -> + match (res, post_process) with + | (Ok ok, Ok success_fun) -> success_fun ok + | (Error _, Error (error_title, _error_category)) -> + Assert.proto_error_with_info ~loc res error_title + | (Ok _, Error _) -> Assert.error ~loc res (fun _ -> false) + | (Error _, Ok _) -> Assert.error ~loc res (fun _ -> false) + + (****************************************************************) + (* Tests *) + (****************************************************************) + + (** OK: bake a block "_b2_1" at round 1, containing a PQC and a locked + round of round 0 *) + let include_preendorsement_in_block_with_locked_round () = + aux_simple_preendorsement_inclusion ~loc:__LOC__ () >>=? fun _ -> + return_unit + + (** KO: bake a block "_b2_1" at round 1, containing a PQC and a locked + round of round 0. But the preendorsement is on a bad branch *) + let test_preendorsement_with_bad_branch () = + aux_simple_preendorsement_inclusion + (* preendorsement should be on branch _pred to be valid *) + ~preend_branch:(fun predpred _pred _curr -> predpred) + ~loc:__LOC__ + ~post_process:(Error ("Wrong consensus operation branch", `Temporary)) + () + + (** KO: The same preendorsement injected twice in the PQC *) + let duplicate_preendorsement_in_pqc () = + aux_simple_preendorsement_inclusion (* inject the op twice *) + ~mk_ops:(fun op -> [op; op]) + ~loc:__LOC__ + ~post_process:(Error ("double inclusion of consensus operation", `Branch)) + () + + (** KO: locked round declared in the block is not smaller than + that block's round *) + let locked_round_not_before_block_round () = + aux_simple_preendorsement_inclusion + (* default locked_round = 0 < block_round = 1 for this aux function *) + ~block_round:0 + ~loc:__LOC__ + ~post_process:(Error ("Locked round not smaller than round", `Permanent)) + () + + (** KO: because we announce a locked_round, but we don't provide the + preendorsement quorum certificate in the operations *) + let with_locked_round_in_block_but_without_any_pqc () = + (* This test only fails in Application mode. If full_construction mode, the + given locked_round is not used / checked. Moreover, the test succeed in + this case. + *) + let post_process = + if Mode.baking_mode == Block.Application then + Error ("Wrong fitness", `Permanent) + else Ok (fun _ -> return_unit) + in + aux_simple_preendorsement_inclusion + (* with declared locked_round but without a PQC in the ops *) + ~mk_ops:(fun _p -> []) + ~loc:__LOC__ + ~post_process + () + + (** KO: The preendorsed block is the pred one, not the current one *) + let preendorsement_has_wrong_level () = + aux_simple_preendorsement_inclusion + (* preendorsement should be for _curr block to be valid *) + ~preendorsed_block:(fun _predpred pred _curr -> pred) + ~loc:__LOC__ + ~post_process:(Error ("wrong level for consensus operation", `Permanent)) + () + + (** OK: explicit the correct endorser and preendorsing slot in the test *) + let preendorsement_in_block_with_good_slot () = + aux_simple_preendorsement_inclusion + ~get_delegate_and_slot:(fun _predpred _pred curr -> + let module V = Plugin.RPC.Validators in + Context.get_endorsers (B curr) >>=? function + | {V.delegate; slots = s :: _ as slots; _} :: _ -> + return (Some (delegate, slots), Some s) + | _ -> assert false + (* there is at least one endorser with a slot *)) + ~loc:__LOC__ + () + + (** KO: the used slot for injecting the endorsement is not the canonical one *) + let preendorsement_in_block_with_wrong_slot () = + aux_simple_preendorsement_inclusion + ~get_delegate_and_slot:(fun _predpred _pred curr -> + let module V = Plugin.RPC.Validators in + Context.get_endorsers (B curr) >>=? function + | {V.delegate; V.slots = _ :: non_canonical_slot :: _ as slots; _} :: _ + -> + return (Some (delegate, slots), Some non_canonical_slot) + | _ -> assert false + (* there is at least one endorser with a slot *)) + ~loc:__LOC__ + ~post_process:(Error ("wrong slot", `Permanent)) + () + + (** KO: the delegate tries to injects with a canonical slot of another delegate *) + let preendorsement_in_block_with_wrong_signature () = + aux_simple_preendorsement_inclusion + ~get_delegate_and_slot:(fun _predpred _pred curr -> + let module V = Plugin.RPC.Validators in + Context.get_endorsers (B curr) >>=? function + | {V.delegate; _} :: {V.slots = s :: _ as slots; _} :: _ -> + (* the canonical slot s is not owned by the delegate "delegate" !*) + return (Some (delegate, slots), Some s) + | _ -> assert false + (* there is at least one endorser with a slot *)) + ~loc:__LOC__ + ~post_process:(Error ("Invalid operation signature", `Permanent)) + () + + (** KO: cannot have a locked_round higher than attached PQC's round *) + let locked_round_is_higher_than_pqc_round () = + (* This test only fails in Application mode. If full_construction mode, the + given locked_round is not used / checked. Moreover, the test succeed in + this case. + *) + let post_process = + if Mode.baking_mode == Application then + Error ("wrong round for consensus operation", `Permanent) + else Ok (fun _ -> return_unit) + in + aux_simple_preendorsement_inclusion + ~preend_round:Round.zero + ~locked_round:(Some (Round.succ Round.zero)) + ~block_round:2 + ~loc:__LOC__ + ~post_process + () + + let my_tztest title test = + Tztest.tztest (Format.sprintf "%s: %s" name title) test + + let tests = + [ + my_tztest + "ok: include_preendorsement_in_block_with_locked_round" + `Quick + include_preendorsement_in_block_with_locked_round; + my_tztest + "ko: test_preendorsement_with_bad_branch" + `Quick + test_preendorsement_with_bad_branch; + my_tztest + "ko: duplicate_preendorsement_in_pqc" + `Quick + duplicate_preendorsement_in_pqc; + my_tztest + "ko:locked_round_not_before_block_round" + `Quick + locked_round_not_before_block_round; + my_tztest + "ko: with_locked_round_in_block_but_without_any_pqc" + `Quick + with_locked_round_in_block_but_without_any_pqc; + my_tztest + "ko: preendorsement_has_wrong_level" + `Quick + preendorsement_has_wrong_level; + my_tztest + "ok: preendorsement_in_block_with_good_slot" + `Quick + preendorsement_in_block_with_good_slot; + my_tztest + "ko: preendorsement_in_block_with_wrong_slot" + `Quick + preendorsement_in_block_with_wrong_slot; + my_tztest + "ko: preendorsement_in_block_with_wrong_signature" + `Quick + preendorsement_in_block_with_wrong_signature; + my_tztest + "ko: locked_round_is_higher_than_pqc_round" + `Quick + locked_round_is_higher_than_pqc_round; + ] +end diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_qty.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_qty.ml new file mode 100644 index 000000000000..4494f0778bfd --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_qty.ml @@ -0,0 +1,159 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (quantities) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^qty$" + Subject: On tez quantities. +*) + +open Protocol + +let known_ok_tez_literals = + [ + (0L, "0"); + (10L, "0.00001"); + (100L, "0.0001"); + (1_000L, "0.001"); + (10_000L, "0.01"); + (100_000L, "0.1"); + (1_000_000L, "1"); + (10_000_000L, "10"); + (100_000_000L, "100"); + (1_000_000_000L, "1000"); + (10_000_000_000L, "10000"); + (100_000_000_000L, "100000"); + (1_000_000_000_000L, "1000000"); + (1_000_000_000_001L, "1000000.000001"); + (1_000_000_000_010L, "1000000.00001"); + (1_000_000_000_100L, "1000000.0001"); + (1_000_000_001_000L, "1000000.001"); + (1_000_000_010_000L, "1000000.01"); + (1_000_000_100_000L, "1000000.1"); + (123_123_123_123_123_123L, "123123123123.123123"); + (999_999_999_999_999_999L, "999999999999.999999"); + ] + +let known_bad_tez_literals = + [ + "10000."; + "100,."; + "100,"; + "1,0000"; + "0.0000,1"; + "0.00,1"; + "0,1"; + "HAHA"; + "0.000,000,1"; + "0.0000000"; + "9,999,999,999,999.999,999"; + ] + +let fail expected given msg = + Format.kasprintf + Stdlib.failwith + "@[%s@ expected: %s@ got: %s@]" + msg + expected + given + +let fail_msg fmt = Format.kasprintf (fail "" "") fmt + +let default_printer _ = "" + +(** Literals which are supposed to be parsed correctly. *) +let test_known_tez_literals () = + List.iter + (fun (v, s) -> + let vv = Tez_repr.of_mutez v in + let vs = Tez_repr.of_string s in + let vs' = + Tez_repr.of_string (String.concat "" (String.split_on_char ',' s)) + in + let vv = + match vv with None -> fail_msg "could not unopt %Ld" v | Some vv -> vv + in + let vs = + match vs with None -> fail_msg "could not unopt %s" s | Some vs -> vs + in + let vs' = + match vs' with + | None -> fail_msg "could not unopt %s" s + | Some vs' -> vs' + in + assert (vv = vs) ; + assert (vv = vs') ; + assert (Tez_repr.to_string vv = s)) + known_ok_tez_literals ; + List.iter + (fun s -> + let vs = Tez_repr.of_string s in + assert (vs = None)) + known_bad_tez_literals ; + return_unit + +(** Randomly generated tez value which is printed into a string then + parsed again for their equality. *) +let test_random_tez_literals () = + for _ = 0 to 100_000 do + let v = Random.int64 12L in + let vv = Tez_repr.of_mutez v in + let vv = + match vv with None -> fail_msg "could not unopt %Ld" v | Some vv -> vv + in + let s = Tez_repr.to_string vv in + let vs = Tez_repr.of_string s in + let s' = String.concat "" (String.split_on_char ',' s) in + let vs' = Tez_repr.of_string s' in + assert (vs <> None) ; + assert (vs' <> None) ; + (match vs with + | None -> assert false + | Some vs -> + let rev = Tez_repr.to_mutez vs in + assert (v = rev)) ; + match vs' with + | None -> assert false + | Some vs' -> + let rev = Tez_repr.to_mutez vs' in + assert (v = rev) + done ; + return_unit + +let tests = + [ + ("tez-literals", fun _ -> test_known_tez_literals ()); + ("rnd-tez-literals", fun _ -> test_random_tez_literals ()); + ] + +let wrap (n, f) = + Alcotest_lwt.test_case n `Quick (fun _ () -> + f () >|= function + | Ok () -> () + | Error error -> + Format.kasprintf Stdlib.failwith "%a" pp_print_trace error) + +let tests = List.map wrap tests diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_receipt.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_receipt.ml new file mode 100644 index 000000000000..eddfe8337fb2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_receipt.ml @@ -0,0 +1,93 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (token) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^receipt" + Subject: Test receipt endocings. +*) + +open Protocol +open Alpha_context +open Data_encoding + +let random_amount () = + match Tez.of_mutez (Int64.add 1L (Random.int64 100L)) with + | None -> assert false + | Some x -> x + +(** Test that [decode (encode balance_updates) = balance_updates]. *) +let test_encodings balance = + Random.init 0 ; + let am = random_amount () in + let r1 = Receipt.(balance, Debited am, Protocol_migration) in + let r2 = Receipt.(balance, Credited am, Protocol_migration) in + let r3 = Receipt.(balance, Debited am, Subsidy) in + let r4 = Receipt.(balance, Credited am, Subsidy) in + let r5 = Receipt.(balance, Debited am, Simulation) in + let r6 = Receipt.(balance, Credited am, Simulation) in + let r7 = Receipt.(balance, Debited am, Block_application) in + let r8 = Receipt.(balance, Credited am, Block_application) in + let coded = + Json.construct + Receipt.balance_updates_encoding + [r1; r2; r3; r4; r5; r6; r7; r8] + in + let decoded = Json.destruct Receipt.balance_updates_encoding coded in + match decoded with + | [r1'; r2'; r3'; r4'; r5'; r6'; r7'; r8'] -> + assert ( + r1' = r1 && r2' = r2 && r3' = r3 && r4' = r4 && r5 = r5' && r6 = r6' + && r7 = r7' && r8 = r8') ; + return_unit + | _ -> assert false + +let test_encodings () = + let open Receipt in + let pkh = Signature.Public_key_hash.zero in + test_encodings (Contract (Contract.implicit_contract pkh)) >>=? fun () -> + test_encodings (Legacy_rewards (pkh, Cycle.root)) >>=? fun () -> + test_encodings Block_fees >>=? fun () -> + test_encodings (Legacy_deposits (pkh, Cycle.root)) >>=? fun () -> + test_encodings (Deposits pkh) >>=? fun () -> + test_encodings Nonce_revelation_rewards >>=? fun () -> + test_encodings Double_signing_evidence_rewards >>=? fun () -> + test_encodings Endorsing_rewards >>=? fun () -> + test_encodings Baking_rewards >>=? fun () -> + test_encodings Baking_bonuses >>=? fun () -> + test_encodings (Legacy_fees (pkh, Cycle.root)) >>=? fun () -> + test_encodings Storage_fees >>=? fun () -> + test_encodings Double_signing_punishments >>=? fun () -> + test_encodings (Lost_endorsing_rewards (pkh, Random.bool (), Random.bool ())) + >>=? fun () -> + test_encodings Liquidity_baking_subsidies >>=? fun () -> + test_encodings Burned >>=? fun () -> + test_encodings (Commitments Blinded_public_key_hash.zero) >>=? fun () -> + test_encodings Bootstrap >>=? fun () -> + test_encodings Invoice >>=? fun () -> + test_encodings Initial_commitments >>=? fun () -> test_encodings Minted + +let tests = Tztest.[tztest "receipt - encoding" `Quick test_encodings] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_reveal.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_reveal.ml new file mode 100644 index 000000000000..d85e040313e6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_reveal.ml @@ -0,0 +1,109 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (revelation) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^revelation$" + Subject: On the reveal operation. +*) + +(** Test for the [Reveal] operation. *) + +open Protocol +open Alpha_context +open Test_tez + +let ten_tez = of_int 10 + +let test_simple_reveal () = + Context.init ~consensus_threshold:0 1 >>=? fun (blk, contracts) -> + let c = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + let new_c = Account.new_account () in + let new_contract = Alpha_context.Contract.implicit_contract new_c.pkh in + (* Create the contract *) + Op.transaction (B blk) c new_contract Tez.one >>=? fun operation -> + Block.bake blk ~operation >>=? fun blk -> + (Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function + | true -> Stdlib.failwith "Unexpected revelation" + | false -> ()) + >>=? fun () -> + (* Reveal the contract *) + Op.revelation (B blk) new_c.pk >>=? fun operation -> + Block.bake blk ~operation >>=? fun blk -> + Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function + | true -> () + | false -> Stdlib.failwith "New contract revelation failed." + +let test_empty_account_on_reveal () = + Context.init ~consensus_threshold:0 1 >>=? fun (blk, contracts) -> + let c = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + let new_c = Account.new_account () in + let new_contract = Alpha_context.Contract.implicit_contract new_c.pkh in + let amount = Tez.one_mutez in + (* Create the contract *) + Op.transaction (B blk) c new_contract amount >>=? fun operation -> + Block.bake blk ~operation >>=? fun blk -> + (Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function + | true -> Stdlib.failwith "Unexpected revelation" + | false -> ()) + >>=? fun () -> + (* Reveal the contract *) + Op.revelation ~fee:amount (B blk) new_c.pk >>=? fun operation -> + Incremental.begin_construction blk >>=? fun inc -> + Incremental.add_operation inc operation >>=? fun _ -> + Block.bake blk ~operation >>=? fun blk -> + Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function + | false -> () + | true -> Stdlib.failwith "Empty account still exists and is revealed." + +let test_not_enough_found_for_reveal () = + Context.init 1 >>=? fun (blk, contracts) -> + let c = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + let new_c = Account.new_account () in + let new_contract = Alpha_context.Contract.implicit_contract new_c.pkh in + (* Create the contract *) + Op.transaction (B blk) c new_contract Tez.one_mutez >>=? fun operation -> + Block.bake blk ~operation >>=? fun blk -> + (Context.Contract.is_manager_key_revealed (B blk) new_contract >|=? function + | true -> Stdlib.failwith "Unexpected revelation" + | false -> ()) + >>=? fun () -> + (* Reveal the contract *) + Op.revelation ~fee:Tez.fifty_cents (B blk) new_c.pk >>=? fun operation -> + Block.bake blk ~operation >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + +let tests = + [ + Tztest.tztest "simple reveal" `Quick test_simple_reveal; + Tztest.tztest "empty account on reveal" `Quick test_empty_account_on_reveal; + Tztest.tztest + "not enough found for reveal" + `Quick + test_not_enough_found_for_reveal; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_round_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_round_repr.ml new file mode 100644 index 000000000000..af81ae884060 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_round_repr.ml @@ -0,0 +1,541 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: protocol + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^round$" + Subject: test the Round_repr module +*) + +open Protocol +open Alpha_context + +let ( >>>=? ) v f = v >|= Environment.wrap_tzresult >>=? f + +let ( >>>?= ) v f = v |> Environment.wrap_tzresult >>?= f + +let ( >>>? ) v f = v |> Environment.wrap_tzresult >>? f + +type round_test = { + (* input: round; output: round duration *) + round_duration : (int * int) list; + (* input: level offset; output: round, round offset *) + round_and_offset : (int * (int * int)) list; + (* input: pred_ts, pred_round, round; output: ts *) + timestamp_of_round : ((int * int * int) * int) list; + (* input: pred_ts, pred_round, ts; output: round *) + round_of_timestamp : ((int * int * int) * int) list; +} + +(* an association list of the input, output values *) +let case_3_4 = + { + round_duration = [(0, 3); (1, 4); (2, 5); (3, 6)]; + round_and_offset = + [ + (0, (0, 0)); + (1, (0, 1)); + (2, (0, 2)); + (3, (1, 0)); + (4, (1, 1)); + (5, (1, 2)); + (6, (1, 3)); + (7, (2, 0)); + (8, (2, 1)); + ]; + timestamp_of_round = [((100, 0, 6), 136); ((100, 1, 6), 137)]; + round_of_timestamp = + [ + ((100, 0, 121), 4); + ((100, 0, 122), 4); + ((100, 0, 123), 4); + ((100, 0, 124), 4); + ((100, 0, 125), 4); + ((100, 0, 126), 4); + ((100, 1, 121), 3); + ((100, 1, 122), 4); + ((100, 1, 123), 4); + ((100, 1, 124), 4); + ((100, 1, 125), 4); + ((100, 1, 126), 4); + ]; + } + +let case_3_6 = + { + round_duration = + [ + (0, 3); + (1, 6); + (2, 9); + (3, 12); + (4, 15); + (5, 18); + (6, 21); + (7, 24); + (8, 27); + ]; + round_and_offset = + [ + (0, (0, 0)); + (1, (0, 1)); + (2, (0, 2)); + (3, (1, 0)); + (4, (1, 1)); + (5, (1, 2)); + (6, (1, 3)); + (7, (1, 4)); + (8, (1, 5)); + (9, (2, 0)); + (10, (2, 1)); + (11, (2, 2)); + (97, (7, 13)); + ]; + timestamp_of_round = + [ + ((100, 0, 0), 103); + ((100, 1, 0), 106); + ((100, 0, 6), 166); + ((100, 1, 6), 169); + ]; + round_of_timestamp = + [ + ((100, 0, 103), 0); + ((100, 0, 104), 0); + ((100, 0, 105), 0); + ((100, 0, 106), 1); + ((100, 0, 111), 1); + ((100, 0, 112), 2); + ((100, 0, 120), 2); + ((100, 0, 121), 3); + ((100, 0, 132), 3); + ((100, 0, 133), 4); + ((100, 1, 106), 0); + ((100, 1, 107), 0); + ((100, 1, 108), 0); + ((100, 1, 109), 1); + ((100, 1, 114), 1); + ((100, 1, 115), 2); + ]; + } + +let test_cases = + [ + (* (first_round_duration, delay_increment_per_round), test_case_expectations *) + ((3, 1), case_3_4, "case_3_4"); + ((3, 3), case_3_6, "case_3_6"); + ] + +let round_of_int i = Round_repr.of_int i |> Environment.wrap_tzresult + +let mk_round_durations first_round_duration delay_increment_per_round = + let first_round_duration = + Period_repr.of_seconds_exn @@ Int64.of_int first_round_duration + in + let delay_increment_per_round = + Period_repr.of_seconds_exn @@ Int64.of_int delay_increment_per_round + in + (* We assume test specifications do respect round_durations + invariants and cannot fail *) + Stdlib.Option.get + @@ Round_repr.Durations.create_opt + ~first_round_duration + ~delay_increment_per_round + +let process_test_case (round_durations, ios, _) = + let open Round_repr in + List.iter_es + (fun (i, o) -> + round_of_int i >>?= fun round -> + let dur = Durations.round_duration round_durations round in + Assert.equal_int64 + ~loc:__LOC__ + (Int64.of_int o) + (Period_repr.to_seconds dur)) + ios.round_duration + >>=? fun () -> + let open Internals_for_test in + (* test [round_and_offset] *) + List.iter_es + (fun (level_offset, (round, ro)) -> + let level_offset = + Period_repr.of_seconds_exn (Int64.of_int level_offset) + in + Environment.wrap_tzresult (round_and_offset round_durations ~level_offset) + >>?= fun round_and_offset -> + Assert.equal_int32 + ~loc:__LOC__ + (Int32.of_int round) + (Round_repr.to_int32 round_and_offset.round) + >>=? fun () -> + Assert.equal_int64 + ~loc:__LOC__ + (Int64.of_int ro) + (Period_repr.to_seconds round_and_offset.offset)) + ios.round_and_offset + >>=? fun () -> + (* test [timestamp_of_round] *) + List.iter_es + (fun ((pred_ts, pred_round, round), o) -> + let predecessor_timestamp = Time_repr.of_seconds (Int64.of_int pred_ts) in + Lwt.return + ( Round_repr.of_int pred_round >>? fun predecessor_round -> + Round_repr.of_int round >>? fun round -> + timestamp_of_round + round_durations + ~predecessor_timestamp + ~predecessor_round + ~round ) + >>>=? fun ts -> + Assert.equal_int64 ~loc:__LOC__ (Int64.of_int o) (Time_repr.to_seconds ts)) + ios.timestamp_of_round + >>=? fun () -> + (* test [round_of_timestamp] *) + List.iter_es + (fun ((pred_ts, pred_round, ts), o) -> + let predecessor_timestamp = Time_repr.of_seconds (Int64.of_int pred_ts) in + Lwt.return + ( Round_repr.of_int pred_round >>? fun predecessor_round -> + round_of_timestamp + round_durations + ~predecessor_timestamp + ~predecessor_round + ~timestamp:(Time_repr.of_seconds (Int64.of_int ts)) ) + >>>=? fun round -> + Assert.equal_int32 + ~loc:__LOC__ + (Int32.of_int o) + (Round_repr.to_int32 round)) + ios.round_of_timestamp + +let test_round () = + let final_test_cases = + List.map + (fun ((first_round_duration, delay_increment_per_round), ios, name) -> + ( mk_round_durations first_round_duration delay_increment_per_round, + ios, + name )) + test_cases + in + (* TODO this could be run in the error monad instead of lwt *) + List.iter_es process_test_case final_test_cases + +let ts_add ts period = + match Timestamp.(ts +? period) with + | Ok ts' -> ts' + | Error _ -> Environment.Pervasives.failwith "timestamp add" + +let test_round_of_timestamp () = + let duration0 = Period.of_seconds_exn 1L in + Environment.wrap_tzresult + @@ Round.Durations.create + ~first_round_duration:duration0 + ~delay_increment_per_round:Period.one_second + >>?= fun round_durations -> + let predecessor_timestamp = Time.Protocol.epoch in + let level_start = ts_add predecessor_timestamp duration0 in + let rec loop ~expected_round ~elapsed_time = + if elapsed_time < 1000 then + let timestamp = + ts_add level_start (Period.of_seconds_exn (Int64.of_int elapsed_time)) + in + match + Round.round_of_timestamp + round_durations + ~predecessor_timestamp + ~timestamp + ~predecessor_round:Round.zero + with + | Ok round -> + Assert.equal_int32 + ~loc:__LOC__ + (Round.to_int32 round) + (Int32.of_int expected_round) + >>=? fun () -> + let elapsed_time = elapsed_time + (expected_round + 1) + and expected_round = 1 + expected_round in + loop ~expected_round ~elapsed_time + | Error _ -> failwith "error " + else return_unit + in + loop ~elapsed_time:0 ~expected_round:0 + +let round_of_timestamp_perf (duration0_int64, dipr) = + let duration0 = Period.of_seconds_exn duration0_int64 in + let delay_increment_per_round = Period.of_seconds_exn dipr in + let round_durations = + Stdlib.Option.get + @@ Round.Durations.create_opt + ~first_round_duration:duration0 + ~delay_increment_per_round + in + let predecessor_timestamp = Time.Protocol.epoch in + let level_start = ts_add predecessor_timestamp duration0 in + let max_ts = Int64.(sub (of_int32 Int32.max_int) duration0_int64) in + let rec loop i = + if i >= 0L then ( + let timestamp = + ts_add level_start (Period.of_seconds_exn (Int64.sub max_ts i)) + in + let t0 = Unix.gettimeofday () in + Round.round_of_timestamp + round_durations + ~predecessor_timestamp + ~timestamp + ~predecessor_round:Round.zero + >>? fun _round -> + let t1 = Unix.gettimeofday () in + let time = t1 -. t0 in + assert (time < 0.01) ; + loop (Int64.pred i)) + else ok () + in + Environment.wrap_tzresult (loop 1000L) >>?= fun () -> return_unit + +let default_round_durations_list = + [(1L, 1L); (1L, 2L); (1L, 3L); (2L, 3L); (2L, 4L)] + +let test_round_of_timestamp_perf () = + List.iter_es round_of_timestamp_perf default_round_durations_list + +let timestamp_of_round_perf (duration0_int64, dipr) = + let duration0 = Period.of_seconds_exn duration0_int64 in + let delay_increment_per_round = Period.of_seconds_exn dipr in + let round_durations = + Stdlib.Option.get + @@ Round.Durations.create_opt + ~first_round_duration:duration0 + ~delay_increment_per_round + in + let predecessor_timestamp = Time.Protocol.epoch in + let rec loop i = + if i >= 0l then ( + Round.of_int32 Int32.(sub max_int i) >>? fun round -> + let t0 = Unix.gettimeofday () in + Round.timestamp_of_round + round_durations + ~predecessor_timestamp + ~predecessor_round:Round.zero + ~round + >>? fun _ts -> + let t1 = Unix.gettimeofday () in + let time = t1 -. t0 in + assert (time < 0.01) ; + loop (Int32.pred i)) + else ok () + in + Environment.wrap_tzresult (loop 1000l) >>?= fun () -> return_unit + +let test_timestamp_of_round_perf () = + List.iter_es timestamp_of_round_perf default_round_durations_list + +let test_error_is_triggered_for_too_high_timestamp () = + let round_durations = + Stdlib.Option.get + @@ Round.Durations.create_opt + ~first_round_duration:Period.one_second + ~delay_increment_per_round:Period.one_second + in + + let predecessor_timestamp = Time.Protocol.epoch in + let res = + Round.round_of_timestamp + round_durations + ~predecessor_timestamp + ~predecessor_round:Round.zero + ~timestamp:(Time_repr.of_seconds Int64.max_int) + in + let res = Environment.wrap_tzresult res in + match res with + | Error _ -> + Assert.proto_error ~loc:__LOC__ res (function err -> + let error_info = + Error_monad.find_info_of_error (Environment.wrap_tzerror err) + in + error_info.title = "level offset too high") + | Ok _ -> Assert.error ~loc:__LOC__ res (fun _ -> false) + +let rec ( --> ) i j = + (* [i; i+1; ...; j] *) + if Compare.Int.(i > j) then [] else i :: (succ i --> j) + +let ts_of_round_inverse (duration0_int64, dipr) round_int = + let first_round_duration = Period.of_seconds_exn duration0_int64 in + let delay_increment_per_round = Period.of_seconds_exn dipr in + let round_durations = + Stdlib.Option.get + @@ Round.Durations.create_opt + ~first_round_duration + ~delay_increment_per_round + in + let predecessor_timestamp = Time.Protocol.epoch in + let predecessor_round = Round.zero in + Round.of_int round_int >>>?= fun round -> + Round.timestamp_of_round + round_durations + ~predecessor_timestamp + ~predecessor_round + ~round + >>>?= fun timestamp -> + Round.round_of_timestamp + round_durations + ~predecessor_timestamp + ~predecessor_round + ~timestamp + >>>?= fun round' -> + Round.to_int round' >>>?= fun round' -> + Assert.equal_int ~loc:__LOC__ round_int round' + +let test_ts_of_round_inverse () = + List.iter_es + (fun durations -> + List.iter_es + (ts_of_round_inverse durations) + ((0 --> 20) @ (60000 --> 60010))) + default_round_durations_list + >>=? fun () -> + List.iter_es + (ts_of_round_inverse (1L, 1L)) + (List.map (fun i -> Int32.to_int Int32.max_int - i) (1 --> 20)) + +let round_of_ts_inverse ~first_round_duration ~delay_increment_per_round ts = + Format.printf "ts = %Ld@." ts ; + let first_round_duration = Period.of_seconds_exn first_round_duration in + let delay_increment_per_round = + Period.of_seconds_exn delay_increment_per_round + in + Round.Durations.create ~first_round_duration ~delay_increment_per_round + >>>?= fun round_durations -> + let predecessor_timestamp = Time.Protocol.epoch in + let predecessor_round = Round.zero in + Timestamp.( +? ) predecessor_timestamp first_round_duration + >>>?= fun level_start -> + let start_of_round timestamp = + Round.round_of_timestamp + round_durations + ~predecessor_timestamp + ~predecessor_round + ~timestamp + >>>? fun round -> + Round.timestamp_of_round + round_durations + ~predecessor_timestamp + ~predecessor_round + ~round + >>>? fun t -> ok (round, t) + in + Period.of_seconds_exn ts |> Timestamp.( +? ) level_start + >>>?= fun timestamp -> + start_of_round timestamp >>?= fun (round, ts_start_of_round) -> + Assert.leq_int64 + ~loc:__LOC__ + (Timestamp.to_seconds ts_start_of_round) + (Timestamp.to_seconds timestamp) + >>=? fun () -> + let pred ts = Period.one_second |> Timestamp.( - ) ts in + let rec iter ts = + start_of_round ts >>?= fun (round', ts_start_of_round') -> + Assert.equal_int64 + ~loc:__LOC__ + (Timestamp.to_seconds ts_start_of_round) + (Timestamp.to_seconds ts_start_of_round') + >>=? fun () -> + Assert.equal_int32 + ~loc:__LOC__ + (Round.to_int32 round) + (Round.to_int32 round') + >>=? fun () -> + if Timestamp.(ts > ts_start_of_round') then iter (pred ts) else return_unit + in + if Timestamp.(timestamp > ts_start_of_round) then iter (pred timestamp) + else return_unit + +let test_round_of_ts_inverse () = + List.iter_es + (fun (first_round_duration, delay_increment_per_round) -> + List.iter_es + (fun ts -> + round_of_ts_inverse + ~first_round_duration + ~delay_increment_per_round + (Int64.of_int ts)) + ((0 --> 20) @ (60000 --> 60010))) + default_round_durations_list + >>=? fun () -> + List.iter_es + (fun ts -> + Format.printf "%Ld@." ts ; + round_of_ts_inverse + ~first_round_duration:1L + ~delay_increment_per_round:2L + ts) + (List.map + (fun i -> Int64.of_int (Int32.to_int Int32.max_int - i)) + (0 --> 20)) + +let test_level_offset_of_round () = + let rd1 = + let first_round_duration = 3 in + let delay_increment_per_round = 1 in + mk_round_durations first_round_duration delay_increment_per_round + in + List.iter_es + (fun (round_durations, tests) -> + List.iter_es + (fun (round, expected_offset) -> + Lwt.return @@ Environment.wrap_tzresult @@ Round_repr.of_int round + >>=? fun round -> + Lwt.return @@ Environment.wrap_tzresult + @@ Round_repr.level_offset_of_round round_durations ~round + >>=? fun computed_offset -> + Assert.equal_int64 + ~loc:__LOC__ + (Period_repr.to_seconds computed_offset) + (Int64.of_int expected_offset)) + tests) + [ + (rd1, [(0, 0); (1, 3); (2, 7)]); + (mk_round_durations 3 3, [(0, 0); (1, 3); (2, 9); (3, 18)]); + ] + +let tests = + Tztest. + [ + tztest "test_level_offset_of_round" `Quick test_level_offset_of_round; + tztest "test Round_duration" `Quick test_round; + tztest "round_of_timestamp" `Quick test_round_of_timestamp; + tztest "round_of_timestamp_perf" `Quick test_round_of_timestamp_perf; + tztest "timestamp_of_round_perf" `Quick test_timestamp_of_round_perf; + tztest + "test level offset too high error is triggered" + `Quick + test_error_is_triggered_for_too_high_timestamp; + tztest "round_of_ts (ts_of_round r) = r" `Quick test_ts_of_round_inverse; + tztest + "ts_of_round (round_of_ts ts) <= ts" + `Quick + test_round_of_ts_inverse; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_sampler.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_sampler.ml new file mode 100644 index 000000000000..630794d84a96 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_sampler.ml @@ -0,0 +1,270 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol Library + Invocation: dune exec src/proto_alpha/lib_protocol/test/test_sampler.exe + Subject: Sampler +*) + +open Lib_test.Qcheck_helpers +open Protocol.Sampler + +(* ------------------------------------------------------------------------- *) +(* Helpers *) + +module Int = struct + include Int + + let hash = Hashtbl.hash +end + +let equal_array elt_eq arr1 arr2 = + Array.length arr1 = Array.length arr2 + && Stdlib.List.for_all2 elt_eq (Array.to_list arr1) (Array.to_list arr2) + +(* Support of a distribution on Z (sorted, with potential duplicates) *) +let support cmp array = + Array.to_seq array |> Seq.map fst |> List.of_seq |> List.sort cmp + |> Array.of_list + +(* Support of a distribution on Z (sorted, without duplicates) *) +let support_uniq cmp array = + Array.to_seq array |> Seq.map fst |> List.of_seq |> List.sort_uniq cmp + |> Array.of_list + +module type Std = sig + type t + + val equal : t -> t -> bool + + val compare : t -> t -> int + + val hash : t -> int +end + +module Helpers = struct + let sample_n_times (total : int) sample = + let rec loop n acc = + if n = 0 then acc + else + let res = sample () in + loop (n - 1) (res :: acc) + in + loop total [] + + let empirical_distribution : + type a. + (module Std with type t = a) -> + nsamples:int -> + (unit -> a) -> + (a * int) array = + fun (module H) ~nsamples sampler -> + let module Table = Hashtbl.Make (H) in + let samples = sample_n_times nsamples sampler in + let table = Table.create 127 in + List.iter + (fun sample -> + let count = Option.value ~default:0 (Table.find table sample) in + Table.replace table sample (count + 1)) + samples ; + let result = Table.to_seq table |> Array.of_seq in + (* check that the support of [result] has no duplicate elements (should + be true since we use [replace]). *) + assert ( + equal_array + H.equal + (support H.compare result) + (support_uniq H.compare result)) ; + result +end + +let normalize : ('a * int) array -> ('a * Q.t) array = + fun empirical -> + let total = + Array.fold_left + (fun acc (_, weight) -> Z.add (Z.of_int weight) acc) + Z.zero + empirical + in + Array.map (fun (n, weight) -> (n, Q.(Z.of_int weight /// total))) empirical + +let pp_dist pp fmtr dist = + let l = Array.to_list dist in + Format.pp_print_list + ~pp_sep:(fun fmtr () -> Format.fprintf fmtr ",") + (fun fmtr (elt, w) -> Format.fprintf fmtr "(%a, %f)" pp elt (Q.to_float w)) + fmtr + l + +let linf (dist : ('a * Q.t) array) pmf = + Array.fold_left (fun acc (n, q) -> Q.(max acc (abs (pmf n - q)))) Q.zero dist + +(* ------------------------------------------------------------------------- *) + +let state = + Random.State.make + [| + 0x1337533D; + 71287309; + 666932349; + 719132214; + 461480042; + 387006837; + 443018964; + 450865457; + 901711679; + 833353016; + 397060904; + |] + +module Make_test (Mass : sig + include Mass + + val to_float : t -> float +end) (S : sig + val sample : int_bound:int -> mass_bound:Mass.t -> int * Mass.t +end) = +struct + let make p = + let module Probability = Internal_for_tests.Make (Mass) in + let measure = List.mapi (fun i p -> (i, p)) p in + let total_mass = List.fold_left Mass.add Mass.zero p in + let state = Probability.create measure in + let sampler = Probability.sample state in + let empirical = + normalize + @@ Helpers.empirical_distribution + (module Int) + ~nsamples:5_000_000 + (fun () -> sampler S.sample) + in + (* We need to rescale the empirical to match that the total mass is not necessarily one. *) + let empirical = + let rescaling = Q.of_float (Mass.to_float total_mass) in + Array.map (fun (x, q) -> (x, Q.mul q rescaling)) empirical + in + (* map the mass to Q to better measure the error *) + let truth = + let array = + measure |> List.to_seq + |> Seq.map (fun (_, mass) -> Q.of_float (Mass.to_float mass)) + |> Array.of_seq + in + fun i -> array.(i) + in + let error = linf empirical truth in + let max_error = 0.001 *. Mass.to_float total_mass in + if not Q.(error < Q.of_float max_error) then + QCheck.Test.fail_reportf + "didn't converge (%f)@.%a" + (Q.to_float error) + (pp_dist Format.pp_print_int) + empirical ; + true +end + +(* Testing the alias sampler with float-valued measures *) + +module Probability_mass_float : Mass with type t = float = struct + type t = float + + let encoding = Data_encoding.float + + let zero = 0.0 + + let of_int = float_of_int + + let mul = ( *. ) + + let add = ( +. ) + + let sub = ( -. ) + + let ( = ) = Float.equal + + let ( <= ) (x : t) (y : t) = x <= y + + let ( < ) (x : t) (y : t) = x < y +end + +module Test_float = + Make_test + (struct + include Probability_mass_float + + let to_float x = x + end) + (struct + let sample ~int_bound ~mass_bound = + (Random.State.int state int_bound, Random.State.float state mass_bound) + end) + +(* Testing the alias sampler with Z-valued measures *) + +module Probability_mass_z : Mass with type t = Z.t = struct + let encoding = Data_encoding.z + + include Z + include Z.Compare +end + +module Test_z = + Make_test + (struct + include Probability_mass_z + + let to_float = Z.to_float + end) + (struct + let sample ~int_bound ~mass_bound = + ( Random.State.int state int_bound, + Z.of_int64 (Random.State.int64 state (Z.to_int64 mass_bound)) ) + end) + +let qcheck_wrap = qcheck_wrap ~rand:state + +let alias_float_test = + QCheck.Test.make + ~count:100 + ~name:"alias_float" + QCheck.(list_of_size (Gen.int_range 1 20) pos_float) + Test_float.make + +let alias_z_test = + QCheck.Test.make + ~count:100 + ~name:"alias_z" + QCheck.( + list_of_size + (Gen.int_range 1 20) + (make Gen.(nat >>= fun n -> return (Z.of_int n)))) + Test_z.make + +let () = + Alcotest.run + "Sampling" + [("sampling", qcheck_wrap [alias_float_test; alias_z_test])] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_sapling.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_sapling.ml new file mode 100644 index 000000000000..137d1cf8ca92 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_sapling.ml @@ -0,0 +1,1126 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (Sapling) + Invocation: cd src/proto_alpha/lib_protocol/test + dune exec ./main.exe -- test "^sapling$" + Subject: On the privacy-preserving library Sapling +*) + +open Protocol +open Alpha_context +open Test_tez + +let ( >>??= ) x y = + match x with + | Ok s -> y s + | Error err -> Lwt.return @@ Error (Environment.wrap_tztrace err) + +module Raw_context_tests = struct + open Sapling_helpers.Common + + (* This test adds to the first 100 positions in the commitments tree the + constant value `uncommitted` for which we know the corresponding root and + tests that the returned root is as expected. *) + let commitments_add_uncommitted () = + Context.init 1 >>=? fun (b, _) -> + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >>= wrap + >>=? fun ctx -> + let module H = Tezos_sapling.Core.Client.Hash in + let cm = H.uncommitted ~height:0 in + let expected_root = H.uncommitted ~height:32 in + Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx + >>= wrap + >>=? fun (ctx, id) -> + Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> + List.fold_left_es + (fun ctx pos -> + Sapling_storage.Commitments.get_root ctx id >>= wrap + >>=? fun (ctx, root) -> + assert (root = expected_root) ; + Sapling_storage.Commitments.add + ctx + id + [H.to_commitment cm] + (Int64.of_int pos) + >>= wrap + >>=? fun (ctx, _size) -> + Sapling_storage.Commitments.get_root ctx id >>= wrap + >|=? fun (ctx, root) -> + assert (root = expected_root) ; + ctx) + ctx + (0 -- 99) + >>=? fun _ctx -> return_unit + + (* Nullifiers don't check for duplicates are it's done by verify_update, + however committing to disk twice the same nf causes a storage error by + trying to initialize the same key twice. *) + let nullifier_double () = + Context.init 1 >>=? fun (b, _) -> + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >>= wrap + >>=? fun ctx -> + Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx + >>= wrap + >>=? fun (ctx, id) -> + Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> + let nf = gen_nf () in + let open Sapling_storage in + let state = + {id = Some id; diff = Sapling_storage.empty_diff; memo_size = 0} + in + let state = nullifiers_add state nf in + let state = nullifiers_add state nf in + assert (Compare.List_length_with.(state.diff.nullifiers = 2)) ; + Sapling_storage.Nullifiers.size ctx id >>= wrap >>=? fun disk_size -> + assert (disk_size = 0L) ; + Sapling_storage.apply_diff ctx id state.diff |> assert_error + + (* In this test we add two lists of nullifiers to the state, one is applied to + the context (committed to disk) and one is kept in kept in a diff (only in + memory). We then check that nullifier_mem answers true for those two lists + and false for a third one. *) + let nullifier_test () = + Context.init 1 >>=? fun (b, _) -> + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >>= wrap + >>=? fun ctx -> + Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx + >>= wrap + >>=? fun (ctx, id) -> + Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> + let nf_list_ctx = + List.init ~when_negative_length:() 10 (fun _ -> gen_nf ()) |> function + | Error () -> assert false (* 10 > 0 *) + | Ok nf_list_ctx -> nf_list_ctx + in + let state = + List.fold_left + (fun state nf -> Sapling_storage.nullifiers_add state nf) + {id = Some id; diff = Sapling_storage.empty_diff; memo_size = 0} + nf_list_ctx + in + Sapling_storage.apply_diff ctx id state.diff >>= wrap >>=? fun (ctx, _) -> + let nf_list_diff = + List.init ~when_negative_length:() 10 (fun _ -> gen_nf ()) |> function + | Error () -> assert false (* 10 > 0 *) + | Ok nf_list_diff -> nf_list_diff + in + let state = + List.fold_left + (fun state nf -> Sapling_storage.nullifiers_add state nf) + state + nf_list_diff + in + List.iter_ep + (fun nf -> + Sapling_storage.nullifiers_mem ctx state nf >>= wrap + >>=? fun (_, bool) -> + assert bool ; + return_unit) + (nf_list_ctx @ nf_list_diff) + >>=? fun () -> + let nf_list_absent = + List.init 10 ~when_negative_length:() (fun _ -> gen_nf ()) |> function + | Error () -> assert false (* 10 > 0 *) + | Ok nf_list_absent -> nf_list_absent + in + List.iter_ep + (fun nf -> + Sapling_storage.nullifiers_mem ctx state nf >>= wrap + >>=? fun (_, bool) -> + assert (not bool) ; + return_unit) + nf_list_absent + + (* This test applies a diff with tuples of ciphertext, commitment. Then it + checks the result of get_from with different indexes. *) + let cm_cipher_test () = + Random.self_init () ; + let memo_size = Random.int 200 in + Context.init 1 >>=? fun (b, _) -> + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >>= wrap + >>=? fun ctx -> + Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx + >>= wrap + >>=? fun (ctx, id) -> + Sapling_storage.init ctx id ~memo_size >>= wrap >>=? fun ctx -> + Sapling_storage.state_from_id ctx id >>= wrap >>=? fun (diff, ctx) -> + let list_added = + List.init ~when_negative_length:() 10 (fun _ -> + gen_cm_cipher ~memo_size ()) + |> function + | Error () -> assert false (* 10 > 0 *) + | Ok list_added -> list_added + in + let state = Sapling_storage.add diff list_added in + Sapling_storage.apply_diff ctx id state.diff >>= wrap >>=? fun (ctx, _) -> + let rec test_from from until expected = + if from > until then return_unit + else + Sapling_storage.Ciphertexts.get_from ctx id from >>= wrap + >>=? fun (ctx, result) -> + let expected_cipher = List.map snd expected in + assert (result = expected_cipher) ; + Sapling_storage.Commitments.get_from ctx id from >>= wrap + >>=? fun result -> + let expected_cm = List.map fst expected in + assert (result = expected_cm) ; + test_from + (Int64.succ from) + until + (WithExceptions.Option.get ~loc:__LOC__ @@ List.tl expected) + in + test_from 0L 9L list_added + + (* This test tests the insertion of a list vs inserting one by one. + It does so by checking the equality of the roots. *) + let list_insertion_test () = + Random.self_init () ; + let memo_size = Random.int 200 in + Context.init 1 >>=? fun (b, _) -> + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >>= wrap + >>=? fun ctx -> + Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx + >>= wrap + >>=? fun (ctx, id_one_by_one) -> + Sapling_storage.init ctx id_one_by_one ~memo_size >>= wrap >>=? fun ctx -> + let list_to_add = + fst @@ List.split + @@ (List.init ~when_negative_length:() 33 (fun _ -> + gen_cm_cipher ~memo_size ()) + |> function + | Error () -> assert false (* 33 > 0 *) + | Ok r -> r) + in + let rec test counter ctx = + if counter >= 32 then return_unit + else + (* add a single cm to the existing tree *) + Sapling_storage.Commitments.add + ctx + id_one_by_one + [ + WithExceptions.Option.get ~loc:__LOC__ + @@ List.nth list_to_add counter; + ] + (Int64.of_int counter) + >>= wrap + (* create a new tree and add a list of cms *) + >>=? fun (ctx, _size) -> + Lazy_storage_diff.fresh + Lazy_storage_kind.Sapling_state + ~temporary:false + ctx + >>= wrap + >>=? fun (ctx, id_all_at_once) -> + Sapling_storage.init ctx id_all_at_once ~memo_size >>= wrap + >>=? fun ctx -> + Sapling_storage.Commitments.add + ctx + id_all_at_once + (List.init ~when_negative_length:() (counter + 1) (fun i -> + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth list_to_add i) + |> function + | Error () -> assert false (* counter >= 0*) + | Ok r -> r) + 0L + >>= wrap + >>=? fun (ctx, _size) -> + Sapling_storage.Commitments.get_root ctx id_one_by_one >>= wrap + >>=? fun (ctx, root_one_by_one) -> + Sapling_storage.Commitments.get_root ctx id_all_at_once >>= wrap + >>=? fun (ctx, root_all_at_once) -> + assert (root_all_at_once = root_one_by_one) ; + test (counter + 1) ctx + in + test 0 ctx + + (* This test adds 10 more roots the maximum capacity, all at different + levels, and checks that all but the first 10 are stored. + Then it adds one in the diff and checks it is stored. + Then it adds 10 at the same level and check that only the last one is + stored. *) + let root_test () = + let open Tezos_sapling.Core in + let gen_root () = + Data_encoding.Binary.of_bytes_exn + Validator.Hash.encoding + (Hacl.Rand.gen 32) + in + let roots_ctx = + List.init + ~when_negative_length:() + (Int32.to_int Sapling_storage.Roots.size + 10) + (fun _ -> gen_root ()) + |> function + | Error () -> assert false (* size >= 0 *) + | Ok roots_ctx -> roots_ctx + in + Context.init 1 >>=? fun (b, _) -> + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >>= wrap + >>=? fun ctx -> + Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx + >>= wrap + >>=? fun (ctx, id) -> + Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> + (* Add one root per level to the context *) + List.fold_left_es + (fun (ctx, cnt) root -> + Sapling_storage.Roots.add ctx id root >>= wrap >>=? fun ctx -> + (* Very low level way to "bake" a block. It would be better to use the + helpers functions but they complicate the access to the raw_context. *) + Raw_context.prepare + ~level:(Int32.add b.header.shell.level cnt) + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + (Raw_context.recover ctx) + >>= wrap + >|=? fun ctx -> (ctx, Int32.succ cnt)) + (ctx, 0l) + roots_ctx + >>=? fun (ctx, _) -> + (* Check mem on all the roots in the context. *) + let state = + Sapling_storage. + {id = Some id; diff = Sapling_storage.empty_diff; memo_size = 0} + in + List.fold_left_es + (fun i root -> + Sapling_storage.root_mem ctx state root >>= wrap >|=? fun bool -> + assert (if i < 10 then not bool else bool) ; + i + 1) + 0 + roots_ctx + >>=? fun _ -> + (* Add roots w/o increasing the level *) + let roots_same_level = + List.init ~when_negative_length:() 10 (fun _ -> gen_root ()) |> function + | Error () -> assert false (* 10 > 0 *) + | Ok roots_same_level -> roots_same_level + in + List.fold_left_es + (fun ctx root -> Sapling_storage.Roots.add ctx id root >>= wrap) + ctx + roots_same_level + >>=? fun ctx -> + List.fold_left_es + (fun (i, ctx) root -> + Sapling_storage.root_mem ctx state root >>= wrap >|=? fun bool -> + assert (if i < 9 then not bool else bool) ; + (i + 1, ctx)) + (0, ctx) + roots_same_level + >>=? fun _ -> return_unit + + let test_get_memo_size () = + Context.init 1 >>=? fun (b, _) -> + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >>= wrap + >>=? fun ctx -> + Lazy_storage_diff.fresh Lazy_storage_kind.Sapling_state ~temporary:false ctx + >>= wrap + >>=? fun (ctx, id) -> + Sapling_storage.init ctx id ~memo_size:0 >>= wrap >>=? fun ctx -> + Sapling_storage.get_memo_size ctx id >>= wrap >|=? fun memo_size -> + assert (memo_size = 0) +end + +module Alpha_context_tests = struct + open Sapling_helpers.Alpha_context_helpers + + (* Create a transaction with memo_size 1, test that is validates with a newly + created empty_state with memo_size 1 and does not with memo_size 0. *) + let test_verify_memo () = + init () >>=? fun ctx -> + let sk = + Tezos_sapling.Core.Wallet.Spending_key.of_seed + (Tezos_crypto.Hacl.Rand.gen 32) + in + let vt = + let ps = Tezos_sapling.Storage.empty ~memo_size:0 in + (* the dummy output will have memo_size 0 *) + Tezos_sapling.Forge.forge_transaction + ~number_dummy_outputs:1 + [] + [] + sk + "anti-replay" + ps + in + verify_update ctx vt ~memo_size:0 |> assert_some >>=? fun _ -> + verify_update ctx vt ~memo_size:1 |> assert_none + + (* Bench the proving and validation time of shielding and transferring several + tokens. *) + let test_bench_phases () = + init () >>=? fun ctx -> + let rounds = 5 in + Printf.printf "\nrounds: %d\n" rounds ; + let w = wallet_gen () in + let cs = Tezos_sapling.Storage.empty ~memo_size:8 in + (* one verify_update to get the id *) + let vt = transfer w cs [] in + verify_update ctx vt |> assert_some >>=? fun (ctx, id) -> + client_state_alpha ctx id >>=? fun cs -> + let start = Unix.gettimeofday () in + let vts = List.map (fun _ -> transfer w cs []) (1 -- rounds) in + let ctime_shields = Unix.gettimeofday () -. start in + Printf.printf "client_shields %f\n" ctime_shields ; + let start = Unix.gettimeofday () in + List.fold_left_es + (fun ctx vt -> + verify_update ctx ~id vt |> assert_some >|=? fun (ctx, _id) -> ctx) + ctx + vts + >>=? fun ctx -> + let vtime_shields = Unix.gettimeofday () -. start in + Printf.printf "valdtr_shields %f\n" vtime_shields ; + client_state_alpha ctx id >>=? fun cs -> + let start = Unix.gettimeofday () in + let vts = List.map (fun i -> transfer w cs [i]) (1 -- rounds) in + let ctime_transfers = Unix.gettimeofday () -. start in + Printf.printf "client_txs %f\n" ctime_transfers ; + let start = Unix.gettimeofday () in + List.fold_left_es + (fun ctx vt -> + verify_update ctx ~id vt |> assert_some >|=? fun (ctx, _id) -> ctx) + ctx + vts + >|=? fun _ctx -> + let vtime_transfers = Unix.gettimeofday () -. start in + Printf.printf "valdtr_txs %f\n" vtime_transfers + + (* Transfer several times the same token. *) + let test_bench_fold_over_same_token () = + init () >>=? fun ctx -> + let rounds = 5 in + let w = wallet_gen () in + let cs = Tezos_sapling.Storage.empty ~memo_size:8 in + (* one verify_update to get the id *) + let vt = transfer w cs [] in + verify_update ctx vt |> assert_some >>=? fun (ctx, id) -> + let rec loop cnt ctx = + if cnt >= rounds then return_unit + else + (* inefficient: re-synch from scratch at each round *) + client_state_alpha ctx id >>=? fun cs -> + let vt = transfer w cs [cnt] in + verify_update ctx ~id vt |> assert_some >>=? fun (ctx, _id) -> + loop (cnt + 1) ctx + in + loop 0 ctx + + (* + The following tests trigger all the branches of + Sapling_validator.verify_update. + The function performs several checks and returns None in case of failure. + During development the function was modified to throw a different exception + for each of its checks so to be sure that they were reached. + *) + + (* Test that double spending the same input fails the nf check. *) + let test_double_spend_same_input () = + init () >>=? fun ctx -> + let w = wallet_gen () in + let cs = Tezos_sapling.Storage.empty ~memo_size:8 in + (* one verify_update to get the id *) + let vt = transfer w cs [] in + verify_update ctx vt |> assert_some >>=? fun (ctx, id) -> + client_state_alpha ctx id >>=? fun cs -> + let vt = transfer w cs [0] in + verify_update ctx ~id vt |> assert_some >>=? fun (_ctx, id) -> + let vt = transfer w cs [0; 0] in + verify_update ctx ~id vt |> assert_none + + let test_verifyupdate_one_transaction () = + init () >>=? fun ctx -> + let w = wallet_gen () in + let cs = Tezos_sapling.Storage.empty ~memo_size:8 in + let vt = transfer w cs [] in + verify_update ctx vt |> assert_some >>=? fun (ctx, id) -> + client_state_alpha ctx id >>=? fun cs -> + let vt = transfer w cs [0] in + (* fails sig check because of wrong balance *) + let vt_broken = + Tezos_sapling.Core.Validator.UTXO. + {vt with balance = Int64.(succ vt.balance)} + in + verify_update ctx ~id vt_broken |> assert_none >>=? fun () -> + (* randomize one output to fail check outputs *) + (* don't randomize the ciphertext as it is not part of the proof *) + let open Tezos_sapling.Core.Client.UTXO in + let o = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd vt.outputs in + let o_wrong_cm = + { + o with + cm = randomized_byte o.cm Tezos_sapling.Core.Client.Commitment.encoding; + } + in + let vt_broken = + Tezos_sapling.Core.Validator.UTXO.{vt with outputs = [o_wrong_cm]} + in + verify_update ctx ~id vt_broken |> assert_none >>=? fun () -> + (* position inside the cv *) + let pos = Random.int 32 in + let o_wrong_cv = + { + o with + ciphertext = + randomized_byte + ~pos + o.ciphertext + Tezos_sapling.Core.Client.Ciphertext.encoding; + } + in + let vt_broken = + Tezos_sapling.Core.Validator.UTXO.{vt with outputs = [o_wrong_cv]} + in + verify_update ctx ~id vt_broken |> assert_none + + let test_verifyupdate_two_transactions () = + init () >>=? fun ctx -> + let w = wallet_gen () in + let cs = Tezos_sapling.Storage.empty ~memo_size:8 in + (* generate the first storage *) + let vt = transfer w cs [] in + verify_update ctx vt |> assert_some >>=? fun (ctx, id1) -> + client_state_alpha ctx id1 >>=? fun cs1 -> + let vt1 = transfer w cs1 [0] in + (* generate the second storage *) + let vt = transfer w cs [] in + verify_update ctx vt |> assert_some >>=? fun (ctx, id2) -> + client_state_alpha ctx id2 >>=? fun cs2 -> + let vt2 = transfer w cs2 [0] in + (* fail root check *) + verify_update ctx ~id:id1 vt2 |> assert_none >>=? fun () -> + (* Swap the root so that it passes the root_mem check but fails + the input check *) + let vt1_broken = + Tezos_sapling.Core.Validator.UTXO.{vt2 with root = vt1.root} + in + verify_update ctx ~id:id1 vt1_broken |> assert_none >>=? fun () -> + (* fail the sig check *) + let vt1_broken = + Tezos_sapling.Core.Validator.UTXO.{vt1 with outputs = vt2.outputs} + in + verify_update ctx ~id:id1 vt1_broken |> assert_none +end + +module Interpreter_tests = struct + open Sapling_helpers.Interpreter_helpers + + let parameters_of_list transactions = + let string = "{ " ^ String.concat " ; " transactions ^ " }" in + Alpha_context.Script.(lazy_expr (Expr.from_string string)) + + (* In this test we use a contract which takes a list of transactions, applies + all of them, and assert all of them are correct. It also enforces a 1-to-1 + conversion with mutez by asking an amount to shield and asking for a pkh to + unshield. + We create 2 keys a and b. We originate the contract, then do two lists of + shield for a, then transfers several outputs to b while unshielding, then + transfer all of b inputs to a while adding dummy inputs and outputs. + At last we fail we make a failing transaction. *) + let test_shielded_tez () = + init () >>=? fun (genesis, baker, src0, src1) -> + let memo_size = 8 in + originate_contract "contracts/sapling_contract.tz" "{ }" src0 genesis baker + >>=? fun (dst, b1, anti_replay) -> + let wa = wallet_gen () in + let (list_transac, total) = + shield + ~memo_size + wa.sk + 4 + wa.vk + (Format.sprintf "Pair 0x%s None") + anti_replay + in + let parameters = parameters_of_list list_transac in + (* a does a list of shield transaction *) + transac_and_sync ~memo_size b1 parameters total src0 dst baker + >>=? fun (b2, _state) -> + (* we shield again on another block, forging with the empty state *) + let (list_transac, total) = + shield + ~memo_size + wa.sk + 4 + wa.vk + (Format.sprintf "Pair 0x%s None") + anti_replay + in + let parameters = parameters_of_list list_transac in + (* a does a list of shield transaction *) + transac_and_sync ~memo_size b2 parameters total src0 dst baker + >>=? fun (b3, state) -> + (* address that will receive an unshield *) + Context.Contract.balance (B b3) src1 >>=? fun balance_before_shield -> + (* address that will receive an unshield *) + let wb = wallet_gen () in + let list_addr = gen_addr 15 wb.vk in + let list_forge_input = + List.init ~when_negative_length:() 14 (fun pos_int -> + let pos = Int64.of_int pos_int in + let forge_input = + snd + (Tezos_sapling.Forge.Input.get state pos wa.vk + |> WithExceptions.Option.get ~loc:__LOC__) + in + forge_input) + |> function + | Error () -> assert false (* 14 > 0 *) + | Ok list_forge_input -> list_forge_input + in + let list_forge_output = + List.map + (fun addr -> Tezos_sapling.Forge.make_output addr 1L (Bytes.create 8)) + list_addr + in + let hex_transac = + to_hex + (Tezos_sapling.Forge.forge_transaction + ~number_dummy_inputs:0 + ~number_dummy_outputs:0 + list_forge_input + list_forge_output + wa.sk + anti_replay + state) + Tezos_sapling.Core.Client.UTXO.transaction_encoding + in + let hex_pkh = + to_hex + (Alpha_context.Contract.is_implicit src1 + |> WithExceptions.Option.get ~loc:__LOC__) + Signature.Public_key_hash.encoding + in + let string = + Format.sprintf "{Pair 0x%s (Some 0x%s) }" hex_transac hex_pkh + in + let parameters = + Alpha_context.Script.(lazy_expr (Expr.from_string string)) + in + (* a transfers to b and unshield some money to src_2 (the pkh) *) + transac_and_sync ~memo_size b3 parameters 0 src0 dst baker + >>=? fun (b4, state) -> + Context.Contract.balance (B b4) src1 >>=? fun balance_after_shield -> + let diff_due_to_shield = + Int64.sub + (Test_tez.to_mutez balance_after_shield) + (Test_tez.to_mutez balance_before_shield) + in + (* The balance after shield is obtained from the balance before shield by + the shield specific update. *) + (* The inputs total [total] mutez and 15 of those are transfered in shielded tez *) + Assert.equal_int ~loc:__LOC__ (Int64.to_int diff_due_to_shield) (total - 15) + >>=? fun () -> + let list_forge_input = + List.init ~when_negative_length:() 15 (fun i -> + let pos = Int64.of_int (i + 14 + 14) in + let forge_input = + snd + (Tezos_sapling.Forge.Input.get state pos wb.vk + |> WithExceptions.Option.get ~loc:__LOC__) + in + forge_input) + |> function + | Error () -> assert false (* 14 > 0 *) + | Ok list_forge_input -> list_forge_input + in + let addr_a = + snd + @@ Tezos_sapling.Core.Client.Viewing_key.new_address + wa.vk + Tezos_sapling.Core.Client.Viewing_key.default_index + in + let output = Tezos_sapling.Forge.make_output addr_a 15L (Bytes.create 8) in + let hex_transac = + to_hex + (Tezos_sapling.Forge.forge_transaction + ~number_dummy_inputs:2 + ~number_dummy_outputs:2 + list_forge_input + [output] + wb.sk + anti_replay + state) + Tezos_sapling.Core.Client.UTXO.transaction_encoding + in + let string = Format.sprintf "{Pair 0x%s None }" hex_transac in + let parameters = + Alpha_context.Script.(lazy_expr (Expr.from_string string)) + in + (* b transfers to a with dummy inputs and outputs *) + transac_and_sync ~memo_size b4 parameters 0 src0 dst baker + >>=? fun (b, _state) -> + (* Here we fail by doing the same transaction again*) + Incremental.begin_construction b >>=? fun incr -> + let fee = Test_tez.of_int 10 in + Op.transaction ~fee (B b) src0 dst Tez.zero ~parameters + >>=? fun operation -> + Incremental.add_operation (* TODO make more precise *) + ~expect_failure:(fun _ -> return_unit) + incr + operation + >>=? fun _incr -> return_unit + + let test_push_sapling_state_should_be_forbidden () = + init () + (* Originating a contract to get a sapling_state with ID 0, used in the next contract *) + >>=? + fun (block, baker, src, _) -> + originate_contract "contracts/sapling_contract.tz" "{ }" src block baker + >>=? fun _ -> + (* Originating the next contract should fail *) + originate_contract + "contracts/sapling_push_sapling_state.tz" + "{ }" + src + block + baker + >>= function + | Error + [ + Environment.Ecoproto_error (Script_tc_errors.Ill_typed_contract _); + Environment.Ecoproto_error + (Script_tc_errors.Unexpected_lazy_storage _); + ] -> + return_unit + | _ -> assert false + + let test_use_state_from_other_contract_and_transact () = + (* + Attempt to use a sapling state of a contract A in a contract B + *) + init () (* Originating the contracts *) >>=? fun (block, baker, src, _) -> + let memo_size = 8 in + (* originate_contract "contracts/sapling_contract.tz" "{ }" src block baker + >>=? fun (_shielded_pool_contract_address, block, _anti_replay_shielded_pool) + -> *) + originate_contract + "contracts/sapling_use_existing_state.tz" + "{ }" + src + block + baker + >>=? fun (existing_state_contract_address, block, anti_replay_2) -> + (* we create one shielding transaction and transform it in Micheline to use + it as a parameter + *) + let wa = wallet_gen () in + let (transactions, _total) = + shield + ~memo_size + wa.sk + 1 + wa.vk + (Format.sprintf "(Pair 0x%s 0)") + anti_replay_2 + in + let transaction = + WithExceptions.Option.get ~loc:__LOC__ @@ List.hd transactions + in + let parameters = + Alpha_context.Script.(lazy_expr (Expr.from_string transaction)) + in + transac_and_sync + ~memo_size + block + parameters + 0 + src + existing_state_contract_address + baker + >|= function + | Ok _ -> Alcotest.failf "Unexpected operations success" + | Error errs -> + assert ( + List.exists + (function + | Environment.Ecoproto_error + (Tezos_raw_protocol_012_PsiThaCa.Script_tc_errors + .Unexpected_forged_value _) -> + true + | _ -> false) + errs) ; + Result.return_unit + + (* In this test we do two transactions in one block and same two in two block. + We check that the sate is the same expect for roots. + The second transaction is possible only if the first one is done. *) + let test_transac_and_block () = + init () >>=? fun (b, baker, src, _) -> + let memo_size = 8 in + originate_contract "contracts/sapling_contract.tz" "{ }" src b baker + >>=? fun (dst, block_start, anti_replay) -> + let {sk; vk} = wallet_gen () in + let hex_transac_1 = hex_shield ~memo_size {sk; vk} anti_replay in + let string_1 = Format.sprintf "{Pair %s None }" hex_transac_1 in + let parameters_1 = + Alpha_context.Script.(lazy_expr (Expr.from_string string_1)) + in + transac_and_sync ~memo_size block_start parameters_1 15 src dst baker + >>=? fun (block_1, state) -> + let intermediary_root = Tezos_sapling.Storage.get_root state in + let addr = + snd + @@ Tezos_sapling.Core.Wallet.Viewing_key.(new_address vk default_index) + in + let output = Tezos_sapling.Forge.make_output addr 15L (Bytes.create 8) in + let hex_transac_2 = + "0x" + ^ to_hex + (Tezos_sapling.Forge.forge_transaction + [ + snd + (Tezos_sapling.Forge.Input.get state 0L vk + |> WithExceptions.Option.get ~loc:__LOC__); + ] + [output] + sk + anti_replay + state) + Tezos_sapling.Core.Client.UTXO.transaction_encoding + in + let string_2 = Format.sprintf "{Pair %s None }" hex_transac_2 in + let parameters_2 = + Alpha_context.Script.(lazy_expr (Expr.from_string string_2)) + in + transac_and_sync ~memo_size block_1 parameters_2 0 src dst baker + >>=? fun (block_1, state_1) -> + let final_root = Tezos_sapling.Storage.get_root state_1 in + Alpha_services.Contract.single_sapling_get_diff + Block.rpc_ctxt + block_1 + dst + ~offset_commitment:0L + ~offset_nullifier:0L + () + >>=? fun (_root, diff_1) -> + let fee = Test_tez.of_int 10 in + Tez.one_mutez *? Int64.of_int 15 >>?= fun amount_tez -> + Op.transaction + ~fee + (B block_start) + src + dst + amount_tez + ~parameters:parameters_1 + >>=? fun operation -> + Incremental.begin_construction block_start >>=? fun incr -> + Incremental.add_operation incr operation >>=? fun incr -> + (* We need to manually get the counter here *) + let ctx = Incremental.alpha_ctxt incr in + let pkh = + Alpha_context.Contract.is_implicit src + |> WithExceptions.Option.get ~loc:__LOC__ + in + Alpha_context.Contract.get_counter ctx pkh >>= wrap >>=? fun counter -> + Op.transaction + ~counter + ~fee + (B block_start) + src + dst + Tez.zero + ~parameters:parameters_2 + >>=? fun operation -> + Incremental.add_operation incr operation >>=? fun incr -> + Incremental.finalize_block incr >>=? fun block_2 -> + Alpha_services.Contract.single_sapling_get_diff + Block.rpc_ctxt + block_2 + dst + ~offset_commitment:0L + ~offset_nullifier:0L + () + >>=? fun (_root, diff_2) -> + (* We check that the same transactions have passed *) + assert (diff_1 = diff_2) ; + let is_root_in block dst root = + Incremental.begin_construction block >>=? fun incr -> + let ctx_2 = Incremental.alpha_ctxt incr in + Alpha_services.Contract.script Block.rpc_ctxt block dst >>=? fun script -> + let ctx_without_gas_2 = Alpha_context.Gas.set_unlimited ctx_2 in + Script_ir_translator.parse_script + ctx_without_gas_2 + ~legacy:true + ~allow_forged_in_storage:true + script + >>= wrap + >>=? fun (Ex_script script, ctxt) -> + Script_ir_translator.get_single_sapling_state + ctxt + script.storage_type + script.storage + |> wrap + >>=? fun (id, _ctx_2) -> + let single_id = WithExceptions.Option.get ~loc:__LOC__ id in + let id = + Lazy_storage_kind.Sapling_state.Id.parse_z + @@ Alpha_context.Sapling.Id.unparse_to_z single_id + in + Raw_context.prepare + block.context + ~level:block.header.shell.level + ~predecessor_timestamp:block.header.shell.timestamp + ~timestamp:block.header.shell.timestamp + >>= wrap + >>=? fun raw_ctx -> Sapling_storage.Roots.mem raw_ctx id root >>= wrap + in + (* We check that the second state did not store the root in between + transactions. *) + is_root_in block_2 dst intermediary_root |> assert_false >>=? fun () -> + (* We check that the second state did store the final root. *) + is_root_in block_2 dst final_root |> assert_true >>=? fun () -> + (* We check that the first state did store the final root. *) + is_root_in block_1 dst final_root |> assert_true >>=? fun () -> + (* We check that the first state did store the root in between transactions. *) + is_root_in block_1 dst intermediary_root |> assert_true + + (* In this test we try a contract which creates an empty sapling state on the + fly. It then applies a list of transactions, checks they are correct and + drops the result. We make several shields in the same list (since the state + is drop). *) + let test_drop () = + init () >>=? fun (b, baker, src, _) -> + originate_contract "contracts/sapling_contract_drop.tz" "Unit" src b baker + >>=? fun (dst, b, anti_replay) -> + let {sk; vk} = wallet_gen () in + let (list_transac, _total) = + shield ~memo_size:8 sk 4 vk (Format.sprintf "0x%s") anti_replay + in + let parameters = parameters_of_list list_transac in + Op.transaction ~fee:(Test_tez.of_int 10) (B b) src dst Tez.zero ~parameters + >>=? fun operation -> + next_block b operation >>=? fun _b -> return_unit + + (* We use a contrac with two states. Its parameter is two transactions and a + bool. The two transactions are tested valid against the two states, but + only one state according to the bool is updated. + We do two transactions shielding to different keys in the two states. + At each transactions both are applied but only state is updated. + We then check that the first state is updated in the correct way. *) + let test_double () = + init () >>=? fun (b, baker, src, _) -> + let memo_size = 8 in + originate_contract + "contracts/sapling_contract_double.tz" + "(Pair { } { })" + src + b + baker + >>=? fun (dst, b, anti_replay) -> + let wa = wallet_gen () in + let hex_transac_1 = hex_shield ~memo_size wa anti_replay in + let wb = wallet_gen () in + let hex_transac_2 = hex_shield ~memo_size wb anti_replay in + let str_1 = + "(Pair True (Pair " ^ hex_transac_1 ^ " " ^ hex_transac_2 ^ "))" + in + let str_2 = + "(Pair False (Pair " ^ hex_transac_2 ^ " " ^ hex_transac_1 ^ "))" + in + (* transac 1 is applied to state_1*) + let parameters_1 = + Alpha_context.Script.(lazy_expr (Expr.from_string str_1)) + in + (* tranasc_2 is applied to state_2*) + let parameters_2 = + Alpha_context.Script.(lazy_expr (Expr.from_string str_2)) + in + let fee = Test_tez.of_int 10 in + Op.transaction ~fee (B b) src dst Tez.zero ~parameters:parameters_1 + >>=? fun operation -> + next_block b operation >>=? fun b -> + Op.transaction ~fee (B b) src dst Tez.zero ~parameters:parameters_2 + >>=? fun operation -> + next_block b operation >>=? fun b -> + Incremental.begin_construction b >>=? fun incr -> + let ctx = Incremental.alpha_ctxt incr in + let ctx_without_gas = Alpha_context.Gas.set_unlimited ctx in + Alpha_services.Contract.storage Block.rpc_ctxt b dst >>=? fun storage -> + let storage_lazy_expr = Alpha_context.Script.lazy_expr storage in + + (let memo_size = memo_size_of_int memo_size in + let open Script_typed_ir in + let state_ty = sapling_state_t ~memo_size ~annot:None in + pair_t (-1) (state_ty, None, None) (state_ty, None, None) ~annot:None) + >>??= fun tytype -> + Script_ir_translator.parse_storage + ctx_without_gas + ~legacy:true + ~allow_forged:true + tytype + ~storage:storage_lazy_expr + >>= wrap + >>=? fun ((state_1, state_2), _ctx) -> + (*Only works when diff is empty*) + let local_state_from_disk disk_state ctx = + let id = + Alpha_context.Sapling.(disk_state.id) + |> WithExceptions.Option.get ~loc:__LOC__ + in + Alpha_context.Sapling.get_diff + ctx + id + ~offset_commitment:0L + ~offset_nullifier:0L + () + >>= wrap + >|=? fun diff -> client_state_of_diff ~memo_size diff + in + local_state_from_disk state_1 ctx >>=? fun state_1 -> + local_state_from_disk state_2 ctx >|=? fun state_2 -> + (* we check that first state contains 15 to addr_1 but not 15 to addr_2*) + assert (Option.is_some @@ Tezos_sapling.Forge.Input.get state_1 0L wa.vk) ; + assert (Option.is_some @@ Tezos_sapling.Forge.Input.get state_2 0L wa.vk) ; + assert (Option.is_none @@ Tezos_sapling.Forge.Input.get state_1 0L wb.vk) ; + assert (Option.is_none @@ Tezos_sapling.Forge.Input.get state_2 0L wb.vk) + + let test_state_as_arg () = + init () >>=? fun (b, baker, src, _) -> + originate_contract + "contracts/sapling_contract_state_as_arg.tz" + "None" + src + b + baker + >>=? fun (dst, b, anti_replay) -> + originate_contract "contracts/sapling_contract_send.tz" "Unit" src b baker + >>=? fun (dst_2, b, anti_replay_2) -> + let w = wallet_gen () in + let hex_transac_1 = hex_shield ~memo_size:8 w anti_replay in + let string = "Left " ^ hex_transac_1 in + let parameters = + Alpha_context.Script.(lazy_expr (Expr.from_string string)) + in + let fee = Test_tez.of_int 10 in + Op.transaction ~fee (B b) src dst Tez.zero ~parameters >>=? fun operation -> + next_block b operation >>=? fun b -> + let contract = "0x" ^ to_hex dst Alpha_context.Contract.encoding in + let hex_transac_2 = hex_shield ~memo_size:8 w anti_replay_2 in + let string = "(Pair " ^ contract ^ " " ^ hex_transac_2 ^ ")" in + let parameters = + Alpha_context.Script.(lazy_expr (Expr.from_string string)) + in + Op.transaction ~fee (B b) src dst_2 Tez.zero ~parameters + >>=? fun operation -> + next_block b operation >>=? fun _b -> return_unit +end + +let tests = + [ + Tztest.tztest + "commitments_add_uncommitted" + `Quick + Raw_context_tests.commitments_add_uncommitted; + Tztest.tztest "nullifier_double" `Quick Raw_context_tests.nullifier_double; + Tztest.tztest "nullifier_test" `Quick Raw_context_tests.nullifier_test; + Tztest.tztest "cm_cipher_test" `Quick Raw_context_tests.cm_cipher_test; + Tztest.tztest + "list_insertion_test" + `Quick + Raw_context_tests.list_insertion_test; + Tztest.tztest "root" `Quick Raw_context_tests.root_test; + Tztest.tztest + "test_get_memo_size" + `Quick + Raw_context_tests.test_get_memo_size; + Tztest.tztest "test_verify_memo" `Quick Alpha_context_tests.test_verify_memo; + Tztest.tztest + "test_bench_phases" + `Slow + Alpha_context_tests.test_bench_phases; + Tztest.tztest + "test_bench_fold_over_same_token" + `Slow + Alpha_context_tests.test_bench_fold_over_same_token; + Tztest.tztest + "test_double_spend_same_input" + `Quick + Alpha_context_tests.test_double_spend_same_input; + Tztest.tztest + "test_verifyupdate_one_transaction" + `Quick + Alpha_context_tests.test_verifyupdate_one_transaction; + Tztest.tztest + "test_verifyupdate_two_transactions" + `Quick + Alpha_context_tests.test_verifyupdate_two_transactions; + Tztest.tztest "test_shielded_tez" `Quick Interpreter_tests.test_shielded_tez; + Tztest.tztest + "test use state from other contract and transact" + `Quick + Interpreter_tests.test_use_state_from_other_contract_and_transact; + Tztest.tztest + "Instruction PUSH sapling_state 0 should be forbidden" + `Quick + Interpreter_tests.test_push_sapling_state_should_be_forbidden; + Tztest.tztest + "test_transac_and_block" + `Quick + Interpreter_tests.test_transac_and_block; + Tztest.tztest "test_drop" `Quick Interpreter_tests.test_drop; + Tztest.tztest "test_double" `Quick Interpreter_tests.test_double; + Tztest.tztest "test_state_as_arg" `Quick Interpreter_tests.test_state_as_arg; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_saturation.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_saturation.ml new file mode 100644 index 000000000000..099ead7ed739 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_saturation.ml @@ -0,0 +1,218 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (saturated arithmetic) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ + -- test "^saturation arithmetic$" + Subject: The gas is represented using saturated arithmetic. + These unit tests check that saturated arithmetic operations + are correctly implemented. +*) + +open Protocol + +let valid (z : _ Saturation_repr.t) = + let x = z |> Saturation_repr.to_int in + x >= 0 && x < max_int + +exception Saturating_test_error of string + +let err x = Exn (Saturating_test_error x) + +let small_enough (z : _ Saturation_repr.t) = + Saturation_repr.(Compare.Int.((z |> to_int) land 0x7fffffff80000000 = 0)) + +let ok_int x = + match Saturation_repr.of_int_opt x with None -> assert false | Some x -> x + +let n = ok_int 123123 + +let m = ok_int 377337 + +let add () = + Saturation_repr.( + fail_unless + (add saturated (ok_int 1) = saturated) + (err "saturated + 1 <> saturated") + >>=? fun () -> + fail_unless (add zero n = n) (err "zero + n <> n") >>=? fun () -> + fail_unless (add n zero = n) (err "n + zero <> n") >>=? fun () -> + let r = add n m in + fail_unless + (valid r && r = ok_int ((n |> to_int) + (m |> to_int))) + (err "add does not behave like + on small numbers.")) + +let sub () = + Saturation_repr.( + fail_unless (sub zero n = zero) (err "zero - n <> zero") >>=? fun () -> + let n = max n m and m = min n m in + let r = sub n m in + fail_unless + (valid r && r = ok_int ((n |> to_int) - (m |> to_int))) + (err "sub does not behave like - on small numbers.")) + +let mul_safe_of_int x = + Saturation_repr.( + match mul_safe (ok_int x) with Some x -> x | None -> assert false) + +let n' = mul_safe_of_int 1000 + +let m' = mul_safe_of_int 10000 + +let mul_fast () = + Saturation_repr.( + fail_unless (mul_fast zero n' = zero) (err "mul_fast zero x <> zero") + >>=? fun () -> + fail_unless (mul_fast n' zero = zero) (err "mul_fast x zero <> zero") + >>=? fun () -> + let r = mul_fast n' m' in + fail_unless + (valid r && r = ok_int ((n' |> to_int) * (m' |> to_int))) + (err "mul_fast does not behave like * on small numbers.")) + +let scale_fast () = + Saturation_repr.( + fail_unless (scale_fast zero n = zero) (err "scale_fast zero x <> zero") + >>=? fun () -> + fail_unless (scale_fast n' zero = zero) (err "scale_fast x zero <> zero") + >>=? fun () -> + fail_unless + (scale_fast n' saturated = saturated) + (err "scale_fast x saturated <> saturated") + >>=? fun () -> + let r = scale_fast n' m in + fail_unless + (valid r && r = ok_int ((n' |> to_int) * (m |> to_int))) + (err "mul_fast does not behave like * on small numbers.")) + +let mul () = + Saturation_repr.( + fail_unless + (mul saturated saturated = saturated) + (err "saturated * saturated <> saturated") + >>=? fun () -> + fail_unless (mul zero saturated = zero) (err "zero * saturated <> zero") + >>=? fun () -> + fail_unless (mul saturated zero = zero) (err "saturated * zero <> zero") + >>=? fun () -> + let max_squared = ok_int (1 lsl 31) in + let r = mul max_squared max_squared in + fail_unless (r = saturated) (err "2 ^ 31 * 2 ^ 31 should be saturated") + >>=? fun () -> + let safe_squared = ok_int ((1 lsl 31) - 1) in + let r = mul safe_squared safe_squared in + fail_unless + (valid r && r <> saturated) + (err "(2 ^ 31 - 1) * (2 ^ 31 - 1) should not be saturated") + >>=? fun () -> + let r = mul n m in + fail_unless + (valid r && r = ok_int ((n |> to_int) * (m |> to_int))) + (err "mul does not behave like * on small numbers.")) + +let shift_left () = + Saturation_repr.( + let must_saturate flag (k, v) = + fail_unless + (Bool.equal flag (shift_left k v = saturated)) + (err + (Printf.sprintf + "shift_left %d %d %s saturated" + (k |> to_int) + v + (if flag then "<>" else "="))) + in + List.iter_es + (must_saturate true) + [(saturated, 1); (shift_right saturated 1, 2); (ok_int 1, 62)] + >>=? fun () -> + List.iter_es + (must_saturate false) + [ + (ok_int 1, 0); + (ok_int 1, 31); + (ok_int 1, 61); + (ok_int 0, 99); + (ok_int ((1 lsl 62) - 2), 0); + ]) + +let of_z_opt () = + fail_unless + (Saturation_repr.(of_z_opt (Z.succ (Z.of_int max_int))) = None) + (err + "of_z_opt should saturate when given a z integer greater than max_int.") + >>=? fun () -> + fail_unless + (Saturation_repr.(of_z_opt (Z.pred Z.zero)) = None) + (err "of_z_opt should fail on a z negative integer.") + >>=? fun () -> + fail_unless + (Saturation_repr.(of_z_opt (Z.of_int min_int)) = None) + (err "of_z_opt should fail on a z negative integer.") + +let encoding encoder () = + let check_encode_decode x = + Data_encoding.Binary.( + match to_bytes encoder (ok_int x) with + | Error _ -> + fail (err (Printf.sprintf "Problem during binary encoding of %d" x)) + | Ok bytes -> ( + match of_bytes encoder bytes with + | Error _ -> + fail + (err (Printf.sprintf "Problem during binary decoding of %d" x)) + | Ok x' -> + fail_unless + (ok_int x = x') + (err + (Printf.sprintf + "decode (encode %d) = %d <> %d" + x + (x' :> int) + x)))) + in + Error_monad.Lwt_tzresult_syntax.join + (List.map check_encode_decode [0; 7373737373; max_int - 1]) + +let tests = + [ + Tztest.tztest "Addition" `Quick add; + Tztest.tztest "Subtraction" `Quick sub; + Tztest.tztest "Multiplication" `Quick mul; + Tztest.tztest "Multiplication (fast version)" `Quick mul_fast; + Tztest.tztest "Shift left" `Quick shift_left; + Tztest.tztest "Scale fast" `Quick scale_fast; + Tztest.tztest "Conversion from Z" `Quick of_z_opt; + Tztest.tztest + "Encoding through z" + `Quick + (encoding Saturation_repr.z_encoding); + Tztest.tztest + "Encoding through n" + `Quick + (encoding Saturation_repr.n_encoding); + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_script_comparison.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_script_comparison.ml new file mode 100644 index 000000000000..3c498983811f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_script_comparison.ml @@ -0,0 +1,369 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Script_comparison + Invocation: dune exec src/proto_alpha/lib_protocol/test/test_script_comparison.exe + Subject: PBT of the Script_comparable.compare_comparable function. +*) + +open Protocol +open Alpha_context +open Script_typed_ir +open Lib_test.Qcheck_helpers + +(* Reference implementation *) + +let normalize_compare c = + let open Compare.Int in + if c > 0 then 1 else if c < 0 then -1 else 0 + +(* This reference implementation of the Michelson comparison function is a + simplified version of the Script_ir_translator.compare_comparable function + that was used in the Florence protocol, before a refactoring broke it in + Granada. *) +let rec reference_compare_comparable : type a. a comparable_ty -> a -> a -> int + = + fun ty x y -> + match (ty, x, y) with + | (Unit_key _, (), ()) -> 0 + | (Never_key _, _, _) -> . + | (Signature_key _, x, y) -> normalize_compare @@ Signature.compare x y + | (String_key _, x, y) -> normalize_compare @@ Script_string.compare x y + | (Bool_key _, x, y) -> normalize_compare @@ Compare.Bool.compare x y + | (Mutez_key _, x, y) -> normalize_compare @@ Tez.compare x y + | (Key_hash_key _, x, y) -> + normalize_compare @@ Signature.Public_key_hash.compare x y + | (Key_key _, x, y) -> normalize_compare @@ Signature.Public_key.compare x y + | (Int_key _, x, y) -> normalize_compare @@ Script_int.compare x y + | (Nat_key _, x, y) -> normalize_compare @@ Script_int.compare x y + | (Timestamp_key _, x, y) -> normalize_compare @@ Script_timestamp.compare x y + | (Address_key _, x, y) -> + normalize_compare @@ Script_comparable.compare_address x y + | (Bytes_key _, x, y) -> normalize_compare @@ Compare.Bytes.compare x y + | (Chain_id_key _, x, y) -> normalize_compare @@ Chain_id.compare x y + | (Pair_key ((tl, _), (tr, _), _), (lx, rx), (ly, ry)) -> + let cl = reference_compare_comparable tl lx ly in + if Compare.Int.(cl = 0) then reference_compare_comparable tr rx ry else cl + | (Union_key ((tl, _), _, _), L x, L y) -> reference_compare_comparable tl x y + | (Union_key _, L _, R _) -> -1 + | (Union_key _, R _, L _) -> 1 + | (Union_key (_, (tr, _), _), R x, R y) -> reference_compare_comparable tr x y + | (Option_key _, None, None) -> 0 + | (Option_key _, None, Some _) -> -1 + | (Option_key _, Some _, None) -> 1 + | (Option_key (t, _), Some x, Some y) -> reference_compare_comparable t x y + +(* Generation of one to three values of the same comparable type. *) + +type ex_comparable_data = + | Ex_comparable_data : 'a comparable_ty * 'a -> ex_comparable_data + +type ex_comparable_data_2 = + | Ex_comparable_data_2 : 'a comparable_ty * 'a * 'a -> ex_comparable_data_2 + +type ex_comparable_data_3 = + | Ex_comparable_data_3 : + 'a comparable_ty * 'a * 'a * 'a + -> ex_comparable_data_3 + +(* We use the Michelson samplers from lib_benchmark and turn them into QCheck + generators *) +module Parameters = struct + let atom_size_range : Tezos_benchmark.Base_samplers.range = + {min = 0; max = 10} + + let other_size : Tezos_benchmark.Base_samplers.range = {min = 0; max = 100} + + let parameters : Michelson_samplers.parameters = + { + base_parameters = + { + int_size = atom_size_range; + string_size = atom_size_range; + bytes_size = atom_size_range; + }; + list_size = other_size; + set_size = other_size; + map_size = other_size; + } +end + +module Crypto_samplers = +Tezos_benchmark.Crypto_samplers.Make_finite_key_pool (struct + let size = 1000 + + let algo = `Default +end) + +module Samplers : Michelson_samplers.S = + Michelson_samplers.Make (Parameters) (Crypto_samplers) + +let ex_comparable_data_sampler : + ex_comparable_data Tezos_benchmark.Base_samplers.sampler = + fun random_state -> + let size = + Tezos_benchmark.Base_samplers.sample_in_interval + ~range:{min = 1; max = 20} + random_state + in + let (Ex_comparable_ty ty) = + Samplers.Random_type.m_comparable_type ~size random_state + in + let x = Samplers.Random_value.comparable ty random_state in + Ex_comparable_data (ty, x) + +let ex_comparable_data_2_sampler : + ex_comparable_data_2 Tezos_benchmark.Base_samplers.sampler = + fun random_state -> + let size = + Tezos_benchmark.Base_samplers.sample_in_interval + ~range:{min = 1; max = 20} + random_state + in + let (Ex_comparable_ty ty) = + Samplers.Random_type.m_comparable_type ~size random_state + in + let x = Samplers.Random_value.comparable ty random_state in + let y = Samplers.Random_value.comparable ty random_state in + Ex_comparable_data_2 (ty, x, y) + +let ex_comparable_data_3_sampler : + ex_comparable_data_3 Tezos_benchmark.Base_samplers.sampler = + fun random_state -> + let size = + Tezos_benchmark.Base_samplers.sample_in_interval + ~range:{min = 1; max = 20} + random_state + in + let (Ex_comparable_ty ty) = + Samplers.Random_type.m_comparable_type ~size random_state + in + let x = Samplers.Random_value.comparable ty random_state in + let y = Samplers.Random_value.comparable ty random_state in + let z = Samplers.Random_value.comparable ty random_state in + Ex_comparable_data_3 (ty, x, y, z) + +let comparable_data_generator : ex_comparable_data QCheck.Gen.t = + ex_comparable_data_sampler + +let comparable_data_2_generator : ex_comparable_data_2 QCheck.Gen.t = + ex_comparable_data_2_sampler + +let comparable_data_3_generator : ex_comparable_data_3 QCheck.Gen.t = + ex_comparable_data_3_sampler + +let comparable_data_arbitrary : ex_comparable_data QCheck.arbitrary = + QCheck.make comparable_data_generator + +let comparable_data_2_arbitrary : ex_comparable_data_2 QCheck.arbitrary = + QCheck.make comparable_data_2_generator + +let comparable_data_3_arbitrary : ex_comparable_data_3 QCheck.arbitrary = + QCheck.make comparable_data_3_generator + +(* We need a context because packing (used in one of the tests) and unparsing + (used for pretty-printing error messages) Michelson data are carbonated + operations. But since we don't care about gas consumption here we use the + same value of type context everywhere instead of threading it through the + error monad. *) + +let assert_ok = function Ok x -> x | Error _ -> assert false + +let assert_return x = assert_ok (Lwt_main.run x) + +let ctxt = + assert_return + ( Context.init 3 >>=? fun (b, _cs) -> + Incremental.begin_construction b >>=? fun v -> + return (Incremental.alpha_ctxt v) ) + +let unparse_comparable_ty ty = + Micheline.strip_locations + (fst + (assert_ok + Script_ir_translator.( + unparse_ty ~loc:() ctxt (ty_of_comparable_ty ty)))) + +let unparse_comparable_data ty x = + Micheline.strip_locations + (fst + (assert_return + Script_ir_translator.( + unparse_data ctxt Readable (ty_of_comparable_ty ty) x))) + +let pack_comparable_data ty x = + fst + (assert_return + Script_ir_translator.(pack_data ctxt (ty_of_comparable_ty ty) x)) + +let unpack_comparable_data ty bytes = + let ty = Script_ir_translator.ty_of_comparable_ty ty in + fst (assert_return (Script_interpreter_defs.unpack ctxt ~ty ~bytes)) + +let pp_comparable_ty fmt ty = + Michelson_v1_printer.print_expr fmt (unparse_comparable_ty ty) + +let pp_comparable_data ty fmt x = + Michelson_v1_printer.print_expr fmt (unparse_comparable_data ty x) + +let pp ty x y pp_c fmt c = + Format.fprintf + fmt + "Compare(ty=%a, %a, %a) = %a" + pp_comparable_ty + ty + (pp_comparable_data ty) + x + (pp_comparable_data ty) + y + pp_c + c + +let compare_through_pack ty x y = + Bytes.compare (pack_comparable_data ty x) (pack_comparable_data ty y) = 0 + +let qcheck_compare_comparable ~expected ty x y = + qcheck_eq + ~pp:(pp ty x y Format.pp_print_int) + expected + (Script_comparable.compare_comparable ty x y) + +let qcheck_compare_comparable_eq ~expected ty x y = + qcheck_eq + ~pp:(pp ty x y Format.pp_print_bool) + expected + (Script_comparable.compare_comparable ty x y = 0) + +(* Test. + * Tests that compare_comparable returns the same values than the reference + * implementation. + *) +let test_compatible_with_reference = + QCheck.Test.make + ~name:"compatible_with_reference" + comparable_data_2_arbitrary + (fun (Ex_comparable_data_2 (ty, x, y)) -> + qcheck_compare_comparable + ~expected:(reference_compare_comparable ty x y) + ty + x + y) + +(* Test. + * Tests that compare_comparable returns 0 iff packing then comparing the + * resulting bytes returns 0. + *) +let test_compatible_with_packing = + QCheck.Test.make + ~name:"compatible_with_packing" + comparable_data_2_arbitrary + (fun (Ex_comparable_data_2 (ty, x, y)) -> + qcheck_compare_comparable_eq + ~expected:(compare_through_pack ty x y) + ty + x + y) + +(* Test. + * Tests that compare_comparable is reflexive. + *) +let test_reflexivity = + QCheck.Test.make + ~name:"reflexivity" + comparable_data_arbitrary + (fun (Ex_comparable_data (ty, x)) -> + qcheck_compare_comparable ~expected:0 ty x x) + +(* Test. + * Tests that compare_comparable is symmetric. + *) +let test_symmetry = + QCheck.Test.make + ~name:"symmetry" + comparable_data_2_arbitrary + (fun (Ex_comparable_data_2 (ty, x, y)) -> + qcheck_compare_comparable + ~expected:(-Script_comparable.compare_comparable ty x y) + ty + y + x) + +(* Test. + * Tests that compare_comparable is transitive. + *) +let test_transitivity = + QCheck.Test.make + ~name:"transitivity" + comparable_data_3_arbitrary + (fun (Ex_comparable_data_3 (ty, x, y, z)) -> + let cxy = Script_comparable.compare_comparable ty x y in + let cyz = Script_comparable.compare_comparable ty y z in + match (cxy, cyz) with + | (0, n) | (n, 0) -> qcheck_compare_comparable ~expected:n ty x z + | (-1, -1) -> qcheck_compare_comparable ~expected:(-1) ty x z + | (1, 1) -> qcheck_compare_comparable ~expected:1 ty x z + | _ -> QCheck.assume_fail ()) + +(* Test. + * Tests the round-trip property for PACK and UNPACK (modulo compare_comparable). + *) +let test_pack_unpack = + QCheck.Test.make + ~count: + 100_000 + (* We run this test on many more cases than the default (100) because this + is a very important property. Packing and then unpacking happens each + time data is sent from a contract to another and also each time storage + is saved at the end of a smart contract call and restored at the next + call of the same contract. Also, injectivity of packing (which is a + direct consequence of this) is an important property for big maps + (because the keys are packed and then hashed). *) + ~name:"pack_unpack" + comparable_data_arbitrary + (fun (Ex_comparable_data (ty, x)) -> + let oty = + match option_key (-1) ty ~annot:None with + | Ok ty -> ty + | Error _ -> assert false + in + qcheck_eq + ~cmp:(Script_comparable.compare_comparable oty) + ~pp:(pp_comparable_data oty) + (Some x) + (unpack_comparable_data ty (pack_comparable_data ty x))) + +let () = + Alcotest.run + "Script_comparison" + [ + ("compatible_with_reference", qcheck_wrap [test_compatible_with_reference]); + ("compatible_with_packing", qcheck_wrap [test_compatible_with_packing]); + ("reflexivity", qcheck_wrap [test_reflexivity]); + ("symmetry", qcheck_wrap [test_symmetry]); + ("transitivity", qcheck_wrap [test_transitivity]); + ("pack_unpack", qcheck_wrap [test_pack_unpack]); + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_script_typed_ir_size.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_script_typed_ir_size.ml new file mode 100644 index 000000000000..4c6ea30a6019 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_script_typed_ir_size.ml @@ -0,0 +1,400 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (script typed IR size) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ + -- test "^script typed ir size$" + Subject: Script_typed_ir computes good approximation of values' sizes +*) + +open Protocol + +(* + Helpers + ------- +*) + +exception Script_typed_ir_test_error of string + +let err x = Exn (Script_typed_ir_test_error x) + +let wrap e = Lwt.return (Environment.wrap_tzresult e) + +let iter_n_es n f = + let rec aux k = if k = n then return () else f k >>=? fun () -> aux (k + 1) in + aux 0 + +(* + + We use Snoop's samplers to test that our good approximation of + Michelson values' sizes is indeed a good approximation and that it + is never too far from the reality. + + Architecture: + ------------- + + - module [Samplers] provides samplers for values of type [ty], + [comparable_ty], [code] and any value whose types is dynamically + representable with a [ty]. + + - module [Tests] defines the actual testing procedures and reports + error using [Printers]. + +*) + +module Samplers = struct + let size = {Tezos_benchmark.Base_samplers.min = 4; max = 32} + + module Crypto_samplers = + Tezos_benchmark.Crypto_samplers.Make_finite_key_pool (struct + let size = 10 + + let algo = `Default + end) + + include + Michelson_samplers.Make + (struct + let parameters : Michelson_samplers.parameters = + { + base_parameters = + { + Michelson_samplers_base.int_size = size; + string_size = size; + bytes_size = size; + }; + list_size = size; + set_size = size; + map_size = size; + } + end) + (Crypto_samplers) + + let random_state = Random.State.make [|37; 73; 17; 71; 42|] + + let sample_ty () = Random_type.m_type ~size:10 random_state + + let sample_cty () = Random_type.m_comparable_type ~size:10 random_state + + let sample_value ty = Random_value.value ty random_state + + module Gen = + Michelson_mcmc_samplers.Make_code_sampler (Michelson_base) (Crypto_samplers) + (struct + let rng_state = random_state + + let target_size = 500 + + let verbosity = `Silent + end) + + (* Delay and cache the generator as it's expensive to create. *) + let generator = lazy (Gen.generator ~burn_in:(500 * 7) random_state) + + type exdescr = + | Ex_descr : ('a, 's, 'r, 'f) Script_ir_translator.descr -> exdescr + + let sample_ir_code () = + let Michelson_mcmc_samplers.{term = sample; bef = stack; aft = _} = + (Lazy.force generator) random_state + in + let accounts = Account.generate_accounts 1 in + Block.alpha_context accounts >>=? fun ctxt -> + let code = Micheline.root sample in + let (Ex_stack_ty bef) = + Type_helpers.michelson_type_list_to_ex_stack_ty stack ctxt + in + Script_ir_translator.(parse_instr Lambda ctxt ~legacy:true code bef) + >>= wrap + >>=? fun (ir_code, _) -> + match ir_code with + | Script_ir_translator.Typed ir_code -> return (sample, Ex_descr ir_code) + | _ -> assert false +end + +module Printers = struct + let string_of_something f = + Lwt_main.run + (let accounts = Account.generate_accounts 1 in + Block.alpha_context accounts >>=? fun ctxt -> + f ctxt >>= wrap >>=? fun node -> + let printable = + Micheline_printer.printable + Protocol.Michelson_v1_primitives.string_of_prim + node + in + let b = Buffer.create 13 in + let fmt = Format.formatter_of_buffer b in + Format.fprintf fmt "@[%a@]@." Micheline_printer.print_expr printable ; + return @@ Buffer.contents b) + |> function + | Ok s -> s + | Error (errs : tztrace) -> + Format.eprintf "@[Error: %a@]" pp_print_trace errs ; + exit 1 + + let string_of_value : type a. a Script_typed_ir.ty -> a -> string = + fun ty v -> + string_of_something @@ fun ctxt -> + Script_ir_translator.( + unparse_data ctxt Readable ty v >>=? fun (node, _) -> + return @@ Micheline.strip_locations node) + + let string_of_ty ty = + string_of_something @@ fun ctxt -> + Lwt.return + @@ Script_ir_translator.( + unparse_ty ~loc:() ctxt ty >>? fun (node, _) -> + Ok (Micheline.strip_locations node)) + + let string_of_code code = string_of_something @@ fun _ -> return code + + let string_of_comparable_ty cty = + string_of_ty (Script_ir_translator.ty_of_comparable_ty cty) +end + +module Tests = struct + let footprint v = 8 * Obj.(reachable_words (repr v)) + + let stats = Stdlib.Hashtbl.create 13 + + let remember what vsize rsize = Stdlib.Hashtbl.add stats what (vsize, rsize) + + let check_good_approximation kind ratio what vsize x = + let rsize = footprint x in + let vsize = Saturation_repr.to_int vsize in + remember kind vsize rsize ; + fail_unless + (rsize = 0 || (vsize >= rsize / ratio && vsize <= rsize * ratio)) + (err + (Printf.sprintf + "Computed size for %s is not a good approximation (%d ~/~ %d)" + what + vsize + rsize)) + + let check_in_range what w (v, error) = + let lower_bound = v -. error and upper_bound = v +. error in + fail_unless + (lower_bound <= w && w <= upper_bound) + (err + (Printf.sprintf + "For %s: %f not in [%f; %f]" + what + w + lower_bound + upper_bound)) + + let check_stats what ~expected_mean ~expected_stddev ~expected_ratios = + let entries = Stdlib.Hashtbl.find_all stats what in + let nb_entries = List.length entries in + if nb_entries = 0 then + (* TODO break dependency on other test's side effects: + this value is 0 if the generator did not load the values *) + return_unit + else + let nentries = float_of_int @@ nb_entries in + let ratios = + List.map + (fun (vsize, rsize) -> + (1. +. float_of_int vsize) /. (1. +. float_of_int rsize)) + entries + in + let sum = List.fold_left (fun accu r -> accu +. r) 0. ratios in + let mean = sum /. nentries in + Format.printf "mean: %f@." mean ; + let sqr x = x *. x in + let stddev = + sqrt + (List.fold_left (fun accu r -> accu +. sqr (r -. mean)) 0. ratios + /. nentries) + in + let entries_min = List.fold_left min max_float ratios in + let entries_max = List.fold_left max min_float ratios in + check_in_range (what ^ ":mean") mean expected_mean >>=? fun () -> + check_in_range (what ^ ":stddev") stddev expected_stddev >>=? fun () -> + check_in_range (what ^ ":min") entries_min expected_ratios >>=? fun () -> + check_in_range (what ^ ":max") entries_max expected_ratios + + let ty_size nsamples = + iter_n_es nsamples @@ fun i -> + match Samplers.sample_ty () with + | Ex_ty ty -> + check_good_approximation + "ty_size" + 2 + (Printf.sprintf "type #%d `%s'" i (Printers.string_of_ty ty)) + (snd (Script_typed_ir_size.ty_size ty)) + ty + | exception _ -> return () + + let check_ty_size_stats () = + check_stats + "ty_size" + ~expected_mean:(1., 0.01) + ~expected_stddev:(0., 0.01) + ~expected_ratios:(1., 0.05) + + let comparable_ty_size nsamples = + iter_n_es nsamples @@ fun i -> + match Samplers.sample_cty () with + | Ex_comparable_ty cty -> + check_good_approximation + "comparable_ty_size" + 2 + (Printf.sprintf + "comparable type #%d `%s'" + i + (Printers.string_of_comparable_ty cty)) + (snd (Script_typed_ir_size.comparable_ty_size cty)) + cty + | exception _ -> return () + + let check_comparable_ty_size_stats () = + check_stats + "comparable_ty_size" + ~expected_mean:(1., 0.01) + ~expected_stddev:(0., 0.01) + ~expected_ratios:(1., 0.05) + + let contains_exceptions ty = + let apply : type a. bool -> a Script_typed_ir.ty -> bool = + fun accu -> function + (* Boxed sets and maps point to a shared first class module. + This is an overapproximation that we want to ignore in + the tests. *) + | Set_t _ | Map_t _ + (* We also want to avoid interferences between testing + [lambda_size] and [value_size]. *) + | Lambda_t _ | Contract_t _ -> + true + | _ -> accu + in + Script_typed_ir.ty_traverse + ty + false + {apply; apply_comparable = (fun accu _ -> accu)} + + let value_size nsamples = + iter_n_es nsamples @@ fun i -> + match Samplers.sample_ty () with + | Ex_ty ty when not (contains_exceptions ty) -> ( + match Samplers.sample_value ty with + | v -> + check_good_approximation + "value_size" + (* Used to be 3 but leads to flaky tests. Revert when + determinism is restored and the protocol is more precise + about value sizes. + FIXME: https://gitlab.com/tezos/tezos/-/issues/1784 + FIXME: https://gitlab.com/tezos/tezos/-/issues/1834 *) + 10 + (Printf.sprintf + "value #%d `%s' of type `%s'" + i + (Printers.string_of_value ty v) + (Printers.string_of_ty ty)) + (snd (Script_typed_ir_size.value_size ty v)) + v + | exception _ -> return ()) + | _ | (exception _) -> return () + + let check_value_size_stats () = + (* Stddev set to 0.5, used to be 0.2 but leads to flaky tests. + Revert when determinism is restored and the protocol is more + precise about value sizes. + + FIXME: https://gitlab.com/tezos/tezos/-/issues/1784 + FIXME: https://gitlab.com/tezos/tezos/-/issues/1834 + + Expected_ratios set to 9, used to be 3. + Revert when the following issue is implemented: + FIXME: https://gitlab.com/dannywillems/ocaml-bls12-381/-/issues/55 + *) + check_stats + "value_size" + ~expected_mean:(1., 0.2) + ~expected_stddev:(0., 0.7) + ~expected_ratios:(1., 9.) + + let lambda_size nsamples = + iter_n_es nsamples @@ fun i -> + Samplers.sample_ir_code () >>=? fun (code, Samplers.Ex_descr icode) -> + let kinstr = (Script_ir_translator.close_descr icode).kinstr in + check_good_approximation + "lambda_size" + 3 + (Printf.sprintf "code #%d `%s'" i (Printers.string_of_code code)) + (snd (Script_typed_ir_size.kinstr_size kinstr)) + kinstr + + let check_lambda_size_stats () = + check_stats + "lambda_size" + ~expected_mean:(1., 0.2) + ~expected_stddev:(0., 0.1) + ~expected_ratios:(1., 0.4) +end + +let tests = + let open Tztest in + Tests. + [ + tztest "lambda size is a good approximation (fast)" `Quick (fun () -> + lambda_size 50); + tztest "ty size is a good approximation (fast)" `Quick (fun () -> + ty_size 50); + tztest "value size is a good approximation (fast)" `Quick (fun () -> + value_size 50); + tztest + "comparable ty size is a good approximation (fast)" + `Quick + (fun () -> comparable_ty_size 50); + tztest "lambda size is a good approximation" `Slow (fun () -> + lambda_size 2000); + tztest "value size is a good approximation" `Slow (fun () -> + value_size 1000); + tztest "ty size is a good approximation" `Slow (fun () -> ty_size 1000); + tztest "comparable ty size is a good approximation" `Slow (fun () -> + comparable_ty_size 1000); + tztest + "statistics about ty size are satisfying" + `Quick + check_ty_size_stats; + tztest + "statistics about comparable ty size are satisfying" + `Quick + check_comparable_ty_size_stats; + tztest + "statistics about value size are satisfying" + `Quick + check_value_size_stats; + tztest + "statistics about lambda size are satisfying" + `Quick + check_lambda_size_stats; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_seed.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_seed.ml new file mode 100644 index 000000000000..b0067764e34b --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_seed.ml @@ -0,0 +1,252 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (seed) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^seed$" + Subject: - seed_nonce_hash included in some blocks + - revelation operation of seed_nonce that should correspond + to each seed_nonce_hash +*) + +open Protocol + +(** Baking [blocks_per_commitment] blocks without a [seed_nonce_hash] + commitment fails with [Invalid_commitment]. *) +let test_no_commitment () = + Context.init ~consensus_threshold:0 5 >>=? fun (b, _) -> + Context.get_constants (B b) + >>=? fun {parametric = {blocks_per_commitment; _}; _} -> + let blocks_per_commitment = Int32.to_int blocks_per_commitment in + (* Bake normally until before the commitment *) + Block.bake_n (blocks_per_commitment - 2) b >>=? fun b -> + (* Forge a block with empty commitment and apply it *) + Block.Forge.forge_header b >>=? fun header -> + Block.Forge.set_seed_nonce_hash None header |> Block.Forge.sign_header + >>=? fun header -> + Block.apply header b >>= fun e -> + Assert.proto_error ~loc:__LOC__ e (function + | Alpha_context.Block_header.Invalid_commitment _ -> true + | _ -> false) + +(** Choose a baker, denote it by id. In the first cycle, make id bake only once. + Check that: + - when id reveals the nonce too early, there's an error + - when id reveals at the right time but the wrong value, there's an error + - when another baker reveals correctly, it receives the tip + - revealing twice produces an error *) +let test_revelation_early_wrong_right_twice () = + let open Assert in + Context.init ~consensus_threshold:0 5 >>=? fun (b, _) -> + Context.get_constants (B b) >>=? fun csts -> + let tip = csts.parametric.seed_nonce_revelation_tip in + let blocks_per_commitment = + Int32.to_int csts.parametric.blocks_per_commitment + in + let baking_reward_fixed_portion = + csts.parametric.baking_reward_fixed_portion + in + (* get the pkh of a baker *) + Block.get_next_baker b >>=? fun (pkh, _, _) -> + let id = Alpha_context.Contract.implicit_contract pkh in + let policy = Block.Excluding [pkh] in + (* bake until commitment - 2, excluding id *) + Block.bake_n ~policy (blocks_per_commitment - 2) b >>=? fun b -> + Context.Contract.balance (B b) id >>=? fun bal_main -> + (* the baker [id] will include a seed_nonce commitment *) + Block.bake ~policy:(Block.By_account pkh) b >>=? fun b -> + Context.get_level (B b) >>?= fun level_commitment -> + Context.get_seed_nonce_hash (B b) >>=? fun committed_hash -> + (* test that the baking reward is received *) + balance_was_credited + ~loc:__LOC__ + (B b) + id + bal_main + baking_reward_fixed_portion + >>=? fun () -> + (* test that revealing too early produces an error *) + Op.seed_nonce_revelation + (B b) + level_commitment + (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get committed_hash) + |> fun operation -> + Block.bake ~policy ~operation b >>= fun e -> + let expected = function + | Nonce_storage.Too_early_revelation -> true + | _ -> false + in + Assert.proto_error ~loc:__LOC__ e expected >>=? fun () -> + (* finish the cycle excluding the committing baker, id *) + Block.bake_until_cycle_end ~policy b >>=? fun b -> + (* test that revealing at the right time but the wrong value + produces an error *) + let (wrong_hash, _) = Nonce.generate () in + Op.seed_nonce_revelation + (B b) + level_commitment + (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get wrong_hash) + |> fun operation -> + Block.bake ~operation b >>= fun e -> + Assert.proto_error ~loc:__LOC__ e (function + | Nonce_storage.Inconsistent_nonce -> true + | _ -> false) + >>=? fun () -> + (* reveals correctly *) + Op.seed_nonce_revelation + (B b) + level_commitment + (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get committed_hash) + |> fun operation -> + Block.get_next_baker ~policy b >>=? fun (baker_pkh, _, _) -> + let baker = Alpha_context.Contract.implicit_contract baker_pkh in + Context.Contract.balance (B b) baker >>=? fun baker_bal -> + Block.bake ~policy:(Block.By_account baker_pkh) ~operation b >>=? fun b -> + (* test that the baker gets the tip reward plus the baking reward*) + balance_was_credited + ~loc:__LOC__ + (B b) + baker + baker_bal + Test_tez.(tip +! baking_reward_fixed_portion) + >>=? fun () -> + (* test that revealing twice produces an error *) + Op.seed_nonce_revelation + (B b) + level_commitment + (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get wrong_hash) + |> fun operation -> + Block.bake ~operation ~policy b >>= fun e -> + Assert.proto_error ~loc:__LOC__ e (function + | Nonce_storage.Previously_revealed_nonce -> true + | _ -> false) + +(** Test that revealing too late produces an error. Note that a + committer who doesn't reveal at cycle 1 is not punished.*) +let test_revelation_missing_and_late () = + let open Context in + let open Assert in + Context.init ~consensus_threshold:0 5 >>=? fun (b, _) -> + get_constants (B b) >>=? fun csts -> + let blocks_per_commitment = + Int32.to_int csts.parametric.blocks_per_commitment + in + (* bake until commitment *) + Block.bake_n (blocks_per_commitment - 2) b >>=? fun b -> + (* the next baker [id] will include a seed_nonce commitment *) + Block.get_next_baker b >>=? fun (pkh, _, _) -> + Block.bake b >>=? fun b -> + Context.get_level (B b) >>?= fun level_commitment -> + Context.get_seed_nonce_hash (B b) >>=? fun committed_hash -> + (* finish cycle 0 excluding the committing baker [id] *) + let policy = Block.Excluding [pkh] in + Block.bake_until_cycle_end ~policy b >>=? fun b -> + (* finish cycle 1 excluding the committing baker [id] *) + Block.bake_until_cycle_end ~policy b >>=? fun b -> + (* test that revealing too late (after cycle 1) produces an error *) + Op.seed_nonce_revelation + (B b) + level_commitment + (WithExceptions.Option.to_exn ~none:Not_found @@ Nonce.get committed_hash) + |> fun operation -> + Block.bake ~operation b >>= fun e -> + Assert.proto_error ~loc:__LOC__ e (function + | Nonce_storage.Too_late_revelation -> true + | _ -> false) + +let wrap e = e >|= Environment.wrap_tzresult + +(** Test that we do not distribute endorsing rewards if the nonce was + not revealed. *) +let test_unrevealed () = + let open Alpha_context in + let constants = + { + Default_parameters.constants_test with + endorsing_reward_per_slot = Tez.one_mutez; + baking_reward_bonus_per_slot = Tez.zero; + baking_reward_fixed_portion = Tez.zero; + seed_nonce_revelation_tip = Tez.zero; + consensus_threshold = 0; + minimal_participation_ratio = Constants.{numerator = 0; denominator = 1}; + } + in + Context.init_with_constants constants 2 >>=? fun (b, accounts) -> + let (account1, account2) = + match accounts with a1 :: a2 :: _ -> (a1, a2) | _ -> assert false + in + let (_delegate1, delegate2) = + match (Contract.is_implicit account1, Contract.is_implicit account2) with + | (Some d, Some d') -> (d, d') + | _ -> assert false + in + (* Delegate 2 will add a nonce but never reveals it *) + Context.get_constants (B b) >>=? fun csts -> + let blocks_per_commitment = + Int32.to_int csts.parametric.blocks_per_commitment + in + let bake_and_endorse_block ?policy (pred_b, b) = + Context.get_endorsers (B b) >>=? fun slots -> + List.map_es + (fun {Plugin.RPC.Validators.delegate; slots; _} -> + Op.endorsement + ~delegate:(delegate, slots) + ~endorsed_block:b + (B pred_b) + () + >>=? fun op -> Operation.pack op |> return) + slots + >>=? fun endorsements -> Block.bake ?policy ~operations:endorsements b + in + (* Bake until commitment *) + Block.bake_n (blocks_per_commitment - 2) b >>=? fun b -> + (* Baker delegate 2 will include a seed_nonce commitment *) + let policy = Block.By_account delegate2 in + Block.bake_until_cycle_end ~policy b >>=? fun b -> + Context.Delegate.info (B b) delegate2 >>=? fun info_before -> + Block.bake ~policy b >>=? fun b' -> + bake_and_endorse_block ~policy (b, b') >>=? fun b -> + (* Finish cycle 1 excluding the first baker *) + Block.bake_until_cycle_end ~policy b >>=? fun b -> + Context.Delegate.info (B b) delegate2 >>=? fun info_after -> + (* Assert that we did not received a reward because we didn't + reveal the nonce. *) + Assert.equal_tez ~loc:__LOC__ info_before.full_balance info_after.full_balance + >>=? fun () -> return_unit + +let tests = + [ + Tztest.tztest "no commitment" `Quick test_no_commitment; + Tztest.tztest + "revelation_early_wrong_right_twice" + `Quick + test_revelation_early_wrong_right_twice; + Tztest.tztest + "revelation_missing_and_late" + `Quick + test_revelation_missing_and_late; + Tztest.tztest "test unrevealed" `Quick test_unrevealed; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_storage.ml new file mode 100644 index 000000000000..b65ceab189b2 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_storage.ml @@ -0,0 +1,224 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Context Storage + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test storage + Subject: Test the correctnesss of debug message from storage_functor + *) + +open Protocol +open Storage_functors +open Storage_sigs + +module Int32 = struct + type t = int32 + + let encoding = Data_encoding.int32 + + module Index = struct + type t = int + + let path_length = 1 + + let to_path c l = string_of_int c :: l + + let of_path = function + | [] | _ :: _ :: _ -> None + | [c] -> int_of_string_opt c + + type 'a ipath = 'a * t + + let args = + Storage_description.One + { + rpc_arg = Environment.RPC_arg.int; + encoding = Data_encoding.int31; + compare = Compare.Int.compare; + } + end +end + +module Int64 = struct + type t = int64 + + let encoding = Data_encoding.int64 + + module Index = struct + type t = int64 + + let path_length = 1 + + let to_path c l = Int64.to_string c :: l + + let of_path = function + | [] | _ :: _ :: _ -> None + | [c] -> Int64.of_string_opt c + + type 'a ipath = 'a * t + + let args = + Storage_description.One + { + rpc_arg = Environment.RPC_arg.int64; + encoding = Data_encoding.int64; + compare = Compare.Int64.compare; + } + end +end + +let create_context name : (module Raw_context.T with type t = Raw_context.t) = + (module Make_subcontext (Registered) (Raw_context) + (struct + let name = [name] + end)) + +let create_subcontext name + (module Context : Raw_context.T with type t = Raw_context.t) : + (module Raw_context.T with type t = Raw_context.t) = + (module Make_subcontext (Registered) (Context) + (struct + let name = [name] + end)) + +let create_single_data_storage name + (module Context : Raw_context.T with type t = Raw_context.t) : + (module Single_data_storage with type t = Context.t and type value = Int32.t) + = + (module Make_single_data_storage (Registered) (Context) + (struct + let name = [name] + end) + (Int32)) + +let create_indexed_subcontext_int32 + (module Context : Raw_context.T with type t = Raw_context.t) : + (module Data_set_storage with type t = Raw_context.t) = + (module Make_data_set_storage (Context) (Int32.Index)) + +let create_indexed_subcontext_int64 + (module Context : Raw_context.T with type t = Raw_context.t) : + (module Data_set_storage with type t = Raw_context.t) = + (module Make_data_set_storage (Context) (Int64.Index)) + +let must_failwith f_prog error = + try + let _ = f_prog () in + Alcotest.fail "Unexpected successful result" + with exc -> + if exc = error then Lwt.return_unit + else Alcotest.fail "Unexpected error result" + +(** Test: + + This test check that creating value where value already exists + fails*) +let test_register_single_data () = + let f_prog () = + let context = create_context "context1" in + let _single_data = create_single_data_storage "single_data" context in + create_single_data_storage "single_data" context + in + let error = + Invalid_argument + "Could not register a value at [context1 / single_data] because of an \ + existing Value." + in + must_failwith f_prog error + +(** Test: + + This test check that creating a subcontext where a value already exists + fails*) +let test_register_named_subcontext () = + let f_prog () = + let context = create_context "context2" in + let subcontext = create_subcontext "sub_context" context in + let _single_data = create_single_data_storage "error_register" subcontext in + let subcontext = create_subcontext "error_register" subcontext in + create_single_data_storage "single_data2" subcontext + in + let error = + Invalid_argument + "Could not register a named subcontext at [context2 / sub_context / \ + error_register] because of an existing Value." + in + must_failwith f_prog error + +(** Test: + + This test check that creating a indexed subcontext where a value already + exists fails*) +let test_register_indexed_subcontext () = + let f_prog () = + let context = create_context "context3" in + let _ = create_single_data_storage "single_value" context in + create_indexed_subcontext_int32 context + in + let error = + Invalid_argument + "Could not register an indexed subcontext at [context3] because of an \ + existing \n\ + single_value Value." + in + must_failwith f_prog error + +(** Test: + + This test check that creating a indexed subcontext where an indexed + subcontext already exists fails*) +let test_register_indexed_subcontext_2 () = + let f_prog () = + let context = create_context "context4" in + let _ = create_indexed_subcontext_int32 context in + create_indexed_subcontext_int64 context + in + let error = + Invalid_argument + "An indexed subcontext at [context4] already exists but has a different \ + argument: `int64` <> `int`." + in + must_failwith f_prog error + +let tests = + [ + Alcotest_lwt.test_case + "register single data in existing path" + `Quick + (fun _ -> test_register_single_data); + Alcotest_lwt.test_case + "register named subcontext in existing path" + `Quick + (fun _ -> test_register_named_subcontext); + Alcotest_lwt.test_case + "register indexed subcontext in existing path" + `Quick + (fun _ -> test_register_indexed_subcontext); + Alcotest_lwt.test_case + "register indexed subcontext with existing indexed subcontext" + `Quick + (fun _ -> test_register_indexed_subcontext_2); + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_temp_big_maps.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_temp_big_maps.ml new file mode 100644 index 000000000000..831e68be7919 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_temp_big_maps.ml @@ -0,0 +1,100 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (temporary big maps) + Invocation: cd src/proto_alpha/lib_protocol/test && dune exec ./main.exe -- test "^temp big maps$" + Subject: On temporary big maps. +*) + +open Protocol + +let to_raw_context (b : Block.t) = + Raw_context.prepare + b.context + ~level:b.header.shell.level + ~predecessor_timestamp:b.header.shell.timestamp + ~timestamp:b.header.shell.timestamp + >|= Environment.wrap_tzresult + +let check_no_dangling_temp_big_map b = + to_raw_context b >>=? fun ctxt -> + Storage.Big_map.fold ctxt ~init:() ~order:`Sorted ~f:(fun id () -> + assert (not (Lazy_storage_kind.Big_map.Id.is_temp id)) ; + Lwt.return_unit) + >>= fun () -> + Storage.Big_map.fold ctxt ~init:() ~order:`Undefined ~f:(fun id () -> + assert (not (Lazy_storage_kind.Big_map.Id.is_temp id)) ; + Lwt.return_unit) + >>= fun () -> return_unit + +let call_the_contract b ~baker ~src contract param_left param_right = + let fee = Alpha_context.Tez.one in + let amount = Alpha_context.Tez.zero in + let param = Printf.sprintf "Pair (%s) %s" param_left param_right in + let parameters = Alpha_context.Script.lazy_expr (Expr.from_string param) in + Op.transaction ~fee (B b) src contract amount ~parameters + >>=? fun operation -> + Incremental.begin_construction ~policy:Block.(By_account baker) b + >>=? fun incr -> + Incremental.add_operation incr operation >>=? fun incr -> + Incremental.finalize_block incr + +(** Originates the contract at contracts/temp_big_maps.tz and calls it with + the pair [(param_left, param_right)]. + An action (originating, storing, passing, passing twice) is done on a big + map (either fresh, passed, or stored). + All combinations are exercised. +*) +let test_temp_big_maps_contract param_left param_right () = + Contract_helpers.init () >>=? fun (b, baker, src, _src2) -> + Contract_helpers.originate_contract + "contracts/temp_big_maps.tz" + "{}" + src + b + baker + >>=? fun (contract, b) -> + check_no_dangling_temp_big_map b >>=? fun () -> + call_the_contract b ~baker ~src contract param_left param_right >>=? fun b -> + check_no_dangling_temp_big_map b + +let param_left_values = ["Left True"; "Left False"; "Right {}"] + +let param_right_values = ["-1"; "0"; "1"; "2"] + +let tests = + List.flatten + (List.map + (fun param_left -> + List.map + (fun param_right -> + Tztest.tztest + (Printf.sprintf "temp_big_maps(%s, %s)" param_left param_right) + `Quick + (test_temp_big_maps_contract param_left param_right)) + param_right_values) + param_left_values) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_tez_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_tez_repr.ml new file mode 100644 index 000000000000..12007f6647e7 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_tez_repr.ml @@ -0,0 +1,140 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol Library + Invocation: dune exec src/proto_alpha/lib_protocol/test/test_tez_repr.exe + Subject: Operations in Tez_repr +*) + +open Protocol.Alpha_context +open Test_tez + +let z_mutez_min = Z.zero + +let z_mutez_max = Z.of_int64 Int64.max_int + +let tez_to_z (tez : Tez.t) : Z.t = Z.of_int64 (Tez.to_mutez tez) + +let z_in_mutez_bounds (z : Z.t) : bool = + Z.Compare.(z_mutez_min <= z && z <= z_mutez_max) + +let compare (c' : Z.t) (c : Tez.t tzresult) : bool = + match (z_in_mutez_bounds @@ c', c) with + | (true, Ok c) -> + Lib_test.Qcheck_helpers.qcheck_eq' + ~pp:Z.pp_print + ~expected:c' + ~actual:(tez_to_z c) + () + | (true, Error _) -> + QCheck.Test.fail_reportf + "@[Results are in Z bounds, but tez operation fails.@]" + | (false, Ok _) -> + QCheck.Test.fail_reportf + "@[Results are not in Z bounds, but tez operation did not fail.@]" + | (false, Error _) -> true + +(* [prop_binop f f' (a, b)] compares the function [f] in Tez with a model + function function [f'] in [Z]. + + If [f' a' b'] falls outside Tez bounds, it is true if [f a b] has + failed. If not, it it is true if [f a b = f' a' b'] where [a'] + (resp. [b']) are [a] (resp. [b']) in [Z]. *) +let prop_binop (f : Tez.t -> Tez.t -> Tez.t tzresult) (f' : Z.t -> Z.t -> Z.t) + ((a, b) : Tez.t * Tez.t) : bool = + compare (f' (tez_to_z a) (tez_to_z b)) (f a b) + +(* [prop_binop64 f f' (a, b)] is as [prop_binop] but for binary operations + where the second operand is of type [int64]. *) +let prop_binop64 (f : Tez.t -> int64 -> Tez.t tzresult) (f' : Z.t -> Z.t -> Z.t) + ((a, b) : Tez.t * int64) : bool = + compare (f' (tez_to_z a) (Z.of_int64 b)) (f a b) + +(** Arbitrary int64 by conversion from int32 *) +let arb_int64_of32 : int64 QCheck.arbitrary = + QCheck.(map ~rev:Int64.to_int32 Int64.of_int32 int32) + +(** Arbitrary int64 mixing small positive integers, + int64s from int32 and arbitrary int64 with equal frequency *) +let arb_int64_sizes : int64 QCheck.arbitrary = + let open QCheck in + oneof + [ + QCheck.map ~rev:Int64.to_int Int64.of_int (int_range (-10) 10); + arb_int64_of32; + int64; + ] + +(** Arbitrary positive int64, mixing small positive integers, + int64s from int32 and arbitrary int64 with equal frequency *) +let arb_ui64_sizes : int64 QCheck.arbitrary = + let open QCheck in + map_same_type + (fun i -> + let v = if i = Int64.min_int then Int64.max_int else Int64.abs i in + assert (v >= 0L) ; + v) + arb_int64_sizes + +(** Arbitrary tez based on [arb_tez_sizes] *) +let arb_tez_sizes = + let open QCheck in + map ~rev:Tez.to_mutez Tez.of_mutez_exn arb_ui64_sizes + +let test_coherent_mul = + QCheck.Test.make + ~name:"Tez.(*?) is coherent w.r.t. Z.(*)" + QCheck.(pair arb_tez_sizes arb_ui64_sizes) + (prop_binop64 ( *? ) Z.( * )) + +let test_coherent_sub = + QCheck.Test.make + ~name:"Tez.(-?) is coherent w.r.t. Z.(-)" + QCheck.(pair arb_tez_sizes arb_tez_sizes) + (prop_binop ( -? ) Z.( - )) + +let test_coherent_add = + QCheck.Test.make + ~name:"Tez.(+?) is coherent w.r.t. Z.(+)" + QCheck.(pair arb_tez_sizes arb_tez_sizes) + (prop_binop ( +? ) Z.( + )) + +let test_coherent_div = + QCheck.Test.make + ~name:"Tez.(/?) is coherent w.r.t. Z.(/)" + QCheck.(pair arb_tez_sizes arb_ui64_sizes) + (fun (a, b) -> + QCheck.assume (b > 0L) ; + prop_binop64 ( /? ) Z.( / ) (a, b)) + +let tests = + [test_coherent_mul; test_coherent_sub; test_coherent_add; test_coherent_div] + +let () = + Alcotest.run + "Tez_repr" + [("Tez_repr", Lib_test.Qcheck_helpers.qcheck_wrap tests)] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_balance_key.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_balance_key.ml new file mode 100644 index 000000000000..455b87809d28 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_balance_key.ml @@ -0,0 +1,497 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (Ticket_balance_key) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe \ + -- test "^ticket balance key" + Subject: Ticket balance key hashing +*) + +open Protocol +open Alpha_context + +let ( let* ) m f = m >>=? f + +let wrap m = m >|= Environment.wrap_tzresult + +let new_ctxt () = + let* (block, _) = Context.init 1 in + let* incr = Incremental.begin_construction block in + return @@ Incremental.alpha_ctxt incr + +let make_contract ticketer = wrap @@ Lwt.return @@ Contract.of_b58check ticketer + +let make_ex_ticket ctxt ~ticketer ~typ ~content ~amount = + let* (Script_ir_translator.Ex_comparable_ty cty, ctxt) = + let node = Micheline.root @@ Expr.from_string typ in + wrap @@ Lwt.return @@ Script_ir_translator.parse_comparable_ty ctxt node + in + let* ticketer = make_contract ticketer in + let* (contents, ctxt) = + let node = Micheline.root @@ Expr.from_string content in + wrap @@ Script_ir_translator.parse_comparable_data ctxt cty node + in + let amount = Script_int.(abs @@ of_int amount) in + let ticket = Script_typed_ir.{ticketer; contents; amount} in + return (Ticket_scanner.Ex_ticket (cty, ticket), ctxt) + +let make_key ctxt ~ticketer ~typ ~content ~amount ~owner = + let* (ex_ticket, ctxt) = + make_ex_ticket ctxt ~ticketer ~typ ~content ~amount + in + let* owner = make_contract owner in + let* (key, amount, ctxt) = + wrap + @@ Ticket_balance_key.ticket_balance_key_and_amount ctxt ex_ticket ~owner + in + return (key, amount, ctxt) + +let equal_script_hash ~loc msg key1 key2 = + Assert.equal + ~loc + Script_expr_hash.equal + msg + Script_expr_hash.pp + (Ticket_balance.script_expr_hash_of_key_hash key1) + (Ticket_balance.script_expr_hash_of_key_hash key2) + +let not_equal_script_hash ~loc msg key1 key2 = + Assert.not_equal + ~loc + Script_expr_hash.equal + msg + Script_expr_hash.pp + (Ticket_balance.script_expr_hash_of_key_hash key1) + (Ticket_balance.script_expr_hash_of_key_hash key2) + +let assert_keys ~ticketer1 ~ticketer2 ~typ1 ~typ2 ~amount1 ~amount2 ~content1 + ~content2 ~owner1 ~owner2 assert_condition = + let* ctxt = new_ctxt () in + let* (key1, amount1, ctxt) = + make_key + ctxt + ~ticketer:ticketer1 + ~typ:typ1 + ~content:content1 + ~amount:amount1 + ~owner:owner1 + in + let* (key2, amount2, _) = + make_key + ctxt + ~ticketer:ticketer2 + ~typ:typ2 + ~content:content2 + ~amount:amount2 + ~owner:owner2 + in + assert_condition (key1, amount1) (key2, amount2) + +let assert_keys_not_equal ~loc = + assert_keys (fun (key1, _) (key2, _) -> + not_equal_script_hash ~loc "Assert that keys are not equal" key1 key2) + +let assert_keys_equal ~loc = + assert_keys (fun (key1, _) (key2, _) -> + equal_script_hash ~loc "Assert that keys are equal" key1 key2) + +let assert_amount ~loc ~ticketer ~typ ~content ~amount ~owner expected = + let* ctxt = new_ctxt () in + let* (_, amount, _ctxt) = + make_key ctxt ~ticketer ~typ ~content ~amount ~owner + in + Assert.equal_int ~loc (Z.to_int amount) expected + +(** Test that the amount returned is as expected. *) +let test_amount () = + assert_amount + ~loc:__LOC__ + ~ticketer:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ:"unit" + ~content:"Unit" + ~amount:42 + ~owner:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + 42 + +(** Test that tickets with two different amounts map to the same hash. + The amount is not part of the ticket balance key. *) +let test_different_amounts () = + assert_keys_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"unit" + ~typ2:"unit" + ~content1:"Unit" + ~content2:"Unit" + ~amount1:1 + ~amount2:2 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that two tickets with different ticketers map to different hashes. *) +let test_different_ticketers () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~typ1:"nat" + ~typ2:"nat" + ~content1:"1" + ~content2:"1" + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that two tickets with different owners map to different hashes. *) +let test_different_owners () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"nat" + ~typ2:"nat" + ~content1:"1" + ~content2:"1" + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + +(** Test that two tickets with different contents map to different hashes. *) +let test_different_content () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"nat" + ~typ2:"nat" + ~content1:"1" + ~content2:"2" + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type nat and a ticket of type int, with the same + content, map to different hashes. *) +let test_nat_int () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"nat" + ~typ2:"int" + ~content1:"1" + ~content2:"1" + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type nat and a ticket of type mutez, with the same + content, map to different hashes. *) +let test_nat_mutez () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"nat" + ~typ2:"mutez" + ~content1:"1" + ~content2:"1" + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type nat and a ticket of type bool, with the + contents (False/0), map to different hashes. *) +let test_bool_nat () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"bool" + ~typ2:"nat" + ~content1:"False" + ~content2:"0" + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type nat and a ticket of type bytes, with the + contents (0/0x), map to different hashes. *) +let test_nat_bytes () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"nat" + ~typ2:"bytes" + ~content1:"0" + ~content2:"0x" + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type string and a chain_id with same content + map to different hashes. *) +let test_string_chain_id () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"string" + ~typ2:"chain_id" + ~content1:{|"NetXynUjJNZm7wi"|} + ~content2:{|"NetXynUjJNZm7wi"|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type string and a key_hash with same content + map to different hashes. *) +let test_string_key_hash () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"string" + ~typ2:"key_hash" + ~content1:{|"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"|} + ~content2:{|"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type string and a key with same content + map to different hashes. *) +let test_string_key () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"string" + ~typ2:"key" + ~content1:{|"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"|} + ~content2:{|"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type string and a timestamp with same content + map to different hashes. *) +let test_string_timestamp () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"string" + ~typ2:"timestamp" + ~content1:{|"2019-09-26T10:59:51Z"|} + ~content2:{|"2019-09-26T10:59:51Z"|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type string and a address with same content + map to different hashes. *) +let test_string_address () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"string" + ~typ2:"address" + ~content1:{|"KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%entrypoint"|} + ~content2:{|"KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%entrypoint"|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type string and a signature with same content + map to different hashes. *) +let test_string_signature () = + let signature = + {|"edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7"|} + in + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"string" + ~typ2:"signature" + ~content1:signature + ~content2:signature + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Tests that annotations are not taken into account when hashing keys. + Two comparable types that only differ in their annotations should + map to to the same hash. Here, the type [pair int string] is identical to + [pair (int %id) (string %name)]. + *) +let test_annotation_pair () = + assert_keys_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"(pair int string)" + ~typ2:{|(pair (int %id) (string %name))|} + ~content1:{|Pair 1 "hello"|} + ~content2:{|Pair 1 "hello"|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Tests that annotations are not taken into account when hashing keys. + Here the types [or int string] and [or (int %id) (string %name)] + should hash to the same key. + *) +let test_annotation_or () = + assert_keys_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"(or int string)" + ~typ2:{|(or (int %id) (string %name))|} + ~content1:{|Left 1|} + ~content2:{|Left 1|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Tests that annotations are not taken into account when hashing keys. + Here the types [int] and [(int :int_alias)] should hash to the same key. + *) +let test_annotation_type_alias () = + assert_keys_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"int" + ~typ2:"(int :int_alias)" + ~content1:"0" + ~content2:"0" + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Tests that annotations are not taken into account when hashing keys. + Here the types [pair (or int string) int] and + [pair (or (int %id) (string %name)) int] should hash to the same key. + *) +let test_annotation_pair_or () = + assert_keys_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"pair (or int string) int" + ~typ2:{|pair (or (int %id) (string %name)) int|} + ~content1:{|Pair (Left 1) 2|} + ~content2:{|Pair (Left 1) 2|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type [option int] and [option nat] with the same + content, [None], don't map to the same hash. *) +let test_option_none () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"option int" + ~typ2:"option nat" + ~content1:{|None|} + ~content2:{|None|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +(** Test that a ticket of type [option int] and [option nat] with the same + content, [Some 0], don't map to the same hash. *) +let test_option_some () = + assert_keys_not_equal + ~loc:__LOC__ + ~ticketer1:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~ticketer2:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~typ1:"option int" + ~typ2:"option nat" + ~content1:{|Some 0|} + ~content2:{|Some 0|} + ~amount1:1 + ~amount2:1 + ~owner1:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + ~owner2:"KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" + +let tests = + [ + Tztest.tztest "Test amount" `Quick test_amount; + Tztest.tztest "Test different ticketers" `Quick test_different_ticketers; + Tztest.tztest "Test different owners" `Quick test_different_owners; + Tztest.tztest "Test different content" `Quick test_different_content; + Tztest.tztest "Test different amounts" `Quick test_different_amounts; + Tztest.tztest "Test nat int" `Quick test_nat_int; + Tztest.tztest "Test nat mutez" `Quick test_nat_mutez; + Tztest.tztest "Test not bool" `Quick test_bool_nat; + Tztest.tztest "Test nat bytes" `Quick test_nat_bytes; + Tztest.tztest "Test string chain_id" `Quick test_string_chain_id; + Tztest.tztest "Test string key_hash" `Quick test_string_key_hash; + Tztest.tztest "Test string timestamp" `Quick test_string_timestamp; + Tztest.tztest "Test string address" `Quick test_string_address; + Tztest.tztest "Test string key" `Quick test_string_key; + Tztest.tztest "Test string signature" `Quick test_string_signature; + Tztest.tztest "Test annotations for pair" `Quick test_annotation_pair; + Tztest.tztest "Test annotations for or" `Quick test_annotation_or; + Tztest.tztest + "Test annotations for type alias" + `Quick + test_annotation_type_alias; + Tztest.tztest + "Test annotations for paired ors" + `Quick + test_annotation_pair_or; + Tztest.tztest "Test option none" `Quick test_option_none; + Tztest.tztest "Test option some" `Quick test_option_some; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_scanner.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_scanner.ml new file mode 100644 index 000000000000..d83a71677195 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_scanner.ml @@ -0,0 +1,593 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (Ticket_scanner) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^ticket scanner" + Subject: Ticket scanner tests +*) + +open Protocol +open Alpha_context + +let ( let* ) m f = m >>=? f + +let wrap m = m >|= Environment.wrap_tzresult + +let new_ctxt () = + let* (block, _) = Context.init 1 in + let* incr = Incremental.begin_construction block in + return @@ Incremental.alpha_ctxt incr + +let assert_equal_string_list ~loc msg = + Assert.assert_equal_list ~loc String.equal msg Format.pp_print_string + +let string_list_of_ex_tickets ctxt tickets = + let accum (xs, ctxt) + (Ticket_scanner.Ex_ticket + (cty, {Script_typed_ir.ticketer; contents; amount})) = + let* (x, ctxt) = + wrap + @@ Script_ir_translator.unparse_data + ctxt + Script_ir_translator.Readable + (Script_ir_translator.ty_of_comparable_ty cty) + contents + in + let content = + Format.kasprintf + Fun.id + "%a" + Michelson_v1_printer.print_expr + (Micheline.strip_locations x) + in + let str = + Format.kasprintf + Fun.id + "(%a, %s, %a)" + Contract.pp + ticketer + content + Z.pp_print + (Script_int.to_zint amount) + in + return (str :: xs, ctxt) + in + let* (xs, ctxt) = List.fold_left_es accum ([], ctxt) tickets in + return (List.rev xs, ctxt) + +let make_ex_ticket ctxt ~ticketer ~type_exp ~content_exp ~amount = + let* (Script_ir_translator.Ex_comparable_ty cty, ctxt) = + let node = Micheline.root @@ Expr.from_string type_exp in + wrap @@ Lwt.return @@ Script_ir_translator.parse_comparable_ty ctxt node + in + let* ticketer = wrap @@ Lwt.return @@ Contract.of_b58check ticketer in + let* (contents, ctxt) = + let node = Micheline.root @@ Expr.from_string content_exp in + wrap @@ Script_ir_translator.parse_comparable_data ctxt cty node + in + let amount = Script_int.(abs @@ of_int amount) in + let ticket = Script_typed_ir.{ticketer; contents; amount} in + return (Ticket_scanner.Ex_ticket (cty, ticket), ctxt) + +let assert_equals_ex_tickets ctxt ~loc ex_tickets expected = + let* (str_tickets, ctxt) = string_list_of_ex_tickets ctxt ex_tickets in + let* (str_tickets_expected, _ctxt) = + string_list_of_ex_tickets ctxt expected + in + assert_equal_string_list + ~loc + "Compare with expected tickets" + (List.sort String.compare str_tickets) + (List.sort String.compare str_tickets_expected) + +let tickets_of_value ctxt ~include_lazy ~type_exp ~value_exp = + let (Script_ir_translator.Ex_ty ty, ctxt) = + let node = Micheline.root @@ Expr.from_string type_exp in + Result.value_f + ~default:(fun () -> Stdlib.failwith "Failed to parse") + (Script_ir_translator.parse_any_ty ctxt ~legacy:false node) + in + let node = Micheline.root @@ Expr.from_string value_exp in + let* (value, ctxt) = + wrap + @@ Script_ir_translator.parse_data + ctxt + ~legacy:false + ~allow_forged:true + ty + node + in + wrap @@ Ticket_scanner.tickets_of_value ctxt ~include_lazy ty value + +let assert_contains_tickets ctxt ~loc ~include_lazy ~type_exp ~value_exp + expected = + let* (ex_tickets, _) = + tickets_of_value ctxt ~include_lazy ~type_exp ~value_exp + in + assert_equals_ex_tickets ctxt ~loc ex_tickets expected + +let assert_fail_non_empty_overlay ctxt ~loc ~include_lazy ~type_exp ~value_exp = + tickets_of_value ctxt ~include_lazy ~type_exp ~value_exp >>= fun res -> + match res with + | Error [x] -> + let x = Format.kasprintf Fun.id "%a" Error_monad.pp x in + Assert.equal + ~loc + String.equal + "" + Format.pp_print_string + "Unsupported big-map value with non-empty overlay" + x + | _ -> failwith "Expected an error at %s" loc + +let make_string_tickets ctxt ticketer_amounts = + List.fold_right_es + (fun (ticketer, content, amount) (tickets, ctxt) -> + let* (ticket, ctxt) = + make_ex_ticket + ctxt + ~ticketer + ~type_exp:"string" + ~content_exp:(Printf.sprintf {|"%s"|} content) + ~amount + in + return (ticket :: tickets, ctxt)) + ticketer_amounts + ([], ctxt) + +let tickets_from_big_map_ref ~pre_populated value_exp = + let* (block, contracts) = Context.init 1 in + let source = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + let* (operation, originated) = + Op.origination (B block) source ~script:Op.dummy_script + in + let* block = Block.bake ~operation block in + let* inc = Incremental.begin_construction block in + let ctxt = Incremental.alpha_ctxt inc in + let* (ctxt, big_map_id) = wrap @@ Big_map.fresh ~temporary:false ctxt in + let int_ty_expr = Expr.from_string "int" in + let* (diffs, ctxt) = + let* (updates, ctxt) = + List.fold_left_es + (fun (kvs, ctxt) (key, value) -> + let* (key_hash, ctxt) = + wrap + @@ Script_ir_translator.hash_comparable_data + ctxt + (Script_typed_ir.int_key ~annot:None) + (Script_int_repr.of_int key) + in + return + ( { + Big_map.key = Expr.from_string @@ string_of_int key; + key_hash; + value = Some (Expr.from_string value); + } + :: kvs, + ctxt )) + ([], ctxt) + pre_populated + in + let alloc = + Big_map. + {key_type = int_ty_expr; value_type = Expr.from_string "ticket string"} + in + return + ( [ + Lazy_storage.make + Lazy_storage.Kind.Big_map + big_map_id + (Update {init = Lazy_storage.Alloc alloc; updates}); + ], + ctxt ) + in + let* ctxt = + wrap + @@ Contract.update_script_storage ctxt originated int_ty_expr (Some diffs) + in + let value_exp = + value_exp @@ Z.to_string (Big_map.Id.unparse_to_z big_map_id) + in + return (value_exp, ctxt) + +let assert_big_map_int_ticket_string_ref ~loc ~pre_populated ~big_map_exp + ex_tickets = + let* (value_exp, ctxt) = + tickets_from_big_map_ref ~pre_populated big_map_exp + in + let* (ex_tickets, ctxt) = make_string_tickets ctxt ex_tickets in + assert_contains_tickets + ctxt + ~include_lazy:true + ~loc + ~type_exp:"big_map int (ticket string)" + ~value_exp + ex_tickets + +let assert_fail_non_empty_overlay_with_big_map_ref ~loc ~pre_populated + ~big_map_exp = + let* (value_exp, ctxt) = + tickets_from_big_map_ref ~pre_populated big_map_exp + in + assert_fail_non_empty_overlay + ctxt + ~include_lazy:true + ~loc + ~type_exp:"big_map int (ticket string)" + ~value_exp + +(** Test that the ticket can be extracted from a a single unit ticket *) +let test_tickets_in_unit_ticket () = + let* ctxt = new_ctxt () in + let type_exp = "ticket(unit)" in + let value_exp = {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" Unit 10|} in + let* (ex_ticket, ctxt) = + make_ex_ticket + ctxt + ~ticketer:"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" + ~type_exp:"unit" + ~content_exp:"Unit" + ~amount:10 + in + assert_contains_tickets + ctxt + ~loc:__LOC__ + ~include_lazy:false + ~type_exp + ~value_exp + [ex_ticket] + +let assert_string_tickets ~loc ~include_lazy ~type_exp ~value_exp ~expected = + let* ctxt = new_ctxt () in + let* (ex_tickets, ctxt) = make_string_tickets ctxt expected in + assert_contains_tickets + ctxt + ~include_lazy + ~loc + ~type_exp + ~value_exp + ex_tickets + +(** Test that all tickets can be extracted from a list of tickets *) +let test_tickets_in_list () = + assert_string_tickets + ~loc:__LOC__ + ~include_lazy:false + ~type_exp:"list(ticket(string))" + ~value_exp: + {| + { + Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1; + Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2; + Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 3; + } + |} + ~expected: + [ + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1); + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "green", 2); + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "blue", 3); + ] + +(** Test that all tickets can be extracted from a pair of tickets *) +let test_tickets_in_pair () = + assert_string_tickets + ~loc:__LOC__ + ~include_lazy:false + ~type_exp:"pair (ticket string) (ticket string)" + ~value_exp: + {| + Pair + (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) + (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2) + |} + ~expected: + [ + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1); + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "green", 2); + ] + +(** Test that all tickets from a map can be extracted. *) +let test_tickets_in_map () = + assert_string_tickets + ~loc:__LOC__ + ~include_lazy:false + ~type_exp:"map int (ticket string)" + ~value_exp: + {| + { + Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); + Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); + } + |} + ~expected: + [ + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1); + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "green", 2); + ] + +(** Test that all tickets from a big-map with non-empty overlay fails. + If we extend the ticket scanner function to support non-empty overlays + this test needs to be adapted. + *) +let test_tickets_in_big_map () = + let* ctxt = new_ctxt () in + assert_fail_non_empty_overlay + ctxt + ~loc:__LOC__ + ~include_lazy:true + ~type_exp:"big_map int (ticket string)" + ~value_exp: + {| + { + Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); + Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); + } + |} + +(** Test that tickets are not extracted from big-map with [include_lazy] set + to false. *) +let test_tickets_in_big_map_strict_only () = + assert_string_tickets + ~loc:__LOC__ + ~include_lazy:false + ~type_exp:"big_map int (ticket string)" + ~value_exp: + {| + { + Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); + Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); + } + |} + ~expected:[] + +(** Test that tickets can be extracted from a list of tickets inside a big-map + This fails due to non-empty overlay. If we extend the ticket scanner + function to support non-empty overlays this test needs to be adapted. +*) +let test_tickets_in_list_in_big_map () = + let* ctxt = new_ctxt () in + assert_fail_non_empty_overlay + ctxt + ~loc:__LOC__ + ~include_lazy:true + ~type_exp:"(big_map int (list(ticket string)))" + ~value_exp: + {| + { + Elt 1 { + Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1 ; + Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1 + }; + Elt 2 { + Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1 ; + Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 1 + } + } + |} + +(** Test that tickets can be extracted from a combination of a list and lazy structure + and that only the strict part is considered with [include_lazy] set to fasle *) +let test_tickets_in_pair_big_map_and_list_strict_only () = + assert_string_tickets + ~loc:__LOC__ + ~include_lazy:false + ~type_exp:"pair (big_map int (ticket string)) (list (ticket string))" + ~value_exp: + {| + Pair + { + Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); + Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1) + } + { + Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1; + Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 1 + } + |} + ~expected: + [ + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "blue", 1); + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "orange", 1); + ] + +(** Test that tickets can be extracted from the left side of an or-expression. *) +let test_tickets_in_or_left () = + assert_string_tickets + ~loc:__LOC__ + ~include_lazy:false + ~type_exp:"or (ticket string) int" + ~value_exp:{| Left (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) |} + ~expected:[("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1)] + +(** Test that tickets can be extracted from the right side of an or-expression. *) +let test_tickets_in_or_right () = + assert_string_tickets + ~loc:__LOC__ + ~include_lazy:false + ~type_exp:"or int (ticket string)" + ~value_exp:{| Right (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) |} + ~expected:[("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1)] + +(* + Big maps have three possible representations. Either as a list of key-value + pairs, as an identifier (int), or as a pair of identifier and overrides. + Example values: + + 1) { Elt "bar" True ; Elt "foo" False } + 2) 42 + 3) Pair 42 { Elt "foo" (Some False) } + *) + +(** Test tickets from empty big_map when passed by reference. *) +let test_tickets_in_empty_big_map_ref () = + assert_big_map_int_ticket_string_ref + ~loc:__LOC__ + ~pre_populated:[] + ~big_map_exp:(Printf.sprintf "%s") + [] + +(** Test tickets from non-empty big-map when passed by reference. + Here, tickets are scanned from the context. *) +let test_tickets_in_non_empty_big_map_ref () = + assert_big_map_int_ticket_string_ref + ~loc:__LOC__ + ~pre_populated: + [ + (1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|}); + (2, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1|}); + (3, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1|}); + ] + ~big_map_exp:(Printf.sprintf "%s") + [ + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1); + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "green", 1); + ("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "blue", 1); + ] + +(** Test tickets from empty big-map when passed as a pair of identifier + and overrides. Here, the scanned tickets are only contained in the overlay + why ticket-scanning fails. + + If we extend the ticket scanner function to support non-empty overlays + this test needs to be adapted. + *) +let test_tickets_overlay_in_empty_big_map_ref () = + assert_fail_non_empty_overlay_with_big_map_ref + ~loc:__LOC__ + ~pre_populated:[] + ~big_map_exp: + (Printf.sprintf + {|Pair %s { Elt 1 (Some (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1))}|}) + +(** Test tickets from non-empty big-map when passed as a pair of identifier + and overrides. The scanned tickets are contained in the context as well as + in the overlay. Since overlay is non-empty is non-empty, ticket scanning + fails. + + If we extend the ticket scanner function to support non-empty overlays + this test needs to be adapted + *) +let test_tickets_overlay_in_non_empty_in_big_map_ref () = + assert_fail_non_empty_overlay_with_big_map_ref + ~loc:__LOC__ + ~pre_populated: + [ + (1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|}); + (2, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1|}); + (3, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1|}); + ] + ~big_map_exp: + (Printf.sprintf + {| Pair + %s + { Elt 4 (Some (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 1))} + |}) + +(** Test tickets from non-empty big-map when passed as a pair of identifier + and overrides, and where the override replaces an existing ticket. + Ticket scanning fails due to non-empty overlay. + + If we extend the ticket scanner function to support non-empty overlays + this test needs to be adapted. + *) +let test_tickets_replace_overlay_in_non_empty_in_big_map_ref () = + assert_fail_non_empty_overlay_with_big_map_ref + ~loc:__LOC__ + ~pre_populated: + [(1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|})] + ~big_map_exp: + (Printf.sprintf + {| Pair + %s + { Elt 1 (Some (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1))} + |}) + +(** Test tickets from non-empty big-map when passed as a pair of identifier + and overrides, and where the override removes an existing ticket. + Ticket scanning fails due to non-empty overlay. + + If we extend the ticket scanner function to support non-empty overlays + this test needs to be adapted. + *) +let test_tickets_remove_overlay_in_non_empty_in_big_map_ref () = + assert_fail_non_empty_overlay_with_big_map_ref + ~loc:__LOC__ + ~pre_populated: + [(1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|})] + ~big_map_exp:(Printf.sprintf {| Pair %s { Elt 1 None} |}) + +let tests = + [ + Tztest.tztest + "Test tickets in unit ticket" + `Quick + test_tickets_in_unit_ticket; + Tztest.tztest "Test tickets in list" `Quick test_tickets_in_list; + Tztest.tztest "Test tickets in pair" `Quick test_tickets_in_pair; + Tztest.tztest "Test tickets in map" `Quick test_tickets_in_map; + Tztest.tztest "Test tickets in big map" `Quick test_tickets_in_big_map; + Tztest.tztest + "Test tickets in big map with include lazy set to false" + `Quick + test_tickets_in_big_map_strict_only; + Tztest.tztest + "Test tickets in list in big map" + `Quick + test_tickets_in_list_in_big_map; + Tztest.tztest + "Test tickets in a pair of big-map and list with include lazy set to \ + false" + `Quick + test_tickets_in_pair_big_map_and_list_strict_only; + Tztest.tztest "Test tickets in or left" `Quick test_tickets_in_or_left; + Tztest.tztest "Test tickets in or right" `Quick test_tickets_in_or_right; + Tztest.tztest + "Test tickets in empty big-map ref" + `Quick + test_tickets_overlay_in_empty_big_map_ref; + Tztest.tztest + "Test tickets in big-map ref" + `Quick + test_tickets_in_empty_big_map_ref; + Tztest.tztest + "Test tickets in non-empty big-map ref" + `Quick + test_tickets_in_non_empty_big_map_ref; + Tztest.tztest + "Test tickets in non-empty big-map ref with overlay" + `Quick + test_tickets_overlay_in_non_empty_in_big_map_ref; + Tztest.tztest + "Test tickets replace existing value from overlay" + `Quick + test_tickets_replace_overlay_in_non_empty_in_big_map_ref; + Tztest.tztest + "Test tickets remove existing value from overlay" + `Quick + test_tickets_remove_overlay_in_non_empty_in_big_map_ref; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_storage.ml new file mode 100644 index 000000000000..ab67b92e5de1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_ticket_storage.ml @@ -0,0 +1,288 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (Alpha_context.Ticket_balance) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^ticket storage$" + Subject: Ticket storage functions tested using the Ticket_balance module in Alpha_context. +*) + +open Protocol +open Alpha_context + +let ( let* ) m f = m >>=? f + +let wrap m = m >|= Environment.wrap_tzresult + +let make_context () = + let* (block, _) = Context.init 1 in + let* incr = Incremental.begin_construction block in + return (Incremental.alpha_ctxt incr) + +let hash_key ctxt ~ticketer ~typ ~contents ~owner = + let ticketer = Micheline.root @@ Expr.from_string ticketer in + let typ = Micheline.root @@ Expr.from_string typ in + let contents = Micheline.root @@ Expr.from_string contents in + let owner = Micheline.root @@ Expr.from_string owner in + wrap + @@ Lwt.return + (Alpha_context.Ticket_balance.make_key_hash + ctxt + ~ticketer + ~typ + ~contents + ~owner) + +let assert_balance ctxt ~loc key expected = + let* (balance, _) = wrap @@ Ticket_balance.get_balance ctxt key in + match balance with + | Some b -> Assert.equal_int ~loc (Z.to_int b) expected + | None -> failwith "Expected balance %d" expected + +let assert_no_balance ctxt key = + let* (balance, _) = wrap @@ Ticket_balance.get_balance ctxt key in + match balance with + | Some b -> failwith "Expected empty (none) balance but got %d" (Z.to_int b) + | None -> return () + +let adjust_balance ctxt key delta = + wrap @@ Ticket_balance.adjust_balance ctxt key ~delta:(Z.of_int delta) + +let assert_non_overlapping_keys ~loc ~ticketer1 ~ticketer2 ~contents1 ~contents2 + ~typ1 ~typ2 ~owner1 ~owner2 = + let* ctxt = make_context () in + let* (k1, ctxt) = + hash_key + ctxt + ~ticketer:ticketer1 + ~typ:typ1 + ~contents:contents1 + ~owner:owner1 + in + let* (k2, _ctxt) = + hash_key + ctxt + ~ticketer:ticketer2 + ~typ:typ2 + ~contents:contents2 + ~owner:owner2 + in + let k1 = Ticket_balance.script_expr_hash_of_key_hash k1 in + let k2 = Ticket_balance.script_expr_hash_of_key_hash k2 in + Assert.not_equal + ~loc + Script_expr_hash.equal + "Keys should not overlap" + Script_expr_hash.pp + k1 + k2 + +let make_key ctxt content = + hash_key + ctxt + ~ticketer:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~typ:"string" + ~contents:(Printf.sprintf {|"%s"|} content) + ~owner:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + +(** Test that key-hashes constructed from different ticketers don't overlap. *) +let test_non_overlapping_keys_ticketer () = + assert_non_overlapping_keys + ~loc:__LOC__ + ~ticketer1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~ticketer2:{|"KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn"|} + ~typ1:"nat" + ~typ2:"int" + ~contents1:{|"1"|} + ~contents2:{|"1"|} + ~owner1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~owner2:{|"KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn"|} + +(** Test that key-hashes constructed from different contents don't overlap. *) +let test_non_overlapping_keys_contents () = + assert_non_overlapping_keys + ~loc:__LOC__ + ~ticketer1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~ticketer2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~typ1:"string" + ~typ2:"string" + ~contents1:{|"red"|} + ~contents2:{|"blue"|} + ~owner1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~owner2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + +(** Test that key-hashes constructed from different content-types don't overlap. *) +let test_non_overlapping_keys_type () = + assert_non_overlapping_keys + ~loc:__LOC__ + ~ticketer1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~ticketer2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~typ1:"nat" + ~typ2:"int" + ~contents1:{|"1"|} + ~contents2:{|"1"|} + ~owner1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~owner2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + +(** Test that key-hashes constructed from different owners don't overlap. *) +let test_non_overlapping_keys_owner () = + assert_non_overlapping_keys + ~loc:__LOC__ + ~ticketer1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~ticketer2:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~typ1:"nat" + ~typ2:"int" + ~contents1:{|"1"|} + ~contents2:{|"1"|} + ~owner1:{|"KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq"|} + ~owner2:{|"KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn"|} + +(** Test that updating the ticket balance table has + the intended effect. + *) +let test_ticket_balance_single_update () = + let* ctxt = make_context () in + let* (alice_red, ctxt) = make_key ctxt "alice_red" in + let* (_, ctxt) = adjust_balance ctxt alice_red 1 in + assert_balance ctxt ~loc:__LOC__ alice_red 1 + +(** Test that updating the ticket-balance table with different keys + updates both entries. *) +let test_ticket_balance_different_owners () = + let* ctxt = make_context () in + let* (alice_red, ctxt) = make_key ctxt "alice_red" in + let* (alice_blue, ctxt) = make_key ctxt "alice_blue" in + let* (_, ctxt) = adjust_balance ctxt alice_red 1 in + let* (_, ctxt) = adjust_balance ctxt alice_blue 1 in + let* () = assert_balance ctxt ~loc:__LOC__ alice_red 1 in + let* () = assert_balance ctxt ~loc:__LOC__ alice_blue 1 in + return () + +(** Test updating the same entry with multiple updates yields + the net result of all balance updates *) +let test_ticket_balance_multiple_updates () = + let* ctxt = make_context () in + let* (alice_red, ctxt) = make_key ctxt "alice_red" in + let* (_, ctxt) = adjust_balance ctxt alice_red 1 in + let* (_, ctxt) = adjust_balance ctxt alice_red 2 in + let* (_, ctxt) = adjust_balance ctxt alice_red (-1) in + assert_balance ctxt ~loc:__LOC__ alice_red 2 + +(** Test that with no updates to the table, no balance is present in + the table *) +let test_empty_balance () = + let* ctxt = make_context () in + let* (alice_red, ctxt) = make_key ctxt "alice_red" in + assert_no_balance ctxt alice_red + +(** Test that adding one entry with positive balance and then + updating with a negative balance also removes the entry *) +let test_empty_balance_after_update () = + let* ctxt = make_context () in + let* (alice_red, ctxt) = make_key ctxt "alice_red" in + let* (_, ctxt) = adjust_balance ctxt alice_red 1 in + let* (_, ctxt) = adjust_balance ctxt alice_red (-1) in + assert_no_balance ctxt alice_red + +(** Test that attempting to update an entry with a negative balance + results in an error. *) +let test_negative_balance () = + let* ctxt = make_context () in + let* (alice_red, ctxt) = make_key ctxt "alice_red" in + adjust_balance ctxt alice_red (-1) >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (fun _err -> true) + +(** Test that positive storage spaces are returned for operations + resulting in extra storage space and negative for ones that frees up storage. + *) +let test_storage_space () = + let* ctxt = make_context () in + let* (alice_red, ctxt) = make_key ctxt "alice_red" in + (* Space for adding an entry is 65 for the key plus 1 for the value. *) + let* (space, ctxt) = adjust_balance ctxt alice_red 1 in + let* () = Assert.equal_int ~loc:__LOC__ 66 (Z.to_int space) in + (* Adding one does not consume additional space. *) + let* (space, ctxt) = adjust_balance ctxt alice_red 1 in + let* () = Assert.equal_int ~loc:__LOC__ 0 (Z.to_int space) in + (* Adding a big balance costs extra. *) + let* (space, ctxt) = adjust_balance ctxt alice_red 1000 in + let* () = Assert.equal_int ~loc:__LOC__ 1 (Z.to_int space) in + (* Reset balance to zero should free up space. + The freed up space is 65 for the key + 2 for the value *) + let* (b, ctxt) = wrap @@ Ticket_balance.get_balance ctxt alice_red in + let* (space, ctxt) = + wrap + (Ticket_balance.adjust_balance + ctxt + alice_red + ~delta:(Z.neg @@ Option.value ~default:Z.zero b)) + in + let* () = Assert.equal_int ~loc:__LOC__ (-67) (Z.to_int space) in + (* Adjusting the space to 0 again should not free anything *) + let* (space, ctxt) = adjust_balance ctxt alice_red 0 in + let* () = Assert.equal_int ~loc:__LOC__ 0 (Z.to_int space) in + (* Adding a balance requiers extra space. *) + let* (space, _) = adjust_balance ctxt alice_red 10 in + Assert.equal_int ~loc:__LOC__ 66 (Z.to_int space) + +let tests = + [ + Tztest.tztest + "no overlapping keys for ticketer" + `Quick + test_non_overlapping_keys_ticketer; + Tztest.tztest + "no overlapping keys for content" + `Quick + test_non_overlapping_keys_contents; + Tztest.tztest + "no overlapping keys for content type" + `Quick + test_non_overlapping_keys_type; + Tztest.tztest + "no overlapping keys for owner" + `Quick + test_non_overlapping_keys_owner; + Tztest.tztest + "ticket balance single update" + `Quick + test_ticket_balance_single_update; + Tztest.tztest "empty balance" `Quick test_empty_balance; + Tztest.tztest + "empty balance after update" + `Quick + test_empty_balance_after_update; + Tztest.tztest "negative balance" `Quick test_negative_balance; + Tztest.tztest + "ticket balance multiple updates" + `Quick + test_ticket_balance_multiple_updates; + Tztest.tztest + "ticket balance different owners" + `Quick + test_ticket_balance_different_owners; + Tztest.tztest "ticket storage space" `Quick test_storage_space; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_time_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_time_repr.ml new file mode 100644 index 000000000000..b2f67327deb9 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_time_repr.ml @@ -0,0 +1,44 @@ +(** Testing + ------- + Component: Protocol (time repr) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^time$" + Subject: Error handling of time operations +*) + +open Protocol + +let test_nominal_add () = + let t = Time_repr.of_seconds (Int64.of_int 2) in + let addition = + Period_repr.of_seconds Int64.one >>? fun p -> Time_repr.( +? ) t p + in + match addition with + | Ok v -> + Assert.equal + ~loc:__LOC__ + Time_repr.equal + "test_nominal_add" + Time_repr.pp_hum + v + (Time_repr.of_seconds (Int64.of_int 3)) + | Error _ -> failwith "Addition has overflowed" + +let test_overflow_add () = + let t = Time_repr.of_seconds Int64.max_int in + match Period_repr.of_seconds Int64.one with + | Error _ -> failwith "period_repr conversion" + | Ok p -> ( + match Time_repr.( +? ) t p with + | Error _ -> return_unit + | Ok tres -> + failwith + "No overflow: %Ld + %Ld = %Ld" + (Time_repr.to_seconds t) + (Period_repr.to_seconds p) + (Time_repr.to_seconds tres)) + +let tests = + [ + Tztest.tztest "non-overflowing addition" `Quick test_nominal_add; + Tztest.tztest "overflowing addition" `Quick test_overflow_add; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_timelock.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_timelock.ml new file mode 100644 index 000000000000..9cdf04695699 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_timelock.ml @@ -0,0 +1,168 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (Timelock) + Invocation: cd src/proto_alpha/lib_protocol/test + dune exec ./main.exe -- test "^timelock$" + Subject: On timelock +*) + +open Protocol + +let wrap e = Lwt.return (Environment.wrap_tzresult e) + +let simple_test () = + let (public, secret) = Timelock.gen_rsa_keys () in + let locked_value = Timelock.gen_locked_value public in + let time = 1000 in + let unlocked_value = Timelock.unlock_with_secret secret ~time locked_value in + let (same_unlocked, proof) = + Timelock.unlock_and_prove_without_secret public ~time locked_value + in + assert (unlocked_value = same_unlocked) ; + let sym_key = Timelock.unlocked_value_to_symmetric_key unlocked_value in + let message = Bytes.create 12 in + let c = Timelock.encrypt sym_key message in + let expected_result = Environment.Timelock.Correct message in + let chest_key = Timelock.{unlocked_value; proof} in + let chest = Timelock.{locked_value; rsa_public = public; ciphertext = c} in + let result = Environment.Timelock.open_chest chest chest_key ~time in + assert (result = expected_result) ; + return_unit + +let contract_test () = + (* Parse a Michelson contract from string. *) + let originate_contract file storage src b = + let load_file f = + let ic = open_in f in + let res = really_input_string ic (in_channel_length ic) in + close_in ic ; + res + in + let contract_string = load_file file in + let code = Expr.toplevel_from_string contract_string in + let storage = Expr.from_string storage in + let script = + Alpha_context.Script.{code = lazy_expr code; storage = lazy_expr storage} + in + Op.origination (B b) src ~fee:(Test_tez.of_int 10) ~script + >>=? fun (operation, dst) -> + Incremental.begin_construction b >>=? fun incr -> + Incremental.add_operation incr operation >>=? fun incr -> + Incremental.finalize_block incr >|=? fun b -> (dst, b) + in + Context.init ~consensus_threshold:0 3 >>=? fun (b, contracts) -> + let src = match contracts with hd :: _ -> hd | _ -> assert false in + originate_contract "contracts/timelock.tz" "0xaa" src b >>=? fun (dst, b) -> + let (public, secret) = Timelock.gen_rsa_keys () in + let locked_value = Timelock.gen_locked_value public in + let time = 1000 in + let unlocked_value = Timelock.unlock_with_secret secret ~time locked_value in + let (_same_unlocked, proof) = + Timelock.unlock_and_prove_without_secret public ~time locked_value + in + let sym_key = Timelock.unlocked_value_to_symmetric_key unlocked_value in + let message = Bytes.of_string "this is my message" in + let c = Timelock.encrypt sym_key message in + let check_storage chest chest_key expected_storage_hexa = + let chest_key_bytes = + "0x" + ^ Hex.show + (Hex.of_bytes + (Data_encoding.Binary.to_bytes_exn + Timelock.chest_key_encoding + chest_key)) + in + let chest_bytes = + "0x" + ^ Hex.show + (Hex.of_bytes + (Data_encoding.Binary.to_bytes_exn Timelock.chest_encoding chest)) + in + let michelson_string = + Format.sprintf "(Pair %s %s )" chest_key_bytes chest_bytes + in + let parameters = + Alpha_context.Script.(lazy_expr (Expr.from_string michelson_string)) + in + let fee = Test_tez.of_int 10 in + Op.transaction ~fee (B b) src dst (Test_tez.of_int 3) ~parameters + >>=? fun operation -> + Incremental.begin_construction b >>=? fun incr -> + Incremental.add_operation incr operation >>=? fun incr -> + Incremental.finalize_block incr >>=? fun block -> + Incremental.begin_construction block >>=? fun incr -> + let ctxt = Incremental.alpha_ctxt incr in + Alpha_context.Contract.get_storage ctxt dst >>= wrap + >>=? fun (_, expr_option) -> + let expr = expr_option |> WithExceptions.Option.get ~loc:__LOC__ in + let bytes = + match Micheline.root expr with + | Micheline.Bytes (_, b) -> b + | _ -> assert false + in + let to_check = Hex.show (Hex.of_bytes bytes) in + assert (to_check = expected_storage_hexa) ; + return_unit + in + let chest_key_correct = Timelock.{unlocked_value; proof} in + let chest_correct = + Timelock.{locked_value; rsa_public = public; ciphertext = c} + in + check_storage + chest_correct + chest_key_correct + (Hex.show (Hex.of_bytes message)) + >>=? fun () -> + (* We redo an RSA parameters generation to create incorrect cipher and proof *) + let (public_bogus, secret_bogus) = Timelock.gen_rsa_keys () in + let locked_value_bogus = Timelock.gen_locked_value public_bogus in + let time = 1000 in + let unlocked_value_bogus = + Timelock.unlock_with_secret secret_bogus ~time locked_value_bogus + in + let (_same_unlocked, proof_bogus) = + Timelock.unlock_and_prove_without_secret public ~time locked_value_bogus + in + let sym_key_bogus = + Timelock.unlocked_value_to_symmetric_key unlocked_value_bogus + in + let c_bogus = Timelock.encrypt sym_key_bogus message in + + let chest_incorrect = + Timelock.{locked_value; rsa_public = public; ciphertext = c_bogus} + in + check_storage chest_incorrect chest_key_correct "00" >>=? fun () -> + let chest_key_incorrect = Timelock.{unlocked_value; proof = proof_bogus} in + check_storage chest_correct chest_key_incorrect "01" >>=? fun () -> + return_unit + +let tests = + [ + Tztest.tztest "simple test" `Quick simple_test; + Tztest.tztest "contract test" `Quick contract_test; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_token.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_token.ml new file mode 100644 index 000000000000..39d5b1510b59 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_token.ml @@ -0,0 +1,732 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (token) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^token" + Subject: Token movements in the protocol. +*) + +open Protocol +open Alpha_context +open Test_tez + +let wrap e = e >|= Environment.wrap_tzresult + +(** Creates a context with a single account. Returns the context and the public + key hash of the account. *) +let create_context () = + let accounts = Account.generate_accounts 1 in + Block.alpha_context accounts >>=? fun ctxt -> + match accounts with + | [({pkh; _}, _)] -> return (ctxt, pkh) + | _ -> (* Exactly one account has been generated. *) assert false + +let random_amount () = + match Tez.of_mutez (Int64.add 1L (Random.int64 100L)) with + | None -> assert false + | Some x -> x + +(** Check balances for a simple transfer from [bootstrap] to new [Implicit]. *) +let test_simple_balances () = + Random.init 0 ; + create_context () >>=? fun (ctxt, pkh) -> + let src = `Contract (Contract.implicit_contract pkh) in + let (pkh, _pk, _sk) = Signature.generate_key () in + let dest = `Contract (Contract.implicit_contract pkh) in + let amount = Tez.one in + wrap (Token.transfer ctxt src dest amount) >>=? fun (ctxt', _) -> + wrap (Token.balance ctxt src) >>=? fun bal_src -> + wrap (Token.balance ctxt' src) >>=? fun bal_src' -> + wrap (Token.balance ctxt dest) >>=? fun bal_dest -> + wrap (Token.balance ctxt' dest) >>=? fun bal_dest' -> + bal_src' +? amount >>?= fun add_bal_src'_amount -> + bal_dest +? amount >>?= fun add_bal_dest_amount -> + Assert.equal_tez ~loc:__LOC__ bal_src add_bal_src'_amount >>=? fun () -> + Assert.equal_tez ~loc:__LOC__ bal_dest' add_bal_dest_amount + +(** Check balance updates for a simple transfer from [bootstrap] to new + [Implicit]. *) +let test_simple_balance_updates () = + Random.init 0 ; + create_context () >>=? fun (ctxt, pkh) -> + let src = Contract.implicit_contract pkh in + let (pkh, _pk, _sk) = Signature.generate_key () in + let dest = Contract.implicit_contract pkh in + let amount = Tez.one in + wrap (Token.transfer ctxt (`Contract src) (`Contract dest) amount) + >>=? fun (_, bal_updates) -> + Alcotest.( + check + bool + "Missing balance update for source contract." + (List.mem + ~equal:( = ) + Receipt.(Contract src, Debited amount, Block_application) + bal_updates) + true) ; + Alcotest.( + check + bool + "Missing balance update for destination contract." + (List.mem + ~equal:( = ) + Receipt.(Contract dest, Credited amount, Block_application) + bal_updates) + true) ; + return_unit + +let test_allocated_and_deallocated ctxt dest initial_status status_when_empty = + wrap (Token.allocated ctxt dest) >>=? fun allocated -> + Assert.equal_bool ~loc:__LOC__ allocated initial_status >>=? fun () -> + let amount = Tez.one in + wrap (Token.transfer ctxt `Minted dest amount) >>=? fun (ctxt', _) -> + wrap (Token.allocated ctxt' dest) >>=? fun allocated -> + Assert.equal_bool ~loc:__LOC__ allocated true >>=? fun () -> + wrap (Token.balance ctxt' dest) >>=? fun bal_dest' -> + wrap (Token.transfer ctxt' dest `Burned bal_dest') >>=? fun (ctxt', _) -> + wrap (Token.allocated ctxt' dest) >>=? fun allocated -> + Assert.equal_bool ~loc:__LOC__ allocated status_when_empty >>=? fun () -> + return_unit + +let test_allocated_and_deallocated_when_empty ctxt dest = + test_allocated_and_deallocated ctxt dest false false + +let test_allocated_and_still_allocated_when_empty ctxt dest initial_status = + test_allocated_and_deallocated ctxt dest initial_status true + +let test_allocated () = + Random.init 0 ; + create_context () >>=? fun (ctxt, pkh) -> + let dest = `Delegate_balance pkh in + test_allocated_and_still_allocated_when_empty ctxt dest true >>=? fun _ -> + let (pkh, _pk, _sk) = Signature.generate_key () in + let dest = `Contract (Contract.implicit_contract pkh) in + test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> + let dest = `Collected_commitments Blinded_public_key_hash.zero in + test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> + let dest = `Frozen_deposits pkh in + test_allocated_and_still_allocated_when_empty ctxt dest false >>=? fun _ -> + let dest = `Legacy_deposits (pkh, Cycle.root) in + test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> + let dest = `Legacy_fees (pkh, Cycle.root) in + test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> + let dest = `Legacy_rewards (pkh, Cycle.root) in + test_allocated_and_deallocated_when_empty ctxt dest >>=? fun _ -> + let dest = `Block_fees in + test_allocated_and_still_allocated_when_empty ctxt dest true + +let check_sink_balances ctxt ctxt' dest amount = + wrap (Token.balance ctxt dest) >>=? fun bal_dest -> + wrap (Token.balance ctxt' dest) >>=? fun bal_dest' -> + bal_dest +? amount >>?= fun add_bal_dest_amount -> + Assert.equal_tez ~loc:__LOC__ bal_dest' add_bal_dest_amount + +let test_transferring_to_sink ctxt sink amount expected_bupds = + (* Transferring zero must not return balance updates. *) + (match sink with + | `Contract _ | `Delegate_balance _ -> + return_unit (* Transaction of 0tz is forbidden. *) + | _ -> + wrap (Token.transfer ctxt `Minted sink Tez.zero) + >>=? fun (ctxt', bupds) -> + check_sink_balances ctxt ctxt' sink Tez.zero >>=? fun _ -> + Assert.equal_bool ~loc:__LOC__ (bupds = []) true) + >>=? fun _ -> + (* Test transferring a non null amount. *) + wrap (Token.transfer ctxt `Minted sink amount) >>=? fun (ctxt', bupds) -> + check_sink_balances ctxt ctxt' sink amount >>=? fun _ -> + let expected_bupds = + Receipt.(Minted, Debited amount, Block_application) :: expected_bupds + in + Alcotest.( + check bool "Balance updates do not match." (bupds = expected_bupds) true) ; + return_unit + +let test_transferring_to_contract ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let dest = Contract.implicit_contract pkh in + let amount = random_amount () in + test_transferring_to_sink + ctxt + (`Contract dest) + amount + [(Contract dest, Credited amount, Block_application)] + +let test_transferring_to_collected_commitments ctxt = + let amount = random_amount () in + let bpkh = Blinded_public_key_hash.zero in + test_transferring_to_sink + ctxt + (`Collected_commitments bpkh) + amount + [(Commitments bpkh, Credited amount, Block_application)] + +let test_transferring_to_delegate_balance ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let dest = Contract.implicit_contract pkh in + (* First we need to force the allocation of [dest]. *) + wrap (Token.transfer ctxt `Minted (`Contract dest) Tez.one) + >>=? fun (ctxt, _) -> + wrap (Token.allocated ctxt (`Delegate_balance pkh)) >>=? fun allocated -> + Assert.equal_bool ~loc:__LOC__ allocated true >>=? fun () -> + let amount = random_amount () in + test_transferring_to_sink + ctxt + (`Delegate_balance pkh) + amount + [(Contract dest, Credited amount, Block_application)] + +let test_transferring_to_frozen_deposits ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let amount = random_amount () in + test_transferring_to_sink + ctxt + (`Frozen_deposits pkh) + amount + [(Deposits pkh, Credited amount, Block_application)] + +let test_transferring_to_collected_fees ctxt = + let amount = random_amount () in + test_transferring_to_sink + ctxt + `Block_fees + amount + [(Block_fees, Credited amount, Block_application)] + +let test_transferring_to_legacy_deposits ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let amount = random_amount () in + let cycle = Cycle.(add root (Random.int 10)) in + test_transferring_to_sink + ctxt + (`Legacy_deposits (pkh, cycle)) + amount + [(Legacy_deposits (pkh, cycle), Credited amount, Block_application)] + +let test_transferring_to_legacy_fees ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let amount = random_amount () in + let cycle = Cycle.(add root (Random.int 10)) in + test_transferring_to_sink + ctxt + (`Legacy_fees (pkh, cycle)) + amount + [(Legacy_fees (pkh, cycle), Credited amount, Block_application)] + +let test_transferring_to_legacy_rewards ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let amount = random_amount () in + let cycle = Cycle.(add root (Random.int 10)) in + test_transferring_to_sink + ctxt + (`Legacy_rewards (pkh, cycle)) + amount + [(Legacy_rewards (pkh, cycle), Credited amount, Block_application)] + +let test_transferring_to_burned ctxt = + let amount = random_amount () in + let minted_bupd = Receipt.(Minted, Debited amount, Block_application) in + wrap (Token.transfer ctxt `Minted `Burned amount) >>=? fun (_, bupds) -> + Assert.equal_bool + ~loc:__LOC__ + (bupds = [minted_bupd; (Burned, Credited amount, Block_application)]) + true + >>=? fun () -> + wrap (Token.transfer ctxt `Minted `Storage_fees amount) >>=? fun (_, bupds) -> + Assert.equal_bool + ~loc:__LOC__ + (bupds = [minted_bupd; (Storage_fees, Credited amount, Block_application)]) + true + >>=? fun () -> + wrap (Token.transfer ctxt `Minted `Double_signing_punishments amount) + >>=? fun (_, bupds) -> + Assert.equal_bool + ~loc:__LOC__ + (bupds + = [ + minted_bupd; + (Double_signing_punishments, Credited amount, Block_application); + ]) + true + >>=? fun () -> + let pkh = Signature.Public_key_hash.zero in + let (p, r) = (Random.bool (), Random.bool ()) in + wrap + (Token.transfer ctxt `Minted (`Lost_endorsing_rewards (pkh, p, r)) amount) + >>=? fun (_, bupds) -> + Assert.equal_bool + ~loc:__LOC__ + (bupds + = [ + minted_bupd; + (Lost_endorsing_rewards (pkh, p, r), Credited amount, Block_application); + ]) + true + +let test_transferring_to_sink () = + Random.init 0 ; + create_context () >>=? fun (ctxt, _) -> + test_transferring_to_contract ctxt >>=? fun _ -> + test_transferring_to_collected_commitments ctxt >>=? fun _ -> + test_transferring_to_delegate_balance ctxt >>=? fun _ -> + test_transferring_to_frozen_deposits ctxt >>=? fun _ -> + test_transferring_to_collected_fees ctxt >>=? fun _ -> + test_transferring_to_burned ctxt >>=? fun _ -> + test_transferring_to_legacy_deposits ctxt >>=? fun _ -> + test_transferring_to_legacy_fees ctxt >>=? fun _ -> + test_transferring_to_legacy_rewards ctxt + +let check_src_balances ctxt ctxt' src amount = + wrap (Token.balance ctxt src) >>=? fun bal_src -> + wrap (Token.balance ctxt' src) >>=? fun bal_src' -> + bal_src' +? amount >>?= fun add_bal_src'_amount -> + Assert.equal_tez ~loc:__LOC__ bal_src add_bal_src'_amount + +let test_transferring_from_unbounded_source ctxt src expected_bupds = + (* Transferring zero must not return balance updates. *) + wrap (Token.transfer ctxt src `Burned Tez.zero) >>=? fun (_, bupds) -> + Assert.equal_bool ~loc:__LOC__ (bupds = []) true >>=? fun () -> + (* Test transferring a non null amount. *) + let amount = random_amount () in + wrap (Token.transfer ctxt src `Burned amount) >>=? fun (_, bupds) -> + let expected_bupds = + expected_bupds amount + @ Receipt.[(Burned, Credited amount, Block_application)] + in + Assert.equal_bool ~loc:__LOC__ (bupds = expected_bupds) true >>=? fun () -> + return_unit + +let test_transferring_from_bounded_source ctxt src amount expected_bupds = + (* Transferring zero must not return balance updates. *) + (match src with + | `Contract _ | `Delegate_balance _ -> + return_unit (* Transaction of 0tz is forbidden. *) + | _ -> + wrap (Token.transfer ctxt src `Burned Tez.zero) >>=? fun (ctxt', bupds) -> + check_src_balances ctxt ctxt' src Tez.zero >>=? fun _ -> + Assert.equal_bool ~loc:__LOC__ (bupds = []) true) + >>=? fun _ -> + (* Test transferring a non null amount. *) + wrap (Token.transfer ctxt `Minted src amount) >>=? fun (ctxt, _) -> + wrap (Token.transfer ctxt src `Burned amount) >>=? fun (ctxt', bupds) -> + check_src_balances ctxt ctxt' src amount >>=? fun _ -> + let expected_bupds = + expected_bupds @ Receipt.[(Burned, Credited amount, Block_application)] + in + Assert.equal_bool ~loc:__LOC__ (bupds = expected_bupds) true + +let test_transferring_from_contract ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let src = Contract.implicit_contract pkh in + let amount = random_amount () in + test_transferring_from_bounded_source + ctxt + (`Contract src) + amount + [(Contract src, Debited amount, Block_application)] + +let test_transferring_from_collected_commitments ctxt = + let amount = random_amount () in + let bpkh = Blinded_public_key_hash.zero in + test_transferring_from_bounded_source + ctxt + (`Collected_commitments bpkh) + amount + [(Commitments bpkh, Debited amount, Block_application)] + +let test_transferring_from_delegate_balance ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let amount = random_amount () in + let src = Contract.implicit_contract pkh in + (* First we need to force the allocation of [dest]. *) + wrap (Token.transfer ctxt `Minted (`Contract src) Tez.one) + >>=? fun (ctxt, _) -> + test_transferring_from_bounded_source + ctxt + (`Delegate_balance pkh) + amount + [(Contract src, Debited amount, Block_application)] + +let test_transferring_from_frozen_deposits ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let amount = random_amount () in + test_transferring_from_bounded_source + ctxt + (`Frozen_deposits pkh) + amount + [(Deposits pkh, Debited amount, Block_application)] + +let test_transferring_from_collected_fees ctxt = + let amount = random_amount () in + test_transferring_from_bounded_source + ctxt + `Block_fees + amount + [(Block_fees, Debited amount, Block_application)] + +let test_transferring_from_legacy_deposits ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let amount = random_amount () in + let cycle = Cycle.(add root (Random.int 10)) in + test_transferring_from_bounded_source + ctxt + (`Legacy_deposits (pkh, cycle)) + amount + [(Legacy_deposits (pkh, cycle), Debited amount, Block_application)] + +let test_transferring_from_legacy_fees ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let amount = random_amount () in + let cycle = Cycle.(add root (Random.int 10)) in + test_transferring_from_bounded_source + ctxt + (`Legacy_fees (pkh, cycle)) + amount + [(Legacy_fees (pkh, cycle), Debited amount, Block_application)] + +let test_transferring_from_legacy_rewards ctxt = + let (pkh, _pk, _sk) = Signature.generate_key () in + let amount = random_amount () in + let cycle = Cycle.(add root (Random.int 10)) in + test_transferring_from_bounded_source + ctxt + (`Legacy_rewards (pkh, cycle)) + amount + [(Legacy_rewards (pkh, cycle), Debited amount, Block_application)] + +let test_transferring_from_source () = + Random.init 0 ; + create_context () >>=? fun (ctxt, _) -> + test_transferring_from_unbounded_source ctxt `Invoice (fun am -> + [(Invoice, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_unbounded_source ctxt `Bootstrap (fun am -> + [(Bootstrap, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_unbounded_source ctxt `Initial_commitments (fun am -> + [(Initial_commitments, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_unbounded_source ctxt `Revelation_rewards (fun am -> + [(Nonce_revelation_rewards, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_unbounded_source + ctxt + `Double_signing_evidence_rewards + (fun am -> + [(Double_signing_evidence_rewards, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_unbounded_source ctxt `Endorsing_rewards (fun am -> + [(Endorsing_rewards, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_unbounded_source ctxt `Baking_rewards (fun am -> + [(Baking_rewards, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_unbounded_source ctxt `Baking_bonuses (fun am -> + [(Baking_bonuses, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_unbounded_source ctxt `Minted (fun am -> + [(Minted, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_unbounded_source + ctxt + `Liquidity_baking_subsidies + (fun am -> [(Liquidity_baking_subsidies, Debited am, Block_application)]) + >>=? fun _ -> + test_transferring_from_contract ctxt >>=? fun _ -> + test_transferring_from_collected_commitments ctxt >>=? fun _ -> + test_transferring_from_delegate_balance ctxt >>=? fun _ -> + test_transferring_from_frozen_deposits ctxt >>=? fun _ -> + test_transferring_from_collected_fees ctxt >>=? fun _ -> + test_transferring_from_legacy_deposits ctxt >>=? fun _ -> + test_transferring_from_legacy_fees ctxt >>=? fun _ -> + test_transferring_from_legacy_rewards ctxt + +let cast_to_container_type x = + match x with + | `Burned | `Invoice | `Bootstrap | `Initial_commitments | `Minted + | `Liquidity_baking_subsidies -> + None + | `Contract _ as x -> Some x + | `Collected_commitments _ as x -> Some x + | `Delegate_balance _ as x -> Some x + | `Block_fees as x -> Some x + +(** Generates all combinations of constructors. *) +let build_test_cases () = + create_context () >>=? fun (ctxt, pkh) -> + let origin = `Contract (Contract.implicit_contract pkh) in + let (user1, _, _) = Signature.generate_key () in + let user1c = `Contract (Contract.implicit_contract user1) in + let (user2, _, _) = Signature.generate_key () in + let user2c = `Contract (Contract.implicit_contract user2) in + let (baker1, baker1_pk, _) = Signature.generate_key () in + let baker1c = `Contract (Contract.implicit_contract baker1) in + let (baker2, baker2_pk, _) = Signature.generate_key () in + let baker2c = `Contract (Contract.implicit_contract baker2) in + (* Allocate contracts for user1, user2, baker1, and baker2. *) + wrap (Token.transfer ctxt origin user1c (random_amount ())) + >>=? fun (ctxt, _) -> + wrap (Token.transfer ctxt origin user2c (random_amount ())) + >>=? fun (ctxt, _) -> + wrap (Token.transfer ctxt origin baker1c (random_amount ())) + >>=? fun (ctxt, _) -> + wrap (Token.transfer ctxt origin baker2c (random_amount ())) + >>=? fun (ctxt, _) -> + (* Configure baker1, and baker2 as delegates by self-delegation, for which + revealing their manager key is a prerequisite. *) + wrap (Contract.reveal_manager_key ctxt baker1 baker1_pk) >>=? fun ctxt -> + wrap (Delegate.set ctxt (Contract.implicit_contract baker1) (Some baker1)) + >>=? fun ctxt -> + wrap (Contract.reveal_manager_key ctxt baker2 baker2_pk) >>=? fun ctxt -> + wrap (Delegate.set ctxt (Contract.implicit_contract baker2) (Some baker2)) + (* Let user1 delegate to baker2. *) + >>=? fun ctxt -> + wrap (Delegate.set ctxt (Contract.implicit_contract user1) (Some baker2)) + >>=? fun ctxt -> + let src_list = + [ + (`Invoice, random_amount ()); + (`Bootstrap, random_amount ()); + (`Initial_commitments, random_amount ()); + (`Minted, random_amount ()); + (`Liquidity_baking_subsidies, random_amount ()); + (`Collected_commitments Blinded_public_key_hash.zero, random_amount ()); + (`Delegate_balance baker1, random_amount ()); + (`Delegate_balance baker2, random_amount ()); + (`Block_fees, random_amount ()); + (user1c, random_amount ()); + (user2c, random_amount ()); + (baker1c, random_amount ()); + (baker2c, random_amount ()); + ] + in + let dest_list = + [ + `Collected_commitments Blinded_public_key_hash.zero; + `Delegate_balance baker1; + `Delegate_balance baker2; + `Block_fees; + user1c; + user2c; + baker1c; + baker2c; + `Burned; + ] + in + return (ctxt, List.product src_list dest_list) + +let check_src_balances ctxt ctxt' src amount = + match cast_to_container_type src with + | None -> return_unit + | Some src -> check_src_balances ctxt ctxt' src amount + +let check_sink_balances ctxt ctxt' dest amount = + match cast_to_container_type dest with + | None -> return_unit + | Some dest -> check_sink_balances ctxt ctxt' dest amount + +let rec check_balances ctxt ctxt' src dest amount = + match (cast_to_container_type src, cast_to_container_type dest) with + | (None, None) -> return_unit + | (Some (`Delegate_balance d), Some (`Contract c as contract)) + when Contract.implicit_contract d = c -> + (* src and dest are in fact referring to the same contract *) + check_balances ctxt ctxt' contract contract amount + | (Some (`Contract c as contract), Some (`Delegate_balance d)) + when Contract.implicit_contract d = c -> + (* src and dest are in fact referring to the same contract *) + check_balances ctxt ctxt' contract contract amount + | (Some src, Some dest) when src = dest -> + (* src and dest are the same contract *) + wrap (Token.balance ctxt dest) >>=? fun bal_dest -> + wrap (Token.balance ctxt' dest) >>=? fun bal_dest' -> + Assert.equal_tez ~loc:__LOC__ bal_dest bal_dest' + | (Some src, None) -> check_src_balances ctxt ctxt' src amount + | (None, Some dest) -> check_sink_balances ctxt ctxt' dest amount + | (Some src, Some dest) -> + check_src_balances ctxt ctxt' src amount >>=? fun _ -> + check_sink_balances ctxt ctxt' dest amount + +let test_all_combinations_of_sources_and_sinks () = + Random.init 0 ; + build_test_cases () >>=? fun (ctxt, cases) -> + List.iter_es + (fun ((src, amount), dest) -> + (match cast_to_container_type src with + | None -> return ctxt + | Some src -> + wrap (Token.transfer ctxt `Minted src amount) >>=? fun (ctxt, _) -> + return ctxt) + >>=? fun ctxt -> + wrap (Token.transfer ctxt src dest amount) >>=? fun (ctxt', _) -> + check_balances ctxt ctxt' src dest amount) + cases + +(** [coalesce (account, Credited am1, origin) (account, Credited am2, origin) + = Some (account, Credited (am1+am2), origin)] + + [coalesce (account, Debited am1, origin) (account, Debited am2, origin) + = Some (account, Debited (am1+am2), origin)] + + Fails if bu1 and bu2 have different accounts or different origins, or + if one is a credit while the other is a debit. *) +let coalesce_balance_updates bu1 bu2 = + match (bu1, bu2) with + | ((bu1_bal, bu1_balupd, bu1_origin), (bu2_bal, bu2_balupd, bu2_origin)) -> ( + assert (bu1_bal = bu2_bal) ; + assert (bu1_origin = bu2_origin) ; + let open Receipt in + match (bu1_balupd, bu2_balupd) with + | (Credited bu1_am, Credited bu2_am) -> + let bu_am = + match bu1_am +? bu2_am with Ok am -> am | _ -> assert false + in + (bu1_bal, Credited bu_am, bu1_origin) + | (Debited bu1_am, Debited bu2_am) -> + let bu_am = + match bu1_am +? bu2_am with Ok am -> am | _ -> assert false + in + (bu1_bal, Debited bu_am, bu1_origin) + | (Credited _, Debited _) | (Debited _, Credited _) -> assert false) + +(** Check that elt has the same balance in ctxt1 and ctxt2. *) +let check_balances_are_consistent ctxt1 ctxt2 elt = + match elt with + | #Token.container as elt -> + Token.balance ctxt1 elt >>=? fun elt_bal1 -> + Token.balance ctxt2 elt >>=? fun elt_bal2 -> + assert (elt_bal1 = elt_bal2) ; + return_unit + | `Invoice | `Bootstrap | `Initial_commitments | `Minted + | `Liquidity_baking_subsidies | `Burned -> + return_unit + +(** Test that [transfer_n] is equivalent to n debits followed by n credits. *) +let test_transfer_n ctxt src dest = + (* Run transfer_n. *) + Token.transfer_n ctxt src dest >>=? fun (ctxt1, bal_updates1) -> + (* Debit all sources. *) + List.fold_left_es + (fun (ctxt, bal_updates) (src, am) -> + Token.transfer ctxt src `Burned am >>=? fun (ctxt, debit_logs) -> + return (ctxt, bal_updates @ debit_logs)) + (ctxt, []) + src + >>=? fun (ctxt, debit_logs) -> + (* remove burning balance updates *) + let debit_logs = + List.filter + (fun b -> match b with (Receipt.Burned, _, _) -> false | _ -> true) + debit_logs + in + (* Credit the sink for each source. *) + List.fold_left_es + (fun (ctxt, bal_updates) (_, am) -> + Token.transfer ctxt `Minted dest am >>=? fun (ctxt, credit_logs) -> + return (ctxt, bal_updates @ credit_logs)) + (ctxt, []) + src + >>=? fun (ctxt2, credit_logs) -> + (* remove minting balance updates *) + let credit_logs = + List.filter + (fun b -> match b with (Receipt.Minted, _, _) -> false | _ -> true) + credit_logs + in + (* Check equivalence of balance updates. *) + let credit_logs = + match credit_logs with + | [] -> [] + | head :: tail -> [List.fold_left coalesce_balance_updates head tail] + in + assert (bal_updates1 = debit_logs @ credit_logs) ; + (* Check balances are the same in ctxt1 and ctxt2. *) + List.(iter_es (check_balances_are_consistent ctxt1 ctxt2) (map fst src)) + >>=? fun _ -> check_balances_are_consistent ctxt1 ctxt2 dest + +let test_transfer_n_with_empty_source () = + Random.init 0 ; + create_context () >>=? fun (ctxt, pkh) -> + wrap (test_transfer_n ctxt [] `Block_fees) >>=? fun _ -> + let dest = `Delegate_balance pkh in + wrap (test_transfer_n ctxt [] dest) + +let test_transfer_n_with_non_empty_source () = + Random.init 0 ; + create_context () >>=? fun (ctxt, pkh) -> + let origin = `Contract (Contract.implicit_contract pkh) in + let (user1, _, _) = Signature.generate_key () in + let user1c = `Contract (Contract.implicit_contract user1) in + let (user2, _, _) = Signature.generate_key () in + let user2c = `Contract (Contract.implicit_contract user2) in + let (user3, _, _) = Signature.generate_key () in + let user3c = `Contract (Contract.implicit_contract user3) in + let (user4, _, _) = Signature.generate_key () in + let user4c = `Contract (Contract.implicit_contract user4) in + (* Allocate contracts for user1, user2, user3, and user4. *) + let amount = + match Tez.of_mutez 1000L with None -> assert false | Some x -> x + in + wrap (Token.transfer ctxt origin user1c amount) >>=? fun (ctxt, _) -> + wrap (Token.transfer ctxt origin user2c amount) >>=? fun (ctxt, _) -> + wrap (Token.transfer ctxt origin user3c amount) >>=? fun (ctxt, _) -> + wrap (Token.transfer ctxt origin user4c (random_amount ())) + >>=? fun (ctxt, _) -> + let sources = + [ + (user2c, random_amount ()); + (user3c, random_amount ()); + (user4c, random_amount ()); + ] + in + wrap (test_transfer_n ctxt sources user1c) >>=? fun _ -> + wrap (test_transfer_n ctxt ((user1c, random_amount ()) :: sources) user1c) + +let tests = + Tztest. + [ + tztest "transfer - balances" `Quick test_simple_balances; + tztest "transfer - balance updates" `Quick test_simple_balance_updates; + tztest "transfer - test allocated" `Quick test_allocated; + tztest "transfer - test transfer to sink" `Quick test_transferring_to_sink; + tztest + "transfer - test transfer from source" + `Quick + test_transferring_from_source; + tztest + "transfer - test all (sources x sinks)" + `Quick + test_all_combinations_of_sources_and_sinks; + tztest + "transfer - test from empty sources to a destination" + `Quick + test_transfer_n_with_empty_source; + tztest + "transfer - test from n sources to a destination" + `Quick + test_transfer_n_with_non_empty_source; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_transfer.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_transfer.ml new file mode 100644 index 000000000000..c00597850c00 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_transfer.ml @@ -0,0 +1,801 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (transfer) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^transfer$" + Subject: Quantities transfer between contracts. +*) + +open Protocol +open Alpha_context +open Test_tez + +(*********************************************************************) +(* Utility functions *) +(*********************************************************************) + +(** + [transfer_and_check_balances b fee src dst amount] + this function takes a block, an optional parameter fee if fee does not + given it will be set to zero tez, a source contract, a destination contract + and the amount that one wants to transfer. + + 1- Transfer the amount of tez (w/wo fee) from a source contract to a + destination contract. + + 2- Check the equivalent of the balance of the source/destination + contract before and after transfer is validated. + + This function returns a pair: + - A block that added a valid operation + - a valid operation *) +let transfer_and_check_balances ?(with_burn = false) ~loc b ?(fee = Tez.zero) + ?expect_failure src dst amount = + fee +? amount >>?= fun amount_fee -> + Context.Contract.balance (I b) src >>=? fun bal_src -> + Context.Contract.balance (I b) dst >>=? fun bal_dst -> + Op.transaction + ~gas_limit:(Alpha_context.Gas.Arith.integral_of_int_exn 3000) + (I b) + ~fee + src + dst + amount + >>=? fun op -> + Incremental.add_operation ?expect_failure b op >>=? fun b -> + Context.get_constants (I b) + >>=? fun {parametric = {origination_size; cost_per_byte; _}; _} -> + cost_per_byte *? Int64.of_int origination_size >>?= fun origination_burn -> + let amount_fee_maybe_burn = + if with_burn then + match Tez.(amount_fee +? origination_burn) with + | Ok r -> r + | Error _ -> assert false + else amount_fee + in + Assert.balance_was_debited ~loc (I b) src bal_src amount_fee_maybe_burn + >>=? fun () -> + Assert.balance_was_credited ~loc (I b) dst bal_dst amount >|=? fun () -> + (b, op) + +(** + [transfer_to_itself_and_check_balances b fee contract amount] + this function takes a block, an optional parameter fee, + a contract that is a source and a destination contract, + and an amount of tez that one wants to transfer. + + 1- Transfer the amount of tez (w/wo transfer fee) from/to a contract itself. + + 2- Check the equivalent of the balance of the contract before + and after transfer. + + This function returns a pair: + - a block that added the valid transaction + - an valid transaction *) +let transfer_to_itself_and_check_balances ~loc b ?(fee = Tez.zero) contract + amount = + Context.Contract.balance (I b) contract >>=? fun bal -> + Op.transaction (I b) ~fee contract contract amount >>=? fun op -> + Incremental.add_operation b op >>=? fun b -> + Assert.balance_was_debited ~loc (I b) contract bal fee >|=? fun () -> (b, op) + +(** + [n_transactions n b fee source dest amount] + this function takes a number of "n" that one wish to transfer, + a block, an optional parameter fee, a source contract, + a destination contract and an amount one wants to transfer. + + This function will do a transaction from a source contract to + a destination contract with the amount "n" times. *) +let n_transactions n b ?fee source dest amount = + List.fold_left_es + (fun b _ -> + transfer_and_check_balances ~loc:__LOC__ b ?fee source dest amount + >|=? fun (b, _) -> b) + b + (1 -- n) + +let ten_tez = of_int 10 + +(*********************************************************************) +(* Tests *) +(*********************************************************************) + +let register_two_contracts ?consensus_threshold () = + Context.init ?consensus_threshold 2 >|=? function + | (_, []) | (_, [_]) -> assert false + | (b, contract_1 :: contract_2 :: _) -> (b, contract_1, contract_2) + +(** Compute a fraction of 2/[n] of the balance of [contract] *) +let two_over_n_of_balance incr contract n = + Context.Contract.balance (I incr) contract >>=? fun balance -> + Lwt.return (balance /? n >>? fun res -> res *? 2L) + +(********************) +(** Single transfer *) + +(********************) + +let single_transfer ?fee ?expect_failure amount = + register_two_contracts () >>=? fun (b, contract_1, contract_2) -> + Incremental.begin_construction b >>=? fun b -> + transfer_and_check_balances + ~loc:__LOC__ + ?fee + ?expect_failure + b + contract_1 + contract_2 + amount + >>=? fun (b, _) -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(** Single transfer without fee. *) +let test_block_with_a_single_transfer () = single_transfer Tez.one + +(** Single transfer with fee. *) +let test_block_with_a_single_transfer_with_fee () = + single_transfer ~fee:Tez.one Tez.one + +(** Single transfer without fee. *) +let test_transfer_zero_tez () = + single_transfer + ~expect_failure:(function + | Environment.Ecoproto_error (Apply.Empty_transaction _ as e) :: _ -> + Assert.test_error_encodings e ; + return_unit + | _ -> failwith "Empty transaction should fail") + Tez.zero + +(** Transfer zero tez from an implicit contract. *) +let test_transfer_zero_implicit () = + Context.init 1 >>=? fun (b, contracts) -> + let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in + let account = Account.new_account () in + Incremental.begin_construction b >>=? fun i -> + let src = Contract.implicit_contract account.Account.pkh in + Op.transaction (I i) src dest Tez.zero >>=? fun op -> + Incremental.add_operation i op >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Contract_storage.Empty_implicit_contract _ -> true + | _ -> false) + +(** Transfer to originated contract. *) +let test_transfer_to_originate_with_fee () = + Context.init 1 >>=? fun (b, contracts) -> + let contract = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 + in + Incremental.begin_construction b >>=? fun b -> + two_over_n_of_balance b contract 10L >>=? fun fee -> + (* originated contract, paying a fee to originated this contract *) + Op.origination (I b) ~fee:ten_tez contract ~script:Op.dummy_script + >>=? fun (operation, new_contract) -> + Incremental.add_operation b operation >>=? fun b -> + two_over_n_of_balance b contract 3L >>=? fun amount -> + transfer_and_check_balances ~loc:__LOC__ b ~fee contract new_contract amount + >>=? fun (b, _) -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(** Transfer from balance. *) +let test_transfer_amount_of_contract_balance () = + register_two_contracts () >>=? fun (b, contract_1, contract_2) -> + Context.Contract.pkh contract_1 >>=? fun pkh1 -> + (* given that contract_1 no longer has a sufficient balance to bake, + make sure it cannot be chosen as baker *) + Incremental.begin_construction b ~policy:(Block.Excluding [pkh1]) + >>=? fun b -> + (* get the balance of the source contract *) + Context.Contract.balance (I b) contract_1 >>=? fun balance -> + (* transfer all the tez inside contract 1 *) + transfer_and_check_balances ~loc:__LOC__ b contract_1 contract_2 balance + >>=? fun (b, _) -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(** Transfer to oneself. *) +let test_transfers_to_self () = + Context.init 1 >>=? fun (b, contracts) -> + let contract = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 + in + Incremental.begin_construction b >>=? fun b -> + two_over_n_of_balance b contract 3L >>=? fun amount -> + transfer_to_itself_and_check_balances ~loc:__LOC__ b contract amount + >>=? fun (b, _) -> + two_over_n_of_balance b contract 5L >>=? fun fee -> + transfer_to_itself_and_check_balances ~loc:__LOC__ b ~fee contract ten_tez + >>=? fun (b, _) -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(** Forgot to add the valid transaction into the block. *) +let test_missing_transaction () = + register_two_contracts () >>=? fun (b, contract_1, contract_2) -> + (* given that contract_1 no longer has a sufficient balance to bake, + make sure it cannot be chosen as baker *) + Context.Contract.pkh contract_1 >>=? fun pkh1 -> + Incremental.begin_construction b ~policy:(Block.Excluding [pkh1]) + >>=? fun b -> + two_over_n_of_balance b contract_1 6L >>=? fun amount -> + (* Do the transfer 3 times from source contract to destination contract *) + n_transactions 3 b contract_1 contract_2 amount >>=? fun b -> + (* do the fourth transfer from source contract to destination contract *) + Op.transaction (I b) contract_1 contract_2 amount >>=? fun _ -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(** Transfer zero tez to an implicit contract, with fee equals balance of src. *) +let test_transfer_zero_implicit_with_bal_src_as_fee () = + Context.init 1 >>=? fun (b, contracts) -> + let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in + let account = Account.new_account () in + Incremental.begin_construction b >>=? fun i -> + let src = Contract.implicit_contract account.Account.pkh in + Op.transaction (I i) dest src (Tez.of_mutez_exn 100L) >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Context.Contract.balance (I i) src >>=? fun bal_src -> + Assert.equal_tez ~loc:__LOC__ bal_src (Tez.of_mutez_exn 100L) >>=? fun () -> + Op.transaction (I i) ~fee:bal_src src dest Tez.zero >>=? fun op -> + Incremental.add_operation i op >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Apply.Empty_transaction _ -> true + | _ -> false) + +(** Transfer zero tez to an originated contract, with fee equals balance of src. *) +let test_transfer_zero_to_originated_with_bal_src_as_fee () = + Context.init 1 >>=? fun (b, contracts) -> + let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in + let account = Account.new_account () in + Incremental.begin_construction b >>=? fun i -> + let src = Contract.implicit_contract account.Account.pkh in + Op.transaction (I i) dest src (Tez.of_mutez_exn 100L) >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Op.origination (I i) dest ~script:Op.dummy_script + >>=? fun (op, new_contract) -> + Incremental.add_operation i op >>=? fun i -> + Context.Contract.balance (I i) src >>=? fun bal_src -> + Op.transaction (I i) ~fee:bal_src src new_contract Tez.zero >>=? fun op -> + Assert.equal_tez ~loc:__LOC__ bal_src (Tez.of_mutez_exn 100L) >>=? fun () -> + Incremental.add_operation i op >>=? fun i -> + Incremental.finalize_block i >>=? fun _ -> return_unit + +(** Transfer one tez to an implicit contract, with fee equals balance of src. *) +let test_transfer_one_to_implicit_with_bal_src_as_fee () = + Context.init 1 >>=? fun (b, contracts) -> + let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in + let account = Account.new_account () in + Incremental.begin_construction b >>=? fun i -> + let src = Contract.implicit_contract account.Account.pkh in + Op.transaction (I i) dest src (Tez.of_mutez_exn 100L) >>=? fun op -> + Incremental.add_operation i op >>=? fun i -> + Context.Contract.balance (I i) src >>=? fun bal_src -> + Assert.equal_tez ~loc:__LOC__ bal_src (Tez.of_mutez_exn 100L) >>=? fun () -> + Op.transaction (I i) ~fee:bal_src src dest Tez.one >>=? fun op -> + Incremental.add_operation i op >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Contract_storage.Balance_too_low _ -> true + | _ -> false) + +(********************) +(* The following tests are for different kind of contracts: + - implicit to implicit + - implicit to originated + - originated to implicit + - originated to originated *) + +(********************) + +(** Implicit to Implicit. *) +let test_transfer_from_implicit_to_implicit_contract () = + Context.init 1 >>=? fun (b, contracts) -> + let bootstrap_contract = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 + in + let account_a = Account.new_account () in + let account_b = Account.new_account () in + Incremental.begin_construction b >>=? fun b -> + let src = Contract.implicit_contract account_a.Account.pkh in + two_over_n_of_balance b bootstrap_contract 3L >>=? fun amount1 -> + two_over_n_of_balance b bootstrap_contract 10L >>=? fun fee1 -> + transfer_and_check_balances + ~with_burn:true + ~loc:__LOC__ + ~fee:fee1 + b + bootstrap_contract + src + amount1 + >>=? fun (b, _) -> + (* Create an implicit contract as a destination contract. *) + let dest = Contract.implicit_contract account_b.pkh in + two_over_n_of_balance b bootstrap_contract 4L >>=? fun amount2 -> + two_over_n_of_balance b bootstrap_contract 10L >>=? fun fee2 -> + (* Transfer from implicit contract to another implicit contract. *) + transfer_and_check_balances + ~with_burn:true + ~loc:__LOC__ + ~fee:fee2 + b + src + dest + amount2 + >>=? fun (b, _) -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(** Implicit to originated. *) +let test_transfer_from_implicit_to_originated_contract () = + Context.init 1 >>=? fun (b, contracts) -> + let bootstrap_contract = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 + in + let contract = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 + in + let account = Account.new_account () in + let src = Contract.implicit_contract account.Account.pkh in + Incremental.begin_construction b >>=? fun b -> + two_over_n_of_balance b bootstrap_contract 3L >>=? fun amount1 -> + (* transfer the money to implicit contract *) + transfer_and_check_balances + ~with_burn:true + ~loc:__LOC__ + b + bootstrap_contract + src + amount1 + >>=? fun (b, _) -> + (* originated contract *) + Op.origination (I b) contract ~script:Op.dummy_script + >>=? fun (operation, new_contract) -> + Incremental.add_operation b operation >>=? fun b -> + two_over_n_of_balance b bootstrap_contract 4L >>=? fun amount2 -> + (* transfer from implicit contract to originated contract *) + transfer_and_check_balances ~loc:__LOC__ b src new_contract amount2 + >>=? fun (b, _) -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(********************) +(* Slow tests case *) + +(********************) + +let multiple_transfer n ?fee amount = + register_two_contracts () >>=? fun (b, contract_1, contract_2) -> + Incremental.begin_construction b >>=? fun b -> + n_transactions n b ?fee contract_1 contract_2 amount >>=? fun b -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(** 1- Create a block with two contracts; + 2- Apply 100 transfers. +*) +let test_block_with_multiple_transfers () = multiple_transfer 99 (of_int 1000) + +(** 1- Create a block with two contracts; + 2- Apply 100 transfers with 10tz fee. *) +let test_block_with_multiple_transfers_pay_fee () = + multiple_transfer 10 ~fee:ten_tez (of_int 1000) + +(* TODO : increase the number of operations and add a `Slow tag to it in `tests` *) + +(** 1- Create a block with 8 contracts; + 2- Apply multiple transfers without fees; + 3- Apply multiple transfers with fees. *) +let test_block_with_multiple_transfers_with_without_fee () = + Context.init 8 >>=? fun (b, contracts) -> + let contracts = Array.of_list contracts in + Incremental.begin_construction b >>=? fun b -> + let hundred = of_int 100 in + let ten = of_int 10 in + let twenty = of_int 20 in + n_transactions 10 b contracts.(0) contracts.(1) Tez.one >>=? fun b -> + n_transactions 30 b contracts.(1) contracts.(2) hundred >>=? fun b -> + n_transactions 30 b contracts.(1) contracts.(3) hundred >>=? fun b -> + n_transactions 30 b contracts.(4) contracts.(3) hundred >>=? fun b -> + n_transactions 20 b contracts.(0) contracts.(1) hundred >>=? fun b -> + n_transactions 10 b contracts.(1) contracts.(3) hundred >>=? fun b -> + n_transactions 10 b contracts.(1) contracts.(3) hundred >>=? fun b -> + n_transactions 20 ~fee:ten b contracts.(3) contracts.(4) ten >>=? fun b -> + n_transactions 10 ~fee:twenty b contracts.(4) contracts.(5) ten >>=? fun b -> + n_transactions 70 ~fee:twenty b contracts.(6) contracts.(0) twenty + >>=? fun b -> + n_transactions 550 ~fee:twenty b contracts.(6) contracts.(4) twenty + >>=? fun b -> + n_transactions 50 ~fee:ten b contracts.(7) contracts.(5) twenty >>=? fun b -> + n_transactions 30 ~fee:ten b contracts.(0) contracts.(7) hundred >>=? fun b -> + n_transactions 20 ~fee:ten b contracts.(1) contracts.(0) twenty >>=? fun b -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(** Build a chain that has 10 blocks. *) +let test_build_a_chain () = + register_two_contracts ~consensus_threshold:0 () + >>=? fun (b, contract_1, contract_2) -> + let ten = of_int 10 in + List.fold_left_es + (fun b _ -> + Incremental.begin_construction b >>=? fun b -> + transfer_and_check_balances ~loc:__LOC__ b contract_1 contract_2 ten + >>=? fun (b, _) -> Incremental.finalize_block b) + b + (1 -- 10) + >>=? fun _ -> return_unit + +(*********************************************************************) +(* Expected error test cases *) +(*********************************************************************) + +(** Transferring zero tez is forbidden in implicit contract. *) +let test_empty_implicit () = + Context.init 1 >>=? fun (b, contracts) -> + let dest = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in + let account = Account.new_account () in + Incremental.begin_construction b >>=? fun incr -> + let src = Contract.implicit_contract account.Account.pkh in + two_over_n_of_balance incr dest 3L >>=? fun amount -> + (* Transfer zero tez from an implicit contract. *) + Op.transaction (I incr) src dest amount >>=? fun op -> + Incremental.add_operation incr op >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Contract_storage.Empty_implicit_contract _ -> true + | _ -> false) + +(** Balance is too low to transfer. *) +let test_balance_too_low fee () = + register_two_contracts () >>=? fun (b, contract_1, contract_2) -> + Incremental.begin_construction b >>=? fun i -> + Context.Contract.balance (I i) contract_1 >>=? fun balance1 -> + Context.Contract.balance (I i) contract_2 >>=? fun balance2 -> + (* transfer the amount of tez that is bigger than the balance in the source contract *) + Op.transaction ~fee (I i) contract_1 contract_2 max_tez >>=? fun op -> + let expect_failure = function + | Environment.Ecoproto_error (Contract_storage.Balance_too_low _ as e) :: _ + -> + Assert.test_error_encodings e ; + return_unit + | _ -> failwith "balance too low should fail" + in + (* the fee is higher than the balance then raise an error "Balance_too_low" *) + if fee > balance1 then + Incremental.add_operation ~expect_failure i op >>= fun _res -> return_unit + (* the fee is smaller than the balance, then the transfer is accepted + but it is not processed, and fees are taken *) + else + Incremental.add_operation ~expect_failure i op >>=? fun i -> + (* contract_1 loses the fees *) + Assert.balance_was_debited ~loc:__LOC__ (I i) contract_1 balance1 fee + >>=? fun () -> + (* contract_2 is not credited *) + Assert.balance_was_credited ~loc:__LOC__ (I i) contract_2 balance2 Tez.zero + +(** 1- Create a block, and three contracts; + 2- Add a transfer that at the end the balance of a contract is + zero into this block; + 3- Add another transfer that send tez from a zero balance contract; + 4- Catch the expected error: Balance_too_low. *) +let test_balance_too_low_two_transfers fee () = + Context.init 3 >>=? fun (b, contracts) -> + let contract_1 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 + in + let contract_2 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 + in + let contract_3 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 2 + in + Incremental.begin_construction b >>=? fun i -> + Context.Contract.balance (I i) contract_1 >>=? fun balance -> + balance /? 3L >>?= fun res -> + res *? 2L >>?= fun two_third_of_balance -> + transfer_and_check_balances + ~loc:__LOC__ + i + contract_1 + contract_2 + two_third_of_balance + >>=? fun (i, _) -> + Context.Contract.balance (I i) contract_1 >>=? fun balance1 -> + Context.Contract.balance (I i) contract_3 >>=? fun balance3 -> + Op.transaction ~fee (I i) contract_1 contract_3 two_third_of_balance + >>=? fun operation -> + let expect_failure = function + | Environment.Ecoproto_error (Contract_storage.Balance_too_low _ as e) :: _ + -> + Assert.test_error_encodings e ; + return_unit + | _ -> failwith "balance too low should fail" + in + Incremental.add_operation ~expect_failure i operation >>=? fun i -> + (* contract_1 loses the fees *) + Assert.balance_was_debited ~loc:__LOC__ (I i) contract_1 balance1 fee + >>=? fun () -> + (* contract_3 is not credited *) + Assert.balance_was_credited ~loc:__LOC__ (I i) contract_3 balance3 Tez.zero + +(** The counter is already used for the previous operation. *) +let invalid_counter () = + register_two_contracts () >>=? fun (b, contract_1, contract_2) -> + Incremental.begin_construction b >>=? fun b -> + Op.transaction (I b) contract_1 contract_2 Tez.one >>=? fun op1 -> + Op.transaction (I b) contract_1 contract_2 Tez.one >>=? fun op2 -> + Incremental.add_operation b op1 >>=? fun b -> + Incremental.add_operation b op2 >>= fun b -> + Assert.proto_error ~loc:__LOC__ b (function + | Contract_storage.Counter_in_the_past _ -> true + | _ -> false) + +(** Same as before but through a different way to perform this + error. *) +let test_add_the_same_operation_twice () = + register_two_contracts () >>=? fun (b, contract_1, contract_2) -> + Incremental.begin_construction b >>=? fun b -> + transfer_and_check_balances ~loc:__LOC__ b contract_1 contract_2 ten_tez + >>=? fun (b, op_transfer) -> + Op.transaction (I b) contract_1 contract_2 ten_tez >>=? fun _ -> + Incremental.add_operation b op_transfer >>= fun b -> + Assert.proto_error ~loc:__LOC__ b (function + | Contract_storage.Counter_in_the_past _ -> true + | _ -> false) + +(** The counter is in the future *) +let invalid_counter_in_the_future () = + register_two_contracts () >>=? fun (b, contract_1, contract_2) -> + Incremental.begin_construction b >>=? fun b -> + Context.Contract.counter (I b) contract_1 >>=? fun cpt -> + let counter = Z.add cpt (Z.of_int 10) in + Op.transaction (I b) contract_1 contract_2 Tez.one ~counter >>=? fun op -> + Incremental.add_operation b op >>= fun b -> + Assert.proto_error_with_info + ~loc:__LOC__ + b + "Invalid counter (not yet reached) in a manager operation" + +(** Check ownership. *) +let test_ownership_sender () = + register_two_contracts () >>=? fun (b, contract_1, contract_2) -> + Incremental.begin_construction b >>=? fun b -> + (* get the manager of the contract_1 as a sender *) + Context.Contract.manager (I b) contract_1 >>=? fun manager -> + (* create an implicit_contract *) + let imcontract_1 = Alpha_context.Contract.implicit_contract manager.pkh in + transfer_and_check_balances ~loc:__LOC__ b imcontract_1 contract_2 Tez.one + >>=? fun (b, _) -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(*********************************************************************) +(* Random transfer *) + +(* Return a pair of minimum and maximum random number. *) +let random_range (min, max) = + let interv = max - min + 1 in + let init = + Random.self_init () ; + Random.int interv + min + in + init + +(* Return a random contract. *) +let random_contract contract_array = + let i = Random.int (Array.length contract_array) in + contract_array.(i) + +(** Transfer by randomly choose amount 10 contracts, and randomly + choose the amount in the source contract. *) +let test_random_transfer () = + Context.init 10 >>=? fun (b, contracts) -> + let contracts = Array.of_list contracts in + let source = random_contract contracts in + let dest = random_contract contracts in + Context.Contract.pkh source >>=? fun source_pkh -> + (* given that source may not have a sufficient balance for the transfer + to bake, + make sure it cannot be chosen as baker *) + Incremental.begin_construction b ~policy:(Block.Excluding [source_pkh]) + >>=? fun b -> + Context.Contract.balance (I b) source >>=? fun amount -> + (if source = dest then + transfer_to_itself_and_check_balances ~loc:__LOC__ b source amount + else transfer_and_check_balances ~loc:__LOC__ b source dest amount) + >>=? fun (b, _) -> + Incremental.finalize_block b >>=? fun _ -> return_unit + +(** Transfer random transactions. *) +let test_random_multi_transactions () = + let n = random_range (1, 100) in + multiple_transfer n (of_int 100) + +(*********************************************************************) + +let test_bad_entrypoint () = + Context.init 1 >>=? fun (b, _cs) -> + Incremental.begin_construction b >>=? fun v -> + let ctxt = Incremental.alpha_ctxt v in + let storage = "Unit" in + let parameter = "Unit" in + let entrypoint = "bad entrypoint" in + (* bad entrypoint *) + Contract_helpers.run_script + ctxt + "{parameter unit; storage unit; code { CAR; NIL operation; PAIR }}" + ~entrypoint + ~storage + ~parameter + () + >>= function + | Ok _ -> Alcotest.fail "expected error" + | Error lst + when List.mem + ~equal:( = ) + (Environment.Ecoproto_error + (Script_tc_errors.No_such_entrypoint entrypoint)) + lst -> + return () + | Error errs -> + Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs + +let test_bad_parameter () = + Context.init 1 >>=? fun (b, _cs) -> + Incremental.begin_construction b >>=? fun v -> + let ctxt = Incremental.alpha_ctxt v in + let storage = "Unit" in + let parameter = "1" in + (* bad parameter *) + Contract_helpers.run_script + ctxt + "{parameter unit; storage unit; code { CAR; NIL operation; PAIR }}" + ~storage + ~parameter + () + >>= function + | Ok _ -> Alcotest.fail "expected error" + | Error lst + when List.mem + ~equal:( = ) + (Environment.Ecoproto_error + (Script_interpreter.Bad_contract_parameter + (Contract.implicit_contract Signature.Public_key_hash.zero))) + lst -> + return () + | Error errs -> + Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs + +let transfer_to_itself_with_no_such_entrypoint () = + let entrypoint = "bad entrypoint" in + Context.init 1 >>=? fun (b, contract) -> + Incremental.begin_construction b >>=? fun i -> + let addr = match contract with [hd] -> hd | _ -> assert false in + Op.transaction (B b) addr addr Tez.one ~entrypoint >>=? fun transaction -> + let expect_failure = function + | Environment.Ecoproto_error (Script_tc_errors.No_such_entrypoint _ as e) + :: _ -> + Assert.test_error_encodings e ; + return () + | _ -> failwith "no such entrypoint should fail" + in + Incremental.add_operation ~expect_failure i transaction >>= fun _res -> + return () + +let tests = + [ + (* single transfer *) + Tztest.tztest "single transfer" `Quick test_block_with_a_single_transfer; + Tztest.tztest + "single transfer with fee" + `Quick + test_block_with_a_single_transfer_with_fee; + (* transfer zero tez *) + Tztest.tztest "single transfer zero tez" `Quick test_transfer_zero_tez; + Tztest.tztest + "transfer zero tez from implicit contract" + `Quick + test_transfer_zero_implicit; + Tztest.tztest + "transfer zero tez to an implicit contract with balance of src as fee" + `Quick + test_transfer_zero_implicit_with_bal_src_as_fee; + (* transfer to originated contract *) + Tztest.tztest + "transfer to originated contract paying transaction fee" + `Quick + test_transfer_to_originate_with_fee; + Tztest.tztest + "transfer zero tez to an originated contract with balance of src as fee" + `Quick + test_transfer_zero_to_originated_with_bal_src_as_fee; + (* transfer by the balance of contract *) + Tztest.tztest + "transfer the amount from source contract balance" + `Quick + test_transfer_amount_of_contract_balance; + (* transfer to itself *) + Tztest.tztest "transfers to itself" `Quick test_transfers_to_self; + (* missing operation *) + Tztest.tztest "missing transaction" `Quick test_missing_transaction; + (* transfer from/to implicit/originated contracts*) + Tztest.tztest + "transfer from an implicit to implicit contract " + `Quick + test_transfer_from_implicit_to_implicit_contract; + Tztest.tztest + "transfer from an implicit to an originated contract" + `Quick + test_transfer_from_implicit_to_originated_contract; + (* Slow tests *) + Tztest.tztest + "block with multiple transfers" + `Slow + test_block_with_multiple_transfers; + (* TODO increase the number of transaction times *) + Tztest.tztest + "block with multiple transfer paying fee" + `Slow + test_block_with_multiple_transfers_pay_fee; + Tztest.tztest + "block with multiple transfer without paying fee" + `Slow + test_block_with_multiple_transfers_with_without_fee; + (* build the chain *) + Tztest.tztest "build a chain" `Quick test_build_a_chain; + (* Erroneous *) + Tztest.tztest "empty implicit" `Quick test_empty_implicit; + Tztest.tztest + "balance too low - transfer zero" + `Quick + (test_balance_too_low Tez.zero); + Tztest.tztest "balance too low" `Quick (test_balance_too_low Tez.one); + Tztest.tztest + "balance too low (max fee)" + `Quick + (test_balance_too_low max_tez); + Tztest.tztest + "balance too low with two transfers - transfer zero" + `Quick + (test_balance_too_low_two_transfers Tez.zero); + Tztest.tztest + "balance too low with two transfers" + `Quick + (test_balance_too_low_two_transfers Tez.one); + Tztest.tztest + "transfer one tez to an implicit contract with balance of src as fee" + `Quick + test_transfer_one_to_implicit_with_bal_src_as_fee; + Tztest.tztest "invalid_counter" `Quick invalid_counter; + Tztest.tztest + "add the same operation twice" + `Quick + test_add_the_same_operation_twice; + Tztest.tztest + "invalid_counter_in_the_future" + `Quick + invalid_counter_in_the_future; + Tztest.tztest "ownership sender" `Quick test_ownership_sender; + (* Random tests *) + Tztest.tztest "random transfer" `Quick test_random_transfer; + Tztest.tztest "random multi transfer" `Quick test_random_multi_transactions; + Tztest.tztest "bad entrypoint" `Quick test_bad_entrypoint; + Tztest.tztest "bad parameter" `Quick test_bad_parameter; + Tztest.tztest + "no such entrypoint" + `Quick + transfer_to_itself_with_no_such_entrypoint; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_typechecking.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_typechecking.ml new file mode 100644 index 000000000000..0ac6aadb4e57 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_typechecking.ml @@ -0,0 +1,915 @@ +(** Testing + ------- + Component: Protocol (type-checking) + Invocation: cd src/proto_alpha/lib_protocol/test + dune exec ./main.exe -- test "^typechecking$" + Subject: Type-checking +*) + +open Protocol +open Alpha_context +open Micheline +open Error_monad_operators + +let wrap_error_lwt x = x >>= fun x -> Lwt.return @@ Environment.wrap_tzresult x + +(* Test for Script_ir_translator.unparse_script on a script declaring views. *) +let test_unparse_view () = + let dummy_contract = + "{parameter unit; storage unit; code { CAR; NIL operation; PAIR }; view \ + \"v0\" unit unit { DROP; UNIT }; view \"v1\" nat nat {CAR}}" + in + let contract_expr = Expr.from_string dummy_contract in + let storage_expr = Expr.from_string "Unit" in + let bef = Script.lazy_expr contract_expr |> Data_encoding.force_bytes in + let script = + Script.{code = lazy_expr contract_expr; storage = lazy_expr storage_expr} + in + Context.init 3 >>=? fun (b, _cs) -> + Incremental.begin_construction b >>=? fun v -> + let ctx = Incremental.alpha_ctxt v in + Script_ir_translator.parse_script + ctx + ~legacy:true + ~allow_forged_in_storage:false + script + >>=?? fun (Ex_script script, ctx) -> + Script_ir_translator.unparse_script ctx Readable script + >>=?? fun (unparse_script, _ctx) -> + let aft = Data_encoding.force_bytes unparse_script.code in + Alcotest.(check bytes) "didn't match" bef aft |> return + +let test_context () = + Context.init ~consensus_threshold:0 3 >>=? fun (b, _cs) -> + Incremental.begin_construction b >>=? fun v -> + return (Incremental.alpha_ctxt v) + +let test_context_with_nat_nat_big_map () = + Context.init 3 >>=? fun (b, contracts) -> + let source = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd contracts in + Op.origination (B b) source ~script:Op.dummy_script + >>=? fun (operation, originated) -> + Block.bake ~operation b >>=? fun b -> + Incremental.begin_construction b >>=? fun v -> + let ctxt = Incremental.alpha_ctxt v in + wrap_error_lwt @@ Big_map.fresh ~temporary:false ctxt >>=? fun (ctxt, id) -> + let nat_ty = Script_typed_ir.nat_t ~annot:None in + wrap_error_lwt @@ Lwt.return + @@ Script_ir_translator.unparse_ty ~loc:() ctxt nat_ty + >>=? fun (nat_ty_node, ctxt) -> + let nat_ty_expr = Micheline.strip_locations nat_ty_node in + let alloc = Big_map.{key_type = nat_ty_expr; value_type = nat_ty_expr} in + let init = Lazy_storage.Alloc alloc in + let diffs = + [ + Lazy_storage.make + Lazy_storage.Kind.Big_map + id + (Update {init; updates = []}); + ] + in + wrap_error_lwt + @@ Contract.update_script_storage ctxt originated nat_ty_expr (Some diffs) + >>=? fun ctxt -> return (ctxt, id) + +let read_file filename = + let ch = open_in filename in + let s = really_input_string ch (in_channel_length ch) in + close_in ch ; + s + +(** Check that the custom stack overflow exception is triggered when + it should be. *) +let test_typecheck_stack_overflow () = + test_context () >>=? fun ctxt -> + let storage = "Unit" in + let parameter = "Unit" in + let script = read_file "./contracts/big_interpreter_stack.tz" in + Contract_helpers.run_script ctxt script ~storage ~parameter () >>= function + | Ok _ -> Alcotest.fail "expected an error" + | Error lst + when List.mem + ~equal:( = ) + (Environment.Ecoproto_error + Script_tc_errors.Typechecking_too_many_recursive_calls) + lst -> + return () + | Error errs -> + Alcotest.failf "Unexpected error: %a" Error_monad.pp_print_trace errs + +(* NOTE: this test fails with an out-of-memory exception. *) +let _test_unparse_stack_overflow () = + test_context () >>=? fun ctxt -> + (* Meme *) + let enorme_et_seq n = + let rec aux n acc = aux (n - 1) @@ Micheline.Seq (0, [acc]) in + aux n (Micheline.Int (0, Z.zero)) + in + Script_ir_translator.(unparse_code ctxt Readable (enorme_et_seq 10_001)) + >>= function + | Ok _ -> Alcotest.fail "expected an error" + | Error trace -> + let trace_string = + Format.asprintf "%a" Environment.Error_monad.pp_trace trace + in + let expect_id = "michelson_v1.unparsing_stack_overflow" in + let expect_descrfiption = + "Too many recursive calls were needed for unparsing" + in + if + Astring.String.is_infix ~affix:expect_id trace_string + && Astring.String.is_infix ~affix:expect_descrfiption trace_string + then return_unit + else + Alcotest.failf + "Unexpected error (%s) at %s" + trace_string + __LOC__ + return_unit + +let location = function + | Prim (loc, _, _, _) + | Int (loc, _) + | String (loc, _) + | Bytes (loc, _) + | Seq (loc, _) -> + loc + +let test_parse_ty ctxt node expected = + let legacy = false in + let allow_lazy_storage = true in + let allow_operation = true in + let allow_contract = true in + let allow_ticket = true in + Environment.wrap_tzresult + ( Script_ir_translator.parse_ty + ctxt + ~legacy + ~allow_lazy_storage + ~allow_operation + ~allow_contract + ~allow_ticket + node + >>? fun (Script_ir_translator.Ex_ty actual, ctxt) -> + Script_ir_translator.ty_eq ctxt (location node) actual expected + >|? fun (_, ctxt) -> ctxt ) + +let var_annot = Script_ir_annot.FOR_TESTS.unsafe_var_annot_of_string + +let type_annot = Script_ir_annot.FOR_TESTS.unsafe_type_annot_of_string + +let field_annot = Script_ir_annot.FOR_TESTS.unsafe_field_annot_of_string + +let test_parse_comb_type () = + let open Script in + let open Script_typed_ir in + let nat_prim = Prim (-1, T_nat, [], []) in + let nat_prim_a = Prim (-1, T_nat, [], ["%a"]) in + let nat_prim_b = Prim (-1, T_nat, [], ["%b"]) in + let nat_prim_c = Prim (-1, T_nat, [], ["%c"]) in + let nat_ty = nat_t ~annot:None in + let pair_prim l = Prim (-1, T_pair, l, []) in + let pair_ty ty1 ty2 = + pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None + in + let pair_prim2 a b = pair_prim [a; b] in + let pair_nat_nat_prim = pair_prim2 nat_prim nat_prim in + pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> + test_context () >>=? fun ctxt -> + (* pair nat nat *) + test_parse_ty ctxt pair_nat_nat_prim pair_nat_nat_ty >>?= fun ctxt -> + (* pair (pair nat nat) nat *) + pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> + test_parse_ty + ctxt + (pair_prim2 pair_nat_nat_prim nat_prim) + pair_pair_nat_nat_nat_ty + >>?= fun ctxt -> + (* pair nat (pair nat nat) *) + pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_pair_nat_nat_ty -> + test_parse_ty + ctxt + (pair_prim2 nat_prim pair_nat_nat_prim) + pair_nat_pair_nat_nat_ty + >>?= fun ctxt -> + (* pair nat nat nat *) + pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_nat_nat_ty -> + test_parse_ty + ctxt + (pair_prim [nat_prim; nat_prim; nat_prim]) + pair_nat_nat_nat_ty + >>?= fun ctxt -> + (* pair (nat %a) nat *) + pair_t + (-1) + (nat_ty, Some (field_annot "a"), None) + (nat_ty, None, None) + ~annot:None + >>??= fun pair_nat_a_nat_ty -> + test_parse_ty ctxt (pair_prim2 nat_prim_a nat_prim) pair_nat_a_nat_ty + >>?= fun ctxt -> + (* pair nat (nat %b) *) + pair_t + (-1) + (nat_ty, None, None) + (nat_ty, Some (field_annot "b"), None) + ~annot:None + >>??= fun pair_nat_nat_b_ty -> + test_parse_ty ctxt (pair_prim2 nat_prim nat_prim_b) pair_nat_nat_b_ty + >>?= fun ctxt -> + (* pair (nat %a) (nat %b) *) + pair_t + (-1) + (nat_ty, Some (field_annot "a"), None) + (nat_ty, Some (field_annot "b"), None) + ~annot:None + >>??= fun pair_nat_a_nat_b_ty -> + test_parse_ty ctxt (pair_prim2 nat_prim_a nat_prim_b) pair_nat_a_nat_b_ty + >>?= fun ctxt -> + (* pair (nat %a) (nat %b) (nat %c) *) + pair_t + (-1) + (nat_ty, Some (field_annot "b"), None) + (nat_ty, Some (field_annot "c"), None) + ~annot:None + >>??= fun pair_nat_b_nat_c_ty -> + pair_t + (-1) + (nat_ty, Some (field_annot "a"), None) + (pair_nat_b_nat_c_ty, None, None) + ~annot:None + >>??= fun pair_nat_a_nat_b_nat_c_ty -> + test_parse_ty + ctxt + (pair_prim [nat_prim_a; nat_prim_b; nat_prim_c]) + pair_nat_a_nat_b_nat_c_ty + >>?= fun ctxt -> + (* pair (nat %a) (pair %b nat nat) *) + pair_t (-1) (nat_ty, None, None) (nat_ty, None, None) ~annot:None + >>??= fun pair_b_nat_nat_ty -> + pair_t + (-1) + (nat_ty, Some (field_annot "a"), None) + (pair_b_nat_nat_ty, Some (field_annot "b"), None) + ~annot:None + >>??= fun pair_nat_a_pair_b_nat_nat_ty -> + test_parse_ty + ctxt + (pair_prim2 nat_prim_a (Prim (-1, T_pair, [nat_prim; nat_prim], ["%b"]))) + pair_nat_a_pair_b_nat_nat_ty + >>?= fun _ -> return_unit + +let test_unparse_ty loc ctxt expected ty = + Environment.wrap_tzresult + ( Script_ir_translator.unparse_ty ~loc:() ctxt ty >>? fun (actual, ctxt) -> + if actual = expected then ok ctxt + else Alcotest.failf "Unexpected error: %s" loc ) + +let test_unparse_comb_type () = + let open Script in + let open Script_typed_ir in + let nat_prim = Prim ((), T_nat, [], []) in + let nat_prim_a = Prim ((), T_nat, [], ["%a"]) in + let nat_prim_b = Prim ((), T_nat, [], ["%b"]) in + let nat_prim_c = Prim ((), T_nat, [], ["%c"]) in + let nat_ty = nat_t ~annot:None in + let pair_prim l = Prim ((), T_pair, l, []) in + let pair_ty ty1 ty2 = + pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None + in + let pair_prim2 a b = pair_prim [a; b] in + let pair_nat_nat_prim = pair_prim2 nat_prim nat_prim in + pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> + test_context () >>=? fun ctxt -> + (* pair nat nat *) + test_unparse_ty __LOC__ ctxt pair_nat_nat_prim pair_nat_nat_ty + >>?= fun ctxt -> + (* pair (pair nat nat) nat *) + pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> + test_unparse_ty + __LOC__ + ctxt + (pair_prim2 pair_nat_nat_prim nat_prim) + pair_pair_nat_nat_nat_ty + >>?= fun ctxt -> + (* pair nat nat nat *) + pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_nat_nat_ty -> + test_unparse_ty + __LOC__ + ctxt + (pair_prim [nat_prim; nat_prim; nat_prim]) + pair_nat_nat_nat_ty + >>?= fun ctxt -> + (* pair (nat %a) nat *) + pair_t + (-1) + (nat_ty, Some (field_annot "a"), None) + (nat_ty, None, None) + ~annot:None + >>??= fun pair_nat_a_nat_ty -> + test_unparse_ty + __LOC__ + ctxt + (pair_prim2 nat_prim_a nat_prim) + pair_nat_a_nat_ty + >>?= fun ctxt -> + (* pair nat (nat %b) *) + pair_t + (-1) + (nat_ty, None, None) + (nat_ty, Some (field_annot "b"), None) + ~annot:None + >>??= fun pair_nat_nat_b_ty -> + test_unparse_ty + __LOC__ + ctxt + (pair_prim2 nat_prim nat_prim_b) + pair_nat_nat_b_ty + >>?= fun ctxt -> + (* pair (nat %a) (nat %b) *) + pair_t + (-1) + (nat_ty, Some (field_annot "a"), None) + (nat_ty, Some (field_annot "b"), None) + ~annot:None + >>??= fun pair_nat_a_nat_b_ty -> + test_unparse_ty + __LOC__ + ctxt + (pair_prim2 nat_prim_a nat_prim_b) + pair_nat_a_nat_b_ty + >>?= fun ctxt -> + (* pair (nat %a) (nat %b) (nat %c) *) + pair_t + (-1) + (nat_ty, Some (field_annot "b"), None) + (nat_ty, Some (field_annot "c"), None) + ~annot:None + >>??= fun pair_nat_b_nat_c_ty -> + pair_t + (-1) + (nat_ty, Some (field_annot "a"), None) + (pair_nat_b_nat_c_ty, None, None) + ~annot:None + >>??= fun pair_nat_a_nat_b_nat_c_ty -> + test_unparse_ty + __LOC__ + ctxt + (pair_prim [nat_prim_a; nat_prim_b; nat_prim_c]) + pair_nat_a_nat_b_nat_c_ty + >>?= fun ctxt -> + (* pair (nat %a) (pair %b nat nat) *) + pair_t (-1) (nat_ty, None, None) (nat_ty, None, None) ~annot:None + >>??= fun pair_nat_nat_ty -> + pair_t + (-1) + (nat_ty, Some (field_annot "a"), None) + (pair_nat_nat_ty, Some (field_annot "b"), None) + ~annot:None + >>??= fun pair_nat_a_pair_b_nat_nat_ty -> + test_unparse_ty + __LOC__ + ctxt + (pair_prim2 nat_prim_a (Prim ((), T_pair, [nat_prim; nat_prim], ["%b"]))) + pair_nat_a_pair_b_nat_nat_ty + >>?= fun ctxt -> + (* pair nat (pair @b nat nat) *) + pair_t + (-1) + (nat_ty, None, None) + (pair_nat_nat_ty, None, Some (var_annot "b")) + ~annot:None + >>??= fun pair_nat_pair_b_nat_nat_ty -> + test_unparse_ty + __LOC__ + ctxt + (pair_prim2 nat_prim (Prim ((), T_pair, [nat_prim; nat_prim], ["@b"]))) + pair_nat_pair_b_nat_nat_ty + >>?= fun ctxt -> + (* pair nat (pair :b nat nat) *) + pair_t + (-1) + (nat_ty, None, None) + (nat_ty, None, None) + ~annot:(Some (type_annot "b")) + >>??= fun pair_b_nat_nat_ty -> + pair_t (-1) (nat_ty, None, None) (pair_b_nat_nat_ty, None, None) ~annot:None + >>??= fun pair_nat_pair_b_nat_nat_ty -> + test_unparse_ty + __LOC__ + ctxt + (pair_prim2 nat_prim (Prim ((), T_pair, [nat_prim; nat_prim], [":b"]))) + pair_nat_pair_b_nat_nat_ty + >>?= fun _ -> return_unit + +let test_unparse_comparable_ty loc ctxt expected ty = + (* unparse_comparable_ty is not exported, the simplest way to call it is to + call parse_ty on a set type *) + let open Script_typed_ir in + Environment.wrap_tzresult + ( set_t (-1) ty ~annot:None >>? fun set_ty_ty -> + Script_ir_translator.unparse_ty ~loc:() ctxt set_ty_ty + >>? fun (actual, ctxt) -> + if actual = Prim ((), T_set, [expected], []) then ok ctxt + else Alcotest.failf "Unexpected error: %s" loc ) + +let test_unparse_comb_comparable_type () = + let open Script in + let open Script_typed_ir in + let nat_prim = Prim ((), T_nat, [], []) in + let nat_prim_a = Prim ((), T_nat, [], ["%a"]) in + let nat_prim_b = Prim ((), T_nat, [], ["%b"]) in + let nat_prim_c = Prim ((), T_nat, [], ["%c"]) in + let nat_ty = nat_key ~annot:None in + let pair_prim l = Prim ((), T_pair, l, []) in + let pair_ty ty1 ty2 = pair_key (-1) (ty1, None) (ty2, None) ~annot:None in + let pair_prim2 a b = pair_prim [a; b] in + let pair_nat_nat_prim = pair_prim2 nat_prim nat_prim in + pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> + test_context () >>=? fun ctxt -> + (* pair nat nat *) + test_unparse_comparable_ty __LOC__ ctxt pair_nat_nat_prim pair_nat_nat_ty + >>?= fun ctxt -> + (* pair (pair nat nat) nat *) + pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> + test_unparse_comparable_ty + __LOC__ + ctxt + (pair_prim2 pair_nat_nat_prim nat_prim) + pair_pair_nat_nat_nat_ty + >>?= fun ctxt -> + (* pair nat nat nat *) + pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_nat_nat_ty -> + test_unparse_comparable_ty + __LOC__ + ctxt + (pair_prim [nat_prim; nat_prim; nat_prim]) + pair_nat_nat_nat_ty + >>?= fun ctxt -> + (* pair (nat %a) nat *) + pair_key (-1) (nat_ty, Some (field_annot "a")) (nat_ty, None) ~annot:None + >>??= fun pair_nat_a_nat_ty -> + test_unparse_comparable_ty + __LOC__ + ctxt + (pair_prim2 nat_prim_a nat_prim) + pair_nat_a_nat_ty + >>?= fun ctxt -> + (* pair nat (nat %b) *) + pair_key (-1) (nat_ty, None) (nat_ty, Some (field_annot "b")) ~annot:None + >>??= fun pair_nat_nat_b_ty -> + test_unparse_comparable_ty + __LOC__ + ctxt + (pair_prim2 nat_prim nat_prim_b) + pair_nat_nat_b_ty + >>?= fun ctxt -> + (* pair (nat %a) (nat %b) *) + pair_key + (-1) + (nat_ty, Some (field_annot "a")) + (nat_ty, Some (field_annot "b")) + ~annot:None + >>??= fun pair_nat_a_nat_b_ty -> + test_unparse_comparable_ty + __LOC__ + ctxt + (pair_prim2 nat_prim_a nat_prim_b) + pair_nat_a_nat_b_ty + >>?= fun ctxt -> + (* pair (nat %a) (nat %b) (nat %c) *) + pair_key + (-1) + (nat_ty, Some (field_annot "b")) + (nat_ty, Some (field_annot "c")) + ~annot:None + >>??= fun pair_nat_b_nat_c_ty -> + pair_key + (-1) + (nat_ty, Some (field_annot "a")) + (pair_nat_b_nat_c_ty, None) + ~annot:None + >>??= fun pair_nat_a_nat_b_nat_c_ty -> + test_unparse_comparable_ty + __LOC__ + ctxt + (pair_prim [nat_prim_a; nat_prim_b; nat_prim_c]) + pair_nat_a_nat_b_nat_c_ty + >>?= fun ctxt -> + (* pair (nat %a) (pair %b nat nat) *) + pair_key + (-1) + (nat_ty, Some (field_annot "a")) + (pair_nat_nat_ty, Some (field_annot "b")) + ~annot:None + >>??= fun pair_nat_a_pair_b_nat_nat_ty -> + test_unparse_comparable_ty + __LOC__ + ctxt + (pair_prim2 nat_prim_a (Prim ((), T_pair, [nat_prim; nat_prim], ["%b"]))) + pair_nat_a_pair_b_nat_nat_ty + >>?= fun ctxt -> + (* pair nat (pair :b nat nat) *) + pair_key (-1) (nat_ty, None) (nat_ty, None) ~annot:(Some (type_annot "b")) + >>??= fun pair_b_nat_nat_ty -> + pair_key (-1) (nat_ty, None) (pair_b_nat_nat_ty, None) ~annot:None + >>??= fun pair_nat_pair_b_nat_nat_ty -> + test_unparse_comparable_ty + __LOC__ + ctxt + (pair_prim2 nat_prim (Prim ((), T_pair, [nat_prim; nat_prim], [":b"]))) + pair_nat_pair_b_nat_nat_ty + >>?= fun _ -> return_unit + +let test_parse_data ?(equal = Stdlib.( = )) loc ctxt ty node expected = + let legacy = false in + let allow_forged = true in + wrap_error_lwt + ( Script_ir_translator.parse_data ctxt ~legacy ~allow_forged ty node + >>=? fun (actual, ctxt) -> + if equal actual expected then return ctxt + else Alcotest.failf "Unexpected error: %s" loc ) + +let test_parse_data_fails loc ctxt ty node = + let legacy = false in + let allow_forged = false in + wrap_error_lwt + (Script_ir_translator.parse_data ctxt ~legacy ~allow_forged ty node + >>= function + | Ok _ -> Alcotest.failf "Unexpected typechecking success: %s" loc + | Error trace -> + let trace_string = + Format.asprintf "%a" Environment.Error_monad.pp_trace trace + in + let expect_id = "michelson_v1.invalid_constant" in + let expect_descrfiption = + "A data expression was invalid for its expected type." + in + if + Astring.String.is_infix ~affix:expect_id trace_string + && Astring.String.is_infix ~affix:expect_descrfiption trace_string + then return_unit + else + Alcotest.failf + "Unexpected error (%s) at %s" + trace_string + __LOC__ + return_unit) + +let test_parse_comb_data () = + let open Script in + let open Script_typed_ir in + let z = Script_int.zero_n in + let z_prim = Micheline.Int (-1, Z.zero) in + let nat_ty = nat_t ~annot:None in + let pair_prim l = Prim (-1, D_Pair, l, []) in + let pair_ty ty1 ty2 = + pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None + in + pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> + let pair_prim2 a b = pair_prim [a; b] in + let pair_z_z_prim = pair_prim2 z_prim z_prim in + list_t (-1) nat_ty ~annot:None >>??= fun list_nat_ty -> + big_map_t (-1) (nat_key ~annot:None) nat_ty ~annot:None + >>??= fun big_map_nat_nat_ty -> + test_context_with_nat_nat_big_map () >>=? fun (ctxt, big_map_id) -> + (* Pair 0 0 *) + test_parse_data __LOC__ ctxt pair_nat_nat_ty pair_z_z_prim (z, z) + >>=? fun ctxt -> + (* {0; 0} *) + test_parse_data + __LOC__ + ctxt + pair_nat_nat_ty + (Micheline.Seq (-1, [z_prim; z_prim])) + (z, z) + >>=? fun ctxt -> + (* Pair (Pair 0 0) 0 *) + pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> + test_parse_data + __LOC__ + ctxt + pair_pair_nat_nat_nat_ty + (pair_prim2 pair_z_z_prim z_prim) + ((z, z), z) + >>=? fun ctxt -> + (* Pair 0 (Pair 0 0) *) + pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_pair_nat_nat_ty -> + test_parse_data + __LOC__ + ctxt + pair_nat_pair_nat_nat_ty + (pair_prim2 z_prim pair_z_z_prim) + (z, (z, z)) + >>=? fun ctxt -> + (* Pair 0 0 0 *) + test_parse_data + __LOC__ + ctxt + pair_nat_pair_nat_nat_ty + (pair_prim [z_prim; z_prim; z_prim]) + (z, (z, z)) + >>=? fun ctxt -> + (* {0; 0; 0} *) + test_parse_data + __LOC__ + ctxt + pair_nat_pair_nat_nat_ty + (Micheline.Seq (-1, [z_prim; z_prim; z_prim])) + (z, (z, z)) + >>=? fun ctxt -> + (* Should fail: {0} against pair nat (list nat) *) + pair_ty nat_ty list_nat_ty >>??= fun pair_nat_list_nat_ty -> + test_parse_data_fails + __LOC__ + ctxt + pair_nat_list_nat_ty + (Micheline.Seq (-1, [z_prim])) + >>=? fun () -> + (* Should fail: {0; 0; 0} against pair nat (list nat) *) + test_parse_data_fails + __LOC__ + ctxt + pair_nat_list_nat_ty + (Micheline.Seq (-1, [z_prim; z_prim; z_prim])) + >>=? fun () -> + (* check Pair 0 (Pair 0 {}) against pair nat (big_map nat nat) + so that the following test fails for the good reason and not because + the big map doesn't exist + *) + let id_z = Big_map.Id.unparse_to_z big_map_id in + let id_prim = Int (-1, id_z) in + let expected_big_map = + let open Script_typed_ir in + let diff = {map = Big_map_overlay.empty; size = 0} in + let nat_key_ty = nat_key ~annot:None in + {id = Some big_map_id; diff; key_type = nat_key_ty; value_type = nat_ty} + in + let equal (nat1, big_map1) (nat2, big_map2) = + (* Custom equal needed because big maps contain boxed maps containing functional values *) + nat1 = nat2 && big_map1.id = big_map2.id + && big_map1.key_type = big_map2.key_type + && big_map1.value_type = big_map2.value_type + && big_map1.diff.size = big_map2.diff.size + && Big_map_overlay.bindings big_map1.diff.map + = Big_map_overlay.bindings big_map2.diff.map + in + pair_ty nat_ty big_map_nat_nat_ty >>??= fun pair_nat_big_map_nat_nat_ty -> + test_parse_data + ~equal + __LOC__ + ctxt + pair_nat_big_map_nat_nat_ty + (pair_prim2 z_prim (pair_prim2 id_prim (Seq (-1, [])))) + (Script_int.zero_n, expected_big_map) + >>=? fun ctxt -> + (* Should fail: Pair 0 0 {} against pair nat (big_map nat nat) *) + test_parse_data_fails + __LOC__ + ctxt + pair_nat_big_map_nat_nat_ty + (pair_prim [z_prim; id_prim; Seq (-1, [])]) + +let test_parse_address () = + let open Script_typed_ir in + test_context_with_nat_nat_big_map () >>=? fun (ctxt, _big_map_id) -> + (* KT1% (empty entrypoint) *) + wrap_error_lwt + (Lwt.return (Contract.of_b58check "KT1FAKEFAKEFAKEFAKEFAKEFAKEFAKGGSE2x")) + >>=? fun kt1fake -> + test_parse_data + __LOC__ + ctxt + (address_t ~annot:None) + (String (-1, "KT1FAKEFAKEFAKEFAKEFAKEFAKEFAKGGSE2x%")) + (kt1fake, "default") + >>=? fun ctxt -> + (* tz1% (empty entrypoint) *) + wrap_error_lwt + (Lwt.return (Contract.of_b58check "tz1fakefakefakefakefakefakefakcphLA5")) + >>=? fun tz1fake -> + test_parse_data + __LOC__ + ctxt + (address_t ~annot:None) + (String (-1, "tz1fakefakefakefakefakefakefakcphLA5%")) + (tz1fake, "default") + >|=? fun _ctxt -> () + +let test_unparse_data loc ctxt ty x ~expected_readable ~expected_optimized = + wrap_error_lwt + ( Script_ir_translator.unparse_data ctxt Script_ir_translator.Readable ty x + >>=? fun (actual_readable, ctxt) -> + (if actual_readable = expected_readable then return ctxt + else Alcotest.failf "Error in readable unparsing: %s" loc) + >>=? fun ctxt -> + Script_ir_translator.unparse_data ctxt Script_ir_translator.Optimized ty x + >>=? fun (actual_optimized, ctxt) -> + if actual_optimized = expected_optimized then return ctxt + else Alcotest.failf "Error in optimized unparsing: %s" loc ) + +let test_unparse_comb_data () = + let open Script in + let open Script_typed_ir in + let z = Script_int.zero_n in + let z_prim = Micheline.Int (-1, Z.zero) in + let nat_ty = nat_t ~annot:None in + let pair_prim l = Prim (-1, D_Pair, l, []) in + let pair_ty ty1 ty2 = + pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None + in + pair_ty nat_ty nat_ty >>??= fun pair_nat_nat_ty -> + let pair_prim2 a b = pair_prim [a; b] in + let pair_z_z_prim = pair_prim2 z_prim z_prim in + test_context () >>=? fun ctxt -> + (* Pair 0 0 *) + test_unparse_data + __LOC__ + ctxt + pair_nat_nat_ty + (z, z) + ~expected_readable:pair_z_z_prim + ~expected_optimized:pair_z_z_prim + >>=? fun ctxt -> + (* Pair (Pair 0 0) 0 *) + pair_ty pair_nat_nat_ty nat_ty >>??= fun pair_pair_nat_nat_nat_ty -> + test_unparse_data + __LOC__ + ctxt + pair_pair_nat_nat_nat_ty + ((z, z), z) + ~expected_readable:(pair_prim2 pair_z_z_prim z_prim) + ~expected_optimized:(pair_prim2 pair_z_z_prim z_prim) + >>=? fun ctxt -> + (* Readable: Pair 0 0 0; Optimized: Pair 0 (Pair 0 0) *) + pair_ty nat_ty pair_nat_nat_ty >>??= fun pair_nat_pair_nat_nat_ty -> + test_unparse_data + __LOC__ + ctxt + pair_nat_pair_nat_nat_ty + (z, (z, z)) + ~expected_readable:(pair_prim [z_prim; z_prim; z_prim]) + ~expected_optimized:(pair_prim2 z_prim pair_z_z_prim) + >>=? fun ctxt -> + (* Readable: Pair 0 0 0 0; Optimized: {0; 0; 0; 0} *) + pair_ty nat_ty pair_nat_pair_nat_nat_ty + >>??= fun pair_nat_pair_nat_pair_nat_nat_ty -> + test_unparse_data + __LOC__ + ctxt + pair_nat_pair_nat_pair_nat_nat_ty + (z, (z, (z, z))) + ~expected_readable:(pair_prim [z_prim; z_prim; z_prim; z_prim]) + ~expected_optimized:(Micheline.Seq (-1, [z_prim; z_prim; z_prim; z_prim])) + >>=? fun _ -> return_unit + +(* Generate all the possible syntaxes for pairs *) +let gen_pairs left right = + [Prim ((), Script.D_Pair, [left; right], []); Seq ((), [left; right])] + +(* Generate all the possible syntaxes for combs *) +let rec gen_combs leaf arity = + assert (arity >= 2) ; + if arity = 2 then gen_pairs leaf leaf + else + gen_combs leaf (arity - 1) + |> List.map (fun smaller -> + (match smaller with + | Prim (loc, Script.D_Pair, vs, []) -> + Prim (loc, Script.D_Pair, leaf :: vs, []) + | Seq (loc, vs) -> Seq (loc, leaf :: vs) + | _ -> assert false) + :: gen_pairs leaf smaller) + |> List.flatten + +(* Checks the optimality of the Optimized Micheline representation for combs *) +let test_optimal_comb () = + let open Script_typed_ir in + let leaf_ty = nat_t ~annot:None in + let leaf_mich = Int ((), Z.zero) in + let leaf_v = Script_int.zero_n in + let size_of_micheline mich = + let canonical = Micheline.strip_locations mich in + ( canonical, + Bytes.length + @@ Data_encoding.Binary.to_bytes_exn Script.expr_encoding canonical ) + in + let check_optimal_comb loc ctxt ty v arity = + wrap_error_lwt + ( Script_ir_translator.unparse_data + ctxt + Script_ir_translator.Optimized + ty + v + >>=? fun (unparsed, ctxt) -> + let (unparsed_canonical, unparsed_size) = size_of_micheline unparsed in + List.iter_es (fun other_repr -> + let (other_repr_canonical, other_repr_size) = + size_of_micheline other_repr + in + if other_repr_size < unparsed_size then + Alcotest.failf + "At %s, for comb of arity %d, representation %a (size %d \ + bytes) is shorter than representation %a (size %d bytes) \ + returned by unparse_data in Optimized mode" + loc + arity + Michelson_v1_printer.print_expr + other_repr_canonical + other_repr_size + Michelson_v1_printer.print_expr + unparsed_canonical + unparsed_size + else return_unit) + @@ gen_combs leaf_mich arity + >>=? fun () -> return ctxt ) + in + let pair_ty ty1 ty2 = + pair_t (-1) (ty1, None, None) (ty2, None, None) ~annot:None + in + test_context () >>=? fun ctxt -> + pair_ty leaf_ty leaf_ty >>??= fun comb2_ty -> + let comb2_v = (leaf_v, leaf_v) in + check_optimal_comb __LOC__ ctxt comb2_ty comb2_v 2 >>=? fun ctxt -> + pair_ty leaf_ty comb2_ty >>??= fun comb3_ty -> + let comb3_v = (leaf_v, comb2_v) in + check_optimal_comb __LOC__ ctxt comb3_ty comb3_v 3 >>=? fun ctxt -> + pair_ty leaf_ty comb3_ty >>??= fun comb4_ty -> + let comb4_v = (leaf_v, comb3_v) in + check_optimal_comb __LOC__ ctxt comb4_ty comb4_v 4 >>=? fun ctxt -> + pair_ty leaf_ty comb4_ty >>??= fun comb5_ty -> + let comb5_v = (leaf_v, comb4_v) in + check_optimal_comb __LOC__ ctxt comb5_ty comb5_v 5 >>=? fun _ctxt -> + return_unit + +(* Check that UNPACK on contract is forbidden. + See https://gitlab.com/tezos/tezos/-/issues/301 for the motivation + behind this restriction. + *) +let test_contract_not_packable () = + let contract_unit = + Prim (0, Script.T_contract, [Prim (0, T_unit, [], [])], []) + in + test_context () >>=? fun ctxt -> + (* Test that [contract_unit] is parsable *) + (match Script_ir_translator.parse_any_ty ctxt ~legacy:false contract_unit with + | Ok _ -> return_unit + | Error _ -> Alcotest.failf "Could not parse (contract unit)") + >>=? fun () -> + (* Test that [contract_unit] is not packable *) + (match + Script_ir_translator.parse_packable_ty ctxt ~legacy:false contract_unit + with + | Ok _ -> + Alcotest.failf + "(contract unit) should not be packable, see \ + https://gitlab.com/tezos/tezos/-/issues/301" + | Error _ -> return_unit) + >>=? fun () -> + (* Test that elaboration of the [UNPACK unit] instruction succeeds *) + (Script_ir_translator.parse_instr + Lambda + ctxt + ~legacy:false + (Prim (0, I_UNPACK, [Prim (0, T_unit, [], [])], [])) + (Item_t (Script_typed_ir.bytes_t ~annot:None, Bot_t, None)) + >>= function + | Ok _ -> return_unit + | Error _ -> Alcotest.failf "Could not parse UNPACK unit") + >>=? fun () -> + (* Test that elaboration of the [UNPACK (contract unit)] instruction fails *) + Script_ir_translator.parse_instr + Lambda + ctxt + ~legacy:false + (Prim (0, I_UNPACK, [contract_unit], [])) + (Item_t (Script_typed_ir.bytes_t ~annot:None, Bot_t, None)) + >>= function + | Ok _ -> + Alcotest.failf + "UNPACK (contract unit) should not be allowed, see \ + https://gitlab.com/tezos/tezos/-/issues/301" + | Error _ -> return_unit + +let tests = + [ + Tztest.tztest "test unparse view" `Quick test_unparse_view; + Tztest.tztest + "test typecheck stack overflow error" + `Quick + test_typecheck_stack_overflow; + Tztest.tztest "test comb type parsing" `Quick test_parse_comb_type; + Tztest.tztest "test comb type unparsing" `Quick test_unparse_comb_type; + Tztest.tztest + "test comb comparable type unparsing" + `Quick + test_unparse_comb_comparable_type; + Tztest.tztest "test comb data parsing" `Quick test_parse_comb_data; + Tztest.tztest "test comb data unparsing" `Quick test_unparse_comb_data; + Tztest.tztest "test optimal comb data unparsing" `Quick test_optimal_comb; + Tztest.tztest "test parse address" `Quick test_parse_address; + Tztest.tztest + "test unpackability of the contract type" + `Quick + test_contract_not_packable; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/test_voting.ml b/src/proto_012_PsiThaCa/lib_protocol/test/test_voting.ml new file mode 100644 index 000000000000..10ae3ba37c41 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/test_voting.ml @@ -0,0 +1,1167 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Protocol (voting) + Invocation: dune exec src/proto_alpha/lib_protocol/test/main.exe -- test "^voting$" + Subject: On the voting process. + +*) + +(* Note that some of these tests assume (more or less) that the + accounts remain active during a voting period, which roughly + translates to the following condition being assumed to hold: + `blocks_per_voting_period <= preserved_cycles * blocks_per_cycle.` + *) + +open Protocol +open Alpha_context + +(* missing stuff in Vote *) +let ballots_zero = Vote.{yay = 0l; nay = 0l; pass = 0l} + +let ballots_equal b1 b2 = + Vote.(b1.yay = b2.yay && b1.nay = b2.nay && b1.pass = b2.pass) + +let ballots_pp ppf v = + Vote.( + Format.fprintf ppf "{ yay = %ld ; nay = %ld ; pass = %ld" v.yay v.nay v.pass) + +(* constants and ratios used in voting: + percent_mul denotes the percent multiplier + initial_participation is 7000 that is, 7/10 * percent_mul + the participation EMA ratio pr_ema_weight / den = 7 / 10 + the participation ratio pr_num / den = 2 / 10 + note: we use the same denominator for both participation EMA and participation rate. + supermajority rate is s_num / s_den = 8 / 10 *) +let percent_mul = 100_00 + +let den = 10 + +let initial_participation_num = 7 + +let initial_participation = initial_participation_num * percent_mul / den + +let pr_ema_weight = 8 + +let pr_num = den - pr_ema_weight + +let s_num = 8 + +let s_den = 10 + +let qr_min_num = 2 + +let qr_max_num = 7 + +let expected_qr_num participation_ema = + let participation_ema = Int32.to_int participation_ema in + let participation_ema = participation_ema * den / percent_mul in + Float.( + of_int qr_min_num + +. of_int participation_ema + *. (of_int qr_max_num -. of_int qr_min_num) + /. of_int den) + +(* Protocol_hash.zero is "PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i" *) +let protos = + Array.map + (fun s -> Protocol_hash.of_b58check_exn s) + [| + "ProtoALphaALphaALphaALphaALphaALphaALpha61322gcLUGH"; + "ProtoALphaALphaALphaALphaALphaALphaALphabc2a7ebx6WB"; + "ProtoALphaALphaALphaALphaALphaALphaALpha84efbeiF6cm"; + "ProtoALphaALphaALphaALphaALphaALphaALpha91249Z65tWS"; + "ProtoALphaALphaALphaALphaALphaALphaALpha537f5h25LnN"; + "ProtoALphaALphaALphaALphaALphaALphaALpha5c8fefgDYkr"; + "ProtoALphaALphaALphaALphaALphaALphaALpha3f31feSSarC"; + "ProtoALphaALphaALphaALphaALphaALphaALphabe31ahnkxSC"; + "ProtoALphaALphaALphaALphaALphaALphaALphabab3bgRb7zQ"; + "ProtoALphaALphaALphaALphaALphaALphaALphaf8d39cctbpk"; + "ProtoALphaALphaALphaALphaALphaALphaALpha3b981byuYxD"; + "ProtoALphaALphaALphaALphaALphaALphaALphaa116bccYowi"; + "ProtoALphaALphaALphaALphaALphaALphaALphacce68eHqboj"; + "ProtoALphaALphaALphaALphaALphaALphaALpha225c7YrWwR7"; + "ProtoALphaALphaALphaALphaALphaALphaALpha58743cJL6FG"; + "ProtoALphaALphaALphaALphaALphaALphaALphac91bcdvmJFR"; + "ProtoALphaALphaALphaALphaALphaALphaALpha1faaadhV7oW"; + "ProtoALphaALphaALphaALphaALphaALphaALpha98232gD94QJ"; + "ProtoALphaALphaALphaALphaALphaALphaALpha9d1d8cijvAh"; + "ProtoALphaALphaALphaALphaALphaALphaALphaeec52dKF6Gx"; + "ProtoALphaALphaALphaALphaALphaALphaALpha841f2cQqajX"; + |] + +(** helper functions *) + +let assert_period_kind expected_kind kind loc = + if Stdlib.(expected_kind = kind) then return_unit + else + Alcotest.failf + "%s - Unexpected voting period kind - expected %a, got %a" + loc + Voting_period.pp_kind + expected_kind + Voting_period.pp_kind + kind + +let assert_period_index expected_index index loc = + if expected_index = index then return_unit + else + Alcotest.failf + "%s - Unexpected voting period index - expected %ld, got %ld" + loc + expected_index + index + +let assert_period_position expected_position position loc = + if position = expected_position then return_unit + else + Alcotest.failf + "%s - Unexpected voting period position blocks - expected %ld, got %ld" + loc + expected_position + position + +let assert_period_remaining expected_remaining remaining loc = + if remaining = expected_remaining then return_unit + else + Alcotest.failf + "%s - Unexpected voting period remaining blocks - expected %ld, got %ld" + loc + expected_remaining + remaining + +let assert_period ?expected_kind ?expected_index ?expected_position + ?expected_remaining b loc = + Context.Vote.get_current_period (B b) + >>=? fun {voting_period; position; remaining} -> + (if Option.is_some expected_kind then + assert_period_kind + (WithExceptions.Option.get ~loc:__LOC__ expected_kind) + voting_period.kind + loc + else return_unit) + >>=? fun () -> + (if Option.is_some expected_index then + assert_period_index + (WithExceptions.Option.get ~loc:__LOC__ expected_index) + voting_period.index + loc + else return_unit) + >>=? fun () -> + (if Option.is_some expected_position then + assert_period_position + (WithExceptions.Option.get ~loc:__LOC__ expected_position) + position + loc + else return_unit) + >>=? fun () -> + if Option.is_some expected_remaining then + assert_period_remaining + (WithExceptions.Option.get ~loc:__LOC__ expected_remaining) + remaining + loc + else return_unit + +let mk_contracts_from_pkh pkh_list = + List.map Contract.implicit_contract pkh_list + +(* get the list of delegates and the list of their rolls from listings *) +let get_delegates_and_rolls_from_listings b = + Context.Vote.get_listings (B b) >|=? fun l -> + (mk_contracts_from_pkh (List.map fst l), List.map snd l) + +(* compute the rolls of each delegate *) +let get_rolls b delegates loc = + Context.Vote.get_listings (B b) >>=? fun l -> + List.map_es + (fun delegate -> + Context.Contract.pkh delegate >>=? fun pkh -> + match List.find_opt (fun (del, _) -> del = pkh) l with + | None -> failwith "%s - Missing delegate" loc + | Some (_, rolls) -> return rolls) + delegates + +(* Checks that the listings are populated *) +let assert_listings_not_empty b ~loc = + Context.Vote.get_listings (B b) >>=? function + | [] -> failwith "Unexpected empty listings (%s)" loc + | _ -> return_unit + +let bake_until_first_block_of_next_period b = + Context.Vote.get_current_period (B b) >>=? fun {remaining; _} -> + Block.bake_n Int32.(add remaining one |> to_int) b + +(** A normal and successful vote sequence. *) +let test_successful_vote num_delegates () = + let open Alpha_context in + let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in + Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates + >>=? fun (b, _) -> + (* no ballots in proposal period *) + Context.Vote.get_ballots (B b) >>=? fun v -> + Assert.equal + ~loc:__LOC__ + ballots_equal + "Unexpected ballots" + ballots_pp + v + ballots_zero + >>=? fun () -> + (* no ballots in proposal period *) + (Context.Vote.get_ballot_list (B b) >>=? function + | [] -> return_unit + | _ -> failwith "%s - Unexpected ballot list" __LOC__) + >>=? fun () -> + (* Last baked block is first block of period Proposal *) + assert_period + ~expected_kind:Proposal + ~expected_index:0l + ~expected_position:0l + b + __LOC__ + >>=? fun () -> + assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + (* participation EMA starts at initial_participation *) + Context.Vote.get_participation_ema b >>=? fun v -> + Assert.equal_int ~loc:__LOC__ initial_participation (Int32.to_int v) + >>=? fun () -> + (* listings must be populated in proposal period *) + assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + (* beginning of proposal, denoted by _p1; + take a snapshot of the active delegates and their rolls from listings *) + get_delegates_and_rolls_from_listings b >>=? fun (delegates_p1, rolls_p1) -> + (* no proposals at the beginning of proposal period *) + Context.Vote.get_proposals (B b) >>=? fun ps -> + (if Environment.Protocol_hash.Map.is_empty ps then return_unit + else failwith "%s - Unexpected proposals" __LOC__) + >>=? fun () -> + (* no current proposal during proposal period *) + (Context.Vote.get_current_proposal (B b) >>=? function + | None -> return_unit + | Some _ -> failwith "%s - Unexpected proposal" __LOC__) + >>=? fun () -> + let del1 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates_p1 0 + in + let del2 = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates_p1 1 + in + let props = + List.map (fun i -> protos.(i)) (2 -- Constants.max_proposals_per_delegate) + in + Op.proposals (B b) del1 (Protocol_hash.zero :: props) >>=? fun ops1 -> + Op.proposals (B b) del2 [Protocol_hash.zero] >>=? fun ops2 -> + Block.bake ~operations:[ops1; ops2] b >>=? fun b -> + (* proposals are now populated *) + Context.Vote.get_proposals (B b) >>=? fun ps -> + (* correctly count the double proposal for zero *) + (let weight = + Int32.add + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth rolls_p1 0) + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth rolls_p1 1) + in + match Environment.Protocol_hash.(Map.find zero ps) with + | Some v -> + if v = weight then return_unit + else failwith "%s - Wrong count %ld is not %ld" __LOC__ v weight + | None -> failwith "%s - Missing proposal" __LOC__) + >>=? fun () -> + (* proposing more than maximum_proposals fails *) + Op.proposals (B b) del1 (Protocol_hash.zero :: props) >>=? fun ops -> + Block.bake ~operations:[ops] b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Amendment.Too_many_proposals -> true + | _ -> false) + >>=? fun () -> + (* proposing less than one proposal fails *) + Op.proposals (B b) del1 [] >>=? fun ops -> + Block.bake ~operations:[ops] b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Amendment.Empty_proposal -> true + | _ -> false) + >>=? fun () -> + (* first block of exploration period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* next block is first block of exploration *) + assert_period ~expected_kind:Exploration ~expected_index:1l b __LOC__ + >>=? fun () -> + assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + (* listings must be populated in proposal period before moving to exploration period *) + assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + (* beginning of exploration period, denoted by _p2; + take a snapshot of the active delegates and their rolls from listings *) + get_delegates_and_rolls_from_listings b >>=? fun (delegates_p2, rolls_p2) -> + (* no proposals during exploration period *) + Context.Vote.get_proposals (B b) >>=? fun ps -> + (if Environment.Protocol_hash.Map.is_empty ps then return_unit + else failwith "%s - Unexpected proposals" __LOC__) + >>=? fun () -> + (* current proposal must be set during exploration period *) + (Context.Vote.get_current_proposal (B b) >>=? function + | Some v -> + if Protocol_hash.(equal zero v) then return_unit + else failwith "%s - Wrong proposal" __LOC__ + | None -> failwith "%s - Missing proposal" __LOC__) + >>=? fun () -> + (* unanimous vote: all delegates --active when p2 started-- vote *) + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + delegates_p2 + >>=? fun operations -> + Block.bake ~operations b >>=? fun b -> + Op.ballot (B b) del1 Protocol_hash.zero Vote.Nay >>=? fun op -> + Block.bake ~operations:[op] b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res (function + | Amendment.Unauthorized_ballot -> true + | _ -> false) + >>=? fun () -> + (* Allocate votes from weight (rolls) of active delegates *) + List.fold_left (fun acc v -> Int32.(add v acc)) 0l rolls_p2 + |> fun rolls_sum -> + (* # of Yay rolls in ballots matches votes of the delegates *) + Context.Vote.get_ballots (B b) >>=? fun v -> + Assert.equal + ~loc:__LOC__ + ballots_equal + "Unexpected ballots" + ballots_pp + v + Vote.{yay = rolls_sum; nay = 0l; pass = 0l} + >>=? fun () -> + (* One Yay ballot per delegate *) + (Context.Vote.get_ballot_list (B b) >>=? function + | [] -> failwith "%s - Unexpected empty ballot list" __LOC__ + | l -> + List.iter_es + (fun delegate -> + Context.Contract.pkh delegate >>=? fun pkh -> + match List.find_opt (fun (del, _) -> del = pkh) l with + | None -> failwith "%s - Missing delegate" __LOC__ + | Some (_, Vote.Yay) -> return_unit + | Some _ -> failwith "%s - Wrong ballot" __LOC__) + delegates_p2) + >>=? fun () -> + (* skip to cooldown period *) + bake_until_first_block_of_next_period b >>=? fun b -> + assert_period ~expected_index:2l ~expected_kind:Cooldown b __LOC__ + >>=? fun () -> + (* no ballots in cooldown period *) + Context.Vote.get_ballots (B b) >>=? fun v -> + Assert.equal + ~loc:__LOC__ + ballots_equal + "Unexpected ballots" + ballots_pp + v + ballots_zero + >>=? fun () -> + (* listings must be populated in cooldown period before moving to promotion_vote period *) + assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + (* skip to promotion period *) + bake_until_first_block_of_next_period b >>=? fun b -> + assert_period ~expected_kind:Promotion ~expected_index:3l b __LOC__ + >>=? fun () -> + assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + (* period 3 *) + (* listings must be populated in promotion period *) + assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + (* beginning of promotion period, denoted by _p4; + take a snapshot of the active delegates and their rolls from listings *) + get_delegates_and_rolls_from_listings b >>=? fun (delegates_p4, rolls_p4) -> + (* no proposals during promotion period *) + Context.Vote.get_proposals (B b) >>=? fun ps -> + (if Environment.Protocol_hash.Map.is_empty ps then return_unit + else failwith "%s - Unexpected proposals" __LOC__) + >>=? fun () -> + (* current proposal must be set during promotion period *) + (Context.Vote.get_current_proposal (B b) >>=? function + | Some v -> + if Protocol_hash.(equal zero v) then return_unit + else failwith "%s - Wrong proposal" __LOC__ + | None -> failwith "%s - Missing proposal" __LOC__) + >>=? fun () -> + (* unanimous vote: all delegates --active when p4 started-- vote *) + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + delegates_p4 + >>=? fun operations -> + Block.bake ~operations b >>=? fun b -> + List.fold_left (fun acc v -> Int32.(add v acc)) 0l rolls_p4 + |> fun rolls_sum -> + (* # of Yays in ballots matches rolls of the delegate *) + Context.Vote.get_ballots (B b) >>=? fun v -> + Assert.equal + ~loc:__LOC__ + ballots_equal + "Unexpected ballots" + ballots_pp + v + Vote.{yay = rolls_sum; nay = 0l; pass = 0l} + >>=? fun () -> + (* One Yay ballot per delegate *) + (Context.Vote.get_ballot_list (B b) >>=? function + | [] -> failwith "%s - Unexpected empty ballot list" __LOC__ + | l -> + List.iter_es + (fun delegate -> + Context.Contract.pkh delegate >>=? fun pkh -> + match List.find_opt (fun (del, _) -> del = pkh) l with + | None -> failwith "%s - Missing delegate" __LOC__ + | Some (_, Vote.Yay) -> return_unit + | Some _ -> failwith "%s - Wrong ballot" __LOC__) + delegates_p4) + >>=? fun () -> + (* skip to end of promotion period and activation*) + bake_until_first_block_of_next_period b >>=? fun b -> + assert_period ~expected_kind:Adoption ~expected_index:4l b __LOC__ + >>=? fun () -> + (* skip to end of Adoption period and bake 1 more to activate *) + bake_until_first_block_of_next_period b >>=? fun b -> + assert_period ~expected_kind:Proposal ~expected_index:5l b __LOC__ + >>=? fun () -> + assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> + (* zero is the new protocol (before the vote this value is unset) *) + Context.Vote.get_protocol b >>= fun p -> + Assert.equal + ~loc:__LOC__ + Protocol_hash.equal + "Unexpected proposal" + Protocol_hash.pp + p + Protocol_hash.zero + >>=? fun () -> return_unit + +(* given a list of active delegates, + return the first k active delegates with which one can have quorum, that is: + their roll sum divided by the total roll sum is bigger than pr_ema_weight/den *) +let get_smallest_prefix_voters_for_quorum active_delegates active_rolls + participation_ema = + let expected_quorum = expected_qr_num participation_ema in + List.fold_left (fun acc v -> Int32.(add v acc)) 0l active_rolls + |> fun active_rolls_sum -> + let rec loop delegates rolls sum selected = + match (delegates, rolls) with + | ([], []) -> selected + | (del :: delegates, del_rolls :: rolls) -> + if + den * sum + < Float.to_int (expected_quorum *. Int32.to_float active_rolls_sum) + then + loop delegates rolls (sum + Int32.to_int del_rolls) (del :: selected) + else selected + | (_, _) -> [] + in + loop active_delegates active_rolls 0 [] + +let get_expected_participation_ema rolls voter_rolls old_participation_ema = + (* formula to compute the updated participation_ema *) + let get_updated_participation_ema old_participation_ema participation = + ((pr_ema_weight * Int32.to_int old_participation_ema) + + (pr_num * participation)) + / den + in + List.fold_left (fun acc v -> Int32.(add v acc)) 0l rolls |> fun rolls_sum -> + List.fold_left (fun acc v -> Int32.(add v acc)) 0l voter_rolls + |> fun voter_rolls_sum -> + let participation = + Int32.to_int voter_rolls_sum * percent_mul / Int32.to_int rolls_sum + in + get_updated_participation_ema old_participation_ema participation + +(** If not enough quorum + -- get_updated_participation_ema < pr_ema_weight/den -- + in exploration, go back to proposal period. *) +let test_not_enough_quorum_in_exploration num_delegates () = + let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in + Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates + >>=? fun (b, delegates) -> + (* proposal period *) + let open Alpha_context in + assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + let proposer = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 + in + Op.proposals (B b) proposer [Protocol_hash.zero] >>=? fun ops -> + Block.bake ~operations:[ops] b >>=? fun b -> + (* skip to exploration period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* we moved to an exploration period with one proposal *) + assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> + Context.Vote.get_participation_ema b >>=? fun initial_participation_ema -> + (* beginning of exploration period, denoted by _p2; + take a snapshot of the active delegates and their rolls from listings *) + get_delegates_and_rolls_from_listings b >>=? fun (delegates_p2, rolls_p2) -> + Context.Vote.get_participation_ema b >>=? fun participation_ema -> + get_smallest_prefix_voters_for_quorum delegates_p2 rolls_p2 participation_ema + |> fun voters -> + (* take the first two voters out so there cannot be quorum *) + let voters_without_quorum = + WithExceptions.Option.get ~loc:__LOC__ @@ List.tl voters + in + get_rolls b voters_without_quorum __LOC__ + >>=? fun voters_rolls_in_exploration -> + (* all voters_without_quorum vote, for yays; + no nays, so supermajority is satisfied *) + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + voters_without_quorum + >>=? fun operations -> + Block.bake ~operations b >>=? fun b -> + (* bake to next period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* we move back to the proposal period because not enough quorum *) + assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + (* check participation_ema update *) + get_expected_participation_ema + rolls_p2 + voters_rolls_in_exploration + initial_participation_ema + |> fun expected_participation_ema -> + Context.Vote.get_participation_ema b >>=? fun new_participation_ema -> + (* assert the formula to calculate participation_ema is correct *) + Assert.equal_int + ~loc:__LOC__ + expected_participation_ema + (Int32.to_int new_participation_ema) + >>=? fun () -> return_unit + +(** If not enough quorum + -- get_updated_participation_ema < pr_ema_weight/den -- + In promotion period, go back to proposal period. *) +let test_not_enough_quorum_in_promotion num_delegates () = + let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in + Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates + >>=? fun (b, delegates) -> + assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + let proposer = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 + in + Op.proposals (B b) proposer [Protocol_hash.zero] >>=? fun ops -> + Block.bake ~operations:[ops] b >>=? fun b -> + (* skip to exploration period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* we moved to an exploration period with one proposal *) + assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> + (* beginning of exploration period, denoted by _p2; + take a snapshot of the active delegates and their rolls from listings *) + get_delegates_and_rolls_from_listings b >>=? fun (delegates_p2, rolls_p2) -> + Context.Vote.get_participation_ema b >>=? fun participation_ema -> + get_smallest_prefix_voters_for_quorum delegates_p2 rolls_p2 participation_ema + |> fun voters -> + let open Alpha_context in + (* all voters vote, for yays; + no nays, so supermajority is satisfied *) + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + voters + >>=? fun operations -> + Block.bake ~operations b >>=? fun b -> + (* skip to first block cooldown period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* we move to cooldown because we have supermajority and enough quorum *) + assert_period ~expected_kind:Cooldown b __LOC__ >>=? fun () -> + (* skip to first block of promotion period *) + bake_until_first_block_of_next_period b >>=? fun b -> + assert_period ~expected_kind:Promotion b __LOC__ + (* bake_until_first_block_of_next_period ~offset:1l b + * >>=? fun b -> + * assert_period ~expected_kind:Promotion b __LOC__ *) + >>=? + fun () -> + Context.Vote.get_participation_ema b >>=? fun initial_participation_ema -> + (* beginning of promotion period, denoted by _p4; + take a snapshot of the active delegates and their rolls from listings *) + get_delegates_and_rolls_from_listings b >>=? fun (delegates_p4, rolls_p4) -> + Context.Vote.get_participation_ema b >>=? fun participation_ema -> + get_smallest_prefix_voters_for_quorum delegates_p4 rolls_p4 participation_ema + |> fun voters -> + (* take the first voter out so there cannot be quorum *) + let voters_without_quorum = + WithExceptions.Option.get ~loc:__LOC__ @@ List.tl voters + in + get_rolls b voters_without_quorum __LOC__ >>=? fun voter_rolls -> + (* all voters_without_quorum vote, for yays; + no nays, so supermajority is satisfied *) + List.map_es + (fun del -> Op.ballot (B b) del Protocol_hash.zero Vote.Yay) + voters_without_quorum + >>=? fun operations -> + Block.bake ~operations b >>=? fun b -> + (* skip to end of promotion period *) + bake_until_first_block_of_next_period b >>=? fun b -> + get_expected_participation_ema rolls_p4 voter_rolls initial_participation_ema + |> fun expected_participation_ema -> + Context.Vote.get_participation_ema b >>=? fun new_participation_ema -> + (* assert the formula to calculate participation_ema is correct *) + Assert.equal_int + ~loc:__LOC__ + expected_participation_ema + (Int32.to_int new_participation_ema) + >>=? fun () -> + (* we move back to the proposal period because not enough quorum *) + assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + assert_listings_not_empty b ~loc:__LOC__ >>=? fun () -> return_unit + +(** Identical proposals (identified by their hash) must be counted as + one. *) +let test_multiple_identical_proposals_count_as_one () = + Context.init 1 >>=? fun (b, delegates) -> + assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + let proposer = WithExceptions.Option.get ~loc:__LOC__ @@ List.hd delegates in + Op.proposals (B b) proposer [Protocol_hash.zero; Protocol_hash.zero] + >>=? fun ops -> + Block.bake ~operations:[ops] b >>=? fun b -> + (* compute the weight of proposals *) + Context.Vote.get_proposals (B b) >>=? fun ps -> + (* compute the rolls of proposer *) + Context.Contract.pkh proposer >>=? fun pkh -> + Context.Vote.get_listings (B b) >>=? fun l -> + (match List.find_opt (fun (del, _) -> del = pkh) l with + | None -> failwith "%s - Missing delegate" __LOC__ + | Some (_, proposer_rolls) -> return proposer_rolls) + >>=? fun proposer_rolls -> + (* correctly count the double proposal for zero as one proposal *) + let expected_weight_proposer = proposer_rolls in + match Environment.Protocol_hash.(Map.find zero ps) with + | Some v -> + if v = expected_weight_proposer then return_unit + else + failwith + "%s - Wrong count %ld is not %ld; identical proposals count as one" + __LOC__ + v + expected_weight_proposer + | None -> failwith "%s - Missing proposal" __LOC__ + +(** Assume the initial balance of allocated by Context.init is at + least 4 times the value of the tokens_per_roll constant. *) +let test_supermajority_in_proposal there_is_a_winner () = + let min_proposal_quorum = 0l in + Context.init + ~consensus_threshold:0 + ~min_proposal_quorum + ~initial_balances:[1L; 1L; 1L] + 10 + >>=? fun (b, delegates) -> + Context.get_constants (B b) + >>=? fun { + parametric = + {blocks_per_cycle; tokens_per_roll; blocks_per_voting_period; _}; + _; + } -> + let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in + let del2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 1 in + let del3 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 2 in + List.map_es (fun del -> Context.Contract.pkh del) [del1; del2; del3] + >>=? fun pkhs -> + let policy = Block.Excluding pkhs in + Op.transaction + (B b) + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 3) + del1 + tokens_per_roll + >>=? fun op1 -> + Op.transaction + (B b) + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 4) + del2 + tokens_per_roll + >>=? fun op2 -> + (if there_is_a_winner then Test_tez.( *? ) tokens_per_roll 3L + else Test_tez.( *? ) tokens_per_roll 2L) + >>?= fun bal3 -> + Op.transaction + (B b) + (WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 5) + del3 + bal3 + >>=? fun op3 -> + Block.bake ~policy ~operations:[op1; op2; op3] b >>=? fun b -> + (* we let one voting period pass; we make sure that: + - the three selected delegates remain active by re-registering as delegates + - their number of rolls do not change *) + List.fold_left_es + (fun b _ -> + List.map_es + (fun del -> + Context.Contract.pkh del >>=? fun pkh -> + Op.delegation (B b) del (Some pkh)) + delegates + >>=? fun ops -> + Block.bake ~policy ~operations:ops b >>=? fun b -> + Block.bake_until_cycle_end ~policy b) + b + (1 -- Int32.to_int (Int32.div blocks_per_voting_period blocks_per_cycle)) + >>=? fun b -> + (* make the proposals *) + Op.proposals (B b) del1 [protos.(0)] >>=? fun ops1 -> + Op.proposals (B b) del2 [protos.(0)] >>=? fun ops2 -> + Op.proposals (B b) del3 [protos.(1)] >>=? fun ops3 -> + Block.bake ~policy ~operations:[ops1; ops2; ops3] b >>=? fun b -> + bake_until_first_block_of_next_period b >>=? fun b -> + (* we remain in the proposal period when there is no winner, + otherwise we move to the exploration period *) + (if there_is_a_winner then assert_period ~expected_kind:Exploration b __LOC__ + else assert_period ~expected_kind:Proposal b __LOC__) + >>=? fun () -> return_unit + +(** After one voting period, if [has_quorum] then the period kind must + have been the cooldown vote. Otherwise, it should have remained in + place in the proposal period. *) +let test_quorum_in_proposal has_quorum () = + let total_tokens = 32_000_000_000_000L in + let half_tokens = Int64.div total_tokens 2L in + Context.init + ~consensus_threshold:0 + ~initial_balances:[1L; half_tokens; half_tokens] + 3 + >>=? fun (b, delegates) -> + Context.get_constants (B b) + >>=? fun { + parametric = + { + blocks_per_cycle; + min_proposal_quorum; + blocks_per_voting_period; + _; + }; + _; + } -> + let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in + let del2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 1 in + List.map_es (fun del -> Context.Contract.pkh del) [del1; del2] + >>=? fun pkhs -> + let policy = Block.Excluding pkhs in + let quorum = + if has_quorum then Int64.of_int32 min_proposal_quorum + else Int64.(sub (of_int32 min_proposal_quorum) 10L) + in + let bal = + Int64.(div (mul total_tokens quorum) 100_00L) |> Test_tez.of_mutez_exn + in + Op.transaction (B b) del2 del1 bal >>=? fun op2 -> + Block.bake ~policy ~operations:[op2] b >>=? fun b -> + (* we let one voting period pass; we make sure that: + - the two selected delegates remain active by re-registering as delegates + - their number of rolls do not change *) + List.fold_left_es + (fun b _ -> + List.map_es + (fun del -> + Context.Contract.pkh del >>=? fun pkh -> + Op.delegation (B b) del (Some pkh)) + [del1; del2] + >>=? fun ops -> + Block.bake ~policy ~operations:ops b >>=? fun b -> + Block.bake_until_cycle_end ~policy b) + b + (1 -- Int32.to_int (Int32.div blocks_per_voting_period blocks_per_cycle)) + >>=? fun b -> + (* make the proposal *) + Op.proposals (B b) del1 [protos.(0)] >>=? fun ops -> + Block.bake ~policy ~operations:[ops] b >>=? fun b -> + bake_until_first_block_of_next_period b >>=? fun b -> + (* we remain in the proposal period when there is no quorum, + otherwise we move to the cooldown vote period *) + (if has_quorum then assert_period ~expected_kind:Exploration b __LOC__ + else assert_period ~expected_kind:Proposal b __LOC__) + >>=? fun () -> return_unit + +(** If a supermajority is reached, then the voting period must be + reached. Otherwise, it remains in proposal period. *) +let test_supermajority_in_exploration supermajority () = + let min_proposal_quorum = Int32.(of_int @@ (100_00 / 100)) in + Context.init ~consensus_threshold:0 ~min_proposal_quorum 100 + >>=? fun (b, delegates) -> + let del1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 in + let proposal = protos.(0) in + Op.proposals (B b) del1 [proposal] >>=? fun ops1 -> + Block.bake ~operations:[ops1] b >>=? fun b -> + bake_until_first_block_of_next_period b >>=? fun b -> + (* move to exploration *) + assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> + (* assert our proposal won *) + (Context.Vote.get_current_proposal (B b) >>=? function + | Some v -> + if Protocol_hash.(equal proposal v) then return_unit + else failwith "%s - Wrong proposal" __LOC__ + | None -> failwith "%s - Missing proposal" __LOC__) + >>=? fun () -> + (* beginning of exploration period, denoted by _p2; + take a snapshot of the active delegates and their rolls from listings *) + get_delegates_and_rolls_from_listings b >>=? fun (delegates_p2, _rolls_p2) -> + (* supermajority means [num_yays / (num_yays + num_nays) >= s_num / s_den], + which is equivalent with [num_yays >= num_nays * s_num / (s_den - s_num)] *) + let num_delegates = List.length delegates_p2 in + let num_nays = num_delegates / 5 in + (* any smaller number will do as well *) + let num_yays = num_nays * s_num / (s_den - s_num) in + (* majority/minority vote depending on the [supermajority] parameter *) + let num_yays = if supermajority then num_yays else num_yays - 1 in + let open Alpha_context in + let (nays_delegates, rest) = List.split_n num_nays delegates_p2 in + let (yays_delegates, _) = List.split_n num_yays rest in + List.map_es (fun del -> Op.ballot (B b) del proposal Vote.Yay) yays_delegates + >>=? fun operations_yays -> + List.map_es (fun del -> Op.ballot (B b) del proposal Vote.Nay) nays_delegates + >>=? fun operations_nays -> + let operations = operations_yays @ operations_nays in + Block.bake ~operations b >>=? fun b -> + bake_until_first_block_of_next_period b >>=? fun b -> + (if supermajority then assert_period ~expected_kind:Cooldown b __LOC__ + else assert_period ~expected_kind:Proposal b __LOC__) + >>=? fun () -> return_unit + +(** Test also how the selection scales: all delegates propose max + proposals. *) +let test_no_winning_proposal num_delegates () = + let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in + Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates + >>=? fun (b, _) -> + (* beginning of proposal, denoted by _p1; + take a snapshot of the active delegates and their rolls from listings *) + get_delegates_and_rolls_from_listings b >>=? fun (delegates_p1, _rolls_p1) -> + let open Alpha_context in + let props = + List.map (fun i -> protos.(i)) (1 -- Constants.max_proposals_per_delegate) + in + (* all delegates active in p1 propose the same proposals *) + List.map_es (fun del -> Op.proposals (B b) del props) delegates_p1 + >>=? fun ops_list -> + Block.bake ~operations:ops_list b >>=? fun b -> + (* skip to exploration period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* we stay in the same proposal period because no winning proposal *) + assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> return_unit + +(** Vote to pass with maximum possible participation_ema (100%), it is + sufficient for the vote quorum to be equal or greater than the + maximum quorum cap. *) +let test_quorum_capped_maximum num_delegates () = + let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in + Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates + >>=? fun (b, delegates) -> + (* set the participation EMA to 100% *) + Context.Vote.set_participation_ema b 100_00l >>= fun b -> + Context.get_constants (B b) >>=? fun {parametric = {quorum_max; _}; _} -> + (* proposal period *) + let open Alpha_context in + assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + (* propose a new protocol *) + let protocol = Protocol_hash.zero in + let proposer = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 + in + Op.proposals (B b) proposer [protocol] >>=? fun ops -> + Block.bake ~operations:[ops] b >>=? fun b -> + (* skip to exploration period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* we moved to an exploration period with one proposal *) + assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> + (* take percentage of the delegates equal or greater than quorum_max *) + let minimum_to_pass = + Float.of_int (List.length delegates) + *. Int32.(to_float quorum_max) + /. 100_00. + |> Float.ceil |> Float.to_int + in + let voters = List.take_n minimum_to_pass delegates in + (* all voters vote for yays; no nays, so supermajority is satisfied *) + List.map_es (fun del -> Op.ballot (B b) del protocol Vote.Yay) voters + >>=? fun operations -> + Block.bake ~operations b >>=? fun b -> + (* skip to next period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* expect to move to cooldown because we have supermajority and enough quorum *) + assert_period ~expected_kind:Cooldown b __LOC__ + +(** Vote to pass with minimum possible participation_ema (0%), it is + sufficient for the vote quorum to be equal or greater than the + minimum quorum cap. *) +let test_quorum_capped_minimum num_delegates () = + let min_proposal_quorum = Int32.(of_int @@ (100_00 / num_delegates)) in + Context.init ~consensus_threshold:0 ~min_proposal_quorum num_delegates + >>=? fun (b, delegates) -> + (* set the participation EMA to 0% *) + Context.Vote.set_participation_ema b 0l >>= fun b -> + Context.get_constants (B b) >>=? fun {parametric = {quorum_min; _}; _} -> + (* proposal period *) + let open Alpha_context in + assert_period ~expected_kind:Proposal b __LOC__ >>=? fun () -> + (* propose a new protocol *) + let protocol = Protocol_hash.zero in + let proposer = + WithExceptions.Option.get ~loc:__LOC__ @@ List.nth delegates 0 + in + Op.proposals (B b) proposer [protocol] >>=? fun ops -> + Block.bake ~operations:[ops] b >>=? fun b -> + (* skip to exploration period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* we moved to an exploration period with one proposal *) + assert_period ~expected_kind:Exploration b __LOC__ >>=? fun () -> + (* take percentage of the delegates equal or greater than quorum_min *) + let minimum_to_pass = + Float.of_int (List.length delegates) + *. Int32.(to_float quorum_min) + /. 100_00. + |> Float.ceil |> Float.to_int + in + let voters = List.take_n minimum_to_pass delegates in + (* all voters vote for yays; no nays, so supermajority is satisfied *) + List.map_es (fun del -> Op.ballot (B b) del protocol Vote.Yay) voters + >>=? fun operations -> + Block.bake ~operations b >>=? fun b -> + (* skip to next period *) + bake_until_first_block_of_next_period b >>=? fun b -> + (* expect to move to cooldown because we have supermajority and enough quorum *) + assert_period ~expected_kind:Cooldown b __LOC__ + +(* gets the voting power *) +let get_voting_power block pkhash = + let ctxt = Context.B block in + Context.get_voting_power ctxt pkhash + +(** Test that the voting power changes if the balance between bakers changes + and the blockchain moves to the next voting period. It also checks that + the total voting power coincides with the addition of the voting powers + of bakers *) +let test_voting_power_updated_each_voting_period () = + let init_bal1 = 80_000_000_000L in + let init_bal2 = 48_000_000_000L in + let init_bal3 = 40_000_000_000L in + (* Create three accounts with different amounts *) + Context.init + ~consensus_threshold:0 + ~initial_balances:[init_bal1; init_bal2; init_bal3] + 3 + >>=? fun (genesis, contracts) -> + Context.get_constants (B genesis) + >>=? fun {parametric = {tokens_per_roll; _}; _} -> + let con1 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 0 in + let con2 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 1 in + let con3 = WithExceptions.Option.get ~loc:__LOC__ @@ List.nth contracts 2 in + (* Get the key hashes of the bakers *) + Context.Contract.pkh con1 >>=? fun baker1 -> + Context.Contract.pkh con2 >>=? fun baker2 -> + Context.Contract.pkh con3 >>=? fun baker3 -> + (* Retrieve balance of con1 *) + let open Test_tez in + Context.Contract.balance (B genesis) con1 >>=? fun balance1 -> + Context.Delegate.current_frozen_deposits (B genesis) baker1 + >>=? fun frozen_deposits1 -> + balance1 +? frozen_deposits1 >>?= fun full_balance1 -> + Assert.equal_tez ~loc:__LOC__ full_balance1 (of_mutez_exn init_bal1) + >>=? fun () -> + (* Retrieve balance of con2 *) + Context.Contract.balance (B genesis) con2 >>=? fun balance2 -> + Context.Delegate.current_frozen_deposits (B genesis) baker2 + >>=? fun frozen_deposits2 -> + balance2 +? frozen_deposits2 >>?= fun full_balance2 -> + Assert.equal_tez ~loc:__LOC__ full_balance2 (of_mutez_exn init_bal2) + >>=? fun () -> + (* Retrieve balance of con3 *) + Context.Contract.balance (B genesis) con3 >>=? fun balance3 -> + Context.Delegate.current_frozen_deposits (B genesis) baker3 + >>=? fun frozen_deposits3 -> + balance3 +? frozen_deposits3 >>?= fun full_balance3 -> + Assert.equal_tez ~loc:__LOC__ full_balance3 (of_mutez_exn init_bal3) + >>=? fun () -> + (* Auxiliary assert_voting_power *) + let assert_voting_power ~loc n block baker = + get_voting_power block baker >>=? fun voting_power -> + Assert.equal_int ~loc n (Int32.to_int voting_power) + in + (* Auxiliary assert_total_voting_power *) + let assert_total_voting_power ~loc n block = + Context.get_total_voting_power (B block) >>=? fun total_voting_power -> + Assert.equal_int ~loc n (Int32.to_int total_voting_power) + in + (* Assert voting power is equal to the balance divided by tokens_per_roll *) + let expected_power_of_baker_1 = + Int64.(to_int (div (to_mutez full_balance1) (to_mutez tokens_per_roll))) + in + assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 genesis baker1 + >>=? fun () -> + (* Assert voting power is equal to the balance divided by tokens_per_roll *) + let expected_power_of_baker_2 = + Int64.(to_int (div (to_mutez full_balance2) (to_mutez tokens_per_roll))) + in + assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 genesis baker2 + >>=? fun () -> + (* Assert total voting power *) + let expected_power_of_baker_3 = + Int64.(to_int (div (to_mutez full_balance3) (to_mutez tokens_per_roll))) + in + assert_total_voting_power + ~loc:__LOC__ + Int.( + add + (add expected_power_of_baker_1 expected_power_of_baker_2) + expected_power_of_baker_3) + genesis + >>=? fun () -> + (* Create policy that excludes baker1 and baker2 from baking *) + let policy = Block.Excluding [baker1; baker2] in + (* Transfer tokens_per_roll * num_rolls from baker1 to baker2 *) + let num_rolls = 5L in + tokens_per_roll *? num_rolls >>?= fun amount -> + Op.transaction (B genesis) con1 con2 amount >>=? fun op -> + (* Bake the block containing the transaction *) + Block.bake ~policy ~operations:[op] genesis >>=? fun block -> + (* Retrieve balance of con1 *) + Context.Contract.balance (B block) con1 >>=? fun balance1 -> + (* Assert balance has changed by deducing the amount *) + of_mutez_exn init_bal1 -? amount >>?= fun balance1_after_deducing_amount -> + Context.Delegate.current_frozen_deposits (B block) baker1 + >>=? fun frozen_deposit1 -> + balance1_after_deducing_amount -? frozen_deposit1 + >>?= Assert.equal_tez ~loc:__LOC__ balance1 + >>=? fun () -> + (* Retrieve balance of con2 *) + Context.Contract.balance (B block) con2 >>=? fun balance2 -> + (* Assert balance has changed by adding amount *) + of_mutez_exn init_bal2 +? amount >>?= fun balance2_after_adding_amount -> + Context.Delegate.current_frozen_deposits (B block) baker2 + >>=? fun frozen_deposit2 -> + balance2_after_adding_amount -? frozen_deposit2 + >>?= Assert.equal_tez ~loc:__LOC__ balance2 + >>=? fun () -> + Block.bake ~policy block >>=? fun block -> + (* Assert voting power (and total) remains the same before next voting period *) + assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 block baker1 + >>=? fun () -> + assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 block baker2 + >>=? fun () -> + assert_voting_power ~loc:__LOC__ expected_power_of_baker_3 block baker3 + >>=? fun () -> + assert_total_voting_power + ~loc:__LOC__ + Int.( + add + (add expected_power_of_baker_1 expected_power_of_baker_2) + expected_power_of_baker_3) + block + >>=? fun () -> + bake_until_first_block_of_next_period block >>=? fun block -> + (* Assert voting power of baker1 has decreased by num_rolls *) + let expected_power_of_baker_1 = + Int.sub expected_power_of_baker_1 (Int64.to_int num_rolls) + in + assert_voting_power ~loc:__LOC__ expected_power_of_baker_1 block baker1 + >>=? fun _ -> + (* Assert voting power of baker2 has increased by num_rolls *) + let expected_power_of_baker_2 = + Int.add expected_power_of_baker_2 (Int64.to_int num_rolls) + in + assert_voting_power ~loc:__LOC__ expected_power_of_baker_2 block baker2 + >>=? fun _ -> + (* Retrieve voting power of baker3 *) + get_voting_power block baker3 >>=? fun power -> + let power_of_baker_3 = Int32.to_int power in + (* Assert total voting power *) + assert_total_voting_power + ~loc:__LOC__ + Int.( + add + (add expected_power_of_baker_1 expected_power_of_baker_2) + power_of_baker_3) + block + +let test_voting_period_pp () = + let vp = + Voting_period_repr. + { + index = Int32.of_int 123; + kind = Proposal; + start_position = Int32.of_int 321; + } + in + Assert.equal + ~loc:__LOC__ + ( = ) + "Unexpected pretty printing of voting period" + Format.pp_print_string + (Format.asprintf "%a" Voting_period_repr.pp vp) + "index: 123, kind:proposal, start_position: 321" + +let tests = + [ + Tztest.tztest "voting successful_vote" `Quick (test_successful_vote 137); + Tztest.tztest + "voting cooldown, not enough quorum" + `Quick + (test_not_enough_quorum_in_exploration 245); + Tztest.tztest + "voting promotion, not enough quorum" + `Quick + (test_not_enough_quorum_in_promotion 432); + Tztest.tztest + "voting counting double proposal" + `Quick + test_multiple_identical_proposals_count_as_one; + Tztest.tztest + "voting proposal, with supermajority" + `Quick + (test_supermajority_in_proposal true); + Tztest.tztest + "voting proposal, without supermajority" + `Quick + (test_supermajority_in_proposal false); + Tztest.tztest + "voting proposal, with quorum" + `Quick + (test_quorum_in_proposal true); + Tztest.tztest + "voting proposal, without quorum" + `Quick + (test_quorum_in_proposal false); + Tztest.tztest + "voting cooldown, with supermajority" + `Quick + (test_supermajority_in_exploration true); + Tztest.tztest + "voting cooldown, without supermajority" + `Quick + (test_supermajority_in_exploration false); + Tztest.tztest + "voting proposal, no winning proposal" + `Quick + (test_no_winning_proposal 400); + Tztest.tztest + "voting quorum, quorum capped maximum" + `Quick + (test_quorum_capped_maximum 400); + Tztest.tztest + "voting quorum, quorum capped minimum" + `Quick + (test_quorum_capped_minimum 401); + Tztest.tztest + "voting power updated in each voting period" + `Quick + test_voting_power_updated_each_voting_period; + Tztest.tztest "voting period pretty print" `Quick test_voting_period_pp; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/unit/.ocamlformat b/src/proto_012_PsiThaCa/lib_protocol/test/unit/.ocamlformat new file mode 100644 index 000000000000..5e1158919e85 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/unit/.ocamlformat @@ -0,0 +1,17 @@ +version=0.18.0 +wrap-fun-args=false +let-binding-spacing=compact +field-space=loose +break-separators=after +space-around-arrays=false +space-around-lists=false +space-around-records=false +space-around-variants=false +dock-collection-brackets=true +space-around-records=false +sequence-style=separator +doc-comments=before +margin=80 +module-item-spacing=sparse +parens-tuple=always +parens-tuple-patterns=always diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/unit/dune b/src/proto_012_PsiThaCa/lib_protocol/test/unit/dune new file mode 100644 index 000000000000..f59953beacc3 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/unit/dune @@ -0,0 +1,20 @@ +(test + (name main) + (package tezos-protocol-012-PsiThaCa-tests) + (libraries tezos-base + tezos-micheline + tezos-protocol-environment + alcotest-lwt + tezos-012-PsiThaCa-test-helpers + tezos-stdlib-unix + tezos-client-base + tezos-protocol-012-PsiThaCa-parameters + tezos-base-test-helpers) + (flags (:standard -open Tezos_base__TzPervasives + -open Tezos_base_test_helpers + -open Tezos_micheline + -open Tezos_client_012_PsiThaCa + -open Tezos_protocol_012_PsiThaCa + -open Tezos_protocol_environment_012_PsiThaCa + -open Tezos_012_PsiThaCa_test_helpers)) + (action (run %{test} "test" "Unit"))) diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/unit/main.ml b/src/proto_012_PsiThaCa/lib_protocol/test/unit/main.ml new file mode 100644 index 000000000000..9d9bbd2f10df --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/unit/main.ml @@ -0,0 +1,60 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +module Unit_test : sig + (** + * Example: [spec "Alpha_context.ml" Test_alpha_context.test_cases] + * Unit tests needs tag in log (like "[UNIT] some test description here...") + * This function handles such meta data *) + val spec : + string -> + unit Alcotest_lwt.test_case list -> + string * unit Alcotest_lwt.test_case list + + (** Tests with description string without [Unit] are skipped *) + val skip : + string -> + unit Alcotest_lwt.test_case list -> + string * unit Alcotest_lwt.test_case list +end = struct + let spec unit_name test_cases = ("[Unit] " ^ unit_name, test_cases) + + let skip unit_name test_cases = ("[SKIPPED] " ^ unit_name, test_cases) +end + +let () = + Alcotest_lwt.run + "protocol_012_PsiThaCa unit tests" + [ + Unit_test.spec "Alpha_context.ml" Test_alpha_context.tests; + Unit_test.spec "Raw_level_repr.ml" Test_raw_level_repr.tests; + Unit_test.skip "Raw_level_repr.ml" Test_raw_level_repr.skipped_tests; + Unit_test.spec "Tez_repr.ml" Test_tez_repr.tests; + Unit_test.spec "Contract_repr.ml" Test_contract_repr.tests; + Unit_test.spec "Operation_repr.ml" Test_operation_repr.tests; + Unit_test.spec + "Global_constants_storage.ml" + Test_global_constants_storage.tests; + ] + |> Lwt_main.run diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_alpha_context.ml b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_alpha_context.ml new file mode 100644 index 000000000000..ef7f84ba9a0e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_alpha_context.ml @@ -0,0 +1,129 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** Testing + ------- + Component: Alpha_context + Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe -- test Alpha_context + Dependencies: helpers/block.ml + Subject: To test the modules (including the top-level) + in alpha_context.ml as individual units, particularly + failure cases. Superficial goal: increase coverage percentage. +*) + +(** Creates an Alpha_context without creating a full-fledged block *) +let create () = + let accounts = Account.generate_accounts 1 in + Block.alpha_context accounts + +module Test_Script = struct + (** Force serialise of lazy [Big_map.t] in a given [alpha_context] *) + let test_force_bytes_in_context () = + create () >>=? fun alpha_context -> + let mbytes_pp ppf t = + Format.pp_print_string ppf (Environment.Bytes.to_string t) + in + let open Alpha_context.Script in + Environment.wrap_tzresult + @@ force_bytes_in_context alpha_context + @@ lazy_expr @@ Micheline.strip_locations + @@ Prim (0, D_Unit, [], []) + >>?= fun (bytes, _) -> + Assert.equal + ~loc:__LOC__ + Environment.Bytes.equal + "script serialised incorrectly" + mbytes_pp + bytes + (`Hex "030b" |> Hex.to_bytes_exn) +end + +module Test_Big_map = struct + (** Test failure path: look for a non-existent key in a [Big_map] *) + let test_mem () = + ( create () >>=? fun alpha_context -> + Big_map.fresh ~temporary:true alpha_context >|= Environment.wrap_tzresult + >>=? fun (alpha_context, big_map_id) -> + Big_map.mem + alpha_context + big_map_id + (Script_expr_hash.hash_string ["0"; "0"]) + >|= Environment.wrap_tzresult ) + >>=? fun (_alpha_context, is_member) -> + Assert.equal_bool ~loc:__LOC__ is_member false + + (** Test failure code path of [get_opt] by looking for missing key in a [Big_map.t] *) + let test_get_opt () = + ( create () >>=? fun alpha_context -> + Big_map.fresh ~temporary:true alpha_context >|= Environment.wrap_tzresult + >>=? fun (alpha_context, big_map_id) -> + Big_map.get_opt + alpha_context + big_map_id + (Script_expr_hash.hash_string ["0"; "0"]) + >|= Environment.wrap_tzresult ) + >>=? fun (_alpha_context, value) -> + match value with + | Some _ -> + failwith "get_opt should have failed looking for a non-existent key" + | None -> return_unit + + (** Test existence of a non-existent [Big_map] in an [Alpha_context.t] *) + let test_exists () = + ( create () >>=? fun alpha_context -> + Big_map.fresh ~temporary:true alpha_context >|= Environment.wrap_tzresult + >>=? fun (alpha_context, big_map_id) -> + Big_map.exists alpha_context big_map_id >|= Environment.wrap_tzresult ) + >>=? fun (_alpha_context, value) -> + match value with + | Some _ -> + failwith "exists should have failed looking for a non-existent big_map" + | None -> return_unit +end + +let tests = + [ + Tztest.tztest + "Script.force_bytes_in_context: checks if it serialises a simple \ + michelson expression" + `Quick + Test_Script.test_force_bytes_in_context; + Tztest.tztest + "Big_map.mem: failure case - must return false when starting with an \ + empty map" + `Quick + Test_Big_map.test_mem; + Tztest.tztest + "Big_map.get_opt: failure case - looking up key that doesn't exist" + `Quick + Test_Big_map.test_get_opt; + Tztest.tztest + "Big_map.exists: failure case - looking up big_map that doesn't exist" + `Quick + Test_Big_map.test_exists; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_contract_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_contract_repr.ml new file mode 100644 index 000000000000..7ecff1016d63 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_contract_repr.ml @@ -0,0 +1,161 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Contract_repr + Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe -- test Contract_repr + Dependencies: contract_hash.ml + Subject: To test the modules (including the top-level) + in contract_repr.ml as individual units, particularly + failure cases. Superficial goal: increase coverage percentage. +*) +open Protocol + +open Tztest + +(* + + TODO: Remove dependence on contract_hash.ml and mock it + + *) + +module Test_contract_repr = struct + (** Assert if [is_implicit] correctly returns the implicit contract *) + open Contract_repr + + let dummy_operation_hash = + Operation_hash.of_bytes_exn + (Bytes.of_string "test-operation-hash-of-length-32") + + let dummy_origination_nonce = initial_origination_nonce dummy_operation_hash + + let dummy_contract_hash = + (* WARNING: Uses Contract_repr itself, which is yet to be tested. This happened because Contract_hash wasn't mocked *) + let data = + Data_encoding.Binary.to_bytes_exn + Contract_repr.origination_nonce_encoding + dummy_origination_nonce + in + Contract_hash.hash_bytes [data] + + let dummy_implicit_contract = implicit_contract Signature.Public_key_hash.zero + + let dummy_originated_contract = originated_contract @@ dummy_origination_nonce + + let test_implicit () = + match is_implicit dummy_implicit_contract with + | Some _ -> return_unit + | None -> + failwith + "must have returned the public key hash of implicit contract. \n\ + \ Instead, returned None" + + (** Check if [is_implicit] catches a non-implicit (originated) contract and returns None *) + let test_not_implicit () = + match is_implicit dummy_originated_contract with + | None -> return_unit + | Some _ -> failwith "must have returned the None. Instead, returned Some _" + + let test_originated () = + match is_originated dummy_originated_contract with + | Some _ -> return_unit + | None -> + failwith + "must have returned the origination nonce correctly. Instead \ + returned None." + + let test_not_originated () = + match is_originated dummy_implicit_contract with + | None -> return_unit + | Some _ -> failwith "must have returned the None. Instead, returned Some _" + + let test_to_b58check_implicit () = + Assert.equal + ~loc:__LOC__ + String.equal + "%s should have been equal to %" + Format.pp_print_string + (to_b58check dummy_implicit_contract) + Signature.Public_key_hash.(to_b58check zero) + + let test_to_b58check_originated () = + Assert.equal + ~loc:__LOC__ + String.equal + "%s should have been equal to %" + Format.pp_print_string + (to_b58check dummy_originated_contract) + Contract_hash.(to_b58check @@ dummy_contract_hash) + + let test_originated_contracts_basic () = + let since = dummy_origination_nonce in + let rec incr_n_times nonce = function + | 0 -> nonce + | n -> incr_n_times (Contract_repr.incr_origination_nonce nonce) (n - 1) + in + let until = incr_n_times since 5 in + let contracts = originated_contracts ~since ~until in + Assert.equal_int ~loc:__LOC__ (List.length contracts) 5 +end + +let tests = + [ + tztest + "Contract_repr.is_implicit: must correctly identify a valid implicit \ + contract" + `Quick + Test_contract_repr.test_implicit; + tztest + "Contract_repr.is_implicit: must correctly return None for a originated \ + contract" + `Quick + Test_contract_repr.test_not_implicit; + tztest + "Contract_repr.is_originated: must correctly return operation hash of \ + the originated contract" + `Quick + Test_contract_repr.test_originated; + tztest + "Contract_repr.is_originated: must correctly return None for an implicit \ + contract contract" + `Quick + Test_contract_repr.test_not_originated; + tztest + "Contract_repr.to_b58check: must correctly stringify, b58check encoded, \ + an implicit contract" + `Quick + Test_contract_repr.test_to_b58check_implicit; + tztest + "Contract_repr.originated_contract: must correctly create an originated \ + contract" + `Quick + Test_contract_repr.test_originated_contracts_basic; + tztest + "Contract_repr.to_b58check: must correctly stringify, b58check encoded, \ + an originated contract" + `Quick + Test_contract_repr.test_to_b58check_originated; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_global_constants_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_global_constants_storage.ml new file mode 100644 index 000000000000..454127b5e679 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_global_constants_storage.ml @@ -0,0 +1,413 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Global table of constants + Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe \ + -- test Global_constants_storage + Dependencies: contract_hash.ml + Subject: Test the global table of constants +*) + +open Protocol +open Alpha_context +open Tztest +open Micheline +open QCheck +open Lib_test.Qcheck_helpers +open Michelson_v1_primitives +open Michelson_v1_printer +open Test_global_constants + +(** [get] on a nonexistent global constant + returns an error. *) +let test_get_on_nonexistent_fails = + tztest_qcheck + ~name:"get on a nonexistent global constants fails" + (pair + (Generators.context_arbitrary ()) + (Generators.canonical_without_constant_arbitrary ())) + (fun (context, expr) -> + expr_to_hash expr |> Environment.wrap_tzresult >>?= fun hash -> + Global_constants_storage.get context hash + >|= Environment.wrap_tzresult + >>= assert_proto_error_id __LOC__ "Nonexistent_global") + +(** If registering an expression yields a hash [h] and context [c], + then [get c h] should yield the original expression. *) +let test_get_always_returns_registered_expr = + tztest_qcheck + ~name:"get always returned the registered constant" + (pair + (Generators.context_arbitrary ()) + (Generators.canonical_without_constant_arbitrary ())) + (fun (context, expr) -> + Global_constants_storage.register context expr + >|= Environment.wrap_tzresult + >>=? fun (context, hash, _cost) -> + Global_constants_storage.get context hash >|= Environment.wrap_tzresult + >|=? fun (_context, actual_expr) -> + qcheck_eq ~pp:print_expr actual_expr expr) + +(* Attempts to register an expression that contains references + to expressions not already registered should fail. *) +let test_register_fails_with_unregistered_references = + tztest "register: fails with unregistered references" `Quick (fun () -> + let prim_with_constant = + Expr.from_string + {| Pair 1 + (constant "exprubuoE4JFvkSpxsZJXAvhTdozCNZpgfCnyg6WsiAYX79q4z3bXu")|} + in + create_context () >>=? fun context -> + Global_constants_storage.register context prim_with_constant + >|= Environment.wrap_tzresult + >>= assert_proto_error_id __LOC__ "Nonexistent_global") + +(** Same test as [test_register_fails_with_unregistered_references] + but with random values. *) +let test_register_fails_with_unregistered_references_pbt = + tztest_qcheck + ~name:"register: fails with unregistered references pbt" + (pair + (Generators.context_arbitrary ()) + (Generators.canonical_with_constant_arbitrary ())) + (fun (context, (_, expr, _)) -> + assume_expr_not_too_large expr ; + Global_constants_storage.register context expr + >|= Environment.wrap_tzresult + >>= assert_proto_error_id __LOC__ "Nonexistent_global") + +let rec grow n node = + match n with n when n <= 0 -> node | n -> grow (n - 1) (Seq ((), [node])) + +(* Any expression with a depth that exceeds + [Global_constants_storage.max_allowed_global_constant_depth] + should be rejected. *) +let test_register_fails_if_too_deep = + tztest "register: fails if expression too deep" `Quick (fun () -> + let vdeep_expr = + grow + (Constants_repr.max_allowed_global_constant_depth + 1) + (Int ((), Z.of_int 1)) + |> Micheline.strip_locations + in + create_context () >>=? fun context -> + Global_constants_storage.register context vdeep_expr + >|= Environment.wrap_tzresult + >>= assert_proto_error_id __LOC__ "Expression_too_deep") + +(** [expand] on an expression containing a nonexistent global + constant returns an error. *) +let test_expand_nonexistent_fails = + tztest_qcheck + ~name: + "expand on an expression containing a nonexistent global constant fails" + (pair + (Generators.context_arbitrary ()) + (Generators.canonical_with_constant_arbitrary ())) + @@ fun (context, (_, expr, _)) -> + assume_expr_not_too_large expr ; + Global_constants_storage.expand context expr + >|= Environment.wrap_tzresult + >>= assert_proto_error_id __LOC__ "Nonexistent_global" + +(** Expanding an expression without constants should yield the same expression. *) +let test_expand_no_constants = + tztest "expand: no constants case" `Quick (fun () -> + create_context () >>=? fun context -> + let expected = Expr.from_string "Pair 1 (Pair 2 3)" in + Global_constants_storage.expand context expected + >|= Environment.wrap_tzresult + >>=? fun (_, result_expr) -> + assert_expr_equal __LOC__ expected result_expr) + +(** Similar to [test_expand_no_constants], but random. *) +let test_register_and_expand_orthogonal = + tztest_qcheck + ~name:"register and expand are orthogonal" + (triple + (Generators.context_arbitrary ()) + (Generators.canonical_without_constant_arbitrary ()) + (Generators.canonical_without_constant_arbitrary ())) + (fun (context, expr1, expr2) -> + assume_expr_not_too_large expr1 ; + assume_expr_not_too_large expr2 ; + let open Michelson_v1_printer in + Global_constants_storage.register context expr1 + >|= Environment.wrap_tzresult + >>=? fun (context, _hash, _cost) -> + Global_constants_storage.expand context expr2 + >|= Environment.wrap_tzresult + >|=? fun (_, expr2_result) -> qcheck_eq ~pp:print_expr expr2 expr2_result) + +(** Expanding should expand constants in the given + expression, then expand any new constants, etc. + recursively until no constants remain. *) +let test_expand_deep_constants = + tztest "expand: deep constants" `Quick (fun () -> + (* Should hold for any n, but this test is very slow, + hence we don't do QCheck. *) + let n = 1000 in + let expr1 = Expr.from_string "{}" in + create_context () >>=? fun context -> + let rec n_constants_deep context node n = + Global_constants_storage.register context (strip_locations node) + >|= Environment.wrap_tzresult + >>=? fun (context, hash, _) -> + if n <= 1 then return (context, node, hash) + else + let new_node = + Seq + ( -1, + [ + Prim + ( -1, + H_constant, + [String (-1, Script_expr_hash.to_b58check hash)], + [] ); + ] ) + in + n_constants_deep context new_node (n - 1) + in + n_constants_deep context (root expr1) n >>=? fun (context, _, hash) -> + let deep_expr = + Expr.from_string + @@ Format.sprintf + "{constant \"%s\"; CDR; NIL operation; PAIR}" + (Script_expr_hash.to_b58check hash) + in + Global_constants_storage.expand context deep_expr + >|= Environment.wrap_tzresult + >>=? fun (_, result) -> + let seq_n_deep n = + let rec advance n acc = + match n with 0 -> acc | _ -> advance (n - 1) (Seq (-1, [acc])) + in + advance (n - 1) (Seq (-1, [])) + in + let seq_str = Expr.to_string @@ strip_locations @@ seq_n_deep n in + let expected = + Expr.from_string + @@ Format.sprintf "{ %s; CDR; NIL operation; PAIR; }" + @@ seq_str + in + assert_expr_equal __LOC__ expected result) + +(** The [constant] prim is permitted only to have a + single string argument, representing a valid + Script_repr.expr hash, with no annotations *) +let test_expand_reject_ill_formed = + tztest "expand: ill formed constants are rejected" `Quick (fun () -> + (* first, create a context, register a constant and check + that its expansion works well. *) + create_context () >>=? fun context -> + let some_expr = Expr.from_string "0" in + Global_constants_storage.register context some_expr + >|= Environment.wrap_tzresult + >>=? fun (context, hash, _) -> + let hash = Script_expr_hash.to_b58check hash in + (* check that expansion of the registered constant works *) + Global_constants_storage.expand + context + (Expr.from_string @@ Format.sprintf "constant \"%s\"" hash) + >|= Environment.wrap_tzresult + >>=? fun (context, result) -> + assert_expr_equal __LOC__ some_expr result >>=? fun () -> + let test expr = + let expected = Expr.from_string expr in + Global_constants_storage.expand context expected + >|= Environment.wrap_tzresult + >>= assert_proto_error_id __LOC__ "Badly_formed_constant_expression" + in + (* constant with an argument other than String fails *) + test "constant 9" >>=? fun () -> + (* same as above but nested *) + test "Pair 1 (constant (Pair 2 3))" >>=? fun () -> + (* constant with bad hash fails *) + test "constant \"foobar\"" >>=? fun () -> + (* constant with type annot *) + test @@ Format.sprintf "(constant :a \"%s\")" hash >>=? fun () -> + (* constant with var annot *) + test @@ Format.sprintf "(constant @a \"%s\")" hash >>=? fun () -> + (* constant with field annot *) + test @@ Format.sprintf "(constant %%a \"%s\")" hash) + +(** The [constant] prim is not permitted to have a + [constant] child argument. + + The idea is to have expansion like this: + + constant (constant ) -> constant hash -> value + + But we want to forbid this as a badly formed constant. + Asserting that every constant must be a *static* string + makes it easier to see which constants are used where, because + you can just traverse the AST (no expansion necessary). *) +let test_reject_use_of_inner_constant = + tztest + "expand: use of 'constant (constant ...)' is rejected" + `Quick + (fun () -> + (* First, create a context, register a constant and check + that its expansion works well. *) + create_context () >>=? fun context -> + let some_expr = Expr.from_string "0" in + Global_constants_storage.register context some_expr + >|= Environment.wrap_tzresult + >>=? fun (context, hash, _) -> + let hash = Script_expr_hash.to_b58check hash in + (* Next, register the hash itself as a constant. *) + Global_constants_storage.register + context + (strip_locations (Micheline.String (-1, hash))) + >|= Environment.wrap_tzresult + >>=? fun (context, hash, _) -> + let hash = Script_expr_hash.to_b58check hash in + Global_constants_storage.expand + context + (Expr.from_string + @@ Format.sprintf "{ constant (constant \"%s\") } " hash) + >|= Environment.wrap_tzresult + >>= assert_proto_error_id __LOC__ "Badly_formed_constant_expression") + +(** [test_expand] accepts an expression [stored] to be + registered in the store, an expression [expr] that includes a template slot for + the hash of [stored], and an [expected] expression, and generates a test that + asserts the value of [expr] after expansion matches [expected]. *) +let make_expand_test ~stored ~expr ~expected () = + create_context () >>=? fun context -> + let stored_expr = Expr.from_string stored in + Global_constants_storage.register context stored_expr + >|= Environment.wrap_tzresult + >>=? fun (context, hash, _) -> + let expected = Expr.from_string expected in + let expr_with_constant = + Format.sprintf expr (Script_expr_hash.to_b58check hash) |> Expr.from_string + in + Global_constants_storage.expand context expr_with_constant + >|= Environment.wrap_tzresult + >>=? fun (_, result_expr) -> assert_expr_equal __LOC__ expected result_expr + +let test_expand_data_example = + tztest + "expand: data" + `Quick + (make_expand_test + ~stored:"3" + ~expr:"Pair 1 (Pair 2 (constant \"%s\"))" + ~expected:"Pair 1 (Pair 2 3)") + +let test_expand_types_example = + tztest + "expand: types" + `Quick + (make_expand_test + ~stored:"big_map string string" + ~expr:"PUSH (constant \"%s\") {}" + ~expected:"PUSH (big_map string string) {}") + +let test_expand_instr_example = + tztest + "expand: instr" + `Quick + (make_expand_test + ~stored:"PUSH int 3" + ~expr:"{ DROP; constant \"%s\"; DROP }" + ~expected:"{ DROP; PUSH int 3 ; DROP }") + +(** For any expression [e], when replacing any subexpression + [e'] with a constant hash and registering [e'], calling + [expand] on the new expression yields the + original expression [e]*) +let test_expand_pbt = + let open Michelson_v1_printer in + tztest_qcheck + ~name:"expand: random" + (pair + (Generators.context_arbitrary ()) + (Generators.canonical_with_constant_arbitrary ())) + (fun (context, (full_expr, expr_with_constant, sub_expr)) -> + assume_expr_not_too_large full_expr ; + assume_expr_not_too_large expr_with_constant ; + assume_expr_not_too_large sub_expr ; + Global_constants_storage.register context sub_expr + >|= Environment.wrap_tzresult + >>=? fun (context, _, _) -> + Global_constants_storage.expand context expr_with_constant + >|= Environment.wrap_tzresult + >|=? fun (_, result_expr) -> + qcheck_eq ~pp:print_expr full_expr result_expr) + +let test_expand_is_idempotent = + tztest_qcheck + ~name:"expand is idempotent" + (pair + (Generators.context_arbitrary ()) + (Generators.canonical_with_constant_arbitrary ())) + (fun (context, (full_expr, expr_with_constant, sub_expr)) -> + assume_expr_not_too_large full_expr ; + Global_constants_storage.register context sub_expr + >|= Environment.wrap_tzresult + >>=? fun (context, _, _) -> + Global_constants_storage.expand context expr_with_constant + >|= Environment.wrap_tzresult + >>=? fun (context, result1) -> + Global_constants_storage.expand context full_expr + >|= Environment.wrap_tzresult + >|=? fun (_, result2) -> qcheck_eq ~pp:print_expr result1 result2) + +(** [bottom_up_fold_cps] does not stack overflow even when + given large values. *) +let test_fold_does_not_stack_overflow = + tztest "bottom_up_fold_cps: does not stack overflow" `Quick (fun () -> + let node = grow 1_000_000 @@ Int ((), Z.zero) in + return @@ ignore + @@ Global_constants_storage.Internal_for_tests.bottom_up_fold_cps + () + node + (fun _ _ -> ()) + (fun _ node k -> k () node)) + +let tests = + [ + test_get_on_nonexistent_fails; + test_get_always_returns_registered_expr; + test_register_fails_with_unregistered_references; + test_register_fails_with_unregistered_references_pbt; + test_register_fails_if_too_deep; + test_expand_nonexistent_fails; + test_expand_no_constants; + test_register_and_expand_orthogonal; + test_expand_deep_constants; + test_expand_reject_ill_formed; + test_reject_use_of_inner_constant; + test_expand_data_example; + test_expand_types_example; + test_expand_instr_example; + test_expand_pbt; + test_expand_is_idempotent; + test_fold_does_not_stack_overflow; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_operation_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_operation_repr.ml new file mode 100644 index 000000000000..ee36932c65cf --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_operation_repr.ml @@ -0,0 +1,112 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Operation_repr + Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe -- test Operation_repr + Dependencies: -- + Subject: To test the modules (including the top-level) + in operation_repr.ml as individual units, particularly + failure cases. Superficial goal: increase coverage percentage. +*) +open Protocol + +open Tztest + +module Test_operation_repr = struct + open Operation_repr + + let test_of_list_single_case () = + Environment.wrap_tzresult + @@ of_list + [ + Contents + (Manager_operation + { + fee = Obj.magic 0; + operation = Obj.magic 0; + gas_limit = Obj.magic 0; + storage_limit = Obj.magic 0; + counter = Obj.magic 0; + source = Obj.magic 0; + }); + ] + >>?= fun contents_list -> + match contents_list with + | Contents_list (Single _) -> return_unit + | _ -> failwith "Unexpected value" + + let test_of_list_multiple_case () = + Environment.wrap_tzresult + @@ of_list + [ + Contents + (Manager_operation + { + fee = Obj.magic 0; + operation = Obj.magic 0; + gas_limit = Obj.magic 0; + storage_limit = Obj.magic 0; + counter = Obj.magic 0; + source = Obj.magic 0; + }); + Contents + (Manager_operation + { + fee = Obj.magic 0; + operation = Obj.magic 0; + gas_limit = Obj.magic 0; + storage_limit = Obj.magic 0; + counter = Obj.magic 0; + source = Obj.magic 0; + }); + ] + >>?= fun contents_list -> + match contents_list with + | Contents_list (Cons (_, Single _)) -> return_unit + | _ -> failwith "Unexpected value" + + let test_of_list_empty_case () = + match of_list [] with + | Ok _ -> failwith "of_list of an empty list was expected to fail" + | Error _ -> return_unit +end + +let tests = + [ + tztest + "of_list: single element input list" + `Quick + Test_operation_repr.test_of_list_single_case; + tztest + "of_list: multiple element input list" + `Quick + Test_operation_repr.test_of_list_multiple_case; + tztest + "of_list: empty input list" + `Quick + Test_operation_repr.test_of_list_empty_case; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_raw_level_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_raw_level_repr.ml new file mode 100644 index 000000000000..9543efcdf22e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_raw_level_repr.ml @@ -0,0 +1,176 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Protocol +open Tztest + +(** Testing + ------- + Component: Raw_level_repr + Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe \ + -- test '^\[Unit\] Raw_level_repr.ml$' + Dependencies: -- + Subject: To test the modules (including the top-level) + in raw_level_repr.ml as individual units, particularly + failure cases. Superficial goal: increase coverage percentage. +*) + +module Test_raw_level_repr = struct + (* NOTE: Avoid assertions against too many functions from Raw_level_repr. For instance, + Raw_level_repr contains a [compare] function, but while [Assert]'ing, convert them to + int32 (or any convenient OCaml value) and compare instead of using [Raw_level_repr]'s compare *) + + (** Testing [encoding], int32 underneath, by applying it with Data_encoding *) + let test_encoding () = + let encoding = Raw_level_repr.encoding in + let bytes = Bytes.make 4 '0' in + Bytes.set_int32_ne bytes 0 0l ; + (Data_encoding.Binary.of_bytes encoding bytes |> function + | Ok x -> Lwt.return (Ok x) + | Error e -> + failwith + "Data_encoding.Binary.read shouldn't have failed with \ + Raw_level_repr.encoding: %a" + Data_encoding.Binary.pp_read_error + e) + >>=? fun v -> + Assert.equal_int ~loc:__LOC__ (Int32.to_int (Raw_level_repr.to_int32 v)) 0 + >>=? fun () -> + Bytes.set_int32_ne bytes 0 (-1l) ; + Data_encoding.Binary.of_bytes encoding bytes |> function + | Error _ -> return_unit + | Ok x -> + failwith + "Data_encoding.Binary.read shouldn't have succeeded with %a" + Raw_level_repr.pp + x + + (* TODO rpc_arg. RPC_arg needs to be unit tested separately. Preferably, with a functor *) + (* let rpc_arg () = () *) + + (** int32 interop tests *) + let test_int32_interop () = + let int32v = 100l in + Lwt.return (Raw_level_repr.of_int32 int32v) >|= Environment.wrap_tzresult + >>=? fun raw_level -> + Assert.equal_int32 ~loc:__LOC__ (Raw_level_repr.to_int32 raw_level) int32v + >>=? fun () -> + let int32v = -1l in + (Lwt.return (Raw_level_repr.of_int32 int32v) >|= Environment.wrap_tzresult + >>= function + | Ok _ -> failwith "Negative int32s should not be coerced into raw_level" + | Error _ -> return_unit) + >>=? fun () -> + try + let _ = Raw_level_repr.of_int32_exn int32v in + failwith "Negative int32s should not be coerced into raw_level" + with Invalid_argument _ -> return_unit + + (** Asserting [root]'s runtime value. Expected to be [0l] *) + let test_root () = + let root = Raw_level_repr.root in + Assert.equal_int32 ~loc:__LOC__ (root |> Raw_level_repr.to_int32) 0l + + (** Asserting [succ] which is expected to return successor levels *) + let test_succ () = + let next_raw_level = Raw_level_repr.succ Raw_level_repr.root in + Assert.equal_int32 + ~loc:__LOC__ + (next_raw_level |> Raw_level_repr.to_int32) + 1l + >>=? fun () -> + let arbitrary_next_raw_level = + Raw_level_repr.succ (Raw_level_repr.of_int32_exn 99l) + in + Assert.equal_int32 + ~loc:__LOC__ + (arbitrary_next_raw_level |> Raw_level_repr.to_int32) + 100l + + (** Asserting [pred] which is expected to return predecessor levels *) + let test_pred () = + (match Raw_level_repr.pred (Raw_level_repr.of_int32_exn 1l) with + | Some previous_raw_level -> + Assert.equal_int32 + ~loc:__LOC__ + (previous_raw_level |> Raw_level_repr.to_int32) + 0l + | None -> + failwith + "Raw_level_repr.pred should have successfully returned 0l as the \ + predecessor of 1l") + >>=? fun () -> + Raw_level_repr.pred Raw_level_repr.root |> function + | Some _ -> + failwith + "Raw_level_repr.pred should have returned None when asked for \ + predecessor of [root]" + | None -> return_unit + + let test_skip_succ () = + let int32_limit = 0x7FFFFFFFl in + let overflown_next_raw_level = + Raw_level_repr.succ (Raw_level_repr.of_int32_exn int32_limit) + in + if Int32.compare (Raw_level_repr.to_int32 overflown_next_raw_level) 0l >= 0 + then return_unit + else + failwith + "succ of 0x7FFFFFFFl %a was expected to be non-negative" + Assert.Int32.pp + (overflown_next_raw_level |> Raw_level_repr.to_int32) +end + +let tests = + [ + tztest + "Raw_level_repr.encoding: checks if encoding is int32 as expected" + `Quick + Test_raw_level_repr.test_encoding; + tztest + "Raw_level_repr.root: check if value is 0l" + `Quick + Test_raw_level_repr.test_root; + tztest + "Raw_level_repr.succ: basic assertions" + `Quick + Test_raw_level_repr.test_succ; + tztest + "Raw_level_repr.pred: basic assertions" + `Quick + Test_raw_level_repr.test_pred; + tztest + "Raw_level_repr: int32 interop" + `Quick + Test_raw_level_repr.test_int32_interop; + ] + +let skipped_tests = + [ + tztest + "Raw_level_repr.succ: overflow" + `Quick + Test_raw_level_repr.test_skip_succ; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_tez_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_tez_repr.ml new file mode 100644 index 000000000000..6d94465845d6 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/test/unit/test_tez_repr.ml @@ -0,0 +1,202 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Tez_repr + Invocation: dune exec ./src/proto_alpha/lib_protocol/test/unit/main.exe -- test Tez_repr + Dependencies: -- + Subject: To test the modules (including the top-level) + in tez_repr.ml as individual units, particularly + failure cases. Superficial goal: increase coverage percentage. +*) +open Protocol + +open Tztest + +module Test_tez_repr = struct + (** Testing predefined units: zero, one_mutez etc *) + let test_predefined_values () = + let zero_int64 = Tez_repr.to_mutez Tez_repr.zero in + Assert.equal_int64 ~loc:__LOC__ zero_int64 0L >>=? fun () -> + let one_mutez_int64 = Tez_repr.to_mutez Tez_repr.one_mutez in + Assert.equal_int64 ~loc:__LOC__ one_mutez_int64 1L >>=? fun () -> + let one_cent_int64 = Tez_repr.to_mutez Tez_repr.one_cent in + Assert.equal_int64 ~loc:__LOC__ one_cent_int64 10000L >>=? fun () -> + let fifty_cents_int64 = Tez_repr.to_mutez Tez_repr.fifty_cents in + Assert.equal_int64 ~loc:__LOC__ fifty_cents_int64 500000L >>=? fun () -> + let one_int64 = Tez_repr.to_mutez Tez_repr.one in + Assert.equal_int64 ~loc:__LOC__ one_int64 1000000L + + let test_subtract () = + (Lwt.return @@ Tez_repr.(one -? zero)) >|= Environment.wrap_tzresult + >>=? fun res -> + Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez res) 1000000L + + let test_substract_underflow () = + (Lwt.return @@ Tez_repr.(zero -? one)) >|= Environment.wrap_tzresult + >>= function + | Ok _ -> failwith "Expected to underflow" + | Error _ -> return_unit + + let test_addition () = + (Lwt.return @@ Tez_repr.(one +? zero)) >|= Environment.wrap_tzresult + >>=? fun res -> + Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez res) 1000000L + + let test_addition_overflow () = + (Lwt.return @@ Tez_repr.(of_mutez_exn 0x7fffffffffffffffL +? one)) + >|= Environment.wrap_tzresult + >>= function + | Ok _ -> failwith "Expected to overflow" + | Error _ -> return_unit + + let test_mul () = + (Lwt.return @@ Tez_repr.(zero *? 1L)) >|= Environment.wrap_tzresult + >>=? fun res -> Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez res) 0L + + let test_mul_overflow () = + (Lwt.return @@ Tez_repr.(of_mutez_exn 0x7fffffffffffffffL *? 2L)) + >|= Environment.wrap_tzresult + >>= function + | Ok _ -> failwith "Expected to overflow" + | Error _ -> return_unit + + let test_div () = + (Lwt.return @@ Tez_repr.(one *? 1L)) >|= Environment.wrap_tzresult + >>=? fun res -> + Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez res) 1000000L + + let test_div_by_zero () = + (Lwt.return @@ Tez_repr.(one /? 0L)) >|= Environment.wrap_tzresult + >>= function + | Ok _ -> failwith "Expected to overflow" + | Error _ -> return_unit + + let test_to_mutez () = + let int64v = Tez_repr.(to_mutez one) in + Assert.equal_int64 ~loc:__LOC__ int64v 1000000L + + let test_of_mutez_non_negative () = + match Tez_repr.of_mutez 1000000L with + | Some tz -> + Assert.equal_int64 + ~loc:__LOC__ + (Tez_repr.to_mutez tz) + Tez_repr.(to_mutez one) + | None -> failwith "should have successfully converted 1000000L to tez" + + let test_of_mutez_negative () = + match Tez_repr.of_mutez (-1000000L) with + | Some _ -> failwith "should have failed to converted -1000000L to tez" + | None -> return_unit + + let test_of_mutez_exn () = + try + let tz = Tez_repr.of_mutez_exn 1000000L in + Assert.equal_int64 + ~loc:__LOC__ + (Tez_repr.to_mutez tz) + Tez_repr.(to_mutez one) + with e -> + let msg = Printexc.to_string e and stack = Printexc.get_backtrace () in + failwith "Unexpected exception: %s %s" msg stack + + let test_of_mutez_exn_negative () = + try + let _ = Tez_repr.of_mutez_exn (-1000000L) in + failwith "should have failed to converted -1000000L to tez" + with + | Invalid_argument _ -> return_unit + | e -> + let msg = Printexc.to_string e and stack = Printexc.get_backtrace () in + failwith "Unexpected exception: %s %s" msg stack + + (* NOTE: Avoid assertions against too many functions from Tez_repr. Convert them to + int64 and compare instead of using [Tez_repr]'s compare *) + + (** Testing [encoding], int64 underneath, by applying it with Data_encoding *) + let test_data_encoding () = + let encoding = Tez_repr.encoding in + let bytes = + Data_encoding.Binary.to_bytes_exn Data_encoding.n (Z.of_int 1000000) + in + (Data_encoding.Binary.of_bytes encoding bytes |> function + | Ok x -> Lwt.return (Ok x) + | Error e -> + failwith + "Data_encoding.Binary.read shouldn't have failed with \ + Tez_repr.encoding: %a" + Data_encoding.Binary.pp_read_error + e) + >>=? fun v -> Assert.equal_int64 ~loc:__LOC__ (Tez_repr.to_mutez v) 1000000L +end + +let tests = + [ + tztest + "Check if predefined values hold expected values" + `Quick + Test_tez_repr.test_predefined_values; + tztest "Tez.substract: basic behaviour" `Quick Test_tez_repr.test_subtract; + tztest + "Tez.substract: underflow case" + `Quick + Test_tez_repr.test_substract_underflow; + tztest + "Tez.add: basic behaviour (one + zero)" + `Quick + Test_tez_repr.test_addition; + tztest "Tez.add: overflow" `Quick Test_tez_repr.test_addition_overflow; + tztest "Tez.mul: basic case" `Quick Test_tez_repr.test_mul; + tztest "Tez.mul: overflow case" `Quick Test_tez_repr.test_mul_overflow; + tztest "Tez.div: basic case" `Quick Test_tez_repr.test_div; + tztest "Tez.div: division by zero" `Quick Test_tez_repr.test_div_by_zero; + tztest "Tez.to_mutez: basic assertion" `Quick Test_tez_repr.test_to_mutez; + tztest + "Tez.of_mutez: of non-negative ints" + `Quick + Test_tez_repr.test_of_mutez_non_negative; + tztest + "Tez.of_mutez: of non-negative ints" + `Quick + Test_tez_repr.test_of_mutez_non_negative; + tztest + "Tez.of_mutez: of negative ints" + `Quick + Test_tez_repr.test_of_mutez_negative; + tztest + "Tez.of_mutez_exn: of non-negative ints" + `Quick + Test_tez_repr.test_of_mutez_non_negative; + tztest + "Tez.of_mutez_exn: of negative ints" + `Quick + Test_tez_repr.test_of_mutez_negative; + tztest + "Tez.data_encoding: must encode tezzies correctly" + `Quick + Test_tez_repr.test_data_encoding; + ] diff --git a/src/proto_012_PsiThaCa/lib_protocol/tez_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/tez_repr.ml new file mode 100644 index 000000000000..5636b07a16f0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/tez_repr.ml @@ -0,0 +1,245 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let id = "tez" + +let name = "mutez" + +include Compare.Int64 (* invariant: positive *) + +type error += + | Addition_overflow of t * t (* `Temporary *) + | Subtraction_underflow of t * t (* `Temporary *) + | Multiplication_overflow of t * int64 (* `Temporary *) + | Negative_multiplicator of t * int64 (* `Temporary *) + | Invalid_divisor of t * int64 + +(* `Temporary *) + +let zero = 0L + +(* all other constant are defined from the value of one micro tez *) +let one_mutez = 1L + +let one_cent = Int64.mul one_mutez 10_000L + +let fifty_cents = Int64.mul one_cent 50L + +(* 1 tez = 100 cents = 1_000_000 mutez *) +let one = Int64.mul one_cent 100L + +let of_string s = + let triplets = function + | hd :: tl -> + let len = String.length hd in + Compare.Int.( + len <= 3 && len > 0 && List.for_all (fun s -> String.length s = 3) tl) + | [] -> false + in + let integers s = triplets (String.split_on_char ',' s) in + let decimals s = + let l = String.split_on_char ',' s in + if Compare.List_length_with.(l > 2) then false else triplets (List.rev l) + in + let parse left right = + let remove_commas s = String.concat "" (String.split_on_char ',' s) in + let pad_to_six s = + let len = String.length s in + String.init 6 (fun i -> if Compare.Int.(i < len) then s.[i] else '0') + in + Int64.of_string_opt (remove_commas left ^ pad_to_six (remove_commas right)) + in + match String.split_on_char '.' s with + | [left; right] -> + if String.contains s ',' then + if integers left && decimals right then parse left right else None + else if + Compare.Int.(String.length right > 0) + && Compare.Int.(String.length right <= 6) + then parse left right + else None + | [left] -> + if (not (String.contains s ',')) || integers left then parse left "" + else None + | _ -> None + +let pp ppf amount = + let mult_int = 1_000_000L in + let[@coq_struct "amount"] rec left ppf amount = + let (d, r) = (Int64.(div amount 1000L), Int64.(rem amount 1000L)) in + if d > 0L then Format.fprintf ppf "%a%03Ld" left d r + else Format.fprintf ppf "%Ld" r + in + let right ppf amount = + let triplet ppf v = + if Compare.Int.(v mod 10 > 0) then Format.fprintf ppf "%03d" v + else if Compare.Int.(v mod 100 > 0) then Format.fprintf ppf "%02d" (v / 10) + else Format.fprintf ppf "%d" (v / 100) + in + let (hi, lo) = (amount / 1000, amount mod 1000) in + if Compare.Int.(lo = 0) then Format.fprintf ppf "%a" triplet hi + else Format.fprintf ppf "%03d%a" hi triplet lo + in + let (ints, decs) = + (Int64.(div amount mult_int), Int64.(to_int (rem amount mult_int))) + in + left ppf ints ; + if Compare.Int.(decs > 0) then Format.fprintf ppf ".%a" right decs + +let to_string t = Format.asprintf "%a" pp t + +let ( -? ) t1 t2 = + if t2 <= t1 then ok (Int64.sub t1 t2) + else error (Subtraction_underflow (t1, t2)) + +let sub_opt t1 t2 = if t2 <= t1 then Some (Int64.sub t1 t2) else None + +let ( +? ) t1 t2 = + let t = Int64.add t1 t2 in + if t < t1 then error (Addition_overflow (t1, t2)) else ok t + +let ( *? ) t m = + if m < 0L then error (Negative_multiplicator (t, m)) + else if m = 0L then ok 0L + else if t > Int64.(div max_int m) then error (Multiplication_overflow (t, m)) + else ok (Int64.mul t m) + +let ( /? ) t d = + if d <= 0L then error (Invalid_divisor (t, d)) else ok (Int64.div t d) + +let mul_exn t m = + match t *? Int64.(of_int m) with + | Ok v -> v + | Error _ -> invalid_arg "mul_exn" + +let div_exn t d = + match t /? Int64.(of_int d) with + | Ok v -> v + | Error _ -> invalid_arg "div_exn" + +let of_mutez t = if t < 0L then None else Some t + +let of_mutez_exn x = + match of_mutez x with None -> invalid_arg "Tez.of_mutez" | Some v -> v + +let to_mutez t = t + +let encoding = + let open Data_encoding in + Data_encoding.def + name + (check_size 10 (conv Z.of_int64 (Json.wrap_error Z.to_int64) n)) + +let () = + let open Data_encoding in + register_error_kind + `Temporary + ~id:(id ^ ".addition_overflow") + ~title:("Overflowing " ^ id ^ " addition") + ~pp:(fun ppf (opa, opb) -> + Format.fprintf + ppf + "Overflowing addition of %a %s and %a %s" + pp + opa + id + pp + opb + id) + ~description:("An addition of two " ^ id ^ " amounts overflowed") + (obj1 (req "amounts" (tup2 encoding encoding))) + (function Addition_overflow (a, b) -> Some (a, b) | _ -> None) + (fun (a, b) -> Addition_overflow (a, b)) ; + register_error_kind + `Temporary + ~id:(id ^ ".subtraction_underflow") + ~title:("Underflowing " ^ id ^ " subtraction") + ~pp:(fun ppf (opa, opb) -> + Format.fprintf + ppf + "Underflowing subtraction of %a %s and %a %s" + pp + opa + id + pp + opb + id) + ~description:("A subtraction of two " ^ id ^ " amounts underflowed") + (obj1 (req "amounts" (tup2 encoding encoding))) + (function Subtraction_underflow (a, b) -> Some (a, b) | _ -> None) + (fun (a, b) -> Subtraction_underflow (a, b)) ; + register_error_kind + `Temporary + ~id:(id ^ ".multiplication_overflow") + ~title:("Overflowing " ^ id ^ " multiplication") + ~pp:(fun ppf (opa, opb) -> + Format.fprintf + ppf + "Overflowing multiplication of %a %s and %Ld" + pp + opa + id + opb) + ~description: + ("A multiplication of a " ^ id ^ " amount by an integer overflowed") + (obj2 (req "amount" encoding) (req "multiplicator" int64)) + (function Multiplication_overflow (a, b) -> Some (a, b) | _ -> None) + (fun (a, b) -> Multiplication_overflow (a, b)) ; + register_error_kind + `Temporary + ~id:(id ^ ".negative_multiplicator") + ~title:("Negative " ^ id ^ " multiplicator") + ~pp:(fun ppf (opa, opb) -> + Format.fprintf + ppf + "Multiplication of %a %s by negative integer %Ld" + pp + opa + id + opb) + ~description:("Multiplication of a " ^ id ^ " amount by a negative integer") + (obj2 (req "amount" encoding) (req "multiplicator" int64)) + (function Negative_multiplicator (a, b) -> Some (a, b) | _ -> None) + (fun (a, b) -> Negative_multiplicator (a, b)) ; + register_error_kind + `Temporary + ~id:(id ^ ".invalid_divisor") + ~title:("Invalid " ^ id ^ " divisor") + ~pp:(fun ppf (opa, opb) -> + Format.fprintf + ppf + "Division of %a %s by non positive integer %Ld" + pp + opa + id + opb) + ~description: + ("Multiplication of a " ^ id ^ " amount by a non positive integer") + (obj2 (req "amount" encoding) (req "divisor" int64)) + (function Invalid_divisor (a, b) -> Some (a, b) | _ -> None) + (fun (a, b) -> Invalid_divisor (a, b)) + +type tez = t diff --git a/src/proto_012_PsiThaCa/lib_protocol/tez_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/tez_repr.mli new file mode 100644 index 000000000000..168dcac9b04f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/tez_repr.mli @@ -0,0 +1,75 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t + +type tez = t + +val zero : t + +val one_mutez : t + +val one_cent : t + +val fifty_cents : t + +val one : t + +val ( -? ) : t -> t -> t tzresult + +(** Same as ( -? ) but returns None instead of an error. *) +val sub_opt : t -> t -> t option + +val ( +? ) : t -> t -> t tzresult + +val ( *? ) : t -> int64 -> t tzresult + +val ( /? ) : t -> int64 -> t tzresult + +val to_mutez : t -> int64 + +(** [of_mutez n] (micro tez) is None if n is negative *) +val of_mutez : int64 -> t option + +(** [of_mutez_exn n] fails if n is negative. + It should only be used at toplevel for constants. *) +val of_mutez_exn : int64 -> t + +(** It should only be used at toplevel for constants. *) +val mul_exn : t -> int -> t + +(** It should only be used at toplevel for constants. *) +val div_exn : t -> int -> t + +val encoding : t Data_encoding.t + +include Compare.S with type t := t + +val pp : Format.formatter -> t -> unit + +val of_string : string -> t option + +val to_string : t -> string diff --git a/src/proto_012_PsiThaCa/lib_protocol/tezos-embedded-protocol-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_protocol/tezos-embedded-protocol-012-PsiThaCa.opam new file mode 100644 index 000000000000..b4adacc5f3d4 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/tezos-embedded-protocol-012-PsiThaCa.opam @@ -0,0 +1,25 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-protocol-012-PsiThaCa" + "tezos-protocol-compiler" + "tezos-protocol-updater" +] +build: [ + [ + "%{tezos-protocol-compiler:lib}%/replace" + "%{tezos-protocol-compiler:lib}%/dune_protocol.template.v1" + "dune" + "%{tezos-protocol-compiler:lib}%/final_protocol_versions" + "012_PsiThaCa" + ] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: economic-protocol definition, embedded in `tezos-node`" diff --git a/src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-012-PsiThaCa-tests.opam b/src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-012-PsiThaCa-tests.opam new file mode 100644 index 000000000000..fe3eea4ba5bc --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-012-PsiThaCa-tests.opam @@ -0,0 +1,36 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-protocol-compiler" + "alcotest-lwt" { with-test & >= "1.1.0" } + "astring" { with-test } + "tezos-test-helpers" { with-test } + "qcheck-alcotest" { with-test } + "tezos-012-PsiThaCa-test-helpers" { with-test } + "tezos-stdlib-unix" { with-test } + "tezos-protocol-environment" { with-test } + "tezos-client-base" { with-test } + "tezos-protocol-012-PsiThaCa-parameters" { with-test } + "tezos-shell-services" { with-test } + "tezos-base-test-helpers" { with-test } + "tezos-benchmark" { with-test } + "tezos-benchmark-012-PsiThaCa" { with-test } +] +build: [ + [ + "%{tezos-protocol-compiler:lib}%/replace" + "%{tezos-protocol-compiler:lib}%/dune_protocol.template.v1" + "dune" + "%{tezos-protocol-compiler:lib}%/final_protocol_versions" + "012_PsiThaCa" + ] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: tests for economic-protocol definition" diff --git a/src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-012-PsiThaCa.opam new file mode 100644 index 000000000000..d5ac2fcc085f --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-012-PsiThaCa.opam @@ -0,0 +1,23 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-protocol-compiler" +] +build: [ + [ + "%{tezos-protocol-compiler:lib}%/replace" + "%{tezos-protocol-compiler:lib}%/dune_protocol.template.v1" + "dune" + "%{tezos-protocol-compiler:lib}%/final_protocol_versions" + "012_PsiThaCa" + ] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: economic-protocol definition" diff --git a/src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-functor-012-PsiThaCa.opam b/src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-functor-012-PsiThaCa.opam new file mode 100644 index 000000000000..6e13881c468d --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/tezos-protocol-functor-012-PsiThaCa.opam @@ -0,0 +1,24 @@ +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: [ "Tezos devteam" ] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "2.9" } + "tezos-protocol-012-PsiThaCa" + "tezos-protocol-compiler" +] +build: [ + [ + "%{tezos-protocol-compiler:lib}%/replace" + "%{tezos-protocol-compiler:lib}%/dune_protocol.template.v1" + "dune" + "%{tezos-protocol-compiler:lib}%/final_protocol_versions" + "012_PsiThaCa" + ] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Tezos/Protocol: economic-protocol definition parameterized by its environment implementation" diff --git a/src/proto_012_PsiThaCa/lib_protocol/ticket_balance_key.ml b/src/proto_012_PsiThaCa/lib_protocol/ticket_balance_key.ml new file mode 100644 index 000000000000..8546d3a221b8 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/ticket_balance_key.ml @@ -0,0 +1,70 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +(* This function extracts nodes of: + - Ticketer + - Type of content + - Content + - Owner + to generate at ticket-balance key-hash. +*) +let ticket_balance_key_and_amount ctxt ~owner + (Ticket_scanner.Ex_ticket + (comp_ty, Script_typed_ir.{ticketer; contents; amount})) = + let loc = Micheline.dummy_location in + Script_ir_translator.unparse_comparable_ty ~loc ctxt comp_ty + >>?= fun (cont_ty_unstripped, ctxt) -> + (* We strip the annotations from the content type in order to map + tickets with the same content type, but with different annotations, to the + same hash. *) + Gas.consume ctxt (Script.strip_annotations_cost cont_ty_unstripped) + >>?= fun ctxt -> + let typ = Script.strip_annotations cont_ty_unstripped in + let ticketer_address = (ticketer, "default") in + let owner_address = (owner, "default") in + let address_t = Script_typed_ir.address_t ~annot:None in + Script_ir_translator.unparse_data + ctxt + Script_ir_translator.Optimized_legacy + address_t + ticketer_address + >>=? fun (ticketer, ctxt) -> + Script_ir_translator.unparse_comparable_data + ~loc + ctxt + Script_ir_translator.Optimized_legacy + comp_ty + contents + >>=? fun (contents, ctxt) -> + Script_ir_translator.unparse_data + ctxt + Script_ir_translator.Optimized_legacy + address_t + owner_address + >>=? fun (owner, ctxt) -> + Ticket_balance.make_key_hash ctxt ~ticketer ~typ ~contents ~owner + >>?= fun (hash, ctxt) -> return (hash, Script_int.to_zint amount, ctxt) diff --git a/src/proto_012_PsiThaCa/lib_protocol/ticket_balance_key.mli b/src/proto_012_PsiThaCa/lib_protocol/ticket_balance_key.mli new file mode 100644 index 000000000000..a88a87bd3921 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/ticket_balance_key.mli @@ -0,0 +1,40 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module exposes a function for generating a ticket-balance key-hash + and an amount, given an owner and a ticket. The key-hash and the amount is + used for populating the global ticket-balance table that tracks ownership + of different types of tickets. + *) + +(** [ticket_balance_key_and_amount ctxt ~owner ex_ticket] returns the [key_hash] + of the given [owner] and [ex_ticket], as well as the amount of the + ticket. *) +val ticket_balance_key_and_amount : + Alpha_context.context -> + owner:Alpha_context.Contract.t -> + Ticket_scanner.ex_ticket -> + (Alpha_context.Ticket_balance.key_hash * Z.t * Alpha_context.context) tzresult + Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/ticket_costs.ml b/src/proto_012_PsiThaCa/lib_protocol/ticket_costs.ml new file mode 100644 index 000000000000..72be4eda1a76 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/ticket_costs.ml @@ -0,0 +1,52 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +module Constants = struct + module S = Saturation_repr + + (* TODO: Fill in real benchmarked values *) + let cost_contains_tickets_step = S.safe_int 28 + + (* TODO: Fill in real benchmarked values *) + let cost_collect_tickets_step = S.safe_int 360 + + (* TODO: Fill in real benchmarked values *) + let cost_has_tickets_of_ty type_size = S.mul (S.safe_int 20) type_size +end + +let consume_gas_steps ctxt ~step_cost ~num_steps = + let ( * ) = Saturation_repr.mul in + if Compare.Int.(num_steps <= 0) then Ok ctxt + else + let gas = + Gas.atomic_step_cost (step_cost * Saturation_repr.safe_int num_steps) + in + Gas.consume ctxt gas + +let has_tickets_of_ty_cost ty = + Constants.cost_has_tickets_of_ty + Script_typed_ir.(ty_size ty |> Type_size.to_int) diff --git a/src/proto_012_PsiThaCa/lib_protocol/ticket_costs.mli b/src/proto_012_PsiThaCa/lib_protocol/ticket_costs.mli new file mode 100644 index 000000000000..de052916f7de --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/ticket_costs.mli @@ -0,0 +1,53 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module contains constants and utility functions for gas metering + functions used for extracting and handling tickets for the global ticket + balance table. *) + +module Constants : sig + val cost_contains_tickets_step : Alpha_context.Gas.cost + + val cost_collect_tickets_step : Alpha_context.Gas.cost +end + +(** [consume_gas_steps ctxt ~num_steps] consumes gas corresponding to + a given [num_steps] and [step_cost]. It's useful for paying for gas + upfront where the number of steps can be determined. + + This function is generic and should probably be moved. See issue + https://gitlab.com/tezos/tezos/-/issues/1950. + + *) +val consume_gas_steps : + Alpha_context.t -> + step_cost:Alpha_context.Gas.cost -> + num_steps:int -> + Alpha_context.t tzresult + +(** [has_tickets_of_ty_cost ty] returns the cost of producing a [has_tickets], + used internally in the [Ticket_scanner] module. *) +val has_tickets_of_ty_cost : + 'a Script_typed_ir.ty -> Saturation_repr.may_saturate Saturation_repr.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/ticket_scanner.ml b/src/proto_012_PsiThaCa/lib_protocol/ticket_scanner.ml new file mode 100644 index 000000000000..ae4281f2cfa1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/ticket_scanner.ml @@ -0,0 +1,515 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +(* Impossible error *) +type error += Unsupported_type_invariant_violated + +type error += Unsupported_non_empty_overlay | Unsupported_type_operation + +let () = + register_error_kind + `Branch + ~id:"Unsupported_non_empty_overlay" + ~title:"Unsupported non empty overlay" + ~description:"Unsupported big-map value with non-empty overlay" + ~pp:(fun ppf () -> + Format.fprintf ppf "Unsupported big-map value with non-empty overlay") + Data_encoding.empty + (function Unsupported_non_empty_overlay -> Some () | _ -> None) + (fun () -> Unsupported_non_empty_overlay) ; + register_error_kind + `Branch + ~id:"Unsupported_type_operation" + ~title:"Unsupported type operation" + ~description:"Types embedding operations are not supported" + ~pp:(fun ppf () -> + Format.fprintf ppf "Types embedding operations are not supported") + Data_encoding.empty + (function Unsupported_type_operation -> Some () | _ -> None) + (fun () -> Unsupported_type_operation) + +type ex_ticket = + | Ex_ticket : + 'a Script_typed_ir.comparable_ty * 'a Script_typed_ir.ticket + -> ex_ticket + +module Ticket_inspection = struct + (* TODO: 1951 + Replace with use of meta-data for ['a ty] type. + Once ['a ty] values can be extended with custom meta data, this type + can be removed. + *) + (** + Witness flag for whether a type can be populated by a value containing a + ticket. [False_ht] must be used only when a value of the type cannot + contain a ticket. + + This flag is necessary for avoiding ticket collection (see below) to have + quadratic complexity in the order of: size-of-the-type * size-of-value. + + This type is local to the [Ticket_scanner] module and should not be + exported. + + *) + type 'a has_tickets = + | True_ht : _ Script_typed_ir.ticket has_tickets + | False_ht : _ has_tickets + | Pair_ht : + 'a has_tickets * 'b has_tickets + -> ('a, 'b) Script_typed_ir.pair has_tickets + | Union_ht : + 'a has_tickets * 'b has_tickets + -> ('a, 'b) Script_typed_ir.union has_tickets + | Option_ht : 'a has_tickets -> 'a option has_tickets + | List_ht : 'a has_tickets -> 'a Script_typed_ir.boxed_list has_tickets + | Set_ht : 'k has_tickets -> 'k Script_typed_ir.set has_tickets + | Map_ht : + 'k has_tickets * 'v has_tickets + -> ('k, 'v) Script_typed_ir.map has_tickets + | Big_map_ht : + 'k has_tickets * 'v has_tickets + -> ('k, 'v) Script_typed_ir.big_map has_tickets + + (* Returns whether or not a comparable type embeds tickets. Currently + this function returns [false] for all input. + + The only reason we keep this code is so that in the future, if tickets were + ever to be comparable, the compiler would detect a missing pattern match + case. + + Note that in case tickets are made comparable, this function needs to change + so that constructors like [Union_key] and [Pair_key] are traversed + recursively. + *) + let has_tickets_of_comparable : + type a ret. + a Script_typed_ir.comparable_ty -> (a has_tickets -> ret) -> ret = + fun key_ty k -> + let open Script_typed_ir in + match key_ty with + | Unit_key _ -> (k [@ocaml.tailcall]) False_ht + | Never_key _ -> (k [@ocaml.tailcall]) False_ht + | Int_key _ -> (k [@ocaml.tailcall]) False_ht + | Nat_key _ -> (k [@ocaml.tailcall]) False_ht + | Signature_key _ -> (k [@ocaml.tailcall]) False_ht + | String_key _ -> (k [@ocaml.tailcall]) False_ht + | Bytes_key _ -> (k [@ocaml.tailcall]) False_ht + | Mutez_key _ -> (k [@ocaml.tailcall]) False_ht + | Bool_key _ -> (k [@ocaml.tailcall]) False_ht + | Key_hash_key _ -> (k [@ocaml.tailcall]) False_ht + | Key_key _ -> (k [@ocaml.tailcall]) False_ht + | Timestamp_key _ -> (k [@ocaml.tailcall]) False_ht + | Chain_id_key _ -> (k [@ocaml.tailcall]) False_ht + | Address_key _ -> (k [@ocaml.tailcall]) False_ht + | Pair_key ((_, _), (_, _), _) -> (k [@ocaml.tailcall]) False_ht + | Union_key (_, (_, _), _) -> (k [@ocaml.tailcall]) False_ht + | Option_key (_, _) -> (k [@ocaml.tailcall]) False_ht + + (* Short circuit pairing of two [has_tickets] values. + If neither left nor right branch contains a ticket, [False_ht] is + returned. *) + let pair_has_tickets pair ht1 ht2 = + match (ht1, ht2) with (False_ht, False_ht) -> False_ht | _ -> pair ht1 ht2 + + let map_has_tickets map ht = + match ht with False_ht -> False_ht | _ -> map ht + + type ('a, 'r) continuation = 'a has_tickets -> 'r tzresult + + (* Creates a [has_tickets] type-witness value from the given ['a ty]. + The returned value matches the given shape of the [ty] value, except + it collapses whole branches where no types embed tickets to [False_ht]. + *) + let rec has_tickets_of_ty : + type a ret. a Script_typed_ir.ty -> (a, ret) continuation -> ret tzresult + = + fun ty k -> + let open Script_typed_ir in + match ty with + | Ticket_t _ -> (k [@ocaml.tailcall]) True_ht + | Unit_t _ -> (k [@ocaml.tailcall]) False_ht + | Int_t _ -> (k [@ocaml.tailcall]) False_ht + | Nat_t _ -> (k [@ocaml.tailcall]) False_ht + | Signature_t _ -> (k [@ocaml.tailcall]) False_ht + | String_t _ -> (k [@ocaml.tailcall]) False_ht + | Bytes_t _ -> (k [@ocaml.tailcall]) False_ht + | Mutez_t _ -> (k [@ocaml.tailcall]) False_ht + | Key_hash_t _ -> (k [@ocaml.tailcall]) False_ht + | Key_t _ -> (k [@ocaml.tailcall]) False_ht + | Timestamp_t _ -> (k [@ocaml.tailcall]) False_ht + | Address_t _ -> (k [@ocaml.tailcall]) False_ht + | Bool_t _ -> (k [@ocaml.tailcall]) False_ht + | Pair_t ((ty1, _, _), (ty2, _, _), _) -> + (has_tickets_of_pair [@ocaml.tailcall]) + ty1 + ty2 + ~pair:(fun ht1 ht2 -> Pair_ht (ht1, ht2)) + k + | Union_t ((ty1, _), (ty2, _), _) -> + (has_tickets_of_pair [@ocaml.tailcall]) + ty1 + ty2 + ~pair:(fun ht1 ht2 -> Union_ht (ht1, ht2)) + k + | Lambda_t (_, _, _) -> + (* As of H, closures cannot contain tickets because APPLY requires + a packable type and tickets are not packable. *) + (k [@ocaml.tailcall]) False_ht + | Option_t (ty, _) -> + (has_tickets_of_ty [@ocaml.tailcall]) ty (fun ht -> + let opt_hty = map_has_tickets (fun ht -> Option_ht ht) ht in + (k [@ocaml.tailcall]) opt_hty) + | List_t (ty, _) -> + (has_tickets_of_ty [@ocaml.tailcall]) ty (fun ht -> + let list_hty = map_has_tickets (fun ht -> List_ht ht) ht in + (k [@ocaml.tailcall]) list_hty) + | Set_t (key_ty, _) -> + (has_tickets_of_comparable [@ocaml.tailcall]) key_ty (fun ht -> + let set_hty = map_has_tickets (fun ht -> Set_ht ht) ht in + (k [@ocaml.tailcall]) set_hty) + | Map_t (key_ty, val_ty, _) -> + (has_tickets_of_key_and_value [@ocaml.tailcall]) + key_ty + val_ty + ~pair:(fun ht1 ht2 -> Map_ht (ht1, ht2)) + k + | Big_map_t (key_ty, val_ty, _) -> + (has_tickets_of_key_and_value [@ocaml.tailcall]) + key_ty + val_ty + ~pair:(fun ht1 ht2 -> Big_map_ht (ht1, ht2)) + k + | Contract_t _ -> (k [@ocaml.tailcall]) False_ht + | Sapling_transaction_t _ -> (k [@ocaml.tailcall]) False_ht + | Sapling_state_t _ -> (k [@ocaml.tailcall]) False_ht + | Operation_t _ -> + (* Operations may contain tickets but they should never be passed + why we fail in this case. *) + error Unsupported_type_operation + | Chain_id_t _ -> (k [@ocaml.tailcall]) False_ht + | Never_t _ -> (k [@ocaml.tailcall]) False_ht + | Bls12_381_g1_t _ -> (k [@ocaml.tailcall]) False_ht + | Bls12_381_g2_t _ -> (k [@ocaml.tailcall]) False_ht + | Bls12_381_fr_t _ -> (k [@ocaml.tailcall]) False_ht + | Chest_t _ -> (k [@ocaml.tailcall]) False_ht + | Chest_key_t _ -> (k [@ocaml.tailcall]) False_ht + + and has_tickets_of_pair : + type a b c ret. + a Script_typed_ir.ty -> + b Script_typed_ir.ty -> + pair:(a has_tickets -> b has_tickets -> c has_tickets) -> + (c, ret) continuation -> + ret tzresult = + fun ty1 ty2 ~pair k -> + (has_tickets_of_ty [@ocaml.tailcall]) ty1 (fun ht1 -> + (has_tickets_of_ty [@ocaml.tailcall]) ty2 (fun ht2 -> + (k [@ocaml.tailcall]) (pair_has_tickets pair ht1 ht2))) + + and has_tickets_of_key_and_value : + type k v t ret. + k Script_typed_ir.comparable_ty -> + v Script_typed_ir.ty -> + pair:(k has_tickets -> v has_tickets -> t has_tickets) -> + (t, ret) continuation -> + ret tzresult = + fun key_ty val_ty ~pair k -> + (has_tickets_of_comparable [@ocaml.tailcall]) key_ty (fun ht1 -> + (has_tickets_of_ty [@ocaml.tailcall]) val_ty (fun ht2 -> + (k [@ocaml.tailcall]) (pair_has_tickets pair ht1 ht2))) + + let has_tickets_of_ty ctxt ty = + Gas.consume ctxt (Ticket_costs.has_tickets_of_ty_cost ty) >>? fun ctxt -> + has_tickets_of_ty ty ok >|? fun ht -> (ht, ctxt) +end + +module Ticket_collection = struct + let consume_gas_steps = + Ticket_costs.consume_gas_steps + ~step_cost:Ticket_costs.Constants.cost_collect_tickets_step + + type accumulator = ex_ticket list + + type 'a continuation = + Alpha_context.context -> accumulator -> 'a tzresult Lwt.t + + (* Currently this always returns the original list. + + If comparables are ever extended to support tickets, this function + needs to be modified. In particular constructors like [Option] and [Pair] + would have to recurse on their arguments. *) + + let tickets_of_comparable : + type a ret. + Alpha_context.context -> + a Script_typed_ir.comparable_ty -> + accumulator -> + ret continuation -> + ret tzresult Lwt.t = + fun ctxt comp_ty acc k -> + let open Script_typed_ir in + match comp_ty with + | Unit_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Never_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Int_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Nat_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Signature_key _ -> (k [@ocaml.tailcall]) ctxt acc + | String_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Bytes_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Mutez_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Bool_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Key_hash_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Key_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Timestamp_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Chain_id_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Address_key _ -> (k [@ocaml.tailcall]) ctxt acc + | Pair_key ((_, _), (_, _), _) -> (k [@ocaml.tailcall]) ctxt acc + | Union_key ((_, _), (_, _), _) -> (k [@ocaml.tailcall]) ctxt acc + | Option_key (_, _) -> (k [@ocaml.tailcall]) ctxt acc + + let tickets_of_set : + type a ret. + Alpha_context.context -> + a Script_typed_ir.comparable_ty -> + a Script_typed_ir.set -> + accumulator -> + ret continuation -> + ret tzresult Lwt.t = + fun ctxt key_ty _set acc k -> + consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> + (* This is only invoked to support any future extensions making tickets + comparable. *) + (tickets_of_comparable [@ocaml.tailcall]) ctxt key_ty acc k + + let rec tickets_of_value : + type a ret. + include_lazy:bool -> + Alpha_context.context -> + a Ticket_inspection.has_tickets -> + a Script_typed_ir.ty -> + a -> + accumulator -> + ret continuation -> + ret tzresult Lwt.t = + fun ~include_lazy ctxt hty ty x acc k -> + let open Script_typed_ir in + consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> + match (hty, ty) with + | (False_ht, _) -> (k [@ocaml.tailcall]) ctxt acc + | (Pair_ht (hty1, hty2), Pair_t ((ty1, _, _), (ty2, _, _), _)) -> + let (l, r) = x in + (tickets_of_value [@ocaml.tailcall]) + ~include_lazy + ctxt + hty1 + ty1 + l + acc + (fun ctxt acc -> + (tickets_of_value [@ocaml.tailcall]) + ~include_lazy + ctxt + hty2 + ty2 + r + acc + k) + | (Union_ht (htyl, htyr), Union_t ((tyl, _), (tyr, _), _)) -> ( + match x with + | L v -> + (tickets_of_value [@ocaml.tailcall]) + ~include_lazy + ctxt + htyl + tyl + v + acc + k + | R v -> + (tickets_of_value [@ocaml.tailcall]) + ~include_lazy + ctxt + htyr + tyr + v + acc + k) + | (Option_ht el_hty, Option_t (el_ty, _)) -> ( + match x with + | Some x -> + (tickets_of_value [@ocaml.tailcall]) + ~include_lazy + ctxt + el_hty + el_ty + x + acc + k + | None -> (k [@ocaml.tailcall]) ctxt acc) + | (List_ht el_hty, List_t (el_ty, _)) -> + let {elements; _} = x in + (tickets_of_list [@ocaml.tailcall]) + ctxt + ~include_lazy + el_hty + el_ty + elements + acc + k + | (Set_ht _, Set_t (key_ty, _)) -> + (tickets_of_set [@ocaml.tailcall]) ctxt key_ty x acc k + | (Map_ht (_, val_hty), Map_t (key_ty, val_ty, _)) -> + (tickets_of_comparable [@ocaml.tailcall]) + ctxt + key_ty + acc + (fun ctxt acc -> + (tickets_of_map [@ocaml.tailcall]) + ctxt + ~include_lazy + val_hty + val_ty + x + acc + k) + | (Big_map_ht (_, val_hty), Big_map_t (key_ty, _, _)) -> + if include_lazy then + (tickets_of_big_map [@ocaml.tailcall]) ctxt val_hty key_ty x acc k + else (k [@ocaml.tailcall]) ctxt acc + | (True_ht, Ticket_t (comp_ty, _)) -> + (k [@ocaml.tailcall]) ctxt (Ex_ticket (comp_ty, x) :: acc) + | _ -> fail Unsupported_type_invariant_violated + + and tickets_of_list : + type a ret. + Alpha_context.context -> + include_lazy:bool -> + a Ticket_inspection.has_tickets -> + a Script_typed_ir.ty -> + a list -> + accumulator -> + ret continuation -> + ret tzresult Lwt.t = + fun ctxt ~include_lazy el_hty el_ty elements acc k -> + consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> + match elements with + | elem :: elems -> + (tickets_of_value [@ocaml.tailcall]) + ~include_lazy + ctxt + el_hty + el_ty + elem + acc + (fun ctxt acc -> + (tickets_of_list [@ocaml.tailcall]) + ~include_lazy + ctxt + el_hty + el_ty + elems + acc + k) + | [] -> (k [@ocaml.tailcall]) ctxt acc + + and tickets_of_map : + type k v ret. + include_lazy:bool -> + Alpha_context.context -> + v Ticket_inspection.has_tickets -> + v Script_typed_ir.ty -> + (k, v) Script_typed_ir.map -> + accumulator -> + ret continuation -> + ret tzresult Lwt.t = + fun ~include_lazy ctxt val_hty val_ty (module M) acc k -> + consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> + (* Pay gas for folding over the values *) + consume_gas_steps ctxt ~num_steps:M.size >>?= fun ctxt -> + let values = M.OPS.fold (fun _ v vs -> v :: vs) M.boxed [] in + (tickets_of_list [@ocaml.tailcall]) + ~include_lazy + ctxt + val_hty + val_ty + values + acc + k + + and tickets_of_big_map : + type k v ret. + Alpha_context.context -> + v Ticket_inspection.has_tickets -> + k Script_typed_ir.comparable_ty -> + (k, v) Script_typed_ir.big_map -> + accumulator -> + ret continuation -> + ret tzresult Lwt.t = + fun ctxt + val_hty + key_ty + {Script_typed_ir.id; diff = {map = _; size}; key_type = _; value_type} + acc + k -> + consume_gas_steps ctxt ~num_steps:1 >>?= fun ctxt -> + (* Require empty overlay *) + if Compare.Int.(size > 0) then fail Unsupported_non_empty_overlay + else + (* Traverse the keys for tickets, although currently keys should never + contain any tickets. *) + (tickets_of_comparable [@ocaml.tailcall]) ctxt key_ty acc (fun ctxt acc -> + (* Accumulate tickets from values of the big-map stored in the context *) + match id with + | Some id -> + let accum (values, ctxt) exp = + Script_ir_translator.parse_data + ~legacy:true + ctxt + ~allow_forged:true + value_type + (Micheline.root exp) + >|=? fun (v, ctxt) -> (v :: values, ctxt) + in + Big_map.list_values ctxt id >>=? fun (ctxt, exps) -> + List.fold_left_es accum ([], ctxt) exps >>=? fun (values, ctxt) -> + (tickets_of_list [@ocaml.tailcall]) + ~include_lazy:true + ctxt + val_hty + value_type + values + acc + k + | None -> (k [@ocaml.tailcall]) ctxt acc) + + let tickets_of_value ctxt ~include_lazy ty x = + Ticket_inspection.has_tickets_of_ty ctxt ty >>?= fun (ht, ctxt) -> + tickets_of_value ctxt ~include_lazy ht ty x [] (fun ctxt ex_tickets -> + return (ex_tickets, ctxt)) +end + +let tickets_of_value ctxt = Ticket_collection.tickets_of_value ctxt diff --git a/src/proto_012_PsiThaCa/lib_protocol/ticket_scanner.mli b/src/proto_012_PsiThaCa/lib_protocol/ticket_scanner.mli new file mode 100644 index 000000000000..b5f859a89c4e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/ticket_scanner.mli @@ -0,0 +1,55 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** This module provides an API for extracting tickets of arbitrary types + from an OCaml values, given a type-witness. *) + +(** A type for representing existentially quantified tickets (tickets with + different types of payloads). An [ex_ticket] value consists of: + - A type-witness representing the type of the content of the ticket. + - A ticket value of the particular content type. + *) +type ex_ticket = + | Ex_ticket : + 'a Script_typed_ir.comparable_ty * 'a Script_typed_ir.ticket + -> ex_ticket + +(** [tickets_of_value ctxt ~include_lazy ty value] extracts all tickets from the + given shape [ty] and value [value]. The [include_lazy] flag determines whether + or not to traverse lazy structures (values from the context). + In case the [include_lazy] flag is [true], any big-map contained in the value + must have an empty overlay or else an error of type + [Unsupported_non_empty_overlay] is returned. The reason for this restriction + is that we assume that all lazy big-map diffs should be applied before + calling this function. Dealing with non-empty overlays would be possible + in theory, but practically difficult. The challenge is to distinguish + between overlapping keys between the context and the overlay. + *) +val tickets_of_value : + Alpha_context.context -> + include_lazy:bool -> + 'a Script_typed_ir.ty -> + 'a -> + (ex_ticket list * Alpha_context.context) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/ticket_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/ticket_storage.ml new file mode 100644 index 000000000000..9e97567d1708 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/ticket_storage.ml @@ -0,0 +1,119 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type key_hash = Script_expr_hash.t + +type error += + | Negative_ticket_balance of {key : Script_expr_hash.t; balance : Z.t} + | Failed_to_hash_node + +let script_expr_hash_of_key_hash key_hash = key_hash + +let hash_bytes_cost bytes = + let module S = Saturation_repr in + let ( + ) = S.add in + let v0 = S.safe_int @@ Bytes.length bytes in + let ( lsr ) = S.shift_right in + S.safe_int 200 + (v0 + (v0 lsr 2)) |> Gas_limit_repr.atomic_step_cost + +let hash_of_node ctxt node = + Raw_context.consume_gas ctxt (Script_repr.strip_locations_cost node) + >>? fun ctxt -> + let node = Micheline.strip_locations node in + match Data_encoding.Binary.to_bytes_opt Script_repr.expr_encoding node with + | Some bytes -> + Raw_context.consume_gas ctxt (hash_bytes_cost bytes) >|? fun ctxt -> + (Script_expr_hash.hash_bytes [bytes], ctxt) + | None -> error Failed_to_hash_node + +let make_key_hash ctxt ~ticketer ~typ ~contents ~owner = + hash_of_node ctxt + @@ Micheline.Seq (Micheline.dummy_location, [ticketer; typ; contents; owner]) + +let () = + let open Data_encoding in + register_error_kind + `Permanent + ~id:"Negative_ticket_balance" + ~title:"Negative ticket balance" + ~description:"Attempted to set a negative ticket balance value" + ~pp:(fun ppf (key, balance) -> + Format.fprintf + ppf + "Attempted to set negative ticket balance value '%a' for key %a." + Z.pp_print + balance + Script_expr_hash.pp + key) + (obj2 (req "key" Script_expr_hash.encoding) (req "balance" Data_encoding.z)) + (function + | Negative_ticket_balance {key; balance} -> Some (key, balance) + | _ -> None) + (fun (key, balance) -> Negative_ticket_balance {key; balance}) ; + register_error_kind + `Branch + ~id:"Failed_to_hash_node" + ~title:"Failed to hash node" + ~description:"Failed to hash node for a key in the ticket-balance table" + ~pp:(fun ppf () -> + Format.fprintf + ppf + "Failed to hash node for a key in the ticket-balance table") + Data_encoding.empty + (function Failed_to_hash_node -> Some () | _ -> None) + (fun () -> Failed_to_hash_node) + +let get_balance ctxt key = + Storage.Ticket_balance.Table.find ctxt key >|=? fun (ctxt, res) -> (res, ctxt) + +let set_balance ctxt key balance = + let cost_of_key = Z.of_int 65 in + fail_when + Compare.Z.(balance < Z.zero) + (Negative_ticket_balance {key; balance}) + >>=? fun () -> + if Compare.Z.(balance = Z.zero) then + Storage.Ticket_balance.Table.remove ctxt key + >|=? fun (ctxt, freed, existed) -> + (* If we remove an existing entry, then we return the freed size for + both the key and the value. *) + let freed = + if existed then Z.neg @@ Z.add cost_of_key (Z.of_int freed) else Z.zero + in + (freed, ctxt) + else + Storage.Ticket_balance.Table.add ctxt key balance + >|=? fun (ctxt, size_diff, existed) -> + let size_diff = + let z_diff = Z.of_int size_diff in + (* For a new entry we also charge the space for storing the key *) + if existed then z_diff else Z.add cost_of_key z_diff + in + (size_diff, ctxt) + +let adjust_balance ctxt key ~delta = + get_balance ctxt key >>=? fun (res, ctxt) -> + let old_balance = Option.value ~default:Z.zero res in + set_balance ctxt key (Z.add old_balance delta) diff --git a/src/proto_012_PsiThaCa/lib_protocol/ticket_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/ticket_storage.mli new file mode 100644 index 000000000000..c116eb052177 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/ticket_storage.mli @@ -0,0 +1,71 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Trili Tech, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** A value of type [key_hash] is a hashed combination of: + - Ticketer + - Content type + - Content + - Owner +*) +type key_hash + +(** [script_expr_hash_of_key_hash key_hash] returns a [Script_expr_hash.t] value + representation of the given [key_hash]. This is useful for comparing and + pretty-printing key-hash values. *) +val script_expr_hash_of_key_hash : key_hash -> Script_expr_hash.t + +(** [make_key_hash ctxt ~ticketer ~typ ~contents ~owner] creates a hashed + representation of the given [ticketer], [typ], [contents] and [owner]. +*) +val make_key_hash : + Raw_context.t -> + ticketer:Script_repr.node -> + typ:Script_repr.node -> + contents:Script_repr.node -> + owner:Script_repr.node -> + (key_hash * Raw_context.t) tzresult + +(** [get_balance ctxt key] receives the ticket balance for the given + [key] in the context [ctxt]. The [key] represents a ticket content and a + ticket creator pair. In case there exists no value for the given [key], + [None] is returned. + *) +val get_balance : + Raw_context.t -> key_hash -> (Z.t option * Raw_context.t) tzresult Lwt.t + +(** [adjust_balance ctxt key ~delta] adjusts the balance of the + given key (representing a ticket content, creator and owner pair) + and [delta]. The value of [delta] can be positive as well as negative. + If there is no pre-exising balance for the given ticket type and owner, + it is assumed to be 0 and the new balance is [delta]. The function also + returns the difference between the old and the new size of the storage. + Note that the difference may be negative. For example, because when + setting the balance to zero, an entry is removed. + + The function fails with a [Negative_ticket_balance] error + in case the resulting balance is negative. + *) +val adjust_balance : + Raw_context.t -> key_hash -> delta:Z.t -> (Z.t * Raw_context.t) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/time_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/time_repr.ml new file mode 100644 index 000000000000..d19897b7122e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/time_repr.ml @@ -0,0 +1,73 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +include Time + +type time = Time.t + +type error += Timestamp_add (* `Permanent *) + +type error += Timestamp_sub (* `Permanent *) + +let () = + register_error_kind + `Permanent + ~id:"timestamp_add" + ~title:"Timestamp add" + ~description:"Overflow when adding timestamps." + ~pp:(fun ppf () -> Format.fprintf ppf "Overflow when adding timestamps.") + Data_encoding.empty + (function Timestamp_add -> Some () | _ -> None) + (fun () -> Timestamp_add) ; + register_error_kind + `Permanent + ~id:"timestamp_sub" + ~title:"Timestamp sub" + ~description:"Subtracting timestamps resulted in negative period." + ~pp:(fun ppf () -> + Format.fprintf ppf "Subtracting timestamps resulted in negative period.") + Data_encoding.empty + (function Timestamp_sub -> Some () | _ -> None) + (fun () -> Timestamp_sub) + +let of_seconds_string s = Option.map Time.of_seconds (Int64.of_string_opt s) + +let to_seconds_string s = Int64.to_string (to_seconds s) + +let pp = pp_hum + +let ( +? ) x y = + let span = Period_repr.to_seconds y in + let t64 = Time.add x span in + (* As long as span and time representations are int64, we cannont overflow if + x is negative. *) + if x < Time.of_seconds 0L then ok t64 + else if t64 < Time.of_seconds 0L then error Timestamp_add + else ok t64 + +let ( -? ) x y = + record_trace Timestamp_sub (Period_repr.of_seconds (Time.diff x y)) + +let ( - ) x y = + Time.of_seconds Int64.(sub (Time.to_seconds x) (Period_repr.to_seconds y)) diff --git a/src/proto_012_PsiThaCa/lib_protocol/time_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/time_repr.mli new file mode 100644 index 000000000000..c35b2da6f283 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/time_repr.mli @@ -0,0 +1,55 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include module type of struct + include Time +end + +(** Internal timestamp representation. *) +type time = t + +(** Pretty-prints the time stamp using RFC3339 format. *) +val pp : Format.formatter -> t -> unit + +(** Parses RFC3339 representation and returns a timestamp. *) +val of_seconds_string : string -> time option + +(** Returns the timestamp encoded in RFC3339 format. *) +val to_seconds_string : time -> string + +(** Adds a time span to a timestamp. + This function fails on integer overflow *) +val ( +? ) : time -> Period_repr.t -> time tzresult + +(** Returns the difference between two timestamps as a time span. + This function fails when the difference is negative *) +val ( -? ) : time -> time -> Period_repr.t tzresult + +(** [t - p] Returns a timestamps [p] seconds before [t]. + + TODO: https://gitlab.com/tezos/tezos/-/issues/2054 + This function should be made available in the environment. + *) +val ( - ) : time -> Period_repr.t -> time diff --git a/src/proto_012_PsiThaCa/lib_protocol/token.ml b/src/proto_012_PsiThaCa/lib_protocol/token.ml new file mode 100644 index 000000000000..957eff96a669 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/token.ml @@ -0,0 +1,266 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type container = + [ `Contract of Contract_repr.t + | `Collected_commitments of Blinded_public_key_hash.t + | `Delegate_balance of Signature.Public_key_hash.t + | `Frozen_deposits of Signature.Public_key_hash.t + | `Block_fees + | `Legacy_deposits of Signature.Public_key_hash.t * Cycle_repr.t + | `Legacy_fees of Signature.Public_key_hash.t * Cycle_repr.t + | `Legacy_rewards of Signature.Public_key_hash.t * Cycle_repr.t ] + +type source = + [ `Invoice + | `Bootstrap + | `Initial_commitments + | `Revelation_rewards + | `Double_signing_evidence_rewards + | `Endorsing_rewards + | `Baking_rewards + | `Baking_bonuses + | `Minted + | `Liquidity_baking_subsidies + | container ] + +type sink = + [ `Storage_fees + | `Double_signing_punishments + | `Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool + | `Burned + | container ] + +let allocated ctxt stored = + match stored with + | `Contract contract -> Contract_storage.allocated ctxt contract + | `Collected_commitments bpkh -> Commitment_storage.exists ctxt bpkh >|= ok + | `Delegate_balance delegate -> + let contract = Contract_repr.implicit_contract delegate in + Contract_storage.allocated ctxt contract + | `Frozen_deposits delegate -> + let contract = Contract_repr.implicit_contract delegate in + Frozen_deposits_storage.allocated ctxt contract >|= ok + | `Block_fees -> return_true + (* TODO: remove in J *) + | `Legacy_deposits (delegate, cycle) -> + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Legacy_frozen_deposits.mem (ctxt, contract) cycle >|= ok + | `Legacy_fees (delegate, cycle) -> + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Legacy_frozen_fees.mem (ctxt, contract) cycle >|= ok + | `Legacy_rewards (delegate, cycle) -> + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Legacy_frozen_rewards.mem (ctxt, contract) cycle >|= ok + +let balance ctxt stored = + match stored with + | `Contract contract -> Contract_storage.get_balance ctxt contract + | `Collected_commitments bpkh -> Commitment_storage.committed_amount ctxt bpkh + | `Delegate_balance delegate -> + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Balance.get ctxt contract + | `Frozen_deposits delegate -> ( + let contract = Contract_repr.implicit_contract delegate in + Frozen_deposits_storage.find ctxt contract >|=? fun frozen_deposits -> + match frozen_deposits with + | None -> Tez_repr.zero + | Some frozen_deposits -> frozen_deposits.current_amount) + | `Block_fees -> return (Raw_context.get_collected_fees ctxt) + (* TODO: remove in J *) + | `Legacy_deposits (delegate, cycle) -> + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Legacy_frozen_deposits.find (ctxt, contract) cycle + >|=? Option.value ~default:Tez_repr.zero + | `Legacy_fees (delegate, cycle) -> + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Legacy_frozen_fees.find (ctxt, contract) cycle + >|=? Option.value ~default:Tez_repr.zero + | `Legacy_rewards (delegate, cycle) -> + let contract = Contract_repr.implicit_contract delegate in + Storage.Contract.Legacy_frozen_rewards.find (ctxt, contract) cycle + >|=? Option.value ~default:Tez_repr.zero + +let credit ctxt dest amount origin = + let open Receipt_repr in + (match dest with + | `Storage_fees -> return (ctxt, Storage_fees) + | `Double_signing_punishments -> return (ctxt, Double_signing_punishments) + | `Lost_endorsing_rewards (d, p, r) -> + return (ctxt, Lost_endorsing_rewards (d, p, r)) + | `Burned -> return (ctxt, Burned) + | `Contract dest -> + Contract_storage.credit_only_call_from_token ctxt dest amount + >|=? fun ctxt -> (ctxt, Contract dest) + | `Collected_commitments bpkh -> + Commitment_storage.increase_commitment_only_call_from_token + ctxt + bpkh + amount + >|=? fun ctxt -> (ctxt, Commitments bpkh) + | `Delegate_balance delegate -> + let contract = Contract_repr.implicit_contract delegate in + Contract_storage.increase_balance_only_call_from_token + ctxt + contract + amount + >|=? fun ctxt -> (ctxt, Contract contract) + | `Frozen_deposits delegate as dest -> + allocated ctxt dest >>=? fun allocated -> + (if not allocated then Frozen_deposits_storage.init ctxt delegate + else return ctxt) + >>=? fun ctxt -> + Frozen_deposits_storage.credit_only_call_from_token ctxt delegate amount + >|=? fun ctxt -> (ctxt, Deposits delegate) + | `Block_fees -> + Raw_context.credit_collected_fees_only_call_from_token ctxt amount + >>?= fun ctxt -> return (ctxt, Block_fees) + (* TODO: remove in J *) + | `Legacy_deposits (delegate, cycle) as dest -> + let contract = Contract_repr.implicit_contract delegate in + balance ctxt dest >>=? fun old_amount -> + Tez_repr.(old_amount +? amount) >>?= fun new_amount -> + Storage.Contract.Legacy_frozen_deposits.add + (ctxt, contract) + cycle + new_amount + >>= fun ctxt -> return (ctxt, Legacy_deposits (delegate, cycle)) + | `Legacy_fees (delegate, cycle) as dest -> + let contract = Contract_repr.implicit_contract delegate in + balance ctxt dest >>=? fun old_amount -> + Tez_repr.(old_amount +? amount) >>?= fun new_amount -> + Storage.Contract.Legacy_frozen_fees.add (ctxt, contract) cycle new_amount + >>= fun ctxt -> return (ctxt, Legacy_fees (delegate, cycle)) + | `Legacy_rewards (delegate, cycle) as dest -> + let contract = Contract_repr.implicit_contract delegate in + balance ctxt dest >>=? fun old_amount -> + Tez_repr.(old_amount +? amount) >>?= fun new_amount -> + Storage.Contract.Legacy_frozen_rewards.add + (ctxt, contract) + cycle + new_amount + >>= fun ctxt -> return (ctxt, Legacy_rewards (delegate, cycle))) + >|=? fun (ctxt, balance) -> (ctxt, (balance, Credited amount, origin)) + +let spend ctxt src amount origin = + let open Receipt_repr in + (match src with + | `Bootstrap -> return (ctxt, Bootstrap) + | `Invoice -> return (ctxt, Invoice) + | `Initial_commitments -> return (ctxt, Initial_commitments) + | `Minted -> return (ctxt, Minted) + | `Liquidity_baking_subsidies -> return (ctxt, Liquidity_baking_subsidies) + | `Revelation_rewards -> return (ctxt, Nonce_revelation_rewards) + | `Double_signing_evidence_rewards -> + return (ctxt, Double_signing_evidence_rewards) + | `Endorsing_rewards -> return (ctxt, Endorsing_rewards) + | `Baking_rewards -> return (ctxt, Baking_rewards) + | `Baking_bonuses -> return (ctxt, Baking_bonuses) + | `Contract src -> + Contract_storage.spend_only_call_from_token ctxt src amount + >|=? fun ctxt -> (ctxt, Contract src) + | `Collected_commitments bpkh -> + Commitment_storage.decrease_commitment_only_call_from_token + ctxt + bpkh + amount + >>=? fun ctxt -> return (ctxt, Commitments bpkh) + | `Delegate_balance delegate -> + let contract = Contract_repr.implicit_contract delegate in + Contract_storage.decrease_balance_only_call_from_token + ctxt + contract + amount + >|=? fun ctxt -> (ctxt, Contract contract) + | `Frozen_deposits delegate -> + (if Tez_repr.(amount = zero) then return ctxt + else + Frozen_deposits_storage.spend_only_call_from_token ctxt delegate amount) + >>=? fun ctxt -> return (ctxt, Deposits delegate) + | `Block_fees -> + Raw_context.spend_collected_fees_only_call_from_token ctxt amount + >>?= fun ctxt -> return (ctxt, Block_fees) + (* TODO: remove in J *) + | `Legacy_deposits (delegate, cycle) as src -> + balance ctxt src >>=? fun old_amount -> + Tez_repr.(old_amount -? amount) >>?= fun new_amount -> + let contract = Contract_repr.implicit_contract delegate in + (if Tez_repr.(new_amount = zero) then + Storage.Contract.Legacy_frozen_deposits.remove (ctxt, contract) cycle + else + Storage.Contract.Legacy_frozen_deposits.add + (ctxt, contract) + cycle + new_amount) + >>= fun ctxt -> return (ctxt, Legacy_deposits (delegate, cycle)) + | `Legacy_fees (delegate, cycle) as src -> + balance ctxt src >>=? fun old_amount -> + Tez_repr.(old_amount -? amount) >>?= fun new_amount -> + let contract = Contract_repr.implicit_contract delegate in + (if Tez_repr.(new_amount = zero) then + Storage.Contract.Legacy_frozen_fees.remove (ctxt, contract) cycle + else + Storage.Contract.Legacy_frozen_fees.add + (ctxt, contract) + cycle + new_amount) + >>= fun ctxt -> return (ctxt, Legacy_fees (delegate, cycle)) + | `Legacy_rewards (delegate, cycle) as src -> + balance ctxt src >>=? fun old_amount -> + Tez_repr.(old_amount -? amount) >>?= fun new_amount -> + let contract = Contract_repr.implicit_contract delegate in + (if Tez_repr.(new_amount = zero) then + Storage.Contract.Legacy_frozen_rewards.remove (ctxt, contract) cycle + else + Storage.Contract.Legacy_frozen_rewards.add + (ctxt, contract) + cycle + new_amount) + >>= fun ctxt -> return (ctxt, Legacy_rewards (delegate, cycle))) + >|=? fun (ctxt, balance) -> (ctxt, (balance, Debited amount, origin)) + +let transfer_n ?(origin = Receipt_repr.Block_application) ctxt src dest = + let sources = List.filter (fun (_, am) -> Tez_repr.(am <> zero)) src in + match sources with + | [] -> + (* Avoid accessing context data when there is nothing to transfer. *) + return (ctxt, []) + | _ :: _ -> + List.fold_left_es + (fun (ctxt, total, debit_logs) (source, amount) -> + spend ctxt source amount origin >>=? fun (ctxt, debit_log) -> + Tez_repr.(amount +? total) >>?= fun total -> + return (ctxt, total, debit_log :: debit_logs)) + (ctxt, Tez_repr.zero, []) + sources + >>=? fun (ctxt, amount, debit_logs) -> + credit ctxt dest amount origin >|=? fun (ctxt, credit_log) -> + (* Make sure the order of balance updates is : debit logs in the order of + of the parameter [src], and then the credit log. *) + let balance_updates = List.rev (credit_log :: debit_logs) in + (ctxt, balance_updates) + +let transfer ?(origin = Receipt_repr.Block_application) ctxt src dest amount = + transfer_n ~origin ctxt [(src, amount)] dest diff --git a/src/proto_012_PsiThaCa/lib_protocol/token.mli b/src/proto_012_PsiThaCa/lib_protocol/token.mli new file mode 100644 index 000000000000..ef8c0eabcdca --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/token.mli @@ -0,0 +1,134 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020-2021 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** The aim of this module is to manage operations involving tokens such as + minting, transferring, and burning. Every constructor of the types [source], + [container], or [sink] represents a kind of account that holds a given (or + possibly infinite) amount of tokens. + + Tokens can be transferred from a [source] to a [sink]. To uniformly handle + all cases, special constructors of sources and sinks may be used. For + example, the source [`Minted] is used to express a transfer of minted tokens + to a destination, and the sink [`Burned] is used to express the action of + burning a given amount of tokens taken from a source. Thanks to uniformity, + it is easier to track transfers of tokens throughout the protocol by running + [grep -R "Token.transfer" src/proto_alpha]. *) + +(** [container] is the type of token holders with finite capacity, and whose assets + are contained in the context. Let [d] be a delegate. Be aware that transferring + to/from [`Delegate_balance d] will not update [d]'s stake, while transferring + to/from [`Contract (Contract_repr.implicit_contract d)] will update [d]'s + stake. *) +type container = + [ `Contract of Contract_repr.t + | `Collected_commitments of Blinded_public_key_hash.t + | `Delegate_balance of Signature.Public_key_hash.t + | `Frozen_deposits of Signature.Public_key_hash.t + | `Block_fees + | `Legacy_deposits of Signature.Public_key_hash.t * Cycle_repr.t + | `Legacy_fees of Signature.Public_key_hash.t * Cycle_repr.t + | `Legacy_rewards of Signature.Public_key_hash.t * Cycle_repr.t ] + +(** [source] is the type of token providers. Token providers that are not + containers are considered to have infinite capacity. *) +type source = + [ `Invoice + | `Bootstrap + | `Initial_commitments + | `Revelation_rewards + | `Double_signing_evidence_rewards + | `Endorsing_rewards + | `Baking_rewards + | `Baking_bonuses + | `Minted + | `Liquidity_baking_subsidies + | container ] + +(** [sink] is the type of token receivers. Token receivers that are not + containers are considered to have infinite capacity. *) +type sink = + [ `Storage_fees + | `Double_signing_punishments + | `Lost_endorsing_rewards of Signature.Public_key_hash.t * bool * bool + | `Burned + | container ] + +(** [allocated ctxt container] returns true if [balance ctxt container] is + guaranteed not to fail, and returns false when [balance ctxt container] may + fail. *) +val allocated : Raw_context.t -> container -> bool tzresult Lwt.t + +(** [balance ctxt container] returns the balance associated to the token holder, + may fail if [allocated ctxt container] returns [false]. + Returns an error with the message "get_balance" if [container] refers to an + originated contract that is not allocated. + Returns a {!Storage_Error Missing_key} error if [container] is of the form + [`Delegate_balance pkh], where [pkh] refers to an implicit contract that is + not allocated. *) +val balance : Raw_context.t -> container -> Tez_repr.t tzresult Lwt.t + +(** [transfer_n ?origin ctxt sources dest] transfers [amount] Tez from [src] to + [dest] for each [(src, amount)] pair in [sources], and returns a new + context, and the list of corresponding balance updates. The function behaves + as though [transfer src dest amount] was invoked for each pair + [(src, amount)] in [sources], however a single balance update is generated + for the total amount transferred to [dest]. + When [sources] is an empty list, the function does nothing to the context, + and returns an empty list of balance updates. *) +val transfer_n : + ?origin:Receipt_repr.update_origin -> + Raw_context.t -> + ([< source] * Tez_repr.t) list -> + [< sink] -> + (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t + +(** [transfer ?origin ctxt src dest amount] transfers [amount] Tez from source + [src] to destination [dest], and returns a new context, and the list of + corresponding balance updates tagged with [origin]. By default, [~origin] is + set to [Receipt_repr.Block_application]. + Returns {!Storage_Error Missing_key} if [src] refers to a contract that is + not allocated. + Returns a [Balance_too_low] error if [src] refers to a contract whose + balance is less than [amount]. + Returns a [Subtraction_underflow] error if [src] refers to a source that is + not a contract and whose balance is less than [amount]. + Returns a [Empty_implicit_delegated_contract] error if [src] is an + implicit contract that delegates to a different contract, and whose balance + is equal to [amount]. + Returns a [Non_existing_contract] error if + [dest] refers to an originated contract that is not allocated. + Returns a [Non_existing_contract] error if [amount <> Tez_repr.zero], and + [dest] refers to an originated contract that is not allocated. + Returns a [Addition_overflow] error if [dest] refers to a sink whose balance + is greater than [Int64.max - amount]. + Returns a [Wrong_level] error if [src] or [dest] refer to a level that is + not the current level. *) +val transfer : + ?origin:Receipt_repr.update_origin -> + Raw_context.t -> + [< source] -> + [< sink] -> + Tez_repr.t -> + (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/vote_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/vote_repr.ml new file mode 100644 index 000000000000..e94cc33ddf52 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/vote_repr.ml @@ -0,0 +1,42 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type proposal = Protocol_hash.t + +type ballot = Yay | Nay | Pass + +let ballot_encoding = + let of_int8 = function + | 0 -> Ok Yay + | 1 -> Ok Nay + | 2 -> Ok Pass + | _ -> Error "ballot_of_int8" + in + let to_int8 = function Yay -> 0 | Nay -> 1 | Pass -> 2 in + let open Data_encoding in + (* union *) + splitted + ~binary:(conv_with_guard to_int8 of_int8 int8) + ~json:(string_enum [("yay", Yay); ("nay", Nay); ("pass", Pass)]) diff --git a/src/proto_012_PsiThaCa/lib_protocol/vote_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/vote_repr.mli new file mode 100644 index 000000000000..8a7d4a59b685 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/vote_repr.mli @@ -0,0 +1,33 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** a protocol change proposal *) +type proposal = Protocol_hash.t + +(** votes can be for, against or neutral. + Neutral serves to count towards a quorum *) +type ballot = Yay | Nay | Pass + +val ballot_encoding : ballot Data_encoding.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/vote_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/vote_storage.ml new file mode 100644 index 000000000000..3ceec4c6e4e0 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/vote_storage.ml @@ -0,0 +1,169 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let recorded_proposal_count_for_delegate ctxt proposer = + Storage.Vote.Proposals_count.find ctxt proposer >|=? Option.value ~default:0 + +let record_proposal ctxt proposal proposer = + recorded_proposal_count_for_delegate ctxt proposer >>=? fun count -> + Storage.Vote.Proposals_count.add ctxt proposer (count + 1) >>= fun ctxt -> + Storage.Vote.Proposals.add ctxt (proposal, proposer) >|= ok + +let get_proposals ctxt = + Storage.Vote.Proposals.fold + ctxt + ~order:`Sorted + ~init:(ok Protocol_hash.Map.empty) + ~f:(fun (proposal, delegate) acc -> + (* Assuming the same listings is used at votings *) + Storage.Vote.Listings.get ctxt delegate >>=? fun weight -> + Lwt.return + ( acc >|? fun acc -> + let previous = + match Protocol_hash.Map.find proposal acc with + | None -> 0l + | Some x -> x + in + Protocol_hash.Map.add proposal (Int32.add weight previous) acc )) + +let clear_proposals ctxt = + Storage.Vote.Proposals_count.clear ctxt >>= fun ctxt -> + Storage.Vote.Proposals.clear ctxt + +type ballots = {yay : int32; nay : int32; pass : int32} + +let ballots_encoding = + let open Data_encoding in + conv + (fun {yay; nay; pass} -> (yay, nay, pass)) + (fun (yay, nay, pass) -> {yay; nay; pass}) + @@ obj3 (req "yay" int32) (req "nay" int32) (req "pass" int32) + +let has_recorded_ballot = Storage.Vote.Ballots.mem + +let record_ballot = Storage.Vote.Ballots.init + +let get_ballots ctxt = + Storage.Vote.Ballots.fold + ctxt + ~order:`Sorted + ~f:(fun delegate ballot (ballots : ballots tzresult) -> + (* Assuming the same listings is used at votings *) + Storage.Vote.Listings.get ctxt delegate >>=? fun weight -> + let count = Int32.add weight in + Lwt.return + ( ballots >|? fun ballots -> + match ballot with + | Yay -> {ballots with yay = count ballots.yay} + | Nay -> {ballots with nay = count ballots.nay} + | Pass -> {ballots with pass = count ballots.pass} )) + ~init:(ok {yay = 0l; nay = 0l; pass = 0l}) + +let get_ballot_list = Storage.Vote.Ballots.bindings + +let clear_ballots = Storage.Vote.Ballots.clear + +let listings_encoding = + Data_encoding.( + list + (obj2 (req "pkh" Signature.Public_key_hash.encoding) (req "rolls" int32))) + +let update_listings ctxt = + Storage.Vote.Listings.clear ctxt >>= fun ctxt -> + let tokens_per_roll = + Tez_repr.to_mutez (Constants_storage.tokens_per_roll ctxt) + in + Stake_storage.fold + ctxt + (ctxt, 0l) + ~order:`Sorted + ~f:(fun (delegate, stake) (ctxt, total) -> + let nb_rolls = + Int64.to_int32 @@ Int64.div (Tez_repr.to_mutez stake) tokens_per_roll + in + Storage.Vote.Listings.init ctxt delegate nb_rolls >|=? fun ctxt -> + (ctxt, Int32.add total nb_rolls)) + >>=? fun (ctxt, total) -> + Storage.Vote.Listings_size.add ctxt total >>= fun ctxt -> return ctxt + +let listing_size = Storage.Vote.Listings_size.get + +let in_listings = Storage.Vote.Listings.mem + +let get_listings = Storage.Vote.Listings.bindings + +let get_voting_power_free ctxt owner = + Storage.Vote.Listings.find ctxt owner >|=? Option.value ~default:0l + +(* This function bypasses the carbonated functors to account for gas consumption. + This is a temporary situation intended to be fixed by adding the right + carbonated functors in a future amendment *) +let get_voting_power ctxt owner = + let open Raw_context in + (* Always consume read access to memory *) + (* Accessing an int32 at /votes/listings// *) + consume_gas ctxt (Storage_costs.read_access ~path_length:4 ~read_bytes:4) + >>?= fun ctxt -> + Storage.Vote.Listings.find ctxt owner >|=? function + | None -> (ctxt, 0l) + | Some power -> (ctxt, power) + +let get_total_voting_power_free = listing_size + +(* This function bypasses the carbonated functors to account for gas consumption. + This is a temporary situation intended to be fixed by adding the right + carbonated functors in a future amendment *) +let get_total_voting_power ctxt = + let open Raw_context in + (* Accessing an int32 at /votes/listings_size *) + consume_gas ctxt (Storage_costs.read_access ~path_length:2 ~read_bytes:4) + >>?= fun ctxt -> + get_total_voting_power_free ctxt >|=? fun total_voting_power -> + (ctxt, total_voting_power) + +let get_current_quorum ctxt = + Storage.Vote.Participation_ema.get ctxt >|=? fun participation_ema -> + let quorum_min = Constants_storage.quorum_min ctxt in + let quorum_max = Constants_storage.quorum_max ctxt in + let quorum_diff = Int32.sub quorum_max quorum_min in + Int32.(add quorum_min (div (mul participation_ema quorum_diff) 100_00l)) + +let get_participation_ema = Storage.Vote.Participation_ema.get + +let set_participation_ema = Storage.Vote.Participation_ema.update + +let get_current_proposal = Storage.Vote.Current_proposal.get + +let find_current_proposal = Storage.Vote.Current_proposal.find + +let init_current_proposal = Storage.Vote.Current_proposal.init + +let clear_current_proposal = Storage.Vote.Current_proposal.remove_existing + +let init ctxt ~start_position = + (* participation EMA is in centile of a percentage *) + let participation_ema = Constants_storage.quorum_max ctxt in + Storage.Vote.Participation_ema.init ctxt participation_ema >>=? fun ctxt -> + Voting_period_storage.init_first_period ctxt ~start_position diff --git a/src/proto_012_PsiThaCa/lib_protocol/vote_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/vote_storage.mli new file mode 100644 index 000000000000..5bfc0ae34eb5 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/vote_storage.mli @@ -0,0 +1,116 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Manages all the voting related storage in Storage.Vote. *) + +(** Records a protocol proposal with the delegate that proposed it. *) +val record_proposal : + Raw_context.t -> + Protocol_hash.t -> + Signature.Public_key_hash.t -> + Raw_context.t tzresult Lwt.t + +val recorded_proposal_count_for_delegate : + Raw_context.t -> Signature.Public_key_hash.t -> int tzresult Lwt.t + +(** Computes for each proposal how many delegates proposed it. *) +val get_proposals : Raw_context.t -> int32 Protocol_hash.Map.t tzresult Lwt.t + +val clear_proposals : Raw_context.t -> Raw_context.t Lwt.t + +(** Counts of the votes *) +type ballots = {yay : int32; nay : int32; pass : int32} + +val ballots_encoding : ballots Data_encoding.t + +val has_recorded_ballot : + Raw_context.t -> Signature.Public_key_hash.t -> bool Lwt.t + +(** Records a vote for a delegate, returns a {!Storage_error Existing_key} if + the vote was already registered *) +val record_ballot : + Raw_context.t -> + Signature.Public_key_hash.t -> + Vote_repr.ballot -> + Raw_context.t tzresult Lwt.t + +(** Computes the sum of the current ballots weighted by stake. *) +val get_ballots : Raw_context.t -> ballots tzresult Lwt.t + +val get_ballot_list : + Raw_context.t -> (Signature.Public_key_hash.t * Vote_repr.ballot) list Lwt.t + +val clear_ballots : Raw_context.t -> Raw_context.t Lwt.t + +val listings_encoding : + (Signature.Public_key_hash.t * int32) list Data_encoding.t + +(** Populates [!Storage.Vote.Listings] using the currently existing rolls and + sets Listings_size. Delegates without rolls are not included in the listing. *) +val update_listings : Raw_context.t -> Raw_context.t tzresult Lwt.t + +(** Returns the sum of all rolls of all delegates. *) +val listing_size : Raw_context.t -> int32 tzresult Lwt.t + +(** Verifies the presence of a delegate in the listing. *) +val in_listings : Raw_context.t -> Signature.Public_key_hash.t -> bool Lwt.t + +val get_listings : + Raw_context.t -> (Signature.Public_key_hash.t * int32) list Lwt.t + +val get_voting_power_free : + Raw_context.t -> Signature.public_key_hash -> int32 tzresult Lwt.t + +val get_voting_power : + Raw_context.t -> + Signature.public_key_hash -> + (Raw_context.t * int32) tzresult Lwt.t + +val get_total_voting_power_free : Raw_context.t -> int32 tzresult Lwt.t + +val get_total_voting_power : + Raw_context.t -> (Raw_context.t * int32) tzresult Lwt.t + +val get_current_quorum : Raw_context.t -> int32 tzresult Lwt.t + +val get_participation_ema : Raw_context.t -> int32 tzresult Lwt.t + +val set_participation_ema : + Raw_context.t -> int32 -> Raw_context.t tzresult Lwt.t + +val get_current_proposal : Raw_context.t -> Protocol_hash.t tzresult Lwt.t + +val find_current_proposal : + Raw_context.t -> Protocol_hash.t option tzresult Lwt.t + +val init_current_proposal : + Raw_context.t -> Protocol_hash.t -> Raw_context.t tzresult Lwt.t + +val clear_current_proposal : Raw_context.t -> Raw_context.t tzresult Lwt.t + +(** Sets the initial quorum to 80% and period kind to proposal. *) +val init : + Raw_context.t -> start_position:Int32.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/voting_period_repr.ml b/src/proto_012_PsiThaCa/lib_protocol/voting_period_repr.ml new file mode 100644 index 000000000000..de4cf915bc46 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/voting_period_repr.ml @@ -0,0 +1,175 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type kind = Proposal | Exploration | Cooldown | Promotion | Adoption + +let string_of_kind = function + | Proposal -> "proposal" + | Exploration -> "exploration" + | Cooldown -> "cooldown" + | Promotion -> "promotion" + | Adoption -> "adoption" + +let pp_kind ppf kind = Format.fprintf ppf "%s" @@ string_of_kind kind + +let kind_encoding = + let open Data_encoding in + union + ~tag_size:`Uint8 + [ + case + (Tag 0) + ~title:"Proposal" + (constant "proposal") + (function Proposal -> Some () | _ -> None) + (fun () -> Proposal); + case + (Tag 1) + ~title:"exploration" + (constant "exploration") + (function Exploration -> Some () | _ -> None) + (fun () -> Exploration); + case + (Tag 2) + ~title:"Cooldown" + (constant "cooldown") + (function Cooldown -> Some () | _ -> None) + (fun () -> Cooldown); + case + (Tag 3) + ~title:"Promotion" + (constant "promotion") + (function Promotion -> Some () | _ -> None) + (fun () -> Promotion); + case + (Tag 4) + ~title:"Adoption" + (constant "adoption") + (function Adoption -> Some () | _ -> None) + (fun () -> Adoption); + ] + +let succ_kind = function + | Proposal -> Exploration + | Exploration -> Cooldown + | Cooldown -> Promotion + | Promotion -> Adoption + | Adoption -> Proposal + +type voting_period = {index : int32; kind : kind; start_position : int32} + +type t = voting_period + +type info = {voting_period : t; position : int32; remaining : int32} + +let root ~start_position = {index = 0l; kind = Proposal; start_position} + +let pp ppf {index; kind; start_position} = + Format.fprintf + ppf + "@[index: %ld,@ kind:%a,@ start_position: %ld@]" + index + pp_kind + kind + start_position + +let pp_info ppf {voting_period; position; remaining} = + Format.fprintf + ppf + "@[voting_period: %a,@ position:%ld,@ remaining: %ld@]" + pp + voting_period + position + remaining + +let encoding = + let open Data_encoding in + conv + (fun {index; kind; start_position} -> (index, kind, start_position)) + (fun (index, kind, start_position) -> {index; kind; start_position}) + (obj3 + (req + "index" + ~description: + "The voting period's index. Starts at 0 with the first block of \ + the Alpha family of protocols." + int32) + (req + ~description: + "One of the several kinds of periods in the voting procedure." + "kind" + kind_encoding) + (req + ~description: + "The relative position of the first level of the period with \ + respect to the first level of the Alpha family of protocols." + "start_position" + int32)) + +let info_encoding = + let open Data_encoding in + conv + (fun {voting_period; position; remaining} -> + (voting_period, position, remaining)) + (fun (voting_period, position, remaining) -> + {voting_period; position; remaining}) + (obj3 + (req + ~description:"The voting period to which the block belongs." + "voting_period" + encoding) + (req + ~description:"The position of the block within the voting period." + "position" + int32) + (req + ~description: + "The number of blocks remaining till the end of the voting period." + "remaining" + int32)) + +include Compare.Make (struct + type nonrec t = t + + let compare p p' = Compare.Int32.compare p.index p'.index +end) + +let raw_reset period ~start_position = + let index = Int32.succ period.index in + let kind = Proposal in + {index; kind; start_position} + +let raw_succ period ~start_position = + let index = Int32.succ period.index in + let kind = succ_kind period.kind in + {index; kind; start_position} + +let position_since (level : Level_repr.t) (voting_period : t) = + Int32.(sub level.level_position voting_period.start_position) + +let remaining_blocks (level : Level_repr.t) (voting_period : t) + ~blocks_per_voting_period = + let position = position_since level voting_period in + Int32.(sub blocks_per_voting_period (succ position)) diff --git a/src/proto_012_PsiThaCa/lib_protocol/voting_period_repr.mli b/src/proto_012_PsiThaCa/lib_protocol/voting_period_repr.mli new file mode 100644 index 000000000000..028281ec567e --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/voting_period_repr.mli @@ -0,0 +1,82 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** The voting period kinds are ordered as follows: + Proposal -> Testing_vote -> Testing -> Promotion -> Adoption. + This order is the one used be the function [succ] below. + *) +type kind = + | Proposal (** protocols can be proposed *) + | Exploration (** a proposal can be voted *) + | Cooldown (** a delay before the second vote of the Promotion period. *) + | Promotion (** activation can be voted *) + | Adoption (** a delay before activation *) + +val kind_encoding : kind Data_encoding.t + +(** A voting period can be of several kinds and is uniquely identified by + the counter 'index'. The 'start_position' represents the relative + position of the first level of the period with respect to the + first level of the Alpha family of protocols. *) +type voting_period = {index : Int32.t; kind : kind; start_position : Int32.t} + +type t = voting_period + +(** Information about a block with respect to the voting period it + belongs to: the voting period, the position within the voting + period and the number of remaining blocks till the end of the + period. The following invariant is satisfied: + `position + remaining + 1 = blocks_per_voting_period` *) +type info = {voting_period : t; position : Int32.t; remaining : Int32.t} + +val root : start_position:Int32.t -> t + +include Compare.S with type t := voting_period + +val encoding : t Data_encoding.t + +val info_encoding : info Data_encoding.t + +val pp : Format.formatter -> t -> unit + +val pp_info : Format.formatter -> info -> unit + +val pp_kind : Format.formatter -> kind -> unit + +(** [raw_reset period ~start_position] increment the index by one and set the + kind to Proposal which is the period kind that start the voting + process. [start_position] is the level at wich this voting_period started. +*) +val raw_reset : t -> start_position:Int32.t -> t + +(** [raw_succ period ~start_position] increment the index by one and set the + kind to its successor. [start_position] is the level at which this + voting_period started. *) +val raw_succ : t -> start_position:Int32.t -> t + +val position_since : Level_repr.t -> t -> Int32.t + +val remaining_blocks : + Level_repr.t -> t -> blocks_per_voting_period:Int32.t -> Int32.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/voting_period_storage.ml b/src/proto_012_PsiThaCa/lib_protocol/voting_period_storage.ml new file mode 100644 index 000000000000..b6a9156bb7a1 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/voting_period_storage.ml @@ -0,0 +1,191 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* + The shell uses the convention that a context at level n is the resulting + context of the application of block n. + Therefore when using an RPC on the last level of a voting period, the context + that is inspected is the resulting one. + + However [Amendment.may_start_new_voting_period] is run at the end of voting + period and it has to prepare the context for validating operations of the next + period. This causes the counter-intuitive result that the info returned by RPCs + at last level of a voting period mention data of the next voting period. + + For example, when validating the last block of a proposal period at level n + we have: + - Input context: + + voting_period = { kind = Proposal; + index = i; + start_position = n - blocks_per_voting_period} + + - position = n - start_position = blocks_per_voting_period + - remaining = blocks_per_voting_period - (position + 1) = 0 + + - Output context: + + voting_period = { kind = Exploration; + index = i + 1; + start_position = n + 1} + + Now if we calculate position and remaining in the voting period we get + strange results: + - position = n - (n + 1) = -1 + - remaining = blocks_per_voting_period + + To work around this issue, two RPCs were added + `Voting_period_storage.get_rpc_current_info`, which returns the correct + info also for the last context of a period, and + `Voting_period_storage.get_rpc_succ_info`, which can be used at the last + context of a period to craft operations that will be valid for the first + block of the new period. + + This odd behaviour could be fixed if [Amendment.may_start_new_voting_period] + was called when we start validating the first block of a voting period instead + that at the end of the validation of the last block of a voting period. + This should be carefully done because the voting period listing depends on + the rolls and it might break some invariant. + + When this is implemented one should: + - edit the function [reset_current] and [inc_current] to use the + current level and not the next one. + - remove the storage for pred_kind + - make Voting_period_repr.t abstract + + You can also look at the MR description here: + https://gitlab.com/metastatedev/tezos/-/merge_requests/333 + *) + +(* Voting periods start at the first block of a cycle. More formally, + the invariant of start_position with respect to cycle_position is: + cycle_position mod blocks_per_cycle == + position_in_period mod blocks_per_cycle *) + +let set_current = Storage.Vote.Current_period.update + +let get_current = Storage.Vote.Current_period.get + +let init = Storage.Vote.Current_period.init + +let init_first_period ctxt ~start_position = + init ctxt @@ Voting_period_repr.root ~start_position >>=? fun ctxt -> + Storage.Vote.Pred_period_kind.init ctxt Voting_period_repr.Proposal + +let common ctxt = + get_current ctxt >>=? fun current_period -> + Storage.Vote.Pred_period_kind.update ctxt current_period.kind >|=? fun ctxt -> + let start_position = + (* because we are preparing the voting period for the next block we need to + use the next level. *) + Int32.succ (Level_storage.current ctxt).level_position + in + (ctxt, current_period, start_position) + +let reset ctxt = + common ctxt >>=? fun (ctxt, current_period, start_position) -> + Voting_period_repr.raw_reset current_period ~start_position + |> set_current ctxt + +let succ ctxt = + common ctxt >>=? fun (ctxt, current_period, start_position) -> + Voting_period_repr.raw_succ current_period ~start_position |> set_current ctxt + +let get_current_kind ctxt = get_current ctxt >|=? fun {kind; _} -> kind + +let get_current_info ctxt = + get_current ctxt >|=? fun voting_period -> + let blocks_per_voting_period = + Constants_storage.blocks_per_voting_period ctxt + in + let level = Level_storage.current ctxt in + let position = Voting_period_repr.position_since level voting_period in + let remaining = + Voting_period_repr.remaining_blocks + level + voting_period + ~blocks_per_voting_period + in + Voting_period_repr.{voting_period; position; remaining} + +let get_current_remaining ctxt = + get_current ctxt >|=? fun voting_period -> + let blocks_per_voting_period = + Constants_storage.blocks_per_voting_period ctxt + in + Voting_period_repr.remaining_blocks + (Level_storage.current ctxt) + voting_period + ~blocks_per_voting_period + +let is_last_block ctxt = + get_current_remaining ctxt >|=? fun remaining -> + Compare.Int32.(remaining = 0l) + +let get_rpc_current_info ctxt = + get_current_info ctxt + >>=? fun ({voting_period; position; _} as voting_period_info) -> + if Compare.Int32.(position = Int32.minus_one) then + let level = Level_storage.current ctxt in + let blocks_per_voting_period = + Constants_storage.blocks_per_voting_period ctxt + in + Storage.Vote.Pred_period_kind.get ctxt >|=? fun pred_kind -> + let voting_period : Voting_period_repr.t = + { + index = Int32.pred voting_period.index; + kind = pred_kind; + start_position = + Int32.(sub voting_period.start_position blocks_per_voting_period); + } + in + let position = Voting_period_repr.position_since level voting_period in + let remaining = + Voting_period_repr.remaining_blocks + level + voting_period + ~blocks_per_voting_period + in + ({voting_period; remaining; position} : Voting_period_repr.info) + else return voting_period_info + +let get_rpc_succ_info ctxt = + Level_storage.from_raw_with_offset + ctxt + ~offset:1l + (Level_storage.current ctxt).level + >>?= fun level -> + get_current ctxt >|=? fun voting_period -> + let blocks_per_voting_period = + Constants_storage.blocks_per_voting_period ctxt + in + let position = Voting_period_repr.position_since level voting_period in + let remaining = + Voting_period_repr.remaining_blocks + level + voting_period + ~blocks_per_voting_period + in + Voting_period_repr.{voting_period; position; remaining} diff --git a/src/proto_012_PsiThaCa/lib_protocol/voting_period_storage.mli b/src/proto_012_PsiThaCa/lib_protocol/voting_period_storage.mli new file mode 100644 index 000000000000..f18dc5e9aa10 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/voting_period_storage.mli @@ -0,0 +1,51 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2020 Metastate AG *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val init : Raw_context.t -> Voting_period_repr.t -> Raw_context.t tzresult Lwt.t + +(** Sets the initial period to [{voting_period = root; kind = Proposal; + start_position}]. *) +val init_first_period : + Raw_context.t -> start_position:Int32.t -> Raw_context.t tzresult Lwt.t + +(** Increment the index by one and set the kind to Proposal. *) +val reset : Raw_context.t -> Raw_context.t tzresult Lwt.t + +(** Increment the index by one and set the kind to its successor. *) +val succ : Raw_context.t -> Raw_context.t tzresult Lwt.t + +val get_current : Raw_context.t -> Voting_period_repr.t tzresult Lwt.t + +val get_current_kind : Raw_context.t -> Voting_period_repr.kind tzresult Lwt.t + +(** Returns true if the context level is the last of current voting period. *) +val is_last_block : Raw_context.t -> bool tzresult Lwt.t + +(** Returns the voting period information for the current level. *) +val get_rpc_current_info : + Raw_context.t -> Voting_period_repr.info tzresult Lwt.t + +(** Returns the voting period information for the next level. *) +val get_rpc_succ_info : Raw_context.t -> Voting_period_repr.info tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/lib_protocol/voting_services.ml b/src/proto_012_PsiThaCa/lib_protocol/voting_services.ml new file mode 100644 index 000000000000..0ff6088eb536 --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/voting_services.ml @@ -0,0 +1,152 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +module S = struct + let path = RPC_path.(open_root / "votes") + + let ballots = + RPC_service.get_service + ~description:"Sum of ballots casted so far during a voting period." + ~query:RPC_query.empty + ~output:Vote.ballots_encoding + RPC_path.(path / "ballots") + + let ballot_list = + RPC_service.get_service + ~description:"Ballots casted so far during a voting period." + ~query:RPC_query.empty + ~output: + Data_encoding.( + list + (obj2 + (req "pkh" Signature.Public_key_hash.encoding) + (req "ballot" Vote.ballot_encoding))) + RPC_path.(path / "ballot_list") + + let current_period = + RPC_service.get_service + ~description: + "Returns the voting period (index, kind, starting position) and \ + related information (position, remaining) of the interrogated block." + ~query:RPC_query.empty + ~output:Voting_period.info_encoding + RPC_path.(path / "current_period") + + let successor_period = + RPC_service.get_service + ~description: + "Returns the voting period (index, kind, starting position) and \ + related information (position, remaining) of the next block.Useful to \ + craft operations that will be valid in the next block." + ~query:RPC_query.empty + ~output:Voting_period.info_encoding + RPC_path.(path / "successor_period") + + let current_quorum = + RPC_service.get_service + ~description:"Current expected quorum." + ~query:RPC_query.empty + ~output:Data_encoding.int32 + RPC_path.(path / "current_quorum") + + let listings = + RPC_service.get_service + ~description: + "List of delegates with their voting weight, in number of rolls." + ~query:RPC_query.empty + ~output:Vote.listings_encoding + RPC_path.(path / "listings") + + let proposals = + RPC_service.get_service + ~description:"List of proposals with number of supporters." + ~query:RPC_query.empty + ~output:(Protocol_hash.Map.encoding Data_encoding.int32) + RPC_path.(path / "proposals") + + let current_proposal = + RPC_service.get_service + ~description:"Current proposal under evaluation." + ~query:RPC_query.empty + ~output:(Data_encoding.option Protocol_hash.encoding) + RPC_path.(path / "current_proposal") + + let total_voting_power = + RPC_service.get_service + ~description: + "Total number of rolls for the delegates in the voting listings." + ~query:RPC_query.empty + ~output:Data_encoding.int32 + RPC_path.(path / "total_voting_power") +end + +let register () = + let open Services_registration in + register0 ~chunked:false S.ballots (fun ctxt () () -> Vote.get_ballots ctxt) ; + register0 ~chunked:true S.ballot_list (fun ctxt () () -> + Vote.get_ballot_list ctxt >|= ok) ; + register0 ~chunked:false S.current_period (fun ctxt () () -> + Voting_period.get_rpc_current_info ctxt) ; + register0 ~chunked:false S.successor_period (fun ctxt () () -> + Voting_period.get_rpc_succ_info ctxt) ; + register0 ~chunked:false S.current_quorum (fun ctxt () () -> + Vote.get_current_quorum ctxt) ; + register0 ~chunked:true S.proposals (fun ctxt () () -> + Vote.get_proposals ctxt) ; + register0 ~chunked:true S.listings (fun ctxt () () -> + Vote.get_listings ctxt >|= ok) ; + register0 ~chunked:false S.current_proposal (fun ctxt () () -> + Vote.find_current_proposal ctxt) ; + register0 ~chunked:false S.total_voting_power (fun ctxt () () -> + Vote.get_total_voting_power_free ctxt) + [@@coq_axiom_with_reason + "disabled because we would need to re-create the error e in order to have \ + different polymorphic variables"] + +let ballots ctxt block = RPC_context.make_call0 S.ballots ctxt block () () + +let ballot_list ctxt block = + RPC_context.make_call0 S.ballot_list ctxt block () () + +let current_period ctxt block = + RPC_context.make_call0 S.current_period ctxt block () () + +let successor_period ctxt block = + RPC_context.make_call0 S.successor_period ctxt block () () + +let current_quorum ctxt block = + RPC_context.make_call0 S.current_quorum ctxt block () () + +let listings ctxt block = RPC_context.make_call0 S.listings ctxt block () () + +let proposals ctxt block = RPC_context.make_call0 S.proposals ctxt block () () + +let current_proposal ctxt block = + RPC_context.make_call0 S.current_proposal ctxt block () () + +let total_voting_power ctxt block = + RPC_context.make_call0 S.total_voting_power ctxt block () () diff --git a/src/proto_012_PsiThaCa/lib_protocol/voting_services.mli b/src/proto_012_PsiThaCa/lib_protocol/voting_services.mli new file mode 100644 index 000000000000..d56157aa6c1a --- /dev/null +++ b/src/proto_012_PsiThaCa/lib_protocol/voting_services.mli @@ -0,0 +1,60 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +val ballots : 'a #RPC_context.simple -> 'a -> Vote.ballots shell_tzresult Lwt.t + +val ballot_list : + 'a #RPC_context.simple -> + 'a -> + (Signature.Public_key_hash.t * Vote.ballot) list shell_tzresult Lwt.t + +val current_period : + 'a #RPC_context.simple -> 'a -> Voting_period.info shell_tzresult Lwt.t + +val successor_period : + 'a #RPC_context.simple -> 'a -> Voting_period.info shell_tzresult Lwt.t + +val current_quorum : + 'a #RPC_context.simple -> 'a -> Int32.t shell_tzresult Lwt.t + +val listings : + 'a #RPC_context.simple -> + 'a -> + (Signature.Public_key_hash.t * int32) list shell_tzresult Lwt.t + +val proposals : + 'a #RPC_context.simple -> + 'a -> + Int32.t Protocol_hash.Map.t shell_tzresult Lwt.t + +val current_proposal : + 'a #RPC_context.simple -> 'a -> Protocol_hash.t option shell_tzresult Lwt.t + +val register : unit -> unit + +val total_voting_power : + 'a #RPC_context.simple -> 'a -> Int32.t shell_tzresult Lwt.t diff --git a/src/proto_012_PsiThaCa/parameters/dune b/src/proto_012_PsiThaCa/parameters/dune new file mode 100644 index 000000000000..f9a324da0bf8 --- /dev/null +++ b/src/proto_012_PsiThaCa/parameters/dune @@ -0,0 +1,4 @@ +(copy_files + (alias copy-parameters) + (mode promote-until-clean) + (files ../lib_parameters/*.json)) \ No newline at end of file diff --git a/tests_python/contracts_012/attic/accounts.tz b/tests_python/contracts_012/attic/accounts.tz new file mode 100644 index 000000000000..de80046b29a6 --- /dev/null +++ b/tests_python/contracts_012/attic/accounts.tz @@ -0,0 +1,54 @@ +# This is a very simple accounts system. +# (Left key) initializes or deposits into an account +# (Right key (pair mutez (signed mutez))) withdraws mutez amount to a +# IMPLICIT_ACCOUNT created from the key if the balance is available +# and the key is correctly signed +parameter (or (key_hash %Initialize) + (pair %Withdraw + (key %from) + (pair + (mutez %withdraw_amount) + (signature %sig)))); +# Maps the key to the balance they have stored +storage (map :stored_balance key_hash mutez); +code { DUP; CAR; + # Deposit into account + IF_LEFT { DUP; DIIP{ CDR %stored_balance; DUP }; + DIP{ SWAP }; GET @opt_prev_balance; + # Create the account + IF_SOME # Add to an existing account + { RENAME @previous_balance; + AMOUNT; ADD; SOME; SWAP; UPDATE; NIL operation; PAIR } + { DIP{ AMOUNT; SOME }; UPDATE; NIL operation; PAIR }} + # Withdrawal + { DUP; DUP; DUP; DUP; + # Check signature on data + CAR %from; + DIIP{ CDAR %withdraw_amount; PACK ; BLAKE2B @signed_amount }; + DIP{ CDDR %sig }; CHECK_SIGNATURE; + IF {} { PUSH string "Bad signature"; FAILWITH }; + # Get user account information + DIIP{ CDR %stored_balance; DUP }; + CAR %from; HASH_KEY @from_hash; DUP; DIP{ DIP { SWAP }; SWAP}; GET; + # Account does not exist + IF_NONE { PUSH string "Account does not exist"; PAIR; FAILWITH } + # Account exists + { RENAME @previous_balance; + DIP { DROP }; + DUP; DIIP{ DUP; CDAR %withdraw_amount; DUP }; + # Ensure funds are available + DIP{ CMPLT @not_enough }; SWAP; + IF { PUSH string "Not enough funds"; FAILWITH } + { SUB_MUTEZ @new_balance; ASSERT_SOME; DIP{ DUP; DIP{ SWAP }}; DUP; + # Delete account if balance is 0 + PUSH @zero mutez 0; CMPEQ @null_balance; + IF { DROP; NONE @new_balance mutez } + # Otherwise update storage with new balance + { SOME @new_balance }; + SWAP; CAR %from; HASH_KEY @from_hash; UPDATE; + SWAP; DUP; CDAR %withdraw_amount; + # Execute the transfer + DIP{ CAR %from; HASH_KEY @from_hash; IMPLICIT_ACCOUNT @from_account}; UNIT; + TRANSFER_TOKENS @withdraw_transfer_op; + NIL operation; SWAP; CONS; + PAIR }}}} diff --git a/tests_python/contracts_012/attic/add1.tz b/tests_python/contracts_012/attic/add1.tz new file mode 100644 index 000000000000..78d4f9d1c020 --- /dev/null +++ b/tests_python/contracts_012/attic/add1.tz @@ -0,0 +1,7 @@ +parameter int; +storage int; +code {CAR; # Get the parameter + PUSH int 1; # We're adding 1, so we need to put 1 on the stack + ADD; # Add the two numbers + NIL operation; # We put an empty list of operations on the stack + PAIR} # Create the end value diff --git a/tests_python/contracts_012/attic/add1_list.tz b/tests_python/contracts_012/attic/add1_list.tz new file mode 100644 index 000000000000..c11616286475 --- /dev/null +++ b/tests_python/contracts_012/attic/add1_list.tz @@ -0,0 +1,6 @@ +parameter (list int); +storage (list int); +code { CAR; # Get the parameter + MAP { PUSH int 1; ADD }; # Map over the list adding one + NIL operation; # No internal op + PAIR } # Match the calling convention diff --git a/tests_python/contracts_012/attic/after_strategy.tz b/tests_python/contracts_012/attic/after_strategy.tz new file mode 100644 index 000000000000..70812e52b200 --- /dev/null +++ b/tests_python/contracts_012/attic/after_strategy.tz @@ -0,0 +1,3 @@ +parameter nat; +storage (pair (pair nat bool) timestamp); +code {DUP; CAR; DIP{CDDR; DUP; NOW; CMPGT}; PAIR; PAIR ; NIL operation ; PAIR}; diff --git a/tests_python/contracts_012/attic/always.tz b/tests_python/contracts_012/attic/always.tz new file mode 100644 index 000000000000..a7802fec96c8 --- /dev/null +++ b/tests_python/contracts_012/attic/always.tz @@ -0,0 +1,4 @@ +parameter nat; +storage (pair nat bool); +code { CAR; PUSH bool True; SWAP; + PAIR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/append.tz b/tests_python/contracts_012/attic/append.tz new file mode 100644 index 000000000000..3b8335455dcd --- /dev/null +++ b/tests_python/contracts_012/attic/append.tz @@ -0,0 +1,8 @@ +parameter (pair (list int) (list int)); +storage (list int); +code { CAR; UNPAIR ; # Unpack lists + NIL int; SWAP; # Setup reverse accumulator + ITER {CONS}; # Reverse list + ITER {CONS}; # Append reversed list + NIL operation; + PAIR} diff --git a/tests_python/contracts_012/attic/at_least.tz b/tests_python/contracts_012/attic/at_least.tz new file mode 100644 index 000000000000..6c6d2968cd12 --- /dev/null +++ b/tests_python/contracts_012/attic/at_least.tz @@ -0,0 +1,6 @@ +parameter unit; +storage mutez; # How much you have to send me +code {CDR; DUP; # Get the amount required (once for comparison, once to save back in storage) + AMOUNT; CMPLT; # Check to make sure no one is wasting my time + IF {FAIL} # Reject the person + {NIL operation;PAIR}} # Finish the transaction diff --git a/tests_python/contracts_012/attic/auction.tz b/tests_python/contracts_012/attic/auction.tz new file mode 100644 index 000000000000..af8aedfb7c22 --- /dev/null +++ b/tests_python/contracts_012/attic/auction.tz @@ -0,0 +1,8 @@ +parameter key_hash; +storage (pair timestamp (pair mutez key_hash)); +code { DUP; CDAR; DUP; NOW; CMPGT; IF {FAIL} {}; SWAP; # Check if auction has ended + DUP; CAR; DIP{CDDR}; AMOUNT; PAIR; SWAP; DIP{SWAP; PAIR}; # Setup replacement storage + DUP; CAR; AMOUNT; CMPLE; IF {FAIL} {}; # Check to make sure that the new amount is greater + DUP; CAR; # Get amount of refund + DIP{CDR; IMPLICIT_ACCOUNT}; UNIT; TRANSFER_TOKENS; # Make refund + NIL operation; SWAP; CONS; PAIR} # Calling convention diff --git a/tests_python/contracts_012/attic/bad_lockup.tz b/tests_python/contracts_012/attic/bad_lockup.tz new file mode 100644 index 000000000000..f334e899e71c --- /dev/null +++ b/tests_python/contracts_012/attic/bad_lockup.tz @@ -0,0 +1,6 @@ +parameter unit; +storage (pair timestamp (pair address address)); +code { CDR; DUP; CAR; NOW; CMPLT; IF {FAIL} {}; + DUP; CDAR; CONTRACT unit ; ASSERT_SOME ; PUSH mutez 100000000; UNIT; TRANSFER_TOKENS; SWAP; + DUP; CDDR; CONTRACT unit ; ASSERT_SOME ; PUSH mutez 100000000; UNIT; TRANSFER_TOKENS; DIP {SWAP} ; + NIL operation ; SWAP ; CONS ; SWAP ; CONS ; PAIR } diff --git a/tests_python/contracts_012/attic/big_map_union.tz b/tests_python/contracts_012/attic/big_map_union.tz new file mode 100644 index 000000000000..0c971ff11ce9 --- /dev/null +++ b/tests_python/contracts_012/attic/big_map_union.tz @@ -0,0 +1,8 @@ +parameter (list (pair string int)) ; +storage (pair (big_map string int) unit) ; +code { UNPAPAIR ; + ITER { UNPAIR ; DUUUP ; DUUP; GET ; + IF_NONE { PUSH int 0 } {} ; + SWAP ; DIP { ADD ; SOME } ; + UPDATE } ; + PAIR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/attic/cadr_annotation.tz b/tests_python/contracts_012/attic/cadr_annotation.tz new file mode 100644 index 000000000000..3f4978aebf9e --- /dev/null +++ b/tests_python/contracts_012/attic/cadr_annotation.tz @@ -0,0 +1,3 @@ +parameter (pair (pair %p1 unit (string %no_name)) bool); +storage unit; +code { CAR @param; CADR @name %no_name; DROP; UNIT; NIL operation; PAIR } diff --git a/tests_python/contracts_012/attic/concat.tz b/tests_python/contracts_012/attic/concat.tz new file mode 100644 index 000000000000..26814afca55a --- /dev/null +++ b/tests_python/contracts_012/attic/concat.tz @@ -0,0 +1,7 @@ +parameter string; +storage string; +code { DUP; + DIP { CDR ; NIL string ; SWAP ; CONS } ; + CAR ; CONS ; + CONCAT; + NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/conditionals.tz b/tests_python/contracts_012/attic/conditionals.tz new file mode 100644 index 000000000000..16bf8e91645c --- /dev/null +++ b/tests_python/contracts_012/attic/conditionals.tz @@ -0,0 +1,9 @@ +parameter (or string (option int)); +storage string; +code { CAR; # Access the storage + IF_LEFT {} # The string is on top of the stack, nothing to do + { IF_NONE { FAIL} # Fail if None + { PUSH int 0; CMPGT; # Check for negative number + IF {FAIL} # Fail if negative + {PUSH string ""}}}; # Push the empty string + NIL operation; PAIR} # Calling convention diff --git a/tests_python/contracts_012/attic/cons_twice.tz b/tests_python/contracts_012/attic/cons_twice.tz new file mode 100644 index 000000000000..4761b23f71f1 --- /dev/null +++ b/tests_python/contracts_012/attic/cons_twice.tz @@ -0,0 +1,9 @@ +parameter nat; +storage (list nat); +code { DUP; # Duplicate the storage and parameter + CAR; # Extract the parameter + DIP{CDR}; # Extract the storage + DUP; # Duplicate the parameter + DIP{CONS}; # Add the first instance of the parameter to the list + CONS; # Add the second instance of the parameter to the list + NIL operation; PAIR} # Finish the calling convention diff --git a/tests_python/contracts_012/attic/cps_fact.tz b/tests_python/contracts_012/attic/cps_fact.tz new file mode 100644 index 000000000000..6c8ee7146290 --- /dev/null +++ b/tests_python/contracts_012/attic/cps_fact.tz @@ -0,0 +1,16 @@ +storage nat ; +parameter nat ; +code { UNPAIR ; + DIP { SELF ; ADDRESS ; SENDER; + IFCMPEQ {} { DROP ; PUSH @storage nat 1 } }; + DUP ; + PUSH nat 1 ; + IFCMPGE + { DROP ; NIL operation ; PAIR } + { PUSH nat 1 ; SWAP ; SUB @parameter ; ISNAT ; + IF_NONE + { NIL operation ; PAIR } + { DUP ; DIP { PUSH nat 1 ; ADD ; MUL @storage } ; SWAP; + DIP { DIP { SELF; PUSH mutez 0 } ; + TRANSFER_TOKENS ; NIL operation ; SWAP ; CONS } ; + SWAP ; PAIR } } } \ No newline at end of file diff --git a/tests_python/contracts_012/attic/create_add1_lists.tz b/tests_python/contracts_012/attic/create_add1_lists.tz new file mode 100644 index 000000000000..5a4245966379 --- /dev/null +++ b/tests_python/contracts_012/attic/create_add1_lists.tz @@ -0,0 +1,14 @@ +parameter unit; +storage address; +code { DROP; NIL int; # starting storage for contract + AMOUNT; # Push the starting balance + NONE key_hash; # No delegate + CREATE_CONTRACT # Create the contract + { parameter (list int) ; + storage (list int) ; + code + { CAR; + MAP {PUSH int 1; ADD}; + NIL operation; + PAIR } }; + NIL operation; SWAP; CONS; PAIR} # Ending calling convention stuff diff --git a/tests_python/contracts_012/attic/data_publisher.tz b/tests_python/contracts_012/attic/data_publisher.tz new file mode 100644 index 000000000000..9240d63021bc --- /dev/null +++ b/tests_python/contracts_012/attic/data_publisher.tz @@ -0,0 +1,8 @@ +parameter (pair signature (pair string nat)); +storage (pair (pair key nat) string); +code { DUP; CAR; DIP{CDR; DUP}; + SWAP; DIP{DUP}; CAAR; DIP{DUP; CAR; DIP{CDR; PACK ; BLAKE2B}}; + CHECK_SIGNATURE; + IF { CDR; DUP; DIP{CAR; DIP{CAAR}}; CDR; PUSH nat 1; ADD; + DIP{SWAP}; SWAP; PAIR; PAIR; NIL operation; PAIR} + {FAIL}} diff --git a/tests_python/contracts_012/attic/dispatch.tz b/tests_python/contracts_012/attic/dispatch.tz new file mode 100644 index 000000000000..9c185133ac7f --- /dev/null +++ b/tests_python/contracts_012/attic/dispatch.tz @@ -0,0 +1,9 @@ +parameter (or string (pair string (lambda unit string))); +storage (pair string (map string (lambda unit string))); +code { DUP; DIP{CDDR}; CAR; # Unpack stack + IF_LEFT { DIP{DUP}; GET; # Get lambda if it exists + IF_NONE {FAIL} {}; # Fail if it doesn't + UNIT; EXEC } # Execute the lambda + { DUP; CAR; DIP {CDR; SOME}; UPDATE; PUSH string ""}; # Update the storage + PAIR; + NIL operation; PAIR} # Calling convention diff --git a/tests_python/contracts_012/attic/empty.tz b/tests_python/contracts_012/attic/empty.tz new file mode 100644 index 000000000000..d3aecdb25066 --- /dev/null +++ b/tests_python/contracts_012/attic/empty.tz @@ -0,0 +1,3 @@ +parameter unit; +storage unit; +code {CDR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/fail_amount.tz b/tests_python/contracts_012/attic/fail_amount.tz new file mode 100644 index 000000000000..95b71c4f0ff1 --- /dev/null +++ b/tests_python/contracts_012/attic/fail_amount.tz @@ -0,0 +1,6 @@ +# Fail if the amount transferred is less than 10 +parameter unit; +storage unit; +code { DROP; + AMOUNT; PUSH mutez 10000000; CMPGT; IF {FAIL} {}; + UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/faucet.tz b/tests_python/contracts_012/attic/faucet.tz new file mode 100644 index 000000000000..0c92a0744d94 --- /dev/null +++ b/tests_python/contracts_012/attic/faucet.tz @@ -0,0 +1,7 @@ +parameter key_hash ; +storage timestamp ; +code { UNPAIR ; SWAP ; + PUSH int 300 ; ADD @FIVE_MINUTES_LATER ; + NOW ; ASSERT_CMPGE ; + IMPLICIT_ACCOUNT ; PUSH mutez 1000000 ; UNIT ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; DIP { NOW } ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/attic/forward.tz b/tests_python/contracts_012/attic/forward.tz new file mode 100644 index 000000000000..829192f5a313 --- /dev/null +++ b/tests_python/contracts_012/attic/forward.tz @@ -0,0 +1,150 @@ +parameter + (or string nat) ; +storage + (pair + (pair nat (pair mutez mutez)) # counter from_buyer from_seller + (pair + (pair nat (pair timestamp timestamp)) # Q T Z + (pair + (pair mutez mutez) # K C + (pair + (pair address address) # B S + address)))) ; # W +code + { DUP ; CDDADDR ; # Z + PUSH int 86400 ; SWAP ; ADD ; # one day in second + NOW ; COMPARE ; LT ; + IF { # Before Z + 24 + DUP ; CAR ; # we must receive (Left "buyer") or (Left "seller") + IF_LEFT + { DUP ; PUSH string "buyer" ; COMPARE ; EQ ; + IF { DROP ; + DUP ; CDADAR ; # amount already versed by the buyer + DIP { AMOUNT } ; ADD ; # transaction + # then we rebuild the globals + DIP { DUP ; CDADDR } ; PAIR ; # seller amount + PUSH nat 0 ; PAIR ; # delivery counter at 0 + DIP { CDDR } ; PAIR ; # parameters + # and return Unit + NIL operation ; PAIR } + { PUSH string "seller" ; COMPARE ; EQ ; + IF { DUP ; CDADDR ; # amount already versed by the seller + DIP { AMOUNT } ; ADD ; # transaction + # then we rebuild the globals + DIP { DUP ; CDADAR } ; SWAP ; PAIR ; # buyer amount + PUSH nat 0 ; PAIR ; # delivery counter at 0 + DIP { CDDR } ; PAIR ; # parameters + # and return Unit + NIL operation ; PAIR } + { FAIL } } } # (Left _) + { FAIL } } # (Right _) + { # After Z + 24 + # if balance is emptied, just fail + BALANCE ; PUSH mutez 0 ; IFCMPEQ { FAIL } {} ; + # test if the required amount is reached + DUP ; CDDAAR ; # Q + DIP { DUP ; CDDDADR } ; MUL ; # C + PUSH nat 2 ; MUL ; + BALANCE ; COMPARE ; LT ; # balance < 2 * (Q * C) + IF { # refund the parties + CDR ; DUP ; CADAR ; # amount versed by the buyer + DIP { DUP ; CDDDAAR } ; # B + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; SWAP ; + DUP ; CADDR ; # amount versed by the seller + DIP { DUP ; CDDDADR } ; # S + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS ; SWAP ; + DIP { CONS } ; + DUP ; CADAR ; DIP { DUP ; CADDR } ; ADD ; + BALANCE ; SUB_MUTEZ ; ASSERT_SOME; # bonus to the warehouse + DIP { DUP ; CDDDDR } ; # W + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS ; + DIP { SWAP } ; CONS ; + # leave the storage as-is, as the balance is now 0 + PAIR } + { # otherwise continue + DUP ; CDDADAR ; # T + NOW ; COMPARE ; LT ; + IF { FAIL } # Between Z + 24 and T + { # after T + DUP ; CDDADAR ; # T + PUSH int 86400 ; ADD ; # one day in second + NOW ; COMPARE ; LT ; + IF { # Between T and T + 24 + # we only accept transactions from the buyer + DUP ; CAR ; # we must receive (Left "buyer") + IF_LEFT + { PUSH string "buyer" ; COMPARE ; EQ ; + IF { DUP ; CDADAR ; # amount already versed by the buyer + DIP { AMOUNT } ; ADD ; # transaction + # The amount must not exceed Q * K + DUP ; + DIIP { DUP ; CDDAAR ; # Q + DIP { DUP ; CDDDAAR } ; MUL ; } ; # K + DIP { COMPARE ; GT ; # new amount > Q * K + IF { FAIL } { } } ; # abort or continue + # then we rebuild the globals + DIP { DUP ; CDADDR } ; PAIR ; # seller amount + PUSH nat 0 ; PAIR ; # delivery counter at 0 + DIP { CDDR } ; PAIR ; # parameters + # and return Unit + NIL operation ; PAIR } + { FAIL } } # (Left _) + { FAIL } } # (Right _) + { # After T + 24 + # test if the required payment is reached + DUP ; CDDAAR ; # Q + DIP { DUP ; CDDDAAR } ; MUL ; # K + DIP { DUP ; CDADAR } ; # amount already versed by the buyer + COMPARE ; NEQ ; + IF { # not reached, pay the seller + BALANCE ; + DIP { DUP ; CDDDDADR } ; # S + DIIP { CDR } ; + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; PAIR } + { # otherwise continue + DUP ; CDDADAR ; # T + PUSH int 86400 ; ADD ; + PUSH int 86400 ; ADD ; # two days in second + NOW ; COMPARE ; LT ; + IF { # Between T + 24 and T + 48 + # We accept only delivery notifications, from W + DUP ; CDDDDDR ; # W + SENDER ; + COMPARE ; NEQ ; + IF { FAIL } {} ; # fail if not the warehouse + DUP ; CAR ; # we must receive (Right amount) + IF_LEFT + { FAIL } # (Left _) + { # We increment the counter + DIP { DUP ; CDAAR } ; ADD ; + # And rebuild the globals in advance + DIP { DUP ; CDADR } ; PAIR ; + DIP { CDDR } ; PAIR ; + UNIT ; PAIR ; + # We test if enough have been delivered + DUP ; CDAAR ; + DIP { DUP ; CDDAAR } ; + COMPARE ; LT ; # counter < Q + IF { CDR ; NIL operation } # wait for more + { # Transfer all the money to the seller + BALANCE ; + DIP { DUP ; CDDDDADR } ; # S + DIIP { CDR } ; + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS } } ; + PAIR } + { # after T + 48, transfer everything to the buyer + BALANCE ; + DIP { DUP ; CDDDDAAR } ; # B + DIIP { CDR } ; + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; + PAIR} } } } } } } \ No newline at end of file diff --git a/tests_python/contracts_012/attic/id.tz b/tests_python/contracts_012/attic/id.tz new file mode 100644 index 000000000000..4eee565ca2e9 --- /dev/null +++ b/tests_python/contracts_012/attic/id.tz @@ -0,0 +1,3 @@ +parameter string; +storage string; +code {CAR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/attic/infinite_loop.tz b/tests_python/contracts_012/attic/infinite_loop.tz new file mode 100644 index 000000000000..77cdbc48c0d1 --- /dev/null +++ b/tests_python/contracts_012/attic/infinite_loop.tz @@ -0,0 +1,3 @@ +parameter unit; +storage unit; +code { DROP; PUSH bool True; LOOP {PUSH bool True}; UNIT; NIL operation; PAIR } diff --git a/tests_python/contracts_012/attic/insertion_sort.tz b/tests_python/contracts_012/attic/insertion_sort.tz new file mode 100644 index 000000000000..34eca64d092c --- /dev/null +++ b/tests_python/contracts_012/attic/insertion_sort.tz @@ -0,0 +1,16 @@ +parameter (list int) ; +storage (list int) ; +code { CAR ; + NIL int ; SWAP ; + ITER { SWAP; DIIP{NIL int} ; PUSH bool True ; + LOOP + { IF_CONS + { SWAP ; + DIP{DUP ; DIIP{DUP} ; DIP{CMPLT} ; SWAP} ; + SWAP ; + IF { DIP{SWAP ; DIP{CONS}} ; PUSH bool True} + { SWAP ; CONS ; PUSH bool False}} + { NIL int ; PUSH bool False}} ; + SWAP ; CONS ; SWAP ; + ITER {CONS}} ; + NIL operation ; PAIR } diff --git a/tests_python/contracts_012/attic/int_publisher.tz b/tests_python/contracts_012/attic/int_publisher.tz new file mode 100644 index 000000000000..6ee49b979e2c --- /dev/null +++ b/tests_python/contracts_012/attic/int_publisher.tz @@ -0,0 +1,17 @@ +# (signed hash of the string, string) +parameter (option (pair signature int)); +storage (pair key int); +code {DUP; DUP; CAR; + IF_NONE {PUSH mutez 1000000; # Fee pattern from July 26 + AMOUNT; CMPLE; IF {FAIL} {}; + # Provide the data + CDR; DIP {CDDR}} + {DUP; DIP{SWAP}; SWAP; CDAR; # Move key to the top + DIP {DUP; CAR; DIP {CDR; PACK ; BLAKE2B}}; # Arrange the new piece of data + CHECK_SIGNATURE; # Check to ensure the data is authentic + # Update data + IF {CDR; SWAP; DIP{DUP}; CDAR; PAIR} + # Revert the update. This could be replaced with FAIL + {DROP; DUP; CDR; DIP{CDDR}}}; + # Cleanup + DIP{DROP}; NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/king_of_tez.tz b/tests_python/contracts_012/attic/king_of_tez.tz new file mode 100644 index 000000000000..033ead7f168c --- /dev/null +++ b/tests_python/contracts_012/attic/king_of_tez.tz @@ -0,0 +1,19 @@ +parameter key_hash; +storage (pair timestamp (pair mutez key_hash)); +code { DUP; CDAR; + # If the time is more than 2 weeks, any amount makes you king + NOW; CMPGT; + # User becomes king of mutez + IF { CAR; AMOUNT; PAIR; NOW; PUSH int 604800; ADD; PAIR; + NIL operation } + # Check balance to see if user has paid enough to become the new king + { DUP; CDDAR; AMOUNT; CMPLT; + IF { FAIL } # user has not paid out + { CAR; DUP; + # New storage + DIP{ AMOUNT; PAIR; NOW; PUSH int 604800; ADD; PAIR }; + # Pay funds to old king + IMPLICIT_ACCOUNT; AMOUNT; UNIT; TRANSFER_TOKENS; + NIL operation; SWAP; CONS}}; + # Cleanup + PAIR }; diff --git a/tests_python/contracts_012/attic/list_of_transactions.tz b/tests_python/contracts_012/attic/list_of_transactions.tz new file mode 100644 index 000000000000..620ceedd5a67 --- /dev/null +++ b/tests_python/contracts_012/attic/list_of_transactions.tz @@ -0,0 +1,8 @@ +parameter unit; +storage (list address); +code { CDR; DUP; + DIP {NIL operation}; PUSH bool True; # Setup loop + LOOP {IF_CONS { CONTRACT unit ; ASSERT_SOME ; PUSH mutez 1000000; UNIT; TRANSFER_TOKENS; # Make transfer + SWAP; DIP {CONS}; PUSH bool True} # Setup for next round of loop + { NIL address ; PUSH bool False}}; # Data to satisfy types and end loop + DROP; PAIR}; # Calling convention diff --git a/tests_python/contracts_012/attic/queue.tz b/tests_python/contracts_012/attic/queue.tz new file mode 100644 index 000000000000..a074906ddf91 --- /dev/null +++ b/tests_python/contracts_012/attic/queue.tz @@ -0,0 +1,24 @@ +parameter (option string); +storage (pair (option string) (pair (pair nat nat) (map nat string))); +code { DUP; CAR; + # Retrieving an element + IF_NONE { CDDR; DUP; CAR; DIP{CDR; DUP}; DUP; + CAR; SWAP; DIP{GET}; # Check if an element is available + SWAP; + # Put NONE on stack and finish + IF_NONE { NONE string; DIP{PAIR}; PAIR} + # Reoption the element and remove the entry from the map + { SOME; + DIP{ DUP; DIP{ CAR; DIP{ NONE string }; UPDATE }; + # Increment the counter and cleanup + DUP; CAR; PUSH nat 1; ADD; DIP{ CDR }; PAIR; PAIR}; + PAIR }} + # Arrange the stack + { DIP{DUP; CDDAR; DIP{CDDDR}; DUP}; SWAP; CAR; + # Add the element to the map + DIP{ SOME; SWAP; CDR; DUP; DIP{UPDATE}; + # Increment the second number + PUSH nat 1; ADD}; + # Cleanup and finish + PAIR; PAIR; NONE string; PAIR }; + NIL operation; PAIR} diff --git a/tests_python/contracts_012/attic/reduce_map.tz b/tests_python/contracts_012/attic/reduce_map.tz new file mode 100644 index 000000000000..aab8ea60d367 --- /dev/null +++ b/tests_python/contracts_012/attic/reduce_map.tz @@ -0,0 +1,16 @@ + +parameter (pair (lambda int int) (list int)); +storage (list int); +code { DIP{NIL int}; + CAR; + DUP; + DIP{CAR; PAIR}; # Unpack data and setup accumulator + CDR; + ITER {PAIR; + DUP; CDAR; + DIP{ DUP; DIP{CDAR}; DUP; + CAR; DIP{CDDR; SWAP}; EXEC; CONS}; + PAIR}; + CDR; DIP{NIL int}; # First reduce + ITER {CONS}; # Reverse + NIL operation; PAIR} # Calling convention diff --git a/tests_python/contracts_012/attic/reentrancy.tz b/tests_python/contracts_012/attic/reentrancy.tz new file mode 100644 index 000000000000..b9e614a4e53e --- /dev/null +++ b/tests_python/contracts_012/attic/reentrancy.tz @@ -0,0 +1,7 @@ +parameter unit; +storage (pair address address); +code { CDR; DUP; CAR; + CONTRACT unit ; ASSERT_SOME ; PUSH mutez 5000000; UNIT; TRANSFER_TOKENS; + DIP {DUP; CDR; + CONTRACT unit ; ASSERT_SOME ; PUSH mutez 5000000; UNIT; TRANSFER_TOKENS}; + DIIP{NIL operation};DIP{CONS};CONS;PAIR}; diff --git a/tests_python/contracts_012/attic/reservoir.tz b/tests_python/contracts_012/attic/reservoir.tz new file mode 100644 index 000000000000..291e09b262b5 --- /dev/null +++ b/tests_python/contracts_012/attic/reservoir.tz @@ -0,0 +1,25 @@ +parameter unit ; +storage + (pair + (pair (timestamp %T) (mutez %N)) + (pair (address %A) (address %B))) ; +code + { CDR ; DUP ; CAAR %T; # T + NOW ; COMPARE ; LE ; + IF { DUP ; CADR %N; # N + BALANCE ; + COMPARE ; LE ; + IF { NIL operation ; PAIR } + { DUP ; CDDR %B; # B + CONTRACT unit ; ASSERT_SOME ; + BALANCE ; UNIT ; + TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; + PAIR } } + { DUP ; CDAR %A; # A + CONTRACT unit ; ASSERT_SOME ; + BALANCE ; + UNIT ; + TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; + PAIR } } diff --git a/tests_python/contracts_012/attic/scrutable_reservoir.tz b/tests_python/contracts_012/attic/scrutable_reservoir.tz new file mode 100644 index 000000000000..d415cdda0f54 --- /dev/null +++ b/tests_python/contracts_012/attic/scrutable_reservoir.tz @@ -0,0 +1,67 @@ +parameter unit ; +storage + (pair + string # S + (pair + timestamp # T + (pair + (pair mutez mutez) # P N + (pair + address # X + (pair address address))))) ; # A B +code + { DUP ; CDAR ; # S + PUSH string "open" ; + COMPARE ; NEQ ; + IF { FAIL } # on "success", "timeout" or a bad init value + { DUP ; CDDAR ; # T + NOW ; + COMPARE ; LT ; + IF { # Before timeout + # We compute (P + N) mutez + PUSH mutez 0 ; + DIP { DUP ; CDDDAAR } ; ADD ; # P + DIP { DUP ; CDDDADR } ; ADD ; # N + # We compare to the cumulated amount + BALANCE ; + COMPARE; LT ; + IF { # Not enough cash, we just accept the transaction + # and leave the global untouched + CDR ; NIL operation ; PAIR } + { # Enough cash, successful ending + # We update the global + CDDR ; PUSH string "success" ; PAIR ; + # We transfer the fee to the broker + DUP ; CDDAAR ; # P + DIP { DUP ; CDDDAR } ; # X + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS ; + # We transfer the rest to A + DIP { DUP ; CDDADR ; # N + DIP { DUP ; CDDDDAR } ; # A + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS } ; + NIL operation ; SWAP ; CONS ; SWAP ; CONS ; + PAIR } } + { # After timeout, we refund + # We update the global + CDDR ; PUSH string "timeout" ; PAIR ; + # We try to transfer the fee to the broker + BALANCE ; # available + DIP { DUP ; CDDAAR } ; # P + COMPARE ; LT ; # available < P + IF { BALANCE ; # available + DIP { DUP ; CDDDAR } ; # X + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS } + { DUP ; CDDAAR ; # P + DIP { DUP ; CDDDAR } ; # X + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS } ; + # We transfer the rest to B + DIP { BALANCE ; # available + DIP { DUP ; CDDDDDR } ; # B + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT ; TRANSFER_TOKENS } ; + NIL operation ; SWAP ; CONS ; SWAP ; CONS ; + PAIR } } } diff --git a/tests_python/contracts_012/attic/spawn_identities.tz b/tests_python/contracts_012/attic/spawn_identities.tz new file mode 100644 index 000000000000..2208e0d0928d --- /dev/null +++ b/tests_python/contracts_012/attic/spawn_identities.tz @@ -0,0 +1,20 @@ +parameter nat; +storage (list address); +code { DUP; + CAR; # Get the number + DIP{CDR; NIL operation}; # Put the accumulators on the stack + PUSH bool True; # Push true so we have a do while loop + LOOP { DUP; PUSH nat 0; CMPEQ; # Check if the number is 0 + IF { PUSH bool False} # End the loop + { PUSH nat 1; SWAP; SUB; ABS; # Subtract 1. The ABS is to make it back into a nat + PUSH string "init"; # Storage type + PUSH mutez 5000000; # Starting balance + NONE key_hash; + CREATE_CONTRACT + { parameter string ; + storage string ; + code { CAR ; NIL operation ; PAIR } } ; # Make the contract + SWAP ; DIP { SWAP ; DIP { CONS } } ; # emit the operation + SWAP ; DIP { SWAP ; DIP { CONS } } ; # add to the list + PUSH bool True}}; # Continue the loop + DROP; PAIR} # Calling convention diff --git a/tests_python/contracts_012/entrypoints/big_map_entrypoints.tz b/tests_python/contracts_012/entrypoints/big_map_entrypoints.tz new file mode 100644 index 000000000000..d49e6257167a --- /dev/null +++ b/tests_python/contracts_012/entrypoints/big_map_entrypoints.tz @@ -0,0 +1,31 @@ +storage + (pair (big_map string nat) (big_map string nat)) ; +parameter + (or (unit %default) + (or (or %mem (string %mem_left) (string %mem_right)) + (or (or %add (pair %add_left string nat) (pair %add_right string nat)) + (or %rem (string %rem_left) (string %rem_right))))) ; +code { UNPAIR ; + IF_LEFT + { DROP ; + DUP ; CAR ; + PUSH mutez 0 ; + NONE key_hash ; + CREATE_CONTRACT + { parameter string ; + storage (big_map string nat) ; + code { UNPAIR ; DROP ; NIL operation ; PAIR }} ; + DIP { DROP } ; + NIL operation ; SWAP ; CONS ; PAIR } + { IF_LEFT + { IF_LEFT + { DIP { UNPAIR } ; DIP { DUP } ; MEM ; ASSERT } + { DIP { UNPAIR ; SWAP } ; DIP { DUP } ; MEM ; ASSERT ; SWAP } } + { IF_LEFT + { IF_LEFT + { UNPAIR ; DIIP { UNPAIR } ; DIP { SOME } ; UPDATE } + { UNPAIR ; DIIP { UNPAIR ; SWAP } ; DIP { SOME } ; UPDATE ; SWAP } } + { IF_LEFT + { DIP { UNPAIR } ; DIP { NONE nat } ; UPDATE } + { DIP { UNPAIR ; SWAP } ; DIP { NONE nat } ; UPDATE ; SWAP } } } ; + PAIR ; NIL operation ; PAIR } } diff --git a/tests_python/contracts_012/entrypoints/delegatable_target.tz b/tests_python/contracts_012/entrypoints/delegatable_target.tz new file mode 100644 index 000000000000..0db00f4945ed --- /dev/null +++ b/tests_python/contracts_012/entrypoints/delegatable_target.tz @@ -0,0 +1,79 @@ +# Michelson pseudo-code to transform from source script. + # This transformation adds 'set_delegate' entrypoint, e.g.: + # + # parameter ; + # storage ; + # code ; + # + # to: +parameter + (or + (or (key_hash %set_delegate) + (unit %remove_delegate)) + (or %default string nat) + ) ; + +storage + (pair + key_hash # manager + (pair string nat) + ) ; + +code { + DUP ; + CAR ; + IF_LEFT + { # 'set_delegate'/'remove_delegate' entrypoints + # Assert no token was sent: + # to send tokens, the default entry point should be used + PUSH mutez 0 ; + AMOUNT ; + ASSERT_CMPEQ ; + # Assert that the sender is the manager + DUUP ; + CDR ; + CAR ; + IMPLICIT_ACCOUNT ; ADDRESS ; + SENDER ; + IFCMPNEQ + { SENDER ; + PUSH string "Only the owner can operate." ; + PAIR ; + FAILWITH ; + } + { DIP { CDR ; NIL operation } ; + IF_LEFT + { # 'set_delegate' entrypoint + SOME ; + SET_DELEGATE ; + CONS ; + PAIR ; + } + { # 'remove_delegate' entrypoint + DROP ; + NONE key_hash ; + SET_DELEGATE ; + CONS ; + PAIR ; + } + } + } + { # Transform the inputs to the original script types + DIP { CDR ; DUP ; CDR } ; + PAIR ; + + # 'default' entrypoint - original code + { UNPAIR; + IF_LEFT + { DIP { UNPAIR ; DROP } } + { DUG 1; UNPAIR ; DIP { DROP } } ; + PAIR ; NIL operation ; PAIR } + # Transform the outputs to the new script types (manager's storage is unchanged) + SWAP ; + CAR ; + SWAP ; + UNPAIR ; + DIP { SWAP ; PAIR } ; + PAIR ; + } + } diff --git a/tests_python/contracts_012/entrypoints/manager.tz b/tests_python/contracts_012/entrypoints/manager.tz new file mode 100644 index 000000000000..06d9b1067bf4 --- /dev/null +++ b/tests_python/contracts_012/entrypoints/manager.tz @@ -0,0 +1,31 @@ +parameter + (or + (lambda %do unit (list operation)) + (unit %default)); +storage key_hash; +code + { UNPAIR ; + IF_LEFT + { # 'do' entrypoint + # Assert no token was sent: + # to send tokens, the default entry point should be used + PUSH mutez 0 ; + AMOUNT ; + ASSERT_CMPEQ ; + # Assert that the sender is the manager + DUUP ; + IMPLICIT_ACCOUNT ; + ADDRESS ; + SENDER ; + ASSERT_CMPEQ ; + # Execute the lambda argument + UNIT ; + EXEC ; + PAIR ; + } + { # 'default' entrypoint + DROP ; + NIL operation ; + PAIR ; + } + }; diff --git a/tests_python/contracts_012/entrypoints/no_default_target.tz b/tests_python/contracts_012/entrypoints/no_default_target.tz new file mode 100644 index 000000000000..48d5d53df996 --- /dev/null +++ b/tests_python/contracts_012/entrypoints/no_default_target.tz @@ -0,0 +1,11 @@ +storage (pair string nat) ; +parameter + (or unit (or %data string nat)) ; +code { UNPAIR ; + IF_LEFT + { DROP ; NIL operation ; PAIR } + { IF_LEFT + { DIP { UNPAIR ; DROP } } + { DUG 1; UNPAIR ; DIP { DROP } } ; + PAIR ; NIL operation ; PAIR } + } diff --git a/tests_python/contracts_012/entrypoints/no_entrypoint_target.tz b/tests_python/contracts_012/entrypoints/no_entrypoint_target.tz new file mode 100644 index 000000000000..d8041507d58c --- /dev/null +++ b/tests_python/contracts_012/entrypoints/no_entrypoint_target.tz @@ -0,0 +1,11 @@ +storage (pair string nat) ; +parameter + (or unit (or string nat)) ; +code { UNPAIR ; + IF_LEFT + { DROP ; NIL operation ; PAIR } + { IF_LEFT + { DIP { UNPAIR ; DROP } } + { DUG 1; UNPAIR ; DIP { DROP } } ; + PAIR ; NIL operation ; PAIR } + } diff --git a/tests_python/contracts_012/entrypoints/rooted_target.tz b/tests_python/contracts_012/entrypoints/rooted_target.tz new file mode 100644 index 000000000000..2ca2dfb1296d --- /dev/null +++ b/tests_python/contracts_012/entrypoints/rooted_target.tz @@ -0,0 +1,11 @@ +storage (pair string nat) ; +parameter + (or %root unit (or %default string nat)) ; +code { UNPAIR ; + IF_LEFT + { DROP ; NIL operation ; PAIR } + { IF_LEFT + { DIP { UNPAIR ; DROP } } + { DUG 1; UNPAIR ; DIP { DROP } } ; + PAIR ; NIL operation ; PAIR } + } diff --git a/tests_python/contracts_012/entrypoints/simple_entrypoints.tz b/tests_python/contracts_012/entrypoints/simple_entrypoints.tz new file mode 100644 index 000000000000..7b7abb7cb86e --- /dev/null +++ b/tests_python/contracts_012/entrypoints/simple_entrypoints.tz @@ -0,0 +1,4 @@ +# A trivial contract with some entrypoints +parameter (or (unit %A) (or (string %B) (nat %C))) ; +storage unit; +code { CDR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/ill_typed/badly_indented.tz b/tests_python/contracts_012/ill_typed/badly_indented.tz new file mode 100644 index 000000000000..0fc54663a9f9 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/badly_indented.tz @@ -0,0 +1,3 @@ +parameter string; + storage string; + code {CAR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/ill_typed/big_dip.tz b/tests_python/contracts_012/ill_typed/big_dip.tz new file mode 100644 index 000000000000..697370fdc87e --- /dev/null +++ b/tests_python/contracts_012/ill_typed/big_dip.tz @@ -0,0 +1,4 @@ +parameter unit; +storage unit; +code { DIP 1073741824 { }; # = 0x3fffffff + 1 + DROP; } diff --git a/tests_python/contracts_012/ill_typed/big_drop.tz b/tests_python/contracts_012/ill_typed/big_drop.tz new file mode 100644 index 000000000000..40d81cf8448b --- /dev/null +++ b/tests_python/contracts_012/ill_typed/big_drop.tz @@ -0,0 +1,4 @@ +parameter unit; +storage unit; +code { DROP 1073741824; # = 0x3fffffff + 1 + DROP; } diff --git a/tests_python/contracts_012/ill_typed/big_map_arity.tz b/tests_python/contracts_012/ill_typed/big_map_arity.tz new file mode 100644 index 000000000000..5e5a7d60d5b7 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/big_map_arity.tz @@ -0,0 +1,5 @@ +# This contract tests the error message in case the EMPTY_BIG_MAP instruction has bad arity (1 argument instead of 2). +# The expected type-checking error is "primitive EMPTY_BIG_MAP expects 2 arguments but is given 1." +parameter unit; +storage unit; +code { DROP; EMPTY_BIG_MAP nat; DROP; UNIT; NIL operation; PAIR; } diff --git a/tests_python/contracts_012/ill_typed/chain_id_arity.tz b/tests_python/contracts_012/ill_typed/chain_id_arity.tz new file mode 100644 index 000000000000..4bc9f4f70107 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/chain_id_arity.tz @@ -0,0 +1,3 @@ +parameter (chain_id nat); +storage unit; +code { CDR; NIL operation; PAIR } diff --git a/tests_python/contracts_012/ill_typed/comb0.tz b/tests_python/contracts_012/ill_typed/comb0.tz new file mode 100644 index 000000000000..ab3c79153035 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/comb0.tz @@ -0,0 +1,3 @@ +parameter unit; +storage unit; +code { PAIR 0 } diff --git a/tests_python/contracts_012/ill_typed/comb1.tz b/tests_python/contracts_012/ill_typed/comb1.tz new file mode 100644 index 000000000000..07b709d61cfd --- /dev/null +++ b/tests_python/contracts_012/ill_typed/comb1.tz @@ -0,0 +1,3 @@ +parameter unit; +storage unit; +code { PAIR 1 } diff --git a/tests_python/contracts_012/ill_typed/contract_annotation_default.tz b/tests_python/contracts_012/ill_typed/contract_annotation_default.tz new file mode 100644 index 000000000000..742e140c5e48 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/contract_annotation_default.tz @@ -0,0 +1,11 @@ +parameter (contract (or (or (int %A) (nat %B)) (unit %default))); +storage unit; +code { + CAR; + # CONTRACT %default nat == CONTRACT nat and the former is not allowed. + DUP; ADDRESS; CONTRACT %default nat; ASSERT_SOME; DROP; + DROP; + UNIT; + NIL operation; + PAIR + }; diff --git a/tests_python/contracts_012/ill_typed/dip_failwith.tz b/tests_python/contracts_012/ill_typed/dip_failwith.tz new file mode 100644 index 000000000000..fe3a17b7b1ab --- /dev/null +++ b/tests_python/contracts_012/ill_typed/dip_failwith.tz @@ -0,0 +1,4 @@ +# Test that DIP {FAILWITH} is not allowed by the typechecker +parameter string; +storage nat; +code { UNPAIR; DIP {FAILWITH} } diff --git a/tests_python/contracts_012/ill_typed/dup0.tz b/tests_python/contracts_012/ill_typed/dup0.tz new file mode 100644 index 000000000000..2e46599e490a --- /dev/null +++ b/tests_python/contracts_012/ill_typed/dup0.tz @@ -0,0 +1,3 @@ +parameter unit; +storage unit; +code { DUP 0 } diff --git a/tests_python/contracts_012/ill_typed/failwith_big_map.tz b/tests_python/contracts_012/ill_typed/failwith_big_map.tz new file mode 100644 index 000000000000..33d73c26123c --- /dev/null +++ b/tests_python/contracts_012/ill_typed/failwith_big_map.tz @@ -0,0 +1,22 @@ +# This contract uses FAILWITH to expose a big map diff +# See https://gitlab.com/tezos/tezos/-/issues/1708#note_667884499 + +parameter (big_map int int); + +# Even if the stored big_map is dropped by the initial CAR instruction, +# it can still be accessed by its big-map id and sent as parameter so +# it is important that the type of the storage matches the type of the +# parameter. + +# This test is now ill-typed because FAILWITH accepts only packable types + +storage (big_map int int); + +code { CAR; + PUSH (option int) (Some 1); + PUSH int 1; + UPDATE; + PUSH (option int) None; + PUSH int 2; + UPDATE; + FAILWITH } diff --git a/tests_python/contracts_012/ill_typed/invalid_self_entrypoint.tz b/tests_python/contracts_012/ill_typed/invalid_self_entrypoint.tz new file mode 100644 index 000000000000..4fac9c635044 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/invalid_self_entrypoint.tz @@ -0,0 +1,10 @@ +parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))); +storage unit; +code { + DROP; + # This entrypoint does not exist + SELF %D; DROP; + UNIT; + NIL operation; + PAIR; + } diff --git a/tests_python/contracts_012/ill_typed/map_failwith.tz b/tests_python/contracts_012/ill_typed/map_failwith.tz new file mode 100644 index 000000000000..e3e19c0784ce --- /dev/null +++ b/tests_python/contracts_012/ill_typed/map_failwith.tz @@ -0,0 +1,4 @@ +# Test that MAP {FAILWITH} is not allowed by the typechecker +parameter (list nat); +storage unit; +code { UNPAIR; MAP {FAILWITH}; DROP; NIL operation; PAIR } diff --git a/tests_python/contracts_012/ill_typed/missing_only_code_field.tz b/tests_python/contracts_012/ill_typed/missing_only_code_field.tz new file mode 100644 index 000000000000..4b5b2cd62f56 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/missing_only_code_field.tz @@ -0,0 +1,2 @@ +storage unit; +parameter nat; \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/missing_only_parameter_field.tz b/tests_python/contracts_012/ill_typed/missing_only_parameter_field.tz new file mode 100644 index 000000000000..1f7e8ac75da9 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/missing_only_parameter_field.tz @@ -0,0 +1,4 @@ +storage unit; +code { CAR; + DUP; NEG; ABS; COMPARE; ASSERT_EQ; + UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/missing_only_storage_field.tz b/tests_python/contracts_012/ill_typed/missing_only_storage_field.tz new file mode 100644 index 000000000000..2aa28922287a --- /dev/null +++ b/tests_python/contracts_012/ill_typed/missing_only_storage_field.tz @@ -0,0 +1,4 @@ +parameter nat; +code { CAR; + DUP; NEG; ABS; COMPARE; ASSERT_EQ; + UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/missing_parameter_and_storage_fields.tz b/tests_python/contracts_012/ill_typed/missing_parameter_and_storage_fields.tz new file mode 100644 index 000000000000..18e7b35b0a8c --- /dev/null +++ b/tests_python/contracts_012/ill_typed/missing_parameter_and_storage_fields.tz @@ -0,0 +1,3 @@ +code { CAR; + DUP; NEG; ABS; COMPARE; ASSERT_EQ; + UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/multiple_code_field.tz b/tests_python/contracts_012/ill_typed/multiple_code_field.tz new file mode 100644 index 000000000000..cd47b356d14e --- /dev/null +++ b/tests_python/contracts_012/ill_typed/multiple_code_field.tz @@ -0,0 +1,6 @@ +parameter nat; +storage unit; +code { CAR; + DUP; NEG; ABS; COMPARE; ASSERT_EQ; + UNIT; NIL operation; PAIR }; +code {} \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/multiple_parameter_field.tz b/tests_python/contracts_012/ill_typed/multiple_parameter_field.tz new file mode 100644 index 000000000000..e59fb9fe05be --- /dev/null +++ b/tests_python/contracts_012/ill_typed/multiple_parameter_field.tz @@ -0,0 +1,6 @@ +parameter nat; +parameter nat; +storage unit; +code { CAR; + DUP; NEG; ABS; COMPARE; ASSERT_EQ; + UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/multiple_storage_and_code_fields.tz b/tests_python/contracts_012/ill_typed/multiple_storage_and_code_fields.tz new file mode 100644 index 000000000000..3b32484dc200 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/multiple_storage_and_code_fields.tz @@ -0,0 +1,7 @@ +parameter nat; +storage unit; +storage unit; +code { CAR; + DUP; NEG; ABS; COMPARE; ASSERT_EQ; + UNIT; NIL operation; PAIR }; +code {} \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/multiple_storage_field.tz b/tests_python/contracts_012/ill_typed/multiple_storage_field.tz new file mode 100644 index 000000000000..06c25f51d3b2 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/multiple_storage_field.tz @@ -0,0 +1,6 @@ +parameter nat; +storage unit; +storage unit; +code { CAR; + DUP; NEG; ABS; COMPARE; ASSERT_EQ; + UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/never_literal.tz b/tests_python/contracts_012/ill_typed/never_literal.tz new file mode 100644 index 000000000000..ba36b3b5f205 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/never_literal.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { + PUSH never {}; + FAILWITH + } diff --git a/tests_python/contracts_012/ill_typed/pack_big_map.tz b/tests_python/contracts_012/ill_typed/pack_big_map.tz new file mode 100644 index 000000000000..29ae0d665051 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/pack_big_map.tz @@ -0,0 +1,7 @@ +parameter unit; +storage (pair (big_map int int) unit); +code { CDAR; + DUP; PACK; DROP; + UNIT; SWAP; PAIR; + NIL operation; + PAIR; } diff --git a/tests_python/contracts_012/ill_typed/pack_operation.tz b/tests_python/contracts_012/ill_typed/pack_operation.tz new file mode 100644 index 000000000000..349ca053af27 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/pack_operation.tz @@ -0,0 +1,20 @@ +parameter unit; +storage unit; +code { DROP; + UNIT; # starting storage for contract + AMOUNT; # Push the starting balance + NONE key_hash; # No delegate + CREATE_CONTRACT # Create the contract + { parameter unit ; + storage unit ; + code + { CDR; + NIL operation; + PAIR; } }; + DIP { DROP }; + # invalid PACK + PACK; + DROP; + UNIT; + NIL operation; + PAIR; } diff --git a/tests_python/contracts_012/ill_typed/pack_sapling_state.tz b/tests_python/contracts_012/ill_typed/pack_sapling_state.tz new file mode 100644 index 000000000000..0524d9b27911 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/pack_sapling_state.tz @@ -0,0 +1,13 @@ +# Verify SAPLING_STATE is not packable. The contract should not typecheck when using `PACK`. +# The lines below PACK are present only in case of PACK allows SAPLING_STATE to +# make the typechecker happy. +parameter unit; +storage (sapling_state 8); +code { UNPAIR; + DROP; + PACK; + DROP; + SAPLING_EMPTY_STATE 8; + NIL operation; + PAIR; + } diff --git a/tests_python/contracts_012/ill_typed/push_big_map_with_id_with_parens.tz b/tests_python/contracts_012/ill_typed/push_big_map_with_id_with_parens.tz new file mode 100644 index 000000000000..2c659e9a639d --- /dev/null +++ b/tests_python/contracts_012/ill_typed/push_big_map_with_id_with_parens.tz @@ -0,0 +1,10 @@ +# This contract verifies it is not possible to use the instruction `PUSH big_map +# tk tv i` where i is the ID of an existing big_map +parameter int; +storage (big_map string nat); +code { UNPAIR; + DROP; + PUSH (big_map string nat) 0; + NIL operation; + PAIR + } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/push_big_map_with_id_without_parens.tz b/tests_python/contracts_012/ill_typed/push_big_map_with_id_without_parens.tz new file mode 100644 index 000000000000..c5eeef97c7e3 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/push_big_map_with_id_without_parens.tz @@ -0,0 +1,11 @@ +# This contract verifies it is not possible to use the instruction `PUSH big_map +# tk tv i` where i is the ID of an existing big_map +parameter int; +storage (big_map string nat); +code { + UNPAIR; + DROP; + PUSH big_map string nat 0; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/sapling_build_empty_state_with_int_parameter.tz b/tests_python/contracts_012/ill_typed/sapling_build_empty_state_with_int_parameter.tz new file mode 100644 index 000000000000..21b48391060b --- /dev/null +++ b/tests_python/contracts_012/ill_typed/sapling_build_empty_state_with_int_parameter.tz @@ -0,0 +1,10 @@ +parameter nat; +storage (sapling_state 8); +code { + UNPAIR; + SWAP; + DROP; + SAPLING_EMPTY_STATE; + NIL operation; + PAIR; + }; diff --git a/tests_python/contracts_012/ill_typed/set_update_non_comparable.tz b/tests_python/contracts_012/ill_typed/set_update_non_comparable.tz new file mode 100644 index 000000000000..4a70691793c7 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/set_update_non_comparable.tz @@ -0,0 +1,9 @@ +# This contract tests the error message in case the UPDATE instruction on set +# is used with a non-comparable type +parameter (set nat); +storage unit; +code { CAR; + PUSH bool True; + NIL operation; + UPDATE; + UNIT; NIL operation; PAIR; } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undig2able.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undig2able.tz new file mode 100644 index 000000000000..6f7061e004a0 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_undig2able.tz @@ -0,0 +1,5 @@ +parameter unit; +storage unit; +code { + DIG 2; + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undigable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undigable.tz new file mode 100644 index 000000000000..2aba7d303eaf --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_undigable.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { + DROP; + DIG 0; + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undip2able.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undip2able.tz new file mode 100644 index 000000000000..e048a24f74b8 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_undip2able.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { + DUP; + DIP 2 { DUP }; + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undipable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undipable.tz new file mode 100644 index 000000000000..09f94b133e50 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_undipable.tz @@ -0,0 +1,5 @@ +parameter unit; +storage unit; +code { + DIP { DUP }; + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undropable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undropable.tz new file mode 100644 index 000000000000..d33142cdb82b --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_undropable.tz @@ -0,0 +1,5 @@ +parameter unit; +storage unit; +code { + DROP 2; + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undug2able.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undug2able.tz new file mode 100644 index 000000000000..5eef1da706f2 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_undug2able.tz @@ -0,0 +1,5 @@ +parameter unit; +storage unit; +code { + DUG 2; + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undugable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undugable.tz new file mode 100644 index 000000000000..eaf5d7d486e7 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_undugable.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { + DROP; + DUG 0; + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_undup2able.tz b/tests_python/contracts_012/ill_typed/stack_bottom_undup2able.tz new file mode 100644 index 000000000000..c760764fd5b2 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_undup2able.tz @@ -0,0 +1,5 @@ +parameter unit; +storage unit; +code { + DUP 2; + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unfailwithable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unfailwithable.tz new file mode 100644 index 000000000000..c8cf263e5dcc --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_unfailwithable.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { + DROP; + FAILWITH; + } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_ungetable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_ungetable.tz new file mode 100644 index 000000000000..6bc5a629e2a4 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_ungetable.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { + DROP; + GET; + } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unleftable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unleftable.tz new file mode 100644 index 000000000000..0bc846effa3b --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_unleftable.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { + DROP; + LEFT unit; + } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unpairable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unpairable.tz new file mode 100644 index 000000000000..70f7e3a40c10 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_unpairable.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { + DROP; + UNPAIR; + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unpopable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unpopable.tz new file mode 100644 index 000000000000..0f1d8ea456a2 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_unpopable.tz @@ -0,0 +1,10 @@ +parameter unit; +storage unit; +code { + DROP ; + DUP ; + DROP ; + PUSH unit Unit ; + NIL operation ; + PAIR + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unpopable_in_lambda.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unpopable_in_lambda.tz new file mode 100644 index 000000000000..4299b8bef474 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_unpopable_in_lambda.tz @@ -0,0 +1,10 @@ +parameter unit; +storage unit; +code { + DROP ; + LAMBDA int unit { DROP ; DUP }; + DROP ; + PUSH unit Unit ; + NIL operation ; + PAIR + } diff --git a/tests_python/contracts_012/ill_typed/stack_bottom_unrightable.tz b/tests_python/contracts_012/ill_typed/stack_bottom_unrightable.tz new file mode 100644 index 000000000000..a7cf3d06a470 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/stack_bottom_unrightable.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { + DROP; + RIGHT unit; + } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/ticket_apply.tz b/tests_python/contracts_012/ill_typed/ticket_apply.tz new file mode 100644 index 000000000000..a77fb08a6611 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/ticket_apply.tz @@ -0,0 +1,17 @@ +# This script attempts to duplicate a ticket by capturing it using APPLY. +# Is should fail at parsing because tickets are not packable so they are +# not allowed to be captured by APPLY. +parameter (ticket unit); +storage (option (pair (ticket unit) (ticket unit))); +code { + CAR; + LAMBDA (pair (ticket unit) unit) (ticket unit) { CAR }; + SWAP; APPLY; + DUP; + UNIT; EXEC; SWAP; + UNIT; EXEC; + PAIR; + SOME; + NIL operation; + PAIR + } diff --git a/tests_python/contracts_012/ill_typed/ticket_dup.tz b/tests_python/contracts_012/ill_typed/ticket_dup.tz new file mode 100644 index 000000000000..fee0ea3785bc --- /dev/null +++ b/tests_python/contracts_012/ill_typed/ticket_dup.tz @@ -0,0 +1,3 @@ +parameter (ticket %store nat) ; +storage unit; +code { UNPAIR; DUP; DROP 2; NIL operation; PAIR } diff --git a/tests_python/contracts_012/ill_typed/ticket_in_ticket.tz b/tests_python/contracts_012/ill_typed/ticket_in_ticket.tz new file mode 100644 index 000000000000..ee6bdf238723 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/ticket_in_ticket.tz @@ -0,0 +1,16 @@ +# This script attempts to duplicate a ticket by storing it +# in another ticket and calling READ_TICKET twice on it. +# It should fail at parsing because ticket contents must be +# comparable so (ticket (ticket unit)) cannot be built. +parameter (ticket unit); +storage (option (pair (ticket unit) (ticket unit))); +code { + CAR; + PUSH nat 0; + SWAP; + TICKET; + READ_TICKET; CDR; CAR; + SWAP; READ_TICKET; CDR; CAR; + SWAP; DROP; + PAIR; SOME; NIL operation; PAIR + } \ No newline at end of file diff --git a/tests_python/contracts_012/ill_typed/ticket_unpack.tz b/tests_python/contracts_012/ill_typed/ticket_unpack.tz new file mode 100644 index 000000000000..888746f42eb0 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/ticket_unpack.tz @@ -0,0 +1,5 @@ +# UNPACK on ticket should produce a type error +parameter unit; +storage (option (ticket nat)); +code { DROP ; PUSH nat 2 ; PACK ; UNPACK (ticket nat) ; + NIL operation ; PAIR } diff --git a/tests_python/contracts_012/ill_typed/uncomb0.tz b/tests_python/contracts_012/ill_typed/uncomb0.tz new file mode 100644 index 000000000000..9c3370912937 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/uncomb0.tz @@ -0,0 +1,3 @@ +parameter unit; +storage unit; +code { UNPAIR 0 } diff --git a/tests_python/contracts_012/ill_typed/uncomb1.tz b/tests_python/contracts_012/ill_typed/uncomb1.tz new file mode 100644 index 000000000000..6cc515335072 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/uncomb1.tz @@ -0,0 +1,3 @@ +parameter unit; +storage unit; +code { UNPAIR 1 } diff --git a/tests_python/contracts_012/ill_typed/unpack_sapling_state.tz b/tests_python/contracts_012/ill_typed/unpack_sapling_state.tz new file mode 100644 index 000000000000..a80f81eb84b6 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/unpack_sapling_state.tz @@ -0,0 +1,12 @@ +# Verify SAPLING_STATE is not packable. The contract should not typecheck when using `UNPACK`. +# The lines below UNPACK are present only in case of UNPACK allows SAPLING_STATE to +# make the typechecker happy. +parameter bytes; +storage (unit); +code { CAR; + UNPACK (sapling_state 8); + DROP; + PUSH unit Unit; + NIL operation; + PAIR; + } diff --git a/tests_python/contracts_012/ill_typed/unpair_field_annotation_mismatch.tz b/tests_python/contracts_012/ill_typed/unpair_field_annotation_mismatch.tz new file mode 100644 index 000000000000..c2b3fe0a498d --- /dev/null +++ b/tests_python/contracts_012/ill_typed/unpair_field_annotation_mismatch.tz @@ -0,0 +1,10 @@ +parameter (unit :param_unit); +storage (unit :u1); +code { DROP ; + + UNIT @b; UNIT @a; PAIR %@ %@; + # Field annotations must match (or be ommited) + DUP; UNPAIR %c %d; DROP 2; + DROP; + + UNIT; NIL operation; PAIR } diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_char_set.tz b/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_char_set.tz new file mode 100644 index 000000000000..1bc14a4facef --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_char_set.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage nat ; +code { CAR ; UNPAIR ; VIEW "^$&*!#~(-=)" nat ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_type.tz b/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_type.tz new file mode 100644 index 000000000000..4bde2b617adc --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_op_bad_name_invalid_type.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage nat ; +code { CAR ; UNPAIR ; VIEW 1 nat ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_name_non_printable_char.tz b/tests_python/contracts_012/ill_typed/view_op_bad_name_non_printable_char.tz new file mode 100644 index 000000000000..22b3f5665af5 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_op_bad_name_non_printable_char.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage nat ; +code { CAR ; UNPAIR ; VIEW "\\x00" nat ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_name_too_long.tz b/tests_python/contracts_012/ill_typed/view_op_bad_name_too_long.tz new file mode 100644 index 000000000000..263ecba19684 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_op_bad_name_too_long.tz @@ -0,0 +1,4 @@ +parameter (pair nat address) ; +storage nat ; +code { CAR ; UNPAIR ; VIEW "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" nat ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; + diff --git a/tests_python/contracts_012/ill_typed/view_op_bad_return_type.tz b/tests_python/contracts_012/ill_typed/view_op_bad_return_type.tz new file mode 100644 index 000000000000..3c9ef69e7ffa --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_op_bad_return_type.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage nat ; +code { CAR ; UNPAIR ; VIEW "add" string; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_dupable_type.tz b/tests_python/contracts_012/ill_typed/view_op_dupable_type.tz new file mode 100644 index 000000000000..45e7ebc43704 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_op_dupable_type.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage nat ; +code { CAR ; UNPAIR ; VIEW "add" (ticket nat); DROP ; PUSH nat 1 ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_invalid_arity.tz b/tests_python/contracts_012/ill_typed/view_op_invalid_arity.tz new file mode 100644 index 000000000000..a56f40d15c54 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_op_invalid_arity.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage nat ; +code { CAR ; UNPAIR ; VIEW "add" ; IF_SOME { } { PUSH nat 1 } ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/ill_typed/view_op_lazy_storage.tz b/tests_python/contracts_012/ill_typed/view_op_lazy_storage.tz new file mode 100644 index 000000000000..82bfb31f0bce --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_op_lazy_storage.tz @@ -0,0 +1,8 @@ +parameter address; +storage (big_map string nat); +code { + CAR; + UNIT; + VIEW "get_map" (big_map string nat); + IF_SOME { PUSH nat 10 ; SOME ; PUSH string "bar"; UPDATE; NIL operation; PAIR; } { FAIL; } + } diff --git a/tests_python/contracts_012/ill_typed/view_op_lazy_storage_type.tz b/tests_python/contracts_012/ill_typed/view_op_lazy_storage_type.tz new file mode 100644 index 000000000000..82bfb31f0bce --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_op_lazy_storage_type.tz @@ -0,0 +1,8 @@ +parameter address; +storage (big_map string nat); +code { + CAR; + UNIT; + VIEW "get_map" (big_map string nat); + IF_SOME { PUSH nat 10 ; SOME ; PUSH string "bar"; UPDATE; NIL operation; PAIR; } { FAIL; } + } diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_input_type.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_input_type.tz new file mode 100644 index 000000000000..9d1551d24285 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_bad_input_type.tz @@ -0,0 +1,4 @@ +parameter nat ; +storage nat ; +code { CAR ; NIL operation ; PAIR } ; +view "add" string nat { UNPAIR; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_char_set.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_char_set.tz new file mode 100644 index 000000000000..f9d2a3f1ad5b --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_char_set.tz @@ -0,0 +1,5 @@ +parameter nat ; +storage nat ; +code { CAR ; NIL operation ; PAIR } ; +view "^$&*!#~(-=)" nat nat { UNPAIR ; ADD } ; + diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_type.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_type.tz new file mode 100644 index 000000000000..fafd89ffd29a --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_invalid_type.tz @@ -0,0 +1,4 @@ +parameter nat ; +storage nat ; +code { CAR ; NIL operation ; PAIR } ; +view 1 nat nat { UNPAIR ; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_non_printable_char.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_non_printable_char.tz new file mode 100644 index 000000000000..7a1128527518 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_non_printable_char.tz @@ -0,0 +1,4 @@ +parameter nat ; +storage nat ; +code { CAR ; NIL operation ; PAIR } ; +view "\\x00" nat nat { UNPAIR ; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_too_long.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_too_long.tz new file mode 100644 index 000000000000..4f61ae081410 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_bad_name_too_long.tz @@ -0,0 +1,4 @@ +parameter nat ; +storage nat ; +code { CAR ; NIL operation ; PAIR } ; +view "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" nat nat { UNPAIR ; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_return_type.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_return_type.tz new file mode 100644 index 000000000000..4572674664ca --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_bad_return_type.tz @@ -0,0 +1,4 @@ +parameter nat ; +storage nat ; +code { CAR ; NIL operation ; PAIR } ; +view "add" nat nat { DROP ; PUSH unit Unit } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_bad_type.tz b/tests_python/contracts_012/ill_typed/view_toplevel_bad_type.tz new file mode 100644 index 000000000000..a56d7bc4f88e --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_bad_type.tz @@ -0,0 +1,7 @@ +{ parameter nat; + storage nat; + code { CAR; NIL operation ; PAIR }; + view "add_v" nat nat { UNPAIR; ADD }; + view "mul_v" nat nat { UNPAIR; PUSH nat 30; LSR; }; +} + diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_input.tz b/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_input.tz new file mode 100644 index 000000000000..c252b2eddb28 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_input.tz @@ -0,0 +1,5 @@ +parameter nat; +storage nat; +code { CAR ; NIL operation ; PAIR } ; +view "dup" (ticket nat) nat { DROP; PUSH nat 1; PUSH nat 1 ; PAIR} ; + diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_output.tz b/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_output.tz new file mode 100644 index 000000000000..17919d0004dc --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_dupable_type_output.tz @@ -0,0 +1,4 @@ +parameter nat; +storage nat; +code { CAR ; NIL operation ; PAIR } ; +view "dup" address (ticket nat) { DROP; PUSH nat 1; PUSH nat 1 ; TICKET } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_duplicated_name.tz b/tests_python/contracts_012/ill_typed/view_toplevel_duplicated_name.tz new file mode 100644 index 000000000000..680b0ab585d1 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_duplicated_name.tz @@ -0,0 +1,5 @@ +parameter nat ; +storage nat ; +code { CAR ; NIL operation ; PAIR } ; +view "add" nat nat { UNPAIR ; ADD } ; +view "add" nat unit { DROP ; PUSH unit Unit } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_invalid_arity.tz b/tests_python/contracts_012/ill_typed/view_toplevel_invalid_arity.tz new file mode 100644 index 000000000000..929e27b6a766 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_invalid_arity.tz @@ -0,0 +1,4 @@ +parameter nat ; +storage nat ; +code { CAR ; NIL operation ; PAIR } ; +view "add" nat nat nat { UNPAIR ; ADD } ; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_input.tz b/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_input.tz new file mode 100644 index 000000000000..3ae7f626a1cf --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_input.tz @@ -0,0 +1,4 @@ +parameter unit; +storage nat; +code { FAIL }; +view "map" (big_map string nat) unit { DROP; UNIT;}; diff --git a/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_output.tz b/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_output.tz new file mode 100644 index 000000000000..b0ecc0503343 --- /dev/null +++ b/tests_python/contracts_012/ill_typed/view_toplevel_lazy_storage_output.tz @@ -0,0 +1,4 @@ +parameter unit; +storage nat; +code { FAIL; }; +view "get_map" unit (big_map string nat) { CDR; CDR; }; diff --git a/tests_python/contracts_012/legacy/create_account.tz b/tests_python/contracts_012/legacy/create_account.tz new file mode 100644 index 000000000000..7cd38465a10b --- /dev/null +++ b/tests_python/contracts_012/legacy/create_account.tz @@ -0,0 +1,29 @@ +/* +- optional storage: the address of the created account +- param: Left [hash]: + + Create an account with manager [hash]; then perform a recursive call + on Right [addr] where [addr] is the address of the newly created + account. + + The created account has an initial balance of 100tz. It is not + delegatable. + +- param: Right [addr]: + + Check that the sender is self and that [addr] is a contract of type + [unit]. Finally store [addr]. + +*/ +parameter (or key_hash address) ; +storage (option address) ; +code { CAR; + IF_LEFT + { DIP { PUSH mutez 100000000 ; PUSH bool False ; NONE key_hash }; + CREATE_ACCOUNT ; + DIP { RIGHT key_hash ; DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS } ; + CONS ; NONE address ; SWAP ; PAIR } + { SELF ; ADDRESS ; SENDER ; IFCMPNEQ { FAIL } {} ; + DUP ; CONTRACT unit ; IF_SOME { DROP ; SOME } { FAIL } ; + NIL operation ; PAIR } } ; diff --git a/tests_python/contracts_012/legacy/create_contract.tz b/tests_python/contracts_012/legacy/create_contract.tz new file mode 100644 index 000000000000..a162044ac62b --- /dev/null +++ b/tests_python/contracts_012/legacy/create_contract.tz @@ -0,0 +1,18 @@ +parameter (or key_hash address); +storage unit; +code { CAR; + IF_LEFT + { DIP { PUSH string "dummy"; + PUSH mutez 100000000 ; PUSH bool False ; + PUSH bool False ; NONE key_hash } ; + CREATE_CONTRACT + { parameter string ; + storage string ; + code { CAR ; NIL operation ; PAIR } } ; + DIP { RIGHT key_hash ; DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS } ; + CONS ; UNIT ; SWAP ; PAIR } + { SELF ; ADDRESS ; SENDER ; IFCMPNEQ { FAIL } {} ; + CONTRACT string ; IF_SOME {} { FAIL } ; + PUSH mutez 0 ; PUSH string "abcdefg" ; TRANSFER_TOKENS ; + NIL operation; SWAP; CONS ; UNIT ; SWAP ; PAIR } }; diff --git a/tests_python/contracts_012/legacy/create_contract_flags.tz b/tests_python/contracts_012/legacy/create_contract_flags.tz new file mode 100644 index 000000000000..888637dd7266 --- /dev/null +++ b/tests_python/contracts_012/legacy/create_contract_flags.tz @@ -0,0 +1,26 @@ +parameter (pair key_hash (pair bool bool)); +storage unit; +code { CAR; + + UNPAPAIR @mgr @spendable @deletagable; + DIP { NONE @delegate key_hash } ; + DIIIIP { UNIT @init; + PUSH @credit mutez 100000000 ; + }; + # type of legacy create_contract + # :: key_hash : option key_hash : bool : bool : mutez : 'g : 'S + # -> operation : address : 'S + CREATE_CONTRACT + { parameter (string %default) ; + storage unit ; + code { DROP; UNIT ; NIL operation ; PAIR } } ; + # simulate create_contract but typecheck for dev + # DROP 6; + # PUSH address "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; + # NONE key_hash; SET_DELEGATE @origination; + DIP { DROP }; + + NIL operation; + SWAP; CONS; + UNIT; SWAP; PAIR + }; diff --git a/tests_python/contracts_012/legacy/create_contract_rootname.tz b/tests_python/contracts_012/legacy/create_contract_rootname.tz new file mode 100644 index 000000000000..13e24ae5cc24 --- /dev/null +++ b/tests_python/contracts_012/legacy/create_contract_rootname.tz @@ -0,0 +1,18 @@ +parameter (or key_hash address); +storage unit; +code { CAR; + IF_LEFT + { DIP { PUSH string "dummy"; + PUSH mutez 100000000 ; PUSH bool False ; + PUSH bool False ; NONE key_hash } ; + CREATE_CONTRACT + { parameter (string %root) ; + storage string ; + code { CAR ; NIL operation ; PAIR } } ; + DIP { RIGHT key_hash ; DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS } ; + CONS ; UNIT ; SWAP ; PAIR } + { SELF ; ADDRESS ; SENDER ; IFCMPNEQ { FAIL } {} ; + CONTRACT string ; IF_SOME {} { FAIL } ; + PUSH mutez 0 ; PUSH string "abcdefg" ; TRANSFER_TOKENS ; + NIL operation; SWAP; CONS ; UNIT ; SWAP ; PAIR } }; diff --git a/tests_python/contracts_012/legacy/originator.tz b/tests_python/contracts_012/legacy/originator.tz new file mode 100644 index 000000000000..c454e230dc6d --- /dev/null +++ b/tests_python/contracts_012/legacy/originator.tz @@ -0,0 +1,16 @@ +parameter nat ; +storage (list address) ; +code + { DUP ; CAR ; PUSH nat 0 ; CMPNEQ ; + DIP { DUP ; CAR ; DIP { CDR ; NIL operation } } ; + LOOP + { PUSH mutez 5000000 ; + PUSH bool True ; # delegatable + NONE key_hash ; # delegate + PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ; # manager + CREATE_ACCOUNT ; + SWAP ; DIP { SWAP ; DIP { CONS } } ; + SWAP ; DIP { SWAP ; DIP { CONS } } ; + PUSH nat 1 ; SWAP ; SUB ; ABS ; + DUP ; PUSH nat 0 ; CMPNEQ } ; + DROP ; PAIR } diff --git a/tests_python/contracts_012/legacy/steps_to_quota.tz b/tests_python/contracts_012/legacy/steps_to_quota.tz new file mode 100644 index 000000000000..78e76e308931 --- /dev/null +++ b/tests_python/contracts_012/legacy/steps_to_quota.tz @@ -0,0 +1,12 @@ +parameter int ; +storage nat ; +code { CAR; + DUP; + GT; + LOOP { PUSH int 1; SWAP; SUB; DUP; GT; }; + DROP; + STEPS_TO_QUOTA; + # PUSH nat 1; + NIL operation; + PAIR; + }; diff --git a/tests_python/contracts_012/macros/assert.tz b/tests_python/contracts_012/macros/assert.tz new file mode 100644 index 000000000000..6c5ce503b551 --- /dev/null +++ b/tests_python/contracts_012/macros/assert.tz @@ -0,0 +1,3 @@ +parameter bool; +storage unit; +code {CAR; ASSERT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmpeq.tz b/tests_python/contracts_012/macros/assert_cmpeq.tz new file mode 100644 index 000000000000..55621bac8fe3 --- /dev/null +++ b/tests_python/contracts_012/macros/assert_cmpeq.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPEQ; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmpge.tz b/tests_python/contracts_012/macros/assert_cmpge.tz new file mode 100644 index 000000000000..e98b17044541 --- /dev/null +++ b/tests_python/contracts_012/macros/assert_cmpge.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPGE; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmpgt.tz b/tests_python/contracts_012/macros/assert_cmpgt.tz new file mode 100644 index 000000000000..7a44174b7259 --- /dev/null +++ b/tests_python/contracts_012/macros/assert_cmpgt.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPGT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmple.tz b/tests_python/contracts_012/macros/assert_cmple.tz new file mode 100644 index 000000000000..e4b61cfc44c3 --- /dev/null +++ b/tests_python/contracts_012/macros/assert_cmple.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPLE; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmplt.tz b/tests_python/contracts_012/macros/assert_cmplt.tz new file mode 100644 index 000000000000..290b495378df --- /dev/null +++ b/tests_python/contracts_012/macros/assert_cmplt.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPLT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_cmpneq.tz b/tests_python/contracts_012/macros/assert_cmpneq.tz new file mode 100644 index 000000000000..86b601393b8c --- /dev/null +++ b/tests_python/contracts_012/macros/assert_cmpneq.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; ASSERT_CMPNEQ; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_eq.tz b/tests_python/contracts_012/macros/assert_eq.tz new file mode 100644 index 000000000000..338096a6277c --- /dev/null +++ b/tests_python/contracts_012/macros/assert_eq.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_EQ; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_ge.tz b/tests_python/contracts_012/macros/assert_ge.tz new file mode 100644 index 000000000000..06bb3cec944b --- /dev/null +++ b/tests_python/contracts_012/macros/assert_ge.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_GE; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_gt.tz b/tests_python/contracts_012/macros/assert_gt.tz new file mode 100644 index 000000000000..d041093b0ebf --- /dev/null +++ b/tests_python/contracts_012/macros/assert_gt.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_GT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_le.tz b/tests_python/contracts_012/macros/assert_le.tz new file mode 100644 index 000000000000..8250f3f3bdb1 --- /dev/null +++ b/tests_python/contracts_012/macros/assert_le.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_LE; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_lt.tz b/tests_python/contracts_012/macros/assert_lt.tz new file mode 100644 index 000000000000..e387e9d74070 --- /dev/null +++ b/tests_python/contracts_012/macros/assert_lt.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_LT; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/assert_neq.tz b/tests_python/contracts_012/macros/assert_neq.tz new file mode 100644 index 000000000000..83f19559e1d1 --- /dev/null +++ b/tests_python/contracts_012/macros/assert_neq.tz @@ -0,0 +1,3 @@ +parameter (pair int int); +storage unit; +code {CAR; DUP; CAR; DIP{CDR}; COMPARE; ASSERT_NEQ; UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/big_map_get_add.tz b/tests_python/contracts_012/macros/big_map_get_add.tz new file mode 100644 index 000000000000..2dcf1ce69a08 --- /dev/null +++ b/tests_python/contracts_012/macros/big_map_get_add.tz @@ -0,0 +1,7 @@ +parameter (pair (pair %set_pair int (option int)) (pair %check_pair int (option int))) ; +storage (pair (big_map int int) unit) ; +code { DUP ; DIP { CDAR } ; + DUP ; DIP { CADR; DUP ; CAR ; DIP { CDR } ; UPDATE ; DUP } ; + CADR ; DUP ; CDR ; DIP { CAR ; GET } ; + IF_SOME { SWAP ; IF_SOME { ASSERT_CMPEQ } {FAIL}} { ASSERT_NONE } ; + UNIT ; SWAP ; PAIR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/macros/big_map_mem.tz b/tests_python/contracts_012/macros/big_map_mem.tz new file mode 100644 index 000000000000..55736ab89da6 --- /dev/null +++ b/tests_python/contracts_012/macros/big_map_mem.tz @@ -0,0 +1,5 @@ +# Fails if the boolean does not match the membership criteria +parameter (pair int bool) ; +storage (pair (big_map int unit) unit) ; +code { DUP ; DUP ; CADR ; DIP { CAAR ; DIP { CDAR ; DUP } ; MEM } ; + ASSERT_CMPEQ ; UNIT ; SWAP ; PAIR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/macros/build_list.tz b/tests_python/contracts_012/macros/build_list.tz new file mode 100644 index 000000000000..842056d913ce --- /dev/null +++ b/tests_python/contracts_012/macros/build_list.tz @@ -0,0 +1,6 @@ +parameter nat; +storage (list nat); +code { CAR @counter; NIL @acc nat; SWAP; DUP @cmp_num; PUSH nat 0; CMPNEQ; + LOOP { DUP; DIP {SWAP}; CONS @acc; SWAP; PUSH nat 1; SWAP; SUB @counter; + DUP; DIP{ABS}; PUSH int 0; CMPNEQ}; + CONS; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/macros/carn_and_cdrn.tz b/tests_python/contracts_012/macros/carn_and_cdrn.tz new file mode 100644 index 000000000000..cc3cdccee81a --- /dev/null +++ b/tests_python/contracts_012/macros/carn_and_cdrn.tz @@ -0,0 +1,26 @@ +# Same as ../opcodes/comb-get.tz but using the CAR n and CDR n macros instead of GET +parameter (pair nat nat nat unit); +storage unit; +code { + CAR ; + + # Checking the first element + DUP ; CAR ; + PUSH nat 1 ; ASSERT_CMPEQ ; + DUP ; CAR 0 ; + PUSH nat 1 ; ASSERT_CMPEQ ; + + # Checking the second element + DUP ; CAR 1 ; + PUSH nat 4 ; ASSERT_CMPEQ ; + + # Checking the third element + DUP ; CAR 2 ; + PUSH nat 2 ; ASSERT_CMPEQ ; + + # Checking the last (fourth) element + DUP ; CDR 3 ; + UNIT ; ASSERT_CMPEQ ; + + DROP ; UNIT ; NIL operation ; PAIR + } diff --git a/tests_python/contracts_012/macros/compare.tz b/tests_python/contracts_012/macros/compare.tz new file mode 100644 index 000000000000..698ef3e695ed --- /dev/null +++ b/tests_python/contracts_012/macros/compare.tz @@ -0,0 +1,9 @@ +parameter (pair mutez mutez); +storage (list bool); +code {CAR; DUP; DUP; DUP; DUP; DIIIIIP {NIL bool}; + DIIIIP {DUP; CAR; DIP {CDR}; COMPARE; LE; CONS}; + DIIIP {DUP; CAR; DIP {CDR}; COMPARE; GE; CONS}; + DIIP{DUP; CAR; DIP {CDR}; COMPARE; LT; CONS}; + DIP {DUP; CAR; DIP {CDR}; COMPARE; GT; CONS}; + DUP; CAR; DIP {CDR}; COMPARE; EQ; CONS; + NIL operation; PAIR}; diff --git a/tests_python/contracts_012/macros/compare_bytes.tz b/tests_python/contracts_012/macros/compare_bytes.tz new file mode 100644 index 000000000000..3b5e5a9c400c --- /dev/null +++ b/tests_python/contracts_012/macros/compare_bytes.tz @@ -0,0 +1,9 @@ +parameter (pair bytes bytes); +storage (list bool); +code {CAR; DUP; DUP; DUP; DUP; DIIIIIP {NIL bool}; + DIIIIP {DUP; CAR; DIP {CDR}; COMPARE; LE; CONS}; + DIIIP {DUP; CAR; DIP {CDR}; COMPARE; GE; CONS}; + DIIP{DUP; CAR; DIP {CDR}; COMPARE; LT; CONS}; + DIP {DUP; CAR; DIP {CDR}; COMPARE; GT; CONS}; + DUP; CAR; DIP {CDR}; COMPARE; EQ; CONS; + NIL operation; PAIR}; diff --git a/tests_python/contracts_012/macros/fail.tz b/tests_python/contracts_012/macros/fail.tz new file mode 100644 index 000000000000..7f8bde252130 --- /dev/null +++ b/tests_python/contracts_012/macros/fail.tz @@ -0,0 +1,5 @@ +parameter unit; +storage unit; +code + { # This contract will never accept a incoming transaction + FAIL}; diff --git a/tests_python/contracts_012/macros/guestbook.tz b/tests_python/contracts_012/macros/guestbook.tz new file mode 100644 index 000000000000..b362f94b957e --- /dev/null +++ b/tests_python/contracts_012/macros/guestbook.tz @@ -0,0 +1,10 @@ +parameter string; +storage (map address (option string)); + +code { UNPAIR @message @guestbook; SWAP; + DUP; SENDER; GET @previous_message; + ASSERT_SOME; + ASSERT_NONE; + SWAP; SOME; SOME; SENDER; UPDATE; + NIL operation; + PAIR } diff --git a/tests_python/contracts_012/macros/macro_annotations.tz b/tests_python/contracts_012/macros/macro_annotations.tz new file mode 100644 index 000000000000..f48f18e3d942 --- /dev/null +++ b/tests_python/contracts_012/macros/macro_annotations.tz @@ -0,0 +1,6 @@ +parameter unit; +storage (pair (unit %truc) unit); +code { DROP; UNIT ; UNIT ; PAIR %truc ; UNIT ; + DUUP @new_storage ; + DIP { DROP ; DROP } ; + NIL operation ; PAIR } diff --git a/tests_python/contracts_012/macros/map_caddaadr.tz b/tests_python/contracts_012/macros/map_caddaadr.tz new file mode 100644 index 000000000000..45509839cc01 --- /dev/null +++ b/tests_python/contracts_012/macros/map_caddaadr.tz @@ -0,0 +1,4 @@ +parameter unit; +storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat); +code { MAP_CDADDAADR @new_storage %value { PUSH mutez 1000000 ; ADD } ; + NIL operation ; SWAP; SET_CAR }; diff --git a/tests_python/contracts_012/macros/max_in_list.tz b/tests_python/contracts_012/macros/max_in_list.tz new file mode 100644 index 000000000000..89c4955e9374 --- /dev/null +++ b/tests_python/contracts_012/macros/max_in_list.tz @@ -0,0 +1,9 @@ +parameter (list int); +storage (option int); +code {CAR; DIP{NONE int}; + ITER {SWAP; + IF_NONE {SOME} + {DIP {DUP}; DUP; DIP{SWAP}; + CMPLE; IF {DROP} {DIP {DROP}}; + SOME}}; + NIL operation; PAIR}; diff --git a/tests_python/contracts_012/macros/min.tz b/tests_python/contracts_012/macros/min.tz new file mode 100644 index 000000000000..cedd835bbac8 --- /dev/null +++ b/tests_python/contracts_012/macros/min.tz @@ -0,0 +1,11 @@ + +parameter (pair int int); +storage int; +code { CAR; # Ignore the storage + DUP; # Duplicate so we can get both the numbers passed as parameters + DUP; # Second dup so we can access the lesser number + CAR; DIP{CDR}; # Unpack the numbers on top of the stack + CMPLT; # Compare the two numbers, placing a boolean on top of the stack + IF {CAR} {CDR}; # Access the first number if the boolean was true + NIL operation; # Return no op + PAIR} # Pair the numbers satisfying the calling convention diff --git a/tests_python/contracts_012/macros/pair_macro.tz b/tests_python/contracts_012/macros/pair_macro.tz new file mode 100644 index 000000000000..55c70a3be3e9 --- /dev/null +++ b/tests_python/contracts_012/macros/pair_macro.tz @@ -0,0 +1,6 @@ +parameter unit; +storage unit; +code { UNIT; UNIT; UNIT; UNIT; UNIT; + PAPAPAPAIR @name %x1 %x2 %x3 %x4 %x5; + CDDDAR %x4 @fourth; + DROP; CDR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/macros/set_caddaadr.tz b/tests_python/contracts_012/macros/set_caddaadr.tz new file mode 100644 index 000000000000..e98671e40989 --- /dev/null +++ b/tests_python/contracts_012/macros/set_caddaadr.tz @@ -0,0 +1,5 @@ +parameter mutez; +storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat); +code { DUP ; CAR ; SWAP ; CDR ; + SET_CADDAADR @toplevel_pair_name %value ; + NIL operation ; PAIR }; diff --git a/tests_python/contracts_012/macros/take_my_money.tz b/tests_python/contracts_012/macros/take_my_money.tz new file mode 100644 index 000000000000..bb502d041849 --- /dev/null +++ b/tests_python/contracts_012/macros/take_my_money.tz @@ -0,0 +1,9 @@ +parameter key_hash; +storage unit; +code { CAR; IMPLICIT_ACCOUNT; # Create an account for the recipient of the funds + DIP{UNIT}; # Push a value of the storage type below the contract + PUSH mutez 1000000; # The person can have a ꜩ + UNIT; # Push the contract's argument type + TRANSFER_TOKENS; # Run the transfer + NIL operation; SWAP; CONS; + PAIR }; # Cleanup and put the return values diff --git a/tests_python/contracts_012/macros/unpair_macro.tz b/tests_python/contracts_012/macros/unpair_macro.tz new file mode 100644 index 000000000000..384b6839d88b --- /dev/null +++ b/tests_python/contracts_012/macros/unpair_macro.tz @@ -0,0 +1,9 @@ +parameter (unit :param_unit); +storage (unit :u1); +code { DROP ; + UNIT :u4 @a4; UNIT :u3 @a3; UNIT :u2 @a2; UNIT :u1 @a1; + PAIR; UNPAIR @x1 @x2; + PPAIPAIR @p1 %x1 %x2 %x3 %x4; UNPPAIPAIR %x1 % %x3 %x4 @uno @due @tre @quattro; + PAPAPAIR @p2 %x1 %x2 %x3 %x4; UNPAPAPAIR @un @deux @trois @quatre; + PAPPAIIR @p3 %x1 %x2 %x3 %x4; UNPAPPAIIR @one @two @three @four; + DIP { DROP; DROP; DROP }; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/authentication.tz b/tests_python/contracts_012/mini_scenarios/authentication.tz new file mode 100644 index 000000000000..021bbd26361a --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/authentication.tz @@ -0,0 +1,30 @@ +/* + +This contract is an example of using a cryptographic signature to +handle authentication. A public key is stored, and only the owner of +the secret key associated to this public key can interact with the +contract. She is allowed to perform any list of operations by sending +them wrapped in a lambda to the contract with a cryptographic +signature. + +To ensure that each signature is used only once and is not replayed by +an attacker, not only the lambda is signed but also the unique +identifier of the contract (a pair of the contract address and the +chain id) and a counter that is incremented at each successful call. + +More precisely, the signature should check against pack ((chain_id, +self) (param, counter)). + +*/ +parameter (pair (lambda unit (list operation)) signature); +storage (pair (nat %counter) key); +code + { + UNPPAIPAIR; + DUUUP; DUUP ; SELF; CHAIN_ID ; PPAIPAIR; PACK; + DIP { SWAP }; DUUUUUP ; DIP { SWAP }; + DUUUP; DIP {CHECK_SIGNATURE}; SWAP; IF {DROP} {FAILWITH}; + UNIT; EXEC; + DIP { PUSH nat 1; ADD }; + PAPAIR + } diff --git a/tests_python/contracts_012/mini_scenarios/big_map_entrypoints.tz b/tests_python/contracts_012/mini_scenarios/big_map_entrypoints.tz new file mode 100644 index 000000000000..d49e6257167a --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/big_map_entrypoints.tz @@ -0,0 +1,31 @@ +storage + (pair (big_map string nat) (big_map string nat)) ; +parameter + (or (unit %default) + (or (or %mem (string %mem_left) (string %mem_right)) + (or (or %add (pair %add_left string nat) (pair %add_right string nat)) + (or %rem (string %rem_left) (string %rem_right))))) ; +code { UNPAIR ; + IF_LEFT + { DROP ; + DUP ; CAR ; + PUSH mutez 0 ; + NONE key_hash ; + CREATE_CONTRACT + { parameter string ; + storage (big_map string nat) ; + code { UNPAIR ; DROP ; NIL operation ; PAIR }} ; + DIP { DROP } ; + NIL operation ; SWAP ; CONS ; PAIR } + { IF_LEFT + { IF_LEFT + { DIP { UNPAIR } ; DIP { DUP } ; MEM ; ASSERT } + { DIP { UNPAIR ; SWAP } ; DIP { DUP } ; MEM ; ASSERT ; SWAP } } + { IF_LEFT + { IF_LEFT + { UNPAIR ; DIIP { UNPAIR } ; DIP { SOME } ; UPDATE } + { UNPAIR ; DIIP { UNPAIR ; SWAP } ; DIP { SOME } ; UPDATE ; SWAP } } + { IF_LEFT + { DIP { UNPAIR } ; DIP { NONE nat } ; UPDATE } + { DIP { UNPAIR ; SWAP } ; DIP { NONE nat } ; UPDATE ; SWAP } } } ; + PAIR ; NIL operation ; PAIR } } diff --git a/tests_python/contracts_012/mini_scenarios/big_map_magic.tz b/tests_python/contracts_012/mini_scenarios/big_map_magic.tz new file mode 100644 index 000000000000..f4e36f639bff --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/big_map_magic.tz @@ -0,0 +1,41 @@ +# this contracts handles two big_maps +storage + (or (pair (big_map string string) (big_map string string)) unit) ; +parameter + # it has 5 entry points + # swap: swaps the two maps. + (or (unit %swap) + # reset: resets storage, either to a new pair of maps, or to unit + (or (or %reset (pair (big_map string string) (big_map string string)) unit) + # import: drops the existing storage and creates two maps + # from the given lists of string pairs. + (or (pair %import (list (pair string string)) (list (pair string string))) + # add: adds the given list of key - value pairs into the + # first map + (or (list %add (pair string string)) + # rem: removes the given list of key - value pairs + # from the first map + (list %rem string))))) ; +code { UNPAIR ; + IF_LEFT + { DROP ; ASSERT_LEFT ; UNPAIR ; SWAP ; PAIR ; LEFT unit } + { IF_LEFT + { SWAP ; DROP } + { IF_LEFT + { DIP { ASSERT_RIGHT ; DROP } ; + UNPAIR ; + DIP { EMPTY_BIG_MAP string string } ; + ITER { UNPAIR ; DIP { SOME } ; UPDATE } ; + SWAP ; + DIP { EMPTY_BIG_MAP string string } ; + ITER { UNPAIR ; DIP { SOME } ; UPDATE } ; + SWAP ; + PAIR ; LEFT unit } + { IF_LEFT + { DIP { ASSERT_LEFT ; UNPAIR } ; + ITER { UNPAIR ; DIP { SOME } ; UPDATE } ; + PAIR ; LEFT unit } + { DIP { ASSERT_LEFT ; UNPAIR } ; + ITER { DIP { NONE string } ; UPDATE } ; + PAIR ; LEFT unit } }} } ; + NIL operation ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/big_map_read.tz b/tests_python/contracts_012/mini_scenarios/big_map_read.tz new file mode 100644 index 000000000000..60d666e28f29 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/big_map_read.tz @@ -0,0 +1,9 @@ +storage (nat); +parameter (big_map nat nat); +code { CAR; + PUSH nat 1; + GET; + ASSERT_SOME; + NIL operation; + PAIR; + } diff --git a/tests_python/contracts_012/mini_scenarios/big_map_store.tz b/tests_python/contracts_012/mini_scenarios/big_map_store.tz new file mode 100644 index 000000000000..4dc68145a691 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/big_map_store.tz @@ -0,0 +1,8 @@ +storage (big_map nat nat); +parameter (unit); +code { DROP; + EMPTY_BIG_MAP nat nat; + NIL operation; + PAIR; + } + diff --git a/tests_python/contracts_012/mini_scenarios/big_map_write.tz b/tests_python/contracts_012/mini_scenarios/big_map_write.tz new file mode 100644 index 000000000000..bde3b19baa3d --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/big_map_write.tz @@ -0,0 +1,10 @@ +storage (unit); +parameter (big_map nat nat); +code { UNPAIR ; + PUSH (option nat) (Some 1); + PUSH nat 1; + UPDATE; + DROP; + NIL operation; + PAIR; + } diff --git a/tests_python/contracts_012/mini_scenarios/create_contract.tz b/tests_python/contracts_012/mini_scenarios/create_contract.tz new file mode 100644 index 000000000000..0d09a1fdfca6 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/create_contract.tz @@ -0,0 +1,33 @@ +/* +- param: None: + + Create a contract then perform a recursive call on Some [addr] where + [addr] is the address of the newly created contract. + + The created contract simply stores its parameter (a string). It is + initialized with the storage "dummy" and has an initial balance of + 100tz. It has no delegate so these 100tz are totally frozen. + +- param: Some [addr]: + + Check that the sender is self, call the contract at address [addr] + with param "abcdefg" transferring 0tz. + +*/ +parameter (option address) ; +storage unit ; +code { CAR ; + IF_NONE + { PUSH string "dummy" ; + PUSH mutez 100000000 ; NONE key_hash ; + CREATE_CONTRACT + { parameter string ; + storage string ; + code { CAR ; NIL operation ; PAIR } } ; + DIP { SOME ; DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS } ; + CONS ; UNIT ; SWAP ; PAIR } + { SELF ; ADDRESS ; SENDER ; IFCMPNEQ { FAIL } {} ; + CONTRACT string ; IF_SOME {} { FAIL } ; + PUSH mutez 0 ; PUSH string "abcdefg" ; TRANSFER_TOKENS ; + NIL operation; SWAP; CONS ; UNIT ; SWAP ; PAIR } } ; \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/create_contract_simple.tz b/tests_python/contracts_012/mini_scenarios/create_contract_simple.tz new file mode 100644 index 000000000000..2a5185d74889 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/create_contract_simple.tz @@ -0,0 +1,14 @@ +parameter unit; +storage unit; +code { CAR; + PUSH string "foo"; + PUSH mutez 0; + NONE key_hash; + CREATE_CONTRACT + { parameter string ; + storage string ; + code { CAR ; NIL operation ; PAIR } } ; + DROP; DROP; + NIL operation; + PAIR; + } diff --git a/tests_python/contracts_012/mini_scenarios/default_account.tz b/tests_python/contracts_012/mini_scenarios/default_account.tz new file mode 100644 index 000000000000..74e7693d7ba5 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/default_account.tz @@ -0,0 +1,9 @@ +/* +Send 100 tz to the implicit account given as parameter. +*/ + +parameter key_hash; +storage unit; +code {DIP{UNIT}; CAR; IMPLICIT_ACCOUNT; + PUSH mutez 100000000; UNIT; TRANSFER_TOKENS; + NIL operation; SWAP; CONS; PAIR} diff --git a/tests_python/contracts_012/mini_scenarios/execution_order_appender.tz b/tests_python/contracts_012/mini_scenarios/execution_order_appender.tz new file mode 100644 index 000000000000..9a519f780924 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/execution_order_appender.tz @@ -0,0 +1,17 @@ +# Given a storage (adr, str), calls the contract at adr with the +# parameter str +parameter unit; +storage (pair address string); +code { + CDR; + DUP; + UNPAIR; + CONTRACT string; + ASSERT_SOME; + PUSH mutez 0; + DIG 2; + TRANSFER_TOKENS; + NIL operation; + SWAP; + CONS; + PAIR }; diff --git a/tests_python/contracts_012/mini_scenarios/execution_order_caller.tz b/tests_python/contracts_012/mini_scenarios/execution_order_caller.tz new file mode 100644 index 000000000000..ead37544f4e8 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/execution_order_caller.tz @@ -0,0 +1,17 @@ +# Given storage [adr1; ...; adrn], emits operations +# [ TRANSFER_TOKENS Unit (Mutez 0) adr1 ; +# ... ; +# TRANSFER_TOKENS Unit (Mutez 0) adrn ] +parameter unit; +storage (list address); +code { + CDR; + DUP; + MAP { + CONTRACT unit; + ASSERT_SOME; + PUSH mutez 0; + UNIT; + TRANSFER_TOKENS; + }; + PAIR }; diff --git a/tests_python/contracts_012/mini_scenarios/execution_order_storer.tz b/tests_python/contracts_012/mini_scenarios/execution_order_storer.tz new file mode 100644 index 000000000000..2bfc7505e9cd --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/execution_order_storer.tz @@ -0,0 +1,4 @@ +# Appends the parameter to the string in storage +parameter (string); +storage (string); +code { UNPAIR; SWAP; CONCAT; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/mini_scenarios/fa12_reference.tz b/tests_python/contracts_012/mini_scenarios/fa12_reference.tz new file mode 100644 index 000000000000..7c2265072db4 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/fa12_reference.tz @@ -0,0 +1,749 @@ +# This contract comes from the gitlab.com/tzip/tzip repository. It is +# distributed under the CC0 1.0 license, which can be found at +# https://gitlab.com/tzip/tzip/-/blob/4b3c67aad5abbf04ec36caea4a1809e7b6e55bb8/LICENSE + +# Its purpose is to serve as a reference contract for TZIP-7, which +# defines Financial Assets 1.2. The original file can be found at +# https://gitlab.com/tzip/tzip/-/blob/4b3c67aad5abbf04ec36caea4a1809e7b6e55bb8/proposals/tzip-7/ManagedLedger.tz + +# This contract was generated from +# https://gitlab.com/morley-framework/morley/tree/ce28076a79b93d48aa7745271e6a1395b8b9e50d/lorentz-contracts/src/Lorentz/Contracts/ManagedLedger.hs +# Storage annotations were added manually. + +parameter (or (or (or (pair %transfer (address :from) + (pair (address :to) + (nat :value))) + (pair %approve (address :spender) + (nat :value))) + (or (pair %getAllowance (pair (address :owner) + (address :spender)) + (contract nat)) + (or (pair %getBalance (address :owner) + (contract nat)) + (pair %getTotalSupply unit + (contract nat))))) + (or (or (bool %setPause) + (address %setAdministrator)) + (or (pair %getAdministrator unit + (contract address)) + (or (pair %mint (address :to) + (nat :value)) + (pair %burn (address :from) + (nat :value)))))); +storage (pair (big_map %ledger (address :user) + (pair (nat :balance) + (map :approvals (address :spender) + (nat :value)))) + (pair (address %admin) + (pair (bool %paused) + (nat %totalSupply)))); +code { CAST (pair (or (or (or (pair address (pair address nat)) (pair address nat)) (or (pair (pair address address) (contract nat)) (or (pair address (contract nat)) (pair unit (contract nat))))) (or (or bool address) (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) (pair (big_map address (pair nat (map address nat))) (pair address (pair bool nat)))); + DUP; + CAR; + DIP { CDR }; + IF_LEFT { IF_LEFT { IF_LEFT { DIP { DUP; + CDR; + CDR; + CAR; + IF { UNIT; + PUSH string "TokenOperationsArePaused"; + PAIR; + FAILWITH } + { } }; + DUP; + DUP; + CDR; + CAR; + DIP { CAR }; + COMPARE; + EQ; + IF { DROP } + { DUP; + CAR; + SENDER; + COMPARE; + EQ; + IF { } + { DUP; + DIP { DUP; + DIP { DIP { DUP }; + CAR; + SENDER; + PAIR; + DUP; + DIP { CDR; + DIP { CAR }; + GET; + IF_NONE { EMPTY_MAP (address) nat } + { CDR } }; + CAR; + GET; + IF_NONE { PUSH nat 0 } + { } }; + DUP; + CAR; + DIP { SENDER; + DIP { DUP; + CDR; + CDR; + DIP { DIP { DUP }; + SWAP }; + SWAP; + SUB; + ISNAT; + IF_NONE { DIP { DUP }; + SWAP; + DIP { DUP }; + SWAP; + CDR; + CDR; + PAIR; + PUSH string "NotEnoughAllowance"; + PAIR; + FAILWITH } + { } }; + PAIR }; + PAIR; + DIP { DROP; + DROP }; + DIP { DUP }; + SWAP; + DIP { DUP; + CAR }; + SWAP; + DIP { CAR }; + GET; + IF_NONE { PUSH nat 0; + DIP { EMPTY_MAP (address) nat }; + PAIR; + EMPTY_MAP (address) nat } + { DUP; + CDR }; + DIP { DIP { DUP }; + SWAP }; + SWAP; + CDR; + CDR; + DUP; + INT; + EQ; + IF { DROP; + NONE nat } + { SOME }; + DIP { DIP { DIP { DUP }; + SWAP }; + SWAP }; + SWAP; + CDR; + CAR; + UPDATE; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR; + SWAP; + CAR; + DIP { SOME }; + DIP { DIP { DUP; + CAR } }; + UPDATE; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR } }; + DIP { DUP }; + SWAP; + DIP { DUP }; + SWAP; + CDR; + CAR; + DIP { CAR }; + GET; + IF_NONE { DUP; + CDR; + CDR; + INT; + EQ; + IF { NONE (pair nat (map address nat)) } + { DUP; + CDR; + CDR; + DIP { EMPTY_MAP (address) nat }; + PAIR; + SOME } } + { DIP { DUP }; + SWAP; + CDR; + CDR; + DIP { DUP; + CAR }; + ADD; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR; + SOME }; + SWAP; + DUP; + DIP { CDR; + CAR; + DIP { DIP { DUP; + CAR } }; + UPDATE; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR }; + DUP; + DIP { CDR; + CDR; + INT; + DIP { DUP; + CDR; + CDR; + CDR }; + ADD; + ISNAT; + IF_NONE { PUSH string "Internal: Negative total supply"; + FAILWITH } + { }; + DIP { DUP; + CDR }; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR; + SWAP; + PAIR; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR }; + DIP { DUP }; + SWAP; + DIP { DUP }; + SWAP; + CAR; + DIP { CAR }; + GET; + IF_NONE { CDR; + CDR; + PUSH nat 0; + SWAP; + PAIR; + PUSH string "NotEnoughBalance"; + PAIR; + FAILWITH } + { }; + DUP; + CAR; + DIP { DIP { DUP }; + SWAP }; + SWAP; + CDR; + CDR; + SWAP; + SUB; + ISNAT; + IF_NONE { CAR; + DIP { DUP }; + SWAP; + CDR; + CDR; + PAIR; + PUSH string "NotEnoughBalance"; + PAIR; + FAILWITH } + { }; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR; + DIP { DUP }; + SWAP; + DIP { DUP; + CAR; + INT; + EQ; + IF { DUP; + CDR; + SIZE; + INT; + EQ; + IF { DROP; + NONE (pair nat (map address nat)) } + { SOME } } + { SOME }; + SWAP; + CAR; + DIP { DIP { DUP; + CAR } }; + UPDATE; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR }; + DUP; + DIP { CDR; + CDR; + NEG; + DIP { DUP; + CDR; + CDR; + CDR }; + ADD; + ISNAT; + IF_NONE { PUSH string "Internal: Negative total supply"; + FAILWITH } + { }; + DIP { DUP; + CDR }; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR; + SWAP; + PAIR; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR }; + DROP }; + NIL operation; + PAIR } + { SENDER; + PAIR; + DIP { DUP; + CDR; + CDR; + CAR; + IF { UNIT; + PUSH string "TokenOperationsArePaused"; + PAIR; + FAILWITH } + { } }; + DIP { DUP }; + SWAP; + DIP { DUP }; + SWAP; + DUP; + DIP { CAR; + DIP { CAR }; + GET; + IF_NONE { EMPTY_MAP (address) nat } + { CDR } }; + CDR; + CAR; + GET; + IF_NONE { PUSH nat 0 } + { }; + DUP; + INT; + EQ; + IF { DROP } + { DIP { DUP }; + SWAP; + CDR; + CDR; + INT; + EQ; + IF { DROP } + { PUSH string "UnsafeAllowanceChange"; + PAIR; + FAILWITH } }; + DIP { DUP }; + SWAP; + DIP { DUP; + CAR }; + SWAP; + DIP { CAR }; + GET; + IF_NONE { PUSH nat 0; + DIP { EMPTY_MAP (address) nat }; + PAIR; + EMPTY_MAP (address) nat } + { DUP; + CDR }; + DIP { DIP { DUP }; + SWAP }; + SWAP; + CDR; + CDR; + DUP; + INT; + EQ; + IF { DROP; + NONE nat } + { SOME }; + DIP { DIP { DIP { DUP }; + SWAP }; + SWAP }; + SWAP; + CDR; + CAR; + UPDATE; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR; + SWAP; + CAR; + DIP { SOME }; + DIP { DIP { DUP; + CAR } }; + UPDATE; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR; + NIL operation; + PAIR } } + { IF_LEFT { DUP; + CAR; + DIP { CDR }; + DIP { DIP { DUP }; + SWAP }; + PAIR; + DUP; + CAR; + DIP { CDR }; + DUP; + DIP { CAR; + DIP { CAR }; + GET; + IF_NONE { EMPTY_MAP (address) nat } + { CDR } }; + CDR; + GET; + IF_NONE { PUSH nat 0 } + { }; + DIP { AMOUNT }; + TRANSFER_TOKENS; + NIL operation; + SWAP; + CONS; + PAIR } + { IF_LEFT { DUP; + CAR; + DIP { CDR }; + DIP { DIP { DUP }; + SWAP }; + PAIR; + DUP; + CAR; + DIP { CDR }; + DIP { CAR }; + GET; + IF_NONE { PUSH nat 0 } + { CAR }; + DIP { AMOUNT }; + TRANSFER_TOKENS; + NIL operation; + SWAP; + CONS; + PAIR } + { DUP; + CAR; + DIP { CDR }; + DIP { DIP { DUP }; + SWAP }; + PAIR; + CDR; + CDR; + CDR; + CDR; + DIP { AMOUNT }; + TRANSFER_TOKENS; + NIL operation; + SWAP; + CONS; + PAIR } } } } + { IF_LEFT { IF_LEFT { DIP { DUP; + CDR; + CAR; + SENDER; + COMPARE; + EQ; + IF { } + { UNIT; + PUSH string "SenderIsNotAdmin"; + PAIR; + FAILWITH } }; + DIP { DUP; + CDR }; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR; + SWAP; + PAIR; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR; + NIL operation; + PAIR } + { DIP { DUP; + CDR; + CAR; + SENDER; + COMPARE; + EQ; + IF { } + { UNIT; + PUSH string "SenderIsNotAdmin"; + PAIR; + FAILWITH } }; + DIP { DUP; + CDR }; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR; + NIL operation; + PAIR } } + { IF_LEFT { DUP; + CAR; + DIP { CDR }; + DIP { DIP { DUP }; + SWAP }; + PAIR; + CDR; + CDR; + CAR; + DIP { AMOUNT }; + TRANSFER_TOKENS; + NIL operation; + SWAP; + CONS; + PAIR } + { IF_LEFT { DIP { DUP; + CDR; + CAR; + SENDER; + COMPARE; + EQ; + IF { } + { UNIT; + PUSH string "SenderIsNotAdmin"; + PAIR; + FAILWITH } }; + DIP { DUP }; + SWAP; + DIP { DUP }; + SWAP; + CAR; + DIP { CAR }; + GET; + IF_NONE { DUP; + CDR; + INT; + EQ; + IF { NONE (pair nat (map address nat)) } + { DUP; + CDR; + DIP { EMPTY_MAP (address) nat }; + PAIR; + SOME } } + { DIP { DUP }; + SWAP; + CDR; + DIP { DUP; + CAR }; + ADD; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR; + SOME }; + SWAP; + DUP; + DIP { CAR; + DIP { DIP { DUP; + CAR } }; + UPDATE; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR }; + DUP; + DIP { CDR; + INT; + DIP { DUP; + CDR; + CDR; + CDR }; + ADD; + ISNAT; + IF_NONE { PUSH string "Internal: Negative total supply"; + FAILWITH } + { }; + DIP { DUP; + CDR }; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR; + SWAP; + PAIR; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR }; + DROP; + NIL operation; + PAIR } + { DIP { DUP; + CDR; + CAR; + SENDER; + COMPARE; + EQ; + IF { } + { UNIT; + PUSH string "SenderIsNotAdmin"; + PAIR; + FAILWITH } }; + DIP { DUP }; + SWAP; + DIP { DUP }; + SWAP; + CAR; + DIP { CAR }; + GET; + IF_NONE { CDR; + PUSH nat 0; + SWAP; + PAIR; + PUSH string "NotEnoughBalance"; + PAIR; + FAILWITH } + { }; + DUP; + CAR; + DIP { DIP { DUP }; + SWAP }; + SWAP; + CDR; + SWAP; + SUB; + ISNAT; + IF_NONE { CAR; + DIP { DUP }; + SWAP; + CDR; + PAIR; + PUSH string "NotEnoughBalance"; + PAIR; + FAILWITH } + { }; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR; + DIP { DUP }; + SWAP; + DIP { DUP; + CAR; + INT; + EQ; + IF { DUP; + CDR; + SIZE; + INT; + EQ; + IF { DROP; + NONE (pair nat (map address nat)) } + { SOME } } + { SOME }; + SWAP; + CAR; + DIP { DIP { DUP; + CAR } }; + UPDATE; + DIP { DUP; + DIP { CDR }; + CAR }; + DIP { DROP }; + PAIR }; + DUP; + DIP { CDR; + NEG; + DIP { DUP; + CDR; + CDR; + CDR }; + ADD; + ISNAT; + IF_NONE { PUSH string "Internal: Negative total supply"; + FAILWITH } + { }; + DIP { DUP; + CDR }; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR; + SWAP; + PAIR; + DIP { DUP; + DIP { CAR }; + CDR }; + DIP { DROP }; + SWAP; + PAIR }; + DROP; + NIL operation; + PAIR } } } } }; diff --git a/tests_python/contracts_012/mini_scenarios/generic_multisig.tz b/tests_python/contracts_012/mini_scenarios/generic_multisig.tz new file mode 100644 index 000000000000..2e78f1cea983 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/generic_multisig.tz @@ -0,0 +1,92 @@ +# Source: https://github.com/murbard/smart-contracts/blob/master/multisig/michelson/generic.tz +parameter (or (unit %default) + (pair %main + (pair :payload + (nat %counter) # counter, used to prevent replay attacks + (or :action # payload to sign, represents the requested action + (lambda %operation unit (list operation)) + (pair %change_keys # change the keys controlling the multisig + (nat %threshold) # new threshold + (list %keys key)))) # new list of keys + (list %sigs (option signature)))); # signatures + +storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; + +code + { + UNPAIR ; + IF_LEFT + { # Default entry point: do nothing + # This entry point can be used to send tokens to this contract + DROP ; NIL operation ; PAIR } + { # Main entry point + # Assert no token was sent: + # to send tokens, the default entry point should be used + PUSH mutez 0 ; AMOUNT ; ASSERT_CMPEQ ; + SWAP ; DUP ; DIP { SWAP } ; + DIP + { + UNPAIR ; + # pair the payload with the current contract address, to ensure signatures + # can't be replayed accross different contracts if a key is reused. + DUP ; SELF ; ADDRESS ; CHAIN_ID ; PAIR ; PAIR ; + PACK ; # form the binary payload that we expect to be signed + DIP { UNPAIR @counter ; DIP { SWAP } } ; SWAP + } ; + + # Check that the counters match + UNPAIR @stored_counter; DIP { SWAP }; + ASSERT_CMPEQ ; + + # Compute the number of valid signatures + DIP { SWAP } ; UNPAIR @threshold @keys; + DIP + { + # Running count of valid signatures + PUSH @valid nat 0; SWAP ; + ITER + { + DIP { SWAP } ; SWAP ; + IF_CONS + { + IF_SOME + { SWAP ; + DIP + { + SWAP ; DIIP { DUUP } ; + # Checks signatures, fails if invalid + { DUUUP; DIP {CHECK_SIGNATURE}; SWAP; IF {DROP} {FAILWITH} }; + PUSH nat 1 ; ADD @valid } } + { SWAP ; DROP } + } + { + # There were fewer signatures in the list + # than keys. Not all signatures must be present, but + # they should be marked as absent using the option type. + FAIL + } ; + SWAP + } + } ; + # Assert that the threshold is less than or equal to the + # number of valid signatures. + ASSERT_CMPLE ; + # Assert no unchecked signature remains + IF_CONS {FAIL} {} ; + DROP ; + + # Increment counter and place in storage + DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR} ; + + # We have now handled the signature verification part, + # produce the operation requested by the signers. + IF_LEFT + { # Get operation + UNIT ; EXEC + } + { + # Change set of signatures + DIP { CAR } ; SWAP ; PAIR ; NIL operation + }; + PAIR } + } diff --git a/tests_python/contracts_012/mini_scenarios/groth16.tz b/tests_python/contracts_012/mini_scenarios/groth16.tz new file mode 100644 index 000000000000..66ff23a5e73b --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/groth16.tz @@ -0,0 +1,74 @@ +# The contract returns if the proof verifies, and fails otherwise. +# The verifying key, proof, and inputs are generated from +# ZoKrates, modified to use BLS12-381. +# The circuit proves knowledge of a square root of 113569. +storage unit; + +# The parameter is a pair consisting of: +# * A pair of Fr element inputs, x and y +# * A proof, consisting of +# * G1 points `a` and `c` +# * G2 point `b` +parameter (pair (pair (bls12_381_fr %input_x) (bls12_381_fr %input_y)) + (pair (pair (bls12_381_g1 %proof_a) (bls12_381_g2 %proof_b)) + (bls12_381_g1 %proof_c))); + +code + { + # Discard storage and unpair. Result stack should be + # input{x:y} : proof{a:b:c}. + CAR; UNPPAIPPAIIR; + + # Push the verifying key. Result stack should be + # input{x:y} + # : proof{a:b:c} + # : vk_{a:b:gamma:delta:gamma_{a:b:c}} + DIP 5 + { + PUSH @vk_gamma_c bls12_381_g1 0x063bd6e11e2fcaac1dd8cf68c6b1925a73c3c583e298ed37c41c3715115cf96358a42dbe85a0228cbfd8a6c8a8c54cd015b5ae2860d1cc47f84698d951f14d9448d03f04df2ca0ffe609a2067d6f1a892163a5e05e541279134cae52b1f23c6b; + + PUSH @vk_gamma_b bls12_381_g1 0x11f5b5db1da7f1f26217edcce2219d016003af6e5b4d1ca3ad0ff477e354717e658bf16beddc4f4fb76ce39d3327811e0601709dc7ed98c70463cfa1ba33f99851b52b51d1a042d7425bec6277287441c399973632445ce61e7fdd63a70f0f60; + + PUSH @vk_gamma_a bls12_381_g1 0x03535a322edd23c55b0ca025e54d450d95df49cc9ee873dcd500e8219f4771264bf159b3b105954d85c7bea8ffe1ea0400c767fe58989366c2837fba76f1b4f46644f19be8ad01e22d894b649e427e0d7e04677ee3919d982f0f96bb0a2f0c34; + + PUSH @vk_delta bls12_381_g2 0x10c6d5cdca84fc3c7f33061add256f48e0ab03a697832b338901898b650419eb6f334b28153fb73ad2ecd1cd2ac67053161e9f46cfbdaf7b1132a4654a55162850249650f9b873ac3113fa8c02ef1cd1df481480a4457f351d28f4da89d19fa405c3d77f686dc9a24d2681c9184bf2b091f62e6b24df651a3da8bd7067e14e7908fb02f8955b84af5081614cb5bc49b416d9edf914fc608c441b3f2eb8b6043736ddb9d4e4d62334a23b5625c14ef3e1a7e99258386310221b22d83a5eac035c; + + PUSH @vk_gamma bls12_381_g2 0x16dcbd28bff336c2649c7dd1d8391ac7ce6f7ef0124a9db7a4a485a124199eded7ce963c1c18aee1eca9994fe06f192c00e0fb653e1fc737d8d0e2f2f91424ca01f6e6e7c5c04f1c43db03a2900cf6b942aaed6ae77daea6200e094b78c38d770028d531a9d1a118ec23d5a39be7aa6dc28f778da1988856d2235c4a35e81fa48380f050d4baf7ebd7b5e058bf294da916afc34562f097c02a8fcbcf62a00de44f8ae6cfa7acb8ad254e3aeea8b2af12f65b7ee0f54855cb9bd432f3436f238f; + + PUSH @vk_b bls12_381_g2 0x0e9383f98df2c6e8b5b45f3876c3384596a0cdbc41349f83c4380bf463a050cdbd1d5057aa483a642e66486d1ed7362a1869e423c3877095e215c17282b11108601166f928043254bbce603bf86f4cec9f2e97e9660e98e4f5bce9b2b3bbacb40946b702ccfcc9a31e0bfc1543a2128edcc95807740a2310ae25eb47b935648e392c58dfae5b5e899d3b970d64e4e9e209741ea8bfedcfcc16b3fd890ff02c788ec0943feaaf01bbb354317acb85fcfd611133e4e563d53ca4e0f50e21cf2e7e; + + PUSH @vk_a bls12_381_g1 0x1040577c7d349e332735fc947c868c24a665f812f5dc1e7f60e65e2df80be2267a4b7341ed2287285fccd517acd96d910abba947235c364553aa6445f2f2b3a1a728225a330286ba5197ab87f0edc560d89fc7b623812f7d0d633341726e597a + }; + + # Compute vk_x as + # (vk_gamma_b * input_x) + (vk_gamma_c * input_y) + vk_gamma_a + # Result stack should be + # vk_x + # : input{x:y} + # : proof{a:b:c} + # : vk_{a:b:gamma:delta:gamma_{a:b:c}} + DUP; DUP 12; MUL; + DUP 3; DUP 14; MUL; + ADD; DUP 11; ADD @vk_x; + + # Push the list for the pairing check. The list should be + # [ (proof_a, proof_b); + # (-vk_x, vk_gamma); + # (-proof_c, vk_delta); + # (-vk_a, vk_b) ] + NIL (pair bls12_381_g1 bls12_381_g2); + DUP 9; DUP 9; NEG; PAIR; CONS; + DUP 11; DUP 8; NEG; PAIR; CONS; + DUP 10; DUP 3; NEG; PAIR; CONS; + DUP 6; DUP 6; PAIR; CONS; + + # Compute the pairing check and fail if it doesn't succeed + PAIRING_CHECK; ASSERT; + + # Drop the stack + DROP 13; + + # return no operations + UNIT; NIL operation; PAIR + + } diff --git a/tests_python/contracts_012/mini_scenarios/hardlimit.tz b/tests_python/contracts_012/mini_scenarios/hardlimit.tz new file mode 100644 index 000000000000..464062a52166 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/hardlimit.tz @@ -0,0 +1,5 @@ +parameter unit ; +storage int ; +code { # This contract stops accepting transactions after N incoming transactions + CDR ; DUP ; PUSH int 0 ; CMPLT; IF {PUSH int -1 ; ADD} {FAIL}; + NIL operation ; PAIR} ; diff --git a/tests_python/contracts_012/mini_scenarios/legacy_multisig.tz b/tests_python/contracts_012/mini_scenarios/legacy_multisig.tz new file mode 100644 index 000000000000..98ea6c603898 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/legacy_multisig.tz @@ -0,0 +1,78 @@ +parameter (pair + (pair :payload + (nat %counter) # counter, used to prevent replay attacks + (or :action # payload to sign, represents the requested action + (pair :transfer # transfer tokens + (mutez %amount) # amount to transfer + (contract %dest unit)) # destination to transfer to + (or + (option %delegate key_hash) # change the delegate to this address + (pair %change_keys # change the keys controlling the multisig + (nat %threshold) # new threshold + (list %keys key))))) # new list of keys + (list %sigs (option signature))); # signatures +storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; +code + { + UNPAIR ; SWAP ; DUP ; DIP { SWAP } ; + DIP + { + UNPAIR ; + # pair the payload with the current contract address, to ensure signatures + # can't be replayed across different contracts if a key is reused. + DUP ; SELF ; ADDRESS ; CHAIN_ID ; PAIR ; PAIR ; + PACK ; # form the binary payload that we expect to be signed + DIP { UNPAIR @counter ; DIP { SWAP } } ; SWAP + } ; + # Check that the counters match + UNPAIR @stored_counter; DIP { SWAP }; + ASSERT_CMPEQ ; + # Compute the number of valid signatures + DIP { SWAP } ; UNPAIR @threshold @keys; + DIP + { + # Running count of valid signatures + PUSH @valid nat 0; SWAP ; + ITER + { + DIP { SWAP } ; SWAP ; + IF_CONS + { + IF_SOME + { SWAP ; + DIP + { + SWAP ; DIIP { DUUP } ; + # Checks signatures, fails if invalid + { DUUUP; DIP {CHECK_SIGNATURE}; SWAP; IF {DROP} {FAILWITH} }; + PUSH nat 1 ; ADD @valid } } + { SWAP ; DROP } + } + { + # There were fewer signatures in the list + # than keys. Not all signatures must be present, but + # they should be marked as absent using the option type. + FAIL + } ; + SWAP + } + } ; + # Assert that the threshold is less than or equal to the + # number of valid signatures. + ASSERT_CMPLE ; + DROP ; DROP ; + # Increment counter and place in storage + DIP { UNPAIR ; PUSH nat 1 ; ADD @new_counter ; PAIR} ; + # We have now handled the signature verification part, + # produce the operation requested by the signers. + NIL operation ; SWAP ; + IF_LEFT + { # Transfer tokens + UNPAIR ; UNIT ; TRANSFER_TOKENS ; CONS } + { IF_LEFT { + # Change delegate + SET_DELEGATE ; CONS } + { + # Change set of signatures + DIP { SWAP ; CAR } ; SWAP ; PAIR ; SWAP }} ; + PAIR } diff --git a/tests_python/contracts_012/mini_scenarios/lockup.tz b/tests_python/contracts_012/mini_scenarios/lockup.tz new file mode 100644 index 000000000000..a8ff43aa0f85 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/lockup.tz @@ -0,0 +1,19 @@ +parameter unit; +storage (pair timestamp (pair mutez address)); +code { CDR; # Ignore the parameter + DUP; # Duplicate the storage + CAR; # Get the timestamp + NOW; # Push the current timestamp + CMPLT; # Compare to the current time + IF {FAIL} {}; # Fail if it is too soon + DUP; # Duplicate the storage value + # this must be on the bottom of the stack for us to call transfer tokens + CDR; # Ignore the timestamp, focussing in on the transfer data + DUP; # Duplicate the transfer information + CAR; # Get the amount of the transfer on top of the stack + DIP{CDR}; # Put the contract underneath it + DIP { CONTRACT unit ; ASSERT_SOME } ; + UNIT; # Put the contract's argument type on top of the stack + TRANSFER_TOKENS; # Emit the transfer + NIL operation; SWAP; CONS;# Make a singleton list of internal operations + PAIR} # Pair up to meet the calling convention diff --git a/tests_python/contracts_012/mini_scenarios/lqt_fa12.mligo.tz b/tests_python/contracts_012/mini_scenarios/lqt_fa12.mligo.tz new file mode 100644 index 000000000000..7f606cea3243 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/lqt_fa12.mligo.tz @@ -0,0 +1,328 @@ +# FA1.2 implementation used for Liquidity Baking + +{ parameter + (or (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (pair (address %to) (nat %value))))) ; + storage + (pair (big_map %tokens address nat) + (pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (pair (address %admin) (nat %total_supply)))) ; + code { DUP ; + CDR ; + PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + NEQ ; + IF { PUSH string "DontSendTez" ; FAILWITH } {} ; + SWAP ; + CAR ; + IF_LEFT + { IF_LEFT + { IF_LEFT + { SWAP ; + DUP ; + DUG 2 ; + CDR ; + CAR ; + SWAP ; + DUP ; + DUG 2 ; + CAR ; + SENDER ; + PAIR ; + PUSH nat 0 ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + COMPARE ; + GT ; + PUSH nat 0 ; + DIG 3 ; + DUP ; + DUG 4 ; + DIG 3 ; + DUP ; + DUG 4 ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + COMPARE ; + GT ; + AND ; + IF { PUSH string "UnsafeAllowanceChange" ; FAILWITH } {} ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + CDR ; + DIG 2 ; + DIG 3 ; + CDR ; + PUSH nat 0 ; + SWAP ; + DUP ; + DUG 2 ; + COMPARE ; + EQ ; + IF { DROP ; NONE nat } { SOME } ; + DIG 3 ; + UPDATE ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + NIL operation ; + PAIR } + { SWAP ; + DUP ; + DIG 2 ; + NIL operation ; + SWAP ; + DUP ; + DUG 2 ; + CDR ; + PUSH mutez 0 ; + DIG 4 ; + CDR ; + CAR ; + DIG 4 ; + CAR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + TRANSFER_TOKENS ; + CONS ; + PAIR } } + { IF_LEFT + { SWAP ; + DUP ; + DIG 2 ; + NIL operation ; + SWAP ; + DUP ; + DUG 2 ; + CDR ; + PUSH mutez 0 ; + DIG 4 ; + CAR ; + DIG 4 ; + CAR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + TRANSFER_TOKENS ; + CONS ; + PAIR } + { SWAP ; + DUP ; + DIG 2 ; + NIL operation ; + SWAP ; + CDR ; + PUSH mutez 0 ; + DIG 3 ; + CDR ; + CDR ; + CDR ; + TRANSFER_TOKENS ; + CONS ; + PAIR } } } + { IF_LEFT + { SWAP ; + DUP ; + DUG 2 ; + CDR ; + CDR ; + CAR ; + SENDER ; + COMPARE ; + NEQ ; + IF { PUSH string "OnlyAdmin" ; FAILWITH } {} ; + DUP ; + CAR ; + DIG 2 ; + DUP ; + DUG 3 ; + CAR ; + DIG 2 ; + DUP ; + DUG 3 ; + CDR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + ADD ; + ISNAT ; + IF_NONE + { PUSH string "Cannot burn more than the target's balance." ; FAILWITH } + {} ; + SWAP ; + DUP ; + DUG 2 ; + CAR ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + CDR ; + CDR ; + ADD ; + ABS ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + DIG 4 ; + CAR ; + PUSH nat 0 ; + DIG 4 ; + DUP ; + DUG 5 ; + COMPARE ; + EQ ; + IF { DIG 3 ; DROP ; NONE nat } { DIG 3 ; SOME } ; + DIG 4 ; + CDR ; + UPDATE ; + PAIR ; + DUP ; + DUG 2 ; + CDR ; + CDR ; + CAR ; + PAIR ; + SWAP ; + DUP ; + DUG 2 ; + CDR ; + CAR ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + NIL operation ; + PAIR } + { SWAP ; + DUP ; + DUG 2 ; + CDR ; + CAR ; + DIG 2 ; + DUP ; + DUG 3 ; + CAR ; + DIG 2 ; + DUP ; + DUG 3 ; + CAR ; + SENDER ; + COMPARE ; + EQ ; + IF { SWAP } + { SENDER ; + DIG 3 ; + DUP ; + DUG 4 ; + CAR ; + PAIR ; + DIG 3 ; + DUP ; + DUG 4 ; + CDR ; + CDR ; + DIG 3 ; + DUP ; + DUG 4 ; + DIG 2 ; + DUP ; + DUG 3 ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + SUB ; + ISNAT ; + IF_NONE { PUSH string "NotEnoughAllowance" ; FAILWITH } {} ; + DIG 3 ; + PUSH nat 0 ; + DIG 2 ; + DUP ; + DUG 3 ; + COMPARE ; + EQ ; + IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; + DIG 2 ; + UPDATE } ; + DIG 2 ; + DUP ; + DUG 3 ; + CDR ; + CDR ; + DIG 2 ; + DUP ; + DUG 3 ; + DIG 4 ; + DUP ; + DUG 5 ; + CAR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + SUB ; + ISNAT ; + IF_NONE { PUSH string "NotEnoughBalance" ; FAILWITH } {} ; + DIG 2 ; + PUSH nat 0 ; + DIG 2 ; + DUP ; + DUG 3 ; + COMPARE ; + EQ ; + IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; + DIG 3 ; + DUP ; + DUG 4 ; + CAR ; + UPDATE ; + DIG 2 ; + DUP ; + DUG 3 ; + CDR ; + CDR ; + SWAP ; + DUP ; + DUG 2 ; + DIG 4 ; + DUP ; + DUG 5 ; + CDR ; + CAR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + ADD ; + SWAP ; + PUSH nat 0 ; + DIG 2 ; + DUP ; + DUG 3 ; + COMPARE ; + EQ ; + IF { SWAP ; DROP ; NONE nat } { SWAP ; SOME } ; + DIG 3 ; + CDR ; + CAR ; + UPDATE ; + DIG 2 ; + CDR ; + SWAP ; + PAIR ; + DUP ; + CDR ; + CDR ; + DIG 2 ; + PAIR ; + SWAP ; + CAR ; + PAIR ; + NIL operation ; + PAIR } } } } diff --git a/tests_python/contracts_012/mini_scenarios/multiple_en2.tz b/tests_python/contracts_012/mini_scenarios/multiple_en2.tz new file mode 100644 index 000000000000..a1acafd48706 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/multiple_en2.tz @@ -0,0 +1,77 @@ +{ parameter unit ; + storage (option address) ; + code { SENDER ; + SELF ; + ADDRESS ; + { COMPARE ; + EQ ; + IF { CDR ; + { IF_NONE { { UNIT ; FAILWITH } } {} } ; + DIP { NIL operation } ; + DUP ; + CONTRACT %add unit ; + { IF_NONE {} { { UNIT ; FAILWITH } } } ; + DUP ; + CONTRACT %fact nat ; + { IF_NONE {} { { UNIT ; FAILWITH } } } ; + DUP ; + CONTRACT %add nat ; + { IF_NONE { { UNIT ; FAILWITH } } {} } ; + PUSH mutez 0 ; + PUSH nat 12 ; + TRANSFER_TOKENS ; + SWAP ; + DIP { CONS } ; + DUP ; + CONTRACT unit ; + { IF_NONE { { UNIT ; FAILWITH } } {} } ; + PUSH mutez 0 ; + PUSH unit Unit ; + TRANSFER_TOKENS ; + SWAP ; + DIP { CONS } ; + DUP ; + CONTRACT %sub nat ; + { IF_NONE { { UNIT ; FAILWITH } } {} } ; + PUSH mutez 0 ; + PUSH nat 3 ; + TRANSFER_TOKENS ; + SWAP ; + DIP { CONS } ; + DUP ; + CONTRACT %add nat ; + { IF_NONE { { UNIT ; FAILWITH } } {} } ; + PUSH mutez 0 ; + PUSH nat 5 ; + TRANSFER_TOKENS ; + SWAP ; + DIP { CONS } ; + DROP ; + DIP { NONE address } ; + PAIR } + { CAR ; + DUP ; + DIP { DIP { PUSH int 0 ; PUSH mutez 0 ; NONE key_hash } ; + DROP ; + CREATE_CONTRACT + { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; + storage int ; + code { AMOUNT ; + PUSH mutez 0 ; + { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; + { { DUP ; CAR ; DIP { CDR } } } ; + IF_LEFT + { IF_LEFT { ADD } { SWAP ; SUB } } + { DROP ; DROP ; PUSH int 0 } ; + NIL operation ; + PAIR } } } ; + DIP { SELF ; PUSH mutez 0 } ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + SWAP ; + CONS ; + DIP { SOME } ; + PAIR } } + } } diff --git a/tests_python/contracts_012/mini_scenarios/multiple_entrypoints_counter.tz b/tests_python/contracts_012/mini_scenarios/multiple_entrypoints_counter.tz new file mode 100644 index 000000000000..740190697171 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/multiple_entrypoints_counter.tz @@ -0,0 +1,29 @@ +{ parameter unit ; + storage (option address) ; + code { SENDER ; SELF ; ADDRESS ; + IFCMPEQ + { CDR ; ASSERT_SOME ; + DIP { NIL operation } ; + DUP ; CONTRACT %add unit ; ASSERT_NONE ; + DUP ; CONTRACT %fact nat ; ASSERT_NONE ; + DUP ; CONTRACT %add nat ; ASSERT_SOME ; PUSH mutez 0 ; PUSH nat 12 ; TRANSFER_TOKENS ; SWAP ; DIP { CONS } ; + DUP ; CONTRACT unit ; ASSERT_SOME ; PUSH mutez 0 ; PUSH unit Unit ; TRANSFER_TOKENS ; SWAP ; DIP { CONS } ; + DUP ; CONTRACT %sub nat ; ASSERT_SOME ; PUSH mutez 0 ; PUSH nat 3 ; TRANSFER_TOKENS ; SWAP ; DIP { CONS } ; + DUP ; CONTRACT %add nat ; ASSERT_SOME ; PUSH mutez 0 ; PUSH nat 5 ; TRANSFER_TOKENS ; SWAP ; DIP { CONS } ; + DROP ; DIP { NONE address } ; PAIR } + { CAR ; DUP ; + DIP + { DIP { PUSH int 0 ; PUSH mutez 0 ; NONE key_hash } ; + DROP ; + CREATE_CONTRACT + { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; + storage int ; + code { AMOUNT ; PUSH mutez 0 ; ASSERT_CMPEQ ; + UNPAIR ; + IF_LEFT + { IF_LEFT { ADD } { SWAP ; SUB } } + { DROP ; DROP ; PUSH int 0 } ; + NIL operation ; PAIR } } } ; + DIP { SELF ; PUSH mutez 0 } ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; SWAP ; CONS ; + DIP { SOME } ; PAIR } } } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/parameterized_multisig.tz b/tests_python/contracts_012/mini_scenarios/parameterized_multisig.tz new file mode 100644 index 000000000000..16f785ae0a25 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/parameterized_multisig.tz @@ -0,0 +1,24 @@ +storage (pair bool (pair (map nat (pair bool bool)) (pair key key))); +parameter (or nat (pair signature nat)); +code { DUP; CAR; DIP{CDDR}; # Stack tangling + IF_LEFT { DIP{DUP; CAR}; GET; # Get the value stored for that index + IF_NONE { PUSH bool False} # If not referenced, reject + { DUP; CAR; DIP{CDR}; AND}; + PAIR} + { DUP; CAR; DIP{CDR; DUP; PACK ; BLAKE2B}; PAIR; SWAP; # Create the signature pair + DIP{ DIP{DUP; CDR; DIP{CAR}; DUP}; + SWAP; CAR; DIP{DUP; UNPAIR}; CHECK_SIGNATURE }; # Check the first signature + SWAP; + # If the signature typechecked, get and update the first element of the pair + IF { DIP{DROP; SWAP; DUP}; DUP; + DIP{ GET; IF_NONE{PUSH (pair bool bool) (Pair False False)} {}; + CDR; PUSH bool True; PAIR; SOME }} + # Check the second signature + { DIP{DIP{DUP; CDR}; SWAP; DIP {UNPAIR}; CHECK_SIGNATURE}; SWAP; + IF { DUP; DIP{DIP{SWAP; DUP}; GET}; SWAP; + IF_NONE {PUSH (pair bool bool) (Pair False False)} {}; + CAR; PUSH bool True; SWAP; PAIR; SOME; SWAP} + {FAIL}}; + # Update the stored value and finish off + UPDATE; PAIR; PUSH bool False; PAIR}; + NIL operation; PAIR } diff --git a/tests_python/contracts_012/mini_scenarios/replay.tz b/tests_python/contracts_012/mini_scenarios/replay.tz new file mode 100644 index 000000000000..e03ac4ab2113 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/replay.tz @@ -0,0 +1,8 @@ +# This contract always fail because it tries to execute twice the same operation +parameter unit ; +storage unit ; +code { CDR ; NIL operation ; + SOURCE ; CONTRACT unit ; ASSERT_SOME ; + PUSH mutez 1 ; UNIT ; TRANSFER_TOKENS ; + DUP ; DIP { CONS } ; CONS ; + PAIR } diff --git a/tests_python/contracts_012/mini_scenarios/reveal_signed_preimage.tz b/tests_python/contracts_012/mini_scenarios/reveal_signed_preimage.tz new file mode 100644 index 000000000000..1a7e97eb8a68 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/reveal_signed_preimage.tz @@ -0,0 +1,13 @@ +parameter (pair bytes signature) ; +storage (pair bytes key) ; +code { + #check that sha256(param.bytes) == storage.bytes + DUP ; UNPAIR ; CAR; SHA256; DIP { CAR } ; ASSERT_CMPEQ ; + + # check that the sig is a valid signature of the preimage + DUP ; UNPAIR ; SWAP ; DIP { UNPAIR ; SWAP } ; CDR ; CHECK_SIGNATURE ; ASSERT ; + + # send all our tokens to the implicit account corresponding to the stored public key + CDR ; DUP ; CDR ; HASH_KEY ; IMPLICIT_ACCOUNT ; + BALANCE ; UNIT ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/self_address_receiver.tz b/tests_python/contracts_012/mini_scenarios/self_address_receiver.tz new file mode 100644 index 000000000000..6ebda8daad9e --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/self_address_receiver.tz @@ -0,0 +1,12 @@ +# See self_address_sender.tz +parameter (lambda unit address); +storage unit; +code { + UNPAIR; + UNIT; + EXEC; + SELF_ADDRESS; + ASSERT_CMPEQ; + NIL operation; + PAIR + } diff --git a/tests_python/contracts_012/mini_scenarios/self_address_sender.tz b/tests_python/contracts_012/mini_scenarios/self_address_sender.tz new file mode 100644 index 000000000000..b0f74073c2ff --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/self_address_sender.tz @@ -0,0 +1,17 @@ +# This tests that the SELF_ADDRESS inside a lambda returns the address +# of the contract executing the lambda (not the contract defining it). +# To do so, two contracts called the sender and the receiver are used. +# The sender (this contract) sends the lambda { DROP; SELF_ADDRESS } +# to the receiver (see self_address_receiver.tz) who checks that the +# returned value is the same as its SELF_ADDRESS. +parameter (contract (lambda unit address)); +storage unit; +code { + CAR; + BALANCE; + LAMBDA unit address { DROP; SELF_ADDRESS }; + TRANSFER_TOKENS; + DIP { UNIT; NIL operation }; + CONS; + PAIR + } diff --git a/tests_python/contracts_012/mini_scenarios/ticket_builder_fungible.tz b/tests_python/contracts_012/mini_scenarios/ticket_builder_fungible.tz new file mode 100644 index 000000000000..674ae800771d --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/ticket_builder_fungible.tz @@ -0,0 +1,40 @@ +## A simple fungible token contract implemented using tickets of type +## [ticket unit]. + +## To store and transfer the tokens see ticket_wallet_fungible.tz + +## For non-fungible tokens, see ticket_builder_non_fungible.tz + +parameter (or (ticket %burn unit) (pair %mint (contract %destination (ticket unit)) (nat %amount))); +storage address; +code + { + AMOUNT; PUSH mutez 0; ASSERT_CMPEQ; + + UNPAIR; + IF_LEFT + { + # Burn entrypoint + + # Check that the ticket is ticketed by ourselves + READ_TICKET; CAR; SELF_ADDRESS; ASSERT_CMPEQ; + + # Drop the ticket + DROP; + + # Finish + NIL operation + } + { + # Mint entrypoint + + # Authenticate SENDER + DUP @manager 2; SENDER; ASSERT_CMPEQ; + + UNPAIR; + SWAP; UNIT; TICKET; + PUSH mutez 0; SWAP; TRANSFER_TOKENS; + NIL operation; SWAP; CONS + }; + PAIR + } diff --git a/tests_python/contracts_012/mini_scenarios/ticket_builder_non_fungible.tz b/tests_python/contracts_012/mini_scenarios/ticket_builder_non_fungible.tz new file mode 100644 index 000000000000..ae669d17ad60 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/ticket_builder_non_fungible.tz @@ -0,0 +1,47 @@ +## A simple non-fungible token contract implemented using tickets of +## type [ticket nat] with amounts of 1. + +## To store and transfer the tokens see ticket_wallet_non_fungible.tz + +## For fungible tokens, see ticket_builder_fungible.tz + +parameter (or (ticket %burn nat) (contract %mint_destination (ticket nat))); +storage (pair (address %manager) (nat %counter)); +code + { + AMOUNT; PUSH mutez 0; ASSERT_CMPEQ; + + UNPAIR 3; + IF_LEFT + { + # Burn entrypoint + + # Check that the ticket is ticketed by ourselves + READ_TICKET; CAR; SELF_ADDRESS; ASSERT_CMPEQ; + + # Drop the ticket + DROP; + + # Finish + NIL operation + } + { + # Mint entrypoint + + # Authenticate SENDER + DUP @manager 2; SENDER; ASSERT_CMPEQ; + + # Mint the token + PUSH @amount nat 1; + DUP @counter 4; + TICKET; + + # Send it + PUSH mutez 0; SWAP; TRANSFER_TOKENS; + NIL operation; SWAP; CONS; + + # Increment counter + DIP 2 {PUSH nat 1; ADD}; + }; + PAIR 3 + } diff --git a/tests_python/contracts_012/mini_scenarios/ticket_wallet_fungible.tz b/tests_python/contracts_012/mini_scenarios/ticket_wallet_fungible.tz new file mode 100644 index 000000000000..d04180ddb899 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/ticket_wallet_fungible.tz @@ -0,0 +1,88 @@ +## A simple wallet for fungible tokens implemented using tickets of +## type [ticket unit]. + +## For actually minting or burning the tokens, see ticket_builder_fungible.tz + +## For non-fungible tokens, see ticket_wallet_non_fungible.tz + +parameter (or (ticket %receive unit) (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer))); +storage (pair (address %manager) (big_map %tickets address (ticket unit))); +code + { + AMOUNT; PUSH mutez 0; ASSERT_CMPEQ; + + UNPAIR 3; + IF_LEFT + { + # Receive entrypoint + + # Get the ticketer + READ_TICKET; CAR @ticketer; DUP; + + # Extract the associated ticket, if any, from the stored big map + DIG 4; + NONE (ticket unit); + DIG 2; + GET_AND_UPDATE; + + # Join it with the parameter + IF_SOME + { + DIG 3; + PAIR; + JOIN_TICKETS; + ASSERT_SOME + } + { DIG 2 }; + SOME; + DIG 2; + GET_AND_UPDATE; + ASSERT_NONE; + SWAP; + PAIR; + NIL operation + } + { + # Send entrypoints + + # Authenticate SENDER + DUP @manager 2; SENDER; ASSERT_CMPEQ; + + UNPAIR 3; + + # Get the ticket associated to the requested ticketer + DIG 4; + NONE (ticket unit); + DUP @ticketer 5; + GET_AND_UPDATE; + ASSERT_SOME; + + # Substract the requested amount + READ_TICKET; + GET @total_amount 4; + DUP @amount 5; + SWAP; SUB; ISNAT; ASSERT_SOME @remaining_amount; + + # Split the ticket + DIG 4; PAIR; SWAP; SPLIT_TICKET; + ASSERT_SOME; UNPAIR @to_send @to_keep; + + # Store the ticket to keep + DUG 5; + SOME; + DIG 3; + GET_AND_UPDATE; + ASSERT_NONE; + DIG 2; PAIR; + + # Send the ticket + SWAP; + PUSH mutez 0; + DIG 3; + TRANSFER_TOKENS; + NIL operation; + SWAP; + CONS; + }; + PAIR + } diff --git a/tests_python/contracts_012/mini_scenarios/ticket_wallet_non_fungible.tz b/tests_python/contracts_012/mini_scenarios/ticket_wallet_non_fungible.tz new file mode 100644 index 000000000000..ba0170ae830e --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/ticket_wallet_non_fungible.tz @@ -0,0 +1,61 @@ +## A simple wallet for non-fungible tokens implemented using tickets +## of type [ticket nat]. + +## For each nat [n], the ticketer is assumed to produce at most one +## ticket containing [n] and to always use amounts of exactly one. + +## For fungible tokens, see ticket_wallet_fungible.tz + +parameter (or (ticket %receive nat) (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id))); +storage (pair (address %manager) (big_map %tickets (pair address nat) (ticket nat))); +code + { + AMOUNT; PUSH mutez 0; ASSERT_CMPEQ; + + UNPAIR 3; + IF_LEFT + { + # Receive entrypoint + + # Get the ticketer and id + READ_TICKET; CAST (pair (address %ticketer) (nat %id) (nat %amount)); + UNPAIR 3; + DIG 2; PUSH nat 1; ASSERT_CMPEQ; # This checks that the amount is 1 + PAIR; + + # Extract the associated ticket, if any, from the stored big map + DIP {SOME; DIP {SWAP}}; + GET_AND_UPDATE; + ASSERT_NONE; + + SWAP; + PAIR; + NIL operation + } + { + # Send entrypoints + + # Authenticate SENDER + DUP @manager 2; SENDER; ASSERT_CMPEQ; + + UNPAIR; + + # Get the ticket associated to the requested ticketer and id + DIG 3; + NONE (ticket nat); + DIG 3; + GET_AND_UPDATE; + ASSERT_SOME; + + SWAP; DIG 3; PAIR; DUG 2; + + # Send the ticket + PUSH mutez 0; + SWAP; + TRANSFER_TOKENS; + NIL operation; + SWAP; + CONS; + }; + PAIR + } diff --git a/tests_python/contracts_012/mini_scenarios/tzip4_view.tz b/tests_python/contracts_012/mini_scenarios/tzip4_view.tz new file mode 100644 index 000000000000..aee5f1fa15f3 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/tzip4_view.tz @@ -0,0 +1,7 @@ +parameter (or (pair %view_const unit (contract nat)) (pair %view_add (pair int int) (contract int))); +storage unit; +code { + CAR; + IF_LEFT {CDR; AMOUNT; PUSH nat 5; TRANSFER_TOKENS; NIL operation; SWAP; CONS; UNIT; SWAP; PAIR} + {UNPAIR; UNPAIR; ADD; AMOUNT; SWAP; TRANSFER_TOKENS; NIL operation; SWAP; CONS; UNIT; SWAP; PAIR}; + } diff --git a/tests_python/contracts_012/mini_scenarios/vote_for_delegate.tz b/tests_python/contracts_012/mini_scenarios/vote_for_delegate.tz new file mode 100644 index 000000000000..1155c073f588 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/vote_for_delegate.tz @@ -0,0 +1,30 @@ +parameter (option key_hash) ; +storage (pair + (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) ; +code { # Update the storage + DUP ; CDAAR %addr @%; SENDER ; PAIR %@ %@; UNPAIR; + IFCMPEQ + { UNPAIR ; SWAP ; SET_CADR %key @changed_mgr1_key } + { DUP ; CDDAR ; SENDER ; + IFCMPEQ + { UNPAIR ; SWAP ; SET_CDDR %key } + { FAIL } } ; + # Now compare the proposals + DUP ; CADR ; + DIP { DUP ; CDDR } ; + IF_NONE + { IF_NONE + { NONE key_hash ; + SET_DELEGATE ; NIL operation ; SWAP ; CONS } + { DROP ; NIL operation } } + { SWAP ; + IF_SOME + { DIP { DUP } ; + IFCMPEQ + { SOME ; + SET_DELEGATE ; NIL operation ; SWAP ; CONS } + { DROP ; + NIL operation }} + { DROP ; NIL operation }} ; + PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/mini_scenarios/weather_insurance.tz b/tests_python/contracts_012/mini_scenarios/weather_insurance.tz new file mode 100644 index 000000000000..e7e99e018335 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/weather_insurance.tz @@ -0,0 +1,19 @@ +parameter (pair (signature %signed_weather_data) (nat :rain %actual_level)); +# (pair (under_key over_key) (pair weather_service_key (pair rain_level days_in_future))) +storage (pair (pair (address %under_key) + (address %over_key)) + (pair (nat :rain %rain_level) (key %weather_service_key))); +code { DUP; DUP; + CAR; MAP_CDR{PACK ; BLAKE2B}; + SWAP; CDDDR %weather_service_key; + DIP {UNPAIR} ; CHECK_SIGNATURE @sigok; # Check if the data has been correctly signed + ASSERT; # If signature is not correct, end the execution + DUP; DUP; DUP; DIIIP{CDR %storage}; # Place storage type on bottom of stack + DIIP{CDAR}; # Place contracts below numbers + DIP{CADR %actual_level}; # Get actual rain + CDDAR %rain_level; # Get rain threshold + CMPLT; IF {CAR %under_key} {CDR %over_key}; # Select contract to receive tokens + CONTRACT unit ; ASSERT_SOME ; + BALANCE; UNIT ; TRANSFER_TOKENS @trans.op; # Setup and execute transfer + NIL operation ; SWAP ; CONS ; + PAIR }; diff --git a/tests_python/contracts_012/mini_scenarios/xcat.tz b/tests_python/contracts_012/mini_scenarios/xcat.tz new file mode 100644 index 000000000000..83e6c7ac1d50 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/xcat.tz @@ -0,0 +1,48 @@ +parameter (bytes); +storage (unit); +code { + # Extract parameter from initial stack. + CAR @preimage; + DIP { + # Push contract constants to the stack. + # + # There's a temptation to use @storage to parametrize + # a contract but, in general, there's no reason to encumber + # @storage with immutable values. + PUSH @from key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; #changeme + IMPLICIT_ACCOUNT ; + PUSH @to key_hash "tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN"; #changeme + IMPLICIT_ACCOUNT ; + PUSH @target_hash bytes 0x123456; #changeme + PUSH @deadline timestamp "2018-08-08 00:00:00Z"; #changeme + }; + # Test if the deadline has passed. + SWAP; NOW; + IFCMPLT + # In case the deadline did pass: + { + # Ignore parameter, just transfer xtz balance back to @from + DROP; DROP; DROP; BALANCE; UNIT; TRANSFER_TOKENS; + } + # In case the deadline hasn't passed yet: + { + # Test length of parameter. + DUP; SIZE; + PUSH @max_length nat 32; + IFCMPLT + { PUSH string "preimage too long"; FAILWITH; } + { + # Test if it's a preimage of @target_hash. + SHA256 @candidate_hash; + IFCMPNEQ + { PUSH string "invalid preimage"; FAILWITH; } + { + # Transfer xtz balance to @to. + BALANCE; UNIT; TRANSFER_TOKENS; DIP { DROP }; + }; + }; + }; + # Transform single operation into a list. + NIL operation; SWAP; CONS; + UNIT; SWAP; PAIR + } diff --git a/tests_python/contracts_012/mini_scenarios/xcat_dapp.tz b/tests_python/contracts_012/mini_scenarios/xcat_dapp.tz new file mode 100644 index 000000000000..86ca62c5ac50 --- /dev/null +++ b/tests_python/contracts_012/mini_scenarios/xcat_dapp.tz @@ -0,0 +1,79 @@ +parameter (or + # First possible action is funding, to create an xcat + (pair %fund + (address %dest) + (pair %settings (bytes %target_hash) (timestamp %deadline))) + + # Other possible action is to claim the tokens (or ask a refund) + (or %claim_refund + (bytes %preimage_claim) + (bytes %refund_hash))); + +storage (pair + (big_map + bytes # The target hash is used as a key + (pair + # We store in %from the person who funded the xcat + (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + ) + unit); + +code { + NIL @operations operation; SWAP; + UNPAPAIR @% @% @%; DIP {DUP}; + IF_LEFT # Let's fund a new xcat! + { + # Unpack the parameters + UNPAIR @% @%; + # Assert that the destination address is of type unit. + # This costs a bit more gas but limits foot-shooting. + DUP; CONTRACT @dest unit; ASSERT_SOME; DROP; + SWAP; UNPAIR @% @%; + DIP + { + AMOUNT @amount; + SENDER; + DUP; CONTRACT @from unit; ASSERT_SOME; DROP; + DIP { PAIR; SWAP; }; PAIR; PAIR; SOME @xcat; + SWAP; + }; + DUP; DIP { MEM; NOT; ASSERT }; # Assert that this target hash isn't already in the map + UPDATE; PAIR @new_storage; SWAP; PAIR; + } + { + # Let's process a claim or a refund + IF_LEFT + { # It's a claim! + DUP; SIZE; PUSH nat 32; ASSERT_CMPGE; + SHA256 @hash; DUP; DIP {SWAP}; + DIIP { + GET; ASSERT_SOME; + # Check deadline and prepare transaction. + DUP; CADR @%; CONTRACT @dest unit; ASSERT_SOME; + SWAP; CDR @%; + UNPAIR @% @%; SWAP; + # The deadline must not have passed + NOW; ASSERT_CMPLT; + # prepare transaction + UNIT; TRANSFER_TOKENS; + }; + } + { # It's a refund! + DUP; + DIP + { + GET; ASSERT_SOME; + DUP; CAAR @%; CONTRACT @from unit; ASSERT_SOME; SWAP; CDR; + UNPAIR @% @%; SWAP; + # The deadline must not HAVE passed + NOW; ASSERT_CMPGE; + UNIT; TRANSFER_TOKENS; SWAP; + }; + }; + # Clear the big map + NONE @none (pair (pair address address) (pair mutez timestamp)); + SWAP; UPDATE @cleared_map; SWAP; DIP { PAIR; SWAP }; + CONS; PAIR; + } + } \ No newline at end of file diff --git a/tests_python/contracts_012/non_regression/bug_262.tz b/tests_python/contracts_012/non_regression/bug_262.tz new file mode 100644 index 000000000000..63475c5ac185 --- /dev/null +++ b/tests_python/contracts_012/non_regression/bug_262.tz @@ -0,0 +1,5 @@ +{ parameter unit ; + storage unit ; + code { DROP ; + LAMBDA unit unit {} ; UNIT ; EXEC ; + NIL operation ; PAIR } } \ No newline at end of file diff --git a/tests_python/contracts_012/non_regression/pairk_annot.tz b/tests_python/contracts_012/non_regression/pairk_annot.tz new file mode 100644 index 000000000000..8b0cf242bd9c --- /dev/null +++ b/tests_python/contracts_012/non_regression/pairk_annot.tz @@ -0,0 +1,7 @@ +# Test for old PAIR k annotation handling bug +parameter unit; +storage unit; +code { SENDER; SOURCE; PAIR 2; + SOURCE; SENDER; PAIR 2; + COMPARE; DROP; + CDR; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/abs.tz b/tests_python/contracts_012/opcodes/abs.tz new file mode 100644 index 000000000000..d03d0883fe73 --- /dev/null +++ b/tests_python/contracts_012/opcodes/abs.tz @@ -0,0 +1,5 @@ +parameter nat; +storage unit; +code { CAR; + DUP; NEG; ABS; COMPARE; ASSERT_EQ; + UNIT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add.tz b/tests_python/contracts_012/opcodes/add.tz new file mode 100644 index 000000000000..cbefea08a7a4 --- /dev/null +++ b/tests_python/contracts_012/opcodes/add.tz @@ -0,0 +1,25 @@ +parameter unit; +storage unit; +code + { + CAR; + + PUSH int 2; PUSH int 2; ADD; PUSH int 4; ASSERT_CMPEQ; + PUSH int 2; PUSH int 2; ADD; PUSH int 4; ASSERT_CMPEQ; + PUSH int 2; PUSH nat 2; ADD; PUSH int 4; ASSERT_CMPEQ; + PUSH nat 2; PUSH int 2; ADD; PUSH int 4; ASSERT_CMPEQ; + PUSH nat 2; PUSH nat 2; ADD; PUSH nat 4; ASSERT_CMPEQ; + + # Offset a timestamp by 60 seconds + PUSH int 60; PUSH timestamp "2019-09-09T12:08:37Z"; ADD; + PUSH timestamp "2019-09-09T12:09:37Z"; ASSERT_CMPEQ; + + PUSH timestamp "2019-09-09T12:08:37Z"; PUSH int 60; ADD; + PUSH timestamp "2019-09-09T12:09:37Z"; ASSERT_CMPEQ; + + PUSH mutez 1000; PUSH mutez 1000; ADD; + PUSH mutez 2000; ASSERT_CMPEQ; + + NIL operation; + PAIR; + } diff --git a/tests_python/contracts_012/opcodes/add_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/add_bls12_381_fr.tz new file mode 100644 index 000000000000..e7b60dedc932 --- /dev/null +++ b/tests_python/contracts_012/opcodes/add_bls12_381_fr.tz @@ -0,0 +1,3 @@ +parameter (pair bls12_381_fr bls12_381_fr); +storage (option (bls12_381_fr)); +code {CAR; UNPAIR; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add_bls12_381_g1.tz b/tests_python/contracts_012/opcodes/add_bls12_381_g1.tz new file mode 100644 index 000000000000..9f817c88d8a5 --- /dev/null +++ b/tests_python/contracts_012/opcodes/add_bls12_381_g1.tz @@ -0,0 +1,3 @@ +parameter (pair bls12_381_g1 bls12_381_g1); +storage (option (bls12_381_g1)); +code {CAR; UNPAIR; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add_bls12_381_g2.tz b/tests_python/contracts_012/opcodes/add_bls12_381_g2.tz new file mode 100644 index 000000000000..1d1c0688c1d2 --- /dev/null +++ b/tests_python/contracts_012/opcodes/add_bls12_381_g2.tz @@ -0,0 +1,3 @@ +parameter (pair bls12_381_g2 bls12_381_g2); +storage (option (bls12_381_g2)); +code {CAR; UNPAIR; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add_delta_timestamp.tz b/tests_python/contracts_012/opcodes/add_delta_timestamp.tz new file mode 100644 index 000000000000..b9ed86901726 --- /dev/null +++ b/tests_python/contracts_012/opcodes/add_delta_timestamp.tz @@ -0,0 +1,3 @@ +parameter (pair int timestamp); +storage (option timestamp); +code { CAR; DUP; CAR; DIP{CDR}; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/add_timestamp_delta.tz b/tests_python/contracts_012/opcodes/add_timestamp_delta.tz new file mode 100644 index 000000000000..766bf9f91f51 --- /dev/null +++ b/tests_python/contracts_012/opcodes/add_timestamp_delta.tz @@ -0,0 +1,3 @@ +parameter (pair timestamp int); +storage (option timestamp); +code { CAR; DUP; CAR; DIP{CDR}; ADD; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/address.tz b/tests_python/contracts_012/opcodes/address.tz new file mode 100644 index 000000000000..7e6bcdec337b --- /dev/null +++ b/tests_python/contracts_012/opcodes/address.tz @@ -0,0 +1,3 @@ +parameter (contract unit); +storage (option address); +code {CAR; ADDRESS; SOME; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/amount_after_fib_view.tz b/tests_python/contracts_012/opcodes/amount_after_fib_view.tz new file mode 100644 index 000000000000..50fdf3d7c139 --- /dev/null +++ b/tests_python/contracts_012/opcodes/amount_after_fib_view.tz @@ -0,0 +1,24 @@ +# This contract calls the view `fib` on the address passed as +# parameter. After returning from the view it stores its AMOUNT. +parameter address ; +storage mutez; +code + { CAR ; + DUP ; + PUSH nat 3 ; + VIEW "fib" nat; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 15000000 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + AMOUNT; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + diff --git a/tests_python/contracts_012/opcodes/amount_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/amount_after_nonexistent_view.tz new file mode 100644 index 000000000000..d373e1c9e52b --- /dev/null +++ b/tests_python/contracts_012/opcodes/amount_after_nonexistent_view.tz @@ -0,0 +1,23 @@ +# This contract calls the non-existent view on the address +# passed as parameter. After returning from the view it +# stores it's AMOUNT. +parameter address ; +storage mutez; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "nonexistent" (pair nat nat) ; + ASSERT_NONE ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 15000000 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + AMOUNT; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; diff --git a/tests_python/contracts_012/opcodes/amount_after_view.tz b/tests_python/contracts_012/opcodes/amount_after_view.tz new file mode 100644 index 000000000000..eab7c02256ef --- /dev/null +++ b/tests_python/contracts_012/opcodes/amount_after_view.tz @@ -0,0 +1,26 @@ +# This contract calls the view `id` on the address passed as +# parameter. After returning from the view it stores its AMOUNT. +parameter address ; +storage mutez; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "id" (pair nat nat) ; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 15000000 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + AMOUNT; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + + + diff --git a/tests_python/contracts_012/opcodes/and.tz b/tests_python/contracts_012/opcodes/and.tz new file mode 100644 index 000000000000..48e346ca04f3 --- /dev/null +++ b/tests_python/contracts_012/opcodes/and.tz @@ -0,0 +1,3 @@ +parameter (pair :param (bool %first) (bool %second)); +storage (option bool); +code { CAR ; UNPAIR; AND @and; SOME @res; NIL @noop operation; PAIR; UNPAIR @x @y; PAIR %a %b }; diff --git a/tests_python/contracts_012/opcodes/and_binary.tz b/tests_python/contracts_012/opcodes/and_binary.tz new file mode 100644 index 000000000000..96f60082c713 --- /dev/null +++ b/tests_python/contracts_012/opcodes/and_binary.tz @@ -0,0 +1,27 @@ +parameter unit; +storage unit; +code { DROP; + + # 0101 & 0110 = 0100 + PUSH nat 5; PUSH nat 6; AND; PUSH nat 4; ASSERT_CMPEQ; + + # 0110 & 0101 = 0100 + PUSH nat 6; PUSH int 5; AND; PUSH nat 4; ASSERT_CMPEQ; + + # Negative numbers are represented as with a initial virtual + # infinite series of 1's. + # Hence, AND with -1 (1111...) is identity: + + # 12 = ...1100 + # & -1 = ...1111 + # ---- + # = 12 = ...1100 + PUSH nat 12; PUSH int -1; AND; PUSH nat 12; ASSERT_CMPEQ; + + # 12 = ...0001100 + # & -5 = ...1111011 + # ----------------- + # 8 = ...0001000 + PUSH nat 12; PUSH int -5; AND; PUSH nat 8; ASSERT_CMPEQ; + + UNIT; NIL @noop operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/and_logical_1.tz b/tests_python/contracts_012/opcodes/and_logical_1.tz new file mode 100644 index 000000000000..20743c0bfdf9 --- /dev/null +++ b/tests_python/contracts_012/opcodes/and_logical_1.tz @@ -0,0 +1,3 @@ +parameter (pair bool bool); +storage bool; +code { CAR ; UNPAIR; AND @and; NIL @noop operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/balance.tz b/tests_python/contracts_012/opcodes/balance.tz new file mode 100644 index 000000000000..0a9bfc61494c --- /dev/null +++ b/tests_python/contracts_012/opcodes/balance.tz @@ -0,0 +1,3 @@ +parameter unit; +storage mutez; +code {DROP; BALANCE; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/balance_after_fib_view.tz b/tests_python/contracts_012/opcodes/balance_after_fib_view.tz new file mode 100644 index 000000000000..b9a52d1e895a --- /dev/null +++ b/tests_python/contracts_012/opcodes/balance_after_fib_view.tz @@ -0,0 +1,25 @@ +# This contract calls the view `fib` on the address passed as +# parameter. After returning from the view it stores its BALANCE. +parameter address ; +storage mutez; +code + { CAR ; + DUP ; + PUSH nat 3 ; + VIEW "fib" nat; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 15000000 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + BALANCE; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + + diff --git a/tests_python/contracts_012/opcodes/balance_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/balance_after_nonexistent_view.tz new file mode 100644 index 000000000000..96bb623530df --- /dev/null +++ b/tests_python/contracts_012/opcodes/balance_after_nonexistent_view.tz @@ -0,0 +1,22 @@ +# This contract calls the noneexistent view on the address passed as +# parameter. After returning from the view it stores it's BALANCE. +parameter address ; +storage mutez; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "nonexistent" (pair nat nat) ; + ASSERT_NONE ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 15000000 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + BALANCE; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; diff --git a/tests_python/contracts_012/opcodes/balance_after_view.tz b/tests_python/contracts_012/opcodes/balance_after_view.tz new file mode 100644 index 000000000000..c2acc0320cdc --- /dev/null +++ b/tests_python/contracts_012/opcodes/balance_after_view.tz @@ -0,0 +1,25 @@ +# This contract calls the view `id` on the address passed as +# parameter. After returning from the view it stores its BALANCE. +parameter address ; +storage mutez; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "id" (pair nat nat) ; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 15000000 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + BALANCE; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + + diff --git a/tests_python/contracts_012/opcodes/big_map_mem_nat.tz b/tests_python/contracts_012/opcodes/big_map_mem_nat.tz new file mode 100644 index 000000000000..71ecaf2c4a75 --- /dev/null +++ b/tests_python/contracts_012/opcodes/big_map_mem_nat.tz @@ -0,0 +1,7 @@ +parameter nat; +storage (pair (big_map nat nat) (option bool)) ; +# stores (map, Some flag) where flag = parameter is a member of +# the map in first component of storage +code { UNPAIR; + DIP { CAR; DUP }; + MEM; SOME; SWAP; PAIR; NIL operation; PAIR;} diff --git a/tests_python/contracts_012/opcodes/big_map_mem_string.tz b/tests_python/contracts_012/opcodes/big_map_mem_string.tz new file mode 100644 index 000000000000..8c557f7dc1f8 --- /dev/null +++ b/tests_python/contracts_012/opcodes/big_map_mem_string.tz @@ -0,0 +1,7 @@ +parameter string; +storage (pair (big_map string nat) (option bool)) ; +# stores (map, Some flag) where flag = parameter is a member of +# the map in first component of storage +code { UNPAIR; + DIP { CAR; DUP }; + MEM; SOME; SWAP; PAIR; NIL operation; PAIR;} diff --git a/tests_python/contracts_012/opcodes/big_map_to_self.tz b/tests_python/contracts_012/opcodes/big_map_to_self.tz new file mode 100644 index 000000000000..6a9442b9f3e5 --- /dev/null +++ b/tests_python/contracts_012/opcodes/big_map_to_self.tz @@ -0,0 +1,22 @@ +parameter (or (pair %have_fun (big_map string nat) unit) (unit %default)); +storage (big_map string nat); +code { + UNPAIR; + DIP {NIL operation}; + IF_LEFT { + DROP + } + { + DROP; + SELF %have_fun; + PUSH mutez 0; + DUP 4; + PUSH (option nat) (Some 8); + PUSH string "hahaha"; + UPDATE; + UNIT; SWAP; PAIR; + TRANSFER_TOKENS; + CONS + }; + PAIR + } diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_push_bytes_not_padded.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_push_bytes_not_padded.tz new file mode 100644 index 000000000000..fd4142914d2c --- /dev/null +++ b/tests_python/contracts_012/opcodes/bls12_381_fr_push_bytes_not_padded.tz @@ -0,0 +1,9 @@ +parameter unit; +storage (option bls12_381_fr); +code { + DROP; + PUSH bls12_381_fr 0x00; + SOME; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_push_nat.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_push_nat.tz new file mode 100644 index 000000000000..314b97f2a6b9 --- /dev/null +++ b/tests_python/contracts_012/opcodes/bls12_381_fr_push_nat.tz @@ -0,0 +1,9 @@ +parameter unit; +storage (option bls12_381_fr); +code { + DROP; + PUSH bls12_381_fr 16; + SOME; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_to_int.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_to_int.tz new file mode 100644 index 000000000000..67e2c9b080b1 --- /dev/null +++ b/tests_python/contracts_012/opcodes/bls12_381_fr_to_int.tz @@ -0,0 +1,8 @@ +parameter bls12_381_fr; +storage int; +code { + CAR; + INT; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_to_mutez.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_to_mutez.tz new file mode 100644 index 000000000000..39630958e515 --- /dev/null +++ b/tests_python/contracts_012/opcodes/bls12_381_fr_to_mutez.tz @@ -0,0 +1,12 @@ +parameter bls12_381_fr; +storage mutez; +code { + CAR; + INT; + ISNAT; + ASSERT_SOME; + PUSH mutez 1; + MUL; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_z_int.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_z_int.tz new file mode 100644 index 000000000000..67018c55faba --- /dev/null +++ b/tests_python/contracts_012/opcodes/bls12_381_fr_z_int.tz @@ -0,0 +1,8 @@ +parameter int; +storage (bls12_381_fr); +code { + UNPAIR; + MUL; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_fr_z_nat.tz b/tests_python/contracts_012/opcodes/bls12_381_fr_z_nat.tz new file mode 100644 index 000000000000..1376e0c39561 --- /dev/null +++ b/tests_python/contracts_012/opcodes/bls12_381_fr_z_nat.tz @@ -0,0 +1,8 @@ +parameter nat; +storage (bls12_381_fr); +code { + UNPAIR; + MUL; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_z_fr_int.tz b/tests_python/contracts_012/opcodes/bls12_381_z_fr_int.tz new file mode 100644 index 000000000000..783fb3c0d660 --- /dev/null +++ b/tests_python/contracts_012/opcodes/bls12_381_z_fr_int.tz @@ -0,0 +1,9 @@ +parameter int; +storage (bls12_381_fr); +code { + UNPAIR; + SWAP; + MUL; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bls12_381_z_fr_nat.tz b/tests_python/contracts_012/opcodes/bls12_381_z_fr_nat.tz new file mode 100644 index 000000000000..1210e36db0e1 --- /dev/null +++ b/tests_python/contracts_012/opcodes/bls12_381_z_fr_nat.tz @@ -0,0 +1,9 @@ +parameter nat; +storage (bls12_381_fr); +code { + UNPAIR; + SWAP; + MUL; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/bytes.tz b/tests_python/contracts_012/opcodes/bytes.tz new file mode 100644 index 000000000000..e4dd8445eecc --- /dev/null +++ b/tests_python/contracts_012/opcodes/bytes.tz @@ -0,0 +1,11 @@ +# A contract that accepts bytes in a default entry point and does nothing. +# Useful for testing transfers of arbitrary sizes. +parameter bytes; +storage unit; +code + { + CDR; # @storage + # == default == # @storage + NIL operation; # list operation : @storage + PAIR; # pair (list operation) @storage + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/car.tz b/tests_python/contracts_012/opcodes/car.tz new file mode 100644 index 000000000000..8fd03ba51052 --- /dev/null +++ b/tests_python/contracts_012/opcodes/car.tz @@ -0,0 +1,3 @@ +parameter (pair (nat :l) (nat :r)); +storage nat; +code { CAR; CAR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/cdr.tz b/tests_python/contracts_012/opcodes/cdr.tz new file mode 100644 index 000000000000..dae260c5be74 --- /dev/null +++ b/tests_python/contracts_012/opcodes/cdr.tz @@ -0,0 +1,3 @@ +parameter (pair (nat :l) (nat :r)); +storage nat; +code { CAR; CDR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/chain_id.tz b/tests_python/contracts_012/opcodes/chain_id.tz new file mode 100644 index 000000000000..783d13fa0afc --- /dev/null +++ b/tests_python/contracts_012/opcodes/chain_id.tz @@ -0,0 +1,3 @@ +parameter unit; +storage unit; +code { CHAIN_ID; DROP; CAR; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/chain_id_store.tz b/tests_python/contracts_012/opcodes/chain_id_store.tz new file mode 100644 index 000000000000..11e57fd210c7 --- /dev/null +++ b/tests_python/contracts_012/opcodes/chain_id_store.tz @@ -0,0 +1,3 @@ +parameter unit; +storage (option chain_id); +code { DROP; CHAIN_ID; SOME; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/check_signature.tz b/tests_python/contracts_012/opcodes/check_signature.tz new file mode 100644 index 000000000000..b5d5b2842648 --- /dev/null +++ b/tests_python/contracts_012/opcodes/check_signature.tz @@ -0,0 +1,10 @@ +parameter key; +storage (pair signature string); +code { + DUP; DUP; + DIP{ CDR; DUP; CAR; + DIP{CDR; PACK}}; + CAR; CHECK_SIGNATURE; + IF {} {FAIL} ; + CDR; NIL operation ; PAIR}; + diff --git a/tests_python/contracts_012/opcodes/comb-get.tz b/tests_python/contracts_012/opcodes/comb-get.tz new file mode 100644 index 000000000000..5493d68f2696 --- /dev/null +++ b/tests_python/contracts_012/opcodes/comb-get.tz @@ -0,0 +1,27 @@ +# See also ../macros/carn_and_cdrn.tz for the same test using the +# CAR n and CDR n macros. +parameter (pair nat nat nat unit); +storage unit; +code { + CAR ; + + # Checking the first element + DUP ; CAR ; + PUSH nat 1 ; ASSERT_CMPEQ ; + DUP ; GET 1 ; + PUSH nat 1 ; ASSERT_CMPEQ ; + + # Checking the second element + DUP ; GET 3 ; + PUSH nat 4 ; ASSERT_CMPEQ ; + + # Checking the third element + DUP ; GET 5 ; + PUSH nat 2 ; ASSERT_CMPEQ ; + + # Checking the last (fourth) element + DUP ; GET 6 ; + UNIT ; ASSERT_CMPEQ ; + + DROP ; UNIT ; NIL operation ; PAIR + } diff --git a/tests_python/contracts_012/opcodes/comb-literals.tz b/tests_python/contracts_012/opcodes/comb-literals.tz new file mode 100644 index 000000000000..2a2b217d7857 --- /dev/null +++ b/tests_python/contracts_012/opcodes/comb-literals.tz @@ -0,0 +1,9 @@ +# This pushes a list of combs to test the effect of the normalize script command +parameter unit; +storage unit; +code { + PUSH + (list (pair nat nat nat nat)) + {Pair 0 3 6 9; Pair 1 (Pair 4 (Pair 7 10)); {2; 5; 8; 11}}; + DROP 2; UNIT; NIL operation; PAIR + } diff --git a/tests_python/contracts_012/opcodes/comb-set-2.tz b/tests_python/contracts_012/opcodes/comb-set-2.tz new file mode 100644 index 000000000000..757acfd380e6 --- /dev/null +++ b/tests_python/contracts_012/opcodes/comb-set-2.tz @@ -0,0 +1,10 @@ +# This tests UPDATE on combs. Contrary to comb-set.tz, both the values +# and their types are updated. +parameter (pair nat nat nat unit); +storage (option (pair int nat string bytes)); +code { + CAR ; + PUSH int 2 ; UPDATE 1 ; + PUSH string "toto" ; UPDATE 5 ; + PUSH bytes 0x01 ; UPDATE 6 ; + SOME ; NIL operation ; PAIR ; } diff --git a/tests_python/contracts_012/opcodes/comb-set.tz b/tests_python/contracts_012/opcodes/comb-set.tz new file mode 100644 index 000000000000..fe407571923e --- /dev/null +++ b/tests_python/contracts_012/opcodes/comb-set.tz @@ -0,0 +1,10 @@ +# This tests UPDATE on combs. See also comb-set-2.tz for tests of +# UPDATE that also change the type of fields. +parameter unit; +storage (pair nat nat nat unit); +code { CDR ; + PUSH nat 2 ; UPDATE 1 ; + PUSH nat 12 ; UPDATE 3 ; + PUSH nat 8 ; UPDATE 5 ; + UNIT ; UPDATE 6 ; + NIL operation ; PAIR ; } diff --git a/tests_python/contracts_012/opcodes/comb.tz b/tests_python/contracts_012/opcodes/comb.tz new file mode 100644 index 000000000000..6709bde8b883 --- /dev/null +++ b/tests_python/contracts_012/opcodes/comb.tz @@ -0,0 +1,9 @@ +parameter unit; +storage (pair nat nat nat); +code { DROP ; + PUSH nat 3 ; + PUSH nat 2 ; + PUSH nat 1 ; + NIL operation ; + PAIR 4 + } diff --git a/tests_python/contracts_012/opcodes/compare.tz b/tests_python/contracts_012/opcodes/compare.tz new file mode 100644 index 000000000000..963215fb46cd --- /dev/null +++ b/tests_python/contracts_012/opcodes/compare.tz @@ -0,0 +1,52 @@ +parameter unit; +storage unit; +code { + DROP; + + # bool + PUSH bool True; DUP; COMPARE; ASSERT_EQ; + PUSH bool False; DUP; COMPARE; ASSERT_EQ; + PUSH bool False; PUSH bool True; COMPARE; ASSERT_GT; + PUSH bool True; PUSH bool False; COMPARE; ASSERT_LT; + + # bytes + PUSH bytes 0xAABBCC; DUP; COMPARE; ASSERT_EQ; + PUSH bytes 0x; PUSH bytes 0x; COMPARE; ASSERT_EQ; + PUSH bytes 0x; PUSH bytes 0x01; COMPARE; ASSERT_GT; + PUSH bytes 0x01; PUSH bytes 0x02; COMPARE; ASSERT_GT; + PUSH bytes 0x02; PUSH bytes 0x01; COMPARE; ASSERT_LT; + + # int + PUSH int 1; DUP; COMPARE; ASSERT_EQ; + PUSH int 10; PUSH int 5; COMPARE; ASSERT_LT; + PUSH int -4; PUSH int 1923; COMPARE; ASSERT_GT; + + # nat + PUSH nat 1; DUP; COMPARE; ASSERT_EQ; + PUSH nat 10; PUSH nat 5; COMPARE; ASSERT_LT; + PUSH nat 4; PUSH nat 1923; COMPARE; ASSERT_GT; + + # key_hash + PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; DUP; COMPARE; ASSERT_EQ; + PUSH key_hash "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv"; PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; COMPARE; ASSERT_LT; + PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; PUSH key_hash "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv"; COMPARE; ASSERT_GT; + + # mutez + PUSH mutez 1; DUP; COMPARE; ASSERT_EQ; + PUSH mutez 10; PUSH mutez 5; COMPARE; ASSERT_LT; + PUSH mutez 4; PUSH mutez 1923; COMPARE; ASSERT_GT; + + # string + PUSH string "AABBCC"; DUP; COMPARE; ASSERT_EQ; + PUSH string ""; PUSH string ""; COMPARE; ASSERT_EQ; + PUSH string ""; PUSH string "a"; COMPARE; ASSERT_GT; + PUSH string "a"; PUSH string "b"; COMPARE; ASSERT_GT; + PUSH string "b"; PUSH string "a"; COMPARE; ASSERT_LT; + + # timestamp + PUSH timestamp "2019-09-16T08:38:05Z"; DUP; COMPARE; ASSERT_EQ; + PUSH timestamp "2017-09-16T08:38:04Z"; PUSH timestamp "2019-09-16T08:38:05Z"; COMPARE; ASSERT_GT; + PUSH timestamp "2019-09-16T08:38:05Z"; PUSH timestamp "2019-09-16T08:38:04Z"; COMPARE; ASSERT_LT; + + UNIT; NIL operation; PAIR; + } diff --git a/tests_python/contracts_012/opcodes/compare_big_type.tz b/tests_python/contracts_012/opcodes/compare_big_type.tz new file mode 100644 index 000000000000..666ad3137777 --- /dev/null +++ b/tests_python/contracts_012/opcodes/compare_big_type.tz @@ -0,0 +1,20 @@ +# This contract should cost a lot of gas to typecheck +# because big types are compared in COMPARE +parameter unit; +storage unit; +code { DROP; PUSH nat 0 ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DROP ; UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/compare_big_type2.tz b/tests_python/contracts_012/opcodes/compare_big_type2.tz new file mode 100644 index 000000000000..126217d79fdf --- /dev/null +++ b/tests_python/contracts_012/opcodes/compare_big_type2.tz @@ -0,0 +1,22 @@ +# Like compare_big_type.tz but with an extra line +# DUP ; DUP ; COMPARE ; DROP ; +# so that we can measure how much it costs +parameter unit; +storage unit; +code { DROP; PUSH nat 0 ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DUP ; DUP ; COMPARE ; DROP ; + DROP ; UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/comparisons.tz b/tests_python/contracts_012/opcodes/comparisons.tz new file mode 100644 index 000000000000..c603f07339ce --- /dev/null +++ b/tests_python/contracts_012/opcodes/comparisons.tz @@ -0,0 +1,15 @@ +parameter (list int); +storage (list (list bool)); +code { + CAR; + + NIL (list bool); + DIP {DUP; MAP { EQ; };}; SWAP; CONS; + DIP {DUP; MAP { NEQ; };}; SWAP; CONS; + DIP {DUP; MAP { LE; };}; SWAP; CONS; + DIP {DUP; MAP { LT; };}; SWAP; CONS; + DIP {DUP; MAP { GE; };}; SWAP; CONS; + DIP {MAP { GT; };}; SWAP; CONS; + + NIL operation; PAIR; + } diff --git a/tests_python/contracts_012/opcodes/concat_hello.tz b/tests_python/contracts_012/opcodes/concat_hello.tz new file mode 100644 index 000000000000..e290b90fb2ad --- /dev/null +++ b/tests_python/contracts_012/opcodes/concat_hello.tz @@ -0,0 +1,4 @@ +parameter (list string); +storage (list string); +code{ CAR; + MAP { PUSH @hello string "Hello "; CONCAT }; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/concat_hello_bytes.tz b/tests_python/contracts_012/opcodes/concat_hello_bytes.tz new file mode 100644 index 000000000000..55f8ab7a216b --- /dev/null +++ b/tests_python/contracts_012/opcodes/concat_hello_bytes.tz @@ -0,0 +1,4 @@ +parameter (list bytes); +storage (list bytes); +code{ CAR; + MAP { PUSH bytes 0xFF; CONCAT }; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/concat_list.tz b/tests_python/contracts_012/opcodes/concat_list.tz new file mode 100644 index 000000000000..b570027ff68e --- /dev/null +++ b/tests_python/contracts_012/opcodes/concat_list.tz @@ -0,0 +1,5 @@ +parameter (list string); +storage string; +code {CAR; PUSH string ""; SWAP; + ITER {SWAP; DIP{NIL string; SWAP; CONS}; CONS; CONCAT}; + NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/cons.tz b/tests_python/contracts_012/opcodes/cons.tz new file mode 100644 index 000000000000..5189b47c36b4 --- /dev/null +++ b/tests_python/contracts_012/opcodes/cons.tz @@ -0,0 +1,3 @@ +parameter int; +storage (list int); +code { UNPAIR; CONS; NIL operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/contains_all.tz b/tests_python/contracts_012/opcodes/contains_all.tz new file mode 100644 index 000000000000..fe4160f87227 --- /dev/null +++ b/tests_python/contracts_012/opcodes/contains_all.tz @@ -0,0 +1,7 @@ +parameter (pair (list string) (list string)); +storage (option bool); +code {CAR; DUP; CAR; DIP{CDR}; EMPTY_SET string; SWAP; + ITER {PAIR; DUP; CAR; DIP{CDR}; PUSH bool True; SWAP; UPDATE}; + PUSH bool True; SWAP; PAIR; SWAP; + ITER {PAIR; DUP; DUP; CAR; DIP{CDAR; DIP{CDDR}; DUP}; MEM; DIP{SWAP}; AND; SWAP; PAIR}; + CDR; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/contract.tz b/tests_python/contracts_012/opcodes/contract.tz new file mode 100644 index 000000000000..939337918d1c --- /dev/null +++ b/tests_python/contracts_012/opcodes/contract.tz @@ -0,0 +1,11 @@ +parameter address; +storage unit; +code { + CAR; + CONTRACT unit; + ASSERT_SOME; + DROP; + UNIT; + NIL operation; + PAIR + }; diff --git a/tests_python/contracts_012/opcodes/create_contract.tz b/tests_python/contracts_012/opcodes/create_contract.tz new file mode 100644 index 000000000000..d3fb8dc617a8 --- /dev/null +++ b/tests_python/contracts_012/opcodes/create_contract.tz @@ -0,0 +1,14 @@ +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 unit ; + storage unit ; + code + { CDR; + NIL operation; + PAIR; } }; + DIP {SOME;NIL operation};CONS ; PAIR} # Ending calling convention stuff diff --git a/tests_python/contracts_012/opcodes/create_contract_rootname.tz b/tests_python/contracts_012/opcodes/create_contract_rootname.tz new file mode 100644 index 000000000000..b85b4cf8bb41 --- /dev/null +++ b/tests_python/contracts_012/opcodes/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_012/opcodes/create_contract_rootname_alt.tz b/tests_python/contracts_012/opcodes/create_contract_rootname_alt.tz new file mode 100644 index 000000000000..226a9abba298 --- /dev/null +++ b/tests_python/contracts_012/opcodes/create_contract_rootname_alt.tz @@ -0,0 +1,14 @@ +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 (unit %root) ; + storage unit ; + code + { CDR; + NIL operation; + PAIR; } }; + DIP {SOME;NIL operation}; CONS ; PAIR} # Ending calling convention stuff diff --git a/tests_python/contracts_012/opcodes/create_contract_with_view.tz b/tests_python/contracts_012/opcodes/create_contract_with_view.tz new file mode 100644 index 000000000000..c8b591e9d3bc --- /dev/null +++ b/tests_python/contracts_012/opcodes/create_contract_with_view.tz @@ -0,0 +1,17 @@ +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 unit ; + storage unit ; + code + { CDR; + NIL operation; + PAIR; } ; + view "const" nat nat { CAR; } ; + }; + DIP {SOME;NIL operation};CONS ; PAIR} # Ending calling convention stuff + diff --git a/tests_python/contracts_012/opcodes/diff_timestamps.tz b/tests_python/contracts_012/opcodes/diff_timestamps.tz new file mode 100644 index 000000000000..f1991a37a5d2 --- /dev/null +++ b/tests_python/contracts_012/opcodes/diff_timestamps.tz @@ -0,0 +1,3 @@ +parameter (pair timestamp timestamp); +storage int; +code { CAR; DUP; CAR; DIP{CDR}; SUB; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/dig_eq.tz b/tests_python/contracts_012/opcodes/dig_eq.tz new file mode 100644 index 000000000000..aaafc4271fae --- /dev/null +++ b/tests_python/contracts_012/opcodes/dig_eq.tz @@ -0,0 +1,14 @@ +parameter (pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat); +storage unit; +# this contract receives a 17-tuple, unpairs it, reverses the order, reverses it again, and pairs it and verifies that the result is the same as the original tuple. +code { CAR; + DUP; + + UNPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAIR; + DIG 0; DIG 1; DIG 2; DIG 3; DIG 4; DIG 5; DIG 6; DIG 7; DIG 8; DIG 9; DIG 10; DIG 11; DIG 12; DIG 13; DIG 14; DIG 15; DIG 16; + # PUSH nat 1; ADD; + DIG 0; DIG 1; DIG 2; DIG 3; DIG 4; DIG 5; DIG 6; DIG 7; DIG 8; DIG 9; DIG 10; DIG 11; DIG 12; DIG 13; DIG 14; DIG 15; DIG 16; + PAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAIR; + ASSERT_CMPEQ; + + UNIT; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dign.tz b/tests_python/contracts_012/opcodes/dign.tz new file mode 100644 index 000000000000..ec8a339dd48c --- /dev/null +++ b/tests_python/contracts_012/opcodes/dign.tz @@ -0,0 +1,3 @@ +parameter (pair (pair (pair (pair nat nat) nat) nat) nat); +storage nat; +code {CAR; UNPAIR ; UNPAIR ; UNPAIR ; UNPAIR ; DIG 4 ; DIP { DROP ; DROP ; DROP ; DROP } ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dip.tz b/tests_python/contracts_012/opcodes/dip.tz new file mode 100644 index 000000000000..f0c32a838747 --- /dev/null +++ b/tests_python/contracts_012/opcodes/dip.tz @@ -0,0 +1,8 @@ +parameter (pair nat nat); +storage (pair nat nat); +code{ + CAR; UNPAIR; + DUP; DIP { ADD }; + PAIR; + NIL operation; + PAIR}; diff --git a/tests_python/contracts_012/opcodes/dipn.tz b/tests_python/contracts_012/opcodes/dipn.tz new file mode 100644 index 000000000000..55d088e5518f --- /dev/null +++ b/tests_python/contracts_012/opcodes/dipn.tz @@ -0,0 +1,3 @@ +parameter (pair (pair (pair (pair nat nat) nat) nat) nat); +storage nat; +code {CAR; UNPAIR ; UNPAIR ; UNPAIR ; UNPAIR ; DIP 5 {PUSH nat 6} ; DROP ; DROP ; DROP ; DROP ; DROP ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dropn.tz b/tests_python/contracts_012/opcodes/dropn.tz new file mode 100644 index 000000000000..4b5379b3a3b3 --- /dev/null +++ b/tests_python/contracts_012/opcodes/dropn.tz @@ -0,0 +1,3 @@ +parameter (pair (pair (pair (pair nat nat) nat) nat) nat); +storage nat; +code {CAR; UNPAIR ; UNPAIR ; UNPAIR ; UNPAIR ; DROP 4 ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dugn.tz b/tests_python/contracts_012/opcodes/dugn.tz new file mode 100644 index 000000000000..521c052f1fcd --- /dev/null +++ b/tests_python/contracts_012/opcodes/dugn.tz @@ -0,0 +1,3 @@ +parameter (pair (pair (pair (pair nat nat) nat) nat) nat); +storage nat; +code {CAR; UNPAIR ; UNPAIR ; UNPAIR ; UNPAIR ; DUG 4 ; DROP ; DROP ; DROP ; DROP ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/dup-n.tz b/tests_python/contracts_012/opcodes/dup-n.tz new file mode 100644 index 000000000000..7e530c0971d0 --- /dev/null +++ b/tests_python/contracts_012/opcodes/dup-n.tz @@ -0,0 +1,18 @@ +parameter unit; +storage unit; +code + { + DROP ; + PUSH nat 5 ; + PUSH nat 4 ; + PUSH nat 3 ; + PUSH nat 2 ; + PUSH nat 1 ; + DUP 1 ; PUSH nat 1 ; ASSERT_CMPEQ ; + DUP 2 ; PUSH nat 2 ; ASSERT_CMPEQ ; + DUP 3 ; PUSH nat 3 ; ASSERT_CMPEQ ; + DUP 4 ; PUSH nat 4 ; ASSERT_CMPEQ ; + DUP 5 ; PUSH nat 5 ; ASSERT_CMPEQ ; + DROP 5 ; + UNIT ; NIL operation ; PAIR ; + }; diff --git a/tests_python/contracts_012/opcodes/ediv.tz b/tests_python/contracts_012/opcodes/ediv.tz new file mode 100644 index 000000000000..a1fc89992a02 --- /dev/null +++ b/tests_python/contracts_012/opcodes/ediv.tz @@ -0,0 +1,13 @@ +parameter (pair int int); +storage (pair (option (pair int nat)) (option (pair int nat)) (option (pair int nat)) (option (pair nat nat))); +code { CAR; + # :: nat : nat : 'S -> option (pair nat nat) : 'S + DUP; UNPAIR; ABS; DIP { ABS; }; EDIV; SWAP; + # :: nat : int : 'S -> option (pair int nat) : 'S + DUP; UNPAIR; ABS; EDIV; SWAP; + # :: int : nat : 'S -> option (pair int nat) : 'S + DUP; UNPAIR; DIP { ABS; }; EDIV; SWAP; + # :: int : int : 'S -> option (pair int nat) : 'S + UNPAIR; EDIV; + PAPAPAIR; + NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/ediv_mutez.tz b/tests_python/contracts_012/opcodes/ediv_mutez.tz new file mode 100644 index 000000000000..2df73dd4a0e3 --- /dev/null +++ b/tests_python/contracts_012/opcodes/ediv_mutez.tz @@ -0,0 +1,12 @@ +parameter (pair mutez (or mutez nat)); +storage (or (option (pair nat mutez)) (option (pair mutez mutez))); +code { CAR; + UNPAIR; + SWAP; + IF_LEFT { + SWAP; EDIV; LEFT (option (pair mutez mutez)); + } + { + SWAP; EDIV; RIGHT (option (pair nat mutez)); + }; + NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/empty_map.tz b/tests_python/contracts_012/opcodes/empty_map.tz new file mode 100644 index 000000000000..9023fe847b3f --- /dev/null +++ b/tests_python/contracts_012/opcodes/empty_map.tz @@ -0,0 +1,6 @@ +storage (map string string); +parameter unit; +code {DROP; + EMPTY_MAP string string; + PUSH string "world"; SOME; PUSH string "hello"; UPDATE; + NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/exec_concat.tz b/tests_python/contracts_012/opcodes/exec_concat.tz new file mode 100644 index 000000000000..0265f1557f0e --- /dev/null +++ b/tests_python/contracts_012/opcodes/exec_concat.tz @@ -0,0 +1,7 @@ +parameter string; +storage string; +code {CAR; + LAMBDA string string + {PUSH string "_abc"; NIL string ; + SWAP ; CONS ; SWAP ; CONS ; CONCAT}; + SWAP; EXEC; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/first.tz b/tests_python/contracts_012/opcodes/first.tz new file mode 100644 index 000000000000..6e47b4c008e8 --- /dev/null +++ b/tests_python/contracts_012/opcodes/first.tz @@ -0,0 +1,3 @@ +parameter (list nat); +storage nat; +code{CAR; IF_CONS {DIP{DROP}} {FAIL}; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/get_and_update_big_map.tz b/tests_python/contracts_012/opcodes/get_and_update_big_map.tz new file mode 100644 index 000000000000..3b39c9a6f733 --- /dev/null +++ b/tests_python/contracts_012/opcodes/get_and_update_big_map.tz @@ -0,0 +1,9 @@ +parameter string; +storage (pair (option nat) (big_map string nat)); +code { + UNPAPAIR; + GET_AND_UPDATE; + PAIR; + NIL operation; + PAIR + } diff --git a/tests_python/contracts_012/opcodes/get_and_update_map.tz b/tests_python/contracts_012/opcodes/get_and_update_map.tz new file mode 100644 index 000000000000..b67f08ce7746 --- /dev/null +++ b/tests_python/contracts_012/opcodes/get_and_update_map.tz @@ -0,0 +1,9 @@ +parameter string; +storage (pair (option nat) (map string nat)); +code { + UNPAPAIR; + GET_AND_UPDATE; + PAIR; + NIL operation; + PAIR + } diff --git a/tests_python/contracts_012/opcodes/get_big_map_value.tz b/tests_python/contracts_012/opcodes/get_big_map_value.tz new file mode 100644 index 000000000000..4ca52343d45a --- /dev/null +++ b/tests_python/contracts_012/opcodes/get_big_map_value.tz @@ -0,0 +1,6 @@ +parameter string; +storage (pair (big_map string string) (option string)); +# retrieves the values stored in the big_map on the left side of the +# pair at the key denoted by the parameter and puts it in the right +# hand side of the storage +code {DUP; CAR; DIP{CDAR; DUP}; GET; SWAP; PAIR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/get_map_value.tz b/tests_python/contracts_012/opcodes/get_map_value.tz new file mode 100644 index 000000000000..f46639649a34 --- /dev/null +++ b/tests_python/contracts_012/opcodes/get_map_value.tz @@ -0,0 +1,3 @@ +parameter string; +storage (pair (option string) (map string string)); +code {DUP; CAR; DIP{CDDR; DUP}; GET; PAIR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/hash_consistency_checker.tz b/tests_python/contracts_012/opcodes/hash_consistency_checker.tz new file mode 100644 index 000000000000..fb98a39da496 --- /dev/null +++ b/tests_python/contracts_012/opcodes/hash_consistency_checker.tz @@ -0,0 +1,3 @@ +parameter (pair mutez (pair timestamp int)) ; +storage bytes ; +code { CAR ; PACK ; BLAKE2B ; NIL operation ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/hash_key.tz b/tests_python/contracts_012/opcodes/hash_key.tz new file mode 100644 index 000000000000..6c7f78b4aaf6 --- /dev/null +++ b/tests_python/contracts_012/opcodes/hash_key.tz @@ -0,0 +1,3 @@ +parameter key; +storage (option key_hash); +code {CAR; HASH_KEY; SOME ;NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/hash_string.tz b/tests_python/contracts_012/opcodes/hash_string.tz new file mode 100644 index 000000000000..b0b8ddea6403 --- /dev/null +++ b/tests_python/contracts_012/opcodes/hash_string.tz @@ -0,0 +1,3 @@ +parameter string; +storage bytes; +code {CAR; PACK ; BLAKE2B; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/if.tz b/tests_python/contracts_012/opcodes/if.tz new file mode 100644 index 000000000000..4bc0e353daeb --- /dev/null +++ b/tests_python/contracts_012/opcodes/if.tz @@ -0,0 +1,3 @@ +parameter bool; +storage (option bool); +code {CAR; IF {PUSH bool True} {PUSH bool False}; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/if_some.tz b/tests_python/contracts_012/opcodes/if_some.tz new file mode 100644 index 000000000000..5c3138b2272b --- /dev/null +++ b/tests_python/contracts_012/opcodes/if_some.tz @@ -0,0 +1,3 @@ +parameter (option string); +storage string; +code { CAR; IF_SOME {} {PUSH string ""}; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/int.tz b/tests_python/contracts_012/opcodes/int.tz new file mode 100644 index 000000000000..3f199881392a --- /dev/null +++ b/tests_python/contracts_012/opcodes/int.tz @@ -0,0 +1,5 @@ +parameter nat; +storage (option int); +# this contract takes a natural number as parameter, converts it to an +# integer and stores it. +code { CAR; INT; SOME; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/iter_fail.tz b/tests_python/contracts_012/opcodes/iter_fail.tz new file mode 100644 index 000000000000..4021e8b57efc --- /dev/null +++ b/tests_python/contracts_012/opcodes/iter_fail.tz @@ -0,0 +1,4 @@ +# Test that ITER {FAILWITH} is allowed by the typechecker +parameter (set nat); +storage unit; +code { UNPAIR; ITER {FAILWITH}; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/keccak.tz b/tests_python/contracts_012/opcodes/keccak.tz new file mode 100644 index 000000000000..e96256100999 --- /dev/null +++ b/tests_python/contracts_012/opcodes/keccak.tz @@ -0,0 +1,8 @@ +storage (option bytes); +parameter bytes; +code + { + CAR; + KECCAK; SOME; + NIL operation; PAIR + } diff --git a/tests_python/contracts_012/opcodes/left_right.tz b/tests_python/contracts_012/opcodes/left_right.tz new file mode 100644 index 000000000000..d5650c03422e --- /dev/null +++ b/tests_python/contracts_012/opcodes/left_right.tz @@ -0,0 +1,3 @@ +parameter (or bool string); +storage (or string bool); +code {CAR; IF_LEFT {RIGHT string} {LEFT bool}; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/level.tz b/tests_python/contracts_012/opcodes/level.tz new file mode 100644 index 000000000000..7e3adb9d05f4 --- /dev/null +++ b/tests_python/contracts_012/opcodes/level.tz @@ -0,0 +1,3 @@ +parameter unit; +storage nat; +code {DROP; LEVEL; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/list_concat.tz b/tests_python/contracts_012/opcodes/list_concat.tz new file mode 100644 index 000000000000..d7bfb7d134ea --- /dev/null +++ b/tests_python/contracts_012/opcodes/list_concat.tz @@ -0,0 +1,3 @@ +parameter (list string); +storage string; +code { UNPAIR ; SWAP ; CONS ; CONCAT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_concat_bytes.tz b/tests_python/contracts_012/opcodes/list_concat_bytes.tz new file mode 100644 index 000000000000..0fc8e1620669 --- /dev/null +++ b/tests_python/contracts_012/opcodes/list_concat_bytes.tz @@ -0,0 +1,3 @@ +parameter (list bytes); +storage bytes; +code { UNPAIR ; SWAP ; CONS ; CONCAT; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_id.tz b/tests_python/contracts_012/opcodes/list_id.tz new file mode 100644 index 000000000000..6cd3693a1e14 --- /dev/null +++ b/tests_python/contracts_012/opcodes/list_id.tz @@ -0,0 +1,3 @@ +parameter (list string); +storage (list string); +code {CAR; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_id_map.tz b/tests_python/contracts_012/opcodes/list_id_map.tz new file mode 100644 index 000000000000..38b4493e8e0f --- /dev/null +++ b/tests_python/contracts_012/opcodes/list_id_map.tz @@ -0,0 +1,3 @@ +parameter (list string); +storage (list string); +code {CAR; MAP {}; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_iter.tz b/tests_python/contracts_012/opcodes/list_iter.tz new file mode 100644 index 000000000000..df904d882234 --- /dev/null +++ b/tests_python/contracts_012/opcodes/list_iter.tz @@ -0,0 +1,5 @@ +parameter (list int); +storage int; +code { CAR; PUSH int 1; SWAP; + ITER { MUL }; + NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/list_map_block.tz b/tests_python/contracts_012/opcodes/list_map_block.tz new file mode 100644 index 000000000000..b5202dd9b6fb --- /dev/null +++ b/tests_python/contracts_012/opcodes/list_map_block.tz @@ -0,0 +1,5 @@ +parameter (list int); +storage (list int); +code { CAR; PUSH int 0; SWAP; + MAP { DIP{DUP}; ADD; DIP{PUSH int 1; ADD}}; + NIL operation; PAIR; DIP{DROP}} diff --git a/tests_python/contracts_012/opcodes/list_size.tz b/tests_python/contracts_012/opcodes/list_size.tz new file mode 100644 index 000000000000..6ced12799187 --- /dev/null +++ b/tests_python/contracts_012/opcodes/list_size.tz @@ -0,0 +1,3 @@ +parameter (list int); +storage nat; +code {CAR; SIZE; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/loop_failwith.tz b/tests_python/contracts_012/opcodes/loop_failwith.tz new file mode 100644 index 000000000000..f81a552c8ebc --- /dev/null +++ b/tests_python/contracts_012/opcodes/loop_failwith.tz @@ -0,0 +1,4 @@ +# Test that LOOP {FAILWITH} is allowed by the typechecker +parameter bool; +storage unit; +code { UNPAIR; LOOP {FAILWITH}; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/loop_left.tz b/tests_python/contracts_012/opcodes/loop_left.tz new file mode 100644 index 000000000000..64bcc76c89cc --- /dev/null +++ b/tests_python/contracts_012/opcodes/loop_left.tz @@ -0,0 +1,7 @@ +parameter (list string); +storage (list string); +code { CAR; NIL string; SWAP; PAIR; LEFT (list string); + LOOP_LEFT { DUP; CAR; DIP{CDR}; + IF_CONS { SWAP; DIP{CONS}; PAIR; LEFT (list string) } + { RIGHT (pair (list string) (list string)) }; }; + NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/loop_left_failwith.tz b/tests_python/contracts_012/opcodes/loop_left_failwith.tz new file mode 100644 index 000000000000..98971e409511 --- /dev/null +++ b/tests_python/contracts_012/opcodes/loop_left_failwith.tz @@ -0,0 +1,4 @@ +# Test that LOOP_LEFT {FAILWITH} is allowed by the typechecker +parameter (or string nat); +storage nat; +code { CAR; LOOP_LEFT {FAILWITH}; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/map_car.tz b/tests_python/contracts_012/opcodes/map_car.tz new file mode 100644 index 000000000000..b763590ece2c --- /dev/null +++ b/tests_python/contracts_012/opcodes/map_car.tz @@ -0,0 +1,5 @@ +parameter bool; +storage (pair (bool %b) (nat %n)); +code { DUP; CAR; DIP{CDR}; SWAP; + MAP_CAR @new_storage %b { AND }; + NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/map_id.tz b/tests_python/contracts_012/opcodes/map_id.tz new file mode 100644 index 000000000000..ff0a3bbbf213 --- /dev/null +++ b/tests_python/contracts_012/opcodes/map_id.tz @@ -0,0 +1,3 @@ +parameter (map nat nat); +storage (map nat nat); +code { CAR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/map_iter.tz b/tests_python/contracts_012/opcodes/map_iter.tz new file mode 100644 index 000000000000..3ab5c35c73b8 --- /dev/null +++ b/tests_python/contracts_012/opcodes/map_iter.tz @@ -0,0 +1,7 @@ +parameter (map (int :k) (int :e)); +storage (pair (int :k) (int :e)); +code { CAR; PUSH @acc_e (int :e) 0; PUSH @acc_k (int :k) 0; PAIR % %r; SWAP; + ITER + { DIP {DUP; CAR; DIP{CDR}}; DUP; # Last instr + DIP{CAR; ADD}; SWAP; DIP{CDR; ADD}; PAIR % %r }; + NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/map_map.tz b/tests_python/contracts_012/opcodes/map_map.tz new file mode 100644 index 000000000000..4acbd63c32c4 --- /dev/null +++ b/tests_python/contracts_012/opcodes/map_map.tz @@ -0,0 +1,8 @@ +parameter nat; +storage (map string nat); +# this contract adds the value passed by parameter to each entry in +# the stored map. +code { UNPAIR; SWAP; + MAP { CDR; DIP {DUP}; ADD; }; + DIP { DROP; }; + NIL operation; PAIR; } diff --git a/tests_python/contracts_012/opcodes/map_map_sideeffect.tz b/tests_python/contracts_012/opcodes/map_map_sideeffect.tz new file mode 100644 index 000000000000..960b02a553ce --- /dev/null +++ b/tests_python/contracts_012/opcodes/map_map_sideeffect.tz @@ -0,0 +1,12 @@ +parameter nat; +storage (pair (map string nat) nat); +# this contract adds the value passed by parameter to each entry in +# the stored map, and it sets the second component of the pair to the +# sum of the map's elements +code { UNPAIR; SWAP; CAR; + DIP 2 { PUSH @sum nat 0; }; + MAP { CDR; DIP {DUP}; ADD; + DUP; DUG 2; DIP 2 { ADD @sum }; + }; + DIP { DROP; }; PAIR; + NIL operation; PAIR; } diff --git a/tests_python/contracts_012/opcodes/map_mem_nat.tz b/tests_python/contracts_012/opcodes/map_mem_nat.tz new file mode 100644 index 000000000000..0c245d7e0a65 --- /dev/null +++ b/tests_python/contracts_012/opcodes/map_mem_nat.tz @@ -0,0 +1,7 @@ +parameter nat; +storage (pair (map nat nat) (option bool)) ; +# stores (map, Some flag) where flag = parameter is a member of +# the map in first component of storage +code { UNPAIR; + DIP { CAR; DUP }; + MEM; SOME; SWAP; PAIR; NIL operation; PAIR;} diff --git a/tests_python/contracts_012/opcodes/map_mem_string.tz b/tests_python/contracts_012/opcodes/map_mem_string.tz new file mode 100644 index 000000000000..3fa5cd5b579f --- /dev/null +++ b/tests_python/contracts_012/opcodes/map_mem_string.tz @@ -0,0 +1,7 @@ +parameter string; +storage (pair (map string nat) (option bool)) ; +# stores (map, Some flag) where flag = parameter is a member of +# the map in first component of storage +code { UNPAIR; + DIP { CAR; DUP }; + MEM; SOME; SWAP; PAIR; NIL operation; PAIR;} diff --git a/tests_python/contracts_012/opcodes/map_size.tz b/tests_python/contracts_012/opcodes/map_size.tz new file mode 100644 index 000000000000..4bd6417e6d79 --- /dev/null +++ b/tests_python/contracts_012/opcodes/map_size.tz @@ -0,0 +1,3 @@ +parameter (map string nat); +storage nat; +code {CAR; SIZE; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/merge_comparable_pairs.tz b/tests_python/contracts_012/opcodes/merge_comparable_pairs.tz new file mode 100644 index 000000000000..14fcc73411c7 --- /dev/null +++ b/tests_python/contracts_012/opcodes/merge_comparable_pairs.tz @@ -0,0 +1,14 @@ +# tests that merging comparable pair types works +parameter (set (pair (nat %n) (pair %p (string %s) (int %i)))); +storage nat; +code {UNPAIR; + SWAP; + PUSH nat 3; + COMPARE; + GT; + IF {} + {DROP; + EMPTY_SET (pair nat (pair string int));}; + SIZE; + NIL operation; + PAIR;} diff --git a/tests_python/contracts_012/opcodes/mul.tz b/tests_python/contracts_012/opcodes/mul.tz new file mode 100644 index 000000000000..8432394b526d --- /dev/null +++ b/tests_python/contracts_012/opcodes/mul.tz @@ -0,0 +1,48 @@ +parameter unit ; +storage unit ; +code { CAR ; + DROP ; + # tez-nat, no overflow + PUSH nat 7987 ; + PUSH mutez 10 ; + MUL ; + PUSH mutez 79870 ; + COMPARE ; + ASSERT_EQ ; + # nat-tez, no overflow + PUSH mutez 10 ; + PUSH nat 7987 ; + MUL ; + PUSH mutez 79870 ; + COMPARE ; + ASSERT_EQ ; + # int-int, no overflow + PUSH int 10 ; + PUSH int -7987 ; + MUL ; + PUSH int -79870 ; + COMPARE ; + ASSERT_EQ ; + # int-nat, no overflow + PUSH nat 10 ; + PUSH int -7987 ; + MUL ; + PUSH int -79870 ; + COMPARE ; + ASSERT_EQ ; + # nat-int, no overflow + PUSH int -10 ; + PUSH nat 7987 ; + MUL ; + PUSH int -79870 ; + COMPARE ; + ASSERT_EQ ; + # nat-nat, no overflow + PUSH nat 10 ; + PUSH nat 7987 ; + MUL ; + PUSH nat 79870 ; + COMPARE ; + ASSERT_EQ ; + + UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/mul_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/mul_bls12_381_fr.tz new file mode 100644 index 000000000000..dd201863b034 --- /dev/null +++ b/tests_python/contracts_012/opcodes/mul_bls12_381_fr.tz @@ -0,0 +1,3 @@ +parameter (pair bls12_381_fr bls12_381_fr); +storage (option (bls12_381_fr)); +code {CAR; UNPAIR; MUL; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/mul_bls12_381_g1.tz b/tests_python/contracts_012/opcodes/mul_bls12_381_g1.tz new file mode 100644 index 000000000000..af3f376501da --- /dev/null +++ b/tests_python/contracts_012/opcodes/mul_bls12_381_g1.tz @@ -0,0 +1,3 @@ +parameter (pair bls12_381_g1 bls12_381_fr); +storage (option (bls12_381_g1)); +code {CAR; UNPAIR; MUL; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/mul_bls12_381_g2.tz b/tests_python/contracts_012/opcodes/mul_bls12_381_g2.tz new file mode 100644 index 000000000000..1875e8e3dac8 --- /dev/null +++ b/tests_python/contracts_012/opcodes/mul_bls12_381_g2.tz @@ -0,0 +1,3 @@ +parameter (pair bls12_381_g2 bls12_381_fr); +storage (option (bls12_381_g2)); +code {CAR; UNPAIR; MUL; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/mul_overflow.tz b/tests_python/contracts_012/opcodes/mul_overflow.tz new file mode 100644 index 000000000000..5d2b3a3dcff2 --- /dev/null +++ b/tests_python/contracts_012/opcodes/mul_overflow.tz @@ -0,0 +1,18 @@ +parameter (or unit unit) ; +storage unit ; +code { CAR ; + IF_LEFT + { + PUSH nat 922337203685477580700 ; + PUSH mutez 10 ; + MUL ; # FAILURE + DROP + } + { + PUSH mutez 10 ; + PUSH nat 922337203685477580700 ; + MUL ; # FAILURE + DROP + } ; + + NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/munch.tz b/tests_python/contracts_012/opcodes/munch.tz new file mode 100644 index 000000000000..7efe43ca092d --- /dev/null +++ b/tests_python/contracts_012/opcodes/munch.tz @@ -0,0 +1,14 @@ +# A contract that accepts bytes in a default entry point and does nothing. +# Useful for testing transfers of arbitrary sizes. +parameter (or (bytes %bytes) + (or (lambda %lambda unit unit) + (or (nat %nat) + (list %list_nat nat)))); +storage unit; +code + { + CDR; # @storage + # == default == # @storage + NIL operation; # list operation : @storage + PAIR; # pair (list operation) @storage + }; diff --git a/tests_python/contracts_012/opcodes/mutez_to_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/mutez_to_bls12_381_fr.tz new file mode 100644 index 000000000000..fefc038474da --- /dev/null +++ b/tests_python/contracts_012/opcodes/mutez_to_bls12_381_fr.tz @@ -0,0 +1,14 @@ +parameter mutez; +storage bls12_381_fr; +code { + CAR; + PUSH mutez 1; + SWAP; + EDIV; + ASSERT_SOME; + CAR; + PUSH bls12_381_fr 1; + MUL; + NIL operation; + PAIR; + }; \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/neg.tz b/tests_python/contracts_012/opcodes/neg.tz new file mode 100644 index 000000000000..9cedf765f1b2 --- /dev/null +++ b/tests_python/contracts_012/opcodes/neg.tz @@ -0,0 +1,8 @@ +parameter (or int nat); +storage int; +code { + CAR; + IF_LEFT {NEG} {NEG}; + NIL operation; + PAIR + } diff --git a/tests_python/contracts_012/opcodes/neg_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/neg_bls12_381_fr.tz new file mode 100644 index 000000000000..cd9b0a945cc5 --- /dev/null +++ b/tests_python/contracts_012/opcodes/neg_bls12_381_fr.tz @@ -0,0 +1,3 @@ +parameter bls12_381_fr; +storage (option (bls12_381_fr)); +code {CAR; NEG; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/neg_bls12_381_g1.tz b/tests_python/contracts_012/opcodes/neg_bls12_381_g1.tz new file mode 100644 index 000000000000..60806deada20 --- /dev/null +++ b/tests_python/contracts_012/opcodes/neg_bls12_381_g1.tz @@ -0,0 +1,3 @@ +parameter bls12_381_g1; +storage (option (bls12_381_g1)); +code {CAR; NEG; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/neg_bls12_381_g2.tz b/tests_python/contracts_012/opcodes/neg_bls12_381_g2.tz new file mode 100644 index 000000000000..593052546258 --- /dev/null +++ b/tests_python/contracts_012/opcodes/neg_bls12_381_g2.tz @@ -0,0 +1,3 @@ +parameter bls12_381_g2; +storage (option (bls12_381_g2)); +code {CAR; NEG; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/none.tz b/tests_python/contracts_012/opcodes/none.tz new file mode 100644 index 000000000000..473a288b4926 --- /dev/null +++ b/tests_python/contracts_012/opcodes/none.tz @@ -0,0 +1,3 @@ +parameter unit; +storage (option nat); +code { DROP; NONE nat; NIL operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/noop.tz b/tests_python/contracts_012/opcodes/noop.tz new file mode 100644 index 000000000000..bd19da15cf49 --- /dev/null +++ b/tests_python/contracts_012/opcodes/noop.tz @@ -0,0 +1,3 @@ +parameter unit; +storage unit; +code {CDR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/not.tz b/tests_python/contracts_012/opcodes/not.tz new file mode 100644 index 000000000000..f89394072d2a --- /dev/null +++ b/tests_python/contracts_012/opcodes/not.tz @@ -0,0 +1,3 @@ +parameter bool; +storage (option bool); +code {CAR; NOT; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/not_binary.tz b/tests_python/contracts_012/opcodes/not_binary.tz new file mode 100644 index 000000000000..c1e0f97979d7 --- /dev/null +++ b/tests_python/contracts_012/opcodes/not_binary.tz @@ -0,0 +1,12 @@ +parameter (or int nat); +storage (option int); +code { CAR; + IF_LEFT + { + NOT; + } + { + NOT; + } ; + SOME; NIL operation ; PAIR + } diff --git a/tests_python/contracts_012/opcodes/or.tz b/tests_python/contracts_012/opcodes/or.tz new file mode 100644 index 000000000000..89d533c4483e --- /dev/null +++ b/tests_python/contracts_012/opcodes/or.tz @@ -0,0 +1,3 @@ +parameter (pair bool bool); +storage (option bool); +code {CAR; DUP; CAR; SWAP; CDR; OR; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/or_binary.tz b/tests_python/contracts_012/opcodes/or_binary.tz new file mode 100644 index 000000000000..a31f109827ef --- /dev/null +++ b/tests_python/contracts_012/opcodes/or_binary.tz @@ -0,0 +1,9 @@ +parameter (pair nat nat); +storage (option nat); +# This contract takes a pair of natural numbers as argument and +# stores the result of their binary OR. +code { CAR; + UNPAIR; + OR; + SOME; NIL operation; PAIR + } diff --git a/tests_python/contracts_012/opcodes/originate_big_map.tz b/tests_python/contracts_012/opcodes/originate_big_map.tz new file mode 100644 index 000000000000..97d7db669fe8 --- /dev/null +++ b/tests_python/contracts_012/opcodes/originate_big_map.tz @@ -0,0 +1,3 @@ +parameter (big_map int int); +storage (big_map int int); +code { CAR; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/packunpack.tz b/tests_python/contracts_012/opcodes/packunpack.tz new file mode 100644 index 000000000000..ad313fa8aee6 --- /dev/null +++ b/tests_python/contracts_012/opcodes/packunpack.tz @@ -0,0 +1,6 @@ +parameter (pair (pair (pair string (list int)) (set nat)) bytes) ; +storage unit ; +code { CAR ; UNPAIR ; DIP { DUP } ; + PACK ; ASSERT_CMPEQ ; + UNPACK (pair (pair string (list int)) (set nat)) ; ASSERT_SOME ; DROP ; + UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/packunpack_rev.tz b/tests_python/contracts_012/opcodes/packunpack_rev.tz new file mode 100644 index 000000000000..9c94cd68dcc1 --- /dev/null +++ b/tests_python/contracts_012/opcodes/packunpack_rev.tz @@ -0,0 +1,43 @@ +parameter (pair + int + nat + string + bytes + mutez + bool + key_hash + timestamp address); +storage unit ; +code { CAR; + # Check the int + DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK int; ASSERT_SOME; ASSERT_CMPEQ; + # Check the nat + DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK nat; ASSERT_SOME; ASSERT_CMPEQ; + # Check the string + DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK string; ASSERT_SOME; ASSERT_CMPEQ; + # Check the bytes + DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK bytes; ASSERT_SOME; ASSERT_CMPEQ; + # Check the mutez + DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK mutez; ASSERT_SOME; ASSERT_CMPEQ; + # Check the bool + DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK bool; ASSERT_SOME; ASSERT_CMPEQ; + # Check the key_hash + DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK key_hash; ASSERT_SOME; ASSERT_CMPEQ; + # Check the timestamp + DUP; CAR; DIP { UNPAIR; }; PACK; UNPACK timestamp; ASSERT_SOME; ASSERT_CMPEQ; + # Check the address + DUP; PACK; UNPACK address; ASSERT_SOME; ASSERT_CMPEQ; + + # Assert failure modes of unpack + PUSH int 0; PACK; UNPACK nat; ASSERT_SOME; DROP; + PUSH int -1; PACK; UNPACK nat; ASSERT_NONE; + + # Try deserializing invalid byte sequence (no magic number) + PUSH bytes 0x; UNPACK nat; ASSERT_NONE; + PUSH bytes 0x04; UNPACK nat; ASSERT_NONE; + + # Assert failure for byte sequences that do not correspond to + # any micheline value + PUSH bytes 0x05; UNPACK nat; ASSERT_NONE; + + UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/packunpack_rev_cty.tz b/tests_python/contracts_012/opcodes/packunpack_rev_cty.tz new file mode 100644 index 000000000000..7ca7ca64a3c3 --- /dev/null +++ b/tests_python/contracts_012/opcodes/packunpack_rev_cty.tz @@ -0,0 +1,31 @@ +parameter (pair key unit signature (option signature) (list unit) (set bool) (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes)); +storage unit ; +# for each uncomparable type t (we take an arbitrary parameter for +# parametric data-types e.g. pair, list), +# that is packable (which excludes big_map, operation, and contract) +# this contract receives a parameter v_t. +# it verifies that pack v_t == pack (unpack (pack v_t)) +code { CAR; + # packable uncomparable types + # checking: key + DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK key; ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + # checking: unit + DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK unit; ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + # checking: signature + DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (signature); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + # checking: option signature + DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (option signature); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + # checking: list unit + DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (list unit); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + # checking: set bool + DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (set bool); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + # checking: pair int int + DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (pair int int); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + # checking: or key_hash timestamp + DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (or key_hash timestamp); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + # checking: map int string + DUP; CAR; DIP { UNPAIR; }; PACK; DIP { PACK; UNPACK (map int string); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + # checking: lambda string bytes + DUP; PACK; DIP { PACK; UNPACK (lambda string bytes); ASSERT_SOME; PACK; }; ASSERT_CMPEQ; + + UNIT ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/pair_id.tz b/tests_python/contracts_012/opcodes/pair_id.tz new file mode 100644 index 000000000000..3bfedf2d8cdf --- /dev/null +++ b/tests_python/contracts_012/opcodes/pair_id.tz @@ -0,0 +1,3 @@ +parameter (pair bool bool); +storage (option (pair bool bool)); +code {CAR; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/pairing_check.tz b/tests_python/contracts_012/opcodes/pairing_check.tz new file mode 100644 index 000000000000..3b829f315c05 --- /dev/null +++ b/tests_python/contracts_012/opcodes/pairing_check.tz @@ -0,0 +1,3 @@ +parameter (list (pair bls12_381_g1 bls12_381_g2)); +storage (option bool); +code {CAR; PAIRING_CHECK; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/pexec.tz b/tests_python/contracts_012/opcodes/pexec.tz new file mode 100644 index 000000000000..eab0c71b4f59 --- /dev/null +++ b/tests_python/contracts_012/opcodes/pexec.tz @@ -0,0 +1,6 @@ +parameter nat; +storage nat; +code { + LAMBDA (pair nat nat) nat + {UNPAIR ; ADD}; + SWAP; UNPAIR ; DIP { APPLY } ; EXEC ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/pexec_2.tz b/tests_python/contracts_012/opcodes/pexec_2.tz new file mode 100644 index 000000000000..d64f7442f50e --- /dev/null +++ b/tests_python/contracts_012/opcodes/pexec_2.tz @@ -0,0 +1,11 @@ +parameter int; +storage (list int); +code { + UNPAIR @p @s ; # p :: s + LAMBDA (pair int (pair int int)) int + { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL }; # l :: p :: s + SWAP ; APPLY ; # l :: s + PUSH int 3 ; APPLY ; # l :: s + SWAP ; MAP { DIP { DUP } ; EXEC } ; # s :: l + DIP { DROP } ; # s + NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/proxy.tz b/tests_python/contracts_012/opcodes/proxy.tz new file mode 100644 index 000000000000..185bbcd321cc --- /dev/null +++ b/tests_python/contracts_012/opcodes/proxy.tz @@ -0,0 +1,13 @@ +/* This proxy contract transfers the received amount to the contract given as parameter. + It is used to test the SOURCE and SENDER opcodes; see source.tz and sender.tz. */ +parameter (contract unit) ; +storage unit ; +code{ + UNPAIR; + AMOUNT ; + UNIT ; + TRANSFER_TOKENS; + DIP {NIL operation} ; + CONS; + PAIR + } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/ret_int.tz b/tests_python/contracts_012/opcodes/ret_int.tz new file mode 100644 index 000000000000..720a99568e96 --- /dev/null +++ b/tests_python/contracts_012/opcodes/ret_int.tz @@ -0,0 +1,3 @@ +parameter unit; +storage (option nat); +code {DROP; PUSH nat 300; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/reverse.tz b/tests_python/contracts_012/opcodes/reverse.tz new file mode 100644 index 000000000000..5a851f3e29d0 --- /dev/null +++ b/tests_python/contracts_012/opcodes/reverse.tz @@ -0,0 +1,5 @@ +parameter (list string); +storage (list string); +code { CAR; NIL string; SWAP; + ITER {CONS}; + NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/reverse_loop.tz b/tests_python/contracts_012/opcodes/reverse_loop.tz new file mode 100644 index 000000000000..d8117135c984 --- /dev/null +++ b/tests_python/contracts_012/opcodes/reverse_loop.tz @@ -0,0 +1,5 @@ +parameter (list string); +storage (list string); +code { CAR; NIL string; SWAP; PUSH bool True; + LOOP { IF_CONS {SWAP; DIP{CONS}; PUSH bool True} {NIL string; PUSH bool False}}; + DROP; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/sapling_empty_state.tz b/tests_python/contracts_012/opcodes/sapling_empty_state.tz new file mode 100644 index 000000000000..6a568da92dd3 --- /dev/null +++ b/tests_python/contracts_012/opcodes/sapling_empty_state.tz @@ -0,0 +1,3 @@ +parameter unit; +storage (sapling_state 8); +code { DROP; SAPLING_EMPTY_STATE 8; NIL operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/self.tz b/tests_python/contracts_012/opcodes/self.tz new file mode 100644 index 000000000000..d96457fd1331 --- /dev/null +++ b/tests_python/contracts_012/opcodes/self.tz @@ -0,0 +1,3 @@ +parameter unit ; +storage address ; +code { DROP ; SELF ; ADDRESS ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/self_address.tz b/tests_python/contracts_012/opcodes/self_address.tz new file mode 100644 index 000000000000..73f4779bab24 --- /dev/null +++ b/tests_python/contracts_012/opcodes/self_address.tz @@ -0,0 +1,11 @@ +parameter unit; +storage unit; +code { + DROP; + LAMBDA unit address { DROP; SELF_ADDRESS }; + UNIT; + EXEC; + SELF; ADDRESS; + ASSERT_CMPEQ; + UNIT; NIL operation; PAIR + } diff --git a/tests_python/contracts_012/opcodes/self_address_after_fib_view.tz b/tests_python/contracts_012/opcodes/self_address_after_fib_view.tz new file mode 100644 index 000000000000..0cf80651050a --- /dev/null +++ b/tests_python/contracts_012/opcodes/self_address_after_fib_view.tz @@ -0,0 +1,25 @@ +# This contract calls the view `fib` on the address passed as +# parameter. After returning from the view it stores its +# SELF_ADDRESS. +parameter address ; +storage address ; +code + { CAR ; + DUP ; + PUSH nat 3 ; + VIEW "fib" nat; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 1500 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + SELF_ADDRESS ; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + diff --git a/tests_python/contracts_012/opcodes/self_address_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/self_address_after_nonexistent_view.tz new file mode 100644 index 000000000000..6b174437425c --- /dev/null +++ b/tests_python/contracts_012/opcodes/self_address_after_nonexistent_view.tz @@ -0,0 +1,26 @@ +# This contract calls the non-existent view on the address passed as +# parameter. After returning from the view it stores it's +# SELF_ADDRESS. +parameter address ; +storage address ; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "id" string ; + ASSERT_NONE ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 1500 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + SELF_ADDRESS ; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + + + diff --git a/tests_python/contracts_012/opcodes/self_address_after_view.tz b/tests_python/contracts_012/opcodes/self_address_after_view.tz new file mode 100644 index 000000000000..012c3ce15171 --- /dev/null +++ b/tests_python/contracts_012/opcodes/self_address_after_view.tz @@ -0,0 +1,24 @@ +# This contract calls the view `id` on the address passed as +# parameter. After returning from the view it stores its +# SELF_ADDRESS. +parameter address ; +storage address ; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "id" (pair nat nat) ; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 1500 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + SELF_ADDRESS ; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; diff --git a/tests_python/contracts_012/opcodes/self_after_fib_view.tz b/tests_python/contracts_012/opcodes/self_after_fib_view.tz new file mode 100644 index 000000000000..5bacaeb17673 --- /dev/null +++ b/tests_python/contracts_012/opcodes/self_after_fib_view.tz @@ -0,0 +1,27 @@ +# This contract calls the view `fib` on the address passed as +# parameter. After returning from the view it stores its +# address from SELF. +parameter address ; +storage address ; +code + { CAR ; + DUP ; + PUSH nat 3 ; + VIEW "fib" nat; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 1500 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + SELF ; + ADDRESS ; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + + diff --git a/tests_python/contracts_012/opcodes/self_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/self_after_nonexistent_view.tz new file mode 100644 index 000000000000..74236b85f7f4 --- /dev/null +++ b/tests_python/contracts_012/opcodes/self_after_nonexistent_view.tz @@ -0,0 +1,28 @@ +# This contract calls the non-existent view on the address passed as +# parameter. After returning from the view it stores its +# address from SELF. +parameter address ; +storage address ; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "nonexistent" string ; + ASSERT_NONE ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 1500 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + SELF ; + ADDRESS ; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + + + + diff --git a/tests_python/contracts_012/opcodes/self_after_view.tz b/tests_python/contracts_012/opcodes/self_after_view.tz new file mode 100644 index 000000000000..1dab8f98115d --- /dev/null +++ b/tests_python/contracts_012/opcodes/self_after_view.tz @@ -0,0 +1,26 @@ +# This contract calls the view `id` on the address passed as +# parameter. After returning from the view it stores its +# address from SELF. +parameter address ; +storage address ; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "id" (pair nat nat) ; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 1500 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + SELF ; + ADDRESS ; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + diff --git a/tests_python/contracts_012/opcodes/self_with_default_entrypoint.tz b/tests_python/contracts_012/opcodes/self_with_default_entrypoint.tz new file mode 100644 index 000000000000..47f848c0d5a1 --- /dev/null +++ b/tests_python/contracts_012/opcodes/self_with_default_entrypoint.tz @@ -0,0 +1,19 @@ +parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %default) (string %C))); +storage unit; +code { + DROP; + SELF; DROP; + # Refers to entrypoint A of the current contract. + SELF %A; DROP; + # Refers to the default entry of the current contract + SELF %default; PACK; + # "SELF" w/o annotation also refers to the default + # entry of the current contract. Internally, they are equal. + SELF; PACK; ASSERT_CMPEQ; + # The following instruction would not typecheck: + # SELF %D, + # since there is no entrypoint D. + UNIT; + NIL operation; + PAIR; + } diff --git a/tests_python/contracts_012/opcodes/self_with_entrypoint.tz b/tests_python/contracts_012/opcodes/self_with_entrypoint.tz new file mode 100644 index 000000000000..ea6f8e1898e2 --- /dev/null +++ b/tests_python/contracts_012/opcodes/self_with_entrypoint.tz @@ -0,0 +1,26 @@ +parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))); +storage unit; +code { + DROP; + # Refers to entrypoint A of the current contract. + SELF %A; PACK @Apacked; + # Refers to the default entry of the current contract + SELF %default; PACK @defpacked; DUP; DIP { SWAP }; ASSERT_CMPNEQ; + # "SELF" w/o annotation also refers to the default + # entry of the current contract + SELF; PACK @selfpacked; ASSERT_CMPEQ; + + # Verify the types of the different entrypoints. CAST is noop + # if its argument is convertible with the type of the top of + # the stack. + SELF %A; CAST (contract nat); DROP; + SELF %B; CAST (contract bool); DROP; + SELF %maybe_C; CAST (contract (or (unit) (string))); DROP; + SELF %Z; CAST (contract unit); DROP; + SELF; CAST (contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))); DROP; + SELF %default; CAST (contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))); DROP; + + UNIT; + NIL operation; + PAIR; + } diff --git a/tests_python/contracts_012/opcodes/sender.tz b/tests_python/contracts_012/opcodes/sender.tz new file mode 100644 index 000000000000..fb174179aca5 --- /dev/null +++ b/tests_python/contracts_012/opcodes/sender.tz @@ -0,0 +1,8 @@ +parameter unit ; +storage address ; +code{ + DROP ; + SENDER; + NIL operation ; + PAIR + } diff --git a/tests_python/contracts_012/opcodes/sender_after_fib_view.tz b/tests_python/contracts_012/opcodes/sender_after_fib_view.tz new file mode 100644 index 000000000000..902e1bc8885e --- /dev/null +++ b/tests_python/contracts_012/opcodes/sender_after_fib_view.tz @@ -0,0 +1,26 @@ +# This contract calls the view `fib` on the address passed as +# parameter. After returning from the view it stores its +# SENDER. +parameter address ; +storage address ; +code + { CAR ; + DUP ; + PUSH nat 3 ; + VIEW "fib" nat; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 1500 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + SENDER; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + + diff --git a/tests_python/contracts_012/opcodes/sender_after_nonexistent_view.tz b/tests_python/contracts_012/opcodes/sender_after_nonexistent_view.tz new file mode 100644 index 000000000000..9744af68417f --- /dev/null +++ b/tests_python/contracts_012/opcodes/sender_after_nonexistent_view.tz @@ -0,0 +1,25 @@ +# This contract calls the non-existent view on the address passed as +# parameter. After returning from the view it stores it's +# SENDER. +parameter address ; +storage address ; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "id" string ; + ASSERT_NONE ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 1500 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + SENDER; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + + diff --git a/tests_python/contracts_012/opcodes/sender_after_view.tz b/tests_python/contracts_012/opcodes/sender_after_view.tz new file mode 100644 index 000000000000..b266defa5f3b --- /dev/null +++ b/tests_python/contracts_012/opcodes/sender_after_view.tz @@ -0,0 +1,25 @@ +# This contract calls the view `id` on the address passed as +# parameter. After returning from the view it stores its +# SENDER. +parameter address ; +storage address ; +code + { CAR ; + DUP ; + PUSH nat 0 ; + VIEW "id" (pair nat nat) ; + ASSERT_SOME ; + DROP ; + CONTRACT nat ; + ASSERT_SOME ; + PUSH mutez 1500 ; + PUSH nat 0 ; + TRANSFER_TOKENS ; + SENDER; + SWAP ; + NIL operation ; + SWAP ; + CONS ; + PAIR + } ; + diff --git a/tests_python/contracts_012/opcodes/set_car.tz b/tests_python/contracts_012/opcodes/set_car.tz new file mode 100644 index 000000000000..460b33856743 --- /dev/null +++ b/tests_python/contracts_012/opcodes/set_car.tz @@ -0,0 +1,3 @@ +parameter string; +storage (pair (string %s) (nat %n)); +code { DUP; CDR; DIP{CAR}; SET_CAR %s; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/set_cdr.tz b/tests_python/contracts_012/opcodes/set_cdr.tz new file mode 100644 index 000000000000..d725756bbcaa --- /dev/null +++ b/tests_python/contracts_012/opcodes/set_cdr.tz @@ -0,0 +1,3 @@ +parameter nat; +storage (pair (string %s) (nat %n)); +code { DUP; CDR; DIP{CAR}; SET_CDR %n; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/set_delegate.tz b/tests_python/contracts_012/opcodes/set_delegate.tz new file mode 100644 index 000000000000..a7e051e50494 --- /dev/null +++ b/tests_python/contracts_012/opcodes/set_delegate.tz @@ -0,0 +1,9 @@ +parameter (option key_hash); +storage unit; +code { + UNPAIR; + SET_DELEGATE; + DIP {NIL operation}; + CONS; + PAIR + } diff --git a/tests_python/contracts_012/opcodes/set_id.tz b/tests_python/contracts_012/opcodes/set_id.tz new file mode 100644 index 000000000000..ede301b0e979 --- /dev/null +++ b/tests_python/contracts_012/opcodes/set_id.tz @@ -0,0 +1,3 @@ +parameter (set string); +storage (set string); +code { CAR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/set_iter.tz b/tests_python/contracts_012/opcodes/set_iter.tz new file mode 100644 index 000000000000..55d8ae34aba7 --- /dev/null +++ b/tests_python/contracts_012/opcodes/set_iter.tz @@ -0,0 +1,3 @@ +parameter (set int); +storage int; +code { CAR; PUSH int 0; SWAP; ITER { ADD }; NIL operation; PAIR } diff --git a/tests_python/contracts_012/opcodes/set_member.tz b/tests_python/contracts_012/opcodes/set_member.tz new file mode 100644 index 000000000000..ae97cce14345 --- /dev/null +++ b/tests_python/contracts_012/opcodes/set_member.tz @@ -0,0 +1,3 @@ +parameter string; +storage (pair (set string) (option bool)); +code {DUP; DUP; CAR; DIP{CDAR}; MEM; SOME; DIP {CDAR}; SWAP; PAIR ; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/set_size.tz b/tests_python/contracts_012/opcodes/set_size.tz new file mode 100644 index 000000000000..aa055cb02192 --- /dev/null +++ b/tests_python/contracts_012/opcodes/set_size.tz @@ -0,0 +1,3 @@ +parameter (set int); +storage nat; +code {CAR; SIZE; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/sets.tz b/tests_python/contracts_012/opcodes/sets.tz new file mode 100644 index 000000000000..42873aca228c --- /dev/null +++ b/tests_python/contracts_012/opcodes/sets.tz @@ -0,0 +1,40 @@ +parameter unit; +storage unit; +code + { + DROP; + + # Numerical types + PUSH (set nat) {0; 1; 3}; DROP; + PUSH (set int) {-1 ; 0; 3}; DROP; + PUSH (set mutez) {1; 4; 5; 10; 1923}; DROP; + PUSH + (set timestamp) + {-1; 0; "2017-09-16T08:38:04Z"; "2019-09-16T08:38:05Z"}; + DROP; + + # Booleans + PUSH (set bool) {}; DROP; + PUSH (set bool) {True}; DROP; + PUSH (set bool) {False}; DROP; + PUSH (set bool) {False; True}; DROP; + + # Strings and bytes + PUSH (set string) {""; "A"; "B"; "a"; "aa"; "b"}; DROP; + PUSH (set bytes) {0x; 0x01; 0x02; 0xAABBCC}; DROP; + + # Addresses + PUSH + (set key_hash) + { "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; + "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" }; + DROP; + PUSH + (set address) + { "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; + "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv"; + "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9"}; + DROP; + + UNIT; NIL operation; PAIR; + } diff --git a/tests_python/contracts_012/opcodes/sha3.tz b/tests_python/contracts_012/opcodes/sha3.tz new file mode 100644 index 000000000000..3ce8cde000e3 --- /dev/null +++ b/tests_python/contracts_012/opcodes/sha3.tz @@ -0,0 +1,8 @@ +storage (option bytes); +parameter bytes; +code + { + CAR; + SHA3; SOME; + NIL operation; PAIR + } diff --git a/tests_python/contracts_012/opcodes/shifts.tz b/tests_python/contracts_012/opcodes/shifts.tz new file mode 100644 index 000000000000..71964750c0b8 --- /dev/null +++ b/tests_python/contracts_012/opcodes/shifts.tz @@ -0,0 +1,18 @@ +parameter (or (pair nat nat) (pair nat nat)); +storage (option nat); +# this contract takes either (Left a b) and stores (a << b) +# or (Right a b) and stores (a >> b). +# i.e., in the first case, the first component shifted to the left by +# the second, and the second case, component shifted to the right by +# the second. +code { CAR; + IF_LEFT { + UNPAIR; LSL; + } + { + UNPAIR; LSR; + }; + SOME; + NIL operation; + PAIR; + }; diff --git a/tests_python/contracts_012/opcodes/slice.tz b/tests_python/contracts_012/opcodes/slice.tz new file mode 100644 index 000000000000..3461bb5533d1 --- /dev/null +++ b/tests_python/contracts_012/opcodes/slice.tz @@ -0,0 +1,5 @@ +parameter (pair nat nat); +storage (option string); +code { UNPAIR; SWAP; + IF_SOME {SWAP; UNPAIR; SLICE;} {DROP; NONE string;}; + NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/slice_bytes.tz b/tests_python/contracts_012/opcodes/slice_bytes.tz new file mode 100644 index 000000000000..c0f60f358765 --- /dev/null +++ b/tests_python/contracts_012/opcodes/slice_bytes.tz @@ -0,0 +1,5 @@ +parameter (pair nat nat); +storage (option bytes); +code { UNPAIR; SWAP; + IF_SOME {SWAP; UNPAIR; SLICE;} {DROP; NONE bytes;}; + NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/slices.tz b/tests_python/contracts_012/opcodes/slices.tz new file mode 100644 index 000000000000..fa76827261c0 --- /dev/null +++ b/tests_python/contracts_012/opcodes/slices.tz @@ -0,0 +1,11 @@ +parameter (pair bytes signature) ; +storage key ; +code { DUP ; + CAAR ; DUP ; SIZE ; PUSH nat 128 ; SWAP ; SUB ; ISNAT ; IF_SOME {} { FAIL } ; + PUSH nat 128 ; SLICE @payload ; ASSERT_SOME ; + DUP ; DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; SHA256 ; ASSERT_CMPEQ } ; + DUP ; DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; BLAKE2B ; ASSERT_CMPEQ } ; + DUP ; DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; SHA512 ; ASSERT_CMPEQ } ; + DIP { DUP ; CDR ; DIP { DUP ; CADR }} ; SWAP ; DIP { SWAP } ; CHECK_SIGNATURE ; ASSERT ; + CDR ; DUP ; HASH_KEY ; IMPLICIT_ACCOUNT ; BALANCE ; UNIT ; TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/source.tz b/tests_python/contracts_012/opcodes/source.tz new file mode 100644 index 000000000000..fc3c642027d3 --- /dev/null +++ b/tests_python/contracts_012/opcodes/source.tz @@ -0,0 +1,10 @@ +parameter unit ; + +storage address ; + +code{ + DROP ; + SOURCE; + NIL operation ; + PAIR + } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/split_bytes.tz b/tests_python/contracts_012/opcodes/split_bytes.tz new file mode 100644 index 000000000000..f3b623b3c4b3 --- /dev/null +++ b/tests_python/contracts_012/opcodes/split_bytes.tz @@ -0,0 +1,16 @@ +parameter bytes ; +storage (list bytes) ; +code { UNPAIR ; + DIP { NIL bytes ; SWAP ; ITER { CONS } } ; + DUP ; SIZE ; PUSH nat 0 ; CMPNEQ ; + DIP { PUSH @index nat 0 } ; + LOOP + { PAIR ; DUP ; + DIP { UNPAIR ; DIP { PUSH nat 1 } ; SLICE ; ASSERT_SOME ; CONS @storage } ; + UNPAIR ; + PUSH nat 1 ; ADD @index ; + DUP ; DIP { DIP { DUP } ; SWAP ; SIZE ; CMPNEQ } ; SWAP ; + } ; + DROP ; DROP ; + NIL bytes ; SWAP ; ITER { CONS } ; + NIL operation ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/split_string.tz b/tests_python/contracts_012/opcodes/split_string.tz new file mode 100644 index 000000000000..909ba604742d --- /dev/null +++ b/tests_python/contracts_012/opcodes/split_string.tz @@ -0,0 +1,16 @@ +parameter string ; +storage (list string) ; +code { UNPAIR ; + DIP { NIL string ; SWAP ; ITER { CONS } } ; + DUP ; SIZE ; PUSH nat 0 ; CMPNEQ ; + DIP { PUSH @index nat 0 } ; + LOOP + { PAIR ; DUP ; + DIP { UNPAIR ; DIP { PUSH nat 1 } ; SLICE ; ASSERT_SOME ; CONS @storage } ; + UNPAIR ; + PUSH nat 1 ; ADD @index ; + DUP ; DIP { DIP { DUP } ; SWAP ; SIZE ; CMPNEQ } ; SWAP ; + } ; + DROP ; DROP ; + NIL string ; SWAP ; ITER { CONS } ; + NIL operation ; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/store_bls12_381_fr.tz b/tests_python/contracts_012/opcodes/store_bls12_381_fr.tz new file mode 100644 index 000000000000..b40aa9b4ad1c --- /dev/null +++ b/tests_python/contracts_012/opcodes/store_bls12_381_fr.tz @@ -0,0 +1,3 @@ +parameter bls12_381_fr; +storage (option (bls12_381_fr)); +code {CAR; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/store_bls12_381_g1.tz b/tests_python/contracts_012/opcodes/store_bls12_381_g1.tz new file mode 100644 index 000000000000..1bc148f54282 --- /dev/null +++ b/tests_python/contracts_012/opcodes/store_bls12_381_g1.tz @@ -0,0 +1,3 @@ +parameter bls12_381_g1; +storage (option (bls12_381_g1)); +code {CAR; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/store_bls12_381_g2.tz b/tests_python/contracts_012/opcodes/store_bls12_381_g2.tz new file mode 100644 index 000000000000..b64087706265 --- /dev/null +++ b/tests_python/contracts_012/opcodes/store_bls12_381_g2.tz @@ -0,0 +1,3 @@ +parameter bls12_381_g2; +storage (option (bls12_381_g2)); +code {CAR; SOME; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/store_input.tz b/tests_python/contracts_012/opcodes/store_input.tz new file mode 100644 index 000000000000..4eee565ca2e9 --- /dev/null +++ b/tests_python/contracts_012/opcodes/store_input.tz @@ -0,0 +1,3 @@ +parameter string; +storage string; +code {CAR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/store_now.tz b/tests_python/contracts_012/opcodes/store_now.tz new file mode 100644 index 000000000000..1a868ac06f14 --- /dev/null +++ b/tests_python/contracts_012/opcodes/store_now.tz @@ -0,0 +1,3 @@ +parameter unit; +storage timestamp; +code {DROP; NOW; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/str_id.tz b/tests_python/contracts_012/opcodes/str_id.tz new file mode 100644 index 000000000000..f9e0710c328f --- /dev/null +++ b/tests_python/contracts_012/opcodes/str_id.tz @@ -0,0 +1,3 @@ +parameter string; +storage (option string); +code { CAR ; SOME ; NIL operation ; PAIR }; diff --git a/tests_python/contracts_012/opcodes/sub_timestamp_delta.tz b/tests_python/contracts_012/opcodes/sub_timestamp_delta.tz new file mode 100644 index 000000000000..f154e952414f --- /dev/null +++ b/tests_python/contracts_012/opcodes/sub_timestamp_delta.tz @@ -0,0 +1,3 @@ +parameter (pair timestamp int); +storage timestamp; +code { CAR; DUP; CAR; DIP{CDR}; SUB; NIL operation; PAIR} diff --git a/tests_python/contracts_012/opcodes/subset.tz b/tests_python/contracts_012/opcodes/subset.tz new file mode 100644 index 000000000000..a16ef1695cb2 --- /dev/null +++ b/tests_python/contracts_012/opcodes/subset.tz @@ -0,0 +1,12 @@ +parameter (pair (set string) (set string)); +storage bool; +code { CAR; DUP; CDR; DIP{CAR}; # Unpack lists + PUSH bool True; + PAIR; SWAP; # Setup accumulator + ITER { DIP{ DUP; DUP; CDR; + DIP{CAR; DIP{CDR}}}; + MEM; # Check membership + AND; # Combine accumulator and input + PAIR}; + CAR; # Get the accumulator value + NIL operation; PAIR} # Calling convention diff --git a/tests_python/contracts_012/opcodes/tez_add_sub.tz b/tests_python/contracts_012/opcodes/tez_add_sub.tz new file mode 100644 index 000000000000..990fb2ffac4d --- /dev/null +++ b/tests_python/contracts_012/opcodes/tez_add_sub.tz @@ -0,0 +1,5 @@ +parameter (pair mutez mutez); +storage (option (pair mutez mutez)); +code {CAR; DUP; DUP; CAR; DIP{CDR}; ADD; + DIP{DUP; CAR; DIP{CDR}; SUB_MUTEZ; ASSERT_SOME}; + PAIR; SOME; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/ticket_bad.tz b/tests_python/contracts_012/opcodes/ticket_bad.tz new file mode 100644 index 000000000000..e183ac5278b5 --- /dev/null +++ b/tests_python/contracts_012/opcodes/ticket_bad.tz @@ -0,0 +1,5 @@ +# Although this contract is correctly typed, originating it with a forged +# ticket should be refused +parameter unit; +storage (ticket nat); +code { CDR ; NIL operation ; PAIR } diff --git a/tests_python/contracts_012/opcodes/ticket_big_store.tz b/tests_python/contracts_012/opcodes/ticket_big_store.tz new file mode 100644 index 000000000000..6d1de845235e --- /dev/null +++ b/tests_python/contracts_012/opcodes/ticket_big_store.tz @@ -0,0 +1,3 @@ +parameter nat ; +storage (big_map unit (ticket nat)); +code { UNPAIR ; PUSH nat 1 ; SWAP ; TICKET ; SOME ; UNIT ; UPDATE ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/ticket_join.tz b/tests_python/contracts_012/opcodes/ticket_join.tz new file mode 100644 index 000000000000..3aef469a48c5 --- /dev/null +++ b/tests_python/contracts_012/opcodes/ticket_join.tz @@ -0,0 +1,7 @@ +parameter (ticket nat); +storage (option (ticket nat)); +code { UNPAIR ; SWAP ; + IF_NONE {} { PAIR ; JOIN_TICKETS ; ASSERT_SOME } ; + SOME ; + NIL operation ; + PAIR } diff --git a/tests_python/contracts_012/opcodes/ticket_read.tz b/tests_python/contracts_012/opcodes/ticket_read.tz new file mode 100644 index 000000000000..c41176a5fee0 --- /dev/null +++ b/tests_python/contracts_012/opcodes/ticket_read.tz @@ -0,0 +1,8 @@ +parameter (ticket nat); +storage address; +code { CAR ; + READ_TICKET ; DIP { DROP } ; UNPAIR ; DIP { UNPAIR } ; + DIIP { PUSH nat 1 ; ASSERT_CMPEQ } ; + DIP { PUSH nat 42 ; ASSERT_CMPEQ } ; + NIL operation ; + PAIR } diff --git a/tests_python/contracts_012/opcodes/ticket_split.tz b/tests_python/contracts_012/opcodes/ticket_split.tz new file mode 100644 index 000000000000..a2587beb717e --- /dev/null +++ b/tests_python/contracts_012/opcodes/ticket_split.tz @@ -0,0 +1,11 @@ +parameter (ticket nat) ; +storage unit; +code + { CAR ; + PUSH (pair nat nat) (Pair 1 2) ; SWAP; + SPLIT_TICKET; ASSERT_SOME; UNPAIR; + READ_TICKET; CDDR; PUSH nat 1; ASSERT_CMPEQ; + DROP; + READ_TICKET; CDDR; PUSH nat 2; ASSERT_CMPEQ; + DROP; + UNIT ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/ticket_store-2.tz b/tests_python/contracts_012/opcodes/ticket_store-2.tz new file mode 100644 index 000000000000..cab3dd79d012 --- /dev/null +++ b/tests_python/contracts_012/opcodes/ticket_store-2.tz @@ -0,0 +1,3 @@ +parameter (option (ticket nat)) ; +storage (option (ticket nat)); +code { CAR ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/ticket_store.tz b/tests_python/contracts_012/opcodes/ticket_store.tz new file mode 100644 index 000000000000..926a04aa1e88 --- /dev/null +++ b/tests_python/contracts_012/opcodes/ticket_store.tz @@ -0,0 +1,3 @@ +parameter (ticket nat) ; +storage (option (ticket nat)); +code { CAR ; SOME ; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/ticketer-2.tz b/tests_python/contracts_012/opcodes/ticketer-2.tz new file mode 100644 index 000000000000..bce940ccabe2 --- /dev/null +++ b/tests_python/contracts_012/opcodes/ticketer-2.tz @@ -0,0 +1,9 @@ +parameter (pair (pair address nat) nat) ; +storage unit; +code { CAR ; UNPAIR ; UNPAIR ; + CONTRACT (ticket nat) ; ASSERT_SOME ; + DIP { TICKET } ; + SWAP ; DIP { PUSH mutez 0 } ; + TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; + UNIT ; SWAP ; PAIR } diff --git a/tests_python/contracts_012/opcodes/ticketer.tz b/tests_python/contracts_012/opcodes/ticketer.tz new file mode 100644 index 000000000000..c8ec4565398a --- /dev/null +++ b/tests_python/contracts_012/opcodes/ticketer.tz @@ -0,0 +1,10 @@ +parameter address; +storage nat; +code { UNPAIR ; DIP { DUP } ; + SWAP ; + PUSH nat 1 ; SWAP ; + TICKET ; + DIP { CONTRACT (ticket nat) ; ASSERT_SOME ; PUSH mutez 0 } ; + TRANSFER_TOKENS ; + NIL operation ; SWAP ; CONS ; + PAIR } diff --git a/tests_python/contracts_012/opcodes/transfer_amount.tz b/tests_python/contracts_012/opcodes/transfer_amount.tz new file mode 100644 index 000000000000..973c64f04dcc --- /dev/null +++ b/tests_python/contracts_012/opcodes/transfer_amount.tz @@ -0,0 +1,3 @@ +parameter unit; +storage mutez; +code { DROP; AMOUNT; NIL operation; PAIR }; diff --git a/tests_python/contracts_012/opcodes/transfer_tokens.tz b/tests_python/contracts_012/opcodes/transfer_tokens.tz new file mode 100644 index 000000000000..599b4dae180f --- /dev/null +++ b/tests_python/contracts_012/opcodes/transfer_tokens.tz @@ -0,0 +1,5 @@ +parameter (contract unit); +storage unit; +code { CAR; DIP{UNIT}; PUSH mutez 100000000; UNIT; + TRANSFER_TOKENS; + NIL operation; SWAP; CONS; PAIR}; diff --git a/tests_python/contracts_012/opcodes/uncomb.tz b/tests_python/contracts_012/opcodes/uncomb.tz new file mode 100644 index 000000000000..84c3ced7ca9c --- /dev/null +++ b/tests_python/contracts_012/opcodes/uncomb.tz @@ -0,0 +1,8 @@ +parameter (pair nat nat nat); +storage nat; +code { CAR ; + UNPAIR 3 ; + PUSH nat 100 ; MUL ; + SWAP ; PUSH nat 10 ; MUL ; + ADD ; ADD ; + NIL operation ; PAIR ; } diff --git a/tests_python/contracts_012/opcodes/unpair.tz b/tests_python/contracts_012/opcodes/unpair.tz new file mode 100644 index 000000000000..b45f30a03d38 --- /dev/null +++ b/tests_python/contracts_012/opcodes/unpair.tz @@ -0,0 +1,71 @@ +parameter (unit :param_unit); +storage (unit :u1); +code { DROP ; + + # No annotation + UNIT; UNIT; PAIR; UNPAIR; DROP 2; + + # Variable annotations are overriden by UNPAIR + UNIT @b; UNIT @a; PAIR; UNPAIR @c @d; DROP 2; + + UNIT @b; UNIT @a; PAIR %@ %@; + DUP; UNPAIR %a %b; DROP 2; + DUP; UNPAIR % %b; DROP 2; + DUP; UNPAIR %a %; DROP 2; + DUP; UNPAIR % %; DROP 2; + DUP; UNPAIR %a; DROP 2; + DUP; UNPAIR %; DROP 2; + DUP; UNPAIR; DROP 2; + DUP; UNPAIR %a %b @a @b; DROP 2; + DUP; UNPAIR @a @b %a %b; DROP 2; + DUP; UNPAIR @a @% %a %b; DROP 2; + DUP; UNPAIR @% @% %a %b; DROP 2; + DUP; UNPAIR @% @b %a %b; DROP 2; + DROP; + + # Same test with non-matching field and variable annotations + UNIT @d; UNIT @c; PAIR %a %b; + DUP; UNPAIR %a %b; DROP 2; + DUP; UNPAIR % %b; DROP 2; + DUP; UNPAIR %a %; DROP 2; + DUP; UNPAIR % %; DROP 2; + DUP; UNPAIR %a; DROP 2; + DUP; UNPAIR %; DROP 2; + DUP; UNPAIR; DROP 2; + DUP; UNPAIR %a %b @a @b; DROP 2; + DUP; UNPAIR @a @b %a %b; DROP 2; + DUP; UNPAIR @a @% %a %b; DROP 2; + DUP; UNPAIR @% @% %a %b; DROP 2; + DUP; UNPAIR @% @b %a %b; DROP 2; + DROP; + + # Same tests without the variable annotations in input + UNIT; UNIT; PAIR %a %b; + DUP; UNPAIR %a %b; DROP 2; + DUP; UNPAIR % %b; DROP 2; + DUP; UNPAIR %a %; DROP 2; + DUP; UNPAIR % %; DROP 2; + DUP; UNPAIR %a; DROP 2; + DUP; UNPAIR %; DROP 2; + DUP; UNPAIR; DROP 2; + DUP; UNPAIR %a %b @a @b; DROP 2; + DUP; UNPAIR @a @b %a %b; DROP 2; + DUP; UNPAIR @a @% %a %b; DROP 2; + DUP; UNPAIR @% @% %a %b; DROP 2; + DUP; UNPAIR @% @b %a %b; DROP 2; + DROP; + + # Tests for @%% + UNIT; UNIT; PAIR %a %b @p; + DUP; UNPAIR @%% @b; DROP 2; + DUP; UNPAIR @a @%%; DROP 2; + DUP; UNPAIR @%% @%%; DROP 2; + DUP; UNPAIR @% @%%; DROP 2; + DUP; UNPAIR @%% @%; DROP 2; + DROP; + + # Swapping variable annotations + UNIT @b; UNIT @a; PAIR @c; UNPAIR @b @a; DROP 2; + + # End of test + UNIT; NIL operation; PAIR } \ No newline at end of file diff --git a/tests_python/contracts_012/opcodes/update_big_map.tz b/tests_python/contracts_012/opcodes/update_big_map.tz new file mode 100644 index 000000000000..c403975a38fb --- /dev/null +++ b/tests_python/contracts_012/opcodes/update_big_map.tz @@ -0,0 +1,6 @@ +storage (pair (big_map string string) unit); +parameter (map string (option string)); +# this contract the stored big_map according to the map taken in parameter +code { UNPAPAIR; + ITER { UNPAIR; UPDATE; } ; + PAIR; NIL operation; PAIR}; diff --git a/tests_python/contracts_012/opcodes/utxo_read.tz b/tests_python/contracts_012/opcodes/utxo_read.tz new file mode 100644 index 000000000000..aec29b79730b --- /dev/null +++ b/tests_python/contracts_012/opcodes/utxo_read.tz @@ -0,0 +1,9 @@ +parameter (pair (ticket nat) nat); +storage address; +code { CAR ; + UNPAIR ; + READ_TICKET ; DIP { DROP } ; UNPAIR ; DIP { UNPAIR } ; + DIIP { ASSERT_CMPEQ } ; + DIP { PUSH nat 42 ; ASSERT_CMPEQ } ; + NIL operation ; + PAIR } diff --git a/tests_python/contracts_012/opcodes/utxor.tz b/tests_python/contracts_012/opcodes/utxor.tz new file mode 100644 index 000000000000..81d9632d35d2 --- /dev/null +++ b/tests_python/contracts_012/opcodes/utxor.tz @@ -0,0 +1,24 @@ +parameter (pair address address); +storage nat; +code { UNPAIR ; DIP { DUP } ; + SWAP ; + PUSH nat 5 ; SWAP ; + TICKET ; + PUSH nat 2 ; PUSH nat 3 ; PAIR ; + SWAP ; + SPLIT_TICKET ; + ASSERT_SOME ; + UNPAIR ; + DIP { DIP { DUP ; CAR ; + CONTRACT (pair (ticket nat) nat) ; ASSERT_SOME ; + PUSH mutez 0 } ; + PUSH nat 2 ; SWAP ; PAIR ; } ; + DIP { TRANSFER_TOKENS } ; + SWAP ; + DIP { DIP { CDR ; + CONTRACT (pair (ticket nat) nat) ; ASSERT_SOME ; + PUSH mutez 0 } ; + PUSH nat 3 ; SWAP ; PAIR ; } ; + DIP { TRANSFER_TOKENS } ; + NIL operation ; SWAP ; CONS ; SWAP ; CONS ; + PAIR } diff --git a/tests_python/contracts_012/opcodes/view_fib.tz b/tests_python/contracts_012/opcodes/view_fib.tz new file mode 100644 index 000000000000..1b44288dd4a1 --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_fib.tz @@ -0,0 +1,9 @@ +parameter (pair nat address) ; +storage nat; +code { + CAR; + UNPAIR; + VIEW "fib" nat; + IF_SOME {NIL operation ; PAIR;} { FAIL } + } + diff --git a/tests_python/contracts_012/opcodes/view_mutual_recursion.tz b/tests_python/contracts_012/opcodes/view_mutual_recursion.tz new file mode 100644 index 000000000000..9446a195b6e7 --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_mutual_recursion.tz @@ -0,0 +1,11 @@ +parameter (pair nat address) ; +storage nat; +code { + CAR; + DUP; + CDR; + SWAP; + VIEW "is_twenty" nat; + IF_SOME {NIL operation ; PAIR;} { FAIL } + } + diff --git a/tests_python/contracts_012/opcodes/view_op_add.tz b/tests_python/contracts_012/opcodes/view_op_add.tz new file mode 100644 index 000000000000..e0c611cd3e8c --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_op_add.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage nat ; +code { CAR ; UNPAIR ; VIEW "add" nat ; IF_SOME { } { FAIL }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_constant.tz b/tests_python/contracts_012/opcodes/view_op_constant.tz new file mode 100644 index 000000000000..5fc8b427884a --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_op_constant.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage nat; +code { CAR ; UNPAIR ; VIEW "const" nat ; IF_SOME { } { FAIL }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_id.tz b/tests_python/contracts_012/opcodes/view_op_id.tz new file mode 100644 index 000000000000..7eb267bda064 --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_op_id.tz @@ -0,0 +1,4 @@ +parameter (pair nat address) ; +storage (pair nat nat) ; +code { CAR ; UNPAIR ; VIEW "id" (pair nat nat) ; IF_SOME { } { FAIL }; NIL operation ; PAIR } ; + diff --git a/tests_python/contracts_012/opcodes/view_op_nonexistent_addr.tz b/tests_python/contracts_012/opcodes/view_op_nonexistent_addr.tz new file mode 100644 index 000000000000..f6947732e00e --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_op_nonexistent_addr.tz @@ -0,0 +1,5 @@ +parameter (pair nat address) ; +storage bool ; +code { DROP; PUSH address "tz1SuakBpFdG9b4twyfrSMqZzruxhpMeSrE5"; PUSH nat 0; + VIEW "test" bool; IF_SOME { DROP ; PUSH bool True } { PUSH bool False } ; + NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_nonexistent_func.tz b/tests_python/contracts_012/opcodes/view_op_nonexistent_func.tz new file mode 100644 index 000000000000..ca8ae6be4d34 --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_op_nonexistent_func.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage bool ; +code { CAR ; UNPAIR ; VIEW "not_exist" bool ; IF_SOME { DROP; PUSH bool True } { PUSH bool False }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_test_step_contants.tz b/tests_python/contracts_012/opcodes/view_op_test_step_contants.tz new file mode 100644 index 000000000000..42106d2a6087 --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_op_test_step_contants.tz @@ -0,0 +1,8 @@ +parameter address ; +storage (option (pair (pair mutez mutez) (pair (pair address address) address ))); +code { CAR ; + UNIT; + VIEW "step_constants" (pair (pair mutez mutez) (pair (pair address address) address )) ; + NIL operation ; + PAIR } ; + diff --git a/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_input_type.tz b/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_input_type.tz new file mode 100644 index 000000000000..d99353ace3d9 --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_input_type.tz @@ -0,0 +1,3 @@ +parameter (pair int address) ; +storage nat; +code { CAR ; UNPAIR ; VIEW "add" nat ; IF_SOME { DROP ; PUSH nat 1 } { PUSH nat 0 }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_output_type.tz b/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_output_type.tz new file mode 100644 index 000000000000..258cf616793c --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_op_toplevel_inconsistent_output_type.tz @@ -0,0 +1,3 @@ +parameter (pair nat address) ; +storage bool; +code { CAR ; UNPAIR ; VIEW "add" bool; IF_SOME { DROP ; PUSH bool True} { PUSH bool False }; NIL operation ; PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_rec.tz b/tests_python/contracts_012/opcodes/view_rec.tz new file mode 100644 index 000000000000..490c72d29498 --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_rec.tz @@ -0,0 +1,12 @@ +parameter unit ; +storage unit ; +view "loop" address never { CAR; DUP; VIEW "loop" never; ASSERT_SOME } ; +code { CDR ; + SELF ; + ADDRESS ; + DUP ; + VIEW "loop" never ; + ASSERT_SOME ; + DROP ; + NIL operation ; + PAIR } ; diff --git a/tests_python/contracts_012/opcodes/view_toplevel_lib.tz b/tests_python/contracts_012/opcodes/view_toplevel_lib.tz new file mode 100644 index 000000000000..1810a8a8ec4c --- /dev/null +++ b/tests_python/contracts_012/opcodes/view_toplevel_lib.tz @@ -0,0 +1,67 @@ +parameter nat ; +storage nat ; +code { CAR ; NIL operation ; PAIR } ; +view "add" nat nat { UNPAIR ; ADD } ; +view "id" nat (pair nat nat) { } ; +view "test_failwith" nat (pair nat nat) { FAILWITH } ; +view "step_constants" unit (pair (pair mutez mutez) (pair (pair address address) address )) + { DROP ; + SOURCE; + SENDER; + SELF_ADDRESS; + PAIR; + PAIR; + BALANCE; + AMOUNT; + PAIR; + PAIR; + } ; + +view "succ" (pair nat address) nat + { CAR; + UNPAIR; + PUSH nat 1; ADD; + PAIR; + DUP; CDR; SWAP; + VIEW "is_twenty" nat; ASSERT_SOME; + } ; +view "is_twenty" (pair nat address) nat + { + CAR; + DUP; + CAR; + PUSH nat 20 ; + COMPARE; + EQ ; + IF { CAR; } + { DUP; CDR; SWAP; VIEW "succ" nat; ASSERT_SOME } + } ; +view "fib" nat nat + { + CAR; + DUP; + PUSH nat 0 ; + COMPARE ; + EQ ; + IF { } + { DUP; + PUSH nat 1; + COMPARE; + EQ; + IF { } + { DUP; + PUSH nat 1; SWAP; SUB; ABS; + SELF_ADDRESS; + SWAP; + VIEW "fib" nat; + IF_SOME { SWAP; + PUSH nat 2; SWAP; SUB; ABS; + SELF_ADDRESS; + SWAP; + VIEW "fib" nat; + IF_SOME { ADD; } { FAIL } + } + { FAIL }; + } + } + } diff --git a/tests_python/contracts_012/opcodes/voting_power.tz b/tests_python/contracts_012/opcodes/voting_power.tz new file mode 100644 index 000000000000..741bb196788d --- /dev/null +++ b/tests_python/contracts_012/opcodes/voting_power.tz @@ -0,0 +1,7 @@ +parameter key; # A public key +storage (pair nat nat); +code { CAR; + HASH_KEY; VOTING_POWER; # Get the number of rolls for the key + DIP { TOTAL_VOTING_POWER }; # Get the total number of rolls + PAIR; + NIL operation; PAIR; }; diff --git a/tests_python/contracts_012/opcodes/xor.tz b/tests_python/contracts_012/opcodes/xor.tz new file mode 100644 index 000000000000..557eaa642b9a --- /dev/null +++ b/tests_python/contracts_012/opcodes/xor.tz @@ -0,0 +1,13 @@ +parameter (or (pair bool bool) (pair nat nat)); +storage (option (or bool nat)); +code { + CAR; + IF_LEFT + { + UNPAIR; XOR; LEFT nat + } + { + UNPAIR; XOR; RIGHT bool + } ; + SOME; NIL operation ; PAIR + } diff --git a/tests_python/tests_012/__init__.py b/tests_python/tests_012/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize.out new file mode 100644 index 000000000000..4608b96a4e43 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize.out @@ -0,0 +1,8 @@ +tests_012/test_contract.py::TestNormalize::test_normalize + +{ Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } +{ Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } +{ { 0 ; 3 ; 6 ; 9 } ; { 1 ; 4 ; 7 ; 10 } ; { 2 ; 5 ; 8 ; 11 } } +{ Pair 0 (Pair 3 (Pair 6 9)) ; + Pair 1 (Pair 4 (Pair 7 10)) ; + Pair 2 (Pair 5 (Pair 8 11)) } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_legacy_flag.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_legacy_flag.out new file mode 100644 index 000000000000..272b3a5969d1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_legacy_flag.out @@ -0,0 +1,8 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_legacy_flag + +{ Elt 0 1 } +At (unshown) location 0, value { Elt %a 0 1 } +is invalid for type map nat nat. +At (unshown) location 1, unexpected annotation. +Fatal error: + ill-typed data expression diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[None].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[None].out new file mode 100644 index 000000000000..0c56e660a7a7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[None].out @@ -0,0 +1,10 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_script[None] + +{ parameter unit ; + storage unit ; + code { PUSH (list (pair nat nat nat nat)) + { Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } ; + DROP 2 ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized].out new file mode 100644 index 000000000000..c40d99fcd1e3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized].out @@ -0,0 +1,10 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_script[Optimized] + +{ parameter unit ; + storage unit ; + code { PUSH (list (pair nat nat nat nat)) + { { 0 ; 3 ; 6 ; 9 } ; { 1 ; 4 ; 7 ; 10 } ; { 2 ; 5 ; 8 ; 11 } } ; + DROP 2 ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized_legacy].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized_legacy].out new file mode 100644 index 000000000000..22db8e346804 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Optimized_legacy].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_script[Optimized_legacy] + +{ parameter unit ; + storage unit ; + code { PUSH (list (pair nat nat nat nat)) + { Pair 0 (Pair 3 (Pair 6 9)) ; + Pair 1 (Pair 4 (Pair 7 10)) ; + Pair 2 (Pair 5 (Pair 8 11)) } ; + DROP 2 ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Readable].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Readable].out new file mode 100644 index 000000000000..7a50f118fb80 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_script[Readable].out @@ -0,0 +1,10 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_script[Readable] + +{ parameter unit ; + storage unit ; + code { PUSH (list (pair nat nat nat nat)) + { Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } ; + DROP 2 ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool bytes)].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool bytes)].out new file mode 100644 index 000000000000..f9331cdb9377 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool bytes)].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_type[list (pair nat int bool bytes)] + +list (pair nat (pair int (pair bool bytes))) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool)].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool)].out new file mode 100644 index 000000000000..e2c6bbe429e6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int bool)].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_type[list (pair nat int bool)] + +list (pair nat (pair int bool)) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int)].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int)].out new file mode 100644 index 000000000000..03f2db66141a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list (pair nat int)].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_type[list (pair nat int)] + +list (pair nat int) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list nat].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list nat].out new file mode 100644 index 000000000000..937f616c7483 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[list nat].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_type[list nat] + +list nat diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[nat].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[nat].out new file mode 100644 index 000000000000..71e141ec0cea --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[nat].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_type[nat] + +nat diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool bytes].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool bytes].out new file mode 100644 index 000000000000..87a35a852421 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool bytes].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_type[pair nat int bool bytes] + +pair nat (pair int (pair bool bytes)) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool].out new file mode 100644 index 000000000000..5ba776793aa7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int bool].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_type[pair nat int bool] + +pair nat (pair int bool) diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int].out new file mode 100644 index 000000000000..d91efb117baa --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_type[pair nat int].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_type[pair nat int] + +pair nat int diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[None].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[None].out new file mode 100644 index 000000000000..ff1b2183f03d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[None].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_unparsing_mode[None] + +{ Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized].out new file mode 100644 index 000000000000..446f096a4991 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_unparsing_mode[Optimized] + +{ { 0 ; 3 ; 6 ; 9 } ; { 1 ; 4 ; 7 ; 10 } ; { 2 ; 5 ; 8 ; 11 } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized_legacy].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized_legacy].out new file mode 100644 index 000000000000..8444bb2c028a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Optimized_legacy].out @@ -0,0 +1,5 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_unparsing_mode[Optimized_legacy] + +{ Pair 0 (Pair 3 (Pair 6 9)) ; + Pair 1 (Pair 4 (Pair 7 10)) ; + Pair 2 (Pair 5 (Pair 8 11)) } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Readable].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Readable].out new file mode 100644 index 000000000000..8802fbabac67 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestNormalize::test_normalize_unparsing_mode[Readable].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestNormalize::test_normalize_unparsing_mode[Readable] + +{ Pair 0 3 6 9 ; Pair 1 4 7 10 ; Pair 2 5 8 11 } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out new file mode 100644 index 000000000000..c5299adac0f0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out @@ -0,0 +1,301 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0] + +exprvFK4dJmFGinHHBe92WR4kA7L8WSBQQYDigmyVCyKpiQHCXe9fk [CONTRACT_PATH]/attic/accounts.tz +expruucsMyaSmmP5gmkFWjJfv4a52FQV5EGaf3XpHoeXHQgyJgMJfF [CONTRACT_PATH]/attic/add1.tz +exprvEM4Lvihz6jFYszxazuQQPsHjxA4J54tfLeowwDkY1jjTi8Qft [CONTRACT_PATH]/attic/add1_list.tz +exprta1x6QtexpFktejHoB1KwuMQRXePhgre9rDiJ3GDSZCqb3vtqL [CONTRACT_PATH]/attic/after_strategy.tz +expruEosJCXYteRXxfbAVJ5XythgpVQPMdiu3kbbZj3VAVSVjk8ud7 [CONTRACT_PATH]/attic/always.tz +exprvR9m6PaVeLfPHZjA3A929bbfjonzMJs1Kzcmj8baoEvLct9Ry9 [CONTRACT_PATH]/attic/append.tz +exprvQh7vw7vYfp2qdiyYPCFgd6jVkxqYZimmqoYCGZbqaoMgfLifS [CONTRACT_PATH]/attic/at_least.tz +exprtyZC9vL831BnATCkdrP585F4cEzQQQp1ZqnZSqvCDLqp7S33V1 [CONTRACT_PATH]/attic/auction.tz +expruZ4wjBCm3DQNhEf69L27tqaqAJa1TF34728yyPJ9BUg3sEwcxB [CONTRACT_PATH]/attic/bad_lockup.tz +expruazd13u4uPHS7oFWFeZ5nodWR5QC6nQwgy5LGoUTAR3KXsYPXg [CONTRACT_PATH]/attic/big_map_union.tz +exprv7aEg823PTvrEG5bXr4QGk3XCsEkodhUxWCaMBBSq44ZuAxnNf [CONTRACT_PATH]/attic/cadr_annotation.tz +expruwmej4r1RSMDEmmU4SjWUbrzpURnAwybrSwBaMkHpxVobLkWAe [CONTRACT_PATH]/attic/concat.tz +exprte328K2NmgWrmHLbFrGVjvoZKZNFB7577Vt7cWQa8KdvWbfxYk [CONTRACT_PATH]/attic/conditionals.tz +exprvRVXhJFcFjGMkatDwgaLRcJq4TctY979bjniTqwACgXtC3mWko [CONTRACT_PATH]/attic/cons_twice.tz +exprtcnAL38pt7fyZdCiqd97qcYeESWQStPR6sbN2SxMCfbPJhVjau [CONTRACT_PATH]/attic/cps_fact.tz +exprv9BquR6NXVwKMwD4MS5vdWqqvMzjvWumrBf6NsGQXSfgm2Rtqk [CONTRACT_PATH]/attic/create_add1_lists.tz +exprv4cq5g9hsxWU65zCp8dfUi3RtBzu9rGXZ7otetL23tj1zSkNQ2 [CONTRACT_PATH]/attic/data_publisher.tz +expruavAC89RfrZxSrYwdoA6Wr5ghwdUSns8SNaHcng1JRcqR1dwpR [CONTRACT_PATH]/attic/dispatch.tz +expruat2BS4KCwn9kbopeX1ZwxtrtJbyFhpnpnG6A5KdCBCwHNsdod [CONTRACT_PATH]/attic/empty.tz +exprubD7VQHa8qeqRsFByes3ANZ24mvUnqW3qKAsKVUCncjxYEXtGp [CONTRACT_PATH]/attic/fail_amount.tz +expruYCfXuFoyakdWc3C6Np5ojQrGLDMMN6btVbVEAc97MJzpQYVrm [CONTRACT_PATH]/attic/faucet.tz +expruuvYJkV5YndLNMHFg54yDF1HG6AP4zMsui7RgQBLr6vCZVBVYt [CONTRACT_PATH]/attic/forward.tz +exprv8K6ceBpFH5SFjQm4BRYSLJCHQBFeQU6BFTdvQSRPaPkzdLyAL [CONTRACT_PATH]/attic/id.tz +exprujqMuqia1zKuReMgjumpsn8XAJ5N6RWaoz3kZpLNRUyyQXwrtY [CONTRACT_PATH]/attic/infinite_loop.tz +exprtoE9fvqNeHngkFPopZv412GoqoZ57HgaCi2XFR7YxkwPpvHXBZ [CONTRACT_PATH]/attic/insertion_sort.tz +exprux8tMeArJNXUekbuHqLb6epu2eWXJy85f8Yts5oHASHyWp6bva [CONTRACT_PATH]/attic/int_publisher.tz +expruosSkGQbRDc3NUt5oEqSkt3dqxymQDKDeNxcjRgFNLxARG414v [CONTRACT_PATH]/attic/king_of_tez.tz +exprtZcF9NutGBwyuXTqEi4SyL3bZdAWqzkDc782wxNhYT7LtdY4Lb [CONTRACT_PATH]/attic/list_of_transactions.tz +expruDiMLqyYi67RbkDfNyEjBDgJqQLiCGVx2xLUiWujSkwr7rVyRD [CONTRACT_PATH]/attic/queue.tz +exprtZYeWyxANtdrSANECgXdeakcP9fJm7ecJhpeuGR55a8gDTSXWe [CONTRACT_PATH]/attic/reduce_map.tz +exprvMneQMtBQzcPKboFsEV7R4BAuoF8QLUDMWB62iYLmKz9tztNdJ [CONTRACT_PATH]/attic/reentrancy.tz +exprueaa65wkL9ennP6vZoUP6yCkzz6Wc4cF3w11q8bGXguokXAEvK [CONTRACT_PATH]/attic/reservoir.tz +exprtwrNpVRUJaVTBs5vXFLbt4v6Fb8LRySwc1Ap8ZWZh4JbLfgJ6P [CONTRACT_PATH]/attic/scrutable_reservoir.tz +expruwtkYFMkNLVjKD8hypuDc53SHLQQ65g6VPGiHFXbY5hHwmb552 [CONTRACT_PATH]/attic/spawn_identities.tz +expruiDvGyQG5GzKzcBP7d5Z5doUcdxTmUcM6vL1jCTyTmxLrekmP7 [CONTRACT_PATH]/macros/assert.tz +expruMKaaLoPjYfDaKymizi9fnFY7hSDyPj2NfJFxSuAoEVknDxSM6 [CONTRACT_PATH]/macros/assert_cmpeq.tz +exprtqiRJEnWeqF5KKBRPjamJGoi2oQvekfnRwsdZNRy8w8wkbroKJ [CONTRACT_PATH]/macros/assert_cmpge.tz +exprtZWviL38eegiNAN55KfEtAHhAqUWoadkbxyFCGs3vDnDRzueft [CONTRACT_PATH]/macros/assert_cmpgt.tz +exprvBWTmSLBAGgcuBFSToCQPqH5J1F5R2vf8iJMiPVdZjG3B7hWq7 [CONTRACT_PATH]/macros/assert_cmple.tz +expruuDzygKxAaQ348e6BcRSk8A2Chq4WinaTUCTvg5YEVnGpptBg3 [CONTRACT_PATH]/macros/assert_cmplt.tz +expruxeuWRoEFHhzv7tG1rwderXePZzxtpL9BRQ9N7ZhoFXS6RPy9a [CONTRACT_PATH]/macros/assert_cmpneq.tz +expruaqEBPqAjaUawnFTSbGZXXr1HemnecV8GuLGD15nQvtxaXiH3z [CONTRACT_PATH]/macros/assert_eq.tz +expru9etUCKvNXZyDCx1x55QfZzyGxmgsteFNBoWAZeh6F5FHEHy3m [CONTRACT_PATH]/macros/assert_ge.tz +exprvP9aPgepXY1C4hVPWPMoDGhvSjNvH5sJvB25qcMMPFHurVyH9c [CONTRACT_PATH]/macros/assert_gt.tz +exprtbLVpjXVnhdMUyDM53MXHH2HBNSMxdnXsVTNtFFMHHVn18yUuZ [CONTRACT_PATH]/macros/assert_le.tz +exprtx7nibNobG8Y7asBYktu2NdPv3k3No29rM4nP1WSbricymunvc [CONTRACT_PATH]/macros/assert_lt.tz +exprvQM6Ukz3TKVSo4dqNDYmMvNG5rs3U7WGXpvjSVsM2oQj6SbdLM [CONTRACT_PATH]/macros/assert_neq.tz +exprueGaPWpG6szfmTAccNH5MaoqxovN7JCbx4CDsmpvnhBAUrAizc [CONTRACT_PATH]/macros/big_map_get_add.tz +exprvFc9HFkvwNGZVrJkU2KpXuXieVKCJ9VXbTo51LRWBMAB6oEbWq [CONTRACT_PATH]/macros/big_map_mem.tz +exprv7Gwz5KP32zP9FYPSng9mPqLYbxwttDZin5QPnqzsUM3MZBvLK [CONTRACT_PATH]/macros/build_list.tz +exprvNqdnnqWgrrZYgnkuFeXrboqQYnYiRLSb7wV4E27bdZcbrU5GK [CONTRACT_PATH]/macros/carn_and_cdrn.tz +exprtknptGzyx8quFM8gHyGcpyX5xYeUxUpoVPhZeBkRqz5hUHfuq7 [CONTRACT_PATH]/macros/compare.tz +exprussGZ9wiqKqGkCsFJrfvr5DXxqZiLuHATJuvr3D8ar3KCeNaCz [CONTRACT_PATH]/macros/compare_bytes.tz +expru4Mmhu46yLQj4Q767jgVgvbaNe7B6EwvYvWA9KCrfzCxwBnzCQ [CONTRACT_PATH]/macros/fail.tz +exprtyJ1YYdejX7jRUh8FDjbbwrbAFwZYKPjdEZMNUUWdncqEwvuyr [CONTRACT_PATH]/macros/guestbook.tz +exprvMCL9Ti9C12EZUiFR1YtSp7nYjPN4DoyJPQiyVDYCZsSsheTeV [CONTRACT_PATH]/macros/macro_annotations.tz +expruq2AH96hXvqFqphuMKhJUY8mGMmdHuiHWHjkZqooZoEusTNNRf [CONTRACT_PATH]/macros/map_caddaadr.tz +exprueEkWTdWS8F25vnUP8gWd75MCfxk3vMhETn5dUYtrifV6FU8x5 [CONTRACT_PATH]/macros/max_in_list.tz +expruGfNErSHzpWnoNpgvZ3MRc52jiCHu8YTDUvh2T643QABr7NDZN [CONTRACT_PATH]/macros/min.tz +exprtw4kigYCiREgky6KBKryS7JkaGih6ju8jkjaXtpdcWYrYukRKX [CONTRACT_PATH]/macros/pair_macro.tz +exprtxutG1Nu8d198ebiCraNuQ8a6iYYqJYfGXq19aykNPB1uECc8w [CONTRACT_PATH]/macros/set_caddaadr.tz +exprvCE6JDXrzEfZuxTQzSgxWXtxX5GoNxvidL84CN2TAm6Hk3kuK6 [CONTRACT_PATH]/macros/take_my_money.tz +exprunGqZLZZwm9mY31NFGbBemCgXGevYqLRKdeRKQArPf824Npnni [CONTRACT_PATH]/macros/unpair_macro.tz +exprufRUAYF6r5QHQvK8CzWkKQcdvYkPx5fjEYzWPXc35Dry77KDT1 [CONTRACT_PATH]/mini_scenarios/authentication.tz +exprtjdvZr5J7WfN4SyNgKueLnxX4fALUYJ4cmi675EHJdUu5yyg2n [CONTRACT_PATH]/mini_scenarios/big_map_entrypoints.tz +exprtfWRfK4RoY8CF9VXvcHeBxizfjMMPAkLojfUTuoZkMSyiPKoyK [CONTRACT_PATH]/mini_scenarios/big_map_magic.tz +expruRE8G1Qc1dU8ZeQCTA48D69uPv8hpZYtDiKKHbfiy1mQLno8nx [CONTRACT_PATH]/mini_scenarios/big_map_read.tz +exprtotUpA2o34SHPX7ZQHD69WvJyEykTvPJ8T3RFErKAq4TQHFAgP [CONTRACT_PATH]/mini_scenarios/big_map_store.tz +exprtbeKR4fc2tqCWahuCeXAb42Hpye5dwmq8sj2guSztorTFJnh1J [CONTRACT_PATH]/mini_scenarios/big_map_write.tz +exprvTRcwMZnUPdSeRG8DdiC2xH3DrfMbp8qCwg76Av4pqbX5k4tHw [CONTRACT_PATH]/mini_scenarios/create_contract.tz +exprubRYeqf14u8CU4cEri2RWBrx26gkxyGe5wGeVAf4PDjKdsNhLK [CONTRACT_PATH]/mini_scenarios/create_contract_simple.tz +exprvLDpqaNLp1Cb8hbCqRU6tyU53n9PQkixgcBwFdSLJWsUdwhCQU [CONTRACT_PATH]/mini_scenarios/default_account.tz +expruaNoYRNTQxG5yujhHLetzS68ppQ38MFyi2ZhzNs5WNFv3wBAHG [CONTRACT_PATH]/mini_scenarios/execution_order_appender.tz +exprv6GXw7FheWdWKfY5oxtkB1AcqWkpKQDq4w7rxYFvwypZQijymK [CONTRACT_PATH]/mini_scenarios/execution_order_caller.tz +exprvSqfUw3oLZmQDwys8V5Qn9K1RAgMDGxdUUxzx1wpnyif3uSZG8 [CONTRACT_PATH]/mini_scenarios/execution_order_storer.tz +expruhMQvp6kKepaVGL8EEMPPk6zY1uyyW22Ugrr4ty21dtjDcVdbq [CONTRACT_PATH]/mini_scenarios/fa12_reference.tz +exprub9UzpxmhedNQnsv1J1DazWGJnj1dLhtG1fxkUoWSdFLBGLqJ4 [CONTRACT_PATH]/mini_scenarios/generic_multisig.tz +exprvTVuhJ2wNH8LHYEUiNC6ugx264rdfka1HkGfdVxV5632GjqgNv [CONTRACT_PATH]/mini_scenarios/groth16.tz +expru1u3Ta2uCGgcz6Z86K2mA5ierGB9RMaSwSppzVFxeuiXpBFZrf [CONTRACT_PATH]/mini_scenarios/hardlimit.tz +exprutz4BVGJ3Qms6qjmqvUF8sEk27H1cfqhRT17qpTdhEs5hEjbWm [CONTRACT_PATH]/mini_scenarios/legacy_multisig.tz +exprvRy1WUs7SQaNJm478UQHzz8uJAQoWT3bR5TXSnmbxWAcpZdGKu [CONTRACT_PATH]/mini_scenarios/lockup.tz +exprufAK15C2FCbxGLCEVXFe26p3eQdYuwZRk1morJUwy9NBUmEZVB [CONTRACT_PATH]/mini_scenarios/lqt_fa12.mligo.tz +expruBi6wgss7SRmpBCseBzcu3L283Jfx2CpUjgfuT2MgsozUsvBwt [CONTRACT_PATH]/mini_scenarios/multiple_en2.tz +exprtgxcdQP1EVvEYN2BHjbqTvwzywuYAdCmnfVgeP9zcgkxUrmScN [CONTRACT_PATH]/mini_scenarios/multiple_entrypoints_counter.tz +exprucgYdABPRbbq2yy2rpyt4Z8fv7PN4yhkch3QYZ5QQ5ehbtNA4K [CONTRACT_PATH]/mini_scenarios/parameterized_multisig.tz +exprvJ8zXaBkyXMhJ2eKtPwdwbg5NLrggvW8MEpVK3hk3nAe215PQ6 [CONTRACT_PATH]/mini_scenarios/replay.tz +exprtuiYUMjM6d8XxPda1yfKeN61ko6riom35PzybC31NKXkVhgBQy [CONTRACT_PATH]/mini_scenarios/reveal_signed_preimage.tz +expruB4maBvk1y4JaeSLpDXWC3zKiXK5QFYv4B3R5KfdGEt4B5VvTT [CONTRACT_PATH]/mini_scenarios/self_address_receiver.tz +exprvTG7hjtWXeogStj3pzM1MCVcNg1q6KnivqNVzQjviUrJvsjfQn [CONTRACT_PATH]/mini_scenarios/self_address_sender.tz +expru9ASRmfbXX8Ajf5uDeiZDbNwonrCiS1e6UaDXUstKU3yuwQwdZ [CONTRACT_PATH]/mini_scenarios/ticket_builder_fungible.tz +exprtXrMgaXhLsw6ioNNPThqPF1yDyLjqGdJeB6yMRKLUQZfkTD6jy [CONTRACT_PATH]/mini_scenarios/ticket_builder_non_fungible.tz +expruryVEK55xjeHpeGgHjuLr9jtRS2D1gzAgYXpzGfripoX8qFhNK [CONTRACT_PATH]/mini_scenarios/ticket_wallet_fungible.tz +expruoGtEJH3sXXm2ruNG6DGTFE3GM6fjAS6fzDZKtdaMnRzHvi3Xd [CONTRACT_PATH]/mini_scenarios/ticket_wallet_non_fungible.tz +exprtnBz8poqNTrK4rzTXZFKQx7HWpx4WidHB5wxcM2oTS8NcrkAUt [CONTRACT_PATH]/mini_scenarios/tzip4_view.tz +exprugya6ngixBfjyxV28ffnC8jmJPi4vbJdqD1aVUx82YLhzbH8Tn [CONTRACT_PATH]/mini_scenarios/vote_for_delegate.tz +expruaKedvXmhg6wbV361DHykomz5dPqLi473KxBwJwyicEnKMhpb9 [CONTRACT_PATH]/mini_scenarios/weather_insurance.tz +exprv9PvyjnsPjPCg5f13WtBiuD3o6idDAVWU6QfPtdWMjCLGRpwTh [CONTRACT_PATH]/mini_scenarios/xcat.tz +exprvKm5t6a6LL2d3HjvRiJumGrGei24aRXscJk3zB1hs516Ju4oMZ [CONTRACT_PATH]/mini_scenarios/xcat_dapp.tz +exprucvy7NUDPu2yTWEA6WVsusEZgGRmU1WpVzrFnNZV7m2H8BVysF [CONTRACT_PATH]/non_regression/bug_262.tz +exprv3FvpUYzomvhmzxsQyuR1katpswNnicQZB4jA5uec3MERXk1cB [CONTRACT_PATH]/non_regression/pairk_annot.tz +exprujPzkrPVucSvhHc1d9xm6kcs7oggkQyJXN8L2Rj3fteEABAkTe [CONTRACT_PATH]/opcodes/abs.tz +expruNtqq51Lm75X61pxUx7P2FyR2uyUKLsZNHMXWx6X5rsyJ5M6WX [CONTRACT_PATH]/opcodes/add.tz +exprupWD554EpqFBjo4KUpTqrfQcJAHqr3ijKmv5cmLRJ93Q1SgwGX [CONTRACT_PATH]/opcodes/add_bls12_381_fr.tz +exprugu3H5MPrpWJRZMPMGDM3Dbvykaa1fHejEvYr7ePKaLtahjQV5 [CONTRACT_PATH]/opcodes/add_bls12_381_g1.tz +expru41eYPF7gPvBRAtantBxbFU75RqBEwHPZ7UeX2EgHmExRoA4dh [CONTRACT_PATH]/opcodes/add_bls12_381_g2.tz +exprtcPYR7TZHxzcpmZWjjLgMWp6CeRWAxQ5Bt2bgpUK5uKjmNAdzL [CONTRACT_PATH]/opcodes/add_delta_timestamp.tz +expruLFQ1mcR5sg9sqyFHThknANoBeL4C5HFGgH55MqwPBEb1TUxLt [CONTRACT_PATH]/opcodes/add_timestamp_delta.tz +exprtz1uUW5sVUVaKNLhPaKGjA7jK9JmzWBCQu5Xn1MC3aS1FjTUmK [CONTRACT_PATH]/opcodes/address.tz +expruskF2nSeJeBaVHZsp45yN7mer9a4f8fAUBYvU3oRzbmpm5cVmt [CONTRACT_PATH]/opcodes/amount_after_fib_view.tz +exprucSgNGh1wkijmUcjLdifceE7GeMdLnxL3JZKpbxAmzF41ALo91 [CONTRACT_PATH]/opcodes/amount_after_nonexistent_view.tz +expruUQ1z6YqZM1baKofNLYhK9nocp9puAXCo4MYzEkQPbQcXTnajq [CONTRACT_PATH]/opcodes/amount_after_view.tz +exprvJ4NRS33cboLuTx58f3sbYpXf1m7Cq2ou9gpCh1k8foaCZAoas [CONTRACT_PATH]/opcodes/and.tz +expru5BXwmdpWQ3WDKA24g6gYGwLxPc868wKkdeAaGh899nD77Uxwn [CONTRACT_PATH]/opcodes/and_binary.tz +expruL6aKRTXN2hWb9EXLuJASu7nuBGJxL7VyT1oEjX9b2s3u6Y5Ff [CONTRACT_PATH]/opcodes/and_logical_1.tz +exprtpYYuLewZWKCK1aPb9gfYSiPWSaeXRM4P2e4rpa6UktVueB1uf [CONTRACT_PATH]/opcodes/balance.tz +expruWVQymVzetzkRaBYh4thmdWCvzWZNqdGrCTinGxLn58rPXDkgC [CONTRACT_PATH]/opcodes/balance_after_fib_view.tz +exprukgm7LHJiEywzSseHXp23nXM5Y9GfJ61ULij58BgRQ4nt3bYYT [CONTRACT_PATH]/opcodes/balance_after_nonexistent_view.tz +expruggCnM7PeEcUr2BapBmFMhD1QGvEoM4dUfyxp2u64ic1fM9SYN [CONTRACT_PATH]/opcodes/balance_after_view.tz +exprtZRAy4QHqpF8c3CusD6e1kxWA3KAUrmgeXndfQYSEGArDmkWUm [CONTRACT_PATH]/opcodes/big_map_mem_nat.tz +exprugsT35M51mCw6Fim3ysNKpCh8JyW9m7CYW65QQ7XUEDmspqz2i [CONTRACT_PATH]/opcodes/big_map_mem_string.tz +exprvN3tk4o5YPYJB6aYAxEx8KU93yNSaw4K6mbEZZh9RQayua6odv [CONTRACT_PATH]/opcodes/big_map_to_self.tz +exprv712JoEC7RRhoP7gbTUiVgLbtAgHmenwa5TqhVykDZ3e538MGU [CONTRACT_PATH]/opcodes/bls12_381_fr_push_bytes_not_padded.tz +exprufF1yaR5QHdy8iECBLjhBtDZVLiEjZRuJntSkXjsrJRYozXLmW [CONTRACT_PATH]/opcodes/bls12_381_fr_push_nat.tz +expruSVRATSSsbfHowLHGs5XHms95RuqBWSdDJoUKdns3fWbwasU1p [CONTRACT_PATH]/opcodes/bls12_381_fr_to_int.tz +exprvTBYxSJ7d1z1aZvvAgPrdZUXHzoFxkwBC7McES5BS56xvqkGXg [CONTRACT_PATH]/opcodes/bls12_381_fr_to_mutez.tz +expruTppbXBm1YHSCB4uYv9MQs6zxqRWqbkwGWoiKfF5Sjj5n2TpJx [CONTRACT_PATH]/opcodes/bls12_381_fr_z_int.tz +exprv5Si29PfXErNuJdEvJWQhWRJ3qPETygaWzRE3ctmCU4s6y2V9v [CONTRACT_PATH]/opcodes/bls12_381_fr_z_nat.tz +expruRsYz6JopAFGU95WfFU61SE3RbMGn3XPR9PFiTfLbgQr2kzu7u [CONTRACT_PATH]/opcodes/bls12_381_z_fr_int.tz +expruyE3E3o8EAptRBZtQAB5Kv3sxUZGv7DK6CpJ2YdotQj9gqW5wN [CONTRACT_PATH]/opcodes/bls12_381_z_fr_nat.tz +exprui72n1Jur5Px5ESXgxiF9Uw86DsoXPt1edGDpSv4CvnuPCtBPR [CONTRACT_PATH]/opcodes/bytes.tz +exprtvRRYmpToi9y67ZzNmgjtdrgNkwVduSnBi7GZVrsmgDna8TSjB [CONTRACT_PATH]/opcodes/car.tz +expru5dDnxp1rhgXGmKigbLJ9ASaVHbkpkL6gLggtk9krgYC3jusc8 [CONTRACT_PATH]/opcodes/cdr.tz +expruxH6gEuBmNzg5nWEM4tv3jMBbknbEtTHKTPMeC4EBdFdujbRph [CONTRACT_PATH]/opcodes/chain_id.tz +expruGhHABGLz2wxAyyx3RpfyKHa8HE9voC19vLiAKYWYMMsUUTFdd [CONTRACT_PATH]/opcodes/chain_id_store.tz +exprtjDuLEzh8dcjpCcJiiuKXDdG3XusjuuURVCh3JWKBgjJGsVsMs [CONTRACT_PATH]/opcodes/check_signature.tz +expruHKTiWeY6mty7RokwdyZdwdzHQbu7udbbZbpu3C8h9n6jXnp4v [CONTRACT_PATH]/opcodes/comb-get.tz +exprtsyJo5ceZQM76zpAUeTren1YnBxw2MNDKmx8k11Ejai8T296Sg [CONTRACT_PATH]/opcodes/comb-literals.tz +exprv733yfMh1C9uyuAJJP66WPQDXAjjfcTcSfHhbboJnz6DUCEh41 [CONTRACT_PATH]/opcodes/comb-set-2.tz +exprvHamsTHMJKF6ohaSAwdgp2Sv33LGgYnjase3LUcwXKnJfh53wn [CONTRACT_PATH]/opcodes/comb-set.tz +expruufsxtik2vxyQfL3QKNWWH9TnJZgGx1ELi3AR5L3LM71uqxiP4 [CONTRACT_PATH]/opcodes/comb.tz +expruKknV6VYzPHkSxc3EFb488JPBfUX1UHsJUzceaGFafdnbgsKw2 [CONTRACT_PATH]/opcodes/compare.tz +exprvGXTYwatNh32w78r83SuLAW1YQefufYN1Bcu9AZ1BLDUU77dKR [CONTRACT_PATH]/opcodes/compare_big_type.tz +expruR3ZCLJTuojpTuS2sR3SGxqait52kXQNKfy8bipv69b2XJZG8A [CONTRACT_PATH]/opcodes/compare_big_type2.tz +expruUDL3EP43hFhcdCZD7K1xvfPtiNWfkU2Nyq8jmr9XgZuXqWXc5 [CONTRACT_PATH]/opcodes/comparisons.tz +exprtjqEmEBnmG7yiDXn224ER9bt4qh18LF4LzFSfoeuo1cbJpNBPy [CONTRACT_PATH]/opcodes/concat_hello.tz +exprtqd5qPLeh5Fi52YdkgWuvRXctgUoxU1Q4JDB2VseRk6DAEpMvd [CONTRACT_PATH]/opcodes/concat_hello_bytes.tz +expruv8MHvRmp3ipXYRyyP4aEE4iFHWsNZjNQSaCWUt7fwbgLeFBXY [CONTRACT_PATH]/opcodes/concat_list.tz +expruYk7GXYQ7bKbUcqcHDKs97USVBrxAkzSo2Bkj5AXVjSawDkNAS [CONTRACT_PATH]/opcodes/cons.tz +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_alt.tz +expruxUAUoijmC6A4rZK9XHcQL4WmgreJwT17hrgpuYkg1VeELBdbF [CONTRACT_PATH]/opcodes/create_contract_with_view.tz +exprteqmco8PDGH1PnTGgF5jPjBPCYyZfyvER2ULtv2y3MRgGdcP8T [CONTRACT_PATH]/opcodes/diff_timestamps.tz +exprtt6joHWnYr4AAW3uem8nzbxYgLcSpEJtaUT66qWchoKPS8sFXx [CONTRACT_PATH]/opcodes/dig_eq.tz +exprvKBfwAg4hVHrTtq3UV8AunaqUKxAkvx35TScbZDARNSgH737Ck [CONTRACT_PATH]/opcodes/dign.tz +exprv8t3ZfoBs6B7LMeFNN6U4PRpE1M6MhdtKPT5keNZT4je3RBadj [CONTRACT_PATH]/opcodes/dip.tz +expruncwh1qqNqSwq6kHYXfwhQyjpuJjbernTsyHAMnaLjU5h3qjxr [CONTRACT_PATH]/opcodes/dipn.tz +exprv62zo2ACMdseAu1HKzDDLSjBrYr2nZzi36PCTVJqcBwSdvt4yU [CONTRACT_PATH]/opcodes/dropn.tz +exprujbvaRkoroj5eVgboUyeP3578oJgScTQ78eBYMgfdLVaGWPPTW [CONTRACT_PATH]/opcodes/dugn.tz +exprur99uFkrwM63FXSTqSTypHcfEmzb5KQ9EypTRqZWDY5NP6tCHL [CONTRACT_PATH]/opcodes/dup-n.tz +exprtarW6tiguR7YAo6SxhCUDs1pLDhx9xJEG78h6GnXLAWpt3H1pT [CONTRACT_PATH]/opcodes/ediv.tz +exprvQhRaLYxiWN3QsJgT6VKf6DmGVuXR8DxeU63P9A8iNWA4TVQfs [CONTRACT_PATH]/opcodes/ediv_mutez.tz +exprv8Sy3DsiKMm3ZQPmi46kZGn9ctTigpLB2t6xYFdYkkeVHMXy6z [CONTRACT_PATH]/opcodes/empty_map.tz +exprufqf2G8PoZN768K2YGex6M7zmz7bYHE5LF5QHJBVvFtAFLi6qr [CONTRACT_PATH]/opcodes/exec_concat.tz +exprut53jocMPdPP8FXrKRDYSoRaxk1FXqCt7o46ak2wQaocjsSwwx [CONTRACT_PATH]/opcodes/first.tz +expru5fjTGWP1BXZz3BbbEFyDFkyZGJKHcZ2Y6jDT3CdHHp81n6G1r [CONTRACT_PATH]/opcodes/get_and_update_big_map.tz +exprua5oh3PDJEPQbEsnbHYCz6L7bY6kNvpyhEt7Cg9sPsrx82UmHQ [CONTRACT_PATH]/opcodes/get_and_update_map.tz +exprtgnkjSH6Tdw5C1BMKr8kCJjEnxCfMiaAxHTVLnEcyCQ6WmJ1jr [CONTRACT_PATH]/opcodes/get_big_map_value.tz +expruv8JdHeURNpuLHao37SGJauDPwB9yxFXUaL6hNCdXGzbHSqCZN [CONTRACT_PATH]/opcodes/get_map_value.tz +exprvHC1MDkeqCNL8yrN74nmqk5qrZCvR42qoVUxYCB4ALpgDfmhbL [CONTRACT_PATH]/opcodes/hash_consistency_checker.tz +expruzeve85eDLTpQ1EbgrQQcEUft7AGauZBwtK1ibuvJpwmZt9AE8 [CONTRACT_PATH]/opcodes/hash_key.tz +expruycqvZn4ufKjVQmYXcCfAfm7C81zN3BAqxuYVVfnpFibSKsahG [CONTRACT_PATH]/opcodes/hash_string.tz +expru34ooMhYSarFg7vZCe1Y23jwfxfHiDqwaE1wGXC48yjB21PLi1 [CONTRACT_PATH]/opcodes/if.tz +exprtmbKAmbV2XioTbmpJQpg9QDAxXkTBXmKRWdC8zbk8CWAtVXwAc [CONTRACT_PATH]/opcodes/if_some.tz +expruTGRZeiojz3Rrr45KUcwtpJuJYu6U8pxi4DBZpL2kGavVxxM4H [CONTRACT_PATH]/opcodes/int.tz +exprtu4Xbe67UZyTubEtKx83bMyQGXDwBibcdgLF5hftZYTEL2kSst [CONTRACT_PATH]/opcodes/iter_fail.tz +exprudLYgw6yWSrTHpXYsg9NcZxGGpCxdNFbNv7ksr6Ss8rNmh2fgT [CONTRACT_PATH]/opcodes/keccak.tz +exprusrBf5Sakr6dRngzuPmwsP28X6W56nVqCXqG1Jcfrd1SYwPRuU [CONTRACT_PATH]/opcodes/left_right.tz +exprvHZpmtBKjjsUZmchx2RTLmFAZnYKCnHSKXaKUdP5EUpiPYwsp2 [CONTRACT_PATH]/opcodes/level.tz +exprtkasRZbYRQg7WKnoXwJnRwXkvmjZEY4yPYXKGAQQFUupt5VAmt [CONTRACT_PATH]/opcodes/list_concat.tz +expru32VE4LnqAqhbpUFCdgEdRSHjLQipkXTjn624fL41yk3a4H5Q3 [CONTRACT_PATH]/opcodes/list_concat_bytes.tz +exprvCkexzSQFgEWkFvrkrQ8wATasfkbKCyeXYSM4qZft3g3UuoTBi [CONTRACT_PATH]/opcodes/list_id.tz +exprtbHaLLF4cUTh4VCjtnH32EAA2AFwvPBsCzUTgrrdofbotKMyr7 [CONTRACT_PATH]/opcodes/list_id_map.tz +expruAxpePKSFaGkjukWx4HEZAvXaWvyfyGyxCfhvK9tZjkPNSpZ1m [CONTRACT_PATH]/opcodes/list_iter.tz +exprvSCwmQGBkxgu2Tg5rYUXbyv33SpUskCJS7sPF4LN7e5pQ1fn7z [CONTRACT_PATH]/opcodes/list_map_block.tz +expruu6vcnLhDhSkSo8NNNJWQL99VCFr6iArtKrmavJWSNkQwDJsKC [CONTRACT_PATH]/opcodes/list_size.tz +expru8Et3hTjxKQpydKSThjR6fXSmPEmZDjBTNhTAbuyNjcPYoUQUL [CONTRACT_PATH]/opcodes/loop_failwith.tz +exprv15pFChKhH3QKoJn5BCT1bP4R7DjnXWtTDsSfwf2eVonZNxzZs [CONTRACT_PATH]/opcodes/loop_left.tz +expruAKUrHWCxb3qtVQ1a8qDzrS19HnTm7bS146AztFHekvpqbehaU [CONTRACT_PATH]/opcodes/loop_left_failwith.tz +exprubosuA8peKBt4EEo1RsYjxSxK7HXytSkBFAjns5Zg7ncicPWrC [CONTRACT_PATH]/opcodes/map_car.tz +expruqCpEBS2R8FqpBfDNUNrPhXZr39CBL6zKpyMogJR94sve62iv9 [CONTRACT_PATH]/opcodes/map_id.tz +exprtb1QBmNfCYjce9FnvKdikbtgqcN5o2VdVwZZP2Fmy8C3TJjA7q [CONTRACT_PATH]/opcodes/map_iter.tz +exprtuspLRSrYnp2FyqNcLfsBrBBFD8nnFog2Em3p7tfG4DcGujS3f [CONTRACT_PATH]/opcodes/map_map.tz +exprtipeMFcMFwYRAmzZBMoUjrtPYDk5ZyhMSyuhSgfiJV5UNAcLGp [CONTRACT_PATH]/opcodes/map_map_sideeffect.tz +exprtc9HPyzpfc71TE4a8UbRPxfdm4WGRPNQhfB5fHiWwkh1aA8uzm [CONTRACT_PATH]/opcodes/map_mem_nat.tz +exprtrkfCSUckShrEP5TmC5Y4CdeU35FFL7R8kyJHQUFZ4DNdJZasD [CONTRACT_PATH]/opcodes/map_mem_string.tz +expruqncptpX6oXeX88mAkVHh9DnzWb6vPwT6LvuND9yobgcH5Gd2x [CONTRACT_PATH]/opcodes/map_size.tz +expruZ7Tb7uhcAu3MhiDJFWrJiYseWyagZYEnzjEdpjSei8i73hsfG [CONTRACT_PATH]/opcodes/merge_comparable_pairs.tz +exprvNxEfUTwaryUzets4qyTbHAfNPb5ARQsMsxbm8CnGNHDedqxgy [CONTRACT_PATH]/opcodes/mul.tz +exprtYi1xHmB1AY6j4e3XTPvXpmuWnM4b4o78yVihYt1i2yNjrQqhY [CONTRACT_PATH]/opcodes/mul_bls12_381_fr.tz +expruFTKqYqMmWSakzE1gjs2p8kWtcRWTaddkYL5p2Z8wpcCfe5ei1 [CONTRACT_PATH]/opcodes/mul_bls12_381_g1.tz +exprvBDM3kep2f7bRkhRa2XWt9sdPGJ79sq6TdWNNnM4yydTQ88TaH [CONTRACT_PATH]/opcodes/mul_bls12_381_g2.tz +exprujbPsZAUa1tzgWNgeHEQ22JXDfNhkgx6sCCxbWjYoNWPbTvwhy [CONTRACT_PATH]/opcodes/mul_overflow.tz +exprth31LKm5FDFGxcXg1Rv9z9YeAQ8eu2oYTh2zZ7kJas3f5CWkZm [CONTRACT_PATH]/opcodes/munch.tz +expruP5gECQdRLkmuYg8xqvEAdE4oRGFjDVG3ZkWxtCyxve1jviw6k [CONTRACT_PATH]/opcodes/mutez_to_bls12_381_fr.tz +exprtw9PgkJCxyqdLjuA4dEdRjQXY7Ge4a7jjd2UoU6Q6KrvhFgciM [CONTRACT_PATH]/opcodes/neg.tz +expru5fYi1tAG8a9j2dYT561dXaox8wYjsZDZP18xPa5JN3bUNfHWS [CONTRACT_PATH]/opcodes/neg_bls12_381_fr.tz +expruY94PxNhmT8BeyGrFurRF6gC7XfgsBY9Vjh6hJyiDPaR8nFmri [CONTRACT_PATH]/opcodes/neg_bls12_381_g1.tz +exprv9bM4xnqjA33RkvUzz8ZppJXT32KdNXoYqY2NSh7whBcFPn2QS [CONTRACT_PATH]/opcodes/neg_bls12_381_g2.tz +expruZzA96Rh5o6HBboygY3iD97dgQcepXd45WBBD4DYZ2qcn8cxyY [CONTRACT_PATH]/opcodes/none.tz +expruat2BS4KCwn9kbopeX1ZwxtrtJbyFhpnpnG6A5KdCBCwHNsdod [CONTRACT_PATH]/opcodes/noop.tz +expruMUpBKBPGde4GfNLM8NgMq9nL6KsQXGA3LPt4C6wtMTxcUnE9A [CONTRACT_PATH]/opcodes/not.tz +exprtnpHGyp2TurQb2YzbXBKTipXnrUQ4RrZwPxWfa1yMXS7oi49jV [CONTRACT_PATH]/opcodes/not_binary.tz +exprusKUuYeoKXUAYtUhtknryT9MpbPZVZtbfUNCdRpXUbdzEzbwmN [CONTRACT_PATH]/opcodes/or.tz +exprvG84juZWwLHTrhtvWFWBs8D2wZw6rfpoAbXp2pkekuCMAaPbAn [CONTRACT_PATH]/opcodes/or_binary.tz +exprv39cZxxm6fTcFSbLcwpBbAPW56FPqjdf6aGm21KqGA6DQtwn6u [CONTRACT_PATH]/opcodes/originate_big_map.tz +exprunveMvzjDskHYCvYJzDfRR9aGwwvXkVUMqTwSxJJbEjeq63c2D [CONTRACT_PATH]/opcodes/packunpack.tz +expruKkmmajE1UFXRHXtntLZU8VvnLfFKwYPd4azsAdcrDMaq5zu9H [CONTRACT_PATH]/opcodes/packunpack_rev.tz +exprtk9p4ur3KZK2w8ziFoZVHPABxQWZXeSNowcJuTauL3zTxr1zcH [CONTRACT_PATH]/opcodes/packunpack_rev_cty.tz +expruSamDrL2Dh4zp92cVgfV7ETT7VcnqACDVcvnafi3qgBZq9v3PL [CONTRACT_PATH]/opcodes/pair_id.tz +expru3WFEX5bVjBUkZzuWspLG18hy5jTzbr2WtKEYpfPHGpDFvcqhd [CONTRACT_PATH]/opcodes/pairing_check.tz +expru2U5Bi7ehgkQvP7Qmij4c8gkSFUBNtiCyXMX3WwGjEdRRZc5x1 [CONTRACT_PATH]/opcodes/pexec.tz +expruPr8QtATywJFqPjDhF7gyqdF15L6J7pxgpypzorEvtubdJN8U2 [CONTRACT_PATH]/opcodes/pexec_2.tz +exprvBUenyTMJKwERZ1ULzMVrJ1owqymBF32f627arqtFUzMpaMvbC [CONTRACT_PATH]/opcodes/proxy.tz +exprvPaPcYHvKmnyBMaYXtp6ZuaSEHWr5y92bcroKKppAZvF4RvcWE [CONTRACT_PATH]/opcodes/ret_int.tz +expru8MKLXqiNRYnPccUN4if3VnWfthDy24K4zuJrFh2JaMmmh6Rii [CONTRACT_PATH]/opcodes/reverse.tz +expruta4Bjo3FggDcvZDzEVwzeTcdZptzkJZyFEkdB8suFGbMVtT2Z [CONTRACT_PATH]/opcodes/reverse_loop.tz +exprueR2MPCHUFtPjMZXE57X3EsysuWJXGRz8ZgcPJj21UySLqULV1 [CONTRACT_PATH]/opcodes/sapling_empty_state.tz +exprvSNMswzVUk47vqs4wTGipDb3qDKVUwNBDwXtGzjCprEYx4nWPo [CONTRACT_PATH]/opcodes/self.tz +exprtzokY2FHvPvB9YHSi8MM5YUbPdUPLi7tEKkp8BKongPb2zrZch [CONTRACT_PATH]/opcodes/self_address.tz +exprukm3NvsYbS9ymX3MuXh6LciuF8ef2qt8ktTGaXtyFxCpisMBdD [CONTRACT_PATH]/opcodes/self_address_after_fib_view.tz +expruV4HCC6sRdEL5HyXVC9gTkMZbh8BnxXsKZDTydtztRhDUT3qxa [CONTRACT_PATH]/opcodes/self_address_after_nonexistent_view.tz +expruUWxiqrD566farETUi3VChWNZ5teemC3q4G8tf83xhjTwRSEws [CONTRACT_PATH]/opcodes/self_address_after_view.tz +exprvQ8rhMFcCrwNSLZERQSQ9TMR1Tsnyj7R1jS8J2UESKXUoJuLTV [CONTRACT_PATH]/opcodes/self_after_fib_view.tz +exprvKoMUnUmthGpVmQfYkLa8F6GRwmU36D9jYXNG8j8QbQYNWUoAC [CONTRACT_PATH]/opcodes/self_after_nonexistent_view.tz +exprtXqpN6sqTKUVNissE3rkzKGSBuW2gTh8pRb3XyHZ4dpaAqLnhL [CONTRACT_PATH]/opcodes/self_after_view.tz +exprvDVUQXNsfs9FiHkMSofonWCWcBfYbfxeQy9DRaa5Tnbw1XM18Y [CONTRACT_PATH]/opcodes/self_with_default_entrypoint.tz +expruXGf2YpXKkr74mcv83fQ6bztVD1RBoFXaEnAd9bidnRXcfD3Nj [CONTRACT_PATH]/opcodes/self_with_entrypoint.tz +exprudmJ37Q8ZASPbZSSBfy5UezxLhniszTVkLAB8QKvxkav4gVVYr [CONTRACT_PATH]/opcodes/sender.tz +exprtufbuVP6RKm1PGPUQnZy6dqwxCha1jbafqyVGpCUNWeUVpcBhc [CONTRACT_PATH]/opcodes/sender_after_fib_view.tz +exprug4Jd1WdLqrZWiG8PsGDETN1ahpX5PycBrdNWadM96M5SjvLae [CONTRACT_PATH]/opcodes/sender_after_nonexistent_view.tz +exprvR3pRxvwuwM1c4Jk1zRfuDabRPwLnazpSsySQkzymatANufH9h [CONTRACT_PATH]/opcodes/sender_after_view.tz +exprurSxmHBRCHUxtXcqNkPA8UE6gaFeJa19bBhq1CarZ3CZuAzShs [CONTRACT_PATH]/opcodes/set_car.tz +expruogQk6tG5W7CtZrcMzsRtJ1f9moG9y5Qg5j29NATiaSywvQCcS [CONTRACT_PATH]/opcodes/set_cdr.tz +exprvCt5LtbC3mLLWHdvyxGcX3ND21Ym5GayCvePEHHGXAtgWu32sJ [CONTRACT_PATH]/opcodes/set_delegate.tz +expru133Wm63xA1qs5ymovjbP3N3iwPoTMcdUsbUqqbTf896jU78WR [CONTRACT_PATH]/opcodes/set_id.tz +expru151wgMY5reA7WVbnvkHrh9MVnfYFbCDaiE2aTGmkKACu2ZbJA [CONTRACT_PATH]/opcodes/set_iter.tz +expru13v2dm35MgMgTbwDJ4nEwNjRTau8mqztAyxGxXVbHNmskAA2q [CONTRACT_PATH]/opcodes/set_member.tz +expruE8c9EzG6kYQdp5RQXrAt2CekSFXVtKUzNDUnpVTDygEBP7VvF [CONTRACT_PATH]/opcodes/set_size.tz +exprtzSBcPatLYnGe5xtsSNGVjNBLMmHefxsQ7Q2QNjDMGmADKdWUC [CONTRACT_PATH]/opcodes/sets.tz +exprteVcB53uqnwQsZMTsBojwez6tkgRqj1qWCQTLgaQWxQGiNWXEE [CONTRACT_PATH]/opcodes/sha3.tz +exprvPbB5NtiV87RARduqoXtMoRjjy6jX8WYrfiu3RDjQrTKxPQnoe [CONTRACT_PATH]/opcodes/shifts.tz +exprtnS2EjwJ3MdSWS7R6UbZMqFoUHj1JpUhhtJacXdfmmzRNHL33W [CONTRACT_PATH]/opcodes/slice.tz +exprugZMQtZN7safMU7hV5QpM7nh7Vi5ur9sGjeWsmGRkW1ETox8uR [CONTRACT_PATH]/opcodes/slice_bytes.tz +exprvCqvDAp66YnPaZDdaAkCNafoGtw1fEuWaLxMFeMnX6oqrb93nP [CONTRACT_PATH]/opcodes/slices.tz +exprtzW4jh4MgY6iXgiCXft5q3Mig5XXANHn9CmcL8ApTrdnQgWzAm [CONTRACT_PATH]/opcodes/source.tz +exprvD9HJMfLEUdamfH9U8ozBaxA7hYVRMbK7At6sUqFMmhZ6UorWv [CONTRACT_PATH]/opcodes/split_bytes.tz +exprvJcmHwozD2DTtagjJJfyPgoCvBx5bMzXAkrsteYVvxeMr9SWm3 [CONTRACT_PATH]/opcodes/split_string.tz +expruDY992zB37mWpZwFQCrfDbkwmrCmjSHD4fzQcW1z1AeWeW8M3r [CONTRACT_PATH]/opcodes/store_bls12_381_fr.tz +expruZAkBxtwSXuMp6ZDNp41mJ6uZ4bw7RF9HNzJS9EnzTLxVhQ4SB [CONTRACT_PATH]/opcodes/store_bls12_381_g1.tz +expruZfFC7WkBQhK4Ksg5k5WxBamF4PvH2NGCxcd4DHUkKfeqQEBUe [CONTRACT_PATH]/opcodes/store_bls12_381_g2.tz +exprv8K6ceBpFH5SFjQm4BRYSLJCHQBFeQU6BFTdvQSRPaPkzdLyAL [CONTRACT_PATH]/opcodes/store_input.tz +exprvStWRo24QuETruMmMqkmLme6UAMHuTRNNq9Lq65oFgUvQmJGPV [CONTRACT_PATH]/opcodes/store_now.tz +exprtZPsTsBtNf9hjv7Yfda2EV4Sz3iaHpk4NkYHcKteXbsyQ9d6pH [CONTRACT_PATH]/opcodes/str_id.tz +exprv4UZUuBDCZZjtW5kaezZjaKqpi1GN6vxHsvQNNkFktnaEbDb1M [CONTRACT_PATH]/opcodes/sub_timestamp_delta.tz +expruVuXhQmoBMzZjPeY7VQSuJxefBBTuPyNR7PGnYhwouo9zKg3T1 [CONTRACT_PATH]/opcodes/subset.tz +exprtz2jbsXuMMPAXYAGJZqjuBp8iF38XadE3YuZoC2W5NkyhhHMuq [CONTRACT_PATH]/opcodes/tez_add_sub.tz +exprugbVFDGWcSSozyN3EK3AcdwtPeES3ao45HNogWc5V8fsJ8NsSP [CONTRACT_PATH]/opcodes/ticket_bad.tz +exprtvedUmBuu66gdQXWpEJNQBU96bnUVQmrWWLAbcdsCLV4Rwa34K [CONTRACT_PATH]/opcodes/ticket_big_store.tz +expruqx789AMcKUYwDeeeRvSnwdCw8gMVvWA6vuzPzBQwBM2qcDXJB [CONTRACT_PATH]/opcodes/ticket_join.tz +exprvMp1LX8aeyEq9NiMXGyD34J4offZDANGRwFTxoEWXumEsDdAP8 [CONTRACT_PATH]/opcodes/ticket_read.tz +exprtvtEFi6v3awAwbHivJkjki6mDNivewiCBeJDJT78PqWtq7VyUD [CONTRACT_PATH]/opcodes/ticket_split.tz +exprtifPFaLqHvR9uGWbeLj5r3YVBnKaawt12q3BMhM9wsUdM9dFNy [CONTRACT_PATH]/opcodes/ticket_store-2.tz +exprvJGjz1EDdnAPWZQ7ZngDNDDDXnxA2VY6SHdHKu8LxqcVHd3E6z [CONTRACT_PATH]/opcodes/ticket_store.tz +expruhNaUWmTNpmFWSXUgf1ZjgcUXmjtXGaMumzteyFYzT9CMmU4wc [CONTRACT_PATH]/opcodes/ticketer-2.tz +exprvPfYzs3x1V67saypcaPGwj5rnuKsb3tFi2VtqX7gtP4W3sjfye [CONTRACT_PATH]/opcodes/ticketer.tz +expruhV9RSEPAtKAUhBbdTw5gPFdjcKk8zr7cVLSsGtmJuH3o7VXXo [CONTRACT_PATH]/opcodes/transfer_amount.tz +expru3MSjYZRmQi3yiN6gYa4X6rs88XLWH4H8ivzrCvxs8z8cJfu4Z [CONTRACT_PATH]/opcodes/transfer_tokens.tz +exprtbACDcFtDfEwsBA5LAG13uMRAjnQsFjzNELMS7jQ87bcqgdE6r [CONTRACT_PATH]/opcodes/uncomb.tz +exprufJpS3BWpgv4QBaBEMucbn1jsVpdqEGLLMfXjDuKGPRGCpZUkj [CONTRACT_PATH]/opcodes/unpair.tz +exprv4ACaZe4aECCfG93NGVVHbQBNQ5Atxtju5vWASZSEp5sLECcjg [CONTRACT_PATH]/opcodes/update_big_map.tz +expruWzM36ATA3fAee4WHDS4vvMeewkwhya1fZaa6HFPbjwt9vvGpg [CONTRACT_PATH]/opcodes/utxo_read.tz +expru3YgRPQBAnTWgKytSMs3tRj7dMgtWUxo75b1pUFrTLscKy2byF [CONTRACT_PATH]/opcodes/utxor.tz +expruJxgC2Q8Ubt8tPyQbZ41j6w4b8yw5f6bxjrMMM81TmMC9x5Lrc [CONTRACT_PATH]/opcodes/view_fib.tz +expru9EavkgPCUAwHccJf9j1t4aTTssPKoBkCqC4YNr12kxXSwqFqD [CONTRACT_PATH]/opcodes/view_mutual_recursion.tz +exprv4QXQuZtQE7CpKyecjrXJ8U2ovU1qjUKtw37J6kAEmu3fAKyN5 [CONTRACT_PATH]/opcodes/view_op_add.tz +exprugGjNh2tTsofJyhkNMrQVJnkyLydJywNVMAXL9rW3nhnCmRd3F [CONTRACT_PATH]/opcodes/view_op_constant.tz +exprtn56ZZ3mXHoz9GMS9HGMfmgayukvVXub8zXeDKbE4U7L5L8dXX [CONTRACT_PATH]/opcodes/view_op_id.tz +exprtaNDFRcdw8SB4Bz1a6CKARxZaoxpc6G2hnJYedp1iZgJqEwMNV [CONTRACT_PATH]/opcodes/view_op_nonexistent_addr.tz +exprtmA9Auh8GAHpvKP2qkVhiaRCtokWcw7qg31CaxbouJW1g8yYK7 [CONTRACT_PATH]/opcodes/view_op_nonexistent_func.tz +exprubMFU6xrnHREoXUZinEeV3PuZBjSw35M6gti7tyQ83S6LTKja1 [CONTRACT_PATH]/opcodes/view_op_test_step_contants.tz +exprtj9pixxS7UHchhthZa8zdU2GAjvW7oA7QEMA3PHgf88vmAEjFb [CONTRACT_PATH]/opcodes/view_op_toplevel_inconsistent_input_type.tz +exprurrbjDgnipRBhqb7pPLQFAgtPm5jrpwJjJL5ZvQyFJZzGvqteY [CONTRACT_PATH]/opcodes/view_op_toplevel_inconsistent_output_type.tz +exprvSPcq1w7iTMA3LjQcHegnRUQ621sqQLRJm1Zh4tjHCkmeZV268 [CONTRACT_PATH]/opcodes/view_rec.tz +exprv1LkSMvSyZSBrg9Tf2PdcoiWDYPz2npmYb7rH6bWx2sYMAHMgg [CONTRACT_PATH]/opcodes/view_toplevel_lib.tz +expruF13NKWWyF51seiYv4tsb55dZHYViNWDKTmhLq9b1LXXenwaB2 [CONTRACT_PATH]/opcodes/voting_power.tz +exprvSZMaiMSbKgRYm1W4rcoBGN21bPu8NMQuYBH9ujhXGeHhdtVGk [CONTRACT_PATH]/opcodes/xor.tz diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fac.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fac.tz].out new file mode 100644 index 000000000000..f2257eada560 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fac.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_fac.tz] + +exprv5Zq1iL1bPVUnL4TZZcmuezBhf3BBoCa3HyktPw1AivsHv1FnP diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fib.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fib.tz].out new file mode 100644 index 000000000000..4f7a53dfaa93 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_fib.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_fib.tz] + +expruJxgC2Q8Ubt8tPyQbZ41j6w4b8yw5f6bxjrMMM81TmMC9x5Lrc diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_mutual_recursion.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_mutual_recursion.tz].out new file mode 100644 index 000000000000..66d9977f1371 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_mutual_recursion.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_mutual_recursion.tz] + +expru9EavkgPCUAwHccJf9j1t4aTTssPKoBkCqC4YNr12kxXSwqFqD diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_add.tz].out new file mode 100644 index 000000000000..60b9ac6aea77 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_add.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_add.tz] + +exprv4QXQuZtQE7CpKyecjrXJ8U2ovU1qjUKtw37J6kAEmu3fAKyN5 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_id.tz].out new file mode 100644 index 000000000000..a723a8a7ccb7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_id.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_id.tz] + +exprtn56ZZ3mXHoz9GMS9HGMfmgayukvVXub8zXeDKbE4U7L5L8dXX diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_addr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_addr.tz].out new file mode 100644 index 000000000000..fe504296577a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_addr.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_nonexistent_addr.tz] + +exprtaNDFRcdw8SB4Bz1a6CKARxZaoxpc6G2hnJYedp1iZgJqEwMNV diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_func.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_func.tz].out new file mode 100644 index 000000000000..dfa7334690a8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_nonexistent_func.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_nonexistent_func.tz] + +exprtmA9Auh8GAHpvKP2qkVhiaRCtokWcw7qg31CaxbouJW1g8yYK7 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_test_step_contants.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_test_step_contants.tz].out new file mode 100644 index 000000000000..34f3e03afa2e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_test_step_contants.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_test_step_contants.tz] + +exprubMFU6xrnHREoXUZinEeV3PuZBjSw35M6gti7tyQ83S6LTKja1 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_input_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_input_type.tz].out new file mode 100644 index 000000000000..3c8e63008161 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_input_type.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_toplevel_inconsistent_input_type.tz] + +exprtj9pixxS7UHchhthZa8zdU2GAjvW7oA7QEMA3PHgf88vmAEjFb diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_output_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_output_type.tz].out new file mode 100644 index 000000000000..f8cf06ec46e1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_op_toplevel_inconsistent_output_type.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_op_toplevel_inconsistent_output_type.tz] + +exprurrbjDgnipRBhqb7pPLQFAgtPm5jrpwJjJL5ZvQyFJZzGvqteY diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_rec.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_rec.tz].out new file mode 100644 index 000000000000..b16b6437f6fd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_rec.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_rec.tz] + +exprvSPcq1w7iTMA3LjQcHegnRUQ621sqQLRJm1Zh4tjHCkmeZV268 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_toplevel_lib.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_toplevel_lib.tz].out new file mode 100644 index 000000000000..a9ab2c1b772f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[opcodes--view_toplevel_lib.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract.py::TestScriptHashRegression::test_contract_hash[opcodes/view_toplevel_lib.tz] + +exprv1LkSMvSyZSBrg9Tf2PdcoiWDYPz2npmYb7rH6bWx2sYMAHMgg diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_receiver.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_receiver.out new file mode 100644 index 000000000000..56b8f1f52cca --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_receiver.out @@ -0,0 +1,53 @@ +tests_012/test_contract.py::TestSelfAddressTransfer::test_self_address_originate_receiver + +Node is bootstrapped. +Estimated gas: 1413.723 units (will add 100 for safety) +Estimated storage: 340 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000462 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1514 + Storage limit: 360 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000462 + payload fees(the block proposer) ....... +ꜩ0.000462 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ0 + Script: + { parameter (lambda unit address) ; + storage unit ; + code { UNPAIR ; + UNIT ; + EXEC ; + SELF_ADDRESS ; + ASSERT_CMPEQ ; + NIL operation ; + PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 83 bytes + Paid storage size diff: 83 bytes + Consumed gas: 1413.723 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.02075 + storage fees ........................... +ꜩ0.02075 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as self_address_receiver. +Injected block at minimal timestamp +[ [ "[BLOCK_HASH]" ], [], [], + [ "[BLOCK_HASH]" ] ] diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_sender.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_sender.out new file mode 100644 index 000000000000..6bd21b2b7f5e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_self_address_originate_sender.out @@ -0,0 +1,52 @@ +tests_012/test_contract.py::TestSelfAddressTransfer::test_self_address_originate_sender + +Node is bootstrapped. +Estimated gas: 1413.674 units (will add 100 for safety) +Estimated storage: 339 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000461 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1514 + Storage limit: 359 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000461 + payload fees(the block proposer) ....... +ꜩ0.000461 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ0 + Script: + { parameter (contract (lambda unit address)) ; + storage unit ; + code { CAR ; + BALANCE ; + LAMBDA unit address { DROP ; SELF_ADDRESS } ; + TRANSFER_TOKENS ; + DIP { UNIT ; NIL operation } ; + CONS ; + PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 82 bytes + Paid storage size diff: 82 bytes + Consumed gas: 1413.674 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0205 + storage fees ........................... +ꜩ0.0205 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as self_address_sender. +Injected block at minimal timestamp +[ [], [], [], [ "[BLOCK_HASH]" ] ] diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_send_self_address.out b/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_send_self_address.out new file mode 100644 index 000000000000..8532ebd1d96d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestSelfAddressTransfer::test_send_self_address.out @@ -0,0 +1,42 @@ +tests_012/test_contract.py::TestSelfAddressTransfer::test_send_self_address + +Node is bootstrapped. +Estimated gas: 5413.006 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000846 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 5514 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000846 + payload fees(the block proposer) ....... +ꜩ0.000846 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: "[CONTRACT_HASH]" + This transaction was successfully applied + Updated storage: Unit + Storage size: 82 bytes + Consumed gas: 3353.748 + Internal operations: + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: { DROP ; SELF_ADDRESS } + This transaction was successfully applied + Updated storage: Unit + Storage size: 83 bytes + Consumed gas: 2059.258 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--accounts.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--accounts.tz].out new file mode 100644 index 000000000000..51db6b263fa1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--accounts.tz].out @@ -0,0 +1,379 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/accounts.tz] + +Well typed +Gas remaining: 1039925.145 units remaining +{ parameter + (or (key_hash %Initialize) + (pair %Withdraw (key %from) (pair (mutez %withdraw_amount) (signature %sig)))) ; + storage (map :stored_balance key_hash mutez) ; + code { DUP + /* [ pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + CAR + /* [ @parameter or (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig)) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + IF_LEFT + { DUP + /* [ @parameter.Initialize key_hash : @parameter.Initialize key_hash + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + DIIP { CDR %stored_balance + /* [ @stored_balance map :stored_balance key_hash mutez ] */ ; + DUP + /* [ @stored_balance map :stored_balance key_hash mutez + : @stored_balance map :stored_balance key_hash mutez ] */ } + /* [ @parameter.Initialize key_hash : @parameter.Initialize key_hash + : @stored_balance map :stored_balance key_hash mutez + : @stored_balance map :stored_balance key_hash mutez ] */ ; + DIP { SWAP + /* [ @stored_balance map :stored_balance key_hash mutez + : @parameter.Initialize key_hash + : @stored_balance map :stored_balance key_hash mutez ] */ } + /* [ @parameter.Initialize key_hash + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Initialize key_hash + : @stored_balance map :stored_balance key_hash mutez ] */ ; + GET @opt_prev_balance + /* [ @opt_prev_balance option mutez : @parameter.Initialize key_hash + : @stored_balance map :stored_balance key_hash mutez ] */ ; + IF_SOME + { RENAME @previous_balance + /* [ @previous_balance mutez : @parameter.Initialize key_hash + : @stored_balance map :stored_balance key_hash mutez ] */ ; + AMOUNT + /* [ @amount mutez : @previous_balance mutez : @parameter.Initialize key_hash + : @stored_balance map :stored_balance key_hash mutez ] */ ; + ADD + /* [ mutez : @parameter.Initialize key_hash + : @stored_balance map :stored_balance key_hash mutez ] */ ; + SOME + /* [ option mutez : @parameter.Initialize key_hash + : @stored_balance map :stored_balance key_hash mutez ] */ ; + SWAP + /* [ @parameter.Initialize key_hash : option mutez + : @stored_balance map :stored_balance key_hash mutez ] */ ; + UPDATE + /* [ @stored_balance map :stored_balance key_hash mutez ] */ ; + NIL operation + /* [ list operation : @stored_balance map :stored_balance key_hash mutez ] */ ; + PAIR + /* [ pair (list operation) (map :stored_balance @stored_balance key_hash mutez) ] */ } + { DIP { AMOUNT + /* [ @amount mutez : @stored_balance map :stored_balance key_hash mutez ] */ ; + SOME + /* [ option mutez : @stored_balance map :stored_balance key_hash mutez ] */ } + /* [ @parameter.Initialize key_hash : option mutez + : @stored_balance map :stored_balance key_hash mutez ] */ ; + UPDATE + /* [ @stored_balance map :stored_balance key_hash mutez ] */ ; + NIL operation + /* [ list operation : @stored_balance map :stored_balance key_hash mutez ] */ ; + PAIR + /* [ pair (list operation) (map :stored_balance @stored_balance key_hash mutez) ] */ } } + { DUP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + DUP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + DUP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + DUP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + CAR %from + /* [ key + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + DIIP { CDAR %withdraw_amount ; + PACK + /* [ @packed bytes + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + BLAKE2B @signed_amount + /* [ @signed_amount bytes + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ } + /* [ key + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @signed_amount bytes + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + DIP { CDDR %sig } + /* [ key : signature : @signed_amount bytes + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + CHECK_SIGNATURE + /* [ bool + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + IF { /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ } + { PUSH string + "Bad signature" + /* [ string + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : pair (or @parameter + (key_hash %Initialize) + (pair %Withdraw (key %from) (mutez %withdraw_amount) (signature %sig))) + (map :stored_balance @stored_balance key_hash mutez) ] */ ; + FAILWITH + /* [] */ } ; + DIIP { CDR %stored_balance + /* [ @stored_balance map :stored_balance key_hash mutez ] */ ; + DUP + /* [ @stored_balance map :stored_balance key_hash mutez + : @stored_balance map :stored_balance key_hash mutez ] */ } + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @stored_balance map :stored_balance key_hash mutez ] */ ; + CAR %from + /* [ key + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @stored_balance map :stored_balance key_hash mutez ] */ ; + HASH_KEY @from_hash + /* [ @from_hash key_hash + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @stored_balance map :stored_balance key_hash mutez ] */ ; + DUP + /* [ @from_hash key_hash : @from_hash key_hash + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @stored_balance map :stored_balance key_hash mutez ] */ ; + DIP { DIP { SWAP + /* [ @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ } + /* [ @from_hash key_hash : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + SWAP + /* [ @stored_balance map :stored_balance key_hash mutez : @from_hash key_hash + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ } + /* [ @from_hash key_hash : @stored_balance map :stored_balance key_hash mutez + : @from_hash key_hash + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + GET + /* [ option mutez : @from_hash key_hash + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + IF_NONE + { PUSH string + "Account does not exist" + /* [ string : @from_hash key_hash + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + PAIR + /* [ pair string (key_hash @from_hash) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + FAILWITH + /* [] */ } + { RENAME @previous_balance + /* [ @previous_balance mutez : @from_hash key_hash + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + DIP { DROP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ } + /* [ @previous_balance mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + DUP + /* [ @previous_balance mutez : @previous_balance mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + DIIP { DUP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + CDAR %withdraw_amount ; + DUP + /* [ mutez : mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ } + /* [ @previous_balance mutez : @previous_balance mutez : mutez : mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + DIP { CMPLT @not_enough } + /* [ @previous_balance mutez : @not_enough bool : mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + SWAP + /* [ @not_enough bool : @previous_balance mutez : mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + IF { PUSH string + "Not enough funds" + /* [ string : @previous_balance mutez : mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + FAILWITH + /* [] */ } + { SUB_MUTEZ @new_balance + /* [ @new_balance option mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + ASSERT_SOME ; + DIP { DUP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + DIP { SWAP + /* [ @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ } + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ } + /* [ @new_balance.some mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; + DUP + /* [ @new_balance.some mutez : @new_balance.some mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; + PUSH @zero + mutez + 0 + /* [ @zero mutez : @new_balance.some mutez : @new_balance.some mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; + CMPEQ @null_balance ; + IF { DROP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; + NONE @new_balance + mutez + /* [ @new_balance option mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ } + { SOME @new_balance + /* [ @new_balance option mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ } ; + SWAP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @new_balance option mutez + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; + CAR %from + /* [ key : @new_balance option mutez + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; + HASH_KEY @from_hash + /* [ @from_hash key_hash : @new_balance option mutez + : @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; + UPDATE + /* [ @stored_balance map :stored_balance key_hash mutez + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) ] */ ; + SWAP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + DUP + /* [ @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @parameter.Withdraw pair (key %from) (mutez %withdraw_amount) (signature %sig) + : @stored_balance map :stored_balance key_hash mutez ] */ ; + CDAR %withdraw_amount ; + DIP { CAR %from + /* [ key : @stored_balance map :stored_balance key_hash mutez ] */ ; + HASH_KEY @from_hash + /* [ @from_hash key_hash : @stored_balance map :stored_balance key_hash mutez ] */ ; + IMPLICIT_ACCOUNT @from_account + /* [ @from_account contract unit + : @stored_balance map :stored_balance key_hash mutez ] */ } + /* [ mutez : @from_account contract unit + : @stored_balance map :stored_balance key_hash mutez ] */ ; + UNIT + /* [ unit : mutez : @from_account contract unit + : @stored_balance map :stored_balance key_hash mutez ] */ ; + TRANSFER_TOKENS @withdraw_transfer_op + /* [ @withdraw_transfer_op operation + : @stored_balance map :stored_balance key_hash mutez ] */ ; + NIL operation + /* [ list operation : @withdraw_transfer_op operation + : @stored_balance map :stored_balance key_hash mutez ] */ ; + SWAP + /* [ @withdraw_transfer_op operation : list operation + : @stored_balance map :stored_balance key_hash mutez ] */ ; + CONS + /* [ list operation : @stored_balance map :stored_balance key_hash mutez ] */ ; + PAIR + /* [ pair (list operation) (map :stored_balance @stored_balance key_hash mutez) ] */ } } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1.tz].out new file mode 100644 index 000000000000..718ebecbfef5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/add1.tz] + +Well typed +Gas remaining: 1039996.134 units remaining +{ parameter int ; + storage int ; + code { CAR + /* [ @parameter int ] */ ; + PUSH int 1 + /* [ int : @parameter int ] */ ; + ADD + /* [ int ] */ ; + NIL operation + /* [ list operation : int ] */ ; + PAIR + /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1_list.tz].out new file mode 100644 index 000000000000..b82e5d9c4955 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--add1_list.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/add1_list.tz] + +Well typed +Gas remaining: 1039995.173 units remaining +{ parameter (list int) ; + storage (list int) ; + code { CAR + /* [ @parameter list int ] */ ; + MAP { PUSH int 1 /* [ int : @parameter.elt int ] */ ; ADD /* [ int ] */ } + /* [ list int ] */ ; + NIL operation + /* [ list operation : list int ] */ ; + PAIR + /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--after_strategy.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--after_strategy.tz].out new file mode 100644 index 000000000000..bb2a0fcd46b0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--after_strategy.tz].out @@ -0,0 +1,27 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/after_strategy.tz] + +Well typed +Gas remaining: 1039989.643 units remaining +{ parameter nat ; + storage (pair (pair nat bool) timestamp) ; + code { DUP + /* [ pair (nat @parameter) (pair @storage (pair nat bool) timestamp) + : pair (nat @parameter) (pair @storage (pair nat bool) timestamp) ] */ ; + CAR + /* [ @parameter nat + : pair (nat @parameter) (pair @storage (pair nat bool) timestamp) ] */ ; + DIP { CDDR ; + DUP + /* [ timestamp : timestamp ] */ ; + NOW + /* [ @now timestamp : timestamp : timestamp ] */ ; + CMPGT } + /* [ @parameter nat : bool : timestamp ] */ ; + PAIR + /* [ pair (nat @parameter) bool : timestamp ] */ ; + PAIR + /* [ pair (pair (nat @parameter) bool) timestamp ] */ ; + NIL operation + /* [ list operation : pair (pair (nat @parameter) bool) timestamp ] */ ; + PAIR + /* [ pair (list operation) (pair (nat @parameter) bool) timestamp ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--always.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--always.tz].out new file mode 100644 index 000000000000..6c9c14fd13e0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--always.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/always.tz] + +Well typed +Gas remaining: 1039994.981 units remaining +{ parameter nat ; + storage (pair nat bool) ; + code { CAR + /* [ @parameter nat ] */ ; + PUSH bool True + /* [ bool : @parameter nat ] */ ; + SWAP + /* [ @parameter nat : bool ] */ ; + PAIR + /* [ pair (nat @parameter) bool ] */ ; + NIL operation + /* [ list operation : pair (nat @parameter) bool ] */ ; + PAIR + /* [ pair (list operation) (nat @parameter) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--append.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--append.tz].out new file mode 100644 index 000000000000..db0f1320bc3a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--append.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/append.tz] + +Well typed +Gas remaining: 1039991.379 units remaining +{ parameter (pair (list int) (list int)) ; + storage (list int) ; + code { CAR + /* [ @parameter pair (list int) (list int) ] */ ; + UNPAIR + /* [ list int : list int ] */ ; + NIL int + /* [ list int : list int : list int ] */ ; + SWAP + /* [ list int : list int : list int ] */ ; + ITER { CONS /* [ list int : list int ] */ } + /* [ list int : list int ] */ ; + ITER { CONS /* [ list int ] */ } + /* [ list int ] */ ; + NIL operation + /* [ list operation : list int ] */ ; + PAIR + /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--at_least.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--at_least.tz].out new file mode 100644 index 000000000000..d86bc2879271 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--at_least.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/at_least.tz] + +Well typed +Gas remaining: 1039992.950 units remaining +{ parameter unit ; + storage mutez ; + code { CDR + /* [ @storage mutez ] */ ; + DUP + /* [ @storage mutez : @storage mutez ] */ ; + AMOUNT + /* [ @amount mutez : @storage mutez : @storage mutez ] */ ; + CMPLT ; + IF { FAIL } + { NIL operation + /* [ list operation : @storage mutez ] */ ; + PAIR + /* [ pair (list operation) (mutez @storage) ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--auction.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--auction.tz].out new file mode 100644 index 000000000000..7d56aeb3cdb4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--auction.tz].out @@ -0,0 +1,87 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/auction.tz] + +Well typed +Gas remaining: 1039972.258 units remaining +{ parameter key_hash ; + storage (pair timestamp (pair mutez key_hash)) ; + code { DUP + /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; + CDAR ; + DUP + /* [ timestamp : timestamp + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; + NOW + /* [ @now timestamp : timestamp : timestamp + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; + CMPGT ; + IF { FAIL } + { /* [ timestamp + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ } ; + SWAP + /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) + : timestamp ] */ ; + DUP + /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) + : timestamp ] */ ; + CAR + /* [ @parameter key_hash + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) + : timestamp ] */ ; + DIP { CDDR } + /* [ @parameter key_hash : pair mutez key_hash : timestamp ] */ ; + AMOUNT + /* [ @amount mutez : @parameter key_hash : pair mutez key_hash : timestamp ] */ ; + PAIR + /* [ pair (mutez @amount) (key_hash @parameter) : pair mutez key_hash + : timestamp ] */ ; + SWAP + /* [ pair mutez key_hash : pair (mutez @amount) (key_hash @parameter) + : timestamp ] */ ; + DIP { SWAP + /* [ timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; + PAIR + /* [ pair timestamp (mutez @amount) (key_hash @parameter) ] */ } + /* [ pair mutez key_hash + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + DUP + /* [ pair mutez key_hash : pair mutez key_hash + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + CAR + /* [ mutez : pair mutez key_hash + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + AMOUNT + /* [ @amount mutez : mutez : pair mutez key_hash + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + CMPLE ; + IF { FAIL } + { /* [ pair mutez key_hash + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ } ; + DUP + /* [ pair mutez key_hash : pair mutez key_hash + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + CAR + /* [ mutez : pair mutez key_hash + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + DIP { CDR + /* [ key_hash : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + IMPLICIT_ACCOUNT + /* [ contract unit : pair timestamp (mutez @amount) (key_hash @parameter) ] */ } + /* [ mutez : contract unit + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + UNIT + /* [ unit : mutez : contract unit + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + TRANSFER_TOKENS + /* [ operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + NIL operation + /* [ list operation : operation + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + SWAP + /* [ operation : list operation + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + CONS + /* [ list operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + PAIR + /* [ pair (list operation) timestamp (mutez @amount) (key_hash @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--bad_lockup.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--bad_lockup.tz].out new file mode 100644 index 000000000000..8596f4336905 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--bad_lockup.tz].out @@ -0,0 +1,71 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/bad_lockup.tz] + +Well typed +Gas remaining: 1039972.793 units remaining +{ parameter unit ; + storage (pair timestamp (pair address address)) ; + code { CDR + /* [ @storage pair timestamp address address ] */ ; + DUP + /* [ @storage pair timestamp address address + : @storage pair timestamp address address ] */ ; + CAR + /* [ timestamp : @storage pair timestamp address address ] */ ; + NOW + /* [ @now timestamp : timestamp : @storage pair timestamp address address ] */ ; + CMPLT ; + IF { FAIL } { /* [ @storage pair timestamp address address ] */ } ; + DUP + /* [ @storage pair timestamp address address + : @storage pair timestamp address address ] */ ; + CDAR ; + CONTRACT + unit + /* [ @contract option (contract unit) + : @storage pair timestamp address address ] */ ; + ASSERT_SOME ; + PUSH mutez + 100000000 + /* [ mutez : @contract.some contract unit + : @storage pair timestamp address address ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : @storage pair timestamp address address ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage pair timestamp address address ] */ ; + SWAP + /* [ @storage pair timestamp address address : operation ] */ ; + DUP + /* [ @storage pair timestamp address address + : @storage pair timestamp address address : operation ] */ ; + CDDR ; + CONTRACT + unit + /* [ @contract option (contract unit) : @storage pair timestamp address address + : operation ] */ ; + ASSERT_SOME ; + PUSH mutez + 100000000 + /* [ mutez : @contract.some contract unit + : @storage pair timestamp address address : operation ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : @storage pair timestamp address address : operation ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage pair timestamp address address : operation ] */ ; + DIP { SWAP /* [ operation : @storage pair timestamp address address ] */ } + /* [ operation : operation : @storage pair timestamp address address ] */ ; + NIL operation + /* [ list operation : operation : operation + : @storage pair timestamp address address ] */ ; + SWAP + /* [ operation : list operation : operation + : @storage pair timestamp address address ] */ ; + CONS + /* [ list operation : operation : @storage pair timestamp address address ] */ ; + SWAP + /* [ operation : list operation : @storage pair timestamp address address ] */ ; + CONS + /* [ list operation : @storage pair timestamp address address ] */ ; + PAIR + /* [ pair (list operation) (pair @storage timestamp address address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--big_map_union.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--big_map_union.tz].out new file mode 100644 index 000000000000..f10b57e00aad --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--big_map_union.tz].out @@ -0,0 +1,34 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/big_map_union.tz] + +Well typed +Gas remaining: 1039983.939 units remaining +{ parameter (list (pair string int)) ; + storage (pair (big_map string int) unit) ; + code { UNPAPAIR ; + ITER { UNPAIR + /* [ string : int : big_map string int : unit ] */ ; + DUUUP + /* [ big_map string int : string : int : big_map string int : unit ] */ ; + DUUP + /* [ string : big_map string int : string : int : big_map string int : unit ] */ ; + GET + /* [ option int : string : int : big_map string int : unit ] */ ; + IF_NONE + { PUSH int 0 /* [ int : string : int : big_map string int : unit ] */ } + { /* [ @some int : string : int : big_map string int : unit ] */ } ; + SWAP + /* [ string : int : int : big_map string int : unit ] */ ; + DIP { ADD + /* [ int : big_map string int : unit ] */ ; + SOME + /* [ option int : big_map string int : unit ] */ } + /* [ string : option int : big_map string int : unit ] */ ; + UPDATE + /* [ big_map string int : unit ] */ } + /* [ big_map string int : unit ] */ ; + PAIR + /* [ pair (big_map string int) unit ] */ ; + NIL operation + /* [ list operation : pair (big_map string int) unit ] */ ; + PAIR + /* [ pair (list operation) (big_map string int) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cadr_annotation.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cadr_annotation.tz].out new file mode 100644 index 000000000000..c9209094fe5c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cadr_annotation.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/cadr_annotation.tz] + +Well typed +Gas remaining: 1039994.745 units remaining +{ parameter (pair (pair %p1 unit (string %no_name)) bool) ; + storage unit ; + code { CAR @param + /* [ @param pair (pair %p1 unit (string %no_name)) bool ] */ ; + CADR @name %no_name ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--concat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--concat.tz].out new file mode 100644 index 000000000000..c69756696c96 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--concat.tz].out @@ -0,0 +1,28 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/concat.tz] + +Well typed +Gas remaining: 1039992.618 units remaining +{ parameter string ; + storage string ; + code { DUP + /* [ pair (string @parameter) (string @storage) + : pair (string @parameter) (string @storage) ] */ ; + DIP { CDR + /* [ @storage string ] */ ; + NIL string + /* [ list string : @storage string ] */ ; + SWAP + /* [ @storage string : list string ] */ ; + CONS + /* [ list string ] */ } + /* [ pair (string @parameter) (string @storage) : list string ] */ ; + CAR + /* [ @parameter string : list string ] */ ; + CONS + /* [ list string ] */ ; + CONCAT + /* [ string ] */ ; + NIL operation + /* [ list operation : string ] */ ; + PAIR + /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--conditionals.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--conditionals.tz].out new file mode 100644 index 000000000000..20a0e7c2c13f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--conditionals.tz].out @@ -0,0 +1,20 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/conditionals.tz] + +Well typed +Gas remaining: 1039989.496 units remaining +{ parameter (or string (option int)) ; + storage string ; + code { CAR + /* [ @parameter or string (option int) ] */ ; + IF_LEFT + { /* [ @parameter.left string ] */ } + { IF_NONE + { FAIL } + { PUSH int 0 + /* [ int : @parameter.right.some int ] */ ; + CMPGT ; + IF { FAIL } { PUSH string "" /* [ string ] */ } } } ; + NIL operation + /* [ list operation : string ] */ ; + PAIR + /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cons_twice.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cons_twice.tz].out new file mode 100644 index 000000000000..9d2c7873c26b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cons_twice.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/cons_twice.tz] + +Well typed +Gas remaining: 1039992.638 units remaining +{ parameter nat ; + storage (list nat) ; + code { DUP + /* [ pair (nat @parameter) (list @storage nat) + : pair (nat @parameter) (list @storage nat) ] */ ; + CAR + /* [ @parameter nat : pair (nat @parameter) (list @storage nat) ] */ ; + DIP { CDR /* [ @storage list nat ] */ } + /* [ @parameter nat : @storage list nat ] */ ; + DUP + /* [ @parameter nat : @parameter nat : @storage list nat ] */ ; + DIP { CONS /* [ list nat ] */ } + /* [ @parameter nat : list nat ] */ ; + CONS + /* [ list nat ] */ ; + NIL operation + /* [ list operation : list nat ] */ ; + PAIR + /* [ pair (list operation) (list nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cps_fact.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cps_fact.tz].out new file mode 100644 index 000000000000..afd574b441d9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--cps_fact.tz].out @@ -0,0 +1,71 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/cps_fact.tz] + +Well typed +Gas remaining: 1039973.219 units remaining +{ storage nat ; + parameter nat ; + code { UNPAIR + /* [ @parameter nat : @storage nat ] */ ; + DIP { SELF + /* [ @self contract nat : @storage nat ] */ ; + ADDRESS + /* [ @self.address address : @storage nat ] */ ; + SENDER + /* [ @sender address : @self.address address : @storage nat ] */ ; + IFCMPEQ + { /* [ @storage nat ] */ } + { DROP /* [] */ ; PUSH @storage nat 1 /* [ @storage nat ] */ } } + /* [ @parameter nat : @storage nat ] */ ; + DUP + /* [ @parameter nat : @parameter nat : @storage nat ] */ ; + PUSH nat 1 + /* [ nat : @parameter nat : @parameter nat : @storage nat ] */ ; + IFCMPGE + { DROP + /* [ @storage nat ] */ ; + NIL operation + /* [ list operation : @storage nat ] */ ; + PAIR + /* [ pair (list operation) (nat @storage) ] */ } + { PUSH nat 1 + /* [ nat : @parameter nat : @storage nat ] */ ; + SWAP + /* [ @parameter nat : nat : @storage nat ] */ ; + SUB @parameter + /* [ @parameter int : @storage nat ] */ ; + ISNAT + /* [ @parameter option nat : @storage nat ] */ ; + IF_NONE + { NIL operation + /* [ list operation : @storage nat ] */ ; + PAIR + /* [ pair (list operation) (nat @storage) ] */ } + { DUP + /* [ @parameter.some nat : @parameter.some nat : @storage nat ] */ ; + DIP { PUSH nat 1 + /* [ nat : @parameter.some nat : @storage nat ] */ ; + ADD + /* [ nat : @storage nat ] */ ; + MUL @storage + /* [ @storage nat ] */ } + /* [ @parameter.some nat : @storage nat ] */ ; + SWAP + /* [ @storage nat : @parameter.some nat ] */ ; + DIP { DIP { SELF + /* [ @self contract nat ] */ ; + PUSH mutez 0 + /* [ mutez : @self contract nat ] */ } + /* [ @parameter.some nat : mutez : @self contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + NIL operation + /* [ list operation : operation ] */ ; + SWAP + /* [ operation : list operation ] */ ; + CONS + /* [ list operation ] */ } + /* [ @storage nat : list operation ] */ ; + SWAP + /* [ list operation : @storage nat ] */ ; + PAIR + /* [ pair (list operation) (nat @storage) ] */ } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--create_add1_lists.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--create_add1_lists.tz].out new file mode 100644 index 000000000000..c6541faf298f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--create_add1_lists.tz].out @@ -0,0 +1,30 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/create_add1_lists.tz] + +Well typed +Gas remaining: 1039986.470 units remaining +{ parameter unit ; + storage address ; + code { DROP + /* [] */ ; + NIL int /* [ @parameter list int ] */ + /* [ list int ] */ ; + AMOUNT + /* [ list int ] */ ; + NONE key_hash + /* [ int : @parameter.elt int ] */ + /* [ option key_hash : @amount mutez : list int ] */ ; + CREATE_CONTRACT + { parameter (list int /* [ list operation : list int ] */) + /* [ int ] */ ; + storage (list int) + /* [ pair (list operation) (list int) ] */ ; + code { CAR ; MAP { PUSH int 1 ; ADD } ; NIL operation ; PAIR } } + /* [ operation : address ] */ ; + NIL operation + /* [ list operation : operation : address ] */ ; + SWAP + /* [ operation : list operation : address ] */ ; + CONS + /* [ list operation : address ] */ ; + PAIR + /* [ pair (list operation) address ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--data_publisher.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--data_publisher.tz].out new file mode 100644 index 000000000000..f8f6cb6d73d3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--data_publisher.tz].out @@ -0,0 +1,80 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/data_publisher.tz] + +Well typed +Gas remaining: 1039974.524 units remaining +{ parameter (pair signature (pair string nat)) ; + storage (pair (pair key nat) string) ; + code { DUP + /* [ pair (pair @parameter signature string nat) (pair @storage (pair key nat) string) + : pair (pair @parameter signature string nat) (pair @storage (pair key nat) string) ] */ ; + CAR + /* [ @parameter pair signature string nat + : pair (pair @parameter signature string nat) (pair @storage (pair key nat) string) ] */ ; + DIP { CDR + /* [ @storage pair (pair key nat) string ] */ ; + DUP + /* [ @storage pair (pair key nat) string : @storage pair (pair key nat) string ] */ } + /* [ @parameter pair signature string nat : @storage pair (pair key nat) string + : @storage pair (pair key nat) string ] */ ; + SWAP + /* [ @storage pair (pair key nat) string : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ ; + DIP { DUP + /* [ @parameter pair signature string nat : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ } + /* [ @storage pair (pair key nat) string : @parameter pair signature string nat + : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ ; + CAAR ; + DIP { DUP + /* [ @parameter pair signature string nat : @parameter pair signature string nat + : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ ; + CAR + /* [ signature : @parameter pair signature string nat + : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ ; + DIP { CDR + /* [ pair string nat : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ ; + PACK + /* [ @packed bytes : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ ; + BLAKE2B + /* [ bytes : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ } + /* [ signature : bytes : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ } + /* [ key : signature : bytes : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ ; + CHECK_SIGNATURE + /* [ bool : @parameter pair signature string nat + : @storage pair (pair key nat) string ] */ ; + IF { CDR + /* [ pair string nat : @storage pair (pair key nat) string ] */ ; + DUP + /* [ pair string nat : pair string nat : @storage pair (pair key nat) string ] */ ; + DIP { CAR + /* [ string : @storage pair (pair key nat) string ] */ ; + DIP { CAAR } + /* [ string : key ] */ } + /* [ pair string nat : string : key ] */ ; + CDR + /* [ nat : string : key ] */ ; + PUSH nat 1 + /* [ nat : nat : string : key ] */ ; + ADD + /* [ nat : string : key ] */ ; + DIP { SWAP /* [ key : string ] */ } + /* [ nat : key : string ] */ ; + SWAP + /* [ key : nat : string ] */ ; + PAIR + /* [ pair key nat : string ] */ ; + PAIR + /* [ pair (pair key nat) string ] */ ; + NIL operation + /* [ list operation : pair (pair key nat) string ] */ ; + PAIR + /* [ pair (list operation) (pair key nat) string ] */ } + { FAIL } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--dispatch.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--dispatch.tz].out new file mode 100644 index 000000000000..d01aabf96e55 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--dispatch.tz].out @@ -0,0 +1,54 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/dispatch.tz] + +Well typed +Gas remaining: 1039979.486 units remaining +{ parameter (or string (pair string (lambda unit string))) ; + storage (pair string (map string (lambda unit string))) ; + code { DUP + /* [ pair (or @parameter string (pair string (lambda unit string))) + (pair @storage string (map string (lambda unit string))) + : pair (or @parameter string (pair string (lambda unit string))) + (pair @storage string (map string (lambda unit string))) ] */ ; + DIP { CDDR } + /* [ pair (or @parameter string (pair string (lambda unit string))) + (pair @storage string (map string (lambda unit string))) + : map string (lambda unit string) ] */ ; + CAR + /* [ @parameter or string (pair string (lambda unit string)) + : map string (lambda unit string) ] */ ; + IF_LEFT + { DIP { DUP + /* [ map string (lambda unit string) : map string (lambda unit string) ] */ } + /* [ @parameter.left string : map string (lambda unit string) + : map string (lambda unit string) ] */ ; + GET + /* [ option (lambda unit string) : map string (lambda unit string) ] */ ; + IF_NONE + { FAIL } + { /* [ @some lambda unit string : map string (lambda unit string) ] */ } ; + UNIT + /* [ unit : @some lambda unit string : map string (lambda unit string) ] */ ; + EXEC + /* [ string : map string (lambda unit string) ] */ } + { DUP + /* [ @parameter.right pair string (lambda unit string) + : @parameter.right pair string (lambda unit string) + : map string (lambda unit string) ] */ ; + CAR + /* [ string : @parameter.right pair string (lambda unit string) + : map string (lambda unit string) ] */ ; + DIP { CDR + /* [ lambda unit string : map string (lambda unit string) ] */ ; + SOME + /* [ option (lambda unit string) : map string (lambda unit string) ] */ } + /* [ string : option (lambda unit string) : map string (lambda unit string) ] */ ; + UPDATE + /* [ map string (lambda unit string) ] */ ; + PUSH string "" + /* [ string : map string (lambda unit string) ] */ } ; + PAIR + /* [ pair string (map string (lambda unit string)) ] */ ; + NIL operation + /* [ list operation : pair string (map string (lambda unit string)) ] */ ; + PAIR + /* [ pair (list operation) string (map string (lambda unit string)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--empty.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--empty.tz].out new file mode 100644 index 000000000000..fde466977ab8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--empty.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/empty.tz] + +Well typed +Gas remaining: 1039997.267 units remaining +{ parameter unit ; + storage unit ; + code { CDR + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--fail_amount.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--fail_amount.tz].out new file mode 100644 index 000000000000..bf7624331dca --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--fail_amount.tz].out @@ -0,0 +1,20 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/fail_amount.tz] + +Well typed +Gas remaining: 1039992.147 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + AMOUNT + /* [ @amount mutez ] */ ; + PUSH mutez 10000000 + /* [ mutez : @amount mutez ] */ ; + CMPGT ; + IF { FAIL } { /* [] */ } ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--faucet.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--faucet.tz].out new file mode 100644 index 000000000000..8f95fb90cc79 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--faucet.tz].out @@ -0,0 +1,35 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/faucet.tz] + +Well typed +Gas remaining: 1039986.830 units remaining +{ parameter key_hash ; + storage timestamp ; + code { UNPAIR + /* [ @parameter key_hash : @storage timestamp ] */ ; + SWAP + /* [ @storage timestamp : @parameter key_hash ] */ ; + PUSH int 300 + /* [ int : @storage timestamp : @parameter key_hash ] */ ; + ADD @FIVE_MINUTES_LATER + /* [ @FIVE_MINUTES_LATER timestamp : @parameter key_hash ] */ ; + NOW + /* [ @now timestamp : @FIVE_MINUTES_LATER timestamp : @parameter key_hash ] */ ; + ASSERT_CMPGE ; + IMPLICIT_ACCOUNT + /* [ contract unit ] */ ; + PUSH mutez 1000000 + /* [ mutez : contract unit ] */ ; + UNIT + /* [ unit : mutez : contract unit ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + NIL operation + /* [ list operation : operation ] */ ; + SWAP + /* [ operation : list operation ] */ ; + CONS + /* [ list operation ] */ ; + DIP { NOW /* [ @now timestamp ] */ } + /* [ list operation : @now timestamp ] */ ; + PAIR + /* [ pair (list operation) (timestamp @now) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--forward.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--forward.tz].out new file mode 100644 index 000000000000..1af409e2f7f6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--forward.tz].out @@ -0,0 +1,1920 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/forward.tz] + +Well typed +Gas remaining: 1039634.172 units remaining +{ parameter (or string nat) ; + storage + (pair (pair nat (pair mutez mutez)) + (pair (pair nat (pair timestamp timestamp)) + (pair (pair mutez mutez) (pair (pair address address) address)))) ; + code { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDADDR ; + PUSH int + 86400 + /* [ int : timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + SWAP + /* [ timestamp : int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + ADD + /* [ timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + NOW + /* [ @now timestamp : timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + LT + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CAR + /* [ @parameter or string nat + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF_LEFT + { DUP + /* [ @parameter.left string : @parameter.left string + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PUSH string + "buyer" + /* [ string : @parameter.left string : @parameter.left string + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int : @parameter.left string + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + EQ + /* [ bool : @parameter.left string + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { DROP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDADAR ; + DIP { AMOUNT + /* [ @amount mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } + /* [ mutez : @amount mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + ADD + /* [ mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDADDR } + /* [ mutez : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PAIR + /* [ pair mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PUSH nat + 0 + /* [ nat : pair mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PAIR + /* [ pair nat mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { CDDR } + /* [ pair nat mutez mutez + : pair (pair nat timestamp timestamp) (pair mutez mutez) (pair address address) address ] */ ; + PAIR + /* [ pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + NIL operation + /* [ list operation + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + PAIR + /* [ pair (list operation) + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } + { PUSH string + "seller" + /* [ string : @parameter.left string + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + EQ + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDADDR ; + DIP { AMOUNT + /* [ @amount mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } + /* [ mutez : @amount mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + ADD + /* [ mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDADAR } + /* [ mutez : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + SWAP + /* [ mutez : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PAIR + /* [ pair mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PUSH nat + 0 + /* [ nat : pair mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PAIR + /* [ pair nat mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { CDDR } + /* [ pair nat mutez mutez + : pair (pair nat timestamp timestamp) (pair mutez mutez) (pair address address) address ] */ ; + PAIR + /* [ pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + NIL operation + /* [ list operation + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + PAIR + /* [ pair (list operation) + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } + { FAIL } } } + { FAIL } } + { BALANCE + /* [ @balance mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PUSH mutez + 0 + /* [ mutez : @balance mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IFCMPEQ + { FAIL } + { /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } ; + DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDAAR ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDDADR } + /* [ nat : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + MUL + /* [ mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PUSH nat + 2 + /* [ nat : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + MUL + /* [ mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + BALANCE + /* [ @balance mutez : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + LT + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { CDR + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + DUP + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CADAR ; + DIP { DUP + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CDDDAAR } + /* [ mutez : address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + ASSERT_SOME } + /* [ mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + TRANSFER_TOKENS + /* [ operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + NIL operation + /* [ list operation : operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + SWAP + /* [ operation : list operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CONS + /* [ list operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + SWAP + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + DUP + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + CADDR ; + DIP { DUP + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + CDDDADR } + /* [ mutez : address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + ASSERT_SOME } + /* [ mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + SWAP + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : operation : list operation ] */ ; + DIP { CONS /* [ list operation ] */ } + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + DUP + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + CADAR ; + DIP { DUP + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + CADDR } + /* [ mutez : mutez + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + ADD + /* [ mutez + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + BALANCE + /* [ @balance mutez : mutez + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + SUB_MUTEZ + /* [ option mutez + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + ASSERT_SOME ; + DIP { DUP + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + CDDDDR } + /* [ @some mutez : address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + ASSERT_SOME } + /* [ @some mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + UNIT + /* [ unit : @some mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address : list operation ] */ ; + DIP { SWAP + /* [ list operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } + /* [ operation : list operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CONS + /* [ list operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } + { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDADAR ; + NOW + /* [ @now timestamp : timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + LT + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { FAIL } + { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDADAR ; + PUSH int + 86400 + /* [ int : timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + ADD + /* [ timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + NOW + /* [ @now timestamp : timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + LT + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CAR + /* [ @parameter or string nat + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF_LEFT + { PUSH string + "buyer" + /* [ string : @parameter.left string + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + EQ + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDADAR ; + DIP { AMOUNT + /* [ @amount mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } + /* [ mutez : @amount mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + ADD + /* [ mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DUP + /* [ mutez : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDAAR ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDDAAR } + /* [ nat : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + MUL + /* [ mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } + /* [ mutez : mutez : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + GT + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { FAIL } + { /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } } + /* [ mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDADDR } + /* [ mutez : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PAIR + /* [ pair mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PUSH nat + 0 + /* [ nat : pair mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PAIR + /* [ pair nat mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { CDDR } + /* [ pair nat mutez mutez + : pair (pair nat timestamp timestamp) (pair mutez mutez) (pair address address) address ] */ ; + PAIR + /* [ pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + NIL operation + /* [ list operation + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + PAIR + /* [ pair (list operation) + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } + { FAIL } } + { FAIL } } + { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDAAR ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDDAAR } + /* [ nat : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + MUL + /* [ mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDADAR } + /* [ mutez : mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + NEQ + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { BALANCE + /* [ @balance mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDDDADR } + /* [ @balance mutez : address + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIIP { CDR + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } + /* [ @balance mutez : address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + ASSERT_SOME } + /* [ @balance mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + UNIT + /* [ unit : @balance mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + TRANSFER_TOKENS + /* [ operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + NIL operation + /* [ list operation : operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + SWAP + /* [ operation : list operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CONS + /* [ list operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } + { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDADAR ; + PUSH int + 86400 + /* [ int : timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + ADD + /* [ timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PUSH int + 86400 + /* [ int : timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + ADD + /* [ timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + NOW + /* [ @now timestamp : timestamp + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + LT + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDDDDR ; + SENDER + /* [ @sender address : address + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + COMPARE + /* [ int + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + NEQ + /* [ bool + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF { FAIL } + { /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } ; + DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CAR + /* [ @parameter or string nat + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + IF_LEFT + { FAIL } + { DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDAAR } + /* [ @parameter.right nat : nat + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + ADD + /* [ nat + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDADR } + /* [ nat : pair mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + PAIR + /* [ pair nat mutez mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { CDDR } + /* [ pair nat mutez mutez + : pair (pair nat timestamp timestamp) (pair mutez mutez) (pair address address) address ] */ ; + PAIR + /* [ pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + UNIT + /* [ unit + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + PAIR + /* [ pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + DUP + /* [ pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CDAAR ; + DIP { DUP + /* [ pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CDDAAR } + /* [ nat : nat + : pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + COMPARE + /* [ int + : pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + LT + /* [ bool + : pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + IF { CDR + /* [ pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + NIL operation + /* [ list operation + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } + { BALANCE + /* [ @balance mutez + : pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + DIP { DUP + /* [ pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address + : pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CDDDDADR } + /* [ @balance mutez : address + : pair unit + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + DIIP { CDR + /* [ pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } + /* [ @balance mutez : address + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + ASSERT_SOME } + /* [ @balance mutez : @contract.some contract unit + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + UNIT + /* [ unit : @balance mutez : @contract.some contract unit + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + NIL operation + /* [ list operation : operation + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + SWAP + /* [ operation : list operation + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CONS + /* [ list operation + : pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } } ; + PAIR + /* [ pair (list operation) + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } + { BALANCE + /* [ @balance mutez + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIP { DUP + /* [ pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + CDDDDAAR } + /* [ @balance mutez : address + : pair (or @parameter string nat) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ ; + DIIP { CDR + /* [ @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ } + /* [ @balance mutez : address + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + ASSERT_SOME } + /* [ @balance mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + UNIT + /* [ unit : @balance mutez : @contract.some contract unit + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + TRANSFER_TOKENS + /* [ operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + NIL operation + /* [ list operation : operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + SWAP + /* [ operation : list operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + CONS + /* [ list operation + : @storage pair (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage + (pair nat mutez mutez) + (pair nat timestamp timestamp) + (pair mutez mutez) + (pair address address) + address) ] */ } } } } } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--id.tz].out new file mode 100644 index 000000000000..a73e5e8a4ede --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--id.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/id.tz] + +Well typed +Gas remaining: 1039997.267 units remaining +{ parameter string ; + storage string ; + code { CAR + /* [ @parameter string ] */ ; + NIL operation + /* [ list operation : @parameter string ] */ ; + PAIR + /* [ pair (list operation) (string @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--infinite_loop.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--infinite_loop.tz].out new file mode 100644 index 000000000000..07f206951c8a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--infinite_loop.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/infinite_loop.tz] + +Well typed +Gas remaining: 1039994.665 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + PUSH bool True + /* [ bool ] */ ; + LOOP { PUSH bool True /* [ bool ] */ } + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--insertion_sort.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--insertion_sort.tz].out new file mode 100644 index 000000000000..c05247970795 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--insertion_sort.tz].out @@ -0,0 +1,63 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/insertion_sort.tz] + +Well typed +Gas remaining: 1039971.505 units remaining +{ parameter (list int) ; + storage (list int) ; + code { CAR + /* [ @parameter list int ] */ ; + NIL int + /* [ list int : @parameter list int ] */ ; + SWAP + /* [ @parameter list int : list int ] */ ; + ITER { SWAP + /* [ list int : @parameter.elt int ] */ ; + DIIP { NIL int /* [ list int ] */ } + /* [ list int : @parameter.elt int : list int ] */ ; + PUSH bool True + /* [ bool : list int : @parameter.elt int : list int ] */ ; + LOOP { IF_CONS + { SWAP + /* [ @tl list int : @hd int : @parameter.elt int : list int ] */ ; + DIP { DUP + /* [ @hd int : @hd int : @parameter.elt int : list int ] */ ; + DIIP { DUP /* [ @parameter.elt int : @parameter.elt int : list int ] */ } + /* [ @hd int : @hd int : @parameter.elt int : @parameter.elt int : list int ] */ ; + DIP { CMPLT } + /* [ @hd int : bool : @parameter.elt int : list int ] */ ; + SWAP + /* [ bool : @hd int : @parameter.elt int : list int ] */ } + /* [ @tl list int : bool : @hd int : @parameter.elt int : list int ] */ ; + SWAP + /* [ bool : @tl list int : @hd int : @parameter.elt int : list int ] */ ; + IF { DIP { SWAP + /* [ @parameter.elt int : @hd int : list int ] */ ; + DIP { CONS /* [ list int ] */ } + /* [ @parameter.elt int : list int ] */ } + /* [ @tl list int : @parameter.elt int : list int ] */ ; + PUSH bool True + /* [ bool : @tl list int : @parameter.elt int : list int ] */ } + { SWAP + /* [ @hd int : @tl list int : @parameter.elt int : list int ] */ ; + CONS + /* [ list int : @parameter.elt int : list int ] */ ; + PUSH bool False + /* [ bool : list int : @parameter.elt int : list int ] */ } } + { NIL int + /* [ list int : @parameter.elt int : list int ] */ ; + PUSH bool False + /* [ bool : list int : @parameter.elt int : list int ] */ } } + /* [ list int : @parameter.elt int : list int ] */ ; + SWAP + /* [ @parameter.elt int : list int : list int ] */ ; + CONS + /* [ list int : list int ] */ ; + SWAP + /* [ list int : list int ] */ ; + ITER { CONS /* [ list int ] */ } + /* [ list int ] */ } + /* [ list int ] */ ; + NIL operation + /* [ list operation : list int ] */ ; + PAIR + /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--int_publisher.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--int_publisher.tz].out new file mode 100644 index 000000000000..a839c63f27cb --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--int_publisher.tz].out @@ -0,0 +1,105 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/int_publisher.tz] + +Well typed +Gas remaining: 1039967.523 units remaining +{ parameter (option (pair signature int)) ; + storage (pair key int) ; + code { DUP + /* [ pair (option @parameter (pair signature int)) (pair @storage key int) + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + DUP + /* [ pair (option @parameter (pair signature int)) (pair @storage key int) + : pair (option @parameter (pair signature int)) (pair @storage key int) + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + CAR + /* [ @parameter option (pair signature int) + : pair (option @parameter (pair signature int)) (pair @storage key int) + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + IF_NONE + { PUSH mutez + 1000000 + /* [ mutez + : pair (option @parameter (pair signature int)) (pair @storage key int) + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + AMOUNT + /* [ @amount mutez : mutez + : pair (option @parameter (pair signature int)) (pair @storage key int) + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + CMPLE ; + IF { FAIL } + { /* [ pair (option @parameter (pair signature int)) (pair @storage key int) + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ } ; + CDR + /* [ @storage pair key int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + DIP { CDDR } + /* [ @storage pair key int : int ] */ } + { DUP + /* [ @parameter.some pair signature int : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + DIP { SWAP + /* [ pair (option @parameter (pair signature int)) (pair @storage key int) + : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ } + /* [ @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) + : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + SWAP + /* [ pair (option @parameter (pair signature int)) (pair @storage key int) + : @parameter.some pair signature int : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + CDAR ; + DIP { DUP + /* [ @parameter.some pair signature int : @parameter.some pair signature int + : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + CAR + /* [ signature : @parameter.some pair signature int + : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + DIP { CDR + /* [ int : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + PACK + /* [ @packed bytes : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + BLAKE2B + /* [ bytes : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ } + /* [ signature : bytes : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ } + /* [ key : signature : bytes : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + CHECK_SIGNATURE + /* [ bool : @parameter.some pair signature int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + IF { CDR + /* [ int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + SWAP + /* [ pair (option @parameter (pair signature int)) (pair @storage key int) + : int ] */ ; + DIP { DUP /* [ int : int ] */ } + /* [ pair (option @parameter (pair signature int)) (pair @storage key int) : int + : int ] */ ; + CDAR ; + PAIR + /* [ pair key int : int ] */ } + { DROP + /* [ pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + DUP + /* [ pair (option @parameter (pair signature int)) (pair @storage key int) + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + CDR + /* [ @storage pair key int + : pair (option @parameter (pair signature int)) (pair @storage key int) ] */ ; + DIP { CDDR } + /* [ @storage pair key int : int ] */ } } ; + DIP { DROP /* [] */ } + /* [ pair key int ] */ ; + NIL operation + /* [ list operation : pair key int ] */ ; + PAIR + /* [ pair (list operation) key int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--king_of_tez.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--king_of_tez.tz].out new file mode 100644 index 000000000000..c83fc9eb1926 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--king_of_tez.tz].out @@ -0,0 +1,79 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/king_of_tez.tz] + +Well typed +Gas remaining: 1039971.047 units remaining +{ parameter key_hash ; + storage (pair timestamp (pair mutez key_hash)) ; + code { DUP + /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; + CDAR ; + NOW + /* [ @now timestamp : timestamp + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; + CMPGT ; + IF { CAR + /* [ @parameter key_hash ] */ ; + AMOUNT + /* [ @amount mutez : @parameter key_hash ] */ ; + PAIR + /* [ pair (mutez @amount) (key_hash @parameter) ] */ ; + NOW + /* [ @now timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; + PUSH int + 604800 + /* [ int : @now timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; + ADD + /* [ timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; + PAIR + /* [ pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + NIL operation + /* [ list operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ } + { DUP + /* [ pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; + CDDAR ; + AMOUNT + /* [ @amount mutez : mutez + : pair (key_hash @parameter) (pair @storage timestamp mutez key_hash) ] */ ; + CMPLT ; + IF { FAIL } + { CAR + /* [ @parameter key_hash ] */ ; + DUP + /* [ @parameter key_hash : @parameter key_hash ] */ ; + DIP { AMOUNT + /* [ @amount mutez : @parameter key_hash ] */ ; + PAIR + /* [ pair (mutez @amount) (key_hash @parameter) ] */ ; + NOW + /* [ @now timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; + PUSH int + 604800 + /* [ int : @now timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; + ADD + /* [ timestamp : pair (mutez @amount) (key_hash @parameter) ] */ ; + PAIR + /* [ pair timestamp (mutez @amount) (key_hash @parameter) ] */ } + /* [ @parameter key_hash + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + IMPLICIT_ACCOUNT + /* [ contract unit : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + AMOUNT + /* [ @amount mutez : contract unit + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + UNIT + /* [ unit : @amount mutez : contract unit + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + TRANSFER_TOKENS + /* [ operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + NIL operation + /* [ list operation : operation + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + SWAP + /* [ operation : list operation + : pair timestamp (mutez @amount) (key_hash @parameter) ] */ ; + CONS + /* [ list operation : pair timestamp (mutez @amount) (key_hash @parameter) ] */ } } ; + PAIR + /* [ pair (list operation) timestamp (mutez @amount) (key_hash @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--list_of_transactions.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--list_of_transactions.tz].out new file mode 100644 index 000000000000..67928a2406df --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--list_of_transactions.tz].out @@ -0,0 +1,49 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/list_of_transactions.tz] + +Well typed +Gas remaining: 1039982.122 units remaining +{ parameter unit ; + storage (list address) ; + code { CDR + /* [ @storage list address ] */ ; + DUP + /* [ @storage list address : @storage list address ] */ ; + DIP { NIL operation /* [ list operation : @storage list address ] */ } + /* [ @storage list address : list operation : @storage list address ] */ ; + PUSH bool + True + /* [ bool : @storage list address : list operation : @storage list address ] */ ; + LOOP { IF_CONS + { CONTRACT + unit + /* [ @storage.hd.contract option (contract unit) : @storage.tl list address + : list operation : @storage list address ] */ ; + ASSERT_SOME ; + PUSH mutez + 1000000 + /* [ mutez : @storage.hd.contract.some contract unit : @storage.tl list address + : list operation : @storage list address ] */ ; + UNIT + /* [ unit : mutez : @storage.hd.contract.some contract unit + : @storage.tl list address : list operation : @storage list address ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage.tl list address : list operation + : @storage list address ] */ ; + SWAP + /* [ @storage.tl list address : operation : list operation + : @storage list address ] */ ; + DIP { CONS /* [ list operation : @storage list address ] */ } + /* [ @storage.tl list address : list operation : @storage list address ] */ ; + PUSH bool + True + /* [ bool : @storage.tl list address : list operation : @storage list address ] */ } + { NIL address + /* [ list address : list operation : @storage list address ] */ ; + PUSH bool + False + /* [ bool : list address : list operation : @storage list address ] */ } } + /* [ @storage list address : list operation : @storage list address ] */ ; + DROP + /* [ list operation : @storage list address ] */ ; + PAIR + /* [ pair (list operation) (list @storage address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--queue.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--queue.tz].out new file mode 100644 index 000000000000..637da4badd51 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--queue.tz].out @@ -0,0 +1,111 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/queue.tz] + +Well typed +Gas remaining: 1039952.504 units remaining +{ parameter (option string) ; + storage (pair (option string) (pair (pair nat nat) (map nat string))) ; + code { DUP + /* [ pair (option @parameter string) + (pair @storage (option string) (pair nat nat) (map nat string)) + : pair (option @parameter string) + (pair @storage (option string) (pair nat nat) (map nat string)) ] */ ; + CAR + /* [ @parameter option string + : pair (option @parameter string) + (pair @storage (option string) (pair nat nat) (map nat string)) ] */ ; + IF_NONE + { CDDR ; + DUP + /* [ pair (pair nat nat) (map nat string) + : pair (pair nat nat) (map nat string) ] */ ; + CAR + /* [ pair nat nat : pair (pair nat nat) (map nat string) ] */ ; + DIP { CDR /* [ map nat string ] */ ; DUP /* [ map nat string : map nat string ] */ } + /* [ pair nat nat : map nat string : map nat string ] */ ; + DUP + /* [ pair nat nat : pair nat nat : map nat string : map nat string ] */ ; + CAR + /* [ nat : pair nat nat : map nat string : map nat string ] */ ; + SWAP + /* [ pair nat nat : nat : map nat string : map nat string ] */ ; + DIP { GET /* [ option string : map nat string ] */ } + /* [ pair nat nat : option string : map nat string ] */ ; + SWAP + /* [ option string : pair nat nat : map nat string ] */ ; + IF_NONE + { NONE string + /* [ option string : pair nat nat : map nat string ] */ ; + DIP { PAIR /* [ pair (pair nat nat) (map nat string) ] */ } + /* [ option string : pair (pair nat nat) (map nat string) ] */ ; + PAIR + /* [ pair (option string) (pair nat nat) (map nat string) ] */ } + { SOME + /* [ option string : pair nat nat : map nat string ] */ ; + DIP { DUP + /* [ pair nat nat : pair nat nat : map nat string ] */ ; + DIP { CAR + /* [ nat : map nat string ] */ ; + DIP { NONE string /* [ option string : map nat string ] */ } + /* [ nat : option string : map nat string ] */ ; + UPDATE + /* [ map nat string ] */ } + /* [ pair nat nat : map nat string ] */ ; + DUP + /* [ pair nat nat : pair nat nat : map nat string ] */ ; + CAR + /* [ nat : pair nat nat : map nat string ] */ ; + PUSH nat 1 + /* [ nat : nat : pair nat nat : map nat string ] */ ; + ADD + /* [ nat : pair nat nat : map nat string ] */ ; + DIP { CDR /* [ nat : map nat string ] */ } + /* [ nat : nat : map nat string ] */ ; + PAIR + /* [ pair nat nat : map nat string ] */ ; + PAIR + /* [ pair (pair nat nat) (map nat string) ] */ } + /* [ option string : pair (pair nat nat) (map nat string) ] */ ; + PAIR + /* [ pair (option string) (pair nat nat) (map nat string) ] */ } } + { DIP { DUP + /* [ pair (option @parameter string) + (pair @storage (option string) (pair nat nat) (map nat string)) + : pair (option @parameter string) + (pair @storage (option string) (pair nat nat) (map nat string)) ] */ ; + CDDAR ; + DIP { CDDDR } + /* [ pair nat nat : map nat string ] */ ; + DUP + /* [ pair nat nat : pair nat nat : map nat string ] */ } + /* [ @parameter.some string : pair nat nat : pair nat nat : map nat string ] */ ; + SWAP + /* [ pair nat nat : @parameter.some string : pair nat nat : map nat string ] */ ; + CAR + /* [ nat : @parameter.some string : pair nat nat : map nat string ] */ ; + DIP { SOME + /* [ option string : pair nat nat : map nat string ] */ ; + SWAP + /* [ pair nat nat : option string : map nat string ] */ ; + CDR + /* [ nat : option string : map nat string ] */ ; + DUP + /* [ nat : nat : option string : map nat string ] */ ; + DIP { UPDATE /* [ map nat string ] */ } + /* [ nat : map nat string ] */ ; + PUSH nat 1 + /* [ nat : nat : map nat string ] */ ; + ADD + /* [ nat : map nat string ] */ } + /* [ nat : nat : map nat string ] */ ; + PAIR + /* [ pair nat nat : map nat string ] */ ; + PAIR + /* [ pair (pair nat nat) (map nat string) ] */ ; + NONE string + /* [ option string : pair (pair nat nat) (map nat string) ] */ ; + PAIR + /* [ pair (option string) (pair nat nat) (map nat string) ] */ } ; + NIL operation + /* [ list operation : pair (option string) (pair nat nat) (map nat string) ] */ ; + PAIR + /* [ pair (list operation) (option string) (pair nat nat) (map nat string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reduce_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reduce_map.tz].out new file mode 100644 index 000000000000..855e6395dac9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reduce_map.tz].out @@ -0,0 +1,58 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/reduce_map.tz] + +Well typed +Gas remaining: 1039975.926 units remaining +{ parameter (pair (lambda int int) (list int)) ; + storage (list int) ; + code { DIP { NIL int /* [ list int ] */ } + /* [ pair (pair @parameter (lambda int int) (list int)) (list @storage int) + : list int ] */ ; + CAR + /* [ @parameter pair (lambda int int) (list int) : list int ] */ ; + DUP + /* [ @parameter pair (lambda int int) (list int) + : @parameter pair (lambda int int) (list int) : list int ] */ ; + DIP { CAR + /* [ lambda int int : list int ] */ ; + PAIR + /* [ pair (lambda int int) (list int) ] */ } + /* [ @parameter pair (lambda int int) (list int) + : pair (lambda int int) (list int) ] */ ; + CDR + /* [ list int : pair (lambda int int) (list int) ] */ ; + ITER { PAIR + /* [ pair (int @elt) (lambda int int) (list int) ] */ ; + DUP + /* [ pair (int @elt) (lambda int int) (list int) + : pair (int @elt) (lambda int int) (list int) ] */ ; + CDAR ; + DIP { DUP + /* [ pair (int @elt) (lambda int int) (list int) + : pair (int @elt) (lambda int int) (list int) ] */ ; + DIP { CDAR } + /* [ pair (int @elt) (lambda int int) (list int) : lambda int int ] */ ; + DUP + /* [ pair (int @elt) (lambda int int) (list int) + : pair (int @elt) (lambda int int) (list int) : lambda int int ] */ ; + CAR + /* [ @elt int : pair (int @elt) (lambda int int) (list int) : lambda int int ] */ ; + DIP { CDDR ; SWAP /* [ lambda int int : list int ] */ } + /* [ @elt int : lambda int int : list int ] */ ; + EXEC + /* [ int : list int ] */ ; + CONS + /* [ list int ] */ } + /* [ lambda int int : list int ] */ ; + PAIR + /* [ pair (lambda int int) (list int) ] */ } + /* [ pair (lambda int int) (list int) ] */ ; + CDR + /* [ list int ] */ ; + DIP { NIL int /* [ list int ] */ } + /* [ list int : list int ] */ ; + ITER { CONS /* [ list int ] */ } + /* [ list int ] */ ; + NIL operation + /* [ list operation : list int ] */ ; + PAIR + /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reentrancy.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reentrancy.tz].out new file mode 100644 index 000000000000..7b4e1bdfa3c1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reentrancy.tz].out @@ -0,0 +1,49 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/reentrancy.tz] + +Well typed +Gas remaining: 1039981.752 units remaining +{ parameter unit ; + storage (pair address address) ; + code { CDR + /* [ @storage pair address address ] */ ; + DUP + /* [ @storage pair address address : @storage pair address address ] */ ; + CAR + /* [ address : @storage pair address address ] */ ; + CONTRACT + unit + /* [ @contract option (contract unit) : @storage pair address address ] */ ; + ASSERT_SOME ; + PUSH mutez + 5000000 + /* [ mutez : @contract.some contract unit : @storage pair address address ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : @storage pair address address ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage pair address address ] */ ; + DIP { DUP + /* [ @storage pair address address : @storage pair address address ] */ ; + CDR + /* [ address : @storage pair address address ] */ ; + CONTRACT + unit + /* [ @contract option (contract unit) : @storage pair address address ] */ ; + ASSERT_SOME ; + PUSH mutez + 5000000 + /* [ mutez : @contract.some contract unit : @storage pair address address ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : @storage pair address address ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage pair address address ] */ } + /* [ operation : operation : @storage pair address address ] */ ; + DIIP { NIL operation /* [ list operation : @storage pair address address ] */ } + /* [ operation : operation : list operation : @storage pair address address ] */ ; + DIP { CONS /* [ list operation : @storage pair address address ] */ } + /* [ operation : list operation : @storage pair address address ] */ ; + CONS + /* [ list operation : @storage pair address address ] */ ; + PAIR + /* [ pair (list operation) (pair @storage address address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reservoir.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reservoir.tz].out new file mode 100644 index 000000000000..8501c7bb7b86 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--reservoir.tz].out @@ -0,0 +1,100 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/reservoir.tz] + +Well typed +Gas remaining: 1039963.237 units remaining +{ parameter unit ; + storage (pair (pair (timestamp %T) (mutez %N)) (pair (address %A) (address %B))) ; + code { CDR + /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + DUP + /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + CAAR %T ; + NOW + /* [ @now timestamp : timestamp + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + COMPARE + /* [ int + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + LE + /* [ bool + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + IF { DUP + /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + CADR %N ; + BALANCE + /* [ @balance mutez : mutez + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + COMPARE + /* [ int + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + LE + /* [ bool + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + IF { NIL operation + /* [ list operation + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage (pair (timestamp %T) (mutez %N)) (address %A) (address %B)) ] */ } + { DUP + /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + CDDR %B ; + CONTRACT + unit + /* [ @contract option (contract unit) + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + ASSERT_SOME ; + BALANCE + /* [ @balance mutez : @contract.some contract unit + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + UNIT + /* [ unit : @balance mutez : @contract.some contract unit + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + TRANSFER_TOKENS + /* [ operation + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + NIL operation + /* [ list operation : operation + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + SWAP + /* [ operation : list operation + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + CONS + /* [ list operation + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage (pair (timestamp %T) (mutez %N)) (address %A) (address %B)) ] */ } } + { DUP + /* [ @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + CDAR %A ; + CONTRACT + unit + /* [ @contract option (contract unit) + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + ASSERT_SOME ; + BALANCE + /* [ @balance mutez : @contract.some contract unit + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + UNIT + /* [ unit : @balance mutez : @contract.some contract unit + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + TRANSFER_TOKENS + /* [ operation + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + NIL operation + /* [ list operation : operation + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + SWAP + /* [ operation : list operation + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + CONS + /* [ list operation + : @storage pair (pair (timestamp %T) (mutez %N)) (address %A) (address %B) ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage (pair (timestamp %T) (mutez %N)) (address %A) (address %B)) ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--scrutable_reservoir.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--scrutable_reservoir.tz].out new file mode 100644 index 000000000000..840cee340c35 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--scrutable_reservoir.tz].out @@ -0,0 +1,273 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/scrutable_reservoir.tz] + +Well typed +Gas remaining: 1039876.691 units remaining +{ parameter unit ; + storage + (pair string + (pair timestamp (pair (pair mutez mutez) (pair address (pair address address))))) ; + code { DUP + /* [ pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + CDAR ; + PUSH string + "open" + /* [ string : string + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + COMPARE + /* [ int + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + NEQ + /* [ bool + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + IF { FAIL } + { DUP + /* [ pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + CDDAR ; + NOW + /* [ @now timestamp : timestamp + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + COMPARE + /* [ int + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + LT + /* [ bool + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + IF { PUSH mutez + 0 + /* [ mutez + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + DIP { DUP + /* [ pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + CDDDAAR } + /* [ mutez : mutez + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + ADD + /* [ mutez + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + DIP { DUP + /* [ pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + CDDDADR } + /* [ mutez : mutez + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + ADD + /* [ mutez + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + BALANCE + /* [ @balance mutez : mutez + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + COMPARE + /* [ int + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + LT + /* [ bool + : pair (unit @parameter) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ ; + IF { CDR + /* [ @storage pair string timestamp (pair mutez mutez) address address address ] */ ; + NIL operation + /* [ list operation + : @storage pair string timestamp (pair mutez mutez) address address address ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage string timestamp (pair mutez mutez) address address address) ] */ } + { CDDR ; + PUSH string + "success" + /* [ string : pair timestamp (pair mutez mutez) address address address ] */ ; + PAIR + /* [ pair string timestamp (pair mutez mutez) address address address ] */ ; + DUP + /* [ pair string timestamp (pair mutez mutez) address address address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CDDAAR ; + DIP { DUP + /* [ pair string timestamp (pair mutez mutez) address address address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CDDDAR } + /* [ mutez : address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : pair string timestamp (pair mutez mutez) address address address ] */ ; + ASSERT_SOME } + /* [ mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + DIP { DUP + /* [ pair string timestamp (pair mutez mutez) address address address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CDDADR ; + DIP { DUP + /* [ pair string timestamp (pair mutez mutez) address address address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CDDDDAR } + /* [ mutez : address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : pair string timestamp (pair mutez mutez) address address address ] */ ; + ASSERT_SOME } + /* [ mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair string timestamp (pair mutez mutez) address address address ] */ } + /* [ operation : operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + NIL operation + /* [ list operation : operation : operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + SWAP + /* [ operation : list operation : operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CONS + /* [ list operation : operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + SWAP + /* [ operation : list operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CONS + /* [ list operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + PAIR + /* [ pair (list operation) string timestamp (pair mutez mutez) address address address ] */ } } + { CDDR ; + PUSH string + "timeout" + /* [ string : pair timestamp (pair mutez mutez) address address address ] */ ; + PAIR + /* [ pair string timestamp (pair mutez mutez) address address address ] */ ; + BALANCE + /* [ @balance mutez + : pair string timestamp (pair mutez mutez) address address address ] */ ; + DIP { DUP + /* [ pair string timestamp (pair mutez mutez) address address address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CDDAAR } + /* [ @balance mutez : mutez + : pair string timestamp (pair mutez mutez) address address address ] */ ; + COMPARE + /* [ int : pair string timestamp (pair mutez mutez) address address address ] */ ; + LT + /* [ bool : pair string timestamp (pair mutez mutez) address address address ] */ ; + IF { BALANCE + /* [ @balance mutez + : pair string timestamp (pair mutez mutez) address address address ] */ ; + DIP { DUP + /* [ pair string timestamp (pair mutez mutez) address address address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CDDDAR } + /* [ @balance mutez : address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : pair string timestamp (pair mutez mutez) address address address ] */ ; + ASSERT_SOME } + /* [ @balance mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + UNIT + /* [ unit : @balance mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair string timestamp (pair mutez mutez) address address address ] */ } + { DUP + /* [ pair string timestamp (pair mutez mutez) address address address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CDDAAR ; + DIP { DUP + /* [ pair string timestamp (pair mutez mutez) address address address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CDDDAR } + /* [ mutez : address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : pair string timestamp (pair mutez mutez) address address address ] */ ; + ASSERT_SOME } + /* [ mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair string timestamp (pair mutez mutez) address address address ] */ } ; + DIP { BALANCE + /* [ @balance mutez + : pair string timestamp (pair mutez mutez) address address address ] */ ; + DIP { DUP + /* [ pair string timestamp (pair mutez mutez) address address address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CDDDDDR } + /* [ @balance mutez : address + : pair string timestamp (pair mutez mutez) address address address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) + : pair string timestamp (pair mutez mutez) address address address ] */ ; + ASSERT_SOME } + /* [ @balance mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + UNIT + /* [ unit : @balance mutez : @contract.some contract unit + : pair string timestamp (pair mutez mutez) address address address ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair string timestamp (pair mutez mutez) address address address ] */ } + /* [ operation : operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + NIL operation + /* [ list operation : operation : operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + SWAP + /* [ operation : list operation : operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CONS + /* [ list operation : operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + SWAP + /* [ operation : list operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + CONS + /* [ list operation + : pair string timestamp (pair mutez mutez) address address address ] */ ; + PAIR + /* [ pair (list operation) string timestamp (pair mutez mutez) address address address ] */ } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--spawn_identities.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--spawn_identities.tz].out new file mode 100644 index 000000000000..91f106df7ec3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[attic--spawn_identities.tz].out @@ -0,0 +1,71 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[attic/spawn_identities.tz] + +Well typed +Gas remaining: 1039971.200 units remaining +{ parameter nat ; + storage (list address) ; + code { /* [ pair (string @parameter) (string @storage) ] */ + DUP + /* [ list operation : @parameter string ] */ ; + CAR + /* [ @parameter nat : pair (nat @parameter) (list @storage address) ] */ ; + DIP { CDR + /* [ @storage list address ] */ ; + NIL operation + /* [ list operation : @storage list address ] */ } + /* [ pair (list operation) (string @parameter) ] */ ; + PUSH bool + True + /* [ bool : @parameter nat : list operation : @storage list address ] */ ; + LOOP { DUP + /* [ @parameter nat : @parameter nat : list operation : @storage list address ] */ ; + PUSH nat + 0 + /* [ nat : @parameter nat : @parameter nat : list operation + : @storage list address ] */ ; + CMPEQ ; + IF { PUSH bool + False + /* [ bool : @parameter nat : list operation : @storage list address ] */ } + { PUSH nat 1 + /* [ nat : @parameter nat : list operation : @storage list address ] */ ; + SWAP + /* [ @parameter nat : nat : list operation : @storage list address ] */ ; + SUB + /* [ int : list operation : @storage list address ] */ ; + ABS + /* [ nat : list operation : @storage list address ] */ ; + PUSH string "init" + /* [ string : nat : list operation : @storage list address ] */ ; + PUSH mutez + 5000000 + /* [ mutez : string : nat : list operation : @storage list address ] */ ; + NONE key_hash + /* [ option key_hash : mutez : string : nat : list operation + : @storage list address ] */ ; + CREATE_CONTRACT + { parameter string ; + storage string ; + code { CAR ; NIL operation ; PAIR } } + /* [ operation : address : nat : list operation : @storage list address ] */ ; + SWAP + /* [ address : operation : nat : list operation : @storage list address ] */ ; + DIP { SWAP + /* [ nat : operation : list operation : @storage list address ] */ ; + DIP { CONS /* [ list operation : @storage list address ] */ } + /* [ nat : list operation : @storage list address ] */ } + /* [ address : nat : list operation : @storage list address ] */ ; + SWAP + /* [ nat : address : list operation : @storage list address ] */ ; + DIP { SWAP + /* [ list operation : address : @storage list address ] */ ; + DIP { CONS /* [ list address ] */ } + /* [ list operation : list address ] */ } + /* [ nat : list operation : list address ] */ ; + PUSH bool True + /* [ bool : nat : list operation : list address ] */ } } + /* [ @parameter nat : list operation : @storage list address ] */ ; + DROP + /* [ list operation : @storage list address ] */ ; + PAIR + /* [ pair (list operation) (list @storage address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert.tz].out new file mode 100644 index 000000000000..580fe2c4f736 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert.tz].out @@ -0,0 +1,15 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert.tz] + +Well typed +Gas remaining: 1039994.573 units remaining +{ parameter bool ; + storage unit ; + code { CAR + /* [ @parameter bool ] */ ; + ASSERT ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpeq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpeq.tz].out new file mode 100644 index 000000000000..ececb7d6ec9e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpeq.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmpeq.tz] + +Well typed +Gas remaining: 1039990.676 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + ASSERT_CMPEQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpge.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpge.tz].out new file mode 100644 index 000000000000..808469ab751c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpge.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmpge.tz] + +Well typed +Gas remaining: 1039990.676 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + ASSERT_CMPGE ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpgt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpgt.tz].out new file mode 100644 index 000000000000..069a9c50bdc7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpgt.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmpgt.tz] + +Well typed +Gas remaining: 1039990.676 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + ASSERT_CMPGT ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmple.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmple.tz].out new file mode 100644 index 000000000000..6fc959162746 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmple.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmple.tz] + +Well typed +Gas remaining: 1039990.676 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + ASSERT_CMPLE ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmplt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmplt.tz].out new file mode 100644 index 000000000000..a1b965e356e7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmplt.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmplt.tz] + +Well typed +Gas remaining: 1039990.676 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + ASSERT_CMPLT ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpneq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpneq.tz].out new file mode 100644 index 000000000000..5c102bd027b9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_cmpneq.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_cmpneq.tz] + +Well typed +Gas remaining: 1039990.676 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + ASSERT_CMPNEQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_eq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_eq.tz].out new file mode 100644 index 000000000000..98e95e219f2d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_eq.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_eq.tz] + +Well typed +Gas remaining: 1039990.923 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_ge.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_ge.tz].out new file mode 100644 index 000000000000..7d37efcc1f6e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_ge.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_ge.tz] + +Well typed +Gas remaining: 1039990.923 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GE ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_gt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_gt.tz].out new file mode 100644 index 000000000000..619d923be04f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_gt.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_gt.tz] + +Well typed +Gas remaining: 1039990.923 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_le.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_le.tz].out new file mode 100644 index 000000000000..ddcafb8860fc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_le.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_le.tz] + +Well typed +Gas remaining: 1039990.923 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LE ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_lt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_lt.tz].out new file mode 100644 index 000000000000..27c7664335fa --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_lt.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_lt.tz] + +Well typed +Gas remaining: 1039990.923 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LT ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_neq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_neq.tz].out new file mode 100644 index 000000000000..a38cce08c937 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--assert_neq.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/assert_neq.tz] + +Well typed +Gas remaining: 1039990.923 units remaining +{ parameter (pair int int) ; + storage unit ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_NEQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_get_add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_get_add.tz].out new file mode 100644 index 000000000000..0a1988426f17 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_get_add.tz].out @@ -0,0 +1,71 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/big_map_get_add.tz] + +Well typed +Gas remaining: 1039968.666 units remaining +{ parameter (pair (pair %set_pair int (option int)) (pair %check_pair int (option int))) ; + storage (pair (big_map int int) unit) ; + code { DUP + /* [ pair (pair @parameter + (pair %set_pair int (option int)) + (pair %check_pair int (option int))) + (pair @storage (big_map int int) unit) + : pair (pair @parameter + (pair %set_pair int (option int)) + (pair %check_pair int (option int))) + (pair @storage (big_map int int) unit) ] */ ; + DIP { CDAR } + /* [ pair (pair @parameter + (pair %set_pair int (option int)) + (pair %check_pair int (option int))) + (pair @storage (big_map int int) unit) : big_map int int ] */ ; + DUP + /* [ pair (pair @parameter + (pair %set_pair int (option int)) + (pair %check_pair int (option int))) + (pair @storage (big_map int int) unit) + : pair (pair @parameter + (pair %set_pair int (option int)) + (pair %check_pair int (option int))) + (pair @storage (big_map int int) unit) : big_map int int ] */ ; + DIP { CADR ; + DUP + /* [ pair int (option int) : pair int (option int) : big_map int int ] */ ; + CAR + /* [ int : pair int (option int) : big_map int int ] */ ; + DIP { CDR /* [ option int : big_map int int ] */ } + /* [ int : option int : big_map int int ] */ ; + UPDATE + /* [ big_map int int ] */ ; + DUP + /* [ big_map int int : big_map int int ] */ } + /* [ pair (pair @parameter + (pair %set_pair int (option int)) + (pair %check_pair int (option int))) + (pair @storage (big_map int int) unit) : big_map int int + : big_map int int ] */ ; + CADR ; + DUP + /* [ pair int (option int) : pair int (option int) : big_map int int + : big_map int int ] */ ; + CDR + /* [ option int : pair int (option int) : big_map int int : big_map int int ] */ ; + DIP { CAR + /* [ int : big_map int int : big_map int int ] */ ; + GET + /* [ option int : big_map int int ] */ } + /* [ option int : option int : big_map int int ] */ ; + IF_SOME + { SWAP + /* [ option int : @some int : big_map int int ] */ ; + IF_SOME { ASSERT_CMPEQ } { FAIL } } + { ASSERT_NONE } ; + UNIT + /* [ unit : big_map int int ] */ ; + SWAP + /* [ big_map int int : unit ] */ ; + PAIR + /* [ pair (big_map int int) unit ] */ ; + NIL operation + /* [ list operation : pair (big_map int int) unit ] */ ; + PAIR + /* [ pair (list operation) (big_map int int) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_mem.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_mem.tz].out new file mode 100644 index 000000000000..d25e218c8488 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--big_map_mem.tz].out @@ -0,0 +1,31 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/big_map_mem.tz] + +Well typed +Gas remaining: 1039982.471 units remaining +{ parameter (pair int bool) ; + storage (pair (big_map int unit) unit) ; + code { DUP + /* [ pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) + : pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) ] */ ; + DUP + /* [ pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) + : pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) + : pair (pair @parameter int bool) (pair @storage (big_map int unit) unit) ] */ ; + CADR ; + DIP { CAAR ; + DIP { CDAR ; DUP /* [ big_map int unit : big_map int unit ] */ } + /* [ int : big_map int unit : big_map int unit ] */ ; + MEM + /* [ bool : big_map int unit ] */ } + /* [ bool : bool : big_map int unit ] */ ; + ASSERT_CMPEQ ; + UNIT + /* [ unit : big_map int unit ] */ ; + SWAP + /* [ big_map int unit : unit ] */ ; + PAIR + /* [ pair (big_map int unit) unit ] */ ; + NIL operation + /* [ list operation : pair (big_map int unit) unit ] */ ; + PAIR + /* [ pair (list operation) (big_map int unit) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--build_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--build_list.tz].out new file mode 100644 index 000000000000..cd4da3f58ae3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--build_list.tz].out @@ -0,0 +1,45 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/build_list.tz] + +Well typed +Gas remaining: 1039982.791 units remaining +{ parameter nat ; + storage (list nat) ; + code { CAR @counter + /* [ @counter nat ] */ ; + NIL @acc nat + /* [ @acc list nat : @counter nat ] */ ; + SWAP + /* [ @counter nat : @acc list nat ] */ ; + DUP @cmp_num + /* [ @cmp_num nat : @counter nat : @acc list nat ] */ ; + PUSH nat 0 + /* [ nat : @cmp_num nat : @counter nat : @acc list nat ] */ ; + CMPNEQ ; + LOOP { DUP + /* [ @counter nat : @counter nat : @acc list nat ] */ ; + DIP { SWAP /* [ @acc list nat : @counter nat ] */ } + /* [ @counter nat : @acc list nat : @counter nat ] */ ; + CONS @acc + /* [ @acc list nat : @counter nat ] */ ; + SWAP + /* [ @counter nat : @acc list nat ] */ ; + PUSH nat 1 + /* [ nat : @counter nat : @acc list nat ] */ ; + SWAP + /* [ @counter nat : nat : @acc list nat ] */ ; + SUB @counter + /* [ @counter int : @acc list nat ] */ ; + DUP + /* [ @counter int : @counter int : @acc list nat ] */ ; + DIP { ABS /* [ nat : @acc list nat ] */ } + /* [ @counter int : nat : @acc list nat ] */ ; + PUSH int 0 + /* [ int : @counter int : nat : @acc list nat ] */ ; + CMPNEQ } + /* [ @counter nat : @acc list nat ] */ ; + CONS + /* [ list nat ] */ ; + NIL operation + /* [ list operation : list nat ] */ ; + PAIR + /* [ pair (list operation) (list nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--carn_and_cdrn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--carn_and_cdrn.tz].out new file mode 100644 index 000000000000..415f570850c2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--carn_and_cdrn.tz].out @@ -0,0 +1,47 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/carn_and_cdrn.tz] + +Well typed +Gas remaining: 1039963.184 units remaining +{ parameter (pair nat nat nat unit) ; + storage unit ; + code { CAR + /* [ @parameter pair nat nat nat unit ] */ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + CAR + /* [ nat : @parameter pair nat nat nat unit ] */ ; + PUSH nat 1 + /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + CAR 0 ; + PUSH nat 1 + /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + CAR 1 ; + PUSH nat 4 + /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + CAR 2 ; + PUSH nat 2 + /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + CDR 3 ; + UNIT + /* [ unit : unit : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare.tz].out new file mode 100644 index 000000000000..6542fcd4c6f4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare.tz].out @@ -0,0 +1,97 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/compare.tz] + +Well typed +Gas remaining: 1039968.322 units remaining +{ parameter (pair mutez mutez) ; + storage (list bool) ; + code { CAR + /* [ @parameter pair mutez mutez ] */ ; + DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; + DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez + : @parameter pair mutez mutez ] */ ; + DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez + : @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; + DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez + : @parameter pair mutez mutez : @parameter pair mutez mutez + : @parameter pair mutez mutez ] */ ; + DIIIIIP + { NIL bool /* [ list bool ] */ } + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez + : @parameter pair mutez mutez : @parameter pair mutez mutez + : @parameter pair mutez mutez : list bool ] */ ; + DIIIIP + { DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; + CAR + /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; + DIP { CDR /* [ mutez : list bool ] */ } + /* [ mutez : mutez : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + LE + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ } + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez + : @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; + DIIIP + { DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; + CAR + /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; + DIP { CDR /* [ mutez : list bool ] */ } + /* [ mutez : mutez : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + GE + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ } + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez + : @parameter pair mutez mutez : list bool ] */ ; + DIIP { DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; + CAR + /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; + DIP { CDR /* [ mutez : list bool ] */ } + /* [ mutez : mutez : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + LT + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ } + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; + DIP { DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; + CAR + /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; + DIP { CDR /* [ mutez : list bool ] */ } + /* [ mutez : mutez : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + GT + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ } + /* [ @parameter pair mutez mutez : list bool ] */ ; + DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez : list bool ] */ ; + CAR + /* [ mutez : @parameter pair mutez mutez : list bool ] */ ; + DIP { CDR /* [ mutez : list bool ] */ } + /* [ mutez : mutez : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + EQ + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ ; + NIL operation + /* [ list operation : list bool ] */ ; + PAIR + /* [ pair (list operation) (list bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare_bytes.tz].out new file mode 100644 index 000000000000..3e8066e73de0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--compare_bytes.tz].out @@ -0,0 +1,97 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/compare_bytes.tz] + +Well typed +Gas remaining: 1039968.322 units remaining +{ parameter (pair bytes bytes) ; + storage (list bool) ; + code { CAR + /* [ @parameter pair bytes bytes ] */ ; + DUP + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes ] */ ; + DUP + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes + : @parameter pair bytes bytes ] */ ; + DUP + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes + : @parameter pair bytes bytes : @parameter pair bytes bytes ] */ ; + DUP + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes + : @parameter pair bytes bytes : @parameter pair bytes bytes + : @parameter pair bytes bytes ] */ ; + DIIIIIP + { NIL bool /* [ list bool ] */ } + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes + : @parameter pair bytes bytes : @parameter pair bytes bytes + : @parameter pair bytes bytes : list bool ] */ ; + DIIIIP + { DUP + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; + CAR + /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; + DIP { CDR /* [ bytes : list bool ] */ } + /* [ bytes : bytes : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + LE + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ } + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes + : @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; + DIIIP + { DUP + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; + CAR + /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; + DIP { CDR /* [ bytes : list bool ] */ } + /* [ bytes : bytes : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + GE + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ } + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes + : @parameter pair bytes bytes : list bool ] */ ; + DIIP { DUP + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; + CAR + /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; + DIP { CDR /* [ bytes : list bool ] */ } + /* [ bytes : bytes : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + LT + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ } + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; + DIP { DUP + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; + CAR + /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; + DIP { CDR /* [ bytes : list bool ] */ } + /* [ bytes : bytes : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + GT + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ } + /* [ @parameter pair bytes bytes : list bool ] */ ; + DUP + /* [ @parameter pair bytes bytes : @parameter pair bytes bytes : list bool ] */ ; + CAR + /* [ bytes : @parameter pair bytes bytes : list bool ] */ ; + DIP { CDR /* [ bytes : list bool ] */ } + /* [ bytes : bytes : list bool ] */ ; + COMPARE + /* [ int : list bool ] */ ; + EQ + /* [ bool : list bool ] */ ; + CONS + /* [ list bool ] */ ; + NIL operation + /* [ list operation : list bool ] */ ; + PAIR + /* [ pair (list operation) (list bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--fail.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--fail.tz].out new file mode 100644 index 000000000000..44d023e672d8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--fail.tz].out @@ -0,0 +1,5 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/fail.tz] + +Well typed +Gas remaining: 1039998.449 units remaining +{ parameter unit ; storage unit ; code { FAIL } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--guestbook.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--guestbook.tz].out new file mode 100644 index 000000000000..f0ca38479d3c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--guestbook.tz].out @@ -0,0 +1,36 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/guestbook.tz] + +Well typed +Gas remaining: 1039986.383 units remaining +{ parameter string ; + storage (map address (option string)) ; + code { UNPAIR @message @guestbook + /* [ @message string : @guestbook map address (option string) ] */ ; + SWAP + /* [ @guestbook map address (option string) : @message string ] */ ; + DUP + /* [ @guestbook map address (option string) + : @guestbook map address (option string) : @message string ] */ ; + SENDER + /* [ @sender address : @guestbook map address (option string) + : @guestbook map address (option string) : @message string ] */ ; + GET @previous_message + /* [ @previous_message option (option string) + : @guestbook map address (option string) : @message string ] */ ; + ASSERT_SOME ; + ASSERT_NONE ; + SWAP + /* [ @message string : @guestbook map address (option string) ] */ ; + SOME + /* [ option string : @guestbook map address (option string) ] */ ; + SOME + /* [ option (option string) : @guestbook map address (option string) ] */ ; + SENDER + /* [ @sender address : option (option string) + : @guestbook map address (option string) ] */ ; + UPDATE + /* [ @guestbook map address (option string) ] */ ; + NIL operation + /* [ list operation : @guestbook map address (option string) ] */ ; + PAIR + /* [ pair (list operation) (map @guestbook address (option string)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--macro_annotations.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--macro_annotations.tz].out new file mode 100644 index 000000000000..ada98a3ac9ec --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--macro_annotations.tz].out @@ -0,0 +1,24 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/macro_annotations.tz] + +Well typed +Gas remaining: 1039992.402 units remaining +{ parameter unit ; + storage (pair (unit %truc) unit) ; + code { DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + UNIT + /* [ unit : unit ] */ ; + PAIR %truc + /* [ pair (unit %truc) unit ] */ ; + UNIT + /* [ unit : pair (unit %truc) unit ] */ ; + DUUP @new_storage + /* [ @new_storage pair (unit %truc) unit : unit : pair (unit %truc) unit ] */ ; + DIP { DROP /* [ pair (unit %truc) unit ] */ ; DROP /* [] */ } + /* [ @new_storage pair (unit %truc) unit ] */ ; + NIL operation + /* [ list operation : @new_storage pair (unit %truc) unit ] */ ; + PAIR + /* [ pair (list operation) (pair @new_storage (unit %truc) unit) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--map_caddaadr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--map_caddaadr.tz].out new file mode 100644 index 000000000000..11ea7a729d46 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--map_caddaadr.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/map_caddaadr.tz] + +Well typed +Gas remaining: 1039964.206 units remaining +{ parameter unit ; + storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat) ; + code { MAP_CDADDAADR @new_storage %value + { PUSH mutez 1000000 + /* [ mutez : @value mutez : pair (nat %p) (mutez %value) ] */ ; + ADD + /* [ mutez : pair (nat %p) (mutez %value) ] */ } ; + NIL operation + /* [ list operation + : @new_storage pair unit (pair nat nat (pair (pair (nat %p @p) (mutez %value)) nat) nat) nat ] */ ; + SWAP + /* [ @new_storage pair unit (pair nat nat (pair (pair (nat %p @p) (mutez %value)) nat) nat) nat + : list operation ] */ ; + SET_CAR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--max_in_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--max_in_list.tz].out new file mode 100644 index 000000000000..b5e4e2ae51e1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--max_in_list.tz].out @@ -0,0 +1,29 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/max_in_list.tz] + +Well typed +Gas remaining: 1039985.981 units remaining +{ parameter (list int) ; + storage (option int) ; + code { CAR + /* [ @parameter list int ] */ ; + DIP { NONE int /* [ option int ] */ } + /* [ @parameter list int : option int ] */ ; + ITER { SWAP + /* [ option int : @parameter.elt int ] */ ; + IF_NONE + { SOME /* [ option int ] */ } + { DIP { DUP /* [ @parameter.elt int : @parameter.elt int ] */ } + /* [ @some int : @parameter.elt int : @parameter.elt int ] */ ; + DUP + /* [ @some int : @some int : @parameter.elt int : @parameter.elt int ] */ ; + DIP { SWAP /* [ @parameter.elt int : @some int : @parameter.elt int ] */ } + /* [ @some int : @parameter.elt int : @some int : @parameter.elt int ] */ ; + CMPLE ; + IF { DROP /* [ @parameter.elt int ] */ } { DIP { DROP /* [] */ } /* [ @some int ] */ } ; + SOME + /* [ option int ] */ } } + /* [ option int ] */ ; + NIL operation + /* [ list operation : option int ] */ ; + PAIR + /* [ pair (list operation) (option int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--min.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--min.tz].out new file mode 100644 index 000000000000..42c1f18ff275 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--min.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/min.tz] + +Well typed +Gas remaining: 1039990.871 units remaining +{ parameter (pair int int) ; + storage int ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int + : @parameter pair int int ] */ ; + CAR + /* [ int : @parameter pair int int : @parameter pair int int ] */ ; + DIP { CDR /* [ int : @parameter pair int int ] */ } + /* [ int : int : @parameter pair int int ] */ ; + CMPLT ; + IF { CAR /* [ int ] */ } { CDR /* [ int ] */ } ; + NIL operation + /* [ list operation : int ] */ ; + PAIR + /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--pair_macro.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--pair_macro.tz].out new file mode 100644 index 000000000000..a61c93ee2b5d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--pair_macro.tz].out @@ -0,0 +1,26 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/pair_macro.tz] + +Well typed +Gas remaining: 1039988.218 units remaining +{ parameter unit ; + storage unit ; + code { UNIT + /* [ unit : pair (unit @parameter) (unit @storage) ] */ ; + UNIT + /* [ unit : unit : pair (unit @parameter) (unit @storage) ] */ ; + UNIT + /* [ unit : unit : unit : pair (unit @parameter) (unit @storage) ] */ ; + UNIT + /* [ unit : unit : unit : unit : pair (unit @parameter) (unit @storage) ] */ ; + UNIT + /* [ unit : unit : unit : unit : unit : pair (unit @parameter) (unit @storage) ] */ ; + PAPAPAPAIR @name %x1 %x2 %x3 %x4 %x5 ; + CDDDAR %x4 @fourth ; + DROP + /* [ pair (unit @parameter) (unit @storage) ] */ ; + CDR + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--set_caddaadr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--set_caddaadr.tz].out new file mode 100644 index 000000000000..81ca6e6dfb34 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--set_caddaadr.tz].out @@ -0,0 +1,52 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/set_caddaadr.tz] + +Well typed +Gas remaining: 1039968.110 units remaining +{ parameter mutez ; + storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat) ; + code { DUP + /* [ pair (mutez @parameter) + (pair @storage (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat) + : pair (mutez @parameter) + (pair @storage (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat) ] */ ; + CAR + /* [ @parameter mutez + : pair (mutez @parameter) + (pair @storage (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat) ] */ ; + SWAP + /* [ pair (mutez @parameter) + (pair @storage (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat) + : @parameter mutez ] */ ; + CDR + /* [ @storage pair (pair nat nat (pair (pair (nat %p) (mutez %value)) nat) nat) nat + : @parameter mutez ] */ ; + SET_CADDAADR @toplevel_pair_name %value ; + NIL operation + /* [ list operation + : @toplevel_pair_name pair (pair @storage.car + (nat @storage.car.car) + (pair @storage.car.cdr + (nat @storage.car.cdr.car) + (pair @storage.car.cdr.cdr + (pair @storage.car.cdr.cdr.car + (pair @storage.car.cdr.cdr.car.car + (nat %p @storage.car.cdr.cdr.car.car.p) + (mutez %value @parameter)) + (nat @storage.car.cdr.cdr.car.cdr)) + (nat @storage.car.cdr.cdr.cdr)))) + (nat @storage.cdr) ] */ ; + PAIR + /* [ pair (list operation) + (pair @toplevel_pair_name + (pair @storage.car + (nat @storage.car.car) + (pair @storage.car.cdr + (nat @storage.car.cdr.car) + (pair @storage.car.cdr.cdr + (pair @storage.car.cdr.cdr.car + (pair @storage.car.cdr.cdr.car.car + (nat %p @storage.car.cdr.cdr.car.car.p) + (mutez %value @parameter)) + (nat @storage.car.cdr.cdr.car.cdr)) + (nat @storage.car.cdr.cdr.cdr)))) + (nat @storage.cdr)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--take_my_money.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--take_my_money.tz].out new file mode 100644 index 000000000000..e8bbc1fd614f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--take_my_money.tz].out @@ -0,0 +1,26 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/take_my_money.tz] + +Well typed +Gas remaining: 1039992.790 units remaining +{ parameter key_hash ; + storage unit ; + code { CAR + /* [ @parameter key_hash ] */ ; + IMPLICIT_ACCOUNT + /* [ contract unit ] */ ; + DIP { UNIT /* [ unit ] */ } + /* [ contract unit : unit ] */ ; + PUSH mutez 1000000 + /* [ mutez : contract unit : unit ] */ ; + UNIT + /* [ unit : mutez : contract unit : unit ] */ ; + TRANSFER_TOKENS + /* [ operation : unit ] */ ; + NIL operation + /* [ list operation : operation : unit ] */ ; + SWAP + /* [ operation : list operation : unit ] */ ; + CONS + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--unpair_macro.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--unpair_macro.tz].out new file mode 100644 index 000000000000..8358caec285e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[macros--unpair_macro.tz].out @@ -0,0 +1,32 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[macros/unpair_macro.tz] + +Well typed +Gas remaining: 1039976.490 units remaining +{ parameter (unit :param_unit) ; + storage (unit :u1) ; + code { DROP + /* [] */ ; + UNIT :u4 @a4 + /* [ @a4 unit :u4 ] */ ; + UNIT :u3 @a3 + /* [ @a3 unit :u3 : @a4 unit :u4 ] */ ; + UNIT :u2 @a2 + /* [ @a2 unit :u2 : @a3 unit :u3 : @a4 unit :u4 ] */ ; + UNIT :u1 @a1 + /* [ @a1 unit :u1 : @a2 unit :u2 : @a3 unit :u3 : @a4 unit :u4 ] */ ; + PAIR + /* [ pair (unit :u1 @a1) (unit :u2 @a2) : @a3 unit :u3 : @a4 unit :u4 ] */ ; + UNPAIR @x1 @x2 + /* [ @x1 unit :u1 : @x2 unit :u2 : @a3 unit :u3 : @a4 unit :u4 ] */ ; + PPAIPAIR @p1 %x1 %x2 %x3 %x4 ; + UNPPAIPAIR %x1 % %x3 %x4 @uno @due @tre @quattro ; + PAPAPAIR @p2 %x1 %x2 %x3 %x4 ; + UNPAPAPAIR @un @deux @trois @quatre ; + PAPPAIIR @p3 %x1 %x2 %x3 %x4 ; + UNPAPPAIIR @one @two @three @four ; + DIP { DROP /* [ @a3 unit :u3 : @a4 unit :u4 ] */ ; DROP /* [ @a4 unit :u4 ] */ ; DROP /* [] */ } + /* [ @x1 unit :u1 ] */ ; + NIL operation + /* [ list operation : @x1 unit :u1 ] */ ; + PAIR + /* [ pair (list operation) (unit :u1 @x1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--authentication.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--authentication.tz].out new file mode 100644 index 000000000000..8170ae63b4b5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--authentication.tz].out @@ -0,0 +1,47 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/authentication.tz] + +Well typed +Gas remaining: 1039978.751 units remaining +{ parameter (pair (lambda unit (list operation)) signature) ; + storage (pair (nat %counter) key) ; + code { UNPPAIPAIR ; + DUUUP + /* [ nat : lambda unit (list operation) : signature : nat : key ] */ ; + DUUP + /* [ lambda unit (list operation) : nat : lambda unit (list operation) + : signature : nat : key ] */ ; + SELF + /* [ @self contract (pair (lambda unit (list operation)) signature) + : lambda unit (list operation) : nat : lambda unit (list operation) + : signature : nat : key ] */ ; + CHAIN_ID + /* [ chain_id : @self contract (pair (lambda unit (list operation)) signature) + : lambda unit (list operation) : nat : lambda unit (list operation) + : signature : nat : key ] */ ; + PPAIPAIR ; + PACK + /* [ @packed bytes : lambda unit (list operation) : signature : nat : key ] */ ; + DIP { SWAP /* [ signature : lambda unit (list operation) : nat : key ] */ } + /* [ @packed bytes : signature : lambda unit (list operation) : nat : key ] */ ; + DUUUUUP + /* [ key : @packed bytes : signature : lambda unit (list operation) : nat + : key ] */ ; + DIP { SWAP + /* [ signature : @packed bytes : lambda unit (list operation) : nat : key ] */ } + /* [ key : signature : @packed bytes : lambda unit (list operation) : nat + : key ] */ ; + DUUUP + /* [ bytes : key : signature : @packed bytes : lambda unit (list operation) + : nat : key ] */ ; + DIP { CHECK_SIGNATURE /* [ bool : lambda unit (list operation) : nat : key ] */ } + /* [ bytes : bool : lambda unit (list operation) : nat : key ] */ ; + SWAP + /* [ bool : bytes : lambda unit (list operation) : nat : key ] */ ; + IF { DROP /* [ lambda unit (list operation) : nat : key ] */ } { FAILWITH /* [] */ } ; + UNIT + /* [ unit : lambda unit (list operation) : nat : key ] */ ; + EXEC + /* [ list operation : nat : key ] */ ; + DIP { PUSH nat 1 /* [ nat : nat : key ] */ ; ADD /* [ nat : key ] */ } + /* [ list operation : nat : key ] */ ; + PAPAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_entrypoints.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_entrypoints.tz].out new file mode 100644 index 000000000000..d41e74f26914 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_entrypoints.tz].out @@ -0,0 +1,132 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_entrypoints.tz] + +Well typed +Gas remaining: 1039940.196 units remaining +{ storage (pair (big_map string nat) (big_map string nat)) ; + parameter + (or (unit %default + /* [ list operation : @storage big_map string nat ] */) + (or (or %mem + (string %mem_left) + (string %mem_right) + /* [ pair (list operation) (big_map @storage string nat) ] */) + (or (or %add (pair %add_left string nat) (pair %add_right string nat)) + (or %rem (string %rem_left) (string %rem_right)))) + /* [ @storage big_map string nat ] */) + /* [ @parameter string : @storage big_map string nat ] */ ; + code { UNPAIR + /* [ @parameter or (unit %default) + (or (or %mem (string %mem_left) (string %mem_right)) + (or (or %add (pair %add_left string nat) (pair %add_right string nat)) + (or %rem (string %rem_left) (string %rem_right)))) + : @storage pair (big_map string nat) (big_map string nat) ] */ ; + IF_LEFT + { DROP + /* [ @storage pair (big_map string nat) (big_map string nat) ] */ ; + DUP + /* [ @storage pair (big_map string nat) (big_map string nat) + : @storage pair (big_map string nat) (big_map string nat) ] */ ; + CAR + /* [ big_map string nat + : @storage pair (big_map string nat) (big_map string nat) ] */ ; + PUSH mutez + 0 + /* [ mutez : big_map string nat + : @storage pair (big_map string nat) (big_map string nat) ] */ ; + NONE key_hash + /* [ option key_hash : mutez : big_map string nat + : @storage pair (big_map string nat) (big_map string nat) ] */ ; + CREATE_CONTRACT + { parameter string ; + storage (big_map string nat) ; + code { UNPAIR ; DROP ; NIL operation ; PAIR } } + /* [ operation : address + : @storage pair (big_map string nat) (big_map string nat) ] */ ; + DIP { DROP /* [ @storage pair (big_map string nat) (big_map string nat) ] */ } + /* [ operation : @storage pair (big_map string nat) (big_map string nat) ] */ ; + NIL operation + /* [ list operation : operation + : @storage pair (big_map string nat) (big_map string nat) ] */ ; + SWAP + /* [ operation : list operation + : @storage pair (big_map string nat) (big_map string nat) ] */ ; + CONS + /* [ list operation : @storage pair (big_map string nat) (big_map string nat) ] */ ; + PAIR + /* [ pair (list operation) (pair @storage (big_map string nat) (big_map string nat)) ] */ } + { IF_LEFT + { IF_LEFT + { DIP { UNPAIR /* [ big_map string nat : big_map string nat ] */ } + /* [ @parameter.right.mem.mem_left string : big_map string nat + : big_map string nat ] */ ; + DIP { DUP /* [ big_map string nat : big_map string nat : big_map string nat ] */ } + /* [ @parameter.right.mem.mem_left string : big_map string nat + : big_map string nat : big_map string nat ] */ ; + MEM + /* [ bool : big_map string nat : big_map string nat ] */ ; + ASSERT } + { DIP { UNPAIR + /* [ big_map string nat : big_map string nat ] */ ; + SWAP + /* [ big_map string nat : big_map string nat ] */ } + /* [ @parameter.right.mem.mem_right string : big_map string nat + : big_map string nat ] */ ; + DIP { DUP /* [ big_map string nat : big_map string nat : big_map string nat ] */ } + /* [ @parameter.right.mem.mem_right string : big_map string nat + : big_map string nat : big_map string nat ] */ ; + MEM + /* [ bool : big_map string nat : big_map string nat ] */ ; + ASSERT ; + SWAP + /* [ big_map string nat : big_map string nat ] */ } } + { IF_LEFT + { IF_LEFT + { UNPAIR + /* [ string : nat : @storage pair (big_map string nat) (big_map string nat) ] */ ; + DIIP { UNPAIR /* [ big_map string nat : big_map string nat ] */ } + /* [ string : nat : big_map string nat : big_map string nat ] */ ; + DIP { SOME /* [ option nat : big_map string nat : big_map string nat ] */ } + /* [ string : option nat : big_map string nat : big_map string nat ] */ ; + UPDATE + /* [ big_map string nat : big_map string nat ] */ } + { UNPAIR + /* [ string : nat : @storage pair (big_map string nat) (big_map string nat) ] */ ; + DIIP { UNPAIR + /* [ big_map string nat : big_map string nat ] */ ; + SWAP + /* [ big_map string nat : big_map string nat ] */ } + /* [ string : nat : big_map string nat : big_map string nat ] */ ; + DIP { SOME /* [ option nat : big_map string nat : big_map string nat ] */ } + /* [ string : option nat : big_map string nat : big_map string nat ] */ ; + UPDATE + /* [ big_map string nat : big_map string nat ] */ ; + SWAP + /* [ big_map string nat : big_map string nat ] */ } } + { IF_LEFT + { DIP { UNPAIR /* [ big_map string nat : big_map string nat ] */ } + /* [ @parameter.right.right.rem.rem_left string : big_map string nat + : big_map string nat ] */ ; + DIP { NONE nat /* [ option nat : big_map string nat : big_map string nat ] */ } + /* [ @parameter.right.right.rem.rem_left string : option nat + : big_map string nat : big_map string nat ] */ ; + UPDATE + /* [ big_map string nat : big_map string nat ] */ } + { DIP { UNPAIR + /* [ big_map string nat : big_map string nat ] */ ; + SWAP + /* [ big_map string nat : big_map string nat ] */ } + /* [ @parameter.right.right.rem.rem_right string : big_map string nat + : big_map string nat ] */ ; + DIP { NONE nat /* [ option nat : big_map string nat : big_map string nat ] */ } + /* [ @parameter.right.right.rem.rem_right string : option nat + : big_map string nat : big_map string nat ] */ ; + UPDATE + /* [ big_map string nat : big_map string nat ] */ ; + SWAP + /* [ big_map string nat : big_map string nat ] */ } } } ; + PAIR + /* [ pair (big_map string nat) (big_map string nat) ] */ ; + NIL operation + /* [ list operation : pair (big_map string nat) (big_map string nat) ] */ ; + PAIR + /* [ pair (list operation) (big_map string nat) (big_map string nat) ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_magic.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_magic.tz].out new file mode 100644 index 000000000000..c0b664eddbce --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_magic.tz].out @@ -0,0 +1,106 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_magic.tz] + +Well typed +Gas remaining: 1039941.750 units remaining +{ storage (or (pair (big_map string string) (big_map string string)) unit) ; + parameter + (or (unit %swap) + (or (or %reset (pair (big_map string string) (big_map string string)) unit) + (or (pair %import (list (pair string string)) (list (pair string string))) + (or (list %add (pair string string)) (list %rem string))))) ; + code { UNPAIR + /* [ @parameter or (unit %swap) + (or (or %reset (pair (big_map string string) (big_map string string)) unit) + (or (pair %import (list (pair string string)) (list (pair string string))) + (or (list %add (pair string string)) (list %rem string)))) + : @storage or (pair (big_map string string) (big_map string string)) unit ] */ ; + IF_LEFT + { DROP + /* [ @storage or (pair (big_map string string) (big_map string string)) unit ] */ ; + ASSERT_LEFT ; + UNPAIR + /* [ big_map string string : big_map string string ] */ ; + SWAP + /* [ big_map string string : big_map string string ] */ ; + PAIR + /* [ pair (big_map string string) (big_map string string) ] */ ; + LEFT unit + /* [ or (pair (big_map string string) (big_map string string)) unit ] */ } + { IF_LEFT + { SWAP + /* [ @storage or (pair (big_map string string) (big_map string string)) unit + : @parameter.right.reset or (pair (big_map string string) (big_map string string)) unit ] */ ; + DROP + /* [ @parameter.right.reset or (pair (big_map string string) (big_map string string)) unit ] */ } + { IF_LEFT + { DIP { ASSERT_RIGHT ; DROP /* [] */ } + /* [ @parameter.right.right.import pair (list (pair string string)) (list (pair string string)) ] */ ; + UNPAIR + /* [ list (pair string string) : list (pair string string) ] */ ; + DIP { EMPTY_BIG_MAP + string + string + /* [ big_map string string : list (pair string string) ] */ } + /* [ list (pair string string) : big_map string string + : list (pair string string) ] */ ; + ITER { UNPAIR + /* [ string : string : big_map string string : list (pair string string) ] */ ; + DIP { SOME + /* [ option string : big_map string string : list (pair string string) ] */ } + /* [ string : option string : big_map string string + : list (pair string string) ] */ ; + UPDATE + /* [ big_map string string : list (pair string string) ] */ } + /* [ big_map string string : list (pair string string) ] */ ; + SWAP + /* [ list (pair string string) : big_map string string ] */ ; + DIP { EMPTY_BIG_MAP string string + /* [ big_map string string : big_map string string ] */ } + /* [ list (pair string string) : big_map string string : big_map string string ] */ ; + ITER { UNPAIR + /* [ string : string : big_map string string : big_map string string ] */ ; + DIP { SOME /* [ option string : big_map string string : big_map string string ] */ } + /* [ string : option string : big_map string string : big_map string string ] */ ; + UPDATE + /* [ big_map string string : big_map string string ] */ } + /* [ big_map string string : big_map string string ] */ ; + SWAP + /* [ big_map string string : big_map string string ] */ ; + PAIR + /* [ pair (big_map string string) (big_map string string) ] */ ; + LEFT unit + /* [ or (pair (big_map string string) (big_map string string)) unit ] */ } + { IF_LEFT + { DIP { ASSERT_LEFT ; UNPAIR /* [ big_map string string : big_map string string ] */ } + /* [ @parameter.right.right.right.add list (pair string string) + : big_map string string : big_map string string ] */ ; + ITER { UNPAIR + /* [ string : string : big_map string string : big_map string string ] */ ; + DIP { SOME /* [ option string : big_map string string : big_map string string ] */ } + /* [ string : option string : big_map string string : big_map string string ] */ ; + UPDATE + /* [ big_map string string : big_map string string ] */ } + /* [ big_map string string : big_map string string ] */ ; + PAIR + /* [ pair (big_map string string) (big_map string string) ] */ ; + LEFT unit + /* [ or (pair (big_map string string) (big_map string string)) unit ] */ } + { DIP { ASSERT_LEFT ; UNPAIR /* [ big_map string string : big_map string string ] */ } + /* [ @parameter.right.right.right.rem list string : big_map string string + : big_map string string ] */ ; + ITER { DIP { NONE string + /* [ option string : big_map string string : big_map string string ] */ } + /* [ @parameter.right.right.right.rem.elt string : option string + : big_map string string : big_map string string ] */ ; + UPDATE + /* [ big_map string string : big_map string string ] */ } + /* [ big_map string string : big_map string string ] */ ; + PAIR + /* [ pair (big_map string string) (big_map string string) ] */ ; + LEFT unit + /* [ or (pair (big_map string string) (big_map string string)) unit ] */ } } } } ; + NIL operation + /* [ list operation + : or (pair (big_map string string) (big_map string string)) unit ] */ ; + PAIR + /* [ pair (list operation) (or (pair (big_map string string) (big_map string string)) unit) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_read.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_read.tz].out new file mode 100644 index 000000000000..972abc04e756 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_read.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_read.tz] + +Well typed +Gas remaining: 1039993.434 units remaining +{ storage nat ; + parameter (big_map nat nat) ; + code { CAR + /* [ @parameter big_map nat nat ] */ ; + PUSH nat 1 + /* [ nat : @parameter big_map nat nat ] */ ; + GET + /* [ option nat ] */ ; + ASSERT_SOME ; + NIL operation + /* [ list operation : @some nat ] */ ; + PAIR + /* [ pair (list operation) (nat @some) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_store.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_store.tz].out new file mode 100644 index 000000000000..186faf784886 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_store.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_store.tz] + +Well typed +Gas remaining: 1039995.896 units remaining +{ storage (big_map nat nat) ; + parameter unit ; + code { DROP + /* [] */ ; + EMPTY_BIG_MAP nat nat + /* [ big_map nat nat ] */ ; + NIL operation + /* [ list operation : big_map nat nat ] */ ; + PAIR + /* [ pair (list operation) (big_map nat nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_write.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_write.tz].out new file mode 100644 index 000000000000..bce73c2de1c7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--big_map_write.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/big_map_write.tz] + +Well typed +Gas remaining: 1039994.022 units remaining +{ storage unit ; + parameter (big_map nat nat) ; + code { UNPAIR + /* [ @parameter big_map nat nat : @storage unit ] */ ; + PUSH (option nat) + (Some 1) + /* [ option nat : @parameter big_map nat nat : @storage unit ] */ ; + PUSH nat 1 + /* [ nat : option nat : @parameter big_map nat nat : @storage unit ] */ ; + UPDATE + /* [ @parameter big_map nat nat : @storage unit ] */ ; + DROP + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract.tz].out new file mode 100644 index 000000000000..fe17421a4c85 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract.tz].out @@ -0,0 +1,75 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/create_contract.tz] + +Well typed +Gas remaining: 1039968.907 units remaining +{ parameter (option address) ; + storage unit ; + code { /* [ pair (string @parameter) (string @storage) ] */ + CAR + /* [ list operation : @parameter string ] */ ; + IF_NONE + { /* [ list operation : @parameter string ] */ + PUSH string "dummy" + /* [ string ] */ ; + PUSH mutez 100000000 + /* [ mutez : string ] */ ; + NONE key_hash + /* [ option key_hash : mutez : string ] */ ; + CREATE_CONTRACT + { parameter string ; + storage string ; + code { CAR ; NIL operation ; PAIR } } + /* [ operation : address ] */ ; + DIP { SOME + /* [ option address ] */ ; + DIP { SELF + /* [ @self contract (option address) ] */ ; + PUSH mutez 0 + /* [ mutez : @self contract (option address) ] */ } + /* [ option address : mutez : @self contract (option address) ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + NIL operation + /* [ list operation : operation ] */ ; + SWAP + /* [ operation : list operation ] */ ; + CONS + /* [ list operation ] */ } + /* [ operation : list operation ] */ ; + CONS + /* [ list operation ] */ ; + UNIT + /* [ unit : list operation ] */ ; + SWAP + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } + { SELF + /* [ @self contract (option address) : @parameter.some address ] */ ; + ADDRESS + /* [ @self.address address : @parameter.some address ] */ ; + SENDER + /* [ @sender address : @self.address address : @parameter.some address ] */ ; + IFCMPNEQ { FAIL } { /* [ @parameter.some address ] */ } ; + CONTRACT string + /* [ @parameter.some.contract option (contract string) ] */ ; + IF_SOME { /* [ @parameter.some.contract.some contract string ] */ } { FAIL } ; + PUSH mutez 0 + /* [ mutez : @parameter.some.contract.some contract string ] */ ; + PUSH string + "abcdefg" + /* [ string : mutez : @parameter.some.contract.some contract string ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + NIL operation + /* [ list operation : operation ] */ ; + SWAP + /* [ operation : list operation ] */ ; + CONS + /* [ list operation ] */ ; + UNIT + /* [ unit : list operation ] */ ; + SWAP + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract_simple.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract_simple.tz].out new file mode 100644 index 000000000000..09a505e2b3a9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--create_contract_simple.tz].out @@ -0,0 +1,29 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/create_contract_simple.tz] + +Well typed +Gas remaining: 1039989.249 units remaining +{ parameter unit ; + storage unit ; + code { CAR + /* [ @parameter string ] */ ; + PUSH string + "foo" + /* [ pair (list operation) (string @parameter) ] */ + /* [ list operation : @parameter string ] */ ; + PUSH mutez 0 + /* [ mutez : string : @parameter unit ] */ ; + NONE key_hash + /* [ option key_hash : mutez : string : @parameter unit ] */ ; + CREATE_CONTRACT + { parameter string ; + storage string ; + code { CAR ; NIL operation ; PAIR } } + /* [ operation : address : @parameter unit ] */ ; + DROP + /* [ address : @parameter unit ] */ ; + DROP + /* [ @parameter unit ] */ ; + NIL operation + /* [ list operation : @parameter unit ] */ ; + PAIR + /* [ pair (list operation) (unit @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--default_account.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--default_account.tz].out new file mode 100644 index 000000000000..0d6e700dec3e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--default_account.tz].out @@ -0,0 +1,26 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/default_account.tz] + +Well typed +Gas remaining: 1039992.790 units remaining +{ parameter key_hash ; + storage unit ; + code { DIP { UNIT /* [ unit ] */ } + /* [ pair (key_hash @parameter) (unit @storage) : unit ] */ ; + CAR + /* [ @parameter key_hash : unit ] */ ; + IMPLICIT_ACCOUNT + /* [ contract unit : unit ] */ ; + PUSH mutez 100000000 + /* [ mutez : contract unit : unit ] */ ; + UNIT + /* [ unit : mutez : contract unit : unit ] */ ; + TRANSFER_TOKENS + /* [ operation : unit ] */ ; + NIL operation + /* [ list operation : operation : unit ] */ ; + SWAP + /* [ operation : list operation : unit ] */ ; + CONS + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_appender.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_appender.tz].out new file mode 100644 index 000000000000..36cef4d6a9ea --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_appender.tz].out @@ -0,0 +1,34 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/execution_order_appender.tz] + +Well typed +Gas remaining: 1039989.364 units remaining +{ parameter unit ; + storage (pair address string) ; + code { CDR + /* [ @storage pair address string ] */ ; + DUP + /* [ @storage pair address string : @storage pair address string ] */ ; + UNPAIR + /* [ address : string : @storage pair address string ] */ ; + CONTRACT + string + /* [ @contract option (contract string) : string + : @storage pair address string ] */ ; + ASSERT_SOME ; + PUSH mutez + 0 + /* [ mutez : @contract.some contract string : string + : @storage pair address string ] */ ; + DIG 2 + /* [ string : mutez : @contract.some contract string + : @storage pair address string ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage pair address string ] */ ; + NIL operation + /* [ list operation : operation : @storage pair address string ] */ ; + SWAP + /* [ operation : list operation : @storage pair address string ] */ ; + CONS + /* [ list operation : @storage pair address string ] */ ; + PAIR + /* [ pair (list operation) (pair @storage address string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_caller.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_caller.tz].out new file mode 100644 index 000000000000..ad95e74b3045 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_caller.tz].out @@ -0,0 +1,25 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/execution_order_caller.tz] + +Well typed +Gas remaining: 1039991.291 units remaining +{ parameter unit ; + storage (list address) ; + code { CDR + /* [ @storage list address ] */ ; + DUP + /* [ @storage list address : @storage list address ] */ ; + MAP { CONTRACT + unit + /* [ @storage.elt.contract option (contract unit) : @storage list address ] */ ; + ASSERT_SOME ; + PUSH mutez + 0 + /* [ mutez : @storage.elt.contract.some contract unit : @storage list address ] */ ; + UNIT + /* [ unit : mutez : @storage.elt.contract.some contract unit + : @storage list address ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage list address ] */ } + /* [ list operation : @storage list address ] */ ; + PAIR + /* [ pair (list operation) (list @storage address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_storer.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_storer.tz].out new file mode 100644 index 000000000000..34629670e303 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--execution_order_storer.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/execution_order_storer.tz] + +Well typed +Gas remaining: 1039996.340 units remaining +{ parameter string ; + storage string ; + code { UNPAIR + /* [ @parameter string : @storage string ] */ ; + SWAP + /* [ @storage string : @parameter string ] */ ; + CONCAT + /* [ string ] */ ; + NIL operation + /* [ list operation : string ] */ ; + PAIR + /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--fa12_reference.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--fa12_reference.tz].out new file mode 100644 index 000000000000..005bcaf73f60 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--fa12_reference.tz].out @@ -0,0 +1,2761 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/fa12_reference.tz] + +Well typed +Gas remaining: 1039229.258 units remaining +{ parameter + (or (or (or (pair %transfer (address :from) (pair (address :to) (nat :value))) + (pair %approve (address :spender) (nat :value))) + (or (pair %getAllowance (pair (address :owner) (address :spender)) (contract nat)) + (or (pair %getBalance (address :owner) (contract nat)) + (pair %getTotalSupply unit (contract nat))))) + (or (or (bool %setPause) (address %setAdministrator)) + (or (pair %getAdministrator unit (contract address)) + (or (pair %mint (address :to) (nat :value)) (pair %burn (address :from) (nat :value)))))) ; + storage + (pair (big_map %ledger + (address :user) + (pair (nat :balance) (map :approvals (address :spender) (nat :value)))) + (pair (address %admin) (pair (bool %paused) (nat %totalSupply)))) ; + code { CAST (pair (or (or (or (pair address (pair address nat)) (pair address nat)) + (or (pair (pair address address) (contract nat)) + (or (pair address (contract nat)) (pair unit (contract nat))))) + (or (or bool address) + (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) + (pair (big_map address (pair nat (map address nat))) (pair address (pair bool nat)))) + /* [ pair (or (or (or (pair address address nat) (pair address nat)) + (or (pair (pair address address) (contract nat)) + (or (pair address (contract nat)) (pair unit (contract nat))))) + (or (or bool address) + (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) + (big_map address (pair nat (map address nat))) + address + bool + nat ] */ ; + DUP + /* [ pair (or (or (or (pair address address nat) (pair address nat)) + (or (pair (pair address address) (contract nat)) + (or (pair address (contract nat)) (pair unit (contract nat))))) + (or (or bool address) + (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) + (big_map address (pair nat (map address nat))) + address + bool + nat + : pair (or (or (or (pair address address nat) (pair address nat)) + (or (pair (pair address address) (contract nat)) + (or (pair address (contract nat)) (pair unit (contract nat))))) + (or (or bool address) + (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) + (big_map address (pair nat (map address nat))) + address + bool + nat ] */ ; + CAR + /* [ or (or (or (pair address address nat) (pair address nat)) + (or (pair (pair address address) (contract nat)) + (or (pair address (contract nat)) (pair unit (contract nat))))) + (or (or bool address) + (or (pair unit (contract address)) (or (pair address nat) (pair address nat)))) + : pair (or (or (or (pair address address nat) (pair address nat)) + (or (pair (pair address address) (contract nat)) + (or (pair address (contract nat)) (pair unit (contract nat))))) + (or (or bool address) + (or (pair unit (contract address)) (or (pair address nat) (pair address nat))))) + (big_map address (pair nat (map address nat))) + address + bool + nat ] */ ; + DIP { CDR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ or (or (or (pair address address nat) (pair address nat)) + (or (pair (pair address address) (contract nat)) + (or (pair address (contract nat)) (pair unit (contract nat))))) + (or (or bool address) + (or (pair unit (contract address)) (or (pair address nat) (pair address nat)))) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_LEFT + { IF_LEFT + { IF_LEFT + { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ bool + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { UNIT + /* [ unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH string + "TokenOperationsArePaused" + /* [ string : unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } + { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address address nat : pair address address nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ address : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : address : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + COMPARE + /* [ int : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { DROP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SENDER + /* [ @sender address : address : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + COMPARE + /* [ int : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SENDER + /* [ @sender address : address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (address @sender) address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair (address @sender) address : pair (address @sender) address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { EMPTY_MAP + address + nat + /* [ map address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { CDR + /* [ map address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + /* [ pair (address @sender) address : map address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ @sender address : map address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { /* [ @some nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + /* [ pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address address nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { SENDER + /* [ @sender address : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address address nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address address nat : nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ nat : nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SUB + /* [ int : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ISNAT + /* [ option nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { DIP { DUP + /* [ nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address address nat : nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address address nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : pair address address nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address address nat : nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH string + "NotEnoughAllowance" + /* [ string : pair nat nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string nat nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + /* [ @sender address : @some nat : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (address @sender) (nat @some) : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : pair (address @sender) (nat @some) : pair address address nat + : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair address (address @sender) (nat @some) : pair address address nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DROP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address (address @sender) (nat @some) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : address : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : big_map address (pair nat (map address nat)) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option (pair nat (map address nat)) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { EMPTY_MAP + address + nat + /* [ map address nat : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : map address nat : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EMPTY_MAP + address + nat + /* [ map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ map address nat : @some pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { DIP { DUP + /* [ pair address (address @sender) (nat @some) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address (address @sender) (nat @some) : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ map address nat : pair address (address @sender) (nat @some) + : pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address (address @sender) (nat @some) : map address nat + : pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair (address @sender) (nat @some) : map address nat + : pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ @some nat : map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ @some nat : @some nat : map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int : @some nat : map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : @some nat : map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { DROP + /* [ map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NONE nat + /* [ option nat : map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { SOME + /* [ option nat : map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { DIP { DIP { DUP + /* [ pair address (address @sender) (nat @some) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address (address @sender) (nat @some) : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ map address nat : pair address (address @sender) (nat @some) + : pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address (address @sender) (nat @some) : map address nat + : pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ option nat : pair address (address @sender) (nat @some) : map address nat + : pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address (address @sender) (nat @some) : option nat : map address nat + : pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair (address @sender) (nat @some) : option nat : map address nat + : pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ @sender address : option nat : map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + UPDATE + /* [ map address nat : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair nat (map address nat) : pair nat (map address nat) + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ nat : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair nat (map address nat) : nat + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ map address nat : nat : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ map address nat : map address nat : nat + : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ nat : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ map address nat : nat : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ nat : map address nat : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat (map address nat) : pair address (address @sender) (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address (address @sender) (nat @some) : pair nat (map address nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : pair nat (map address nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { SOME + /* [ option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + UPDATE + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR /* [ pair address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + DIP { DROP /* [ pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : big_map address (pair nat (map address nat)) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option (pair nat (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { NONE (pair nat (map address nat)) + /* [ option (pair nat (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { EMPTY_MAP + address + nat + /* [ map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SOME + /* [ option (pair nat (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + { DIP { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some pair nat (map address nat) : pair address address nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address address nat : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ nat : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : nat : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ADD + /* [ nat : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some pair nat (map address nat) : map address nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ nat : map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : nat : map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SOME + /* [ option (pair nat (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + SWAP + /* [ pair address address nat : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address address nat : pair address address nat + : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ pair address nat : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + UPDATE + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR /* [ pair address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + DIP { DROP /* [ pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ int : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ADD + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ISNAT + /* [ option nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { PUSH string + "Internal: Negative total supply" + /* [ string + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address bool nat : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair bool nat : pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair bool nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ bool : @some nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair bool (nat @some) : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ address : pair bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + CDR + /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool (nat @some) : pair address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool (nat @some) + : big_map address (pair nat (map address nat)) ] */ ; + SWAP + /* [ big_map address (pair nat (map address nat)) + : pair address bool (nat @some) ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ address : big_map address (pair nat (map address nat)) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + GET + /* [ option (pair nat (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + IF_NONE + { CDR + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PUSH nat + 0 + /* [ nat : nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ nat : nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PAIR + /* [ pair nat nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PUSH string + "NotEnoughBalance" + /* [ string : pair nat nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PAIR + /* [ pair string nat nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + FAILWITH + /* [] */ } + { /* [ @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; + DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CAR + /* [ nat : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DIP { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ @some pair nat (map address nat) : pair address address nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ pair address address nat : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ nat : pair address address nat : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ pair address address nat : nat : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ pair address nat : nat : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ nat : nat : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ nat : nat : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SUB + /* [ int : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + ISNAT + /* [ option nat : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + IF_NONE + { CAR + /* [ nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ nat : pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ pair address address nat : nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ pair address nat : nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ nat : nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PAIR + /* [ pair nat nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PUSH string + "NotEnoughBalance" + /* [ string : pair nat nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PAIR + /* [ pair string nat nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat : @some pair nat (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; + DIP { DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { CDR + /* [ map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ @some pair nat (map address nat) : map address nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CAR + /* [ nat : map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ @some nat : nat : map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DROP + /* [ map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ @some nat : map address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PAIR + /* [ pair (nat @some) (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair (nat @some) (map address nat) : pair address address nat + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ pair address address nat : pair (nat @some) (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair (nat @some) (map address nat) : pair (nat @some) (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CAR + /* [ @some nat : pair (nat @some) (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + INT + /* [ int : pair (nat @some) (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + EQ + /* [ bool : pair (nat @some) (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + IF { DUP + /* [ pair (nat @some) (map address nat) : pair (nat @some) (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ map address nat : pair (nat @some) (map address nat) + : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SIZE + /* [ nat : pair (nat @some) (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + INT + /* [ int : pair (nat @some) (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + EQ + /* [ bool : pair (nat @some) (map address nat) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + IF { DROP + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + NONE (pair nat (map address nat)) + /* [ option (pair nat (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + { SOME + /* [ option (pair (nat @some) (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } } + { SOME + /* [ option (pair (nat @some) (map address nat)) : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; + SWAP + /* [ pair address address nat : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CAR + /* [ address : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ address : option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + UPDATE + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { CDR /* [ pair address bool (nat @some) ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair address bool (nat @some) ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) + : pair address bool (nat @some) ] */ } + /* [ big_map address (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair address bool (nat @some) ] */ ; + DIP { DROP /* [ pair address bool (nat @some) ] */ } + /* [ big_map address (pair nat (map address nat)) + : pair address bool (nat @some) ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DUP + /* [ pair address address nat : pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { CDR + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + NEG + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ pair address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ pair bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ @some nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ int : @some nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + ADD + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + ISNAT + /* [ option nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + IF_NONE + { PUSH string + "Internal: Negative total supply" + /* [ string + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ pair address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ @some nat : pair address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair address bool (nat @some) : pair address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair address bool (nat @some) : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ pair bool (nat @some) : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ @some nat : pair bool (nat @some) : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair bool (nat @some) : pair bool (nat @some) : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { CAR + /* [ bool : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair bool (nat @some) : bool : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + CDR + /* [ @some nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ @some nat : @some nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DROP + /* [ bool : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ @some nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ bool : @some nat : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PAIR + /* [ pair bool (nat @some) : address + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + SWAP + /* [ address : pair bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PAIR + /* [ pair address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) + : big_map address (pair nat (map address nat)) ] */ ; + CDR + /* [ pair address bool (nat @some) + : big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool (nat @some) : pair address bool (nat @some) + : big_map address (pair nat (map address nat)) ] */ ; + DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool (nat @some) + : big_map address (pair nat (map address nat)) ] */ ; + SWAP + /* [ big_map address (pair nat (map address nat)) + : pair address bool (nat @some) ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair address address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DROP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } ; + NIL operation + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } + { SENDER + /* [ @sender address : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ bool + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { UNIT + /* [ unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH string + "TokenOperationsArePaused" + /* [ string : unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } + { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + /* [ pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (address @sender) address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (address @sender) address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair (address @sender) address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ @sender address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @sender address : big_map address (pair nat (map address nat)) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option (pair nat (map address nat)) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { EMPTY_MAP + address + nat + /* [ map address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { CDR + /* [ map address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + /* [ pair (address @sender) address nat : map address nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : map address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : map address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { /* [ @some nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DUP + /* [ nat : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { DROP + /* [ pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { DIP { DUP + /* [ pair (address @sender) address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : pair (address @sender) address nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (address @sender) address nat : nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { DROP + /* [ pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { PUSH string + "UnsafeAllowanceChange" + /* [ string : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } } ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (address @sender) address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ @sender address : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : @sender address : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ @sender address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @sender address : big_map address (pair nat (map address nat)) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option (pair nat (map address nat)) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { EMPTY_MAP + address + nat + /* [ map address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : map address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat (map address nat) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EMPTY_MAP + address + nat + /* [ map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ map address nat : @some pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { DIP { DUP + /* [ pair (address @sender) address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair nat (map address nat) : pair (address @sender) address nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (address @sender) address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ map address nat : pair (address @sender) address nat + : pair nat (map address nat) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (address @sender) address nat : map address nat + : pair nat (map address nat) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ nat : nat : map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int : nat : map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : nat : map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { DROP + /* [ map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NONE nat + /* [ option nat : map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { SOME + /* [ option nat : map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { DIP { DIP { DUP + /* [ pair (address @sender) address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair nat (map address nat) : pair (address @sender) address nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (address @sender) address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ map address nat : pair (address @sender) address nat + : pair nat (map address nat) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (address @sender) address nat : map address nat + : pair nat (map address nat) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ option nat : pair (address @sender) address nat : map address nat + : pair nat (map address nat) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (address @sender) address nat : option nat : map address nat + : pair nat (map address nat) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address nat : option nat : map address nat + : pair nat (map address nat) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : option nat : map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + UPDATE + /* [ map address nat : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair nat (map address nat) : pair nat (map address nat) + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair nat (map address nat) : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ map address nat : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ map address nat : map address nat : nat + : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ map address nat : nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ nat : map address nat : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat (map address nat) : pair (address @sender) address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (address @sender) address nat : pair nat (map address nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ @sender address : pair nat (map address nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { SOME + /* [ option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @sender address : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @sender address : option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + UPDATE + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR /* [ pair address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + DIP { DROP /* [ pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NIL operation + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } } + { IF_LEFT + { DUP + /* [ pair (pair address address) (contract nat) + : pair (pair address address) (contract nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ pair address address : pair (pair address address) (contract nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address address : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address address + : pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (pair address address) + (big_map address (pair nat (map address nat))) + address + bool + nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair (pair address address) + (big_map address (pair nat (map address nat))) + address + bool + nat + : pair (pair address address) + (big_map address (pair nat (map address nat))) + address + bool + nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ pair address address + : pair (pair address address) + (big_map address (pair nat (map address nat))) + address + bool + nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address address + : pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address address : pair address address + : pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : big_map address (pair nat (map address nat)) : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option (pair nat (map address nat)) : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { EMPTY_MAP + address + nat + /* [ map address nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { CDR + /* [ map address nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + /* [ pair address address : map address nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ address : map address nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { /* [ @some nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { AMOUNT + /* [ @amount mutez : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : @amount mutez : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NIL operation + /* [ list operation : operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ operation : list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CONS + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } + { IF_LEFT + { DUP + /* [ pair address (contract nat) : pair address (contract nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : pair address (contract nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair address (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address (big_map address (pair nat (map address nat))) address bool nat + : pair address (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address + : pair address (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : big_map address (pair nat (map address nat)) : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option (pair nat (map address nat)) : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { CAR + /* [ nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { AMOUNT + /* [ @amount mutez : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : @amount mutez : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NIL operation + /* [ list operation : operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ operation : list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CONS + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } + { DUP + /* [ pair unit (contract nat) : pair unit (contract nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ unit : pair unit (contract nat) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ unit : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ unit : pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair unit (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { AMOUNT + /* [ @amount mutez : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : @amount mutez : contract nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NIL operation + /* [ list operation : operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ operation : list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CONS + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } } } } + { IF_LEFT + { IF_LEFT + { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SENDER + /* [ @sender address : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + COMPARE + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { UNIT + /* [ unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH string + "SenderIsNotAdmin" + /* [ string : unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } } + /* [ bool + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ bool : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address bool nat : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ bool : pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair bool nat : pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair bool nat : nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ bool : nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ bool : bool : nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ bool : nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ address : pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + CDR + /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool nat : pair address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ ; + SWAP + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NIL operation + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } + { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SENDER + /* [ @sender address : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + COMPARE + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { UNIT + /* [ unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH string + "SenderIsNotAdmin" + /* [ string : unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } } + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address bool nat : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address bool nat : pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : address : pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + CDR + /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool nat : pair address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ ; + SWAP + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NIL operation + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } } + { IF_LEFT + { DUP + /* [ pair unit (contract address) : pair unit (contract address) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ unit : pair unit (contract address) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ unit : contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ contract address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ unit : pair (big_map address (pair nat (map address nat))) address bool nat + : contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair unit (big_map address (pair nat (map address nat))) address bool nat + : contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat : contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { AMOUNT + /* [ @amount mutez : contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : @amount mutez : contract address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NIL operation + /* [ list operation : operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ operation : list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CONS + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (list operation) (big_map address (pair nat (map address nat))) address bool nat ] */ } + { IF_LEFT + { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SENDER + /* [ @sender address : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + COMPARE + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { UNIT + /* [ unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH string + "SenderIsNotAdmin" + /* [ string : unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } } + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : big_map address (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { NONE (pair nat (map address nat)) + /* [ option (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { EMPTY_MAP + address + nat + /* [ map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SOME + /* [ option (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + { DIP { DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some pair nat (map address nat) : pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ADD + /* [ nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some pair nat (map address nat) : map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ nat : map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : nat : map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SOME + /* [ option (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + SWAP + /* [ pair address nat : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address nat : pair address nat : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ address : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + UPDATE + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR /* [ pair address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + DIP { DROP /* [ pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ int : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ADD + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ISNAT + /* [ option nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { PUSH string + "Internal: Negative total supply" + /* [ string + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address bool nat : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair bool nat : pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair bool nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ bool : @some nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair bool (nat @some) : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ address : pair bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + CDR + /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool (nat @some) : pair address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool (nat @some) + : big_map address (pair nat (map address nat)) ] */ ; + SWAP + /* [ big_map address (pair nat (map address nat)) + : pair address bool (nat @some) ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DROP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + NIL operation + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PAIR + /* [ pair (list operation) + (big_map address (pair nat (map address nat))) + address + bool + (nat @some) ] */ } + { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SENDER + /* [ @sender address : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + COMPARE + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { UNIT + /* [ unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH string + "SenderIsNotAdmin" + /* [ string : unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string unit + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } } + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ big_map address (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : big_map address (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + GET + /* [ option (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { CDR + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH nat + 0 + /* [ nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ nat : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH string + "NotEnoughBalance" + /* [ string : pair nat nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string nat nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } + { /* [ @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some pair nat (map address nat) : pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : pair address nat : @some pair nat (map address nat) + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address nat : nat : @some pair nat (map address nat) + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ nat : nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SUB + /* [ int : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ISNAT + /* [ option nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { CAR + /* [ nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ nat : pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address nat : nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair nat nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PUSH string + "NotEnoughBalance" + /* [ string : pair nat nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair string nat nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat : @some pair nat (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { DUP + /* [ @some pair nat (map address nat) : @some pair nat (map address nat) + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some pair nat (map address nat) : map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ nat : map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : nat : map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : map address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair (nat @some) (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair (nat @some) (map address nat) : pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ pair address nat : pair (nat @some) (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (nat @some) (map address nat) : pair (nat @some) (map address nat) + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ @some nat : pair (nat @some) (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int : pair (nat @some) (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : pair (nat @some) (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { DUP + /* [ pair (nat @some) (map address nat) : pair (nat @some) (map address nat) + : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ map address nat : pair (nat @some) (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SIZE + /* [ nat : pair (nat @some) (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + INT + /* [ int : pair (nat @some) (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + EQ + /* [ bool : pair (nat @some) (map address nat) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF { DROP + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NONE (pair nat (map address nat)) + /* [ option (pair nat (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + { SOME + /* [ option (pair (nat @some) (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } } + { SOME + /* [ option (pair (nat @some) (map address nat)) : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + SWAP + /* [ pair address nat : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ address : option (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ address : option (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + UPDATE + /* [ big_map address (pair nat (map address nat)) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR /* [ pair address bool nat ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair address bool nat ] */ ; + CAR + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) + : big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + DIP { DROP /* [ pair address bool nat ] */ } + /* [ big_map address (pair nat (map address nat)) : pair address bool nat ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DUP + /* [ pair address nat : pair address nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CDR + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + NEG + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ int : nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ADD + /* [ int + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + ISNAT + /* [ option nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + IF_NONE + { PUSH string + "Internal: Negative total supply" + /* [ string + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair address bool nat : pair address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair address bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair bool nat : pair bool nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR + /* [ bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ pair bool nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + CDR + /* [ nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DROP + /* [ bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ } + /* [ @some nat : bool : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ bool : @some nat : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair bool (nat @some) : address + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + SWAP + /* [ address : pair bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + PAIR + /* [ pair address bool (nat @some) + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { DUP + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : pair (big_map address (pair nat (map address nat))) address bool nat ] */ ; + DIP { CAR /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair (big_map address (pair nat (map address nat))) address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + CDR + /* [ pair address bool nat : big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool (nat @some) : pair address bool nat + : big_map address (pair nat (map address nat)) ] */ ; + DIP { DROP /* [ big_map address (pair nat (map address nat)) ] */ } + /* [ pair address bool (nat @some) + : big_map address (pair nat (map address nat)) ] */ ; + SWAP + /* [ big_map address (pair nat (map address nat)) + : pair address bool (nat @some) ] */ ; + PAIR + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ } + /* [ pair address nat + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + DROP + /* [ pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + NIL operation + /* [ list operation + : pair (big_map address (pair nat (map address nat))) address bool (nat @some) ] */ ; + PAIR + /* [ pair (list operation) + (big_map address (pair nat (map address nat))) + address + bool + (nat @some) ] */ } } } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--generic_multisig.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--generic_multisig.tz].out new file mode 100644 index 000000000000..7d056c6f0916 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--generic_multisig.tz].out @@ -0,0 +1,438 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/generic_multisig.tz] + +Well typed +Gas remaining: 1039928.421 units remaining +{ parameter + (or (unit %default) + (pair %main + (pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)))) + (list %sigs (option signature)))) ; + storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; + code { UNPAIR + /* [ @parameter or (unit %default) + (pair %main + (pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)))) + (list %sigs (option signature))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + IF_LEFT + { DROP + /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + NIL operation + /* [ list operation + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage (nat %stored_counter) (nat %threshold) (list %keys key)) ] */ } + { PUSH mutez + 0 + /* [ mutez + : @parameter.main pair (pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)))) + (list %sigs (option signature)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + AMOUNT + /* [ @amount mutez : mutez + : @parameter.main pair (pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)))) + (list %sigs (option signature)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ASSERT_CMPEQ ; + SWAP + /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @parameter.main pair (pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)))) + (list %sigs (option signature)) ] */ ; + DUP + /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @parameter.main pair (pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)))) + (list %sigs (option signature)) ] */ ; + DIP { SWAP + /* [ @parameter.main pair (pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)))) + (list %sigs (option signature)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @parameter.main pair (pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)))) + (list %sigs (option signature)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { UNPAIR + /* [ pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DUP + /* [ pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SELF + /* [ @self contract unit + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ADDRESS + /* [ @self.address address + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + CHAIN_ID + /* [ chain_id : @self.address address + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + PAIR + /* [ pair chain_id (address @self.address) + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + PAIR + /* [ pair (pair chain_id (address @self.address)) + (pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)))) + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + PACK + /* [ @packed bytes + : pair :payload + (nat %counter) + (or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { UNPAIR @counter + /* [ @counter nat + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { SWAP + /* [ list (option signature) + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @counter nat : list (option signature) + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @packed bytes : @counter nat : list (option signature) + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ @counter nat : @packed bytes : list (option signature) + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @counter nat : @packed bytes : list (option signature) + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + UNPAIR @stored_counter + /* [ @stored_counter nat : pair (nat %threshold) (list %keys key) : @counter nat + : @packed bytes : list (option signature) + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { SWAP + /* [ @counter nat : pair (nat %threshold) (list %keys key) : @packed bytes + : list (option signature) + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @stored_counter nat : @counter nat : pair (nat %threshold) (list %keys key) + : @packed bytes : list (option signature) + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ASSERT_CMPEQ ; + DIP { SWAP + /* [ list (option signature) : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ pair (nat %threshold) (list %keys key) : list (option signature) + : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + UNPAIR @threshold @keys + /* [ @threshold nat : @keys list key : list (option signature) : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { PUSH @valid + nat + 0 + /* [ @valid nat : @keys list key : list (option signature) : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ @keys list key : @valid nat : list (option signature) : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ITER { DIP { SWAP + /* [ list (option signature) : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @keys.elt key : list (option signature) : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ list (option signature) : @keys.elt key : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + IF_CONS + { IF_SOME + { SWAP + /* [ @tl list (option signature) : @hd.some signature : @keys.elt key + : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { SWAP + /* [ @keys.elt key : @hd.some signature : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIIP { DUUP + /* [ bytes : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @keys.elt key : @hd.some signature : bytes : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + { DUUUP + /* [ bytes : @keys.elt key : @hd.some signature : bytes : @valid nat + : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { CHECK_SIGNATURE + /* [ bool : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ bytes : bool : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ bool : bytes : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + IF { DROP + /* [ @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + { FAILWITH /* [] */ } } ; + PUSH nat + 1 + /* [ nat : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ADD @valid + /* [ @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @tl list (option signature) : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + { SWAP + /* [ @keys.elt key : @tl list (option signature) : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DROP + /* [ @tl list (option signature) : @valid nat : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } } + { FAIL } ; + SWAP + /* [ @valid nat : @tl list (option signature) : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @valid nat : list (option signature) : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @threshold nat : @valid nat : list (option signature) : @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ASSERT_CMPLE ; + IF_CONS + { FAIL } + { /* [ @packed bytes + : or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } ; + DROP + /* [ or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { UNPAIR + /* [ nat : pair (nat %threshold) (list %keys key) ] */ ; + PUSH nat 1 + /* [ nat : nat : pair (nat %threshold) (list %keys key) ] */ ; + ADD @new_counter + /* [ @new_counter nat : pair (nat %threshold) (list %keys key) ] */ ; + PAIR + /* [ pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } + /* [ or :action + (lambda %operation unit (list operation)) + (pair %change_keys (nat %threshold) (list %keys key)) + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; + IF_LEFT + { UNIT + /* [ unit : @operation lambda unit (list operation) + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; + EXEC + /* [ list operation + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } + { DIP { CAR /* [ @new_counter nat ] */ } + /* [ @change_keys pair (nat %threshold) (list %keys key) : @new_counter nat ] */ ; + SWAP + /* [ @new_counter nat : @change_keys pair (nat %threshold) (list %keys key) ] */ ; + PAIR + /* [ pair (nat @new_counter) (pair @change_keys (nat %threshold) (list %keys key)) ] */ ; + NIL operation + /* [ list operation + : pair (nat @new_counter) (pair @change_keys (nat %threshold) (list %keys key)) ] */ } ; + PAIR + /* [ pair (list operation) (nat @new_counter) (nat %threshold) (list %keys key) ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--groth16.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--groth16.tz].out new file mode 100644 index 000000000000..f9c2c339693a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--groth16.tz].out @@ -0,0 +1,233 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/groth16.tz] + +Well typed +Gas remaining: 1039478.027 units remaining +{ storage unit ; + parameter + (pair (pair (bls12_381_fr %input_x) (bls12_381_fr %input_y)) + (pair (pair (bls12_381_g1 %proof_a) (bls12_381_g2 %proof_b)) (bls12_381_g1 %proof_c))) ; + code { CAR + /* [ @parameter pair (pair (bls12_381_fr %input_x) (bls12_381_fr %input_y)) + (pair (bls12_381_g1 %proof_a) (bls12_381_g2 %proof_b)) + (bls12_381_g1 %proof_c) ] */ ; + UNPPAIPPAIIR ; + DIP 5 + { PUSH @vk_gamma_c + bls12_381_g1 + 0x063bd6e11e2fcaac1dd8cf68c6b1925a73c3c583e298ed37c41c3715115cf96358a42dbe85a0228cbfd8a6c8a8c54cd015b5ae2860d1cc47f84698d951f14d9448d03f04df2ca0ffe609a2067d6f1a892163a5e05e541279134cae52b1f23c6b + /* [ @vk_gamma_c bls12_381_g1 ] */ ; + PUSH @vk_gamma_b + bls12_381_g1 + 0x11f5b5db1da7f1f26217edcce2219d016003af6e5b4d1ca3ad0ff477e354717e658bf16beddc4f4fb76ce39d3327811e0601709dc7ed98c70463cfa1ba33f99851b52b51d1a042d7425bec6277287441c399973632445ce61e7fdd63a70f0f60 + /* [ @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + PUSH @vk_gamma_a + bls12_381_g1 + 0x03535a322edd23c55b0ca025e54d450d95df49cc9ee873dcd500e8219f4771264bf159b3b105954d85c7bea8ffe1ea0400c767fe58989366c2837fba76f1b4f46644f19be8ad01e22d894b649e427e0d7e04677ee3919d982f0f96bb0a2f0c34 + /* [ @vk_gamma_a bls12_381_g1 : @vk_gamma_b bls12_381_g1 + : @vk_gamma_c bls12_381_g1 ] */ ; + PUSH @vk_delta + bls12_381_g2 + 0x10c6d5cdca84fc3c7f33061add256f48e0ab03a697832b338901898b650419eb6f334b28153fb73ad2ecd1cd2ac67053161e9f46cfbdaf7b1132a4654a55162850249650f9b873ac3113fa8c02ef1cd1df481480a4457f351d28f4da89d19fa405c3d77f686dc9a24d2681c9184bf2b091f62e6b24df651a3da8bd7067e14e7908fb02f8955b84af5081614cb5bc49b416d9edf914fc608c441b3f2eb8b6043736ddb9d4e4d62334a23b5625c14ef3e1a7e99258386310221b22d83a5eac035c + /* [ @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + PUSH @vk_gamma + bls12_381_g2 + 0x16dcbd28bff336c2649c7dd1d8391ac7ce6f7ef0124a9db7a4a485a124199eded7ce963c1c18aee1eca9994fe06f192c00e0fb653e1fc737d8d0e2f2f91424ca01f6e6e7c5c04f1c43db03a2900cf6b942aaed6ae77daea6200e094b78c38d770028d531a9d1a118ec23d5a39be7aa6dc28f778da1988856d2235c4a35e81fa48380f050d4baf7ebd7b5e058bf294da916afc34562f097c02a8fcbcf62a00de44f8ae6cfa7acb8ad254e3aeea8b2af12f65b7ee0f54855cb9bd432f3436f238f + /* [ @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + PUSH @vk_b + bls12_381_g2 + 0x0e9383f98df2c6e8b5b45f3876c3384596a0cdbc41349f83c4380bf463a050cdbd1d5057aa483a642e66486d1ed7362a1869e423c3877095e215c17282b11108601166f928043254bbce603bf86f4cec9f2e97e9660e98e4f5bce9b2b3bbacb40946b702ccfcc9a31e0bfc1543a2128edcc95807740a2310ae25eb47b935648e392c58dfae5b5e899d3b970d64e4e9e209741ea8bfedcfcc16b3fd890ff02c788ec0943feaaf01bbb354317acb85fcfd611133e4e563d53ca4e0f50e21cf2e7e + /* [ @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 + : @vk_gamma_a bls12_381_g1 : @vk_gamma_b bls12_381_g1 + : @vk_gamma_c bls12_381_g1 ] */ ; + PUSH @vk_a + bls12_381_g1 + 0x1040577c7d349e332735fc947c868c24a665f812f5dc1e7f60e65e2df80be2267a4b7341ed2287285fccd517acd96d910abba947235c364553aa6445f2f2b3a1a728225a330286ba5197ab87f0edc560d89fc7b623812f7d0d633341726e597a + /* [ @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ } + /* [ bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP + /* [ bls12_381_fr : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 + : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 12 + /* [ bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + MUL + /* [ bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 + : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 3 + /* [ bls12_381_fr : bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 14 + /* [ bls12_381_g1 : bls12_381_fr : bls12_381_g1 : bls12_381_fr : bls12_381_fr + : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 + : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 + : @vk_gamma_a bls12_381_g1 : @vk_gamma_b bls12_381_g1 + : @vk_gamma_c bls12_381_g1 ] */ ; + MUL + /* [ bls12_381_g1 : bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + ADD + /* [ bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 + : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 11 + /* [ bls12_381_g1 : bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + ADD @vk_x + /* [ @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + NIL (pair bls12_381_g1 bls12_381_g2) + /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr + : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 9 + /* [ bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 + : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 9 + /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + NEG + /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + PAIR + /* [ pair bls12_381_g1 bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + CONS + /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr + : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 11 + /* [ bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 + : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 8 + /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + NEG + /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + PAIR + /* [ pair bls12_381_g1 bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + CONS + /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr + : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 10 + /* [ bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 + : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 3 + /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + NEG + /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + PAIR + /* [ pair bls12_381_g1 bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + CONS + /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr + : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 6 + /* [ bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 + : bls12_381_fr : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + DUP 6 + /* [ bls12_381_g1 : bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + PAIR + /* [ pair bls12_381_g1 bls12_381_g2 : list (pair bls12_381_g1 bls12_381_g2) + : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + CONS + /* [ list (pair bls12_381_g1 bls12_381_g2) : @vk_x bls12_381_g1 : bls12_381_fr + : bls12_381_fr : bls12_381_g1 : bls12_381_g2 : bls12_381_g1 + : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 : @vk_gamma bls12_381_g2 + : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + PAIRING_CHECK + /* [ bool : @vk_x bls12_381_g1 : bls12_381_fr : bls12_381_fr : bls12_381_g1 + : bls12_381_g2 : bls12_381_g1 : @vk_a bls12_381_g1 : @vk_b bls12_381_g2 + : @vk_gamma bls12_381_g2 : @vk_delta bls12_381_g2 : @vk_gamma_a bls12_381_g1 + : @vk_gamma_b bls12_381_g1 : @vk_gamma_c bls12_381_g1 ] */ ; + ASSERT ; + DROP 13 + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--hardlimit.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--hardlimit.tz].out new file mode 100644 index 000000000000..07619ac50efb --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--hardlimit.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/hardlimit.tz] + +Well typed +Gas remaining: 1039991.583 units remaining +{ parameter unit ; + storage int ; + code { CDR + /* [ @storage int ] */ ; + DUP + /* [ @storage int : @storage int ] */ ; + PUSH int 0 + /* [ int : @storage int : @storage int ] */ ; + CMPLT ; + IF { PUSH int -1 /* [ int : @storage int ] */ ; ADD /* [ int ] */ } { FAIL } ; + NIL operation + /* [ list operation : int ] */ ; + PAIR + /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--legacy_multisig.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--legacy_multisig.tz].out new file mode 100644 index 000000000000..285bf7585614 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--legacy_multisig.tz].out @@ -0,0 +1,501 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/legacy_multisig.tz] + +Well typed +Gas remaining: 1039931.026 units remaining +{ parameter + (pair (pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))))) + (list %sigs (option signature))) ; + storage (pair (nat %stored_counter) (pair (nat %threshold) (list %keys key))) ; + code { UNPAIR + /* [ @parameter pair (pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))))) + (list %sigs (option signature)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @parameter pair (pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))))) + (list %sigs (option signature)) ] */ ; + DUP + /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @parameter pair (pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))))) + (list %sigs (option signature)) ] */ ; + DIP { SWAP + /* [ @parameter pair (pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))))) + (list %sigs (option signature)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @parameter pair (pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))))) + (list %sigs (option signature)) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { UNPAIR + /* [ pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DUP + /* [ pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SELF + /* [ @self contract + (pair (pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))))) + (list %sigs (option signature))) + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ADDRESS + /* [ @self.address address + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + CHAIN_ID + /* [ chain_id : @self.address address + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + PAIR + /* [ pair chain_id (address @self.address) + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + PAIR + /* [ pair (pair chain_id (address @self.address)) + (pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))))) + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + PACK + /* [ @packed bytes + : pair :payload + (nat %counter) + (or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key)))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { UNPAIR @counter + /* [ @counter nat + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : list (option signature) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { SWAP + /* [ list (option signature) + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @counter nat : list (option signature) + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @packed bytes : @counter nat : list (option signature) + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ @counter nat : @packed bytes : list (option signature) + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) + : @counter nat : @packed bytes : list (option signature) + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + UNPAIR @stored_counter + /* [ @stored_counter nat : pair (nat %threshold) (list %keys key) : @counter nat + : @packed bytes : list (option signature) + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { SWAP + /* [ @counter nat : pair (nat %threshold) (list %keys key) : @packed bytes + : list (option signature) + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @stored_counter nat : @counter nat : pair (nat %threshold) (list %keys key) + : @packed bytes : list (option signature) + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ASSERT_CMPEQ ; + DIP { SWAP + /* [ list (option signature) : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ pair (nat %threshold) (list %keys key) : list (option signature) + : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + UNPAIR @threshold @keys + /* [ @threshold nat : @keys list key : list (option signature) : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { PUSH @valid + nat + 0 + /* [ @valid nat : @keys list key : list (option signature) : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ @keys list key : @valid nat : list (option signature) : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ITER { DIP { SWAP + /* [ list (option signature) : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @keys.elt key : list (option signature) : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ list (option signature) : @keys.elt key : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + IF_CONS + { IF_SOME + { SWAP + /* [ @tl list (option signature) : @hd.some signature : @keys.elt key + : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { SWAP + /* [ @keys.elt key : @hd.some signature : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIIP { DUUP + /* [ bytes : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @keys.elt key : @hd.some signature : bytes : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + { DUUUP + /* [ bytes : @keys.elt key : @hd.some signature : bytes : @valid nat + : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { CHECK_SIGNATURE + /* [ bool : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ bytes : bool : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ bool : bytes : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + IF { DROP + /* [ @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + { FAILWITH /* [] */ } } ; + PUSH nat + 1 + /* [ nat : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ADD @valid + /* [ @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @tl list (option signature) : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + { SWAP + /* [ @keys.elt key : @tl list (option signature) : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DROP + /* [ @tl list (option signature) : @valid nat : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } } + { FAIL } ; + SWAP + /* [ @valid nat : @tl list (option signature) : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @valid nat : list (option signature) : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ } + /* [ @threshold nat : @valid nat : list (option signature) : @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + ASSERT_CMPLE ; + DROP + /* [ @packed bytes + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DROP + /* [ or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : @storage pair (nat %stored_counter) (nat %threshold) (list %keys key) ] */ ; + DIP { UNPAIR + /* [ nat : pair (nat %threshold) (list %keys key) ] */ ; + PUSH nat 1 + /* [ nat : nat : pair (nat %threshold) (list %keys key) ] */ ; + ADD @new_counter + /* [ @new_counter nat : pair (nat %threshold) (list %keys key) ] */ ; + PAIR + /* [ pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } + /* [ or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; + NIL operation + /* [ list operation + : or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; + SWAP + /* [ or :action + (pair :transfer (mutez %amount) (contract %dest unit)) + (or (option %delegate key_hash) + (pair %change_keys (nat %threshold) (list %keys key))) : list operation + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; + IF_LEFT + { UNPAIR + /* [ mutez : contract unit : list operation + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; + UNIT + /* [ unit : mutez : contract unit : list operation + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; + TRANSFER_TOKENS + /* [ operation : list operation + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; + CONS + /* [ list operation + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } + { IF_LEFT + { SET_DELEGATE + /* [ operation : list operation + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ ; + CONS + /* [ list operation + : pair (nat @new_counter) (nat %threshold) (list %keys key) ] */ } + { DIP { SWAP + /* [ pair (nat @new_counter) (nat %threshold) (list %keys key) + : list operation ] */ ; + CAR + /* [ @new_counter nat : list operation ] */ } + /* [ @change_keys pair (nat %threshold) (list %keys key) : @new_counter nat + : list operation ] */ ; + SWAP + /* [ @new_counter nat : @change_keys pair (nat %threshold) (list %keys key) + : list operation ] */ ; + PAIR + /* [ pair (nat @new_counter) (pair @change_keys (nat %threshold) (list %keys key)) + : list operation ] */ ; + SWAP + /* [ list operation + : pair (nat @new_counter) (pair @change_keys (nat %threshold) (list %keys key)) ] */ } } ; + PAIR + /* [ pair (list operation) (nat @new_counter) (nat %threshold) (list %keys key) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lockup.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lockup.tz].out new file mode 100644 index 000000000000..33e437ec7728 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lockup.tz].out @@ -0,0 +1,48 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/lockup.tz] + +Well typed +Gas remaining: 1039981.235 units remaining +{ parameter unit ; + storage (pair timestamp (pair mutez address)) ; + code { CDR + /* [ @storage pair timestamp mutez address ] */ ; + DUP + /* [ @storage pair timestamp mutez address + : @storage pair timestamp mutez address ] */ ; + CAR + /* [ timestamp : @storage pair timestamp mutez address ] */ ; + NOW + /* [ @now timestamp : timestamp : @storage pair timestamp mutez address ] */ ; + CMPLT ; + IF { FAIL } { /* [ @storage pair timestamp mutez address ] */ } ; + DUP + /* [ @storage pair timestamp mutez address + : @storage pair timestamp mutez address ] */ ; + CDR + /* [ pair mutez address : @storage pair timestamp mutez address ] */ ; + DUP + /* [ pair mutez address : pair mutez address + : @storage pair timestamp mutez address ] */ ; + CAR + /* [ mutez : pair mutez address : @storage pair timestamp mutez address ] */ ; + DIP { CDR /* [ address : @storage pair timestamp mutez address ] */ } + /* [ mutez : address : @storage pair timestamp mutez address ] */ ; + DIP { CONTRACT + unit + /* [ @contract option (contract unit) : @storage pair timestamp mutez address ] */ ; + ASSERT_SOME } + /* [ mutez : @contract.some contract unit + : @storage pair timestamp mutez address ] */ ; + UNIT + /* [ unit : mutez : @contract.some contract unit + : @storage pair timestamp mutez address ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage pair timestamp mutez address ] */ ; + NIL operation + /* [ list operation : operation : @storage pair timestamp mutez address ] */ ; + SWAP + /* [ operation : list operation : @storage pair timestamp mutez address ] */ ; + CONS + /* [ list operation : @storage pair timestamp mutez address ] */ ; + PAIR + /* [ pair (list operation) (pair @storage timestamp mutez address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lqt_fa12.mligo.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lqt_fa12.mligo.tz].out new file mode 100644 index 000000000000..783357fc8422 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--lqt_fa12.mligo.tz].out @@ -0,0 +1,2834 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/lqt_fa12.mligo.tz] + +Well typed +Gas remaining: 1039662.882 units remaining +{ parameter + (or (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (pair (address %to) (nat %value))))) ; + storage + (pair (big_map %tokens address nat) + (pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (pair (address %admin) (nat %total_supply)))) ; + code { DUP + /* [ pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) + : pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ ; + CDR + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ ; + PUSH mutez + 0 + /* [ mutez + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ ; + AMOUNT + /* [ @amount mutez : mutez + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ ; + COMPARE + /* [ int + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ ; + NEQ + /* [ bool + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ ; + IF { PUSH string + "DontSendTez" + /* [ string + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ ; + FAILWITH + /* [] */ } + { /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ } ; + SWAP + /* [ pair (or @parameter + (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value)))) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ @parameter or (or (or (pair %approve (address %spender) (nat %value)) + (pair %getAllowance + (pair %request (address %owner) (address %spender)) + (contract %callback nat))) + (or (pair %getBalance (address %owner) (contract %callback nat)) + (pair %getTotalSupply (unit %request) (contract %callback nat)))) + (or (pair %mintOrBurn (int %quantity) (address %target)) + (pair %transfer (address %from) (address %to) (nat %value))) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_LEFT + { IF_LEFT + { IF_LEFT + { SWAP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.left.approve pair (address %spender) (nat %value) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.left.approve pair (address %spender) (nat %value) ] */ ; + DUG 2 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ @parameter.left.left.approve pair (address %spender) (nat %value) + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.left.left.approve pair (address %spender) (nat %value) + : @parameter.left.left.approve pair (address %spender) (nat %value) + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 2 + /* [ @parameter.left.left.approve pair (address %spender) (nat %value) + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SENDER + /* [ @sender address : address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PUSH nat + 0 + /* [ nat : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ @parameter.left.left.approve pair (address %spender) (nat %value) : nat + : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.left.left.approve pair (address %spender) (nat %value) + : @parameter.left.left.approve pair (address %spender) (nat %value) : nat + : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 4 + /* [ @parameter.left.left.approve pair (address %spender) (nat %value) : nat + : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ nat : nat : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + COMPARE + /* [ int : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + GT + /* [ bool : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PUSH nat + 0 + /* [ nat : bool : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ big_map (pair (address %owner) (address %spender)) nat : nat : bool + : pair (address @sender) address + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ big_map (pair (address %owner) (address %spender)) nat + : big_map (pair (address %owner) (address %spender)) nat : nat : bool + : pair (address @sender) address + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 4 + /* [ big_map (pair (address %owner) (address %spender)) nat : nat : bool + : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat : nat : bool + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ pair (address @sender) address : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat : nat : bool + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 4 + /* [ pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat : nat : bool + : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + GET + /* [ option nat : nat : bool : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : nat : bool : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { /* [ @some nat : nat : bool : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + COMPARE + /* [ int : bool : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + GT + /* [ bool : bool : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + AND + /* [ bool : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF { PUSH string + "UnsafeAllowanceChange" + /* [ string : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + FAILWITH + /* [] */ } + { /* [ pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + DIG 3 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) ] */ ; + DUG 4 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %admin) (nat %total_supply) : pair (address @sender) address + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @parameter.left.left.approve pair (address %spender) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ @parameter.left.left.approve pair (address %spender) (nat %value) + : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ nat : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PUSH nat + 0 + /* [ nat : nat : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ nat : nat : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ nat : nat : nat : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 2 + /* [ nat : nat : nat : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + COMPARE + /* [ int : nat : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + EQ + /* [ bool : nat : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF { DROP + /* [ big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NONE nat + /* [ option nat : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { SOME + /* [ option nat : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) : pair (address @sender) address + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + DIG 3 + /* [ pair (address @sender) address : option nat + : big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + UPDATE + /* [ big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ big_map address nat + : pair (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (big_map address nat) + (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NIL operation + /* [ list operation + : pair (big_map address nat) + (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (list operation) + (big_map address nat) + (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { SWAP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) ] */ ; + DIG 2 + /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NIL operation + /* [ list operation + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 2 + /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : list operation + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ contract nat : list operation + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PUSH mutez + 0 + /* [ mutez : contract nat : list operation + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 4 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : mutez : contract nat : list operation + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : mutez : contract nat : list operation + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ big_map (pair (address %owner) (address %spender)) nat : mutez + : contract nat : list operation + : @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 4 + /* [ @parameter.left.left.getAllowance pair (pair %request (address %owner) (address %spender)) (contract %callback nat) + : big_map (pair (address %owner) (address %spender)) nat : mutez + : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ pair (address %owner) (address %spender) + : big_map (pair (address %owner) (address %spender)) nat : mutez + : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + GET + /* [ option nat : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { /* [ @some nat : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + TRANSFER_TOKENS + /* [ operation : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CONS + /* [ list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ } } + { IF_LEFT + { SWAP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) ] */ ; + DIG 2 + /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NIL operation + /* [ list operation + : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 2 + /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : list operation + : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ contract nat : list operation + : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PUSH mutez + 0 + /* [ mutez : contract nat : list operation + : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 4 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : mutez : contract nat : list operation + : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ big_map address nat : mutez : contract nat : list operation + : @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 4 + /* [ @parameter.left.right.getBalance pair (address %owner) (contract %callback nat) + : big_map address nat : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address : big_map address nat : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + GET + /* [ option nat : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { /* [ @some nat : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + TRANSFER_TOKENS + /* [ operation : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CONS + /* [ list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ } + { SWAP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) ] */ ; + DIG 2 + /* [ @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NIL operation + /* [ list operation + : @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ @parameter.left.right.getTotalSupply pair (unit %request) (contract %callback nat) + : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PUSH mutez + 0 + /* [ mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %admin) (nat %total_supply) : mutez : contract nat + : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ nat : mutez : contract nat : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + TRANSFER_TOKENS + /* [ operation : list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CONS + /* [ list operation + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage + (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply)) ] */ } } } + { IF_LEFT + { SWAP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUG 2 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %admin) (nat %total_supply) + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SENDER + /* [ @sender address : address + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + COMPARE + /* [ int : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NEQ + /* [ bool : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF { PUSH string + "OnlyAdmin" + /* [ string : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + FAILWITH + /* [] */ } + { /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + DUP + /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ int : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : int + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : int + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUG 3 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : int + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ big_map address nat : int + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : big_map address nat : int + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : big_map address nat : int + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 3 + /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : big_map address nat : int + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ address : big_map address nat : int + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + GET + /* [ option nat : int + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : int + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { /* [ @some nat : int + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + ADD + /* [ int : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + ISNAT + /* [ option nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH string + "Cannot burn more than the target's balance." + /* [ string : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + SWAP + /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @some nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @some nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 2 + /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ int : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : int : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : int : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUG 4 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : int : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : int : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %admin) (nat %total_supply) : int : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ nat : int : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + ADD + /* [ int : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + ABS + /* [ nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUG 4 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 4 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + CAR + /* [ big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + PUSH nat + 0 + /* [ nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DIG 4 + /* [ @some nat : nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUP + /* [ @some nat : @some nat : nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DUG 5 + /* [ @some nat : nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + COMPARE + /* [ int : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + EQ + /* [ bool : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat : @some nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + IF { DIG 3 + /* [ @some nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + DROP + /* [ big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + NONE nat + /* [ option nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ } + { DIG 3 + /* [ @some nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ ; + SOME + /* [ option nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat + : @parameter.right.mintOrBurn pair (int %quantity) (address %target) ] */ } ; + DIG 4 + /* [ @parameter.right.mintOrBurn pair (int %quantity) (address %target) + : option nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat ] */ ; + CDR + /* [ address : option nat : big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat ] */ ; + UPDATE + /* [ big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat ] */ ; + PAIR + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat ] */ ; + DUP + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat ] */ ; + DUG 2 + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : nat + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %admin) (nat %total_supply) : nat + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address : nat + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair address nat + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : pair address nat ] */ ; + DUP + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : pair address nat ] */ ; + DUG 2 + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : pair address nat + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : pair address nat + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ big_map (pair (address %owner) (address %spender)) nat : pair address nat + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (big_map (pair (address %owner) (address %spender)) nat) address nat + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (big_map (pair (address %owner) (address %spender)) nat) address nat ] */ ; + CAR + /* [ big_map address nat + : pair (big_map (pair (address %owner) (address %spender)) nat) address nat ] */ ; + PAIR + /* [ pair (big_map address nat) + (big_map (pair (address %owner) (address %spender)) nat) + address + nat ] */ ; + NIL operation + /* [ list operation + : pair (big_map address nat) + (big_map (pair (address %owner) (address %spender)) nat) + address + nat ] */ ; + PAIR + /* [ pair (list operation) + (big_map address nat) + (big_map (pair (address %owner) (address %spender)) nat) + address + nat ] */ } + { SWAP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) ] */ ; + DUG 2 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) ] */ ; + DUP + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) ] */ ; + DUG 3 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 3 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SENDER + /* [ @sender address : address : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + COMPARE + /* [ int : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + EQ + /* [ bool : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF { SWAP + /* [ big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { SENDER + /* [ @sender address : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @sender address : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @sender address : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 4 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @sender address : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address : @sender address : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 4 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %to) (nat %value) : pair address (address @sender) + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ nat : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 3 + /* [ big_map (pair (address %owner) (address %spender)) nat : nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ big_map (pair (address %owner) (address %spender)) nat + : big_map (pair (address %owner) (address %spender)) nat : nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 4 + /* [ big_map (pair (address %owner) (address %spender)) nat : nat + : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ pair address (address @sender) + : big_map (pair (address %owner) (address %spender)) nat : nat + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ pair address (address @sender) : pair address (address @sender) + : big_map (pair (address %owner) (address %spender)) nat : nat + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 3 + /* [ pair address (address @sender) + : big_map (pair (address %owner) (address %spender)) nat : nat + : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + GET + /* [ option nat : nat : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : nat : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { /* [ @some nat : nat : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + SUB + /* [ int : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + ISNAT + /* [ option nat : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH string + "NotEnoughAllowance" + /* [ string : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat : pair address (address @sender) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + DIG 3 + /* [ big_map (pair (address %owner) (address %spender)) nat : @some nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PUSH nat + 0 + /* [ nat : big_map (pair (address %owner) (address %spender)) nat : @some nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ @some nat : nat : big_map (pair (address %owner) (address %spender)) nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @some nat : @some nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 3 + /* [ @some nat : nat : big_map (pair (address %owner) (address %spender)) nat + : @some nat : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + COMPARE + /* [ int : big_map (pair (address %owner) (address %spender)) nat : @some nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + EQ + /* [ bool : big_map (pair (address %owner) (address %spender)) nat : @some nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF { SWAP + /* [ @some nat : big_map (pair (address %owner) (address %spender)) nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DROP + /* [ big_map (pair (address %owner) (address %spender)) nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NONE nat + /* [ option nat : big_map (pair (address %owner) (address %spender)) nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { SWAP + /* [ @some nat : big_map (pair (address %owner) (address %spender)) nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SOME + /* [ option nat : big_map (pair (address %owner) (address %spender)) nat + : pair address (address @sender) : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + DIG 2 + /* [ pair address (address @sender) : option nat + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + UPDATE + /* [ big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + DIG 2 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 3 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %to) (nat %value) + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ nat : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ big_map address nat : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 3 + /* [ big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 4 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 5 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + GET + /* [ option nat : nat : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : nat : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { /* [ @some nat : nat : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + SUB + /* [ int : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + ISNAT + /* [ option nat : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH string + "NotEnoughBalance" + /* [ string : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + FAILWITH + /* [] */ } + { /* [ @some nat : big_map (pair (address %owner) (address %spender)) nat + : big_map address nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + DIG 2 + /* [ big_map address nat : @some nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PUSH nat + 0 + /* [ nat : big_map address nat : @some nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ @some nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @some nat : @some nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 3 + /* [ @some nat : nat : big_map address nat : @some nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + COMPARE + /* [ int : big_map address nat : @some nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + EQ + /* [ bool : big_map address nat : @some nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF { SWAP + /* [ @some nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DROP + /* [ big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NONE nat + /* [ option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { SWAP + /* [ @some nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SOME + /* [ option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + DIG 3 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 4 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address : option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + UPDATE + /* [ big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 3 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %to) (nat %value) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ big_map address nat : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 2 + /* [ big_map address nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 4 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 5 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : big_map address nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %to) (nat %value) : big_map address nat : nat + : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address : big_map address nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + GET + /* [ option nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF_NONE + { PUSH nat + 0 + /* [ nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { /* [ @some nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + ADD + /* [ nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PUSH nat + 0 + /* [ nat : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUP + /* [ nat : nat : nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DUG 3 + /* [ nat : nat : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + COMPARE + /* [ int : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + EQ + /* [ bool : big_map address nat : nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + IF { SWAP + /* [ nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DROP + /* [ big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NONE nat + /* [ option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } + { SWAP + /* [ nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SOME + /* [ option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } ; + DIG 3 + /* [ @parameter.right.transfer pair (address %from) (address %to) (nat %value) + : option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CDR + /* [ pair (address %to) (nat %value) : option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ address : option nat : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + UPDATE + /* [ big_map address nat + : big_map (pair (address %owner) (address %spender)) nat + : @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + DIG 2 + /* [ @storage pair (big_map %tokens address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) : big_map address nat + : big_map (pair (address %owner) (address %spender)) nat ] */ ; + SWAP + /* [ big_map address nat + : pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : big_map (pair (address %owner) (address %spender)) nat ] */ ; + PAIR + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : big_map (pair (address %owner) (address %spender)) nat ] */ ; + DUP + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : big_map (pair (address %owner) (address %spender)) nat ] */ ; + CDR + /* [ pair (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : big_map (pair (address %owner) (address %spender)) nat ] */ ; + CDR + /* [ pair (address %admin) (nat %total_supply) + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : big_map (pair (address %owner) (address %spender)) nat ] */ ; + DIG 2 + /* [ big_map (pair (address %owner) (address %spender)) nat + : pair (address %admin) (nat %total_supply) + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + SWAP + /* [ pair (big_map address nat) + (big_map %allowances (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) + : pair (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + CAR + /* [ big_map address nat + : pair (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (big_map address nat) + (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + NIL operation + /* [ list operation + : pair (big_map address nat) + (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ ; + PAIR + /* [ pair (list operation) + (big_map address nat) + (big_map (pair (address %owner) (address %spender)) nat) + (address %admin) + (nat %total_supply) ] */ } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_en2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_en2.tz].out new file mode 100644 index 000000000000..0776983db7da --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_en2.tz].out @@ -0,0 +1,205 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/multiple_en2.tz] + +Well typed +Gas remaining: 1039921.322 units remaining +{ parameter unit ; + storage (option address) ; + code { SENDER + /* [ @sender address : pair (unit @parameter) (option @storage address) ] */ ; + SELF + /* [ @self contract unit : @sender address + : pair (unit @parameter) (option @storage address) ] */ ; + ADDRESS + /* [ @self.address address : @sender address + : pair (unit @parameter) (option @storage address) ] */ ; + { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ + COMPARE + /* [ mutez : @amount mutez + : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ ; + EQ + /* [ bool : pair (unit @parameter) (option @storage address) ] */ ; + IF { CDR + /* [ @storage option address ] */ ; + { /* [ mutez : @amount mutez + : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ + IF_NONE + { { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ + UNIT + /* [ unit ] */ ; + FAILWITH + /* [] */ } } + { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ } + /* [ bool + : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ } ; + DIP { NIL operation + /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) + : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ + /* [ list operation ] */ } + /* [] */ ; + DUP + /* [ @parameter or (or (nat %add) (nat %sub)) (unit %default) + : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ ; + CONTRACT %add + unit + /* [ @parameter or (or (nat %add) (nat %sub)) (unit %default) : @storage int ] */ ; + { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ + IF_NONE + { /* [ @storage.some address : list operation ] */ } + { { UNIT /* [ int ] */ ; FAILWITH /* [] */ } } } ; + DUP + /* [ @storage int : @parameter.left.sub nat ] */ ; + CONTRACT %fact nat + /* [ int ] */ ; + { /* [ @parameter.default unit : @storage int ] */ + IF_NONE { /* [] */ } { { UNIT /* [ list operation : int ] */ ; FAILWITH /* [] */ } } + /* [] */ } ; + DUP + /* [ pair (list operation) int ] */ ; + CONTRACT %add + nat + /* [ @storage.some.contract option (contract nat) : @storage.some address + : list operation ] */ ; + { IF_NONE + { { UNIT /* [ unit : @storage.some address : list operation ] */ ; FAILWITH /* [] */ } } + { /* [ @storage.some.contract.some contract nat : @storage.some address + : list operation ] */ } } ; + PUSH mutez + 0 + /* [ mutez : @storage.some.contract.some contract nat : @storage.some address + : list operation ] */ ; + PUSH nat + 12 + /* [ nat : mutez : @storage.some.contract.some contract nat + : @storage.some address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage.some address : list operation ] */ ; + SWAP + /* [ @storage.some address : operation : list operation ] */ ; + DIP { CONS /* [ list operation ] */ } + /* [ @storage.some address : list operation ] */ ; + DUP + /* [ @storage.some address : @storage.some address : list operation ] */ ; + CONTRACT + unit + /* [ @storage.some.contract option (contract unit) : @storage.some address + : list operation ] */ ; + { IF_NONE + { { UNIT /* [ unit : @storage.some address : list operation ] */ ; FAILWITH /* [] */ } } + { /* [ @storage.some.contract.some contract unit : @storage.some address + : list operation ] */ } } ; + PUSH mutez + 0 + /* [ mutez : @storage.some.contract.some contract unit : @storage.some address + : list operation ] */ ; + PUSH unit + Unit + /* [ unit : mutez : @storage.some.contract.some contract unit + : @storage.some address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage.some address : list operation ] */ ; + SWAP + /* [ @storage.some address : operation : list operation ] */ ; + DIP { CONS /* [ list operation ] */ } + /* [ @storage.some address : list operation ] */ ; + DUP + /* [ @storage.some address : @storage.some address : list operation ] */ ; + CONTRACT %sub + nat + /* [ @storage.some.contract option (contract nat) : @storage.some address + : list operation ] */ ; + { IF_NONE + { { UNIT /* [ unit : @storage.some address : list operation ] */ ; FAILWITH /* [] */ } } + { /* [ @storage.some.contract.some contract nat : @storage.some address + : list operation ] */ } } ; + PUSH mutez + 0 + /* [ mutez : @storage.some.contract.some contract nat : @storage.some address + : list operation ] */ ; + PUSH nat + 3 + /* [ nat : mutez : @storage.some.contract.some contract nat + : @storage.some address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage.some address : list operation ] */ ; + SWAP + /* [ @storage.some address : operation : list operation ] */ ; + DIP { CONS /* [ list operation ] */ } + /* [ @storage.some address : list operation ] */ ; + DUP + /* [ @storage.some address : @storage.some address : list operation ] */ ; + CONTRACT %add + nat + /* [ @storage.some.contract option (contract nat) : @storage.some address + : list operation ] */ ; + { IF_NONE + { { UNIT /* [ unit : @storage.some address : list operation ] */ ; FAILWITH /* [] */ } } + { /* [ @storage.some.contract.some contract nat : @storage.some address + : list operation ] */ } } ; + PUSH mutez + 0 + /* [ mutez : @storage.some.contract.some contract nat : @storage.some address + : list operation ] */ ; + PUSH nat + 5 + /* [ nat : mutez : @storage.some.contract.some contract nat + : @storage.some address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage.some address : list operation ] */ ; + SWAP + /* [ @storage.some address : operation : list operation ] */ ; + DIP { CONS /* [ list operation ] */ } + /* [ @storage.some address : list operation ] */ ; + DROP + /* [ list operation ] */ ; + DIP { NONE address /* [ option address ] */ } + /* [ list operation : option address ] */ ; + PAIR + /* [ pair (list operation) (option address) ] */ } + { CAR + /* [ @parameter unit ] */ ; + DUP + /* [ @parameter unit : @parameter unit ] */ ; + DIP { DIP { PUSH int 0 + /* [ int ] */ ; + PUSH mutez 0 + /* [ mutez : int ] */ ; + NONE key_hash + /* [ option key_hash : mutez : int ] */ } + /* [ @parameter unit : option key_hash : mutez : int ] */ ; + DROP + /* [ option key_hash : mutez : int ] */ ; + CREATE_CONTRACT + { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; + storage int ; + code { AMOUNT ; + PUSH mutez 0 ; + { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; + { { DUP ; CAR ; DIP { CDR } } } ; + IF_LEFT + { IF_LEFT { ADD } { SWAP ; SUB } } + { DROP ; DROP ; PUSH int 0 } ; + NIL operation ; + PAIR } } + /* [ operation : address ] */ } + /* [ @parameter unit : operation : address ] */ ; + DIP { SELF + /* [ @self contract unit : operation : address ] */ ; + PUSH mutez 0 + /* [ mutez : @self contract unit : operation : address ] */ } + /* [ @parameter unit : mutez : @self contract unit : operation : address ] */ ; + TRANSFER_TOKENS + /* [ operation : operation : address ] */ ; + NIL operation + /* [ list operation : operation : operation : address ] */ ; + SWAP + /* [ operation : list operation : operation : address ] */ ; + CONS + /* [ list operation : operation : address ] */ ; + SWAP + /* [ operation : list operation : address ] */ ; + CONS + /* [ list operation : address ] */ ; + DIP { SOME /* [ option address ] */ } + /* [ list operation : option address ] */ ; + PAIR + /* [ pair (list operation) (option address) ] */ } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_entrypoints_counter.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_entrypoints_counter.tz].out new file mode 100644 index 000000000000..da92fa901a05 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--multiple_entrypoints_counter.tz].out @@ -0,0 +1,180 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/multiple_entrypoints_counter.tz] + +Well typed +Gas remaining: 1039924.032 units remaining +{ parameter unit ; + storage (option address) ; + code { SENDER + /* [ @sender address : pair (unit @parameter) (option @storage address) ] */ ; + SELF + /* [ @self contract unit : @sender address + : pair (unit @parameter) (option @storage address) ] */ ; + ADDRESS + /* [ @self.address address : @sender address + : pair (unit @parameter) (option @storage address) ] */ ; + IFCMPEQ + { CDR + /* [ @storage option address ] */ ; + ASSERT_SOME + /* [ int + : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ ; + DIP { /* [ pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ + NIL operation + /* [ list operation ] */ } + /* [] */ ; + DUP + /* [ @storage.some address : @storage.some address : list operation ] */ ; + CONTRACT %add + unit + /* [ int ] */ + /* [ @storage.some.contract option (contract unit) : @storage.some address + : list operation ] */ ; + ASSERT_NONE ; + DUP + /* [ @storage.some address : @storage.some address : list operation ] */ ; + CONTRACT %fact + nat + /* [ list operation : int ] */ + /* [ @storage.some.contract option (contract nat) : @storage.some address + : list operation ] */ ; + ASSERT_NONE ; + DUP + /* [ @storage.some address : @storage.some address : list operation ] */ ; + CONTRACT %add + nat + /* [ @storage.some.contract option (contract nat) : @storage.some address + : list operation ] */ ; + ASSERT_SOME ; + PUSH mutez + 0 + /* [ mutez : @storage.some.contract.some contract nat : @storage.some address + : list operation ] */ ; + PUSH nat + 12 + /* [ nat : mutez : @storage.some.contract.some contract nat + : @storage.some address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage.some address : list operation ] */ ; + SWAP + /* [ @storage.some address : operation : list operation ] */ ; + DIP { CONS /* [ list operation ] */ } + /* [ @storage.some address : list operation ] */ ; + DUP + /* [ @storage.some address : @storage.some address : list operation ] */ ; + CONTRACT + unit + /* [ @storage.some.contract option (contract unit) : @storage.some address + : list operation ] */ ; + ASSERT_SOME ; + PUSH mutez + 0 + /* [ mutez : @storage.some.contract.some contract unit : @storage.some address + : list operation ] */ ; + PUSH unit + Unit + /* [ unit : mutez : @storage.some.contract.some contract unit + : @storage.some address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage.some address : list operation ] */ ; + SWAP + /* [ @storage.some address : operation : list operation ] */ ; + DIP { CONS /* [ list operation ] */ } + /* [ @storage.some address : list operation ] */ ; + DUP + /* [ @storage.some address : @storage.some address : list operation ] */ ; + CONTRACT %sub + nat + /* [ @storage.some.contract option (contract nat) : @storage.some address + : list operation ] */ ; + ASSERT_SOME ; + PUSH mutez + 0 + /* [ mutez : @storage.some.contract.some contract nat : @storage.some address + : list operation ] */ ; + PUSH nat + 3 + /* [ nat : mutez : @storage.some.contract.some contract nat + : @storage.some address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage.some address : list operation ] */ ; + SWAP + /* [ @storage.some address : operation : list operation ] */ ; + DIP { CONS /* [ list operation ] */ } + /* [ @storage.some address : list operation ] */ ; + DUP + /* [ @storage.some address : @storage.some address : list operation ] */ ; + CONTRACT %add + nat + /* [ @storage.some.contract option (contract nat) : @storage.some address + : list operation ] */ ; + ASSERT_SOME ; + PUSH mutez + 0 + /* [ mutez : @storage.some.contract.some contract nat : @storage.some address + : list operation ] */ ; + PUSH nat + 5 + /* [ nat : mutez : @storage.some.contract.some contract nat + : @storage.some address : list operation ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage.some address : list operation ] */ ; + SWAP + /* [ @storage.some address : operation : list operation ] */ ; + DIP { CONS /* [ list operation ] */ } + /* [ @storage.some address : list operation ] */ ; + DROP + /* [ list operation ] */ ; + DIP { NONE address /* [ option address ] */ } + /* [ list operation : option address ] */ ; + PAIR + /* [ pair (list operation) (option address) ] */ } + { CAR + /* [ @parameter unit ] */ ; + DUP + /* [ @parameter unit : @parameter unit ] */ ; + DIP { DIP { PUSH int 0 + /* [ int ] */ ; + PUSH mutez 0 + /* [ mutez : int ] */ ; + NONE key_hash + /* [ option key_hash : mutez : int ] */ } + /* [ @parameter unit : option key_hash : mutez : int ] */ ; + DROP + /* [ option key_hash : mutez : int ] */ ; + CREATE_CONTRACT + { parameter (or (or (nat %add) (nat %sub)) (unit %default)) ; + storage int ; + code { AMOUNT ; + PUSH mutez 0 ; + ASSERT_CMPEQ ; + UNPAIR ; + IF_LEFT + { IF_LEFT { ADD } { SWAP ; SUB } } + { DROP ; DROP ; PUSH int 0 } ; + NIL operation ; + PAIR } } + /* [ operation : address ] */ } + /* [ @parameter unit : operation : address ] */ ; + DIP { SELF + /* [ @self contract unit : operation : address ] */ ; + PUSH mutez 0 + /* [ mutez : @self contract unit : operation : address ] */ } + /* [ @parameter unit : mutez : @self contract unit : operation : address ] */ ; + TRANSFER_TOKENS + /* [ operation : operation : address ] */ ; + NIL operation + /* [ list operation : operation : operation : address ] */ ; + SWAP + /* [ operation : list operation : operation : address ] */ ; + CONS + /* [ list operation : operation : address ] */ ; + SWAP + /* [ operation : list operation : address ] */ ; + CONS + /* [ list operation : address ] */ ; + DIP { SOME /* [ option address ] */ } + /* [ list operation : option address ] */ ; + PAIR + /* [ pair (list operation) (option address) ] */ } + /* [ @amount mutez + : pair (or @parameter (or (nat %add) (nat %sub)) (unit %default)) (int @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--parameterized_multisig.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--parameterized_multisig.tz].out new file mode 100644 index 000000000000..eb4a0cc5218a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--parameterized_multisig.tz].out @@ -0,0 +1,173 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/parameterized_multisig.tz] + +Well typed +Gas remaining: 1039928.103 units remaining +{ storage (pair bool (pair (map nat (pair bool bool)) (pair key key))) ; + parameter (or nat (pair signature nat)) ; + code { DUP + /* [ pair (or @parameter nat (pair signature nat)) + (pair @storage bool (map nat (pair bool bool)) key key) + : pair (or @parameter nat (pair signature nat)) + (pair @storage bool (map nat (pair bool bool)) key key) ] */ ; + CAR + /* [ @parameter or nat (pair signature nat) + : pair (or @parameter nat (pair signature nat)) + (pair @storage bool (map nat (pair bool bool)) key key) ] */ ; + DIP { CDDR } + /* [ @parameter or nat (pair signature nat) + : pair (map nat (pair bool bool)) key key ] */ ; + IF_LEFT + { DIP { DUP + /* [ pair (map nat (pair bool bool)) key key + : pair (map nat (pair bool bool)) key key ] */ ; + CAR + /* [ map nat (pair bool bool) : pair (map nat (pair bool bool)) key key ] */ } + /* [ @parameter.left nat : map nat (pair bool bool) + : pair (map nat (pair bool bool)) key key ] */ ; + GET + /* [ option (pair bool bool) : pair (map nat (pair bool bool)) key key ] */ ; + IF_NONE + { PUSH bool False /* [ bool : pair (map nat (pair bool bool)) key key ] */ } + { DUP + /* [ @some pair bool bool : @some pair bool bool + : pair (map nat (pair bool bool)) key key ] */ ; + CAR + /* [ bool : @some pair bool bool : pair (map nat (pair bool bool)) key key ] */ ; + DIP { CDR /* [ bool : pair (map nat (pair bool bool)) key key ] */ } + /* [ bool : bool : pair (map nat (pair bool bool)) key key ] */ ; + AND + /* [ bool : pair (map nat (pair bool bool)) key key ] */ } ; + PAIR + /* [ pair bool (map nat (pair bool bool)) key key ] */ } + { DUP + /* [ @parameter.right pair signature nat : @parameter.right pair signature nat + : pair (map nat (pair bool bool)) key key ] */ ; + CAR + /* [ signature : @parameter.right pair signature nat + : pair (map nat (pair bool bool)) key key ] */ ; + DIP { CDR + /* [ nat : pair (map nat (pair bool bool)) key key ] */ ; + DUP + /* [ nat : nat : pair (map nat (pair bool bool)) key key ] */ ; + PACK + /* [ @packed bytes : nat : pair (map nat (pair bool bool)) key key ] */ ; + BLAKE2B + /* [ bytes : nat : pair (map nat (pair bool bool)) key key ] */ } + /* [ signature : bytes : nat : pair (map nat (pair bool bool)) key key ] */ ; + PAIR + /* [ pair signature bytes : nat : pair (map nat (pair bool bool)) key key ] */ ; + SWAP + /* [ nat : pair signature bytes : pair (map nat (pair bool bool)) key key ] */ ; + DIP { DIP { DUP + /* [ pair (map nat (pair bool bool)) key key + : pair (map nat (pair bool bool)) key key ] */ ; + CDR + /* [ pair key key : pair (map nat (pair bool bool)) key key ] */ ; + DIP { CAR /* [ map nat (pair bool bool) ] */ } + /* [ pair key key : map nat (pair bool bool) ] */ ; + DUP + /* [ pair key key : pair key key : map nat (pair bool bool) ] */ } + /* [ pair signature bytes : pair key key : pair key key + : map nat (pair bool bool) ] */ ; + SWAP + /* [ pair key key : pair signature bytes : pair key key + : map nat (pair bool bool) ] */ ; + CAR + /* [ key : pair signature bytes : pair key key : map nat (pair bool bool) ] */ ; + DIP { DUP + /* [ pair signature bytes : pair signature bytes : pair key key + : map nat (pair bool bool) ] */ ; + UNPAIR + /* [ signature : bytes : pair signature bytes : pair key key + : map nat (pair bool bool) ] */ } + /* [ key : signature : bytes : pair signature bytes : pair key key + : map nat (pair bool bool) ] */ ; + CHECK_SIGNATURE + /* [ bool : pair signature bytes : pair key key : map nat (pair bool bool) ] */ } + /* [ nat : bool : pair signature bytes : pair key key + : map nat (pair bool bool) ] */ ; + SWAP + /* [ bool : nat : pair signature bytes : pair key key + : map nat (pair bool bool) ] */ ; + IF { DIP { DROP + /* [ pair key key : map nat (pair bool bool) ] */ ; + SWAP + /* [ map nat (pair bool bool) : pair key key ] */ ; + DUP + /* [ map nat (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } + /* [ nat : map nat (pair bool bool) : map nat (pair bool bool) : pair key key ] */ ; + DUP + /* [ nat : nat : map nat (pair bool bool) : map nat (pair bool bool) + : pair key key ] */ ; + DIP { GET + /* [ option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ ; + IF_NONE + { PUSH (pair bool bool) + (Pair False False) + /* [ pair bool bool : map nat (pair bool bool) : pair key key ] */ } + { /* [ @some pair bool bool : map nat (pair bool bool) : pair key key ] */ } ; + CDR + /* [ bool : map nat (pair bool bool) : pair key key ] */ ; + PUSH bool True + /* [ bool : bool : map nat (pair bool bool) : pair key key ] */ ; + PAIR + /* [ pair bool bool : map nat (pair bool bool) : pair key key ] */ ; + SOME + /* [ option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } + /* [ nat : option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } + { DIP { DIP { DUP + /* [ pair key key : pair key key : map nat (pair bool bool) ] */ ; + CDR + /* [ key : pair key key : map nat (pair bool bool) ] */ } + /* [ pair signature bytes : key : pair key key : map nat (pair bool bool) ] */ ; + SWAP + /* [ key : pair signature bytes : pair key key : map nat (pair bool bool) ] */ ; + DIP { UNPAIR /* [ signature : bytes : pair key key : map nat (pair bool bool) ] */ } + /* [ key : signature : bytes : pair key key : map nat (pair bool bool) ] */ ; + CHECK_SIGNATURE + /* [ bool : pair key key : map nat (pair bool bool) ] */ } + /* [ nat : bool : pair key key : map nat (pair bool bool) ] */ ; + SWAP + /* [ bool : nat : pair key key : map nat (pair bool bool) ] */ ; + IF { DUP + /* [ nat : nat : pair key key : map nat (pair bool bool) ] */ ; + DIP { DIP { SWAP + /* [ map nat (pair bool bool) : pair key key ] */ ; + DUP + /* [ map nat (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } + /* [ nat : map nat (pair bool bool) : map nat (pair bool bool) : pair key key ] */ ; + GET + /* [ option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } + /* [ nat : option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ ; + SWAP + /* [ option (pair bool bool) : nat : map nat (pair bool bool) : pair key key ] */ ; + IF_NONE + { PUSH (pair bool bool) + (Pair False False) + /* [ pair bool bool : nat : map nat (pair bool bool) : pair key key ] */ } + { /* [ @some pair bool bool : nat : map nat (pair bool bool) : pair key key ] */ } ; + CAR + /* [ bool : nat : map nat (pair bool bool) : pair key key ] */ ; + PUSH bool True + /* [ bool : bool : nat : map nat (pair bool bool) : pair key key ] */ ; + SWAP + /* [ bool : bool : nat : map nat (pair bool bool) : pair key key ] */ ; + PAIR + /* [ pair bool bool : nat : map nat (pair bool bool) : pair key key ] */ ; + SOME + /* [ option (pair bool bool) : nat : map nat (pair bool bool) : pair key key ] */ ; + SWAP + /* [ nat : option (pair bool bool) : map nat (pair bool bool) : pair key key ] */ } + { FAIL } } ; + UPDATE + /* [ map nat (pair bool bool) : pair key key ] */ ; + PAIR + /* [ pair (map nat (pair bool bool)) key key ] */ ; + PUSH bool False + /* [ bool : pair (map nat (pair bool bool)) key key ] */ ; + PAIR + /* [ pair bool (map nat (pair bool bool)) key key ] */ } ; + NIL operation + /* [ list operation : pair bool (map nat (pair bool bool)) key key ] */ ; + PAIR + /* [ pair (list operation) bool (map nat (pair bool bool)) key key ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--replay.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--replay.tz].out new file mode 100644 index 000000000000..bd46a61e0a65 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--replay.tz].out @@ -0,0 +1,33 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/replay.tz] + +Well typed +Gas remaining: 1039989.740 units remaining +{ parameter unit ; + storage unit ; + code { CDR + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + SOURCE + /* [ @source address : list operation : @storage unit ] */ ; + CONTRACT + unit + /* [ @source.contract option (contract unit) : list operation : @storage unit ] */ ; + ASSERT_SOME ; + PUSH mutez + 1 + /* [ mutez : @source.contract.some contract unit : list operation + : @storage unit ] */ ; + UNIT + /* [ unit : mutez : @source.contract.some contract unit : list operation + : @storage unit ] */ ; + TRANSFER_TOKENS + /* [ operation : list operation : @storage unit ] */ ; + DUP + /* [ operation : operation : list operation : @storage unit ] */ ; + DIP { CONS /* [ list operation : @storage unit ] */ } + /* [ operation : list operation : @storage unit ] */ ; + CONS + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--reveal_signed_preimage.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--reveal_signed_preimage.tz].out new file mode 100644 index 000000000000..2b61d5249e34 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--reveal_signed_preimage.tz].out @@ -0,0 +1,70 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/reveal_signed_preimage.tz] + +Well typed +Gas remaining: 1039977.336 units remaining +{ parameter (pair bytes signature) ; + storage (pair bytes key) ; + code { DUP + /* [ pair (pair @parameter bytes signature) (pair @storage bytes key) + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + UNPAIR + /* [ @parameter pair bytes signature : @storage pair bytes key + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + CAR + /* [ bytes : @storage pair bytes key + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + SHA256 + /* [ bytes : @storage pair bytes key + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + DIP { CAR + /* [ bytes : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ } + /* [ bytes : bytes + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ pair (pair @parameter bytes signature) (pair @storage bytes key) + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + UNPAIR + /* [ @parameter pair bytes signature : @storage pair bytes key + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + SWAP + /* [ @storage pair bytes key : @parameter pair bytes signature + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + DIP { UNPAIR + /* [ bytes : signature + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + SWAP + /* [ signature : bytes + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ } + /* [ @storage pair bytes key : signature : bytes + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + CDR + /* [ key : signature : bytes + : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + CHECK_SIGNATURE + /* [ bool : pair (pair @parameter bytes signature) (pair @storage bytes key) ] */ ; + ASSERT ; + CDR + /* [ @storage pair bytes key ] */ ; + DUP + /* [ @storage pair bytes key : @storage pair bytes key ] */ ; + CDR + /* [ key : @storage pair bytes key ] */ ; + HASH_KEY + /* [ key_hash : @storage pair bytes key ] */ ; + IMPLICIT_ACCOUNT + /* [ contract unit : @storage pair bytes key ] */ ; + BALANCE + /* [ @balance mutez : contract unit : @storage pair bytes key ] */ ; + UNIT + /* [ unit : @balance mutez : contract unit : @storage pair bytes key ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage pair bytes key ] */ ; + NIL operation + /* [ list operation : operation : @storage pair bytes key ] */ ; + SWAP + /* [ operation : list operation : @storage pair bytes key ] */ ; + CONS + /* [ list operation : @storage pair bytes key ] */ ; + PAIR + /* [ pair (list operation) (pair @storage bytes key) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_receiver.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_receiver.tz].out new file mode 100644 index 000000000000..65aab1e6b6e3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_receiver.tz].out @@ -0,0 +1,19 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/self_address_receiver.tz] + +Well typed +Gas remaining: 1039991.719 units remaining +{ parameter (lambda unit address) ; + storage unit ; + code { UNPAIR + /* [ @parameter lambda unit address : @storage unit ] */ ; + UNIT + /* [ unit : @parameter lambda unit address : @storage unit ] */ ; + EXEC + /* [ address : @storage unit ] */ ; + SELF_ADDRESS + /* [ @self address : address : @storage unit ] */ ; + ASSERT_CMPEQ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_sender.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_sender.tz].out new file mode 100644 index 000000000000..3c23a6789001 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--self_address_sender.tz].out @@ -0,0 +1,24 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/self_address_sender.tz] + +Well typed +Gas remaining: 1039991.879 units remaining +{ parameter (contract (lambda unit address)) ; + storage unit ; + code { CAR + /* [ @parameter contract (lambda unit address) ] */ ; + BALANCE + /* [ @balance mutez : @parameter contract (lambda unit address) ] */ ; + LAMBDA + unit + address + { DROP /* [] */ ; SELF_ADDRESS /* [ @self address ] */ } + /* [ lambda unit address : @balance mutez + : @parameter contract (lambda unit address) ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + DIP { UNIT /* [ unit ] */ ; NIL operation /* [ list operation : unit ] */ } + /* [ operation : list operation : unit ] */ ; + CONS + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_fungible.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_fungible.tz].out new file mode 100644 index 000000000000..5a55d386a7bd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_fungible.tz].out @@ -0,0 +1,71 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/ticket_builder_fungible.tz] + +Well typed +Gas remaining: 1039973.685 units remaining +{ parameter + (or (ticket %burn unit) + (pair %mint (contract %destination (ticket unit)) (nat %amount))) ; + storage address ; + code { AMOUNT + /* [ @amount mutez + : pair (or @parameter + (ticket %burn unit) + (pair %mint (contract %destination (ticket unit)) (nat %amount))) + (address @storage) ] */ ; + PUSH mutez + 0 + /* [ mutez : @amount mutez + : pair (or @parameter + (ticket %burn unit) + (pair %mint (contract %destination (ticket unit)) (nat %amount))) + (address @storage) ] */ ; + ASSERT_CMPEQ ; + UNPAIR + /* [ @parameter or (ticket %burn unit) + (pair %mint (contract %destination (ticket unit)) (nat %amount)) + : @storage address ] */ ; + IF_LEFT + { READ_TICKET + /* [ pair address unit nat : @parameter.burn ticket unit : @storage address ] */ ; + CAR + /* [ address : @parameter.burn ticket unit : @storage address ] */ ; + SELF_ADDRESS + /* [ @self address : address : @parameter.burn ticket unit : @storage address ] */ ; + ASSERT_CMPEQ ; + DROP + /* [ @storage address ] */ ; + NIL operation + /* [ list operation : @storage address ] */ } + { DUP @manager + 2 + /* [ @manager address + : @parameter.mint pair (contract %destination (ticket unit)) (nat %amount) + : @storage address ] */ ; + SENDER + /* [ @sender address : @manager address + : @parameter.mint pair (contract %destination (ticket unit)) (nat %amount) + : @storage address ] */ ; + ASSERT_CMPEQ ; + UNPAIR + /* [ contract (ticket unit) : nat : @storage address ] */ ; + SWAP + /* [ nat : contract (ticket unit) : @storage address ] */ ; + UNIT + /* [ unit : nat : contract (ticket unit) : @storage address ] */ ; + TICKET + /* [ ticket unit : contract (ticket unit) : @storage address ] */ ; + PUSH mutez + 0 + /* [ mutez : ticket unit : contract (ticket unit) : @storage address ] */ ; + SWAP + /* [ ticket unit : mutez : contract (ticket unit) : @storage address ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage address ] */ ; + NIL operation + /* [ list operation : operation : @storage address ] */ ; + SWAP + /* [ operation : list operation : @storage address ] */ ; + CONS + /* [ list operation : @storage address ] */ } ; + PAIR + /* [ pair (list operation) (address @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_non_fungible.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_non_fungible.tz].out new file mode 100644 index 000000000000..0cdc9578fb95 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_builder_non_fungible.tz].out @@ -0,0 +1,73 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/ticket_builder_non_fungible.tz] + +Well typed +Gas remaining: 1039970.718 units remaining +{ parameter (or (ticket %burn nat) (contract %mint_destination (ticket nat))) ; + storage (pair (address %manager) (nat %counter)) ; + code { AMOUNT + /* [ @amount mutez + : pair (or @parameter (ticket %burn nat) (contract %mint_destination (ticket nat))) + (pair @storage (address %manager) (nat %counter)) ] */ ; + PUSH mutez + 0 + /* [ mutez : @amount mutez + : pair (or @parameter (ticket %burn nat) (contract %mint_destination (ticket nat))) + (pair @storage (address %manager) (nat %counter)) ] */ ; + ASSERT_CMPEQ ; + UNPAIR + 3 + /* [ or (ticket %burn nat) (contract %mint_destination (ticket nat)) + : @manager address : @counter nat ] */ ; + IF_LEFT + { READ_TICKET + /* [ pair address nat nat : @burn ticket nat : @manager address : @counter nat ] */ ; + CAR + /* [ address : @burn ticket nat : @manager address : @counter nat ] */ ; + SELF_ADDRESS + /* [ @self address : address : @burn ticket nat : @manager address + : @counter nat ] */ ; + ASSERT_CMPEQ ; + DROP + /* [ @manager address : @counter nat ] */ ; + NIL operation + /* [ list operation : @manager address : @counter nat ] */ } + { DUP @manager + 2 + /* [ @manager address : @mint_destination contract (ticket nat) + : @manager address : @counter nat ] */ ; + SENDER + /* [ @sender address : @manager address + : @mint_destination contract (ticket nat) : @manager address : @counter nat ] */ ; + ASSERT_CMPEQ ; + PUSH @amount + nat + 1 + /* [ @amount nat : @mint_destination contract (ticket nat) : @manager address + : @counter nat ] */ ; + DUP @counter + 4 + /* [ @counter nat : @amount nat : @mint_destination contract (ticket nat) + : @manager address : @counter nat ] */ ; + TICKET + /* [ ticket nat : @mint_destination contract (ticket nat) : @manager address + : @counter nat ] */ ; + PUSH mutez + 0 + /* [ mutez : ticket nat : @mint_destination contract (ticket nat) + : @manager address : @counter nat ] */ ; + SWAP + /* [ ticket nat : mutez : @mint_destination contract (ticket nat) + : @manager address : @counter nat ] */ ; + TRANSFER_TOKENS + /* [ operation : @manager address : @counter nat ] */ ; + NIL operation + /* [ list operation : operation : @manager address : @counter nat ] */ ; + SWAP + /* [ operation : list operation : @manager address : @counter nat ] */ ; + CONS + /* [ list operation : @manager address : @counter nat ] */ ; + DIP 2 + { PUSH nat 1 /* [ nat : @counter nat ] */ ; ADD /* [ nat ] */ } + /* [ list operation : @manager address : nat ] */ } ; + PAIR 3 + /* [ pair (list operation) address nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_fungible.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_fungible.tz].out new file mode 100644 index 000000000000..78be9a41db2d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_fungible.tz].out @@ -0,0 +1,224 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/ticket_wallet_fungible.tz] + +Well typed +Gas remaining: 1039935.806 units remaining +{ parameter + (or (ticket %receive unit) + (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer))) ; + storage (pair (address %manager) (big_map %tickets address (ticket unit))) ; + code { AMOUNT + /* [ @amount mutez + : pair (or @parameter + (ticket %receive unit) + (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer))) + (pair @storage (address %manager) (big_map %tickets address (ticket unit))) ] */ ; + PUSH mutez + 0 + /* [ mutez : @amount mutez + : pair (or @parameter + (ticket %receive unit) + (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer))) + (pair @storage (address %manager) (big_map %tickets address (ticket unit))) ] */ ; + ASSERT_CMPEQ ; + UNPAIR + 3 + /* [ or (ticket %receive unit) + (pair %send (contract %destination (ticket unit)) (nat %amount) (address %ticketer)) + : @manager address : @tickets big_map address (ticket unit) ] */ ; + IF_LEFT + { READ_TICKET + /* [ pair address unit nat : @receive ticket unit : @manager address + : @tickets big_map address (ticket unit) ] */ ; + CAR @ticketer + /* [ @ticketer address : @receive ticket unit : @manager address + : @tickets big_map address (ticket unit) ] */ ; + DUP + /* [ @ticketer address : @ticketer address : @receive ticket unit + : @manager address : @tickets big_map address (ticket unit) ] */ ; + DIG 4 + /* [ @tickets big_map address (ticket unit) : @ticketer address + : @ticketer address : @receive ticket unit : @manager address ] */ ; + NONE (ticket unit) + /* [ option (ticket unit) : @tickets big_map address (ticket unit) + : @ticketer address : @ticketer address : @receive ticket unit + : @manager address ] */ ; + DIG 2 + /* [ @ticketer address : option (ticket unit) + : @tickets big_map address (ticket unit) : @ticketer address + : @receive ticket unit : @manager address ] */ ; + GET_AND_UPDATE + /* [ option (ticket unit) : @tickets big_map address (ticket unit) + : @ticketer address : @receive ticket unit : @manager address ] */ ; + IF_SOME + { DIG 3 + /* [ @receive ticket unit : @some ticket unit + : @tickets big_map address (ticket unit) : @ticketer address + : @manager address ] */ ; + PAIR + /* [ pair (ticket @receive unit) (ticket @some unit) + : @tickets big_map address (ticket unit) : @ticketer address + : @manager address ] */ ; + JOIN_TICKETS + /* [ option (ticket unit) : @tickets big_map address (ticket unit) + : @ticketer address : @manager address ] */ ; + ASSERT_SOME } + { DIG 2 + /* [ @receive ticket unit : @tickets big_map address (ticket unit) + : @ticketer address : @manager address ] */ } ; + SOME + /* [ option (ticket unit) : @tickets big_map address (ticket unit) + : @ticketer address : @manager address ] */ ; + DIG 2 + /* [ @ticketer address : option (ticket unit) + : @tickets big_map address (ticket unit) : @manager address ] */ ; + GET_AND_UPDATE + /* [ option (ticket unit) : @tickets big_map address (ticket unit) + : @manager address ] */ ; + ASSERT_NONE ; + SWAP + /* [ @manager address : @tickets big_map address (ticket unit) ] */ ; + PAIR + /* [ pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; + NIL operation + /* [ list operation + : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ } + { DUP @manager + 2 + /* [ @manager address + : @send pair (contract %destination (ticket unit)) (nat %amount) (address %ticketer) + : @manager address : @tickets big_map address (ticket unit) ] */ ; + SENDER + /* [ @sender address : @manager address + : @send pair (contract %destination (ticket unit)) (nat %amount) (address %ticketer) + : @manager address : @tickets big_map address (ticket unit) ] */ ; + ASSERT_CMPEQ ; + UNPAIR + 3 + /* [ @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address : @tickets big_map address (ticket unit) ] */ ; + DIG 4 + /* [ @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + NONE (ticket unit) + /* [ option (ticket unit) : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + DUP @ticketer + 5 + /* [ @ticketer address : option (ticket unit) + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + GET_AND_UPDATE + /* [ option (ticket unit) : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + ASSERT_SOME ; + READ_TICKET + /* [ pair address unit nat : @some ticket unit + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + GET @total_amount + 4 + /* [ @total_amount nat : @some ticket unit + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + DUP @amount + 5 + /* [ @amount nat : @total_amount nat : @some ticket unit + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + SWAP + /* [ @total_amount nat : @amount nat : @some ticket unit + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + SUB + /* [ int : @some ticket unit : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + ISNAT + /* [ option nat : @some ticket unit : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @amount nat : @ticketer address + : @manager address ] */ ; + ASSERT_SOME @remaining_amount ; + DIG 4 + /* [ @amount nat : @remaining_amount nat : @some ticket unit + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @ticketer address + : @manager address ] */ ; + PAIR + /* [ pair (nat @amount) (nat @remaining_amount) : @some ticket unit + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @ticketer address + : @manager address ] */ ; + SWAP + /* [ @some ticket unit : pair (nat @amount) (nat @remaining_amount) + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @ticketer address + : @manager address ] */ ; + SPLIT_TICKET + /* [ option (pair (ticket @amount unit) (ticket @remaining_amount unit)) + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @ticketer address + : @manager address ] */ ; + ASSERT_SOME ; + UNPAIR @to_send @to_keep + /* [ @to_send ticket unit : @to_keep ticket unit + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @ticketer address + : @manager address ] */ ; + DUG 5 + /* [ @to_keep ticket unit : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @ticketer address : @manager address + : @to_send ticket unit ] */ ; + SOME + /* [ option (ticket unit) : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @ticketer address : @manager address + : @to_send ticket unit ] */ ; + DIG 3 + /* [ @ticketer address : option (ticket unit) + : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @manager address + : @to_send ticket unit ] */ ; + GET_AND_UPDATE + /* [ option (ticket unit) : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @manager address + : @to_send ticket unit ] */ ; + ASSERT_NONE ; + DIG 2 + /* [ @manager address : @tickets big_map address (ticket unit) + : @destination contract (ticket unit) : @to_send ticket unit ] */ ; + PAIR + /* [ pair (address @manager) (big_map @tickets address (ticket unit)) + : @destination contract (ticket unit) : @to_send ticket unit ] */ ; + SWAP + /* [ @destination contract (ticket unit) + : pair (address @manager) (big_map @tickets address (ticket unit)) + : @to_send ticket unit ] */ ; + PUSH mutez + 0 + /* [ mutez : @destination contract (ticket unit) + : pair (address @manager) (big_map @tickets address (ticket unit)) + : @to_send ticket unit ] */ ; + DIG 3 + /* [ @to_send ticket unit : mutez : @destination contract (ticket unit) + : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; + NIL operation + /* [ list operation : operation + : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; + SWAP + /* [ operation : list operation + : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ ; + CONS + /* [ list operation + : pair (address @manager) (big_map @tickets address (ticket unit)) ] */ } ; + PAIR + /* [ pair (list operation) (address @manager) (big_map @tickets address (ticket unit)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_non_fungible.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_non_fungible.tz].out new file mode 100644 index 000000000000..68da04875800 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--ticket_wallet_non_fungible.tz].out @@ -0,0 +1,132 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/ticket_wallet_non_fungible.tz] + +Well typed +Gas remaining: 1039952.622 units remaining +{ parameter + (or (ticket %receive nat) + (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id))) ; + storage (pair (address %manager) (big_map %tickets (pair address nat) (ticket nat))) ; + code { AMOUNT + /* [ @amount mutez + : pair (or @parameter + (ticket %receive nat) + (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id))) + (pair @storage (address %manager) (big_map %tickets (pair address nat) (ticket nat))) ] */ ; + PUSH mutez + 0 + /* [ mutez : @amount mutez + : pair (or @parameter + (ticket %receive nat) + (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id))) + (pair @storage (address %manager) (big_map %tickets (pair address nat) (ticket nat))) ] */ ; + ASSERT_CMPEQ ; + UNPAIR + 3 + /* [ or (ticket %receive nat) + (pair %send (contract %destination (ticket nat)) (address %ticketer) (nat %id)) + : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; + IF_LEFT + { READ_TICKET + /* [ pair address nat nat : @receive ticket nat : @manager address + : @tickets big_map (pair address nat) (ticket nat) ] */ ; + CAST (pair (address %ticketer) (nat %id) (nat %amount)) + /* [ pair (address %ticketer) (nat %id) (nat %amount) : @receive ticket nat + : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; + UNPAIR + 3 + /* [ @ticketer address : @id nat : @amount nat : @receive ticket nat + : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; + DIG 2 + /* [ @amount nat : @ticketer address : @id nat : @receive ticket nat + : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; + PUSH nat + 1 + /* [ nat : @amount nat : @ticketer address : @id nat : @receive ticket nat + : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; + ASSERT_CMPEQ ; + PAIR + /* [ pair (address @ticketer) (nat @id) : @receive ticket nat : @manager address + : @tickets big_map (pair address nat) (ticket nat) ] */ ; + DIP { SOME + /* [ option (ticket nat) : @manager address + : @tickets big_map (pair address nat) (ticket nat) ] */ ; + DIP { SWAP + /* [ @tickets big_map (pair address nat) (ticket nat) : @manager address ] */ } + /* [ option (ticket nat) : @tickets big_map (pair address nat) (ticket nat) + : @manager address ] */ } + /* [ pair (address @ticketer) (nat @id) : option (ticket nat) + : @tickets big_map (pair address nat) (ticket nat) : @manager address ] */ ; + GET_AND_UPDATE + /* [ option (ticket nat) : @tickets big_map (pair address nat) (ticket nat) + : @manager address ] */ ; + ASSERT_NONE ; + SWAP + /* [ @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; + PAIR + /* [ pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; + NIL operation + /* [ list operation + : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ } + { DUP @manager + 2 + /* [ @manager address + : @send pair (contract %destination (ticket nat)) (address %ticketer) (nat %id) + : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; + SENDER + /* [ @sender address : @manager address + : @send pair (contract %destination (ticket nat)) (address %ticketer) (nat %id) + : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; + ASSERT_CMPEQ ; + UNPAIR + /* [ contract (ticket nat) : pair (address %ticketer) (nat %id) + : @manager address : @tickets big_map (pair address nat) (ticket nat) ] */ ; + DIG 3 + /* [ @tickets big_map (pair address nat) (ticket nat) : contract (ticket nat) + : pair (address %ticketer) (nat %id) : @manager address ] */ ; + NONE (ticket nat) + /* [ option (ticket nat) : @tickets big_map (pair address nat) (ticket nat) + : contract (ticket nat) : pair (address %ticketer) (nat %id) + : @manager address ] */ ; + DIG 3 + /* [ pair (address %ticketer) (nat %id) : option (ticket nat) + : @tickets big_map (pair address nat) (ticket nat) : contract (ticket nat) + : @manager address ] */ ; + GET_AND_UPDATE + /* [ option (ticket nat) : @tickets big_map (pair address nat) (ticket nat) + : contract (ticket nat) : @manager address ] */ ; + ASSERT_SOME ; + SWAP + /* [ @tickets big_map (pair address nat) (ticket nat) : @some ticket nat + : contract (ticket nat) : @manager address ] */ ; + DIG 3 + /* [ @manager address : @tickets big_map (pair address nat) (ticket nat) + : @some ticket nat : contract (ticket nat) ] */ ; + PAIR + /* [ pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) + : @some ticket nat : contract (ticket nat) ] */ ; + DUG 2 + /* [ @some ticket nat : contract (ticket nat) + : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; + PUSH mutez + 0 + /* [ mutez : @some ticket nat : contract (ticket nat) + : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; + SWAP + /* [ @some ticket nat : mutez : contract (ticket nat) + : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; + TRANSFER_TOKENS + /* [ operation + : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; + NIL operation + /* [ list operation : operation + : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; + SWAP + /* [ operation : list operation + : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ ; + CONS + /* [ list operation + : pair (address @manager) (big_map @tickets (pair address nat) (ticket nat)) ] */ } ; + PAIR + /* [ pair (list operation) + (address @manager) + (big_map @tickets (pair address nat) (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--tzip4_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--tzip4_view.tz].out new file mode 100644 index 000000000000..cce2cd4edbc2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--tzip4_view.tz].out @@ -0,0 +1,56 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/tzip4_view.tz] + +Well typed +Gas remaining: 1039984.179 units remaining +{ parameter + (or (pair %view_const unit (contract nat)) + (pair %view_add (pair int int) (contract int))) ; + storage unit ; + code { CAR + /* [ @parameter or (pair %view_const unit (contract nat)) + (pair %view_add (pair int int) (contract int)) ] */ ; + IF_LEFT + { CDR + /* [ contract nat ] */ ; + AMOUNT + /* [ @amount mutez : contract nat ] */ ; + PUSH nat 5 + /* [ nat : @amount mutez : contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + NIL operation + /* [ list operation : operation ] */ ; + SWAP + /* [ operation : list operation ] */ ; + CONS + /* [ list operation ] */ ; + UNIT + /* [ unit : list operation ] */ ; + SWAP + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } + { UNPAIR + /* [ pair int int : contract int ] */ ; + UNPAIR + /* [ int : int : contract int ] */ ; + ADD + /* [ int : contract int ] */ ; + AMOUNT + /* [ @amount mutez : int : contract int ] */ ; + SWAP + /* [ int : @amount mutez : contract int ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + NIL operation + /* [ list operation : operation ] */ ; + SWAP + /* [ operation : list operation ] */ ; + CONS + /* [ list operation ] */ ; + UNIT + /* [ unit : list operation ] */ ; + SWAP + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--vote_for_delegate.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--vote_for_delegate.tz].out new file mode 100644 index 000000000000..f2f97c2832c1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--vote_for_delegate.tz].out @@ -0,0 +1,168 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/vote_for_delegate.tz] + +Well typed +Gas remaining: 1039933.671 units remaining +{ parameter (option key_hash) ; + storage + (pair (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) ; + code { DUP + /* [ pair (option @parameter key_hash) + (pair @storage + (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) + : pair (option @parameter key_hash) + (pair @storage + (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; + CDAAR %addr @% ; + SENDER + /* [ @sender address : @addr address + : pair (option @parameter key_hash) + (pair @storage + (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; + PAIR %@ %@ + /* [ pair (address %sender @sender) (address %addr @addr) + : pair (option @parameter key_hash) + (pair @storage + (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; + UNPAIR + /* [ @sender address : @addr address + : pair (option @parameter key_hash) + (pair @storage + (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; + IFCMPEQ + { UNPAIR + /* [ @parameter option key_hash + : @storage pair (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash)) ] */ ; + SWAP + /* [ @storage pair (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash)) + : @parameter option key_hash ] */ ; + SET_CADR %key @changed_mgr1_key } + { DUP + /* [ pair (option @parameter key_hash) + (pair @storage + (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) + : pair (option @parameter key_hash) + (pair @storage + (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; + CDDAR ; + SENDER + /* [ @sender address : address + : pair (option @parameter key_hash) + (pair @storage + (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash))) ] */ ; + IFCMPEQ + { UNPAIR + /* [ @parameter option key_hash + : @storage pair (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash)) ] */ ; + SWAP + /* [ @storage pair (pair %mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 (address %addr) (option %key key_hash)) + : @parameter option key_hash ] */ ; + SET_CDDR %key } + { FAIL } } ; + DUP + /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + CADR ; + DIP { DUP + /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + CDDR } + /* [ option key_hash : option key_hash + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + IF_NONE + { IF_NONE + { NONE key_hash + /* [ option key_hash + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + SET_DELEGATE + /* [ operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + NIL operation + /* [ list operation : operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + SWAP + /* [ operation : list operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + CONS + /* [ list operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } + { DROP + /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + NIL operation + /* [ list operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } } + { SWAP + /* [ option key_hash : @some key_hash + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + IF_SOME + { DIP { DUP + /* [ @some key_hash : @some key_hash + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } + /* [ @some key_hash : @some key_hash : @some key_hash + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + IFCMPEQ + { SOME + /* [ option key_hash + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + SET_DELEGATE + /* [ operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + NIL operation + /* [ list operation : operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + SWAP + /* [ operation : list operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + CONS + /* [ list operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } + { DROP + /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + NIL operation + /* [ list operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } } + { DROP + /* [ pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ ; + NIL operation + /* [ list operation + : pair (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } } ; + PAIR + /* [ pair (list operation) + (pair %mgr1 @storage.mgr1 (address %addr) (option %key key_hash)) + (pair %mgr2 @storage.mgr2 (address %addr) (option %key key_hash)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--weather_insurance.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--weather_insurance.tz].out new file mode 100644 index 000000000000..6ccd0863cb37 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--weather_insurance.tz].out @@ -0,0 +1,259 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/weather_insurance.tz] + +Well typed +Gas remaining: 1039960.200 units remaining +{ parameter (pair (signature %signed_weather_data) (nat :rain %actual_level)) ; + storage + (pair (pair (address %under_key) (address %over_key)) + (pair (nat :rain %rain_level) (key %weather_service_key))) ; + code { DUP + /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + DUP + /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + CAR + /* [ @parameter pair (signature %signed_weather_data) (nat :rain %actual_level) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + MAP_CDR + { PACK + /* [ @packed bytes + : @parameter pair (signature %signed_weather_data) (nat :rain %actual_level) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + BLAKE2B + /* [ bytes + : @parameter pair (signature %signed_weather_data) (nat :rain %actual_level) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ } ; + SWAP + /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : @parameter pair (signature %signed_weather_data @parameter.signed_weather_data) bytes + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + CDDDR %weather_service_key ; + DIP { UNPAIR + /* [ @parameter.signed_weather_data signature : bytes + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ } + /* [ key : @parameter.signed_weather_data signature : bytes + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + CHECK_SIGNATURE @sigok + /* [ @sigok bool + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + ASSERT ; + DUP + /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + DUP + /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + DUP + /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ ; + DIIIP + { CDR %storage + /* [ @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ } + /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + DIIP { CDAR } + /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) + : pair (address %under_key) (address %over_key) + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + DIP { CADR %actual_level } + /* [ pair (pair @parameter (signature %signed_weather_data) (nat :rain %actual_level)) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) : nat :rain + : pair (address %under_key) (address %over_key) + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + CDDAR %rain_level ; + CMPLT ; + IF { CAR %under_key + /* [ address + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ } + { CDR %over_key + /* [ address + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ } ; + CONTRACT + unit + /* [ @contract option (contract unit) + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + ASSERT_SOME ; + BALANCE + /* [ @balance mutez : @contract.some contract unit + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + UNIT + /* [ unit : @balance mutez : @contract.some contract unit + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + TRANSFER_TOKENS @trans.op + /* [ @trans.op operation + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + NIL operation + /* [ list operation : @trans.op operation + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + SWAP + /* [ @trans.op operation : list operation + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + CONS + /* [ list operation + : @storage pair (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key) ] */ ; + PAIR + /* [ pair (list operation) + (pair @storage + (pair (address %under_key) (address %over_key)) + (nat :rain %rain_level) + (key %weather_service_key)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat.tz].out new file mode 100644 index 000000000000..109ef9d4c0af --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat.tz].out @@ -0,0 +1,93 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/xcat.tz] + +Well typed +Gas remaining: 1039965.793 units remaining +{ parameter bytes ; + storage unit ; + code { CAR @preimage + /* [ @preimage bytes ] */ ; + DIP { PUSH @from key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" + /* [ @from key_hash ] */ ; + IMPLICIT_ACCOUNT + /* [ contract unit ] */ ; + PUSH @to + key_hash + "tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" + /* [ @to key_hash : contract unit ] */ ; + IMPLICIT_ACCOUNT + /* [ contract unit : contract unit ] */ ; + PUSH @target_hash + bytes + 0x123456 + /* [ @target_hash bytes : contract unit : contract unit ] */ ; + PUSH @deadline + timestamp + "2018-08-08 00:00:00Z" + /* [ @deadline timestamp : @target_hash bytes : contract unit : contract unit ] */ } + /* [ @preimage bytes : @deadline timestamp : @target_hash bytes : contract unit + : contract unit ] */ ; + SWAP + /* [ @deadline timestamp : @preimage bytes : @target_hash bytes : contract unit + : contract unit ] */ ; + NOW + /* [ @now timestamp : @deadline timestamp : @preimage bytes : @target_hash bytes + : contract unit : contract unit ] */ ; + IFCMPLT + { DROP + /* [ @target_hash bytes : contract unit : contract unit ] */ ; + DROP + /* [ contract unit : contract unit ] */ ; + DROP + /* [ contract unit ] */ ; + BALANCE + /* [ @balance mutez : contract unit ] */ ; + UNIT + /* [ unit : @balance mutez : contract unit ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ } + { DUP + /* [ @preimage bytes : @preimage bytes : @target_hash bytes : contract unit + : contract unit ] */ ; + SIZE + /* [ nat : @preimage bytes : @target_hash bytes : contract unit + : contract unit ] */ ; + PUSH @max_length + nat + 32 + /* [ @max_length nat : nat : @preimage bytes : @target_hash bytes + : contract unit : contract unit ] */ ; + IFCMPLT + { PUSH string + "preimage too long" + /* [ string : @preimage bytes : @target_hash bytes : contract unit + : contract unit ] */ ; + FAILWITH + /* [] */ } + { SHA256 @candidate_hash + /* [ @candidate_hash bytes : @target_hash bytes : contract unit + : contract unit ] */ ; + IFCMPNEQ + { PUSH string "invalid preimage" + /* [ string : contract unit : contract unit ] */ ; + FAILWITH + /* [] */ } + { BALANCE + /* [ @balance mutez : contract unit : contract unit ] */ ; + UNIT + /* [ unit : @balance mutez : contract unit : contract unit ] */ ; + TRANSFER_TOKENS + /* [ operation : contract unit ] */ ; + DIP { DROP /* [] */ } + /* [ operation ] */ } } } ; + NIL operation + /* [ list operation : operation ] */ ; + SWAP + /* [ operation : list operation ] */ ; + CONS + /* [ list operation ] */ ; + UNIT + /* [ unit : list operation ] */ ; + SWAP + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat_dapp.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat_dapp.tz].out new file mode 100644 index 000000000000..ace49540d40e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--xcat_dapp.tz].out @@ -0,0 +1,612 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/xcat_dapp.tz] + +Well typed +Gas remaining: 1039911.852 units remaining +{ parameter + (or (pair %fund + (address %dest) + (pair %settings (bytes %target_hash) (timestamp %deadline))) + (or %claim_refund (bytes %preimage_claim) (bytes %refund_hash))) ; + storage + (pair (big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)))) + unit) ; + code { NIL @operations + operation + /* [ @operations list operation + : pair (or @parameter + (pair %fund + (address %dest) + (pair %settings (bytes %target_hash) (timestamp %deadline))) + (or %claim_refund (bytes %preimage_claim) (bytes %refund_hash))) + (pair @storage + (big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)))) + unit) ] */ ; + SWAP + /* [ pair (or @parameter + (pair %fund + (address %dest) + (pair %settings (bytes %target_hash) (timestamp %deadline))) + (or %claim_refund (bytes %preimage_claim) (bytes %refund_hash))) + (pair @storage + (big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)))) + unit) : @operations list operation ] */ ; + UNPAPAIR @% @% @% ; + DIP { DUP + /* [ big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ } + /* [ @parameter or (pair %fund + (address %dest) + (pair %settings (bytes %target_hash) (timestamp %deadline))) + (or %claim_refund (bytes %preimage_claim) (bytes %refund_hash)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + IF_LEFT + { UNPAIR @% @% + /* [ @dest address : @settings pair (bytes %target_hash) (timestamp %deadline) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DUP + /* [ @dest address : @dest address + : @settings pair (bytes %target_hash) (timestamp %deadline) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + CONTRACT @dest + unit + /* [ @dest option (contract unit) : @dest address + : @settings pair (bytes %target_hash) (timestamp %deadline) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + ASSERT_SOME ; + DROP + /* [ @dest address : @settings pair (bytes %target_hash) (timestamp %deadline) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + SWAP + /* [ @settings pair (bytes %target_hash) (timestamp %deadline) : @dest address + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + UNPAIR @% @% + /* [ @target_hash bytes : @deadline timestamp : @dest address + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DIP { AMOUNT @amount + /* [ @amount mutez : @deadline timestamp : @dest address + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + SENDER + /* [ @sender address : @amount mutez : @deadline timestamp : @dest address + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DUP + /* [ @sender address : @sender address : @amount mutez : @deadline timestamp + : @dest address + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + CONTRACT @from + unit + /* [ @from option (contract unit) : @sender address : @amount mutez + : @deadline timestamp : @dest address + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + ASSERT_SOME ; + DROP + /* [ @sender address : @amount mutez : @deadline timestamp : @dest address + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DIP { PAIR + /* [ pair (mutez @amount) (timestamp @deadline) : @dest address + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + SWAP + /* [ @dest address : pair (mutez @amount) (timestamp @deadline) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ } + /* [ @sender address : @dest address + : pair (mutez @amount) (timestamp @deadline) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + PAIR + /* [ pair (address @sender) (address @dest) + : pair (mutez @amount) (timestamp @deadline) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + PAIR + /* [ pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + SOME @xcat + /* [ @xcat option + (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + SWAP + /* [ big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : @xcat option + (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ } + /* [ @target_hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : @xcat option + (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DUP + /* [ @target_hash bytes : @target_hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : @xcat option + (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DIP { MEM + /* [ bool + : @xcat option + (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + NOT + /* [ bool + : @xcat option + (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + ASSERT } + /* [ @target_hash bytes + : @xcat option + (pair (pair (address @sender) (address @dest)) (mutez @amount) (timestamp @deadline)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + UPDATE + /* [ big_map bytes (pair (pair address address) mutez timestamp) : unit + : @operations list operation ] */ ; + PAIR @new_storage + /* [ @new_storage pair (big_map bytes (pair (pair address address) mutez timestamp)) unit + : @operations list operation ] */ ; + SWAP + /* [ @operations list operation + : @new_storage pair (big_map bytes (pair (pair address address) mutez timestamp)) unit ] */ ; + PAIR + /* [ pair (list @operations operation) + (pair @new_storage (big_map bytes (pair (pair address address) mutez timestamp)) unit) ] */ } + { IF_LEFT + { DUP + /* [ @parameter.claim_refund.preimage_claim bytes + : @parameter.claim_refund.preimage_claim bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + SIZE + /* [ nat : @parameter.claim_refund.preimage_claim bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + PUSH nat + 32 + /* [ nat : nat : @parameter.claim_refund.preimage_claim bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + ASSERT_CMPGE ; + SHA256 @hash + /* [ @hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DUP + /* [ @hash bytes : @hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DIP { SWAP + /* [ big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : @hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ } + /* [ @hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : @hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DIIP { GET + /* [ option + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + ASSERT_SOME ; + DUP + /* [ @some pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)) + : @some pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)) : unit + : @operations list operation ] */ ; + CADR @% ; + CONTRACT @dest + unit + /* [ @dest option (contract unit) + : @some pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)) : unit + : @operations list operation ] */ ; + ASSERT_SOME ; + SWAP + /* [ @some pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)) + : @dest.some contract unit : unit : @operations list operation ] */ ; + CDR @% + /* [ @settings pair (mutez %amount) (timestamp %deadline) + : @dest.some contract unit : unit : @operations list operation ] */ ; + UNPAIR @% @% + /* [ @amount mutez : @deadline timestamp : @dest.some contract unit : unit + : @operations list operation ] */ ; + SWAP + /* [ @deadline timestamp : @amount mutez : @dest.some contract unit : unit + : @operations list operation ] */ ; + NOW + /* [ @now timestamp : @deadline timestamp : @amount mutez + : @dest.some contract unit : unit : @operations list operation ] */ ; + ASSERT_CMPLT ; + UNIT + /* [ unit : @amount mutez : @dest.some contract unit : unit + : @operations list operation ] */ ; + TRANSFER_TOKENS + /* [ operation : unit : @operations list operation ] */ } + /* [ @hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : operation + : unit : @operations list operation ] */ } + { DUP + /* [ @parameter.claim_refund.refund_hash bytes + : @parameter.claim_refund.refund_hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + DIP { GET + /* [ option + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + ASSERT_SOME ; + DUP + /* [ @some pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)) + : @some pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + CAAR @% ; + CONTRACT @from + unit + /* [ @from option (contract unit) + : @some pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + ASSERT_SOME ; + SWAP + /* [ @some pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline)) + : @from.some contract unit + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + CDR + /* [ pair (mutez %amount) (timestamp %deadline) : @from.some contract unit + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + UNPAIR @% @% + /* [ @amount mutez : @deadline timestamp : @from.some contract unit + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + SWAP + /* [ @deadline timestamp : @amount mutez : @from.some contract unit + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + NOW + /* [ @now timestamp : @deadline timestamp : @amount mutez + : @from.some contract unit + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + ASSERT_CMPGE ; + UNIT + /* [ unit : @amount mutez : @from.some contract unit + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + TRANSFER_TOKENS + /* [ operation + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : unit + : @operations list operation ] */ ; + SWAP + /* [ big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : operation + : unit : @operations list operation ] */ } + /* [ @parameter.claim_refund.refund_hash bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : operation + : unit : @operations list operation ] */ } ; + NONE @none + (pair (pair address address) (pair mutez timestamp)) + /* [ @none option (pair (pair address address) mutez timestamp) : bytes + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : operation + : unit : @operations list operation ] */ ; + SWAP + /* [ bytes : @none option (pair (pair address address) mutez timestamp) + : big_map + bytes + (pair (pair %recipients (address %from) (address %dest)) + (pair %settings (mutez %amount) (timestamp %deadline))) : operation + : unit : @operations list operation ] */ ; + UPDATE @cleared_map + /* [ @cleared_map big_map bytes (pair (pair address address) mutez timestamp) + : operation : unit : @operations list operation ] */ ; + SWAP + /* [ operation + : @cleared_map big_map bytes (pair (pair address address) mutez timestamp) + : unit : @operations list operation ] */ ; + DIP { PAIR + /* [ pair (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) unit + : @operations list operation ] */ ; + SWAP + /* [ @operations list operation + : pair (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) unit ] */ } + /* [ operation : @operations list operation + : pair (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) unit ] */ ; + CONS + /* [ list operation + : pair (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) unit ] */ ; + PAIR + /* [ pair (list operation) + (big_map @cleared_map bytes (pair (pair address address) mutez timestamp)) + unit ] */ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--bug_262.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--bug_262.tz].out new file mode 100644 index 000000000000..9f307d779a87 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--bug_262.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[non_regression/bug_262.tz] + +Well typed +Gas remaining: 1039994.949 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + LAMBDA unit unit { /* [ @arg unit ] */ } + /* [ lambda unit unit ] */ ; + UNIT + /* [ unit : lambda unit unit ] */ ; + EXEC + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--pairk_annot.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--pairk_annot.tz].out new file mode 100644 index 000000000000..04b0127ccfdd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[non_regression--pairk_annot.tz].out @@ -0,0 +1,32 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[non_regression/pairk_annot.tz] + +Well typed +Gas remaining: 1039992.198 units remaining +{ parameter unit ; + storage unit ; + code { SENDER + /* [ @sender address : pair (unit @parameter) (unit @storage) ] */ ; + SOURCE + /* [ @source address : @sender address + : pair (unit @parameter) (unit @storage) ] */ ; + PAIR 2 + /* [ pair address address : pair (unit @parameter) (unit @storage) ] */ ; + SOURCE + /* [ @source address : pair address address + : pair (unit @parameter) (unit @storage) ] */ ; + SENDER + /* [ @sender address : @source address : pair address address + : pair (unit @parameter) (unit @storage) ] */ ; + PAIR 2 + /* [ pair address address : pair address address + : pair (unit @parameter) (unit @storage) ] */ ; + COMPARE + /* [ int : pair (unit @parameter) (unit @storage) ] */ ; + DROP + /* [ pair (unit @parameter) (unit @storage) ] */ ; + CDR + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--abs.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--abs.tz].out new file mode 100644 index 000000000000..b02492c2c027 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--abs.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/abs.tz] + +Well typed +Gas remaining: 1039991.794 units remaining +{ parameter nat ; + storage unit ; + code { CAR + /* [ @parameter nat ] */ ; + DUP + /* [ @parameter nat : @parameter nat ] */ ; + NEG + /* [ int : @parameter nat ] */ ; + ABS + /* [ nat : @parameter nat ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add.tz].out new file mode 100644 index 000000000000..8c298e56d221 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add.tz].out @@ -0,0 +1,84 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add.tz] + +Well typed +Gas remaining: 1039944.723 units remaining +{ parameter unit ; + storage unit ; + code { CAR + /* [ @parameter unit ] */ ; + PUSH int 2 + /* [ int : @parameter unit ] */ ; + PUSH int 2 + /* [ int : int : @parameter unit ] */ ; + ADD + /* [ int : @parameter unit ] */ ; + PUSH int 4 + /* [ int : int : @parameter unit ] */ ; + ASSERT_CMPEQ ; + PUSH int 2 + /* [ int : @parameter unit ] */ ; + PUSH int 2 + /* [ int : int : @parameter unit ] */ ; + ADD + /* [ int : @parameter unit ] */ ; + PUSH int 4 + /* [ int : int : @parameter unit ] */ ; + ASSERT_CMPEQ ; + PUSH int 2 + /* [ int : @parameter unit ] */ ; + PUSH nat 2 + /* [ nat : int : @parameter unit ] */ ; + ADD + /* [ int : @parameter unit ] */ ; + PUSH int 4 + /* [ int : int : @parameter unit ] */ ; + ASSERT_CMPEQ ; + PUSH nat 2 + /* [ nat : @parameter unit ] */ ; + PUSH int 2 + /* [ int : nat : @parameter unit ] */ ; + ADD + /* [ int : @parameter unit ] */ ; + PUSH int 4 + /* [ int : int : @parameter unit ] */ ; + ASSERT_CMPEQ ; + PUSH nat 2 + /* [ nat : @parameter unit ] */ ; + PUSH nat 2 + /* [ nat : nat : @parameter unit ] */ ; + ADD + /* [ nat : @parameter unit ] */ ; + PUSH nat 4 + /* [ nat : nat : @parameter unit ] */ ; + ASSERT_CMPEQ ; + PUSH int 60 + /* [ int : @parameter unit ] */ ; + PUSH timestamp "2019-09-09T12:08:37Z" + /* [ timestamp : int : @parameter unit ] */ ; + ADD + /* [ timestamp : @parameter unit ] */ ; + PUSH timestamp "2019-09-09T12:09:37Z" + /* [ timestamp : timestamp : @parameter unit ] */ ; + ASSERT_CMPEQ ; + PUSH timestamp "2019-09-09T12:08:37Z" + /* [ timestamp : @parameter unit ] */ ; + PUSH int 60 + /* [ int : timestamp : @parameter unit ] */ ; + ADD + /* [ timestamp : @parameter unit ] */ ; + PUSH timestamp "2019-09-09T12:09:37Z" + /* [ timestamp : timestamp : @parameter unit ] */ ; + ASSERT_CMPEQ ; + PUSH mutez 1000 + /* [ mutez : @parameter unit ] */ ; + PUSH mutez 1000 + /* [ mutez : mutez : @parameter unit ] */ ; + ADD + /* [ mutez : @parameter unit ] */ ; + PUSH mutez 2000 + /* [ mutez : mutez : @parameter unit ] */ ; + ASSERT_CMPEQ ; + NIL operation + /* [ list operation : @parameter unit ] */ ; + PAIR + /* [ pair (list operation) (unit @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_fr.tz].out new file mode 100644 index 000000000000..e1519299998f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_fr.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_bls12_381_fr.tz] + +Well typed +Gas remaining: 1039995.329 units remaining +{ parameter (pair bls12_381_fr bls12_381_fr) ; + storage (option bls12_381_fr) ; + code { CAR + /* [ @parameter pair bls12_381_fr bls12_381_fr ] */ ; + UNPAIR + /* [ bls12_381_fr : bls12_381_fr ] */ ; + ADD + /* [ bls12_381_fr ] */ ; + SOME + /* [ option bls12_381_fr ] */ ; + NIL operation + /* [ list operation : option bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g1.tz].out new file mode 100644 index 000000000000..a66dc711461c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g1.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_bls12_381_g1.tz] + +Well typed +Gas remaining: 1039995.329 units remaining +{ parameter (pair bls12_381_g1 bls12_381_g1) ; + storage (option bls12_381_g1) ; + code { CAR + /* [ @parameter pair bls12_381_g1 bls12_381_g1 ] */ ; + UNPAIR + /* [ bls12_381_g1 : bls12_381_g1 ] */ ; + ADD + /* [ bls12_381_g1 ] */ ; + SOME + /* [ option bls12_381_g1 ] */ ; + NIL operation + /* [ list operation : option bls12_381_g1 ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_g1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g2.tz].out new file mode 100644 index 000000000000..b6d27a0d65c8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_bls12_381_g2.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_bls12_381_g2.tz] + +Well typed +Gas remaining: 1039995.329 units remaining +{ parameter (pair bls12_381_g2 bls12_381_g2) ; + storage (option bls12_381_g2) ; + code { CAR + /* [ @parameter pair bls12_381_g2 bls12_381_g2 ] */ ; + UNPAIR + /* [ bls12_381_g2 : bls12_381_g2 ] */ ; + ADD + /* [ bls12_381_g2 ] */ ; + SOME + /* [ option bls12_381_g2 ] */ ; + NIL operation + /* [ list operation : option bls12_381_g2 ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_g2) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_delta_timestamp.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_delta_timestamp.tz].out new file mode 100644 index 000000000000..6ec5936684b9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_delta_timestamp.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_delta_timestamp.tz] + +Well typed +Gas remaining: 1039993.598 units remaining +{ parameter (pair int timestamp) ; + storage (option timestamp) ; + code { CAR + /* [ @parameter pair int timestamp ] */ ; + DUP + /* [ @parameter pair int timestamp : @parameter pair int timestamp ] */ ; + CAR + /* [ int : @parameter pair int timestamp ] */ ; + DIP { CDR /* [ timestamp ] */ } + /* [ int : timestamp ] */ ; + ADD + /* [ timestamp ] */ ; + SOME + /* [ option timestamp ] */ ; + NIL operation + /* [ list operation : option timestamp ] */ ; + PAIR + /* [ pair (list operation) (option timestamp) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_timestamp_delta.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_timestamp_delta.tz].out new file mode 100644 index 000000000000..29382a1695b0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--add_timestamp_delta.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/add_timestamp_delta.tz] + +Well typed +Gas remaining: 1039993.598 units remaining +{ parameter (pair timestamp int) ; + storage (option timestamp) ; + code { CAR + /* [ @parameter pair timestamp int ] */ ; + DUP + /* [ @parameter pair timestamp int : @parameter pair timestamp int ] */ ; + CAR + /* [ timestamp : @parameter pair timestamp int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ timestamp : int ] */ ; + ADD + /* [ timestamp ] */ ; + SOME + /* [ option timestamp ] */ ; + NIL operation + /* [ list operation : option timestamp ] */ ; + PAIR + /* [ pair (list operation) (option timestamp) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--address.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--address.tz].out new file mode 100644 index 000000000000..e193ce4f2364 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--address.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/address.tz] + +Well typed +Gas remaining: 1039995.954 units remaining +{ parameter (contract unit) ; + storage (option address) ; + code { CAR + /* [ @parameter contract unit ] */ ; + ADDRESS + /* [ @parameter.address address ] */ ; + SOME + /* [ option address ] */ ; + NIL operation + /* [ list operation : option address ] */ ; + PAIR + /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_fib_view.tz].out new file mode 100644 index 000000000000..f349174faa85 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_fib_view.tz].out @@ -0,0 +1,38 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/amount_after_fib_view.tz] + +Well typed +Gas remaining: 1039985.607 units remaining +{ parameter address ; + storage mutez ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 3 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "fib" nat + /* [ @parameter.contract option nat : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 15000000 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + AMOUNT + /* [ @amount mutez : operation ] */ ; + SWAP + /* [ operation : @amount mutez ] */ ; + NIL operation + /* [ list operation : operation : @amount mutez ] */ ; + SWAP + /* [ operation : list operation : @amount mutez ] */ ; + CONS + /* [ list operation : @amount mutez ] */ ; + PAIR + /* [ pair (list operation) (mutez @amount) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_nonexistent_view.tz].out new file mode 100644 index 000000000000..a3ac48b1b9a9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_nonexistent_view.tz].out @@ -0,0 +1,37 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/amount_after_nonexistent_view.tz] + +Well typed +Gas remaining: 1039985.815 units remaining +{ parameter address ; + storage mutez ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "nonexistent" + (pair nat nat) + /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; + ASSERT_NONE ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 15000000 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + AMOUNT + /* [ @amount mutez : operation ] */ ; + SWAP + /* [ operation : @amount mutez ] */ ; + NIL operation + /* [ list operation : operation : @amount mutez ] */ ; + SWAP + /* [ operation : list operation : @amount mutez ] */ ; + CONS + /* [ list operation : @amount mutez ] */ ; + PAIR + /* [ pair (list operation) (mutez @amount) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_view.tz].out new file mode 100644 index 000000000000..eb1606bad518 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--amount_after_view.tz].out @@ -0,0 +1,39 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/amount_after_view.tz] + +Well typed +Gas remaining: 1039985.432 units remaining +{ parameter address ; + storage mutez ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "id" + (pair nat nat) + /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 15000000 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + AMOUNT + /* [ @amount mutez : operation ] */ ; + SWAP + /* [ operation : @amount mutez ] */ ; + NIL operation + /* [ list operation : operation : @amount mutez ] */ ; + SWAP + /* [ operation : list operation : @amount mutez ] */ ; + CONS + /* [ list operation : @amount mutez ] */ ; + PAIR + /* [ pair (list operation) (mutez @amount) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and.tz].out new file mode 100644 index 000000000000..160120cb34df --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/and.tz] + +Well typed +Gas remaining: 1039994.393 units remaining +{ parameter (pair :param (bool %first) (bool %second)) ; + storage (option bool) ; + code { CAR + /* [ @param pair :param (bool %first) (bool %second) ] */ ; + UNPAIR + /* [ bool : bool ] */ ; + AND @and + /* [ @and bool ] */ ; + SOME @res + /* [ @res option bool ] */ ; + NIL @noop operation + /* [ @noop list operation : @res option bool ] */ ; + PAIR + /* [ pair (list @noop operation) (option @res bool) ] */ ; + UNPAIR @x @y + /* [ @x list operation : @y option bool ] */ ; + PAIR %a %b + /* [ pair (list %a @x operation) (option %b @y bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_binary.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_binary.tz].out new file mode 100644 index 000000000000..b83a04ff8d2e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_binary.tz].out @@ -0,0 +1,50 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/and_binary.tz] + +Well typed +Gas remaining: 1039971.036 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + PUSH nat 5 + /* [ nat ] */ ; + PUSH nat 6 + /* [ nat : nat ] */ ; + AND + /* [ nat ] */ ; + PUSH nat 4 + /* [ nat : nat ] */ ; + ASSERT_CMPEQ ; + PUSH nat 6 + /* [ nat ] */ ; + PUSH int 5 + /* [ int : nat ] */ ; + AND + /* [ nat ] */ ; + PUSH nat 4 + /* [ nat : nat ] */ ; + ASSERT_CMPEQ ; + PUSH nat 12 + /* [ nat ] */ ; + PUSH int -1 + /* [ int : nat ] */ ; + AND + /* [ nat ] */ ; + PUSH nat 12 + /* [ nat : nat ] */ ; + ASSERT_CMPEQ ; + PUSH nat 12 + /* [ nat ] */ ; + PUSH int -5 + /* [ int : nat ] */ ; + AND + /* [ nat ] */ ; + PUSH nat 8 + /* [ nat : nat ] */ ; + ASSERT_CMPEQ ; + UNIT + /* [ unit ] */ ; + NIL @noop operation + /* [ @noop list operation : unit ] */ ; + PAIR + /* [ pair (list @noop operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_logical_1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_logical_1.tz].out new file mode 100644 index 000000000000..813eb62dfa59 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--and_logical_1.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/and_logical_1.tz] + +Well typed +Gas remaining: 1039996.174 units remaining +{ parameter (pair bool bool) ; + storage bool ; + code { CAR + /* [ @parameter pair bool bool ] */ ; + UNPAIR + /* [ bool : bool ] */ ; + AND @and + /* [ @and bool ] */ ; + NIL @noop operation + /* [ @noop list operation : @and bool ] */ ; + PAIR + /* [ pair (list @noop operation) (bool @and) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance.tz].out new file mode 100644 index 000000000000..3bdce329ce88 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/balance.tz] + +Well typed +Gas remaining: 1039996.803 units remaining +{ parameter unit ; + storage mutez ; + code { DROP + /* [] */ ; + BALANCE + /* [ @balance mutez ] */ ; + NIL operation + /* [ list operation : @balance mutez ] */ ; + PAIR + /* [ pair (list operation) (mutez @balance) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_fib_view.tz].out new file mode 100644 index 000000000000..0c77a876e6f5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_fib_view.tz].out @@ -0,0 +1,38 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/balance_after_fib_view.tz] + +Well typed +Gas remaining: 1039985.607 units remaining +{ parameter address ; + storage mutez ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 3 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "fib" nat + /* [ @parameter.contract option nat : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 15000000 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + BALANCE + /* [ @balance mutez : operation ] */ ; + SWAP + /* [ operation : @balance mutez ] */ ; + NIL operation + /* [ list operation : operation : @balance mutez ] */ ; + SWAP + /* [ operation : list operation : @balance mutez ] */ ; + CONS + /* [ list operation : @balance mutez ] */ ; + PAIR + /* [ pair (list operation) (mutez @balance) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_nonexistent_view.tz].out new file mode 100644 index 000000000000..2203259ca5d1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_nonexistent_view.tz].out @@ -0,0 +1,37 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/balance_after_nonexistent_view.tz] + +Well typed +Gas remaining: 1039985.815 units remaining +{ parameter address ; + storage mutez ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "nonexistent" + (pair nat nat) + /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; + ASSERT_NONE ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 15000000 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + BALANCE + /* [ @balance mutez : operation ] */ ; + SWAP + /* [ operation : @balance mutez ] */ ; + NIL operation + /* [ list operation : operation : @balance mutez ] */ ; + SWAP + /* [ operation : list operation : @balance mutez ] */ ; + CONS + /* [ list operation : @balance mutez ] */ ; + PAIR + /* [ pair (list operation) (mutez @balance) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_view.tz].out new file mode 100644 index 000000000000..9e80c49c3dcc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--balance_after_view.tz].out @@ -0,0 +1,39 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/balance_after_view.tz] + +Well typed +Gas remaining: 1039985.432 units remaining +{ parameter address ; + storage mutez ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "id" + (pair nat nat) + /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 15000000 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + BALANCE + /* [ @balance mutez : operation ] */ ; + SWAP + /* [ operation : @balance mutez ] */ ; + NIL operation + /* [ list operation : operation : @balance mutez ] */ ; + SWAP + /* [ operation : list operation : @balance mutez ] */ ; + CONS + /* [ list operation : @balance mutez ] */ ; + PAIR + /* [ pair (list operation) (mutez @balance) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_nat.tz].out new file mode 100644 index 000000000000..a0f01c3a04a4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_nat.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/big_map_mem_nat.tz] + +Well typed +Gas remaining: 1039991.894 units remaining +{ parameter nat ; + storage (pair (big_map nat nat) (option bool)) ; + code { UNPAIR + /* [ @parameter nat : @storage pair (big_map nat nat) (option bool) ] */ ; + DIP { CAR /* [ big_map nat nat ] */ ; DUP /* [ big_map nat nat : big_map nat nat ] */ } + /* [ @parameter nat : big_map nat nat : big_map nat nat ] */ ; + MEM + /* [ bool : big_map nat nat ] */ ; + SOME + /* [ option bool : big_map nat nat ] */ ; + SWAP + /* [ big_map nat nat : option bool ] */ ; + PAIR + /* [ pair (big_map nat nat) (option bool) ] */ ; + NIL operation + /* [ list operation : pair (big_map nat nat) (option bool) ] */ ; + PAIR + /* [ pair (list operation) (big_map nat nat) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_string.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_string.tz].out new file mode 100644 index 000000000000..a44ec7f803f8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_mem_string.tz].out @@ -0,0 +1,25 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/big_map_mem_string.tz] + +Well typed +Gas remaining: 1039991.894 units remaining +{ parameter string ; + storage (pair (big_map string nat) (option bool)) ; + code { UNPAIR + /* [ @parameter string : @storage pair (big_map string nat) (option bool) ] */ ; + DIP { CAR + /* [ big_map string nat ] */ ; + DUP + /* [ big_map string nat : big_map string nat ] */ } + /* [ @parameter string : big_map string nat : big_map string nat ] */ ; + MEM + /* [ bool : big_map string nat ] */ ; + SOME + /* [ option bool : big_map string nat ] */ ; + SWAP + /* [ big_map string nat : option bool ] */ ; + PAIR + /* [ pair (big_map string nat) (option bool) ] */ ; + NIL operation + /* [ list operation : pair (big_map string nat) (option bool) ] */ ; + PAIR + /* [ pair (list operation) (big_map string nat) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_to_self.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_to_self.tz].out new file mode 100644 index 000000000000..90bd798d5dfd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--big_map_to_self.tz].out @@ -0,0 +1,59 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/big_map_to_self.tz] + +Well typed +Gas remaining: 1039984.417 units remaining +{ parameter (or (pair %have_fun (big_map string nat) unit) (unit %default)) ; + storage (big_map string nat) ; + code { UNPAIR + /* [ @parameter or (pair %have_fun (big_map string nat) unit) (unit %default) + : @storage big_map string nat ] */ ; + DIP { NIL operation /* [ list operation : @storage big_map string nat ] */ } + /* [ @parameter or (pair %have_fun (big_map string nat) unit) (unit %default) + : list operation : @storage big_map string nat ] */ ; + IF_LEFT + { DROP /* [ list operation : @storage big_map string nat ] */ } + { DROP + /* [ list operation : @storage big_map string nat ] */ ; + SELF %have_fun + /* [ @self contract (pair (big_map string nat) unit) : list operation + : @storage big_map string nat ] */ ; + PUSH mutez + 0 + /* [ mutez : @self contract (pair (big_map string nat) unit) : list operation + : @storage big_map string nat ] */ ; + DUP 4 + /* [ big_map string nat : mutez + : @self contract (pair (big_map string nat) unit) : list operation + : @storage big_map string nat ] */ ; + PUSH (option nat) + (Some 8) + /* [ option nat : big_map string nat : mutez + : @self contract (pair (big_map string nat) unit) : list operation + : @storage big_map string nat ] */ ; + PUSH string + "hahaha" + /* [ string : option nat : big_map string nat : mutez + : @self contract (pair (big_map string nat) unit) : list operation + : @storage big_map string nat ] */ ; + UPDATE + /* [ big_map string nat : mutez + : @self contract (pair (big_map string nat) unit) : list operation + : @storage big_map string nat ] */ ; + UNIT + /* [ unit : big_map string nat : mutez + : @self contract (pair (big_map string nat) unit) : list operation + : @storage big_map string nat ] */ ; + SWAP + /* [ big_map string nat : unit : mutez + : @self contract (pair (big_map string nat) unit) : list operation + : @storage big_map string nat ] */ ; + PAIR + /* [ pair (big_map string nat) unit : mutez + : @self contract (pair (big_map string nat) unit) : list operation + : @storage big_map string nat ] */ ; + TRANSFER_TOKENS + /* [ operation : list operation : @storage big_map string nat ] */ ; + CONS + /* [ list operation : @storage big_map string nat ] */ } ; + PAIR + /* [ pair (list operation) (big_map @storage string nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_bytes_not_padded.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_bytes_not_padded.tz].out new file mode 100644 index 000000000000..dce18befe18f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_bytes_not_padded.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_push_bytes_not_padded.tz] + +Well typed +Gas remaining: 1039995.606 units remaining +{ parameter unit ; + storage (option bls12_381_fr) ; + code { DROP + /* [] */ ; + PUSH bls12_381_fr 0x00 + /* [ bls12_381_fr ] */ ; + SOME + /* [ option bls12_381_fr ] */ ; + NIL operation + /* [ list operation : option bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_nat.tz].out new file mode 100644 index 000000000000..1740e7aea47d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_push_nat.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_push_nat.tz] + +Well typed +Gas remaining: 1039995.606 units remaining +{ parameter unit ; + storage (option bls12_381_fr) ; + code { DROP + /* [] */ ; + PUSH bls12_381_fr 16 + /* [ bls12_381_fr ] */ ; + SOME + /* [ option bls12_381_fr ] */ ; + NIL operation + /* [ list operation : option bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_int.tz].out new file mode 100644 index 000000000000..a42dbc44c1b6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_int.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_to_int.tz] + +Well typed +Gas remaining: 1039996.803 units remaining +{ parameter bls12_381_fr ; + storage int ; + code { CAR + /* [ @parameter bls12_381_fr ] */ ; + INT + /* [ int ] */ ; + NIL operation + /* [ list operation : int ] */ ; + PAIR + /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_mutez.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_mutez.tz].out new file mode 100644 index 000000000000..be46d82f4288 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_to_mutez.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_to_mutez.tz] + +Well typed +Gas remaining: 1039992.954 units remaining +{ parameter bls12_381_fr ; + storage mutez ; + code { CAR + /* [ @parameter bls12_381_fr ] */ ; + INT + /* [ int ] */ ; + ISNAT + /* [ option nat ] */ ; + ASSERT_SOME ; + PUSH mutez 1 + /* [ mutez : @some nat ] */ ; + MUL + /* [ mutez ] */ ; + NIL operation + /* [ list operation : mutez ] */ ; + PAIR + /* [ pair (list operation) mutez ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_int.tz].out new file mode 100644 index 000000000000..a355325fb8f0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_int.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_z_int.tz] + +Well typed +Gas remaining: 1039996.803 units remaining +{ parameter int ; + storage bls12_381_fr ; + code { UNPAIR + /* [ @parameter int : @storage bls12_381_fr ] */ ; + MUL + /* [ bls12_381_fr ] */ ; + NIL operation + /* [ list operation : bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_nat.tz].out new file mode 100644 index 000000000000..37879db7b58d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_fr_z_nat.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_fr_z_nat.tz] + +Well typed +Gas remaining: 1039996.803 units remaining +{ parameter nat ; + storage bls12_381_fr ; + code { UNPAIR + /* [ @parameter nat : @storage bls12_381_fr ] */ ; + MUL + /* [ bls12_381_fr ] */ ; + NIL operation + /* [ list operation : bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_int.tz].out new file mode 100644 index 000000000000..9c1eed1aa97e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_int.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_z_fr_int.tz] + +Well typed +Gas remaining: 1039996.340 units remaining +{ parameter int ; + storage bls12_381_fr ; + code { UNPAIR + /* [ @parameter int : @storage bls12_381_fr ] */ ; + SWAP + /* [ @storage bls12_381_fr : @parameter int ] */ ; + MUL + /* [ bls12_381_fr ] */ ; + NIL operation + /* [ list operation : bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_nat.tz].out new file mode 100644 index 000000000000..1751cc011e6d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bls12_381_z_fr_nat.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bls12_381_z_fr_nat.tz] + +Well typed +Gas remaining: 1039996.340 units remaining +{ parameter nat ; + storage bls12_381_fr ; + code { UNPAIR + /* [ @parameter nat : @storage bls12_381_fr ] */ ; + SWAP + /* [ @storage bls12_381_fr : @parameter nat ] */ ; + MUL + /* [ bls12_381_fr ] */ ; + NIL operation + /* [ list operation : bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bytes.tz].out new file mode 100644 index 000000000000..f225f02dcac7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--bytes.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/bytes.tz] + +Well typed +Gas remaining: 1039997.267 units remaining +{ parameter bytes ; + storage unit ; + code { CDR + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--car.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--car.tz].out new file mode 100644 index 000000000000..272f47aeeb09 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--car.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/car.tz] + +Well typed +Gas remaining: 1039996.637 units remaining +{ parameter (pair (nat :l) (nat :r)) ; + storage nat ; + code { CAR + /* [ @parameter pair (nat :l) (nat :r) ] */ ; + CAR + /* [ nat :l ] */ ; + NIL operation + /* [ list operation : nat :l ] */ ; + PAIR + /* [ pair (list operation) (nat :l) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cdr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cdr.tz].out new file mode 100644 index 000000000000..df2139897527 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cdr.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/cdr.tz] + +Well typed +Gas remaining: 1039996.637 units remaining +{ parameter (pair (nat :l) (nat :r)) ; + storage nat ; + code { CAR + /* [ @parameter pair (nat :l) (nat :r) ] */ ; + CDR + /* [ nat :r ] */ ; + NIL operation + /* [ list operation : nat :r ] */ ; + PAIR + /* [ pair (list operation) (nat :r) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id.tz].out new file mode 100644 index 000000000000..070dce606488 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/chain_id.tz] + +Well typed +Gas remaining: 1039996.340 units remaining +{ parameter unit ; + storage unit ; + code { CHAIN_ID + /* [ chain_id : pair (unit @parameter) (unit @storage) ] */ ; + DROP + /* [ pair (unit @parameter) (unit @storage) ] */ ; + CAR + /* [ @parameter unit ] */ ; + NIL operation + /* [ list operation : @parameter unit ] */ ; + PAIR + /* [ pair (list operation) (unit @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id_store.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id_store.tz].out new file mode 100644 index 000000000000..08f40696caf9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--chain_id_store.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/chain_id_store.tz] + +Well typed +Gas remaining: 1039996.037 units remaining +{ parameter unit ; + storage (option chain_id) ; + code { DROP + /* [] */ ; + CHAIN_ID + /* [ chain_id ] */ ; + SOME + /* [ option chain_id ] */ ; + NIL operation + /* [ list operation : option chain_id ] */ ; + PAIR + /* [ pair (list operation) (option chain_id) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--check_signature.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--check_signature.tz].out new file mode 100644 index 000000000000..52f6c404d590 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--check_signature.tz].out @@ -0,0 +1,42 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/check_signature.tz] + +Well typed +Gas remaining: 1039988.024 units remaining +{ parameter key ; + storage (pair signature string) ; + code { DUP + /* [ pair (key @parameter) (pair @storage signature string) + : pair (key @parameter) (pair @storage signature string) ] */ ; + DUP + /* [ pair (key @parameter) (pair @storage signature string) + : pair (key @parameter) (pair @storage signature string) + : pair (key @parameter) (pair @storage signature string) ] */ ; + DIP { CDR + /* [ @storage pair signature string + : pair (key @parameter) (pair @storage signature string) ] */ ; + DUP + /* [ @storage pair signature string : @storage pair signature string + : pair (key @parameter) (pair @storage signature string) ] */ ; + CAR + /* [ signature : @storage pair signature string + : pair (key @parameter) (pair @storage signature string) ] */ ; + DIP { CDR + /* [ string : pair (key @parameter) (pair @storage signature string) ] */ ; + PACK + /* [ @packed bytes : pair (key @parameter) (pair @storage signature string) ] */ } + /* [ signature : @packed bytes + : pair (key @parameter) (pair @storage signature string) ] */ } + /* [ pair (key @parameter) (pair @storage signature string) : signature + : @packed bytes : pair (key @parameter) (pair @storage signature string) ] */ ; + CAR + /* [ @parameter key : signature : @packed bytes + : pair (key @parameter) (pair @storage signature string) ] */ ; + CHECK_SIGNATURE + /* [ bool : pair (key @parameter) (pair @storage signature string) ] */ ; + IF { /* [ pair (key @parameter) (pair @storage signature string) ] */ } { FAIL } ; + CDR + /* [ @storage pair signature string ] */ ; + NIL operation + /* [ list operation : @storage pair signature string ] */ ; + PAIR + /* [ pair (list operation) (pair @storage signature string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-get.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-get.tz].out new file mode 100644 index 000000000000..a6a0ef9a1aec --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-get.tz].out @@ -0,0 +1,51 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb-get.tz] + +Well typed +Gas remaining: 1039964.212 units remaining +{ parameter (pair nat nat nat unit) ; + storage unit ; + code { CAR + /* [ @parameter pair nat nat nat unit ] */ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + CAR + /* [ nat : @parameter pair nat nat nat unit ] */ ; + PUSH nat 1 + /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + GET 1 + /* [ nat : @parameter pair nat nat nat unit ] */ ; + PUSH nat 1 + /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + GET 3 + /* [ nat : @parameter pair nat nat nat unit ] */ ; + PUSH nat 4 + /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + GET 5 + /* [ nat : @parameter pair nat nat nat unit ] */ ; + PUSH nat 2 + /* [ nat : nat : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ @parameter pair nat nat nat unit : @parameter pair nat nat nat unit ] */ ; + GET 6 + /* [ unit : @parameter pair nat nat nat unit ] */ ; + UNIT + /* [ unit : unit : @parameter pair nat nat nat unit ] */ ; + ASSERT_CMPEQ ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-literals.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-literals.tz].out new file mode 100644 index 000000000000..c62bce8c1037 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-literals.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb-literals.tz] + +Well typed +Gas remaining: 1039992.630 units remaining +{ parameter unit ; + storage unit ; + code { PUSH (list (pair nat nat nat nat)) + { Pair 0 3 6 9 ; Pair 1 (Pair 4 (Pair 7 10)) ; { 2 ; 5 ; 8 ; 11 } } + /* [ list (pair nat nat nat nat) : pair (unit @parameter) (unit @storage) ] */ ; + DROP 2 + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set-2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set-2.tz].out new file mode 100644 index 000000000000..d281b53dd407 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set-2.tz].out @@ -0,0 +1,26 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb-set-2.tz] + +Well typed +Gas remaining: 1039989.821 units remaining +{ parameter (pair nat nat nat unit) ; + storage (option (pair int nat string bytes)) ; + code { CAR + /* [ @parameter pair nat nat nat unit ] */ ; + PUSH int 2 + /* [ int : @parameter pair nat nat nat unit ] */ ; + UPDATE 1 + /* [ pair int nat nat unit ] */ ; + PUSH string "toto" + /* [ string : pair int nat nat unit ] */ ; + UPDATE 5 + /* [ pair int nat string unit ] */ ; + PUSH bytes 0x01 + /* [ bytes : pair int nat string unit ] */ ; + UPDATE 6 + /* [ pair int nat string bytes ] */ ; + SOME + /* [ option (pair int nat string bytes) ] */ ; + NIL operation + /* [ list operation : option (pair int nat string bytes) ] */ ; + PAIR + /* [ pair (list operation) (option (pair int nat string bytes)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set.tz].out new file mode 100644 index 000000000000..b26fcb8dc9c0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb-set.tz].out @@ -0,0 +1,28 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb-set.tz] + +Well typed +Gas remaining: 1039990.023 units remaining +{ parameter unit ; + storage (pair nat nat nat unit) ; + code { CDR + /* [ @storage pair nat nat nat unit ] */ ; + PUSH nat 2 + /* [ nat : @storage pair nat nat nat unit ] */ ; + UPDATE 1 + /* [ pair nat nat nat unit ] */ ; + PUSH nat 12 + /* [ nat : pair nat nat nat unit ] */ ; + UPDATE 3 + /* [ pair nat nat nat unit ] */ ; + PUSH nat 8 + /* [ nat : pair nat nat nat unit ] */ ; + UPDATE 5 + /* [ pair nat nat nat unit ] */ ; + UNIT + /* [ unit : pair nat nat nat unit ] */ ; + UPDATE 6 + /* [ pair nat nat nat unit ] */ ; + NIL operation + /* [ list operation : pair nat nat nat unit ] */ ; + PAIR + /* [ pair (list operation) nat nat nat unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb.tz].out new file mode 100644 index 000000000000..aa075fec77b6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comb.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comb.tz] + +Well typed +Gas remaining: 1039993.734 units remaining +{ parameter unit ; + storage (pair nat nat nat) ; + code { DROP + /* [] */ ; + PUSH nat 3 + /* [ nat ] */ ; + PUSH nat 2 + /* [ nat : nat ] */ ; + PUSH nat 1 + /* [ nat : nat : nat ] */ ; + NIL operation + /* [ list operation : nat : nat : nat ] */ ; + PAIR 4 + /* [ pair (list operation) nat nat nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare.tz].out new file mode 100644 index 000000000000..0696ab8acf78 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare.tz].out @@ -0,0 +1,217 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/compare.tz] + +Well typed +Gas remaining: 1039832.943 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + PUSH bool True + /* [ bool ] */ ; + DUP + /* [ bool : bool ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH bool False + /* [ bool ] */ ; + DUP + /* [ bool : bool ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH bool False + /* [ bool ] */ ; + PUSH bool True + /* [ bool : bool ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH bool True + /* [ bool ] */ ; + PUSH bool False + /* [ bool : bool ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LT ; + PUSH bytes 0xaabbcc + /* [ bytes ] */ ; + DUP + /* [ bytes : bytes ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH bytes 0x + /* [ bytes ] */ ; + PUSH bytes 0x + /* [ bytes : bytes ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH bytes 0x + /* [ bytes ] */ ; + PUSH bytes 0x01 + /* [ bytes : bytes ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH bytes 0x01 + /* [ bytes ] */ ; + PUSH bytes 0x02 + /* [ bytes : bytes ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH bytes 0x02 + /* [ bytes ] */ ; + PUSH bytes 0x01 + /* [ bytes : bytes ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LT ; + PUSH int 1 + /* [ int ] */ ; + DUP + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH int 10 + /* [ int ] */ ; + PUSH int 5 + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LT ; + PUSH int -4 + /* [ int ] */ ; + PUSH int 1923 + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH nat 1 + /* [ nat ] */ ; + DUP + /* [ nat : nat ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH nat 10 + /* [ nat ] */ ; + PUSH nat 5 + /* [ nat : nat ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LT ; + PUSH nat 4 + /* [ nat ] */ ; + PUSH nat 1923 + /* [ nat : nat ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" + /* [ key_hash ] */ ; + DUP + /* [ key_hash : key_hash ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH key_hash "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" + /* [ key_hash ] */ ; + PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" + /* [ key_hash : key_hash ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LT ; + PUSH key_hash "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" + /* [ key_hash ] */ ; + PUSH key_hash "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" + /* [ key_hash : key_hash ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH mutez 1 + /* [ mutez ] */ ; + DUP + /* [ mutez : mutez ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH mutez 10 + /* [ mutez ] */ ; + PUSH mutez 5 + /* [ mutez : mutez ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LT ; + PUSH mutez 4 + /* [ mutez ] */ ; + PUSH mutez 1923 + /* [ mutez : mutez ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH string "AABBCC" + /* [ string ] */ ; + DUP + /* [ string : string ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH string "" + /* [ string ] */ ; + PUSH string "" + /* [ string : string ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH string "" + /* [ string ] */ ; + PUSH string "a" + /* [ string : string ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH string "a" + /* [ string ] */ ; + PUSH string "b" + /* [ string : string ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH string "b" + /* [ string ] */ ; + PUSH string "a" + /* [ string : string ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LT ; + PUSH timestamp "2019-09-16T08:38:05Z" + /* [ timestamp ] */ ; + DUP + /* [ timestamp : timestamp ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH timestamp "2017-09-16T08:38:04Z" + /* [ timestamp ] */ ; + PUSH timestamp "2019-09-16T08:38:05Z" + /* [ timestamp : timestamp ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_GT ; + PUSH timestamp "2019-09-16T08:38:05Z" + /* [ timestamp ] */ ; + PUSH timestamp "2019-09-16T08:38:04Z" + /* [ timestamp : timestamp ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_LT ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type.tz].out new file mode 100644 index 000000000000..12b1ae2ecd5e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type.tz].out @@ -0,0 +1,3737 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/compare_big_type.tz] + +Well typed +Gas remaining: 1038270.787 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + PUSH nat 0 + /* [ nat ] */ ; + DUP + /* [ nat : nat ] */ ; + PAIR + /* [ pair nat nat ] */ ; + DUP + /* [ pair nat nat : pair nat nat ] */ ; + PAIR + /* [ pair (pair nat nat) nat nat ] */ ; + DUP + /* [ pair (pair nat nat) nat nat : pair (pair nat nat) nat nat ] */ ; + PAIR + /* [ pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat ] */ ; + DUP + /* [ pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat + : pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat ] */ ; + PAIR + /* [ pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + PAIR + /* [ pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + PAIR + /* [ pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + PAIR + /* [ pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + PAIR + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type2.tz].out new file mode 100644 index 000000000000..94aa94b0bf06 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--compare_big_type2.tz].out @@ -0,0 +1,4302 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/compare_big_type2.tz] + +Well typed +Gas remaining: 1037992.958 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + PUSH nat 0 + /* [ nat ] */ ; + DUP + /* [ nat : nat ] */ ; + PAIR + /* [ pair nat nat ] */ ; + DUP + /* [ pair nat nat : pair nat nat ] */ ; + PAIR + /* [ pair (pair nat nat) nat nat ] */ ; + DUP + /* [ pair (pair nat nat) nat nat : pair (pair nat nat) nat nat ] */ ; + PAIR + /* [ pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat ] */ ; + DUP + /* [ pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat + : pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat ] */ ; + PAIR + /* [ pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + PAIR + /* [ pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + PAIR + /* [ pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + PAIR + /* [ pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + PAIR + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DUP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + COMPARE + /* [ int + : pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [ pair (pair (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat) + (pair (pair (pair nat nat) nat nat) (pair nat nat) nat nat) + (pair (pair nat nat) nat nat) + (pair nat nat) + nat + nat ] */ ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comparisons.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comparisons.tz].out new file mode 100644 index 000000000000..45a95f6e874b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--comparisons.tz].out @@ -0,0 +1,65 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/comparisons.tz] + +Well typed +Gas remaining: 1039972.732 units remaining +{ parameter (list int) ; + storage (list (list bool)) ; + code { CAR + /* [ @parameter list int ] */ ; + NIL (list bool) + /* [ list (list bool) : @parameter list int ] */ ; + DIP { DUP + /* [ @parameter list int : @parameter list int ] */ ; + MAP { EQ /* [ bool : @parameter list int ] */ } + /* [ list bool : @parameter list int ] */ } + /* [ list (list bool) : list bool : @parameter list int ] */ ; + SWAP + /* [ list bool : list (list bool) : @parameter list int ] */ ; + CONS + /* [ list (list bool) : @parameter list int ] */ ; + DIP { DUP + /* [ @parameter list int : @parameter list int ] */ ; + MAP { NEQ /* [ bool : @parameter list int ] */ } + /* [ list bool : @parameter list int ] */ } + /* [ list (list bool) : list bool : @parameter list int ] */ ; + SWAP + /* [ list bool : list (list bool) : @parameter list int ] */ ; + CONS + /* [ list (list bool) : @parameter list int ] */ ; + DIP { DUP + /* [ @parameter list int : @parameter list int ] */ ; + MAP { LE /* [ bool : @parameter list int ] */ } + /* [ list bool : @parameter list int ] */ } + /* [ list (list bool) : list bool : @parameter list int ] */ ; + SWAP + /* [ list bool : list (list bool) : @parameter list int ] */ ; + CONS + /* [ list (list bool) : @parameter list int ] */ ; + DIP { DUP + /* [ @parameter list int : @parameter list int ] */ ; + MAP { LT /* [ bool : @parameter list int ] */ } + /* [ list bool : @parameter list int ] */ } + /* [ list (list bool) : list bool : @parameter list int ] */ ; + SWAP + /* [ list bool : list (list bool) : @parameter list int ] */ ; + CONS + /* [ list (list bool) : @parameter list int ] */ ; + DIP { DUP + /* [ @parameter list int : @parameter list int ] */ ; + MAP { GE /* [ bool : @parameter list int ] */ } + /* [ list bool : @parameter list int ] */ } + /* [ list (list bool) : list bool : @parameter list int ] */ ; + SWAP + /* [ list bool : list (list bool) : @parameter list int ] */ ; + CONS + /* [ list (list bool) : @parameter list int ] */ ; + DIP { MAP { GT /* [ bool ] */ } /* [ list bool ] */ } + /* [ list (list bool) : list bool ] */ ; + SWAP + /* [ list bool : list (list bool) ] */ ; + CONS + /* [ list (list bool) ] */ ; + NIL operation + /* [ list operation : list (list bool) ] */ ; + PAIR + /* [ pair (list operation) (list (list bool)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello.tz].out new file mode 100644 index 000000000000..37bf2a056a20 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/concat_hello.tz] + +Well typed +Gas remaining: 1039995.099 units remaining +{ parameter (list string) ; + storage (list string) ; + code { CAR + /* [ @parameter list string ] */ ; + MAP { PUSH @hello string "Hello " + /* [ @hello string : @parameter.elt string ] */ ; + CONCAT + /* [ string ] */ } + /* [ list string ] */ ; + NIL operation + /* [ list operation : list string ] */ ; + PAIR + /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello_bytes.tz].out new file mode 100644 index 000000000000..13ea77d245c5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_hello_bytes.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/concat_hello_bytes.tz] + +Well typed +Gas remaining: 1039995.173 units remaining +{ parameter (list bytes) ; + storage (list bytes) ; + code { CAR + /* [ @parameter list bytes ] */ ; + MAP { PUSH bytes 0xff /* [ bytes : @parameter.elt bytes ] */ ; CONCAT /* [ bytes ] */ } + /* [ list bytes ] */ ; + NIL operation + /* [ list operation : list bytes ] */ ; + PAIR + /* [ pair (list operation) (list bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_list.tz].out new file mode 100644 index 000000000000..5f9bc542ad3b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--concat_list.tz].out @@ -0,0 +1,30 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/concat_list.tz] + +Well typed +Gas remaining: 1039991.417 units remaining +{ parameter (list string) ; + storage string ; + code { CAR + /* [ @parameter list string ] */ ; + PUSH string "" + /* [ string : @parameter list string ] */ ; + SWAP + /* [ @parameter list string : string ] */ ; + ITER { SWAP + /* [ string : @parameter.elt string ] */ ; + DIP { NIL string + /* [ list string : @parameter.elt string ] */ ; + SWAP + /* [ @parameter.elt string : list string ] */ ; + CONS + /* [ list string ] */ } + /* [ string : list string ] */ ; + CONS + /* [ list string ] */ ; + CONCAT + /* [ string ] */ } + /* [ string ] */ ; + NIL operation + /* [ list operation : string ] */ ; + PAIR + /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cons.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cons.tz].out new file mode 100644 index 000000000000..2bbe4fb44b8c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--cons.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/cons.tz] + +Well typed +Gas remaining: 1039996.280 units remaining +{ parameter int ; + storage (list int) ; + code { UNPAIR + /* [ @parameter int : @storage list int ] */ ; + CONS + /* [ list int ] */ ; + NIL operation + /* [ list operation : list int ] */ ; + PAIR + /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contains_all.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contains_all.tz].out new file mode 100644 index 000000000000..99af8ee7b93c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contains_all.tz].out @@ -0,0 +1,79 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/contains_all.tz] + +Well typed +Gas remaining: 1039972.367 units remaining +{ parameter (pair (list string) (list string)) ; + storage (option bool) ; + code { CAR + /* [ @parameter pair (list string) (list string) ] */ ; + DUP + /* [ @parameter pair (list string) (list string) + : @parameter pair (list string) (list string) ] */ ; + CAR + /* [ list string : @parameter pair (list string) (list string) ] */ ; + DIP { CDR /* [ list string ] */ } + /* [ list string : list string ] */ ; + EMPTY_SET string + /* [ set string : list string : list string ] */ ; + SWAP + /* [ list string : set string : list string ] */ ; + ITER { PAIR + /* [ pair (string @elt) (set string) : list string ] */ ; + DUP + /* [ pair (string @elt) (set string) : pair (string @elt) (set string) + : list string ] */ ; + CAR + /* [ @elt string : pair (string @elt) (set string) : list string ] */ ; + DIP { CDR /* [ set string : list string ] */ } + /* [ @elt string : set string : list string ] */ ; + PUSH bool True + /* [ bool : @elt string : set string : list string ] */ ; + SWAP + /* [ @elt string : bool : set string : list string ] */ ; + UPDATE + /* [ set string : list string ] */ } + /* [ set string : list string ] */ ; + PUSH bool True + /* [ bool : set string : list string ] */ ; + SWAP + /* [ set string : bool : list string ] */ ; + PAIR + /* [ pair (set string) bool : list string ] */ ; + SWAP + /* [ list string : pair (set string) bool ] */ ; + ITER { PAIR + /* [ pair (string @elt) (set string) bool ] */ ; + DUP + /* [ pair (string @elt) (set string) bool + : pair (string @elt) (set string) bool ] */ ; + DUP + /* [ pair (string @elt) (set string) bool : pair (string @elt) (set string) bool + : pair (string @elt) (set string) bool ] */ ; + CAR + /* [ @elt string : pair (string @elt) (set string) bool + : pair (string @elt) (set string) bool ] */ ; + DIP { CDAR ; + DIP { CDDR } + /* [ set string : bool ] */ ; + DUP + /* [ set string : set string : bool ] */ } + /* [ @elt string : set string : set string : bool ] */ ; + MEM + /* [ bool : set string : bool ] */ ; + DIP { SWAP /* [ bool : set string ] */ } + /* [ bool : bool : set string ] */ ; + AND + /* [ bool : set string ] */ ; + SWAP + /* [ set string : bool ] */ ; + PAIR + /* [ pair (set string) bool ] */ } + /* [ pair (set string) bool ] */ ; + CDR + /* [ bool ] */ ; + SOME + /* [ option bool ] */ ; + NIL operation + /* [ list operation : option bool ] */ ; + PAIR + /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contract.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contract.tz].out new file mode 100644 index 000000000000..d12bb163416c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--contract.tz].out @@ -0,0 +1,19 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/contract.tz] + +Well typed +Gas remaining: 1039993.550 units remaining +{ parameter address ; + storage unit ; + code { CAR + /* [ @parameter address ] */ ; + CONTRACT unit + /* [ @parameter.contract option (contract unit) ] */ ; + ASSERT_SOME ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract.tz].out new file mode 100644 index 000000000000..f3c4ba9f0512 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract.tz].out @@ -0,0 +1,27 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/create_contract.tz] + +Well typed +Gas remaining: 1039988.704 units remaining +{ parameter unit ; + storage (option address) ; + code { /* [ pair (unit @parameter) (unit @storage) ] */ + DROP + /* [ list operation : @storage unit ] */ ; + UNIT + /* [ unit ] */ ; + AMOUNT + /* [ pair (list operation) (unit @storage) ] */ ; + NONE key_hash + /* [ option key_hash : @amount mutez : unit ] */ ; + CREATE_CONTRACT + { parameter unit ; storage unit ; code { CDR ; NIL operation ; PAIR } } + /* [ operation : address ] */ ; + DIP { SOME + /* [ option address ] */ ; + NIL operation + /* [ list operation : option address ] */ } + /* [ operation : list operation : option address ] */ ; + CONS + /* [ list operation : option address ] */ ; + PAIR + /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out new file mode 100644 index 000000000000..397048c9d024 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname.tz].out @@ -0,0 +1,29 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/create_contract_rootname.tz] + +Well typed +Gas remaining: 1039988.704 units remaining +{ parameter unit ; + storage (option address) ; + code { /* [ pair (unit @parameter) (unit @storage) ] */ + DROP + /* [ list operation : @storage unit ] */ ; + UNIT + /* [ unit ] */ ; + AMOUNT + /* [ pair (list operation) (unit @storage) ] */ ; + NONE key_hash + /* [ option key_hash : @amount mutez : unit ] */ ; + CREATE_CONTRACT + { parameter %root unit ; + storage unit ; + code { CDR ; NIL operation ; PAIR } } + /* [ operation : address ] */ ; + DIP { SOME + /* [ option address ] */ ; + NIL operation + /* [ list operation : option address ] */ } + /* [ operation : list operation : option address ] */ ; + CONS + /* [ list operation : option address ] */ ; + PAIR + /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname_alt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname_alt.tz].out new file mode 100644 index 000000000000..84cd164c89cf --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_rootname_alt.tz].out @@ -0,0 +1,29 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/create_contract_rootname_alt.tz] + +Well typed +Gas remaining: 1039988.704 units remaining +{ parameter unit ; + storage (option address) ; + code { /* [ pair (unit @parameter) (unit @storage) ] */ + DROP + /* [ list operation : @storage unit ] */ ; + UNIT + /* [ unit ] */ ; + AMOUNT + /* [ pair (list operation) (unit @storage) ] */ ; + NONE key_hash + /* [ option key_hash : @amount mutez : unit ] */ ; + CREATE_CONTRACT + { parameter (unit %root) ; + storage unit ; + code { CDR ; NIL operation ; PAIR } } + /* [ operation : address ] */ ; + DIP { SOME + /* [ option address ] */ ; + NIL operation + /* [ list operation : option address ] */ } + /* [ operation : list operation : option address ] */ ; + CONS + /* [ list operation : option address ] */ ; + PAIR + /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_with_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_with_view.tz].out new file mode 100644 index 000000000000..d5922595a95c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--create_contract_with_view.tz].out @@ -0,0 +1,30 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/create_contract_with_view.tz] + +Well typed +Gas remaining: 1039987.516 units remaining +{ parameter unit ; + storage (option address) ; + code { /* [ pair (unit @parameter) (unit @storage) ] */ + DROP + /* [ list operation : @storage unit ] */ ; + UNIT + /* [ unit ] */ ; + AMOUNT + /* [ pair (list operation) (unit @storage) ] */ ; + NONE key_hash + /* [ option key_hash : @amount mutez : unit ] */ ; + CREATE_CONTRACT + { parameter unit /* [ nat ] */ ; + storage unit ; + code { CDR ; NIL operation ; PAIR } ; + view "const" nat nat { CAR } } + /* [ operation : address ] */ ; + DIP { SOME + /* [ option address ] */ ; + NIL operation + /* [ list operation : option address ] */ } + /* [ operation : list operation : option address ] */ ; + CONS + /* [ list operation : option address ] */ ; + PAIR + /* [ pair (list operation) (option address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--diff_timestamps.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--diff_timestamps.tz].out new file mode 100644 index 000000000000..5b0a59eeab26 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--diff_timestamps.tz].out @@ -0,0 +1,20 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/diff_timestamps.tz] + +Well typed +Gas remaining: 1039994.373 units remaining +{ parameter (pair timestamp timestamp) ; + storage int ; + code { CAR + /* [ @parameter pair timestamp timestamp ] */ ; + DUP + /* [ @parameter pair timestamp timestamp : @parameter pair timestamp timestamp ] */ ; + CAR + /* [ timestamp : @parameter pair timestamp timestamp ] */ ; + DIP { CDR /* [ timestamp ] */ } + /* [ timestamp : timestamp ] */ ; + SUB + /* [ int ] */ ; + NIL operation + /* [ list operation : int ] */ ; + PAIR + /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dig_eq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dig_eq.tz].out new file mode 100644 index 000000000000..a017f9750926 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dig_eq.tz].out @@ -0,0 +1,157 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dig_eq.tz] + +Well typed +Gas remaining: 1039899.367 units remaining +{ parameter + (pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat) ; + storage unit ; + code { CAR + /* [ @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DUP + /* [ @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + UNPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAIR ; + DIG 0 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 1 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 2 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 3 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 4 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 5 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 6 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 7 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 8 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 9 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 10 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 11 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 12 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 13 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 14 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 15 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 16 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 0 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 1 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 2 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 3 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 4 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 5 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 6 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 7 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 8 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 9 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 10 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 11 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 12 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 13 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 14 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 15 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + DIG 16 + /* [ nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat : nat + : nat : nat : nat : nat + : @parameter pair nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat nat ] */ ; + PAPAPAPAPAPAPAPAPAPAPAPAPAPAPAPAIR ; + ASSERT_CMPEQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dign.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dign.tz].out new file mode 100644 index 000000000000..9ba1b3f08a64 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dign.tz].out @@ -0,0 +1,24 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dign.tz] + +Well typed +Gas remaining: 1039991.580 units remaining +{ parameter (pair (pair (pair (pair nat nat) nat) nat) nat) ; + storage nat ; + code { CAR + /* [ @parameter pair (pair (pair (pair nat nat) nat) nat) nat ] */ ; + UNPAIR + /* [ pair (pair (pair nat nat) nat) nat : nat ] */ ; + UNPAIR + /* [ pair (pair nat nat) nat : nat : nat ] */ ; + UNPAIR + /* [ pair nat nat : nat : nat : nat ] */ ; + UNPAIR + /* [ nat : nat : nat : nat : nat ] */ ; + DIG 4 + /* [ nat : nat : nat : nat : nat ] */ ; + DIP { DROP /* [ nat : nat : nat ] */ ; DROP /* [ nat : nat ] */ ; DROP /* [ nat ] */ ; DROP /* [] */ } + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dip.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dip.tz].out new file mode 100644 index 000000000000..f5e51cd0143f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dip.tz].out @@ -0,0 +1,20 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dip.tz] + +Well typed +Gas remaining: 1039993.958 units remaining +{ parameter (pair nat nat) ; + storage (pair nat nat) ; + code { CAR + /* [ @parameter pair nat nat ] */ ; + UNPAIR + /* [ nat : nat ] */ ; + DUP + /* [ nat : nat : nat ] */ ; + DIP { ADD /* [ nat ] */ } + /* [ nat : nat ] */ ; + PAIR + /* [ pair nat nat ] */ ; + NIL operation + /* [ list operation : pair nat nat ] */ ; + PAIR + /* [ pair (list operation) nat nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dipn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dipn.tz].out new file mode 100644 index 000000000000..fd733ff07e75 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dipn.tz].out @@ -0,0 +1,32 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dipn.tz] + +Well typed +Gas remaining: 1039990.690 units remaining +{ parameter (pair (pair (pair (pair nat nat) nat) nat) nat) ; + storage nat ; + code { CAR + /* [ @parameter pair (pair (pair (pair nat nat) nat) nat) nat ] */ ; + UNPAIR + /* [ pair (pair (pair nat nat) nat) nat : nat ] */ ; + UNPAIR + /* [ pair (pair nat nat) nat : nat : nat ] */ ; + UNPAIR + /* [ pair nat nat : nat : nat : nat ] */ ; + UNPAIR + /* [ nat : nat : nat : nat : nat ] */ ; + DIP 5 { PUSH nat 6 /* [ nat ] */ } + /* [ nat : nat : nat : nat : nat : nat ] */ ; + DROP + /* [ nat : nat : nat : nat : nat ] */ ; + DROP + /* [ nat : nat : nat : nat ] */ ; + DROP + /* [ nat : nat : nat ] */ ; + DROP + /* [ nat : nat ] */ ; + DROP + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dropn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dropn.tz].out new file mode 100644 index 000000000000..483d913e4537 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dropn.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dropn.tz] + +Well typed +Gas remaining: 1039993.947 units remaining +{ parameter (pair (pair (pair (pair nat nat) nat) nat) nat) ; + storage nat ; + code { CAR + /* [ @parameter pair (pair (pair (pair nat nat) nat) nat) nat ] */ ; + UNPAIR + /* [ pair (pair (pair nat nat) nat) nat : nat ] */ ; + UNPAIR + /* [ pair (pair nat nat) nat : nat : nat ] */ ; + UNPAIR + /* [ pair nat nat : nat : nat : nat ] */ ; + UNPAIR + /* [ nat : nat : nat : nat : nat ] */ ; + DROP 4 + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dugn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dugn.tz].out new file mode 100644 index 000000000000..618378b9929d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dugn.tz].out @@ -0,0 +1,30 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dugn.tz] + +Well typed +Gas remaining: 1039992.076 units remaining +{ parameter (pair (pair (pair (pair nat nat) nat) nat) nat) ; + storage nat ; + code { CAR + /* [ @parameter pair (pair (pair (pair nat nat) nat) nat) nat ] */ ; + UNPAIR + /* [ pair (pair (pair nat nat) nat) nat : nat ] */ ; + UNPAIR + /* [ pair (pair nat nat) nat : nat : nat ] */ ; + UNPAIR + /* [ pair nat nat : nat : nat : nat ] */ ; + UNPAIR + /* [ nat : nat : nat : nat : nat ] */ ; + DUG 4 + /* [ nat : nat : nat : nat : nat ] */ ; + DROP + /* [ nat : nat : nat : nat ] */ ; + DROP + /* [ nat : nat : nat ] */ ; + DROP + /* [ nat : nat ] */ ; + DROP + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dup-n.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dup-n.tz].out new file mode 100644 index 000000000000..6b3687ea1f6a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--dup-n.tz].out @@ -0,0 +1,51 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/dup-n.tz] + +Well typed +Gas remaining: 1039965.992 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + PUSH nat 5 + /* [ nat ] */ ; + PUSH nat 4 + /* [ nat : nat ] */ ; + PUSH nat 3 + /* [ nat : nat : nat ] */ ; + PUSH nat 2 + /* [ nat : nat : nat : nat ] */ ; + PUSH nat 1 + /* [ nat : nat : nat : nat : nat ] */ ; + DUP 1 + /* [ nat : nat : nat : nat : nat : nat ] */ ; + PUSH nat 1 + /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; + ASSERT_CMPEQ ; + DUP 2 + /* [ nat : nat : nat : nat : nat : nat ] */ ; + PUSH nat 2 + /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; + ASSERT_CMPEQ ; + DUP 3 + /* [ nat : nat : nat : nat : nat : nat ] */ ; + PUSH nat 3 + /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; + ASSERT_CMPEQ ; + DUP 4 + /* [ nat : nat : nat : nat : nat : nat ] */ ; + PUSH nat 4 + /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; + ASSERT_CMPEQ ; + DUP 5 + /* [ nat : nat : nat : nat : nat : nat ] */ ; + PUSH nat 5 + /* [ nat : nat : nat : nat : nat : nat : nat ] */ ; + ASSERT_CMPEQ ; + DROP 5 + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv.tz].out new file mode 100644 index 000000000000..3c29ac4d0478 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv.tz].out @@ -0,0 +1,70 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ediv.tz] + +Well typed +Gas remaining: 1039978.198 units remaining +{ parameter (pair int int) ; + storage + (pair (option (pair int nat)) + (option (pair int nat)) + (option (pair int nat)) + (option (pair nat nat))) ; + code { CAR + /* [ @parameter pair int int ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int ] */ ; + UNPAIR + /* [ int : int : @parameter pair int int ] */ ; + ABS + /* [ nat : int : @parameter pair int int ] */ ; + DIP { ABS /* [ nat : @parameter pair int int ] */ } + /* [ nat : nat : @parameter pair int int ] */ ; + EDIV + /* [ option (pair nat nat) : @parameter pair int int ] */ ; + SWAP + /* [ @parameter pair int int : option (pair nat nat) ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int : option (pair nat nat) ] */ ; + UNPAIR + /* [ int : int : @parameter pair int int : option (pair nat nat) ] */ ; + ABS + /* [ nat : int : @parameter pair int int : option (pair nat nat) ] */ ; + EDIV + /* [ option (pair int nat) : @parameter pair int int : option (pair nat nat) ] */ ; + SWAP + /* [ @parameter pair int int : option (pair int nat) : option (pair nat nat) ] */ ; + DUP + /* [ @parameter pair int int : @parameter pair int int : option (pair int nat) + : option (pair nat nat) ] */ ; + UNPAIR + /* [ int : int : @parameter pair int int : option (pair int nat) + : option (pair nat nat) ] */ ; + DIP { ABS + /* [ nat : @parameter pair int int : option (pair int nat) + : option (pair nat nat) ] */ } + /* [ int : nat : @parameter pair int int : option (pair int nat) + : option (pair nat nat) ] */ ; + EDIV + /* [ option (pair int nat) : @parameter pair int int : option (pair int nat) + : option (pair nat nat) ] */ ; + SWAP + /* [ @parameter pair int int : option (pair int nat) : option (pair int nat) + : option (pair nat nat) ] */ ; + UNPAIR + /* [ int : int : option (pair int nat) : option (pair int nat) + : option (pair nat nat) ] */ ; + EDIV + /* [ option (pair int nat) : option (pair int nat) : option (pair int nat) + : option (pair nat nat) ] */ ; + PAPAPAIR ; + NIL operation + /* [ list operation + : pair (option (pair int nat)) + (option (pair int nat)) + (option (pair int nat)) + (option (pair nat nat)) ] */ ; + PAIR + /* [ pair (list operation) + (option (pair int nat)) + (option (pair int nat)) + (option (pair int nat)) + (option (pair nat nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv_mutez.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv_mutez.tz].out new file mode 100644 index 000000000000..1807aa480aba --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ediv_mutez.tz].out @@ -0,0 +1,30 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ediv_mutez.tz] + +Well typed +Gas remaining: 1039987.261 units remaining +{ parameter (pair mutez (or mutez nat)) ; + storage (or (option (pair nat mutez)) (option (pair mutez mutez))) ; + code { CAR + /* [ @parameter pair mutez (or mutez nat) ] */ ; + UNPAIR + /* [ mutez : or mutez nat ] */ ; + SWAP + /* [ or mutez nat : mutez ] */ ; + IF_LEFT + { SWAP + /* [ mutez : mutez ] */ ; + EDIV + /* [ option (pair nat mutez) ] */ ; + LEFT (option (pair mutez mutez)) + /* [ or (option (pair nat mutez)) (option (pair mutez mutez)) ] */ } + { SWAP + /* [ mutez : nat ] */ ; + EDIV + /* [ option (pair mutez mutez) ] */ ; + RIGHT + (option (pair nat mutez)) + /* [ or (option (pair nat mutez)) (option (pair mutez mutez)) ] */ } ; + NIL operation + /* [ list operation : or (option (pair nat mutez)) (option (pair mutez mutez)) ] */ ; + PAIR + /* [ pair (list operation) (or (option (pair nat mutez)) (option (pair mutez mutez))) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--empty_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--empty_map.tz].out new file mode 100644 index 000000000000..fff011420a34 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--empty_map.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/empty_map.tz] + +Well typed +Gas remaining: 1039993.086 units remaining +{ storage (map string string) ; + parameter unit ; + code { DROP + /* [] */ ; + EMPTY_MAP string string + /* [ map string string ] */ ; + PUSH string "world" + /* [ string : map string string ] */ ; + SOME + /* [ option string : map string string ] */ ; + PUSH string "hello" + /* [ string : option string : map string string ] */ ; + UPDATE + /* [ map string string ] */ ; + NIL operation + /* [ list operation : map string string ] */ ; + PAIR + /* [ pair (list operation) (map string string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--exec_concat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--exec_concat.tz].out new file mode 100644 index 000000000000..55377c71bf7b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--exec_concat.tz].out @@ -0,0 +1,34 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/exec_concat.tz] + +Well typed +Gas remaining: 1039991.097 units remaining +{ parameter string ; + storage string ; + code { CAR + /* [ @parameter string ] */ ; + LAMBDA + string + string + { PUSH string "_abc" + /* [ string : @arg string ] */ ; + NIL string + /* [ list string : string : @arg string ] */ ; + SWAP + /* [ string : list string : @arg string ] */ ; + CONS + /* [ list string : @arg string ] */ ; + SWAP + /* [ @arg string : list string ] */ ; + CONS + /* [ list string ] */ ; + CONCAT + /* [ string ] */ } + /* [ lambda string string : @parameter string ] */ ; + SWAP + /* [ @parameter string : lambda string string ] */ ; + EXEC + /* [ string ] */ ; + NIL operation + /* [ list operation : string ] */ ; + PAIR + /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--first.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--first.tz].out new file mode 100644 index 000000000000..b4dfc99f9944 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--first.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/first.tz] + +Well typed +Gas remaining: 1039994.458 units remaining +{ parameter (list nat) ; + storage nat ; + code { CAR + /* [ @parameter list nat ] */ ; + IF_CONS { DIP { DROP /* [] */ } /* [ @parameter.hd nat ] */ } { FAIL } ; + NIL operation + /* [ list operation : @parameter.hd nat ] */ ; + PAIR + /* [ pair (list operation) (nat @parameter.hd) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_big_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_big_map.tz].out new file mode 100644 index 000000000000..06fa0a72d0d8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_big_map.tz].out @@ -0,0 +1,15 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/get_and_update_big_map.tz] + +Well typed +Gas remaining: 1039993.030 units remaining +{ parameter string ; + storage (pair (option nat) (big_map string nat)) ; + code { UNPAPAIR ; + GET_AND_UPDATE + /* [ option nat : big_map string nat ] */ ; + PAIR + /* [ pair (option nat) (big_map string nat) ] */ ; + NIL operation + /* [ list operation : pair (option nat) (big_map string nat) ] */ ; + PAIR + /* [ pair (list operation) (option nat) (big_map string nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_map.tz].out new file mode 100644 index 000000000000..18ebc6f3da3d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_and_update_map.tz].out @@ -0,0 +1,15 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/get_and_update_map.tz] + +Well typed +Gas remaining: 1039993.090 units remaining +{ parameter string ; + storage (pair (option nat) (map string nat)) ; + code { UNPAPAIR ; + GET_AND_UPDATE + /* [ option nat : map string nat ] */ ; + PAIR + /* [ pair (option nat) (map string nat) ] */ ; + NIL operation + /* [ list operation : pair (option nat) (map string nat) ] */ ; + PAIR + /* [ pair (list operation) (option nat) (map string nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_big_map_value.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_big_map_value.tz].out new file mode 100644 index 000000000000..8b646afc10e1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_big_map_value.tz].out @@ -0,0 +1,24 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/get_big_map_value.tz] + +Well typed +Gas remaining: 1039990.479 units remaining +{ parameter string ; + storage (pair (big_map string string) (option string)) ; + code { DUP + /* [ pair (string @parameter) (pair @storage (big_map string string) (option string)) + : pair (string @parameter) (pair @storage (big_map string string) (option string)) ] */ ; + CAR + /* [ @parameter string + : pair (string @parameter) (pair @storage (big_map string string) (option string)) ] */ ; + DIP { CDAR ; DUP /* [ big_map string string : big_map string string ] */ } + /* [ @parameter string : big_map string string : big_map string string ] */ ; + GET + /* [ option string : big_map string string ] */ ; + SWAP + /* [ big_map string string : option string ] */ ; + PAIR + /* [ pair (big_map string string) (option string) ] */ ; + NIL operation + /* [ list operation : pair (big_map string string) (option string) ] */ ; + PAIR + /* [ pair (list operation) (big_map string string) (option string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_map_value.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_map_value.tz].out new file mode 100644 index 000000000000..564d2dea6bfe --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--get_map_value.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/get_map_value.tz] + +Well typed +Gas remaining: 1039991.007 units remaining +{ parameter string ; + storage (pair (option string) (map string string)) ; + code { DUP + /* [ pair (string @parameter) (pair @storage (option string) (map string string)) + : pair (string @parameter) (pair @storage (option string) (map string string)) ] */ ; + CAR + /* [ @parameter string + : pair (string @parameter) (pair @storage (option string) (map string string)) ] */ ; + DIP { CDDR ; DUP /* [ map string string : map string string ] */ } + /* [ @parameter string : map string string : map string string ] */ ; + GET + /* [ option string : map string string ] */ ; + PAIR + /* [ pair (option string) (map string string) ] */ ; + NIL operation + /* [ list operation : pair (option string) (map string string) ] */ ; + PAIR + /* [ pair (list operation) (option string) (map string string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_consistency_checker.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_consistency_checker.tz].out new file mode 100644 index 000000000000..809b62ed64bc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_consistency_checker.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/hash_consistency_checker.tz] + +Well typed +Gas remaining: 1039995.929 units remaining +{ parameter (pair mutez (pair timestamp int)) ; + storage bytes ; + code { CAR + /* [ @parameter pair mutez timestamp int ] */ ; + PACK + /* [ @parameter.packed bytes ] */ ; + BLAKE2B + /* [ bytes ] */ ; + NIL operation + /* [ list operation : bytes ] */ ; + PAIR + /* [ pair (list operation) bytes ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_key.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_key.tz].out new file mode 100644 index 000000000000..371873be8b07 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_key.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/hash_key.tz] + +Well typed +Gas remaining: 1039996.037 units remaining +{ parameter key ; + storage (option key_hash) ; + code { CAR + /* [ @parameter key ] */ ; + HASH_KEY + /* [ key_hash ] */ ; + SOME + /* [ option key_hash ] */ ; + NIL operation + /* [ list operation : option key_hash ] */ ; + PAIR + /* [ pair (list operation) (option key_hash) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_string.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_string.tz].out new file mode 100644 index 000000000000..b13c5a0579e4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--hash_string.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/hash_string.tz] + +Well typed +Gas remaining: 1039996.340 units remaining +{ parameter string ; + storage bytes ; + code { CAR + /* [ @parameter string ] */ ; + PACK + /* [ @parameter.packed bytes ] */ ; + BLAKE2B + /* [ bytes ] */ ; + NIL operation + /* [ list operation : bytes ] */ ; + PAIR + /* [ pair (list operation) bytes ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if.tz].out new file mode 100644 index 000000000000..50615c8c6c60 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if.tz].out @@ -0,0 +1,15 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/if.tz] + +Well typed +Gas remaining: 1039994.330 units remaining +{ parameter bool ; + storage (option bool) ; + code { CAR + /* [ @parameter bool ] */ ; + IF { PUSH bool True /* [ bool ] */ } { PUSH bool False /* [ bool ] */ } ; + SOME + /* [ option bool ] */ ; + NIL operation + /* [ list operation : option bool ] */ ; + PAIR + /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if_some.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if_some.tz].out new file mode 100644 index 000000000000..841b190cc7cd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--if_some.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/if_some.tz] + +Well typed +Gas remaining: 1039995.219 units remaining +{ parameter (option string) ; + storage string ; + code { CAR + /* [ @parameter option string ] */ ; + IF_SOME { /* [ @parameter.some string ] */ } { PUSH string "" /* [ string ] */ } ; + NIL operation + /* [ list operation : string ] */ ; + PAIR + /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--int.tz].out new file mode 100644 index 000000000000..84a40518a7d1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--int.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/int.tz] + +Well typed +Gas remaining: 1039996.037 units remaining +{ parameter nat ; + storage (option int) ; + code { CAR + /* [ @parameter nat ] */ ; + INT + /* [ int ] */ ; + SOME + /* [ option int ] */ ; + NIL operation + /* [ list operation : option int ] */ ; + PAIR + /* [ pair (list operation) (option int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--iter_fail.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--iter_fail.tz].out new file mode 100644 index 000000000000..9007a6bb01ef --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--iter_fail.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/iter_fail.tz] + +Well typed +Gas remaining: 1039996.234 units remaining +{ parameter (set nat) ; + storage unit ; + code { UNPAIR + /* [ @parameter set nat : @storage unit ] */ ; + ITER { FAILWITH /* [] */ } + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--keccak.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--keccak.tz].out new file mode 100644 index 000000000000..d4fb835625e2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--keccak.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/keccak.tz] + +Well typed +Gas remaining: 1039996.037 units remaining +{ storage (option bytes) ; + parameter bytes ; + code { CAR + /* [ @parameter bytes ] */ ; + KECCAK + /* [ bytes ] */ ; + SOME + /* [ option bytes ] */ ; + NIL operation + /* [ list operation : option bytes ] */ ; + PAIR + /* [ pair (list operation) (option bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--left_right.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--left_right.tz].out new file mode 100644 index 000000000000..fa88c3b4a52b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--left_right.tz].out @@ -0,0 +1,15 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/left_right.tz] + +Well typed +Gas remaining: 1039994.130 units remaining +{ parameter (or bool string) ; + storage (or string bool) ; + code { CAR + /* [ @parameter or bool string ] */ ; + IF_LEFT + { RIGHT string /* [ or string bool ] */ } + { LEFT bool /* [ or string bool ] */ } ; + NIL operation + /* [ list operation : or string bool ] */ ; + PAIR + /* [ pair (list operation) (or string bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--level.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--level.tz].out new file mode 100644 index 000000000000..535a279f1f9a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--level.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/level.tz] + +Well typed +Gas remaining: 1039996.803 units remaining +{ parameter unit ; + storage nat ; + code { DROP + /* [] */ ; + LEVEL + /* [ @level nat ] */ ; + NIL operation + /* [ list operation : @level nat ] */ ; + PAIR + /* [ pair (list operation) (nat @level) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat.tz].out new file mode 100644 index 000000000000..55523e259630 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_concat.tz] + +Well typed +Gas remaining: 1039995.574 units remaining +{ parameter (list string) ; + storage string ; + code { UNPAIR + /* [ @parameter list string : @storage string ] */ ; + SWAP + /* [ @storage string : @parameter list string ] */ ; + CONS + /* [ list string ] */ ; + CONCAT + /* [ string ] */ ; + NIL operation + /* [ list operation : string ] */ ; + PAIR + /* [ pair (list operation) string ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat_bytes.tz].out new file mode 100644 index 000000000000..a1dd6671f5cf --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_concat_bytes.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_concat_bytes.tz] + +Well typed +Gas remaining: 1039995.574 units remaining +{ parameter (list bytes) ; + storage bytes ; + code { UNPAIR + /* [ @parameter list bytes : @storage bytes ] */ ; + SWAP + /* [ @storage bytes : @parameter list bytes ] */ ; + CONS + /* [ list bytes ] */ ; + CONCAT + /* [ bytes ] */ ; + NIL operation + /* [ list operation : bytes ] */ ; + PAIR + /* [ pair (list operation) bytes ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id.tz].out new file mode 100644 index 000000000000..ecaaf06159ca --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_id.tz] + +Well typed +Gas remaining: 1039996.880 units remaining +{ parameter (list string) ; + storage (list string) ; + code { CAR + /* [ @parameter list string ] */ ; + NIL operation + /* [ list operation : @parameter list string ] */ ; + PAIR + /* [ pair (list operation) (list @parameter string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id_map.tz].out new file mode 100644 index 000000000000..9ab3162055c2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_id_map.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_id_map.tz] + +Well typed +Gas remaining: 1039996.174 units remaining +{ parameter (list string) ; + storage (list string) ; + code { CAR + /* [ @parameter list string ] */ ; + MAP { /* [ @parameter.elt string ] */ } + /* [ list string ] */ ; + NIL operation + /* [ list operation : list string ] */ ; + PAIR + /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_iter.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_iter.tz].out new file mode 100644 index 000000000000..57a6f3132ef0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_iter.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_iter.tz] + +Well typed +Gas remaining: 1039994.793 units remaining +{ parameter (list int) ; + storage int ; + code { CAR + /* [ @parameter list int ] */ ; + PUSH int 1 + /* [ int : @parameter list int ] */ ; + SWAP + /* [ @parameter list int : int ] */ ; + ITER { MUL /* [ int ] */ } + /* [ int ] */ ; + NIL operation + /* [ list operation : int ] */ ; + PAIR + /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_map_block.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_map_block.tz].out new file mode 100644 index 000000000000..9d6429884bde --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_map_block.tz].out @@ -0,0 +1,25 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_map_block.tz] + +Well typed +Gas remaining: 1039990.664 units remaining +{ parameter (list int) ; + storage (list int) ; + code { CAR + /* [ @parameter list int ] */ ; + PUSH int 0 + /* [ int : @parameter list int ] */ ; + SWAP + /* [ @parameter list int : int ] */ ; + MAP { DIP { DUP /* [ int : int ] */ } + /* [ @parameter.elt int : int : int ] */ ; + ADD + /* [ int : int ] */ ; + DIP { PUSH int 1 /* [ int : int ] */ ; ADD /* [ int ] */ } + /* [ int : int ] */ } + /* [ list int : int ] */ ; + NIL operation + /* [ list operation : list int : int ] */ ; + PAIR + /* [ pair (list operation) (list int) : int ] */ ; + DIP { DROP /* [] */ } + /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_size.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_size.tz].out new file mode 100644 index 000000000000..0faf56f04559 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--list_size.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/list_size.tz] + +Well typed +Gas remaining: 1039996.720 units remaining +{ parameter (list int) ; + storage nat ; + code { CAR + /* [ @parameter list int ] */ ; + SIZE + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_failwith.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_failwith.tz].out new file mode 100644 index 000000000000..0e3c047edec0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_failwith.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/loop_failwith.tz] + +Well typed +Gas remaining: 1039996.317 units remaining +{ parameter bool ; + storage unit ; + code { UNPAIR + /* [ @parameter bool : @storage unit ] */ ; + LOOP { FAILWITH /* [] */ } + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left.tz].out new file mode 100644 index 000000000000..3049b90d4135 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left.tz].out @@ -0,0 +1,41 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/loop_left.tz] + +Well typed +Gas remaining: 1039983.876 units remaining +{ parameter (list string) ; + storage (list string) ; + code { CAR + /* [ @parameter list string ] */ ; + NIL string + /* [ list string : @parameter list string ] */ ; + SWAP + /* [ @parameter list string : list string ] */ ; + PAIR + /* [ pair (list @parameter string) (list string) ] */ ; + LEFT (list string) + /* [ or (pair (list @parameter string) (list string)) (list string) ] */ ; + LOOP_LEFT + { DUP + /* [ pair (list @parameter string) (list string) + : pair (list @parameter string) (list string) ] */ ; + CAR + /* [ @parameter list string : pair (list @parameter string) (list string) ] */ ; + DIP { CDR /* [ list string ] */ } + /* [ @parameter list string : list string ] */ ; + IF_CONS + { SWAP + /* [ @parameter.tl list string : @parameter.hd string : list string ] */ ; + DIP { CONS /* [ list string ] */ } + /* [ @parameter.tl list string : list string ] */ ; + PAIR + /* [ pair (list @parameter.tl string) (list string) ] */ ; + LEFT (list string) + /* [ or (pair (list @parameter.tl string) (list string)) (list string) ] */ } + { RIGHT + (pair (list string) (list string)) + /* [ or (pair (list string) (list string)) (list string) ] */ } } + /* [ list string ] */ ; + NIL operation + /* [ list operation : list string ] */ ; + PAIR + /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left_failwith.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left_failwith.tz].out new file mode 100644 index 000000000000..295a8f528edd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--loop_left_failwith.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/loop_left_failwith.tz] + +Well typed +Gas remaining: 1039996.076 units remaining +{ parameter (or string nat) ; + storage nat ; + code { CAR + /* [ @parameter or string nat ] */ ; + LOOP_LEFT { FAILWITH /* [] */ } + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_car.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_car.tz].out new file mode 100644 index 000000000000..8dd9764177d4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_car.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_car.tz] + +Well typed +Gas remaining: 1039990.103 units remaining +{ parameter bool ; + storage (pair (bool %b) (nat %n)) ; + code { DUP + /* [ pair (bool @parameter) (pair @storage (bool %b) (nat %n)) + : pair (bool @parameter) (pair @storage (bool %b) (nat %n)) ] */ ; + CAR + /* [ @parameter bool + : pair (bool @parameter) (pair @storage (bool %b) (nat %n)) ] */ ; + DIP { CDR /* [ @storage pair (bool %b) (nat %n) ] */ } + /* [ @parameter bool : @storage pair (bool %b) (nat %n) ] */ ; + SWAP + /* [ @storage pair (bool %b) (nat %n) : @parameter bool ] */ ; + MAP_CAR @new_storage %b { AND /* [ bool ] */ } ; + NIL operation + /* [ list operation : @storage pair (bool %b) (nat %n @storage.n) ] */ ; + PAIR + /* [ pair (list operation) (pair @storage (bool %b) (nat %n @storage.n)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_id.tz].out new file mode 100644 index 000000000000..1d0e1b192f02 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_id.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_id.tz] + +Well typed +Gas remaining: 1039996.494 units remaining +{ parameter (map nat nat) ; + storage (map nat nat) ; + code { CAR + /* [ @parameter map nat nat ] */ ; + NIL operation + /* [ list operation : @parameter map nat nat ] */ ; + PAIR + /* [ pair (list operation) (map @parameter nat nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_iter.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_iter.tz].out new file mode 100644 index 000000000000..87bb1981710e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_iter.tz].out @@ -0,0 +1,47 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_iter.tz] + +Well typed +Gas remaining: 1039985.509 units remaining +{ parameter (map (int :k) (int :e)) ; + storage (pair (int :k) (int :e)) ; + code { CAR + /* [ @parameter map (int :k) (int :e) ] */ ; + PUSH @acc_e (int :e) 0 + /* [ @acc_e int :e : @parameter map (int :k) (int :e) ] */ ; + PUSH @acc_k + (int :k) + 0 + /* [ @acc_k int :k : @acc_e int :e : @parameter map (int :k) (int :e) ] */ ; + PAIR % %r + /* [ pair (int :k @acc_k) (int :e %r @acc_e) + : @parameter map (int :k) (int :e) ] */ ; + SWAP + /* [ @parameter map (int :k) (int :e) + : pair (int :k @acc_k) (int :e %r @acc_e) ] */ ; + ITER { DIP { DUP + /* [ pair (int :k @acc_k) (int :e %r @acc_e) + : pair (int :k @acc_k) (int :e %r @acc_e) ] */ ; + CAR + /* [ @acc_k int :k : pair (int :k @acc_k) (int :e %r @acc_e) ] */ ; + DIP { CDR /* [ @acc_e int :e ] */ } + /* [ @acc_k int :k : @acc_e int :e ] */ } + /* [ pair (int :k @key) (int :e @elt) : @acc_k int :k : @acc_e int :e ] */ ; + DUP + /* [ pair (int :k @key) (int :e @elt) : pair (int :k @key) (int :e @elt) + : @acc_k int :k : @acc_e int :e ] */ ; + DIP { CAR + /* [ @key int :k : @acc_k int :k : @acc_e int :e ] */ ; + ADD + /* [ int :k : @acc_e int :e ] */ } + /* [ pair (int :k @key) (int :e @elt) : int :k : @acc_e int :e ] */ ; + SWAP + /* [ int :k : pair (int :k @key) (int :e @elt) : @acc_e int :e ] */ ; + DIP { CDR /* [ @elt int :e : @acc_e int :e ] */ ; ADD /* [ int :e ] */ } + /* [ int :k : int :e ] */ ; + PAIR % %r + /* [ pair (int :k) (int :e %r) ] */ } + /* [ pair (int :k) (int :e %r) ] */ ; + NIL operation + /* [ list operation : pair (int :k) (int :e %r) ] */ ; + PAIR + /* [ pair (list operation) (int :k) (int :e %r) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map.tz].out new file mode 100644 index 000000000000..9bd007ce33aa --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_map.tz] + +Well typed +Gas remaining: 1039992.454 units remaining +{ parameter nat ; + storage (map string nat) ; + code { UNPAIR + /* [ @parameter nat : @storage map string nat ] */ ; + SWAP + /* [ @storage map string nat : @parameter nat ] */ ; + MAP { CDR + /* [ @elt nat : @parameter nat ] */ ; + DIP { DUP /* [ @parameter nat : @parameter nat ] */ } + /* [ @elt nat : @parameter nat : @parameter nat ] */ ; + ADD + /* [ nat : @parameter nat ] */ } + /* [ map string nat : @parameter nat ] */ ; + DIP { DROP /* [] */ } + /* [ map string nat ] */ ; + NIL operation + /* [ list operation : map string nat ] */ ; + PAIR + /* [ pair (list operation) (map string nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map_sideeffect.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map_sideeffect.tz].out new file mode 100644 index 000000000000..3dca6dd1eb7b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_map_sideeffect.tz].out @@ -0,0 +1,36 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_map_sideeffect.tz] + +Well typed +Gas remaining: 1039986.934 units remaining +{ parameter nat ; + storage (pair (map string nat) nat) ; + code { UNPAIR + /* [ @parameter nat : @storage pair (map string nat) nat ] */ ; + SWAP + /* [ @storage pair (map string nat) nat : @parameter nat ] */ ; + CAR + /* [ map string nat : @parameter nat ] */ ; + DIP 2 + { PUSH @sum nat 0 /* [ @sum nat ] */ } + /* [ map string nat : @parameter nat : @sum nat ] */ ; + MAP { CDR + /* [ @elt nat : @parameter nat : @sum nat ] */ ; + DIP { DUP /* [ @parameter nat : @parameter nat : @sum nat ] */ } + /* [ @elt nat : @parameter nat : @parameter nat : @sum nat ] */ ; + ADD + /* [ nat : @parameter nat : @sum nat ] */ ; + DUP + /* [ nat : nat : @parameter nat : @sum nat ] */ ; + DUG 2 + /* [ nat : @parameter nat : nat : @sum nat ] */ ; + DIP 2 { ADD @sum /* [ @sum nat ] */ } + /* [ nat : @parameter nat : @sum nat ] */ } + /* [ map string nat : @parameter nat : @sum nat ] */ ; + DIP { DROP /* [ @sum nat ] */ } + /* [ map string nat : @sum nat ] */ ; + PAIR + /* [ pair (map string nat) (nat @sum) ] */ ; + NIL operation + /* [ list operation : pair (map string nat) (nat @sum) ] */ ; + PAIR + /* [ pair (list operation) (map string nat) (nat @sum) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_nat.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_nat.tz].out new file mode 100644 index 000000000000..26a2f64e12b1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_nat.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_mem_nat.tz] + +Well typed +Gas remaining: 1039991.954 units remaining +{ parameter nat ; + storage (pair (map nat nat) (option bool)) ; + code { UNPAIR + /* [ @parameter nat : @storage pair (map nat nat) (option bool) ] */ ; + DIP { CAR /* [ map nat nat ] */ ; DUP /* [ map nat nat : map nat nat ] */ } + /* [ @parameter nat : map nat nat : map nat nat ] */ ; + MEM + /* [ bool : map nat nat ] */ ; + SOME + /* [ option bool : map nat nat ] */ ; + SWAP + /* [ map nat nat : option bool ] */ ; + PAIR + /* [ pair (map nat nat) (option bool) ] */ ; + NIL operation + /* [ list operation : pair (map nat nat) (option bool) ] */ ; + PAIR + /* [ pair (list operation) (map nat nat) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_string.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_string.tz].out new file mode 100644 index 000000000000..b78bd9e9df66 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_mem_string.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_mem_string.tz] + +Well typed +Gas remaining: 1039991.954 units remaining +{ parameter string ; + storage (pair (map string nat) (option bool)) ; + code { UNPAIR + /* [ @parameter string : @storage pair (map string nat) (option bool) ] */ ; + DIP { CAR /* [ map string nat ] */ ; DUP /* [ map string nat : map string nat ] */ } + /* [ @parameter string : map string nat : map string nat ] */ ; + MEM + /* [ bool : map string nat ] */ ; + SOME + /* [ option bool : map string nat ] */ ; + SWAP + /* [ map string nat : option bool ] */ ; + PAIR + /* [ pair (map string nat) (option bool) ] */ ; + NIL operation + /* [ list operation : pair (map string nat) (option bool) ] */ ; + PAIR + /* [ pair (list operation) (map string nat) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_size.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_size.tz].out new file mode 100644 index 000000000000..123ff0b01fc0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--map_size.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/map_size.tz] + +Well typed +Gas remaining: 1039996.637 units remaining +{ parameter (map string nat) ; + storage nat ; + code { CAR + /* [ @parameter map string nat ] */ ; + SIZE + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--merge_comparable_pairs.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--merge_comparable_pairs.tz].out new file mode 100644 index 000000000000..d2a9726e0b9c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--merge_comparable_pairs.tz].out @@ -0,0 +1,31 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/merge_comparable_pairs.tz] + +Well typed +Gas remaining: 1039990.293 units remaining +{ parameter (set (pair (nat %n) (pair %p (string %s) (int %i)))) ; + storage nat ; + code { UNPAIR + /* [ @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) + : @storage nat ] */ ; + SWAP + /* [ @storage nat + : @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ ; + PUSH nat + 3 + /* [ nat : @storage nat + : @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ ; + COMPARE + /* [ int : @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ ; + GT + /* [ bool : @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ ; + IF { /* [ @parameter set (pair (nat %n) (pair %p (string %s) (int %i))) ] */ } + { DROP + /* [] */ ; + EMPTY_SET (pair nat (pair string int)) + /* [ set (pair nat string int) ] */ } ; + SIZE + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul.tz].out new file mode 100644 index 000000000000..f4e5b4249eaf --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul.tz].out @@ -0,0 +1,82 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul.tz] + +Well typed +Gas remaining: 1039959.301 units remaining +{ parameter unit ; + storage unit ; + code { CAR + /* [ @parameter unit ] */ ; + DROP + /* [] */ ; + PUSH nat 7987 + /* [ nat ] */ ; + PUSH mutez 10 + /* [ mutez : nat ] */ ; + MUL + /* [ mutez ] */ ; + PUSH mutez 79870 + /* [ mutez : mutez ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH mutez 10 + /* [ mutez ] */ ; + PUSH nat 7987 + /* [ nat : mutez ] */ ; + MUL + /* [ mutez ] */ ; + PUSH mutez 79870 + /* [ mutez : mutez ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH int 10 + /* [ int ] */ ; + PUSH int -7987 + /* [ int : int ] */ ; + MUL + /* [ int ] */ ; + PUSH int -79870 + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH nat 10 + /* [ nat ] */ ; + PUSH int -7987 + /* [ int : nat ] */ ; + MUL + /* [ int ] */ ; + PUSH int -79870 + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH int -10 + /* [ int ] */ ; + PUSH nat 7987 + /* [ nat : int ] */ ; + MUL + /* [ int ] */ ; + PUSH int -79870 + /* [ int : int ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + PUSH nat 10 + /* [ nat ] */ ; + PUSH nat 7987 + /* [ nat : nat ] */ ; + MUL + /* [ nat ] */ ; + PUSH nat 79870 + /* [ nat : nat ] */ ; + COMPARE + /* [ int ] */ ; + ASSERT_EQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_fr.tz].out new file mode 100644 index 000000000000..efa1d14a992f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_fr.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul_bls12_381_fr.tz] + +Well typed +Gas remaining: 1039995.329 units remaining +{ parameter (pair bls12_381_fr bls12_381_fr) ; + storage (option bls12_381_fr) ; + code { CAR + /* [ @parameter pair bls12_381_fr bls12_381_fr ] */ ; + UNPAIR + /* [ bls12_381_fr : bls12_381_fr ] */ ; + MUL + /* [ bls12_381_fr ] */ ; + SOME + /* [ option bls12_381_fr ] */ ; + NIL operation + /* [ list operation : option bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g1.tz].out new file mode 100644 index 000000000000..1c0d887c831f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g1.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul_bls12_381_g1.tz] + +Well typed +Gas remaining: 1039995.329 units remaining +{ parameter (pair bls12_381_g1 bls12_381_fr) ; + storage (option bls12_381_g1) ; + code { CAR + /* [ @parameter pair bls12_381_g1 bls12_381_fr ] */ ; + UNPAIR + /* [ bls12_381_g1 : bls12_381_fr ] */ ; + MUL + /* [ bls12_381_g1 ] */ ; + SOME + /* [ option bls12_381_g1 ] */ ; + NIL operation + /* [ list operation : option bls12_381_g1 ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_g1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g2.tz].out new file mode 100644 index 000000000000..d21874d9fb49 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_bls12_381_g2.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul_bls12_381_g2.tz] + +Well typed +Gas remaining: 1039995.329 units remaining +{ parameter (pair bls12_381_g2 bls12_381_fr) ; + storage (option bls12_381_g2) ; + code { CAR + /* [ @parameter pair bls12_381_g2 bls12_381_fr ] */ ; + UNPAIR + /* [ bls12_381_g2 : bls12_381_fr ] */ ; + MUL + /* [ bls12_381_g2 ] */ ; + SOME + /* [ option bls12_381_g2 ] */ ; + NIL operation + /* [ list operation : option bls12_381_g2 ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_g2) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_overflow.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_overflow.tz].out new file mode 100644 index 000000000000..efa225b8c49e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mul_overflow.tz].out @@ -0,0 +1,29 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mul_overflow.tz] + +Well typed +Gas remaining: 1039991.544 units remaining +{ parameter (or unit unit) ; + storage unit ; + code { CAR + /* [ @parameter or unit unit ] */ ; + IF_LEFT + { PUSH nat 922337203685477580700 + /* [ nat : @parameter.left unit ] */ ; + PUSH mutez 10 + /* [ mutez : nat : @parameter.left unit ] */ ; + MUL + /* [ mutez : @parameter.left unit ] */ ; + DROP + /* [ @parameter.left unit ] */ } + { PUSH mutez 10 + /* [ mutez : @parameter.right unit ] */ ; + PUSH nat 922337203685477580700 + /* [ nat : mutez : @parameter.right unit ] */ ; + MUL + /* [ mutez : @parameter.right unit ] */ ; + DROP + /* [ @parameter.right unit ] */ } ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--munch.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--munch.tz].out new file mode 100644 index 000000000000..8741bc184828 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--munch.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/munch.tz] + +Well typed +Gas remaining: 1039996.425 units remaining +{ parameter + (or (bytes %bytes) (or (lambda %lambda unit unit) (or (nat %nat) (list %list_nat nat)))) ; + storage unit ; + code { CDR + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mutez_to_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mutez_to_bls12_381_fr.tz].out new file mode 100644 index 000000000000..612a9dd0787f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--mutez_to_bls12_381_fr.tz].out @@ -0,0 +1,25 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/mutez_to_bls12_381_fr.tz] + +Well typed +Gas remaining: 1039991.653 units remaining +{ parameter mutez ; + storage bls12_381_fr ; + code { CAR + /* [ @parameter mutez ] */ ; + PUSH mutez 1 + /* [ mutez : @parameter mutez ] */ ; + SWAP + /* [ @parameter mutez : mutez ] */ ; + EDIV + /* [ option (pair nat mutez) ] */ ; + ASSERT_SOME ; + CAR + /* [ nat ] */ ; + PUSH bls12_381_fr 1 + /* [ bls12_381_fr : nat ] */ ; + MUL + /* [ bls12_381_fr ] */ ; + NIL operation + /* [ list operation : bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) bls12_381_fr ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg.tz].out new file mode 100644 index 000000000000..49c1843df0c2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/neg.tz] + +Well typed +Gas remaining: 1039995.361 units remaining +{ parameter (or int nat) ; + storage int ; + code { CAR + /* [ @parameter or int nat ] */ ; + IF_LEFT { NEG /* [ int ] */ } { NEG /* [ int ] */ } ; + NIL operation + /* [ list operation : int ] */ ; + PAIR + /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_fr.tz].out new file mode 100644 index 000000000000..479b0be9e1e4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_fr.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/neg_bls12_381_fr.tz] + +Well typed +Gas remaining: 1039996.037 units remaining +{ parameter bls12_381_fr ; + storage (option bls12_381_fr) ; + code { CAR + /* [ @parameter bls12_381_fr ] */ ; + NEG + /* [ bls12_381_fr ] */ ; + SOME + /* [ option bls12_381_fr ] */ ; + NIL operation + /* [ list operation : option bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g1.tz].out new file mode 100644 index 000000000000..95656a8287d7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g1.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/neg_bls12_381_g1.tz] + +Well typed +Gas remaining: 1039996.037 units remaining +{ parameter bls12_381_g1 ; + storage (option bls12_381_g1) ; + code { CAR + /* [ @parameter bls12_381_g1 ] */ ; + NEG + /* [ bls12_381_g1 ] */ ; + SOME + /* [ option bls12_381_g1 ] */ ; + NIL operation + /* [ list operation : option bls12_381_g1 ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_g1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g2.tz].out new file mode 100644 index 000000000000..884f183eee52 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--neg_bls12_381_g2.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/neg_bls12_381_g2.tz] + +Well typed +Gas remaining: 1039996.037 units remaining +{ parameter bls12_381_g2 ; + storage (option bls12_381_g2) ; + code { CAR + /* [ @parameter bls12_381_g2 ] */ ; + NEG + /* [ bls12_381_g2 ] */ ; + SOME + /* [ option bls12_381_g2 ] */ ; + NIL operation + /* [ list operation : option bls12_381_g2 ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_g2) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--none.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--none.tz].out new file mode 100644 index 000000000000..bc51cfab6bba --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--none.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/none.tz] + +Well typed +Gas remaining: 1039996.417 units remaining +{ parameter unit ; + storage (option nat) ; + code { DROP + /* [] */ ; + NONE nat + /* [ option nat ] */ ; + NIL operation + /* [ list operation : option nat ] */ ; + PAIR + /* [ pair (list operation) (option nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--noop.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--noop.tz].out new file mode 100644 index 000000000000..95d59989eba5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--noop.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/noop.tz] + +Well typed +Gas remaining: 1039997.267 units remaining +{ parameter unit ; + storage unit ; + code { CDR + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not.tz].out new file mode 100644 index 000000000000..ad6a9cc30a7b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/not.tz] + +Well typed +Gas remaining: 1039996.037 units remaining +{ parameter bool ; + storage (option bool) ; + code { CAR + /* [ @parameter bool ] */ ; + NOT + /* [ bool ] */ ; + SOME + /* [ option bool ] */ ; + NIL operation + /* [ list operation : option bool ] */ ; + PAIR + /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not_binary.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not_binary.tz].out new file mode 100644 index 000000000000..ba4ec737da7e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--not_binary.tz].out @@ -0,0 +1,15 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/not_binary.tz] + +Well typed +Gas remaining: 1039994.585 units remaining +{ parameter (or int nat) ; + storage (option int) ; + code { CAR + /* [ @parameter or int nat ] */ ; + IF_LEFT { NOT /* [ int ] */ } { NOT /* [ int ] */ } ; + SOME + /* [ option int ] */ ; + NIL operation + /* [ list operation : option int ] */ ; + PAIR + /* [ pair (list operation) (option int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or.tz].out new file mode 100644 index 000000000000..9094a6ec1ea6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or.tz].out @@ -0,0 +1,24 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/or.tz] + +Well typed +Gas remaining: 1039993.625 units remaining +{ parameter (pair bool bool) ; + storage (option bool) ; + code { CAR + /* [ @parameter pair bool bool ] */ ; + DUP + /* [ @parameter pair bool bool : @parameter pair bool bool ] */ ; + CAR + /* [ bool : @parameter pair bool bool ] */ ; + SWAP + /* [ @parameter pair bool bool : bool ] */ ; + CDR + /* [ bool : bool ] */ ; + OR + /* [ bool ] */ ; + SOME + /* [ option bool ] */ ; + NIL operation + /* [ list operation : option bool ] */ ; + PAIR + /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or_binary.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or_binary.tz].out new file mode 100644 index 000000000000..b51af4351567 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--or_binary.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/or_binary.tz] + +Well typed +Gas remaining: 1039995.329 units remaining +{ parameter (pair nat nat) ; + storage (option nat) ; + code { CAR + /* [ @parameter pair nat nat ] */ ; + UNPAIR + /* [ nat : nat ] */ ; + OR + /* [ nat ] */ ; + SOME + /* [ option nat ] */ ; + NIL operation + /* [ list operation : option nat ] */ ; + PAIR + /* [ pair (list operation) (option nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--originate_big_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--originate_big_map.tz].out new file mode 100644 index 000000000000..1a20de4a05c4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--originate_big_map.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/originate_big_map.tz] + +Well typed +Gas remaining: 1039996.374 units remaining +{ parameter (big_map int int) ; + storage (big_map int int) ; + code { CAR + /* [ @parameter big_map int int ] */ ; + NIL operation + /* [ list operation : @parameter big_map int int ] */ ; + PAIR + /* [ pair (list operation) (big_map @parameter int int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack.tz].out new file mode 100644 index 000000000000..b58425d33ba3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack.tz].out @@ -0,0 +1,27 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/packunpack.tz] + +Well typed +Gas remaining: 1039986.390 units remaining +{ parameter (pair (pair (pair string (list int)) (set nat)) bytes) ; + storage unit ; + code { CAR + /* [ @parameter pair (pair (pair string (list int)) (set nat)) bytes ] */ ; + UNPAIR + /* [ pair (pair string (list int)) (set nat) : bytes ] */ ; + DIP { DUP /* [ bytes : bytes ] */ } + /* [ pair (pair string (list int)) (set nat) : bytes : bytes ] */ ; + PACK + /* [ @packed bytes : bytes : bytes ] */ ; + ASSERT_CMPEQ ; + UNPACK + (pair (pair string (list int)) (set nat)) + /* [ @unpacked option (pair (pair string (list int)) (set nat)) ] */ ; + ASSERT_SOME ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev.tz].out new file mode 100644 index 000000000000..16142b62ce1c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev.tz].out @@ -0,0 +1,171 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/packunpack_rev.tz] + +Well typed +Gas remaining: 1039885.614 units remaining +{ parameter (pair int nat string bytes mutez bool key_hash timestamp address) ; + storage unit ; + code { CAR + /* [ @parameter pair int nat string bytes mutez bool key_hash timestamp address ] */ ; + DUP + /* [ @parameter pair int nat string bytes mutez bool key_hash timestamp address + : @parameter pair int nat string bytes mutez bool key_hash timestamp address ] */ ; + CAR + /* [ int + : @parameter pair int nat string bytes mutez bool key_hash timestamp address ] */ ; + DIP { UNPAIR + /* [ int : pair nat string bytes mutez bool key_hash timestamp address ] */ } + /* [ int : int : pair nat string bytes mutez bool key_hash timestamp address ] */ ; + PACK + /* [ @packed bytes : int + : pair nat string bytes mutez bool key_hash timestamp address ] */ ; + UNPACK + int + /* [ @packed.unpacked option int : int + : pair nat string bytes mutez bool key_hash timestamp address ] */ ; + ASSERT_SOME ; + ASSERT_CMPEQ ; + DUP + /* [ pair nat string bytes mutez bool key_hash timestamp address + : pair nat string bytes mutez bool key_hash timestamp address ] */ ; + CAR + /* [ nat : pair nat string bytes mutez bool key_hash timestamp address ] */ ; + DIP { UNPAIR /* [ nat : pair string bytes mutez bool key_hash timestamp address ] */ } + /* [ nat : nat : pair string bytes mutez bool key_hash timestamp address ] */ ; + PACK + /* [ @packed bytes : nat + : pair string bytes mutez bool key_hash timestamp address ] */ ; + UNPACK + nat + /* [ @packed.unpacked option nat : nat + : pair string bytes mutez bool key_hash timestamp address ] */ ; + ASSERT_SOME ; + ASSERT_CMPEQ ; + DUP + /* [ pair string bytes mutez bool key_hash timestamp address + : pair string bytes mutez bool key_hash timestamp address ] */ ; + CAR + /* [ string : pair string bytes mutez bool key_hash timestamp address ] */ ; + DIP { UNPAIR /* [ string : pair bytes mutez bool key_hash timestamp address ] */ } + /* [ string : string : pair bytes mutez bool key_hash timestamp address ] */ ; + PACK + /* [ @packed bytes : string : pair bytes mutez bool key_hash timestamp address ] */ ; + UNPACK + string + /* [ @packed.unpacked option string : string + : pair bytes mutez bool key_hash timestamp address ] */ ; + ASSERT_SOME ; + ASSERT_CMPEQ ; + DUP + /* [ pair bytes mutez bool key_hash timestamp address + : pair bytes mutez bool key_hash timestamp address ] */ ; + CAR + /* [ bytes : pair bytes mutez bool key_hash timestamp address ] */ ; + DIP { UNPAIR /* [ bytes : pair mutez bool key_hash timestamp address ] */ } + /* [ bytes : bytes : pair mutez bool key_hash timestamp address ] */ ; + PACK + /* [ @packed bytes : bytes : pair mutez bool key_hash timestamp address ] */ ; + UNPACK + bytes + /* [ @packed.unpacked option bytes : bytes + : pair mutez bool key_hash timestamp address ] */ ; + ASSERT_SOME ; + ASSERT_CMPEQ ; + DUP + /* [ pair mutez bool key_hash timestamp address + : pair mutez bool key_hash timestamp address ] */ ; + CAR + /* [ mutez : pair mutez bool key_hash timestamp address ] */ ; + DIP { UNPAIR /* [ mutez : pair bool key_hash timestamp address ] */ } + /* [ mutez : mutez : pair bool key_hash timestamp address ] */ ; + PACK + /* [ @packed bytes : mutez : pair bool key_hash timestamp address ] */ ; + UNPACK + mutez + /* [ @packed.unpacked option mutez : mutez + : pair bool key_hash timestamp address ] */ ; + ASSERT_SOME ; + ASSERT_CMPEQ ; + DUP + /* [ pair bool key_hash timestamp address + : pair bool key_hash timestamp address ] */ ; + CAR + /* [ bool : pair bool key_hash timestamp address ] */ ; + DIP { UNPAIR /* [ bool : pair key_hash timestamp address ] */ } + /* [ bool : bool : pair key_hash timestamp address ] */ ; + PACK + /* [ @packed bytes : bool : pair key_hash timestamp address ] */ ; + UNPACK + bool + /* [ @packed.unpacked option bool : bool : pair key_hash timestamp address ] */ ; + ASSERT_SOME ; + ASSERT_CMPEQ ; + DUP + /* [ pair key_hash timestamp address : pair key_hash timestamp address ] */ ; + CAR + /* [ key_hash : pair key_hash timestamp address ] */ ; + DIP { UNPAIR /* [ key_hash : pair timestamp address ] */ } + /* [ key_hash : key_hash : pair timestamp address ] */ ; + PACK + /* [ @packed bytes : key_hash : pair timestamp address ] */ ; + UNPACK + key_hash + /* [ @packed.unpacked option key_hash : key_hash : pair timestamp address ] */ ; + ASSERT_SOME ; + ASSERT_CMPEQ ; + DUP + /* [ pair timestamp address : pair timestamp address ] */ ; + CAR + /* [ timestamp : pair timestamp address ] */ ; + DIP { UNPAIR /* [ timestamp : address ] */ } + /* [ timestamp : timestamp : address ] */ ; + PACK + /* [ @packed bytes : timestamp : address ] */ ; + UNPACK timestamp + /* [ @packed.unpacked option timestamp : timestamp : address ] */ ; + ASSERT_SOME ; + ASSERT_CMPEQ ; + DUP + /* [ address : address ] */ ; + PACK + /* [ @packed bytes : address ] */ ; + UNPACK address + /* [ @packed.unpacked option address : address ] */ ; + ASSERT_SOME ; + ASSERT_CMPEQ ; + PUSH int 0 + /* [ int ] */ ; + PACK + /* [ @packed bytes ] */ ; + UNPACK nat + /* [ @packed.unpacked option nat ] */ ; + ASSERT_SOME ; + DROP + /* [] */ ; + PUSH int -1 + /* [ int ] */ ; + PACK + /* [ @packed bytes ] */ ; + UNPACK nat + /* [ @packed.unpacked option nat ] */ ; + ASSERT_NONE ; + PUSH bytes 0x + /* [ bytes ] */ ; + UNPACK nat + /* [ @unpacked option nat ] */ ; + ASSERT_NONE ; + PUSH bytes 0x04 + /* [ bytes ] */ ; + UNPACK nat + /* [ @unpacked option nat ] */ ; + ASSERT_NONE ; + PUSH bytes 0x05 + /* [ bytes ] */ ; + UNPACK nat + /* [ @unpacked option nat ] */ ; + ASSERT_NONE ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev_cty.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev_cty.tz].out new file mode 100644 index 000000000000..b130f232e1f5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--packunpack_rev_cty.tz].out @@ -0,0 +1,614 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/packunpack_rev_cty.tz] + +Well typed +Gas remaining: 1039871.738 units remaining +{ parameter + (pair key + unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes)) ; + storage unit ; + code { CAR + /* [ @parameter pair key + unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DUP + /* [ @parameter pair key + unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) + : @parameter pair key + unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + CAR + /* [ key + : @parameter pair key + unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { UNPAIR + /* [ key + : pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ key : key + : pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + PACK + /* [ @packed bytes : key + : pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { PACK + /* [ @packed bytes + : pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + UNPACK + key + /* [ @packed.unpacked option key + : pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes + : pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes + : pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) + : pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + CAR + /* [ unit + : pair unit + signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { UNPAIR + /* [ unit + : pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ unit : unit + : pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + PACK + /* [ @packed bytes : unit + : pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { PACK + /* [ @packed bytes + : pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + UNPACK + unit + /* [ @packed.unpacked option unit + : pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes + : pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes + : pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) + : pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + CAR + /* [ signature + : pair signature + (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { UNPAIR + /* [ signature + : pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ signature : signature + : pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + PACK + /* [ @packed bytes : signature + : pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { PACK + /* [ @packed bytes + : pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + UNPACK + signature + /* [ @packed.unpacked option signature + : pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes + : pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes + : pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) + : pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + CAR + /* [ option signature + : pair (option signature) + (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { UNPAIR + /* [ option signature + : pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ option signature : option signature + : pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + PACK + /* [ @packed bytes : option signature + : pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { PACK + /* [ @packed bytes + : pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + UNPACK + (option signature) + /* [ @packed.unpacked option (option signature) + : pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes + : pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes + : pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) + : pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + CAR + /* [ list unit + : pair (list unit) + (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { UNPAIR + /* [ list unit + : pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ list unit : list unit + : pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + PACK + /* [ @packed bytes : list unit + : pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { PACK + /* [ @packed bytes + : pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + UNPACK + (list unit) + /* [ @packed.unpacked option (list unit) + : pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes + : pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes + : pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) + : pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + CAR + /* [ set bool + : pair (set bool) + (pair int int) + (or key_hash timestamp) + (map int string) + (lambda string bytes) ] */ ; + DIP { UNPAIR + /* [ set bool + : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ } + /* [ set bool : set bool + : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + PACK + /* [ @packed bytes : set bool + : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + DIP { PACK + /* [ @packed bytes + : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + UNPACK + (set bool) + /* [ @packed.unpacked option (set bool) + : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes + : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes + : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) + : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + CAR + /* [ pair int int + : pair (pair int int) (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + DIP { UNPAIR + /* [ pair int int + : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ } + /* [ pair int int : pair int int + : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + PACK + /* [ @packed bytes : pair int int + : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + DIP { PACK + /* [ @packed bytes + : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + UNPACK + (pair int int) + /* [ @packed.unpacked option (pair int int) + : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes + : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes + : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ pair (or key_hash timestamp) (map int string) (lambda string bytes) + : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + CAR + /* [ or key_hash timestamp + : pair (or key_hash timestamp) (map int string) (lambda string bytes) ] */ ; + DIP { UNPAIR + /* [ or key_hash timestamp : pair (map int string) (lambda string bytes) ] */ } + /* [ or key_hash timestamp : or key_hash timestamp + : pair (map int string) (lambda string bytes) ] */ ; + PACK + /* [ @packed bytes : or key_hash timestamp + : pair (map int string) (lambda string bytes) ] */ ; + DIP { PACK + /* [ @packed bytes : pair (map int string) (lambda string bytes) ] */ ; + UNPACK + (or key_hash timestamp) + /* [ @packed.unpacked option (or key_hash timestamp) + : pair (map int string) (lambda string bytes) ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes + : pair (map int string) (lambda string bytes) ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes + : pair (map int string) (lambda string bytes) ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ pair (map int string) (lambda string bytes) + : pair (map int string) (lambda string bytes) ] */ ; + CAR + /* [ map int string : pair (map int string) (lambda string bytes) ] */ ; + DIP { UNPAIR /* [ map int string : lambda string bytes ] */ } + /* [ map int string : map int string : lambda string bytes ] */ ; + PACK + /* [ @packed bytes : map int string : lambda string bytes ] */ ; + DIP { PACK + /* [ @packed bytes : lambda string bytes ] */ ; + UNPACK + (map int string) + /* [ @packed.unpacked option (map int string) : lambda string bytes ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes : lambda string bytes ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes : lambda string bytes ] */ ; + ASSERT_CMPEQ ; + DUP + /* [ lambda string bytes : lambda string bytes ] */ ; + PACK + /* [ @packed bytes : lambda string bytes ] */ ; + DIP { PACK + /* [ @packed bytes ] */ ; + UNPACK (lambda string bytes) + /* [ @packed.unpacked option (lambda string bytes) ] */ ; + ASSERT_SOME ; + PACK + /* [ @packed.unpacked.some.packed bytes ] */ } + /* [ @packed bytes : @packed.unpacked.some.packed bytes ] */ ; + ASSERT_CMPEQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pair_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pair_id.tz].out new file mode 100644 index 000000000000..1ff3aed19b47 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pair_id.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/pair_id.tz] + +Well typed +Gas remaining: 1039995.649 units remaining +{ parameter (pair bool bool) ; + storage (option (pair bool bool)) ; + code { CAR + /* [ @parameter pair bool bool ] */ ; + SOME + /* [ option (pair bool bool) ] */ ; + NIL operation + /* [ list operation : option (pair bool bool) ] */ ; + PAIR + /* [ pair (list operation) (option (pair bool bool)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pairing_check.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pairing_check.tz].out new file mode 100644 index 000000000000..5eab4455b17b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pairing_check.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/pairing_check.tz] + +Well typed +Gas remaining: 1039995.709 units remaining +{ parameter (list (pair bls12_381_g1 bls12_381_g2)) ; + storage (option bool) ; + code { CAR + /* [ @parameter list (pair bls12_381_g1 bls12_381_g2) ] */ ; + PAIRING_CHECK + /* [ bool ] */ ; + SOME + /* [ option bool ] */ ; + NIL operation + /* [ list operation : option bool ] */ ; + PAIR + /* [ pair (list operation) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec.tz].out new file mode 100644 index 000000000000..631bbbc2f75b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/pexec.tz] + +Well typed +Gas remaining: 1039992.874 units remaining +{ parameter nat ; + storage nat ; + code { LAMBDA + (pair nat nat) + nat + { UNPAIR /* [ nat : nat ] */ ; ADD /* [ nat ] */ } + /* [ lambda (pair nat nat) nat : pair (nat @parameter) (nat @storage) ] */ ; + SWAP + /* [ pair (nat @parameter) (nat @storage) : lambda (pair nat nat) nat ] */ ; + UNPAIR + /* [ @parameter nat : @storage nat : lambda (pair nat nat) nat ] */ ; + DIP { APPLY /* [ lambda nat nat ] */ } + /* [ @parameter nat : lambda nat nat ] */ ; + EXEC + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec_2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec_2.tz].out new file mode 100644 index 000000000000..19226a51409e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--pexec_2.tz].out @@ -0,0 +1,41 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/pexec_2.tz] + +Well typed +Gas remaining: 1039986.241 units remaining +{ parameter int ; + storage (list int) ; + code { UNPAIR @p @s + /* [ @p int : @s list int ] */ ; + LAMBDA + (pair int (pair int int)) + int + { UNPAIR + /* [ int : pair int int ] */ ; + DIP { UNPAIR /* [ int : int ] */ } + /* [ int : int : int ] */ ; + ADD + /* [ int : int ] */ ; + MUL + /* [ int ] */ } + /* [ lambda (pair int int int) int : @p int : @s list int ] */ ; + SWAP + /* [ @p int : lambda (pair int int int) int : @s list int ] */ ; + APPLY + /* [ lambda (pair int int) int : @s list int ] */ ; + PUSH int 3 + /* [ int : lambda (pair int int) int : @s list int ] */ ; + APPLY + /* [ lambda int int : @s list int ] */ ; + SWAP + /* [ @s list int : lambda int int ] */ ; + MAP { DIP { DUP /* [ lambda int int : lambda int int ] */ } + /* [ @s.elt int : lambda int int : lambda int int ] */ ; + EXEC + /* [ int : lambda int int ] */ } + /* [ list int : lambda int int ] */ ; + DIP { DROP /* [] */ } + /* [ list int ] */ ; + NIL operation + /* [ list operation : list int ] */ ; + PAIR + /* [ pair (list operation) (list int) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--proxy.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--proxy.tz].out new file mode 100644 index 000000000000..a7ab55a70096 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--proxy.tz].out @@ -0,0 +1,20 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/proxy.tz] + +Well typed +Gas remaining: 1039994.321 units remaining +{ parameter (contract unit) ; + storage unit ; + code { UNPAIR + /* [ @parameter contract unit : @storage unit ] */ ; + AMOUNT + /* [ @amount mutez : @parameter contract unit : @storage unit ] */ ; + UNIT + /* [ unit : @amount mutez : @parameter contract unit : @storage unit ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage unit ] */ ; + DIP { NIL operation /* [ list operation : @storage unit ] */ } + /* [ operation : list operation : @storage unit ] */ ; + CONS + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ret_int.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ret_int.tz].out new file mode 100644 index 000000000000..9dc43d75028c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ret_int.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ret_int.tz] + +Well typed +Gas remaining: 1039995.756 units remaining +{ parameter unit ; + storage (option nat) ; + code { DROP + /* [] */ ; + PUSH nat 300 + /* [ nat ] */ ; + SOME + /* [ option nat ] */ ; + NIL operation + /* [ list operation : option nat ] */ ; + PAIR + /* [ pair (list operation) (option nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse.tz].out new file mode 100644 index 000000000000..0b05a6045466 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/reverse.tz] + +Well typed +Gas remaining: 1039994.173 units remaining +{ parameter (list string) ; + storage (list string) ; + code { CAR + /* [ @parameter list string ] */ ; + NIL string + /* [ list string : @parameter list string ] */ ; + SWAP + /* [ @parameter list string : list string ] */ ; + ITER { CONS /* [ list string ] */ } + /* [ list string ] */ ; + NIL operation + /* [ list operation : list string ] */ ; + PAIR + /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse_loop.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse_loop.tz].out new file mode 100644 index 000000000000..7fcff7506b7a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--reverse_loop.tz].out @@ -0,0 +1,32 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/reverse_loop.tz] + +Well typed +Gas remaining: 1039987.683 units remaining +{ parameter (list string) ; + storage (list string) ; + code { CAR + /* [ @parameter list string ] */ ; + NIL string + /* [ list string : @parameter list string ] */ ; + SWAP + /* [ @parameter list string : list string ] */ ; + PUSH bool True + /* [ bool : @parameter list string : list string ] */ ; + LOOP { IF_CONS + { SWAP + /* [ @parameter.tl list string : @parameter.hd string : list string ] */ ; + DIP { CONS /* [ list string ] */ } + /* [ @parameter.tl list string : list string ] */ ; + PUSH bool True + /* [ bool : @parameter.tl list string : list string ] */ } + { NIL string + /* [ list string : list string ] */ ; + PUSH bool False + /* [ bool : list string : list string ] */ } } + /* [ @parameter list string : list string ] */ ; + DROP + /* [ list string ] */ ; + NIL operation + /* [ list operation : list string ] */ ; + PAIR + /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sapling_empty_state.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sapling_empty_state.tz].out new file mode 100644 index 000000000000..5a9108c8fc51 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sapling_empty_state.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sapling_empty_state.tz] + +Well typed +Gas remaining: 1039996.757 units remaining +{ parameter unit ; + storage (sapling_state 8) ; + code { DROP + /* [] */ ; + SAPLING_EMPTY_STATE 8 + /* [ @sapling sapling_state 8 ] */ ; + NIL operation + /* [ list operation : @sapling sapling_state 8 ] */ ; + PAIR + /* [ pair (list operation) (sapling_state @sapling 8) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self.tz].out new file mode 100644 index 000000000000..8e6e8055b917 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self.tz] + +Well typed +Gas remaining: 1039996.340 units remaining +{ parameter unit ; + storage address ; + code { DROP + /* [] */ ; + SELF + /* [ @self contract unit ] */ ; + ADDRESS + /* [ @self.address address ] */ ; + NIL operation + /* [ list operation : @self.address address ] */ ; + PAIR + /* [ pair (list operation) (address @self.address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address.tz].out new file mode 100644 index 000000000000..240bd023957f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address.tz].out @@ -0,0 +1,28 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_address.tz] + +Well typed +Gas remaining: 1039988.984 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + LAMBDA + unit + address + { DROP /* [] */ ; SELF_ADDRESS /* [ @self address ] */ } + /* [ lambda unit address ] */ ; + UNIT + /* [ unit : lambda unit address ] */ ; + EXEC + /* [ address ] */ ; + SELF + /* [ @self contract unit : address ] */ ; + ADDRESS + /* [ @self.address address : address ] */ ; + ASSERT_CMPEQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_fib_view.tz].out new file mode 100644 index 000000000000..62bbea17f30a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_fib_view.tz].out @@ -0,0 +1,38 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_address_after_fib_view.tz] + +Well typed +Gas remaining: 1039985.607 units remaining +{ parameter address ; + storage address ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 3 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "fib" nat + /* [ @parameter.contract option nat : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 1500 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + SELF_ADDRESS + /* [ @self address : operation ] */ ; + SWAP + /* [ operation : @self address ] */ ; + NIL operation + /* [ list operation : operation : @self address ] */ ; + SWAP + /* [ operation : list operation : @self address ] */ ; + CONS + /* [ list operation : @self address ] */ ; + PAIR + /* [ pair (list operation) (address @self) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_nonexistent_view.tz].out new file mode 100644 index 000000000000..2a77224abd90 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_nonexistent_view.tz].out @@ -0,0 +1,36 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_address_after_nonexistent_view.tz] + +Well typed +Gas remaining: 1039986.090 units remaining +{ parameter address ; + storage address ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "id" string + /* [ @parameter.contract option string : @parameter address ] */ ; + ASSERT_NONE ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 1500 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + SELF_ADDRESS + /* [ @self address : operation ] */ ; + SWAP + /* [ operation : @self address ] */ ; + NIL operation + /* [ list operation : operation : @self address ] */ ; + SWAP + /* [ operation : list operation : @self address ] */ ; + CONS + /* [ list operation : @self address ] */ ; + PAIR + /* [ pair (list operation) (address @self) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_view.tz].out new file mode 100644 index 000000000000..511c9288f6df --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_address_after_view.tz].out @@ -0,0 +1,39 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_address_after_view.tz] + +Well typed +Gas remaining: 1039985.432 units remaining +{ parameter address ; + storage address ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "id" + (pair nat nat) + /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 1500 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + SELF_ADDRESS + /* [ @self address : operation ] */ ; + SWAP + /* [ operation : @self address ] */ ; + NIL operation + /* [ list operation : operation : @self address ] */ ; + SWAP + /* [ operation : list operation : @self address ] */ ; + CONS + /* [ list operation : @self address ] */ ; + PAIR + /* [ pair (list operation) (address @self) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_fib_view.tz].out new file mode 100644 index 000000000000..0e5fd8f4453e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_fib_view.tz].out @@ -0,0 +1,40 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_after_fib_view.tz] + +Well typed +Gas remaining: 1039985.135 units remaining +{ parameter address ; + storage address ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 3 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "fib" nat + /* [ @parameter.contract option nat : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 1500 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + SELF + /* [ @self contract address : operation ] */ ; + ADDRESS + /* [ @self.address address : operation ] */ ; + SWAP + /* [ operation : @self.address address ] */ ; + NIL operation + /* [ list operation : operation : @self.address address ] */ ; + SWAP + /* [ operation : list operation : @self.address address ] */ ; + CONS + /* [ list operation : @self.address address ] */ ; + PAIR + /* [ pair (list operation) (address @self.address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_nonexistent_view.tz].out new file mode 100644 index 000000000000..4bbcdb2c6e04 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_nonexistent_view.tz].out @@ -0,0 +1,39 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_after_nonexistent_view.tz] + +Well typed +Gas remaining: 1039985.527 units remaining +{ parameter address ; + storage address ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "nonexistent" + string + /* [ @parameter.contract option string : @parameter address ] */ ; + ASSERT_NONE ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 1500 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + SELF + /* [ @self contract address : operation ] */ ; + ADDRESS + /* [ @self.address address : operation ] */ ; + SWAP + /* [ operation : @self.address address ] */ ; + NIL operation + /* [ list operation : operation : @self.address address ] */ ; + SWAP + /* [ operation : list operation : @self.address address ] */ ; + CONS + /* [ list operation : @self.address address ] */ ; + PAIR + /* [ pair (list operation) (address @self.address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_view.tz].out new file mode 100644 index 000000000000..384cdd964205 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_after_view.tz].out @@ -0,0 +1,41 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_after_view.tz] + +Well typed +Gas remaining: 1039984.961 units remaining +{ parameter address ; + storage address ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "id" + (pair nat nat) + /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 1500 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + SELF + /* [ @self contract address : operation ] */ ; + ADDRESS + /* [ @self.address address : operation ] */ ; + SWAP + /* [ operation : @self.address address ] */ ; + NIL operation + /* [ list operation : operation : @self.address address ] */ ; + SWAP + /* [ operation : list operation : @self.address address ] */ ; + CONS + /* [ list operation : @self.address address ] */ ; + PAIR + /* [ pair (list operation) (address @self.address) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_default_entrypoint.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_default_entrypoint.tz].out new file mode 100644 index 000000000000..db60bbec1e13 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_default_entrypoint.tz].out @@ -0,0 +1,31 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_with_default_entrypoint.tz] + +Well typed +Gas remaining: 1039988.615 units remaining +{ parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %default) (string %C))) ; + storage unit ; + code { DROP + /* [] */ ; + SELF + /* [ @self contract unit ] */ ; + DROP + /* [] */ ; + SELF %A + /* [ @self contract nat ] */ ; + DROP + /* [] */ ; + SELF %default + /* [ @self contract unit ] */ ; + PACK + /* [ @self.packed bytes ] */ ; + SELF + /* [ @self contract unit : @self.packed bytes ] */ ; + PACK + /* [ @self.packed bytes : @self.packed bytes ] */ ; + ASSERT_CMPEQ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_entrypoint.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_entrypoint.tz].out new file mode 100644 index 000000000000..69b7e50ba2d6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--self_with_entrypoint.tz].out @@ -0,0 +1,70 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/self_with_entrypoint.tz] + +Well typed +Gas remaining: 1039967.216 units remaining +{ parameter (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ; + storage unit ; + code { DROP + /* [] */ ; + SELF %A + /* [ @self contract nat ] */ ; + PACK @Apacked + /* [ @Apacked bytes ] */ ; + SELF %default + /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) + : @Apacked bytes ] */ ; + PACK @defpacked + /* [ @defpacked bytes : @Apacked bytes ] */ ; + DUP + /* [ @defpacked bytes : @defpacked bytes : @Apacked bytes ] */ ; + DIP { SWAP /* [ @Apacked bytes : @defpacked bytes ] */ } + /* [ @defpacked bytes : @Apacked bytes : @defpacked bytes ] */ ; + ASSERT_CMPNEQ ; + SELF + /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) + : @defpacked bytes ] */ ; + PACK @selfpacked + /* [ @selfpacked bytes : @defpacked bytes ] */ ; + ASSERT_CMPEQ ; + SELF %A + /* [ @self contract nat ] */ ; + CAST (contract nat) + /* [ @self contract nat ] */ ; + DROP + /* [] */ ; + SELF %B + /* [ @self contract bool ] */ ; + CAST (contract bool) + /* [ @self contract bool ] */ ; + DROP + /* [] */ ; + SELF %maybe_C + /* [ @self contract (or (unit %Z) (string %C)) ] */ ; + CAST (contract (or unit string)) + /* [ @self contract (or unit string) ] */ ; + DROP + /* [] */ ; + SELF %Z + /* [ @self contract unit ] */ ; + CAST (contract unit) + /* [ @self contract unit ] */ ; + DROP + /* [] */ ; + SELF + /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ] */ ; + CAST (contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))) + /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ] */ ; + DROP + /* [] */ ; + SELF %default + /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ] */ ; + CAST (contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C)))) + /* [ @self contract (or (or (nat %A) (bool %B)) (or %maybe_C (unit %Z) (string %C))) ] */ ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender.tz].out new file mode 100644 index 000000000000..55e1a9bc53cb --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sender.tz] + +Well typed +Gas remaining: 1039996.803 units remaining +{ parameter unit ; + storage address ; + code { DROP + /* [] */ ; + SENDER + /* [ @sender address ] */ ; + NIL operation + /* [ list operation : @sender address ] */ ; + PAIR + /* [ pair (list operation) (address @sender) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_fib_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_fib_view.tz].out new file mode 100644 index 000000000000..208c6a7be694 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_fib_view.tz].out @@ -0,0 +1,38 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sender_after_fib_view.tz] + +Well typed +Gas remaining: 1039985.607 units remaining +{ parameter address ; + storage address ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 3 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "fib" nat + /* [ @parameter.contract option nat : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 1500 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + SENDER + /* [ @sender address : operation ] */ ; + SWAP + /* [ operation : @sender address ] */ ; + NIL operation + /* [ list operation : operation : @sender address ] */ ; + SWAP + /* [ operation : list operation : @sender address ] */ ; + CONS + /* [ list operation : @sender address ] */ ; + PAIR + /* [ pair (list operation) (address @sender) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_nonexistent_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_nonexistent_view.tz].out new file mode 100644 index 000000000000..53e769b37b02 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_nonexistent_view.tz].out @@ -0,0 +1,36 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sender_after_nonexistent_view.tz] + +Well typed +Gas remaining: 1039986.090 units remaining +{ parameter address ; + storage address ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "id" string + /* [ @parameter.contract option string : @parameter address ] */ ; + ASSERT_NONE ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 1500 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + SENDER + /* [ @sender address : operation ] */ ; + SWAP + /* [ operation : @sender address ] */ ; + NIL operation + /* [ list operation : operation : @sender address ] */ ; + SWAP + /* [ operation : list operation : @sender address ] */ ; + CONS + /* [ list operation : @sender address ] */ ; + PAIR + /* [ pair (list operation) (address @sender) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_view.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_view.tz].out new file mode 100644 index 000000000000..0911445c0390 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sender_after_view.tz].out @@ -0,0 +1,39 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sender_after_view.tz] + +Well typed +Gas remaining: 1039985.432 units remaining +{ parameter address ; + storage address ; + code { CAR + /* [ @parameter address ] */ ; + DUP + /* [ @parameter address : @parameter address ] */ ; + PUSH nat 0 + /* [ nat : @parameter address : @parameter address ] */ ; + VIEW "id" + (pair nat nat) + /* [ @parameter.contract option (pair nat nat) : @parameter address ] */ ; + ASSERT_SOME ; + DROP + /* [ @parameter address ] */ ; + CONTRACT nat + /* [ @parameter.contract option (contract nat) ] */ ; + ASSERT_SOME ; + PUSH mutez 1500 + /* [ mutez : @parameter.contract.some contract nat ] */ ; + PUSH nat 0 + /* [ nat : mutez : @parameter.contract.some contract nat ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + SENDER + /* [ @sender address : operation ] */ ; + SWAP + /* [ operation : @sender address ] */ ; + NIL operation + /* [ list operation : operation : @sender address ] */ ; + SWAP + /* [ operation : list operation : @sender address ] */ ; + CONS + /* [ list operation : @sender address ] */ ; + PAIR + /* [ pair (list operation) (address @sender) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_car.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_car.tz].out new file mode 100644 index 000000000000..965817881bc2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_car.tz].out @@ -0,0 +1,19 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_car.tz] + +Well typed +Gas remaining: 1039991.314 units remaining +{ parameter string ; + storage (pair (string %s) (nat %n)) ; + code { DUP + /* [ pair (string @parameter) (pair @storage (string %s) (nat %n)) + : pair (string @parameter) (pair @storage (string %s) (nat %n)) ] */ ; + CDR + /* [ @storage pair (string %s) (nat %n) + : pair (string @parameter) (pair @storage (string %s) (nat %n)) ] */ ; + DIP { CAR /* [ @parameter string ] */ } + /* [ @storage pair (string %s) (nat %n) : @parameter string ] */ ; + SET_CAR %s ; + NIL operation + /* [ list operation : @storage pair (string %s @parameter) (nat %n @storage.n) ] */ ; + PAIR + /* [ pair (list operation) (pair @storage (string %s @parameter) (nat %n @storage.n)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_cdr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_cdr.tz].out new file mode 100644 index 000000000000..0a9af5151dde --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_cdr.tz].out @@ -0,0 +1,19 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_cdr.tz] + +Well typed +Gas remaining: 1039991.782 units remaining +{ parameter nat ; + storage (pair (string %s) (nat %n)) ; + code { DUP + /* [ pair (nat @parameter) (pair @storage (string %s) (nat %n)) + : pair (nat @parameter) (pair @storage (string %s) (nat %n)) ] */ ; + CDR + /* [ @storage pair (string %s) (nat %n) + : pair (nat @parameter) (pair @storage (string %s) (nat %n)) ] */ ; + DIP { CAR /* [ @parameter nat ] */ } + /* [ @storage pair (string %s) (nat %n) : @parameter nat ] */ ; + SET_CDR %n ; + NIL operation + /* [ list operation : @storage pair (string %s @storage.s) (nat %n @parameter) ] */ ; + PAIR + /* [ pair (list operation) (pair @storage (string %s @storage.s) (nat %n @parameter)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_delegate.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_delegate.tz].out new file mode 100644 index 000000000000..abcb3bda4652 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_delegate.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_delegate.tz] + +Well typed +Gas remaining: 1039995.476 units remaining +{ parameter (option key_hash) ; + storage unit ; + code { UNPAIR + /* [ @parameter option key_hash : @storage unit ] */ ; + SET_DELEGATE + /* [ operation : @storage unit ] */ ; + DIP { NIL operation /* [ list operation : @storage unit ] */ } + /* [ operation : list operation : @storage unit ] */ ; + CONS + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_id.tz].out new file mode 100644 index 000000000000..b640e740523c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_id.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_id.tz] + +Well typed +Gas remaining: 1039996.880 units remaining +{ parameter (set string) ; + storage (set string) ; + code { CAR + /* [ @parameter set string ] */ ; + NIL operation + /* [ list operation : @parameter set string ] */ ; + PAIR + /* [ pair (list operation) (set @parameter string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_iter.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_iter.tz].out new file mode 100644 index 000000000000..dc215f4d2401 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_iter.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_iter.tz] + +Well typed +Gas remaining: 1039994.793 units remaining +{ parameter (set int) ; + storage int ; + code { CAR + /* [ @parameter set int ] */ ; + PUSH int 0 + /* [ int : @parameter set int ] */ ; + SWAP + /* [ @parameter set int : int ] */ ; + ITER { ADD /* [ int ] */ } + /* [ int ] */ ; + NIL operation + /* [ list operation : int ] */ ; + PAIR + /* [ pair (list operation) int ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_member.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_member.tz].out new file mode 100644 index 000000000000..3c08a1664bad --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_member.tz].out @@ -0,0 +1,36 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_member.tz] + +Well typed +Gas remaining: 1039988.400 units remaining +{ parameter string ; + storage (pair (set string) (option bool)) ; + code { DUP + /* [ pair (string @parameter) (pair @storage (set string) (option bool)) + : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; + DUP + /* [ pair (string @parameter) (pair @storage (set string) (option bool)) + : pair (string @parameter) (pair @storage (set string) (option bool)) + : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; + CAR + /* [ @parameter string + : pair (string @parameter) (pair @storage (set string) (option bool)) + : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; + DIP { CDAR } + /* [ @parameter string : set string + : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; + MEM + /* [ bool + : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; + SOME + /* [ option bool + : pair (string @parameter) (pair @storage (set string) (option bool)) ] */ ; + DIP { CDAR } + /* [ option bool : set string ] */ ; + SWAP + /* [ set string : option bool ] */ ; + PAIR + /* [ pair (set string) (option bool) ] */ ; + NIL operation + /* [ list operation : pair (set string) (option bool) ] */ ; + PAIR + /* [ pair (list operation) (set string) (option bool) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_size.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_size.tz].out new file mode 100644 index 000000000000..1bfdb40fee41 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--set_size.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/set_size.tz] + +Well typed +Gas remaining: 1039996.720 units remaining +{ parameter (set int) ; + storage nat ; + code { CAR + /* [ @parameter set int ] */ ; + SIZE + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sets.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sets.tz].out new file mode 100644 index 000000000000..98e24100ac5f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sets.tz].out @@ -0,0 +1,68 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sets.tz] + +Well typed +Gas remaining: 1038009.188 units remaining +{ parameter unit ; + storage unit ; + code { DROP + /* [] */ ; + PUSH (set nat) { 0 ; 1 ; 3 } + /* [ set nat ] */ ; + DROP + /* [] */ ; + PUSH (set int) { -1 ; 0 ; 3 } + /* [ set int ] */ ; + DROP + /* [] */ ; + PUSH (set mutez) { 1 ; 4 ; 5 ; 10 ; 1923 } + /* [ set mutez ] */ ; + DROP + /* [] */ ; + PUSH (set timestamp) + { -1 ; 0 ; "2017-09-16T08:38:04Z" ; "2019-09-16T08:38:05Z" } + /* [ set timestamp ] */ ; + DROP + /* [] */ ; + PUSH (set bool) {} + /* [ set bool ] */ ; + DROP + /* [] */ ; + PUSH (set bool) { True } + /* [ set bool ] */ ; + DROP + /* [] */ ; + PUSH (set bool) { False } + /* [ set bool ] */ ; + DROP + /* [] */ ; + PUSH (set bool) { False ; True } + /* [ set bool ] */ ; + DROP + /* [] */ ; + PUSH (set string) { "" ; "A" ; "B" ; "a" ; "aa" ; "b" } + /* [ set string ] */ ; + DROP + /* [] */ ; + PUSH (set bytes) { 0x ; 0x01 ; 0x02 ; 0xaabbcc } + /* [ set bytes ] */ ; + DROP + /* [] */ ; + PUSH (set key_hash) + { "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ; + "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" } + /* [ set key_hash ] */ ; + DROP + /* [] */ ; + PUSH (set address) + { "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ; + "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" ; + "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9" } + /* [ set address ] */ ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sha3.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sha3.tz].out new file mode 100644 index 000000000000..ab45db0b9640 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sha3.tz].out @@ -0,0 +1,16 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sha3.tz] + +Well typed +Gas remaining: 1039996.037 units remaining +{ storage (option bytes) ; + parameter bytes ; + code { CAR + /* [ @parameter bytes ] */ ; + SHA3 + /* [ bytes ] */ ; + SOME + /* [ option bytes ] */ ; + NIL operation + /* [ list operation : option bytes ] */ ; + PAIR + /* [ pair (list operation) (option bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--shifts.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--shifts.tz].out new file mode 100644 index 000000000000..64558ac80847 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--shifts.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/shifts.tz] + +Well typed +Gas remaining: 1039993.299 units remaining +{ parameter (or (pair nat nat) (pair nat nat)) ; + storage (option nat) ; + code { CAR + /* [ @parameter or (pair nat nat) (pair nat nat) ] */ ; + IF_LEFT + { UNPAIR /* [ nat : nat ] */ ; LSL /* [ nat ] */ } + { UNPAIR /* [ nat : nat ] */ ; LSR /* [ nat ] */ } ; + SOME + /* [ option nat ] */ ; + NIL operation + /* [ list operation : option nat ] */ ; + PAIR + /* [ pair (list operation) (option nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice.tz].out new file mode 100644 index 000000000000..61c2ac15bf94 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/slice.tz] + +Well typed +Gas remaining: 1039992.627 units remaining +{ parameter (pair nat nat) ; + storage (option string) ; + code { UNPAIR + /* [ @parameter pair nat nat : @storage option string ] */ ; + SWAP + /* [ @storage option string : @parameter pair nat nat ] */ ; + IF_SOME + { SWAP + /* [ @parameter pair nat nat : @storage.some string ] */ ; + UNPAIR + /* [ nat : nat : @storage.some string ] */ ; + SLICE + /* [ @storage.some.slice option string ] */ } + { DROP /* [] */ ; NONE string /* [ option string ] */ } ; + NIL operation + /* [ list operation : option string ] */ ; + PAIR + /* [ pair (list operation) (option string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice_bytes.tz].out new file mode 100644 index 000000000000..2fc811f5c1ae --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slice_bytes.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/slice_bytes.tz] + +Well typed +Gas remaining: 1039992.627 units remaining +{ parameter (pair nat nat) ; + storage (option bytes) ; + code { UNPAIR + /* [ @parameter pair nat nat : @storage option bytes ] */ ; + SWAP + /* [ @storage option bytes : @parameter pair nat nat ] */ ; + IF_SOME + { SWAP + /* [ @parameter pair nat nat : @storage.some bytes ] */ ; + UNPAIR + /* [ nat : nat : @storage.some bytes ] */ ; + SLICE + /* [ @storage.some.slice option bytes ] */ } + { DROP /* [] */ ; NONE bytes /* [ option bytes ] */ } ; + NIL operation + /* [ list operation : option bytes ] */ ; + PAIR + /* [ pair (list operation) (option bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slices.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slices.tz].out new file mode 100644 index 000000000000..ef74797ca296 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--slices.tz].out @@ -0,0 +1,156 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/slices.tz] + +Well typed +Gas remaining: 1039935.257 units remaining +{ parameter (pair bytes signature) ; + storage key ; + code { DUP + /* [ pair (pair @parameter bytes signature) (key @storage) + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + CAAR ; + DUP + /* [ bytes : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SIZE + /* [ nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + PUSH nat + 128 + /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SWAP + /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SUB + /* [ int : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + ISNAT + /* [ option nat : bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + IF_SOME + { /* [ @some nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ } + { FAIL } ; + PUSH nat + 128 + /* [ nat : @some nat : bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SLICE @payload + /* [ @payload option bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + ASSERT_SOME ; + DUP + /* [ @payload.some bytes : @payload.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + DIP { DIP { DUP + /* [ pair (pair @parameter bytes signature) (key @storage) + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + CAAR ; + PUSH nat + 32 + /* [ nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + PUSH nat + 0 + /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SLICE + /* [ @slice option bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + ASSERT_SOME } + /* [ @payload.some bytes : @slice.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SHA256 + /* [ bytes : @slice.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + ASSERT_CMPEQ } + /* [ @payload.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + DUP + /* [ @payload.some bytes : @payload.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + DIP { DIP { DUP + /* [ pair (pair @parameter bytes signature) (key @storage) + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + CAAR ; + PUSH nat + 32 + /* [ nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + PUSH nat + 32 + /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SLICE + /* [ @slice option bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + ASSERT_SOME } + /* [ @payload.some bytes : @slice.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + BLAKE2B + /* [ bytes : @slice.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + ASSERT_CMPEQ } + /* [ @payload.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + DUP + /* [ @payload.some bytes : @payload.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + DIP { DIP { DUP + /* [ pair (pair @parameter bytes signature) (key @storage) + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + CAAR ; + PUSH nat + 64 + /* [ nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + PUSH nat + 64 + /* [ nat : nat : bytes : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SLICE + /* [ @slice option bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + ASSERT_SOME } + /* [ @payload.some bytes : @slice.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SHA512 + /* [ bytes : @slice.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + ASSERT_CMPEQ } + /* [ @payload.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + DIP { DUP + /* [ pair (pair @parameter bytes signature) (key @storage) + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + CDR + /* [ @storage key : pair (pair @parameter bytes signature) (key @storage) ] */ ; + DIP { DUP + /* [ pair (pair @parameter bytes signature) (key @storage) + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + CADR } + /* [ @storage key : signature + : pair (pair @parameter bytes signature) (key @storage) ] */ } + /* [ @payload.some bytes : @storage key : signature + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + SWAP + /* [ @storage key : @payload.some bytes : signature + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + DIP { SWAP + /* [ signature : @payload.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ } + /* [ @storage key : signature : @payload.some bytes + : pair (pair @parameter bytes signature) (key @storage) ] */ ; + CHECK_SIGNATURE + /* [ bool : pair (pair @parameter bytes signature) (key @storage) ] */ ; + ASSERT ; + CDR + /* [ @storage key ] */ ; + DUP + /* [ @storage key : @storage key ] */ ; + HASH_KEY + /* [ key_hash : @storage key ] */ ; + IMPLICIT_ACCOUNT + /* [ contract unit : @storage key ] */ ; + BALANCE + /* [ @balance mutez : contract unit : @storage key ] */ ; + UNIT + /* [ unit : @balance mutez : contract unit : @storage key ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage key ] */ ; + NIL operation + /* [ list operation : operation : @storage key ] */ ; + SWAP + /* [ operation : list operation : @storage key ] */ ; + CONS + /* [ list operation : @storage key ] */ ; + PAIR + /* [ pair (list operation) (key @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--source.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--source.tz].out new file mode 100644 index 000000000000..f27b61fb6234 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--source.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/source.tz] + +Well typed +Gas remaining: 1039996.803 units remaining +{ parameter unit ; + storage address ; + code { DROP + /* [] */ ; + SOURCE + /* [ @source address ] */ ; + NIL operation + /* [ list operation : @source address ] */ ; + PAIR + /* [ pair (list operation) (address @source) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_bytes.tz].out new file mode 100644 index 000000000000..ee3a53431a1a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_bytes.tz].out @@ -0,0 +1,72 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/split_bytes.tz] + +Well typed +Gas remaining: 1039970.057 units remaining +{ parameter bytes ; + storage (list bytes) ; + code { UNPAIR + /* [ @parameter bytes : @storage list bytes ] */ ; + DIP { NIL bytes + /* [ list bytes : @storage list bytes ] */ ; + SWAP + /* [ @storage list bytes : list bytes ] */ ; + ITER { CONS /* [ list bytes ] */ } + /* [ list bytes ] */ } + /* [ @parameter bytes : list bytes ] */ ; + DUP + /* [ @parameter bytes : @parameter bytes : list bytes ] */ ; + SIZE + /* [ nat : @parameter bytes : list bytes ] */ ; + PUSH nat 0 + /* [ nat : nat : @parameter bytes : list bytes ] */ ; + CMPNEQ ; + DIP { PUSH @index nat 0 /* [ @index nat : @parameter bytes : list bytes ] */ } + /* [ bool : @index nat : @parameter bytes : list bytes ] */ ; + LOOP { PAIR + /* [ pair (nat @index) (bytes @parameter) : list bytes ] */ ; + DUP + /* [ pair (nat @index) (bytes @parameter) : pair (nat @index) (bytes @parameter) + : list bytes ] */ ; + DIP { UNPAIR + /* [ @index nat : @parameter bytes : list bytes ] */ ; + DIP { PUSH nat 1 /* [ nat : @parameter bytes : list bytes ] */ } + /* [ @index nat : nat : @parameter bytes : list bytes ] */ ; + SLICE + /* [ @parameter.slice option bytes : list bytes ] */ ; + ASSERT_SOME ; + CONS @storage + /* [ @storage list bytes ] */ } + /* [ pair (nat @index) (bytes @parameter) : @storage list bytes ] */ ; + UNPAIR + /* [ @index nat : @parameter bytes : @storage list bytes ] */ ; + PUSH nat 1 + /* [ nat : @index nat : @parameter bytes : @storage list bytes ] */ ; + ADD @index + /* [ @index nat : @parameter bytes : @storage list bytes ] */ ; + DUP + /* [ @index nat : @index nat : @parameter bytes : @storage list bytes ] */ ; + DIP { DIP { DUP /* [ @parameter bytes : @parameter bytes : @storage list bytes ] */ } + /* [ @index nat : @parameter bytes : @parameter bytes : @storage list bytes ] */ ; + SWAP + /* [ @parameter bytes : @index nat : @parameter bytes : @storage list bytes ] */ ; + SIZE + /* [ nat : @index nat : @parameter bytes : @storage list bytes ] */ ; + CMPNEQ } + /* [ @index nat : bool : @parameter bytes : @storage list bytes ] */ ; + SWAP + /* [ bool : @index nat : @parameter bytes : @storage list bytes ] */ } + /* [ @index nat : @parameter bytes : list bytes ] */ ; + DROP + /* [ @parameter bytes : list bytes ] */ ; + DROP + /* [ list bytes ] */ ; + NIL bytes + /* [ list bytes : list bytes ] */ ; + SWAP + /* [ list bytes : list bytes ] */ ; + ITER { CONS /* [ list bytes ] */ } + /* [ list bytes ] */ ; + NIL operation + /* [ list operation : list bytes ] */ ; + PAIR + /* [ pair (list operation) (list bytes) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_string.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_string.tz].out new file mode 100644 index 000000000000..e0b7d1f3228c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--split_string.tz].out @@ -0,0 +1,72 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/split_string.tz] + +Well typed +Gas remaining: 1039970.057 units remaining +{ parameter string ; + storage (list string) ; + code { UNPAIR + /* [ @parameter string : @storage list string ] */ ; + DIP { NIL string + /* [ list string : @storage list string ] */ ; + SWAP + /* [ @storage list string : list string ] */ ; + ITER { CONS /* [ list string ] */ } + /* [ list string ] */ } + /* [ @parameter string : list string ] */ ; + DUP + /* [ @parameter string : @parameter string : list string ] */ ; + SIZE + /* [ nat : @parameter string : list string ] */ ; + PUSH nat 0 + /* [ nat : nat : @parameter string : list string ] */ ; + CMPNEQ ; + DIP { PUSH @index nat 0 /* [ @index nat : @parameter string : list string ] */ } + /* [ bool : @index nat : @parameter string : list string ] */ ; + LOOP { PAIR + /* [ pair (nat @index) (string @parameter) : list string ] */ ; + DUP + /* [ pair (nat @index) (string @parameter) + : pair (nat @index) (string @parameter) : list string ] */ ; + DIP { UNPAIR + /* [ @index nat : @parameter string : list string ] */ ; + DIP { PUSH nat 1 /* [ nat : @parameter string : list string ] */ } + /* [ @index nat : nat : @parameter string : list string ] */ ; + SLICE + /* [ @parameter.slice option string : list string ] */ ; + ASSERT_SOME ; + CONS @storage + /* [ @storage list string ] */ } + /* [ pair (nat @index) (string @parameter) : @storage list string ] */ ; + UNPAIR + /* [ @index nat : @parameter string : @storage list string ] */ ; + PUSH nat 1 + /* [ nat : @index nat : @parameter string : @storage list string ] */ ; + ADD @index + /* [ @index nat : @parameter string : @storage list string ] */ ; + DUP + /* [ @index nat : @index nat : @parameter string : @storage list string ] */ ; + DIP { DIP { DUP /* [ @parameter string : @parameter string : @storage list string ] */ } + /* [ @index nat : @parameter string : @parameter string : @storage list string ] */ ; + SWAP + /* [ @parameter string : @index nat : @parameter string : @storage list string ] */ ; + SIZE + /* [ nat : @index nat : @parameter string : @storage list string ] */ ; + CMPNEQ } + /* [ @index nat : bool : @parameter string : @storage list string ] */ ; + SWAP + /* [ bool : @index nat : @parameter string : @storage list string ] */ } + /* [ @index nat : @parameter string : list string ] */ ; + DROP + /* [ @parameter string : list string ] */ ; + DROP + /* [ list string ] */ ; + NIL string + /* [ list string : list string ] */ ; + SWAP + /* [ list string : list string ] */ ; + ITER { CONS /* [ list string ] */ } + /* [ list string ] */ ; + NIL operation + /* [ list operation : list string ] */ ; + PAIR + /* [ pair (list operation) (list string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_fr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_fr.tz].out new file mode 100644 index 000000000000..d7679c4c9d16 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_fr.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_bls12_381_fr.tz] + +Well typed +Gas remaining: 1039996.500 units remaining +{ parameter bls12_381_fr ; + storage (option bls12_381_fr) ; + code { CAR + /* [ @parameter bls12_381_fr ] */ ; + SOME + /* [ option bls12_381_fr ] */ ; + NIL operation + /* [ list operation : option bls12_381_fr ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_fr) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g1.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g1.tz].out new file mode 100644 index 000000000000..84ece93e6a5e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g1.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_bls12_381_g1.tz] + +Well typed +Gas remaining: 1039996.500 units remaining +{ parameter bls12_381_g1 ; + storage (option bls12_381_g1) ; + code { CAR + /* [ @parameter bls12_381_g1 ] */ ; + SOME + /* [ option bls12_381_g1 ] */ ; + NIL operation + /* [ list operation : option bls12_381_g1 ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_g1) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g2.tz].out new file mode 100644 index 000000000000..06839924d096 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_bls12_381_g2.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_bls12_381_g2.tz] + +Well typed +Gas remaining: 1039996.500 units remaining +{ parameter bls12_381_g2 ; + storage (option bls12_381_g2) ; + code { CAR + /* [ @parameter bls12_381_g2 ] */ ; + SOME + /* [ option bls12_381_g2 ] */ ; + NIL operation + /* [ list operation : option bls12_381_g2 ] */ ; + PAIR + /* [ pair (list operation) (option bls12_381_g2) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_input.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_input.tz].out new file mode 100644 index 000000000000..d4f2e3c1124b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_input.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_input.tz] + +Well typed +Gas remaining: 1039997.267 units remaining +{ parameter string ; + storage string ; + code { CAR + /* [ @parameter string ] */ ; + NIL operation + /* [ list operation : @parameter string ] */ ; + PAIR + /* [ pair (list operation) (string @parameter) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_now.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_now.tz].out new file mode 100644 index 000000000000..ecbb62125bbd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--store_now.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/store_now.tz] + +Well typed +Gas remaining: 1039996.803 units remaining +{ parameter unit ; + storage timestamp ; + code { DROP + /* [] */ ; + NOW + /* [ @now timestamp ] */ ; + NIL operation + /* [ list operation : @now timestamp ] */ ; + PAIR + /* [ pair (list operation) (timestamp @now) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--str_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--str_id.tz].out new file mode 100644 index 000000000000..0866a7471c97 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--str_id.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/str_id.tz] + +Well typed +Gas remaining: 1039996.500 units remaining +{ parameter string ; + storage (option string) ; + code { CAR + /* [ @parameter string ] */ ; + SOME + /* [ option string ] */ ; + NIL operation + /* [ list operation : option string ] */ ; + PAIR + /* [ pair (list operation) (option string) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sub_timestamp_delta.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sub_timestamp_delta.tz].out new file mode 100644 index 000000000000..20a61ffddea1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--sub_timestamp_delta.tz].out @@ -0,0 +1,20 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/sub_timestamp_delta.tz] + +Well typed +Gas remaining: 1039994.373 units remaining +{ parameter (pair timestamp int) ; + storage timestamp ; + code { CAR + /* [ @parameter pair timestamp int ] */ ; + DUP + /* [ @parameter pair timestamp int : @parameter pair timestamp int ] */ ; + CAR + /* [ timestamp : @parameter pair timestamp int ] */ ; + DIP { CDR /* [ int ] */ } + /* [ timestamp : int ] */ ; + SUB + /* [ timestamp ] */ ; + NIL operation + /* [ list operation : timestamp ] */ ; + PAIR + /* [ pair (list operation) timestamp ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--subset.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--subset.tz].out new file mode 100644 index 000000000000..7d58ca1fb0c3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--subset.tz].out @@ -0,0 +1,46 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/subset.tz] + +Well typed +Gas remaining: 1039984.961 units remaining +{ parameter (pair (set string) (set string)) ; + storage bool ; + code { CAR + /* [ @parameter pair (set string) (set string) ] */ ; + DUP + /* [ @parameter pair (set string) (set string) + : @parameter pair (set string) (set string) ] */ ; + CDR + /* [ set string : @parameter pair (set string) (set string) ] */ ; + DIP { CAR /* [ set string ] */ } + /* [ set string : set string ] */ ; + PUSH bool True + /* [ bool : set string : set string ] */ ; + PAIR + /* [ pair bool (set string) : set string ] */ ; + SWAP + /* [ set string : pair bool (set string) ] */ ; + ITER { DIP { DUP + /* [ pair bool (set string) : pair bool (set string) ] */ ; + DUP + /* [ pair bool (set string) : pair bool (set string) : pair bool (set string) ] */ ; + CDR + /* [ set string : pair bool (set string) : pair bool (set string) ] */ ; + DIP { CAR + /* [ bool : pair bool (set string) ] */ ; + DIP { CDR /* [ set string ] */ } + /* [ bool : set string ] */ } + /* [ set string : bool : set string ] */ } + /* [ @elt string : set string : bool : set string ] */ ; + MEM + /* [ bool : bool : set string ] */ ; + AND + /* [ bool : set string ] */ ; + PAIR + /* [ pair bool (set string) ] */ } + /* [ pair bool (set string) ] */ ; + CAR + /* [ bool ] */ ; + NIL operation + /* [ list operation : bool ] */ ; + PAIR + /* [ pair (list operation) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--tez_add_sub.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--tez_add_sub.tz].out new file mode 100644 index 000000000000..0abc83666944 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--tez_add_sub.tz].out @@ -0,0 +1,37 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/tez_add_sub.tz] + +Well typed +Gas remaining: 1039986.225 units remaining +{ parameter (pair mutez mutez) ; + storage (option (pair mutez mutez)) ; + code { CAR + /* [ @parameter pair mutez mutez ] */ ; + DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; + DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez + : @parameter pair mutez mutez ] */ ; + CAR + /* [ mutez : @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; + DIP { CDR /* [ mutez : @parameter pair mutez mutez ] */ } + /* [ mutez : mutez : @parameter pair mutez mutez ] */ ; + ADD + /* [ mutez : @parameter pair mutez mutez ] */ ; + DIP { DUP + /* [ @parameter pair mutez mutez : @parameter pair mutez mutez ] */ ; + CAR + /* [ mutez : @parameter pair mutez mutez ] */ ; + DIP { CDR /* [ mutez ] */ } + /* [ mutez : mutez ] */ ; + SUB_MUTEZ + /* [ option mutez ] */ ; + ASSERT_SOME } + /* [ mutez : @some mutez ] */ ; + PAIR + /* [ pair mutez (mutez @some) ] */ ; + SOME + /* [ option (pair mutez (mutez @some)) ] */ ; + NIL operation + /* [ list operation : option (pair mutez (mutez @some)) ] */ ; + PAIR + /* [ pair (list operation) (option (pair mutez (mutez @some))) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_bad.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_bad.tz].out new file mode 100644 index 000000000000..7de15dc21377 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_bad.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_bad.tz] + +Well typed +Gas remaining: 1039996.963 units remaining +{ parameter unit ; + storage (ticket nat) ; + code { CDR + /* [ @storage ticket nat ] */ ; + NIL operation + /* [ list operation : @storage ticket nat ] */ ; + PAIR + /* [ pair (list operation) (ticket @storage nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_big_store.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_big_store.tz].out new file mode 100644 index 000000000000..339fb92cb81b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_big_store.tz].out @@ -0,0 +1,24 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_big_store.tz] + +Well typed +Gas remaining: 1039992.430 units remaining +{ parameter nat ; + storage (big_map unit (ticket nat)) ; + code { UNPAIR + /* [ @parameter nat : @storage big_map unit (ticket nat) ] */ ; + PUSH nat 1 + /* [ nat : @parameter nat : @storage big_map unit (ticket nat) ] */ ; + SWAP + /* [ @parameter nat : nat : @storage big_map unit (ticket nat) ] */ ; + TICKET + /* [ ticket nat : @storage big_map unit (ticket nat) ] */ ; + SOME + /* [ option (ticket nat) : @storage big_map unit (ticket nat) ] */ ; + UNIT + /* [ unit : option (ticket nat) : @storage big_map unit (ticket nat) ] */ ; + UPDATE + /* [ @storage big_map unit (ticket nat) ] */ ; + NIL operation + /* [ list operation : @storage big_map unit (ticket nat) ] */ ; + PAIR + /* [ pair (list operation) (big_map @storage unit (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_join.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_join.tz].out new file mode 100644 index 000000000000..2de77ed165c4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_join.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_join.tz] + +Well typed +Gas remaining: 1039990.843 units remaining +{ parameter (ticket nat) ; + storage (option (ticket nat)) ; + code { UNPAIR + /* [ @parameter ticket nat : @storage option (ticket nat) ] */ ; + SWAP + /* [ @storage option (ticket nat) : @parameter ticket nat ] */ ; + IF_NONE + { /* [ @parameter ticket nat ] */ } + { PAIR + /* [ pair (ticket @storage.some nat) (ticket @parameter nat) ] */ ; + JOIN_TICKETS + /* [ option (ticket nat) ] */ ; + ASSERT_SOME } ; + SOME + /* [ option (ticket nat) ] */ ; + NIL operation + /* [ list operation : option (ticket nat) ] */ ; + PAIR + /* [ pair (list operation) (option (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_read.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_read.tz].out new file mode 100644 index 000000000000..4a9a121ae027 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_read.tz].out @@ -0,0 +1,24 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_read.tz] + +Well typed +Gas remaining: 1039984.150 units remaining +{ parameter (ticket nat) ; + storage address ; + code { CAR + /* [ @parameter ticket nat ] */ ; + READ_TICKET + /* [ pair address nat nat : @parameter ticket nat ] */ ; + DIP { DROP /* [] */ } + /* [ pair address nat nat ] */ ; + UNPAIR + /* [ address : pair nat nat ] */ ; + DIP { UNPAIR /* [ nat : nat ] */ } + /* [ address : nat : nat ] */ ; + DIIP { PUSH nat 1 /* [ nat : nat ] */ ; ASSERT_CMPEQ } + /* [ address : nat ] */ ; + DIP { PUSH nat 42 /* [ nat : nat ] */ ; ASSERT_CMPEQ } + /* [ address ] */ ; + NIL operation + /* [ list operation : address ] */ ; + PAIR + /* [ pair (list operation) address ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_split.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_split.tz].out new file mode 100644 index 000000000000..d1aeff5d8e20 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_split.tz].out @@ -0,0 +1,39 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_split.tz] + +Well typed +Gas remaining: 1039978.358 units remaining +{ parameter (ticket nat) ; + storage unit ; + code { CAR + /* [ @parameter ticket nat ] */ ; + PUSH (pair nat nat) (Pair 1 2) + /* [ pair nat nat : @parameter ticket nat ] */ ; + SWAP + /* [ @parameter ticket nat : pair nat nat ] */ ; + SPLIT_TICKET + /* [ option (pair (ticket nat) (ticket nat)) ] */ ; + ASSERT_SOME ; + UNPAIR + /* [ ticket nat : ticket nat ] */ ; + READ_TICKET + /* [ pair address nat nat : ticket nat : ticket nat ] */ ; + CDDR ; + PUSH nat 1 + /* [ nat : nat : ticket nat : ticket nat ] */ ; + ASSERT_CMPEQ ; + DROP + /* [ ticket nat ] */ ; + READ_TICKET + /* [ pair address nat nat : ticket nat ] */ ; + CDDR ; + PUSH nat 2 + /* [ nat : nat : ticket nat ] */ ; + ASSERT_CMPEQ ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store-2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store-2.tz].out new file mode 100644 index 000000000000..03125c41dce4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store-2.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_store-2.tz] + +Well typed +Gas remaining: 1039996.494 units remaining +{ parameter (option (ticket nat)) ; + storage (option (ticket nat)) ; + code { CAR + /* [ @parameter option (ticket nat) ] */ ; + NIL operation + /* [ list operation : @parameter option (ticket nat) ] */ ; + PAIR + /* [ pair (list operation) (option @parameter (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store.tz].out new file mode 100644 index 000000000000..921d7157b436 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticket_store.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticket_store.tz] + +Well typed +Gas remaining: 1039996.114 units remaining +{ parameter (ticket nat) ; + storage (option (ticket nat)) ; + code { CAR + /* [ @parameter ticket nat ] */ ; + SOME + /* [ option (ticket nat) ] */ ; + NIL operation + /* [ list operation : option (ticket nat) ] */ ; + PAIR + /* [ pair (list operation) (option (ticket nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer-2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer-2.tz].out new file mode 100644 index 000000000000..8d4c412361d8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer-2.tz].out @@ -0,0 +1,35 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticketer-2.tz] + +Well typed +Gas remaining: 1039987.194 units remaining +{ parameter (pair (pair address nat) nat) ; + storage unit ; + code { CAR + /* [ @parameter pair (pair address nat) nat ] */ ; + UNPAIR + /* [ pair address nat : nat ] */ ; + UNPAIR + /* [ address : nat : nat ] */ ; + CONTRACT (ticket nat) + /* [ @contract option (contract (ticket nat)) : nat : nat ] */ ; + ASSERT_SOME ; + DIP { TICKET /* [ ticket nat ] */ } + /* [ @contract.some contract (ticket nat) : ticket nat ] */ ; + SWAP + /* [ ticket nat : @contract.some contract (ticket nat) ] */ ; + DIP { PUSH mutez 0 /* [ mutez : @contract.some contract (ticket nat) ] */ } + /* [ ticket nat : mutez : @contract.some contract (ticket nat) ] */ ; + TRANSFER_TOKENS + /* [ operation ] */ ; + NIL operation + /* [ list operation : operation ] */ ; + SWAP + /* [ operation : list operation ] */ ; + CONS + /* [ list operation ] */ ; + UNIT + /* [ unit : list operation ] */ ; + SWAP + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer.tz].out new file mode 100644 index 000000000000..4a7124409f1a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--ticketer.tz].out @@ -0,0 +1,37 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/ticketer.tz] + +Well typed +Gas remaining: 1039987.710 units remaining +{ parameter address ; + storage nat ; + code { UNPAIR + /* [ @parameter address : @storage nat ] */ ; + DIP { DUP /* [ @storage nat : @storage nat ] */ } + /* [ @parameter address : @storage nat : @storage nat ] */ ; + SWAP + /* [ @storage nat : @parameter address : @storage nat ] */ ; + PUSH nat 1 + /* [ nat : @storage nat : @parameter address : @storage nat ] */ ; + SWAP + /* [ @storage nat : nat : @parameter address : @storage nat ] */ ; + TICKET + /* [ ticket nat : @parameter address : @storage nat ] */ ; + DIP { CONTRACT + (ticket nat) + /* [ @parameter.contract option (contract (ticket nat)) : @storage nat ] */ ; + ASSERT_SOME ; + PUSH mutez + 0 + /* [ mutez : @parameter.contract.some contract (ticket nat) : @storage nat ] */ } + /* [ ticket nat : mutez : @parameter.contract.some contract (ticket nat) + : @storage nat ] */ ; + TRANSFER_TOKENS + /* [ operation : @storage nat ] */ ; + NIL operation + /* [ list operation : operation : @storage nat ] */ ; + SWAP + /* [ operation : list operation : @storage nat ] */ ; + CONS + /* [ list operation : @storage nat ] */ ; + PAIR + /* [ pair (list operation) (nat @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_amount.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_amount.tz].out new file mode 100644 index 000000000000..7998161ca7ff --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_amount.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/transfer_amount.tz] + +Well typed +Gas remaining: 1039996.803 units remaining +{ parameter unit ; + storage mutez ; + code { DROP + /* [] */ ; + AMOUNT + /* [ @amount mutez ] */ ; + NIL operation + /* [ list operation : @amount mutez ] */ ; + PAIR + /* [ pair (list operation) (mutez @amount) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_tokens.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_tokens.tz].out new file mode 100644 index 000000000000..24f838cd9839 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--transfer_tokens.tz].out @@ -0,0 +1,24 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/transfer_tokens.tz] + +Well typed +Gas remaining: 1039993.170 units remaining +{ parameter (contract unit) ; + storage unit ; + code { CAR + /* [ @parameter contract unit ] */ ; + DIP { UNIT /* [ unit ] */ } + /* [ @parameter contract unit : unit ] */ ; + PUSH mutez 100000000 + /* [ mutez : @parameter contract unit : unit ] */ ; + UNIT + /* [ unit : mutez : @parameter contract unit : unit ] */ ; + TRANSFER_TOKENS + /* [ operation : unit ] */ ; + NIL operation + /* [ list operation : operation : unit ] */ ; + SWAP + /* [ operation : list operation : unit ] */ ; + CONS + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--uncomb.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--uncomb.tz].out new file mode 100644 index 000000000000..3f49cedeb157 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--uncomb.tz].out @@ -0,0 +1,28 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/uncomb.tz] + +Well typed +Gas remaining: 1039992.541 units remaining +{ parameter (pair nat nat nat) ; + storage nat ; + code { CAR + /* [ @parameter pair nat nat nat ] */ ; + UNPAIR 3 + /* [ nat : nat : nat ] */ ; + PUSH nat 100 + /* [ nat : nat : nat : nat ] */ ; + MUL + /* [ nat : nat : nat ] */ ; + SWAP + /* [ nat : nat : nat ] */ ; + PUSH nat 10 + /* [ nat : nat : nat : nat ] */ ; + MUL + /* [ nat : nat : nat ] */ ; + ADD + /* [ nat : nat ] */ ; + ADD + /* [ nat ] */ ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--unpair.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--unpair.tz].out new file mode 100644 index 000000000000..7af2cc9d0a14 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--unpair.tz].out @@ -0,0 +1,322 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/unpair.tz] + +Well typed +Gas remaining: 1039903.879 units remaining +{ parameter (unit :param_unit) ; + storage (unit :u1) ; + code { DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + UNIT + /* [ unit : unit ] */ ; + PAIR + /* [ pair unit unit ] */ ; + UNPAIR + /* [ unit : unit ] */ ; + DROP 2 + /* [] */ ; + UNIT @b + /* [ @b unit ] */ ; + UNIT @a + /* [ @a unit : @b unit ] */ ; + PAIR + /* [ pair (unit @a) (unit @b) ] */ ; + UNPAIR @c @d + /* [ @c unit : @d unit ] */ ; + DROP 2 + /* [] */ ; + UNIT @b + /* [ @b unit ] */ ; + UNIT @a + /* [ @a unit : @b unit ] */ ; + PAIR %@ %@ + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR %a %b + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR % %b + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR %a % + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR % % + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR %a + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR % + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR %a %b @a @b + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR @a @b %a %b + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR @a @% %a %b + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR @% @% %a %b + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DUP + /* [ pair (unit %a @a) (unit %b @b) : pair (unit %a @a) (unit %b @b) ] */ ; + UNPAIR @% @b %a %b + /* [ @a unit : @b unit : pair (unit %a @a) (unit %b @b) ] */ ; + DROP 2 + /* [ pair (unit %a @a) (unit %b @b) ] */ ; + DROP + /* [] */ ; + UNIT @d + /* [ @d unit ] */ ; + UNIT @c + /* [ @c unit : @d unit ] */ ; + PAIR %a %b + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR %a %b + /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR % %b + /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR %a % + /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR % % + /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR %a + /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR % + /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR + /* [ @c unit : @d unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR %a %b @a @b + /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR @a @b %a %b + /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR @a @% %a %b + /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR @% @% %a %b + /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DUP + /* [ pair (unit %a @c) (unit %b @d) : pair (unit %a @c) (unit %b @d) ] */ ; + UNPAIR @% @b %a %b + /* [ @a unit : @b unit : pair (unit %a @c) (unit %b @d) ] */ ; + DROP 2 + /* [ pair (unit %a @c) (unit %b @d) ] */ ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + UNIT + /* [ unit : unit ] */ ; + PAIR %a %b + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR %a %b + /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR % %b + /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR %a % + /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR % % + /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR %a + /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR % + /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR + /* [ unit : unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR %a %b @a @b + /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR @a @b %a %b + /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR @a @% %a %b + /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR @% @% %a %b + /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DUP + /* [ pair (unit %a) (unit %b) : pair (unit %a) (unit %b) ] */ ; + UNPAIR @% @b %a %b + /* [ @a unit : @b unit : pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ pair (unit %a) (unit %b) ] */ ; + DROP + /* [] */ ; + UNIT + /* [ unit ] */ ; + UNIT + /* [ unit : unit ] */ ; + PAIR %a %b @p + /* [ @p pair (unit %a) (unit %b) ] */ ; + DUP + /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; + UNPAIR @%% @b + /* [ @p.a unit : @b unit : @p pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ @p pair (unit %a) (unit %b) ] */ ; + DUP + /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; + UNPAIR @a @%% + /* [ @a unit : @p.b unit : @p pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ @p pair (unit %a) (unit %b) ] */ ; + DUP + /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; + UNPAIR @%% @%% + /* [ @p.a unit : @p.b unit : @p pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ @p pair (unit %a) (unit %b) ] */ ; + DUP + /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; + UNPAIR @% @%% + /* [ @a unit : @p.b unit : @p pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ @p pair (unit %a) (unit %b) ] */ ; + DUP + /* [ @p pair (unit %a) (unit %b) : @p pair (unit %a) (unit %b) ] */ ; + UNPAIR @%% @% + /* [ @p.a unit : @b unit : @p pair (unit %a) (unit %b) ] */ ; + DROP 2 + /* [ @p pair (unit %a) (unit %b) ] */ ; + DROP + /* [] */ ; + UNIT @b + /* [ @b unit ] */ ; + UNIT @a + /* [ @a unit : @b unit ] */ ; + PAIR @c + /* [ @c pair (unit @a) (unit @b) ] */ ; + UNPAIR @b @a + /* [ @b unit : @a unit ] */ ; + DROP 2 + /* [] */ ; + UNIT + /* [ unit ] */ ; + NIL operation + /* [ list operation : unit ] */ ; + PAIR + /* [ pair (list operation) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--update_big_map.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--update_big_map.tz].out new file mode 100644 index 000000000000..935a43eb7a41 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--update_big_map.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/update_big_map.tz] + +Well typed +Gas remaining: 1039991.231 units remaining +{ storage (pair (big_map string string) unit) ; + parameter (map string (option string)) ; + code { UNPAPAIR ; + ITER { UNPAIR + /* [ @key string : @elt option string : big_map string string : unit ] */ ; + UPDATE + /* [ big_map string string : unit ] */ } + /* [ big_map string string : unit ] */ ; + PAIR + /* [ pair (big_map string string) unit ] */ ; + NIL operation + /* [ list operation : pair (big_map string string) unit ] */ ; + PAIR + /* [ pair (list operation) (big_map string string) unit ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxo_read.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxo_read.tz].out new file mode 100644 index 000000000000..56833fa66b96 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxo_read.tz].out @@ -0,0 +1,26 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/utxo_read.tz] + +Well typed +Gas remaining: 1039984.190 units remaining +{ parameter (pair (ticket nat) nat) ; + storage address ; + code { CAR + /* [ @parameter pair (ticket nat) nat ] */ ; + UNPAIR + /* [ ticket nat : nat ] */ ; + READ_TICKET + /* [ pair address nat nat : ticket nat : nat ] */ ; + DIP { DROP /* [ nat ] */ } + /* [ pair address nat nat : nat ] */ ; + UNPAIR + /* [ address : pair nat nat : nat ] */ ; + DIP { UNPAIR /* [ nat : nat : nat ] */ } + /* [ address : nat : nat : nat ] */ ; + DIIP { ASSERT_CMPEQ } + /* [ address : nat ] */ ; + DIP { PUSH nat 42 /* [ nat : nat ] */ ; ASSERT_CMPEQ } + /* [ address ] */ ; + NIL operation + /* [ list operation : address ] */ ; + PAIR + /* [ pair (list operation) address ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxor.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxor.tz].out new file mode 100644 index 000000000000..6b5b7d05b339 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--utxor.tz].out @@ -0,0 +1,109 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/utxor.tz] + +Well typed +Gas remaining: 1039966.683 units remaining +{ parameter (pair address address) ; + storage nat ; + code { UNPAIR + /* [ @parameter pair address address : @storage nat ] */ ; + DIP { DUP /* [ @storage nat : @storage nat ] */ } + /* [ @parameter pair address address : @storage nat : @storage nat ] */ ; + SWAP + /* [ @storage nat : @parameter pair address address : @storage nat ] */ ; + PUSH nat + 5 + /* [ nat : @storage nat : @parameter pair address address : @storage nat ] */ ; + SWAP + /* [ @storage nat : nat : @parameter pair address address : @storage nat ] */ ; + TICKET + /* [ ticket nat : @parameter pair address address : @storage nat ] */ ; + PUSH nat + 2 + /* [ nat : ticket nat : @parameter pair address address : @storage nat ] */ ; + PUSH nat + 3 + /* [ nat : nat : ticket nat : @parameter pair address address : @storage nat ] */ ; + PAIR + /* [ pair nat nat : ticket nat : @parameter pair address address + : @storage nat ] */ ; + SWAP + /* [ ticket nat : pair nat nat : @parameter pair address address + : @storage nat ] */ ; + SPLIT_TICKET + /* [ option (pair (ticket nat) (ticket nat)) : @parameter pair address address + : @storage nat ] */ ; + ASSERT_SOME ; + UNPAIR + /* [ ticket nat : ticket nat : @parameter pair address address : @storage nat ] */ ; + DIP { DIP { DUP + /* [ @parameter pair address address : @parameter pair address address + : @storage nat ] */ ; + CAR + /* [ address : @parameter pair address address : @storage nat ] */ ; + CONTRACT + (pair (ticket nat) nat) + /* [ @contract option (contract (pair (ticket nat) nat)) + : @parameter pair address address : @storage nat ] */ ; + ASSERT_SOME ; + PUSH mutez + 0 + /* [ mutez : @contract.some contract (pair (ticket nat) nat) + : @parameter pair address address : @storage nat ] */ } + /* [ ticket nat : mutez : @contract.some contract (pair (ticket nat) nat) + : @parameter pair address address : @storage nat ] */ ; + PUSH nat + 2 + /* [ nat : ticket nat : mutez : @contract.some contract (pair (ticket nat) nat) + : @parameter pair address address : @storage nat ] */ ; + SWAP + /* [ ticket nat : nat : mutez : @contract.some contract (pair (ticket nat) nat) + : @parameter pair address address : @storage nat ] */ ; + PAIR + /* [ pair (ticket nat) nat : mutez + : @contract.some contract (pair (ticket nat) nat) + : @parameter pair address address : @storage nat ] */ } + /* [ ticket nat : pair (ticket nat) nat : mutez + : @contract.some contract (pair (ticket nat) nat) + : @parameter pair address address : @storage nat ] */ ; + DIP { TRANSFER_TOKENS + /* [ operation : @parameter pair address address : @storage nat ] */ } + /* [ ticket nat : operation : @parameter pair address address : @storage nat ] */ ; + SWAP + /* [ operation : ticket nat : @parameter pair address address : @storage nat ] */ ; + DIP { DIP { CDR + /* [ address : @storage nat ] */ ; + CONTRACT + (pair (ticket nat) nat) + /* [ @contract option (contract (pair (ticket nat) nat)) : @storage nat ] */ ; + ASSERT_SOME ; + PUSH mutez + 0 + /* [ mutez : @contract.some contract (pair (ticket nat) nat) : @storage nat ] */ } + /* [ ticket nat : mutez : @contract.some contract (pair (ticket nat) nat) + : @storage nat ] */ ; + PUSH nat + 3 + /* [ nat : ticket nat : mutez : @contract.some contract (pair (ticket nat) nat) + : @storage nat ] */ ; + SWAP + /* [ ticket nat : nat : mutez : @contract.some contract (pair (ticket nat) nat) + : @storage nat ] */ ; + PAIR + /* [ pair (ticket nat) nat : mutez + : @contract.some contract (pair (ticket nat) nat) : @storage nat ] */ } + /* [ operation : pair (ticket nat) nat : mutez + : @contract.some contract (pair (ticket nat) nat) : @storage nat ] */ ; + DIP { TRANSFER_TOKENS /* [ operation : @storage nat ] */ } + /* [ operation : operation : @storage nat ] */ ; + NIL operation + /* [ list operation : operation : operation : @storage nat ] */ ; + SWAP + /* [ operation : list operation : operation : @storage nat ] */ ; + CONS + /* [ list operation : operation : @storage nat ] */ ; + SWAP + /* [ operation : list operation : @storage nat ] */ ; + CONS + /* [ list operation : @storage nat ] */ ; + PAIR + /* [ pair (list operation) (nat @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_fib.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_fib.tz].out new file mode 100644 index 000000000000..fbe72ac3e8c7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_fib.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_fib.tz] + +Well typed +Gas remaining: 1039993.990 units remaining +{ parameter (pair nat address) ; + storage nat ; + code { CAR + /* [ @parameter pair nat address ] */ ; + UNPAIR + /* [ nat : address ] */ ; + VIEW "fib" nat + /* [ @contract option nat ] */ ; + IF_SOME + { NIL operation + /* [ list operation : @contract.some nat ] */ ; + PAIR + /* [ pair (list operation) (nat @contract.some) ] */ } + { FAIL } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_mutual_recursion.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_mutual_recursion.tz].out new file mode 100644 index 000000000000..9aaa3e22c06a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_mutual_recursion.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_mutual_recursion.tz] + +Well typed +Gas remaining: 1039992.695 units remaining +{ parameter (pair nat address) ; + storage nat ; + code { CAR + /* [ @parameter pair nat address ] */ ; + DUP + /* [ @parameter pair nat address : @parameter pair nat address ] */ ; + CDR + /* [ address : @parameter pair nat address ] */ ; + SWAP + /* [ @parameter pair nat address : address ] */ ; + VIEW "is_twenty" nat + /* [ @contract option nat ] */ ; + IF_SOME + { NIL operation + /* [ list operation : @contract.some nat ] */ ; + PAIR + /* [ pair (list operation) (nat @contract.some) ] */ } + { FAIL } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_add.tz].out new file mode 100644 index 000000000000..8a62319d8924 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_add.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_add.tz] + +Well typed +Gas remaining: 1039993.770 units remaining +{ parameter (pair nat address) ; + storage nat ; + code { CAR + /* [ @parameter pair nat address ] */ ; + UNPAIR + /* [ nat : address ] */ ; + VIEW "add" nat + /* [ @contract option nat ] */ ; + IF_SOME { /* [ @contract.some nat ] */ } { FAIL } ; + NIL operation + /* [ list operation : @contract.some nat ] */ ; + PAIR + /* [ pair (list operation) (nat @contract.some) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_constant.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_constant.tz].out new file mode 100644 index 000000000000..de42c2c0a404 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_constant.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_constant.tz] + +Well typed +Gas remaining: 1039993.750 units remaining +{ parameter (pair nat address) ; + storage nat ; + code { CAR + /* [ @parameter pair nat address ] */ ; + UNPAIR + /* [ nat : address ] */ ; + VIEW "const" nat + /* [ @contract option nat ] */ ; + IF_SOME { /* [ @contract.some nat ] */ } { FAIL } ; + NIL operation + /* [ list operation : @contract.some nat ] */ ; + PAIR + /* [ pair (list operation) (nat @contract.some) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_id.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_id.tz].out new file mode 100644 index 000000000000..d9279a6bdb19 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_id.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_id.tz] + +Well typed +Gas remaining: 1039992.989 units remaining +{ parameter (pair nat address) ; + storage (pair nat nat) ; + code { CAR + /* [ @parameter pair nat address ] */ ; + UNPAIR + /* [ nat : address ] */ ; + VIEW "id" (pair nat nat) + /* [ @contract option (pair nat nat) ] */ ; + IF_SOME { /* [ @contract.some pair nat nat ] */ } { FAIL } ; + NIL operation + /* [ list operation : @contract.some pair nat nat ] */ ; + PAIR + /* [ pair (list operation) (pair @contract.some nat nat) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_addr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_addr.tz].out new file mode 100644 index 000000000000..9a9131a547a2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_addr.tz].out @@ -0,0 +1,21 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_nonexistent_addr.tz] + +Well typed +Gas remaining: 1039342.059 units remaining +{ parameter (pair nat address) ; + storage bool ; + code { DROP + /* [] */ ; + PUSH address "tz1SuakBpFdG9b4twyfrSMqZzruxhpMeSrE5" + /* [ address ] */ ; + PUSH nat 0 + /* [ nat : address ] */ ; + VIEW "test" bool + /* [ @contract option bool ] */ ; + IF_SOME + { DROP /* [] */ ; PUSH bool True /* [ bool ] */ } + { PUSH bool False /* [ bool ] */ } ; + NIL operation + /* [ list operation : bool ] */ ; + PAIR + /* [ pair (list operation) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_func.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_func.tz].out new file mode 100644 index 000000000000..d8b49a53770f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_nonexistent_func.tz].out @@ -0,0 +1,19 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_nonexistent_func.tz] + +Well typed +Gas remaining: 1039993.059 units remaining +{ parameter (pair nat address) ; + storage bool ; + code { CAR + /* [ @parameter pair nat address ] */ ; + UNPAIR + /* [ nat : address ] */ ; + VIEW "not_exist" bool + /* [ @contract option bool ] */ ; + IF_SOME + { DROP /* [] */ ; PUSH bool True /* [ bool ] */ } + { PUSH bool False /* [ bool ] */ } ; + NIL operation + /* [ list operation : bool ] */ ; + PAIR + /* [ pair (list operation) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_test_step_contants.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_test_step_contants.tz].out new file mode 100644 index 000000000000..d837439afbe6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_test_step_contants.tz].out @@ -0,0 +1,19 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_test_step_contants.tz] + +Well typed +Gas remaining: 1039992.390 units remaining +{ parameter address ; + storage (option (pair (pair mutez mutez) (pair (pair address address) address))) ; + code { CAR + /* [ @parameter address ] */ ; + UNIT + /* [ unit : @parameter address ] */ ; + VIEW "step_constants" + (pair (pair mutez mutez) (pair (pair address address) address)) + /* [ @parameter.contract option (pair (pair mutez mutez) (pair address address) address) ] */ ; + NIL operation + /* [ list operation + : @parameter.contract option (pair (pair mutez mutez) (pair address address) address) ] */ ; + PAIR + /* [ pair (list operation) + (option @parameter.contract (pair (pair mutez mutez) (pair address address) address)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_input_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_input_type.tz].out new file mode 100644 index 000000000000..3d6b281ed422 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_input_type.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_toplevel_inconsistent_input_type.tz] + +Well typed +Gas remaining: 1039993.119 units remaining +{ parameter (pair int address) ; + storage nat ; + code { CAR + /* [ @parameter pair int address ] */ ; + UNPAIR + /* [ int : address ] */ ; + VIEW "add" nat + /* [ @contract option nat ] */ ; + IF_SOME { DROP /* [] */ ; PUSH nat 1 /* [ nat ] */ } { PUSH nat 0 /* [ nat ] */ } ; + NIL operation + /* [ list operation : nat ] */ ; + PAIR + /* [ pair (list operation) nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_output_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_output_type.tz].out new file mode 100644 index 000000000000..d89bb7ef51f1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_op_toplevel_inconsistent_output_type.tz].out @@ -0,0 +1,19 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_op_toplevel_inconsistent_output_type.tz] + +Well typed +Gas remaining: 1039993.119 units remaining +{ parameter (pair nat address) ; + storage bool ; + code { CAR + /* [ @parameter pair nat address ] */ ; + UNPAIR + /* [ nat : address ] */ ; + VIEW "add" bool + /* [ @contract option bool ] */ ; + IF_SOME + { DROP /* [] */ ; PUSH bool True /* [ bool ] */ } + { PUSH bool False /* [ bool ] */ } ; + NIL operation + /* [ list operation : bool ] */ ; + PAIR + /* [ pair (list operation) bool ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_rec.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_rec.tz].out new file mode 100644 index 000000000000..2dc1cde40ecd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_rec.tz].out @@ -0,0 +1,33 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_rec.tz] + +Well typed +Gas remaining: 1039987.709 units remaining +{ parameter unit ; + storage unit ; + view "loop" + address + never + { CAR + /* [ address ] */ ; + DUP + /* [ address : address ] */ ; + VIEW "loop" never + /* [ @contract option never ] */ ; + ASSERT_SOME } ; + code { CDR + /* [ @storage unit ] */ ; + SELF + /* [ @self contract unit : @storage unit ] */ ; + ADDRESS + /* [ @self.address address : @storage unit ] */ ; + DUP + /* [ @self.address address : @self.address address : @storage unit ] */ ; + VIEW "loop" never + /* [ @self.address.contract option never : @storage unit ] */ ; + ASSERT_SOME ; + DROP + /* [ @storage unit ] */ ; + NIL operation + /* [ list operation : @storage unit ] */ ; + PAIR + /* [ pair (list operation) (unit @storage) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_toplevel_lib.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_toplevel_lib.tz].out new file mode 100644 index 000000000000..3566383e137d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--view_toplevel_lib.tz].out @@ -0,0 +1,148 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/view_toplevel_lib.tz] + +Well typed +Gas remaining: 1039942.437 units remaining +{ parameter nat ; + storage nat ; + code { CAR + /* [ @parameter nat ] */ ; + NIL operation + /* [ list operation : @parameter nat ] */ ; + PAIR + /* [ pair (list operation) (nat @parameter) ] */ } ; + view "add" nat nat { UNPAIR /* [ nat : nat ] */ ; ADD /* [ nat ] */ } ; + view "id" nat (pair nat nat) { /* [ pair nat nat ] */ } ; + view "test_failwith" nat (pair nat nat) { FAILWITH /* [] */ } ; + view "step_constants" + unit + (pair (pair mutez mutez) (pair (pair address address) address)) + { DROP + /* [] */ ; + SOURCE + /* [ @source address ] */ ; + SENDER + /* [ @sender address : @source address ] */ ; + SELF_ADDRESS + /* [ @self address : @sender address : @source address ] */ ; + PAIR + /* [ pair (address @self) (address @sender) : @source address ] */ ; + PAIR + /* [ pair (pair (address @self) (address @sender)) (address @source) ] */ ; + BALANCE + /* [ @balance mutez + : pair (pair (address @self) (address @sender)) (address @source) ] */ ; + AMOUNT + /* [ @amount mutez : @balance mutez + : pair (pair (address @self) (address @sender)) (address @source) ] */ ; + PAIR + /* [ pair (mutez @amount) (mutez @balance) + : pair (pair (address @self) (address @sender)) (address @source) ] */ ; + PAIR + /* [ pair (pair (mutez @amount) (mutez @balance)) + (pair (address @self) (address @sender)) + (address @source) ] */ } ; + view "succ" + (pair nat address) + nat + { CAR + /* [ pair nat address ] */ ; + UNPAIR + /* [ nat : address ] */ ; + PUSH nat 1 + /* [ nat : nat : address ] */ ; + ADD + /* [ nat : address ] */ ; + PAIR + /* [ pair nat address ] */ ; + DUP + /* [ pair nat address : pair nat address ] */ ; + CDR + /* [ address : pair nat address ] */ ; + SWAP + /* [ pair nat address : address ] */ ; + VIEW "is_twenty" nat + /* [ @contract option nat ] */ ; + ASSERT_SOME } ; + view "is_twenty" + (pair nat address) + nat + { CAR + /* [ pair nat address ] */ ; + DUP + /* [ pair nat address : pair nat address ] */ ; + CAR + /* [ nat : pair nat address ] */ ; + PUSH nat 20 + /* [ nat : nat : pair nat address ] */ ; + COMPARE + /* [ int : pair nat address ] */ ; + EQ + /* [ bool : pair nat address ] */ ; + IF { CAR /* [ nat ] */ } + { DUP + /* [ pair nat address : pair nat address ] */ ; + CDR + /* [ address : pair nat address ] */ ; + SWAP + /* [ pair nat address : address ] */ ; + VIEW "succ" nat + /* [ @contract option nat ] */ ; + ASSERT_SOME } } ; + view "fib" + nat + nat + { CAR + /* [ nat ] */ ; + DUP + /* [ nat : nat ] */ ; + PUSH nat 0 + /* [ nat : nat : nat ] */ ; + COMPARE + /* [ int : nat ] */ ; + EQ + /* [ bool : nat ] */ ; + IF { /* [ nat ] */ } + { DUP + /* [ nat : nat ] */ ; + PUSH nat 1 + /* [ nat : nat : nat ] */ ; + COMPARE + /* [ int : nat ] */ ; + EQ + /* [ bool : nat ] */ ; + IF { /* [ nat ] */ } + { DUP + /* [ nat : nat ] */ ; + PUSH nat 1 + /* [ nat : nat : nat ] */ ; + SWAP + /* [ nat : nat : nat ] */ ; + SUB + /* [ int : nat ] */ ; + ABS + /* [ nat : nat ] */ ; + SELF_ADDRESS + /* [ @self address : nat : nat ] */ ; + SWAP + /* [ nat : @self address : nat ] */ ; + VIEW "fib" nat + /* [ @self.contract option nat : nat ] */ ; + IF_SOME + { SWAP + /* [ nat : @self.contract.some nat ] */ ; + PUSH nat 2 + /* [ nat : nat : @self.contract.some nat ] */ ; + SWAP + /* [ nat : nat : @self.contract.some nat ] */ ; + SUB + /* [ int : @self.contract.some nat ] */ ; + ABS + /* [ nat : @self.contract.some nat ] */ ; + SELF_ADDRESS + /* [ @self address : nat : @self.contract.some nat ] */ ; + SWAP + /* [ nat : @self address : @self.contract.some nat ] */ ; + VIEW "fib" nat + /* [ @self.contract option nat : @self.contract.some nat ] */ ; + IF_SOME { ADD /* [ nat ] */ } { FAIL } } + { FAIL } } } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--voting_power.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--voting_power.tz].out new file mode 100644 index 000000000000..398157ecc039 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--voting_power.tz].out @@ -0,0 +1,20 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/voting_power.tz] + +Well typed +Gas remaining: 1039994.233 units remaining +{ parameter key ; + storage (pair nat nat) ; + code { CAR + /* [ @parameter key ] */ ; + HASH_KEY + /* [ key_hash ] */ ; + VOTING_POWER + /* [ nat ] */ ; + DIP { TOTAL_VOTING_POWER /* [ nat ] */ } + /* [ nat : nat ] */ ; + PAIR + /* [ pair nat nat ] */ ; + NIL operation + /* [ list operation : pair nat nat ] */ ; + PAIR + /* [ pair (list operation) nat nat ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--xor.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--xor.tz].out new file mode 100644 index 000000000000..f9da7562f119 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[opcodes--xor.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract.py::TestTypecheck::test_typecheck[opcodes/xor.tz] + +Well typed +Gas remaining: 1039990.984 units remaining +{ parameter (or (pair bool bool) (pair nat nat)) ; + storage (option (or bool nat)) ; + code { CAR + /* [ @parameter or (pair bool bool) (pair nat nat) ] */ ; + IF_LEFT + { UNPAIR /* [ bool : bool ] */ ; XOR /* [ bool ] */ ; LEFT nat /* [ or bool nat ] */ } + { UNPAIR /* [ nat : nat ] */ ; XOR /* [ nat ] */ ; RIGHT bool /* [ or bool nat ] */ } ; + SOME + /* [ option (or bool nat) ] */ ; + NIL operation + /* [ list operation : option (or bool nat) ] */ ; + PAIR + /* [ pair (list operation) (option (or bool nat)) ] */ } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[Fr].out new file mode 100644 index 000000000000..8b49506f5fd6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_one[Fr] + +storage + (Some 0x0200000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G1].out new file mode 100644 index 000000000000..fc3fdf65638f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_one[G1] + +storage + (Some 0x0572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G2].out new file mode 100644 index 000000000000..db602b9c2b16 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_one[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_one[G2] + +storage + (Some 0x0a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a0530f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf30468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[Fr].out new file mode 100644 index 000000000000..f2675822471d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_random[Fr] + +storage + (Some 0x660dec4a316a24f34cad26e886cb480da89c55113f5c1a2b6bfdaab82d737708) +emitted operations + +big_map diff + + +storage + (Some 0xa711c66e47a4f376a769f9accfd675dcc6a2b9ce09c0482923c19f8218f16849) +emitted operations + +big_map diff + + +storage + (Some 0x111a13c7d5feb5e8fe5b2c5550d3335c04737fcbeece373eabf07b1b1604bb3b) +emitted operations + +big_map diff + + +storage + (Some 0x366bf41ff7bd7828a3d206500267d5c888aa120292be0cd6399fe4b9db75625b) +emitted operations + +big_map diff + + +storage + (Some 0x86b8dc4aa73cccb08dd143980ec0a4f73c2067807b3b4f2ff96368cb5efd8d4e) +emitted operations + +big_map diff + + +storage + (Some 0x7b83a6a4c37d5536bebe96766b25195e32b69257f3dc2d1e6fcdd7144db0f80c) +emitted operations + +big_map diff + + +storage + (Some 0xac54d72aff4eb7b9acce60a61f8f2ca1a1a387557cd6df2e9fe690ce209eca63) +emitted operations + +big_map diff + + +storage + (Some 0x183b7f72e291320045c63ad9453dacada669ef605e72c708a8735ae2fa7f795d) +emitted operations + +big_map diff + + +storage + (Some 0xb82eba460eb5d8e64d597cca0278098e87f2e1bba06d0fe19f6da2075084c66f) +emitted operations + +big_map diff + + +storage + (Some 0xb87216f6813286cfabec830fa176f2aa127cc1b99b824d312bd8d239c2555d6e) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G1].out new file mode 100644 index 000000000000..7d8a78442e03 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_random[G1] + +storage + (Some 0x058026aa05e53a8be99d756ad00d2f3577786eeb07abe3d0bb51a9c6c4786fa31579791ecca13a22e423a3ca2e1d8ae6049f0d41d63294fa63d9679c2dfda2ccc5263bdff7d8f404fb566e3a420fdf9bcc003cd33b7d4a46f1d9a1dd059c879f) +emitted operations + +big_map diff + + +storage + (Some 0x11613e266146d8bf256974bfd8bc7bcfc1aa33d1abb8407d5199c18c1d71bdc27c37bcc64a30f3e39ef8f04e521a099a029636513b15f1e71a7aa6042fff9d1d552c542caa5f302071504d524d511173027aa21ad9d1928dba8a201c9f24d9a3) +emitted operations + +big_map diff + + +storage + (Some 0x026fcea34d1a4c5125142dfa3b616086309cab49e60e548d95de658af4d9329c269dc132bd5d884617e8767600daeee90c6f5d25f3d63540f3b799d291e5df4a90244346ed780d5c9d3afa8f3c9a196e089fa4edc4a9806592e8561d626579e3) +emitted operations + +big_map diff + + +storage + (Some 0x0f048c8e56ad4ddbb3fe800e2667ecaa5683d33a2828c7f9341ed2708f83e1cc58484085399822f6af8f05e9761cb49f0ee1db03e81501d8982d1362518386e77fbcf240d9d4768187ab4727c6b4ede0057dbe0358f37dac17eb2eb395088a44) +emitted operations + +big_map diff + + +storage + (Some 0x114c27c6a72b3eb7bb0176261d670ce20a9cf90a52da5b68faf2013bac314f7987e735ac04ebb1c164a48f60c16ec4be0c1eb74c865b1df94202b4eceb42e22d86099ad360339303463d68c0d931774304fa4c780208abcf1c79640b0c4190ce) +emitted operations + +big_map diff + + +storage + (Some 0x054b5561e8d9de0052a167f4886efd49890dfda073843dee3077c37ccb3d7ad2326970eb9615f318a0851b30aaa7f1150b4a687ddf9672bdbcf159358ea75025adc8584532a046b48d30868ee38dba0ca8a209af29cd791594cfb7e9ae991119) +emitted operations + +big_map diff + + +storage + (Some 0x174e2a1898303aba4520148510fbdc740d8154886d04d1ef7f65c904cbd2171af98345f2463bf26c35576da1be372d680bd755d4c860640a9991cfe703590382c2c20ab7121bc94926dac025e25526ffbb234785bfb6eb5ebd9b8be521e5cda3) +emitted operations + +big_map diff + + +storage + (Some 0x04cf46cee905ad068310d3e0764cba786372efd7eea4a8a2354da24eea26af1578320cc25a5c0dd9fa016c16ef956b071529c2fe97c6c69690675a5484220900d6c48d03976289801f818899416e014e9d50ca19c165b9c43e4de8ee0b16a792) +emitted operations + +big_map diff + + +storage + (Some 0x0ec968f32f75a84a3bac57f2025ebcef650a8ccf5da9b27ca53331eda42ca2848948e8e9cc7588acdc9430ba4051a0c70ada591853bf90ebcd4df22ce469c453ce5d4bfb7d968ba8b85ec48188f7912a549dc7a81f246264da9b355aeb1b0178) +emitted operations + +big_map diff + + +storage + (Some 0x018637aff527610ee1a083eca3f3ad2a989dbcce2a393e24703e52e418b8d373433155bda3bb4664aef12d8cb058932d14d26d519045ce36b21cb50c77373077cced9fc000b8696cc5e035ad7d2dbdf41971c8403bee31ae0a6a36263066b847) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G2].out new file mode 100644 index 000000000000..a58357132e6a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_random[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_random[G2] + +storage + (Some 0x139bd98ba7fa37cb7e1ba9177ca818063bd14a8aba77a7f4dbff7a6c848683ac17415104d5c63e46df848499f209dfbc105f18d1e114210fbce28d22f30818e75bc412526a55f7937ac290bf37adadeee6f40b9614b74b1962376d5c3078085a02a53c9021eba8b107a43bdebaef9fddc6a8c8d8c19138d06a332f986f256c32b8f19d5e39f203eba23ea36b4bcff9300dad02b62de4defe358fe6b835b3d93571ef66989530e61090c3db145c389f66ab2ee01e4f05a9ca18fb1ecf48faed94) +emitted operations + +big_map diff + + +storage + (Some 0x192438792f58ae648d5cc73d07d263f0866430fa798d61cddcf35ac48533cd60ceb7e1adaf2ac7475b0819d583b5fe210454a94b83d8a110f699db4c1963dd9bbc1f5b8d1de6ae59f0c5c1d0c0fccdc04d5cfaf901b9c1b713b48938589bd53419a11025e8f61abf088d72b3fe3e3f8d6682e235804855d5a02897ad8ce252fb2584670c27dd81e48ba14d01b09add9e0857cd0cfd23bce8702ad2cf73709debce427df15ba1bd920c941eabc712fa2652e906a1f49d604222410929de6498a1) +emitted operations + +big_map diff + + +storage + (Some 0x14e9b22683a66543ec447b7aa76e4404424709728507581d0b3f60a8062c3f7c7d3365197c59f7c961fa9731084f5be60d0a936e93d556bdef2032cdcae2fa9902dcbe105e01d7ab7126d83486d882c4efd2fc1ac55044157333be19acf0cb7a10bc41c8081c9babd8d5b41b645badd4a679b3d4e1b3ea2c0e1f53b39c00b3889a40306c9b9ee2da5831e90148334d91016474d07e0f4e36d2d51b5ca11b633b9a940b9c126aebf4a2537c18fdc6967fb677824bfa902157e53cb499a021e57b) +emitted operations + +big_map diff + + +storage + (Some 0x139bf65acd684812defe34a647e77d562d16ec07aadc8df7460835bb42e52783265fc7062d24399533488aa26f177f300a05c44ba3deb272a9334bfbd15e3df49169622e8cc739c8d8ad1658769e94f28c36b3ddc608a71ea590f5d956820116019860de9ec8f5257791279a546c6d7efc62ce91114bcb11053f999f5adf35c0f0da321602ce11347567aefe05c58bfc17693d82a530ed5c07e7e1d87d3ac3c639005480f5fc9b9fb378aa693781d0ba8ee097bff01964faa41c9361ae9da3ed) +emitted operations + +big_map diff + + +storage + (Some 0x17df1d683296888e1ef6becb004061a658609faa7aecfc56e09be2cb07f621e6bf383f3ed9eaa5ad6eb4c5ff3e4ac51615cf8e6d23843b1665d6efefdc8024b15651ee05b939f1fc529a5d4233d58ee83cd4fcd07508eb0fa1229bf649db9fb407167c5d410f1f4c403bd4cc234e3f757d74587ead39d549b88e6d6e0e187498386152a981e26a0ecfbc89349db5e5f502e61c367aea8d829cbc8d2441362f075c9245a82c8daf849dde2316fb06127db9eeb2d99a5bfee90e39ac18ac062db2) +emitted operations + +big_map diff + + +storage + (Some 0x072666f55bcd0330329524efb1a8bf981fcb0ee73c739be4b83339fa2953888bf058a115c834ed7460f6ef6e7aa36d0d1002adc9e373cfcfc62f47a6a6670700c749e6df92e360fa0a379c5621b39f35b02c578aea5e79d54f692d2fab9ad7c01527640d6462324d6a137bf7c36abd863f3efe2953d3b1729e8d3f07321af14f38893ca2e61eba4c987a5f7988569c4f0626e86728ce9292df1bd38c5e21b32d329b86f8f41eaa11eac36cc0ddf0b3fba543d94f4d3a4b992eb7e60fe9680072) +emitted operations + +big_map diff + + +storage + (Some 0x152f2b940efd3d2c53640e2ccf881935f114404ac116a54c859c59511058db4d7e2f4369e3e846ccdda94e72e22e06ce0fb52ada3931bb686d52e45ef020b58b9da28f370cd27a595b07eae78ec26e044f58c15cd256fb426e0b862a37bb751212256f5e61ef53dcf799657d5071e6dfa1040b2ac0ec31e18069d2e6e7e6424d09ece1b68a8be6d56dca3de4d467e8a80c395cd9ebe4645d3e465f0263bc100bb9d49dbaadf0572836c8bf03d8c2155068a1f56017864a51e8f4915d24885afa) +emitted operations + +big_map diff + + +storage + (Some 0x0c5ae8a5d7042b893b4600512b81b205b0f3aec3b00d0b2ece549e31c0466f49cd8900270ac48f253e66dc8a05a83e3c0ed8790344651fb0d17ef0c0f86340687e890424c06b5426e6732c3ff837ad4c76a2dfb9f5d80e80eadd024cc4c386f10bc203d5bba633fa3f50fb84140e9ef8c0f7c83ad41b2d1230b8af982e541c07f137b59b71142a4e2be49d9a0fd1212f11fe2ebabe025ab38dfc64f38e724edea44610b88239679e60d9ee151174a3bd1425eb865b8533c0b833577e430ae37a) +emitted operations + +big_map diff + + +storage + (Some 0x127093c56626b5e31114ddc6565ac257c3f5642d4eeabb469c2e6cfa23c713bd87fbccc738eae6c6356eb1bc3e62babc1985437cd7bcf96041d3547efa5c1c5ab0dc66aecae18f5a70055a4f4c518b6f7f31f18709d0a7f37f5eb3cd413557f7164ead5569fd618dee7145ce3b5786a4d5551c63b6936e682e618f9db2aa1c97117369cde387255d063890b4a7c788b80ebabf2427faab4c8cc0a71d467ca7c78cc625fd9dbb48fd485124cdf1c5748f6488a06f1e71b429fc904f249fd5885f) +emitted operations + +big_map diff + + +storage + (Some 0x0e18a45de8e16ce54070d9df1ee055e933e7c65e2d33bbfd9eba62dbcd84c00eca86bffec4f0e02ea6172242243ca205067af2bd83fee2481e6ed3fee5b327e9d7aa95513d1fa3b60093b86b29ae14df53b03ac63f5b0c2ea3df9575fddd2bc7045df4179eb4de582fd6c3955d1947036131eea418e57fa977181e9b7c6af89686f47593bc3e1d9ea0be7c46004f23ce0d3abe0bd9fbae591d5b3fba5ed26ee6756ab595e79f27825afe20fa68d7d6b954356b589c80dc909d5d91c6afed0440) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[Fr].out new file mode 100644 index 000000000000..c5ad3b60accd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_zero[Fr] + +storage + (Some 0x0100000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G1].out new file mode 100644 index 000000000000..71b4d0d5d00e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_zero[G1] + +storage + (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G2].out new file mode 100644 index 000000000000..aa98c7d2c4d6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_one_zero[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_one_zero[G2] + +storage + (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[Fr].out new file mode 100644 index 000000000000..a940808843a8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_one[Fr] + +storage + (Some 0xf09d35856fcfe3dd435bed02f67e1a34b246f9eb48f9034e3bce2a83ba806c23) +emitted operations + +big_map diff + + +storage + (Some 0x2a5cababf8f15f832f44e2a935f029722c2e4c87fdcd3ad1bf4ec872042d9f11) +emitted operations + +big_map diff + + +storage + (Some 0x90bdbed3c04f5a16f7dd885aa2bf82e0688da08f687d29a38c6ebf46631d7a38) +emitted operations + +big_map diff + + +storage + (Some 0xb0df3414f8f1b9b0265f7d243790b57dbf3f028bd0e99707a4ec7c6753ff9c5a) +emitted operations + +big_map diff + + +storage + (Some 0xd908b12f4af05efc5a4fc60806a64be2cc267846d93f2d6e857334c2aa66dd62) +emitted operations + +big_map diff + + +storage + (Some 0xb2a92200b1c95da0fbc293e7fb078961820240c26c87ff727a63fbcd3bf7591a) +emitted operations + +big_map diff + + +storage + (Some 0xa4fcd4658ae7312cd766f6d32afb2a57acbc386000d7a817fb45b4ddb7064c5f) +emitted operations + +big_map diff + + +storage + (Some 0x93e781ac13e039a74b9329fe4c62581e78cbe5f98c3a40ef4aef0afffb52e915) +emitted operations + +big_map diff + + +storage + (Some 0x4c7dc9dffae7cafafb2d713f334576a96a530ed57c5fe4c083130f67cce8c33b) +emitted operations + +big_map diff + + +storage + (Some 0x2a72fa0e849cecab222419ae6b7ef22b21221f06f7755caab4aa0c035d10d90e) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G1].out new file mode 100644 index 000000000000..3589386b9675 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_one[G1] + +storage + (Some 0x03511648ff12b05121af6aee879ec39ded8e895f3bf83c64425c374ed1f1eb022d69b23657d36c7caf3a4680c0ac4617193583c1f57a61b18d61b2584a9b373bb45564b67ebdb884f7fc771ee639d596d343b302872a39a649b25eb4420963af) +emitted operations + +big_map diff + + +storage + (Some 0x01382fcd60894365df78f25e41a72e66a8b82633a94c8aad9a782bf880951b2e77794775bc0f2beb2200896c3042f24219fbc49d8c9f4a446ef1e5d3c8bf0d5da5e5c7480389030f971eef2fe382ecf7017351d7a838456e9f32fc7c32400277) +emitted operations + +big_map diff + + +storage + (Some 0x046dfb65aeebf558d612af9e6efe5aca9332026c0bf584afe7f11166a511a209cb750b2a037f28c476d49c0f8d5b42401479f06b06eddadef2139b142d1f44d4d63ec870a12fd574a89fefb05000a48a0c1d4cad1ec1fb53ffecbb05d2fd1a26) +emitted operations + +big_map diff + + +storage + (Some 0x12f06982de9983d040b51bf0cbbca5c8eebd6636f81c49a4b56d06ef8092126c50a0451931917a5ae0a551b16d0e3fa60bab06dbd78fc6a64f6c9647ae4ea534baf2fa5f08d438399937e4458563f47c1e8c4f0495d5c0f6609492d548310cb5) +emitted operations + +big_map diff + + +storage + (Some 0x0d8b71b72b170030fcb76bc7324fa823f8b59f2cb6b014687620a3d01c8cae25a41c423ff9258524571ab273fdd1783704b9fd0d5a4e1801cfb819aff9297579012d3cf77291ad1a2748fb1727c46fe3d0f9d2feadcc57c2cd495b6cb9314a5a) +emitted operations + +big_map diff + + +storage + (Some 0x016a3c5fff7923ad1c3566886a6dd256e32e69d992fd92a34496ae3667b33df6b699b7805fe732c68c98703e93a2ab9716dcf3d2a244889d3ff2804b9aa2043e7b07398789e39b8ac022606a90f303f176dca030856cc0777c2df1f7fe1a58f3) +emitted operations + +big_map diff + + +storage + (Some 0x11851bdd68f0062a6f4729647cc25af2431689ef7bddd79f82a4682d6d1292fcd7922a697a4fb8982d26680ad4af336004af74b34bdb318d0fdae9d0413065d47a5202903a59cb033460b3d88b942e5f611d542fd2e8b9c9d300b3b153f43efb) +emitted operations + +big_map diff + + +storage + (Some 0x07809251bc1b99439e63008e8d783acbe2fde93625f4175c33db220d96c310931753794535e47d84317de54b035582e9060a1f49de845f3f870a46e7e8939bf2d387f2e6d87f2244cb26b9e153723629d92adaa94f46e1be7458fc45c556fb0c) +emitted operations + +big_map diff + + +storage + (Some 0x0ce4e3355f0a5df9eab02eecb2510de9a9837611481d4fe8e5f803e7c60db5da63a1afb13a019a0f1f199d0ffe87297c01d5cbae9a4df48cef28ab34c8e2a684b1601fe30729e2512e937eea6e4071fb715926508fe1efaa9edf0633a1057718) +emitted operations + +big_map diff + + +storage + (Some 0x1358174de7b56cf42eb7d6ffe1ed41fefed8bacb3b18c88925e69ec8c51992ff84942d2d468d49e256d77c5d38d9d71b016480cb05ae9ed0c549b8446e9366493ceffc9471c206a359d8c9f58351ee2f6292208442baa3cfd09813af73d0b7c7) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G2].out new file mode 100644 index 000000000000..70e3c1799267 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_one[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_one[G2] + +storage + (Some 0x08fefb71e4511ed0d6a3bd0409725b908a0c192d13307a72b1c83e586f534897e3d2a7276eddf2c0027b44058e5da8e11911a8bae300eba2295ae0121dd9f78d2dbb3fa6f38f397b8b67dfb43d1c7303e699925597f04c463c55e625b66d0c02107220b0a6af8b1c2f445c396e3920a573e573b90d51d0d7e3baeb7921f35a261a1324fa74cb05cfc5dc3b09c14ea2fb14e0c74a54dd945b8256a69e2f72c084e54e29ba8b0dcaae61f8dded3054c47d0e96eee36c0bb002d2803f7b51cfb96f) +emitted operations + +big_map diff + + +storage + (Some 0x0508c45054a19a896a24fc4cd6f35ff97a3db9375bcd489f2737f4182c6f7dfbbb7412497f3609d417e44934c4ac10b717c67161445629d6d7532e40929c795b8b3d672a053cb59408352c24d5148e97e807dfbca83a3fa49a629b4a00a5a79c0f2f871ff459bfe82b647c864560019a5894f7b0725917bded14f81631f4df52cb88e0d72fb0503d90a562f7b28f49cb00ecf93cf750fb701e2e3fb50a7f1ddb205562a0c84097c241a0491785a8080fcb0340842eb81908a282343ca94c6d38) +emitted operations + +big_map diff + + +storage + (Some 0x128b9b6b5677981632671b3a4200b33265fe75ac2569fd7613357b59dd740e2abb342cd40c3f7021972c2b85a4cc9f680f7e28d1c48fe5bd039569424c63eb9606e7199bcbaf81d3b45ecaee9f469a2278ce9b933961384a21cc547facaa61cc03b6424ecc1f5d20cbec956c93024ed9153c2c3862fdcbcaac5cd2e13806f6ae2ca4d3253b7f712b54c879e26dbf3e5807f58735263798c2c6bc07be9012e4eb586d64021ce5a0ad7ec6dac72224f7a121f2630f07a49e4ad438e359b72c16c8) +emitted operations + +big_map diff + + +storage + (Some 0x040323c862873989f4eb7aedcd6cf03d9c4e6d89fe86ab05767f3b10b988fd452383160f11559ec04b6ad10fab6765fa07416b61c915c55945811dec59808a3640b58243bcdf79cc7d8c5c7b4769118e86fbb5cd9296b6ea8b1009b309f33f6619c20ac87938bd643e0d8fe7f41a2f7fb89987340cc557beb9c499b7ae0beb651d13a16b55fed41e98e8118495d570e3165305df86cd00ab6b884471b0c89c2099731f613bdf07fa5b453fe47edf688b7e340f24aadef705903b4c0abe322a90) +emitted operations + +big_map diff + + +storage + (Some 0x05c66c2a9cd7bff629a8be6b6915f8cbd5b9b50430ad9f1f95ef83df93a289b14b0c069a45e9a3083c8091222e3f44e30b3ed9b7fbec7939db06aad0d5140c7c4933840deb9a514e568e2efa86a4ba835752a6ca91359f8dc20ac43f3fb30a3c04f8c1d1e302d37a0ddf2f4cbef9cc2b317ff16dd818725cb0d0195974992b14ee683afa06101db2acc697ac3f4202ef126995a62e8ae1dff6298dc9f768ab5a183d3a00cc56c81bcf3ab05c17087e66e743d559a4707b23c4b33f484aed3848) +emitted operations + +big_map diff + + +storage + (Some 0x03c9200acd88aa776039333734833f04c3673ef47f8e39ef44a98489a3683f6eb75032a6a5e134adab3b0c06931f444c10c4302c59f70893d23492c5ab767a6f60bc5521aa4ae879706b992726ce64cda1187e26ae2fd0cb3d05fcfa3e8f379902765404f27b2d4b0e22b20cc86a9ab7f0cd3f3f13fb6863ff9d4f26860c3905341d1a267a738e4385270f746afc93260fb6b00fe51f9a34c77e18e99d2c6e21c653eb82450e5bfb2d0d9a40d5e45696a1e1b4e32ea747f1e87500177b67e37c) +emitted operations + +big_map diff + + +storage + (Some 0x0cf8aec4898b6cf6698e74551deb9aac87a11dab50c7a3cbc69b2c4b4b230e9cab2290f2135fc365a6ed4dfaae5504821866a9bc35f182f2bc41a5bc2e4b998385e157bb9b7aab5b3722aa145b45681c85318f45a754c6c324b8ed3be1519ac013f476059991edef5732f11ccef162d314a7eae6aa22d8ab1d63a9d7207bbf3eb73021dc2f3562a7c69326de49e44470106e5429bda1ad096008838511176e879d4902b41cad20ac87bbc36c0d79d424e2a396893566cedfff341354fe901619) +emitted operations + +big_map diff + + +storage + (Some 0x0b9da9500e096383beb19b243b5d02ce37649b33f4e1671d649d8804552882fc1eee23f9fd522b022cabb4c962f73f0208e73a90df86cfcada188576f7f9d0a68b274aa0686402cd6b9af6fa0077d090c7d876faa1ff8222d00a8cd137ba02d31751a64a107ff326767085a8e486c60b604fa734c79935604869499ca2c5a79a8d37fc453c48cd18406e1486b7169445020494338e65c0db9bc80313cd0c4f8bb0c3d797e2a043652d5ee3a13e9ec97b6caa76b139d9e0ca05dcce3318a0ac4f) +emitted operations + +big_map diff + + +storage + (Some 0x091a244f18b87030e2b863c4229cb5e1afe53134e8a49ef8381da6f9a6816bd811cc485d0d9f4af8e702d2473367facc10c88b308cd546cb4f17a41ecf063b1326771b8b06099c402d787fde9f0cc13e837ca584134f725fc4d257ae04aa791d1100b618548b45488a0a0c52831f0f6252d805cc24118a8077d3985011d9afd8524d0dc630fd9c9279187251aa699bb308c895051974015232739452ad614031630ec533cae1f874210d39fda10a3cc34816075703b6e1c7f2902c6afad0518e) +emitted operations + +big_map diff + + +storage + (Some 0x1401fb979d3d7ba9f9b7464c12cc4b299242008ae161e00bccc6d791f8c6c69475eced6fd21f854e1f10e479af46730d08f0ce149b481d41e0862e195794d641337be00ad3ddc17eed2a107d6b20c8abfd109e0f75416f8d03059aa54e1b5c31170a0511c66e5557226619e6d0ddeb786b77fbc2a0e4125d37ed956db6f8eff7238e326d4dfe859f452b9082c21be1c60aec585dc2296b6ba5c10d91ab8235cfa1aa64f11bd5bab8bd9d929e6d0d86e8ce126617376551bc613366fd6e4ded1a) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[Fr].out new file mode 100644 index 000000000000..c7f2b0cedf60 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_random[Fr] + +storage + (Some 0x32c59df1aa60931c6fa6ff2b2d3358ebb570cc673b3519afec797a9a4dfd7427) +emitted operations + +big_map diff + + +storage + (Some 0xf2bff685b56f9e6f601d6a12abdf82db11d0ddf088620f605f873edacd48213f) +emitted operations + +big_map diff + + +storage + (Some 0x49c26f616a9483bbcfa389d8cf7fbe992621180d464407e757114a0804103f1b) +emitted operations + +big_map diff + + +storage + (Some 0x522f644c7566b3ad9445a0ac25b904b76c72434093ac409435d135f6e88e1431) +emitted operations + +big_map diff + + +storage + (Some 0x9efb69b24f277cbd42e5631c2e0ca566bfdaa9d27aa9608741b691fa01ce913e) +emitted operations + +big_map diff + + +storage + (Some 0xf0a71c2682cf211a1c325c530d0505eadc8a18974dffa4619e9b191050540c68) +emitted operations + +big_map diff + + +storage + (Some 0x4b18e93c841b6e6145923e527fd4fc35d6dbd6efba45745dd040a212a93d2d6f) +emitted operations + +big_map diff + + +storage + (Some 0x0918faba389d8ffb1b18345d62186f0980efd1724b792a9fa84e037513b4b165) +emitted operations + +big_map diff + + +storage + (Some 0x9806b79c2d171acc44814af407331430dc012ee27c5e52ae4660e8a3ea967242) +emitted operations + +big_map diff + + +storage + (Some 0xbeb8fa12abe52ffa9fa48d73d3c176a0bc3f8be04586f86dd456e3049dee0428) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G1].out new file mode 100644 index 000000000000..ffca597ddd9b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_random[G1] + +storage + (Some 0x0572db5547103186bdf2f89953627c1c6ee79da42909470ccdb2b3a63d1a56872fa3f3998a53af08e34f6cbbb5d2ae31134939f276ca6eed853a730194aec002dcda3bb02231e12852a23d52665bbb4fd4c9ca2060976768f294e3a651bdfa24) +emitted operations + +big_map diff + + +storage + (Some 0x19bf076ad1697fb06e3006ba85b7299a58da677178781306ed64bfec71f97195e0fe8e5bbf9bf9f130c27fac85cf0ae102f80edcfe8374130006f99a0415e7debe4e2452084af7a92ec6b32a3c23acb1e936098bde4e99ae33d5bd4f098189a5) +emitted operations + +big_map diff + + +storage + (Some 0x0f8a8b4f0e2bf9e5612e906f9dee13de3a4a86a78779579ae0931938c9e33fabc200051dca4c290d3cda64c46c22d65102bbde334d33cc4d9b77b220848ca969b86a4d3fc828ebff8c154f8606a99fdb6c12f8e3a936b7f717307ac66617c155) +emitted operations + +big_map diff + + +storage + (Some 0x168ff86947fb37c511c29b34cd5683045eae063d394d4ca6fb478be51fd0d51f02362afa2e5b829e161744b0cb44537009da2ef5522ecaca11925bbca35be447402f2385fdb000647b0f97fd957706ad54a89dccc9d91a967fd7d3245699ce9a) +emitted operations + +big_map diff + + +storage + (Some 0x132714e690347a4818aa28078c04a9fa00af5a874f6e384b3c10385edff00b078fdd9b2d24756216cd221fcea02836061565f5e4903c19654928de543888be273f11954cfa069ee8b7b28f1501d723b5cd53a070c99976789683a9ba84ec3f88) +emitted operations + +big_map diff + + +storage + (Some 0x1160d2c1a9468460987e83389d2b14e83da2203bccda6af5698088fba85a70b0f81338e7266f1d2aa35c0c9fd90849cb19271f959b22d25e9d39be01e81ca28cbfd941681141e8494cc53eebf0fed66cf1d9c25cff0acb79a9c8de89978d665c) +emitted operations + +big_map diff + + +storage + (Some 0x19e4f619ba2bed08319d9c6d8233ac67992f979a09c1c2b578f6db33160da265453b6534404273f58b62b465081f177a04b2b5742855d0273a9a4b285040d806ac3c9b4222967dda1ca5b15b701e1cd8ea6d903ba3de1d4b772edd312f5f0e4e) +emitted operations + +big_map diff + + +storage + (Some 0x11cdd047200409941c0c76b6d3bcbd8e213190b4a0129a7bca64383d7574b41465771ecf903dec7f572dd4363595be400ca671f579f590ce3014426b45cf4ad91eaab36cc69b4d594dd60c3521ef037eeb4ecacc4449aa71f26f434e35a87746) +emitted operations + +big_map diff + + +storage + (Some 0x00b2274f474533ac0db515a0e9dfaa821f5da4d22602adc3b63757e0258b237710273f0385067c920250f3ac93e58c5106501678f78b7248129687c46e47737e9737cb4b57bd37495b2966b61239e5fe91946d65c19f948d89a2905f23ba4b33) +emitted operations + +big_map diff + + +storage + (Some 0x02469c3272ed5ff2685c19feeb227f6ac7fd45eef79266e78dc17bc53930ba5b754f94ee6f07c28a0be5f7cd63ba616c0cde39bbdb8e3add322a8d0ced1627e2601442dad06a7b1c0fd9ba9e08bca8866913f0336de0075564dad5ecc63c6cc7) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G2].out new file mode 100644 index 000000000000..a14878b6a203 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_random[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_random[G2] + +storage + (Some 0x14e6a70d1e489c9feeefc7314994b0207da500737728cc2cd17919ed6d5eae570622815ee576563c25075fad12129e900b9764ef6332c435e56a57c1a46b1c427889456fbc01b6e571ea995e925337e6cdff2d062520c61c52d2377e773ba34e08bc7961bb8618eb9951954ca98d01eb69e56e04d16b7a2c21d8cb74ed0bcef735fdc43e6939c4d4194958ac1d5f70d41407d01b8bf34478d970a86af954f0ec67bad1a95c43ea118b8ae2e9ad7053cfd92b0058755e4dc1128e4e17476a8653) +emitted operations + +big_map diff + + +storage + (Some 0x071616c0847497f2acd699cdfa848cd50527971ba6d99ab2debfaad23f658f233c262e78e4f841e4e24b16a981b46f5b13b2de1c75de619374ce4715cda6598b7603c474f4bfae3201e26ec1a0ea4dcac5bb859067aa907fd113cbb8e12eaba0099bc61dfcb137a7978464d2c4c2db5eea9dc673857ad8dbacaf8a30156c2495bb0f09dc5e6b66c9b9a5245a5dd99afe0e9f735ed6682f0d92af05b3f965697c1e8f4ee5aea15caaa6e6905db608aa78c788554f1d63bf1781322ca089a73226) +emitted operations + +big_map diff + + +storage + (Some 0x0bcb3473d903308ecbf86e3d7339f636944b30ae69b693ee870ce4313dc5c678a8e3efc782df3c143200fc9f9c74da9805e4d15ec9fd45471f05f6a89c234b4bb353f5f0b59ff1c32aa0a53e3cb5d00d2f1a4bbeb26df8feafc8c6eadd4271ee0a479169a73291553225df03876a1cf264fe9fec6c1d7abb9498b6e9fe6f68373dfb11c897c8f4587bb68a73348624dc114b4430ca48f9e93c2ffdba64d0200b6213aa1c30dc5b8ee1ada58f7d8f17209c80a0638dac2d84706bb964d5adc810) +emitted operations + +big_map diff + + +storage + (Some 0x02bfcc6cedc5432b3094b3c3a07f4f5605e396779c996fc4451a148626994422aaa2813f25e971377cf4a79199e6b64c08dfd812339542c370ab0968994699fe11be923f5ffdfafc489e92f00aa3e7b346c15a216f4756318f2e275c1add44b1184926b94b03ff641a4dd7c48a62a8bc95db0e10051542e64838e919936b1dedb53eff5aff762504b52e7d7f29038b9807052c826bb33a2a63a23d97f1ae4631b78597169d5a8c5c7b44e76a9612b4caf931cb991bc50c400ca2dae41fd284bb) +emitted operations + +big_map diff + + +storage + (Some 0x199dae008159f71a8766dc2dd36b38eea3cc4570f53c5a75e1c634104c2de1fae8d08d82d746a32620f9fe735e1167c20dc0f1f29d8cb8c7003a0134003fd6bedbf06e3ca40163ade57d7c58134ccd178132839a421a0c54e4e3d7f1f7f6f3c302b2e86c3571aa93f060ac296490439624e0a65c3793ca193d12a87dd59d9db0ded93cb48dd1bdf2c253d512fa8740d40c60c89c6f6f3d0a1e031e9cb792c42988c5fd2df05221d44f0b98db56fcd3fce8dc52f7aac73e65da92a97edd38b871) +emitted operations + +big_map diff + + +storage + (Some 0x057b2871d7a164fd1ff36b65aa26203e9ead4073db80fd3e65cb11f526c3a36d04fd5d42d77f2eaf8ecbd87d31860ac60702affc28f09199509f4bcafcafc555e2924dc7023af9663d5e2add1febb92f274f7712bd50773cb3c21e058e06842911a67737914abdeb318d01a4dce9de50cff14a385c919d69f2b6dc9a4fbab82e4bc73ff153379aa09f44c9237c28a97b194536cf4ef1d033722ee02f2da4fdd2c22c6aa5876eb5e4632f57b86c9a5b1a750a6ce6eb38a21c9ebbad3477cc5081) +emitted operations + +big_map diff + + +storage + (Some 0x0f560f66aa318954f1a715277e07586e66ad90e4cae0e3cdd99a927c59cf9dd4fba60a1ab352ce417440e078116f8d4e06102984b8bcad27f90712873b678249ee83a01a30b0a8feacfa2bb4b068fa0f0342ad55bd269bdbebe7c5cfd5769098084ea794e5252f7cf5b0fd10db3a17f5fef9c3df9418109b9a269790dc35ab83821d39cd373dd26a60fcac49f57f1372111b5f5e8bfc1c2c921545561a541a1fd6f3e7b5dab870c16ffa8c41a8d1cc91d148f99700e3968e0cbff2f74b4613e9) +emitted operations + +big_map diff + + +storage + (Some 0x12d73c3ffbbb0e5135c89aed8a0bb246ac94ba2ffb79fdf103a7c9e71bf09b67fc928fef16c4013b45b963bad15e0e020c0635fb75638ffe385e578e06098e1ea4e5697a3850fc31f888c7ffc8544c4322ab5fda30c34b6959636ce6db02998b03c35b506840723cc3bc4788c47e64ad00ccf727581c76898bf1b331860ead87f9984965c6ec515f0b2ea1bc1a1aad1a0e9c8bc1799a1777a8acda5dc68ae83f7200ad998be79c35f252aa1e427c0b51c9fb463665acb7e7678797a0e0677659) +emitted operations + +big_map diff + + +storage + (Some 0x12f203deaa2a60bb330227161f38c0104c92c1598751bae6af52102dbbd6c9c4d2ec72155b9b4363d90ec83dc7f9a23a0fca208610b342d53abf1d5729ae6e39806844a6eef99c0df4bfe6eaa8b1216c0dc9e4d9f6c4d1f7f8a323459aabcc78184bf83ce121264be8e3931e50275dccfeb4318b1d6a834fd3e5df9b0f33748ce3e88da3bee4f3111f3c0787ac93891c073e576342224498c6c3fd5055bb3c33a8165c56dc6829261511b573401e707e055f9e43b1f29307ffb9959fb114162d) +emitted operations + +big_map diff + + +storage + (Some 0x1636bb0aa543964f7b8b5eb9c79a168f4840befc80a40b98716f5be1c85587c87d541df53c5344fc43fd59e7bef0192e149733e479d7e718938a4da503972a834f9e2b725430a3349f1d8359add70c286d912d26afdf0bf9ef72290cce771c9e11bd93d75a681fac52f10efe82c86b2a6e08a154ccdf56ab2af2c199dc9519ed94bc7aea2b2afec5cba663652bc8906c02c0a16e0c8d7ccc739dd4e0939dd5438ee244b52cc7cc22b3711c5738ee6a110442a7a75e8c5324b2e0a2c9ec61c475) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[Fr].out new file mode 100644 index 000000000000..0fb71f1daa1f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_zero[Fr] + +storage + (Some 0xa739fa15d114468388738a042a2d5c1697ae01687088c0f12b1a9aa08e8d333b) +emitted operations + +big_map diff + + +storage + (Some 0x90d72fcd8feff9474e2e54b4b9dd25693f4165bbd63e9fb1df790005841cd138) +emitted operations + +big_map diff + + +storage + (Some 0x1d88e731f9ace2515da1c8a180a91edc5a582ed1c55d4cfd32eec3124afe754c) +emitted operations + +big_map diff + + +storage + (Some 0x239754a5133c74f2cd2e055471a52aad9bf61d0cb8d87c1a145e52fa4b623471) +emitted operations + +big_map diff + + +storage + (Some 0xd96f5c434bc636ac77a076276cf41025130b480175d4ac3b89b492fe8ce02a59) +emitted operations + +big_map diff + + +storage + (Some 0x55da36ff0ab31698692128f58826a17fe737a5de292b3833f84f6b2dc088be48) +emitted operations + +big_map diff + + +storage + (Some 0x8aaac27a92aca48439a67deb4f7d04a291eaf8df409a966a5cc5938a433c8e46) +emitted operations + +big_map diff + + +storage + (Some 0x75c6cc6c226ce12140160f0740499913a5c2c4788868273b15dca2bd7a6b6837) +emitted operations + +big_map diff + + +storage + (Some 0x800a55193f60eb4de95f6c29ab095ac4f3f1d21a1e90096eba89c4c00f2d8a31) +emitted operations + +big_map diff + + +storage + (Some 0x995fdb626195b85107a30d8d6106e7d8c46af3c8f3f6be0bebe198652d2e6c00) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G1].out new file mode 100644 index 000000000000..9e6952939b3d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_zero[G1] + +storage + (Some 0x0e134832be250ddb5839670997abb5d7a89811c1335e7db37a321efe001c35422abe6a14ac850eea1acee01cad17c0330c5437362450b8d760a2d1f0e07fb3dc465a4ef1ceb1b026e6314e5a53a7aa4e7c8e5fc77472c691498680d465c593c9) +emitted operations + +big_map diff + + +storage + (Some 0x05ee99471b023ea35057440bf490170def6356133c85549b45895c0a14f45e450fe1fb44305d57a417461cef5a7132ea137b46dde47bee6177d3300341999d6d3dc996d19767d8c30b8b8425b34230813eda03d6db53f8f2b5e2ac99d0d9aa4a) +emitted operations + +big_map diff + + +storage + (Some 0x0e8cc3b0289c1ec90eb49b97da831d4d9bddf1d3ed02e26ca7328ad618945ca288e736aa7c7c06e59ddd34522765eb5f02ca674a5dffe0aab83d25086876d5a87ebcf4d5903125a8f5c637f9ae0618a1f682d5d18c0bfaeeec866c2dbabbe41b) +emitted operations + +big_map diff + + +storage + (Some 0x16fddca3f0f59d49ba43f6861d71d8f4353f6d43899b14311f4914987ad0fb359cd4048b9dc8db6378e302107296037311ec2289dac6db85e45d3dc93673eb3104711664872dc931d4cfe6fcc6a4afded609a738759078d371b5538436180f24) +emitted operations + +big_map diff + + +storage + (Some 0x114f5bff07e03161a9c9fdd20fbb672a71a9aebe2c187e821d4005129278d5d5c195926c7718afda76194b35943339a00efc8c4c040e9b1dbad9ed20768c9c62e4dcdb680bc0add60b218bb42328a116d3e43d579024dfdb4df0f1f0c016d8ec) +emitted operations + +big_map diff + + +storage + (Some 0x0cdd83bdfa776066c37697324ce0a444d064ebb079d99fdb2c03e63563030f824fa95bc7e1c10ad14cd6362857e9a0010073d89e5fae09c29ee2d1a6e8770f7c5a19be2e2e465a50539833b1a463e24d3ea02c606c5990cb8c892200b6e3ec55) +emitted operations + +big_map diff + + +storage + (Some 0x05a3fc74d5c1f3a883631ef0fb7bc08705e85b62786f2d61560ca231e6f7178d10d6c9a97ff5ef4218046e66f9142d1314d8e28bbba2db0f505669a31b4ccb4cb08aab73e175871139b2fff8cf687a0affe2463f0cdcc88f51a4123434533e79) +emitted operations + +big_map diff + + +storage + (Some 0x039b2ab4cabbf7bc5d0851aa4034d4e478e6350a6508d54fe37232e92e5b673ba1bc14db53ebdb317493c9fb3089a25f0ffb75f9a4da47eb6e54be326a07dd56cf8b57a52d49892669f79922569eebedd0848b172deb497b959855b85d66a8c6) +emitted operations + +big_map diff + + +storage + (Some 0x08fe5a710347c0b1a5f1f61c9268778af2611a42f883479e289f1ae28ae1c15408aef3943b951c8377b6a79faefbfbf2150c7fa5f938156c3d8f27b7f5e5143220f5e0752d762ab54a53d9178f4112eddebd4daca6a585cc469be1ab4f5d5ca2) +emitted operations + +big_map diff + + +storage + (Some 0x00d471074aee131574be07c9b749d7bbd09234578fb2acb4a248e6583564b341cb55f2a2b61a227a093a0dbd4bdea67f190a01cd3614435914153e782cf7332911ad79c48a1dbcb8072063f834347441530091809be2c15692b8c0b98ae646bb) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G2].out new file mode 100644 index 000000000000..240be454e6d0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_random_zero[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_random_zero[G2] + +storage + (Some 0x131c7f76cfde58ed74ce8c26a4e9c6a6e135fcee1a61a41e5c0f2f33a718d6bfcfb7de2f43d98608b68dcca040c217a6007c5a33c5bb8d523634469302348d23df90d150b28e4f41f1539afa50adf951126233146e4dc98d21a0de35312571b310696279b7105aa5830ef3cfa6df1ff1379f17b24ab561c899e3fc830942e23a4b73019b1ef5110baa4068ba2e8b4c2c09e3b16b0894333f41eccf24b96be85a0d17ef071657b1abfd6fd0e7878aa55d3a5446a9c0ee5b5c293ff8d3cb4722f0) +emitted operations + +big_map diff + + +storage + (Some 0x09de05cde8a5a7a1328aac8335bce420aa41f1077e3be4aa51f93b3a8e822423ef67d263d8042a65bcd89e0091a6b3dc03727a50fd6fc80ed0b1078e81560e759b8013d48261a2cd0e65bc83b9a37cd8e952bcb6a63e5c9ac016d7d588915e0d0fa9247132b7488528ee8f136bc9026f8531c5baacd1647a768bc801e726200b34fcdea976e82d1633e1da82a36cec580f8f3e197860bb36ff010e747a361c54f11003d33b6d3c8c29eaa13be92034b2d9e04a1b6e81fea1911fa8c8b1010b8e) +emitted operations + +big_map diff + + +storage + (Some 0x11d76ee03154c0ee80237e9d757e5fc6fb6f0dff68032489db4edfa4a79d4a2ad8af5854d1b80e5eab6046d236bbc97b16a1dbe3dfeac51233c05fb1ce011cffa48dd38b052ff81783cca048ce5d7c44743a57feceee2512aeeb75344fc0123a18459f774f0e6474bf80a154a754e3abfd281dad0a967cdbfe25e98e8d0a22a41c41f0822fffcd3d92a519b40d48f9b109f79370c21568150d9dfbbdbb3187605e4e675280fdc6de9689de0c82083da87a4a776efad2beeb2b2a8e238faf0543) +emitted operations + +big_map diff + + +storage + (Some 0x056ddeca0596e44d080a38cb233517d706f5529482d8e7cf5618e2c1b17222bb3cf9627173a05ed34c19e925244c775d0bae3e10aead5ef97474d420845b1752c054222387e5767797f2ecbebee3f002e930c7ecc666719760a2a7625590d2261360cf5c50023104c36e79765707275f0517283f1834b3b378946f48675459342b701b5d421af115764b639736ec666712e9e21a5028fa9958afb36e610e74bbfe0db03a3147409e11b2d12e45513f0ed91cae918ab723773aa1d16956754b7a) +emitted operations + +big_map diff + + +storage + (Some 0x016319cfc0cc2f9682f2171aee2448828d2dae206cd4eee18485d4d528dbe42d91331c54b99071c54f60852279bee33408843ad79e654427d875c5ac932a82596e88bfd0ed1e7bedeac67cd6d260730a1bfdeb7ee072c10bac1536b77b89ecb614f3b216d3ef4cbf7d12fb26d61e5e3b50ef7fde0ec13311606c55ec631935f5abe99ffced1ff1879df289694091866f088752642b4791b742acef63b6c7068f2789c7a5c37c5b923c9f855deeb15af919537ebc700f0754a5b3cf76a4aeb585) +emitted operations + +big_map diff + + +storage + (Some 0x0487d5eefd82485134b6dc3eb070ad29f24b283e66b21b7ab89dc9837833d577282d6886900daca411e1251851c6898a14540427013fd1777ff4bc6caa17c499b45714fd944c23123c21996f08ddf9c841be93bbc3b427f3e97bcc96f0d2dc80076e1cf2b08d1e061e5dc05d04a9700f0f498c55740cdb07513113481cb2be4ec8b2445c06207bd49199f8784321e3e6188f33ed153ccd194cce9574678af873a515e2fc683d1e949131ec946e212e80c4b48876ac5b4329ebd66e30c3e64716) +emitted operations + +big_map diff + + +storage + (Some 0x1825a997ebad0d60dff12bad0b182818c5939c85bb90df49815f161f160c34b007b765d5f45bf8be5714f5687e8ed52d0067d80904c49cf9f9d7a6f6b6748ef1722a4fe7e5c3ad6e4535188dab7b4fd756e024bff36798349a6b3796d4e0eba00e4a44260a6527af74bc062df2fd3d922b04052e654483234d944edfa3e81b9432d16b804deca1690a2a6ffd276fda7e0f427e3315cf2555c0d3d146715393a24939b0bf36d6284c672a212f7e7902ee2e873281d396290bf26af6b3a330f058) +emitted operations + +big_map diff + + +storage + (Some 0x14fd9f5cb51b90075b3250c91c45be2eeabc425584b7b451539f238c191ad58c6c364020ec6a8ae1810fcd6a894999da065bb45ad11327c28d9bcb1fe85d45b10a2e42fbb1f3eef622a8c261e52ae5207840c8805fd2b8448c7f97aaff8bcb710cba0f99825e190b5de72f359c21058d3a17a30799f1d1552dd1128aeed5ef96ba586e62fd71a004cda332362df3d70b15816951c6070599f40ac6a1bff7d8c21744f00da365ac6c2b81e7abc752a01736e089226911da70e7b908a130af37b3) +emitted operations + +big_map diff + + +storage + (Some 0x07c239bc8ae325e0ea294eb2d7a8134c9986099cdae78224b2326f9d419769b065570154776fa16b98c1b5bf2f69eef41403ed7557754558c686ad6c00cc61b386f3a2a8185d1738e9c6ff6cdf9353ae1a30265ed02828a2979de0e8f10b15d3087901b1d719a2fdf367564719fb05a9196c282f244ef434090e39ff091feb12c45c117c2d68e36e8bf37aa7b7847213110f3424cea97cca09e3939d418883ef7f394715e5448f833fa0ff61ebc8c9d9fc5ecbe8d2480f4955cda3097cd72289) +emitted operations + +big_map diff + + +storage + (Some 0x070a718668a1f4e692191f9a7653827f6051848cfa72df0c3e99fcffcdd9e09267f8e6711948b43565699d4bf02feb0f0faacfa8e44cb5c50d2d07a54c811a0fb86a1e0f565efe32ec11bc147ec6f8073067c6330afe0c5be6ec5962921f58bf0b97bb667d15b6b0596cfe29f41fd994c1ff7332dea6699dd72f828593485a97d72f8322ba503653a6a82a42dfe68eb9166bfb6fe8478bea584d01d252c7e256bbae17b371a8bb87916ddfdbcb28ebb7f4670ce1dd3be5067e38b0e9c9f17140) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[Fr].out new file mode 100644 index 000000000000..c0a6f8b6fce7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_one[Fr] + +storage + (Some 0x0100000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G1].out new file mode 100644 index 000000000000..67ca0a74ca9d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_one[G1] + +storage + (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G2].out new file mode 100644 index 000000000000..f8967f511039 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_one[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_one[G2] + +storage + (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[Fr].out new file mode 100644 index 000000000000..361bb212e04d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_random[Fr] + +storage + (Some 0x6b1f61b3ffa8e49f9a840c0f4114fbc6061bf98a51e51fe4a396f041c50f5e02) +emitted operations + +big_map diff + + +storage + (Some 0x0e4c13a518d43c1a04ca2b7b16ca21d8f2443a861e7b6184a85cee5892916903) +emitted operations + +big_map diff + + +storage + (Some 0xa18e92f24830c77e59167062c6e8b22c08b86800c498b932bffaccb68fa1b934) +emitted operations + +big_map diff + + +storage + (Some 0xa91c486e8bdcba53453336ed752ef9b214926a2b3ab452552a31eda0ef3cfd3b) +emitted operations + +big_map diff + + +storage + (Some 0x0b9fb344957ac93904848f30fb9c068ca7c9cbdd6006445489226be02676026c) +emitted operations + +big_map diff + + +storage + (Some 0xdad4e76170b71edf3c7ae65a00659f332dfa08e9d2cec5a632f8100cf938ac62) +emitted operations + +big_map diff + + +storage + (Some 0xdcb9d72844fc8c9d4e25acafc2c1945f1f8b0556817c333f0e6c0e5c932f4c5f) +emitted operations + +big_map diff + + +storage + (Some 0x53745aa1b2b2734a0b038307fec0d0f20e6ce9d512a4ccca1ce49dc8b294b93e) +emitted operations + +big_map diff + + +storage + (Some 0xb1cc9dcc3ba2a71687b388d23758da47c067e1fa6f0b185fd5d39b9050416a12) +emitted operations + +big_map diff + + +storage + (Some 0xdad6443c3e503dc862ecd96031f0f5c40fc4560b73313dc153bac7118338aa14) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G1].out new file mode 100644 index 000000000000..d43d9901b55c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_random[G1] + +storage + (Some 0x043d39d06dae5a1faa8e462a13a7254b8ca438e47c7846fbeeef71e44379e7df2e29613e18d658ab0da4547b4f3852590831612b23e928a01f20857216d823ca7c5e07fbda46923ea626380c4c95cc2046b9b228ffc599eee8ae2788484a1e4c) +emitted operations + +big_map diff + + +storage + (Some 0x05b38be001d64a2d9e17a27d90e29b9f8f8bb28c7c8720371e7f72612f0306a97162cad563ee5af54df372c89035a2830404865f74dde79ccf6640806f47cfa66373656335a4ad64cb383ee44f339707678730d141cefb643ae5a7ca36fd2b0f) +emitted operations + +big_map diff + + +storage + (Some 0x0f644fff548f117895a24c9e4345c4dfb995caaeb5a01c1bd8092677f0dda287a03d7c86b0cb50a61739e21a5950de540abf3818624bd6f162d808aa8ff6b9993ce584fecf10d3aad86ef521545f2b5dc76839620e52d27f42fbc7d9e548b250) +emitted operations + +big_map diff + + +storage + (Some 0x0dd72a72f8dc7d26d4f54ce50d6bac81bad784cf2b886d5d2ff66a06f5358e945c5c70b81693ace7d21e6fdf8db436820d5f1d73d015e5799f7fe9a1e4068fee0e6874f3e8c56f85f673e0b1cba80511b1f4bbc02d8461b2919bf8cdbdf9a051) +emitted operations + +big_map diff + + +storage + (Some 0x0da1488962b00f17e629884dee4f153e0a717af426bde7c75da0f5067ea5e63297ba068bc230e5179081af8a23c5d5b618f5b3bdae5915cd2724687e228a4c1843578a0c2aa2297031745fc1f3b77024851cad2bdb815197fbc1d76e7dc17e7d) +emitted operations + +big_map diff + + +storage + (Some 0x153d1e9eaba3bb00055584ad97fe9b49fa83bad011d1b97598bfac9db9c54a8ee0152887ddb42d1d46ac4d4ff97da3210e5d38c8b1f74d70b56e94f953a289ca8604fe6731498987c3bd186fb24f569a0c403c0173dfa6765f1cbcc75248547b) +emitted operations + +big_map diff + + +storage + (Some 0x0165ba92201bc7848e74e23c842141407b407f09ae7922e01a290c4268579c84f2a3bdc20a8a1005e9669064ad2e634405e460b2eb3026d92cd2833ae7d1f5a009756ac91c58f2ca88a358c9312de31f9caec97acad38cdbf9f1f8c844ec23ee) +emitted operations + +big_map diff + + +storage + (Some 0x02bbf3966383231f6c0b5a0fd62240867a8944331afa0c6d06b5f1bf83d3c2eb5a37edde3f51860afe887526e343fafe007cd4b0abe3d4868391ccc730e997525108e17740b0edbed0d1cc15bbe411f33e35232ae16e79c77b6acf22ae67210e) +emitted operations + +big_map diff + + +storage + (Some 0x0ec1ff5c67f23f47f82e834bce1d48e56e76b78f42d7ee530e660718c3cac29f207d58aa4c231376f8a8ea4951f37d680991eb20bfd4c9033acda6621b2861bcd983a1066f6add9510215cfe0e66485e6433331232d37d944d1cb56230727b1b) +emitted operations + +big_map diff + + +storage + (Some 0x0b020051cc583ef24590ef0626e7bb42d30556013f5b490c78bd1c689c759e04e3865f04b6807f9b7a52e4f4fd23a4a70684f9d93f58388210075b8de217efbcdbaa41c4c7126dc925c1263d36953db065b15d7fbdd248857651db0f6229ee89) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G2].out new file mode 100644 index 000000000000..29566bb593a4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_random[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_random[G2] + +storage + (Some 0x0a8801dd5d45269185fef3af4c71e27aa302f843c4f75ce58267d5cba2588d63e240629f85cb551fca316f32709a3c6e02487c3309ffda4098b64d73d16074121a6a8bd6ffe89151c45ddd7381e05b7243db96e4f6edfa06c57d0bb0265b20bf03d1c067162e0dda121fa11b9c7dfbd14a027f8b5af1630ab703a146b9a5ec97e820133a732fdf0f438814a693e77a820edf72b5820459bcb682af727b7590463ff39b863dffd2a9839fca3f6530b13942c53a5ba928be5b039b125b88716729) +emitted operations + +big_map diff + + +storage + (Some 0x0afc630b73b1d1b407c89c797f07acf80710dfa9ce57b46722e7dcb8a43a847341372d2eedfd6c2a3c42305306ed468512fd95cfceec1194d749b13948f699beea5b33aeacb902d2e12a2b65e9589c57d26251b350edd142cec634b23a7318bf1553647560e99b285b82153ba4f70fb7c3f494fe5cb65c0b7f1446adedc646d14628f45b4b8d7a22510b8551490b04cf0a0103d13a5deb5d68d32a85189cccf1134dd908da9ea8ee034d067f729d892bad11a45113f0e5f5ab25c021759417f2) +emitted operations + +big_map diff + + +storage + (Some 0x0b8026c50e2cf76e4fc00cf25ada386641261fbe457250746098edbe44d28eb0961b4f4aa7d3d3f65e0f3d0d92a131ef17cf0aa479c55d0c529b2ca05b8488adf9dd829d91f0bec387c5e91ff7082678c6e76a74649279bb327f3a4f3cc73d80104e0f1880c6647428a0b7a5883214cb46255a49c13cf4d8106818b782078ef1007f7e34790535e97ebf8b1cbf3b723317b7223c824964da23c4b6bd421a76603c0dfc8f2779acdea5cdb721f71dd9fd44f9488ad519057def31360c1673e5e3) +emitted operations + +big_map diff + + +storage + (Some 0x0fd3a77a6a919626d31505fbf7ea71d3f60b78dffb1b7232c1b3569dbb67381aa9df4ab99aa25934912112b2b9f1612004b3c9f71504341d8abb591f6d7ba5b9309217467d332b6ae66d634937a112cba73009befc554a2f9c6701d65a29e8cb1525e405ef803bf935000e2b0ed5b7ba1106dce0369069391fda557b7282e7ca77513fea88f364dbfb17ca9b9c308a860760a41f8268069fe3f9f84002add2e2e14b6a4497b3ef826fc885a633050c1d9852e942006aeb234d2944e17a5afc58) +emitted operations + +big_map diff + + +storage + (Some 0x00ea54ce4ab2f8cea7e6f172c249638844225c5e72980030f45e5645680d9f2860ff22d0310d7e2a39b70b2fd2e91fbb099428b8e20bc8895f9e9308b66c8afaaa06f1bea33ff8dd55524d1206e22278e1e4b23aa1eda324bd1446467a995f400fc4d7ab9df219f5af91a3bab904077f36e25450bbbe708f5f4d5a1f0fc3383af24a86ccd3f424bb1acaa65015c0fd9e0e5020e8ac03981166b9ced9b74e0712424e60950c9a774daa4d2677290794c5a34dad95b9e6123d83adb9dfb84acd22) +emitted operations + +big_map diff + + +storage + (Some 0x1667ce729e66b328dfddd67b3308183f2adba83792b637a9d6a54ee5c520f4a84b6d4446e906650ef19be90956246a12109589b3b1c2694b39d3d5ab8a3d2570e70b15a3ce81fdf28b488f90fe54809069b3143faeadf4392fa41b0178382e8e05579ff476cc9290b1847ed3895beebdc1c2fa106cc097ad369d2652b57feffee233a9f8e879164a649e59b7cb22fbef1252d6ab8cf8376f56df57627a064a206843d58ea6fefb53a07088c93786d13f47a91a07839b58d0d230598709bf12eb) +emitted operations + +big_map diff + + +storage + (Some 0x042c1082a0a914a892b975934ca4b161aa2b2c3d45600fc565d71047c95b1e6f0348534309ca6f506f74f1089187507f099ce83b41b120cd8b8d7a6bfec0cfbbeb90a5936ca9dd386e2335eb8c12f9a84ad4ad2a1ecf69bf05427bbe96482384112b2326686e63c03d9f3ded29536fe476366b1ec177c016370ad1b21c93970dfe04779be2dbdcbd1a306f5c6ca9f5bb0629414f83ae3549ab79ee283fb0be885a9706355efc1aa0d0ae6243118e7ac6cc8303e68d0afeaaf6add5d41caa7b57) +emitted operations + +big_map diff + + +storage + (Some 0x191f9cec71fc06393c562a77e79041f3851837dc39efa4b458bb55b6f89e15c8fef9dbadb3f75b4b9873c094503742210deb4371bb8293c102c122bef0c8972b6dcb4f9add18109234c3b94400e3e5ceb52f59beb33ca036c89bb60ad7b629e80ffff89bfcbc65f23e1ce932cf2992530fcb0056901ea31cc425585fcd63b444e2ee671eb7109b0978d23a19ab468387087dda6c1354fc4b645d3f0a6975eef41ba75a14b4450db71f4d899e71d4fa7a52b275b06e1ffdf36f539244c69654de) +emitted operations + +big_map diff + + +storage + (Some 0x091703cb9cd4ba012c631f8be02f949e9c488987c6144dd8a1660a4eb65a41474cac5edeb65824214875ee21298fee01083224b8cb2bcb353c47a796567b823aa8075d28e9e8ed55895dbdbfa8efe589c8c58218308bdf4d7737b27b0c6daeae17b36d402a7f7ea148c3fba6ec80633d64cfce6b31d055bff659b875ce0b513f4bbfd5e79580f1a5d896e551f082ef3912efabf6b0dadbc53fa3e03aab4817ad547fc2877f4850ed5861e37ccc29115c203f6c92154a84f898ac1fce677f702d) +emitted operations + +big_map diff + + +storage + (Some 0x0ed6b993962b955b8fbd1b7e7207ee2faad1460282274305837f89ed9081a405ad1a088f9d46487015b082db7ce3c80f09408e6d2f2e02868d1be1dcf067c8143a887921dc7098ef4c116800562a2786611a65b437ade3db1629d5eaf3b8eb56199fd734d8017287f5b24d4b4f0afae0cc86db7e751d2e1cb25d06f6bb3c7ba69c3b5d94a6913e9e1c8d870fb1a4470a1864d95b7519f8d7230465df4fc23e7f08fb912a467496a58b024b0e82ea5b8cac35aeceb1509db29b2f5bcde0c2d5b8) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[Fr].out new file mode 100644 index 000000000000..ec813cc3434b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_zero[Fr] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G1].out new file mode 100644 index 000000000000..749f9cfc630b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_zero[G1] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G2].out new file mode 100644 index 000000000000..bf26d720e3d5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_add_zero_zero[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_add_zero_zero[G2] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes.out new file mode 100644 index 000000000000..79fcfae9c560 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes.out @@ -0,0 +1,8 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_fr_bytes_parameters_more_than_32_bytes + +Invalid argument passed to contract KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi. +At (unshown) location 0, value + 0xf7ef66f95c90b2f953eb0555af65f22095d4f54b40ea8c6dcc2014740e8662c16bb8786723 +is invalid for type bls12_381_fr. +Fatal error: + error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_groth16.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_groth16.out new file mode 100644 index 000000000000..ab42c9a1fd0a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_groth16.out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_groth16 + +storage + Unit +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[Fr].out new file mode 100644 index 000000000000..7a8e5e9d8a5c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_one[Fr] + +storage + (Some 0x0100000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G1].out new file mode 100644 index 000000000000..f49cf663fe32 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_one[G1] + +storage + (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G2].out new file mode 100644 index 000000000000..017f8a53bdf0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_one[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_one[G2] + +storage + (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[Fr].out new file mode 100644 index 000000000000..a1fef32cc1b6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_random[Fr] + +storage + (Some 0x3a14168aa51fae4ac33e62e94267e61ced8f00785e295c9c7125b881afbe111a) +emitted operations + +big_map diff + + +storage + (Some 0xe842c1ffe3c767806c91f42120e27cda0e3578a1c52c53e1b33a65cff1e22b1b) +emitted operations + +big_map diff + + +storage + (Some 0xeafb8e3cf1e223497893cdc3130c6c13aa7d3d3e6a3502034d19d3ef4a39ee18) +emitted operations + +big_map diff + + +storage + (Some 0x614e3f935e4b1511d8b63143d2a7e3bb2235c5f1b1a8597f44347c4ff1e7764d) +emitted operations + +big_map diff + + +storage + (Some 0xb34999b9256eb7205c0303553559e8b14668241277fc207b21ec9aadc4451a1d) +emitted operations + +big_map diff + + +storage + (Some 0x307b86cff0794406b7e07ff937fa843c09a4e0dade758b297e39569dd41c5b04) +emitted operations + +big_map diff + + +storage + (Some 0x6322ae545e19b2b35e4649e021b2025caa9df47de27b69e023c71e349fb8643c) +emitted operations + +big_map diff + + +storage + (Some 0x36d7ee80fb7f1e6bc31f1384ed67d8c5b195f4daf6ca413e64703cbc4e9d0d53) +emitted operations + +big_map diff + + +storage + (Some 0xfc6cd59996ca5aa047bd59b6001a43e3777d9b19ae65de6ce8c2ef7f52cf1c4a) +emitted operations + +big_map diff + + +storage + (Some 0x6e9f624533c9bed9c971db028e9bd5ad034d25d38f1387b090a2cea2685fcf16) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G1].out new file mode 100644 index 000000000000..d831458dc9ec --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_random[G1] + +storage + (Some 0x0e3c67b12372907bb20da67474058dd766c165200d525b1e0ccb5ff5e3f2c8ab66ce557601ee6f39a81d7f89715e350303ca13302a0866206377c197d62d8e5149dfe3b944179af3646b886a0bb16b89e9864a7bbf89f18d1177c1c010213e4b) +emitted operations + +big_map diff + + +storage + (Some 0x1627a49ada91f905e37da3cb998e77177177866dfa21b714e8e60a969d993dea22dfea1468ec27bb502abffecd297af208a8954ec9b70cce4b5f045e9ad030e1e3a9e822ba31fc9ecda63f7483ed87dd251c117657f331ed316161c22ebd9a8b) +emitted operations + +big_map diff + + +storage + (Some 0x0044c4f40be86203e6d9879fe49fb510b1e40b1a58e26db3265f5c62b49ee1311f12f1e8fd034be3f4027c1a5dcdf0610a721358155dde11af7e315a1246f483973321095593a72d236149904a4761ec3134b482ef46851052e78e24fad5fa2d) +emitted operations + +big_map diff + + +storage + (Some 0x140bc58ab952ed42a4fd28fef1f76f5207f8202f15bb12375d8a4102a6c9323cdf80dca17ee79d1a80cb438b56f75a901822447a54c0b4858e2dbede0ed4634ee0d0f190c2b0f347247da09edc81cbbfcf2f5be25b842cf1777e151582ab797b) +emitted operations + +big_map diff + + +storage + (Some 0x0413f511b1c65f6a27766c69d4518eff63f9bb913feede2c82b7943f620feb27772f48b1a8b0196b88935a8b67eef112038f995b978f71a5d2d0470d026ae5c786be0ebe748045399a688f550e4950f2b5e0bea6131466d72a8eb4c6fbf2f750) +emitted operations + +big_map diff + + +storage + (Some 0x00e088d901aec4f3701eba2206c722276395202270c2a66471a5442861ef6ba997f2b12686e7b5413b24db4aec0babb207e5f81cccca63d939853e1b389695d58e907550fe6e4b347d870ab526b2b7667b888b92182366b5300314dc2fe305d0) +emitted operations + +big_map diff + + +storage + (Some 0x11641aa9417f8eb1659c74cd4a8f180242283634c5b059c497fedd502fad9c6fa00ecc991e978260a7452e79735d5e101559382cd1f3f92d964dc8a3f54b8d7dc37855650bbe11fa9b5e90881002b290951781aee93495d0e5703b35db31bf38) +emitted operations + +big_map diff + + +storage + (Some 0x0804d36e490be2f867fcc99338af37df61df443c73e47bd18f4f6eb8748a31ce403bb3a8aba27f281898a5f8e72f6c4f1321db8c96fffa9893be378e259ea6534fa1aa8be504b3f896e2af2a4cc53c6d017dcb587700689d81382f1cb1013f55) +emitted operations + +big_map diff + + +storage + (Some 0x1843835c32147cd7191e2f2aeecfef744f96757e1e5d2427c7cbe351d2142bb5723dc61b6211adfd79d335d632d72cb10d2e0686443369c8f26dd290b98af5e8d892a4085cfd7eac21742b783c57fbc5ee5a5a89a5b2a03ed732a0271bd2b548) +emitted operations + +big_map diff + + +storage + (Some 0x0d8dc00f3ecfb62c9e9e4af0dc3392fc24f2861de4e609b77d8866f561d90904e9e5531b5203cf646d5a22c4a26885520de353e43fb6cf32bbe12b2f243c858ecf9c388cb02be5b935ff8411f76991c00411a40a990d63af69902d0f3dbb18ee) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G2].out new file mode 100644 index 000000000000..0d43bd2eae81 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_random[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_random[G2] + +storage + (Some 0x0d95415b2c0375d132c0700938c4590a75498165c923d00317fc3baf5048081b92995c9f651438490ea51f47ae1f871d06450ed22ec65658e7583c95236d3224479355196db6f0e0f8edc6c26c6d1e7c6edd8fc0217d86942a0078705c2188d90b4ccbc374d0076cbd6d0f9f01f4992fc87e8b2b4e17d3d4c91c14e3a0eb33000b34a923350c7a7c6f72f04d64db00320cd31bba7dea1243ddfca66e8e14fbd2b233c2201b43bd099e0f68cb9ce347cabe68ab4f42e972bbcb834d9d73da0eec) +emitted operations + +big_map diff + + +storage + (Some 0x1953081fd90afdd618ed308d2e556cc466cd7c0bdc79bcfcf25b96ece923fe8517e72c98034097d9eee722f737e39a41113223084fa6fd9daab9efb9e0481087c30f3cfef3e046fc2f1bab2a8b142a94335ac957f8521646fe4925cd443430f00c90e874ef50eca42050742f7f605d0f8cfe00c5571a2a99240b88541e3a7c08c91af2bc89ad29b4d397d10d42c93e9b0ac8dff1d86ad777e8b5c6f8880411a139155e8ffa1708e085972bbe6d4d5c4f39415e5ee902c3427d54ea84334b7ff3) +emitted operations + +big_map diff + + +storage + (Some 0x06a72dbd7d92de83d95290f1d7e8923e0d8e29eb84024b18fcea2097225481c29fbbbe7d030ff1b4018f12418b9c28a60728f0e17309868072e1dc188bc9548e4f3a0d4fc35ea2203f42539b462b7070feea8293fe47818fe89809ad977179620d727fc335198a6ddbb9e4ba25def0445c22c227bbd811cb005828b2d42024d1ccba6c20d5987bfe9ce114ca112c04b50d142f815aa648bdfb092e5509b72013b6417e6f5b5ada3cc590a6d4ba0ba908afc6ab5dc5a34ae976afc74d8e75da1d) +emitted operations + +big_map diff + + +storage + (Some 0x13ff1086d5713b7931883f01c36424ef26d28dd314473c073ca3ade1da5e8fcd7e22a86f0514beeb5b16f53176bb8ac70d8fe482a5ff16db0f19ac5738b52efc3f9228a997da35fa8e3a2cc9aea049fb23fbf5926f199ed7f29c73022610e4e70ca6547613b84940c90bfe7438339770ee180237cf717b67d2eac23fee8c42c17e0a5a903e0eeaf854856a241781298e0b13af3d210efad5757c6112565bffdcdbf649ba5b645d6d1a46fdea5014d2f3edf257af5ec593fbf69f14f0d8e3ef24) +emitted operations + +big_map diff + + +storage + (Some 0x0f3012df11a5a21ea69e484e3b1aae6426f47131b6c8de2d2ddcf5f08b7e2264beab80d08bdc3464e5ba93ae5c70dfa81792d5af6898237318173dee0241ad29f3a243837764dc8a5f66deb5868fd69ab434912233d3ccdedde5b8ee484a4b6f07ce143b9d525568a35c28ce4ad2ab57463cdc2fd6cd967864e130645e0f2807bf13228b000a2dc124dd4fa45bcee53202b486642d735da0ad84458ff8989cdfe9ff1478b2d80b4e45dad71d7098bffc890d65b720372793fc0ce9c6fc169b0c) +emitted operations + +big_map diff + + +storage + (Some 0x1429e92a93f2ba48ebe5d66ecfaa3b148e8414beae4aa83b5c054caf6937f30821e23621e278e197966ab69806010819156379b3a6f4674207d680dbd0e45a1399efe202631f30507fa96d88c4363bbe852e95edabd9902bc72485e6dce044a0072da73fb04a55e27613ddadd5915d0637f5756e4a489eb29347e76fb329c0e289a156f8e758ccbec03376ccd67a528a0abaa11be4c810443b52082cb54174e2019ea8d9d7373c99e103908da27c1aab943e745d5026304527528def70f391ad) +emitted operations + +big_map diff + + +storage + (Some 0x07d9eda0c029333aa344535a1520d5e1ff32767edc4a9d2f963fae4bf7a76762a1402a70fe2497059912016e20a082a20faff41e659f197f5c99532070782107a586dbd7e6609b31b89b4e91d5eb85ea01aac0e19aaeba32f86090c9f489b1ab0f8c51be59ebfd70a90246e364f817054a149dbc7fb6ad6e5ed3991c3e55f6dd08bcffc0f9e1e7d1c4fef6ed7141aced0da4ff47847aa5f5d7347bdf698525b75c840569e1dc731c1971eafebb305e77d44b2b06737a9f60d3b0cefe5a3412eb) +emitted operations + +big_map diff + + +storage + (Some 0x1047eb6211bae046da85a8085a23c5df6f73ed25abb394b16fa673842d19107b2e40ab9289b36f2699dfe34f5fecd2ad0596e9d73d3b697bb342d5b4a74922fac2c0ba20ed89db874e23dc07ef1c02df48ed3b5f2b9e63e1749b65d64ff3572c1034d01a148145d63b85d0f01b7c84c47ead9963b84233ce9f5cc48b1cee86b094087fba5d718ab4aa8a09153b078aa6036351a3042bfeff633a6e023945a0b6d88bd82cebf4c4b9010d16f98a30299ba276f8451ce728c26010a05bd09ba365) +emitted operations + +big_map diff + + +storage + (Some 0x0acd7057df12eccc09376a20c70c6c054bdd064503446d525413fc494251c0f19181eeb1280c83b6d34916a3904900bf177981828b72d00113c22542eda6e9130fe13f4b9d2f3dc2a78962fac295596cfa28f95bff49e35358f8a85cc764f2030dbadceba39d7e87f274f1b22e0d1f92e79a4452c6a97efad1aa6a71ba2987d6506341c1b8f9352548cdd40f445e545b051e6665e110109b6e80894d973b10ab4469a21d5d167563c2ac7645523fae0a2ae2745318b660f2cd19d725c3a17fda) +emitted operations + +big_map diff + + +storage + (Some 0x04f081fba03150088bdfae16217e3785de649dd8866c728a2ce05abb271cdb664a45d8c539f1a6c7b42335e5beb4a97e07c41c2e946a74f95d390b574fde8df58bda9d43fa695b02ea8cd290949097ba7cec710d802cfbce1a804c74e8b6826a017b201bf0b344cf7d469ebb203b4eb2b7ca41b6f7cd3797423276d55742542d9435b6261956076718a1eaf5fcdf0f1a127b43756c11c7baf603bfb4f929933ad5c263c9774bd6eee6131705416739a15d49c87bbe0a182ab62f70f55db77144) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[Fr].out new file mode 100644 index 000000000000..acf4fd1c07cb --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_zero[Fr] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G1].out new file mode 100644 index 000000000000..60ea7219a688 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_zero[G1] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G2].out new file mode 100644 index 000000000000..d8c642e2de46 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_one_zero[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_one_zero[G2] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[Fr].out new file mode 100644 index 000000000000..6d167393c71e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_one[Fr] + +storage + (Some 0x286f0ec6252484c8bb981a3b8382b975c4ea92e11d1889a4bac541d0657db547) +emitted operations + +big_map diff + + +storage + (Some 0xd3b3ab5cfdfbd937887b10406248e8afef754b2692568adeca80be1c7abe3057) +emitted operations + +big_map diff + + +storage + (Some 0x469fba7341e28e67f35affe2fe4b97662a8b6481cf297346ee94e3d7d932c92d) +emitted operations + +big_map diff + + +storage + (Some 0x8a7177b61d33e4cb78eead124de5a06175df7e3b59f3bc4dca273de59b8a4151) +emitted operations + +big_map diff + + +storage + (Some 0x252050ca68bc0bc7940a33b68e12982233df654e652e96f2d28ab32be9ba046c) +emitted operations + +big_map diff + + +storage + (Some 0xae809d9a60de4be2126f115a819b9399358c9063790951f0373420a664335748) +emitted operations + +big_map diff + + +storage + (Some 0x128327880e041a2d6890d969f494c5581025dc3cdc3e3b6ce2d790f8ee68821e) +emitted operations + +big_map diff + + +storage + (Some 0x709b3e567cd3889a553a34818720157dd38724cf85ff458cfa91cb624db84b72) +emitted operations + +big_map diff + + +storage + (Some 0x932b426e549c4acc360611dfca579d436d7ce59111cb3f2bce5e9fa1562d4c1c) +emitted operations + +big_map diff + + +storage + (Some 0xef9144b2686c7a1de7488aeb9669bc3dafce03e580b27796d5489bbc2d5cef30) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G1].out new file mode 100644 index 000000000000..9aa626685773 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_one[G1] + +storage + (Some 0x121ad63b7b9c90355f2862d56fe793c29fd884e311a65917f860071464068682612e78f29d936ceea7056ccd2506f12d03ffb304ff19fd039c7404c0af9119775534e2d93c5f9fe172893767c1dc12a25edfff52434bd309aed1d54bd0a89fc4) +emitted operations + +big_map diff + + +storage + (Some 0x0538edb42138a4fec97b74645550b722d7e87ccdea13249fe9fbad25e314d8587287821622e9c7cbd8b5ffc5b244a5c70600605fd5a514fbf6d13764bdb35639fc7edb3b95006fad00083bdb65420ac4a2b7a5a67100ec7b0fed8cc3f5bcf251) +emitted operations + +big_map diff + + +storage + (Some 0x0e4b6dbffad2f4b3ff5be58477f3dca892a060954b35a0ba682a9e388071023d32e4d4f241d6b926348d1b76b78369af05485f02b87fe3666c70f04ed7439d175fcd2d76fb9790cd4fea48c38f2fa1194799208195286274a0c94aa4e7225c1b) +emitted operations + +big_map diff + + +storage + (Some 0x0ef689c3ad66bbc9bdb16bae245346c3e1d314091c15b37622720ef5e70defd6c59d2f4e4335c791644c28f967aa5a510607bc31d79aa0a40fe637c47fd825bc06c7ae7839eaeca4a0e4dd8f1589ca8db8b4fee09b91f5a43e04f17ef9ba3c04) +emitted operations + +big_map diff + + +storage + (Some 0x143c03201ff3222e412deca15c6345f6f3a82ea30a8d0b289952dfd4e6edca156617cffdfac43466e7745e5ad5222c7f09b8ed107474064dc0c94140949264aa6b3aec28772a8b1b3dd0571ecf433ccc9a7e51d2ac119b7bbeadec90d1f3c837) +emitted operations + +big_map diff + + +storage + (Some 0x122c5f9870721941131cbed468f1c754dc52f494fcd486dc761b4281e17eb41d29a40a983de68cec836a36f6d3c396e1054b6904fd965d74805b1c088ac71e7b5eeb41a1611b399c63777170365859ce68ed99bfde5158a207ade9807f5cc458) +emitted operations + +big_map diff + + +storage + (Some 0x0fbe56abacb7f089a1e46ca6d2837b8f98e51dd1054445c2dc599deec36800688b6add762d6eaea36823fe5e867955730f1c175b454fb0bae81377a0b30a0017d2c11b4a768b78679e8634e8d2567874ef10b5f523f2e7bf8e4698311de58051) +emitted operations + +big_map diff + + +storage + (Some 0x05014fcf35b18ed937a24b4ec2f635e371e331766f6971204a6d458c6876381476ed691a0d020a6b487b14cf4512fcc20678c937e35d63f63e52af3fd081162d4c34a1333ebcc40841a7bccec941e8596956cb56bae1d2768ce7dcebb31ed170) +emitted operations + +big_map diff + + +storage + (Some 0x016f4c61393eacd1b8365656d475d00271c146649018368fe2b0acb056daa92e133a45acc5ebc121d100673f49a55b1f0a91f97170f0ac67e8f8fa516a173fae35645c26748696f5d6b2094d0a4e5a8402f59cde699ff5627d3f16034d745174) +emitted operations + +big_map diff + + +storage + (Some 0x0a8fdae48244aa6f45cb349ccf56b7dce450c08036f96ca38a13ac8ba3c136bd9bd83a91559c7f5269f4e7f34f001e6d0152b902148420a763d285716810dd24cc17b9b486e8578ad7dbedeee3a4eab0d1ad73cbd3a1ea783b875b171d897030) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G2].out new file mode 100644 index 000000000000..1d1db1246331 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_one[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_one[G2] + +storage + (Some 0x09437976147a4d0d174d809df2b91247f2e2a482fa928fed9817b1740ddd941be108809ec427bba3abebab29e0fc91360dd9f11f94ec1c4cc3da10c13df7fe0a3e089b48c7f129c02c3fc47211f895c2243242f1a238cfca841e8d9d1e7927e400b626a5e4a4bf8f147aa6cd82073d5ec66504722a4ac8cf5939d5676a8b2b37731c94dce4e64ba9862eb657d17d789c19b1fb83a099335db3c569279fad3516257eef911af59c39e72a10da16e2c87394bee5a58b107c55ae00470377dea973) +emitted operations + +big_map diff + + +storage + (Some 0x05ef75bfe22c1366532a0be4e76af4f44c83653e53e7441e31eafd50d23f406093a42d56830ea0b2d6bd72c946c82bd6020366ebc02291ce6864c9923414fa0db8065979cd8031a84ab0bfe58ffa7d97c4f5829fc22126f8818d2b30cec132250207685a42ebd4b3566d3ae6437b12d1397ff6101d5cafb3283c0a26113b39436141bf2a09ec817d49145171a7cb0b4005483eff64cc380f7fab70479ff783e05b0c6a15245c93b732d9483adc38a3beb0179f766e685fae2ac8b91b888a4f3f) +emitted operations + +big_map diff + + +storage + (Some 0x16f479fc7f990fe798762da4e839ae6ab1c3ea82caa08d6d5892f28585b14ae178dcec9cbfe6f1a8128dcd46b87df07609798415e658f9387aa6138fbe3c335fb2327ffd2504c3f5aebd3285a2d08fc9966e8dd12f1c70dfdb369cc98f67b712179379ea1fd9bf46362cd7878a3667aa89f8c08627ad8d60868f219d49ed36336e393e0b7ebccd9027edbe634ab2d44507d065115a3ab3f4bd2ec1bb6361f580aa0040ccb0501426bd186e1e1971f7575e1e12ce77c8c2d8269799dd380de810) +emitted operations + +big_map diff + + +storage + (Some 0x04ff37dc37877f596cf0fee3190b74567c6925c5822c8776a1fdb926d250ecbd59c16109b3e18bf6389fd29a51f9815904b4d3277553a1afed4dc7c441cd16078016edf441df1bd21bf3590b701727a7a4ee5cfb77b4af06f154fcfe47cb44f91400cebb1f66c59f2ef796b5d8309c6d20a948156624e4d46ac09bc6b2566c115d2bc989e53137ee0bfa6e2e17d7b6fd10448f47c61b0fead5e32eb9f24f1f7635730a822166aa400d5537614fbf808d6e40f92746d6932993e74c3b57ef1520) +emitted operations + +big_map diff + + +storage + (Some 0x0b7028a94c140119e30ec04b76f245e78dc6d9828bcb5f503f44f2048faa675fac874f88b058c9b6e9ea2fb878a931fe0606479ff1fbaa8f8a1caa797ee960de8ee345eaef846578e7c6eef78aaa1a16c9cb9985821639cea2ec5866219d77de1593c6981c3da9e8c0a64bd8aa12a12d83e03494bf94ce9b098feb97a8921fc3a4a2656ba5a5eb130210b66766a0dc8512eb97e67cd5fe60859f1810ec7a1237fd80d4cb73e8641e1990a0e9e5c61f738ad8125b9108d78f96d704f3d43c71cd) +emitted operations + +big_map diff + + +storage + (Some 0x0f3e9c3968ce220c8d22fa306fd12e8afd05be41538ce630650650c8461563267ee4eb22e87818cd9e9022a1c23641d50b904a7acea602f907c97fb8701fe29fd6b2a276052b1d5cc152510016c466fe3ffb38ebdc0036058383c7643efaf10f07e7a1e694e4618c2057f4070912400e0c1457b32223be85ceb98afc5a9891ef467bbd4f96aeaf59dd92f39fd7698d4a1464d7b940f605a0afb023c06b2316ae5ce3e522e10e9e67ec2bc5dfef45e85e1272e5d4c26a7eb6b5255eea7117bea5) +emitted operations + +big_map diff + + +storage + (Some 0x17b906ef7baf4816f9ff3930b61253bbee2dc0cb2580449c234979733739d60b1e4c250cf38460240ddd8de171da0e790404c64d73d02d42540bb35b99bb9ef2d51af633c8546ed8eefd7a47cca204d3e6a2a82a6a661940e40995de3068033e12ad259c9a05af8b88196215be9a4310fa41e88454d8037572147571482cb0ffd39d50d1b09c2a68ae8a5694842bc8f9104104b65969eee42a43680a763fb577b0811d4b03d04c5060521b569d253014832d66cbb2163b1a15d5dc395969d47a) +emitted operations + +big_map diff + + +storage + (Some 0x0192202a64ffc9df0023d8b9b7125fb5b889386ea4e421bd8a113b1ebe45f491ecf552369e0e9e297d75264e73f5ac29119347d4871f1452d0375b4a19eaec758c58f6066bdc7c804ac9bab38b61f475913d0b1e80d8eb00790a11cd5ba3b81001069862fe6de4183f916099da7b8cfffdea73965df644dbb21fe2c9036296b01506fbd8299a8dce20c185f12a864e6c0f3c2e18a2e79a922a5f8bc59f48a4cd8ef322c678f080a10c4585c27af5c3bcb38a19f10c83ac484d81b55eb1393dd7) +emitted operations + +big_map diff + + +storage + (Some 0x1251e8448175157c4d2856be19064bf584481dfda30cae0d0b6f1e33b2a335be1a02dba175aec178718db6dc67409e8d09ae2872ec0d74b84c4a6eba82024630c290c6da27f387b39abe0f4fef1e1879bd17d32b1712cd9c2fa59c42796a6beb0f820092b9a5722b03aaf53470ead23b1d1c0a2263f2f010a5872d0251a81e21c21f4900aad8cad4f5615a9f9966e1090b13b49d84b63a6480c608dde86c383c6c943ca211d57b11aa4d518ef81121fa2604c2e650998138942d892fd49c258b) +emitted operations + +big_map diff + + +storage + (Some 0x05d336c2765803c6cb4b385ab9d4f4fa1ce2da0e5efd59a1fff5367678e6620664406da388d05b3b448be22281b2b3460f0c2b3b46ef2845bb1bf11ca2909f321cc35a295c656d7f0a432c31d6ff82b62cebfe000324d5bd35dfcff4016e526d0c424b33f830246ebca7fc52d1843d93275265da2bb6edb6edf6b9a0ff928cbb621aaa0c274614b185e39f3b8a91e50a13c54002d7842ba912b15f0671bc8e10bee8c8cd6f219f7115d9ed6d259cd029e75fc00ddb4cb508841b3c4ffe383d31) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[Fr].out new file mode 100644 index 000000000000..343592a52c8a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_random[Fr] + +storage + (Some 0xb33a7eba53cdefc6ad9cb5c1328402d360c44984ea5dc51c2f542faadc6be816) +emitted operations + +big_map diff + + +storage + (Some 0xd3c6ed5a38abf39effe32bb89f2750a7792d10533191c9e7c24c4a110e918462) +emitted operations + +big_map diff + + +storage + (Some 0x712b1fcd10c384804b22abbcd62dbf10434baf60e33078f349b47a245a99394f) +emitted operations + +big_map diff + + +storage + (Some 0xc2a04fd112a74a4c60193a518a7a2dd968e63c4f122c5ccda2842e30040a1d0a) +emitted operations + +big_map diff + + +storage + (Some 0x145e33354dccac366850661cd8dc6b08f69edcd424055700833440bd798c1f1e) +emitted operations + +big_map diff + + +storage + (Some 0x9add5ab74ffe4b42e3618c846e60ea2b8a785d5b9392762ede89f50c85ff7803) +emitted operations + +big_map diff + + +storage + (Some 0x90827b0e55cd078db382a78e437a2320adeaf00847ad95a6c920ef2a13954727) +emitted operations + +big_map diff + + +storage + (Some 0x5bb1c6b970d42235a163ce608b783311e47114fd2d755624d9ec2c416d09250a) +emitted operations + +big_map diff + + +storage + (Some 0x3c32dff99dd4798310d347d73dcd51055acb344aca9135fd75a5b5be45ac8221) +emitted operations + +big_map diff + + +storage + (Some 0x8951db6a4a847740ee7a89d7e4057e2ba8e0fa5fbd8a6989c99f204492765e3b) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G1].out new file mode 100644 index 000000000000..9df2946a3777 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_random[G1] + +storage + (Some 0x04e31b8535d081c6216917afc0b998284a19efb004598e40af32cf07a7c01baacb96621f42800d560e7bbc1cd76ef211046404a2303e2df0f827efee06a0146a3cf18a213b890080e33478eb652c142191363cec93bfe88f0f29ee65cd8a45a3) +emitted operations + +big_map diff + + +storage + (Some 0x158932735210b3c07f9c15eedec8acccefe84d080d3d5e06795e6ea3383e34a57c8ed1c091b6990d636dc3dc6e2b0a03077fb11f6c64d76840c168238b5838d2f06a27d48b1bd95cfd43b68f0a5871d22df1117b398118e71379602ee7a98e08) +emitted operations + +big_map diff + + +storage + (Some 0x0a32114ba43665abeb4ddb111a262bcd7ef8aab2f628627a4e237dea512835b4c8f7d3ed3bb2c4f8c99d68cff26b138519da6ab3ef7d260c2dbf7e84cb65890d65df014911b2d3f6d6e4248a23f36add20fc3c27c93560959c366a408ea38847) +emitted operations + +big_map diff + + +storage + (Some 0x14512db2530c824ca00345cc815036ad2a6e9d048c7571c74aff33f9f6b3a54239a893ac73142f3e0c74a5d179c0c5b2010a163762468c6feb4d27f1abccc4cf3fca36ce15868737320bff7aa4294bde62d103155e63b74de46d06d6b06ee1fd) +emitted operations + +big_map diff + + +storage + (Some 0x0e4459b6675e6b703556b06bc3db6adf195e4a0e3262bb12fa82fdbbb41d6aa0620743ed337ee87654fa8a22d907847b0d0c3e578ef5c00e360dba8567b12e4f3ecad77a2bdb303888af1c2fd730f5bdcbccfb4ad50e8571a0da0db8d7f63227) +emitted operations + +big_map diff + + +storage + (Some 0x0f32aa210d52283f4495ca85ce595df832cfa90d212922afe466a3d58203d419fa6cac2bc33fe2ef42c684c97ea061f90f49309180a9238b366642cc78ff5bd4ee8ee82aee112368248ec1a13d36210649b5696528e64a16e04f7c52ee14fd8c) +emitted operations + +big_map diff + + +storage + (Some 0x1658a9b3195f1103234c8115a54afd9455751a59223922cfb3b2c680be32511087f3ae762616d843fbfa19096fd58d990d6b9ddff4af5bcdfd44e7f49ed23393bf466a82b3e8e2281d883c6ccf8708755add7581a6a90f19be9263d8d624266b) +emitted operations + +big_map diff + + +storage + (Some 0x0182e82dbcb3151a65e424f9d5962e652eecf163a5a06ef5dcf1835009cd2cc0106b125bc6187a3eabaa25a8c4ef5c5b1009427ce8cf6efc38cdbd6efeb6c5463cd5d508fcf28bd7bd2c7eaf90b29bdc49cdde479a6c64bfb086d023972bb0f5) +emitted operations + +big_map diff + + +storage + (Some 0x130144b4bf38c092a5239371271624d48cbe36a0461feece232015f64917f2bec1bcba8e57597932d2a2776e2288b0e3068a74d96f52781b2b11a40ae730c56d909b6aa82afe81f291ba17667f8def0c8c62cf75b800d42460e5f1956eee18e9) +emitted operations + +big_map diff + + +storage + (Some 0x00f309e7224d4e6d1c59e27e2f651300d9bbb17f58ccf23943d88c7a4ada9902779c3d92a701e419cbf2e719927d94ac106420f6c2c79cc43631033d59ea62663c1c4eb127c43806a2b9d0e34bebca1ade68fefc795913823724a74a15df6a76) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G2].out new file mode 100644 index 000000000000..91f8d40afedd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_random[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_random[G2] + +storage + (Some 0x0b2d5f882010f2406dd4fdda47ed2dce0a7419de3ce13360c709d420955d8fd254c0369250de38a69484f3d42266e56a0df6a9f48674db24a8adc43947f4d4155059769fda12b7de6de9c7d70166c3aa3b5780b3ef4e6285860935c5025a48a70ddb77c5df41cc6653f5ef1edf35776fd7f926e303115c1eca0465ab524626e16095d2d1bd516bf2bfc2ab4bb39c968c03bbda48f947a526fe887442e9cfd9dba4ac84be8f8d03308b9f32d566289a6cbfe19a87b13f87c3220bde5223f13568) +emitted operations + +big_map diff + + +storage + (Some 0x1170918e77a35dfc20db737834c50807efd778b7f0371e0a5cc5621df21f45311fc7d2cf36fa244a15605ac94f9bb12d0002517d54651966d9159aebc372ff2a7deec9a0d7dc80bce22025ace6cc1a32b8165e89790a8d6205121eb00238782709157dd20f2755c12822abc330be0b4a72df19d04d71f8cbd0357de1af8336987fd5db4f91f8813e66ded7570255c2fb11a13ba75e65187d7f342d7b4ef3ab41778bbd01f42680c86488bd7864cb78d9326e2e69f7195fd2fd09e06cffcce84d) +emitted operations + +big_map diff + + +storage + (Some 0x13d581984d95ad0ccedc521ee63077dfbfd3570ddf8dc0372f7411b903ce87caf5fc8a1cb1f66762e267a48f46a488ff1610ef168e28b79c9ab047ac9707de363b1ef06fb5ad86d919acadb9a6bca419d05dd129bc7436d4a8f024d4bdf7af8c0b1342fe8a6e949a51bb0901116d89437e7e18b8a40fb4be11f447879fb2651f7d449d70f84a1f959cc42869a85fe608062802296c3fe013f46b28c458ba28651c70fb61056b9a6af6b947e80becb252040dc8fc2fa9c79478973118d0984fda) +emitted operations + +big_map diff + + +storage + (Some 0x065e2a7e8b6ce16f9d46bfefa994cd13fa6813f6bad47e1d792dfd2e9bb4c3449cd7ebb05a8fb6b82b49116ca0dfb8a4041d960f46a4b0ac4bfe755470dff54f7b4d5bcb4f4d52ccf520b3f7e5defd6e6eac7b09f09f0e429c27477d5ec3a12706ad589e303bbed584d1ce39479c7a709bd73d4cc204ba78b7f4d70927a17d61dcd8e10e3359f396f98509f3b63cb16a06b68abc4b9597262f73f181bf042ef5c79b97c40304c259034534b3716d8168bf975565beea7f1ea21bfee63140d7db) +emitted operations + +big_map diff + + +storage + (Some 0x0c886b3d45067177888373985b7ad9e01f50fa934a67021f917ffe8a4f5730885c490f312bcb74590609a0550b26985711c932d4b30f82101a6b058f27b41edc2374273063470c3015840a9074c433cff7008f7c237bca62eac80cf82408ac85147a01f835601cb405e7a5daafb481462de4f5e765821c5e9c24d79945ffeb9926bcb5c516b1be62474f152fdcd79a7318f5733f19908cb27a4339c7cec46d2e904026ec421f41935ac05ee52dcd32ddf957d36da0478a231483cee910e158e9) +emitted operations + +big_map diff + + +storage + (Some 0x016720c0b2c7541ade5089d83b25c42eb26f76120904edf5d48c12a654df5bc690f3b8274f9a13b471e9d3397b253d5b0070d7e75316b1fe6581e120becefae1963f2c02e3dbe78fccaa0e82f3dc6b26b0f8fc878ccee3aca8681570864732791521735b6585f5543059a43e88d2293b372e76838962fcef28d9063259fcd7dc6216c833ad99fa0cd83c7aba57176da20a8a10c28d40cb495a3b4a7bfdddaa5b721a85b9dcb606bda5763eab6faea0ebceb638af2b2d8c61fa35c7e22d0393f3) +emitted operations + +big_map diff + + +storage + (Some 0x00971061214085d6e490b4e543696d4e2a5da1d7e3593bbb04444ffbc824a8f9bd9273b0a75f9672e5ef75407dc4daa503ebd0198f1af03f5d49688de7c9864836a521b93804a442d582b103d2ce3acf805ab611ed00d94eafe205fee48b1cc808c738a923f793e75b4a3070be1cc70d25eea3939703cddd1490f0f518d0cdcdcd7942b294020cd26338a25d3d8a2ddd02988eec1b3a4bbe0e13b6508b5a3bf790ff8ae7c78fc5ecd3760c7be57e94decf97f0271e7ef0c7396133b2b8927441) +emitted operations + +big_map diff + + +storage + (Some 0x17a0f51a199054d24bf00e707680a5318740b1e0f60935ae262a04a2e6a965d78ca4b066c8810c1c4ece3ba054b4f706132145795844cc04aba7fe5b92af3010c7d2ea264d82257de9caa012d267d5d2f040204d3a9b162ff35d58a94171a1dd0a6bf8ecae4b6109dca88a2bb07a4f2aff9148cb1d5af227278cafdc4a482070df87bd7cb968efafc621bd9fc0019e1114dd78975957c315f8f0988093457cbd710ba31b0f9eeda8b8d78e9d5833037ccb4a729726c3bb14941344aac882b9f1) +emitted operations + +big_map diff + + +storage + (Some 0x19d4f927fb96db848401d650a01ad72d05be245d7d75dc7e670e054e450e59b4c57119c8ba3df43e36ed405553a3439e13d903d0d8644031b13e46030ca2cd9f1450ac1428b54b399db96ed24f3d017a97bf5509470689b7585fdd848c587bc30f2c4d9df0e3b88e7d70a1288dddbc86e9c1f17cc110ea1a84f6900287a6a6ee016f59e02129792808721cee006337cb16657108891cb67ffdb6a5fd6fe4b5160cac312ca16aafd01ad9352a69b9e5ed2fdcbd58624fa800dcf0af4f6afc6cac) +emitted operations + +big_map diff + + +storage + (Some 0x0d4c4a2a8095869ea61b83d864cf7ad2611aeae6d8f2c980e8646e3cf101ebcc53ec086effeff6e79b97c09cd9e49b5719b698cb3540859837103da3bba5f89814a66a4bde5b6b8e12a585cefef8a2b884bb38e4dba52c3dccbe775291f971d41177f7ed1a9360fbc3ab6227d0f71a11dfd2a44f8e7d6fc4e8f42ad1e10bb1bdb3868595beddefd15f75c45fa857bbdb05955023d97e7360438d8588415ee12a626d8c0e147e9de1ccf2ded3e2826e5ebd9f48ca19fdd8b12c98dc6c8da4c951) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[Fr].out new file mode 100644 index 000000000000..372ba7deee07 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_zero[Fr] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G1].out new file mode 100644 index 000000000000..80a26025ddf4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_zero[G1] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G2].out new file mode 100644 index 000000000000..70737f226cf0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_random_zero[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_random_zero[G2] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[Fr].out new file mode 100644 index 000000000000..015844d5742c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_one[Fr] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G1].out new file mode 100644 index 000000000000..ff7aaf69204c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_one[G1] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G2].out new file mode 100644 index 000000000000..4b7ac8320d1e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_one[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_one[G2] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[Fr].out new file mode 100644 index 000000000000..54b3dc67580b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_random[Fr] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G1].out new file mode 100644 index 000000000000..7d180a3dcca7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_random[G1] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G2].out new file mode 100644 index 000000000000..f9893737a0df --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_random[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_random[G2] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[Fr].out new file mode 100644 index 000000000000..23f7706109bb --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_zero[Fr] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G1].out new file mode 100644 index 000000000000..bc9c14446669 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_zero[G1] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G2].out new file mode 100644 index 000000000000..b6ed7273cf56 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_mul_zero_zero[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_mul_zero_zero[G2] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[Fr].out new file mode 100644 index 000000000000..16264131f06c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_one[Fr] + +storage + (Some 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G1].out new file mode 100644 index 000000000000..7259fc3a8b58 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_one[G1] + +storage + (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb114d1d6855d545a8aa7d76c8cf2e21f267816aef1db507c96655b9d5caac42364e6f38ba0ecb751bad54dcd6b939c2ca) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G2].out new file mode 100644 index 000000000000..281fe3ec3d81 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_one[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_one[G2] + +storage + (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb813fa4d4a0ad8b1ce186ed5061789213d993923066dddaf1040bc3ff59f825c78df74f2d75467e25e0f55f8a00fa030ed0d1b3cc2c7027888be51d9ef691d77bcb679afda66c73f17f9ee3837a55024f78c71363275a75d75d86bab79f74782aa) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[Fr].out new file mode 100644 index 000000000000..97d8fb6a7a5a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_random[Fr] + +storage + (Some 0x9ac69bc1db5f20d9044178b065f5a09c8442bae11c45371f325e816bf721d739) +emitted operations + +big_map diff + + +storage + (Some 0x24a3fec4e7f8ad2ed4b6b0284e5d03ad143f3ac4d0ef3aed1f302c3459823c59) +emitted operations + +big_map diff + + +storage + (Some 0x0dd533bc546e5dcc64ac9d74ef41109f23d374ad2885194873e582d7700d0d16) +emitted operations + +big_map diff + + +storage + (Some 0xc0f43e2aff39fa4bcf5319a48396587b076d0193d9a1c31b676614d9b6a2dc0d) +emitted operations + +big_map diff + + +storage + (Some 0xbf12217bfe47d2f1d96db15e3f4a8eb9ba1229c610e2c0ca85205e217fe44422) +emitted operations + +big_map diff + + +storage + (Some 0x5b33082c052de9699109edb03ca4961ccdce7dc0b21f35ffa208f0c380d47353) +emitted operations + +big_map diff + + +storage + (Some 0x56bd703658653401c10d85274f305dec559e9630f202e307dfa3bb3980829360) +emitted operations + +big_map diff + + +storage + (Some 0x8b7fa597cd2d60533467ba57c1a15029a40239dd4cbf50341e7eb8aaa53abf4f) +emitted operations + +big_map diff + + +storage + (Some 0xcf62b00037ebd1ad24ffc51831e12878fdd817915f3bfc1f23150099fb2fb81e) +emitted operations + +big_map diff + + +storage + (Some 0x41df1100e72effd309b1f30f51729681df099140be3fbeeebf55468b9cb35d22) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G1].out new file mode 100644 index 000000000000..821ab890ddd9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_random[G1] + +storage + (Some 0x197eab592fb38019ed2b362a048af848d1cc13b4a6c1d035f0dec4f5c461df58ddc92c9b6cab42fe3683000d91ceafe418d5a984c5833a305e02b18372d56e0b3943e34fc5aa2e79dcc359d8a299928b43bec4667443ab008dc91432a9e81ae1) +emitted operations + +big_map diff + + +storage + (Some 0x15d02840b69f06135d0fb3b82ae94649b2a10da9f7b4a5df7365c95b9d04c755a863ff2010332a8cf2609e08578ff02a05d1699ce8d778f3d2d7aa3841ec11e23682ab0e7933b43d8bd7e8e2c3b0dc5bb3878d7c0f01fcdc2b4e97f84c46472c) +emitted operations + +big_map diff + + +storage + (Some 0x14f7f5b6207b770382e65ebe91981942bc7c88908d1b2e73c6ee1322300f703877064d65d16493a3a9c3e6c45b049dfc0166df18d9caa4a3ba208d1ec549ea8cd27dccb7e22497594b4981ad758393a96de9be4247b185d8117774616032a403) +emitted operations + +big_map diff + + +storage + (Some 0x19b7acfd822ce85763c2d9e81425e571397c506ee31a5ae31c44fad5288bf3ca43c1abf6e78d380f0f75dcb83e1ec9cd17edeaaadb33ca8c4640da22fbb6733c5c11cd77bffc1a8e900399f6ea807bdda382b5173ee95ccb8807f52923a4297f) +emitted operations + +big_map diff + + +storage + (Some 0x16a404c56efceca50db3014d9c764842f6cd2221ff6b89605bc617b48a12e791e01c089489a5cfcf8f02956dcf8d2d8b015b9061f8f854b00f95fd177a0e9d8254b9dcb23e486a2ed13a79cf4f2fb430cf3d1c1eb727909712cc71e780226728) +emitted operations + +big_map diff + + +storage + (Some 0x03fd56e83ffaec3a3441bdcd46ad961f62819e72e9aeadb78b830a271c4d480014215b337fc7fcca3a7a6c9e57b62ed909c0dc635400cf2268eb1b1c841ca68e5cdb7edbba2a388714319740348180b33795377af9228b13035cdb4bbfa5bb60) +emitted operations + +big_map diff + + +storage + (Some 0x0a31c603358cc5f0536c3b4cc7bb8ed1a6e0da1113eb42a13a07201f071f69f84fdab55bfcf3791495317a9826e0a9ca07ea3e8155f0c3a0df59c86120a0decf70bfd0886be8433932dfb62e7eaabb68da56859be8c78fe0efe6d774fbf2ca1b) +emitted operations + +big_map diff + + +storage + (Some 0x0b2b25da57dfdbcd47c80f821d732052e890661fec1b1a89e2bf83b1bfcc0f0c59fa59be2eea602692472819aa581cc319742355a5c737fb173d6fd2b53772de1fb90859d39fc6d9d64528be91b41230dccef41eb8af2e228d73bf80ce152dea) +emitted operations + +big_map diff + + +storage + (Some 0x072cfea08d58f5fc8db45c45c7ac6fcc01a0279b33652a685e1e961c2385b307ef336ff7a7529008158388ec3342a3980b0ffd641f1319835631e7e4c72450900c2d4cfc9ca2a9427189047b4d84ce7cb21148b414f1a160efa4b069c0a884ca) +emitted operations + +big_map diff + + +storage + (Some 0x12d6f85f33ad5cf0c0fc2c77c79bb7ac152b065cbdafbb7ae9b190ef16f3f3ba07a1a7be5af71e80038b843fc6d9772612da90cb178d7a6b48bc95b33cc431168d84bb441364c1df012faa8b53fa7b602d2a961fb65a8e13d37cc4e1d417b8d8) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G2].out new file mode 100644 index 000000000000..913b98b613f6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_random[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_random[G2] + +storage + (Some 0x04c4113c5de4461ee1effcfc208bb5a9804748c180af325b70966de7c379381de993a4659457b37367c9284ebf914033072014d5e51b7a11f6ceecdf68e310399700d00cd49696797fd39a95e701043291aa570cc853a3fc98389428112e62e90827091bae55288eddb843baa59bbbae59aeefc2e92d212a062dca9e1e96d621c4fae7cd94b1abab9b6efcbc720723b60ddfba8ba68bc874a1aab91b5fa6c6cb36a5cec01fb27b513a87c84ee21f18badc394467093a111040da3175c968157c) +emitted operations + +big_map diff + + +storage + (Some 0x19bf6c44cbd63175794a5730a440de20c66d93c2955412f40501117770de06ca62ac213b332dabafc32fb535c27c734d11d897534063baba835363bc6c8bb52d436d0cd6d3b7d80aae8f412960c6e31938b4c8b361ed3452dcf3fcc5021475dd02b7a90965f4ff09880874e59b382e0c1b37619a6f1320a124cf55b36b3aa716e42a588ae6f01af4364d08e3c0d814ef0d02bbeb23ef4c23f4b145aef8a73bb1ffc4895bafccfc86e621c05afbd218cdd3c2fc69268dc8a16129194a72c606c7) +emitted operations + +big_map diff + + +storage + (Some 0x11f4ea2b3cd84230f43e085ae38a0c60d712486564ce5eabf2de3df5f0da8d891657ce1f0c9fcf016b9aff1f48bc583d12ced40a391db04687b45de84f4a59eeef3c3db75ad8862c4241d03dd0bf36ff855156a58f185234bef6ec7301826f8c00b0f31e6a7c2c87eb9866c0259cf5b30997a7ea4513a70edc430c2e201822a3cea3bf3e0d2ad17680036d3423f2db7f132866d134609c331dc4aa1caf0caef348c51633e789f152b6cc255a8fc426c27331b519eb0cefd05b08bd23c2db1aba) +emitted operations + +big_map diff + + +storage + (Some 0x08968210984e1431183676214a406cb925239d7eb1334a07bae001019419d0f41ade7163bcf5578b7b7cea9c9efa12ca0dced010adea7a72bce2be7f2dee13be641ee209b87fb4ae77b00b43f30f770f6c745e9d4617d22020d5686ae40a495219db215c85c3166e233a2027314f1c3807aca9e90315a9dd0da624a87c61c709e2fad9b800290ebddbb413f5655ebb6b01008c500234652c966f668524577ddd3268ba1934d0eb44171fb2d2c8f24c21ff1edc3a68473604e2660646de8fe01a) +emitted operations + +big_map diff + + +storage + (Some 0x04d151207587d306af535541cd193cfc0f0039e84155c78bf9b0e5ef4b61f6cc49f39f9e84ed48c7c9b04c6e78dfc4b317fadc38e9900aefc0ff618ff983eb713861d8ff8cd0af5a9445f0cad43bef39ed4e0855072b8dae4ccec6f6ae7e1a62134d156f2cd1587df87ae54cbb3a6de862dbda2c898cc94e93833a573380d3af53d17061668c6693264cb124c87ab2050c9ecf6526f6401055724eb2fcb5173453c77870eedb8f774a711b8b75d0e7308c8e1aa3acda6466c48f148dbe04d1ad) +emitted operations + +big_map diff + + +storage + (Some 0x0c430e8fe9556cc97d2b00a6d84ae91f4eabd287e8a9ab9fb158b80eae7b000109f5ef7dd5d1efc9b7de64077041337110cdaa2bb05c7dbd6751bcdb6ade70100794d1a0ef3d462ae7e6a969a83e9f81245d389810da2e3ba8993ef7daff017005b222f1c29db487aac92aab1068afda51cd1e5489fc8931d2d9bdc142db5cccc17c65f729a57cf0ef7e4af9449f77000f39713ef371664621e2ad89f7c0261f4415dee34a6fe7c8dd041257bd2b793745d70103be171d0326cdc0321487d37d) +emitted operations + +big_map diff + + +storage + (Some 0x093485ee7701aefb89433f119a5b8d5a4230dabdafe8e55f26b23190b8550a1c51aa83ea1939d33de5477a4599f5101d0b36aa79caab813b87e102a83105b6bdb892e2381578aad742e53293c9bd24463156ca976342cbd03059b174e811884207b155b1dfc641bb0180493fcf47ed39010fd2d8420098b6ce5c1378cd402f725e7a91ee74cf068e4111a76ebdd2e6030b0220df748b9882f8f17cfbd1e624341262073563e037281c86eb70212e399c5efe102e9b0ba01f0b89ef266cb37cf9) +emitted operations + +big_map diff + + +storage + (Some 0x19428930e5a0f05f3319c7f034baf62b00cabd1568cff58065f30046b90021873cf56360730fefba5f2930d9d661dcb5034274f468bd901fed787268a0abaf18641ff90df4651d82e5c6d8c76af87032a8ff6e6e8b1a7bf2965e6f23cf0da586112cd75db7d04b7ed070d16a4372f0520b1c06a995af83d4389b418b8c026f2f3ddbe2ff6d0d8430a61b9b7cce9ff9d7196e415e4390bab69c57f39392dc448df55ea15f576492d15d046904d49e634a03809ccb1873ec89f23e95753c335495) +emitted operations + +big_map diff + + +storage + (Some 0x17692241047f40181fc0ea3d78c9c576477c5c2bef94dc7e795a1f06a32278f59ee4a862338c8d91093336652ea979e20595946083e9500ad695371dd38a84d3782f9bd1362c22210abff64e461b6f0dd6480f5af62ad72f6501a3b1cd5cd36215eec26a3f41f51d8066b88cf6882651b9a90fab9858e91e8cbb4231cc523aa5d031ba95123bc6a5f8e4b2f52fff5b650a81e87155d9e039f6aa9807a4ff68e91c61fc0b80d10e28ffda4e1f088079926575b35ef7f776cb0f36648066765c01) +emitted operations + +big_map diff + + +storage + (Some 0x1541b770bc7b492490eba70ec85bdc68ca78eb22e4f67bfabdf84ee7769e615efde8e6bd754d03ec62c41583b0bef01d06ff063375db383cf814f3807a5127afd82f55bf157bba04e36399cbaf189f63da12d29b0c584833d55b6e788e27d4a5176635964576c34bc77e17c29ffd8cad66a2b14880bfb03f5fbef5a66152617a093935ceca865ff6115b04a3720316db0b0b49aecb7883f2700551b8b1f632d7d6dbb1b2a4777c8745300a152eb4b46c742d08df7e8f99715df3a561c233ef00) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[Fr].out new file mode 100644 index 000000000000..bc22ba307053 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_zero[Fr] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G1].out new file mode 100644 index 000000000000..8fefc56069a9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_zero[G1] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G2].out new file mode 100644 index 000000000000..b98f76c3d6cf --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_neg_zero[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_neg_zero[G2] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g1.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g1.out new file mode 100644 index 000000000000..95b89fe096d4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g1.out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_neg_g1 + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g2.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g2.out new file mode 100644 index 000000000000..385f759e1a5a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_neg_g2.out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_neg_g2 + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_nil.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_nil.out new file mode 100644 index 000000000000..e66ebfa4d9c2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_nil.out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_nil + +storage + (Some True) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_one.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_one.out new file mode 100644 index 000000000000..39f819e6f764 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_one.out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_one_one + +storage + (Some False) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_random.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_random.out new file mode 100644 index 000000000000..ac166d307f77 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_random.out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_one_random + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_zero.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_zero.out new file mode 100644 index 000000000000..cd0c784681ae --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_one_zero.out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_one_zero + +storage + (Some True) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_one.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_one.out new file mode 100644 index 000000000000..0964d74f7af6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_one.out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_random_one + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_random.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_random.out new file mode 100644 index 000000000000..c8f1b6fe0143 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_random.out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_random_random + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + +storage + (Some False) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_zero.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_zero.out new file mode 100644 index 000000000000..b3d8481af27e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_random_zero.out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_random_zero + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_one.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_one.out new file mode 100644 index 000000000000..15a8345bf9a2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_one.out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_zero_one + +storage + (Some True) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_random.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_random.out new file mode 100644 index 000000000000..a82ad61f7a2b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_random.out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_zero_random + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_zero.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_zero.out new file mode 100644 index 000000000000..7c777eb84708 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_pairing_zero_zero.out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_pairing_zero_zero + +storage + (Some True) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_signature_aggregation.out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_signature_aggregation.out new file mode 100644 index 000000000000..15895f8b2db1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_signature_aggregation.out @@ -0,0 +1,142 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_signature_aggregation + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + +storage + (Some True) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[Fr].out new file mode 100644 index 000000000000..98e893cbb1e0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_one[Fr] + +storage + (Some 0x0100000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G1].out new file mode 100644 index 000000000000..f2a038316ece --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_one[G1] + +storage + (Some 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G2].out new file mode 100644 index 000000000000..ed061f0b4c62 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_one[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_one[G2] + +storage + (Some 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[Fr].out new file mode 100644 index 000000000000..64f7daab127d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[Fr].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_random[Fr] + +storage + (Some 0x4fa3eebe8eb999919b25e9496a740ba7e3db1e6af6d7dfc4226af5b7ff1bb31a) +emitted operations + +big_map diff + + +storage + (Some 0xeb3b4692c6d5d3be4529f58dc95561395d4fb06a4b56d5ecee427cb769df650c) +emitted operations + +big_map diff + + +storage + (Some 0x0fd278b6ab93ce8d6b66643b0173fd4e80d0d1776d0de34b13b6ff24227bae29) +emitted operations + +big_map diff + + +storage + (Some 0x9a6bc10fb59d3d43dd642524ddeb3f901c185488da989078efbd0166b878a66b) +emitted operations + +big_map diff + + +storage + (Some 0xd2e244946f6aa1a9f2e36a9f83faf915dd94d7fb31b1a4642eb7bb73861d0a58) +emitted operations + +big_map diff + + +storage + (Some 0xce66a6b5c6d97c52c44f3430271d6c466b1c9f656d43a3f6db6fb76a77b56d02) +emitted operations + +big_map diff + + +storage + (Some 0xfb437df580e072dbc887e9e0546c0843ccdc7b31264730e8e2f3c341a2d13908) +emitted operations + +big_map diff + + +storage + (Some 0xa1d61bc7847d649c7ed6bfdb0511393e83e6a8fe6a8999748ea767f44e2bca11) +emitted operations + +big_map diff + + +storage + (Some 0x5839a13cbc9d2ab02bba8d95197a7145d30d49b05c809ecf226e3e10a5181e02) +emitted operations + +big_map diff + + +storage + (Some 0x90348d02274bba201f5cb5a914c73410d7b34f5bbe090b3cfbe92ae307709055) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G1].out new file mode 100644 index 000000000000..1f3e72010847 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G1].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_random[G1] + +storage + (Some 0x18782e3fbbe1f7abb5e2021b79bce810b5e8ae950c1e60d41731f0ae2ee4ebacbe59a9837bc34d5c61896561b04002be1760374bfa91e105077c507da80c080fe3a6c0ed820ce2515535f339b3f1510016ad6da0ff1a277065798e11aec2f74d) +emitted operations + +big_map diff + + +storage + (Some 0x1054b960d67ee71da9b596e7c543faf72544ba1ea2bc24d635f3da62feeeab2d0b00a8fed7ecf450767e1fdf1f2a913c127c6632387c6b5364a82dd2ff346b93cd29555913377b887c32e5a58fa37a7e69d1d82065e8b84865fee75aca361e6a) +emitted operations + +big_map diff + + +storage + (Some 0x0dbd1f474d065640ee4bde569142e26f7101a5c339c2f6630db6201c47483ed1303637aacb90002e1d7e7a84804b126205a8189fa87963e0fc81ea9c63e0a288768689f0ebe0868d98e9bb7e975026876f1df8502c6340adb3fde872f308704c) +emitted operations + +big_map diff + + +storage + (Some 0x141bebcd3a9c4145dcf836d368618d106cb3ab96669cce51cda04944eb3e0f07f0151a6fb4ba31d395692d4a305d623818a95f330d82b398d85782eb3a2793e098078058a289d5c5903cb78541807339db47e47d7dbbf2b5b4f0b6f9af323626) +emitted operations + +big_map diff + + +storage + (Some 0x088dcd93944d3cd43068b322488e178dd56f0ac3572d535d2c2d1da410e27572e425a4fcbbb8e10836f88d4010dba4a105a5ba71e19fc20bc6054df060a52887551b7b81196d63a3572c080705e9598e20cf3319343940de851d3d7ead06e8e9) +emitted operations + +big_map diff + + +storage + (Some 0x14c66800599dae815074aecfc36e2d43e2cdcf0c6663d9a0ab082488230ed0f6af46976598062df148d8b96144f55c5210e252370e812f951b90cc9765edbd2db2ba8157590338b3f5717a1bed450453f2674e3502bc95b2a8808e6d7442eada) +emitted operations + +big_map diff + + +storage + (Some 0x172318134285db82ebf7eab40d471dd4f733c0a624b360d8df00305ed381f3d59c7a54ce3996be88a63ce593a01c66e813ddee3711dca2ff243ea1e7141de5aec0a7611e67fa1f9c0e89ce7145ce58d0eef987d8949ad02d671166597d3a03ed) +emitted operations + +big_map diff + + +storage + (Some 0x0eb24546ddd153b1f2511c6155417c1d3fcc9750cb6b3af4367d01d485c2b6dba27cb1a7f19286e646e2f7a7aaf0363415735526cbb0f20f3d4141e6776f3c8b3255ee11ef05418ebfa62cf7e03220a5013a27e020544752260e295156f49c0a) +emitted operations + +big_map diff + + +storage + (Some 0x0e76d4b163d641ed1edbfdebdfa71c9fb6ad2e556e56ea0dadc3ea6bfc59b77e1e070063d9eb428b7730f35362310ac917e2386fd701b9389afb48d090552b8cb7a808aaec6669a06db758a7b30cf50933a275bac9a6e56ee4011fce86c496dd) +emitted operations + +big_map diff + + +storage + (Some 0x0a58dd111159092a784e404e0fbe2b03681a0c60ce1ebe52fea33f9780ac82118b6b8583b68fed0907adffdeef055d74120b04a2ebfd3a2a60a638cc4cd997090bb9b04d19cddcd61f9078903bd9f3e65fcdf9e5aec6de5a574ff7daef7cb079) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G2].out new file mode 100644 index 000000000000..e19cf8d9575a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_random[G2].out @@ -0,0 +1,72 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_random[G2] + +storage + (Some 0x0fdb404adcca2b3e91f5b6824e6f3c88d0086605135f34e733a47749f72e941ea0a546307b76881a2735b6aa24d630a20b9c453f8be68c3a875c4623df2156e61419a83dec2945fab6a50256f03cc9beabfb209d91858be53ead266aff598280191da483f4545715b6bfed1f3bc1aed02f97ed2e92f5bd9818432d1a17c6cef0b738beacef691b40c48b310a3befb95c10e67239e6fdf04c5c6720107466f19bb4d21b06ec221b72cf1a0b6ec4c1657872af587ffdda647cb36f9d73089b83d5) +emitted operations + +big_map diff + + +storage + (Some 0x00ec703f53406268b162add4b534cafad633e6d9453d289aad5f00a7ac68e2a9b1d97e9fb3b622bd95597b62b1fa0e7211fc2a54d8fded35cd021de7396db9dc1bdadce1d940da9c0dfbc6883c1212c639f2982b0f8943fe08ec1a12f1ea03081326c959ac2d47e6f75eacdf604efaa784796cafa511ad560c73552b9db0f8c9e0b1c281163f05b5d86b6b939c8fa5f512f6352c990f48e11a057e748a9695ae1d277918be1aa8fab5c96df723c47825136ef09c36d562214c25a087a5667b39) +emitted operations + +big_map diff + + +storage + (Some 0x17100f69943b685b53113c589254c0b26b23808b376a6addffa896ef873147871a0194d077acce64254e667890048f18056a3208afc3295e0829902800cfa9fcf50edc78841749d02198a3946010e6d800bd36171d41dfb6d79988f61524136003db45da43b3825c6dcf8b9ef46c8a40c842fcc3fee4ccf6d119b7b643ead789612ba75fca0d0a16dd31be31658c7b1d122b6a32d75113bb900ccf4a4da9cefc69b23814c486c9ade79d82eaa0593167b14a06ea2158f9d7710318d82553f1c5) +emitted operations + +big_map diff + + +storage + (Some 0x039c8fa2998d6fd874ea7b5cdfa5089bbe4cddd9958b445b6f33f65c27fd47b56a911e8134fe620275e7feece2ba1f560f731c917b8f756ec340c9d213a14c0f04bc79488ad38ca088d96c9a1c899aabc6cbf5070abf3231394b917c428fb0c5148e4d6c75c3b64e614582fefd2ccc979767d4b4da262d9c95ab27cf2fdf500268f0de8ecce5dad0f8ff5a06ef0e270f0dafac5b9ee6c9ff6665954a58e7dc792a257c1d80f27c1f91f9dedf4efc8da6e1d69d445364c7b7c076aef189f594e7) +emitted operations + +big_map diff + + +storage + (Some 0x118f6abab59d71635a4206e8fd16212e6d2f5f7c756e4308505f9e6473002a198292be2c834ca70cb40a1abeb3989c820a94d180da0025992a5c5ce516a2fa84c2e66d772acaf71c990aecefe420f885823f55bfdfa13db98035ae41c06ee6dc1305555d6da8ba4a92fd9eda92934ac5aed6db9fcc925fa51193a0ddf04594f2707d680d710171f041222e14644debfd14f43b880a07bdca546ffd02d792ed38be37171971ff662b094d54a37816aff6efbb2e57875dd9af97dee97e8c5f6109) +emitted operations + +big_map diff + + +storage + (Some 0x11308b1d8c4cb3cb1a57c98f1163ea78c44c1035cbc741988dc56a3c10c3d3b94b29445eae3199073857dbe6b146d6aa087a91a83306c1cbbc1f2eef3d058639ceda4e98ab1124dbaccc52dd25d7116675de0ba740fe95f2700ec1504461365a08ff04b06bba77a77b5b7ffa45a3ec56c8626fb7219f0d2d891251c1b4881f141bbbaf09217044e9bb69c8c1652476500153567f2ca8dd517cbd1c3467c10771d02fbf45fdad811118b325ce97e43ef72beff8857f44b0968de7b01a770fddd0) +emitted operations + +big_map diff + + +storage + (Some 0x0172fab176d798aed92f6ac9abeb28c510d77fd42601522db72c8fd7abe52fa0ce5adfb2ef67739bc4fb64fbbe3cd52b12a54aa1af0a44cdcc5c9110c13eac553ff037f1a8f304d052a0fc96ea40c946d5d31a8427feb1249fec862c28356afc0794bfcdc71fb3dfcf664e9a8db201c5b774ec45c2f0028531ff6abd2292dc1856fa9420fc8f5b632e84a592d73b25ba0fbb3e8cc6371e5f0d6c04b356f0e9d786545619a397f1dc1041854b5bde626b1b1d01258d6b16a80588453996a6eb00) +emitted operations + +big_map diff + + +storage + (Some 0x0156d0250e60af2f0678224eed0afee0594bb6f85293f7c4ab93b17ea0231bc1590d28250968931b8ee23a6f0f364d8c029e81178b6e60e9de5f858d44b102b823a028c4b8c230cf78e5f8a77964fda2bc4cb1a8cafd08641dcb20689b0903c104e58754b4c52b2b225473b407544d32823b8a7b47b2b919b96da883e20bd8a526ffe21928186d36d8355c16aa56523004f6dc232f441b80a9efaedec4dfd3abafffa97af0623f434e324120ecf61516affd143cc275ebda8c7552c89c718764) +emitted operations + +big_map diff + + +storage + (Some 0x058b2dbf9ed4d328d9afa79262a86ef47a044bba9226441df410d255040ae88931ca92ad6f127656c2309a3f9724af830cdb406c0cf88f930976f2b162d300d58930a9ef86869073be0043e9383e5875d9f5ce8a2cfee895f2591b6a265811ca13baaa13b0d54995b9ac5c2bd893730b07abf2f8b4c99b121870227c594365dac3e330dbeff1c2fb93f8b1dc6ec4d8311525ee7f96ac8b71f94b149bde3749c2d03fb8494592daafb6963c6a9427b887d67b0ad72c29804aff97897e6272379b) +emitted operations + +big_map diff + + +storage + (Some 0x0cfe1a34585ccf7095a05262a23fa1acde77911d1b9d0f894d63457ae6da644c417569c14a4e39b0ee2e51926a1ce7f108d6d899a1e78d27e6586f31d50fdf882d001bdb7fe934061214b756c5a9e64b66b5b13cd4c44ba1dd97101e394f82ec0661b38d968d819b85eab59f321c42b2d05e8037f4d1ba00bcaa80f2fe8f4130c4e292c073a856e095cc823965ffe97918ef4fa0f24b9bfa56b0ce783b3a6362de2781080d6ff52651e6ff71176b873318138cade3d284921c3eacf1734f5854) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[Fr].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[Fr].out new file mode 100644 index 000000000000..88cb9becc290 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[Fr].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_zero[Fr] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G1].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G1].out new file mode 100644 index 000000000000..fc8adbe26dbf --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G1].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_zero[G1] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G2].out b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G2].out new file mode 100644 index 000000000000..8062679b969c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_bls12_381.TestBls12_381::test_store_zero[G2].out @@ -0,0 +1,9 @@ +tests_012/test_contract_bls12_381.py::TestBls12_381::test_store_zero[G2] + +storage + (Some 0x400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert.tz].out new file mode 100644 index 000000000000..73b229b0e7b4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert.tz].out @@ -0,0 +1,9 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert.tz] + +{ parameter bool ; + storage unit ; + code { CAR ; + { IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpeq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpeq.tz].out new file mode 100644 index 000000000000..63aefde095f8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpeq.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmpeq.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpge.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpge.tz].out new file mode 100644 index 000000000000..eadfe810d1e8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpge.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmpge.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + { { COMPARE ; GE } ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpgt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpgt.tz].out new file mode 100644 index 000000000000..6c3e2fc00d97 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpgt.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmpgt.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + { { COMPARE ; GT } ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmple.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmple.tz].out new file mode 100644 index 000000000000..a7a0aa339255 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmple.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmple.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + { { COMPARE ; LE } ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmplt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmplt.tz].out new file mode 100644 index 000000000000..7db26261470c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmplt.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmplt.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + { { COMPARE ; LT } ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpneq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpneq.tz].out new file mode 100644 index 000000000000..8281a51a45a5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_cmpneq.tz].out @@ -0,0 +1,12 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_cmpneq.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + { { COMPARE ; NEQ } ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_eq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_eq.tz].out new file mode 100644 index 000000000000..f9d6aa69ffb6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_eq.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_eq.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + COMPARE ; + { EQ ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_ge.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_ge.tz].out new file mode 100644 index 000000000000..e6839e18cde3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_ge.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_ge.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + COMPARE ; + { GE ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_gt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_gt.tz].out new file mode 100644 index 000000000000..8131a6070565 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_gt.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_gt.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + COMPARE ; + { GT ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_le.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_le.tz].out new file mode 100644 index 000000000000..8f6de3876233 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_le.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_le.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + COMPARE ; + { LE ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_lt.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_lt.tz].out new file mode 100644 index 000000000000..62b0df98f5dc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_lt.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_lt.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + COMPARE ; + { LT ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_neq.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_neq.tz].out new file mode 100644 index 000000000000..7517c229153d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--assert_neq.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/assert_neq.tz] + +{ parameter (pair int int) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + DIP { CDR } ; + COMPARE ; + { NEQ ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_get_add.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_get_add.tz].out new file mode 100644 index 000000000000..f8f1fb38a522 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_get_add.tz].out @@ -0,0 +1,23 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/big_map_get_add.tz] + +{ parameter (pair (pair %set_pair int (option int)) (pair %check_pair int (option int))) ; + storage (pair (big_map int int) unit) ; + code { DUP ; + DIP { { CDR ; CAR } } ; + DUP ; + DIP { { CAR ; CDR } ; DUP ; CAR ; DIP { CDR } ; UPDATE ; DUP } ; + { CAR ; CDR } ; + DUP ; + CDR ; + DIP { CAR ; GET } ; + { IF_NONE + { { IF_NONE {} { { UNIT ; FAILWITH } } } } + { SWAP ; + { IF_NONE + { { UNIT ; FAILWITH } } + { { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } } } } } ; + UNIT ; + SWAP ; + PAIR ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_mem.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_mem.tz].out new file mode 100644 index 000000000000..6db7b356f9b9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--big_map_mem.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/big_map_mem.tz] + +{ parameter (pair int bool) ; + storage (pair (big_map int unit) unit) ; + code { DUP ; + DUP ; + { CAR ; CDR } ; + DIP { { CAR ; CAR } ; DIP { { CDR ; CAR } ; DUP } ; MEM } ; + { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; + UNIT ; + SWAP ; + PAIR ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--build_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--build_list.tz].out new file mode 100644 index 000000000000..a20f0c24ff94 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--build_list.tz].out @@ -0,0 +1,24 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/build_list.tz] + +{ parameter nat ; + storage (list nat) ; + code { CAR @counter ; + NIL @acc nat ; + SWAP ; + DUP @cmp_num ; + PUSH nat 0 ; + { COMPARE ; NEQ } ; + LOOP { DUP ; + DIP { SWAP } ; + CONS @acc ; + SWAP ; + PUSH nat 1 ; + SWAP ; + SUB @counter ; + DUP ; + DIP { ABS } ; + PUSH int 0 ; + { COMPARE ; NEQ } } ; + CONS ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--carn_and_cdrn.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--carn_and_cdrn.tz].out new file mode 100644 index 000000000000..c39037ddb4e2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--carn_and_cdrn.tz].out @@ -0,0 +1,29 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/carn_and_cdrn.tz] + +{ parameter (pair nat nat nat unit) ; + storage unit ; + code { CAR ; + DUP ; + CAR ; + PUSH nat 1 ; + { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; + DUP ; + { GET 1 } ; + PUSH nat 1 ; + { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; + DUP ; + { GET 3 } ; + PUSH nat 4 ; + { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; + DUP ; + { GET 5 } ; + PUSH nat 2 ; + { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; + DUP ; + { GET 6 } ; + UNIT ; + { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; + DROP ; + UNIT ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare.tz].out new file mode 100644 index 000000000000..37cd38a739c8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/compare.tz] + +{ parameter (pair mutez mutez) ; + storage (list bool) ; + code { CAR ; + DUP ; + DUP ; + DUP ; + DUP ; + DIP 5 { NIL bool } ; + DIP 4 { DUP ; CAR ; DIP { CDR } ; COMPARE ; LE ; CONS } ; + DIP 3 { DUP ; CAR ; DIP { CDR } ; COMPARE ; GE ; CONS } ; + DIP 2 { DUP ; CAR ; DIP { CDR } ; COMPARE ; LT ; CONS } ; + DIP { DUP ; CAR ; DIP { CDR } ; COMPARE ; GT ; CONS } ; + DUP ; + CAR ; + DIP { CDR } ; + COMPARE ; + EQ ; + CONS ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare_bytes.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare_bytes.tz].out new file mode 100644 index 000000000000..6250ef70c159 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--compare_bytes.tz].out @@ -0,0 +1,22 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/compare_bytes.tz] + +{ parameter (pair bytes bytes) ; + storage (list bool) ; + code { CAR ; + DUP ; + DUP ; + DUP ; + DUP ; + DIP 5 { NIL bool } ; + DIP 4 { DUP ; CAR ; DIP { CDR } ; COMPARE ; LE ; CONS } ; + DIP 3 { DUP ; CAR ; DIP { CDR } ; COMPARE ; GE ; CONS } ; + DIP 2 { DUP ; CAR ; DIP { CDR } ; COMPARE ; LT ; CONS } ; + DIP { DUP ; CAR ; DIP { CDR } ; COMPARE ; GT ; CONS } ; + DUP ; + CAR ; + DIP { CDR } ; + COMPARE ; + EQ ; + CONS ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--fail.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--fail.tz].out new file mode 100644 index 000000000000..64d32bbf527a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--fail.tz].out @@ -0,0 +1,3 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/fail.tz] + +{ parameter unit ; storage unit ; code { { UNIT ; FAILWITH } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--guestbook.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--guestbook.tz].out new file mode 100644 index 000000000000..0ded6828d28f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--guestbook.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/guestbook.tz] + +{ parameter string ; + storage (map address (option string)) ; + code { UNPAIR @message @guestbook ; + SWAP ; + DUP ; + SENDER ; + GET @previous_message ; + { IF_NONE { { UNIT ; FAILWITH } } {} } ; + { IF_NONE {} { { UNIT ; FAILWITH } } } ; + SWAP ; + SOME ; + SOME ; + SENDER ; + UPDATE ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--macro_annotations.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--macro_annotations.tz].out new file mode 100644 index 000000000000..c2cb3318b0d3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--macro_annotations.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/macro_annotations.tz] + +{ parameter unit ; + storage (pair (unit %truc) unit) ; + code { DROP ; + UNIT ; + UNIT ; + PAIR %truc ; + UNIT ; + DUP @new_storage 2 ; + DIP { DROP ; DROP } ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--map_caddaadr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--map_caddaadr.tz].out new file mode 100644 index 000000000000..269f1aa95c0e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--map_caddaadr.tz].out @@ -0,0 +1,40 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/map_caddaadr.tz] + +{ parameter unit ; + storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat) ; + code { { DUP ; + DIP { CDR @%% ; + { DUP ; + DIP { CAR @%% ; + { DUP ; + DIP { CDR @%% ; + { DUP ; + DIP { CDR @%% ; + { DUP ; + DIP { CAR @%% ; + { DUP ; + DIP { CAR @%% ; + { DUP ; + CDR @value ; + { PUSH mutez 1000000 ; ADD } ; + SWAP ; + CAR @%% ; + PAIR %@ %value } } ; + CDR @%% ; + SWAP ; + PAIR %@ %@ } } ; + CDR @%% ; + SWAP ; + PAIR %@ %@ } } ; + CAR @%% ; + PAIR %@ %@ } } ; + CAR @%% ; + PAIR %@ %@ } } ; + CDR @%% ; + SWAP ; + PAIR %@ %@ } } ; + CAR @%% ; + PAIR %@ %@ @new_storage } ; + NIL operation ; + SWAP ; + { CDR @%% ; SWAP ; PAIR % %@ } } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--max_in_list.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--max_in_list.tz].out new file mode 100644 index 000000000000..e1547da1de33 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--max_in_list.tz].out @@ -0,0 +1,17 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/max_in_list.tz] + +{ parameter (list int) ; + storage (option int) ; + code { CAR ; + DIP { NONE int } ; + ITER { SWAP ; + IF_NONE + { SOME } + { DIP { DUP } ; + DUP ; + DIP { SWAP } ; + { COMPARE ; LE } ; + IF { DROP } { DIP { DROP } } ; + SOME } } ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--min.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--min.tz].out new file mode 100644 index 000000000000..237da146c9dc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--min.tz].out @@ -0,0 +1,13 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/min.tz] + +{ parameter (pair int int) ; + storage int ; + code { CAR ; + DUP ; + DUP ; + CAR ; + DIP { CDR } ; + { COMPARE ; LT } ; + IF { CAR } { CDR } ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--pair_macro.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--pair_macro.tz].out new file mode 100644 index 000000000000..a3da0c31fabc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--pair_macro.tz].out @@ -0,0 +1,18 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/pair_macro.tz] + +{ parameter unit ; + storage unit ; + code { UNIT ; + UNIT ; + UNIT ; + UNIT ; + UNIT ; + { DIP 3 { PAIR %x4 %x5 } ; + DIP 2 { PAIR %x3 } ; + DIP { PAIR %x2 } ; + PAIR %x1 @name } ; + { CDR ; CDR ; CDR ; CAR %x4 @fourth } ; + DROP ; + CDR ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--set_caddaadr.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--set_caddaadr.tz].out new file mode 100644 index 000000000000..768648c3987b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--set_caddaadr.tz].out @@ -0,0 +1,33 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/set_caddaadr.tz] + +{ parameter mutez ; + storage (pair (pair nat (pair nat (pair (pair (pair (nat %p) (mutez %value)) nat) nat))) nat) ; + code { DUP ; + CAR ; + SWAP ; + CDR ; + { DUP ; + DIP { CAR @%% ; + { DUP ; + DIP { CDR @%% ; + { DUP ; + DIP { CDR @%% ; + { DUP ; + DIP { CAR @%% ; + { DUP ; + DIP { CAR @%% ; { DUP ; CDR %value ; DROP ; CAR @%% ; PAIR %@ %value } } ; + CDR @%% ; + SWAP ; + PAIR %@ %@ } } ; + CDR @%% ; + SWAP ; + PAIR %@ %@ } } ; + CAR @%% ; + PAIR %@ %@ } } ; + CAR @%% ; + PAIR %@ %@ } } ; + CDR @%% ; + SWAP ; + PAIR %@ %@ @toplevel_pair_name } ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--take_my_money.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--take_my_money.tz].out new file mode 100644 index 000000000000..fc9217b03bf6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--take_my_money.tz].out @@ -0,0 +1,14 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/take_my_money.tz] + +{ parameter key_hash ; + storage unit ; + code { CAR ; + IMPLICIT_ACCOUNT ; + DIP { UNIT } ; + PUSH mutez 1000000 ; + UNIT ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--unpair_macro.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--unpair_macro.tz].out new file mode 100644 index 000000000000..1b5a2e9a4d4d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_macros.TestMacroExpansion::test_macro_expansion[macros--unpair_macro.tz].out @@ -0,0 +1,20 @@ +tests_012/test_contract_macros.py::TestMacroExpansion::test_macro_expansion[macros/unpair_macro.tz] + +{ parameter (unit :param_unit) ; + storage (unit :u1) ; + code { DROP ; + UNIT :u4 @a4 ; + UNIT :u3 @a3 ; + UNIT :u2 @a2 ; + UNIT :u1 @a1 ; + PAIR ; + UNPAIR @x1 @x2 ; + { DIP 2 { PAIR %x3 %x4 } ; PAIR %x1 %x2 ; PAIR @p1 } ; + { UNPAIR ; UNPAIR ; DIP 2 { UNPAIR } } ; + { DIP 2 { PAIR %x3 %x4 } ; DIP { PAIR %x2 } ; PAIR %x1 @p2 } ; + { UNPAIR ; DIP { UNPAIR } ; DIP 2 { UNPAIR } } ; + { DIP { PAIR %x2 %x3 } ; DIP { PAIR % %x4 } ; PAIR %x1 @p3 } ; + { UNPAIR ; DIP { UNPAIR } ; DIP { UNPAIR } } ; + DIP { DROP ; DROP ; DROP } ; + NIL operation ; + PAIR } } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_diff.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_diff.out new file mode 100644 index 000000000000..91dd75404766 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_diff.out @@ -0,0 +1,29 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_origination_diff + +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1040000 + Storage limit: 60000 bytes + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter (big_map int int) ; + storage (big_map int int) ; + code { CAR ; NIL operation ; PAIR } } + Initial storage: (Pair 0 { Elt 1 (Some 4) }) + No delegate for this contract + This operation FAILED. + +Ill typed data: 1: (Pair 0 { Elt 1 (Some 4) }) +is not an expression of type big_map int int +At line 1 characters 0 to 26, value (Pair 0 { Elt 1 (Some 4) }) +is invalid for type big_map int int. +At line 1 characters 6 to 7, +Unexpected forged value. +Fatal error: + origination simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_id.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_id.out new file mode 100644 index 000000000000..f1bf6c969bb1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_id.out @@ -0,0 +1,27 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_origination_id + +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1040000 + Storage limit: 60000 bytes + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter (big_map int int) ; + storage (big_map int int) ; + code { CAR ; NIL operation ; PAIR } } + Initial storage: 0 + No delegate for this contract + This operation FAILED. + +Ill typed data: 1: 0 is not an expression of type big_map int int +At line 1 characters 0 to 1, value 0 is invalid for type big_map int int. +At line 1 characters 0 to 1, +Unexpected forged value. +Fatal error: + origination simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_literal.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_literal.out new file mode 100644 index 000000000000..590a4ff18932 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_origination_literal.out @@ -0,0 +1,50 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_origination_literal + +Node is bootstrapped. +Estimated gas: 1638.345 units (will add 100 for safety) +Estimated storage: 403 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.00046 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1739 + Storage limit: 423 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.00046 + payload fees(the block proposer) ....... +ꜩ0.00046 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter (big_map int int) ; + storage (big_map int int) ; + code { CAR ; NIL operation ; PAIR } } + Initial storage: { Elt 0 0 } + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 146 bytes + Updated big_maps: + New map(4) of type (big_map int int) + Set map(4)[0] to 0 + Paid storage size diff: 146 bytes + Consumed gas: 1638.345 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0365 + storage fees ........................... +ꜩ0.0365 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as originate_big_map_literal. +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_diff.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_diff.out new file mode 100644 index 000000000000..12e3d71a254e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_diff.out @@ -0,0 +1,23 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_transfer_diff + +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1040000 + Storage limit: 60000 bytes + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair 0 { Elt 1 (Some 4) }) + This operation FAILED. + +Invalid argument passed to contract [CONTRACT_HASH]. +At (unshown) location 0, value (Pair 0 { Elt 1 (Some 4) }) +is invalid for type big_map int int. +At (unshown) location 1, Unexpected forged value. +Fatal error: + transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_id.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_id.out new file mode 100644 index 000000000000..6fc4325186f8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractBigMapOrigination::test_big_map_transfer_id.out @@ -0,0 +1,22 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractBigMapOrigination::test_big_map_transfer_id + +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1040000 + Storage limit: 60000 bytes + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: 0 + This operation FAILED. + +Invalid argument passed to contract [CONTRACT_HASH]. +At (unshown) location 0, value 0 is invalid for type big_map int int. +At (unshown) location 0, Unexpected forged value. +Fatal error: + transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainLevel::test_level.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainLevel::test_level.out new file mode 100644 index 000000000000..5ccd959c2d47 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainLevel::test_level.out @@ -0,0 +1,123 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainLevel::test_level + +Node is bootstrapped. +Estimated gas: 1406.044 units (will add 100 for safety) +Estimated storage: 300 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000424 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1507 + Storage limit: 320 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000424 + payload fees(the block proposer) ....... +ꜩ0.000424 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ100 + Script: + { parameter unit ; + storage nat ; + code { DROP ; LEVEL ; NIL operation ; PAIR } } + Initial storage: 9999999 + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 43 bytes + Paid storage size diff: 43 bytes + Consumed gas: 1406.044 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01075 + storage fees ........................... +ꜩ0.01075 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + +New contract [CONTRACT_HASH] originated. +Contract memorized as level. +Injected block at minimal timestamp +Injected block at minimal timestamp +Node is bootstrapped. +Estimated gas: 2049.563 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000467 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2150 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000467 + payload fees(the block proposer) ....... +ꜩ0.000467 + Transaction: + Amount: ꜩ500 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Updated storage: 4 + Storage size: 40 bytes + Consumed gas: 2049.563 + Balance updates: + [CONTRACT_HASH] ... -ꜩ500 + [CONTRACT_HASH] ... +ꜩ500 + +Injected block at minimal timestamp +{ "level": [LEVEL], "proto": 1, + "predecessor": "[BLOCK_HASH]", + "timestamp": "[TIMESTAMP]", "validation_pass": 4, + "operations_hash": "[OPERATION_HASH]", + "fitness": "[FITNESS]", + "context": "[CONTEXT]" } +4 +Injected block at minimal timestamp +Injected block at minimal timestamp +4 +Node is bootstrapped. +Estimated gas: 1202.350 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000383 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1303 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000383 + payload fees(the block proposer) ....... +ꜩ0.000383 + Transaction: + Amount: ꜩ500 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Updated storage: 7 + Storage size: 40 bytes + Consumed gas: 1202.350 + Balance updates: + [CONTRACT_HASH] ... -ꜩ500 + [CONTRACT_HASH] ... +ꜩ500 + +Injected block at minimal timestamp +7 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_contract_fails.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_contract_fails.out new file mode 100644 index 000000000000..bcc125d7efa3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_contract_fails.out @@ -0,0 +1,2 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_contract_fails + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_gen_keys.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_gen_keys.out new file mode 100644 index 000000000000..78abad21129e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_gen_keys.out @@ -0,0 +1,2 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_gen_keys + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_init_proxy.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_init_proxy.out new file mode 100644 index 000000000000..6ed3c49e7854 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_init_proxy.out @@ -0,0 +1,53 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_init_proxy + +Node is bootstrapped. +Estimated gas: 1409.594 units (will add 100 for safety) +Estimated storage: 312 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000437 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1510 + Storage limit: 332 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000437 + payload fees(the block proposer) ....... +ꜩ0.000437 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter (contract unit) ; + storage unit ; + code { UNPAIR ; + AMOUNT ; + UNIT ; + TRANSFER_TOKENS ; + DIP { NIL operation } ; + CONS ; + PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 55 bytes + Paid storage size diff: 55 bytes + Consumed gas: 1409.594 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01375 + storage fees ........................... +ꜩ0.01375 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as proxy. +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_now.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_now.out new file mode 100644 index 000000000000..b92c1b50abac --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_now.out @@ -0,0 +1,2 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_now + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_self.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_self.out new file mode 100644 index 000000000000..e4bce90a657d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_self.out @@ -0,0 +1,2 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_self + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_sender.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_sender.out new file mode 100644 index 000000000000..8fa62935b57c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_sender.out @@ -0,0 +1,2 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_sender + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_set_delegate.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_set_delegate.out new file mode 100644 index 000000000000..caa317622114 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_set_delegate.out @@ -0,0 +1,123 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_set_delegate + +Node is bootstrapped. +Estimated gas: 1408.028 units (will add 100 for safety) +Estimated storage: 308 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000433 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1509 + Storage limit: 328 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000433 + payload fees(the block proposer) ....... +ꜩ0.000433 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter (option key_hash) ; + storage unit ; + code { UNPAIR ; SET_DELEGATE ; DIP { NIL operation } ; CONS ; PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 51 bytes + Paid storage size diff: 51 bytes + Consumed gas: 1408.028 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01275 + storage fees ........................... +ꜩ0.01275 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as set_delegate. +Injected block at minimal timestamp +Injected block at minimal timestamp +none +Node is bootstrapped. +Estimated gas: 3056.118 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000612 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 3157 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000612 + payload fees(the block proposer) ....... +ꜩ0.000612 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: (Some "[CONTRACT_HASH]") + This transaction was successfully applied + Updated storage: Unit + Storage size: 51 bytes + Consumed gas: 2056.118 + Internal operations: + Delegation: + Contract: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This delegation was successfully applied + Consumed gas: 1000 + +Injected block at minimal timestamp +[CONTRACT_HASH] (known as bootstrap5) +Node is bootstrapped. +Estimated gas: 2202.482 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000486 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2303 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000486 + payload fees(the block proposer) ....... +ꜩ0.000486 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: None + This transaction was successfully applied + Updated storage: Unit + Storage size: 51 bytes + Consumed gas: 1202.482 + Internal operations: + Delegation: + Contract: [CONTRACT_HASH] + To: nobody + This delegation was successfully applied + Consumed gas: 1000 + +Injected block at minimal timestamp +none diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice.out new file mode 100644 index 000000000000..97b84db5e807 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice.out @@ -0,0 +1,87 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice + +Node is bootstrapped. +Estimated gas: 1828.800 units (will add 100 for safety) +Estimated storage: 835 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.001023 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1929 + Storage limit: 855 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.001023 + payload fees(the block proposer) ....... +ꜩ0.001023 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter (pair bytes signature) ; + storage key ; + code { DUP ; + CAAR ; + DUP ; + SIZE ; + PUSH nat 128 ; + SWAP ; + SUB ; + ISNAT ; + ASSERT_SOME ; + PUSH nat 128 ; + SLICE @payload ; + ASSERT_SOME ; + DUP ; + DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; + SHA256 ; + ASSERT_CMPEQ } ; + DUP ; + DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; + BLAKE2B ; + ASSERT_CMPEQ } ; + DUP ; + DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; + SHA512 ; + ASSERT_CMPEQ } ; + DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; + SWAP ; + DIP { SWAP } ; + CHECK_SIGNATURE ; + ASSERT ; + CDR ; + DUP ; + HASH_KEY ; + IMPLICIT_ACCOUNT ; + BALANCE ; + UNIT ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } } + Initial storage: + "[OPERATION_HASH]na" + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 578 bytes + Paid storage size diff: 578 bytes + Consumed gas: 1828.800 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.1445 + storage fees ........................... +ꜩ0.1445 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as slices. +Injected block at minimal timestamp diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 \"spsig1PPUFZucuAQybs5wsqs.818025e860.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 \"spsig1PPUFZucuAQybs5wsqs.818025e860.out" new file mode 100644 index 000000000000..05bf8d60e5fa --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 \"spsig1PPUFZucuAQybs5wsqs.818025e860.out" @@ -0,0 +1,66 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] + +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1040000 + Storage limit: 60000 bytes + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair 0xe009ab79e8b84ef0 + "sp[SIGNATURE]m") + This operation FAILED. + +Runtime error in contract [CONTRACT_HASH]: + 01: { parameter (pair bytes signature) ; + 02: storage key ; + 03: code { DUP ; + 04: CAAR ; + 05: DUP ; + 06: SIZE ; + 07: PUSH nat 128 ; + 08: SWAP ; + 09: SUB ; + 10: ISNAT ; + 11: ASSERT_SOME ; + 12: PUSH nat 128 ; + 13: SLICE @payload ; + 14: ASSERT_SOME ; + 15: DUP ; + 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; + 17: SHA256 ; + 18: ASSERT_CMPEQ } ; + 19: DUP ; + 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; + 21: BLAKE2B ; + 22: ASSERT_CMPEQ } ; + 23: DUP ; + 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; + 25: SHA512 ; + 26: ASSERT_CMPEQ } ; + 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; + 28: SWAP ; + 29: DIP { SWAP } ; + 30: CHECK_SIGNATURE ; + 31: ASSERT ; + 32: CDR ; + 33: DUP ; + 34: HASH_KEY ; + 35: IMPLICIT_ACCOUNT ; + 36: BALANCE ; + 37: UNIT ; + 38: TRANSFER_TOKENS ; + 39: NIL operation ; + 40: SWAP ; + 41: CONS ; + 42: PAIR } } +At line 11 characters 9 to 20, +script reached FAILWITH instruction +with Unit +Fatal error: + transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.2d6806d54e.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.2d6806d54e.out new file mode 100644 index 000000000000..a54058e22fff --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.2d6806d54e.out @@ -0,0 +1,66 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2deaad01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] + +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1040000 + Storage limit: 60000 bytes + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 + "sp[SIGNATURE]m") + This operation FAILED. + +Runtime error in contract [CONTRACT_HASH]: + 01: { parameter (pair bytes signature) ; + 02: storage key ; + 03: code { DUP ; + 04: CAAR ; + 05: DUP ; + 06: SIZE ; + 07: PUSH nat 128 ; + 08: SWAP ; + 09: SUB ; + 10: ISNAT ; + 11: ASSERT_SOME ; + 12: PUSH nat 128 ; + 13: SLICE @payload ; + 14: ASSERT_SOME ; + 15: DUP ; + 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; + 17: SHA256 ; + 18: ASSERT_CMPEQ } ; + 19: DUP ; + 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; + 21: BLAKE2B ; + 22: ASSERT_CMPEQ } ; + 23: DUP ; + 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; + 25: SHA512 ; + 26: ASSERT_CMPEQ } ; + 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; + 28: SWAP ; + 29: DIP { SWAP } ; + 30: CHECK_SIGNATURE ; + 31: ASSERT ; + 32: CDR ; + 33: DUP ; + 34: HASH_KEY ; + 35: IMPLICIT_ACCOUNT ; + 36: BALANCE ; + 37: UNIT ; + 38: TRANSFER_TOKENS ; + 39: NIL operation ; + 40: SWAP ; + 41: CONS ; + 42: PAIR } } +At line 22 characters 15 to 27, +script reached FAILWITH instruction +with Unit +Fatal error: + transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.378d03ae2d.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.378d03ae2d.out new file mode 100644 index 000000000000..5850dca7842d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.378d03ae2d.out @@ -0,0 +1,66 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150733eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] + +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1040000 + Storage limit: 60000 bytes + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 + "sp[SIGNATURE]m") + This operation FAILED. + +Runtime error in contract [CONTRACT_HASH]: + 01: { parameter (pair bytes signature) ; + 02: storage key ; + 03: code { DUP ; + 04: CAAR ; + 05: DUP ; + 06: SIZE ; + 07: PUSH nat 128 ; + 08: SWAP ; + 09: SUB ; + 10: ISNAT ; + 11: ASSERT_SOME ; + 12: PUSH nat 128 ; + 13: SLICE @payload ; + 14: ASSERT_SOME ; + 15: DUP ; + 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; + 17: SHA256 ; + 18: ASSERT_CMPEQ } ; + 19: DUP ; + 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; + 21: BLAKE2B ; + 22: ASSERT_CMPEQ } ; + 23: DUP ; + 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; + 25: SHA512 ; + 26: ASSERT_CMPEQ } ; + 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; + 28: SWAP ; + 29: DIP { SWAP } ; + 30: CHECK_SIGNATURE ; + 31: ASSERT ; + 32: CDR ; + 33: DUP ; + 34: HASH_KEY ; + 35: IMPLICIT_ACCOUNT ; + 36: BALANCE ; + 37: UNIT ; + 38: TRANSFER_TOKENS ; + 39: NIL operation ; + 40: SWAP ; + 41: CONS ; + 42: PAIR } } +At line 26 characters 15 to 27, +script reached FAILWITH instruction +with Unit +Fatal error: + transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.57fdc7ad1c.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.57fdc7ad1c.out new file mode 100644 index 000000000000..d2392538cc62 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75.57fdc7ad1c.out @@ -0,0 +1,66 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "p2sigsceCzcDw2AeYDzUonj4JT341WC9Px4wdhHBxbZcG1FhfqFVuG7f2fGCzrEHSAZgrsrQWpxduDPk9qZRgrpzwJnSHC3gZJ")] + +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1040000 + Storage limit: 60000 bytes + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 + "p2[SIGNATURE]") + This operation FAILED. + +Runtime error in contract [CONTRACT_HASH]: + 01: { parameter (pair bytes signature) ; + 02: storage key ; + 03: code { DUP ; + 04: CAAR ; + 05: DUP ; + 06: SIZE ; + 07: PUSH nat 128 ; + 08: SWAP ; + 09: SUB ; + 10: ISNAT ; + 11: ASSERT_SOME ; + 12: PUSH nat 128 ; + 13: SLICE @payload ; + 14: ASSERT_SOME ; + 15: DUP ; + 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; + 17: SHA256 ; + 18: ASSERT_CMPEQ } ; + 19: DUP ; + 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; + 21: BLAKE2B ; + 22: ASSERT_CMPEQ } ; + 23: DUP ; + 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; + 25: SHA512 ; + 26: ASSERT_CMPEQ } ; + 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; + 28: SWAP ; + 29: DIP { SWAP } ; + 30: CHECK_SIGNATURE ; + 31: ASSERT ; + 32: CDR ; + 33: DUP ; + 34: HASH_KEY ; + 35: IMPLICIT_ACCOUNT ; + 36: BALANCE ; + 37: UNIT ; + 38: TRANSFER_TOKENS ; + 39: NIL operation ; + 40: SWAP ; + 41: CONS ; + 42: PAIR } } +At line 31 characters 9 to 15, +script reached FAILWITH instruction +with Unit +Fatal error: + transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75.c583c796bf.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75.c583c796bf.out new file mode 100644 index 000000000000..a3c3b7a93f98 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75.c583c796bf.out @@ -0,0 +1,66 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_fails[(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] + +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1040000 + Storage limit: 60000 bytes + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 + "sp[SIGNATURE]m") + This operation FAILED. + +Runtime error in contract [CONTRACT_HASH]: + 01: { parameter (pair bytes signature) ; + 02: storage key ; + 03: code { DUP ; + 04: CAAR ; + 05: DUP ; + 06: SIZE ; + 07: PUSH nat 128 ; + 08: SWAP ; + 09: SUB ; + 10: ISNAT ; + 11: ASSERT_SOME ; + 12: PUSH nat 128 ; + 13: SLICE @payload ; + 14: ASSERT_SOME ; + 15: DUP ; + 16: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 0 ; SLICE ; ASSERT_SOME } ; + 17: SHA256 ; + 18: ASSERT_CMPEQ } ; + 19: DUP ; + 20: DIP { DIP { DUP ; CAAR ; PUSH nat 32 ; PUSH nat 32 ; SLICE ; ASSERT_SOME } ; + 21: BLAKE2B ; + 22: ASSERT_CMPEQ } ; + 23: DUP ; + 24: DIP { DIP { DUP ; CAAR ; PUSH nat 64 ; PUSH nat 64 ; SLICE ; ASSERT_SOME } ; + 25: SHA512 ; + 26: ASSERT_CMPEQ } ; + 27: DIP { DUP ; CDR ; DIP { DUP ; CADR } } ; + 28: SWAP ; + 29: DIP { SWAP } ; + 30: CHECK_SIGNATURE ; + 31: ASSERT ; + 32: CDR ; + 33: DUP ; + 34: HASH_KEY ; + 35: IMPLICIT_ACCOUNT ; + 36: BALANCE ; + 37: UNIT ; + 38: TRANSFER_TOKENS ; + 39: NIL operation ; + 40: SWAP ; + 41: CONS ; + 42: PAIR } } +At line 18 characters 15 to 27, +script reached FAILWITH instruction +with Unit +Fatal error: + transfer simulation failed diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out new file mode 100644 index 000000000000..537cc249e7e7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out @@ -0,0 +1,46 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] + +Node is bootstrapped. +Estimated gas: 4184.720 units (will add 100 for safety) +Estimated storage: 257 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000936 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 4285 + Storage limit: 277 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000936 + payload fees(the block proposer) ....... +ꜩ0.000936 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair [OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH][OPERATION_HASH]000085341554349535345 + "sp[SIGNATURE]m") + This transaction was successfully applied + Updated storage: + [OPERATION_HASH]48f709699019725ba + Storage size: 578 bytes + Consumed gas: 2764.720 + Internal operations: + Transaction: + Amount: ꜩ1000 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Consumed gas: 1420 + Balance updates: + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_source.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_source.out new file mode 100644 index 000000000000..ce1d610a1d4b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_source.out @@ -0,0 +1,119 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_source + +Node is bootstrapped. +Estimated gas: 2066.897 units (will add 100 for safety) +Estimated storage: 322 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000527 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2167 + Storage limit: 342 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000527 + payload fees(the block proposer) ....... +ꜩ0.000527 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter unit ; + storage address ; + code { DROP ; SOURCE ; NIL operation ; PAIR } } + Initial storage: "[CONTRACT_HASH]" + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 65 bytes + Paid storage size diff: 65 bytes + Consumed gas: 2066.897 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01625 + storage fees ........................... +ꜩ0.01625 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as source. +Injected block at minimal timestamp +Node is bootstrapped. +Estimated gas: 2710.682 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.00053 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2811 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.00053 + payload fees(the block proposer) ....... +ꜩ0.00053 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Updated storage: 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c + Storage size: 65 bytes + Consumed gas: 2710.682 + +Injected block at minimal timestamp +"[CONTRACT_HASH]" +[CONTRACT_HASH] + +Node is bootstrapped. +Estimated gas: 4338.863 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000738 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 4439 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000738 + payload fees(the block proposer) ....... +ꜩ0.000738 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: "[CONTRACT_HASH]" + This transaction was successfully applied + Updated storage: Unit + Storage size: 55 bytes + Consumed gas: 3126.358 + Internal operations: + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Updated storage: 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c + Storage size: 65 bytes + Consumed gas: 1212.505 + +Injected block at minimal timestamp +"[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_bytes.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_bytes.out new file mode 100644 index 000000000000..2f5e5c04c187 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_bytes.out @@ -0,0 +1,139 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_split_bytes + +Node is bootstrapped. +Estimated gas: 1446.644 units (will add 100 for safety) +Estimated storage: 511 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.00064 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1547 + Storage limit: 531 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.00064 + payload fees(the block proposer) ....... +ꜩ0.00064 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter bytes ; + storage (list bytes) ; + code { UNPAIR ; + DIP { NIL bytes ; SWAP ; ITER { CONS } } ; + DUP ; + SIZE ; + PUSH nat 0 ; + CMPNEQ ; + DIP { PUSH @index nat 0 } ; + LOOP { PAIR ; + DUP ; + DIP { UNPAIR ; DIP { PUSH nat 1 } ; SLICE ; ASSERT_SOME ; CONS @storage } ; + UNPAIR ; + PUSH nat 1 ; + ADD @index ; + DUP ; + DIP { DIP { DUP } ; SWAP ; SIZE ; CMPNEQ } ; + SWAP } ; + DROP ; + DROP ; + NIL bytes ; + SWAP ; + ITER { CONS } ; + NIL operation ; + PAIR } } + Initial storage: {} + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 254 bytes + Paid storage size diff: 254 bytes + Consumed gas: 1446.644 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0635 + storage fees ........................... +ꜩ0.0635 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as split_bytes. +Injected block at minimal timestamp +Node is bootstrapped. +Estimated gas: 2097.318 units (will add 100 for safety) +Estimated storage: 18 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000481 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2198 + Storage limit: 38 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000481 + payload fees(the block proposer) ....... +ꜩ0.000481 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: 0xaabbcc + This transaction was successfully applied + Updated storage: { 0xaa ; 0xbb ; 0xcc } + Storage size: 272 bytes + Paid storage size diff: 18 bytes + Consumed gas: 2097.318 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0045 + storage fees ........................... +ꜩ0.0045 + +Injected block at minimal timestamp +{ 0xaa ; 0xbb ; 0xcc } +Node is bootstrapped. +Estimated gas: 1206.757 units (will add 100 for safety) +Estimated storage: 18 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000392 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1307 + Storage limit: 38 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000392 + payload fees(the block proposer) ....... +ꜩ0.000392 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: 0xddeeff + This transaction was successfully applied + Updated storage: { 0xaa ; 0xbb ; 0xcc ; 0xdd ; 0xee ; 0xff } + Storage size: 290 bytes + Paid storage size diff: 18 bytes + Consumed gas: 1206.757 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0045 + storage fees ........................... +ꜩ0.0045 + +Injected block at minimal timestamp +{ 0xaa ; 0xbb ; 0xcc ; 0xdd ; 0xee ; 0xff } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_string.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_string.out new file mode 100644 index 000000000000..316ea751920b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_split_string.out @@ -0,0 +1,139 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_split_string + +Node is bootstrapped. +Estimated gas: 1446.644 units (will add 100 for safety) +Estimated storage: 511 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.00064 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1547 + Storage limit: 531 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.00064 + payload fees(the block proposer) ....... +ꜩ0.00064 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter string ; + storage (list string) ; + code { UNPAIR ; + DIP { NIL string ; SWAP ; ITER { CONS } } ; + DUP ; + SIZE ; + PUSH nat 0 ; + CMPNEQ ; + DIP { PUSH @index nat 0 } ; + LOOP { PAIR ; + DUP ; + DIP { UNPAIR ; DIP { PUSH nat 1 } ; SLICE ; ASSERT_SOME ; CONS @storage } ; + UNPAIR ; + PUSH nat 1 ; + ADD @index ; + DUP ; + DIP { DIP { DUP } ; SWAP ; SIZE ; CMPNEQ } ; + SWAP } ; + DROP ; + DROP ; + NIL string ; + SWAP ; + ITER { CONS } ; + NIL operation ; + PAIR } } + Initial storage: {} + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 254 bytes + Paid storage size diff: 254 bytes + Consumed gas: 1446.644 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0635 + storage fees ........................... +ꜩ0.0635 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as split_string. +Injected block at minimal timestamp +Node is bootstrapped. +Estimated gas: 2097.362 units (will add 100 for safety) +Estimated storage: 18 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000481 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2198 + Storage limit: 38 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000481 + payload fees(the block proposer) ....... +ꜩ0.000481 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: "abc" + This transaction was successfully applied + Updated storage: { "a" ; "b" ; "c" } + Storage size: 272 bytes + Paid storage size diff: 18 bytes + Consumed gas: 2097.362 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0045 + storage fees ........................... +ꜩ0.0045 + +Injected block at minimal timestamp +{ "a" ; "b" ; "c" } +Node is bootstrapped. +Estimated gas: 1206.801 units (will add 100 for safety) +Estimated storage: 18 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000392 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1307 + Storage limit: 38 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000392 + payload fees(the block proposer) ....... +ꜩ0.000392 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: "def" + This transaction was successfully applied + Updated storage: { "a" ; "b" ; "c" ; "d" ; "e" ; "f" } + Storage size: 290 bytes + Paid storage size diff: 18 bytes + Consumed gas: 1206.801 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0045 + storage fees ........................... +ꜩ0.0045 + +Injected block at minimal timestamp +{ "a" ; "b" ; "c" ; "d" ; "e" ; "f" } diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out new file mode 100644 index 000000000000..050517c2c48c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out @@ -0,0 +1,185 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_store_input + +Node is bootstrapped. +Estimated gas: 1420.040 units (will add 100 for safety) +Estimated storage: 257 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000406 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1521 + Storage limit: 277 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000406 + payload fees(the block proposer) ....... +ꜩ0.000406 + Transaction: + Amount: ꜩ1000 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Consumed gas: 1420.040 + Balance updates: + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +Injected block at minimal timestamp +Node is bootstrapped. +Estimated gas: 1420.040 units (will add 100 for safety) +Estimated storage: 257 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000406 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1521 + Storage limit: 277 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000406 + payload fees(the block proposer) ....... +ꜩ0.000406 + Transaction: + Amount: ꜩ2000 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Consumed gas: 1420.040 + Balance updates: + [CONTRACT_HASH] ... -ꜩ2000 + [CONTRACT_HASH] ... +ꜩ2000 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +Injected block at minimal timestamp +1000 ꜩ +2000 ꜩ +Node is bootstrapped. +Estimated gas: 1405.336 units (will add 100 for safety) +Estimated storage: 298 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000422 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1506 + Storage limit: 318 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000422 + payload fees(the block proposer) ....... +ꜩ0.000422 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ100 + Script: + { parameter string ; + storage string ; + code { CAR ; NIL operation ; PAIR } } + Initial storage: "" + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 41 bytes + Paid storage size diff: 41 bytes + Consumed gas: 1405.336 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01025 + storage fees ........................... +ꜩ0.01025 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + +New contract [CONTRACT_HASH] originated. +Contract memorized as store_input. +Injected block at minimal timestamp +Node is bootstrapped. +Estimated gas: 2049.248 units (will add 100 for safety) +Estimated storage: 7 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000483 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2150 + Storage limit: 27 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000483 + payload fees(the block proposer) ....... +ꜩ0.000483 + Transaction: + Amount: ꜩ100 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: "abcdefg" + This transaction was successfully applied + Updated storage: "abcdefg" + Storage size: 48 bytes + Paid storage size diff: 7 bytes + Consumed gas: 2049.248 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.00175 + storage fees ........................... +ꜩ0.00175 + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + +Injected block at minimal timestamp +200 ꜩ +"abcdefg" +Node is bootstrapped. +Estimated gas: 1202.528 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000395 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1303 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000395 + payload fees(the block proposer) ....... +ꜩ0.000395 + Transaction: + Amount: ꜩ100 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: "xyz" + This transaction was successfully applied + Updated storage: "xyz" + Storage size: 44 bytes + Consumed gas: 1202.528 + Balance updates: + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + +Injected block at minimal timestamp +"xyz" diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz].out new file mode 100644 index 000000000000..0affd6b05dcb --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz].out @@ -0,0 +1,93 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_trace_origination[compare_big_type.tz] + +Node is bootstrapped. +Estimated gas: 3415.815 units (will add 100 for safety) +Estimated storage: 385 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000711 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 3516 + Storage limit: 405 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000711 + payload fees(the block proposer) ....... +ꜩ0.000711 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter unit ; + storage unit ; + code { DROP ; + PUSH nat 0 ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DROP ; + UNIT ; + NIL operation ; + PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 128 bytes + Paid storage size diff: 128 bytes + Consumed gas: 3415.815 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.032 + storage fees ........................... +ꜩ0.032 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as compare_big_type. +Injected block at minimal timestamp +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz].out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz].out new file mode 100644 index 000000000000..d2a1102dc7bc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz].out @@ -0,0 +1,97 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_trace_origination[compare_big_type2.tz] + +Node is bootstrapped. +Estimated gas: 3740.366 units (will add 100 for safety) +Estimated storage: 393 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000752 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 3841 + Storage limit: 413 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000752 + payload fees(the block proposer) ....... +ꜩ0.000752 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter unit ; + storage unit ; + code { DROP ; + PUSH nat 0 ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + PAIR ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DUP ; + DUP ; + COMPARE ; + DROP ; + DROP ; + UNIT ; + NIL operation ; + PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 136 bytes + Paid storage size diff: 136 bytes + Consumed gas: 3740.366 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.034 + storage fees ........................... +ꜩ0.034 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as compare_big_type2. +Injected block at minimal timestamp +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_amount.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_amount.out new file mode 100644 index 000000000000..0d8eddd2c790 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_amount.out @@ -0,0 +1,83 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_transfer_amount + +Node is bootstrapped. +Estimated gas: 1405.897 units (will add 100 for safety) +Estimated storage: 297 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000421 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1506 + Storage limit: 317 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000421 + payload fees(the block proposer) ....... +ꜩ0.000421 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ100 + Script: + { parameter unit ; + storage mutez ; + code { DROP ; AMOUNT ; NIL operation ; PAIR } } + Initial storage: 0 + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 40 bytes + Paid storage size diff: 40 bytes + Consumed gas: 1405.897 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01 + storage fees ........................... +ꜩ0.01 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + +New contract [CONTRACT_HASH] originated. +Contract memorized as transfer_amount. +Injected block at minimal timestamp +Node is bootstrapped. +Estimated gas: 2049.528 units (will add 100 for safety) +Estimated storage: 4 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000467 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2150 + Storage limit: 24 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000467 + payload fees(the block proposer) ....... +ꜩ0.000467 + Transaction: + Amount: ꜩ500 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Updated storage: 500000000 + Storage size: 44 bytes + Paid storage size diff: 4 bytes + Consumed gas: 2049.528 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.001 + storage fees ........................... +ꜩ0.001 + [CONTRACT_HASH] ... -ꜩ500 + [CONTRACT_HASH] ... +ꜩ500 + +Injected block at minimal timestamp +500000000 diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_tokens.out b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_tokens.out new file mode 100644 index 000000000000..5d512b1fb6be --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_transfer_tokens.out @@ -0,0 +1,238 @@ +tests_012/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_transfer_tokens + +Node is bootstrapped. +Estimated gas: 1405.250 units (will add 100 for safety) +Estimated storage: 295 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000419 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1506 + Storage limit: 315 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000419 + payload fees(the block proposer) ....... +ꜩ0.000419 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ100 + Script: + { parameter unit ; storage unit ; code { CDR ; NIL operation ; PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 38 bytes + Paid storage size diff: 38 bytes + Consumed gas: 1405.250 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0095 + storage fees ........................... +ꜩ0.0095 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + +New contract [CONTRACT_HASH] originated. +Contract memorized as test_transfer_account1. +Injected block at minimal timestamp +Node is bootstrapped. +Estimated gas: 1405.250 units (will add 100 for safety) +Estimated storage: 295 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000419 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1506 + Storage limit: 315 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000419 + payload fees(the block proposer) ....... +ꜩ0.000419 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ20 + Script: + { parameter unit ; storage unit ; code { CDR ; NIL operation ; PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 38 bytes + Paid storage size diff: 38 bytes + Consumed gas: 1405.250 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0095 + storage fees ........................... +ꜩ0.0095 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ20 + [CONTRACT_HASH] ... +ꜩ20 + +New contract [CONTRACT_HASH] originated. +Contract memorized as test_transfer_account2. +Injected block at minimal timestamp +Node is bootstrapped. +Estimated gas: 1411.459 units (will add 100 for safety) +Estimated storage: 323 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000449 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1512 + Storage limit: 343 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000449 + payload fees(the block proposer) ....... +ꜩ0.000449 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ1000 + Script: + { parameter (contract unit) ; + storage unit ; + code { CAR ; + DIP { UNIT } ; + PUSH mutez 100000000 ; + UNIT ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 66 bytes + Paid storage size diff: 66 bytes + Consumed gas: 1411.459 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ1000 + [CONTRACT_HASH] ... +ꜩ1000 + +New contract [CONTRACT_HASH] originated. +Contract memorized as transfer_tokens. +Injected block at minimal timestamp +100 ꜩ +[CONTRACT_HASH] + +Node is bootstrapped. +Estimated gas: 5177.026 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000825 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 5278 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000825 + payload fees(the block proposer) ....... +ꜩ0.000825 + Transaction: + Amount: ꜩ100 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: "[CONTRACT_HASH]" + This transaction was successfully applied + Updated storage: Unit + Storage size: 66 bytes + Consumed gas: 3128.352 + Balance updates: + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + Internal operations: + Transaction: + Amount: ꜩ100 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Updated storage: Unit + Storage size: 38 bytes + Consumed gas: 2048.674 + Balance updates: + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + +Injected block at minimal timestamp +200 ꜩ +[CONTRACT_HASH] + +Node is bootstrapped. +Estimated gas: 4323.909 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.00074 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 4424 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.00074 + payload fees(the block proposer) ....... +ꜩ0.00074 + Transaction: + Amount: ꜩ100 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: "[CONTRACT_HASH]" + This transaction was successfully applied + Updated storage: Unit + Storage size: 66 bytes + Consumed gas: 2275.235 + Balance updates: + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + Internal operations: + Transaction: + Amount: ꜩ100 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Updated storage: Unit + Storage size: 38 bytes + Consumed gas: 2048.674 + Balance updates: + [CONTRACT_HASH] ... -ꜩ100 + [CONTRACT_HASH] ... +ꜩ100 + +Injected block at minimal timestamp +120 ꜩ diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" new file mode 100644 index 000000000000..f1d6749a08ee --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-\"hello\"-(Pa.f6092ac5d6.out" @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 4) {})-"hello"-(Pair None 4)-big_map_diff10] + +storage + (Pair None 4) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["hello"] to 4 +trace + - location: 13 (remaining gas: 1039989.246 units remaining) + [ (Pair "hello" (Some 4) {}) ] + - location: 13 (remaining gas: 1039989.236 units remaining) + [ "hello" @parameter + (Pair (Some 4) {}) @storage ] + - location: 14 (remaining gas: 1039989.221 units remaining) + [ (Pair (Some 4) {}) @storage ] + - location: 16 (remaining gas: 1039989.211 units remaining) + [ (Some 4) + {} ] + - location: 14 (remaining gas: 1039989.181 units remaining) + [ "hello" @parameter + (Some 4) + {} ] + - location: 17 (remaining gas: 1039988.109 units remaining) + [ None + { Elt "hello" 4 } ] + - location: 18 (remaining gas: 1039988.094 units remaining) + [ (Pair None { Elt "hello" 4 }) ] + - location: 19 (remaining gas: 1039988.079 units remaining) + [ {} + (Pair None { Elt "hello" 4 }) ] + - location: 21 (remaining gas: 1039988.064 units remaining) + [ (Pair {} None { Elt "hello" 4 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0427752f13.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0427752f13.out" new file mode 100644 index 000000000000..8cc228fcf8fa --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0427752f13.out" @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt "hello" 4 })-"hello"-(Pair (Some 4) 4)-big_map_diff12] + +storage + (Pair (Some 4) 4) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["hello"] to 5 +trace + - location: 13 (remaining gas: 1039987.916 units remaining) + [ (Pair "hello" (Some 5) { Elt "hello" 4 }) ] + - location: 13 (remaining gas: 1039987.906 units remaining) + [ "hello" @parameter + (Pair (Some 5) { Elt "hello" 4 }) @storage ] + - location: 14 (remaining gas: 1039987.891 units remaining) + [ (Pair (Some 5) { Elt "hello" 4 }) @storage ] + - location: 16 (remaining gas: 1039987.881 units remaining) + [ (Some 5) + { Elt "hello" 4 } ] + - location: 14 (remaining gas: 1039987.851 units remaining) + [ "hello" @parameter + (Some 5) + { Elt "hello" 4 } ] + - location: 17 (remaining gas: 1039986.774 units remaining) + [ (Some 4) + { Elt "hello" 5 } ] + - location: 18 (remaining gas: 1039986.759 units remaining) + [ (Pair (Some 4) { Elt "hello" 5 }) ] + - location: 19 (remaining gas: 1039986.744 units remaining) + [ {} + (Pair (Some 4) { Elt "hello" 5 }) ] + - location: 21 (remaining gas: 1039986.729 units remaining) + [ (Pair {} (Some 4) { Elt "hello" 5 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0793dc66d5.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0793dc66d5.out" new file mode 100644 index 000000000000..2bc064c3f32a --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt \"hello\" 4.0793dc66d5.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair (Some 5) { Elt "hello" 4 })-"hi"-(Pair None 4)-big_map_diff13] + +storage + (Pair None 4) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["hello"] to 4 + Set map(4)["hi"] to 5 +trace + - location: 13 (remaining gas: 1039987.946 units remaining) + [ (Pair "hi" (Some 5) { Elt "hello" 4 }) ] + - location: 13 (remaining gas: 1039987.936 units remaining) + [ "hi" @parameter + (Pair (Some 5) { Elt "hello" 4 }) @storage ] + - location: 14 (remaining gas: 1039987.921 units remaining) + [ (Pair (Some 5) { Elt "hello" 4 }) @storage ] + - location: 16 (remaining gas: 1039987.911 units remaining) + [ (Some 5) + { Elt "hello" 4 } ] + - location: 14 (remaining gas: 1039987.881 units remaining) + [ "hi" @parameter + (Some 5) + { Elt "hello" 4 } ] + - location: 17 (remaining gas: 1039986.906 units remaining) + [ None + { Elt "hello" 4 ; Elt "hi" 5 } ] + - location: 18 (remaining gas: 1039986.891 units remaining) + [ (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) ] + - location: 19 (remaining gas: 1039986.876 units remaining) + [ {} + (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) ] + - location: 21 (remaining gas: 1039986.861 units remaining) + [ (Pair {} None { Elt "hello" 4 ; Elt "hi" 5 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .df114499b8.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .df114499b8.out" new file mode 100644 index 000000000000..90cf876d8073 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .df114499b8.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt "1" 1 ; Elt "2" 2 })-"1"-(Pair (Some 1) 4)-big_map_diff14] + +storage + (Pair (Some 1) 4) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["2"] to 2 + Unset map(4)["1"] +trace + - location: 13 (remaining gas: 1039987.042 units remaining) + [ (Pair "1" None { Elt "1" 1 ; Elt "2" 2 }) ] + - location: 13 (remaining gas: 1039987.032 units remaining) + [ "1" @parameter + (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] + - location: 14 (remaining gas: 1039987.017 units remaining) + [ (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] + - location: 16 (remaining gas: 1039987.007 units remaining) + [ None + { Elt "1" 1 ; Elt "2" 2 } ] + - location: 14 (remaining gas: 1039986.977 units remaining) + [ "1" @parameter + None + { Elt "1" 1 ; Elt "2" 2 } ] + - location: 17 (remaining gas: 1039986.033 units remaining) + [ (Some 1) + { Elt "2" 2 } ] + - location: 18 (remaining gas: 1039986.018 units remaining) + [ (Pair (Some 1) { Elt "2" 2 }) ] + - location: 19 (remaining gas: 1039986.003 units remaining) + [ {} + (Pair (Some 1) { Elt "2" 2 }) ] + - location: 21 (remaining gas: 1039985.988 units remaining) + [ (Pair {} (Some 1) { Elt "2" 2 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .f9bea98de9.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .f9bea98de9.out" new file mode 100644 index 000000000000..bab91446cb0a --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"1\" 1 ; .f9bea98de9.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt "1" 1 ; Elt "2" 2 })-"1"-(Pair (Some 1) 4)-big_map_diff15] + +storage + (Pair (Some 1) 4) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["2"] to 2 + Unset map(4)["1"] +trace + - location: 13 (remaining gas: 1039987.042 units remaining) + [ (Pair "1" None { Elt "1" 1 ; Elt "2" 2 }) ] + - location: 13 (remaining gas: 1039987.032 units remaining) + [ "1" @parameter + (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] + - location: 14 (remaining gas: 1039987.017 units remaining) + [ (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] + - location: 16 (remaining gas: 1039987.007 units remaining) + [ None + { Elt "1" 1 ; Elt "2" 2 } ] + - location: 14 (remaining gas: 1039986.977 units remaining) + [ "1" @parameter + None + { Elt "1" 1 ; Elt "2" 2 } ] + - location: 17 (remaining gas: 1039986.033 units remaining) + [ (Some 1) + { Elt "2" 2 } ] + - location: 18 (remaining gas: 1039986.018 units remaining) + [ (Pair (Some 1) { Elt "2" 2 }) ] + - location: 19 (remaining gas: 1039986.003 units remaining) + [ {} + (Pair (Some 1) { Elt "2" 2 }) ] + - location: 21 (remaining gas: 1039985.988 units remaining) + [ (Pair {} (Some 1) { Elt "2" 2 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"hello\" 4 })-.1db12cd837.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"hello\" 4 })-.1db12cd837.out" new file mode 100644 index 000000000000..f2fc60c81829 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt \"hello\" 4 })-.1db12cd837.out" @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None { Elt "hello" 4 })-"hello"-(Pair (Some 4) 4)-big_map_diff11] + +storage + (Pair (Some 4) 4) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Unset map(4)["hello"] +trace + - location: 13 (remaining gas: 1039988.016 units remaining) + [ (Pair "hello" None { Elt "hello" 4 }) ] + - location: 13 (remaining gas: 1039988.006 units remaining) + [ "hello" @parameter + (Pair None { Elt "hello" 4 }) @storage ] + - location: 14 (remaining gas: 1039987.991 units remaining) + [ (Pair None { Elt "hello" 4 }) @storage ] + - location: 16 (remaining gas: 1039987.981 units remaining) + [ None + { Elt "hello" 4 } ] + - location: 14 (remaining gas: 1039987.951 units remaining) + [ "hello" @parameter + None + { Elt "hello" 4 } ] + - location: 17 (remaining gas: 1039986.874 units remaining) + [ (Some 4) + {} ] + - location: 18 (remaining gas: 1039986.859 units remaining) + [ (Pair (Some 4) {}) ] + - location: 19 (remaining gas: 1039986.844 units remaining) + [ {} + (Pair (Some 4) {}) ] + - location: 21 (remaining gas: 1039986.829 units remaining) + [ (Pair {} (Some 4) {}) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-\"hello\"-(Pair N.6fc7d0acf2.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-\"hello\"-(Pair N.6fc7d0acf2.out" new file mode 100644 index 000000000000..0816a5510631 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-\"hello\"-(Pair N.6fc7d0acf2.out" @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_and_update_big_map.tz-(Pair None {})-"hello"-(Pair None 4)-big_map_diff9] + +storage + (Pair None 4) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Unset map(4)["hello"] +trace + - location: 13 (remaining gas: 1039989.346 units remaining) + [ (Pair "hello" None {}) ] + - location: 13 (remaining gas: 1039989.336 units remaining) + [ "hello" @parameter + (Pair None {}) @storage ] + - location: 14 (remaining gas: 1039989.321 units remaining) + [ (Pair None {}) @storage ] + - location: 16 (remaining gas: 1039989.311 units remaining) + [ None + {} ] + - location: 14 (remaining gas: 1039989.281 units remaining) + [ "hello" @parameter + None + {} ] + - location: 17 (remaining gas: 1039988.209 units remaining) + [ None + {} ] + - location: 18 (remaining gas: 1039988.194 units remaining) + [ (Pair None {}) ] + - location: 19 (remaining gas: 1039988.179 units remaining) + [ {} + (Pair None {}) ] + - location: 21 (remaining gas: 1039988.164 units remaining) + [ (Pair {} None {}) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"tw.524c5459f8.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"tw.524c5459f8.out" new file mode 100644 index 000000000000..f70db4bc7d1c --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"tw.524c5459f8.out" @@ -0,0 +1,46 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } None)-"1"-(Pair 4 (Some "one"))-big_map_diff2] + +storage + (Pair 4 (Some "one")) +emitted operations + +big_map diff + New map(4) of type (big_map string string) + Set map(4)["2"] to "two" + Set map(4)["1"] to "one" +trace + - location: 12 (remaining gas: 1039983.953 units remaining) + [ (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) ] + - location: 12 (remaining gas: 1039983.943 units remaining) + [ (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) + (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) ] + - location: 13 (remaining gas: 1039983.933 units remaining) + [ "1" @parameter + (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) ] + - location: 14 (remaining gas: 1039983.918 units remaining) + [ (Pair "1" { Elt "1" "one" ; Elt "2" "two" } None) ] + - location: 17 (remaining gas: 1039983.908 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } None) @storage ] + - location: 18 (remaining gas: 1039983.898 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } ] + - location: 19 (remaining gas: 1039983.888 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + { Elt "1" "one" ; Elt "2" "two" } ] + - location: 14 (remaining gas: 1039983.858 units remaining) + [ "1" @parameter + { Elt "1" "one" ; Elt "2" "two" } + { Elt "1" "one" ; Elt "2" "two" } ] + - location: 20 (remaining gas: 1039982.948 units remaining) + [ (Some "one") + { Elt "1" "one" ; Elt "2" "two" } ] + - location: 21 (remaining gas: 1039982.938 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + (Some "one") ] + - location: 22 (remaining gas: 1039982.923 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } (Some "one")) ] + - location: 23 (remaining gas: 1039982.908 units remaining) + [ {} + (Pair { Elt "1" "one" ; Elt "2" "two" } (Some "one")) ] + - location: 25 (remaining gas: 1039982.893 units remaining) + [ (Pair {} { Elt "1" "one" ; Elt "2" "two" } (Some "one")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"\".33eba403e7.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"\".33eba403e7.out" new file mode 100644 index 000000000000..085ebec66966 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"\".33eba403e7.out" @@ -0,0 +1,45 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt "hello" "hi" } None)-""-(Pair 4 None)-big_map_diff1] + +storage + (Pair 4 None) +emitted operations + +big_map diff + New map(4) of type (big_map string string) + Set map(4)["hello"] to "hi" +trace + - location: 12 (remaining gas: 1039985.031 units remaining) + [ (Pair "" { Elt "hello" "hi" } None) ] + - location: 12 (remaining gas: 1039985.021 units remaining) + [ (Pair "" { Elt "hello" "hi" } None) + (Pair "" { Elt "hello" "hi" } None) ] + - location: 13 (remaining gas: 1039985.011 units remaining) + [ "" @parameter + (Pair "" { Elt "hello" "hi" } None) ] + - location: 14 (remaining gas: 1039984.996 units remaining) + [ (Pair "" { Elt "hello" "hi" } None) ] + - location: 17 (remaining gas: 1039984.986 units remaining) + [ (Pair { Elt "hello" "hi" } None) @storage ] + - location: 18 (remaining gas: 1039984.976 units remaining) + [ { Elt "hello" "hi" } ] + - location: 19 (remaining gas: 1039984.966 units remaining) + [ { Elt "hello" "hi" } + { Elt "hello" "hi" } ] + - location: 14 (remaining gas: 1039984.936 units remaining) + [ "" @parameter + { Elt "hello" "hi" } + { Elt "hello" "hi" } ] + - location: 20 (remaining gas: 1039984.061 units remaining) + [ None + { Elt "hello" "hi" } ] + - location: 21 (remaining gas: 1039984.051 units remaining) + [ { Elt "hello" "hi" } + None ] + - location: 22 (remaining gas: 1039984.036 units remaining) + [ (Pair { Elt "hello" "hi" } None) ] + - location: 23 (remaining gas: 1039984.021 units remaining) + [ {} + (Pair { Elt "hello" "hi" } None) ] + - location: 25 (remaining gas: 1039984.006 units remaining) + [ (Pair {} { Elt "hello" "hi" } None) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"h.a5cd1005c9.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"h.a5cd1005c9.out" new file mode 100644 index 000000000000..ad4c2d7be3d8 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt \"hello\" \"hi\" } None)-\"h.a5cd1005c9.out" @@ -0,0 +1,45 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[get_big_map_value.tz-(Pair { Elt "hello" "hi" } None)-"hello"-(Pair 4 (Some "hi"))-big_map_diff0] + +storage + (Pair 4 (Some "hi")) +emitted operations + +big_map diff + New map(4) of type (big_map string string) + Set map(4)["hello"] to "hi" +trace + - location: 12 (remaining gas: 1039984.981 units remaining) + [ (Pair "hello" { Elt "hello" "hi" } None) ] + - location: 12 (remaining gas: 1039984.971 units remaining) + [ (Pair "hello" { Elt "hello" "hi" } None) + (Pair "hello" { Elt "hello" "hi" } None) ] + - location: 13 (remaining gas: 1039984.961 units remaining) + [ "hello" @parameter + (Pair "hello" { Elt "hello" "hi" } None) ] + - location: 14 (remaining gas: 1039984.946 units remaining) + [ (Pair "hello" { Elt "hello" "hi" } None) ] + - location: 17 (remaining gas: 1039984.936 units remaining) + [ (Pair { Elt "hello" "hi" } None) @storage ] + - location: 18 (remaining gas: 1039984.926 units remaining) + [ { Elt "hello" "hi" } ] + - location: 19 (remaining gas: 1039984.916 units remaining) + [ { Elt "hello" "hi" } + { Elt "hello" "hi" } ] + - location: 14 (remaining gas: 1039984.886 units remaining) + [ "hello" @parameter + { Elt "hello" "hi" } + { Elt "hello" "hi" } ] + - location: 20 (remaining gas: 1039983.840 units remaining) + [ (Some "hi") + { Elt "hello" "hi" } ] + - location: 21 (remaining gas: 1039983.830 units remaining) + [ { Elt "hello" "hi" } + (Some "hi") ] + - location: 22 (remaining gas: 1039983.815 units remaining) + [ (Pair { Elt "hello" "hi" } (Some "hi")) ] + - location: 23 (remaining gas: 1039983.800 units remaining) + [ {} + (Pair { Elt "hello" "hi" } (Some "hi")) ] + - location: 25 (remaining gas: 1039983.785 units remaining) + [ (Pair {} { Elt "hello" "hi" } (Some "hi")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .6f3d35b151.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .6f3d35b151.out" new file mode 100644 index 000000000000..ca5783720721 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .6f3d35b151.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{}-(Pair 4 Unit)-big_map_diff3] + +storage + (Pair 4 Unit) +emitted operations + +big_map diff + New map(4) of type (big_map string string) + Set map(4)["2"] to "two" + Set map(4)["1"] to "one" +trace + - location: 15 (remaining gas: 1039984.639 units remaining) + [ (Pair {} { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 15 (remaining gas: 1039984.629 units remaining) + [ {} @parameter + (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 16 (remaining gas: 1039984.614 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 18 (remaining gas: 1039984.604 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 16 (remaining gas: 1039984.574 units remaining) + [ {} @parameter + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 19 (remaining gas: 1039984.574 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 23 (remaining gas: 1039984.559 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 24 (remaining gas: 1039984.544 units remaining) + [ {} + (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 26 (remaining gas: 1039984.529 units remaining) + [ (Pair {} { Elt "1" "one" ; Elt "2" "two" } Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .76aeaa0706.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .76aeaa0706.out" new file mode 100644 index 000000000000..809f7c4f281b --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .76aeaa0706.out" @@ -0,0 +1,48 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "1" (Some "two") }-(Pair 4 Unit)-big_map_diff4] + +storage + (Pair 4 Unit) +emitted operations + +big_map diff + New map(4) of type (big_map string string) + Set map(4)["2"] to "two" + Set map(4)["1"] to "two" +trace + - location: 15 (remaining gas: 1039984.121 units remaining) + [ (Pair { Elt "1" (Some "two") } { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 15 (remaining gas: 1039984.111 units remaining) + [ { Elt "1" (Some "two") } @parameter + (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 16 (remaining gas: 1039984.096 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 18 (remaining gas: 1039984.086 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 16 (remaining gas: 1039984.056 units remaining) + [ { Elt "1" (Some "two") } @parameter + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 19 (remaining gas: 1039984.056 units remaining) + [ (Pair "1" (Some "two")) + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 21 (remaining gas: 1039984.046 units remaining) + [ "1" @key + (Some "two") @elt + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 22 (remaining gas: 1039983.111 units remaining) + [ { Elt "1" "two" ; Elt "2" "two" } + Unit ] + - location: 19 (remaining gas: 1039983.096 units remaining) + [ { Elt "1" "two" ; Elt "2" "two" } + Unit ] + - location: 23 (remaining gas: 1039983.081 units remaining) + [ (Pair { Elt "1" "two" ; Elt "2" "two" } Unit) ] + - location: 24 (remaining gas: 1039983.066 units remaining) + [ {} + (Pair { Elt "1" "two" ; Elt "2" "two" } Unit) ] + - location: 26 (remaining gas: 1039983.051 units remaining) + [ (Pair {} { Elt "1" "two" ; Elt "2" "two" } Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7e7197f248.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7e7197f248.out" new file mode 100644 index 000000000000..076094a58227 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7e7197f248.out" @@ -0,0 +1,48 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "1" (Some "two") }-(Pair 4 Unit)-big_map_diff8] + +storage + (Pair 4 Unit) +emitted operations + +big_map diff + New map(4) of type (big_map string string) + Set map(4)["2"] to "two" + Set map(4)["1"] to "two" +trace + - location: 15 (remaining gas: 1039984.121 units remaining) + [ (Pair { Elt "1" (Some "two") } { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 15 (remaining gas: 1039984.111 units remaining) + [ { Elt "1" (Some "two") } @parameter + (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 16 (remaining gas: 1039984.096 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 18 (remaining gas: 1039984.086 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 16 (remaining gas: 1039984.056 units remaining) + [ { Elt "1" (Some "two") } @parameter + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 19 (remaining gas: 1039984.056 units remaining) + [ (Pair "1" (Some "two")) + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 21 (remaining gas: 1039984.046 units remaining) + [ "1" @key + (Some "two") @elt + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 22 (remaining gas: 1039983.111 units remaining) + [ { Elt "1" "two" ; Elt "2" "two" } + Unit ] + - location: 19 (remaining gas: 1039983.096 units remaining) + [ { Elt "1" "two" ; Elt "2" "two" } + Unit ] + - location: 23 (remaining gas: 1039983.081 units remaining) + [ (Pair { Elt "1" "two" ; Elt "2" "two" } Unit) ] + - location: 24 (remaining gas: 1039983.066 units remaining) + [ {} + (Pair { Elt "1" "two" ; Elt "2" "two" } Unit) ] + - location: 26 (remaining gas: 1039983.051 units remaining) + [ (Pair {} { Elt "1" "two" ; Elt "2" "two" } Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" new file mode 100644 index 000000000000..ded22b12e938 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .7ef2c415a7.out" @@ -0,0 +1,49 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "3" (Some "three") }-(Pair 4 Unit)-big_map_diff5] + +storage + (Pair 4 Unit) +emitted operations + +big_map diff + New map(4) of type (big_map string string) + Set map(4)["2"] to "two" + Set map(4)["3"] to "three" + Set map(4)["1"] to "one" +trace + - location: 15 (remaining gas: 1039984.101 units remaining) + [ (Pair { Elt "3" (Some "three") } { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 15 (remaining gas: 1039984.091 units remaining) + [ { Elt "3" (Some "three") } @parameter + (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 16 (remaining gas: 1039984.076 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 18 (remaining gas: 1039984.066 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 16 (remaining gas: 1039984.036 units remaining) + [ { Elt "3" (Some "three") } @parameter + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 19 (remaining gas: 1039984.036 units remaining) + [ (Pair "3" (Some "three")) + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 21 (remaining gas: 1039984.026 units remaining) + [ "3" @key + (Some "three") @elt + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 22 (remaining gas: 1039983.091 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } + Unit ] + - location: 19 (remaining gas: 1039983.076 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } + Unit ] + - location: 23 (remaining gas: 1039983.061 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } Unit) ] + - location: 24 (remaining gas: 1039983.046 units remaining) + [ {} + (Pair { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } Unit) ] + - location: 26 (remaining gas: 1039983.031 units remaining) + [ (Pair {} { Elt "1" "one" ; Elt "2" "two" ; Elt "3" "three" } Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .b688cc94a7.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .b688cc94a7.out" new file mode 100644 index 000000000000..ca5366eb562b --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .b688cc94a7.out" @@ -0,0 +1,49 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "3" None }-(Pair 4 Unit)-big_map_diff6] + +storage + (Pair 4 Unit) +emitted operations + +big_map diff + New map(4) of type (big_map string string) + Set map(4)["2"] to "two" + Unset map(4)["3"] + Set map(4)["1"] to "one" +trace + - location: 15 (remaining gas: 1039984.265 units remaining) + [ (Pair { Elt "3" None } { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 15 (remaining gas: 1039984.255 units remaining) + [ { Elt "3" None } @parameter + (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 16 (remaining gas: 1039984.240 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 18 (remaining gas: 1039984.230 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 16 (remaining gas: 1039984.200 units remaining) + [ { Elt "3" None } @parameter + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 19 (remaining gas: 1039984.200 units remaining) + [ (Pair "3" None) + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 21 (remaining gas: 1039984.190 units remaining) + [ "3" @key + None @elt + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 22 (remaining gas: 1039983.255 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 19 (remaining gas: 1039983.240 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 23 (remaining gas: 1039983.225 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 24 (remaining gas: 1039983.210 units remaining) + [ {} + (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 26 (remaining gas: 1039983.195 units remaining) + [ (Pair {} { Elt "1" "one" ; Elt "2" "two" } Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .c68db221ed.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .c68db221ed.out" new file mode 100644 index 000000000000..8abe8c64b4e3 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt \"1\" \"one\" ; Elt \"2\" \"two\" .c68db221ed.out" @@ -0,0 +1,48 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test__big_map_contract_io[update_big_map.tz-(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)-{ Elt "2" None }-(Pair 4 Unit)-big_map_diff7] + +storage + (Pair 4 Unit) +emitted operations + +big_map diff + New map(4) of type (big_map string string) + Unset map(4)["2"] + Set map(4)["1"] to "one" +trace + - location: 15 (remaining gas: 1039984.265 units remaining) + [ (Pair { Elt "2" None } { Elt "1" "one" ; Elt "2" "two" } Unit) ] + - location: 15 (remaining gas: 1039984.255 units remaining) + [ { Elt "2" None } @parameter + (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 16 (remaining gas: 1039984.240 units remaining) + [ (Pair { Elt "1" "one" ; Elt "2" "two" } Unit) @storage ] + - location: 18 (remaining gas: 1039984.230 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 16 (remaining gas: 1039984.200 units remaining) + [ { Elt "2" None } @parameter + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 19 (remaining gas: 1039984.200 units remaining) + [ (Pair "2" None) + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 21 (remaining gas: 1039984.190 units remaining) + [ "2" @key + None @elt + { Elt "1" "one" ; Elt "2" "two" } + Unit ] + - location: 22 (remaining gas: 1039983.255 units remaining) + [ { Elt "1" "one" } + Unit ] + - location: 19 (remaining gas: 1039983.240 units remaining) + [ { Elt "1" "one" } + Unit ] + - location: 23 (remaining gas: 1039983.225 units remaining) + [ (Pair { Elt "1" "one" } Unit) ] + - location: 24 (remaining gas: 1039983.210 units remaining) + [ {} + (Pair { Elt "1" "one" } Unit) ] + - location: 26 (remaining gas: 1039983.195 units remaining) + [ (Pair {} { Elt "1" "one" } Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit].out new file mode 100644 index 000000000000..6e787a39b245 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Left Unit] + +Runtime error in contract [CONTRACT_HASH]: + 01: parameter (or unit unit) ; + 02: storage unit ; + 03: code { CAR ; + 04: IF_LEFT + 05: { + 06: PUSH nat 922337203685477580700 ; + 07: PUSH mutez 10 ; + 08: MUL ; # FAILURE + 09: DROP + 10: } + 11: { + 12: PUSH mutez 10 ; + 13: PUSH nat 922337203685477580700 ; + 14: MUL ; # FAILURE + 15: DROP + 16: } ; + 17: + 18: NIL operation ; PAIR } + 19: +At line 8 characters 11 to 14, +unexpected arithmetic overflow +Fatal error: + error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit].out new file mode 100644 index 000000000000..94e5af1e6635 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[mul_overflow.tz-Unit-Right Unit] + +Runtime error in contract [CONTRACT_HASH]: + 01: parameter (or unit unit) ; + 02: storage unit ; + 03: code { CAR ; + 04: IF_LEFT + 05: { + 06: PUSH nat 922337203685477580700 ; + 07: PUSH mutez 10 ; + 08: MUL ; # FAILURE + 09: DROP + 10: } + 11: { + 12: PUSH mutez 10 ; + 13: PUSH nat 922337203685477580700 ; + 14: MUL ; # FAILURE + 15: DROP + 16: } ; + 17: + 18: NIL operation ; PAIR } + 19: +At line 14 characters 11 to 14, +unexpected arithmetic overflow +Fatal error: + error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))].out new file mode 100644 index 000000000000..d0cc3bd45211 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 1 257))] + +Runtime error in contract [CONTRACT_HASH]: + 01: parameter (or (pair nat nat) (pair nat nat)); + 02: storage (option nat); + 03: # this contract takes either (Left a b) and stores (a << b) + 04: # or (Right a b) and stores (a >> b). + 05: # i.e., in the first case, the first component shifted to the left by + 06: # the second, and the second case, component shifted to the right by + 07: # the second. + 08: code { CAR; + 09: IF_LEFT { + 10: UNPAIR; LSL; + 11: } + 12: { + 13: UNPAIR; LSR; + 14: }; + 15: SOME; + 16: NIL operation; + 17: PAIR; + 18: }; + 19: +At line 10 characters 25 to 28, +unexpected arithmetic overflow +Fatal error: + error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))].out new file mode 100644 index 000000000000..f82415042b42 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Left (Pair 123 257))] + +Runtime error in contract [CONTRACT_HASH]: + 01: parameter (or (pair nat nat) (pair nat nat)); + 02: storage (option nat); + 03: # this contract takes either (Left a b) and stores (a << b) + 04: # or (Right a b) and stores (a >> b). + 05: # i.e., in the first case, the first component shifted to the left by + 06: # the second, and the second case, component shifted to the right by + 07: # the second. + 08: code { CAR; + 09: IF_LEFT { + 10: UNPAIR; LSL; + 11: } + 12: { + 13: UNPAIR; LSR; + 14: }; + 15: SOME; + 16: NIL operation; + 17: PAIR; + 18: }; + 19: +At line 10 characters 25 to 28, +unexpected arithmetic overflow +Fatal error: + error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))].out new file mode 100644 index 000000000000..007e71539eda --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 1 257))] + +Runtime error in contract [CONTRACT_HASH]: + 01: parameter (or (pair nat nat) (pair nat nat)); + 02: storage (option nat); + 03: # this contract takes either (Left a b) and stores (a << b) + 04: # or (Right a b) and stores (a >> b). + 05: # i.e., in the first case, the first component shifted to the left by + 06: # the second, and the second case, component shifted to the right by + 07: # the second. + 08: code { CAR; + 09: IF_LEFT { + 10: UNPAIR; LSL; + 11: } + 12: { + 13: UNPAIR; LSR; + 14: }; + 15: SOME; + 16: NIL operation; + 17: PAIR; + 18: }; + 19: +At line 13 characters 25 to 28, +unexpected arithmetic overflow +Fatal error: + error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))].out new file mode 100644 index 000000000000..fd56c0e5185f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_arithmetic_overflow[shifts.tz-None-(Right (Pair 123 257))] + +Runtime error in contract [CONTRACT_HASH]: + 01: parameter (or (pair nat nat) (pair nat nat)); + 02: storage (option nat); + 03: # this contract takes either (Left a b) and stores (a << b) + 04: # or (Right a b) and stores (a >> b). + 05: # i.e., in the first case, the first component shifted to the left by + 06: # the second, and the second case, component shifted to the right by + 07: # the second. + 08: code { CAR; + 09: IF_LEFT { + 10: UNPAIR; LSL; + 11: } + 12: { + 13: UNPAIR; LSR; + 14: }; + 15: SOME; + 16: NIL operation; + 17: PAIR; + 18: }; + 19: +At line 13 characters 25 to 28, +unexpected arithmetic overflow +Fatal error: + error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0.5].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0.5].out new file mode 100644 index 000000000000..0ff01d81e30c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0.5].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[0.5] + +storage + 500000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 0) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039774.922 units remaining) + [ 500000 @balance ] + - location: 9 (remaining gas: 1039774.907 units remaining) + [ {} + 500000 @balance ] + - location: 11 (remaining gas: 1039774.892 units remaining) + [ (Pair {} 500000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0].out new file mode 100644 index 000000000000..2456d766b4f3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[0].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 0) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039774.922 units remaining) + [ 0 @balance ] + - location: 9 (remaining gas: 1039774.907 units remaining) + [ {} + 0 @balance ] + - location: 11 (remaining gas: 1039774.892 units remaining) + [ (Pair {} 0) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1000].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1000].out new file mode 100644 index 000000000000..eb911e0f67a2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1000].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[1000] + +storage + 1000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 0) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039774.922 units remaining) + [ 1000000000 @balance ] + - location: 9 (remaining gas: 1039774.907 units remaining) + [ {} + 1000000000 @balance ] + - location: 11 (remaining gas: 1039774.892 units remaining) + [ (Pair {} 1000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1].out new file mode 100644 index 000000000000..3e139d63f8e1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[1] + +storage + 1000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 0) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039774.922 units remaining) + [ 1000000 @balance ] + - location: 9 (remaining gas: 1039774.907 units remaining) + [ {} + 1000000 @balance ] + - location: 11 (remaining gas: 1039774.892 units remaining) + [ (Pair {} 1000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1e-06].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1e-06].out new file mode 100644 index 000000000000..4946990bfef0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[1e-06].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[1e-06] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 0) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039774.922 units remaining) + [ 1 @balance ] + - location: 9 (remaining gas: 1039774.907 units remaining) + [ {} + 1 @balance ] + - location: 11 (remaining gas: 1039774.892 units remaining) + [ (Pair {} 1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[5].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[5].out new file mode 100644 index 000000000000..6a551763f6af --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[5].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[5] + +storage + 5000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 0) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039774.922 units remaining) + [ 5000000 @balance ] + - location: 9 (remaining gas: 1039774.907 units remaining) + [ {} + 5000000 @balance ] + - location: 11 (remaining gas: 1039774.892 units remaining) + [ (Pair {} 5000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[8000000000000.0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[8000000000000.0].out new file mode 100644 index 000000000000..1b12751eb036 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_balance[8000000000000.0].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_balance[8000000000000.0] + +storage + 8000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 0) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039774.922 units remaining) + [ 8000000000000000000 @balance ] + - location: 9 (remaining gas: 1039774.907 units remaining) + [ {} + 8000000000000000000 @balance ] + - location: 11 (remaining gas: 1039774.892 units remaining) + [ (Pair {} 8000000000000000000) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }) )-(Right (Righ.7492e8cdea.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }) )-(Right (Righ.7492e8cdea.out" new file mode 100644 index 000000000000..e47ae22bc48a --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }) )-(Right (Righ.7492e8cdea.out" @@ -0,0 +1,90 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }) )-(Right (Right (Right (Left { Pair "3" "three" }))))-(Left (Pair 4 5))-big_map_diff4] + +storage + (Left (Pair 4 5)) +emitted operations + +big_map diff + New map(5) of type (big_map string string) + Set map(5)["2"] to "two" + New map(4) of type (big_map string string) + Set map(4)["3"] to "three" + Set map(4)["1"] to "one" +trace + - location: 43 (remaining gas: 1039916.593 units remaining) + [ (Pair (Right (Right (Right (Left { Pair "3" "three" })))) + (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] + - location: 43 (remaining gas: 1039916.583 units remaining) + [ (Right (Right (Right (Left { Pair "3" "three" })))) @parameter + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 44 (remaining gas: 1039916.573 units remaining) + [ (Right (Right (Left { Pair "3" "three" }))) @parameter.right + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 60 (remaining gas: 1039916.563 units remaining) + [ (Right (Left { Pair "3" "three" })) @parameter.right.right + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 65 (remaining gas: 1039916.553 units remaining) + [ (Left { Pair "3" "three" }) @parameter.right.right.right + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 108 (remaining gas: 1039916.543 units remaining) + [ { Pair "3" "three" } @parameter.right.right.right.add + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 110 (remaining gas: 1039916.528 units remaining) + [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 113 (remaining gas: 1039916.518 units remaining) + [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] + - location: 113 (remaining gas: 1039916.503 units remaining) + [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] + - location: 119 (remaining gas: 1039916.493 units remaining) + [ { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 110 (remaining gas: 1039916.463 units remaining) + [ { Pair "3" "three" } @parameter.right.right.right.add + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 120 (remaining gas: 1039916.463 units remaining) + [ (Pair "3" "three") @parameter.right.right.right.add.elt + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 122 (remaining gas: 1039916.453 units remaining) + [ "3" + "three" + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 123 (remaining gas: 1039916.438 units remaining) + [ "three" + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 125 (remaining gas: 1039916.423 units remaining) + [ (Some "three") + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 123 (remaining gas: 1039916.393 units remaining) + [ "3" + (Some "three") + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 126 (remaining gas: 1039915.461 units remaining) + [ { Elt "1" "one" ; Elt "3" "three" } + { Elt "2" "two" } ] + - location: 120 (remaining gas: 1039915.446 units remaining) + [ { Elt "1" "one" ; Elt "3" "three" } + { Elt "2" "two" } ] + - location: 127 (remaining gas: 1039915.431 units remaining) + [ (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" }) ] + - location: 128 (remaining gas: 1039915.416 units remaining) + [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] + - location: 108 (remaining gas: 1039915.401 units remaining) + [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] + - location: 65 (remaining gas: 1039915.386 units remaining) + [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] + - location: 60 (remaining gas: 1039915.371 units remaining) + [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] + - location: 44 (remaining gas: 1039915.356 units remaining) + [ (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] + - location: 151 (remaining gas: 1039915.341 units remaining) + [ {} + (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" })) ] + - location: 153 (remaining gas: 1039915.326 units remaining) + [ (Pair {} (Left (Pair { Elt "1" "one" ; Elt "3" "three" } { Elt "2" "two" }))) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Left Unit)-(.21b30dd90f.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Left Unit)-(.21b30dd90f.out" new file mode 100644 index 000000000000..345d4f93b165 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Left Unit)-(.21b30dd90f.out" @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))-(Left Unit)-(Left (Pair 4 5))-big_map_diff0] + +storage + (Left (Pair 4 5)) +emitted operations + +big_map diff + New map(5) of type (big_map string string) + Set map(5)["1"] to "one" + New map(4) of type (big_map string string) + Set map(4)["2"] to "two" +trace + - location: 43 (remaining gas: 1039917.501 units remaining) + [ (Pair (Left Unit) (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] + - location: 43 (remaining gas: 1039917.491 units remaining) + [ (Left Unit) @parameter + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 44 (remaining gas: 1039917.481 units remaining) + [ Unit @parameter.swap + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 46 (remaining gas: 1039917.471 units remaining) + [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 48 (remaining gas: 1039917.461 units remaining) + [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] + - location: 48 (remaining gas: 1039917.446 units remaining) + [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] + - location: 54 (remaining gas: 1039917.436 units remaining) + [ { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 55 (remaining gas: 1039917.426 units remaining) + [ { Elt "2" "two" } + { Elt "1" "one" } ] + - location: 56 (remaining gas: 1039917.411 units remaining) + [ (Pair { Elt "2" "two" } { Elt "1" "one" }) ] + - location: 57 (remaining gas: 1039917.396 units remaining) + [ (Left (Pair { Elt "2" "two" } { Elt "1" "one" })) ] + - location: 44 (remaining gas: 1039917.381 units remaining) + [ (Left (Pair { Elt "2" "two" } { Elt "1" "one" })) ] + - location: 151 (remaining gas: 1039917.366 units remaining) + [ {} + (Left (Pair { Elt "2" "two" } { Elt "1" "one" })) ] + - location: 153 (remaining gas: 1039917.351 units remaining) + [ (Pair {} (Left (Pair { Elt "2" "two" } { Elt "1" "one" }))) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .2873ef610c.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .2873ef610c.out" new file mode 100644 index 000000000000..e20fb1c461bd --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .2873ef610c.out" @@ -0,0 +1,39 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))-(Right (Left (Left (Pair { Elt "3" "three" } { Elt "4" "four" }))))-(Left (Pair 4 5))-big_map_diff1] + +storage + (Left (Pair 4 5)) +emitted operations + +big_map diff + New map(5) of type (big_map string string) + Set map(5)["4"] to "four" + New map(4) of type (big_map string string) + Set map(4)["3"] to "three" +trace + - location: 43 (remaining gas: 1039913.797 units remaining) + [ (Pair (Right (Left (Left (Pair { Elt "3" "three" } { Elt "4" "four" })))) + (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] + - location: 43 (remaining gas: 1039913.787 units remaining) + [ (Right (Left (Left (Pair { Elt "3" "three" } { Elt "4" "four" })))) @parameter + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 44 (remaining gas: 1039913.777 units remaining) + [ (Left (Left (Pair { Elt "3" "three" } { Elt "4" "four" }))) @parameter.right + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 60 (remaining gas: 1039913.767 units remaining) + [ (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) @parameter.right.reset + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 62 (remaining gas: 1039913.757 units remaining) + [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage + (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) @parameter.right.reset ] + - location: 63 (remaining gas: 1039913.747 units remaining) + [ (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) ] + - location: 60 (remaining gas: 1039913.732 units remaining) + [ (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) ] + - location: 44 (remaining gas: 1039913.717 units remaining) + [ (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) ] + - location: 151 (remaining gas: 1039913.702 units remaining) + [ {} + (Left (Pair { Elt "3" "three" } { Elt "4" "four" })) ] + - location: 153 (remaining gas: 1039913.687 units remaining) + [ (Pair {} (Left (Pair { Elt "3" "three" } { Elt "4" "four" }))) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .8a6f480005.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .8a6f480005.out" new file mode 100644 index 000000000000..7698aecb731b --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Left .8a6f480005.out" @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))-(Right (Left (Right Unit)))-(Right Unit)-big_map_diff2] + +storage + (Right Unit) +emitted operations + +big_map diff + +trace + - location: 43 (remaining gas: 1039916.861 units remaining) + [ (Pair (Right (Left (Right Unit))) (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] + - location: 43 (remaining gas: 1039916.851 units remaining) + [ (Right (Left (Right Unit))) @parameter + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 44 (remaining gas: 1039916.841 units remaining) + [ (Left (Right Unit)) @parameter.right + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 60 (remaining gas: 1039916.831 units remaining) + [ (Right Unit) @parameter.right.reset + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 62 (remaining gas: 1039916.821 units remaining) + [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage + (Right Unit) @parameter.right.reset ] + - location: 63 (remaining gas: 1039916.811 units remaining) + [ (Right Unit) ] + - location: 60 (remaining gas: 1039916.796 units remaining) + [ (Right Unit) ] + - location: 44 (remaining gas: 1039916.781 units remaining) + [ (Right Unit) ] + - location: 151 (remaining gas: 1039916.766 units remaining) + [ {} + (Right Unit) ] + - location: 153 (remaining gas: 1039916.751 units remaining) + [ (Pair {} (Right Unit)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Right.d336ca1903.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Right.d336ca1903.out" new file mode 100644 index 000000000000..d0bdefc1e6ed --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt \"1\" \"one\" } { Elt \"2\" \"two\" }))-(Right (Right.d336ca1903.out" @@ -0,0 +1,83 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))-(Right (Right (Right (Right { "1" }))))-(Left (Pair 4 5))-big_map_diff5] + +storage + (Left (Pair 4 5)) +emitted operations + +big_map diff + New map(5) of type (big_map string string) + Set map(5)["2"] to "two" + New map(4) of type (big_map string string) + Unset map(4)["1"] +trace + - location: 43 (remaining gas: 1039916.857 units remaining) + [ (Pair (Right (Right (Right (Right { "1" })))) + (Left (Pair { Elt "1" "one" } { Elt "2" "two" }))) ] + - location: 43 (remaining gas: 1039916.847 units remaining) + [ (Right (Right (Right (Right { "1" })))) @parameter + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 44 (remaining gas: 1039916.837 units remaining) + [ (Right (Right (Right { "1" }))) @parameter.right + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 60 (remaining gas: 1039916.827 units remaining) + [ (Right (Right { "1" })) @parameter.right.right + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 65 (remaining gas: 1039916.817 units remaining) + [ (Right { "1" }) @parameter.right.right.right + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 108 (remaining gas: 1039916.807 units remaining) + [ { "1" } @parameter.right.right.right.rem + (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 131 (remaining gas: 1039916.792 units remaining) + [ (Left (Pair { Elt "1" "one" } { Elt "2" "two" })) @storage ] + - location: 134 (remaining gas: 1039916.782 units remaining) + [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] + - location: 134 (remaining gas: 1039916.767 units remaining) + [ (Pair { Elt "1" "one" } { Elt "2" "two" }) @storage.left ] + - location: 140 (remaining gas: 1039916.757 units remaining) + [ { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 131 (remaining gas: 1039916.727 units remaining) + [ { "1" } @parameter.right.right.right.rem + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 141 (remaining gas: 1039916.727 units remaining) + [ "1" @parameter.right.right.right.rem.elt + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 143 (remaining gas: 1039916.712 units remaining) + [ { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 145 (remaining gas: 1039916.697 units remaining) + [ None + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 143 (remaining gas: 1039916.667 units remaining) + [ "1" @parameter.right.right.right.rem.elt + None + { Elt "1" "one" } + { Elt "2" "two" } ] + - location: 147 (remaining gas: 1039915.735 units remaining) + [ {} + { Elt "2" "two" } ] + - location: 141 (remaining gas: 1039915.720 units remaining) + [ {} + { Elt "2" "two" } ] + - location: 148 (remaining gas: 1039915.705 units remaining) + [ (Pair {} { Elt "2" "two" }) ] + - location: 149 (remaining gas: 1039915.690 units remaining) + [ (Left (Pair {} { Elt "2" "two" })) ] + - location: 108 (remaining gas: 1039915.675 units remaining) + [ (Left (Pair {} { Elt "2" "two" })) ] + - location: 65 (remaining gas: 1039915.660 units remaining) + [ (Left (Pair {} { Elt "2" "two" })) ] + - location: 60 (remaining gas: 1039915.645 units remaining) + [ (Left (Pair {} { Elt "2" "two" })) ] + - location: 44 (remaining gas: 1039915.630 units remaining) + [ (Left (Pair {} { Elt "2" "two" })) ] + - location: 151 (remaining gas: 1039915.615 units remaining) + [ {} + (Left (Pair {} { Elt "2" "two" })) ] + - location: 153 (remaining gas: 1039915.600 units remaining) + [ (Pair {} (Left (Pair {} { Elt "2" "two" }))) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair \"foo\" \"bar\" } { P.7f2ee47600.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair \"foo\" \"bar\" } { P.7f2ee47600.out" new file mode 100644 index 000000000000..4ca99999edd6 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair \"foo\" \"bar\" } { P.7f2ee47600.out" @@ -0,0 +1,135 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_big_map_magic[(Right Unit)-(Right (Right (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" }) )))-(Left (Pair 4 5))-big_map_diff3] + +storage + (Left (Pair 4 5)) +emitted operations + +big_map diff + New map(5) of type (big_map string string) + Set map(5)["gaz"] to "baz" + New map(4) of type (big_map string string) + Set map(4)["foo"] to "bar" +trace + - location: 43 (remaining gas: 1039919.139 units remaining) + [ (Pair (Right (Right (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" })))) (Right Unit)) ] + - location: 43 (remaining gas: 1039919.129 units remaining) + [ (Right (Right (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" })))) @parameter + (Right Unit) @storage ] + - location: 44 (remaining gas: 1039919.119 units remaining) + [ (Right (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" }))) @parameter.right + (Right Unit) @storage ] + - location: 60 (remaining gas: 1039919.109 units remaining) + [ (Left (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" })) @parameter.right.right + (Right Unit) @storage ] + - location: 65 (remaining gas: 1039919.099 units remaining) + [ (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" }) @parameter.right.right.import + (Right Unit) @storage ] + - location: 67 (remaining gas: 1039919.084 units remaining) + [ (Right Unit) @storage ] + - location: 70 (remaining gas: 1039919.074 units remaining) + [ Unit @storage.right ] + - location: 70 (remaining gas: 1039919.059 units remaining) + [ Unit @storage.right ] + - location: 76 (remaining gas: 1039919.049 units remaining) + [ ] + - location: 67 (remaining gas: 1039919.019 units remaining) + [ (Pair { Pair "foo" "bar" } { Pair "gaz" "baz" }) @parameter.right.right.import ] + - location: 77 (remaining gas: 1039919.009 units remaining) + [ { Pair "foo" "bar" } + { Pair "gaz" "baz" } ] + - location: 78 (remaining gas: 1039918.994 units remaining) + [ { Pair "gaz" "baz" } ] + - location: 80 (remaining gas: 1039918.979 units remaining) + [ {} + { Pair "gaz" "baz" } ] + - location: 78 (remaining gas: 1039918.949 units remaining) + [ { Pair "foo" "bar" } + {} + { Pair "gaz" "baz" } ] + - location: 83 (remaining gas: 1039918.949 units remaining) + [ (Pair "foo" "bar") @elt + {} + { Pair "gaz" "baz" } ] + - location: 85 (remaining gas: 1039918.939 units remaining) + [ "foo" + "bar" + {} + { Pair "gaz" "baz" } ] + - location: 86 (remaining gas: 1039918.924 units remaining) + [ "bar" + {} + { Pair "gaz" "baz" } ] + - location: 88 (remaining gas: 1039918.909 units remaining) + [ (Some "bar") + {} + { Pair "gaz" "baz" } ] + - location: 86 (remaining gas: 1039918.879 units remaining) + [ "foo" + (Some "bar") + {} + { Pair "gaz" "baz" } ] + - location: 89 (remaining gas: 1039917.881 units remaining) + [ { Elt "foo" "bar" } + { Pair "gaz" "baz" } ] + - location: 83 (remaining gas: 1039917.866 units remaining) + [ { Elt "foo" "bar" } + { Pair "gaz" "baz" } ] + - location: 90 (remaining gas: 1039917.856 units remaining) + [ { Pair "gaz" "baz" } + { Elt "foo" "bar" } ] + - location: 91 (remaining gas: 1039917.841 units remaining) + [ { Elt "foo" "bar" } ] + - location: 93 (remaining gas: 1039917.826 units remaining) + [ {} + { Elt "foo" "bar" } ] + - location: 91 (remaining gas: 1039917.796 units remaining) + [ { Pair "gaz" "baz" } + {} + { Elt "foo" "bar" } ] + - location: 96 (remaining gas: 1039917.796 units remaining) + [ (Pair "gaz" "baz") @elt + {} + { Elt "foo" "bar" } ] + - location: 98 (remaining gas: 1039917.786 units remaining) + [ "gaz" + "baz" + {} + { Elt "foo" "bar" } ] + - location: 99 (remaining gas: 1039917.771 units remaining) + [ "baz" + {} + { Elt "foo" "bar" } ] + - location: 101 (remaining gas: 1039917.756 units remaining) + [ (Some "baz") + {} + { Elt "foo" "bar" } ] + - location: 99 (remaining gas: 1039917.726 units remaining) + [ "gaz" + (Some "baz") + {} + { Elt "foo" "bar" } ] + - location: 102 (remaining gas: 1039916.728 units remaining) + [ { Elt "gaz" "baz" } + { Elt "foo" "bar" } ] + - location: 96 (remaining gas: 1039916.713 units remaining) + [ { Elt "gaz" "baz" } + { Elt "foo" "bar" } ] + - location: 103 (remaining gas: 1039916.703 units remaining) + [ { Elt "foo" "bar" } + { Elt "gaz" "baz" } ] + - location: 104 (remaining gas: 1039916.688 units remaining) + [ (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" }) ] + - location: 105 (remaining gas: 1039916.673 units remaining) + [ (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] + - location: 65 (remaining gas: 1039916.658 units remaining) + [ (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] + - location: 60 (remaining gas: 1039916.643 units remaining) + [ (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] + - location: 44 (remaining gas: 1039916.628 units remaining) + [ (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] + - location: 151 (remaining gas: 1039916.613 units remaining) + [ {} + (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" })) ] + - location: 153 (remaining gas: 1039916.598 units remaining) + [ (Pair {} (Left (Pair { Elt "foo" "bar" } { Elt "gaz" "baz" }))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_check_signature.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_check_signature.out new file mode 100644 index 000000000000..206f5005c7ac --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_check_signature.out @@ -0,0 +1,241 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_check_signature + +storage + (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039651.625 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 9 (remaining gas: 1039651.615 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 10 (remaining gas: 1039651.605 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 11 (remaining gas: 1039651.590 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 13 (remaining gas: 1039651.580 units remaining) + [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") @storage + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 14 (remaining gas: 1039651.570 units remaining) + [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") @storage + (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") @storage + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 15 (remaining gas: 1039651.560 units remaining) + [ "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") @storage + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 16 (remaining gas: 1039651.545 units remaining) + [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") @storage + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 18 (remaining gas: 1039651.535 units remaining) + [ "hello" + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 19 (remaining gas: 1039651.044 units remaining) + [ 0x05010000000568656c6c6f @packed + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 16 (remaining gas: 1039651.014 units remaining) + [ "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + 0x05010000000568656c6c6f @packed + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 11 (remaining gas: 1039650.984 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + 0x05010000000568656c6c6f @packed + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 20 (remaining gas: 1039650.974 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @parameter + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + 0x05010000000568656c6c6f @packed + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 21 (remaining gas: 1039585.162 units remaining) + [ True + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 22 (remaining gas: 1039585.152 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 22 (remaining gas: 1039585.137 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + - location: 28 (remaining gas: 1039585.127 units remaining) + [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") @storage ] + - location: 29 (remaining gas: 1039585.112 units remaining) + [ {} + (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") @storage ] + - location: 31 (remaining gas: 1039585.097 units remaining) + [ (Pair {} + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "hello") ] + +Runtime error in contract [CONTRACT_HASH]: + 01: parameter key; + 02: storage (pair signature string); + 03: code { + 04: DUP; DUP; + 05: DIP{ CDR; DUP; CAR; + 06: DIP{CDR; PACK}}; + 07: CAR; CHECK_SIGNATURE; + 08: IF {} {FAIL} ; + 09: CDR; NIL operation ; PAIR}; + 10: + 11: +At line 8 characters 14 to 18, +script reached FAILWITH instruction +with Unit +trace + - location: 9 (remaining gas: 1039651.635 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 9 (remaining gas: 1039651.625 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 10 (remaining gas: 1039651.615 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 11 (remaining gas: 1039651.600 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 13 (remaining gas: 1039651.590 units remaining) + [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") @storage + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 14 (remaining gas: 1039651.580 units remaining) + [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") @storage + (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") @storage + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 15 (remaining gas: 1039651.570 units remaining) + [ "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") @storage + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 16 (remaining gas: 1039651.555 units remaining) + [ (Pair "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") @storage + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 18 (remaining gas: 1039651.545 units remaining) + [ "abcd" + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 19 (remaining gas: 1039651.087 units remaining) + [ 0x05010000000461626364 @packed + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 16 (remaining gas: 1039651.057 units remaining) + [ "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + 0x05010000000461626364 @packed + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 11 (remaining gas: 1039651.027 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + 0x05010000000461626364 @packed + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 20 (remaining gas: 1039651.017 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @parameter + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + 0x05010000000461626364 @packed + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 21 (remaining gas: 1039585.206 units remaining) + [ False + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 22 (remaining gas: 1039585.196 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] + - location: 26 (remaining gas: 1039585.186 units remaining) + [ Unit + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF" + "abcd") ] +Fatal error: + error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit].out new file mode 100644 index 000000000000..9643cd26e8d9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit].out @@ -0,0 +1,38 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[abs.tz-Unit-0-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039988.319 units remaining) + [ (Pair 0 Unit) ] + - location: 7 (remaining gas: 1039988.309 units remaining) + [ 0 @parameter ] + - location: 8 (remaining gas: 1039988.299 units remaining) + [ 0 @parameter + 0 @parameter ] + - location: 9 (remaining gas: 1039988.259 units remaining) + [ 0 + 0 @parameter ] + - location: 10 (remaining gas: 1039988.234 units remaining) + [ 0 + 0 @parameter ] + - location: 11 (remaining gas: 1039988.199 units remaining) + [ 0 ] + - location: 13 (remaining gas: 1039988.184 units remaining) + [ True ] + - location: 14 (remaining gas: 1039988.174 units remaining) + [ ] + - location: 14 (remaining gas: 1039988.159 units remaining) + [ ] + - location: 20 (remaining gas: 1039988.149 units remaining) + [ Unit ] + - location: 21 (remaining gas: 1039988.134 units remaining) + [ {} + Unit ] + - location: 23 (remaining gas: 1039988.119 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit].out new file mode 100644 index 000000000000..40bf09181f50 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit].out @@ -0,0 +1,38 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[abs.tz-Unit-12039123919239192312931-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039988.319 units remaining) + [ (Pair 12039123919239192312931 Unit) ] + - location: 7 (remaining gas: 1039988.309 units remaining) + [ 12039123919239192312931 @parameter ] + - location: 8 (remaining gas: 1039988.299 units remaining) + [ 12039123919239192312931 @parameter + 12039123919239192312931 @parameter ] + - location: 9 (remaining gas: 1039988.259 units remaining) + [ -12039123919239192312931 + 12039123919239192312931 @parameter ] + - location: 10 (remaining gas: 1039988.234 units remaining) + [ 12039123919239192312931 + 12039123919239192312931 @parameter ] + - location: 11 (remaining gas: 1039988.199 units remaining) + [ 0 ] + - location: 13 (remaining gas: 1039988.184 units remaining) + [ True ] + - location: 14 (remaining gas: 1039988.174 units remaining) + [ ] + - location: 14 (remaining gas: 1039988.159 units remaining) + [ ] + - location: 20 (remaining gas: 1039988.149 units remaining) + [ Unit ] + - location: 21 (remaining gas: 1039988.134 units remaining) + [ {} + Unit ] + - location: 23 (remaining gas: 1039988.119 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit].out new file mode 100644 index 000000000000..8f0fe26aa9dd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit].out @@ -0,0 +1,38 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[abs.tz-Unit-948-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039988.319 units remaining) + [ (Pair 948 Unit) ] + - location: 7 (remaining gas: 1039988.309 units remaining) + [ 948 @parameter ] + - location: 8 (remaining gas: 1039988.299 units remaining) + [ 948 @parameter + 948 @parameter ] + - location: 9 (remaining gas: 1039988.259 units remaining) + [ -948 + 948 @parameter ] + - location: 10 (remaining gas: 1039988.234 units remaining) + [ 948 + 948 @parameter ] + - location: 11 (remaining gas: 1039988.199 units remaining) + [ 0 ] + - location: 13 (remaining gas: 1039988.184 units remaining) + [ True ] + - location: 14 (remaining gas: 1039988.174 units remaining) + [ ] + - location: 14 (remaining gas: 1039988.159 units remaining) + [ ] + - location: 20 (remaining gas: 1039988.149 units remaining) + [ Unit ] + - location: 21 (remaining gas: 1039988.134 units remaining) + [ {} + Unit ] + - location: 23 (remaining gas: 1039988.119 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit].out new file mode 100644 index 000000000000..bde601847c3f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit].out @@ -0,0 +1,211 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add.tz-Unit-Unit-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039925.003 units remaining) + [ (Pair Unit Unit) ] + - location: 7 (remaining gas: 1039924.993 units remaining) + [ Unit @parameter ] + - location: 8 (remaining gas: 1039924.983 units remaining) + [ 2 + Unit @parameter ] + - location: 11 (remaining gas: 1039924.973 units remaining) + [ 2 + 2 + Unit @parameter ] + - location: 14 (remaining gas: 1039924.918 units remaining) + [ 4 + Unit @parameter ] + - location: 15 (remaining gas: 1039924.908 units remaining) + [ 4 + 4 + Unit @parameter ] + - location: 20 (remaining gas: 1039924.873 units remaining) + [ 0 + Unit @parameter ] + - location: 21 (remaining gas: 1039924.858 units remaining) + [ True + Unit @parameter ] + - location: 22 (remaining gas: 1039924.848 units remaining) + [ Unit @parameter ] + - location: 22 (remaining gas: 1039924.833 units remaining) + [ Unit @parameter ] + - location: 28 (remaining gas: 1039924.823 units remaining) + [ 2 + Unit @parameter ] + - location: 31 (remaining gas: 1039924.813 units remaining) + [ 2 + 2 + Unit @parameter ] + - location: 34 (remaining gas: 1039924.758 units remaining) + [ 4 + Unit @parameter ] + - location: 35 (remaining gas: 1039924.748 units remaining) + [ 4 + 4 + Unit @parameter ] + - location: 40 (remaining gas: 1039924.713 units remaining) + [ 0 + Unit @parameter ] + - location: 41 (remaining gas: 1039924.698 units remaining) + [ True + Unit @parameter ] + - location: 42 (remaining gas: 1039924.688 units remaining) + [ Unit @parameter ] + - location: 42 (remaining gas: 1039924.673 units remaining) + [ Unit @parameter ] + - location: 48 (remaining gas: 1039924.663 units remaining) + [ 2 + Unit @parameter ] + - location: 51 (remaining gas: 1039924.653 units remaining) + [ 2 + 2 + Unit @parameter ] + - location: 54 (remaining gas: 1039924.598 units remaining) + [ 4 + Unit @parameter ] + - location: 55 (remaining gas: 1039924.588 units remaining) + [ 4 + 4 + Unit @parameter ] + - location: 60 (remaining gas: 1039924.553 units remaining) + [ 0 + Unit @parameter ] + - location: 61 (remaining gas: 1039924.538 units remaining) + [ True + Unit @parameter ] + - location: 62 (remaining gas: 1039924.528 units remaining) + [ Unit @parameter ] + - location: 62 (remaining gas: 1039924.513 units remaining) + [ Unit @parameter ] + - location: 68 (remaining gas: 1039924.503 units remaining) + [ 2 + Unit @parameter ] + - location: 71 (remaining gas: 1039924.493 units remaining) + [ 2 + 2 + Unit @parameter ] + - location: 74 (remaining gas: 1039924.438 units remaining) + [ 4 + Unit @parameter ] + - location: 75 (remaining gas: 1039924.428 units remaining) + [ 4 + 4 + Unit @parameter ] + - location: 80 (remaining gas: 1039924.393 units remaining) + [ 0 + Unit @parameter ] + - location: 81 (remaining gas: 1039924.378 units remaining) + [ True + Unit @parameter ] + - location: 82 (remaining gas: 1039924.368 units remaining) + [ Unit @parameter ] + - location: 82 (remaining gas: 1039924.353 units remaining) + [ Unit @parameter ] + - location: 88 (remaining gas: 1039924.343 units remaining) + [ 2 + Unit @parameter ] + - location: 91 (remaining gas: 1039924.333 units remaining) + [ 2 + 2 + Unit @parameter ] + - location: 94 (remaining gas: 1039924.278 units remaining) + [ 4 + Unit @parameter ] + - location: 95 (remaining gas: 1039924.268 units remaining) + [ 4 + 4 + Unit @parameter ] + - location: 100 (remaining gas: 1039924.233 units remaining) + [ 0 + Unit @parameter ] + - location: 101 (remaining gas: 1039924.218 units remaining) + [ True + Unit @parameter ] + - location: 102 (remaining gas: 1039924.208 units remaining) + [ Unit @parameter ] + - location: 102 (remaining gas: 1039924.193 units remaining) + [ Unit @parameter ] + - location: 108 (remaining gas: 1039924.183 units remaining) + [ 60 + Unit @parameter ] + - location: 111 (remaining gas: 1039924.173 units remaining) + [ "2019-09-09T12:08:37Z" + 60 + Unit @parameter ] + - location: 114 (remaining gas: 1039924.118 units remaining) + [ "2019-09-09T12:09:37Z" + Unit @parameter ] + - location: 115 (remaining gas: 1039924.108 units remaining) + [ "2019-09-09T12:09:37Z" + "2019-09-09T12:09:37Z" + Unit @parameter ] + - location: 120 (remaining gas: 1039924.073 units remaining) + [ 0 + Unit @parameter ] + - location: 121 (remaining gas: 1039924.058 units remaining) + [ True + Unit @parameter ] + - location: 122 (remaining gas: 1039924.048 units remaining) + [ Unit @parameter ] + - location: 122 (remaining gas: 1039924.033 units remaining) + [ Unit @parameter ] + - location: 128 (remaining gas: 1039924.023 units remaining) + [ "2019-09-09T12:08:37Z" + Unit @parameter ] + - location: 131 (remaining gas: 1039924.013 units remaining) + [ 60 + "2019-09-09T12:08:37Z" + Unit @parameter ] + - location: 134 (remaining gas: 1039923.958 units remaining) + [ "2019-09-09T12:09:37Z" + Unit @parameter ] + - location: 135 (remaining gas: 1039923.948 units remaining) + [ "2019-09-09T12:09:37Z" + "2019-09-09T12:09:37Z" + Unit @parameter ] + - location: 140 (remaining gas: 1039923.913 units remaining) + [ 0 + Unit @parameter ] + - location: 141 (remaining gas: 1039923.898 units remaining) + [ True + Unit @parameter ] + - location: 142 (remaining gas: 1039923.888 units remaining) + [ Unit @parameter ] + - location: 142 (remaining gas: 1039923.873 units remaining) + [ Unit @parameter ] + - location: 148 (remaining gas: 1039923.863 units remaining) + [ 1000 + Unit @parameter ] + - location: 151 (remaining gas: 1039923.853 units remaining) + [ 1000 + 1000 + Unit @parameter ] + - location: 154 (remaining gas: 1039923.833 units remaining) + [ 2000 + Unit @parameter ] + - location: 155 (remaining gas: 1039923.823 units remaining) + [ 2000 + 2000 + Unit @parameter ] + - location: 160 (remaining gas: 1039923.788 units remaining) + [ 0 + Unit @parameter ] + - location: 161 (remaining gas: 1039923.773 units remaining) + [ True + Unit @parameter ] + - location: 162 (remaining gas: 1039923.763 units remaining) + [ Unit @parameter ] + - location: 162 (remaining gas: 1039923.748 units remaining) + [ Unit @parameter ] + - location: 168 (remaining gas: 1039923.733 units remaining) + [ {} + Unit @parameter ] + - location: 170 (remaining gas: 1039923.718 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000.3c2de60480.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000.3c2de60480.out new file mode 100644 index 000000000000..dc616e16cde6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000.3c2de60480.out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x00 0x00-(Some 0x0000000000000000000000000000000000000000000000000000000000000000)] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.524 units remaining) + [ (Pair (Pair 0x0000000000000000000000000000000000000000000000000000000000000000 + 0x0000000000000000000000000000000000000000000000000000000000000000) + None) ] + - location: 10 (remaining gas: 1039992.514 units remaining) + [ (Pair 0x0000000000000000000000000000000000000000000000000000000000000000 + 0x0000000000000000000000000000000000000000000000000000000000000000) @parameter ] + - location: 11 (remaining gas: 1039992.504 units remaining) + [ 0x0000000000000000000000000000000000000000000000000000000000000000 + 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039992.459 units remaining) + [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 13 (remaining gas: 1039992.444 units remaining) + [ (Some 0x0000000000000000000000000000000000000000000000000000000000000000) ] + - location: 14 (remaining gas: 1039992.429 units remaining) + [ {} + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) ] + - location: 16 (remaining gas: 1039992.414 units remaining) + [ (Pair {} + (Some 0x0000000000000000000000000000000000000000000000000000000000000000)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000.12b2c1172b.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000.12b2c1172b.out new file mode 100644 index 000000000000..da262115ebfe --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000.12b2c1172b.out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x01 0x00-(Some 0x0100000000000000000000000000000000000000000000000000000000000000)] + +storage + (Some 0x0100000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.524 units remaining) + [ (Pair (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 + 0x0000000000000000000000000000000000000000000000000000000000000000) + None) ] + - location: 10 (remaining gas: 1039992.514 units remaining) + [ (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 + 0x0000000000000000000000000000000000000000000000000000000000000000) @parameter ] + - location: 11 (remaining gas: 1039992.504 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 + 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039992.459 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 13 (remaining gas: 1039992.444 units remaining) + [ (Some 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 14 (remaining gas: 1039992.429 units remaining) + [ {} + (Some 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 16 (remaining gas: 1039992.414 units remaining) + [ (Pair {} + (Some 0x0100000000000000000000000000000000000000000000000000000000000000)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x010.0e44fc6f40.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x010.0e44fc6f40.out new file mode 100644 index 000000000000..964be17ffd41 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x010.0e44fc6f40.out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x00-(Some 0x0100000000000000000000000000000000000000000000000000000000000000)] + +storage + (Some 0x0100000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.524 units remaining) + [ (Pair (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 + 0x0000000000000000000000000000000000000000000000000000000000000000) + None) ] + - location: 10 (remaining gas: 1039992.514 units remaining) + [ (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 + 0x0000000000000000000000000000000000000000000000000000000000000000) @parameter ] + - location: 11 (remaining gas: 1039992.504 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 + 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039992.459 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 13 (remaining gas: 1039992.444 units remaining) + [ (Some 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 14 (remaining gas: 1039992.429 units remaining) + [ {} + (Some 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 16 (remaining gas: 1039992.414 units remaining) + [ (Pair {} + (Some 0x0100000000000000000000000000000000000000000000000000000000000000)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0.7e0ed229a3.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0.7e0ed229a3.out new file mode 100644 index 000000000000..7e3e53f07a5b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0.7e0ed229a3.out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_bls12_381_fr.tz-None-Pair 0x010000 0x010000-(Some 0x0200000000000000000000000000000000000000000000000000000000000000)] + +storage + (Some 0x0200000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.524 units remaining) + [ (Pair (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 + 0x0100000000000000000000000000000000000000000000000000000000000000) + None) ] + - location: 10 (remaining gas: 1039992.514 units remaining) + [ (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 + 0x0100000000000000000000000000000000000000000000000000000000000000) @parameter ] + - location: 11 (remaining gas: 1039992.504 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 + 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039992.459 units remaining) + [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] + - location: 13 (remaining gas: 1039992.444 units remaining) + [ (Some 0x0200000000000000000000000000000000000000000000000000000000000000) ] + - location: 14 (remaining gas: 1039992.429 units remaining) + [ {} + (Some 0x0200000000000000000000000000000000000000000000000000000000000000) ] + - location: 16 (remaining gas: 1039992.414 units remaining) + [ (Pair {} + (Some 0x0200000000000000000000000000000000000000000000000000000000000000)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some \"1970.7c1b1e4e5b.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some \"1970.7c1b1e4e5b.out" new file mode 100644 index 000000000000..c8b84e53c207 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some \"1970.7c1b1e4e5b.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair -100 100)-(Some "1970-01-01T00:00:00Z")] + +storage + (Some "1970-01-01T00:00:00Z") +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.553 units remaining) + [ (Pair (Pair -100 "1970-01-01T00:01:40Z") None) ] + - location: 10 (remaining gas: 1039990.543 units remaining) + [ (Pair -100 "1970-01-01T00:01:40Z") @parameter ] + - location: 11 (remaining gas: 1039990.533 units remaining) + [ (Pair -100 "1970-01-01T00:01:40Z") @parameter + (Pair -100 "1970-01-01T00:01:40Z") @parameter ] + - location: 12 (remaining gas: 1039990.523 units remaining) + [ -100 + (Pair -100 "1970-01-01T00:01:40Z") @parameter ] + - location: 13 (remaining gas: 1039990.508 units remaining) + [ (Pair -100 "1970-01-01T00:01:40Z") @parameter ] + - location: 15 (remaining gas: 1039990.498 units remaining) + [ "1970-01-01T00:01:40Z" ] + - location: 13 (remaining gas: 1039990.468 units remaining) + [ -100 + "1970-01-01T00:01:40Z" ] + - location: 16 (remaining gas: 1039990.413 units remaining) + [ "1970-01-01T00:00:00Z" ] + - location: 17 (remaining gas: 1039990.398 units remaining) + [ (Some "1970-01-01T00:00:00Z") ] + - location: 18 (remaining gas: 1039990.383 units remaining) + [ {} + (Some "1970-01-01T00:00:00Z") ] + - location: 20 (remaining gas: 1039990.368 units remaining) + [ (Pair {} (Some "1970-01-01T00:00:00Z")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 \"1970-01-01T00:00:0.528ed42c01.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 \"1970-01-01T00:00:0.528ed42c01.out" new file mode 100644 index 000000000000..2a69ae290fc5 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 \"1970-01-01T00:00:0.528ed42c01.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 0 "1970-01-01T00:00:00Z")-(Some "1970-01-01T00:00:00Z")] + +storage + (Some "1970-01-01T00:00:00Z") +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.453 units remaining) + [ (Pair (Pair 0 "1970-01-01T00:00:00Z") None) ] + - location: 10 (remaining gas: 1039990.443 units remaining) + [ (Pair 0 "1970-01-01T00:00:00Z") @parameter ] + - location: 11 (remaining gas: 1039990.433 units remaining) + [ (Pair 0 "1970-01-01T00:00:00Z") @parameter + (Pair 0 "1970-01-01T00:00:00Z") @parameter ] + - location: 12 (remaining gas: 1039990.423 units remaining) + [ 0 + (Pair 0 "1970-01-01T00:00:00Z") @parameter ] + - location: 13 (remaining gas: 1039990.408 units remaining) + [ (Pair 0 "1970-01-01T00:00:00Z") @parameter ] + - location: 15 (remaining gas: 1039990.398 units remaining) + [ "1970-01-01T00:00:00Z" ] + - location: 13 (remaining gas: 1039990.368 units remaining) + [ 0 + "1970-01-01T00:00:00Z" ] + - location: 16 (remaining gas: 1039990.313 units remaining) + [ "1970-01-01T00:00:00Z" ] + - location: 17 (remaining gas: 1039990.298 units remaining) + [ (Some "1970-01-01T00:00:00Z") ] + - location: 18 (remaining gas: 1039990.283 units remaining) + [ {} + (Some "1970-01-01T00:00:00Z") ] + - location: 20 (remaining gas: 1039990.268 units remaining) + [ (Pair {} (Some "1970-01-01T00:00:00Z")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some \"1970-.6566111ad2.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some \"1970-.6566111ad2.out" new file mode 100644 index 000000000000..48041181fad7 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some \"1970-.6566111ad2.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_delta_timestamp.tz-None-(Pair 100 100)-(Some "1970-01-01T00:03:20Z")] + +storage + (Some "1970-01-01T00:03:20Z") +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.553 units remaining) + [ (Pair (Pair 100 "1970-01-01T00:01:40Z") None) ] + - location: 10 (remaining gas: 1039990.543 units remaining) + [ (Pair 100 "1970-01-01T00:01:40Z") @parameter ] + - location: 11 (remaining gas: 1039990.533 units remaining) + [ (Pair 100 "1970-01-01T00:01:40Z") @parameter + (Pair 100 "1970-01-01T00:01:40Z") @parameter ] + - location: 12 (remaining gas: 1039990.523 units remaining) + [ 100 + (Pair 100 "1970-01-01T00:01:40Z") @parameter ] + - location: 13 (remaining gas: 1039990.508 units remaining) + [ (Pair 100 "1970-01-01T00:01:40Z") @parameter ] + - location: 15 (remaining gas: 1039990.498 units remaining) + [ "1970-01-01T00:01:40Z" ] + - location: 13 (remaining gas: 1039990.468 units remaining) + [ 100 + "1970-01-01T00:01:40Z" ] + - location: 16 (remaining gas: 1039990.413 units remaining) + [ "1970-01-01T00:03:20Z" ] + - location: 17 (remaining gas: 1039990.398 units remaining) + [ (Some "1970-01-01T00:03:20Z") ] + - location: 18 (remaining gas: 1039990.383 units remaining) + [ {} + (Some "1970-01-01T00:03:20Z") ] + - location: 20 (remaining gas: 1039990.368 units remaining) + [ (Pair {} (Some "1970-01-01T00:03:20Z")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair \"1970-01-01T00:00:00Z.72c424f3da.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair \"1970-01-01T00:00:00Z.72c424f3da.out" new file mode 100644 index 000000000000..8d294941312f --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair \"1970-01-01T00:00:00Z.72c424f3da.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair "1970-01-01T00:00:00Z" 0)-(Some "1970-01-01T00:00:00Z")] + +storage + (Some "1970-01-01T00:00:00Z") +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.453 units remaining) + [ (Pair (Pair "1970-01-01T00:00:00Z" 0) None) ] + - location: 10 (remaining gas: 1039990.443 units remaining) + [ (Pair "1970-01-01T00:00:00Z" 0) @parameter ] + - location: 11 (remaining gas: 1039990.433 units remaining) + [ (Pair "1970-01-01T00:00:00Z" 0) @parameter + (Pair "1970-01-01T00:00:00Z" 0) @parameter ] + - location: 12 (remaining gas: 1039990.423 units remaining) + [ "1970-01-01T00:00:00Z" + (Pair "1970-01-01T00:00:00Z" 0) @parameter ] + - location: 13 (remaining gas: 1039990.408 units remaining) + [ (Pair "1970-01-01T00:00:00Z" 0) @parameter ] + - location: 15 (remaining gas: 1039990.398 units remaining) + [ 0 ] + - location: 13 (remaining gas: 1039990.368 units remaining) + [ "1970-01-01T00:00:00Z" + 0 ] + - location: 16 (remaining gas: 1039990.313 units remaining) + [ "1970-01-01T00:00:00Z" ] + - location: 17 (remaining gas: 1039990.298 units remaining) + [ (Some "1970-01-01T00:00:00Z") ] + - location: 18 (remaining gas: 1039990.283 units remaining) + [ {} + (Some "1970-01-01T00:00:00Z") ] + - location: 20 (remaining gas: 1039990.268 units remaining) + [ (Pair {} (Some "1970-01-01T00:00:00Z")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some \"1970.7c4b12e9aa.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some \"1970.7c4b12e9aa.out" new file mode 100644 index 000000000000..2a2325747c6e --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some \"1970.7c4b12e9aa.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 -100)-(Some "1970-01-01T00:00:00Z")] + +storage + (Some "1970-01-01T00:00:00Z") +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.553 units remaining) + [ (Pair (Pair "1970-01-01T00:01:40Z" -100) None) ] + - location: 10 (remaining gas: 1039990.543 units remaining) + [ (Pair "1970-01-01T00:01:40Z" -100) @parameter ] + - location: 11 (remaining gas: 1039990.533 units remaining) + [ (Pair "1970-01-01T00:01:40Z" -100) @parameter + (Pair "1970-01-01T00:01:40Z" -100) @parameter ] + - location: 12 (remaining gas: 1039990.523 units remaining) + [ "1970-01-01T00:01:40Z" + (Pair "1970-01-01T00:01:40Z" -100) @parameter ] + - location: 13 (remaining gas: 1039990.508 units remaining) + [ (Pair "1970-01-01T00:01:40Z" -100) @parameter ] + - location: 15 (remaining gas: 1039990.498 units remaining) + [ -100 ] + - location: 13 (remaining gas: 1039990.468 units remaining) + [ "1970-01-01T00:01:40Z" + -100 ] + - location: 16 (remaining gas: 1039990.413 units remaining) + [ "1970-01-01T00:00:00Z" ] + - location: 17 (remaining gas: 1039990.398 units remaining) + [ (Some "1970-01-01T00:00:00Z") ] + - location: 18 (remaining gas: 1039990.383 units remaining) + [ {} + (Some "1970-01-01T00:00:00Z") ] + - location: 20 (remaining gas: 1039990.368 units remaining) + [ (Pair {} (Some "1970-01-01T00:00:00Z")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some \"1970-.af32743640.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some \"1970-.af32743640.out" new file mode 100644 index 000000000000..1695417d8fa4 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some \"1970-.af32743640.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[add_timestamp_delta.tz-None-(Pair 100 100)-(Some "1970-01-01T00:03:20Z")] + +storage + (Some "1970-01-01T00:03:20Z") +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.553 units remaining) + [ (Pair (Pair "1970-01-01T00:01:40Z" 100) None) ] + - location: 10 (remaining gas: 1039990.543 units remaining) + [ (Pair "1970-01-01T00:01:40Z" 100) @parameter ] + - location: 11 (remaining gas: 1039990.533 units remaining) + [ (Pair "1970-01-01T00:01:40Z" 100) @parameter + (Pair "1970-01-01T00:01:40Z" 100) @parameter ] + - location: 12 (remaining gas: 1039990.523 units remaining) + [ "1970-01-01T00:01:40Z" + (Pair "1970-01-01T00:01:40Z" 100) @parameter ] + - location: 13 (remaining gas: 1039990.508 units remaining) + [ (Pair "1970-01-01T00:01:40Z" 100) @parameter ] + - location: 15 (remaining gas: 1039990.498 units remaining) + [ 100 ] + - location: 13 (remaining gas: 1039990.468 units remaining) + [ "1970-01-01T00:01:40Z" + 100 ] + - location: 16 (remaining gas: 1039990.413 units remaining) + [ "1970-01-01T00:03:20Z" ] + - location: 17 (remaining gas: 1039990.398 units remaining) + [ (Some "1970-01-01T00:03:20Z") ] + - location: 18 (remaining gas: 1039990.383 units remaining) + [ {} + (Some "1970-01-01T00:03:20Z") ] + - location: 20 (remaining gas: 1039990.368 units remaining) + [ (Pair {} (Some "1970-01-01T00:03:20Z")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[address.tz-None-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[address.tz-None-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" new file mode 100644 index 000000000000..abca1690d6f8 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[address.tz-None-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-.f9045c3a04.out" @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[address.tz-None-"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"-(Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5")] + +storage + (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039343.609 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" None) ] + - location: 9 (remaining gas: 1039343.599 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter ] + - location: 10 (remaining gas: 1039343.589 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter.address ] + - location: 11 (remaining gas: 1039343.574 units remaining) + [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 12 (remaining gas: 1039343.559 units remaining) + [ {} + (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 14 (remaining gas: 1039343.544 units remaining) + [ (Pair {} (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5")) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)].out new file mode 100644 index 000000000000..59214aa8a292 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)].out @@ -0,0 +1,31 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False False)-(Some False)] + +storage + (Some False) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.303 units remaining) + [ (Pair (Pair False False) None) ] + - location: 10 (remaining gas: 1039991.293 units remaining) + [ (Pair False False) @param ] + - location: 11 (remaining gas: 1039991.283 units remaining) + [ False + False ] + - location: 12 (remaining gas: 1039991.263 units remaining) + [ False @and ] + - location: 13 (remaining gas: 1039991.248 units remaining) + [ (Some False) @res ] + - location: 14 (remaining gas: 1039991.233 units remaining) + [ {} @noop + (Some False) @res ] + - location: 16 (remaining gas: 1039991.218 units remaining) + [ (Pair {} (Some False)) ] + - location: 17 (remaining gas: 1039991.208 units remaining) + [ {} @x + (Some False) @y ] + - location: 18 (remaining gas: 1039991.193 units remaining) + [ (Pair {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)].out new file mode 100644 index 000000000000..0de1989da302 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)].out @@ -0,0 +1,31 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair False True)-(Some False)] + +storage + (Some False) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.303 units remaining) + [ (Pair (Pair False True) None) ] + - location: 10 (remaining gas: 1039991.293 units remaining) + [ (Pair False True) @param ] + - location: 11 (remaining gas: 1039991.283 units remaining) + [ False + True ] + - location: 12 (remaining gas: 1039991.263 units remaining) + [ False @and ] + - location: 13 (remaining gas: 1039991.248 units remaining) + [ (Some False) @res ] + - location: 14 (remaining gas: 1039991.233 units remaining) + [ {} @noop + (Some False) @res ] + - location: 16 (remaining gas: 1039991.218 units remaining) + [ (Pair {} (Some False)) ] + - location: 17 (remaining gas: 1039991.208 units remaining) + [ {} @x + (Some False) @y ] + - location: 18 (remaining gas: 1039991.193 units remaining) + [ (Pair {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)].out new file mode 100644 index 000000000000..4b6236ae6839 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)].out @@ -0,0 +1,31 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True False)-(Some False)] + +storage + (Some False) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.303 units remaining) + [ (Pair (Pair True False) None) ] + - location: 10 (remaining gas: 1039991.293 units remaining) + [ (Pair True False) @param ] + - location: 11 (remaining gas: 1039991.283 units remaining) + [ True + False ] + - location: 12 (remaining gas: 1039991.263 units remaining) + [ False @and ] + - location: 13 (remaining gas: 1039991.248 units remaining) + [ (Some False) @res ] + - location: 14 (remaining gas: 1039991.233 units remaining) + [ {} @noop + (Some False) @res ] + - location: 16 (remaining gas: 1039991.218 units remaining) + [ (Pair {} (Some False)) ] + - location: 17 (remaining gas: 1039991.208 units remaining) + [ {} @x + (Some False) @y ] + - location: 18 (remaining gas: 1039991.193 units remaining) + [ (Pair {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)].out new file mode 100644 index 000000000000..8b9d30f12fd8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)].out @@ -0,0 +1,31 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and.tz-None-(Pair True True)-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.303 units remaining) + [ (Pair (Pair True True) None) ] + - location: 10 (remaining gas: 1039991.293 units remaining) + [ (Pair True True) @param ] + - location: 11 (remaining gas: 1039991.283 units remaining) + [ True + True ] + - location: 12 (remaining gas: 1039991.263 units remaining) + [ True @and ] + - location: 13 (remaining gas: 1039991.248 units remaining) + [ (Some True) @res ] + - location: 14 (remaining gas: 1039991.233 units remaining) + [ {} @noop + (Some True) @res ] + - location: 16 (remaining gas: 1039991.218 units remaining) + [ (Pair {} (Some True)) ] + - location: 17 (remaining gas: 1039991.208 units remaining) + [ {} @x + (Some True) @y ] + - location: 18 (remaining gas: 1039991.193 units remaining) + [ (Pair {} (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit].out new file mode 100644 index 000000000000..21e63c6ba144 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit].out @@ -0,0 +1,93 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_binary.tz-Unit-Unit-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039960.451 units remaining) + [ (Pair Unit Unit) ] + - location: 7 (remaining gas: 1039960.441 units remaining) + [ ] + - location: 8 (remaining gas: 1039960.431 units remaining) + [ 5 ] + - location: 11 (remaining gas: 1039960.421 units remaining) + [ 6 + 5 ] + - location: 14 (remaining gas: 1039960.371 units remaining) + [ 4 ] + - location: 15 (remaining gas: 1039960.361 units remaining) + [ 4 + 4 ] + - location: 20 (remaining gas: 1039960.326 units remaining) + [ 0 ] + - location: 21 (remaining gas: 1039960.311 units remaining) + [ True ] + - location: 22 (remaining gas: 1039960.301 units remaining) + [ ] + - location: 22 (remaining gas: 1039960.286 units remaining) + [ ] + - location: 28 (remaining gas: 1039960.276 units remaining) + [ 6 ] + - location: 31 (remaining gas: 1039960.266 units remaining) + [ 5 + 6 ] + - location: 34 (remaining gas: 1039960.216 units remaining) + [ 4 ] + - location: 35 (remaining gas: 1039960.206 units remaining) + [ 4 + 4 ] + - location: 40 (remaining gas: 1039960.171 units remaining) + [ 0 ] + - location: 41 (remaining gas: 1039960.156 units remaining) + [ True ] + - location: 42 (remaining gas: 1039960.146 units remaining) + [ ] + - location: 42 (remaining gas: 1039960.131 units remaining) + [ ] + - location: 48 (remaining gas: 1039960.121 units remaining) + [ 12 ] + - location: 51 (remaining gas: 1039960.111 units remaining) + [ -1 + 12 ] + - location: 54 (remaining gas: 1039960.061 units remaining) + [ 12 ] + - location: 55 (remaining gas: 1039960.051 units remaining) + [ 12 + 12 ] + - location: 60 (remaining gas: 1039960.016 units remaining) + [ 0 ] + - location: 61 (remaining gas: 1039960.001 units remaining) + [ True ] + - location: 62 (remaining gas: 1039959.991 units remaining) + [ ] + - location: 62 (remaining gas: 1039959.976 units remaining) + [ ] + - location: 68 (remaining gas: 1039959.966 units remaining) + [ 12 ] + - location: 71 (remaining gas: 1039959.956 units remaining) + [ -5 + 12 ] + - location: 74 (remaining gas: 1039959.906 units remaining) + [ 8 ] + - location: 75 (remaining gas: 1039959.896 units remaining) + [ 8 + 8 ] + - location: 80 (remaining gas: 1039959.861 units remaining) + [ 0 ] + - location: 81 (remaining gas: 1039959.846 units remaining) + [ True ] + - location: 82 (remaining gas: 1039959.836 units remaining) + [ ] + - location: 82 (remaining gas: 1039959.821 units remaining) + [ ] + - location: 88 (remaining gas: 1039959.811 units remaining) + [ Unit ] + - location: 89 (remaining gas: 1039959.796 units remaining) + [ {} @noop + Unit ] + - location: 91 (remaining gas: 1039959.781 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False].out new file mode 100644 index 000000000000..27ca95166a14 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False].out @@ -0,0 +1,24 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False False)-False] + +storage + False +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039993.804 units remaining) + [ (Pair (Pair False False) False) ] + - location: 9 (remaining gas: 1039993.794 units remaining) + [ (Pair False False) @parameter ] + - location: 10 (remaining gas: 1039993.784 units remaining) + [ False + False ] + - location: 11 (remaining gas: 1039993.764 units remaining) + [ False @and ] + - location: 12 (remaining gas: 1039993.749 units remaining) + [ {} @noop + False @and ] + - location: 14 (remaining gas: 1039993.734 units remaining) + [ (Pair {} False) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False].out new file mode 100644 index 000000000000..1b7db01827a7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False].out @@ -0,0 +1,24 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair False True)-False] + +storage + False +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039993.804 units remaining) + [ (Pair (Pair False True) False) ] + - location: 9 (remaining gas: 1039993.794 units remaining) + [ (Pair False True) @parameter ] + - location: 10 (remaining gas: 1039993.784 units remaining) + [ False + True ] + - location: 11 (remaining gas: 1039993.764 units remaining) + [ False @and ] + - location: 12 (remaining gas: 1039993.749 units remaining) + [ {} @noop + False @and ] + - location: 14 (remaining gas: 1039993.734 units remaining) + [ (Pair {} False) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False].out new file mode 100644 index 000000000000..5a138dcd59b3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False].out @@ -0,0 +1,24 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True False)-False] + +storage + False +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039993.804 units remaining) + [ (Pair (Pair True False) False) ] + - location: 9 (remaining gas: 1039993.794 units remaining) + [ (Pair True False) @parameter ] + - location: 10 (remaining gas: 1039993.784 units remaining) + [ True + False ] + - location: 11 (remaining gas: 1039993.764 units remaining) + [ False @and ] + - location: 12 (remaining gas: 1039993.749 units remaining) + [ {} @noop + False @and ] + - location: 14 (remaining gas: 1039993.734 units remaining) + [ (Pair {} False) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True].out new file mode 100644 index 000000000000..44ef8c1e01c8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True].out @@ -0,0 +1,24 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[and_logical_1.tz-False-(Pair True True)-True] + +storage + True +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039993.804 units remaining) + [ (Pair (Pair True True) False) ] + - location: 9 (remaining gas: 1039993.794 units remaining) + [ (Pair True True) @parameter ] + - location: 10 (remaining gas: 1039993.784 units remaining) + [ True + True ] + - location: 11 (remaining gas: 1039993.764 units remaining) + [ True @and ] + - location: 12 (remaining gas: 1039993.749 units remaining) + [ {} @noop + True @and ] + - location: 14 (remaining gas: 1039993.734 units remaining) + [ (Pair {} True) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000].out new file mode 100644 index 000000000000..142b36bb6d72 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[balance.tz-111-Unit-4000000000000] + +storage + 4000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 111) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039774.922 units remaining) + [ 4000000000000 @balance ] + - location: 9 (remaining gas: 1039774.907 units remaining) + [ {} + 4000000000000 @balance ] + - location: 11 (remaining gas: 1039774.892 units remaining) + [ (Pair {} 4000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out new file mode 100644 index 000000000000..88515501cb5a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.2292d6ce17.out @@ -0,0 +1,43 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (Some False))1] + +storage + (Pair 4 (Some False)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[0] to 1 +trace + - location: 12 (remaining gas: 1039987.011 units remaining) + [ (Pair 1 { Elt 0 1 } None) ] + - location: 12 (remaining gas: 1039987.001 units remaining) + [ 1 @parameter + (Pair { Elt 0 1 } None) @storage ] + - location: 13 (remaining gas: 1039986.986 units remaining) + [ (Pair { Elt 0 1 } None) @storage ] + - location: 15 (remaining gas: 1039986.976 units remaining) + [ { Elt 0 1 } ] + - location: 16 (remaining gas: 1039986.966 units remaining) + [ { Elt 0 1 } + { Elt 0 1 } ] + - location: 13 (remaining gas: 1039986.936 units remaining) + [ 1 @parameter + { Elt 0 1 } + { Elt 0 1 } ] + - location: 17 (remaining gas: 1039986.163 units remaining) + [ False + { Elt 0 1 } ] + - location: 18 (remaining gas: 1039986.148 units remaining) + [ (Some False) + { Elt 0 1 } ] + - location: 19 (remaining gas: 1039986.138 units remaining) + [ { Elt 0 1 } + (Some False) ] + - location: 20 (remaining gas: 1039986.123 units remaining) + [ (Pair { Elt 0 1 } (Some False)) ] + - location: 21 (remaining gas: 1039986.108 units remaining) + [ {} + (Pair { Elt 0 1 } (Some False)) ] + - location: 23 (remaining gas: 1039986.093 units remaining) + [ (Pair {} { Elt 0 1 } (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out new file mode 100644 index 000000000000..d6c58685ff01 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (S.dda583f5e9.out @@ -0,0 +1,43 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair 4 (Some False))0] + +storage + (Pair 4 (Some False)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[0] to 1 +trace + - location: 12 (remaining gas: 1039987.011 units remaining) + [ (Pair 1 { Elt 0 1 } None) ] + - location: 12 (remaining gas: 1039987.001 units remaining) + [ 1 @parameter + (Pair { Elt 0 1 } None) @storage ] + - location: 13 (remaining gas: 1039986.986 units remaining) + [ (Pair { Elt 0 1 } None) @storage ] + - location: 15 (remaining gas: 1039986.976 units remaining) + [ { Elt 0 1 } ] + - location: 16 (remaining gas: 1039986.966 units remaining) + [ { Elt 0 1 } + { Elt 0 1 } ] + - location: 13 (remaining gas: 1039986.936 units remaining) + [ 1 @parameter + { Elt 0 1 } + { Elt 0 1 } ] + - location: 17 (remaining gas: 1039986.163 units remaining) + [ False + { Elt 0 1 } ] + - location: 18 (remaining gas: 1039986.148 units remaining) + [ (Some False) + { Elt 0 1 } ] + - location: 19 (remaining gas: 1039986.138 units remaining) + [ { Elt 0 1 } + (Some False) ] + - location: 20 (remaining gas: 1039986.123 units remaining) + [ (Pair { Elt 0 1 } (Some False)) ] + - location: 21 (remaining gas: 1039986.108 units remaining) + [ {} + (Pair { Elt 0 1 } (Some False)) ] + - location: 23 (remaining gas: 1039986.093 units remaining) + [ (Pair {} { Elt 0 1 } (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out new file mode 100644 index 000000000000..7f6a339bf2ab --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.6d753598ba.out @@ -0,0 +1,43 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (Some True))1] + +storage + (Pair 4 (Some True)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[1] to 0 +trace + - location: 12 (remaining gas: 1039987.011 units remaining) + [ (Pair 1 { Elt 1 0 } None) ] + - location: 12 (remaining gas: 1039987.001 units remaining) + [ 1 @parameter + (Pair { Elt 1 0 } None) @storage ] + - location: 13 (remaining gas: 1039986.986 units remaining) + [ (Pair { Elt 1 0 } None) @storage ] + - location: 15 (remaining gas: 1039986.976 units remaining) + [ { Elt 1 0 } ] + - location: 16 (remaining gas: 1039986.966 units remaining) + [ { Elt 1 0 } + { Elt 1 0 } ] + - location: 13 (remaining gas: 1039986.936 units remaining) + [ 1 @parameter + { Elt 1 0 } + { Elt 1 0 } ] + - location: 17 (remaining gas: 1039986.163 units remaining) + [ True + { Elt 1 0 } ] + - location: 18 (remaining gas: 1039986.148 units remaining) + [ (Some True) + { Elt 1 0 } ] + - location: 19 (remaining gas: 1039986.138 units remaining) + [ { Elt 1 0 } + (Some True) ] + - location: 20 (remaining gas: 1039986.123 units remaining) + [ (Pair { Elt 1 0 } (Some True)) ] + - location: 21 (remaining gas: 1039986.108 units remaining) + [ {} + (Pair { Elt 1 0 } (Some True)) ] + - location: 23 (remaining gas: 1039986.093 units remaining) + [ (Pair {} { Elt 1 0 } (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.73700321f8.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.73700321f8.out new file mode 100644 index 000000000000..933ffdc00ed0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (S.73700321f8.out @@ -0,0 +1,43 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair 4 (Some True))0] + +storage + (Pair 4 (Some True)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[1] to 0 +trace + - location: 12 (remaining gas: 1039987.011 units remaining) + [ (Pair 1 { Elt 1 0 } None) ] + - location: 12 (remaining gas: 1039987.001 units remaining) + [ 1 @parameter + (Pair { Elt 1 0 } None) @storage ] + - location: 13 (remaining gas: 1039986.986 units remaining) + [ (Pair { Elt 1 0 } None) @storage ] + - location: 15 (remaining gas: 1039986.976 units remaining) + [ { Elt 1 0 } ] + - location: 16 (remaining gas: 1039986.966 units remaining) + [ { Elt 1 0 } + { Elt 1 0 } ] + - location: 13 (remaining gas: 1039986.936 units remaining) + [ 1 @parameter + { Elt 1 0 } + { Elt 1 0 } ] + - location: 17 (remaining gas: 1039986.163 units remaining) + [ True + { Elt 1 0 } ] + - location: 18 (remaining gas: 1039986.148 units remaining) + [ (Some True) + { Elt 1 0 } ] + - location: 19 (remaining gas: 1039986.138 units remaining) + [ { Elt 1 0 } + (Some True) ] + - location: 20 (remaining gas: 1039986.123 units remaining) + [ (Pair { Elt 1 0 } (Some True)) ] + - location: 21 (remaining gas: 1039986.108 units remaining) + [ {} + (Pair { Elt 1 0 } (Some True)) ] + - location: 23 (remaining gas: 1039986.093 units remaining) + [ (Pair {} { Elt 1 0 } (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.1182eca937.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.1182eca937.out new file mode 100644 index 000000000000..f3b3c13c182d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.1182eca937.out @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pair 4 (Some True))0] + +storage + (Pair 4 (Some True)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[1] to 4 + Set map(4)[2] to 11 +trace + - location: 12 (remaining gas: 1039985.980 units remaining) + [ (Pair 1 { Elt 1 4 ; Elt 2 11 } None) ] + - location: 12 (remaining gas: 1039985.970 units remaining) + [ 1 @parameter + (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 13 (remaining gas: 1039985.955 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 15 (remaining gas: 1039985.945 units remaining) + [ { Elt 1 4 ; Elt 2 11 } ] + - location: 16 (remaining gas: 1039985.935 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 13 (remaining gas: 1039985.905 units remaining) + [ 1 @parameter + { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 17 (remaining gas: 1039985.131 units remaining) + [ True + { Elt 1 4 ; Elt 2 11 } ] + - location: 18 (remaining gas: 1039985.116 units remaining) + [ (Some True) + { Elt 1 4 ; Elt 2 11 } ] + - location: 19 (remaining gas: 1039985.106 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + (Some True) ] + - location: 20 (remaining gas: 1039985.091 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 21 (remaining gas: 1039985.076 units remaining) + [ {} + (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 23 (remaining gas: 1039985.061 units remaining) + [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out new file mode 100644 index 000000000000..0683aadc22e2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1.2ea67af009.out @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pair 4 (Some True))1] + +storage + (Pair 4 (Some True)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[1] to 4 + Set map(4)[2] to 11 +trace + - location: 12 (remaining gas: 1039985.980 units remaining) + [ (Pair 1 { Elt 1 4 ; Elt 2 11 } None) ] + - location: 12 (remaining gas: 1039985.970 units remaining) + [ 1 @parameter + (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 13 (remaining gas: 1039985.955 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 15 (remaining gas: 1039985.945 units remaining) + [ { Elt 1 4 ; Elt 2 11 } ] + - location: 16 (remaining gas: 1039985.935 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 13 (remaining gas: 1039985.905 units remaining) + [ 1 @parameter + { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 17 (remaining gas: 1039985.131 units remaining) + [ True + { Elt 1 4 ; Elt 2 11 } ] + - location: 18 (remaining gas: 1039985.116 units remaining) + [ (Some True) + { Elt 1 4 ; Elt 2 11 } ] + - location: 19 (remaining gas: 1039985.106 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + (Some True) ] + - location: 20 (remaining gas: 1039985.091 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 21 (remaining gas: 1039985.076 units remaining) + [ {} + (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 23 (remaining gas: 1039985.061 units remaining) + [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.1eead33885.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.1eead33885.out new file mode 100644 index 000000000000..2a6aa7432bfe --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.1eead33885.out @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pair 4 (Some True))1] + +storage + (Pair 4 (Some True)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[1] to 4 + Set map(4)[2] to 11 +trace + - location: 12 (remaining gas: 1039985.980 units remaining) + [ (Pair 2 { Elt 1 4 ; Elt 2 11 } None) ] + - location: 12 (remaining gas: 1039985.970 units remaining) + [ 2 @parameter + (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 13 (remaining gas: 1039985.955 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 15 (remaining gas: 1039985.945 units remaining) + [ { Elt 1 4 ; Elt 2 11 } ] + - location: 16 (remaining gas: 1039985.935 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 13 (remaining gas: 1039985.905 units remaining) + [ 2 @parameter + { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 17 (remaining gas: 1039985.131 units remaining) + [ True + { Elt 1 4 ; Elt 2 11 } ] + - location: 18 (remaining gas: 1039985.116 units remaining) + [ (Some True) + { Elt 1 4 ; Elt 2 11 } ] + - location: 19 (remaining gas: 1039985.106 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + (Some True) ] + - location: 20 (remaining gas: 1039985.091 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 21 (remaining gas: 1039985.076 units remaining) + [ {} + (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 23 (remaining gas: 1039985.061 units remaining) + [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out new file mode 100644 index 000000000000..f35820c42463 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2.47f55c94c8.out @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pair 4 (Some True))0] + +storage + (Pair 4 (Some True)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[1] to 4 + Set map(4)[2] to 11 +trace + - location: 12 (remaining gas: 1039985.980 units remaining) + [ (Pair 2 { Elt 1 4 ; Elt 2 11 } None) ] + - location: 12 (remaining gas: 1039985.970 units remaining) + [ 2 @parameter + (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 13 (remaining gas: 1039985.955 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 15 (remaining gas: 1039985.945 units remaining) + [ { Elt 1 4 ; Elt 2 11 } ] + - location: 16 (remaining gas: 1039985.935 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 13 (remaining gas: 1039985.905 units remaining) + [ 2 @parameter + { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 17 (remaining gas: 1039985.131 units remaining) + [ True + { Elt 1 4 ; Elt 2 11 } ] + - location: 18 (remaining gas: 1039985.116 units remaining) + [ (Some True) + { Elt 1 4 ; Elt 2 11 } ] + - location: 19 (remaining gas: 1039985.106 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + (Some True) ] + - location: 20 (remaining gas: 1039985.091 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 21 (remaining gas: 1039985.076 units remaining) + [ {} + (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 23 (remaining gas: 1039985.061 units remaining) + [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out new file mode 100644 index 000000000000..40380c2f5868 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.7f1f2ab27d.out @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pair 4 (Some False))1] + +storage + (Pair 4 (Some False)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[1] to 4 + Set map(4)[2] to 11 +trace + - location: 12 (remaining gas: 1039985.980 units remaining) + [ (Pair 3 { Elt 1 4 ; Elt 2 11 } None) ] + - location: 12 (remaining gas: 1039985.970 units remaining) + [ 3 @parameter + (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 13 (remaining gas: 1039985.955 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 15 (remaining gas: 1039985.945 units remaining) + [ { Elt 1 4 ; Elt 2 11 } ] + - location: 16 (remaining gas: 1039985.935 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 13 (remaining gas: 1039985.905 units remaining) + [ 3 @parameter + { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 17 (remaining gas: 1039985.131 units remaining) + [ False + { Elt 1 4 ; Elt 2 11 } ] + - location: 18 (remaining gas: 1039985.116 units remaining) + [ (Some False) + { Elt 1 4 ; Elt 2 11 } ] + - location: 19 (remaining gas: 1039985.106 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + (Some False) ] + - location: 20 (remaining gas: 1039985.091 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] + - location: 21 (remaining gas: 1039985.076 units remaining) + [ {} + (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] + - location: 23 (remaining gas: 1039985.061 units remaining) + [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out new file mode 100644 index 000000000000..fa1acb858113 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3.a3c5c126ce.out @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pair 4 (Some False))0] + +storage + (Pair 4 (Some False)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) + Set map(4)[1] to 4 + Set map(4)[2] to 11 +trace + - location: 12 (remaining gas: 1039985.980 units remaining) + [ (Pair 3 { Elt 1 4 ; Elt 2 11 } None) ] + - location: 12 (remaining gas: 1039985.970 units remaining) + [ 3 @parameter + (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 13 (remaining gas: 1039985.955 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 15 (remaining gas: 1039985.945 units remaining) + [ { Elt 1 4 ; Elt 2 11 } ] + - location: 16 (remaining gas: 1039985.935 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 13 (remaining gas: 1039985.905 units remaining) + [ 3 @parameter + { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 17 (remaining gas: 1039985.131 units remaining) + [ False + { Elt 1 4 ; Elt 2 11 } ] + - location: 18 (remaining gas: 1039985.116 units remaining) + [ (Some False) + { Elt 1 4 ; Elt 2 11 } ] + - location: 19 (remaining gas: 1039985.106 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + (Some False) ] + - location: 20 (remaining gas: 1039985.091 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] + - location: 21 (remaining gas: 1039985.076 units remaining) + [ {} + (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] + - location: 23 (remaining gas: 1039985.061 units remaining) + [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0].out new file mode 100644 index 000000000000..a695dad77649 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0].out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))0] + +storage + (Pair 4 (Some False)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) +trace + - location: 12 (remaining gas: 1039988.004 units remaining) + [ (Pair 1 {} None) ] + - location: 12 (remaining gas: 1039987.994 units remaining) + [ 1 @parameter + (Pair {} None) @storage ] + - location: 13 (remaining gas: 1039987.979 units remaining) + [ (Pair {} None) @storage ] + - location: 15 (remaining gas: 1039987.969 units remaining) + [ {} ] + - location: 16 (remaining gas: 1039987.959 units remaining) + [ {} + {} ] + - location: 13 (remaining gas: 1039987.929 units remaining) + [ 1 @parameter + {} + {} ] + - location: 17 (remaining gas: 1039987.158 units remaining) + [ False + {} ] + - location: 18 (remaining gas: 1039987.143 units remaining) + [ (Some False) + {} ] + - location: 19 (remaining gas: 1039987.133 units remaining) + [ {} + (Some False) ] + - location: 20 (remaining gas: 1039987.118 units remaining) + [ (Pair {} (Some False)) ] + - location: 21 (remaining gas: 1039987.103 units remaining) + [ {} + (Pair {} (Some False)) ] + - location: 23 (remaining gas: 1039987.088 units remaining) + [ (Pair {} {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1].out new file mode 100644 index 000000000000..ecbd7447efd2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1].out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_nat.tz-(Pair {} None)-1-(Pair 4 (Some False))1] + +storage + (Pair 4 (Some False)) +emitted operations + +big_map diff + New map(4) of type (big_map nat nat) +trace + - location: 12 (remaining gas: 1039988.004 units remaining) + [ (Pair 1 {} None) ] + - location: 12 (remaining gas: 1039987.994 units remaining) + [ 1 @parameter + (Pair {} None) @storage ] + - location: 13 (remaining gas: 1039987.979 units remaining) + [ (Pair {} None) @storage ] + - location: 15 (remaining gas: 1039987.969 units remaining) + [ {} ] + - location: 16 (remaining gas: 1039987.959 units remaining) + [ {} + {} ] + - location: 13 (remaining gas: 1039987.929 units remaining) + [ 1 @parameter + {} + {} ] + - location: 17 (remaining gas: 1039987.158 units remaining) + [ False + {} ] + - location: 18 (remaining gas: 1039987.143 units remaining) + [ (Some False) + {} ] + - location: 19 (remaining gas: 1039987.133 units remaining) + [ {} + (Some False) ] + - location: 20 (remaining gas: 1039987.118 units remaining) + [ (Pair {} (Some False)) ] + - location: 21 (remaining gas: 1039987.103 units remaining) + [ {} + (Pair {} (Some False)) ] + - location: 23 (remaining gas: 1039987.088 units remaining) + [ (Pair {} {} (Some False)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" new file mode 100644 index 000000000000..48a1663e2d42 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.4be99ce05d.out" @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"baz"-(Pair 4 (Some False))] + +storage + (Pair 4 (Some False)) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["bar"] to 4 + Set map(4)["foo"] to 11 +trace + - location: 12 (remaining gas: 1039985.438 units remaining) + [ (Pair "baz" { Elt "bar" 4 ; Elt "foo" 11 } None) ] + - location: 12 (remaining gas: 1039985.428 units remaining) + [ "baz" @parameter + (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 13 (remaining gas: 1039985.413 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 15 (remaining gas: 1039985.403 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 16 (remaining gas: 1039985.393 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 13 (remaining gas: 1039985.363 units remaining) + [ "baz" @parameter + { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 17 (remaining gas: 1039984.384 units remaining) + [ False + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 18 (remaining gas: 1039984.369 units remaining) + [ (Some False) + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 19 (remaining gas: 1039984.359 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + (Some False) ] + - location: 20 (remaining gas: 1039984.344 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] + - location: 21 (remaining gas: 1039984.329 units remaining) + [ {} + (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] + - location: 23 (remaining gas: 1039984.314 units remaining) + [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" new file mode 100644 index 000000000000..296dc0dd5dfa --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.50c0e0ff8b.out" @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"foo"-(Pair 4 (Some True))] + +storage + (Pair 4 (Some True)) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["bar"] to 4 + Set map(4)["foo"] to 11 +trace + - location: 12 (remaining gas: 1039985.438 units remaining) + [ (Pair "foo" { Elt "bar" 4 ; Elt "foo" 11 } None) ] + - location: 12 (remaining gas: 1039985.428 units remaining) + [ "foo" @parameter + (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 13 (remaining gas: 1039985.413 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 15 (remaining gas: 1039985.403 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 16 (remaining gas: 1039985.393 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 13 (remaining gas: 1039985.363 units remaining) + [ "foo" @parameter + { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 17 (remaining gas: 1039984.384 units remaining) + [ True + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 18 (remaining gas: 1039984.369 units remaining) + [ (Some True) + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 19 (remaining gas: 1039984.359 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + (Some True) ] + - location: 20 (remaining gas: 1039984.344 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + - location: 21 (remaining gas: 1039984.329 units remaining) + [ {} + (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + - location: 23 (remaining gas: 1039984.314 units remaining) + [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" new file mode 100644 index 000000000000..837191329436 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 1.775c22b027.out" @@ -0,0 +1,44 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"bar"-(Pair 4 (Some True))] + +storage + (Pair 4 (Some True)) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["bar"] to 4 + Set map(4)["foo"] to 11 +trace + - location: 12 (remaining gas: 1039985.438 units remaining) + [ (Pair "bar" { Elt "bar" 4 ; Elt "foo" 11 } None) ] + - location: 12 (remaining gas: 1039985.428 units remaining) + [ "bar" @parameter + (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 13 (remaining gas: 1039985.413 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 15 (remaining gas: 1039985.403 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 16 (remaining gas: 1039985.393 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 13 (remaining gas: 1039985.363 units remaining) + [ "bar" @parameter + { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 17 (remaining gas: 1039984.384 units remaining) + [ True + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 18 (remaining gas: 1039984.369 units remaining) + [ (Some True) + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 19 (remaining gas: 1039984.359 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + (Some True) ] + - location: 20 (remaining gas: 1039984.344 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + - location: 21 (remaining gas: 1039984.329 units remaining) + [ {} + (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + - location: 23 (remaining gas: 1039984.314 units remaining) + [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\".968709d39d.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\".968709d39d.out" new file mode 100644 index 000000000000..16b5c6272bde --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\".968709d39d.out" @@ -0,0 +1,43 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "foo" 0 } None)-"foo"-(Pair 4 (Some True))] + +storage + (Pair 4 (Some True)) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["foo"] to 0 +trace + - location: 12 (remaining gas: 1039986.718 units remaining) + [ (Pair "foo" { Elt "foo" 0 } None) ] + - location: 12 (remaining gas: 1039986.708 units remaining) + [ "foo" @parameter + (Pair { Elt "foo" 0 } None) @storage ] + - location: 13 (remaining gas: 1039986.693 units remaining) + [ (Pair { Elt "foo" 0 } None) @storage ] + - location: 15 (remaining gas: 1039986.683 units remaining) + [ { Elt "foo" 0 } ] + - location: 16 (remaining gas: 1039986.673 units remaining) + [ { Elt "foo" 0 } + { Elt "foo" 0 } ] + - location: 13 (remaining gas: 1039986.643 units remaining) + [ "foo" @parameter + { Elt "foo" 0 } + { Elt "foo" 0 } ] + - location: 17 (remaining gas: 1039985.665 units remaining) + [ True + { Elt "foo" 0 } ] + - location: 18 (remaining gas: 1039985.650 units remaining) + [ (Some True) + { Elt "foo" 0 } ] + - location: 19 (remaining gas: 1039985.640 units remaining) + [ { Elt "foo" 0 } + (Some True) ] + - location: 20 (remaining gas: 1039985.625 units remaining) + [ (Pair { Elt "foo" 0 } (Some True)) ] + - location: 21 (remaining gas: 1039985.610 units remaining) + [ {} + (Pair { Elt "foo" 0 } (Some True)) ] + - location: 23 (remaining gas: 1039985.595 units remaining) + [ (Pair {} { Elt "foo" 0 } (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" new file mode 100644 index 000000000000..666895ebf6cb --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\".cdcfaf9d09.out" @@ -0,0 +1,43 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair { Elt "foo" 1 } None)-"bar"-(Pair 4 (Some False))] + +storage + (Pair 4 (Some False)) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) + Set map(4)["foo"] to 1 +trace + - location: 12 (remaining gas: 1039986.718 units remaining) + [ (Pair "bar" { Elt "foo" 1 } None) ] + - location: 12 (remaining gas: 1039986.708 units remaining) + [ "bar" @parameter + (Pair { Elt "foo" 1 } None) @storage ] + - location: 13 (remaining gas: 1039986.693 units remaining) + [ (Pair { Elt "foo" 1 } None) @storage ] + - location: 15 (remaining gas: 1039986.683 units remaining) + [ { Elt "foo" 1 } ] + - location: 16 (remaining gas: 1039986.673 units remaining) + [ { Elt "foo" 1 } + { Elt "foo" 1 } ] + - location: 13 (remaining gas: 1039986.643 units remaining) + [ "bar" @parameter + { Elt "foo" 1 } + { Elt "foo" 1 } ] + - location: 17 (remaining gas: 1039985.665 units remaining) + [ False + { Elt "foo" 1 } ] + - location: 18 (remaining gas: 1039985.650 units remaining) + [ (Some False) + { Elt "foo" 1 } ] + - location: 19 (remaining gas: 1039985.640 units remaining) + [ { Elt "foo" 1 } + (Some False) ] + - location: 20 (remaining gas: 1039985.625 units remaining) + [ (Pair { Elt "foo" 1 } (Some False)) ] + - location: 21 (remaining gas: 1039985.610 units remaining) + [ {} + (Pair { Elt "foo" 1 } (Some False)) ] + - location: 23 (remaining gas: 1039985.595 units remaining) + [ (Pair {} { Elt "foo" 1 } (Some False)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair 4 (Some False))].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair 4 (Some False))].out" new file mode 100644 index 000000000000..11325b8157a5 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair 4 (Some False))].out" @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[big_map_mem_string.tz-(Pair {} None)-"bar"-(Pair 4 (Some False))] + +storage + (Pair 4 (Some False)) +emitted operations + +big_map diff + New map(4) of type (big_map string nat) +trace + - location: 12 (remaining gas: 1039987.960 units remaining) + [ (Pair "bar" {} None) ] + - location: 12 (remaining gas: 1039987.950 units remaining) + [ "bar" @parameter + (Pair {} None) @storage ] + - location: 13 (remaining gas: 1039987.935 units remaining) + [ (Pair {} None) @storage ] + - location: 15 (remaining gas: 1039987.925 units remaining) + [ {} ] + - location: 16 (remaining gas: 1039987.915 units remaining) + [ {} + {} ] + - location: 13 (remaining gas: 1039987.885 units remaining) + [ "bar" @parameter + {} + {} ] + - location: 17 (remaining gas: 1039986.909 units remaining) + [ False + {} ] + - location: 18 (remaining gas: 1039986.894 units remaining) + [ (Some False) + {} ] + - location: 19 (remaining gas: 1039986.884 units remaining) + [ {} + (Some False) ] + - location: 20 (remaining gas: 1039986.869 units remaining) + [ (Pair {} (Some False)) ] + - location: 21 (remaining gas: 1039986.854 units remaining) + [ {} + (Pair {} (Some False)) ] + - location: 23 (remaining gas: 1039986.839 units remaining) + [ (Pair {} {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out new file mode 100644 index 000000000000..2b352118d848 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0.9b6e8bcbd3.out @@ -0,0 +1,24 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_bytes_not_padded.tz-None-Unit-(Some 0x0000000000000000000000000000000000000000000000000000000000000000)] + +storage + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.391 units remaining) + [ (Pair Unit None) ] + - location: 8 (remaining gas: 1039993.381 units remaining) + [ ] + - location: 9 (remaining gas: 1039993.371 units remaining) + [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.356 units remaining) + [ (Some 0x0000000000000000000000000000000000000000000000000000000000000000) ] + - location: 13 (remaining gas: 1039993.341 units remaining) + [ {} + (Some 0x0000000000000000000000000000000000000000000000000000000000000000) ] + - location: 15 (remaining gas: 1039993.326 units remaining) + [ (Pair {} + (Some 0x0000000000000000000000000000000000000000000000000000000000000000)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x100000000000.d1219ca789.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x100000000000.d1219ca789.out new file mode 100644 index 000000000000..a8ca19bc798f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x100000000000.d1219ca789.out @@ -0,0 +1,24 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_push_nat.tz-None-Unit-(Some 0x1000000000000000000000000000000000000000000000000000000000000000)] + +storage + (Some 0x1000000000000000000000000000000000000000000000000000000000000000) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.391 units remaining) + [ (Pair Unit None) ] + - location: 8 (remaining gas: 1039993.381 units remaining) + [ ] + - location: 9 (remaining gas: 1039993.371 units remaining) + [ 0x1000000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.356 units remaining) + [ (Some 0x1000000000000000000000000000000000000000000000000000000000000000) ] + - location: 13 (remaining gas: 1039993.341 units remaining) + [ {} + (Some 0x1000000000000000000000000000000000000000000000000000000000000000) ] + - location: 15 (remaining gas: 1039993.326 units remaining) + [ (Pair {} + (Some 0x1000000000000000000000000000000000000000000000000000000000000000)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0].out new file mode 100644 index 000000000000..6dd195dda91a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x00-0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 0x0000000000000000000000000000000000000000000000000000000000000000 0) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 0x0000000000000000000000000000000000000000000000000000000000000000 @parameter ] + - location: 8 (remaining gas: 1039994.663 units remaining) + [ 0 ] + - location: 9 (remaining gas: 1039994.648 units remaining) + [ {} + 0 ] + - location: 11 (remaining gas: 1039994.633 units remaining) + [ (Pair {} 0) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1].out new file mode 100644 index 000000000000..2b3f3acda3ce --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x01-1] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 0x0100000000000000000000000000000000000000000000000000000000000000 0) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @parameter ] + - location: 8 (remaining gas: 1039994.663 units remaining) + [ 1 ] + - location: 9 (remaining gas: 1039994.648 units remaining) + [ {} + 1 ] + - location: 11 (remaining gas: 1039994.633 units remaining) + [ (Pair {} 1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f2.7a85c336ff.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f2.7a85c336ff.out new file mode 100644 index 000000000000..391d2f43b235 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f2.7a85c336ff.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0x28db8e57af88d9576acd181b89f24e50a89a6423f939026ed91349fc9af16c27-17832688077013577776524784494464728518213913213412866604053735695200962927400] + +storage + 17832688077013577776524784494464728518213913213412866604053735695200962927400 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 0x28db8e57af88d9576acd181b89f24e50a89a6423f939026ed91349fc9af16c27 0) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 0x28db8e57af88d9576acd181b89f24e50a89a6423f939026ed91349fc9af16c27 @parameter ] + - location: 8 (remaining gas: 1039994.663 units remaining) + [ 17832688077013577776524784494464728518213913213412866604053735695200962927400 ] + - location: 9 (remaining gas: 1039994.648 units remaining) + [ {} + 17832688077013577776524784494464728518213913213412866604053735695200962927400 ] + - location: 11 (remaining gas: 1039994.633 units remaining) + [ (Pair {} + 17832688077013577776524784494464728518213913213412866604053735695200962927400) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986.b821eb26b3.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986.b821eb26b3.out new file mode 100644 index 000000000000..d50cfbd38689 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986.b821eb26b3.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_int.tz-0-0xb9e8abf8dc324a010007addde986fe0f7c81fab16d26819d0534b7691c0b0719-11320265829256585830781521966149529460476767408210445238902869222031333517497] + +storage + 11320265829256585830781521966149529460476767408210445238902869222031333517497 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 0xb9e8abf8dc324a010007addde986fe0f7c81fab16d26819d0534b7691c0b0719 0) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 0xb9e8abf8dc324a010007addde986fe0f7c81fab16d26819d0534b7691c0b0719 @parameter ] + - location: 8 (remaining gas: 1039994.663 units remaining) + [ 11320265829256585830781521966149529460476767408210445238902869222031333517497 ] + - location: 9 (remaining gas: 1039994.648 units remaining) + [ {} + 11320265829256585830781521966149529460476767408210445238902869222031333517497 ] + - location: 11 (remaining gas: 1039994.633 units remaining) + [ (Pair {} + 11320265829256585830781521966149529460476767408210445238902869222031333517497) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16].out new file mode 100644 index 000000000000..bc9501dfd03c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_to_mutez.tz-0-0x10-16] + +storage + 16 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039989.509 units remaining) + [ (Pair 0x1000000000000000000000000000000000000000000000000000000000000000 0) ] + - location: 7 (remaining gas: 1039989.499 units remaining) + [ 0x1000000000000000000000000000000000000000000000000000000000000000 @parameter ] + - location: 8 (remaining gas: 1039989.374 units remaining) + [ 16 ] + - location: 9 (remaining gas: 1039989.359 units remaining) + [ (Some 16) ] + - location: 11 (remaining gas: 1039989.349 units remaining) + [ 16 @some ] + - location: 11 (remaining gas: 1039989.334 units remaining) + [ 16 @some ] + - location: 17 (remaining gas: 1039989.324 units remaining) + [ 1 + 16 @some ] + - location: 20 (remaining gas: 1039989.324 units remaining) + [ 16 ] + - location: 21 (remaining gas: 1039989.309 units remaining) + [ {} + 16 ] + - location: 23 (remaining gas: 1039989.294 units remaining) + [ (Pair {} 16) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0accef5bef.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0accef5bef.out new file mode 100644 index 000000000000..7dbb232f0b7b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0accef5bef.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000--42-0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73] + +storage + 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair -42 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ -42 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.457 units remaining) + [ 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] + - location: 9 (remaining gas: 1039994.442 units remaining) + [ {} + 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] + - location: 11 (remaining gas: 1039994.427 units remaining) + [ (Pair {} 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0ecc537252.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0ecc537252.out new file mode 100644 index 000000000000..c34b6ee49065 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.0ecc537252.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-2-0x0200000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0200000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 2 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 2 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.457 units remaining) + [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] + - location: 9 (remaining gas: 1039994.442 units remaining) + [ {} + 0x0200000000000000000000000000000000000000000000000000000000000000 ] + - location: 11 (remaining gas: 1039994.427 units remaining) + [ (Pair {} 0x0200000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2229b767cd.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2229b767cd.out new file mode 100644 index 000000000000..97f716102e0c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2229b767cd.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000--1-0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73] + +storage + 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair -1 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ -1 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.457 units remaining) + [ 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] + - location: 9 (remaining gas: 1039994.442 units remaining) + [ {} + 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] + - location: 11 (remaining gas: 1039994.427 units remaining) + [ (Pair {} 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2ff549b46b.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2ff549b46b.out new file mode 100644 index 000000000000..61ac661c8b5e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.2ff549b46b.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-0-0x0000000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0000000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 0 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 0 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.458 units remaining) + [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 9 (remaining gas: 1039994.443 units remaining) + [ {} + 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 11 (remaining gas: 1039994.428 units remaining) + [ (Pair {} 0x0000000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.bf8a711be6.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.bf8a711be6.out new file mode 100644 index 000000000000..9581090d026b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.bf8a711be6.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-52435875175126190479447740508185965837690552500527637822603658699938581184514-0x0100000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0100000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 52435875175126190479447740508185965837690552500527637822603658699938581184514 + 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.d41cbb044b.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.d41cbb044b.out new file mode 100644 index 000000000000..3dec992e4be9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000.d41cbb044b.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-1-0x0100000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0100000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 1 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 1 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.457 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 9 (remaining gas: 1039994.442 units remaining) + [ {} + 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 11 (remaining gas: 1039994.427 units remaining) + [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.a50412e458.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.a50412e458.out new file mode 100644 index 000000000000..f40696bb9248 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.a50412e458.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f-22620284817922784902564672469917992996328211127984472897491698543785655336309-0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62] + +storage + 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 22620284817922784902564672469917992996328211127984472897491698543785655336309 + 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter + 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.f3a349c4a7.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.f3a349c4a7.out new file mode 100644 index 000000000000..cc884b83d6b3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.f3a349c4a7.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f-33644916630334844239120348434626468649534186770809802792596996408934105684394-0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221] + +storage + 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 33644916630334844239120348434626468649534186770809802792596996408934105684394 + 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter + 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.1b9676e4c2.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.1b9676e4c2.out new file mode 100644 index 000000000000..468e2cd19554 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.1b9676e4c2.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-69615968247920749285624776342583898043608129789011377475114141186797415307882-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] + +storage + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 69615968247920749285624776342583898043608129789011377475114141186797415307882 + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.e966dc6de5.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.e966dc6de5.out new file mode 100644 index 000000000000..78dc893e86b1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03.e966dc6de5.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_int.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-17180093072794558806177035834397932205917577288483739652510482486858834123369-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] + +storage + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 17180093072794558806177035834397932205917577288483739652510482486858834123369 + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.964835cc43.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.964835cc43.out new file mode 100644 index 000000000000..b3cbf75babc6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.964835cc43.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-1-0x0100000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0100000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 1 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 1 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.457 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 9 (remaining gas: 1039994.442 units remaining) + [ {} + 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 11 (remaining gas: 1039994.427 units remaining) + [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.b25ea709fb.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.b25ea709fb.out new file mode 100644 index 000000000000..6ea8cef6c256 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.b25ea709fb.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-0-0x0000000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0000000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 0 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 0 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.458 units remaining) + [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 9 (remaining gas: 1039994.443 units remaining) + [ {} + 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 11 (remaining gas: 1039994.428 units remaining) + [ (Pair {} 0x0000000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.eae36753ea.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.eae36753ea.out new file mode 100644 index 000000000000..4df7e8f123b7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.eae36753ea.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-52435875175126190479447740508185965837690552500527637822603658699938581184514-0x0100000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0100000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 52435875175126190479447740508185965837690552500527637822603658699938581184514 + 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.ee57dac8f7.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.ee57dac8f7.out new file mode 100644 index 000000000000..fd88d683b058 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000.ee57dac8f7.out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-2-0x0200000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0200000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 2 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 2 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.457 units remaining) + [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] + - location: 9 (remaining gas: 1039994.442 units remaining) + [ {} + 0x0200000000000000000000000000000000000000000000000000000000000000 ] + - location: 11 (remaining gas: 1039994.427 units remaining) + [ (Pair {} 0x0200000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out new file mode 100644 index 000000000000..bf1b847aa4ec --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.928f6d4b93.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f-22620284817922784902564672469917992996328211127984472897491698543785655336309-0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62] + +storage + 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 22620284817922784902564672469917992996328211127984472897491698543785655336309 + 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter + 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.bd5800f6b8.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.bd5800f6b8.out new file mode 100644 index 000000000000..f388e993fba4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.bd5800f6b8.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f-33644916630334844239120348434626468649534186770809802792596996408934105684394-0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221] + +storage + 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 33644916630334844239120348434626468649534186770809802792596996408934105684394 + 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter + 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.00e897789a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.00e897789a.out new file mode 100644 index 000000000000..fc558998e551 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.00e897789a.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-17180093072794558806177035834397932205917577288483739652510482486858834123369-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] + +storage + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 17180093072794558806177035834397932205917577288483739652510482486858834123369 + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.a4697eaa13.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.a4697eaa13.out new file mode 100644 index 000000000000..eb22e253da18 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03.a4697eaa13.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_fr_z_nat.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-69615968247920749285624776342583898043608129789011377475114141186797415307882-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] + +storage + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.798 units remaining) + [ (Pair 69615968247920749285624776342583898043608129789011377475114141186797415307882 + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] + - location: 7 (remaining gas: 1039994.788 units remaining) + [ 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] + - location: 8 (remaining gas: 1039994.424 units remaining) + [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 9 (remaining gas: 1039994.409 units remaining) + [ {} + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 11 (remaining gas: 1039994.394 units remaining) + [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.0177355bbf.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.0177355bbf.out new file mode 100644 index 000000000000..0e28c015a739 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.0177355bbf.out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-2-0x0200000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0200000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 2 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 2 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + 2 @parameter ] + - location: 9 (remaining gas: 1039993.849 units remaining) + [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] + - location: 10 (remaining gas: 1039993.834 units remaining) + [ {} + 0x0200000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.819 units remaining) + [ (Pair {} 0x0200000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.744166c609.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.744166c609.out new file mode 100644 index 000000000000..233aff5a652f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.744166c609.out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000--1-0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73] + +storage + 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair -1 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ -1 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + -1 @parameter ] + - location: 9 (remaining gas: 1039993.849 units remaining) + [ 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] + - location: 10 (remaining gas: 1039993.834 units remaining) + [ {} + 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] + - location: 12 (remaining gas: 1039993.819 units remaining) + [ (Pair {} 0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.9f3c5cdc6a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.9f3c5cdc6a.out new file mode 100644 index 000000000000..a1ea71b4bfd9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.9f3c5cdc6a.out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-0-0x0000000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0000000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 0 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 0 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + 0 @parameter ] + - location: 9 (remaining gas: 1039993.850 units remaining) + [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 10 (remaining gas: 1039993.835 units remaining) + [ {} + 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.820 units remaining) + [ (Pair {} 0x0000000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.a54cb341ba.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.a54cb341ba.out new file mode 100644 index 000000000000..5e1bbb009218 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.a54cb341ba.out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000--42-0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73] + +storage + 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair -42 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ -42 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + -42 @parameter ] + - location: 9 (remaining gas: 1039993.849 units remaining) + [ 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] + - location: 10 (remaining gas: 1039993.834 units remaining) + [ {} + 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73 ] + - location: 12 (remaining gas: 1039993.819 units remaining) + [ (Pair {} 0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.b0dc584c94.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.b0dc584c94.out new file mode 100644 index 000000000000..00c2b789aa17 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.b0dc584c94.out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-1-0x0100000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0100000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 1 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 1 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + 1 @parameter ] + - location: 9 (remaining gas: 1039993.849 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 10 (remaining gas: 1039993.834 units remaining) + [ {} + 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.819 units remaining) + [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.bddcad090c.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.bddcad090c.out new file mode 100644 index 000000000000..8cb48f693eae --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000.bddcad090c.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x0100000000000000000000000000000000000000000000000000000000000000-52435875175126190479447740508185965837690552500527637822603658699938581184514-0x0100000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0100000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 52435875175126190479447740508185965837690552500527637822603658699938581184514 + 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.92c153eb47.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.92c153eb47.out new file mode 100644 index 000000000000..aacb2fffc956 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c1.92c153eb47.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f-22620284817922784902564672469917992996328211127984472897491698543785655336309-0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62] + +storage + 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 22620284817922784902564672469917992996328211127984472897491698543785655336309 + 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter + 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage + 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.290ab49d11.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.290ab49d11.out new file mode 100644 index 000000000000..b7bdcaa334bb --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80.290ab49d11.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f-33644916630334844239120348434626468649534186770809802792596996408934105684394-0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221] + +storage + 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 33644916630334844239120348434626468649534186770809802792596996408934105684394 + 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter + 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage + 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.69f3589a06.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.69f3589a06.out new file mode 100644 index 000000000000..378c083f107f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.69f3589a06.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-17180093072794558806177035834397932205917577288483739652510482486858834123369-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] + +storage + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 17180093072794558806177035834397932205917577288483739652510482486858834123369 + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage + 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.fee3c5cf43.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.fee3c5cf43.out new file mode 100644 index 000000000000..14dfca40e3ac --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03.fee3c5cf43.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_int.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-69615968247920749285624776342583898043608129789011377475114141186797415307882-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] + +storage + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 69615968247920749285624776342583898043608129789011377475114141186797415307882 + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage + 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.1bccc033e8.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.1bccc033e8.out new file mode 100644 index 000000000000..e5c31af94bb7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.1bccc033e8.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-52435875175126190479447740508185965837690552500527637822603658699938581184514-0x0100000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0100000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 52435875175126190479447740508185965837690552500527637822603658699938581184514 + 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + 52435875175126190479447740508185965837690552500527637822603658699938581184514 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.40958700fe.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.40958700fe.out new file mode 100644 index 000000000000..4f0b31b80a76 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.40958700fe.out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-0-0x0000000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0000000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 0 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 0 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + 0 @parameter ] + - location: 9 (remaining gas: 1039993.850 units remaining) + [ 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 10 (remaining gas: 1039993.835 units remaining) + [ {} + 0x0000000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.820 units remaining) + [ (Pair {} 0x0000000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.6c62b03d78.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.6c62b03d78.out new file mode 100644 index 000000000000..82e22e036221 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.6c62b03d78.out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-1-0x0100000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0100000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 1 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 1 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + 1 @parameter ] + - location: 9 (remaining gas: 1039993.849 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 10 (remaining gas: 1039993.834 units remaining) + [ {} + 0x0100000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.819 units remaining) + [ (Pair {} 0x0100000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.d23f269341.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.d23f269341.out new file mode 100644 index 000000000000..044d347cc2f2 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000.d23f269341.out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x0100000000000000000000000000000000000000000000000000000000000000-2-0x0200000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0200000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 2 0x0100000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 2 @parameter + 0x0100000000000000000000000000000000000000000000000000000000000000 @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 @storage + 2 @parameter ] + - location: 9 (remaining gas: 1039993.849 units remaining) + [ 0x0200000000000000000000000000000000000000000000000000000000000000 ] + - location: 10 (remaining gas: 1039993.834 units remaining) + [ {} + 0x0200000000000000000000000000000000000000000000000000000000000000 ] + - location: 12 (remaining gas: 1039993.819 units remaining) + [ (Pair {} 0x0200000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.927f808504.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.927f808504.out new file mode 100644 index 000000000000..32d293214e82 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c1.927f808504.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f-22620284817922784902564672469917992996328211127984472897491698543785655336309-0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62] + +storage + 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 22620284817922784902564672469917992996328211127984472897491698543785655336309 + 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter + 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfcdbe3f @storage + 22620284817922784902564672469917992996328211127984472897491698543785655336309 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe677c62) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.0c114c956a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.0c114c956a.out new file mode 100644 index 000000000000..f97d6bac4814 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80.0c114c956a.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f-33644916630334844239120348434626468649534186770809802792596996408934105684394-0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221] + +storage + 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 33644916630334844239120348434626468649534186770809802792596996408934105684394 + 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter + 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c5401f @storage + 33644916630334844239120348434626468649534186770809802792596996408934105684394 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca918a221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.03c4f38e68.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.03c4f38e68.out new file mode 100644 index 000000000000..254103eb4f7f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.03c4f38e68.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-69615968247920749285624776342583898043608129789011377475114141186797415307882-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] + +storage + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 69615968247920749285624776342583898043608129789011377475114141186797415307882 + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage + 69615968247920749285624776342583898043608129789011377475114141186797415307882 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.8ed19cfdd9.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.8ed19cfdd9.out new file mode 100644 index 000000000000..92beeb5bdce0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03.8ed19cfdd9.out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[bls12_381_z_fr_nat.tz-0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d-17180093072794558806177035834397932205917577288483739652510482486858834123369-0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221] + +storage + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.200 units remaining) + [ (Pair 17180093072794558806177035834397932205917577288483739652510482486858834123369 + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d) ] + - location: 7 (remaining gas: 1039994.190 units remaining) + [ 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter + 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage ] + - location: 8 (remaining gas: 1039994.180 units remaining) + [ 0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7fcf2d @storage + 17180093072794558806177035834397932205917577288483739652510482486858834123369 @parameter ] + - location: 9 (remaining gas: 1039993.816 units remaining) + [ 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 10 (remaining gas: 1039993.801 units remaining) + [ {} + 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221 ] + - location: 12 (remaining gas: 1039993.786 units remaining) + [ (Pair {} 0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddecbf221) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34].out new file mode 100644 index 000000000000..6a58103fccae --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[car.tz-0-(Pair 34 17)-34] + +storage + 34 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039994.492 units remaining) + [ (Pair (Pair 34 17) 0) ] + - location: 9 (remaining gas: 1039994.482 units remaining) + [ (Pair 34 17) @parameter ] + - location: 10 (remaining gas: 1039994.472 units remaining) + [ 34 ] + - location: 11 (remaining gas: 1039994.457 units remaining) + [ {} + 34 ] + - location: 13 (remaining gas: 1039994.442 units remaining) + [ (Pair {} 34) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17].out new file mode 100644 index 000000000000..a2b6390e0b1e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[cdr.tz-0-(Pair 34 17)-17] + +storage + 17 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039994.492 units remaining) + [ (Pair (Pair 34 17) 0) ] + - location: 9 (remaining gas: 1039994.482 units remaining) + [ (Pair 34 17) @parameter ] + - location: 10 (remaining gas: 1039994.472 units remaining) + [ 17 ] + - location: 11 (remaining gas: 1039994.457 units remaining) + [ {} + 17 ] + - location: 13 (remaining gas: 1039994.442 units remaining) + [ (Pair {} 17) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some \"NetXdQprcVkpaWU\")-Unit-(Some \".8420090f97.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some \"NetXdQprcVkpaWU\")-Unit-(Some \".8420090f97.out" new file mode 100644 index 000000000000..45bab2656a8e --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some \"NetXdQprcVkpaWU\")-Unit-(Some \".8420090f97.out" @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some "NetXdQprcVkpaWU")-Unit-(Some "NetXdQprcVkpaWU")] + +storage + (Some "NetXdQprcVkpaWU") +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039992.257 units remaining) + [ (Pair Unit (Some "NetXdQprcVkpaWU")) ] + - location: 8 (remaining gas: 1039992.247 units remaining) + [ ] + - location: 9 (remaining gas: 1039992.232 units remaining) + [ "NetXdQprcVkpaWU" ] + - location: 10 (remaining gas: 1039992.217 units remaining) + [ (Some "NetXdQprcVkpaWU") ] + - location: 11 (remaining gas: 1039992.202 units remaining) + [ {} + (Some "NetXdQprcVkpaWU") ] + - location: 13 (remaining gas: 1039992.187 units remaining) + [ (Pair {} (Some "NetXdQprcVkpaWU")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" new file mode 100644 index 000000000000..b00b052d004f --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some \"NetXdQprcVkpaWU\")].out" @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[chain_id_store.tz-(Some 0x7a06a770)-Unit-(Some "NetXdQprcVkpaWU")] + +storage + (Some "NetXdQprcVkpaWU") +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.807 units remaining) + [ (Pair Unit (Some "NetXdQprcVkpaWU")) ] + - location: 8 (remaining gas: 1039993.797 units remaining) + [ ] + - location: 9 (remaining gas: 1039993.782 units remaining) + [ "NetXdQprcVkpaWU" ] + - location: 10 (remaining gas: 1039993.767 units remaining) + [ (Some "NetXdQprcVkpaWU") ] + - location: 11 (remaining gas: 1039993.752 units remaining) + [ {} + (Some "NetXdQprcVkpaWU") ] + - location: 13 (remaining gas: 1039993.737 units remaining) + [ (Pair {} (Some "NetXdQprcVkpaWU")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some \"NetXdQprcVkpaWU\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some \"NetXdQprcVkpaWU\")].out" new file mode 100644 index 000000000000..cbff5cef3b8b --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some \"NetXdQprcVkpaWU\")].out" @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[chain_id_store.tz-None-Unit-(Some "NetXdQprcVkpaWU")] + +storage + (Some "NetXdQprcVkpaWU") +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.957 units remaining) + [ (Pair Unit None) ] + - location: 8 (remaining gas: 1039993.947 units remaining) + [ ] + - location: 9 (remaining gas: 1039993.932 units remaining) + [ "NetXdQprcVkpaWU" ] + - location: 10 (remaining gas: 1039993.917 units remaining) + [ (Some "NetXdQprcVkpaWU") ] + - location: 11 (remaining gas: 1039993.902 units remaining) + [ {} + (Some "NetXdQprcVkpaWU") ] + - location: 13 (remaining gas: 1039993.887 units remaining) + [ (Pair {} (Some "NetXdQprcVkpaWU")) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out new file mode 100644 index 000000000000..f39b23d0a041 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit].out @@ -0,0 +1,123 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comb-get.tz-Unit-(Pair 1 4 2 Unit)-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039950.642 units remaining) + [ (Pair (Pair 1 4 2 Unit) Unit) ] + - location: 11 (remaining gas: 1039950.632 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 12 (remaining gas: 1039950.622 units remaining) + [ (Pair 1 4 2 Unit) @parameter + (Pair 1 4 2 Unit) @parameter ] + - location: 13 (remaining gas: 1039950.612 units remaining) + [ 1 + (Pair 1 4 2 Unit) @parameter ] + - location: 14 (remaining gas: 1039950.602 units remaining) + [ 1 + 1 + (Pair 1 4 2 Unit) @parameter ] + - location: 19 (remaining gas: 1039950.567 units remaining) + [ 0 + (Pair 1 4 2 Unit) @parameter ] + - location: 20 (remaining gas: 1039950.552 units remaining) + [ True + (Pair 1 4 2 Unit) @parameter ] + - location: 21 (remaining gas: 1039950.542 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 21 (remaining gas: 1039950.527 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 27 (remaining gas: 1039950.517 units remaining) + [ (Pair 1 4 2 Unit) @parameter + (Pair 1 4 2 Unit) @parameter ] + - location: 28 (remaining gas: 1039950.487 units remaining) + [ 1 + (Pair 1 4 2 Unit) @parameter ] + - location: 30 (remaining gas: 1039950.477 units remaining) + [ 1 + 1 + (Pair 1 4 2 Unit) @parameter ] + - location: 35 (remaining gas: 1039950.442 units remaining) + [ 0 + (Pair 1 4 2 Unit) @parameter ] + - location: 36 (remaining gas: 1039950.427 units remaining) + [ True + (Pair 1 4 2 Unit) @parameter ] + - location: 37 (remaining gas: 1039950.417 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 37 (remaining gas: 1039950.402 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 43 (remaining gas: 1039950.392 units remaining) + [ (Pair 1 4 2 Unit) @parameter + (Pair 1 4 2 Unit) @parameter ] + - location: 44 (remaining gas: 1039950.361 units remaining) + [ 4 + (Pair 1 4 2 Unit) @parameter ] + - location: 46 (remaining gas: 1039950.351 units remaining) + [ 4 + 4 + (Pair 1 4 2 Unit) @parameter ] + - location: 51 (remaining gas: 1039950.316 units remaining) + [ 0 + (Pair 1 4 2 Unit) @parameter ] + - location: 52 (remaining gas: 1039950.301 units remaining) + [ True + (Pair 1 4 2 Unit) @parameter ] + - location: 53 (remaining gas: 1039950.291 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 53 (remaining gas: 1039950.276 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 59 (remaining gas: 1039950.266 units remaining) + [ (Pair 1 4 2 Unit) @parameter + (Pair 1 4 2 Unit) @parameter ] + - location: 60 (remaining gas: 1039950.234 units remaining) + [ 2 + (Pair 1 4 2 Unit) @parameter ] + - location: 62 (remaining gas: 1039950.224 units remaining) + [ 2 + 2 + (Pair 1 4 2 Unit) @parameter ] + - location: 67 (remaining gas: 1039950.189 units remaining) + [ 0 + (Pair 1 4 2 Unit) @parameter ] + - location: 68 (remaining gas: 1039950.174 units remaining) + [ True + (Pair 1 4 2 Unit) @parameter ] + - location: 69 (remaining gas: 1039950.164 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 69 (remaining gas: 1039950.149 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 75 (remaining gas: 1039950.139 units remaining) + [ (Pair 1 4 2 Unit) @parameter + (Pair 1 4 2 Unit) @parameter ] + - location: 76 (remaining gas: 1039950.106 units remaining) + [ Unit + (Pair 1 4 2 Unit) @parameter ] + - location: 78 (remaining gas: 1039950.096 units remaining) + [ Unit + Unit + (Pair 1 4 2 Unit) @parameter ] + - location: 81 (remaining gas: 1039950.086 units remaining) + [ 0 + (Pair 1 4 2 Unit) @parameter ] + - location: 82 (remaining gas: 1039950.071 units remaining) + [ True + (Pair 1 4 2 Unit) @parameter ] + - location: 83 (remaining gas: 1039950.061 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 83 (remaining gas: 1039950.046 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 89 (remaining gas: 1039950.036 units remaining) + [ ] + - location: 90 (remaining gas: 1039950.026 units remaining) + [ Unit ] + - location: 91 (remaining gas: 1039950.011 units remaining) + [ {} + Unit ] + - location: 93 (remaining gas: 1039949.996 units remaining) + [ (Pair {} Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" new file mode 100644 index 000000000000..1f92cbe932b2 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 \"t.886cc365c6.out" @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comb-set-2.tz-None-(Pair 1 4 2 Unit)-(Some (Pair 2 4 "toto" 0x01))] + +storage + (Some (Pair 2 4 "toto" 0x01)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039985.116 units remaining) + [ (Pair (Pair 1 4 2 Unit) None) ] + - location: 16 (remaining gas: 1039985.106 units remaining) + [ (Pair 1 4 2 Unit) @parameter ] + - location: 17 (remaining gas: 1039985.096 units remaining) + [ 2 + (Pair 1 4 2 Unit) @parameter ] + - location: 20 (remaining gas: 1039985.055 units remaining) + [ (Pair 2 4 2 Unit) ] + - location: 22 (remaining gas: 1039985.045 units remaining) + [ "toto" + (Pair 2 4 2 Unit) ] + - location: 25 (remaining gas: 1039984.999 units remaining) + [ (Pair 2 4 "toto" Unit) ] + - location: 27 (remaining gas: 1039984.989 units remaining) + [ 0x01 + (Pair 2 4 "toto" Unit) ] + - location: 30 (remaining gas: 1039984.942 units remaining) + [ (Pair 2 4 "toto" 0x01) ] + - location: 32 (remaining gas: 1039984.927 units remaining) + [ (Some (Pair 2 4 "toto" 0x01)) ] + - location: 33 (remaining gas: 1039984.912 units remaining) + [ {} + (Some (Pair 2 4 "toto" 0x01)) ] + - location: 35 (remaining gas: 1039984.897 units remaining) + [ (Pair {} (Some (Pair 2 4 "toto" 0x01))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out new file mode 100644 index 000000000000..57838a34ced9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)].out @@ -0,0 +1,39 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comb-set.tz-(Pair 1 4 2 Unit)-Unit-(Pair 2 12 8 Unit)] + +storage + (Pair 2 12 8 Unit) +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039985.453 units remaining) + [ (Pair Unit 1 4 2 Unit) ] + - location: 11 (remaining gas: 1039985.443 units remaining) + [ (Pair 1 4 2 Unit) @storage ] + - location: 12 (remaining gas: 1039985.433 units remaining) + [ 2 + (Pair 1 4 2 Unit) @storage ] + - location: 15 (remaining gas: 1039985.392 units remaining) + [ (Pair 2 4 2 Unit) ] + - location: 17 (remaining gas: 1039985.382 units remaining) + [ 12 + (Pair 2 4 2 Unit) ] + - location: 20 (remaining gas: 1039985.339 units remaining) + [ (Pair 2 12 2 Unit) ] + - location: 22 (remaining gas: 1039985.329 units remaining) + [ 8 + (Pair 2 12 2 Unit) ] + - location: 25 (remaining gas: 1039985.283 units remaining) + [ (Pair 2 12 8 Unit) ] + - location: 27 (remaining gas: 1039985.273 units remaining) + [ Unit + (Pair 2 12 8 Unit) ] + - location: 28 (remaining gas: 1039985.226 units remaining) + [ (Pair 2 12 8 Unit) ] + - location: 30 (remaining gas: 1039985.211 units remaining) + [ {} + (Pair 2 12 8 Unit) ] + - location: 32 (remaining gas: 1039985.196 units remaining) + [ (Pair {} 2 12 8 Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out new file mode 100644 index 000000000000..f5c806d89367 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comb.tz-(Pair 0 0 0)-Unit-(Pair 1 2 3)] + +storage + (Pair 1 2 3) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.399 units remaining) + [ (Pair Unit 0 0 0) ] + - location: 10 (remaining gas: 1039990.389 units remaining) + [ ] + - location: 11 (remaining gas: 1039990.379 units remaining) + [ 3 ] + - location: 14 (remaining gas: 1039990.369 units remaining) + [ 2 + 3 ] + - location: 17 (remaining gas: 1039990.359 units remaining) + [ 1 + 2 + 3 ] + - location: 20 (remaining gas: 1039990.344 units remaining) + [ {} + 1 + 2 + 3 ] + - location: 22 (remaining gas: 1039990.330 units remaining) + [ (Pair {} 1 2 3) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit].out new file mode 100644 index 000000000000..043836fe75be --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit].out @@ -0,0 +1,398 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[compare.tz-Unit-Unit-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039782.668 units remaining) + [ (Pair Unit Unit) ] + - location: 7 (remaining gas: 1039782.658 units remaining) + [ ] + - location: 8 (remaining gas: 1039782.648 units remaining) + [ True ] + - location: 11 (remaining gas: 1039782.638 units remaining) + [ True + True ] + - location: 12 (remaining gas: 1039782.603 units remaining) + [ 0 ] + - location: 14 (remaining gas: 1039782.588 units remaining) + [ True ] + - location: 15 (remaining gas: 1039782.578 units remaining) + [ ] + - location: 15 (remaining gas: 1039782.563 units remaining) + [ ] + - location: 21 (remaining gas: 1039782.553 units remaining) + [ False ] + - location: 24 (remaining gas: 1039782.543 units remaining) + [ False + False ] + - location: 25 (remaining gas: 1039782.508 units remaining) + [ 0 ] + - location: 27 (remaining gas: 1039782.493 units remaining) + [ True ] + - location: 28 (remaining gas: 1039782.483 units remaining) + [ ] + - location: 28 (remaining gas: 1039782.468 units remaining) + [ ] + - location: 34 (remaining gas: 1039782.458 units remaining) + [ False ] + - location: 37 (remaining gas: 1039782.448 units remaining) + [ True + False ] + - location: 40 (remaining gas: 1039782.413 units remaining) + [ 1 ] + - location: 42 (remaining gas: 1039782.398 units remaining) + [ True ] + - location: 43 (remaining gas: 1039782.388 units remaining) + [ ] + - location: 43 (remaining gas: 1039782.373 units remaining) + [ ] + - location: 49 (remaining gas: 1039782.363 units remaining) + [ True ] + - location: 52 (remaining gas: 1039782.353 units remaining) + [ False + True ] + - location: 55 (remaining gas: 1039782.318 units remaining) + [ -1 ] + - location: 57 (remaining gas: 1039782.303 units remaining) + [ True ] + - location: 58 (remaining gas: 1039782.293 units remaining) + [ ] + - location: 58 (remaining gas: 1039782.278 units remaining) + [ ] + - location: 64 (remaining gas: 1039782.268 units remaining) + [ 0xaabbcc ] + - location: 67 (remaining gas: 1039782.258 units remaining) + [ 0xaabbcc + 0xaabbcc ] + - location: 68 (remaining gas: 1039782.223 units remaining) + [ 0 ] + - location: 70 (remaining gas: 1039782.208 units remaining) + [ True ] + - location: 71 (remaining gas: 1039782.198 units remaining) + [ ] + - location: 71 (remaining gas: 1039782.183 units remaining) + [ ] + - location: 77 (remaining gas: 1039782.173 units remaining) + [ 0x ] + - location: 80 (remaining gas: 1039782.163 units remaining) + [ 0x + 0x ] + - location: 83 (remaining gas: 1039782.128 units remaining) + [ 0 ] + - location: 85 (remaining gas: 1039782.113 units remaining) + [ True ] + - location: 86 (remaining gas: 1039782.103 units remaining) + [ ] + - location: 86 (remaining gas: 1039782.088 units remaining) + [ ] + - location: 92 (remaining gas: 1039782.078 units remaining) + [ 0x ] + - location: 95 (remaining gas: 1039782.068 units remaining) + [ 0x01 + 0x ] + - location: 98 (remaining gas: 1039782.033 units remaining) + [ 1 ] + - location: 100 (remaining gas: 1039782.018 units remaining) + [ True ] + - location: 101 (remaining gas: 1039782.008 units remaining) + [ ] + - location: 101 (remaining gas: 1039781.993 units remaining) + [ ] + - location: 107 (remaining gas: 1039781.983 units remaining) + [ 0x01 ] + - location: 110 (remaining gas: 1039781.973 units remaining) + [ 0x02 + 0x01 ] + - location: 113 (remaining gas: 1039781.938 units remaining) + [ 1 ] + - location: 115 (remaining gas: 1039781.923 units remaining) + [ True ] + - location: 116 (remaining gas: 1039781.913 units remaining) + [ ] + - location: 116 (remaining gas: 1039781.898 units remaining) + [ ] + - location: 122 (remaining gas: 1039781.888 units remaining) + [ 0x02 ] + - location: 125 (remaining gas: 1039781.878 units remaining) + [ 0x01 + 0x02 ] + - location: 128 (remaining gas: 1039781.843 units remaining) + [ -1 ] + - location: 130 (remaining gas: 1039781.828 units remaining) + [ True ] + - location: 131 (remaining gas: 1039781.818 units remaining) + [ ] + - location: 131 (remaining gas: 1039781.803 units remaining) + [ ] + - location: 137 (remaining gas: 1039781.793 units remaining) + [ 1 ] + - location: 140 (remaining gas: 1039781.783 units remaining) + [ 1 + 1 ] + - location: 141 (remaining gas: 1039781.748 units remaining) + [ 0 ] + - location: 143 (remaining gas: 1039781.733 units remaining) + [ True ] + - location: 144 (remaining gas: 1039781.723 units remaining) + [ ] + - location: 144 (remaining gas: 1039781.708 units remaining) + [ ] + - location: 150 (remaining gas: 1039781.698 units remaining) + [ 10 ] + - location: 153 (remaining gas: 1039781.688 units remaining) + [ 5 + 10 ] + - location: 156 (remaining gas: 1039781.653 units remaining) + [ -1 ] + - location: 158 (remaining gas: 1039781.638 units remaining) + [ True ] + - location: 159 (remaining gas: 1039781.628 units remaining) + [ ] + - location: 159 (remaining gas: 1039781.613 units remaining) + [ ] + - location: 165 (remaining gas: 1039781.603 units remaining) + [ -4 ] + - location: 168 (remaining gas: 1039781.593 units remaining) + [ 1923 + -4 ] + - location: 171 (remaining gas: 1039781.558 units remaining) + [ 1 ] + - location: 173 (remaining gas: 1039781.543 units remaining) + [ True ] + - location: 174 (remaining gas: 1039781.533 units remaining) + [ ] + - location: 174 (remaining gas: 1039781.518 units remaining) + [ ] + - location: 180 (remaining gas: 1039781.508 units remaining) + [ 1 ] + - location: 183 (remaining gas: 1039781.498 units remaining) + [ 1 + 1 ] + - location: 184 (remaining gas: 1039781.463 units remaining) + [ 0 ] + - location: 186 (remaining gas: 1039781.448 units remaining) + [ True ] + - location: 187 (remaining gas: 1039781.438 units remaining) + [ ] + - location: 187 (remaining gas: 1039781.423 units remaining) + [ ] + - location: 193 (remaining gas: 1039781.413 units remaining) + [ 10 ] + - location: 196 (remaining gas: 1039781.403 units remaining) + [ 5 + 10 ] + - location: 199 (remaining gas: 1039781.368 units remaining) + [ -1 ] + - location: 201 (remaining gas: 1039781.353 units remaining) + [ True ] + - location: 202 (remaining gas: 1039781.343 units remaining) + [ ] + - location: 202 (remaining gas: 1039781.328 units remaining) + [ ] + - location: 208 (remaining gas: 1039781.318 units remaining) + [ 4 ] + - location: 211 (remaining gas: 1039781.308 units remaining) + [ 1923 + 4 ] + - location: 214 (remaining gas: 1039781.273 units remaining) + [ 1 ] + - location: 216 (remaining gas: 1039781.258 units remaining) + [ True ] + - location: 217 (remaining gas: 1039781.248 units remaining) + [ ] + - location: 217 (remaining gas: 1039781.233 units remaining) + [ ] + - location: 223 (remaining gas: 1039781.223 units remaining) + [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] + - location: 226 (remaining gas: 1039781.213 units remaining) + [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" + "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] + - location: 227 (remaining gas: 1039781.177 units remaining) + [ 0 ] + - location: 229 (remaining gas: 1039781.162 units remaining) + [ True ] + - location: 230 (remaining gas: 1039781.152 units remaining) + [ ] + - location: 230 (remaining gas: 1039781.137 units remaining) + [ ] + - location: 236 (remaining gas: 1039781.127 units remaining) + [ "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" ] + - location: 239 (remaining gas: 1039781.117 units remaining) + [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" + "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" ] + - location: 242 (remaining gas: 1039781.081 units remaining) + [ -1 ] + - location: 244 (remaining gas: 1039781.066 units remaining) + [ True ] + - location: 245 (remaining gas: 1039781.056 units remaining) + [ ] + - location: 245 (remaining gas: 1039781.041 units remaining) + [ ] + - location: 251 (remaining gas: 1039781.031 units remaining) + [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] + - location: 254 (remaining gas: 1039781.021 units remaining) + [ "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv" + "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] + - location: 257 (remaining gas: 1039780.985 units remaining) + [ 1 ] + - location: 259 (remaining gas: 1039780.970 units remaining) + [ True ] + - location: 260 (remaining gas: 1039780.960 units remaining) + [ ] + - location: 260 (remaining gas: 1039780.945 units remaining) + [ ] + - location: 266 (remaining gas: 1039780.935 units remaining) + [ 1 ] + - location: 269 (remaining gas: 1039780.925 units remaining) + [ 1 + 1 ] + - location: 270 (remaining gas: 1039780.890 units remaining) + [ 0 ] + - location: 272 (remaining gas: 1039780.875 units remaining) + [ True ] + - location: 273 (remaining gas: 1039780.865 units remaining) + [ ] + - location: 273 (remaining gas: 1039780.850 units remaining) + [ ] + - location: 279 (remaining gas: 1039780.840 units remaining) + [ 10 ] + - location: 282 (remaining gas: 1039780.830 units remaining) + [ 5 + 10 ] + - location: 285 (remaining gas: 1039780.795 units remaining) + [ -1 ] + - location: 287 (remaining gas: 1039780.780 units remaining) + [ True ] + - location: 288 (remaining gas: 1039780.770 units remaining) + [ ] + - location: 288 (remaining gas: 1039780.755 units remaining) + [ ] + - location: 294 (remaining gas: 1039780.745 units remaining) + [ 4 ] + - location: 297 (remaining gas: 1039780.735 units remaining) + [ 1923 + 4 ] + - location: 300 (remaining gas: 1039780.700 units remaining) + [ 1 ] + - location: 302 (remaining gas: 1039780.685 units remaining) + [ True ] + - location: 303 (remaining gas: 1039780.675 units remaining) + [ ] + - location: 303 (remaining gas: 1039780.660 units remaining) + [ ] + - location: 309 (remaining gas: 1039780.650 units remaining) + [ "AABBCC" ] + - location: 312 (remaining gas: 1039780.640 units remaining) + [ "AABBCC" + "AABBCC" ] + - location: 313 (remaining gas: 1039780.605 units remaining) + [ 0 ] + - location: 315 (remaining gas: 1039780.590 units remaining) + [ True ] + - location: 316 (remaining gas: 1039780.580 units remaining) + [ ] + - location: 316 (remaining gas: 1039780.565 units remaining) + [ ] + - location: 322 (remaining gas: 1039780.555 units remaining) + [ "" ] + - location: 325 (remaining gas: 1039780.545 units remaining) + [ "" + "" ] + - location: 328 (remaining gas: 1039780.510 units remaining) + [ 0 ] + - location: 330 (remaining gas: 1039780.495 units remaining) + [ True ] + - location: 331 (remaining gas: 1039780.485 units remaining) + [ ] + - location: 331 (remaining gas: 1039780.470 units remaining) + [ ] + - location: 337 (remaining gas: 1039780.460 units remaining) + [ "" ] + - location: 340 (remaining gas: 1039780.450 units remaining) + [ "a" + "" ] + - location: 343 (remaining gas: 1039780.415 units remaining) + [ 1 ] + - location: 345 (remaining gas: 1039780.400 units remaining) + [ True ] + - location: 346 (remaining gas: 1039780.390 units remaining) + [ ] + - location: 346 (remaining gas: 1039780.375 units remaining) + [ ] + - location: 352 (remaining gas: 1039780.365 units remaining) + [ "a" ] + - location: 355 (remaining gas: 1039780.355 units remaining) + [ "b" + "a" ] + - location: 358 (remaining gas: 1039780.320 units remaining) + [ 1 ] + - location: 360 (remaining gas: 1039780.305 units remaining) + [ True ] + - location: 361 (remaining gas: 1039780.295 units remaining) + [ ] + - location: 361 (remaining gas: 1039780.280 units remaining) + [ ] + - location: 367 (remaining gas: 1039780.270 units remaining) + [ "b" ] + - location: 370 (remaining gas: 1039780.260 units remaining) + [ "a" + "b" ] + - location: 373 (remaining gas: 1039780.225 units remaining) + [ -1 ] + - location: 375 (remaining gas: 1039780.210 units remaining) + [ True ] + - location: 376 (remaining gas: 1039780.200 units remaining) + [ ] + - location: 376 (remaining gas: 1039780.185 units remaining) + [ ] + - location: 382 (remaining gas: 1039780.175 units remaining) + [ "2019-09-16T08:38:05Z" ] + - location: 385 (remaining gas: 1039780.165 units remaining) + [ "2019-09-16T08:38:05Z" + "2019-09-16T08:38:05Z" ] + - location: 386 (remaining gas: 1039780.130 units remaining) + [ 0 ] + - location: 388 (remaining gas: 1039780.115 units remaining) + [ True ] + - location: 389 (remaining gas: 1039780.105 units remaining) + [ ] + - location: 389 (remaining gas: 1039780.090 units remaining) + [ ] + - location: 395 (remaining gas: 1039780.080 units remaining) + [ "2017-09-16T08:38:04Z" ] + - location: 398 (remaining gas: 1039780.070 units remaining) + [ "2019-09-16T08:38:05Z" + "2017-09-16T08:38:04Z" ] + - location: 401 (remaining gas: 1039780.035 units remaining) + [ 1 ] + - location: 403 (remaining gas: 1039780.020 units remaining) + [ True ] + - location: 404 (remaining gas: 1039780.010 units remaining) + [ ] + - location: 404 (remaining gas: 1039779.995 units remaining) + [ ] + - location: 410 (remaining gas: 1039779.985 units remaining) + [ "2019-09-16T08:38:05Z" ] + - location: 413 (remaining gas: 1039779.975 units remaining) + [ "2019-09-16T08:38:04Z" + "2019-09-16T08:38:05Z" ] + - location: 416 (remaining gas: 1039779.940 units remaining) + [ -1 ] + - location: 418 (remaining gas: 1039779.925 units remaining) + [ True ] + - location: 419 (remaining gas: 1039779.915 units remaining) + [ ] + - location: 419 (remaining gas: 1039779.900 units remaining) + [ ] + - location: 425 (remaining gas: 1039779.890 units remaining) + [ Unit ] + - location: 426 (remaining gas: 1039779.875 units remaining) + [ {} + Unit ] + - location: 428 (remaining gas: 1039779.860 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out new file mode 100644 index 000000000000..723f99e4e525 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ .bbaa8924d2.out @@ -0,0 +1,350 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[comparisons.tz-{}-{ -9999999; -1 ; 0 ; 1 ; 9999999 }-{ { False ; False ; False ; True ; True } ;\n { False ; False ; True ; True ; True } ;\n { True ; True ; False ; False ; False } ;\n { True ; True ; True ; False ; False } ;\n { True ; True ; False ; True ; True } ;\n { False ; False ; True ; False ; False } }] + +storage + { { False ; False ; False ; True ; True } ; + { False ; False ; True ; True ; True } ; + { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039962.637 units remaining) + [ (Pair { -9999999 ; -1 ; 0 ; 1 ; 9999999 } {}) ] + - location: 10 (remaining gas: 1039962.627 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 11 (remaining gas: 1039962.612 units remaining) + [ {} + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 14 (remaining gas: 1039962.597 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 16 (remaining gas: 1039962.587 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 17 (remaining gas: 1039962.587 units remaining) + [ -9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 19 (remaining gas: 1039962.572 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 17 (remaining gas: 1039962.557 units remaining) + [ -1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 19 (remaining gas: 1039962.542 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 17 (remaining gas: 1039962.527 units remaining) + [ 0 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 19 (remaining gas: 1039962.512 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 17 (remaining gas: 1039962.497 units remaining) + [ 1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 19 (remaining gas: 1039962.482 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 17 (remaining gas: 1039962.467 units remaining) + [ 9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 19 (remaining gas: 1039962.452 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 17 (remaining gas: 1039962.437 units remaining) + [ { False ; False ; True ; False ; False } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 14 (remaining gas: 1039962.407 units remaining) + [ {} + { False ; False ; True ; False ; False } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 20 (remaining gas: 1039962.397 units remaining) + [ { False ; False ; True ; False ; False } + {} + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 21 (remaining gas: 1039962.382 units remaining) + [ { { False ; False ; True ; False ; False } } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 22 (remaining gas: 1039962.367 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 24 (remaining gas: 1039962.357 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 25 (remaining gas: 1039962.357 units remaining) + [ -9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 27 (remaining gas: 1039962.342 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 25 (remaining gas: 1039962.327 units remaining) + [ -1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 27 (remaining gas: 1039962.312 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 25 (remaining gas: 1039962.297 units remaining) + [ 0 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 27 (remaining gas: 1039962.282 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 25 (remaining gas: 1039962.267 units remaining) + [ 1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 27 (remaining gas: 1039962.252 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 25 (remaining gas: 1039962.237 units remaining) + [ 9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 27 (remaining gas: 1039962.222 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 25 (remaining gas: 1039962.207 units remaining) + [ { True ; True ; False ; True ; True } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 22 (remaining gas: 1039962.177 units remaining) + [ { { False ; False ; True ; False ; False } } + { True ; True ; False ; True ; True } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 28 (remaining gas: 1039962.167 units remaining) + [ { True ; True ; False ; True ; True } + { { False ; False ; True ; False ; False } } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 29 (remaining gas: 1039962.152 units remaining) + [ { { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 30 (remaining gas: 1039962.137 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 32 (remaining gas: 1039962.127 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 33 (remaining gas: 1039962.127 units remaining) + [ -9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 35 (remaining gas: 1039962.112 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 33 (remaining gas: 1039962.097 units remaining) + [ -1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 35 (remaining gas: 1039962.082 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 33 (remaining gas: 1039962.067 units remaining) + [ 0 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 35 (remaining gas: 1039962.052 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 33 (remaining gas: 1039962.037 units remaining) + [ 1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 35 (remaining gas: 1039962.022 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 33 (remaining gas: 1039962.007 units remaining) + [ 9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 35 (remaining gas: 1039961.992 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 33 (remaining gas: 1039961.977 units remaining) + [ { True ; True ; True ; False ; False } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 30 (remaining gas: 1039961.947 units remaining) + [ { { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { True ; True ; True ; False ; False } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 36 (remaining gas: 1039961.937 units remaining) + [ { True ; True ; True ; False ; False } + { { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 37 (remaining gas: 1039961.922 units remaining) + [ { { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 38 (remaining gas: 1039961.907 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 40 (remaining gas: 1039961.897 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 41 (remaining gas: 1039961.897 units remaining) + [ -9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 43 (remaining gas: 1039961.882 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 41 (remaining gas: 1039961.867 units remaining) + [ -1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 43 (remaining gas: 1039961.852 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 41 (remaining gas: 1039961.837 units remaining) + [ 0 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 43 (remaining gas: 1039961.822 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 41 (remaining gas: 1039961.807 units remaining) + [ 1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 43 (remaining gas: 1039961.792 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 41 (remaining gas: 1039961.777 units remaining) + [ 9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 43 (remaining gas: 1039961.762 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 41 (remaining gas: 1039961.747 units remaining) + [ { True ; True ; False ; False ; False } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 38 (remaining gas: 1039961.717 units remaining) + [ { { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { True ; True ; False ; False ; False } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 44 (remaining gas: 1039961.707 units remaining) + [ { True ; True ; False ; False ; False } + { { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 45 (remaining gas: 1039961.692 units remaining) + [ { { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 46 (remaining gas: 1039961.677 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 48 (remaining gas: 1039961.667 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 49 (remaining gas: 1039961.667 units remaining) + [ -9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 51 (remaining gas: 1039961.652 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 49 (remaining gas: 1039961.637 units remaining) + [ -1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 51 (remaining gas: 1039961.622 units remaining) + [ False + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 49 (remaining gas: 1039961.607 units remaining) + [ 0 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 51 (remaining gas: 1039961.592 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 49 (remaining gas: 1039961.577 units remaining) + [ 1 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 51 (remaining gas: 1039961.562 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 49 (remaining gas: 1039961.547 units remaining) + [ 9999999 @parameter.elt + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 51 (remaining gas: 1039961.532 units remaining) + [ True + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 49 (remaining gas: 1039961.517 units remaining) + [ { False ; False ; True ; True ; True } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 46 (remaining gas: 1039961.487 units remaining) + [ { { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { False ; False ; True ; True ; True } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 52 (remaining gas: 1039961.477 units remaining) + [ { False ; False ; True ; True ; True } + { { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 53 (remaining gas: 1039961.462 units remaining) + [ { { False ; False ; True ; True ; True } ; + { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 54 (remaining gas: 1039961.447 units remaining) + [ { -9999999 ; -1 ; 0 ; 1 ; 9999999 } @parameter ] + - location: 56 (remaining gas: 1039961.447 units remaining) + [ -9999999 @parameter.elt ] + - location: 58 (remaining gas: 1039961.432 units remaining) + [ False ] + - location: 56 (remaining gas: 1039961.417 units remaining) + [ -1 @parameter.elt ] + - location: 58 (remaining gas: 1039961.402 units remaining) + [ False ] + - location: 56 (remaining gas: 1039961.387 units remaining) + [ 0 @parameter.elt ] + - location: 58 (remaining gas: 1039961.372 units remaining) + [ False ] + - location: 56 (remaining gas: 1039961.357 units remaining) + [ 1 @parameter.elt ] + - location: 58 (remaining gas: 1039961.342 units remaining) + [ True ] + - location: 56 (remaining gas: 1039961.327 units remaining) + [ 9999999 @parameter.elt ] + - location: 58 (remaining gas: 1039961.312 units remaining) + [ True ] + - location: 56 (remaining gas: 1039961.297 units remaining) + [ { False ; False ; False ; True ; True } ] + - location: 54 (remaining gas: 1039961.267 units remaining) + [ { { False ; False ; True ; True ; True } ; + { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } + { False ; False ; False ; True ; True } ] + - location: 59 (remaining gas: 1039961.257 units remaining) + [ { False ; False ; False ; True ; True } + { { False ; False ; True ; True ; True } ; + { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } ] + - location: 60 (remaining gas: 1039961.242 units remaining) + [ { { False ; False ; False ; True ; True } ; + { False ; False ; True ; True ; True } ; + { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } ] + - location: 61 (remaining gas: 1039961.227 units remaining) + [ {} + { { False ; False ; False ; True ; True } ; + { False ; False ; True ; True ; True } ; + { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } } ] + - location: 63 (remaining gas: 1039961.212 units remaining) + [ (Pair {} + { { False ; False ; False ; True ; True } ; + { False ; False ; True ; True ; True } ; + { True ; True ; False ; False ; False } ; + { True ; True ; True ; False ; False } ; + { True ; True ; False ; True ; True } ; + { False ; False ; True ; False ; False } }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"World!\" }-{ \"Hello World!\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"World!\" }-{ \"Hello World!\" }].out" new file mode 100644 index 000000000000..0316f3a9f753 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"World!\" }-{ \"Hello World!\" }].out" @@ -0,0 +1,28 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ "World!" }-{ "Hello World!" }] + +storage + { "Hello World!" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.305 units remaining) + [ (Pair { "World!" } {}) ] + - location: 9 (remaining gas: 1039992.295 units remaining) + [ { "World!" } @parameter ] + - location: 10 (remaining gas: 1039992.295 units remaining) + [ "World!" @parameter.elt ] + - location: 12 (remaining gas: 1039992.285 units remaining) + [ "Hello " @hello + "World!" @parameter.elt ] + - location: 15 (remaining gas: 1039992.220 units remaining) + [ "Hello World!" ] + - location: 10 (remaining gas: 1039992.205 units remaining) + [ { "Hello World!" } ] + - location: 16 (remaining gas: 1039992.190 units remaining) + [ {} + { "Hello World!" } ] + - location: 18 (remaining gas: 1039992.175 units remaining) + [ (Pair {} { "Hello World!" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"test1\" ; \"test2\" }-{ \"Hello test1.c27e8c3ee6.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"test1\" ; \"test2\" }-{ \"Hello test1.c27e8c3ee6.out" new file mode 100644 index 000000000000..138cb94e8d89 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ \"test1\" ; \"test2\" }-{ \"Hello test1.c27e8c3ee6.out" @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{ "test1" ; "test2" }-{ "Hello test1" ; "Hello test2" }] + +storage + { "Hello test1" ; "Hello test2" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.151 units remaining) + [ (Pair { "test1" ; "test2" } {}) ] + - location: 9 (remaining gas: 1039992.141 units remaining) + [ { "test1" ; "test2" } @parameter ] + - location: 10 (remaining gas: 1039992.141 units remaining) + [ "test1" @parameter.elt ] + - location: 12 (remaining gas: 1039992.131 units remaining) + [ "Hello " @hello + "test1" @parameter.elt ] + - location: 15 (remaining gas: 1039992.066 units remaining) + [ "Hello test1" ] + - location: 10 (remaining gas: 1039992.051 units remaining) + [ "test2" @parameter.elt ] + - location: 12 (remaining gas: 1039992.041 units remaining) + [ "Hello " @hello + "test2" @parameter.elt ] + - location: 15 (remaining gas: 1039991.976 units remaining) + [ "Hello test2" ] + - location: 10 (remaining gas: 1039991.961 units remaining) + [ { "Hello test1" ; "Hello test2" } ] + - location: 16 (remaining gas: 1039991.946 units remaining) + [ {} + { "Hello test1" ; "Hello test2" } ] + - location: 18 (remaining gas: 1039991.931 units remaining) + [ (Pair {} { "Hello test1" ; "Hello test2" }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}].out new file mode 100644 index 000000000000..f0e2661da9da --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello.tz-{}-{}-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.479 units remaining) + [ (Pair {} {}) ] + - location: 9 (remaining gas: 1039992.469 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039992.469 units remaining) + [ {} ] + - location: 16 (remaining gas: 1039992.454 units remaining) + [ {} + {} ] + - location: 18 (remaining gas: 1039992.439 units remaining) + [ (Pair {} {}) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out new file mode 100644 index 000000000000..9ff4f50d3817 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }].out @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xab ; 0xcd }-{ 0xffab ; 0xffcd }] + +storage + { 0xffab ; 0xffcd } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.398 units remaining) + [ (Pair { 0xab ; 0xcd } {}) ] + - location: 9 (remaining gas: 1039992.388 units remaining) + [ { 0xab ; 0xcd } @parameter ] + - location: 10 (remaining gas: 1039992.388 units remaining) + [ 0xab @parameter.elt ] + - location: 12 (remaining gas: 1039992.378 units remaining) + [ 0xff + 0xab @parameter.elt ] + - location: 15 (remaining gas: 1039992.313 units remaining) + [ 0xffab ] + - location: 10 (remaining gas: 1039992.298 units remaining) + [ 0xcd @parameter.elt ] + - location: 12 (remaining gas: 1039992.288 units remaining) + [ 0xff + 0xcd @parameter.elt ] + - location: 15 (remaining gas: 1039992.223 units remaining) + [ 0xffcd ] + - location: 10 (remaining gas: 1039992.208 units remaining) + [ { 0xffab ; 0xffcd } ] + - location: 16 (remaining gas: 1039992.193 units remaining) + [ {} + { 0xffab ; 0xffcd } ] + - location: 18 (remaining gas: 1039992.178 units remaining) + [ (Pair {} { 0xffab ; 0xffcd }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out new file mode 100644 index 000000000000..cc46d28d82c4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }].out @@ -0,0 +1,28 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{ 0xcd }-{ 0xffcd }] + +storage + { 0xffcd } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.498 units remaining) + [ (Pair { 0xcd } {}) ] + - location: 9 (remaining gas: 1039992.488 units remaining) + [ { 0xcd } @parameter ] + - location: 10 (remaining gas: 1039992.488 units remaining) + [ 0xcd @parameter.elt ] + - location: 12 (remaining gas: 1039992.478 units remaining) + [ 0xff + 0xcd @parameter.elt ] + - location: 15 (remaining gas: 1039992.413 units remaining) + [ 0xffcd ] + - location: 10 (remaining gas: 1039992.398 units remaining) + [ { 0xffcd } ] + - location: 16 (remaining gas: 1039992.383 units remaining) + [ {} + { 0xffcd } ] + - location: 18 (remaining gas: 1039992.368 units remaining) + [ (Pair {} { 0xffcd }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}].out new file mode 100644 index 000000000000..5ce91f07ecdc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_hello_bytes.tz-{}-{}-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.598 units remaining) + [ (Pair {} {}) ] + - location: 9 (remaining gas: 1039992.588 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039992.588 units remaining) + [ {} ] + - location: 16 (remaining gas: 1039992.573 units remaining) + [ {} + {} ] + - location: 18 (remaining gas: 1039992.558 units remaining) + [ (Pair {} {}) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"Hello\" ; \" \" ; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"Hello\" ; \" \" ; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" new file mode 100644 index 000000000000..f17bf0e00dd4 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"Hello\" ; \" \" ; \"World\" ; \"!\" }-\"He.0c7b4cd53c.out" @@ -0,0 +1,119 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_list.tz-""-{ "Hello" ; " " ; "World" ; "!" }-"Hello World!"] + +storage + "Hello World!" +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039987.037 units remaining) + [ (Pair { "Hello" ; " " ; "World" ; "!" } "") ] + - location: 8 (remaining gas: 1039987.027 units remaining) + [ { "Hello" ; " " ; "World" ; "!" } @parameter ] + - location: 9 (remaining gas: 1039987.017 units remaining) + [ "" + { "Hello" ; " " ; "World" ; "!" } @parameter ] + - location: 12 (remaining gas: 1039987.007 units remaining) + [ { "Hello" ; " " ; "World" ; "!" } @parameter + "" ] + - location: 13 (remaining gas: 1039987.007 units remaining) + [ "Hello" @parameter.elt + "" ] + - location: 15 (remaining gas: 1039986.997 units remaining) + [ "" + "Hello" @parameter.elt ] + - location: 16 (remaining gas: 1039986.982 units remaining) + [ "Hello" @parameter.elt ] + - location: 18 (remaining gas: 1039986.967 units remaining) + [ {} + "Hello" @parameter.elt ] + - location: 20 (remaining gas: 1039986.957 units remaining) + [ "Hello" @parameter.elt + {} ] + - location: 21 (remaining gas: 1039986.942 units remaining) + [ { "Hello" } ] + - location: 16 (remaining gas: 1039986.912 units remaining) + [ "" + { "Hello" } ] + - location: 22 (remaining gas: 1039986.897 units remaining) + [ { "" ; "Hello" } ] + - location: 23 (remaining gas: 1039986.777 units remaining) + [ "Hello" ] + - location: 13 (remaining gas: 1039986.762 units remaining) + [ " " @parameter.elt + "Hello" ] + - location: 15 (remaining gas: 1039986.752 units remaining) + [ "Hello" + " " @parameter.elt ] + - location: 16 (remaining gas: 1039986.737 units remaining) + [ " " @parameter.elt ] + - location: 18 (remaining gas: 1039986.722 units remaining) + [ {} + " " @parameter.elt ] + - location: 20 (remaining gas: 1039986.712 units remaining) + [ " " @parameter.elt + {} ] + - location: 21 (remaining gas: 1039986.697 units remaining) + [ { " " } ] + - location: 16 (remaining gas: 1039986.667 units remaining) + [ "Hello" + { " " } ] + - location: 22 (remaining gas: 1039986.652 units remaining) + [ { "Hello" ; " " } ] + - location: 23 (remaining gas: 1039986.532 units remaining) + [ "Hello " ] + - location: 13 (remaining gas: 1039986.517 units remaining) + [ "World" @parameter.elt + "Hello " ] + - location: 15 (remaining gas: 1039986.507 units remaining) + [ "Hello " + "World" @parameter.elt ] + - location: 16 (remaining gas: 1039986.492 units remaining) + [ "World" @parameter.elt ] + - location: 18 (remaining gas: 1039986.477 units remaining) + [ {} + "World" @parameter.elt ] + - location: 20 (remaining gas: 1039986.467 units remaining) + [ "World" @parameter.elt + {} ] + - location: 21 (remaining gas: 1039986.452 units remaining) + [ { "World" } ] + - location: 16 (remaining gas: 1039986.422 units remaining) + [ "Hello " + { "World" } ] + - location: 22 (remaining gas: 1039986.407 units remaining) + [ { "Hello " ; "World" } ] + - location: 23 (remaining gas: 1039986.286 units remaining) + [ "Hello World" ] + - location: 13 (remaining gas: 1039986.271 units remaining) + [ "!" @parameter.elt + "Hello World" ] + - location: 15 (remaining gas: 1039986.261 units remaining) + [ "Hello World" + "!" @parameter.elt ] + - location: 16 (remaining gas: 1039986.246 units remaining) + [ "!" @parameter.elt ] + - location: 18 (remaining gas: 1039986.231 units remaining) + [ {} + "!" @parameter.elt ] + - location: 20 (remaining gas: 1039986.221 units remaining) + [ "!" @parameter.elt + {} ] + - location: 21 (remaining gas: 1039986.206 units remaining) + [ { "!" } ] + - location: 16 (remaining gas: 1039986.176 units remaining) + [ "Hello World" + { "!" } ] + - location: 22 (remaining gas: 1039986.161 units remaining) + [ { "Hello World" ; "!" } ] + - location: 23 (remaining gas: 1039986.040 units remaining) + [ "Hello World!" ] + - location: 13 (remaining gas: 1039986.025 units remaining) + [ "Hello World!" ] + - location: 24 (remaining gas: 1039986.010 units remaining) + [ {} + "Hello World!" ] + - location: 26 (remaining gas: 1039985.995 units remaining) + [ (Pair {} "Hello World!") ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" new file mode 100644 index 000000000000..a13a5bb067c8 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{ \"a\" ; \"b\" ; \"c\" }-\"abc\"].out" @@ -0,0 +1,96 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_list.tz-""-{ "a" ; "b" ; "c" }-"abc"] + +storage + "abc" +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039987.241 units remaining) + [ (Pair { "a" ; "b" ; "c" } "") ] + - location: 8 (remaining gas: 1039987.231 units remaining) + [ { "a" ; "b" ; "c" } @parameter ] + - location: 9 (remaining gas: 1039987.221 units remaining) + [ "" + { "a" ; "b" ; "c" } @parameter ] + - location: 12 (remaining gas: 1039987.211 units remaining) + [ { "a" ; "b" ; "c" } @parameter + "" ] + - location: 13 (remaining gas: 1039987.211 units remaining) + [ "a" @parameter.elt + "" ] + - location: 15 (remaining gas: 1039987.201 units remaining) + [ "" + "a" @parameter.elt ] + - location: 16 (remaining gas: 1039987.186 units remaining) + [ "a" @parameter.elt ] + - location: 18 (remaining gas: 1039987.171 units remaining) + [ {} + "a" @parameter.elt ] + - location: 20 (remaining gas: 1039987.161 units remaining) + [ "a" @parameter.elt + {} ] + - location: 21 (remaining gas: 1039987.146 units remaining) + [ { "a" } ] + - location: 16 (remaining gas: 1039987.116 units remaining) + [ "" + { "a" } ] + - location: 22 (remaining gas: 1039987.101 units remaining) + [ { "" ; "a" } ] + - location: 23 (remaining gas: 1039986.981 units remaining) + [ "a" ] + - location: 13 (remaining gas: 1039986.966 units remaining) + [ "b" @parameter.elt + "a" ] + - location: 15 (remaining gas: 1039986.956 units remaining) + [ "a" + "b" @parameter.elt ] + - location: 16 (remaining gas: 1039986.941 units remaining) + [ "b" @parameter.elt ] + - location: 18 (remaining gas: 1039986.926 units remaining) + [ {} + "b" @parameter.elt ] + - location: 20 (remaining gas: 1039986.916 units remaining) + [ "b" @parameter.elt + {} ] + - location: 21 (remaining gas: 1039986.901 units remaining) + [ { "b" } ] + - location: 16 (remaining gas: 1039986.871 units remaining) + [ "a" + { "b" } ] + - location: 22 (remaining gas: 1039986.856 units remaining) + [ { "a" ; "b" } ] + - location: 23 (remaining gas: 1039986.736 units remaining) + [ "ab" ] + - location: 13 (remaining gas: 1039986.721 units remaining) + [ "c" @parameter.elt + "ab" ] + - location: 15 (remaining gas: 1039986.711 units remaining) + [ "ab" + "c" @parameter.elt ] + - location: 16 (remaining gas: 1039986.696 units remaining) + [ "c" @parameter.elt ] + - location: 18 (remaining gas: 1039986.681 units remaining) + [ {} + "c" @parameter.elt ] + - location: 20 (remaining gas: 1039986.671 units remaining) + [ "c" @parameter.elt + {} ] + - location: 21 (remaining gas: 1039986.656 units remaining) + [ { "c" } ] + - location: 16 (remaining gas: 1039986.626 units remaining) + [ "ab" + { "c" } ] + - location: 22 (remaining gas: 1039986.611 units remaining) + [ { "ab" ; "c" } ] + - location: 23 (remaining gas: 1039986.491 units remaining) + [ "abc" ] + - location: 13 (remaining gas: 1039986.476 units remaining) + [ "abc" ] + - location: 24 (remaining gas: 1039986.461 units remaining) + [ {} + "abc" ] + - location: 26 (remaining gas: 1039986.446 units remaining) + [ (Pair {} "abc") ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{}-\"\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{}-\"\"].out" new file mode 100644 index 000000000000..282dd7c01375 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[concat_list.tz-\"\"-{}-\"\"].out" @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[concat_list.tz-""-{}-""] + +storage + "" +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039987.613 units remaining) + [ (Pair {} "") ] + - location: 8 (remaining gas: 1039987.603 units remaining) + [ {} @parameter ] + - location: 9 (remaining gas: 1039987.593 units remaining) + [ "" + {} @parameter ] + - location: 12 (remaining gas: 1039987.583 units remaining) + [ {} @parameter + "" ] + - location: 13 (remaining gas: 1039987.583 units remaining) + [ "" ] + - location: 24 (remaining gas: 1039987.568 units remaining) + [ {} + "" ] + - location: 26 (remaining gas: 1039987.553 units remaining) + [ (Pair {} "") ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out new file mode 100644 index 000000000000..1771411d5d0d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }].out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[cons.tz-{ -5 ; 10 }-99-{ 99 ; -5 ; 10 }] + +storage + { 99 ; -5 ; 10 } +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.045 units remaining) + [ (Pair 99 { -5 ; 10 }) ] + - location: 8 (remaining gas: 1039994.035 units remaining) + [ 99 @parameter + { -5 ; 10 } @storage ] + - location: 9 (remaining gas: 1039994.020 units remaining) + [ { 99 ; -5 ; 10 } ] + - location: 10 (remaining gas: 1039994.005 units remaining) + [ {} + { 99 ; -5 ; 10 } ] + - location: 12 (remaining gas: 1039993.990 units remaining) + [ (Pair {} { 99 ; -5 ; 10 }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out new file mode 100644 index 000000000000..4bbc35568f62 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }].out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[cons.tz-{ 10 }--5-{ -5 ; 10 }] + +storage + { -5 ; 10 } +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.145 units remaining) + [ (Pair -5 { 10 }) ] + - location: 8 (remaining gas: 1039994.135 units remaining) + [ -5 @parameter + { 10 } @storage ] + - location: 9 (remaining gas: 1039994.120 units remaining) + [ { -5 ; 10 } ] + - location: 10 (remaining gas: 1039994.105 units remaining) + [ {} + { -5 ; 10 } ] + - location: 12 (remaining gas: 1039994.090 units remaining) + [ (Pair {} { -5 ; 10 }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }].out new file mode 100644 index 000000000000..c95a25fa5532 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }].out @@ -0,0 +1,22 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[cons.tz-{}-10-{ 10 }] + +storage + { 10 } +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.245 units remaining) + [ (Pair 10 {}) ] + - location: 8 (remaining gas: 1039994.235 units remaining) + [ 10 @parameter + {} @storage ] + - location: 9 (remaining gas: 1039994.220 units remaining) + [ { 10 } ] + - location: 10 (remaining gas: 1039994.205 units remaining) + [ {} + { 10 } ] + - location: 12 (remaining gas: 1039994.190 units remaining) + [ (Pair {} { 10 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"A\" } { \"B\" })-(Some False)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"A\" } { \"B\" })-(Some False)].out" new file mode 100644 index 000000000000..605e66d5d2e5 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"A\" } { \"B\" })-(Some False)].out" @@ -0,0 +1,166 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "A" } { "B" })-(Some False)] + +storage + (Some False) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039963.179 units remaining) + [ (Pair (Pair { "A" } { "B" }) None) ] + - location: 12 (remaining gas: 1039963.169 units remaining) + [ (Pair { "A" } { "B" }) @parameter ] + - location: 13 (remaining gas: 1039963.159 units remaining) + [ (Pair { "A" } { "B" }) @parameter + (Pair { "A" } { "B" }) @parameter ] + - location: 14 (remaining gas: 1039963.149 units remaining) + [ { "A" } + (Pair { "A" } { "B" }) @parameter ] + - location: 15 (remaining gas: 1039963.134 units remaining) + [ (Pair { "A" } { "B" }) @parameter ] + - location: 17 (remaining gas: 1039963.124 units remaining) + [ { "B" } ] + - location: 15 (remaining gas: 1039963.094 units remaining) + [ { "A" } + { "B" } ] + - location: 18 (remaining gas: 1039962.874 units remaining) + [ {} + { "A" } + { "B" } ] + - location: 20 (remaining gas: 1039962.864 units remaining) + [ { "A" } + {} + { "B" } ] + - location: 21 (remaining gas: 1039962.864 units remaining) + [ "A" @elt + {} + { "B" } ] + - location: 23 (remaining gas: 1039962.849 units remaining) + [ (Pair "A" {}) + { "B" } ] + - location: 24 (remaining gas: 1039962.839 units remaining) + [ (Pair "A" {}) + (Pair "A" {}) + { "B" } ] + - location: 25 (remaining gas: 1039962.829 units remaining) + [ "A" @elt + (Pair "A" {}) + { "B" } ] + - location: 26 (remaining gas: 1039962.814 units remaining) + [ (Pair "A" {}) + { "B" } ] + - location: 28 (remaining gas: 1039962.804 units remaining) + [ {} + { "B" } ] + - location: 26 (remaining gas: 1039962.774 units remaining) + [ "A" @elt + {} + { "B" } ] + - location: 29 (remaining gas: 1039962.764 units remaining) + [ True + "A" @elt + {} + { "B" } ] + - location: 32 (remaining gas: 1039962.754 units remaining) + [ "A" @elt + True + {} + { "B" } ] + - location: 33 (remaining gas: 1039962.554 units remaining) + [ { "A" } + { "B" } ] + - location: 21 (remaining gas: 1039962.539 units remaining) + [ { "A" } + { "B" } ] + - location: 34 (remaining gas: 1039962.529 units remaining) + [ True + { "A" } + { "B" } ] + - location: 37 (remaining gas: 1039962.519 units remaining) + [ { "A" } + True + { "B" } ] + - location: 38 (remaining gas: 1039962.504 units remaining) + [ (Pair { "A" } True) + { "B" } ] + - location: 39 (remaining gas: 1039962.494 units remaining) + [ { "B" } + (Pair { "A" } True) ] + - location: 40 (remaining gas: 1039962.494 units remaining) + [ "B" @elt + (Pair { "A" } True) ] + - location: 42 (remaining gas: 1039962.479 units remaining) + [ (Pair "B" { "A" } True) ] + - location: 43 (remaining gas: 1039962.469 units remaining) + [ (Pair "B" { "A" } True) + (Pair "B" { "A" } True) ] + - location: 44 (remaining gas: 1039962.459 units remaining) + [ (Pair "B" { "A" } True) + (Pair "B" { "A" } True) + (Pair "B" { "A" } True) ] + - location: 45 (remaining gas: 1039962.449 units remaining) + [ "B" @elt + (Pair "B" { "A" } True) + (Pair "B" { "A" } True) ] + - location: 46 (remaining gas: 1039962.434 units remaining) + [ (Pair "B" { "A" } True) + (Pair "B" { "A" } True) ] + - location: 49 (remaining gas: 1039962.424 units remaining) + [ (Pair { "A" } True) + (Pair "B" { "A" } True) ] + - location: 50 (remaining gas: 1039962.414 units remaining) + [ { "A" } + (Pair "B" { "A" } True) ] + - location: 51 (remaining gas: 1039962.399 units remaining) + [ (Pair "B" { "A" } True) ] + - location: 54 (remaining gas: 1039962.389 units remaining) + [ (Pair { "A" } True) ] + - location: 55 (remaining gas: 1039962.379 units remaining) + [ True ] + - location: 51 (remaining gas: 1039962.349 units remaining) + [ { "A" } + True ] + - location: 56 (remaining gas: 1039962.339 units remaining) + [ { "A" } + { "A" } + True ] + - location: 46 (remaining gas: 1039962.309 units remaining) + [ "B" @elt + { "A" } + { "A" } + True ] + - location: 57 (remaining gas: 1039962.124 units remaining) + [ False + { "A" } + True ] + - location: 58 (remaining gas: 1039962.109 units remaining) + [ { "A" } + True ] + - location: 60 (remaining gas: 1039962.099 units remaining) + [ True + { "A" } ] + - location: 58 (remaining gas: 1039962.069 units remaining) + [ False + True + { "A" } ] + - location: 61 (remaining gas: 1039962.049 units remaining) + [ False + { "A" } ] + - location: 62 (remaining gas: 1039962.039 units remaining) + [ { "A" } + False ] + - location: 63 (remaining gas: 1039962.024 units remaining) + [ (Pair { "A" } False) ] + - location: 40 (remaining gas: 1039962.009 units remaining) + [ (Pair { "A" } False) ] + - location: 64 (remaining gas: 1039961.999 units remaining) + [ False ] + - location: 65 (remaining gas: 1039961.984 units remaining) + [ (Some False) ] + - location: 66 (remaining gas: 1039961.969 units remaining) + [ {} + (Some False) ] + - location: 68 (remaining gas: 1039961.954 units remaining) + [ (Pair {} (Some False)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" new file mode 100644 index 000000000000..c44d0bfe137e --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"B\" ; \"asdf\" ; \"C\" }.4360bbe5d0.out" @@ -0,0 +1,410 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" })-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039962.499 units remaining) + [ (Pair (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) None) ] + - location: 12 (remaining gas: 1039962.489 units remaining) + [ (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter ] + - location: 13 (remaining gas: 1039962.479 units remaining) + [ (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter + (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter ] + - location: 14 (remaining gas: 1039962.469 units remaining) + [ { "B" ; "B" ; "asdf" ; "C" } + (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter ] + - location: 15 (remaining gas: 1039962.454 units remaining) + [ (Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" }) @parameter ] + - location: 17 (remaining gas: 1039962.444 units remaining) + [ { "B" ; "C" ; "asdf" } ] + - location: 15 (remaining gas: 1039962.414 units remaining) + [ { "B" ; "B" ; "asdf" ; "C" } + { "B" ; "C" ; "asdf" } ] + - location: 18 (remaining gas: 1039962.194 units remaining) + [ {} + { "B" ; "B" ; "asdf" ; "C" } + { "B" ; "C" ; "asdf" } ] + - location: 20 (remaining gas: 1039962.184 units remaining) + [ { "B" ; "B" ; "asdf" ; "C" } + {} + { "B" ; "C" ; "asdf" } ] + - location: 21 (remaining gas: 1039962.184 units remaining) + [ "B" @elt + {} + { "B" ; "C" ; "asdf" } ] + - location: 23 (remaining gas: 1039962.169 units remaining) + [ (Pair "B" {}) + { "B" ; "C" ; "asdf" } ] + - location: 24 (remaining gas: 1039962.159 units remaining) + [ (Pair "B" {}) + (Pair "B" {}) + { "B" ; "C" ; "asdf" } ] + - location: 25 (remaining gas: 1039962.149 units remaining) + [ "B" @elt + (Pair "B" {}) + { "B" ; "C" ; "asdf" } ] + - location: 26 (remaining gas: 1039962.134 units remaining) + [ (Pair "B" {}) + { "B" ; "C" ; "asdf" } ] + - location: 28 (remaining gas: 1039962.124 units remaining) + [ {} + { "B" ; "C" ; "asdf" } ] + - location: 26 (remaining gas: 1039962.094 units remaining) + [ "B" @elt + {} + { "B" ; "C" ; "asdf" } ] + - location: 29 (remaining gas: 1039962.084 units remaining) + [ True + "B" @elt + {} + { "B" ; "C" ; "asdf" } ] + - location: 32 (remaining gas: 1039962.074 units remaining) + [ "B" @elt + True + {} + { "B" ; "C" ; "asdf" } ] + - location: 33 (remaining gas: 1039961.874 units remaining) + [ { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 21 (remaining gas: 1039961.859 units remaining) + [ "B" @elt + { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 23 (remaining gas: 1039961.844 units remaining) + [ (Pair "B" { "B" }) + { "B" ; "C" ; "asdf" } ] + - location: 24 (remaining gas: 1039961.834 units remaining) + [ (Pair "B" { "B" }) + (Pair "B" { "B" }) + { "B" ; "C" ; "asdf" } ] + - location: 25 (remaining gas: 1039961.824 units remaining) + [ "B" @elt + (Pair "B" { "B" }) + { "B" ; "C" ; "asdf" } ] + - location: 26 (remaining gas: 1039961.809 units remaining) + [ (Pair "B" { "B" }) + { "B" ; "C" ; "asdf" } ] + - location: 28 (remaining gas: 1039961.799 units remaining) + [ { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 26 (remaining gas: 1039961.769 units remaining) + [ "B" @elt + { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 29 (remaining gas: 1039961.759 units remaining) + [ True + "B" @elt + { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 32 (remaining gas: 1039961.749 units remaining) + [ "B" @elt + True + { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 33 (remaining gas: 1039961.479 units remaining) + [ { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 21 (remaining gas: 1039961.464 units remaining) + [ "asdf" @elt + { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 23 (remaining gas: 1039961.449 units remaining) + [ (Pair "asdf" { "B" }) + { "B" ; "C" ; "asdf" } ] + - location: 24 (remaining gas: 1039961.439 units remaining) + [ (Pair "asdf" { "B" }) + (Pair "asdf" { "B" }) + { "B" ; "C" ; "asdf" } ] + - location: 25 (remaining gas: 1039961.429 units remaining) + [ "asdf" @elt + (Pair "asdf" { "B" }) + { "B" ; "C" ; "asdf" } ] + - location: 26 (remaining gas: 1039961.414 units remaining) + [ (Pair "asdf" { "B" }) + { "B" ; "C" ; "asdf" } ] + - location: 28 (remaining gas: 1039961.404 units remaining) + [ { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 26 (remaining gas: 1039961.374 units remaining) + [ "asdf" @elt + { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 29 (remaining gas: 1039961.364 units remaining) + [ True + "asdf" @elt + { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 32 (remaining gas: 1039961.354 units remaining) + [ "asdf" @elt + True + { "B" } + { "B" ; "C" ; "asdf" } ] + - location: 33 (remaining gas: 1039961.084 units remaining) + [ { "B" ; "asdf" } + { "B" ; "C" ; "asdf" } ] + - location: 21 (remaining gas: 1039961.069 units remaining) + [ "C" @elt + { "B" ; "asdf" } + { "B" ; "C" ; "asdf" } ] + - location: 23 (remaining gas: 1039961.054 units remaining) + [ (Pair "C" { "B" ; "asdf" }) + { "B" ; "C" ; "asdf" } ] + - location: 24 (remaining gas: 1039961.044 units remaining) + [ (Pair "C" { "B" ; "asdf" }) + (Pair "C" { "B" ; "asdf" }) + { "B" ; "C" ; "asdf" } ] + - location: 25 (remaining gas: 1039961.034 units remaining) + [ "C" @elt + (Pair "C" { "B" ; "asdf" }) + { "B" ; "C" ; "asdf" } ] + - location: 26 (remaining gas: 1039961.019 units remaining) + [ (Pair "C" { "B" ; "asdf" }) + { "B" ; "C" ; "asdf" } ] + - location: 28 (remaining gas: 1039961.009 units remaining) + [ { "B" ; "asdf" } + { "B" ; "C" ; "asdf" } ] + - location: 26 (remaining gas: 1039960.979 units remaining) + [ "C" @elt + { "B" ; "asdf" } + { "B" ; "C" ; "asdf" } ] + - location: 29 (remaining gas: 1039960.969 units remaining) + [ True + "C" @elt + { "B" ; "asdf" } + { "B" ; "C" ; "asdf" } ] + - location: 32 (remaining gas: 1039960.959 units remaining) + [ "C" @elt + True + { "B" ; "asdf" } + { "B" ; "C" ; "asdf" } ] + - location: 33 (remaining gas: 1039960.619 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } ] + - location: 21 (remaining gas: 1039960.604 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } ] + - location: 34 (remaining gas: 1039960.594 units remaining) + [ True + { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } ] + - location: 37 (remaining gas: 1039960.584 units remaining) + [ { "B" ; "C" ; "asdf" } + True + { "B" ; "C" ; "asdf" } ] + - location: 38 (remaining gas: 1039960.569 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) + { "B" ; "C" ; "asdf" } ] + - location: 39 (remaining gas: 1039960.559 units remaining) + [ { "B" ; "C" ; "asdf" } + (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 40 (remaining gas: 1039960.559 units remaining) + [ "B" @elt + (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 42 (remaining gas: 1039960.544 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 43 (remaining gas: 1039960.534 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 44 (remaining gas: 1039960.524 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 45 (remaining gas: 1039960.514 units remaining) + [ "B" @elt + (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 46 (remaining gas: 1039960.499 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 49 (remaining gas: 1039960.489 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 50 (remaining gas: 1039960.479 units remaining) + [ { "B" ; "C" ; "asdf" } + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 51 (remaining gas: 1039960.464 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 54 (remaining gas: 1039960.454 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 55 (remaining gas: 1039960.444 units remaining) + [ True ] + - location: 51 (remaining gas: 1039960.414 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 56 (remaining gas: 1039960.404 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 46 (remaining gas: 1039960.374 units remaining) + [ "B" @elt + { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 57 (remaining gas: 1039960.154 units remaining) + [ True + { "B" ; "C" ; "asdf" } + True ] + - location: 58 (remaining gas: 1039960.139 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 60 (remaining gas: 1039960.129 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 58 (remaining gas: 1039960.099 units remaining) + [ True + True + { "B" ; "C" ; "asdf" } ] + - location: 61 (remaining gas: 1039960.079 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 62 (remaining gas: 1039960.069 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 63 (remaining gas: 1039960.054 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 40 (remaining gas: 1039960.039 units remaining) + [ "C" @elt + (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 42 (remaining gas: 1039960.024 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 43 (remaining gas: 1039960.014 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 44 (remaining gas: 1039960.004 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 45 (remaining gas: 1039959.994 units remaining) + [ "C" @elt + (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 46 (remaining gas: 1039959.979 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 49 (remaining gas: 1039959.969 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 50 (remaining gas: 1039959.959 units remaining) + [ { "B" ; "C" ; "asdf" } + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 51 (remaining gas: 1039959.944 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 54 (remaining gas: 1039959.934 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 55 (remaining gas: 1039959.924 units remaining) + [ True ] + - location: 51 (remaining gas: 1039959.894 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 56 (remaining gas: 1039959.884 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 46 (remaining gas: 1039959.854 units remaining) + [ "C" @elt + { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 57 (remaining gas: 1039959.634 units remaining) + [ True + { "B" ; "C" ; "asdf" } + True ] + - location: 58 (remaining gas: 1039959.619 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 60 (remaining gas: 1039959.609 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 58 (remaining gas: 1039959.579 units remaining) + [ True + True + { "B" ; "C" ; "asdf" } ] + - location: 61 (remaining gas: 1039959.559 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 62 (remaining gas: 1039959.549 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 63 (remaining gas: 1039959.534 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 40 (remaining gas: 1039959.519 units remaining) + [ "asdf" @elt + (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 42 (remaining gas: 1039959.504 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 43 (remaining gas: 1039959.494 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 44 (remaining gas: 1039959.484 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 45 (remaining gas: 1039959.474 units remaining) + [ "asdf" @elt + (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 46 (remaining gas: 1039959.459 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 49 (remaining gas: 1039959.449 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 50 (remaining gas: 1039959.439 units remaining) + [ { "B" ; "C" ; "asdf" } + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 51 (remaining gas: 1039959.424 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 54 (remaining gas: 1039959.414 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 55 (remaining gas: 1039959.404 units remaining) + [ True ] + - location: 51 (remaining gas: 1039959.374 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 56 (remaining gas: 1039959.364 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 46 (remaining gas: 1039959.334 units remaining) + [ "asdf" @elt + { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 57 (remaining gas: 1039959.114 units remaining) + [ True + { "B" ; "C" ; "asdf" } + True ] + - location: 58 (remaining gas: 1039959.099 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 60 (remaining gas: 1039959.089 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 58 (remaining gas: 1039959.059 units remaining) + [ True + True + { "B" ; "C" ; "asdf" } ] + - location: 61 (remaining gas: 1039959.039 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 62 (remaining gas: 1039959.029 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 63 (remaining gas: 1039959.014 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 40 (remaining gas: 1039958.999 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 64 (remaining gas: 1039958.989 units remaining) + [ True ] + - location: 65 (remaining gas: 1039958.974 units remaining) + [ (Some True) ] + - location: 66 (remaining gas: 1039958.959 units remaining) + [ {} + (Some True) ] + - location: 68 (remaining gas: 1039958.944 units remaining) + [ (Pair {} (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" new file mode 100644 index 000000000000..dc49c27995b1 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" ; \"C\" ; \"asdf\" } { \"B\".ff6e4785ee.out" @@ -0,0 +1,437 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" })-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039962.499 units remaining) + [ (Pair (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) None) ] + - location: 12 (remaining gas: 1039962.489 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter ] + - location: 13 (remaining gas: 1039962.479 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter + (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter ] + - location: 14 (remaining gas: 1039962.469 units remaining) + [ { "B" ; "C" ; "asdf" } + (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter ] + - location: 15 (remaining gas: 1039962.454 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" }) @parameter ] + - location: 17 (remaining gas: 1039962.444 units remaining) + [ { "B" ; "B" ; "asdf" ; "C" } ] + - location: 15 (remaining gas: 1039962.414 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 18 (remaining gas: 1039962.194 units remaining) + [ {} + { "B" ; "C" ; "asdf" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 20 (remaining gas: 1039962.184 units remaining) + [ { "B" ; "C" ; "asdf" } + {} + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 21 (remaining gas: 1039962.184 units remaining) + [ "B" @elt + {} + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 23 (remaining gas: 1039962.169 units remaining) + [ (Pair "B" {}) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 24 (remaining gas: 1039962.159 units remaining) + [ (Pair "B" {}) + (Pair "B" {}) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 25 (remaining gas: 1039962.149 units remaining) + [ "B" @elt + (Pair "B" {}) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 26 (remaining gas: 1039962.134 units remaining) + [ (Pair "B" {}) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 28 (remaining gas: 1039962.124 units remaining) + [ {} + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 26 (remaining gas: 1039962.094 units remaining) + [ "B" @elt + {} + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 29 (remaining gas: 1039962.084 units remaining) + [ True + "B" @elt + {} + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 32 (remaining gas: 1039962.074 units remaining) + [ "B" @elt + True + {} + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 33 (remaining gas: 1039961.874 units remaining) + [ { "B" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 21 (remaining gas: 1039961.859 units remaining) + [ "C" @elt + { "B" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 23 (remaining gas: 1039961.844 units remaining) + [ (Pair "C" { "B" }) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 24 (remaining gas: 1039961.834 units remaining) + [ (Pair "C" { "B" }) + (Pair "C" { "B" }) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 25 (remaining gas: 1039961.824 units remaining) + [ "C" @elt + (Pair "C" { "B" }) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 26 (remaining gas: 1039961.809 units remaining) + [ (Pair "C" { "B" }) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 28 (remaining gas: 1039961.799 units remaining) + [ { "B" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 26 (remaining gas: 1039961.769 units remaining) + [ "C" @elt + { "B" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 29 (remaining gas: 1039961.759 units remaining) + [ True + "C" @elt + { "B" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 32 (remaining gas: 1039961.749 units remaining) + [ "C" @elt + True + { "B" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 33 (remaining gas: 1039961.479 units remaining) + [ { "B" ; "C" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 21 (remaining gas: 1039961.464 units remaining) + [ "asdf" @elt + { "B" ; "C" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 23 (remaining gas: 1039961.449 units remaining) + [ (Pair "asdf" { "B" ; "C" }) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 24 (remaining gas: 1039961.439 units remaining) + [ (Pair "asdf" { "B" ; "C" }) + (Pair "asdf" { "B" ; "C" }) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 25 (remaining gas: 1039961.429 units remaining) + [ "asdf" @elt + (Pair "asdf" { "B" ; "C" }) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 26 (remaining gas: 1039961.414 units remaining) + [ (Pair "asdf" { "B" ; "C" }) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 28 (remaining gas: 1039961.404 units remaining) + [ { "B" ; "C" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 26 (remaining gas: 1039961.374 units remaining) + [ "asdf" @elt + { "B" ; "C" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 29 (remaining gas: 1039961.364 units remaining) + [ True + "asdf" @elt + { "B" ; "C" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 32 (remaining gas: 1039961.354 units remaining) + [ "asdf" @elt + True + { "B" ; "C" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 33 (remaining gas: 1039961.014 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 21 (remaining gas: 1039960.999 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 34 (remaining gas: 1039960.989 units remaining) + [ True + { "B" ; "C" ; "asdf" } + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 37 (remaining gas: 1039960.979 units remaining) + [ { "B" ; "C" ; "asdf" } + True + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 38 (remaining gas: 1039960.964 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) + { "B" ; "B" ; "asdf" ; "C" } ] + - location: 39 (remaining gas: 1039960.954 units remaining) + [ { "B" ; "B" ; "asdf" ; "C" } + (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 40 (remaining gas: 1039960.954 units remaining) + [ "B" @elt + (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 42 (remaining gas: 1039960.939 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 43 (remaining gas: 1039960.929 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 44 (remaining gas: 1039960.919 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 45 (remaining gas: 1039960.909 units remaining) + [ "B" @elt + (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 46 (remaining gas: 1039960.894 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 49 (remaining gas: 1039960.884 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 50 (remaining gas: 1039960.874 units remaining) + [ { "B" ; "C" ; "asdf" } + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 51 (remaining gas: 1039960.859 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 54 (remaining gas: 1039960.849 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 55 (remaining gas: 1039960.839 units remaining) + [ True ] + - location: 51 (remaining gas: 1039960.809 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 56 (remaining gas: 1039960.799 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 46 (remaining gas: 1039960.769 units remaining) + [ "B" @elt + { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 57 (remaining gas: 1039960.549 units remaining) + [ True + { "B" ; "C" ; "asdf" } + True ] + - location: 58 (remaining gas: 1039960.534 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 60 (remaining gas: 1039960.524 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 58 (remaining gas: 1039960.494 units remaining) + [ True + True + { "B" ; "C" ; "asdf" } ] + - location: 61 (remaining gas: 1039960.474 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 62 (remaining gas: 1039960.464 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 63 (remaining gas: 1039960.449 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 40 (remaining gas: 1039960.434 units remaining) + [ "B" @elt + (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 42 (remaining gas: 1039960.419 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 43 (remaining gas: 1039960.409 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 44 (remaining gas: 1039960.399 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 45 (remaining gas: 1039960.389 units remaining) + [ "B" @elt + (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 46 (remaining gas: 1039960.374 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 49 (remaining gas: 1039960.364 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 50 (remaining gas: 1039960.354 units remaining) + [ { "B" ; "C" ; "asdf" } + (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 51 (remaining gas: 1039960.339 units remaining) + [ (Pair "B" { "B" ; "C" ; "asdf" } True) ] + - location: 54 (remaining gas: 1039960.329 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 55 (remaining gas: 1039960.319 units remaining) + [ True ] + - location: 51 (remaining gas: 1039960.289 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 56 (remaining gas: 1039960.279 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 46 (remaining gas: 1039960.249 units remaining) + [ "B" @elt + { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 57 (remaining gas: 1039960.029 units remaining) + [ True + { "B" ; "C" ; "asdf" } + True ] + - location: 58 (remaining gas: 1039960.014 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 60 (remaining gas: 1039960.004 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 58 (remaining gas: 1039959.974 units remaining) + [ True + True + { "B" ; "C" ; "asdf" } ] + - location: 61 (remaining gas: 1039959.954 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 62 (remaining gas: 1039959.944 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 63 (remaining gas: 1039959.929 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 40 (remaining gas: 1039959.914 units remaining) + [ "asdf" @elt + (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 42 (remaining gas: 1039959.899 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 43 (remaining gas: 1039959.889 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 44 (remaining gas: 1039959.879 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 45 (remaining gas: 1039959.869 units remaining) + [ "asdf" @elt + (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 46 (remaining gas: 1039959.854 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 49 (remaining gas: 1039959.844 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 50 (remaining gas: 1039959.834 units remaining) + [ { "B" ; "C" ; "asdf" } + (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 51 (remaining gas: 1039959.819 units remaining) + [ (Pair "asdf" { "B" ; "C" ; "asdf" } True) ] + - location: 54 (remaining gas: 1039959.809 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 55 (remaining gas: 1039959.799 units remaining) + [ True ] + - location: 51 (remaining gas: 1039959.769 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 56 (remaining gas: 1039959.759 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 46 (remaining gas: 1039959.729 units remaining) + [ "asdf" @elt + { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 57 (remaining gas: 1039959.509 units remaining) + [ True + { "B" ; "C" ; "asdf" } + True ] + - location: 58 (remaining gas: 1039959.494 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 60 (remaining gas: 1039959.484 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 58 (remaining gas: 1039959.454 units remaining) + [ True + True + { "B" ; "C" ; "asdf" } ] + - location: 61 (remaining gas: 1039959.434 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 62 (remaining gas: 1039959.424 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 63 (remaining gas: 1039959.409 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 40 (remaining gas: 1039959.394 units remaining) + [ "C" @elt + (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 42 (remaining gas: 1039959.379 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 43 (remaining gas: 1039959.369 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 44 (remaining gas: 1039959.359 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 45 (remaining gas: 1039959.349 units remaining) + [ "C" @elt + (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 46 (remaining gas: 1039959.334 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 49 (remaining gas: 1039959.324 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 50 (remaining gas: 1039959.314 units remaining) + [ { "B" ; "C" ; "asdf" } + (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 51 (remaining gas: 1039959.299 units remaining) + [ (Pair "C" { "B" ; "C" ; "asdf" } True) ] + - location: 54 (remaining gas: 1039959.289 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 55 (remaining gas: 1039959.279 units remaining) + [ True ] + - location: 51 (remaining gas: 1039959.249 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 56 (remaining gas: 1039959.239 units remaining) + [ { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 46 (remaining gas: 1039959.209 units remaining) + [ "C" @elt + { "B" ; "C" ; "asdf" } + { "B" ; "C" ; "asdf" } + True ] + - location: 57 (remaining gas: 1039958.989 units remaining) + [ True + { "B" ; "C" ; "asdf" } + True ] + - location: 58 (remaining gas: 1039958.974 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 60 (remaining gas: 1039958.964 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 58 (remaining gas: 1039958.934 units remaining) + [ True + True + { "B" ; "C" ; "asdf" } ] + - location: 61 (remaining gas: 1039958.914 units remaining) + [ True + { "B" ; "C" ; "asdf" } ] + - location: 62 (remaining gas: 1039958.904 units remaining) + [ { "B" ; "C" ; "asdf" } + True ] + - location: 63 (remaining gas: 1039958.889 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 40 (remaining gas: 1039958.874 units remaining) + [ (Pair { "B" ; "C" ; "asdf" } True) ] + - location: 64 (remaining gas: 1039958.864 units remaining) + [ True ] + - location: 65 (remaining gas: 1039958.849 units remaining) + [ (Some True) ] + - location: 66 (remaining gas: 1039958.834 units remaining) + [ {} + (Some True) ] + - location: 68 (remaining gas: 1039958.819 units remaining) + [ (Pair {} (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" } { \"B\" })-(Some True)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" } { \"B\" })-(Some True)].out" new file mode 100644 index 000000000000..197c63eff07f --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"B\" } { \"B\" })-(Some True)].out" @@ -0,0 +1,166 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "B" } { "B" })-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039963.179 units remaining) + [ (Pair (Pair { "B" } { "B" }) None) ] + - location: 12 (remaining gas: 1039963.169 units remaining) + [ (Pair { "B" } { "B" }) @parameter ] + - location: 13 (remaining gas: 1039963.159 units remaining) + [ (Pair { "B" } { "B" }) @parameter + (Pair { "B" } { "B" }) @parameter ] + - location: 14 (remaining gas: 1039963.149 units remaining) + [ { "B" } + (Pair { "B" } { "B" }) @parameter ] + - location: 15 (remaining gas: 1039963.134 units remaining) + [ (Pair { "B" } { "B" }) @parameter ] + - location: 17 (remaining gas: 1039963.124 units remaining) + [ { "B" } ] + - location: 15 (remaining gas: 1039963.094 units remaining) + [ { "B" } + { "B" } ] + - location: 18 (remaining gas: 1039962.874 units remaining) + [ {} + { "B" } + { "B" } ] + - location: 20 (remaining gas: 1039962.864 units remaining) + [ { "B" } + {} + { "B" } ] + - location: 21 (remaining gas: 1039962.864 units remaining) + [ "B" @elt + {} + { "B" } ] + - location: 23 (remaining gas: 1039962.849 units remaining) + [ (Pair "B" {}) + { "B" } ] + - location: 24 (remaining gas: 1039962.839 units remaining) + [ (Pair "B" {}) + (Pair "B" {}) + { "B" } ] + - location: 25 (remaining gas: 1039962.829 units remaining) + [ "B" @elt + (Pair "B" {}) + { "B" } ] + - location: 26 (remaining gas: 1039962.814 units remaining) + [ (Pair "B" {}) + { "B" } ] + - location: 28 (remaining gas: 1039962.804 units remaining) + [ {} + { "B" } ] + - location: 26 (remaining gas: 1039962.774 units remaining) + [ "B" @elt + {} + { "B" } ] + - location: 29 (remaining gas: 1039962.764 units remaining) + [ True + "B" @elt + {} + { "B" } ] + - location: 32 (remaining gas: 1039962.754 units remaining) + [ "B" @elt + True + {} + { "B" } ] + - location: 33 (remaining gas: 1039962.554 units remaining) + [ { "B" } + { "B" } ] + - location: 21 (remaining gas: 1039962.539 units remaining) + [ { "B" } + { "B" } ] + - location: 34 (remaining gas: 1039962.529 units remaining) + [ True + { "B" } + { "B" } ] + - location: 37 (remaining gas: 1039962.519 units remaining) + [ { "B" } + True + { "B" } ] + - location: 38 (remaining gas: 1039962.504 units remaining) + [ (Pair { "B" } True) + { "B" } ] + - location: 39 (remaining gas: 1039962.494 units remaining) + [ { "B" } + (Pair { "B" } True) ] + - location: 40 (remaining gas: 1039962.494 units remaining) + [ "B" @elt + (Pair { "B" } True) ] + - location: 42 (remaining gas: 1039962.479 units remaining) + [ (Pair "B" { "B" } True) ] + - location: 43 (remaining gas: 1039962.469 units remaining) + [ (Pair "B" { "B" } True) + (Pair "B" { "B" } True) ] + - location: 44 (remaining gas: 1039962.459 units remaining) + [ (Pair "B" { "B" } True) + (Pair "B" { "B" } True) + (Pair "B" { "B" } True) ] + - location: 45 (remaining gas: 1039962.449 units remaining) + [ "B" @elt + (Pair "B" { "B" } True) + (Pair "B" { "B" } True) ] + - location: 46 (remaining gas: 1039962.434 units remaining) + [ (Pair "B" { "B" } True) + (Pair "B" { "B" } True) ] + - location: 49 (remaining gas: 1039962.424 units remaining) + [ (Pair { "B" } True) + (Pair "B" { "B" } True) ] + - location: 50 (remaining gas: 1039962.414 units remaining) + [ { "B" } + (Pair "B" { "B" } True) ] + - location: 51 (remaining gas: 1039962.399 units remaining) + [ (Pair "B" { "B" } True) ] + - location: 54 (remaining gas: 1039962.389 units remaining) + [ (Pair { "B" } True) ] + - location: 55 (remaining gas: 1039962.379 units remaining) + [ True ] + - location: 51 (remaining gas: 1039962.349 units remaining) + [ { "B" } + True ] + - location: 56 (remaining gas: 1039962.339 units remaining) + [ { "B" } + { "B" } + True ] + - location: 46 (remaining gas: 1039962.309 units remaining) + [ "B" @elt + { "B" } + { "B" } + True ] + - location: 57 (remaining gas: 1039962.124 units remaining) + [ True + { "B" } + True ] + - location: 58 (remaining gas: 1039962.109 units remaining) + [ { "B" } + True ] + - location: 60 (remaining gas: 1039962.099 units remaining) + [ True + { "B" } ] + - location: 58 (remaining gas: 1039962.069 units remaining) + [ True + True + { "B" } ] + - location: 61 (remaining gas: 1039962.049 units remaining) + [ True + { "B" } ] + - location: 62 (remaining gas: 1039962.039 units remaining) + [ { "B" } + True ] + - location: 63 (remaining gas: 1039962.024 units remaining) + [ (Pair { "B" } True) ] + - location: 40 (remaining gas: 1039962.009 units remaining) + [ (Pair { "B" } True) ] + - location: 64 (remaining gas: 1039961.999 units remaining) + [ True ] + - location: 65 (remaining gas: 1039961.984 units remaining) + [ (Some True) ] + - location: 66 (remaining gas: 1039961.969 units remaining) + [ {} + (Some True) ] + - location: 68 (remaining gas: 1039961.954 units remaining) + [ (Pair {} (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"c\" } { \"B\" })-(Some False)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"c\" } { \"B\" })-(Some False)].out" new file mode 100644 index 000000000000..4dab6b7ac088 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { \"c\" } { \"B\" })-(Some False)].out" @@ -0,0 +1,166 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair { "c" } { "B" })-(Some False)] + +storage + (Some False) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039963.179 units remaining) + [ (Pair (Pair { "c" } { "B" }) None) ] + - location: 12 (remaining gas: 1039963.169 units remaining) + [ (Pair { "c" } { "B" }) @parameter ] + - location: 13 (remaining gas: 1039963.159 units remaining) + [ (Pair { "c" } { "B" }) @parameter + (Pair { "c" } { "B" }) @parameter ] + - location: 14 (remaining gas: 1039963.149 units remaining) + [ { "c" } + (Pair { "c" } { "B" }) @parameter ] + - location: 15 (remaining gas: 1039963.134 units remaining) + [ (Pair { "c" } { "B" }) @parameter ] + - location: 17 (remaining gas: 1039963.124 units remaining) + [ { "B" } ] + - location: 15 (remaining gas: 1039963.094 units remaining) + [ { "c" } + { "B" } ] + - location: 18 (remaining gas: 1039962.874 units remaining) + [ {} + { "c" } + { "B" } ] + - location: 20 (remaining gas: 1039962.864 units remaining) + [ { "c" } + {} + { "B" } ] + - location: 21 (remaining gas: 1039962.864 units remaining) + [ "c" @elt + {} + { "B" } ] + - location: 23 (remaining gas: 1039962.849 units remaining) + [ (Pair "c" {}) + { "B" } ] + - location: 24 (remaining gas: 1039962.839 units remaining) + [ (Pair "c" {}) + (Pair "c" {}) + { "B" } ] + - location: 25 (remaining gas: 1039962.829 units remaining) + [ "c" @elt + (Pair "c" {}) + { "B" } ] + - location: 26 (remaining gas: 1039962.814 units remaining) + [ (Pair "c" {}) + { "B" } ] + - location: 28 (remaining gas: 1039962.804 units remaining) + [ {} + { "B" } ] + - location: 26 (remaining gas: 1039962.774 units remaining) + [ "c" @elt + {} + { "B" } ] + - location: 29 (remaining gas: 1039962.764 units remaining) + [ True + "c" @elt + {} + { "B" } ] + - location: 32 (remaining gas: 1039962.754 units remaining) + [ "c" @elt + True + {} + { "B" } ] + - location: 33 (remaining gas: 1039962.554 units remaining) + [ { "c" } + { "B" } ] + - location: 21 (remaining gas: 1039962.539 units remaining) + [ { "c" } + { "B" } ] + - location: 34 (remaining gas: 1039962.529 units remaining) + [ True + { "c" } + { "B" } ] + - location: 37 (remaining gas: 1039962.519 units remaining) + [ { "c" } + True + { "B" } ] + - location: 38 (remaining gas: 1039962.504 units remaining) + [ (Pair { "c" } True) + { "B" } ] + - location: 39 (remaining gas: 1039962.494 units remaining) + [ { "B" } + (Pair { "c" } True) ] + - location: 40 (remaining gas: 1039962.494 units remaining) + [ "B" @elt + (Pair { "c" } True) ] + - location: 42 (remaining gas: 1039962.479 units remaining) + [ (Pair "B" { "c" } True) ] + - location: 43 (remaining gas: 1039962.469 units remaining) + [ (Pair "B" { "c" } True) + (Pair "B" { "c" } True) ] + - location: 44 (remaining gas: 1039962.459 units remaining) + [ (Pair "B" { "c" } True) + (Pair "B" { "c" } True) + (Pair "B" { "c" } True) ] + - location: 45 (remaining gas: 1039962.449 units remaining) + [ "B" @elt + (Pair "B" { "c" } True) + (Pair "B" { "c" } True) ] + - location: 46 (remaining gas: 1039962.434 units remaining) + [ (Pair "B" { "c" } True) + (Pair "B" { "c" } True) ] + - location: 49 (remaining gas: 1039962.424 units remaining) + [ (Pair { "c" } True) + (Pair "B" { "c" } True) ] + - location: 50 (remaining gas: 1039962.414 units remaining) + [ { "c" } + (Pair "B" { "c" } True) ] + - location: 51 (remaining gas: 1039962.399 units remaining) + [ (Pair "B" { "c" } True) ] + - location: 54 (remaining gas: 1039962.389 units remaining) + [ (Pair { "c" } True) ] + - location: 55 (remaining gas: 1039962.379 units remaining) + [ True ] + - location: 51 (remaining gas: 1039962.349 units remaining) + [ { "c" } + True ] + - location: 56 (remaining gas: 1039962.339 units remaining) + [ { "c" } + { "c" } + True ] + - location: 46 (remaining gas: 1039962.309 units remaining) + [ "B" @elt + { "c" } + { "c" } + True ] + - location: 57 (remaining gas: 1039962.124 units remaining) + [ False + { "c" } + True ] + - location: 58 (remaining gas: 1039962.109 units remaining) + [ { "c" } + True ] + - location: 60 (remaining gas: 1039962.099 units remaining) + [ True + { "c" } ] + - location: 58 (remaining gas: 1039962.069 units remaining) + [ False + True + { "c" } ] + - location: 61 (remaining gas: 1039962.049 units remaining) + [ False + { "c" } ] + - location: 62 (remaining gas: 1039962.039 units remaining) + [ { "c" } + False ] + - location: 63 (remaining gas: 1039962.024 units remaining) + [ (Pair { "c" } False) ] + - location: 40 (remaining gas: 1039962.009 units remaining) + [ (Pair { "c" } False) ] + - location: 64 (remaining gas: 1039961.999 units remaining) + [ False ] + - location: 65 (remaining gas: 1039961.984 units remaining) + [ (Some False) ] + - location: 66 (remaining gas: 1039961.969 units remaining) + [ {} + (Some False) ] + - location: 68 (remaining gas: 1039961.954 units remaining) + [ (Pair {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)].out new file mode 100644 index 000000000000..8c83513a868c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)].out @@ -0,0 +1,63 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contains_all.tz-None-(Pair {} {})-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039963.427 units remaining) + [ (Pair (Pair {} {}) None) ] + - location: 12 (remaining gas: 1039963.417 units remaining) + [ (Pair {} {}) @parameter ] + - location: 13 (remaining gas: 1039963.407 units remaining) + [ (Pair {} {}) @parameter + (Pair {} {}) @parameter ] + - location: 14 (remaining gas: 1039963.397 units remaining) + [ {} + (Pair {} {}) @parameter ] + - location: 15 (remaining gas: 1039963.382 units remaining) + [ (Pair {} {}) @parameter ] + - location: 17 (remaining gas: 1039963.372 units remaining) + [ {} ] + - location: 15 (remaining gas: 1039963.342 units remaining) + [ {} + {} ] + - location: 18 (remaining gas: 1039963.122 units remaining) + [ {} + {} + {} ] + - location: 20 (remaining gas: 1039963.112 units remaining) + [ {} + {} + {} ] + - location: 21 (remaining gas: 1039963.112 units remaining) + [ {} + {} ] + - location: 34 (remaining gas: 1039963.102 units remaining) + [ True + {} + {} ] + - location: 37 (remaining gas: 1039963.092 units remaining) + [ {} + True + {} ] + - location: 38 (remaining gas: 1039963.077 units remaining) + [ (Pair {} True) + {} ] + - location: 39 (remaining gas: 1039963.067 units remaining) + [ {} + (Pair {} True) ] + - location: 40 (remaining gas: 1039963.067 units remaining) + [ (Pair {} True) ] + - location: 64 (remaining gas: 1039963.057 units remaining) + [ True ] + - location: 65 (remaining gas: 1039963.042 units remaining) + [ (Some True) ] + - location: 66 (remaining gas: 1039963.027 units remaining) + [ {} + (Some True) ] + - location: 68 (remaining gas: 1039963.012 units remaining) + [ (Pair {} (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contract.tz-Unit-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contract.tz-Unit-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" new file mode 100644 index 000000000000..d6b635359adc --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[contract.tz-Unit-\"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5\"-Unit].out" @@ -0,0 +1,29 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[contract.tz-Unit-"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039340.345 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" Unit) ] + - location: 7 (remaining gas: 1039340.335 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter ] + - location: 8 (remaining gas: 1039340.085 units remaining) + [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter.contract ] + - location: 11 (remaining gas: 1039340.075 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter.contract.some ] + - location: 11 (remaining gas: 1039340.060 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @parameter.contract.some ] + - location: 17 (remaining gas: 1039340.050 units remaining) + [ ] + - location: 18 (remaining gas: 1039340.040 units remaining) + [ Unit ] + - location: 19 (remaining gas: 1039340.025 units remaining) + [ {} + Unit ] + - location: 21 (remaining gas: 1039340.010 units remaining) + [ (Pair {} Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" new file mode 100644 index 000000000000..56f33bb0882b --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some \"KT1Mjjcb6tmSsLm7Cb3.c3984fbc14.out" @@ -0,0 +1,49 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[create_contract.tz-None-Unit-(Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm")] + +storage + (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") +emitted operations + Internal origination: + From: KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi + Credit: ꜩ0.05 + Script: + { parameter unit ; storage unit ; code { CDR ; NIL operation ; PAIR } } + Initial storage: Unit + No delegate for this contract + big_map diff + + trace + - location: 8 (remaining gas: 1039984.194 units remaining) + [ (Pair Unit None) ] + - location: 8 (remaining gas: 1039984.184 units remaining) + [ ] + - location: 9 (remaining gas: 1039984.174 units remaining) + [ Unit ] + - location: 10 (remaining gas: 1039984.159 units remaining) + [ 50000 @amount + Unit ] + - location: 11 (remaining gas: 1039984.144 units remaining) + [ None + 50000 @amount + Unit ] + - location: 13 (remaining gas: 1039983.538 units remaining) + [ 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b + "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm" ] + - location: 25 (remaining gas: 1039983.523 units remaining) + [ "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm" ] + - location: 27 (remaining gas: 1039983.508 units remaining) + [ (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] + - location: 28 (remaining gas: 1039983.493 units remaining) + [ {} + (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] + - location: 25 (remaining gas: 1039983.463 units remaining) + [ 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b + {} + (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] + - location: 30 (remaining gas: 1039983.448 units remaining) + [ { 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b } + (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm") ] + - location: 31 (remaining gas: 1039983.433 units remaining) + [ (Pair { 0x011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600000002d08603000000001c02000000170500036c0501036c050202000000080317053d036d034200000002030b } + (Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair \"1970-01-01T00:03:20Z\" \"19.90e9215d17.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair \"1970-01-01T00:03:20Z\" \"19.90e9215d17.out" new file mode 100644 index 000000000000..bc28b1cdc720 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair \"1970-01-01T00:03:20Z\" \"19.90e9215d17.out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z")-200] + +storage + 200 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039991.353 units remaining) + [ (Pair (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") 111) ] + - location: 9 (remaining gas: 1039991.343 units remaining) + [ (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 10 (remaining gas: 1039991.333 units remaining) + [ (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter + (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 11 (remaining gas: 1039991.323 units remaining) + [ "1970-01-01T00:03:20Z" + (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 12 (remaining gas: 1039991.308 units remaining) + [ (Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 14 (remaining gas: 1039991.298 units remaining) + [ "1970-01-01T00:00:00Z" ] + - location: 12 (remaining gas: 1039991.268 units remaining) + [ "1970-01-01T00:03:20Z" + "1970-01-01T00:00:00Z" ] + - location: 15 (remaining gas: 1039991.213 units remaining) + [ 200 ] + - location: 16 (remaining gas: 1039991.198 units remaining) + [ {} + 200 ] + - location: 18 (remaining gas: 1039991.183 units remaining) + [ (Pair {} 200) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0].out new file mode 100644 index 000000000000..438ed9200f1f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0].out @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 0)-0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039991.553 units remaining) + [ (Pair (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") 111) ] + - location: 9 (remaining gas: 1039991.543 units remaining) + [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 10 (remaining gas: 1039991.533 units remaining) + [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter + (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 11 (remaining gas: 1039991.523 units remaining) + [ "1970-01-01T00:00:00Z" + (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 12 (remaining gas: 1039991.508 units remaining) + [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 14 (remaining gas: 1039991.498 units remaining) + [ "1970-01-01T00:00:00Z" ] + - location: 12 (remaining gas: 1039991.468 units remaining) + [ "1970-01-01T00:00:00Z" + "1970-01-01T00:00:00Z" ] + - location: 15 (remaining gas: 1039991.413 units remaining) + [ 0 ] + - location: 16 (remaining gas: 1039991.398 units remaining) + [ {} + 0 ] + - location: 18 (remaining gas: 1039991.383 units remaining) + [ (Pair {} 0) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1].out new file mode 100644 index 000000000000..158119a92ce9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1].out @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 0 1)--1] + +storage + -1 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039991.553 units remaining) + [ (Pair (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") 111) ] + - location: 9 (remaining gas: 1039991.543 units remaining) + [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter ] + - location: 10 (remaining gas: 1039991.533 units remaining) + [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter + (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter ] + - location: 11 (remaining gas: 1039991.523 units remaining) + [ "1970-01-01T00:00:00Z" + (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter ] + - location: 12 (remaining gas: 1039991.508 units remaining) + [ (Pair "1970-01-01T00:00:00Z" "1970-01-01T00:00:01Z") @parameter ] + - location: 14 (remaining gas: 1039991.498 units remaining) + [ "1970-01-01T00:00:01Z" ] + - location: 12 (remaining gas: 1039991.468 units remaining) + [ "1970-01-01T00:00:00Z" + "1970-01-01T00:00:01Z" ] + - location: 15 (remaining gas: 1039991.413 units remaining) + [ -1 ] + - location: 16 (remaining gas: 1039991.398 units remaining) + [ {} + -1 ] + - location: 18 (remaining gas: 1039991.383 units remaining) + [ (Pair {} -1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1].out new file mode 100644 index 000000000000..e67644c0c7e8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1].out @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[diff_timestamps.tz-111-(Pair 1 0)-1] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039991.553 units remaining) + [ (Pair (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") 111) ] + - location: 9 (remaining gas: 1039991.543 units remaining) + [ (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 10 (remaining gas: 1039991.533 units remaining) + [ (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter + (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 11 (remaining gas: 1039991.523 units remaining) + [ "1970-01-01T00:00:01Z" + (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 12 (remaining gas: 1039991.508 units remaining) + [ (Pair "1970-01-01T00:00:01Z" "1970-01-01T00:00:00Z") @parameter ] + - location: 14 (remaining gas: 1039991.498 units remaining) + [ "1970-01-01T00:00:00Z" ] + - location: 12 (remaining gas: 1039991.468 units remaining) + [ "1970-01-01T00:00:01Z" + "1970-01-01T00:00:00Z" ] + - location: 15 (remaining gas: 1039991.413 units remaining) + [ 1 ] + - location: 16 (remaining gas: 1039991.398 units remaining) + [ {} + 1 ] + - location: 18 (remaining gas: 1039991.383 units remaining) + [ (Pair {} 1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out new file mode 100644 index 000000000000..c915ccc0a863 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pai.2794d4782e.out @@ -0,0 +1,3431 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pair 13 (Pair 12 (Pair 11 (Pair 10 (Pair 9 (Pair 8 (Pair 7 (Pair 6 (Pair 5 (Pair 4 (Pair 3 (Pair 2 1))))))))))))))))-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 24 (remaining gas: 1039868.707 units remaining) + [ (Pair (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) Unit) ] + - location: 24 (remaining gas: 1039868.697 units remaining) + [ (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 25 (remaining gas: 1039868.687 units remaining) + [ (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 27 (remaining gas: 1039868.677 units remaining) + [ 17 + (Pair 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 28 (remaining gas: 1039868.662 units remaining) + [ (Pair 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 30 (remaining gas: 1039868.652 units remaining) + [ 16 + (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 28 (remaining gas: 1039868.622 units remaining) + [ 17 + 16 + (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 31 (remaining gas: 1039868.574 units remaining) + [ (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 34 (remaining gas: 1039868.564 units remaining) + [ 15 + (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 31 (remaining gas: 1039868.539 units remaining) + [ 16 + 15 + (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 31 (remaining gas: 1039868.529 units remaining) + [ 17 + 16 + 15 + (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 31 (remaining gas: 1039868.529 units remaining) + [ 17 + 16 + 15 + (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 35 (remaining gas: 1039868.480 units remaining) + [ (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 38 (remaining gas: 1039868.470 units remaining) + [ 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 35 (remaining gas: 1039868.445 units remaining) + [ 15 + 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 35 (remaining gas: 1039868.435 units remaining) + [ 16 + 15 + 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 35 (remaining gas: 1039868.425 units remaining) + [ 17 + 16 + 15 + 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 35 (remaining gas: 1039868.425 units remaining) + [ 17 + 16 + 15 + 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 39 (remaining gas: 1039868.374 units remaining) + [ (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 42 (remaining gas: 1039868.364 units remaining) + [ 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 39 (remaining gas: 1039868.339 units remaining) + [ 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 39 (remaining gas: 1039868.329 units remaining) + [ 15 + 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 39 (remaining gas: 1039868.319 units remaining) + [ 16 + 15 + 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 39 (remaining gas: 1039868.309 units remaining) + [ 17 + 16 + 15 + 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 39 (remaining gas: 1039868.309 units remaining) + [ 17 + 16 + 15 + 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 43 (remaining gas: 1039868.257 units remaining) + [ (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 46 (remaining gas: 1039868.247 units remaining) + [ 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 43 (remaining gas: 1039868.222 units remaining) + [ 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 43 (remaining gas: 1039868.212 units remaining) + [ 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 43 (remaining gas: 1039868.202 units remaining) + [ 15 + 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 43 (remaining gas: 1039868.192 units remaining) + [ 16 + 15 + 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 43 (remaining gas: 1039868.182 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 43 (remaining gas: 1039868.182 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 47 (remaining gas: 1039868.128 units remaining) + [ (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 50 (remaining gas: 1039868.118 units remaining) + [ 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 47 (remaining gas: 1039868.093 units remaining) + [ 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 47 (remaining gas: 1039868.083 units remaining) + [ 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 47 (remaining gas: 1039868.073 units remaining) + [ 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 47 (remaining gas: 1039868.063 units remaining) + [ 15 + 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 47 (remaining gas: 1039868.053 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 47 (remaining gas: 1039868.043 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 47 (remaining gas: 1039868.043 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 51 (remaining gas: 1039867.988 units remaining) + [ (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 54 (remaining gas: 1039867.978 units remaining) + [ 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 51 (remaining gas: 1039867.953 units remaining) + [ 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 51 (remaining gas: 1039867.943 units remaining) + [ 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 51 (remaining gas: 1039867.933 units remaining) + [ 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 51 (remaining gas: 1039867.923 units remaining) + [ 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 51 (remaining gas: 1039867.913 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 51 (remaining gas: 1039867.903 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 51 (remaining gas: 1039867.893 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 51 (remaining gas: 1039867.893 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.835 units remaining) + [ (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 58 (remaining gas: 1039867.825 units remaining) + [ 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.800 units remaining) + [ 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.790 units remaining) + [ 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.780 units remaining) + [ 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.770 units remaining) + [ 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.760 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.750 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.740 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.730 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 55 (remaining gas: 1039867.730 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.671 units remaining) + [ (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 62 (remaining gas: 1039867.661 units remaining) + [ 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.636 units remaining) + [ 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.626 units remaining) + [ 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.616 units remaining) + [ 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.606 units remaining) + [ 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.596 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.586 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.576 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.566 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.556 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 59 (remaining gas: 1039867.556 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.495 units remaining) + [ (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 66 (remaining gas: 1039867.485 units remaining) + [ 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.460 units remaining) + [ 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.450 units remaining) + [ 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.440 units remaining) + [ 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.430 units remaining) + [ 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.420 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.410 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.400 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.390 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.380 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.370 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 63 (remaining gas: 1039867.370 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.308 units remaining) + [ (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 70 (remaining gas: 1039867.298 units remaining) + [ 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.273 units remaining) + [ 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.263 units remaining) + [ 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.253 units remaining) + [ 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.243 units remaining) + [ 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.233 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.223 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.213 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.203 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.193 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.183 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.173 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 67 (remaining gas: 1039867.173 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039867.109 units remaining) + [ (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 74 (remaining gas: 1039867.099 units remaining) + [ 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039867.074 units remaining) + [ 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039867.064 units remaining) + [ 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039867.054 units remaining) + [ 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039867.044 units remaining) + [ 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039867.034 units remaining) + [ 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039867.024 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039867.014 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039867.004 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039866.994 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039866.984 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039866.974 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039866.964 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 71 (remaining gas: 1039866.964 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.899 units remaining) + [ (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 78 (remaining gas: 1039866.889 units remaining) + [ 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.864 units remaining) + [ 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.854 units remaining) + [ 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.844 units remaining) + [ 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.834 units remaining) + [ 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.824 units remaining) + [ 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.814 units remaining) + [ 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.804 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.794 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.784 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.774 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.764 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.754 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.744 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 75 (remaining gas: 1039866.744 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.677 units remaining) + [ (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 82 (remaining gas: 1039866.667 units remaining) + [ 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.642 units remaining) + [ 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.632 units remaining) + [ 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.622 units remaining) + [ 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.612 units remaining) + [ 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.602 units remaining) + [ 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.592 units remaining) + [ 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.582 units remaining) + [ 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.572 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.562 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.552 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.542 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.532 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.522 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.512 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 79 (remaining gas: 1039866.512 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.444 units remaining) + [ (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 86 (remaining gas: 1039866.434 units remaining) + [ 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.409 units remaining) + [ 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.399 units remaining) + [ 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.389 units remaining) + [ 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.379 units remaining) + [ 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.369 units remaining) + [ 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.359 units remaining) + [ 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.349 units remaining) + [ 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.339 units remaining) + [ 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.329 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.319 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.309 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.299 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.289 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.279 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.269 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 83 (remaining gas: 1039866.269 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 87 (remaining gas: 1039866.209 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 89 (remaining gas: 1039866.143 units remaining) + [ 16 + 17 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 91 (remaining gas: 1039866.070 units remaining) + [ 15 + 16 + 17 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 93 (remaining gas: 1039865.991 units remaining) + [ 14 + 15 + 16 + 17 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 95 (remaining gas: 1039865.904 units remaining) + [ 13 + 14 + 15 + 16 + 17 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 97 (remaining gas: 1039865.811 units remaining) + [ 12 + 13 + 14 + 15 + 16 + 17 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 99 (remaining gas: 1039865.711 units remaining) + [ 11 + 12 + 13 + 14 + 15 + 16 + 17 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 101 (remaining gas: 1039865.605 units remaining) + [ 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 103 (remaining gas: 1039865.491 units remaining) + [ 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 105 (remaining gas: 1039865.371 units remaining) + [ 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 107 (remaining gas: 1039865.244 units remaining) + [ 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 109 (remaining gas: 1039865.111 units remaining) + [ 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 111 (remaining gas: 1039864.970 units remaining) + [ 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 113 (remaining gas: 1039864.823 units remaining) + [ 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 115 (remaining gas: 1039864.669 units remaining) + [ 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 117 (remaining gas: 1039864.509 units remaining) + [ 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 119 (remaining gas: 1039864.341 units remaining) + [ 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 121 (remaining gas: 1039864.281 units remaining) + [ 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 123 (remaining gas: 1039864.215 units remaining) + [ 2 + 1 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 125 (remaining gas: 1039864.142 units remaining) + [ 3 + 2 + 1 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 127 (remaining gas: 1039864.063 units remaining) + [ 4 + 3 + 2 + 1 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 129 (remaining gas: 1039863.976 units remaining) + [ 5 + 4 + 3 + 2 + 1 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 131 (remaining gas: 1039863.883 units remaining) + [ 6 + 5 + 4 + 3 + 2 + 1 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 133 (remaining gas: 1039863.783 units remaining) + [ 7 + 6 + 5 + 4 + 3 + 2 + 1 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 135 (remaining gas: 1039863.677 units remaining) + [ 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 137 (remaining gas: 1039863.563 units remaining) + [ 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 139 (remaining gas: 1039863.443 units remaining) + [ 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 141 (remaining gas: 1039863.316 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 12 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 143 (remaining gas: 1039863.183 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 13 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 145 (remaining gas: 1039863.042 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 14 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 147 (remaining gas: 1039862.895 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 15 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 149 (remaining gas: 1039862.741 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 16 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 151 (remaining gas: 1039862.581 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 17 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 153 (remaining gas: 1039862.413 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.345 units remaining) + [ 2 + 1 + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 159 (remaining gas: 1039862.330 units remaining) + [ (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.305 units remaining) + [ 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.295 units remaining) + [ 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.285 units remaining) + [ 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.275 units remaining) + [ 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.265 units remaining) + [ 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.255 units remaining) + [ 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.245 units remaining) + [ 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.235 units remaining) + [ 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.225 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.215 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.205 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.195 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.185 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.175 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.165 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 156 (remaining gas: 1039862.165 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039862.098 units remaining) + [ 3 + (Pair 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 163 (remaining gas: 1039862.083 units remaining) + [ (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039862.058 units remaining) + [ 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039862.048 units remaining) + [ 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039862.038 units remaining) + [ 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039862.028 units remaining) + [ 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039862.018 units remaining) + [ 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039862.008 units remaining) + [ 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039861.998 units remaining) + [ 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039861.988 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039861.978 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039861.968 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039861.958 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039861.948 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039861.938 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039861.928 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 160 (remaining gas: 1039861.928 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.863 units remaining) + [ 4 + (Pair 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 167 (remaining gas: 1039861.848 units remaining) + [ (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.823 units remaining) + [ 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.813 units remaining) + [ 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.803 units remaining) + [ 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.793 units remaining) + [ 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.783 units remaining) + [ 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.773 units remaining) + [ 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.763 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.753 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.743 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.733 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.723 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.713 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.703 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 164 (remaining gas: 1039861.703 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.639 units remaining) + [ 5 + (Pair 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 171 (remaining gas: 1039861.624 units remaining) + [ (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.599 units remaining) + [ 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.589 units remaining) + [ 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.579 units remaining) + [ 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.569 units remaining) + [ 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.559 units remaining) + [ 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.549 units remaining) + [ 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.539 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.529 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.519 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.509 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.499 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.489 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 168 (remaining gas: 1039861.489 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.427 units remaining) + [ 6 + (Pair 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 175 (remaining gas: 1039861.412 units remaining) + [ (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.387 units remaining) + [ 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.377 units remaining) + [ 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.367 units remaining) + [ 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.357 units remaining) + [ 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.347 units remaining) + [ 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.337 units remaining) + [ 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.327 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.317 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.307 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.297 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.287 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 172 (remaining gas: 1039861.287 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.226 units remaining) + [ 7 + (Pair 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 179 (remaining gas: 1039861.211 units remaining) + [ (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.186 units remaining) + [ 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.176 units remaining) + [ 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.166 units remaining) + [ 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.156 units remaining) + [ 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.146 units remaining) + [ 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.136 units remaining) + [ 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.126 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.116 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.106 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.096 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 176 (remaining gas: 1039861.096 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039861.037 units remaining) + [ 8 + (Pair 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 183 (remaining gas: 1039861.022 units remaining) + [ (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.997 units remaining) + [ 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.987 units remaining) + [ 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.977 units remaining) + [ 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.967 units remaining) + [ 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.957 units remaining) + [ 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.947 units remaining) + [ 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.937 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.927 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.917 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 180 (remaining gas: 1039860.917 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.859 units remaining) + [ 9 + (Pair 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 187 (remaining gas: 1039860.844 units remaining) + [ (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.819 units remaining) + [ 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.809 units remaining) + [ 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.799 units remaining) + [ 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.789 units remaining) + [ 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.779 units remaining) + [ 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.769 units remaining) + [ 15 + 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.759 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.749 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 184 (remaining gas: 1039860.749 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 188 (remaining gas: 1039860.694 units remaining) + [ 10 + (Pair 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 191 (remaining gas: 1039860.679 units remaining) + [ (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 188 (remaining gas: 1039860.654 units remaining) + [ 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 188 (remaining gas: 1039860.644 units remaining) + [ 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 188 (remaining gas: 1039860.634 units remaining) + [ 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 188 (remaining gas: 1039860.624 units remaining) + [ 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 188 (remaining gas: 1039860.614 units remaining) + [ 15 + 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 188 (remaining gas: 1039860.604 units remaining) + [ 16 + 15 + 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 188 (remaining gas: 1039860.594 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 188 (remaining gas: 1039860.594 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 192 (remaining gas: 1039860.540 units remaining) + [ 11 + (Pair 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 195 (remaining gas: 1039860.525 units remaining) + [ (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 192 (remaining gas: 1039860.500 units remaining) + [ 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 192 (remaining gas: 1039860.490 units remaining) + [ 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 192 (remaining gas: 1039860.480 units remaining) + [ 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 192 (remaining gas: 1039860.470 units remaining) + [ 15 + 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 192 (remaining gas: 1039860.460 units remaining) + [ 16 + 15 + 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 192 (remaining gas: 1039860.450 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 192 (remaining gas: 1039860.450 units remaining) + [ 17 + 16 + 15 + 14 + 13 + 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 196 (remaining gas: 1039860.398 units remaining) + [ 12 + (Pair 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 199 (remaining gas: 1039860.383 units remaining) + [ (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 196 (remaining gas: 1039860.358 units remaining) + [ 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 196 (remaining gas: 1039860.348 units remaining) + [ 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 196 (remaining gas: 1039860.338 units remaining) + [ 15 + 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 196 (remaining gas: 1039860.328 units remaining) + [ 16 + 15 + 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 196 (remaining gas: 1039860.318 units remaining) + [ 17 + 16 + 15 + 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 196 (remaining gas: 1039860.318 units remaining) + [ 17 + 16 + 15 + 14 + 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 200 (remaining gas: 1039860.267 units remaining) + [ 13 + (Pair 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 203 (remaining gas: 1039860.252 units remaining) + [ (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 200 (remaining gas: 1039860.227 units remaining) + [ 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 200 (remaining gas: 1039860.217 units remaining) + [ 15 + 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 200 (remaining gas: 1039860.207 units remaining) + [ 16 + 15 + 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 200 (remaining gas: 1039860.197 units remaining) + [ 17 + 16 + 15 + 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 200 (remaining gas: 1039860.197 units remaining) + [ 17 + 16 + 15 + 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 204 (remaining gas: 1039860.148 units remaining) + [ 14 + (Pair 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 207 (remaining gas: 1039860.133 units remaining) + [ (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 204 (remaining gas: 1039860.108 units remaining) + [ 15 + (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 204 (remaining gas: 1039860.098 units remaining) + [ 16 + 15 + (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 204 (remaining gas: 1039860.088 units remaining) + [ 17 + 16 + 15 + (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 204 (remaining gas: 1039860.088 units remaining) + [ 17 + 16 + 15 + (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 208 (remaining gas: 1039860.040 units remaining) + [ 15 + (Pair 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 211 (remaining gas: 1039860.025 units remaining) + [ (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 208 (remaining gas: 1039860 units remaining) + [ 16 + (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 208 (remaining gas: 1039859.990 units remaining) + [ 17 + 16 + (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 208 (remaining gas: 1039859.990 units remaining) + [ 17 + 16 + (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 212 (remaining gas: 1039859.975 units remaining) + [ 16 + (Pair 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 214 (remaining gas: 1039859.960 units remaining) + [ (Pair 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 212 (remaining gas: 1039859.930 units remaining) + [ 17 + (Pair 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 215 (remaining gas: 1039859.915 units remaining) + [ (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) + (Pair 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1) @parameter ] + - location: 218 (remaining gas: 1039859.160 units remaining) + [ 0 ] + - location: 219 (remaining gas: 1039859.145 units remaining) + [ True ] + - location: 220 (remaining gas: 1039859.135 units remaining) + [ ] + - location: 220 (remaining gas: 1039859.120 units remaining) + [ ] + - location: 226 (remaining gas: 1039859.110 units remaining) + [ Unit ] + - location: 227 (remaining gas: 1039859.095 units remaining) + [ {} + Unit ] + - location: 229 (remaining gas: 1039859.080 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out new file mode 100644 index 000000000000..ef1cd7ba980f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair .d473151c0f.out @@ -0,0 +1,3431 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dig_eq.tz-Unit-(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair 10 (Pair 14 (Pair 19 (Pair 9 (Pair 18 (Pair 6 (Pair 8 (Pair 11 (Pair 4 (Pair 13 (Pair 15 (Pair 5 1))))))))))))))))-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 24 (remaining gas: 1039868.707 units remaining) + [ (Pair (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) Unit) ] + - location: 24 (remaining gas: 1039868.697 units remaining) + [ (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 25 (remaining gas: 1039868.687 units remaining) + [ (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 27 (remaining gas: 1039868.677 units remaining) + [ 2 + (Pair 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 28 (remaining gas: 1039868.662 units remaining) + [ (Pair 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 30 (remaining gas: 1039868.652 units remaining) + [ 3 + (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 28 (remaining gas: 1039868.622 units remaining) + [ 2 + 3 + (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 31 (remaining gas: 1039868.574 units remaining) + [ (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 34 (remaining gas: 1039868.564 units remaining) + [ 12 + (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 31 (remaining gas: 1039868.539 units remaining) + [ 3 + 12 + (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 31 (remaining gas: 1039868.529 units remaining) + [ 2 + 3 + 12 + (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 31 (remaining gas: 1039868.529 units remaining) + [ 2 + 3 + 12 + (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 35 (remaining gas: 1039868.480 units remaining) + [ (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 38 (remaining gas: 1039868.470 units remaining) + [ 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 35 (remaining gas: 1039868.445 units remaining) + [ 12 + 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 35 (remaining gas: 1039868.435 units remaining) + [ 3 + 12 + 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 35 (remaining gas: 1039868.425 units remaining) + [ 2 + 3 + 12 + 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 35 (remaining gas: 1039868.425 units remaining) + [ 2 + 3 + 12 + 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 39 (remaining gas: 1039868.374 units remaining) + [ (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 42 (remaining gas: 1039868.364 units remaining) + [ 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 39 (remaining gas: 1039868.339 units remaining) + [ 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 39 (remaining gas: 1039868.329 units remaining) + [ 12 + 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 39 (remaining gas: 1039868.319 units remaining) + [ 3 + 12 + 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 39 (remaining gas: 1039868.309 units remaining) + [ 2 + 3 + 12 + 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 39 (remaining gas: 1039868.309 units remaining) + [ 2 + 3 + 12 + 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 43 (remaining gas: 1039868.257 units remaining) + [ (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 46 (remaining gas: 1039868.247 units remaining) + [ 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 43 (remaining gas: 1039868.222 units remaining) + [ 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 43 (remaining gas: 1039868.212 units remaining) + [ 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 43 (remaining gas: 1039868.202 units remaining) + [ 12 + 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 43 (remaining gas: 1039868.192 units remaining) + [ 3 + 12 + 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 43 (remaining gas: 1039868.182 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 43 (remaining gas: 1039868.182 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 47 (remaining gas: 1039868.128 units remaining) + [ (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 50 (remaining gas: 1039868.118 units remaining) + [ 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 47 (remaining gas: 1039868.093 units remaining) + [ 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 47 (remaining gas: 1039868.083 units remaining) + [ 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 47 (remaining gas: 1039868.073 units remaining) + [ 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 47 (remaining gas: 1039868.063 units remaining) + [ 12 + 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 47 (remaining gas: 1039868.053 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 47 (remaining gas: 1039868.043 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 47 (remaining gas: 1039868.043 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 51 (remaining gas: 1039867.988 units remaining) + [ (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 54 (remaining gas: 1039867.978 units remaining) + [ 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 51 (remaining gas: 1039867.953 units remaining) + [ 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 51 (remaining gas: 1039867.943 units remaining) + [ 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 51 (remaining gas: 1039867.933 units remaining) + [ 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 51 (remaining gas: 1039867.923 units remaining) + [ 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 51 (remaining gas: 1039867.913 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 51 (remaining gas: 1039867.903 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 51 (remaining gas: 1039867.893 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 51 (remaining gas: 1039867.893 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.835 units remaining) + [ (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 58 (remaining gas: 1039867.825 units remaining) + [ 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.800 units remaining) + [ 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.790 units remaining) + [ 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.780 units remaining) + [ 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.770 units remaining) + [ 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.760 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.750 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.740 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.730 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 55 (remaining gas: 1039867.730 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.671 units remaining) + [ (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 62 (remaining gas: 1039867.661 units remaining) + [ 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.636 units remaining) + [ 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.626 units remaining) + [ 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.616 units remaining) + [ 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.606 units remaining) + [ 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.596 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.586 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.576 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.566 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.556 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 59 (remaining gas: 1039867.556 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.495 units remaining) + [ (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 66 (remaining gas: 1039867.485 units remaining) + [ 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.460 units remaining) + [ 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.450 units remaining) + [ 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.440 units remaining) + [ 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.430 units remaining) + [ 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.420 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.410 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.400 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.390 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.380 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.370 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 63 (remaining gas: 1039867.370 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.308 units remaining) + [ (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 70 (remaining gas: 1039867.298 units remaining) + [ 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.273 units remaining) + [ 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.263 units remaining) + [ 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.253 units remaining) + [ 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.243 units remaining) + [ 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.233 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.223 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.213 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.203 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.193 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.183 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.173 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 67 (remaining gas: 1039867.173 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039867.109 units remaining) + [ (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 74 (remaining gas: 1039867.099 units remaining) + [ 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039867.074 units remaining) + [ 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039867.064 units remaining) + [ 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039867.054 units remaining) + [ 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039867.044 units remaining) + [ 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039867.034 units remaining) + [ 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039867.024 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039867.014 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039867.004 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039866.994 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039866.984 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039866.974 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039866.964 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 71 (remaining gas: 1039866.964 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.899 units remaining) + [ (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 78 (remaining gas: 1039866.889 units remaining) + [ 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.864 units remaining) + [ 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.854 units remaining) + [ 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.844 units remaining) + [ 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.834 units remaining) + [ 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.824 units remaining) + [ 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.814 units remaining) + [ 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.804 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.794 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.784 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.774 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.764 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.754 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.744 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 75 (remaining gas: 1039866.744 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.677 units remaining) + [ (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 82 (remaining gas: 1039866.667 units remaining) + [ 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.642 units remaining) + [ 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.632 units remaining) + [ 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.622 units remaining) + [ 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.612 units remaining) + [ 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.602 units remaining) + [ 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.592 units remaining) + [ 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.582 units remaining) + [ 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.572 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.562 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.552 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.542 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.532 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.522 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.512 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 79 (remaining gas: 1039866.512 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.444 units remaining) + [ (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 86 (remaining gas: 1039866.434 units remaining) + [ 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.409 units remaining) + [ 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.399 units remaining) + [ 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.389 units remaining) + [ 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.379 units remaining) + [ 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.369 units remaining) + [ 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.359 units remaining) + [ 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.349 units remaining) + [ 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.339 units remaining) + [ 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.329 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.319 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.309 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.299 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.289 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.279 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.269 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 83 (remaining gas: 1039866.269 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 87 (remaining gas: 1039866.209 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 89 (remaining gas: 1039866.143 units remaining) + [ 3 + 2 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 91 (remaining gas: 1039866.070 units remaining) + [ 12 + 3 + 2 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 93 (remaining gas: 1039865.991 units remaining) + [ 16 + 12 + 3 + 2 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 95 (remaining gas: 1039865.904 units remaining) + [ 10 + 16 + 12 + 3 + 2 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 97 (remaining gas: 1039865.811 units remaining) + [ 14 + 10 + 16 + 12 + 3 + 2 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 99 (remaining gas: 1039865.711 units remaining) + [ 19 + 14 + 10 + 16 + 12 + 3 + 2 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 101 (remaining gas: 1039865.605 units remaining) + [ 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 103 (remaining gas: 1039865.491 units remaining) + [ 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 105 (remaining gas: 1039865.371 units remaining) + [ 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 107 (remaining gas: 1039865.244 units remaining) + [ 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 109 (remaining gas: 1039865.111 units remaining) + [ 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 111 (remaining gas: 1039864.970 units remaining) + [ 4 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 113 (remaining gas: 1039864.823 units remaining) + [ 13 + 4 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 115 (remaining gas: 1039864.669 units remaining) + [ 15 + 13 + 4 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 117 (remaining gas: 1039864.509 units remaining) + [ 5 + 15 + 13 + 4 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 119 (remaining gas: 1039864.341 units remaining) + [ 1 + 5 + 15 + 13 + 4 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 121 (remaining gas: 1039864.281 units remaining) + [ 1 + 5 + 15 + 13 + 4 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 123 (remaining gas: 1039864.215 units remaining) + [ 5 + 1 + 15 + 13 + 4 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 125 (remaining gas: 1039864.142 units remaining) + [ 15 + 5 + 1 + 13 + 4 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 127 (remaining gas: 1039864.063 units remaining) + [ 13 + 15 + 5 + 1 + 4 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 129 (remaining gas: 1039863.976 units remaining) + [ 4 + 13 + 15 + 5 + 1 + 11 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 131 (remaining gas: 1039863.883 units remaining) + [ 11 + 4 + 13 + 15 + 5 + 1 + 8 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 133 (remaining gas: 1039863.783 units remaining) + [ 8 + 11 + 4 + 13 + 15 + 5 + 1 + 6 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 135 (remaining gas: 1039863.677 units remaining) + [ 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + 18 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 137 (remaining gas: 1039863.563 units remaining) + [ 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + 9 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 139 (remaining gas: 1039863.443 units remaining) + [ 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + 19 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 141 (remaining gas: 1039863.316 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + 14 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 143 (remaining gas: 1039863.183 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + 10 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 145 (remaining gas: 1039863.042 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + 16 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 147 (remaining gas: 1039862.895 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + 12 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 149 (remaining gas: 1039862.741 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + 3 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 151 (remaining gas: 1039862.581 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + 2 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 153 (remaining gas: 1039862.413 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.345 units remaining) + [ 5 + 1 + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 159 (remaining gas: 1039862.330 units remaining) + [ (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.305 units remaining) + [ 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.295 units remaining) + [ 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.285 units remaining) + [ 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.275 units remaining) + [ 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.265 units remaining) + [ 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.255 units remaining) + [ 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.245 units remaining) + [ 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.235 units remaining) + [ 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.225 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.215 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.205 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.195 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.185 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.175 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.165 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 156 (remaining gas: 1039862.165 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039862.098 units remaining) + [ 15 + (Pair 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 163 (remaining gas: 1039862.083 units remaining) + [ (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039862.058 units remaining) + [ 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039862.048 units remaining) + [ 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039862.038 units remaining) + [ 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039862.028 units remaining) + [ 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039862.018 units remaining) + [ 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039862.008 units remaining) + [ 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039861.998 units remaining) + [ 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039861.988 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039861.978 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039861.968 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039861.958 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039861.948 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039861.938 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039861.928 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 160 (remaining gas: 1039861.928 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.863 units remaining) + [ 13 + (Pair 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 167 (remaining gas: 1039861.848 units remaining) + [ (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.823 units remaining) + [ 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.813 units remaining) + [ 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.803 units remaining) + [ 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.793 units remaining) + [ 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.783 units remaining) + [ 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.773 units remaining) + [ 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.763 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.753 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.743 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.733 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.723 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.713 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.703 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 164 (remaining gas: 1039861.703 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.639 units remaining) + [ 4 + (Pair 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 171 (remaining gas: 1039861.624 units remaining) + [ (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.599 units remaining) + [ 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.589 units remaining) + [ 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.579 units remaining) + [ 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.569 units remaining) + [ 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.559 units remaining) + [ 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.549 units remaining) + [ 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.539 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.529 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.519 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.509 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.499 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.489 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 168 (remaining gas: 1039861.489 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.427 units remaining) + [ 11 + (Pair 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 175 (remaining gas: 1039861.412 units remaining) + [ (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.387 units remaining) + [ 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.377 units remaining) + [ 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.367 units remaining) + [ 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.357 units remaining) + [ 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.347 units remaining) + [ 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.337 units remaining) + [ 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.327 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.317 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.307 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.297 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.287 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 172 (remaining gas: 1039861.287 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.226 units remaining) + [ 8 + (Pair 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 179 (remaining gas: 1039861.211 units remaining) + [ (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.186 units remaining) + [ 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.176 units remaining) + [ 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.166 units remaining) + [ 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.156 units remaining) + [ 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.146 units remaining) + [ 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.136 units remaining) + [ 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.126 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.116 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.106 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.096 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 176 (remaining gas: 1039861.096 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039861.037 units remaining) + [ 6 + (Pair 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 183 (remaining gas: 1039861.022 units remaining) + [ (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.997 units remaining) + [ 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.987 units remaining) + [ 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.977 units remaining) + [ 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.967 units remaining) + [ 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.957 units remaining) + [ 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.947 units remaining) + [ 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.937 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.927 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.917 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 180 (remaining gas: 1039860.917 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.859 units remaining) + [ 18 + (Pair 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 187 (remaining gas: 1039860.844 units remaining) + [ (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.819 units remaining) + [ 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.809 units remaining) + [ 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.799 units remaining) + [ 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.789 units remaining) + [ 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.779 units remaining) + [ 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.769 units remaining) + [ 12 + 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.759 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.749 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 184 (remaining gas: 1039860.749 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 188 (remaining gas: 1039860.694 units remaining) + [ 9 + (Pair 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 191 (remaining gas: 1039860.679 units remaining) + [ (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 188 (remaining gas: 1039860.654 units remaining) + [ 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 188 (remaining gas: 1039860.644 units remaining) + [ 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 188 (remaining gas: 1039860.634 units remaining) + [ 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 188 (remaining gas: 1039860.624 units remaining) + [ 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 188 (remaining gas: 1039860.614 units remaining) + [ 12 + 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 188 (remaining gas: 1039860.604 units remaining) + [ 3 + 12 + 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 188 (remaining gas: 1039860.594 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 188 (remaining gas: 1039860.594 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 192 (remaining gas: 1039860.540 units remaining) + [ 19 + (Pair 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 195 (remaining gas: 1039860.525 units remaining) + [ (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 192 (remaining gas: 1039860.500 units remaining) + [ 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 192 (remaining gas: 1039860.490 units remaining) + [ 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 192 (remaining gas: 1039860.480 units remaining) + [ 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 192 (remaining gas: 1039860.470 units remaining) + [ 12 + 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 192 (remaining gas: 1039860.460 units remaining) + [ 3 + 12 + 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 192 (remaining gas: 1039860.450 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 192 (remaining gas: 1039860.450 units remaining) + [ 2 + 3 + 12 + 16 + 10 + 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 196 (remaining gas: 1039860.398 units remaining) + [ 14 + (Pair 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 199 (remaining gas: 1039860.383 units remaining) + [ (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 196 (remaining gas: 1039860.358 units remaining) + [ 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 196 (remaining gas: 1039860.348 units remaining) + [ 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 196 (remaining gas: 1039860.338 units remaining) + [ 12 + 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 196 (remaining gas: 1039860.328 units remaining) + [ 3 + 12 + 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 196 (remaining gas: 1039860.318 units remaining) + [ 2 + 3 + 12 + 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 196 (remaining gas: 1039860.318 units remaining) + [ 2 + 3 + 12 + 16 + 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 200 (remaining gas: 1039860.267 units remaining) + [ 10 + (Pair 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 203 (remaining gas: 1039860.252 units remaining) + [ (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 200 (remaining gas: 1039860.227 units remaining) + [ 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 200 (remaining gas: 1039860.217 units remaining) + [ 12 + 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 200 (remaining gas: 1039860.207 units remaining) + [ 3 + 12 + 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 200 (remaining gas: 1039860.197 units remaining) + [ 2 + 3 + 12 + 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 200 (remaining gas: 1039860.197 units remaining) + [ 2 + 3 + 12 + 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 204 (remaining gas: 1039860.148 units remaining) + [ 16 + (Pair 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 207 (remaining gas: 1039860.133 units remaining) + [ (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 204 (remaining gas: 1039860.108 units remaining) + [ 12 + (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 204 (remaining gas: 1039860.098 units remaining) + [ 3 + 12 + (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 204 (remaining gas: 1039860.088 units remaining) + [ 2 + 3 + 12 + (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 204 (remaining gas: 1039860.088 units remaining) + [ 2 + 3 + 12 + (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 208 (remaining gas: 1039860.040 units remaining) + [ 12 + (Pair 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 211 (remaining gas: 1039860.025 units remaining) + [ (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 208 (remaining gas: 1039860 units remaining) + [ 3 + (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 208 (remaining gas: 1039859.990 units remaining) + [ 2 + 3 + (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 208 (remaining gas: 1039859.990 units remaining) + [ 2 + 3 + (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 212 (remaining gas: 1039859.975 units remaining) + [ 3 + (Pair 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 214 (remaining gas: 1039859.960 units remaining) + [ (Pair 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 212 (remaining gas: 1039859.930 units remaining) + [ 2 + (Pair 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 215 (remaining gas: 1039859.915 units remaining) + [ (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) + (Pair 2 3 12 16 10 14 19 9 18 6 8 11 4 13 15 5 1) @parameter ] + - location: 218 (remaining gas: 1039859.160 units remaining) + [ 0 ] + - location: 219 (remaining gas: 1039859.145 units remaining) + [ True ] + - location: 220 (remaining gas: 1039859.135 units remaining) + [ ] + - location: 220 (remaining gas: 1039859.120 units remaining) + [ ] + - location: 226 (remaining gas: 1039859.110 units remaining) + [ Unit ] + - location: 227 (remaining gas: 1039859.095 units remaining) + [ {} + Unit ] + - location: 229 (remaining gas: 1039859.080 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out new file mode 100644 index 000000000000..abdd55127e74 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out @@ -0,0 +1,61 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dign.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5] + +storage + 5 +emitted operations + +big_map diff + +trace + - location: 15 (remaining gas: 1039987.170 units remaining) + [ (Pair (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) 0) ] + - location: 15 (remaining gas: 1039987.160 units remaining) + [ (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) @parameter ] + - location: 16 (remaining gas: 1039987.150 units remaining) + [ (Pair (Pair (Pair 1 2) 3) 4) + 5 ] + - location: 17 (remaining gas: 1039987.140 units remaining) + [ (Pair (Pair 1 2) 3) + 4 + 5 ] + - location: 18 (remaining gas: 1039987.130 units remaining) + [ (Pair 1 2) + 3 + 4 + 5 ] + - location: 19 (remaining gas: 1039987.120 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 20 (remaining gas: 1039987.033 units remaining) + [ 5 + 1 + 2 + 3 + 4 ] + - location: 22 (remaining gas: 1039987.018 units remaining) + [ 1 + 2 + 3 + 4 ] + - location: 24 (remaining gas: 1039987.008 units remaining) + [ 2 + 3 + 4 ] + - location: 25 (remaining gas: 1039986.998 units remaining) + [ 3 + 4 ] + - location: 26 (remaining gas: 1039986.988 units remaining) + [ 4 ] + - location: 27 (remaining gas: 1039986.978 units remaining) + [ ] + - location: 22 (remaining gas: 1039986.948 units remaining) + [ 5 ] + - location: 28 (remaining gas: 1039986.933 units remaining) + [ {} + 5 ] + - location: 30 (remaining gas: 1039986.918 units remaining) + [ (Pair {} 5) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out new file mode 100644 index 000000000000..151d7e05c7be --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)].out @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 1 1)-(Pair 1 2)] + +storage + (Pair 1 2) +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039990.758 units remaining) + [ (Pair (Pair 1 1) 0 0) ] + - location: 11 (remaining gas: 1039990.748 units remaining) + [ (Pair 1 1) @parameter ] + - location: 12 (remaining gas: 1039990.738 units remaining) + [ 1 + 1 ] + - location: 13 (remaining gas: 1039990.728 units remaining) + [ 1 + 1 + 1 ] + - location: 14 (remaining gas: 1039990.713 units remaining) + [ 1 + 1 ] + - location: 16 (remaining gas: 1039990.658 units remaining) + [ 2 ] + - location: 14 (remaining gas: 1039990.628 units remaining) + [ 1 + 2 ] + - location: 17 (remaining gas: 1039990.613 units remaining) + [ (Pair 1 2) ] + - location: 18 (remaining gas: 1039990.598 units remaining) + [ {} + (Pair 1 2) ] + - location: 20 (remaining gas: 1039990.583 units remaining) + [ (Pair {} 1 2) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out new file mode 100644 index 000000000000..0218b12b4a84 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)].out @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dip.tz-(Pair 0 0)-(Pair 15 9)-(Pair 15 24)] + +storage + (Pair 15 24) +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039990.758 units remaining) + [ (Pair (Pair 15 9) 0 0) ] + - location: 11 (remaining gas: 1039990.748 units remaining) + [ (Pair 15 9) @parameter ] + - location: 12 (remaining gas: 1039990.738 units remaining) + [ 15 + 9 ] + - location: 13 (remaining gas: 1039990.728 units remaining) + [ 15 + 15 + 9 ] + - location: 14 (remaining gas: 1039990.713 units remaining) + [ 15 + 9 ] + - location: 16 (remaining gas: 1039990.658 units remaining) + [ 24 ] + - location: 14 (remaining gas: 1039990.628 units remaining) + [ 15 + 24 ] + - location: 17 (remaining gas: 1039990.613 units remaining) + [ (Pair 15 24) ] + - location: 18 (remaining gas: 1039990.598 units remaining) + [ {} + (Pair 15 24) ] + - location: 20 (remaining gas: 1039990.583 units remaining) + [ (Pair {} 15 24) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out new file mode 100644 index 000000000000..80ff2c6ec1a5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6].out @@ -0,0 +1,93 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dipn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-6] + +storage + 6 +emitted operations + +big_map diff + +trace + - location: 15 (remaining gas: 1039986.010 units remaining) + [ (Pair (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) 0) ] + - location: 15 (remaining gas: 1039986 units remaining) + [ (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) @parameter ] + - location: 16 (remaining gas: 1039985.990 units remaining) + [ (Pair (Pair (Pair 1 2) 3) 4) + 5 ] + - location: 17 (remaining gas: 1039985.980 units remaining) + [ (Pair (Pair 1 2) 3) + 4 + 5 ] + - location: 18 (remaining gas: 1039985.970 units remaining) + [ (Pair 1 2) + 3 + 4 + 5 ] + - location: 19 (remaining gas: 1039985.960 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 20 (remaining gas: 1039985.908 units remaining) + [ ] + - location: 23 (remaining gas: 1039985.898 units remaining) + [ 6 ] + - location: 20 (remaining gas: 1039985.873 units remaining) + [ 5 + 6 ] + - location: 20 (remaining gas: 1039985.863 units remaining) + [ 4 + 5 + 6 ] + - location: 20 (remaining gas: 1039985.853 units remaining) + [ 3 + 4 + 5 + 6 ] + - location: 20 (remaining gas: 1039985.843 units remaining) + [ 2 + 3 + 4 + 5 + 6 ] + - location: 20 (remaining gas: 1039985.833 units remaining) + [ 1 + 2 + 3 + 4 + 5 + 6 ] + - location: 20 (remaining gas: 1039985.833 units remaining) + [ 1 + 2 + 3 + 4 + 5 + 6 ] + - location: 26 (remaining gas: 1039985.823 units remaining) + [ 2 + 3 + 4 + 5 + 6 ] + - location: 27 (remaining gas: 1039985.813 units remaining) + [ 3 + 4 + 5 + 6 ] + - location: 28 (remaining gas: 1039985.803 units remaining) + [ 4 + 5 + 6 ] + - location: 29 (remaining gas: 1039985.793 units remaining) + [ 5 + 6 ] + - location: 30 (remaining gas: 1039985.783 units remaining) + [ 6 ] + - location: 31 (remaining gas: 1039985.768 units remaining) + [ {} + 6 ] + - location: 33 (remaining gas: 1039985.753 units remaining) + [ (Pair {} 6) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out new file mode 100644 index 000000000000..3f38b3f3431d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5].out @@ -0,0 +1,39 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dropn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-5] + +storage + 5 +emitted operations + +big_map diff + +trace + - location: 15 (remaining gas: 1039990.347 units remaining) + [ (Pair (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) 0) ] + - location: 15 (remaining gas: 1039990.337 units remaining) + [ (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) @parameter ] + - location: 16 (remaining gas: 1039990.327 units remaining) + [ (Pair (Pair (Pair 1 2) 3) 4) + 5 ] + - location: 17 (remaining gas: 1039990.317 units remaining) + [ (Pair (Pair 1 2) 3) + 4 + 5 ] + - location: 18 (remaining gas: 1039990.307 units remaining) + [ (Pair 1 2) + 3 + 4 + 5 ] + - location: 19 (remaining gas: 1039990.297 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 20 (remaining gas: 1039990.227 units remaining) + [ 5 ] + - location: 22 (remaining gas: 1039990.212 units remaining) + [ {} + 5 ] + - location: 24 (remaining gas: 1039990.197 units remaining) + [ (Pair {} 5) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out new file mode 100644 index 000000000000..cbcd0a0ddeab --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1].out @@ -0,0 +1,57 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dugn.tz-0-(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)-1] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 15 (remaining gas: 1039987.936 units remaining) + [ (Pair (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) 0) ] + - location: 15 (remaining gas: 1039987.926 units remaining) + [ (Pair (Pair (Pair (Pair 1 2) 3) 4) 5) @parameter ] + - location: 16 (remaining gas: 1039987.916 units remaining) + [ (Pair (Pair (Pair 1 2) 3) 4) + 5 ] + - location: 17 (remaining gas: 1039987.906 units remaining) + [ (Pair (Pair 1 2) 3) + 4 + 5 ] + - location: 18 (remaining gas: 1039987.896 units remaining) + [ (Pair 1 2) + 3 + 4 + 5 ] + - location: 19 (remaining gas: 1039987.886 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 20 (remaining gas: 1039987.799 units remaining) + [ 2 + 3 + 4 + 5 + 1 ] + - location: 22 (remaining gas: 1039987.789 units remaining) + [ 3 + 4 + 5 + 1 ] + - location: 23 (remaining gas: 1039987.779 units remaining) + [ 4 + 5 + 1 ] + - location: 24 (remaining gas: 1039987.769 units remaining) + [ 5 + 1 ] + - location: 25 (remaining gas: 1039987.759 units remaining) + [ 1 ] + - location: 26 (remaining gas: 1039987.744 units remaining) + [ {} + 1 ] + - location: 28 (remaining gas: 1039987.729 units remaining) + [ (Pair {} 1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit].out new file mode 100644 index 000000000000..e67663195ffd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit].out @@ -0,0 +1,248 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[dup-n.tz-Unit-Unit-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039951.987 units remaining) + [ (Pair Unit Unit) ] + - location: 7 (remaining gas: 1039951.977 units remaining) + [ ] + - location: 8 (remaining gas: 1039951.967 units remaining) + [ 5 ] + - location: 11 (remaining gas: 1039951.957 units remaining) + [ 4 + 5 ] + - location: 14 (remaining gas: 1039951.947 units remaining) + [ 3 + 4 + 5 ] + - location: 17 (remaining gas: 1039951.937 units remaining) + [ 2 + 3 + 4 + 5 ] + - location: 20 (remaining gas: 1039951.927 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 23 (remaining gas: 1039951.906 units remaining) + [ 1 + 1 + 2 + 3 + 4 + 5 ] + - location: 25 (remaining gas: 1039951.896 units remaining) + [ 1 + 1 + 1 + 2 + 3 + 4 + 5 ] + - location: 30 (remaining gas: 1039951.861 units remaining) + [ 0 + 1 + 2 + 3 + 4 + 5 ] + - location: 31 (remaining gas: 1039951.846 units remaining) + [ True + 1 + 2 + 3 + 4 + 5 ] + - location: 32 (remaining gas: 1039951.836 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 32 (remaining gas: 1039951.821 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 38 (remaining gas: 1039951.799 units remaining) + [ 2 + 1 + 2 + 3 + 4 + 5 ] + - location: 40 (remaining gas: 1039951.789 units remaining) + [ 2 + 2 + 1 + 2 + 3 + 4 + 5 ] + - location: 45 (remaining gas: 1039951.754 units remaining) + [ 0 + 1 + 2 + 3 + 4 + 5 ] + - location: 46 (remaining gas: 1039951.739 units remaining) + [ True + 1 + 2 + 3 + 4 + 5 ] + - location: 47 (remaining gas: 1039951.729 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 47 (remaining gas: 1039951.714 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 53 (remaining gas: 1039951.691 units remaining) + [ 3 + 1 + 2 + 3 + 4 + 5 ] + - location: 55 (remaining gas: 1039951.681 units remaining) + [ 3 + 3 + 1 + 2 + 3 + 4 + 5 ] + - location: 60 (remaining gas: 1039951.646 units remaining) + [ 0 + 1 + 2 + 3 + 4 + 5 ] + - location: 61 (remaining gas: 1039951.631 units remaining) + [ True + 1 + 2 + 3 + 4 + 5 ] + - location: 62 (remaining gas: 1039951.621 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 62 (remaining gas: 1039951.606 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 68 (remaining gas: 1039951.582 units remaining) + [ 4 + 1 + 2 + 3 + 4 + 5 ] + - location: 70 (remaining gas: 1039951.572 units remaining) + [ 4 + 4 + 1 + 2 + 3 + 4 + 5 ] + - location: 75 (remaining gas: 1039951.537 units remaining) + [ 0 + 1 + 2 + 3 + 4 + 5 ] + - location: 76 (remaining gas: 1039951.522 units remaining) + [ True + 1 + 2 + 3 + 4 + 5 ] + - location: 77 (remaining gas: 1039951.512 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 77 (remaining gas: 1039951.497 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 83 (remaining gas: 1039951.472 units remaining) + [ 5 + 1 + 2 + 3 + 4 + 5 ] + - location: 85 (remaining gas: 1039951.462 units remaining) + [ 5 + 5 + 1 + 2 + 3 + 4 + 5 ] + - location: 90 (remaining gas: 1039951.427 units remaining) + [ 0 + 1 + 2 + 3 + 4 + 5 ] + - location: 91 (remaining gas: 1039951.412 units remaining) + [ True + 1 + 2 + 3 + 4 + 5 ] + - location: 92 (remaining gas: 1039951.402 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 92 (remaining gas: 1039951.387 units remaining) + [ 1 + 2 + 3 + 4 + 5 ] + - location: 98 (remaining gas: 1039951.315 units remaining) + [ ] + - location: 100 (remaining gas: 1039951.305 units remaining) + [ Unit ] + - location: 101 (remaining gas: 1039951.290 units remaining) + [ {} + Unit ] + - location: 103 (remaining gas: 1039951.275 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out new file mode 100644 index 000000000000..c79f2bac3360 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (S.ecc0e72cbb.out @@ -0,0 +1,142 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair -8 2)-(Pair (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0)))] + +storage + (Pair (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) +emitted operations + +big_map diff + +trace + - location: 25 (remaining gas: 1039969.963 units remaining) + [ (Pair (Pair -8 2) None None None None) ] + - location: 25 (remaining gas: 1039969.953 units remaining) + [ (Pair -8 2) @parameter ] + - location: 26 (remaining gas: 1039969.943 units remaining) + [ (Pair -8 2) @parameter + (Pair -8 2) @parameter ] + - location: 27 (remaining gas: 1039969.933 units remaining) + [ -8 + 2 + (Pair -8 2) @parameter ] + - location: 28 (remaining gas: 1039969.908 units remaining) + [ 8 + 2 + (Pair -8 2) @parameter ] + - location: 29 (remaining gas: 1039969.893 units remaining) + [ 2 + (Pair -8 2) @parameter ] + - location: 31 (remaining gas: 1039969.868 units remaining) + [ 2 + (Pair -8 2) @parameter ] + - location: 29 (remaining gas: 1039969.838 units remaining) + [ 8 + 2 + (Pair -8 2) @parameter ] + - location: 32 (remaining gas: 1039969.698 units remaining) + [ (Some (Pair 4 0)) + (Pair -8 2) @parameter ] + - location: 33 (remaining gas: 1039969.688 units remaining) + [ (Pair -8 2) @parameter + (Some (Pair 4 0)) ] + - location: 34 (remaining gas: 1039969.678 units remaining) + [ (Pair -8 2) @parameter + (Pair -8 2) @parameter + (Some (Pair 4 0)) ] + - location: 35 (remaining gas: 1039969.668 units remaining) + [ -8 + 2 + (Pair -8 2) @parameter + (Some (Pair 4 0)) ] + - location: 36 (remaining gas: 1039969.643 units remaining) + [ 8 + 2 + (Pair -8 2) @parameter + (Some (Pair 4 0)) ] + - location: 37 (remaining gas: 1039969.503 units remaining) + [ (Some (Pair 4 0)) + (Pair -8 2) @parameter + (Some (Pair 4 0)) ] + - location: 38 (remaining gas: 1039969.493 units remaining) + [ (Pair -8 2) @parameter + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 39 (remaining gas: 1039969.483 units remaining) + [ (Pair -8 2) @parameter + (Pair -8 2) @parameter + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 40 (remaining gas: 1039969.473 units remaining) + [ -8 + 2 + (Pair -8 2) @parameter + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 41 (remaining gas: 1039969.458 units remaining) + [ 2 + (Pair -8 2) @parameter + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 43 (remaining gas: 1039969.433 units remaining) + [ 2 + (Pair -8 2) @parameter + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 41 (remaining gas: 1039969.403 units remaining) + [ -8 + 2 + (Pair -8 2) @parameter + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 44 (remaining gas: 1039969.263 units remaining) + [ (Some (Pair -4 0)) + (Pair -8 2) @parameter + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 45 (remaining gas: 1039969.253 units remaining) + [ (Pair -8 2) @parameter + (Some (Pair -4 0)) + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 46 (remaining gas: 1039969.243 units remaining) + [ -8 + 2 + (Some (Pair -4 0)) + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 47 (remaining gas: 1039969.103 units remaining) + [ (Some (Pair -4 0)) + (Some (Pair -4 0)) + (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 49 (remaining gas: 1039969.055 units remaining) + [ (Some (Pair 4 0)) + (Some (Pair 4 0)) ] + - location: 52 (remaining gas: 1039969.040 units remaining) + [ (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] + - location: 49 (remaining gas: 1039969.015 units remaining) + [ (Some (Pair -4 0)) + (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] + - location: 49 (remaining gas: 1039969.005 units remaining) + [ (Some (Pair -4 0)) + (Some (Pair -4 0)) + (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] + - location: 49 (remaining gas: 1039969.005 units remaining) + [ (Some (Pair -4 0)) + (Some (Pair -4 0)) + (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] + - location: 53 (remaining gas: 1039968.990 units remaining) + [ (Some (Pair -4 0)) + (Pair (Some (Pair 4 0)) (Some (Pair 4 0))) ] + - location: 55 (remaining gas: 1039968.975 units remaining) + [ (Pair (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] + - location: 53 (remaining gas: 1039968.945 units remaining) + [ (Some (Pair -4 0)) + (Pair (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] + - location: 56 (remaining gas: 1039968.930 units remaining) + [ (Pair (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] + - location: 57 (remaining gas: 1039968.915 units remaining) + [ {} + (Pair (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] + - location: 59 (remaining gas: 1039968.900 units remaining) + [ (Pair {} (Some (Pair -4 0)) (Some (Pair -4 0)) (Some (Pair 4 0)) (Some (Pair 4 0))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (.3caea50555.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (.3caea50555.out new file mode 100644 index 000000000000..27086e5770e0 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (.3caea50555.out @@ -0,0 +1,142 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 -3)-(Pair (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1)))] + +storage + (Pair (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) +emitted operations + +big_map diff + +trace + - location: 25 (remaining gas: 1039969.963 units remaining) + [ (Pair (Pair 10 -3) None None None None) ] + - location: 25 (remaining gas: 1039969.953 units remaining) + [ (Pair 10 -3) @parameter ] + - location: 26 (remaining gas: 1039969.943 units remaining) + [ (Pair 10 -3) @parameter + (Pair 10 -3) @parameter ] + - location: 27 (remaining gas: 1039969.933 units remaining) + [ 10 + -3 + (Pair 10 -3) @parameter ] + - location: 28 (remaining gas: 1039969.908 units remaining) + [ 10 + -3 + (Pair 10 -3) @parameter ] + - location: 29 (remaining gas: 1039969.893 units remaining) + [ -3 + (Pair 10 -3) @parameter ] + - location: 31 (remaining gas: 1039969.868 units remaining) + [ 3 + (Pair 10 -3) @parameter ] + - location: 29 (remaining gas: 1039969.838 units remaining) + [ 10 + 3 + (Pair 10 -3) @parameter ] + - location: 32 (remaining gas: 1039969.698 units remaining) + [ (Some (Pair 3 1)) + (Pair 10 -3) @parameter ] + - location: 33 (remaining gas: 1039969.688 units remaining) + [ (Pair 10 -3) @parameter + (Some (Pair 3 1)) ] + - location: 34 (remaining gas: 1039969.678 units remaining) + [ (Pair 10 -3) @parameter + (Pair 10 -3) @parameter + (Some (Pair 3 1)) ] + - location: 35 (remaining gas: 1039969.668 units remaining) + [ 10 + -3 + (Pair 10 -3) @parameter + (Some (Pair 3 1)) ] + - location: 36 (remaining gas: 1039969.643 units remaining) + [ 10 + -3 + (Pair 10 -3) @parameter + (Some (Pair 3 1)) ] + - location: 37 (remaining gas: 1039969.503 units remaining) + [ (Some (Pair -3 1)) + (Pair 10 -3) @parameter + (Some (Pair 3 1)) ] + - location: 38 (remaining gas: 1039969.493 units remaining) + [ (Pair 10 -3) @parameter + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 39 (remaining gas: 1039969.483 units remaining) + [ (Pair 10 -3) @parameter + (Pair 10 -3) @parameter + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 40 (remaining gas: 1039969.473 units remaining) + [ 10 + -3 + (Pair 10 -3) @parameter + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 41 (remaining gas: 1039969.458 units remaining) + [ -3 + (Pair 10 -3) @parameter + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 43 (remaining gas: 1039969.433 units remaining) + [ 3 + (Pair 10 -3) @parameter + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 41 (remaining gas: 1039969.403 units remaining) + [ 10 + 3 + (Pair 10 -3) @parameter + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 44 (remaining gas: 1039969.263 units remaining) + [ (Some (Pair 3 1)) + (Pair 10 -3) @parameter + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 45 (remaining gas: 1039969.253 units remaining) + [ (Pair 10 -3) @parameter + (Some (Pair 3 1)) + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 46 (remaining gas: 1039969.243 units remaining) + [ 10 + -3 + (Some (Pair 3 1)) + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 47 (remaining gas: 1039969.103 units remaining) + [ (Some (Pair -3 1)) + (Some (Pair 3 1)) + (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 49 (remaining gas: 1039969.055 units remaining) + [ (Some (Pair -3 1)) + (Some (Pair 3 1)) ] + - location: 52 (remaining gas: 1039969.040 units remaining) + [ (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] + - location: 49 (remaining gas: 1039969.015 units remaining) + [ (Some (Pair 3 1)) + (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] + - location: 49 (remaining gas: 1039969.005 units remaining) + [ (Some (Pair -3 1)) + (Some (Pair 3 1)) + (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] + - location: 49 (remaining gas: 1039969.005 units remaining) + [ (Some (Pair -3 1)) + (Some (Pair 3 1)) + (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] + - location: 53 (remaining gas: 1039968.990 units remaining) + [ (Some (Pair 3 1)) + (Pair (Some (Pair -3 1)) (Some (Pair 3 1))) ] + - location: 55 (remaining gas: 1039968.975 units remaining) + [ (Pair (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] + - location: 53 (remaining gas: 1039968.945 units remaining) + [ (Some (Pair -3 1)) + (Pair (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] + - location: 56 (remaining gas: 1039968.930 units remaining) + [ (Pair (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] + - location: 57 (remaining gas: 1039968.915 units remaining) + [ {} + (Pair (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] + - location: 59 (remaining gas: 1039968.900 units remaining) + [ (Pair {} (Some (Pair -3 1)) (Some (Pair 3 1)) (Some (Pair -3 1)) (Some (Pair 3 1))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair No.f9448c04fb.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair No.f9448c04fb.out new file mode 100644 index 000000000000..6051aaea92a3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair No.f9448c04fb.out @@ -0,0 +1,142 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv.tz-(Pair None None None None)-(Pair 10 0)-(Pair None None None None)] + +storage + (Pair None None None None) +emitted operations + +big_map diff + +trace + - location: 25 (remaining gas: 1039969.963 units remaining) + [ (Pair (Pair 10 0) None None None None) ] + - location: 25 (remaining gas: 1039969.953 units remaining) + [ (Pair 10 0) @parameter ] + - location: 26 (remaining gas: 1039969.943 units remaining) + [ (Pair 10 0) @parameter + (Pair 10 0) @parameter ] + - location: 27 (remaining gas: 1039969.933 units remaining) + [ 10 + 0 + (Pair 10 0) @parameter ] + - location: 28 (remaining gas: 1039969.908 units remaining) + [ 10 + 0 + (Pair 10 0) @parameter ] + - location: 29 (remaining gas: 1039969.893 units remaining) + [ 0 + (Pair 10 0) @parameter ] + - location: 31 (remaining gas: 1039969.868 units remaining) + [ 0 + (Pair 10 0) @parameter ] + - location: 29 (remaining gas: 1039969.838 units remaining) + [ 10 + 0 + (Pair 10 0) @parameter ] + - location: 32 (remaining gas: 1039969.698 units remaining) + [ None + (Pair 10 0) @parameter ] + - location: 33 (remaining gas: 1039969.688 units remaining) + [ (Pair 10 0) @parameter + None ] + - location: 34 (remaining gas: 1039969.678 units remaining) + [ (Pair 10 0) @parameter + (Pair 10 0) @parameter + None ] + - location: 35 (remaining gas: 1039969.668 units remaining) + [ 10 + 0 + (Pair 10 0) @parameter + None ] + - location: 36 (remaining gas: 1039969.643 units remaining) + [ 10 + 0 + (Pair 10 0) @parameter + None ] + - location: 37 (remaining gas: 1039969.503 units remaining) + [ None + (Pair 10 0) @parameter + None ] + - location: 38 (remaining gas: 1039969.493 units remaining) + [ (Pair 10 0) @parameter + None + None ] + - location: 39 (remaining gas: 1039969.483 units remaining) + [ (Pair 10 0) @parameter + (Pair 10 0) @parameter + None + None ] + - location: 40 (remaining gas: 1039969.473 units remaining) + [ 10 + 0 + (Pair 10 0) @parameter + None + None ] + - location: 41 (remaining gas: 1039969.458 units remaining) + [ 0 + (Pair 10 0) @parameter + None + None ] + - location: 43 (remaining gas: 1039969.433 units remaining) + [ 0 + (Pair 10 0) @parameter + None + None ] + - location: 41 (remaining gas: 1039969.403 units remaining) + [ 10 + 0 + (Pair 10 0) @parameter + None + None ] + - location: 44 (remaining gas: 1039969.263 units remaining) + [ None + (Pair 10 0) @parameter + None + None ] + - location: 45 (remaining gas: 1039969.253 units remaining) + [ (Pair 10 0) @parameter + None + None + None ] + - location: 46 (remaining gas: 1039969.243 units remaining) + [ 10 + 0 + None + None + None ] + - location: 47 (remaining gas: 1039969.103 units remaining) + [ None + None + None + None ] + - location: 49 (remaining gas: 1039969.055 units remaining) + [ None + None ] + - location: 52 (remaining gas: 1039969.040 units remaining) + [ (Pair None None) ] + - location: 49 (remaining gas: 1039969.015 units remaining) + [ None + (Pair None None) ] + - location: 49 (remaining gas: 1039969.005 units remaining) + [ None + None + (Pair None None) ] + - location: 49 (remaining gas: 1039969.005 units remaining) + [ None + None + (Pair None None) ] + - location: 53 (remaining gas: 1039968.990 units remaining) + [ None + (Pair None None) ] + - location: 55 (remaining gas: 1039968.975 units remaining) + [ (Pair None None None) ] + - location: 53 (remaining gas: 1039968.945 units remaining) + [ None + (Pair None None None) ] + - location: 56 (remaining gas: 1039968.930 units remaining) + [ (Pair None None None None) ] + - location: 57 (remaining gas: 1039968.915 units remaining) + [ {} + (Pair None None None None) ] + - location: 59 (remaining gas: 1039968.900 units remaining) + [ (Pair {} None None None None) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)].out new file mode 100644 index 000000000000..b31a4a4d5a4f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)].out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 0))-(Left None)] + +storage + (Left None) +emitted operations + +big_map diff + +trace + - location: 19 (remaining gas: 1039981.901 units remaining) + [ (Pair (Pair 10 (Left 0)) (Left None)) ] + - location: 19 (remaining gas: 1039981.891 units remaining) + [ (Pair 10 (Left 0)) @parameter ] + - location: 20 (remaining gas: 1039981.881 units remaining) + [ 10 + (Left 0) ] + - location: 21 (remaining gas: 1039981.871 units remaining) + [ (Left 0) + 10 ] + - location: 22 (remaining gas: 1039981.861 units remaining) + [ 0 + 10 ] + - location: 24 (remaining gas: 1039981.851 units remaining) + [ 10 + 0 ] + - location: 25 (remaining gas: 1039981.711 units remaining) + [ None ] + - location: 26 (remaining gas: 1039981.696 units remaining) + [ (Left None) ] + - location: 22 (remaining gas: 1039981.681 units remaining) + [ (Left None) ] + - location: 39 (remaining gas: 1039981.666 units remaining) + [ {} + (Left None) ] + - location: 41 (remaining gas: 1039981.651 units remaining) + [ (Pair {} (Left None)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (So.f782cc1dec.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (So.f782cc1dec.out new file mode 100644 index 000000000000..bc587cb24256 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (So.f782cc1dec.out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 10))-(Left (Some (Pair 1 0)))] + +storage + (Left (Some (Pair 1 0))) +emitted operations + +big_map diff + +trace + - location: 19 (remaining gas: 1039981.901 units remaining) + [ (Pair (Pair 10 (Left 10)) (Left None)) ] + - location: 19 (remaining gas: 1039981.891 units remaining) + [ (Pair 10 (Left 10)) @parameter ] + - location: 20 (remaining gas: 1039981.881 units remaining) + [ 10 + (Left 10) ] + - location: 21 (remaining gas: 1039981.871 units remaining) + [ (Left 10) + 10 ] + - location: 22 (remaining gas: 1039981.861 units remaining) + [ 10 + 10 ] + - location: 24 (remaining gas: 1039981.851 units remaining) + [ 10 + 10 ] + - location: 25 (remaining gas: 1039981.711 units remaining) + [ (Some (Pair 1 0)) ] + - location: 26 (remaining gas: 1039981.696 units remaining) + [ (Left (Some (Pair 1 0))) ] + - location: 22 (remaining gas: 1039981.681 units remaining) + [ (Left (Some (Pair 1 0))) ] + - location: 39 (remaining gas: 1039981.666 units remaining) + [ {} + (Left (Some (Pair 1 0))) ] + - location: 41 (remaining gas: 1039981.651 units remaining) + [ (Pair {} (Left (Some (Pair 1 0)))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Som.016b4db96c.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Som.016b4db96c.out new file mode 100644 index 000000000000..45bb02f14157 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Som.016b4db96c.out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Left 3))-(Left (Some (Pair 3 1)))] + +storage + (Left (Some (Pair 3 1))) +emitted operations + +big_map diff + +trace + - location: 19 (remaining gas: 1039981.901 units remaining) + [ (Pair (Pair 10 (Left 3)) (Left None)) ] + - location: 19 (remaining gas: 1039981.891 units remaining) + [ (Pair 10 (Left 3)) @parameter ] + - location: 20 (remaining gas: 1039981.881 units remaining) + [ 10 + (Left 3) ] + - location: 21 (remaining gas: 1039981.871 units remaining) + [ (Left 3) + 10 ] + - location: 22 (remaining gas: 1039981.861 units remaining) + [ 3 + 10 ] + - location: 24 (remaining gas: 1039981.851 units remaining) + [ 10 + 3 ] + - location: 25 (remaining gas: 1039981.711 units remaining) + [ (Some (Pair 3 1)) ] + - location: 26 (remaining gas: 1039981.696 units remaining) + [ (Left (Some (Pair 3 1))) ] + - location: 22 (remaining gas: 1039981.681 units remaining) + [ (Left (Some (Pair 3 1))) ] + - location: 39 (remaining gas: 1039981.666 units remaining) + [ {} + (Left (Some (Pair 3 1))) ] + - location: 41 (remaining gas: 1039981.651 units remaining) + [ (Pair {} (Left (Some (Pair 3 1)))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)].out new file mode 100644 index 000000000000..194fa4dc850d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)].out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 0))-(Right None)] + +storage + (Right None) +emitted operations + +big_map diff + +trace + - location: 19 (remaining gas: 1039981.901 units remaining) + [ (Pair (Pair 10 (Right 0)) (Left None)) ] + - location: 19 (remaining gas: 1039981.891 units remaining) + [ (Pair 10 (Right 0)) @parameter ] + - location: 20 (remaining gas: 1039981.881 units remaining) + [ 10 + (Right 0) ] + - location: 21 (remaining gas: 1039981.871 units remaining) + [ (Right 0) + 10 ] + - location: 22 (remaining gas: 1039981.861 units remaining) + [ 0 + 10 ] + - location: 32 (remaining gas: 1039981.851 units remaining) + [ 10 + 0 ] + - location: 33 (remaining gas: 1039981.711 units remaining) + [ None ] + - location: 34 (remaining gas: 1039981.696 units remaining) + [ (Right None) ] + - location: 22 (remaining gas: 1039981.681 units remaining) + [ (Right None) ] + - location: 39 (remaining gas: 1039981.666 units remaining) + [ {} + (Right None) ] + - location: 41 (remaining gas: 1039981.651 units remaining) + [ (Pair {} (Right None)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (.e705a30e07.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (.e705a30e07.out new file mode 100644 index 000000000000..852f89144cce --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (.e705a30e07.out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 10))-(Right (Some (Pair 1 0)))] + +storage + (Right (Some (Pair 1 0))) +emitted operations + +big_map diff + +trace + - location: 19 (remaining gas: 1039981.901 units remaining) + [ (Pair (Pair 10 (Right 10)) (Left None)) ] + - location: 19 (remaining gas: 1039981.891 units remaining) + [ (Pair 10 (Right 10)) @parameter ] + - location: 20 (remaining gas: 1039981.881 units remaining) + [ 10 + (Right 10) ] + - location: 21 (remaining gas: 1039981.871 units remaining) + [ (Right 10) + 10 ] + - location: 22 (remaining gas: 1039981.861 units remaining) + [ 10 + 10 ] + - location: 32 (remaining gas: 1039981.851 units remaining) + [ 10 + 10 ] + - location: 33 (remaining gas: 1039981.711 units remaining) + [ (Some (Pair 1 0)) ] + - location: 34 (remaining gas: 1039981.696 units remaining) + [ (Right (Some (Pair 1 0))) ] + - location: 22 (remaining gas: 1039981.681 units remaining) + [ (Right (Some (Pair 1 0))) ] + - location: 39 (remaining gas: 1039981.666 units remaining) + [ {} + (Right (Some (Pair 1 0))) ] + - location: 41 (remaining gas: 1039981.651 units remaining) + [ (Pair {} (Right (Some (Pair 1 0)))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (S.44485eda6a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (S.44485eda6a.out new file mode 100644 index 000000000000..d62b27fed57a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (S.44485eda6a.out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 10 (Right 3))-(Right (Some (Pair 3 1)))] + +storage + (Right (Some (Pair 3 1))) +emitted operations + +big_map diff + +trace + - location: 19 (remaining gas: 1039981.901 units remaining) + [ (Pair (Pair 10 (Right 3)) (Left None)) ] + - location: 19 (remaining gas: 1039981.891 units remaining) + [ (Pair 10 (Right 3)) @parameter ] + - location: 20 (remaining gas: 1039981.881 units remaining) + [ 10 + (Right 3) ] + - location: 21 (remaining gas: 1039981.871 units remaining) + [ (Right 3) + 10 ] + - location: 22 (remaining gas: 1039981.861 units remaining) + [ 3 + 10 ] + - location: 32 (remaining gas: 1039981.851 units remaining) + [ 10 + 3 ] + - location: 33 (remaining gas: 1039981.711 units remaining) + [ (Some (Pair 3 1)) ] + - location: 34 (remaining gas: 1039981.696 units remaining) + [ (Right (Some (Pair 3 1))) ] + - location: 22 (remaining gas: 1039981.681 units remaining) + [ (Right (Some (Pair 3 1))) ] + - location: 39 (remaining gas: 1039981.666 units remaining) + [ {} + (Right (Some (Pair 3 1))) ] + - location: 41 (remaining gas: 1039981.651 units remaining) + [ (Pair {} (Right (Some (Pair 3 1)))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (S.8ab987af15.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (S.8ab987af15.out new file mode 100644 index 000000000000..8d96cfab11c5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (S.8ab987af15.out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ediv_mutez.tz-(Left None)-(Pair 5 (Right 10))-(Right (Some (Pair 0 5)))] + +storage + (Right (Some (Pair 0 5))) +emitted operations + +big_map diff + +trace + - location: 19 (remaining gas: 1039981.901 units remaining) + [ (Pair (Pair 5 (Right 10)) (Left None)) ] + - location: 19 (remaining gas: 1039981.891 units remaining) + [ (Pair 5 (Right 10)) @parameter ] + - location: 20 (remaining gas: 1039981.881 units remaining) + [ 5 + (Right 10) ] + - location: 21 (remaining gas: 1039981.871 units remaining) + [ (Right 10) + 5 ] + - location: 22 (remaining gas: 1039981.861 units remaining) + [ 10 + 5 ] + - location: 32 (remaining gas: 1039981.851 units remaining) + [ 5 + 10 ] + - location: 33 (remaining gas: 1039981.711 units remaining) + [ (Some (Pair 0 5)) ] + - location: 34 (remaining gas: 1039981.696 units remaining) + [ (Right (Some (Pair 0 5))) ] + - location: 22 (remaining gas: 1039981.681 units remaining) + [ (Right (Some (Pair 0 5))) ] + - location: 39 (remaining gas: 1039981.666 units remaining) + [ {} + (Right (Some (Pair 0 5))) ] + - location: 41 (remaining gas: 1039981.651 units remaining) + [ (Pair {} (Right (Some (Pair 0 5)))) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt \"hello\" \"world\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt \"hello\" \"world\" }].out" new file mode 100644 index 000000000000..469a5d0f99ec --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt \"hello\" \"world\" }].out" @@ -0,0 +1,33 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[empty_map.tz-{}-Unit-{ Elt "hello" "world" }] + +storage + { Elt "hello" "world" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039989.971 units remaining) + [ (Pair Unit {}) ] + - location: 9 (remaining gas: 1039989.961 units remaining) + [ ] + - location: 10 (remaining gas: 1039989.741 units remaining) + [ {} ] + - location: 13 (remaining gas: 1039989.731 units remaining) + [ "world" + {} ] + - location: 16 (remaining gas: 1039989.716 units remaining) + [ (Some "world") + {} ] + - location: 17 (remaining gas: 1039989.706 units remaining) + [ "hello" + (Some "world") + {} ] + - location: 20 (remaining gas: 1039989.556 units remaining) + [ { Elt "hello" "world" } ] + - location: 21 (remaining gas: 1039989.541 units remaining) + [ {} + { Elt "hello" "world" } ] + - location: 23 (remaining gas: 1039989.526 units remaining) + [ (Pair {} { Elt "hello" "world" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" new file mode 100644 index 000000000000..980d5ed568b5 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"\"-\"_abc\"].out" @@ -0,0 +1,48 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[exec_concat.tz-"?"-""-"_abc"] + +storage + "_abc" +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039987.134 units remaining) + [ (Pair "" "?") ] + - location: 7 (remaining gas: 1039987.124 units remaining) + [ "" @parameter ] + - location: 8 (remaining gas: 1039987.114 units remaining) + [ { PUSH string "_abc" ; NIL string ; SWAP ; CONS ; SWAP ; CONS ; CONCAT } + "" @parameter ] + - location: 22 (remaining gas: 1039987.104 units remaining) + [ "" @parameter + { PUSH string "_abc" ; NIL string ; SWAP ; CONS ; SWAP ; CONS ; CONCAT } ] + - location: 12 (remaining gas: 1039987.094 units remaining) + [ "_abc" + "" @arg ] + - location: 15 (remaining gas: 1039987.079 units remaining) + [ {} + "_abc" + "" @arg ] + - location: 17 (remaining gas: 1039987.069 units remaining) + [ "_abc" + {} + "" @arg ] + - location: 18 (remaining gas: 1039987.054 units remaining) + [ { "_abc" } + "" @arg ] + - location: 19 (remaining gas: 1039987.044 units remaining) + [ "" @arg + { "_abc" } ] + - location: 20 (remaining gas: 1039987.029 units remaining) + [ { "" ; "_abc" } ] + - location: 21 (remaining gas: 1039986.909 units remaining) + [ "_abc" ] + - location: 23 (remaining gas: 1039986.879 units remaining) + [ "_abc" ] + - location: 24 (remaining gas: 1039986.864 units remaining) + [ {} + "_abc" ] + - location: 26 (remaining gas: 1039986.849 units remaining) + [ (Pair {} "_abc") ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"test\"-\"test_abc\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"test\"-\"test_abc\"].out" new file mode 100644 index 000000000000..aaa9c79f9c28 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[exec_concat.tz-\"?\"-\"test\"-\"test_abc\"].out" @@ -0,0 +1,48 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[exec_concat.tz-"?"-"test"-"test_abc"] + +storage + "test_abc" +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039987.094 units remaining) + [ (Pair "test" "?") ] + - location: 7 (remaining gas: 1039987.084 units remaining) + [ "test" @parameter ] + - location: 8 (remaining gas: 1039987.074 units remaining) + [ { PUSH string "_abc" ; NIL string ; SWAP ; CONS ; SWAP ; CONS ; CONCAT } + "test" @parameter ] + - location: 22 (remaining gas: 1039987.064 units remaining) + [ "test" @parameter + { PUSH string "_abc" ; NIL string ; SWAP ; CONS ; SWAP ; CONS ; CONCAT } ] + - location: 12 (remaining gas: 1039987.054 units remaining) + [ "_abc" + "test" @arg ] + - location: 15 (remaining gas: 1039987.039 units remaining) + [ {} + "_abc" + "test" @arg ] + - location: 17 (remaining gas: 1039987.029 units remaining) + [ "_abc" + {} + "test" @arg ] + - location: 18 (remaining gas: 1039987.014 units remaining) + [ { "_abc" } + "test" @arg ] + - location: 19 (remaining gas: 1039987.004 units remaining) + [ "test" @arg + { "_abc" } ] + - location: 20 (remaining gas: 1039986.989 units remaining) + [ { "test" ; "_abc" } ] + - location: 21 (remaining gas: 1039986.869 units remaining) + [ "test_abc" ] + - location: 23 (remaining gas: 1039986.839 units remaining) + [ "test_abc" ] + - location: 24 (remaining gas: 1039986.824 units remaining) + [ {} + "test_abc" ] + - location: 26 (remaining gas: 1039986.809 units remaining) + [ (Pair {} "test_abc") ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out new file mode 100644 index 000000000000..655c0f3109a4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[first.tz-111-{ 1 ; 2 ; 3 ; 4 }-1] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039991.033 units remaining) + [ (Pair { 1 ; 2 ; 3 ; 4 } 111) ] + - location: 8 (remaining gas: 1039991.023 units remaining) + [ { 1 ; 2 ; 3 ; 4 } @parameter ] + - location: 9 (remaining gas: 1039991.013 units remaining) + [ 1 @parameter.hd + { 2 ; 3 ; 4 } @parameter.tl ] + - location: 11 (remaining gas: 1039990.998 units remaining) + [ { 2 ; 3 ; 4 } @parameter.tl ] + - location: 13 (remaining gas: 1039990.988 units remaining) + [ ] + - location: 11 (remaining gas: 1039990.958 units remaining) + [ 1 @parameter.hd ] + - location: 9 (remaining gas: 1039990.943 units remaining) + [ 1 @parameter.hd ] + - location: 18 (remaining gas: 1039990.928 units remaining) + [ {} + 1 @parameter.hd ] + - location: 20 (remaining gas: 1039990.913 units remaining) + [ (Pair {} 1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4].out new file mode 100644 index 000000000000..cc7dd42f5d6b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[first.tz-111-{ 4 }-4] + +storage + 4 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039991.333 units remaining) + [ (Pair { 4 } 111) ] + - location: 8 (remaining gas: 1039991.323 units remaining) + [ { 4 } @parameter ] + - location: 9 (remaining gas: 1039991.313 units remaining) + [ 4 @parameter.hd + {} @parameter.tl ] + - location: 11 (remaining gas: 1039991.298 units remaining) + [ {} @parameter.tl ] + - location: 13 (remaining gas: 1039991.288 units remaining) + [ ] + - location: 11 (remaining gas: 1039991.258 units remaining) + [ 4 @parameter.hd ] + - location: 9 (remaining gas: 1039991.243 units remaining) + [ 4 @parameter.hd ] + - location: 18 (remaining gas: 1039991.228 units remaining) + [ {} + 4 @parameter.hd ] + - location: 20 (remaining gas: 1039991.213 units remaining) + [ (Pair {} 4) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-\"hello\"-(Pair .161d86cef6.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-\"hello\"-(Pair .161d86cef6.out" new file mode 100644 index 000000000000..9d02b880505d --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-\"hello\"-(Pair .161d86cef6.out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 4) {})-"hello"-(Pair None { Elt "hello" 4 })] + +storage + (Pair None { Elt "hello" 4 }) +emitted operations + +big_map diff + +trace + - location: 13 (remaining gas: 1039989.746 units remaining) + [ (Pair "hello" (Some 4) {}) ] + - location: 13 (remaining gas: 1039989.736 units remaining) + [ "hello" @parameter + (Pair (Some 4) {}) @storage ] + - location: 14 (remaining gas: 1039989.721 units remaining) + [ (Pair (Some 4) {}) @storage ] + - location: 16 (remaining gas: 1039989.711 units remaining) + [ (Some 4) + {} ] + - location: 14 (remaining gas: 1039989.681 units remaining) + [ "hello" @parameter + (Some 4) + {} ] + - location: 17 (remaining gas: 1039989.496 units remaining) + [ None + { Elt "hello" 4 } ] + - location: 18 (remaining gas: 1039989.481 units remaining) + [ (Pair None { Elt "hello" 4 }) ] + - location: 19 (remaining gas: 1039989.466 units remaining) + [ {} + (Pair None { Elt "hello" 4 }) ] + - location: 21 (remaining gas: 1039989.451 units remaining) + [ (Pair {} None { Elt "hello" 4 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).684ab7e326.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).684ab7e326.out" new file mode 100644 index 000000000000..5e6b64ab7d35 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).684ab7e326.out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt "hello" 4 })-"hi"-(Pair None { Elt "hello" 4 ; Elt "hi" 5 })] + +storage + (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) +emitted operations + +big_map diff + +trace + - location: 13 (remaining gas: 1039989.362 units remaining) + [ (Pair "hi" (Some 5) { Elt "hello" 4 }) ] + - location: 13 (remaining gas: 1039989.352 units remaining) + [ "hi" @parameter + (Pair (Some 5) { Elt "hello" 4 }) @storage ] + - location: 14 (remaining gas: 1039989.337 units remaining) + [ (Pair (Some 5) { Elt "hello" 4 }) @storage ] + - location: 16 (remaining gas: 1039989.327 units remaining) + [ (Some 5) + { Elt "hello" 4 } ] + - location: 14 (remaining gas: 1039989.297 units remaining) + [ "hi" @parameter + (Some 5) + { Elt "hello" 4 } ] + - location: 17 (remaining gas: 1039989.007 units remaining) + [ None + { Elt "hello" 4 ; Elt "hi" 5 } ] + - location: 18 (remaining gas: 1039988.992 units remaining) + [ (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) ] + - location: 19 (remaining gas: 1039988.977 units remaining) + [ {} + (Pair None { Elt "hello" 4 ; Elt "hi" 5 }) ] + - location: 21 (remaining gas: 1039988.962 units remaining) + [ (Pair {} None { Elt "hello" 4 ; Elt "hi" 5 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).d49817fb83.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).d49817fb83.out" new file mode 100644 index 000000000000..8a4671f44a82 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt \"hello\" 4 }).d49817fb83.out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair (Some 5) { Elt "hello" 4 })-"hello"-(Pair (Some 4) { Elt "hello" 5 })] + +storage + (Pair (Some 4) { Elt "hello" 5 }) +emitted operations + +big_map diff + +trace + - location: 13 (remaining gas: 1039989.332 units remaining) + [ (Pair "hello" (Some 5) { Elt "hello" 4 }) ] + - location: 13 (remaining gas: 1039989.322 units remaining) + [ "hello" @parameter + (Pair (Some 5) { Elt "hello" 4 }) @storage ] + - location: 14 (remaining gas: 1039989.307 units remaining) + [ (Pair (Some 5) { Elt "hello" 4 }) @storage ] + - location: 16 (remaining gas: 1039989.297 units remaining) + [ (Some 5) + { Elt "hello" 4 } ] + - location: 14 (remaining gas: 1039989.267 units remaining) + [ "hello" @parameter + (Some 5) + { Elt "hello" 4 } ] + - location: 17 (remaining gas: 1039988.977 units remaining) + [ (Some 4) + { Elt "hello" 5 } ] + - location: 18 (remaining gas: 1039988.962 units remaining) + [ (Pair (Some 4) { Elt "hello" 5 }) ] + - location: 19 (remaining gas: 1039988.947 units remaining) + [ {} + (Pair (Some 4) { Elt "hello" 5 }) ] + - location: 21 (remaining gas: 1039988.932 units remaining) + [ (Pair {} (Some 4) { Elt "hello" 5 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .6900b1da14.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .6900b1da14.out" new file mode 100644 index 000000000000..f16ee1ae16ba --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .6900b1da14.out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt "1" 1 ; Elt "2" 2 })-"1"-(Pair (Some 1) { Elt "2" 2 })1] + +storage + (Pair (Some 1) { Elt "2" 2 }) +emitted operations + +big_map diff + +trace + - location: 13 (remaining gas: 1039989.033 units remaining) + [ (Pair "1" None { Elt "1" 1 ; Elt "2" 2 }) ] + - location: 13 (remaining gas: 1039989.023 units remaining) + [ "1" @parameter + (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] + - location: 14 (remaining gas: 1039989.008 units remaining) + [ (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] + - location: 16 (remaining gas: 1039988.998 units remaining) + [ None + { Elt "1" 1 ; Elt "2" 2 } ] + - location: 14 (remaining gas: 1039988.968 units remaining) + [ "1" @parameter + None + { Elt "1" 1 ; Elt "2" 2 } ] + - location: 17 (remaining gas: 1039988.573 units remaining) + [ (Some 1) + { Elt "2" 2 } ] + - location: 18 (remaining gas: 1039988.558 units remaining) + [ (Pair (Some 1) { Elt "2" 2 }) ] + - location: 19 (remaining gas: 1039988.543 units remaining) + [ {} + (Pair (Some 1) { Elt "2" 2 }) ] + - location: 21 (remaining gas: 1039988.528 units remaining) + [ (Pair {} (Some 1) { Elt "2" 2 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .bca0ede8be.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .bca0ede8be.out" new file mode 100644 index 000000000000..8e3e8d6dde08 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"1\" 1 ; .bca0ede8be.out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt "1" 1 ; Elt "2" 2 })-"1"-(Pair (Some 1) { Elt "2" 2 })0] + +storage + (Pair (Some 1) { Elt "2" 2 }) +emitted operations + +big_map diff + +trace + - location: 13 (remaining gas: 1039989.033 units remaining) + [ (Pair "1" None { Elt "1" 1 ; Elt "2" 2 }) ] + - location: 13 (remaining gas: 1039989.023 units remaining) + [ "1" @parameter + (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] + - location: 14 (remaining gas: 1039989.008 units remaining) + [ (Pair None { Elt "1" 1 ; Elt "2" 2 }) @storage ] + - location: 16 (remaining gas: 1039988.998 units remaining) + [ None + { Elt "1" 1 ; Elt "2" 2 } ] + - location: 14 (remaining gas: 1039988.968 units remaining) + [ "1" @parameter + None + { Elt "1" 1 ; Elt "2" 2 } ] + - location: 17 (remaining gas: 1039988.573 units remaining) + [ (Some 1) + { Elt "2" 2 } ] + - location: 18 (remaining gas: 1039988.558 units remaining) + [ (Pair (Some 1) { Elt "2" 2 }) ] + - location: 19 (remaining gas: 1039988.543 units remaining) + [ {} + (Pair (Some 1) { Elt "2" 2 }) ] + - location: 21 (remaining gas: 1039988.528 units remaining) + [ (Pair {} (Some 1) { Elt "2" 2 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" new file mode 100644 index 000000000000..e91a6ddb38db --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt \"hello\" 4 })-\"he.c1b4e1d6dc.out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None { Elt "hello" 4 })-"hello"-(Pair (Some 4) {})] + +storage + (Pair (Some 4) {}) +emitted operations + +big_map diff + +trace + - location: 13 (remaining gas: 1039989.432 units remaining) + [ (Pair "hello" None { Elt "hello" 4 }) ] + - location: 13 (remaining gas: 1039989.422 units remaining) + [ "hello" @parameter + (Pair None { Elt "hello" 4 }) @storage ] + - location: 14 (remaining gas: 1039989.407 units remaining) + [ (Pair None { Elt "hello" 4 }) @storage ] + - location: 16 (remaining gas: 1039989.397 units remaining) + [ None + { Elt "hello" 4 } ] + - location: 14 (remaining gas: 1039989.367 units remaining) + [ "hello" @parameter + None + { Elt "hello" 4 } ] + - location: 17 (remaining gas: 1039989.077 units remaining) + [ (Some 4) + {} ] + - location: 18 (remaining gas: 1039989.062 units remaining) + [ (Pair (Some 4) {}) ] + - location: 19 (remaining gas: 1039989.047 units remaining) + [ {} + (Pair (Some 4) {}) ] + - location: 21 (remaining gas: 1039989.032 units remaining) + [ (Pair {} (Some 4) {}) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-\"hello\"-(Pair None {})].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-\"hello\"-(Pair None {})].out" new file mode 100644 index 000000000000..a393b2da07f7 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-\"hello\"-(Pair None {})].out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_and_update_map.tz-(Pair None {})-"hello"-(Pair None {})] + +storage + (Pair None {}) +emitted operations + +big_map diff + +trace + - location: 13 (remaining gas: 1039989.846 units remaining) + [ (Pair "hello" None {}) ] + - location: 13 (remaining gas: 1039989.836 units remaining) + [ "hello" @parameter + (Pair None {}) @storage ] + - location: 14 (remaining gas: 1039989.821 units remaining) + [ (Pair None {}) @storage ] + - location: 16 (remaining gas: 1039989.811 units remaining) + [ None + {} ] + - location: 14 (remaining gas: 1039989.781 units remaining) + [ "hello" @parameter + None + {} ] + - location: 17 (remaining gas: 1039989.596 units remaining) + [ None + {} ] + - location: 18 (remaining gas: 1039989.581 units remaining) + [ (Pair None {}) ] + - location: 19 (remaining gas: 1039989.566 units remaining) + [ {} + (Pair None {}) ] + - location: 21 (remaining gas: 1039989.551 units remaining) + [ (Pair {} None {}) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"1\" \"one\" ; .bc4127094e.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"1\" \"one\" ; .bc4127094e.out" new file mode 100644 index 000000000000..f32bf7eea1b3 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"1\" \"one\" ; .bc4127094e.out" @@ -0,0 +1,41 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt "1" "one" ; Elt "2" "two" })-"1"-(Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" })] + +storage + (Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" }) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039986.547 units remaining) + [ (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) ] + - location: 12 (remaining gas: 1039986.537 units remaining) + [ (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) + (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) ] + - location: 13 (remaining gas: 1039986.527 units remaining) + [ "1" @parameter + (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) ] + - location: 14 (remaining gas: 1039986.512 units remaining) + [ (Pair "1" None { Elt "1" "one" ; Elt "2" "two" }) ] + - location: 17 (remaining gas: 1039986.502 units remaining) + [ (Pair None { Elt "1" "one" ; Elt "2" "two" }) @storage ] + - location: 18 (remaining gas: 1039986.492 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } ] + - location: 19 (remaining gas: 1039986.482 units remaining) + [ { Elt "1" "one" ; Elt "2" "two" } + { Elt "1" "one" ; Elt "2" "two" } ] + - location: 14 (remaining gas: 1039986.452 units remaining) + [ "1" @parameter + { Elt "1" "one" ; Elt "2" "two" } + { Elt "1" "one" ; Elt "2" "two" } ] + - location: 20 (remaining gas: 1039986.267 units remaining) + [ (Some "one") + { Elt "1" "one" ; Elt "2" "two" } ] + - location: 21 (remaining gas: 1039986.252 units remaining) + [ (Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" }) ] + - location: 22 (remaining gas: 1039986.237 units remaining) + [ {} + (Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" }) ] + - location: 24 (remaining gas: 1039986.222 units remaining) + [ (Pair {} (Some "one") { Elt "1" "one" ; Elt "2" "two" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"\"-(P.0c03056487.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"\"-(P.0c03056487.out" new file mode 100644 index 000000000000..46f19946b29a --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"\"-(P.0c03056487.out" @@ -0,0 +1,41 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt "hello" "hi" })-""-(Pair None { Elt "hello" "hi" })] + +storage + (Pair None { Elt "hello" "hi" }) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039987.050 units remaining) + [ (Pair "" None { Elt "hello" "hi" }) ] + - location: 12 (remaining gas: 1039987.040 units remaining) + [ (Pair "" None { Elt "hello" "hi" }) + (Pair "" None { Elt "hello" "hi" }) ] + - location: 13 (remaining gas: 1039987.030 units remaining) + [ "" @parameter + (Pair "" None { Elt "hello" "hi" }) ] + - location: 14 (remaining gas: 1039987.015 units remaining) + [ (Pair "" None { Elt "hello" "hi" }) ] + - location: 17 (remaining gas: 1039987.005 units remaining) + [ (Pair None { Elt "hello" "hi" }) @storage ] + - location: 18 (remaining gas: 1039986.995 units remaining) + [ { Elt "hello" "hi" } ] + - location: 19 (remaining gas: 1039986.985 units remaining) + [ { Elt "hello" "hi" } + { Elt "hello" "hi" } ] + - location: 14 (remaining gas: 1039986.955 units remaining) + [ "" @parameter + { Elt "hello" "hi" } + { Elt "hello" "hi" } ] + - location: 20 (remaining gas: 1039986.805 units remaining) + [ None + { Elt "hello" "hi" } ] + - location: 21 (remaining gas: 1039986.790 units remaining) + [ (Pair None { Elt "hello" "hi" }) ] + - location: 22 (remaining gas: 1039986.775 units remaining) + [ {} + (Pair None { Elt "hello" "hi" }) ] + - location: 24 (remaining gas: 1039986.760 units remaining) + [ (Pair {} None { Elt "hello" "hi" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"hell.cc45544c66.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"hell.cc45544c66.out" new file mode 100644 index 000000000000..c66696c489ec --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt \"hello\" \"hi\" })-\"hell.cc45544c66.out" @@ -0,0 +1,41 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[get_map_value.tz-(Pair None { Elt "hello" "hi" })-"hello"-(Pair (Some "hi") { Elt "hello" "hi" })] + +storage + (Pair (Some "hi") { Elt "hello" "hi" }) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039987 units remaining) + [ (Pair "hello" None { Elt "hello" "hi" }) ] + - location: 12 (remaining gas: 1039986.990 units remaining) + [ (Pair "hello" None { Elt "hello" "hi" }) + (Pair "hello" None { Elt "hello" "hi" }) ] + - location: 13 (remaining gas: 1039986.980 units remaining) + [ "hello" @parameter + (Pair "hello" None { Elt "hello" "hi" }) ] + - location: 14 (remaining gas: 1039986.965 units remaining) + [ (Pair "hello" None { Elt "hello" "hi" }) ] + - location: 17 (remaining gas: 1039986.955 units remaining) + [ (Pair None { Elt "hello" "hi" }) @storage ] + - location: 18 (remaining gas: 1039986.945 units remaining) + [ { Elt "hello" "hi" } ] + - location: 19 (remaining gas: 1039986.935 units remaining) + [ { Elt "hello" "hi" } + { Elt "hello" "hi" } ] + - location: 14 (remaining gas: 1039986.905 units remaining) + [ "hello" @parameter + { Elt "hello" "hi" } + { Elt "hello" "hi" } ] + - location: 20 (remaining gas: 1039986.755 units remaining) + [ (Some "hi") + { Elt "hello" "hi" } ] + - location: 21 (remaining gas: 1039986.740 units remaining) + [ (Pair (Some "hi") { Elt "hello" "hi" }) ] + - location: 22 (remaining gas: 1039986.725 units remaining) + [ {} + (Pair (Some "hi") { Elt "hello" "hi" }) ] + - location: 24 (remaining gas: 1039986.710 units remaining) + [ (Pair {} (Some "hi") { Elt "hello" "hi" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" new file mode 100644 index 000000000000..14dcf7cfe34e --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAb.613ad6b637.out" @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[hash_key.tz-None-"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"-(Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx")] + +storage + (Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039668.957 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" None) ] + - location: 8 (remaining gas: 1039668.947 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @parameter ] + - location: 9 (remaining gas: 1039668.292 units remaining) + [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] + - location: 10 (remaining gas: 1039668.277 units remaining) + [ (Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") ] + - location: 11 (remaining gas: 1039668.262 units remaining) + [ {} + (Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") ] + - location: 13 (remaining gas: 1039668.247 units remaining) + [ (Pair {} (Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" new file mode 100644 index 000000000000..0294665126d5 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_key.tz-None-\"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTa.da50984e8d.out" @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[hash_key.tz-None-"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTawUPqR8vZTAMcx61ES"-(Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k")] + +storage + (Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k") +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039668.957 units remaining) + [ (Pair "edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTawUPqR8vZTAMcx61ES" None) ] + - location: 8 (remaining gas: 1039668.947 units remaining) + [ "edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTawUPqR8vZTAMcx61ES" @parameter ] + - location: 9 (remaining gas: 1039668.292 units remaining) + [ "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k" ] + - location: 10 (remaining gas: 1039668.277 units remaining) + [ (Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k") ] + - location: 11 (remaining gas: 1039668.262 units remaining) + [ {} + (Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k") ] + - location: 13 (remaining gas: 1039668.247 units remaining) + [ (Pair {} (Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"12345\"-0xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"12345\"-0xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" new file mode 100644 index 000000000000..5198a93e4cee --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"12345\"-0xb4c26c20de52a4eaf0d8a340d.2bba28b0bf.out" @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-"12345"-0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f] + +storage + 0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.241 units remaining) + [ (Pair "12345" 0x00) ] + - location: 7 (remaining gas: 1039994.231 units remaining) + [ "12345" @parameter ] + - location: 8 (remaining gas: 1039993.740 units remaining) + [ 0x0501000000053132333435 @parameter.packed ] + - location: 9 (remaining gas: 1039993.298 units remaining) + [ 0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f ] + - location: 10 (remaining gas: 1039993.283 units remaining) + [ {} + 0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f ] + - location: 12 (remaining gas: 1039993.268 units remaining) + [ (Pair {} 0xb4c26c20de52a4eaf0d8a340db47ad8cb1e74049570859c9a9a3952b204c772f) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"abcdefg\"-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"abcdefg\"-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" new file mode 100644 index 000000000000..eb69749a8503 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-\"abcdefg\"-0x46fdbcb4ea4eadad5615cda.acc82cd954.out" @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[hash_string.tz-0x00-"abcdefg"-0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e] + +storage + 0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.221 units remaining) + [ (Pair "abcdefg" 0x00) ] + - location: 7 (remaining gas: 1039994.211 units remaining) + [ "abcdefg" @parameter ] + - location: 8 (remaining gas: 1039993.654 units remaining) + [ 0x05010000000761626364656667 @parameter.packed ] + - location: 9 (remaining gas: 1039993.210 units remaining) + [ 0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e ] + - location: 10 (remaining gas: 1039993.195 units remaining) + [ {} + 0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e ] + - location: 12 (remaining gas: 1039993.180 units remaining) + [ (Pair {} 0x46fdbcb4ea4eadad5615cdaa17d67f783e01e21149ce2b27de497600b4cd8f4e) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)].out new file mode 100644 index 000000000000..c11260cd1903 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[if.tz-None-False-(Some False)] + +storage + (Some False) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039991.305 units remaining) + [ (Pair False None) ] + - location: 8 (remaining gas: 1039991.295 units remaining) + [ False @parameter ] + - location: 9 (remaining gas: 1039991.285 units remaining) + [ ] + - location: 15 (remaining gas: 1039991.275 units remaining) + [ False ] + - location: 9 (remaining gas: 1039991.260 units remaining) + [ False ] + - location: 18 (remaining gas: 1039991.245 units remaining) + [ (Some False) ] + - location: 19 (remaining gas: 1039991.230 units remaining) + [ {} + (Some False) ] + - location: 21 (remaining gas: 1039991.215 units remaining) + [ (Pair {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)].out new file mode 100644 index 000000000000..a588a6adcb03 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[if.tz-None-True-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039991.305 units remaining) + [ (Pair True None) ] + - location: 8 (remaining gas: 1039991.295 units remaining) + [ True @parameter ] + - location: 9 (remaining gas: 1039991.285 units remaining) + [ ] + - location: 11 (remaining gas: 1039991.275 units remaining) + [ True ] + - location: 9 (remaining gas: 1039991.260 units remaining) + [ True ] + - location: 18 (remaining gas: 1039991.245 units remaining) + [ (Some True) ] + - location: 19 (remaining gas: 1039991.230 units remaining) + [ {} + (Some True) ] + - location: 21 (remaining gas: 1039991.215 units remaining) + [ (Pair {} (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-(Some \"hello\")-\"hello\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-(Some \"hello\")-\"hello\"].out" new file mode 100644 index 000000000000..0ae59ef448d1 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-(Some \"hello\")-\"hello\"].out" @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[if_some.tz-"?"-(Some "hello")-"hello"] + +storage + "hello" +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039992.411 units remaining) + [ (Pair (Some "hello") "?") ] + - location: 8 (remaining gas: 1039992.401 units remaining) + [ (Some "hello") @parameter ] + - location: 10 (remaining gas: 1039992.391 units remaining) + [ "hello" ] + - location: 10 (remaining gas: 1039992.376 units remaining) + [ "hello" ] + - location: 16 (remaining gas: 1039992.361 units remaining) + [ {} + "hello" ] + - location: 18 (remaining gas: 1039992.346 units remaining) + [ (Pair {} "hello") ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-None-\"\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-None-\"\"].out" new file mode 100644 index 000000000000..4303f734550c --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[if_some.tz-\"?\"-None-\"\"].out" @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[if_some.tz-"?"-None-""] + +storage + "" +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039992.575 units remaining) + [ (Pair None "?") ] + - location: 8 (remaining gas: 1039992.565 units remaining) + [ None @parameter ] + - location: 10 (remaining gas: 1039992.555 units remaining) + [ ] + - location: 12 (remaining gas: 1039992.545 units remaining) + [ "" ] + - location: 10 (remaining gas: 1039992.530 units remaining) + [ "" ] + - location: 16 (remaining gas: 1039992.515 units remaining) + [ {} + "" ] + - location: 18 (remaining gas: 1039992.500 units remaining) + [ (Pair {} "") ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)].out new file mode 100644 index 000000000000..a31049a6db6d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)].out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[int.tz-None-0-(Some 0)] + +storage + (Some 0) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.957 units remaining) + [ (Pair 0 None) ] + - location: 8 (remaining gas: 1039993.947 units remaining) + [ 0 @parameter ] + - location: 9 (remaining gas: 1039993.932 units remaining) + [ 0 ] + - location: 10 (remaining gas: 1039993.917 units remaining) + [ (Some 0) ] + - location: 11 (remaining gas: 1039993.902 units remaining) + [ {} + (Some 0) ] + - location: 13 (remaining gas: 1039993.887 units remaining) + [ (Pair {} (Some 0)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)].out new file mode 100644 index 000000000000..3c0cb54e839f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)].out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[int.tz-None-1-(Some 1)] + +storage + (Some 1) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.957 units remaining) + [ (Pair 1 None) ] + - location: 8 (remaining gas: 1039993.947 units remaining) + [ 1 @parameter ] + - location: 9 (remaining gas: 1039993.932 units remaining) + [ 1 ] + - location: 10 (remaining gas: 1039993.917 units remaining) + [ (Some 1) ] + - location: 11 (remaining gas: 1039993.902 units remaining) + [ {} + (Some 1) ] + - location: 13 (remaining gas: 1039993.887 units remaining) + [ (Pair {} (Some 1)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)].out new file mode 100644 index 000000000000..8c4d872a7d91 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)].out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[int.tz-None-9999-(Some 9999)] + +storage + (Some 9999) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.957 units remaining) + [ (Pair 9999 None) ] + - location: 8 (remaining gas: 1039993.947 units remaining) + [ 9999 @parameter ] + - location: 9 (remaining gas: 1039993.932 units remaining) + [ 9999 ] + - location: 10 (remaining gas: 1039993.917 units remaining) + [ (Some 9999) ] + - location: 11 (remaining gas: 1039993.902 units remaining) + [ {} + (Some 9999) ] + - location: 13 (remaining gas: 1039993.887 units remaining) + [ (Pair {} (Some 9999)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e.34c02678c9.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e.34c02678c9.out new file mode 100644 index 000000000000..8185a1c3118d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e.34c02678c9.out @@ -0,0 +1,24 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[keccak.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4)] + +storage + (Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.957 units remaining) + [ (Pair 0x48656c6c6f2c20776f726c6421 None) ] + - location: 8 (remaining gas: 1039993.947 units remaining) + [ 0x48656c6c6f2c20776f726c6421 @parameter ] + - location: 9 (remaining gas: 1039992.490 units remaining) + [ 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4 ] + - location: 10 (remaining gas: 1039992.475 units remaining) + [ (Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4) ] + - location: 11 (remaining gas: 1039992.460 units remaining) + [ {} + (Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4) ] + - location: 13 (remaining gas: 1039992.445 units remaining) + [ (Pair {} + (Some 0xb6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Left True)-(Right True)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Left True)-(Right True)].out" new file mode 100644 index 000000000000..96798c5942bc --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Left True)-(Right True)].out" @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[left_right.tz-(Left "X")-(Left True)-(Right True)] + +storage + (Right True) +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039990.926 units remaining) + [ (Pair (Left True) (Left "X")) ] + - location: 11 (remaining gas: 1039990.916 units remaining) + [ (Left True) @parameter ] + - location: 12 (remaining gas: 1039990.906 units remaining) + [ True @parameter.left ] + - location: 14 (remaining gas: 1039990.891 units remaining) + [ (Right True) ] + - location: 12 (remaining gas: 1039990.876 units remaining) + [ (Right True) ] + - location: 19 (remaining gas: 1039990.861 units remaining) + [ {} + (Right True) ] + - location: 21 (remaining gas: 1039990.846 units remaining) + [ (Pair {} (Right True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Right \"a\")-(Left \"a\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Right \"a\")-(Left \"a\")].out" new file mode 100644 index 000000000000..72695097beb4 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[left_right.tz-(Left \"X\")-(Right \"a\")-(Left \"a\")].out" @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[left_right.tz-(Left "X")-(Right "a")-(Left "a")] + +storage + (Left "a") +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039990.902 units remaining) + [ (Pair (Right "a") (Left "X")) ] + - location: 11 (remaining gas: 1039990.892 units remaining) + [ (Right "a") @parameter ] + - location: 12 (remaining gas: 1039990.882 units remaining) + [ "a" @parameter.right ] + - location: 17 (remaining gas: 1039990.867 units remaining) + [ (Left "a") ] + - location: 12 (remaining gas: 1039990.852 units remaining) + [ (Left "a") ] + - location: 19 (remaining gas: 1039990.837 units remaining) + [ {} + (Left "a") ] + - location: 21 (remaining gas: 1039990.822 units remaining) + [ (Pair {} (Left "a")) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1].out new file mode 100644 index 000000000000..87a3a32e550e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[level.tz-111-Unit-1] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 111) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039994.923 units remaining) + [ 1 @level ] + - location: 9 (remaining gas: 1039994.908 units remaining) + [ {} + 1 @level ] + - location: 11 (remaining gas: 1039994.893 units remaining) + [ (Pair {} 1) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" new file mode 100644 index 000000000000..c6a322512a4b --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{ \"d\" ; \"e\" ; \"f\" }-\"abcdef\"].out" @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat.tz-"abc"-{ "d" ; "e" ; "f" }-"abcdef"] + +storage + "abcdef" +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039992.898 units remaining) + [ (Pair { "d" ; "e" ; "f" } "abc") ] + - location: 8 (remaining gas: 1039992.888 units remaining) + [ { "d" ; "e" ; "f" } @parameter + "abc" @storage ] + - location: 9 (remaining gas: 1039992.878 units remaining) + [ "abc" @storage + { "d" ; "e" ; "f" } @parameter ] + - location: 10 (remaining gas: 1039992.863 units remaining) + [ { "abc" ; "d" ; "e" ; "f" } ] + - location: 11 (remaining gas: 1039992.723 units remaining) + [ "abcdef" ] + - location: 12 (remaining gas: 1039992.708 units remaining) + [ {} + "abcdef" ] + - location: 14 (remaining gas: 1039992.693 units remaining) + [ (Pair {} "abcdef") ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{}-\"abc\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{}-\"abc\"].out" new file mode 100644 index 000000000000..61dd6bb056cc --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat.tz-\"abc\"-{}-\"abc\"].out" @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat.tz-"abc"-{}-"abc"] + +storage + "abc" +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.270 units remaining) + [ (Pair {} "abc") ] + - location: 8 (remaining gas: 1039993.260 units remaining) + [ {} @parameter + "abc" @storage ] + - location: 9 (remaining gas: 1039993.250 units remaining) + [ "abc" @storage + {} @parameter ] + - location: 10 (remaining gas: 1039993.235 units remaining) + [ { "abc" } ] + - location: 11 (remaining gas: 1039993.125 units remaining) + [ "abc" ] + - location: 12 (remaining gas: 1039993.110 units remaining) + [ {} + "abc" ] + - location: 14 (remaining gas: 1039993.095 units remaining) + [ (Pair {} "abc") ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out new file mode 100644 index 000000000000..eb0c95e7c0ce --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{ 0x00 ; 0x11 ; 0x00 }-0x001100] + +storage + 0x001100 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.014 units remaining) + [ (Pair { 0x00 ; 0x11 ; 0x00 } 0x) ] + - location: 8 (remaining gas: 1039993.004 units remaining) + [ { 0x00 ; 0x11 ; 0x00 } @parameter + 0x @storage ] + - location: 9 (remaining gas: 1039992.994 units remaining) + [ 0x @storage + { 0x00 ; 0x11 ; 0x00 } @parameter ] + - location: 10 (remaining gas: 1039992.979 units remaining) + [ { 0x ; 0x00 ; 0x11 ; 0x00 } ] + - location: 11 (remaining gas: 1039992.839 units remaining) + [ 0x001100 ] + - location: 12 (remaining gas: 1039992.824 units remaining) + [ {} + 0x001100 ] + - location: 14 (remaining gas: 1039992.809 units remaining) + [ (Pair {} 0x001100) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x].out new file mode 100644 index 000000000000..0c13a3d9c08b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x-{}-0x] + +storage + 0x +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.314 units remaining) + [ (Pair {} 0x) ] + - location: 8 (remaining gas: 1039993.304 units remaining) + [ {} @parameter + 0x @storage ] + - location: 9 (remaining gas: 1039993.294 units remaining) + [ 0x @storage + {} @parameter ] + - location: 10 (remaining gas: 1039993.279 units remaining) + [ { 0x } ] + - location: 11 (remaining gas: 1039993.169 units remaining) + [ 0x ] + - location: 12 (remaining gas: 1039993.154 units remaining) + [ {} + 0x ] + - location: 14 (remaining gas: 1039993.139 units remaining) + [ (Pair {} 0x) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out new file mode 100644 index 000000000000..5262f39f7c17 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0x00ab-{ 0xcd ; 0xef ; 0x00 }-0x00abcdef00] + +storage + 0x00abcdef00 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.014 units remaining) + [ (Pair { 0xcd ; 0xef ; 0x00 } 0x00ab) ] + - location: 8 (remaining gas: 1039993.004 units remaining) + [ { 0xcd ; 0xef ; 0x00 } @parameter + 0x00ab @storage ] + - location: 9 (remaining gas: 1039992.994 units remaining) + [ 0x00ab @storage + { 0xcd ; 0xef ; 0x00 } @parameter ] + - location: 10 (remaining gas: 1039992.979 units remaining) + [ { 0x00ab ; 0xcd ; 0xef ; 0x00 } ] + - location: 11 (remaining gas: 1039992.839 units remaining) + [ 0x00abcdef00 ] + - location: 12 (remaining gas: 1039992.824 units remaining) + [ {} + 0x00abcdef00 ] + - location: 14 (remaining gas: 1039992.809 units remaining) + [ (Pair {} 0x00abcdef00) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd].out new file mode 100644 index 000000000000..bd24f1060b2b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_concat_bytes.tz-0xabcd-{}-0xabcd] + +storage + 0xabcd +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.314 units remaining) + [ (Pair {} 0xabcd) ] + - location: 8 (remaining gas: 1039993.304 units remaining) + [ {} @parameter + 0xabcd @storage ] + - location: 9 (remaining gas: 1039993.294 units remaining) + [ 0xabcd @storage + {} @parameter ] + - location: 10 (remaining gas: 1039993.279 units remaining) + [ { 0xabcd } ] + - location: 11 (remaining gas: 1039993.169 units remaining) + [ 0xabcd ] + - location: 12 (remaining gas: 1039993.154 units remaining) + [ {} + 0xabcd ] + - location: 14 (remaining gas: 1039993.139 units remaining) + [ (Pair {} 0xabcd) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" new file mode 100644 index 000000000000..1f14db663cc8 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" @@ -0,0 +1,19 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id.tz-{""}-{ "1" ; "2" ; "3" }-{ "1" ; "2" ; "3" }] + +storage + { "1" ; "2" ; "3" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039994.539 units remaining) + [ (Pair { "1" ; "2" ; "3" } { "" }) ] + - location: 9 (remaining gas: 1039994.529 units remaining) + [ { "1" ; "2" ; "3" } @parameter ] + - location: 10 (remaining gas: 1039994.514 units remaining) + [ {} + { "1" ; "2" ; "3" } @parameter ] + - location: 12 (remaining gas: 1039994.499 units remaining) + [ (Pair {} { "1" ; "2" ; "3" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" new file mode 100644 index 000000000000..214a4660bd14 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" @@ -0,0 +1,19 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id.tz-{""}-{ "a" ; "b" ; "c" }-{ "a" ; "b" ; "c" }] + +storage + { "a" ; "b" ; "c" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039994.539 units remaining) + [ (Pair { "a" ; "b" ; "c" } { "" }) ] + - location: 9 (remaining gas: 1039994.529 units remaining) + [ { "a" ; "b" ; "c" } @parameter ] + - location: 10 (remaining gas: 1039994.514 units remaining) + [ {} + { "a" ; "b" ; "c" } @parameter ] + - location: 12 (remaining gas: 1039994.499 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{}-{}].out" new file mode 100644 index 000000000000..8e4aeb5bcb20 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id.tz-{\"\"}-{}-{}].out" @@ -0,0 +1,19 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id.tz-{""}-{}-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039994.911 units remaining) + [ (Pair {} { "" }) ] + - location: 9 (remaining gas: 1039994.901 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039994.886 units remaining) + [ {} + {} @parameter ] + - location: 12 (remaining gas: 1039994.871 units remaining) + [ (Pair {} {}) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" new file mode 100644 index 000000000000..ee6935c47fcf --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"1\" ; \"2\" ; \"3\" }-{ \"1\" ; \"2\" ; \"3\" }].out" @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id_map.tz-{""}-{ "1" ; "2" ; "3" }-{ "1" ; "2" ; "3" }] + +storage + { "1" ; "2" ; "3" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039993.518 units remaining) + [ (Pair { "1" ; "2" ; "3" } { "" }) ] + - location: 9 (remaining gas: 1039993.508 units remaining) + [ { "1" ; "2" ; "3" } @parameter ] + - location: 10 (remaining gas: 1039993.508 units remaining) + [ "1" ] + - location: 10 (remaining gas: 1039993.493 units remaining) + [ "2" ] + - location: 10 (remaining gas: 1039993.478 units remaining) + [ "3" ] + - location: 10 (remaining gas: 1039993.463 units remaining) + [ { "1" ; "2" ; "3" } ] + - location: 12 (remaining gas: 1039993.448 units remaining) + [ {} + { "1" ; "2" ; "3" } ] + - location: 14 (remaining gas: 1039993.433 units remaining) + [ (Pair {} { "1" ; "2" ; "3" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" new file mode 100644 index 000000000000..3b1caf6cdff5 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id_map.tz-{""}-{ "a" ; "b" ; "c" }-{ "a" ; "b" ; "c" }] + +storage + { "a" ; "b" ; "c" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039993.518 units remaining) + [ (Pair { "a" ; "b" ; "c" } { "" }) ] + - location: 9 (remaining gas: 1039993.508 units remaining) + [ { "a" ; "b" ; "c" } @parameter ] + - location: 10 (remaining gas: 1039993.508 units remaining) + [ "a" ] + - location: 10 (remaining gas: 1039993.493 units remaining) + [ "b" ] + - location: 10 (remaining gas: 1039993.478 units remaining) + [ "c" ] + - location: 10 (remaining gas: 1039993.463 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 12 (remaining gas: 1039993.448 units remaining) + [ {} + { "a" ; "b" ; "c" } ] + - location: 14 (remaining gas: 1039993.433 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{}-{}].out" new file mode 100644 index 000000000000..58589fde07e1 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_id_map.tz-{\"\"}-{}-{}].out" @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_id_map.tz-{""}-{}-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039993.890 units remaining) + [ (Pair {} { "" }) ] + - location: 9 (remaining gas: 1039993.880 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039993.880 units remaining) + [ {} ] + - location: 12 (remaining gas: 1039993.865 units remaining) + [ {} + {} ] + - location: 14 (remaining gas: 1039993.850 units remaining) + [ (Pair {} {}) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out new file mode 100644 index 000000000000..7040bc57e419 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20].out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 10 ; 2 ; 1 }-20] + +storage + 20 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039991.873 units remaining) + [ (Pair { 10 ; 2 ; 1 } 0) ] + - location: 8 (remaining gas: 1039991.863 units remaining) + [ { 10 ; 2 ; 1 } @parameter ] + - location: 9 (remaining gas: 1039991.853 units remaining) + [ 1 + { 10 ; 2 ; 1 } @parameter ] + - location: 12 (remaining gas: 1039991.843 units remaining) + [ { 10 ; 2 ; 1 } @parameter + 1 ] + - location: 13 (remaining gas: 1039991.843 units remaining) + [ 10 @parameter.elt + 1 ] + - location: 15 (remaining gas: 1039991.739 units remaining) + [ 10 ] + - location: 13 (remaining gas: 1039991.724 units remaining) + [ 2 @parameter.elt + 10 ] + - location: 15 (remaining gas: 1039991.620 units remaining) + [ 20 ] + - location: 13 (remaining gas: 1039991.605 units remaining) + [ 1 @parameter.elt + 20 ] + - location: 15 (remaining gas: 1039991.501 units remaining) + [ 20 ] + - location: 13 (remaining gas: 1039991.486 units remaining) + [ 20 ] + - location: 16 (remaining gas: 1039991.471 units remaining) + [ {} + 20 ] + - location: 18 (remaining gas: 1039991.456 units remaining) + [ (Pair {} 20) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out new file mode 100644 index 000000000000..7d81ce16671e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162].out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_iter.tz-0-{ 3 ; 6 ; 9 }-162] + +storage + 162 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039991.873 units remaining) + [ (Pair { 3 ; 6 ; 9 } 0) ] + - location: 8 (remaining gas: 1039991.863 units remaining) + [ { 3 ; 6 ; 9 } @parameter ] + - location: 9 (remaining gas: 1039991.853 units remaining) + [ 1 + { 3 ; 6 ; 9 } @parameter ] + - location: 12 (remaining gas: 1039991.843 units remaining) + [ { 3 ; 6 ; 9 } @parameter + 1 ] + - location: 13 (remaining gas: 1039991.843 units remaining) + [ 3 @parameter.elt + 1 ] + - location: 15 (remaining gas: 1039991.739 units remaining) + [ 3 ] + - location: 13 (remaining gas: 1039991.724 units remaining) + [ 6 @parameter.elt + 3 ] + - location: 15 (remaining gas: 1039991.620 units remaining) + [ 18 ] + - location: 13 (remaining gas: 1039991.605 units remaining) + [ 9 @parameter.elt + 18 ] + - location: 15 (remaining gas: 1039991.501 units remaining) + [ 162 ] + - location: 13 (remaining gas: 1039991.486 units remaining) + [ 162 ] + - location: 16 (remaining gas: 1039991.471 units remaining) + [ {} + 162 ] + - location: 18 (remaining gas: 1039991.456 units remaining) + [ (Pair {} 162) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out new file mode 100644 index 000000000000..3b9c8e154e9e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }].out @@ -0,0 +1,136 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 1 ; 1 ; 1 }-{ 1 ; 2 ; 3 ; 4 }] + +storage + { 1 ; 2 ; 3 ; 4 } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039985.969 units remaining) + [ (Pair { 1 ; 1 ; 1 ; 1 } { 0 }) ] + - location: 9 (remaining gas: 1039985.959 units remaining) + [ { 1 ; 1 ; 1 ; 1 } @parameter ] + - location: 10 (remaining gas: 1039985.949 units remaining) + [ 0 + { 1 ; 1 ; 1 ; 1 } @parameter ] + - location: 13 (remaining gas: 1039985.939 units remaining) + [ { 1 ; 1 ; 1 ; 1 } @parameter + 0 ] + - location: 14 (remaining gas: 1039985.939 units remaining) + [ 1 @parameter.elt + 0 ] + - location: 16 (remaining gas: 1039985.924 units remaining) + [ 0 ] + - location: 18 (remaining gas: 1039985.914 units remaining) + [ 0 + 0 ] + - location: 16 (remaining gas: 1039985.884 units remaining) + [ 1 @parameter.elt + 0 + 0 ] + - location: 19 (remaining gas: 1039985.829 units remaining) + [ 1 + 0 ] + - location: 20 (remaining gas: 1039985.814 units remaining) + [ 0 ] + - location: 22 (remaining gas: 1039985.804 units remaining) + [ 1 + 0 ] + - location: 25 (remaining gas: 1039985.749 units remaining) + [ 1 ] + - location: 20 (remaining gas: 1039985.719 units remaining) + [ 1 + 1 ] + - location: 14 (remaining gas: 1039985.704 units remaining) + [ 1 @parameter.elt + 1 ] + - location: 16 (remaining gas: 1039985.689 units remaining) + [ 1 ] + - location: 18 (remaining gas: 1039985.679 units remaining) + [ 1 + 1 ] + - location: 16 (remaining gas: 1039985.649 units remaining) + [ 1 @parameter.elt + 1 + 1 ] + - location: 19 (remaining gas: 1039985.594 units remaining) + [ 2 + 1 ] + - location: 20 (remaining gas: 1039985.579 units remaining) + [ 1 ] + - location: 22 (remaining gas: 1039985.569 units remaining) + [ 1 + 1 ] + - location: 25 (remaining gas: 1039985.514 units remaining) + [ 2 ] + - location: 20 (remaining gas: 1039985.484 units remaining) + [ 2 + 2 ] + - location: 14 (remaining gas: 1039985.469 units remaining) + [ 1 @parameter.elt + 2 ] + - location: 16 (remaining gas: 1039985.454 units remaining) + [ 2 ] + - location: 18 (remaining gas: 1039985.444 units remaining) + [ 2 + 2 ] + - location: 16 (remaining gas: 1039985.414 units remaining) + [ 1 @parameter.elt + 2 + 2 ] + - location: 19 (remaining gas: 1039985.359 units remaining) + [ 3 + 2 ] + - location: 20 (remaining gas: 1039985.344 units remaining) + [ 2 ] + - location: 22 (remaining gas: 1039985.334 units remaining) + [ 1 + 2 ] + - location: 25 (remaining gas: 1039985.279 units remaining) + [ 3 ] + - location: 20 (remaining gas: 1039985.249 units remaining) + [ 3 + 3 ] + - location: 14 (remaining gas: 1039985.234 units remaining) + [ 1 @parameter.elt + 3 ] + - location: 16 (remaining gas: 1039985.219 units remaining) + [ 3 ] + - location: 18 (remaining gas: 1039985.209 units remaining) + [ 3 + 3 ] + - location: 16 (remaining gas: 1039985.179 units remaining) + [ 1 @parameter.elt + 3 + 3 ] + - location: 19 (remaining gas: 1039985.124 units remaining) + [ 4 + 3 ] + - location: 20 (remaining gas: 1039985.109 units remaining) + [ 3 ] + - location: 22 (remaining gas: 1039985.099 units remaining) + [ 1 + 3 ] + - location: 25 (remaining gas: 1039985.044 units remaining) + [ 4 ] + - location: 20 (remaining gas: 1039985.014 units remaining) + [ 4 + 4 ] + - location: 14 (remaining gas: 1039984.999 units remaining) + [ { 1 ; 2 ; 3 ; 4 } + 4 ] + - location: 26 (remaining gas: 1039984.984 units remaining) + [ {} + { 1 ; 2 ; 3 ; 4 } + 4 ] + - location: 28 (remaining gas: 1039984.969 units remaining) + [ (Pair {} { 1 ; 2 ; 3 ; 4 }) + 4 ] + - location: 29 (remaining gas: 1039984.954 units remaining) + [ 4 ] + - location: 31 (remaining gas: 1039984.944 units remaining) + [ ] + - location: 29 (remaining gas: 1039984.914 units remaining) + [ (Pair {} { 1 ; 2 ; 3 ; 4 }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out new file mode 100644 index 000000000000..f6621e550850 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }].out @@ -0,0 +1,136 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{ 1 ; 2 ; 3 ; 0 }-{ 1 ; 3 ; 5 ; 3 }] + +storage + { 1 ; 3 ; 5 ; 3 } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039985.969 units remaining) + [ (Pair { 1 ; 2 ; 3 ; 0 } { 0 }) ] + - location: 9 (remaining gas: 1039985.959 units remaining) + [ { 1 ; 2 ; 3 ; 0 } @parameter ] + - location: 10 (remaining gas: 1039985.949 units remaining) + [ 0 + { 1 ; 2 ; 3 ; 0 } @parameter ] + - location: 13 (remaining gas: 1039985.939 units remaining) + [ { 1 ; 2 ; 3 ; 0 } @parameter + 0 ] + - location: 14 (remaining gas: 1039985.939 units remaining) + [ 1 @parameter.elt + 0 ] + - location: 16 (remaining gas: 1039985.924 units remaining) + [ 0 ] + - location: 18 (remaining gas: 1039985.914 units remaining) + [ 0 + 0 ] + - location: 16 (remaining gas: 1039985.884 units remaining) + [ 1 @parameter.elt + 0 + 0 ] + - location: 19 (remaining gas: 1039985.829 units remaining) + [ 1 + 0 ] + - location: 20 (remaining gas: 1039985.814 units remaining) + [ 0 ] + - location: 22 (remaining gas: 1039985.804 units remaining) + [ 1 + 0 ] + - location: 25 (remaining gas: 1039985.749 units remaining) + [ 1 ] + - location: 20 (remaining gas: 1039985.719 units remaining) + [ 1 + 1 ] + - location: 14 (remaining gas: 1039985.704 units remaining) + [ 2 @parameter.elt + 1 ] + - location: 16 (remaining gas: 1039985.689 units remaining) + [ 1 ] + - location: 18 (remaining gas: 1039985.679 units remaining) + [ 1 + 1 ] + - location: 16 (remaining gas: 1039985.649 units remaining) + [ 2 @parameter.elt + 1 + 1 ] + - location: 19 (remaining gas: 1039985.594 units remaining) + [ 3 + 1 ] + - location: 20 (remaining gas: 1039985.579 units remaining) + [ 1 ] + - location: 22 (remaining gas: 1039985.569 units remaining) + [ 1 + 1 ] + - location: 25 (remaining gas: 1039985.514 units remaining) + [ 2 ] + - location: 20 (remaining gas: 1039985.484 units remaining) + [ 3 + 2 ] + - location: 14 (remaining gas: 1039985.469 units remaining) + [ 3 @parameter.elt + 2 ] + - location: 16 (remaining gas: 1039985.454 units remaining) + [ 2 ] + - location: 18 (remaining gas: 1039985.444 units remaining) + [ 2 + 2 ] + - location: 16 (remaining gas: 1039985.414 units remaining) + [ 3 @parameter.elt + 2 + 2 ] + - location: 19 (remaining gas: 1039985.359 units remaining) + [ 5 + 2 ] + - location: 20 (remaining gas: 1039985.344 units remaining) + [ 2 ] + - location: 22 (remaining gas: 1039985.334 units remaining) + [ 1 + 2 ] + - location: 25 (remaining gas: 1039985.279 units remaining) + [ 3 ] + - location: 20 (remaining gas: 1039985.249 units remaining) + [ 5 + 3 ] + - location: 14 (remaining gas: 1039985.234 units remaining) + [ 0 @parameter.elt + 3 ] + - location: 16 (remaining gas: 1039985.219 units remaining) + [ 3 ] + - location: 18 (remaining gas: 1039985.209 units remaining) + [ 3 + 3 ] + - location: 16 (remaining gas: 1039985.179 units remaining) + [ 0 @parameter.elt + 3 + 3 ] + - location: 19 (remaining gas: 1039985.124 units remaining) + [ 3 + 3 ] + - location: 20 (remaining gas: 1039985.109 units remaining) + [ 3 ] + - location: 22 (remaining gas: 1039985.099 units remaining) + [ 1 + 3 ] + - location: 25 (remaining gas: 1039985.044 units remaining) + [ 4 ] + - location: 20 (remaining gas: 1039985.014 units remaining) + [ 3 + 4 ] + - location: 14 (remaining gas: 1039984.999 units remaining) + [ { 1 ; 3 ; 5 ; 3 } + 4 ] + - location: 26 (remaining gas: 1039984.984 units remaining) + [ {} + { 1 ; 3 ; 5 ; 3 } + 4 ] + - location: 28 (remaining gas: 1039984.969 units remaining) + [ (Pair {} { 1 ; 3 ; 5 ; 3 }) + 4 ] + - location: 29 (remaining gas: 1039984.954 units remaining) + [ 4 ] + - location: 31 (remaining gas: 1039984.944 units remaining) + [ ] + - location: 29 (remaining gas: 1039984.914 units remaining) + [ (Pair {} { 1 ; 3 ; 5 ; 3 }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}].out new file mode 100644 index 000000000000..a4efd4c4e7c7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}].out @@ -0,0 +1,36 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_map_block.tz-{0}-{}-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039986.369 units remaining) + [ (Pair {} { 0 }) ] + - location: 9 (remaining gas: 1039986.359 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039986.349 units remaining) + [ 0 + {} @parameter ] + - location: 13 (remaining gas: 1039986.339 units remaining) + [ {} @parameter + 0 ] + - location: 14 (remaining gas: 1039986.339 units remaining) + [ {} + 0 ] + - location: 26 (remaining gas: 1039986.324 units remaining) + [ {} + {} + 0 ] + - location: 28 (remaining gas: 1039986.309 units remaining) + [ (Pair {} {}) + 0 ] + - location: 29 (remaining gas: 1039986.294 units remaining) + [ 0 ] + - location: 31 (remaining gas: 1039986.284 units remaining) + [ ] + - location: 29 (remaining gas: 1039986.254 units remaining) + [ (Pair {} {}) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out new file mode 100644 index 000000000000..b8aa5db61d9e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6] + +storage + 6 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.220 units remaining) + [ (Pair { 1 ; 2 ; 3 ; 4 ; 5 ; 6 } 111) ] + - location: 8 (remaining gas: 1039994.210 units remaining) + [ { 1 ; 2 ; 3 ; 4 ; 5 ; 6 } @parameter ] + - location: 9 (remaining gas: 1039994.195 units remaining) + [ 6 ] + - location: 10 (remaining gas: 1039994.180 units remaining) + [ {} + 6 ] + - location: 12 (remaining gas: 1039994.165 units remaining) + [ (Pair {} 6) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out new file mode 100644 index 000000000000..15754fc3681c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 ; 2 ; 3 }-3] + +storage + 3 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.520 units remaining) + [ (Pair { 1 ; 2 ; 3 } 111) ] + - location: 8 (remaining gas: 1039994.510 units remaining) + [ { 1 ; 2 ; 3 } @parameter ] + - location: 9 (remaining gas: 1039994.495 units remaining) + [ 3 ] + - location: 10 (remaining gas: 1039994.480 units remaining) + [ {} + 3 ] + - location: 12 (remaining gas: 1039994.465 units remaining) + [ (Pair {} 3) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1].out new file mode 100644 index 000000000000..371c740de31f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_size.tz-111-{ 1 }-1] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.720 units remaining) + [ (Pair { 1 } 111) ] + - location: 8 (remaining gas: 1039994.710 units remaining) + [ { 1 } @parameter ] + - location: 9 (remaining gas: 1039994.695 units remaining) + [ 1 ] + - location: 10 (remaining gas: 1039994.680 units remaining) + [ {} + 1 ] + - location: 12 (remaining gas: 1039994.665 units remaining) + [ (Pair {} 1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0].out new file mode 100644 index 000000000000..058a5faddf19 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[list_size.tz-111-{}-0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.820 units remaining) + [ (Pair {} 111) ] + - location: 8 (remaining gas: 1039994.810 units remaining) + [ {} @parameter ] + - location: 9 (remaining gas: 1039994.795 units remaining) + [ 0 ] + - location: 10 (remaining gas: 1039994.780 units remaining) + [ {} + 0 ] + - location: 12 (remaining gas: 1039994.765 units remaining) + [ (Pair {} 0) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" new file mode 100644 index 000000000000..a121fbfbae0e --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" @@ -0,0 +1,163 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[loop_left.tz-{""}-{ "c" ; "b" ; "a" }-{ "a" ; "b" ; "c" }] + +storage + { "a" ; "b" ; "c" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039977.710 units remaining) + [ (Pair { "c" ; "b" ; "a" } { "" }) ] + - location: 9 (remaining gas: 1039977.700 units remaining) + [ { "c" ; "b" ; "a" } @parameter ] + - location: 10 (remaining gas: 1039977.685 units remaining) + [ {} + { "c" ; "b" ; "a" } @parameter ] + - location: 12 (remaining gas: 1039977.675 units remaining) + [ { "c" ; "b" ; "a" } @parameter + {} ] + - location: 13 (remaining gas: 1039977.660 units remaining) + [ (Pair { "c" ; "b" ; "a" } {}) ] + - location: 14 (remaining gas: 1039977.645 units remaining) + [ (Left (Pair { "c" ; "b" ; "a" } {})) ] + - location: 17 (remaining gas: 1039977.645 units remaining) + [ (Pair { "c" ; "b" ; "a" } {}) ] + - location: 19 (remaining gas: 1039977.635 units remaining) + [ (Pair { "c" ; "b" ; "a" } {}) + (Pair { "c" ; "b" ; "a" } {}) ] + - location: 20 (remaining gas: 1039977.625 units remaining) + [ { "c" ; "b" ; "a" } @parameter + (Pair { "c" ; "b" ; "a" } {}) ] + - location: 21 (remaining gas: 1039977.610 units remaining) + [ (Pair { "c" ; "b" ; "a" } {}) ] + - location: 23 (remaining gas: 1039977.600 units remaining) + [ {} ] + - location: 21 (remaining gas: 1039977.570 units remaining) + [ { "c" ; "b" ; "a" } @parameter + {} ] + - location: 24 (remaining gas: 1039977.560 units remaining) + [ "c" @parameter.hd + { "b" ; "a" } @parameter.tl + {} ] + - location: 26 (remaining gas: 1039977.550 units remaining) + [ { "b" ; "a" } @parameter.tl + "c" @parameter.hd + {} ] + - location: 27 (remaining gas: 1039977.535 units remaining) + [ "c" @parameter.hd + {} ] + - location: 29 (remaining gas: 1039977.520 units remaining) + [ { "c" } ] + - location: 27 (remaining gas: 1039977.490 units remaining) + [ { "b" ; "a" } @parameter.tl + { "c" } ] + - location: 30 (remaining gas: 1039977.475 units remaining) + [ (Pair { "b" ; "a" } { "c" }) ] + - location: 31 (remaining gas: 1039977.460 units remaining) + [ (Left (Pair { "b" ; "a" } { "c" })) ] + - location: 24 (remaining gas: 1039977.445 units remaining) + [ (Left (Pair { "b" ; "a" } { "c" })) ] + - location: 17 (remaining gas: 1039977.430 units remaining) + [ (Pair { "b" ; "a" } { "c" }) ] + - location: 19 (remaining gas: 1039977.420 units remaining) + [ (Pair { "b" ; "a" } { "c" }) + (Pair { "b" ; "a" } { "c" }) ] + - location: 20 (remaining gas: 1039977.410 units remaining) + [ { "b" ; "a" } @parameter + (Pair { "b" ; "a" } { "c" }) ] + - location: 21 (remaining gas: 1039977.395 units remaining) + [ (Pair { "b" ; "a" } { "c" }) ] + - location: 23 (remaining gas: 1039977.385 units remaining) + [ { "c" } ] + - location: 21 (remaining gas: 1039977.355 units remaining) + [ { "b" ; "a" } @parameter + { "c" } ] + - location: 24 (remaining gas: 1039977.345 units remaining) + [ "b" @parameter.hd + { "a" } @parameter.tl + { "c" } ] + - location: 26 (remaining gas: 1039977.335 units remaining) + [ { "a" } @parameter.tl + "b" @parameter.hd + { "c" } ] + - location: 27 (remaining gas: 1039977.320 units remaining) + [ "b" @parameter.hd + { "c" } ] + - location: 29 (remaining gas: 1039977.305 units remaining) + [ { "b" ; "c" } ] + - location: 27 (remaining gas: 1039977.275 units remaining) + [ { "a" } @parameter.tl + { "b" ; "c" } ] + - location: 30 (remaining gas: 1039977.260 units remaining) + [ (Pair { "a" } { "b" ; "c" }) ] + - location: 31 (remaining gas: 1039977.245 units remaining) + [ (Left (Pair { "a" } { "b" ; "c" })) ] + - location: 24 (remaining gas: 1039977.230 units remaining) + [ (Left (Pair { "a" } { "b" ; "c" })) ] + - location: 17 (remaining gas: 1039977.215 units remaining) + [ (Pair { "a" } { "b" ; "c" }) ] + - location: 19 (remaining gas: 1039977.205 units remaining) + [ (Pair { "a" } { "b" ; "c" }) + (Pair { "a" } { "b" ; "c" }) ] + - location: 20 (remaining gas: 1039977.195 units remaining) + [ { "a" } @parameter + (Pair { "a" } { "b" ; "c" }) ] + - location: 21 (remaining gas: 1039977.180 units remaining) + [ (Pair { "a" } { "b" ; "c" }) ] + - location: 23 (remaining gas: 1039977.170 units remaining) + [ { "b" ; "c" } ] + - location: 21 (remaining gas: 1039977.140 units remaining) + [ { "a" } @parameter + { "b" ; "c" } ] + - location: 24 (remaining gas: 1039977.130 units remaining) + [ "a" @parameter.hd + {} @parameter.tl + { "b" ; "c" } ] + - location: 26 (remaining gas: 1039977.120 units remaining) + [ {} @parameter.tl + "a" @parameter.hd + { "b" ; "c" } ] + - location: 27 (remaining gas: 1039977.105 units remaining) + [ "a" @parameter.hd + { "b" ; "c" } ] + - location: 29 (remaining gas: 1039977.090 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 27 (remaining gas: 1039977.060 units remaining) + [ {} @parameter.tl + { "a" ; "b" ; "c" } ] + - location: 30 (remaining gas: 1039977.045 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) ] + - location: 31 (remaining gas: 1039977.030 units remaining) + [ (Left (Pair {} { "a" ; "b" ; "c" })) ] + - location: 24 (remaining gas: 1039977.015 units remaining) + [ (Left (Pair {} { "a" ; "b" ; "c" })) ] + - location: 17 (remaining gas: 1039977 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) ] + - location: 19 (remaining gas: 1039976.990 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) + (Pair {} { "a" ; "b" ; "c" }) ] + - location: 20 (remaining gas: 1039976.980 units remaining) + [ {} @parameter + (Pair {} { "a" ; "b" ; "c" }) ] + - location: 21 (remaining gas: 1039976.965 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) ] + - location: 23 (remaining gas: 1039976.955 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 21 (remaining gas: 1039976.925 units remaining) + [ {} @parameter + { "a" ; "b" ; "c" } ] + - location: 24 (remaining gas: 1039976.915 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 35 (remaining gas: 1039976.900 units remaining) + [ (Right { "a" ; "b" ; "c" }) ] + - location: 24 (remaining gas: 1039976.885 units remaining) + [ (Right { "a" ; "b" ; "c" }) ] + - location: 17 (remaining gas: 1039976.870 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 41 (remaining gas: 1039976.855 units remaining) + [ {} + { "a" ; "b" ; "c" } ] + - location: 43 (remaining gas: 1039976.840 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{}-{}].out" new file mode 100644 index 000000000000..127dcdfabce2 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[loop_left.tz-{\"\"}-{}-{}].out" @@ -0,0 +1,52 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[loop_left.tz-{""}-{}-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039978.082 units remaining) + [ (Pair {} { "" }) ] + - location: 9 (remaining gas: 1039978.072 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039978.057 units remaining) + [ {} + {} @parameter ] + - location: 12 (remaining gas: 1039978.047 units remaining) + [ {} @parameter + {} ] + - location: 13 (remaining gas: 1039978.032 units remaining) + [ (Pair {} {}) ] + - location: 14 (remaining gas: 1039978.017 units remaining) + [ (Left (Pair {} {})) ] + - location: 17 (remaining gas: 1039978.017 units remaining) + [ (Pair {} {}) ] + - location: 19 (remaining gas: 1039978.007 units remaining) + [ (Pair {} {}) + (Pair {} {}) ] + - location: 20 (remaining gas: 1039977.997 units remaining) + [ {} @parameter + (Pair {} {}) ] + - location: 21 (remaining gas: 1039977.982 units remaining) + [ (Pair {} {}) ] + - location: 23 (remaining gas: 1039977.972 units remaining) + [ {} ] + - location: 21 (remaining gas: 1039977.942 units remaining) + [ {} @parameter + {} ] + - location: 24 (remaining gas: 1039977.932 units remaining) + [ {} ] + - location: 35 (remaining gas: 1039977.917 units remaining) + [ (Right {}) ] + - location: 24 (remaining gas: 1039977.902 units remaining) + [ (Right {}) ] + - location: 17 (remaining gas: 1039977.887 units remaining) + [ {} ] + - location: 41 (remaining gas: 1039977.872 units remaining) + [ {} + {} ] + - location: 43 (remaining gas: 1039977.857 units remaining) + [ (Pair {} {}) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out new file mode 100644 index 000000000000..3e6e600e313d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }].out @@ -0,0 +1,19 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 ; Elt 3 4 }-{ Elt 0 0 ; Elt 3 4 }] + +storage + { Elt 0 0 ; Elt 3 4 } +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039993.699 units remaining) + [ (Pair { Elt 0 0 ; Elt 3 4 } {}) ] + - location: 11 (remaining gas: 1039993.689 units remaining) + [ { Elt 0 0 ; Elt 3 4 } @parameter ] + - location: 12 (remaining gas: 1039993.674 units remaining) + [ {} + { Elt 0 0 ; Elt 3 4 } @parameter ] + - location: 14 (remaining gas: 1039993.659 units remaining) + [ (Pair {} { Elt 0 0 ; Elt 3 4 }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out new file mode 100644 index 000000000000..ce1ad16cf869 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }].out @@ -0,0 +1,19 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 0 }-{ Elt 0 0 }] + +storage + { Elt 0 0 } +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039994.154 units remaining) + [ (Pair { Elt 0 0 } {}) ] + - location: 11 (remaining gas: 1039994.144 units remaining) + [ { Elt 0 0 } @parameter ] + - location: 12 (remaining gas: 1039994.129 units remaining) + [ {} + { Elt 0 0 } @parameter ] + - location: 14 (remaining gas: 1039994.114 units remaining) + [ (Pair {} { Elt 0 0 }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out new file mode 100644 index 000000000000..d1932e6dcb18 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }].out @@ -0,0 +1,19 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_id.tz-{}-{ Elt 0 1 }-{ Elt 0 1 }] + +storage + { Elt 0 1 } +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039994.154 units remaining) + [ (Pair { Elt 0 1 } {}) ] + - location: 11 (remaining gas: 1039994.144 units remaining) + [ { Elt 0 1 } @parameter ] + - location: 12 (remaining gas: 1039994.129 units remaining) + [ {} + { Elt 0 1 } @parameter ] + - location: 14 (remaining gas: 1039994.114 units remaining) + [ (Pair {} { Elt 0 1 }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out new file mode 100644 index 000000000000..f1bc24482162 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)].out @@ -0,0 +1,152 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 0 100 ; Elt 2 100 }-(Pair 2 200)] + +storage + (Pair 2 200) +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039978.509 units remaining) + [ (Pair { Elt 0 100 ; Elt 2 100 } 0 0) ] + - location: 11 (remaining gas: 1039978.499 units remaining) + [ { Elt 0 100 ; Elt 2 100 } @parameter ] + - location: 12 (remaining gas: 1039978.489 units remaining) + [ 0 @acc_e + { Elt 0 100 ; Elt 2 100 } @parameter ] + - location: 15 (remaining gas: 1039978.479 units remaining) + [ 0 @acc_k + 0 @acc_e + { Elt 0 100 ; Elt 2 100 } @parameter ] + - location: 18 (remaining gas: 1039978.464 units remaining) + [ (Pair 0 0) + { Elt 0 100 ; Elt 2 100 } @parameter ] + - location: 19 (remaining gas: 1039978.454 units remaining) + [ { Elt 0 100 ; Elt 2 100 } @parameter + (Pair 0 0) ] + - location: 20 (remaining gas: 1039978.454 units remaining) + [ (Pair 0 100) + (Pair 0 0) ] + - location: 22 (remaining gas: 1039978.439 units remaining) + [ (Pair 0 0) ] + - location: 24 (remaining gas: 1039978.429 units remaining) + [ (Pair 0 0) + (Pair 0 0) ] + - location: 25 (remaining gas: 1039978.419 units remaining) + [ 0 @acc_k + (Pair 0 0) ] + - location: 26 (remaining gas: 1039978.404 units remaining) + [ (Pair 0 0) ] + - location: 28 (remaining gas: 1039978.394 units remaining) + [ 0 @acc_e ] + - location: 26 (remaining gas: 1039978.364 units remaining) + [ 0 @acc_k + 0 @acc_e ] + - location: 22 (remaining gas: 1039978.334 units remaining) + [ (Pair 0 100) + 0 @acc_k + 0 @acc_e ] + - location: 29 (remaining gas: 1039978.324 units remaining) + [ (Pair 0 100) + (Pair 0 100) + 0 @acc_k + 0 @acc_e ] + - location: 30 (remaining gas: 1039978.309 units remaining) + [ (Pair 0 100) + 0 @acc_k + 0 @acc_e ] + - location: 32 (remaining gas: 1039978.299 units remaining) + [ 0 @key + 0 @acc_k + 0 @acc_e ] + - location: 33 (remaining gas: 1039978.244 units remaining) + [ 0 + 0 @acc_e ] + - location: 30 (remaining gas: 1039978.214 units remaining) + [ (Pair 0 100) + 0 + 0 @acc_e ] + - location: 34 (remaining gas: 1039978.204 units remaining) + [ 0 + (Pair 0 100) + 0 @acc_e ] + - location: 35 (remaining gas: 1039978.189 units remaining) + [ (Pair 0 100) + 0 @acc_e ] + - location: 37 (remaining gas: 1039978.179 units remaining) + [ 100 @elt + 0 @acc_e ] + - location: 38 (remaining gas: 1039978.124 units remaining) + [ 100 ] + - location: 35 (remaining gas: 1039978.094 units remaining) + [ 0 + 100 ] + - location: 39 (remaining gas: 1039978.079 units remaining) + [ (Pair 0 100) ] + - location: 20 (remaining gas: 1039978.064 units remaining) + [ (Pair 2 100) + (Pair 0 100) ] + - location: 22 (remaining gas: 1039978.049 units remaining) + [ (Pair 0 100) ] + - location: 24 (remaining gas: 1039978.039 units remaining) + [ (Pair 0 100) + (Pair 0 100) ] + - location: 25 (remaining gas: 1039978.029 units remaining) + [ 0 @acc_k + (Pair 0 100) ] + - location: 26 (remaining gas: 1039978.014 units remaining) + [ (Pair 0 100) ] + - location: 28 (remaining gas: 1039978.004 units remaining) + [ 100 @acc_e ] + - location: 26 (remaining gas: 1039977.974 units remaining) + [ 0 @acc_k + 100 @acc_e ] + - location: 22 (remaining gas: 1039977.944 units remaining) + [ (Pair 2 100) + 0 @acc_k + 100 @acc_e ] + - location: 29 (remaining gas: 1039977.934 units remaining) + [ (Pair 2 100) + (Pair 2 100) + 0 @acc_k + 100 @acc_e ] + - location: 30 (remaining gas: 1039977.919 units remaining) + [ (Pair 2 100) + 0 @acc_k + 100 @acc_e ] + - location: 32 (remaining gas: 1039977.909 units remaining) + [ 2 @key + 0 @acc_k + 100 @acc_e ] + - location: 33 (remaining gas: 1039977.854 units remaining) + [ 2 + 100 @acc_e ] + - location: 30 (remaining gas: 1039977.824 units remaining) + [ (Pair 2 100) + 2 + 100 @acc_e ] + - location: 34 (remaining gas: 1039977.814 units remaining) + [ 2 + (Pair 2 100) + 100 @acc_e ] + - location: 35 (remaining gas: 1039977.799 units remaining) + [ (Pair 2 100) + 100 @acc_e ] + - location: 37 (remaining gas: 1039977.789 units remaining) + [ 100 @elt + 100 @acc_e ] + - location: 38 (remaining gas: 1039977.734 units remaining) + [ 200 ] + - location: 35 (remaining gas: 1039977.704 units remaining) + [ 2 + 200 ] + - location: 39 (remaining gas: 1039977.689 units remaining) + [ (Pair 2 200) ] + - location: 20 (remaining gas: 1039977.674 units remaining) + [ (Pair 2 200) ] + - location: 40 (remaining gas: 1039977.659 units remaining) + [ {} + (Pair 2 200) ] + - location: 42 (remaining gas: 1039977.644 units remaining) + [ (Pair {} 2 200) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out new file mode 100644 index 000000000000..61dbfad8a435 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)].out @@ -0,0 +1,152 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_iter.tz-(Pair 0 0)-{ Elt 1 1 ; Elt 2 100 }-(Pair 3 101)] + +storage + (Pair 3 101) +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039978.509 units remaining) + [ (Pair { Elt 1 1 ; Elt 2 100 } 0 0) ] + - location: 11 (remaining gas: 1039978.499 units remaining) + [ { Elt 1 1 ; Elt 2 100 } @parameter ] + - location: 12 (remaining gas: 1039978.489 units remaining) + [ 0 @acc_e + { Elt 1 1 ; Elt 2 100 } @parameter ] + - location: 15 (remaining gas: 1039978.479 units remaining) + [ 0 @acc_k + 0 @acc_e + { Elt 1 1 ; Elt 2 100 } @parameter ] + - location: 18 (remaining gas: 1039978.464 units remaining) + [ (Pair 0 0) + { Elt 1 1 ; Elt 2 100 } @parameter ] + - location: 19 (remaining gas: 1039978.454 units remaining) + [ { Elt 1 1 ; Elt 2 100 } @parameter + (Pair 0 0) ] + - location: 20 (remaining gas: 1039978.454 units remaining) + [ (Pair 1 1) + (Pair 0 0) ] + - location: 22 (remaining gas: 1039978.439 units remaining) + [ (Pair 0 0) ] + - location: 24 (remaining gas: 1039978.429 units remaining) + [ (Pair 0 0) + (Pair 0 0) ] + - location: 25 (remaining gas: 1039978.419 units remaining) + [ 0 @acc_k + (Pair 0 0) ] + - location: 26 (remaining gas: 1039978.404 units remaining) + [ (Pair 0 0) ] + - location: 28 (remaining gas: 1039978.394 units remaining) + [ 0 @acc_e ] + - location: 26 (remaining gas: 1039978.364 units remaining) + [ 0 @acc_k + 0 @acc_e ] + - location: 22 (remaining gas: 1039978.334 units remaining) + [ (Pair 1 1) + 0 @acc_k + 0 @acc_e ] + - location: 29 (remaining gas: 1039978.324 units remaining) + [ (Pair 1 1) + (Pair 1 1) + 0 @acc_k + 0 @acc_e ] + - location: 30 (remaining gas: 1039978.309 units remaining) + [ (Pair 1 1) + 0 @acc_k + 0 @acc_e ] + - location: 32 (remaining gas: 1039978.299 units remaining) + [ 1 @key + 0 @acc_k + 0 @acc_e ] + - location: 33 (remaining gas: 1039978.244 units remaining) + [ 1 + 0 @acc_e ] + - location: 30 (remaining gas: 1039978.214 units remaining) + [ (Pair 1 1) + 1 + 0 @acc_e ] + - location: 34 (remaining gas: 1039978.204 units remaining) + [ 1 + (Pair 1 1) + 0 @acc_e ] + - location: 35 (remaining gas: 1039978.189 units remaining) + [ (Pair 1 1) + 0 @acc_e ] + - location: 37 (remaining gas: 1039978.179 units remaining) + [ 1 @elt + 0 @acc_e ] + - location: 38 (remaining gas: 1039978.124 units remaining) + [ 1 ] + - location: 35 (remaining gas: 1039978.094 units remaining) + [ 1 + 1 ] + - location: 39 (remaining gas: 1039978.079 units remaining) + [ (Pair 1 1) ] + - location: 20 (remaining gas: 1039978.064 units remaining) + [ (Pair 2 100) + (Pair 1 1) ] + - location: 22 (remaining gas: 1039978.049 units remaining) + [ (Pair 1 1) ] + - location: 24 (remaining gas: 1039978.039 units remaining) + [ (Pair 1 1) + (Pair 1 1) ] + - location: 25 (remaining gas: 1039978.029 units remaining) + [ 1 @acc_k + (Pair 1 1) ] + - location: 26 (remaining gas: 1039978.014 units remaining) + [ (Pair 1 1) ] + - location: 28 (remaining gas: 1039978.004 units remaining) + [ 1 @acc_e ] + - location: 26 (remaining gas: 1039977.974 units remaining) + [ 1 @acc_k + 1 @acc_e ] + - location: 22 (remaining gas: 1039977.944 units remaining) + [ (Pair 2 100) + 1 @acc_k + 1 @acc_e ] + - location: 29 (remaining gas: 1039977.934 units remaining) + [ (Pair 2 100) + (Pair 2 100) + 1 @acc_k + 1 @acc_e ] + - location: 30 (remaining gas: 1039977.919 units remaining) + [ (Pair 2 100) + 1 @acc_k + 1 @acc_e ] + - location: 32 (remaining gas: 1039977.909 units remaining) + [ 2 @key + 1 @acc_k + 1 @acc_e ] + - location: 33 (remaining gas: 1039977.854 units remaining) + [ 3 + 1 @acc_e ] + - location: 30 (remaining gas: 1039977.824 units remaining) + [ (Pair 2 100) + 3 + 1 @acc_e ] + - location: 34 (remaining gas: 1039977.814 units remaining) + [ 3 + (Pair 2 100) + 1 @acc_e ] + - location: 35 (remaining gas: 1039977.799 units remaining) + [ (Pair 2 100) + 1 @acc_e ] + - location: 37 (remaining gas: 1039977.789 units remaining) + [ 100 @elt + 1 @acc_e ] + - location: 38 (remaining gas: 1039977.734 units remaining) + [ 101 ] + - location: 35 (remaining gas: 1039977.704 units remaining) + [ 3 + 101 ] + - location: 39 (remaining gas: 1039977.689 units remaining) + [ (Pair 3 101) ] + - location: 20 (remaining gas: 1039977.674 units remaining) + [ (Pair 3 101) ] + - location: 40 (remaining gas: 1039977.659 units remaining) + [ {} + (Pair 3 101) ] + - location: 42 (remaining gas: 1039977.644 units remaining) + [ (Pair {} 3 101) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"bar\" 5 ; Elt \"foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"bar\" 5 ; Elt \"foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" new file mode 100644 index 000000000000..ff415657be0f --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"bar\" 5 ; Elt \"foo\" 1 }-15-{ Elt \"bar\".12b9d73d5a.out" @@ -0,0 +1,68 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt "bar" 5 ; Elt "foo" 1 }-15-{ Elt "bar" 20 ; Elt "foo" 16 }] + +storage + { Elt "bar" 20 ; Elt "foo" 16 } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039988.041 units remaining) + [ (Pair 15 { Elt "bar" 5 ; Elt "foo" 1 }) ] + - location: 9 (remaining gas: 1039988.031 units remaining) + [ 15 @parameter + { Elt "bar" 5 ; Elt "foo" 1 } @storage ] + - location: 10 (remaining gas: 1039988.021 units remaining) + [ { Elt "bar" 5 ; Elt "foo" 1 } @storage + 15 @parameter ] + - location: 11 (remaining gas: 1039988.021 units remaining) + [ (Pair "bar" 5) + 15 @parameter ] + - location: 13 (remaining gas: 1039988.011 units remaining) + [ 5 @elt + 15 @parameter ] + - location: 14 (remaining gas: 1039987.996 units remaining) + [ 15 @parameter ] + - location: 16 (remaining gas: 1039987.986 units remaining) + [ 15 @parameter + 15 @parameter ] + - location: 14 (remaining gas: 1039987.956 units remaining) + [ 5 @elt + 15 @parameter + 15 @parameter ] + - location: 17 (remaining gas: 1039987.901 units remaining) + [ 20 + 15 @parameter ] + - location: 11 (remaining gas: 1039987.886 units remaining) + [ (Pair "foo" 1) + 15 @parameter ] + - location: 13 (remaining gas: 1039987.876 units remaining) + [ 1 @elt + 15 @parameter ] + - location: 14 (remaining gas: 1039987.861 units remaining) + [ 15 @parameter ] + - location: 16 (remaining gas: 1039987.851 units remaining) + [ 15 @parameter + 15 @parameter ] + - location: 14 (remaining gas: 1039987.821 units remaining) + [ 1 @elt + 15 @parameter + 15 @parameter ] + - location: 17 (remaining gas: 1039987.766 units remaining) + [ 16 + 15 @parameter ] + - location: 11 (remaining gas: 1039987.751 units remaining) + [ { Elt "bar" 20 ; Elt "foo" 16 } + 15 @parameter ] + - location: 18 (remaining gas: 1039987.736 units remaining) + [ 15 @parameter ] + - location: 20 (remaining gas: 1039987.726 units remaining) + [ ] + - location: 18 (remaining gas: 1039987.696 units remaining) + [ { Elt "bar" 20 ; Elt "foo" 16 } ] + - location: 21 (remaining gas: 1039987.681 units remaining) + [ {} + { Elt "bar" 20 ; Elt "foo" 16 } ] + - location: 23 (remaining gas: 1039987.666 units remaining) + [ (Pair {} { Elt "bar" 20 ; Elt "foo" 16 }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" new file mode 100644 index 000000000000..9cb0ff466142 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt \"foo\" 1 }-10-{ Elt \"foo\" 11 }].out" @@ -0,0 +1,50 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_map.tz-{ Elt "foo" 1 }-10-{ Elt "foo" 11 }] + +storage + { Elt "foo" 11 } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039988.540 units remaining) + [ (Pair 10 { Elt "foo" 1 }) ] + - location: 9 (remaining gas: 1039988.530 units remaining) + [ 10 @parameter + { Elt "foo" 1 } @storage ] + - location: 10 (remaining gas: 1039988.520 units remaining) + [ { Elt "foo" 1 } @storage + 10 @parameter ] + - location: 11 (remaining gas: 1039988.520 units remaining) + [ (Pair "foo" 1) + 10 @parameter ] + - location: 13 (remaining gas: 1039988.510 units remaining) + [ 1 @elt + 10 @parameter ] + - location: 14 (remaining gas: 1039988.495 units remaining) + [ 10 @parameter ] + - location: 16 (remaining gas: 1039988.485 units remaining) + [ 10 @parameter + 10 @parameter ] + - location: 14 (remaining gas: 1039988.455 units remaining) + [ 1 @elt + 10 @parameter + 10 @parameter ] + - location: 17 (remaining gas: 1039988.400 units remaining) + [ 11 + 10 @parameter ] + - location: 11 (remaining gas: 1039988.385 units remaining) + [ { Elt "foo" 11 } + 10 @parameter ] + - location: 18 (remaining gas: 1039988.370 units remaining) + [ 10 @parameter ] + - location: 20 (remaining gas: 1039988.360 units remaining) + [ ] + - location: 18 (remaining gas: 1039988.330 units remaining) + [ { Elt "foo" 11 } ] + - location: 21 (remaining gas: 1039988.315 units remaining) + [ {} + { Elt "foo" 11 } ] + - location: 23 (remaining gas: 1039988.300 units remaining) + [ (Pair {} { Elt "foo" 11 }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}].out new file mode 100644 index 000000000000..8760d9c7de28 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_map.tz-{}-10-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039988.934 units remaining) + [ (Pair 10 {}) ] + - location: 9 (remaining gas: 1039988.924 units remaining) + [ 10 @parameter + {} @storage ] + - location: 10 (remaining gas: 1039988.914 units remaining) + [ {} @storage + 10 @parameter ] + - location: 11 (remaining gas: 1039988.914 units remaining) + [ {} + 10 @parameter ] + - location: 18 (remaining gas: 1039988.899 units remaining) + [ 10 @parameter ] + - location: 20 (remaining gas: 1039988.889 units remaining) + [ ] + - location: 18 (remaining gas: 1039988.859 units remaining) + [ {} ] + - location: 21 (remaining gas: 1039988.844 units remaining) + [ {} + {} ] + - location: 23 (remaining gas: 1039988.829 units remaining) + [ (Pair {} {}) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 .7396e5f090.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 .7396e5f090.out new file mode 100644 index 000000000000..10374688bda7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 .7396e5f090.out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 0 1 } None)-1-(Pair { Elt 0 1 } (Some False))] + +storage + (Pair { Elt 0 1 } (Some False)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039988.154 units remaining) + [ (Pair 1 { Elt 0 1 } None) ] + - location: 12 (remaining gas: 1039988.144 units remaining) + [ 1 @parameter + (Pair { Elt 0 1 } None) @storage ] + - location: 13 (remaining gas: 1039988.129 units remaining) + [ (Pair { Elt 0 1 } None) @storage ] + - location: 15 (remaining gas: 1039988.119 units remaining) + [ { Elt 0 1 } ] + - location: 16 (remaining gas: 1039988.109 units remaining) + [ { Elt 0 1 } + { Elt 0 1 } ] + - location: 13 (remaining gas: 1039988.079 units remaining) + [ 1 @parameter + { Elt 0 1 } + { Elt 0 1 } ] + - location: 17 (remaining gas: 1039987.929 units remaining) + [ False + { Elt 0 1 } ] + - location: 18 (remaining gas: 1039987.914 units remaining) + [ (Some False) + { Elt 0 1 } ] + - location: 19 (remaining gas: 1039987.904 units remaining) + [ { Elt 0 1 } + (Some False) ] + - location: 20 (remaining gas: 1039987.889 units remaining) + [ (Pair { Elt 0 1 } (Some False)) ] + - location: 21 (remaining gas: 1039987.874 units remaining) + [ {} + (Pair { Elt 0 1 } (Some False)) ] + - location: 23 (remaining gas: 1039987.859 units remaining) + [ (Pair {} { Elt 0 1 } (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out new file mode 100644 index 000000000000..cb796ca357d8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 .cef8ce601a.out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 0 } None)-1-(Pair { Elt 1 0 } (Some True))] + +storage + (Pair { Elt 1 0 } (Some True)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039988.154 units remaining) + [ (Pair 1 { Elt 1 0 } None) ] + - location: 12 (remaining gas: 1039988.144 units remaining) + [ 1 @parameter + (Pair { Elt 1 0 } None) @storage ] + - location: 13 (remaining gas: 1039988.129 units remaining) + [ (Pair { Elt 1 0 } None) @storage ] + - location: 15 (remaining gas: 1039988.119 units remaining) + [ { Elt 1 0 } ] + - location: 16 (remaining gas: 1039988.109 units remaining) + [ { Elt 1 0 } + { Elt 1 0 } ] + - location: 13 (remaining gas: 1039988.079 units remaining) + [ 1 @parameter + { Elt 1 0 } + { Elt 1 0 } ] + - location: 17 (remaining gas: 1039987.929 units remaining) + [ True + { Elt 1 0 } ] + - location: 18 (remaining gas: 1039987.914 units remaining) + [ (Some True) + { Elt 1 0 } ] + - location: 19 (remaining gas: 1039987.904 units remaining) + [ { Elt 1 0 } + (Some True) ] + - location: 20 (remaining gas: 1039987.889 units remaining) + [ (Pair { Elt 1 0 } (Some True)) ] + - location: 21 (remaining gas: 1039987.874 units remaining) + [ {} + (Pair { Elt 1 0 } (Some True)) ] + - location: 23 (remaining gas: 1039987.859 units remaining) + [ (Pair {} { Elt 1 0 } (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out new file mode 100644 index 000000000000..7bdeef3d3c56 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pa.1a55a5bfa5.out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-1-(Pair { Elt 1 4 ; Elt 2 11 } (Some True))] + +storage + (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039987.699 units remaining) + [ (Pair 1 { Elt 1 4 ; Elt 2 11 } None) ] + - location: 12 (remaining gas: 1039987.689 units remaining) + [ 1 @parameter + (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 13 (remaining gas: 1039987.674 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 15 (remaining gas: 1039987.664 units remaining) + [ { Elt 1 4 ; Elt 2 11 } ] + - location: 16 (remaining gas: 1039987.654 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 13 (remaining gas: 1039987.624 units remaining) + [ 1 @parameter + { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 17 (remaining gas: 1039987.439 units remaining) + [ True + { Elt 1 4 ; Elt 2 11 } ] + - location: 18 (remaining gas: 1039987.424 units remaining) + [ (Some True) + { Elt 1 4 ; Elt 2 11 } ] + - location: 19 (remaining gas: 1039987.414 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + (Some True) ] + - location: 20 (remaining gas: 1039987.399 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 21 (remaining gas: 1039987.384 units remaining) + [ {} + (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 23 (remaining gas: 1039987.369 units remaining) + [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out new file mode 100644 index 000000000000..14a5f6d3c18a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pa.89cc24d256.out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-2-(Pair { Elt 1 4 ; Elt 2 11 } (Some True))] + +storage + (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039987.699 units remaining) + [ (Pair 2 { Elt 1 4 ; Elt 2 11 } None) ] + - location: 12 (remaining gas: 1039987.689 units remaining) + [ 2 @parameter + (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 13 (remaining gas: 1039987.674 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 15 (remaining gas: 1039987.664 units remaining) + [ { Elt 1 4 ; Elt 2 11 } ] + - location: 16 (remaining gas: 1039987.654 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 13 (remaining gas: 1039987.624 units remaining) + [ 2 @parameter + { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 17 (remaining gas: 1039987.439 units remaining) + [ True + { Elt 1 4 ; Elt 2 11 } ] + - location: 18 (remaining gas: 1039987.424 units remaining) + [ (Some True) + { Elt 1 4 ; Elt 2 11 } ] + - location: 19 (remaining gas: 1039987.414 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + (Some True) ] + - location: 20 (remaining gas: 1039987.399 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 21 (remaining gas: 1039987.384 units remaining) + [ {} + (Pair { Elt 1 4 ; Elt 2 11 } (Some True)) ] + - location: 23 (remaining gas: 1039987.369 units remaining) + [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out new file mode 100644 index 000000000000..abb8917ba56f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pa.2fba3165c0.out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair { Elt 1 4 ; Elt 2 11 } None)-3-(Pair { Elt 1 4 ; Elt 2 11 } (Some False))] + +storage + (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039987.699 units remaining) + [ (Pair 3 { Elt 1 4 ; Elt 2 11 } None) ] + - location: 12 (remaining gas: 1039987.689 units remaining) + [ 3 @parameter + (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 13 (remaining gas: 1039987.674 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } None) @storage ] + - location: 15 (remaining gas: 1039987.664 units remaining) + [ { Elt 1 4 ; Elt 2 11 } ] + - location: 16 (remaining gas: 1039987.654 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 13 (remaining gas: 1039987.624 units remaining) + [ 3 @parameter + { Elt 1 4 ; Elt 2 11 } + { Elt 1 4 ; Elt 2 11 } ] + - location: 17 (remaining gas: 1039987.439 units remaining) + [ False + { Elt 1 4 ; Elt 2 11 } ] + - location: 18 (remaining gas: 1039987.424 units remaining) + [ (Some False) + { Elt 1 4 ; Elt 2 11 } ] + - location: 19 (remaining gas: 1039987.414 units remaining) + [ { Elt 1 4 ; Elt 2 11 } + (Some False) ] + - location: 20 (remaining gas: 1039987.399 units remaining) + [ (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] + - location: 21 (remaining gas: 1039987.384 units remaining) + [ {} + (Pair { Elt 1 4 ; Elt 2 11 } (Some False)) ] + - location: 23 (remaining gas: 1039987.369 units remaining) + [ (Pair {} { Elt 1 4 ; Elt 2 11 } (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))].out new file mode 100644 index 000000000000..a694a3b068f4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))].out @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_nat.tz-(Pair {} None)-1-(Pair {} (Some False))] + +storage + (Pair {} (Some False)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039988.504 units remaining) + [ (Pair 1 {} None) ] + - location: 12 (remaining gas: 1039988.494 units remaining) + [ 1 @parameter + (Pair {} None) @storage ] + - location: 13 (remaining gas: 1039988.479 units remaining) + [ (Pair {} None) @storage ] + - location: 15 (remaining gas: 1039988.469 units remaining) + [ {} ] + - location: 16 (remaining gas: 1039988.459 units remaining) + [ {} + {} ] + - location: 13 (remaining gas: 1039988.429 units remaining) + [ 1 @parameter + {} + {} ] + - location: 17 (remaining gas: 1039988.314 units remaining) + [ False + {} ] + - location: 18 (remaining gas: 1039988.299 units remaining) + [ (Some False) + {} ] + - location: 19 (remaining gas: 1039988.289 units remaining) + [ {} + (Some False) ] + - location: 20 (remaining gas: 1039988.274 units remaining) + [ (Pair {} (Some False)) ] + - location: 21 (remaining gas: 1039988.259 units remaining) + [ {} + (Pair {} (Some False)) ] + - location: 23 (remaining gas: 1039988.244 units remaining) + [ (Pair {} {} (Some False)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" new file mode 100644 index 000000000000..2b97af7a2e53 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .6d625e02a5.out" @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"bar"-(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True))] + +storage + (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039987.567 units remaining) + [ (Pair "bar" { Elt "bar" 4 ; Elt "foo" 11 } None) ] + - location: 12 (remaining gas: 1039987.557 units remaining) + [ "bar" @parameter + (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 13 (remaining gas: 1039987.542 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 15 (remaining gas: 1039987.532 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 16 (remaining gas: 1039987.522 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 13 (remaining gas: 1039987.492 units remaining) + [ "bar" @parameter + { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 17 (remaining gas: 1039987.307 units remaining) + [ True + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 18 (remaining gas: 1039987.292 units remaining) + [ (Some True) + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 19 (remaining gas: 1039987.282 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + (Some True) ] + - location: 20 (remaining gas: 1039987.267 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + - location: 21 (remaining gas: 1039987.252 units remaining) + [ {} + (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + - location: 23 (remaining gas: 1039987.237 units remaining) + [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" new file mode 100644 index 000000000000..2373d63fabe3 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .a7e3837a82.out" @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"foo"-(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True))] + +storage + (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039987.567 units remaining) + [ (Pair "foo" { Elt "bar" 4 ; Elt "foo" 11 } None) ] + - location: 12 (remaining gas: 1039987.557 units remaining) + [ "foo" @parameter + (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 13 (remaining gas: 1039987.542 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 15 (remaining gas: 1039987.532 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 16 (remaining gas: 1039987.522 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 13 (remaining gas: 1039987.492 units remaining) + [ "foo" @parameter + { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 17 (remaining gas: 1039987.307 units remaining) + [ True + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 18 (remaining gas: 1039987.292 units remaining) + [ (Some True) + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 19 (remaining gas: 1039987.282 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + (Some True) ] + - location: 20 (remaining gas: 1039987.267 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + - location: 21 (remaining gas: 1039987.252 units remaining) + [ {} + (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + - location: 23 (remaining gas: 1039987.237 units remaining) + [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" new file mode 100644 index 000000000000..25cb7f94f8a4 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"bar\" 4 ; Elt \"foo\" 11 } .c7716fe79e.out" @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)-"baz"-(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False))] + +storage + (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039987.567 units remaining) + [ (Pair "baz" { Elt "bar" 4 ; Elt "foo" 11 } None) ] + - location: 12 (remaining gas: 1039987.557 units remaining) + [ "baz" @parameter + (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 13 (remaining gas: 1039987.542 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } None) @storage ] + - location: 15 (remaining gas: 1039987.532 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 16 (remaining gas: 1039987.522 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 13 (remaining gas: 1039987.492 units remaining) + [ "baz" @parameter + { Elt "bar" 4 ; Elt "foo" 11 } + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 17 (remaining gas: 1039987.307 units remaining) + [ False + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 18 (remaining gas: 1039987.292 units remaining) + [ (Some False) + { Elt "bar" 4 ; Elt "foo" 11 } ] + - location: 19 (remaining gas: 1039987.282 units remaining) + [ { Elt "bar" 4 ; Elt "foo" 11 } + (Some False) ] + - location: 20 (remaining gas: 1039987.267 units remaining) + [ (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] + - location: 21 (remaining gas: 1039987.252 units remaining) + [ {} + (Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] + - location: 23 (remaining gas: 1039987.237 units remaining) + [ (Pair {} { Elt "bar" 4 ; Elt "foo" 11 } (Some False)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" new file mode 100644 index 000000000000..1793c4146a13 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 0 } None)-\"foo\"-(Pa.7861a3b1e2.out" @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "foo" 0 } None)-"foo"-(Pair { Elt "foo" 0 } (Some True))] + +storage + (Pair { Elt "foo" 0 } (Some True)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039988.066 units remaining) + [ (Pair "foo" { Elt "foo" 0 } None) ] + - location: 12 (remaining gas: 1039988.056 units remaining) + [ "foo" @parameter + (Pair { Elt "foo" 0 } None) @storage ] + - location: 13 (remaining gas: 1039988.041 units remaining) + [ (Pair { Elt "foo" 0 } None) @storage ] + - location: 15 (remaining gas: 1039988.031 units remaining) + [ { Elt "foo" 0 } ] + - location: 16 (remaining gas: 1039988.021 units remaining) + [ { Elt "foo" 0 } + { Elt "foo" 0 } ] + - location: 13 (remaining gas: 1039987.991 units remaining) + [ "foo" @parameter + { Elt "foo" 0 } + { Elt "foo" 0 } ] + - location: 17 (remaining gas: 1039987.841 units remaining) + [ True + { Elt "foo" 0 } ] + - location: 18 (remaining gas: 1039987.826 units remaining) + [ (Some True) + { Elt "foo" 0 } ] + - location: 19 (remaining gas: 1039987.816 units remaining) + [ { Elt "foo" 0 } + (Some True) ] + - location: 20 (remaining gas: 1039987.801 units remaining) + [ (Pair { Elt "foo" 0 } (Some True)) ] + - location: 21 (remaining gas: 1039987.786 units remaining) + [ {} + (Pair { Elt "foo" 0 } (Some True)) ] + - location: 23 (remaining gas: 1039987.771 units remaining) + [ (Pair {} { Elt "foo" 0 } (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" new file mode 100644 index 000000000000..ed7a9995a660 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt \"foo\" 1 } None)-\"bar\"-(Pa.fa8366e8a8.out" @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair { Elt "foo" 1 } None)-"bar"-(Pair { Elt "foo" 1 } (Some False))] + +storage + (Pair { Elt "foo" 1 } (Some False)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039988.066 units remaining) + [ (Pair "bar" { Elt "foo" 1 } None) ] + - location: 12 (remaining gas: 1039988.056 units remaining) + [ "bar" @parameter + (Pair { Elt "foo" 1 } None) @storage ] + - location: 13 (remaining gas: 1039988.041 units remaining) + [ (Pair { Elt "foo" 1 } None) @storage ] + - location: 15 (remaining gas: 1039988.031 units remaining) + [ { Elt "foo" 1 } ] + - location: 16 (remaining gas: 1039988.021 units remaining) + [ { Elt "foo" 1 } + { Elt "foo" 1 } ] + - location: 13 (remaining gas: 1039987.991 units remaining) + [ "bar" @parameter + { Elt "foo" 1 } + { Elt "foo" 1 } ] + - location: 17 (remaining gas: 1039987.841 units remaining) + [ False + { Elt "foo" 1 } ] + - location: 18 (remaining gas: 1039987.826 units remaining) + [ (Some False) + { Elt "foo" 1 } ] + - location: 19 (remaining gas: 1039987.816 units remaining) + [ { Elt "foo" 1 } + (Some False) ] + - location: 20 (remaining gas: 1039987.801 units remaining) + [ (Pair { Elt "foo" 1 } (Some False)) ] + - location: 21 (remaining gas: 1039987.786 units remaining) + [ {} + (Pair { Elt "foo" 1 } (Some False)) ] + - location: 23 (remaining gas: 1039987.771 units remaining) + [ (Pair {} { Elt "foo" 1 } (Some False)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair {} (Some False))].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair {} (Some False))].out" new file mode 100644 index 000000000000..d8eaa16bfc05 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-\"bar\"-(Pair {} (Some False))].out" @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_mem_string.tz-(Pair {} None)-"bar"-(Pair {} (Some False))] + +storage + (Pair {} (Some False)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039988.460 units remaining) + [ (Pair "bar" {} None) ] + - location: 12 (remaining gas: 1039988.450 units remaining) + [ "bar" @parameter + (Pair {} None) @storage ] + - location: 13 (remaining gas: 1039988.435 units remaining) + [ (Pair {} None) @storage ] + - location: 15 (remaining gas: 1039988.425 units remaining) + [ {} ] + - location: 16 (remaining gas: 1039988.415 units remaining) + [ {} + {} ] + - location: 13 (remaining gas: 1039988.385 units remaining) + [ "bar" @parameter + {} + {} ] + - location: 17 (remaining gas: 1039988.270 units remaining) + [ False + {} ] + - location: 18 (remaining gas: 1039988.255 units remaining) + [ (Some False) + {} ] + - location: 19 (remaining gas: 1039988.245 units remaining) + [ {} + (Some False) ] + - location: 20 (remaining gas: 1039988.230 units remaining) + [ (Pair {} (Some False)) ] + - location: 21 (remaining gas: 1039988.215 units remaining) + [ {} + (Pair {} (Some False)) ] + - location: 23 (remaining gas: 1039988.200 units remaining) + [ (Pair {} {} (Some False)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" new file mode 100644 index 000000000000..6a9d61d2fa04 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 ; .1da2c2c3fa.out" @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 ; Elt "d" 4 ; Elt "e" 5 ; Elt "f" 6 }-6] + +storage + 6 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039991.503 units remaining) + [ (Pair { Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 ; Elt "d" 4 ; Elt "e" 5 ; Elt "f" 6 } 111) ] + - location: 9 (remaining gas: 1039991.493 units remaining) + [ { Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 ; Elt "d" 4 ; Elt "e" 5 ; Elt "f" 6 } @parameter ] + - location: 10 (remaining gas: 1039991.478 units remaining) + [ 6 ] + - location: 11 (remaining gas: 1039991.463 units remaining) + [ {} + 6 ] + - location: 13 (remaining gas: 1039991.448 units remaining) + [ (Pair {} 6) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" new file mode 100644 index 000000000000..3c98980d1d46 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 ; Elt \"b\" 2 ; Elt \"c\" 3 }-3].out" @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 }-3] + +storage + 3 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039993.290 units remaining) + [ (Pair { Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 } 111) ] + - location: 9 (remaining gas: 1039993.280 units remaining) + [ { Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 } @parameter ] + - location: 10 (remaining gas: 1039993.265 units remaining) + [ 3 ] + - location: 11 (remaining gas: 1039993.250 units remaining) + [ {} + 3 ] + - location: 13 (remaining gas: 1039993.235 units remaining) + [ (Pair {} 3) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 }-1].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 }-1].out" new file mode 100644 index 000000000000..8d19f5b7c50b --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt \"a\" 1 }-1].out" @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_size.tz-111-{ Elt "a" 1 }-1] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039994.318 units remaining) + [ (Pair { Elt "a" 1 } 111) ] + - location: 9 (remaining gas: 1039994.308 units remaining) + [ { Elt "a" 1 } @parameter ] + - location: 10 (remaining gas: 1039994.293 units remaining) + [ 1 ] + - location: 11 (remaining gas: 1039994.278 units remaining) + [ {} + 1 ] + - location: 13 (remaining gas: 1039994.263 units remaining) + [ (Pair {} 1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0].out new file mode 100644 index 000000000000..8d7ef741acac --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[map_size.tz-111-{}-0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039994.692 units remaining) + [ (Pair {} 111) ] + - location: 9 (remaining gas: 1039994.682 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039994.667 units remaining) + [ 0 ] + - location: 11 (remaining gas: 1039994.652 units remaining) + [ {} + 0 ] + - location: 13 (remaining gas: 1039994.637 units remaining) + [ (Pair {} 0) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit].out new file mode 100644 index 000000000000..cec0840b05ac --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit].out @@ -0,0 +1,131 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[mul.tz-Unit-Unit-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039944.576 units remaining) + [ (Pair Unit Unit) ] + - location: 7 (remaining gas: 1039944.566 units remaining) + [ Unit @parameter ] + - location: 8 (remaining gas: 1039944.556 units remaining) + [ ] + - location: 9 (remaining gas: 1039944.546 units remaining) + [ 7987 ] + - location: 12 (remaining gas: 1039944.536 units remaining) + [ 10 + 7987 ] + - location: 15 (remaining gas: 1039944.536 units remaining) + [ 79870 ] + - location: 16 (remaining gas: 1039944.526 units remaining) + [ 79870 + 79870 ] + - location: 19 (remaining gas: 1039944.491 units remaining) + [ 0 ] + - location: 21 (remaining gas: 1039944.476 units remaining) + [ True ] + - location: 22 (remaining gas: 1039944.466 units remaining) + [ ] + - location: 22 (remaining gas: 1039944.451 units remaining) + [ ] + - location: 28 (remaining gas: 1039944.441 units remaining) + [ 10 ] + - location: 31 (remaining gas: 1039944.431 units remaining) + [ 7987 + 10 ] + - location: 34 (remaining gas: 1039944.431 units remaining) + [ 79870 ] + - location: 35 (remaining gas: 1039944.421 units remaining) + [ 79870 + 79870 ] + - location: 38 (remaining gas: 1039944.386 units remaining) + [ 0 ] + - location: 40 (remaining gas: 1039944.371 units remaining) + [ True ] + - location: 41 (remaining gas: 1039944.361 units remaining) + [ ] + - location: 41 (remaining gas: 1039944.346 units remaining) + [ ] + - location: 47 (remaining gas: 1039944.336 units remaining) + [ 10 ] + - location: 50 (remaining gas: 1039944.326 units remaining) + [ -7987 + 10 ] + - location: 53 (remaining gas: 1039944.220 units remaining) + [ -79870 ] + - location: 54 (remaining gas: 1039944.210 units remaining) + [ -79870 + -79870 ] + - location: 57 (remaining gas: 1039944.175 units remaining) + [ 0 ] + - location: 59 (remaining gas: 1039944.160 units remaining) + [ True ] + - location: 60 (remaining gas: 1039944.150 units remaining) + [ ] + - location: 60 (remaining gas: 1039944.135 units remaining) + [ ] + - location: 66 (remaining gas: 1039944.125 units remaining) + [ 10 ] + - location: 69 (remaining gas: 1039944.115 units remaining) + [ -7987 + 10 ] + - location: 72 (remaining gas: 1039944.009 units remaining) + [ -79870 ] + - location: 73 (remaining gas: 1039943.999 units remaining) + [ -79870 + -79870 ] + - location: 76 (remaining gas: 1039943.964 units remaining) + [ 0 ] + - location: 78 (remaining gas: 1039943.949 units remaining) + [ True ] + - location: 79 (remaining gas: 1039943.939 units remaining) + [ ] + - location: 79 (remaining gas: 1039943.924 units remaining) + [ ] + - location: 85 (remaining gas: 1039943.914 units remaining) + [ -10 ] + - location: 88 (remaining gas: 1039943.904 units remaining) + [ 7987 + -10 ] + - location: 91 (remaining gas: 1039943.798 units remaining) + [ -79870 ] + - location: 92 (remaining gas: 1039943.788 units remaining) + [ -79870 + -79870 ] + - location: 95 (remaining gas: 1039943.753 units remaining) + [ 0 ] + - location: 97 (remaining gas: 1039943.738 units remaining) + [ True ] + - location: 98 (remaining gas: 1039943.728 units remaining) + [ ] + - location: 98 (remaining gas: 1039943.713 units remaining) + [ ] + - location: 104 (remaining gas: 1039943.703 units remaining) + [ 10 ] + - location: 107 (remaining gas: 1039943.693 units remaining) + [ 7987 + 10 ] + - location: 110 (remaining gas: 1039943.587 units remaining) + [ 79870 ] + - location: 111 (remaining gas: 1039943.577 units remaining) + [ 79870 + 79870 ] + - location: 114 (remaining gas: 1039943.542 units remaining) + [ 0 ] + - location: 116 (remaining gas: 1039943.527 units remaining) + [ True ] + - location: 117 (remaining gas: 1039943.517 units remaining) + [ ] + - location: 117 (remaining gas: 1039943.502 units remaining) + [ ] + - location: 123 (remaining gas: 1039943.492 units remaining) + [ Unit ] + - location: 124 (remaining gas: 1039943.477 units remaining) + [ {} + Unit ] + - location: 126 (remaining gas: 1039943.462 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000.be11332c7f.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000.be11332c7f.out new file mode 100644 index 000000000000..8c209c0b84c3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000.be11332c7f.out @@ -0,0 +1,38 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x00-257-0x0101000000000000000000000000000000000000000000000000000000000000] + +storage + 0x0101000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039987.713 units remaining) + [ (Pair 257 0x0000000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039987.703 units remaining) + [ 257 @parameter ] + - location: 8 (remaining gas: 1039987.693 units remaining) + [ 1 + 257 @parameter ] + - location: 11 (remaining gas: 1039987.683 units remaining) + [ 257 @parameter + 1 ] + - location: 12 (remaining gas: 1039987.543 units remaining) + [ (Some (Pair 257 0)) ] + - location: 14 (remaining gas: 1039987.533 units remaining) + [ (Pair 257 0) @some ] + - location: 14 (remaining gas: 1039987.518 units remaining) + [ (Pair 257 0) @some ] + - location: 20 (remaining gas: 1039987.508 units remaining) + [ 257 ] + - location: 21 (remaining gas: 1039987.498 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 + 257 ] + - location: 24 (remaining gas: 1039987.166 units remaining) + [ 0x0101000000000000000000000000000000000000000000000000000000000000 ] + - location: 25 (remaining gas: 1039987.151 units remaining) + [ {} + 0x0101000000000000000000000000000000000000000000000000000000000000 ] + - location: 27 (remaining gas: 1039987.136 units remaining) + [ (Pair {} 0x0101000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x10000000000000000000.8230fb4fac.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x10000000000000000000.8230fb4fac.out new file mode 100644 index 000000000000..a38e72278e0d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x10000000000000000000.8230fb4fac.out @@ -0,0 +1,38 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[mutez_to_bls12_381_fr.tz-0x02-16-0x1000000000000000000000000000000000000000000000000000000000000000] + +storage + 0x1000000000000000000000000000000000000000000000000000000000000000 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039987.713 units remaining) + [ (Pair 16 0x0200000000000000000000000000000000000000000000000000000000000000) ] + - location: 7 (remaining gas: 1039987.703 units remaining) + [ 16 @parameter ] + - location: 8 (remaining gas: 1039987.693 units remaining) + [ 1 + 16 @parameter ] + - location: 11 (remaining gas: 1039987.683 units remaining) + [ 16 @parameter + 1 ] + - location: 12 (remaining gas: 1039987.543 units remaining) + [ (Some (Pair 16 0)) ] + - location: 14 (remaining gas: 1039987.533 units remaining) + [ (Pair 16 0) @some ] + - location: 14 (remaining gas: 1039987.518 units remaining) + [ (Pair 16 0) @some ] + - location: 20 (remaining gas: 1039987.508 units remaining) + [ 16 ] + - location: 21 (remaining gas: 1039987.498 units remaining) + [ 0x0100000000000000000000000000000000000000000000000000000000000000 + 16 ] + - location: 24 (remaining gas: 1039987.167 units remaining) + [ 0x1000000000000000000000000000000000000000000000000000000000000000 ] + - location: 25 (remaining gas: 1039987.152 units remaining) + [ {} + 0x1000000000000000000000000000000000000000000000000000000000000000 ] + - location: 27 (remaining gas: 1039987.137 units remaining) + [ (Pair {} 0x1000000000000000000000000000000000000000000000000000000000000000) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2].out new file mode 100644 index 000000000000..0867b5c733dd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2].out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left -2)-2] + +storage + 2 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.641 units remaining) + [ (Pair (Left -2) 0) ] + - location: 9 (remaining gas: 1039992.631 units remaining) + [ (Left -2) @parameter ] + - location: 10 (remaining gas: 1039992.621 units remaining) + [ -2 @parameter.left ] + - location: 12 (remaining gas: 1039992.581 units remaining) + [ 2 ] + - location: 10 (remaining gas: 1039992.566 units remaining) + [ 2 ] + - location: 15 (remaining gas: 1039992.551 units remaining) + [ {} + 2 ] + - location: 17 (remaining gas: 1039992.536 units remaining) + [ (Pair {} 2) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0].out new file mode 100644 index 000000000000..4ca986199d07 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0].out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 0)-0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.641 units remaining) + [ (Pair (Left 0) 0) ] + - location: 9 (remaining gas: 1039992.631 units remaining) + [ (Left 0) @parameter ] + - location: 10 (remaining gas: 1039992.621 units remaining) + [ 0 @parameter.left ] + - location: 12 (remaining gas: 1039992.581 units remaining) + [ 0 ] + - location: 10 (remaining gas: 1039992.566 units remaining) + [ 0 ] + - location: 15 (remaining gas: 1039992.551 units remaining) + [ {} + 0 ] + - location: 17 (remaining gas: 1039992.536 units remaining) + [ (Pair {} 0) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2].out new file mode 100644 index 000000000000..f9001507df02 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2].out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Left 2)--2] + +storage + -2 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.641 units remaining) + [ (Pair (Left 2) 0) ] + - location: 9 (remaining gas: 1039992.631 units remaining) + [ (Left 2) @parameter ] + - location: 10 (remaining gas: 1039992.621 units remaining) + [ 2 @parameter.left ] + - location: 12 (remaining gas: 1039992.581 units remaining) + [ -2 ] + - location: 10 (remaining gas: 1039992.566 units remaining) + [ -2 ] + - location: 15 (remaining gas: 1039992.551 units remaining) + [ {} + -2 ] + - location: 17 (remaining gas: 1039992.536 units remaining) + [ (Pair {} -2) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0].out new file mode 100644 index 000000000000..b1951ca8b639 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0].out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 0)-0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.641 units remaining) + [ (Pair (Right 0) 0) ] + - location: 9 (remaining gas: 1039992.631 units remaining) + [ (Right 0) @parameter ] + - location: 10 (remaining gas: 1039992.621 units remaining) + [ 0 @parameter.right ] + - location: 14 (remaining gas: 1039992.581 units remaining) + [ 0 ] + - location: 10 (remaining gas: 1039992.566 units remaining) + [ 0 ] + - location: 15 (remaining gas: 1039992.551 units remaining) + [ {} + 0 ] + - location: 17 (remaining gas: 1039992.536 units remaining) + [ (Pair {} 0) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2].out new file mode 100644 index 000000000000..690fc426fac7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2].out @@ -0,0 +1,25 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[neg.tz-0-(Right 2)--2] + +storage + -2 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039992.641 units remaining) + [ (Pair (Right 2) 0) ] + - location: 9 (remaining gas: 1039992.631 units remaining) + [ (Right 2) @parameter ] + - location: 10 (remaining gas: 1039992.621 units remaining) + [ 2 @parameter.right ] + - location: 14 (remaining gas: 1039992.581 units remaining) + [ -2 ] + - location: 10 (remaining gas: 1039992.566 units remaining) + [ -2 ] + - location: 15 (remaining gas: 1039992.551 units remaining) + [ {} + -2 ] + - location: 17 (remaining gas: 1039992.536 units remaining) + [ (Pair {} -2) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None].out new file mode 100644 index 000000000000..99b08e73f2b8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[none.tz-Some 10-Unit-None] + +storage + None +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.327 units remaining) + [ (Pair Unit (Some 10)) ] + - location: 8 (remaining gas: 1039994.317 units remaining) + [ ] + - location: 9 (remaining gas: 1039994.302 units remaining) + [ None ] + - location: 11 (remaining gas: 1039994.287 units remaining) + [ {} + None ] + - location: 13 (remaining gas: 1039994.272 units remaining) + [ (Pair {} None) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)].out new file mode 100644 index 000000000000..260d89338a55 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)].out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not.tz-None-False-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.957 units remaining) + [ (Pair False None) ] + - location: 8 (remaining gas: 1039993.947 units remaining) + [ False @parameter ] + - location: 9 (remaining gas: 1039993.937 units remaining) + [ True ] + - location: 10 (remaining gas: 1039993.922 units remaining) + [ (Some True) ] + - location: 11 (remaining gas: 1039993.907 units remaining) + [ {} + (Some True) ] + - location: 13 (remaining gas: 1039993.892 units remaining) + [ (Pair {} (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)].out new file mode 100644 index 000000000000..a562518ab7c7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)].out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not.tz-None-True-(Some False)] + +storage + (Some False) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.957 units remaining) + [ (Pair True None) ] + - location: 8 (remaining gas: 1039993.947 units remaining) + [ True @parameter ] + - location: 9 (remaining gas: 1039993.937 units remaining) + [ False ] + - location: 10 (remaining gas: 1039993.922 units remaining) + [ (Some False) ] + - location: 11 (remaining gas: 1039993.907 units remaining) + [ {} + (Some False) ] + - location: 13 (remaining gas: 1039993.892 units remaining) + [ (Pair {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)].out new file mode 100644 index 000000000000..8959830172dc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -8)-(Some 7)] + +storage + (Some 7) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.640 units remaining) + [ (Pair (Left -8) None) ] + - location: 10 (remaining gas: 1039991.630 units remaining) + [ (Left -8) @parameter ] + - location: 11 (remaining gas: 1039991.620 units remaining) + [ -8 @parameter.left ] + - location: 13 (remaining gas: 1039991.570 units remaining) + [ 7 ] + - location: 11 (remaining gas: 1039991.555 units remaining) + [ 7 ] + - location: 16 (remaining gas: 1039991.540 units remaining) + [ (Some 7) ] + - location: 17 (remaining gas: 1039991.525 units remaining) + [ {} + (Some 7) ] + - location: 19 (remaining gas: 1039991.510 units remaining) + [ (Pair {} (Some 7)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)].out new file mode 100644 index 000000000000..ca49cf1ecc31 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left -9)-(Some 8)] + +storage + (Some 8) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.640 units remaining) + [ (Pair (Left -9) None) ] + - location: 10 (remaining gas: 1039991.630 units remaining) + [ (Left -9) @parameter ] + - location: 11 (remaining gas: 1039991.620 units remaining) + [ -9 @parameter.left ] + - location: 13 (remaining gas: 1039991.570 units remaining) + [ 8 ] + - location: 11 (remaining gas: 1039991.555 units remaining) + [ 8 ] + - location: 16 (remaining gas: 1039991.540 units remaining) + [ (Some 8) ] + - location: 17 (remaining gas: 1039991.525 units remaining) + [ {} + (Some 8) ] + - location: 19 (remaining gas: 1039991.510 units remaining) + [ (Pair {} (Some 8)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)].out new file mode 100644 index 000000000000..3e9e63e63200 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 0)-(Some -1)] + +storage + (Some -1) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.640 units remaining) + [ (Pair (Left 0) None) ] + - location: 10 (remaining gas: 1039991.630 units remaining) + [ (Left 0) @parameter ] + - location: 11 (remaining gas: 1039991.620 units remaining) + [ 0 @parameter.left ] + - location: 13 (remaining gas: 1039991.570 units remaining) + [ -1 ] + - location: 11 (remaining gas: 1039991.555 units remaining) + [ -1 ] + - location: 16 (remaining gas: 1039991.540 units remaining) + [ (Some -1) ] + - location: 17 (remaining gas: 1039991.525 units remaining) + [ {} + (Some -1) ] + - location: 19 (remaining gas: 1039991.510 units remaining) + [ (Pair {} (Some -1)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)].out new file mode 100644 index 000000000000..0ce373cf61af --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 7)-(Some -8)] + +storage + (Some -8) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.640 units remaining) + [ (Pair (Left 7) None) ] + - location: 10 (remaining gas: 1039991.630 units remaining) + [ (Left 7) @parameter ] + - location: 11 (remaining gas: 1039991.620 units remaining) + [ 7 @parameter.left ] + - location: 13 (remaining gas: 1039991.570 units remaining) + [ -8 ] + - location: 11 (remaining gas: 1039991.555 units remaining) + [ -8 ] + - location: 16 (remaining gas: 1039991.540 units remaining) + [ (Some -8) ] + - location: 17 (remaining gas: 1039991.525 units remaining) + [ {} + (Some -8) ] + - location: 19 (remaining gas: 1039991.510 units remaining) + [ (Pair {} (Some -8)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)].out new file mode 100644 index 000000000000..341cb4eb8780 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Left 8)-(Some -9)] + +storage + (Some -9) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.640 units remaining) + [ (Pair (Left 8) None) ] + - location: 10 (remaining gas: 1039991.630 units remaining) + [ (Left 8) @parameter ] + - location: 11 (remaining gas: 1039991.620 units remaining) + [ 8 @parameter.left ] + - location: 13 (remaining gas: 1039991.570 units remaining) + [ -9 ] + - location: 11 (remaining gas: 1039991.555 units remaining) + [ -9 ] + - location: 16 (remaining gas: 1039991.540 units remaining) + [ (Some -9) ] + - location: 17 (remaining gas: 1039991.525 units remaining) + [ {} + (Some -9) ] + - location: 19 (remaining gas: 1039991.510 units remaining) + [ (Pair {} (Some -9)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)].out new file mode 100644 index 000000000000..f8004a52381e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 0)-(Some -1)] + +storage + (Some -1) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.640 units remaining) + [ (Pair (Right 0) None) ] + - location: 10 (remaining gas: 1039991.630 units remaining) + [ (Right 0) @parameter ] + - location: 11 (remaining gas: 1039991.620 units remaining) + [ 0 @parameter.right ] + - location: 15 (remaining gas: 1039991.570 units remaining) + [ -1 ] + - location: 11 (remaining gas: 1039991.555 units remaining) + [ -1 ] + - location: 16 (remaining gas: 1039991.540 units remaining) + [ (Some -1) ] + - location: 17 (remaining gas: 1039991.525 units remaining) + [ {} + (Some -1) ] + - location: 19 (remaining gas: 1039991.510 units remaining) + [ (Pair {} (Some -1)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)].out new file mode 100644 index 000000000000..e2ab81878c2d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 7)-(Some -8)] + +storage + (Some -8) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.640 units remaining) + [ (Pair (Right 7) None) ] + - location: 10 (remaining gas: 1039991.630 units remaining) + [ (Right 7) @parameter ] + - location: 11 (remaining gas: 1039991.620 units remaining) + [ 7 @parameter.right ] + - location: 15 (remaining gas: 1039991.570 units remaining) + [ -8 ] + - location: 11 (remaining gas: 1039991.555 units remaining) + [ -8 ] + - location: 16 (remaining gas: 1039991.540 units remaining) + [ (Some -8) ] + - location: 17 (remaining gas: 1039991.525 units remaining) + [ {} + (Some -8) ] + - location: 19 (remaining gas: 1039991.510 units remaining) + [ (Pair {} (Some -8)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)].out new file mode 100644 index 000000000000..aed6afe4314b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[not_binary.tz-None-(Right 8)-(Some -9)] + +storage + (Some -9) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039991.640 units remaining) + [ (Pair (Right 8) None) ] + - location: 10 (remaining gas: 1039991.630 units remaining) + [ (Right 8) @parameter ] + - location: 11 (remaining gas: 1039991.620 units remaining) + [ 8 @parameter.right ] + - location: 15 (remaining gas: 1039991.570 units remaining) + [ -9 ] + - location: 11 (remaining gas: 1039991.555 units remaining) + [ -9 ] + - location: 16 (remaining gas: 1039991.540 units remaining) + [ (Some -9) ] + - location: 17 (remaining gas: 1039991.525 units remaining) + [ {} + (Some -9) ] + - location: 19 (remaining gas: 1039991.510 units remaining) + [ (Pair {} (Some -9)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)].out new file mode 100644 index 000000000000..5b96023794ae --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)].out @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False False)-(Some False)] + +storage + (Some False) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.715 units remaining) + [ (Pair (Pair False False) None) ] + - location: 10 (remaining gas: 1039990.705 units remaining) + [ (Pair False False) @parameter ] + - location: 11 (remaining gas: 1039990.695 units remaining) + [ (Pair False False) @parameter + (Pair False False) @parameter ] + - location: 12 (remaining gas: 1039990.685 units remaining) + [ False + (Pair False False) @parameter ] + - location: 13 (remaining gas: 1039990.675 units remaining) + [ (Pair False False) @parameter + False ] + - location: 14 (remaining gas: 1039990.665 units remaining) + [ False + False ] + - location: 15 (remaining gas: 1039990.650 units remaining) + [ False ] + - location: 16 (remaining gas: 1039990.635 units remaining) + [ (Some False) ] + - location: 17 (remaining gas: 1039990.620 units remaining) + [ {} + (Some False) ] + - location: 19 (remaining gas: 1039990.605 units remaining) + [ (Pair {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)].out new file mode 100644 index 000000000000..0145dbad770b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)].out @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair False True)-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.715 units remaining) + [ (Pair (Pair False True) None) ] + - location: 10 (remaining gas: 1039990.705 units remaining) + [ (Pair False True) @parameter ] + - location: 11 (remaining gas: 1039990.695 units remaining) + [ (Pair False True) @parameter + (Pair False True) @parameter ] + - location: 12 (remaining gas: 1039990.685 units remaining) + [ False + (Pair False True) @parameter ] + - location: 13 (remaining gas: 1039990.675 units remaining) + [ (Pair False True) @parameter + False ] + - location: 14 (remaining gas: 1039990.665 units remaining) + [ True + False ] + - location: 15 (remaining gas: 1039990.650 units remaining) + [ True ] + - location: 16 (remaining gas: 1039990.635 units remaining) + [ (Some True) ] + - location: 17 (remaining gas: 1039990.620 units remaining) + [ {} + (Some True) ] + - location: 19 (remaining gas: 1039990.605 units remaining) + [ (Pair {} (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)].out new file mode 100644 index 000000000000..5ca2b285f0ba --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)].out @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True False)-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.715 units remaining) + [ (Pair (Pair True False) None) ] + - location: 10 (remaining gas: 1039990.705 units remaining) + [ (Pair True False) @parameter ] + - location: 11 (remaining gas: 1039990.695 units remaining) + [ (Pair True False) @parameter + (Pair True False) @parameter ] + - location: 12 (remaining gas: 1039990.685 units remaining) + [ True + (Pair True False) @parameter ] + - location: 13 (remaining gas: 1039990.675 units remaining) + [ (Pair True False) @parameter + True ] + - location: 14 (remaining gas: 1039990.665 units remaining) + [ False + True ] + - location: 15 (remaining gas: 1039990.650 units remaining) + [ True ] + - location: 16 (remaining gas: 1039990.635 units remaining) + [ (Some True) ] + - location: 17 (remaining gas: 1039990.620 units remaining) + [ {} + (Some True) ] + - location: 19 (remaining gas: 1039990.605 units remaining) + [ (Pair {} (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)].out new file mode 100644 index 000000000000..50bd4b5a9c56 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)].out @@ -0,0 +1,35 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or.tz-None-(Pair True True)-(Some True)] + +storage + (Some True) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039990.715 units remaining) + [ (Pair (Pair True True) None) ] + - location: 10 (remaining gas: 1039990.705 units remaining) + [ (Pair True True) @parameter ] + - location: 11 (remaining gas: 1039990.695 units remaining) + [ (Pair True True) @parameter + (Pair True True) @parameter ] + - location: 12 (remaining gas: 1039990.685 units remaining) + [ True + (Pair True True) @parameter ] + - location: 13 (remaining gas: 1039990.675 units remaining) + [ (Pair True True) @parameter + True ] + - location: 14 (remaining gas: 1039990.665 units remaining) + [ True + True ] + - location: 15 (remaining gas: 1039990.650 units remaining) + [ True ] + - location: 16 (remaining gas: 1039990.635 units remaining) + [ (Some True) ] + - location: 17 (remaining gas: 1039990.620 units remaining) + [ {} + (Some True) ] + - location: 19 (remaining gas: 1039990.605 units remaining) + [ (Pair {} (Some True)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)].out new file mode 100644 index 000000000000..fe0f77583800 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 0 8)-(Some 8)] + +storage + (Some 8) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.824 units remaining) + [ (Pair (Pair 0 8) None) ] + - location: 10 (remaining gas: 1039992.814 units remaining) + [ (Pair 0 8) @parameter ] + - location: 11 (remaining gas: 1039992.804 units remaining) + [ 0 + 8 ] + - location: 12 (remaining gas: 1039992.749 units remaining) + [ 8 ] + - location: 13 (remaining gas: 1039992.734 units remaining) + [ (Some 8) ] + - location: 14 (remaining gas: 1039992.719 units remaining) + [ {} + (Some 8) ] + - location: 16 (remaining gas: 1039992.704 units remaining) + [ (Pair {} (Some 8)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)].out new file mode 100644 index 000000000000..58de04bbb320 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 14 1)-(Some 15)] + +storage + (Some 15) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.824 units remaining) + [ (Pair (Pair 14 1) None) ] + - location: 10 (remaining gas: 1039992.814 units remaining) + [ (Pair 14 1) @parameter ] + - location: 11 (remaining gas: 1039992.804 units remaining) + [ 14 + 1 ] + - location: 12 (remaining gas: 1039992.749 units remaining) + [ 15 ] + - location: 13 (remaining gas: 1039992.734 units remaining) + [ (Some 15) ] + - location: 14 (remaining gas: 1039992.719 units remaining) + [ {} + (Some 15) ] + - location: 16 (remaining gas: 1039992.704 units remaining) + [ (Pair {} (Some 15)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)].out new file mode 100644 index 000000000000..5916c50e9f91 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 15 4)-(Some 15)] + +storage + (Some 15) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.824 units remaining) + [ (Pair (Pair 15 4) None) ] + - location: 10 (remaining gas: 1039992.814 units remaining) + [ (Pair 15 4) @parameter ] + - location: 11 (remaining gas: 1039992.804 units remaining) + [ 15 + 4 ] + - location: 12 (remaining gas: 1039992.749 units remaining) + [ 15 ] + - location: 13 (remaining gas: 1039992.734 units remaining) + [ (Some 15) ] + - location: 14 (remaining gas: 1039992.719 units remaining) + [ {} + (Some 15) ] + - location: 16 (remaining gas: 1039992.704 units remaining) + [ (Pair {} (Some 15)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)].out new file mode 100644 index 000000000000..97adce911211 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 4 8)-(Some 12)] + +storage + (Some 12) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.824 units remaining) + [ (Pair (Pair 4 8) None) ] + - location: 10 (remaining gas: 1039992.814 units remaining) + [ (Pair 4 8) @parameter ] + - location: 11 (remaining gas: 1039992.804 units remaining) + [ 4 + 8 ] + - location: 12 (remaining gas: 1039992.749 units remaining) + [ 12 ] + - location: 13 (remaining gas: 1039992.734 units remaining) + [ (Some 12) ] + - location: 14 (remaining gas: 1039992.719 units remaining) + [ {} + (Some 12) ] + - location: 16 (remaining gas: 1039992.704 units remaining) + [ (Pair {} (Some 12)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)].out new file mode 100644 index 000000000000..f3fcd58b547a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 7 7)-(Some 7)] + +storage + (Some 7) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.824 units remaining) + [ (Pair (Pair 7 7) None) ] + - location: 10 (remaining gas: 1039992.814 units remaining) + [ (Pair 7 7) @parameter ] + - location: 11 (remaining gas: 1039992.804 units remaining) + [ 7 + 7 ] + - location: 12 (remaining gas: 1039992.749 units remaining) + [ 7 ] + - location: 13 (remaining gas: 1039992.734 units remaining) + [ (Some 7) ] + - location: 14 (remaining gas: 1039992.719 units remaining) + [ {} + (Some 7) ] + - location: 16 (remaining gas: 1039992.704 units remaining) + [ (Pair {} (Some 7)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)].out new file mode 100644 index 000000000000..6e3c16582f08 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)].out @@ -0,0 +1,26 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[or_binary.tz-None-(Pair 8 0)-(Some 8)] + +storage + (Some 8) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039992.824 units remaining) + [ (Pair (Pair 8 0) None) ] + - location: 10 (remaining gas: 1039992.814 units remaining) + [ (Pair 8 0) @parameter ] + - location: 11 (remaining gas: 1039992.804 units remaining) + [ 8 + 0 ] + - location: 12 (remaining gas: 1039992.749 units remaining) + [ 8 ] + - location: 13 (remaining gas: 1039992.734 units remaining) + [ (Some 8) ] + - location: 14 (remaining gas: 1039992.719 units remaining) + [ {} + (Some 8) ] + - location: 16 (remaining gas: 1039992.704 units remaining) + [ (Pair {} (Some 8)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".368bdfd73a.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".368bdfd73a.out" new file mode 100644 index 000000000000..d24dc5144bda --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".368bdfd73a.out" @@ -0,0 +1,845 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair "foobar" (Pair 0x00AABBCC (Pair 1000 (Pair False (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"))))))))-Unit1] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039185.305 units remaining) + [ (Pair (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + Unit) ] + - location: 16 (remaining gas: 1039185.295 units remaining) + [ (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] + - location: 17 (remaining gas: 1039185.285 units remaining) + [ (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter + (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] + - location: 18 (remaining gas: 1039185.275 units remaining) + [ -1 + (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] + - location: 19 (remaining gas: 1039185.260 units remaining) + [ (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] + - location: 21 (remaining gas: 1039185.250 units remaining) + [ -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 19 (remaining gas: 1039185.220 units remaining) + [ -1 + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 22 (remaining gas: 1039184.993 units remaining) + [ 0x050041 @packed + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 23 (remaining gas: 1039184.573 units remaining) + [ (Some -1) @packed.unpacked + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 26 (remaining gas: 1039184.563 units remaining) + [ -1 @packed.unpacked.some + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 26 (remaining gas: 1039184.548 units remaining) + [ -1 @packed.unpacked.some + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 34 (remaining gas: 1039184.513 units remaining) + [ 0 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 35 (remaining gas: 1039184.498 units remaining) + [ True + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 36 (remaining gas: 1039184.488 units remaining) + [ (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 36 (remaining gas: 1039184.473 units remaining) + [ (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 42 (remaining gas: 1039184.463 units remaining) + [ (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 43 (remaining gas: 1039184.453 units remaining) + [ 1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 44 (remaining gas: 1039184.438 units remaining) + [ (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 46 (remaining gas: 1039184.428 units remaining) + [ 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 44 (remaining gas: 1039184.398 units remaining) + [ 1 + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 47 (remaining gas: 1039184.171 units remaining) + [ 0x050001 @packed + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 48 (remaining gas: 1039183.751 units remaining) + [ (Some 1) @packed.unpacked + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 51 (remaining gas: 1039183.741 units remaining) + [ 1 @packed.unpacked.some + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 51 (remaining gas: 1039183.726 units remaining) + [ 1 @packed.unpacked.some + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 59 (remaining gas: 1039183.691 units remaining) + [ 0 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 60 (remaining gas: 1039183.676 units remaining) + [ True + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 61 (remaining gas: 1039183.666 units remaining) + [ (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 61 (remaining gas: 1039183.651 units remaining) + [ (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 67 (remaining gas: 1039183.641 units remaining) + [ (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 68 (remaining gas: 1039183.631 units remaining) + [ "foobar" + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 69 (remaining gas: 1039183.616 units remaining) + [ (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 71 (remaining gas: 1039183.606 units remaining) + [ "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 69 (remaining gas: 1039183.576 units remaining) + [ "foobar" + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 72 (remaining gas: 1039183.052 units remaining) + [ 0x050100000006666f6f626172 @packed + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 73 (remaining gas: 1039182.377 units remaining) + [ (Some "foobar") @packed.unpacked + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 76 (remaining gas: 1039182.367 units remaining) + [ "foobar" @packed.unpacked.some + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 76 (remaining gas: 1039182.352 units remaining) + [ "foobar" @packed.unpacked.some + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 84 (remaining gas: 1039182.317 units remaining) + [ 0 + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 85 (remaining gas: 1039182.302 units remaining) + [ True + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 86 (remaining gas: 1039182.292 units remaining) + [ (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 86 (remaining gas: 1039182.277 units remaining) + [ (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 92 (remaining gas: 1039182.267 units remaining) + [ (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 93 (remaining gas: 1039182.257 units remaining) + [ 0x00aabbcc + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 94 (remaining gas: 1039182.242 units remaining) + [ (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 96 (remaining gas: 1039182.232 units remaining) + [ 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 94 (remaining gas: 1039182.202 units remaining) + [ 0x00aabbcc + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 97 (remaining gas: 1039181.744 units remaining) + [ 0x050a0000000400aabbcc @packed + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 98 (remaining gas: 1039181.183 units remaining) + [ (Some 0x00aabbcc) @packed.unpacked + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 101 (remaining gas: 1039181.173 units remaining) + [ 0x00aabbcc @packed.unpacked.some + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 101 (remaining gas: 1039181.158 units remaining) + [ 0x00aabbcc @packed.unpacked.some + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 109 (remaining gas: 1039181.123 units remaining) + [ 0 + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 110 (remaining gas: 1039181.108 units remaining) + [ True + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 111 (remaining gas: 1039181.098 units remaining) + [ (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 111 (remaining gas: 1039181.083 units remaining) + [ (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 117 (remaining gas: 1039181.073 units remaining) + [ (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 118 (remaining gas: 1039181.063 units remaining) + [ 1000 + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 119 (remaining gas: 1039181.048 units remaining) + [ (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 121 (remaining gas: 1039181.038 units remaining) + [ 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 119 (remaining gas: 1039181.008 units remaining) + [ 1000 + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 122 (remaining gas: 1039180.748 units remaining) + [ 0x0500a80f @packed + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 123 (remaining gas: 1039180.308 units remaining) + [ (Some 1000) @packed.unpacked + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 126 (remaining gas: 1039180.298 units remaining) + [ 1000 @packed.unpacked.some + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 126 (remaining gas: 1039180.283 units remaining) + [ 1000 @packed.unpacked.some + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 134 (remaining gas: 1039180.248 units remaining) + [ 0 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 135 (remaining gas: 1039180.233 units remaining) + [ True + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 136 (remaining gas: 1039180.223 units remaining) + [ (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 136 (remaining gas: 1039180.208 units remaining) + [ (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 142 (remaining gas: 1039180.198 units remaining) + [ (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 143 (remaining gas: 1039180.188 units remaining) + [ False + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 144 (remaining gas: 1039180.173 units remaining) + [ (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 146 (remaining gas: 1039180.163 units remaining) + [ False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 144 (remaining gas: 1039180.133 units remaining) + [ False + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 147 (remaining gas: 1039179.906 units remaining) + [ 0x050303 @packed + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 148 (remaining gas: 1039179.486 units remaining) + [ (Some False) @packed.unpacked + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 151 (remaining gas: 1039179.476 units remaining) + [ False @packed.unpacked.some + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 151 (remaining gas: 1039179.461 units remaining) + [ False @packed.unpacked.some + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 159 (remaining gas: 1039179.426 units remaining) + [ 0 + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 160 (remaining gas: 1039179.411 units remaining) + [ True + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 161 (remaining gas: 1039179.401 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 161 (remaining gas: 1039179.386 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 167 (remaining gas: 1039179.376 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 168 (remaining gas: 1039179.366 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 169 (remaining gas: 1039179.351 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 171 (remaining gas: 1039179.341 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 169 (remaining gas: 1039179.311 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 172 (remaining gas: 1039178.221 units remaining) + [ 0x050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 173 (remaining gas: 1039177.268 units remaining) + [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 176 (remaining gas: 1039177.258 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 176 (remaining gas: 1039177.243 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 184 (remaining gas: 1039177.207 units remaining) + [ 0 + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 185 (remaining gas: 1039177.192 units remaining) + [ True + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 186 (remaining gas: 1039177.182 units remaining) + [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 186 (remaining gas: 1039177.167 units remaining) + [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 192 (remaining gas: 1039177.157 units remaining) + [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 193 (remaining gas: 1039177.147 units remaining) + [ "2019-09-09T08:35:33Z" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 194 (remaining gas: 1039177.132 units remaining) + [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 196 (remaining gas: 1039177.122 units remaining) + [ "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 194 (remaining gas: 1039177.092 units remaining) + [ "2019-09-09T08:35:33Z" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 197 (remaining gas: 1039176.733 units remaining) + [ 0x050095bbb0d70b @packed + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 198 (remaining gas: 1039176.233 units remaining) + [ (Some "2019-09-09T08:35:33Z") @packed.unpacked + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 201 (remaining gas: 1039176.223 units remaining) + [ "2019-09-09T08:35:33Z" @packed.unpacked.some + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 201 (remaining gas: 1039176.208 units remaining) + [ "2019-09-09T08:35:33Z" @packed.unpacked.some + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 209 (remaining gas: 1039176.173 units remaining) + [ 0 + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 210 (remaining gas: 1039176.158 units remaining) + [ True + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 211 (remaining gas: 1039176.148 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 211 (remaining gas: 1039176.133 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 217 (remaining gas: 1039176.123 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 218 (remaining gas: 1039165.170 units remaining) + [ 0x050a000000160000bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 219 (remaining gas: 1038514.247 units remaining) + [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 222 (remaining gas: 1038514.237 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 222 (remaining gas: 1038514.222 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 230 (remaining gas: 1038514.186 units remaining) + [ 0 ] + - location: 231 (remaining gas: 1038514.171 units remaining) + [ True ] + - location: 232 (remaining gas: 1038514.161 units remaining) + [ ] + - location: 232 (remaining gas: 1038514.146 units remaining) + [ ] + - location: 238 (remaining gas: 1038514.136 units remaining) + [ 0 ] + - location: 241 (remaining gas: 1038513.909 units remaining) + [ 0x050000 @packed ] + - location: 242 (remaining gas: 1038513.489 units remaining) + [ (Some 0) @packed.unpacked ] + - location: 245 (remaining gas: 1038513.479 units remaining) + [ 0 @packed.unpacked.some ] + - location: 245 (remaining gas: 1038513.464 units remaining) + [ 0 @packed.unpacked.some ] + - location: 251 (remaining gas: 1038513.454 units remaining) + [ ] + - location: 252 (remaining gas: 1038513.444 units remaining) + [ -1 ] + - location: 255 (remaining gas: 1038513.217 units remaining) + [ 0x050041 @packed ] + - location: 256 (remaining gas: 1038416.897 units remaining) + [ None @packed.unpacked ] + - location: 259 (remaining gas: 1038416.887 units remaining) + [ ] + - location: 259 (remaining gas: 1038416.872 units remaining) + [ ] + - location: 265 (remaining gas: 1038416.862 units remaining) + [ 0x ] + - location: 268 (remaining gas: 1038416.602 units remaining) + [ None @unpacked ] + - location: 271 (remaining gas: 1038416.592 units remaining) + [ ] + - location: 271 (remaining gas: 1038416.577 units remaining) + [ ] + - location: 277 (remaining gas: 1038416.567 units remaining) + [ 0x04 ] + - location: 280 (remaining gas: 1038416.287 units remaining) + [ None @unpacked ] + - location: 283 (remaining gas: 1038416.277 units remaining) + [ ] + - location: 283 (remaining gas: 1038416.262 units remaining) + [ ] + - location: 289 (remaining gas: 1038416.252 units remaining) + [ 0x05 ] + - location: 292 (remaining gas: 1038415.972 units remaining) + [ None @unpacked ] + - location: 295 (remaining gas: 1038415.962 units remaining) + [ ] + - location: 295 (remaining gas: 1038415.947 units remaining) + [ ] + - location: 301 (remaining gas: 1038415.937 units remaining) + [ Unit ] + - location: 302 (remaining gas: 1038415.922 units remaining) + [ {} + Unit ] + - location: 304 (remaining gas: 1038415.907 units remaining) + [ (Pair {} Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".735d9ae802.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".735d9ae802.out" new file mode 100644 index 000000000000..89f333f82bd8 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair \"foobar\".735d9ae802.out" @@ -0,0 +1,845 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[packunpack_rev.tz-Unit-(Pair -1 (Pair 1 (Pair "foobar" (Pair 0x00AABBCC (Pair 1000 (Pair False (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"))))))))-Unit0] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039185.305 units remaining) + [ (Pair (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + Unit) ] + - location: 16 (remaining gas: 1039185.295 units remaining) + [ (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] + - location: 17 (remaining gas: 1039185.285 units remaining) + [ (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter + (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] + - location: 18 (remaining gas: 1039185.275 units remaining) + [ -1 + (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] + - location: 19 (remaining gas: 1039185.260 units remaining) + [ (Pair -1 + 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @parameter ] + - location: 21 (remaining gas: 1039185.250 units remaining) + [ -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 19 (remaining gas: 1039185.220 units remaining) + [ -1 + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 22 (remaining gas: 1039184.993 units remaining) + [ 0x050041 @packed + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 23 (remaining gas: 1039184.573 units remaining) + [ (Some -1) @packed.unpacked + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 26 (remaining gas: 1039184.563 units remaining) + [ -1 @packed.unpacked.some + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 26 (remaining gas: 1039184.548 units remaining) + [ -1 @packed.unpacked.some + -1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 34 (remaining gas: 1039184.513 units remaining) + [ 0 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 35 (remaining gas: 1039184.498 units remaining) + [ True + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 36 (remaining gas: 1039184.488 units remaining) + [ (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 36 (remaining gas: 1039184.473 units remaining) + [ (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 42 (remaining gas: 1039184.463 units remaining) + [ (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 43 (remaining gas: 1039184.453 units remaining) + [ 1 + (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 44 (remaining gas: 1039184.438 units remaining) + [ (Pair 1 + "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 46 (remaining gas: 1039184.428 units remaining) + [ 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 44 (remaining gas: 1039184.398 units remaining) + [ 1 + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 47 (remaining gas: 1039184.171 units remaining) + [ 0x050001 @packed + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 48 (remaining gas: 1039183.751 units remaining) + [ (Some 1) @packed.unpacked + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 51 (remaining gas: 1039183.741 units remaining) + [ 1 @packed.unpacked.some + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 51 (remaining gas: 1039183.726 units remaining) + [ 1 @packed.unpacked.some + 1 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 59 (remaining gas: 1039183.691 units remaining) + [ 0 + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 60 (remaining gas: 1039183.676 units remaining) + [ True + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 61 (remaining gas: 1039183.666 units remaining) + [ (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 61 (remaining gas: 1039183.651 units remaining) + [ (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 67 (remaining gas: 1039183.641 units remaining) + [ (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 68 (remaining gas: 1039183.631 units remaining) + [ "foobar" + (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 69 (remaining gas: 1039183.616 units remaining) + [ (Pair "foobar" + 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 71 (remaining gas: 1039183.606 units remaining) + [ "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 69 (remaining gas: 1039183.576 units remaining) + [ "foobar" + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 72 (remaining gas: 1039183.052 units remaining) + [ 0x050100000006666f6f626172 @packed + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 73 (remaining gas: 1039182.377 units remaining) + [ (Some "foobar") @packed.unpacked + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 76 (remaining gas: 1039182.367 units remaining) + [ "foobar" @packed.unpacked.some + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 76 (remaining gas: 1039182.352 units remaining) + [ "foobar" @packed.unpacked.some + "foobar" + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 84 (remaining gas: 1039182.317 units remaining) + [ 0 + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 85 (remaining gas: 1039182.302 units remaining) + [ True + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 86 (remaining gas: 1039182.292 units remaining) + [ (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 86 (remaining gas: 1039182.277 units remaining) + [ (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 92 (remaining gas: 1039182.267 units remaining) + [ (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 93 (remaining gas: 1039182.257 units remaining) + [ 0x00aabbcc + (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 94 (remaining gas: 1039182.242 units remaining) + [ (Pair 0x00aabbcc + 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 96 (remaining gas: 1039182.232 units remaining) + [ 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 94 (remaining gas: 1039182.202 units remaining) + [ 0x00aabbcc + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 97 (remaining gas: 1039181.744 units remaining) + [ 0x050a0000000400aabbcc @packed + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 98 (remaining gas: 1039181.183 units remaining) + [ (Some 0x00aabbcc) @packed.unpacked + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 101 (remaining gas: 1039181.173 units remaining) + [ 0x00aabbcc @packed.unpacked.some + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 101 (remaining gas: 1039181.158 units remaining) + [ 0x00aabbcc @packed.unpacked.some + 0x00aabbcc + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 109 (remaining gas: 1039181.123 units remaining) + [ 0 + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 110 (remaining gas: 1039181.108 units remaining) + [ True + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 111 (remaining gas: 1039181.098 units remaining) + [ (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 111 (remaining gas: 1039181.083 units remaining) + [ (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 117 (remaining gas: 1039181.073 units remaining) + [ (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 118 (remaining gas: 1039181.063 units remaining) + [ 1000 + (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 119 (remaining gas: 1039181.048 units remaining) + [ (Pair 1000 + False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 121 (remaining gas: 1039181.038 units remaining) + [ 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 119 (remaining gas: 1039181.008 units remaining) + [ 1000 + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 122 (remaining gas: 1039180.748 units remaining) + [ 0x0500a80f @packed + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 123 (remaining gas: 1039180.308 units remaining) + [ (Some 1000) @packed.unpacked + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 126 (remaining gas: 1039180.298 units remaining) + [ 1000 @packed.unpacked.some + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 126 (remaining gas: 1039180.283 units remaining) + [ 1000 @packed.unpacked.some + 1000 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 134 (remaining gas: 1039180.248 units remaining) + [ 0 + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 135 (remaining gas: 1039180.233 units remaining) + [ True + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 136 (remaining gas: 1039180.223 units remaining) + [ (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 136 (remaining gas: 1039180.208 units remaining) + [ (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 142 (remaining gas: 1039180.198 units remaining) + [ (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 143 (remaining gas: 1039180.188 units remaining) + [ False + (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 144 (remaining gas: 1039180.173 units remaining) + [ (Pair False + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 146 (remaining gas: 1039180.163 units remaining) + [ False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 144 (remaining gas: 1039180.133 units remaining) + [ False + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 147 (remaining gas: 1039179.906 units remaining) + [ 0x050303 @packed + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 148 (remaining gas: 1039179.486 units remaining) + [ (Some False) @packed.unpacked + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 151 (remaining gas: 1039179.476 units remaining) + [ False @packed.unpacked.some + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 151 (remaining gas: 1039179.461 units remaining) + [ False @packed.unpacked.some + False + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 159 (remaining gas: 1039179.426 units remaining) + [ 0 + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 160 (remaining gas: 1039179.411 units remaining) + [ True + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 161 (remaining gas: 1039179.401 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 161 (remaining gas: 1039179.386 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 167 (remaining gas: 1039179.376 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 168 (remaining gas: 1039179.366 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 169 (remaining gas: 1039179.351 units remaining) + [ (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 171 (remaining gas: 1039179.341 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 169 (remaining gas: 1039179.311 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 172 (remaining gas: 1039178.221 units remaining) + [ 0x050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 173 (remaining gas: 1039177.268 units remaining) + [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 176 (remaining gas: 1039177.258 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 176 (remaining gas: 1039177.243 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 184 (remaining gas: 1039177.207 units remaining) + [ 0 + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 185 (remaining gas: 1039177.192 units remaining) + [ True + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 186 (remaining gas: 1039177.182 units remaining) + [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 186 (remaining gas: 1039177.167 units remaining) + [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 192 (remaining gas: 1039177.157 units remaining) + [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 193 (remaining gas: 1039177.147 units remaining) + [ "2019-09-09T08:35:33Z" + (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 194 (remaining gas: 1039177.132 units remaining) + [ (Pair "2019-09-09T08:35:33Z" "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") ] + - location: 196 (remaining gas: 1039177.122 units remaining) + [ "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 194 (remaining gas: 1039177.092 units remaining) + [ "2019-09-09T08:35:33Z" + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 197 (remaining gas: 1039176.733 units remaining) + [ 0x050095bbb0d70b @packed + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 198 (remaining gas: 1039176.233 units remaining) + [ (Some "2019-09-09T08:35:33Z") @packed.unpacked + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 201 (remaining gas: 1039176.223 units remaining) + [ "2019-09-09T08:35:33Z" @packed.unpacked.some + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 201 (remaining gas: 1039176.208 units remaining) + [ "2019-09-09T08:35:33Z" @packed.unpacked.some + "2019-09-09T08:35:33Z" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 209 (remaining gas: 1039176.173 units remaining) + [ 0 + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 210 (remaining gas: 1039176.158 units remaining) + [ True + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 211 (remaining gas: 1039176.148 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 211 (remaining gas: 1039176.133 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 217 (remaining gas: 1039176.123 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 218 (remaining gas: 1039165.170 units remaining) + [ 0x050a000000160000bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 219 (remaining gas: 1038514.247 units remaining) + [ (Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 222 (remaining gas: 1038514.237 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 222 (remaining gas: 1038514.222 units remaining) + [ "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" @packed.unpacked.some + "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ] + - location: 230 (remaining gas: 1038514.186 units remaining) + [ 0 ] + - location: 231 (remaining gas: 1038514.171 units remaining) + [ True ] + - location: 232 (remaining gas: 1038514.161 units remaining) + [ ] + - location: 232 (remaining gas: 1038514.146 units remaining) + [ ] + - location: 238 (remaining gas: 1038514.136 units remaining) + [ 0 ] + - location: 241 (remaining gas: 1038513.909 units remaining) + [ 0x050000 @packed ] + - location: 242 (remaining gas: 1038513.489 units remaining) + [ (Some 0) @packed.unpacked ] + - location: 245 (remaining gas: 1038513.479 units remaining) + [ 0 @packed.unpacked.some ] + - location: 245 (remaining gas: 1038513.464 units remaining) + [ 0 @packed.unpacked.some ] + - location: 251 (remaining gas: 1038513.454 units remaining) + [ ] + - location: 252 (remaining gas: 1038513.444 units remaining) + [ -1 ] + - location: 255 (remaining gas: 1038513.217 units remaining) + [ 0x050041 @packed ] + - location: 256 (remaining gas: 1038416.897 units remaining) + [ None @packed.unpacked ] + - location: 259 (remaining gas: 1038416.887 units remaining) + [ ] + - location: 259 (remaining gas: 1038416.872 units remaining) + [ ] + - location: 265 (remaining gas: 1038416.862 units remaining) + [ 0x ] + - location: 268 (remaining gas: 1038416.602 units remaining) + [ None @unpacked ] + - location: 271 (remaining gas: 1038416.592 units remaining) + [ ] + - location: 271 (remaining gas: 1038416.577 units remaining) + [ ] + - location: 277 (remaining gas: 1038416.567 units remaining) + [ 0x04 ] + - location: 280 (remaining gas: 1038416.287 units remaining) + [ None @unpacked ] + - location: 283 (remaining gas: 1038416.277 units remaining) + [ ] + - location: 283 (remaining gas: 1038416.262 units remaining) + [ ] + - location: 289 (remaining gas: 1038416.252 units remaining) + [ 0x05 ] + - location: 292 (remaining gas: 1038415.972 units remaining) + [ None @unpacked ] + - location: 295 (remaining gas: 1038415.962 units remaining) + [ ] + - location: 295 (remaining gas: 1038415.947 units remaining) + [ ] + - location: 301 (remaining gas: 1038415.937 units remaining) + [ Unit ] + - location: 302 (remaining gas: 1038415.922 units remaining) + [ {} + Unit ] + - location: 304 (remaining gas: 1038415.907 units remaining) + [ (Pair {} Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" new file mode 100644 index 000000000000..359da4be18b8 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.1ac5de50fb.out" @@ -0,0 +1,1194 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" (Pair Unit (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") (Pair { Unit } (Pair { True } (Pair (Pair 19 10) (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK } )))))))))-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 28 (remaining gas: 1039468.020 units remaining) + [ (Pair (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) + Unit) ] + - location: 28 (remaining gas: 1039468.010 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) @parameter ] + - location: 29 (remaining gas: 1039468 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) @parameter + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) @parameter ] + - location: 30 (remaining gas: 1039467.990 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) @parameter ] + - location: 31 (remaining gas: 1039467.975 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) @parameter ] + - location: 33 (remaining gas: 1039467.965 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 31 (remaining gas: 1039467.935 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 34 (remaining gas: 1039466.063 units remaining) + [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed + "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 35 (remaining gas: 1039466.048 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 37 (remaining gas: 1039464.176 units remaining) + [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 38 (remaining gas: 1039143.032 units remaining) + [ (Some "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav") @packed.unpacked + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 41 (remaining gas: 1039143.022 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @packed.unpacked.some + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 41 (remaining gas: 1039143.007 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @packed.unpacked.some + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 47 (remaining gas: 1039141.135 units remaining) + [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed.unpacked.some.packed + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 35 (remaining gas: 1039141.105 units remaining) + [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed + 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed.unpacked.some.packed + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 50 (remaining gas: 1039141.070 units remaining) + [ 0 + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 51 (remaining gas: 1039141.055 units remaining) + [ True + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 52 (remaining gas: 1039141.045 units remaining) + [ (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 52 (remaining gas: 1039141.030 units remaining) + [ (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 58 (remaining gas: 1039141.020 units remaining) + [ (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 59 (remaining gas: 1039141.010 units remaining) + [ Unit + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 60 (remaining gas: 1039140.995 units remaining) + [ (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 62 (remaining gas: 1039140.985 units remaining) + [ Unit + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 60 (remaining gas: 1039140.955 units remaining) + [ Unit + Unit + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 63 (remaining gas: 1039140.728 units remaining) + [ 0x05030b @packed + Unit + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 64 (remaining gas: 1039140.713 units remaining) + [ Unit + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 66 (remaining gas: 1039140.486 units remaining) + [ 0x05030b @packed + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 67 (remaining gas: 1039140.066 units remaining) + [ (Some Unit) @packed.unpacked + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 70 (remaining gas: 1039140.056 units remaining) + [ Unit @packed.unpacked.some + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 70 (remaining gas: 1039140.041 units remaining) + [ Unit @packed.unpacked.some + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 76 (remaining gas: 1039139.814 units remaining) + [ 0x05030b @packed.unpacked.some.packed + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 64 (remaining gas: 1039139.784 units remaining) + [ 0x05030b @packed + 0x05030b @packed.unpacked.some.packed + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 79 (remaining gas: 1039139.749 units remaining) + [ 0 + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 80 (remaining gas: 1039139.734 units remaining) + [ True + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 81 (remaining gas: 1039139.724 units remaining) + [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 81 (remaining gas: 1039139.709 units remaining) + [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 87 (remaining gas: 1039139.699 units remaining) + [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 88 (remaining gas: 1039139.689 units remaining) + [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 89 (remaining gas: 1039139.674 units remaining) + [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 91 (remaining gas: 1039139.664 units remaining) + [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 89 (remaining gas: 1039139.634 units remaining) + [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 92 (remaining gas: 1039137.147 units remaining) + [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 93 (remaining gas: 1039137.132 units remaining) + [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 95 (remaining gas: 1039134.645 units remaining) + [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 96 (remaining gas: 1039132.842 units remaining) + [ (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe") @packed.unpacked + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 99 (remaining gas: 1039132.832 units remaining) + [ "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe" @packed.unpacked.some + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 99 (remaining gas: 1039132.817 units remaining) + [ "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe" @packed.unpacked.some + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 105 (remaining gas: 1039130.330 units remaining) + [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 93 (remaining gas: 1039130.300 units remaining) + [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed + 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 108 (remaining gas: 1039130.264 units remaining) + [ 0 + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 109 (remaining gas: 1039130.249 units remaining) + [ True + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 110 (remaining gas: 1039130.239 units remaining) + [ (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 110 (remaining gas: 1039130.224 units remaining) + [ (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 116 (remaining gas: 1039130.214 units remaining) + [ (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 117 (remaining gas: 1039130.204 units remaining) + [ (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 118 (remaining gas: 1039130.189 units remaining) + [ (Pair (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 120 (remaining gas: 1039130.179 units remaining) + [ (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 118 (remaining gas: 1039130.149 units remaining) + [ (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 121 (remaining gas: 1039127.500 units remaining) + [ 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed + (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 122 (remaining gas: 1039127.485 units remaining) + [ (Some "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 124 (remaining gas: 1039124.836 units remaining) + [ 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 125 (remaining gas: 1039122.892 units remaining) + [ (Some (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe")) @packed.unpacked + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 129 (remaining gas: 1039122.882 units remaining) + [ (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe") @packed.unpacked.some + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 129 (remaining gas: 1039122.867 units remaining) + [ (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe") @packed.unpacked.some + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 135 (remaining gas: 1039120.218 units remaining) + [ 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 122 (remaining gas: 1039120.188 units remaining) + [ 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed + 0x0505090a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 138 (remaining gas: 1039120.152 units remaining) + [ 0 + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 139 (remaining gas: 1039120.137 units remaining) + [ True + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 140 (remaining gas: 1039120.127 units remaining) + [ (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 140 (remaining gas: 1039120.112 units remaining) + [ (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 146 (remaining gas: 1039120.102 units remaining) + [ (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 147 (remaining gas: 1039120.092 units remaining) + [ { Unit } + (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 148 (remaining gas: 1039120.077 units remaining) + [ (Pair { Unit } + { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 150 (remaining gas: 1039120.067 units remaining) + [ { Unit } + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 148 (remaining gas: 1039120.037 units remaining) + [ { Unit } + { Unit } + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 151 (remaining gas: 1039119.549 units remaining) + [ 0x050200000002030b @packed + { Unit } + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 152 (remaining gas: 1039119.534 units remaining) + [ { Unit } + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 154 (remaining gas: 1039119.046 units remaining) + [ 0x050200000002030b @packed + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 155 (remaining gas: 1039118.425 units remaining) + [ (Some { Unit }) @packed.unpacked + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 159 (remaining gas: 1039118.415 units remaining) + [ { Unit } @packed.unpacked.some + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 159 (remaining gas: 1039118.400 units remaining) + [ { Unit } @packed.unpacked.some + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 165 (remaining gas: 1039117.912 units remaining) + [ 0x050200000002030b @packed.unpacked.some.packed + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 152 (remaining gas: 1039117.882 units remaining) + [ 0x050200000002030b @packed + 0x050200000002030b @packed.unpacked.some.packed + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 168 (remaining gas: 1039117.847 units remaining) + [ 0 + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 169 (remaining gas: 1039117.832 units remaining) + [ True + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 170 (remaining gas: 1039117.822 units remaining) + [ (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 170 (remaining gas: 1039117.807 units remaining) + [ (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 176 (remaining gas: 1039117.797 units remaining) + [ (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 177 (remaining gas: 1039117.787 units remaining) + [ { True } + (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 178 (remaining gas: 1039117.772 units remaining) + [ (Pair { True } + (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 180 (remaining gas: 1039117.762 units remaining) + [ { True } + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 178 (remaining gas: 1039117.732 units remaining) + [ { True } + { True } + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 181 (remaining gas: 1039117.244 units remaining) + [ 0x050200000002030a @packed + { True } + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 182 (remaining gas: 1039117.229 units remaining) + [ { True } + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 184 (remaining gas: 1039116.741 units remaining) + [ 0x050200000002030a @packed + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 185 (remaining gas: 1039115.920 units remaining) + [ (Some { True }) @packed.unpacked + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 189 (remaining gas: 1039115.910 units remaining) + [ { True } @packed.unpacked.some + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 189 (remaining gas: 1039115.895 units remaining) + [ { True } @packed.unpacked.some + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 195 (remaining gas: 1039115.407 units remaining) + [ 0x050200000002030a @packed.unpacked.some.packed + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 182 (remaining gas: 1039115.377 units remaining) + [ 0x050200000002030a @packed + 0x050200000002030a @packed.unpacked.some.packed + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 198 (remaining gas: 1039115.342 units remaining) + [ 0 + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 199 (remaining gas: 1039115.327 units remaining) + [ True + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 200 (remaining gas: 1039115.317 units remaining) + [ (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 200 (remaining gas: 1039115.302 units remaining) + [ (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 206 (remaining gas: 1039115.292 units remaining) + [ (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 207 (remaining gas: 1039115.282 units remaining) + [ (Pair 19 10) + (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 208 (remaining gas: 1039115.267 units remaining) + [ (Pair (Pair 19 10) + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 210 (remaining gas: 1039115.257 units remaining) + [ (Pair 19 10) + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 208 (remaining gas: 1039115.227 units remaining) + [ (Pair 19 10) + (Pair 19 10) + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 211 (remaining gas: 1039114.676 units remaining) + [ 0x0507070013000a @packed + (Pair 19 10) + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 212 (remaining gas: 1039114.661 units remaining) + [ (Pair 19 10) + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 214 (remaining gas: 1039114.110 units remaining) + [ 0x0507070013000a @packed + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 215 (remaining gas: 1039113.410 units remaining) + [ (Some (Pair 19 10)) @packed.unpacked + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 220 (remaining gas: 1039113.400 units remaining) + [ (Pair 19 10) @packed.unpacked.some + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 220 (remaining gas: 1039113.385 units remaining) + [ (Pair 19 10) @packed.unpacked.some + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 226 (remaining gas: 1039112.834 units remaining) + [ 0x0507070013000a @packed.unpacked.some.packed + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 212 (remaining gas: 1039112.804 units remaining) + [ 0x0507070013000a @packed + 0x0507070013000a @packed.unpacked.some.packed + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 229 (remaining gas: 1039112.769 units remaining) + [ 0 + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 230 (remaining gas: 1039112.754 units remaining) + [ True + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 231 (remaining gas: 1039112.744 units remaining) + [ (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 231 (remaining gas: 1039112.729 units remaining) + [ (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 237 (remaining gas: 1039112.719 units remaining) + [ (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 238 (remaining gas: 1039112.709 units remaining) + [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 239 (remaining gas: 1039112.694 units remaining) + [ (Pair (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK }) ] + - location: 241 (remaining gas: 1039112.684 units remaining) + [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 239 (remaining gas: 1039112.654 units remaining) + [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 242 (remaining gas: 1039111.402 units remaining) + [ 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed + (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 243 (remaining gas: 1039111.387 units remaining) + [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 245 (remaining gas: 1039110.135 units remaining) + [ 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 246 (remaining gas: 1039109.042 units remaining) + [ (Some (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5")) @packed.unpacked + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 251 (remaining gas: 1039109.032 units remaining) + [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked.some + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 251 (remaining gas: 1039109.017 units remaining) + [ (Left "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5") @packed.unpacked.some + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 257 (remaining gas: 1039107.765 units remaining) + [ 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed.unpacked.some.packed + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 243 (remaining gas: 1039107.735 units remaining) + [ 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed + 0x0505050a0000001500bdfe3885e846fdea23c9acbe3bb1cfcca9c03e4a @packed.unpacked.some.packed + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 260 (remaining gas: 1039107.700 units remaining) + [ 0 + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 261 (remaining gas: 1039107.685 units remaining) + [ True + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 262 (remaining gas: 1039107.675 units remaining) + [ (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 262 (remaining gas: 1039107.660 units remaining) + [ (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 268 (remaining gas: 1039107.650 units remaining) + [ (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 269 (remaining gas: 1039107.640 units remaining) + [ { Elt 0 "foo" ; Elt 1 "bar" } + (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 270 (remaining gas: 1039107.625 units remaining) + [ (Pair { Elt 0 "foo" ; Elt 1 "bar" } { PACK }) ] + - location: 272 (remaining gas: 1039107.615 units remaining) + [ { Elt 0 "foo" ; Elt 1 "bar" } + { PACK } ] + - location: 270 (remaining gas: 1039107.585 units remaining) + [ { Elt 0 "foo" ; Elt 1 "bar" } + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK } ] + - location: 273 (remaining gas: 1039105.980 units remaining) + [ 0x050200000018070400000100000003666f6f070400010100000003626172 @packed + { Elt 0 "foo" ; Elt 1 "bar" } + { PACK } ] + - location: 274 (remaining gas: 1039105.965 units remaining) + [ { Elt 0 "foo" ; Elt 1 "bar" } + { PACK } ] + - location: 276 (remaining gas: 1039104.360 units remaining) + [ 0x050200000018070400000100000003666f6f070400010100000003626172 @packed + { PACK } ] + - location: 277 (remaining gas: 1039102.504 units remaining) + [ (Some { Elt 0 "foo" ; Elt 1 "bar" }) @packed.unpacked + { PACK } ] + - location: 282 (remaining gas: 1039102.494 units remaining) + [ { Elt 0 "foo" ; Elt 1 "bar" } @packed.unpacked.some + { PACK } ] + - location: 282 (remaining gas: 1039102.479 units remaining) + [ { Elt 0 "foo" ; Elt 1 "bar" } @packed.unpacked.some + { PACK } ] + - location: 288 (remaining gas: 1039100.874 units remaining) + [ 0x050200000018070400000100000003666f6f070400010100000003626172 @packed.unpacked.some.packed + { PACK } ] + - location: 274 (remaining gas: 1039100.844 units remaining) + [ 0x050200000018070400000100000003666f6f070400010100000003626172 @packed + 0x050200000018070400000100000003666f6f070400010100000003626172 @packed.unpacked.some.packed + { PACK } ] + - location: 291 (remaining gas: 1039100.809 units remaining) + [ 0 + { PACK } ] + - location: 292 (remaining gas: 1039100.794 units remaining) + [ True + { PACK } ] + - location: 293 (remaining gas: 1039100.784 units remaining) + [ { PACK } ] + - location: 293 (remaining gas: 1039100.769 units remaining) + [ { PACK } ] + - location: 299 (remaining gas: 1039100.759 units remaining) + [ { PACK } + { PACK } ] + - location: 300 (remaining gas: 1039100.086 units remaining) + [ 0x050200000002030c @packed + { PACK } ] + - location: 301 (remaining gas: 1039100.071 units remaining) + [ { PACK } ] + - location: 303 (remaining gas: 1039099.398 units remaining) + [ 0x050200000002030c @packed ] + - location: 304 (remaining gas: 1039098.217 units remaining) + [ (Some { PACK }) @packed.unpacked ] + - location: 309 (remaining gas: 1039098.207 units remaining) + [ { PACK } @packed.unpacked.some ] + - location: 309 (remaining gas: 1039098.192 units remaining) + [ { PACK } @packed.unpacked.some ] + - location: 315 (remaining gas: 1039097.519 units remaining) + [ 0x050200000002030c @packed.unpacked.some.packed ] + - location: 301 (remaining gas: 1039097.489 units remaining) + [ 0x050200000002030c @packed + 0x050200000002030c @packed.unpacked.some.packed ] + - location: 318 (remaining gas: 1039097.454 units remaining) + [ 0 ] + - location: 319 (remaining gas: 1039097.439 units remaining) + [ True ] + - location: 320 (remaining gas: 1039097.429 units remaining) + [ ] + - location: 320 (remaining gas: 1039097.414 units remaining) + [ ] + - location: 326 (remaining gas: 1039097.404 units remaining) + [ Unit ] + - location: 327 (remaining gas: 1039097.389 units remaining) + [ {} + Unit ] + - location: 329 (remaining gas: 1039097.374 units remaining) + [ (Pair {} Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.4e20b52378.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.4e20b52378.out" new file mode 100644 index 000000000000..9684d352eff7 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair \"edpkuBknW28nW72KG6RoH.4e20b52378.out" @@ -0,0 +1,1032 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[packunpack_rev_cty.tz-Unit-(Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" (Pair Unit (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" (Pair None (Pair { } (Pair { } (Pair (Pair 40 -10) (Pair (Right "2019-09-09T08:35:33Z") (Pair { } { DUP ; DROP ; PACK } )))))))))-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 28 (remaining gas: 1039478.033 units remaining) + [ (Pair (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) + Unit) ] + - location: 28 (remaining gas: 1039478.023 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) @parameter ] + - location: 29 (remaining gas: 1039478.013 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) @parameter + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) @parameter ] + - location: 30 (remaining gas: 1039478.003 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) @parameter ] + - location: 31 (remaining gas: 1039477.988 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) @parameter ] + - location: 33 (remaining gas: 1039477.978 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 31 (remaining gas: 1039477.948 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 34 (remaining gas: 1039476.076 units remaining) + [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed + "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 35 (remaining gas: 1039476.061 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 37 (remaining gas: 1039474.189 units remaining) + [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 38 (remaining gas: 1039153.045 units remaining) + [ (Some "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav") @packed.unpacked + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 41 (remaining gas: 1039153.035 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @packed.unpacked.some + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 41 (remaining gas: 1039153.020 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @packed.unpacked.some + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 47 (remaining gas: 1039151.148 units remaining) + [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed.unpacked.some.packed + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 35 (remaining gas: 1039151.118 units remaining) + [ 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed + 0x050a00000021004798d2cc98473d7e250c898885718afd2e4efbcb1a1595ab9730761ed830de0f @packed.unpacked.some.packed + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 50 (remaining gas: 1039151.083 units remaining) + [ 0 + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 51 (remaining gas: 1039151.068 units remaining) + [ True + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 52 (remaining gas: 1039151.058 units remaining) + [ (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 52 (remaining gas: 1039151.043 units remaining) + [ (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 58 (remaining gas: 1039151.033 units remaining) + [ (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 59 (remaining gas: 1039151.023 units remaining) + [ Unit + (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 60 (remaining gas: 1039151.008 units remaining) + [ (Pair Unit + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 62 (remaining gas: 1039150.998 units remaining) + [ Unit + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 60 (remaining gas: 1039150.968 units remaining) + [ Unit + Unit + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 63 (remaining gas: 1039150.741 units remaining) + [ 0x05030b @packed + Unit + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 64 (remaining gas: 1039150.726 units remaining) + [ Unit + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 66 (remaining gas: 1039150.499 units remaining) + [ 0x05030b @packed + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 67 (remaining gas: 1039150.079 units remaining) + [ (Some Unit) @packed.unpacked + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 70 (remaining gas: 1039150.069 units remaining) + [ Unit @packed.unpacked.some + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 70 (remaining gas: 1039150.054 units remaining) + [ Unit @packed.unpacked.some + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 76 (remaining gas: 1039149.827 units remaining) + [ 0x05030b @packed.unpacked.some.packed + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 64 (remaining gas: 1039149.797 units remaining) + [ 0x05030b @packed + 0x05030b @packed.unpacked.some.packed + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 79 (remaining gas: 1039149.762 units remaining) + [ 0 + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 80 (remaining gas: 1039149.747 units remaining) + [ True + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 81 (remaining gas: 1039149.737 units remaining) + [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 81 (remaining gas: 1039149.722 units remaining) + [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 87 (remaining gas: 1039149.712 units remaining) + [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 88 (remaining gas: 1039149.702 units remaining) + [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 89 (remaining gas: 1039149.687 units remaining) + [ (Pair "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 91 (remaining gas: 1039149.677 units remaining) + [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 89 (remaining gas: 1039149.647 units remaining) + [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 92 (remaining gas: 1039147.160 units remaining) + [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed + "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 93 (remaining gas: 1039147.145 units remaining) + [ "edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 95 (remaining gas: 1039144.658 units remaining) + [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 96 (remaining gas: 1039142.855 units remaining) + [ (Some "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe") @packed.unpacked + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 99 (remaining gas: 1039142.845 units remaining) + [ "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe" @packed.unpacked.some + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 99 (remaining gas: 1039142.830 units remaining) + [ "sigXeXB5JD5TaLb3xgTPKjgf9W45judiCmNP9UBdZBdmtHSGBxL1M8ZSUb6LpjGP2MdfUBTB4WHs5APnvyRV1LooU6QHJuDe" @packed.unpacked.some + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 105 (remaining gas: 1039140.343 units remaining) + [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 93 (remaining gas: 1039140.313 units remaining) + [ 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed + 0x050a0000004049d47dba27bd76208b092f3e500f64818920c817491b8b9094f28c2c2b9c6721b257b8878ce47182122b8ea84aeacd84a8aa28cb1f1fe48a26355a7bca4b8306 @packed.unpacked.some.packed + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 108 (remaining gas: 1039140.277 units remaining) + [ 0 + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 109 (remaining gas: 1039140.262 units remaining) + [ True + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 110 (remaining gas: 1039140.252 units remaining) + [ (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 110 (remaining gas: 1039140.237 units remaining) + [ (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 116 (remaining gas: 1039140.227 units remaining) + [ (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 117 (remaining gas: 1039140.217 units remaining) + [ None + (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 118 (remaining gas: 1039140.202 units remaining) + [ (Pair None + {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 120 (remaining gas: 1039140.192 units remaining) + [ None + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 118 (remaining gas: 1039140.162 units remaining) + [ None + None + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 121 (remaining gas: 1039139.935 units remaining) + [ 0x050306 @packed + None + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 122 (remaining gas: 1039139.920 units remaining) + [ None + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 124 (remaining gas: 1039139.693 units remaining) + [ 0x050306 @packed + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 125 (remaining gas: 1039139.273 units remaining) + [ (Some None) @packed.unpacked + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 129 (remaining gas: 1039139.263 units remaining) + [ None @packed.unpacked.some + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 129 (remaining gas: 1039139.248 units remaining) + [ None @packed.unpacked.some + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 135 (remaining gas: 1039139.021 units remaining) + [ 0x050306 @packed.unpacked.some.packed + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 122 (remaining gas: 1039138.991 units remaining) + [ 0x050306 @packed + 0x050306 @packed.unpacked.some.packed + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 138 (remaining gas: 1039138.956 units remaining) + [ 0 + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 139 (remaining gas: 1039138.941 units remaining) + [ True + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 140 (remaining gas: 1039138.931 units remaining) + [ (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 140 (remaining gas: 1039138.916 units remaining) + [ (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 146 (remaining gas: 1039138.906 units remaining) + [ (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 147 (remaining gas: 1039138.896 units remaining) + [ {} + (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 148 (remaining gas: 1039138.881 units remaining) + [ (Pair {} + {} + (Pair 40 -10) + (Right "2019-09-09T08:35:33Z") + {} + { DUP ; DROP ; PACK }) ] + - location: 150 (remaining gas: 1039138.871 units remaining) + [ {} + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 148 (remaining gas: 1039138.841 units remaining) + [ {} + {} + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 151 (remaining gas: 1039138.515 units remaining) + [ 0x050200000000 @packed + {} + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 152 (remaining gas: 1039138.500 units remaining) + [ {} + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 154 (remaining gas: 1039138.174 units remaining) + [ 0x050200000000 @packed + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 155 (remaining gas: 1039137.694 units remaining) + [ (Some {}) @packed.unpacked + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 159 (remaining gas: 1039137.684 units remaining) + [ {} @packed.unpacked.some + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 159 (remaining gas: 1039137.669 units remaining) + [ {} @packed.unpacked.some + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 165 (remaining gas: 1039137.343 units remaining) + [ 0x050200000000 @packed.unpacked.some.packed + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 152 (remaining gas: 1039137.313 units remaining) + [ 0x050200000000 @packed + 0x050200000000 @packed.unpacked.some.packed + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 168 (remaining gas: 1039137.278 units remaining) + [ 0 + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 169 (remaining gas: 1039137.263 units remaining) + [ True + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 170 (remaining gas: 1039137.253 units remaining) + [ (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 170 (remaining gas: 1039137.238 units remaining) + [ (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 176 (remaining gas: 1039137.228 units remaining) + [ (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 177 (remaining gas: 1039137.218 units remaining) + [ {} + (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 178 (remaining gas: 1039137.203 units remaining) + [ (Pair {} (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 180 (remaining gas: 1039137.193 units remaining) + [ {} + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 178 (remaining gas: 1039137.163 units remaining) + [ {} + {} + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 181 (remaining gas: 1039136.837 units remaining) + [ 0x050200000000 @packed + {} + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 182 (remaining gas: 1039136.822 units remaining) + [ {} + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 184 (remaining gas: 1039136.496 units remaining) + [ 0x050200000000 @packed + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 185 (remaining gas: 1039136.016 units remaining) + [ (Some {}) @packed.unpacked + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 189 (remaining gas: 1039136.006 units remaining) + [ {} @packed.unpacked.some + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 189 (remaining gas: 1039135.991 units remaining) + [ {} @packed.unpacked.some + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 195 (remaining gas: 1039135.665 units remaining) + [ 0x050200000000 @packed.unpacked.some.packed + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 182 (remaining gas: 1039135.635 units remaining) + [ 0x050200000000 @packed + 0x050200000000 @packed.unpacked.some.packed + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 198 (remaining gas: 1039135.600 units remaining) + [ 0 + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 199 (remaining gas: 1039135.585 units remaining) + [ True + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 200 (remaining gas: 1039135.575 units remaining) + [ (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 200 (remaining gas: 1039135.560 units remaining) + [ (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 206 (remaining gas: 1039135.550 units remaining) + [ (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 207 (remaining gas: 1039135.540 units remaining) + [ (Pair 40 -10) + (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 208 (remaining gas: 1039135.525 units remaining) + [ (Pair (Pair 40 -10) (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 210 (remaining gas: 1039135.515 units remaining) + [ (Pair 40 -10) + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 208 (remaining gas: 1039135.485 units remaining) + [ (Pair 40 -10) + (Pair 40 -10) + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 211 (remaining gas: 1039134.934 units remaining) + [ 0x0507070028004a @packed + (Pair 40 -10) + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 212 (remaining gas: 1039134.919 units remaining) + [ (Pair 40 -10) + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 214 (remaining gas: 1039134.368 units remaining) + [ 0x0507070028004a @packed + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 215 (remaining gas: 1039133.668 units remaining) + [ (Some (Pair 40 -10)) @packed.unpacked + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 220 (remaining gas: 1039133.658 units remaining) + [ (Pair 40 -10) @packed.unpacked.some + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 220 (remaining gas: 1039133.643 units remaining) + [ (Pair 40 -10) @packed.unpacked.some + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 226 (remaining gas: 1039133.092 units remaining) + [ 0x0507070028004a @packed.unpacked.some.packed + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 212 (remaining gas: 1039133.062 units remaining) + [ 0x0507070028004a @packed + 0x0507070028004a @packed.unpacked.some.packed + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 229 (remaining gas: 1039133.027 units remaining) + [ 0 + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 230 (remaining gas: 1039133.012 units remaining) + [ True + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 231 (remaining gas: 1039133.002 units remaining) + [ (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 231 (remaining gas: 1039132.987 units remaining) + [ (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 237 (remaining gas: 1039132.977 units remaining) + [ (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 238 (remaining gas: 1039132.967 units remaining) + [ (Right "2019-09-09T08:35:33Z") + (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 239 (remaining gas: 1039132.952 units remaining) + [ (Pair (Right "2019-09-09T08:35:33Z") {} { DUP ; DROP ; PACK }) ] + - location: 241 (remaining gas: 1039132.942 units remaining) + [ (Right "2019-09-09T08:35:33Z") + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 239 (remaining gas: 1039132.912 units remaining) + [ (Right "2019-09-09T08:35:33Z") + (Right "2019-09-09T08:35:33Z") + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 242 (remaining gas: 1039132.391 units remaining) + [ 0x0505080095bbb0d70b @packed + (Right "2019-09-09T08:35:33Z") + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 243 (remaining gas: 1039132.376 units remaining) + [ (Right "2019-09-09T08:35:33Z") + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 245 (remaining gas: 1039131.855 units remaining) + [ 0x0505080095bbb0d70b @packed + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 246 (remaining gas: 1039131.214 units remaining) + [ (Some (Right "2019-09-09T08:35:33Z")) @packed.unpacked + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 251 (remaining gas: 1039131.204 units remaining) + [ (Right "2019-09-09T08:35:33Z") @packed.unpacked.some + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 251 (remaining gas: 1039131.189 units remaining) + [ (Right "2019-09-09T08:35:33Z") @packed.unpacked.some + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 257 (remaining gas: 1039130.668 units remaining) + [ 0x0505080095bbb0d70b @packed.unpacked.some.packed + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 243 (remaining gas: 1039130.638 units remaining) + [ 0x0505080095bbb0d70b @packed + 0x0505080095bbb0d70b @packed.unpacked.some.packed + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 260 (remaining gas: 1039130.603 units remaining) + [ 0 + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 261 (remaining gas: 1039130.588 units remaining) + [ True + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 262 (remaining gas: 1039130.578 units remaining) + [ (Pair {} { DUP ; DROP ; PACK }) ] + - location: 262 (remaining gas: 1039130.563 units remaining) + [ (Pair {} { DUP ; DROP ; PACK }) ] + - location: 268 (remaining gas: 1039130.553 units remaining) + [ (Pair {} { DUP ; DROP ; PACK }) + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 269 (remaining gas: 1039130.543 units remaining) + [ {} + (Pair {} { DUP ; DROP ; PACK }) ] + - location: 270 (remaining gas: 1039130.528 units remaining) + [ (Pair {} { DUP ; DROP ; PACK }) ] + - location: 272 (remaining gas: 1039130.518 units remaining) + [ {} + { DUP ; DROP ; PACK } ] + - location: 270 (remaining gas: 1039130.488 units remaining) + [ {} + {} + { DUP ; DROP ; PACK } ] + - location: 273 (remaining gas: 1039130.162 units remaining) + [ 0x050200000000 @packed + {} + { DUP ; DROP ; PACK } ] + - location: 274 (remaining gas: 1039130.147 units remaining) + [ {} + { DUP ; DROP ; PACK } ] + - location: 276 (remaining gas: 1039129.821 units remaining) + [ 0x050200000000 @packed + { DUP ; DROP ; PACK } ] + - location: 277 (remaining gas: 1039129.341 units remaining) + [ (Some {}) @packed.unpacked + { DUP ; DROP ; PACK } ] + - location: 282 (remaining gas: 1039129.331 units remaining) + [ {} @packed.unpacked.some + { DUP ; DROP ; PACK } ] + - location: 282 (remaining gas: 1039129.316 units remaining) + [ {} @packed.unpacked.some + { DUP ; DROP ; PACK } ] + - location: 288 (remaining gas: 1039128.990 units remaining) + [ 0x050200000000 @packed.unpacked.some.packed + { DUP ; DROP ; PACK } ] + - location: 274 (remaining gas: 1039128.960 units remaining) + [ 0x050200000000 @packed + 0x050200000000 @packed.unpacked.some.packed + { DUP ; DROP ; PACK } ] + - location: 291 (remaining gas: 1039128.925 units remaining) + [ 0 + { DUP ; DROP ; PACK } ] + - location: 292 (remaining gas: 1039128.910 units remaining) + [ True + { DUP ; DROP ; PACK } ] + - location: 293 (remaining gas: 1039128.900 units remaining) + [ { DUP ; DROP ; PACK } ] + - location: 293 (remaining gas: 1039128.885 units remaining) + [ { DUP ; DROP ; PACK } ] + - location: 299 (remaining gas: 1039128.875 units remaining) + [ { DUP ; DROP ; PACK } + { DUP ; DROP ; PACK } ] + - location: 300 (remaining gas: 1039127.738 units remaining) + [ 0x05020000000603210320030c @packed + { DUP ; DROP ; PACK } ] + - location: 301 (remaining gas: 1039127.723 units remaining) + [ { DUP ; DROP ; PACK } ] + - location: 303 (remaining gas: 1039126.586 units remaining) + [ 0x05020000000603210320030c @packed ] + - location: 304 (remaining gas: 1039124.345 units remaining) + [ (Some { DUP ; DROP ; PACK }) @packed.unpacked ] + - location: 309 (remaining gas: 1039124.335 units remaining) + [ { DUP ; DROP ; PACK } @packed.unpacked.some ] + - location: 309 (remaining gas: 1039124.320 units remaining) + [ { DUP ; DROP ; PACK } @packed.unpacked.some ] + - location: 315 (remaining gas: 1039123.183 units remaining) + [ 0x05020000000603210320030c @packed.unpacked.some.packed ] + - location: 301 (remaining gas: 1039123.153 units remaining) + [ 0x05020000000603210320030c @packed + 0x05020000000603210320030c @packed.unpacked.some.packed ] + - location: 318 (remaining gas: 1039123.118 units remaining) + [ 0 ] + - location: 319 (remaining gas: 1039123.103 units remaining) + [ True ] + - location: 320 (remaining gas: 1039123.093 units remaining) + [ ] + - location: 320 (remaining gas: 1039123.078 units remaining) + [ ] + - location: 326 (remaining gas: 1039123.068 units remaining) + [ Unit ] + - location: 327 (remaining gas: 1039123.053 units remaining) + [ {} + Unit ] + - location: 329 (remaining gas: 1039123.038 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))].out new file mode 100644 index 000000000000..a11b48dde9c6 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False False)-(Some (Pair False False))] + +storage + (Some (Pair False False)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039993.234 units remaining) + [ (Pair (Pair False False) None) ] + - location: 12 (remaining gas: 1039993.224 units remaining) + [ (Pair False False) @parameter ] + - location: 13 (remaining gas: 1039993.209 units remaining) + [ (Some (Pair False False)) ] + - location: 14 (remaining gas: 1039993.194 units remaining) + [ {} + (Some (Pair False False)) ] + - location: 16 (remaining gas: 1039993.179 units remaining) + [ (Pair {} (Some (Pair False False))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))].out new file mode 100644 index 000000000000..aee166018b89 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair False True)-(Some (Pair False True))] + +storage + (Some (Pair False True)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039993.234 units remaining) + [ (Pair (Pair False True) None) ] + - location: 12 (remaining gas: 1039993.224 units remaining) + [ (Pair False True) @parameter ] + - location: 13 (remaining gas: 1039993.209 units remaining) + [ (Some (Pair False True)) ] + - location: 14 (remaining gas: 1039993.194 units remaining) + [ {} + (Some (Pair False True)) ] + - location: 16 (remaining gas: 1039993.179 units remaining) + [ (Pair {} (Some (Pair False True))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))].out new file mode 100644 index 000000000000..0d5d310c9d97 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True False)-(Some (Pair True False))] + +storage + (Some (Pair True False)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039993.234 units remaining) + [ (Pair (Pair True False) None) ] + - location: 12 (remaining gas: 1039993.224 units remaining) + [ (Pair True False) @parameter ] + - location: 13 (remaining gas: 1039993.209 units remaining) + [ (Some (Pair True False)) ] + - location: 14 (remaining gas: 1039993.194 units remaining) + [ {} + (Some (Pair True False)) ] + - location: 16 (remaining gas: 1039993.179 units remaining) + [ (Pair {} (Some (Pair True False))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))].out new file mode 100644 index 000000000000..3cdd76bdb2e4 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pair_id.tz-None-(Pair True True)-(Some (Pair True True))] + +storage + (Some (Pair True True)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039993.234 units remaining) + [ (Pair (Pair True True) None) ] + - location: 12 (remaining gas: 1039993.224 units remaining) + [ (Pair True True) @parameter ] + - location: 13 (remaining gas: 1039993.209 units remaining) + [ (Some (Pair True True)) ] + - location: 14 (remaining gas: 1039993.194 units remaining) + [ {} + (Some (Pair True True)) ] + - location: 16 (remaining gas: 1039993.179 units remaining) + [ (Pair {} (Some (Pair True True))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52].out new file mode 100644 index 000000000000..fc264351ed8e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52].out @@ -0,0 +1,47 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pexec.tz-14-38-52] + +storage + 52 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039989.309 units remaining) + [ (Pair 38 14) ] + - location: 7 (remaining gas: 1039989.299 units remaining) + [ { UNPAIR ; ADD } + (Pair 38 14) ] + - location: 15 (remaining gas: 1039989.289 units remaining) + [ (Pair 38 14) + { UNPAIR ; ADD } ] + - location: 16 (remaining gas: 1039989.279 units remaining) + [ 38 @parameter + 14 @storage + { UNPAIR ; ADD } ] + - location: 17 (remaining gas: 1039989.264 units remaining) + [ 14 @storage + { UNPAIR ; ADD } ] + - location: 19 (remaining gas: 1039989.039 units remaining) + [ { PUSH nat 14 ; PAIR ; { UNPAIR ; ADD } } ] + - location: 17 (remaining gas: 1039989.009 units remaining) + [ 38 @parameter + { PUSH nat 14 ; PAIR ; { UNPAIR ; ADD } } ] + - location: 12 (remaining gas: 1039988.999 units remaining) + [ 14 + 38 ] + - location: 12 (remaining gas: 1039988.984 units remaining) + [ (Pair 14 38) @arg ] + - location: 13 (remaining gas: 1039988.974 units remaining) + [ 14 + 38 ] + - location: 14 (remaining gas: 1039988.919 units remaining) + [ 52 ] + - location: 20 (remaining gas: 1039988.889 units remaining) + [ 52 ] + - location: 21 (remaining gas: 1039988.874 units remaining) + [ {} + 52 ] + - location: 23 (remaining gas: 1039988.859 units remaining) + [ (Pair {} 52) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out new file mode 100644 index 000000000000..88586313650a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }].out @@ -0,0 +1,282 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[pexec_2.tz-{ 0 ; 1 ; 2 ; 3}-4-{ 0 ; 7 ; 14 ; 21 }] + +storage + { 0 ; 7 ; 14 ; 21 } +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039979.891 units remaining) + [ (Pair 4 { 0 ; 1 ; 2 ; 3 }) ] + - location: 8 (remaining gas: 1039979.881 units remaining) + [ 4 @p + { 0 ; 1 ; 2 ; 3 } @s ] + - location: 9 (remaining gas: 1039979.871 units remaining) + [ { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } + 4 @p + { 0 ; 1 ; 2 ; 3 } @s ] + - location: 23 (remaining gas: 1039979.861 units remaining) + [ 4 @p + { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } + { 0 ; 1 ; 2 ; 3 } @s ] + - location: 24 (remaining gas: 1039979.636 units remaining) + [ { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } + { 0 ; 1 ; 2 ; 3 } @s ] + - location: 25 (remaining gas: 1039979.626 units remaining) + [ 3 + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } + { 0 ; 1 ; 2 ; 3 } @s ] + - location: 28 (remaining gas: 1039979.401 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } + { 0 ; 1 ; 2 ; 3 } @s ] + - location: 29 (remaining gas: 1039979.391 units remaining) + [ { 0 ; 1 ; 2 ; 3 } @s + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 30 (remaining gas: 1039979.391 units remaining) + [ 0 @s.elt + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 32 (remaining gas: 1039979.376 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 34 (remaining gas: 1039979.366 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 32 (remaining gas: 1039979.336 units remaining) + [ 0 @s.elt + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 16 (remaining gas: 1039979.326 units remaining) + [ 3 + 0 ] + - location: 16 (remaining gas: 1039979.311 units remaining) + [ (Pair 3 0) ] + - location: 16 (remaining gas: 1039979.301 units remaining) + [ 4 + (Pair 3 0) ] + - location: 16 (remaining gas: 1039979.286 units remaining) + [ (Pair 4 3 0) @arg ] + - location: 17 (remaining gas: 1039979.276 units remaining) + [ 4 + (Pair 3 0) ] + - location: 18 (remaining gas: 1039979.261 units remaining) + [ (Pair 3 0) ] + - location: 20 (remaining gas: 1039979.251 units remaining) + [ 3 + 0 ] + - location: 18 (remaining gas: 1039979.221 units remaining) + [ 4 + 3 + 0 ] + - location: 21 (remaining gas: 1039979.166 units remaining) + [ 7 + 0 ] + - location: 22 (remaining gas: 1039979.065 units remaining) + [ 0 ] + - location: 35 (remaining gas: 1039979.035 units remaining) + [ 0 + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 30 (remaining gas: 1039979.020 units remaining) + [ 1 @s.elt + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 32 (remaining gas: 1039979.005 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 34 (remaining gas: 1039978.995 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 32 (remaining gas: 1039978.965 units remaining) + [ 1 @s.elt + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 16 (remaining gas: 1039978.955 units remaining) + [ 3 + 1 ] + - location: 16 (remaining gas: 1039978.940 units remaining) + [ (Pair 3 1) ] + - location: 16 (remaining gas: 1039978.930 units remaining) + [ 4 + (Pair 3 1) ] + - location: 16 (remaining gas: 1039978.915 units remaining) + [ (Pair 4 3 1) @arg ] + - location: 17 (remaining gas: 1039978.905 units remaining) + [ 4 + (Pair 3 1) ] + - location: 18 (remaining gas: 1039978.890 units remaining) + [ (Pair 3 1) ] + - location: 20 (remaining gas: 1039978.880 units remaining) + [ 3 + 1 ] + - location: 18 (remaining gas: 1039978.850 units remaining) + [ 4 + 3 + 1 ] + - location: 21 (remaining gas: 1039978.795 units remaining) + [ 7 + 1 ] + - location: 22 (remaining gas: 1039978.691 units remaining) + [ 7 ] + - location: 35 (remaining gas: 1039978.661 units remaining) + [ 7 + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 30 (remaining gas: 1039978.646 units remaining) + [ 2 @s.elt + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 32 (remaining gas: 1039978.631 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 34 (remaining gas: 1039978.621 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 32 (remaining gas: 1039978.591 units remaining) + [ 2 @s.elt + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 16 (remaining gas: 1039978.581 units remaining) + [ 3 + 2 ] + - location: 16 (remaining gas: 1039978.566 units remaining) + [ (Pair 3 2) ] + - location: 16 (remaining gas: 1039978.556 units remaining) + [ 4 + (Pair 3 2) ] + - location: 16 (remaining gas: 1039978.541 units remaining) + [ (Pair 4 3 2) @arg ] + - location: 17 (remaining gas: 1039978.531 units remaining) + [ 4 + (Pair 3 2) ] + - location: 18 (remaining gas: 1039978.516 units remaining) + [ (Pair 3 2) ] + - location: 20 (remaining gas: 1039978.506 units remaining) + [ 3 + 2 ] + - location: 18 (remaining gas: 1039978.476 units remaining) + [ 4 + 3 + 2 ] + - location: 21 (remaining gas: 1039978.421 units remaining) + [ 7 + 2 ] + - location: 22 (remaining gas: 1039978.317 units remaining) + [ 14 ] + - location: 35 (remaining gas: 1039978.287 units remaining) + [ 14 + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 30 (remaining gas: 1039978.272 units remaining) + [ 3 @s.elt + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 32 (remaining gas: 1039978.257 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 34 (remaining gas: 1039978.247 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 32 (remaining gas: 1039978.217 units remaining) + [ 3 @s.elt + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 16 (remaining gas: 1039978.207 units remaining) + [ 3 + 3 ] + - location: 16 (remaining gas: 1039978.192 units remaining) + [ (Pair 3 3) ] + - location: 16 (remaining gas: 1039978.182 units remaining) + [ 4 + (Pair 3 3) ] + - location: 16 (remaining gas: 1039978.167 units remaining) + [ (Pair 4 3 3) @arg ] + - location: 17 (remaining gas: 1039978.157 units remaining) + [ 4 + (Pair 3 3) ] + - location: 18 (remaining gas: 1039978.142 units remaining) + [ (Pair 3 3) ] + - location: 20 (remaining gas: 1039978.132 units remaining) + [ 3 + 3 ] + - location: 18 (remaining gas: 1039978.102 units remaining) + [ 4 + 3 + 3 ] + - location: 21 (remaining gas: 1039978.047 units remaining) + [ 7 + 3 ] + - location: 22 (remaining gas: 1039977.943 units remaining) + [ 21 ] + - location: 35 (remaining gas: 1039977.913 units remaining) + [ 21 + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 30 (remaining gas: 1039977.898 units remaining) + [ { 0 ; 7 ; 14 ; 21 } + { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 36 (remaining gas: 1039977.883 units remaining) + [ { PUSH int 3 ; + PAIR ; + { PUSH int 4 ; PAIR ; { UNPAIR ; DIP { UNPAIR } ; ADD ; MUL } } } ] + - location: 38 (remaining gas: 1039977.873 units remaining) + [ ] + - location: 36 (remaining gas: 1039977.843 units remaining) + [ { 0 ; 7 ; 14 ; 21 } ] + - location: 39 (remaining gas: 1039977.828 units remaining) + [ {} + { 0 ; 7 ; 14 ; 21 } ] + - location: 41 (remaining gas: 1039977.813 units remaining) + [ (Pair {} { 0 ; 7 ; 14 ; 21 }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)].out new file mode 100644 index 000000000000..ce62a83e88ea --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)].out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[ret_int.tz-None-Unit-(Some 300)] + +storage + (Some 300) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.541 units remaining) + [ (Pair Unit None) ] + - location: 8 (remaining gas: 1039993.531 units remaining) + [ ] + - location: 9 (remaining gas: 1039993.521 units remaining) + [ 300 ] + - location: 12 (remaining gas: 1039993.506 units remaining) + [ (Some 300) ] + - location: 13 (remaining gas: 1039993.491 units remaining) + [ {} + (Some 300) ] + - location: 15 (remaining gas: 1039993.476 units remaining) + [ (Pair {} (Some 300)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" new file mode 100644 index 000000000000..425d52e23f47 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" @@ -0,0 +1,42 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[reverse.tz-{""}-{ "c" ; "b" ; "a" }-{ "a" ; "b" ; "c" }] + +storage + { "a" ; "b" ; "c" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039990.977 units remaining) + [ (Pair { "c" ; "b" ; "a" } { "" }) ] + - location: 9 (remaining gas: 1039990.967 units remaining) + [ { "c" ; "b" ; "a" } @parameter ] + - location: 10 (remaining gas: 1039990.952 units remaining) + [ {} + { "c" ; "b" ; "a" } @parameter ] + - location: 12 (remaining gas: 1039990.942 units remaining) + [ { "c" ; "b" ; "a" } @parameter + {} ] + - location: 13 (remaining gas: 1039990.942 units remaining) + [ "c" @parameter.elt + {} ] + - location: 15 (remaining gas: 1039990.927 units remaining) + [ { "c" } ] + - location: 13 (remaining gas: 1039990.912 units remaining) + [ "b" @parameter.elt + { "c" } ] + - location: 15 (remaining gas: 1039990.897 units remaining) + [ { "b" ; "c" } ] + - location: 13 (remaining gas: 1039990.882 units remaining) + [ "a" @parameter.elt + { "b" ; "c" } ] + - location: 15 (remaining gas: 1039990.867 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 13 (remaining gas: 1039990.852 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 16 (remaining gas: 1039990.837 units remaining) + [ {} + { "a" ; "b" ; "c" } ] + - location: 18 (remaining gas: 1039990.822 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{}-{}].out" new file mode 100644 index 000000000000..6d4f9478a112 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse.tz-{\"\"}-{}-{}].out" @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[reverse.tz-{""}-{}-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039991.349 units remaining) + [ (Pair {} { "" }) ] + - location: 9 (remaining gas: 1039991.339 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039991.324 units remaining) + [ {} + {} @parameter ] + - location: 12 (remaining gas: 1039991.314 units remaining) + [ {} @parameter + {} ] + - location: 13 (remaining gas: 1039991.314 units remaining) + [ {} ] + - location: 16 (remaining gas: 1039991.299 units remaining) + [ {} + {} ] + - location: 18 (remaining gas: 1039991.284 units remaining) + [ (Pair {} {}) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" new file mode 100644 index 000000000000..237f3ee98370 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{ \"c\" ; \"b\" ; \"a\" }-{ \"a\" ; \"b\" ; \"c\" }].out" @@ -0,0 +1,131 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{""}-{ "c" ; "b" ; "a" }-{ "a" ; "b" ; "c" }] + +storage + { "a" ; "b" ; "c" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039982.192 units remaining) + [ (Pair { "c" ; "b" ; "a" } { "" }) ] + - location: 9 (remaining gas: 1039982.182 units remaining) + [ { "c" ; "b" ; "a" } @parameter ] + - location: 10 (remaining gas: 1039982.167 units remaining) + [ {} + { "c" ; "b" ; "a" } @parameter ] + - location: 12 (remaining gas: 1039982.157 units remaining) + [ { "c" ; "b" ; "a" } @parameter + {} ] + - location: 13 (remaining gas: 1039982.147 units remaining) + [ True + { "c" ; "b" ; "a" } @parameter + {} ] + - location: 16 (remaining gas: 1039982.147 units remaining) + [ { "c" ; "b" ; "a" } @parameter + {} ] + - location: 18 (remaining gas: 1039982.137 units remaining) + [ "c" @parameter.hd + { "b" ; "a" } @parameter.tl + {} ] + - location: 20 (remaining gas: 1039982.127 units remaining) + [ { "b" ; "a" } @parameter.tl + "c" @parameter.hd + {} ] + - location: 21 (remaining gas: 1039982.112 units remaining) + [ "c" @parameter.hd + {} ] + - location: 23 (remaining gas: 1039982.097 units remaining) + [ { "c" } ] + - location: 21 (remaining gas: 1039982.067 units remaining) + [ { "b" ; "a" } @parameter.tl + { "c" } ] + - location: 24 (remaining gas: 1039982.057 units remaining) + [ True + { "b" ; "a" } @parameter + { "c" } ] + - location: 18 (remaining gas: 1039982.042 units remaining) + [ True + { "b" ; "a" } @parameter + { "c" } ] + - location: 16 (remaining gas: 1039982.027 units remaining) + [ { "b" ; "a" } @parameter + { "c" } ] + - location: 18 (remaining gas: 1039982.017 units remaining) + [ "b" @parameter.hd + { "a" } @parameter.tl + { "c" } ] + - location: 20 (remaining gas: 1039982.007 units remaining) + [ { "a" } @parameter.tl + "b" @parameter.hd + { "c" } ] + - location: 21 (remaining gas: 1039981.992 units remaining) + [ "b" @parameter.hd + { "c" } ] + - location: 23 (remaining gas: 1039981.977 units remaining) + [ { "b" ; "c" } ] + - location: 21 (remaining gas: 1039981.947 units remaining) + [ { "a" } @parameter.tl + { "b" ; "c" } ] + - location: 24 (remaining gas: 1039981.937 units remaining) + [ True + { "a" } @parameter + { "b" ; "c" } ] + - location: 18 (remaining gas: 1039981.922 units remaining) + [ True + { "a" } @parameter + { "b" ; "c" } ] + - location: 16 (remaining gas: 1039981.907 units remaining) + [ { "a" } @parameter + { "b" ; "c" } ] + - location: 18 (remaining gas: 1039981.897 units remaining) + [ "a" @parameter.hd + {} @parameter.tl + { "b" ; "c" } ] + - location: 20 (remaining gas: 1039981.887 units remaining) + [ {} @parameter.tl + "a" @parameter.hd + { "b" ; "c" } ] + - location: 21 (remaining gas: 1039981.872 units remaining) + [ "a" @parameter.hd + { "b" ; "c" } ] + - location: 23 (remaining gas: 1039981.857 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 21 (remaining gas: 1039981.827 units remaining) + [ {} @parameter.tl + { "a" ; "b" ; "c" } ] + - location: 24 (remaining gas: 1039981.817 units remaining) + [ True + {} @parameter + { "a" ; "b" ; "c" } ] + - location: 18 (remaining gas: 1039981.802 units remaining) + [ True + {} @parameter + { "a" ; "b" ; "c" } ] + - location: 16 (remaining gas: 1039981.787 units remaining) + [ {} @parameter + { "a" ; "b" ; "c" } ] + - location: 18 (remaining gas: 1039981.777 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 28 (remaining gas: 1039981.762 units remaining) + [ {} + { "a" ; "b" ; "c" } ] + - location: 30 (remaining gas: 1039981.752 units remaining) + [ False + {} @parameter + { "a" ; "b" ; "c" } ] + - location: 18 (remaining gas: 1039981.737 units remaining) + [ False + {} @parameter + { "a" ; "b" ; "c" } ] + - location: 16 (remaining gas: 1039981.722 units remaining) + [ {} @parameter + { "a" ; "b" ; "c" } ] + - location: 33 (remaining gas: 1039981.712 units remaining) + [ { "a" ; "b" ; "c" } ] + - location: 34 (remaining gas: 1039981.697 units remaining) + [ {} + { "a" ; "b" ; "c" } ] + - location: 36 (remaining gas: 1039981.682 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{}-{}].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{}-{}].out" new file mode 100644 index 000000000000..1b3e40264e2f --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{\"\"}-{}-{}].out" @@ -0,0 +1,50 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[reverse_loop.tz-{""}-{}-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039982.564 units remaining) + [ (Pair {} { "" }) ] + - location: 9 (remaining gas: 1039982.554 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039982.539 units remaining) + [ {} + {} @parameter ] + - location: 12 (remaining gas: 1039982.529 units remaining) + [ {} @parameter + {} ] + - location: 13 (remaining gas: 1039982.519 units remaining) + [ True + {} @parameter + {} ] + - location: 16 (remaining gas: 1039982.519 units remaining) + [ {} @parameter + {} ] + - location: 18 (remaining gas: 1039982.509 units remaining) + [ {} ] + - location: 28 (remaining gas: 1039982.494 units remaining) + [ {} + {} ] + - location: 30 (remaining gas: 1039982.484 units remaining) + [ False + {} @parameter + {} ] + - location: 18 (remaining gas: 1039982.469 units remaining) + [ False + {} @parameter + {} ] + - location: 16 (remaining gas: 1039982.454 units remaining) + [ {} @parameter + {} ] + - location: 33 (remaining gas: 1039982.444 units remaining) + [ {} ] + - location: 34 (remaining gas: 1039982.429 units remaining) + [ {} + {} ] + - location: 36 (remaining gas: 1039982.414 units remaining) + [ (Pair {} {}) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0].out new file mode 100644 index 000000000000..b4ab6636d25d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sapling_empty_state.tz-{}-Unit-0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.857 units remaining) + [ (Pair Unit {}) ] + - location: 8 (remaining gas: 1039994.847 units remaining) + [ ] + - location: 9 (remaining gas: 1039994.832 units remaining) + [ {} @sapling ] + - location: 11 (remaining gas: 1039994.817 units remaining) + [ {} + {} @sapling ] + - location: 13 (remaining gas: 1039994.802 units remaining) + [ (Pair {} {}) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit].out new file mode 100644 index 000000000000..7bd609ae2c8b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit].out @@ -0,0 +1,46 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[self_address.tz-Unit-Unit-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039984.339 units remaining) + [ (Pair Unit Unit) ] + - location: 7 (remaining gas: 1039984.329 units remaining) + [ ] + - location: 8 (remaining gas: 1039984.319 units remaining) + [ { DROP ; SELF_ADDRESS } ] + - location: 14 (remaining gas: 1039984.309 units remaining) + [ Unit + { DROP ; SELF_ADDRESS } ] + - location: 12 (remaining gas: 1039984.299 units remaining) + [ ] + - location: 13 (remaining gas: 1039984.284 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] + - location: 15 (remaining gas: 1039984.254 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" ] + - location: 16 (remaining gas: 1039984.239 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self + "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" ] + - location: 17 (remaining gas: 1039984.229 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self.address + "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" ] + - location: 20 (remaining gas: 1039984.193 units remaining) + [ 0 ] + - location: 21 (remaining gas: 1039984.178 units remaining) + [ True ] + - location: 22 (remaining gas: 1039984.168 units remaining) + [ ] + - location: 22 (remaining gas: 1039984.153 units remaining) + [ ] + - location: 28 (remaining gas: 1039984.143 units remaining) + [ Unit ] + - location: 29 (remaining gas: 1039984.128 units remaining) + [ {} + Unit ] + - location: 31 (remaining gas: 1039984.113 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit].out new file mode 100644 index 000000000000..34396ccd66a8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit].out @@ -0,0 +1,47 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[self_with_default_entrypoint.tz-Unit-Unit-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 13 (remaining gas: 1039983.500 units remaining) + [ (Pair (Right (Left Unit)) Unit) ] + - location: 13 (remaining gas: 1039983.490 units remaining) + [ ] + - location: 14 (remaining gas: 1039983.475 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] + - location: 15 (remaining gas: 1039983.465 units remaining) + [ ] + - location: 16 (remaining gas: 1039983.450 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%A" @self ] + - location: 17 (remaining gas: 1039983.440 units remaining) + [ ] + - location: 18 (remaining gas: 1039983.425 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] + - location: 19 (remaining gas: 1039972.472 units remaining) + [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @self.packed ] + - location: 20 (remaining gas: 1039972.457 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self + 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @self.packed ] + - location: 21 (remaining gas: 1039961.504 units remaining) + [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @self.packed + 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @self.packed ] + - location: 24 (remaining gas: 1039961.469 units remaining) + [ 0 ] + - location: 25 (remaining gas: 1039961.454 units remaining) + [ True ] + - location: 26 (remaining gas: 1039961.444 units remaining) + [ ] + - location: 26 (remaining gas: 1039961.429 units remaining) + [ ] + - location: 32 (remaining gas: 1039961.419 units remaining) + [ Unit ] + - location: 33 (remaining gas: 1039961.404 units remaining) + [ {} + Unit ] + - location: 35 (remaining gas: 1039961.389 units remaining) + [ (Pair {} Unit) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit].out new file mode 100644 index 000000000000..c26f56a21d20 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit].out @@ -0,0 +1,93 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[self_with_entrypoint.tz-Unit-Left (Left 0)-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 13 (remaining gas: 1039954.631 units remaining) + [ (Pair (Left (Left 0)) Unit) ] + - location: 13 (remaining gas: 1039954.621 units remaining) + [ ] + - location: 14 (remaining gas: 1039954.606 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%A" @self ] + - location: 15 (remaining gas: 1039943.620 units remaining) + [ 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] + - location: 16 (remaining gas: 1039943.605 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self + 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] + - location: 17 (remaining gas: 1039932.652 units remaining) + [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked + 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] + - location: 18 (remaining gas: 1039932.642 units remaining) + [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked + 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked + 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] + - location: 19 (remaining gas: 1039932.627 units remaining) + [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked + 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked ] + - location: 21 (remaining gas: 1039932.617 units remaining) + [ 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked + 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] + - location: 19 (remaining gas: 1039932.587 units remaining) + [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked + 0x050a00000017011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe60041 @Apacked + 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] + - location: 24 (remaining gas: 1039932.552 units remaining) + [ -1 + 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] + - location: 25 (remaining gas: 1039932.537 units remaining) + [ True + 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] + - location: 26 (remaining gas: 1039932.527 units remaining) + [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] + - location: 26 (remaining gas: 1039932.512 units remaining) + [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] + - location: 32 (remaining gas: 1039932.497 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self + 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] + - location: 33 (remaining gas: 1039921.544 units remaining) + [ 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @selfpacked + 0x050a00000016011d23c1d3d2f8a4ea5e8784b8f7ecf2ad304c0fe600 @defpacked ] + - location: 36 (remaining gas: 1039921.509 units remaining) + [ 0 ] + - location: 37 (remaining gas: 1039921.494 units remaining) + [ True ] + - location: 38 (remaining gas: 1039921.484 units remaining) + [ ] + - location: 38 (remaining gas: 1039921.469 units remaining) + [ ] + - location: 44 (remaining gas: 1039921.454 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%A" @self ] + - location: 48 (remaining gas: 1039921.444 units remaining) + [ ] + - location: 49 (remaining gas: 1039921.429 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%B" @self ] + - location: 53 (remaining gas: 1039921.419 units remaining) + [ ] + - location: 54 (remaining gas: 1039921.404 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%maybe_C" @self ] + - location: 60 (remaining gas: 1039921.394 units remaining) + [ ] + - location: 61 (remaining gas: 1039921.379 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi%Z" @self ] + - location: 65 (remaining gas: 1039921.369 units remaining) + [ ] + - location: 66 (remaining gas: 1039921.354 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] + - location: 76 (remaining gas: 1039921.344 units remaining) + [ ] + - location: 77 (remaining gas: 1039921.329 units remaining) + [ "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi" @self ] + - location: 87 (remaining gas: 1039921.319 units remaining) + [ ] + - location: 88 (remaining gas: 1039921.309 units remaining) + [ Unit ] + - location: 89 (remaining gas: 1039921.294 units remaining) + [ {} + Unit ] + - location: 91 (remaining gas: 1039921.279 units remaining) + [ (Pair {} Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" new file mode 100644 index 000000000000..f67f6179b746 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"\"-(Pair \"\" 0)].out" @@ -0,0 +1,49 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair "hello" 0)-""-(Pair "" 0)] + +storage + (Pair "" 0) +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039987.561 units remaining) + [ (Pair "" "hello" 0) ] + - location: 9 (remaining gas: 1039987.551 units remaining) + [ (Pair "" "hello" 0) + (Pair "" "hello" 0) ] + - location: 10 (remaining gas: 1039987.541 units remaining) + [ (Pair "hello" 0) @storage + (Pair "" "hello" 0) ] + - location: 11 (remaining gas: 1039987.526 units remaining) + [ (Pair "" "hello" 0) ] + - location: 13 (remaining gas: 1039987.516 units remaining) + [ "" @parameter ] + - location: 11 (remaining gas: 1039987.486 units remaining) + [ (Pair "hello" 0) @storage + "" @parameter ] + - location: 15 (remaining gas: 1039987.476 units remaining) + [ (Pair "hello" 0) @storage + (Pair "hello" 0) @storage + "" @parameter ] + - location: 16 (remaining gas: 1039987.466 units remaining) + [ "hello" + (Pair "hello" 0) @storage + "" @parameter ] + - location: 17 (remaining gas: 1039987.456 units remaining) + [ (Pair "hello" 0) @storage + "" @parameter ] + - location: 18 (remaining gas: 1039987.446 units remaining) + [ 0 @storage.n + "" @parameter ] + - location: 19 (remaining gas: 1039987.436 units remaining) + [ "" @parameter + 0 @storage.n ] + - location: 20 (remaining gas: 1039987.421 units remaining) + [ (Pair "" 0) @storage ] + - location: 21 (remaining gas: 1039987.406 units remaining) + [ {} + (Pair "" 0) @storage ] + - location: 23 (remaining gas: 1039987.391 units remaining) + [ (Pair {} "" 0) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" new file mode 100644 index 000000000000..419116f73969 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"abc\"-(Pair \"abc\" 0)].out" @@ -0,0 +1,49 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair "hello" 0)-"abc"-(Pair "abc" 0)] + +storage + (Pair "abc" 0) +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039987.531 units remaining) + [ (Pair "abc" "hello" 0) ] + - location: 9 (remaining gas: 1039987.521 units remaining) + [ (Pair "abc" "hello" 0) + (Pair "abc" "hello" 0) ] + - location: 10 (remaining gas: 1039987.511 units remaining) + [ (Pair "hello" 0) @storage + (Pair "abc" "hello" 0) ] + - location: 11 (remaining gas: 1039987.496 units remaining) + [ (Pair "abc" "hello" 0) ] + - location: 13 (remaining gas: 1039987.486 units remaining) + [ "abc" @parameter ] + - location: 11 (remaining gas: 1039987.456 units remaining) + [ (Pair "hello" 0) @storage + "abc" @parameter ] + - location: 15 (remaining gas: 1039987.446 units remaining) + [ (Pair "hello" 0) @storage + (Pair "hello" 0) @storage + "abc" @parameter ] + - location: 16 (remaining gas: 1039987.436 units remaining) + [ "hello" + (Pair "hello" 0) @storage + "abc" @parameter ] + - location: 17 (remaining gas: 1039987.426 units remaining) + [ (Pair "hello" 0) @storage + "abc" @parameter ] + - location: 18 (remaining gas: 1039987.416 units remaining) + [ 0 @storage.n + "abc" @parameter ] + - location: 19 (remaining gas: 1039987.406 units remaining) + [ "abc" @parameter + 0 @storage.n ] + - location: 20 (remaining gas: 1039987.391 units remaining) + [ (Pair "abc" 0) @storage ] + - location: 21 (remaining gas: 1039987.376 units remaining) + [ {} + (Pair "abc" 0) @storage ] + - location: 23 (remaining gas: 1039987.361 units remaining) + [ (Pair {} "abc" 0) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"world\"-(Pair \"world\" 0)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"world\"-(Pair \"world\" 0)].out" new file mode 100644 index 000000000000..99d16e7db2dd --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair \"hello\" 0)-\"world\"-(Pair \"world\" 0)].out" @@ -0,0 +1,49 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_car.tz-(Pair "hello" 0)-"world"-(Pair "world" 0)] + +storage + (Pair "world" 0) +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039987.511 units remaining) + [ (Pair "world" "hello" 0) ] + - location: 9 (remaining gas: 1039987.501 units remaining) + [ (Pair "world" "hello" 0) + (Pair "world" "hello" 0) ] + - location: 10 (remaining gas: 1039987.491 units remaining) + [ (Pair "hello" 0) @storage + (Pair "world" "hello" 0) ] + - location: 11 (remaining gas: 1039987.476 units remaining) + [ (Pair "world" "hello" 0) ] + - location: 13 (remaining gas: 1039987.466 units remaining) + [ "world" @parameter ] + - location: 11 (remaining gas: 1039987.436 units remaining) + [ (Pair "hello" 0) @storage + "world" @parameter ] + - location: 15 (remaining gas: 1039987.426 units remaining) + [ (Pair "hello" 0) @storage + (Pair "hello" 0) @storage + "world" @parameter ] + - location: 16 (remaining gas: 1039987.416 units remaining) + [ "hello" + (Pair "hello" 0) @storage + "world" @parameter ] + - location: 17 (remaining gas: 1039987.406 units remaining) + [ (Pair "hello" 0) @storage + "world" @parameter ] + - location: 18 (remaining gas: 1039987.396 units remaining) + [ 0 @storage.n + "world" @parameter ] + - location: 19 (remaining gas: 1039987.386 units remaining) + [ "world" @parameter + 0 @storage.n ] + - location: 20 (remaining gas: 1039987.371 units remaining) + [ (Pair "world" 0) @storage ] + - location: 21 (remaining gas: 1039987.356 units remaining) + [ {} + (Pair "world" 0) @storage ] + - location: 23 (remaining gas: 1039987.341 units remaining) + [ (Pair {} "world" 0) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 0)-1-(Pair \"hello\" 1)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 0)-1-(Pair \"hello\" 1)].out" new file mode 100644 index 000000000000..43427018d89d --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 0)-1-(Pair \"hello\" 1)].out" @@ -0,0 +1,46 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair "hello" 0)-1-(Pair "hello" 1)] + +storage + (Pair "hello" 1) +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039988.178 units remaining) + [ (Pair 1 "hello" 0) ] + - location: 9 (remaining gas: 1039988.168 units remaining) + [ (Pair 1 "hello" 0) + (Pair 1 "hello" 0) ] + - location: 10 (remaining gas: 1039988.158 units remaining) + [ (Pair "hello" 0) @storage + (Pair 1 "hello" 0) ] + - location: 11 (remaining gas: 1039988.143 units remaining) + [ (Pair 1 "hello" 0) ] + - location: 13 (remaining gas: 1039988.133 units remaining) + [ 1 @parameter ] + - location: 11 (remaining gas: 1039988.103 units remaining) + [ (Pair "hello" 0) @storage + 1 @parameter ] + - location: 15 (remaining gas: 1039988.093 units remaining) + [ (Pair "hello" 0) @storage + (Pair "hello" 0) @storage + 1 @parameter ] + - location: 16 (remaining gas: 1039988.083 units remaining) + [ 0 + (Pair "hello" 0) @storage + 1 @parameter ] + - location: 17 (remaining gas: 1039988.073 units remaining) + [ (Pair "hello" 0) @storage + 1 @parameter ] + - location: 18 (remaining gas: 1039988.063 units remaining) + [ "hello" @storage.s + 1 @parameter ] + - location: 19 (remaining gas: 1039988.048 units remaining) + [ (Pair "hello" 1) @storage ] + - location: 20 (remaining gas: 1039988.033 units remaining) + [ {} + (Pair "hello" 1) @storage ] + - location: 22 (remaining gas: 1039988.018 units remaining) + [ (Pair {} "hello" 1) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 500)-3-(Pair \"hello\" 3)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 500)-3-(Pair \"hello\" 3)].out" new file mode 100644 index 000000000000..334ac1c28dac --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 500)-3-(Pair \"hello\" 3)].out" @@ -0,0 +1,46 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair "hello" 500)-3-(Pair "hello" 3)] + +storage + (Pair "hello" 3) +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039988.178 units remaining) + [ (Pair 3 "hello" 500) ] + - location: 9 (remaining gas: 1039988.168 units remaining) + [ (Pair 3 "hello" 500) + (Pair 3 "hello" 500) ] + - location: 10 (remaining gas: 1039988.158 units remaining) + [ (Pair "hello" 500) @storage + (Pair 3 "hello" 500) ] + - location: 11 (remaining gas: 1039988.143 units remaining) + [ (Pair 3 "hello" 500) ] + - location: 13 (remaining gas: 1039988.133 units remaining) + [ 3 @parameter ] + - location: 11 (remaining gas: 1039988.103 units remaining) + [ (Pair "hello" 500) @storage + 3 @parameter ] + - location: 15 (remaining gas: 1039988.093 units remaining) + [ (Pair "hello" 500) @storage + (Pair "hello" 500) @storage + 3 @parameter ] + - location: 16 (remaining gas: 1039988.083 units remaining) + [ 500 + (Pair "hello" 500) @storage + 3 @parameter ] + - location: 17 (remaining gas: 1039988.073 units remaining) + [ (Pair "hello" 500) @storage + 3 @parameter ] + - location: 18 (remaining gas: 1039988.063 units remaining) + [ "hello" @storage.s + 3 @parameter ] + - location: 19 (remaining gas: 1039988.048 units remaining) + [ (Pair "hello" 3) @storage ] + - location: 20 (remaining gas: 1039988.033 units remaining) + [ {} + (Pair "hello" 3) @storage ] + - location: 22 (remaining gas: 1039988.018 units remaining) + [ (Pair {} "hello" 3) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 7)-100-(Pair \"hello\" 100)].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 7)-100-(Pair \"hello\" 100)].out" new file mode 100644 index 000000000000..a2fea7a57765 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair \"hello\" 7)-100-(Pair \"hello\" 100)].out" @@ -0,0 +1,46 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_cdr.tz-(Pair "hello" 7)-100-(Pair "hello" 100)] + +storage + (Pair "hello" 100) +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039988.178 units remaining) + [ (Pair 100 "hello" 7) ] + - location: 9 (remaining gas: 1039988.168 units remaining) + [ (Pair 100 "hello" 7) + (Pair 100 "hello" 7) ] + - location: 10 (remaining gas: 1039988.158 units remaining) + [ (Pair "hello" 7) @storage + (Pair 100 "hello" 7) ] + - location: 11 (remaining gas: 1039988.143 units remaining) + [ (Pair 100 "hello" 7) ] + - location: 13 (remaining gas: 1039988.133 units remaining) + [ 100 @parameter ] + - location: 11 (remaining gas: 1039988.103 units remaining) + [ (Pair "hello" 7) @storage + 100 @parameter ] + - location: 15 (remaining gas: 1039988.093 units remaining) + [ (Pair "hello" 7) @storage + (Pair "hello" 7) @storage + 100 @parameter ] + - location: 16 (remaining gas: 1039988.083 units remaining) + [ 7 + (Pair "hello" 7) @storage + 100 @parameter ] + - location: 17 (remaining gas: 1039988.073 units remaining) + [ (Pair "hello" 7) @storage + 100 @parameter ] + - location: 18 (remaining gas: 1039988.063 units remaining) + [ "hello" @storage.s + 100 @parameter ] + - location: 19 (remaining gas: 1039988.048 units remaining) + [ (Pair "hello" 100) @storage ] + - location: 20 (remaining gas: 1039988.033 units remaining) + [ {} + (Pair "hello" 100) @storage ] + - location: 22 (remaining gas: 1039988.018 units remaining) + [ (Pair {} "hello" 100) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" new file mode 100644 index 000000000000..f0dca424f003 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"a\" ; \"b\" ; \"c\" }-{ \"a\" ; \"b\" ; \"c\" }].out" @@ -0,0 +1,19 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ "a" ; "b" ; "c" }-{ "a" ; "b" ; "c" }] + +storage + { "a" ; "b" ; "c" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039993.773 units remaining) + [ (Pair { "a" ; "b" ; "c" } {}) ] + - location: 9 (remaining gas: 1039993.763 units remaining) + [ { "a" ; "b" ; "c" } @parameter ] + - location: 10 (remaining gas: 1039993.748 units remaining) + [ {} + { "a" ; "b" ; "c" } @parameter ] + - location: 12 (remaining gas: 1039993.733 units remaining) + [ (Pair {} { "a" ; "b" ; "c" }) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"asdf\" ; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"asdf\" ; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" new file mode 100644 index 000000000000..c5bc49081234 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ \"asdf\" ; \"bcde\" }-{ \"asdf\" ; \"bcde\" }].out" @@ -0,0 +1,19 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{ "asdf" ; "bcde" }-{ "asdf" ; "bcde" }] + +storage + { "asdf" ; "bcde" } +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039994.212 units remaining) + [ (Pair { "asdf" ; "bcde" } {}) ] + - location: 9 (remaining gas: 1039994.202 units remaining) + [ { "asdf" ; "bcde" } @parameter ] + - location: 10 (remaining gas: 1039994.187 units remaining) + [ {} + { "asdf" ; "bcde" } @parameter ] + - location: 12 (remaining gas: 1039994.172 units remaining) + [ (Pair {} { "asdf" ; "bcde" }) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}].out new file mode 100644 index 000000000000..9cf1d4bc35c8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}].out @@ -0,0 +1,19 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_id.tz-{}-{}-{}] + +storage + {} +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039995.025 units remaining) + [ (Pair {} {}) ] + - location: 9 (remaining gas: 1039995.015 units remaining) + [ {} @parameter ] + - location: 10 (remaining gas: 1039995 units remaining) + [ {} + {} @parameter ] + - location: 12 (remaining gas: 1039994.985 units remaining) + [ (Pair {} {}) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out new file mode 100644 index 000000000000..37b9bba85809 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94].out @@ -0,0 +1,47 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ -100 ; 1 ; 2 ; 3 }--94] + +storage + -94 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039990.518 units remaining) + [ (Pair { -100 ; 1 ; 2 ; 3 } 111) ] + - location: 8 (remaining gas: 1039990.508 units remaining) + [ { -100 ; 1 ; 2 ; 3 } @parameter ] + - location: 9 (remaining gas: 1039990.498 units remaining) + [ 0 + { -100 ; 1 ; 2 ; 3 } @parameter ] + - location: 12 (remaining gas: 1039990.488 units remaining) + [ { -100 ; 1 ; 2 ; 3 } @parameter + 0 ] + - location: 13 (remaining gas: 1039990.488 units remaining) + [ -100 @parameter.elt + 0 ] + - location: 15 (remaining gas: 1039990.433 units remaining) + [ -100 ] + - location: 13 (remaining gas: 1039990.418 units remaining) + [ 1 @parameter.elt + -100 ] + - location: 15 (remaining gas: 1039990.363 units remaining) + [ -99 ] + - location: 13 (remaining gas: 1039990.348 units remaining) + [ 2 @parameter.elt + -99 ] + - location: 15 (remaining gas: 1039990.293 units remaining) + [ -97 ] + - location: 13 (remaining gas: 1039990.278 units remaining) + [ 3 @parameter.elt + -97 ] + - location: 15 (remaining gas: 1039990.223 units remaining) + [ -94 ] + - location: 13 (remaining gas: 1039990.208 units remaining) + [ -94 ] + - location: 16 (remaining gas: 1039990.193 units remaining) + [ {} + -94 ] + - location: 18 (remaining gas: 1039990.178 units remaining) + [ (Pair {} -94) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1].out new file mode 100644 index 000000000000..0c16b0d15cee --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{ 1 }-1] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039991.873 units remaining) + [ (Pair { 1 } 111) ] + - location: 8 (remaining gas: 1039991.863 units remaining) + [ { 1 } @parameter ] + - location: 9 (remaining gas: 1039991.853 units remaining) + [ 0 + { 1 } @parameter ] + - location: 12 (remaining gas: 1039991.843 units remaining) + [ { 1 } @parameter + 0 ] + - location: 13 (remaining gas: 1039991.843 units remaining) + [ 1 @parameter.elt + 0 ] + - location: 15 (remaining gas: 1039991.788 units remaining) + [ 1 ] + - location: 13 (remaining gas: 1039991.773 units remaining) + [ 1 ] + - location: 16 (remaining gas: 1039991.758 units remaining) + [ {} + 1 ] + - location: 18 (remaining gas: 1039991.743 units remaining) + [ (Pair {} 1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0].out new file mode 100644 index 000000000000..46e022d0202f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0].out @@ -0,0 +1,27 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_iter.tz-111-{}-0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039992.173 units remaining) + [ (Pair {} 111) ] + - location: 8 (remaining gas: 1039992.163 units remaining) + [ {} @parameter ] + - location: 9 (remaining gas: 1039992.153 units remaining) + [ 0 + {} @parameter ] + - location: 12 (remaining gas: 1039992.143 units remaining) + [ {} @parameter + 0 ] + - location: 13 (remaining gas: 1039992.143 units remaining) + [ 0 ] + - location: 16 (remaining gas: 1039992.128 units remaining) + [ {} + 0 ] + - location: 18 (remaining gas: 1039992.113 units remaining) + [ (Pair {} 0) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hello\" ; \"World\" } None)-\"\"-(Pai.3d2044726e.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hello\" ; \"World\" } None)-\"\"-(Pai.3d2044726e.out" new file mode 100644 index 000000000000..c9b68333b65c --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hello\" ; \"World\" } None)-\"\"-(Pai.3d2044726e.out" @@ -0,0 +1,61 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { "Hello" ; "World" } None)-""-(Pair { "Hello" ; "World" } (Some False))] + +storage + (Pair { "Hello" ; "World" } (Some False)) +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039983.293 units remaining) + [ (Pair "" { "Hello" ; "World" } None) ] + - location: 11 (remaining gas: 1039983.283 units remaining) + [ (Pair "" { "Hello" ; "World" } None) + (Pair "" { "Hello" ; "World" } None) ] + - location: 12 (remaining gas: 1039983.273 units remaining) + [ (Pair "" { "Hello" ; "World" } None) + (Pair "" { "Hello" ; "World" } None) + (Pair "" { "Hello" ; "World" } None) ] + - location: 13 (remaining gas: 1039983.263 units remaining) + [ "" @parameter + (Pair "" { "Hello" ; "World" } None) + (Pair "" { "Hello" ; "World" } None) ] + - location: 14 (remaining gas: 1039983.248 units remaining) + [ (Pair "" { "Hello" ; "World" } None) + (Pair "" { "Hello" ; "World" } None) ] + - location: 17 (remaining gas: 1039983.238 units remaining) + [ (Pair { "Hello" ; "World" } None) @storage + (Pair "" { "Hello" ; "World" } None) ] + - location: 18 (remaining gas: 1039983.228 units remaining) + [ { "Hello" ; "World" } + (Pair "" { "Hello" ; "World" } None) ] + - location: 14 (remaining gas: 1039983.198 units remaining) + [ "" @parameter + { "Hello" ; "World" } + (Pair "" { "Hello" ; "World" } None) ] + - location: 19 (remaining gas: 1039982.978 units remaining) + [ False + (Pair "" { "Hello" ; "World" } None) ] + - location: 20 (remaining gas: 1039982.963 units remaining) + [ (Some False) + (Pair "" { "Hello" ; "World" } None) ] + - location: 21 (remaining gas: 1039982.948 units remaining) + [ (Pair "" { "Hello" ; "World" } None) ] + - location: 24 (remaining gas: 1039982.938 units remaining) + [ (Pair { "Hello" ; "World" } None) @storage ] + - location: 25 (remaining gas: 1039982.928 units remaining) + [ { "Hello" ; "World" } ] + - location: 21 (remaining gas: 1039982.898 units remaining) + [ (Some False) + { "Hello" ; "World" } ] + - location: 26 (remaining gas: 1039982.888 units remaining) + [ { "Hello" ; "World" } + (Some False) ] + - location: 27 (remaining gas: 1039982.873 units remaining) + [ (Pair { "Hello" ; "World" } (Some False)) ] + - location: 28 (remaining gas: 1039982.858 units remaining) + [ {} + (Pair { "Hello" ; "World" } (Some False)) ] + - location: 30 (remaining gas: 1039982.843 units remaining) + [ (Pair {} { "Hello" ; "World" } (Some False)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hi\" } None)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hi\" } None)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" new file mode 100644 index 000000000000..f422fe657467 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { \"Hi\" } None)-\"Hi\"-(Pair { \"Hi\" } .564beb9251.out" @@ -0,0 +1,61 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair { "Hi" } None)-"Hi"-(Pair { "Hi" } (Some True))] + +storage + (Pair { "Hi" } (Some True)) +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039983.772 units remaining) + [ (Pair "Hi" { "Hi" } None) ] + - location: 11 (remaining gas: 1039983.762 units remaining) + [ (Pair "Hi" { "Hi" } None) + (Pair "Hi" { "Hi" } None) ] + - location: 12 (remaining gas: 1039983.752 units remaining) + [ (Pair "Hi" { "Hi" } None) + (Pair "Hi" { "Hi" } None) + (Pair "Hi" { "Hi" } None) ] + - location: 13 (remaining gas: 1039983.742 units remaining) + [ "Hi" @parameter + (Pair "Hi" { "Hi" } None) + (Pair "Hi" { "Hi" } None) ] + - location: 14 (remaining gas: 1039983.727 units remaining) + [ (Pair "Hi" { "Hi" } None) + (Pair "Hi" { "Hi" } None) ] + - location: 17 (remaining gas: 1039983.717 units remaining) + [ (Pair { "Hi" } None) @storage + (Pair "Hi" { "Hi" } None) ] + - location: 18 (remaining gas: 1039983.707 units remaining) + [ { "Hi" } + (Pair "Hi" { "Hi" } None) ] + - location: 14 (remaining gas: 1039983.677 units remaining) + [ "Hi" @parameter + { "Hi" } + (Pair "Hi" { "Hi" } None) ] + - location: 19 (remaining gas: 1039983.492 units remaining) + [ True + (Pair "Hi" { "Hi" } None) ] + - location: 20 (remaining gas: 1039983.477 units remaining) + [ (Some True) + (Pair "Hi" { "Hi" } None) ] + - location: 21 (remaining gas: 1039983.462 units remaining) + [ (Pair "Hi" { "Hi" } None) ] + - location: 24 (remaining gas: 1039983.452 units remaining) + [ (Pair { "Hi" } None) @storage ] + - location: 25 (remaining gas: 1039983.442 units remaining) + [ { "Hi" } ] + - location: 21 (remaining gas: 1039983.412 units remaining) + [ (Some True) + { "Hi" } ] + - location: 26 (remaining gas: 1039983.402 units remaining) + [ { "Hi" } + (Some True) ] + - location: 27 (remaining gas: 1039983.387 units remaining) + [ (Pair { "Hi" } (Some True)) ] + - location: 28 (remaining gas: 1039983.372 units remaining) + [ {} + (Pair { "Hi" } (Some True)) ] + - location: 30 (remaining gas: 1039983.357 units remaining) + [ (Pair {} { "Hi" } (Some True)) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-\"Hi\"-(Pair {} (Some False))].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-\"Hi\"-(Pair {} (Some False))].out" new file mode 100644 index 000000000000..8e3eb8792a57 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-\"Hi\"-(Pair {} (Some False))].out" @@ -0,0 +1,61 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_member.tz-(Pair {} None)-"Hi"-(Pair {} (Some False))] + +storage + (Pair {} (Some False)) +emitted operations + +big_map diff + +trace + - location: 11 (remaining gas: 1039984.106 units remaining) + [ (Pair "Hi" {} None) ] + - location: 11 (remaining gas: 1039984.096 units remaining) + [ (Pair "Hi" {} None) + (Pair "Hi" {} None) ] + - location: 12 (remaining gas: 1039984.086 units remaining) + [ (Pair "Hi" {} None) + (Pair "Hi" {} None) + (Pair "Hi" {} None) ] + - location: 13 (remaining gas: 1039984.076 units remaining) + [ "Hi" @parameter + (Pair "Hi" {} None) + (Pair "Hi" {} None) ] + - location: 14 (remaining gas: 1039984.061 units remaining) + [ (Pair "Hi" {} None) + (Pair "Hi" {} None) ] + - location: 17 (remaining gas: 1039984.051 units remaining) + [ (Pair {} None) @storage + (Pair "Hi" {} None) ] + - location: 18 (remaining gas: 1039984.041 units remaining) + [ {} + (Pair "Hi" {} None) ] + - location: 14 (remaining gas: 1039984.011 units remaining) + [ "Hi" @parameter + {} + (Pair "Hi" {} None) ] + - location: 19 (remaining gas: 1039983.861 units remaining) + [ False + (Pair "Hi" {} None) ] + - location: 20 (remaining gas: 1039983.846 units remaining) + [ (Some False) + (Pair "Hi" {} None) ] + - location: 21 (remaining gas: 1039983.831 units remaining) + [ (Pair "Hi" {} None) ] + - location: 24 (remaining gas: 1039983.821 units remaining) + [ (Pair {} None) @storage ] + - location: 25 (remaining gas: 1039983.811 units remaining) + [ {} ] + - location: 21 (remaining gas: 1039983.781 units remaining) + [ (Some False) + {} ] + - location: 26 (remaining gas: 1039983.771 units remaining) + [ {} + (Some False) ] + - location: 27 (remaining gas: 1039983.756 units remaining) + [ (Pair {} (Some False)) ] + - location: 28 (remaining gas: 1039983.741 units remaining) + [ {} + (Pair {} (Some False)) ] + - location: 30 (remaining gas: 1039983.726 units remaining) + [ (Pair {} {} (Some False)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out new file mode 100644 index 000000000000..e7a62b39c4f1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }-6] + +storage + 6 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039992.075 units remaining) + [ (Pair { 1 ; 2 ; 3 ; 4 ; 5 ; 6 } 111) ] + - location: 8 (remaining gas: 1039992.065 units remaining) + [ { 1 ; 2 ; 3 ; 4 ; 5 ; 6 } @parameter ] + - location: 9 (remaining gas: 1039992.050 units remaining) + [ 6 ] + - location: 10 (remaining gas: 1039992.035 units remaining) + [ {} + 6 ] + - location: 12 (remaining gas: 1039992.020 units remaining) + [ (Pair {} 6) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out new file mode 100644 index 000000000000..c9e499b3996a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 ; 2 ; 3 }-3] + +storage + 3 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.640 units remaining) + [ (Pair { 1 ; 2 ; 3 } 111) ] + - location: 8 (remaining gas: 1039993.630 units remaining) + [ { 1 ; 2 ; 3 } @parameter ] + - location: 9 (remaining gas: 1039993.615 units remaining) + [ 3 ] + - location: 10 (remaining gas: 1039993.600 units remaining) + [ {} + 3 ] + - location: 12 (remaining gas: 1039993.585 units remaining) + [ (Pair {} 3) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1].out new file mode 100644 index 000000000000..dbc893156115 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_size.tz-111-{ 1 }-1] + +storage + 1 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.520 units remaining) + [ (Pair { 1 } 111) ] + - location: 8 (remaining gas: 1039994.510 units remaining) + [ { 1 } @parameter ] + - location: 9 (remaining gas: 1039994.495 units remaining) + [ 1 ] + - location: 10 (remaining gas: 1039994.480 units remaining) + [ {} + 1 ] + - location: 12 (remaining gas: 1039994.465 units remaining) + [ (Pair {} 1) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0].out new file mode 100644 index 000000000000..4407ad4c6053 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0].out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[set_size.tz-111-{}-0] + +storage + 0 +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.820 units remaining) + [ (Pair {} 111) ] + - location: 8 (remaining gas: 1039994.810 units remaining) + [ {} @parameter ] + - location: 9 (remaining gas: 1039994.795 units remaining) + [ 0 ] + - location: 10 (remaining gas: 1039994.780 units remaining) + [ {} + 0 ] + - location: 12 (remaining gas: 1039994.765 units remaining) + [ (Pair {} 0) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a.a07ae9dddf.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a.a07ae9dddf.out new file mode 100644 index 000000000000..b363ff7ea1fb --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a.a07ae9dddf.out @@ -0,0 +1,24 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sha3.tz-None-0x48656c6c6f2c20776f726c6421-(Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722)] + +storage + (Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722) +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039993.957 units remaining) + [ (Pair 0x48656c6c6f2c20776f726c6421 None) ] + - location: 8 (remaining gas: 1039993.947 units remaining) + [ 0x48656c6c6f2c20776f726c6421 @parameter ] + - location: 9 (remaining gas: 1039992.490 units remaining) + [ 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722 ] + - location: 10 (remaining gas: 1039992.475 units remaining) + [ (Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722) ] + - location: 11 (remaining gas: 1039992.460 units remaining) + [ {} + (Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722) ] + - location: 13 (remaining gas: 1039992.445 units remaining) + [ (Pair {} + (Some 0xf345a219da005ebe9c1a1eaad97bbf38a10c8473e41d0af7fb617caa0c6aa722)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)].out new file mode 100644 index 000000000000..319389b31832 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 0))-(Some 0)] + +storage + (Some 0) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Left (Pair 0 0)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Left (Pair 0 0)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 0 0) @parameter.left ] + - location: 17 (remaining gas: 1039989.674 units remaining) + [ 0 + 0 ] + - location: 18 (remaining gas: 1039989.674 units remaining) + [ 0 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 0 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 0) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 0) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 0)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)].out new file mode 100644 index 000000000000..4ca9302454b3 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 0 1))-(Some 0)] + +storage + (Some 0) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Left (Pair 0 1)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Left (Pair 0 1)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 0 1) @parameter.left ] + - location: 17 (remaining gas: 1039989.674 units remaining) + [ 0 + 1 ] + - location: 18 (remaining gas: 1039989.674 units remaining) + [ 0 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 0 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 0) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 0) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 0)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)].out new file mode 100644 index 000000000000..9767e95878bc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 1 2))-(Some 4)] + +storage + (Some 4) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Left (Pair 1 2)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Left (Pair 1 2)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 1 2) @parameter.left ] + - location: 17 (remaining gas: 1039989.674 units remaining) + [ 1 + 2 ] + - location: 18 (remaining gas: 1039989.674 units remaining) + [ 4 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 4 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 4) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 4) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 4)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)].out new file mode 100644 index 000000000000..d4515ea764d5 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 15 2))-(Some 60)] + +storage + (Some 60) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Left (Pair 15 2)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Left (Pair 15 2)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 15 2) @parameter.left ] + - location: 17 (remaining gas: 1039989.674 units remaining) + [ 15 + 2 ] + - location: 18 (remaining gas: 1039989.674 units remaining) + [ 60 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 60 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 60) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 60) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 60)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)].out new file mode 100644 index 000000000000..7438e9021817 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Left (Pair 8 1))-(Some 16)] + +storage + (Some 16) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Left (Pair 8 1)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Left (Pair 8 1)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 8 1) @parameter.left ] + - location: 17 (remaining gas: 1039989.674 units remaining) + [ 8 + 1 ] + - location: 18 (remaining gas: 1039989.674 units remaining) + [ 16 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 16 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 16) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 16) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 16)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)].out new file mode 100644 index 000000000000..3a1126488924 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 0))-(Some 0)] + +storage + (Some 0) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Right (Pair 0 0)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Right (Pair 0 0)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 0 0) @parameter.right ] + - location: 20 (remaining gas: 1039989.674 units remaining) + [ 0 + 0 ] + - location: 21 (remaining gas: 1039989.674 units remaining) + [ 0 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 0 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 0) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 0) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 0)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)].out new file mode 100644 index 000000000000..426c4a4750b8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 0 1))-(Some 0)] + +storage + (Some 0) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Right (Pair 0 1)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Right (Pair 0 1)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 0 1) @parameter.right ] + - location: 20 (remaining gas: 1039989.674 units remaining) + [ 0 + 1 ] + - location: 21 (remaining gas: 1039989.674 units remaining) + [ 0 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 0 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 0) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 0) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 0)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)].out new file mode 100644 index 000000000000..3415da0027cd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 1 2))-(Some 0)] + +storage + (Some 0) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Right (Pair 1 2)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Right (Pair 1 2)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 1 2) @parameter.right ] + - location: 20 (remaining gas: 1039989.674 units remaining) + [ 1 + 2 ] + - location: 21 (remaining gas: 1039989.674 units remaining) + [ 0 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 0 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 0) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 0) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 0)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)].out new file mode 100644 index 000000000000..34ee09106209 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 15 2))-(Some 3)] + +storage + (Some 3) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Right (Pair 15 2)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Right (Pair 15 2)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 15 2) @parameter.right ] + - location: 20 (remaining gas: 1039989.674 units remaining) + [ 15 + 2 ] + - location: 21 (remaining gas: 1039989.674 units remaining) + [ 3 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 3 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 3) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 3) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 3)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)].out new file mode 100644 index 000000000000..a81434d99414 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)].out @@ -0,0 +1,30 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[shifts.tz-None-(Right (Pair 8 1))-(Some 4)] + +storage + (Some 4) +emitted operations + +big_map diff + +trace + - location: 14 (remaining gas: 1039989.704 units remaining) + [ (Pair (Right (Pair 8 1)) None) ] + - location: 14 (remaining gas: 1039989.694 units remaining) + [ (Right (Pair 8 1)) @parameter ] + - location: 15 (remaining gas: 1039989.684 units remaining) + [ (Pair 8 1) @parameter.right ] + - location: 20 (remaining gas: 1039989.674 units remaining) + [ 8 + 1 ] + - location: 21 (remaining gas: 1039989.674 units remaining) + [ 4 ] + - location: 15 (remaining gas: 1039989.659 units remaining) + [ 4 ] + - location: 22 (remaining gas: 1039989.644 units remaining) + [ (Some 4) ] + - location: 23 (remaining gas: 1039989.629 units remaining) + [ {} + (Some 4) ] + - location: 25 (remaining gas: 1039989.614 units remaining) + [ (Pair {} (Some 4)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None].out new file mode 100644 index 000000000000..be74e3e6af86 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None].out @@ -0,0 +1,31 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-None-Pair 0 0-None] + +storage + None +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039989.042 units remaining) + [ (Pair (Pair 0 0) None) ] + - location: 10 (remaining gas: 1039989.032 units remaining) + [ (Pair 0 0) @parameter + None @storage ] + - location: 11 (remaining gas: 1039989.022 units remaining) + [ None @storage + (Pair 0 0) @parameter ] + - location: 13 (remaining gas: 1039989.012 units remaining) + [ (Pair 0 0) @parameter ] + - location: 15 (remaining gas: 1039989.002 units remaining) + [ ] + - location: 16 (remaining gas: 1039988.987 units remaining) + [ None ] + - location: 13 (remaining gas: 1039988.972 units remaining) + [ None ] + - location: 22 (remaining gas: 1039988.957 units remaining) + [ {} + None ] + - location: 24 (remaining gas: 1039988.942 units remaining) + [ (Pair {} None) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" new file mode 100644 index 000000000000..635d3d4a9cf0 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 0-(Some \"\")].out" @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 0 0-(Some "")] + +storage + (Some "") +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.898 units remaining) + [ (Pair (Pair 0 0) (Some "Foo")) ] + - location: 10 (remaining gas: 1039988.888 units remaining) + [ (Pair 0 0) @parameter + (Some "Foo") @storage ] + - location: 11 (remaining gas: 1039988.878 units remaining) + [ (Some "Foo") @storage + (Pair 0 0) @parameter ] + - location: 13 (remaining gas: 1039988.868 units remaining) + [ "Foo" @storage.some + (Pair 0 0) @parameter ] + - location: 19 (remaining gas: 1039988.858 units remaining) + [ (Pair 0 0) @parameter + "Foo" @storage.some ] + - location: 20 (remaining gas: 1039988.848 units remaining) + [ 0 + 0 + "Foo" @storage.some ] + - location: 21 (remaining gas: 1039988.808 units remaining) + [ (Some "") ] + - location: 13 (remaining gas: 1039988.793 units remaining) + [ (Some "") ] + - location: 22 (remaining gas: 1039988.778 units remaining) + [ {} + (Some "") ] + - location: 24 (remaining gas: 1039988.763 units remaining) + [ (Pair {} (Some "")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 10-None].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 10-None].out" new file mode 100644 index 000000000000..05ac55895964 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 10-None].out" @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 0 10-None] + +storage + None +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.898 units remaining) + [ (Pair (Pair 0 10) (Some "Foo")) ] + - location: 10 (remaining gas: 1039988.888 units remaining) + [ (Pair 0 10) @parameter + (Some "Foo") @storage ] + - location: 11 (remaining gas: 1039988.878 units remaining) + [ (Some "Foo") @storage + (Pair 0 10) @parameter ] + - location: 13 (remaining gas: 1039988.868 units remaining) + [ "Foo" @storage.some + (Pair 0 10) @parameter ] + - location: 19 (remaining gas: 1039988.858 units remaining) + [ (Pair 0 10) @parameter + "Foo" @storage.some ] + - location: 20 (remaining gas: 1039988.848 units remaining) + [ 0 + 10 + "Foo" @storage.some ] + - location: 21 (remaining gas: 1039988.808 units remaining) + [ None ] + - location: 13 (remaining gas: 1039988.793 units remaining) + [ None ] + - location: 22 (remaining gas: 1039988.778 units remaining) + [ {} + None ] + - location: 24 (remaining gas: 1039988.763 units remaining) + [ (Pair {} None) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" new file mode 100644 index 000000000000..9fa8b466a588 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 0 2-(Some \"Fo\")].out" @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 0 2-(Some "Fo")] + +storage + (Some "Fo") +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.898 units remaining) + [ (Pair (Pair 0 2) (Some "Foo")) ] + - location: 10 (remaining gas: 1039988.888 units remaining) + [ (Pair 0 2) @parameter + (Some "Foo") @storage ] + - location: 11 (remaining gas: 1039988.878 units remaining) + [ (Some "Foo") @storage + (Pair 0 2) @parameter ] + - location: 13 (remaining gas: 1039988.868 units remaining) + [ "Foo" @storage.some + (Pair 0 2) @parameter ] + - location: 19 (remaining gas: 1039988.858 units remaining) + [ (Pair 0 2) @parameter + "Foo" @storage.some ] + - location: 20 (remaining gas: 1039988.848 units remaining) + [ 0 + 2 + "Foo" @storage.some ] + - location: 21 (remaining gas: 1039988.808 units remaining) + [ (Some "Fo") ] + - location: 13 (remaining gas: 1039988.793 units remaining) + [ (Some "Fo") ] + - location: 22 (remaining gas: 1039988.778 units remaining) + [ {} + (Some "Fo") ] + - location: 24 (remaining gas: 1039988.763 units remaining) + [ (Pair {} (Some "Fo")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" new file mode 100644 index 000000000000..57ce8c271fad --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 1-(Some \"o\")].out" @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 1 1-(Some "o")] + +storage + (Some "o") +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.898 units remaining) + [ (Pair (Pair 1 1) (Some "Foo")) ] + - location: 10 (remaining gas: 1039988.888 units remaining) + [ (Pair 1 1) @parameter + (Some "Foo") @storage ] + - location: 11 (remaining gas: 1039988.878 units remaining) + [ (Some "Foo") @storage + (Pair 1 1) @parameter ] + - location: 13 (remaining gas: 1039988.868 units remaining) + [ "Foo" @storage.some + (Pair 1 1) @parameter ] + - location: 19 (remaining gas: 1039988.858 units remaining) + [ (Pair 1 1) @parameter + "Foo" @storage.some ] + - location: 20 (remaining gas: 1039988.848 units remaining) + [ 1 + 1 + "Foo" @storage.some ] + - location: 21 (remaining gas: 1039988.808 units remaining) + [ (Some "o") ] + - location: 13 (remaining gas: 1039988.793 units remaining) + [ (Some "o") ] + - location: 22 (remaining gas: 1039988.778 units remaining) + [ {} + (Some "o") ] + - location: 24 (remaining gas: 1039988.763 units remaining) + [ (Pair {} (Some "o")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 3-None].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 3-None].out" new file mode 100644 index 000000000000..533cc770e1c2 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 1 3-None].out" @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 1 3-None] + +storage + None +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.898 units remaining) + [ (Pair (Pair 1 3) (Some "Foo")) ] + - location: 10 (remaining gas: 1039988.888 units remaining) + [ (Pair 1 3) @parameter + (Some "Foo") @storage ] + - location: 11 (remaining gas: 1039988.878 units remaining) + [ (Some "Foo") @storage + (Pair 1 3) @parameter ] + - location: 13 (remaining gas: 1039988.868 units remaining) + [ "Foo" @storage.some + (Pair 1 3) @parameter ] + - location: 19 (remaining gas: 1039988.858 units remaining) + [ (Pair 1 3) @parameter + "Foo" @storage.some ] + - location: 20 (remaining gas: 1039988.848 units remaining) + [ 1 + 3 + "Foo" @storage.some ] + - location: 21 (remaining gas: 1039988.808 units remaining) + [ None ] + - location: 13 (remaining gas: 1039988.793 units remaining) + [ None ] + - location: 22 (remaining gas: 1039988.778 units remaining) + [ {} + None ] + - location: 24 (remaining gas: 1039988.763 units remaining) + [ (Pair {} None) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 10 5-None].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 10 5-None].out" new file mode 100644 index 000000000000..4c16587872d3 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some \"Foo\"-Pair 10 5-None].out" @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some "Foo"-Pair 10 5-None] + +storage + None +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.898 units remaining) + [ (Pair (Pair 10 5) (Some "Foo")) ] + - location: 10 (remaining gas: 1039988.888 units remaining) + [ (Pair 10 5) @parameter + (Some "Foo") @storage ] + - location: 11 (remaining gas: 1039988.878 units remaining) + [ (Some "Foo") @storage + (Pair 10 5) @parameter ] + - location: 13 (remaining gas: 1039988.868 units remaining) + [ "Foo" @storage.some + (Pair 10 5) @parameter ] + - location: 19 (remaining gas: 1039988.858 units remaining) + [ (Pair 10 5) @parameter + "Foo" @storage.some ] + - location: 20 (remaining gas: 1039988.848 units remaining) + [ 10 + 5 + "Foo" @storage.some ] + - location: 21 (remaining gas: 1039988.808 units remaining) + [ None ] + - location: 13 (remaining gas: 1039988.793 units remaining) + [ None ] + - location: 22 (remaining gas: 1039988.778 units remaining) + [ {} + None ] + - location: 24 (remaining gas: 1039988.763 units remaining) + [ (Pair {} None) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some\"FooFooFooFooFooFooFooFooFooFooFooFooFooFo.c508d67bb0.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some\"FooFooFooFooFooFooFooFooFooFooFooFooFooFo.c508d67bb0.out" new file mode 100644 index 000000000000..5d14300881f4 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice.tz-Some\"FooFooFooFooFooFooFooFooFooFooFooFooFooFo.c508d67bb0.out" @@ -0,0 +1,38 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice.tz-Some"FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo"-Pair 1 10000-None] + +storage + None +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039928.928 units remaining) + [ (Pair (Pair 1 10000) + (Some "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo")) ] + - location: 10 (remaining gas: 1039928.918 units remaining) + [ (Pair 1 10000) @parameter + (Some "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo") @storage ] + - location: 11 (remaining gas: 1039928.908 units remaining) + [ (Some "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo") @storage + (Pair 1 10000) @parameter ] + - location: 13 (remaining gas: 1039928.898 units remaining) + [ "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo" @storage.some + (Pair 1 10000) @parameter ] + - location: 19 (remaining gas: 1039928.888 units remaining) + [ (Pair 1 10000) @parameter + "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo" @storage.some ] + - location: 20 (remaining gas: 1039928.878 units remaining) + [ 1 + 10000 + "FooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFooFoo" @storage.some ] + - location: 21 (remaining gas: 1039928.463 units remaining) + [ None ] + - location: 13 (remaining gas: 1039928.448 units remaining) + [ None ] + - location: 22 (remaining gas: 1039928.433 units remaining) + [ {} + None ] + - location: 24 (remaining gas: 1039928.418 units remaining) + [ (Pair {} None) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None].out new file mode 100644 index 000000000000..056809f94e7f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None].out @@ -0,0 +1,31 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-None-Pair 0 1-None] + +storage + None +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039989.042 units remaining) + [ (Pair (Pair 0 1) None) ] + - location: 10 (remaining gas: 1039989.032 units remaining) + [ (Pair 0 1) @parameter + None @storage ] + - location: 11 (remaining gas: 1039989.022 units remaining) + [ None @storage + (Pair 0 1) @parameter ] + - location: 13 (remaining gas: 1039989.012 units remaining) + [ (Pair 0 1) @parameter ] + - location: 15 (remaining gas: 1039989.002 units remaining) + [ ] + - location: 16 (remaining gas: 1039988.987 units remaining) + [ None ] + - location: 13 (remaining gas: 1039988.972 units remaining) + [ None ] + - location: 22 (remaining gas: 1039988.957 units remaining) + [ {} + None ] + - location: 24 (remaining gas: 1039988.942 units remaining) + [ (Pair {} None) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out new file mode 100644 index 000000000000..ace4c5ffd265 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)].out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 0-(Some 0x)] + +storage + (Some 0x) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.942 units remaining) + [ (Pair (Pair 0 0) (Some 0xaabbcc)) ] + - location: 10 (remaining gas: 1039988.932 units remaining) + [ (Pair 0 0) @parameter + (Some 0xaabbcc) @storage ] + - location: 11 (remaining gas: 1039988.922 units remaining) + [ (Some 0xaabbcc) @storage + (Pair 0 0) @parameter ] + - location: 13 (remaining gas: 1039988.912 units remaining) + [ 0xaabbcc @storage.some + (Pair 0 0) @parameter ] + - location: 19 (remaining gas: 1039988.902 units remaining) + [ (Pair 0 0) @parameter + 0xaabbcc @storage.some ] + - location: 20 (remaining gas: 1039988.892 units remaining) + [ 0 + 0 + 0xaabbcc @storage.some ] + - location: 21 (remaining gas: 1039988.852 units remaining) + [ (Some 0x) ] + - location: 13 (remaining gas: 1039988.837 units remaining) + [ (Some 0x) ] + - location: 22 (remaining gas: 1039988.822 units remaining) + [ {} + (Some 0x) ] + - location: 24 (remaining gas: 1039988.807 units remaining) + [ (Pair {} (Some 0x)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out new file mode 100644 index 000000000000..5bd41372be37 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)].out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 0 1-(Some 0xaa)] + +storage + (Some 0xaa) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.942 units remaining) + [ (Pair (Pair 0 1) (Some 0xaabbcc)) ] + - location: 10 (remaining gas: 1039988.932 units remaining) + [ (Pair 0 1) @parameter + (Some 0xaabbcc) @storage ] + - location: 11 (remaining gas: 1039988.922 units remaining) + [ (Some 0xaabbcc) @storage + (Pair 0 1) @parameter ] + - location: 13 (remaining gas: 1039988.912 units remaining) + [ 0xaabbcc @storage.some + (Pair 0 1) @parameter ] + - location: 19 (remaining gas: 1039988.902 units remaining) + [ (Pair 0 1) @parameter + 0xaabbcc @storage.some ] + - location: 20 (remaining gas: 1039988.892 units remaining) + [ 0 + 1 + 0xaabbcc @storage.some ] + - location: 21 (remaining gas: 1039988.852 units remaining) + [ (Some 0xaa) ] + - location: 13 (remaining gas: 1039988.837 units remaining) + [ (Some 0xaa) ] + - location: 22 (remaining gas: 1039988.822 units remaining) + [ {} + (Some 0xaa) ] + - location: 24 (remaining gas: 1039988.807 units remaining) + [ (Pair {} (Some 0xaa)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out new file mode 100644 index 000000000000..bdc0aadfb384 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0].out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)0] + +storage + (Some 0xbb) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.942 units remaining) + [ (Pair (Pair 1 1) (Some 0xaabbcc)) ] + - location: 10 (remaining gas: 1039988.932 units remaining) + [ (Pair 1 1) @parameter + (Some 0xaabbcc) @storage ] + - location: 11 (remaining gas: 1039988.922 units remaining) + [ (Some 0xaabbcc) @storage + (Pair 1 1) @parameter ] + - location: 13 (remaining gas: 1039988.912 units remaining) + [ 0xaabbcc @storage.some + (Pair 1 1) @parameter ] + - location: 19 (remaining gas: 1039988.902 units remaining) + [ (Pair 1 1) @parameter + 0xaabbcc @storage.some ] + - location: 20 (remaining gas: 1039988.892 units remaining) + [ 1 + 1 + 0xaabbcc @storage.some ] + - location: 21 (remaining gas: 1039988.852 units remaining) + [ (Some 0xbb) ] + - location: 13 (remaining gas: 1039988.837 units remaining) + [ (Some 0xbb) ] + - location: 22 (remaining gas: 1039988.822 units remaining) + [ {} + (Some 0xbb) ] + - location: 24 (remaining gas: 1039988.807 units remaining) + [ (Pair {} (Some 0xbb)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out new file mode 100644 index 000000000000..9039624247d1 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1].out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 1-(Some 0xbb)1] + +storage + (Some 0xbb) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.942 units remaining) + [ (Pair (Pair 1 1) (Some 0xaabbcc)) ] + - location: 10 (remaining gas: 1039988.932 units remaining) + [ (Pair 1 1) @parameter + (Some 0xaabbcc) @storage ] + - location: 11 (remaining gas: 1039988.922 units remaining) + [ (Some 0xaabbcc) @storage + (Pair 1 1) @parameter ] + - location: 13 (remaining gas: 1039988.912 units remaining) + [ 0xaabbcc @storage.some + (Pair 1 1) @parameter ] + - location: 19 (remaining gas: 1039988.902 units remaining) + [ (Pair 1 1) @parameter + 0xaabbcc @storage.some ] + - location: 20 (remaining gas: 1039988.892 units remaining) + [ 1 + 1 + 0xaabbcc @storage.some ] + - location: 21 (remaining gas: 1039988.852 units remaining) + [ (Some 0xbb) ] + - location: 13 (remaining gas: 1039988.837 units remaining) + [ (Some 0xbb) ] + - location: 22 (remaining gas: 1039988.822 units remaining) + [ {} + (Some 0xbb) ] + - location: 24 (remaining gas: 1039988.807 units remaining) + [ (Pair {} (Some 0xbb)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out new file mode 100644 index 000000000000..fcc33f223012 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)].out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 2-(Some 0xbbcc)] + +storage + (Some 0xbbcc) +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.942 units remaining) + [ (Pair (Pair 1 2) (Some 0xaabbcc)) ] + - location: 10 (remaining gas: 1039988.932 units remaining) + [ (Pair 1 2) @parameter + (Some 0xaabbcc) @storage ] + - location: 11 (remaining gas: 1039988.922 units remaining) + [ (Some 0xaabbcc) @storage + (Pair 1 2) @parameter ] + - location: 13 (remaining gas: 1039988.912 units remaining) + [ 0xaabbcc @storage.some + (Pair 1 2) @parameter ] + - location: 19 (remaining gas: 1039988.902 units remaining) + [ (Pair 1 2) @parameter + 0xaabbcc @storage.some ] + - location: 20 (remaining gas: 1039988.892 units remaining) + [ 1 + 2 + 0xaabbcc @storage.some ] + - location: 21 (remaining gas: 1039988.852 units remaining) + [ (Some 0xbbcc) ] + - location: 13 (remaining gas: 1039988.837 units remaining) + [ (Some 0xbbcc) ] + - location: 22 (remaining gas: 1039988.822 units remaining) + [ {} + (Some 0xbbcc) ] + - location: 24 (remaining gas: 1039988.807 units remaining) + [ (Pair {} (Some 0xbbcc)) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None].out new file mode 100644 index 000000000000..c0d8cff4a565 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None].out @@ -0,0 +1,37 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbcc-Pair 1 3-None] + +storage + None +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.942 units remaining) + [ (Pair (Pair 1 3) (Some 0xaabbcc)) ] + - location: 10 (remaining gas: 1039988.932 units remaining) + [ (Pair 1 3) @parameter + (Some 0xaabbcc) @storage ] + - location: 11 (remaining gas: 1039988.922 units remaining) + [ (Some 0xaabbcc) @storage + (Pair 1 3) @parameter ] + - location: 13 (remaining gas: 1039988.912 units remaining) + [ 0xaabbcc @storage.some + (Pair 1 3) @parameter ] + - location: 19 (remaining gas: 1039988.902 units remaining) + [ (Pair 1 3) @parameter + 0xaabbcc @storage.some ] + - location: 20 (remaining gas: 1039988.892 units remaining) + [ 1 + 3 + 0xaabbcc @storage.some ] + - location: 21 (remaining gas: 1039988.852 units remaining) + [ None ] + - location: 13 (remaining gas: 1039988.837 units remaining) + [ None ] + - location: 22 (remaining gas: 1039988.822 units remaining) + [ {} + None ] + - location: 24 (remaining gas: 1039988.807 units remaining) + [ (Pair {} None) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaab.df5895de85.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaab.df5895de85.out new file mode 100644 index 000000000000..821cf5fd08fd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaab.df5895de85.out @@ -0,0 +1,38 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[slice_bytes.tz-Some 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc-Pair 1 10000-None] + +storage + None +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.942 units remaining) + [ (Pair (Pair 1 10000) + (Some 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc)) ] + - location: 10 (remaining gas: 1039988.932 units remaining) + [ (Pair 1 10000) @parameter + (Some 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc) @storage ] + - location: 11 (remaining gas: 1039988.922 units remaining) + [ (Some 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc) @storage + (Pair 1 10000) @parameter ] + - location: 13 (remaining gas: 1039988.912 units remaining) + [ 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc @storage.some + (Pair 1 10000) @parameter ] + - location: 19 (remaining gas: 1039988.902 units remaining) + [ (Pair 1 10000) @parameter + 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc @storage.some ] + - location: 20 (remaining gas: 1039988.892 units remaining) + [ 1 + 10000 + 0xaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbccaabbcc @storage.some ] + - location: 21 (remaining gas: 1039988.477 units remaining) + [ None ] + - location: 13 (remaining gas: 1039988.462 units remaining) + [ None ] + - location: 22 (remaining gas: 1039988.447 units remaining) + [ {} + None ] + - location: 24 (remaining gas: 1039988.432 units remaining) + [ (Pair {} None) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"Hello\"-(Some \"Hello\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"Hello\"-(Some \"Hello\")].out" new file mode 100644 index 000000000000..50bfdf6aeb65 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"Hello\"-(Some \"Hello\")].out" @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[str_id.tz-None-"Hello"-(Some "Hello")] + +storage + (Some "Hello") +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.491 units remaining) + [ (Pair "Hello" None) ] + - location: 8 (remaining gas: 1039994.481 units remaining) + [ "Hello" @parameter ] + - location: 9 (remaining gas: 1039994.466 units remaining) + [ (Some "Hello") ] + - location: 10 (remaining gas: 1039994.451 units remaining) + [ {} + (Some "Hello") ] + - location: 12 (remaining gas: 1039994.436 units remaining) + [ (Pair {} (Some "Hello")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"abcd\"-(Some \"abcd\")].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"abcd\"-(Some \"abcd\")].out" new file mode 100644 index 000000000000..3ea650a63a94 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[str_id.tz-None-\"abcd\"-(Some \"abcd\")].out" @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[str_id.tz-None-"abcd"-(Some "abcd")] + +storage + (Some "abcd") +emitted operations + +big_map diff + +trace + - location: 8 (remaining gas: 1039994.501 units remaining) + [ (Pair "abcd" None) ] + - location: 8 (remaining gas: 1039994.491 units remaining) + [ "abcd" @parameter ] + - location: 9 (remaining gas: 1039994.476 units remaining) + [ (Some "abcd") ] + - location: 10 (remaining gas: 1039994.461 units remaining) + [ {} + (Some "abcd") ] + - location: 12 (remaining gas: 1039994.446 units remaining) + [ (Pair {} (Some "abcd")) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-\"1970-01-01T00:03:20Z\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-\"1970-01-01T00:03:20Z\"].out" new file mode 100644 index 000000000000..8e27fe5702f2 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-\"1970-01-01T00:03:20Z\"].out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 -100)-"1970-01-01T00:03:20Z"] + +storage + "1970-01-01T00:03:20Z" +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039991.553 units remaining) + [ (Pair (Pair "1970-01-01T00:01:40Z" -100) "1970-01-01T00:01:51Z") ] + - location: 9 (remaining gas: 1039991.543 units remaining) + [ (Pair "1970-01-01T00:01:40Z" -100) @parameter ] + - location: 10 (remaining gas: 1039991.533 units remaining) + [ (Pair "1970-01-01T00:01:40Z" -100) @parameter + (Pair "1970-01-01T00:01:40Z" -100) @parameter ] + - location: 11 (remaining gas: 1039991.523 units remaining) + [ "1970-01-01T00:01:40Z" + (Pair "1970-01-01T00:01:40Z" -100) @parameter ] + - location: 12 (remaining gas: 1039991.508 units remaining) + [ (Pair "1970-01-01T00:01:40Z" -100) @parameter ] + - location: 14 (remaining gas: 1039991.498 units remaining) + [ -100 ] + - location: 12 (remaining gas: 1039991.468 units remaining) + [ "1970-01-01T00:01:40Z" + -100 ] + - location: 15 (remaining gas: 1039991.413 units remaining) + [ "1970-01-01T00:03:20Z" ] + - location: 16 (remaining gas: 1039991.398 units remaining) + [ {} + "1970-01-01T00:03:20Z" ] + - location: 18 (remaining gas: 1039991.383 units remaining) + [ (Pair {} "1970-01-01T00:03:20Z") ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-\"1970-01-01T00:00:00Z\"].out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-\"1970-01-01T00:00:00Z\"].out" new file mode 100644 index 000000000000..d0073a04e534 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-\"1970-01-01T00:00:00Z\"].out" @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 100)-"1970-01-01T00:00:00Z"] + +storage + "1970-01-01T00:00:00Z" +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039991.553 units remaining) + [ (Pair (Pair "1970-01-01T00:01:40Z" 100) "1970-01-01T00:01:51Z") ] + - location: 9 (remaining gas: 1039991.543 units remaining) + [ (Pair "1970-01-01T00:01:40Z" 100) @parameter ] + - location: 10 (remaining gas: 1039991.533 units remaining) + [ (Pair "1970-01-01T00:01:40Z" 100) @parameter + (Pair "1970-01-01T00:01:40Z" 100) @parameter ] + - location: 11 (remaining gas: 1039991.523 units remaining) + [ "1970-01-01T00:01:40Z" + (Pair "1970-01-01T00:01:40Z" 100) @parameter ] + - location: 12 (remaining gas: 1039991.508 units remaining) + [ (Pair "1970-01-01T00:01:40Z" 100) @parameter ] + - location: 14 (remaining gas: 1039991.498 units remaining) + [ 100 ] + - location: 12 (remaining gas: 1039991.468 units remaining) + [ "1970-01-01T00:01:40Z" + 100 ] + - location: 15 (remaining gas: 1039991.413 units remaining) + [ "1970-01-01T00:00:00Z" ] + - location: 16 (remaining gas: 1039991.398 units remaining) + [ {} + "1970-01-01T00:00:00Z" ] + - location: 18 (remaining gas: 1039991.383 units remaining) + [ (Pair {} "1970-01-01T00:00:00Z") ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 200000000000000000.3db82d2c25.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 200000000000000000.3db82d2c25.out new file mode 100644 index 000000000000..948f70cdeb37 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 200000000000000000.3db82d2c25.out @@ -0,0 +1,34 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[sub_timestamp_delta.tz-111-(Pair 100 2000000000000000000)--1999999999999999900] + +storage + -1999999999999999900 +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039991.553 units remaining) + [ (Pair (Pair "1970-01-01T00:01:40Z" 2000000000000000000) "1970-01-01T00:01:51Z") ] + - location: 9 (remaining gas: 1039991.543 units remaining) + [ (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter ] + - location: 10 (remaining gas: 1039991.533 units remaining) + [ (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter + (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter ] + - location: 11 (remaining gas: 1039991.523 units remaining) + [ "1970-01-01T00:01:40Z" + (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter ] + - location: 12 (remaining gas: 1039991.508 units remaining) + [ (Pair "1970-01-01T00:01:40Z" 2000000000000000000) @parameter ] + - location: 14 (remaining gas: 1039991.498 units remaining) + [ 2000000000000000000 ] + - location: 12 (remaining gas: 1039991.468 units remaining) + [ "1970-01-01T00:01:40Z" + 2000000000000000000 ] + - location: 15 (remaining gas: 1039991.413 units remaining) + [ -1999999999999999900 ] + - location: 16 (remaining gas: 1039991.398 units remaining) + [ {} + -1999999999999999900 ] + - location: 18 (remaining gas: 1039991.383 units remaining) + [ (Pair {} -1999999999999999900) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair .b461aa042b.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair .b461aa042b.out new file mode 100644 index 000000000000..13ed6d183eaf --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair .b461aa042b.out @@ -0,0 +1,71 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2000000 1000000)-(Some (Pair 3000000 1000000))] + +storage + (Some (Pair 3000000 1000000)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039980.750 units remaining) + [ (Pair (Pair 2000000 1000000) None) ] + - location: 12 (remaining gas: 1039980.740 units remaining) + [ (Pair 2000000 1000000) @parameter ] + - location: 13 (remaining gas: 1039980.730 units remaining) + [ (Pair 2000000 1000000) @parameter + (Pair 2000000 1000000) @parameter ] + - location: 14 (remaining gas: 1039980.720 units remaining) + [ (Pair 2000000 1000000) @parameter + (Pair 2000000 1000000) @parameter + (Pair 2000000 1000000) @parameter ] + - location: 15 (remaining gas: 1039980.710 units remaining) + [ 2000000 + (Pair 2000000 1000000) @parameter + (Pair 2000000 1000000) @parameter ] + - location: 16 (remaining gas: 1039980.695 units remaining) + [ (Pair 2000000 1000000) @parameter + (Pair 2000000 1000000) @parameter ] + - location: 18 (remaining gas: 1039980.685 units remaining) + [ 1000000 + (Pair 2000000 1000000) @parameter ] + - location: 16 (remaining gas: 1039980.655 units remaining) + [ 2000000 + 1000000 + (Pair 2000000 1000000) @parameter ] + - location: 19 (remaining gas: 1039980.635 units remaining) + [ 3000000 + (Pair 2000000 1000000) @parameter ] + - location: 20 (remaining gas: 1039980.620 units remaining) + [ (Pair 2000000 1000000) @parameter ] + - location: 22 (remaining gas: 1039980.610 units remaining) + [ (Pair 2000000 1000000) @parameter + (Pair 2000000 1000000) @parameter ] + - location: 23 (remaining gas: 1039980.600 units remaining) + [ 2000000 + (Pair 2000000 1000000) @parameter ] + - location: 24 (remaining gas: 1039980.585 units remaining) + [ (Pair 2000000 1000000) @parameter ] + - location: 26 (remaining gas: 1039980.575 units remaining) + [ 1000000 ] + - location: 24 (remaining gas: 1039980.545 units remaining) + [ 2000000 + 1000000 ] + - location: 27 (remaining gas: 1039980.525 units remaining) + [ (Some 1000000) ] + - location: 29 (remaining gas: 1039980.515 units remaining) + [ 1000000 @some ] + - location: 29 (remaining gas: 1039980.500 units remaining) + [ 1000000 @some ] + - location: 20 (remaining gas: 1039980.470 units remaining) + [ 3000000 + 1000000 @some ] + - location: 35 (remaining gas: 1039980.455 units remaining) + [ (Pair 3000000 1000000) ] + - location: 36 (remaining gas: 1039980.440 units remaining) + [ (Some (Pair 3000000 1000000)) ] + - location: 37 (remaining gas: 1039980.425 units remaining) + [ {} + (Some (Pair 3000000 1000000)) ] + - location: 39 (remaining gas: 1039980.410 units remaining) + [ (Pair {} (Some (Pair 3000000 1000000))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair .1e8cf7679c.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair .1e8cf7679c.out new file mode 100644 index 000000000000..e8170a8679af --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair .1e8cf7679c.out @@ -0,0 +1,71 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[tez_add_sub.tz-None-(Pair 2310000 1010000)-(Some (Pair 3320000 1300000))] + +storage + (Some (Pair 3320000 1300000)) +emitted operations + +big_map diff + +trace + - location: 12 (remaining gas: 1039980.750 units remaining) + [ (Pair (Pair 2310000 1010000) None) ] + - location: 12 (remaining gas: 1039980.740 units remaining) + [ (Pair 2310000 1010000) @parameter ] + - location: 13 (remaining gas: 1039980.730 units remaining) + [ (Pair 2310000 1010000) @parameter + (Pair 2310000 1010000) @parameter ] + - location: 14 (remaining gas: 1039980.720 units remaining) + [ (Pair 2310000 1010000) @parameter + (Pair 2310000 1010000) @parameter + (Pair 2310000 1010000) @parameter ] + - location: 15 (remaining gas: 1039980.710 units remaining) + [ 2310000 + (Pair 2310000 1010000) @parameter + (Pair 2310000 1010000) @parameter ] + - location: 16 (remaining gas: 1039980.695 units remaining) + [ (Pair 2310000 1010000) @parameter + (Pair 2310000 1010000) @parameter ] + - location: 18 (remaining gas: 1039980.685 units remaining) + [ 1010000 + (Pair 2310000 1010000) @parameter ] + - location: 16 (remaining gas: 1039980.655 units remaining) + [ 2310000 + 1010000 + (Pair 2310000 1010000) @parameter ] + - location: 19 (remaining gas: 1039980.635 units remaining) + [ 3320000 + (Pair 2310000 1010000) @parameter ] + - location: 20 (remaining gas: 1039980.620 units remaining) + [ (Pair 2310000 1010000) @parameter ] + - location: 22 (remaining gas: 1039980.610 units remaining) + [ (Pair 2310000 1010000) @parameter + (Pair 2310000 1010000) @parameter ] + - location: 23 (remaining gas: 1039980.600 units remaining) + [ 2310000 + (Pair 2310000 1010000) @parameter ] + - location: 24 (remaining gas: 1039980.585 units remaining) + [ (Pair 2310000 1010000) @parameter ] + - location: 26 (remaining gas: 1039980.575 units remaining) + [ 1010000 ] + - location: 24 (remaining gas: 1039980.545 units remaining) + [ 2310000 + 1010000 ] + - location: 27 (remaining gas: 1039980.525 units remaining) + [ (Some 1300000) ] + - location: 29 (remaining gas: 1039980.515 units remaining) + [ 1300000 @some ] + - location: 29 (remaining gas: 1039980.500 units remaining) + [ 1300000 @some ] + - location: 20 (remaining gas: 1039980.470 units remaining) + [ 3320000 + 1300000 @some ] + - location: 35 (remaining gas: 1039980.455 units remaining) + [ (Pair 3320000 1300000) ] + - location: 36 (remaining gas: 1039980.440 units remaining) + [ (Some (Pair 3320000 1300000)) ] + - location: 37 (remaining gas: 1039980.425 units remaining) + [ {} + (Some (Pair 3320000 1300000)) ] + - location: 39 (remaining gas: 1039980.410 units remaining) + [ (Pair {} (Some (Pair 3320000 1300000))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142].out new file mode 100644 index 000000000000..7413c60982a9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142].out @@ -0,0 +1,50 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[uncomb.tz-0-(Pair 1 4 2)-142] + +storage + 142 +emitted operations + +big_map diff + +trace + - location: 10 (remaining gas: 1039988.846 units remaining) + [ (Pair (Pair 1 4 2) 0) ] + - location: 10 (remaining gas: 1039988.836 units remaining) + [ (Pair 1 4 2) @parameter ] + - location: 11 (remaining gas: 1039988.799 units remaining) + [ 1 + 4 + 2 ] + - location: 13 (remaining gas: 1039988.789 units remaining) + [ 100 + 1 + 4 + 2 ] + - location: 16 (remaining gas: 1039988.685 units remaining) + [ 100 + 4 + 2 ] + - location: 17 (remaining gas: 1039988.675 units remaining) + [ 4 + 100 + 2 ] + - location: 18 (remaining gas: 1039988.665 units remaining) + [ 10 + 4 + 100 + 2 ] + - location: 21 (remaining gas: 1039988.561 units remaining) + [ 40 + 100 + 2 ] + - location: 22 (remaining gas: 1039988.506 units remaining) + [ 140 + 2 ] + - location: 23 (remaining gas: 1039988.451 units remaining) + [ 142 ] + - location: 24 (remaining gas: 1039988.436 units remaining) + [ {} + 142 ] + - location: 26 (remaining gas: 1039988.421 units remaining) + [ (Pair {} 142) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit].out new file mode 100644 index 000000000000..0cee98524344 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit].out @@ -0,0 +1,462 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[unpair.tz-Unit-Unit-Unit] + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039873.089 units remaining) + [ (Pair Unit Unit) ] + - location: 7 (remaining gas: 1039873.079 units remaining) + [ ] + - location: 8 (remaining gas: 1039873.069 units remaining) + [ Unit ] + - location: 9 (remaining gas: 1039873.059 units remaining) + [ Unit + Unit ] + - location: 10 (remaining gas: 1039873.044 units remaining) + [ (Pair Unit Unit) ] + - location: 11 (remaining gas: 1039873.034 units remaining) + [ Unit + Unit ] + - location: 12 (remaining gas: 1039872.969 units remaining) + [ ] + - location: 14 (remaining gas: 1039872.959 units remaining) + [ Unit @b ] + - location: 15 (remaining gas: 1039872.949 units remaining) + [ Unit @a + Unit @b ] + - location: 16 (remaining gas: 1039872.934 units remaining) + [ (Pair Unit Unit) ] + - location: 17 (remaining gas: 1039872.924 units remaining) + [ Unit @c + Unit @d ] + - location: 18 (remaining gas: 1039872.859 units remaining) + [ ] + - location: 20 (remaining gas: 1039872.849 units remaining) + [ Unit @b ] + - location: 21 (remaining gas: 1039872.839 units remaining) + [ Unit @a + Unit @b ] + - location: 22 (remaining gas: 1039872.824 units remaining) + [ (Pair Unit Unit) ] + - location: 23 (remaining gas: 1039872.814 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 24 (remaining gas: 1039872.804 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 25 (remaining gas: 1039872.739 units remaining) + [ (Pair Unit Unit) ] + - location: 27 (remaining gas: 1039872.729 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 28 (remaining gas: 1039872.719 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 29 (remaining gas: 1039872.654 units remaining) + [ (Pair Unit Unit) ] + - location: 31 (remaining gas: 1039872.644 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 32 (remaining gas: 1039872.634 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 33 (remaining gas: 1039872.569 units remaining) + [ (Pair Unit Unit) ] + - location: 35 (remaining gas: 1039872.559 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 36 (remaining gas: 1039872.549 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 37 (remaining gas: 1039872.484 units remaining) + [ (Pair Unit Unit) ] + - location: 39 (remaining gas: 1039872.474 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 40 (remaining gas: 1039872.464 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 41 (remaining gas: 1039872.399 units remaining) + [ (Pair Unit Unit) ] + - location: 43 (remaining gas: 1039872.389 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 44 (remaining gas: 1039872.379 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 45 (remaining gas: 1039872.314 units remaining) + [ (Pair Unit Unit) ] + - location: 47 (remaining gas: 1039872.304 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 48 (remaining gas: 1039872.294 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 49 (remaining gas: 1039872.229 units remaining) + [ (Pair Unit Unit) ] + - location: 51 (remaining gas: 1039872.219 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 52 (remaining gas: 1039872.209 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 53 (remaining gas: 1039872.144 units remaining) + [ (Pair Unit Unit) ] + - location: 55 (remaining gas: 1039872.134 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 56 (remaining gas: 1039872.124 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 57 (remaining gas: 1039872.059 units remaining) + [ (Pair Unit Unit) ] + - location: 59 (remaining gas: 1039872.049 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 60 (remaining gas: 1039872.039 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 61 (remaining gas: 1039871.974 units remaining) + [ (Pair Unit Unit) ] + - location: 63 (remaining gas: 1039871.964 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 64 (remaining gas: 1039871.954 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 65 (remaining gas: 1039871.889 units remaining) + [ (Pair Unit Unit) ] + - location: 67 (remaining gas: 1039871.879 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 68 (remaining gas: 1039871.869 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 69 (remaining gas: 1039871.804 units remaining) + [ (Pair Unit Unit) ] + - location: 71 (remaining gas: 1039871.794 units remaining) + [ ] + - location: 72 (remaining gas: 1039871.784 units remaining) + [ Unit @d ] + - location: 73 (remaining gas: 1039871.774 units remaining) + [ Unit @c + Unit @d ] + - location: 74 (remaining gas: 1039871.759 units remaining) + [ (Pair Unit Unit) ] + - location: 75 (remaining gas: 1039871.749 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 76 (remaining gas: 1039871.739 units remaining) + [ Unit @c + Unit @d + (Pair Unit Unit) ] + - location: 77 (remaining gas: 1039871.674 units remaining) + [ (Pair Unit Unit) ] + - location: 79 (remaining gas: 1039871.664 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 80 (remaining gas: 1039871.654 units remaining) + [ Unit @c + Unit @d + (Pair Unit Unit) ] + - location: 81 (remaining gas: 1039871.589 units remaining) + [ (Pair Unit Unit) ] + - location: 83 (remaining gas: 1039871.579 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 84 (remaining gas: 1039871.569 units remaining) + [ Unit @c + Unit @d + (Pair Unit Unit) ] + - location: 85 (remaining gas: 1039871.504 units remaining) + [ (Pair Unit Unit) ] + - location: 87 (remaining gas: 1039871.494 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 88 (remaining gas: 1039871.484 units remaining) + [ Unit @c + Unit @d + (Pair Unit Unit) ] + - location: 89 (remaining gas: 1039871.419 units remaining) + [ (Pair Unit Unit) ] + - location: 91 (remaining gas: 1039871.409 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 92 (remaining gas: 1039871.399 units remaining) + [ Unit @c + Unit @d + (Pair Unit Unit) ] + - location: 93 (remaining gas: 1039871.334 units remaining) + [ (Pair Unit Unit) ] + - location: 95 (remaining gas: 1039871.324 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 96 (remaining gas: 1039871.314 units remaining) + [ Unit @c + Unit @d + (Pair Unit Unit) ] + - location: 97 (remaining gas: 1039871.249 units remaining) + [ (Pair Unit Unit) ] + - location: 99 (remaining gas: 1039871.239 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 100 (remaining gas: 1039871.229 units remaining) + [ Unit @c + Unit @d + (Pair Unit Unit) ] + - location: 101 (remaining gas: 1039871.164 units remaining) + [ (Pair Unit Unit) ] + - location: 103 (remaining gas: 1039871.154 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 104 (remaining gas: 1039871.144 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 105 (remaining gas: 1039871.079 units remaining) + [ (Pair Unit Unit) ] + - location: 107 (remaining gas: 1039871.069 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 108 (remaining gas: 1039871.059 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 109 (remaining gas: 1039870.994 units remaining) + [ (Pair Unit Unit) ] + - location: 111 (remaining gas: 1039870.984 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 112 (remaining gas: 1039870.974 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 113 (remaining gas: 1039870.909 units remaining) + [ (Pair Unit Unit) ] + - location: 115 (remaining gas: 1039870.899 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 116 (remaining gas: 1039870.889 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 117 (remaining gas: 1039870.824 units remaining) + [ (Pair Unit Unit) ] + - location: 119 (remaining gas: 1039870.814 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 120 (remaining gas: 1039870.804 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 121 (remaining gas: 1039870.739 units remaining) + [ (Pair Unit Unit) ] + - location: 123 (remaining gas: 1039870.729 units remaining) + [ ] + - location: 124 (remaining gas: 1039870.719 units remaining) + [ Unit ] + - location: 125 (remaining gas: 1039870.709 units remaining) + [ Unit + Unit ] + - location: 126 (remaining gas: 1039870.694 units remaining) + [ (Pair Unit Unit) ] + - location: 127 (remaining gas: 1039870.684 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 128 (remaining gas: 1039870.674 units remaining) + [ Unit + Unit + (Pair Unit Unit) ] + - location: 129 (remaining gas: 1039870.609 units remaining) + [ (Pair Unit Unit) ] + - location: 131 (remaining gas: 1039870.599 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 132 (remaining gas: 1039870.589 units remaining) + [ Unit + Unit + (Pair Unit Unit) ] + - location: 133 (remaining gas: 1039870.524 units remaining) + [ (Pair Unit Unit) ] + - location: 135 (remaining gas: 1039870.514 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 136 (remaining gas: 1039870.504 units remaining) + [ Unit + Unit + (Pair Unit Unit) ] + - location: 137 (remaining gas: 1039870.439 units remaining) + [ (Pair Unit Unit) ] + - location: 139 (remaining gas: 1039870.429 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 140 (remaining gas: 1039870.419 units remaining) + [ Unit + Unit + (Pair Unit Unit) ] + - location: 141 (remaining gas: 1039870.354 units remaining) + [ (Pair Unit Unit) ] + - location: 143 (remaining gas: 1039870.344 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 144 (remaining gas: 1039870.334 units remaining) + [ Unit + Unit + (Pair Unit Unit) ] + - location: 145 (remaining gas: 1039870.269 units remaining) + [ (Pair Unit Unit) ] + - location: 147 (remaining gas: 1039870.259 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 148 (remaining gas: 1039870.249 units remaining) + [ Unit + Unit + (Pair Unit Unit) ] + - location: 149 (remaining gas: 1039870.184 units remaining) + [ (Pair Unit Unit) ] + - location: 151 (remaining gas: 1039870.174 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 152 (remaining gas: 1039870.164 units remaining) + [ Unit + Unit + (Pair Unit Unit) ] + - location: 153 (remaining gas: 1039870.099 units remaining) + [ (Pair Unit Unit) ] + - location: 155 (remaining gas: 1039870.089 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 156 (remaining gas: 1039870.079 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 157 (remaining gas: 1039870.014 units remaining) + [ (Pair Unit Unit) ] + - location: 159 (remaining gas: 1039870.004 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 160 (remaining gas: 1039869.994 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 161 (remaining gas: 1039869.929 units remaining) + [ (Pair Unit Unit) ] + - location: 163 (remaining gas: 1039869.919 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 164 (remaining gas: 1039869.909 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 165 (remaining gas: 1039869.844 units remaining) + [ (Pair Unit Unit) ] + - location: 167 (remaining gas: 1039869.834 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 168 (remaining gas: 1039869.824 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 169 (remaining gas: 1039869.759 units remaining) + [ (Pair Unit Unit) ] + - location: 171 (remaining gas: 1039869.749 units remaining) + [ (Pair Unit Unit) + (Pair Unit Unit) ] + - location: 172 (remaining gas: 1039869.739 units remaining) + [ Unit @a + Unit @b + (Pair Unit Unit) ] + - location: 173 (remaining gas: 1039869.674 units remaining) + [ (Pair Unit Unit) ] + - location: 175 (remaining gas: 1039869.664 units remaining) + [ ] + - location: 176 (remaining gas: 1039869.654 units remaining) + [ Unit ] + - location: 177 (remaining gas: 1039869.644 units remaining) + [ Unit + Unit ] + - location: 178 (remaining gas: 1039869.629 units remaining) + [ (Pair Unit Unit) @p ] + - location: 179 (remaining gas: 1039869.619 units remaining) + [ (Pair Unit Unit) @p + (Pair Unit Unit) @p ] + - location: 180 (remaining gas: 1039869.609 units remaining) + [ Unit @p.a + Unit @b + (Pair Unit Unit) @p ] + - location: 181 (remaining gas: 1039869.544 units remaining) + [ (Pair Unit Unit) @p ] + - location: 183 (remaining gas: 1039869.534 units remaining) + [ (Pair Unit Unit) @p + (Pair Unit Unit) @p ] + - location: 184 (remaining gas: 1039869.524 units remaining) + [ Unit @a + Unit @p.b + (Pair Unit Unit) @p ] + - location: 185 (remaining gas: 1039869.459 units remaining) + [ (Pair Unit Unit) @p ] + - location: 187 (remaining gas: 1039869.449 units remaining) + [ (Pair Unit Unit) @p + (Pair Unit Unit) @p ] + - location: 188 (remaining gas: 1039869.439 units remaining) + [ Unit @p.a + Unit @p.b + (Pair Unit Unit) @p ] + - location: 189 (remaining gas: 1039869.374 units remaining) + [ (Pair Unit Unit) @p ] + - location: 191 (remaining gas: 1039869.364 units remaining) + [ (Pair Unit Unit) @p + (Pair Unit Unit) @p ] + - location: 192 (remaining gas: 1039869.354 units remaining) + [ Unit @a + Unit @p.b + (Pair Unit Unit) @p ] + - location: 193 (remaining gas: 1039869.289 units remaining) + [ (Pair Unit Unit) @p ] + - location: 195 (remaining gas: 1039869.279 units remaining) + [ (Pair Unit Unit) @p + (Pair Unit Unit) @p ] + - location: 196 (remaining gas: 1039869.269 units remaining) + [ Unit @p.a + Unit @b + (Pair Unit Unit) @p ] + - location: 197 (remaining gas: 1039869.204 units remaining) + [ (Pair Unit Unit) @p ] + - location: 199 (remaining gas: 1039869.194 units remaining) + [ ] + - location: 200 (remaining gas: 1039869.184 units remaining) + [ Unit @b ] + - location: 201 (remaining gas: 1039869.174 units remaining) + [ Unit @a + Unit @b ] + - location: 202 (remaining gas: 1039869.159 units remaining) + [ (Pair Unit Unit) @c ] + - location: 203 (remaining gas: 1039869.149 units remaining) + [ Unit @b + Unit @a ] + - location: 204 (remaining gas: 1039869.084 units remaining) + [ ] + - location: 206 (remaining gas: 1039869.074 units remaining) + [ Unit ] + - location: 207 (remaining gas: 1039869.059 units remaining) + [ {} + Unit ] + - location: 209 (remaining gas: 1039869.044 units remaining) + [ (Pair {} Unit) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-\"edpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-\"edpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" new file mode 100644 index 000000000000..e01136ae2e98 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-\"edpkuBknW28nW72KG6RoHtYW7p1.bfa38be34d.out" @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[voting_power.tz-(Pair 0 0)-"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"-(Pair 666 3330)] + +storage + (Pair 666 3330) +emitted operations + +big_map diff + +trace + - location: 9 (remaining gas: 1039666.323 units remaining) + [ (Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" 0 0) ] + - location: 9 (remaining gas: 1039666.313 units remaining) + [ "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" @parameter ] + - location: 10 (remaining gas: 1039665.658 units remaining) + [ "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" ] + - location: 11 (remaining gas: 1039445.120 units remaining) + [ 666 ] + - location: 12 (remaining gas: 1039445.105 units remaining) + [ ] + - location: 14 (remaining gas: 1039234.727 units remaining) + [ 3330 ] + - location: 12 (remaining gas: 1039234.697 units remaining) + [ 666 + 3330 ] + - location: 15 (remaining gas: 1039234.682 units remaining) + [ (Pair 666 3330) ] + - location: 16 (remaining gas: 1039234.667 units remaining) + [ {} + (Pair 666 3330) ] + - location: 18 (remaining gas: 1039234.652 units remaining) + [ (Pair {} 666 3330) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))].out new file mode 100644 index 000000000000..b021b9670f1d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False False)-(Some (Left False))] + +storage + (Some (Left False)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Left (Pair False False)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Left (Pair False False)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair False False) @parameter.left ] + - location: 19 (remaining gas: 1039986.729 units remaining) + [ False + False ] + - location: 20 (remaining gas: 1039986.709 units remaining) + [ False ] + - location: 21 (remaining gas: 1039986.694 units remaining) + [ (Left False) ] + - location: 17 (remaining gas: 1039986.679 units remaining) + [ (Left False) ] + - location: 28 (remaining gas: 1039986.664 units remaining) + [ (Some (Left False)) ] + - location: 29 (remaining gas: 1039986.649 units remaining) + [ {} + (Some (Left False)) ] + - location: 31 (remaining gas: 1039986.634 units remaining) + [ (Pair {} (Some (Left False))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))].out new file mode 100644 index 000000000000..0bb69d3ad379 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair False True)-(Some (Left True))] + +storage + (Some (Left True)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Left (Pair False True)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Left (Pair False True)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair False True) @parameter.left ] + - location: 19 (remaining gas: 1039986.729 units remaining) + [ False + True ] + - location: 20 (remaining gas: 1039986.709 units remaining) + [ True ] + - location: 21 (remaining gas: 1039986.694 units remaining) + [ (Left True) ] + - location: 17 (remaining gas: 1039986.679 units remaining) + [ (Left True) ] + - location: 28 (remaining gas: 1039986.664 units remaining) + [ (Some (Left True)) ] + - location: 29 (remaining gas: 1039986.649 units remaining) + [ {} + (Some (Left True)) ] + - location: 31 (remaining gas: 1039986.634 units remaining) + [ (Pair {} (Some (Left True))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))].out new file mode 100644 index 000000000000..110677de363e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True False)-(Some (Left True))] + +storage + (Some (Left True)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Left (Pair True False)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Left (Pair True False)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair True False) @parameter.left ] + - location: 19 (remaining gas: 1039986.729 units remaining) + [ True + False ] + - location: 20 (remaining gas: 1039986.709 units remaining) + [ True ] + - location: 21 (remaining gas: 1039986.694 units remaining) + [ (Left True) ] + - location: 17 (remaining gas: 1039986.679 units remaining) + [ (Left True) ] + - location: 28 (remaining gas: 1039986.664 units remaining) + [ (Some (Left True)) ] + - location: 29 (remaining gas: 1039986.649 units remaining) + [ {} + (Some (Left True)) ] + - location: 31 (remaining gas: 1039986.634 units remaining) + [ (Pair {} (Some (Left True))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))].out new file mode 100644 index 000000000000..55902d209582 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Left (Pair True True)-(Some (Left False))] + +storage + (Some (Left False)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Left (Pair True True)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Left (Pair True True)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair True True) @parameter.left ] + - location: 19 (remaining gas: 1039986.729 units remaining) + [ True + True ] + - location: 20 (remaining gas: 1039986.709 units remaining) + [ False ] + - location: 21 (remaining gas: 1039986.694 units remaining) + [ (Left False) ] + - location: 17 (remaining gas: 1039986.679 units remaining) + [ (Left False) ] + - location: 28 (remaining gas: 1039986.664 units remaining) + [ (Some (Left False)) ] + - location: 29 (remaining gas: 1039986.649 units remaining) + [ {} + (Some (Left False)) ] + - location: 31 (remaining gas: 1039986.634 units remaining) + [ (Pair {} (Some (Left False))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))].out new file mode 100644 index 000000000000..c4573befc22f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 0)-(Some (Right 0))] + +storage + (Some (Right 0)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Right (Pair 0 0)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Right (Pair 0 0)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair 0 0) @parameter.right ] + - location: 24 (remaining gas: 1039986.729 units remaining) + [ 0 + 0 ] + - location: 25 (remaining gas: 1039986.674 units remaining) + [ 0 ] + - location: 26 (remaining gas: 1039986.659 units remaining) + [ (Right 0) ] + - location: 17 (remaining gas: 1039986.644 units remaining) + [ (Right 0) ] + - location: 28 (remaining gas: 1039986.629 units remaining) + [ (Some (Right 0)) ] + - location: 29 (remaining gas: 1039986.614 units remaining) + [ {} + (Some (Right 0)) ] + - location: 31 (remaining gas: 1039986.599 units remaining) + [ (Pair {} (Some (Right 0))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))].out new file mode 100644 index 000000000000..c3303fbf3b98 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 0 1)-(Some (Right 1))] + +storage + (Some (Right 1)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Right (Pair 0 1)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Right (Pair 0 1)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair 0 1) @parameter.right ] + - location: 24 (remaining gas: 1039986.729 units remaining) + [ 0 + 1 ] + - location: 25 (remaining gas: 1039986.674 units remaining) + [ 1 ] + - location: 26 (remaining gas: 1039986.659 units remaining) + [ (Right 1) ] + - location: 17 (remaining gas: 1039986.644 units remaining) + [ (Right 1) ] + - location: 28 (remaining gas: 1039986.629 units remaining) + [ (Some (Right 1)) ] + - location: 29 (remaining gas: 1039986.614 units remaining) + [ {} + (Some (Right 1)) ] + - location: 31 (remaining gas: 1039986.599 units remaining) + [ (Pair {} (Some (Right 1))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))].out new file mode 100644 index 000000000000..1cfa8069aa68 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 0)-(Some (Right 1))] + +storage + (Some (Right 1)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Right (Pair 1 0)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Right (Pair 1 0)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair 1 0) @parameter.right ] + - location: 24 (remaining gas: 1039986.729 units remaining) + [ 1 + 0 ] + - location: 25 (remaining gas: 1039986.674 units remaining) + [ 1 ] + - location: 26 (remaining gas: 1039986.659 units remaining) + [ (Right 1) ] + - location: 17 (remaining gas: 1039986.644 units remaining) + [ (Right 1) ] + - location: 28 (remaining gas: 1039986.629 units remaining) + [ (Some (Right 1)) ] + - location: 29 (remaining gas: 1039986.614 units remaining) + [ {} + (Some (Right 1)) ] + - location: 31 (remaining gas: 1039986.599 units remaining) + [ (Pair {} (Some (Right 1))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))].out new file mode 100644 index 000000000000..c5aa1e891270 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 1 1)-(Some (Right 0))] + +storage + (Some (Right 0)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Right (Pair 1 1)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Right (Pair 1 1)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair 1 1) @parameter.right ] + - location: 24 (remaining gas: 1039986.729 units remaining) + [ 1 + 1 ] + - location: 25 (remaining gas: 1039986.674 units remaining) + [ 0 ] + - location: 26 (remaining gas: 1039986.659 units remaining) + [ (Right 0) ] + - location: 17 (remaining gas: 1039986.644 units remaining) + [ (Right 0) ] + - location: 28 (remaining gas: 1039986.629 units remaining) + [ (Some (Right 0)) ] + - location: 29 (remaining gas: 1039986.614 units remaining) + [ {} + (Some (Right 0)) ] + - location: 31 (remaining gas: 1039986.599 units remaining) + [ (Pair {} (Some (Right 0))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))].out new file mode 100644 index 000000000000..3a5445a5efad --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 21)-(Some (Right 63))] + +storage + (Some (Right 63)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Right (Pair 42 21)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Right (Pair 42 21)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair 42 21) @parameter.right ] + - location: 24 (remaining gas: 1039986.729 units remaining) + [ 42 + 21 ] + - location: 25 (remaining gas: 1039986.674 units remaining) + [ 63 ] + - location: 26 (remaining gas: 1039986.659 units remaining) + [ (Right 63) ] + - location: 17 (remaining gas: 1039986.644 units remaining) + [ (Right 63) ] + - location: 28 (remaining gas: 1039986.629 units remaining) + [ (Some (Right 63)) ] + - location: 29 (remaining gas: 1039986.614 units remaining) + [ {} + (Some (Right 63)) ] + - location: 31 (remaining gas: 1039986.599 units remaining) + [ (Pair {} (Some (Right 63))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))].out new file mode 100644 index 000000000000..cf13144f4774 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))].out @@ -0,0 +1,32 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_contract_input_output[xor.tz-None-Right (Pair 42 63)-(Some (Right 21))] + +storage + (Some (Right 21)) +emitted operations + +big_map diff + +trace + - location: 16 (remaining gas: 1039986.759 units remaining) + [ (Pair (Right (Pair 42 63)) None) ] + - location: 16 (remaining gas: 1039986.749 units remaining) + [ (Right (Pair 42 63)) @parameter ] + - location: 17 (remaining gas: 1039986.739 units remaining) + [ (Pair 42 63) @parameter.right ] + - location: 24 (remaining gas: 1039986.729 units remaining) + [ 42 + 63 ] + - location: 25 (remaining gas: 1039986.674 units remaining) + [ 21 ] + - location: 26 (remaining gas: 1039986.659 units remaining) + [ (Right 21) ] + - location: 17 (remaining gas: 1039986.644 units remaining) + [ (Right 21) ] + - location: 28 (remaining gas: 1039986.629 units remaining) + [ (Some (Right 21)) ] + - location: 29 (remaining gas: 1039986.614 units remaining) + [ {} + (Some (Right 21)) ] + - location: 31 (remaining gas: 1039986.599 units remaining) + [ (Pair {} (Some (Right 21))) ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_hash_consistency_michelson_cli.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_hash_consistency_michelson_cli.out new file mode 100644 index 000000000000..0380b3fc5ffb --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_hash_consistency_michelson_cli.out @@ -0,0 +1,23 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_hash_consistency_michelson_cli + +Raw packed data: 0x0507070080acd2c6a501070700bcc485a30b0022 +Script-expression-ID-Hash: expruenXhGp5JQoHJTGv4DzBR8Zm3HGvea8Q8BaMPywsY2bxrHAEgC +Raw Script-expression-ID-Hash: 0x95a69fcbbf773989333dc9b31e246575812dbea19d25089f83a2aeeea16ab4bc +Ledger Blake2b hash: B5B7PuGGVUrdHUW9Df8wPNJQRuUmx56aH1XVpvbUZvW7 +Raw Sha256 hash: 0x538634a0f81b55f1c946c1207a25c262479566d20bd3d5cd2cdbb2940fc45774 +Raw Sha512 hash: 0x49d5c19c2da4ee74f85225c95625a4b77b94724f4285b436b9d4be27d40491354bdc8e9d8a3d9b2857e5fb59b172605edd02fc4b61ce3cd3f84aa11ed1731ff6 +Gas remaining: 1039997.927 units remaining +storage + 0x95a69fcbbf773989333dc9b31e246575812dbea19d25089f83a2aeeea16ab4bc +emitted operations + +big_map diff + + +storage + 0x95a69fcbbf773989333dc9b31e246575812dbea19d25089f83a2aeeea16ab4bc +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_level.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_level.out new file mode 100644 index 000000000000..5852d1c8ff5a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_level.out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_level + +storage + 10 +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.948 units remaining) + [ (Pair Unit 9999999) ] + - location: 7 (remaining gas: 1039994.938 units remaining) + [ ] + - location: 8 (remaining gas: 1039994.923 units remaining) + [ 10 @level ] + - location: 9 (remaining gas: 1039994.908 units remaining) + [ {} + 10 @level ] + - location: 11 (remaining gas: 1039994.893 units remaining) + [ (Pair {} 10) ] + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" new file mode 100644 index 000000000000..e4f96e31b1b6 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"bar\" 5 ; Elt \"foo\" 1 } .480b9afc63.out" @@ -0,0 +1,9 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt "bar" 5 ; Elt "foo" 1 } 6)-15-(Pair { Elt "bar" 20 ; Elt "foo" 16 } 36)] + +storage + (Pair { Elt "bar" 20 ; Elt "foo" 16 } 36) +emitted operations + +big_map diff + + diff --git "a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" new file mode 100644 index 000000000000..928c8032a426 --- /dev/null +++ "b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt \"foo\" 1 } 1)-10-(Pair { .811573b5a7.out" @@ -0,0 +1,9 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair { Elt "foo" 1 } 1)-10-(Pair { Elt "foo" 11 } 11)] + +storage + (Pair { Elt "foo" 11 } 11) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out new file mode 100644 index 000000000000..511bc3654a14 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)].out @@ -0,0 +1,9 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_map_map_sideeffect[map_map_sideeffect.tz-(Pair {} 0)-10-(Pair {} 0)] + +storage + (Pair {} 0) +emitted operations + +big_map diff + + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_now.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_now.out new file mode 100644 index 000000000000..c554477d2bb7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_now.out @@ -0,0 +1,21 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_now + +storage + "2021-10-13T10:16:52Z" +emitted operations + +big_map diff + +trace + - location: 7 (remaining gas: 1039994.848 units remaining) + [ (Pair Unit "2017-07-13T09:19:01Z") ] + - location: 7 (remaining gas: 1039994.838 units remaining) + [ ] + - location: 8 (remaining gas: 1039994.823 units remaining) + [ "2021-10-13T10:16:52Z" @now ] + - location: 9 (remaining gas: 1039994.808 units remaining) + [ {} + "2021-10-13T10:16:52Z" @now ] + - location: 11 (remaining gas: 1039994.793 units remaining) + [ (Pair {} "2021-10-13T10:16:52Z") ] + diff --git a/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_packunpack.out b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_packunpack.out new file mode 100644 index 000000000000..4d8f7a7aee15 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_contract_opcodes.TestContractOpcodes::test_packunpack.out @@ -0,0 +1,106 @@ +tests_012/test_contract_opcodes.py::TestContractOpcodes::test_packunpack + +storage + Unit +emitted operations + +big_map diff + +trace + - location: 15 (remaining gas: 1039977.531 units remaining) + [ (Pair (Pair (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003) + Unit) ] + - location: 15 (remaining gas: 1039977.521 units remaining) + [ (Pair (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003) @parameter ] + - location: 16 (remaining gas: 1039977.511 units remaining) + [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] + - location: 17 (remaining gas: 1039977.496 units remaining) + [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] + - location: 19 (remaining gas: 1039977.486 units remaining) + [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] + - location: 17 (remaining gas: 1039977.456 units remaining) + [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] + - location: 20 (remaining gas: 1039975.016 units remaining) + [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 @packed + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] + - location: 23 (remaining gas: 1039974.981 units remaining) + [ 0 + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] + - location: 24 (remaining gas: 1039974.966 units remaining) + [ True + 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] + - location: 25 (remaining gas: 1039974.956 units remaining) + [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] + - location: 25 (remaining gas: 1039974.941 units remaining) + [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 ] + - location: 31 (remaining gas: 1039971.783 units remaining) + [ (Some (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 })) @unpacked ] + - location: 40 (remaining gas: 1039971.773 units remaining) + [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) @unpacked.some ] + - location: 40 (remaining gas: 1039971.758 units remaining) + [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) @unpacked.some ] + - location: 46 (remaining gas: 1039971.748 units remaining) + [ ] + - location: 47 (remaining gas: 1039971.738 units remaining) + [ Unit ] + - location: 48 (remaining gas: 1039971.723 units remaining) + [ {} + Unit ] + - location: 50 (remaining gas: 1039971.708 units remaining) + [ (Pair {} Unit) ] + +Runtime error in contract [CONTRACT_HASH]: + 1: parameter (pair (pair (pair string (list int)) (set nat)) bytes) ; + 2: storage unit ; + 3: code { CAR ; UNPAIR ; DIP { DUP } ; + 4: PACK ; ASSERT_CMPEQ ; + 5: UNPACK (pair (pair string (list int)) (set nat)) ; ASSERT_SOME ; DROP ; + 6: UNIT ; NIL operation ; PAIR } + 7: +At line 4 characters 14 to 26, +script reached FAILWITH instruction +with Unit +trace + - location: 15 (remaining gas: 1039977.531 units remaining) + [ (Pair (Pair (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004) + Unit) ] + - location: 15 (remaining gas: 1039977.521 units remaining) + [ (Pair (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004) @parameter ] + - location: 16 (remaining gas: 1039977.511 units remaining) + [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] + - location: 17 (remaining gas: 1039977.496 units remaining) + [ 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] + - location: 19 (remaining gas: 1039977.486 units remaining) + [ 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] + - location: 17 (remaining gas: 1039977.456 units remaining) + [ (Pair (Pair "toto" { 3 ; 7 ; 9 ; 1 }) { 1 ; 2 ; 3 }) + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] + - location: 20 (remaining gas: 1039975.016 units remaining) + [ 0x05070707070100000004746f746f020000000800030007000900010200000006000100020003 @packed + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] + - location: 23 (remaining gas: 1039974.981 units remaining) + [ -1 + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] + - location: 24 (remaining gas: 1039974.966 units remaining) + [ False + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] + - location: 25 (remaining gas: 1039974.956 units remaining) + [ 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] + - location: 29 (remaining gas: 1039974.946 units remaining) + [ Unit + 0x05070707070100000004746f746f0200000008000300070009000102000000060001000200030004 ] +Fatal error: + error running script diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_add_liquidity.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_add_liquidity.out new file mode 100644 index 000000000000..2cb76616e71e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_add_liquidity.out @@ -0,0 +1,83 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_add_liquidity + +Node is bootstrapped. +Estimated gas: 11854.210 units (will add 100 for safety) +Estimated storage: 141 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.001551 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 11955 + Storage limit: 161 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.001551 + payload fees(the block proposer) ....... +ꜩ0.001551 + Transaction: + Amount: ꜩ9001 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: addLiquidity + Parameter: (Pair "[CONTRACT_HASH]" 0 1000000000 "[TIMESTAMP]") + This transaction was successfully applied + Updated storage: + { 722 ; + 9013500100 ; + 72107 ; + 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; + 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } + Storage size: 4633 bytes + Paid storage size diff: 3 bytes + Consumed gas: 2911.771 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.00075 + storage fees ........................... +ꜩ0.00075 + [CONTRACT_HASH] ... -ꜩ9001 + [CONTRACT_HASH] ... +ꜩ9001 + Internal operations: + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: transfer + Parameter: (Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 + (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 721)) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(1)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 + 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 999999279 + Set map(0)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 99999279 + Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 721 + Storage size: 2263 bytes + Paid storage size diff: 68 bytes + Consumed gas: 4394.451 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.017 + storage fees ........................... +ꜩ0.017 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: mintOrBurn + Parameter: (Pair 72007 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78) + This transaction was successfully applied + Updated storage: + { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 72107 } + Updated big_maps: + Set map(2)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 72007 + Storage size: 2048 bytes + Paid storage size diff: 70 bytes + Consumed gas: 4547.988 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0175 + storage fees ........................... +ꜩ0.0175 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approval.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approval.out new file mode 100644 index 000000000000..2c343c6c373a --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approval.out @@ -0,0 +1,41 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_approval + +Node is bootstrapped. +Estimated gas: 2375.388 units (will add 100 for safety) +Estimated storage: 68 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000555 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2476 + Storage limit: 88 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000555 + payload fees(the block proposer) ....... +ꜩ0.000555 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: approve + Parameter: (Pair "[CONTRACT_HASH]" 1000) + This transaction was successfully applied + Updated storage: + { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 72107 } + Updated big_maps: + Set map(3)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 + 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c)] to 1000 + Storage size: 2116 bytes + Paid storage size diff: 68 bytes + Consumed gas: 2375.388 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.017 + storage fees ........................... +ꜩ0.017 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approved_transfer.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approved_transfer.out new file mode 100644 index 000000000000..b2c07dc7373e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_approved_transfer.out @@ -0,0 +1,41 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_approved_transfer + +Node is bootstrapped. +Estimated gas: 4366.195 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000804 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 4467 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000804 + payload fees(the block proposer) ....... +ꜩ0.000804 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: transfer + Parameter: (Pair "[CONTRACT_HASH]" + "[CONTRACT_HASH]" + 1000) + This transaction was successfully applied + Updated storage: + { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 72107 } + Updated big_maps: + Unset map(3)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 + 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c)] + Set map(2)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 71007 + Set map(2)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] to 1000 + Storage size: 2116 bytes + Consumed gas: 4366.195 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve1.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve1.out new file mode 100644 index 000000000000..08d8d166d54d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve1.out @@ -0,0 +1,41 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_call_approve1 + +Node is bootstrapped. +Estimated gas: 2375.464 units (will add 100 for safety) +Estimated storage: 71 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000558 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2476 + Storage limit: 91 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000558 + payload fees(the block proposer) ....... +ꜩ0.000558 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: approve + Parameter: (Pair "[CONTRACT_HASH]" 1000000000) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(1)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 + 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 + Storage size: 2053 bytes + Paid storage size diff: 71 bytes + Consumed gas: 2375.464 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01775 + storage fees ........................... +ꜩ0.01775 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve2.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve2.out new file mode 100644 index 000000000000..4a76141eb2cd --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve2.out @@ -0,0 +1,41 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_call_approve2 + +Node is bootstrapped. +Estimated gas: 2375.464 units (will add 100 for safety) +Estimated storage: 71 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000558 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2476 + Storage limit: 91 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000558 + payload fees(the block proposer) ....... +ꜩ0.000558 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: approve + Parameter: (Pair "[CONTRACT_HASH]" 1000000000) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(1)[(Pair 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c + 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 + Storage size: 2124 bytes + Paid storage size diff: 71 bytes + Consumed gas: 2375.464 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01775 + storage fees ........................... +ꜩ0.01775 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve3.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve3.out new file mode 100644 index 000000000000..ccd2b7c7a352 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_approve3.out @@ -0,0 +1,41 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_call_approve3 + +Node is bootstrapped. +Estimated gas: 2375.464 units (will add 100 for safety) +Estimated storage: 71 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000558 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2476 + Storage limit: 91 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000558 + payload fees(the block proposer) ....... +ꜩ0.000558 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: approve + Parameter: (Pair "[CONTRACT_HASH]" 1000000000) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(1)[(Pair 0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6 + 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 + Storage size: 2195 bytes + Paid storage size diff: 71 bytes + Consumed gas: 2375.464 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01775 + storage fees ........................... +ꜩ0.01775 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_mint_or_burn.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_mint_or_burn.out new file mode 100644 index 000000000000..a196ce78b0de --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_call_mint_or_burn.out @@ -0,0 +1,40 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_call_mint_or_burn + +Node is bootstrapped. +Estimated gas: 4548.314 units (will add 100 for safety) +Estimated storage: 71 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000777 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 4649 + Storage limit: 91 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000777 + payload fees(the block proposer) ....... +ꜩ0.000777 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: mintOrBurn + Parameter: (Pair 100000000 "[CONTRACT_HASH]") + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(0)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 100000000 + Storage size: 1982 bytes + Paid storage size diff: 71 bytes + Consumed gas: 4548.941 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01775 + storage fees ........................... +ꜩ0.01775 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_dex_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_dex_storage.out new file mode 100644 index 000000000000..35934a19c03f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_dex_storage.out @@ -0,0 +1,7 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_dex_storage + +Pair 712 + 8895894353 + 71107 + "[CONTRACT_HASH]" + "[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_lqt_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_lqt_storage.out new file mode 100644 index 000000000000..7b4f11764452 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_lqt_storage.out @@ -0,0 +1,3 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_lqt_storage + +Pair 2 3 "[CONTRACT_HASH]" 71107 diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out new file mode 100644 index 000000000000..353910347f1d --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out @@ -0,0 +1,80 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_remove_liquidity + +Node is bootstrapped. +Estimated gas: 10533.836 units (will add 100 for safety) +Estimated storage: 67 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.001416 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 10634 + Storage limit: 87 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.001416 + payload fees(the block proposer) ....... +ꜩ0.001416 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: removeLiquidity + Parameter: (Pair "[CONTRACT_HASH]" 1000 0 0 "[TIMESTAMP]") + This transaction was successfully applied + Updated storage: + { 712 ; + 8895894353 ; + 71107 ; + 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; + 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } + Storage size: 4633 bytes + Consumed gas: 2913.981 + Internal operations: + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: mintOrBurn + Parameter: (Pair -1000 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c) + This transaction was successfully applied + Updated storage: + { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 71107 } + Updated big_maps: + Unset map(2)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] + Storage size: 2048 bytes + Consumed gas: 2522.649 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: transfer + Parameter: (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 + (Pair 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c 10)) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 711 + Set map(0)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] to 10 + Storage size: 2330 bytes + Paid storage size diff: 67 bytes + Consumed gas: 3677.206 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01675 + storage fees ........................... +ꜩ0.01675 + Transaction: + Amount: ꜩ125.105747 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Consumed gas: 1420 + Balance updates: + [CONTRACT_HASH] ... -ꜩ125.105747 + [CONTRACT_HASH] ... +ꜩ125.105747 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_setup.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_setup.out new file mode 100644 index 000000000000..d0f34ec3c344 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_setup.out @@ -0,0 +1,8 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_setup + +"[CONTRACT_HASH]" +Pair 1 + 100 + 100 + "[CONTRACT_HASH]" + "[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_tok_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_tok_storage.out new file mode 100644 index 000000000000..a537d1ec8a1e --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_tok_storage.out @@ -0,0 +1,3 @@ +tests_012/test_liquidity_baking.py::TestAddApproveTransferRemove::test_tok_storage + +Pair 0 1 "[CONTRACT_HASH]" 100010000 diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_add_liquidity.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_add_liquidity.out new file mode 100644 index 000000000000..a3eb3f301791 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_add_liquidity.out @@ -0,0 +1,83 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_add_liquidity + +Node is bootstrapped. +Estimated gas: 11854.210 units (will add 100 for safety) +Estimated storage: 141 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.001551 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 11955 + Storage limit: 161 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.001551 + payload fees(the block proposer) ....... +ꜩ0.001551 + Transaction: + Amount: ꜩ9001 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: addLiquidity + Parameter: (Pair "[CONTRACT_HASH]" 0 1000000000 "[TIMESTAMP]") + This transaction was successfully applied + Updated storage: + { 722 ; + 9013500100 ; + 72107 ; + 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; + 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } + Storage size: 4633 bytes + Paid storage size diff: 3 bytes + Consumed gas: 2911.771 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.00075 + storage fees ........................... +ꜩ0.00075 + [CONTRACT_HASH] ... -ꜩ9001 + [CONTRACT_HASH] ... +ꜩ9001 + Internal operations: + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: transfer + Parameter: (Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 + (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 721)) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(1)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 + 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 999999279 + Set map(0)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 99999279 + Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 721 + Storage size: 2263 bytes + Paid storage size diff: 68 bytes + Consumed gas: 4394.451 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.017 + storage fees ........................... +ꜩ0.017 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: mintOrBurn + Parameter: (Pair 72007 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78) + This transaction was successfully applied + Updated storage: + { 2 ; 3 ; 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 ; 72107 } + Updated big_maps: + Set map(2)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 72007 + Storage size: 2048 bytes + Paid storage size diff: 70 bytes + Consumed gas: 4547.988 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.0175 + storage fees ........................... +ꜩ0.0175 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out new file mode 100644 index 000000000000..b523ea381261 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out @@ -0,0 +1,75 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_buy_tok + +Node is bootstrapped. +Estimated gas: 7499.668 units (will add 100 for safety) +Estimated storage: 326 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.001107 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 7600 + Storage limit: 346 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.001107 + payload fees(the block proposer) ....... +ꜩ0.001107 + Transaction: + Amount: ꜩ9001 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: xtzToToken + Parameter: (Pair "[CONTRACT_HASH]" 0 "[TIMESTAMP]") + This transaction was successfully applied + Updated storage: + { 362 ; + 18007999100 ; + 72107 ; + 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; + 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } + Storage size: 4634 bytes + Paid storage size diff: 1 bytes + Consumed gas: 2402.458 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.00025 + storage fees ........................... +ꜩ0.00025 + [CONTRACT_HASH] ... -ꜩ9001 + [CONTRACT_HASH] ... +ꜩ9001 + Internal operations: + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: transfer + Parameter: (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 + (Pair 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c 360)) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 361 + Set map(0)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] to 360 + Storage size: 2331 bytes + Paid storage size diff: 68 bytes + Consumed gas: 3677.210 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.017 + storage fees ........................... +ꜩ0.017 + Transaction: + Amount: ꜩ9.001 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Consumed gas: 1420 + Balance updates: + [CONTRACT_HASH] ... -ꜩ9.001 + [CONTRACT_HASH] ... +ꜩ9.001 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve1.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve1.out new file mode 100644 index 000000000000..1435a7ad409c --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve1.out @@ -0,0 +1,41 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_call_approve1 + +Node is bootstrapped. +Estimated gas: 2375.464 units (will add 100 for safety) +Estimated storage: 71 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000558 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2476 + Storage limit: 91 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000558 + payload fees(the block proposer) ....... +ꜩ0.000558 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: approve + Parameter: (Pair "[CONTRACT_HASH]" 1000000000) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(1)[(Pair 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 + 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 + Storage size: 2053 bytes + Paid storage size diff: 71 bytes + Consumed gas: 2375.464 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01775 + storage fees ........................... +ꜩ0.01775 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve2.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve2.out new file mode 100644 index 000000000000..7ef25cb3dec9 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve2.out @@ -0,0 +1,41 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_call_approve2 + +Node is bootstrapped. +Estimated gas: 2375.464 units (will add 100 for safety) +Estimated storage: 71 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000558 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2476 + Storage limit: 91 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000558 + payload fees(the block proposer) ....... +ꜩ0.000558 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: approve + Parameter: (Pair "[CONTRACT_HASH]" 1000000000) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(1)[(Pair 0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c + 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 + Storage size: 2124 bytes + Paid storage size diff: 71 bytes + Consumed gas: 2375.464 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01775 + storage fees ........................... +ꜩ0.01775 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve3.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve3.out new file mode 100644 index 000000000000..b0be0ba16311 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_approve3.out @@ -0,0 +1,41 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_call_approve3 + +Node is bootstrapped. +Estimated gas: 2375.464 units (will add 100 for safety) +Estimated storage: 71 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000558 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2476 + Storage limit: 91 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000558 + payload fees(the block proposer) ....... +ꜩ0.000558 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: approve + Parameter: (Pair "[CONTRACT_HASH]" 1000000000) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(1)[(Pair 0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6 + 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 1000000000 + Storage size: 2195 bytes + Paid storage size diff: 71 bytes + Consumed gas: 2375.464 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01775 + storage fees ........................... +ꜩ0.01775 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_mint_or_burn.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_mint_or_burn.out new file mode 100644 index 000000000000..ee84d8a5c15b --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_call_mint_or_burn.out @@ -0,0 +1,40 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_call_mint_or_burn + +Node is bootstrapped. +Estimated gas: 4548.314 units (will add 100 for safety) +Estimated storage: 71 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000777 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 4649 + Storage limit: 91 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000777 + payload fees(the block proposer) ....... +ꜩ0.000777 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: mintOrBurn + Parameter: (Pair 100000000 "[CONTRACT_HASH]") + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(0)[0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78] to 100000000 + Storage size: 1982 bytes + Paid storage size diff: 71 bytes + Consumed gas: 4548.941 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.01775 + storage fees ........................... +ꜩ0.01775 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_dex_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_dex_storage.out new file mode 100644 index 000000000000..36ab02138639 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_dex_storage.out @@ -0,0 +1,7 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_dex_storage + +Pair 462 + 14117137204 + 72107 + "[CONTRACT_HASH]" + "[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_lqt_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_lqt_storage.out new file mode 100644 index 000000000000..44e4dc9acdd8 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_lqt_storage.out @@ -0,0 +1,3 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_lqt_storage + +Pair 2 3 "[CONTRACT_HASH]" 72107 diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out new file mode 100644 index 000000000000..b9dfed6faf07 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out @@ -0,0 +1,74 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_sell_tok + +Node is bootstrapped. +Estimated gas: 9818.099 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.001337 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 9919 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.001337 + payload fees(the block proposer) ....... +ꜩ0.001337 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: tokenToXtz + Parameter: (Pair "[CONTRACT_HASH]" 100 0 "[TIMESTAMP]") + This transaction was successfully applied + Updated storage: + { 462 ; + 14117137204 ; + 72107 ; + 0x01e927f00ef734dfc85919635e9afc9166c83ef9fc00 ; + 0x0115eb0104481a6d7921160bc982c5e0a561cd8a3a00 } + Storage size: 4633 bytes + Consumed gas: 2403.612 + Internal operations: + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: transfer + Parameter: (Pair 0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6 + (Pair 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600 100)) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(1)[(Pair 0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6 + 0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600)] to 999999900 + Unset map(0)[0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6] + Set map(0)[0x01d496def47a3be89f5d54c6e6bb13cc6645d6e16600] to 461 + Storage size: 2331 bytes + Consumed gas: 4574.487 + Transaction: + Amount: ꜩ3891.966034 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Consumed gas: 1420 + Balance updates: + [CONTRACT_HASH] ... -ꜩ3891.966034 + [CONTRACT_HASH] ... +ꜩ3891.966034 + Transaction: + Amount: ꜩ3.895862 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + This transaction was successfully applied + Consumed gas: 1420 + Balance updates: + [CONTRACT_HASH] ... -ꜩ3.895862 + [CONTRACT_HASH] ... +ꜩ3.895862 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_setup.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_setup.out new file mode 100644 index 000000000000..c2d918b666cc --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_setup.out @@ -0,0 +1,8 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_setup + +"[CONTRACT_HASH]" +Pair 1 + 100 + 100 + "[CONTRACT_HASH]" + "[CONTRACT_HASH]" diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_tok_storage.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_tok_storage.out new file mode 100644 index 000000000000..5251c4db61c7 --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_tok_storage.out @@ -0,0 +1,3 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_tok_storage + +Pair 0 1 "[CONTRACT_HASH]" 100010000 diff --git a/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_transfer.out b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_transfer.out new file mode 100644 index 000000000000..cba1b68b4f4f --- /dev/null +++ b/tests_python/tests_012/_regtest_outputs/test_liquidity_baking.TestTrades::test_transfer.out @@ -0,0 +1,43 @@ +tests_012/test_liquidity_baking.py::TestTrades::test_transfer + +Node is bootstrapped. +Estimated gas: 3679.110 units (will add 100 for safety) +Estimated storage: 68 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000735 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 3780 + Storage limit: 88 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000735 + payload fees(the block proposer) ....... +ꜩ0.000735 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: transfer + Parameter: (Pair "[CONTRACT_HASH]" + "[CONTRACT_HASH]" + 100) + This transaction was successfully applied + Updated storage: + { 0 ; 1 ; 0x000002298c03ed7d454a101eb7022bc95f7e5f41ac78 ; 100010000 } + Updated big_maps: + Set map(0)[0x0000dac9f52543da1aed0bc1d6b46bf7c10db7014cd6] to 100 + Set map(0)[0x0000e7670f32038107a59a2b9cfefae36ea21f5aa63c] to 260 + Storage size: 2399 bytes + Paid storage size diff: 68 bytes + Consumed gas: 3679.110 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.017 + storage fees ........................... +ꜩ0.017 + +Injected block at minimal timestamp diff --git a/tests_python/tests_012/conftest.py b/tests_python/tests_012/conftest.py new file mode 100644 index 000000000000..354e05df60fb --- /dev/null +++ b/tests_python/tests_012/conftest.py @@ -0,0 +1,121 @@ +"""Protocol-specific hooks and fixtures""" + +import tempfile +from typing import Optional, Iterator, List +import pytest +from launchers.sandbox import Sandbox +from tools import constants, utils +from tools.client_regression import ClientRegression +from client.client import Client +from client.client_output import CreateMockupResult + +from . import protocol + + +@pytest.fixture(scope="class") +def client(sandbox: Sandbox) -> Iterator[Client]: + """One node with protocol 012. + + Activate protocol 012 one year in the past. This avoids waiting + when baking blocks manually from the client using `bake for` + """ + sandbox.add_node(0, params=constants.NODE_PARAMS) + client = sandbox.client(0) + parameters = protocol.get_parameters() + parameters['consensus_threshold'] = 0 + protocol.activate(client, parameters=parameters, activate_in_the_past=True) + yield client + + +@pytest.fixture(scope="class") +def client_regtest_bis(sandbox: Sandbox) -> Iterator[Client]: + """One node with protocol 012, regression test enabled. + + Activate protocol 012 one year in the past. (see fixture client). + """ + + def reg_client_factory( + client_path: str, + admin_client_path: str, + host: Optional[str] = None, + base_dir: Optional[str] = None, + rpc_port: Optional[int] = None, + use_tls: Optional[bool] = None, + endpoint: Optional[str] = 'http://127.0.0.1:8732', + mode: str = None, + disable_disclaimer: bool = True, + ) -> ClientRegression: + client = ClientRegression( + client_path=client_path, + admin_client_path=admin_client_path, + host=host, + base_dir=base_dir, + rpc_port=rpc_port, + use_tls=use_tls, + endpoint=endpoint, + mode=mode, + disable_disclaimer=disable_disclaimer, + ) + return client + + sandbox.add_node( + 1, client_factory=reg_client_factory, params=constants.NODE_PARAMS + ) + client = sandbox.client(1) + parameters = protocol.get_parameters() + parameters['consensus_threshold'] = 0 + protocol.activate(client, activate_in_the_past=True, parameters=parameters) + yield client + + +@pytest.fixture(scope="class") +def clients(sandbox: Sandbox, request) -> Iterator[List[Client]]: + """N node with protocol 012. Parameterized by the number of nodes. + + Number of nodes is specified as a class annotation. + @pytest.mark.parametrize('clients', [N], indirect=True) + + Activate protocol 012 one year in the past. (see fixture client). + """ + assert request.param is not None + num_nodes = request.param + for i in range(num_nodes): + # Large number may increases peers connection time + sandbox.add_node(i, params=constants.NODE_PARAMS) + parameters = protocol.get_parameters() + parameters['consensus_threshold'] = 0 + parameters['minimal_block_delay'] = '1' + parameters['delay_increment_per_round'] = '1' + protocol.activate( + sandbox.client(0), parameters=parameters, activate_in_the_past=True + ) + + clients = sandbox.all_clients() + for client in clients: + proto = protocol.HASH + assert utils.check_protocol(client, proto) + yield clients + + +@pytest.fixture +def mockup_client(sandbox: Sandbox) -> Iterator[Client]: + """ + Returns a mockup client with its persistent directory created + + This is done in two steps, because we want to create the mockup + with a client that doesn't have "--mode mockup" (as per + the public documentation) but we want to return a + client that has "--mode mockup" and uses the base-dir created + in the first step. + + There is no way around this pattern. If you want to create + a mockup using custom arguments; you MUST do the same + as this method. + """ + with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: + unmanaged_client = sandbox.create_client(base_dir=base_dir) + res = unmanaged_client.create_mockup( + protocol=protocol.HASH + ).create_mockup_result + assert res == CreateMockupResult.OK + yield sandbox.create_client(base_dir=base_dir, mode="mockup") diff --git a/tests_python/tests_012/contract_paths.py b/tests_python/tests_012/contract_paths.py new file mode 100644 index 000000000000..351ddf8caa24 --- /dev/null +++ b/tests_python/tests_012/contract_paths.py @@ -0,0 +1,20 @@ +from os import path +from typing import List +from tools import paths + + +def all_contracts(directories: List[str] = None) -> List[str]: + return paths.all_contracts(CONTRACT_PATH, directories) + + +def all_legacy_contracts() -> List[str]: + return all_contracts(['legacy']) + + +CONTRACT_PATH = path.join(paths.TEZOS_HOME, 'tests_python', 'contracts_012') +ATTIC_CONTRACT_PATH = path.join(CONTRACT_PATH, 'attic') +MACROS_CONTRACT_PATH = path.join(CONTRACT_PATH, 'macros') +ILLTYPED_CONTRACT_PATH = path.join(CONTRACT_PATH, 'ill_typed') +LEGACY_CONTRACT_PATH = path.join(CONTRACT_PATH, 'legacy') +OPCODES_CONTRACT_PATH = path.join(CONTRACT_PATH, 'opcodes') +MINI_SCENARIOS_CONTRACT_PATH = path.join(CONTRACT_PATH, 'mini_scenarios') diff --git a/tests_python/tests_012/per_block_vote_files/false.json b/tests_python/tests_012/per_block_vote_files/false.json new file mode 100644 index 000000000000..af74e026a98a --- /dev/null +++ b/tests_python/tests_012/per_block_vote_files/false.json @@ -0,0 +1 @@ +{"liquidity_baking_escape_vote": false} diff --git a/tests_python/tests_012/per_block_vote_files/invalid.json b/tests_python/tests_012/per_block_vote_files/invalid.json new file mode 100644 index 000000000000..200b380f75f3 --- /dev/null +++ b/tests_python/tests_012/per_block_vote_files/invalid.json @@ -0,0 +1 @@ +{"liquidity_baking_escape_vote": true diff --git a/tests_python/tests_012/per_block_vote_files/non_boolean.json b/tests_python/tests_012/per_block_vote_files/non_boolean.json new file mode 100644 index 000000000000..a5de5f628964 --- /dev/null +++ b/tests_python/tests_012/per_block_vote_files/non_boolean.json @@ -0,0 +1 @@ +{"liquidity_baking_escape_vote": "true"} diff --git a/tests_python/tests_012/per_block_vote_files/true.json b/tests_python/tests_012/per_block_vote_files/true.json new file mode 100644 index 000000000000..cc092c95ad99 --- /dev/null +++ b/tests_python/tests_012/per_block_vote_files/true.json @@ -0,0 +1 @@ +{"liquidity_baking_escape_vote": true} diff --git a/tests_python/tests_012/per_block_vote_files/wrong_key.json b/tests_python/tests_012/per_block_vote_files/wrong_key.json new file mode 100644 index 000000000000..37863375f220 --- /dev/null +++ b/tests_python/tests_012/per_block_vote_files/wrong_key.json @@ -0,0 +1 @@ +{"liquidity_baking_escape": true } diff --git a/tests_python/tests_012/protocol.py b/tests_python/tests_012/protocol.py new file mode 100644 index 000000000000..138aaec40312 --- /dev/null +++ b/tests_python/tests_012/protocol.py @@ -0,0 +1,69 @@ +import datetime +from enum import Enum, auto +from typing import Optional +from copy import deepcopy +from tools import constants, utils + +HASH = constants.ITHACA +DAEMON = constants.ITHACA_DAEMON +PARAMETERS = constants.ITHACA_PARAMETERS + +TENDERBAKE_PARAMETERS = deepcopy(PARAMETERS) +TENDERBAKE_PARAMETERS['consensus_threshold'] = 45 +TENDERBAKE_PARAMETERS['consensus_committee_size'] = 67 + +FOLDER = constants.ITHACA_FOLDER + +PREV_HASH = constants.HANGZHOU +PREV_DAEMON = constants.HANGZHOU_DAEMON +PREV_PARAMETERS = constants.HANGZHOU_PARAMETERS + + +def activate( + client, + parameters=PARAMETERS, + proto=HASH, + timestamp=None, + activate_in_the_past=False, +): + utils.activate_protocol( + client, proto, parameters, timestamp, activate_in_the_past + ) + + +class Protocol(Enum): + CURRENT = auto() + PREV = auto() + + +def get_parameters(protocol: Optional[Protocol] = Protocol.CURRENT): + """ + Args: + protocol (Protocol): protocol id (either CURRENT or PREV). + Defaults to CURRENT + + Returns: + A fresh copy of the protocol parameters w.r.t to protocol + """ + # deepcopy call prevents any unforeseen and unwanted side effects + # on the array parameters + # e.g., bootstrap_accounts, commitments, endorsement_reward + return deepcopy( + dict((PARAMETERS if protocol is Protocol.CURRENT else PREV_PARAMETERS)) + ) + + +def get_now(client) -> str: + """Returns the timestamp of next-to-last block, + offset by the minimum time between blocks""" + + timestamp_date = client.get_block_timestamp(block='head~1') + + constants = client.rpc('get', '/chains/main/blocks/head/context/constants') + + delta = datetime.timedelta(seconds=int(constants['minimal_block_delay'])) + + now_date = timestamp_date + delta + + rfc3399_format = "%Y-%m-%dT%H:%M:%SZ" + return now_date.strftime(rfc3399_format) diff --git a/tests_python/tests_012/test_accuser.py b/tests_python/tests_012/test_accuser.py new file mode 100644 index 000000000000..1104ed5c67c0 --- /dev/null +++ b/tests_python/tests_012/test_accuser.py @@ -0,0 +1,126 @@ +import time + +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox +from . import protocol + + +NUM_NODES = 2 + + +@pytest.mark.multinode +@pytest.mark.incremental +class TestAccuser: + """Constructs a double endorsement, and lets the accuser inject + the evidence.""" + + def test_init(self, sandbox: Sandbox): + for i in range(NUM_NODES): + sandbox.add_node(i, params=constants.NODE_PARAMS) + protocol.activate(sandbox.client(0), activate_in_the_past=True) + # We inject 3 blocks so that the double-endorsement-evidence operation + # is always branched from a known predecessor. (If the level of the + # evidence is smaller than 5, then the operation is branched from the + # head; however the node might change branch, and then the operation + # becomes invalid, namely "branch refused".) + for i in range(3): + utils.bake(sandbox.client(0)) + + def test_level(self, sandbox: Sandbox): + level = 4 + for client in sandbox.all_clients(): + assert utils.check_level(client, level) + + def test_terminate_node_1(self, sandbox: Sandbox): + sandbox.node(1).terminate() + + def test_bake_node_0(self, sandbox: Sandbox): + """Client 0 bakes block A at level 5, not communicated to node 1. + Inject an operation (transfer) to ensure a different hash""" + sandbox.client(0).transfer(1, 'bootstrap4', 'bootstrap5') + sandbox.client(0).propose( + delegates=['bootstrap1'], args=['--minimal-timestamp'] + ) + + def test_endorse_node_0(self, sandbox: Sandbox, session: dict): + """bootstrap1 builds an endorsement for block A""" + client = sandbox.client(0) + client.run(["endorse", "for", 'bootstrap3', '--force']) + mempool = client.get_mempool() + endorsement = mempool['applied'][0] + session['endorsement1'] = endorsement + utils.bake(client, bake_for='bootstrap2') + + def test_terminate_node_0(self, sandbox: Sandbox): + sandbox.node(0).terminate() + + def test_restart_node_1(self, sandbox: Sandbox): + sandbox.node(1).run() + assert sandbox.client(1).check_node_listening() + + def test_start_accuser(self, sandbox: Sandbox): + sandbox.add_accuser(1, proto=protocol.DAEMON) + # We make sure that there is enough time for the accuser to start + # listing to the node's block stream, otherwise the accuser might miss + # the next two blocks. + time.sleep(2) + + def test_bake_node_1(self, sandbox: Sandbox): + """Client 1 bakes block B at level 5, not communicated to node 0""" + sandbox.client(1).propose( + delegates=['bootstrap1'], args=['--minimal-timestamp'] + ) + + def test_endorse_node_2(self, sandbox: Sandbox, session: dict): + """bootstrap1 builds an endorsement for block B, which is included in + a new block at level 6 by bootstrap2""" + client = sandbox.client(1) + client.run(["endorse", "for", 'bootstrap3', "--force"]) + mempool = client.get_mempool() + endorsement = mempool['applied'][0] + session['endorsement2'] = endorsement + utils.bake(client, bake_for='bootstrap2') + mempool = client.get_mempool() + client.get_operations("4") + + def test_restart_node_0(self, sandbox: Sandbox): + sandbox.node(0).run() + sandbox.client(0).check_node_listening() + + def test_check_level(self, sandbox: Sandbox): + """All nodes are at level 6, head is either block A or B""" + level = 6 + for client in sandbox.all_clients(): + assert utils.check_level(client, level) + + def test_bake_block(self, sandbox: Sandbox): + """Bake a block on node 0, which makes the chain on node 0 longer; in + this way, we make sure that node 1 sees the block at level 6, + which containts the conflicting endorsement. + """ + utils.bake(sandbox.client(0)) + + @pytest.mark.xfail(reason="Works locally - CI fails") + def test_double_baking_evidence_generated(self, sandbox: Sandbox): + """Check that a double baking evidence operation is in the + mempool of node 1 or in the block at level 7, depending on + whether the double endorsement operation has reached node 1 + before or after node 1 sees the block at level 7. + """ + in_mempool = False + in_block = False + + mempool = sandbox.client(1).get_mempool() + applied = mempool['applied'] + evidence_kind = "double_baking_evidence" + + if len(applied) > 0 and len(applied[0]['contents']) > 0: + in_mempool = applied[0]['contents'][0]['kind'] == evidence_kind + + if not in_mempool: + ops = sandbox.client(1).get_operations() + if len(ops[2]) > 0 and len(ops[2][0]['contents']) > 0: + in_block = ops[2][0]['contents'][0]['kind'] == evidence_kind + + assert in_mempool or in_block diff --git a/tests_python/tests_012/test_baker_endorser.py b/tests_python/tests_012/test_baker_endorser.py new file mode 100644 index 000000000000..e5747f5f8516 --- /dev/null +++ b/tests_python/tests_012/test_baker_endorser.py @@ -0,0 +1,113 @@ +import itertools +import random +import time +import subprocess +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox +from . import protocol + +random.seed(42) +KEYS = [f'bootstrap{i}' for i in range(1, 6)] +NEXT_KEY = itertools.cycle(KEYS) +NUM_NODES = 5 +NEW_NODES = 5 +REPLACE = False +NUM_CYCLES = 60 +TIME_BETWEEN_CYCLE = 2 +assert NEW_NODES <= NUM_CYCLES + + +def random_op(client): + sender = next(NEXT_KEY) + dest = random.choice([key for key in KEYS if key != sender]) + amount = random.randrange(10000) + return client.transfer(amount, sender, dest) + + +@pytest.mark.baker +@pytest.mark.endorser +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +class TestAllDaemonsWithOperations: + """Runs two baker and two endorsers, generates random op, and + add (or replace) new nodes dynamically. After a little while, + we kill the bakers and check everyone synchronize to the same head.""" + + def test_setup_network(self, sandbox: Sandbox): + parameters = protocol.get_parameters() + # each priority has a delay of 1 sec + # parameters["time_between_blocks"] = ["1"] + for i in range(NUM_NODES): + sandbox.add_node(i, params=constants.NODE_PARAMS) + protocol.activate(sandbox.client(0), parameters=parameters) + time.sleep(3) + for i in range(NUM_NODES - 1): + sandbox.add_baker(i, [f'bootstrap{5 - i}'], protocol.DAEMON) + + def test_wait_for_protocol(self, sandbox: Sandbox): + clients = sandbox.all_clients() + for client in clients: + proto = protocol.HASH + assert utils.check_protocol(client, proto) + + def test_network_gen_operations_and_add_nodes( + self, sandbox: Sandbox, session + ): + node_add_period = NUM_CYCLES // NEW_NODES + for cycle in range(NUM_CYCLES): + i = random.randrange(NUM_NODES) + client = sandbox.client(i) + try: + transfer = random_op(client) + session[f'op{cycle}'] = transfer.operation_hash + except subprocess.CalledProcessError: + # some operations may be invalid, e.g. the client sends + # several operation with the same counter + print('# IGNORED INVALID OPERATION') + + if cycle % node_add_period == 0: + # add node + running_nodes = list(sandbox.nodes.keys()) + new_node = max(running_nodes) + 1 + if REPLACE: + running_nodes.remove(0) + running_nodes.remove(1) + sandbox.rm_node(random.choice(running_nodes)) + sandbox.add_node(new_node, params=constants.NODE_PARAMS) + proto = protocol.HASH + assert utils.check_protocol(sandbox.client(new_node), proto) + time.sleep(TIME_BETWEEN_CYCLE) + + def test_kill_baker(self, sandbox: Sandbox): + for i in range(NUM_NODES - 1): + sandbox.rm_baker(i, proto=protocol.DAEMON) + + def test_synchronize(self, sandbox: Sandbox): + utils.synchronize(sandbox.all_clients()) + + @pytest.mark.xfail(reason="Not enough time to reach level?") + def test_progress(self, sandbox: Sandbox): + level = sandbox.client(0).get_level() + assert level >= 5 + + def test_check_operations(self, sandbox: Sandbox): + min_level = min( + [client.get_level() for client in sandbox.all_clients()] + ) + heads_hash = set() + # check there is exactly one head + for client in sandbox.all_clients(): + block_hash = utils.get_block_hash(client, min_level) + heads_hash.add(block_hash) + assert len(heads_hash) == 1 + # TODO check for operations inclusion + + def test_check_logs(self, sandbox: Sandbox): + if not sandbox.log_dir: + pytest.skip() + assert sandbox.logs + # TODO check more things in the log! endorsement, baking... + error_pattern = r"Uncaught|registered" + assert utils.check_logs(sandbox.logs, error_pattern) diff --git a/tests_python/tests_012/test_basic.py b/tests_python/tests_012/test_basic.py new file mode 100644 index 000000000000..f40471aa5bfd --- /dev/null +++ b/tests_python/tests_012/test_basic.py @@ -0,0 +1,503 @@ +from os import path +from typing import List +import pytest +from client.client import Client +from tools import constants, utils +from tools.paths import ACCOUNT_PATH +from tools.utils import assert_run_failure +from .contract_paths import CONTRACT_PATH + + +BAKE_ARGS: List[str] = [] +TRANSFER_ARGS = ['--burn-cap', '0.257'] + + +@pytest.mark.incremental +class TestRawContext: + def test_delegates(self, client: Client): + path = '/chains/main/blocks/head/context/raw/bytes/delegates/?depth=2' + res = client.rpc('get', path) + expected = { + "ed25519": { + "02298c03ed7d454a101eb7022bc95f7e5f41ac78": None, + "a9ceae0f8909125492a7c4700acc59274cc6c846": None, + "c55cf02dbeecc978d9c84625dcae72bb77ea4fbd": None, + "dac9f52543da1aed0bc1d6b46bf7c10db7014cd6": None, + "e7670f32038107a59a2b9cfefae36ea21f5aa63c": None, + } + } + assert res == expected + + def test_no_service_1(self, client: Client): + path = '/chains/main/blocks/head/context/raw/bytes/non-existent' + with assert_run_failure('No service found at this URL'): + client.rpc('get', path) + + def test_no_service_2(self, client: Client): + path = ( + '/chains/main/blocks/head/context/raw/bytes/' + 'non-existent?depth=-1' + ) + expected = r'Failed to parse argument \'depth\' \("-1"\)' + with assert_run_failure(expected): + client.rpc('get', path) + + def test_no_service_3(self, client: Client): + path = '/chains/main/blocks/head/context/raw/bytes/non-existent?depth=0' + with assert_run_failure('No service found at this URL'): + client.rpc('get', path) + + def test_bake(self, client: Client): + utils.bake(client, 'bootstrap4') + + @pytest.mark.parametrize( + "identity, message, expected_signature", + [ + ( + 'bootstrap1', + 'msg1', + 'edsigtz68o4FdbpvycnAMDLaa7hpmmhjDx' + 'hx4Zu3QWHLYJtcY1mVhW9m6CCvsciFXwf1' + 'zLmah8fJP51cqaeaciBPGy5osH11AnR', + ), + ( + 'bootstrap2', + 'msg2', + 'edsigtZqhR5SW6vbRSmqwzfS1KiJZLYLe' + 'FhLcCEw7WxjBDxotVx83M2rLe4Baq52SUT' + 'jxfXhQ5J3TabCwqt78kNpoU8j42GDEk4', + ), + ( + 'bootstrap3', + 'msg3', + 'edsigu2PvAWxVYY3jQFVfBRW2Dg61xZMN' + 'esHiNbwCTmpJSyfcJMW8Ch9WABHqsgHQRB' + 'aSs6zZNHVGXfHSBnGCxT9x2b49L2zpMW', + ), + ( + 'bootstrap4', + 'msg4', + 'edsigu5jieost8eeD3JwVrpPuSnKzLLvR3' + 'aqezLPDTvxC3p41qwBEpxuViKriipxig5' + '2NQmJ7AFXTzhM3xgKM2ZaADcSMYWztuJ', + ), + ], + ) + def test_sign_message(self, client, identity, message, expected_signature): + assert client.sign_message(message, identity) == expected_signature + + @pytest.mark.parametrize( + "identity, message, signature", + [ + ( + 'bootstrap1', + 'msg1', + 'edsigtz68o4FdbpvycnAMDLaa7hpmmhjDx' + 'hx4Zu3QWHLYJtcY1mVhW9m6CCvsciFXwf1' + 'zLmah8fJP51cqaeaciBPGy5osH11AnR', + ), + ( + 'bootstrap2', + 'msg2', + 'edsigtZqhR5SW6vbRSmqwzfS1KiJZLYLe' + 'FhLcCEw7WxjBDxotVx83M2rLe4Baq52SUT' + 'jxfXhQ5J3TabCwqt78kNpoU8j42GDEk4', + ), + ( + 'bootstrap3', + 'msg3', + 'edsigu2PvAWxVYY3jQFVfBRW2Dg61xZMN' + 'esHiNbwCTmpJSyfcJMW8Ch9WABHqsgHQRB' + 'aSs6zZNHVGXfHSBnGCxT9x2b49L2zpMW', + ), + ( + 'bootstrap4', + 'msg4', + 'edsigu5jieost8eeD3JwVrpPuSnKzLLvR3' + 'aqezLPDTvxC3p41qwBEpxuViKriipxig5' + '2NQmJ7AFXTzhM3xgKM2ZaADcSMYWztuJ', + ), + ], + ) + def test_check_message(self, client, identity, message, signature): + assert client.check_message(message, identity, signature) + + @pytest.mark.parametrize( + "identity, message, head_block", + [ + ("bootstrap1", "msg1", False), + ("bootstrap2", "msg2", False), + ("bootstrap3", "msg3", True), + ("bootstrap4", "msg4", True), + ], + ) + def test_fail_inject_signed_arbitrary_ope( + self, client, identity, message, head_block + ): + if head_block: + signature = client.sign_message(message, identity, block="head") + else: + signature = client.sign_message(message, identity) + chain_id = client.rpc('get', '/chains/main/chain_id') + head_hash = client.rpc('get', '/chains/main/blocks/head/hash') + run_json = { + 'operation': { + "branch": head_hash, + "contents": [{"kind": "failing_noop", "arbitrary": message}], + 'signature': signature, + }, + 'chain_id': chain_id, + } + run_operation_path = ( + '/chains/main/blocks/head/helpers/scripts/run_operation' + ) + with assert_run_failure( + 'The failing_noop operation cannot be executed by the protocol' + ): + client.rpc('post', run_operation_path, data=run_json) + + def test_gen_keys(self, client: Client, session): + session['keys'] = ['foo', 'bar', 'boo'] + sigs = [None, 'secp256k1', 'ed25519'] + for key, sig in zip(session['keys'], sigs): + args = [] if sig is None else ['--sig', sig] + client.gen_key(key, args) + + def test_transfers(self, client: Client, session): + client.transfer(1000, 'bootstrap1', session['keys'][0], TRANSFER_ARGS) + utils.bake(client) + client.transfer(2000, 'bootstrap1', session['keys'][1], TRANSFER_ARGS) + utils.bake(client) + client.transfer(3000, 'bootstrap1', session['keys'][2], TRANSFER_ARGS) + utils.bake(client) + + def test_balances(self, client: Client, session): + assert client.get_balance(session['keys'][0]) == 1000 + assert client.get_balance(session['keys'][1]) == 2000 + assert client.get_balance(session['keys'][2]) == 3000 + + def test_transfer_bar_foo(self, client: Client, session): + client.reveal(session['keys'][1], ['--fee', '0', '--force-low-fee']) + utils.bake(client) + client.transfer( + 1000, + session['keys'][1], + session['keys'][0], + ['--fee', '0', '--force-low-fee'], + ) + utils.bake(client) + + def test_balances_bar_foo(self, client: Client, session): + assert client.get_balance(session['keys'][0]) == 2000 + assert client.get_balance(session['keys'][1]) == 1000 + + def test_transfer_foo_bar(self, client: Client, session): + client.reveal(session['keys'][0], ['--fee', '0', '--force-low-fee']) + utils.bake(client) + client.transfer( + 1000, session['keys'][0], session['keys'][1], ['--fee', '0.05'] + ) + utils.bake(client) + + def test_balances_foo_bar(self, client: Client, session): + # 999.95 = 1000 - transfer fees + assert client.get_balance(session['keys'][0]) == 999.95 + assert client.get_balance(session['keys'][1]) == 2000 + + def test_transfer_failure(self, client: Client, session): + with pytest.raises(Exception): + client.transfer(999.95, session['keys'][0], session['keys'][1]) + + def test_originate_contract_noop(self, client: Client): + contract = path.join(CONTRACT_PATH, 'opcodes', 'noop.tz') + client.remember('noop', contract) + client.typecheck(contract) + client.originate( + 'noop', 1000, 'bootstrap1', contract, ['--burn-cap', '0.295'] + ) + utils.bake(client) + + def test_transfer_to_noop(self, client: Client): + client.transfer(10, 'bootstrap1', 'noop', ['--arg', 'Unit']) + utils.bake(client) + + def test_contract_hardlimit(self, client: Client): + contract = path.join(CONTRACT_PATH, 'mini_scenarios', 'hardlimit.tz') + client.originate( + 'hardlimit', + 1000, + 'bootstrap1', + contract, + ['--init', '3', '--burn-cap', '0.341'], + ) + utils.bake(client) + client.transfer(10, 'bootstrap1', 'hardlimit', ['--arg', 'Unit']) + utils.bake(client) + client.transfer(10, 'bootstrap1', 'hardlimit', ['--arg', 'Unit']) + utils.bake(client) + + def test_transfers_bootstraps5_bootstrap1(self, client: Client): + bootstrap5 = constants.IDENTITIES['bootstrap5']['identity'] + all_deposits = client.frozen_deposits(bootstrap5) + balance = client.get_mutez_balance('bootstrap5') + assert balance + all_deposits == utils.mutez_of_tez(4000000.0) + client.transfer( + 400000, + 'bootstrap5', + 'bootstrap1', + ['--fee', '0', '--force-low-fee'], + ) + utils.bake(client) + client.transfer( + 400000, + 'bootstrap1', + 'bootstrap5', + ['--fee', '0', '--force-low-fee'], + ) + utils.bake(client) + all_deposits = client.frozen_deposits(bootstrap5) + assert client.get_mutez_balance( + 'bootstrap5' + ) + all_deposits == utils.mutez_of_tez(4000000.0) + + def test_activate_accounts(self, client: Client, session): + account = f"{ACCOUNT_PATH}/king_commitment.json" + session['keys'] += ['king', 'queen'] + client.activate_account(session['keys'][3], account) + utils.bake(client) + account = f"{ACCOUNT_PATH}/queen_commitment.json" + client.activate_account(session['keys'][4], account) + utils.bake(client) + assert client.get_balance(session['keys'][3]) == 23932454.669343 + assert client.get_balance(session['keys'][4]) == 72954577.464032 + + def test_transfer_king_queen(self, client: Client, session): + keys = session['keys'] + client.transfer(10, keys[3], keys[4], TRANSFER_ARGS) + utils.bake(client) + + def test_duplicate_alias(self, client: Client): + client.add_address("baz", "foo", force=True) + show_foo = client.show_address("foo", show_secret=True) + assert show_foo.secret_key is not None + + +@pytest.mark.incremental +class TestRememberContract: + @pytest.mark.parametrize( + "contract_name,non_originated_contract_address", + [ + ("test", "KT1BuEZtb68c1Q4yjtckcNjGELqWt56Xyesc"), + ("test-2", "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9"), + ], + ) + def test_non_originated_contract_no_forcing_not_saved_before( + self, + client, + contract_name, + non_originated_contract_address, + ): + client.remember_contract(contract_name, non_originated_contract_address) + + # As it is always the same client, the contracts have been saved + # before + @pytest.mark.parametrize( + "contract_name,non_originated_contract_address", + [ + ("test", "KT1BuEZtb68c1Q4yjtckcNjGELqWt56Xyesc"), + ("test-2", "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9"), + ], + ) + def test_non_originated_contract_with_forcing_and_saved_before( + self, + client, + contract_name, + non_originated_contract_address, + ): + client.remember_contract( + contract_name, non_originated_contract_address, force=True + ) + + # As it is always the same client, the contracts have been saved + # before + @pytest.mark.parametrize( + "contract_name,non_originated_contract_address", + [ + ("test", "KT1BuEZtb68c1Q4yjtckcNjGELqWt56Xyesc"), + ("test-2", "KT1TZCh8fmUbuDqFxetPWC2fsQanAHzLx4W9"), + ], + ) + def test_non_originated_contract_no_forcing_and_saved_before( + self, + client, + contract_name, + non_originated_contract_address, + ): + expected_error = f"The contract alias {contract_name} already exists" + + with assert_run_failure(expected_error): + client.remember_contract( + contract_name, non_originated_contract_address, force=False + ) + + # Test operation size. + def test_operation_size_originate_byte_contract(self, client: Client): + contract = path.join(CONTRACT_PATH, 'opcodes', 'bytes.tz') + client.remember('bytes', contract) + client.typecheck(contract) + client.originate( + 'bytes', 1000, 'bootstrap1', contract, ['--burn-cap', '0.295'] + ) + utils.bake(client) + + # Test that operations under 16KB can be injected in the node. + def test_operation_size_small(self, client: Client): + bytes_arg = "0x" + ("00" * 6 * 1024) # 6 KB of data. + + client.transfer(10, 'bootstrap1', 'bytes', ['--arg', bytes_arg]) + utils.bake(client) + + # Test that operations between 16KB and 32KB can be injected in the node. + def test_operation_size_medium(self, client: Client): + bytes_arg = "0x" + ("00" * 24 * 1024) # 24 KB of data. + + client.transfer(10, 'bootstrap1', 'bytes', ['--arg', bytes_arg]) + utils.bake(client) + + # Test that operations above 32KB fail to be injected. + def test_operation_size_oversized(self, client: Client): + bytes_arg = "0x" + ("00" * 36 * 1024) # 36 KB of data. + + expected_error = "Oversized operation" + with assert_run_failure(expected_error): + client.transfer(10, 'bootstrap1', 'bytes', ['--arg', bytes_arg]) + + # Test operation size with various data types. + def test_operation_size_originate_munch_contract(self, client: Client): + contract = path.join(CONTRACT_PATH, 'opcodes', 'munch.tz') + client.remember('munch', contract) + client.typecheck(contract) + client.originate( + 'munch', 1000, 'bootstrap1', contract, ['--burn-cap', '0.295'] + ) + utils.bake(client) + + # Test that a large operation under 32KB can be injected in the node + # (variant using a lambda with deep nesting). + def test_operation_size_with_lambda_ok(self, client: Client): + # Each pair of braces is encoded on 5 bytes so this takes + # 5 * 6 * 1024 = 30 KB < 32KB + big_arg = ("{" * 6 * 1024) + ("}" * 6 * 1024) + + client.transfer( + 10, + 'bootstrap1', + 'munch', + ['--arg', big_arg, "--entrypoint", "lambda"], + ) + utils.bake(client) + + # Test that a large operation over 32KB cannot be injected in the node, + # and the error is not a stack overflow + # (variant using a lambda with deep nesting). + def test_operation_size_with_lambda_fail(self, client: Client): + # Each pair of braces is encoded on 5 bytes so this takes + # 5 * 7 * 1024 = 35 KB > 32KB + big_arg = ("{" * 7 * 1024) + ("}" * 7 * 1024) + + expected_error = "Oversized operation" + with assert_run_failure(expected_error): + client.transfer( + 10, + 'bootstrap1', + 'munch', + ['--arg', big_arg, "--entrypoint", "lambda"], + ) + + # Test that a large operation under 32KB can be injected in the node + # (variant using a long list). + def test_operation_size_with_list_ok(self, client: Client): + # Each element in the list takes 2 bytes so about 30KB in total + big_arg = "{" + ("0; " * 15 * 1024) + "}" + + client.transfer( + 10, + 'bootstrap1', + 'munch', + ['--arg', big_arg, "--entrypoint", "list_nat"], + ) + utils.bake(client) + + def test_operation_size_with_list_syntax_error(self, client: Client): + # Each element in the list takes 2 bytes so about 30KB in total + big_arg = "{" + ("0; " * 15 * 1024) + "'foo;'" + "}" + + expected_error = "transfer simulation failed" + with assert_run_failure(expected_error): + client.transfer( + 10, + 'bootstrap1', + 'munch', + ['--arg', big_arg, "--entrypoint", "list_nat"], + ) + + def test_operation_size_with_list_ill_typed(self, client: Client): + # Each element in the list takes 2 bytes so about 30KB in total + big_arg = "{" + ("0; " * 15 * 1024) + "Unit;" + "}" + + expected_error = "transfer simulation failed" + with assert_run_failure(expected_error): + client.transfer( + 10, + 'bootstrap1', + 'munch', + ['--arg', big_arg, "--entrypoint", "list_nat"], + ) + + # Test that a large operation over 32KB cannot be injected in the node, + # and the error is not a stack overflow + # (variant using a long list). + def test_operation_size_with_list_fail(self, client: Client): + # Each element in the list takes 2 bytes so about 34KB in total + big_arg = "{" + ("0; " * 17 * 1024) + "}" + + expected_error = "Oversized operation" + with assert_run_failure(expected_error): + client.transfer( + 10, + 'bootstrap1', + 'munch', + ['--arg', big_arg, "--entrypoint", "list_nat"], + ) + + # Test that a large operation under 32KB can be injected in the node + # (variant using a big nat). + def test_operation_size_with_nat_ok(self, client: Client): + # The encoding for nat uses a byte to encode 7 bits of the number + # so the size of 2 ** (7 * n) is about n bytes + big_arg = 2 ** (7 * 30 * 1024) + + client.transfer( + 10, + 'bootstrap1', + 'munch', + ['--arg', f"{big_arg}", "--entrypoint", "nat"], + ) + utils.bake(client) + + # Test that a large operation over 32KB cannot be injected in the node, + # and the error is not a stack overflow + # (variant using a big nat). + def test_operation_size_with_nat_fail(self, client: Client): + # The encoding for nat uses a byte to encode 7 bits of the number + # so the size of 2 ** (7 * n) is about n bytes + big_arg = 2 ** (7 * 33 * 1024) + + expected_error = "Oversized operation" + with assert_run_failure(expected_error): + client.transfer( + 10, + 'bootstrap1', + 'munch', + ['--arg', f"{big_arg}", "--entrypoint", "nat"], + ) diff --git a/tests_python/tests_012/test_binaries.py b/tests_python/tests_012/test_binaries.py new file mode 100644 index 000000000000..63cb9934746d --- /dev/null +++ b/tests_python/tests_012/test_binaries.py @@ -0,0 +1,48 @@ +""" +Tests common utility functionality of binaries shipped with Tezos. +""" + +import subprocess +from typing import List + +from process import process_utils +from tools import paths +from . import protocol + + +PROTO_BINARIES = [ + binary + "-" + protocol.DAEMON + for binary in ["tezos-baker", "tezos-accuser"] +] + +BINARIES = [ + "tezos-codec", + "tezos-client", + "tezos-admin-client", + "tezos-protocol-compiler", + "tezos-node", + "tezos-snoop", + "tezos-validator", +] + PROTO_BINARIES + + +def run_cmd(cmd: List[str]) -> str: + """Pretty print a command. Execute it, print and return its standard + output.""" + print(process_utils.format_command(cmd)) + process_ret = subprocess.run( + cmd, check=True, capture_output=True, text=True + ) + print(process_ret.stdout) + return process_ret.stdout.strip() + + +class TestBinaries: + def test_version(self): + """Tests that all binaries accept the --version flag and that the + report the same version""" + versions = set() + for binary in BINARIES: + version = run_cmd([paths.TEZOS_HOME + binary, "--version"]) + versions.add(version) + assert len(versions) == 1, "All binaries should report the same version" diff --git a/tests_python/tests_012/test_bootstrap.py b/tests_python/tests_012/test_bootstrap.py new file mode 100644 index 000000000000..c817b0354534 --- /dev/null +++ b/tests_python/tests_012/test_bootstrap.py @@ -0,0 +1,221 @@ +import time + +import pytest +from launchers.sandbox import Sandbox +from . import protocol + +LOG_LEVEL = {"validator.chain": "debug", "validator.peer": "debug"} + + +def params(threshold=0, latency=3): + return [ + '--sync-latency', + str(latency), + '--synchronisation-threshold', + str(threshold), + '--connections', + '100', + ] + + +def add_fully_delegated_baker(sandbox: Sandbox, node: int, protocol: str): + """Add a baker that has all known bootstrap accounts delegated to it.""" + sandbox.add_baker(node, [], proto=protocol) + + +@pytest.mark.baker +@pytest.mark.incremental +class TestThresholdZero: + """Threshold 0, peer always bootstrapped.""" + + def test_setup_network(self, sandbox: Sandbox): + sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) + sandbox.add_baker(0, ['bootstrap5'], proto=protocol.DAEMON) + + def test_bootstrap(self, sandbox: Sandbox): + client = sandbox.client(0) + assert client.sync_state() == 'synced' + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.incremental +class TestThresholdOne: + """First peer has threshold zero, second peer has threshold one""" + + def test_setup_network(self, sandbox: Sandbox): + sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) + protocol.activate(sandbox.client(0)) + sandbox.add_baker(0, ['bootstrap5'], proto=protocol.DAEMON) + + def test_bootstrap(self, sandbox: Sandbox): + client = sandbox.client(0) + assert client.sync_state() == 'synced' + + def test_add_node(self, sandbox: Sandbox): + sandbox.add_node( + 1, params=params(1), log_levels=LOG_LEVEL, config_client=False + ) + sandbox.client(1).bootstrapped() + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.incremental +class TestThresholdTwo: + def test_setup_network(self, sandbox: Sandbox): + sandbox.add_node(0, params=params(0), log_levels=LOG_LEVEL) + protocol.activate(sandbox.client(0)) + time.sleep(3) + sandbox.add_baker(0, ['bootstrap5'], proto=protocol.DAEMON) + + def test_add_nodes(self, sandbox: Sandbox): + sandbox.add_node( + 1, params=params(2), log_levels=LOG_LEVEL, config_client=False + ) + sandbox.add_node( + 2, params=params(2), log_levels=LOG_LEVEL, config_client=False + ) + sandbox.add_node( + 3, params=params(1), log_levels=LOG_LEVEL, config_client=False + ) + + # Some lower timeouts (5, 10) make the test fails. 15 seems to be enough + # If the test fails again, look at increasing this timeout first. + @pytest.mark.timeout(15) + def test_node_3_bootstrapped(self, sandbox: Sandbox): + sandbox.client(3).bootstrapped() + + # See comment for previous test + @pytest.mark.timeout(5) + def test_node_1_bootstrapped(self, sandbox: Sandbox): + sandbox.client(1).bootstrapped() + + +@pytest.mark.slow +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.incremental +class TestStuck: + def test_setup_network(self, sandbox: Sandbox): + sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) + protocol.activate(sandbox.client(0)) + add_fully_delegated_baker(sandbox, 0, protocol.DAEMON) + + def test_kill_baker(self, sandbox: Sandbox): + """Bake a few blocks and kill baker""" + time.sleep(14) + sandbox.rm_baker(0, proto=protocol.DAEMON) + time.sleep(5) + + def test_progress(self, sandbox: Sandbox): + assert sandbox.client(0).get_level() >= 2 + + def test_add_node(self, sandbox: Sandbox): + sandbox.add_node( + 1, params=params(2), config_client=False, log_levels=LOG_LEVEL + ) + sandbox.add_node( + 2, params=params(2), config_client=False, log_levels=LOG_LEVEL + ) + + def test_all_nodes_boostrap(self, sandbox: Sandbox): + """Eventually, 1 and 2 are bootstrapped with the chain stuck. """ + sandbox.client(1).bootstrapped() + sandbox.client(2).bootstrapped() + assert sandbox.client(1).sync_state() == 'stuck' + assert sandbox.client(2).sync_state() == 'stuck' + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.incremental +class TestSplitView: + def test_setup_network(self, sandbox: Sandbox): + sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) + protocol.activate(sandbox.client(0)) + sandbox.add_node( + 1, params=params(), config_client=False, log_levels=LOG_LEVEL + ) + sandbox.add_node( + 2, + params=params(2, latency=15), + config_client=False, + log_levels=LOG_LEVEL, + ) + add_fully_delegated_baker(sandbox, 0, protocol.DAEMON) + + @pytest.mark.timeout(10) + def test_all_nodes_boostrap(self, sandbox: Sandbox): + assert sandbox.client(0).sync_state() == 'synced' + assert sandbox.client(1).sync_state() == 'synced' + sandbox.client(2).bootstrapped() + + def test_pause(self): + time.sleep(2) + + def test_disconnect_node(self, sandbox: Sandbox): + """node 1 is disconnected from baker""" + sandbox.client(1).ban_peer(sandbox.node(0).p2p_port) + sandbox.client(0).ban_peer(sandbox.node(1).p2p_port) + + def test_sync_status(self, sandbox: Sandbox): + assert sandbox.client(0).sync_state() == 'synced' + assert sandbox.client(1).sync_state() == 'synced' + assert sandbox.client(2).sync_state() == 'synced' + + +NUM_NODES = 8 +RUNNING_TIME = 10 + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +class TestManyNodesBootstrap: + """Run many nodes, bake for a while, add a node and check it's bootstrapped + when it should be.""" + + def test_init(self, sandbox: Sandbox): + sandbox.add_node(0, params=params(), log_levels=LOG_LEVEL) + parameters = protocol.get_parameters() + protocol.activate(sandbox.client(0), parameters=parameters) + time.sleep(3) + add_fully_delegated_baker(sandbox, 0, protocol.DAEMON) + sandbox.add_node( + 1, params=params(), log_levels=LOG_LEVEL, config_client=False + ) + + def test_bootstrap(self, sandbox: Sandbox): + sandbox.client(0).bootstrapped() + sandbox.client(1).bootstrapped() + + def test_add_nodes(self, sandbox: Sandbox): + for i in range(2, NUM_NODES): + sandbox.add_node( + i, params=params(), config_client=False, log_levels=LOG_LEVEL + ) + + def test_let_baking(self): + time.sleep(RUNNING_TIME) + + def test_progress(self, sandbox, session): + cur_level = sandbox.client(NUM_NODES - 1).get_level() + assert cur_level > RUNNING_TIME // 2 # check progress + session['cur_level'] = cur_level + + @pytest.mark.timeout(50) + def test_add_one_more_node(self, sandbox, session): + new_node = NUM_NODES + sandbox.add_node( + new_node, + params=params(NUM_NODES), + config_client=False, + log_levels=LOG_LEVEL, + ) + time.sleep(1) + sandbox.client(new_node).p2p_stat() + sandbox.client(new_node).bootstrapped() + cur_level = session['cur_level'] + assert sandbox.client(new_node).get_level() >= cur_level diff --git a/tests_python/tests_012/test_client.py b/tests_python/tests_012/test_client.py new file mode 100644 index 000000000000..f42255fba442 --- /dev/null +++ b/tests_python/tests_012/test_client.py @@ -0,0 +1,35 @@ +import pytest +from client.client import Client +from tools.utils import assert_run_failure, bake + + +@pytest.mark.client +@pytest.mark.incremental +@pytest.mark.usefixtures("encrypted_account_with_tez") +class TestSimulation: + """ Tests the behavior of the --simulation flag. """ + + def test_transfer_simulation(self, client: Client): + """ Tests that --simulation does not ask for the key password. """ + client.transfer( + 0.1, "encrypted_account", "bootstrap1", ["--simulation"] + ) + + def test_transfer_without_simulation(self, client: Client): + """ Tests that the client asks for the password w/o --simulation. """ + with assert_run_failure("End_of_file", mode="stdout"): + client.transfer(0.1, "encrypted_account", "bootstrap1") + + def test_delegate_simulation(self, client: Client): + """ Tests that --simulation does not ask for the key password. """ + client.gen_key("delegate") + client.transfer(100, "bootstrap1", "delegate", ["--burn-cap", "1.0"]) + bake(client, bake_for="bootstrap1") + client.register_delegate("delegate") + bake(client, bake_for="bootstrap1") + client.set_delegate("encrypted_account", "delegate", ["--simulation"]) + + def test_delegate_without_simulation(self, client: Client): + """ Tests that the client asks for the password w/o --simulation. """ + with assert_run_failure("End_of_file", mode="stdout"): + client.set_delegate("encrypted_account", "delegate") diff --git a/tests_python/tests_012/test_client_without_node.py b/tests_python/tests_012/test_client_without_node.py new file mode 100644 index 000000000000..8e5a27bac845 --- /dev/null +++ b/tests_python/tests_012/test_client_without_node.py @@ -0,0 +1,450 @@ +"""Node-less tests for the client. + +Some client tests do not require a node running, nor a +persistent mockup environment. These can be placed here. +""" +import json +import os +import subprocess +import tempfile +from typing import List, Optional +import pytest +from client.client import Client +from tools.utils import assert_run_failure + +# Note that specifying "endpoint" and "web_port" is required +# for the final assertion of test_config_init_roundtrip to pass. That's because +# `config init -o` writes them even if unspecified by `--config-file` +# (it's a fine behavior, I just wanted to highlight it). +_INPUT_CONFIG_FILE = { + "confirmations": 1, + "endpoint": "http://127.0.0.1:8732", + "remote_signer": "http://127.0.0.2", + "web_port": 8080, + "password_filename": "/tmp/doesnt_exist", +} +_INPUT_CONFIG_FILES = [None, _INPUT_CONFIG_FILE] +_CMD_LINE_ARGS = { + "--endpoint": "http://127.0.0.1:9732", + "--wait": "3", + "--remote-signer": "http://10.0.0.2", + "--password-filename": "/tmp/doesnt_exist_either", +} +_CONFIG_FILE_FLAG = "--config-file" + + +@pytest.mark.client +class TestImportKeyMnemonic: + """ Checks that the keys are correctly imported from a mnemonic. """ + + @pytest.fixture + def mnemonic(self): + return ( + "seek paddle siege sting siege sick kidney " + + "detect coral because comfort long enforce napkin enter" + ) + + @pytest.fixture + def passphrase(self): + return "very_secure_passphrase" + + def test_import_simple(self, client: Client): + """ Tests a simple import. """ + mnemonic = "release easy pulp drop select attack false math cook \ +angry spin ostrich round dress acoustic" + prms = ["import", "keys", "from", "mnemonic", "zebra", "--force"] + stdin = mnemonic + "\n\n" + client.run_generic(prms, stdin=stdin) + addr = client.get_known_addresses() + assert addr.wallet["zebra"] == "tz1aGUKE72eN21iWztoDEeH4FeKaxWb7SAUb" + + def test_import_already_present_alias(self, client: Client, mnemonic): + """ Tests that importing fails if the alias is already present. """ + prms = [ + "import", + "keys", + "from", + "mnemonic", + "super_original", + "--force", + ] + stdin = mnemonic + "\n\n" + client.run_generic(prms, stdin=stdin) + prms = ["import", "keys", "from", "mnemonic", "super_original"] + expected_error = "The secret_key alias super_original already exists." + with assert_run_failure(expected_error): + client.run_generic(prms, stdin=stdin) + + def test_import_passphrase(self, client: Client, mnemonic, passphrase): + """ Tests an import where the user specifies a passphrase. """ + stdin = mnemonic + "\n" + passphrase + "\n" + prms = ["import", "keys", "from", "mnemonic", "key", "--force"] + client.run_generic(prms, stdin=stdin) + addr = client.get_known_addresses() + assert addr.wallet["key"] == "tz1QSF4TSVzaosgbaxnFJpRbs7798Skeb8Re" + + def test_encrypted(self, client: Client, mnemonic, passphrase): + """ Tests an import where the user wants to encrypt the key. """ + encrypt_pwd = "imgonnaencryptthiskeysohard" + stdin = ( + mnemonic + + "\n" + + passphrase + + "\n" + + encrypt_pwd + + "\n" + + encrypt_pwd + + "\n" + ) + prms = [ + "import", + "keys", + "from", + "mnemonic", + "cryptkey", + "--encrypt", + "--force", + ] + client.run_generic(prms, stdin=stdin) + addr = client.get_known_addresses() + pkh = addr.wallet["cryptkey"] + secret_key = client.show_address( + "cryptkey", show_secret=True + ).secret_key + assert secret_key is not None + assert secret_key.startswith("encrypted:") + assert pkh == "tz1QSF4TSVzaosgbaxnFJpRbs7798Skeb8Re" + + def test_gen_key_from_menmonic_bad_mnemonic(self, client: Client): + """ Tests that the command fails if the user gives a bad mnemonic. """ + prms = ["import", "keys", "from", "mnemonic", "alias", "--force"] + stdin = "hello\n\n" + expected_error = '"hello" is not a valid BIP39 mnemonic.' + with assert_run_failure(expected_error): + client.run_generic(prms, stdin=stdin) + + +@pytest.mark.usefixtures("encrypted_account_with_tez") +class TestStopLoopPassword: + """Tests that the client stops asking for the password after + three erroneous passwords given by the user""" + + @pytest.mark.parametrize('stdin', ["\n\n\n", "\n\n\nign", "\n\n\npassword"]) + def test_stops_after_three_tries(self, client: Client, stdin): + with assert_run_failure("3 incorrect password attempt"): + client.transfer(0.1, 'encrypted_account', 'bootstrap1', stdin=stdin) + + @pytest.mark.parametrize( + 'stdin', ["password\n", "\npassword\n", "\n\npassword\n"] + ) + def test_password_succeed_before_three_tries(self, client: Client, stdin): + client.transfer(0.1, 'encrypted_account', 'bootstrap1', stdin=stdin) + + +@pytest.mark.client +class TestChainId: + def test_chain_id_block_hash(self, nodeless_client: Client): + block_hash = 'BKyFui5WPY1n3e9aKF3qd2kGBKBtHu3rtm5miYFnUagJC1BdHTF' + prms = ['compute', 'chain', 'id', 'from', 'block', 'hash', block_hash] + assert nodeless_client.run(prms).strip() == 'NetXuwrXPL4VeX5' + + def test_chain_id_seed(self, nodeless_client: Client): + seed = 'choucroute' + prms = ['compute', 'chain', 'id', 'from', 'seed', seed] + assert nodeless_client.run(prms).strip() == 'NetXLGmPi3c5DXf' + + +def _write_config_file( + client: Client, filename: str, config_dict: Optional[dict] +): + """Writes `config_dict` to `filename`. Returns the json effectively + written""" + assert client is not None + assert filename is not None + assert config_dict is not None + + augmented_dict = dict(config_dict) # Copy for safety + # We need to set base_dir, it's required in the config file + augmented_dict["base_dir"] = client.base_dir + with open(filename, 'w') as handle: + json.dump(augmented_dict, handle) + + return augmented_dict + + +def _with_config_file_cmd(config_file: Optional[str], cmd: List[str]): + """Prefixes `cmd` with ["--config-file", config_file] if + config_file is not None""" + return ([_CONFIG_FILE_FLAG, config_file] if config_file else []) + cmd + + +def _gen_assert_msg(flag, sent, received): + result = f"Json sent with --{flag} differs from" + result += " json received" + result += f"\nJson sent is:\n{sent}" + result += f"\nwhile json received is:\n{received}" + + +@pytest.mark.client +@pytest.mark.parametrize('config_dict', _INPUT_CONFIG_FILES) +class TestConfigInit: + def test_config_init( + self, nodeless_client: Client, config_dict: Optional[dict] + ): + """ + Tests that calling + `[--config-file config_dict]? config init -o tmp_file` + works and yields valid json. + """ + try: + out_file = tempfile.mktemp(prefix='tezos-client.config_file') + in_file = None + + if config_dict is not None: + in_file = tempfile.mktemp(prefix='tezos-client.config_file') + _write_config_file(nodeless_client, in_file, config_dict) + + cmd = _with_config_file_cmd( + in_file, ["config", "init", "-o", out_file] + ) + nodeless_client.run(cmd) + # Try loading the file as json, to check it is valid + with open(out_file) as handle: + json.load(handle) + finally: + if in_file is not None: + os.remove(in_file) + os.remove(out_file) + + def test_config_init_roundtrip( + self, nodeless_client: Client, config_dict: Optional[dict] + ): + """Tests that calling `config init -o tmp_file` and + feeding its result to `tezos-client --config-file` works + and yields the same result (i.e. calling `tezos-client + --config-file tmp_file config init -o tmp_file2 yields + a `tmp_file2` that is similar to `tmp_file`). + + `config_dict` specifies the content of the initial config file + to use or None not to specify one. + """ + try: + if config_dict is None: + # Take initial json from default output of `config init` + + tmp_file1 = tempfile.mktemp(prefix='tezos-client.config_file') + cmd = ["config", "init", "-o", tmp_file1] + nodeless_client.run(cmd) + with open(tmp_file1) as handle: + json1 = json.load(handle) + + # Execute an arbitrary effectless command: + list_protos = ["list", "understood", "protocols"] + # This checks that + # `--config-file tmp_file1 arbitrary command` works + cmd = _with_config_file_cmd(tmp_file1, list_protos) + nodeless_client.run(cmd) + else: + # Take initial json from config_dict + + # Write config_dict to a file + tmp_file1 = tempfile.mktemp(prefix='tezos-client.config_file') + json1 = _write_config_file( + nodeless_client, tmp_file1, config_dict + ) + + # Execute `config init -o` + tmp_file2 = tempfile.mktemp(prefix='tezos-client.config_file') + cmd = _with_config_file_cmd( + tmp_file1, ["config", "init", "-o", tmp_file2] + ) + nodeless_client.run(cmd) + + # Load file generated by `config init -o` + with open(tmp_file2) as handle: + json2 = json.load(handle) + + # and finally check that the json generated by `config init -o` + # matches the input data (either the default one or the one + # specified with --config-file) + assert json1 == json2, _gen_assert_msg( + _CONFIG_FILE_FLAG, json1, json2 + ) + finally: + os.remove(tmp_file1) + os.remove(tmp_file2) + + +def _cmd_line_flag_to_json_field(cmd_line_flag: str): + if cmd_line_flag == "--wait": + return "confirmations" + result = cmd_line_flag + if cmd_line_flag.startswith("--"): + result = result[2:] + return result.replace("-", "_") + + +@pytest.mark.client +@pytest.mark.parametrize('config_dict', _INPUT_CONFIG_FILES) +class TestConfigShow: + """ Tests of `tezos-client config show` """ + + def test_config_show( + self, nodeless_client: Client, config_dict: Optional[dict] + ): + """ + Tests that calling `config show` works, with or without + specifying `--config-file` + """ + try: + tmp_file = None + if config_dict is not None: + tmp_file = tempfile.mktemp(prefix='tezos-client.config_file') + _write_config_file(nodeless_client, tmp_file, config_dict) + + cmd = _with_config_file_cmd(tmp_file, ["config", "show"]) + nodeless_client.run(cmd) + finally: + if tmp_file is not None: + os.remove(tmp_file) + + @pytest.mark.parametrize('cmd_line_args', [{}, _CMD_LINE_ARGS]) + def test_config_show_roundtrip( + self, + nodeless_client: Client, + config_dict: Optional[dict], + cmd_line_args: dict, + ): + """ + Tests calling `config show` with or without `--config-file` + and with some command line parameters (`cmd_line_arg`). It + then parses the output to check its valid json and to check + that command line parameters were honored. + + Then it feeds this output to a new call to `--config-file file + config show` and checks that the json returned by this second call + agrees with what was specified by `file`. + + This is a roundtrip test using a small matrix. + """ + try: + in_file1 = None + in_file2 = None + if config_dict is not None: + in_file1 = tempfile.mktemp(prefix='tezos-client.config_file') + _write_config_file(nodeless_client, in_file1, config_dict) + + cmd = [] + # Pass command line parameters + for (flag, value) in cmd_line_args.items(): + cmd += [flag, value] + cmd += ["config", "show"] + cmd = _with_config_file_cmd(in_file1, cmd) + # Take standard output + (stdout, _, _) = nodeless_client.run_generic(cmd) + + output_json1 = json.loads(stdout) + # Verify that command line parameters were honored + for (flag, value) in cmd_line_args.items(): + input_value = cmd_line_args[flag] + assert isinstance(input_value, str) + output_value = output_json1[_cmd_line_flag_to_json_field(flag)] + output_value = str(output_value) + err_msg = ( + f"Value of command line flag {flag} is not honored:" + f" passed {input_value} but" + f" config show yielded {output_value}" + ) + assert output_value == input_value, err_msg + in_file2 = tempfile.mktemp(prefix='tezos-client.config_file') + # Write output of first call to `config show` to disk, + # to pass it to second call below + with open(in_file2, 'w') as handle: + handle.write(json.dumps(output_json1)) + + # Use previous ouput file as input now + cmd = _with_config_file_cmd(in_file2, ["config", "show"]) + (stdout, _, _) = nodeless_client.run_generic(cmd) + + output_json2 = json.loads(stdout) + + # And finally check that the final output matches the input + assert output_json1 == output_json2, _gen_assert_msg( + _CONFIG_FILE_FLAG, output_json1, output_json2 + ) + finally: + for in_file in [in_file1, in_file2]: + if in_file is not None: + os.remove(in_file) + + +@pytest.mark.client +class TestConfigValid: + """ Tests of validity of tezos-client config """ + + def test_config_node_port(self, nodeless_client: Client): + """ + Tests that calling `config show` works, with a valid node port + """ + self._run_config_show_with_node_port(nodeless_client, 8732) + self._run_config_show_with_node_port(nodeless_client, 58732) + pytest.raises( + subprocess.CalledProcessError, + self._run_config_show_with_node_port, + nodeless_client, + 158732, + ) + pytest.raises( + subprocess.CalledProcessError, + self._run_config_show_with_node_port, + nodeless_client, + -8732, + ) + + def test_config_web_port(self, nodeless_client: Client): + """ + Tests that calling `config show` works, with a valid node port + """ + self._run_config_show_with_web_port(nodeless_client, 8732) + self._run_config_show_with_web_port(nodeless_client, 58732) + pytest.raises( + subprocess.CalledProcessError, + self._run_config_show_with_web_port, + nodeless_client, + 158732, + ) + pytest.raises( + subprocess.CalledProcessError, + self._run_config_show_with_web_port, + nodeless_client, + -8732, + ) + + def _run_config_show_with_temp_config_file( + self, nodeless_client: Client, config_dict: dict + ): + try: + tmp_file = tempfile.mktemp(prefix='tezos-client.config_file') + _write_config_file(nodeless_client, tmp_file, config_dict) + + cmd = _with_config_file_cmd(tmp_file, ["config", "show"]) + nodeless_client.run(cmd) + finally: + if tmp_file is not None: + os.remove(tmp_file) + + def _run_config_show_with_node_port( + self, nodeless_client: Client, port: int + ): + config_dict = {"node_port": port} + self._run_config_show_with_temp_config_file( + nodeless_client, config_dict + ) + + def _run_config_show_with_web_port( + self, nodeless_client: Client, port: int + ): + config_dict = {"web_port": port} + self._run_config_show_with_temp_config_file( + nodeless_client, config_dict + ) diff --git a/tests_python/tests_012/test_codec.py b/tests_python/tests_012/test_codec.py new file mode 100644 index 000000000000..bb87d8b037f7 --- /dev/null +++ b/tests_python/tests_012/test_codec.py @@ -0,0 +1,23 @@ +from typing import Any +import pytest +from codec.codec import Codec +from tools import paths + +CODEC_BIN = paths.TEZOS_HOME + "tezos-codec" + +ENCODINGS = [ + ( + "network_version", + {"p2p_version": 0, "distributed_db_version": 1, "chain_name": "main"}, + ) +] + + +@pytest.mark.codec +class TestCodec: + @pytest.mark.parametrize("encoding_name, data", ENCODINGS) + def test_codec_encode_decode(self, encoding_name: str, data: Any): + codec = Codec(CODEC_BIN) + data_encoded = codec.encode(encoding_name, data_json=data) + data_decoded = codec.decode(encoding_name, data=data_encoded) + assert data_decoded == data diff --git a/tests_python/tests_012/test_contract.py b/tests_python/tests_012/test_contract.py new file mode 100644 index 000000000000..5941681eeb8e --- /dev/null +++ b/tests_python/tests_012/test_contract.py @@ -0,0 +1,2296 @@ +import os +import re +import itertools +from typing import List, Union, Any +import pytest + +from client.client import Client +from tools import utils +from tools.constants import IDENTITIES +from tools.utils import originate +from .contract_paths import ( + CONTRACT_PATH, + ILLTYPED_CONTRACT_PATH, + all_contracts, + all_legacy_contracts, +) + + +ID_SCRIPT_LITERAL = ''' +parameter unit; storage unit; code {CAR; NIL operation; PAIR} +'''.strip() +ID_SCRIPT_HASH = ''' +exprtpyospPfMqcARmu5FGukprC7kbbe4jb4zxFd4Gxrp2vcCPjRNa +'''.strip() + + +@pytest.mark.contract +@pytest.mark.incremental +class TestManager: + def test_manager_origination(self, client: Client, session: dict): + path = os.path.join(CONTRACT_PATH, 'entrypoints', 'manager.tz') + pubkey = IDENTITIES['bootstrap2']['identity'] + originate(client, session, path, f'"{pubkey}"', 1000) + originate( + client, session, path, f'"{pubkey}"', 1000, contract_name="manager2" + ) + + def test_delegatable_origination(self, client: Client, session: dict): + path = os.path.join( + CONTRACT_PATH, 'entrypoints', 'delegatable_target.tz' + ) + pubkey = IDENTITIES['bootstrap2']['identity'] + originate( + client, session, path, f'Pair "{pubkey}" (Pair "hello" 45)', 1000 + ) + + def test_target_with_entrypoints_origination(self, client: Client, session): + path = os.path.join( + CONTRACT_PATH, 'entrypoints', 'big_map_entrypoints.tz' + ) + originate( + client, session, path, 'Pair {} {}', 1000, contract_name='target' + ) + + def test_target_without_entrypoints_origination( + self, client: Client, session + ): + path = os.path.join( + CONTRACT_PATH, 'entrypoints', 'no_entrypoint_target.tz' + ) + originate( + client, + session, + path, + 'Pair "hello" 42', + 1000, + contract_name='target_no_entrypoints', + ) + + def test_target_without_default_origination(self, client: Client, session): + path = os.path.join( + CONTRACT_PATH, 'entrypoints', 'no_default_target.tz' + ) + originate( + client, + session, + path, + 'Pair "hello" 42', + 1000, + contract_name='target_no_default', + ) + + def test_target_with_root_origination(self, client: Client, session): + path = os.path.join(CONTRACT_PATH, 'entrypoints', 'rooted_target.tz') + originate( + client, + session, + path, + 'Pair "hello" 42', + 1000, + contract_name='rooted_target', + ) + + def test_manager_set_delegate(self, client: Client): + client.set_delegate('manager', 'bootstrap2', []) + utils.bake(client, bake_for='bootstrap5') + bootstrap2_pkh = IDENTITIES['bootstrap2']['identity'] + client.set_delegate('delegatable_target', bootstrap2_pkh, []) + utils.bake(client, bake_for='bootstrap5') + delegate = IDENTITIES['bootstrap2']['identity'] + assert client.get_delegate('manager', []).delegate == delegate + assert ( + client.get_delegate('delegatable_target', []).delegate == delegate + ) + client.set_delegate('manager', 'bootstrap3', []) + utils.bake(client, bake_for='bootstrap5') + client.set_delegate('delegatable_target', 'bootstrap3', []) + utils.bake(client, bake_for='bootstrap5') + delegate = IDENTITIES['bootstrap3']['identity'] + assert client.get_delegate('manager', []).delegate == delegate + assert ( + client.get_delegate('delegatable_target', []).delegate == delegate + ) + + def test_manager_withdraw_delegate(self, client: Client): + client.withdraw_delegate('manager', []) + utils.bake(client, bake_for='bootstrap5') + client.withdraw_delegate('delegatable_target', []) + utils.bake(client, bake_for='bootstrap5') + assert client.get_delegate('manager', []).delegate is None + assert client.get_delegate('delegatable_target', []).delegate is None + + def test_transfer_to_manager(self, client: Client): + balance = client.get_mutez_balance('manager') + balance_bootstrap = client.get_mutez_balance('bootstrap2') + amount = 10.001 + amount_mutez = utils.mutez_of_tez(amount) + client.transfer( + amount, + 'bootstrap2', + 'manager', + ['--gas-limit', f'{128 * 15450 + 108}'], + ) + utils.bake(client, bake_for='bootstrap5') + new_balance = client.get_mutez_balance('manager') + new_balance_bootstrap = client.get_mutez_balance('bootstrap2') + fee = 0.000382 + fee_mutez = utils.mutez_of_tez(fee) + assert balance + amount_mutez == new_balance + assert ( + balance_bootstrap - fee_mutez - amount_mutez + == new_balance_bootstrap + ) + + def test_simple_transfer_from_manager_to_implicit(self, client: Client): + balance = client.get_mutez_balance('manager') + balance_bootstrap = client.get_mutez_balance('bootstrap2') + amount = 10.1 + amount_mutez = utils.mutez_of_tez(amount) + client.transfer( + amount, + 'manager', + 'bootstrap2', + ['--gas-limit', f'{128 * 26350 + 12}'], + ) + utils.bake(client, bake_for='bootstrap5') + new_balance = client.get_mutez_balance('manager') + new_balance_bootstrap = client.get_mutez_balance('bootstrap2') + fee = 0.000584 + fee_mutez = utils.mutez_of_tez(fee) + assert balance - amount_mutez == new_balance + assert ( + balance_bootstrap + amount_mutez - fee_mutez + == new_balance_bootstrap + ) + + def test_transfer_from_manager_to_manager(self, client: Client): + balance = client.get_mutez_balance('manager') + balance_dest = client.get_mutez_balance('manager2') + balance_bootstrap = client.get_mutez_balance('bootstrap2') + amount = 10 + amount_mutez = utils.mutez_of_tez(amount) + client.transfer( + amount, + 'manager', + 'manager2', + ['--gas-limit', f'{128 * 44950 + 112}'], + ) + utils.bake(client, bake_for='bootstrap5') + new_balance = client.get_mutez_balance('manager') + new_balance_dest = client.get_mutez_balance('manager2') + new_balance_bootstrap = client.get_mutez_balance('bootstrap2') + fee = 0.000787 + fee_mutez = utils.mutez_of_tez(fee) + assert balance - amount_mutez == new_balance + assert balance_dest + amount_mutez == new_balance_dest + assert balance_bootstrap - fee_mutez == new_balance_bootstrap + + def test_transfer_from_manager_to_default(self, client: Client): + client.transfer( + 10, 'manager', 'bootstrap2', ['--entrypoint', 'default'] + ) + utils.bake(client, bake_for='bootstrap5') + client.transfer(10, 'manager', 'manager', ['--entrypoint', 'default']) + utils.bake(client, bake_for='bootstrap5') + + def test_transfer_from_manager_to_target(self, client: Client): + client.transfer(10, 'manager', 'target', ['--burn-cap', '0.356']) + utils.bake(client, bake_for='bootstrap5') + + def test_transfer_from_manager_to_entrypoint_with_args( + self, client: Client + ): + arg = 'Pair "hello" 42' + # using 'transfer' + client.transfer( + 0, + 'manager', + 'target', + ['--entrypoint', 'add_left', '--arg', arg, '--burn-cap', '0.067'], + ) + utils.bake(client, bake_for='bootstrap5') + client.transfer( + 0, + 'manager', + 'target', + ['--entrypoint', 'mem_left', '--arg', '"hello"'], + ) + utils.bake(client, bake_for='bootstrap5') + + # using 'call' + client.call( + 'manager', + 'target', + ['--entrypoint', 'add_left', '--arg', arg, '--burn-cap', '0.067'], + ) + utils.bake(client, bake_for='bootstrap5') + client.call( + 'manager', + 'target', + ['--entrypoint', 'mem_left', '--arg', '"hello"'], + ) + utils.bake(client, bake_for='bootstrap5') + + def test_transfer_from_manager_no_entrypoint_with_args( + self, client: Client + ): + arg = 'Left Unit' + client.transfer(0, 'manager', 'target_no_entrypoints', ['--arg', arg]) + utils.bake(client, bake_for='bootstrap5') + + client.call('manager', 'target_no_entrypoints', ['--arg', arg]) + utils.bake(client, bake_for='bootstrap5') + + def test_transfer_from_manager_to_no_default_with_args( + self, client: Client + ): + arg = 'Left Unit' + client.transfer(0, 'manager', 'target_no_default', ['--arg', arg]) + utils.bake(client, bake_for='bootstrap5') + + client.call('manager', 'target_no_default', ['--arg', arg]) + utils.bake(client, bake_for='bootstrap5') + + def test_transfer_from_manager_to_rooted_target_with_args( + self, client: Client + ): + arg = 'Left Unit' + client.transfer( + 0, + 'manager', + 'rooted_target', + ['--arg', arg, '--entrypoint', 'root'], + ) + utils.bake(client, bake_for='bootstrap5') + + client.call( + 'manager', 'rooted_target', ['--arg', arg, '--entrypoint', 'root'] + ) + utils.bake(client, bake_for='bootstrap5') + + +# This test to verifies contract execution order. There are 3 +# contracts: Storer, Caller, and Appender. Storer appends its argument +# to storage. Caller calls the list of unit contracts in its +# storage. Appender calls the string contract in its storage with a +# stored argument. +# +# For each test, there is one unique Storer. Each test is +# parameterized by a tree and the expected final storage of the +# Storer. A leaf in the tree is a string. Inner nodes are lists of +# leafs/inner nodes. The test maps maps over this tree to build a +# tree of contracts. Leaf nodes map to Appender contracts calling +# the Storer. Inner nodes map to Caller contract that calling +# children. +# +# Example. Given the tree: ["A", ["B"], "C"], we obtain +# Caller([Appender("A"), Caller([Appender("B")]), Appender("C")]) +# Before the protocol 009, contract execution order was in BFS +# In BFS, Storer would've ended up with storage ACB. +# In DFS, Storer will end up with storage ABC. +@pytest.mark.contract +@pytest.mark.incremental +class TestExecutionOrdering: + STORER = f'{CONTRACT_PATH}/mini_scenarios/execution_order_storer.tz' + CALLER = f'{CONTRACT_PATH}/mini_scenarios/execution_order_caller.tz' + APPENDER = f'{CONTRACT_PATH}/mini_scenarios/execution_order_appender.tz' + + def originate_storer(self, client: Client, session: dict): + origination = originate( + client, session, self.STORER, '""', 0, arguments=['--force'] + ) + session['storer'] = origination.contract + utils.bake(client, bake_for='bootstrap3') + return origination.contract + + def originate_appender( + self, client: Client, session: dict, storer: str, argument: str + ): + origination = originate( + client, + session, + self.APPENDER, + f'Pair "{storer}" "{argument}"', + 0, + contract_name=f'appender-{argument}', + arguments=['--force'], + ) + session[f'appender.{argument}'] = origination.contract + utils.bake(client, bake_for='bootstrap3') + return origination.contract + + def originate_caller( + self, client: Client, session: dict, callees: List[str] + ): + storage = "{" + '; '.join(map('"{}"'.format, callees)) + "}" + origination = originate( + client, + session, + self.CALLER, + storage, + 0, + contract_name=f'caller-{hash(storage)}', + ) + utils.bake(client, bake_for='bootstrap3') + return origination.contract + + @pytest.mark.parametrize( + "tree, expected", + [ + # before 009, the result should be "DABCEFG". + ([["A", "B", "C"], "D", ["E", "F", "G"]], "ABCDEFG"), + # before 009, the result should be "ACB". + ([["A", ["B"], "C"]], "ABC"), + # before 009, the result should be "ABDC". + ([["A", ["B", ["C"], "D"]]], "ABCD"), + ([], ""), + ], + ) + def test_ordering( + self, + client: Client, + session: dict, + # approximation of recursive type annotation + tree: Union[str, List[Any]], + expected: str, + ): + storer = self.originate_storer(client, session) + + def deploy_tree(tree: Union[str, List[Any]]) -> str: + # leaf + if isinstance(tree, str): + # deploy and return caller str + return self.originate_appender(client, session, storer, tree) + # inner node + children = list(map(deploy_tree, tree)) + return self.originate_caller(client, session, children) + + root = deploy_tree(tree) + + client.transfer( + 0, + 'bootstrap2', + root, + ["--burn-cap", "5"], + ) + utils.bake(client, bake_for='bootstrap3') + assert client.get_storage(storer) == '"{}"'.format(expected) + + +@pytest.mark.contract +@pytest.mark.regression +class TestTypecheck: + """Regression testing of Michelson typechecking""" + + @pytest.mark.parametrize("contract", all_contracts()) + def test_typecheck(self, client_regtest: Client, contract): + client = client_regtest + assert contract.endswith( + '.tz' + ), "test contract should have .tz extension" + client.typecheck(os.path.join(CONTRACT_PATH, contract), details=True) + + +@pytest.mark.slow +@pytest.mark.contract +class TestContracts: + """Test type checking errors""" + + @pytest.mark.parametrize("contract", all_legacy_contracts()) + def test_deprecated_typecheck_breaks(self, client, contract): + if contract in [ + "legacy/create_contract.tz", + "legacy/create_contract_flags.tz", + "legacy/create_contract_rootname.tz", + ]: + with utils.assert_run_failure(r'ill-typed script'): + client.typecheck(os.path.join(CONTRACT_PATH, contract)) + else: + with utils.assert_run_failure(r'Use of deprecated instruction'): + client.typecheck(os.path.join(CONTRACT_PATH, contract)) + + @pytest.mark.parametrize("contract", all_legacy_contracts()) + def test_deprecated_typecheck_in_legacy(self, client, contract): + if contract in [ + "legacy/create_contract.tz", + "legacy/create_contract_flags.tz", + "legacy/create_contract_rootname.tz", + ]: + with utils.assert_run_failure(r'ill-typed script'): + client.typecheck( + os.path.join(CONTRACT_PATH, contract), legacy=True + ) + else: + with utils.assert_run_failure(r'Use of deprecated instruction'): + client.typecheck( + os.path.join(CONTRACT_PATH, contract), legacy=True + ) + + @pytest.mark.parametrize( + "contract,error_pattern", + [ + # Even though the interpreter uses a nonempty stack internally, + # the typechecker should not be able to observe it. + ( + "stack_bottom_unfailwithable.tz", + r'wrong stack type for instruction FAILWITH', + ), + ( + "stack_bottom_unrightable.tz", + r'wrong stack type for instruction RIGHT', + ), + ( + "stack_bottom_unleftable.tz", + r'wrong stack type for instruction LEFT', + ), + ( + "stack_bottom_ungetable.tz", + r'wrong stack type for instruction GET', + ), + ( + "stack_bottom_unpairable.tz", + r'wrong stack type for instruction UNPAIR', + ), + ( + "stack_bottom_undug2able.tz", + r'wrong stack type for instruction DUG', + ), + ( + "stack_bottom_undugable.tz", + r'wrong stack type for instruction DUG', + ), + ( + "stack_bottom_undig2able.tz", + r'wrong stack type for instruction DIG', + ), + ( + "stack_bottom_undigable.tz", + r'wrong stack type for instruction DIG', + ), + ( + "stack_bottom_undip2able.tz", + r'wrong stack type for instruction DUP', + ), + ( + "stack_bottom_undipable.tz", + r'wrong stack type for instruction DUP', + ), + ( + "stack_bottom_undup2able.tz", + r'wrong stack type for instruction DUP', + ), + ( + "stack_bottom_undropable.tz", + r'wrong stack type for instruction DROP', + ), + ( + "stack_bottom_unpopable.tz", + r'wrong stack type for instruction DUP', + ), + ( + "stack_bottom_unpopable_in_lambda.tz", + r'wrong stack type for instruction DUP', + ), + # operations cannot be PACKed + ( + "pack_operation.tz", + r'operation type forbidden in parameter, storage and constants', + ), + # big_maps cannot be PACKed + ( + "pack_big_map.tz", + r'big_map or sapling_state type not expected here', + ), + ( + "invalid_self_entrypoint.tz", + r'Contract has no entrypoint named D', + ), + ("contract_annotation_default.tz", r'unexpected annotation'), + # Missing field + ( + "missing_only_storage_field.tz", + r'Missing contract field: storage', + ), + ("missing_only_code_field.tz", r'Missing contract field: code'), + ( + "missing_only_parameter_field.tz", + r'Missing contract field: parameter', + ), + ( + "missing_parameter_and_storage_fields.tz", + r'Missing contract field: parameter', + ), + # Duplicated field + ( + "multiple_parameter_field.tz", + r'duplicate contract field: parameter', + ), + ("multiple_code_field.tz", r'duplicate contract field: code'), + ("multiple_storage_field.tz", r'duplicate contract field: storage'), + # The first duplicated field is reported, storage in this case + ( + "multiple_storage_and_code_fields.tz", + r'duplicate contract field: storage', + ), + # error message for set update on non-comparable type + ( + "set_update_non_comparable.tz", + r'Type nat is not compatible with type list operation', + ), + # error message for the arity of the chain_id type + ( + "chain_id_arity.tz", + r'primitive chain_id expects 0 arguments but is given 1', + ), + # error message for DIP over the limit + ("big_dip.tz", r'expected a positive 10-bit integer'), + # error message for DROP over the limit + ("big_drop.tz", r'expected a positive 10-bit integer'), + # error message for set update on non-comparable type + ( + "set_update_non_comparable.tz", + r'Type nat is not compatible with type list operation', + ), + # error message for attempting to push a value of type never + ("never_literal.tz", r'type never has no inhabitant.'), + # field annotation mismatch with UNPAIR + ( + "unpair_field_annotation_mismatch.tz", + r'The field access annotation does not match', + ), + # COMB, UNCOMB, and DUP cannot take 0 as argument + ("comb0.tz", r"PAIR expects an argument of at least 2"), + ("comb1.tz", r"PAIR expects an argument of at least 2"), + ("uncomb0.tz", r"UNPAIR expects an argument of at least 2"), + ("uncomb1.tz", r"UNPAIR expects an argument of at least 2"), + ("dup0.tz", r"DUP n expects an argument of at least 1"), + ( + "push_big_map_with_id_with_parens.tz", + r"big_map or sapling_state type not expected here", + ), + ( + "push_big_map_with_id_without_parens.tz", + r"primitive PUSH expects 2 arguments but is given 4", + ), + # sapling_state is not packable + ( + "pack_sapling_state.tz", + r"big_map or sapling_state type not expected here", + ), + # sapling_state is not packable + ( + "unpack_sapling_state.tz", + r"big_map or sapling_state type not expected here", + ), + # Ticket duplication attempt + ( + "ticket_dup.tz", + r'ticket nat cannot be used here because it is not duplicable', + ), + # error message for ticket unpack + ("ticket_unpack.tz", r'Ticket in unauthorized position'), + # error message for attempting to use APPLY to capture a ticket + ("ticket_apply.tz", r'Ticket in unauthorized position'), + # error message for attempting to wrap a ticket in a ticket + ( + "ticket_in_ticket.tz", + r'comparable type expected.Type ticket unit is not comparable', + ), + # error message for DIP { FAILWITH } + ( + "dip_failwith.tz", + r'The FAIL instruction must appear in a tail position.', + ), + # error message for MAP { FAILWITH } + ( + "map_failwith.tz", + r'The proper type of the return list cannot be inferred.', + ), + ], + ) + def test_ill_typecheck(self, client: Client, contract, error_pattern): + with utils.assert_run_failure(error_pattern): + client.typecheck(os.path.join(ILLTYPED_CONTRACT_PATH, contract)) + + def test_zero_transfer_to_implicit_contract(self, client): + pubkey = IDENTITIES['bootstrap3']['identity'] + err = ( + 'Transactions of 0ꜩ towards a contract without code are ' + rf'forbidden \({pubkey}\).' + ) + with utils.assert_run_failure(err): + client.transfer(0, 'bootstrap2', 'bootstrap3', []) + + def test_zero_transfer_to_nonexistent_contract(self, client): + nonexistent = "KT1Fcq4inD44aMhmUiTEHR1QMQwJT7p2u641" + err = rf'Contract {nonexistent} does not exist' + with utils.assert_run_failure(err): + client.transfer(0, 'bootstrap2', nonexistent, []) + + +FIRST_EXPLOSION = ''' +{ parameter unit; + storage unit; + code{ DROP; PUSH nat 0 ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DROP ; UNIT ; NIL operation ; PAIR} } +''' + + +# FIRST_EXPLOSION costs a large amount of gas just for typechecking. +# FIRST_EXPLOSION_BIGTYPE type size exceeds the protocol set bound. +FIRST_EXPLOSION_BIGTYPE = ''' +{ parameter unit; + storage unit; + code{ DROP; PUSH nat 0 ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DUP ; PAIR ; + DROP ; UNIT ; NIL operation ; PAIR} } +''' + + +SECOND_EXPLOSION = ''' +{ parameter (list int) ; + storage (list (list (list int))) ; + code { CAR ; DIP { NIL (list int) } ; + DUP ; ITER { DROP ; DUP ; DIP { CONS } } ; + DROP ; DIP { NIL (list (list int)) } ; + DUP ; ITER { DROP ; DUP ; DIP { CONS } } ; + DROP ; NIL operation ; PAIR } } +''' + + +@pytest.mark.incremental +@pytest.mark.contract +class TestView: + def test_deploy_view_lib(self, client, session): + path = f'{CONTRACT_PATH}/opcodes/view_toplevel_lib.tz' + originate(client, session, path, '3', 999) + session['lib'] = session['contract'] + client.bake('bootstrap3', ["--minimal-timestamp"]) + + @pytest.mark.parametrize( + "contract,init_storage,expected", + [ + ('view_op_id', '(Pair 0 0)', 'Pair 10 3'), + ('view_op_add', '42', '13'), + ('view_fib', '0', '55'), + ('view_mutual_recursion', '0', '20'), + ('view_op_nonexistent_func', 'True', 'False'), + ('view_op_nonexistent_addr', 'True', 'False'), + ('view_op_toplevel_inconsistent_input_type', '5', '0'), + ('view_op_toplevel_inconsistent_output_type', 'True', 'False'), + ], + ) + def test_runtime(self, client, session, contract, init_storage, expected): + path = f'{CONTRACT_PATH}/opcodes/' + contract + '.tz' + originate(client, session, path, init_storage, 0) + client.transfer( + 0, + 'bootstrap1', + contract, + [ + "--arg", + "(Pair 10 \"" + session['lib'] + "\")", + '--gas-limit', + '1000000', + "--burn-cap", + "0.1", + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + assert client.get_storage(contract) == expected + + def test_create_contract( + self, + client, + session, + ): + contract = 'create_contract_with_view' + path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' + originate(client, session, path, 'None', 0) + client.transfer( + 0, + 'bootstrap1', + contract, + [ + "--arg", + "Unit", + "--burn-cap", + "0.1", + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + + addr = client.get_storage(contract).split()[1] + contract = 'view_op_constant' + path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' + originate(client, session, path, '2', 0) + expected = "10" + + client.transfer( + 0, + "bootstrap1", + contract, + [ + "--arg", + f"(Pair {expected} {addr})", + "--burn-cap", + "0.1", + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + + assert client.get_storage(contract) == expected + + def test_step_constants(self, client, session): + contract = 'view_op_test_step_contants' + path = f'{CONTRACT_PATH}/opcodes/' + contract + '.tz' + originate(client, session, path, 'None', 0) + client.transfer( + 0, + 'bootstrap1', + contract, + [ + "--arg", + "\"" + session['lib'] + "\"", + '--gas-limit', + '5000', + "--burn-cap", + "0.1", + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + + source = IDENTITIES['bootstrap1']['identity'] + self_address = session['lib'] + sender = session['contract'] + expected = ( + 'Some (Pair (Pair 0 999000000)\n' + + ' (Pair "' + + self_address + + '" "' + + sender + + '")\n' + + ' "' + + source + + '")' + ) + + assert client.get_storage(contract) == expected + + @pytest.mark.parametrize( + "contract", + [ + 'self_after_view', + 'self_after_fib_view', + 'self_after_nonexistent_view', + ], + ) + def test_self(self, client, session, contract): + path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' + lib_address = session['lib'] + originate(client, session, path, f'"{lib_address}"', 1000) + client.bake('bootstrap2', ["--minimal-timestamp"]) + self_address = session['contract'] + client.transfer( + 0, + 'bootstrap1', + contract, + [ + '--arg', + f'"{lib_address}"', + '--burn-cap', + '0.1', + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + assert client.get_storage(contract) == f'"{self_address}"' + + @pytest.mark.parametrize( + "contract", + [ + 'self_address_after_view', + 'self_address_after_fib_view', + 'self_address_after_nonexistent_view', + ], + ) + def test_self_address(self, client, session, contract): + path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' + lib_address = session['lib'] + originate(client, session, path, f'"{lib_address}"', 1000) + client.bake('bootstrap2', ["--minimal-timestamp"]) + self_address = session['contract'] + client.transfer( + 0, + 'bootstrap1', + contract, + [ + '--arg', + f'"{lib_address}"', + '--burn-cap', + '0.1', + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + assert client.get_storage(contract) == f'"{self_address}"' + + @pytest.mark.parametrize( + "contract", + [ + 'sender_after_view', + 'sender_after_fib_view', + 'sender_after_nonexistent_view', + ], + ) + def test_sender(self, client, session, contract): + path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' + lib_address = session['lib'] + originate(client, session, path, f'"{lib_address}"', 1000) + client.bake('bootstrap2', ["--minimal-timestamp"]) + sender = IDENTITIES['bootstrap1']['identity'] + client.transfer( + 0, + 'bootstrap1', + contract, + [ + '--arg', + f'"{lib_address}"', + '--burn-cap', + '0.1', + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + assert client.get_storage(contract) == f'"{sender}"' + + @pytest.mark.parametrize( + "contract", + [ + 'balance_after_view', + 'balance_after_fib_view', + 'balance_after_nonexistent_view', + ], + ) + def test_balance_after_view(self, client, session, contract): + path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' + lib_address = session['lib'] + initial_balance = 1000 + originate(client, session, path, '0', initial_balance) + client.bake('bootstrap2', ["--minimal-timestamp"]) + amount = 10 + client.transfer( + amount, + 'bootstrap1', + contract, + [ + '--arg', + f'"{lib_address}"', + '--burn-cap', + '0.1', + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + expected_balance = initial_balance + amount + assert ( + client.get_storage(contract) + == f'{utils.mutez_of_tez(expected_balance)}' + ) + + @pytest.mark.parametrize( + "contract", + [ + 'amount_after_view', + 'amount_after_fib_view', + 'amount_after_nonexistent_view', + ], + ) + def test_amount_after_view(self, client, session, contract): + path = f'{CONTRACT_PATH}/opcodes/{contract}.tz' + lib_address = session['lib'] + originate(client, session, path, '0', 1000) + client.bake('bootstrap2', ["--minimal-timestamp"]) + amount = 3 + client.transfer( + amount, + 'bootstrap1', + contract, + [ + '--arg', + f'"{lib_address}"', + '--burn-cap', + '0.1', + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + assert client.get_storage(contract) == f'{utils.mutez_of_tez(amount)}' + + def test_recursion(self, client, session): + contract = 'view_rec' + path = f'{CONTRACT_PATH}/opcodes/' + contract + '.tz' + originate(client, session, path, 'Unit', 0) + with utils.assert_run_failure( + "Gas limit exceeded during typechecking or execution." + ): + client.transfer( + 0, + 'bootstrap1', + contract, + [ + "--arg", + "Unit", + '--gas-limit', + '5000', + ], + ) + client.bake('bootstrap2', ["--minimal-timestamp"]) + + @pytest.mark.parametrize( + "contract,expected_error", + [ + ( + 'view_toplevel_bad_type', + 'the return of a view block did not match the expected type.', + ), + ( + 'view_toplevel_bad_return_type', + 'the return of a view block did not match the expected type.', + ), + ( + 'view_toplevel_bad_input_type', + 'operator ADD is undefined between string', + ), + ( + 'view_toplevel_invalid_arity', + 'primitive view expects 4 arguments', + ), + ( + 'view_toplevel_bad_name_too_long', + 'exceeds the maximum length of 31 characters', + ), + ( + 'view_toplevel_bad_name_invalid_type', + 'only a string can be used here', + ), + ( + 'view_toplevel_bad_name_non_printable_char', + 'string \\[a-zA-Z0-9_.%@\\]', + ), + ( + 'view_toplevel_bad_name_invalid_char_set', + 'string \\[a-zA-Z0-9_.%@\\]', + ), + ( + 'view_toplevel_duplicated_name', + 'the name of view in toplevel should be unique', + ), + ( + 'view_toplevel_dupable_type_output', + 'Ticket in unauthorized position', + ), + ( + 'view_toplevel_dupable_type_input', + 'Ticket in unauthorized position', + ), + ( + 'view_toplevel_lazy_storage_input', + 'big_map or sapling_state type not expected here', + ), + ( + 'view_toplevel_lazy_storage_output', + 'big_map or sapling_state type not expected here', + ), + ('view_op_invalid_arity', 'primitive VIEW expects 2 arguments'), + ( + 'view_op_bad_name_invalid_type', + 'unexpected int, only a string', + ), + ( + 'view_op_bad_name_too_long', + 'exceeds the maximum length of 31 characters', + ), + ( + 'view_op_bad_name_non_printable_char', + 'string \\[a-zA-Z0-9_.%@\\]', + ), + ( + 'view_op_bad_name_invalid_char_set', + 'string \\[a-zA-Z0-9_.%@\\]', + ), + ( + 'view_op_bad_return_type', + 'two branches don\'t end with the same stack type', + ), + ( + 'view_op_dupable_type', + 'Ticket in unauthorized position', + ), + ( + 'view_op_lazy_storage', + 'big_map or sapling_state type not expected here', + ), + ], + ) + def test_typechecking_error( + self, client, session, contract, expected_error + ): + path = f'{CONTRACT_PATH}/ill_typed/' + contract + '.tz' + with utils.assert_run_failure(expected_error): + originate(client, session, path, '4', 0) + + +@pytest.mark.contract +class TestGasBound: + def test_write_contract(self, tmpdir, session: dict): + items = { + 'first_explosion.tz': FIRST_EXPLOSION, + 'first_explosion_bigtype.tz': FIRST_EXPLOSION_BIGTYPE, + 'second_explosion.tz': SECOND_EXPLOSION, + }.items() + for name, script in items: + contract = f'{tmpdir}/{name}' + with open(contract, 'w') as contract_file: + contract_file.write(script) + session[name] = contract + + def test_originate_first_explosion(self, client: Client, session: dict): + name = 'first_explosion.tz' + contract = session[name] + client.typecheck(contract) + args = ['-G', f'{1461}', '--burn-cap', '10'] + + expected_error = "Gas limit exceeded during typechecking or execution" + with utils.assert_run_failure(expected_error): + client.originate(f'{name}', 0, 'bootstrap1', contract, args) + + def test_originate_big_type(self, client: Client, session: dict): + name = 'first_explosion_bigtype.tz' + contract = session[name] + + expected_error = "type exceeded maximum type size" + with utils.assert_run_failure(expected_error): + client.typecheck(contract) + + def test_originate_second_explosion(self, client: Client, session: dict): + name = 'second_explosion.tz' + contract = session[name] + storage = '{}' + inp = '{1;2;3;4;5;6;7;8;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1}' + client.run_script(contract, storage, inp) + + def test_originate_second_explosion_fail( + self, client: Client, session: dict + ): + name = 'second_explosion.tz' + contract = session[name] + storage = '{}' + inp = ( + '{1;2;3;4;5;6;7;8;9;0;1;2;3;4;5;6;7;1;1;1;1;1;1;1;1;1;1;1' + + ';1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1}' + ) + + expected_error = ( + "Cannot serialize the resulting storage" + + " value within the provided gas bounds." + ) + with utils.assert_run_failure(expected_error): + client.run_script(contract, storage, inp, gas=9290) + + def test_typecheck_map_dup_key(self, client: Client): + + expected_error = ( + 'Map literals cannot contain duplicate' + + ' keys, however a duplicate key was found' + ) + with utils.assert_run_failure(expected_error): + client.typecheck_data('{ Elt 0 1 ; Elt 0 1}', '(map nat nat)') + + def test_typecheck_map_bad_ordering(self, client: Client): + + expected_error = ( + "Keys in a map literal must be in strictly" + + " ascending order, but they were unordered in literal" + ) + with utils.assert_run_failure(expected_error): + client.typecheck_data( + '{ Elt 0 1 ; Elt 10 1 ; Elt 5 1 }', '(map nat nat)' + ) + + def test_typecheck_set_bad_ordering(self, client: Client): + + expected_error = ( + "Values in a set literal must be in strictly" + + " ascending order, but they were unordered in literal" + ) + with utils.assert_run_failure(expected_error): + client.typecheck_data('{ "A" ; "C" ; "B" }', '(set string)') + + def test_typecheck_set_no_duplicates(self, client: Client): + expected_error = ( + "Set literals cannot contain duplicate values," + + " however a duplicate value was found" + ) + with utils.assert_run_failure(expected_error): + client.typecheck_data('{ "A" ; "B" ; "B" }', '(set string)') + + +@pytest.mark.incremental +@pytest.mark.contract +class TestChainId: + def test_chain_id_opcode(self, client: Client, session: dict): + path = os.path.join(CONTRACT_PATH, 'opcodes', 'chain_id.tz') + originate(client, session, path, 'Unit', 0) + client.call('bootstrap2', "chain_id", []) + utils.bake(client, bake_for='bootstrap5') + + def test_chain_id_authentication_origination(self, client: Client, session): + path = os.path.join( + CONTRACT_PATH, 'mini_scenarios', 'authentication.tz' + ) + pubkey = IDENTITIES['bootstrap1']['public'] + originate(client, session, path, f'Pair 0 "{pubkey}"', 1000) + utils.bake(client, bake_for='bootstrap5') + + def test_chain_id_authentication_first_run( + self, client: Client, session: dict + ): + destination = IDENTITIES['bootstrap2']['identity'] + operation = ( + '{DROP; NIL operation; ' + + f'PUSH address "{destination}"; ' + + 'CONTRACT unit; ASSERT_SOME; PUSH mutez 1000; UNIT; ' + + 'TRANSFER_TOKENS; CONS}' + ) + chain_id = client.rpc('get', 'chains/main/chain_id') + contract_address = session['contract'] + packed = client.pack( + f'Pair (Pair "{chain_id}" "{contract_address}") ' + + f'(Pair {operation} 0)', + 'pair (pair chain_id address)' + + '(pair (lambda unit (list operation)) nat)', + ) + signature = client.sign_bytes_of_string(packed, "bootstrap1") + client.call( + 'bootstrap2', + 'authentication', + ['--arg', f'Pair {operation} \"{signature}\"'], + ) + utils.bake(client, bake_for='bootstrap5') + + +@pytest.mark.incremental +@pytest.mark.contract +class TestBigMapToSelf: + def test_big_map_to_self_origination(self, client: Client, session: dict): + path = os.path.join(CONTRACT_PATH, 'opcodes', 'big_map_to_self.tz') + originate(client, session, path, '{}', 0) + utils.bake(client, bake_for='bootstrap5') + + def test_big_map_to_self_transfer(self, client: Client): + client.call('bootstrap2', "big_map_to_self", []) + utils.bake(client, bake_for='bootstrap5') + + client.transfer(0, 'bootstrap2', "big_map_to_self", []) + utils.bake(client, bake_for='bootstrap5') + + +@pytest.mark.incremental +@pytest.mark.contract +class TestNonRegression: + """Test contract-related non-regressions""" + + def test_issue_242_originate(self, client: Client, session: dict): + path = os.path.join(CONTRACT_PATH, 'non_regression', 'bug_262.tz') + originate(client, session, path, 'Unit', 1) + + def test_issue_242_assert_balance(self, client: Client): + assert client.get_balance('bug_262') == 1 + + +@pytest.mark.incremental +@pytest.mark.contract +class TestMiniScenarios: + """Test mini scenarios""" + + # replay.tz related tests + def test_replay_originate(self, client: Client, session: dict): + path = os.path.join(CONTRACT_PATH, 'mini_scenarios', 'replay.tz') + originate(client, session, path, 'Unit', 0) + + def test_replay_transfer_fail(self, client: Client): + with utils.assert_run_failure("Internal operation replay attempt"): + client.transfer(10, "bootstrap1", "replay", []) + + # create_contract.tz related tests + def test_create_contract_originate(self, client: Client, session: dict): + path = os.path.join( + CONTRACT_PATH, 'mini_scenarios', 'create_contract.tz' + ) + originate(client, session, path, 'Unit', 1000) + + def test_create_contract_balance(self, client: Client): + assert client.get_balance('create_contract') == 1000 + + def test_create_contract_perform_creation(self, client: Client): + transfer_result = client.transfer( + 0, + "bootstrap1", + "create_contract", + ['-arg', 'None', '--burn-cap', '10'], + ) + utils.bake(client, bake_for='bootstrap5') + pattern = r"New contract (\w*) originated" + match = re.search(pattern, transfer_result.client_output) + assert match is not None + kt_1 = match.groups()[0] + assert client.get_storage(kt_1) == '"abcdefg"' + assert client.get_balance(kt_1) == 100 + assert client.get_balance('create_contract') == 900 + + # Originates a contract that when called, creates a contract with a + # rootname annotation. Such annotations comes in two flavors, thus the + # parameterization. Then calls the first contract and verifies the + # existence and type of the root entrypoint of the create contract. + @pytest.mark.parametrize( + "contract", + [ + 'create_contract_rootname.tz', + 'create_contract_rootname_alt.tz', + ], + ) + def test_create_contract_rootname_originate( + self, client: Client, session: dict, contract + ): + path = os.path.join(CONTRACT_PATH, 'opcodes', contract) + origination_res = originate(client, session, path, 'None', 1000) + + transfer_result = client.transfer( + 0, + "bootstrap1", + origination_res.contract, + ['-arg', 'Unit', '--burn-cap', '10'], + ) + utils.bake(client, bake_for='bootstrap5') + + pattern = r"New contract (\w*) originated" + match = re.search(pattern, transfer_result.client_output) + assert match is not None + kt_1 = match.groups()[0] + + entrypoint_type = client.get_contract_entrypoint_type( + 'root', kt_1 + ).entrypoint_type + + assert entrypoint_type == 'unit', ( + 'the entrypoint my_root of the originated contract should exist' + 'with type unit' + ) + + # default_account.tz related tests + def test_default_account_originate(self, client: Client, session: dict): + path = os.path.join( + CONTRACT_PATH, 'mini_scenarios', 'default_account.tz' + ) + originate(client, session, path, 'Unit', 1000) + + def test_default_account_transfer_then_bake(self, client: Client): + tz1 = IDENTITIES['bootstrap4']['identity'] + client.transfer( + 0, + "bootstrap1", + "default_account", + ['-arg', f'"{tz1}"', '--burn-cap', '10'], + ) + utils.bake(client, bake_for='bootstrap5') + account = 'tz1SuakBpFdG9b4twyfrSMqZzruxhpMeSrE5' + client.transfer( + 0, + "bootstrap1", + "default_account", + ['-arg', f'"{account}"', '--burn-cap', '10'], + ) + utils.bake(client, bake_for='bootstrap5') + assert client.get_balance(account) == 100 + + # Test bytes, SHA252, CHECK_SIGNATURE + def test_reveal_signed_preimage_originate( + self, client: Client, session: dict + ): + path = os.path.join( + CONTRACT_PATH, 'mini_scenarios', 'reveal_signed_preimage.tz' + ) + byt = ( + '0x9995c2ef7bcc7ae3bd15bdd9b02' + + 'dc6e877c27b26732340d641a4cbc6524813bb' + ) + sign = 'p2pk66uq221795tFxT7jfNmXtBMdjMf6RAaxRTwv1dbuSHbH6yfqGwz' + storage = f'(Pair {byt} "{sign}")' + originate(client, session, path, storage, 1000) + + def test_wrong_preimage(self, client: Client): + byt = ( + '0x050100000027566f756c657a2d766f75732' + + '0636f75636865722061766563206d6f692c20636520736f6972' + ) + sign = ( + 'p2sigvgDSBnN1bUsfwyMvqpJA1cFhE5s5oi7SetJ' + + 'VQ6LJsbFrU2idPvnvwJhf5v9DhM9ZTX1euS9DgWozVw6BTHiK9VcQVpAU8' + ) + arg = f'(Pair {byt} "{sign}")' + + # We check failure of ASSERT_CMPEQ in the script. + with utils.assert_run_failure("At line 8 characters 9 to 21"): + client.transfer( + 0, + "bootstrap1", + "reveal_signed_preimage", + ['-arg', arg, '--burn-cap', '10'], + ) + + def test_wrong_signature(self, client: Client): + byt = ( + '0x050100000027566f756c657a2d766f757320636' + + 'f75636865722061766563206d6f692c20636520736f6972203f' + ) + sign = ( + 'p2sigvgDSBnN1bUsfwyMvqpJA1cFhE5s5oi7SetJVQ6' + + 'LJsbFrU2idPvnvwJhf5v9DhM9ZTX1euS9DgWozVw6BTHiK9VcQVpAU8' + ) + arg = f'(Pair {byt} "{sign}")' + + # We check failure of CHECK_SIGNATURE ; ASSERT in the script. + with utils.assert_run_failure("At line 15 characters 9 to 15"): + client.transfer( + 0, + "bootstrap1", + "reveal_signed_preimage", + ['-arg', arg, '--burn-cap', '10'], + ) + + def test_good_preimage_and_signature(self, client: Client): + byt = ( + '0x050100000027566f756c657a2d766f757320636f7563' + + '6865722061766563206d6f692c20636520736f6972203f' + ) + sign = ( + 'p2sigsceCzcDw2AeYDzUonj4JT341WC9Px4wdhHBxbZcG1F' + + 'hfqFVuG7f2fGCzrEHSAZgrsrQWpxduDPk9qZRgrpzwJnSHC3gZJ' + ) + arg = f'(Pair {byt} "{sign}")' + client.transfer( + 0, + "bootstrap1", + "reveal_signed_preimage", + ['-arg', arg, '--burn-cap', '10'], + ) + utils.bake(client, bake_for='bootstrap5') + + # Test vote_for_delegate + def test_vote_for_delegate_originate(self, client: Client, session: dict): + b_3 = IDENTITIES['bootstrap3']['identity'] + b_4 = IDENTITIES['bootstrap4']['identity'] + path = os.path.join( + CONTRACT_PATH, 'mini_scenarios', 'vote_for_delegate.tz' + ) + storage = f'''(Pair (Pair "{b_3}" None) (Pair "{b_4}" None))''' + originate(client, session, path, storage, 1000) + assert client.get_delegate('vote_for_delegate').delegate is None + + def test_vote_for_delegate_wrong_identity1(self, client: Client): + # We check failure of CHECK_SIGNATURE ; ASSERT in the script. + with utils.assert_run_failure("At line 15 characters 57 to 61"): + client.transfer( + 0, + "bootstrap1", + "vote_for_delegate", + ['-arg', 'None', '--burn-cap', '10'], + ) + + def test_vote_for_delegate_wrong_identity2(self, client: Client): + # We check failure of CHECK_SIGNATURE ; ASSERT in the script. + with utils.assert_run_failure("At line 15 characters 57 to 61"): + client.transfer( + 0, + "bootstrap2", + "vote_for_delegate", + ['-arg', 'None', '--burn-cap', '10'], + ) + + def test_vote_for_delegate_b3_vote_for_b5(self, client: Client): + b_5 = IDENTITIES['bootstrap5']['identity'] + client.transfer( + 0, + "bootstrap3", + "vote_for_delegate", + ['-arg', f'(Some "{b_5}")', '--burn-cap', '10'], + ) + utils.bake(client, bake_for='bootstrap5') + storage = client.get_storage('vote_for_delegate') + assert re.search(b_5, storage) + + def test_vote_for_delegate_still_no_delegate1(self, client: Client): + assert client.get_delegate('vote_for_delegate').delegate is None + + def test_vote_for_delegate_b4_vote_for_b2(self, client: Client): + b_2 = IDENTITIES['bootstrap2']['identity'] + client.transfer( + 0, + "bootstrap4", + "vote_for_delegate", + ['-arg', f'(Some "{b_2}")', '--burn-cap', '10'], + ) + utils.bake(client, bake_for='bootstrap5') + storage = client.get_storage('vote_for_delegate') + assert re.search(b_2, storage) + + def test_vote_for_delegate_still_no_delegate2(self, client: Client): + assert client.get_delegate('vote_for_delegate').delegate is None + + def test_vote_for_delegate_b4_vote_for_b5(self, client: Client): + b_5 = IDENTITIES['bootstrap5']['identity'] + client.transfer( + 0, + "bootstrap4", + "vote_for_delegate", + ['-arg', f'(Some "{b_5}")', '--burn-cap', '10'], + ) + utils.bake(client, bake_for='bootstrap5') + storage = client.get_storage('vote_for_delegate') + assert re.search(b_5, storage) + + def test_vote_for_delegate_has_delegate(self, client: Client): + b_5 = IDENTITIES['bootstrap5']['identity'] + result = client.get_delegate('vote_for_delegate') + assert result.delegate == b_5 + + def test_multiple_entrypoints_counter(self, session: dict, client: Client): + path = os.path.join( + CONTRACT_PATH, 'mini_scenarios', 'multiple_entrypoints_counter.tz' + ) + + storage = 'None' + + # originate contract + originate(client, session, path, storage, 0) + utils.bake(client, bake_for='bootstrap5') + + # call contract: creates the internal contract and calls it. + client.transfer( + 0, + 'bootstrap1', + 'multiple_entrypoints_counter', + ['--burn-cap', '10'], + ) + utils.bake(client, bake_for='bootstrap5') + assert client.get_storage('multiple_entrypoints_counter') == 'None', ( + "The storage of the multiple_entrypoints_counter contract" + " should be None" + ) + + # Test CONTRACT with/without entrypoint annotation on literal address + # parameters with/without entrypoint annotation + def test_originate_simple_entrypoints(self, session: dict, client: Client): + """originates the contract simple_entrypoints.tz + with entrypoint %A of type unit used in + test_simple_entrypoints""" + + contract_target = os.path.join( + CONTRACT_PATH, 'entrypoints', 'simple_entrypoints.tz' + ) + originate(client, session, contract_target, 'Unit', 0) + utils.bake(client, bake_for='bootstrap5') + + @pytest.mark.parametrize( + 'contract_annotation, contract_type, param, expected_storage', + [ + # tests passing adr to CONTRACT %A unit + # where adr has an entrypoint %A of type unit, is allowed. + ('%A', 'unit', '"{adr}"', '(Some "{adr}%A")'), + ('%B', 'string', '"{adr}"', '(Some "{adr}%B")'), + ('%C', 'nat', '"{adr}"', '(Some "{adr}%C")'), + # tests passing adr%A to CONTRACT %A unit: redundant specification + # of entrypoint not allowed so CONTRACT returns None + ('%A', 'unit', '"{adr}%A"', 'None'), + ('%A', 'unit', '"{adr}%B"', 'None'), + ('%A', 'unit', '"{adr}%D"', 'None'), + ('%A', 'unit', '"{adr}%A"', 'None'), + ('%B', 'unit', '"{adr}%A"', 'None'), + ('%D', 'unit', '"{adr}%A"', 'None'), + # tests passing adr%A to CONTRACT unit: + # where adr has an entrypoint %A of type unit, is allowed. + ('', 'unit', '"{adr}%A"', '(Some "{adr}%A")'), + ('', 'string', '"{adr}%B"', '(Some "{adr}%B")'), + ('', 'nat', '"{adr}%C"', '(Some "{adr}%C")'), + # tests passing adr%B to CONTRACT unit: + # as entrypoint %B of simple_entrypoints.tz has type string, + # CONTRACT will return None. + ('', 'unit', '"{adr}%B"', 'None'), + # tests passing adr%D to CONTRACT unit: + # as entrypoint %D does not exist in simple_entrypoints.tz, + # CONTRACT will return None. + ('', 'unit', '"{adr}%D"', 'None'), + # tests passing adr to CONTRACT unit: + # as adr does not have type unit, CONTRACT returns None. + ('', 'unit', '"{adr}"', 'None'), + # entrypoint that does not exist + ('%D', 'unit', '"{adr}"', 'None'), + # ill-typed entrypoints + ('%A', 'int', '"{adr}"', 'None'), + ('%B', 'unit', '"{adr}"', 'None'), + ('%C', 'int', '"{adr}"', 'None'), + ], + ) + def test_simple_entrypoints( + self, + session, + client, + contract_annotation, + contract_type, + param, + expected_storage, + ): + contract = f'''parameter address; +storage (option address); +code {{ + CAR; + CONTRACT {contract_annotation} {contract_type}; + IF_SOME {{ ADDRESS; SOME }} {{ NONE address; }}; + NIL operation; + PAIR + }};''' + + param = param.format(adr=session['contract']) + expected_storage = expected_storage.format(adr=session['contract']) + run_script_res = client.run_script(contract, 'None', param, file=False) + assert run_script_res.storage == expected_storage + + +@pytest.mark.contract +class TestComparables: + def test_comparable_unit(self, client): + client.typecheck_data('{}', '(set unit)') + client.typecheck_data('{Unit}', '(set unit)') + + def test_comparable_options(self, client): + client.typecheck_data('{}', '(set (option nat))') + client.typecheck_data('{None; Some 1; Some 2}', '(set (option int))') + utils.assert_typecheck_data_failure( + client, '{Some "foo"; Some "bar"}', '(set (option string))' + ) + utils.assert_typecheck_data_failure( + client, '{Some Unit; None}', '(set (option unit))' + ) + + def test_comparable_unions(self, client): + client.typecheck_data('{}', '(set (or unit bool))') + client.typecheck_data( + '{Left 3; Left 4; Right "bar"; Right "foo"}', + '(set (or nat string))', + ) + utils.assert_typecheck_data_failure( + client, '{Left 2; Left 1}', '(set (or mutez unit))' + ) + utils.assert_typecheck_data_failure( + client, '{Right True; Right False}', '(set (or unit bool))' + ) + utils.assert_typecheck_data_failure( + client, '{Right 0; Left 1}', '(set (or nat nat))' + ) + + def test_comparable_pair(self, client: Client): + # tests that comb pairs are comparable and that the order is the + # expected one + client.typecheck_data('{}', '(set (pair nat string))') + client.typecheck_data('{Pair 0 "foo"}', '(set (pair nat string))') + client.typecheck_data( + '{Pair 0 "foo"; Pair 1 "bar"}', '(set (pair nat string))' + ) + client.typecheck_data( + '{Pair 0 "bar"; Pair 0 "foo"; \ + Pair 1 "bar"; Pair 1 "foo"}', + '(set (pair nat string))', + ) + client.typecheck_data('{}', '(set (pair nat (pair string bytes)))') + + client.typecheck_data('{}', '(map (pair nat string) unit)') + client.typecheck_data( + '{Elt (Pair 0 "foo") Unit}', '(map (pair nat string) unit)' + ) + client.typecheck_data( + '{Elt (Pair 0 "foo") Unit; \ + Elt (Pair 1 "bar") Unit}', + '(map (pair nat string) unit)', + ) + client.typecheck_data( + '{Elt (Pair 0 "bar") Unit; \ + Elt (Pair 0 "foo") Unit; \ + Elt (Pair 1 "bar") Unit; \ + Elt (Pair 1 "foo") Unit}', + '(map (pair nat string) unit)', + ) + client.typecheck_data('{}', '(map (pair nat (pair string bytes)) unit)') + + client.typecheck_data('{}', '(big_map (pair nat string) unit)') + client.typecheck_data( + '{Elt (Pair 0 "foo") Unit}', '(big_map (pair nat string) unit)' + ) + client.typecheck_data( + '{Elt (Pair 0 "foo") Unit; \ + Elt (Pair 1 "bar") Unit}', + '(big_map (pair nat string) unit)', + ) + client.typecheck_data( + '{Elt (Pair 0 "bar") Unit; \ + Elt (Pair 0 "foo") Unit; \ + Elt (Pair 1 "bar") Unit; \ + Elt (Pair 1 "foo") Unit}', + '(big_map (pair nat string) unit)', + ) + client.typecheck_data( + '{}', '(big_map (pair nat (pair string bytes)) unit)' + ) + client.typecheck_data('{}', '(set (pair (pair nat nat) nat))') + client.typecheck_data( + '{}', + '(set (pair (pair int nat) \ + (pair bool bytes)))', + ) + + def test_order_of_pairs(self, client: Client): + # tests that badly-ordered set literals are rejected + utils.assert_typecheck_data_failure( + client, '{Pair 0 "foo"; Pair 0 "bar"}', '(set (pair nat string))' + ) + utils.assert_typecheck_data_failure( + client, '{Pair 1 "bar"; Pair 0 "foo"}', '(set (pair nat string))' + ) + + def test_comparable_chain_id(self, client): + client.typecheck_data('{}', '(set chain_id)') + chain1 = client.rpc('get', 'chains/main/chain_id') + chain2 = 'NetXZVhNXbDTx5M' + utils.assert_typecheck_data_failure( + client, + '{"' + f'{chain1}' + '"; "' + f'{chain2}' + '"}', + '(set chain_id)', + ) + client.typecheck_data( + '{"' + f'{chain2}' + '"; "' + f'{chain1}' + '"}', '(set chain_id)' + ) + + def test_comparable_signature(self, client): + client.typecheck_data('{}', '(set signature)') + packed = client.pack('Unit', 'unit') + sig1 = client.sign_bytes_of_string(packed, "bootstrap1") + sig2 = client.sign_bytes_of_string(packed, "bootstrap2") + utils.assert_typecheck_data_failure( + client, + '{"' + f'{sig1}' + '"; "' + f'{sig2}' + '"}', + '(set signature)', + ) + client.typecheck_data( + '{"' + f'{sig2}' + '"; "' + f'{sig1}' + '"}', '(set signature)' + ) + + def test_comparable_key(self, client): + pubkey1 = IDENTITIES['bootstrap1']['public'] + pubkey2 = IDENTITIES['bootstrap2']['public'] + client.typecheck_data('{}', '(set key)') + utils.assert_typecheck_data_failure( + client, + '{"' + f'{pubkey1}' + '"; "' + f'{pubkey2}' + '"}', + '(set key)', + ) + client.typecheck_data( + '{"' + f'{pubkey2}' + '"; "' + f'{pubkey1}' + '"}', '(set key)' + ) + + def test_comparable_key_different_schemes(self, client): + client.gen_key('sk1', ['--sig', 'ed25519']) + key1 = client.show_address('sk1').public_key + + client.gen_key('sk2', ['--sig', 'secp256k1']) + key2 = client.show_address('sk2').public_key + + client.gen_key('sk3', ['--sig', 'p256']) + key3 = client.show_address('sk3').public_key + + # Three public keys of the three different signature schemes, ordered + client.typecheck_data( + '{"' + key1 + '"; "' + key2 + '"; "' + key3 + '"}', '(set key)' + ) + + # Test all orderings that do not respect the comparable order + utils.assert_typecheck_data_failure( + client, + '{"' + key1 + '"; "' + key3 + '"; "' + key2 + '"}', + '(set key)', + ) + + utils.assert_typecheck_data_failure( + client, + '{"' + key2 + '"; "' + key1 + '"; "' + key3 + '"}', + '(set key)', + ) + + utils.assert_typecheck_data_failure( + client, + '{"' + key2 + '"; "' + key3 + '"; "' + key1 + '"}', + '(set key)', + ) + + utils.assert_typecheck_data_failure( + client, + '{"' + key3 + '"; "' + key1 + '"; "' + key2 + '"}', + '(set key)', + ) + + utils.assert_typecheck_data_failure( + client, + '{"' + key3 + '"; "' + key2 + '"; "' + key1 + '"}', + '(set key)', + ) + + +@pytest.mark.contract +class TestTypecheckingErrors: + def test_big_map_arity_error(self, client: Client): + error_pattern = ( + 'primitive EMPTY_BIG_MAP expects 2 arguments but is given 1.' + ) + with utils.assert_run_failure(error_pattern): + client.typecheck( + os.path.join(CONTRACT_PATH, 'ill_typed', 'big_map_arity.tz') + ) + + +BAD_ANNOT_TEST = ''' +parameter bytes; +storage (option (lambda unit unit)); +code { CAR; UNPACK (lambda unit unit); NIL operation; PAIR} +''' + + +@pytest.mark.incremental +@pytest.mark.contract +class TestBadAnnotation: + def test_write_contract_bad_annot(self, tmpdir, session: dict): + name = 'bad_annot.tz' + contract = f'{tmpdir}/{name}' + script = BAD_ANNOT_TEST + with open(contract, 'w') as contract_file: + contract_file.write(script) + session[name] = contract + + def test_bad_annotation(self, client: Client, session: dict): + name = 'bad_annot.tz' + contract = session[name] + + # This was produced by running "tezos-client hash data '{ UNIT + # ; PAIR ; CAR %faa }' of type 'lambda unit unit'" and + # replacing the two last bytes (that correspond to the two + # 'a's at the end of the annotation) by the 0xff byte which is + # not a valid UTF8-encoding of a string + parameter = '0x05020000000e034f03420416000000042566ffff' + + res = client.run_script(contract, 'None', parameter) + assert res.storage == 'None' + + +@pytest.mark.contract +class TestOrderInTopLevelDoesNotMatter: + @pytest.fixture + def contract_splitted_in_top_level_elements(self): + return [ + "parameter nat", + "storage unit", + "code { CDR; NIL operation; PAIR }", + ] + + def test_shuffle( + self, client: Client, contract_splitted_in_top_level_elements + ): + """ + Test that the storage, code, and parameter sections can appear in any + order in a contract script. + """ + for shuffled_list in itertools.permutations( + contract_splitted_in_top_level_elements + ): + contract = ";\n".join(shuffled_list) + client.typecheck(contract, file=False) + + +@pytest.mark.incremental +@pytest.mark.contract +@pytest.mark.regression +class TestSelfAddressTransfer: + def test_self_address_originate_sender( + self, client_regtest_scrubbed, session + ): + client = client_regtest_scrubbed + path = os.path.join( + CONTRACT_PATH, 'mini_scenarios', 'self_address_sender.tz' + ) + originate(client, session, path, 'Unit', 0) + + def test_self_address_originate_receiver( + self, client_regtest_scrubbed, session + ): + client = client_regtest_scrubbed + path = os.path.join( + CONTRACT_PATH, 'mini_scenarios', 'self_address_receiver.tz' + ) + originate(client, session, path, 'Unit', 0) + session['receiver_address'] = session['contract'] + + def test_send_self_address(self, client_regtest_scrubbed, session): + client = client_regtest_scrubbed + receiver_address = session['receiver_address'] + client.transfer( + 0, + 'bootstrap2', + 'self_address_sender', + ['--arg', f'"{receiver_address}"', '--burn-cap', '2'], + ) + utils.bake(client, 'bootstrap5') + + +@pytest.mark.slow +@pytest.mark.contract +@pytest.mark.regression +class TestScriptHashRegression: + @pytest.mark.parametrize( + "client_regtest_custom_scrubber", + [[(re.escape(CONTRACT_PATH), '[CONTRACT_PATH]')]], + indirect=True, + ) + def test_contract_hash(self, client_regtest_custom_scrubber: Client): + client = client_regtest_custom_scrubber + contracts = all_contracts() + contracts.sort() + for contract in contracts: + assert contract.endswith( + '.tz' + ), "test contract should have .tz extension" + + client.hash_script( + [os.path.join(CONTRACT_PATH, contract) for contract in contracts], + display_names=True, + ) + + +@pytest.mark.contract +class TestScriptHashOrigination: + def test_contract_hash_with_origination( + self, client: Client, session: dict + ): + script = ID_SCRIPT_LITERAL + originate( + client, + session, + contract=script, + init_storage='Unit', + amount=1000, + contract_name='dummy_contract', + ) + [(hash1, _)] = client.hash_script([script]) + hash2 = client.get_script_hash('dummy_contract') + assert hash1 == hash2 + + +@pytest.mark.contract +class TestScriptHashMultiple: + """Test tezos-client hash script with diffent number and type of + arguments""" + + def test_contract_hashes_empty(self, client: Client): + assert client.hash_script([]) == [] + + def test_contract_hashes_single(self, client: Client): + assert client.hash_script([ID_SCRIPT_LITERAL]) == [ + (ID_SCRIPT_HASH, None) + ] + + def test_contract_hashes_single_display_names(self, client: Client): + assert client.hash_script([ID_SCRIPT_LITERAL], display_names=True,) == [ + ( + ID_SCRIPT_HASH, + 'Literal script 1', + ) + ] + + def test_contract_hashes_mixed(self, client: Client): + contract_path = os.path.join(CONTRACT_PATH, 'attic', 'empty.tz') + script_empty_hash = ''' +expruat2BS4KCwn9kbopeX1ZwxtrtJbyFhpnpnG6A5KdCBCwHNsdod + '''.strip() + with open(contract_path, 'r') as contract_file: + script = contract_file.read() + + hashes = client.hash_script([contract_path, script]) + + assert hashes == [ + ( + script_empty_hash, + None, + ), + ( + script_empty_hash, + None, + ), + ] + + hashes = client.hash_script( + [contract_path, script], display_names=True + ) + + assert hashes == [ + ( + script_empty_hash, + contract_path, + ), + ( + script_empty_hash, + 'Literal script 2', + ), + ] + + @pytest.mark.parametrize( + "for_script, display_names, results", + [ + ('csv', True, (ID_SCRIPT_HASH, 'Literal script 1')), + ('csv', False, (ID_SCRIPT_HASH, None)), + ('tsv', True, (ID_SCRIPT_HASH, 'Literal script 1')), + ('tsv', False, (ID_SCRIPT_HASH, None)), + ], + ) + def test_contract_hashes_for_script( + self, client: Client, for_script, display_names, results + ): + assert ( + client.hash_script( + [ID_SCRIPT_LITERAL], + display_names=display_names, + for_script=for_script, + ) + == [results] + ) + + +@pytest.mark.contract +@pytest.mark.regression +class TestNormalize: + """Regression tests for the "normalize data" command.""" + + modes = [None, 'Readable', 'Optimized', 'Optimized_legacy'] + + @pytest.mark.parametrize('mode', modes) + def test_normalize_unparsing_mode(self, client_regtest_scrubbed, mode): + client = client_regtest_scrubbed + input_data = ( + '{Pair 0 3 6 9; Pair 1 (Pair 4 (Pair 7 10)); {2; 5; 8; 11}}' + ) + input_type = 'list (pair nat nat nat nat)' + client.normalize(input_data, input_type, mode=mode) + + def test_normalize_legacy_flag(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + input_data = '{Elt %a 0 1}' + input_type = 'map nat nat' + client.normalize(input_data, input_type, legacy=True) + error_pattern = 'unexpected annotation.' + with utils.assert_run_failure(error_pattern): + client.normalize(input_data, input_type, legacy=False) + + @pytest.mark.parametrize('mode', modes) + def test_normalize_script(self, client_regtest_scrubbed, mode): + client = client_regtest_scrubbed + path = os.path.join(CONTRACT_PATH, 'opcodes', 'comb-literals.tz') + client.normalize_script(path, mode=mode) + + types = [ + 'nat', + 'list nat', + 'pair nat int', + 'list (pair nat int)', + 'pair nat int bool', + 'list (pair nat int bool)', + 'pair nat int bool bytes', + 'list (pair nat int bool bytes)', + ] + + @pytest.mark.parametrize('typ', types) + def test_normalize_type(self, client_regtest_scrubbed, typ): + client = client_regtest_scrubbed + client.normalize_type(typ) + + +@pytest.mark.contract +class TestTZIP4View: + """Tests for the "run tzip4 view" command.""" + + def test_run_view(self, client: Client, session: dict): + + path = os.path.join(CONTRACT_PATH, 'mini_scenarios', 'tzip4_view.tz') + originate( + client, + session, + contract=path, + init_storage='Unit', + amount=1000, + contract_name='view_contract', + ) + utils.bake(client, bake_for='bootstrap5') + + const_view_res = client.run_view( + "view_const", "view_contract", "Unit", [] + ) + add_view_res = client.run_view( + "view_add", "view_contract", "Pair 1 3", [] + ) + + assert const_view_res.result == "5\n" and add_view_res.result == "4\n" + + +@pytest.mark.contract +@pytest.mark.incremental +class TestBadIndentation: + """Tests for the "hash script" and "convert script" commands on + badly-indented scripts.""" + + BADLY_INDENTED = os.path.join(ILLTYPED_CONTRACT_PATH, 'badly_indented.tz') + + SCRIPT_HASH = "exprv8K6ceBpFH5SFjQm4BRYSLJCHQBFeQU6BFTdvQSRPaPkzdLyAL" + + def test_bad_indentation_ill_typed(self, client): + with utils.assert_run_failure('syntax error in program'): + client.typecheck(self.BADLY_INDENTED) + + def test_bad_indentation_hash(self, client): + assert client.hash_script([self.BADLY_INDENTED]) == [ + (self.SCRIPT_HASH, None) + ] + + def test_formatting(self, client, session): + session['formatted_script'] = client.convert_script( + self.BADLY_INDENTED, 'Michelson', 'Michelson' + ) + + def test_formatted_hash(self, client, session): + assert client.hash_script([session['formatted_script']]) == [ + (self.SCRIPT_HASH, None) + ] + + def test_formatted_typechecks(self, client, session): + client.typecheck(session['formatted_script'], file=False) + + +@pytest.mark.contract +@pytest.mark.incremental +class TestContractTypeChecking: + """Typechecking tests for the address and (contract _) types.""" + + def check_address(self, client, address): + """An address followed by an entrypoint typechecks at type address if + and only if the entrypoint is not "default".""" + + address_a = f'"{address}%a"' + address_opt = client.normalize( + f'"{address}"', 'address', 'Optimized' + ).strip() + address_opt_a = client.normalize( + address_a, 'address', 'Optimized' + ).strip() + + client.typecheck_data(f'"{address}"', 'address') + client.typecheck_data(f'{address_a}', 'address') + client.typecheck_data(f'{address_opt}', 'address') + client.typecheck_data(f'{address_opt_a}', 'address') + + unexpected_annotation_error = "unexpected annotation." + + with utils.assert_run_failure(unexpected_annotation_error): + client.typecheck_data(f'"{address}%default"', 'address') + + # 64656661756c74 is "default" in hexa + with utils.assert_run_failure(unexpected_annotation_error): + client.typecheck_data(address_opt + '64656661756c74', 'address') + + def check_contract_ok(self, client, address, entrypoint, typ): + """Helper to check that an address followed by an entrypoint typechecks + at type (contract typ) using both readable and optimised + representations.""" + + address_readable = f'"{address}"' + if entrypoint is not None: + address_readable = f'"{address}%{entrypoint}"' + + address_opt = client.normalize( + address_readable, 'address', 'Optimized' + ).strip() + + client.typecheck_data(address_readable, f'contract ({typ})') + client.typecheck_data(address_opt, f'contract ({typ})') + + client.run_script( + f""" +parameter unit; +storage address; +code {{ + CDR; + CONTRACT ({typ}); + ASSERT_SOME; + ADDRESS; + NIL operation; + PAIR }}""", + address_readable, + 'Unit', + file=False, + ) + + def check_contract_ko( + self, client, address, entrypoint, typ, expected_error + ): + """Helper to check that an address followed by an entrypoint does not + typecheck at type (contract typ) using both readable and optimised + representations.""" + + address_readable = f'"{address}"' + if entrypoint is not None: + address_readable = f'"{address}%{entrypoint}"' + + address_opt = client.normalize( + address_readable, 'address', 'Optimized' + ).strip() + + with utils.assert_run_failure(expected_error): + client.typecheck_data(address_readable, f'contract ({typ})') + with utils.assert_run_failure(expected_error): + client.typecheck_data(address_opt, f'contract ({typ})') + + client.run_script( + f""" +parameter unit; +storage address; +code {{ + CDR; + DUP; + CONTRACT ({typ}); + ASSERT_NONE; + NIL operation; + PAIR }}""", + address_readable, + 'Unit', + file=False, + ) + + def test_implicit(self, client): + """The address of an implicit account followed by some entrypoint + typechecks: + - at type address if the entrypoint is not "default", + - at type (contract ) if the entrypoint is empty and ty is unit.""" + + tz1 = 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx' + + self.check_address(client, tz1) + self.check_contract_ok(client, tz1, None, 'unit') + + no_entrypoint_error = 'Contract has no entrypoint named a' + type_mismatch_error = 'Type nat is not compatible with type unit.' + self.check_contract_ko(client, tz1, 'a', 'unit', no_entrypoint_error) + self.check_contract_ko(client, tz1, 'a', 'nat', no_entrypoint_error) + self.check_contract_ko(client, tz1, None, 'nat', type_mismatch_error) + + def test_originated_inexistent(self, client): + """The address of an inexistent originated account followed by some + entrypoint typechecks: + - at type address if the entrypoint is not "default", + - at no (contract _) type.""" + + kt1 = 'KT1RvwLgpxVv9ANCKsDb5vBgTaZRG1W4bKWP' + + self.check_address(client, kt1) + + invalid_contract_error = 'invalid contract.' + self.check_contract_ko( + client, kt1, None, 'unit', invalid_contract_error + ) + self.check_contract_ko(client, kt1, 'a', 'unit', invalid_contract_error) + self.check_contract_ko(client, kt1, None, 'nat', invalid_contract_error) + self.check_contract_ko(client, kt1, 'a', 'nat', invalid_contract_error) + + def test_originated_no_default(self, client, session): + """The address of an existent originated account that does not specify + a default entrypoint followed by some entrypoint typechecks: + - at type address if the entrypoint is not "default", + - at type (contract ) if + - the entrypoint is empty and is the root type + - the entrypoint is non-empty, one of the declared entrypoints, and + is the type associated to that entrypoint.""" + + path = os.path.join( + CONTRACT_PATH, 'entrypoints', 'simple_entrypoints.tz' + ) + origination = originate(client, session, path, 'Unit', 0) + kt1 = origination.contract + root_type = 'or (unit %A) (or (string %B) (nat %C))' + a_type = 'unit' + b_type = 'string' + + self.check_address(client, kt1) + self.check_contract_ok(client, kt1, None, root_type) + self.check_contract_ok(client, kt1, 'A', a_type) + self.check_contract_ok(client, kt1, 'B', b_type) + + no_entrypoint_error = 'Contract has no entrypoint named a' + self.check_contract_ko(client, kt1, 'a', a_type, no_entrypoint_error) + + def test_originated_with_default(self, client, session): + """The address of an existent originated account that specifies + a default entrypoint followed by some entrypoint typechecks: + - at type address if the entrypoint is not "default", + - at type (contract ) if + - the entrypoint is empty and is the type of the default + entrypoint + - the entrypoint is non-empty, one of the declared entrypoints, and + is the type associated to that entrypoint.""" + + path = os.path.join( + CONTRACT_PATH, 'entrypoints', 'delegatable_target.tz' + ) + initial_storage = 'Pair "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" "" 0' + origination = originate(client, session, path, initial_storage, 0) + kt1 = origination.contract + root_type = ( + 'or (or (key_hash %set_delegate) (unit %remove_delegate))' + '(or %default string nat)' + ) + default_type = 'or string nat' + + self.check_address(client, kt1) + self.check_contract_ok(client, kt1, None, default_type) + self.check_contract_ok(client, kt1, 'set_delegate', 'key_hash') + + no_entrypoint_error = 'Contract has no entrypoint named a' + self.check_contract_ko(client, kt1, 'a', root_type, no_entrypoint_error) + + type_mismatch_error = 'is not compatible with type' + self.check_contract_ko( + client, kt1, None, root_type, type_mismatch_error + ) diff --git a/tests_python/tests_012/test_contract_annotations.py b/tests_python/tests_012/test_contract_annotations.py new file mode 100644 index 000000000000..c34dcc016ee1 --- /dev/null +++ b/tests_python/tests_012/test_contract_annotations.py @@ -0,0 +1,88 @@ +import pytest +from tools.utils import assert_typecheck_data_failure, assert_typecheck_failure +from client.client import Client + + +@pytest.mark.slow +@pytest.mark.contract +class TestAnnotations: + """Tests of Michelson annotations.""" + + def test_annotation_length_success(self, client: Client): + client.typecheck_data('3', f"(int :{'a' * 254})") + + def test_annotation_length_failure(self, client: Client): + assert_typecheck_data_failure( + client, + '3', + f"(int :{'a' * 255})", + r'annotation exceeded maximum length \(255 chars\)', + ) + + def test_field_annotation_in_type_alphabetic(self, client): + client.typecheck_data('Pair 0 0', 'pair (nat %x) (int %y)') + + def test_field_annotation_in_type_numeral(self, client): + client.typecheck_data('Pair 0 0', 'pair (nat %1) (int %2)') + + def test_field_annotation_in_type_invalid_character(self, client): + assert_typecheck_data_failure( + client, + 'Pair 0 0', + 'pair (nat %.) (int %.)', + 'unexpected annotation', + ) + + def test_field_annotation_in_instruction_alphabetic(self, client): + client.typecheck_data( + '{ CAR %x }', 'lambda (pair (nat %x) (int %y)) nat' + ) + + def test_field_annotation_in_instruction_numeral(self, client): + client.typecheck_data( + '{ CAR %1 }', 'lambda (pair (nat %1) (int %2)) nat' + ) + + def test_field_annotation_in_instruction_invalid_character(self, client): + assert_typecheck_data_failure( + client, + '{ CAR %. }', + 'lambda (pair (nat %.) (int %.)) nat', + 'unexpected annotation', + ) + + def test_field_annotation_in_root_alphabetic(self, client): + client.typecheck( + 'parameter %r unit; storage unit; code {FAILWITH}', file=False + ) + + def test_field_annotation_in_root_numeral(self, client): + client.typecheck( + 'parameter %1 unit; storage unit; code {FAILWITH}', file=False + ) + + def test_field_annotation_in_root_invalid_character(self, client): + assert_typecheck_failure( + client, + 'parameter %. unit; storage unit; code {FAILWITH}', + 'unexpected annotation', + file=False, + ) + + def test_field_annotation_in_root_type_alphabetic(self, client): + client.typecheck( + 'parameter (unit %r); storage unit; code {FAILWITH}', file=False + ) + + def test_field_annotation_in_root_type_numeral(self, client): + client.typecheck( + 'parameter (unit %1); storage unit; code {FAILWITH}', file=False + ) + + def test_field_annotation_in_root_type_invalid_character(self, client): + assert_typecheck_failure( + client, + 'parameter (unit %.); storage unit; code {FAILWITH}', + 'unexpected annotation', + file=False, + ) diff --git a/tests_python/tests_012/test_contract_baker.py b/tests_python/tests_012/test_contract_baker.py new file mode 100644 index 000000000000..73dfd0cd43a5 --- /dev/null +++ b/tests_python/tests_012/test_contract_baker.py @@ -0,0 +1,55 @@ +import os +import pytest +from tools import constants, utils +from client.client import Client +from . import contract_paths + + +@pytest.mark.contract +@pytest.mark.baker +@pytest.mark.incremental +class TestOriginationCall: + """Test a simple contract origination and call""" + + def test_originate(self, client: Client, session: dict): + initial_storage = 'Unit' + contract = os.path.join( + contract_paths.OPCODES_CONTRACT_PATH, 'transfer_tokens.tz' + ) + args = ['--init', initial_storage, '--burn-cap', '0.400'] + origination = client.originate( + 'foobar', 1000, 'bootstrap1', contract, args + ) + session['contract'] = origination.contract + utils.bake(client, bake_for="bootstrap5") + + # Unsolved mystery: + # client.wait_for_inclusion(origination.operation_hash) + # fails sometimes with tezos-client crashing. Maybe caused with + # subprocess captured of forked process output? + # + # Safer to poll with `check_block_contain_operations` + assert utils.check_block_contains_operations( + client, [origination.operation_hash] + ) + + def test_call(self, client: Client, session: dict): + contract = session['contract'] + bootstrap3 = '"tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU"' + transfer = client.call('bootstrap2', contract, ['--arg', bootstrap3]) + utils.bake(client, bake_for="bootstrap5") + assert utils.check_block_contains_operations( + client, [transfer.operation_hash] + ) + + def test_balance(self, client: Client): + bootstrap3 = constants.IDENTITIES['bootstrap3']['identity'] + deposit = client.frozen_deposits(bootstrap3) + balance = client.get_mutez_balance('bootstrap3') + assert balance + deposit == utils.mutez_of_tez(4000100.0) + + def test_query_storage(self, client: Client, session: dict): + contract = session['contract'] + url = f'/chains/main/blocks/head/context/contracts/{contract}/storage' + res = client.rpc('get', url) + assert res['prim'] == 'Unit' diff --git a/tests_python/tests_012/test_contract_bls12_381.py b/tests_python/tests_012/test_contract_bls12_381.py new file mode 100644 index 000000000000..50e626c0623f --- /dev/null +++ b/tests_python/tests_012/test_contract_bls12_381.py @@ -0,0 +1,317 @@ +from os import path +import random +from hashlib import blake2b +import pytest + +from tools.bls12_381 import G1, G2, Fr, pairing_check +from tools.utils import assert_run_failure +from .contract_paths import MINI_SCENARIOS_CONTRACT_PATH, OPCODES_CONTRACT_PATH + + +def check_contract(client, contract_name, arg, expected_storage): + contract_path = path.join(OPCODES_CONTRACT_PATH, f'{contract_name}.tz') + result = client.run_script(contract_path, 'None', arg) + assert result.storage == f'(Some {expected_storage})' + + +def check_contract_binop(client, contract_name, arg0, arg1, expected_storage): + check_contract( + client, contract_name, f'Pair {arg0} {arg1}', expected_storage + ) + + +# prefix a type name with 'bls12_381_' +def bls(tname): + return f'bls12_381_{tname}' + + +# Store +def check_store(client, cls, arg): + arg = cls.to_hex(arg) + check_contract(client, f'store_{bls(cls.name)}', arg, arg) + + +# Add +def check_add(client, cls, xxx, yyy): + check_contract_binop( + client, + f'add_{bls(cls.name)}', + cls.to_hex(xxx), + cls.to_hex(yyy), + cls.to_hex(cls.add(xxx, yyy)), + ) + + +# Mul +def check_mul(client, cls, xxx, yyy): + check_contract_binop( + client, + f'mul_{bls(cls.name)}', + cls.to_hex(xxx), + Fr.to_hex(yyy), + cls.to_hex(cls.mul(xxx, yyy)), + ) + + +# Neg +def check_neg(client, cls, arg): + res = cls.to_hex(cls.neg(arg)) + arg = cls.to_hex(arg) + check_contract(client, f'neg_{bls(cls.name)}', arg, res) + + +# Pairing Check +def check_pairing_check(client, args): + res = pairing_check(args) + args = [(G1.to_hex(g1), G2.to_hex(g2)) for g1, g2 in args] + args = [f'Pair {g1} {g2}' for g1, g2 in args] + args = f'{{ {"; ".join(args)} }}' + check_contract(client, 'pairing_check', args, res) + + +# Setting this higher makes things rather slow +RANDOM_ITERATIONS = range(10) + + +STORE_CLASSES = [G1, G2, Fr] +CURVES = [G1, G2] +ADD_CLASSES = [G1, G2, Fr] +MUL_CLASSES = [G1, G2, Fr] +NEG_CLASSES = [G1, G2, Fr] + + +@pytest.mark.incremental +@pytest.mark.contract +@pytest.mark.regression +class TestBls12_381: + + # Fix the random seed to ensure reproducibility + h = blake2b() + h.update(b'seed') + gen = random.Random() + gen.seed(bytes.fromhex(h.hexdigest())) + + # Store + + @pytest.mark.parametrize("cls", STORE_CLASSES) + def test_store_zero(self, client_regtest, cls): + check_store(client_regtest, cls, cls.zero) + + @pytest.mark.parametrize("cls", STORE_CLASSES) + def test_store_one(self, client_regtest, cls): + check_store(client_regtest, cls, cls.one) + + @pytest.mark.parametrize("cls", STORE_CLASSES) + def test_store_random(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_store(client_regtest, cls, cls.random(self.gen)) + + # Add + @pytest.mark.parametrize("cls", ADD_CLASSES) + def test_add_zero_zero(self, client_regtest, cls): + check_add(client_regtest, cls, cls.zero, cls.zero) + + @pytest.mark.parametrize("cls", ADD_CLASSES) + def test_add_zero_one(self, client_regtest, cls): + check_add(client_regtest, cls, cls.zero, cls.one) + + @pytest.mark.parametrize("cls", ADD_CLASSES) + def test_add_zero_random(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_add(client_regtest, cls, cls.zero, cls.random(self.gen)) + + @pytest.mark.parametrize("cls", ADD_CLASSES) + def test_add_one_zero(self, client_regtest, cls): + check_add(client_regtest, cls, cls.one, cls.zero) + + @pytest.mark.parametrize("cls", ADD_CLASSES) + def test_add_one_one(self, client_regtest, cls): + check_add(client_regtest, cls, cls.one, cls.one) + + @pytest.mark.parametrize("cls", ADD_CLASSES) + def test_add_one_random(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_add(client_regtest, cls, cls.one, cls.random(self.gen)) + + @pytest.mark.parametrize("cls", ADD_CLASSES) + def test_add_random_zero(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_add(client_regtest, cls, cls.random(self.gen), cls.zero) + + @pytest.mark.parametrize("cls", ADD_CLASSES) + def test_add_random_one(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_add(client_regtest, cls, cls.random(self.gen), cls.one) + + @pytest.mark.parametrize("cls", ADD_CLASSES) + def test_add_random_random(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_add( + client_regtest, cls, cls.random(self.gen), cls.random(self.gen) + ) + + # Mul + @pytest.mark.parametrize("cls", MUL_CLASSES) + def test_mul_zero_zero(self, client_regtest, cls): + check_mul(client_regtest, cls, cls.zero, Fr.zero) + + @pytest.mark.parametrize("cls", MUL_CLASSES) + def test_mul_zero_one(self, client_regtest, cls): + check_mul(client_regtest, cls, cls.zero, Fr.one) + + @pytest.mark.parametrize("cls", MUL_CLASSES) + def test_mul_zero_random(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_mul(client_regtest, cls, cls.zero, Fr.random(self.gen)) + + @pytest.mark.parametrize("cls", MUL_CLASSES) + def test_mul_one_zero(self, client_regtest, cls): + check_mul(client_regtest, cls, cls.one, Fr.zero) + + @pytest.mark.parametrize("cls", MUL_CLASSES) + def test_mul_one_one(self, client_regtest, cls): + check_mul(client_regtest, cls, cls.one, Fr.one) + + @pytest.mark.parametrize("cls", MUL_CLASSES) + def test_mul_one_random(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_mul(client_regtest, cls, cls.one, Fr.random(self.gen)) + + @pytest.mark.parametrize("cls", MUL_CLASSES) + def test_mul_random_zero(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_mul(client_regtest, cls, cls.random(self.gen), Fr.zero) + + @pytest.mark.parametrize("cls", MUL_CLASSES) + def test_mul_random_one(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_mul(client_regtest, cls, cls.random(self.gen), Fr.one) + + @pytest.mark.parametrize("cls", MUL_CLASSES) + def test_mul_random_random(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_mul( + client_regtest, cls, cls.random(self.gen), Fr.random(self.gen) + ) + + # Neg + @pytest.mark.parametrize("cls", NEG_CLASSES) + def test_neg_zero(self, client_regtest, cls): + check_neg(client_regtest, cls, cls.zero) + + @pytest.mark.parametrize("cls", NEG_CLASSES) + def test_neg_one(self, client_regtest, cls): + check_neg(client_regtest, cls, cls.one) + + @pytest.mark.parametrize("cls", NEG_CLASSES) + def test_neg_random(self, client_regtest, cls): + for _ in RANDOM_ITERATIONS: + check_neg(client_regtest, cls, cls.random(self.gen)) + + # Pairing checks + def test_pairing_nil(self, client_regtest): + check_pairing_check(client_regtest, []) + + def test_pairing_zero_zero(self, client_regtest): + args = [(G1.zero, G2.zero)] + check_pairing_check(client_regtest, args) + + def test_pairing_zero_one(self, client_regtest): + args = [(G1.zero, G2.one)] + check_pairing_check(client_regtest, args) + + def test_pairing_zero_random(self, client_regtest): + for _ in RANDOM_ITERATIONS: + args = [(G1.zero, G2.random(self.gen))] + check_pairing_check(client_regtest, args) + + def test_pairing_one_zero(self, client_regtest): + args = [(G1.one, G2.zero)] + check_pairing_check(client_regtest, args) + + def test_pairing_one_one(self, client_regtest): + args = [(G1.one, G2.one)] + check_pairing_check(client_regtest, args) + + def test_pairing_one_random(self, client_regtest): + for _ in RANDOM_ITERATIONS: + args = [(G1.one, G2.random(self.gen))] + check_pairing_check(client_regtest, args) + + def test_pairing_random_zero(self, client_regtest): + for _ in RANDOM_ITERATIONS: + args = [(G1.random(self.gen), G2.zero)] + check_pairing_check(client_regtest, args) + + def test_pairing_random_one(self, client_regtest): + for _ in RANDOM_ITERATIONS: + args = [(G1.random(self.gen), G2.one)] + check_pairing_check(client_regtest, args) + + def test_pairing_random_random(self, client_regtest): + for _ in RANDOM_ITERATIONS: + args = [(G1.random(self.gen), G2.random(self.gen))] + check_pairing_check(client_regtest, args) + + def test_pairing_neg_g1(self, client_regtest): + for _ in RANDOM_ITERATIONS: + g1_point = G1.random(self.gen) + g2_point = G2.random(self.gen) + args = [(g1_point, g2_point), (G1.neg(g1_point), g2_point)] + check_pairing_check(client_regtest, args) + + def test_pairing_neg_g2(self, client_regtest): + for _ in RANDOM_ITERATIONS: + g1_point = G1.random(self.gen) + g2_point = G2.random(self.gen) + args = [(g1_point, g2_point), (g1_point, G2.neg(g2_point))] + check_pairing_check(client_regtest, args) + + # Pairing Check test based on signature aggregation + def test_signature_aggregation(self, client_regtest): + for _ in RANDOM_ITERATIONS: + sk0 = Fr.random(self.gen) # secret key + pk0 = G2.mul(G2.one, sk0) # public key + # we don't have hash-to-curve on g1, so compute a random point + msg_hash = G1.random(self.gen) # message hash + sig0 = G1.mul(msg_hash, sk0) # signature + args0 = [(msg_hash, pk0), (G1.neg(sig0), G2.one)] + check_pairing_check(client_regtest, args0) + + sk1 = Fr.random(self.gen) # secret key + pk1 = G2.mul(G2.one, sk1) # public key + # we don't have hash-to-curve on g1, so compute a random point + sig1 = G1.mul(msg_hash, sk1) # signature + args1 = [ + (G1.add(msg_hash, msg_hash), G2.add(pk0, pk1)), + (G1.neg(G1.add(sig0, sig1)), G2.add(G2.one, G2.one)), + ] + check_pairing_check(client_regtest, args1) + + def test_groth16(self, client_regtest): + # pylint: disable=line-too-long + # The verifying key, proof, and inputs are generated from + # ZoKrates, modified to use BLS12-381. + # The circuit proves knowledge of a square root of 113569. + + input_x = "0xa1bb010000000000000000000000000000000000000000000000000000000000" # noqa + input_y = "0x0100000000000000000000000000000000000000000000000000000000000000" # noqa + proof_a = "0x0a2841423326ab08f5f406409775e43fa0f9a0b97631fa85d2dd9242507d25059e9cf48b8b98f99a0008671423a148ec106d70637056972ef49fb6f62de2e89ba3682b9972292b6bb4e6f53799a75d2f8001ccfde280d8ac05fc209352236cbd" # noqa + proof_b = "0x0fced939fb1ad733f99669f50a383ef632f6d41dfbde434a6715afd5c7dfbb7bc5835e058ad8b590c7b38dd137d0bd0f0e1540f1b45d8aa626c360e2ea484a116243f7c802034de915db6b18d5303946f676e423cbd6046d37a82208d500625a11c7250ccb953a7ee49d704ad14de4b727733cff7cf06875d8b6444f3c0a8cbf0bd980e539c74bd5b37bb15fe816f23407d269193105fda71adf35fae9309d9d46729fcd4685699097a86f0460a2bc8b16293940cabfdcfe0f27e4107e74e90c" # noqa + proof_c = "0x0a1fb5a144ca3bdfe4ad0f183cf71dd7fdd28cbef4fcd47b5b419f65186703f62ecaaa1255fa21a6ebdd917ab1f9bd9707de7066865e2ff3875e22088619125a0d4088a622ab42224425ef89a5a149ce2db9c8292b62c7e7aaa7e87f3535304b" # noqa + + inputs = f"Pair {input_x} {input_y}" + proof = f"Pair (Pair {proof_a} {proof_b}) {proof_c}" + arg = f"Pair ({inputs}) ({proof})" + + contract = path.join(MINI_SCENARIOS_CONTRACT_PATH, 'groth16.tz') + client_regtest.run_script(contract, 'Unit', arg) + + def test_fr_bytes_parameters_more_than_32_bytes(self, client_regtest): + random_bytes = ( + "0xf7ef66f95c90b2f953eb0555af65f22095d4f54b40ea8c6d" + + "cc2014740e8662c16bb8786723" + ) + contract = path.join(OPCODES_CONTRACT_PATH, 'bls12_381_fr_to_int.tz') + with assert_run_failure(r'error running script'): + client_regtest.run_script(contract, storage='0', inp=random_bytes) diff --git a/tests_python/tests_012/test_contract_macros.py b/tests_python/tests_012/test_contract_macros.py new file mode 100644 index 000000000000..8528f37165f7 --- /dev/null +++ b/tests_python/tests_012/test_contract_macros.py @@ -0,0 +1,447 @@ +from os import path +import pytest +from tools.utils import ( + assert_run_script_failwith, + assert_transfer_failwith, + init_with_transfer, + bake, + assert_storage_contains, +) +from tools.client_regression import ClientRegression +from client.client import Client +from .contract_paths import MACROS_CONTRACT_PATH, CONTRACT_PATH, all_contracts + + +@pytest.mark.contract +class TestContractMacros: + """Tests for contracts using macros that do not require origination.""" + + @pytest.mark.parametrize( + "contract,param,storage,expected", + [ # FORMAT: assert_output contract_file storage input expected_result + # Build list + ('build_list.tz', '{}', '0', '{ 0 }'), + ('build_list.tz', '{}', '3', '{ 0 ; 1 ; 2 ; 3 }'), + ( + 'build_list.tz', + '{}', + '10', + '{ 0 ; 1 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7 ; 8 ; 9 ; 10 }', + ), + # Find maximum int in list -- returns None if not found + ('max_in_list.tz', 'None', '{}', 'None'), + ('max_in_list.tz', 'None', '{ 1 }', '(Some 1)'), + ('max_in_list.tz', 'None', '{ -1 }', '(Some -1)'), + ( + 'max_in_list.tz', + 'None', + '{ 10 ; -1 ; -20 ; 100 ; 0 }', + '(Some 100)', + ), + ( + 'max_in_list.tz', + 'None', + '{ 10 ; -1 ; -20 ; 100 ; 0 }', + '(Some 100)', + ), + ( + 'max_in_list.tz', + 'None', + '{ -10 ; -1 ; -20 ; -100 }', + '(Some -1)', + ), + # Test comparisons on tez { EQ ; GT ; LT ; GE ; LE } + ( + 'compare.tz', + '{}', + '(Pair 1000000 2000000)', + '{ False ; False ; True ; False ; True }', + ), + ( + 'compare.tz', + '{}', + '(Pair 2000000 1000000)', + '{ False ; True ; False ; True ; False }', + ), + ( + 'compare.tz', + '{}', + '(Pair 2370000 2370000)', + '{ True ; False ; False ; True ; True }', + ), + # Test ASSERT + ('assert.tz', 'Unit', 'True', 'Unit'), + # ASSERT_{OP} + ('assert_eq.tz', 'Unit', '(Pair -1 -1)', 'Unit'), + ('assert_eq.tz', 'Unit', '(Pair -1 -1)', 'Unit'), + ('assert_neq.tz', 'Unit', '(Pair 0 -1)', 'Unit'), + ('assert_lt.tz', 'Unit', '(Pair -1 0)', 'Unit'), + ('assert_le.tz', 'Unit', '(Pair 0 0)', 'Unit'), + ('assert_le.tz', 'Unit', '(Pair -1 0)', 'Unit'), + ('assert_gt.tz', 'Unit', '(Pair 0 -1)', 'Unit'), + ('assert_ge.tz', 'Unit', '(Pair 0 0)', 'Unit'), + ('assert_ge.tz', 'Unit', '(Pair 0 -1)', 'Unit'), + # ASSERT_CMP{OP} + ('assert_cmpeq.tz', 'Unit', '(Pair -1 -1)', 'Unit'), + ('assert_cmpneq.tz', 'Unit', '(Pair 0 -1)', 'Unit'), + ('assert_cmplt.tz', 'Unit', '(Pair -1 0)', 'Unit'), + ('assert_cmple.tz', 'Unit', '(Pair -1 0)', 'Unit'), + ('assert_cmple.tz', 'Unit', '(Pair 0 0)', 'Unit'), + ('assert_cmpgt.tz', 'Unit', '(Pair 0 -1)', 'Unit'), + ('assert_cmpge.tz', 'Unit', '(Pair 0 -1)', 'Unit'), + ('assert_cmpge.tz', 'Unit', '(Pair 0 0)', 'Unit'), + # Tests the SET_CAR and SET_CDR instructions + ( + 'set_caddaadr.tz', + '(Pair (Pair 1 2 (Pair (Pair 3 0) 4) 5) 6)', + '3000000', + '(Pair (Pair 1 2 (Pair (Pair 3 3000000) 4) 5) 6)', + ), + ( + 'map_caddaadr.tz', + '(Pair (Pair 1 2 (Pair (Pair 3 0) 4) 5) 6)', + 'Unit', + '(Pair (Pair 1 2 (Pair (Pair 3 1000000) 4) 5) 6)', + ), + # Test comparisons on bytes { EQ ; GT ; LT ; GE ; LE } + ( + 'compare_bytes.tz', + '{}', + '(Pair 0x33 0x34)', + '{ False ; False ; True ; False ; True }', + ), + ( + 'compare_bytes.tz', + '{}', + '(Pair 0x33 0x33aa)', + '{ False ; False ; True ; False ; True }', + ), + ( + 'compare_bytes.tz', + '{}', + '(Pair 0x33 0x33)', + '{ True ; False ; False ; True ; True }', + ), + ( + 'compare_bytes.tz', + '{}', + '(Pair 0x34 0x33)', + '{ False ; True ; False ; True ; False }', + ), + ], + ) + def test_contract_input_output( + self, + client: Client, + contract: str, + param: str, + storage: str, + expected: str, + ): + assert contract.endswith( + '.tz' + ), "test contract should have .tz extension" + contract = path.join(MACROS_CONTRACT_PATH, contract) + run_script_res = client.run_script(contract, param, storage) + assert run_script_res.storage == expected + + @pytest.mark.parametrize( + "contract,param,storage", + [ # FORMAT: assert_output contract_file storage input expected_result + ('assert.tz', 'Unit', 'False'), + ('assert_eq.tz', 'Unit', '(Pair 0 -1)'), + ('assert_eq.tz', 'Unit', '(Pair 0 -1)'), + ('assert_neq.tz', 'Unit', '(Pair -1 -1)'), + ('assert_lt.tz', 'Unit', '(Pair 0 -1)'), + ('assert_lt.tz', 'Unit', '(Pair 0 0)'), + ('assert_le.tz', 'Unit', '(Pair 0 -1)'), + ('assert_gt.tz', 'Unit', '(Pair -1 0)'), + ('assert_gt.tz', 'Unit', '(Pair 0 0)'), + ('assert_ge.tz', 'Unit', '(Pair -1 0)'), + ('assert_cmpeq.tz', 'Unit', '(Pair 0 -1)'), + ('assert_cmpneq.tz', 'Unit', '(Pair -1 -1)'), + ('assert_cmplt.tz', 'Unit', '(Pair 0 0)'), + ('assert_cmplt.tz', 'Unit', '(Pair 0 -1)'), + ('assert_cmple.tz', 'Unit', '(Pair 0 -1)'), + ('assert_cmpgt.tz', 'Unit', '(Pair 0 0)'), + ('assert_cmpgt.tz', 'Unit', '(Pair -1 0)'), + ('assert_cmpge.tz', 'Unit', '(Pair -1 0)'), + ], + ) + def test_contract_failures(self, client: Client, contract, param, storage): + contract = path.join(MACROS_CONTRACT_PATH, contract) + assert_run_script_failwith(client, contract, param, storage) + + +@pytest.mark.slow +@pytest.mark.contract +class TestGuestBook: + """Test on the guestbook contract.""" + + def test_guestbook(self, client: Client): + contract = path.join(MACROS_CONTRACT_PATH, 'guestbook.tz') + + init_with_transfer( + client, + contract, + '{ Elt "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" None }', + 100, + 'bootstrap1', + ) + + assert_transfer_failwith( + client, + 0, + 'bootstrap2', + 'guestbook', + ['--arg', '"Pas moi"', '--burn-cap', '10'], + ) + + client.transfer( + 0, + 'bootstrap1', + 'guestbook', + ['-arg', '"Coucou"', '--burn-cap', '10'], + ) + bake(client) + assert_storage_contains( + client, + 'guestbook', + '{ Elt "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" (Some "Coucou") }', + ) + + assert_transfer_failwith( + client, + 0, + 'bootstrap3', + 'guestbook', + ['--arg', '"Pas moi non plus"', '--burn-cap', '10'], + ) + assert_transfer_failwith( + client, + 0, + 'bootstrap1', + 'guestbook', + ['--arg', '"Recoucou ?"', '--burn-cap', '10'], + ) + + +@pytest.mark.slow +@pytest.mark.contract +class TestBigmap: + """Tests on the big_map_mem contract.""" + + def test_bigmap(self, client: Client): + contract = path.join(MACROS_CONTRACT_PATH, 'big_map_mem.tz') + + init_with_transfer( + client, + contract, + '(Pair { Elt 1 Unit ; Elt 2 Unit ; Elt 3 Unit } Unit)', + 100, + 'bootstrap1', + ) + + client.transfer( + 1, + 'bootstrap1', + 'big_map_mem', + ['-arg', '(Pair 0 False)', '--burn-cap', '10'], + ) + bake(client) + + assert_transfer_failwith( + client, + 0, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 0 True)', '--burn-cap', '10'], + ) + + client.transfer( + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 0 False)', '--burn-cap', '10'], + ) + bake(client) + assert_transfer_failwith( + client, + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 0 True)', '--burn-cap', '10'], + ) + client.transfer( + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 1 True)', '--burn-cap', '10'], + ) + bake(client) + assert_transfer_failwith( + client, + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 1 False)', '--burn-cap', '10'], + ) + client.transfer( + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 2 True)', '--burn-cap', '10'], + ) + bake(client) + assert_transfer_failwith( + client, + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 2 False)', '--burn-cap', '10'], + ) + client.transfer( + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 3 True)', '--burn-cap', '10'], + ) + bake(client) + assert_transfer_failwith( + client, + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 3 False)', '--burn-cap', '10'], + ) + client.transfer( + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 4 False)', '--burn-cap', '10'], + ) + bake(client) + assert_transfer_failwith( + client, + 1, + 'bootstrap1', + 'big_map_mem', + ['--arg', '(Pair 4 True)', '--burn-cap', '10'], + ) + + +@pytest.mark.slow +@pytest.mark.contract +class TestBigmapGetAdd: + """Tests on the big_map_get_add contract.""" + + def test_bigmap(self, client: Client): + contract = path.join(MACROS_CONTRACT_PATH, 'big_map_get_add.tz') + + init_with_transfer( + client, + contract, + '(Pair { Elt 0 1 ; Elt 1 2 ; Elt 2 3 } Unit)', + 100, + 'bootstrap1', + ) + + client.transfer( + 1, + 'bootstrap1', + 'big_map_get_add', + [ + '--arg', + '(Pair (Pair 200 (Some 2)) (Pair 200 (Some 2)))', + '--burn-cap', + '10', + ], + ) + bake(client) + client.transfer( + 1, + 'bootstrap1', + 'big_map_get_add', + [ + '--arg', + '(Pair (Pair 200 None) (Pair 200 None))', + '--burn-cap', + '10', + ], + ) + bake(client) + client.transfer( + 1, + 'bootstrap1', + 'big_map_get_add', + [ + '--arg', + '(Pair (Pair 200 None) (Pair 300 None))', + '--burn-cap', + '10', + ], + ) + bake(client) + client.transfer( + 1, + 'bootstrap1', + 'big_map_get_add', + [ + '--arg', + '(Pair (Pair 1 None) (Pair 200 None))', + '--burn-cap', + '10', + ], + ) + bake(client) + client.transfer( + 1, + 'bootstrap1', + 'big_map_get_add', + [ + '--arg', + '(Pair (Pair 1 (Some 2)) (Pair 0 (Some 1)))', + '--burn-cap', + '10', + ], + ) + bake(client) + client.transfer( + 1, + 'bootstrap1', + 'big_map_get_add', + [ + '--arg', + '(Pair (Pair 400 (Some 1232)) (Pair 400 (Some 1232)))', + '--burn-cap', + '10', + ], + ) + bake(client) + client.transfer( + 1, + 'bootstrap1', + 'big_map_get_add', + [ + '--arg', + '(Pair (Pair 401 (Some 0)) (Pair 400 (Some 1232)))', + '--burn-cap', + '10', + ], + ) + bake(client) + + +@pytest.mark.regression +class TestMacroExpansion: + """Test expanding macros""" + + @pytest.mark.parametrize("contract", all_contracts(['macros'])) + def test_macro_expansion( + self, client_regtest: ClientRegression, contract: str + ): + """This test expands macros in all macro test contracts, with + regression detection enabled. This test should fail if the definition + of any macros change. + """ + client_regtest.expand_macros(path.join(CONTRACT_PATH, contract)) diff --git a/tests_python/tests_012/test_contract_onchain_opcodes.py b/tests_python/tests_012/test_contract_onchain_opcodes.py new file mode 100644 index 000000000000..16f920fd6ede --- /dev/null +++ b/tests_python/tests_012/test_contract_onchain_opcodes.py @@ -0,0 +1,1312 @@ +from os import path + +import pytest +from tools.client_regression import ClientRegression +from tools import paths +from tools.utils import ( + assert_run_failure, + assert_storage_contains, + bake, + init_with_transfer, + assert_balance, +) +from tools.constants import IDENTITIES +from .contract_paths import OPCODES_CONTRACT_PATH, MINI_SCENARIOS_CONTRACT_PATH +from . import protocol + +KEY1 = 'foo' +KEY2 = 'bar' + + +@pytest.mark.incremental +@pytest.mark.slow +@pytest.mark.contract +@pytest.mark.regression +class TestContractOnchainOpcodes: + """Tests for individual opcodes that requires origination.""" + + def test_gen_keys(self, client_regtest_scrubbed: ClientRegression): + """Add keys used by later tests.""" + client = client_regtest_scrubbed + client.gen_key(KEY1) + client.gen_key(KEY2) + + def test_store_input(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + client.transfer(1000, "bootstrap1", KEY1, ['--burn-cap', '0.257']) + bake(client) + + client.transfer(2000, "bootstrap1", KEY2, ['--burn-cap', '0.257']) + bake(client) + + assert_balance(client, KEY1, 1000) + assert_balance(client, KEY2, 2000) + + # Create a contract and transfer 100 ꜩ to it + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'store_input.tz'), + '""', + 100, + 'bootstrap1', + ) + + client.transfer( + 100, + "bootstrap1", + "store_input", + ["-arg", '"abcdefg"', '--burn-cap', '10'], + ) + bake(client) + + assert_balance(client, "store_input", 200) + + assert_storage_contains(client, "store_input", '"abcdefg"') + + client.transfer( + 100, + "bootstrap1", + "store_input", + ["-arg", '"xyz"', '--burn-cap', '10'], + ) + bake(client) + + assert_storage_contains(client, "store_input", '"xyz"') + + def test_transfer_amount(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'transfer_amount.tz'), + '0', + 100, + 'bootstrap1', + ) + + client.transfer( + 500, + "bootstrap1", + 'transfer_amount', + ['-arg', 'Unit', '--burn-cap', '10'], + ) + + bake(client) + + assert_storage_contains(client, "transfer_amount", '500000000') + + def test_now(self, client_regtest_scrubbed: ClientRegression): + # Regtest is disabled for this test, since one would need to + # scrub storage for this one as it changes (the timestamp) + # on every run. + client = client_regtest_scrubbed + client.set_regtest(None) + + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'store_now.tz'), + '"2017-07-13T09:19:01Z"', + 100, + 'bootstrap1', + ) + + client.transfer( + 500, "bootstrap1", 'store_now', ['-arg', 'Unit', '--burn-cap', '10'] + ) + bake(client) + + assert_storage_contains( + client, 'store_now', f'"{protocol.get_now(client)}"' + ) + + def test_transfer_tokens(self, client_regtest_scrubbed: ClientRegression): + """Tests TRANSFER_TOKENS.""" + client = client_regtest_scrubbed + client.originate( + 'test_transfer_account1', + 100, + 'bootstrap1', + path.join(OPCODES_CONTRACT_PATH, 'noop.tz'), + ['--burn-cap', '10'], + ) + bake(client) + + client.originate( + 'test_transfer_account2', + 20, + 'bootstrap1', + path.join(OPCODES_CONTRACT_PATH, 'noop.tz'), + ['--burn-cap', '10'], + ) + bake(client) + + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'transfer_tokens.tz'), + 'Unit', + 1000, + 'bootstrap1', + ) + + assert_balance(client, 'test_transfer_account1', 100) + + account1_addr = client.get_contract_address('test_transfer_account1') + client.transfer( + 100, + 'bootstrap1', + 'transfer_tokens', + ['-arg', f'"{account1_addr}"', '--burn-cap', '10'], + ) + bake(client) + + # Why isn't this 200 ꜩ? Baking fee? + assert_balance(client, 'test_transfer_account1', 200) + + account2_addr = client.get_contract_address('test_transfer_account2') + client.transfer( + 100, + 'bootstrap1', + 'transfer_tokens', + ['-arg', f'"{account2_addr}"', '--burn-cap', '10'], + ) + bake(client) + + assert_balance(client, 'test_transfer_account2', 120) + + def test_self(self, client_regtest_scrubbed: ClientRegression): + # Regtest is disabled for this test, since one would need to + # scrub storage for this one as it changes (the contract + # address) on every run. + client = client_regtest_scrubbed + client.set_regtest(None) + + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'self.tz'), + '"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"', + 1000, + 'bootstrap1', + ) + + client.transfer(0, 'bootstrap1', 'self', ['--burn-cap', '10']) + bake(client) + + self_addr = client.get_contract_address('self') + assert_storage_contains(client, 'self', f'"{self_addr}"') + + def test_contract_fails(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + client.set_regtest(None) + + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'contract.tz'), + 'Unit', + 1000, + 'bootstrap1', + ) + + client.transfer(0, 'bootstrap1', 'self', ['--burn-cap', '10']) + bake(client) + addr = client.get_contract_address('contract') + + with assert_run_failure(r'script reached FAILWITH instruction'): + client.transfer( + 0, + 'bootstrap1', + 'contract', + ['-arg', f'"{addr}"', '--burn-cap', '10'], + ) + + def test_init_proxy(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'proxy.tz'), + 'Unit', + 1000, + 'bootstrap1', + ) + + def test_source(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + init_store = IDENTITIES['bootstrap4']['identity'] + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'source.tz'), + f'"{init_store}"', + 1000, + 'bootstrap1', + ) + + # direct transfer to the contract + client.transfer(0, 'bootstrap2', 'source', ['--burn-cap', '10']) + bake(client) + + source_addr = IDENTITIES['bootstrap2']['identity'] + assert_storage_contains(client, 'source', f'"{source_addr}"') + + # indirect transfer to the contract through proxy + contract_addr = client.get_contract_address('source') + client.transfer( + 0, + 'bootstrap2', + 'proxy', + ['--burn-cap', '10', '--arg', f'"{contract_addr}"'], + ) + bake(client) + assert_storage_contains(client, 'source', f'"{source_addr}"') + + def test_sender(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + client.set_regtest(None) + + init_store = IDENTITIES['bootstrap4']['identity'] + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'sender.tz'), + f'"{init_store}"', + 1000, + 'bootstrap1', + ) + + # direct transfer to the contract + client.transfer(0, 'bootstrap2', 'sender', ['--burn-cap', '10']) + bake(client) + + sender_addr = IDENTITIES['bootstrap2']['identity'] + assert_storage_contains(client, 'sender', f'"{sender_addr}"') + + # indirect transfer to the contract through proxy + contract_addr = client.get_contract_address('sender') + proxy_addr = client.get_contract_address('proxy') + client.transfer( + 0, + 'bootstrap2', + 'proxy', + ['--burn-cap', '10', '--arg', f'"{contract_addr}"'], + ) + bake(client) + assert_storage_contains(client, 'sender', f'"{proxy_addr}"') + + def test_slice(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'slices.tz'), + '"sppk7dBPqMPjDjXgKbb5f7V3PuKUrA4Zuwc3c3H7XqQerqPUWbK7Hna"', + 1000, + 'bootstrap1', + ) + + @pytest.mark.parametrize( + 'contract_arg', + [ + line.rstrip('\n') + for line in open( + f'{paths.TEZOS_HOME}' + + '/tests_python/tests_012/' + + 'test_slice_fails_params.txt' + ) + ], + ) + def test_slice_fails( + self, client_regtest_scrubbed: ClientRegression, contract_arg: str + ): + client = client_regtest_scrubbed + + with assert_run_failure(r'script reached FAILWITH instruction'): + client.transfer( + 0, + 'bootstrap1', + 'slices', + ['-arg', contract_arg, '--burn-cap', '10'], + ) + # bake(client) + + @pytest.mark.parametrize( + 'contract_arg', + [ + line.rstrip('\n') + for line in open( + f'{paths.TEZOS_HOME}' + + '/tests_python/tests_012/' + + 'test_slice_success_params.txt' + ) + ], + ) + def test_slice_success( + self, client_regtest_scrubbed: ClientRegression, contract_arg: str + ): + client = client_regtest_scrubbed + client.transfer( + 0, + 'bootstrap1', + 'slices', + ['-arg', contract_arg, '--burn-cap', '10'], + ) + bake(client) + + def test_split_string(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'split_string.tz'), + '{}', + 1000, + 'bootstrap1', + ) + + client.transfer( + 0, + 'bootstrap1', + 'split_string', + ['-arg', '"abc"', '--burn-cap', '10'], + ) + bake(client) + assert_storage_contains(client, 'split_string', '{ "a" ; "b" ; "c" }') + + client.transfer( + 0, + 'bootstrap1', + 'split_string', + ['-arg', '"def"', '--burn-cap', '10'], + ) + bake(client) + assert_storage_contains( + client, 'split_string', '{ "a" ; "b" ; "c" ; "d" ; "e" ; "f" }' + ) + + def test_split_bytes(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'split_bytes.tz'), + '{}', + 1000, + 'bootstrap1', + ) + + client.transfer( + 0, + 'bootstrap1', + 'split_bytes', + ['-arg', '0xaabbcc', '--burn-cap', '10'], + ) + bake(client) + assert_storage_contains(client, 'split_bytes', '{ 0xaa ; 0xbb ; 0xcc }') + + client.transfer( + 0, + 'bootstrap1', + 'split_bytes', + ['-arg', '0xddeeff', '--burn-cap', '10'], + ) + bake(client) + assert_storage_contains( + client, 'split_bytes', '{ 0xaa ; 0xbb ; 0xcc ; 0xdd ; 0xee ; 0xff }' + ) + + def test_set_delegate(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'set_delegate.tz'), + 'Unit', + 1000, + 'bootstrap1', + ) + bake(client) + + assert client.get_delegate('set_delegate').delegate is None + + addr = IDENTITIES['bootstrap5']['identity'] + client.transfer( + 0, 'bootstrap1', 'set_delegate', ['-arg', f'(Some "{addr}")'] + ) + bake(client) + + assert client.get_delegate('set_delegate').delegate == addr + + client.transfer(0, 'bootstrap1', 'set_delegate', ['-arg', 'None']) + bake(client) + + assert client.get_delegate('set_delegate').delegate is None + + @pytest.mark.parametrize( + 'contract', + [ + 'compare_big_type.tz', + 'compare_big_type2.tz', + ], + ) + def test_trace_origination(self, client_regtest_scrubbed, contract): + client = client_regtest_scrubbed + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, contract), + 'Unit', + 1000, + 'bootstrap1', + ) + bake(client) + + +@pytest.mark.incremental +class TestTickets: + """Tests for tickets.""" + + def test_ticket_user_forge(self, client): + bake(client) + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticket_store-2.tz'), + 'None', + 100, + 'bootstrap1', + 'storer', + ) + + # Create parameter by hand with a ticket type but no ticket in it + client.transfer( + 100, 'bootstrap1', 'storer', ['-arg', 'None', '--burn-cap', '10'] + ) + + with assert_run_failure(r'Unexpected forged value'): + # Create parameter by hand with a ticket in it + client.transfer( + 100, + 'bootstrap1', + 'storer', + ['-arg', 'Some 1', '--burn-cap', '10'], + ) + + with assert_run_failure(r'Unexpected forged value'): + # Create storage by hand with a ticket in it + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticket_bad.tz'), + '1', + 100, + 'bootstrap1', + 'ticket_bad', + ) + + def test_ticket_user_big_forge(self, client): + bake(client) + contract_name = 'big_storer' + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticket_big_store.tz'), + '{}', + 100, + 'bootstrap1', + contract_name, + ) + bake(client) + client.transfer( + 100, 'bootstrap1', contract_name, ['-arg', '42', '--burn-cap', '10'] + ) + bake(client) + storage = client.get_storage(contract_name) + + with assert_run_failure(r'Unexpected forged value'): + # Create a storage with the ID of a big map that has tickets in it + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticket_big_store.tz'), + storage, + 100, + 'bootstrap1', + 'thief', + ) + + with assert_run_failure(r'Unexpected forged value'): + # Create a storage with the ID of a big map that has tickets in it + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticket_big_store.tz'), + '(Pair ' + storage + ' {})', + 100, + 'bootstrap1', + 'thief', + ) + + def test_ticket_read(self, client): + """Test TICKETS""" + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticketer.tz'), + '42', + 100, + 'bootstrap1', + 'ticketer_read', + ) + bake(client) + ticketer_addr = client.get_contract_address('ticketer_read') + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticket_read.tz'), + '"' + ticketer_addr + '"', + 100, + 'bootstrap1', + 'reader', + ) + bake(client) + reader_addr = client.get_contract_address('reader') + client.transfer( + 100, + 'bootstrap1', + 'ticketer_read', + ['-arg', '"' + reader_addr + '"', '--burn-cap', '10'], + ) + bake(client) + assert_storage_contains(client, "reader", '"' + ticketer_addr + '"') + + def test_bad_ticket(self, client): + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticketer.tz'), + '42', + 100, + 'bootstrap1', + 'ticketer_bad', + ) + bake(client) + ticketer_addr = client.get_contract_address('ticketer_bad') + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticket_read.tz'), + '"' + ticketer_addr + '"', + 100, + 'bootstrap1', + 'reader_bad', + ) + bake(client) + with assert_run_failure(r'Unexpected forged value'): + client.transfer( + 100, + 'bootstrap1', + 'reader_bad', + ['-arg', '1', '--burn-cap', '10'], + ) + bake(client) + + def test_ticket_utxo(self, client): + """Test UTXOs""" + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'utxor.tz'), + '42', + 100, + 'bootstrap1', + ) + bake(client) + utxor_addr = client.get_contract_address('utxor') + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'utxo_read.tz'), + '"' + utxor_addr + '"', + 100, + 'bootstrap1', + "reader_a", + ) + bake(client) + reader_a_addr = client.get_contract_address('reader_a') + utxor_addr = client.get_contract_address('utxor') + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'utxo_read.tz'), + '"' + utxor_addr + '"', + 100, + 'bootstrap1', + "reader_b", + ) + bake(client) + reader_b_addr = client.get_contract_address('reader_b') + client.transfer( + 100, + 'bootstrap1', + 'utxor', + [ + '-arg', + '(Pair "' + reader_a_addr + '" "' + reader_b_addr + '")', + '--burn-cap', + '10', + ], + ) + bake(client) + + def test_ticket_split(self, client): + def ticket(target_addr, param, utxo_amount): + param = ( + '(Pair (Pair "' + + target_addr + + '" ' + + str(param) + + ') ' + + str(utxo_amount) + + ')' + ) + client.transfer( + 100, + 'bootstrap1', + 'ticketer', + ['-arg', param, '--burn-cap', '10'], + ) + + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticketer-2.tz'), + 'Unit', + 100, + 'bootstrap1', + 'ticketer', + ) + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticket_split.tz'), + 'Unit', + 100, + 'bootstrap1', + 'splitter', + ) + bake(client) + splitter_addr = client.get_contract_address('splitter') + ticket(splitter_addr, 42, 3) + with assert_run_failure(r'script reached FAILWITH instruction'): + # Wrong Split Amount + ticket(splitter_addr, 42, 4) + bake(client) + + def test_ticket_join(self, client): + """Test JOIN""" + + def params(target_addr, utxo_amount, param): + return ( + '(Pair (Pair "' + + target_addr + + '" ' + + str(param) + + ') ' + + str(utxo_amount) + + ')' + ) + + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticketer-2.tz'), + 'Unit', + 100, + 'bootstrap1', + 'ticketer_a', + ) + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticketer-2.tz'), + 'Unit', + 100, + 'bootstrap1', + 'ticketer_b', + ) + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'ticket_join.tz'), + 'None', + 100, + 'bootstrap1', + 'joiner', + ) + bake(client) + joiner_addr = client.get_contract_address('joiner') + client.transfer( + 100, + 'bootstrap1', + 'ticketer_a', + ['-arg', params(joiner_addr, 42, 1), '--burn-cap', '10'], + ) + bake(client) + client.transfer( + 100, + 'bootstrap1', + 'ticketer_a', + ['-arg', params(joiner_addr, 144, 1), '--burn-cap', '10'], + ) + bake(client) + with assert_run_failure(r'script reached FAILWITH instruction'): + # Different Ticketer + client.transfer( + 100, + 'bootstrap1', + 'ticketer_b', + ['-arg', params(joiner_addr, 23, 1), '--burn-cap', '10'], + ) + with assert_run_failure(r'script reached FAILWITH instruction'): + # Different Content + client.transfer( + 100, + 'bootstrap1', + 'ticketer_a', + ['-arg', params(joiner_addr, 21, 23), '--burn-cap', '10'], + ) + + def test_ticket_fungible_originations(self, client, session): + """Test the origination of builder and wallet contracts for fungible + tokens implemented using tickets.""" + + builder_path = path.join( + MINI_SCENARIOS_CONTRACT_PATH, 'ticket_builder_fungible.tz' + ) + + wallet_path = path.join( + MINI_SCENARIOS_CONTRACT_PATH, 'ticket_wallet_fungible.tz' + ) + + manager_address = IDENTITIES['bootstrap1']['identity'] + + builders = {} + wallets = {} + + # Helper functions + def originate_builder(name): + """Create a fungible token contract managed by bootstrap1.""" + origination = client.originate( + contract_name=f'builder_{name}', + amount="0", + sender='bootstrap1', + contract=builder_path, + args=['--init', f'"{manager_address}"', '--burn-cap', "10"], + ) + builders[name] = origination.contract + bake(client) + + def originate_wallet(name): + """Create a fungible token wallet managed by bootstrap1.""" + origination = client.originate( + contract_name=f'wallet_{name}', + amount="0", + sender='bootstrap1', + contract=wallet_path, + args=[ + '--init', + f'Pair "{manager_address}" {{}}', + '--burn-cap', + "10", + ], + ) + wallets[name] = origination.contract + bake(client) + + # Create 3 token contracts "A", "B", and "C". + originate_builder("A") + originate_builder("B") + originate_builder("C") + + # Create 2 wallets "Alice" and "Bob". + originate_wallet("Alice") + originate_wallet("Bob") + + session['fungible_builders'] = builders + session['fungible_wallets'] = wallets + + def test_ticket_fungible_transfers(self, client, session): + """Test the life cycle of fungible tokens implemented using tickets.""" + + manager_address = IDENTITIES['bootstrap1']['identity'] + + builders = session['fungible_builders'] + wallets = session['fungible_wallets'] + + def mint(builder, wallet, amount): + """Mint fungible tokens.""" + wallet_address = wallets[wallet] + parameter = f'(Pair "{wallet_address}%receive" {amount})' + client.transfer( + amount=0, + giver=manager_address, + receiver=f'builder_{builder}', + args=[ + '--burn-cap', + '2', + '--entrypoint', + 'mint', + '--arg', + parameter, + ], + ) + bake(client) + + def burn(builder, wallet, amount): + """Burn fungible tokens.""" + builder_addr = builders[builder] + parameter = f'Pair "{builder_addr}%burn" {amount} "{builder_addr}"' + client.transfer( + amount=0, + giver=manager_address, + receiver=f'wallet_{wallet}', + args=[ + '--burn-cap', + '2', + '--entrypoint', + 'send', + '--arg', + parameter, + ], + ) + bake(client) + + def transfer(builder, source_wallet, destination_wallet, amount): + """Transfer fungible tokens.""" + builder_addr = builders[builder] + dest_addr = wallets[destination_wallet] + parameter = f'Pair "{dest_addr}%receive" {amount} "{builder_addr}"' + client.transfer( + amount=0, + giver=manager_address, + receiver=f'wallet_{source_wallet}', + args=[ + '--burn-cap', + '2', + '--entrypoint', + 'send', + '--arg', + parameter, + ], + ) + bake(client) + + # 100A --> Alice + mint(builder="A", wallet="Alice", amount=100) + # 100B --> Alice + mint(builder="B", wallet="Alice", amount=100) + + # Fail: Alice --1C--> Bob + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="C", + source_wallet="Alice", + destination_wallet="Bob", + amount=1, + ) + + # Fail: Alice --0C--> Bob + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="C", + source_wallet="Alice", + destination_wallet="Bob", + amount=0, + ) + + # Fail: Alice --150A--> Bob + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="A", + source_wallet="Alice", + destination_wallet="Bob", + amount=150, + ) + + # Fail: Bob --50A--> Alice + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="A", + source_wallet="Bob", + destination_wallet="Alice", + amount=50, + ) + + # Alice --50A--> Bob + transfer( + builder="A", + source_wallet="Alice", + destination_wallet="Bob", + amount=50, + ) + + # Alice --50A--> Bob + transfer( + builder="A", + source_wallet="Alice", + destination_wallet="Bob", + amount=50, + ) + + # Alice --0A--> Bob + transfer( + builder="A", + source_wallet="Alice", + destination_wallet="Bob", + amount=0, + ) + + # Fail: Alice --1A--> Bob + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="A", + source_wallet="Alice", + destination_wallet="Bob", + amount=1, + ) + + # Bob --100A--> Bob + transfer( + builder="A", + source_wallet="Bob", + destination_wallet="Bob", + amount=100, + ) + + # Fail: Bob --150A--> Bob + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="A", + source_wallet="Bob", + destination_wallet="Bob", + amount=150, + ) + + # Bob --100A--> + burn(builder="A", wallet="Bob", amount=100) + + # Bob --0A--> + burn(builder="A", wallet="Bob", amount=0) + + # Fail: Bob --1A--> + with assert_run_failure(r'script reached FAILWITH instruction'): + burn(builder="A", wallet="Bob", amount=1) + + def test_ticket_non_fungible_originations(self, client, session): + """Test the origination of builder and wallet contracts for + non-fungible tokens implemented using tickets.""" + + builder_path = path.join( + MINI_SCENARIOS_CONTRACT_PATH, 'ticket_builder_non_fungible.tz' + ) + + wallet_path = path.join( + MINI_SCENARIOS_CONTRACT_PATH, 'ticket_wallet_non_fungible.tz' + ) + + manager_address = IDENTITIES['bootstrap1']['identity'] + + builders = {} + wallets = {} + + # Helper functions + def originate_builder(name): + """Create a non-fungible token contract managed by bootstrap1.""" + storage = f'(Pair "{manager_address}" 0)' + origination = client.originate( + contract_name=f'nft_builder_{name}', + amount="0", + sender='bootstrap1', + contract=builder_path, + args=['--init', storage, '--burn-cap', "10"], + ) + builders[name] = origination.contract + bake(client) + + def originate_wallet(name): + """Create a non-fungible token wallet managed by bootstrap1.""" + origination = client.originate( + contract_name=f'nft_wallet_{name}', + amount="0", + sender='bootstrap1', + contract=wallet_path, + args=[ + '--init', + f'Pair "{manager_address}" {{}}', + '--burn-cap', + "10", + ], + ) + wallets[name] = origination.contract + bake(client) + + # Create 3 token contracts "A", "B", and "C". + originate_builder("A") + originate_builder("B") + originate_builder("C") + + # Create 2 wallets "Alice" and "Bob". + originate_wallet("Alice") + originate_wallet("Bob") + + session['non_fungible_builders'] = builders + session['non_fungible_wallets'] = wallets + + def test_ticket_non_fungible_transfers(self, client, session): + """Test the life cycle of non-fungible tokens implemented using + tickets.""" + + manager_address = IDENTITIES['bootstrap1']['identity'] + + builders = session['non_fungible_builders'] + wallets = session['non_fungible_wallets'] + + def mint(builder, wallet, token_id): + """Mint a non-fungible token and assert that it has the expected + id.""" + builder_alias = f'nft_builder_{builder}' + expected_builder_storage = f'Pair "{manager_address}" {token_id}' + actual_builder_storage = client.get_storage(builder_alias) + assert expected_builder_storage == actual_builder_storage + + wallet_address = wallets[wallet] + parameter = f'"{wallet_address}%receive"' + client.transfer( + amount=0, + giver=manager_address, + receiver=builder_alias, + args=[ + '--burn-cap', + '2', + '--entrypoint', + 'mint_destination', + '--arg', + parameter, + ], + ) + bake(client) + + def burn(builder, wallet, token_id): + """Burn a non-fungible token.""" + builder_addr = builders[builder] + parameter = ( + f'Pair "{builder_addr}%burn" "{builder_addr}" {token_id}' + ) + client.transfer( + amount=0, + giver=manager_address, + receiver=f'nft_wallet_{wallet}', + args=[ + '--burn-cap', + '2', + '--entrypoint', + 'send', + '--arg', + parameter, + ], + ) + bake(client) + + def transfer(builder, source_wallet, destination_wallet, token_id): + """Transfer fungible tokens.""" + builder_addr = builders[builder] + dest_addr = wallets[destination_wallet] + parameter = ( + f'Pair "{dest_addr}%receive" "{builder_addr}" {token_id}' + ) + client.transfer( + amount=0, + giver=manager_address, + receiver=f'nft_wallet_{source_wallet}', + args=[ + '--burn-cap', + '2', + '--entrypoint', + 'send', + '--arg', + parameter, + ], + ) + bake(client) + + # A0 --> Alice + mint(builder="A", wallet="Alice", token_id=0) + # A1 --> Alice + mint(builder="A", wallet="Alice", token_id=1) + # B0 --> Alice + mint(builder="B", wallet="Alice", token_id=0) + + # Fail: Alice --C0--> Bob + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="C", + source_wallet="Alice", + destination_wallet="Bob", + token_id=0, + ) + + # Fail: Alice --A2--> Bob + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="A", + source_wallet="Alice", + destination_wallet="Bob", + token_id=2, + ) + + # Fail: Bob --A0--> Alice + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="A", + source_wallet="Bob", + destination_wallet="Alice", + token_id=0, + ) + + # Fail: Bob --A1--> Bob + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="A", + source_wallet="Bob", + destination_wallet="Bob", + token_id=1, + ) + + # Alice --A1--> Bob + transfer( + builder="A", + source_wallet="Alice", + destination_wallet="Bob", + token_id=1, + ) + + # Alice --A0--> Bob + transfer( + builder="A", + source_wallet="Alice", + destination_wallet="Bob", + token_id=0, + ) + + # Fail: Alice --A1--> Bob + with assert_run_failure(r'script reached FAILWITH instruction'): + transfer( + builder="A", + source_wallet="Alice", + destination_wallet="Bob", + token_id=1, + ) + + # Bob --A0--> Bob + transfer( + builder="A", + source_wallet="Bob", + destination_wallet="Bob", + token_id=0, + ) + + # Bob --A0--> + burn(builder="A", wallet="Bob", token_id=0) + + # Bob --A1--> + burn(builder="A", wallet="Bob", token_id=1) + + # Fail: Bob --B0--> + with assert_run_failure(r'script reached FAILWITH instruction'): + burn(builder="B", wallet="Bob", token_id=0) + + # Alice --B0--> + burn(builder="B", wallet="Alice", token_id=0) + + +ORIGINATE_BIG_MAP_FILE = path.join( + OPCODES_CONTRACT_PATH, 'originate_big_map.tz' +) + + +@pytest.mark.incremental +@pytest.mark.contract +@pytest.mark.regression +class TestContractBigMapOrigination: + def test_big_map_origination_literal(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + # originate a first version of the contract from a literal so + # that a big_map with id 0 exists + init_with_transfer( + client, + ORIGINATE_BIG_MAP_FILE, + '{Elt 0 0}', + 1000, + 'bootstrap1', + contract_name='originate_big_map_literal', + ) + + def test_big_map_origination_id(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + # originate again the same script from the big-map id 0 + with assert_run_failure(r'Unexpected forged value'): + init_with_transfer( + client, + ORIGINATE_BIG_MAP_FILE, + '0', + 1000, + 'bootstrap1', + contract_name='originate_big_map_id', + ) + + def test_big_map_origination_diff(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + + # originate again the same script from a big-diff + with assert_run_failure(r'Unexpected forged value'): + init_with_transfer( + client, + ORIGINATE_BIG_MAP_FILE, + 'Pair 0 {Elt 1 (Some 4)}', + 1000, + 'bootstrap1', + contract_name='originate_big_map_diff', + ) + + def test_big_map_transfer_id(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + # call the first contract, passing an id as parameter + with assert_run_failure(r'Unexpected forged value'): + client.call( + source='bootstrap1', + destination='originate_big_map_literal', + args=['--arg', '0'], + ) + + def test_big_map_transfer_diff(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + # call the first contract, passing a diff as parameter + with assert_run_failure(r'Unexpected forged value'): + client.call( + source='bootstrap1', + destination='originate_big_map_literal', + args=['--arg', 'Pair 0 {Elt 1 (Some 4)}'], + ) + + +@pytest.mark.incremental +@pytest.mark.slow +@pytest.mark.contract +@pytest.mark.regression +class TestContractOnchainLevel: + """Onchain tests for LEVEL.""" + + # This test needs to be in a separate class to not depend on the number + # of operations happening before + + def test_level(self, client_regtest_scrubbed: ClientRegression): + client = client_regtest_scrubbed + + init_with_transfer( + client, + path.join(OPCODES_CONTRACT_PATH, 'level.tz'), + '9999999', + 100, + 'bootstrap1', + ) + bake(client) + client.transfer( + 500, "bootstrap1", 'level', ['-arg', 'Unit', '--burn-cap', '10'] + ) + bake(client) + level = client.get_level() + slevel = str(level) + assert_storage_contains(client, 'level', slevel) + bake(client) + bake(client) + # checks the storage hasn't changed even though the current level has + assert_storage_contains(client, 'level', slevel) + # Run again to check the storage gets updated + client.transfer( + 500, "bootstrap1", 'level', ['-arg', 'Unit', '--burn-cap', '10'] + ) + bake(client) + assert_storage_contains(client, 'level', str(level + 3)) diff --git a/tests_python/tests_012/test_contract_opcodes.py b/tests_python/tests_012/test_contract_opcodes.py new file mode 100644 index 000000000000..abab6e86b61e --- /dev/null +++ b/tests_python/tests_012/test_contract_opcodes.py @@ -0,0 +1,1943 @@ +from os import path + +import pytest + +from tools.client_regression import ClientRegression +from tools.constants import IDENTITIES +from tools.utils import ( + assert_run_failure, + assert_run_script_failwith, + assert_run_script_success, +) +from .contract_paths import MINI_SCENARIOS_CONTRACT_PATH, OPCODES_CONTRACT_PATH + + +PUBLIC_KEY = IDENTITIES['bootstrap1']['public'] + + +@pytest.mark.slow +@pytest.mark.contract +@pytest.mark.regression +class TestContractOpcodes: + """Tests for individual opcodes that do not require origination.""" + + @pytest.mark.parametrize( + "contract,param,storage,expected", + [ # FORMAT: assert_output contract_file storage input expected_result + # TODO add tests for map_car.tz, subset.tz + # NB: noop.tz is tested in test_basic.sh + ('cons.tz', '{}', '10', '{ 10 }'), + ('cons.tz', '{ 10 }', '-5', '{ -5 ; 10 }'), + ('cons.tz', '{ -5 ; 10 }', '99', '{ 99 ; -5 ; 10 }'), + # Tests on Options + ('none.tz', 'Some 10', 'Unit', 'None'), + ('ret_int.tz', 'None', 'Unit', '(Some 300)'), + # Map block on lists + ('list_map_block.tz', '{0}', '{}', '{}'), + ( + 'list_map_block.tz', + '{0}', + '{ 1 ; 1 ; 1 ; 1 }', + '{ 1 ; 2 ; 3 ; 4 }', + ), + ( + 'list_map_block.tz', + '{0}', + '{ 1 ; 2 ; 3 ; 0 }', + '{ 1 ; 3 ; 5 ; 3 }', + ), + # Reverse a list + ('reverse.tz', '{""}', '{}', '{}'), + ( + 'reverse.tz', + '{""}', + '{ "c" ; "b" ; "a" }', + '{ "a" ; "b" ; "c" }', + ), + # Reverse using LOOP_LEFT + ('loop_left.tz', '{""}', '{}', '{}'), + ( + 'loop_left.tz', + '{""}', + '{ "c" ; "b" ; "a" }', + '{ "a" ; "b" ; "c" }', + ), + # Identity on strings + ('str_id.tz', 'None', '"Hello"', '(Some "Hello")'), + ('str_id.tz', 'None', '"abcd"', '(Some "abcd")'), + # Slice strings + ('slice.tz', 'None', 'Pair 0 0', 'None'), + ('slice.tz', 'Some "Foo"', 'Pair 10 5', 'None'), + ('slice.tz', 'Some "Foo"', 'Pair 0 0', '(Some "")'), + ('slice.tz', 'Some "Foo"', 'Pair 0 10', 'None'), + ('slice.tz', 'Some "Foo"', 'Pair 0 2', '(Some "Fo")'), + ('slice.tz', 'Some "Foo"', 'Pair 1 3', 'None'), + ('slice.tz', 'Some "Foo"', 'Pair 1 1', '(Some "o")'), + # Stress-test the failure case of slice for a + # non-trivial gas consumption + ( + 'slice.tz', + 'Some' + '"' + 'Foo' * 2000 + '"', + 'Pair 1 10000', + 'None', + ), + # Slice bytes + ('slice_bytes.tz', 'None', 'Pair 0 1', 'None'), + ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 0 0', '(Some 0x)'), + ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 0 1', '(Some 0xaa)'), + ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 1 1', '(Some 0xbb)'), + ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 1 2', '(Some 0xbbcc)'), + ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 1 3', 'None'), + ('slice_bytes.tz', 'Some 0xaabbcc', 'Pair 1 1', '(Some 0xbb)'), + # Stress-test the failure case of slice for a + # non-trivial gas consumption + ( + 'slice_bytes.tz', + 'Some 0x' + 'aabbcc' * 2000, + 'Pair 1 10000', + 'None', + ), + # Identity on pairs + ( + 'pair_id.tz', + 'None', + '(Pair True False)', + '(Some (Pair True False))', + ), + ( + 'pair_id.tz', + 'None', + '(Pair False True)', + '(Some (Pair False True))', + ), + ( + 'pair_id.tz', + 'None', + '(Pair True True)', + '(Some (Pair True True))', + ), + ( + 'pair_id.tz', + 'None', + '(Pair False False)', + '(Some (Pair False False))', + ), + # Tests CAR and CDR instructions + ('car.tz', '0', '(Pair 34 17)', '34'), + ('cdr.tz', '0', '(Pair 34 17)', '17'), + # Logical not + ('not.tz', 'None', 'True', '(Some False)'), + ('not.tz', 'None', 'False', '(Some True)'), + # Logical and + ('and.tz', 'None', '(Pair False False)', '(Some False)'), + ('and.tz', 'None', '(Pair False True)', '(Some False)'), + ('and.tz', 'None', '(Pair True False)', '(Some False)'), + ('and.tz', 'None', '(Pair True True)', '(Some True)'), + # Logical or + ('or.tz', 'None', '(Pair False False)', '(Some False)'), + ('or.tz', 'None', '(Pair False True)', '(Some True)'), + ('or.tz', 'None', '(Pair True False)', '(Some True)'), + ('or.tz', 'None', '(Pair True True)', '(Some True)'), + # Logical and + ('and_logical_1.tz', 'False', "(Pair False False)", 'False'), + ('and_logical_1.tz', 'False', "(Pair False True)", 'False'), + ('and_logical_1.tz', 'False', "(Pair True False)", 'False'), + ('and_logical_1.tz', 'False', "(Pair True True)", 'True'), + # Binary and + ('and_binary.tz', 'Unit', 'Unit', 'Unit'), + # Binary or + ('or_binary.tz', 'None', '(Pair 4 8)', '(Some 12)'), + ('or_binary.tz', 'None', '(Pair 0 8)', '(Some 8)'), + ('or_binary.tz', 'None', '(Pair 8 0)', '(Some 8)'), + ('or_binary.tz', 'None', '(Pair 15 4)', '(Some 15)'), + ('or_binary.tz', 'None', '(Pair 14 1)', '(Some 15)'), + ('or_binary.tz', 'None', '(Pair 7 7)', '(Some 7)'), + # Binary not + ('not_binary.tz', 'None', '(Left 0)', '(Some -1)'), + ('not_binary.tz', 'None', '(Left 8)', '(Some -9)'), + ('not_binary.tz', 'None', '(Left 7)', '(Some -8)'), + ('not_binary.tz', 'None', '(Left -9)', '(Some 8)'), + ('not_binary.tz', 'None', '(Left -8)', '(Some 7)'), + ('not_binary.tz', 'None', '(Right 0)', '(Some -1)'), + ('not_binary.tz', 'None', '(Right 8)', '(Some -9)'), + ('not_binary.tz', 'None', '(Right 7)', '(Some -8)'), + # XOR + ( + 'xor.tz', + 'None', + 'Left (Pair False False)', + '(Some (Left False))', + ), + ('xor.tz', 'None', 'Left (Pair False True)', '(Some (Left True))'), + ('xor.tz', 'None', 'Left (Pair True False)', '(Some (Left True))'), + ('xor.tz', 'None', 'Left (Pair True True)', '(Some (Left False))'), + ('xor.tz', 'None', 'Right (Pair 0 0)', '(Some (Right 0))'), + ('xor.tz', 'None', 'Right (Pair 0 1)', '(Some (Right 1))'), + ('xor.tz', 'None', 'Right (Pair 1 0)', '(Some (Right 1))'), + ('xor.tz', 'None', 'Right (Pair 1 1)', '(Some (Right 0))'), + ('xor.tz', 'None', 'Right (Pair 42 21)', '(Some (Right 63))'), + ('xor.tz', 'None', 'Right (Pair 42 63)', '(Some (Right 21))'), + # test shifts: LSL & LSR + ('shifts.tz', 'None', '(Left (Pair 8 1))', '(Some 16)'), + ('shifts.tz', 'None', '(Left (Pair 0 0))', '(Some 0)'), + ('shifts.tz', 'None', '(Left (Pair 0 1))', '(Some 0)'), + ('shifts.tz', 'None', '(Left (Pair 1 2))', '(Some 4)'), + ('shifts.tz', 'None', '(Left (Pair 15 2))', '(Some 60)'), + ('shifts.tz', 'None', '(Right (Pair 8 1))', '(Some 4)'), + ('shifts.tz', 'None', '(Right (Pair 0 0))', '(Some 0)'), + ('shifts.tz', 'None', '(Right (Pair 0 1))', '(Some 0)'), + ('shifts.tz', 'None', '(Right (Pair 1 2))', '(Some 0)'), + ('shifts.tz', 'None', '(Right (Pair 15 2))', '(Some 3)'), + # Concatenate all strings of a list into one string + ('concat_list.tz', '""', '{ "a" ; "b" ; "c" }', '"abc"'), + ('concat_list.tz', '""', '{}', '""'), + ( + 'concat_list.tz', + '""', + '{ "Hello" ; " " ; "World" ; "!" }', + '"Hello World!"', + ), + # Concatenate the bytes in storage with all bytes in the given list + ('concat_hello_bytes.tz', '{}', '{ 0xcd }', '{ 0xffcd }'), + ('concat_hello_bytes.tz', '{}', '{}', '{}'), + ( + 'concat_hello_bytes.tz', + '{}', + '{ 0xab ; 0xcd }', + '{ 0xffab ; 0xffcd }', + ), + # Identity on lists + ( + 'list_id.tz', + '{""}', + '{ "1" ; "2" ; "3" }', + '{ "1" ; "2" ; "3" }', + ), + ('list_id.tz', '{""}', '{}', '{}'), + ( + 'list_id.tz', + '{""}', + '{ "a" ; "b" ; "c" }', + '{ "a" ; "b" ; "c" }', + ), + ( + 'list_id_map.tz', + '{""}', + '{ "1" ; "2" ; "3" }', + '{ "1" ; "2" ; "3" }', + ), + ('list_id_map.tz', '{""}', '{}', '{}'), + ( + 'list_id_map.tz', + '{""}', + '{ "a" ; "b" ; "c" }', + '{ "a" ; "b" ; "c" }', + ), + # Identity on maps + ('map_id.tz', '{}', '{ Elt 0 1 }', '{ Elt 0 1 }'), + ('map_id.tz', '{}', '{ Elt 0 0 }', '{ Elt 0 0 }'), + ( + 'map_id.tz', + '{}', + '{ Elt 0 0 ; Elt 3 4 }', + '{ Elt 0 0 ; Elt 3 4 }', + ), + # Memberships in maps + ( + 'map_mem_nat.tz', + '(Pair { Elt 0 1 } None)', + '1', + '(Pair { Elt 0 1 } (Some False))', + ), + ('map_mem_nat.tz', '(Pair {} None)', '1', '(Pair {} (Some False))'), + ( + 'map_mem_nat.tz', + '(Pair { Elt 1 0 } None)', + '1', + '(Pair { Elt 1 0 } (Some True))', + ), + ( + 'map_mem_nat.tz', + '(Pair { Elt 1 4 ; Elt 2 11 } None)', + '1', + '(Pair { Elt 1 4 ; Elt 2 11 } (Some True))', + ), + ( + 'map_mem_nat.tz', + '(Pair { Elt 1 4 ; Elt 2 11 } None)', + '2', + '(Pair { Elt 1 4 ; Elt 2 11 } (Some True))', + ), + ( + 'map_mem_nat.tz', + '(Pair { Elt 1 4 ; Elt 2 11 } None)', + '3', + '(Pair { Elt 1 4 ; Elt 2 11 } (Some False))', + ), + ( + 'map_mem_string.tz', + '(Pair { Elt "foo" 1 } None)', + '"bar"', + '(Pair { Elt "foo" 1 } (Some False))', + ), + ( + 'map_mem_string.tz', + '(Pair {} None)', + '"bar"', + '(Pair {} (Some False))', + ), + ( + 'map_mem_string.tz', + '(Pair { Elt "foo" 0 } None)', + '"foo"', + '(Pair { Elt "foo" 0 } (Some True))', + ), + ( + 'map_mem_string.tz', + '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', + '"foo"', + '(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True))', + ), + ( + 'map_mem_string.tz', + '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', + '"bar"', + '(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some True))', + ), + ( + 'map_mem_string.tz', + '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', + '"baz"', + '(Pair { Elt "bar" 4 ; Elt "foo" 11 } (Some False))', + ), + # Mapping over maps + ('map_map.tz', '{}', '10', '{}'), + ('map_map.tz', '{ Elt "foo" 1 }', '10', '{ Elt "foo" 11 }'), + ( + 'map_map.tz', + '{ Elt "bar" 5 ; Elt "foo" 1 }', + '15', + '{ Elt "bar" 20 ; Elt "foo" 16 }', + ), + # Memberships in big maps + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 0 1 } None)', + '1', + '(Pair 4 (Some False))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair {} None)', + '1', + '(Pair 4 (Some False))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 1 0 } None)', + '1', + '(Pair 4 (Some True))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 1 4 ; Elt 2 11 } None)', + '1', + '(Pair 4 (Some True))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 1 4 ; Elt 2 11 } None)', + '2', + '(Pair 4 (Some True))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 1 4 ; Elt 2 11 } None)', + '3', + '(Pair 4 (Some False))', + ), + ( + 'big_map_mem_string.tz', + '(Pair { Elt "foo" 1 } None)', + '"bar"', + '(Pair 4 (Some False))', + ), + ( + 'big_map_mem_string.tz', + '(Pair {} None)', + '"bar"', + '(Pair 4 (Some False))', + ), + ( + 'big_map_mem_string.tz', + '(Pair { Elt "foo" 0 } None)', + '"foo"', + '(Pair 4 (Some True))', + ), + ( + 'big_map_mem_string.tz', + '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', + '"foo"', + '(Pair 4 (Some True))', + ), + ( + 'big_map_mem_string.tz', + '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', + '"bar"', + '(Pair 4 (Some True))', + ), + ( + 'big_map_mem_string.tz', + '(Pair { Elt "bar" 4 ; Elt "foo" 11 } None)', + '"baz"', + '(Pair 4 (Some False))', + ), + # Memberships in big maps + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 0 1 } None)', + '1', + '(Pair 4 (Some False))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair {} None)', + '1', + '(Pair 4 (Some False))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 1 0 } None)', + '1', + '(Pair 4 (Some True))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 1 4 ; Elt 2 11 } None)', + '1', + '(Pair 4 (Some True))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 1 4 ; Elt 2 11 } None)', + '2', + '(Pair 4 (Some True))', + ), + ( + 'big_map_mem_nat.tz', + '(Pair { Elt 1 4 ; Elt 2 11 } None)', + '3', + '(Pair 4 (Some False))', + ), + # Identity on sets + ('set_id.tz', '{}', '{ "a" ; "b" ; "c" }', '{ "a" ; "b" ; "c" }'), + ('set_id.tz', '{}', '{}', '{}'), + ('set_id.tz', '{}', '{ "asdf" ; "bcde" }', '{ "asdf" ; "bcde" }'), + # List concat + ('list_concat.tz', '"abc"', '{ "d" ; "e" ; "f" }', '"abcdef"'), + ('list_concat.tz', '"abc"', '{}', '"abc"'), + ( + 'list_concat_bytes.tz', + '0x00ab', + '{ 0xcd ; 0xef ; 0x00 }', + '0x00abcdef00', + ), + ( + 'list_concat_bytes.tz', + '0x', + '{ 0x00 ; 0x11 ; 0x00 }', + '0x001100', + ), + ('list_concat_bytes.tz', '0xabcd', '{}', '0xabcd'), + ('list_concat_bytes.tz', '0x', '{}', '0x'), + # List iter + ('list_iter.tz', '0', '{ 10 ; 2 ; 1 }', '20'), + ('list_iter.tz', '0', '{ 3 ; 6 ; 9 }', '162'), + # List size + ('list_size.tz', '111', '{}', '0'), + ('list_size.tz', '111', '{ 1 }', '1'), + ('list_size.tz', '111', '{ 1 ; 2 ; 3 }', '3'), + ('list_size.tz', '111', '{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }', '6'), + # Set member -- set is in storage + ( + 'set_member.tz', + '(Pair {} None)', + '"Hi"', + '(Pair {} (Some False))', + ), + ( + 'set_member.tz', + '(Pair { "Hi" } None)', + '"Hi"', + '(Pair { "Hi" } (Some True))', + ), + ( + 'set_member.tz', + '(Pair { "Hello" ; "World" } None)', + '""', + '(Pair { "Hello" ; "World" } (Some False))', + ), + # Set size + ('set_size.tz', '111', '{}', '0'), + ('set_size.tz', '111', '{ 1 }', '1'), + ('set_size.tz', '111', '{ 1 ; 2 ; 3 }', '3'), + ('set_size.tz', '111', '{ 1 ; 2 ; 3 ; 4 ; 5 ; 6 }', '6'), + # Set iter + ('set_iter.tz', '111', '{}', '0'), + ('set_iter.tz', '111', '{ 1 }', '1'), + ('set_iter.tz', '111', '{ -100 ; 1 ; 2 ; 3 }', '-94'), + # Map size + ('map_size.tz', '111', '{}', '0'), + ('map_size.tz', '111', '{ Elt "a" 1 }', '1'), + ( + 'map_size.tz', + '111', + '{ Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 }', + '3', + ), + ( + 'map_size.tz', + '111', + '{ Elt "a" 1 ; Elt "b" 2 ; Elt "c" 3 ; \ + Elt "d" 4 ; Elt "e" 5 ; Elt "f" 6 }', + '6', + ), + # Contains all elements -- does the second list contain + # all of the same elements as the first one? I'm ignoring + # element multiplicity + ('contains_all.tz', 'None', '(Pair {} {})', '(Some True)'), + ( + 'contains_all.tz', + 'None', + '(Pair { "c" } { "B" })', + '(Some False)', + ), + ( + 'contains_all.tz', + 'None', + '(Pair { "A" } { "B" })', + '(Some False)', + ), + ( + 'contains_all.tz', + 'None', + '(Pair { "B" } { "B" })', + '(Some True)', + ), + ( + 'contains_all.tz', + 'None', + '(Pair { "B" ; "C" ; "asdf" } { "B" ; "B" ; "asdf" ; "C" })', + '(Some True)', + ), + ( + 'contains_all.tz', + 'None', + '(Pair { "B" ; "B" ; "asdf" ; "C" } { "B" ; "C" ; "asdf" })', + '(Some True)', + ), + # Concatenate the string in storage with all strings in + # the given list + ('concat_hello.tz', '{}', '{ "World!" }', '{ "Hello World!" }'), + ('concat_hello.tz', '{}', '{}', '{}'), + ( + 'concat_hello.tz', + '{}', + '{ "test1" ; "test2" }', + '{ "Hello test1" ; "Hello test2" }', + ), + # Create an empty map and add a string to it + ('empty_map.tz', '{}', 'Unit', '{ Elt "hello" "world" }'), + # Get the value stored at the given key in the map + ( + 'get_map_value.tz', + '(Pair None { Elt "hello" "hi" })', + '"hello"', + '(Pair (Some "hi") { Elt "hello" "hi" })', + ), + ( + 'get_map_value.tz', + '(Pair None { Elt "hello" "hi" })', + '""', + '(Pair None { Elt "hello" "hi" })', + ), + ( + 'get_map_value.tz', + '(Pair None { Elt "1" "one" ; \ + Elt "2" "two" })', + '"1"', + '(Pair (Some "one") { Elt "1" "one" ; Elt "2" "two" })', + ), + # Get and update the value stored at the given key in the map + ( + 'get_and_update_map.tz', + '(Pair None {})', + '"hello"', + '(Pair None {})', + ), + ( + 'get_and_update_map.tz', + '(Pair (Some 4) {})', + '"hello"', + '(Pair None { Elt "hello" 4 })', + ), + ( + 'get_and_update_map.tz', + '(Pair None { Elt "hello" 4 })', + '"hello"', + '(Pair (Some 4) {})', + ), + ( + 'get_and_update_map.tz', + '(Pair (Some 5) { Elt "hello" 4 })', + '"hello"', + '(Pair (Some 4) { Elt "hello" 5 })', + ), + ( + 'get_and_update_map.tz', + '(Pair (Some 5) { Elt "hello" 4 })', + '"hi"', + '(Pair None { Elt "hello" 4 ; Elt "hi" 5 })', + ), + ( + 'get_and_update_map.tz', + '(Pair None { Elt "1" 1 ; \ + Elt "2" 2 })', + '"1"', + '(Pair (Some 1) { Elt "2" 2 })', + ), + ( + 'get_and_update_map.tz', + '(Pair None { Elt "1" 1 ; \ + Elt "2" 2 })', + '"1"', + '(Pair (Some 1) { Elt "2" 2 })', + ), + # Map iter + ( + 'map_iter.tz', + '(Pair 0 0)', + '{ Elt 0 100 ; Elt 2 100 }', + '(Pair 2 200)', + ), + ( + 'map_iter.tz', + '(Pair 0 0)', + '{ Elt 1 1 ; Elt 2 100 }', + '(Pair 3 101)', + ), + # Return True if True branch of if was taken and False otherwise + ('if.tz', 'None', 'True', '(Some True)'), + ('if.tz', 'None', 'False', '(Some False)'), + # Generate a pair of or types + ('left_right.tz', '(Left "X")', '(Left True)', '(Right True)'), + ('left_right.tz', '(Left "X")', '(Right "a")', '(Left "a")'), + # Reverse a list + ('reverse_loop.tz', '{""}', '{}', '{}'), + ( + 'reverse_loop.tz', + '{""}', + '{ "c" ; "b" ; "a" }', + '{ "a" ; "b" ; "c" }', + ), + # Exec concat contract + ('exec_concat.tz', '"?"', '""', '"_abc"'), + ('exec_concat.tz', '"?"', '"test"', '"test_abc"'), + # Get the current balance of the contract + ('balance.tz', '111', 'Unit', '4000000000000'), + # Get the current level of the block + # Test the produced variable annotation + ('level.tz', '111', 'Unit', '1'), + # Test addition and subtraction on tez + ( + 'tez_add_sub.tz', + 'None', + '(Pair 2000000 1000000)', + '(Some (Pair 3000000 1000000))', + ), + ( + 'tez_add_sub.tz', + 'None', + '(Pair 2310000 1010000)', + '(Some (Pair 3320000 1300000))', + ), + # Test various additions + ('add.tz', 'Unit', 'Unit', 'Unit'), + # Test ABS + ('abs.tz', 'Unit', '12039123919239192312931', 'Unit'), + ('abs.tz', 'Unit', '0', 'Unit'), + ('abs.tz', 'Unit', '948', 'Unit'), + # Test INT + ('int.tz', 'None', '0', '(Some 0)'), + ('int.tz', 'None', '1', '(Some 1)'), + ('int.tz', 'None', '9999', '(Some 9999)'), + # Test DIP + ('dip.tz', '(Pair 0 0)', '(Pair 15 9)', '(Pair 15 24)'), + ('dip.tz', '(Pair 0 0)', '(Pair 1 1)', '(Pair 1 2)'), + # Test get first element of list + ('first.tz', '111', '{ 1 ; 2 ; 3 ; 4 }', '1'), + ('first.tz', '111', '{ 4 }', '4'), + # Hash input string + # Test assumed to be correct -- hash is based on encoding of AST + ( + 'hash_string.tz', + '0x00', + '"abcdefg"', + '0x46fdbcb4ea4eadad5615c' + + 'daa17d67f783e01e21149ce2b27de497600b4cd8f4e', + ), + ( + 'hash_string.tz', + '0x00', + '"12345"', + '0xb4c26c20de52a4eaf0d8a34' + + '0db47ad8cb1e74049570859c9a9a3952b204c772f', + ), + # IF_SOME + ('if_some.tz', '"?"', '(Some "hello")', '"hello"'), + ('if_some.tz', '"?"', 'None', '""'), + # Tests the SET_CAR and SET_CDR instructions + ('set_car.tz', '(Pair "hello" 0)', '"world"', '(Pair "world" 0)'), + ('set_car.tz', '(Pair "hello" 0)', '"abc"', '(Pair "abc" 0)'), + ('set_car.tz', '(Pair "hello" 0)', '""', '(Pair "" 0)'), + ('set_cdr.tz', '(Pair "hello" 0)', '1', '(Pair "hello" 1)'), + ('set_cdr.tz', '(Pair "hello" 500)', '3', '(Pair "hello" 3)'), + ('set_cdr.tz', '(Pair "hello" 7)', '100', '(Pair "hello" 100)'), + # Convert a public key to a public key hash + ( + 'hash_key.tz', + 'None', + '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"', + '(Some "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx")', + ), + ( + 'hash_key.tz', + 'None', + '"edpkuJqtDcA2m2muMxViSM47MPsGQzmyjnNTawUPqR8vZTAMcx61ES"', + '(Some "tz1XPTDmvT3vVE5Uunngmixm7gj7zmdbPq6k")', + ), + # Test timestamp operations + ( + 'add_timestamp_delta.tz', + 'None', + '(Pair 100 100)', + '(Some "1970-01-01T00:03:20Z")', + ), + ( + 'add_timestamp_delta.tz', + 'None', + '(Pair 100 -100)', + '(Some "1970-01-01T00:00:00Z")', + ), + ( + 'add_timestamp_delta.tz', + 'None', + '(Pair "1970-01-01T00:00:00Z" 0)', + '(Some "1970-01-01T00:00:00Z")', + ), + ( + 'add_delta_timestamp.tz', + 'None', + '(Pair 100 100)', + '(Some "1970-01-01T00:03:20Z")', + ), + ( + 'add_delta_timestamp.tz', + 'None', + '(Pair -100 100)', + '(Some "1970-01-01T00:00:00Z")', + ), + ( + 'add_delta_timestamp.tz', + 'None', + '(Pair 0 "1970-01-01T00:00:00Z")', + '(Some "1970-01-01T00:00:00Z")', + ), + ( + 'sub_timestamp_delta.tz', + '111', + '(Pair 100 100)', + '"1970-01-01T00:00:00Z"', + ), + ( + 'sub_timestamp_delta.tz', + '111', + '(Pair 100 -100)', + '"1970-01-01T00:03:20Z"', + ), + ( + 'sub_timestamp_delta.tz', + '111', + '(Pair 100 2000000000000000000)', + '-1999999999999999900', + ), + ('diff_timestamps.tz', '111', '(Pair 0 0)', '0'), + ('diff_timestamps.tz', '111', '(Pair 0 1)', '-1'), + ('diff_timestamps.tz', '111', '(Pair 1 0)', '1'), + ( + 'diff_timestamps.tz', + '111', + '(Pair "1970-01-01T00:03:20Z" "1970-01-01T00:00:00Z")', + '200', + ), + # Test pack/unpack + ( + 'packunpack_rev.tz', + 'Unit', + '(Pair -1 (Pair 1 (Pair "foobar" (Pair 0x00AABBCC (Pair 1000 ' + + '(Pair False (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ' + + '(Pair "2019-09-09T08:35:33Z" ' + + '"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"))))))))', + 'Unit', + ), + ( + 'packunpack_rev.tz', + 'Unit', + '(Pair -1 (Pair 1 (Pair "foobar" (Pair 0x00AABBCC (Pair 1000 ' + + '(Pair False (Pair "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5" ' + + '(Pair "2019-09-09T08:35:33Z" ' + + '"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"))))))))', + 'Unit', + ), + ( + 'packunpack_rev_cty.tz', + 'Unit', + '(Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9' + + 'sDVC9yav" (Pair Unit (Pair "edsigthTzJ8X7MPmNeEwybRAv' + + 'dxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8' + + 'V2w8ayB5dMJzrYCHhD8C7" (Pair (Some "edsigthTzJ8X7MPmN' + + 'eEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5' + + 'CwoNgqs8V2w8ayB5dMJzrYCHhD8C7") (Pair { Unit } (Pair' + + ' { True } (Pair (Pair 19 10) (Pair (Left "tz1cxcwwnz' + + 'ENRdhe2Kb8ZdTrdNy4bFNyScx5") (Pair { Elt 0 "foo" ; El' + + 't 1 "bar" } { PACK } )))))))))', + 'Unit', + ), + ( + 'packunpack_rev_cty.tz', + 'Unit', + '(Pair "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9' + + 'sDVC9yav" (Pair Unit (Pair "edsigthTzJ8X7MPmNeEwybRAv' + + 'dxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8' + + 'V2w8ayB5dMJzrYCHhD8C7" (Pair None (Pair { } (Pair {' + + ' } (Pair (Pair 40 -10) (Pair (Right "2019-09-09T08:' + + '35:33Z") (Pair { } { DUP ; DROP ; PACK } )))))))))', + 'Unit', + ), + # Test EDIV on nat and int + ( + 'ediv.tz', + '(Pair None None None None)', + '(Pair 10 -3)', + '(Pair (Some (Pair -3 1)) (Some (Pair 3 1)) ' + + '(Some (Pair -3 1)) (Some (Pair 3 1)))', + ), + ( + 'ediv.tz', + '(Pair None None None None)', + '(Pair 10 0)', + '(Pair None None None None)', + ), + ( + 'ediv.tz', + '(Pair None None None None)', + '(Pair -8 2)', + '(Pair (Some (Pair -4 0)) (Some (Pair -4 0)) ' + + '(Some (Pair 4 0)) (Some (Pair 4 0)))', + ), + # Test EDIV on mutez + ( + 'ediv_mutez.tz', + '(Left None)', + '(Pair 10 (Left 10))', + '(Left (Some (Pair 1 0)))', + ), + ( + 'ediv_mutez.tz', + '(Left None)', + '(Pair 10 (Left 3))', + '(Left (Some (Pair 3 1)))', + ), + ( + 'ediv_mutez.tz', + '(Left None)', + '(Pair 10 (Left 0))', + '(Left None)', + ), + ( + 'ediv_mutez.tz', + '(Left None)', + '(Pair 10 (Right 10))', + '(Right (Some (Pair 1 0)))', + ), + ( + 'ediv_mutez.tz', + '(Left None)', + '(Pair 10 (Right 3))', + '(Right (Some (Pair 3 1)))', + ), + ( + 'ediv_mutez.tz', + '(Left None)', + '(Pair 10 (Right 0))', + '(Right None)', + ), + ( + 'ediv_mutez.tz', + '(Left None)', + '(Pair 5 (Right 10))', + '(Right (Some (Pair 0 5)))', + ), + # Test compare + ('compare.tz', 'Unit', 'Unit', 'Unit'), + # Test comparison combinators: + # GT, GE, LT, LE, NEQ, EQ + ( + 'comparisons.tz', + '{}', + '{ -9999999; -1 ; 0 ; 1 ; 9999999 }', + '{ ' + '{ False ; False ; False ; True ; True } ;' + "\n" + ' { False ; False ; True ; True ; True } ;' + "\n" + ' { True ; True ; False ; False ; False } ;' + "\n" + ' { True ; True ; True ; False ; False } ;' + "\n" + ' { True ; True ; False ; True ; True } ;' + "\n" + ' { False ; False ; True ; False ; False }' + ' }', + ), + # Test ADDRESS + ( + 'address.tz', + 'None', + '"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"', + '(Some "tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5")', + ), + # Test (CONTRACT unit) + ( + 'contract.tz', + 'Unit', + '"tz1cxcwwnzENRdhe2Kb8ZdTrdNy4bFNyScx5"', + 'Unit', + ), + # Test create_contract + ( + 'create_contract.tz', + 'None', + 'Unit', + '(Some "KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm")', + ), + # Test multiplication - success case (no overflow) + # Failure case is tested in m̀ul_overflow.tz + ('mul.tz', 'Unit', 'Unit', 'Unit'), + # Test NEG + ('neg.tz', '0', '(Left 2)', '-2'), + ('neg.tz', '0', '(Right 2)', '-2'), + ('neg.tz', '0', '(Left 0)', '0'), + ('neg.tz', '0', '(Right 0)', '0'), + ('neg.tz', '0', '(Left -2)', '2'), + # Test DIGN, DUGN, DROPN, DIPN + ('dign.tz', '0', '(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)', '5'), + ('dugn.tz', '0', '(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)', '1'), + ('dropn.tz', '0', '(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)', '5'), + ('dipn.tz', '0', '(Pair (Pair (Pair (Pair 1 2) 3) 4) 5)', '6'), + # Test DIGN 17 times. + ( + 'dig_eq.tz', + 'Unit', + '(Pair 17 (Pair 16 (Pair 15 (Pair 14 (Pair 13 (Pair 12' + + ' (Pair 11 (Pair 10 (Pair 9 (Pair 8 (Pair 7 (Pair 6 (P' + + 'air 5 (Pair 4 (Pair 3 (Pair 2 1))))))))))))))))', + 'Unit', + ), + ( + 'dig_eq.tz', + 'Unit', + '(Pair 2 (Pair 3 (Pair 12 (Pair 16 (Pair 10 (Pair 14 (' + + 'Pair 19 (Pair 9 (Pair 18 (Pair 6 (Pair 8 (Pair 11 (Pa' + + 'ir 4 (Pair 13 (Pair 15 (Pair 5 1))))))))))))))))', + 'Unit', + ), + # Test Partial Exec + ('pexec.tz', '14', '38', '52'), + ('pexec_2.tz', "{ 0 ; 1 ; 2 ; 3}", '4', "{ 0 ; 7 ; 14 ; 21 }"), + # Test CHAIN_ID + ('chain_id_store.tz', 'None', 'Unit', '(Some "NetXdQprcVkpaWU")'), + ( + 'chain_id_store.tz', + '(Some 0x7a06a770)', + 'Unit', + '(Some "NetXdQprcVkpaWU")', + ), + ( + 'chain_id_store.tz', + '(Some "NetXdQprcVkpaWU")', + 'Unit', + '(Some "NetXdQprcVkpaWU")', + ), + # Test SELF + ('self_with_entrypoint.tz', 'Unit', 'Left (Left 0)', 'Unit'), + ('self_with_default_entrypoint.tz', 'Unit', 'Unit', 'Unit'), + # Test SELF_ADDRESS + ('self_address.tz', 'Unit', 'Unit', 'Unit'), + # Test UNPAIR + ('unpair.tz', 'Unit', 'Unit', 'Unit'), + # Test VOTING_POWER + ( + 'voting_power.tz', + '(Pair 0 0)', + f'"{PUBLIC_KEY}"', + '(Pair 666 3330)', + ), + # Test KECCAK + ( + 'keccak.tz', + 'None', + f'0x{b"Hello, world!".hex()}', + '(Some 0xb6e16d27ac5ab427a7f68900ac5559ce2' + + '72dc6c37c82b3e052246c82244c50e4)', + ), + # Test SHA3 + ( + 'sha3.tz', + 'None', + f'0x{b"Hello, world!".hex()}', + '(Some 0xf345a219da005ebe9c1a1eaad97bbf38' + + 'a10c8473e41d0af7fb617caa0c6aa722)', + ), + # Test COMBs + ('comb.tz', '(Pair 0 0 0)', 'Unit', '(Pair 1 2 3)'), + ('uncomb.tz', '0', '(Pair 1 4 2)', '142'), + ('comb-get.tz', 'Unit', '(Pair 1 4 2 Unit)', 'Unit'), + ('comb-set.tz', '(Pair 1 4 2 Unit)', 'Unit', '(Pair 2 12 8 Unit)'), + ( + 'comb-set-2.tz', + 'None', + '(Pair 1 4 2 Unit)', + '(Some (Pair 2 4 "toto" 0x01))', + ), + # Test DUP n + ('dup-n.tz', 'Unit', 'Unit', 'Unit'), + # Test Sapling + ('sapling_empty_state.tz', '{}', 'Unit', '0'), + # Test building Fr element from nat. + # The initial storage is dropped then any value is valid. + # Random values can be generated using the following OCaml program. + # let r = Bls12_381.Fr.(random ()) in + # let x = Bls12_381.Fr.random () in + # Printf.printf "Param = (Pair %s 0x%s). Result = 0x%s" + # (Bls12_381.Fr.to_string r) + # (Hex.(show (of_bytes (Bls12_381.Fr.to_bytes x)))) + # (Hex.(show (of_bytes (Bls12_381.Fr.(to_bytes (mul r x)))))) + ( + 'bls12_381_fr_z_nat.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '0', + '0x00000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_fr_z_nat.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '1', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + # The natural is 1 in Fr. + ( + 'bls12_381_fr_z_nat.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '524358751751261904794477405081859658376905525005276378226036' + '58699938581184514', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_fr_z_nat.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '2', + '0x02000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_fr_z_nat.tz', + '0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c' + + '5401f', + '3364491663033484423912034843462646864953418677080980279259699' + + '6408934105684394', + '0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca91' + + '8a221', + ), + ( + 'bls12_381_fr_z_nat.tz', + '0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfc' + + 'dbe3f', + '2262028481792278490256467246991799299632821112798447289749169' + + '8543785655336309', + '0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe6' + + '77c62', + ), + ( + 'bls12_381_fr_z_nat.tz', + '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' + + 'fcf2d', + '1718009307279455880617703583439793220591757728848373965251048' + + '2486858834123369', + '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' + + 'bf221', + ), + # Same than previous one, but we added the order to the natural to + # verify the modulo is computed correctly and the multiplication + # computation does not fail. + ( + 'bls12_381_fr_z_nat.tz', + '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' + + 'fcf2d', + '69615968247920749285624776342583898043608129789011377475114141' + + '186797415307882', + '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' + + 'bf221', + ), + # Test with (positive and negative) integers. + ( + 'bls12_381_fr_z_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '0', + '0x00000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_fr_z_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '1', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_fr_z_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '524358751751261904794477405081859658376905525005276378226036' + '58699938581184514', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_fr_z_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '2', + '0x02000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_fr_z_int.tz', + '0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c' + + '5401f', + '3364491663033484423912034843462646864953418677080980279259699' + + '6408934105684394', + '0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca91' + + '8a221', + ), + ( + 'bls12_381_fr_z_int.tz', + '0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfc' + + 'dbe3f', + '2262028481792278490256467246991799299632821112798447289749169' + + '8543785655336309', + '0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe6' + + '77c62', + ), + ( + 'bls12_381_fr_z_int.tz', + '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' + + 'fcf2d', + '1718009307279455880617703583439793220591757728848373965251048' + + '2486858834123369', + '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' + + 'bf221', + ), + # Same than previous one, but we added the order to the natural to + # verify the modulo is computed correctly and the multiplication + # computation does not fail. + ( + 'bls12_381_fr_z_int.tz', + '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' + + 'fcf2d', + '69615968247920749285624776342583898043608129789011377475114141' + + '186797415307882', + '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' + + 'bf221', + ), + ( + 'bls12_381_fr_z_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '-1', + '0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953' + + 'a7ed73', + ), + ( + 'bls12_381_fr_z_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '-42', + '0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a' + + '7ed73', + ), + # Test building Fr element from nat. + # The initial storage is dropped then any value is valid. + # Random values can be generated using the following OCaml program. + # let r = Bls12_381.Fr.(random ()) in + # let x = Bls12_381.Fr.random () in + # Printf.printf "Param = (Pair %s 0x%s). Result = 0x%s" + # (Bls12_381.Fr.to_string r) + # (Hex.(show (of_bytes (Bls12_381.Fr.to_bytes x)))) + # (Hex.(show (of_bytes (Bls12_381.Fr.(to_bytes (mul r x)))))) + ( + 'bls12_381_z_fr_nat.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '0', + '0x00000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_z_fr_nat.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '1', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + # The natural is 1 in Fr. + ( + 'bls12_381_z_fr_nat.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '524358751751261904794477405081859658376905525005276378226036' + '58699938581184514', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_z_fr_nat.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '2', + '0x02000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_z_fr_nat.tz', + '0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c' + + '5401f', + '3364491663033484423912034843462646864953418677080980279259699' + + '6408934105684394', + '0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca91' + + '8a221', + ), + ( + 'bls12_381_z_fr_nat.tz', + '0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfc' + + 'dbe3f', + '2262028481792278490256467246991799299632821112798447289749169' + + '8543785655336309', + '0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe6' + + '77c62', + ), + ( + 'bls12_381_z_fr_nat.tz', + '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' + + 'fcf2d', + '1718009307279455880617703583439793220591757728848373965251048' + + '2486858834123369', + '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' + + 'bf221', + ), + # Same than previous one, but we added the order to the natural to + # verify the modulo is computed correctly and the multiplication + # computation does not fail. + ( + 'bls12_381_z_fr_nat.tz', + '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' + + 'fcf2d', + '69615968247920749285624776342583898043608129789011377475114141' + + '186797415307882', + '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' + + 'bf221', + ), + # Test with (positive and negative) integers. + ( + 'bls12_381_z_fr_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '0', + '0x00000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_z_fr_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '1', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_z_fr_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '524358751751261904794477405081859658376905525005276378226036' + '58699938581184514', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_z_fr_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '2', + '0x02000000000000000000000000000000000000000000000000000000000' + + '00000', + ), + ( + 'bls12_381_z_fr_int.tz', + '0x5b0ecd0fa853810e356f1eb79721e80b30510fcc3a455f4fc02fdd9a90c' + + '5401f', + '3364491663033484423912034843462646864953418677080980279259699' + + '6408934105684394', + '0x2ef123703093cbbbd124e15f2054fa5781ed0b8d092ec3c6e5d76b4ca91' + + '8a221', + ), + ( + 'bls12_381_z_fr_int.tz', + '0x4147a5ad0a633e4880d2296f08ec5c12d03e3fa4a6b49ecbd16a30a3cfc' + + 'dbe3f', + '2262028481792278490256467246991799299632821112798447289749169' + + '8543785655336309', + '0x4e387e0ebfb3d1633153c195036e0c0b672955c4a0e420f93ec20a76fe6' + + '77c62', + ), + ( + 'bls12_381_z_fr_int.tz', + '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' + + 'fcf2d', + '1718009307279455880617703583439793220591757728848373965251048' + + '2486858834123369', + '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' + + 'bf221', + ), + ( + 'bls12_381_z_fr_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '-1', + '0x00000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953' + + 'a7ed73', + ), + ( + 'bls12_381_z_fr_int.tz', + '0x01000000000000000000000000000000000000000000000000000000000' + + '00000', + '-42', + '0xd7fffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a' + + '7ed73', + ), + # Same than previous one, but we added the order to the natural to + # verify the modulo is computed correctly and the multiplication + # computation does not fail. + ( + 'bls12_381_z_fr_int.tz', + '0x8578be1766f92cd82c5e5135c374a03a8562e263ea953a3f9711b0153b7' + + 'fcf2d', + '69615968247920749285624776342583898043608129789011377475114141' + + '186797415307882', + '0xfaa60dacea8e26112e524d379720fe4f95fbc5a26f1b1a67e229e26ddec' + + 'bf221', + ), + # Test Fr bytes can be pushed without being padded + ( + 'add_bls12_381_fr.tz', + 'None', + 'Pair 0x00 0x00', + '(Some 0x000000000000000000000000000000000000000000000000000000' + + '0000000000)', + ), + ( + 'add_bls12_381_fr.tz', + 'None', + 'Pair 0x01 0x00', + '(Some 0x010000000000000000000000000000000000000000000000000000' + + '0000000000)', + ), + ( + 'add_bls12_381_fr.tz', + 'None', + 'Pair 0x010000 0x00', + '(Some 0x010000000000000000000000000000000000000000000000000000' + + '0000000000)', + ), + ( + 'add_bls12_381_fr.tz', + 'None', + 'Pair 0x010000 0x010000', + '(Some 0x020000000000000000000000000000000000000000000000000000' + + '0000000000)', + ), + ( + 'bls12_381_fr_push_bytes_not_padded.tz', + 'None', + 'Unit', + '(Some 0x000000000000000000000000000000000000000000000000000000' + + '0000000000)', + ), + ( + 'bls12_381_fr_push_nat.tz', + 'None', + 'Unit', + '(Some 0x100000000000000000000000000000000000000000000000000000' + + '0000000000)', + ), + ('bls12_381_fr_to_int.tz', '0', '0x00', '0'), + ('bls12_381_fr_to_int.tz', '0', '0x01', '1'), + # Generated using + # let r = Bls12_381.Fr.(random ()) in + # Printf.printf "%s = 0x%s" + # (Bls12_381.Fr.to_string r) + # (Hex.(show (of_bytes (Bls12_381.Fr.to_bytes r)))) + ( + 'bls12_381_fr_to_int.tz', + '0', + '0x28db8e57af88d9576acd181b89f24e50a89a6423f939026ed91349fc9' + + 'af16c27', + '1783268807701357777652478449446472851821391321341286660405373' + + '5695200962927400', + ), + ( + 'bls12_381_fr_to_int.tz', + '0', + '0xb9e8abf8dc324a010007addde986fe0f7c81fab16d26819d0534b7691c' + + '0b0719', + '1132026582925658583078152196614952946047676740821044523890286' + + '9222031333517497', + ), + # Mutez -> Fr + ( + 'mutez_to_bls12_381_fr.tz', + '0x02', + '16', + '0x100000000000000000000000000000000000000000000000000000000' + + '0000000', + ), + # # would fail if trying to PACK mutez and UNPACK to Fr + ( + 'mutez_to_bls12_381_fr.tz', + '0x00', + '257', + '0x010100000000000000000000000000000000000000000000000000000' + + '0000000', + ), + # Fr -> Mutez + ('bls12_381_fr_to_mutez.tz', '0', '0x10', '16'), + ], + ) + def test_contract_input_output( + self, + client_regtest: ClientRegression, + contract: str, + param: str, + storage: str, + expected: str, + ): + client = client_regtest + assert contract.endswith( + '.tz' + ), "test contract should have .tz extension" + contract = path.join(OPCODES_CONTRACT_PATH, contract) + run_script_res = client.run_script( + contract, param, storage, trace_stack=True + ) + assert run_script_res.storage == expected + + @pytest.mark.parametrize("balance", [0, 0.000001, 0.5, 1, 5, 1000, 8e12]) + def test_balance(self, client_regtest: ClientRegression, balance: float): + client = client_regtest + contract = 'balance.tz' + contract = path.join(OPCODES_CONTRACT_PATH, contract) + run_script_res = client.run_script( + contract, '0', 'Unit', balance=balance, trace_stack=True + ) + assert run_script_res.storage == str(int(1000000 * balance)) + + def test_now(self, client_regtest: ClientRegression): + """Test that the --now flag of 'tezos-client run script' affects the + value returned by the NOW instruction. See also + test_contract_onchain_opcodes.py for a complementary test of the NOW + instruction.""" + client = client_regtest + contract = 'store_now.tz' + initial_storage = '"2017-07-13T09:19:01Z"' + now = '2021-10-13T10:16:52Z' + contract = path.join(OPCODES_CONTRACT_PATH, contract) + run_script_res = client.run_script( + contract, + storage=initial_storage, + inp='Unit', + now=now, + trace_stack=True, + ) + assert run_script_res.storage == f'"{now}"' + + def test_level(self, client_regtest: ClientRegression): + """Test that the --level flag of 'tezos-client run script' affects the + value returned by the LEVEL instruction. See also + test_contract_onchain_opcodes.py for a complementary test of the LEVEL + instuction.""" + client = client_regtest + contract = 'level.tz' + initial_storage = '9999999' + level = 10 + contract = path.join(OPCODES_CONTRACT_PATH, contract) + run_script_res = client.run_script( + contract, + storage=initial_storage, + inp='Unit', + level=level, + trace_stack=True, + ) + assert run_script_res.storage == f'{level}' + + @pytest.mark.parametrize( + "contract,param,storage,expected,big_map_diff", + [ # FORMAT: assert_output contract_file storage input expected_result + # expected_diffs + # Get the value stored at the given key in the big map + ( + 'get_big_map_value.tz', + '(Pair { Elt "hello" "hi" } None)', + '"hello"', + '(Pair 4 (Some "hi"))', + [ + ["New map(4) of type (big_map string string)"], + ['Set map(4)["hello"] to "hi"'], + ], + ), + ( + 'get_big_map_value.tz', + '(Pair { Elt "hello" "hi" } None)', + '""', + '(Pair 4 None)', + [ + ["New map(4) of type (big_map string string)"], + ['Set map(4)["hello"] to "hi"'], + ], + ), + ( + 'get_big_map_value.tz', + '(Pair { Elt "1" "one" ; Elt "2" "two" } None)', + '"1"', + '(Pair 4 (Some "one"))', + [ + ["New map(4) of type (big_map string string)"], + ['Set map(4)["2"] to "two"'], + ['Set map(4)["1"] to "one"'], + ], + ), + # Test updating big maps + ( + 'update_big_map.tz', + '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', + '{}', + '(Pair 4 Unit)', + [ + ["New map(4) of type (big_map string string)"], + ['Set map(4)["2"] to "two"'], + ['Set map(4)["1"] to "one"'], + ], + ), + ( + 'update_big_map.tz', + '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', + '{ Elt "1" (Some "two") }', + '(Pair 4 Unit)', + [ + ["New map(4) of type (big_map string string)"], + ['Set map(4)["2"] to "two"'], + ['Set map(4)["1"] to "two"'], + ], + ), + ( + 'update_big_map.tz', + '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', + '{ Elt "3" (Some "three") }', + '(Pair 4 Unit)', + [ + ["New map(4) of type (big_map string string)"], + ['Set map(4)["2"] to "two"'], + ['Set map(4)["3"] to "three"'], + ['Set map(4)["1"] to "one"'], + ], + ), + ( + 'update_big_map.tz', + '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', + '{ Elt "3" None }', + '(Pair 4 Unit)', + [ + ["New map(4) of type (big_map string string)"], + ['Set map(4)["2"] to "two"'], + ['Unset map(4)["3"]'], + ['Set map(4)["1"] to "one"'], + ], + ), + ( + 'update_big_map.tz', + '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', + '{ Elt "2" None }', + '(Pair 4 Unit)', + [ + ["New map(4) of type (big_map string string)"], + ['Unset map(4)["2"]'], + ['Set map(4)["1"] to "one"'], + ], + ), + ( + 'update_big_map.tz', + '(Pair { Elt "1" "one" ; Elt "2" "two" } Unit)', + '{ Elt "1" (Some "two") }', + '(Pair 4 Unit)', + [ + ["New map(4) of type (big_map string string)"], + ['Set map(4)["2"] to "two"'], + ['Set map(4)["1"] to "two"'], + ], + ), + # test the GET_AND_UPDATE instruction on big maps + # Get and update the value stored at the given key in the map + ( + 'get_and_update_big_map.tz', + '(Pair None {})', + '"hello"', + '(Pair None 4)', + [ + ["New map(4) of type (big_map string nat)"], + ['Unset map(4)["hello"]'], + ], + ), + ( + 'get_and_update_big_map.tz', + '(Pair (Some 4) {})', + '"hello"', + '(Pair None 4)', + [ + ["New map(4) of type (big_map string nat)"], + ['Set map(4)["hello"] to 4'], + ], + ), + ( + 'get_and_update_big_map.tz', + '(Pair None { Elt "hello" 4 })', + '"hello"', + '(Pair (Some 4) 4)', + [ + ["New map(4) of type (big_map string nat)"], + ['Unset map(4)["hello"]'], + ], + ), + ( + 'get_and_update_big_map.tz', + '(Pair (Some 5) { Elt "hello" 4 })', + '"hello"', + '(Pair (Some 4) 4)', + [ + ["New map(4) of type (big_map string nat)"], + ['Set map(4)["hello"] to 5'], + ], + ), + ( + 'get_and_update_big_map.tz', + '(Pair (Some 5) { Elt "hello" 4 })', + '"hi"', + '(Pair None 4)', + [ + ["New map(4) of type (big_map string nat)"], + ['Set map(4)["hello"] to 4'], + ['Set map(4)["hi"] to 5'], + ], + ), + ( + 'get_and_update_big_map.tz', + '(Pair None { Elt "1" 1 ; \ + Elt "2" 2 })', + '"1"', + '(Pair (Some 1) 4)', + [ + ["New map(4) of type (big_map string nat)"], + ['Set map(4)["2"] to 2'], + ['Unset map(4)["1"]'], + ], + ), + ( + 'get_and_update_big_map.tz', + '(Pair None { Elt "1" 1 ; \ + Elt "2" 2 })', + '"1"', + '(Pair (Some 1) 4)', + [ + ["New map(4) of type (big_map string nat)"], + ['Set map(4)["2"] to 2'], + ['Unset map(4)["1"]'], + ], + ), + ], + ) + def test__big_map_contract_io( + self, + client_regtest: ClientRegression, + contract: str, + param: str, + storage: str, + expected: str, + big_map_diff: str, + ): + client = client_regtest + contract = path.join(OPCODES_CONTRACT_PATH, contract) + run_script_res = client.run_script( + contract, param, storage, trace_stack=True + ) + assert run_script_res.storage == expected + assert run_script_res.big_map_diff == big_map_diff + + @pytest.mark.parametrize( + "storage,param,expected,big_map_diff", + [ # test swap + ( + '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))', + '(Left Unit)', + '(Left (Pair 4 5))', + [ + ['New map(5) of type (big_map string string)'], + ['Set map(5)["1"] to "one"'], + ['New map(4) of type (big_map string string)'], + ['Set map(4)["2"] to "two"'], + ], + ), + # test reset with new map + ( + '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))', + '(Right (Left (Left (Pair { Elt "3" "three" } ' + + '{ Elt "4" "four" }))))', + '(Left (Pair 4 5))', + [ + ['New map(5) of type (big_map string string)'], + ['Set map(5)["4"] to "four"'], + ['New map(4) of type (big_map string string)'], + ['Set map(4)["3"] to "three"'], + ], + ), + # test reset to unit + ( + '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))', + '(Right (Left (Right Unit)))', + '(Right Unit)', + [], + ), + # test import to big_map + ( + '(Right Unit)', + '(Right (Right (Left (Pair { Pair "foo" "bar" } ' + + '{ Pair "gaz" "baz" }) )))', + '(Left (Pair 4 5))', + [ + ['New map(5) of type (big_map string string)'], + ['Set map(5)["gaz"] to "baz"'], + ['New map(4) of type (big_map string string)'], + ['Set map(4)["foo"] to "bar"'], + ], + ), + # test add to big_map + ( + '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }) )', + '(Right (Right (Right (Left { Pair "3" "three" }))))', + '(Left (Pair 4 5))', + [ + ['New map(5) of type (big_map string string)'], + ['Set map(5)["2"] to "two"'], + ['New map(4) of type (big_map string string)'], + ['Set map(4)["3"] to "three"'], + ['Set map(4)["1"] to "one"'], + ], + ), + # test remove from big_map + ( + '(Left (Pair { Elt "1" "one" } { Elt "2" "two" }))', + '(Right (Right (Right (Right { "1" }))))', + '(Left (Pair 4 5))', + [ + ['New map(5) of type (big_map string string)'], + ['Set map(5)["2"] to "two"'], + ['New map(4) of type (big_map string string)'], + ['Unset map(4)["1"]'], + ], + ), + ], + ) + def test_big_map_magic( + self, + client_regtest: ClientRegression, + storage: str, + param: str, + expected: str, + big_map_diff: str, + ): + client = client_regtest + contract = path.join(MINI_SCENARIOS_CONTRACT_PATH, 'big_map_magic.tz') + run_script_res = client.run_script( + contract, storage, param, trace_stack=True + ) + assert run_script_res.storage == expected + assert run_script_res.big_map_diff == big_map_diff + + def test_packunpack(self, client_regtest: ClientRegression): + """Test PACK/UNPACK and binary format.""" + client = client_regtest + assert_run_script_success( + client, + path.join(OPCODES_CONTRACT_PATH, 'packunpack.tz'), + 'Unit', + '(Pair (Pair (Pair "toto" {3;7;9;1}) {1;2;3}) ' + + '0x05070707070100000004746f746f020000000800030' + + '007000900010200000006000100020003)', + ) + assert_run_script_failwith( + client, + path.join(OPCODES_CONTRACT_PATH, 'packunpack.tz'), + 'Unit', + '(Pair (Pair (Pair "toto" {3;7;9;1}) {1;2;3}) ' + + '0x05070707070100000004746f746f020000000800030' + + '0070009000102000000060001000200030004)', + ) + + def test_check_signature(self, client_regtest: ClientRegression): + client = client_regtest + sig = ( + 'edsigu3QszDjUpeqYqbvhyRxMpVFamEnvm9FYnt7YiiNt' + + '9nmjYfh8ZTbsybZ5WnBkhA7zfHsRVyuTnRsGLR6fNHt1Up1FxgyRtF' + ) + assert_run_script_success( + client, + path.join(OPCODES_CONTRACT_PATH, 'check_signature.tz'), + f'(Pair "{sig}" "hello")', + '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"', + ) + assert_run_script_failwith( + client, + path.join(OPCODES_CONTRACT_PATH, 'check_signature.tz'), + f'(Pair "{sig}" "abcd")', + '"edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"', + ) + + def test_hash_consistency_michelson_cli( + self, client_regtest: ClientRegression + ): + client = client_regtest + hash_result = client.hash( + '(Pair 22220000000 (Pair "2017-12-13T04:49:00Z" 034))', + '(pair mutez (pair timestamp int))', + ).blake2b + hash_contract = path.join( + OPCODES_CONTRACT_PATH, 'hash_consistency_checker.tz' + ) + run_script_res = client.run_script( + hash_contract, + '0x00', + '(Pair 22220000000 (Pair "2017-12-13T04:49:00Z" 034))', + ) + assert run_script_res.storage == hash_result + run_script_res = client.run_script( + hash_contract, + '0x00', + '(Pair 22220000000 (Pair "2017-12-13T04:49:00Z" 034))', + ) + assert run_script_res.storage == hash_result + + @pytest.mark.parametrize( + "contract,param,storage", + [ # FORMAT: assert_output contract_file storage input + # Test overflow in shift + ('shifts.tz', 'None', '(Left (Pair 1 257))'), + ('shifts.tz', 'None', '(Left (Pair 123 257))'), + ('shifts.tz', 'None', '(Right (Pair 1 257))'), + ('shifts.tz', 'None', '(Right (Pair 123 257))'), + ('mul_overflow.tz', 'Unit', 'Left Unit'), + ('mul_overflow.tz', 'Unit', 'Right Unit'), + ], + ) + def test_arithmetic_overflow( + self, + client_regtest_scrubbed: ClientRegression, + contract: str, + param: str, + storage: str, + ): + client = client_regtest_scrubbed + contract = path.join(OPCODES_CONTRACT_PATH, contract) + + with assert_run_failure(r'unexpected arithmetic overflow'): + client.run_script(contract, param, storage) + + @pytest.mark.skip(reason="Bug in annotation system") + def test_fails_annotated_set_car_cdr( + self, client_regtest: ClientRegression + ): + """Tests the SET_CAR and SET_CDR instructions.""" + client = client_regtest + + with assert_run_failure(r'The two annotations do not match'): + client.run_script( + path.join(OPCODES_CONTRACT_PATH, 'set_car.tz'), + '(Pair %wrong %field "hello" 0)', + '""', + ) + + @pytest.mark.parametrize( + "contract,storage,param,expected", + [ # FORMAT: assert_output contract_file storage input expected_result + # Mapping over maps + ('map_map_sideeffect.tz', '(Pair {} 0)', '10', '(Pair {} 0)'), + ( + 'map_map_sideeffect.tz', + '(Pair { Elt "foo" 1 } 1)', + '10', + '(Pair { Elt "foo" 11 } 11)', + ), + ( + 'map_map_sideeffect.tz', + '(Pair { Elt "bar" 5 ; Elt "foo" 1 } 6)', + '15', + '(Pair { Elt "bar" 20 ; Elt "foo" 16 } 36)', + ), + ], + ) + def test_map_map_sideeffect( + self, + client_regtest: ClientRegression, + contract: str, + param: str, + storage: str, + expected: str, + ): + client = client_regtest + contract = path.join(OPCODES_CONTRACT_PATH, contract) + run_script_res = client.run_script(contract, storage, param) + assert run_script_res.storage == expected diff --git a/tests_python/tests_012/test_cors.py b/tests_python/tests_012/test_cors.py new file mode 100644 index 000000000000..80b064285d86 --- /dev/null +++ b/tests_python/tests_012/test_cors.py @@ -0,0 +1,47 @@ +import pytest +from daemons.node import Node +from launchers.sandbox import Sandbox +from tools import utils + + +@pytest.fixture(scope="class") +def node(sandbox: Sandbox): + """Launches one node in sandbox mode (genesis)""" + sandbox.add_node(0, params=['--cors-origin', '*']) + yield sandbox.node(0) + + +class TestCors: + def test_preflight(self, node: Node): + origin = 'localhost' + port = node.rpc_port + headers = { + 'Origin': origin, + 'Access-Control-Request-Method': 'GET', + 'Access-Control-Request-Headers': 'Content-Type', + } + res = utils.rpc( + origin, + port, + 'options', + '/chains/main/blocks/head/header/shell', + headers=headers, + ) + print(res.headers) + assert res.headers["access-control-allow-origin"] == '*' + assert res.headers["access-control-allow-methods"] == 'GET' + assert res.headers["access-control-allow-headers"] == 'Content-Type' + + def test_request(self, node: Node): + origin = 'localhost' + port = node.rpc_port + headers = {'Origin': origin, 'Content-Type': 'application/json'} + res = utils.rpc( + origin, + port, + 'get', + '/chains/main/blocks/head/header/shell', + headers=headers, + ) + print(res.headers) + assert res.headers["access-control-allow-origin"] == '*' diff --git a/tests_python/tests_012/test_crypto.py b/tests_python/tests_012/test_crypto.py new file mode 100644 index 000000000000..995b48fdf617 --- /dev/null +++ b/tests_python/tests_012/test_crypto.py @@ -0,0 +1,47 @@ +from random import getrandbits + +from os import path + +import pytest + +from Crypto.Hash import keccak, SHA3_256 + +from .contract_paths import OPCODES_CONTRACT_PATH + +RANDOM_ITERATIONS = 50 + +HASH_FUNCTIONS = { + "keccak": lambda bytes_to_hash: keccak.new(digest_bits=256) + .update(bytes_to_hash) + .hexdigest(), + "sha3": lambda bytes_to_hash: SHA3_256.new() + .update(bytes_to_hash) + .hexdigest(), +} + + +@pytest.fixture(params=HASH_FUNCTIONS.keys()) +def hash_fun(request): + return request.param + + +@pytest.mark.contract +class TestHash: + @pytest.mark.parametrize( + "bytes_to_hash", + [b"", b"a"] + + [ + getrandbits(bytes_length * 8).to_bytes( + bytes_length, byteorder="little" + ) + for bytes_length in [32] + for _ in range(RANDOM_ITERATIONS) + ], + ) + def test_hash(self, client, hash_fun, bytes_to_hash): + contract = path.join(OPCODES_CONTRACT_PATH, f"{hash_fun}.tz") + + hashed = HASH_FUNCTIONS[hash_fun](bytes_to_hash) + arg = f"0x{bytes_to_hash.hex()}" + result = client.run_script(contract, "None", arg) + assert result.storage == f"(Some 0x{hashed})" diff --git a/tests_python/tests_012/test_fa12.py b/tests_python/tests_012/test_fa12.py new file mode 100644 index 000000000000..ce94cc066e46 --- /dev/null +++ b/tests_python/tests_012/test_fa12.py @@ -0,0 +1,352 @@ +"""This file tests the tezos-client commands offering support for the +FA1.2 standard. Several implementations of the standard are tested.""" + +import json +import os +import pytest +from tools import utils +from tools.constants import IDENTITIES +from client.client import Client +from .contract_paths import CONTRACT_PATH + +BAKE_ARGS = ['--minimal-timestamp'] +BURN_CAP_ARGS = ['--burn-cap', '1.0'] + + +def reset_viewer(client: Client, contract: str): + args = ['--arg', '0'] + client.transfer(0.0, 'bootstrap2', contract, args) + client.bake('bootstrap5', BAKE_ARGS) + + +def check_expected_balance(client, token_contract, addr, expected): + bal = client.fa12_get_balance_offchain(token_contract, addr, []) + return bal.amount == expected + + +def check_expected_allowance(client, token_contract, src, dst, expected): + alw = client.fa12_get_allowance_offchain(token_contract, src, dst, []) + return alw.amount == expected + + +@pytest.fixture( + scope="class", + ids=[ + 'fa12_reference', + 'lqt_fa12', + ], + params=[ + ( + 'fa12_reference', + 'fa12_reference.tz', + lambda key: f'Pair {{}} (Pair "{key}" (Pair False 0))', + ), + ( + 'lqt_fa12', + 'lqt_fa12.mligo.tz', + lambda key: f'Pair {{}} {{}} "{key}" 0', + ), + ], +) +def token_contract(client: Client, session: dict, request): + (contract_alias, contract_path, init_fun) = request.param + + path = os.path.join(CONTRACT_PATH, 'mini_scenarios', contract_path) + identity = IDENTITIES['bootstrap2']['identity'] + init = init_fun(identity) + + utils.originate(client, session, path, init, 0, contract_alias) + + if contract_alias == 'fa12_reference': + identity = IDENTITIES['bootstrap2']['identity'] + param = f'(Pair "{identity}" 20000)' + args = [ + '--entrypoint', + 'mint', + '--arg', + param, + '--burn-cap', + '0.078', + ] + client.transfer(0, 'bootstrap2', contract_alias, args) + client.bake('bootstrap5', BAKE_ARGS) + elif contract_alias == 'lqt_fa12': + identity = IDENTITIES['bootstrap2']['identity'] + param = f'(Pair 20000 "{identity}")' + args = [ + '--entrypoint', + 'mintOrBurn', + '--arg', + param, + '--burn-cap', + '0.078', + ] + client.transfer(0, 'bootstrap2', contract_alias, args) + client.bake('bootstrap5', BAKE_ARGS) + + return contract_alias + + +@pytest.fixture(scope="class") +def view(client: Client, session: dict): + # Only deploy once, it can be used by any fa1.2 contract + contract_alias = 'nat-viewer' + args = ['--init', '0', '--burn-cap', '0.08'] + viewer = "parameter nat; storage nat; code { CAR; NIL operation; PAIR; }" + + origination = client.originate( + contract_alias, 0, 'bootstrap1', viewer, args + ) + session['contract'] = origination.contract + client.bake('bootstrap5', BAKE_ARGS) + return contract_alias + + +class TestFA12Basic: + def test_check_contract(self, client: Client, token_contract: str): + assert client.fa12_check(token_contract).check + + # NOTE: this test does not depend on the token_contract + # fixture (nor should it) + def test_check_contract_fail(self, client: Client, session: dict): + path = os.path.join(CONTRACT_PATH, 'entrypoints', 'manager.tz') + identity = IDENTITIES['bootstrap2']['identity'] + init = f'"{identity}"' + token_contract = 'manager-fail' + utils.originate(client, session, path, init, 0, token_contract) + + assert not client.fa12_check(token_contract).check + + def test_get_balance_offchain(self, client: Client, token_contract: str): + res = client.fa12_get_balance_offchain(token_contract, 'bootstrap2', []) + assert res.amount == 20000 + + def test_get_allowance_offchain(self, client: Client, token_contract: str): + res = client.fa12_get_allowance_offchain( + token_contract, 'bootstrap2', 'bootstrap3', [] + ) + assert res.amount == 0 + + def test_get_total_supply_offchain( + self, client: Client, token_contract: str + ): + res = client.fa12_get_total_supply_offchain(token_contract, []) + expected = 20000 + assert res.amount == expected + + def test_get_balance_callback( + self, client: Client, token_contract: str, view + ): + reset_viewer(client, view) + client.fa12_get_balance_callback( + token_contract, 'bootstrap2', view, BURN_CAP_ARGS + ) + client.bake('bootstrap5', BAKE_ARGS) + utils.assert_storage_contains(client, view, '20000') + + def test_get_allowance_callback( + self, client: Client, token_contract: str, view + ): + reset_viewer(client, view) + client.fa12_get_allowance_callback( + token_contract, 'bootstrap2', 'bootstrap3', view, BURN_CAP_ARGS + ) + client.bake('bootstrap5', BAKE_ARGS) + utils.assert_storage_contains(client, view, '0') + + def test_get_total_supply_callback( + self, client: Client, token_contract: str, view + ): + reset_viewer(client, view) + client.fa12_get_total_supply_callback( + token_contract, 'bootstrap2', view, BURN_CAP_ARGS + ) + client.bake('bootstrap5', BAKE_ARGS) + expected = '20000' + utils.assert_storage_contains(client, view, expected) + + +@pytest.mark.incremental +class TestFA12Incremental: + def test_transfer(self, client: Client, token_contract: str): + client.fa12_transfer( + token_contract, 100, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS + ) + client.bake('bootstrap5', BAKE_ARGS) + + assert check_expected_balance( + client, token_contract, 'bootstrap2', 19900 + ) and check_expected_balance(client, token_contract, 'bootstrap3', 100) + + def test_transfer_not_enough_balance( + self, client: Client, token_contract: str + ): + if token_contract == 'fa12_reference': + error_pattern = r'Not enough balance' + else: + error_pattern = '' + with utils.assert_run_failure(error_pattern): + client.fa12_transfer( + token_contract, 200, 'bootstrap3', 'bootstrap2', BURN_CAP_ARGS + ) + + def test_approve(self, client: Client, token_contract: str): + client.fa12_approve( + token_contract, 20, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS + ) + client.bake('bootstrap5', BAKE_ARGS) + + assert check_expected_allowance( + client, token_contract, 'bootstrap2', 'bootstrap3', 20 + ) + + def test_approve_unsafe_allowance_change( + self, client: Client, token_contract + ): + if token_contract == 'fa12_reference': + error_pattern = r'Unsafe allowance change' + else: + error_pattern = '' + with utils.assert_run_failure(error_pattern): + client.fa12_approve( + token_contract, 30, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS + ) + + def test_transfer_as(self, client: Client, token_contract: str): + client.fa12_transfer_as( + token_contract, + 10, + 'bootstrap2', + 'bootstrap3', + 'bootstrap3', + BURN_CAP_ARGS, + ) + client.bake('bootstrap5', BAKE_ARGS) + + assert ( + check_expected_balance(client, token_contract, 'bootstrap2', 19890) + and check_expected_balance( + client, token_contract, 'bootstrap3', 110 + ) + and check_expected_allowance( + client, token_contract, 'bootstrap2', 'bootstrap3', 10 + ) + ) + + def test_transfer_as_not_enough_allowance( + self, client: Client, token_contract + ): + if token_contract == 'fa12_reference': + error_pattern = r'Not enough allowance' + else: + error_pattern = '' + with utils.assert_run_failure(error_pattern): + client.fa12_transfer_as( + token_contract, + 20, + 'bootstrap2', + 'bootstrap3', + 'bootstrap3', + BURN_CAP_ARGS, + ) + + def test_multiple_transfers(self, client: Client, token_contract: str): + op1 = client.fa12_mk_batch_transfer('bootstrap4', token_contract, 100) + op2 = client.fa12_mk_batch_transfer('bootstrap5', token_contract, 10) + json_ops = json.dumps(op1 + op2, separators=(',', ':')) + client.fa12_multiple_tokens_transfers( + 'bootstrap2', json_ops, BURN_CAP_ARGS + ) + client.bake('bootstrap5', BAKE_ARGS) + + assert ( + check_expected_balance(client, token_contract, 'bootstrap2', 19780) + and check_expected_balance( + client, token_contract, 'bootstrap4', 100 + ) + and check_expected_balance(client, token_contract, 'bootstrap5', 10) + and check_expected_allowance( + client, token_contract, 'bootstrap2', 'bootstrap3', 10 + ) + ) + + def test_multiple_transfers_fail(self, client: Client, token_contract: str): + op1 = client.fa12_mk_batch_transfer('bootstrap4', token_contract, 100) + op2 = client.fa12_mk_batch_transfer( + 'bootstrap5', token_contract, 100000 + ) + json_ops = json.dumps(op1 + op2, separators=(',', ':')) + + bal_sender_before = client.fa12_get_balance_offchain( + token_contract, 'bootstrap2', [] + ) + bal_receiver1_before = client.fa12_get_balance_offchain( + token_contract, 'bootstrap4', [] + ) + bal_receiver2_before = client.fa12_get_balance_offchain( + token_contract, 'bootstrap5', [] + ) + + error_pattern = r'multiple transfers simulation failed' + with utils.assert_run_failure(error_pattern): + client.fa12_multiple_tokens_transfers( + 'bootstrap2', json_ops, BURN_CAP_ARGS + ) + + client.bake('bootstrap5', BAKE_ARGS) + + assert ( + check_expected_balance( + client, + token_contract, + 'bootstrap2', + bal_sender_before.amount, + ) + and check_expected_balance( + client, + token_contract, + 'bootstrap4', + bal_receiver1_before.amount, + ) + and check_expected_balance( + client, + token_contract, + 'bootstrap5', + bal_receiver2_before.amount, + ) + ) + + def test_multiple_transfers_as(self, client: Client, token_contract: str): + client.fa12_approve( + token_contract, 0, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS + ) + client.bake('bootstrap5', BAKE_ARGS) + + client.fa12_approve( + token_contract, 30, 'bootstrap2', 'bootstrap3', BURN_CAP_ARGS + ) + client.bake('bootstrap5', BAKE_ARGS) + check_allowance_before = check_expected_allowance( + client, token_contract, 'bootstrap2', 'bootstrap3', 30 + ) + + op1 = client.fa12_mk_batch_transfer('bootstrap4', token_contract, 10) + op2 = client.fa12_mk_batch_transfer('bootstrap5', token_contract, 20) + json_ops = json.dumps(op1 + op2, separators=(',', ':')) + + client.fa12_multiple_tokens_transfers_as( + 'bootstrap2', 'bootstrap3', json_ops, BURN_CAP_ARGS + ) + client.bake('bootstrap5', BAKE_ARGS) + + assert ( + check_expected_balance(client, token_contract, 'bootstrap2', 19750) + and check_expected_balance( + client, token_contract, 'bootstrap4', 110 + ) + and check_expected_balance(client, token_contract, 'bootstrap5', 30) + and check_allowance_before + and check_expected_allowance( + client, token_contract, 'bootstrap2', 'bootstrap3', 0 + ) + ) diff --git a/tests_python/tests_012/test_forge_block.py b/tests_python/tests_012/test_forge_block.py new file mode 100755 index 000000000000..b931cf986537 --- /dev/null +++ b/tests_python/tests_012/test_forge_block.py @@ -0,0 +1,46 @@ +import datetime +import pytest +from tools import constants +from tools.constants import PROTO_DEMO_NOOPS +from launchers.sandbox import Sandbox + + +@pytest.mark.slow +@pytest.mark.incremental +class TestForgeBlock: + """ Check that a block more than 5 seconds in the future is rejected """ + + def test_setup_network(self, sandbox: Sandbox): + sandbox.add_node(1, params=constants.NODE_PARAMS) + + def test_protocol_exists(self, sandbox: Sandbox): + client = sandbox.client(1) + protocols = client.list_protocols() + assert PROTO_DEMO_NOOPS in protocols + + def test_activate_proto_demo_time_shifted_ok(self, sandbox: Sandbox): + parameters = {} # type: dict + delta = datetime.timedelta(seconds=5) + sandbox.client(1).activate_protocol_json( + PROTO_DEMO_NOOPS, + parameters, + key='activator', + timestamp=(datetime.datetime.utcnow() + delta).strftime( + "%Y-%m-%dT%H:%M:%SZ" + ), + fitness='1', + ) + + @pytest.mark.xfail + def test_activate_proto_demo_time_shifted_ko(self, sandbox: Sandbox): + parameters = {} # type: dict + delta = datetime.timedelta(seconds=30) + sandbox.client(1).activate_protocol_json( + PROTO_DEMO_NOOPS, + parameters, + key='activator', + timestamp=(datetime.datetime.utcnow() + delta).strftime( + "%Y-%m-%dT%H:%M:%SZ" + ), + fitness='1', + ) diff --git a/tests_python/tests_012/test_fork.py b/tests_python/tests_012/test_fork.py new file mode 100644 index 000000000000..0ce7d92a6a53 --- /dev/null +++ b/tests_python/tests_012/test_fork.py @@ -0,0 +1,88 @@ +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox +from . import protocol + + +NUM_NODES = 3 + + +@pytest.mark.multinode +@pytest.mark.incremental +class TestFork: + """Constructs two independent branches on disconnected subsets of nodes, + one head has higher fitness. At reconnection, check the the highest + fitness head is the chosen one""" + + def test_init(self, sandbox: Sandbox): + for i in range(NUM_NODES): + sandbox.add_node(i, params=constants.NODE_PARAMS) + parameters = protocol.get_parameters() + parameters['consensus_threshold'] = 0 + protocol.activate( + sandbox.client(0), parameters=parameters, activate_in_the_past=True + ) + + def test_level(self, sandbox: Sandbox): + level = 1 + for client in sandbox.all_clients(): + assert utils.check_level(client, level) + + def test_terminate_nodes_1_and_2(self, sandbox: Sandbox): + sandbox.node(1).terminate() + sandbox.node(2).terminate() + + def test_bake_node_0(self, sandbox: Sandbox): + """Client 0 bakes block A at level 2, not communicated to 1 and 2""" + utils.bake(sandbox.client(0)) + + def test_endorse_node_0(self, sandbox: Sandbox, session: dict): + """bootstrap1 builds an endorsement for block A""" + client = sandbox.client(0) + client.run(["endorse", "for", "bootstrap1", "--force"]) + mempool = client.get_mempool() + endorsement = mempool['applied'][0] + session['endorsement1'] = endorsement + + def test_bake_node_0_again(self, sandbox: Sandbox): + """Client 0 bakes block A' at level 3, not communicated to 1 and 2""" + utils.bake(sandbox.client(0), bake_for='bootstrap1') + + def test_first_branch(self, sandbox: Sandbox, session: dict): + head = sandbox.client(0).get_head() + assert head['header']['level'] == 3 + session['hash1'] = head['hash'] + assert len(head['operations'][0]) == 1 + + def test_terminate_node_0(self, sandbox: Sandbox): + sandbox.node(0).terminate() + + def test_restart_node_2(self, sandbox: Sandbox): + sandbox.node(2).run() + assert sandbox.client(2).check_node_listening() + + def test_bake_node_2(self, sandbox: Sandbox): + """Client 2 bakes block B at level 2, not communicated to 0 and 1""" + utils.bake(sandbox.client(2), bake_for='bootstrap1') + + def test_bake_node_2_again(self, sandbox: Sandbox): + """Client 2 bakes block B' at level 3, not communicated to 0 and 1""" + utils.bake(sandbox.client(2), bake_for='bootstrap1') + + def test_second_branch(self, sandbox: Sandbox, session: dict): + head = sandbox.client(2).get_head() + session['hash2'] = head['hash'] + assert head['header']['level'] == 3 + assert len(head['operations'][0]) == 1 + + def test_restart_all(self, sandbox: Sandbox): + sandbox.node(0).run() + sandbox.node(1).run() + assert sandbox.client(0).check_node_listening() + assert sandbox.client(1).check_node_listening() + + def test_check_head(self, sandbox: Sandbox, session: dict): + """All nodes are at level 3, head should be hash1""" + for client in sandbox.all_clients(): + head = client.get_head() + assert session['hash1'] == head['hash'] diff --git a/tests_python/tests_012/test_injection.py b/tests_python/tests_012/test_injection.py new file mode 100644 index 000000000000..fee00a37d5d4 --- /dev/null +++ b/tests_python/tests_012/test_injection.py @@ -0,0 +1,103 @@ +import os +from typing import List +import subprocess +import pytest +from tools import utils, paths, constants +from tools.constants import PROTO_DEMO_NOOPS, PROTO_GENESIS +from client.client import Client + + +@pytest.fixture(scope="class") +def clients(sandbox): + """Launches 3 nodes in sandbox mode (genesis, doesn't activate 012).""" + num_nodes = 3 + for i in range(num_nodes): + sandbox.add_node(i, params=constants.NODE_PARAMS) + yield sandbox.all_clients() + + +PROTO = f'{paths.TEZOS_HOME}/src/bin_client/test/proto_test_injection' +COMPILER = ( + f'{paths.TEZOS_HOME}/_build/default/src/lib_protocol_compiler/bin/' + 'main_native.exe' +) +PARAMS = ['-p', PROTO_GENESIS] + + +@pytest.mark.incremental +class TestInjectionAndActivation: + """Protocol injection and activation""" + + def test_check_resources(self): + assert os.path.isfile(COMPILER) + assert os.path.isdir(PROTO) + + def test_compute_hash(self, session: dict): + cmd = [COMPILER, '-hash-only', PROTO] + res = subprocess.run( + cmd, universal_newlines=True, check=True, stdout=subprocess.PIPE + ) + proto_hash = res.stdout[:-1] + assert len(proto_hash) == 51 + session['proto_hash'] = proto_hash + + def test_injection(self, clients: List[Client]): + clients[0].inject_protocol(PROTO) + + def test_check_injected(self, clients: List[Client], session: dict): + proto = session['proto_hash'] + protos = clients[0].list_protocols() + assert proto in protos + + def test_environment_version(self, clients: List[Client], session: dict): + proto = session['proto_hash'] + assert clients[0].environment_protocol(proto) == "V1" + + def test_activation(self, clients: List[Client], session: dict): + proto = session['proto_hash'] + parameters = {} # type: dict + res = clients[0].activate_protocol_json( + proto, parameters, key='activator', fitness='1' + ) + assert res.block_hash + + def test_check_protocol(self, clients: List[Client], session: dict): + proto = session['proto_hash'] + for client in clients: + assert utils.check_protocol(client, proto, params=PARAMS) + + +@pytest.fixture(scope="class") +def client(sandbox): + """One node in sandbox mode (genesis, doesn't activate 012).""" + sandbox.add_node(0) + client = sandbox.client(0) + yield client + + +@pytest.mark.incremental +class TestActivation: + """ Protocol activation (protocol already linked to the node) """ + + def test_proto_known(self, client: Client): + res = client.list_protocols() + assert PROTO_DEMO_NOOPS in res + + def test_first_protocol(self, client: Client): + proto = 'PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i' + assert client.get_protocol() == proto + + def test_activate_demo(self, client: Client): + proto = PROTO_DEMO_NOOPS + parameters = {} # type: dict + res = client.activate_protocol_json( + proto, parameters, key='activator', fitness='1' + ) + assert res.block_hash + + def test_level1(self, client: Client): + assert client.get_level(params=PARAMS) == 1 + + def test_protocol_genesis(self, client: Client): + proto = PROTO_GENESIS + assert client.get_protocol(params=PARAMS) == proto diff --git a/tests_python/tests_012/test_liquidity_baking.py b/tests_python/tests_012/test_liquidity_baking.py new file mode 100644 index 000000000000..17aaafa06305 --- /dev/null +++ b/tests_python/tests_012/test_liquidity_baking.py @@ -0,0 +1,279 @@ +import pytest + +from tools import utils +from tools.constants import IDENTITIES + +DEX = "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5" +TOK = "KT1VqarPDicMFn1ejmQqqshUkUXTCTXwmkCN" +LQT = "KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo" +BOOTSTRAP1 = IDENTITIES['bootstrap1']['identity'] +TOK_ADMIN = BOOTSTRAP1 +BOOTSTRAP2 = IDENTITIES['bootstrap2']['identity'] +BOOTSTRAP3 = IDENTITIES['bootstrap3']['identity'] +FUTURE = "2050-01-01T00:00:00Z" + + +@pytest.mark.contract +@pytest.mark.regression +@pytest.mark.incremental +class SetupMintAndApprove: + """Test calling entrypoints of liquidity baking contracts""" + + def test_setup(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + assert DEX == client.rpc( + 'get', + "/chains/main/blocks/head/context/liquidity_baking/cpmm_address", + ) + dex_storage = client.get_storage(DEX).split() + assert dex_storage[4].strip('"') == TOK + assert dex_storage[5].strip('"') == LQT + + # mint some test TOK (1 tzBTC?) for ourselves + def test_call_mint_or_burn(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.call( + TOK_ADMIN, + TOK, + [ + '--entrypoint', + 'mintOrBurn', + '--arg', + f'(Pair 100000000 "{BOOTSTRAP1}")', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + # pre-approve big allowances in TOK for DEX + def test_call_approve1(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.call( + 'bootstrap1', + TOK, + [ + '--entrypoint', + 'approve', + '--arg', + f'(Pair "{DEX}" 1000000000)', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + def test_call_approve2(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.call( + 'bootstrap2', + TOK, + [ + '--entrypoint', + 'approve', + '--arg', + f'(Pair "{DEX}" 1000000000)', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + def test_call_approve3(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.call( + 'bootstrap3', + TOK, + [ + '--entrypoint', + 'approve', + '--arg', + f'(Pair "{DEX}" 1000000000)', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + +@pytest.mark.contract +@pytest.mark.regression +@pytest.mark.incremental +class TestAddApproveTransferRemove(SetupMintAndApprove): + """Test add/approve/transfer/remove liquidity""" + + # first add liquidity on DEX so that we have some LQT + def test_add_liquidity(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.transfer( + 9001, + 'bootstrap1', + DEX, + [ + '--entrypoint', + 'addLiquidity', + '--arg', + f'(Pair "{BOOTSTRAP1}" 0 1000000000 "{FUTURE}")', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + # test LQT approval + def test_approval(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.call( + 'bootstrap1', + LQT, + [ + '--entrypoint', + 'approve', + '--arg', + f'(Pair "{BOOTSTRAP2}" 1000)', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + # transfer LQT to bootstrap2 (using approval) + def test_approved_transfer(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.call( + 'bootstrap2', + LQT, + [ + '--entrypoint', + 'transfer', + '--arg', + f'(Pair "{BOOTSTRAP1}" "{BOOTSTRAP2}" 1000)', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + # now remove LQT for bootstrap2 + def test_remove_liquidity(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.call( + 'bootstrap2', + DEX, + [ + '--entrypoint', + 'removeLiquidity', + '--arg', + f'(Pair "{BOOTSTRAP2}" 1000 0 0 "{FUTURE}")', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + # check DEX storage + def test_dex_storage(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.get_storage(DEX) + + # check LQT storage + def test_lqt_storage(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.get_storage(LQT) + + # check TOK storage + def test_tok_storage(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.get_storage(TOK) + + +@pytest.mark.contract +@pytest.mark.regression +@pytest.mark.incremental +class TestTrades(SetupMintAndApprove): + """Test trades""" + + # add liquidity + def test_add_liquidity(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.transfer( + 9001, + 'bootstrap1', + DEX, + [ + '--entrypoint', + 'addLiquidity', + '--arg', + f'(Pair "{BOOTSTRAP1}" 0 1000000000 "{FUTURE}")', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + # bootstrap2 buys some TOK + def test_buy_tok(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.transfer( + 9001, + 'bootstrap2', + DEX, + [ + '--entrypoint', + 'xtzToToken', + '--arg', + f'(Pair "{BOOTSTRAP2}" 0 "{FUTURE}")', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + # bootstrap2 transfers TOK to bootstrap3 + def test_transfer(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.call( + 'bootstrap2', + TOK, + [ + '--entrypoint', + 'transfer', + '--arg', + f'(Pair "{BOOTSTRAP2}" "{BOOTSTRAP3}" 100)', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + # bootstrap3 sells TOK + def test_sell_tok(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.call( + 'bootstrap3', + DEX, + [ + '--entrypoint', + 'tokenToXtz', + '--arg', + f'(Pair "{BOOTSTRAP3}" 100 0 "{FUTURE}")', + '--burn-cap', + '10', + ], + ) + utils.bake(client, 'bootstrap5') + + # check DEX storage + def test_dex_storage(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.get_storage(DEX) + + # check LQT storage + def test_lqt_storage(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.get_storage(LQT) + + # check TOK storage + def test_tok_storage(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.get_storage(TOK) diff --git a/tests_python/tests_012/test_many_bakers.py b/tests_python/tests_012/test_many_bakers.py new file mode 100644 index 000000000000..f13981411ede --- /dev/null +++ b/tests_python/tests_012/test_many_bakers.py @@ -0,0 +1,42 @@ +import time +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox +from . import protocol + +# TODO parameterize test + +MINIMAL_BLOCK_DELAY = 15 + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +class TestManyBakers: + """Run 5 bakers and num nodes, wait and check logs""" + + def test_init(self, sandbox: Sandbox): + for i in range(10): + sandbox.add_node(i, params=constants.NODE_PARAMS) + protocol.activate(sandbox.client(0)) + for i in range(5): + sandbox.add_baker(i, [f'bootstrap{i + 1}'], proto=protocol.DAEMON) + + def test_wait(self): + # expects two level to be added to level start + time.sleep(2 * MINIMAL_BLOCK_DELAY) + + def test_progress(self, sandbox: Sandbox): + min_level = min( + [client.get_level() for client in sandbox.all_clients()] + ) + assert min_level >= 3 + + @pytest.mark.xfail + def test_check_logs(self, sandbox: Sandbox): + if not sandbox.log_dir: + pytest.skip() + assert sandbox.logs + error_pattern = r"canceled|crashed" + assert utils.check_logs(sandbox.logs, error_pattern) diff --git a/tests_python/tests_012/test_many_nodes.py b/tests_python/tests_012/test_many_nodes.py new file mode 100644 index 000000000000..a24489cb4d00 --- /dev/null +++ b/tests_python/tests_012/test_many_nodes.py @@ -0,0 +1,66 @@ +import random +import time +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox +from . import protocol + +NUM_NODES = 5 +NEW_NODES = 3 +REPLACE = False +ERROR_PATTERN = r"Uncaught|registered" + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +class TestManyNodesBootstrap: + """Run many nodes, wait a while, run more nodes, check logs""" + + def test_init(self, sandbox: Sandbox): + sandbox.add_node(0, params=constants.NODE_PARAMS) + parameters = dict(protocol.PARAMETERS) + # smaller threshold to make (almost sure) that 3/5 of the delegates + # have enough endorsing power + parameters['consensus_threshold'] = 5 + parameters['minimal_block_delay'] = '3' + parameters['delay_increment_per_round'] = '1' + protocol.activate(sandbox.client(0), parameters) + for i in range(1, NEW_NODES): + sandbox.add_node(i, params=constants.NODE_PARAMS) + for i in range(3): + sandbox.add_baker(i, [f'bootstrap{i + 1}'], proto=protocol.DAEMON) + + def test_add_nodes(self, sandbox: Sandbox): + for i in range(NEW_NODES, NUM_NODES): + sandbox.add_node(i, params=constants.NODE_PARAMS) + + def test_sleep_30s(self): + time.sleep(30) + + def test_add_more_nodes(self, sandbox: Sandbox): + new_node = NUM_NODES + for i in range(NEW_NODES): + if REPLACE: + running_nodes = list(sandbox.nodes.keys()) + sandbox.rm_node(random.choice(running_nodes)) + sandbox.add_node(new_node + i, params=constants.NODE_PARAMS) + + def test_kill_baker(self, sandbox: Sandbox): + assert utils.check_logs(sandbox.logs, ERROR_PATTERN) + for i in range(3): + sandbox.rm_baker(i, proto=protocol.DAEMON) + + def test_synchronize(self, sandbox: Sandbox): + utils.synchronize(sandbox.all_clients()) + + def test_progress(self, sandbox: Sandbox): + level = sandbox.client(0).get_level() + assert level >= 5 + + def test_check_logs(self, sandbox: Sandbox): + if not sandbox.log_dir: + pytest.skip() + assert sandbox.logs + assert utils.check_logs(sandbox.logs, ERROR_PATTERN) diff --git a/tests_python/tests_012/test_mempool.py b/tests_python/tests_012/test_mempool.py new file mode 100644 index 000000000000..11d9a459c2d7 --- /dev/null +++ b/tests_python/tests_012/test_mempool.py @@ -0,0 +1,66 @@ +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox + +from . import protocol + + +@pytest.mark.mempool +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +class TestMempool: + " Tests mempool" + + def test_init(self, sandbox: Sandbox): + sandbox.add_node(1, params=constants.NODE_PARAMS) + sandbox.add_node(2, params=constants.NODE_PARAMS) + sandbox.add_node( + 3, params=constants.NODE_PARAMS + ['--disable-mempool'] + ) + protocol.activate(sandbox.client(1), activate_in_the_past=True) + + def test_level1(self, sandbox: Sandbox): + level = 1 + for client in sandbox.all_clients(): + assert utils.check_level(client, level) + + def test_running_prevalidators(self, sandbox: Sandbox): + assert sandbox.client(1).get_prevalidator() + assert sandbox.client(2).get_prevalidator() + assert not sandbox.client(3).get_prevalidator() + + def test_mempool_empty(self, sandbox: Sandbox): + for i in range(1, 4): + assert sandbox.client(i).mempool_is_empty() + + def test_transfer(self, sandbox: Sandbox, session: dict): + client = sandbox.client(1) + session['trsfr_hash'] = client.transfer( + 1.000, 'bootstrap1', 'bootstrap2' + ).operation_hash + + def test_mempool_include_transfer(self, sandbox: Sandbox, session: dict): + assert utils.check_mempool_contains_operations( + sandbox.client(1), [session['trsfr_hash']] + ) + assert utils.check_mempool_contains_operations( + sandbox.client(2), [session['trsfr_hash']] + ) + assert sandbox.client(3).mempool_is_empty() + + def test_bake_for1(self, sandbox: Sandbox): + utils.bake(sandbox.client(1)) + + def test_level2(self, sandbox: Sandbox): + level = 2 + for client in sandbox.all_clients(): + assert utils.check_level(client, level) + + def test_mempools_are_empty(self, sandbox: Sandbox): + for i in range(1, 4): + assert sandbox.client(i).mempool_is_empty() + + def test_injection_fails_on_mempool_disabled_node(self, sandbox: Sandbox): + with pytest.raises(Exception): + sandbox.client(3).transfer(2.000, 'bootstrap2', 'bootstrap3') diff --git a/tests_python/tests_012/test_migration.py b/tests_python/tests_012/test_migration.py new file mode 100644 index 000000000000..ca1566181e6a --- /dev/null +++ b/tests_python/tests_012/test_migration.py @@ -0,0 +1,298 @@ +import time + +import pytest + +from launchers.sandbox import Sandbox +from tools import constants, utils +from tools.constants import PROTO_GENESIS +from . import protocol + +MIGRATION_LEVEL = 8 +BAKER = 'bootstrap1' +BAKER_PKH = constants.IDENTITIES[BAKER]['identity'] +PREV_DEPOSIT = protocol.PREV_PARAMETERS["block_security_deposit"] +BAKER_BALANCE = next( + bal for [BAKER_PKH, bal] in protocol.PARAMETERS["bootstrap_accounts"] +) + +PREV_DEPOSIT_RECEIPTS = [ + { + "kind": "contract", + "contract": BAKER_PKH, + "change": "-" + PREV_DEPOSIT, + "origin": "block", + }, + { + "kind": "freezer", + "category": "deposits", + "delegate": BAKER_PKH, + "cycle": 0, + "change": PREV_DEPOSIT, + "origin": "block", + }, +] + +# configure user-activate-upgrade at MIGRATION_LEVEL to test migration +NODE_CONFIG = { + 'network': { + 'genesis': { + 'timestamp': '2018-06-30T16:07:32Z', + 'block': 'BLockGenesisGenesisGenesisGenesisGenesisf79b5d1CoW2', + 'protocol': PROTO_GENESIS, + }, + 'genesis_parameters': { + 'values': {'genesis_pubkey': constants.GENESIS_PK} + }, + 'chain_name': 'TEZOS', + 'sandboxed_chain_name': 'SANDBOXED_TEZOS', + 'user_activated_upgrades': [ + {'level': MIGRATION_LEVEL, 'replacement_protocol': protocol.HASH} + ], + } +} + + +def filter_out_rewards(balance_updates): + """Keep elements for BAKER_PKH which either have no category key + or are not labeled as rewards""" + return [ + bu + for bu in balance_updates + if ( + ("delegate" in bu and bu["delegate"] == BAKER_PKH) + or ("contract" in bu and bu["contract"] == BAKER_PKH) + ) + and ("category" not in bu or bu["category"] != 'rewards') + ] + + +@pytest.fixture(scope="class") +def client(sandbox): + sandbox.add_node(0, params=constants.NODE_PARAMS, node_config=NODE_CONFIG) + protocol.activate( + sandbox.client(0), + proto=protocol.PREV_HASH, + parameters=protocol.PREV_PARAMETERS, + activate_in_the_past=True, + ) + yield sandbox.client(0) + + +all_bootstrap_accounts = [f"bootstrap{i}" for i in range(1, 6)] + + +def endorse_all(client, endorse="endorse"): + cmd = [endorse, "for"] + all_bootstrap_accounts + ["--force"] + client.run(cmd) + + +def manual_bake(client, baker): + """Tenderbake baking using propose/preendorse/endorse + + Using the 3 lower level steps instead of `bake for` allows to control who + bakes while (pre)endorsing with all known accounts. Such fine-grained + control cannot be achieved through `bake for`. + + """ + client.propose([baker], ["--minimal-timestamp"]) + endorse_all(client, endorse="preendorse") + endorse_all(client) + + +@pytest.mark.incremental +class TestMigration: + """Test migration from PROTO_A (the previous protocol) to PROTO_B (the + current protocol). + + After migration, test snapshots: + - node0: activate PROTO_A, migrate to PROTO_B, bake, export + a snapshot in full and rolling modes, and terminate + - node1: import full, bake + - node2: import rolling, sync, bake + - node3: reconstruct full, sync, bake + - all 4 are synced + """ + + def test_init(self, client): + # 1: genesis block + client.get_head() + client.rpc('get', '/config/network/user_activated_upgrades') + + def test_activate(self, client, sandbox): + # 2: activated PROTO_A + utils.bake(client, BAKER) + assert client.get_protocol() == protocol.PREV_HASH + assert sandbox.client(0).get_head()['header']['proto'] == 1 + metadata = client.get_metadata() + assert metadata['balance_updates'] == PREV_DEPOSIT_RECEIPTS + # PROTO_A is using env. V1+, metadata hashes should be present + _ops_metadata_hash = client.get_operations_metadata_hash() + _block_metadata_hash = client.get_block_metadata_hash() + + def test_migration(self, client, sandbox): + # 3: last block of PROTO_A, runs migration code (MIGRATION_LEVEL) + for _i in range(MIGRATION_LEVEL - 2): + utils.bake(client, BAKER) + metadata = client.get_metadata() + assert metadata['next_protocol'] == protocol.HASH + assert metadata['balance_updates'] == PREV_DEPOSIT_RECEIPTS + # PROTO_B is using env. V1+, metadata hashes should be present + _ops_metadata_hash = client.get_operations_metadata_hash() + _block_metadata_hash = client.get_block_metadata_hash() + assert sandbox.client(0).get_head()['header']['proto'] == 2 + + def test_new_proto(self, client, sandbox): + # 4: first block of PROTO_B + manual_bake(client, BAKER) + # client.multibake(args=["--minimal-timestamp"]) + # utils.bake(client, "bootstrap1 bootstrap2") + assert client.get_protocol() == protocol.HASH + assert sandbox.client(0).get_head()['header']['proto'] == 2 + # check that migration balance update appears in receipts + _metadata = client.get_metadata() + constants = client.rpc( + 'get', '/chains/main/blocks/head/context/constants' + ) + # N.B.: after migration, the values being used are those set in + # raw_context + bond = str( + int(constants["frozen_deposits_percentage"]) + * int(int(BAKER_BALANCE) / 100) + ) + block_reward = str(constants["baking_reward_fixed_portion"]) + deposit = str((MIGRATION_LEVEL - 1) * int(PREV_DEPOSIT)) + # these receipts appear in the first block of TB + migration_receipts = [ + { + "kind": "freezer", + "category": "deposits", + "delegate": BAKER_PKH, + "change": bond, + "origin": "migration", + }, + { + "kind": "freezer", + "category": "legacy_deposits", + "delegate": BAKER_PKH, + "cycle": 0, + "change": "-" + deposit, + "origin": "migration", + }, + { + "kind": "contract", + "contract": BAKER_PKH, + "change": "-" + str(int(bond) - int(deposit)), + "origin": "migration", + }, + # BAKER has baked the first block of TB; + # hence, the reward for baking + { + "kind": "contract", + "contract": BAKER_PKH, + "change": block_reward, + "origin": "block", + }, + ] + initial_balance_updates = migration_receipts + new_balance_updates = filter_out_rewards(_metadata['balance_updates']) + assert initial_balance_updates == new_balance_updates + _ops_metadata_hash = client.get_operations_metadata_hash() + _block_metadata_hash = client.get_block_metadata_hash() + + def test_new_proto_second(self, client): + # 5: second block of PROTO_B + manual_bake(client, BAKER) + metadata = client.get_metadata() + constants = client.rpc( + 'get', '/chains/main/blocks/head/context/constants' + ) + # N.B.: after migration, the values being used are those set + # in raw_context + # using protocol.PARAMETERS["consensus_threshold"] is wrong + bonus_per_slot = constants["baking_reward_bonus_per_slot"] + bonus = ( + constants["consensus_committee_size"] + - constants["consensus_threshold"] + ) * int(bonus_per_slot) + block_reward = str(constants["baking_reward_fixed_portion"]) + receipts = [ + { + "kind": "contract", + "contract": BAKER_PKH, + "change": block_reward, + "origin": "block", + }, + { + "kind": "contract", + "contract": BAKER_PKH, + "change": str(bonus), + "origin": "block", + }, + ] + assert filter_out_rewards(metadata['balance_updates']) == receipts + + def test_terminate_node0(self, client, sandbox: Sandbox, session: dict): + # to export rolling snapshot, we need to be at level > 60 + # (see `max_operations_ttl`) + level = client.get_head()['header']['level'] + for _ in range(60 - level + 1): + manual_bake(client, BAKER) + assert client.get_head()['header']['level'] == 61 + + # terminate node0 + session['head_hash'] = sandbox.client(0).get_head()['hash'] + sandbox.node(0).terminate() + time.sleep(1) + + def test_export_snapshots(self, sandbox, tmpdir, session: dict): + node_export = sandbox.node(0) + file_full = f'{tmpdir}/FILE.full' + file_rolling = f'{tmpdir}/FILE.rolling' + head_hash = session['head_hash'] + session['snapshot_full'] = file_full + session['snapshot_rolling'] = file_rolling + node_export.snapshot_export(file_full, params=['--block', head_hash]) + node_export.snapshot_export( + file_rolling, params=['--block', head_hash, '--rolling'] + ) + + def test_import_full_snapshot_node1(self, sandbox, session): + sandbox.add_node( + 1, snapshot=session['snapshot_full'], node_config=NODE_CONFIG + ) + client = sandbox.client(1) + client.multibake(args=["--minimal-timestamp"]) + + def test_import_rolling_snapshot_node2(self, sandbox, session): + sandbox.add_node( + 2, + snapshot=session['snapshot_rolling'], + params=constants.NODE_PARAMS, + node_config=NODE_CONFIG, + ) + client = sandbox.client(2) + utils.synchronize([sandbox.client(1), client], max_diff=0) + client.multibake(args=["--minimal-timestamp"]) + + def test_reconstruct_full_node3(self, sandbox, session): + sandbox.add_node( + 3, + snapshot=session['snapshot_full'], + node_config=NODE_CONFIG, + params=constants.NODE_PARAMS, + ) + sandbox.node(3).terminate() + time.sleep(3) + sandbox.node(3).reconstruct() + sandbox.node(3).run() + client = sandbox.client(3) + assert client.check_node_listening() + utils.synchronize( + [sandbox.client(1), sandbox.client(2), client], max_diff=0 + ) + client.multibake(args=["--minimal-timestamp"]) + + def test_rerun_node0(self, sandbox): + sandbox.node(0).run() + sandbox.client(0).check_node_listening() + utils.synchronize(sandbox.all_clients(), max_diff=0) diff --git a/tests_python/tests_012/test_mockup.py b/tests_python/tests_012/test_mockup.py new file mode 100644 index 000000000000..f88cc5cf1f82 --- /dev/null +++ b/tests_python/tests_012/test_mockup.py @@ -0,0 +1,762 @@ +""" This file tests the mockup mode (tezos-client --mode mockup). + In this mode the client does not need a node running. + + Make sure to either use the fixture mockup_client or + to mimick it if you want a mockup with custom parameters. + + Care is taken not to leave any base_dir dangling after + tests are finished. Please continue doing this. +""" +import json +import os +import re +import shutil +import tempfile +from pathlib import Path +from typing import Any, List, Optional, Tuple +import pytest +from launchers.sandbox import Sandbox +from client.client import Client +from client.client_output import CreateMockupResult + +from . import protocol + +_BA_FLAG = "bootstrap-accounts" +_PC_FLAG = "protocol-constants" + + +@pytest.mark.client +def test_list_mockup_protocols(sandbox: Sandbox): + """Executes `tezos-client list mockup protocols` + The call must succeed and return a non empty list. + """ + try: + client = sandbox.create_client() + protocols = client.list_mockup_protocols().mockup_protocols + assert protocols + finally: + shutil.rmtree(client.base_dir) + + +@pytest.mark.client +def test_create_mockup_dir_exists_nonempty(sandbox: Sandbox): + """Executes `tezos-client --base-dir /tmp/mdir create mockup` + when /tmp/mdir is a non empty directory which is NOT a mockup + directory. The call must fail. + """ + with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: + # Make the directory not empty + with open(os.path.join(base_dir, "whatever"), "w") as handle: + handle.write("") + unmanaged_client = sandbox.create_client(base_dir=base_dir) + res = unmanaged_client.create_mockup( + protocol=protocol.HASH, check=False + ).create_mockup_result + assert res == CreateMockupResult.DIR_NOT_EMPTY + + +@pytest.mark.client +def test_retrieve_addresses(mockup_client: Client): + """Retrieves known addresses of a fresh mockup. + The call must succeed. + """ + addresses = mockup_client.get_known_addresses().wallet + assert addresses == { + 'bootstrap1': 'tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx', + 'bootstrap2': 'tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN', + 'bootstrap3': 'tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU', + 'bootstrap4': 'tz1b7tUupMgCNw2cCLpKTkSD1NZzB5TkP2sv', + 'bootstrap5': 'tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv', + } + + +@pytest.mark.client +def test_create_mockup_already_initialized(mockup_client: Client): + """Executes `tezos-client --base-dir /tmp/mdir create mockup` + when /tmp/mdir is not fresh. + The call must fail. + """ + # mockup was created already by fixture, try to create it second time: + res = mockup_client.create_mockup( + protocol=protocol.HASH, check=False + ).create_mockup_result + # it should fail: + assert res == CreateMockupResult.ALREADY_INITIALIZED + + +@pytest.mark.client +def test_transfer(mockup_client: Client): + """Executes `tezos-client --base-dir /tmp/mdir -M mockup + transfer 1 from bootstrap1 to bootstrap2` + in a valid mockup environment. + The call must succeed and the balances must be updated correctly. + """ + giver = "bootstrap1" + receiver = "bootstrap2" + transferred = 1.0 + + giver_balance_before = mockup_client.get_balance(giver) + receiver_balance_before = mockup_client.get_balance(receiver) + mockup_client.transfer(transferred, giver, receiver) + giver_balance_after = mockup_client.get_balance(giver) + receiver_balance_after = mockup_client.get_balance(receiver) + + assert giver_balance_after < giver_balance_before - transferred + assert receiver_balance_after == receiver_balance_before + transferred + + +# It's impossible to guess values of chain_id, these ones have been +# obtained by looking at the output of `compute chain id from seed` +@pytest.mark.parametrize( + 'chain_id', + [ + "NetXcqTGZX74DxG", + "NetXaFDF7xZQCpR", + "NetXkKbtqncJcAz", + "NetXjjE5cZUeWPy", + "NetXi7C1pyLhQNe", + ], +) +@pytest.mark.parametrize( + 'initial_timestamp', ["2020-07-21T17:11:10+02:00", "1970-01-01T00:00:00Z"] +) +@pytest.mark.client +def test_create_mockup_custom_constants( + sandbox: Sandbox, chain_id: str, initial_timestamp: str +): + """Tests `tezos-client create mockup` --protocols-constants argument + The call must succeed. + + Args: + mockup_client: the client to use + chain_id (str): the string to pass for field `chain_id` + initial_timestamp(str): an ISO-8601 formatted date string + """ + # Use another directory so that the constants change takes effect + with tempfile.TemporaryDirectory( + prefix='tezos-client.' + ) as base_dir, tempfile.NamedTemporaryFile( + prefix='tezos-custom-constants', mode='w+t' + ) as json_file: + json_data = { + "hard_gas_limit_per_operation": "400000", + "chain_id": chain_id, + "initial_timestamp": initial_timestamp, + } + json.dump(json_data, json_file) + json_file.flush() + unmanaged_client = sandbox.create_client(base_dir=base_dir) + res = unmanaged_client.create_mockup( + protocol=protocol.HASH, protocol_constants_file=json_file.name + ).create_mockup_result + assert res == CreateMockupResult.OK + + +def _create_accounts_list(): + """ + Returns a list of dictionary with 3 entries, that are + valid for being translated to json and passed + to `--bootstrap-accounts` + """ + accounts_list = [] + + def add_account(name: str, sk_uri: str, amount: str): + entry = { + "name": name, + "sk_uri": "unencrypted:" + sk_uri, + "amount": amount, + } + accounts_list.append(entry) + + # Took json structure from + # https://gitlab.com/tezos/tezos/-/merge_requests/1720 + add_account( + "bootstrap0", + "edsk2uqQB9AY4FvioK2YMdfmyMrer5R8mGFyuaLLFfSRo8EoyNdht3", + "2000000000000", + ) + add_account( + "bootstrap1", + "edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh", + "1000000000000", + ) + + return accounts_list + + +@pytest.mark.client +def test_create_mockup_custom_bootstrap_accounts(sandbox: Sandbox): + """Tests `tezos-client create mockup` --bootstrap-accounts argument + The call must succeed. + """ + accounts_list = _create_accounts_list() + + # Use another directory so that the constants change takes effect + with tempfile.TemporaryDirectory( + prefix='tezos-client.' + ) as base_dir, tempfile.NamedTemporaryFile( + prefix='tezos-bootstrap-accounts', mode='w+t' + ) as json_file: + json.dump(accounts_list, json_file) + json_file.flush() + # Follow pattern of mockup_client fixture: + unmanaged_client = sandbox.create_client(base_dir=base_dir) + res = unmanaged_client.create_mockup( + protocol=protocol.HASH, bootstrap_accounts_file=json_file.name + ).create_mockup_result + assert res == CreateMockupResult.OK + mock_client = sandbox.create_client(base_dir=base_dir, mode="mockup") + addresses_result = mock_client.get_known_addresses() + names_sent = sorted([account["name"] for account in accounts_list]) + names_witnessed = sorted(list(addresses_result.wallet.keys())) + assert names_sent == names_witnessed + + +@pytest.mark.client +def test_transfer_bad_base_dir(sandbox: Sandbox): + """Executes `tezos-client --base-dir /tmp/mdir create mockup` + when /tmp/mdir looks like a dubious base directory. + Checks that a warning is printed. + """ + try: + unmanaged_client = sandbox.create_client() + res = unmanaged_client.create_mockup( + protocol=protocol.HASH + ).create_mockup_result + assert res == CreateMockupResult.OK + base_dir = unmanaged_client.base_dir + mockup_dir = os.path.join(base_dir, "mockup") + + # A valid mockup has a directory named "mockup", in its directory: + assert os.path.isdir(mockup_dir) + mock_client = sandbox.create_client(base_dir=base_dir, mode="mockup") + # Delete this directory: + shutil.rmtree(mockup_dir) + # And put a file instead: + Path(os.path.join(mockup_dir)).touch() + + # Now execute a command + cmd = ["transfer", "1", "from", "bootstrap1", "to", "bootstrap2"] + (_, err_output, _) = mock_client.run_generic(cmd, check=False) + # See + # https://gitlab.com/tezos/tezos/-/merge_requests/1760#note_329071488 + # for the content being matched + searched = "Some commands .* might not work correctly." + # Witness that warning is printed: + assert re.search( + searched, err_output + ), f"'{searched}' not matched in error output" + finally: + shutil.rmtree(base_dir) + + +@pytest.mark.client +def test_config_show_mockup(mockup_client: Client): + """Executes `tezos-client --mode mockup config show` in + a state where it should succeed. + """ + mockup_client.run_generic(["--protocol", protocol.HASH, "config", "show"]) + + +@pytest.mark.client +def test_config_show_mockup_fail(mockup_client: Client): + """Executes `tezos-client --mode mockup config show` when + base dir is NOT a mockup. It should fail as this is dangerous + (the default base directory could contain sensitive data, + such as private keys) + """ + shutil.rmtree(mockup_client.base_dir) # See test_config_init_mockup_fail + # for a variant of how to make the base dir invalid for the mockup mode + _, _, return_code = mockup_client.run_generic( + ["config", "show"], check=False + ) + + # recreate directory: the cleanup later on expects its existence + os.mkdir(mockup_client.base_dir) + assert return_code != 0 + + +@pytest.mark.client +def test_config_init_mockup(mockup_client: Client): + """Executes `tezos-client config init mockup` in + a state where it should succeed. + """ + # We cannot use NamedTemporaryFile because `config init mockup` + # does not overwrite files. Because NamedTemporaryFile creates the file + # it would make the test fail. + ba_json_file = tempfile.mktemp(prefix='tezos-bootstrap-accounts') + pc_json_file = tempfile.mktemp(prefix='tezos-proto-consts') + # 1/ call `config init mockup` + mockup_client.run( + [ + "--protocol", + protocol.HASH, + "config", + "init", + f"--{_BA_FLAG}", + ba_json_file, + f"--{_PC_FLAG}", + pc_json_file, + ] + ) + + # 2/ Try loading the files, to check they are valid json + with open(ba_json_file) as handle: + json.load(handle) + with open(pc_json_file) as handle: + json.load(handle) + + # Cleanup + os.remove(ba_json_file) + os.remove(pc_json_file) + + +@pytest.mark.client +def test_config_init_mockup_fail(mockup_client: Client): + """Executes `tezos-client config init mockup` when + base dir is NOT a mockup. It should fail as this is dangerous + (the default base directory could contain sensitive data, + such as private keys) + """ + ba_json_file = tempfile.mktemp(prefix='tezos-bootstrap-accounts') + pc_json_file = tempfile.mktemp(prefix='tezos-proto-consts') + cmd = [ + "--protocol", + protocol.HASH, + "config", + "init", + f"--{_BA_FLAG}", + ba_json_file, + f"--{_PC_FLAG}", + pc_json_file, + ] + + # A valid mockup has a directory named "mockup" in its base_dir: + mockup_dir = os.path.join(mockup_client.base_dir, "mockup") + assert os.path.isdir(mockup_dir) + # Delete this directory, so that the base_dir is not a valid mockup + # base dir anymore: + shutil.rmtree(mockup_dir) # See test_config_show_mockup_fail above + # for a variant of how to make the base_dir invalid for the mockup mode + + _, _, return_code = mockup_client.run_generic(cmd, check=False) + assert return_code != 0 + # Check the test doesn't leak directories: + assert not os.path.exists(ba_json_file) + assert not os.path.exists(pc_json_file) + + +def _try_json_loads(flag: str, string: str) -> Any: + """ Converts the given string to a json object """ + try: + return json.loads(string) + except json.JSONDecodeError: + pytest.fail( + f"""Write back of {flag} value is not valid json: +{string}""" + ) + # Added to get rid of pylint warning inconsistent-return-statements. + # pytest.fail has no return value (NoReturn). + return None + + +def _get_state_using_config_init_mockup( + mock_client: Client, +) -> Tuple[str, str]: + """ + Calls `config init mockup` on a mockup client and returns + the strings of the bootstrap accounts and the protocol + constants + + Note that because this a mockup specific operation, the `mock_client` + parameter must be in mockup mode; do not give a vanilla client. + """ + ba_json_file = tempfile.mktemp(prefix='tezos-bootstrap-accounts') + pc_json_file = tempfile.mktemp(prefix='tezos-proto-consts') + + mock_client.run( + [ + "--protocol", + protocol.HASH, + "config", + "init", + f"--{_BA_FLAG}", + ba_json_file, + f"--{_PC_FLAG}", + pc_json_file, + ] + ) + + with open(ba_json_file) as handle: + ba_str = handle.read() + with open(pc_json_file) as handle: + pc_str = handle.read() + + # Cleanup of tempfile.mktemp + os.remove(ba_json_file) + os.remove(pc_json_file) + + return (ba_str, pc_str) + + +def _get_state_using_config_show_mockup( + mock_client: Client, +) -> Tuple[str, str]: + """ + Calls `--mode mockup config show` on a mockup client and returns + the strings of the bootstrap accounts and the protocol + constants, by parsing standard output. + + Note that because this a mockup specific operation, the `mock_client` + parameter must be in mockup mode; do not give a vanilla client. + """ + + def _find_line_starting_with(strings, searched) -> int: + i = 0 + for string in strings: + if string.startswith(searched): + return i + i += 1 + return -1 + + def _parse_config_init_output(string: str) -> Tuple[str, str]: + """Parses the output of `--mode mockup config init` + and return the json of the bootstrap accounts + and the protocol constants + """ + tagline1 = f"Default value of --{_BA_FLAG}:" + bootstrap_accounts_index = string.find(tagline1) + assert bootstrap_accounts_index >= 0, f"{_BA_FLAG} line not found" + + tagline2 = f"Default value of --{_PC_FLAG}:" + proto_constants_index = string.find(tagline2) + assert proto_constants_index > 0, f"{_PC_FLAG} line not found" + + bc_json = string[ + bootstrap_accounts_index + len(tagline1) : proto_constants_index - 1 + ] + + pc_json = string[proto_constants_index + len(tagline2) + 1 :] + return (bc_json, pc_json) + + stdout = mock_client.run(["--protocol", protocol.HASH, "config", "show"]) + return _parse_config_init_output(stdout) + + +def write_file(filename, contents): + filename.write(contents) + filename.flush() + + +def _gen_assert_msg(flag, sent, received): + return ( + f"Json sent with --{flag} differs from json received" + f"\nJson sent is:\n{sent}" + f"\nwhile json received is:\n{received}" + ) + + +def rm_amounts(bootstrap_accounts): + for account in bootstrap_accounts: + account.pop('amount', None) + + +def compute_expected_amounts( + bootstrap_accounts, frozen_deposits_percentage: int +) -> None: + pct = 100 - frozen_deposits_percentage + for account in bootstrap_accounts: + account['amount'] = str(int(pct * int(account['amount']) / 100)) + + +def _test_create_mockup_init_show_roundtrip( + sandbox: Sandbox, + read_initial_state, + read_final_state, + bootstrap_json: Optional[str] = None, + protocol_constants_json: Optional[str] = None, +): + """1/ Creates a mockup, using possibly custom bootstrap_accounts + (as specified by `bootstrap_json`) + 2/ Then execute either `--mode mockup config show` or + `--mode mockup config init` to obtain the mockup's parameters + (parse stdout if `show` is called, + read the files generated by `init` otherwise) + + This is done by executing `read_initial_state` + 3/ Recreate a mockup using the output gathered in 2/ and call + `--mode mockup config show`/`--mode mockup config init` + (this is done by executing `read_final_state`) to check that output + received is similar to output seen in 2. + + This is a roundtrip test. + """ + + ba_file = None + pc_file = None + + try: + if protocol_constants_json is not None: + pc_file = tempfile.mktemp(prefix='tezos-proto-consts') + with open(pc_file, 'w') as handle: + handle.write(protocol_constants_json) + + if bootstrap_json is not None: + ba_file = tempfile.mktemp(prefix='tezos-bootstrap-accounts') + with open(ba_file, 'w') as handle: + handle.write(bootstrap_json) + + with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: + # Follow pattern of mockup_client fixture: + unmanaged_client = sandbox.create_client(base_dir=base_dir) + res = unmanaged_client.create_mockup( + protocol=protocol.HASH, + bootstrap_accounts_file=ba_file, + protocol_constants_file=pc_file, + ).create_mockup_result + assert res == CreateMockupResult.OK + mock_client = sandbox.create_client( + base_dir=base_dir, mode="mockup" + ) + (ba_str, pc_str) = read_initial_state(mock_client) + finally: + if pc_file is not None: + os.remove(pc_file) + if ba_file is not None: + os.remove(ba_file) + + # 2a/ Check the json obtained is valid by building json objects + ba_sent = _try_json_loads(_BA_FLAG, ba_str) + pc_sent = _try_json_loads(_PC_FLAG, pc_str) + + # Test that the initial mockup call honored the values it received. If + # it didn't, all calls would return the default values all along, and + # everything would seem fine; but it wouldn't be. This was witnessed in + # https://gitlab.com/tezos/tezos/-/issues/938 + if bootstrap_json: + ba_input = json.loads(bootstrap_json) + # adjust amount field on Tenderbake w.r.t. to frozen_deposits_percentage + compute_expected_amounts( + ba_input, int(pc_sent['frozen_deposits_percentage']) + ) + assert ba_sent == ba_input + + if protocol_constants_json: + pc_input = json.loads(protocol_constants_json) + assert pc_sent == pc_input + + # 3/ Pass obtained json to a new mockup instance, to check json + # is valid w.r.t. ocaml encoding + + # Use another directory so that the constants change takes effect + with tempfile.TemporaryDirectory( + prefix='tezos-client.' + ) as base_dir, tempfile.NamedTemporaryFile( + prefix='tezos-bootstrap-accounts', mode='w+t' + ) as ba_json_file, tempfile.NamedTemporaryFile( + prefix='tezos-proto-consts', mode='w+t' + ) as pc_json_file, tempfile.TemporaryDirectory( + prefix='tezos-client.' + ) as base_dir: + + write_file(ba_json_file, ba_str) + write_file(pc_json_file, pc_str) + + with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: + # Follow pattern of mockup_client fixture: + unmanaged_client = sandbox.create_client(base_dir=base_dir) + res = unmanaged_client.create_mockup( + protocol=protocol.HASH, + protocol_constants_file=pc_json_file.name, + bootstrap_accounts_file=ba_json_file.name, + ).create_mockup_result + assert res == CreateMockupResult.OK + mock_client = sandbox.create_client( + base_dir=base_dir, mode="mockup" + ) + # 4/ Retrieve state again + (ba_received_str, pc_received_str) = read_final_state(mock_client) + + # Convert it to json objects (check that json is valid) + ba_received = _try_json_loads(_BA_FLAG, ba_received_str) + pc_received = _try_json_loads(_PC_FLAG, pc_received_str) + + # and finally check that json objects received are the same + # as the ones that were given as input + + # adjust amount field on Tenderbake w.r.t. to frozen_deposits_percentage + compute_expected_amounts( + ba_sent, int(pc_sent['frozen_deposits_percentage']) + ) + + assert ba_sent == ba_received, _gen_assert_msg( + _BA_FLAG, ba_sent, ba_received + ) + assert pc_sent == pc_received, _gen_assert_msg( + _PC_FLAG, pc_sent, pc_received + ) + + +@pytest.mark.client +@pytest.mark.parametrize( + 'initial_bootstrap_accounts', [None, json.dumps(_create_accounts_list())] +) +@pytest.mark.parametrize( + 'protocol_constants', + [ + None, + json.dumps( + { + "initial_timestamp": "2021-02-03T12:34:56Z", + "chain_id": "NetXaFDF7xZQCpR", + "min_proposal_quorum": 501, + "quorum_max": 7001, + "quorum_min": 2001, + "hard_storage_limit_per_operation": "60001", + "cost_per_byte": "251", + "baking_reward_fixed_portion": "20000000", + "baking_reward_bonus_per_slot": "2500", + "endorsing_reward_per_slot": "2857", + "origination_size": 258, + "seed_nonce_revelation_tip": "125001", + "tokens_per_roll": "8000000001", + "proof_of_work_threshold": "-2", + "hard_gas_limit_per_block": "10400001", + "hard_gas_limit_per_operation": "1040001", + 'consensus_committee_size': 12, + # DO NOT EDIT the value consensus_threshold this is actually a + # constant, not a parameter + 'consensus_threshold': 0, + 'delegate_selection': 'random', + 'minimal_participation_ratio': { + 'denominator': 5, + 'numerator': 1, + }, + 'minimal_block_delay': '1', + 'delay_increment_per_round': '1', + 'max_slashing_period': 12, + "blocks_per_voting_period": 65, + "blocks_per_stake_snapshot": 5, + "blocks_per_commitment": 5, + "blocks_per_cycle": 9, + "preserved_cycles": 3, + "liquidity_baking_escape_ema_threshold": 1000000, + "liquidity_baking_subsidy": "2500000", + "liquidity_baking_sunset_level": 1024, + "max_operations_time_to_live": 120, + "frozen_deposits_percentage": 10, + 'ratio_of_frozen_deposits_slashed_per_double_endorsement': { + 'numerator': 1, + 'denominator': 2, + }, + "double_baking_punishment": "640000001", + } + ), + ], +) +@pytest.mark.parametrize( + 'read_initial_state', + [_get_state_using_config_show_mockup, _get_state_using_config_init_mockup], +) +@pytest.mark.parametrize( + 'read_final_state', + [_get_state_using_config_show_mockup, _get_state_using_config_init_mockup], +) +def test_create_mockup_config_show_init_roundtrip( + sandbox: Sandbox, + initial_bootstrap_accounts, + protocol_constants, + read_initial_state, + read_final_state, +): + """1/ Create a mockup, using possibly custom bootstrap_accounts + (as specified by `initial_bootstrap_json`). + 2/ Then execute either `--mode mockup config show` + or `--mode mockup config init` to obtain the mockup's parameters, + as specified by `read_initial_state`. + 3/ Recreate a mockup using the output gathered in 2/ and call + `read_final_state` to check that output + received is similar to output seen in 2. + This is a roundtrip test using a matrix. + """ + _test_create_mockup_init_show_roundtrip( + sandbox, + read_initial_state, + read_final_state, + initial_bootstrap_accounts, + protocol_constants, + ) + + +def test_transfer_rpc(mockup_client: Client): + """Variant of test_transfer that uses RPCs to get the balances.""" + giver = "bootstrap1" + receiver = "bootstrap2" + transferred = 1.0 + transferred_mutz = transferred * 1000000 + + def get_balance(tz1): + res = mockup_client.rpc( + 'get', + f'chains/main/blocks/head/context/contracts/{tz1}/balance', + ) + return float(res) + + addresses = mockup_client.get_known_addresses() + giver_tz1 = addresses.wallet[giver] + recvr_tz1 = addresses.wallet[receiver] + giver_balance_before = get_balance(giver_tz1) + receiver_balance_before = get_balance(recvr_tz1) + mockup_client.transfer(transferred, giver, receiver) + giver_balance_after = get_balance(giver_tz1) + receiver_balance_after = get_balance(recvr_tz1) + + assert giver_balance_after < giver_balance_before - transferred_mutz + assert receiver_balance_after == receiver_balance_before + transferred_mutz + + +@pytest.mark.parametrize( + 'protos', + [ + (proto1, proto2) + for proto1 in [protocol.HASH, protocol.PREV_HASH] + for proto2 in [protocol.HASH, protocol.PREV_HASH, ""] + ], +) +@pytest.mark.parametrize( + 'command', + [ + ["config", "show"], + ["config", "init"], + ["list", "known", "addresses"], + ["get", "balance", "for", "bootstrap1"], + ], +) +def test_proto_mix( + sandbox: Sandbox, protos: Tuple[str, str], command: List[str] +): + """ + This test covers 3 cases: + + 1/ When proto's second element equals the first member: + it tests that the command works. + 2/ When proto's second element is empty: + it tests that the correct mockup implementation is picked + (i.e. the one of the first element) and that the command works. + 3/ When protos' second element is not empty and differs from + the first member: it tests + that creating a mockup with a protocol and using it with another + protocol fails. + """ + proto1 = protos[0] + proto2 = protos[1] + with tempfile.TemporaryDirectory(prefix='tezos-client.') as base_dir: + # Follow pattern of mockup_client fixture: + unmanaged_client = sandbox.create_client(base_dir=base_dir) + res = unmanaged_client.create_mockup(protocol=proto1) + assert res.create_mockup_result == CreateMockupResult.OK + mock_client = sandbox.create_client(base_dir=base_dir, mode="mockup") + cmd = (["--protocol", proto2] if proto2 else []) + command + success = (proto2 == proto1) or (not proto2) + (_, _, return_code) = mock_client.run_generic(cmd, check=False) + assert (return_code == 0) == success diff --git a/tests_python/tests_012/test_multinode_snapshot.py b/tests_python/tests_012/test_multinode_snapshot.py new file mode 100644 index 000000000000..b993886cda0a --- /dev/null +++ b/tests_python/tests_012/test_multinode_snapshot.py @@ -0,0 +1,753 @@ +import tempfile +import shutil +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox +from . import protocol + +PARAMS = constants.NODE_PARAMS + +BATCH_1 = 48 +BATCH_2 = 48 # not enough bakes to drag the savepoint after snapshot import +BATCH_3 = 32 # enough bakes to drag the savepoint +GROUP1 = [0, 1, 2] +GROUP2 = [0, 1, 2, 3, 4, 5] +GROUP_FULL = [1, 3] +GROUP_ROLLING = [2, 4, 5] +SNAPSHOT_DIR = tempfile.mkdtemp(prefix='tezos-snapshots.') +BLOCKS_PER_CYCLE = 8 +PRESERVED_CYCLES = 2 +RETAINED_CYCLES = 8 + + +def clean(node): + shutil.rmtree(node.node_dir) + + +# Restart node. Side effect: clean store caches +def restart(sandbox, node_id): + sandbox.node(node_id).terminate_or_kill() + sandbox.node(node_id).run() + assert sandbox.client(node_id).check_node_listening() + + +@pytest.mark.multinode +@pytest.mark.incremental +@pytest.mark.snapshot +@pytest.mark.slow +class TestMultiNodeSnapshot: + # Tests both the snapshot mechanism and the store's behaviour + # TL;DR, how it works: + # - bake few blocks using all history modes + # - export all kinds of snapshots + # - import all kinds of snapshots + # - check consistency (the snapshot's window includes genesis) + # - bake a few blocks + # - check consistency (the checkpoints should not move yet) + # - bake a few blocks + # - check consistency (the checkpoints should have moved) + # - export all kinds of snapshots + # - import all kinds of snapshots + # - check consistency (checkpoints should be still valid) + # - bake a few blocks + # - check consistency (the checkpoints should have moved) + + def test_init(self, sandbox: Sandbox): + # Node 0: archive baker + sandbox.add_node(0, params=PARAMS + ['--history-mode', 'archive']) + # Node 1: full + sandbox.add_node(1, params=PARAMS + ['--history-mode', 'full']) + # Node 2: rolling + sandbox.add_node(2, params=PARAMS + ['--history-mode', 'rolling']) + protocol.activate(sandbox.client(GROUP1[0]), activate_in_the_past=True) + + def test_bake_batch_1(self, sandbox, session): + for _ in range(BATCH_1): + utils.bake(sandbox.client(0)) + sandbox.client(0).run(['endorse', "for", 'bootstrap2', '--force']) + session['head_hash'] = sandbox.client(0).get_head()['hash'] + session['head_level'] = sandbox.client(0).get_head()['header']['level'] + session['snapshot_level'] = session['head_level'] + + def test_group1_batch_1(self, sandbox, session): + for i in GROUP1: + assert utils.check_level(sandbox.client(i), session['head_level']) + + ########################################################################### + # Export all kinds of snapshots + def test_archive_export_full_1(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node0_batch_1.full' + export_level = session['snapshot_level'] + sandbox.node(0).snapshot_export( + file, params=['--block', f'{export_level}'] + ) + + def test_archive_export_rolling_1(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node0_batch_1.rolling' + export_level = session['snapshot_level'] + sandbox.node(0).snapshot_export( + file, params=['--block', f'{export_level}', '--rolling'] + ) + + def test_full_export_full_1(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node1_batch_1.full' + export_level = session['snapshot_level'] + sandbox.node(1).snapshot_export( + file, params=['--block', f'{export_level}'] + ) + + def test_full_export_rolling_1(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node1_batch_1.rolling' + export_level = session['snapshot_level'] + sandbox.node(1).snapshot_export( + file, params=['--block', f'{export_level}', '--rolling'] + ) + + def test_rolling_export_rolling_1(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node2_batch_1.rolling' + export_level = session['snapshot_level'] + sandbox.node(2).snapshot_export( + file, params=['--block', f'{export_level}', '--rolling'] + ) + + ########################################################################### + # Import all kinds of snapshots + # New node: 3 + def test_run_full_node_from_archive_1(self, sandbox): + file = f'{SNAPSHOT_DIR}/node0_batch_1.full' + sandbox.add_node(3, snapshot=file, params=PARAMS) + + # New node: 4 + def test_run_rolling_node_from_archive_1(self, sandbox): + file = f'{SNAPSHOT_DIR}/node0_batch_1.rolling' + sandbox.add_node(4, snapshot=file, params=PARAMS) + + # Reset node 1 + def test_reset_full_node_from_full_1(self, sandbox): + file = f'{SNAPSHOT_DIR}/node1_batch_1.full' + sandbox.rm_node(1) + sandbox.add_node(1, snapshot=file, params=PARAMS) + + # New node: 5 + def test_run_rolling_node_from_full_1(self, sandbox): + file = f'{SNAPSHOT_DIR}/node1_batch_1.rolling' + sandbox.add_node(5, snapshot=file, params=PARAMS) + + # Reset node 2 + def test_reset_rolling_node_from_rolling_1(self, sandbox): + file = f'{SNAPSHOT_DIR}/node2_batch_1.rolling' + sandbox.rm_node(2) + sandbox.add_node(2, snapshot=file, params=PARAMS) + + ########################################################################### + # Check consistency of imported snapshots + # Do not factorize calls to ease debugging + # For the full nodes + def test_node_1_consistency_1(self, sandbox, session): + node_id = 1 + restart(sandbox, node_id) + expected_level = session['snapshot_level'] + expected_checkpoint = expected_level + expected_savepoint = expected_checkpoint + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.full_node_blocks_availability( + node_id, sandbox, expected_savepoint, expected_level + ) + + def test_node_3_consistency_1(self, sandbox, session): + node_id = 3 + restart(sandbox, node_id) + expected_level = session['snapshot_level'] + expected_checkpoint = expected_level + expected_savepoint = expected_checkpoint + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.full_node_blocks_availability( + node_id, sandbox, expected_savepoint, expected_level + ) + + # For the rolling nodes + def test_node_2_consistency_1(self, sandbox, session): + node_id = 2 + restart(sandbox, node_id) + expected_level = session['snapshot_level'] + expected_checkpoint = expected_level + expected_savepoint = expected_checkpoint + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + def test_node_4_consistency_1(self, sandbox, session): + node_id = 4 + restart(sandbox, node_id) + expected_level = session['snapshot_level'] + expected_checkpoint = expected_level + expected_savepoint = expected_checkpoint + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + def test_node_5_consistency_1(self, sandbox, session): + node_id = 5 + restart(sandbox, node_id) + expected_level = session['snapshot_level'] + expected_checkpoint = expected_level + expected_savepoint = expected_checkpoint + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + ########################################################################### + # Bake a few blocks + def test_bake_batch_2(self, sandbox, session): + for _ in range(BATCH_2): + utils.bake(sandbox.client(0)) + sandbox.client(0).run(['endorse', 'for', 'bootstrap2', '--force']) + session['head_hash'] = sandbox.client(0).get_head()['hash'] + session['head_level'] = sandbox.client(0).get_head()['header']['level'] + for i in GROUP2: + assert utils.check_level(sandbox.client(i), session['head_level']) + + ########################################################################### + # Check consistency of imported snapshots after > 5 baked cycles + # The savepoints of full and rolling nodes **have not** been dragged yet + + # For the full nodes + def test_node_1_consistency_2(self, sandbox, session): + node_id = 1 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + savepoint_when_imported = session['snapshot_level'] + expected_savepoint = savepoint_when_imported + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.full_node_blocks_availability( + node_id, sandbox, expected_savepoint, expected_level + ) + + def test_node_3_consistency_2(self, sandbox, session): + node_id = 3 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + savepoint_when_imported = session['snapshot_level'] + expected_savepoint = savepoint_when_imported + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.full_node_blocks_availability( + node_id, sandbox, expected_savepoint, expected_level + ) + + # For the rolling nodes + # The caboose of rolling mode were no dragged yet as + # (checkpoint - max_op_ttl(head)) < savepoint + def test_node_2_consistency_2(self, sandbox, session): + node_id = 2 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + savepoint_when_imported = session['snapshot_level'] + expected_savepoint = savepoint_when_imported + head = sandbox.client(node_id).get_head() + max_op_ttl = head['metadata']['max_operations_ttl'] + expected_caboose = max(expected_checkpoint - max_op_ttl, 0) + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + def test_node_4_consistency_2(self, sandbox, session): + node_id = 4 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + savepoint_when_imported = session['snapshot_level'] + expected_savepoint = savepoint_when_imported + head = sandbox.client(node_id).get_head() + max_op_ttl = head['metadata']['max_operations_ttl'] + expected_caboose = max(expected_checkpoint - max_op_ttl, 0) + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + def test_node_5_consistency_2(self, sandbox, session): + node_id = 5 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + savepoint_when_imported = session['snapshot_level'] + expected_savepoint = savepoint_when_imported + head = sandbox.client(node_id).get_head() + max_op_ttl = head['metadata']['max_operations_ttl'] + expected_caboose = max(expected_checkpoint - max_op_ttl, 0) + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + ########################################################################### + # Bake a few blocks + def test_bake_batch_3(self, sandbox, session): + for _ in range(BATCH_3): + utils.bake(sandbox.client(0)) + sandbox.client(0).run(['endorse', 'for', 'bootstrap2', '--force']) + session['head_hash'] = sandbox.client(0).get_head()['hash'] + session['head_level'] = sandbox.client(0).get_head()['header']['level'] + session['snapshot_level'] = session['head_level'] + for i in GROUP2: + assert utils.check_level(sandbox.client(i), session['head_level']) + + ########################################################################### + # Check consistency of imported snapshots after > 5 baked cycles + # The savepoints of full and rolling nodes **have** been dragged yet + + # For the full nodes + def test_node_1_consistency_3(self, sandbox, session): + node_id = 1 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + expected_savepoint = expected_checkpoint - ( + RETAINED_CYCLES * BLOCKS_PER_CYCLE + ) + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.full_node_blocks_availability( + node_id, sandbox, expected_savepoint, expected_level + ) + + def test_node_3_consistency_3(self, sandbox, session): + node_id = 3 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + expected_savepoint = expected_checkpoint - ( + RETAINED_CYCLES * BLOCKS_PER_CYCLE + ) + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.full_node_blocks_availability( + node_id, sandbox, expected_savepoint, expected_level + ) + + # For the rolling nodes + def test_node_2_consistency_3(self, sandbox, session): + node_id = 2 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + head = sandbox.client(node_id).get_head() + max_op_ttl = head['metadata']['max_operations_ttl'] + expected_savepoint = expected_checkpoint - ( + RETAINED_CYCLES * BLOCKS_PER_CYCLE + ) + expected_caboose = max(expected_checkpoint - max_op_ttl, 0) + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + def test_node_4_consistency_3(self, sandbox, session): + node_id = 4 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + head = sandbox.client(node_id).get_head() + max_op_ttl = head['metadata']['max_operations_ttl'] + expected_savepoint = expected_checkpoint - ( + RETAINED_CYCLES * BLOCKS_PER_CYCLE + ) + expected_caboose = max(expected_checkpoint - max_op_ttl, 0) + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + def test_node_5_consistency_3(self, sandbox, session): + node_id = 5 + restart(sandbox, node_id) + expected_level = session['head_level'] + # last allowed fork level of the head + expected_checkpoint = ( + expected_level - PRESERVED_CYCLES * BLOCKS_PER_CYCLE + ) + head = sandbox.client(node_id).get_head() + max_op_ttl = head['metadata']['max_operations_ttl'] + expected_savepoint = expected_checkpoint - ( + RETAINED_CYCLES * BLOCKS_PER_CYCLE + ) + expected_caboose = max(expected_checkpoint - max_op_ttl, 0) + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + ########################################################################### + # Re-export all kinds of snapshots + def test_archive_export_full_2(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node0_batch_3.full' + export_level = session['snapshot_level'] + sandbox.node(0).snapshot_export( + file, params=['--block', f'{export_level}'] + ) + + def test_archive_export_rolling_2(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node0_batch_3.rolling' + export_level = session['snapshot_level'] + sandbox.node(0).snapshot_export( + file, params=['--block', f'{export_level}', '--rolling'] + ) + + def test_full_export_full_2(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node1_batch_3.full' + export_level = session['snapshot_level'] + sandbox.node(1).snapshot_export( + file, params=['--block', f'{export_level}'] + ) + + def test_full_export_rolling_2(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node1_batch_3.rolling' + export_level = session['snapshot_level'] + sandbox.node(1).snapshot_export( + file, params=['--block', f'{export_level}', '--rolling'] + ) + + def test_rolling_export_rolling_2(self, sandbox, session): + file = f'{SNAPSHOT_DIR}/node2_batch_3.rolling' + export_level = session['snapshot_level'] + sandbox.node(2).snapshot_export( + file, params=['--block', f'{export_level}', '--rolling'] + ) + + ########################################################################### + # Import all kinds of snapshots + # Reset node: 3 + def test_run_full_node_from_archive_2(self, sandbox): + file = f'{SNAPSHOT_DIR}/node0_batch_3.full' + sandbox.rm_node(3) + sandbox.add_node(3, snapshot=file, params=PARAMS) + + # Reset node: 4 + def test_run_rolling_node_from_archive_2(self, sandbox): + file = f'{SNAPSHOT_DIR}/node0_batch_3.rolling' + sandbox.rm_node(4) + sandbox.add_node(4, snapshot=file, params=PARAMS) + + # Reset node 1 + def test_reset_full_node_from_full_2(self, sandbox): + file = f'{SNAPSHOT_DIR}/node1_batch_3.full' + sandbox.rm_node(1) + sandbox.add_node(1, snapshot=file, params=PARAMS) + + # Reset node: 5 + def test_run_rolling_node_from_full_2(self, sandbox): + file = f'{SNAPSHOT_DIR}/node1_batch_3.rolling' + sandbox.rm_node(5) + sandbox.add_node(5, snapshot=file, params=PARAMS) + + # Reset node 2 + def test_reset_rolling_node_from_rolling_2(self, sandbox): + file = f'{SNAPSHOT_DIR}/node2_batch_3.rolling' + sandbox.rm_node(2) + sandbox.add_node(2, snapshot=file, params=PARAMS) + + ########################################################################### + # Check consistency of imported snapshots with > 5 cycles + + # For the full nodes + def test_node_1_consistency_4(self, sandbox, session): + node_id = 1 + restart(sandbox, node_id) + expected_level = session['head_level'] + expected_checkpoint = expected_level + expected_savepoint = expected_checkpoint + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.full_node_blocks_availability( + node_id, sandbox, expected_savepoint, expected_level + ) + + def test_node_3_consistency_4(self, sandbox, session): + node_id = 3 + restart(sandbox, node_id) + expected_level = session['head_level'] + expected_checkpoint = expected_level + expected_savepoint = expected_checkpoint + expected_caboose = 0 + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.full_node_blocks_availability( + node_id, sandbox, expected_savepoint, expected_level + ) + + # For the rolling nodes + def test_node_2_consistency_4(self, sandbox, session): + node_id = 2 + restart(sandbox, node_id) + expected_level = session['head_level'] + expected_checkpoint = expected_level + head = sandbox.client(node_id).get_head() + max_op_ttl = head['metadata']['max_operations_ttl'] + expected_savepoint = expected_checkpoint + expected_caboose = expected_checkpoint - max_op_ttl + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + def test_node_4_consistency_4(self, sandbox, session): + node_id = 4 + restart(sandbox, node_id) + expected_level = session['head_level'] + expected_checkpoint = expected_level + head = sandbox.client(node_id).get_head() + max_op_ttl = head['metadata']['max_operations_ttl'] + expected_savepoint = expected_checkpoint + expected_caboose = expected_checkpoint - max_op_ttl + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + def test_node_5_consistency_4(self, sandbox, session): + node_id = 5 + restart(sandbox, node_id) + expected_level = session['head_level'] + expected_checkpoint = expected_level + head = sandbox.client(node_id).get_head() + max_op_ttl = head['metadata']['max_operations_ttl'] + expected_savepoint = expected_checkpoint + expected_caboose = expected_checkpoint - max_op_ttl + utils.node_consistency_after_import( + node_id, + sandbox, + expected_level, + expected_checkpoint, + expected_savepoint, + expected_caboose, + ) + utils.rolling_node_blocks_availability( + node_id, + sandbox, + expected_savepoint, + expected_caboose, + expected_level, + ) + + ########################################################################### + # Clean exported snapshots + + def test_clean_files(self): + shutil.rmtree(SNAPSHOT_DIR) diff --git a/tests_python/tests_012/test_multinode_storage_reconstruction.py b/tests_python/tests_012/test_multinode_storage_reconstruction.py new file mode 100644 index 000000000000..e3dcea034a18 --- /dev/null +++ b/tests_python/tests_012/test_multinode_storage_reconstruction.py @@ -0,0 +1,180 @@ +import pytest +from tools import utils +from launchers.sandbox import Sandbox +from . import protocol + +PARAMS = ['--bootstrap-threshold', '0'] +# 2*cycle_size - (protocol_activation) +CEMENTED_LIMIT = 2 * 8 - 1 +# The whole store is cemented +BATCH_1 = 48 +# 2 cycles are pruned in full 5 mode +# This constant is above MAX_OP_TTL +BATCH_2 = 144 + +SNAPSHOT_1 = f'snapshot_block_{BATCH_1}.full' +SNAPSHOT_2 = f'snapshot_block_{BATCH_2}.full' + + +def clear_cache(sandbox, node_id): + # Restart node to clear the store's cache + sandbox.node(node_id).terminate_or_kill() + sandbox.node(node_id).run() + assert sandbox.client(node_id).check_node_listening() + + +@pytest.mark.multinode +@pytest.mark.incremental +@pytest.mark.snapshot +@pytest.mark.slow +class TestMultiNodeStorageReconstruction: + def test_init(self, sandbox: Sandbox): + sandbox.add_node(0, params=PARAMS) + parameters = protocol.get_parameters() + parameters['consensus_threshold'] = 0 + protocol.activate( + sandbox.client(0), parameters=parameters, activate_in_the_past=True + ) + # Keep node 3 in the dance + # History mode by default (full) + sandbox.add_node(3, params=PARAMS) + + # Node 0 bakes a few blocks + def test_bake_node0_level_a(self, sandbox: Sandbox, session: dict): + for _ in range(BATCH_1): + utils.bake(sandbox.client(0)) + session['head_hash'] = sandbox.client(0).get_head()['hash'] + session['head_level'] = sandbox.client(0).get_head()['header']['level'] + + # Node 3 tries to reconstruct its storage after the first batch. + # Reconstruct is expected to fail: nothing to reconstruct + def test_reconstruct_on_bootstrapped_node(self, sandbox: Sandbox): + # Stop, reconstruct the storage and restart the node + sandbox.node(3).terminate_or_kill() + pattern = 'nothing to reconstruct.' + with utils.assert_run_failure(pattern): + sandbox.node(3).reconstruct() + sandbox.node(3).run() + assert sandbox.client(3).check_node_listening() + + # Node 0 exports a snapshot + def test_export_snapshot_batch1(self, sandbox: Sandbox, session: dict): + node_export = sandbox.node(0) + session['snapshot_1_head_hash'] = session['head_hash'] + session['snapshot_1_head_level'] = session['head_level'] + file = f'{sandbox.node(0).node_dir}/{SNAPSHOT_1}' + export_level = session['head_level'] + assert export_level == (BATCH_1 + 1) + node_export.snapshot_export(file, params=['--block', f'{export_level}']) + + # Node 1 import and reconstruct (using the `--reconstruct` + # flag of the `snapshot import` command) + def test_node1_import_and_reconstruct( + self, sandbox: Sandbox, session: dict + ): + n0_tmpdir = sandbox.node(0).node_dir + file = f'{n0_tmpdir}/{SNAPSHOT_1}' + sandbox.add_node( + 1, + snapshot=file, + reconstruct=True, + params=PARAMS + ['--history-mode', 'archive'], + ) + assert utils.check_level(sandbox.client(1), session['head_level']) + clear_cache(sandbox, 1) + + # Test that all the reconstructed blocks can be requested + # with their metadata + def test_node1_request_all_blocks_with_metadata( + self, sandbox: Sandbox, session: dict + ): + for i in range(session['head_level']): + assert utils.get_block_at_level(sandbox.client(1), i) + + # Node 2 import and then reconstruct using the dedicated command. + def test_import_before_reconstruct(self, sandbox: Sandbox, session: dict): + n0_tmpdir = sandbox.node(0).node_dir + file = f'{n0_tmpdir}/{SNAPSHOT_1}' + sandbox.add_node(2, snapshot=file) + assert utils.check_level(sandbox.client(2), session['head_level']) + + # Checking node's 2 storage + def test_unavailable_blocks_node2(self, sandbox: Sandbox, session: dict): + # We must fail while requesting those pruned blocks + for i in range(1, session['snapshot_1_head_level'] - 1): + utils.get_block_metadata_at_level( + sandbox.client(2), i, expect_failure=True + ) + + # Call the reconstruct command on Node 2 + def test_reconstruct_after_snapshot_import(self, sandbox: Sandbox): + # Stop, reconstruct the storage and restart the node + sandbox.node(2).terminate_or_kill() + sandbox.node(2).reconstruct() + sandbox.node(2).run() + assert sandbox.client(2).check_node_listening() + + # Test that all the reconstructed blocks can be requested + # with their metadata + def test_available_blocks_node_2(self, sandbox: Sandbox, session: dict): + # We should now success requesting those reconstructed blocks + for i in range(session['head_level']): + assert utils.get_block_at_level(sandbox.client(2), i) + + # Second batch + + # Bake a few blocks + def test_bake_node0_level_b(self, sandbox: Sandbox, session: dict): + for _ in range(BATCH_2 - BATCH_1): + utils.bake(sandbox.client(0)) + session['head_hash'] = sandbox.client(0).get_head()['hash'] + session['head_level'] = sandbox.client(0).get_head()['header']['level'] + assert utils.check_level(sandbox.client(0), session['head_level']) + assert utils.check_level(sandbox.client(1), session['head_level']) + assert utils.check_level(sandbox.client(2), session['head_level']) + + # Node 0 exports a snapshot (with no floating to reconstruct) + def test_export_snapshot_batch2(self, sandbox: Sandbox, session: dict): + node_export = sandbox.node(0) + # to export on a cemented cycle + export_block_level = 64 + export_block = utils.get_block_at_level( + sandbox.client(0), export_block_level + ) + export_block_hash = export_block['hash'] + session['snapshot_2_head_hash'] = export_block_hash + session['snapshot_2_head_level'] = export_block_level + file = f'{sandbox.node(0).node_dir}/{SNAPSHOT_2}' + node_export.snapshot_export( + file, params=['--block', f'{export_block_level}'] + ) + + # Check that node 3 (full bootstrapped) can be reconstructed + def test_sync_node3(self, sandbox: Sandbox, session: dict): + assert utils.check_level(sandbox.client(3), session['head_level']) + clear_cache(sandbox, 3) + + # Checking node's 3 storage + def test_unavailable_blocks_node3(self, sandbox: Sandbox): + savepoint = int(sandbox.client(3).get_savepoint()) + assert utils.get_block_at_level(sandbox.client(3), savepoint) + # We must fail while requesting blocks before savepoint + for i in range(1, savepoint): + utils.get_block_metadata_at_level( + sandbox.client(3), i, expect_failure=True + ) + + def test_reconstruct_command_after_bootstrap(self, sandbox: Sandbox): + # Stop, reconstruct the storage and restart the node + sandbox.node(3).terminate_or_kill() + sandbox.node(3).reconstruct() + # History mode is now archive + sandbox.node(3).run() + assert sandbox.client(3).check_node_listening() + + def test_available_blocks_node3(self, sandbox: Sandbox, session: dict): + assert sandbox.client(3).get_savepoint() == 0 + assert sandbox.client(3).get_caboose() == 0 + # We should now success requesting those reconstructed blocks + for i in range(session['head_level']): + assert utils.get_block_at_level(sandbox.client(3), i) diff --git a/tests_python/tests_012/test_multiple_transfers.py b/tests_python/tests_012/test_multiple_transfers.py new file mode 100644 index 000000000000..468147f64c20 --- /dev/null +++ b/tests_python/tests_012/test_multiple_transfers.py @@ -0,0 +1,133 @@ +"""Test the multiple transfer feature of tezos-client""" +import os +import json +import pytest + +from client.client import Client +from tools import utils +from tools.constants import IDENTITIES +from .contract_paths import CONTRACT_PATH + + +def manager(client: Client) -> str: + """Originate and return the alias of a manager contract""" + alias = 'manager' + path = os.path.join(CONTRACT_PATH, 'entrypoints', alias + '.tz') + pubkey = IDENTITIES['bootstrap2']['identity'] + utils.init_with_transfer( + client, path, f'"{pubkey}"', 1000, sender='bootstrap1' + ) + return alias + + +@pytest.fixture(scope="class") +def big_map_entrypoints(client: Client) -> str: + """Originate and return the alias of a big_map_entrypoints contract""" + alias = 'big_map_entrypoints' + path = os.path.join(CONTRACT_PATH, 'entrypoints', alias + '.tz') + utils.init_with_transfer( + client, path, 'Pair {} {Elt "Hello" 42}', 1000, sender='bootstrap1' + ) + return alias + + +@pytest.fixture +def source(client: Client, request) -> str: + """A contract alias that will be used as source for a multiple transfers + command. + + This fixture is indirectly instantiated: the argument specifies + whether the alias of an originated manager contract should be + returned (if argument equals 'manager'). Otherwise, the alias is + assumed to already exist in the client's wallet and is returned + unmodified. + """ + alias = request.param + return manager(client) if alias == 'manager' else alias + + +@pytest.mark.contract +@pytest.mark.incremental +class TestMultipleTransfers: + def test_empty(self, client: Client): + with utils.assert_run_failure(r'Empty operation list'): + json_obj = '[]' + client.run(client.cmd_batch('bootstrap1', json_obj)) + + @pytest.mark.parametrize( + "payer, source", + [('bootstrap2', 'manager'), ('bootstrap4', 'bootstrap4')], + indirect=["source"], + ) + def test_transfer_json_to_entrypoint_with_args( + self, big_map_entrypoints: str, client: Client, payer: str, source: str + ): + """Test the multiple transfers command with a single transfer + to a contract's entrypoint, with implicit accounts or a manager + contract as source as per parametrization. + """ + balance_source = client.get_mutez_balance(source) + balance_payer = client.get_mutez_balance(payer) + fee = 0.0123 + fee_mutez = utils.mutez_of_tez(fee) + json_obj = [ + { + "destination": big_map_entrypoints, + "amount": "0", + "fee": str(fee), + "gas-limit": "65942", + "storage-limit": "1024", + "arg": '"Hello"', + "entrypoint": "mem_right", + } + ] + json_ops = json.dumps(json_obj, separators=(',', ':')) + client.run(client.cmd_batch(source, json_ops)) + utils.bake(client, 'bootstrap5') + new_balance_source = client.get_mutez_balance(source) + new_balance_payer = client.get_mutez_balance(payer) + + if payer != source: + assert balance_source == new_balance_source + + assert balance_payer - fee_mutez == new_balance_payer + + @pytest.mark.parametrize( + "payer, source", + [('bootstrap2', 'manager'), ('bootstrap4', 'bootstrap4')], + ) + def test_multiple_transfers(self, client: Client, payer: str, source: str): + """Test a multiple transfers to implicit accounts, with implicit + accounts or a manager contract as source as per parametrization. + """ + balance_source = client.get_mutez_balance(source) + balance_bootstrap1 = client.get_mutez_balance('bootstrap1') + balance_bootstrap3 = client.get_mutez_balance('bootstrap3') + amount_1 = 10.1 + amount_mutez_1 = utils.mutez_of_tez(amount_1) + amount_3 = 11.01 + amount_mutez_3 = utils.mutez_of_tez(amount_3) + json_obj = [ + {"destination": "bootstrap1", "amount": str(amount_1)}, + {"destination": "bootstrap3", "amount": str(amount_3)}, + ] + json_ops = json.dumps(json_obj, separators=(',', ':')) + client.run(client.cmd_batch(source, json_ops)) + utils.bake(client, 'bootstrap5') + new_balance_source = client.get_mutez_balance(source) + new_balance_bootstrap1 = client.get_mutez_balance('bootstrap1') + new_balance_bootstrap3 = client.get_mutez_balance('bootstrap3') + + if payer == source: + fee_first_transfer = 404 + fee_second_transfer = 308 + source_fee_mutez = fee_first_transfer + fee_second_transfer + else: + source_fee_mutez = 0 + + assert ( + balance_source - amount_mutez_1 - amount_mutez_3 - source_fee_mutez + == new_balance_source + ) + assert balance_bootstrap1 + amount_mutez_1 == new_balance_bootstrap1 + assert balance_bootstrap3 + amount_mutez_3 == new_balance_bootstrap3 diff --git a/tests_python/tests_012/test_multisig.py b/tests_python/tests_012/test_multisig.py new file mode 100644 index 000000000000..06108327a82c --- /dev/null +++ b/tests_python/tests_012/test_multisig.py @@ -0,0 +1,620 @@ +# tezos-client has builtin support for multisig smart contracts. See +# docs/user/multisig.rst for more details about it. + +# This file tests the client multisig support; more precisely it tests +# that both the generic and the legacy versions of the multisig smart +# contract behave as intended. For all commands, we check that we can +# interact with the multisig contract when invoking it by its address +# or by its alias. + +import os +import re +from typing import List +import pytest +from tools import utils, constants +from client.client import Client +from .contract_paths import MINI_SCENARIOS_CONTRACT_PATH, ATTIC_CONTRACT_PATH + + +def get_keys(client): + """Generate 3 pairs of keys using various schemes and return the list + of aliases.""" + keys = ['foo', 'bar', 'boo'] + sigs = [None, 'secp256k1', 'ed25519'] + for key, sig in zip(keys, sigs): + args = [] if sig is None else ['--sig', sig] + client.gen_key(key, args) + return keys + + +@pytest.fixture(scope="class") +def keys(client): + return get_keys(client) + + +def msig_path(msig_version: str) -> str: + return os.path.join( + MINI_SCENARIOS_CONTRACT_PATH, f'{msig_version}_multisig.tz' + ) + + +MSIG_PARAMS = [ + {'by_address': by_address, 'msig_version': msig_version} + for msig_version in ['generic', 'legacy'] + for by_address in [True, False] +] + + +def parse_msig_storage(storage: str): + """Parse the storage of a multisig contract to get its counter (as a + number), threshold (as a number), and the keys of the signers (as + Micheline sequence in a string).""" + # put everything on a single line + storage = ' '.join(storage.split('\n')) + storage_regexp = r'Pair\s+?([0-9]+)\s+?([0-9]+)\s+?(.*)\s*' + match = re.search(storage_regexp, storage) + assert match is not None + return { + 'counter': int(match[1]), + 'threshold': int(match[2]), + 'keys': match[3], + } + + +def resolve_key_alias(client: Client, alias: str) -> str: + """Convert a key alias into a public key that can be understood in + Michelson.""" + ret = client.show_address(alias).public_key + assert ret is not None + return ret + + +def build_michelson_key_list(client: Client, keys: List[str]): + """From a list of key aliases, build a Michelson list of public keys.""" + keys = [resolve_key_alias(client, k) for k in keys] + return '{"' + '"; "'.join(keys) + '"}' + + +def build_msig_storage( + client: Client, counter: int, threshold: int, keys: List[str] +): + """Build a multisig storage from its components: a counter, a + threshold and the list of signer public keys.""" + keys = build_michelson_key_list(client, keys) + return f'Pair {counter} {threshold} {keys}' + + +def assert_michelson_eq(client, data1, data2, typ): + """Check that two Michelson expressions of the same type are equal by + normalizing them.""" + normalized1 = client.normalize(data=data1, typ=typ) + normalized2 = client.normalize(data=data2, typ=typ) + assert normalized1 == normalized2 + + +def assert_msig_storage_eq(client, data1, data2): + """Check that two multisig storages are equal.""" + assert_michelson_eq(client, data1, data2, 'pair nat nat (list key)') + + +def assert_msig_counter_incr(current_storage, new_storage): + """Check that [new_storage] is the same multisig storage than + [current_storage] except that it uses the next counter.""" + current_storage = parse_msig_storage(current_storage) + new_storage = parse_msig_storage(new_storage) + assert new_storage['counter'] == 1 + current_storage['counter'] + assert new_storage['threshold'] == current_storage['threshold'] + assert new_storage['keys'] == current_storage['keys'] + + +@pytest.fixture(scope="class", params=MSIG_PARAMS) +def msig(client: Client, keys, request): + """This fixture originates a multisig contract with a threshold of 2 + and the keys given as parameter. The version of the script is given by + the msig_version parameter, it can be either 'generic' or + 'legacy'. This fixture returns a dictionary containing: + + - a [handle] that can be used to interact with the contract: + either the address of the script or an alias, depending on the + [by_address] parameter + + - the list of [keys] that are stored in the contract which is a + copy of the [keys] parameter + + - the [version], which is a copy of the [msig_version] parameter + + """ + + # We use the same alias for all multisig originations, this makes + # testing simpler but requires using the '--force' option. + msig_alias = 'msig' + msig_version = request.param['msig_version'] + by_address = request.param['by_address'] + initial_storage = build_msig_storage( + client=client, counter=0, threshold=2, keys=keys + ) + deployment = client.originate( + msig_alias, + 100, + 'bootstrap1', + msig_path(msig_version), + # Initialize with empty key list and null threshold + ['--init', initial_storage, '--burn-cap', '100', '--force'], + ) + utils.bake(client) + handle = deployment.contract if by_address else msig_alias + return {'handle': handle, 'keys': keys, 'version': msig_version} + + +@pytest.mark.incremental +class TestMultisig: + def test_deploy_multisig(self, msig, client: Client): + """Test that: + - the script originated by the "deploy multisig" command, + - the generic_multisig.tz script found in the mini_scenarios + directory, and + - the script printed by the "show multisig script" + are the same.""" + keys = msig['keys'] + + # The command cannot originate the legacy contract so there is + # nothing to test in the legacy case. + if msig['version'] == 'generic': + client.deploy_msig( + 'dummy_msig', + 100, + 'bootstrap1', + 2, + keys, + ['--burn-cap', '100', '--force'], + ) + utils.bake(client) + expected_hash = ( + 'exprub9UzpxmhedNQnsv1J1DazWGJnj1dLhtG1fxkUoWSdFLBGLqJ4' + ) + assert expected_hash in client.run( + ['show', 'supported', 'multisig', 'hashes'] + ) + assert client.get_script_hash(msig['handle']) == expected_hash + assert client.get_script_hash('dummy_msig') == expected_hash + assert client.hash_script( + [client.run(['show', 'multisig', 'script'])] + ) == [(expected_hash, None)] + assert client.get_balance('dummy_msig') == 100 + + def test_transfer(self, msig, client: Client, session: dict): + """Test the client command for signing a multisig transfer from key + number 0 and store the signature in the session.""" + keys = msig['keys'] + key = keys[0] + session['sig0'] = client.msig_sign_transfer( + msig['handle'], 10, 'bootstrap2', key + ) + + def test_prepare_msig_transfer(self, msig, client: Client): + """Test the client command for preparing a transfer. The result of the + command is ignored in this test, we only test that the command + succeeds.""" + client.msig_prepare_transfer(msig['handle'], 10, 'bootstrap2') + + def test_prepare_msig_sign(self, msig, client: Client, session: dict): + """Produce signatures for keys number 1 and 2 using the the + preparation command together with the sign_bytes client command. The + signatures are stored in the session.""" + to_sign = client.msig_prepare_transfer( + msig['handle'], 10, 'bootstrap2', ['--bytes-only'] + ) + session['sig1'] = client.sign_bytes_of_string(to_sign, msig['keys'][1]) + session['sig2'] = client.sign_bytes_of_string(to_sign, msig['keys'][2]) + + def test_transfer_failure(self, msig, client: Client, session: dict): + """Test transfer failure when there are too few signatures.""" + error_pattern = ( + r"Not enough signatures: " + + r"only 1 signatures were given " + + r"but the threshold is currently 2" + ) + + with utils.assert_run_failure(error_pattern): + client.msig_transfer( + msig['handle'], + 10, + 'bootstrap2', + 'bootstrap1', + [session['sig2']], + ) + + def test_transfer_success(self, msig, client: Client, session: dict): + """Test a successful transfer using signatures obtained by different + methods. The signatures are taken from the session.""" + current_storage = client.get_storage(msig['handle']) + current_balance = client.get_balance(msig['handle']) + + client.msig_transfer( + msig['handle'], + 10, + 'bootstrap2', + 'bootstrap1', + [session['sig0'], session['sig2']], + ) + utils.bake(client) + new_storage = client.get_storage(msig['handle']) + assert_msig_counter_incr(current_storage, new_storage) + new_balance = client.get_balance(msig['handle']) + assert new_balance == current_balance - 10 + + def test_default_entrypoint(self, msig, client): + """The generic multisig contract features an unauthorized default + entrypoint to receive donations but the legacy one does not.""" + + def cmd(): + client.transfer( + amount=100, giver='bootstrap1', receiver=msig['handle'] + ) + + if msig['version'] == 'legacy': + error_pattern = r'Invalid argument passed to contract' + with utils.assert_run_failure(error_pattern): + cmd() + else: + current_storage = client.get_storage(msig['handle']) + current_balance = client.get_balance(msig['handle']) + cmd() + utils.bake(client) + new_storage = client.get_storage(msig['handle']) + new_balance = client.get_balance(msig['handle']) + assert new_storage == current_storage + assert new_balance == current_balance + 100 + + def test_transfer_with_entrypoint(self, msig, client: Client): + """Both versions of the contract can call arbitrary entrypoints of + type unit. This test uses the two possible methods to produce the + signatures.""" + current_storage = client.get_storage(msig['handle']) + current_balance = client.get_balance(msig['handle']) + contract = ( + 'parameter (or (unit %a) (string %b)); ' + 'storage unit; ' + 'code {CDR; NIL operation; PAIR}' + ) + client.originate( + 'dest_entrypoint', + 0, + 'bootstrap1', + contract, + args=['--burn-cap', '10.0', '--force'], + ) + args = ['--entrypoint', 'a'] + utils.bake(client) + to_sign = client.msig_prepare_transfer( + msig_name=msig['handle'], + amount=10, + dest='dest_entrypoint', + args=args + ['--bytes-only'], + ) + sig0 = client.sign_bytes_of_string(to_sign, msig['keys'][0]) + sig2 = client.msig_sign_transfer( + msig_name=msig['handle'], + amount=10, + dest='dest_entrypoint', + secret_key=msig['keys'][2], + args=args, + ) + client.msig_transfer( + msig_name=msig['handle'], + amount=10, + dest='dest_entrypoint', + src='bootstrap1', + signatures=[sig0, sig2], + args=args, + ) + utils.bake(client) + new_storage = client.get_storage(msig['handle']) + new_balance = client.get_balance(msig['handle']) + assert_msig_counter_incr(current_storage, new_storage) + assert new_balance == current_balance - 10 + + def test_transfer_with_arg(self, msig, client: Client): + """The generic multisig contract can call other contracts with + arbitrary parameters but the legacy one can only send Unit.""" + contract = ( + 'parameter (or (int %a) (string %b)); ' + 'storage unit; ' + 'code {CDR; NIL operation; PAIR}' + ) + client.originate( + 'dest', + 0, + 'bootstrap1', + contract, + args=['--burn-cap', '10.0', '--force'], + ) + args = ['--entrypoint', 'a', '--arg', '42'] + utils.bake(client) + + def cmd(): + return client.msig_prepare_transfer( + msig_name=msig['handle'], + amount=10, + dest='dest', + args=args + ['--bytes-only'], + ) + + if msig['version'] == 'legacy': + error_pattern = ( + r'This multisig contract can only transfer tokens to' + ' contracts of type unit; calling a contract with argument 42' + ' is not supported.' + ) + with utils.assert_run_failure(error_pattern): + cmd() + else: + current_storage = client.get_storage(msig['handle']) + current_balance = client.get_balance(msig['handle']) + to_sign = cmd() + utils.bake(client) + sig0 = client.sign_bytes_of_string(to_sign, msig['keys'][0]) + sig2 = client.msig_sign_transfer( + msig_name=msig['handle'], + amount=10, + dest='dest', + secret_key=msig['keys'][2], + args=args, + ) + client.msig_transfer( + msig_name=msig['handle'], + amount=10, + dest='dest', + src='bootstrap1', + signatures=[sig0, sig2], + args=args, + ) + utils.bake(client) + new_storage = client.get_storage(msig['handle']) + new_balance = client.get_balance(msig['handle']) + assert_msig_counter_incr(current_storage, new_storage) + assert new_balance == current_balance - 10 + + def test_transfer_ill_typed(self, msig, client: Client): + """Test that the multisig transfer preparation command type checks the + parameter.""" + error_pattern = ( + ( + r'The entrypoint b of contract .* ' + 'called from a multisig contract is of type string; ' + 'the provided parameter 42 is ill-typed.' + ) + if msig['version'] == 'generic' + else ( + r'This multisig contract can only transfer tokens to' + ' contracts of type unit; calling a contract with argument 42' + ' is not supported.' + ) + ) + + args = ['--entrypoint', 'b', '--arg', '42'] + + def cmd(): + client.msig_prepare_transfer( + msig_name=msig['handle'], + amount=10, + dest='dest', + args=args + ['--bytes-only'], + ) + + with utils.assert_run_failure(error_pattern): + cmd() + + def test_transfer_too_high(self, msig, client: Client): + """Test that the multisig transfer preparation command checks the + balance.""" + expected_warning = ( + 'Transferred amount is bigger than current multisig balance' + ) + + client.msig_prepare_transfer( + msig_name=msig['handle'], + amount=1000, + dest='bootstrap1', + args=['--bytes-only'], + expected_warning=expected_warning, + ) + + def test_multiple_operations(self, msig, client: Client): + """The generic multisig client can run lambdas, this can be used to + atomically run several operations.""" + bootstrap1_address = constants.IDENTITIES['bootstrap1']['identity'] + bootstrap2_address = constants.IDENTITIES['bootstrap2']['identity'] + bootstrap3_address = constants.IDENTITIES['bootstrap3']['identity'] + lam = ( + '{ DROP; NIL operation; ' + f'PUSH key_hash "{bootstrap1_address}"; IMPLICIT_ACCOUNT; ' + 'PUSH mutez 1000000; UNIT; TRANSFER_TOKENS; CONS; ' + f'PUSH key_hash "{bootstrap2_address}"; IMPLICIT_ACCOUNT; ' + 'PUSH mutez 2000000; UNIT; TRANSFER_TOKENS; CONS; ' + f'PUSH key_hash "{bootstrap3_address}"; SOME; ' + 'SET_DELEGATE; CONS}' + ) + lam = client.normalize( + lam, typ='lambda unit (list operation)', mode='Optimized' + ) + + def cmd(): + return client.msig_prepare_lambda( + msig_name=msig['handle'], lam=lam, args=['--bytes-only'] + ) + + if msig['version'] == 'legacy': + error_pattern = 'This multisig contract has a fixed set of actions' + with utils.assert_run_failure(error_pattern): + cmd() + else: + current_storage = client.get_storage(msig['handle']) + current_balance = client.get_balance(msig['handle']) + to_sign = cmd() + sig0 = client.sign_bytes_of_string(to_sign, msig['keys'][0]) + sig2 = client.msig_sign_lambda( + msig_name=msig['handle'], lam=lam, secret_key=msig['keys'][2] + ) + client.msig_run_lambda( + msig_name=msig['handle'], + lam=lam, + src='bootstrap1', + signatures=[sig0, sig2], + ) + utils.bake(client) + new_storage = client.get_storage(msig['handle']) + new_balance = client.get_balance(msig['handle']) + assert_msig_counter_incr(current_storage, new_storage) + assert new_balance == current_balance - 3 + # TODO: check the delegate change + + def test_multiple_operations_failure(self, msig, client: Client): + """Test for the error message for ill-typed lambdas.""" + lam = '{ DROP }' + + def cmd(): + client.msig_prepare_lambda( + msig_name=msig['handle'], lam=lam, args=['--bytes-only'] + ) + + error_pattern = ( + ( + r'The provided lambda .* for multisig contract' + r' is ill-typed; .* is expected.' + ) + if msig['version'] == 'generic' + else 'This multisig contract has a fixed set of actions' + ) + + with utils.assert_run_failure(error_pattern): + cmd() + + def test_delegate_change(self, msig, client: Client): + """Test the multisig command for changing delegate.""" + current_storage = client.get_storage(msig['handle']) + current_balance = client.get_balance(msig['handle']) + sig0 = client.msig_sign_set_delegate( + msig['handle'], 'bootstrap5', msig['keys'][0] + ) + to_sign = client.msig_prepare_set_delegate( + msig['handle'], 'bootstrap5', ['--bytes-only'] + ) + sig2 = client.sign_bytes_of_string(to_sign, msig['keys'][2]) + client.msig_set_delegate( + msig['handle'], 'bootstrap5', 'bootstrap1', [sig0, sig2] + ) + utils.bake(client) + new_storage = client.get_storage(msig['handle']) + new_balance = client.get_balance(msig['handle']) + assert_msig_counter_incr(current_storage, new_storage) + assert new_balance == current_balance + + def test_delegate_withdraw(self, msig, client: Client): + """Test the multisig command for removing delegation.""" + current_storage = client.get_storage(msig['handle']) + current_balance = client.get_balance(msig['handle']) + sig0 = client.msig_sign_withdrawing_delegate( + msig['handle'], msig['keys'][0] + ) + to_sign = client.msig_prepare_withdrawing_delegate( + msig['handle'], ['--bytes-only'] + ) + + sig1 = client.sign_bytes_of_string(to_sign, msig['keys'][1]) + client.msig_withdrawing_delegate( + msig['handle'], 'bootstrap1', [sig0, sig1] + ) + utils.bake(client) + new_storage = client.get_storage(msig['handle']) + new_balance = client.get_balance(msig['handle']) + assert_msig_counter_incr(current_storage, new_storage) + assert new_balance == current_balance + + def test_run_transaction_change_keys_and_threshold( + self, msig, client: Client + ): + """Test changing the keys and threshold with the `run transaction` + command.""" + current_storage = client.get_storage(msig['handle']) + current_counter = parse_msig_storage(storage=current_storage)['counter'] + current_balance = client.get_balance(msig['handle']) + keys = msig['keys'] + sig0 = client.msig_sign_setting_threshold( + msig['handle'], keys[0], 2, [keys[0], keys[2]] + ) + to_sign = client.msig_prepare_setting_threshold( + msig['handle'], 2, [keys[0], keys[2]], ['--bytes-only'] + ) + sig2 = client.sign_bytes_of_string(to_sign, msig['keys'][2]) + client.msig_run_transaction( + msig['handle'], to_sign, 'bootstrap1', [sig0, sig2] + ) + utils.bake(client) + new_storage = client.get_storage(msig['handle']) + expected_counter = 1 + current_counter + expected_storage = build_msig_storage( + client=client, + counter=expected_counter, + threshold=2, + keys=[keys[0], keys[2]], + ) + assert_msig_storage_eq(client, new_storage, expected_storage) + new_balance = client.get_balance(msig['handle']) + assert new_balance == current_balance + + def test_change_keys_and_threshold(self, msig, client: Client): + """Test changing the keys and threshold with `set threshold of + multisig` command.""" + current_storage = client.get_storage(msig['handle']) + current_counter = parse_msig_storage(storage=current_storage)['counter'] + current_balance = client.get_balance(msig['handle']) + keys = msig['keys'] + new_keys = [keys[0], keys[2]] + sig0 = client.msig_sign_setting_threshold( + msig['handle'], keys[0], 2, new_keys + ) + to_sign = client.msig_prepare_setting_threshold( + msig['handle'], 2, new_keys, ['--bytes-only'] + ) + sig2 = client.sign_bytes_of_string(to_sign, msig['keys'][2]) + client.msig_set_threshold( + msig['handle'], 2, new_keys, 'bootstrap1', [sig0, sig2] + ) + utils.bake(client) + new_storage = client.get_storage(msig['handle']) + expected_counter = 1 + current_counter + expected_storage = build_msig_storage( + client=client, + counter=expected_counter, + threshold=2, + keys=[keys[0], keys[2]], + ) + assert_msig_storage_eq(client, new_storage, expected_storage) + new_balance = client.get_balance(msig['handle']) + assert new_balance == current_balance + + +class TestUnsupportedMultisig: + """Verify that non-multisig contracts are rejected""" + + def test_deploy_nonmultisig(self, client: Client): + contract = os.path.join(ATTIC_CONTRACT_PATH, 'id.tz') + client.originate( + 'id', + 0, + 'bootstrap1', + contract, + args=['--burn-cap', '10.0', '--force', '--init', '""'], + ) + utils.bake(client) + + error_pattern = ( + 'The hash of this script is ' + 'exprv8K6ceBpFH5SFjQm4BRYSLJCHQBFeQU6BFTdvQSRPaPkzdLyAL, ' + 'it was not found among in the list of known multisig ' + 'script hashes.' + ) + + with utils.assert_run_failure(error_pattern): + client.msig_transfer('id', 10, 'bootstrap2', 'bootstrap1', []) diff --git a/tests_python/tests_012/test_nonce_seed_revelation.py b/tests_python/tests_012/test_nonce_seed_revelation.py new file mode 100644 index 000000000000..6a0f8506ac21 --- /dev/null +++ b/tests_python/tests_012/test_nonce_seed_revelation.py @@ -0,0 +1,133 @@ +import time +import pytest +from tools import constants +from launchers.sandbox import Sandbox +from . import protocol + + +BLOCKS_PER_COMMITMENT = protocol.PARAMETERS['blocks_per_commitment'] +BLOCKS_PER_CYCLE = protocol.PARAMETERS['blocks_per_cycle'] +FIRST_PROTOCOL_BLOCK = 1 +TIMEOUT = 60 + +MINIMAL_BLOCK_DELAY = 1 +DELAY_INCREMENT_PER_ROUND = 1 +TEST_DURATION = ( + FIRST_PROTOCOL_BLOCK + 2 * BLOCKS_PER_CYCLE +) * MINIMAL_BLOCK_DELAY +NUM_NODES = 5 + + +@pytest.mark.incremental +@pytest.mark.slow +@pytest.mark.baker +class TestNonceSeedRevelation: + """Test baker injection of nonce revelations. + + See http://tezos.gitlab.io/012_ithaca/proof_of_stake.html + + Runs a node and a baker. The baker bakes two full cycles. + We collect nonce hashes from the first cycle. And check + that they are revealed in the second cycle""" + + def test_init(self, sandbox: Sandbox): + """Run a node and a baker. + + The node runs in archive mode to get metadata in `client.get_block()`. + The protocol is activated in the past so the baker can submit blocks + immediately without waiting for current time.""" + + node_params = constants.NODE_PARAMS + ['--history-mode', 'archive'] + for i in range(NUM_NODES): + sandbox.add_node(i, params=node_params) + + # client setup + parameters = protocol.get_parameters() + parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) + parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) + protocol.activate(sandbox.client(0), parameters=parameters) + + # baker setup + # delegated_accounts = [f'bootstrap{i}' for i in range(1, 6)] + for i in range(NUM_NODES): + sandbox.add_baker( + i, + [f"bootstrap{i + 1}"], + proto=protocol.DAEMON, + log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, + ) + + @pytest.mark.timeout(2 * TEST_DURATION) + def test_wait_for_two_cycles(self, sandbox: Sandbox): + """Poll the node until target level is reached """ + target = FIRST_PROTOCOL_BLOCK + 2 * BLOCKS_PER_CYCLE + level = target - 1 + while level < target: + time.sleep( + 4 * MINIMAL_BLOCK_DELAY + ) # sleep first to avoid useless first query + if sandbox.client(0).get_level() >= target: + break + # No need to bake more + for i in range(NUM_NODES): + sandbox.rm_baker(i, proto=protocol.DAEMON) + + def test_get_all_blocks(self, sandbox: Sandbox, session: dict): + """Retrieve all blocks for two full cycles. """ + blocks = [ + sandbox.client(0).get_block(FIRST_PROTOCOL_BLOCK + i) + for i in range(2 * BLOCKS_PER_CYCLE) + ] + session['blocks'] = blocks + + def test_cycle_alignment(self, session): + """Test cycles start where they are supposed to start. + + Not really needed but helps clarifying cycles positions.""" + + blocks = session['blocks'] + # blocks[0] is considered cycle = 0, cycle_position = 0 for the new + # protocol, but because it is a protocol transition block, it + # doesn't have the "cycle" and "cycle_position" metadata (unlike + # the remaining blocks) + initial_block_level = blocks[1]['metadata']['level_info'] + assert initial_block_level['cycle'] == 0 + assert initial_block_level['cycle_position'] == 1 + final_block_level = blocks[BLOCKS_PER_CYCLE]['metadata']['level_info'] + assert final_block_level['cycle'] == 1 + assert final_block_level['cycle_position'] == 0 + + def test_collect_seed_nonce_hashes(self, session): + """Collect nonce hashes in the block headers in the first cycle """ + seed_nonce_hashes = {} + blocks = session['blocks'] + for i in range(BLOCKS_PER_CYCLE // BLOCKS_PER_COMMITMENT): + level = (i + 1) * BLOCKS_PER_COMMITMENT - 1 + seed_nonce_hash = blocks[level]['header']['seed_nonce_hash'] + seed_nonce_hashes[level] = seed_nonce_hash + session['seed_nonce_hashes'] = seed_nonce_hashes + + def test_check_revelations(self, session): + """Collect reveal ops in second cycle and check they match + the nonce hashes from first cycle.""" + blocks = session['blocks'] + seed_nonce_hashes = session['seed_nonce_hashes'] + ops = [] + # collect all operations + for i in range(BLOCKS_PER_CYCLE, 2 * BLOCKS_PER_CYCLE): + ops.extend(blocks[i]['operations'][2]) + reveal_ops = {} + for operation in ops: + content = operation['contents'][0] + # there should be only revelations there + assert content['kind'] == "seed_nonce_revelation" + level = content['level'] - FIRST_PROTOCOL_BLOCK + # Can't submit twice the same reveal op + assert level not in reveal_ops + # level should match a seed + assert level in seed_nonce_hashes + reveal_ops[level] = content['nonce'] + + # check all nonce hashes have been revealed + assert len(reveal_ops) == len(seed_nonce_hashes) + # we could go a step further and check that revelations are correct diff --git a/tests_python/tests_012/test_openapi.py b/tests_python/tests_012/test_openapi.py new file mode 100644 index 000000000000..9348d2302b31 --- /dev/null +++ b/tests_python/tests_012/test_openapi.py @@ -0,0 +1,73 @@ +""" Tests generating the implementation of openapi/swagger: + https://swagger.io/ + + This script launches a sandbox node, activates folder specific + protocol, gets the RPC descriptions as JSON, and converts this JSON + into an OpenAPI specification. + + This test mimicks src/openapi/generate.sh. +""" + +import json +import subprocess +from pathlib import Path +import requests +import openapi_spec_validator +import pytest + +from launchers.sandbox import Sandbox +from tools.constants import NODE_PARAMS +from . import protocol + + +def _get_tezos_node_version() -> str: + cmd = ["ocaml", "../scripts/print_version.ml"] + process_ret = subprocess.run( + cmd, check=True, capture_output=True, text=True + ) + version = process_ret.stdout.strip() + assert version, "version should not be empty" + return version + + +class TestOpenAPI: + @pytest.fixture(scope="class") + def sandbox(self, sandbox: Sandbox): + sandbox.add_node(0, params=NODE_PARAMS) + client = sandbox.client(0) + protocol.activate(client) + return sandbox + + @pytest.mark.parametrize( + "rpc_path", ["describe", "describe/chains/main/blocks/head/"] + ) + def test_validity(self, sandbox: Sandbox, rpc_path: str, tmp_path: Path): + """ + Mimicks the script src/openapi/generate.sh. Generates the API + and check it generates a valid OpenAPI specification. + """ + node = sandbox.node(0) + addr = f"http://localhost:{node.rpc_port}/{rpc_path}?recurse=yes" + json_path = tmp_path / "result.json" + with open(json_path, "w") as o_file: + json_res = requests.get(addr).json() + json.dump(json_res, o_file) + + # If you need to debug, insert time.sleep(15) in there, + # to give you time to inspect generated files before the + # enclosing 'with' block finishes or to execute the dune + # command manually while the temporary files are still there. + version = _get_tezos_node_version() + cmd = [ + "dune", + "exec", + "../src/bin_openapi/rpc_openapi.exe", + "--", + version, + str(json_path.absolute()), + ] + process_ret = subprocess.run( + cmd, check=True, capture_output=True, text=True + ) + res = json.loads(process_ret.stdout) + openapi_spec_validator.validate_spec(res) diff --git a/tests_python/tests_012/test_p2p.py b/tests_python/tests_012/test_p2p.py new file mode 100644 index 000000000000..f4d54953ce5b --- /dev/null +++ b/tests_python/tests_012/test_p2p.py @@ -0,0 +1,147 @@ +import time +import pytest +from tools import constants +from launchers.sandbox import Sandbox + + +NUM_NODES = 5 +NUM_RETRIES = 20 # empirical values for testing a liveness property +POLLING_TIME = 10 # NUM_RETRY * POLLING_TIME = 200s, should be conservative + + +@pytest.mark.multinode +@pytest.mark.incremental +class TestTrustedRing: + """This test sets up a network of public peers (running the default + p2p protocol), with no initial bootstrap peers. It initializes a + trusted ring relationship, and checks that points are advertised + correctly to the whole network.""" + + def test_init(self, sandbox: Sandbox): + for i in range(NUM_NODES): + sandbox.add_node( + i, + private=False, + peers=[], + params=constants.NODE_PARAMS, + config_client=False, + ) + + def test_no_peers(self, sandbox: Sandbox): + """ Initially, nobody knows other peers. """ + for client in sandbox.all_clients(): + res = client.p2p_stat() + assert not res.peers + + def test_add_peers(self, sandbox: Sandbox): + """ Set up a trusted ring topology. """ + base_p2p = sandbox.p2p + for i in range(NUM_NODES): + client = sandbox.client(i) + client.trust_peer(base_p2p + ((i + 1) % NUM_NODES)) + + def test_check_clique(self, sandbox: Sandbox): + """Everyone should be connected to everyone else. This is a + liveness property. Its realization depends on the timing of the + p2p maintenance process. The check is repeated up to NUM_RETRIES + times with a POLLING_TIME seconds wait.""" + for i in range(NUM_NODES): + client = sandbox.client(i) + for _ in range(NUM_RETRIES): + points = client.p2p_stat().points.values() + num_connected = len( + [point for point in points if point.is_connected] + ) + if num_connected == NUM_NODES - 1: + break + time.sleep(POLLING_TIME) + assert num_connected == NUM_NODES - 1 + + def test_check_tables(self, sandbox: Sandbox): + """Test various assumptions on the point/peer tables. + Each peer has exactly one trusted neighbor. Tables don't + contain their own peer/point id and contain exactly NUM_NODES - 1 + values. + + The previous test should guarantee that maintenance has been + performed when this test is run.""" + base_p2p = sandbox.p2p + for i in range(NUM_NODES): + client = sandbox.client(i) + point_id = f'127.0.0.1:{base_p2p + i}' + peer_id = client.rpc('get', '/network/self') + res = client.p2p_stat() + assert peer_id not in res.peers + assert point_id not in res.points + num_trusted = 0 + for point_id, point in res.points.items(): + num_trusted += point.is_trusted + assert num_trusted == 1 + assert len(res.peers) == NUM_NODES - 1 + assert len(res.points) == NUM_NODES - 1 + + def test_set_expected_peers(self, sandbox: Sandbox): + """For all nodes, we add one expected peer_id + for the successor node.""" + peers_id = {} + for i in range(NUM_NODES): + client = sandbox.client(i) + peers_id[i] = client.rpc('get', '/network/self') + + for i in range(NUM_NODES): + client = sandbox.client(i) + client.set_expected_peer_id( + sandbox.p2p + ((i + 1) % NUM_NODES), + peers_id[(i + 1) % NUM_NODES], + ) + + def test_expected_peers(self, sandbox: Sandbox): + """For all nodes, we check that expected peer_id was + set properly.""" + peers_id = {} + for i in range(NUM_NODES): + client = sandbox.client(i) + peers_id[i] = client.rpc('get', '/network/self') + + for i in range(NUM_NODES): + client = sandbox.client(i) + expected_id = client.get_expected_peer_id( + sandbox.p2p + ((i + 1) % NUM_NODES) + ) + assert expected_id == peers_id[(i + 1) % NUM_NODES] + + def test_wrong_expected_peer(self, sandbox: Sandbox): + """We change the expected peer_id set previously to a wrong + expected peer_id.""" + peers_id = {} + for i in range(NUM_NODES): + client = sandbox.client(i) + peers_id[i] = client.rpc('get', '/network/self') + + for i in range(NUM_NODES): + client = sandbox.client(i) + client.set_expected_peer_id( + sandbox.p2p + ((i + 2) % NUM_NODES), peers_id[i] + ) + + def test_check_stat_with_wrong_expected_peers(self, sandbox: Sandbox): + """All nodes are public, everyone should be connected. But + only one neighbor should be trusted.""" + base_p2p = sandbox.p2p + for i in range(NUM_NODES): + client = sandbox.client(i) + point_id = '127.0.0.1:' + str(base_p2p + i) + peer_id = client.rpc('get', '/network/self') + res = client.p2p_stat() + assert peer_id not in res.peers + assert point_id not in res.points + num_trusted = 0 + num_connected = 0 + for point_id, point in res.points.items(): + num_trusted += point.is_trusted + num_connected += point.is_connected + assert len(res.peers) == NUM_NODES - 1 + assert len(res.points) == NUM_NODES - 1 + assert num_trusted == 1 + # We lost two connections + assert num_connected == NUM_NODES - 1 - 2 diff --git a/tests_python/tests_012/test_per_block_votes.py b/tests_python/tests_012/test_per_block_votes.py new file mode 100644 index 000000000000..5bf3b73bac3b --- /dev/null +++ b/tests_python/tests_012/test_per_block_votes.py @@ -0,0 +1,131 @@ +import time + +from typing import Optional, Iterator + +import pytest + +from launchers.sandbox import Sandbox +from tools import utils, constants, paths + +from . import protocol + +MINIMAL_BLOCK_DELAY = 2 +SLEEP = 2 * MINIMAL_BLOCK_DELAY + + +def run_vote_file(sandbox: Sandbox, filename: str) -> None: + sandbox.rm_baker(0, proto=protocol.DAEMON) + sandbox.add_baker( + 0, + [f'bootstrap{i}' for i in range(1, 6)], + proto=protocol.DAEMON, + run_params=["--votefile", filename], + ) + if not sandbox.log_dir: + pytest.skip() + time.sleep(SLEEP) + assert sandbox.logs + + +def run_vote_file_test(sandbox: Sandbox, filename: str) -> None: + run_vote_file(sandbox, filename) + assert utils.check_logs( + sandbox.logs, + ( + r'The provided block vote file path ' + f'"{filename}" does not point to an existing file.' + '|' + r'The provided block vote file path ' + f'"{filename}" does not point to a valid JSON file.' + '|' + r'The provided block vote file ' + f'"{filename}" is a valid JSON file but its content is unexpected.' + ), + ) + + +def run_vote_file_test_error( + sandbox: Sandbox, filename: str, error_pattern: str +) -> None: + run_vote_file(sandbox, filename) + assert not utils.check_logs(sandbox.logs, error_pattern) + + +def run_nonexistent_file_test(sandbox, filename): + error_pattern = ( + r'The provided block vote file path ' + f'"{filename}" does not point to an existing file.' + ) + run_vote_file_test_error(sandbox, filename, error_pattern) + + +def run_invalid_file_test(sandbox, filename): + error_pattern = ( + r'The provided block vote file path ' + f'"{filename}" does not point to a valid JSON file.' + ) + run_vote_file_test_error(sandbox, filename, error_pattern) + + +def run_wrong_content_file_test(sandbox, filename): + error_pattern = ( + r'The provided block vote file ' + f'"{filename}" is a valid JSON file but its content is unexpected.' + ) + run_vote_file_test_error(sandbox, filename, error_pattern) + + +@pytest.fixture(scope="class") +def sandbox(log_dir: Optional[str], singleprocess: bool) -> Iterator[Sandbox]: + """Sandboxed network of nodes where daemons are allowed to fail. + + Nodes, bakers and endorsers are added/removed dynamically.""" + # log_dir is None if not provided on command-line + # singleprocess is false if not provided on command-line + with Sandbox( + paths.TEZOS_HOME, + constants.IDENTITIES, + log_dir=log_dir, + singleprocess=singleprocess, + ) as sandbox: + yield sandbox + + +class TestAllPerBlockVotes: + def test_setup_network(self, sandbox: Sandbox): + sandbox.add_node(0, params=constants.NODE_PARAMS) + parameters = protocol.get_parameters() + parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) + parameters['delay_increment_per_round'] = "1" + protocol.activate(sandbox.client(0), parameters=parameters) + sandbox.add_baker(0, ['bootstrap1'], proto=protocol.DAEMON) + + def test_wait_for_protocol(self, sandbox: Sandbox): + clients = sandbox.all_clients() + for client in clients: + proto = protocol.HASH + assert utils.check_protocol(client, proto) + + def test_true_vote_file(self, sandbox: Sandbox): + filename = "tests_012/per_block_vote_files/true.json" + run_vote_file_test(sandbox, filename) + + def test_false_vote_file(self, sandbox: Sandbox): + filename = "tests_012/per_block_vote_files/false.json" + run_vote_file_test(sandbox, filename) + + def test_nonexistent_vote_file(self, sandbox: Sandbox): + filename = "tests_012/per_block_vote_files/nonexistant.json" + run_nonexistent_file_test(sandbox, filename) + + def test_invalid_json(self, sandbox: Sandbox): + filename = "tests_012/per_block_vote_files/invalid.json" + run_invalid_file_test(sandbox, filename) + + def test_nonboolean(self, sandbox: Sandbox): + filename = "tests_012/per_block_vote_files/non_boolean.json" + run_wrong_content_file_test(sandbox, filename) + + def test_wrong_key(self, sandbox: Sandbox): + filename = "tests_012/per_block_vote_files/wrong_key.json" + run_wrong_content_file_test(sandbox, filename) diff --git a/tests_python/tests_012/test_programs.py b/tests_python/tests_012/test_programs.py new file mode 100644 index 000000000000..184f8a17c817 --- /dev/null +++ b/tests_python/tests_012/test_programs.py @@ -0,0 +1,97 @@ +import itertools +from client.client import Client + +CONVERT_INPUT_FORMATS = ["michelson", "json", "binary"] +CONVERT_OUTPUT_FORMATS = ["michelson", "json", "binary", "ocaml"] +CONVERT_SCRIPT = { + "michelson": """{ parameter unit ; + storage unit ; + code { CDR ; + NIL operation ; + SELF ; + PUSH mutez 0 ; + UNIT ; + TRANSFER_TOKENS ; + DUP ; + DIP { CONS } ; + CONS ; + PAIR } }""", + "json": """[ { "prim": "parameter", "args": [ { "prim": "unit" } ] }, + { "prim": "storage", "args": [ { "prim": "unit" } ] }, + { "prim": "code", + "args": + [ [ { "prim": "CDR" }, + { "prim": "NIL", "args": [ { "prim": "operation" } ] }, + { "prim": "SELF" }, + { "prim": "PUSH", "args": [ { "prim": "mutez" }, { "int": "0" } ] }, + { "prim": "UNIT" }, { "prim": "TRANSFER_TOKENS" }, + { "prim": "DUP" }, + { "prim": "DIP", "args": [ [ { "prim": "CONS" } ] ] }, + { "prim": "CONS" }, { "prim": "PAIR" } ] ] } ]""", + "binary": "0x02000000300500036c0501036c050202000000210317053d036d03490743036a0000034f034d0321051f0200000002031b031b0342", # pylint: disable=line-too-long # noqa: E501 + "ocaml": "Seq (0, [Prim (1, K_parameter, [Prim (2, T_unit, [], [])], []); Prim (3, K_storage, [Prim (4, T_unit, [], [])], []); Prim (5, K_code, [Seq (6, [Prim (7, I_CDR, [], []); Prim (8, I_NIL, [Prim (9, T_operation, [], [])], []); Prim (10, I_SELF, [], []); Prim (11, I_PUSH, [Prim (12, T_mutez, [], []); Int (13, Z.zero)], []); Prim (14, I_UNIT, [], []); Prim (15, I_TRANSFER_TOKENS, [], []); Prim (16, I_DUP, [], []); Prim (17, I_DIP, [Seq (18, [Prim (19, I_CONS, [], [])])], []); Prim (20, I_CONS, [], []); Prim (21, I_PAIR, [], [])])], [])])", # pylint: disable=line-too-long # noqa: E501 +} +CONVERT_DATA = { + "michelson": """{ DROP ; + PUSH address "tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU" ; + CONTRACT unit ; + { IF_NONE { { UNIT ; FAILWITH } } {} } ; + PUSH mutez 1 ; + UNIT ; + TRANSFER_TOKENS ; + DIP { NIL operation } ; + CONS }""", + "json": """[ { "prim": "DROP" }, + { "prim": "PUSH", + "args": + [ { "prim": "address" }, + { "string": "tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU" } ] }, + { "prim": "CONTRACT", "args": [ { "prim": "unit" } ] }, + [ { "prim": "IF_NONE", + "args": [ [ [ { "prim": "UNIT" }, { "prim": "FAILWITH" } ] ], [] ] } ], + { "prim": "PUSH", "args": [ { "prim": "mutez" }, { "int": "1" } ] }, + { "prim": "UNIT" }, { "prim": "TRANSFER_TOKENS" }, + { "prim": "DIP", + "args": [ [ { "prim": "NIL", "args": [ { "prim": "operation" } ] } ] ] }, + { "prim": "CONS" } ]""", + "binary": "0x020000006403200743036e0100000024747a31666173774354446369527a45346f4a396a6e32566d3264766a6579413966557a550555036c0200000015072f02000000090200000004034f032702000000000743036a0001034f034d051f0200000004053d036d031b", # pylint: disable=line-too-long # noqa: E501 + "ocaml": "Seq (0, [Prim (1, I_DROP, [], []); Prim (2, I_PUSH, [Prim (3, T_address, [], []); String (4, \"tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU\")], []); Prim (5, I_CONTRACT, [Prim (6, T_unit, [], [])], []); Seq (7, [Prim (8, I_IF_NONE, [Seq (9, [Seq (10, [Prim (11, I_UNIT, [], []); Prim (12, I_FAILWITH, [], [])])]); Seq (13, [])], [])]); Prim (14, I_PUSH, [Prim (15, T_mutez, [], []); Int (16, Z.one)], []); Prim (17, I_UNIT, [], []); Prim (18, I_TRANSFER_TOKENS, [], []); Prim (19, I_DIP, [Seq (20, [Prim (21, I_NIL, [Prim (22, T_operation, [], [])], [])])], []); Prim (23, I_CONS, [], [])])", # pylint: disable=line-too-long # noqa: E501 + "type": "lambda unit (list operation)", +} + + +class TestProgramsCommands: + def test_convert_script(self, client: Client): + for (input_, output) in itertools.product( + CONVERT_INPUT_FORMATS, CONVERT_OUTPUT_FORMATS + ): + result = client.run( + [ + "convert", + "script", + CONVERT_SCRIPT[input_], + "from", + input_, + "to", + output, + ] + ) + assert result.strip() == f"{CONVERT_SCRIPT[output]}" + + def test_convert_data(self, client: Client): + for (input_, output, typecheck) in itertools.product( + CONVERT_INPUT_FORMATS, CONVERT_OUTPUT_FORMATS, [True, False] + ): + args = [ + "convert", + "data", + CONVERT_DATA[input_], + "from", + input_, + "to", + output, + ] + if typecheck: + args += ["--type", CONVERT_DATA["type"]] + result = client.run(args) + assert result.strip() == f"{CONVERT_DATA[output]}" diff --git a/tests_python/tests_012/test_proto_demo_counter.py b/tests_python/tests_012/test_proto_demo_counter.py new file mode 100644 index 000000000000..12c2c7bb5e68 --- /dev/null +++ b/tests_python/tests_012/test_proto_demo_counter.py @@ -0,0 +1,88 @@ +import time +import pytest +from tools import constants +from tools.constants import PROTO_DEMO_COUNTER, PROTO_GENESIS +from client.client import Client + +PARAMS = ['-p', PROTO_GENESIS] + + +@pytest.fixture(scope="class") +def client(sandbox): + """One node with genesis.""" + sandbox.add_node(0, params=constants.NODE_PARAMS) + client = sandbox.client(0) + yield client + + +@pytest.mark.incremental +class TestProtoDemo: + """Activate protocol demo_counter, inject operations and bake block. + + This test relies on the fixture client which launches a single + sandboxed node. + """ + + def test_proto_known(self, client: Client): + res = client.list_protocols() + assert PROTO_DEMO_COUNTER in res + + def test_proto_client_known(self, client: Client): + res = client.list_understood_protocols() + assert PROTO_DEMO_COUNTER[:12] in res + + def test_first_protocol(self, client: Client): + proto = 'PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i' + assert client.get_protocol() == proto + + def test_activate_proto(self, client: Client): + parameters = {'init_a': 100, 'init_b': 100} + res = client.activate_protocol_json( + PROTO_DEMO_COUNTER, parameters, key='activator', fitness='1' + ) + assert res.block_hash + + def test_level1(self, client: Client): + assert client.get_level() == 1 + + def test_protocol_genesis(self, client: Client): + assert client.get_protocol() == PROTO_GENESIS + + def test_bake_command(self, client: Client): + time.sleep(1) + client.run(['bake', 'This is block 2']) + + def test_level2(self, client: Client): + head = client.rpc('get', '/chains/main/blocks/head/') + assert head['header']['level'] == 2 + + def test_inject_operations(self, client: Client): + client.run(['increment', 'a']) + client.run(['increment', 'b']) + client.run(['transfer', '10']) + + def test_mempool(self, client: Client): + ops = client.get_mempool() + assert len(ops['applied']) == 3 + + def test_bake_command_2(self, client: Client): + time.sleep(1) + client.run(['bake', 'This is block 3']) + + def test_level3(self, client: Client): + head = client.rpc('get', '/chains/main/blocks/head/') + assert head['header']['level'] == 3 + + def test_rpc_counter_a(self, client: Client): + head = client.rpc('get', '/chains/main/blocks/head/counter/a') + assert head == 91 + + def test_rpc_counter_b(self, client: Client): + head = client.rpc('get', '/chains/main/blocks/head/counter/b') + assert head == 111 + + def test_get_counter_commands(self, client: Client): + message_a = client.run(['get', 'a']) + assert message_a == "The counter value is 91\n" + message_b = client.run(['get', 'b']) + assert message_b == "The counter value is 111\n" diff --git a/tests_python/tests_012/test_proto_demo_noops_manual_bake.py b/tests_python/tests_012/test_proto_demo_noops_manual_bake.py new file mode 100644 index 000000000000..215f2ed99f1e --- /dev/null +++ b/tests_python/tests_012/test_proto_demo_noops_manual_bake.py @@ -0,0 +1,97 @@ +import time +import pytest +from tools.constants import PROTO_DEMO_NOOPS, PROTO_GENESIS +from client.client import Client + +PARAMS = ['-p', PROTO_GENESIS] + + +@pytest.fixture(scope="class") +def client(sandbox): + """One node with genesis.""" + sandbox.add_node(0) + client = sandbox.client(0) + yield client + + +def forge_block_header_data(protocol_data): + """ + Returns a binary encoding for a dict of the form + `{'block_header_data: string}`, as expected by the protocol. + + This corresponds to the encoding given by + `data_encoding.(obj1 (req "block_header_data" string))`. See + `lib_data_encoding/data_encoding.mli` for the spec. + """ + assert len(protocol_data) == 1 and 'block_header_data' in protocol_data + string = protocol_data['block_header_data'] + tag = '0000' + padded_hex_len = f'{len(string):#06x}'[2:] + return tag + padded_hex_len + bytes(string, 'utf-8').hex() + + +@pytest.mark.incremental +class TestProtoDemo: + """Activate protocol demo_noops, injection some operations and bake block. + + This test relies on the fixture client which launches a single + sandboxed node. + """ + + def test_proto_known(self, client: Client): + res = client.list_protocols() + assert PROTO_DEMO_NOOPS in res + + def test_first_protocol(self, client: Client): + proto = 'PrihK96nBAFSxVL1GLJTVhu9YnzkMFiBeuJRPA8NwuZVZCE1L6i' + assert client.get_protocol() == proto + + def test_activate_proto(self, client: Client): + parameters = {} # type: dict + res = client.activate_protocol_json( + PROTO_DEMO_NOOPS, parameters, key='activator', fitness='1' + ) + assert res.block_hash + + def test_level1(self, client: Client): + assert client.get_level(params=PARAMS) == 1 + + def test_protocol_genesis(self, client: Client): + assert client.get_protocol(params=PARAMS) == PROTO_GENESIS + + def test_manual_bake(self, client: Client): + time.sleep(1) + message = "hello world" + + data = { + "protocol_data": { + "protocol": PROTO_DEMO_NOOPS, + "block_header_data": message, + }, + "operations": [], + } + block = client.rpc( + 'post', + '/chains/main/blocks/head/helpers/preapply/block', + data=data, + params=PARAMS, + ) + + protocol_data = {'block_header_data': message} + encoded = forge_block_header_data(protocol_data) + + shell_header = block['shell_header'] + shell_header['protocol_data'] = encoded + encoded = client.rpc( + 'post', + '/chains/main/blocks/head/helpers/forge_block_header', + data=shell_header, + params=PARAMS, + ) + + inject = {'data': encoded['block'], 'operations': []} + client.rpc('post', '/injection/block', data=inject, params=PARAMS) + + def test_level2(self, client: Client): + head = client.rpc('get', '/chains/main/blocks/head/', params=PARAMS) + assert head['header']['level'] == 2 diff --git a/tests_python/tests_012/test_rpc.py b/tests_python/tests_012/test_rpc.py new file mode 100644 index 000000000000..ee8ba1a5ed15 --- /dev/null +++ b/tests_python/tests_012/test_rpc.py @@ -0,0 +1,639 @@ +import os +import time +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox +from . import protocol +from . import contract_paths + +CHAIN_ID = "main" +BLOCK_ID = "head" +PKH = "edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" +PROTOCOL_HASH = protocol.HASH +BLOCK_LEVEL = "3" +LIST_OFFSET = "0" +OPERATION_OFFSET = "0" + + +@pytest.fixture(scope="class") +def session(): + session = {} + session["implicit_accounts"] = [ + "tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN", + "tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv", + "tz1b7tUupMgCNw2cCLpKTkSD1NZzB5TkP2sv", + "tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU", + "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx", + ] + return session + + +@pytest.fixture(scope="class") +def contract_name(): + return "contract_identity" + + +@pytest.fixture(scope="class", params=[None, "proxy"]) +def sandbox(request, sandbox: Sandbox, contract_name, session: dict): + """Adds two nodes to sandbox. Using the first node, originates the + identity contract `id.tz` with the name contract_name and makes it + address available under session['originated_accounts']. + """ + sandbox.add_node(1, params=constants.NODE_PARAMS, mode=request.param) + sandbox.add_node(2, params=constants.NODE_PARAMS, mode=request.param) + client = sandbox.client(1) + parameters = protocol.get_parameters() + parameters['consensus_threshold'] = 0 + protocol.activate( + sandbox.client(1), activate_in_the_past=True, parameters=parameters + ) + + utils.bake(client) + time.sleep(2) + # Deploy a contract + contract = os.path.join(contract_paths.CONTRACT_PATH, 'attic', 'id.tz') + args = ['--init', "\"tezos\"", '--burn-cap', '10.0'] + origination = client.originate( + contract_name, 10.0, "bootstrap1", contract, args + ) + session['originated_accounts'] = [origination.contract] + utils.bake(client) + assert utils.check_block_contains_operations( + client, [origination.operation_hash] + ) + return sandbox + + +@pytest.mark.incremental +@pytest.mark.mempool +@pytest.mark.multinode +@pytest.mark.slow +class TestRPCsExistence: + """ + Tests the existence of RPCs. It does not check the output! + Existence relying on the storage are tested using bootstrap + accounts/originated contracts. + """ + + block_hash = "" + + def test_config_file(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/config') + + def test_network_self(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/network/self') + + def test_constants(self, sandbox: Sandbox): + sandbox.client(2).rpc('get', '/network/self') + utils.bake(sandbox.client(1)) + time.sleep(3) + + def test_chain_blocks(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', f'/chains/{CHAIN_ID}/blocks') + + def test_chain_chain_id(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', f'/chains/{CHAIN_ID}/chain_id') + + def test_chain_invalid_blocks(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', f'/chains/{CHAIN_ID}/invalid_blocks') + + def test_errors(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/errors') + + def test_fetch_protocol_protocol_hash(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', f'/fetch_protocol/{PROTOCOL_HASH}') + + def test_network_connections(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/network/connections') + + def test_network_connections_peer_id(self, sandbox: Sandbox): + peer_id = sandbox.client(2).rpc('get', '/network/self') + sandbox.client(1).rpc('get', f'/network/connections/{peer_id}') + + def test_network_greylist_clear(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/network/greylist/clear') + + def test_network_peers(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/network/peers') + + def test_network_peers_peer_id(self, sandbox: Sandbox): + peer_id = sandbox.client(2).rpc('get', '/network/self') + sandbox.client(1).rpc('get', f'/network/peers/{peer_id}') + + def test_network_peers_peer_id_ban(self, sandbox: Sandbox): + peer_id = sandbox.client(2).rpc('get', '/network/self') + sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/ban') + + def test_network_peers_peer_id_banned(self, sandbox: Sandbox): + peer_id = sandbox.client(2).rpc('get', '/network/self') + sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/banned') + + def test_network_peers_peer_id_unban(self, sandbox: Sandbox): + peer_id = sandbox.client(2).rpc('get', '/network/self') + sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/unban') + + def test_network_peers_peer_id_untrust(self, sandbox: Sandbox): + peer_id = sandbox.client(2).rpc('get', '/network/self') + sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/untrust') + + def test_network_peers_peer_id_trust(self, sandbox: Sandbox): + peer_id = sandbox.client(2).rpc('get', '/network/self') + sandbox.client(1).rpc('get', f'/network/peers/{peer_id}/trust') + + def test_network_points(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/network/points') + + def test_network_points_point(self, sandbox: Sandbox): + points = sandbox.client(1).rpc('get', '/network/points') + point = points[-1][0] + sandbox.client(1).rpc('get', f'/network/points/{point}') + + def test_network_points_point_ban(self, sandbox: Sandbox): + points = sandbox.client(1).rpc('get', '/network/points') + point = points[-1][0] + sandbox.client(1).rpc('get', f'/network/points/{point}/ban') + + def test_network_points_point_banned(self, sandbox: Sandbox): + points = sandbox.client(1).rpc('get', '/network/points') + point = points[-1][0] + sandbox.client(1).rpc('get', f'/network/points/{point}/banned') + + def test_network_points_point_trust(self, sandbox: Sandbox): + points = sandbox.client(1).rpc('get', '/network/points') + point = points[-1][0] + sandbox.client(1).rpc('get', f'/network/points/{point}/trust') + + def test_network_points_point_unban(self, sandbox: Sandbox): + points = sandbox.client(1).rpc('get', '/network/points') + point = points[-1][0] + sandbox.client(1).rpc('get', f'/network/points/{point}/unban') + + def test_network_points_point_untrust(self, sandbox: Sandbox): + points = sandbox.client(1).rpc('get', '/network/points') + point = points[-1][0] + sandbox.client(1).rpc('get', f'/network/points/{point}/untrust') + + def test_network_stat(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/network/stat') + + def test_network_version(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/network/version') + + def test_network_versions(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/network/versions') + + def test_protocols(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/protocols') + + def test_protocols_protocol_hash(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', f'/protocols/{PROTOCOL_HASH}') + + def test_workers_block_validator(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/workers/block_validator') + + def test_workers_chain_validators(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/workers/chain_validators') + + def test_workers_chain_validator(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', f'/workers/chain_validators/{CHAIN_ID}') + + def test_workers_chain_validator_ddb(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/workers/chain_validators/{CHAIN_ID}/ddb' + ) + + def test_workers_chain_validator_peers_validators(self, sandbox): + sandbox.client(1).rpc( + 'get', f'/workers/chain_validators/{CHAIN_ID}/' 'peers_validators' + ) + + def test_workers_prevalidators(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', '/workers/prevalidators') + + def test_workers_prevalidators_chain_id(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', f'/workers/prevalidators/{CHAIN_ID}') + + def test_chain_block(self, sandbox: Sandbox): + sandbox.client(1).rpc('get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}') + + def test_chain_block_context_constants(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/constants' + ) + + def test_chain_block_context_constants_errors(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/constants/errors', + ) + + def test_chain_block_context_contracts(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/contracts' + ) + + def test_chain_block_context_contract_id( + self, sandbox: Sandbox, session: dict + ): + accounts = session["originated_accounts"] + session["implicit_accounts"] + for contract_id in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/contracts/{contract_id}', + ) + + def test_chain_block_context_contract_balance( + self, sandbox: Sandbox, session: dict + ): + accounts = session["originated_accounts"] + session["implicit_accounts"] + for contract_id in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/contracts/{contract_id}/balance', + ) + + def test_chain_block_context_contract_counter( + self, sandbox: Sandbox, session: dict + ): + # only implicit contracts, see + # proto_012_PsiThaCa/lib_protocol/contract_repr.ml + for contract_id in session["implicit_accounts"]: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/contracts/{contract_id}/counter', + ) + + def test_chain_block_context_contract_delegate( + self, sandbox: Sandbox, session: dict + ): + for contract_id in session["implicit_accounts"]: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/contracts/{contract_id}/delegate', + ) + + def test_chain_block_context_contract_script_originated( + self, sandbox: Sandbox, session: dict + ): + # only originated contracts + accounts = session["originated_accounts"] + for contract_id in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/contracts/{contract_id}/script', + ) + + def test_chain_block_context_contract_script_implicit( + self, sandbox: Sandbox, session: dict + ): + accounts = session["implicit_accounts"] + for contract_id in accounts: + with utils.assert_run_failure('No service found at this URL'): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/contracts/{contract_id}/' + 'script', + ) + + def test_chain_block_context_contract_storage_originated( + self, sandbox: Sandbox, session: dict + ): + # only originated contracts + accounts = session["originated_accounts"] + for contract_id in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/contracts/{contract_id}/storage', + ) + + def test_chain_block_context_contract_storage_implicit( + self, sandbox: Sandbox, session: dict + ): + # only implicit contracts + accounts = session["implicit_accounts"] + for contract_id in accounts: + with utils.assert_run_failure('No service found at this URL'): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/contracts/{contract_id}/' + 'storage', + ) + + def test_chain_block_context_delegates(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/delegates' + ) + + def test_chain_block_context_delegate_implicit( + self, sandbox: Sandbox, session: dict + ): + # only implicit accounts + accounts = session["implicit_accounts"] + for pkh in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/delegates/{pkh}', + ) + + def test_chain_block_context_delegate_deactivated_implicit( + self, sandbox: Sandbox, session: dict + ): + # only implicit accounts + accounts = session["implicit_accounts"] + for pkh in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/delegates/{pkh}/deactivated', + ) + + def test_chain_block_context_delegate_delegated_balance_implicit( + self, sandbox: Sandbox, session: dict + ): + # only implicit accounts + accounts = session["implicit_accounts"] + for pkh in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/delegates/{pkh}/delegated_balance', + ) + + def test_chain_block_context_delegate_delegated_contracts_implicit( + self, sandbox: Sandbox, session: dict + ): + # only implicit accounts + accounts = session["implicit_accounts"] + for pkh in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/delegates/{pkh}/' + 'delegated_contracts', + ) + + def test_chain_block_context_delegate_frozen_deposits_implicit( + self, sandbox: Sandbox, session: dict + ): + # only implicit accounts + accounts = session["implicit_accounts"] + for pkh in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/delegates/{pkh}/' + 'frozen_deposits', + ) + + def test_chain_block_context_delegate_grace_period_implicit( + self, sandbox: Sandbox, session: dict + ): + # only implicit accounts + accounts = session["implicit_accounts"] + for pkh in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/delegates/{pkh}/grace_period', + ) + + def test_chain_block_context_delegate_staking_balance_implicit( + self, sandbox: Sandbox, session: dict + ): + # only implicit accounts + accounts = session["implicit_accounts"] + for pkh in accounts: + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/delegates/{pkh}/staking_balance', + ) + + def test_chain_block_context_nonces_block_level(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/nonces/{BLOCK_LEVEL}', + ) + + def test_chain_block_context_raw_bytes(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'context/raw/bytes' + ) + + def test_chain_block_hash(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/hash' + ) + + def test_chain_block_header(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header' + ) + + def test_chain_block_header_protocol_data(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header/protocol_data', + ) + + def test_chain_block_header_protocol_data_raw(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header/protocol_data/raw', + ) + + def test_chain_block_header_raw(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header/raw' + ) + + def test_chain_block_header_shell(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'header/shell' + ) + + def test_chain_block_helpers_baking_rights(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'helpers/baking_rights', + ) + + def test_chain_block_helpers_complete_prefix1(self, sandbox: Sandbox): + prefix = PKH[:10] + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'helpers/complete/{prefix}', + ) + + def test_chain_block_helpers_complete_prefix2(self, sandbox: Sandbox): + res = utils.bake(sandbox.client(1)) + prefix = res.block_hash[:5] + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'helpers/complete/{prefix}', + ) + + def test_chain_block_helpers_current_level(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'helpers/current_level', + ) + + def test_chain_block_helpers_endorsing_rights(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'helpers/endorsing_rights', + ) + + def test_chain_block_helpers_levels_in_current_cycle( + self, sandbox: Sandbox + ): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + 'helpers/levels_in_current_cycle', + ) + + def test_chain_block_live_blocks(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'live_blocks' + ) + + def test_chain_block_metadata(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'metadata' + ) + + def test_chain_block_operation_hashes(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'operation_hashes' + ) + + def test_add_transactions(self, sandbox: Sandbox): + sandbox.client(1).transfer(1.000, 'bootstrap1', 'bootstrap2') + sandbox.client(2).transfer(1.000, 'bootstrap3', 'bootstrap4') + # FIXME: Use client.endorse + # Not clear where to put it w.r.t to Tenderbake, + # knowing that bake for does endorse + sandbox.client(1).run(["endorse", "for", 'bootstrap2', '--force']) + utils.bake(sandbox.client(1)) + time.sleep(3) + + def test_chain_block_operation_hashes_list_offset(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'operation_hashes/{LIST_OFFSET}', + ) + + def test_chain_block_operation_hashes_list_operation( + self, sandbox: Sandbox + ): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'operation_hashes/{LIST_OFFSET}/{OPERATION_OFFSET}', + ) + + def test_chain_block_operations(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'operations' + ) + + def test_chain_block_operations_list(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'operations/{LIST_OFFSET}', + ) + + def test_chain_block_operations_list_operation(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'operations/{LIST_OFFSET}/' + f'{OPERATION_OFFSET}', + ) + + def test_chain_block_votes_ballot_list(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' f'votes/ballot_list' + ) + + def test_chain_block_votes_ballots(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/ballots' + ) + + def test_chain_block_votes_current_period(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/current_period', + ) + + def test_chain_block_votes_current_proposal(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/current_proposal', + ) + + def test_chain_block_votes_current_quorum(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/current_quorum', + ) + + def test_chain_block_votes_listings(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/listings' + ) + + def test_chain_block_votes_proposals(self, sandbox: Sandbox): + sandbox.client(1).rpc( + 'get', f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' 'votes/proposals' + ) + + def test_stat_gc(self, sandbox: Sandbox): + assert sandbox.client(1).rpc('get', "/stats/gc") + + def test_stat_memory(self, sandbox: Sandbox): + assert sandbox.client(1).rpc('get', "/stats/memory") + + +class TestDeprecatedRPCs: + def test_chain_block_context_contract_delegatable( + self, sandbox: Sandbox, session: dict + ): + for contract_id in session["implicit_accounts"]: + with utils.assert_run_failure(r"Did not find service"): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/' + f'{BLOCK_ID}/context/contracts/' + f'{contract_id}/delegatable', + ) + + def test_chain_block_context_contract_spendable( + self, sandbox: Sandbox, session: dict + ): + accounts = session["originated_accounts"] + session["implicit_accounts"] + for contract_id in accounts: + with utils.assert_run_failure(r"Did not find service"): + sandbox.client(1).rpc( + 'get', + f'/chains/{CHAIN_ID}/blocks/{BLOCK_ID}/' + f'context/contracts/{contract_id}/' + 'spendable', + ) diff --git a/tests_python/tests_012/test_sapling.py b/tests_python/tests_012/test_sapling.py new file mode 100644 index 000000000000..f8b6af4fb939 --- /dev/null +++ b/tests_python/tests_012/test_sapling.py @@ -0,0 +1,962 @@ +import json +import re +from os import path +import pytest +from tools import utils, paths, constants +from tools.utils import assert_run_failure +from . import contract_paths +from . import protocol + +CONTRACT_PATH = path.join( + paths.TEZOS_HOME, 'src', protocol.FOLDER, 'lib_protocol', 'test' +) +TX_AMOUNT = 100.0 + + +# TODO: Use a random valid memo size for shielded-tez and others +@pytest.fixture +def contract_path(): + return CONTRACT_PATH + + +@pytest.fixture(scope="class") +def sandbox(sandbox): + sandbox.add_node(0, params=constants.NODE_PARAMS) + parameters = protocol.get_parameters() + parameters['consensus_threshold'] = 0 + protocol.activate( + sandbox.client(0), parameters=parameters, activate_in_the_past=True + ) + return sandbox + + +@pytest.fixture(scope="class") +def node(sandbox): + return sandbox.node(0) + + +@pytest.fixture(scope="class") +def client(sandbox, node): + client = sandbox.get_new_client(node) + return client + + +@pytest.fixture +def mnemonic(): + return [ + "morning", + "dinosaur", + "estate", + "youth", + "sausage", + "feature", + "apology", + "bullet", + "square", + "type", + "zoo", + "coyote", + "extra", + "fabric", + "grain", + "phone", + "pipe", + "despair", + "razor", + "ranch", + "blouse", + "debris", + "urge", + "evidence", + ] + + +@pytest.fixture +def non_originated_contract_address(): + return "KT1MXuZJJFg4EVpLQeLeuHvznTRiNefh3yCs" + + +@pytest.fixture +def non_originated_contract_name(): + return "fake-contract" + + +@pytest.fixture +def key_name(): + return "test_key_name" + + +# here baker 'account' has baked a block and has sent 'tx_amount' +def check_baker_balance(client, account, tx_amount): + parameters = dict(protocol.PARAMETERS) + initial_amount = float(parameters["bootstrap_accounts"][0][1]) + identity = constants.IDENTITIES[account]['identity'] + all_deposits = client.frozen_deposits(identity) + # sender's balance without fees + expected_baker_balance = ( + initial_amount / 1000000 - all_deposits / 1000000 - tx_amount + ) + baker_balance = client.get_balance(account) + # the fees are assumed to be at most 1 tez + fees_upper_bound = 3 + assert expected_baker_balance - fees_upper_bound <= baker_balance + assert baker_balance <= expected_baker_balance + + +@pytest.mark.client +class TestSaplingWalletImportKey: + @pytest.fixture + def client( + self, + sandbox, + node, + non_originated_contract_name, + non_originated_contract_address, + ): + """ + A client with a pre-registered contract to link the wallet with. + """ + client = sandbox.get_new_client(node) + client.remember_contract( + non_originated_contract_name, non_originated_contract_address + ) + return client + + def test_import_key_no_force(self, client, mnemonic, key_name): + """ + Import key without forcing and without pre-existing alias + """ + client.sapling_import_key(key_name, mnemonic, force=False) + + def test_import_key_force_and_non_previously_saved( + self, + client, + mnemonic, + key_name, + ): + """ + Import key with forcing and without pre-existing alias + """ + client.sapling_import_key(key_name, mnemonic, force=True) + + def test_import_key_force_and_previously_saved( + self, + client, + mnemonic, + key_name, + ): + """ + Import key with forcing and with pre-existing alias + """ + client.sapling_import_key(key_name, mnemonic, force=False) + client.sapling_import_key(key_name, mnemonic, force=True) + + +class TestSaplingWalletAddressGeneration: + @pytest.fixture + def client(self, sandbox, node, key_name, mnemonic): + """ + A client with a sapling wallet + """ + client = sandbox.get_new_client(node) + client.sapling_import_key(key_name, mnemonic, force=False) + return client + + @pytest.mark.parametrize( + "expected_address,expected_index", + [ + ( + "zet13XtyU5Bkasoj1b19sy4DJc7U13XydbxLHqLUdf8Y5tarGb" + "HgFLgDrT6J6FYJoHGL3", + 0, + ) + ], + ) + def test_generate_first_address_of_key( + self, client, key_name, expected_address, expected_index + ): + result = client.sapling_gen_address(key_name) + assert result.index == expected_index + assert result.address == expected_address + + @pytest.mark.parametrize( + "requested_index,expected_address,expected_index", + [ + ( + 0, + "zet13XtyU5Bkasoj1b19sy4DJc7U13XydbxLHqLUdf8Y5tarGb" + "HgFLgDrT6J6FYJoHGL3", + 0, + ), + ( + 1, + "zet13mN26QV67FgPzMSzrigXjKZNMMtCubhi9L3kUePnFYdXqEj" + "c8pmjw1h2wC6NLZf5F", + 1, + ), + ( + 2, + "zet12hzbYRRKbWwKPY61FkjLg7CRWTcjooqeH7VH18fA6Vxnwy7" + "WyTrAEqBXmEdHp9woU", + 4, + ), + ( + 3, + "zet12hzbYRRKbWwKPY61FkjLg7CRWTcjooqeH7VH18fA6Vxnwy7" + "WyTrAEqBXmEdHp9woU", + 4, + ), + ( + 4, + "zet12hzbYRRKbWwKPY61FkjLg7CRWTcjooqeH7VH18fA6Vxnwy7" + "WyTrAEqBXmEdHp9woU", + 4, + ), + ( + 100, + "zet14LmgdAzVrTtQKpeuD3f2y7wFSjXTMEexNNuiEWhGimm25en" + "xkqmwmbdFsC4y6YmYx", + 100, + ), + ( + 143534, + "zet14EWNxZYoHJASHFpcCYSfTfQokWSMzdJeV5SfaGEPDtiYiDC" + "X5jz8QkMF5jZaK5F4k", + 143536, + ), + ( + 42, + "zet143WVQUmNodhSe4ytHL6gvtdXYhRp7bywDWASUFYUCMGAS71" + "juXT6AyWY89fjg3eZn", + 42, + ), + ( + 90870987456348, + "zet13CiUqFsVEr2LdMnyyUQNL3Nh74sa4LdU6V3oD3YfcizbwuF" + "tftPRYvRrB2zsVaEw1", + 90870987456348, + ), + ], + ) + def test_generate_address_with_address_index( + self, + client, + key_name, + expected_address, + expected_index, + requested_index, + ): + result = client.sapling_gen_address(key_name, index=requested_index) + assert result.index == expected_index + assert result.address == expected_address + + +@pytest.mark.client +@pytest.mark.contract +@pytest.mark.incremental +class TestSaplingShieldedTez: + """ + Tests involving sapling key management and shielded transactions using + the shielded tez example contract. + """ + + @pytest.fixture + def contract_path(self): + return path.join(CONTRACT_PATH, 'contracts', 'sapling_contract.tz') + + @pytest.fixture + def contract_name(self): + return "sapling" + + @pytest.fixture(scope="session") + def tmpdir(self, tmpdir_factory): + """ + Temporary directory. Forged transactions will be saved + in this directory. + FIXME/IMPROVEME: tmpdir_factory is a fixture provided by pytest. It is + session-scoped, then the fixture tmpdir must be session-scoped. + Would be nice to have a class-scoped fixture. + """ + tmpdir = tmpdir_factory.mktemp("sapling_transactions_shielded_tez") + return tmpdir + + def test_originate_sapling_contract( + self, contract_path, client, session, contract_name + ): + sender = "bootstrap1" + origination = client.originate( + contract_name=contract_name, + amount=0, + sender=sender, + contract=contract_path, + args=["--init", "{ }", "--burn-cap", "3.0"], + ) + session["contract_address"] = origination.contract + utils.bake(client, bake_for=sender) + assert utils.check_block_contains_operations( + client, + [origination.operation_hash], + ) + + def test_generate_bob(self, client, session, contract_name): + key_name = "bob" + result = client.sapling_gen_key(key_name=key_name) + client.sapling_use_key_for_contract( + key_name, contract_name, memo_size=8 + ) + session['bob_mnemonic'] = result.mnemonic + + def test_list_keys_bob(self, client): + keys = client.sapling_list_keys() + assert keys == ["bob"] + + def test_list_keys_with_alice_and_bob(self, client, contract_name): + """ + NB: another key (ali) is generated in the test, but the mnemonic + is not saved. + We add this test to verify the list keys command orders alphabetically + """ + key_name = "ali" + client.sapling_gen_key(key_name=key_name) + client.sapling_use_key_for_contract( + key_name=key_name, contract_name=contract_name + ) + keys = client.sapling_list_keys() + assert keys == ["ali", "bob"] + + def test_generate_bob_address_0(self, client, session): + result = client.sapling_gen_address( + key_name="bob", + ) + session['last_address_index'] = result.index + session['bob_address_0'] = result.address + + def test_generate_bob_address_1(self, client, session): + result = client.sapling_gen_address( + key_name="bob", + ) + assert result.index > session['last_address_index'] + session['bob_address_1'] = result.address + + def test_check_bob_balance(self, client, contract_name): + result = client.sapling_get_balance( + key_name="bob", + contract_name=contract_name, + ) + assert result.balance == 0 + + def test_shield_bob_address_0(self, client, session, contract_name): + client.sapling_shield( + amount=TX_AMOUNT, + src="bootstrap2", + dest=session['bob_address_0'], + contract=contract_name, + args=["--burn-cap", "3.0"], + ) + utils.bake(client, bake_for="bootstrap1") + check_baker_balance(client, "bootstrap2", TX_AMOUNT) + bob_balance = client.sapling_get_balance( + key_name="bob", contract_name=contract_name + ).balance + assert bob_balance == TX_AMOUNT + + def test_check_contract_balance_after_shielding( + self, client, contract_name + ): + assert client.get_balance(contract_name) == TX_AMOUNT + + def test_regenerate_bob_from_mnemonic(self, client, session): + # Overwrite the old 'bob' key with one restored from the mnemonic. + key_name = "bob" + client.sapling_import_key( + key_name=key_name, + mnemonic=session['bob_mnemonic'], + force=True, + ) + + def test_derive_alice(self, client, contract_name): + result = client.sapling_derive_key( + source_key_name='bob', + target_key_name='alice', + contract_name=contract_name, + index='0', + ) + assert result.path == '0/0' + + def test_derive_yves(self, client, contract_name): + result = client.sapling_derive_key( + source_key_name='bob', + target_key_name='yves', + contract_name=contract_name, + index='1', + ) + assert result.path == '0/1' + + def test_generate_alice_address_0(self, client, session): + result = client.sapling_gen_address( + key_name="alice", + ) + session['alice_address_0'] = result.address + + def test_alice_shields_money_insufficient_funds( + self, client, session, contract_name + ): + bootstrap3 = constants.IDENTITIES['bootstrap3']['identity'] + alice_balance = int(client.get_balance('bootstrap3')) + amount = 2 * alice_balance + with assert_run_failure( + r"Balance of contract {} too low \({}\) to spend {}".format( + bootstrap3, alice_balance, amount + ) + ): + client.sapling_shield( + amount=amount, + src="bootstrap3", + dest=session['alice_address_0'], + contract=contract_name, + args=["--burn-cap", "3.0"], + ) + + def test_alice_shields_money(self, client, session, contract_name): + client.sapling_shield( + amount=TX_AMOUNT, + src="bootstrap3", + dest=session['alice_address_0'], + contract=contract_name, + args=[ + "--burn-cap", + "3.0", + ], + ) + utils.bake(client, bake_for="bootstrap1") + check_baker_balance(client, "bootstrap3", TX_AMOUNT) + alice_balance = client.sapling_get_balance( + key_name="alice", contract_name=contract_name + ).balance + assert alice_balance == TX_AMOUNT + + @pytest.mark.parametrize( + "transaction_file,use_json", + [ + ("sapling_transaction.bin", False), + ("sapling_transaction.json", True), + ], + ) + def test_forge_alice_to_bob_insufficient_funds( + self, + client, + tmpdir, + contract_name, + session, + transaction_file, + use_json, + ): + transaction_file = f'{tmpdir}/{transaction_file}' + amount = 2100000000.0 + account = 'alice' + additional_args = [] + if use_json: + additional_args += ["--json"] + + with assert_run_failure( + r"Balance too low \({}\) to spend {}".format(100, int(amount)) + ): + client.sapling_forge_transaction( + amount=amount, + src=account, + dest=session['bob_address_1'], + contract=contract_name, + file=transaction_file, + args=additional_args, + ) + + def test_forge_alice_to_bob_address_0( + self, tmpdir, session, client, contract_name + ): + transaction_file = f'{tmpdir}/sapling_transaction0.bin' + client.sapling_forge_transaction( + amount=TX_AMOUNT, + src='alice', + dest=session['bob_address_0'], + contract=contract_name, + file=transaction_file, + ) + + def test_forge_alice_to_bob_address_1_binary_format( + self, tmpdir, session, client, contract_name + ): + transaction_file = f'{tmpdir}/sapling_transaction1.bin' + client.sapling_forge_transaction( + amount=50.0, + src='alice', + dest=session['bob_address_1'], + contract=contract_name, + file=transaction_file, + ) + + @pytest.mark.parametrize( + "key_name,expected_balance", [("alice", TX_AMOUNT), ("bob", TX_AMOUNT)] + ) + def test_check_sapling_balances_post_forge_binary_format( + self, client, contract_name, key_name, expected_balance + ): + result = client.sapling_get_balance( + key_name=key_name, + contract_name=contract_name, + ) + assert result.balance == expected_balance + + def test_submit_alice_to_bob_address_1_binary_format( + self, client, tmpdir, contract_name + ): + transaction_file = f'{tmpdir}/sapling_transaction1.bin' + additional_args = ["--burn-cap", "3.0"] + client.sapling_submit( + file=transaction_file, + fee_payer='bootstrap2', + contract=contract_name, + args=additional_args, + ) + utils.bake(client, bake_for="bootstrap2") + + @pytest.mark.parametrize( + "key_name,expected_balance", [("alice", 50.0), ("bob", 150.0)] + ) + def test_check_sapling_balances_after_successfull_transaction_in_binary( + self, client, contract_name, key_name, expected_balance + ): + balance = client.sapling_get_balance( + key_name=key_name, contract_name=contract_name + ).balance + assert balance == expected_balance + + def test_forge_alice_to_bob_address_1_json_format( + self, tmpdir, session, client, contract_name + ): + transaction_file = f'{tmpdir}/sapling_transaction1.json' + client.sapling_forge_transaction( + amount=50.0, + src='alice', + dest=session['bob_address_1'], + contract=contract_name, + file=transaction_file, + args=['--json'], + ) + # Try to load the file as JSON. Must not fail. + with open(transaction_file, "r") as file_descriptor: + json.load(file_descriptor) + + @pytest.mark.parametrize( + "key_name,expected_balance", [("alice", 50.0), ("bob", 150.0)] + ) + def test_check_sapling_balances_post_forge_json_format( + self, client, contract_name, key_name, expected_balance + ): + result = client.sapling_get_balance( + key_name=key_name, + contract_name=contract_name, + ) + assert result.balance == expected_balance + + def test_submit_alice_to_bob_address_1_json_format( + self, client, tmpdir, contract_name + ): + transaction_file = f'{tmpdir}/sapling_transaction1.json' + additional_args = ["--burn-cap", "3.0", "--json"] + client.sapling_submit( + file=transaction_file, + fee_payer='bootstrap2', + contract=contract_name, + args=additional_args, + ) + utils.bake(client, bake_for="bootstrap2") + + @pytest.mark.parametrize( + "key_name,expected_balance", [("alice", 0.0), ("bob", 200.0)] + ) + def test_check_sapling_balances_after_successfull_transaction_in_json( + self, client, contract_name, key_name, expected_balance + ): + balance = client.sapling_get_balance( + key_name=key_name, contract_name=contract_name + ).balance + assert balance == expected_balance + + @pytest.mark.parametrize( + "transaction_file,use_json", + [ + ("sapling_transaction0.bin", False), + # ("sapling_transaction0.json", True), + ], + ) + def test_submit_alice_to_bob0( + self, client, transaction_file, use_json, tmpdir, contract_name + ): + transaction_file = f'{tmpdir}/{transaction_file}' + additional_args = ["--burn-cap", "3.0"] + if use_json: + additional_args.append("--json") + + with assert_run_failure(r'transfer simulation failed'): + client.sapling_submit( + file=transaction_file, + fee_payer='bootstrap2', + contract=contract_name, + args=additional_args, + ) + + @pytest.mark.parametrize( + "requested_token,real_balance,key_name", + [ + (2100000000, 200, "bob"), + (300, 200, "bob"), + (2100000000, 0, "alice"), + (100, 0, "alice"), + ], + ) + def test_unshields_money_insufficient_funds( + self, client, contract_name, requested_token, real_balance, key_name + ): + with assert_run_failure( + r'Balance too low \({}\) to spend {}'.format( + real_balance, requested_token + ) + ): + client.sapling_unshield( + amount=requested_token, + src=key_name, + dest="bootstrap4", + contract=contract_name, + args=["--burn-cap", "3.0"], + ) + + def test_bob_unshields_money(self, client, contract_name): + bootstrap4_prev_balance = client.get_balance('bootstrap4') + amount = 90.0 + client.sapling_unshield( + amount=amount, + src="bob", + dest="bootstrap4", + contract=contract_name, + args=["--burn-cap", "3.0"], + ) + utils.bake(client, bake_for="bootstrap2") + bob_balance = client.sapling_get_balance( + key_name="bob", contract_name=contract_name + ).balance + assert bob_balance == 200.0 - amount + bootstrap4_balance = client.get_balance("bootstrap4") + # The receiver pays fees by default so it will not get the full amount, + # but still, it should have more than before + assert bootstrap4_balance >= bootstrap4_prev_balance + assert bootstrap4_balance <= bootstrap4_prev_balance + amount + + def test_check_state_with_another_client( + self, sandbox, node, contract_name, session + ): + client = sandbox.get_new_client(node) + client.remember_contract(contract_name, session["contract_address"]) + key_name = "bob" + # Restore bob's key from mnemonic: + client.sapling_import_key( + key_name=key_name, + mnemonic=session['bob_mnemonic'], + ) + client.sapling_use_key_for_contract( + key_name, contract_name, memo_size=8 + ) + # Check Bob's balance again, it should be the same: + bob_balance = client.sapling_get_balance( + key_name=key_name, contract_name=contract_name + ).balance + assert bob_balance == 110.0 + + @pytest.mark.parametrize( + "transparent_signer,baker", [("bootstrap4", "bootstrap2")] + ) + def test_shielded_transfer_using_non_sapling_transfer_method( + self, client, contract_name, session, transparent_signer, baker, tmpdir + ): + transaction_filename = f'{tmpdir}/sapling_transaction_2.bin' + client.sapling_forge_transaction( + amount=10.0, + src='bob', + dest=session['bob_address_1'], + contract=contract_name, + file=transaction_filename, + args=[], + ) + with open(transaction_filename, "r") as file_descriptor: + content = re.sub(r'\s+', ' ', file_descriptor.read()) + client.transfer( + 0, + giver=transparent_signer, + receiver=contract_name, + args=[ + "--arg", + '{Pair %s None }' % content, + "--burn-cap", + "3.0", + ], + ) + utils.bake(client, bake_for=baker) + + @pytest.mark.parametrize( + "key_name,expected_balance", [("alice", 0.0), ("bob", 110.0)] + ) + def test_check_sapling_balances_after_calling_smart_contract( + self, client, contract_name, key_name, expected_balance + ): + balance = client.sapling_get_balance( + key_name=key_name, contract_name=contract_name + ).balance + assert balance == expected_balance + + +class TestSaplingMemoSize: + @pytest.fixture(scope="class") + def contract_name(self): + return "sapling_memo_size" + + @pytest.fixture(scope="class") + def contract_generator(self): + def generator(memo_size): + return ''' +parameter unit; +storage (sapling_state %s); +code { + DROP; + SAPLING_EMPTY_STATE %s; + NIL operation; + PAIR; + } +''' % ( + memo_size, + memo_size, + ) + + return generator + + @pytest.mark.parametrize("memo_size", [0, 1, 10, 42, 100, 65535]) + def test_originate_with_valid_size_and_update_with_valid_size( + self, client, memo_size, contract_name, tmpdir, contract_generator + ): + contract_path = tmpdir.join("c.tz") + contract_path.write(contract_generator(memo_size)) + sender = "bootstrap1" + client.originate( + contract_name=contract_name, + amount=0, + sender=sender, + contract=str(contract_path), + args=["--init", '{ }', "--burn-cap", "3.0", "--force"], + ) + utils.bake(client, bake_for="bootstrap1") + client.transfer( + 0, + giver="bootstrap1", + receiver=contract_name, + args=["--arg", "Unit", "--burn-cap", "3.0"], + ) + utils.bake(client, bake_for="bootstrap1") + + @pytest.mark.parametrize("memo_size", [-1, 65536, 65598909, 908923434]) + def test_originate_with_invalid_size( + self, + client, + memo_size, + contract_path, + contract_name, + contract_generator, + tmpdir, + ): + contract_path = tmpdir.join("c.tz") + contract_path.write(contract_generator(memo_size)) + sender = "bootstrap1" + err = r"expected a positive 16-bit integer" + with assert_run_failure(err): + client.originate( + contract_name=contract_name, + amount=0, + sender=sender, + contract=str(contract_path), + args=["--init", "{ }", "--burn-cap", "3.0", "--force"], + ) + + +@pytest.mark.incremental +class TestSaplingStateCorruption: + @pytest.fixture(scope="session") + def tmpdir(self, tmpdir_factory): + """ + Temporary directory. Forged transactions will be saved + in this directory. + FIXME/IMPROVEME: tmpdir_factory is a fixture provided by pytest. It is + session-scoped, then the fixture tmpdir must be session-scoped. + Would be nice to have a class-scoped fixture. + """ + tmpdir = tmpdir_factory.mktemp("sapling_transactions_shielded_tez") + return tmpdir + + def test_push_sapling_state_with_id_is_forbidden( + self, client, contract_path + ): + contract_name = ( + f"{contract_path}/contracts/sapling_push_sapling_state.tz" + ) + sender = "bootstrap1" + msg = r"big_map or sapling_state type not expected here" + with assert_run_failure(msg): + client.originate( + contract_name="push_sapling_state", + amount=0, + sender=sender, + contract=contract_name, + args=["--init", "Unit", "--burn-cap", "3.0"], + ) + + def test_originate_with_empty(self, client): + """ + Makes sure sapling state with id 0 exists + """ + contract = path.join( + contract_paths.OPCODES_CONTRACT_PATH, "sapling_empty_state.tz" + ) + client.originate( + amount=0, + sender="bootstrap1", + contract=contract, + contract_name="sapling_empty_state", + args=["--init", "{}", "--burn-cap", "3.0"], + ) + utils.bake(client, bake_for="bootstrap1") + + def test_originate_with_id_is_forbidden(self, client): + contract = path.join( + contract_paths.OPCODES_CONTRACT_PATH, "sapling_empty_state.tz" + ) + with assert_run_failure(r'Unexpected forged value'): + client.originate( + amount=0, + sender="bootstrap1", + contract=contract, + contract_name="sapling_empty_state2", + args=["--init", "0", "--burn-cap", "3.0"], + ) + + +class TestSaplingDifferentMemosize: + """ + Deploy a sapling contract using a sapling state with a memo size N and + create transactions with a memo size of M + """ + + @pytest.fixture + def contract_path(self): + return f'{CONTRACT_PATH}/contracts/sapling_contract.tz' + + def test_shield_with_different_memo_size(self, contract_path, client): + contract_name = "sapling_memo_size_different" + implicit_account = "bootstrap1" + contract_address = client.originate( + contract_name=contract_name, + amount=0, + sender=implicit_account, + contract=contract_path, + args=["--init", "{ }", "--burn-cap", "3.0"], + ).contract + utils.bake(client, bake_for=implicit_account) + client.sapling_gen_key(key_name='alice') + client.sapling_use_key_for_contract( + 'alice', contract_name, memo_size=16 + ) + address = client.sapling_gen_address(key_name='alice').address + # Key was registered with a memo_size of 16, it should fail + with assert_run_failure(r"Memo sizes of two sapling states"): + client.sapling_shield( + amount=TX_AMOUNT, + src=implicit_account, + dest=address, + contract=contract_address, + args=["--burn-cap", "3.0"], + ) + + +class TestSaplingRightMemosize: + """ + Deploy a sapling contract using a sapling state with a memo size N and + create transactions with a memo size of N and diverse messages + """ + + @pytest.fixture + def contract_path(self): + return f'{CONTRACT_PATH}/contracts/sapling_contract.tz' + + def test_shield_with_same_memo_size(self, contract_path, client): + contract_name = "sapling_memo_size_same" + implicit_account = "bootstrap1" + contract_address = client.originate( + contract_name=contract_name, + amount=0, + sender=implicit_account, + contract=contract_path, + args=["--init", "{ }", "--burn-cap", "3.0"], + ).contract + utils.bake(client, bake_for=implicit_account) + client.sapling_gen_key(key_name='alice') + client.sapling_use_key_for_contract('alice', contract_name, memo_size=8) + address = client.sapling_gen_address(key_name='alice').address + # Should pass since memo-sizes are equal and message is + # filled with 0's + client.sapling_shield( + amount=TX_AMOUNT, + src=implicit_account, + dest=address, + contract=contract_address, + args=["--burn-cap", "3.0"], + ) + utils.bake(client, bake_for="bootstrap2") + # Deriving a new key should work as well since + # the memo-size is kept + client.sapling_derive_key( + source_key_name='alice', + target_key_name='bob', + contract_name=contract_name, + index=10, + ) + address_derived = client.sapling_gen_address(key_name='bob').address + client.sapling_shield( + amount=TX_AMOUNT, + src=implicit_account, + dest=address_derived, + contract=contract_address, + args=["--burn-cap", "3.0"], + ) + utils.bake(client, bake_for="bootstrap2") + # Now with a too short message + client.sapling_shield( + amount=TX_AMOUNT, + src=implicit_account, + dest=address, + contract=contract_address, + args=["--burn-cap", "3.0", "--message", "aB"], + ) + utils.bake(client, bake_for="bootstrap2") + # Now with a right length message + client.sapling_shield( + amount=TX_AMOUNT, + src=implicit_account, + dest=address, + contract=contract_address, + args=["--burn-cap", "3.0", "--message", "aBbf19F00a"], + ) + utils.bake(client, bake_for="bootstrap2") + # Now with a too long message + client.sapling_shield( + amount=TX_AMOUNT, + src=implicit_account, + dest=address, + contract=contract_address, + args=["--burn-cap", "3.0", "--message", "aBbf19F00aaBbf19F00aC"], + ) + utils.bake(client, bake_for="bootstrap2") diff --git a/tests_python/tests_012/test_slice_fails_params.txt b/tests_python/tests_012/test_slice_fails_params.txt new file mode 100644 index 000000000000..7241bd22aff3 --- /dev/null +++ b/tests_python/tests_012/test_slice_fails_params.txt @@ -0,0 +1,5 @@ +(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "p2sigsceCzcDw2AeYDzUonj4JT341WC9Px4wdhHBxbZcG1FhfqFVuG7f2fGCzrEHSAZgrsrQWpxduDPk9qZRgrpzwJnSHC3gZJ") +(Pair 0xeaa9ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") +(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2deaad01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") +(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150733eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") +(Pair 0xe009ab79e8b84ef0 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") diff --git a/tests_python/tests_012/test_slice_success_params.txt b/tests_python/tests_012/test_slice_success_params.txt new file mode 100644 index 000000000000..8c0d89bd8142 --- /dev/null +++ b/tests_python/tests_012/test_slice_success_params.txt @@ -0,0 +1 @@ +(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm") diff --git a/tests_python/tests_012/test_tenderbake.py b/tests_python/tests_012/test_tenderbake.py new file mode 100644 index 000000000000..b2fac3f0978d --- /dev/null +++ b/tests_python/tests_012/test_tenderbake.py @@ -0,0 +1,59 @@ +import time +import copy +import pytest +from tools import constants +from launchers.sandbox import Sandbox +from . import protocol + + +MINIMAL_BLOCK_DELAY = 4 +DELAY_INCREMENT_PER_ROUND = 1 +TEST_DURATION = 5 * MINIMAL_BLOCK_DELAY +NUM_NODES = 5 + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +@pytest.mark.tenderbake +class TestProtoTenderbake: + """Run a number of nodes and bakers, wait and check that all blocks + were agreed upon at round 0""" + + def test_init(self, sandbox: Sandbox): + + for i in range(NUM_NODES): + sandbox.add_node(i, params=constants.NODE_PARAMS) + + proto_params = dict(protocol.TENDERBAKE_PARAMETERS) + parameters = copy.deepcopy(proto_params) + parameters['consensus_threshold'] = ( + 2 * (parameters['consensus_threshold'] // 3) + 1 + ) + parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) + parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) + protocol.activate(sandbox.client(0), parameters=parameters) + + for i in range(NUM_NODES): + sandbox.add_baker( + i, + [f'bootstrap{i + 1}'], + proto=protocol.DAEMON, + log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, + ) + + def test_wait(self): + time.sleep(TEST_DURATION) + + def test_level(self, sandbox: Sandbox): + # a decision should be taken in the first round, so we can deduce at + # which minimal level the nodes should be at + expected_min_level = 1 + TEST_DURATION // MINIMAL_BLOCK_DELAY + for client in sandbox.all_clients(): + level = client.get_level() + assert level >= expected_min_level + for i in range(level + 1): + if i > 1: + block_round = client.get_tenderbake_round(level=str(i)) + assert block_round == 0 diff --git a/tests_python/tests_012/test_tenderbake_bakers_restart.py b/tests_python/tests_012/test_tenderbake_bakers_restart.py new file mode 100644 index 000000000000..897d602cd673 --- /dev/null +++ b/tests_python/tests_012/test_tenderbake_bakers_restart.py @@ -0,0 +1,80 @@ +import copy +import time +import pytest +from tools import constants +from launchers.sandbox import Sandbox +from . import protocol + +NUM_NODES = 5 # because we assume 5 (bootstrap) accounts +NUM_TEST_CYCLES = 4 +# CYCLE_DUR should be correlated with MINIMAL_BLOCK_DELAY and +# DELAY_INCREMENT_PER_ROUND below +CYCLE_DUR = 10 +MINIMAL_BLOCK_DELAY = 4 +DELAY_INCREMENT_PER_ROUND = 1 + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +@pytest.mark.tenderbake +class TestProtoTenderbake: + """Run a number of nodes and start the bakers incrementally, each one + after one round duration more. After all bakers have been + started, they should be able to reach a decision.""" + + def test_init(self, sandbox: Sandbox): + for i in range(NUM_NODES): + sandbox.add_node( + i, + params=constants.NODE_PARAMS, + log_levels=constants.TENDERBAKE_NODE_LOG_LEVELS, + ) + + proto_params = dict(protocol.TENDERBAKE_PARAMETERS) + parameters = copy.deepcopy(proto_params) + parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) + parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) + parameters['consensus_threshold'] = ( + 2 * (parameters['consensus_threshold'] // 3) + 1 + ) + + protocol.activate(sandbox.client(0), parameters=parameters) + + for i in range(NUM_NODES): + sandbox.add_baker( + i, + [f'bootstrap{i + 1}'], + proto=protocol.DAEMON, + log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, + ) + + def test_restart(self, sandbox): + # in the even cycles we run all the bakers + # in the odd cycles one is dead + # we iterate cyclically through the bakers to choose the dead one + dead_baker = 0 + for cycle in range(NUM_TEST_CYCLES): + if cycle % 2 == 1: + sandbox.rm_baker(dead_baker, proto=protocol.DAEMON) + # we let some time pass + # (there will be no progress during this time) + time.sleep(MINIMAL_BLOCK_DELAY) + else: + if cycle > 1: + sandbox.add_baker( + dead_baker, + [f'bootstrap{dead_baker + 1}'], + proto=protocol.DAEMON, + log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, + ) + # the CYCLE_DUR is long enough for bakers to take a decision + time.sleep(CYCLE_DUR) + dead_baker = (dead_baker + 1) % NUM_NODES + + def test_level(self, sandbox): + expected_min_level = 2 + NUM_TEST_CYCLES / 2 + for client in sandbox.all_clients(): + level = client.get_level() + assert level >= expected_min_level diff --git a/tests_python/tests_012/test_tenderbake_incremental_start.py b/tests_python/tests_012/test_tenderbake_incremental_start.py new file mode 100644 index 000000000000..0f36d4208483 --- /dev/null +++ b/tests_python/tests_012/test_tenderbake_incremental_start.py @@ -0,0 +1,82 @@ +import copy +import time +import pytest +from tools import constants +from launchers.sandbox import Sandbox +from . import protocol + +NUM_NODES = 5 # because we assume 5 (bootstrap) accounts +NUM_EARLY_START_NODES = 2 +MINIMAL_BLOCK_DELAY = 4 +DELAY_INCREMENT_PER_ROUND = 1 +TEST_DURATION = 5 * MINIMAL_BLOCK_DELAY + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +@pytest.mark.tenderbake +class TestProtoTenderbakeIncrementalStart: + """Run a number of nodes and start the bakers incrementally, each one + after one round duration more. After all bakers have been + started, they should be able to reach a decision.""" + + def test_init_nodes(self, sandbox: Sandbox): + for i in range(NUM_NODES): + sandbox.add_node( + i, + params=constants.NODE_PARAMS, + log_levels=constants.TENDERBAKE_NODE_LOG_LEVELS, + ) + + def test_start_some_bakers(self, sandbox: Sandbox): + for i in range(NUM_EARLY_START_NODES): + account = f'bootstrap{i + 1}' + sandbox.add_baker( + i, + [account], + proto=protocol.DAEMON, + log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, + ) + + def test_activate(self, sandbox): + proto_params = dict(protocol.TENDERBAKE_PARAMETERS) + parameters = copy.deepcopy(proto_params) + parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) + parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) + parameters['consensus_threshold'] = ( + 2 * (parameters['consensus_threshold'] // 3) + 1 + ) + + time.sleep(2 * MINIMAL_BLOCK_DELAY) + protocol.activate( + sandbox.client(0), + parameters=parameters, + ) + + def test_start_remaining_bakers(self, sandbox: Sandbox): + for i in range(NUM_EARLY_START_NODES, NUM_NODES): + account = f'bootstrap{i + 1}' + sandbox.add_baker( + i, + [account], + proto=protocol.DAEMON, + log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, + ) + time.sleep(MINIMAL_BLOCK_DELAY) + + def test_wait(self): + time.sleep(TEST_DURATION) + + def test_level(self, sandbox): + # a decision should be taken in the first round, so we can deduce at + # which minimal level the nodes should be at + expected_min_level = 1 + TEST_DURATION // MINIMAL_BLOCK_DELAY + for client in sandbox.all_clients(): + level = client.get_level() + assert level >= expected_min_level + for i in range(level + 1): + if i > 1: + block_round = client.get_tenderbake_round(level=str(i)) + assert block_round == 0 diff --git a/tests_python/tests_012/test_tenderbake_long_dynamic_bake.py b/tests_python/tests_012/test_tenderbake_long_dynamic_bake.py new file mode 100644 index 000000000000..317504fecd72 --- /dev/null +++ b/tests_python/tests_012/test_tenderbake_long_dynamic_bake.py @@ -0,0 +1,237 @@ +import copy +import itertools +import random +import time +import subprocess +from datetime import datetime +from typing import List, Optional, Tuple, Dict, Iterable, Any + +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox +from client.client import Client +from . import protocol + +# This test runs NUM_NODES, and 3 bakers. It runs NUM_TEST_CYCLES test cycles +# (not to be confused for protocol cycle) where each cycle lasts +# TIME_BETWEEN_CYCLE seconds, for TEST_DURATION seconds. +# At each cycle, a random transaction is injected. Every CHECK_PROGRESS +# cycles, a client checks that the chain is progressing. +# It does so by polling the chain (and checking that the level is increasing) +# at most MAX_RETRY times, with a timeout of TIMEOUT seconds +# At the end of the test, checks that the chain has at least +# EXPECTED_LEVEL blocks + +random.seed(42) +KEYS = [f'bootstrap{i}' for i in range(1, 6)] +NEXT_KEY = itertools.cycle(KEYS) +NUM_NODES = 5 +NUM_TEST_CYCLES = 500 +TIME_BETWEEN_CYCLE = 2 +CHECK_PROGRESS = 10 +KILL_BAKER = 4 +TIMEOUT = 6 +MAX_RETRY = 6 +TEST_DURATION = 300 # duration of the main loop +MINIMAL_BLOCK_DELAY = 1 +DELAY_INCREMENT_PER_ROUND = 1 +MAX_LEVEL_DURATION = 6 # that is, decision expected in at most 3 rounds +EXPECTED_LEVEL = TEST_DURATION // MAX_LEVEL_DURATION + + +def random_op(client: Client) -> None: + sender = next(NEXT_KEY) + dest = random.choice([key for key in KEYS if key != sender]) + amount = random.randrange(10) + 1 + client.run(['transfer', str(amount), 'from', sender, 'to', dest]) + + +def setup_parameters() -> Dict[str, Any]: + proto_params = dict(protocol.TENDERBAKE_PARAMETERS) + parameters = copy.deepcopy(proto_params) + parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) + parameters['delay_increment_per_round'] = str(DELAY_INCREMENT_PER_ROUND) + parameters['consensus_threshold'] = ( + 2 * (parameters['consensus_threshold'] // 3) + 1 + ) + return parameters + + +def add_nodes( + sandbox: Sandbox, + node_peers_assoc: Iterable[Tuple[int, Optional[List[int]]]], +) -> None: + for node_id, peers in node_peers_assoc: + sandbox.add_node( + node_id, + params=constants.NODE_PARAMS, + log_levels=constants.TENDERBAKE_NODE_LOG_LEVELS, + peers=peers, + ) + + +def add_bakers(sandbox: Sandbox, nodes: Iterable[int]) -> None: + for node_id in nodes: + account = f'bootstrap{node_id + 1}' + sandbox.add_baker( + node_id, + [account], + proto=protocol.DAEMON, + log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, + ) + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +@pytest.mark.tenderbake +@pytest.mark.manual +class TestAllDaemonsWithOperations: + """Runs three baker, generates random op, and + add (or replace) new nodes dynamically. After a little while, + we kill the bakers and check everyone synchronize to the same head.""" + + def test_setup_network(self, sandbox: Sandbox): + parameters = setup_parameters() + add_nodes(sandbox, [(i, None) for i in range(NUM_NODES)]) + protocol.activate(sandbox.client(0), parameters=parameters) + add_bakers(sandbox, range(NUM_NODES - 1)) + + def test_wait_for_012(self, sandbox: Sandbox): + clients = sandbox.all_clients() + for client in clients: + proto = protocol.HASH + assert utils.check_protocol(client, proto) + + def test_network_gen_operations(self, sandbox: Sandbox, session): + dead_baker = NUM_NODES - 1 + cur_time = datetime.now() + cycle = 1 + while (datetime.now() - cur_time).total_seconds() < TEST_DURATION: + i = random.randrange(NUM_NODES) + client = sandbox.client(i) + try: + random_op(client) + except subprocess.CalledProcessError: + # some operations may be invalid, e.g. the client sends + # several operation with the same counter + print('# IGNORED INVALID OPERATION') + + # test chain progresses every X cycles + if cycle % CHECK_PROGRESS == 0: + client = sandbox.client(0) + + level_before = client.get_level() + current_time = datetime.now().strftime("%H:%M:%S") + print(current_time, "client level: ", level_before) + + retry = MAX_RETRY + while client.get_level() == level_before and retry >= 1: + if retry != MAX_RETRY: + current_time = datetime.now().strftime("%H:%M:%S") + print( + current_time, + "level did not increase, retries: ", + retry, + ) + time.sleep(TIMEOUT) + retry -= 1 + msg = f"chain level didn't increase for {MAX_RETRY*TIMEOUT}s" + assert retry, msg + + # cyclically kill bakers + if cycle % KILL_BAKER == 0: + baker = (dead_baker + 1) % NUM_NODES + current_time = datetime.now().strftime("%H:%M:%S") + print(current_time, "killing baker on node ", baker) + sandbox.rm_baker(baker, proto=protocol.DAEMON) + time.sleep(1) + # wake up the dead baker + current_time = datetime.now().strftime("%H:%M:%S") + print(current_time, "starting baker on node ", dead_baker) + sandbox.add_baker( + dead_baker, + [f'bootstrap{dead_baker+1}'], + proto=protocol.DAEMON, + log_levels=constants.TENDERBAKE_BAKER_LOG_LEVELS, + ) + # set the next baker to die + dead_baker = baker + time.sleep(TIME_BETWEEN_CYCLE) + cycle += 1 + session['dead_baker'] = dead_baker + + def test_kill_baker(self, sandbox: Sandbox, session): + for i in range(NUM_NODES): + if i != session['dead_baker']: + sandbox.rm_baker(i, proto=protocol.DAEMON) + + def test_synchronize(self, sandbox: Sandbox): + utils.synchronize(sandbox.all_clients()) + + def test_check_operations(self, sandbox: Sandbox): + min_level = min( + [client.get_level() for client in sandbox.all_clients()] + ) + heads_hash = set() + assert min_level >= EXPECTED_LEVEL + # check there is exactly one head + for client in sandbox.all_clients(): + block_hash = utils.get_block_hash(client, min_level) + heads_hash.add(block_hash) + assert len(heads_hash) == 1 + + +@pytest.mark.baker +@pytest.mark.multinode +@pytest.mark.slow +@pytest.mark.incremental +@pytest.mark.tenderbake +@pytest.mark.manual +class TestAllDaemonsWithOperationsRingTopo(TestAllDaemonsWithOperations): + """Runs three baker, generates random op, and + add (or replace) new nodes dynamically. After a little while, + we kill the bakers and check everyone synchronize to the same head. + Use a ring topology instead of the default clique""" + + def test_setup_network(self, sandbox: Sandbox): + parameters = setup_parameters() + add_nodes( + sandbox, + [ + (i, [(i + 1) % NUM_NODES, (NUM_NODES + i - 1) % NUM_NODES]) + for i in range(NUM_NODES) + ], + ) + protocol.activate(sandbox.client(0), parameters=parameters) + add_bakers(sandbox, range(NUM_NODES - 1)) + + def test_check_topology(self, sandbox: Sandbox): + for i in range(NUM_NODES): + client = sandbox.client(i) + res = client.p2p_stat() + num_connected = 0 + for point in res.points.values(): + num_connected += point.is_connected + assert num_connected == 2 + + # The calls to super() below allow to implicitly specifiy the test sequence + # by "pseudo-redefining" some inherited methods. Otherwise, there's no + # guarantee regarding when test_check_topology will be executed. + # + # pylint: disable=W0235 + def test_wait_for_012(self, sandbox: Sandbox): + super().test_wait_for_012(sandbox) + + def test_network_gen_operations(self, sandbox: Sandbox, session): + super().test_network_gen_operations(sandbox, session) + + def test_kill_baker(self, sandbox: Sandbox, session): + super().test_kill_baker(sandbox, session) + + def test_synchronize(self, sandbox: Sandbox): + utils.synchronize(sandbox.all_clients()) + + def test_check_operations(self, sandbox: Sandbox): + super().test_check_operations(sandbox) diff --git a/tests_python/tests_012/test_tenderbake_manual_bake.py b/tests_python/tests_012/test_tenderbake_manual_bake.py new file mode 100644 index 000000000000..e8297d0caad7 --- /dev/null +++ b/tests_python/tests_012/test_tenderbake_manual_bake.py @@ -0,0 +1,231 @@ +import copy +import time +import pytest +from tools import utils, constants +from launchers.sandbox import Sandbox +from . import protocol + + +MINIMAL_BLOCK_DELAY = 1 +TRANSFER_AMOUNT = 500 +INITIAL_BALANCE = 4000000.0 +FEE = 0.1 +ALL_ACOUNTS = [ + 'bootstrap1', + 'bootstrap2', + 'bootstrap3', + 'bootstrap4', + 'bootstrap5', +] + + +def find_account(identity): + for account, keys in constants.IDENTITIES.items(): + if keys['identity'] == identity: + return account + return None + + +def baker_at_round_0(client, level='head'): + if level == 'head': + arg = '' + else: + arg = f'?level={level}' + res = client.rpc( + 'get', f'/chains/main/blocks/head/helpers/baking_rights{arg}' + ) + delegate_id = res[0]['delegate'] + return find_account(delegate_id) + + +@pytest.mark.slow +@pytest.mark.tenderbake +@pytest.mark.incremental +@pytest.mark.tenderbake +class TestManualBake: + """Run a number of nodes, and bake, preendorse, and endorse using the + client commands""" + + def test_init(self, sandbox: Sandbox): + sandbox.add_node(0, params=constants.NODE_PARAMS) + + proto_params = dict(protocol.TENDERBAKE_PARAMETERS) + parameters = copy.deepcopy(proto_params) + parameters['minimal_block_delay'] = str(MINIMAL_BLOCK_DELAY) + parameters['delay_increment_per_round'] = '1' + protocol.activate( + sandbox.client(0), + parameters=proto_params, + activate_in_the_past=True, + ) + + def test_choose_players(self, sandbox: Sandbox, session: dict): + # we will make a transfer to someone who is not baking, to simplify + # the computation of the expected balance + client = sandbox.client(0) + session['level2_baker'] = baker_at_round_0(client) + session['level3_baker'] = baker_at_round_0(client, str(3)) + # recepient should also be different from bootstrap1 because + # bootstrap1 makes the transfer and we don't want a self-transfer + for account in ALL_ACOUNTS[1:]: + if account not in [ + session['level3_baker'], + session['level2_baker'], + ]: + session['recepient'] = account + break + + def test_bake(self, sandbox: Sandbox, session: dict): + client = sandbox.client(0) + client.propose([session['level2_baker']], ['--minimal-timestamp']) + + def test_deposit(self, sandbox: Sandbox, session: dict): + """Test balance of the receipient takes into account deposits taken at + level 2""" + client = sandbox.client(0) + balance = client.get_mutez_balance(session['recepient']) + recepient_pkh = constants.IDENTITIES[session['recepient']]['identity'] + deposit_mutez = client.frozen_deposits(recepient_pkh) + assert balance == utils.mutez_of_tez(INITIAL_BALANCE) - deposit_mutez + + def test_level(self, sandbox: Sandbox): + client = sandbox.client(0) + head = client.get_head() + assert head['header']['level'] == 2 + + def test_preendorse(self, sandbox: Sandbox): + client = sandbox.client(0) + client.run(['preendorse', 'for', 'bootstrap1', '--force']) + client.run(['preendorse', 'for', 'bootstrap2', '--force']) + client.run(['preendorse', 'for', 'bootstrap3', '--force']) + client.run(['preendorse', 'for', 'bootstrap4', '--force']) + + def test_transfer(self, sandbox: Sandbox, session: dict): + client = sandbox.client(0) + transfer = client.transfer( + TRANSFER_AMOUNT, + 'bootstrap1', + session['recepient'], + ['--fee', str(FEE), '--force-low-fee'], + ) + session["transfer_hash"] = transfer.operation_hash + + def test_endorse(self, sandbox: Sandbox): + client = sandbox.client(0) + client.run(['endorse', 'for', 'bootstrap1', '--force']) + client.run(['endorse', 'for', 'bootstrap2', '--force']) + client.run(['endorse', 'for', 'bootstrap3', '--force']) + client.run(['endorse', 'for', 'bootstrap4', '--force']) + + def test_transfer_is_pending(self, sandbox: Sandbox, session: dict): + client = sandbox.client(0) + pending_ops = client.rpc( + 'get', '/chains/main/mempool/pending_operations' + ) + # Checking the transfer hash is in pending_operaionts + assert any( + map( + lambda op: op["hash"] == session["transfer_hash"], + pending_ops["applied"], + ) + ) + + def test_bake_again(self, sandbox: Sandbox, session: dict): + print("Sleeping") + time.sleep(2 * MINIMAL_BLOCK_DELAY) + client = sandbox.client(0) + client.propose([session['level3_baker']], ['--minimal-timestamp']) + client.get_head() + + def test_level_again(self, sandbox: Sandbox): + client = sandbox.client(0) + head = client.get_head() + assert head['header']['level'] == 3 + + def test_balance(self, sandbox: Sandbox, session: dict): + client = sandbox.client(0) + recepient_pkh = constants.IDENTITIES[session['recepient']]['identity'] + deposit_mutez = client.frozen_deposits(recepient_pkh) + balance = client.get_mutez_balance(session['recepient']) + assert ( + balance + == utils.mutez_of_tez(INITIAL_BALANCE + TRANSFER_AMOUNT) + - deposit_mutez + ) + + def test_bake_fail(self, sandbox: Sandbox): + """Baking with not enough endorsing power should fail in Tenderbake. + + This is the case in sandboxed mode since a lone bootstrap account does + not have enough slots in the default settings. + + """ + client = sandbox.client(0) + error_pattern = 'Delegates do not have enough voting power.' + with utils.assert_run_failure(error_pattern): + utils.bake(client, bake_for='bootstrap1') + + +@pytest.mark.incremental +@pytest.mark.tenderbake +class TestManualBakeNullThreshold: + """Run a number of nodes, and bake when no endorsements are expected""" + + def test_init(self, sandbox: Sandbox): + sandbox.add_node(0, params=constants.NODE_PARAMS) + proto_params = protocol.TENDERBAKE_PARAMETERS + parameters = copy.deepcopy(proto_params) + parameters['consensus_threshold'] = 0 + + protocol.activate( + sandbox.client(0), parameters=parameters, activate_in_the_past=True + ) + + def test_choose_players(self, sandbox: Sandbox, session: dict): + # we will make a transfer to someone who is not baking, to simplify + # the computation of the expected balance + client = sandbox.client(0) + session['level2_baker'] = baker_at_round_0(client) + session['level3_baker'] = baker_at_round_0(client, str(3)) + # recepient should also be different from bootstrap1 because + # bootstrap1 makes the transfer and we don't want a self-transfer + for account in ALL_ACOUNTS[1:]: + if account not in [ + session['level3_baker'], + session['level2_baker'], + ]: + session['recepient'] = account + break + + def test_bake(self, sandbox: Sandbox, session: dict): + client = sandbox.client(0) + client.propose([session['level2_baker']], ['--minimal-timestamp']) + + def test_level(self, sandbox: Sandbox): + client = sandbox.client(0) + level = client.get_level() + assert level == 2 + + def test_transfer(self, sandbox: Sandbox, session: dict): + client = sandbox.client(0) + client.transfer(TRANSFER_AMOUNT, 'bootstrap1', session['recepient']) + + def test_bake_again(self, sandbox: Sandbox, session: dict): + client = sandbox.client(0) + client.propose([session['level3_baker']], ['--minimal-timestamp']) + + def test_level_again(self, sandbox: Sandbox): + client = sandbox.client(0) + head = client.get_head() + assert head['header']['level'] == 3 + + def test_balance(self, sandbox: Sandbox, session: dict): + client = sandbox.client(0) + balance = client.get_mutez_balance(session['recepient']) + recepient_pkh = constants.IDENTITIES[session['recepient']]['identity'] + deposit_mutez = client.frozen_deposits(recepient_pkh) + assert ( + balance + == utils.mutez_of_tez(INITIAL_BALANCE + TRANSFER_AMOUNT) + - deposit_mutez + ) diff --git a/tests_python/tests_012/test_tls.py b/tests_python/tests_012/test_tls.py new file mode 100755 index 000000000000..475d786823bb --- /dev/null +++ b/tests_python/tests_012/test_tls.py @@ -0,0 +1,23 @@ +import pytest +from tools import constants +from client.client import Client + + +@pytest.fixture(scope="class") +def client(sandbox): + sandbox.add_node( + 0, + use_tls=(constants.TEZOS_CRT, constants.TEZOS_KEY), + params=constants.NODE_PARAMS, + ) + yield sandbox.client(0) + + +@pytest.mark.vote +@pytest.mark.incremental +@pytest.mark.skip(reason="requires to install a custom CA") +class TestTLS: + """Test voting protocol with manual baking, 4 blocks per voting period.""" + + def test_bootstrapped(self, client: Client): + assert client.bootstrapped() diff --git a/tests_python/tests_012/test_voting.py b/tests_python/tests_012/test_voting.py new file mode 100644 index 000000000000..dc8b38ba0331 --- /dev/null +++ b/tests_python/tests_012/test_voting.py @@ -0,0 +1,249 @@ +import copy +import shutil +import pytest +from client.client import Client +from tools import constants, paths, utils +from . import protocol + + +@pytest.fixture(scope="class") +def client(sandbox): + """One node, 4 blocks per voting period.""" + proto_params = dict(protocol.PARAMETERS) + parameters = copy.deepcopy(proto_params) + parameters["blocks_per_voting_period"] = 4 + parameters['consensus_threshold'] = 0 + sandbox.add_node(0, params=constants.NODE_PARAMS) + protocol.activate(sandbox.client(0), parameters, activate_in_the_past=True) + yield sandbox.client(0) + + +@pytest.mark.vote +@pytest.mark.incremental +class TestManualBaking: + """Test voting protocol with manual baking, 4 blocks per voting period.""" + + def test_current_period(self, client: Client): + period_info = client.get_current_period() + level = client.get_current_level() + assert level["level_position"] == 0 + assert period_info["voting_period"]["index"] == 0 + assert period_info["voting_period"]["kind"] == "proposal" + assert period_info["voting_period"]["start_position"] == 0 + assert period_info["position"] == 0 + assert period_info["remaining"] == 3 + + def test_succ_period(self, client: Client): + period_info = client.get_succ_period() + assert period_info["voting_period"]["index"] == 0 + assert period_info["voting_period"]["kind"] == "proposal" + assert period_info["voting_period"]["start_position"] == 0 + assert period_info["position"] == 1 + assert period_info["remaining"] == 2 + + def test_level_info_offset(self, client: Client): + level = client.get_current_level(offset=1) + assert level["level_position"] == 1 + level = client.get_current_level(offset=4) + assert level["level_position"] == 4 + level = client.get_current_level(offset=10) + assert level["level_position"] == 10 + + def test_bake_two_blocks(self, client: Client): + utils.bake(client) + utils.bake(client) + period_info = client.get_current_period() + level = client.get_current_level() + assert level["level_position"] == 2 + assert period_info["voting_period"]["index"] == 0 + assert period_info["voting_period"]["kind"] == "proposal" + assert period_info["voting_period"]["start_position"] == 0 + assert period_info["position"] == 2 + assert period_info["remaining"] == 1 + + def test_last_block_of_proposal_period(self, client: Client): + # last block of voting period 0 + utils.bake(client) + period_info = client.get_current_period() + assert period_info["voting_period"]["index"] == 0 + assert period_info["voting_period"]["kind"] == "proposal" + assert period_info["voting_period"]["start_position"] == 0 + assert period_info["position"] == 3 + assert period_info["remaining"] == 0 + + def test_listing_is_not_empty(self, client: Client): + assert client.get_listings() != [] + + def test_inject_proto1(self, client: Client, tmpdir): + proto_fp = ( + f'{paths.TEZOS_HOME}/src/bin_client/test/proto_test_injection' + ) + + for i in range(1, 4): + proto = f'{tmpdir}/proto{i}' + shutil.copytree(proto_fp, proto) + main = f'{proto}/main.ml' + print(main) + with open(main, "a") as file: + file.write(f'(* {i} *)') + client.inject_protocol(proto) + + # this is maybe useless because the protocol already knows more than 4 + # protocol + def test_known_protocol(self, client: Client, session: dict): + protos = client.list_protocols() + assert len(protos) >= 4 + session['protos'] = protos[:4] + + def test_proposals_is_empty(self, client: Client): + assert client.get_proposals() == [] + + def test_show_voting_period2(self, client: Client): + client.show_voting_period() + + def test_bake_first_block_of_proposal_period(self, client: Client): + # using the client it's not possible to add voting operation on the + # first block of a voting period. This is to be fixed in a future + # protocol + utils.bake(client) + period_info = client.get_current_period() + assert period_info["voting_period"]["index"] == 1 + assert period_info["voting_period"]["kind"] == "proposal" + assert period_info["voting_period"]["start_position"] == 4 + assert period_info["position"] == 0 + assert period_info["remaining"] == 3 + + def test_submit_proposals(self, client: Client, session: dict): + protos = session['protos'] + client.submit_proposals('bootstrap1', [protos[0]]) + client.submit_proposals('bootstrap2', [protos[0], protos[1]]) + client.submit_proposals('bootstrap3', [protos[1]]) + client.submit_proposals('bootstrap4', [protos[2]]) + + def test_bake_one_block(self, client: Client): + utils.bake(client) + period_info = client.get_current_period() + assert period_info["voting_period"]["index"] == 1 + assert period_info["voting_period"]["kind"] == "proposal" + assert period_info["voting_period"]["start_position"] == 4 + assert period_info["position"] == 1 + assert period_info["remaining"] == 2 + + def test_proposals_is_not_empty(self, client: Client): + assert client.get_proposals() != [] + + def test_bake_until_prev_last_block_of_voting_period(self, client: Client): + utils.bake(client) + period_info = client.get_current_period() + assert period_info["position"] == 2 + assert period_info["remaining"] == 1 + + def test_break_proposal_tie(self, client: Client, session: dict): + protos = session['protos'] + client.submit_proposals('bootstrap4', [protos[1]]) + + def test_bake_last_block_of_proposal_period(self, client: Client): + utils.bake(client) + period_info = client.get_current_period() + metadata = client.get_metadata() + level = client.get_current_level() + level_info = metadata["level_info"] + meta_period_info = metadata["voting_period_info"] + expected_commitment = level["expected_commitment"] + assert level["level"] == level_info["level"] + assert level["level_position"] == level_info["level_position"] + assert level["cycle"] == level_info["cycle"] + assert level["cycle_position"] == level_info["cycle_position"] + assert expected_commitment == level_info["expected_commitment"] + assert level["level_position"] == 7 + assert period_info["voting_period"]["index"] == 1 + assert period_info["voting_period"]["kind"] == "proposal" + assert period_info["voting_period"]["start_position"] == 4 + assert period_info["position"] == 3 + assert period_info["remaining"] == 0 + assert meta_period_info == period_info + + def test_listing_is_not_empty2(self, client: Client): + assert client.get_listings() != [] + + def test_current_proposal(self, client: Client, session: dict): + expected = session['protos'][1] + assert expected == client.get_current_proposal() + + def test_bake_first_block_of_cooldown_vote_period(self, client: Client): + # using the client it's not possible to add voting operation on the + # first block of a voting period. This is to be fixed in a future + # protocol + utils.bake(client) + period_info = client.get_current_period() + assert period_info["voting_period"]["index"] == 2 + assert period_info["voting_period"]["kind"] == "exploration" + assert period_info["voting_period"]["start_position"] == 8 + assert period_info["position"] == 0 + assert period_info["remaining"] == 3 + + def test_submit_ballot(self, client: Client, session: dict): + # next block is going to be of 'exploration' kind + proto = session['protos'][1] + for i in range(1, 4): + client.submit_ballot(f'bootstrap{i}', proto, 'yay') + + def test_bake_until_prev_last_block_of_voting_period2(self, client: Client): + utils.bake(client) + utils.bake(client) + period_info = client.get_current_period() + level = client.get_current_level() + assert level["level_position"] == 10 + assert period_info["voting_period"]["index"] == 2 + assert period_info["voting_period"]["kind"] == "exploration" + assert period_info["voting_period"]["start_position"] == 8 + assert period_info["position"] == 2 + assert period_info["remaining"] == 1 + + def test_submit_failing_ballot(self, client: Client, session: dict): + proto = session['protos'][1] + client.submit_ballot(f'bootstrap{4}', proto, 'nay') + + def test_level_info_offset2(self, client: Client): + level = client.get_current_level(block='head~1') + assert level["level_position"] == 9 + level = client.get_current_level(block='head~4') + assert level["level_position"] == 6 + level = client.get_current_level(block='head~10') + assert level["level_position"] == 0 + + def test_bake_first_block_of_new_proposal_period(self, client: Client): + utils.bake(client) + # Because of the current hack in proposal here we make sure we get the + # correct value + level = client.get_current_level() + period_info = client.get_current_period() + metadata = client.get_metadata() + level_info = metadata["level_info"] + meta_period_info = metadata["voting_period_info"] + expected_commitment = level["expected_commitment"] + assert level["level"] == level_info["level"] + assert level["level_position"] == level_info["level_position"] + assert level["cycle"] == level_info["cycle"] + assert level["cycle_position"] == level_info["cycle_position"] + assert expected_commitment == level_info["expected_commitment"] + assert level["level_position"] == 11 + assert period_info["voting_period"]["index"] == 2 + assert period_info["voting_period"]["kind"] == "exploration" + assert period_info["voting_period"]["start_position"] == 8 + assert period_info["position"] == 3 + assert period_info["remaining"] == 0 + assert meta_period_info == period_info + utils.bake(client) + period_info = client.get_current_period() + level = client.get_current_level() + assert level["level_position"] == 12 + assert period_info["voting_period"]["index"] == 3 + assert period_info["voting_period"]["kind"] == "proposal" + assert period_info["voting_period"]["start_position"] == 12 + assert period_info["position"] == 0 + assert period_info["remaining"] == 3 + assert client.get_listings() != '[]' + # strange behavior here, RPC returns 'null' on stderr + assert client.get_current_proposal() is None + assert client.get_ballot_list() == [] diff --git a/tests_python/tests_012/test_voting_full.py b/tests_python/tests_012/test_voting_full.py new file mode 100644 index 000000000000..00d07d84b9d1 --- /dev/null +++ b/tests_python/tests_012/test_voting_full.py @@ -0,0 +1,217 @@ +import time + +import subprocess +import pytest + +from launchers.sandbox import Sandbox +from client.client import Client +from tools import utils, constants +from . import protocol + +BLOCKS_PER_VOTING_PERIOD = 8 +OFFSET = int(BLOCKS_PER_VOTING_PERIOD / 2) +POLLING_TIME = 5 +BAKING_RATE = 1 +NUM_NODES = 5 +BAKER = "bootstrap1" +ERROR_PATTERN = r"Uncaught|registered|error" + +PROTO_A = protocol.PREV_HASH +PROTO_A_DAEMON = protocol.PREV_DAEMON +PROTO_A_PATH = f"proto_{PROTO_A_DAEMON.replace('-','_')}" +PROTO_B = protocol.HASH +PROTO_B_DAEMON = protocol.DAEMON + + +def client_get_current_period_kind(client) -> dict: + res = client.get_current_period() + return res['voting_period']['kind'] + + +def tenderbake(client: Client): + """Call to 'bake for' that uses the multi-account command for Tenderbake. + + In particular, this allows to never get a 'Delegates do not have enough + voting power' error in sandboxed mode since we bake for all known accounts + (aka all bootstrap accounts) by default in method multibake. + + """ + client.multibake(args=['--minimal-timestamp']) + + +def bake_n_blocks(client: Client, baker: str, n_blocks: int): + for _ in range(n_blocks): + utils.bake(client, bake_for=baker) + + +def bake_until_next_voting_period(client: Client, baker: str, offset: int = 0): + period_info = client.get_current_period() + remaining_blocks = period_info["remaining"] + # if offset is the constant OFFSET, it will take us to + # the middle of the next voting period + bake_n_blocks(client, baker, 1 + remaining_blocks + offset) + + +@pytest.mark.timeout(60) +def wait_until_level(clients, level): + print(f"Waiting until {level}") + for client in clients: + while client.get_level() < level: + time.sleep(1) + + +def assert_all_clients_in_period(clients, period): + for client in clients: + assert client_get_current_period_kind(client) == period + + +@pytest.mark.vote +@pytest.mark.slow +@pytest.mark.baker +@pytest.mark.incremental +class TestVotingFull: + """This tests the migration from PROTO_A to PROTO_B using the voting + procedure. PROTO_A and PROTO_B are the previous and + respectively the current protocol as given by the 'protocol' + module. + + This test advances through all the periods of the voting procedure + until the last one (adoption), by manually baking the right number + of blocks. Once the adoption period is reached, a baker takes over + to bake the remaining blocks of the period. From there the baker + for the next protocol, which was started at the beginning of the + test, takes over. (Bakers are used to make the test more + realistic. However, to be sure that proposals and ballots are + injected at the right moment, manual baking is used instead.) + + This test differs in the following aspects from test_voting.py: + - it uses more nodes, not just one + - it goes through all voting periods, not just the first two + - it uses bakers + - it uses already registered protocols, instead of injecting a + new dummy protocol + """ + + def test_add_initial_nodes(self, sandbox: Sandbox): + for i in range(NUM_NODES): + sandbox.add_node(i, params=constants.NODE_PARAMS) + + def test_activate_proto_a(self, sandbox: Sandbox): + parameters = protocol.get_parameters(protocol.Protocol.PREV) + parameters["blocks_per_voting_period"] = BLOCKS_PER_VOTING_PERIOD + utils.activate_protocol( + sandbox.client(0), + PROTO_A, + parameters=parameters, + activate_in_the_past=True, + ) + + # def test_add_bakers(self, sandbox: Sandbox): + # """Add a baker per node""" + # sandbox.add_baker( + # 1, [f"bootstrap{i}" for i in range(1, 6)], proto=PROTO_B_DAEMON + # ) + + def test_client_knows_proto_b(self, sandbox: Sandbox): + client = sandbox.client(0) + protos = client.list_protocols() + assert PROTO_B in protos + + def test_proposal_period(self, sandbox: Sandbox): + assert_all_clients_in_period(sandbox.all_clients(), 'proposal') + + def test_submit_proto_b_proposal(self, sandbox): + client = sandbox.client(0) + proposals = client.submit_proposals(BAKER, [PROTO_B]) + # bake a block for the submit proposal to be included + bake_n_blocks(client, BAKER, 1) + client.wait_for_inclusion(proposals.operation_hash, check_previous=1) + + def test_check_proto_b_proposed(self, sandbox: Sandbox): + clients = sandbox.all_clients() + wait_until_level(clients, sandbox.client(0).get_level()) + for client in clients: + proposals = client.get_proposals() + assert PROTO_B in [proto for (proto, _) in proposals] + + def test_wait_for_exploration_period(self, sandbox: Sandbox): + client = sandbox.client(0) + bake_until_next_voting_period(client, BAKER, OFFSET) + clients = sandbox.all_clients() + wait_until_level(clients, client.get_level()) + assert_all_clients_in_period(clients, 'exploration') + + def test_delegates_vote_proto_b(self, sandbox: Sandbox): + client = sandbox.client(0) + listings = client.get_listings() + # submit ballot for all bakers with listings + for listing in listings: + client.submit_ballot(listing["pkh"], PROTO_B, 'yay') + + def test_wait_for_cooldown(self, sandbox: Sandbox): + client = sandbox.client(0) + bake_until_next_voting_period(client, BAKER, OFFSET) + clients = sandbox.all_clients() + wait_until_level(clients, client.get_level()) + assert_all_clients_in_period(clients, 'cooldown') + + def test_wait_for_promotion_period(self, sandbox: Sandbox): + client = sandbox.client(0) + bake_until_next_voting_period(client, BAKER, OFFSET) + clients = sandbox.all_clients() + wait_until_level(clients, client.get_level()) + assert_all_clients_in_period(clients, 'promotion') + + def test_vote_in_promotion_phase(self, sandbox: Sandbox): + client = sandbox.client(0) + listings = client.get_listings() + for listing in listings: + client.submit_ballot(listing["pkh"], PROTO_B, 'yay') + + def test_wait_for_adoption(self, sandbox: Sandbox): + client = sandbox.client(0) + bake_until_next_voting_period(client, BAKER) + clients = sandbox.all_clients() + wait_until_level(clients, client.get_level()) + assert_all_clients_in_period(clients, 'adoption') + + @pytest.mark.timeout(60) + def test_all_nodes_run_proto_b(self, sandbox: Sandbox): + # we let a PROTO_A baker bake the last blocks of PROTO_A + # sandbox.add_baker( + # 0, [f"bootstrap{i}" for i in range(1, 6)], proto=PROTO_A_DAEMON + # ) + # for i in range(1,NUM_NODES): + # sandbox.add_baker( + # i, [f"bootstrap{i}"], proto=PROTO_B_DAEMON + # ) + clients = sandbox.all_clients() + client = clients[0] + utils.bake(client, bake_for="bootstrap2") + all_have_proto_b = False + while not all_have_proto_b: + try: + utils.bake(client, bake_for="bootstrap2") + except subprocess.CalledProcessError: + # A fatal error is raised when we do not have enough endorsing + # power. + # This is typical of a simple bake for call in Tenderbake + # Therefore this means we actually have migrated to Tenderbake + # Let's use a baking call that is sure to pass + tenderbake(client) + # either succeeds out of the loop or fails due to the timeout header + client_protocols = [client.get_protocol() for c in clients] + all_have_proto_b = all(p == PROTO_B for p in client_protocols) + time.sleep(POLLING_TIME) + + def test_new_chain_progress(self, sandbox: Sandbox): + # sandbox.rm_baker(0, proto=PROTO_A_DAEMON) + client = sandbox.client(0) + level_before = client.get_level(chain='main') + tenderbake(client) + print(f"level before {level_before}") + assert utils.check_level_greater_than(client, level_before + 1) + + @pytest.mark.xfail + def test_check_logs(self, sandbox: Sandbox): + assert utils.check_logs(sandbox.logs, ERROR_PATTERN) diff --git a/tests_python/tests_alpha/protocol.py b/tests_python/tests_alpha/protocol.py index 06e52dccd1cc..34166afbfda8 100644 --- a/tests_python/tests_alpha/protocol.py +++ b/tests_python/tests_alpha/protocol.py @@ -14,9 +14,9 @@ TENDERBAKE_PARAMETERS['consensus_committee_size'] = 67 FOLDER = constants.ALPHA_FOLDER -PREV_HASH = constants.HANGZHOU -PREV_DAEMON = constants.HANGZHOU_DAEMON -PREV_PARAMETERS = constants.HANGZHOU_PARAMETERS +PREV_HASH = constants.ITHACA +PREV_DAEMON = constants.ITHACA_DAEMON +PREV_PARAMETERS = constants.ITHACA_PARAMETERS def activate( diff --git a/tests_python/tools/constants.py b/tests_python/tools/constants.py index f398c3dd430e..3920bdebb17f 100644 --- a/tests_python/tools/constants.py +++ b/tests_python/tools/constants.py @@ -102,6 +102,11 @@ HANGZHOU_DAEMON = "011-PtHangz2" HANGZHOU_FOLDER = "proto_011_PtHangz2" HANGZHOU_PARAMETERS = get_parameters(HANGZHOU_FOLDER) +ITHACA = "PsiThaCaT47Zboaw71QWScM8sXeMM7bbQFncK9FLqYc6EKdpjVP" +ITHACA_DAEMON = "012-PsiThaCa" +ITHACA_FOLDER = "proto_012_PsiThaCa" +ITHACA_PARAMETERS = get_parameters(ITHACA_FOLDER) + TEZOS_CRT = """ Certificate: Data: -- GitLab From 473326666b1b1fe84c48fdb71dcd708050a6066c Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Thu, 16 Dec 2021 23:58:29 +0000 Subject: [PATCH 07/10] Build: link Ithaca --- .gitlab/ci/unittest.yml | 14 +++++++++++++- active_protocol_versions | 1 + src/bin_client/dune | 12 ++++++++++++ src/bin_client/tezos-client.opam | 3 +++ src/bin_codec/dune | 4 ++++ src/bin_codec/tezos-codec.opam | 1 + src/bin_node/dune | 8 ++++++++ src/bin_node/tezos-node.opam | 2 ++ src/bin_proxy_server/dune | 8 ++++++++ src/bin_proxy_server/tezos-proxy-server.opam | 2 ++ 10 files changed, 54 insertions(+), 1 deletion(-) diff --git a/.gitlab/ci/unittest.yml b/.gitlab/ci/unittest.yml index b32082ae4d84..a0331401eb37 100644 --- a/.gitlab/ci/unittest.yml +++ b/.gitlab/ci/unittest.yml @@ -75,6 +75,19 @@ unit:011_PtHangz2: src/proto_011_PtHangz2/lib_client.test_proto src/proto_011_PtHangz2/lib_protocol.test_proto +unit:012_PsiThaCa: + extends: + - .unit_test_template_x86_64 + - .template__coverage_files + variables: + MAKE_TARGETS: > + src/proto_012_PsiThaCa/lib_benchmark/lib_benchmark_type_inference.test_proto + src/proto_012_PsiThaCa/lib_benchmark.test_proto + src/proto_012_PsiThaCa/lib_client.test_proto + src/proto_012_PsiThaCa/lib_plugin.test_proto + src/proto_012_PsiThaCa/lib_protocol.test_proto + src/proto_012_PsiThaCa/lib_delegate.test_proto + unit:alpha: extends: - .unit_test_template_x86_64 @@ -87,7 +100,6 @@ unit:alpha: src/proto_alpha/lib_plugin.test_proto src/proto_alpha/lib_protocol.test_proto src/proto_alpha/lib_delegate.test_proto - unit:non-proto-x86_64: extends: - .unit_test_template_x86_64 diff --git a/active_protocol_versions b/active_protocol_versions index ec3fe7cdd955..542357a96b79 100644 --- a/active_protocol_versions +++ b/active_protocol_versions @@ -1,3 +1,4 @@ 010-PtGRANAD 011-PtHangz2 +012-PsiThaCa alpha diff --git a/src/bin_client/dune b/src/bin_client/dune index d7541c171d4b..2bb7c9c4d7d5 100644 --- a/src/bin_client/dune +++ b/src/bin_client/dune @@ -68,6 +68,9 @@ (select void_for_linking-tezos-client-011-PtHangz2-commands-registration from (tezos-client-011-PtHangz2-commands-registration -> void_for_linking-tezos-client-011-PtHangz2-commands-registration.empty) (-> void_for_linking-tezos-client-011-PtHangz2-commands-registration.empty)) + (select void_for_linking-tezos-client-012-PsiThaCa-commands-registration from + (tezos-client-012-PsiThaCa-commands-registration -> void_for_linking-tezos-client-012-PsiThaCa-commands-registration.empty) + (-> void_for_linking-tezos-client-012-PsiThaCa-commands-registration.empty)) (select void_for_linking-tezos-client-alpha-commands-registration from (tezos-client-alpha-commands-registration -> void_for_linking-tezos-client-alpha-commands-registration.empty) (-> void_for_linking-tezos-client-alpha-commands-registration.empty)) @@ -82,6 +85,9 @@ (select void_for_linking-tezos-baking-011-PtHangz2-commands-registration from (tezos-baking-011-PtHangz2-commands.registration -> void_for_linking-tezos-baking-011-PtHangz2-commands-registration.empty) (-> void_for_linking-tezos-baking-011-PtHangz2-commands-registration.empty)) + (select void_for_linking-tezos-baking-012-PsiThaCa-commands-registration from + (tezos-baking-012-PsiThaCa-commands.registration -> void_for_linking-tezos-baking-012-PsiThaCa-commands-registration.empty) + (-> void_for_linking-tezos-baking-012-PsiThaCa-commands-registration.empty)) (select void_for_linking-tezos-baking-alpha-commands-registration from (tezos-baking-alpha-commands.registration -> void_for_linking-tezos-baking-alpha-commands-registration.empty) (-> void_for_linking-tezos-baking-alpha-commands-registration.empty)) @@ -100,6 +106,9 @@ (select void_for_linking-tezos-protocol-plugin-011-PtHangz2 from (tezos-protocol-plugin-011-PtHangz2 -> void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty) (-> void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty)) + (select void_for_linking-tezos-protocol-plugin-012-PsiThaCa from + (tezos-protocol-plugin-012-PsiThaCa -> void_for_linking-tezos-protocol-plugin-012-PsiThaCa.empty) + (-> void_for_linking-tezos-protocol-plugin-012-PsiThaCa.empty)) (select void_for_linking-tezos-protocol-plugin-alpha from (tezos-protocol-plugin-alpha -> void_for_linking-tezos-protocol-plugin-alpha.empty) (-> void_for_linking-tezos-protocol-plugin-alpha.empty))) @@ -133,15 +142,18 @@ (write-file void_for_linking-tezos-client-009-PsFLoren-commands-registration.empty "") (write-file void_for_linking-tezos-client-010-PtGRANAD-commands-registration.empty "") (write-file void_for_linking-tezos-client-011-PtHangz2-commands-registration.empty "") + (write-file void_for_linking-tezos-client-012-PsiThaCa-commands-registration.empty "") (write-file void_for_linking-tezos-client-alpha-commands-registration.empty "") (write-file void_for_linking-tezos-baking-010-PtGRANAD-commands-registration.empty "") (write-file void_for_linking-tezos-baking-011-PtHangz2-commands-registration.empty "") + (write-file void_for_linking-tezos-baking-012-PsiThaCa-commands-registration.empty "") (write-file void_for_linking-tezos-baking-alpha-commands-registration.empty "") (write-file void_for_linking-tezos-protocol-plugin-007-PsDELPH1.empty "") (write-file void_for_linking-tezos-protocol-plugin-008-PtEdo2Zk.empty "") (write-file void_for_linking-tezos-protocol-plugin-009-PsFLoren.empty "") (write-file void_for_linking-tezos-protocol-plugin-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty "") + (write-file void_for_linking-tezos-protocol-plugin-012-PsiThaCa.empty "") (write-file void_for_linking-tezos-protocol-plugin-alpha.empty "")))) (install diff --git a/src/bin_client/tezos-client.opam b/src/bin_client/tezos-client.opam index 8e71ec5f0a82..9c4387788baf 100644 --- a/src/bin_client/tezos-client.opam +++ b/src/bin_client/tezos-client.opam @@ -34,15 +34,18 @@ depopts: [ "tezos-client-009-PsFLoren-commands-registration" "tezos-client-010-PtGRANAD-commands-registration" "tezos-client-011-PtHangz2-commands-registration" + "tezos-client-012-PsiThaCa-commands-registration" "tezos-client-alpha-commands-registration" "tezos-baking-010-PtGRANAD-commands" "tezos-baking-011-PtHangz2-commands" + "tezos-baking-012-PsiThaCa-commands" "tezos-baking-alpha-commands" "tezos-protocol-plugin-007-PsDELPH1" "tezos-protocol-plugin-008-PtEdo2Zk" "tezos-protocol-plugin-009-PsFLoren" "tezos-protocol-plugin-010-PtGRANAD" "tezos-protocol-plugin-011-PtHangz2" + "tezos-protocol-plugin-012-PsiThaCa" "tezos-protocol-plugin-alpha" ] build: [ diff --git a/src/bin_codec/dune b/src/bin_codec/dune index aee18a1a369a..6dd8f266d59f 100644 --- a/src/bin_codec/dune +++ b/src/bin_codec/dune @@ -37,6 +37,9 @@ (select void_for_linking-tezos-client-011-PtHangz2 from (tezos-client-011-PtHangz2 -> void_for_linking-tezos-client-011-PtHangz2.empty) (-> void_for_linking-tezos-client-011-PtHangz2.empty)) + (select void_for_linking-tezos-client-012-PsiThaCa from + (tezos-client-012-PsiThaCa -> void_for_linking-tezos-client-012-PsiThaCa.empty) + (-> void_for_linking-tezos-client-012-PsiThaCa.empty)) (select void_for_linking-tezos-client-alpha from (tezos-client-alpha -> void_for_linking-tezos-client-alpha.empty) (-> void_for_linking-tezos-client-alpha.empty))) @@ -61,4 +64,5 @@ (write-file void_for_linking-tezos-client-009-PsFLoren.empty "") (write-file void_for_linking-tezos-client-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-client-011-PtHangz2.empty "") + (write-file void_for_linking-tezos-client-012-PsiThaCa.empty "") (write-file void_for_linking-tezos-client-alpha.empty "")))) diff --git a/src/bin_codec/tezos-codec.opam b/src/bin_codec/tezos-codec.opam index e85861cd6a40..33c18328f197 100644 --- a/src/bin_codec/tezos-codec.opam +++ b/src/bin_codec/tezos-codec.opam @@ -24,6 +24,7 @@ depopts: [ "tezos-client-009-PsFLoren" "tezos-client-010-PtGRANAD" "tezos-client-011-PtHangz2" + "tezos-client-012-PsiThaCa" "tezos-client-alpha" ] build: [ diff --git a/src/bin_node/dune b/src/bin_node/dune index dbeca49a8e80..cd167568c56f 100644 --- a/src/bin_node/dune +++ b/src/bin_node/dune @@ -89,6 +89,9 @@ (select void_for_linking-tezos-embedded-protocol-011-PtHangz2 from (tezos-embedded-protocol-011-PtHangz2 -> void_for_linking-tezos-embedded-protocol-011-PtHangz2.empty) (-> void_for_linking-tezos-embedded-protocol-011-PtHangz2.empty)) + (select void_for_linking-tezos-embedded-protocol-012-PsiThaCa from + (tezos-embedded-protocol-012-PsiThaCa -> void_for_linking-tezos-embedded-protocol-012-PsiThaCa.empty) + (-> void_for_linking-tezos-embedded-protocol-012-PsiThaCa.empty)) (select void_for_linking-tezos-embedded-protocol-alpha from (tezos-embedded-protocol-alpha -> void_for_linking-tezos-embedded-protocol-alpha.empty) (-> void_for_linking-tezos-embedded-protocol-alpha.empty)) @@ -107,6 +110,9 @@ (select void_for_linking-tezos-protocol-plugin-011-PtHangz2-registerer from (tezos-protocol-plugin-011-PtHangz2-registerer -> void_for_linking-tezos-protocol-plugin-011-PtHangz2-registerer.empty) (-> void_for_linking-tezos-protocol-plugin-011-PtHangz2-registerer.empty)) + (select void_for_linking-tezos-protocol-plugin-012-PsiThaCa-registerer from + (tezos-protocol-plugin-012-PsiThaCa-registerer -> void_for_linking-tezos-protocol-plugin-012-PsiThaCa-registerer.empty) + (-> void_for_linking-tezos-protocol-plugin-012-PsiThaCa-registerer.empty)) (select void_for_linking-tezos-protocol-plugin-alpha-registerer from (tezos-protocol-plugin-alpha-registerer -> void_for_linking-tezos-protocol-plugin-alpha-registerer.empty) (-> void_for_linking-tezos-protocol-plugin-alpha-registerer.empty))) @@ -149,12 +155,14 @@ (write-file void_for_linking-tezos-embedded-protocol-009-PsFLoren.empty "") (write-file void_for_linking-tezos-embedded-protocol-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-embedded-protocol-011-PtHangz2.empty "") + (write-file void_for_linking-tezos-embedded-protocol-012-PsiThaCa.empty "") (write-file void_for_linking-tezos-embedded-protocol-alpha.empty "") (write-file void_for_linking-tezos-protocol-plugin-007-PsDELPH1-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-008-PtEdo2Zk-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-009-PsFLoren-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-010-PtGRANAD-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-011-PtHangz2-registerer.empty "") + (write-file void_for_linking-tezos-protocol-plugin-012-PsiThaCa-registerer.empty "") (write-file void_for_linking-tezos-protocol-plugin-alpha-registerer.empty "")))) (install diff --git a/src/bin_node/tezos-node.opam b/src/bin_node/tezos-node.opam index 31e2fb5b2b2b..8c0c3b9efa1f 100644 --- a/src/bin_node/tezos-node.opam +++ b/src/bin_node/tezos-node.opam @@ -44,12 +44,14 @@ depopts: [ "tezos-embedded-protocol-009-PsFLoren" "tezos-embedded-protocol-010-PtGRANAD" "tezos-embedded-protocol-011-PtHangz2" + "tezos-embedded-protocol-012-PsiThaCa" "tezos-embedded-protocol-alpha" "tezos-protocol-plugin-007-PsDELPH1-registerer" "tezos-protocol-plugin-008-PtEdo2Zk-registerer" "tezos-protocol-plugin-009-PsFLoren-registerer" "tezos-protocol-plugin-010-PtGRANAD-registerer" "tezos-protocol-plugin-011-PtHangz2-registerer" + "tezos-protocol-plugin-012-PsiThaCa-registerer" "tezos-protocol-plugin-alpha-registerer" ] build: [ diff --git a/src/bin_proxy_server/dune b/src/bin_proxy_server/dune index 21479e2f9f19..f1ab498d79e0 100644 --- a/src/bin_proxy_server/dune +++ b/src/bin_proxy_server/dune @@ -66,6 +66,9 @@ (select void_for_linking-tezos-client-011-PtHangz2 from (tezos-client-011-PtHangz2 -> void_for_linking-tezos-client-011-PtHangz2.empty) (-> void_for_linking-tezos-client-011-PtHangz2.empty)) + (select void_for_linking-tezos-client-012-PsiThaCa from + (tezos-client-012-PsiThaCa -> void_for_linking-tezos-client-012-PsiThaCa.empty) + (-> void_for_linking-tezos-client-012-PsiThaCa.empty)) (select void_for_linking-tezos-client-alpha from (tezos-client-alpha -> void_for_linking-tezos-client-alpha.empty) (-> void_for_linking-tezos-client-alpha.empty)) @@ -84,6 +87,9 @@ (select void_for_linking-tezos-protocol-plugin-011-PtHangz2 from (tezos-protocol-plugin-011-PtHangz2 -> void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty) (-> void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty)) + (select void_for_linking-tezos-protocol-plugin-012-PsiThaCa from + (tezos-protocol-plugin-012-PsiThaCa -> void_for_linking-tezos-protocol-plugin-012-PsiThaCa.empty) + (-> void_for_linking-tezos-protocol-plugin-012-PsiThaCa.empty)) (select void_for_linking-tezos-protocol-plugin-alpha from (tezos-protocol-plugin-alpha -> void_for_linking-tezos-protocol-plugin-alpha.empty) (-> void_for_linking-tezos-protocol-plugin-alpha.empty))) @@ -112,10 +118,12 @@ (write-file void_for_linking-tezos-client-009-PsFLoren.empty "") (write-file void_for_linking-tezos-client-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-client-011-PtHangz2.empty "") + (write-file void_for_linking-tezos-client-012-PsiThaCa.empty "") (write-file void_for_linking-tezos-client-alpha.empty "") (write-file void_for_linking-tezos-protocol-plugin-007-PsDELPH1.empty "") (write-file void_for_linking-tezos-protocol-plugin-008-PtEdo2Zk.empty "") (write-file void_for_linking-tezos-protocol-plugin-009-PsFLoren.empty "") (write-file void_for_linking-tezos-protocol-plugin-010-PtGRANAD.empty "") (write-file void_for_linking-tezos-protocol-plugin-011-PtHangz2.empty "") + (write-file void_for_linking-tezos-protocol-plugin-012-PsiThaCa.empty "") (write-file void_for_linking-tezos-protocol-plugin-alpha.empty "")))) diff --git a/src/bin_proxy_server/tezos-proxy-server.opam b/src/bin_proxy_server/tezos-proxy-server.opam index e77f4ab09118..a32a4cb21483 100644 --- a/src/bin_proxy_server/tezos-proxy-server.opam +++ b/src/bin_proxy_server/tezos-proxy-server.opam @@ -33,12 +33,14 @@ depopts: [ "tezos-client-009-PsFLoren" "tezos-client-010-PtGRANAD" "tezos-client-011-PtHangz2" + "tezos-client-012-PsiThaCa" "tezos-client-alpha" "tezos-protocol-plugin-007-PsDELPH1" "tezos-protocol-plugin-008-PtEdo2Zk" "tezos-protocol-plugin-009-PsFLoren" "tezos-protocol-plugin-010-PtGRANAD" "tezos-protocol-plugin-011-PtHangz2" + "tezos-protocol-plugin-012-PsiThaCa" "tezos-protocol-plugin-alpha" ] build: [ -- GitLab From 5cbdddde520f48afacc12909e5e941790370e832 Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Tue, 30 Nov 2021 11:30:25 +0000 Subject: [PATCH 08/10] Test: test stitching from H for now Migration code needs to be updated and this change reverted. --- tests_python/tests_alpha/protocol.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests_python/tests_alpha/protocol.py b/tests_python/tests_alpha/protocol.py index 34166afbfda8..06e52dccd1cc 100644 --- a/tests_python/tests_alpha/protocol.py +++ b/tests_python/tests_alpha/protocol.py @@ -14,9 +14,9 @@ TENDERBAKE_PARAMETERS['consensus_committee_size'] = 67 FOLDER = constants.ALPHA_FOLDER -PREV_HASH = constants.ITHACA -PREV_DAEMON = constants.ITHACA_DAEMON -PREV_PARAMETERS = constants.ITHACA_PARAMETERS +PREV_HASH = constants.HANGZHOU +PREV_DAEMON = constants.HANGZHOU_DAEMON +PREV_PARAMETERS = constants.HANGZHOU_PARAMETERS def activate( -- GitLab From 7012433e152f8319e91db624a2e3fc250b945c4c Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Tue, 14 Dec 2021 11:27:16 +0000 Subject: [PATCH 09/10] Doc: rename Alpha to Ithaca --- docs/protocols/012_ithaca.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/protocols/012_ithaca.rst b/docs/protocols/012_ithaca.rst index f6e4cc5eeb34..a47df8e778e1 100644 --- a/docs/protocols/012_ithaca.rst +++ b/docs/protocols/012_ithaca.rst @@ -1,13 +1,13 @@ -Protocol Alpha -============== +Protocol Ithaca +=============== -This page contains all the relevant information for protocol Alpha +This page contains all the relevant information for protocol Ithaca (see :ref:`naming_convention`). The code can be found in the :src:`src/proto_012_PsiThaCa` directory of the ``master`` branch of Tezos. -This page documents the changes brought by protocol Alpha with respect +This page documents the changes brought by protocol Ithaca with respect to Hangzhou. .. contents:: -- GitLab From edf3a725afa7f187176d868be9072427ea06647a Mon Sep 17 00:00:00 2001 From: Fedor Sheremetyev Date: Tue, 14 Dec 2021 11:33:01 +0000 Subject: [PATCH 10/10] Doc: Generate RPC and commands docs --- docs/Makefile | 13 +++++++++++-- docs/doc_gen/dune | 1 + docs/doc_gen/rpc_doc.ml | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index ddb6a168a40f..11e4d0f99bed 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -10,11 +10,13 @@ DOCERRORDIR = $(DOCGENDIR)/errors DOCRPCDIR = $(DOCGENDIR)/rpcs ALPHA_LONG = ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK +ITHACA_LONG = PsiThaCaT47Zboaw71QWScM8sXeMM7bbQFncK9FLqYc6EKdpjVP HANGZHOU_LONG = PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx ACTIVE_LONG = $(HANGZHOU_LONG) ALPHA_SHORT = alpha HANGZHOU_SHORT = 011-PtHangz2 +ITHACA_SHORT = 012-PsiThaCa ACTIVE_SHORT = $(HANGZHOU_SHORT) SCRIPTSDIR = scripts @@ -30,6 +32,11 @@ manuals: main @../tezos-client -protocol $(ALPHA_LONG) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > alpha/tezos-client.html @../tezos-baker-$(ALPHA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > alpha/tezos-baker.html @../tezos-accuser-$(ALPHA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > alpha/tezos-accuser.html + # 012 (Ithaca) protocol + @../tezos-client -protocol $(ITHACA_LONG) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 012/tezos-client.html + @../tezos-baker-$(ITHACA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 012/tezos-baker.html + @../tezos-endorser-$(ITHACA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 012/tezos-endorser.html + @../tezos-accuser-$(ITHACA_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 012/tezos-accuser.html # 011 (Hangzhou) protocol @../tezos-client -protocol $(HANGZHOU_LONG) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 011/tezos-client.html @../tezos-baker-$(HANGZHOU_SHORT) man -verbosity 3 -format html | sed "s#${HOME}#\$$HOME#g" > 011/tezos-baker.html @@ -65,6 +72,7 @@ redirectcheck: # - on each other protocol including alpha, also checking label defs (option -l) xrefscheck: $(CHECKXREFS) 011 + $(CHECKXREFS) -l 012 $(CHECKXREFS) -l alpha scriptsindoccheck: @@ -94,6 +102,7 @@ $(DOCGENDIR)/rpc_doc.exe: rpc: $(DOCGENDIR)/rpc_doc.exe @dune exec $(DOCGENDIR)/rpc_doc.exe index "" > active/rpc.rst + @dune exec $(DOCGENDIR)/rpc_doc.exe index "012" > 012/rpc.rst @dune exec $(DOCGENDIR)/rpc_doc.exe index alpha > alpha/rpc.rst @dune exec $(DOCGENDIR)/rpc_doc.exe index shell > shell/rpc.rst @dune exec $(DOCGENDIR)/rpc_doc.exe acl > user/default-acl.json @@ -158,5 +167,5 @@ lint: pylint pycodestyle lint_black clean: @-rm -Rf "$(BUILDDIR)" - @-rm -Rf api/errors.rst active/rpc.rst 011/rpc.rst alpha/rpc.rst shell/rpc.rst shell/p2p_api.rst CHANGES.rst - @-rm -Rf api/tezos-*.html api/tezos-*.txt active/tezos-*.html 011/tezos-*.html alpha/tezos-*.html + @-rm -Rf api/errors.rst active/rpc.rst 011/rpc.rst 012/rpc.rst alpha/rpc.rst shell/rpc.rst shell/p2p_api.rst CHANGES.rst + @-rm -Rf api/tezos-*.html api/tezos-*.txt active/tezos-*.html 011/tezos-*.html 012/tezos-*.html alpha/tezos-*.html diff --git a/docs/doc_gen/dune b/docs/doc_gen/dune index 2ccda203a55f..99184dd8f3f1 100644 --- a/docs/doc_gen/dune +++ b/docs/doc_gen/dune @@ -8,6 +8,7 @@ tezos-protocol-updater ; TODO tezos/tezos#2170: adapt next line(s) tezos-embedded-protocol-011-PtHangz2 + tezos-embedded-protocol-012-PsiThaCa tezos-embedded-protocol-alpha data-encoding re) diff --git a/docs/doc_gen/rpc_doc.ml b/docs/doc_gen/rpc_doc.ml index 6fa6c13aa5f8..75c7b6a7daaa 100644 --- a/docs/doc_gen/rpc_doc.ml +++ b/docs/doc_gen/rpc_doc.ml @@ -37,6 +37,10 @@ let protocols = "011 Hangzhou", Some "/include/rpc_introduction.rst.inc", "PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx" ); + ( "012", + "012 Ithaca", + Some "/include/rpc_introduction.rst.inc", + "PsiThaCaT47Zboaw71QWScM8sXeMM7bbQFncK9FLqYc6EKdpjVP" ); ] let pp_name ppf = function -- GitLab